]> git.sur5r.net Git - cc65/blobdiff - libsrc/tgi/tgi_vectorchar.s
remove superfluous ".code" line
[cc65] / libsrc / tgi / tgi_vectorchar.s
index dafef75b27b6a728f17c9785be864c4edc12b420..72a5b234bb4c9fbdf16c5f9291cf7331378e1bf6 100644 (file)
@@ -7,13 +7,13 @@
 ;  */
 ;
 
-        .export         _tgi_vectorchar
-
-        .import         push0ax, tosmuleax
+        .import         _toascii, imul16x16r32, umul16x16r32, negax, negeax
 
         .include        "tgi-kernel.inc"
+        .include        "tgi-vectorfont.inc"
         .include        "zeropage.inc"
 
+        .macpack        longbranch
 
 ;----------------------------------------------------------------------------
 ; Data
@@ -26,8 +26,99 @@ X1:     .res    2
 Y1:     .res    2
 X2:     .res    2
 Y2:     .res    2
+BaseX:  .res    2
+BaseY:  .res    2
+Char:   .res    1
+
+;----------------------------------------------------------------------------
+; Get the next operation from the Ops pointer, remove the flag bit and sign
+; extend the 8 bit value. On return, the flags are set for the value in A.
+
+.code
+.proc   GetOp
+
+; Load delta value
+
+        ldy     #0
+        lda     (Ops),y
+        inc     Ops
+        bne     :+
+        inc     Ops+1
+
+; Move bit 7 into Flag, then sign extend the value in A
+
+:       asl     a                       ; Flag into carry
+        ror     Flag
+        cmp     #$80                    ; Sign bit into carry
+        ror     a                       ; Sign extend the value
+
+; Done
+
+        rts
+
+.endproc
+
 
+;----------------------------------------------------------------------------
+; Round a 16.8 fixed point value in eax
+
+.code
+.proc   RoundFix
+
+        cmp     #$80                    ; frac(val) >= 0.5?
+        txa
+        ldx     sreg
+        adc     #$00
+        bcc     @L1
+        inx
+@L1:    rts
 
+.endproc
+
+;----------------------------------------------------------------------------
+; Get and process one coordinate value. The scale factor is passed in a/x
+
+.code
+.proc   GetProcessedCoord
+
+; Save scale factor as left operand for multiplication
+
+        sta     ptr1
+        stx     ptr1+1
+
+; Load next operation value. This will set the flags for the value in A.
+
+        jsr     GetOp
+
+; Since we know that the scale factor is always positive, we will remember
+; the sign of the coordinate offset, make it positive, do an unsigned mul
+; and negate the result if the vector was negative. This is faster than
+; relying on the signed multiplication, which will do the same, but for
+; both operands.
+
+        sta     tmp1                    ; Remember sign of vector offset
+        bpl     :+
+        eor     #$FF
+        clc
+        adc     #$01                    ; Negate
+:       ldx     #$00                    ; High byte is always zero
+
+; Multiplicate with the scale factor.
+
+        jsr     umul16x16r32            ; Multiplicate
+
+; The result is a 16.8 fixed point value. Round it.
+
+        jsr     RoundFix
+
+; Check the sign and negate if necessary
+
+        bit     tmp1                    ; Check sign
+        bpl     :+
+        jmp     negax                   ; Negate result if necessary
+:       rts
+
+.endproc
 
 ;----------------------------------------------------------------------------
 ;
@@ -35,10 +126,15 @@ Y2:     .res    2
 .code
 .proc   _tgi_vectorchar
 
+; Convert the character to ASCII, multiplicate by two and save into Y
+
+        jsr     _toascii
+        asl     a
+        tay
+
 ; Since we will call tgi_lineto, which uses the zero page, and we do also
 ; need the zero page, make room in the register bank.
 
-        tay
         lda     Ops
         pha
         lda     Ops+1
@@ -46,24 +142,92 @@ Y2:     .res    2
         lda     Flag
         pha
 
