]> git.sur5r.net Git - cc65/blobdiff - libsrc/c64/soft80_cputc.s
added optimization for indexed 16-bit array load of form (array[i & 0x7f])
[cc65] / libsrc / c64 / soft80_cputc.s
index 3ef982aaa779ff1b25bd95b1e0d043da55cea2f8..f00f7792f0684171e14d45bb310dc0f7e94447f1 100644 (file)
@@ -1,4 +1,8 @@
 ;
+; 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
@@ -48,40 +47,39 @@ soft80_plot:
 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
@@ -96,12 +94,13 @@ advance:
         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
@@ -117,70 +116,47 @@ soft80_newline:
         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
@@ -189,22 +165,55 @@ _spaceinvers:
         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
 
@@ -218,26 +227,27 @@ soft80_putchar:
 
 .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
@@ -247,9 +257,10 @@ soft80_putchar:
         iny
         .endif
         .endrepeat
-        jmp     @l2
-@l1:
+        jmp     draw_back
 
+; output character (even)
+draw_char_even:
         .repeat 8,line
         lda     (SCREEN_PTR),y
         and     #$f0
@@ -260,9 +271,7 @@ soft80_putchar:
         .endif
         .endrepeat
 
-@l2:
-
-_back:
+draw_back:
         lda     tmp4
         sta     $01
         cli
@@ -270,34 +279,34 @@ _back:
         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
@@ -329,7 +338,8 @@ _invers:
 ;
 ; in:  x must be $34
 ;      y must be $00
-; out: y = $00
+; out: x = $34
+;      y = $00
 remcolor:
 
         ;ldy     #$00            ; is still $00
@@ -339,7 +349,7 @@ remcolor:
         ; 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,
@@ -348,30 +358,23 @@ remcolor:
         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
@@ -383,12 +386,12 @@ remcolor:
         ; => 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
@@ -416,7 +419,7 @@ soft80_putcolor:
 
         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
@@ -425,31 +428,29 @@ soft80_putcolor:
         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
@@ -463,55 +464,58 @@ soft80_putcolor:
         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