CP/Mの入手
cpm2-asm.zipと、cpm2-plm.zipを入手する。
CBIOS.ASMをZ80表記にする。
CBIOS.ASMはcpm2-plmのディレクトリ内にある。まずTOZ.EXEを入手する。ターミナル画面からMS-DOS playerを使って以下のように入力する。
> msdos.exe TOZ.EXE CBIOS
これでZ80表記のCBIOS.MACが生成される。CBIOS.Z80とかにリネームすると便利。
CP/Mシステムソースコードを修正する
cpm2-asmディレクトリの中にあるCPM22.Z80はアセンブラによってはエラーが出るので修正する。
1284行の以下の文を、21行目のTBASE~の下に挿入する。
NFUNCTS EQU 41
367行目の以下の文を修正する。
JP NZ,HALT
↓
JP NZ,HLT
674行目の以下の文を修正する。
HALT: LD HL,76F3H
↓
HLT: LD HL,76F3H
2043行目の以下の文を修正する。
CHKSUM1:ADD A,M
↓
CHKSUM1:ADD A,(HL)
3705行目の以下の文を修正する。
CKSUMTBL: DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
↓
CKSUMTBL: DEFW 0
DEFB: 0,0,0,0,0,0,0,0,0,0,0,0,0,0
3709行目の以下の文を修正する。
DEFB 0,0,0,0
↓
DEFB 0
ZASM.EXEはHEX出力なので、BINに変換する必要がある。hex2bin.exeで変換できる。
AILZ80ASM.EXEを使う場合
更に、WindowsネイティブなアセンブラであるAILZ80ASM.EXEを利用するためには、以下の修正を行う。
2169行目、3341行目、3344行目の以下の文を修正する。
SBC A,M
↓
SBC A,0
更に先ほど変更した3705行目を更に変更する(DEFBの次の「:」を取る)。
CKSUMTBL: DEFW 0
DEFB: 0,0,0,0,0,0,0,0,0,0,0,0,0,0
↓
CKSUMTBL: DEFW 0
DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0
これで、AILZ80ASM.EXEでも動作するアセンブラリストになる。またAILZ80ASM.EXEはオプションでBIN出力があるので、ZASM.EXEよりも作業が一つ減る。
このバイナリで実行するとディスク周りにバグが入ります。問題ないことを確認しました。
CP/Mのメモリモデルの選択
20Kモデルなら、CPM22.Z80の14行目の以下の文のようにする。
MEM EQU 20
まずは20KBモデルを選択する方が無難。より大きなモデルにするのは簡単。
BIOSを書く
ディスクread/writeルーチンは、DMA転送なしのバージョンを単体の機能だけのプログラムを書いて、うまく動いたら、次にDMA転送ありで書くと着実。最後にCP/Mに実装する。
hstbufアドレスとDMAが利用するI/Oバッファアドレスを一致させる
DMACが読み書きするメモリエリア(I/Oバッファ)の位置に注意。このI/Oバッファのアドレスは、CP/Mのホストアドレスバッファhstbufに一致させる必要がある。これをやらないと、ディスクデータとCP/M間でデータのやり取りができなくて、DIRコマンドの出力が全て空欄になる。
5230 erflag: DS 1 ;error reporting
5231 rsflag: DS 1 ;read sector flag
5232 readop: DS 1 ;1 if read operation
5233 wrtype: DS 1 ;write operation type
5234 dmaadr: DS 2 ;last dma address
5236 hstbuf: DS hstsiz ;host buffer
この最下行のhstbufのアドレスとDMAコマンドチェーンの36H,52Hは同じである必要がある。書き込み時のDMAコマンドチェーンも同様。
DMA_COMMANDS:
DB 15H,0C3H,0C3H,0C3H,0C3H,03CH,0C3H
DB 0BBH,01H,9BFH
DB 6DH
DB 0C3H,0FFH,00H,02CH,010H,08DH
DB 36H,52H ; this address is hstbuf address !!!!
DB 9AH
DB 0CFH,87H
蛇足だが、hstbufのアドレスの確認はアセンブル時にlistファイルの出力をONにしておき、 listファイルを確認して行う。つまり、確認の為に一度アセンブルし、DMAのI/Oバッファアドレスを修正してもう一度アセンブルする必要がある。
CP/MでDMAというと関連書籍やソースコードで80H番地をよく見るが、内部的に使っているだけなのでBIOSを書くうえでは無視して良い。
ブロッキング/デブロッキング実装のタイミング
個人的には、まずは単密度(128バイト/セクタ)でディスクイメージを作って、ブロッキング/デブロッキングなしで、一度移植を行なって問題なく動いたら、その後、倍密度(256バイト/セクタ)でブロッキング/デブロッキングを実装するのが理想と思われる。