-; Save the pointer
+; Get the width of the char in question
+
+        lda     _tgi_vectorfont
+        clc
+        adc     #<(TGI_VECTORFONT::WIDTHS - TGI_VF_FIRSTCHAR)
+        sta     Ops
+        lda     _tgi_vectorfont+1
+        adc     #>(TGI_VECTORFONT::WIDTHS - TGI_VF_FIRSTCHAR)
+        sta     Ops+1
+        lda     (Ops),y
+
+; Save the character
+
+        sty     Char
+
+; Calculate the width of the character by multiplying with the scale
+; factor for the width
+
+        sta     ptr1
+        lda     #0
+        sta     ptr1+1
+
+        lda     _tgi_textscalew
+        ldx     _tgi_textscalew+1
+        jsr     umul16x16r32
+        jsr     RoundFix
+
+; Store the current value of the graphics cursor into BaseX/BaseY, then
+; move it to the next character position
+
+        pha
+        ldy     #3
+:       lda     _tgi_curx,y
+        sta     BaseX,y
+        dey
+        bpl     :-
+        pla
+
+        ldy     _tgi_textdir
+        beq     :+                      ; Jump if horizontal text
+
+        jsr     negax
+        ldy     #2                      ; Offset of tgi_cury
+
+; Advance graphics cursor
+
+:       clc
+        adc     _tgi_curx,y
+        sta     _tgi_curx,y
+        txa
+        adc     _tgi_curx+1,y
+        sta     _tgi_curx+1,y
+
+; Calculate a pointer to the vector ops for the given char (now in Y). We
+; definitely expect a font here, that has to be checked by the caller.
+
+        lda     _tgi_vectorfont
+        clc
+        adc     #<(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
+        sta     Ops
+        lda     _tgi_vectorfont+1
+        adc     #>(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
+        sta     Ops+1
 
-        sty     Ops
+        ldy     Char
+        iny
+        lda     (Ops),y
+        tax
+        dey
+        lda     (Ops),y
+        sta     Ops
         stx     Ops+1
 
 ; Main loop executing vector operations
 
 Loop:   lda     _tgi_textscalew+0
         ldx     _tgi_textscalew+1
-        jsr     GetProcessedCoord
+        jsr     GetProcessedCoord       ; Get X vector
 
-; X2 = tgi_curx + XMag * XDelta.
+; X2 = BaseX + XMag * XDelta.
 
         clc
-        adc     _tgi_curx+0
+        adc     BaseX+0
         sta     X2+0
         txa
-        adc     _tgi_curx+1
+        adc     BaseX+1
         sta     X2+1
 
 ; Process the Y value
@@ -72,19 +236,19 @@ Loop:   lda     _tgi_textscalew+0
         ldx     _tgi_textscaleh+1
         jsr     GetProcessedCoord
 
-; Y2 = tgi_cury - YMag * YDelta;
-; Y2 = tgi_cury + (~(YMag * YDelta) + 1);
+; Y2 = BaseY - YMag * YDelta;
+; Y2 = BaseY + (~(YMag * YDelta) + 1);
 
         eor     #$FF
         sec                             ; + 1
-        adc     _tgi_cury+0
+        adc     BaseY+0
         sta     Y2+0
         txa
         eor     #$FF
-        adc     _tgi_cury+1
+        adc     BaseY+1
         sta     Y2+1
 
-; Do the actual operation
+; Draw, then move - or just move
 
         bit     Flag
         bpl     @Move                   ; Jump if move only
@@ -112,7 +276,7 @@ Loop:   lda     _tgi_textscalew+0
 
 ; Done. Restore zp and return.
 
-@Done:  pla
+Done:   pla
         sta     Flag
         pla
         sta     Ops+1
@@ -122,53 +286,3 @@ Loop:   lda     _tgi_textscalew+0
 
 .endproc
 
-;----------------------------------------------------------------------------
-; Get and process one coordinate value. The scale factor is passed in a/x
-
-.proc   GetProcessedCoord
-
-; Push the scale factor
-
-        jsr     push0ax
-
-; Load delta value
-
-        ldy     #0
-        lda     (Ops),y
-        inc     Ops
-        bne     :+
-        inc     Ops+1
-
-; Move bit 7 into Flag
-
-:       asl     a                       ; Flag into carry
-        ror     Flag
-
-; Sign extend the value
-
-        ldx     #0
-        cmp     #$80                    ; Sign bit into carry
-        bcc     :+
-        dex
-:       ror     a                       ; Sign extend the value
-
-; Multiplicate with the scale factor.
-
-        stx     sreg
-        stx     sreg+1
-        jsr     tosmuleax               ; Multiplicate
-
-; The result is a 16.8 fixed point value. Round and return it.
-
-        cmp     #$80                    ; Check digits after the dec point
-        txa
-        adc     #$00
-        tay
-        lda     sreg
-        adc     #$00
-        tax
-        tya
-        rts
-
-.endproc
-