;
;**************************************
;
; CFMT: CUSTOM FORMAT TRACK
;
; ENTRY:ACC CONTAINS TIME FOR 1 TRACK
;      :TIME= ACC * 1.024MSEC
;      :IT IS ASSUMED THAT THE BUFFER
;      :STARTS AT $2000
;      :BUFFER WAS LOADED USING THE
;      :THE DOWNLOAD COMMAND
;      :AUX1 AND AUX2 CONTAIN #OF BYTES
;      :USES BPNT TO POINT TO BUFFER
;      :SETUP THE DENSITY LINE ON THE
;      :FDC FOR SINGLE DENSITY ON ENTRY
;      :RETURNS IT TO WHAT EVER ON EXIT
;  EXIT:NONE, DOES NOT CHECK FOR ANY
;      :ERRORS
;
;**************************************
;
CFMT	PROC
;
:STATUS	=	$A0
:TIME	=	$A1
:TRYS	=	$A2
;
	STA	:TIME
	LDA	#$00
	STA	:TRYS	;INT RETRY COUNTER
;
;CHECK TO SEE IF DOOR IS OPEN
;
	BPL	:CFT01
	BVC	:CFT01
	LDA	#$01	;SET ERROR STATUS
	JMP	:CFTXT	;EXIT ROUTINE
;
:CFT01	LDY	#$00
	LDA	#$00	;SET UP BPNT TO POINT TO
	STA	BPNT	;CUSTOM DATA IN TRACK BUFFER
	LDA	#$20
	STA	BPNT+1
	CLC	;CLEAR CARRY FOR ADD
	LDA	BPNT
	ADC	CMDFRM+2
	STA	CMDFRM+2
	LDA	BPNT+1
	ADC	CMDFRM+3
	STA	CMDFRM+3	;END OF FORMAT BUFFER
	LDA	(BPNT),Y
	JSR	IBPNT	;INCREMENT POINTER
	STA	DTAREG	;FIRST BYTE OF TRACK DATA
	LDA	#1
	STA	WT24E	;START TIMER TO GEN IP
	LDX	#$10
:LOOP	DEX
	BNE	:LOOP	;JUST DELAY A BIT, HUMOR ME
	LDA	#$F0	;FORMAT COMMAND
	STA	CMDREG
:WAIT	BIT	DRA	;WAIT FOR FIRST DRQ
	BPL	:WAIT
	LDA	(BPNT),Y
	STA	DTAREG	;PUT DATA INTO DATA REG
	JSR	IBPNT	;INCREMENT POINTER
:WAIT1	BIT	DRA	;WAIT FOR SECOND DRQ
	BPL	:WAIT1
	LDA	(BPNT),Y
	STA	DTAREG
	LDA	WT64D	;CLEAR IP PULSE
	LDA	:TIME	;SET TIME FOR DISK ROTATION
	STA	WT24E	;ACCORDINT TO UPLOADED TIME
	JSR	IBPNT	;INCREMENT POINTER
:LOOP1	BIT	DRA	;WAIT FOR DRQ
	BVC	:CFTER	;TIMEOUT ERROR, RETRY
	BPL	:LOOP1
	LDA	(BPNT),Y
	STA	DTAREG
	JSR	IBPNT	;INCREMENT BPNT
	LDA	BPNT+1	;END OF BUFFER?
	CMP	CMDFRM+3
	BCC	:CFT02
	BNE	:CFT02
	LDA	BPNT
	CMP	CMDFRM+2
:CFT02	BNE	:LOOP1
	LDA	#$01	;MASK FOR BUSY
	LDX	#0	;DATA TO DISK
:CFT03	AND	STREG	;FDC BUSY?
	BEQ	:CFT04	;DONE
	BIT	DRA	;WAIT FOR DATA REQUEST
	BPL	:CFT03	;WAIT FOR DRQ
	STX	DTAREG
	BMI	:CFT03
:CFT04	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BEQ	:CFT05	;TRACK OK, WE HOPE
:CFTER	LDA	WT64D	;CLEAR IP
	JSR	FINT	;CLEAR FDC
	INC	:TRYS	;INCREMENT RETRYS
	LDA	#$06
	CMP	:TRYS	;SIX TIMES?
	BEQ	:CFT06
	JMP	:CFT01	;NOPE TRY AGAIN
