;
;**************************************
;
; RCMDFRM:
;       RECIEVE COMMAND FRAME
;
;  ENTRY:NONE
;  EXIT: NONE
;
;  REGISTERS USED:A,X
;
;  MEMORY USED:COMMAND FRAME BUFFER
;
;**************************************
;
RCMDFRM	PROC
:STATUS	=	$A0	;GET STATUS
;
	LDA	#$32	;50 MS TIMEOUT
	JSR	STMO
;
;FILL COMMAND FRAME BUFFER
;
	LDA	#LOW CMDFRM
	STA	BPNT
	LDA	#HIGH CMDFRM
	STA	BPNT+1
	LDA	#$04	;GET 4 BYTES FROM ATARI
	JSR	READ	;GET DATA
;
;WAIT FOR CMD LINE TO GO HIGH
;
RCF002	BIT	DRB	;MONITOR CMD LINE
	BMI	RCF002	;STILL LOW KEEP WAITING
;
;CMD LINE HIGH, CHECK CHECK SUM
;
	LDA	:STATUS	;CHECK STATUS
	BNE	RCFERR	;BRANCH ON ERROR
;
	LDA	STAT	;SET CHECKSUM OK
	AND	#$FD
	STA	STAT
	LDA	#0
	STA	CMDRT	;REZERO RETRYS
	LDA	DRA	;READ PORT A
	AND	#$01
	STA	TEMP
	LDA	DRA
	LSR	A
	AND	#$01
	EOR	TEMP
	STA	TEMP
	LDA	DRA
	AND	#$01
	EOR	#$01
	ASL	A
	ORA	TEMP
	CLC
	ADC	#$31	;ASCII FOR DRIVE NUMBER
	CMP	CMDFRM	;THIS DEVICE REQUESTED?
	BNE	RCFERR	;NO GO BACK AND WAIT

; OK WE GOT A COMMAND, LETS GO AND
; DECODE IT

	JSR	CMDSEL	;DECODE COMMAND

; WE RETURN HERE AFTER PROCESSING
; THE COMMAND
	RTS
;
;HANDLE COMMAND FRAME ERROR
;
RCFERR	CMP	#$02	;WAS IT A CHECKSUM?
	BEQ	:RF002
	LDA	SSTAT
	BEQ	RCFEXT	;NO, EXIT
	JSR	BTOG
	JMP	RCFEXT
;
:RF002	LDA	CMDRT	;HAVE WE BEEN TRYING?
	BNE	:RF001	;YES TRY SOME MORE
	JSR	BTOG	;TOGGLE BAUD RATE AND TRY
	LDA	#3
	STA	CMDRT	;SOME MORE
	BNE	RCFEXT
:RF001	DEC	CMDRT	;DECREMENT RETRY
RCFEXT	LDA	#$01
	STA	:STATUS
	RTS	;RETURN TO IDLE CONDITION
	EPROC
;
;**************************************

; CMDSEL:
;        THIS IS WHERE WE DECODE THE
;        COMMAND THAT WE HAVE JUST GOT

;  ENTRY:VALID COMMAND FRAME IN
;        COMMAND FRAM BUFFER
;  EXIT:COMMAND PROCESSED

; MEMORY USED:COMMAND FRAME BUFFER

; REGISTERS USED:A,X
;
; COMMAND SUMMARY
;
; P :WRITE TO DISK NO VERIFY
; W :WRITE TO DISK WITH VERIFY
; R :READ DISK
; S :GET STATUS
; ! :FORMAT DISK
; " :FORMAT DUAL DENSITY
; N :READ DRIVE CONFIG
; O :WRITE DRIVE CONFIG
; ? :RETURN SPEED INDEX
; u :upload data to drive
; r :run program in drive
; s :set load address in drive
; g :seek new track
; c :custom format
; f :sparta dos custom format
; b :track buffer toggle
; a :analyze a track
; w :write a sector with deleted data
; m :upload sector pattern and 
;   :and read a track of data
; t :get sector data from m command
; v :upload a sector to write
; n :upload sector pattern and write
;   :data from v to track
; j :change drive rpm
; h :set drive on hold time
; d :disable density sense
;
;**************************************

RD	=	$50	;RECEIVE DATA FROM ATARI
RDV	=	$57	;RECEIVE AND VERIFY DATA
WRT	=	$52	;SEND DATA TO ATARI
STATUS	=	$53	;SEND STATUS TO ATARI
RCONFIG	=	$4E	;READ DRIVE CONFIG
WCONFIG	=	$4F	;WRITE DRIVE CONFIG
FORMAT	=	$21	;FORMAT DISK
UPLOAD	=	'u'	;$75 UPLOAD PROGRAM DATA
RUN	=	'r'	;$72 RUN PROGRAM
SETADR	=	's'	;$73 SET ADDRESS LOAD
GTRACK	=	'g'	;$67 seek new track
CFRMAT	=	'c'	;$63 custom format a track
HTME	=	'h'	;set hang on time (TL)
BAUD	=	'?'	;SET TO WARP SPEED
TBUFF	=	'b'	;track buffer toggle
ANAL	=	'a'	;ANALYZE A TRACK
WDDM	=	'w'	;WRITE WITH DELETED DTA MARK
;
CMDSEL	PROC
;
:STATUS	=	$A0	;STATUS FROM GET
;
	LDA	CMDFRM+1	;LOAD COMMAND
	CMP	#RD	;DO WE GET DATA FROM ATARI
	BEQ	CSEL00	;YES
	CMP	#RDV	;READ WITH VERIFY?
	BNE	CSEL01	;NO READ, TRY NEXT COMMAND

