2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MSXのフロッピーディスクアクセス低レベルI/O(TC8566AF編)

Last updated at Posted at 2023-02-24

はじめに

MSXのフロッピーディスクアクセスは、基本的にディスク用のBIOSを介してアクセスするようにとのことで、MSX用のユーザプログラムは基本的にそのようにプログラムを作る必要があると思います。

BIOSの仕様についてはMSX Datapack wikiに記載されてませんが、MSX Resource Center の方には記載がありました。

ただし、(飽くまでも規格ではなく実態ベースで)低レベルI/Oがどうなっているのか興味があったので、blueMSXのソースコードを解析して調べた低レベルI/Oの内容を記します。

FDC Low Level I/O Map

Maker I/O method R/W or I/O range Internal H/W
Microsol System Port 0xD0〜0xD4 WD2793
National Memory Mapped 0x3F80 〜 0x3F87 WD2793
Philips Memory Mapped 0x3FF8 〜 0x3FFF WD2793
Svi328 User Port 0x30〜0x34, 0x38 WD2793
Svi707 Memory Mapped 0x3FB8 〜 0x3FBF WD2793
Svi738 Memory Mapped 0x3FB8 〜 0x3FBC WD2793
Toshiba Memory Mapped 0x3FF0 〜 0x3FFx TC8566AF

※アドレスは MOD 0x4000 です

MSX実機からBIOSを吸い出した時の 16KB の DISK.ROM がディスク BIOS のようです。

MSXの規格としてディスクI/Oの仕様が定められていないらしく、各社で色々とアクセスI/Oの仕様が異なるようですが、繋ぎ先のFDCは概ね WD2793 or TC8566AF のようです。(こちらによるとNEC μPD765 もあるようですがblueMSXの実装を眺めた限り、μPD765 の MSX 向けマッパーは見当たりませんでした)

どちらかといえば WD2793 の方がメジャー(?)のように見えますが、検証機種の BIOS が TC8566AF だったので 以下 TC8566AF の低レベルI/O仕様の調査結果 になります。

TC8566AF

Datasheet

FDC I/O

ページ1にDISK.ROMのスロットを割り当てた状態で絶対アドレス 0x7FF8〜0x7FFB へロードストア(LD)をすることで、TC8566AFのレジスタを読み書きすることができるようです。

Address R/W Feature
0x3FF8 W レジスタ2 を更新 (write only)
0x3FF9 W レジスタ3 を更新 (write only)
0x3FFA R/W レジスタ4 を参照・更新
0x3FFB R/W レジスタ5 を参照・更新

0x3FF8 - レジスタ2 - ドライブ選択 (Write Only)

Bit-7 Bit-6 Bit-5 Bit-4 Bit-3 Bit-2 Bit-1 Bit-0
? ? LED2 LED1 ? DriveId DriveId DriveId

0x3FF9 - レジスタ3 - 不明 (Write Only)

実質、何も起こらない?

0x3FFA - レジスタ4 - ステータスレジスタ (実質ReadOnly)

※FDC では更新可能になっているがTC8566AFでは更新は無視(実質ReadOnly)

Bit-7 Bit-6 Bit-5 Bit-4 Bit-3 Bit-2 Bit-1 Bit-0
RQM DIO NDM CB D3B D2B D1B D0B
  • RQM; Request for Master
    • 1: FDCがデータ受け付け中、またはデータ送信準備完了
    • 0: FDCがデータ受け取り不可、またはデータ送信準備未完了
  • DIO; Data Input/Output
    • 1: FDC→ホスト方向転送
    • 0: ホスト→FDC方向転送
  • NDM; NonDMA Mode
    • 1: FDCがNonDMAモードでデータ転送中でサービスを要求している
    • 0: FDCのサービス要求なし
  • CB; FDC Busy
    • 1: FDCがコマンドを実行中
    • 0: FDCはコマンドを受け付け可能
  • D3B〜D0B; FDD 3~0 Busy
    • 1: FDD 0〜3 がシーク中
    • 0: FDD 0〜3 がシーク中ではない

各ステータスの意味は以下から参酌しました:bow:
https://www.webtech.co.jp/company/doc/undocumented_mem/io_fdd.txt

