ディスクI/Oについて
CP/M-68KのディスクI/OはCP/M-80と同じ128バイト単位の読み書きになります。やり取りに使われるメモリ空間は、CP/MのDMAアドレスに書かれています。DMAと書いてありますが、もはやDirect Memory Accessと言う意味はほとんどなく、単にディスクから読み込んだデータと書き込みたいデータのアドレスが示されるポインタ程度の意味しかありません。
今回は、1トラック分8kバイトのリードとライト用の二つのバッファを用意して、バッファリングを実現します。
参考にしたのは「インターフェース1984年1月号」です。アルゴリズムは丸パクりです。ただ、参考元のFDCはX68000のFDC(uPD72065)とは異なっていますし、今回はIOCSを利用するので、その部分は修正しました。
アルゴリズムを以下に示します。
少なくともリード用、ライト用バッファとして16kバイト確保できるメモリ量を持っている機種なら、特に68000に限らず応用できるアルゴリズムだと思います。
また、CP/M-68Kの実装例の載った他の書籍としては、「トランジスタ技術SPECIAL No.2 特集 作りながら学ぶMC68000」があります。こちらの実装の方が凝っていますので、興味があればこちらを選択するのも良いかと思います。
実際に書いたBIOSの全コードは、このシリーズの最後で載せます。
Disk Parameter Block(DPB)を書く
DPBはCP/Mでハマりやすいポイントだと思います。CP/M-80用のマクロDISKDEF.LIBを使います。
今回は、以下のようにパラメータを書きました。
DISKDEF の行が全てです。各値は以下のような意味です。
DISKDEF dn,fsc,lsc,skf,bls,dks,dir,cks,ofs
dn --- ロジカルディスク番号。
fsc --- 各トラックの最初のセクタ番号。
lsc --- 各トラックの最終セクタ番号。
skf --- セクタスキューファクター。スキューなしなら、なし。
bls --- 1データ・ブロックのサイズ(バイト数)。
dks --- システムトラックを除くディスクの全容量をbls単位で表したもの。
dir --- ディレクトリエントリの数
cks --- 書き込み用にログインされてからディスケットが交換されていないかをチェックするディレクトリエントリの数。フロッピーディスクの様にメディアを交換できるものの場合は、dirと同じ数。
ofs --- システムトラックを確保するためのオフセット数。通常は、システムトラック数を書く。
まず、値として悩むのはlscです。これは1トラックの総ロジカルセクタ数を書きます。今回は、1セクタ1024バイトで8セクタで1トラックです。1トラックの総バイト数は1024*8=8192バイトとなります。CP/Mのロジカルセクタは128バイトなので、8192/128=64となります。
blsはその1に書いたように8192バイトです。
dksはbls単位で記載します。まず、システムトラックは何トラックなのかですが、CP/M-68Kのシステムサイズは大体25kバイトです。1トラック8kバイトですから、このシステムを載せるのには最低でも4トラック必要です。その1で書きましたが、このディスクは、1024バイト/セクタ、8セクタ/トラック、77トラック、2サイドです。よって、dksは以下のような計算になります。
1024*8*((77*2 )-4) = 1228800
これをbls=8192で割ります。
1228800 / 8192 = 150
よって、dksは150となります。あとは特に説明は不要と思います。
CPMプレイヤーCPM.EXEを使って、MAC.COMにこのファイルを食わせます。すると、次のような結果が返ってきます(抜粋)。
0020+4000 DW 64 ;SEC PER TRACK
0022+06 DB 6 ;BLOCK SHIFT
0023+3F DB 63 ;BLOCK MASK
0024+07 DB 7 ;EXTNT MASK
0025+9500 DW 149 ;DISK SIZE-1
0027+7F00 DW 127 ;DIRECTORY MAX
0029+80 DB 128 ;ALLOC0
002A+00 DB 0 ;ALLOC1
002B+2000 DW 32 ;CHECK SIZE
002D+0400 DW 4 ;OFFSET
0000+= XLT0 EQU 0 ;NO XLATE TABLE
これを、BIOSの後半に転記しますが、いくつかCP/M-80とは異なっている点があります。これはサンプルのBIOSにならって適宜修正します。具体的にはdummy fillのところと、directory maskのところです。特にdirectory maskはよくわからないですが、サンプルそのまま利用しても問題ありませんでした。
これでその1で作ったディスクイメージにアクセスできます。