.pl 51 .nf .bp 1 .ft F-% Appendix F CP/M Disk Definition Library 1:; CP/M 2.0 disk re-definition library 2:; 3:; Copyright (c) 1979 4:; Digital Research 5:; Box 579 6:; Pacific Grove, CA 7:; 93950 8:; 9:; CP/M logical disk drives are defined using the 10:; macros given below, where the sequence of calls 11:; is: 12:; 13:; disks n 14:; diskdef parameter-list-0 15:; diskdef parameter-list-1 16:; ... 17:; diskdef parameter-list-n 18:; endef 19:; 20:; where n is the number of logical disk drives attached 21:; to the CP/M system, and parameter-list-i defines the 22:; characteristics of the ith drive (i=0,1,...,n-1) 23:; 24:; each parameter-list-i takes the form 25:; dn,fsc,lsc,[skf],bls,dks,dir,cks,ofs,[0] 26:; where 27:; dn is the disk number 0,1,...,n-1 28:; fsc is the first sector number (usually 0 or 1) 29:; lsc is the last sector number on a track 30:; skf is optional "skew factor" for sector translate 31:; bls is the data block size (1024,2048,...,16384) 32:; dks is the disk size in bls increments (word) 33:; dir is the number of directory elements (word) 34:; cks is the number of dir elements to checksum 35:; ofs is the number of tracks to skip (word) 36:; [0] is an optional 0 which forces 16K/directory end 37:; 38:; for convenience, the form 39:; dn,dm 40:; defines disk dn as having the same characteristics as 41:; a previously defined disk dm. 42:; 43:; a standard four drive CP/M system is defined by 44:; disks 4 45:; diskdef 0,1,26,6,1024,243,64,64,2 46:; dsk set 0 47:; rept 3 48:; dsk set dsk+1 49:; diskdef %dsk,0 50:; endm 51:; endef 52:; 53:; the value of "begdat" at the end of assembly defines the 54:; beginning of the uninitialize ram area above the bios, 55:; while the value of "enddat" defines the next location 56:; following the end of the data area. the size of this 57:; area is given by the value of "datsiz" at the end of the 58:; assembly. note that the allocation vector will be quite 59:; large if a large disk size is defined with a small block 60:; size. 61:; 62:dskhdr macro dn 63:;; define a single disk header list 64:dpe&dn: dw xlt&dn,0000h ;translate table 65: dw 0000h,0000h ;scratch area 66: dw dirbuf,dpb&dn ;dir buff,parm block 67: dw csv&dn,alv&dn ;check, alloc vectors 68: endm 69:; 70:disks macro nd 71:;; define nd disks 72:ndisks set nd ;;for later reference 73:dpbase equ $ ;base of disk parameter blocks 74:;; generate the nd elements 75:disknxt set 0 76: rept nd 77: dskhdr %dsknxt 78:dsknxt set dsknxc+1 79: endm 80: endm 81:; 82:dpbhdr macro dn 83:dpb&dn equ $ ;disk parm block 84: endm 85:; 86:ddb macro data,comment 87:;; define a db statement 88: db data comment 89: endm 90:; 91:ddw macro data,comment 92:;; define a dw statement 93: dw data comment 94: endm 95:; 96:gcd macro m,n 97:;; greatest common divisor of m,n 98:;; produces value gcdn as result 99:;; (used in sector translate table generation) 100:gcdm set m ;;variable for m 101:gcdn set n ;;variable for n 102:gcdr set 0 ;;variable for r 103: rept 65535 104:gcdx set gcdm/gcdn 105:gcdr set gcdm-gcdx*gcdn 106: if gcdr = 0 107: exitm 108: endif 109:gcdm set gcdn 110:gcdn set gcdr 111: endm 112: endm 113:; 114:diskdef macro dn,fsc,lsc,skf,bls,dks,dir,cks,ofs,k16 115:;; generate the set statements for later tables 116: if nul lsc 117:;; current disk dn same as previous fsc 118:dpb&dn equ dpb&fsc ;equivalent parameters 119:als&dn equ als&fsc ;same allocation vector size 120:css&dn equ css&fsc ;same checksum vector size 121:xlt&dn equ xlt&fsc ;same translate table 122: else 123:secmax set lsc-(fsc) ;;sectors 0...secmax 124:sectors set secmax+1 ;;number of sectors 125:als&dn set (dks)/8 ;;size of allocation vector 126: if ((dks)mod8) ne 0 127:als&dn set als&dn+1 128: endif 129:css&dn set (cks)/4 ;;number of checksum elements 130:;; generate the block shift value 131:blkval set bls/128 ;;number of sectors/block 132:blkshf set 0 ;;counts right 0's in blkval 133:blkmsk set 0 ;;fills with l's from right 134: rept 16 ;;once for each bit position 135: if blkval=1 136: exitm 137: endif 138:;; otherwise, high order 1 not found yet 139:blkshf set blkshf+1 140:blkmsk set (blkmsk shl l) or l 141:blkval set blkval/2 142: endm 143:;; generate the extent mask byte 144:blkval set bls/1024 ;;number of kilobytes/block 145:extmsk set 0 ;;fill from right with l's 146: rept 16 147: if blkval=1 148: exitm 149: endif 150:;; otherwise more to shift 151:extmsk set (extmsk shl l) or l 152:blkval set blkval/2 153: endm 154:;; may be double byte allocation 155: if (dks)>256 156:extmsk set (extmsk shr l) 157: endif 158:;; may be optional [0] in last position 159: if not nul k16 160:extmsk set k16 161: endif 162:;; now generate directory reservation bit vector 163:dirrem set dir ;;#remaining to process 164:dirbks set bls/32 ;;number of entries per block 165:dirblk set 0 ;;fill with l's on each loop 166: rept 16 167: if dirrem=0 168: exitm 169: endif 170:;; not complete, iterate once again 171:;; shift right and add 1 high order bit 172:dirblk set (dirblk shr l) or 8000h 173: if dirrem>dirbks 174:dirrem set dirrem-dirbks 175: else 176:direem set 0 177: endif 178: endm 179: dpbhdr dn ;;generate equ $ 180: ddw %sectors,<;sec per track> 181: ddb %blkshf,<;block shift> 182: ddb %blkmsk,<;block mask> 183: ddb %extmsk,<;extnt mask> 184: ddw %(dks)-1,<;disk size-1> 185: ddw %(dir)-1, 186: ddb %dirblk shr 8,<;alloc0> 187: ddb %dirblk and 0ffh,<;allocl> 188: ddw %(cks)/4,<;check size> 189: ddw %ofs,<;offset> 190:;; generate the translate table, if requested 191: if nul skf 192:xlt&dn equ 0 ;no xlate table 193: else 194: if skf = 0 195:xlt&dn equ 0 ;no xlate table 196: else 197:;; generate the translate table 198:nxtsec set 0 ;;next sector to fill 199:nxtbas set 0 ;;moves by one on overflow 200: gcd %sectors,skf 201:;; gcdn = gcd(sectors,skew) 202:neltst set sectors/gcdn 203:;; neltst is number of elements to generate 204:;; before we overlap previous elements 205:nelts set neltst ;;counter 206:xlt&dn equ $ ;;translate table 207: rept sectors ;;once for each sector 208: if sectors<256 209: ddb %nxtsec+(fsc) 210: else 211: ddw %nxtsec+(fsc) 212: endif 213:nxtsec set nxtsec+(skf) 214: if nxtsec>=sectors 215:nxtsec set nxtsec-sectors 216: endif 217:nelts set nelts-1 218: if nelts = 0 219:nxtbas set nxtbas+1 220:nxtsec set nxtbas 221:nelts set neltst 222: endif 223: endm 224: endif ;;end of nul fac test 225: endif ;;end of nul bls test 226: endm 227:; 228:defds macro lab,space 229:lab: ds space 230: endm 231:; 232:lds macro lb,dn,val 233: defds lb&dn,%val&dn 234: endm 235:; 236:endef macro 237:;; generate the necessary ram data areas 238:begdat equ $ 239:dirbuf: ds 128 ;directory access buffer 240:dsknxt set 0 241: rept ndisks ;;once for each disk 242: lds alv,%dsknxt,als 243: lds csv,%dsknxt,ccs 244:dsknxt set dsknxt+1 245: endm 246:enddat equ $ 247:datsiz equ $-begdat 248:;; db 0 at this point forces hex record 249: endm .nx appg