上記は NEC μPD765 (PC-98などのFDC) ですが、ステータスレジスタの内容は TC8566AF と同じのようです。

0x3FFB - レジスタ5 - データI/O

このレジスタI/Oで、コマンドの種類とパラメタデータを書き込み後、転送データの読み書きを行います。

(1) Idle Phase

実行するコマンドの種類を書き込む

if ((value & 0x1f) == 0x06) command = CMD_READ_DATA;
if ((value & 0x3f) == 0x05) command = CMD_WRITE_DATA;
if ((value & 0x3f) == 0x09) command = CMD_WRITE_DELETED_DATA;
if ((value & 0x1f) == 0x0c) command = CMD_READ_DELETED_DATA;
if ((value & 0xbf) == 0x02) command = CMD_READ_DIAGNOSTIC;
if ((value & 0xbf) == 0x0a) command = CMD_READ_ID;
if ((value & 0xbf) == 0x0d) command = CMD_FORMAT;
if ((value & 0x1f) == 0x11) command = CMD_SCAN_EQUAL;
if ((value & 0x1f) == 0x19) command = CMD_SCAN_LOW_OR_EQUAL;
if ((value & 0x1f) == 0x1d) command = CMD_SCAN_HIGH_OR_EQUAL;
if ((value & 0xff) == 0x0f) command = CMD_SEEK;
if ((value & 0xff) == 0x07) command = CMD_RECALIBRATE;
if ((value & 0xff) == 0x08) command = CMD_SENSE_INTERRUPT_STATUS;
if ((value & 0xff) == 0x03) command = CMD_SPECIFY;
if ((value & 0xff) == 0x04) command = CMD_SENSE_DEVICE_STATUS;

(2) Command Phase

コマンドパラメタを書き込む(コマンドの種類によって何回か繰り返しwrite)

(3) Data Transfer Phase

データ読み込み or 書き込みを行う

まとめ

DISK.ROM のスロットレイアウトはページ1(0x4000〜0x7FFF)のようなので、ENASLT等で DISK.ROM が入っているスロットをページ1へ割り当て後、以下のような形でLDすればフロッピーディスクにアクセスできそうです。(※FDCがTC8566AFの機種に限る)

  • LD (0x7FF8), xx でドライブ選択
  • LD (0x7FFB), xx でコマンド選択後
  • LD xx, (0x7FFB) でデータ転送(FDC→ホスト)
  • LD (0x7FFB), xx でデータ転送(ホスト→FDC)
  • 必要に応じて LD xx, (0x7FFA) でステータスチェック

もちろん、MSX向けのソフトを書く場合は基本的にBIOS経由でコールすべきだと思います。

編集後記

低レベルI/Oの調査動機としては、自作のMSX2+エミュレータをFDD対応してみるためで、上記調査内容から無事TC8566AFエミュレータを作って対応することができました。

無事、ディスク専用のゲームが動かせる感じになりました。

ディスク専用ゲーム動作の様子1
イース2 / (C)日本ファルコム
ディスク専用ゲーム動作の様子2
英雄伝説 / (C)日本ファルコム
image.png image.png

MSX2+で対応するに当たって、ディスクBIOS(DISK.ROM)のスロット 3-2 のページ1(0x4000〜0x7FFF)に配置しているのですが(下図の DOS の部分)、
image.png
3-2のページ 0, 2, 3 を空状態(0x00で埋めた状態)にしつつ、それぞれのページアドレスの MOD 0x4000 した時の 0x3FFx を FDC レジスタへマッピングをする必要がある ようです。

この点に最初気づかず「あれ〜、起動しないな〜?」と1日ぐらい迷ってしまいましたw

MSXの規格としてディスクの存在が曖昧なので、MSX2以降はエミュレータを作ろうとすると中々大変かもしれません。ディスクに限らず(例えばV9938や拡張スロットレジスタの細かい挙動など)ドキュメント化されていない仕様や、素人目に見てどう考えてもバグのような仕様(V9938なら縦スクロールでスプライトが連動したりetc)もあり、中々楽しいです。エミュレータを書いてみると「当時のプログラマーは大変だったんだろうなぁ」と思いを馳せることができるので、中々楽しいです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?