;
;**************************************
;
; THIS IS WHERE WE ENTER WHEN PROCESSOR
; IS RESET.
; PERIPHERAL DEVICES ARE INITIALIZED
; MEMORY IS CLEARED
; BACKGROUND PROCESSING, IF ANY IS
; STARTED
;
;**************************************
;
;
START	LDX	#$FF
	TXS		;SET THE STACK POINTER TO
			;TOP OF STACK
	JSR	CLRMEM	;CLEAR MEMORY
	JSR	CLRZER	;CLEAR PAGE ZERO
;
	LDA	#$4C	;LOAD JUMP INSTRUCTION
	STA	GET
	STA	PUT
	LDA	SGVEC	;SET UP SLOW GET VECTOR
	STA	GET+1
	LDA	SGVEC+1
	STA	GET+2
	LDA	SPVEC	;SET UP SLOW PUT VECTOR
	STA	PUT+1
	LDA	SPVEC+1
	STA	PUT+2
	LDA	#0
	STA	DCKFLG	;CHECK TRACK DENSITY
	STA	CMDRT	;SET COMMAND RETRYS TO 0
	LDA	#$FF
	STA	SSTAT	;SPEED STAT AT NORMAL
;
	LDA	#$FF
	STA	FDCFLG	;HAVE NOT FOUND FDC TYPE
	LDA	#$82	;READ SECTOR FOR 1793
	STA	RSECCM
	LDA	#$A2	;WRITE SECTOR FOR 1793
	STA	WSECCM
	LDA	#$A3	;WRITE SECTOR WITH DM 1793
	STA	WSDMCM
;
	LDA	#108	;INITIAL STEP RATE
	STA	SRATE
;
	LDA	#LOW CMDNAK	;INIT USER COMMAND
	STA	CSELXX	;DECODE VECTOR TO COMAND
	LDA	#HIGH CMDNAK	;NAK
	STA	CSELXX+1
	LDA	#$FF
	STA	TINB
	LDA	#$10	;MAX OF 16 SEC TIMEOUT
	STA	STAT+2
	LDA	#$10
	STA	STAT	;TELL THE WORLD WE ARE HERE
;
	LDA	#$3C	;SET PORT A FOR INPUT
	STA	DDRA	;USER MAY IF HE/SHE CHOOSES
	LDA	#$3D
	STA	DDRB
	LDA	#%00111101
	STA	STPPOS
	STA	DRB
	LDA	#$FF
	STA	DRA
	LDA	#$FF
	STA	TFLAG	;PUT IN UNBUFFER MODE
;
	LDA	#40	;DRIVE CONFIG INITIAL (STDRD)
	STA	CONFIG	;40 TRACKS PER SIDE
	LDA	#18
	STA	CONFIG+3	;18 SECTORS PER TRACK
	LDA	#128
	STA	CONFIG+7
	STA	LENTH	;SECTOR LENGTH
	LDA	#$40
	STA	CONFIG+8
;
	LDA	#10
	STA	TL	;INIT MOTOR HANGON TIME 1 SEC
;
	CLD	;CLEAR DECIMAL MODE

	JSR	MCK	;TURN ON MOTOR
	JSR	TRK0	;SEEK TRACK 0
	LDA	#15
	STA	NTRK
	JSR	SKTK	;SEEK TRACK 15
	JSR	TRK0	;SEEK TRACK 0
;
; CHECK TO SEE IF THERE IS A DISK IN
; THE DRIVE
;
	BIT	STREG	;CHECK FDC STATUS
	BMI	STRT01	;DOOR OPEN
	JSR	CSSK	;CHECK TO SEE WHAT FORMAT
;
;
STRT01	JSR	I5SEC	;INIT 5 SECOND TIMER
;
BKGRND	PROC
;
:STATUS	=	$A0
;
	LDA	#2	;BIT MASK
	BIT	DRB	;TEST CMD LINE
	BPL	BK001	;CMD NOT HIGH
	BNE	BK004	;COMPUTER NOT ON
	JSR	RCMDFRM	;GET COMMAND FRAME
;
;ON RETURN, DO A COMPLETE RE-INIT OF
;THE TIMER IF STATUS = 0
;
	LDA	:STATUS	;CHECK STATUS
	BNE	BK003
	JSR	I5SEC	;RE INIT 5 SEC TIMER
	JMP	BK001
