]> git.sur5r.net Git - cc65/blob - libsrc/tgi/tgi_vectorchar.s
tgi_vectorchar takes now a char argument. Added tgi_install_vectorfont.
[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         .import         _toascii, imul16x16r32, umul16x16r32, negax, negeax
11
12         .include        "tgi-kernel.inc"
13         .include        "tgi-vectorfont.inc"
14         .include        "zeropage.inc"
15                     
16         .macpack        longbranch
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 .code
35 .proc   _tgi_vectorchar
36
37 ; Convert the character to ASCII, multiplicate by two and save into Y
38
39         jsr     _toascii
40         asl     a
41         tay
42
43 ; Since we will call tgi_lineto, which uses the zero page, and we do also
44 ; need the zero page, make room in the register bank.
45
46         lda     Ops
47         pha
48         lda     Ops+1
49         pha
50         lda     Flag
51         pha
52
53 ; Calculate a pointer to the vector ops for the given char (now in Y).
54
55         lda     _tgi_vectorfont+1
56         tax
57         ora     _tgi_vectorfont
58         jeq     Done                    ; Bail out if no font installed
59         lda     _tgi_vectorfont
60         clc
61         adc     #<(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
62         sta     Ops
63         lda     _tgi_vectorfont+1
64         adc     #>(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
65         sta     Ops+1
66
67         iny
68         lda     (Ops),y
69         tax
70         dey
71         lda     (Ops),y
72         sta     Ops
73         stx     Ops+1
74
75 ; Main loop executing vector operations
76
77 Loop:   lda     _tgi_textscalew+0
78         ldx     _tgi_textscalew+1
79         jsr     GetProcessedCoord
80
81 ; X2 = tgi_curx + XMag * XDelta.
82
83         clc
84         adc     _tgi_curx+0
85         sta     X2+0
86         txa
87         adc     _tgi_curx+1
88         sta     X2+1
89
90 ; Process the Y value
91
92         lda     _tgi_textscaleh+0
93         ldx     _tgi_textscaleh+1
94         jsr     GetProcessedCoord
95
96 ; Y2 = tgi_cury - YMag * YDelta;
97 ; Y2 = tgi_cury + (~(YMag * YDelta) + 1);
98
99         eor     #$FF
100         sec                             ; + 1
101         adc     _tgi_cury+0
102         sta     Y2+0
103         txa
104         eor     #$FF
105         adc     _tgi_cury+1
106         sta     Y2+1
107
108 ; Draw, then move - or just move
109
110         bit     Flag
111         bpl     @Move                   ; Jump if move only
112
113         ldy     #7                      ; Copy start coords into zp
114 :       lda     X1,y
115         sta     ptr1,y
116         dey
117         bpl     :-
118
119         jsr     tgi_line                ; Call the driver
120
121 ; Move the start position
122
123 @Move:  ldy     #3
124 :       lda     X2,y
125         sta     X1,y
126         dey
127         bpl     :-
128
129 ; Loop if not done
130
131         bit     Flag
132         bvc     Loop
133
134 ; Done. Restore zp and return.
135
136 Done:   pla
137         sta     Flag
138         pla
139         sta     Ops+1
140         pla
141         sta     Ops
142         rts
143
144 .endproc
145
146 ;----------------------------------------------------------------------------
147 ; Get and process one coordinate value. The scale factor is passed in a/x
148
149 .proc   GetProcessedCoord
150
151 ; Save scale factor as left operand for multiplication
152
153         sta     ptr1
154         stx     ptr1+1
155
156 ; Load delta value
157
158         ldy     #0
159         lda     (Ops),y
160         inc     Ops
161         bne     :+
162         inc     Ops+1
163
164 ; Move bit 7 into Flag
165
166 :       asl     a                       ; Flag into carry
167         ror     Flag
168
169 ; Since we know that the scale factor is always positive, we will remember
170 ; the sign of the coordinate offset, make it positive, do an unsigned mul
171 ; and negate the result if the vector was negative. This is faster than
172 ; relying on the signed multiplication, which will do the same, but for
173 ; both operands.
174
175         sta     tmp1                    ; Remember sign of vector offset
176         cmp     #$80                    ; Sign bit into carry
177         ror     a                       ; Sign extend the value
178         bpl     :+
179         eor     #$FF
180         clc
181         adc     #$01                    ; Negate
182 :       ldx     #$00                    ; High byte is always zero
183
184 ; Multiplicate with the scale factor.
185
186         jsr     umul16x16r32            ; Multiplicate
187
188 ; The result is a 16.8 fixed point value. Round it.
189
190         cmp     #$80                    ; frac(val) >= 0.5?
191         txa
192         adc     #$00
193         tay
194         lda     sreg
195         adc     #$00
196         tax
197         tya
198         bit     tmp1                    ; Check sign
199         bpl     :+
200         jmp     negax                   ; Negate result if necessary
201 :       rts
202
203 .endproc
204