普通の VGA メモリマップは 0xA0000 から始まる 64k です。64k より 大きなメモリにアクセスするための機構として、SuperVGA チップセット は ``バンク切り替え機能 (bank switching)'' - 高位のアドレスビット により画像操作を行うメモリバンクを選択する機能を実装しています。 バンクのサイズと数はチップセットによりさまざまであり、詳細は それぞれのチップセットに関する資料に記載されています。 チップセットの持つバンクレジスタの数は 0, 1, 2 のいずれかです。 バンクレジスタなしの場合はたぶん generic な VGA *だけ* なので、 ここでは関係ありません。
新しいチップセット (例えば Trident 8900CL や Cirrus 製チップなど) は ビデオメモリをリニアに割り当てる事が可能であることに注意してください。 この仕組を使うことによってサーバの性能を向上できますが、現在ではまた この機能のサポートはありません。従って、新しいチップセットについても この機能を活用できる方法はまだありません。
[訳注: 例えば C&T や Trident などのアクセラレータに 対応している SVGA ドライバーは PCI バス上のチップについて リニアアドレスの使用が標準となっています。もし興味があるなら、 既存のコードを調べてみると良いでしょう。]
ほとんどの SVGA チップセットは二つのバンクレジスタを持っています。 データを画面のある領域から他の領域に単純な 'mov' 命令で移動できるため 最も望ましい構造です (もしバンク構造に ``望ましい'' と呼べるものが 存在するなら、ですが)。 二重化バンキング (dual-banking) には二つの方式があり、一方は 二つのバンク操作により読み込み専用バンクと書き込み専用バンクを定義する もので、もう一方は二つの書き込み/読み込み兼用窓を持つ方式です。 最初の方式は SVGA メモリ窓全体を読み込みと書き込みの両方に使い、 二つのバンクレジスタによってどちらのバンクを実際に使うかを指定します。 (例: ET3000, ET4000) 二番目の方式では SVGA メモリ窓を読み込み/書き込み可能な二つのバンクに 分配し、それぞれのバンクポインタが一つの窓を制御します。 この場合には一つの窓が読み込み操作に使用され、他の窓が書き込み操作に 使用されます。 (例: PVGA1/Western Digital, Cirrus)
単一のバンクレジスタを持つチップセットは、その一つのバンクを 読み込みと書き出しの両方に使用します。画面のある部分の情報を 他の部分へとコピーするには、データを読み込み、蓄え、それから 書き出すという手順が要求されるため、この方式はあまり好ましい ものではありません。幸運にも、チップセットの持つバンク数が 一つでも二つでも、サーバーは問題無く扱うことができます。 次に説明するドライバデータ構造中の項目を定義することによって その挙動が決まります。
ドライバを動作させるにはまず `sdc_bank.s
' ファイル内に
三つの関数をアセンブラ言語で書く必要があります。
これらの関数は、バンク読み込み設定 - SDCSetRead(),
バンク書き出し設定 - SDCSetWrite() と 両バンク設定 -
SDCSetReadWrite() です。
一つのバンクしか持たないチップセットの場合は、三つの関数すべてを
同じ関数へのエントリーポイントとして宣言できるでしょう。
(``tvga8900'' ドライバを例として参照してください)
[訳注: 3.3.3.1 の場合 vga256/drivers/tvga8900/bank.s の最初 に書いてある TVGA8900{SetReadWrite,SetRead,SetWrite} の 3 つが 同じ関数に対するエントリーポイントとして書かれています。 なお i386Architecture 以外は bankc.c が使われますが、こちらは ここで説明している例とは異なります。 (そもそも C で書かれてます) i386Architecture 以外の環境でドライバーを開発しようとする人は 注意して下さい。 ]
これらの関数はとても単純なものです - バンク番号が関数の %al レジスタへ渡されるので、その値に対してシフトやビットマスクなど、 バンク番号を正しい形式に変換するための操作を実行した後、 適切な I/O ポートへその値を書き出します。 二つのバンクが同時に読み込み専用になったり書き出し専用になったりする チップセットの場合、 SetReadWrite()関数はそれぞれのバンクに 対して一回づつ、計二回上記の動作を実行する必要があります。 二つの独立な読み込み/書き出し窓を持つチップセットの場合、 SetReadWrite() 関数は SetWrite() 関数が使うのと 同じバンクを使用します。
特別な注意として、これらの関数は ``assyntax.h'' ファイルで 定義されているマクロアセンブラの書式で書く必要があります。 これは OS に関係な く正しいアセンブラコードを生成することを保証する為です。現在、この マクロ形式は USL, GNU と インテルのアセンブラの書式をサポートしてい ます。
以上がバンク機能に関する作業です。普通、チップセットに関する資料が このプログラムの例題を掲載していますが、そうでない場合でも他のドライバを 例にとれば理解することは難しくはありません。