;RECIEVE DATA FROM COMPUTER

CSEL00	JSR	NTS	;CALCULATE NEW SECTOR
	LDA	NSEC	;LOAD SECTOR NUMBER
	JSR	CTS	;CHECK LENTH OF SECTOR
	JSR	SBPNT	;SET BUFFER POINTER
	JSR	ACK	;SEND ACKNOLEDGE
	LDA	LENTH	;LENTH OF BUFFER TO RECIEVE
	JSR	READ	;READ DATA FROM ATARI
	LDA	:STATUS	;GET STATUS
	CMP	#$02
	BNE	:CS001
	JMP	CMDNAK	;COMMAND ERROR
:CS001	CMP	#$01
	BNE	:CS002	;TIMEOUT ERROR?
	JMP	CMDXIT
:CS002	JSR	ACK
	JSR	MCK	;DO MOTOR CHECK
	LDA	SRATE	;SAVE STEP RATE
	PHA
	LDA	#108
	STA	SRATE
	JSR	SKTK	;SEEK TRACK
	PLA
	STA	SRATE
	LDA	DTAREG	;DO A DUMB READ
	LDA	NSEC
	JSR	WSEC

	BIT	STREG	;WRITE PROTECT?
	BVC	C0B	;NO PROTECT
	JSR	ERR	;PROTECTED, SEND ERROR
	JMP	C0A	;DON'T VERIFY

C0B	LDA	CMDFRM+1	;LOAD COMMAND
	CMP	#$57	;READ WITH VERIFY?
	BNE	C0A	;NO VERIFY
	LDA	NSEC
	JSR	VSEC	;VERIFY READ
;
C0A	LDA	#$FF
	STA	TINB	;NO DATA IN TRACK BUFFER
;
CM0002	JSR	CMPLT	;SEND COMPLETE
	LDA	#$00
	STA	:STATUS
	JMP	CMDXIT	;EXIT FROM COMMAND PROCESS
;
;CHECK FOR SEND DATA
;
CSEL01	CMP	#WRT	;SEND DATA TO ATARI?
	BNE	CSEL02	;NO, TRY NEXT COMMAND
;
; SEND DATA FRAME BACK TO ATARI
;
	JSR	ACK
;
;IF THE PERIPHERAL HAS TO DO SOMETHING
;TO GET THE DATA, IT WOULD DO IT HERE
;
;
;SEE IF IN FORCE SLOW MODE
;
	LDA	TFLAG
	BEQ	:CS022
;
	JSR	MCK
;
	JSR	NTS	;CALCULATE NEW TRACK/SECTOR
	JSR	SKTK	;FIND THE TRACK TO READ FIRST
	BCS	BOUNCE	;COMMAND NOT ACKNOLEDGED
;
	LDA	DTAREG
	LDA	NSEC
	JSR	CTS	;CHECK OUT LENTH
	JSR	SBPNT	;SET BUFFER
	JSR	RSEC	;READ SECTOR
	LDA	:STATUS
	BEQ	:CS023
	JSR	CMDERR	;SEND ERROR
	JMP	:CS024	;SEND ERROR
:CS023	JSR	CMPLT
:CS024	LDA	LENTH
	JSR	SEND
	LDA	#$00
	STA	:STATUS	;RE INIT MOTOR
	JMP	CMDXIT
;
:CS022	JSR	RDTK	;READ TRACK
	BCS	BOUNCE	;COMMAND NOT ACKNOLEDGED
	LDA	:STATUS
	PHA	;SAVE FOR LATER
	LDX	NSEC	;SET INDEX TO SEC TABLE
	DEX
	LDA	TRKCH,X
	STA	STAT+1	;SAVE IN HW STATUS
	EOR	#$FF	;COMPLEMENT STATUS
	AND	#%00111000	;CHECK FOR FDC ERROR
	BEQ	OKSEC	;NO ERROR
	JSR	ERR	;SEND ERROR
	JSR	RDSC
	PLA	;POP STATUS
	STA	:STATUS
	JMP	CMDXIT
OKSEC	JSR	CMPLT
	JSR	RDSC
	PLA	;POP STATUS
	STA	:STATUS
	JMP	CMDXIT	;EXIT FROM COMMAND PROCESS
BOUNCE	JMP	CMDNAK	;SEND NAK TO ATARI
;
; IS IT A REQUEST FOR STATUS
;
CSEL02	CMP	#STATUS	;IS IT STATUS
	BNE	CSEL03	;NO, TRY NEXT COMMAND

