0
+ − 1 ;=============================================================================
+ − 2 ;
+ − 3 ; File tft.asm
+ − 4 ;
+ − 5 ; Managing the TFT screen
+ − 6 ;
+ − 7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
+ − 8 ;=============================================================================
+ − 9 ; HISTORY
+ − 10 ; 2011-05-24 : [jDG] Cleanups from initial Matthias code.
+ − 11
275
+ − 12 #include "hwos.inc"
0
+ − 13 #include "wait.inc"
+ − 14 #include "varargs.inc"
+ − 15 #include "external_flash.inc"
+ − 16 #include "tft_outputs.inc"
+ − 17 #include "eeprom_rs232.inc"
+ − 18
+ − 19 ;=============================================================================
+ − 20 ; TFT_frame needs to backup coordinates.
+ − 21 CBLOCK tmp
+ − 22 save_top
+ − 23 save_height
+ − 24 save_left
+ − 25 save_width
+ − 26 ds_line ; Current line (0..239).
+ − 27 ds_column ; Current columnx2 (0..159)
+ − 28 ds_pixel:2 ; Current pixel color.
+ − 29 ds_count ; Repetition count.
+ − 30 ENDC
+ − 31
+ − 32 ;=============================================================================
+ − 33 ; Basic bit-level macros
+ − 34
+ − 35 RD_H macro
+ − 36 bsf tft_rd,0
+ − 37 endm
+ − 38
+ − 39 RD_L macro
+ − 40 bcf tft_rd,0
+ − 41 endm
+ − 42
+ − 43 RS_H macro
+ − 44 bsf tft_rs,0
+ − 45 endm
+ − 46
+ − 47 RS_L macro
+ − 48 bcf tft_rs,0
+ − 49 endm
+ − 50
+ − 51 NCS_H macro
+ − 52 bsf tft_cs,0
+ − 53 endm
+ − 54
+ − 55 NCS_L macro
+ − 56 bcf tft_cs,0
+ − 57 endm
+ − 58
+ − 59 WR_H macro
+ − 60 bsf tft_nwr,0
+ − 61 endm
+ − 62
+ − 63 WR_L macro
+ − 64 bcf tft_nwr,0
+ − 65 endm
+ − 66
+ − 67 ;=============================================================================
+ − 68 ; Byte-leve macros
+ − 69 ;
+ − 70 Index_out macro low_b
+ − 71 movlw low_b
+ − 72 rcall TFT_CmdWrite
+ − 73 endm
+ − 74
+ − 75 Parameter_out macro high_b, low_b
+ − 76 movlw high_b
+ − 77 movwf PORTA ; Upper
+ − 78 movlw low_b
+ − 79 rcall TFT_DataWrite
+ − 80 endm
+ − 81
+ − 82
+ − 83 basic CODE
151
+ − 84 ;
+ − 85 ;
+ − 86 ;;=============================================================================
+ − 87 ;; TFT_write_flash_image
+ − 88 ;;
+ − 89 ;; Inputs: FSR2 = EEPROM address / 256
+ − 90 ;; win_left, win_top : imagte CENTER position
+ − 91 ;; Outputs: win_height, win_width.
+ − 92 ;; image copyed on screen.
+ − 93 ;; Trashed: PROD, hi, lo
+ − 94 ;;
+ − 95 ; global TFT_write_flash_image
+ − 96 ;TFT_write_flash_image:
+ − 97 ; ; Get back the full 24bit EEPROM address
+ − 98 ; clrf ext_flash_address+0
+ − 99 ; movff FSR2L,ext_flash_address+1
+ − 100 ; movf FSR2H,W
+ − 101 ; iorlw 0x30
+ − 102 ; movwf ext_flash_address+2
+ − 103 ;
+ − 104 ; ; Read header: width and height
+ − 105 ; global TFT_write_flash_image_addr
+ − 106 ;TFT_write_flash_image_addr:
+ − 107 ; call ext_flash_read_block_start
+ − 108 ; movff SSP2BUF,win_width+0
+ − 109 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 110 ; btfss SSP2STAT, BF ; Next byte ready ?
+ − 111 ; bra $-2 ; NO: wait...
+ − 112 ; movff SSP2BUF,win_width+1
+ − 113 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 114 ; btfss SSP2STAT, BF ; Next byte ready ?
+ − 115 ; bra $-2 ; NO: wait...
+ − 116 ; movff SSP2BUF,win_height
+ − 117 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 118 ; btfss SSP2STAT, BF ; Next byte ready ?
+ − 119 ; bra $-2 ; NO: wait...
+ − 120 ; movff SSP2BUF,WREG ; drop 4th byte.
+ − 121 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 122 ; btfss SSP2STAT, BF ; Next byte ready ?
+ − 123 ; bra $-2 ; NO: wait...
+ − 124 ;
+ − 125 ; ; Sanity check on header to avoid badly uploaded images.
+ − 126 ; iorwf WREG ; Check height < 256
+ − 127 ; bnz TFT_write_flash_image_failed
+ − 128 ; movf win_width+1,W ; Check width < 512
+ − 129 ; andlw 0xFE
+ − 130 ; bnz TFT_write_flash_image_failed
+ − 131 ;
+ − 132 ; ; Center image on win_top, win_left values
+ − 133 ; bcf STATUS,C ; Clear carry
+ − 134 ; rrcf win_height,W ; And get height/2
+ − 135 ; subwf win_top,F ; top -= height/2
+ − 136 ; rrcf win_width+1,W ; Get 9th bit into carry
+ − 137 ; rrcf win_width+0,W ; Get width/2 (in 0..320 range)
+ − 138 ; bcf STATUS,C
+ − 139 ; rrcf WREG,W ; Get width/2 in 0..160 range
+ − 140 ; subwf win_leftx2,F ; left -= width/2
+ − 141 ;
+ − 142 ; rcall TFT_box_write ; Inputs : win_top, win_leftx2, win_height, win_width(in 1..320 range)
0
+ − 143 ;
151
+ − 144 ; ; Compute number of pixels to move (result on 17 bits !)
+ − 145 ; clrf TBLPTRU
+ − 146 ; movf win_width+0,W
+ − 147 ; mulwf win_height ; Result in PRODL:H
+ − 148 ; movf win_width+1,W
+ − 149 ; bz TFT_write_flash_image_1 ; width > 8bits ?
+ − 150 ; movf win_height,W ; YES: add extra
+ − 151 ; addwf PRODH,F
+ − 152 ; rlcf TBLPTRU ; And carry into upper register.
+ − 153 ;TFT_write_flash_image_1:
+ − 154 ; incf PRODH,F ; Pre-condition nested loops
+ − 155 ; incf TBLPTRU,F
+ − 156 ;
+ − 157 ; ; Write pixels
+ − 158 ; Index_out 0x22 ; Frame Memory Data Write start
+ − 159 ; RS_H ; Data
+ − 160 ;
+ − 161 ;TFT_write_flash_image_loop:
+ − 162 ; btfss SSP2STAT, BF ; Buffer full?
+ − 163 ; bra $-2 ; NO: wait...
+ − 164 ; movff SSP2BUF,PORTH ; Read lo
+ − 165 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 166 ;
+ − 167 ; btfss SSP2STAT, BF ; Buffer full?
+ − 168 ; bra $-2 ; NO: wait...
+ − 169 ; movff SSP2BUF,PORTA ; And read hi
+ − 170 ; movwf SSP2BUF ; Write to buffer to initiate new read
+ − 171 ; WR_L
+ − 172 ; WR_H ; Write 1 Pixel
+ − 173 ;
+ − 174 ; decfsz PRODL,F
+ − 175 ; bra TFT_write_flash_image_loop
+ − 176 ; decfsz PRODH,F
+ − 177 ; bra TFT_write_flash_image_loop
+ − 178 ; decfsz TBLPTRU,F
+ − 179 ; bra TFT_write_flash_image_loop
+ − 180 ;
+ − 181 ; btfss SSP2STAT, BF ; Buffer full?
+ − 182 ; bra $-2 ; No, wait
+ − 183 ; movf SSP2BUF,W ; Read dummy byte
+ − 184 ;
+ − 185 ; bsf flash_ncs ; CS=1
+ − 186 ; movlw 0x00 ; NOP, to stop window mode
+ − 187 ; bra TFT_CmdWrite ; This routine "returns"
+ − 188 ;
+ − 189 ; ;---- Draw a 4x4 red square in place of missing images...
+ − 190 ;TFT_write_flash_image_failed:
+ − 191 ; movlw -1
+ − 192 ; addwf win_leftx2,F
+ − 193 ; movlw -2
+ − 194 ; addwf win_top,F
+ − 195 ; movlw 2
+ − 196 ; movwf win_width+0
+ − 197 ; clrf win_width+1
+ − 198 ; movlw 4
+ − 199 ; movwf win_height
+ − 200 ; movlw color_red
+ − 201 ; rcall TFT_set_color
+ − 202 ; goto TFT_box
+ − 203 ;
+ − 204 ;;=============================================================================
0
+ − 205 ;
+ − 206
+ − 207 global TFT_CmdWrite
+ − 208 TFT_CmdWrite:
+ − 209 RS_L ; Command
+ − 210 clrf PORTA ; Upper
+ − 211 movwf PORTH ; Lower
+ − 212 WR_L
+ − 213 WR_H ; Tick
+ − 214 return;
+ − 215
+ − 216 global TFT_DataWrite
+ − 217 TFT_DataWrite:
+ − 218 RS_H ; Data
+ − 219 movwf PORTH ; Lower
+ − 220 WR_L
+ − 221 WR_H ; Tick
+ − 222 return
+ − 223
+ − 224 ;=============================================================================
+ − 225 ;
+ − 226 global TFT_ClearScreen
+ − 227 TFT_ClearScreen:
+ − 228 Index_out 0x50 ; Window Horizontal Start Address
+ − 229 Parameter_out 0x00, 0x00 ; 0-239
+ − 230 Index_out 0x51 ; Window Horizontal End Address
+ − 231 Parameter_out 0x00, 0xEF ; 0-239
+ − 232 Index_out 0x52 ; Window Vertical Start Address
+ − 233 Parameter_out 0x00, 0x00 ; 0-319
+ − 234 Index_out 0x53 ; Window Vertical End Address
+ − 235 Parameter_out 0x01, 0x3F ; 0-319
+ − 236 Index_out 0x20 ; Frame Memory Horizontal Address
+ − 237 Parameter_out 0x00, 0x00 ; 0-239
+ − 238 Index_out 0x21 ; Frame Memory Vertical Address
+ − 239 Parameter_out 0x01, 0x3F ; 0-319
+ − 240
+ − 241 Index_out 0x22 ; Frame Memory Data Write start
+ − 242
+ − 243 RD_H ; Not Read
+ − 244 RS_H ; Data
+ − 245 NCS_L ; Not CS
+ − 246 clrf PORTH ; Data Lower
+ − 247
+ − 248 movlw d'10'
+ − 249 movwf tft_temp3
+ − 250 TFT_ClearScreen2:
+ − 251 movlw d'30'
+ − 252 movwf tft_temp2
+ − 253 TFT_ClearScreen3:
+ − 254 clrf tft_temp1 ; 30*10*256=76800 Pixels -> Clear complete 240*320
+ − 255 TFT_ClearScreen4:
+ − 256 WR_L
+ − 257 WR_H ; Tick
+ − 258 decfsz tft_temp1,F
+ − 259 bra TFT_ClearScreen4
+ − 260 decfsz tft_temp2,F
+ − 261 bra TFT_ClearScreen3
+ − 262 decfsz tft_temp3,F
+ − 263 bra TFT_ClearScreen2
+ − 264 return
+ − 265
+ − 266 ;=============================================================================
+ − 267 ;
+ − 268 global TFT_DisplayOff
+ − 269 TFT_DisplayOff:
+ − 270 clrf CCPR1L ; PWM OFF
+ − 271 clrf PORTA
+ − 272 clrf PORTH
+ − 273 RD_L ; LOW
+ − 274 nop
+ − 275 RS_L ; LOW
+ − 276 bcf tft_nwr
+ − 277 nop
+ − 278 bcf tft_cs
+ − 279 nop
+ − 280 bcf tft_nreset
+ − 281 WAITMS d'1'
+ − 282 bsf tft_power ; inverted...
+ − 283 bcf lightsen_power ; power-down light sensor
+ − 284 return
+ − 285
+ − 286 ; -----------------------------
+ − 287 ; TFT boot
+ − 288 ; -----------------------------
+ − 289 global TFT_boot
+ − 290 TFT_boot:
+ − 291 clrf PORTA
+ − 292 clrf PORTH
+ − 293 RD_L ; LOW
+ − 294 bcf tft_nwr
+ − 295 nop
+ − 296 bcf tft_cs
+ − 297 nop
+ − 298 bcf tft_nreset
+ − 299 WAITMS d'1'
+ − 300 bcf tft_power ; inverted...
+ − 301 WAITMS d'1'
+ − 302
+ − 303 RD_H ; Keep high
+ − 304 WR_H ;
+ − 305 NCS_L ; Not CS
+ − 306
+ − 307 WAITMS d'2'
+ − 308 bsf tft_nreset
+ − 309 WAITMS d'150'
+ − 310 bsf lightsen_power ; Supply power to light sensor
+ − 311
+ − 312 ; Data Transfer Synchronization
+ − 313 Parameter_out 0x00, 0x00
+ − 314 Parameter_out 0x00, 0x00
+ − 315
360
+ − 316 Index_out 0x00
+ − 317 rcall TFT_CmdRead_PROD ; Get ID into PRODL:PRODH
+ − 318 ; 5:197 -> display0
361
+ − 319 ;37:147 -> display1
360
+ − 320 movlw .5
+ − 321 cpfseq PRODL ; display0?
+ − 322 bra TFT_boot_1 ; No
+ − 323 movlw .197
+ − 324 cpfseq PRODH ; display0?
+ − 325 bra TFT_boot_1 ; No
312
+ − 326
0
+ − 327 ; Init through config table...
+ − 328 movlw LOW display0_config_table
+ − 329 movwf TBLPTRL
+ − 330 movlw HIGH display0_config_table
+ − 331 movwf TBLPTRH
+ − 332 movlw UPPER display0_config_table
+ − 333 movwf TBLPTRU
360
+ − 334 bcf screen_type
+ − 335 bra TFT_boot_com
+ − 336
+ − 337 TFT_boot_1:
+ − 338 ; Init through config table...
363
+ − 339 movlw 0x74
360
+ − 340 movwf TBLPTRL
363
+ − 341 movlw 0xF7
360
+ − 342 movwf TBLPTRH
363
+ − 343 movlw 0x01
360
+ − 344 movwf TBLPTRU
+ − 345 bsf screen_type
+ − 346
+ − 347 TFT_boot_com:
0
+ − 348 rcall display0_init_loop
+ − 349
152
+ − 350 Index_out 0x03
+ − 351 btfsc flip_screen ; 180° rotation ?
+ − 352 bra TFT_boot2 ; Yes
360
+ − 353
+ − 354 btfss screen_type ; display1?
+ − 355 bra TFT_boot1a ; no
+ − 356 Parameter_out 0x10, 0x00 ; display1
+ − 357 bra TFT_boot3
+ − 358 TFT_boot1a:
+ − 359 Parameter_out 0x50, 0x20 ; display0
152
+ − 360 bra TFT_boot3
+ − 361 TFT_boot2:
360
+ − 362 btfss screen_type ; display1?
+ − 363 bra TFT_boot2a ; no
+ − 364 Parameter_out 0x10, 0x30 ; display1
+ − 365 bra TFT_boot3
+ − 366 TFT_boot2a:
+ − 367 Parameter_out 0x50, 0x10 ; display0
152
+ − 368 TFT_boot3:
0
+ − 369 Index_out 0x22
225
+ − 370 rcall TFT_ClearScreen
0
+ − 371 Index_out 0x07
312
+ − 372 Parameter_out 0x01, 0x33
0
+ − 373 return
+ − 374
+ − 375 display0_config_table:
+ − 376 ; Reg, Dat0, Dat1 or 0xFF,0x00,0x00 for end
+ − 377 db 0xA4,0x00,0x01,0xFF,.002,0x00
+ − 378 db 0x09,0x00,0x01,0x92,0x04,0x00
+ − 379 db 0x93,0x04,0x02,0x94,0x00,0x02
+ − 380 db 0x07,0x00,0x00,0x10,0x04,0x30
+ − 381 db 0x11,0x02,0x37,0x12,0x11,0x8D
+ − 382 db 0x13,0x11,0x00,0x01,0x01,0x00
+ − 383 db 0x02,0x02,0x00,0x03,0x50,0x20
+ − 384 db 0x0A,0x00,0x08,0x0D,0x00,0x00
+ − 385 db 0x0E,0x00,0x30,0xFF,.151,0x00
+ − 386 db 0x12,0x11,0xBD,0x20,0x00,0x00
+ − 387 db 0x21,0x00,0x00,0x30,0x06,0x02
+ − 388 db 0x31,0x56,0x0D,0x32,0x05,0x07
+ − 389 db 0x33,0x06,0x09,0x34,0x00,0x00
+ − 390 db 0x35,0x09,0x06,0x36,0x57,0x05
+ − 391 db 0x37,0x0D,0x06,0x38,0x02,0x06
+ − 392 db 0x39,0x00,0x00,0xFF,0x00,0x00
+ − 393
+ − 394 display0_init_loop:
+ − 395 TBLRD*+
+ − 396 movlw 0xFF
+ − 397 cpfseq TABLAT
+ − 398 bra display0_config_write ; Write Config pair to Display
+ − 399 ; Delay ms or quit (return)
+ − 400 TBLRD*+
+ − 401 tstfsz TABLAT ; End of config?
+ − 402 bra $+4 ; No
+ − 403 return ; Done.
+ − 404 movf TABLAT,W
+ − 405 call WAITMSX ; Wait WREG milliseconds
+ − 406 TBLRD*+ ; Dummy read (Third byte of delay command)
+ − 407 bra display0_init_loop ; Loop
+ − 408
+ − 409 display0_config_write: ; With command in WREG
+ − 410 movf TABLAT,W
+ − 411 rcall TFT_CmdWrite ; Write command
+ − 412 TBLRD*+ ; Get config0
+ − 413 movff TABLAT,PORTA
+ − 414 TBLRD*+ ; Get config1
+ − 415 movf TABLAT,W
+ − 416 rcall TFT_DataWrite ; Write config
+ − 417 bra display0_init_loop ; Loop
+ − 418
+ − 419
+ − 420 ;=============================================================================
+ − 421 ; Smooth lighting-up of the display:
+ − 422 ;
+ − 423 ; Trashes: WREG, PRODL
+ − 424 ; Typical usage:
+ − 425 ; clrf CCPR1L ; Backlight off
+ − 426 ; [draw splash screen]
+ − 427 ; call TFT_DisplayFadeIn
+ − 428 ;
+ − 429 global TFT_Display_FadeIn
+ − 430 TFT_Display_FadeIn:
275
+ − 431 movlw CCP1CON_VALUE ; See hwos.inc
0
+ − 432 movwf CCP1CON
+ − 433 bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor!
+ − 434 clrf CCPR1L ; Backlight off - to be sure
+ − 435 movff max_CCPR1L,PRODL
+ − 436 TFT_Display_FadeIn_0:
+ − 437 incf CCPR1L,F ; Duty cycle
+ − 438 WAITMS d'2'
+ − 439 decfsz PRODL,F
+ − 440 bra TFT_Display_FadeIn_0
+ − 441 bcf tft_is_dimming ; dimming done.
+ − 442 return
+ − 443
+ − 444 ;=============================================================================
+ − 445 ; Smooth lighting-off of the display:
+ − 446 ; Trashes: WREG, PRODL
+ − 447 global TFT_Display_FadeOut
+ − 448 TFT_Display_FadeOut:
+ − 449 movff max_CCPR1L,PRODL
+ − 450 bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor!
+ − 451 TFT_Display_FadeOut_0:
+ − 452 movff PRODL,CCPR1L ; Duty cycle
+ − 453 WAITMS d'1'
+ − 454 decfsz PRODL,F
+ − 455 bra TFT_Display_FadeOut_0
+ − 456 clrf CCPR1L
+ − 457 return
+ − 458
+ − 459 ;=============================================================================
+ − 460
+ − 461 global box_std_block, box_black_block, box_color_block
+ − 462
+ − 463 box_std_block: ; Use white color
+ − 464 setf WREG
+ − 465 bra box_common
+ − 466 box_black_block: ; Use black color
+ − 467 clrf WREG
+ − 468 box_common:
+ − 469 box_color_block:
+ − 470 rcall TFT_set_color
+ − 471 VARARGS_BEGIN
+ − 472 VARARGS_GET8 win_top
+ − 473 VARARGS_GET8 win_height
+ − 474 VARARGS_GET8 win_leftx2
+ − 475 VARARGS_GET8 win_width
+ − 476 VARARGS_END
+ − 477 bra TFT_box
+ − 478
+ − 479 ;-----------------------------------------------------------------------------
+ − 480
+ − 481 global box_frame_std, box_frame_common, box_frame_color, box_frame_color16
+ − 482
+ − 483 box_frame_std:
+ − 484 setf WREG
+ − 485 rcall TFT_set_color
+ − 486
+ − 487 box_frame_common:
+ − 488 VARARGS_BEGIN
+ − 489 VARARGS_GET8 win_top
+ − 490 VARARGS_GET8 win_height
+ − 491 VARARGS_GET8 win_leftx2
+ − 492 VARARGS_GET8 win_width
+ − 493 VARARGS_END
+ − 494 bra TFT_frame
+ − 495
+ − 496 box_frame_color:
+ − 497 rcall TFT_set_color
+ − 498 box_frame_color16:
+ − 499 bra box_frame_common
+ − 500
+ − 501 ;=============================================================================
+ − 502 ; Init for half_pixel_write
+ − 503 ; Set column register on TFT device, and current color.
+ − 504 ; Inputs: win_leftx2
+ − 505 ; Outputs: win_color:2
+ − 506 ; Trashed: WREG, PROD
+ − 507 global init_pixel_write
+ − 508 init_pixel_write:
+ − 509 movff win_leftx2,WREG
+ − 510 mullw 2
+ − 511 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 512 setf WREG
+ − 513 bra TFT_set_color
+ − 514
+ − 515 ;-----------------------------------------------------------------------------
+ − 516 ; Writes two half-pixels at position (win_top,win_leftx2)
+ − 517 ; Inputs: win_leftx2, win_top, win_color:2
+ − 518 ; Trashed: WREG, PROD
+ − 519 global pixel_write
+ − 520 pixel_write:
+ − 521 movff win_leftx2,WREG
+ − 522 mullw 2 ; win_leftx2 x 2 -> PRODH:PRODL
+ − 523 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 524 rcall half_pixel_write ; Write this half-one.
+ − 525
+ − 526 movff win_leftx2,WREG ; Address of next one
+ − 527 mullw 2
+ − 528 infsnz PRODL ; +1
+ − 529 incf PRODH
+ − 530 rcall pixel_write_col320
+ − 531 bra half_pixel_write ; Note: Cmd 0x20 is mandatory, because
+ − 532 ; of the autoincrement going vertical
+ − 533
+ − 534 global pixel_write_col320
+ − 535 pixel_write_col320:
371
+ − 536 btfsc screen_type ; display1?
+ − 537 bra pixel_write_col320_d1 ; Yes
+ − 538 ; Display0
+ − 539 btfss flip_screen ; 180° rotation?
+ − 540 bra pixel_write_noflip_H ; No
+ − 541 bra pixel_write_flip_H ; Yes
+ − 542 pixel_write_col320_d1: ; Display1
+ − 543 btfsc flip_screen ; 180° rotation?
+ − 544 bra pixel_write_noflip_H ; Yes for d1
+ − 545 pixel_write_flip_H: ; Flip d0
151
+ − 546 movf PRODL,W ; 16bits 319 - PROD --> PROD
+ − 547 sublw LOW(.319) ; 319-W --> W
+ − 548 movwf PRODL
+ − 549 movf PRODH,W
+ − 550 btfss STATUS,C ; Borrow = /CARRY
+ − 551 incf WREG
+ − 552 sublw HIGH(.319)
+ − 553 movwf PRODH
+ − 554
+ − 555 pixel_write_noflip_H:
0
+ − 556 Index_out 0x21 ; Frame Memory Vertical Address
371
+ − 557 bra TFT_DataWrite_PROD ; and return...
0
+ − 558
+ − 559 ;-----------------------------------------------------------------------------
+ − 560 ; Writes one half-pixel at position (win_top,win_leftx2).
+ − 561 ; Inputs: win_leftx2, win_top, win_color:2
+ − 562 ; Trashed: WREG, PROD
+ − 563 global half_pixel_write
+ − 564 half_pixel_write:
+ − 565 movff win_top,WREG ; d'0' ... d'239'
+ − 566 ; Variant with Y position in WREG.
+ − 567 half_pixel_write_1:
151
+ − 568 btfss flip_screen ; 180° rotation?
+ − 569 sublw .239 ; 239-Y --> Y
371
+ − 570 mullw 1 ; Copy row to PRODL (PRODH=0)
+ − 571 Index_out 0x20 ; Frame Memory Horizontal Address
0
+ − 572 rcall TFT_DataWrite_PROD
+ − 573
371
+ − 574 Index_out 0x22 ; Frame Memory Data Write start
0
+ − 575 RS_H ; Data
+ − 576 movff win_color1,PORTA ; Upper
+ − 577 movff win_color2,PORTH ; Lower
+ − 578 WR_L
+ − 579 WR_H ; Tick
+ − 580 return
+ − 581
+ − 582 ;-----------------------------------------------------------------------------
+ − 583 ; Writes a vertical line of half-pixel at position (win_top,win_leftx2,win_height).
+ − 584 ; Inputs: win_leftx2, win_top, win_height, win_color:2
+ − 585 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
+ − 586 global half_vertical_line
+ − 587 half_vertical_line:
+ − 588 clrf TABLAT ; Loop index.
+ − 589
+ − 590 half_vertical_line_loop:
+ − 591 movff win_leftx2,WREG ; Init X position.
+ − 592 mullw 2
+ − 593 movf TABLAT,W ; Get loop index
+ − 594 andlw 1 ; Just low bit
+ − 595 xorwf PRODL,F ; And use it to jitter current X position
+ − 596 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 597
+ − 598 movff win_height,WREG ; Index reached height (Bank0 read) ?
+ − 599 xorwf TABLAT,W
+ − 600 btfsc STATUS,Z ; Equals ?
+ − 601 return ; Yes: done.
+ − 602 movff win_top,WREG ; Y = top + index (Bank0 read)
+ − 603 addwf TABLAT,W
+ − 604 rcall half_pixel_write_1
+ − 605 incf TABLAT,F ; index++
+ − 606 bra half_vertical_line_loop
+ − 607
+ − 608 ;-----------------------------------------------------------------------------
+ − 609 ; Writes a horizontal line of half-pixel at position (win_top,win_leftx2,win_width).
+ − 610 ; Inputs: win_leftx2, win_top, win_width, win_color:2
+ − 611 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
+ − 612 global half_horizontal_line
+ − 613 half_horizontal_line:
+ − 614 clrf TABLAT ; Loop index.
+ − 615
+ − 616 half_horizontal_line_loop:
+ − 617 movff win_leftx2,WREG ; Init X position.
+ − 618 mullw 2
+ − 619 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 620 movff win_width,WREG ; Index reached height (Bank0 read) ?
+ − 621 xorwf TABLAT,W
+ − 622 btfsc STATUS,Z ; Equals ?
+ − 623 return ; Yes: done.
+ − 624 movff win_top,WREG ; Y = top + index (Bank0 read)
+ − 625 addwf TABLAT,W
+ − 626 rcall half_pixel_write_1
+ − 627 incf TABLAT,F ; index++
+ − 628 bra half_horizontal_line_loop
+ − 629
+ − 630
+ − 631 ;-----------------------------------------------------------------------------
+ − 632 ; TFT Data Cmd via W
+ − 633 ;
+ − 634 global TFT_DataWrite_PROD
+ − 635 TFT_DataWrite_PROD:
+ − 636 ; RD_H ; Keep high
+ − 637 RS_H ; Data
+ − 638 movff PRODH,PORTA ; Move high byte to PORTA
+ − 639 movff PRODL,PORTH ; Move low byte to PORTH
+ − 640 WR_L
+ − 641 WR_H ; Tick
+ − 642 return
+ − 643
+ − 644 TFT_DataRead_PROD:
+ − 645 Index_out 0x22 ; Frame Memory Data Read start
360
+ − 646 TFT_CmdRead_PROD:
0
+ − 647 setf TRISA ; PortA as input.
+ − 648 setf TRISH ; PortH as input.
+ − 649 RS_H ; Data
366
+ − 650 ; WR_H ; Not write
0
+ − 651 RD_L ; Read!
+ − 652 nop
+ − 653 nop
+ − 654 nop
+ − 655 RD_H ; Tick
+ − 656 nop
366
+ − 657 nop
+ − 658 nop
0
+ − 659 RD_L ; Read!
+ − 660 nop
366
+ − 661 ; nop
+ − 662 ; nop
0
+ − 663 movff PORTA,PRODH
+ − 664 movff PORTH,PRODL
+ − 665 RD_H ; Tick
+ − 666 nop
+ − 667 clrf TRISA ; PortA as output
+ − 668 clrf TRISH ; PortH as output
+ − 669 return
+ − 670
+ − 671 ;=============================================================================
+ − 672 ; Output TFT Window Address commands.
+ − 673 ; Inputs : win_top, win_leftx2, win_height, win_width.
+ − 674 ; Output : PortA/PortH commands.
+ − 675 ; Trashed: PROD
+ − 676 ;
+ − 677 global TFT_box_write
+ − 678 TFT_box_write:
+ − 679 movff win_leftx2,WREG ; Compute left = 2*leftx2 --> PROD
+ − 680 mullw 2
+ − 681
152
+ − 682 global TFT_box_write_16bit_win_left
+ − 683 TFT_box_write_16bit_win_left: ; With column in PRODL:PRODH
361
+ − 684 btfsc screen_type ; display1?
+ − 685 bra TFT_box_write_16bit_win_left_d1 ; Yes
+ − 686 ; Display0
+ − 687 btfsc flip_screen ; 180° rotation?
151
+ − 688 bra DISP_box_flip_H ; Yes
361
+ − 689 bra TFT_box_write_16bit_win_left_com ; No
+ − 690 TFT_box_write_16bit_win_left_d1: ; Display1
+ − 691 btfss flip_screen ; 180° rotation?
370
+ − 692 bra DISP_box_flip_H ; No for d1
+ − 693 ; Yes for d1
361
+ − 694 TFT_box_write_16bit_win_left_com:
0
+ − 695 ;---- Normal horizontal window ---------------------------------------
+ − 696 Index_out 0x52 ; Window Vertical Start Address
+ − 697 rcall TFT_DataWrite_PROD ; Output left
+ − 698 Index_out 0x21 ; Frame Memory Vertical Address
+ − 699 rcall TFT_DataWrite_PROD ; Output left
+ − 700
+ − 701 movff win_width+0,WREG ; right = left + width - 1
+ − 702 addwf PRODL,F
+ − 703 movff win_width+1,WREG
+ − 704 addwfc PRODH,F
+ − 705 decf PRODL,F ; decrement result
+ − 706 btfss STATUS,C
+ − 707 decf PRODH,F
+ − 708
+ − 709 Index_out 0x53 ; Window Vertical End Address
+ − 710 rcall TFT_DataWrite_PROD
151
+ − 711 bra DISP_box_noflip_H
0
+ − 712
151
+ − 713 ;---- Flipped horizontal window --------------------------------------
+ − 714 DISP_box_flip_H:
+ − 715 movf PRODL,W ; 16bits 319 - PROD --> PROD
+ − 716 sublw LOW(.319) ; 319-W --> W
+ − 717 movwf PRODL
+ − 718 movf PRODH,W
+ − 719 btfss STATUS,C ; Borrow = /CARRY
+ − 720 incf WREG
+ − 721 sublw HIGH(.319)
+ − 722 movwf PRODH
152
+ − 723
371
+ − 724 Index_out 0x53 ; Window Vertical Start Address
152
+ − 725 rcall TFT_DataWrite_PROD ; Output left
151
+ − 726 Index_out 0x21 ; Frame Memory Vertical Address
152
+ − 727 rcall TFT_DataWrite_PROD ; Output left
151
+ − 728
152
+ − 729 movff win_width+0,WREG ; 16bits PROD - width --> PROD
+ − 730 subwf PRODL,F ; PRODL - WREG --> PRODL
+ − 731 movff win_width+1,WREG
+ − 732 subwfb PRODH,F
+ − 733 infsnz PRODL ; PROD+1 --> PROD
+ − 734 incf PRODH
151
+ − 735
152
+ − 736 Index_out 0x52 ; Window Vertical End Address
151
+ − 737 rcall TFT_DataWrite_PROD
+ − 738
+ − 739 DISP_box_noflip_H:
+ − 740 btfss flip_screen ; 180° rotation ?
152
+ − 741 bra TFT_box_noflip_V ; No.
151
+ − 742
152
+ − 743 ;---- Flipped vertical window -----------------------------------------
+ − 744 movff win_top,PRODH ; top --> PRODH (first byte)
151
+ − 745 movff win_height,WREG
152
+ − 746 addwf PRODH,W
+ − 747 decf WREG
+ − 748 movwf PRODL ; top+height-1 --> PRODL (second byte)
151
+ − 749
+ − 750 Index_out 0x50 ; Window Horizontal Start Address
+ − 751 movf PRODH,W
+ − 752 rcall TFT_DataWrite ; Lower (and tick)
+ − 753
+ − 754 Index_out 0x51 ; Window Horizontal End Address
+ − 755 movf PRODL,W
+ − 756 rcall TFT_DataWrite ; Lower (and tick)
+ − 757
+ − 758 Index_out 0x20 ; Frame Memory Horizontal Address
152
+ − 759 movf PRODH,W
151
+ − 760 rcall TFT_DataWrite ; Lower (and tick)
+ − 761 return
+ − 762
+ − 763
152
+ − 764 TFT_box_noflip_V:
+ − 765 ;---- Normal vertical window ----------------------------------------
0
+ − 766 movff win_top,PRODL
+ − 767 movff win_height,WREG
+ − 768 addwf PRODL,W
+ − 769 sublw .240 ; 240 - top - height
+ − 770 movwf PRODH ; First byte
+ − 771
+ − 772 movf PRODL,W
151
+ − 773 sublw .239 ; 239-top
0
+ − 774 movwf PRODL ; --> second byte.
+ − 775
+ − 776 Index_out 0x50 ; Window Horizontal Start Address
+ − 777 movf PRODH,W
+ − 778 rcall TFT_DataWrite ; Lower (and tick)
+ − 779
+ − 780 Index_out 0x51 ; Window Horizontal End Address
+ − 781 movf PRODL,W
+ − 782 rcall TFT_DataWrite ; Lower (and tick)
+ − 783
+ − 784 Index_out 0x20 ; Frame Memory Horizontal Address
+ − 785 movf PRODL,W
+ − 786 rcall TFT_DataWrite ; Lower (and tick)
+ − 787 return
+ − 788
+ − 789
+ − 790 ;=============================================================================
+ − 791 ; TFT_frame : draw a frame around current box with current color.
+ − 792 ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2
+ − 793 ; Outputs: (none)
+ − 794 ; Trashed: WREG, PROD, aa_start:2, aa_end:2
+ − 795 global TFT_frame
+ − 796 TFT_frame:
+ − 797 movff win_top,save_top ; Backup everything.
+ − 798 movff win_height,save_height
+ − 799 movff win_leftx2,save_left
+ − 800 movff win_width,save_width
+ − 801
+ − 802 ;---- TOP line -----------------------------------------------------------
+ − 803 movlw 1 ; row ~ height=1
+ − 804 movff WREG,win_height
+ − 805 rcall TFT_box
+ − 806
+ − 807 ;---- BOTTOM line --------------------------------------------------------
+ − 808 movff save_top,PRODL ; Get back top,
+ − 809 movff save_height,WREG ; and height
+ − 810 addwf PRODL,W ; top+height
+ − 811 decf WREG ; top+height-1
+ − 812 movff WREG,win_top ; top+height-1 --> top
+ − 813 rcall TFT_box
+ − 814
+ − 815 ;---- LEFT column --------------------------------------------------------
+ − 816 movff save_top,win_top ; Restore top/height.
+ − 817 movff save_height,win_height
+ − 818 movlw 1 ; column ~ width=1
+ − 819 movff WREG,win_width
+ − 820 rcall TFT_box
+ − 821
+ − 822 ;---- RIGHT column -------------------------------------------------------
+ − 823 movff save_left,WREG
+ − 824 movff save_width,PRODL
+ − 825 addwf PRODL,W
+ − 826 decf WREG
+ − 827 movff WREG,win_leftx2
+ − 828 rcall TFT_box
+ − 829
+ − 830 ;---- Restore everything -------------------------------------------------
+ − 831 movff save_left,win_leftx2
+ − 832 movff save_width,win_width
+ − 833 return
+ − 834
+ − 835 ;=============================================================================
+ − 836 ; TFT_box : fills current box with current color.
+ − 837 ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2
+ − 838 ; Outputs: (none)
+ − 839 ; Trashed: WREG, PROD
+ − 840 global TFT_box
+ − 841
+ − 842 TFT_box:
+ − 843 ;---- Define Window ------------------------------------------------------
+ − 844 movf win_width,W
+ − 845 bcf STATUS,C
+ − 846 rlcf WREG
+ − 847 movwf win_width+0
+ − 848 movlw 0
+ − 849 rlcf WREG
+ − 850 movwf win_width+1
83
+ − 851 rcall TFT_box_write ; Setup box
0
+ − 852
83
+ − 853 global TFT_box_16bit_win_left
+ − 854 TFT_box_16bit_win_left:
0
+ − 855 rrcf win_width+1,W ; width /= 2
+ − 856 rrcf win_width+0,W
+ − 857 movwf win_width
+ − 858
+ − 859 ;---- Fill Window --------------------------------------------------------
+ − 860 Index_out 0x22 ; Frame Memory Data Write start
+ − 861
+ − 862 clrf PRODH ; Column counter.
+ − 863 RS_H ; Data
+ − 864
+ − 865 TFT_box2: ; Loop height times
+ − 866 movff win_height,PRODL
+ − 867
+ − 868 TFT_box3: ; loop width times
+ − 869 movff win_color1,PORTA ; Upper
+ − 870 movff win_color2,PORTH ; Lower
+ − 871 WR_L
+ − 872 WR_H ; Tick
370
+ − 873 ;
+ − 874 ; movff win_color1,PORTA ; Upper
+ − 875 ; movff win_color2,PORTH ; Lower
0
+ − 876 WR_L
+ − 877 WR_H ; Tick
+ − 878
+ − 879 decfsz PRODL,F ; row loop finished ?
+ − 880 bra TFT_box3 ; No: continue.
+ − 881
+ − 882 incf PRODH,F ; column count ++
+ − 883
+ − 884 movff win_bargraph,WREG ; current column == bargraph ?
+ − 885 cpfseq PRODH
+ − 886 bra TFT_box4 ; No: just loop.
+ − 887
+ − 888 clrf WREG ; Yes: switch to black
+ − 889 movff WREG,win_color1
+ − 890 movff WREG,win_color2
+ − 891 TFT_box4:
+ − 892
+ − 893 movff win_width+0,WREG ; compare ?
+ − 894 xorwf PRODH,W
+ − 895 bnz TFT_box2 ; Loop not finished.
+ − 896
+ − 897 movlw 0x00 ; NOP, to stop window mode
+ − 898 rcall TFT_CmdWrite
+ − 899
+ − 900 setf WREG ; Reset bargraph mode...
+ − 901 movff WREG,win_bargraph
+ − 902
+ − 903 return
+ − 904
+ − 905 ;=============================================================================
+ − 906 ;Converts 8Bit RGB b'RRRGGGBB' into 16Bit RGB b'RRRRRGGGGGGBBBBB'
+ − 907 global TFT_set_color
+ − 908
+ − 909 TFT_set_color:
+ − 910 movwf tft_temp1 ; Get 8Bit RGB b'RRRGGGBB'
+ − 911 movwf tft_temp2 ; Copy
+ − 912
+ − 913 ; Mask Bit 7,6,5,4,3,2
+ − 914 movlw b'00000011'
+ − 915 andwf tft_temp2,F
+ − 916
+ − 917 movlw b'00000000'
+ − 918 dcfsnz tft_temp2,F
+ − 919 movlw b'01010000'
+ − 920 dcfsnz tft_temp2,F
+ − 921 movlw b'10100000'
+ − 922 dcfsnz tft_temp2,F
+ − 923 movlw b'11111000'
+ − 924 movwf tft_temp3 ; Blue done.
+ − 925
+ − 926 movff tft_temp1, tft_temp2 ; Copy
+ − 927 ; Mask Bit 7,6,5,1,0
+ − 928 movlw b'00011100'
+ − 929 andwf tft_temp2,F
+ − 930 rrncf tft_temp2,F
+ − 931 rrncf tft_temp2,F
+ − 932
+ − 933 movlw b'00000000'
+ − 934 dcfsnz tft_temp2,F
+ − 935 movlw b'00000100'
+ − 936 dcfsnz tft_temp2,F
+ − 937 movlw b'00001000'
+ − 938 dcfsnz tft_temp2,F
+ − 939 movlw b'00001100'
+ − 940 dcfsnz tft_temp2,F
+ − 941 movlw b'00010000'
+ − 942 dcfsnz tft_temp2,F
+ − 943 movlw b'00010100'
+ − 944 dcfsnz tft_temp2,F
+ − 945 movlw b'00100000'
+ − 946 dcfsnz tft_temp2,F
+ − 947 movlw b'00111111'
+ − 948 movwf tft_temp4
+ − 949
+ − 950 rrcf tft_temp4,F
+ − 951 rrcf tft_temp3,F
+ − 952
+ − 953 rrcf tft_temp4,F
+ − 954 rrcf tft_temp3,F
+ − 955
+ − 956 rrcf tft_temp4,F
+ − 957 rrcf tft_temp3,F ; tft_temp3 (b'GGGBBBBB') done.
+ − 958
+ − 959 movff tft_temp1, tft_temp2 ; Copy
+ − 960 clrf tft_temp1
+ − 961
+ − 962 rrcf tft_temp4,F
+ − 963 rrcf tft_temp1,F
+ − 964
+ − 965 rrcf tft_temp4,F
+ − 966 rrcf tft_temp1,F
+ − 967
+ − 968 rrcf tft_temp4,F
+ − 969 rrcf tft_temp1,F ; Green done.
+ − 970
+ − 971 ; Mask Bit 4,3,2,1,0
+ − 972 movlw b'11100000'
+ − 973 andwf tft_temp2,F
+ − 974
+ − 975 rrncf tft_temp2,F
+ − 976 rrncf tft_temp2,F
+ − 977 rrncf tft_temp2,F
+ − 978 rrncf tft_temp2,F
+ − 979 rrncf tft_temp2,F
+ − 980
+ − 981 movlw b'00000000'
+ − 982 dcfsnz tft_temp2,F
+ − 983 movlw b'00000100'
+ − 984 dcfsnz tft_temp2,F
+ − 985 movlw b'00001000'
+ − 986 dcfsnz tft_temp2,F
+ − 987 movlw b'00001100'
+ − 988 dcfsnz tft_temp2,F
+ − 989 movlw b'00010000'
+ − 990 dcfsnz tft_temp2,F
+ − 991 movlw b'00010100'
+ − 992 dcfsnz tft_temp2,F
+ − 993 movlw b'00100000'
+ − 994 dcfsnz tft_temp2,F
+ − 995 movlw b'00111111'
+ − 996 movwf tft_temp4
+ − 997
+ − 998 rrcf tft_temp4,F
+ − 999 rrcf tft_temp1,F
+ − 1000
+ − 1001 rrcf tft_temp4,F
+ − 1002 rrcf tft_temp1,F
+ − 1003
+ − 1004 rrcf tft_temp4,F
+ − 1005 rrcf tft_temp1,F
+ − 1006
+ − 1007 rrcf tft_temp4,F
+ − 1008 rrcf tft_temp1,F
+ − 1009
+ − 1010 rrcf tft_temp4,F
+ − 1011 rrcf tft_temp1,F ; Red done.
+ − 1012
+ − 1013 movff tft_temp1,win_color1
+ − 1014 movff tft_temp3,win_color2 ; Set Bank0 Color registers...
+ − 1015 return
+ − 1016
+ − 1017 ;=============================================================================
+ − 1018 ; Dump screen contents to the UART
+ − 1019
+ − 1020 global TFT_dump_screen
+ − 1021 TFT_dump_screen:
+ − 1022 bsf no_sensor_int
+ − 1023 movlw 'l'
+ − 1024 movwf TXREG ; Send command echo.
+ − 1025 call rs232_wait_tx ; wait for UART
+ − 1026 ;---- Send DISPLAY box command for the full screen window -------------------
+ − 1027 Index_out 0x50 ; Window Horizontal Start Address
+ − 1028 Parameter_out 0x00, 0x00 ; 0-239
+ − 1029 Index_out 0x51 ; Window Horizontal End Address
+ − 1030 Parameter_out 0x00, 0xEF ; 0-239
+ − 1031 Index_out 0x52 ; Window Vertical Start Address
+ − 1032 Parameter_out 0x00, 0x00 ; 0-319
+ − 1033 Index_out 0x53 ; Window Vertical End Address
+ − 1034 Parameter_out 0x01, 0x3F ; 0-319
+ − 1035
+ − 1036 clrf ds_column
+ − 1037 rcall dump_screen_pixel_reset
+ − 1038 dump_screen_1:
+ − 1039 btg LEDr ; LED activity toggle
+ − 1040 ; Dump even column
+ − 1041 movlw .240 ; 240 lines, once.
+ − 1042 movwf ds_line
+ − 1043 dump_screen_2:
+ − 1044 Index_out 0x20 ; Frame Memory Horizontal Address
+ − 1045 movff ds_line,WREG ; d'0' ... d'239'
+ − 1046 mullw 1 ; Copy row to PRODH:L
+ − 1047 rcall TFT_DataWrite_PROD
+ − 1048
+ − 1049 movff ds_column,WREG ; Init X position.
+ − 1050 mullw 2
+ − 1051 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 1052
+ − 1053 rcall TFT_DataRead_PROD ; read pixel
+ − 1054 rcall dump_screen_pixel
+ − 1055
+ − 1056 decfsz ds_line,F
+ − 1057 bra dump_screen_2
+ − 1058 rcall dump_screen_pixel_flush
+ − 1059
+ − 1060 ; Dump odd column
+ − 1061 movlw .240 ; 240 lines, twice.
+ − 1062 movwf ds_line
+ − 1063 dump_screen_3:
+ − 1064 Index_out 0x20 ; Frame Memory Horizontal Address
+ − 1065 movff ds_line,WREG ; d'0' ... d'239'
+ − 1066 mullw 1 ; Copy row to PRODH:L
+ − 1067 rcall TFT_DataWrite_PROD
+ − 1068
+ − 1069 movff ds_column,WREG ; Init X position.
+ − 1070 mullw 2
+ − 1071 movlw .1
+ − 1072 addwf PRODL,F
+ − 1073 movlw 0
+ − 1074 addwfc PRODH,F ; +1
+ − 1075 rcall pixel_write_col320 ; Start Address Vertical (.0 - .319)
+ − 1076
+ − 1077 rcall TFT_DataRead_PROD ; read pixel
+ − 1078 rcall dump_screen_pixel
+ − 1079
+ − 1080 decfsz ds_line,F
+ − 1081 bra dump_screen_3
+ − 1082 rcall dump_screen_pixel_flush
+ − 1083
+ − 1084 incf ds_column,F
+ − 1085 movlw .160
+ − 1086 cpfseq ds_column
+ − 1087 bra dump_screen_1
+ − 1088
+ − 1089 bcf no_sensor_int
+ − 1090 clrf RCREG1 ; Clear receive buffer
+ − 1091 bcf RCSTA1,CREN ; Clear receiver status
+ − 1092 bsf RCSTA1,CREN
+ − 1093 bsf enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
+ − 1094 return
+ − 1095
+ − 1096
+ − 1097 ;=============================================================================
+ − 1098 ; Pixel compression
+ − 1099 ;
+ − 1100 ; Input: PRODH:L = pixel.
+ − 1101 ; Output: Compressed stream on output.
+ − 1102 ; Compressed format:
+ − 1103 ; 0ccccccc : BLACK pixel, repeated ccccccc+1 times (1..128).
+ − 1104 ; 11cccccc : WHITE pixel, repeated cccccc+1 times (1..64).
+ − 1105 ; 10cccccc HIGH LOW : color pixel (H:L) repeated ccccc+1 times (1..64).
+ − 1106 ;
+ − 1107 dump_screen_pixel:
+ − 1108 movf PRODH,W ; Compare pixel-high
+ − 1109 xorwf ds_pixel+1,W
+ − 1110 bnz dump_screen_pixel_1 ; Different -> dump.
+ − 1111
+ − 1112 movf PRODL,W ; Compare pixel-low
+ − 1113 xorwf ds_pixel+0,W
+ − 1114 bnz dump_screen_pixel_1 ; Different -> dump.
+ − 1115
+ − 1116 incf ds_count,F ; Same color: just increment.
+ − 1117 return
+ − 1118
+ − 1119 dump_screen_pixel_1: ; Send (pixel,count) tuple
+ − 1120 movf ds_count,W ; Is count zero ?
+ − 1121 bz dump_screen_pixel_2 ; Yes: skip sending.
+ − 1122
+ − 1123 movf ds_pixel+1,W ; This is a BLACK pixel ?
+ − 1124 iorwf ds_pixel+0,W
+ − 1125 bz dump_screen_pix_black ; YES.
+ − 1126
+ − 1127 movf ds_pixel+1,W ; This is a white pixel ?
+ − 1128 andwf ds_pixel+0,W
+ − 1129 incf WREG
+ − 1130 bz dump_screen_pix_white ; YES.
+ − 1131
+ − 1132 ; No: write the pixel itself...
+ − 1133 movlw .64 ; Max color pixel on a single byte.
+ − 1134 cpfsgt ds_count ; Skip if count > 64
+ − 1135 movf ds_count,W ; W <- min(64,count)
+ − 1136 subwf ds_count,F ; ds_count <- ds_count-W
+ − 1137 decf WREG ; Save as 0..63
+ − 1138 iorlw b'10000000' ; MARK as a color pixel.
+ − 1139
+ − 1140 movwf TXREG
+ − 1141 call rs232_wait_tx ; wait for UART
+ − 1142 movff ds_pixel+1,TXREG
+ − 1143 call rs232_wait_tx ; wait for UART
+ − 1144 movff ds_pixel+0,TXREG
+ − 1145 call rs232_wait_tx ; wait for UART
+ − 1146 bra dump_screen_pixel_1
+ − 1147
+ − 1148 dump_screen_pixel_2:
+ − 1149 movff PRODH,ds_pixel+1 ; Save new pixel color
+ − 1150 movff PRODL,ds_pixel+0
+ − 1151 movlw 1
+ − 1152 movwf ds_count ; And set count=1.
+ − 1153 return
+ − 1154
+ − 1155 dump_screen_pix_black:
+ − 1156 movlw .128 ; Max black pixel on a single byte.
+ − 1157 cpfsgt ds_count ; Skip if count > 128
+ − 1158 movf ds_count,W ; W <- min(128,count)
+ − 1159 subwf ds_count,F ; ds_count <- ds_count-W
+ − 1160 decf WREG ; Save as 0..127
+ − 1161 dump_screen_pix_3:
+ − 1162 movwf TXREG
+ − 1163 call rs232_wait_tx
+ − 1164 bra dump_screen_pixel_1 ; More to dump ?
+ − 1165
+ − 1166 dump_screen_pix_white:
+ − 1167 movlw .64 ; Max white pixel on a single byte.
+ − 1168 cpfsgt ds_count ; Skip if count > 64
+ − 1169 movf ds_count,W ; W <- min(64,count)
+ − 1170 subwf ds_count,F ; ds_count <- ds_count-W
+ − 1171 decf WREG ; Save as 0..63
+ − 1172 iorlw b'11000000' ; MARK as a compressed white.
+ − 1173 bra dump_screen_pix_3
+ − 1174
+ − 1175 dump_screen_pixel_flush:
+ − 1176 clrf PRODH
+ − 1177 clrf PRODL
+ − 1178 rcall dump_screen_pixel_1 ; Send it
+ − 1179 dump_screen_pixel_reset:
+ − 1180 clrf ds_count ; But clear count.
+ − 1181 return
+ − 1182
+ − 1183 end