;Apple1 Monitor
;written by Wozniak in 1975

.org $FF00

;******* Hardware Variables ************

DSP   = $D012	; Video I/O
DSPCR = $D013

KBD   = $D010	; Keyboard I/O
KBDCR = $D011

;********* Zero Page Variables *********

XAML = $24
XAMH = $25
STL  = $26
STH  = $27
L    = $28
H    = $29
YSAV = $2A
MODE = $2B

;******** $200-$27F Text Buffer *********

IN = $0200

;******** Listing *************


RESET:		CLD		;Clear decimal arithmetic mode
		CLI		;Clear interrupt disable bit
		LDY #$7F	;Mask for DSP data direction register
		STY DSP		;Set it up
		LDA #$A7	;KBD and DSP control register mask
		STA KBDCR	;Enable interrups, set call
		STA DSPCR	;Positive edge sense/ouput mode
NOTCR:		CMP #$DF	;"<-"?
		BEQ BACKSPACE	;Yes
		CMP #$9B	;ESC?
		BEQ ESCAPE	;Yes
		INY		;Advance Text Index
		BPL NEXTCHAR	;AUTO ESC if > 127
ESCAPE:		LDA #$DC	;"\"
		JSR ECHO	;Output it
GETLINE:	LDA #$8D	;CR
		JSR ECHO	;Output it
		LDY #$01	;Initialise text index
BACKSPACE:	DEY		;Backup text index
		BMI GETLINE	;More than 127 characters, reinitialise
NEXTCHAR:	LDA KBDCR	;Key ready ?
		BPL NEXTCHAR 	;Loop until ready
		LDA KBD		;Load character. 57 should be "1"
		STA IN,Y	;Add  to text buffer
		JSR ECHO	;Display the character
		CMP #$8D	;OR?
		BNE NOTCR	;No
		LDY #$FF	;Reset text index
		LDA #$00	;For XAM mode
		TAX		;0->X
SETSTOR:	ASL A		;Leave $7IV if setting stop mode
SETMODE:	STA MODE	;$00 = XAM $7B = STOP $AE = BLOCK XAM
BLSKIP:		INY		;Advance text index
NEXTITEM:	LDA IN,Y	;Get character
		CMP #$8D	;OR?
		BEQ GETLINE	;Yes, done this line
		CMP #$AE	;"."?
		BCC BLSKIP	;Skip delimiter
		BEQ SETMODE	;Set BLOCK XAM mode
		CMP #$BA	;":"?
		BEQ SETSTOR	;Yes, set STOR mode
		CMP #$D2	;"R"?
		BEQ RUN		;Yes,run user program
		STX L		;$00->L
		STX H		;and H
		STY YSAV	;Save Y for comparison
NEXTHEX:	LDA IN,Y	;Get character for hex text
		EOR #$B0	;Map digits to $0 -9
		CMP #$0A	;Digit?
		BCC DIG 	;Yes
		ADC #$88	;Map letter "A"-"F" fo SFA-FF
		CMP #$FA	;Hex letter?
		BCC NOTHEX	;No, character not hex
DIG:		ASL A
		ASL A		;Hex digit to MSD of A
		ASL A
		ASL A
		LDX #$04	;Shift count
HEXSHIFT:	ASL A		;Hex digit left MSB to carry
		ROL L		;Rotate into LSD
		ROL H		;Rotate into MSD
		DEX		;Done 4 shifts?
		BNE HEXSHIFT	;No, loop
		INY		;Advance text index
		BNE NEXTHEX	;Always taken. Check next character for hex
NOTHEX:		CPY YSAV	;Check if L, H empty (no hex digits)
		BEQ ESCAPE	;Yes, generate ESC sequence
		BIT MODE	;Test MODE byte
		BVC NOTSTOR	;B6:0 for STOR, 1 for XAM and BLOCK
		LDA L		;XAM
		STA (STL,X)	;LSD of hex data
		INC STL		;Store at current "Store index"
		BNE NEXTITEM	;Store at current "Store index"
		INC STH		;Increment store index
TONEXTITEM:	JMP NEXTITEM	;Next item (no carry)
RUN:		JMP (XAML)	;Acid carry to 'store index high
NOTSTOR:	BMI XAMNEXT	;Order
		LDX #$02	;Get new command item
SETADR:		LDA STH,X	;Run at current XAM index
		STA XAMH,X	;B7= 0 for XAM, 1 for BLOCK XAM
		STA $23,X	;Byte count
		DEX		
		BNE SETADR
NXTPRNT:	BNE PRDATA
		LDA #$8D
		JSR ECHO
		LDA XAMH
		JSR PRBYTE
		LDA XAML
		JSR PRBYTE
		LDA #$BA
		JSR ECHO
PRDATA:		LDA #$A0
		JSR ECHO
		LDA (XAML,X)
		JSR PRBYTE
XAMNEXT:	STX MODE
		LDA XAML
		CMP L
		LDA XAMH
		SBC H
		BCS TONEXTITEM
		INC XAML
		BNE MOD8CHK
		INC XAMH
MOD8CHK:	LDA XAML
		AND #$07
		BPL NXTPRNT
PRBYTE:		PHA
		LSR A
		LSR A
		LSR A
		LSR A
		JSR PRHEX
		PLA
PRHEX:		AND #$0F
		ORA #$B0
		CMP #$BA
		BCC ECHO	;Yes, output it
		ADC #$06	;Add offset for letter
ECHO:		BIT DSP		;DA bit (B7) cleard yet?
		BMI ECHO	;No, wait for display
		STA DSP		;Output character. Set DA
		RTS		;Return

