;
;**************************************
;
; SRT: SPECIAL READ TRACK ROUTINE
;
; USES SECTOR SKEW TABLE TO READ IN
; SECTORS FROM THE DISK.
; ALLOWS USER TO READ TRACKS THAT HAVE
; A DOUBLE SECTOR ON THEM.
; THE FIRST SECTOR IN THE TABLE SHOULD
; NOT BE A DOUBLE SECTOR
;
;**************************************
;
SRT	PROC
;
:STATUS	=	$A0
:COUNT	=	$A1
:SERR	=	$3F00	;SPECIAL ERROR AREA
;
;SET UP BUFFER POINTER
;
	LDA	#$00
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	JSR	FINT	;CLEAR OUT ANY OLD COMMANDS
	LDA	#$FF
	STA	TINB	;CLEAR BUFFER FLAG
	LDA	CMDFRM+2	;GET AUX 1
	STA	NTRK
	JSR	SKTK	;GOTO THAT TRACK
;
;ZERO SPECIAL ERROR AREA
;
	LDA	#$00
	LDX	#0
:SRT01	STA	:SERR,X
	INX
	BNE	:SRT01
;
	LDA	#128
	STA	LENTH	;SET LENTH TO 128 BYTES
	LDA	#$00
	STA	:COUNT	;SECTOR COUNT
:LOOP	LDX	:COUNT
	LDA	SKTAB,X	;GET FIRST SECTOR
	BEQ	:SRT02	;EXIT LOOP IF SECTOR=0
	LDY	DTAREG	;DUMMY READ
	JSR	RSEC
	LDX	:COUNT
	LDA	STAT+1	;GET FDC STATUS
	STA	:SERR,X
	LDA	#$80
	CLC
	ADC	BPNT	;INCREMENT BUFFER POINTER
	STA	BPNT
	LDA	#0
	ADC	BPNT+1
	STA	BPNT+1
	INC	:COUNT
	INX
	CPX	#26	;TWENTY SIX SECTORS, NO WAY
	BNE	:LOOP
	LDA	#$01
	STA	:STATUS
	JMP	:SRTXT
:SRT02	LDA	#0
	STA	:STATUS
:SRTXT	RTS
;
	EPROC
;
;
;**************************************
;
; SPWT: SPECIAL WRITE TRACK ROUTINE
;
;**************************************
;
SPWT	PROC
;
:STATUS	=	$A0
:COUNT	=	$A1
:SERR	=	$3F00	;SPECIAL ERROR AREA
;
;SET UP BUFFER POINTER
;
	LDA	#$00
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	JSR	FINT	;CLEAR OUT ANY OLD COMMANDS
	LDA	#$FF
	STA	TINB	;CLEAR BUFFER FLAG
	LDA	CMDFRM+2	;GET AUX 1
	STA	NTRK
	JSR	SKTK	;GOTO THAT TRACK
;
;
	LDA	#128
	STA	LENTH	;SET LENTH TO 128 BYTES
	LDA	#$00
	STA	:COUNT	;SECTOR COUNT
;
;FIRST HALF OF TRACK WRITE
;
:LOOP	LDX	:COUNT
	LDA	:SERR,X	;CHECK THE TYPE OF ERROR
	EOR	#$FF
	STA	TEMP	;PUT STATUS IN TEMP PLACE
	AND	#$08	;CHECK FOR CRC ERROR
	BEQ	:SWT05
;
	LDA	SKTAB,X
	BEQ	:SWT02	;END OF TABLE
	LDY	DTAREG	;DUMMY READ
	JSR	CRC	;WRITE CRC ERROR TO DISK
	JMP	:SWT04
;
:SWT05	LDA	TEMP
	AND	#$20	;CHECK FOR DELTED DATA MARK
	BEQ	:SWT03
	LDA	SKTAB,X	;GET FIRST SECTOR
	BEQ	:SWT02	;EXIT LOOP IF SECTOR=0
	LDY	DTAREG	;DUMMY READ
	JSR	SWS
	JMP	:SWT04
;
:SWT03	LDA	SKTAB,X	;GET FIRST SECTOR
	BEQ	:SWT02	;EXIT LOOP IF SECTOR=0
	LDY	DTAREG	;DUMMY READ
	JSR	WSEC
;
:SWT04	BCC	:SWT14	;STATUS OK
	LDA	#$01
	STA	:STATUS
	JMP	:SWTXT	;BARF
