mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 09:54:20 +00:00
Upload
Digital Research
This commit is contained in:
349
CPM OPERATING SYSTEMS/CPM 86/CPM 86 1.1 SOURCE/DEBLOCK.LIB
Normal file
349
CPM OPERATING SYSTEMS/CPM 86/CPM 86 1.1 SOURCE/DEBLOCK.LIB
Normal file
@@ -0,0 +1,349 @@
|
||||
;*****************************************************
|
||||
;* *
|
||||
;* 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
|
||||
|
||||
Reference in New Issue
Block a user