;SEND STATUS

	LDA	#$E0	;SET TIMEOUT
	STA	STAT+2
	LDA	#$24	;WHO KNOWS WHY?
	STA	STAT+3
	JSR	ACK
	JSR	DELAY	;WAIT BEFORE SENDING COMPLT
	JSR	CMPLT	;SEND COMPLETE
	JSR	SDSTAT	;SEND STATUS
	LDA	#$01
	STA	:STATUS	;DO NOT REINIT TIMER
	JMP	CMDXIT	;EXIT FROM COMMAND PROCESS


;READ CONFIGURATION FROM DRIVE

CSEL03	CMP	#RCONFIG	;READ CONFIG?
	BNE	CSEL04	;NO, TRY NEXT COMMAND
;
	JSR	DELAY
	JSR	ACK	;ACKNOWLEDGE CMD
	JSR	DELAY	;WAIT TO SEND CMPLT
	JSR	CMPLT	;SEND OPERATION COMPLETE
	LDA	LENTH
	PHA		;SAVE LENGTH ON STACK
	LDA	#12	;12 BYTES TO SEND
	STA	LENTH
	LDA	#LOW CONFIG
	STA	BPNT	;POINTER TO DATA TO SEND
	LDA	#HIGH CONFIG
	STA	BPNT+1
	LDA	LENTH
	JSR	SEND	;SEND CONFIG TO ATARI
	PLA
	STA	LENTH	;RESTORE LENTH
	LDA	#1
	STA	:STATUS	;DO NOT REINT TIMER
	JMP	CMDXIT


;WRITE CONFIGURATION TO DRIVE

CSEL04	CMP	#WCONFIG	;WRITE CONFIG?
	BNE	CSEL05	;NO, TRY NEXT COMMAND

	JSR	ACK	;ACKNOWLEDGE CMD
	LDA	#$FF
	JSR	STMO	;SET TIME OUT
	LDA	#$0C	;SET TO READ 12 BYTES
	LDX	#LOW CONFIG	;SET POINTER BPNT
	STX	BPNT
	LDX	#HIGH CONFIG	;STORE DATA
	STX	BPNT+1
;
	JSR	READ	;READ DATA FROM SERIAL BUS
	LDA	:STATUS
	CMP	#$02
	BNE	C4A10
	JMP	CMDERR
C4A10	CMP	#$01
	BNE	C4A11
	JMP	CMDNAK
C4A11	JSR	DELAY
	JSR	ACK
;
	LDA	CONFIG+5	;CHECK DENSITY CONTROL
	AND	#$04
	BEQ	C4A12
	LDA	CONFIG+3
	CMP	#18	;CHECK FOR DUAL DENS
	BEQ	C4A14
	LDA	STAT
	AND	#%01011111
	ORA	#%10000000
	STA	STAT
	JMP	C4A13
;
C4A14	LDA	STAT	;DOBLE DENSITY
	AND	#%01011111
	ORA	#%00100000
	STA	STAT
	JMP	C4A13
;
C4A12	LDA	STAT	;SINGLE DENSITY
	AND	#%01011111
	STA	STAT
C4A13	JSR	DELAY
	JSR	CMPLT	;SEND OPERATION COMPLETE
	LDA	#$01
	STA	:STATUS	;DO NOT REINIT TIMER
;
	JMP	CMDXIT
;
CSEL05	CMP	#FORMAT	;FORMAT?
	BEQ	CSEL5
	JMP	CSEL06	;NO NEXT COMMAND!!
;
CSEL5	JSR	ACK
	JSR	MCK	;DO MOTOR THING
	LDA	SRATE	;SAVE STEP RATE
	PHA
	LDA	#200	;REAL SLOW MAN!
	STA	SRATE
	LDA	#0
	STA	NTRK	;GOTO TRACK 0
	JSR	SKTK
;
;CHECK THE TYPE OF FORMAT
;
	LDA	#$04
	AND	CONFIG+5
	BEQ	:CS501	;SINGLE DENSITY
	LDA	CONFIG+3
	CMP	#26
	BEQ	:CS501
;
;DOUBLE DENS
;
	LDA	STAT	;SET STATUS TO DD
	AND	#%01011111
	ORA	#%00100000
	STA	STAT
	JSR	DFLTS	;SET DEFAULT SKEW
	JSR	DDFMT
	PLA
	STA	SRATE	;RESTORE STEP RATE
;
;CHECK FDC
;
	LDA	#39	;ON TRACK 39
	JSR	FDCCK
	LDA	:STATUS
	BNE	:CS506
;
	LDA	#$BF
	JSR	VDSK
	LDA	:STATUS
	BEQ	:CS502
:CS506	JSR	ERR
	JMP	:CS503
;
:CS502	JSR	CMPLT
:CS503	LDA	#$20
	STA	BPNT+1
	LDA	#$00
	STA	BPNT
	JSR	SEND
	LDA	#$00
	STA	:STATUS
	JMP	CMDXIT
;
:CS501	LDA	STAT
	AND	#%01011111
	STA	STAT
	LDA	#18
	STA	CONFIG+3
	LDA	#0
	STA	CONFIG+5
	STA	CONFIG+6
	LDA	#128
	STA	CONFIG+7
	JSR	DFLTS
	JSR	SFRMAT
	PLA
	STA	SRATE	;RESTORE STEP RATE
