title Kaypro 4-83 Resident Software Package subttl Deblocking ; extrn denflag, sekdsk, seksec, sektrk extrn move extrn rd, readhst extrn wrt, writehst ; entry read, write, setdma ; entry hstdsk, hsttrk, hstsec, hstbuf entry hstwrt, hstact, unacnt, erflag ; dseg ; ; Disk deblocking etc. hstdsk: ds 1; host disk number hsttrk: ds 2; host track number hstsec: ds 1; host sector number sekhst: ds 1; seek shr secshf hstact: ds 1; host active flag hstwrt: ds 1; host written flag unacnt: ds 1; unallocted record count unadsk: ds 1; last unallocated disk unatrk: ds 2; last unallocated track unasec: ds 1; last unallocated sector erflag: ds 1; error reporting rsflag: ds 1; read sector flag readop: ds 1; 1 if read operation wrtype: ds 1; write operation type dmaadr: ds 2; current DMA address hstbuf: ds 512; deblocking buffer ; ; cseg ; ;***************************************************** ;* Logical BIOS entry points * ;* Sector Deblocking Algorithms * ;***************************************************** blksiz equ 1024 ;CP/M allocation size hstsiz equ 512 ;host disk sector size hstspt equ 10 ;host disk sectors/trk hstblk equ hstsiz/128 ;CP/M sects/host buff cpmspt equ hstblk * hstspt ;CP/M sectors/track secmsk equ hstblk-1 ;sector mask secshf equ 2 ;log2(hstblk) sector mask wrall equ 0 ;write to allocated wrdir equ 1 ;write to directory wrual equ 2 ;write to unallocated ; ; -------------------------------------------------------- ; ; set current dma address setdma: ld (dmaadr),bc; set dma address given by BC ret ; ; read selected logical sector read: ld a,(denflag); read the selected CP/M sector or a ld hl,(dmaadr) ex de,hl ld b,1; sector record jp nz,rd; single density read into dmaadr xor a; a patch by DRI ld (unacnt),a ld a,1 ld (readop),a; read operation ld (rsflag),a; must read data ld a,wrual ld (wrtype),a; treat as unalloc jp rwoper; to perform the read ; ; write selected logical sector write: ld a,(denflag); write the selected CP/M sector or a ld hl,(dmaadr) ex de,hl ld b,1; sector record jp nz,wrt; single density write from dmaadr xor a; 0 to accumulator ld (readop),a; not a read operation ld a,c; write type in c ld (wrtype),a cp wrual; write unallocated? jp nz,chkuna; check for unalloc ; " " ; write to unallocated, set parameters ld a,blksiz/128; next unalloc recs ld (unacnt),a ld a,(sekdsk); disk to seek ld (unadsk),a; unadsk = sekdsk ld hl,(sektrk) ld (unatrk),hl; unatrk = sectrk ld a,(seksec) ld (unasec),a; unasec = seksec ; " " ; check for write to unallocated sector chkuna: ld a,(unacnt); any unalloc remain? or a jp z,alloc; skip if not ; " " ; more unallocated records remain dec a; unacnt = unacnt-1 ld (unacnt),a ld a,(sekdsk); same disk? ld hl,unadsk cp (hl); sekdsk = unadsk? jp nz,alloc; skip if not ; " " ; disks are the same ld hl,unatrk call cpsktrk; sektrk = unatrk? jp nz,alloc; skip if not ; " " ; tracks are the same ld a,(seksec); same sector? ld hl,unasec cp (hl); seksec = unasec? jp nz,alloc; skip if not ; " " ; match, move to next sector for future ref inc (hl); unasec = unasec+1 ld a,(hl); end of track? cp cpmspt; count CP/M sectors jp c,noovf; skip if no overflow ; " " ; overflow to next track ld (hl),0; unasec = 0 ld hl,(unatrk) inc hl ld (unatrk),hl; unatrk = unatrk+1 ; " " ; match found, mark as unnecessary read noovf: xor a; 0 to accumulator ld (rsflag),a; rsflag = 0 jp rwoper; to perform the write ; ; not an unallocated record, requires pre-read alloc: xor a; 0 to accum ld (unacnt),a; unacnt = 0 inc a; 1 to accum ld (rsflag),a; rsflag = 1 ; " " ; * Common code for READ and WRITE follows *; ; enter here to perform the read/write rwoper: xor a; zero to accum ld (erflag),a; no errors (yet) ld a,(seksec); compute host sector or a; carry = 0 rra; shift right or a; carry = 0 rra; shift right ld (sekhst),a; host sector to seek ; " " active host sector? ld hl,hstact; host active flag ld a,(hl) ld (hl),1; always becomes 1 or a; was it already? jp z,filhst; fill host if not ; " " ; host buffer active, same as seek buffer? ld a,(sekdsk) ld hl,hstdsk; same disk? cp (hl); sekdsk = hstdsk? jp nz,nomatch ld hl,hsttrk; same disk, is it same track? call cpsktrk; sektrk = hsttrk? jp nz,nomatch ; " " same disk, same track, same buffer? ld a,(sekhst) ld hl,hstsec; sekhst = hstsec? cp (hl) jp z,match; skip if match ; " " ; proper disk but not correct sector nomatch: ld a,(hstwrt); host written? or a call nz,writehst; clear host buff ; " " ; may have to fill the host buffer filhst: ld a,(sekdsk) ld (hstdsk),a ld hl,(sektrk) ld (hsttrk),hl ld a,(sekhst) ld (hstsec),a ld a,(rsflag); need to read? or a call nz,readhst; yes, if 1 xor a; 0 to accum ld (hstwrt),a; no pending write ; " " ; copy data to or from buffer match: ld a,(seksec); mask buffer number and secmsk; least signif bits ld l,a; ready to shift ld h,0; double count add hl,hl; shift left 7 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ; " " hl has relative host buffer address ld de,hstbuf add hl,de; hl = host address ld de,(dmaadr); de = dma address ld bc,128; length ld a,(readop); which way? or a jp nz,rwmove; skip if read ; " " ; write operation, mark and switch direction ld a,1 ld (hstwrt),a; hstwrt = 1 ex de,hl; source/dest swap ; " " rwmove: call move; move a logical sector to/from buffer ; " " ; data has been moved to/from host buffer ld a,(wrtype); write type cp wrdir; to directory? ld a,(erflag); in case of errors ret nz; no further processing ; " " ; clear host buffer for directory write or a; errors? ret nz; skip if so xor a; 0 to accum ld (hstwrt),a; buffer written call writehst ld a,(erflag) ret ; ;* Utility subroutine for 16-bit compare *; ; HL = .unatrk or .hsttrk, compare with sektrk cpsktrk: ex de,hl ld hl,sektrk ld a,(de); low byte compare cp (hl); same? ret nz; return if not inc de; low bytes equal, test hi byte inc hl ld a,(de) cp (hl); sets flags ret ; end