home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
turbodos
/
mdrv-td.lbr
/
DSKMDRV.MZC
/
DSKMDRV.MAC
Wrap
Text File
|
1987-11-08
|
4KB
|
159 lines
Title TurboDOS driver for CompuPro Mdrive/H - 2 Megabyte version.
;Assemble with M80 or compatible assembler.
.Z80 ;Use Zilog mnemonics.
; 10/07/87 Rev 0 Bob Clyne Changed disk parameters and streamlined the
; code. This is a wierd disk configuration but
; the code is lean. There is no error checking
; in order to make the driver as fast as possible
; it just trusts that the M-Drive/H is OK.
NAME ('DSKDRM') ;Module ID.
; Disk packet declaration.
OPCODE EQU 0
DRIVE EQU 1
TRACK EQU 2
SECTOR EQU 4
SECCNT EQU 6
BYTCNT EQU 8
DMADR EQU 10
DSTADR EQU 12
BLKSIZ EQU 14
NMBLKS EQU 15
NMBDIR EQU 17
SECSIZ EQU 18
SECTRK EQU 19
TRKDSK EQU 21
RESTRK EQU 23
; M-drive ports. Set for whatever ports you are using.
HBASE EQU 040H ;Base port as set on M-Drive/H DIP switches.
HDATA EQU HBASE ;M-drive data port.
HADDR EQU HBASE+1 ;M-drive address port.
; Disk driver code starts here.
CSEG
DSKDR@::
LD HL,DMXSPH ;Disk mutual exclusion semaphore.
CALL WAIT## ;Wait until driver code is idle.
LD (RETSP),SP ;Save the old stack pointer.
LD SP,MYSTAK ;Set up a new stack.
CALL DRVR ;Call the driver.
LD SP,(RETSP)
PUSH AF ;Save the return code.
LD HL,DMXSPH
CALL SIGNAL## ;Tell TurboDOS we are done.
POP AF ;Get return code back.
RET ;To TurboDOS
; The driver subroutine.
DRVR:
LD A,(IX+OPCODE) ;Get the operation code.
SUB 2 ;Subtract 2 - if carry must be 0 or 1.
JR C,COMN ;If so go to read/write common routine.
JP Z,QPARMS ;If it was 2 return disk parameters.
DEC A ;Let's see if it was 3.
JP Z,STATUS ;If so return status - always ready.
JP FORMAT ;Else format - not implemented here.
; Read/write code.
COMN:
LD A,(IX+TRACK) ;Get track number.
OUT (HADDR),A ;Send it as high address byte to addr port.
LD A,(IX+SECTOR) ;Get sector number.
ADD A,A ;Times 2.
ADD A,A ;Times 4.
OUT (HADDR),A ;Send it as middle address byte to addr port.
XOR A ;Zero the accumulator.
LD (SECTCNT),A ;Set 0 initial sector count for mult sect oper.
LD B,A ;Save 0 in B for 256 byte loop count.
OUT (HADDR),A ;Send 0 as low address byte to address port.
LD L,(IX+DMADR) ;Get low byte of DMA address.
LD H,(IX+DMADR+1) ;Get high byte of DMA address.
LD C,HDATA ;Load data port address in C.
MSECLP: LD A,(IX+OPCODE) ;Get operation code.
OR A ;Set flags.
JR NZ,WRITE ;0 = read, 1 = write.
READ:
INIR ;Read 256 bytes
INIR ;and another 256 makes 512
INIR ;and another 256 makes 768
INIR ;and another 256 bytes makes a 1K sector.
JR GOOD ;See if another sector wanted.
WRITE:
OTIR ;Write 256 bytes
OTIR ;and another 256 makes 512
OTIR ;and another 256 makes 768
OTIR ;and another 256 bytes makes a 1K sector.
GOOD:
LD A,(SECTCNT) ;Get our sector count.
INC A ;Increment for sector just done.
LD (SECTCNT),A ;Save it again.
CP (IX+SECCNT) ;Compare with TurboDOS's requested #.
JR NZ,MSECLP ;If not enough go do another sector.
XOR A ;Else 0 the accumulator.
RET ;And return successful.
; Return disk parameters.
QPARMS:
LD HL,DPB ;Get address of our disk parameter block.
LD (IX+DSTADR),L ;Put low byte in TurboDOS disk packet.
LD (IX+DSTADR+1),H ;Put high byte in packet.
OR 0FFH
RET ;Return successful.
; Return drive status - always ready.
STATUS: OR 0FFH
RET
; Format a track - not implemented - always returns reporting success.
FORMAT: XOR A
RET
DSEG
; This is a wierd disk format but it makes for fast compact code. Note: The
; last track only has 16 sectors.
DPB: DB 0C4H ;Block size = 2K, fixed disk, 16K extents.
DW 1000 ;Total blocks on disk, excluding reserved trks.
DB 8 ;Number of directory blocks -> 512 dir entries.
DB 3 ;Sector size -> 1024 byte sectors.
DW 64 ;Sectors per track.
DW 32 ;Number of tracks on disk.
DW 0 ;Number of reserved tracks.
; Mutual exclusion semaphore.
DMXSPH: DW 1
DW DMXSPH+2
DW DMXSPH+2
SECTCNT:DB 0 ;Sector count.
; Space for stack.
DS 8
MYSTAK:
RETSP: DW 0 ;Return stack pointer stored here.
END