;
;**************************************
;
; READ SECTOR FROM DISK
;
; ENTRY:ACC=SECTOR NUMBER
;      :BUFFER POINTER POINTS TO SECTOR
;      :BUFFER WHERE DATA IS TO BE PUT
;  EXIT:CARRY SET IF ANY ERROR
;
;**************************************
;
RSEC	PROC
;
:STATUS	=	$A0
;
	STA	SECREG	;STORE IN SECTOR REG
	LDA	TRACK
	STA	TRKREG	;SET UP TRACK REGISTER
RSEC12	LDY	#$00	;SET UP INDEX POINTER
	LDA	#$E6
	STA	WT24E	;SET TIME OUT
	LDA	RSECCM	;READ SECTOR COMMAND
	STA	CMDREG	;PUT INTO COMMAND REGISTER
RSEC01	BIT	DRA	;TEST STATUS
	BVC	RSEC10	;TIMEOUT
	BPL	RSEC01	;DATA NOT READY YET
	LDA	DTAREG	;LOAD DATA REGISTER
	EOR	#$FF	;COMPLEMENT DATA IF NEED BE
	STA	(BPNT),Y	;STORE IN BUFFER
;	LDA	RTDE	;CLEAR TIMEOUT COUNTER
	INY
	CPY	LENTH	;COMPARE LENTH OF SECTOR
	BNE	RSEC01	;NOT DONE KEEP GETTING DATA
	LDA	#$01	;MASK FOR FDC
RSEC02	BIT	STREG	;CHECK FDC STATUS
	BNE	RSEC02
	LDA	STREG
	EOR	#$FF
	STA	STAT+1
	EOR	#$FF	;PUT IT BACK THE WAY IT WAS
	AND	#%00101000	;CHECK CRC AND
			;DELETED DATA MARK
	BEQ	:RS003
	LDA	#$01	;SET BAD STATUS
	STA	:STATUS
	SEC
	BCS	RSECXT
:RS003	LDA	#0	;OK NO PROBLEM
	STA	:STATUS	;RETURN GOOD STATUS
	CLC
RSECXT	RTS
RSEC10	LDA	STREG
	AND	#$01
	BEQ	RSEC11
	LDA	#$E6
	JSR	STMO	;SET TIMEOUT
	BNE	RSEC01
RSEC11	LDA	WT64D
	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BNE	RSEC12
	LDA	#$01
	STA	:STATUS	;SET YUCKY STATUS
	LDA	STREG
	EOR	#$FF
	STA	STAT+1	;SAVE FDC STATUS
	SEC
	BCS	RSECXT	;ERROR EXIT
	EPROC
;
;
;**************************************
;
; VERIFY SECTOR JUST READ
;
; ENTRY:ACC=SECTOR NUMBER
;      :BUFFER POINTER POINTS TO SECTOR
;      :BUFFER WHERE DATA IS TO BE PUT
;  EXIT:CARRY SET IF ANY ERROR
;
;**************************************

VSEC	PROC
;
:STATUS	=	$A0
;
	STA	SECREG	;STORE IN SECTOR REG
	LDA	TRACK
	STA	TRKREG	;SET UP TRACK REGISTER
	LDA	#$00
	STA	:STATUS
	STA	TEMP	;CLEAR FLAG
:VSEC1	LDY	#$00	;SET UP INDEX POINTER
	LDX	#$00
	LDA	#$F6
	JSR	STMO	;SET TIME OUT
	LDA	RSECCM	;READ SECTOR COMMAND
	STA	CMDREG	;PUT INTO COMMAND REGISTER
:VSEC2	BIT	DRA	;TEST STATUS
	BVC	:VSEC6	;TIMEOUT
	BPL	:VSEC2	;DATA NOT READY YET
	LDA	DTAREG	;LOAD DATA REGISTER
	EOR	#$FF	;COMPLEMENT DATA
	CMP	(BPNT),Y	;COMPARE WITH BUFFER
	BEQ	:VSEC3	;DATA OK
	LDA	#$FF
	STA	TEMP	;SET FLAG
:VSEC3	INY
	CPY	LENTH	;COMPARE LENTH OF SECTOR
	BNE	:VSEC2	;NOT DONE KEEP GETTING DATA
	LDA	#$01	;MASK FOR FDC
:VSEC4	BIT	STREG	;CHECK FDC STATUS
	BNE	:VSEC4
	LDA	STREG
	EOR	#$FF
	STA	STAT+1
	EOR	#$FF
	AND	#%00111000	;CHECK FOR ERRORS
	BNE	:VSEC8
	LDA	#0	;SET GOOD STATUS
	STA	:STATUS
	CLC
:VSEC5	LDA	TEMP	;LOAD FLAG
	BPL	:VSECXT	;DATA OK
	LDA	#$01
	STA	:STATUS	;SET BAD STATUS
	SEC
	BCS	:VSECXT	;BAD READ
