PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
				.LIST OFF	
				.OP	65C02
				.OR $2000
				.TF /A2OSX.BOOT/DRV/CONSOLE.DRV
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/IO.I
*--------------------------------------
CURSOR.BLINK.SPEED	.EQ 8
ESCSEQ.MAXLEN	.EQ 16
*--------------------------------------
ZPBaseL1		.EQ ZPDRV
ZPBaseL2		.EQ ZPDRV+2
ZPTmpByte		.EQ ZPDRV+4
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp Dev.Detect			cld,jmp abs=DRV
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					DRV Layout Version 1
				.DA 0
				.DA CS.END-CS.START			Code Length
				.DA DEV.HEADER-CS.START		Device Header Offset
				.DA DRV.CS.START-CS.START	Driver Code Offset
				.DA DRV.CS.END-DRV.CS.START	Drv Code Length
*--------------------------------------
* Relocation Table
*--------------------------------------
L.MSG.DETECT	.DA MSG.DETECT
				.DA 0					End Of Reloc Table
*--------------------------------------
Dev.Detect		>LDYA L.MSG.DETECT
				>SYSCALL SYS.PrintFYA

				clc
				rts
CS.END
MSG.DETECT		>CSTRING "Apple IIe/IIc 80 Col Driver.\n"
*--------------------------------------
*			Device Header (16 Bytes)
*--------------------------------------
DEV.HEADER		cld
				jmp (DRV.CS.START,x)
				.HS 00					DevID
				.DA #S.DEV.F.EVENT+S.DEV.F.COUT+S.DEV.F.CHAR
				>PSTRING "CON"			NAME
				.HS 00					NAME must Be 5 bytes long
				.HS 00
				.HS 00.00.00.00
*--------------------------------------
*			Driver Code
*--------------------------------------
DRV.CS.START	.DA OPEN
				.DA GETEVENT
				.DA COUT
				.DA CLOSE
				.DA GETINFO
				.DA IRQ
				.DA SELECT
L.DEVINFO		.DA DEVINFO
*--------------------------------------
J.CtrlChars		.DA BS					8
				.DA LF					10
				.DA	HOME				12
				.DA CROUT				13
				.DA ESC					27
*--------------------------------------
J.EscCodes		.DA Scroll.Dn			D
				.DA Scroll.Up			M
				.DA RESET				c
*--------------------------------------
J.EscSequences	.DA Esc.DispAttr		m
				.DA Esc.Query			n
				.DA Esc.Scroll			r
				.DA Esc.Erase			K
				.DA	Esc.Home			H
				.DA 0					end of relocation
*--------------------------------------
OPEN			stz CURON

				stz bEscMode
				stz bEscModeCSI
				
				stz OutPtr
				stz OutCnt

				ldy #S.DEV.ID
				lda (pDev),y
				sta A2osX.SCRNDEVS

				jsr SELECT
				lda #1
				sta A2osX.ASCREEN
				jsr RESET
				jsr HOME
				clc
				rts
*--------------------------------------
GETEVENT		jsr Char.Out.Get
				bcc .7					no char in output buffer...
				
				lda A2osX.ASCREEN
				cmp #1					is CON active?
				bne .9					no....exit
				
				lda A2osX.TIMER16
				and #CURSOR.BLINK.SPEED
				eor CURON
				beq .1
				jsr CURBLNK

.1				lda	OPENAPPLE
				bmi .9					Open apple key, not for us...

				lda KBD
				bpl .9
				sta KBDSTROBE

				and #$7F
				
				ldx KeyRemapped
.2				cmp KeyRemapped,x
				beq .3
				dex 
				bne .2
				bra .7
				
.3				lda KeyRemappedIdx,x
				tay
				
.4				lda KeyRemappedTbl,y
				beq .6
				jsr Char.Out.Put
				iny
				bra .4
	
.6				jsr Char.Out.Get				
				
.7				ldy #S.EVT.DATALO
				sta (pEvent),y
				iny					S.EVT.DATAHI
				lda #0
				sta (pEvent),y
				lda #S.EVT.F.KEY
				sta (pEvent)
			
.8				clc
				rts
				
.9				lda	#0					Error = no event
				sec
				rts
*--------------------------------------
COUT			bit bEscMode
				bmi COUT.EscMode
				
				pha
				jsr CUROFF
				pla
				cmp #32
				bcc COUT.Ctrl

				ora INVFLG
				ldx CH
				ldy CV
				jsr SetCharAtXY
				jmp FSOUT
*--------------------------------------
SELECT			sta SETTEXT
				sta SETALTCHAR
				sta SET80DISP
				sta CLR80STORE
				sta CLRPAGE2
				clc
				rts
