Fix up RLE-to-TMDS encoder for bad apple

two-pixels-per-word
Luke Wren 2021-03-04 20:33:15 +00:00
rodzic 0ddc935866
commit 6585015fa5
2 zmienionych plików z 26 dodań i 30 usunięć

Wyświetl plik

@ -38,12 +38,13 @@ int main() {
dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
// Fill all of DVI's TMDS buffers with valid symbols (fine vertical stripes),
// Fill all of DVI's TMDS buffers with valid DC-balanced symbol pairs (mid-grey),
// as we'll only be rendering into the middle part of each span
uint32_t *buf;
const uint32_t two_0x80_symbols = 0x5fd80u;
while (queue_try_remove_u32(&dvi0.q_tmds_free, &buf)) {
for (int i = 0; i < FRAME_WIDTH; ++i)
buf[i] = i & 1 ? 0x99555 : 0x96aaa;
for (int i = 0; i < FRAME_WIDTH / DVI_SYMBOLS_PER_WORD; ++i)
buf[i] = two_0x80_symbols;
queue_add_blocking_u32(&dvi0.q_tmds_valid, &buf);
}
// Shuffle them back to the free queue so we don't have to deal with the timing later
@ -52,14 +53,14 @@ int main() {
dvi_start(&dvi0);
const uint8_t *line = (const uint8_t *)MOVIE_BASE;
int frame = 0;
while (true) {
const uint8_t *line = frame_bin;
uint32_t *render_target;
for (int y = 0; y < FRAME_HEIGHT; ++y) {
uint8_t line_len = *line++;
queue_remove_blocking_u32(&dvi0.q_tmds_free, &render_target);
rle_to_tmds(line, render_target + (1280 - 960) / 2, line_len);
rle_to_tmds(line, render_target + (1280 - 960) / 2 / DVI_SYMBOLS_PER_WORD, line_len);
queue_add_blocking_u32(&dvi0.q_tmds_valid, &render_target);
line += line_len;
}

Wyświetl plik

@ -1,3 +1,6 @@
// Note this is a fairly suboptimal approach now, see tmds_encode_1bpp in
// tmds_encode.S for a faster and more general solution
// Taking the encoder from DVI spec, with initial balance 0:
//
// - Encoding either 0x00 or 0xff will produce a running balance of -8, with
@ -11,12 +14,12 @@
//
// x % 2 | Colour | Output
// ------+--------+--------
// 0 | 0 | 0x9aaaa
// 0 | 1 | 0x6aaaa
// 1 | 0 | 0x95555
// 1 | 1 | 0x65555
// 0 | 0 | 0x100
// 0 | 1 | 0x200
// 1 | 0 | 0x1ff
// 1 | 1 | 0x2ff
//
// We will use this to rapidly unpack bytes encoded in the following RLE:
// We will use this to unpack bytes encoded in the following RLE:
//
// 7|6|5 0
// a|b|nnnnnn
@ -31,43 +34,35 @@
.type rle_to_tmds,%function
.thumb_func
rle_to_tmds:
push {r4-r6, lr}
push {r4, lr}
add r2, r0
mov ip, r2
adr r5, tmds_bw_pix0
adr r6, tmds_bw_pix1
adr r4, tmds_table
b 3f
1:
ldrb r2, [r0]
add r0, #1
// Pixel 0 symbol in r3: (could speed these bits up with interp)
lsr r3, r2, #7
// Load symbol pair
lsr r3, r2, #6
lsl r3, #2
ldr r3, [r3, r5]
// Pixel 1 symbol in r4:
lsr r4, r2, #6
lsl r4, #31
lsr r4, #29
ldr r4, [r4, r6]
ldr r3, [r4, r3]
// run length - 1 in r2:
lsl r2, #26
lsr r2, #26
2:
stmia r1!, {r3, r4}
stmia r1!, {r3}
sub r2, #1
bcs 2b
3:
cmp r0, ip
bne 1b
pop {r4-r6, pc}
pop {r4, pc}
.align 2
tmds_bw_pix0:
.word 0x9aaaa
.word 0x6aaaa
tmds_bw_pix1:
.word 0x95555
.word 0x65555
tmds_table:
.word 0x7fd00 // 00
.word 0xbfd00 // 10
.word 0x7fe00 // 01
.word 0xbfe00 // 11