BK003	LDA	#97	;.1 SEC INTERVAL
	JSR	STMO	;SET TIMER
	JMP	BK001
;
BK004	LDA	SGVEC	;SET UP SLOW VECTOR
	STA	GET+1
	LDA	SGVEC+1
	STA	GET+2
	LDA	SPVEC
	STA	PUT+1
	LDA	SPVEC+1
	STA	PUT+2
;
;CONTINUE COUNTDOWN
;
BK001	JSR	DRCHK	;CHECK DOOR STATUS
	LDA	MFLAG
	BEQ	BKGRND
	JSR	CK5S	;CHECK 5 SECOND TIMER
	BCC	BK002
	JSR	MOOFF	;TURN OFF MOTOT
	LDA	WT64D
	LDA	#$00
	STA	MFLAG
BK002	JMP	BKGRND	;JUMP TO BACKGROUND
			;ROUTINE
	EPROC
;
;
;**************************************
;
; DRCHK:  CHECK DOOR STATUS
;
; ENTRY: NONE
; EXIT:  NONE
; REGISTERS USED: ACCUMULATOR
;
;**************************************

DRCHK	BIT	STREG
	BPL	DRCHK1	;DOOR CLOSED
	BIT	DRCLSD
	BPL	DRCKXT	;STILL OPEN, EXIT
	LDA	#0	;JUST OPENED
	STA	DRCLSD
	JMP	DRCKXT
DRCHK1	BIT	DRCLSD
	BMI	DRCKXT	;STILL CLOSED, EXIT
	LDA	#$FF	;JUST CLOSED
	STA	DRCLSD
	JSR	MCK	;TURN ON MOTOR
	JSR	CSSK	;CHECK THE FORMAT
	JSR	I5SEC
DRCKXT	RTS


;**************************************
;
; DELAY: ABOUT 250USEC
;
;**************************************
;
DELAY	PHA	;SAVE ACCUMULATOR
	LDA	#42
DEL01	SEC
	SBC	#$01	;DECREMANT ACC
	BNE	DEL01
	PLA
	RTS
;
;**************************************
;
; BTOG: BUAD RATE TOGGLE
;
; ENTRY:NONE
;  EXIT:NONE
;  BUAD RATE IS TOGGLED
;
;**************************************
;
BTOG	PROC
;
	LDA	SSTAT	;LOAD SPEED STATUS
	BNE	:BTG01
	LDA	SGVEC	;SET UP SLOW GET VECTOR
	STA	GET+1
	LDA	SGVEC+1
	STA	GET+2
	LDA	SPVEC	;SET UP SLOW PUT VECTOR
	STA	PUT+1
	LDA	SPVEC+1
	STA	PUT+2
	LDA	#$FF
	STA	SSTAT	;SPEED STAT AT NORMAL
	BNE	:BTGXT
;
:BTG01	LDA	FGVEC	;SET UP US GET VECTOR
	STA	GET+1
	LDA	FGVEC+1
	STA	GET+2
	LDA	FPVEC	;SET UP US PUT VECTOR
	STA	PUT+1
	LDA	FPVEC+1
	STA	PUT+2
	LDA	#$0
	STA	SSTAT	;SPEED STAT AT US
:BTGXT	RTS
;
;
;**************************************
;
; SGET: GET SLOW DATA FROM SERIAL BUS
;
; ENTRY:A-REG =# OF BYTES TO GET
;      :BPNT CONTAIN ADDRESS OF BUFFER
; EXIT:DATA IN BUFFER
;     :$A0 CONTAINS STAUTUS
;     :$A1 CONTAINS CHECKSUM
;
; REGISTERS USED:ACCUMULATOR,X,Y
;               :USES BPNT
;**************************************
;
SGET	PROC
;
:STATUS	=	$A0
:CKSUM	=	$A1
;
	STA	GCNT	;SAVE BYTE COUNT
	LDY	#$00
	STY	FLAG	;INIT CHECKSUM FLAG
