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 |