;
:CFT06	LDA	#$01
	STA	:STATUS	;SET BAD STATUS
	BNE	:CFTXT	;GOODBY
:CFT05	LDA	#0
	STA	:STATUS	;GOOD STATUS
:CFTXT	JSR	FINT
	RTS
	EPROC
;
;
;**************************************
;
; IBPNT: INCREMENT BPNT
;
; ENTRY:NONE
;  EXIT:BPNT INCREMENTED BY ONE
;
;**************************************
;
IBPNT	PROC
;
	INC	BPNT
	BNE	:IBPTX	;INCREMENT IF NO OVER FLOW
	INC	BPNT+1
:IBPTX	RTS
	EPROC
;
;
;**************************************
;
; CSSK: CHECK SECTOR SKEWING
;
; PROGRAM LOOKS AT TRACK 0 AND ATTEMPTS
; TO DETERMINE WHAT THE SECTOR SKEW IS
; PUTS INFO INTO TABLE USED BY RDTK TO
; MAXIMIZE THE SPEED AT WHICH THIS
; HAPPENS.  IF NO SENSE CAN BE MADE OUT
; OF TRACK ZERO, THEN A DEFAULT SECTOR
; SKEW IS PUT IN TABLE
; ENTRY:NONE
;  EXIT:SKEW TABLE IS SET UP
;  USES:ALL REGISTERS
;      :MEMORY ON PAGE $20
;      :ZERO PAGE $A0$AF
;      :CALLS RADR
;
;**************************************
;
CSSK	PROC
;
:STATUS	=	$A0
:TRYS	=	$AF	;NUMBER OF RETRYS
;
;FIRST CHECK TO SEE WHAT FORMAT
;
	LDA	#$FF
	STA	TINB	;BUFFER EMPTY
	LDA	DCKFLG
	BEQ	:CSK31
	JMP	:CSK04
:CSK31	JSR	FINT
	LDA	#$00	;GO TO TRACK ZERO
	STA	NTRK
	JSR	SKTK
	JSR	RESTOR
	JSR	FINT
	LDA	#$20	;PUT INTO SINGLE DENSITY
	ORA	DRA	;SET BIT HIGH
	STA	DRA
	JSR	RADR
	BCS	:CSK01	;NOT SINGLE DENSITY
	LDA	#$80	;SET LENTH TO 128 BYTES
	STA	LENTH
	STA	CONFIG+7
	LDA	#$00
	STA	CONFIG+6
	LDA	#$FB
	AND	CONFIG+5	;PUT IS SD MODE
	STA	CONFIG+5
	LDA	#18
	STA	CONFIG+3	;SECTORS PER TRACK
	LDA	STAT
	AND	#%01011111
	STA	STAT
	JMP	:CSK02	;OK, NOW MAKE SKEW TABLE
;
;CHECK FOR DOUBLE DENSITY
;
:CSK01	LDA	#$DF	;PUT INTO DBL DENSITY
	AND	DRA	;CLEAR BIT LOW
	STA	DRA
	JSR	RADR	;CHECK DISK
	BCC	:CSK11
	JMP	:BDISK	;BAD DISK, SET DEFAULTS
;
;OK IT IS A DD DISK, BUT WHAT FLAVOR
;
:CSK11	JSR	RADR	;CHECK DISK AGAIN
	LDA	TADRES+2	;GET SECTOR NUMBER
	CMP	#4
	BCC	:CSK11	;LESS THAN 4
	LDA	TADRES+3
	BEQ	:CSK21	;THIS IS A DUAL DENS DISK
;
;DOUBLE DENSITY DISK
;
	LDA	#$00	;SET LENTH TO 256
	STA	LENTH
	STA	CONFIG+7
	LDA	#$01
	STA	CONFIG+6	;SET CONFIG LENTH
	LDA	#$04
	ORA	CONFIG+5	;SET STATUS FOR DD
	STA	CONFIG+5
	LDA	STAT
	AND	#%01011111	;MASK DENSITY
	ORA	#%00100000	;SET DOUBLE DENS
	STA	STAT
	LDA	#18
	STA	CONFIG+3
	JMP	:CSK02
;
:CSK21	LDA	#$80	;SET LENTH TO 128
	STA	LENTH
	STA	CONFIG+7
	LDA	#$00
	STA	CONFIG+6	;SET CONFIG LENTH
	LDA	#$04
	ORA	CONFIG+5	;SET STATUS FOR DD
	STA	CONFIG+5
	LDA	STAT
	AND	#%01011111	;MASK DENSITY
	ORA	#%10000000	;SET DUEL DENS
	STA	STAT
	LDA	#26
	STA	CONFIG+3