;
:SWT14	CLC
	LDA	#$01
	ADC	BPNT+1
	STA	BPNT+1
	INC	:COUNT
	INC	:COUNT
	JSR	DELAY	;MAKE SURE WE MISS NEXT
	LDX	:COUNT
	CPX	#26	;TWENTY SIX SECTORS, NO WAY
	BNE	:LOOP
;
;SECOND HALF OF TRACK WRITE
;
:SWT02	LDA	#$20
	STA	BPNT+1
	LDA	#$80
	STA	BPNT
	LDA	#$01
	STA	:COUNT	;SECTOR COUNT
;
:LOOP1	LDX	:COUNT
	LDA	:SERR,X	;CHECK THE TYPE OF ERROR
	EOR	#$FF
	STA	TEMP	;PUT STATUS IN TEMP PLACE
	AND	#$08	;CHECK FOR CRC ERROR
	BEQ	:SWT06
;
	LDA	SKTAB,X
	BEQ	:SWT09	;END OF TABLE
	LDY	DTAREG	;DUMMY READ
	JSR	CRC	;WRITE CRC ERROR TO DISK
	JMP	:SWT08
;
:SWT06	LDA	TEMP
	AND	#$20	;CHECK FOR DELTED DATA MARK
	BEQ	:SWT07
	LDA	SKTAB,X	;GET FIRST SECTOR
	BEQ	:SWT09	;EXIT LOOP1 IF SECTOR=0
	LDY	DTAREG	;DUMMY READ
	JSR	SWS
	JMP	:SWT08
;
:SWT07	LDA	SKTAB,X	;GET FIRST SECTOR
	BEQ	:SWT09	;EXIT LOOP1 IF SECTOR=0
	LDY	DTAREG	;DUMMY READ
	JSR	WSEC
;
:SWT08	BCC	:SWT18	;STATUS OK
	LDA	#$01
	STA	:STATUS
	JMP	:SWTXT	;BARF
;
:SWT18	CLC
	LDA	#$01
	ADC	BPNT+1
	STA	BPNT+1
	INC	:COUNT
	INC	:COUNT
	JSR	DELAY	;MAKE SURE WE MISS NEXT
	LDX	:COUNT
	CPX	#26	;TWENTY SIX SECTORS, NO WAY
	BNE	:LOOP1
;
	LDA	#$01
	STA	:STATUS
	JMP	:SWTXT
:SWT09	LDA	#0
	STA	:STATUS
:SWTXT	RTS
;
	EPROC
	RTS
;
;**************************************
;
; CRC: PUTS A CRC ERROR ON THE DISK
;    : WHERE WE WANT IT WITH THE DATA
;    : THAT WE WANT WE HOPE
; ENTRY:BPNT POINTS TO DATA TO WRITE
;      :ACC HOLDS SECTOR NUMBER
;      :X REG HOLD CURRENT BLOCK NUM
;  EXIT:$A0 HOLDS STATUS
;
;**************************************
;
CRC	PROC
;
:STATUS	=	$A0
:LEN	=	$A1
;
	STA	SECREG
	LDA	TRACK
	STA	TRKREG	;SET UP SECTOR TO WRITE TO
:WCE01	LDY	#$00
	LDX	#$00
	LDA	#$E6
	JSR	STMO
	LDA	#$20	;DELETED DATA MARK MASK
	AND	TEMP
	BEQ	:WCE12
	LDA	WSDMCM	;WRITE SECTOR COMMAND
			;DELEATED DATA MARK
	BNE	:WCE22
:WCE12	LDA	WSECCM	;NORMAL WRITE SECTOR
:WCE22	STA	CMDREG
:WCE02	LDA	(BPNT),Y
	EOR	#$FF	;LOAD AND COMPLEMENT DATA
:WCE03	BIT	DRA	;CHECK FOR WHEN FDC REDY
	BVC	:WCE10	;TIME OUT ERROR
	BPL	:WCE03	;LOOP UNTIL READY
	STA	DTAREG	;SEND DATA TO FDC 4
	LDA	WT64D	;4
	INY	;2
	CPY	LENTH	;COMPARE WITH SECTOR :LEN 3
	BNE	:WCE02	;2
	JSR	FINT	;STOP WRITE NOW!
	LDA	#$01
:WCE04	BIT	STREG
	BNE	:WCE04	;LOOP UNTIL DONE
	LDA	STREG
	LDA	#0
	STA	:STATUS	;SET STATUS OK!
	CLC
	RTS
