240624 PS/55エミュ製作 [32]FDDの読み出しバグ
2HDフォーマットのフロッピーからブートすると途中でDOSのロードが止まる問題について。
いまだメモリダンプの解析方法を十分理解できていなかったのでどこで止まったのか判明していなかったけど、割り込みなどをログに残すようにして調べた結果、無効な命令を実行しようとしてハングしていたことが分かった。しかし、これだけの情報では根本的な原因は分からないのが厄介だ。ジャンプ命令で飛んできた先に正しいプログラムデータがないか、途中で他のプログラムじゃないデータが間違って上書きされたことが原因なのだろうが、なぜそれが起きたのかを突き止めないといけない。
IO.SYSのロードは完了できているようなので、前回の記事でも書いたように、DOS内の初期化ルーチンで15セクター/トラック(2HD)が9セクター/トラック(2DD)の読み取りになってしまっていることは明らかなようだ。しかし、DOS 4.0のソースコード(数か月前に公式でオープンソース化された)を読むと、この動作は想定の範囲内のようにも読める。しかし、HDDのような論理セクターでのアクセスではないから、このままでは通用しないはず。
→ MS-DOS/v4.0/src/BIOS/MSINIT.ASM at main · microsoft/MS-DOS · GitHub
;J.K. 10/9/86 If CMOS is bad, it gives ES,AX,BX,CX,DH,DI=0. CY=0.
;In this case, we are going to put bogus informations to BDS table.
;We are going to set CH=39,CL=9,DH=1 to avoid divide overflow when
;they are calculated at the later time. This is just for the Diagnostic
;Diskette which need MSBIO,MSDOS to boot up before it sets CMOS.
;This should only happen with drive B.
CMP CH,0 ; if ch=0, then cl,dh=0 too.
JNE PFR_OK
MOV CH,39 ; ROM gave wrong info.
MOV CL,9 ; Let's default to 360K.
MOV DH,1
PFR_OK:
INC DH ; MAKE NUMBER OF HEADS 1-BASED
INC CH ; MAKE NUMBER OF CYLINDERS 1-BASED
MOV NUM_HEADS,DH ; SAVE PARMS RETURNED BY ROM
AND CL,00111111B ; EXTRACT SECTORS/TRACK
MOV SEC_TRK,CL
MOV NUM_CYLN,CH ; ASSUME LESS THAN 256 CYLINDERS!!