PC98

EMSとXMS


640KBの壁を超える方法

前回、MS-DOSではCPUが640KB以上のメモリーを認識できないという話をしました。
しかし当時のエンジニアは、いくつかの方法でその壁を越えようとしました。

ひとつは、DOSエクステンダーという専用の拡張プログラムを使う方法です。
マイクロソフトがMS-DOSのプロテクトモード化を渋り、ウインドウズのリリースに時間をかけていたころ、いくつかのソフトメーカーや有志がMS-DOS上でCPUをプロテクトモード化するソフトウェアを作りました。
実際、海外のゲーム「Doom」などは、DOSエクステンダーを使ってDOSソフトウェアとは思えないほどリッチな表現を行っていました。
しかし、DOSエクステンダーは実質的にはOSに近い性質を持っていて、これを使ってしまうと、もうMS-DOS用のソフトウェアではなくなってしまうし、何よりもマイクロソフトの公認OSから外れてハードウェアの互換性が保証できないため、安定した実行環境を好むソフトウェア開発では普及しませんでした。

物理的に解決しようとしたEMS

窓から眺める広い世界

リアルモードのDOSで、640KB以上のメモリーを使う古い技術はEMSです。
これは、Cバスなどの拡張スロットに物理的なEMSメモリーを差し込む仕組みでした。
当時DOSを使っていた人は「うちのパソコンはEMSメモリーなんて積んでなかったけど、普通にEMSを使えていたよ」と思うかもしれませんが、MS-DOSではEMM386.EXEというドライバーが後に開発され、通常のメモリーをEMSとしてエミュレートすることが可能になっていました。

EMSのメモリーマップイメージ

では、1MBのメモリー空間しか認識できないリアルモードのCPUが、どうやってEMSを認識したのか?
それは、メモリー空間にページフレームという窓を作る方法です。
メモリーアドレスの一部に16KBの窓を最大で4つまで作ることができ、同時に64KBのEMSを覗くことができたのです。
そして、窓から見えるEMSの景色はページングという仕組みで切り替えることができました。

この技術の便利なところは、EMSから通常のメモリーにコピーしなくても、そのままEMSを参照できるという点です。
一方、窓の大きさが64KBしかないため、例えば640x400の16色の画像をEMSから取り出して描画しようとすると転送量は128KB必要になり、描画の途中でページを切り替えるという処理を入れなければなりませんでした。
また、初期の物理的なEMSはCバススロットから読み取っていたため、帯域が細くメモリーなのに読み書きが非常に遅いという欠点もありました。

CPUを一瞬だけモードチェンジするXMS

物理的なメモリーボードで解決しようとしたEMSに対して、後の時代にソフトウェアで解決しようしたのがXMSです。
マイクロソフトはMS-DOSの完全なプロテクトモード対応こそ行いませんでしたが、XMSドライバーを作り、MS-DOSで大容量メモリーを使えるようにしました。
これは、どのような魔法を使っているのかというと、メモリーの読み書きをする一瞬だけCPUをリアルモードからプロテクトモードに切り替え、終わったら即座にリアルモードに戻す力技のプログラムです。
なお、先ほど紹介したEMM386.EXEも、この仕組みでEMSをエミュレートしています。

一見、MS-DOSでも大容量を扱えるように見えますが、この仕組みにも欠点がありました。

ひとつは、メモリー転送の回数が多くなることです。
たとえばゲームの画像をXMSから取り出して描画する場合、拡張メモリーから直接VRAMに送ることはできず、必ず拡張メモリーからコンベンショナルメモリーにXMSでコピーして、それからVRAMに転送するという2ステップが必要でした。
これでは描画が遅くなるのはもちろん、コンベンショナルメモリーの節約にはならず、たとえば画像の加算を行うメモリーをコンベンショナルメモリーに確保した場合、16色モードだと128KB、256色モードだと256KBのメモリーが必要で、さらにXMSから取り出した画像もコンベンショナルメモリーに一時的に置かなければならず、画像だけでコンベンショナルメモリーを半分近く取られてしまうという状況になります。
当時のPC-9801向けゲームが画面の周囲にフレームを置いてビジュアルを小さくしていたのも、単にフロッピーディスクの容量節約ではなく、このメモリー問題が大きかったと言えます。

286の特殊な制限

もうひとつ、XMSには大きな欠点があり、それはリアルモードとプロテクトモードの切り替えに必要なオーバーヘッドです。
CPUの動作モードを切り替えるわけですから、1サイクルで一瞬で切り替わるということはなく、XMSで読み書きをするたびに無駄な時間が掛かっていました。
また、その中でも286という初期のプロテクトモード搭載のCPUには大きな欠点がありました。
286は、一度プロテクトモードに切り替わるとリアルモードに戻せなくなるという仕様だったのです。
当時、ビルゲイツ氏が「286は欠陥品」と言ったという逸話が残っているぐらいです。
ちなみに286でもXMS自体を使うことができるものの、それはプロテクトモードからリアルモードに戻す時に一度内部で動作中のCPUをリセットするという方法で実現されていて、まるで手術中に患者を殺してから瞬時に蘇生するというような荒業の対応でした。
先ほど話したEMSのエミュレータであるEMM386.EXEのファイル名も、プロテクトモードとリアルモードを行き来できる386以降でしか使えないという明確な意思表示です。

結局のところ、どれだけEMSやXMSを用いても、コンベンショナルメモリーを少しでも確保しておくというのはソフトウェア開発側にもエンドユーザー側にも極めて重要だったのです。