2012.4.6
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第83回]

●BIOSの変更

前回からの続きです。
変更箇所は大きく分けて2つになります。
1つはデイスクドライブに関する定義をしているところです。
もう1つはディスクドライブをアクセスしているBIOSルーチンの変更です。

まず最初にディスクドライブの定義部分を変更します。
現行のCP/Mソースプログラムは、[第76回]で作成したCPM22J.TXTです。
それをもとにして、CPM22K.TXTを作ります。

●ディスクドライブの定義部分の追加と変更

1)CSV、ALVの追加と変更

ディスクサイズの変更とBドライブの追加にともない、CSV(チェックサムベクタ)とALV(アローケーションベクタ)を追加および変更します。
下左が変更前(CPM22J.TXT)で下右が変更後(CPM22K.TXT)です。



変更前の

CSV00 EQU 0B880H
ALV00 EQU 0B888H

を、下のように追加、変更します。

CSV00 EQU 0B880H
ALV00 EQU 0B884H
CSV01 EQU 0B886H
ALV01 EQU 0B88AH

CSV01、ALV01はBドライブのために追加しました。
CSV、ALVについては[第33回]で説明をしていますので、そちらを参照願います。
今回の変更により、ディレクトリは4セクタ、ブロック数は12になりました。

2)ディスクパラメータの追加と変更

ディスクパラメータの追加と変更を行ないます。
下左が変更前で下右が変更後です。



まずはdrive No.1を追加します。
drive No.0の記述の下に、以下のようにdrive No.1の記述を追加します。

;drive No.1(b drive)
DEFW 0
DEFW 0
DEFW 0
DEFW 0
DEFW DIRBF
DEFW DPTOP
DEFW CSV01
DEFW ALV01

最後のCSV01とALV01だけが、drive No.0と異なっていることに注意してください。

次にディスクパラメータを変更します。
ディスクサイズ、ディレクトリサイズを小さくしたための変更です。
変更するのは次の3箇所です。

DEFW 23
DEFW 31
DEFW 0C0H

を、下のように変更します。

DEFW 11
DEFW 15
DEFW 80H

最初の数値は、ブロック数が24−1から半分の12−1になったことによる変更です。
2番目の数値はディレクトリサイズが8セクタから4セクタになったことで、FCB数4×8−1=31から4×4−1=15に変更になります。
最後の数値は、ディレクトリが2ブロックから1ブロックになったため、ディスク先頭からの位置が、ビットマップで11000000(C0H)から10000000(80H)に変更になります。

各パラメータの意味と数値の根拠については[第12回][第13回]で説明をしていますので、そちらも参照してください。

●BIOSルーチンの変更

Bドライブの追加によってBIOSルーチンも変更が必要になります。

●Bドライブの先頭アドレスを定義する

BドライブのRAM上での先頭アドレスを追加します。



DISKTOP EQU 8800H

の下に、次の行を追加します。

DISKTOP2 EQU 0A000H

●リブートルーチンの変更(Cレジスタをクリア)

ファンクションコール0Eのテストを進めていくなかで見えてきたことがあります。
カレントドライブ(カレントディスク)がどのように決められるのか、というあたりにちょいと疑問があったのですが、おそらくその解明に関係していると思われる動作です。
本来のCP/Mでは、リブートしたとき、カレントドライブはAドライブになります。
この場合AドライブにはCP/Mシステムディスクが装着されている必要があります。
そしてそのシステムディスクからCP/Mシステムプログラムの一部がメモリに再ロードされます。

しかし、今作業中のCP/M仮システムでは、AドライブにはCP/Mシステムはありません。
ZB3BASICシステムにエントリしたときに、必要ならばWindowsのハードディスクから、CP/Mシステムプログラムをロードしてから、BIOSのエントリルーチン(リブートルーチン)にジャンプします(この仕組みは将来は変わるかも知れません)。

そのため、リブートしてもAドライブをセレクトすることは意識していませんでした。
でもいつもCP/Mを起動すると、最初にAドライブが選択されていました。
今回、Bドライブを追加したことによって、そのテストをしていくなかで、CP/M起動時にAドライブが選択されていたのは「たまたま」そうなっていたに過ぎない、ということがわかりました。

こういうところがプログラミングの恐いところです。
「たまたま」動いてしまうことがよくあるのですよねえ。
それでデバッグ完了、のつもりになって納入すると、ユーザーのところにいってから、信じられないような、有り得ない誤動作が発生して悩んでしまう、などということがおこります。

