* DRIVER ROUTINES FOR SWTPC MF-68
*
* COPYRIGHT (C) 1980 BY
* TECHNICAL SYSTEMS CONSULTANTS, INC.
* PO BOX 2570, W. LAFAYETTE, IN 47906
*
* THESE DRIVERS ARE FOR A SINGLE-SIDED, SINGLE-
* DENSITY SWTPC MF-68 MINIFLOPPY DISK SYSTEM.
*
* THE DRIVER ROUTINES PERFORM THE FOLLOWING
*  1. READ SINGLE SECTOR - DREAD
*  2. WRITE SINGLE SECTOR - DWRITE
*  3. VERIFY WRITE OPERATION - VERIFY
*  4. RESTORE HEAD TO TRACK 00 - RESTOR
*  5. DRIVE SELECTION - DRIVE
*  6. CHECK READY - DCHECK
*  7. QUICK CHECK READY - DQUICK
*  8. DRIVER INITIALIZATION - DINIT
*  9. WARM START ROUTINE - DWARM
* 10. SEEK ROUTINE - DSEEK

* EQUATES

DRQ EQU 2 DRQ BIT MASK
BUSY EQU 1 BUSY MASK
RDMSK EQU $1C READ ERROR MASK
VERMSK EQU $18 VERIFY ERROR MASK
WTMSK EQU $5C WRITE ERROR MASK
DRVREG EQU $8014 DRIVE REGISTER
COMREG EQU $8018 COMMAND REGISTER
TRKREG EQU $8019 TRACK REGISTER
SECREG EQU $801A SECTOR REGISTER
DATREG EQU $801B DATA REGISTER
RDCMND EQU $8C READ COMMAND
WTCMND EQU $AC WRITE COMMAND
RSCMND EQU $0B RESTORE COMMAND
SKCMND EQU $1B SEEK COMMAND
PRCNT EQU $AC34

*********************************************
* DISK DRIVER JUMP TABLE
*********************************************
 ORG  $BE80
DREAD JMP READ
DWRITE JMP WRITE
DVERFY JMP VERIFY
RESTOR JMP RST
DRIVE JMP DRV
DCHECK JMP CHKRDY
DQUICK JMP CHKRDY
DINIT JMP INIT
DWARM JMP WARM
DSEEK JMP SEEK
*********************************************

* GLOBAL VARIABLE STORAGE

CURDRV FCB 0 CURRENT DRIVE
DRVTRK FDB 0,0 CURRENT TRACK PER DRIVE
INDEX FDB 0 TEMPORARY STORAGE


* INIT AND WARM
*
* DRIVER INITIALIZATION

INIT LDX #CURDRV POINT TO VARIABLES
 LDAB #5 NO. OF BYTES TO CLEAR
INIT2 CLR 0,X CLEAR THE STORAGE
 INX
 DECB
 BNE INIT2 LOOP TIL DONE
WARM RTS WARM START NOT NEEDED

* READ
*
* READ ONE SECTOR

READ BSR SEEK SEEK TO TRACK
 LDAA #RDCMND SETUP READ SECTOR COMMAND
 TST PRCNT ARE WE SPOOLING?
 BEQ READ2 SKIP IF NOT
 SWI ELSE, SWITCH TASKS
READ2 NOP
 SEI DISABLE INTERRUPTS
 STAA COMREG ISSUE READ COMMAND
 JSR DEL28 DELAY
 CLRB GET SECTOR LENGTH (=256)
READ3 LDAA COMREG GET WD STATUS
 BITA #DRQ CHECK FOR DATA
 BNE READ5 BRANCH IF DATA PRESENT
 BITA #BUSY CHECK IF BUSY
 BNE READ3 LOOP IF SO
 TAB ERROR IF NOT
 BRA READ6
READ5 LDAA DATREG GET DATA BYTE
 STAA 0,X PUT IN MEMORY
 INX BUMP THE POINTER
 DECB DEC THE COUNTER
 BNE READ3 LOOP TIL DONE
 BSR WAIT WAIT TIL WD IS FINISHED
READ6 BITB #RDMSK MASK ERRORS
 NOP
 CLI ENABLE INTERRUPTS
 RTS RETURN

* WAIT
*
* WAIT FOR 1771 TO FINISH COMMAND

WAIT TST PRCNT ARE WE SPOOLING?
 BEQ WAIT1 SKIP IF NOT
 SWI SWITCH TASKS IF SO
WAIT1 LDAB COMREG GET WD STATUS
 BITB #BUSY CHECK IF BUSY
 BNE WAIT LOOP TIL NOT BUSY
 RTS RETURN

