]> git.sur5r.net Git - cc65/blob - libsrc/tgi/tgi_vectorchar.s
3c171e9d742113d6e4bd57d7f5169dcc93584ac9
[cc65] / libsrc / tgi / tgi_vectorchar.s
1 ;
2 ; Ullrich von Bassewitz, 2009-11-02
3 ;
4 ; void __fastcall__ tgi_vectorchar (const unsigned char* Ops);
5 ; /* Draw one character of the vector font at the current graphics cursor
6 ;  * position using the current font magnification.
7 ;  */
8 ;
9
10         .export         _tgi_vectorchar
11
12         .import         imul16x16r32, umul16x16r32, negax, negeax
13
14         .include        "tgi-kernel.inc"
15         .include        "zeropage.inc"
16
17
18 ;----------------------------------------------------------------------------
19 ; Data
20
21 Ops     = regbank
22 Flag    = regbank+2
23
24 .bss
25 X1:     .res    2
26 Y1:     .res    2
27 X2:     .res    2
28 Y2:     .res    2
29
30
31
32 ;----------------------------------------------------------------------------
33 ;
34
35 .code
36 .proc   _tgi_vectorchar
37
38 ; Since we will call tgi_lineto, which uses the zero page, and we do also
39 ; need the zero page, make room in the register bank.
40
41         tay
42         lda     Ops
43         pha
44         lda     Ops+1
45         pha
46         lda     Flag
47         pha
48
49 ; Save the pointer
50
51         sty     Ops
52         stx     Ops+1
53
54 ; Main loop executing vector operations
55
56 Loop:   lda     _tgi_textscalew+0
57         ldx     _tgi_textscalew+1
58         jsr     GetProcessedCoord
59
60 ; X2 = tgi_curx + XMag * XDelta.
61
62         clc
63         adc     _tgi_curx+0
64         sta     X2+0
65         txa
66         adc     _tgi_curx+1
67         sta     X2+1
68
69 ; Process the Y value
70
71         lda     _tgi_textscaleh+0
72         ldx     _tgi_textscaleh+1
73         jsr     GetProcessedCoord
74
75 ; Y2 = tgi_cury - YMag * YDelta;
76 ; Y2 = tgi_cury + (~(YMag * YDelta) + 1);
77
78         eor     #$FF
79         sec                             ; + 1
80         adc     _tgi_cury+0
81         sta     Y2+0
82         txa
83         eor     #$FF
84         adc     _tgi_cury+1
85         sta     Y2+1
86
87 ; Draw, then move - or just move
88
89         bit     Flag
90         bpl     @Move                   ; Jump if move only
91
92         ldy     #7                      ; Copy start coords into zp
93 :       lda     X1,y
94         sta     ptr1,y
95         dey
96         bpl     :-
97
98         jsr     tgi_line                ; Call the driver
99
100 ; Move the start position
101
102 @Move:  ldy     #3
103 :       lda     X2,y
104         sta     X1,y
105         dey
106         bpl     :-
107
108 ; Loop if not done
109
110         bit     Flag
111         bvc     Loop
112
113 ; Done. Restore zp and return.
114
115 @Done:  pla
116         sta     Flag
117         pla
118         sta     Ops+1
119         pla
120         sta     Ops
121         rts
122
123 .endproc
124
125 ;----------------------------------------------------------------------------
126 ; Get and process one coordinate value. The scale factor is passed in a/x
127
128 .proc   GetProcessedCoord
129
130 ; Save scale factor as left operand for multiplication
131
132         sta     ptr1
133         stx     ptr1+1
134
135 ; Load delta value
136
137         ldy     #0
138         lda     (Ops),y
139         inc     Ops
140         bne     :+
141         inc     Ops+1
142
143 ; Move bit 7 into Flag
144
145 :       asl     a                       ; Flag into carry
146         ror     Flag
147
148 ; Since we know that the scale factor is always positive, we will remember
149 ; the sign of the coordinate offset, make it positive, do an unsigned mul
150 ; and negate the result if the vector was negative. This is faster than
151 ; relying on the signed multiplication, which will do the same, but for
152 ; both operands.
153
154         sta     tmp1                    ; Remember sign of vector offset
155         cmp     #$80                    ; Sign bit into carry
156         ror     a                       ; Sign extend the value
157         bpl     :+
158         eor     #$FF
159         clc
160         adc     #$01                    ; Negate
161 :       ldx     #$00                    ; High byte is always zero
162
163 ; Multiplicate with the scale factor.
164
165         jsr     umul16x16r32            ; Multiplicate
166
167 ; The result is a 16.8 fixed point value. Round it.
168
169         cmp     #$80                    ; frac(val) >= 0.5?
170         txa
171         adc     #$00
172         tay
173         lda     sreg
174         adc     #$00
175         tax
176         tya
177         bit     tmp1                    ; Check sign
178         bpl     :+
179         jmp     negax                   ; Negate result if necessary
180 :       rts
181
182 .endproc
183