;
;BUILD SKEW TALBE
;
:CSK02	LDA	#$00
	JSR	FDCCK	;CHECK FDC TYPE
	LDA	#$06	;SET TRYS TO SIX
	STA	:TRYS
:LOOP1	LDX	#0	;INDEX INTO SKEW TALBE
:LOOP	JSR	RADR	;READ ADRESS OF SECTOR
	BCC	:CSK03	;GOOD READ
	DEC	:TRYS	;BAD READ DEC RETRYS
	BNE	:LOOP1	;RETRY WHOLE THING
	JSR	DFLTS	;MAKE DEFALT SKEW TABLE
	LDA	#$01
	STA	:STATUS
	SEC
	BCS	:CSKXT	;BUMP OUT
;
:CSK03	LDA	TADRES+2	;GET SECTOR NUMBER
	STA	SKTAB,X	;STORE IN SKEWTABLE
	INX
	CPX	CONFIG+3	;ALL SECTORS FETCHED?
	BNE	:LOOP	;NOPE NOT YET
;
	JSR	CST	;CHECK SKEW TABLE FOR BOO-BOO
	BCC	:CSK04	;GOOD TABLE
	DEC	:TRYS	;BAD READ DEC TRYS
	BNE	:LOOP1
	JSR	DFLTS	;MAKE DEFAULT SKEW TABLE
	LDA	#$01
	STA	:STATUS
	SEC
	BCS	:CSKXT	;BUMP OUT
;
:BDISK	JSR	DFLTS	;MAKE DEFALT SKEW TAB
	LDA	#$20
	ORA	DRA	;PUT INTO SINGLE DENSITY
	STA	DRA
	LDA	#$01
	STA	:STATUS
	SEC
	BCS	:CSKXT
;
:CSK04	LDA	#$00
	STA	:STATUS
	CLC
;
:CSKXT	RTS
	EPROC
;
;
;**************************************
;
; RESTOR: CHECKS TRACK ZERO
;       : ALSO UPDATES STATUS FLAGS
;
; ENTRY:NONE
;  EXIT:CARRY SET IF NOTHING FOUND
;
;**************************************
;
RESTOR	PROC
;
:STATUS	=	$A0
;
	LDA	#$D0	;SET TIME OUT
	STA	WT24E
	LDA	#%00001100	;RESTORE COMMAND
	STA	CMDREG
	JSR	DELAY
:LOOP	LDA	#$01
	BIT	STREG
	BMI	:RES01
	BEQ	:RES01
	BIT	DRA	;CHECK TIME OUT
	BVC	:RES11
	JMP	:LOOP
;
:RES11	LDA	RTDE	;CLEAR INTERRUPT
	LDA	STREG
	AND	#$01
	BEQ	:RES01	;NOT BUSY
	LDA	#$D0
	STA	WT24E
;
:RES01	LDA	STREG
	STA	TEMP
	EOR	#$FF
	STA	STAT+1
	EOR	#$FF
	AND	#$40	;CHECK WRITE PROTECT
	LSR	A
	LSR	A
	LSR	A
	STA	TEMP
	LDA	#$F7
	AND	STAT
	ORA	TEMP
	STA	STAT
	LDA	STREG
	AND	#$10	;CHECK FOR SEEK ERROR
	BEQ	:RES02
	SEC
	LDA	#$01
	STA	:STATUS
	JMP	:RESXIT
:RES02	LDA	#$00
	STA	:STATUS
	CLC
:RESXIT	RTS
	EPROC
;
;
;**************************************
;
; DFLTS:	MAKE DEFALT SECTOR TABLE
;
; ENTRY: CHECKS STAT FOR DENSITY
;  EXIT: SKTAB SET TO DEFUALT
;
;**************************************
;
DFLTS	PROC
;
:SCNT	=	$AE
;
;SAVE BPNT JUST IN CASE
;
	LDA	BPNT
	PHA
	LDA	BPNT+1
	PHA
;
	LDA	#$20	;CHECK STATUS
	BIT	STAT
	BMI	:DFTHD	;WE HAVE HALF DENSITY
	BNE	:DFTDD	;WE HAVE DOUBLE DENSITY
