1ChipMSXのBIOSロード機能覚書2016年12月25日 08:06

1ChipMSXの隠し機能のBIOSロード機能の覚書。

SDカードの先頭に、MSXのBIOSを連結してファイル化したものを配置し、1ChipMSXにセットしたまま起動すると、そのSDカード上のBIOSファイルを読み込んでスロットに配置し起動する。
この際、SDカードの先頭というのはまさにFATファイルシステムのデータ領域の先頭となり、その位置はBPB(BIOS Parameter Block)の各パラメータから計算される。

具体的には、セクタ0の
&h10 (BPB_NumFATs)
&h0B (BPB_BytsPerSec)
&h0E &h0F (BPB_RsvdSecCnt)
&h11 &h12 (BPB_RootEntCnt)
&h16 &h17 (BPB_FATSz16)

から値を取得し、以下のように計算する。
BPB_ResvdSecCnt + (BPB_FATSz16 * BPB_NumFATs) + ((32 * BPB_RootEntCnt) /BPB_BytsPerSec)

この計算結果がデータ領域の先頭セクタとなる。
※BPB_BytsPerSec取得してないようにも見えるけど、512決め打ちかな?
※最後の部分は(32 * BPB_RootEntCnt + BPB_BytsPerSec -1) /BPB_BytsPerSecと説明してるページもあるんだけど、計算合わない…

で、先頭セクタの最初2バイトを読み取り、そこが"AB"だったら結合されたBIOSファイルとみなしデータ読込を実行する。

この一連の動きはDOSを経由せず、直接SDから値を読んで行われる。
FATのファイルエントリも参照していないようなのでファイル名や論理削除されているか否かもチェックしていないらしい。

と、ここまでが前提。

WindowsでSDカードを初期化すると、初期化直後に「system volume information」という隠しフォルダが自動的に生成される。
初期化直後に自動生成されるので作成位置は当然データ領域の先頭。
ということで、Windowsで初期化したSDカードは(その初期化がエクスぽローラーであろうとSDアソシエーションのSDFormatterであろうと)1ChipMSXのBIOSロード機能には使えない、みたい。
(とりあえず、自宅のWindows10で作業しているときは100%この症状になった)

じゃあ、どうすればよいかといえば、Windows以外で初期化、領域確保しWindowsを利用することなくBIOSファイルを書き込めばよい。(もしくは適当なサイズのファイルを書き込んでデータ領域の先頭を使用してしまう)

で、せっかく1ChipMSXでNextorOSが利用できるようになったのでそれを利用することに。

・SDカードを刺したまま1ChipMSXでNextorOSを起動
・BASICでCALL FDISKを実行し、SDカードを任意のパーティションサイズで初期化
・1ChipMSXの電源を一度落とし再起動
・領域確保したドライブにアクセスできることを確認したらそこに連結BIOSファイルをコピー
 (とりあえず、RAMディスク経由で別のSDカードからコピーしてみた)

この手順でデータ領域の先頭に連結BIOSファイルを配置できた。

※考えてみれば今BIOSロード機能の確認に使っているSDカード、昔の携帯に付属していた16MBのものを中のファイルを消しただけで初期化せずに使っていたものだった。
※初期化していないのでsystem volume informationは生成されているけど使用されるのはデータ領域の先頭ではなく、その時の未使用セクタの先頭になるのでかなりうしろの方。

…何か勘違いしてたらごめんなさい。

1ChipMSXのBIOSロード機能覚書 その22016年12月25日 23:17

1ChipMSXの起動時のBIOS読込機能、iplrom.vhdに埋め込まれたROMがその処理を担当しているんだけど、分らないなりにアセンブラを読んでみる。
で、忘れないように覚書。

