Mercurial > public > hwos_code
annotate src/aa_wordprocessor.asm @ 212:5fd93901b735
Merge
author | heinrichsweikamp |
---|---|
date | Wed, 10 Dec 2014 09:13:49 +0100 |
parents | e79bc535ef9e |
children | 653a3ab08062 |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
3 ; File aa_wordprocessor.asm | |
4 ; | |
5 ; Anti-aliased word processor | |
6 ; | |
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. | |
8 ;============================================================================= | |
9 ; HISTORY | |
10 ; 2010-11-22 : [jDG] Creation. | |
11 ; 2010-12-01 : [jDG] Adding 3bits antialiased fonts. | |
12 ; 2010-12-30 : [jDG] Revised to put temp into ACCESSRAM0 | |
13 ; 2012-08-12 : [mH] Moved font28 into bootloader section 0x1C000 | |
14 ; | |
15 ; BUGS : | |
16 ; * If the three fonts are not in the same half of the PROM memory, TBLPTRU | |
17 ; will be badly set, and font48 or font90 will display giberish... | |
18 ;============================================================================= | |
19 ; | |
20 ; MEMORY FOOTPRINT: | |
21 ;------------------ | |
22 ; | |
23 ; wp_wordprocessor : 8KB, including fonts. | |
24 ; aa_wordprocessor : 0.5KB code | |
25 ; + 3.5KB aa_font28 (reduced to 99 chars) | |
26 ; + 1.6KB aa_font48 | |
27 ; + 2.2KB aa_font90 | |
28 ; = 7.9 KB including fonts... | |
29 ; | |
30 ; Input registers: | |
31 ; buffer:26 String to print. | |
32 ; win_font Font size (0=tiny, 1=small, 2=medium, 3=large) | |
33 ; win_color1:2 16bits unpacked color | |
34 ; win_top, win_leftx2 Position on screen | |
35 ; win_inverse Inverse video mode. | |
36 ; | |
37 ; Available general purpose registers: | |
38 ; PRODH, PRODL (needed for array indexing) | |
39 ; FSRx 12bits. Usefull as RAM pointers. | |
40 ;============================================================================= | |
41 | |
42 #include "ostc3.inc" | |
43 #include "tft.inc" | |
44 | |
45 extern aa_font16_block | |
46 extern aa_font28_block | |
47 extern aa_font36_block | |
48 extern aa_font48_block | |
49 extern aa_font90_block | |
50 | |
51 ;============================================================================= | |
52 ; Temporary variables are overlayed in Bank 1, used also by C-code | |
53 ; (p2_deco), MPLAB math and stdlib libraries. | |
54 | |
55 CBLOCK tmp ; Data overlay in reserved tmp area. | |
56 aa_flags:1 ; Various flags for aa_wordprocessor | |
57 aa_bitlen:1 ; Count of pixels when decoding bitmaps. | |
58 aa_start:2 ; PROM ptr to start of encoded bitmap | |
59 aa_end:2 ; and end of it. | |
60 aa_temp:2 ; Current color, divided by 2 or 4 | |
61 ; Reserved to tmp+0x07... | |
62 ENDC | |
63 ; Flags allocation: | |
64 #define aa_antialias aa_flags,0 | |
65 #define aa_color_quart aa_flags,1 | |
66 #define aa_color_half aa_flags,2 | |
67 | |
68 ;------------------------------------------------------------------------------ | |
69 ; Setup pointers for a char: | |
70 ; Inputs WREG = char to draw, win_font | |
71 ; Output aa_start, aa_end, win_height, aa_flags | |
72 ; Trashed PRODH, PRODL, TBLPTR, TABLAT | |
73 ; | |
74 basic CODE | |
75 aa_char_setup: | |
76 movwf PRODL ; save char into PROD for now. | |
77 | |
78 movf win_font,W,BANKED ; Get font number (updates Z flag) | |
79 bnz aa_char_1 | |
80 | |
81 ; TINY font --------------------------------------------------------- | |
82 ; Font TINY character folding... | |
83 aa_char_0: | |
84 movlw LOW aa_font16_block | |
85 movwf TBLPTRL | |
86 movlw HIGH aa_font16_block | |
87 movwf TBLPTRH | |
88 movlw UPPER aa_font16_block | |
89 movwf TBLPTRU | |
90 bra aa_char_99 | |
91 | |
92 ; SMALL font --------------------------------------------------------- | |
93 ; Font SMALL character folding... | |
94 aa_char_1: | |
95 decfsz WREG ; This is small font ??? | |
96 bra aa_char_2 | |
97 | |
98 movlw LOW aa_font28_block | |
99 movwf TBLPTRL | |
100 movlw HIGH aa_font28_block | |
101 movwf TBLPTRH | |
102 movlw UPPER aa_font28_block | |
103 movwf TBLPTRU | |
104 bra aa_char_99 | |
105 | |
106 ; STD font ----------------------------------------------------------- | |
107 ; Font SMALL character folding... | |
108 aa_char_2: | |
109 decfsz WREG ; This is small font ??? | |
110 bra aa_char_3 | |
111 | |
112 movlw LOW aa_font36_block | |
113 movwf TBLPTRL | |
114 movlw HIGH aa_font36_block | |
115 movwf TBLPTRH | |
116 movlw UPPER aa_font36_block | |
117 movwf TBLPTRU | |
118 bra aa_char_99 | |
119 | |
120 ; MEDIUM font -------------------------------------------------------- | |
121 aa_char_3: | |
122 decfsz WREG ; This is medium font ??? | |
123 bra aa_char_4 | |
124 | |
125 ; Font MEDIUM block: | |
126 movlw LOW aa_font48_block | |
127 movwf TBLPTRL | |
128 movlw HIGH aa_font48_block | |
129 movwf TBLPTRH | |
130 movlw UPPER aa_font48_block | |
131 movwf TBLPTRU | |
132 bra aa_char_99 | |
133 | |
134 ; LARGE font --------------------------------------------------------- | |
135 aa_char_4: | |
136 ; Font LARGE block: | |
137 movlw LOW aa_font90_block | |
138 movwf TBLPTRL | |
139 movlw HIGH aa_font90_block | |
140 movwf TBLPTRH | |
141 movlw UPPER aa_font90_block | |
142 movwf TBLPTRU | |
143 | |
144 ; Execute font block ------------------------------------------------- | |
145 aa_char_99: | |
146 ; This is safe if the three fonts are in the same code segment | |
147 ; (and that segment do not span the 64K edge...) | |
148 movlw UPPER aa_font16_block | |
149 movwf TBLPTRU | |
150 | |
151 ; Proceed to character substitutions | |
152 aa_char_30: | |
153 tblrd*+ ; Read FROM char | |
154 movf TABLAT,W ; Get it, and set Z,N | |
155 bz aa_char_32 ; Break at end of translations | |
156 | |
157 tblrd*+ ; Read TO char | |
158 cpfseq PRODL ; FROM == current char ? | |
159 bra aa_char_30 ; Different: loop | |
160 movff TABLAT, PRODL ; make substitution | |
161 bra aa_char_30 ; Loop. | |
162 | |
163 ; Make sure char is in the available range | |
164 aa_char_32: | |
165 tblrd*+ ; Read first char | |
166 movf TABLAT,W ; get it. | |
167 subwf PRODL,F ; (char - first) --> PRODL | |
168 | |
169 tblrd*+ ; Read nb chars | |
170 movf TABLAT,W ; nbchars --> WREG | |
171 tblrd*+ ; Read default char | |
172 cpfslt PRODL ; if char > WREG ? | |
173 movff TABLAT,PRODL ; replace PRODL | |
174 | |
175 ; Decode font height and anti-aliasing mode | |
176 clrf aa_flags ; Default to no AA | |
177 tblrd*+ ; Read font height + AA flag | |
178 movf TABLAT,W ; into WREG | |
179 bnn aa_char_34 ; High bit set ? | |
180 bsf aa_antialias ; YES : then the font is AA. | |
181 aa_char_34: | |
182 andlw 0x7F ; Keep just font height, | |
183 movwf win_height,BANKED ; then save it (its a register) | |
184 | |
185 ; Set PROM pointer to the char index | |
186 movf PRODL,W ; Read back char | |
187 mullw 2 ; PROD = 2*(char - base), TBLPTR=idx | |
188 movf PRODL,W | |
189 addwf TBLPTRL,F ; Add into TBLPTR (low byte) | |
190 movf PRODH,W | |
191 addwfc TBLPTRH,F ; and high byte. | |
192 | |
193 ; Read start and stop pointers | |
194 tblrd*+ ; aa_start = PROM16(*tblptr++) | |
195 movff TABLAT,aa_start+0 ; Read low byte | |
196 tblrd*+ | |
197 movff TABLAT,aa_start+1 ; and high byte | |
198 | |
199 tblrd*+ ; aa_end = PROM16(*tblptr++) | |
200 movff TABLAT,aa_end+0 ; Read low byte | |
201 tblrd*+ | |
202 movff TABLAT,aa_end+1 ; and high byte | |
203 | |
204 return | |
205 | |
206 ;------------------------------------------------------------------------------ | |
207 ; Character width | |
208 ; Inputs aa_start, aa_end, win_width, win_height, aa_flags | |
209 ; Output width added to win_width | |
210 ; Trashed aa_bitlen, TBLPTR, TABLAT | |
211 ; | |
212 aa_char_width: | |
213 movff aa_start+0, TBLPTRL ; TBLPTR = aa_start | |
214 movff aa_start+1, TBLPTRH | |
215 clrf aa_bitlen ; clear reminders... | |
216 | |
217 ; Read bitmap byte, and decode length: | |
218 aa_char_width_1: | |
219 ifdef AA_BYTE_SWAP | |
220 btg TBLPTRL,0 ; Toggle low ptr bit. | |
221 tblrd* | |
222 movf TABLAT,W ; Store to WREG | |
223 btg TBLPTRL,0 ; Get is back | |
224 tblrd*+ ; then increment (but trash TABLAT) | |
225 movwf TABLAT ; Then restore copy to TABLAT. | |
226 else | |
227 tblrd*+ ; Normal read... | |
228 movf TABLAT,W ; Store copy to WREG | |
229 endif | |
230 btfss aa_antialias ; Antialiased font ? | |
231 bra aa_char_width_10 ; No: always 7 bits count | |
232 | |
233 bn aa_char_width_10 ; Non-white pixels ? | |
234 andlw 0x1F ; Yes : 5 bits count. | |
235 aa_char_width_10: | |
236 andlw 0x7F ; No: 7 bit count. | |
237 incf WREG ; WREG = repetition count | |
238 addwf aa_bitlen,F ; Add remaining pixels from last code. | |
239 | |
240 movf win_height,W,BANKED ; WREG = - height | |
241 negf WREG | |
242 | |
243 ; This is a hand-made division by successive substraction of height | |
244 aa_char_width_2: | |
245 addwf aa_bitlen,F ; Try to substract win_height | |
246 bn aa_char_width_3 ; If neg it was a bad idea... | |
247 | |
248 infsnz win_width+0,F ; Succeded: do a 16bit increment | |
249 incf win_width+1,F ; on the win_width counter. | |
250 bra aa_char_width_2 ; and loop. | |
251 | |
252 aa_char_width_3: | |
253 negf WREG ; WREG = +height | |
254 addwf aa_bitlen,F ; Restore true reminder. | |
255 | |
256 ; Are we done ? | |
257 movf TBLPTRL,W ; Compare TBLPTR to aa_end | |
258 cpfseq aa_end+0 | |
259 bra aa_char_width_1 ; Loop if LOW is different | |
260 movf TBLPTRH,W | |
261 cpfseq aa_end+1 ; Loop to if HIGH is different | |
262 bra aa_char_width_1 | |
263 | |
264 return | |
265 | |
266 ;------------------------------------------------------------------------------ | |
267 ; String width | |
268 ; Inputs buffer (SHOULD BE NULL TERMINATED) | |
269 ; Output win_width, win_height | |
270 ; Trashed PROD, TBLPTR, FSR2, aa_bitlen, aa_start, aa_end, aa_flags | |
271 ; | |
272 aa_string_width: | |
273 lfsr FSR2, buffer ; FSR2 pointer to start of string. | |
274 | |
275 clrf win_width+0 ; Clear width sum. | |
276 clrf win_width+1 ; (16 bit counter) | |
277 | |
278 aa_string_width_1: | |
279 movf POSTINC2,W ; WREG = *FSR2++ | |
280 bz aa_string_width99 ; Exit if null byte encountered. | |
281 | |
282 rcall aa_char_setup ; setup aa_start / aa_end | |
283 rcall aa_char_width ; sum-up width into win_width | |
284 bra aa_string_width_1 ; and loop. | |
285 | |
286 aa_string_width99: | |
287 return | |
288 | |
289 ;------------------------------------------------------------------------------ | |
290 ; Decode a compressed char. | |
291 ; Inputs aa_start, aa_end, win_height, win_invert, win_color1, win_color2 | |
292 ; Output none | |
293 ; Trashed TBLPTR, TABLAT, PROD, aa_bitlen, aa_flags, aa_colorDir:2 | |
294 ; | |
295 aa_decode_char: | |
296 movff aa_start+0, TBLPTRL ; TBLPTR = aa_start | |
297 movff aa_start+1, TBLPTRH | |
298 | |
299 ; Read bitmap byte, and decode color & length | |
300 aa_decode_1: | |
301 ifdef AA_BYTE_SWAP | |
302 btg TBLPTRL,0 ; Toggle low ptr bit. | |
303 tblrd* | |
304 movf TABLAT,W ; Store to WREG | |
305 btg TBLPTRL,0 ; Get is back | |
306 tblrd*+ ; then increment (but trash TABLAT) | |
307 movwf TABLAT ; Then restore copy to TABLAT. | |
308 else | |
309 tblrd*+ ; Normal read... | |
310 movf TABLAT,W ; Store copy to WREG | |
311 endif | |
312 btfss aa_antialias ; Antialiased font ? | |
313 bra aa_decode_10 ; No: always 7 bits count | |
314 bn aa_decode_10 ; Non-white pixels ? | |
315 andlw 0x1F ; Yes : 5 bits count. | |
316 aa_decode_10: | |
317 andlw 0x7F ; No: 7 bit count. | |
318 incf WREG | |
319 movwf aa_bitlen ; repetition count --> aa_bitlen | |
320 | |
321 ;---- COLOR DECODING ------------------------------------------------- | |
322 ; | |
323 ; Code Normal Inverse | |
324 ; 1xx 0% 100% : Managed by aa_decode_13 | |
325 ; 011 25% 75% | |
326 ; 010 50% 50% | |
327 ; 001 75% 25% | |
328 ; 000 100% 0% : Managed by aa_decode_13 too. | |
329 ; | |
330 movf TABLAT,W ; Get back code | |
331 btfss aa_antialias ; Antialiased font ? | |
332 bra aa_decode_13 ; NO: 1bit case | |
333 | |
334 ; Asymetry test: 1xx code is another case for 1bit color. | |
335 ; This have to be done before inverse video, because | |
336 ; of the asymetric processing ! | |
337 bn aa_decode_13 ; decode as not-aa | |
338 | |
339 ; Manage 000 special case too: | |
340 andlw 0xE0 ; Select color bits | |
341 bz aa_decode_13 ; That's a 000 ! | |
342 | |
343 ; Apply reverse video, in a reversed way | |
189
e79bc535ef9e
ignore un-calibrated sensors even if they become valid
heinrichsweikamp
parents:
0
diff
changeset
|
344 btfss win_invert ; Inverse video mode ? |
0 | 345 sublw 0x80 |
346 | |
347 ; Move the two bits to aa_color_half and aa_color_quarter: | |
348 swapf WREG ; --> 0000.0LL0 byte | |
349 iorlw b'001' ; We are in AA mode, don't forget it ! | |
350 movwf aa_flags ; save that to aa_color_(half/quad)/AA flags. | |
351 | |
352 ;---- 2 bit x RGB(16bits) computation -------------------------------- | |
353 clrf PRODL ; We will accumulate result here... | |
354 clrf PRODH | |
355 | |
356 ; Take color div 2 into aa_temp. Max red = 15/31 | |
357 rrcf win_color1,W,BANKED ; xRRRRxGG | |
358 andlw b'01111011' ; 0RRRR0GG (don't change C) | |
359 movwf aa_temp+0 | |
360 rrcf win_color2,W,BANKED ; GGGxBBBB | |
361 andlw b'11101111' ; GGG0BBBB | |
362 movwf aa_temp+1 | |
363 | |
364 btfss aa_color_half | |
365 bra aa_decode_12 | |
366 | |
367 movff aa_temp+0,PRODH ; Add color/2 if bit set. | |
368 movff aa_temp+1,PRODL ; TFT is big endian, so swap here. | |
369 aa_decode_12: | |
370 btfss aa_color_quart | |
371 bra aa_decode_3 | |
372 | |
373 ; Divide it once again by 2. Max red = 7/31. | |
374 rrcf aa_temp+0,W ; xxRRRxxG | |
375 andlw b'00111001' ; 00RRR00G (don't change C) | |
376 movwf aa_temp+0 | |
377 rrcf aa_temp+1,W ; GGGxxBBB | |
378 andlw b'11100111' ; GGG00BBB | |
379 movwf aa_temp+1 | |
380 | |
381 movf aa_temp+1,W ; Add color/4 | |
382 addwf PRODL,F ; NOTE: 7/31+15/31=22/31, | |
383 movf aa_temp+0,W ; hence composants won't overlap. | |
384 addwfc PRODH,F ; In right order, to propagate carry. | |
385 | |
386 bra aa_decode_3 ; Done. | |
387 | |
388 ; ---- Simple BLACK and WHITE cases ------------------------------ | |
389 aa_decode_13: ; Got a 1xx or a 000 code... | |
189
e79bc535ef9e
ignore un-calibrated sensors even if they become valid
heinrichsweikamp
parents:
0
diff
changeset
|
390 btfsc win_invert ; Inverse video mode ? |
0 | 391 xorlw 0x80 ; YES: invert levels. |
392 bn aa_decode_2 ; Then test high bit. | |
393 | |
394 ; WHITE pixel (ie. full color) | |
395 bsf tft_rs,0 ; RS_H ; Data | |
396 movff win_color1,PORTA ; current draw color | |
397 movff win_color2,PORTH ; (rem: TFT is big endian) | |
398 bra aa_decode_4 | |
399 | |
400 aa_decode_2: | |
401 bsf tft_rs,0 ; RS_H ; Data | |
402 clrf PORTA ; BLACK pixel | |
403 clrf PORTH | |
404 bra aa_decode_4 | |
405 | |
406 aa_decode_3: | |
407 bsf tft_rs,0 ; RS_H ; Data | |
408 movff PRODH,PORTA ; Move high byte to PORTA | |
409 movff PRODL,PORTH ; Move low byte to PORTH | |
410 aa_decode_4: | |
411 ;---- PIXEL WRITE LOOP ----------------------------------------------- | |
412 bcf tft_nwr,0 ; WR_L | |
413 bsf tft_nwr,0 ; WR_H ; Tick | |
414 | |
415 decf aa_bitlen,F | |
416 bnz aa_decode_4 | |
417 | |
418 ;---- BYTE-CODE LOOP ------------------------------------------------- | |
419 ; Are we done ? | |
420 movf TBLPTRL,W ; Compare TBLPTR to aa_end | |
421 cpfseq aa_end+0 | |
422 bra aa_decode_1 ; Loop if LOW is different | |
423 movf TBLPTRH,W | |
424 cpfseq aa_end+1 ; Loop to if HIGH is different | |
425 bra aa_decode_1 | |
426 | |
427 return | |
428 | |
429 ;------------------------------------------------------------------------------ | |
430 ; Setup pointers for a char: | |
431 ; Inputs : buffer : string to print (SHOULD BE NULL TERMINATED) | |
432 ; Output : TFT commands on port D + clocks. | |
433 ; | |
434 global aa_wordprocessor ; Callable from C-code. | |
435 aa_wordprocessor: | |
436 banksel win_font ; Bank1, just to be sure. | |
437 rcall aa_string_width ; Set win_height, compute win_width | |
438 call TFT_box_write ; Use that for the box. | |
439 | |
440 ; Restart the loop for each char to print | |
441 lfsr FSR2, buffer ; FSR2 pointer to start of string. | |
442 | |
443 ; DATA bloc commande: | |
444 Index_out 0x22 | |
445 | |
446 aa_wordprocessor_1: | |
447 movf POSTINC2,W ; WREG = *FSR2++ | |
448 bz aa_wordprocessor_99 ; Exit if null byte encountered. | |
449 | |
450 rcall aa_char_setup ; setup aa_start / aa_end | |
451 rcall aa_decode_char ; write pixels to screen | |
452 bra aa_wordprocessor_1 ; and loop. | |
453 | |
454 aa_wordprocessor_99: | |
455 ; END of bloc commande | |
456 Index_out 0x00 | |
457 | |
458 return | |
459 END |