:GET01	BIT	DRA	;CHECK FOR TIME OUT
	BVC	DITOUT
	BIT	DRB	;WAIT FOR START BIT
	BVC	:GET01	;LOOP IF NO OVERFLOW
	SEC		;SET CARRY
	LDA	#$80	;A := $80
	LDX	#$06	;
:GET02	DEX	;
	BNE	:GET02	;DELAY LOOP
LB80	LDX	#$06	;
:GET03	DEX	;
	BNE	:GET03	;DELAY LOOP
	NOP
	NOP
	NOP		;TIMING
	BIT	DRB
	BVC	:GET04	;JMP AND SET CARRY
	CLC
	BCC	:GET05	;JMP WITH CARRY CLEAR
:GET04	SEC
	NOP
:GET05	ROR	A
	BCC	LB80
	LDX	FLAG
	BNE	:GETXIT
	STA	(BPNT),Y
	INY
	CPY	GCNT	;DECREMENT BYTE COUNT
	BNE	:GET01	;KEEP GOING, MORE DATA
	LDX	#$FF
	STX	FLAG	;NOW WE GET THE CHECKSUM
	BNE	:GET01
:GETXIT	STA	:CKSUM	;SAVE CHECKSUM
	LDA	#0
	STA	:STATUS
	LDA	WT64D
:GETXT	RTS
;
;DO THIS IF THERE IS A TIMEOUT
;
DITOUT	LDA	#$01
	STA	:STATUS	;TIMEOUT STATUS RETURNED
	LDA	WT64D
	JMP	:GETXT
	EPROC;
SGVEC	DW	SGET
;
;
;**************************************
;
; SPUT:
;    SEND THE BYTE IN THE ACCUMULATOR
;    TO THE ATARI COMPUTER SLOWLY
;
; ENTRY:A<-- BYTE TO SEND
; EXIT: NONE
;
; REGISTERS USED:ALL PRESERVED
;
;
;**************************************
;
;
SPUT	PROC
;
:DATA	=	$A0	;DATA TO TRANSMIT
:SAVEX	=	$A1	;SAVE AREA FOR X REG
:SAVEY	=	$A2	;SAVE AREA FOR Y REG
;
	STA	:DATA
	STY	:SAVEY
	STX	:SAVEX
	LDY	#$08
	LDA	#$FE
	AND	DRB
	STA	DRB
	INC	:SAVEX
PUT93	ROR	:DATA
	BCC	PUT90
	LDA	#$01
	ORA	DRB
	BNE	PUT91
PUT90	LDA	#$FE
	AND	DRB
	NOP
PUT91	LDX	#$05
PUT92	DEX
	BNE	PUT92
	STA	DRB
	DEY
	BNE	PUT93
	LDX	#$06
PUT94	DEX
	BNE	PUT94
	NOP
	DEC	:SAVEX
	LDA	#$01
	ORA	DRB
	STA	DRB
	LDX	#$05
PUT95	DEX
	BNE	PUT95
	LDX	:SAVEX
	LDA	:DATA
	LDY	:SAVEY
	RTS
	EPROC
SPVEC	DW	SPUT
;
;**************************************
;
; SET TIME OUT:
;
;**************************************
;
STMO	STA	WT64D
	STA	WT24E
	RTS
;
;**************************************
;
; ACK:
;     SEND ACKNOLEGDE BACK TO ATARI
;
;  ENTRY:NONE
;  EXIT:NONE
;
;  REGISTERS USED:
;                ACCUMULATOR
;
;**************************************
;
ACK	LDA	#'A'	;LOAD ACK CODE
	JSR	PUT	;SEND IT TO THE ATARI
	RTS
;
;**************************************
;
; NAK:
;     SEND NOT ACKNOLEGED BACK TO ATARI
;
;  ENTRY:NONE
;  EXIT:NONE
;
;  REGISTERS USED:
;                ACCUMULATOR
;
;**************************************
;
NAK	LDA	#'N'	;LOAD NAK CODE
	JSR	PUT	;SEND IT TO THE ARARI
	RTS
;
;**************************************
;
; ERR:
;     SEND ERROR BACK TO ATARI
;
;  ENTRY:NONE
;  EXIT:NONE
;
;   REGISTERS USED:A
;
;**************************************
;
ERR	LDA	#'E'	;LOAD ERROR CODE
	JSR	PUT	;SEND IT TO THE ARARI
	RTS