;
	LDA	#39
	JSR	FDCCK	;CHECK FDC WITH TRACK 39
	LDA	:STATUS
	BNE	:CS507
	LDA	#0
	JSR	VDSK
	LDA	:STATUS
	BEQ	:CS504
:CS507	JSR	ERR
	JMP	:CS505
;
:CS504	JSR	CMPLT
:CS505	LDA	#0
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	LDA	#$80
	JSR	SEND
;
	LDA	#0
	STA	:STATUS	;REINIT TIMER
	JMP	CMDXIT
;
;**************************************
;
;THESE ARE SPECIAL COMMANDS FOR USERS
;TO LOAD THEIR OWN PROGRAMS UP TO THE
;DUPLICATOR BOARD. THIS ALSO PUTS LESS
;BURDEN ON US AS HACKERS WILL LOVE TO
;MESS WITH THE DRIVE
;
;**************************************
;
CSEL06	CMP	#SETADR	;SET START ADRESS?
	BNE	CSEL07	;NO, NEXT COMMAND
;
;THE START ADDRESS IS CONTAINED IN
;AUX1 AND AUX2 OF THE COMMAND FRAME
;
	JSR	DELAY	;WAIT JUST A BIT
	JSR	ACK
	LDA	CMDFRM+2	;LOAD AUX1
	STA	STRADR
	LDA	CMDFRM+3	;LOAD AUX2
	STA	STRADR+1
	JSR	DELAY
	JSR	CMPLT
	LDA	#1
	STA	:STATUS
	JMP	CMDXIT	;OPERATION COMPLETE
;
CSEL07	CMP	#UPLOAD	;UPLOAD COMMAND
	BNE	CSEL08	;NOPE, TRY NEXT ONE
;
;THIS COMMAND WILL START LOADING DATA
;IN 256 BYTE CHUNKS STARTING AT THE
;ADDRESS SET IN THE SET START ADDRESS
;COMMAND.  AFTER DATA HAS BEEN LOADED
;THE START ADDRESS WILL BE INCREMENTED
;BY ONE PAGE.  IF IT IS POINTING TO
;AN AREA OF MEMORY THAT DOES NOT EXIST
;ON TE DUPLICATOR, THEN AN ERROR IS
;RETURNED
;
	JSR	DELAY
	JSR	ACK
	JSR	ULD	;UPLOAD THE DATA FROM ATARI
	;
	;ULD RETURNS STATUS IN $A0
	;
	JSR	DELAY
	JSR	ACK
	JSR	DELAY
	LDA	:STATUS	;CHECK STATUS FROM ULD
	CMP	#2	;MEMORY BOUND ERROR?
	BNE	CSEL72
	JMP	CMDERR	;YES,SEND BACK ERROR
CSEL72	CMP	#1	;CHECKSUM ERROR?
	BNE	CSEL71
	JMP	CMDNAK	;SEND NACK
CSEL71	JSR	CMPLT
	LDA	#1
	STA	:STATUS
	JMP	CMDXIT
;
CSEL08	CMP	#RUN	;RUN PROGRAM COMMAND?
	BNE	CSEL09	;NO, NEXT COMMAND
;
;DO AN INDIRECT JUMP TO ADDRESS PASSED
;IN AUX1 AND AUX2.  USER ROUTINE MUST
;PERFORM AN RTS TO RETURN TO CRET AND
;MUST RETURN A STATUS IN MEM LOCATION
;$A0 WHERE $00=OK, $02=ERROR
;
	JSR	DELAY
	JSR	ACK
	LDA	#HIGH [CRET-1]	;PUT RETURN ADDRESS
	PHA		;ONTO THE STACK
	LDA	#LOW [CRET-1]
	PHA
	LDA	CMDFRM+3
	PHA		;PUSH ADDRESS ON STACK TO
	LDA	CMDFRM+2	;JUMP TO
	PHA
	RTS
CRET	JSR	DELAY	;DO DELAY
	LDA	:STATUS	;GET STATUS
	CMP	#2
	BNE	CRET1
	JMP	CMDERR
CRET1	JSR	CMPLT	;STATUS OK
	LDA	#$01
	STA	:STATUS	;DO NOT REINT TIMER
	JMP	CMDXIT
;
CSEL09	CMP	#GTRACK	;SEEK TRACK?
	BNE	CSEL10	;NO NEXT COMMAND
;
;NEW TRACK NUMBER IS IN AUX1
;
	JSR	DELAY	;WAIT A BIT
	JSR	ACK	;SEND ACK
	LDA	#41	;CHECK FOR ILLEAGE TRACK
	CMP	CMDFRM+2	;COMPARE WITH AUX1
	BCS	CSEL99
	JMP	CMDERR
CSEL99	JSR	MCK	;TURN ON MOTOR
	LDA	CMDFRM+2
	STA	NTRK
	JSR	SKTK	;SEEK TRACK
	JSR	CMPLT	;SEND COMMPLETE
	LDA	#$01
	STA	:STATUS	;DO NOT RE-INIT
	JMP	CMDXIT
;
;
CSEL10	CMP	#CFRMAT	;CUSTOM FORMAT?
	BNE	CSEL11