:VSEC6	INC	:STATUS
	CMP	#$02	;TRY TWO TIMES
	BEQ	:VSEC8
	LDA	STREG
	AND	#$01
	BEQ	:VSEC7
	LDA	#$E6
	JSR	STMO	;SET TIMEOUT
	BNE	:VSEC2
:VSEC7	LDA	WT64D
	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BNE	:VSEC1
:VSEC8	LDA	#$01
	STA	:STATUS
	SEC
:VSECXT	RTS
	EPROC
;
;
;**************************************
;
; READ TRACK ROUTINE
;
; ENTRY:NONE
;  EXIT:CARRY SET IF ERROR
;      :$A0 = # OF BAD SECTORS
;**************************************

RDTK	PROC
;
:STATUS	=	$A0
:COUNT	=	$A5	;COUNT OF SECTORS
;
	JSR	FINT
	JSR	NTS
	LDA	TINB
	CMP	#$FF	;BUFFER EMPTY?
	BEQ	:RTK02	;YES READ TRACK
;
	CMP	NTRK	;IS NEW TRACK DIFFERENT?
	BNE	:RTK02
	LDA	#01	;INDICATE MOTOR NOT TURNED ON
	STA	:STATUS
	CLC	;CLEAR CARRY FOR OK
	BCC	:RTKXT
;
:RTK02	JSR	MCK	;CHECK MOTOR THING
	JSR	SKTK	;SEEK TRACK IF NESSESACARY
	BCC	:RTK12
	LDA	#$01	;MOTOR WAS ON STATUS
	STA	:STATUS
	BCS	:RTKXT
;
:RTK12	LDX	#0
	TXA
	STA	:COUNT	;INIT GOOD SECTOR COUNT
;
:RTK05	STA	TRKCH,X	;CLEAR SECTOR STATUS
	INX
	CPX	CONFIG+3	;ALL SECTOR STATS CLEAR?
	BNE	:RTK05
:RTK01	LDX	:COUNT	;LOAD INDEX TO SKTAB
	LDA	SKTAB,X	;SECTOR NUMBER
	JSR	CTS	;CHECK FOR SECTOR 1,2,3 ON
			;TRACK ZERO
	JSR	SBPNT	;SET BUFFER POINTER
	LDY	DTAREG	;DUMMY READ
	JSR	RSEC	;READ IN SECTOR
	LDX	:COUNT
	LDA	SKTAB,X	;SECTOR NUMBER
	TAX
	DEX
	LDA	STAT+1	;GET FDC STATUS
	STA	TRKCH,X	;STORE IN SECTOR CHECK
;
	INC	:COUNT
	LDA	:COUNT
	CMP	CONFIG+3	;ALL SECTORS?
	BEQ	:RTK03	;YES, EXIT
	LDA	SKTAB,X	;LOAD SECTOR
	JSR	SBPNT
	JMP	:RTK01
:RTK03	LDA	NTRK
	STA	TINB	;SET TRACK IN BUFFER IND.
	CLC
	LDA	#$0	;INDICATE THAT MOTOR WAS
	STA	:STATUS	;TURNED ON
:RTKXT	RTS
	EPROC
;
;
;**************************************
;
; SET BUFFER POINTER TO MEMORY PAGE FOR
; SECTOR
; ENTRY:ACC=SECTOR NUMBER
;  EXIT:BPNT=PAGE POINTER
;
; ALL REGISTERS PRESERVED
;
;**************************************
;
SBPNT	PROC
;
:BFOFF	=	$82	;BUFFER OFFSET
;
	STA	:BFOFF+1
	PHA	;SAVE SECTOR NUMBER
	TXA	;SAVE X REGISTER
	PHA
;
	DEC	:BFOFF+1
;
	LDA	#$20
	BIT	STAT	;CHECK DENSITIES
	BMI	:SB128	;128 BYTE SECTORS
	BEQ	:SB128	;128 BYTE SECTORS
	CLC
	LDA	:BFOFF+1	;THESE ARE 256 BYTE BUFFERS
	ADC	#HIGH BUFF
	STA	BPNT+1
	LDA	#$00
	STA	BPNT
	BEQ	:SBXIT
;
:SB128	LDX	#$00	;DO A 7 BIT SHIFT LEFT
	STX	:BFOFF
	LSR	:BFOFF+1
	ROR	:BFOFF
	CLC
	LDA	#LOW BUFF
	ADC	:BFOFF
	STA	BPNT
	LDA	#HIGH BUFF
	ADC	:BFOFF+1
	STA	BPNT+1
;
:SBXIT	PLA
	TAX	;RECOVER X REG
	PLA	;RECOVER ACC
	RTS
	EPROC
