;##########################################################################
;
;                       *** ct-BASIC Bootloader ***
;
; EHBASIC Bootloader for T65 Core on FPGA by C. Meyer 3/2009
; Version 2.3 mit Hardware-Multiplier für Textdarstellung
; Erkennt Maus oder PS/2-Keyboard und lädt entsprechendes 
; ehbas_m.dat (Maus), ehbas_k.dat (Keyboard) oder ehbas_a.dat (Autostart) nach
; 
; Im 6502 Simulator (Download unter http://home.pacbell.net/michal_k/) 
; als Code "ehboot.dat" speichern mit:
; Dateityp "Binary image"
; Options: Begin $F000, End $FFFF bei AIM=61440 in BASIC.INI
; C.Meyer 06/2010, cm@ctmagazin.de
;
;##########################################################################

	.START Reset
	.ROM_AREA $F000, $FFFF
	.OPT	Proc65c02, CaseInsensitive

; supported by t65 core: inc, dec, phx, plx, phy, ply
; missing: bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8

VGA640		= 0	; Version für VGA 640x480
LCD320		= 0	; Version für LCD 320 x 240, 40 Zeichen / 20 zeilen
LCD480		= 1	; Version für LCD 480 x 234, 60 Zeichen / 19 zeilen

	.INCLUDE "defines_cm.asm"	; HW- und ZeroPage-Belegung
	
	*=$F000


Print2SP       jsr   Print1SP          ; print 2 SPACES
Print1SP       LDA   #$20              ; print 1 SPACE
               JMP   WriteScreen            ;
               
Print_CR       PHA                     ; Save Acc
               LDA   #$0D              ; "cr"
               JSR   WriteScreen            ; send it
               LDA   #$0A              ; "lf"
               JSR   WriteScreen            ; send it
               PLA                     ; Restore Acc
               RTS                     ; 

;############################################################
;#	 Zeichen-Ausgabe auf Bildschirm oder COM	    #
;############################################################

; Kommunikationsroutinen
	

omode_stx:		; sende STX (Start Text), warte auf ACK
	LDA #$80
	STA Omode
	LDA #2		; CTRL-B als Startzeichen senden
	JSR SendByte	; 
	LDA #4	
	JSR TickerDelay	; Verarbeitung abwarten
	RTS
	
omode_etx:
	LDA #$00
	STA Omode
	LDA #3		; CTRL-C/ETX als Ende-Zeichen-senden
	JMP SendByte	; nicht auf Screen, sondern Abschlusszeichen seriell

WriteAcc:		; Zeichen in Acc ausgeben
	CMP #$02	; STX? Omode auf AVR-COM/OptoBusCore, $02 senden
	BEQ omode_stx
	CMP #$03	; ETX? Omode auf Screen
	BEQ omode_etx	
	BIT Omode	; wenn $80, Ausgabe auf COM
	BPL WriteScreen
;	BVS WriteStatus	; Fehlermeldungen landen hier mit omode=$40

SendByte:		; Zeichen auf AVR-COM ausgeben
	STA asave
	STY ysave
	LDA COMCH
	BEQ SendByte0

SendByte1:		; SerialCore
	BIT UART1TxS
	BVS SendByte1	; warte bis Buffer nicht mehr voll
	LDA asave
	STA UART1D	; ausgeben
	LDY #0
Ydelay:		; 102 us Pause pro Byte
	DEY
	BNE Ydelay
	LDY ysave
	RTS
		
SendByte0:		; AVR COMport SPI
	BIT Tx0ACK
	BPL SendByte0	; noch kein ACK empfangen?
SendByte0weiter:
	LDA asave
	STA COMport
	LDY #$01	; Byte ausgeben, F_INT kurz triggern
	STY IRQena
	DEY
	STY IRQena	; ist 0
	JSR Ydelay
	CMP #$0D	; Acc=CR?
	BNE SendByte0exit
	LDA #0
	STA Tx0ACK	; ACK löschen nach CR
SendByte0exit:
	LDY ysave
	LDA asave		
	RTS

	

WriteStatus:		; Fehlermeldungen landen hier mit omode=$40

WriteScreen:		; Akku auf Screen, aktualisiert TextPosX/Y
	STA	asave
	STX	xsave	; benutzt nur A und X, sofern keine Controls
	LDX	TextPosX
	STX	TextX
	LDX	TextPosY
	STX	TextY
; I/O-Steuerzeichen behandeln
	CMP 	#$20	; writable?
	BCC 	WriteControls
	
writeChar1:
	STA	TextWR		; Zeichen in GTEXT-Schreibregister
	LDX	TextPosX
	CPX	TextWinRight	; #colstotal	; Ende der Zeile?
	BEQ	writeCharLF
	INX
	STX	TextX
	STX 	TextPosX
	LDX	xsave
	LDA	asave
	RTS	

writeCharLF:	
	STY	ysave
	LDX	TextWinLeft		; #0		; Zeilenanfang
	STX	TextPosX
	JMP	lf

; Sondertasten behandeln, Pfeiltasten usw.
DispatchControls_0:
	LDY	#0
	STY	asave		; nur ausführen, aber nicht merken
WriteControls:
	STY ysave
DispatchControls:
	STA	work
CodeDispatch_0:	; Suchroutine
	LDY	#$FF
CodeDispatch_1:
	INY
	LDA	SpecialCode,Y
	BEQ	GetKeyNone	; Nicht gefunden?
	CMP	work
	BNE	CodeDispatch_1
	LDA	SpecialActionL,Y
	STA	ptrsrc
	LDA	SpecialActionH,Y
	STA	ptrsrc+1
	JMP	(ptrsrc)

GetKeyExit:
	LDY	ysave
	LDX	xsave
	CMP 	#0
	BNE	GetKeyExit_0
	CLC
	RTS
GetKeyExit_0:
	SEC
	RTS
GetKeyNone:
	LDA	#0
	BEQ	GetKeyExit	; immer

SpecialCode:
; normale ASCII-Controls
	.DB	$0D	; CR
	.DB	$0A	; LF
	.DB	$0B	; VT
	.DB	$09	; TAB, hier HT
	.DB	$03	; ETX
	.DB	$08	; BS, hier DEL
	.DB	$0C	; CLS
	.DB	$1F	; HOME
	.DB	$00

SpecialActionL:
; normale ASCII-Controls
	.DB	<cr
	.DB	<lf
	.DB	<vt
	.DB	<ht
	.DB	<omode_etx
	.DB	<del
	.DB	<cls	
	.DB	<hc
	

SpecialActionH:
; normale ASCII-Controls
	.DB	>cr
	.DB	>lf
	.DB	>vt
	.DB	>ht
	.DB	>omode_etx
	.DB	>del
	.DB	>cls	
	.DB	>hc

restore:
	LDA TextPosX
	STA TextX
	LDA TextPosY
	STA TextY
	LDA Color
	STA ColorP
	LDX xsave
	LDY ysave
	LDA asave
	RTS	



	

vt:	LDX TextPosY
	CPX TextWinTop	; #rowstart
	BEQ restore	; schon ganz oben?
	DEX
	STX TextPosY
	JMP restore

bs:	LDX TextPosX
	CPX TextWinLeft
	BEQ restore	; nicht unter 0
	DEX
	STX TextPosX
	JMP restore
	
ht:	LDX TextPosX
	CPX TextWinRight	; #colstotal-1
	BEQ restore	; nicht über Ende der Zeile
	INX
	STX TextPosX
	JMP restore

lf:	LDX TextPosY
	INC TextPosY
	CPX TextWinBtm	; #rowstotal
	BEQ scroll
	JMP restore

hc:	LDA TextWinTop	; #rowstart	; Home Cursor
	STA TextPosY
	LDA TextWinLeft	; #0
	STA TextPosX
	JMP restore

cr:	LDA #0
	STA InsFlg
cr_0:
	LDA TextWinLeft	; #0
	STA TextPosX
cr_end:
	JMP restore

del:	LDX TextPosX
	BEQ del_end	; nicht unter 0
	DEX
	STX TextX
	STX TextPosX
	LDA #$20	; mit Leerzeichen löschen
	STA TextWR
del_end:
	JMP restore
		
scroll:
	LDY TextWinTop	; #rowstart+1
scrollLoop:
	INY
	JSR LineCopyUp
	CPY TextWinBtm	; #rowstotal	; letzte Zeile?
	BNE scrollLoop
	JSR lineclrY
	STY TextPosY
	JMP restore
	
OverlayClear:
; Bigfont-Overlay-Text löschen
	LDA	#' '
	LDY	#11	
OverlayClear_Y:
	LDX	#colstotal/2	
OverlayClear_X:
	STY BtnY
	STX BtnX
	STA BtnWR		; Zeichen in GTEXT-Schreibregister
	DEX
	BPL OverlayClear_X
	DEY
	BPL OverlayClear_Y
	LDA	#0
	RTS
	
ClearFullScreen:
	STA asave
	STX xsave
	STY ysave
ClearFullScreen_0:
	JSR SetFullScreen
	JSR OverlayClear
	LDA	#0
	STA	MouseOverlayToggle
	LDY #rowstotal		; Müll in letzter Zeile+1
	JSR lineclrY
	
	LDA #$02		; CLS von Tastatur oder Reset immer auf grün
	STA Color
	LDA #$00
	STA GFrameC
	
cls:	LDY #0		; oberste Zeile
	LDX #0
	.IF LCD320
	LDA #$01
	.ELSE
	LDA #7
	.ENDIF	
	STA ColorP
	
	JSR ClearWindow
	JMP restore

StatusBar:
	LDX #0
	LDY #1
	LDA #202	; code page 437 "-"
statusbarloop:
	JSR writecharxy
	INX
	CPX #colstotal
	BNE statusbarloop
	RTS

ClearWindow:
	LDA Color	; letzte Grundfarbe
	STA ColorP
	LDA #$20
	LDY #0	; #rowstart 
clsloop:
	JSR lineclrY
	INY
	CPY TextWinBtm	; #rowstotal+1
	BNE clsloop
	JSR lineclrY
	LDX TextWinLeft
	STX TextX
	STX TextPosX
	LDY TextWinTop	; #rowstart
	STY TextY
	STY TextPosY
	RTS
			

lineclrY:			
; Löscht Zeile in Y
	LDX TextWinLeft		; Ende der Zeile
lineclrFromX:
	STY TextY
	DEX
	LDA #$20		; Leerzeichen
lineclrloop:	
	INX
	STX TextX
	STA TextWR
	CPX TextWinRight
	BNE lineclrloop
	RTS

LineCopyUp:
; kopiert Zeile Y in Zeile Y-1
	STY TextY
	LDX TextWinRight
LineCopyUploop:
	STX TextX
	LDA TextWR
	PHA
	LDA ColorP
	DEY
	STY TextY
	STA ColorP
	PLA
	STA TextWR
	INY
	STY TextY
	DEX
	CPX TextWinLeft	;#colstotal	; Ende der Zeile?
	BPL LineCopyUploop
	RTS

; Zeichen in A in Zeile X und Spalte Y schreiben, ohne Cursorposition zu verändern
WriteCharXY:
	STY TextY
	STX TextX
	STA TextWR		; Zeichen in GTEXT-Schreibregister
restoreTextXY:
	PHA
	LDA TextPosY
	STA TextY
	LDA TextPosX
	STA TextX
	PLA
	RTS
	
ReadCharXY:
	STY TextY
	STX TextX
	LDA TextWR		; Zeichen aus GTEXT-RAM
	JMP restoreTextXY
	
	
SetFullScreen:
;rowstart  = 2	; 
;rowstotal = 39	; 
;colstotal = 80	; 
	LDA #$00
	STA TextWinLeft
	STA TextPosX
	LDA #colstotal-1
	STA TextWinRight
	LDA #rowstart
	STA TextWinTop
	STA TextPosY
	LDA #rowstotal-1
	STA TextWinBtm
	
;	LDA colstotal		; in neuem main.bit nicht mehr nötig
;	STA TextCols	
	
	JMP restoreTextXY

; Byte in Acc vom FPGA-Modul SPI, von SerialCore oder OptoBusCore
; setzt Carry=1 wenn Byte empfangen, sonst Carry=0 und Acc=0

ReceiveByte:
	STY ytemp
; von AVRCOM- oder UART-IRQ im Buffer abgelegt
	LDY RxPtr	; prüfen, ob etwas empfangen wurde
	CPY iRxPtr
	BEQ ReceiveByteExitNone	; nix da
	INY
	STY RxPtr
	LDA RxBuf,Y

ReceiveByteOK:
	LDY ytemp
	CMP #0
	SEC
	RTS

ReceiveByteExitNone:
	LDY ytemp
ReceiveStringError:
	LDA #0
	CLC
	RTS



; Universelle String-Input-Routine, behandelt CR/LF und LabReqIgnoreChr
; als Ende-Zeichen
; Für LABINP-Antwort vom Modul setzt sie
; HashSignIdx	= $0716	; Position nach "#" in Ibuffs
; EqualSignIdx	= $0717 ; Position nach "=" in Ibuffs
; Setzt ein (von INPUT entferntes) <"> an den Ibuffs-Anfang $220

ReceiveString:
	LDA 	#10		; Timeout 0,15s
	STA 	TimeOut
	LDX	#0		; Pointer für Ibuffs
	STX	HashSignIdx
	STX	EqualSignIdx
	STX	ColonSignIdx
	LDA	#'"'		; String-Input erwünscht, also mit "-Anfang simulieren
	STA	Ibuffs
	STA	Srchc
	INX
ReceiveString1:
	LDA	#0
	STA	Ibuffs,X	; Mit Ende-Null vorbelegen
	LDA	TimeOut
	BEQ	ReceiveStringError
	JSR	ReceiveByte
	BCC	ReceiveString1
	CMP	#$0A		; evt. übrig von der letzten Antwort, ignorieren
	BEQ	ReceiveString1
	CMP 	#$0D		; CR?
	BEQ 	ReceiveStringEnded
	CMP 	LabReqIgnoreChr
	BEQ 	ReceiveStringRemaining
	CMP 	#'#'		; Startzeichen der Antwort?
	BNE 	ReceiveString2
	STX	HashSignIdx
	INC	HashSignIdx
ReceiveString2:
	CMP 	#':'		; Ergebnis der Antwort?
	BNE 	ReceiveString3
	STX	ColonSignIdx
	INC	ColonSignIdx
ReceiveString3:
	CMP 	#'='		; Ergebnis der Antwort?
	BNE 	ReceiveString4
	STX	EqualSignIdx
	INC	EqualSignIdx
ReceiveString4:
	CPX	#Ibuffe-Ibuffs	; compare character count with max
	BCS	ReceiveStringError	; exit if buffer full, Error!
	STA	Ibuffs,X	; else store in buffer
	INX
	BNE	ReceiveString1	; immer!
	BEQ	ReceiveStringError
	
ReceiveStringEnded:
	SEC
	RTS
	
ReceiveStringRemaining:
; Rest nach LabReqIgnoreChr abrufen (aber nicht speichern) bis CR kommt
	LDA	TimeOut
	BEQ	ReceiveStringError
	JSR	ReceiveByte
	BCC	ReceiveStringRemaining
	CMP 	#$0D		; CR?
	BNE	ReceiveStringRemaining
	LDX	#'X'-'0'		; "Extra Ignored (Rest of Line)"
	STX	LabErrFlags
	JMP 	ReceiveStringEnded


TickerDelay:	; Timer-Wert in Acc, 60 => 1s
	STA	TimeOut
TickerDelayLoop:
	LDA	TimeOut	; NMI-Timer
	BNE	TickerDelayLoop
	RTS
	


;############################################################################
;#                   OS-Routinen, Hilfsroutinen COM                         #
;############################################################################
	
	
; does BASIC Timeout error
AVRCOM_ERR
	LDX	#$1E			; error code $1E ("Timeout" error)
	JMP	Reset		; do error #X, then warm start
	
;Warten bis Antwort vom AVR (intern) eintrifft und bis Timeout nochmal versuchen	
WriteResponse:
	JSR	ReceiveString
	BCC	WriteResponseExit
	JSR	WriteIbuffS
	JMP	WriteResponse		; nochmal versuchen
WriteResponseExit:
	RTS
		
WriteIbuffS:
	LDY	#1
WriteIbuffSlp:
	LDA	IBuffS,Y		; Adresse des Strings +1 wg. "
	BEQ	WriteIbuffSExit
	JSR	WriteScreen
	INY
	BNE	WriteIbuffSlp
WriteIbuffSExit:
	JMP	Print_CR		; print CR/LF and return
	

; allg. Ausgabe an AVR

; Hilfsroutine zur Screen-Ausgabe eines Strings nach JSR WriteMsg
WriteMsg:		; Put Msg String Routine
	PLA		; Get the return address LSB from stack
	STA Cmdptr	; ..into w/s
	PLA		; Get the return address MSB from stack
	STA Cmdptr+1	; ..into w/s
WriteMsgChar:
	LDY #$0
	INC Cmdptr	; Point to the next byte of embedded text
	BNE WriteMsgNext
	INC Cmdptr+1	; Increment MSB text pointer if carried over
WriteMsgNext:
	LDA (Cmdptr),Y	; Get the next character of embedded text
	BMI WriteMsgExit; ..reached terminator - execute from here
	JSR WriteScreen	; Send character to Screen
	JMP WriteMsgChar; ..and go for the next character
WriteMsgExit:
	JMP (Cmdptr)	; Continue execution from the negative byte

; Hilfsroutine zur COM-Ausgabe eines Strings nach JSR PutMsg
SendMsg:		; Put Msg String Routine
	PLA		; Get the return address LSB from stack
	STA Cmdptr	; ..into w/s
	PLA		; Get the return address MSB from stack
	STA Cmdptr+1	; ..into w/s
SendMsgChar:
	LDY #$0
	INC Cmdptr	; Point to the next byte of embedded text
	BNE SendMsgNext
	INC Cmdptr+1	; Increment MSB text pointer if carried over
SendMsgNext:
	LDA (Cmdptr),Y	; Get the next character of embedded text
	BMI SendMsgExit	; ..reached terminator - execute from here
	JSR SendByte	; Send character to AVR
	JMP SendMsgChar	; ..and go for the next character
SendMsgExit:
	JMP (Cmdptr)	; Continue execution from the negative byte

	
SendScratchStr:		; 0-Terminated-String im scratch-Buffer an COM übermitteln
	LDX #0
SendScratchStrLoop:
	LDA scratch,x
	BEQ SendScratchStrExit
	JSR SendByte
	INX
	BNE SendScratchStrLoop
SendScratchStrExit:
	RTS

COMswitch:
	LDA COMCH
	STA COMCHsave
	LDA #0
	STA COMCH
LAB_FlushRx:			; Buffer leeren, benutzt nur Acc
	SEI
	STA 	UART1RxC	; UART-RxFIFO leeren
LAB_FlushRx0:
	LDA	UART1D
	BIT	UART1RxS
	BMI	LAB_FlushRx0
	LDA	#$00
	STA	LabReqIgnoreChr 
	STA 	iRxPtr		; Input Buffer leeren
	STA 	RxPtr
	LDA	#0
	STA	LabErrFlags	; Clear LABBUS Error
	CLI
	RTS

	
;############################################################################

	
	
ResponseAndExit:
	JSR WriteResponse
NoResponseAndExit:
	JSR LAB_FlushRx
	LDA COMCHsave
	STA COMCH
	LDA CurrBank
	STA Bank
	JMP LAB_WARM	; do EhBASIC warm start
	

Reboot:				; bei CTRL-ALT-DELETE
	JSR COMswitch
	JSR SendMsg	
	.ASCII $0D,"9:CFG=BASIC.INI",$0D ; 
	NOP
	JMP ResponseAndExit	; do EhBASIC warm start

	
TypeFile:
	;JMP Break	; ##############################
	JSR SendMsg
	.ASCII "9:TTF 67=",34 	; 
	NOP
	JSR SendScratchStr		; evaluated string
	JSR SendMsg	
	.ASCII 34,$0D
	NOP
	JMP NoResponseAndExit	; do EhBASIC warm start


;############################################################################
;############################################################################
;#        OS-Routinen, RST, IRQ-Aufbereitung und Initialisierung            #
;############################################################################
;############################################################################


Reset:
	SEI		; IRQ sperren bis IRQ-Routine ins RAM kopiert
	CLD		; clear decimal mode
	
	LDX #$FF	; empty stack
	TXS		; set the stack
	
	LDA	#colstotal
	STA	TextCols
		
	LDA	#<WriteAcc
	STA	WritejpL	; alten Write-Vektor wiederherstellen
	LDA	#>WriteAcc
	STA	WritejpH
	LDA	#0
	STA COMCH
	STA IRQena
	STA iRxPtr
	STA RxPtr
	STA KbdPtr
	STA iKbdPtr
	STA CapsFlg	; UpCase-Flag, $20=Basic, $00=Terminal
	STA GetbFlg
	STA Omode	; 0 wenn PRINT, $80 wenn LABOUT auf COM
	STA Gsmall
	STA GFrameC	; Fenster-Hintergrund
	STA 	scratch
	STA 	scratch+1
	LDA IRQack
	LDA IRQclr
	LDA CurrBank
	STA Bank
	STA AccessBank	; für PEEKs/POKEs
	STA	PS2sendStackPtr
	STA	MouseBufPtr
	STA	MouseStyle	; kein Zeiger
	
	LDA #$80	; FlowControl einschalten
	STA Tx0ACK

	STA GsizeX
	LDA #50		; Grafik-Fenster
	STA GstartX
	LDA #36		; Grafik-Fenster
	STA GstartY
	LDA #$60	; Grafik-Fenster
	STA GsizeY
	
	JSR ClearFullScreen
	LDA	#0
	STA	TextPosY
	JSR 	WriteMsg
	.DB "c't-Lab EhBASIC Bootloader #0.1 by cm 06/2010" ,$0d,$0a,$0d,$0a
	NOP
	
	CLI
; PS/2-Maus initialisieren	
	LDA	#$55
	STA	scratch
	STA	scratch+1
	
	STA	TimeOut
	LDA	#$FF		; PS/2 init
	STA	PS2sendStack+0
	LDA	#1
	STA 	PS2sendStackPtr	; immer zuletzt
	LDA	#30
	JSR	TickerDelay
	
	STA	MouseBufPtr	; Acc=0
	LDA	#$F2		; Mouse ID request
	STA	PS2sendStack+0
	LDA	#1
	STA 	PS2sendStackPtr	; immer zuletzt
	STA	MouseSync
	LDA	#30	
	STA	TimeOut
	JSR 	WriteMsg
	.ASCII "Searching for PS/2 device...",$0d,$0a ; 
	NOP

WaitMouse:
	LDA	TimeOut
	BEQ	WaitMouseTimeout
	LDA	MouseBufPtr	; Warte auf Maus-Initialisierung
	CMP	#2
	BCC	WaitMouse
	LDA 	#5	
	JSR	TickerDelay
	LDA	MouseBuf
	STA 	scratch
	LDA	MouseBuf+1
	STA 	scratch+1
	LDA	MouseBuf+2
	STA 	scratch+2
WaitMouseTimeout:	
	JSR 	COMswitch
	LDA 	#$0D
	JSR 	SendByte
	LDA 	#5
	JSR	TickerDelay
	JSR 	LAB_FlushRx
	LDA 	#$00
	LDA 	COMCHsave
	STA 	COMCH
	JSR 	LAB_FlushRx
	

               
	LDA	scratch+1
;	CMP	#$00
	BNE	NoMouse		; Mouse-ID=$00
	JSR 	WriteMsg
	.ASCII "Loading PS/2 mouse version",$0d,$0a ; 
	NOP
	JSR 	COMswitch
	JSR 	SendMsg
	.ASCII "9:AIS=0",$0D
	.ASCII "9:AIR=128",$0D	; Default-AutoIncRegister
	.ASCII "9:AIW=1",$0D
	.ASCII "9:AIM=0"	; Startadresse übermitteln, 45056 für $B000
	NOP
	JSR 	SendMsg
	.ASCII $0D,"9:BLD=ehbas_m.dat",$0D	; 
	NOP
EndlessLoop:
	JMP	EndlessLoop

NoMouse:
;	LDA	scratch+1
	CMP	#$AB		; Keyboard-ID
	BNE 	NoPS2device
	JSR 	WriteMsg
	.ASCII "Loading keyboard version",$0d,$0a ; 
	NOP
	JSR 	COMswitch
	JSR 	SendMsg
	.ASCII "9:AIS=0",$0D
	.ASCII "9:AIR=128",$0D	; Default-AutoIncRegister
	.ASCII "9:AIW=1",$0D
	.ASCII "9:AIM=0"	; Startadresse übermitteln, 45056 für $B000
	NOP
	JSR 	SendMsg
	.ASCII $0D,"9:BLD=ehbas_k.dat",$0D	; 
	NOP
	JMP EndlessLoop	; wait for .dat beeing loaded
	
NoPS2device:
	JSR 	WriteMsg
	.ASCII "No mouse/keyboard detected",$0d,$0a ; 
	.ASCII "Loading autostart version, runs AUTOSTART.BAS",$0d,$0a ; 
	NOP
	LDA 	#60
	JSR	TickerDelay
	JSR 	COMswitch
	JSR 	SendMsg
	.ASCII "9:AIS=0",$0D
	.ASCII "9:AIR=128",$0D	; Default-AutoIncRegister
	.ASCII "9:AIW=1",$0D
	.ASCII "9:AIM=0"	; Startadresse übermitteln, 45056 für $B000
	NOP
	JSR 	SendMsg
	.ASCII $0D,"9:BLD=ehbas_a.dat",$0D	; 
	NOP
	JMP EndlessLoop	; wait for .dat beeing loaded
	

;############################################################################
;#                            IRQ- und BRK-Handler                          #
;############################################################################
; BRK-Handler entfernt 06/2010

; CMs IRQ Handler: COM-, VS60Hz- und SPI-IRQ auswerten

IRQentry:
	PHA
	TYA	; PHY führt hier zu sporadischen Fehlern!
	PHA
	LDA IRQsrc	; HW-Interrupt-Quelle vorrangig
	AND #$0F	; ungültige ausblenden
	STA irqs	; retten	
; IRQs zuordnen: Bit 0 ist PS/2
IRQ_PS2:
	LSR 	irqs	; Saved IRQsrc
;	BEQ 	IRQexit	; sonst nix drin?	
	BCC 	IRQ_COM	; JMP auf IRQ_COM
		
; Maus ist im Stream Mode, sendet also selbsttätig Bewegungen
	LDA	MouseSync	; Inaktivitäts-Timer abgelaufen?
	BNE	IRQ_MouseSync_1
IRQ_MouseSync_0:
	LDA	#$00
	STA	MouseBufPtr	
IRQ_MouseSync_1:
	LDA	#2
	STA	MouseSync	; Timeout für Maus-Aktivität setzen
	
	LDY	MouseBufPtr
	CPY	#3	; Überlauf?	
	BEQ	IRQ_MouseSync_0	; wieder auf -1 + INY
	LDA	PS2code		; Rohdaten vom Port
	STA	MouseBuf,Y	; alter MouseBuf-Pointer
	INY
	STY	MouseBufPtr
; war Bit 1, also AVRCOM
IRQ_COM:
	LSR 	irqs	; Saved IRQsrc
	BCC	IRQ_UART
	LDA COMport	; COM-Byte von SPI eingetroffen
	BEQ IRQ_UART	; Null-byte, nix machen
	CMP #$06
	BNE IRQ_COM_store
	LDA #$80	; ACK feststellen, aber nicht speichern
	STA Tx0ACK
	
; Bit 2, also UART?
IRQ_UART:
IRQ_COM_store:
	LDY iRxPtr	; war AVRCOM oder UART
	INY		; Zeiger erhöhen, weil Byte eingetroffen
	STA RxBuf,Y	; in Eingangspuffer
	STY iRxPtr

		
IRQexit:
	LDY IRQack	; IRQsrc gelesen, FIFO nächsten Eintrag, falls vorhanden
	PLA
	TAY
	PLA
	RTI

; 60Hz Ticker NMI, reentrant zu IRQ
; PS2sendStackPtr	= $07E0	; Anzahl der PS/2-Bytes zum Gerät (max. 5)
; PS2sendStack = $07E8	; 5 Bytes an PS/2, wird von oben abgearbeitet

NMIentry:
	PHA
	TYA
	PHA
;	LDA NMIack	; NMI angenommen
	LDY	PS2sendStackPtr
	BEQ	NMI_PS2sent	; alles gesendet?
	DEY
	LDA	PS2sendStack,Y
	STA	PS2code		; hat 1 Frame Zeit zum Senden
	STY	PS2sendStackPtr
NMI_PS2sent:	
	LDA 	TimeOut	
	BEQ 	NMI_noDecTimer
	DEC 	TimeOut
NMI_noDecTimer:
	DEC 	Timer60	; war VSync
	LDA 	MouseSync	
	BEQ 	NMI_noDecMouseSync
	DEC	MouseSync
NMI_noDecMouseSync:
	PLA
	TAY
	PLA
	RTI

	               
; system vectors
	*= $FFFA
SysVec:
	.word	NMIentry	; NMI vector
	.word	Reset		; RESET vector
	.word	IRQentry	; IRQ vector


	.END