*--------------------------------------
COUT.Ctrl		ldy #0
				ldx #0

.2				iny
				cmp CtrlChars,y
				beq .3
				inx
				inx
				cpy CtrlChars
				bne .2
				clc
				rts
				
.3				jmp (J.CtrlChars,x)
*--------------------------------------
COUT.EscMode	bit bEscModeCSI
				bmi COUT.EscModeCSI
				cmp #'['
				bne .1
								
				dec bEscModeCSI
				stz EscSeq
				clc
				rts
				
.1				stz bEscMode
				
				ldy #0
				ldx #0

.2				iny
				cmp EscCodes,y
				beq .3
				inx
				inx
				cpy EscCodes
				bne .2
				clc
				rts
				
.3				jmp (J.EscCodes,x)
*--------------------------------------
COUT.EscModeCSI	inc EscSeq
				ldx EscSeq
				sta EscSeq,x
				cmp #64					End of Seq ?
				bcs COUT.ExecEscSeq
				cpx #ESCSEQ.MAXLEN		too long?
				bne .1
				stz bEscModeCSI
				stz bEscMode
.1				clc
				rts

COUT.ExecEscSeq	stz EscSeqParamCnt
				stz bEscSeqInNum
				
				ldx #0					EscSeq Ptr

.10				stz EscSeqParamTmp
				stz EscSeqParamTmp+1
				
.1				inx
				lda EscSeq,x
				jsr IsDigit 
				bcs .2
				
				dec bEscSeqInNum
				and #$0F
				pha
				lda EscSeqParamTmp
				ldy EscSeqParamTmp+1
				asl EscSeqParamTmp	    param=param*10
				rol EscSeqParamTmp+1
				asl EscSeqParamTmp
				rol EscSeqParamTmp+1
				clc
				adc EscSeqParamTmp
				sta EscSeqParamTmp
				tya
				adc EscSeqParamTmp+1
				sta EscSeqParamTmp+1
				asl EscSeqParamTmp
				rol EscSeqParamTmp+1

				pla
				clc
				adc EscSeqParamTmp
				sta EscSeqParamTmp
				bcc .1
				inc EscSeqParamTmp+1
				bra .1
				
.2				bit bEscSeqInNum
				bpl .3
				
				stz bEscSeqInNum
				lda #255
				ldy EscSeqParamTmp+1
				bne .21
				
				lda EscSeqParamTmp
.21				ldy EscSeqParamCnt
				sta EscSeqParam,y
				inc EscSeqParamCnt
				
.3				lda EscSeq,x
				cmp #';'
				beq .10
				
				stz bEscModeCSI
				stz bEscMode
				
				ldy #0
				ldx #0

.4				iny
				cmp EscSeqCmds,y
				beq .5
				inx
				inx
				cpy EscSeqCmds
				bne .4
				clc
				rts
				
.5				jmp (J.EscSequences,x)
*--------------------------------------
CLOSE			stz A2osX.SCRNDEVS
				clc
				rts
*--------------------------------------
GETINFO			>LDYA L.DEVINFO
IRQ				clc
				rts
*--------------------------------------
*				PRIVATE
*--------------------------------------
RESET			lda #0
				sta SCROLLTOP
				lda #23
				sta SCROLLBOT
*--------------------------------------
RESETATTR		lda #$80
				sta INVFLG
				clc
				rts
*--------------------------------------
ESC				lda #$80
				sta bEscMode
				clc
				rts
*--------------------------------------
BS 				ldx CH
				beq .1
				dec CH
				bra .3
				
.1				ldy CV
				bne .2
				clc
				rts
				
.2				lda #79
				sta CH
				dec CV	
				
.3				lda #$20
				ora INVFLG
				ldx CH
				ldy CV
				jmp SetCharAtXY
*--------------------------------------
HOME			stz CH
				stz CV

				ldx #23
				
.1				lda BASEL,x
				sta ZPBaseL1
				lda BASEH,x
				sta ZPBaseL1+1
				
				lda #' '
				ora INVFLG

				sta SETWRITEAUX
				
				ldy #39
.2				sta (ZPBaseL1),y		
				dey
				bpl .2
				
				sta CLRWRITEAUX

				ldy #39
.3				sta (ZPBaseL1),y		
				dey
				bpl .3

				dex
				bpl .1
				
				clc
				rts
*--------------------------------------
FSOUT			ldx CH
				cpx #79
				beq CROUT1
				inc CH
				clc
				rts				
*--------------------------------------
CROUT			jsr CLREOL
				stz CH
				clc
				rts
CROUT1			stz CH
LF				ldy CV
				cpy #23
				beq SCROLL.UP
				inc CV
				clc
				rts