前提
SDカードにアクセスする際はSPIモードとSDモードの2種類があるが、通常使われるのはSPIモード(SDモードはライセンス料がかかるらしい)
SPIモードでSDカードにアクセスするには初期化等の手順が必要。
SDカードとSDHCカードは初期化手順が異なる。
SDカードはCMD0→CMD1で取り敢えずアクセス可能になる?
SDHCカードはCMD0、CMD8、CMD58、ACMD41、CMD58、CMD9とコマンドを発行する、らしい。(→参考にしたページ

iplrom.vhdの中では
X"7E",X"CB",X"23",X"CB",X"12",X"CB",X"11",X"70",X"71",
X"72",X"73",X"36",X"00",X"36",X"95",X"7E",X"06",X"10",X"7E",X"FE",X"FF",X"3F",X"D0",X"10",X"F9",
X"37",X"C9",X"06",X"0A",X"3A",X"00",X"50",X"10",X"FB",X"01",X"00",X"40",X"59",X"51",X"CD",X"97",
X"FD",X"D8",X"E6",X"F7",X"FE",X"01",X"37",X"C0",X"06",X"77",X"CD",X"97",X"FD",X"E6",X"04",X"28",
X"07",X"06",X"41",X"CD",X"97",X"FD",X"18",X"05",X"06",X"69",X"CD",X"97",X"FD",X"D8",X"FE",X"01",
X"28",X"E6",X"B7",X"C8",X"37",X"C9"
このあたりがSDカードへのコマンド発行ルーチンと初期化コマンド発行部分みたい。

「MSX Z80逆アセンブラ」で逆アセンブルしてみた。
FD97 : 7E LD A,(HL)
FD98 : CB 23 SLA E
FD9A : CB 12 RL D
FD9C : CB 11 RL C
FD9E : 70 LD (HL),B
FD9F : 71 LD (HL),C
FDA0 : 72 LD (HL),D
FDA1 : 73 LD (HL),E
FDA2 : 36 00 LD (HL),#$00
FDA4 : 36 95 LD (HL),#$95
FDA6 : 7E LD A,(HL)
FDA7 : 06 10 LD B,#$10
FDA9 : 7E LD A,(HL)
FDAA : FE FF CP #$FF
FDAC : 3F CCF
FDAD : D0 RET NC
FDAE : 10 F9 DJNZ $FDA9
FDB0 : 37 SCF
FDB1 : C9 RET
FDB2 : 06 0A LD B,#$0A
FDB4 : 3A 00 50 LD A,($5000) ; BANK-4000
FDB7 : 10 FB DJNZ $FDB4
FDB9 : 01 00 40 LD BC,#$4000 CMD0
FDBC : 59 LD E,C
FDBD : 51 LD D,C
FDBE : CD 97 FD CALL $FD97
FDC1 : D8 RET C
FDC2 : E6 F7 AND #$F7
FDC4 : FE 01 CP #$01
FDC6 : 37 SCF
FDC7 : C0 RET NZ
FDC8 : 06 77 LD B,#$77 CMD55
FDCA : CD 97 FD CALL $FD97
FDCD : E6 04 AND #$04
FDCF : 28 07 JR Z,$FDD8
FDD1 : 06 41 LD B,#$41 CMD1
FDD3 : CD 97 FD CALL $FD97
FDD6 : 18 05 JR $FDDD
FDD8 : 06 69 LD B,#$69 CMD41
FDDA : CD 97 FD CALL $FD97
FDDD : D8 RET C
FDDE : FE 01 CP #$01
FDE0 : 28 E6 JR Z,$FDC8
FDE2 : B7 OR A
FDE3 : C8 RET Z
FDE4 : 37 SCF
FDE5 : C9 RET
※12/26:アドレス一部間違っていたので修正

で、実際に発行しているコマンドはCMD0、CMD55、CMD1、CMD41ということのようなので、SDカードは初期化できてもSDHCは初期化できないのではないかと想像。

OKEIさんから掲示板に頂いた「SDHCを挿入していると1ChipMSXが起動しない」という症状はこの辺が原因ではないだろうか?
Nextorは起動してしまえばSDHCアクセス可能とのことなので、NextorのSDカードドライバはSDHCを初期化できるコマンド発行していると思われる。

じゃあ、ここを直してSDHCを初期化できるようにすればSDHC挿入していてもとりあえず起動できるようになるのかな?

Nextor OS その42016年12月28日 23:46

ここに書き忘れていたけど、1ChipMSXに内蔵するNextorのROMは
Nextor-2.0.4.StandaloneASCII8.rom
ではなく
Nextor-2.0.4.MegaFlashSDSCC.rom
の方を利用し、SDカードを刺したまま起動すると、1ChipMSXのSDカードスロットが有効になる。

内蔵FDISKを利用すれば4GB以上のSDHCも利用可能。
ただし、OKEIさんがコメントしてくれたようにSDHCを刺したままでは1ChipMSXは起動しない。
一度2GB以下のSDカードを刺して起動してあとから差し替えが必要。

この動作は前エントリで書いた通り、HW的な制約ではなく、iplromに起因するSW的制約な模様。



1ChipMSXのBIOSロード機能覚書 その32016年12月28日 23:53

OKEIさんにNextorBIOSのSDカードドライバの逆アセンブルリストをいただいた。
とても分かりやすく纏められていて感動!

で、とてもいいサンプルがあるわけなので、さっそくIPLROMの改変に着手。
着手部分はSDカード初期化部分。

元のIPLROMではSDカードコマンドを
1・CMD0→CMD55→CMD41(CMD55とCMD41の組み合わせでACMD41)
もしくは
2・CMD0→CMD55→CMD1
と発行する。
どちらが実行されるかはCMD55の返値で判断されている。
おそらく、1がSDカード、2がMMC用と思われる。

で、ACMD41やCMD1は初期化処理なので初期化終了まで繰り返し発行される。

SDHCに対応するには
CMD0→CMD8→ACMD41→CMD58
と発行する必要があるみたい。

既存の初期化ルーチンにCMD8を組み込んでみたところ、動作は変わらずSDカードは起動するけどSDHCは起動途中でアクセスランプがつきっぱなしでハングした。

アクセスランプがつきっぱなしでハングということはループ抜けていないんだろうとCMD1を発行するか判断するルーチンをつぶして強制的にCMD0→CMD8→ACMD41→CMD58と発行されるように書き換えたところ、SDHCを刺したままでも1ChipMSXがブートするようにはなった。

この状態ではSDカードからのBIOSロードは機能する。しかし、SDHCからのBIOSロード機能が動かない…

どこか見落としあるのかな?




1ChipMSXのBIOSロード機能覚書 その42016年12月29日 20:30

SDHCでBIOSロード機能が働かなかった原因が判明。

IPLROMではSDからのデータリードをREAD_SINGLE_BLOCK(CMD17)で行っているんだけど、
このコマンドの引数はSDカードの時にはバイト指定だけどSDHCの時はブロック指定で
値の渡し方が違った。
※引数が4バイト(32ビット=アドレス範囲とすると4GB)の為、バイト指定ではSDHCの全域にアクセスできない。その為1ブロック=512バイトでブロック数を指定する。

試しに引数にセクタ数をそのまま渡したところ、テスト用の8GBのSDHCの先頭パーティションからBIOSロードに成功した。
※SDアクセスの1ブロック=512バイト、SDの1セクタも標準512バイト。本当はこのあたりもBPBから取得した値で計算するべきなんだろうけど…

でも、このままだと今度はSDカードからのBIOSロード機能が効かないので、その辺をどうにかできるか?

とりあえず、ベータ版