;
;**************************************
;
; CMPLT:
;     SEND PROCESS COMPLETE CODE
;
; ENTRY: NONE
; EXIT:  NONE
;
;   REGISTERS USED:A
;
;**************************************
;
CMPLT	LDA	#'C'	;LOAD COMPLETE CODE
	JSR	PUT	;SEND IT TO THE ATARI
	RTS
;
;
;**************************************
;
; CSUM:
;      COMPUTE THE CHECKSUM
;
; ENTRY:A CONTAINS VALUE TO ADD TO CSUM
;  EXIT:NONE
;
;**************************************
;
CSUM	PHA	;SAVE ACCUMULATOR
	CLC	;PREPARE TO ADD
	ADC	CHKSUM
	ADC	#$00
	STA	CHKSUM
	PLA	;RECOVER ORIGINAL VALUE
	RTS
;
;**************************************
;
; CKSM:
;
;      COMPUTE THE CHECKSUM ATARI STYLE
;
;  ENTRY:X REG NUMBER OF VALUES TO CHK
;       :BPNT=ADDRESS OF STRING
;       :CHKSUM IS IN REG A
;  EXIT:CARRY SET IF BAD CHECKSUM
;
;   REGISTERS USED:A,X,Y
;
;   MEMORY USE:
;             ONE BYTE ON PAGE ZERO
;             CHKSUM
;
;**************************************
;
CKSM	PROC
;
:CHKSM	=	$A0
;
	STA	:CHKSM	;SAVE CHECKSUM
	STX	GCNT	;SET UP LOOP COUNTER
	LDY	#$00	;ZERO INDEX
	TYA	;ZERO ACCUMULATOR
CKSM01	CLC
	ADC	(BPNT),Y;SUM WITH CHECKSUM
	ADC	#$00	;ADD CARRY IF ANY
	INY
	CPY	GCNT	;END OF STRING?
	BNE	CKSM01
	SEC
	SBC	:CHKSM	;EQUAL TO CHECKSUM?
	STA	:CHKSM	;RETURN 0 IF EQUAL
	BEQ	:EXIT
	LDA	#$02
	STA	:CHKSM	;BAD CHECKSUM
:EXIT	RTS
	EPROC
;
;**************************************
;
; CLRMEM:
;       CLEAR MEMORY PAGES 2 TO $0F
;
;  ENTRY:NONE
;  EXIT:PAGES 2 TO 15 FILLED WITH $00
; 
;   REGISTERS USED:A,X,Y
;
;   MEMORY USED:2 BYTES PAGE ZERO
;
;**************************************
;
CLRMEM	LDA	#HIGH BUFF	;ON PAGE ZERO TO POINT
	STA	BPNT+1	;TO MEMORY TO CLEAR
	LDA	#LOW BUFF	;CLEAR ACCUM
	STA	BPNT	;SET UP INDIRECT POINTER
;
	LDY	#$00	;INIT INDEX REGISTER
CLMEM1	STA	(BPNT),Y
	INY	;POINT TO NEXT BYTE
	BNE	CLMEM1
	INC	BPNT+1	;INC MEMORY POINTER
	LDX	BPNT+1
	CPX	#$40	;END OF MEMORY TO CLEAR (2K)
	BNE	CLMEM1	;CONTINUE UNTILL DONE
	RTS
;
;HIGH SPEED TRANSFER ROUTINES
;
;**************************************
;
; FGET: GET FAST DATA FROM SERIAL BUS
;
; ENTRY:A-REG =# OF BYTES TO GET
;      :BPNT CONTAIN ADDRESS OF BUFFER
; EXIT:DATA IN BUFFER
;     :$A0 CONTAINS STAUTUS
;     :$A1 CONTAINS CHECKSUM
;
; REGISTERS USED:ACCUMULATOR,X,Y
;               :USES BPNT
;**************************************
;
FGET	PROC
;
:STATUS	=	$A0
:CKSUM	=	$A1
:DUMMY	=	$A8
;
	STA	GCNT	;SAVE BYTE COUNT
	TAX
	LDY	#$00
:FGET1	BIT	DRA	;4 CHECK FOR TIME OUT
	BVC	:TOUT	;2
