CP/Mを幾つか動作させ、アプリケーションもいろいろ試してみた。しかしディレクトリの階層構造がないのは辛い。
A:に基本的なコマンドを入れ、B:〜に実験するプログラムを入れるとして、理論上はB〜Pまで15のフォルダが作れるとはいうものの、出来合いのBIOSではせいぜいB:、C:ぐらいまで。microSDの容量はCP/Mの世界から見ればとんでもなく大きく、使わないのはもったいないので出来るだけ使うことにした。
ただしAVRCPMでは、dsk_fsys.asmで以下の定義があり、A〜Hまでしか出来ない
.equ MAXDISKS = 8 ;Max number of Disks (partitions)
変更箇所はipl.asm, bios.asm, dsk_fsys.asm, dskdefs。ただしbiosが大きくなりすぎた場合はCPM.SYSも変更する必要が出る。ドライブを増やすとアロケーションベクタが増えるため得策ではない。そこで8ドライブで十分と考えた。
他の領域を増やす方法としてはuserコマンドがある。user 0 や user 1 としてユーザを切り替えて使用することが出来る(0〜15の16ユーザまで可能)。これだと1つのドライブに複数ユーザ分の領域を取ることが出来る。ところが登録出来るファイル数を超えると「NO DIRECTORY SPACE」というエラーとなる。そのためディレクトリエントリも増やしておきたい。
以前はneko Javaさんの「CP/Mディスクイメージ作成手順メモ」http://star.gmobb.jp/koji/cgi/wiki.cgi?page=CP%A1%BFM%A5%C7%A5%A3%A5%B9%A5%AF%A5%A4%A5%E1%A1%BC%A5%B8%BA%EE%C0%AE%BC%EA%BD%E7%A5%E1%A5%E2
を参考にディスクを作成したのだが、今回は必要な設定を調べるため、複数のCP/MのBIOSからディスクパラメタブロック(DPB)を抽出しリスト化した(標準8inch、AVR-CP/M(RAMディスクとneko Javaさん記載のもの)、z80-mbc2、multicomp、Z80pack-1.36)
・Z80-MBC2やmulticompのDSMが2047ではなく2043、コメントが .DW 2043 ;(2047-4) DSM - Storage size (blocks - 1)となっているので意図的
・Z80-MBC2のAllocation Vector(256じゃなくて257?)
が理解出来ない。
今回の場合はちょうどZ80pack-1.36のHDBLKが使えそう。ディレクトリエントリ数も最大1024まである。このままではシステム領域がないのでオフセットを1と変更して使用しよう。
修正ポイント
[1]ipl.asm
トラック0のセクタ0はIPLが入っている。セクタ1〜44までの44トラック(5.6KB)はCCP, BDOSが使用。セクタ45〜127までの83トラック(10KB)はBIOSが使えることになる。とはいうもののBIOSが大きくなるとCP/Mの大きさも変える必要がある(CPM.SYSの作り変えを伴う)
; CCP BIOS BIOSの容量 BIOSに許されるセクタ数
; 56K CP/M c400 da00 9.7KB 76
; 58K CP/M cc00 e200 7.6KB 60
; 60K CP/M d400 ea00 5.6KB 44
; 62K CP/M dc00 f200 3.5KB 28 <-- 以下のBIOSは約2.9KBのため、これが使える
; 64K CP/M e400 fa00 1.5KB 12
今回の例では約8MBの8ドライブで、アロケーションベクタだけでも255x8=2KBは必要になるが、BIOSはトータル2.9KBとなるため、62K CP/M版のCPM.SYSが使える。
> ld b,72 ;44(CCP+BDOS)+28(BIOS)=72
> ld de,$0001 ;d=trk e=sec ;ここではセクタは0オリジンなので注意
> ld hl,$dc00 ;CCP
[2]bios.asm
デイスクを大容量化し、8ドライブ+RAMドライブ1とする。
drvtbl: ;9drive
dw dpha
dw dphb
dw dphc
dw dphd
dw dphe
dw dphf
dw dphg
dw dphh
dw dphi
;
dpbrd: ;ram disk
dw 32 ;sec per track
db 3 ;block shift BSH 1028=128*(2^3)
db 7 ;block mask BLM 1028/128-1=7
db 0 ;extnt mask EXM
dw 55 ;disk size-1 DSM 128*32*(16-2)/1024-1=55
dw 31 ;directory max DRM 2*16-1
db 128 ;alloc0
db 0 ;alloc1
dw 0 ;check size CKS (DRM+1)/4=(31+1)/4=8 取り外し不可のため0
dw 2 ;offset
;
hdblk:
dw 128 ;sec per track
db 4 ;block shift BSH 2048=128*(2^4)
db 15 ;block mask BLM 2048/128-1=15
db 0 ;extnt mask EXM
dw 2039 ;disk size-1 DSM 255*128*128/2048-1=2039
dw 1023 ;directory max DRM 256*128/32-1=1023
db 255 ;alloc0
db 255 ;alloc1
dw 0 ;check size 取り外し不可のため0
dw 1 ;offset
;
dpha:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv0
dphb:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv1
dphc:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv2
dphd:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv3
dphe:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv4
dphf:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv5
dphg:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv6
dphh:
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,hdblk ;dir buff,parm block
dw 0
dw alv7
;
dphi: ;ramdisk
dw 0000h,0000h ;no translate table
dw 0000h,0000h ;scratch area
dw dirbuf,dpbrd ;dir buff,parm block
dw 0
dw alv8
;
[3]dsk_fsys.asm
AVR-CPMのエミュレータ側だが、ここでもディスクの定義が必要
dpbdat_avrcpm: ;
.db 0x00,128 ;sector offset, low(spt)
.db 0x00,4 ;high (spt), block shift
.db 15,0x00 ;bock mask, extent mask
.db 0xF7,0x07 ;disk size - 1,
.db 0xFF,0x03 ;dir max
.db 0xFF,0xFF ;alloc0, alloc1
.db 0x00,0x00 ;chk size
.db 0x01,0x00 ;offset
[4]diskdefs
ディスク内容を生成するための定義も変更が必要
# HDBLK -----------------
diskdef HDBLK
seclen 128
tracks 255
sectrk 128
blocksize 2048
maxdir 1024
skew 1
boottrk 1
os 2.2
end
ちなみにこれを利用して、以下のシェルスクリプトでコンテンツを作成(contentsフォルダ内にAからHのディレクトリを作成(ドライブ相当)、その下に0〜15のディレクトリを作成(ユーザ相当)している。これはRunCPMで使用されている構造と同じ)
===コンテンツ作成シェルスクリプト===
#62K CP/M CCP BIOS
# DC00 F200
# F200-DC00=1600 $1600=5632 5632/128=44sector
# 10000-F200=e00 ->28sector
dd conv=sync bs=128 count=1 if=ipl.bin > cpm.bin
dd conv=sync bs=128 count=44 if=cpm.sys >> cpm.bin
dd conv=sync bs=128 count=28 if=bios.bin >> cpm.bin
echo make contents
#255track 128sector/track 128byte/sec
drive=( A B C D E F G H )
b=16384
c=255
for d in ${drive[@]}; do
dd conv=sync bs=${b} count=${c} if=/dev/zero > CPMDSK_${d}.IMG
if [ ${d} = "A" ]; then
mkfs.cpm -f HDBLK -b cpm.bin -L DRIVE_${d} CPMDSK_${d}.IMG
else
mkfs.cpm -f HDBLK -L DRIVE_${d} CPMDSK_${d}.IMG
fi
for i in `seq 0 15`; do
if [ -d contents_folder/${d}/${i} ]; then
cpmcp -f HDBLK CPMDSK_${d}.IMG contents_folder/${d}/${i}/*.* ${i}:
echo ${d} ${i}
fi
done
done
※コメント投稿者のブログIDはブログ作成者のみに通知されます