--- /dev/null
+;
+; Groepaz/Hitmen, 12.10.2015
+;
+; character set for use with the soft80 implementation
+;
+
+; the format of the data follows the following layout:
+;
+; - to avoid unnecessary petscii->screencode conversions, the order of the
+; individual characters is different to the C64 ROM charset:
+; - $00 - $1f screencodes $60 - $7f (petscii codes $a0 - $bf)
+; - $20 - $3f screencodes $20 - $3f (petscii codes $20 - $3f)
+; - $40 - $5f screencodes $00 - $1f (petscii codes $40 - $5f)
+; - $60 - $7f screencodes $40 - $5f (petscii codes $60 - $7f)
+; - only 128 characters are defined here, the soft80 implementation will invert
+; the graphics data for inverted display on the fly.
+; - since the charset is 4 by 8 pixels, only the lower 4bit of each byte is
+; used. the upper bits have to be 0.
+; - finally the lower 4bits are "inverted", ie a space character is represented
+; as $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
+;
+; the graphics data is arranged differently to normal C64 charsets for speed,
+; first comes the first row of all characters, then the second row in the next
+; block, etc. like this:
+;
+; +000 ....xxxx ......xx ....xxxx ........
+; +080 ....xxxx ......xx ....xxxx ....xxxx
+; +100 ....xxxx ......xx ....xxxx ....xxxx
+; +180 ....x..x ......xx ....xxxx ....xxxx
+; +200 ....x..x ......xx ........ ....xxxx
+; +280 ....xxxx ......xx ........ ....xxxx
+; +300 ....xxxx ......xx ........ ....xxxx
+; +380 ....xxxx ......xx ........ ....xxxx
+; [...]
+; +040 ....x.xx ....xxxx ....xxxx ....xxxx
+; +0c0 .....x.x ....xxxx .....xxx ....xxxx
+; +140 .......x ....x.xx .....xxx ....x..x
+; +1c0 .......x ....xx.x ......xx .....xxx
+; +240 .....xxx ....x..x .....x.x .....xxx
+; +2c0 .....x.x .....x.x .....x.x .....xxx
+; +340 ....x.xx ....x..x ......xx ....x..x
+; +3c0 ....xxxx ....xxxx ....xxxx ....xxxx
+
+ .export soft80_charset
+
+ .segment "INIT"
+soft80_charset:
+ .byte $0f,$03,$0f,$00,$0f,$07,$05,$0e
+ .byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f
+ .byte $0f,$0b,$0f,$0b,$07,$07,$0e,$00
+ .byte $00,$0f,$0e,$0f,$0c,$0b,$03,$03
+ .byte $0f,$0b,$05,$05,$0b,$05,$0b,$0b
+ .byte $0d,$07,$0f,$0f,$0f,$0f,$0f,$0d
+ .byte $0b,$0b,$0b,$0b,$05,$01,$0b,$01
+ .byte $0b,$0b,$0f,$0f,$0d,$0f,$07,$0b
+ .byte $0b,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$09,$07,$03,$0b,$0f
+ .byte $0f,$0b,$03,$0b,$03,$01,$01,$0b
+ .byte $05,$01,$09,$05,$07,$05,$05,$0b
+ .byte $03,$0b,$03,$0b,$01,$05,$05,$05
+ .byte $05,$05,$01,$0b,$07,$0b,$0f,$0a
+
+ .byte $0f,$03,$0f,$0f,$0f,$07,$05,$0e
+ .byte $0f,$0a,$0e,$0b,$0f,$0b,$0f,$0f
+ .byte $0f,$0b,$0f,$0b,$07,$07,$0e,$00
+ .byte $00,$0f,$0e,$0f,$0c,$0b,$03,$03
+ .byte $0f,$0b,$05,$05,$09,$05,$05,$0b
+ .byte $0b,$0b,$05,$0b,$0f,$0f,$0f,$0d
+ .byte $05,$0b,$05,$05,$05,$07,$05,$05
+ .byte $05,$05,$0f,$0f,$0b,$0f,$0b,$05
+ .byte $05,$0f,$07,$0f,$0d,$0f,$09,$0f
+ .byte $07,$0b,$0d,$07,$03,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0b,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0b,$07,$0b,$0b,$0b
+ .byte $0f,$0b,$05,$05,$05,$07,$07,$05
+ .byte $05,$0b,$0d,$05,$07,$01,$01,$05
+ .byte $05,$05,$05,$05,$0b,$05,$05,$05
+ .byte $05,$05,$0d,$0b,$07,$0b,$0f,$0a
+
+ .byte $0f,$03,$0f,$0f,$0f,$07,$0a,$0e
+ .byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f
+ .byte $0f,$0b,$0f,$0b,$07,$07,$0e,$0f
+ .byte $00,$0f,$0d,$0f,$0c,$0b,$03,$03
+ .byte $0f,$0b,$05,$00,$07,$0d,$0b,$07
+ .byte $0b,$0b,$0b,$0b,$0f,$0f,$0f,$0b
+ .byte $01,$03,$0d,$0d,$05,$03,$07,$0d
+ .byte $05,$05,$0b,$0b,$0b,$08,$0b,$0d
+ .byte $01,$0b,$07,$09,$0d,$0b,$0b,$09
+ .byte $07,$0f,$0f,$07,$0b,$05,$03,$0b
+ .byte $03,$09,$03,$09,$01,$05,$05,$05
+ .byte $05,$05,$01,$0b,$0b,$0b,$05,$0b
+ .byte $0f,$05,$05,$07,$05,$07,$07,$07
+ .byte $05,$0b,$0d,$03,$07,$01,$01,$05
+ .byte $05,$05,$05,$07,$0b,$05,$05,$05
+ .byte $0b,$05,$0b,$0b,$0b,$0b,$0a,$05
+
+ .byte $09,$03,$0f,$0f,$0f,$07,$0a,$0e
+ .byte $0f,$0a,$0e,$08,$0f,$08,$03,$0f
+ .byte $08,$00,$00,$03,$07,$07,$0e,$0f
+ .byte $0f,$0f,$05,$0f,$0c,$03,$03,$03
+ .byte $0f,$0b,$0f,$05,$0b,$0b,$0b,$0f
+ .byte $0b,$0b,$01,$01,$0f,$01,$0f,$0b
+ .byte $05,$0b,$0b,$0b,$01,$0d,$03,$0b
+ .byte $0b,$09,$0f,$0f,$07,$0f,$0d,$0b
+ .byte $01,$0d,$03,$07,$09,$05,$01,$05
+ .byte $03,$03,$0d,$05,$0b,$01,$05,$05
+ .byte $05,$05,$05,$07,$0b,$05,$05,$05
+ .byte $05,$05,$0d,$0b,$0b,$0b,$05,$00
+ .byte $00,$01,$03,$07,$05,$03,$03,$01
+ .byte $01,$0b,$0d,$03,$07,$05,$01,$05
+ .byte $03,$05,$03,$0b,$0b,$05,$05,$01
+ .byte $0b,$0b,$0b,$00,$0b,$0b,$05,$05
+
+ .byte $09,$03,$00,$0f,$0f,$07,$05,$0e
+ .byte $05,$05,$0e,$08,$0c,$08,$03,$0f
+ .byte $08,$00,$00,$03,$07,$07,$0e,$0f
+ .byte $0f,$0f,$03,$03,$0f,$03,$0f,$0c
+ .byte $0f,$0f,$0f,$00,$0d,$07,$04,$0f
+ .byte $0b,$0b,$0b,$0b,$0f,$0f,$0f,$0b
+ .byte $05,$0b,$07,$0d,$0d,$0d,$05,$0b
+ .byte $05,$0d,$0f,$0f,$0b,$08,$0b,$0b
+ .byte $07,$09,$05,$07,$05,$01,$0b,$05
+ .byte $05,$0b,$0d,$03,$0b,$01,$05,$05
+ .byte $05,$05,$07,$0b,$0b,$05,$05,$01
+ .byte $0b,$05,$0b,$0b,$0b,$0b,$0f,$00
+ .byte $00,$05,$05,$07,$05,$07,$07,$05
+ .byte $05,$0b,$0d,$03,$07,$05,$01,$05
+ .byte $07,$05,$03,$0d,$0b,$05,$05,$01
+ .byte $0b,$0b,$0b,$00,$07,$0b,$05,$0a
+
+ .byte $0f,$03,$00,$0f,$0f,$07,$05,$0e
+ .byte $05,$0a,$0e,$0b,$0c,$0f,$0b,$0f
+ .byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
+ .byte $0f,$00,$03,$03,$0f,$0f,$0f,$0c
+ .byte $0f,$0f,$0f,$05,$03,$05,$05,$0f
+ .byte $0b,$0b,$05,$0b,$0b,$0f,$0b,$07
+ .byte $05,$0b,$07,$05,$0d,$05,$05,$0b
+ .byte $05,$05,$0b,$0b,$0b,$0f,$0b,$0f
+ .byte $05,$05,$05,$07,$05,$07,$0b,$09
+ .byte $05,$0b,$0d,$05,$0b,$05,$05,$05
+ .byte $03,$09,$07,$0d,$0b,$05,$0b,$01
+ .byte $05,$09,$07,$0b,$0d,$0b,$0f,$0b
+ .byte $0f,$05,$05,$05,$05,$07,$07,$05
+ .byte $05,$0b,$05,$05,$07,$05,$05,$05
+ .byte $07,$0b,$05,$05,$0b,$05,$0b,$05
+ .byte $05,$0b,$07,$0b,$07,$0b,$05,$0a
+
+ .byte $0f,$03,$00,$0f,$0f,$07,$0a,$0e
+ .byte $0a,$05,$0e,$0b,$0c,$0f,$0b,$00
+ .byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
+ .byte $0f,$00,$07,$03,$0f,$0f,$0f,$0c
+ .byte $0f,$0b,$0f,$05,$0b,$05,$08,$0f
+ .byte $0d,$07,$0f,$0f,$0b,$0f,$0b,$07
+ .byte $0b,$01,$01,$0b,$0d,$0b,$0b,$0b
+ .byte $0b,$0b,$0f,$0b,$0d,$0f,$07,$0b
+ .byte $0b,$09,$03,$09,$09,$09,$0b,$0d
+ .byte $05,$01,$0d,$05,$01,$05,$05,$0b
+ .byte $07,$0d,$07,$03,$0d,$09,$0b,$05
+ .byte $05,$0d,$01,$09,$0d,$03,$0f,$0b
+ .byte $0f,$05,$03,$0b,$03,$01,$07,$0b
+ .byte $05,$01,$0b,$05,$01,$05,$05,$0b
+ .byte $07,$0d,$05,$0b,$0b,$0b,$0b,$05
+ .byte $05,$0b,$01,$0b,$0b,$0b,$05,$05
+
+ .byte $0f,$03,$00,$0f,$00,$07,$0a,$0e
+ .byte $0a,$0a,$0e,$0b,$0c,$0f,$0b,$00
+ .byte $0b,$0f,$0b,$0b,$07,$07,$0e,$0f
+ .byte $0f,$00,$0f,$03,$0f,$0f,$0f,$0c
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$07,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$07,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$03
+ .byte $0f,$0f,$03,$0f,$0f,$0f,$0f,$0f
+ .byte $07,$0d,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$03,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ .byte $0f,$0f,$0f,$0b,$0b,$0b,$0f,$05
--- /dev/null
+;
+; Groepaz/Hitmen, 11.10.2015
+;
+; void cputcxy (unsigned char x, unsigned char y, char c);
+; void cputc (char c);
+;
+
+ .export soft80_cputcxy, soft80_cputc
+ .export soft80_cputdirect, soft80_putchar
+ .export soft80_newline, soft80_plot
+ .export soft80_checkchar
+
+ .import popa, _gotoxy
+
+ .import soft80_kplot
+ .import soft80_internal_bgcolor, soft80_internal_cellcolor
+ .import soft80_internal_cursorxlsb
+
+ .importzp tmp4,tmp3
+
+ .include "c64.inc"
+ .include "soft80.inc"
+
+soft80_cputcxy:
+ pha ; Save C
+ jsr popa ; Get Y
+ jsr _gotoxy ; Set cursor, drop x
+ pla ; Restore C
+
+; Plot a character - also used as internal function
+
+soft80_cputc:
+ cmp #$0A ; CR?
+ bne L1
+
+ lda #0
+ sta CURS_X
+
+ ; Set cursor position, calculate RAM pointers
+soft80_plot:
+ ldx CURS_Y
+ ldy CURS_X
+ clc
+ jmp soft80_kplot ; Set the new cursor
+
+L1: cmp #$0D ; LF?
+ beq soft80_newline ; Recalculate pointers
+
+ ; shortcut for codes < $80 ... codes $20-$7f can be printed directly,
+ ; codes $00-$1f are control codes which are not printable and thus may
+ ; give undefined result.
+ tay
+ bpl @L10
+
+ ; codes $80-$ff must get converted like this:
+ ; $80-$9f -> dont care (control codes)
+ ; $a0-$bf -> $00-$1f
+ ; $c0-$df -> $60-$7f
+ ; $e0-$ff -> $00-$1f
+
+ ora #%01000000 ; $40
+ clc
+ adc #%00100000 ; $20
+ and #%01111111 ; $7f
+@L10:
+
+ ; entry point for direct output of a character. the value passed in
+ ; akku must match the offset in the charset.
+ ; - the following may not modify tmp1
+soft80_cputdirect:
+ jsr soft80_putchar ; Write the character to the screen
+
+ ; Advance cursor position
+ iny ; contains CURS_X
+ cpy #charsperline
+ beq @L3
+
+ sty CURS_X
+ tya
+ and #$01
+ sta soft80_internal_cursorxlsb
+ bne @L5
+
+ lda SCREEN_PTR
+ clc
+ adc #8
+ sta SCREEN_PTR
+ bcc @L4
+ inc SCREEN_PTR+1
+@L4:
+ inc CRAM_PTR
+ bne @L5
+ inc CRAM_PTR+1
+@L5:
+ rts
+@L3:
+ inc CURS_Y ; new line
+ ldy #0 ; + cr
+ sty CURS_X
+ jmp soft80_plot
+
+ ; - the following may not modify tmp1
+soft80_newline:
+
+ lda SCREEN_PTR
+ clc
+ adc #<(40*8)
+ sta SCREEN_PTR
+
+ lda SCREEN_PTR+1
+ adc #>(40*8)
+ sta SCREEN_PTR+1
+
+ lda CRAM_PTR
+ clc
+ adc #40
+ sta CRAM_PTR
+ bcc @L5
+ inc CRAM_PTR+1
+@L5:
+ inc CURS_Y
+ rts
+
+;-------------------------------------------------------------------------------
+; All following code belongs to the character output to bitmap
+;
+; this stuff is going to be used a lot so we unroll it a bit for speed
+;-------------------------------------------------------------------------------
+
+.if SOFT80FASTSPACE = 1
+
+; output inverted space (odd)
+draw_spaceinvers_odd:
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$f0
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+; output inverted space (general entry point)
+; in: y must be $00
+draw_spaceinvers:
+
+.if SOFT80COLORVOODOO = 1
+ jsr soft80_putcolor
+.else
+ lda soft80_internal_cellcolor
+ sta (CRAM_PTR),y ; vram
+.endif
+
+ lda soft80_internal_cursorxlsb
+ bne draw_spaceinvers_odd
+
+; output inverted space (even)
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$0f
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+; output space (odd)
+draw_space_odd:
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ ora #$0f
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+; output space (general entry point)
+; in: y must be $00
+draw_space:
+
+ lda RVS
+ bne draw_spaceinvers
+
+.if SOFT80COLORVOODOO = 1
+ jsr remcolor
+.endif
+ ;ldy #$00 ; is still $00
+
+ lda soft80_internal_cursorxlsb
+ bne draw_space_odd
+
+; output space (even)
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ ora #$f0
+ sta (SCREEN_PTR),y
+ .if (line < 7)
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+.endif
+
+;-------------------------------------------------------------------------------
+; output one character in internal encoding without advancing cursor position
+; generic entry point
+;
+; - the following may not modify tmp1
+; in: A: charcode
+; out: Y: CURS_X
+;
+soft80_putchar:
+ sta tmp3 ; remember charcode
+
+ sei
+ ldx $01
+ stx tmp4
+ ldx #$34
+
+ stx $01 ; will stay $34 for space
+ ldy #$00 ; will be $00 from now on
+
+.if SOFT80FASTSPACE = 1
+ cmp #' ' ; space is a special (optimized) case
+ beq draw_space
+.endif
+
+.if SOFT80COLORVOODOO = 1
+ jsr soft80_putcolor
+.else
+ lda soft80_internal_cellcolor
+ sta (CRAM_PTR),y ; vram
+.endif
+
+; output character
+ ldx tmp3 ; get charcode
+
+ lda RVS
+ beq @skp
+ jmp draw_charinvers
+@skp:
+ lda soft80_internal_cursorxlsb
+ bne draw_char_even
+
+; output character (odd)
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$0f
+ ora soft80_hi_charset+(line*$80),x
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+; output character (even)
+draw_char_even:
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$f0
+ ora soft80_lo_charset+(line*$80),x
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+
+draw_back:
+ lda tmp4
+ sta $01
+ cli
+
+ ldy CURS_X
+ rts
+
+; output inverted character (odd)
+draw_charinvers_odd:
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ ora #$0f
+ eor soft80_lo_charset+(line*$80),x
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+; output inverted character (generic)
+draw_charinvers:
+ lda soft80_internal_cursorxlsb
+ bne draw_charinvers_odd
+
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ ora #$f0
+ eor soft80_hi_charset+(line*$80),x
+ sta (SCREEN_PTR),y
+ .if line < 7
+ iny
+ .endif
+ .endrepeat
+ jmp draw_back
+
+;-------------------------------------------------------------------------------
+; optional "color voodoo". the problem is that each 8x8 cell can only contain
+; two colors, one of which is used for the background color, so two characters
+; have to share the same text color.
+;
+; - in a cell that contains two spaces, both the color ram and the text color
+; in vram contain the background color
+;
+; - in a cell that contains one character, its text color goes into vram. the
+; color ram contains the background color.
+;
+; - in a cell that contains two characters, the color of the left character goes
+; to vram (and is shared by both for display). the "would be" color of the
+; right character goes to color ram as a reminder and can be restored when one
+; of the two characters is cleared by a space.
+
+.if SOFT80COLORVOODOO = 1
+
+; remove color from cell, called before putting a "space" character to the bitmap
+;
+; __ -> __ -
+; _A -> _A -
+; B_ -> B_ -
+; _A -> __ vram = bgcol
+; B_ -> __ vram = bgcol
+; BA -> _A vram = colram, colram = bgcol
+; BA -> B_ colram = bgcol
+;
+; in: x must be $34
+; y must be $00
+; out: x = $34
+; y = $00
+remcolor:
+
+ ;ldy #$00 ; is still $00
+
+ ; if the textcolor in vram is equal to the background color, then
+ ; no (visible) character is in the current cell and we can exit
+ ; immediately.
+ lda (CRAM_PTR),y ; vram (textcolor)
+ and #$0f
+ cmp soft80_internal_bgcolor
+ beq @sk1 ; yes, vram==bgcolor
+
+ ; now check if the textcolor in color ram is equal the background color,
+ ; if yes then there is only one (visible) character in the current cell
+ inc $01 ; $35
+ lda (CRAM_PTR),y ; colram (2nd textcolor)
+ stx $01 ; $34
+ and #$0f
+ cmp soft80_internal_bgcolor
+ beq @sk2 ; yes, colram==bgcolor
+ sta tmp3 ; A contains colram
+
+ ; two characters in the current cell, of which one will get removed
+
+ lda soft80_internal_cursorxlsb
+ bne @sk3
+
+ ; vram = colram
+ lda (CRAM_PTR),y ; vram
+ and #$f0
+ ora tmp3 ; colram value
+ sta (CRAM_PTR),y ; vram
+@sk3:
+ ; colram = bgcolor
+ lda soft80_internal_bgcolor
+ inc $01 ; $35
+ sta (CRAM_PTR),y ; colram
+ stx $01 ; $34
+
+ rts
+
+@sk2:
+ ; colram is bgcolor
+ ; => only one char in cell used
+
+ jsr soft80_checkchar
+ bcs @sk1 ; space at current position
+
+ ; vram (textcolor) = bgcolor
+ lda (CRAM_PTR),y ; vram
+ and #$f0
+ ora soft80_internal_bgcolor
+ sta (CRAM_PTR),y ; vram
+@sk1:
+ rts
+
+; put color to cell
+;
+; __ -> _A vram = textcol
+; __ -> B_ vram = textcol
+; _A -> BA colram = vram, vram = textcol
+; B_ -> BA colram = textcol
+;
+; _A -> _C vram = textcol
+; B_ -> C_ vram = textcol
+; BA -> BC colram = textcol
+; BA -> CA vram = textcol
+;
+; in: $01 is $34 (RAM under I/O) when entering
+; x must be $34
+; y must be $00
+; out: x = $34
+; y = $00
+soft80_putcolor:
+
+ ;ldy #$00 ; is still $00
+
+ lda (CRAM_PTR),y ; vram
+ and #$0f
+ cmp soft80_internal_bgcolor
+ beq @sk1 ; vram==bgcolor => first char in cell
+
+ ; vram!=bgcolor => second char in cell
+
+ inc $01 ; $35
+ lda (CRAM_PTR),y ; colram
+ stx $01 ; $34
+ and #$0f
+ cmp soft80_internal_bgcolor
+ beq @l2s ; colram==bgcolor -> second char in cell
+
+ ; botch characters in the cell are used
+
+ lda soft80_internal_cursorxlsb
+ bne @sk2 ; jump if odd xpos
+
+ ; vram = textcol
+ lda soft80_internal_cellcolor
+ sta (CRAM_PTR),y ; vram
+ rts
+
+@l2s:
+ ; one character in cell is already used
+ jsr soft80_checkchar
+ bcc @sk1 ; char at current position => overwrite 1st
+
+ lda soft80_internal_cursorxlsb
+ beq @sk3 ; jump if even xpos
+@sk2:
+ ; colram = textcol
+ lda CHARCOLOR
+ inc $01 ; $35
+ sta (CRAM_PTR),y ; colram
+ stx $01 ; $34
+ rts
+
+@sk3:
+ ; colram=vram
+ lda (CRAM_PTR),y ; vram
+ inc $01 ; $35
+ sta (CRAM_PTR),y ; colram
+ stx $01 ; $34
+@sk1:
+ ; vram = textcol
+ lda soft80_internal_cellcolor
+ sta (CRAM_PTR),y ; vram
+ rts
+
+;
+; test if there is a space or a character at current position
+;
+; in: x = $34
+; $01 must be $34
+;
+; out: SEC: space
+; CLC: character
+; x = $34
+; y = $00
+soft80_checkchar:
+
+ lda soft80_internal_cursorxlsb
+ bne @l1a
+
+ ; check charset data from bottom up, since a lot of eg lowercase chars
+ ; have no data in the top rows, but all of them DO have data in the
+ ; second to bottom row, this will likely be faster in average.
+
+ ldy #7
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$f0
+ cmp #$f0
+ bne @ischar
+ .if (line < 7)
+ dey
+ .endif
+ .endrepeat
+ ;ldy #$00 ; is 0
+ ;sec ; is set
+ rts
+@ischar:
+ ldy #$00
+ ;clc ; is cleared
+ rts
+@l1a:
+ ldy #$07
+ .repeat 8,line
+ lda (SCREEN_PTR),y
+ and #$0f
+ cmp #$0f
+ bne @ischar
+ .if line < 7
+ dey
+ .endif
+ .endrepeat
+ ;ldy #$00 ; is 0
+ ;sec ; is set
+ rts
+.endif