* SEEK
*
* SEEK THE SPECIFIED TRACK

SEEK STAB SECREG SET SECTOR
 CMPA TRKREG DIF THAN LAST?
 BEQ SEEK4 EXIT IF NOT
 STAA DATREG SET NEW WD TRACK
 JSR DEL28 GO DELAY
 LDAA #SKCMND SETUP SEEK COMMAND
 STAA COMREG ISSUE SEEK COMMAND
 JSR DEL28 GO DELAY
 BSR WAIT WAIT TIL DONE
 BITB #$10 CHECK FOR SEEK ERROR
SEEK4 JMP DEL28 DELAY

* WRITE
*
* WRITE ONE SECTOR

WRITE BSR SEEK SEEK TO TRACK
 LDAA #WTCMND SETUP WRITE SCTR COMMAND
 TST PRCNT ARE WE SPOOLING?
 BEQ WRITE2 SKIP IF NOT
 SWI CHANGE TASKS IF SO
WRITE2 NOP
 SEI DISABLE INTERRUPTS
 STAA COMREG ISSUE WRITE COMMAND
 JSR DEL28 DELAY
 CLRB SET SECTOR LENGTH (=256)
WRITE3 LDAA COMREG CHECK WD STATUS
 BITA #DRQ READY FOR DATA?
 BNE WRITE5 SKIP IF READY
 BITA #BUSY STILL BUSY?
 BNE WRITE3 LOOP IF SO
 TAB ERROR IF NOT
 BRA WRITE6
WRITE5 LDAA 0,X GET A DATA BYTE
 STAA DATREG SEND TO DISK
 INX BUMP POINTER
 DECB DEC THE COUNT
 BNE WRITE3 FINISHED?
 BSR WAIT WAIT TIL WD FINISHED
WRITE6 BITB #WTMSK MASK ERRORS
 NOP
 CLI ENABLE INTERRUPTS
 RTS RETURN

* VERIFY
*
* VERIFY LAST SECTOR WRITTEN

VERIFY LDAA #RDCMND SETUP VERIFY COMMAND
 TST PRCNT ARE WE SPOOLING?
 BEQ VERIF2 SKIP IF NOT
 SWI CHANGE TASKS IF SO
VERIF2 NOP
 SEI DISABLE INTERRUPTS
 STAA COMREG ISSUE VERIFY COMMAND
 JSR DEL28 GO DELAY
 BSR WAIT WAIT TIL WD IS DONE
 NOP
 CLI ENABLE INTERRUPTS
 BITB #VERMSK MASK ERRORS
 RTS RETURN

* RST
* RST RESTORES THE HEAD TO 00

RST STX INDEX SAVE INDEX
 BSR DRV DO SELECT
 LDAA #RSCMND SETUP RESTORE COMMAND
 STAA COMREG ISSUE RESTORE COMMAND
 BSR DEL28 DELAY
 JSR WAIT WAIT TIL WD IS FINISHED
 LDX INDEX RESTORE POINTER
 BITB #$D8 CHECK FOR ERROR
 RTS RETURN

* DRV
*
* SELECT THE SPECIFIED DRIVE

DRV LDAA 3,X GET DRIVE NUMBER
 CMPA #3 ENSURE IT'S < 4
 BLS DRV2 BRANCH IF OK
 LDAB #$0F ELSE SET ERROR VALUE
 SEC
 RTS
DRV2 BSR FNDTRK FIND TRACK
 LDAB TRKREG GET CURRENT TRACK
 STAB 0,X SAVE IT
 STAA DRVREG SET NEW DRIVE
 STAA CURDRV
 BSR FNDTRK FIND NEW TRACK
 LDAA 0,X
 STAA TRKREG PUT NEW TRACK IN WD
 BSR DEL28 DELAY
 BRA OK

* CHKRDY
*
* CHECK DRIVE READY ROUTINE

CHKRDY LDAA 3,X GET DRIVE NUMBER
 CMPA #1 BE SURE IT'S 0 OR 1
 BLS OK BRANCH IF OK
 LDAB #$80 ELSE, SHOW NOT READY
 SEC
 RTS RETURN
OK CLRB SHOW NO ERROR
 CLC
 RTS


* FIND THE TRACK FOR CURRENT DRIVE

FNDTRK LDX #DRVTRK POINT TO TRACK STORE
 LDAB CURDRV GET CURRENT DRIVE
 BEQ FNDTR4
FNDTR2 INX POINT TO DRIVE'S TRACK
 DECB
 BNE FNDTR2
FNDTR4 RTS RETURN

* DELAY

DEL28 JSR  DEL14
DEL14 JSR  DEL
DEL RTS


 END
