home *** CD-ROM | disk | FTP | other *** search
- title 'disk handling routines'
-
- true equ -1
- false equ 0
-
- banked equ true
- check equ false
-
- .Z80
-
- .comment *
- disk handling routines for assembly by m80
-
- routines (dph address in DE):
- fread return 0 in A for success, 1 for failure
- fwrite return 0 for success, 1 for error, 2 for write protected disk
- flogin login - set density
- finita initialize drive a
- finitb initialize drive b
- finitc initialize drive c
-
- external variables
- @adrv absolute drive code
- @rdrv relative drive code
- @dma disk transfer address
- @trk track
- @sect sector
- @ermde error mode
- @dbnk bank
-
- external routines
- ?pmsg print message
- ?pdec print decimal
- ?pderr print disk error header
- ?wboot warm boot
- ?conin,?cono,?const console routines
- ?move,?xmove,?trans bank transfer routines
-
- codes for disk format
- bit 5: 1 for double sided
- bit 4: 1
- bit 2,3: 0 for 128 byte sectors,
- 1 for 256 byte sectors,
- 2 for 512 byte sectors,
- 3 for 1024 byte sectors
- all bits=0 if density determination fails
-
- *
-
- dseg
-
- entry fread,fwrite,flogin,finita,finitb,finitc
- external @adrv,@rdrv,@dma,@trk,@sect,@ermde
- external ?pmsg,?pdec,?pderr,?wboot,?conin,?cono,?const,?move
- if banked
- external ?xmove,?trans,@cbnk,@dbnk
- endif
- external adrv,bdrv,cdrv,ddrv ; drives
- external dskdef ; disk characteristics
- cr equ 13
- lf equ 10
- xbuff equ 0E800H ;Buffer for r/w to nonzero banks
- ntry equ 4 ;number of retries
-
- origin equ 0E000H
- djboot equ origin ;Disk Jockey 2D cold boot
- djcin equ origin+3h ;Disk Jockey 2D character input routine
- djcout equ origin+6h ;Disk Jockey 2D character output routine
- djhome equ origin+9h ;Disk Jockey 2D track zero seek
- djtrk equ origin+0ch ;Disk Jockey 2D track seek routine
- djsec equ origin+0fh ;Disk Jockey 2D set sector routine
- djdma equ origin+12h ;Disk Jockey 2D set DMA address
- djread equ origin+15h ;Disk Jockey 2D read routine
- djwrit equ origin+18h ;Disk Jockey 2D write routine
- djsel equ origin+1bh ;Disk Jockey 2D select drive routine
- djtsta equ origin+21h ;Disk Jockey 2D terminal status routine
- djstat equ origin+27h ;Disk Jockey 2D status routine
- djerr equ origin+2ah ;Disk Jockey 2D error, flash led
- djden equ origin+2dh ;Disk Jockey 2D set density routine
- djside equ origin+30h ;Disk Jockey 2D set side routine
- djleav equ origin+222h ;leave routine in dj rom
- djprep equ origin+233h ;prep routine in dj rom
-
-
- finita: ; initialize disk a
- ld a,'A'
- ld (drvtp),a ; disk A expected
- ld c,0
- call djsel ; physical drive A
- xor a ; clear a
- ld (adrv-1),a ; error or unset code for disk format
- ret
- finitb: ; initialize disk b
- xor a ; clear a
- ld (bdrv-1),a ; error or unset code for disk format
- ret
- finitc: ; initialize disk c
- xor a ; clear a
- ld (cdrv-1),a ; error or unset code for disk format
- ret
-
- setup: ; set up disk parameters
- push de ; keep de
- call dsk ; check correct disk loaded
- if banked
- ld a,(@dbnk) ; check bank
- and a
- jr z,bnk0 ; bank 0
- ; get sector length / 128
- pop bc ; get dhp
- push bc ; & restore to stack
- ld hl,12
- add hl,bc ; points to address of dpb
- ld c,(hl)
- inc hl
- ld b,(hl) ; bc contains address of dpb
- ld hl,16
- add hl,bc ; hl points to phm
- ld a,(hl)
- inc a ; a contains sector length / 128
- ld (seclen),a ; store in seclen
- ld bc,xbuff ; temporary buffer
- jr bnkx
- endif
- bnk0: ld bc,(@dma) ; get dma
- bnkx: xor a ; necessary to detect dma error
- call djdma ; set dma
- and a
- jp nz,err2 ; dma invalid
- ld a,(@sect) ; get sector
- ld c,a
- call djsec ; set sector
- jp c,err1
- ld a,(@trk) ; get track
- ld b,a
- pop hl
- dec hl ; points to disk format
- ld a,(hl) ; get disk format
- ld (fmt),a ; keep disk format
- or a ; get flags
- jp z,nologi ; login not done or failed
- bit 5,a ; check for double sided
- ld c,0
- jr z,ss ; jump if single sided
- srl b ; divide track by 2 - rem to carry bit
- rl c ; side 1 if track number odd
- ss: call djside ; set side (to 0 for ss disk)
- ld c,b
- call djtrk ; set track
- jp c,err1
- ret
-
- dsk: ; check correct disk loaded
- ex de,hl
- dec hl
- dec hl ; points to unit
- ld a,(drvtp) ; get current disk name
- cp (hl)
- ret z ; return if disk ok
- ld a,(hl)
- ld (drvtp),a ; store disk name
- call clear ; clear console input
- ld hl,chdsk ; change disk message
- call ?pmsg ; type message
- call ?conin ; wait for input
- call crlf
- call djhome ; track 0
- ret
-
- chdsk: db cr,lf,'Load disk ' ; change disk message
- drvtp: db 'A'
- db ', <ret>',0
- if banked
- seclen: ds 1 ; sector length / 128
- endif
- fmt: ds 1 ; disk format
-
- clear: ; clear console buffer
- call ?const ; check for character
- or a ; set flags
- ret z ; return if no character
- call ?conin ; get character
- jr clear ; try again
-
- yesno: ; return with zero set if y or Y entered
- call ?conin
- cp 'y'
- ret z
- cp 'Y'
- ret z
- cp 'n'
- jr z,yesno1
- cp 'N'
- jr z,yesno1
- jr yesno ; cycle if not y,Y,n or N
- yesno1: and a ; to set flag to nz
- ret
-
- crlf: ; output a cr and lf
- ld hl,lcrlf
- call ?pmsg
- ret
-
- lcrlf: db cr,lf,0
-
- fread: ; read sector
- if check
- ld hl,xr
- call record
- endif
- call setup ; set disk parameters
- cycr1: ld b,ntry ; number of attempts
- cycr: push bc ; store these
- call djread ; diskjockey read
- pop bc
- if banked
- jr nc,fre1 ; exit if successful
- else
- ret nc
- endif
- and a ; set flags
- call m,notred ; drive not ready
- djnz cycr ; try ntry times
- call errcd
- if banked
- jr nz,fre2 ; exit anyway
- else
- ret nz
- endif
- jr cycr1
- if banked
- fre1: call frex
- xor a ; return code
- ret
- fre2: push af ; keep error code
- call frex
- pop af ; return code
- ret
- frex: ld a,(@dbnk) ; interblock transf reqd?
- and a
- ret z ; return if reading from bank 0
- ld b,a ; destination
- ld hl,(@dma)
- ld c,0 ; source
- ld de,xbuff
- ld a,(seclen) ; get sector length / 128
- call ?trans ; interblock transfer
- ret
- endif
-
- fwrite: ; write sector
- if check
- ld hl,xw
- call record
- endif
- call setup ; set disk parameters
- if banked
- ld a,(@dbnk) ; check bank
- and a
- jr z,cycw1 ; jump if bank 0
- ld c,a ; source
- ld de,(@dma)
- ld b,0 ; destination
- ld hl,xbuff
- ld a,(seclen)
- call ?trans ; interblock transfer
- endif
- cycw1: ld b,ntry ; number of attempts
- cycw: push bc ; store these
- call djwrite ; diskjockey write
- pop bc
- ret nc ; return if successful
- and a ; set flags
- call m,notred ; drive not ready
- djnz cycw ; try ntry times
- call errcd
- ret nz ; return anyway
- jr cycw1
- flogin: ; login drive
- push de ; contains dph location
- ; now carry out dummy op to get disk characteristics
- call dsk ; check correct disk
- call djhome ; to track 0
- ld c,1
- call djsec ; sector 1
- ld c,0
- call djside ; side 0
- ld c,2
- call djtrk ; track 2
- call djprep ; dummy disk op
- call djleav
- jr nc,contin ; jump if successful
- pop hl
- ld d,h ; so we can jump to flogin
- ld e,l
- dec hl
- ld (hl),0 ; to indicate login failed
- bit 7,a
- jr nz,nr1 ; jump if not ready
- push de ; keep de
- call errcd
- pop de
- ret nz ; return anyway
- jr flogin
- nr1: push de ; keep de
- call notred
- pop de
- jr flogin
-
- contin: call djstat ; get disk characteristics
- or 10h ; set bit 4
- pop hl ; get dph location
- ld d,h ; copy it to de
- ld e,l
- dec hl ; points to disk format
- ld (hl),a ; store disk characteristics
- rrca ; move right
- and 16h ; 2 * sec.lng.code + 16 * side.code
- ld hl,dskdef ; get table of disk table addresses
- ld b,0
- ld c,a
- add hl,bc ; hl points to address of skew table
- ldi ; copy two bytes
- ldi
- ld bc,6
- add hl,bc ; address of pointer to dpb
- ld bc,10
- ex de,hl
- add hl,bc ; pointer to dpb in dph
- ex de,hl
- ldi ; copy two bytes
- ldi
- ret
-
- ; handle errors
- notred: ; drive not ready
- push bc
- call clear
- ld hl,x0
- call ?pmsg
- call ?conin ; wait for keyboard entry
- pop bc
- ret
- err1: call ?pderr
- ld hl,x1
- call ?pmsg
- jp ?wboot
- err2: call ?pderr
- ld hl,x11
- call ?pmsg
- jp ?wboot
- err3: ; check for disk change
- call djstat ; get actual disk format
- or 10h ; set bit 4
- ld hl,fmt
- cp (hl) ; compare with recorded format
- jr z,err1 ; no disk change detected
- ld a,0ffh ; disk change code
- pop hl ; adjust stack
- ret ; return
-
- errcd: bit 6,a
- jr nz,wrpr ; write protected disk
- bit 4,a
- jr nz,err3 ; invalid record/sector
- ld a,1 ; error code
- ld (ecx),a
- ld a,(@ermde) ; error mode
- inc a ; zero if @ermde=0ffh
- jr z,herror ; if error messages are not being written
- call ?pderr ; bios error message
- call clear
- ld hl,x2
- call ?pmsg ; ask whether to try again
- call yesno
- ret z ; try again
- ec1: ld hl,x21
- call ?pmsg ; ask whether to return to cpm
- call yesno
- jp z,?wboot ; return to cpm
- ld hl,x22
- call ?pmsg ; ask whether to return error code
- call yesno
- push af ; keep flag
- ld hl,x23
- call ?pmsg
- pop af
- jr z,herror
- ld a,0 ; if no: clear error code, leave nz flag
- ret
-
- wrpr: ld a,2 ; error return code
- ld (ecx),a ; store in ecx
- ld a,(@ermde) ; error mode
- inc a ; zero if @ermde=0ffh
- jr z,herror ; if error messages are not being written
- call ?pderr ; bios error message
- call clear
- ld hl,x24
- call ?pmsg
- jr ec1
-
- nologi: call ?pderr
- ld hl,x3
- call ?pmsg
- jp ?wboot
-
- herror: ld a,(ecx)
- and a ; to set flags
- ret
-
- ecx: ds 1 ; code for error location
-
- x0: db cr,lf,'close drive <ret>',cr,lf,0
- x1: db cr,lf,'invalid sector/record',cr,lf,0
- x11: db cr,lf,'illegal dma',cr,lf,0
- x2: db cr,lf,'parity error - try again (y/n)?',0
- x21: db cr,lf,' - return to cpm (y/n)?',0
- x22: db ' - return error code (y/n)?',0
- x23: db ' - continuing',cr,lf,0
- x24: db cr,lf,'write protected disk',0
- x3: db cr,lf,'drive not logged in',cr,lf,0
-
- if check ; debugging messages
-
- xcrlf: db cr,lf,0
- xr: db 'read ',0
- xw: db 'write ',0
- xtrk: db ' trk ',0
- xsect: db ' sect ',0
- xdma: db ' dma ',0
- if banked
- xcbnk: db ' cbnk ',0
- xdbnk: db ' dbnk ',0
- endif
-
- record: push de
- push hl
- ld hl,xcrlf
- call ?pmsg
- pop hl
- call ?pmsg
- ld hl,xtrk
- call ?pmsg
- ld hl,(@trk)
- call ?pdec
- ld hl,xsect
- call ?pmsg
- ld hl,(@sect)
- call ?pdec
- ld hl,xdma
- call ?pmsg
- ld hl,(@dma)
- call ?pdec
- if banked
- ld hl,xcbnk
- call ?pmsg
- ld hl,(@cbnk)
- ld h,0
- call ?pdec
- ld hl,xdbnk
- call ?pmsg
- ld hl,(@dbnk)
- ld h,0
- call ?pdec
- endif
- ld hl,xcrlf
- call ?pmsg
- pop de
- ret
- endif
-
- end
- p 'N'
- jr z,yesno1
- jr yesno ; cycle if not y,Y,n