;
;DO A USER SET CUSTOM FORMAT
;
	JSR	DELAY	;WAIT A BIT
	LDA	#LOW CFMTBF	;SET UP POINTER TO
	STA	BPNT	;CUSTOM FORMAT BUFFER
	LDA	#HIGH CFMTBF
	STA	BPNT+1
	JSR	ACK
	LDA	#1	;READ IN ONE BYTE
	JSR	READ
;
	LDA	:STATUS	;CHECK STATUS
	BEQ	:CS101	;BRANCH IF OK
	CMP	#2	;CHECK SUM?
	BNE	:CS102
	LDA	#$01
	STA	:STATUS	;DO NOT REINT MOTR
	JMP	CMDNAK
;
:CS102	LDA	#$01
	STA	:STATUS
	JMP	CMDXIT	;TIMEOUT

:CS101	JSR	DELAY
	JSR	ACK	;SEND ACKNOWLEDGE
	JSR	MCK	;DO MOTOR THING
	LDA	#$20	;PUT INTO SD MODE
	ORA	DRA
	STA	DRA
	LDA	#$80
	STA	LENTH
	STA	CONFIG+7
	LDA	#$0
	STA	CONFIG+6
	LDA	#$FB
	AND	CONFIG+5
	STA	CONFIG+5
	LDA	#18
	STA	CONFIG+3
	LDA	STAT
	AND	#$5F
	STA	STAT
	LDA	CFMTBF	;LOAD TRACK TIME
	JSR	CFMT	;DO FORMAT
	LDA	:STATUS	;CHECK STATUS
	BEQ	:CS10
	LDA	TRACK	;GET TRACK NUMBER
	JSR	FDCCK	;CHECK THIS TRACK
	LDA	#0
	STA	:STATUS
	JMP	CMDERR	;ERROR IN FORMAT
:CS10	JSR	CMPLT	;SEND COMPLETE
	LDA	#0
	STA	:STATUS	;DO MOTOR THING
	JMP	CMDXIT
;
;
CSEL11	CMP	#HTME	;SET MOTOR HANG ON
	BNE	CSEL12	;NOPE TRY NEXT ONE
;
;SET LOCATION TL WITH CONTENTS OF AUX1
;
	JSR	DELAY	;WAIT A BIT
	JSR	ACK	;SEND ACK
	LDA	CMDFRM+2
	STA	TL
	JSR	DELAY
	JSR	CMPLT	;SEND COMMPLETE
	LDA	#$01
	STA	:STATUS	;DO NOT RE-INIT
	JMP	CMDXIT
;
;
CSEL12	CMP	#BAUD	;CHANGE BUAD RATE?
	BNE	CSEL13	;NO NEXT COMMAND
;
;SET DUPLICATOR TO ULTRA SPEED MODE
;
	JSR	DELAY	;WAIT A BIT
	JSR	ACK	;SEND ACC
	JSR	DELAY
	JSR	CMPLT	;SEND COMPLETE
	LDA	#$0A	;SEND ONE BYTE OF DATA BACK
	JSR	PUT	;AN $0A? OH WELL WHO KNOWS
	LDA	#$0A
	JSR	PUT
	LDA	FPVEC
	STA	PUT+1
	LDA	FPVEC+1
	STA	PUT+2
	LDA	FGVEC
	STA	GET+1
	LDA	FGVEC+1
	STA	GET+2	;SET UP FAST GET AND PUT
	LDA	#$01
	STA	:STATUS
	JMP	CMDXIT
;
CSEL13	CMP	#TBUFF	;TOGGLE TRACK BUFFER?
	BNE	CSEL14	;NO NEXT COMMAND
;
	JSR	DELAY	;WAIT A BIT
	JSR	ACK	;SEND ACC
	JSR	DELAY
	JSR	CMPLT	;SEND COMPLETE
	LDA	CMDFRM+2	;LOAD AUX1
	STA	TFLAG
	JMP	CMDXIT
;
CSEL14	CMP	#ANAL	;ANALYZE TRACK?
	BNE	CSEL15	;NO
;
	JSR	DELAY
	JSR	ACK
	JSR	MCK	;CHECK MOTOR
	LDA	#0
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	LDY	#0
	TYA
;
;ZERO TRACK INFO BUFFER
;
:CS140	STA	(BPNT),Y
	INY
	BNE	:CS140
	INC	BPNT+1
	LDX	BPNT+1
	CPX	#$24
	BNE	:CS140
;
	JSR	ANL	;ANALYZE TRACK
	LDA	:STATUS
	PHA
	LDA	:STATUS+1
	PHA
	LDA	#0
	STA	BPNT
	LDA	#$20
	STA	BPNT+1
	PLA
	LDY	#$FE
	STA	(BPNT),Y	;PUT NUMBER OF SECTORS
	INY
	PLA
	STA	(BPNT),Y	;STATUS OF OPERATION
	JSR	CMPLT	;OPERATION OK
	LDA	#0	;LENTH OF 256 BYTES
	JSR	SEND
	LDA	#$00
	STA	:STATUS
	JMP	CMDXIT
;
CSEL15	CMP	#WDDM	;WRITE D.D.M.
	BNE	CSEL16
