Skip to content

Memory Map

Masakazu Yonehara edited this page Aug 25, 2026 · 4 revisions

メモリマップ

PC-98 の 1MB の空間に、メインメモリ・画面用のメモリ・ROM が並んでいます。 どこが書けるかは、画面のモードによって変わります。

実測したメモリマップ

4KB ごとに実際に書き込んで、書けたかどうかで調べたものです。

範囲 内容
0x00000-0x9FFFF メインメモリ(640KB)
0xA0000-0xA1FFF テキスト VRAM(文字コード面)
0xA2000-0xA3FFF テキスト VRAM(属性面)
0xA3FE2-0xA3FFE メモリスイッチ(8バイト。下記)
0xA4000-0xA4FFF CG ウィンドウ(フォントの読み書き用)
0xA5000-0xA7FFF 未使用
0xA8000-0xAFFFF グラフィック VRAM(青)
0xB0000-0xB7FFF グラフィック VRAM(赤)
0xB8000-0xBFFFF グラフィック VRAM(緑)
0xC0000-0xC7FFF ユーザー用の拡張 ROM 空間(32KB)
0xC8000-0xDFFFF システム用の拡張 ROM 空間(96KB・使用不可)
0xE0000-0xE7FFF グラフィック VRAM(輝度)※16色モードのときだけ
0xE8000-0xFFFFF ROM(BIOS・BASIC。96KB)

拡張 ROM 空間は、ボードが載っていなければ何もありません。実測では 0xC0000 は 0xFF が読め、書き込みもできました(何も載っていないため)。 0xD8000 には何かの ROM が載っていて、書き込めませんでした。

0xC8000-0xDFFFF はシステム用で、勝手に使ってはいけない領域です。

モードで変わります

0xE0000(輝度プレーン)は、16色モードにしないと存在しません。

8色モード(既定)では、この領域を読むと 0xFF が返るだけで、 書いても何も起きません。エラーも出ません。

        mov     al, 0x01
        out     0x6A, al        ; 16色モードにする → 0xE0000 が使えるようになる

グラフィックについては グラフィック画面 を参照してください。

メモリスイッチ

0xA3FE2 から 4バイトおきに8バイト、本体の設定を保持する領域があります。 電源を切っても消えません。

実測で読めた値です(この環境での値であり、設定によって変わります)。

アドレス 値
0xA3FE2 0x48
0xA3FE6 0x05
0xA3FEA 0x04
0xA3FEE 0x08
0xA3FF2 0x01
0xA3FF6 0xA0
0xA3FFA 0x00
0xA3FFE 0x6E

それぞれのバイトが何の設定かは確認できていません。 書き換えると本体の設定が変わる領域なので、意味が分からないまま触らないでください。

DOS の空きメモリ

.COM プログラムは、起動した時点で残りのメモリを全部確保しています。

そのままでは他にメモリを渡せません。子プロセスを起動する場合や、 常駐して残りを解放したい場合は、自分の取り分を縮めてください。

        ; 自分の PSP を得る
        mov     ah, 0x62
        int     0x21            ; BX = PSP のセグメント

        ; 自分の取り分を縮める
        mov     es, bx
        mov     bx, 0x100       ; 残すパラグラフ数(この例では4KB)
        mov     ah, 0x4A
        int     0x21

実測では、縮める前は「確保できる最大ブロック」が 0(空きなし)で、 AH=0x4A で 4KB に縮めたあとは 604KB になりました。

確保できる最大の大きさは AH=0x48 に BX=0xFFFF を渡すと BX に返ります (このとき確保自体は失敗し、AX にはエラーコード 8 が入ります)。

拡張メモリ(XMS)

640KB の外側のメモリは XMS として使えます。ドライバが入っていれば、 INT 2Fh で有無を調べ、専用の入口を呼び出して使います。

        mov     ax, 0x4300
        int     0x2F            ; AL = 0x80 なら XMS が使える

        mov     ax, 0x4310
        int     0x2F            ; ES:BX = 呼び出す入口。控えておく

入口は INT ではなく far call で呼びます。

AH 機能 戻り値
0x00 バージョン AX にバージョン
0x08 空き容量を調べる AX = 最大の空きブロック(KB)、DX = 合計(KB)
0x09 確保(DX に KB) AX=1 成功、DX = ハンドル
0x0A 解放(DX にハンドル) AX=1 成功

実測では XMS バージョン 2.00、空きが 863KB ありました。 64KB を確保すると空きが 799KB にちょうど減り、解放すると戻りました。

確保しても、そのメモリは直接アドレスできません。 本体のメモリとの間で 転送する呼び出し(AH=0x0B)を使います(未検証)。

EMS と UMB

EMS はこの環境では使えませんでした。 窓口になるデバイス EMMXXXX0 を 開こうとすると「ファイルが無い」で失敗します。ドライバが入っていません。

UMB(640KB より上の空き領域)は、既定ではつながっていません。

        mov     ax, 0x5802
        int     0x21            ; AL = 0 ならつながっていない

        mov     ax, 0x5803
        mov     bx, 1
        int     0x21            ; つなぐ

実測では、0x5802 が 0x00(つながっていない)を返し、0x5803 でのリンクは成功しました。

よくある間違い

  • 0xE0000 に書いても何も起きない。 16色モードにしていないと存在しません。 読むと 0xFF が返るだけで、書き込みも無視されます。
  • 拡張 ROM 空間を空きメモリとして使う。 何も載っていなければ書けてしまいますが、 ボードを挿すとそこに ROM が現れます。0xC8000 以降はシステム用です。
  • メモリスイッチの領域を、ただの RAM だと思って使う。 本体の設定です。
  • 子プロセスを起動しようとしてメモリ不足になる。 .COM が全部持っています。 AH=0x4A で縮めてください。
  • 読めた値で「そこに何かある」と判断する。 未実装の領域も 0xFF が読めます。 書いて読み返さないと区別できません。

実機との差異

0xD0000 台は増設ボードの ROM が載る領域なので、構成によって変わります。 ここでの結果は、この環境での構成にすぎません。

そのほかについて、現時点で確認できている差異はありません。 ただし 測定は np2kai 上で行っています。

未検証

  • メモリスイッチの各バイトが何の設定か
  • CG ウィンドウ(0xA4000)の使い方。フォントの読み書きは I/O ポート経由でできました(→ テキスト VRAM)が、この領域を使う方法は未確認です
  • 0xD8000 に載っている ROM が何か
  • XMS のメモリと本体メモリの間で転送する呼び出し(AH=0x0B)
  • UMB をつないだあと、実際にその領域を使う手順
  • メインメモリが 640KB より少ない構成での見え方
  • 0x100000 以降(プロテクトモードでのみアクセスできる領域)

検証: 2026-08-24 / WebNP2 (np2kai) + FreeDOS(98) / 再現: guest/probes/MEMSCAN.ASM(8色モード), MEMSCAN2.ASM(16色モード)

4KB ごとに「元の値を読む → 反転して書く → 読み返す → 元に戻す」を行い、 書けたかどうかで分類しています。元の値も記録して、ROM と未実装を見分けています。

Clone this wiki locally