Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

349 lines
10 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;* *
;* Sector Blocking / Deblocking *
;* *
;* This algorithm is a direct translation of the *
;* CP/M-80 Version, and is included here for refer- *
;* ence purposes only. The file DEBLOCK.LIB is in- *
;* cluded on your CP/M-86 disk, and should be used *
;* for actual applications. You may wish to contact *
;* Digital Research for notices of updates. *
;* *
;*****************************************************
;
;*****************************************************
;* *
;* CP/M to host disk constants *
;* *
;* (This example is setup for CP/M block size of 16K *
;* with a host sector size of 512 bytes, and 12 sec- *
;* tors per track. Blksiz, hstsiz, hstspt, hstblk *
;* and secshf may change for different hardware.) *
;*****************************************************
una equ byte ptr [BX] ;name for byte at BX
;
blksiz equ 16384 ;CP/M allocation size
hstsiz equ 512 ;host disk sector size
hstspt equ 12 ;host disk sectors/trk
hstblk equ hstsiz/128 ;CP/M sects/host buff
;
;*****************************************************
;* *
;* secshf is log2(hstblk), and is listed below for *
;* values of hstsiz up to 2048. *
;* *
;* hstsiz hstblk secshf *
;* 256 2 1 *
;* 512 4 2 *
;* 1024 8 3 *
;* 2048 16 4 *
;* *
;*****************************************************
secshf equ 2 ;log2(hstblk)
cpmspt equ hstblk * hstspt ;CP/M sectors/track
secmsk equ hstblk-1 ;sector mask
;
;*****************************************************
;* *
;* BDOS constants on entry to write *
;* *
;*****************************************************
wrall equ 0 ;write to allocated
wrdir equ 1 ;write to directory
wrual equ 2 ;write to unallocated
;
;*****************************************************
;* *
;* The BIOS entry points given below show the *
;* code which is relevant to deblocking only. *
;* *
;*****************************************************
seldsk:
;select disk
;is this the first activation of the drive?
test DL,1 ;lsb = 0?
jnz selset
;this is the first activation, clear host buff
mov hstact,0
mov unacnt,0
selset:
mov al,cl ! cbw ;put in AX
mov sekdsk,al ;seek disk number
mov cl,4 ! shl al,cl ;times 16
add ax,offset dpbase
mov bx,ax
ret
;
home:
;home the selected disk
mov al,hstwrt ;check for pending write
test al,al
jnz homed
mov hstact,0 ;clear host active flag
homed:
mov cx,0 ;now, set track zero
; (continue HOME routine)
ret
;
settrk:
;set track given by registers CX
mov sektrk,CX ;track to seek
ret
;
setsec:
;set sector given by register cl
mov seksec,cl ;sector to seek
ret
;
setdma:
;set dma address given by CX
mov dma_off,CX
ret
;
setdmab:
;set segment address given by CX
mov dma_seg,CX
ret
;
sectran:
;translate sector number CX with table at [DX]
test DX,DX ;test for hard skewed
jz notran ;(blocked must be hard skewed)
mov BX,CX
add BX,DX
mov BL,[BX]
ret
no_tran:
;hard skewed disk, physical = logical sector
mov BX,CX
ret
;
read:
;read the selected CP/M sector
mov unacnt,0 ;clear unallocated counter
mov readop,1 ;read operation
mov rsflag,1 ;must read data
mov wrtype,wrual ;treat as unalloc
jmp rwoper ;to perform the read
;
write:
;write the selected CP/M sector
mov readop,0 ;write operation
mov wrtype,cl
cmp cl,wrual ;write unallocated?
jnz chkuna ;check for unalloc
;
; write to unallocated, set parameters
;
mov unacnt,(blksiz/128) ;next unalloc recs
mov al,sekdsk ;disk to seek
mov unadsk,al ;unadsk = sekdsk
mov ax,sektrk
mov unatrk,ax ;unatrk = sektrk
mov al,seksec
mov unasec,al ;unasec = seksec
;
chkuna:
;check for write to unallocated sector
;
mov bx,offset unacnt ;point "UNA" at UNACNT
mov al,una ! test al,al ;any unalloc remain?
jz alloc ;skip if not
;
; more unallocated records remain
dec al ;unacnt = unacnt-1
mov una,al
mov al,sekdsk ;same disk?
mov BX,offset unadsk
cmp al,una ;sekdsk = unadsk?
jnz alloc ;skip if not
;
; disks are the same
mov AX, unatrk
cmp AX, sektrk
jnz alloc ;skip if not
;
; tracks are the same
mov al,seksec ;same sector?
;
mov BX,offset unasec ;point una at unasec
;
cmp al,una ;seksec = unasec?
jnz alloc ;skip if not
;
; match, move to next sector for future ref
inc una ;unasec = unasec+1
mov al,una ;end of track?
cmp al,cpmspt ;count CP/M sectors
jb noovf ;skip if below
;
; overflow to next track
mov una,0 ;unasec = 0
inc unatrk ;unatrk=unatrk+1
;
noovf:
;match found, mark as unnecessary read
mov rsflag,0 ;rsflag = 0
jmps rwoper ;to perform the write
;
alloc:
;not an unallocated record, requires pre-read
mov unacnt,0 ;unacnt = 0
mov rsflag,1 ;rsflag = 1
;drop through to rwoper
;
;*****************************************************
;* *
;* Common code for READ and WRITE follows *
;* *
;*****************************************************
rwoper:
;enter here to perform the read/write
mov erflag,0 ;no errors (yet)
mov al, seksec ;compute host sector
mov cl, secshf
shr al,cl
mov sekhst,al ;host sector to seek
;
; active host sector?
mov al,1
xchg al,hstact ;always becomes 1
test al,al ;was it already?
jz filhst ;fill host if not
;
; host buffer active, same as seek buffer?
mov al,sekdsk
cmp al,hstdsk ;sekdsk = hstdsk?
jnz nomatch
;
; same disk, same track?
mov ax,hsttrk
cmp ax,sektrk ;host track same as seek track
jnz nomatch
;
; same disk, same track, same buffer?
mov al,sekhst
cmp al,hstsec ;sekhst = hstsec?
jz match ;skip if match
nomatch:
;proper disk, but not correct sector
mov al, hstwrt
test al,al ;"dirty" buffer ?
jz filhst ;no, don't need to write
call writehst ;yes, clear host buff
; (check errors here)
;
filhst:
;may have to fill the host buffer
mov al,sekdsk ! mov hstdsk,al
mov ax,sektrk ! mov hsttrk,ax
mov al,sekhst ! mov hstsec,al
mov al,rsflag
test al,al ;need to read?
jz filhst1
;
call readhst ;yes, if 1
; (check errors here)
;
filhst1:
mov hstwrt,0 ;no pending write
;
match:
;copy data to or from buffer depending on "readop"
mov al,seksec ;mask buffer number
and ax,secmsk ;least signif bits are masked
mov cl, 7 ! shl ax,cl ;shift left 7 (* 128 = 2**7)
;
; ax has relative host buffer offset
;
add ax,offset hstbuf ;ax has buffer address
mov si,ax ;put in source index register
mov di,dma_off ;user buffer is dest if readop
;
push DS ! push ES ;save segment registers
;
mov ES,dma_seg ;set destseg to the users seg
;SI/DI and DS/ES is swapped
;if write op
mov cx,128/2 ;length of move in words
mov al,readop
test al,al ;which way?
jnz rwmove ;skip if read
;
; write operation, mark and switch direction
mov hstwrt,1 ;hstwrt = 1 (dirty buffer now)
xchg si,di ;source/dest index swap
mov ax,DS
mov ES,ax
mov DS,dma_seg ;setup DS,ES for write
;
rwmove:
cld ! rep movs AX,AX ;move as 16 bit words
pop ES ! pop DS ;restore segment registers
;
; data has been moved to/from host buffer
cmp wrtype,wrdir ;write type to directory?
mov al,erflag ;in case of errors
jnz return_rw ;no further processing
;
; clear host buffer for directory write
test al,al ;errors?
jnz return_rw ;skip if so
mov hstwrt,0 ;buffer written
call writehst
mov al,erflag
return_rw:
ret
;
;*****************************************************
;* *
;* WRITEHST performs the physical write to the host *
;* disk, while READHST reads the physical disk. *
;* *
;*****************************************************
writehst:
ret
;
readhst:
ret
;
;*****************************************************
;* *
;* Use the GENDEF utility to create disk def tables *
;* *
;*****************************************************
dpbase equ offset $
; disk parameter tables go here
;
;*****************************************************
;* *
;* Uninitialized RAM areas follow, including the *
;* areas created by the GENDEF utility listed above. *
;* *
;*****************************************************
sek_dsk rb 1 ;seek disk number
sek_trk rw 1 ;seek track number
sek_sec rb 1 ;seek sector number
;
hst_dsk rb 1 ;host disk number
hst_trk rw 1 ;host track number
hst_sec rb 1 ;host sector number
;
sek_hst rb 1 ;seek shr secshf
hst_act rb 1 ;host active flag
hst_wrt rb 1 ;host written flag
;
una_cnt rb 1 ;unalloc rec cnt
una_dsk rb 1 ;last unalloc disk
una_trk rw 1 ;last unalloc track
una_sec rb 1 ;last unalloc sector
;
erflag rb 1 ;error reporting
rsflag rb 1 ;read sector flag
readop rb 1 ;1 if read operation
wrtype rb 1 ;write operation type
dma_seg rw 1 ;last dma segment
dma_off rw 1 ;last dma offset
hstbuf rb hstsiz ;host buffer
end