	PROCESSOR 6502
	LIST	ON
;-------------------------------------------------------------------------
; Defines - this code can be built one of four ways
;	1. to run in RAM
;	2. to run out of Hobbycard EEPROM
;
;	select one of these three options
;-------------------------------------------------------------------------

;-------------------------------------------------------------------------
;  Constants
;-------------------------------------------------------------------------

BS              EQU     $DF             ;Backspace key, arrow left key
CR              EQU     $8D             ;Carriage Return
ESC             EQU     $9B             ;ESC key
PROMPT          EQU     "\"             ;Prompt character

;-------------------------------------------------------------------------
;  MONITOR FUNCTIONS
;-------------------------------------------------------------------------

COUT            EQU     $FDED           ;Backspace key, arrow left key
IOSAVE		EQU	$FF4A		;Save all registers
IOREST		EQU	$FF3F		;Restore all registers
HOME		EQU	$FC58		;Clear Screen
MOVE		EQU	$FE2C		;Move memory
MON		EQU	$FF65		;Monitor entry point
SETKBD		EQU	$FE89		;IN#0 sets default input vector
SETVID		EQU	$FE93		;PR#0 sets default output vector
WAIT		EQU	$FCA8		;wait function
PRBYTE		EQU	$FDDA		;print hex byte
NXTA4		EQU	$FCB4		;inc A4 and A1 until A1 = A2


;-------------------------------------------------------------------------
;  I/O FUNCTIONS
;-------------------------------------------------------------------------
KEYBOARD	EQU	$C000		;keyboard data
KEYSTROBE	EQU	$C010		;clears keyboard data

;-------------------------------------------------------------------------
;  6522A FUNCTIONS
;-------------------------------------------------------------------------
TMR2L	EQU	$c088			;timer2 low byte
					; write: load LS byte
					;
					; read: tjo read low counter and clear interrupt
TMR2H	EQU	$c089			;tijmer2 high byte
					; wrt: high byte, transfer high and low to counter & enable int
					; rd: read high counter
					; 
ACR	EQU	$c08B			;aux control register
					;bit 5 = 0 timer 2 one shot mode
					;bit5 = 1 timer 2 count pulses output on PB 6
					;
IFR	EQU	$c08C			;interrupt flag register
					; read: bit 7 state of IRQ, bit 5 timer 2 interrupt pending
					; write: set bit to clear interrupt
					;
IER	EQU	$c08E			;interrupt enable register
					;bit 7 = 1 to set
					;bit 7 = 0 to clear
					;bit 5 = timer 2

;-------------------------------------------------------------------------
;  Memory declaration
;-------------------------------------------------------------------------

WINDOWTOP	EQU	$22		;top edge of window

HEX1L           EQU     $24     	    ;End address of dump block
HEX1H           EQU     $25
HEX2L           EQU     $26             ;Begin address of dump block
HEX2H           EQU     $27

SAVEINDEX       EQU     $28             ;Save index in input buffer
LASTSTATE       EQU     $29             ;Last input state


;unused by monitor or applesoft
; address setup for move command
AD1L		EQU	$1a
AD1H		EQU	$1b
AD2L		EQU	$1c
AD2H		EQU	$1d
AD4L		EQU	$1e
AD4H		EQU	$1f
;address holding locations for monitor move command
A1L		EQU	$3c
A1H		EQU	$3d
A2L		EQU	$3e
A2H		EQU	$3f
A4L		EQU	$42
A4H		EQU	$43

IN              EQU     $0200	     	    ;Input buffer

WORKING		EQU	$0800		;Working Memory

FLIP            EQU     $C020           ;Output flip-flop
TAPEIN          EQU     $C060           ;Tape input
KBD             EQU     $C000           ;keyboard input
KBDCR           EQU     $C010           ;keybaord strobe clear


;---------------------------------------------------------------------------
; build in ACI Driver
;---------------------------------------------------------------------------
;BLD4RAM EQU 0
		IFCONST	BLD4RAM 
                	ORG $800	; build for memory
		ELSE
			ORG $c700	; plug in hobbyboard
		ENDIF



