home *** CD-ROM | disk | FTP | other *** search
- ; rename this IO-KP.DRV to RSXIO.INC for assembly with RSXMAST
- subttl 'DSKDRIVE machine dependant drivers'
- ;
- ; Most of this file can be used unchanged with any 1790 series
- ; disk controller chip. The actual seek mechanism, at the end,
- ; will have to be customized. This version is for the 1983
- ; style Kaypro 4. The kp84 equate converts to the 1984 model,
- ; BUT HAS NOT BEEN CHECKED.
- ;
- ; rdhst/wthst read or write to/from buff from/to hstrk/hstsec.
- ; One physical block is transferred. Errflg is set to zero on
- ; a good transfer, else non-zero. This is the total responsiblity
- ; of this portion of the system. It refers to the extended disk
- ; parameter tables for host configuration.
- ;
- ; Set only one of the following true (choose Kaypro model)
- k83 equ true
- k84 equ false; *** NOT checked. CAUTION ***
- k10 equ false; *** NOT checked. Kaypro 10 ***
- ;
- ; This option, when set yes, increases disk transfer time
- detect equ no; yes to detect disk not mounted
- ; no to wait for disk to be mounted
- ;
- ; 1791/2/3 Controller chip specific
- ; For most Z80 implementations the data request and interrupt from
- ; the 1791 is connected to NMI (possibly gated by the CPU halt
- ; status line). Thus a CPU halt is ended by the appropriate
- ; controller status, with the RET instruction in memory location
- ; 066h. A status read after the interrupt will reset the interrupt,
- ; as will satisfying the data request. 8080s need more hardware.
- wrtmsk equ 0FDH; Status bits useful after write
- rdmask equ 09DH; " " read
- clrcmd equ 000H; home disk
- rdcmd equ 08CH; read physical sector
- wtcmd equ 0ACH; write physical sector
- radrcmd equ 0C4H; read address command
- seekcmd equ 014H; seek track
- ficmd equ 0D0H; clear controller.
- ;
- ; Z80 opcodes used in driver
- outi macro
- db 0edh,0a3h
- endm
- ini macro
- db 0edh,0a2h
- endm
- ;
- ; This writes a physical sector to the disk. The size, etc.
- ; of that sector are controlled by the extended disk parameter
- ; tables. All i/o is performed to/from buff.
- ; a,f,b,c,d,e,h,l
- wthst: call rwtbgn
- wthst1: ei; during seeks
- call setup; (disables interrupts)
- jnz rwtxit
- mvi e,wtcmd; write command
- rrc
- jnc wthst2; Not 128 byte physical rcd
- mvi b,128
- call dcmnde
- jmp w256
- wthst2: mvi b,0
- rrc
- jnc wthst3; Not 256 byte physical rcd
- call dcmnde
- jmp w256
- wthst3: rrc
- jnc wthst4; 1024 byte physical rcd
- call dcmnde
- jmp w512; 512 byte physical rcd
- wthst4: call dcmnde
- ; " "
- w1024: hlt; Else 1024 byte rcd.
- outi; *** Z80 code
- jnz w1024
- w768: hlt
- outi
- jnz w768
- w512: hlt
- outi
- jnz w512
- w256: hlt
- outi
- jnz w256; May be a W128, on entry bc
- call notbsy
- ani wrtmsk
- jz rwtxit
- call clear
- dcr d
- jnz wthst1; retry
- ori 0FFH; Signal error
- jmp rwtxit
- ;
- ; Set up NMI return, save controller track setting.
- ; Sets the number of retries to be performed.
- ; a,f,d
- rwtbgn: lda 0066H
- sta save66
- mvi a,0C9H; "RET" instruction for NMI
- sta 0066H
- in trkreg
- sta trksav
- mvi d,10; retries
- ret
- ;
- ; Similar to wthst, reads from disk into buff, using the
- ; extended parameter table.
- ; a,f,b,c,d,e,h,l
- rdhst: call rwtbgn
- rdhst1: ei
- call setup; (disables interrupts)
- jnz rwtxit
- mvi e,rdcmd; read command
- rrc
- jnc rdhst2; Not 128 bytes per phys. block
- mvi b,128
- call dcmnde
- jmp r256
- rdhst2: mvi b,0; i.e. 256
- rrc
- jnc rdhst3; Not 256 bytes per block
- call dcmnde
- jmp r256
- rdhst3: rrc
- jnc rdhst4; 1024 byte physical record
- call dcmnde
- jmp r512; 512 bytes per block
- rdhst4: call dcmnde
- ; " "
- r1024: hlt; else 1024 bytes per block
- ini; *** Z80 code
- jnz r1024
- r768: hlt
- ini
- jnz r768
- r512: hlt
- ini
- jnz r512
- r256: hlt
- ini
- jnz r256; May be r128, on entry (b)
- call notbsy
- ani rdmask
- jz rwtxit
- call clear
- dcr d
- jnz rdhst1; retry
- ori 0FFH; Signal error
- ; " "
- ; Exit, restoring 66, trkreg, setting errflg on (a)
- rwtxit: push psw
- lda save66
- sta 0066H
- lda trksav; restore the controller, in
- out trkreg; case bios assumes unchanged
- pop psw
- ei
- sta errflg
- ret
- ;
- ; The actual selection and addressing of the disk controller. This
- ; is responsible for address conversion, and uses the extended disk
- ; parameter table. z flag for success, nz for failure. d preserved.
- ; a,f,b,c,e,h,l
- setup: lhld hsttrk
- shld adrtrk
- lda hstsec
- sta adrsec
- xra a
- sta side; default use side 0
- lda config
- ani 0fh; remove density selection
- cpi maxcase+1
- jnc error
- lxi h,cases; Execute the appropriate code
- call docase; This varies with the format
- call seek; being read/written.
- ; " "
- ; Setup registers for read/write commands
- lda hstblk; block size in 128 byte records
- mvi c,datapt; port to read/write data from/to
- lxi h,buff; and where to/from
- di; Can't interrupt during rd/wrt
- ret; with z/nz flag from seek
- ;
- ; docase (a) on table (hl)^ to muck with disk addressing.
- ; a,f,h,l (and the destination code)
- docase: add a
- add l
- mov l,a
- adc h
- sub l
- mov h,a
- mov a,m
- inx h
- mov h,m
- mov l,a
- pchl
- ;
- cases: dw case0, case1, case2
- dw case3, case4
- ;
- ; Native and logical addresses are the same
- case0: ret
- ;
- ; logical sectors from 0 to offsec-1 are on side 0.
- ; from offsec up are on side 1, and addressed by adding nsecs.
- ; a,f,h,l
- case1: lda adrsec; config = 1
- lxi h,offsec
- sub m
- rc
- lxi h,nsecs
- add m
- sta adrsec
- ; " "
- ; set side one to be accessed
- ; a,f
- sside1: mvi a,1
- sta side
- ret
- ;
- ; odd logical tracks on side 1, even on side 0.
- ; physical track address = logical track/2
- ; Side 1 uses an offset to the sector address.
- ; a,f,h,l
- case2: lhld adrtrk
- mov a,l
- ani 1
- sta side
- mov a,h
- rar
- mov h,a
- mov a,l
- rar
- mov l,a
- shld adrtrk
- rnc; on side 0
- lxi h,nsecs
- lda adrsec; side 1, correct sector address
- add m
- sta adrsec
- ret
- ;
- ; 1st ntrks are on side 0, others side 1. For logical track
- ; on side 1, physical track is logical track - ntrks.
- ; a,f,h,l
- case3: lda adrtrk
- lxi h,ntrks
- cmp m; tracks per side
- rc
- sub m; On second side
- sta adrtrk
- jmp sside1
- ;
- ; 1st ntrks are on side 0, others on side 1. For side 1 track
- ; numbers count down from ntrk, i.e. the disk looks like
- ;
- ; side0 0 1 2 . . ntrk-1
- ; side1 2ntrk-1 . . ntrk+1 ntrk (CPM86 on IBM PC)
- ; a,f,h,l
- case4: lda adrtrk
- lxi h,ntrks
- cmp m
- rc; On first side
- cma
- add m
- add m; Now we count down
- sta adrtrk
- jmp sside1
- ;
- ; Haven't the vaguest idea how to address this disk
- ; a,f
- error: ori 0FFH; config unknown, error
- sta dsktrk; and mark disk unused
- ret
- ;
- ; Clear disc controller. nz flag for timeout
- ; a,f
- clear: mvi a,clrcmd; reset controller
- call dcmnd
- call notbsy
- ani 1
- rnz; timed out
- sta dsktrk
- ret
- ;
- ; await not busy controller status
- ; a,f
- notbsy: push h
- lxi h,0
- call dkwait
- pop h
- ral; restore status
- ret; with busy bit (1) if time out
- ;
- ; Timed out wait for non-busy controller. Time varies with hl
- ; Carry set for timeout. (a) is status right shifted
- ; a,f,h,l
- dkwait: in statpt
- rar
- rnc; not busy, ok
- if detect
- dcr l; preserve status in a
- jnz dkwait; for possible time-out exit
- dcr h; (re-getting may be different)
- jnz dkwait
- push psw; busy time-out, save status bits
- mvi a,ficmd
- call dcmnd; clear controller chip
- pop psw; show status bits
- stc; and signal error
- ret
- else; not detect
- jmp dkwait
- endif
- ;
- ; command (e) to disk controller
- ; a,f
- dcmnde: mov a,e
- ; " "
- ; command (a) to disk controller. Pause for status valid
- ; f
- dcmnd: out ctrlpt
- push b; and 20 uSec. delay
- mvi b,(20*clkspd - 37)/14; clkspd >= 3(00 khz)
- dcmnd1: dcr b
- jnz dcmnd1; pause for controller status
- pop b
- ret
- ;
- ; pause (b) * 10 Millisec. Set for 2.5 Mhz clock.
- ; a,f,b
- pause: push d
- pause1: lxi d,41*clkspd; clkspd in 100khz units
- pause2: dcx d
- mov a,e
- ora d
- jnz pause2
- dcr b
- jnz pause1
- pop d
- ret
- ;
- ; =================================================================
- ; Everything above this point probably does not have to be changed
- ; for any machine using the 1790 series disk controllers. The rest
- ; will have to be customized.
- ; =================================================================
- ;
- ; Kaypro Specific
- sideb equ 2; side selection, bit number
- drvmsk equ 3; bits 0 & 1 select drive
- densb equ 32; bit weight for density selection
- ;
- if k83; 1983 version
- bitpt equ 1ch; system control port
- mtrb equ 6; bit number
- mtron equ 0
- abit equ 0; bit number
- bbit equ 1; bit number
- side0 equ 0
- side1 equ 1 shl sideb
- endif
- if k84 or K10; 1984 version
- bitpt equ 14H; system control port
- mtrb equ 4; bit number
- mtron equ 1
- abit equ 1; bit number
- bbit equ 0; bit number
- side0 equ 1 shl sideb
- side1 equ 0
- endif
- drivea equ 1 shl abit
- driveb equ 1 shl bbit
- ;
- ; Field to be controlled here
- modmsk equ drvmsk+(1 shl mtrb)+(1 shl sideb)+densb
- ;
- ; Host specific routines here - setup for Kaypro 4
- ; This performs the actual seek, sets density, etc.
- ; *** ENTRY IN THE MIDDLE at "seek" *** <<<
- ; a,f,b,c,e,h,l (allowed). (d is retry count)
- ;
- seek3: call clear; Never used yet, clear controller
- jnz error; timeout error, no disk mounted
- seek4: lda adrtrk; Do physical seek
- out datapt; changing tracks
- mvi a,seekcmd; seek track
- call dcmnd
- call notbsy
- ani 99H; Check status
- jz seek5; good seek, finish up
- ani 1
- jnz error; no disk, error exit
- call error; mark physical seek needed
- dcr d
- jz error; no more retries, error
- ; " "
- ; Main routine entry point. <<< *** ENTRY HERE <<
- seek: lda dsktrk; If we have switched drives
- out trkreg; set the controller to match history
- ; " "
- ; set up density
- lda config; Set up for side and density
- ora a
- lxi h,dendbl
- jp seek1; Normal double density system
- inx h; else set single density command
- seek1: mov b,m
- ; " "
- ; set up side selection
- lda side; Move side selection bit into place.
- if k84 OR k10; Side bit is complemented
- cma
- endif
- ani 1
- ral; Position the side select bit
- ral
- ora b; Compute drive selection/density code
- mov b,a
- ; " "
- ; Kaypro combines all these things in one port
- in bitpt; Keep bank (80), turn mtr on (40=0)
- push psw; clear DDEN (20), keep lptstrobe (10)
- ani NOT modmsk; ignore prtbusy(8), clear side(4),
- ora b; drive code (2, 1) bit weights
- ori mtron shl mtrb
- ; " "
- ; add in the physical drive selection coding.
- lxi h,dskode
- ora m
- ; " "
- ; now we actually select drive/side/density and turn on motors
- out bitpt
- pop psw
- ani 1 shl mtrb
- if k84 OR k10; inverted motor control bit
- xri mtron shl mtrb
- endif
- mvi b,50; *10 = 500 millisec
- cnz pause; if motor was off wait for it
- lda dsktrk
- inr a; check for 1st access to this drv
- jz seek3; 1st access to this drive
- dcr a
- lxi h,adrtrk
- cmp m
- jnz seek4; Need a physical seek
- ; " "
- ; All well, final setup and exit
- seek5: if detect
- mvi a,radrcmd
- call dcmnd; try to read an address
- call notbsy
- ani 1
- jnz error; busy time out, no disk
- endif; detect
- lda adrsec; Successful seek or not needed
- lxi h,sec1st; last buggery with sec. address
- add m
- out secreg; set physical sector
- lda adrtrk
- sta dsktrk; record what track we are on
- xra a
- ret
- ;
- ; These four bytes following MUST BE the last portion of this file.
- ; This makes them accessible by a negative offset from the "info"
- ; pointer, which is returned by the master RSX enquiry call, and
- ; allows supporting software to dynamically reconfigure the system.
- ; This portion must be customized on installation to host only.
- ;
- modrv: db drv-'A'; and drive id to use (0=A). patchable
- ;
- dskode: if k10; Only 1 floppy drive
- db drivea; addressed as C.
- else
- db driveb; drive selection coding. drive B
- endif
- dendbl: db 0; base command for double density
- densgl: db densb; base command for single density
- í