99 lines
2.1 KiB
Plaintext
99 lines
2.1 KiB
Plaintext
; video_dma.pio
|
|
;
|
|
; Composite video generator:
|
|
; - SM1: sync timing + line start IRQ
|
|
; - SM0: pixel output during active video
|
|
;
|
|
; Based on the same timing structure as alanpreed/pico-composite-video:
|
|
; 4us hsync, 6us back porch, 52us active video, 2us front porch,
|
|
; 288 active lines per field, interlaced fields.
|
|
|
|
.define DATA_DELAY 4
|
|
.define LINE_IRQ 0
|
|
.define PUBLIC CLOCKS_PER_BIT DATA_DELAY + 2
|
|
|
|
.program cvsync
|
|
.side_set 1
|
|
|
|
; OSR = lines_per_field - 1
|
|
; Y = field flag: 0 = even field, !0 = odd field
|
|
|
|
.wrap_target
|
|
vsync_start:
|
|
; First set of short pulses:
|
|
; even field: 6
|
|
; odd field : 5
|
|
jmp !y set_even_counter side 0
|
|
set x, 3 side 1
|
|
jmp vsync_short_pulse side 1 [13]
|
|
|
|
set_even_counter:
|
|
set x, 4 side 1 [14]
|
|
|
|
vsync_short_pulse:
|
|
nop side 0
|
|
jmp x-- vsync_short_pulse [14] side 1
|
|
|
|
; Long sync pulses: always 5
|
|
set x, 4 side 0 [13]
|
|
|
|
vsync_long_start:
|
|
jmp !x vsync_long_end [1] side 1
|
|
jmp x-- vsync_long_start [13] side 0
|
|
vsync_long_end:
|
|
|
|
; Second set of short pulses:
|
|
; even field: 5
|
|
; odd field : 4
|
|
jmp !y set_even_counter_2 side 0
|
|
set x, 2 side 1
|
|
jmp flip_field_flag side 1 [12]
|
|
|
|
set_even_counter_2:
|
|
set x, 3 side 1 [13]
|
|
|
|
flip_field_flag:
|
|
mov y, !y side 1
|
|
|
|
vsync_short_pulse_2:
|
|
nop side 0
|
|
jmp x-- vsync_short_pulse_2 [14] side 1
|
|
|
|
; 17 blank lines
|
|
set x, 16 side 0 [1]
|
|
|
|
hsync_blank_start:
|
|
nop side 1 [14]
|
|
jmp !x hsync_blank_end side 1 [14]
|
|
jmp x-- hsync_blank_start side 0 [1]
|
|
hsync_blank_end:
|
|
|
|
; 288 active video lines
|
|
mov x, osr side 0 [1]
|
|
|
|
hsync_video:
|
|
nop side 1 [2] ; 6us back porch
|
|
irq set LINE_IRQ side 1 [13] ; 52us active video
|
|
jmp !x vsync_start side 1 [12] ; 2us front porch (+ tail of active)
|
|
jmp x-- hsync_video side 0 [1] ; 4us hsync pulse
|
|
.wrap
|
|
|
|
|
|
.program cvdata
|
|
|
|
; X = pixels_per_line - 1, preloaded once from C
|
|
; Each line:
|
|
; clear output
|
|
; reload Y from X
|
|
; wait for sync SM to raise LINE_IRQ
|
|
; shift out one bit per loop
|
|
|
|
.wrap_target
|
|
set pins, 0
|
|
mov y, x
|
|
wait 1 irq LINE_IRQ
|
|
|
|
data_out:
|
|
out pins, 1 [DATA_DELAY]
|
|
jmp y-- data_out
|
|
.wrap |