見出し画像

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

アセンブラ

今回のマシンでは機械語モニタに Universal monitor を使っており、このモニタのビルドに、Macro Assembler AS を使っています。複数のクロスアセンブラを使い分けるのは面倒なので、BIOSを書くにも、このアセンブラをそのまま使うことにしてみます。

BIOS のソースコード

以前、CP/M-8000 を移植したときは、C言語で書かれたBIOSのソースコードをアセンブリ言語に翻訳して作ったのですが、幸いにも CP/M-68K には、DISK7の中に アセンブリ言語で書かれたソースコード ERGBIOS.S が入っているので、それを参考にします。

リンク方法の確認

コンソールの入出力だけできる最低限のBIOSを作って、BIOSのリンク方法が正しいのか確認してみました。

	cpu	68000
	org	$1b000

trap3	equ	$8c
_ccp	equ	$150bc
nfuncs	equ	23

_init:
	move.l	#traphndl, trap3
	clr.l	d0
	rts

traphndl:
	cmpi	#nfuncs, d0
	bcc	    trapng
	lsl	    #2, d0
	lea.l	biosbase, a0
	movea.l	(a0, d0), a0
	jsr	    (a0)
trapng:
	rte

biosbase:
	dc.l	_init
	dc.l	wboot
	dc.l	constat
	dc.l	conin
	dc.l	conout
    : 
	dc.l	setexc

wboot:
	jmp	_ccp

constat:
	: 省略
	rts

conin:
	: 省略 
    rts

conout:
	: 省略
	rts

setexc:
	andi    #$ff, d1
	cmpi    #47,d1
	beq     noset
	cmpi	#9,d1
	beq     noset
	lsl     #2, d1
	movea.l	d1, a0
	move.l	(a0), d0
	move.l	d2, (a0)
noset:
	rts

上のコードは、かなり省略したBIOSのアセンブリコードです。
BIOSのスタートアドレスは、
    org $1b000
で指定しています。BIOSの開始は _init からで、trap 3 のベクタをtraphndl に設定します。BIOS ファンクションをコールをする場合、D0 にファンクション番号を入れて trap 3を実行すると traphndl に処理が移り、D0 の値をもとに biosbase からアドレスを引いて、それぞれのサブールチンをコールします。

もともとのERGBIOSのコードでは、biosbase からアドレスを引くのに              movea.l 6(pc, d0), a0
が使われていたのですが、Macro Assembler As では、書き方を色々試したもののアセンブルできませんでした。上のコードでは、
    lea.l biosbase, a0
    movea.l (a0, d0), a0
の2命令に書き換えています。

wboot は、
    jmp _ccp
で、CCPにジャンプするコードになっています。これで、CCP + BDOS とBIOS のリンクは大丈夫なはず。

動作を確認するため、にコンソール入出力 constat, conin, conout を書いています。この部分はマシンに依存するので省略します。

コンソール入出力を書いただけでは動作しないので、さらに、setexc を書いています。これは、BDOS をコールするための trap 2 のベクターを設定するために使われます。これは、ERGBIOSのコードそのままです。

CPM15000のバイナリを 0x15000 から、BIOS のバイナリを 0x1b000 から配置し、0x15000 から実行するとコマンドプロンプトが出て動作することが確認できます。

よくわからない Exception $03 が出ていますが、その後に、プロンプト A> が出ています。ディスク入出力のコードがまだ無いので、dir を入力しても何も起こりませんが、CCPがBISOを呼べておりリンクができていることを確認できました。


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