Files
picopal/video_dma.pio
2026-04-01 13:56:21 +02:00

101 lines
2.0 KiB
Plaintext

; video_dma.pio
;
; Composite video generator:
; - SM1: sync timing + line start IRQ
; - SM0: pixel output during active video
;
; NTSC-compatible progressive timing using the same coarse 2us timing grid as
; the original PAL implementation:
; - 64us line period
; - 4us hsync
; - 6us back porch
; - 52us active video + front porch tail
; - 240 active lines, 262 total lines per frame (~59.64Hz)
.define DATA_DELAY 4
.define LINE_IRQ 0
.define DMA_IRQ 1
.define PUBLIC CLOCKS_PER_BIT DATA_DELAY + 2
.program cvsync
.side_set 1
; OSR = active_lines_per_frame - 1
.wrap_target
frame_start:
; 3 lines of broad vertical sync.
set x, 2 side 1
vsync_lines:
nop side 0 [14]
nop side 0
nop side 1 [14]
jmp x-- vsync_lines side 1
; 19 blank lines before active video.
set x, 18 side 1
blank_lines:
irq set DMA_IRQ side 0 [1]
nop side 1 [14]
jmp x-- blank_lines side 1 [14]
; 240 active video lines.
mov x, osr side 1
active_lines:
irq set DMA_IRQ side 0 [1] ; 4us hsync, ask CPU to arm DMA
nop side 1 [2] ; 6us back porch
irq set LINE_IRQ side 1 [13] ; 28us visible video
jmp x-- active_lines side 1 [12]
jmp frame_start side 1 [12]
.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
irq clear LINE_IRQ
data_out:
out pins, 1 [DATA_DELAY]
jmp y-- data_out
.wrap
.program cvdata_diag
; Diagnostic program:
; waits for each active line, then emits wide black/white bars without DMA.
; This isolates the analog output path from the framebuffer/DMA path.
.wrap_target
wait 1 irq LINE_IRQ
irq clear LINE_IRQ
set x, 3
diag_bars:
set pins, 1 [15]
nop [15]
nop [15]
set pins, 0 [15]
nop [15]
nop [15]
jmp x-- diag_bars [15]
set pins, 0
.wrap