diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-06-15 08:54:45 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-07-08 10:20:41 -0600 |
commit | 6fd11a1bf4d1bc4c4919c3381be8d4c476dd4235 (patch) | |
tree | d356d5ed2c944d9d15f06cc36a14c8c779a8c4f7 | |
parent | 72b9036dc961d9fe7e0e9deb12e87f121a4d0ccf (diff) |
wip: flashimg/cpu_hdmi: Initial version of the TMDS decoder/downscalerlukeshu/vid-hdmi
-rw-r--r-- | .editorconfig | 5 | ||||
-rw-r--r-- | GNUmakefile | 6 | ||||
-rwxr-xr-x | build-aux/lint-src | 2 | ||||
-rw-r--r-- | flashimg/cpu_hdmi/tmds_decode-interp.S | 95 | ||||
-rw-r--r-- | flashimg/cpu_hdmi/tmds_decode.S | 82 | ||||
-rw-r--r-- | flashimg/cpu_hdmi/tmds_decode_table.h | 1025 | ||||
-rwxr-xr-x | flashimg/cpu_hdmi/tmds_decode_table.h.gen | 39 |
7 files changed, 1251 insertions, 3 deletions
diff --git a/.editorconfig b/.editorconfig index d281cf0..6d6ef60 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,6 +20,9 @@ trim_trailing_whitespace = true [*.{c,h}] _mode = c +[*.S] +_mode = asm + [GNUmakefile] _mode = make @@ -51,7 +54,7 @@ _mode = sh [{build-aux/lint-{src,bin},build-aux/gcov-prune,libmisc/error_generated.c.gen,libusb/include/libusb/tusb_helpers.h.gen}] _mode = bash -[{build-aux/stack.c.gen,build-aux/tent-graph,libmisc/wrap-cc,lib9p_util/nut.h.gen}] +[{build-aux/stack.c.gen,build-aux/tent-graph,libmisc/wrap-cc,lib9p_util/nut.h.gen,flashimg/cpu_hdmi/tmds_decode_table.h.gen}] _mode = python3 indent_style = space indent_size = 4 diff --git a/GNUmakefile b/GNUmakefile index d4422d4..a4dfb56 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -69,6 +69,10 @@ generate/files += lib9p_util/nut.h lib9p_util/nut.h: %: %.gen lib9p_util/nut_gen lib9p_util/nut_gen/*.py $< $@ +generate/files += flashimg/cpu_hdmi/tmds_decode_table.h +flashimg/cpu_hdmi/tmds_decode_table.h: %: %.gen + $^ >$@ + generate/files += build-aux/sources.mk ifeq ($(INNER),) nonsource/files = $(generate/files) @@ -183,5 +187,5 @@ format/sh format/bash: format/%: format/python3: ./build-aux/venv ./build-aux/venv/bin/black $(sources_$(@F)) ./build-aux/venv/bin/isort $(sources_$(@F)) -format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat: +format/asm format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat: @: TODO: Write/adopt formatters for these file types diff --git a/build-aux/lint-src b/build-aux/lint-src index d536631..15327f4 100755 --- a/build-aux/lint-src +++ b/build-aux/lint-src @@ -148,7 +148,7 @@ get-dscname() { done ./build-aux/venv/bin/pytest "${testfiles[@]}" || exit $? ;; - make | cmake | gitignore | ini | 9p-idl | 9p-log | markdown | pip | man-cat) + asm | make | cmake | gitignore | ini | 9p-idl | 9p-log | markdown | pip | man-cat) # TODO: Write/adopt linters for these file types : ;; diff --git a/flashimg/cpu_hdmi/tmds_decode-interp.S b/flashimg/cpu_hdmi/tmds_decode-interp.S new file mode 100644 index 0000000..de1605a --- /dev/null +++ b/flashimg/cpu_hdmi/tmds_decode-interp.S @@ -0,0 +1,95 @@ +// flashimg/cpu_hdmi/tmds_decode-interp.S - Variant of tmds_decode.S that does linear interpolation +// +// Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +// SPDX-License-Identifier: AGPL-3.0-or-later + +.syntax unified +.cpu cortex-m0plus +.thumb + +// .tmds_table is a LUT from 10-bit TMDS-encoded values to the 8-bit +// decoded values. +.section .scratch_x.tmds_table, "a" +tmds_table: +#define X(dec) .byte dec +#include "tmds_decode_table.h" +#undef X + +// void tmds_decode_line(uint16_t in_r[width], +// uint16_t in_g[width], +// uint16_t in_b[width], +// uint8_t out[width/2], +// size_t width); +// +// Read in `width` values from 10-bit-encoded TMDS streams of R/G/B +// channels of 24-bit RGB pixels; and write that out as RGB 2:3:2, +// scaled down horizontally by half. +// +// `width` must be either 640 or 720. +.section .scratch_x.tmds_decode_line, "ax" +.global tmds_decode_line +.type tmds_decode_line,%function +.thumb_func +tmds_decode_line: + // Of our supported screen formats, the one with the tightest + // cycles/pixel requirement is 720x480p@60Hz, which has + // H_active=720, H_total=858, meaning that we need to decode + // 720 pixels in under 858*10 cycles, giving us a budget of + // ~11.9 cycles per pixel. +#define iR r0 +#define iG r1 +#define iB r2 +#define o r3 +#define w r4 +#define vTab r4 +#define vAcc r5 +#define vTmp1 r6 +#define vTmp2 r7 +#define vOEnd r12 + push {r4-r7, lr} // ONCE += 1+5 cyc + lsrs w, w, #1 // ONCE += 1 cyc + add w, o, w // ONCE += 1 cyc + mov vOEnd, w // ONCE += 1 cyc +#undef w + ldr vTab, =tmds_table // ONCE += 2 cyc +loop: +.rept 4 + // red + ldmia iR!, {vTmp2} // REPT += 1+1 cyc + lsrs vTmp1, vTmp2, #16 // REPT += 1 cyc + uxth vTmp2, vTmp2 // REPT += 1 cyc + ldsb vTmp1, [vTab, vTmp1] // REPT += 2 cyc + ldsb vTmp2, [vTab, vTmp2] // REPT += 2 cyc + add vTmp1, vTmp1, vTmp2 // REPT += 1 cyc // add 2 8-bit values, producing a 9-bit value... + lsrs vTmp1, vTmp1, #7 // REPT += 1 cyc // ...shrink it from 9-bits to 2-bits + lsls vAcc, vTmp1, #5 // REPT += 1 cyc + // green + ldmia iG!, {vTmp2} // REPT += 1+1 cyc + lsrs vTmp1, vTmp2, #16 // REPT += 1 cyc + uxth vTmp2, vTmp2 // REPT += 1 cyc + ldsb vTmp1, [vTab, vTmp1] // REPT += 2 cyc + ldsb vTmp2, [vTab, vTmp2] // REPT += 2 cyc + add vTmp1, vTmp1, vTmp2 // REPT += 1 cyc // add 2 8-bit values, producing a 9-bit value... + lsrs vTmp1, vTmp1, #6 // REPT += 1 cyc // ...shrink it from 9-bits to 3-bits + lsls vTmp1, vTmp1, #2 // REPT += 1 cyc + orrs vAcc, vAcc, vTmp1 // REPT += 1 cyc + // blue + ldmia iB!, {vTmp2} // REPT += 1+1 cyc + lsrs vTmp1, vTmp2, #16 // REPT += 1 cyc + uxth vTmp2, vTmp2 // REPT += 1 cyc + ldsb vTmp1, [vTab, vTmp1] // REPT += 2 cyc + ldsb vTmp2, [vTab, vTmp2] // REPT += 2 cyc + add vTmp1, vTmp1, vTmp2 // REPT += 1 cyc // add 2 8-bit values, producing a 9-bit value... + lsrs vTmp1, vTmp1, #7 // REPT += 1 cyc // ...shrink it from 9-bits to 2-bits + orrs vAcc, vAcc, vTmp1 // REPT += 1 cyc + // store + strb vAcc, [o, #0] // REPT += 2 cyc + adds o, o, #1 // REPT += 1 cyc +.endr + cmp o, vOEnd // LOOP += 1 cyc + bne loop // LOOP += 2 cyc ; ONCE -= 1 cyc + pop {r4-r7, pc} // ONCE += 3+5 cyc + // TOTAL = ONCE+((720/2)/N)*LOOP+(720/2)*REPT cyc + // = 18 +( 360 /4)* 3 + 360 * 37 cyc + // = 13608 cyc + // BUDGET = 8580 cyc diff --git a/flashimg/cpu_hdmi/tmds_decode.S b/flashimg/cpu_hdmi/tmds_decode.S new file mode 100644 index 0000000..888b5b9 --- /dev/null +++ b/flashimg/cpu_hdmi/tmds_decode.S @@ -0,0 +1,82 @@ +// flashimg/cpu_hdmi/tmds_decode.S - Decode TMDS-encoded scanlines +// +// Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +// SPDX-License-Identifier: AGPL-3.0-or-later + +.syntax unified +.cpu cortex-m0plus +.thumb + +// .tmds_table is a LUT from 10-bit TMDS-encoded values to the 8-bit +// decoded values, shifted right 6 bits. +.section .scratch_x.tmds_table, "a" +tmds_table: +#define X(dec) .byte dec>>6 +#include "tmds_decode_table.h" +#undef X + +// void tmds_decode_line(uint16_t in_r[width], +// uint16_t in_g[width], +// uint16_t in_b[width], +// uint8_t out[width/2], +// size_t width); +// +// Read in `width` values from 10-bit-encoded TMDS streams of R/G/B +// channels of 24-bit RGB pixels; and write that out as RGB 2:3:2, +// scaled down horizontally by half. +// +// `width` must be either 640 or 720. +// +// BUG: Scaling down happens by discarding every other pixel, not by +// interpolation. +.section .scratch_x.tmds_decode_line, "ax" +.global tmds_decode_line +.type tmds_decode_line,%function +.thumb_func +tmds_decode_line: + // Of our supported screen formats, the one with the tightest + // cycles/pixel requirement is 720x480p@60Hz, which has + // H_active=720, H_total=858, meaning that we need to decode + // 720 pixels in under 858*10 cycles, giving us a budget of + // ~11.9 cycles per pixel. +#define iR r0 +#define iG r1 +#define iB r2 +#define o r3 +#define w r4 +#define vTab r5 +#define vAcc r6 +#define vTmp r7 + push {r4-r7, lr} // ONCE += 1+5 cyc + lsrs w, w, #1 // ONCE += 1 cyc + add w, o, w // ONCE += 1 cyc + ldr vTab, =tmds_table // ONCE += 2 cyc +loop: +.rept 4 + // red + ldmia iR!, {vTmp} // REPT += 1+1 cyc + uxth vTmp, vTmp // REPT += 1 cyc + ldsb vTmp, [vTab, vTmp] // REPT += 2 cyc + lsls vAcc, vTmp, #5 // REPT += 1 cyc + // green + ldmia iG!, {vTmp} // REPT += 1+1 cyc + uxth vTmp, vTmp // REPT += 1 cyc + ldsb vTmp, [vTab, vTmp] // REPT += 2 cyc + lsls vTmp, vTmp, #3 // REPT += 1 cyc + orrs vAcc, vAcc, vTmp // REPT += 1 cyc + // blue + ldmia iB!, {vTmp} // REPT += 1+1 cyc + uxth vTmp, vTmp // REPT += 1 cyc + ldsb vTmp, [vTab, vTmp] // REPT += 2 cyc + orrs vAcc, vAcc, vTmp // REPT += 1 cyc + // store + strb vAcc, [o, #0] // REPT += 2 cyc + adds o, o, #1 // REPT += 1 cyc +.endr + cmp o, w // LOOP += 1 cyc + bne loop // LOOP += 2 cyc ; ONCE -= 1 cyc + pop {r4-r7, pc} // ONCE += 3+5 cyc + // TOTAL = ONCE+((720/2)/N)*LOOP+(720/2)*REPT cyc + // = 17 +( 360 /4)* 3 + 360 * 22 cyc + // = 8207 cyc + // BUDGET = 8580 cyc diff --git a/flashimg/cpu_hdmi/tmds_decode_table.h b/flashimg/cpu_hdmi/tmds_decode_table.h new file mode 100644 index 0000000..4e1d6ea --- /dev/null +++ b/flashimg/cpu_hdmi/tmds_decode_table.h @@ -0,0 +1,1025 @@ +// Generated by `flashimg/cpu_hdmi/tmds_decode_table.h.gen`. DO NOT EDIT! +X(0b01111111) +X(0b11111111) +X(0b00000000) +X(0b10000000) +X(0b01111110) +X(0b11111110) +X(0b00000001) +X(0b10000001) +X(0b01111100) +X(0b11111100) +X(0b00000011) +X(0b10000011) +X(0b01111101) +X(0b11111101) +X(0b00000010) +X(0b10000010) +X(0b01111001) +X(0b11111001) +X(0b00000110) +X(0b10000110) +X(0b01111000) +X(0b11111000) +X(0b00000111) +X(0b10000111) +X(0b01111010) +X(0b11111010) +X(0b00000101) +X(0b10000101) +X(0b01111011) +X(0b11111011) +X(0b00000100) +X(0b10000100) +X(0b01110011) +X(0b11110011) +X(0b00001100) +X(0b10001100) +X(0b01110010) +X(0b11110010) +X(0b00001101) +X(0b10001101) +X(0b01110000) +X(0b11110000) +X(0b00001111) +X(0b10001111) +X(0b01110001) +X(0b11110001) +X(0b00001110) +X(0b10001110) +X(0b01110101) +X(0b11110101) +X(0b00001010) +X(0b10001010) +X(0b01110100) +X(0b11110100) +X(0b00001011) +X(0b10001011) +X(0b01110110) +X(0b11110110) +X(0b00001001) +X(0b10001001) +X(0b01110111) +X(0b11110111) +X(0b00001000) +X(0b10001000) +X(0b01100111) +X(0b11100111) +X(0b00011000) +X(0b10011000) +X(0b01100110) +X(0b11100110) +X(0b00011001) +X(0b10011001) +X(0b01100100) +X(0b11100100) +X(0b00011011) +X(0b10011011) +X(0b01100101) +X(0b11100101) +X(0b00011010) +X(0b10011010) +X(0b01100001) +X(0b11100001) +X(0b00011110) +X(0b10011110) +X(0b01100000) +X(0b11100000) +X(0b00011111) +X(0b10011111) +X(0b01100010) +X(0b11100010) +X(0b00011101) +X(0b10011101) +X(0b01100011) +X(0b11100011) +X(0b00011100) +X(0b10011100) +X(0b01101011) +X(0b11101011) +X(0b00010100) +X(0b10010100) +X(0b01101010) +X(0b11101010) +X(0b00010101) +X(0b10010101) +X(0b01101000) +X(0b11101000) +X(0b00010111) +X(0b10010111) +X(0b01101001) +X(0b11101001) +X(0b00010110) +X(0b10010110) +X(0b01101101) +X(0b11101101) +X(0b00010010) +X(0b10010010) +X(0b01101100) +X(0b11101100) +X(0b00010011) +X(0b10010011) +X(0b01101110) +X(0b11101110) +X(0b00010001) +X(0b10010001) +X(0b01101111) +X(0b11101111) +X(0b00010000) +X(0b10010000) +X(0b01001111) +X(0b11001111) +X(0b00110000) +X(0b10110000) +X(0b01001110) +X(0b11001110) +X(0b00110001) +X(0b10110001) +X(0b01001100) +X(0b11001100) +X(0b00110011) +X(0b10110011) +X(0b01001101) +X(0b11001101) +X(0b00110010) +X(0b10110010) +X(0b01001001) +X(0b11001001) +X(0b00110110) +X(0b10110110) +X(0b01001000) +X(0b11001000) +X(0b00110111) +X(0b10110111) +X(0b01001010) +X(0b11001010) +X(0b00110101) +X(0b10110101) +X(0b01001011) +X(0b11001011) +X(0b00110100) +X(0b10110100) +X(0b01000011) +X(0b11000011) +X(0b00111100) +X(0b10111100) +X(0b01000010) +X(0b11000010) +X(0b00111101) +X(0b10111101) +X(0b01000000) +X(0b11000000) +X(0b00111111) +X(0b10111111) +X(0b01000001) +X(0b11000001) +X(0b00111110) +X(0b10111110) +X(0b01000101) +X(0b11000101) +X(0b00111010) +X(0b10111010) +X(0b01000100) +X(0b11000100) +X(0b00111011) +X(0b10111011) +X(0b01000110) +X(0b11000110) +X(0b00111001) +X(0b10111001) +X(0b01000111) +X(0b11000111) +X(0b00111000) +X(0b10111000) +X(0b01010111) +X(0b11010111) +X(0b00101000) +X(0b10101000) +X(0b01010110) +X(0b11010110) +X(0b00101001) +X(0b10101001) +X(0b01010100) +X(0b11010100) +X(0b00101011) +X(0b10101011) +X(0b01010101) +X(0b11010101) +X(0b00101010) +X(0b10101010) +X(0b01010001) +X(0b11010001) +X(0b00101110) +X(0b10101110) +X(0b01010000) +X(0b11010000) +X(0b00101111) +X(0b10101111) +X(0b01010010) +X(0b11010010) +X(0b00101101) +X(0b10101101) +X(0b01010011) +X(0b11010011) +X(0b00101100) +X(0b10101100) +X(0b01011011) +X(0b11011011) +X(0b00100100) +X(0b10100100) +X(0b01011010) +X(0b11011010) +X(0b00100101) +X(0b10100101) +X(0b01011000) +X(0b11011000) +X(0b00100111) +X(0b10100111) +X(0b01011001) +X(0b11011001) +X(0b00100110) +X(0b10100110) +X(0b01011101) +X(0b11011101) +X(0b00100010) +X(0b10100010) +X(0b01011100) +X(0b11011100) +X(0b00100011) +X(0b10100011) +X(0b01011110) +X(0b11011110) +X(0b00100001) +X(0b10100001) +X(0b01011111) +X(0b11011111) +X(0b00100000) +X(0b10100000) +X(0b00011111) +X(0b10011111) +X(0b01100000) +X(0b11100000) +X(0b00011110) +X(0b10011110) +X(0b01100001) +X(0b11100001) +X(0b00011100) +X(0b10011100) +X(0b01100011) +X(0b11100011) +X(0b00011101) +X(0b10011101) +X(0b01100010) +X(0b11100010) +X(0b00011001) +X(0b10011001) +X(0b01100110) +X(0b11100110) +X(0b00011000) +X(0b10011000) +X(0b01100111) +X(0b11100111) +X(0b00011010) +X(0b10011010) +X(0b01100101) +X(0b11100101) +X(0b00011011) +X(0b10011011) +X(0b01100100) +X(0b11100100) +X(0b00010011) +X(0b10010011) +X(0b01101100) +X(0b11101100) +X(0b00010010) +X(0b10010010) +X(0b01101101) +X(0b11101101) +X(0b00010000) +X(0b10010000) +X(0b01101111) +X(0b11101111) +X(0b00010001) +X(0b10010001) +X(0b01101110) +X(0b11101110) +X(0b00010101) +X(0b10010101) +X(0b01101010) +X(0b11101010) +X(0b00010100) +X(0b10010100) +X(0b01101011) +X(0b11101011) +X(0b00010110) +X(0b10010110) +X(0b01101001) +X(0b11101001) +X(0b00010111) +X(0b10010111) +X(0b01101000) +X(0b11101000) +X(0b00000111) +X(0b10000111) +X(0b01111000) +X(0b11111000) +X(0b00000110) +X(0b10000110) +X(0b01111001) +X(0b11111001) +X(0b00000100) +X(0b10000100) +X(0b01111011) +X(0b11111011) +X(0b00000101) +X(0b10000101) +X(0b01111010) +X(0b11111010) +X(0b00000001) +X(0b10000001) +X(0b01111110) +X(0b11111110) +X(0b00000000) +X(0b10000000) +X(0b01111111) +X(0b11111111) +X(0b00000010) +X(0b10000010) +X(0b01111101) +X(0b11111101) +X(0b00000011) +X(0b10000011) +X(0b01111100) +X(0b11111100) +X(0b00001011) +X(0b10001011) +X(0b01110100) +X(0b11110100) +X(0b00001010) +X(0b10001010) +X(0b01110101) +X(0b11110101) +X(0b00001000) +X(0b10001000) +X(0b01110111) +X(0b11110111) +X(0b00001001) +X(0b10001001) +X(0b01110110) +X(0b11110110) +X(0b00001101) +X(0b10001101) +X(0b01110010) +X(0b11110010) +X(0b00001100) +X(0b10001100) +X(0b01110011) +X(0b11110011) +X(0b00001110) +X(0b10001110) +X(0b01110001) +X(0b11110001) +X(0b00001111) +X(0b10001111) +X(0b01110000) +X(0b11110000) +X(0b00101111) +X(0b10101111) +X(0b01010000) +X(0b11010000) +X(0b00101110) +X(0b10101110) +X(0b01010001) +X(0b11010001) +X(0b00101100) +X(0b10101100) +X(0b01010011) +X(0b11010011) +X(0b00101101) +X(0b10101101) +X(0b01010010) +X(0b11010010) +X(0b00101001) +X(0b10101001) +X(0b01010110) +X(0b11010110) +X(0b00101000) +X(0b10101000) +X(0b01010111) +X(0b11010111) +X(0b00101010) +X(0b10101010) +X(0b01010101) +X(0b11010101) +X(0b00101011) +X(0b10101011) +X(0b01010100) +X(0b11010100) +X(0b00100011) +X(0b10100011) +X(0b01011100) +X(0b11011100) +X(0b00100010) +X(0b10100010) +X(0b01011101) +X(0b11011101) +X(0b00100000) +X(0b10100000) +X(0b01011111) +X(0b11011111) +X(0b00100001) +X(0b10100001) +X(0b01011110) +X(0b11011110) +X(0b00100101) +X(0b10100101) +X(0b01011010) +X(0b11011010) +X(0b00100100) +X(0b10100100) +X(0b01011011) +X(0b11011011) +X(0b00100110) +X(0b10100110) +X(0b01011001) +X(0b11011001) +X(0b00100111) +X(0b10100111) +X(0b01011000) +X(0b11011000) +X(0b00110111) +X(0b10110111) +X(0b01001000) +X(0b11001000) +X(0b00110110) +X(0b10110110) +X(0b01001001) +X(0b11001001) +X(0b00110100) +X(0b10110100) +X(0b01001011) +X(0b11001011) +X(0b00110101) +X(0b10110101) +X(0b01001010) +X(0b11001010) +X(0b00110001) +X(0b10110001) +X(0b01001110) +X(0b11001110) +X(0b00110000) +X(0b10110000) +X(0b01001111) +X(0b11001111) +X(0b00110010) +X(0b10110010) +X(0b01001101) +X(0b11001101) +X(0b00110011) +X(0b10110011) +X(0b01001100) +X(0b11001100) +X(0b00111011) +X(0b10111011) +X(0b01000100) +X(0b11000100) +X(0b00111010) +X(0b10111010) +X(0b01000101) +X(0b11000101) +X(0b00111000) +X(0b10111000) +X(0b01000111) +X(0b11000111) +X(0b00111001) +X(0b10111001) +X(0b01000110) +X(0b11000110) +X(0b00111101) +X(0b10111101) +X(0b01000010) +X(0b11000010) +X(0b00111100) +X(0b10111100) +X(0b01000011) +X(0b11000011) +X(0b00111110) +X(0b10111110) +X(0b01000001) +X(0b11000001) +X(0b00111111) +X(0b10111111) +X(0b01000000) +X(0b11000000) +X(0b10111111) +X(0b00111111) +X(0b11000000) +X(0b01000000) +X(0b10111110) +X(0b00111110) +X(0b11000001) +X(0b01000001) +X(0b10111100) +X(0b00111100) +X(0b11000011) +X(0b01000011) +X(0b10111101) +X(0b00111101) +X(0b11000010) +X(0b01000010) +X(0b10111001) +X(0b00111001) +X(0b11000110) +X(0b01000110) +X(0b10111000) +X(0b00111000) +X(0b11000111) +X(0b01000111) +X(0b10111010) +X(0b00111010) +X(0b11000101) +X(0b01000101) +X(0b10111011) +X(0b00111011) +X(0b11000100) +X(0b01000100) +X(0b10110011) +X(0b00110011) +X(0b11001100) +X(0b01001100) +X(0b10110010) +X(0b00110010) +X(0b11001101) +X(0b01001101) +X(0b10110000) +X(0b00110000) +X(0b11001111) +X(0b01001111) +X(0b10110001) +X(0b00110001) +X(0b11001110) +X(0b01001110) +X(0b10110101) +X(0b00110101) +X(0b11001010) +X(0b01001010) +X(0b10110100) +X(0b00110100) +X(0b11001011) +X(0b01001011) +X(0b10110110) +X(0b00110110) +X(0b11001001) +X(0b01001001) +X(0b10110111) +X(0b00110111) +X(0b11001000) +X(0b01001000) +X(0b10100111) +X(0b00100111) +X(0b11011000) +X(0b01011000) +X(0b10100110) +X(0b00100110) +X(0b11011001) +X(0b01011001) +X(0b10100100) +X(0b00100100) +X(0b11011011) +X(0b01011011) +X(0b10100101) +X(0b00100101) +X(0b11011010) +X(0b01011010) +X(0b10100001) +X(0b00100001) +X(0b11011110) +X(0b01011110) +X(0b10100000) +X(0b00100000) +X(0b11011111) +X(0b01011111) +X(0b10100010) +X(0b00100010) +X(0b11011101) +X(0b01011101) +X(0b10100011) +X(0b00100011) +X(0b11011100) +X(0b01011100) +X(0b10101011) +X(0b00101011) +X(0b11010100) +X(0b01010100) +X(0b10101010) +X(0b00101010) +X(0b11010101) +X(0b01010101) +X(0b10101000) +X(0b00101000) +X(0b11010111) +X(0b01010111) +X(0b10101001) +X(0b00101001) +X(0b11010110) +X(0b01010110) +X(0b10101101) +X(0b00101101) +X(0b11010010) +X(0b01010010) +X(0b10101100) +X(0b00101100) +X(0b11010011) +X(0b01010011) +X(0b10101110) +X(0b00101110) +X(0b11010001) +X(0b01010001) +X(0b10101111) +X(0b00101111) +X(0b11010000) +X(0b01010000) +X(0b10001111) +X(0b00001111) +X(0b11110000) +X(0b01110000) +X(0b10001110) +X(0b00001110) +X(0b11110001) +X(0b01110001) +X(0b10001100) +X(0b00001100) +X(0b11110011) +X(0b01110011) +X(0b10001101) +X(0b00001101) +X(0b11110010) +X(0b01110010) +X(0b10001001) +X(0b00001001) +X(0b11110110) +X(0b01110110) +X(0b10001000) +X(0b00001000) +X(0b11110111) +X(0b01110111) +X(0b10001010) +X(0b00001010) +X(0b11110101) +X(0b01110101) +X(0b10001011) +X(0b00001011) +X(0b11110100) +X(0b01110100) +X(0b10000011) +X(0b00000011) +X(0b11111100) +X(0b01111100) +X(0b10000010) +X(0b00000010) +X(0b11111101) +X(0b01111101) +X(0b10000000) +X(0b00000000) +X(0b11111111) +X(0b01111111) +X(0b10000001) +X(0b00000001) +X(0b11111110) +X(0b01111110) +X(0b10000101) +X(0b00000101) +X(0b11111010) +X(0b01111010) +X(0b10000100) +X(0b00000100) +X(0b11111011) +X(0b01111011) +X(0b10000110) +X(0b00000110) +X(0b11111001) +X(0b01111001) +X(0b10000111) +X(0b00000111) +X(0b11111000) +X(0b01111000) +X(0b10010111) +X(0b00010111) +X(0b11101000) +X(0b01101000) +X(0b10010110) +X(0b00010110) +X(0b11101001) +X(0b01101001) +X(0b10010100) +X(0b00010100) +X(0b11101011) +X(0b01101011) +X(0b10010101) +X(0b00010101) +X(0b11101010) +X(0b01101010) +X(0b10010001) +X(0b00010001) +X(0b11101110) +X(0b01101110) +X(0b10010000) +X(0b00010000) +X(0b11101111) +X(0b01101111) +X(0b10010010) +X(0b00010010) +X(0b11101101) +X(0b01101101) +X(0b10010011) +X(0b00010011) +X(0b11101100) +X(0b01101100) +X(0b10011011) +X(0b00011011) +X(0b11100100) +X(0b01100100) +X(0b10011010) +X(0b00011010) +X(0b11100101) +X(0b01100101) +X(0b10011000) +X(0b00011000) +X(0b11100111) +X(0b01100111) +X(0b10011001) +X(0b00011001) +X(0b11100110) +X(0b01100110) +X(0b10011101) +X(0b00011101) +X(0b11100010) +X(0b01100010) +X(0b10011100) +X(0b00011100) +X(0b11100011) +X(0b01100011) +X(0b10011110) +X(0b00011110) +X(0b11100001) +X(0b01100001) +X(0b10011111) +X(0b00011111) +X(0b11100000) +X(0b01100000) +X(0b11011111) +X(0b01011111) +X(0b10100000) +X(0b00100000) +X(0b11011110) +X(0b01011110) +X(0b10100001) +X(0b00100001) +X(0b11011100) +X(0b01011100) +X(0b10100011) +X(0b00100011) +X(0b11011101) +X(0b01011101) +X(0b10100010) +X(0b00100010) +X(0b11011001) +X(0b01011001) +X(0b10100110) +X(0b00100110) +X(0b11011000) +X(0b01011000) +X(0b10100111) +X(0b00100111) +X(0b11011010) +X(0b01011010) +X(0b10100101) +X(0b00100101) +X(0b11011011) +X(0b01011011) +X(0b10100100) +X(0b00100100) +X(0b11010011) +X(0b01010011) +X(0b10101100) +X(0b00101100) +X(0b11010010) +X(0b01010010) +X(0b10101101) +X(0b00101101) +X(0b11010000) +X(0b01010000) +X(0b10101111) +X(0b00101111) +X(0b11010001) +X(0b01010001) +X(0b10101110) +X(0b00101110) +X(0b11010101) +X(0b01010101) +X(0b10101010) +X(0b00101010) +X(0b11010100) +X(0b01010100) +X(0b10101011) +X(0b00101011) +X(0b11010110) +X(0b01010110) +X(0b10101001) +X(0b00101001) +X(0b11010111) +X(0b01010111) +X(0b10101000) +X(0b00101000) +X(0b11000111) +X(0b01000111) +X(0b10111000) +X(0b00111000) +X(0b11000110) +X(0b01000110) +X(0b10111001) +X(0b00111001) +X(0b11000100) +X(0b01000100) +X(0b10111011) +X(0b00111011) +X(0b11000101) +X(0b01000101) +X(0b10111010) +X(0b00111010) +X(0b11000001) +X(0b01000001) +X(0b10111110) +X(0b00111110) +X(0b11000000) +X(0b01000000) +X(0b10111111) +X(0b00111111) +X(0b11000010) +X(0b01000010) +X(0b10111101) +X(0b00111101) +X(0b11000011) +X(0b01000011) +X(0b10111100) +X(0b00111100) +X(0b11001011) +X(0b01001011) +X(0b10110100) +X(0b00110100) +X(0b11001010) +X(0b01001010) +X(0b10110101) +X(0b00110101) +X(0b11001000) +X(0b01001000) +X(0b10110111) +X(0b00110111) +X(0b11001001) +X(0b01001001) +X(0b10110110) +X(0b00110110) +X(0b11001101) +X(0b01001101) +X(0b10110010) +X(0b00110010) +X(0b11001100) +X(0b01001100) +X(0b10110011) +X(0b00110011) +X(0b11001110) +X(0b01001110) +X(0b10110001) +X(0b00110001) +X(0b11001111) +X(0b01001111) +X(0b10110000) +X(0b00110000) +X(0b11101111) +X(0b01101111) +X(0b10010000) +X(0b00010000) +X(0b11101110) +X(0b01101110) +X(0b10010001) +X(0b00010001) +X(0b11101100) +X(0b01101100) +X(0b10010011) +X(0b00010011) +X(0b11101101) +X(0b01101101) +X(0b10010010) +X(0b00010010) +X(0b11101001) +X(0b01101001) +X(0b10010110) +X(0b00010110) +X(0b11101000) +X(0b01101000) +X(0b10010111) +X(0b00010111) +X(0b11101010) +X(0b01101010) +X(0b10010101) +X(0b00010101) +X(0b11101011) +X(0b01101011) +X(0b10010100) +X(0b00010100) +X(0b11100011) +X(0b01100011) +X(0b10011100) +X(0b00011100) +X(0b11100010) +X(0b01100010) +X(0b10011101) +X(0b00011101) +X(0b11100000) +X(0b01100000) +X(0b10011111) +X(0b00011111) +X(0b11100001) +X(0b01100001) +X(0b10011110) +X(0b00011110) +X(0b11100101) +X(0b01100101) +X(0b10011010) +X(0b00011010) +X(0b11100100) +X(0b01100100) +X(0b10011011) +X(0b00011011) +X(0b11100110) +X(0b01100110) +X(0b10011001) +X(0b00011001) +X(0b11100111) +X(0b01100111) +X(0b10011000) +X(0b00011000) +X(0b11110111) +X(0b01110111) +X(0b10001000) +X(0b00001000) +X(0b11110110) +X(0b01110110) +X(0b10001001) +X(0b00001001) +X(0b11110100) +X(0b01110100) +X(0b10001011) +X(0b00001011) +X(0b11110101) +X(0b01110101) +X(0b10001010) +X(0b00001010) +X(0b11110001) +X(0b01110001) +X(0b10001110) +X(0b00001110) +X(0b11110000) +X(0b01110000) +X(0b10001111) +X(0b00001111) +X(0b11110010) +X(0b01110010) +X(0b10001101) +X(0b00001101) +X(0b11110011) +X(0b01110011) +X(0b10001100) +X(0b00001100) +X(0b11111011) +X(0b01111011) +X(0b10000100) +X(0b00000100) +X(0b11111010) +X(0b01111010) +X(0b10000101) +X(0b00000101) +X(0b11111000) +X(0b01111000) +X(0b10000111) +X(0b00000111) +X(0b11111001) +X(0b01111001) +X(0b10000110) +X(0b00000110) +X(0b11111101) +X(0b01111101) +X(0b10000010) +X(0b00000010) +X(0b11111100) +X(0b01111100) +X(0b10000011) +X(0b00000011) +X(0b11111110) +X(0b01111110) +X(0b10000001) +X(0b00000001) +X(0b11111111) +X(0b01111111) +X(0b10000000) +X(0b00000000) diff --git a/flashimg/cpu_hdmi/tmds_decode_table.h.gen b/flashimg/cpu_hdmi/tmds_decode_table.h.gen new file mode 100755 index 0000000..f3b330f --- /dev/null +++ b/flashimg/cpu_hdmi/tmds_decode_table.h.gen @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# flashimg/cpu_hdmi/tmds_decode_table.h.gen - Generate a table for TMDS decoding +# +# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +import sys + +print(f"// Generated by `{' '.join(sys.argv)}`. DO NOT EDIT!") +for enc in range(1 << 10): + D = [bool((enc >> (9 - i)) & 1) for i in range(10)] + # Algorithm from DVI 1.0 Figure 3-6 + if D[9]: + for i in range(8): + D[i] = not D[i] + if D[8]: + Q = [ + D[0], + D[1] != D[0], + D[2] != D[1], + D[3] != D[2], + D[4] != D[3], + D[5] != D[4], + D[6] != D[5], + D[7] != D[6], + ] + else: + Q = [ + D[0], + D[1] == D[0], + D[2] == D[1], + D[3] == D[2], + D[4] == D[3], + D[5] == D[4], + D[6] == D[5], + D[7] == D[6], + ] + s = "".join("1" if b else "0" for b in Q) + print(f"X(0b{s})") |