;
+; Groepaz/Hitmen, 11.10.2015
+;
+; high level implementation for the soft80 implementation
+;
; 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 gotoxy
- .import popa, _gotoxy
- .import xsize
.import soft80_kplot
- .import __bgcolor, __textcolor
+ .import soft80_internal_bgcolor, soft80_internal_cellcolor
+ .import soft80_internal_cursorxlsb
.importzp tmp4,tmp3
- .macpack longbranch
-
.include "c64.inc"
.include "soft80.inc"
-.if SOFT80COLORVOODOO = 1
- .export soft80_putcolor
-.endif
-
soft80_cputcxy:
pha ; Save C
- jsr popa ; Get Y
- jsr _gotoxy ; Set cursor, drop x
+ jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function
L1: cmp #$0D ; LF?
beq soft80_newline ; Recalculate pointers
- ; Printable char of some sort
-
+ ; 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
+ bpl @L10
- ; extra check for petscii codes 160-191, these have been moved to
- ; 0-31 in the charset
- and #%11100000
- cmp #%10100000
- bne @sk
+ ; 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
- tya
- and #%00011111
- bpl L10 ; branch always
-@sk:
- tya
+ ora #%01000000 ; $40
clc
- adc #$20
- and #$7F
-L10:
+ 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
-
-advance:
+ ; Advance cursor position
iny ; contains CURS_X
cpy #charsperline
- beq L3
+ beq @L3
sty CURS_X
tya
and #$01
+ sta soft80_internal_cursorxlsb
bne @L5
lda SCREEN_PTR
inc CRAM_PTR+1
@L5:
rts
-L3:
+@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
sta CRAM_PTR
- bcc L5
+ bcc @L5
inc CRAM_PTR+1
-L5:
+@L5:
inc CURS_Y
rts
-; Write one character to the screen without doing anything else
-; in: A: character
-; returns: Y: cursor X position
-; this function is going to be used a lot so we unroll it a bit for speed
+;-------------------------------------------------------------------------------
+; 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 space
-; in: y must be $00
-_space:
- lda RVS
- jne _spaceinvers
-
-.if SOFT80COLORVOODOO = 1
- jsr remcolor
-.endif
- ;ldy #$00 ; is still $00
-
- lda CURS_X
- and #$01
- bne @l1
-
- .repeat 8,line
- lda (SCREEN_PTR),y
- ora #$f0
- sta (SCREEN_PTR),y
- .if (line < 7)
- iny
- .endif
- .endrepeat
- jmp _back
-@l1:
+; output inverted space (odd)
+draw_spaceinvers_odd:
.repeat 8,line
lda (SCREEN_PTR),y
- ora #$0f
+ and #$f0
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
-@l2:
- jmp _back
+ jmp draw_back
-; output inverted space
+; output inverted space (general entry point)
; in: y must be $00
-_spaceinvers:
+draw_spaceinvers:
.if SOFT80COLORVOODOO = 1
jsr soft80_putcolor
.else
- lda CHARCOLOR
+ lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
.endif
- lda CURS_X
- and #$01
- bne @l1
+ lda soft80_internal_cursorxlsb
+ bne draw_spaceinvers_odd
+; output inverted space (even)
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
iny
.endif
.endrepeat
- jmp _back
-@l1:
+ jmp draw_back
+
+; output space (odd)
+draw_space_odd:
.repeat 8,line
lda (SCREEN_PTR),y
- and #$f0
+ 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:
- jmp _back
+ 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 a character
+; 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
.if SOFT80FASTSPACE = 1
cmp #' ' ; space is a special (optimized) case
- jeq _space
+ beq draw_space
.endif
.if SOFT80COLORVOODOO = 1
jsr soft80_putcolor
.else
- lda CHARCOLOR
+ lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
.endif
- ; output character
+; output character
ldx tmp3 ; get charcode
lda RVS
- jne _invers
-
- lda CURS_X
- and #$01
- bne @l1
+ 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
iny
.endif
.endrepeat
- jmp @l2
-@l1:
+ jmp draw_back
+; output character (even)
+draw_char_even:
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
.endif
.endrepeat
-@l2:
-
-_back:
+draw_back:
lda tmp4
sta $01
cli
ldy CURS_X
rts
-; output inverted character
-_invers:
-
- lda CURS_X
- and #$01
- bne @l1
-
+; output inverted character (odd)
+draw_charinvers_odd:
.repeat 8,line
lda (SCREEN_PTR),y
- ora #$f0
- eor soft80_hi_charset+(line*$80),x
+ ora #$0f
+ eor soft80_lo_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
- jmp _back
-@l1:
+ 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 #$0f
- eor soft80_lo_charset+(line*$80),x
+ ora #$f0
+ eor soft80_hi_charset+(line*$80),x
sta (SCREEN_PTR),y
.if line < 7
iny
.endif
.endrepeat
- jmp _back
+ jmp draw_back
;-------------------------------------------------------------------------------
; optional "color voodoo". the problem is that each 8x8 cell can only contain
;
; in: x must be $34
; y must be $00
-; out: y = $00
+; out: x = $34
+; y = $00
remcolor:
;ldy #$00 ; is still $00
; immediately.
lda (CRAM_PTR),y ; vram (textcolor)
and #$0f
- cmp __bgcolor
+ cmp soft80_internal_bgcolor
beq @sk1 ; yes, vram==bgcolor
; now check if the textcolor in color ram is equal the background color,
lda (CRAM_PTR),y ; colram (2nd textcolor)
stx $01 ; $34
and #$0f
- cmp __bgcolor
+ 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
- ; vram = colram
- ;inc $01
- ;lda (CRAM_PTR),y ; colram
- ;stx $01 ;$34
- ;and #$0f
- sta tmp3 ; A contains colram
-
- lda CURS_X
- and #$01
+ lda soft80_internal_cursorxlsb
bne @sk3
; vram = colram
lda (CRAM_PTR),y ; vram
and #$f0
- ora tmp3
+ ora tmp3 ; colram value
sta (CRAM_PTR),y ; vram
@sk3:
; colram = bgcolor
- lda __bgcolor
+ lda soft80_internal_bgcolor
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
; => only one char in cell used
jsr soft80_checkchar
- bcc @sk1 ; space at current position
+ bcs @sk1 ; space at current position
; vram (textcolor) = bgcolor
lda (CRAM_PTR),y ; vram
and #$f0
- ora __bgcolor
+ ora soft80_internal_bgcolor
sta (CRAM_PTR),y ; vram
@sk1:
rts
lda (CRAM_PTR),y ; vram
and #$0f
- cmp __bgcolor
+ cmp soft80_internal_bgcolor
beq @sk1 ; vram==bgcolor => first char in cell
; vram!=bgcolor => second char in cell
lda (CRAM_PTR),y ; colram
stx $01 ; $34
and #$0f
- cmp __bgcolor
+ cmp soft80_internal_bgcolor
beq @l2s ; colram==bgcolor -> second char in cell
; botch characters in the cell are used
- lda CURS_X
- and #$01
+ lda soft80_internal_cursorxlsb
bne @sk2 ; jump if odd xpos
; vram = textcol
- lda CHARCOLOR
+ lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
rts
@l2s:
; one character in cell is already used
jsr soft80_checkchar
- bcs @sk1 ; char at current position => overwrite 1st
+ bcc @sk1 ; char at current position => overwrite 1st
- lda CURS_X
- and #$01
+ lda soft80_internal_cursorxlsb
beq @sk3 ; jump if even xpos
@sk2:
; colram = textcol
- lda __textcolor
+ lda CHARCOLOR
inc $01 ; $35
sta (CRAM_PTR),y ; colram
stx $01 ; $34
stx $01 ; $34
@sk1:
; vram = textcol
- lda CHARCOLOR
+ lda soft80_internal_cellcolor
sta (CRAM_PTR),y ; vram
rts
+;
; test if there is a space or a character at current position
-; in: y must be $00
-; out: CLC: space SEC: character
+;
+; in: x = $34
+; $01 must be $34
+;
+; out: SEC: space
+; CLC: character
+; x = $34
; y = $00
soft80_checkchar:
- ;ldy #$00 ; is still $00
+ lda soft80_internal_cursorxlsb
+ bne @l1a
- lda CURS_X
- and #$01
- jne @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 @l2b
+ bne @ischar
.if (line < 7)
- iny
+ dey
.endif
.endrepeat
-
- ldy #$00
- clc
+ ;ldy #$00 ; is 0
+ ;sec ; is set
rts
-@l2b:
+@ischar:
ldy #$00
- sec
+ ;clc ; is cleared
rts
@l1a:
+ ldy #$07
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
cmp #$0f
- bne @l2bb
+ bne @ischar
.if line < 7
- iny
+ dey
.endif
.endrepeat
- ldy #$00
- clc
+ ;ldy #$00 ; is 0
+ ;sec ; is set
rts
-@l2bb:
- ldy #$00
- sec
- rts
-
.endif