; 8uS of back porch.
active_back_porch:
sbi _SFR_IO_ADDR(TVTEXT_SYNC_PORT),TVTEXT_SYNC_BIT ; [1]
; Have we finished scanning the active display? [25]
lds YL,scan_region_repeat+0 ; [2]
lds YH,scan_region_repeat+1 ; [2]
adiw YL,1 ; [2]
sts scan_region_repeat+0,YL ; [2]
sts scan_region_repeat+1,YH ; [2]
brne active_display_not_finished ; [2/1]
active_display_finished:
ldi ZL,lo8(pm(short_vsync_sync)) ; [1] \.
ldi ZH,hi8(pm(short_vsync_sync)) ; [1] |
ldi YL,6 ; [1] |_ [7]
sts scan_region_repeat,YL ; [2] |
jmp active_display_exit ; [2] /'
active_display_not_finished_delay:
rjmp . ; [2] \.
rjmp . ; [2] |_ [6]
rjmp . ; [2] /'
active_display_not_finished:
ldi ZL,lo8(pm(active_sync)) ; [1] \_ [2]
ldi ZH,hi8(pm(active_sync)) ; [1] /
rjmp . ; [2] \.
rjmp . ; [2] |_ [5]
nop ; [1] /'
active_display_exit:
ldi YL,lo8(cycles_us(t_active_picture)) ; [1] \_ [2]
ldi YH,hi8(cycles_us(t_active_picture)) ; [1] /
sts timer1_compa_handler+0,ZL ; [2] \.
sts timer1_compa_handler+1,ZH ; [2] |_ [8]
sts _SFR_MEM_ADDR(OCR1AH),YH ; [2] |
sts _SFR_MEM_ADDR(OCR1AL),YL ; [2] /'
push r0
push r1
push r_font_data_l
push r_font_data_h
push r_characters_left
push r_font_row
push r_font_invert_mask
push XL
push XH
active_display:
; Delay by the screen offset value.
lds r_characters_left,tvtext_offset_x
inc r_characters_left
1: dec r_characters_left
brne 1b
; Is the screen inverted?
lds r_font_row,tvtext_flags ; [1]
clr r_font_invert_mask ; [1]
sbrc r_font_row,TVTEXT_INVERTED ; [2/1]
ser r_font_invert_mask ; [1]
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_invert_mask ; [1]
; Are we on the screen?
lds r_characters_left,scanline_counter+1
or r_characters_left,r_characters_left
breq 1f
jmp active_display_skip_scanline
1:
.if TVTEXT_SKIP_ALTERNATE_ROWS
lds r_characters_left,scanline_counter+0 ; [2]
sbrc r_characters_left,0 ; [2/1]
jmp active_display_skip_scanline ; [2]
.endif
; Handle the cursor.
lds YL,cursor_cell+0 ; [2]
lds YH,cursor_cell+1 ; [2]
ld r0,Y ; [1]
push r0 ; [2]
lds r0,cursor_char ; [2]
st Y,r0 ; [2]
; Get font data offset.
ldi r_font_data_l,lo8(tvtext_font_data)
ldi r_font_data_h,hi8(tvtext_font_data)
; Offset the font data by the scanline number.
lds XL,scanline_counter+0
lsr XL
andi XL,7
clr XH
add r_font_data_l,XL
adc r_font_data_h,XH
; Calculate the position in the text buffer:
lds XL,scanline_counter+0 ; [2]
swap XL ; [1]
andi XL,15 ; [1]
ldi XH,TVTEXT_BUFFER_WIDTH ; [1]
mul XH,XL ; [2]
ldi XL,lo8(tvtext_buffer) ; [1]
ldi XH,hi8(tvtext_buffer) ; [1]
add XL,r0 ; [1]
adc XH,r1 ; [1]
; Fetch first character.
ldi ZL, 8 ; [1]
ld r0, X+ ; [2]
mul r0, ZL ; [2] Multiply character index by 8.
add r0, r_font_data_l ; [1] \_ Offset font data row by scanline number.
adc r1, r_font_data_h ; [1] /
movw ZL, r0 ; [1]
; Display first five columns of first character and fetch second one.
; (1)
lpm r_font_row,Z ; [3]
eor r_font_row,r_font_invert_mask ; [1]
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_row ; [1]
nop ; [1]
rol r_font_row ; [1]
; (2)
rjmp . ; [2] <- [2] before.
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_row ; [1]
ldi ZL,8 ; [1] \_ [2] after.
rol r_font_row ; [1] /
; (3)
ld r0,X+ ; [2] <- [2] before.
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_row ; [1]
mul r0,ZL ; [2] <- [2] after. (Multiply character index by 8).
; (4)
rol r_font_row ; [1] \_ [2] before.
add r0,r_font_data_l ; [1] /
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_row ; [1]
nop ; [1] \_ [2] after.
adc r1,r_font_data_h ; [1] / Offset font data row by scanline number.
; (5)
movw ZL,r0 ; [1] \_ [2] before.
rol r_font_row ; [1] /
out _SFR_IO_ADDR(TVTEXT_PICTURE_PORT),r_font_row ; [1]
ldi r_characters_left,TVTEXT_BUFFER_WIDTH-1 ; [1] \_ [2] after.
nop ; [1] /