*--------------------------------------
SCROLL.UP		ldx SCROLLTOP
				
.1				lda BASEL,x
				sta ZPBaseL1
				lda BASEH,x
				sta ZPBaseL1+1
				inx
				lda BASEL,x
				sta ZPBaseL2
				lda BASEH,x
				sta ZPBaseL2+1
				
				ldy #39
				sta SETWRITEAUX
				sta SETREADAUX
				
.2				lda (ZPBaseL2),y
				sta (ZPBaseL1),y 
				dey
				bpl .2

				ldy #39
				sta CLRWRITEAUX
				sta CLRREADAUX
				
.3				lda (ZPBaseL2),y
				sta (ZPBaseL1),y 
				dey
				bpl .3

				cpx SCROLLBOT
				bne .1
*--------------------------------------
CLREOL			ldx CH
				ldy #80
				bra CLR
				
CLRLINE			ldx #0
				ldy #80
				bra CLR
				
CLRSOL			ldx #0
				ldy CH	
				
CLR				sty ZPTmpByte
.1				phx
				lda #$20
				ora INVFLG
				ldy CV
				jsr SetCharAtXY
				plx
				inx
				cpx ZPTmpByte
				bne .1
				clc
				rts
*--------------------------------------
SCROLL.DN		ldx SCROLLBOT
				
.1				lda BASEL,x
				sta ZPBaseL1
				lda BASEH,x
				sta ZPBaseL1+1
				dex
				lda BASEL,x
				sta ZPBaseL2
				lda BASEH,x
				sta ZPBaseL2+1
				
				ldy #39
				sta SETWRITEAUX
				sta SETREADAUX
				
.2				lda (ZPBaseL2),y
				sta (ZPBaseL1),y 
				dey
				bpl .2

				ldy #39
				sta CLRWRITEAUX
				sta CLRREADAUX
				
.3				lda (ZPBaseL2),y
				sta (ZPBaseL1),y 
				dey
				bpl .3

				cpx SCROLLTOP
				bne .1
				
				
				
				clc
				rts
*--------------------------------------
Esc.DispAttr	ldx EscSeqParamCnt
				beq .8
				
.1				lda EscSeqParam-1,x
				bne .2
				jsr RESETATTR
				bra .7
				
.2				cmp #7
				bne .8
				stz INVFLG
				
.7				dex
				bne .1
	
.8				clc
				rts
*--------------------------------------
Esc.Query		ldx EscSeqParamCnt
				beq .8
				dex
				bne .8

				lda EscSeqParam
				cmp #6
				bne .8
				
				lda #$1B
				jsr Char.Out.Put
				lda #$5B
				jsr Char.Out.Put
				lda CV
				inc
				jsr Decimal.Out
				lda #';'
				jsr Char.Out.Put
				lda CH
				inc
				jsr Decimal.Out 
				lda #'R'
				jsr Char.Out.Put
				
.8				clc
				rts
*--------------------------------------
Esc.Scroll		ldx EscSeqParamCnt
				bne .1
				
				lda #0
				ldy #23
				bra .8
				
.1				cpx #2
				bne .9
				
				lda EscSeqParam
				dec
				ldy EscSeqParam+1
				dey
				
.8				sta SCROLLTOP
				sty SCROLLBOT
.9				clc
				rts
*--------------------------------------
Esc.Erase		ldx EscSeqParamCnt

				bne .1
				jmp CLREOL
				
.1				lda EscSeqParam
				cmp #1
				bne .2
				jmp CLRSOL

.2				cmp #2
				bne .9
				jmp CLRLINE

.9				clc
				rts
*--------------------------------------
Esc.Home		ldx EscSeqParamCnt
				bne .1
				stz CH
				stz CV
				clc
				rts
				
.1				ldx #1
				lda EscSeqParam
				beq .2
				
				ldx #24
				cmp #24
				bcs .2
				
				tax
				
.2				dex
				stx CV
				
				dec EscSeqParamCnt
				beq .8
				
				ldx #1
				lda EscSeqParam+1
				beq .3
				
				ldx #80
				cmp #80
				
				bcs .3
				
				tax
				
.3				dex
				stx CH
				
.8				clc
				rts
*--------------------------------------
CUROFF			lda CURON
				beq	CUREXIT.RTS
				
CURBLNK			lda A2osX.ASCREEN
				cmp #1
				beq CURBLNK1
				
				lda CURON
				bne	CURBLNK.OFF
				rts						do not Light if screen is not active
				
CURBLNK1		lda CURON
				bne CURBLNK.OFF
				ldx CH
				ldy CV
				jsr GetCharAtXY
				sta CURCHAR
				and #$80
				ldx CH
				ldy CV
				eor #" "
				jsr SetCharAtXY
				bra CUREXIT
				
