* NAM SWTPDK
*
* DISK DRIVERS FOR SOUTHWEST TECHNICAL PRODUCTOS
*
* MODIFIED BY ROBERTO SANCHO TO SUPPORT MF68 DISKS ON SWTPC SIMH EMULATION
* APR/2022
*
* UPDATED BY MIKE DOUGLAS TO RUN ON REAL HARDWARE JUL/2022
*
* AFTER LOADING CP68.S19 AND THEN THIS FILE (SWTPDK.S19), SAVE CP68.SYS WITH
*    SAVE CP68.SYS,$0039,$1ECF,$0100
*
* DISK GEOMETRY: 35 TRACKS X 18 SECTORS X 128 BYTES
* TRACK 0 HAS SECTORS NUMBERED 0,1,2,4..18 (NO SECTOR 3, FIRST SECTOR IS ZERO)
* TRACK 1..34 HAS SECTORS NUMBERED 1,2..18
*
* TRACK 0: SECTORS 0,1,2: HOLD THE CP68 BOOT PROGRAM
* TRACK 0: SECTOR 4..18: DIRECTORY
* TRACK 1..34: DATA SECTORS FOR FILES
*
* FD1771 COMMANDS
*
FDRSC  EQU $0B    RESTORE
FDSKI  EQU $1B    SEEK
FDRDC  EQU $8C    READ A SECTOR
FDWRC  EQU $AC    WRITE A SECTOR

DRVREG EQU $8014  DRIVE REGISTER
CMDREG EQU $8018  COMMAND REGISTER  
TRKREG EQU $8019  TRACK REGISTER
SECREG EQU $801A  SECTOR REGISTER
DATREG EQU $801B  DATA REGISTER
*
* FCB DEFINITIONS:
*
FCBSTA EQU 5  STATUS 
FCBDBA EQU 7  DATA BUFFER ADDRESS
FCBDRV EQU 9  DRIVE#
FCBTRK EQU 10 TRACK# 
FCBSCT EQU 11 SECTOR# 
*
* USER REGISTERS
*
UA     EQU 6  RETURN "A"
UXH    EQU 7  X-REG (FCBADR)
*
*
CTRK0  EQU 0        
CTRK1  EQU 1        
CTRK2  EQU 2        
CTRK3  EQU 3        
CDRIV  EQU 4        
RCNT   EQU 5
*
NUMTRK EQU 35
NUMSEC EQU 18      
*
* START ADDRESS OF DISK DRIVER FOR MF68
*
       ORG $1D5A
*
* INIT THE DISK SYSTEM
*
INTDK  LDAA #$FF
       STAA CTRK0       
       STAA CTRK1
       STAA CTRK2       
       STAA CTRK3
       CLR CDRIV
       RTS
*
* COLD START - SET THE CP-68 START ADDRESS TO POINT HERE
*
COLD   LDX #$0103     POINT SWI TO CP/68
       STX $A012      SWI VECTOR IN SWTBUG
       JMP $07C1      JUMP TO CP/68 COLD START
*
* READ A SECTOR
*
RDSEC  SWI TABX       GET FCBADR
        FCB 3       
       LDAA FCBDRV,X GET DRIVE#
       LDX #CTRK0     POINT TO TRACK TABLE
       SWI ADDAX      ADD OFFSET
        FCB 9
       LDAB 0,X      GET ENTRY
       CMPB #$FF     INITIALIZED?
       BNE RDSEC1     YES
*
       JSR RESTOR     SEEK TRACK0
       BCS QUIT10     ERROR
*
RDSEC1 JSR DRIVE
       BCS QUIT10     ERROR
*
       LDAA #5
       STAA RCNT
*
RDSEC2 TSX
       LDX UXH,X      GET FCBADR
       LDAA FCBTRK,X GET TRACK#        
       LDAB FCBSCT,X GET SECTOR
       LDX FCBDBA,X   GET BUFFER ADRESS
*
       JSR READ       GETA SECTOR
       BEQ QUIT10     OK
*
       DEC RCNT       RETRY AGAIN?
       BNE RDSEC2     YES
       BRA QUIT
*
* WRITE A SECTOR
*
WTSEC  SWI TABX          X=FCBADR
        FCB 3
       LDAA FCBDRV,X GET DRIVE#
       LDX #CTRK0     POINT TO TABLE
       SWI ADDAX         ADD OFFSET
        FCB 9
       LDAB 0,X      GET ENTRY
       CMPB #$FF     INITIALIZED?
       BNE WTSEC1     YES      
* 
       JSR RESTOR     
       BCS QUIT10     
*
WTSEC1 JSR DRIVE
       BCS QUIT10     
*
       LDAA #5
       STAA RCNT
*
WTSEC2 TSX
       LDX UXH,X      GET FCBADR
       LDAA FCBTRK,X GET TRACK#        
       LDAB FCBSCT,X GET SECTOR
       LDX FCBDBA,X   GET BUFFER ADRESS
*
       JSR WRITE
       BEQ QUIT10     OK
*
       DEC RCNT       TRY AGAIN?
       BNE WTSEC2     YES
*
QUIT   TSTA          OK?
       BEQ QUIT10     YES
*
       LDAA #5       ERROR
*
QUIT10 TSX
       STAA UA,X     STORE RC IN USER A-REG
       LDX UXH,X      GET FCBADR
       ORAA FCBSTA,X
       STAA FCBSTA,X
       RTS
*
*
* READ A SECTOR (A=TRK, B=SECTOR)
*
READ   JSR SEEK
       LDAA #FDRDC   READ
       STAA CMDREG
       JSR DEL30U     DELAY
       LDAB #128     128 BYTES/SECTOR     