START:
	BIT $20		; pretend this is Disk 2, so autostart will run it automatically
	BIT $00
	BIT $03
	BIT $3C
;------------------------------------------------------------------------
; make sure no other card has 2K block selected
;--------------------------------------------------------------------------
	LDA	$CFFF			; 

;------------------------------------------------------------------------
; now figure out our slot
;--------------------------------------------------------------------------
	JSR 	IOSAVE			; save registers
	SEI				; block interrupts
	JSR	$FF58			; move current PC to stack
	TSX
	LDA	$0100,X			; fetch high address
	STA	$07F8			; save currently active card
	AND	#$07			; mask off $CX to get slot #
	TAY
	ASL
	ASL
	ASL
	ASL	
	TAX				; can be used to access 6522 VIA at C0SX
	STA	$478,y			;save in scratchpad register
	LDA	#0			;initialize pass count
	STA	$4f8,y			;save in scratchpad register
	STA	$6f8,y			;save interrupt count
;
; save default interrupt routine
;
	LDA	$3FE			;
	STA	$578,y
	LDA	$3FF
	STA	$5f8,y
;
; set up hobby board interupt handler
;
	LDA	#<HOBBYINTERRUPT
	STA	$3FE
	IFCONST	BLD4RAM 
	LDA	#>HOBBYINTERRUPT
	ELSE
	LDA	$07F8
	ENDIF
	STA	$3FF
;
; restore normal COUT and CIN
;
	JSR	SETKBD
	JSR	SETVID				

	JSR	HOME			;clear screen

;
; print banner
;
	LDA	#>BANNER
	STA	A1H
	LDA	#<BANNER
	STA	A1L
	JSR	PRINTSTRING

	LDA	#1			; prevents banner from being scrolled off top
	STA	WINDOWTOP
		
	LDA	#>TESTSTART
	STA	A1H
	LDA	#<TESTSTART
	STA	A1L
	JSR	PRINTSTRING
;
; initialize 6522A counter interrupt
;
	LDA	$07F8
	AND	#$07			; mask off $CX to get slot #
	ASL
	ASL
	ASL
	ASL	
	TAX				; can be used to access 6522 VIA at C0SX
; setup timer 2 as a oneshot
	LDA	#$0
	STA	ACR,X
;
	LDA	#$ff			; change to $FF
	STA	TMR2L,X
	STA	TMR2H,X
;	
	LDA	#$A0			; enable interupt for Timer 2
	STA	IER,X

STRTTEST:
	JSR	PIATEST
	CLI				; enable interupts
	NOP				; give interrupts a chance to come in
	NOP
	SEI				; disable interrupts again
	LDA	KEYBOARD		;check to see if keyboard input (stops test)
	BMI	TESTEXIT		;yes clear strobe, print finished and back to monitor


	LDA	$CFFF			;clear strobe

;
; finished pass, increment count and print banner
;

	LDA	#>PASSED
	STA	A1H
	LDA	#<PASSED
	STA	A1L
	JSR	PRINTSTRING
	LDA	$07F8			; save currently active card
	AND	#$07			; mask off $CX to get slot #
	TAY
	LDA	$6f8,Y			;fetch interrupt count from scratchpad register
	PHA				;save interrupt count
	LDA	$4F8,Y			;fetch pass count
	TAX
	INX				;increment count
	TXA
	STA	$4f8,Y			;save count
	JSR	PRBYTE			;print hex number

	LDA	#>INTERUPTS
	STA	A1H
	LDA	#<INTERUPTS
	STA	A1L
	JSR	PRINTSTRING
	PLA				;fetch interrupt counter
	JSR	PRBYTE

	LDA	#$8d
	JSR	COUT			;newline
	SEC
	BCS	STRTTEST

TESTEXIT:
	LDA	KEYSTROBE		;clear keyboard strobe
	LDA	#0			; reset window top
	STA	WINDOWTOP

	LDA	#>ABORTED
	STA	A1H
	LDA	#<ABORTED
	STA	A1L
	JSR	PRINTSTRING
;
; restore default interrupt routine
;
	LDA	$07F8			; save currently active card
	AND	#$07			; mask off $CX to get slot #
	TAY

	LDA	$578,y
	STA	$3FE			;
	LDA	$5f8,y
	STA	$3FF
	JMP	MON