;
	JSR	MCK
	JSR	NTS	;CALCULATE NEW TRACK/SECTOR
	JSR	CTS
	JSR	SBPNT
	JSR	ACK
	LDA	LENTH
	JSR	READ
	LDA	:STATUS
	CMP	#$02	;BAD READ
	BNE	:CS150	;STATUS OK
	LDA	#$00
	STA	:STATUS	;REINIT MOTOR TIME
	JMP	CMDNAK	;SEND NAK
;
:CS150	CMP	#$01	;TIME OUT?
	BNE	:CS151	;NO
	LDA	#0
	STA	:STATUS	;REINTI MOTOR TIME
	JMP	CMDXIT	;YES
;
:CS151	JSR	ACK
	JSR	SKTK	;SEEK TRACK
	LDA	DTAREG	;DO DUMB READ
	BIT	STREG	;CHECK FOR WRITE PROTECT
	BVC	:CS152	;OK
	JMP	CMDERR	;SEND ERROR
;
:CS152	LDA	NSEC
	JSR	SWS
	LDA	#$FF
	STA	TINB	;CLEAR TRACK IN BUFFER
	JSR	CMPLT
	LDA	#0
	STA	:STATUS	;REINIT MOTOR
	JMP	CMDXIT
;
;
CSEL16	CMP	#'f'	;IS IT A CUSTOM SECT SK
	BEQ	:CS16
	JMP	CSEL17	;NO, NEXT COMMAND
;
:CS16	LDA	#0
	STA	BPNT	;SET UP BUFFER POINTER TO 
	LDA	#$20	;RECIEVE CONFIG DATA FROM
	STA	BPNT+1	;COMPUTER
	JSR	DELAY
	JSR	ACK	;SAY WE ARE READY
;
	LDA	#128	;GET 128 BYTES
	JSR	READ
	LDA	:STATUS
	CMP	#$01	;TIME OUT
	BNE	:CS161
	JMP	CMDXIT	;JUST ABORT
:CS161	CMP	#2	;CHECKSUM ERROR?
	BNE	:CS162
	JMP	CMDNAK	;SEND NAK
;
:CS162	JSR	ACK
	LDX	#0
	LDY	#0
:CS163	LDA	(BPNT),Y
	STA	CONFIG,X
	INY
	INX
	CPX	#12	;MOVED ALL CONFIG BYTES?
	BNE	:CS163
;
	LDX	#0
:CS164	LDA	(BPNT),Y
	BEQ	:CS165	;EXIT WHEN SECTOR IS ZERO
	STA	SKTAB,X
	INX
	INY
	JMP	:CS164
;
:CS165	JSR	MCK	;TURN ON MOTOR
	LDA	SRATE	;SAVE STEP RATE
	PHA
	LDA	#200	;REAL SLOW MAN
	STA	SRATE
	LDA	#0
	STA	NTRK
	JSR	SKTK
	LDA	CONFIG+5	;CHECK FOR DD
	AND	#$04
	BEQ	:CS167	;SINGLE OR DUAL DENSITY
	LDA	CONFIG+3
	CMP	#26	;EIGHTEEN SECTORS
	BEQ	:CS167
;
;DOUBLE DENSITY
;
	LDA	STAT
	AND	#%01011111
	ORA	#%00100000
	STA	STAT
	JSR	DDFMT	;FORMAT DISK
	PLA	;RESTORE STEP RATE
	STA	SRATE
;
;CHECK FDC
;
	LDA	#39
	JSR	FDCCK
	LDA	:STATUS
	BNE	:CS169
;
	LDA	#$BF	;VERIFY DATA
	JSR	VDSK
	LDA	:STATUS
	BEQ	:CS16C	;SEND COMPLETE
:CS169	JSR	ERR
	LDA	#$00
	STA	:STATUS
	JMP	CMDXIT
;
;
;DENSITY AND A HALF
;
:CS167	LDA	STAT
	AND	#%01011111
	ORA	#%10000000
	STA	STAT
	JSR	DAHF
	PLA	;RESTORE STEP RATE
	STA	SRATE
;
;CHECK FDC
;
	LDA	#128
	STA	LENTH
	LDA	#39
	JSR	FDCCK
	LDA	:STATUS
	BNE	:C1691
	LDA	#$BF	;VERIFY DATA
	JSR	VDSK
	LDA	:STATUS
	BEQ	:CS16C
:C1691	JSR	ERR
	LDA	#$0
	STA	:STATUS
	JMP	CMDXIT
;
;SINGLE DENSITY FORMAT
;
:CS168	LDA	STAT
	AND	#%01011111
	STA	STAT
	JSR	SFRMAT	;FORMAT DISK
	PLA	;RESTORE STEP RATE
	STA	SRATE
;
	LDA	#39
	JSR	FDCCK
	LDA	:STATUS
	BNE	:C1692
	LDA	#$00
	JSR	VDSK
	LDA	:STATUS	;CHECK STATUS
	BEQ	:CS16C
:C1692	JSR	ERR	;SEND ERROR
	LDA	#$00
	STA	:STATUS
	JMP	CMDXIT
;
:CS16C	JSR	CMPLT
	JMP	CMDXIT
;
CSEL17	CMP	#'m'	;upload sector pattern
			;read track into buffer
	BNE	CSEL18