:FGET2	BIT	DRB	;4 WAIT FOR START BIT
	BVC	:FGET2	;2 LOOP IF NO OVERFLOW
	SEC		;2 SET CARRY
	LDA	#$80	;2 A := $80
	NOP	;2
	NOP	;2
	NOP	;2
	NOP	;2
	STX	:DUMMY	;3
;
:LOOP	STX	:DUMMY	;3
	BIT	DRB	;4
	BVC	:FGET4	;JMP AND SET CARRY
	CLC
	BCC	:FGET5	;JMP WITH CARRY CLEAR
:FGET4	SEC
	NOP
:FGET5	ROR	A
	BCC	:LOOP
	STA	(BPNT),Y	;STORE RECIEVED DATA
	INY
	DEX
	BEQ	:FGET9	;END OF GET
	JMP	:FGET2	;KEEP GOING, MORE DATA
;
;GET CHECKSUM
;
:FGET6	BIT	DRA	;4 CHECK FOR TIME OUT
	BVC	:TOUT	;2
:FGET9	BIT	DRB	;4 WAIT FOR START BIT
	BVC	:FGET9	;2 LOOP IF NO OVERFLOW
	SEC		;2 SET CARRY
	LDA	#$80	;2 A := $80
	NOP	;2
	NOP	;2
	NOP	;2
	NOP	;2
	STX	:DUMMY	;3
;
:LOOP1	STX	:DUMMY	;3
	BIT	DRB	;4
	BVC	:FGET7	;JMP AND SET CARRY
	CLC
	BCC	:FGET8	;JMP WITH CARRY CLEAR
:FGET7	SEC
	NOP
:FGET8	ROR	A
	BCC	:LOOP1
;
	STA	:CKSUM	;SAVE CHECKSUM
	LDA	#0
	STA	:STATUS
	LDA	WT64D
:GETXT	RTS
;
;DO THIS IF THERE IS A TIMEOUT
;
:TOUT	LDA	#$01
	STA	:STATUS	;TIMEOUT STATUS RETURNED
	LDA	WT64D
	JMP	:GETXT
	EPROC;
FGVEC	DW	FGET
;
;
;**************************************
;
; FPUT:
;    SEND THE BYTE IN THE ACCUMULATOR
;    TO THE ATARI COMPUTER SLOWLY
;
; ENTRY:A<-- BYTE TO SEND
; EXIT: NONE
;
; REGISTERS USED:ALL PRESERVED
;
;
;**************************************
;
;
FPUT	PROC
;
:DATA	=	$A0	;DATA TO TRANSMIT
:SAVEX	=	$A1	;SAVE AREA FOR X REG
:SAVEY	=	$A2	;SAVE AREA FOR Y REG
:DUMMY	=	$A8
:;
	STA	:DATA	;STORE DATA
	STY	:SAVEY
	LDY	#$08
	LDA	#$FE
	AND	DRB
	STA	DRB	;SET DATA BIT LOW
	BIT	:DUMMY
	NOP
:FPUT3	LSR	A
	LSR	:DATA+$100
	ROL	A	;PUT DATA BIT INTO D0 POSITION
	STA	DRB
	DEY
	BNE	:FPUT3	;LOOP UNTIL OUT OF DATA
;
	LSR	A
	SEC
	ROL	A	;MAKE DATA BIT =1
	NOP
	BIT	:DUMMY
	STA	DRB
	LDY	:SAVEY
	RTS
	EPROC
FPVEC	DW	FPUT
;
;
;**************************************
;
; CLRZER:
;       CLEAR PAGE ZERO
;
; ENTRY:NONE
; EXIT: PAGE ZERO FILLED WITH $00
;
;  REGISTERS USED :A,X
;
;**************************************
;
CLRZER	LDA	#$00	;SET UP TO CLEAR MEM
	TAX	;INIT INDEX REGISTER
CLZER1	STA	ZERO,X	;CLEAR MEMORY BYTE
	INX
	CPX	#$80
	BNE	CLZER1	;CONTINUE TILL DONE
	RTS