HOBBYINTERRUPT:
	LDA	$CFFF
	JMP	HOBBYINT



	IFCONST	BLD4RAM 
        	ORG $0900	; build for memory
	ELSE
		ORG $C800	; plug in hobbyboard:w
	ENDIF
	;
;  MOVE from A1 to A4 - until A1 = ending address in A2
;
MOV:
	LDY	#0	; index = 0
	LDA	AD1L
	STA	A1L
	LDA	AD1H
	STA	A1H

	LDA	AD2L
	STA	A2L
	LDA	AD2H
	STA	A2H

	LDA	AD4L
	STA	A4L
	LDA	AD4H
	STA	A4H
MOV2:
	LDA   (A1L),Y    ; MOVE A1[0x3C] TO A2[0x3E] TO
	STA   (A4L),Y    ; A4[0x42]
MOVEWAIT:
	CMP	(A4L),Y		; for eeprom - wait till write takes
	BNE	MOVEWAIT	; MSB not correct until write is done
	JSR   NXTA4
	BCC   MOV2
	RTS
BEGIN:	
PIATEST:
	LDA	$07F8			; fetch currently active card
	AND	#$07			; mask off $CX to get slot #
	ASL
	ASL
	ASL
	ASL	
	TAX				; can be used to access 6522 VIA at C0SX

	LDA	#$FF
	TAY
	STA	$C083,X		; set port A for output
BLINKLED:
	STA	$C081,X		; set port A, all bits on
	JSR	WAIT			; wait 1/2*(26+27*255+5*255^2) =166018 useconds
	LDA	#$0
	STA	$C081,X		; turn all bits off
	LDA	#$ff
	JSR	WAIT

	LDA	KEYBOARD
	BMI	BRKTEST

	LDA	#$ff
	DEY
	BNE	BLINKLED		; continue forever
BRKTEST
	RTS

PRINTSTRING:
	LDY	#0
PS1:
	LDA	(A1L),Y
	BEQ	PSDONE
	ORA	#$80
	JSR	COUT
	INY
	BNE	PS1
PSDONE:
	RTS

HOBBYINT:
	LDA	$07F8			; save currently active card
	AND	#$07			; mask off $CX to get slot #
	TAX
	INC	$6F8,X			;increment interrupt count

	ASL
	ASL
	ASL
	ASL	
	TAX				; can be used to access 6522 VIA at C0SX

; clear timer 2 interrupt and restart
	LDA	#$FF
	STA	TMR2H,X			; clear interrupt from timer register
	LDA	#20
	STA	IFR,X			; clear interrupt from interrupt flag register
	RTI



BANNER:	DC	"SUPER PROTO COPYRIGHT 2010 MIKE WILLEGAL",$0d,0
TESTSTART: DC	"STARTING AUTOMATIC TEST",$0d,0
PASSED:	DC	"PASS:  ",0
ABORTED: DC	"TEST STOPPED BY KEYBOARD INPUT",$0d,0
INTERUPTS: DC	" INTERRUPTS: ",0

	IFCONST EXTRACODE
;
; make sure magic number is in STROBE space
;;
; move copy of code to DRAM
;
	LDA	#<BEGIN				
	STA	A1L
	LDA	#>BEGIN
	STA	A1H
	LDA	#<END
	STA	A2L
	LDA	#>END
	STA	A2H
	LDA	#<WORKING
	STA	A4L
	LDA	#>WORKING
	STA	A4H
	LDY	#0
	JSR	MOVE			;put copy of program in DRAM
	LDA	#$C8
	STA	A1H
	LDA	#$00
	STA	A1L
	TAX
`	LDA	$55
	CMP	(A1L),X
;	BEQ	BEGIN

WRITEEEPROM:
	PHA
	LDA	#0
	TAX
	PLA
	CMP	(A1L),X			; only write if data is different than current data
	BEQ	WRITEDONE
	STA	(A1L),X
WRITEWAIT:
	CMP	(A1L),X
	BNE	WRITEWAIT
WRITEDONE:
	RTS
	ENDIF