:WCE10	LDA	STREG
	AND	#$01	;CHECK FOR BUSY
	BEQ	:WCE20
	LDA	#$E6
	JSR	STMO
	BNE	:WCE02
:WCE20	LDA	WT64D
	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BNE	:WCE01
	LDA	STREG
	LDA	#$01
	STA	:STATUS	;SET STATUS YUCKY!
	SEC
	RTS
	EPROC
;
;**************************************
;
; REVT:WAIT FOR ONE DISK REVOLUTION
;
;**************************************
;
REVT	PROC
;
	LDA	#$C6	;A LITTLE LESS THAN ONE REV
	JSR	STMO
:LOOP	BIT	DRA	;WAIT FOR INTERRUPT
	BVS	:LOOP
	RTS
	EPROC
;
;
;**************************************
;
; CKBF: CHECK SECTOR BUFFER FOR GARBAGE
;
; ENTRY:ACC=TRACK
;      :X=LSB OF POINTER TO BUFFER
;      :Y=MSB OF POINTER TO BUFFER
;  EXIT:$A0 NUMBER OF SECTORS FOUND
;
;**************************************
;
CKBF	PROC
;
;LOCAL VARIABLES
;
:STATUS	=	$A0
:TRACK	=	$2800
:TDPNT	=	$2801	;POINTER TO TRACK INFO
			;2 BYTES
:INDX	=	$2803
:ADAT	=	$2804
:JNDX	=	$2805
:COUNT	=	$2806
:SECTOR	=	$2807
:FSTAT	=	$2817
:K	=	$2818
;
	STA	:TRACK
	STX	:TDPNT
	STY	:TDPNT+1
	LDY	#0
	STY	:COUNT
	STY	:INDX
	STY	:K
:LOOP0	LDA	:TDPNT	;SET PNTER TO TDPNT
	STA	BPNT1
	LDA	:TDPNT+1
	STA	BPNT1+1
	LDY	:INDX
	LDA	(BPNT1),Y	;LOAD TRACK DATA
	STA	:ADAT
	CLC
	LDA	#2
	ADC	:INDX
	TAY
	LDA	(BPNT1),Y
	STA	:SECTOR
	LDA	#6	;FDC STATUS
	CLC
	ADC	:INDX
	TAY
	LDA	(BPNT1),Y
	AND	#%00011000
	STA	:FSTAT
;
	LDA	:ADAT
	CMP	:TRACK	;ADAT<>TRACK?
	BNE	:CK001
;
	LDA	:FSTAT
	BNE	:CK001	;BAD FDC STATUS
;
	LDA	:SECTOR
	BEQ	:CK001	;SECTOR=0
	CMP	#19	;SECTOR >= 19?
	BCC	:CK002
;
:CK001	LDA	:INDX
	LDX	:TDPNT
	LDY	:TDPNT+1
	JSR	DLNTRY	;DELETE BAD ENTRY
	INC	:K	;INCREMENT MAX DELETE COUNT
	LDA	:K
	CMP	#32
	BEQ	:CK004	;EXIT WHEN EQUAL
	JMP	:CK003
;
:CK002	INC	:COUNT	;COUNT==+1
	INC	:INDX	;INDX==+1
	LDA	#$00
	STA	:JNDX
;
:LOOP1	LDY	:INDX
	LDA	:ADAT
	ORA	(BPNT1),Y
	STA	:ADAT
	INC	:INDX
	INC	:JNDX
	LDX	:JNDX
	CPX	#7
	BNE	:LOOP1
	LDA	:ADAT
	CMP	#0	;END OF SECTOR DATA?
	BEQ	:CK004
;
:CK003	LDA	:INDX
	CMP	#240
	BCS	:CK004
	JMP	:LOOP0
:CK004	LDA	:COUNT
	STA	:STATUS
	RTS
	EPROC
;
;*************************************
;
; DLNTRY: DELETE ENTRY IN TRACK DATA
;
;  ENTRY:ACC=INDEX OF ENTRY TO DELETE
;       :X=LSB OF BUFFER
;       :Y=MSB OF BUFFER
;   EXIT:NONE
;
;*************************************
;
DLNTRY	PROC
;
:INDX	=	$2808
:TDPNT	=	$2809	;POINTER 2 BYTES
:JNDX	=	$280B
;
	STA	:INDX
	STX	:TDPNT
	STY	:TDPNT+1
