バンク切り換え
バンク切り換え(バンクきりかえ、Bank Switching)はコンピュータのメモリ内のアドレス空間を、1次元配列から多次元配列にする事によりアクセス可能なアドレス空間を拡張する技術である。ミニコンピュータで生まれた技術である。8ビットのマイクロコンピュータシステムで一般に使われた技術であり、アクセス可能なRAMやROMの量をアドレスバスを拡張せずに増やすことを目的としていた。
かつてよく使われたタイプは、アドレス空間を2次元配列にする物である。たとえばアドレスバスが16ビットしか無く、まったく工夫されていない場合アドレス空間は65536ワードしか使えない。そこでたとえばアドレス0xc000番地から0xffff番地をバンク切り換えして二つの要素を持つようにすると、49152+16384×2=81920ワードを扱える様になる。この手法は、古くは磁気コアメモリとROMバンクを切り換えて、アドレス線を節約する方法に用いられた。8ビットパソコンでは最大メインメモリ空間に匹敵するVRAMのアドレス空間や、テキストVRAM等を、主記憶容量を確保しつつ、CPUからアクセスさせるために使われた。また、メインメモリを64Kバイト搭載した8ビットパソコンにおいて、初期ローダからのロードしたシステムへの遷移、書き換えの不可能なROM空間をRAMとして、ユーザーに開放するためなどの切り替えにも用いられている。これらの実装により、予め実装されているROMに書き込まれているもの以外のシステムの利用や、より自由度の高い利用が可能となった。
仮想記憶の普及によって単純なバンク切り換え機構は廃れた。仮想記憶においては、論理アドレス空間をページまたはセグメントと呼ばれる小さな単位に分割し、それぞれをアドレス変換機構において物理アドレスに結び付けている。現在の実装では、アドレス空間はプロセス・ページまたはセグメント・論理アドレスオフセットによって構成される3次元疎配列となる(仮想マシンモニタを使っている場合には4次元疎配列)。原理的にはバンク切り換えの発展系であるが、仮想記憶をバンク切り換えと呼ぶ事は無い。
バンク切り換えでは、CPUのアドレスの他にページ切り換え用のレジスタが必要である。このレジスタは、少なくとも論理的(ソフトウェア的)にはCPUの外にあるのが一般的である(HD64180のようにCPUチップの中にこのページ切り換え用のレジスタを持っているチップも存在したが、プログラミング上は、CPU内部のレジスタとして扱われていなかった)。
このことはアドレスをCPU内部のレジスタとページ切り換え用のレジスタの2箇所で別々に管理することを意味する。それはCPU内部のレジスタからページレジスタへの桁上がり等のハードウェアが実装されていないことになるため、配列等がページサイズより大きい場合等はソフトウェアでページを管理する必要が生じた。
これはソフトウェアの処理が必要な分、1次元アドレス管理より速度が低下し、またソフトウェアを必要とするということは、そのソフトウェアにバグが潜む可能性が生じるということであり、システムの信頼性の低下が起こった。
このようなバグの例として、一塊のデータがページ境界に配置される場合が挙げられる、これは大きさが2nバイトではない構造体の配列が、全体としてページサイズを超えた場合等に起こる。
また、大量のデータをメモリ間で転送する場合に、バンク切り換えを行いながら転送する処理が必要になるが、この処理はかなり煩雑になった。
バンク切り換え用のレジスタの仕様(接続されているI/Oアドレス等)は、たとえCPUが同一であっても、一般論として機種毎に異なっていたために、同一CPUでありながら非互換となる原因の一つとなった。
また、必ずしもその空間がCPUが持つアドレス空間内に無いため、単純なバンク切り替えの場合、その実行コードの場所が限定された。例えば、VRAMが出現するアドレスに描画を伴う処理をおくことは、VRAMが排他的にそのアドレスのメインメモリの代わりにその場所に出現することになるので、不可能となる。同様に、バンク切り替えで実装されたROMのルーチンをコールするためには、それを呼び出すプログラム自身が存在している場所以外のページに、該当する処理のあるROMを接続の上、処理する必要がある。
Z80 や 6502 といった 8ビットマイクロプロセッサではメモリアドレスは 16ビットで表されるため、最大でも64Kバイトのメモリ空間しかアクセスできない。そのため、64Kバイト以上のメモリを搭載する 8ビットシステムではメモリは64Kバイトの空間を複数のバンク(あるいはページ)に分割して使用した。つまり、同時にアクセスできるメモリ空間は依然として64Kバイトであるが、バンクを切り換えることでそれ以上のメモリを使用可能としたのである。
その仕組みはいくつかの発展を遂げ、メモリマップドI/Oと組み合わせ四つの空間を「スロット」として扱い、接続アドレスの移動こそできないものの、ハードウェアのI/Oと制御プログラムの接続とその競合を防ぐ仕組みがMSXには実装されている。メモリ空間に接続されるアドレス間の移動は不可能であるため、その組み合わせによっては配置に制限が発生する。
その後、MB-S1やFM-77、MZ-2500ではメモリをページ単位で空間に割り当てる原始的なメモリ管理ユニットが内蔵されるようになり、より自由に配置できるようになった。
前述のMSXでも、固定だったアドレスや組み合わせの制限等を回避するため、MSX2においてメモリマッパという仕組みが追加された。
1982年にリリースされた最終バージョンのCP/Mでは、8080やZ80で64KB以上のメモリを使えるようバンク切り換えをサポートしていた。
バンク切り換えは初期のゲーム機でも使われていた。例えば Atari 2600 は4KBまでのROMしかアクセスできないため、ロムカセット内に独自のバンク切り換えハードウェアを内蔵して4KB以上のROMを使った洗練されたゲームを実現していた。
ファミリーコンピュータには本来バンク切り換え機能はなく、ROMカートリッジ側にコントローラ(Virtual Rom Controller など)を搭載することでバンク切り換えが行われた。ファミリーコンピュータはもともと扱える容量が少なく、ディスクシステムの登場によってROMカートリッジは終了となるはずであった。ところがバンク切り換えによって大容量ROMカートリッジを扱う手法が確立されると、読み込み速度の遅いディスクシステムの方が次第に廃れ、最終的にはディスクよりもカートリッジの方が大容量となっていた。ゲームボーイのカートリッジには MBC (Memory Bank Controller) というチップが使われており、ROMバンク切り換えだけでなく、カートリッジ内のSRAMバンク切り換えや赤外線リンクなどの周辺機器へのアクセスも提供していた。
NECのPC-9801(とその後継)においては、16ビットマイクロプロセッサであるIntel 8086(とその上位互換CPU)が採用されたが、アドレス空間が1メガバイトしかなかったので、アプリケーション等のメモリ要求量の増大にともない、後述のEMSの国内での普及に先行して、バンク切り換え用メモリとしてのバンクメモリが開発された。各周辺機器メーカーからそれぞれ独自規格のバンク切り換え用メモリが発売され、対応アプリケーションやゲーム等も一部でそれぞれ発売された。その後、アイ・オー・データ機器が提唱した「I/Oバンク方式」によるバンク切り換えメモリ管理BMS(Bank Memory Specification) が制定され、複数のアプリケーション間の競合を避けるメモリ管理も行われた。バンクメモリだけでなくハードウェアEMS/プロテクトメモリにも兼用できる製品もあった。
Intel 8086アーキテクチャではアドレス空間が1メガバイトしかなかったので、EMSと呼ばれるメモリ管理方式が考案された。1988年、ロータス社、インテル、マイクロソフトは、MS-DOSを搭載したPC/AT互換機で使用するEMSの仕様について合意した。これは Upper Memory Area と呼ばれるメモリ空間の一部を拡張し、より多くのメモリ資源にアクセスさせる為のメカニズムである。これは広く普及し、プロセッサの世代が交代しIntel 80286以降のようにMMUが搭載されるようになってからも使われ続けた(贅沢にもMMUは単なるバンク切り換えコントローラとして使われた)。EMSの仕様は互換性を保つために後のMicrosoft Windowsでもエミュレートされてサポートされていた。
読み出しバンクと書き込みバンクを別途指定できるようにする事で、入力と出力を同じアドレスで行い、出力データの保持とアドレス計算を省く方式が考え出された(リード・モディファイ・ライト Read Modify Write)。これもまたに応用された。
モトローラ MC68000シリーズではブート時、アドレス0番地から2ロングワードにスタックポインタ初期値・ブートストラップへのアドレスをCPUに提示しなければならず、起動時のバンク切り換えは必須であった。