;
;WE HAVE SINGLE DENSITY
;
	LDA	#LOW :DTABS
	STA	BPNT
	LDA	#HIGH :DTABS
	STA	BPNT+1
	LDA	#18
	STA	:SCNT	;SET SECTOR COUNT TO 18
	JMP	:DFT01
;
:DFTHD	LDA	#LOW :DTABH
	STA	BPNT
	LDA	#HIGH :DTABH
	STA	BPNT+1
	LDA	#26
	STA	:SCNT
	JMP	:DFT01
;
:DFTDD	LDA	#LOW :DTABD
	STA	BPNT
	LDA	#HIGH :DTABD
	STA	BPNT+1
	LDA	#18
	STA	:SCNT
;
:DFT01	LDY	#$00	;SET INDEX
	LDX	#0
:LOOP	LDA	(BPNT),Y	;GET DEFAULT SECTOR
	STA	SKTAB,X	;STORE IN SKEW TABLE
	INY
	INX
	CPX	:SCNT	;ALL POSITIONS?
	BNE	:LOOP
	PLA
	STA	BPNT+1
	PLA
	STA	BPNT
	RTS
;
:DTABS	DB	17,15,13,11,9,7,5,3,1
	DB	18,16,14,12,10,8,6,4,2
:DTABD	DB	18,17,16,15,14,13,12,11,10
	DB	9,8,7,6,5,4,3,2,1
:DTABH	DB	1,3,5,7,9,11,13,15,17,19,21
	DB	23,25,2,4,6,8,10,12,14,16,18,20
	DB	22,24,26
;
	EPROC
;
;**************************************
;
; CST: CHECK SKEW TABLE FOR ERRORS
;
; MAKE SURE THAT EACH ELEMENT OF
; SKEW TABLE IS UNIQUE
;
; ENTRY:NONE
;  EXIT:CARRY SET IF ERROR
;
;**************************************
;
CST	PROC
;
:TEMP	=	$A1
;
; X-REG CONTAINS THE SEARCH INDEX
; Y-REG CONTAINS THE CURRENT INDEX
;
	LDA	CONFIG+3
	STA	:TEMP
	DEC	:TEMP
	LDX	#1
	LDY	#0	;INIT BOTH INDEXES
:LOOP1	LDA	SKTAB,Y	;GET CURRENT VALUE
:LOOP	CMP	SKTAB,X	;EQUAL TO ANY OTHER?
	BEQ	:YUK;YUK, DUPLICATE
	INX	;INCREMENT Y REG
	CPX	CONFIG+3	;WHOLE TABLE?
	BNE	:LOOP
	INY	;INC CURRENT INDEX
	TYA	;MOVE Y TO X
	TAX
	INX	;POINT TO NEXT VALUE IN TABLE
	CPY	:TEMP	;ALL VALUES CHECKED?
	BNE	:LOOP1
	CLC	;SET GOOD JOB
	BCC	:CSTXT
;
:YUK	SEC
:CSTXT	RTS
;
	EPROC
;
;*************************************
;
; DDTRK : CREATE DOUBLE DENSITY TRACK
;        IMAGE FOR FORMATTING
;
; ENTRY : SECT IS SECTOR #
;         TRCK IS TRCK #
;  EXIT : MODEL TRACK AT $2000
;
;*************************************
;
DDTRK	PROC
;
:TRACK	=	$A0
;
	STA	:TRACK	;SAVE TRACK NUMBER
	LDA	#$00	;SET UP BPNT
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
;
;START BUILDING THE TRACK
;
	LDA	#$4E	;DATA
	LDX	#80	;80 BYTES
	JSR	BB
	LDA	#0
	LDX	#12
	JSR	BB	;12 ZEROS
	LDA	#$F6	;WRITES C2
	LDX	#3	;THREE TIMES
	JSR	BB
	LDA	#$FC
	LDX	#1	;ONE INDEX AM
	JSR	BB
	LDA	#$4E	;DATA
	LDX	#50
	JSR	BB
;
;TRACK PREAMBLE DONE, NOW FOR THE
;SECTORS
;
	LDA	#$00
	STA	SECT	;INIT SECTOR INDEX