;
	CLC
	LDA	:INDX
	ADC	#$08
	STA	:JNDX
	LDA	:TDPNT
	STA	BPNT1
	LDA	:TDPNT+1
	STA	BPNT1+1
:LOOP0	LDY	:JNDX
	LDA	(BPNT1),Y
	LDY	:INDX
	STA	(BPNT1),Y
	INC	:INDX
	INC	:JNDX
	BNE	:LOOP0
	RTS
	EPROC
;
;*************************************
;
; RTAT: MOVES ENTRYS AROUND
;
; ENTRY:ACC=LSB OF BUFFER POINTER
;      :X=MSB OF BUFFER POINTER
;      :Y=NUMBER OF ENTRY TO MOVE
;  EXIT:NONE
;
;*************************************
;
RTAT	PROC
;
:DPNT	=	$A0
:ENT1	=	$A2
:INDX	=	$A3
:JNDX	=	$A4
:CNT	=	$A5
;
	STA	:DPNT
	STX	:DPNT+1
	STY	:ENT1
;
	LDY	#0	;SAVE FIRST ENTRY ON STACK
:LOOP	LDA	(:DPNT),Y
	PHA	;SAVE DATA
	INY
	CPY	#8
	BNE	:LOOP
;
	LDA	#0
	STA	:INDX	;DESTINATION INDEX
	LDA	#8
	STA	:JNDX	;SOURCE INDEX
	LDA	:ENT1
	ASL	A
	ASL	A
	ASL	A	;MULT TIME 8
	STA	:CNT
;
:LOOP1	LDY	:JNDX
	LDA	(:DPNT),Y
	LDY	:INDX
	STA	(:DPNT),Y
	INC	:INDX
	INC	:JNDX
	LDA	:JNDX
	CMP	:CNT
	BNE	:LOOP1
;
	LDX	#0
:LOOP2	DEC	:JNDX
	LDY	:JNDX
	PLA
	STA	(:DPNT),Y
	INX
	CPX	#8
	BNE	:LOOP2
	RTS
	EPROC
;
;**************************************
;
; CMP: COMPARE TWO BUFFERS OF DATA FOR
;      EQUIVELENT SECTOR DATA
;
; ENTRY:ACC=LSB OF POINTER TO BUFF1
;      :X = MSB OF POINTER TO BUFF1
;      :Y = LSB OF POINTER TO BUFF2
;      :$A3=MSB OF POINTER TO BUFF2
;      :$A4=NUMBER OF SECTORS
;  EXIT:$A0=0 IF GOOD, 1 IF BAD
;
;**************************************
;
CMP	PROC
;
;LOCAL VARIABLES
;
:STATUS	=	$A0
:PARM1	=	$A3
:PARM2	=	$A4
:PNT1	=	$280E	;POINTER TO BUFF1 DATA
:PNT2	=	$2810	;POINTER TO BUFF2 DATA
:NUMS	=	$2812	;NUMBER OF SECTORS
:TRYS	=	$2813	;NUMBER OF TIMES
:INDX	=	$2814
:ADAT	=	$2815
:BDAT	=	$2816
;
:TPNT1	=	$A0	;TEMPORARY POINTER REGS
:TPNT2	=	$A2
;
;MAKE THE FIRST SECTOR IN EACH BUFFER
;THE SAME
;
;SAVE PASSED PARAMETERS
;
	STA	:PNT1
	STX	:PNT1+1
	STY	:PNT2
	LDA	:PARM1
	STA	:PNT2+1
	LDA	:PARM2
	STA	:NUMS
;
	LDY	#0	;TRYS := 0
	STY	:TRYS
;
:LOOP	LDA	:PNT1
	STA	:TPNT1
	LDA	:PNT1+1
	STA	:TPNT1+1
	LDY	#2	;POINT TO SECTOR ADDRESS
	LDA	(:TPNT1),Y
	STA	:ADAT
	LDA	:PNT2
	STA	:TPNT2
	LDA	:PNT2+1
	STA	:TPNT2+1
	LDA	(:TPNT2),Y
	STA	:BDAT
;
	CMP	:ADAT
	BEQ	:CMP01	;ENTRIES = COMPARE ARRAY
;
;ROTATE BUFF1
;
	LDA	:PNT1
	LDX	:PNT1+1
	LDY	:NUMS
	JSR	RTAT
	INC	:TRYS
	LDA	:TRYS
	CMP	:NUMS	;EXHASTED ALL POSIBILITIES?
	BNE	:LOOP
