見出し画像

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

今回は、ディスクドライブの読み書きをするコードです。ドライブを直接扱う部分は、ハードウェアごとに違うので省略します。

セクターリード

下は、1セクターをDMAに読みこむコードです。CP/Mの1セクターは128バイトですが、IDEドライブでは512バイトなので、少し工夫が必要です。

read:
	bsr   cnvlba
	cmp.l	bufdsec, d1
	beq   read1
	move.l	d1, bufdsec
	lea.l	secbuf, a0
	bsr   iderd
read1:
	move	sector, d0
	andi	#$0003, d0
	lsl	#7, d0
	lea.l	secbuf, a0
	lea.l	(a0, d0), a0
	movea.l	dma, a1
	moveq	#127, d0
read2:
	move.b	(a0)+, (a1)+
	dbf	d0, read2
	clr.l	d0
	rts

このコードでは、IDEの1セクターを、CP/Mの4セクター分にまとめて扱います。cnvlbaで、ドライブ番号、セクター番号、トラック番後から対応するLBAをもとめます。iderdで、求めたLBAセクターから512バイト、secbufに読み込みます。secbufには4セクター分のデータが格納されているので、対応する部分のアドレスをもとめて、そこからDMAに転送します。
4セクター分をsecbufにキャッシュすることになるので、前後のセクターは同じLBAの場合もありえます。その場合は、iderdをスキップしてメモリ転送だけをします。

セクターライト

write:
	bsr   cnvlba
	cmp.l	bufdsec, d1
	beq   wr2
wr1:
	move.l	d1, bufdsec
	lea.l	secbuf, a0
	bsr   iderd
wr2:
	move	sector, d0
	andi	#$03, d0
	lsl	#7, d0
	lea.l	secbuf, a0
	lea.l	(a0, d0), a0
	movea.l	dma, a1
	moveq	#127, d0
wr3:
	move.b	(a1)+, (a0)+
	dbf   d0, wr3
	bsr   flush
	clr.l	d0
	rts

セクターライトは、リードと同じ考え方で実装しています。該当するLBAセクターがsecbufにない場合は、iderdでまず読み出します。その上にDMAからのデータを転送上書きし、IDEドライブに書き戻します。
高速化するため、ドライブに書き戻すのを、違うLBAセクターが必要になるまで遅らす方法も考えられますが、今回は単純化するため見送りました。

これで終わりのはずが…

BIOSの残りの部分は比較的簡単なので、公開されているCP/M-68Kのディスクに入っているERGBIOS.Sを読めば理解できました。フルのBIOSを書いてCPM1500とつなげ、それをメモリに読み込んで実行すればCP/M-68Kが起動します。MC68000でCP/Mを動かすなら、これで終わり…だったのですが。


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