:LOOP	LDA	#0
	LDX	#12	;12 ZEROS
	JSR	BB
	LDA	#$F5	;WRITES A1
	LDX	#3	;THREE TIMES
	JSR	BB
	LDA	#$FE	;ID AM
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	:TRACK
	STA	(BPNT),Y
	JSR	STKP	;STORE TRACK POINTER
	JSR	IBPNT
	LDA	#0
	STA	(BPNT),Y	;SIDE NUMBER
	JSR	IBPNT
	LDX	SECT
	LDA	SKTAB,X	;GET SECTOR NUMBER
	STA	(BPNT),Y
	JSR	IBPNT
	LDX	SECT
	LDA	SKTAB,X	;GET SECTOR
	LDX	:TRACK
	JSR	SL	;DO SECTOR LENTH CALC
	PHA	;SAVE ACCUMULATOR
	LDA	#$F7	;CAUSES 2 CRC BYTES
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$4E
	LDX	#22	;GAP ID
	JSR	BB
	LDA	#$00
	LDX	#12
	JSR	BB
	LDA	#$F5
	LDX	#3
	JSR	BB	;WRITE 3 $A1
	LDA	#$FB
	STA	(BPNT),Y
	JSR	IBPNT
;
;WRITE SECTOR BLOCK
;
	PLA	;GET SECTOR LENTH
	TAX
	LDA	#$40	;DATA FOR SECTOR
	JSR	BB
	LDA	#$F7	;WRITE 2 CRC BYTES
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$4E
	LDX	#16
	JSR	BB
	INC	SECT	;INCREMENT SECTOR INDEX
	LDA	SECT
	CMP	#18	;EIGHTEEN SECTORS?
	BEQ	:EXIT
	JMP	:LOOP
:EXIT	LDA	#$B7	;END OF DD TRACK MARK
	STA	(BPNT),Y
	RTS
	EPROC
;
;*************************************
;
;DUTRK : CREATE DUAL DENSITY TRACK
;        IMAGE FOR FORMATTING
;
; ENTRY : SECT IS SECTOR #
;        TRCK IS TRCK #
;  EXIT : MODEL TRACK AT $2000
;
;*************************************

DUTRK	PROC
;
:TRACK	=	$A0
;
	STA	:TRACK	;SAVE TRACK NUMBER
	LDA	#$00	;SET UP BPNT
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
;
;START BUILDING THE TRACK
;
	LDA	#$4E	;DATA
	LDX	#80	;80 BYTES
	JSR	BB
	LDA	#0
	LDX	#12
	JSR	BB	;12 ZEROS
	LDA	#$F6	;WRITES C2
	LDX	#3	;THREE TIMES
	JSR	BB
	LDA	#$FC
	LDX	#1	;ONE INDEX AM
	JSR	BB
	LDA	#$4E	;DATA
	LDX	#50
	JSR	BB
;
;TRACK PREAMBLE DONE, NOW FOR THE
;SECTORS
;
	LDA	#$00
	STA	SECT	;INIT SECTOR INDEX
:LOOP	LDA	#0
	LDX	#12	;12 ZEROS
	JSR	BB
	LDA	#$F5	;WRITES A1
	LDX	#3	;THREE TIMES
	JSR	BB
	LDA	#$FE	;ID AM
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	:TRACK
	STA	(BPNT),Y
	JSR	STKP	;STORE TRACK POINTER
	JSR	IBPNT
	LDA	#0
	STA	(BPNT),Y	;SIDE NUMBER
	JSR	IBPNT
	LDX	SECT
	LDA	SKTAB,X	;GET SECTOR NUMBER
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$00
	STA	(BPNT),Y	;SECTOR LENTH=128
	JSR	IBPNT
	LDA	#$F7	;CAUSES 2 CRC BYTES
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$4E
	LDX	#22	;GAP ID
	JSR	BB
	LDA	#$00
	LDX	#12
	JSR	BB
	LDA	#$F5
	LDX	#3
	JSR	BB	;WRITE 3 $A1
	LDA	#$FB
	STA	(BPNT),Y
	JSR	IBPNT
;
;WRITE SECTOR BLOCK
;
	LDX	#128	;128 BYTE SECTOR
	LDA	#$40	;DATA FOR SECTOR
	JSR	BB
	LDA	#$F7	;WRITE 2 CRC BYTES
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$4E
	LDX	#16
	JSR	BB
	INC	SECT	;INCREMENT SECTOR INDEX
	LDA	SECT
	CMP	#26	;TWENTY SIX SECTORS?
	BEQ	:EXIT
	JMP	:LOOP