:CMP02	LDA	#$01
	STA	:STATUS	;SEND BAD STATUS BACK
	JMP	:CMPXT
;
;COMPARE ENTIRE BUFFER
;
:CMP01	LDA	:PNT1	;SET UP POINTERS
	STA	:TPNT1
	LDA	:PNT1+1
	STA	:TPNT1+1
	LDA	:PNT2
	STA	:TPNT2
	LDA	:PNT2+1
	STA	:TPNT2+1
;
	LDA	#0
	STA	:TRYS	;INIT LOOP COUNT
	LDA	#2
	STA	:INDX
:LOOP1	LDY	:INDX
	LDA	(:TPNT1),Y
	CMP	(:TPNT2),Y
	BNE	:CMP02	;BAD DATA, BREAK FROM LOOP
	LDA	:INDX
	CLC
	ADC	#8	;INDX ==+8
	STA	:INDX
	INC	:TRYS
	LDA	:TRYS
	CMP	:NUMS	;END OF SEARCH?
	BNE	:LOOP1	;NO
	LDA	#0
	STA	:STATUS	;GOOD SEARCH
:CMPXT	RTS
	EPROC
;
;
;*************************************
;
; FDCCK: CHECK FLOPPY DISK CONTROLLER
;        TYPE
;
; ENTRY:ACC=TRACK TO CHECK
;  EXIT:$A0=0 IF FDC CHECKED
;      :$A0=1 IF ERROR
;      :IF ERROR, FDC COMMANDS SET TO
;      :1793 TYPE, ELSE SET TO TYPE
;      :FOUND AND  FOUND FLAG IS SET
;      :TO FDC FOUND STATUS
;      :$00=FOUND
;      :$FF=NOT FOUND
;
; KILLS: X-REG, A-REG
; SAVES: $A1 CONTENTS
;
;**************************************
;
FDCCK	PROC
;
:STATUS	=	$A0
:TRACK	=	$A1
;
	TAX	;SAVE ACC
	LDA	:TRACK
	PHA	;SAVE FOR EXIT
	STX	:TRACK
	LDA	FDCFLG	;CHECK FDC FLAG
	BNE	:FD001	;NO FOUND, CHECK IT OUT
;
	LDA	#$00	;ALREADY FOUND, EXIT
	STA	:STATUS
	JMP	:FDCXT
;
;TRY 1793 COMMAND FIRST
;
:FD001	LDA	:TRACK
	STA	NTRK
	JSR	SKTK	;SEEK TRACK
;
	LDA	:C2793
	STA	RSECCM
	LDA	#0
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	LDA	#$01	;SECTOR 1
	JSR	RSEC
	BCS	:FD002	;NO GOOD, TRY 1797 COMMAND
;
;COMMAND GOOD, SET FDC COMMANDS TO 2793
;
	LDX	#$00
:LOOP1	LDA	:C2793,X
	STA	RSECCM,X
	INX
	CPX	#$03
	BNE	:LOOP1
	LDA	#$0
	STA	FDCFLG
	STA	:STATUS
	JMP	:FDCXT	;EXIT ROUTINE
;
:FD002	LDA	:C2797	;LOAD COMMAND 1797
	STA	RSECCM
	LDA	#$01	;SECTOR 1
	JSR	RSEC	;READ SECTOR
	BCS	:FD003	;NOT THIS EITHER, BAD DISK?
;
	LDX	#$00
:LOOP2	LDA	:C2797,X
	STA	RSECCM,X
	INX
	CPX	#$03
	BNE	:LOOP2
	LDA	#$00
	STA	FDCFLG
	STA	:STATUS
	JMP	:FDCXT
;
;FDC NOT FOUND, SET TO 1793 FOR NOW
;
:FD003	LDX	#$00
:LOOP3	LDA	:C2793,X
	STA	RSECCM,X
	INX
	CPX	#$03
	BNE	:LOOP3
	LDA	#$01
	STA	:STATUS
:FDCXT	PLA
	STA	:TRACK
	RTS
:C2793	DB	$82,$A2,$A3
:C2797	DB	$88,$A8,$A9
	EPROC
;
	DB	'2793/2797 VERSION'
	DB	'REV 3.10 '
	DB	'2-21-87
	DB	'COPYRIGHT (C) 1986 BY EMC'
	DB	'COPYRIGHT (C) 1986 BY DTI'
;
	ORG	$5FFC
	LOC	$FFFC
	DW	START	;RESET VECTOR
	DW	START	;IRQ VECTOR
;
	END
;
