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