Mercurial > public > hwos_code
annotate src/aa_wordprocessor.asm @ 223:940155e9aefb
PC config, 1.72 release
| author | heinrichsweikamp |
|---|---|
| date | Wed, 14 Jan 2015 11:37:19 +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 |
