[MSX] MSXを動かしたコードの正体:BASICとDOSが築いた標準の裏側

概観:MSX の標準と基本構成

MSX は 1983 年に ASCII/Microsoft 主導で発表された共通仕様のホビーパソコン規格

CPU は Z80A(約 3.58 MHz)、表示は VDP(初代は TMS9918A 系、MSX2 で Yamaha V9938、MSX2+ で V9958)、音源は PSG(GI AY-3-8910 互換。MSX-Engine 内蔵時は YM2149 互換) をコアに据え、拡張カートリッジの互換性を前提に設計された。

OS は MSX-BASICMSX-DOS が標準(MSX2 以降は MSX-DOS2、BASIC も 2.x/3.x に拡張)。(ウィキペディア)

アーキテクチャ上の要点は次のとおり:


1. MSX-BASIC の正体と内側

1.1 どのBASICの系譜か

MSX-BASICは Microsoft系MBASIC を土台に、機種側のグラフィック/サウンド/周辺I/Oを叩く命令を拡張した方言で、世代に応じて BASIC 1.0(MSX1)→ 2.0/2.1(MSX2)→ 3.0(MSX2+)→ 4.x(turbo R) と進化した。仕様書や技術資料群もこの系譜を前提に構成されている。(download.file-hunter.com)


1.2 ROM配置と“起動直後の64KB”

MSXは 16KB×4ページの64KB空間スロット/サブスロットで切り替える設計で、BASIC起動時は ROM(BIOS+BASIC)とRAMの割り当てが決まったパターンで見える(MSX-DOS起動時は別パターン)。
公式テクニカルハンドブックには、BASIC時/MSX-DOS時のメモリ使用例が図示されている。(konamiman.github.io)


1.3 トークン化とプログラム内部表現

MSX-BASICのプログラムは トークン化され、各行は 「次行へのポインタ」「行番号」「トークン列」 で構成される。
保存時は行番号が数値として書き出されるが、実行時には 行番号参照が該当行へのポインタに置き換わる(LIST/SAVE時に相互変換) という設計で、リンクリスト的にたどれる。
(msx.org)


1.4 ディスクBASICという“後付け”

初代MSX(BASIC 1.0)では FDD機能は本体ROMに含まず、FDDカートリッジ側の Disk BASIC拡張ROM がコマンド群を提供する(そのぶんRAMは消費)。
この設計はマニュアルや資料でも“MSX-BASICを基盤に拡張ROMで機能追加”という前提で説明される。(download.file-hunter.com)


1.5 VDP/PSGへの素手アクセス(BASICの裏で動くI/O)

  • VDP(映像)
    MSX1の TMS9918A/MSX2以降の V9938/V9958 は、CPU側から I/O 0x99(制御)/0x98(データ) でレジスタ設定・VRAM転送を行う。
    BASICの SCREEN/LINE/VPOKE などの最終到達点はこのポート操作に落ちる(MSX2以降は 0x9A/0x9B など拡張ポートも追加)。
    (konamiman.github.io)


  • PSG(音)
    標準は AY-3-8910互換PSG(多くはYM2149互換として実装)。
    PSGの機能・制御はテクニカルハンドブックの BIOS経由アクセス章にまとまっている。(konamiman.github.io)


  • PPI(周辺制御)
    8255 PPI がキーボード行列・スロット制御・カセットI/O等を担当。
    主要ポートは 0xA8〜0xAB とされ、I/Oポート表にも整理されている。
    (retrobrewcomputers.org)


例メモ:OUT &H99, <VDPレジスタ設定> → OUT &H98, <VRAMデータ> の往復や、PSGのレジスタ選択→データ書込みは、BASIC側の SOUND/PLAY/VPOKE といった命令の“最下層”で起きている。VDPは機種世代で拡張されるが、0x98/0x99 を中核に据えるI/O構図は一貫している。
(konamiman.github.io)

2. MSX-DOS:なぜ“8ビットでDOS”が動くのか

2.1 設計思想:CP/M 互換+MS-DOS 風味

1984年に Microsoft Japan / ASCII が設計した MSX-DOS は、CP/M-80 の BDOS 互換API を土台にしつつ、MS-DOS 風のコマンド体系を導入。ファイルシステムは FAT12 を採用し、8ビット Z80 上で CP/M 資産と IBM PC 系との相互運用を両立させた。COMMAND.COM 互換のシェルを持ち、ユーザー体験はほぼ PC-DOS に近い形が意識された。


2.2 CALL 5:CP/M 譲りのシステムコール入口

MSX-DOS の API 呼び出しは、アドレス 0005h へのコールを基本とする。これは CP/M 以来の「CALL 5」文化を踏襲したもの。MSX-DOS2 ではさらに 0F37Dh などの入口が併設され、ファイルハンドル管理や環境文字列処理など“16ビット的”機能を追加した。 興味深いのは、MS-DOS 側も初期には旧BDOS互換ベクタ(PSP:0005h)を保持していた点で、CP/M → MS-DOS → MSX-DOS という歴史的連続性が見える。


