見出し画像

CP/M-68Kを移植していく Part 5

DISK I/O を書いていく

CP/Mのディスクアクセスは、ドライブ番号、トラック番号、セクター番号を指定して読み書きするCHS方式です。しかし、最近のATA対応のドライブでは、通しでつけられた32ビットの論理ブロック番号でアクセスするLBA方式です。
更に違うところがセクタサイズです。CP/Mは1セクタ128バイトですが、ATA対応のデイスクドライブでは512バイトです。
CP/Mで最近のディスクドライブを使おうとすると、このあたりの変換作業が必要になります。

どうするか?

CP/M-8000を移植した際、この辺りの知識がなかったので、かなり悩んだのですが、次のGrant氏のWEBページに解決方法が書かれていました。

この方法は、CP/Mの4セクターを、ATAの1セクターとして扱います。
そして、LBAの下位5ビットでセクター番号を表し、続く上位9ビットはトラック番号、さらに上位4ビットでドライブ番号を表します。つまり、32セクター/トラック、512トラック/ドライブということになります。
ATAでは512バイト/セクターなので、1トラックは32セクターで16384バイトになり、CP/Mの128バイト/セクターでは、128セクター/トラックということになります。
1ドライブのサイズは、512トラック × 128セクター × 128バイトで、8Mバイトになります。CP/Mで8Mバイトのディスクだとかなり贅沢な仕様です。

Disk Parameter Block

ディスクドライブのセクタ数やトラック数などパラメータは、DPMに設定します。同じパラメーターのディスクは、DPBを共有できます。
各値の詳細は、CP/M-68k System Guide に書かれています。

  • SPTは 、1トラックのセクター数で128です。

  • BSHBLMは、ブロックサイズで決まります。Grant氏フォーマットでは、ブロックサイズは4096バイトなので、BSHは5 BLMは31になります。

  • OFFは、CP/Mシステムを保存するためにディスク先頭から確保するトラック数です。今回の移植では、2トラック 32kバイトを確保します。

  • DSMは、記憶領域のブロック数 - 1 で、OFFで確保したトラック数分8ブロックは除くので、2039になります

  • EXMはブロックサイズとDSMから決まり、1になります。

  • CKSは、DRM / 4 + 1 ですが、マウントしっぱなしのハードディスクでは0で良いようです

  • DRMは、ディレクトリエントリー数 - 1で、Grant氏フォーマットでは511です。

Disk Parameter Header

各ドライブの設定はDPHに書き、接続するドライブの台数分準備します。

  • XLTには、論理ブロック番号と物理セクター番号を変換するテーブルのアドレスを入れるのですが、変換しないなら値は0です。

  • DIRBUFには、128バイトのバッファのアドレスをいれます。

  • DPBは、対応するDPBのアドレスです

  • CSVは、マウントしっぱなしのディスクの場合は、0に設定します。

  • ALVは、(DSM / 8 + 1)バイトのバッファのアドレスを設定します。今回は255バイトになりますが、偶数のほうが都合が良いので256バイトにしておきます。

dph0:
	dc.l	0	    ; XLT
	dc.w	0	    ; Scratchpad
	dc.w	0	    ; Scratchpad
	dc.w	0	    ; Scartchpad
	dc.l	dirbuf	; DIRBUF
	dc.l	dpb	    ; DPB
	dc.l	0	    ; CSV
	dc.l	alv0	; ALV

dpb:
	dc.w	128	    ; SPT
	dc.b	5	    ; BSH
	dc.b	31	    ; BLM
	dc.b	1	    ; EXM
	dc.b	0	    ; dummy
	dc.w	2039	; DSM
	dc.w	511	    ; DRM
	dc.w	0	    ; Reserved
	dc.w	0	    ; CKS
	dc.w	2	    ; OFF

ckv0:
	ds.b	128	    

alv0:
	ds.b	256	

dirbuf:
	ds.b	128

いいなと思ったら応援しよう!