今回もBドライブを追加してからテストをしましたら、
むむむ。おかしいではないか?
という事態が発生してしまいました。

ある条件でリブートすると、Aドライブが選択されません。
でもCP/M起動時のBIOSのリブートルーチンは全く同じように実行されています。
あらためてCP/Mのエントリ部分のソースプログラムを調べてみて、納得いたしました。

CP/Mはエントリ時にCレジスタの値をチェックしていたのです。
Cレジスタの上位4ビットにはユーザー識別No.があって、下位4ビットがカレントドライブbノなっているようです。

現行のBIOSのリブートエントリールーチンを確認しましたら、Cレジスタは全くさわっておりませんでした。
ZB3BASICからCP/Mにジャンプするときに、ZB3BASICのコマンド処理ルーチンの中でCレジスタがクリアされていたようです。
Cレジスタの値が00のときにAドライブが選択され、01のときにBドライブが選択されます(以下同様にして、02ならCドライブ、03ならDドライブ…が選択されます)。
[注記]Cレジスタの上位4ビットはユーザーbナすが、ユーザーによる使い分けは考えないことにしますから、それは0にしておきます。

そこで、BIOSリブートルーチンに、Cレジスタクリアを追加します。



JP CBASE の前に、
LD C,A
を追加します。

●HOMEルーチンの変更

ホームポジションへのスキップルーチンもAドライブだけに対して行なっていたところを、Bドライブに対しても行なうように変更します。



CPM22J.TXT(上図左側)の以下の部分を

HOMEJ:	LD HL,DISKTOP
	LD (TRKADRS),HL
	LD (SCTADRS),HL
	XOR A
	RET

次のように変更します。

HOMEJ:	LD HL,DISKTOP
	LD A,(DRVNO)
	OR A
	JP Z,HOMEJ2
	LD HL,DISKTOP2
HOMEJ2:LD (TRKADRS),HL
	LD (SCTADRS),HL
	XOR A
	RET

●SELDSKルーチンの変更

ディスクドライブセレクトルーチンも大きく変わります。



CPM22J.TXT(上図左側)の以下の部分を

SELDSKJ:LD HL,DPBASE
	LD A,C
	LD (DRVNO),A
	RET

次のように変更します。

SELDSKJ:LD HL,0
	LD A,C
	CP 02
	RET NC
	LD (DRVNO),A
	LD L,A
	ADD HL,HL;*2
	ADD HL,HL;*4
	ADD HL,HL;*8
	ADD HL,HL;*16
	LD DE,DPBASE
	ADD HL,DE
	RET

Cレジスタ=00(Aドライブ)、Cレジスタ=01(Bドライブ)のときは、それぞれのディスクパラメータアドレスをHLレジスタに入れます。
それ以外のドライブbェ指定されたときはHLレジスタに0を入れてリターンします。

●SETTRKルーチンの変更

トラックアドレスのセットルーチンもAドライブだけに対して行なっていたところを、Bドライブに対しても行なうように変更します。



CPM22J.TXT(上図左側)の以下の部分を

SETTRKJ:LD HL,DISKTOP
	LD DE,800H
	INC C
STTRK1:	DEC C
	JP Z,STTRK9
	ADD HL,DE
	JP STTRK1
STTRK9:LD (TRKADRS),HL
	XOR A
	RET	

次のように変更します。

SETTRKJ:LD HL,DISKTOP
	LD A,(DRVNO)
	OR A
	JP Z,SETTRKJ2
	LD HL,DISKTOP2
SETTRKJ2:LD DE,800H
	INC C
STTRK1:	DEC C
	JP Z,STTRK9
	ADD HL,DE
	JP STTRK1
STTRK9:LD (TRKADRS),HL
	XOR A
	RET	

以上で変更作業は終了です。
名前をCPM22K.TXTに変更して保存します。

●アセンブル

CPM22K.TXTをZASM.EXEでアセンブルして、CPM22K.BINを作成します。



これでやっと準備ができました。
いよいよファンクションコール0Eのテストにかかるわけですが、本日はちょっと時間がありません。
この続きは次回に説明することにいたします。

ワンボードマイコンでCP/Mを![第83回]
2012.4.6upload

前へ
次へ
ホームページトップへ戻る