;
;**************************************
; READ SECTOR
;
; ENTRY:NONE
;  EXIT:CARRY SET IF ERROR
;
;**************************************
;
RDSC	LDA	NSEC
	JSR	SBPNT
	JSR	CTS	;SET LENTH ACORDING TO TRACK 0
			;AND SECTOR 1,2,3
	LDA	LENTH	;LENTH OF SECTOR
	JSR	SEND
	RTS
;
;**************************************
;
; TURN ON DRIVE MOTOR
;
; ENTRY:NONE
;  EXIT:NONE
;
; PRESERVES ALL USED REGISTERS
;
;**************************************
;
MOON	PROC
	PHA
	LDA	DRA	;LOAD DATA REGISTER
	AND	#$F7	;SET CONTROLL BIT LOW
	STA	DRA	;FOR MOTOR
	LDA	#$FF
	STA	MFLAG	;SET MOTOR ON FLAG
	LDA	STAT
	ORA	#$10
	STA	STAT
	LDA	STPPOS
	ORA	#$01
	STA	DRB	;TURN ON STEPPER MOTOR
	PLA
	RTS
	EPROC
;
;**************************************
;
; TURN OFF DRIVE MOTOT
;
; ENTRY:NONE
;  EXIT:NONT
;
; PRESERVES ALL REGISTERS
;
;**************************************
;
MOOFF	PROC
	PHA
	LDA	DRA	;LOAD DATA REGISTER
	ORA	#$08	;SET MOTOR CONTROL BIT HIGH
	STA	DRA
	LDA	STAT
	AND	#$EF
	STA	STAT
	LDA	DRB	;TURN OFF STEPPER MOTOR
	STA	STPPOS
	ORA	#%00111100	;ALL BITS OFF
	STA	DRB
	PLA
	RTS
	EPROC
;
;**************************************
;
; INIT 5 SECOND TIMER
;
; ENTRY:NONE
;  EXIT:NONE
;
; PRESERVES ALL REGISTERS
;
;**************************************
;
I5SEC	PHA
	LDA	TL	;LOAD TIME LIMIT
	STA	TC
	LDA	#$97	;.1 SECOND INTERVAL
	JSR	STMO	;START TIMER
	PLA
	RTS
;
;**************************************
;
; CHECK 5 SECOND TIMER
;
; ENTRY:NONE
;  EXIT:CARRY SET IF TIMED OUT
;
; PRESERVES ALL REGISTERS
;
;**************************************
;
CK5S	PHA
	BIT	DRA	;CHECK FOR TIMER TIMEOUT
	BVS	CK5SXT
	DEC	TC	;DECREMENT TIMER COUNT
	LDA	TC
	BEQ	CK5S01	;COUNT ENDED
	LDA	#97
	JSR	STMO	;RESET TIMER
	CLC
	BCC	CK5XIT
CK5S01	LDA	RTDE	;DISABLE TIMER
	SEC
	BCS	CK5XIT
CK5SXT	CLC
CK5XIT	PLA
	RTS
;
;**************************************
;
; WRITE SECTOR
;
; ENTRY:ACC=SECTOR TO WRITE
;      :BUFFER POINTER POINTS TO DATA
;  EXIT:CARRY SET IF ANY ERRORS
;
;**************************************
;
WSEC	PROC
;
:STATUS	=	$A0
;
	STA	SECREG
	LDA	TRACK
	STA	TRKREG	;SET UP SECTOR TO WRITE TO
WSEC01	LDY	#$00
	LDA	#$E6
	STA	WT24E
	LDA	WSECCM	;WRITE SECTOR COMMAND
	STA	CMDREG
WSEC02	LDA	(BPNT),Y
	EOR	#$FF	;LOAD AND COMPLEMENT DATA
WSEC03	BIT	DRA	;CHECK FOR WHEN FDC REDY
	BVC	WSEC10	;TIME OUT ERROR
	BPL	WSEC03	;LOOP UNTIL READY
	STA	DTAREG	;SEND DATA TO FDC
	LDA	WT64D
	INY
	CPY	LENTH	;COMPARE WITH SECTOR LENTH
	BNE	WSEC02
	LDA	#$01
WSEC04	BIT	STREG
	BNE	WSEC04	;LOOP UNTIL DONE
	LDA	STREG
	LDA	#0
	STA	:STATUS	;SET STATUS OK!
	CLC
	RTS
WSEC10	LDA	STREG
	AND	#$01	;CHECK FOR BUSY
	BEQ	WSEC20
	LDA	#$E6
	JSR	STMO
	BNE	WSEC02
WSEC20	LDA	WT64D
	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BNE	WSEC01
	LDA	STREG
	LDA	#$01
	STA	:STATUS	;SET STATUS YUCKY!
	SEC
	RTS
	EPROC