CURBLNK.OFF		ldx CH
				ldy CV
				lda CURCHAR
				jsr SetCharAtXY

CUREXIT			lda CURON
				eor #CURSOR.BLINK.SPEED
				sta CURON
CUREXIT.RTS		rts
*--------------------------------------
SetCharAtXY		cmp #$40
				bcc .10
				cmp #$5F
				bcs .10
				and #$3F
				
.10				pha
				txa
				lsr

				bcs .1
				sta SETWRITEAUX
				
.1				clc
				adc BASEL,y
				sta ZPBaseL1
				lda BASEH,y
				sta ZPBaseL1+1

				pla
				sta (ZPBaseL1)
				sta CLRWRITEAUX
				rts	
*--------------------------------------
GetCharAtXY		txa
				lsr

				bcs .1
				sta SETREADAUX
				
.1				clc
				adc BASEL,y
				sta ZPBaseL1
				lda BASEH,y
				sta ZPBaseL1+1

				lda (ZPBaseL1)
				sta CLRREADAUX
				rts	
*--------------------------------------
IsDigit			cmp #'0'
				bcc .9
				cmp #'9'+1
				rts					cc if ok, cs if not
.9				sec
				rts
*--------------------------------------
Decimal.Out		stz DecimalBuffer
				stz DecimalBuffer+1
				
				ldx #8
				sed
				
				tay
				
.1				tya
				asl
				tay
				lda DecimalBuffer
				adc DecimalBuffer
				sta DecimalBuffer
				lda DecimalBuffer+1
				adc DecimalBuffer+1
				sta DecimalBuffer+1
				dex
				bne .1
				cld
				
				stz bDecimal0Out
				lda DecimalBuffer+1
				and #$0f
				beq .2
				ora #$30
				dec bDecimal0Out
				jsr Char.Out.Put
				
.2				lda DecimalBuffer
				lsr
				lsr
				lsr
				lsr
				bne .3
				bit bDecimal0Out
				bpl .4
.3				ora #$30
				jsr Char.Out.Put
.4				lda DecimalBuffer
				and #$0f
				ora #$30
*--------------------------------------
Char.Out.Put	pha
				lda OutPtr
				clc
				adc OutCnt
				and #$0f
				tax
				pla
				sta OutBuffer,x
				inc OutCnt
				rts
*--------------------------------------
Char.Out.Get	sec
				lda OutCnt
				beq .9
				dec OutCnt
				ldx OutPtr
				lda OutBuffer,x
				pha
				txa
				inc
				and #$0f
				sta OutPtr
				pla
				clc
.9				rts				
*--------------------------------------
DRV.CS.END
EscCodes		>PSTRING "DMc" 
EscSeqCmds		>PSTRING "mnrKH"
BASEL			.HS	00.80.00.80.00.80.00.80.28.A8.28.A8.28.A8.28.A8.50.D0.50.D0.50.D0.50.D0
BASEH			.HS	04.04.05.05.06.06.07.07.04.04.05.05.06.06.07.07.04.04.05.05.06.06.07.07
CH				.BS 1
CV				.BS 1
INVFLG			.BS 1
SCROLLTOP		.BS 1
SCROLLBOT		.BS 1
CURON			.BS 1
CURCHAR			.BS 1
OutBuffer		.BS 16
OutPtr			.BS 1
OutCnt			.BS 1
DecimalBuffer	.BS 2
bDecimal0Out	.BS 1
*--------------------------------------
KeyRemapped		.HS 05080A0B0D15		L,D,U,CR,R
KeyRemappedIdx	.HS 050004080C0F
KeyRemappedTbl	.EQ *
KeyRemappedLEFT	.HS 1B5B4400			esc[D
KeyRemappedDOWN	.HS 1B5B4200			esc[B
KeyRemappedUP	.HS 1B5B4100			esc[A
KeyRemappedCR	.HS 0D0A00				crlf
KeyRemappedRGHT	.HS 1B5B4300			esc[C
*--------------------------------------
CtrlChars		.HS 05080A0C0D1B
bEscMode		.BS 1
bEscModeCSI		.BS 1
bEscSeqInNum	.BS 1
EscSeq			.BS ESCSEQ.MAXLEN+1
EscSeqParamTmp	.BS 2
EscSeqParamCnt	.BS 1
EscSeqParam		.BS 4
*--------------------------------------
DEVINFO			.DA #S.DEVINFO.TYPE.CHAR
*--------------------------------------
MAN
SAVE DRV/CONSOLE.DRV.S
ASM