:EXIT	LDA	#$B7	;END OF DD TRACK MARK
	STA	(BPNT),Y
	RTS
	EPROC
;
;*************************************
;
; SL: CALCUTLATE SECTOR LENTH
;
; ENTRY:A = SECTOR
;      :X = TRACK
;  EXIT:ACC = LENTH (0=256)
;      :SECTOR LENTH PUT IN TABLE
;      :BPNT IS INCREMENTED
;
;*************************************
;
SL	PROC
;
	CPX	#0	;TRACK 0?
	BEQ	:SL001	;YES CHECK FOR SECTOR 1->3
:SL002	LDA	#01
	LDY	#$00
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$00	;SECTOR LENTH 256
	BEQ	:SLXIT	;LEAVE
;
:SL001	CMP	#4	;SECTOR >= 4?
	BCS	:SL002	;YES
;
;OK, THIS ONE IS 128 BYTES LONG
;
	LDA	#0
	TAY
	STA	(BPNT),Y
	JSR	IBPNT
	LDA	#$80	;128 TO SEND BACK
:SLXIT	RTS
	EPROC
;
;
;*************************************
;
; BB: BUILD A BLOCK, WELL ALMOST
;
; ENTRY:A= DATA TO FILL WITH
;      :X= LENTH OF BLOCK (0-> 256 BYTE
;  EXIT:NONE
;
;**************************************
;
BB	PROC
;
:LEN	=	$A1	;LENTH OF SECTOR
;
	STX	:LEN
	LDY	#$00	;INIT INDEX REGISTERS
	LDX	#$00
:LOOP	STA	(BPNT),Y
	JSR	IBPNT	;INCREMENT POINTER
	INX
	CPX	:LEN	;END OF BLOCK
	BNE	:LOOP
	RTS
	EPROC
;
;
;*************************************
;
; ANAL: ANALYZE A TRACK ON THE DISK
;
; ENTRY:AUX1 CONTAINS TRACK NUMBER
;  EXIT:BUFFER OF 256 BYTES AT $2000
;      :CONTAINS TRACK INFO
;      :IN FOLLOWING FORMAT:
;      TRACK NUMBER
;      SIDE NUMBER
;      SECTOR NUMBER
;      SECTOR LENTH
;      CRC1
;      CRC2
;      FDC STATUS REGISTER
;
; STATUS:00=NO ERROR
;       :01=BAD TRACK NUMBER
;       :02=TRACK BLANK
;       :03=CAN'T COPE
;
;**************************************
;
ANL	PROC
;
:STATUS	=	$A0
:TRYS	=	$AE	;RETRY COUNT
:TEMP	=	$AF	;TEMP SAVE AREA
:NSC1	=	$280C	;NUM OF SECS FIRST PASS
:NSC2	=	$280D	;NUM OF SECS SECND PASS
;
RDTME	=	$28C	;READ TIMER ENABLE IQR
;
	LDA	#$20
	STA	BPNT+1
	LDA	#0
	STA	BPNT
	LDA	#2	;CLEAR 2 PAGES
	JSR	ZAB	;ZERO ANL BUFFER
	LDA	#$FF
	STA	TINB	;INDICATE THAT TRACK BUFFER
			;GOT YUCKED UP
	LDA	DRA	;GET OLD DATA REGISTER AND SAV
	STA	:TEMP
	ORA	#$20	;PUT IN SINGLE DENSITY IF NOT
	STA	DRA
	JSR	FINT	;FRESH START
	LDA	CMDFRM+2	;GET TRACK NUMBER
	STA	NTRK
	JSR	SKTK
	BCC	:AN001	;NO ERROR CONTINUE
	LDA	#$01
	STA	:STATUS
	JMP	:ANXIT	;GOODBY
;
:AN001	LDA	#$02
	STA	:TRYS	;SET NUMBER OF RETRYS
:AN002	JSR	RADR	;SEE IF ANYTHING ALIVE
	BCC	:AN003	;OK WE HAVE SOMETHING HERE
	DEC	:TRYS	;DEC RETRYS
	BNE	:AN002	;KEEP GOING UNTIL GIVE UP
	LDA	#$02	;BLANK TRACK OR SOMETHING
	STA	:STATUS
	JMP	:ANXIT
;
;NOW WE DO TRACK ANALYSIS
;TRY TO READ IN 26 SECTORS WORTH OF
;DATA, THEN REDUCE DATA TO FIND IDENT
;ENTRYS
;
;FORMAT OF DATA
;
; BYTE0:=TRACK ADDRESS
; BYTE1:=SIDE NUMBER
; BYTE2:=SECTOR ADDRESS
; BYTE3:=SECTOR LENTH
; BYTE4:=CRC1
; BYTE5:=CRC2
; BYTE6:=STATUS REGISTER
; BYTE7:=SECTOR TIME (K micro seconds)
;
:AN003	LDA	#$06
	STA	:TRYS	;TRY SIX TIMES TO FIGURE
			;OUT FORMAT OF TRACK
:AN009	LDA	#$00
	STA	BPNT	;SET UP BUFFER POINTER
	LDA	#$20
	STA	BPNT+1
	LDA	#2	;CLEAR 2 PAGES
	JSR	ZAB
:AN007	LDX	#$00
	LDY	#$00
	LDA	#$CE	;TIME FOR ONE TRACK AND A
			;LITTLE BIT LESS
	STA	WT24E	;START TIMER
;
;RECORD AS MANY SECTORS AS YOU CAN
;
:AN004	JSR	SRDA	;DO SPECIAL READ ADRESS
	BCC	:AN005	;OK NEXT SECTOR
	JMP	:AN006	;GOODBY
;
:AN005	LDA	:STATUS
	STA	(BPNT),Y
	INY
	LDA	RDTME
	STA	(BPNT),Y
	INY
	JMP	:AN004	;NO
;
:AN006	LDA	:STATUS+1	;CHECK NUMBER
	BEQ	:AN012	;(ZERO BYTES OK TOO!)
	CMP	#6	;OF BYTES READ
	BEQ	:AN012
;
	JSR	CLEAN	;CLEAN UP LAST ENTRY
:AN012	JSR	FINT	;TEMINATE OLD COMMAND
	INC	BPNT+1
	LDA	BPNT+1
	CMP	#$22	;BOTH BUFFERS FILLED?
	BNE	:AN007;
;
	LDA	NTRK	;GET TRACK NUMBER
	LDX	#$00
	LDY	#$20	;ADDRESS OF FIRST BUFFER
	JSR	CKBF	;CHECK BUFFER
	LDA	:STATUS
	STA	:NSC1	;NUMBER OF SECTORS FOUND
;
	LDA	NTRK
	LDX	#00
	LDY	#$21	;ADDRESS OF SECOND BUFFER
	JSR	CKBF	;CHECK THIS BUFFER TOO
	LDA	:STATUS
	STA	:NSC2
	CMP	:NSC1	;ARE THEY EQUAL?
	BEQ	:AN008
:AN011	DEC	:TRYS
	BNE	:AN009	;TRY SOME MORE
	LDA	#03
	STA	:STATUS
	JMP	:ANXIT
;
;OK NOW COMPARE THE TWO BUFFERS
;
:AN008	LDA	:NSC1	;NUMBER OF SECTORS
	STA	$A4	;PARAM2
	LDA	#$21
	STA	$A3	;PARAM1
	LDA	#$00
	LDX	#$20
	LDY	#$00
	JSR	CMP
	LDA	:STATUS
	BEQ	:AN010
	BNE	:AN011
:AN010	LDA	:NSC1
	STA	:STATUS+1
	LDA	#$00
	STA	:STATUS
:ANXIT	RTS
;
	EPROC
;
;
;**************************************
;
; SRDA: SPECIAL READ ADDRESS
;
; READ DISK ADDRESS
; RETURNS ADDRESS IN SIX BYTE BLOCK
; POINTED TO BY BPNT ON PAGE ZERO
; AND Y INDEX REGISTER
; STATUS REGISTER IN $A0
; NUMBER OF BYTES READ IN $A1
;
;**************************************
;
SRDA	PROC
;
:STATUS	=	$A0
;
	PHA	;SAVE ACC
	TXA
	PHA
			;THIS ROUTINE DOES NOT INIT THE
			;TIMER, BUT DOES CHECK FOR TIMEOUT
;
:SRD10	LDX	#$00	;INDEX OF BLOCK
	LDA	#$C0	;LOAD READ ADRESS COMMAND
	STA	CMDREG	;
:SRD01	BIT	DRA	;WATCH DATA READY FLAG
	BVC	:SRD04
	BPL	:SRD01
	LDA	DTAREG	;READ DATA REGISTER
	STA	(BPNT),Y	;STORE DATA
	INY
	INX
	CPX	#$06	;SIX BYTES YET?
	BNE	:SRD01
	LDA	#$01
:SRD03	BIT	STREG
	BNE	:SRD03
	LDA	STREG
	STA	:STATUS
	EOR	#$FF
	STA	STAT+1
	CLC
	JMP	:SRDXT
:SRD04	SEC
	LDA	RTDE	;CLEAR TIMER
;
:SRDXT	STX	:STATUS+1
	PLA
	TAX
	PLA
	RTS
;
;
;**************************************
;
; SPECIAL WRITE SECTOR
; WRITES DELEATED DATA MARK
; ENTRY:ACC=SECTOR TO WRITE
;      :BUFFER POINTER POINTS TO DATA
;  EXIT:CARRY SET IF ANY ERRORS
;
;**************************************
;
SWS	PROC
;
:STATUS	=	$A0
;
	STA	SECREG
	LDA	TRACK
	STA	TRKREG	;SET UP SECTOR TO WRITE TO
:SWS01	LDY	#$00
	LDX	#$00
	LDA	#$E6
	JSR	STMO
	LDA	WSDMCM	;WRITE SECTOR COMMAND
			;DELEATED DATA MARK
	STA	CMDREG
:SWS02	LDA	(BPNT),Y
	EOR	#$FF	;LOAD AND COMPLEMENT DATA
:SWS03	BIT	DRA	;CHECK FOR WHEN FDC REDY
	BVC	:SWS10	;TIME OUT ERROR
	BPL	:SWS03	;LOOP UNTIL READY
	STA	DTAREG	;SEND DATA TO FDC
	LDA	WT64D
	INY
	CPY	LENTH	;COMPARE WITH SECTOR LENTH
	BNE	:SWS02
	LDA	#$01
:SWS04	BIT	STREG
	BNE	:SWS04	;LOOP UNTIL DONE
	LDA	STREG
	LDA	#0
	STA	:STATUS	;SET STATUS OK!
	CLC
	RTS
:SWS10	LDA	STREG
	AND	#$01	;CHECK FOR BUSY
	BEQ	:SWS20
	LDA	#$E6
	JSR	STMO
	BNE	:SWS02
:SWS20	LDA	WT64D
	LDA	STREG
	AND	#$04	;CHECK FOR LOST DATA
	BNE	:SWS01
	LDA	STREG
	LDA	#$01
	STA	:STATUS	;SET STATUS YUCKY!
	SEC
	RTS
	EPROC
;
;
;**************************************
;
; ZAB: ZERO BUFFER FOR ANL
;
; ENTRY:NUMBER OF PAGES CLEARED
;      :BPNT POINTS TO START OF BUFF
;  EXIT:PAGE(S) ZEROED
;
;**************************************
;
ZAB	PROC
;
:COUNT	=	$A0
;
	STA	:COUNT
	LDA	BPNT	;SAVE ORIGIANL BUFFER POINTER
	PHA
	LDA	BPNT+1
	PHA
	LDX	#0
	LDY	#$00
	TYA
:LOOP	STA	(BPNT),Y
	INY
	BNE	:LOOP
	INC	BPNT+1
	INX
	CPX	:COUNT
	BNE	:LOOP
	PLA	;RECOVER BUFFER POINTER
	STA	BPNT+1
	PLA
	STA	BPNT
	RTS
	EPROC
;
;**************************************
;
; CLEAN: CLEAN UP LAST ENTRY ON SEC MAP
;
; ENTRY:ACC=NUMBER OF BYTES LAST READ
;      :BPNT=POINTER TO DATA
;      :Y=INDEX TO DATA
;
;**************************************
;
CLEAN	PROC
;
:INDX	=	$2818
:N	=	$2819
:FINDX	=	$281A
;
	STA	:N
	STY	:INDX
	LDA	:INDX
	LSR	A
	LSR	A
	LSR	A
	ASL	A
	ASL	A
	ASL	A
	STA	:FINDX
	LDY	:FINDX
	LDA	#0
	TAX
:LOOP	STA	(BPNT),Y
	INY
	INX
	CPX	:N
	BNE	:LOOP
	RTS
;
	EPROC
;
	LINK	D2:DD15M6.ASM