*
READ1  LDAA CMDREG
       BITA #$02     DATA REG FULL?
       BNE READ2      YES
*
       BITA #1       BUSY?
       BNE READ1      YES
*
       BRA READ3      ERROR
*
READ2  LDAA DATREG   GET A BYTE
       STAA 0,X      STORE IN BUFFER
       INX
       DECB
       BNE READ1      DO AGAIN
*
       BSR WBUSY      WAIT TILL DONE
*
READ3  ANDA #$1C     MASK OF STATUS BITS
       RTS
*
WBUSY  LDAA CMDREG
       BITA #1       BUSY?
       BNE WBUSY      YES
*
       RTS
*
* WRITE A SECTOR (A=TRK, B=SECTOR, X=DATA BUFFER)
*
WRITE  JSR SEEK
       LDAA #FDWRC   WRITE COMMAND
       STAA CMDREG
       JSR DEL30U
       LDAB #128     128 BYTES/SECTOR
*
WRITE1 LDAA CMDREG
       BITA #2       REG EMPTY?
       BNE WRITE2     YES
*
       BITA #1       BUSY?
       BNE WRITE1     YES
*
       BRA WRITE3     ERROR
*
WRITE2 LDAA 0,X      GET A BYTE
       STAA DATREG
       INX
       DECB
       BNE WRITE1     DO AGAIN
*
       JSR WBUSY      WAIT FOR BUSY
*
WRITE3 ANDA #$5C     MASK OFF STATUS BITS
       RTS
*
* SEEK TRACK IN A-REG
*
SEEK   CMPA TRKREG   ON TRACK?
       BEQ SEEK2      YES
*
       STAA DATREG   NO, STORE TRACK#
       JSR DEL30U
       LDAA #FDSKI   SEEK COMMAND
       STAA CMDREG
       JSR DEL30U
       JSR WBUSY      WAIT FOR BUSY
*
SEEK2  STAB SECREG   SET SECTOR
       JSR DEL30U
       RTS
*
* DELAY 30 USECS
*
DEL30U INX
       DEX
       INX
       DEX
       INX
       DEX
       INX
       DEX
       RTS
*
* DELAY ONE SECOND
*
DEL1S  SWI PSHX
        FCB 5
       PSHA
       LDAA #2
       LDX #0000
*
DEL1SA INX
       BNE DEL1SA
*
       DECA
       BNE DEL1SA
*
       PULA 
       SWI PULX
        FCB 6
       RTS
*
* TURN ON MOTORS (A=UNIT#)
*
MOTOR  LDAB CMDREG
       ANDB #$80     READY?
       BEQ MOTOR1     YES
*
       JSR DEL1S      DELAY A SECOND
*
       LDAB CMDREG
       ANDB #$80     READY?
       BEQ MOTOR1     YES
*
       LDAA #10      ERROR CODE
       SEC
       RTS
*
MOTOR1 CLC
       RTS
*
* DRIVE SELECT (A=DRIVE#)
*
DRIVE  ANDA #3
       PSHA
       BSR DSEL1
       BSR MOTOR
       BCS DRIV1
*
       LDAB TRKREG   GET CURRENT TRACK
       STAB 0,X      SAVE IN TABLE
       STAA DRVREG   INIT REGISTER
       STAA CDRIV    NEW CURRENT DRIVE
       BSR DSEL1
       LDAA 0,X      GET CURRENT TRK
       STAA TRKREG
       JSR DEL30U
DRIV1  PULA
       RTS
*
DSEL1  LDX #CTRK0     POINT TO TABLE
       LDAB CDRIV
       BEQ DSEL3
*
DSEL2  INX
       DECB
       BNE DSEL2
*
DSEL3  RTS
*
* RESTORE SEEK TRACK0 (X=CTRLx)
*
RESTOR PSHA
       JSR DRIVE
       BCS RESTR1     ERROR  
*
       LDAA #FDRSC   RESTORE COMMAND
       STAA CMDREG
       JSR DEL30U
*
       JSR WBUSY
       CLR 0,X        CTRKx:=00
       CLC
*
RESTR1 PULA
       RTS

*--------------------------------------------------------------------
* PATCHES TO CP/68
*--------------------------------------------------------------------
	ORG	$0100		JUMP TO OUR COLD START TO BEGIN
	JMP	COLD

	ORG	$04C4		CONSOLE PORT AT $8004
	FDB	$8004

	ORG	$075E		POINT TO SECTOR READ/WRITE ROTUINES IN 
	JMP	RDSEC		  IN THIS FILE
	JMP	WTSEC

	ORG	$16B8		CORRECT NUMBER OF SECTORS IN CLI
	FCB	NUMSEC

	ORG	$192A		CORRECT NUMBER OF SECTORS IN GETDR
	FCB	NUMSEC+1

	ORG	$17DD		CORRECT FREE SPACE RECORD FROM 3 TO 2 
	FCB	2		SECTOR 2

	ORG	$1A76
	FCB	2
	
	ORG	$1B7A
	FCB	2

	ORG	$0039		INIT PAGE ZERO DATA

* BACK SPACE, LINE-DELETE, CON LINES, CON LINE, CON WIDTH, NULLS, TAB
	FCB	$08,$15,0,1,0,0,$09

* FULL DUPLEX, PAGE LFs, PAUSE OFF, ESCAPE, LP LINES, LP LINE, LP WIDTH
	FCB	0,0,$FF,$1B,60,0,80

	END