;
;**************************************
;
; SDSTAT:
;       SEND STATUS TO THE ATARI COMPT
;
; ENTRY:NONE
; EXIT: STATUS SENT TO ATARI
;
;  REGISTERS USED:A,X
;
;  MEMORY USED:SENDS STATUS BLOCK FROM
;              PAGE ZERO SEE ABOVE
;
;  FORMAT OF STATUS ARRAY:
;  BYTE 0:COMMAND STATUS
;  BYTE 1:HARDWARE STATUS
;  BYTE 2:TIMEOUT
;  BYTE 3:UNUSED
;
;  COMMAND STATUS:
; BIT0=1 INDICATES INVALID CMD FRM REC
; BIT1=1 IND. INVALID DATA FRAME REC.
; BIT2=1 IND. PUT WAS UNSUCCESSFUL
; BIT3=1 IND. DISKET IS WRITE PROTECTED
; BIT4=1 IND ACTIVE STANDBY
; BIT5=1 IND DOUBLE DENSITY
;
; BIT7=1 IND DUAL DENSITY
;
; HARWARE STATUS = STAT REG OF 1793
;
; TIME OUT = MAX TIME HANDLER TO USE
;
;
;**************************************
;
SDSTAT	LDA	#$00	;INITIALIZE CHECKSUM
	STA	CHKSUM
	TAX	;INIT INDEX REGISTER
SSTAT1	LDA	STAT,X	;LOAD BYTE FROM
			;STATUS ARRAY
	JSR	CSUM	;CALCULATE CHECKSUM FOR XMIT
	JSR	PUT	;SEND IT TO ATARI
	INX
	CPX	#$04	;SENT ALL FOUR BYTES?
	BNE	SSTAT1
;
	LDA	CHKSUM	;LOAD CHECK SUM
	JSR	PUT	;SEND IT TO ATARI TOO
	RTS	;RETURN
;
;
;**************************************
;
; READ:
;      FILLS BUFFER ON PAGE TWO WITH
;      256 BYTES OF DATA SENT BY
;      ATARI
;
; ENTRY:ACC=LENTH (0=256 BYTES)
;      :BPNT= BUFFER AREA TO PUT DATA
; EXIT: BUFFER FILLED WITH DATA
;     : $A0 STATUS OF OPERATION
;     : 0=OK
;     : 1=TIMEOUT
;     : 2=CHECKSUM ERROR
;
; REGISTERS USED:A,X,Y
;
; MEMORY USED:PAGE 2
;
;**************************************
;
READ	PROC
:CHKS	=	$A1	;CHECKSUM RETURNED FROM GET
:STATUS	=	$A0	;STATUS RETURNED BY GET
:LEN	=	$A2	;LENTH OF BUFFER TO SEND
;
	STA	:LEN
	JSR	GET	;GET DATA FROM SIO BUS
	LDA	:STATUS	;CHECK STATUS
	BNE	:RDXIT
	LDA	:CHKS
	LDX	:LEN	;CHECK LEN BYTES
	JSR	CKSM
:RDXIT	RTS
	EPROC
;
;
;**************************************
;
; SEND:
;      SEND DATA IN PAGE 2 BUFFER BACK
;      TO THE ATARI COMPUTER
;
;  ENTRY:BPNT POINTS TO DATA TO SEND
;  EXIT :DATA SENT TO ATARI
;
;  REGISTERS USED:A,Y
;
;  MEMORY USED:PAGE 2 AS MEMORY BUFFER
;             :$A4
;**************************************
;
SEND	PROC
;
:LEN	=	$A4
	STA	:LEN
	LDA	#$00	;INITIALIZE CHECKSUM
	STA	CHKSUM
	TAY	;INITIALIZE INDEX REGISTER
:SEND1	LDA	(BPNT),Y	;LOAD DAT FROM BUFF
	JSR	CSUM	;CALCULATE CHECK SUM
	JSR	PUT	;SEND DATA TO ATARI
	INY	;NEXT MEMORY LOCATION TO SEND
	CPY	:LEN	;COMPARE TO LENTH TO SEND
	BNE	:SEND1	;SENT ALL 256 BYTES?
;
	LDA	CHKSUM	;LOAD CHECKSUM
	JSR	PUT	;AND SEND IT ON ITS WAY
	RTS	;DONE
	EPROC
;
	LINK	D2:DD15M2.ASM