;
;
;**************************************
;
;	ITRKS : INITIALIZE A SINGLE DENSITY
;		TRACK BY SETTING UP A MODEL TRACK
;		IN RAM AT LOCATION $2000
;
;	ENTRY : SECT IS SECTOR #
;	        TRCK IS TRACK #
;	EXIT  : MODEL TRACK AT $2000
;
;**************************************

ITRKS	LDA	#$00
	STA	BPNT
	LDA	#$20
	STA	BPNT+1	;COPY BASE POINTER

	LDY	#0	;INITIALIZE INDEX
	LDX	#$AC	;# OF BYTES TO LOOP
	LDA	#0	;INIT BYTES TO $FF
TKHDR1	DEX		;DECREMENT LOOP COUNT
	STA	(BPNT),Y	;STORE DATA
	JSR	IBPNT	;INC BASE
	CPX	#0	;STOP LOOP?
	BNE	TKHDR1

	LDA	#$FC	;INIT BYTE TO $FC
	STA	(BPNT),Y	;STORE DATA
	JSR	IBPNT	;INC BASE		;UPDATE BASE INDEX

	LDX	#16
	LDA	#0
TKHDR3	DEX
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE
	CPX	#0
	BNE	TKHDR3	;END OF TRACK HEADER?

	LDX	#0
	STX	SECT	;SECT IS SECTOR # INDEX

; BEGIN SECTOR FORMAT MODEL

SHDR1	LDX	#6	;6 BYTES
	LDA	#0	;LOAD 0
SHDR2	DEX
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE
	CPX	#0
	BNE	SHDR2

	LDA	#$FE
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDA	TRCK	;TRACK #
	STA	(BPNT),Y
	JSR	STKP	;SAVE TRACK POINTER IN SKTAB
	JSR	IBPNT	;INC BASE

	LDA	#0	;SIDE #
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDX	SECT	;SECTOR #
	LDA	SKTAB,X	;GET SECTOR FROM SKEW
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDA	#0	;SECTOR LENGTH = 128
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDA	#$F7	;FOR 2 BYTE CRC
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDX	#17	;11 BYTES
	LDA	#0	;LOAD $FF
SHDR3	DEX
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE
	CPX	#0
	BNE	SHDR3

	LDA	#$FB
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDX	#128
	LDA	#$FF
SDATA	DEX
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE
	CPX	#0
	BNE	SDATA

	LDA	#$F7
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE

	LDX	#12
	LDA	#0
SECEND	DEX
	STA	(BPNT),Y
	JSR	IBPNT	;INC BASE
	CPX	#0
	BNE	SECEND

	INC	SECT
	LDA	SECT	;INCREMENT SECTOR INDEX
	CMP	#18	;DONE WITH ALL 18 SECTORS?
	BEQ	ITRKXT	;YES, NOW PAD TRACK
	JMP	SHDR1

ITRKXT	RTS	;DONE WITH TRACK IMAGE!
;
;**************************************
;
; STKP: SAVE POINTER TO TRACK NUMBER
;
; ENTRY:SECT=CURRENT SECTOR INDEX
;  EXIT:POINTER IN SKTAB
;
; SAVE X,Y AND A REGISTERS
;
;**************************************
;
STKP	PROC
;
	PHA	;SAVE ACC
	TXA	;SAVE X REG
	PHA
	LDA	SECT	;GET SECTOR INDEX
	ASL	A	;MULTIPLY BY 2
	TAX	;MOVE TO INDEX REGISTER
	LDA	BPNT
	STA	TNPNT,X	;STORE IN TRACK NUMBER
	INX
	LDA	BPNT+1
	STA	TNPNT,X	;POINTER AREA
	PLA	;GET X REG
	TAX
	PLA	;GET ACC
	RTS
;
;**************************************
;
; CTS: CHECK TRACK/SECTOR STATUS
;
; ENTRY:ACC = SECTOR
;      :NTRK = TRACK
;  EXIT:LENTH APROPRIATLY SET
;
; SAVE ACC,X,Y
;
;**************************************
;
CTS	PROC
;
	PHA	;SAVE ACCUMULATOR
	LDA	CONFIG+7	;SET LENTH
	STA	LENTH
	LDA	NTRK	;CHECK TRACK NUMBER
	BNE	:EXIT	;NOT ZERO JUST EXIT
	PLA	;GET SECTOR NUMBER
	CMP	#4	;CHECK FOR LESS THAT 4
	BCS	:EXIT1
	PHA	;SAVE SECTOR NUMBER AGAIN
	LDA	#$80	;SET LENTH TO 128
	STA	LENTH
:EXIT	PLA	;GET ACC BACK
:EXIT1	RTS
	EPROC
;
	LINK	D2:DD15M5.ASM