;
;**************************************
;
; THIS COMMAND WILL TAKE AUX1, AND USE
; IT AS THE TRACK NUMBER, AND THE FIRST
; PACKET OF NON-ZERO NUMBER IN THE 128
; BYTE BUFFER SENT TO BE THE SECTOR
; PATTERN.  IT WILL THEN READ THE 
; SECTORS IN THAT PATTERN INTO THE
; BUFFER AT $2000
;
;**************************************
;
	JSR	GBH	;GET A 128 BYTE BUFFER
	LDA	:STATUS
	BEQ	:CS171
	CMP	#2	;CHECKSUM ERROR?
	BNE	:CS172
	LDA	#0
	STA	:STATUS
	JMP	CMDNAK
:CS172	LDA	#0	;TIMEOUT ERROR
	STA	:STATUS
	JMP	CMDXIT
;
:CS171	JSR	ACK
;
;MOVE SECTOR SKEW TABLE
;
	JSR	MCK	;CHECK MOTOR
	LDX	#0
	LDY	#0
:CS173	LDA	(BPNT),Y
	STA	SKTAB,X
	INX
	INY
	CPX	#26
	BNE	:CS173
;
	JSR	SRT	;GO DO SPECIAL RD TRCK
	LDA	:STATUS
	BEQ	:CS174
	LDA	#0
	STA	:STATUS
	JMP	CMDERR	;SEND ERROR
;
:CS174	JSR	CMPLT	;SEND COMPLETE
	LDA	#$00
	STA	:STATUS
	STA	BCNT	;INIT BUFFER COUNT FRO
			;COMMAND "t"
	JMP	CMDXIT
;
CSEL18	CMP	#'t'	;GET SECTOR FROM BUFFER
	BNE	CSEL19	;NEXT COMMAND
;
;**************************************
;
; THIS COMMAND WORKS IN CONJUCTION WITH
; "r".  IT WILL READ BACK THE SECTOR
; DATA ONE AT A TIME WITH THE FDC STAT
; RETURNED WITH EACH ONE
;
; ON EACH READ, THE NEXT BUFFER IS 
; RETURNED, IT IS ASSUMED THAT THE
; USER KNOWS BETTER
;
;**************************************
;
:SERR	=	$3F00	;SPECIAL PLACE TO PUT
			;TRACK ERRORS IF ANY
;
	JSR	DELAY
	JSR	ACK
	LDA	#0
	STA	BPNT	;SET UP POINTER BASE
	LDA	#$20
	STA	BPNT+1
;
;ADD OFFSET ACORDING TO BCNT
;
	LDA	BCNT
	LDX	#$80
	JSR	MULT	;DO MULTIPLY
	CLC
	ADC	BPNT
	STA	BPNT
	TXA
	ADC	BPNT+1
	STA	BPNT+1
;
	JSR	CMPLT
	LDA	#128
	JSR	SEND
	LDX	BCNT
	LDA	:SERR,X
	STA	STAT+1	;PUT FDC STATUS IN STAT LOC
	LDA	#$01	;DO NOT REINIT MOTOR TIMEOUT
	STA	:STATUS
	INC	BCNT	;NEXT BLOCK OF DATA
	JMP	CMDXIT
;
CSEL19	CMP	#'v'	;upload sctrs to write
	BNE	CSEL20	;NO NEXT COMMAND
