石原 博の覚書

電子工作に関する日々の覚書を記載します

AVR CPMフディスクパラメタブロックの設定変更

2021-08-22 18:39:58 | 日記

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

 



最新の画像もっと見る

コメントを投稿