2.3 MSX-DOS 1 → 2 の進化点

MSX-DOS2(1988〜) は、大幅に機能が拡張された。

代表例は以下の通り:

  • サブディレクトリの導入(ツリー構造化)
  • 環境変数と CONFIG.SYS 的な仕組み
  • ファイルハンドルベースのAPI
  • エラー処理改善(リターンコード、例外の整理)
  • メモリマッパ対応(64KBを超えるRAM利用)
  • パイプ/リダイレクトのサポート

カーネルファイルは MSXDOS2.SYS で、詳細な関数仕様とエラーテーブルが公式に公開されている。これにより、MSX 上でもかなり PC-DOS に近い開発環境が成立した。


2.4 ブートとBIOS拡張の役割分担

MSX 本体 BIOS はディスク非依存であるため、FDD 側の Disk ROMBDOS 層として BASIC/DOS 双方にフックを提供する。
これにより、BASIC と DOS が同じ FAT12 フォーマットを扱えるという統一感が保たれた。

DOS起動時はブートセクタから MSXDOS.SYS → COMMAND.COM がロードされ、さらに AUTOEXEC.BAT があれば実行される。

これは IBM PC 系 DOS とほぼ同じ流れで、Z80 ベースの 8bit 機で“PCライク”な運用が可能になった所以でもある。


コラム:FAT12とは?

MSX-DOS が採用した FAT12 は、MS-DOS 1.x 以来の 標準的なファイルシステムで、フロッピーを中心に使われた。

  • 仕組み
    ディスクを「クラスタ」という単位に区切り、12ビットの番号(最大約4,096個) で管理する。


  • 容量上限
    最大で約 32MB まで。フロッピー(360KB〜1.44MB)には十分だった。


  • MS-DOSとの関係
    PCでもフロッピーはすべて FAT12 で統一されていたため、PCとMSXでフロッピーを共有できた


  • FAT16との違い
    FAT16は16ビット番号を使うため、より大容量(数百MB〜2GB)まで対応できるが、FD時代は FAT12 が主流だった。


「BASICで作ったファイルをDOSで読める」「PCのFDをMSXでそのまま開ける」 という体験は、この FAT12 共通仕様が支えていた。

■ FAT12 と FAT16 の主な違い

項目 FAT12 FAT16
エントリ幅 12ビット(1.5バイト) 16ビット(2バイト)
最大クラスタ数 約 4,096 約 65,536
理論上の最大容量 約 32MB 約 2GB(実用は 512MB 前後までが主流)
典型的な用途 フロッピー、初期の小容量 HDD HDD(数十〜数百MBクラス)、後にPC-98やDOS/Vの標準
オーバーヘッド 管理領域が小さい(フロッピーに最適) エントリが大きくなるぶんディスク管理も大きめ
導入時期 MS-DOS 1.x〜2.x、MSX-DOS MS-DOS 3.x 以降で本格普及

■ 要点

  • FAT12 → 小容量ディスク向け
    360KB/720KB/1.44MB のフロッピーに最適。
    (クラスタ数が少ないので無駄が少ない)

  • FAT16 → HDD 向け
    数十MB〜数百MBのディスクを使えるようにするため拡張。
    (クラスタ数が増えた分、大きな領域を効率的に扱える)

3. 誰が作ったのか:MSX-DOSの“作り方”の証言

MSX-DOS の開発背景については、Tim Paterson(86-DOS/MS-DOSの作者) 本人が証言を残している。 1983年に Microsoft との契約により、MS-DOS 1.25 を Z80 上に移植する作業を担当したと語っている。

Paterson は Z80 向け実機で直接開発するのではなく、まず MS-DOS 上で動作する Z80 エミュレータを自作。これにより PC/AT 環境上で Z80 命令を走らせながら MSX-DOS を構築でき、ファイル管理機構などの大部分を先にテスト可能にした。

エミュレータによって MS-DOS 上で MSX-DOS をクロス開発する形が成立し、効率的に移植が進んだ。

一方で、ASCII 側のエンジニアは I/O System (BIOS相当) を MSX 実機向けに整備した。

これはディスク制御や周辺アクセスを担う部分で、Microsoft 側のカーネル(MSXDOS.SYS)と組み合わさることで、初めて MSX 実機上で MSX-DOS が動作した。

MSX コミュニティに残る記録では、「Microsoft がカーネルを、ASCII がI/Oを」 という役割分担が明確に語られている。