;
;**************************************
;
; THIS COMMAND LOADS SECTORS TO WRITE
; TO THE DISK.  AUX1 CONTAINS THE
; BUFFER NUMBER (NOT THE SECTOR #) AND
; AUX2 CONTAINS THE TYPE OF ERROR IF
; ANY THAT SECTOR IS TO CONTAIN
;
;**************************************
;
AUX1	=	CMDFRM+2
AUX2	=	AUX1+1
;
	LDA	AUX1	;GET BUFFER POSITION NUMBER
	LDX	#$80	;SIZE OF BUFFER
	JSR	MULT
	CLC	;CALCULATE BUFFER ADDRESS
	ADC	#$00
	STA	BPNT
	TXA
	ADC	#$20
	STA	BPNT+1
;
	JSR	ACK	;SEND ACKNOLEDGE
	LDA	#128
	JSR	READ	;READ BUFFER
	LDA	:STATUS	;CHECK STATUS
	BEQ	:CS191	;BRANCH IF OK
	CMP	#2	;CHECK SUM?
	BNE	:CS192
	LDA	#$01
	STA	:STATUS	;DO NOT REINT MOTR
	JMP	CMDNAK
;
:CS192	LDA	#$01
	STA	:STATUS
	JMP	CMDXIT	;TIMEOUT
;
:CS191	JSR	ACK
	LDA	AUX2
	LDX	AUX1
	STA	:SERR,X
	JSR	DELAY
	JSR	CMPLT
	LDA	#$01
	STA	:STATUS
	JMP	CMDXIT
;
CSEL20	CMP	#'n'	;upload sector pattern
			;and write buffers to disk
	BNE	CSEL21	;NOPE NEXT COMMAND
;
	JSR	GBH	;GET SECTOR SKEW DATA
	LDA	:STATUS
	BEQ	:CS201	;BRANCH IF DATA GOOD
	CMP	#$02	;CHECKSUM ERROR?
	BNE	:CS202
	LDA	#$0
	STA	:STATUS	;REINIT MOTOR
	JMP	CMDNAK
:CS202	LDA	#0
	STA	:STATUS
	JMP	CMDXIT
;
:CS201	JSR	ACK
	JSR	MCK	;DO MOTOR CHECK
	LDX	#0
	LDY	#0	;MOVE SECTOR SKEW DATA
:CS203	LDA	(BPNT),Y
	STA	SKTAB,X
	INX
	INY
	CPX	#26
	BNE	:CS203
;
	JSR	SPWT
	LDA	:STATUS
	BEQ	:CS204
	LDA	#0
	STA	:STATUS
	JMP	CMDERR	;SEND ERROR
:CS204	JSR	CMPLT
	JMP	CMDXIT
;
CSEL21	CMP	#'j'	;rpm change?
	BNE	CSEL22
;
	JSR	DELAY
	JSR	ACK
	LDA	CMDFRM+2	;LOAD AUX1
;
;AUX1=0 IS NORMAL SPEED
;AUX1=1 IS SLOW SPEED
;
	BNE	:CS211
;
;NORMAL SPEED
;
	LDA	DRA
	ORA	#$04	;SPEED CHANGE BIT
	STA	DRA
	JMP	:CS212
;
:CS211	LDA	DRA	;SLOW SPEED
	AND	#$FB
	STA	DRA
;
:CS212	JSR	DELAY
	JSR	CMPLT
	LDA	#$01
	STA	:STATUS	;DO NOT REINT MOTOR
;
CSEL22	CMP	#$22	;DUAL DENS FORMAT
	BNE	CSEL23
;
	JSR	ACK
	LDA	STAT
	AND	#%01011111
	ORA	#%10000000
	STA	STAT
	LDA	#26
	STA	CONFIG+3
	LDA	#0
	STA	CONFIG+6
	LDA	#4
	STA	CONFIG+5
	LDA	#128
	STA	CONFIG+7
	JSR	MCK
	LDA	SRATE
	PHA	;SAVE STEP RATE
	LDA	#200	;REAL SLOW MAN
	STA	SRATE
	JSR	DAHF	;DO DENS AND HALF FORMAT
	PLA	;RESTORE STEP RATE
	STA	SRATE
;
	LDA	#128
	STA	LENTH
	LDA	#39	;CHECK FDC ON TRACK 39
	JSR	FDCCK
	LDA	:STATUS
	BNE	:CS221
	LDA	#$BF	;VERIFY DATA
	JSR	VDSK
	LDA	:STATUS
	BEQ	:CS220
:CS221	JSR	ERR	;SEND ERROR
	JMP	:CS222
;
:CS220	JSR	CMPLT
:CS222	LDA	#$20
	STA	BPNT+1
	LDA	#0
	STA	BPNT
	LDA	#128
	JSR	SEND
;
	LDA	#0
	STA	:STATUS
	JMP	CMDXIT
;
CSEL23	CMP	#'d
	BNE	CSEL24
;
; THIS COMMAND SETS A FLAG ACORDING
; TO AUX 1, IF AUX1=0 THE FLAG IS DO
; DENSITY TEST, IF AUX<>1 THEN DON'T
;
	JSR	DELAY
	JSR	ACK
	LDA	CMDFRM+2
	STA	DCKFLG
	JSR	DELAY
	JSR	CMPLT
	LDA	#$01
	STA	:STATUS
	JMP	CMDXIT
;
CSEL24	JMP	(CSELXX)	;USR DECODE ROUTINE
;
;COMMAND ERROR
;
CMDERR	JSR	DELAY
	JSR	ERR
	JMP	CMDXIT
;
;BAD COMMAND
;
;BAD COMMAND NAK
;
CMDNAK	JSR	DELAY	;WAIT BEFORE NAK SENT
	JSR	NAK	;SEND NOT ACKNOLEDGE
;
CMDXIT	RTS
;
;**************************************
;
; MCK: MOTOR CHECK
;
; ENTRY:NONE
;  EXIT:NONE
;
;**************************************
;
MCK	PROC
;
	LDA	MFLAG	;CHECK MOTOR ON FLAG
	BNE	:MC01
	JSR	MOON	;TURN ON MOTOT
	LDX	#40	;200MSEC WAIT
:LOOP	JSR	SWAIT
	DEX
	BNE	:LOOP
:MC01	RTS
;
	EPROC
;
;**************************************
;
; GBH :GET A BUFFER OF DATA AND PUT
;     :IT AT $2000
;
; ENTRY:NONE
;  EXIT:STATUS SAME AS READ
;
;**************************************
;
GBH	PROC
;
:STATUS	=	$A0
;
;SET UP BUFFER POINTER
;
	LDA	#0
	STA	BPNT
	LDA	#$2E
	STA	BPNT+1
	JSR	DELAY
	JSR	ACK	;SEND ACK TO COMPUTER
	LDA	#128
	JSR	READ
	RTS
	EPROC
;
;
	LINK	D2:DD15M3.ASM
