MC6800 ROMモニタ自作 その13 番外編 〜SBC-IOとSDカード拡張を考える〜

MC6800 ROMモニタMC6800 ROMモニタ自作 その13 番外編 〜SBC-IOとSDカード拡張を考える〜

前回までで、ROM モニタはだいぶ実機で使いやすくなってきました。DMGLBRUF あたりがそろってくると、小さいプログラムを書いて、ロードして、止めて、見るところまでは回せます。

そうなると次に欲しくなるのは、やはり保存先です。今は PC からシリアルで S-Record や Intel HEX を流し込めますが、独立した MC6800 マイコンとして考えると、SD カードからプログラムを選んでロードしたくなります。

今回は実装回ではなく、番外編として SD カードと FAT32 をどうつなぐかを考えました。元になった検討は、GitHub の Issue #38 にまとめています。

SBC-IO は、MC6821 PIA や RAM 拡張を載せられる I/O 拡張基板です。こちらの記事を前提にしています。

今回考えたこと

今回考えたのは、大きく分けると次の 4 つです。

  • MC6821 PIA のビットバング SPI で SD カードを読めるか
  • MC6800 側で FAT32 の DIRLOAD をできるか
  • ROM を小さくするために、SD カードから第2段を bootstrap できるか
  • 外付けマイコンへ SD/FAT 処理を逃がすべきか

最初から FAT32 の read/write を全部 ROM に入れるのは、さすがに重そうです。ROM は $E000-$FFFF の最大 8KB まで見られますが、モニタ本体、MIKBUG 互換入口、既存ローダ、エラー処理を残したまま、SD 初期化、FAT32、SAVE まで全部入れるのは厳しいです。

なので、初期実装は SDHC、FAT32、512 バイト sector、8.3 filename、単一 volume、root directory、read-only、同時 open は 1 ファイルだけに絞ります。

`DIR
LF TEST.S
LF TEST.HEX`

SBC6800 + SBC-IO + SDカードの構成

まずは素直に、SBC-IO 上の MC6821 PIA を GPIO 的に使い、SD カードの SPI 信号を作る案です。

SBC6800 に SBC-IO をつなぎ、MC6821 PIA のポートで SD カードの SPI 信号を作る案

SD カードは 3.3V デバイスなので、5V 系の MC6800/PIA とはレベル変換が必要です。SPI としては Mode 0 で、初期化時は 100kHz から 400kHz 程度に抑えます。

PIA で SPI 信号を作ること自体はできそうです。ただし、1 ビット送るたびに PIA レジスタを read/write するので、512 バイト sector を読むだけでも 4096 クロック分のビット操作が必要になります。

メモリマップをどう使うか

ROM は $E000-$FFFF、SD/FAT driver や sector buffer は RAM 拡張時の $C000-$DFFF を候補にする

今の 8KB RAM だけだと、モニタ作業領域、スタック、ロード先、sector buffer を同時に置くのは窮屈です。SBC-IO で RAM を 32KB 以上へ拡張できるなら、$C000-$DFFF の 8KB を SD/FAT 用の buffer や driver に使えるとかなり楽になります。

MC6800だけでFAT32を読む案

MC6800 + PIA だけで FAT32 をフルに扱うのは大変です。ただ、用途をかなり絞れば、不可能ではなさそうです。

初期目標は、PC で普通に FAT32 として見える SD カードから、root directory のファイル一覧を出して、S-Record / Intel HEX をロードすることです。

  • LFN entry
  • 削除済み entry
  • volume label
  • subdirectory
  • system / hidden 属性

これらは初期実装ではスキップします。Windows で普通に日本語ファイル名や長いファイル名を置くと、LFN entry が作られます。初期実装ではそれを読まないので、SD カード上のファイル名は TEST.SBASIC.S のような 8.3 名に寄せる必要があります。

SDFS.BINとAUTOEXEC.S

ROM に全部入らない場合は、SD カードから第2段を RAM へロードする案があります。初期実装では subdirectory をサポートしない前提なので、第2段本体は root directory の SDFS.BIN に固定します。ただし、ROM が root directory から SDFS.BIN を直接探す案は、BPB、root cluster、directory entry、FAT chain の最小処理が必要になります。reserved sector bootstrap 案では、ROM は専用ツールで検証済みの第1段 bootstrap を読むところまでに寄せ、root の SDFS.BIN 探索は第1段側へ逃がす分担になります。

ROM直FAT案では ROM が root の SDFS.BIN を探し、reserved bootstrap案では第1段が SDFS.BIN 探索を担当する

AUTOEXEC.S は、いわゆる DOS の AUTOEXEC.BAT 的な位置づけです。RTC 読み出し、MC6847 画面初期化、キーボード初期化、BASIC 起動、モニタ拡張パッチなどを入れられると便利そうです。

reserved sector bootstrap案

FAT32 には boot sector、FSInfo、backup boot sector などを置く reserved region があります。通常の Windows ファイルコピーでは、ここはファイル領域として使われません。なので、専用ツールでこの領域に第1段 bootstrap を書いておけば、ROM は検証済みの候補 sector から第1段を RAM へ持ってこられます。

ただし、reserved sector は空き領域ではなく、FAT32 の管理領域です。boot sector、FSInfo、backup boot sector、フォーマッタごとの予約領域の使い方と衝突しない保証が必要です。Windows で普通にファイルコピーするだけなら壊れにくいですが、format、chkdsk、ディスク管理ツール、boot sector 修復などで書き換えられる可能性があります。

外付けマイコン案

初期は ROM直FAT read-only、将来は外部MCUも検討する。方式ごとに FAT を読む主体が異なる

外付けマイコンを使う案は、block device MCU と FAT MCU の 2 段階で考えると整理しやすいです。block device MCU は SD カードの初期化、sector read/write、timeout、busy 待ちを担当します。ただし FAT 更新の責務は MC6800 側に残るので、SAVE がすぐ簡単になるわけではありません。FAT MCU は DIROPENREADWRITECLOSE まで担当します。

FAT MCU の本命候補は Raspberry Pi Pico / RP2040 系です。ATmega328P や CH32V003 は 2KB SRAM が厳しいため、block device MCU や簡易 read 補助寄りに見るのがよさそうです。

当面の結論

  1. PIA 直結で SD カードの SPI 初期化を確認する
  2. CMD17 で固定 LBA の 512 バイト sector read を確認する
  3. FAT32 BPB を読み、root directory をたどる
  4. DIR で 8.3 ファイル名とサイズを表示する
  5. LF TEST.S / LF TEST.HEX で既存ローダへ stream 入力する
  6. 必要なら SDFS.BIN を第2段として RAM へロードする
  7. SAVE や安定運用が必要になったら外部 MCU 案を検討する

PIA 直結は遅いと思います。それでも、read-only の DIRLF に絞れば、MC6800 だけで FAT32 の SD カードからプログラムをロードする線は残せそうです。

まずは、ロジックアナライザで PIA の SPI 信号を見て、SD カードが CMD0CMD8 に応答するところから始めるのがよさそうです。

関連リンク

MC6800 ROMモニタSBC6800