;       CP/M 2.0 disk re-definition library
;
;       Copyright (c) 1979
;       Digital Research
;       Box 579
;       Pacific Grove, CA
;       93950
;
;       Modified by:
;       Copyright (c) 1980
;       Robert M. White
;       H & W Computer Systems, Inc.
;       8530 Stonehaven
;       Boise, Idaho
;       83704
;
;
;       This set of macros provide necessary table
;       definitions for the use of the new BIOS
;       routines.
;
;
;               * * *  Disk Parameter Block  * * *
;       each parameter-list-i takes the form
;               dfc,ssc,nsc,bls,dks,dir,cks,ofs,xlt,[0]
;       where
;       dfc     is the Disk Format Code defined by DFOCO
;       ssc     is the physical host sector size
;                       (128,256,512,1024)
�       ns�     i� th� number of physical sectors per track
;       bls     is the data block size (1024,2048,...,16384)
;       dks     is the disk size in bls increments (word)
;       dir     is the number of directory elements (word)
;       cks     is the number of dir elements to checksum
;       ofs     is the number of tracks to skip (word)
;       xlt     is the optional Sector Translation Table adr
;                       (should be 0 if none)
;       [0]     is an optional 0 which forces 16K/directory entry
;
ddb     macro   data,comment
;;      define a db statement
       db      data            comment
       endm
;
ddw     macro   data,comment
;;      define a dw statement
       dw      data            comment
       endm
;
;
DPB     macro   dfc,ssc,nsc,bls,dks,dir,cks,ofs,xlt,k16
;;      generate the block shift value
blkval  set     bls/128 ;;number of sectors/block
blkshf  set     0       ;;counts right 0's in blkval
blkmsk  set     0       ;;fills with 1's from right
       rept    16      ;;once for each bit position
       if      blkval=1
       exitm
       endif
;;      otherwise, high order 1 not found yet
blkshf  set     blkshf+1
blkmsk  set     (blkmsk shl 1) or 1
blkval  set     blkval/2
       endm
;;      generate the extent mask byte
blkval  set     bls/1024        ;;number of kilobytes/block
extmsk  set     0       ;;fill from right with 1's
       rept    16
       if      blkval=1
       exitm
       endif
;;      otherwise more to shift
extmsk  set     (extmsk shl 1) or 1
blkval  set     blkval/2
       endm
;;      may be double byte allocation
       if      (dks) > 256
extmsk  set     (extmsk shr 1)
       endif
;;      may be optional [0] in last position
       if      not nul k16
extmsk  set     k16
       endif
;;      now generate directory reservation bit vector
dirrem  set     dir     ;;# remaining to process
dirbks  set     bls/32  ;;number of entries per block
dirblk  set     0       ;;fill with 1's on each loop
       rept    16
       if      dirrem=0
       exitm
       endif
;;      not complete, iterate once again
;;      shift right and add 1 high order bit
dirblk  set     (dirblk shr 1) or 8000h
       if      dirrem > dirbks
dirrem  set     dirrem-dirbks
       else
dirrem  set     0
       endif
       endm
;;
hstblk  set     ssc/128 ;;number of CP/M sectors
;;                      ;;      in a host sector
cpmspt  set     hstblk*nsc
                       ;;number of CP/M sectors
;;                      ;;      per track
secmsk  set     hstblk-1 ;;host sector mask
secrem  set     hstblk
secshf  set     0
       rept    8
       if      secrem=1
       exitm
       endif
;;      not complete, iterate once again
;;      shift right one position.
secrem  set     (secrem shr 1)
secshf  set     secshf+1
       endm
;;
;;
;;              generate the DPB.
       ddw     %cpmspt,<;# of CP/M sec/trk>
       ddb     %blkshf,<;block shift>
       ddb     %blkmsk,<;block mask>
       ddb     %extmsk,<;extnt mask>
       ddw     %(dks)-1,<;disk size-1>
       ddw     %(dir)-1,<;directory max>
       ddb     %dirblk shr 8,<;alloc0>
       ddb     %dirblk and 0ffh,<;alloc1>
       ddw     %(cks)/4,<;check size>
       ddw     %ofs,<;offset>
       ddb     %dfc,<;Disk Format Code>
       ddw     %ssc,<;host sector size>
       ddb     %secmsk,<;host sector mask>
       ddb     %secshf,<;host sector shift value>
       ddw     %xlt,<;Sector Xlat Table>
       endm
;
;
;               * * * Register Address w/disp * * *
rxad    macro   base,disp
       if      not nul base
       lhld    base            ;get base address.
       endif
       if      not nul disp
       push    d               ;add in disp.
       lxi     d,disp
       dad     d
       pop     d
       endif
       endm
;
;
;               * * *  Load Register w/disp  * * *
rxld    macro   reg,base,disp
       rxad    base,disp
       mov     reg,m           ;get the value.
       endm
;
;
;               * * *  Load Double Register w/disp  * * *
rxdld   macro   regpr,base,disp
       rxad    base,disp
       mov     regpr+1,m       ;get low byte.
       inx     h
       mov     regpr,m         ;get high byte.
       endm