この「米国のDOS作者 × 日本のASCII技術陣」という共同作業こそが、MSX-DOSを短期間で実現させた原動力だった。表に出るのは Gates や Nishi の構想だが、実際のコードを動かしたのはこうした地道なエンジニアリングであった。

4. 世代差まとめ(BASIC/VDP/OS)

  • BASIC 1.0(MSX1, 1983)


  • BASIC 2.0 / 2.1(MSX2, 1985〜)

    • ROM 32KBに拡大。
    • SCREEN 5–8 を追加(512色中16色、VRAM 64KB対応など)。
    • ハードウェアブロック転送(コピー/フィル) を V9938 の機能としてBASIC命令に対応。
    • 80桁表示モード (SCREEN 0,80) をサポート。
    • RAMディスク機能や SET PAGE による VRAMページ切替も利用可能に。

  • BASIC 3.0(MSX2+, 1988)

    • V9958 対応で 水平スクロール/YJK方式の256色モード を追加。
    • SCREEN 10–12 が利用可能になり、グラフィック性能が飛躍的に強化。
    • 日本語版では JIS第一水準漢字ROMを持つ機種も登場。

  • BASIC 4.x(MSX turbo R, 1990)

    • R800 CPU を搭載し、Z80互換+高速モードを切替可能。
    • BASIC自体は3.xからの延長だが、CPU性能とメモリマッパでDOS環境が実用的に。
    • MSX-BASIC 4.0 ではサウンド機能(PCM録音/再生)やメモリ拡張をサポート。

  • MSX-DOS2(1988〜)

    • サブディレクトリ、環境変数、ファイルハンドルベースI/Oなどを導入。
    • 64KB以上のRAMを管理するメモリマッパ対応
    • パイプ/リダイレクトなど、16bit的な操作体系を8bitに持ち込んだ。
    • APIは従来の CALL 5 互換を維持しつつ、拡張入口(0F37Dh)を追加している。

  • I/O の勘所(共通)

    • VDP: 0x98(データ)/0x99(制御)が基本。MSX2以降は拡張ポートも併用。
    • PSG: AY-3-8910 互換、ポート経由で音声・I/O(ジョイスティック)を制御。
    • PPI (8255): 0xA8〜0xAB を使用。キーボード行列スキャン、スロット制御、カセットI/O を担当。

5. 小ネタ:当時よく刺さる“実装の現実感”

  • BASIC と DOS が同一フォーマット
    MSX-DOS のファイルシステムは FAT12 を採用しており、BASICで作ったファイルを DOS 側でそのまま読み書きできるという統一設計になっていた。
    教育向けに「まず BASIC でデータを作り、それを DOS で扱う」という流れが自然に成り立ち、ホビーから実務への橋渡しを果たした。これは CP/M マシンには無かった MSX 独自の強みだった。


  • VDP転送の“待ち”
    VDP への VRAM アクセスは I/O ポート 0x98(データ)を叩いて行うが、連続書き込み時に必要な待ちサイクルは VDP の世代ごとに微妙に異なった。

    • MSX1 (TMS9918A):
      遅い VRAM バスのため、CPU が高速に OUT を繰り返すとデータが欠落する。
      NOP を挟む、または BIOS 経由の安全ルーチンを使う必要があった。

    • MSX2 (V9938) / MSX2+ (V9958):
      高速ブロック転送命令を持つが、互換性維持のため同じ 0x98 アクセスも残り、世代差を意識しないと「同じコードで速度や挙動が変わる」体験をした人も多い。
      実機派は「ループ内に NOP を入れるかどうか」で盛り上がったものだった。


  • BASICの行リストは“リンクリスト” MSX-BASIC のプログラムは RAM 上で リンクリストとして保持される。各行は以下の形式:

    1. 次の行の先頭アドレス(2バイト)
    2. 行番号(2バイト)
    3. トークン化された命令列
    4. 行末 0x00

    NEW 直後は「終端リンクのみ」の状態で、プログラムは存在しない。
    LIST や SAVE はこのポインタ列を順番にたどる仕組みで、逆に GOTO 100 などは 行番号を RAM 上のアドレスに解決して高速化している。
    これにより ASCII⇄トークンの変換ツールや逆アセンブラが成立する基盤になった。

6. 触りたくなる人向け:最短の実験ロードマップ

MSX-BASIC/MSX-DOS の内側をさらに確かめたい人に向けて、現存する一次資料と定番リソースを挙げておく。

実機を持っていなくても、エミュレータとこれらの文献があれば当時の開発体験を追体験できる。

付録:BASICワンライナ例(VDP寄り)

10 SCREEN 2: COLOR 15,1,1
20 LINE (0,0)-(255,191),15,BF:
30 FOR I=0 TO 15: LINE (I*16,0)-(I*16,191),I: NEXT

(※ 実際は VPEEK/VPoke や BASE(n),SET PAGE などMSX2系のページ機能と絡めると面白い)