kopia lustrzana https://github.com/Wren6991/PicoDVI
Add colour terminal demo
rodzic
cb56252a0b
commit
0af9473d46
|
@ -0,0 +1,2 @@
|
|||
.vscode
|
||||
build
|
|
@ -1,4 +1,5 @@
|
|||
add_subdirectory(bad_apple)
|
||||
add_subdirectory(colour_terminal)
|
||||
add_subdirectory(dht_logging)
|
||||
add_subdirectory(dual_display)
|
||||
add_subdirectory(hello_dvi)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
add_executable(colour_terminal
|
||||
main.c
|
||||
tmds_encode_font_2bpp.S
|
||||
tmds_encode_font_2bpp.h
|
||||
)
|
||||
|
||||
target_compile_definitions(colour_terminal PRIVATE
|
||||
DVI_VERTICAL_REPEAT=1
|
||||
)
|
||||
|
||||
# We have a lot in SRAM4 (particularly TMDS LUT) but don't need much stack on
|
||||
# core 1. Probably even 256 bytes would be fine.
|
||||
target_compile_definitions(colour_terminal PRIVATE PICO_CORE1_STACK_SIZE=0x200)
|
||||
|
||||
target_link_libraries(colour_terminal
|
||||
pico_stdlib
|
||||
pico_multicore
|
||||
libdvi
|
||||
)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(colour_terminal)
|
|
@ -0,0 +1,143 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "hardware/structs/bus_ctrl.h"
|
||||
#include "hardware/structs/ssi.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "pico/sem.h"
|
||||
|
||||
#include "dvi.h"
|
||||
#include "dvi_serialiser.h"
|
||||
#include "common_dvi_pin_configs.h"
|
||||
#include "tmds_encode_font_2bpp.h"
|
||||
|
||||
// TODO should put this in scratch_x, it out to fit...
|
||||
#include "font_8x8.h"
|
||||
#define FONT_CHAR_WIDTH 8
|
||||
#define FONT_CHAR_HEIGHT 8
|
||||
#define FONT_N_CHARS 95
|
||||
#define FONT_FIRST_ASCII 32
|
||||
|
||||
|
||||
// Pick one:
|
||||
#define MODE_640x480_60Hz
|
||||
// #define MODE_800x600_60Hz
|
||||
// #define MODE_960x540p_60Hz
|
||||
// #define MODE_1280x720_30Hz
|
||||
|
||||
#if defined(MODE_640x480_60Hz)
|
||||
// DVDD 1.2V (1.1V seems ok too)
|
||||
#define FRAME_WIDTH 640
|
||||
#define FRAME_HEIGHT 480
|
||||
#define VREG_VSEL VREG_VOLTAGE_1_20
|
||||
#define DVI_TIMING dvi_timing_640x480p_60hz
|
||||
|
||||
#elif defined(MODE_800x600_60Hz)
|
||||
// DVDD 1.3V, going downhill with a tailwind
|
||||
#define FRAME_WIDTH 800
|
||||
#define FRAME_HEIGHT 600
|
||||
#define VREG_VSEL VREG_VOLTAGE_1_30
|
||||
#define DVI_TIMING dvi_timing_800x600p_60hz
|
||||
|
||||
|
||||
#elif defined(MODE_960x540p_60Hz)
|
||||
// DVDD 1.25V (slower silicon may need the full 1.3, or just not work)
|
||||
#define FRAME_WIDTH 960
|
||||
#define FRAME_HEIGHT 540
|
||||
#define VREG_VSEL VREG_VOLTAGE_1_25
|
||||
#define DVI_TIMING dvi_timing_960x540p_60hz
|
||||
|
||||
#elif defined(MODE_1280x720_30Hz)
|
||||
// 1280x720p 30 Hz (nonstandard)
|
||||
// DVDD 1.25V (slower silicon may need the full 1.3, or just not work)
|
||||
#define FRAME_WIDTH 1280
|
||||
#define FRAME_HEIGHT 720
|
||||
#define VREG_VSEL VREG_VOLTAGE_1_25
|
||||
#define DVI_TIMING dvi_timing_1280x720p_30hz
|
||||
|
||||
#else
|
||||
#error "Select a video mode!"
|
||||
#endif
|
||||
|
||||
struct dvi_inst dvi0;
|
||||
|
||||
#define CHAR_COLS (FRAME_WIDTH / FONT_CHAR_WIDTH)
|
||||
#define CHAR_ROWS (FRAME_HEIGHT / FONT_CHAR_HEIGHT)
|
||||
|
||||
#define COLOUR_PLANE_SIZE_WORDS (CHAR_ROWS * CHAR_COLS * 4 / 32)
|
||||
char charbuf[CHAR_ROWS * CHAR_COLS];
|
||||
uint32_t colourbuf[3 * COLOUR_PLANE_SIZE_WORDS];
|
||||
|
||||
static inline void set_char(uint x, uint y, char c) {
|
||||
if (x >= CHAR_COLS || y >= CHAR_ROWS)
|
||||
return;
|
||||
charbuf[x + y * CHAR_COLS] = c;
|
||||
}
|
||||
|
||||
// Pixel format RGB222
|
||||
static inline void set_colour(uint x, uint y, uint8_t fg, uint8_t bg) {
|
||||
if (x >= CHAR_COLS || y >= CHAR_ROWS)
|
||||
return;
|
||||
uint char_index = x + y * CHAR_COLS;
|
||||
uint bit_index = char_index % 8 * 4;
|
||||
uint word_index = char_index / 8;
|
||||
for (int plane = 0; plane < 3; ++plane) {
|
||||
uint32_t fg_bg_combined = (fg & 0x3) | (bg << 2 & 0xc);
|
||||
colourbuf[word_index] = (colourbuf[word_index] & ~(0xfu << bit_index)) | (fg_bg_combined << bit_index);
|
||||
fg >>= 2;
|
||||
bg >>= 2;
|
||||
word_index += COLOUR_PLANE_SIZE_WORDS;
|
||||
}
|
||||
}
|
||||
|
||||
void core1_main() {
|
||||
dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
|
||||
dvi_start(&dvi0);
|
||||
while (true) {
|
||||
for (uint y = 0; y < FRAME_HEIGHT; ++y) {
|
||||
uint32_t *tmdsbuf;
|
||||
queue_remove_blocking(&dvi0.q_tmds_free, &tmdsbuf);
|
||||
for (int plane = 0; plane < 3; ++plane) {
|
||||
tmds_encode_font_2bpp(
|
||||
(const uint8_t*)&charbuf[y / FONT_CHAR_HEIGHT * CHAR_COLS],
|
||||
&colourbuf[y / FONT_CHAR_HEIGHT * (COLOUR_PLANE_SIZE_WORDS / CHAR_ROWS) + plane * COLOUR_PLANE_SIZE_WORDS],
|
||||
tmdsbuf + plane * (FRAME_WIDTH / DVI_SYMBOLS_PER_WORD),
|
||||
FRAME_WIDTH,
|
||||
(const uint8_t*)&font_8x8[y % FONT_CHAR_HEIGHT * FONT_N_CHARS] - FONT_FIRST_ASCII
|
||||
);
|
||||
}
|
||||
queue_add_blocking(&dvi0.q_tmds_valid, &tmdsbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int __not_in_flash("main") main() {
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
// Run system at TMDS bit clock
|
||||
set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);
|
||||
|
||||
dvi0.timing = &DVI_TIMING;
|
||||
dvi0.ser_cfg = DEFAULT_DVI_SERIAL_CONFIG;
|
||||
dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
|
||||
|
||||
for (uint y = 0; y < CHAR_ROWS; ++y) {
|
||||
for (uint x = 0; x < CHAR_COLS; ++x) {
|
||||
set_char(x, y, (x + y * CHAR_COLS) % FONT_N_CHARS + FONT_FIRST_ASCII);
|
||||
set_colour(x, y, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
hw_set_bits(&bus_ctrl_hw->priority, BUSCTRL_BUS_PRIORITY_PROC1_BITS);
|
||||
multicore_launch_core1(core1_main);
|
||||
|
||||
while (1)
|
||||
__wfi();
|
||||
}
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/sio.h"
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
||||
// Using the following:
|
||||
//
|
||||
// - A font stored as a 1bpp bitmap, with row 0 of each character stored in
|
||||
// one contiguous array, then row 1, etc, where each character is 8 bits
|
||||
// wide
|
||||
//
|
||||
// - A character buffer
|
||||
//
|
||||
// - A colour buffer for each of R, G, B (so 3 planes total), each buffer
|
||||
// storing a 2-bit foreground and background colour for each character
|
||||
//
|
||||
// Generate encoded TMDS buffers, fast enough to fit all the encode on one
|
||||
// core, and with small memory footprint (so no framebuffer of any depth!) The
|
||||
// main trick here is a LUT with an 8 bit index, composed of 4x1bpp pixels
|
||||
// (the 4 LSBs of the index) and a 2x2-bit palette (the four MSBs of the
|
||||
// index). Each LUT entry is 4 TMDS symbols, so 2 32-bit words, giving a total
|
||||
// table size of 2 kB.
|
||||
|
||||
// Offsets suitable for ldr/str (must be <= 0x7c):
|
||||
#define ACCUM0_OFFS (SIO_INTERP0_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define ACCUM1_OFFS (SIO_INTERP0_ACCUM1_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define ACCUM1_ADD_OFFS (SIO_INTERP0_ACCUM1_ADD_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define PEEK0_OFFS (SIO_INTERP0_PEEK_LANE0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define PEEK1_OFFS (SIO_INTERP0_PEEK_LANE1_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define PEEK2_OFFS (SIO_INTERP0_PEEK_FULL_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
#define INTERP1 (SIO_INTERP1_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET)
|
||||
|
||||
// There is no vertical repeat, so the the budget (ignoring DMA IRQs) is 8000
|
||||
// cycles per 640 pixels, and there are three symbols to be generated per
|
||||
// pixel, so 4.17 cyc/pix.
|
||||
|
||||
|
||||
// Once in the loop:
|
||||
// r0 contains character buffer pointer (only updated once per 8 chars)
|
||||
// r1 contains 8 2-colour 2bpp palettes, enough for 8 characters
|
||||
// r2 contains output buffer pointer
|
||||
// r3 contains a mask for the colour lookup bits
|
||||
// r4-r7 are for scratch + pixels
|
||||
// r8 contains a pointer to the font bitmap for this scanline.
|
||||
// r9 contains the TMDS LUT base.
|
||||
.macro do_char charbuf_offs colour_shift_instr colour_shamt
|
||||
// Get 8x font bits for next character, put 4 LSBs in bits 6:3 of r4 (so
|
||||
// scaled to 8-byte LUT entries), and 4 MSBs in bits 6:3 of r6.
|
||||
ldrb r4, [r0, #\charbuf_offs] // 2
|
||||
add r4, r8 // 1
|
||||
ldrb r4, [r4] // 2
|
||||
lsrs r6, r4, #4 // 1
|
||||
lsls r6, #3 // 1
|
||||
lsls r4, #28 // 1
|
||||
lsrs r4, #25 // 1
|
||||
|
||||
// Get colour bits, add to TMDS LUT base and font bits
|
||||
\colour_shift_instr r5, r1, #\colour_shamt // 1
|
||||
ands r5, r3 // 1
|
||||
add r5, r9 // 1
|
||||
add r4, r5 // 1
|
||||
add r6, r5 // 1
|
||||
|
||||
// Look up and write out 8 TMDS symbols
|
||||
ldmia r4, {r4, r5} // 3
|
||||
ldmia r6, {r6, r7} // 3
|
||||
stmia r2!, {r4-r7} // 5
|
||||
.endm
|
||||
|
||||
|
||||
// r0 is character buffer
|
||||
// r1 is colour buffer
|
||||
// r2 is output TMDS buffer
|
||||
// r3 is pixel count
|
||||
// First stack argument is the font bitmap for this scanline.
|
||||
|
||||
.section .scratch_x.tmds_encode_font_2bpp, "ax"
|
||||
.global tmds_encode_font_2bpp
|
||||
.type tmds_encode_font_2bpp,%function
|
||||
.thumb_func
|
||||
tmds_encode_font_2bpp:
|
||||
push {r4-r7, lr}
|
||||
mov r4, r8
|
||||
mov r5, r9
|
||||
mov r6, r10
|
||||
push {r4-r6}
|
||||
|
||||
lsls r3, #1
|
||||
add r3, r2
|
||||
mov ip, r3
|
||||
ldr r3, =(0xf0 * 8)
|
||||
|
||||
ldr r7, [sp, #32] // 8 words saved, so 32-byte offset to first stack argument
|
||||
mov r8, r7
|
||||
ldr r7, =palettised_1bpp_tables
|
||||
mov r9, r7
|
||||
|
||||
mov r10, r1
|
||||
|
||||
b 2f
|
||||
1:
|
||||
mov r4, r10
|
||||
ldmia r4!, {r1}
|
||||
mov r10, r4
|
||||
do_char 0 lsls 7
|
||||
do_char 1 lsls 3
|
||||
do_char 2 lsrs 1
|
||||
do_char 3 lsrs 5
|
||||
do_char 4 lsrs 9
|
||||
do_char 5 lsrs 13
|
||||
do_char 6 lsrs 17
|
||||
do_char 7 lsrs 21
|
||||
adds r0, #8
|
||||
2:
|
||||
cmp r2, ip
|
||||
blo 1b
|
||||
|
||||
pop {r4-r6}
|
||||
mov r8, r4
|
||||
mov r9, r5
|
||||
mov r10, r6
|
||||
pop {r4-r7, pc}
|
||||
|
||||
|
||||
// Table generation:
|
||||
// levels_2bpp_even = [0x05, 0x50, 0xaf, 0xfa]
|
||||
// levels_2bpp_odd = [0x04, 0x51, 0xae, 0xfb]
|
||||
//
|
||||
// def level(bg, fg, x, pix):
|
||||
// index = fg if pix & 1 << x else bg
|
||||
// return (levels_2bpp_odd if x & 1 else levels_2bpp_even)[index]
|
||||
//
|
||||
// for background in range(4):
|
||||
// for foreground in range(4):
|
||||
// print(f"// background, foreground = {background:02b}, {foreground:02b}")
|
||||
// for pixrun in range(16):
|
||||
// sym = list(enc.encode(level(background, foreground, x, pixrun), 0, 1) for x in range(4))
|
||||
// assert(enc.imbalance == 0)
|
||||
// print(f".word 0x{sym[1] << 10 | sym[0]:05x}, 0x{sym[3] << 10 | sym[2]:05x} // {pixrun:04b}")
|
||||
|
||||
.section .scratch_x.palettised_1bpp_tables, "a"
|
||||
.align 2
|
||||
palettised_1bpp_tables:
|
||||
// background, foreground = 00, 00
|
||||
.word 0x7f103, 0x7f103 // 0000
|
||||
.word 0x7f103, 0x7f103 // 0001
|
||||
.word 0x7f103, 0x7f103 // 0010
|
||||
.word 0x7f103, 0x7f103 // 0011
|
||||
.word 0x7f103, 0x7f103 // 0100
|
||||
.word 0x7f103, 0x7f103 // 0101
|
||||
.word 0x7f103, 0x7f103 // 0110
|
||||
.word 0x7f103, 0x7f103 // 0111
|
||||
.word 0x7f103, 0x7f103 // 1000
|
||||
.word 0x7f103, 0x7f103 // 1001
|
||||
.word 0x7f103, 0x7f103 // 1010
|
||||
.word 0x7f103, 0x7f103 // 1011
|
||||
.word 0x7f103, 0x7f103 // 1100
|
||||
.word 0x7f103, 0x7f103 // 1101
|
||||
.word 0x7f103, 0x7f103 // 1110
|
||||
.word 0x7f103, 0x7f103 // 1111
|
||||
// background, foreground = 00, 01
|
||||
.word 0x7f103, 0x7f103 // 0000
|
||||
.word 0x7f130, 0x7f103 // 0001
|
||||
.word 0x73d03, 0x7f103 // 0010
|
||||
.word 0x73d30, 0x7f103 // 0011
|
||||
.word 0x7f103, 0x7f130 // 0100
|
||||
.word 0x7f130, 0x7f130 // 0101
|
||||
.word 0x73d03, 0x7f130 // 0110
|
||||
.word 0x73d30, 0x7f130 // 0111
|
||||
.word 0x7f103, 0x73d03 // 1000
|
||||
.word 0x7f130, 0x73d03 // 1001
|
||||
.word 0x73d03, 0x73d03 // 1010
|
||||
.word 0x73d30, 0x73d03 // 1011
|
||||
.word 0x7f103, 0x73d30 // 1100
|
||||
.word 0x7f130, 0x73d30 // 1101
|
||||
.word 0x73d03, 0x73d30 // 1110
|
||||
.word 0x73d30, 0x73d30 // 1111
|
||||
// background, foreground = 00, 10
|
||||
.word 0x7f103, 0x7f103 // 0000
|
||||
.word 0x7f230, 0x7f103 // 0001
|
||||
.word 0xb3d03, 0x7f103 // 0010
|
||||
.word 0xb3e30, 0x7f103 // 0011
|
||||
.word 0x7f103, 0x7f230 // 0100
|
||||
.word 0x7f230, 0x7f230 // 0101
|
||||
.word 0xb3d03, 0x7f230 // 0110
|
||||
.word 0xb3e30, 0x7f230 // 0111
|
||||
.word 0x7f103, 0xb3d03 // 1000
|
||||
.word 0x7f230, 0xb3d03 // 1001
|
||||
.word 0xb3d03, 0xb3d03 // 1010
|
||||
.word 0xb3e30, 0xb3d03 // 1011
|
||||
.word 0x7f103, 0xb3e30 // 1100
|
||||
.word 0x7f230, 0xb3e30 // 1101
|
||||
.word 0xb3d03, 0xb3e30 // 1110
|
||||
.word 0xb3e30, 0xb3e30 // 1111
|
||||
// background, foreground = 00, 11
|
||||
.word 0x7f103, 0x7f103 // 0000
|
||||
.word 0x7f203, 0x7f103 // 0001
|
||||
.word 0xbf103, 0x7f103 // 0010
|
||||
.word 0xbf203, 0x7f103 // 0011
|
||||
.word 0x7f103, 0x7f203 // 0100
|
||||
.word 0x7f203, 0x7f203 // 0101
|
||||
.word 0xbf103, 0x7f203 // 0110
|
||||
.word 0xbf203, 0x7f203 // 0111
|
||||
.word 0x7f103, 0xbf103 // 1000
|
||||
.word 0x7f203, 0xbf103 // 1001
|
||||
.word 0xbf103, 0xbf103 // 1010
|
||||
.word 0xbf203, 0xbf103 // 1011
|
||||
.word 0x7f103, 0xbf203 // 1100
|
||||
.word 0x7f203, 0xbf203 // 1101
|
||||
.word 0xbf103, 0xbf203 // 1110
|
||||
.word 0xbf203, 0xbf203 // 1111
|
||||
// background, foreground = 01, 00
|
||||
.word 0x73d30, 0x73d30 // 0000
|
||||
.word 0x73d03, 0x73d30 // 0001
|
||||
.word 0x7f130, 0x73d30 // 0010
|
||||
.word 0x7f103, 0x73d30 // 0011
|
||||
.word 0x73d30, 0x73d03 // 0100
|
||||
.word 0x73d03, 0x73d03 // 0101
|
||||
.word 0x7f130, 0x73d03 // 0110
|
||||
.word 0x7f103, 0x73d03 // 0111
|
||||
.word 0x73d30, 0x7f130 // 1000
|
||||
.word 0x73d03, 0x7f130 // 1001
|
||||
.word 0x7f130, 0x7f130 // 1010
|
||||
.word 0x7f103, 0x7f130 // 1011
|
||||
.word 0x73d30, 0x7f103 // 1100
|
||||
.word 0x73d03, 0x7f103 // 1101
|
||||
.word 0x7f130, 0x7f103 // 1110
|
||||
.word 0x7f103, 0x7f103 // 1111
|
||||
// background, foreground = 01, 01
|
||||
.word 0x73d30, 0x73d30 // 0000
|
||||
.word 0x73d30, 0x73d30 // 0001
|
||||
.word 0x73d30, 0x73d30 // 0010
|
||||
.word 0x73d30, 0x73d30 // 0011
|
||||
.word 0x73d30, 0x73d30 // 0100
|
||||
.word 0x73d30, 0x73d30 // 0101
|
||||
.word 0x73d30, 0x73d30 // 0110
|
||||
.word 0x73d30, 0x73d30 // 0111
|
||||
.word 0x73d30, 0x73d30 // 1000
|
||||
.word 0x73d30, 0x73d30 // 1001
|
||||
.word 0x73d30, 0x73d30 // 1010
|
||||
.word 0x73d30, 0x73d30 // 1011
|
||||
.word 0x73d30, 0x73d30 // 1100
|
||||
.word 0x73d30, 0x73d30 // 1101
|
||||
.word 0x73d30, 0x73d30 // 1110
|
||||
.word 0x73d30, 0x73d30 // 1111
|
||||
// background, foreground = 01, 10
|
||||
.word 0x73d30, 0x73d30 // 0000
|
||||
.word 0x73e30, 0x73d30 // 0001
|
||||
.word 0xb3d30, 0x73d30 // 0010
|
||||
.word 0xb3e30, 0x73d30 // 0011
|
||||
.word 0x73d30, 0x73e30 // 0100
|
||||
.word 0x73e30, 0x73e30 // 0101
|
||||
.word 0xb3d30, 0x73e30 // 0110
|
||||
.word 0xb3e30, 0x73e30 // 0111
|
||||
.word 0x73d30, 0xb3d30 // 1000
|
||||
.word 0x73e30, 0xb3d30 // 1001
|
||||
.word 0xb3d30, 0xb3d30 // 1010
|
||||
.word 0xb3e30, 0xb3d30 // 1011
|
||||
.word 0x73d30, 0xb3e30 // 1100
|
||||
.word 0x73e30, 0xb3e30 // 1101
|
||||
.word 0xb3d30, 0xb3e30 // 1110
|
||||
.word 0xb3e30, 0xb3e30 // 1111
|
||||
// background, foreground = 01, 11
|
||||
.word 0x73d30, 0x73d30 // 0000
|
||||
.word 0x73e03, 0x73d30 // 0001
|
||||
.word 0xbf130, 0x73d30 // 0010
|
||||
.word 0xbf203, 0x73d30 // 0011
|
||||
.word 0x73d30, 0x73e03 // 0100
|
||||
.word 0x73e03, 0x73e03 // 0101
|
||||
.word 0xbf130, 0x73e03 // 0110
|
||||
.word 0xbf203, 0x73e03 // 0111
|
||||
.word 0x73d30, 0xbf130 // 1000
|
||||
.word 0x73e03, 0xbf130 // 1001
|
||||
.word 0xbf130, 0xbf130 // 1010
|
||||
.word 0xbf203, 0xbf130 // 1011
|
||||
.word 0x73d30, 0xbf203 // 1100
|
||||
.word 0x73e03, 0xbf203 // 1101
|
||||
.word 0xbf130, 0xbf203 // 1110
|
||||
.word 0xbf203, 0xbf203 // 1111
|
||||
// background, foreground = 10, 00
|
||||
.word 0xb3e30, 0xb3e30 // 0000
|
||||
.word 0xb3d03, 0xb3e30 // 0001
|
||||
.word 0x7f230, 0xb3e30 // 0010
|
||||
.word 0x7f103, 0xb3e30 // 0011
|
||||
.word 0xb3e30, 0xb3d03 // 0100
|
||||
.word 0xb3d03, 0xb3d03 // 0101
|
||||
.word 0x7f230, 0xb3d03 // 0110
|
||||
.word 0x7f103, 0xb3d03 // 0111
|
||||
.word 0xb3e30, 0x7f230 // 1000
|
||||
.word 0xb3d03, 0x7f230 // 1001
|
||||
.word 0x7f230, 0x7f230 // 1010
|
||||
.word 0x7f103, 0x7f230 // 1011
|
||||
.word 0xb3e30, 0x7f103 // 1100
|
||||
.word 0xb3d03, 0x7f103 // 1101
|
||||
.word 0x7f230, 0x7f103 // 1110
|
||||
.word 0x7f103, 0x7f103 // 1111
|
||||
// background, foreground = 10, 01
|
||||
.word 0xb3e30, 0xb3e30 // 0000
|
||||
.word 0xb3d30, 0xb3e30 // 0001
|
||||
.word 0x73e30, 0xb3e30 // 0010
|
||||
.word 0x73d30, 0xb3e30 // 0011
|
||||
.word 0xb3e30, 0xb3d30 // 0100
|
||||
.word 0xb3d30, 0xb3d30 // 0101
|
||||
.word 0x73e30, 0xb3d30 // 0110
|
||||
.word 0x73d30, 0xb3d30 // 0111
|
||||
.word 0xb3e30, 0x73e30 // 1000
|
||||
.word 0xb3d30, 0x73e30 // 1001
|
||||
.word 0x73e30, 0x73e30 // 1010
|
||||
.word 0x73d30, 0x73e30 // 1011
|
||||
.word 0xb3e30, 0x73d30 // 1100
|
||||
.word 0xb3d30, 0x73d30 // 1101
|
||||
.word 0x73e30, 0x73d30 // 1110
|
||||
.word 0x73d30, 0x73d30 // 1111
|
||||
// background, foreground = 10, 10
|
||||
.word 0xb3e30, 0xb3e30 // 0000
|
||||
.word 0xb3e30, 0xb3e30 // 0001
|
||||
.word 0xb3e30, 0xb3e30 // 0010
|
||||
.word 0xb3e30, 0xb3e30 // 0011
|
||||
.word 0xb3e30, 0xb3e30 // 0100
|
||||
.word 0xb3e30, 0xb3e30 // 0101
|
||||
.word 0xb3e30, 0xb3e30 // 0110
|
||||
.word 0xb3e30, 0xb3e30 // 0111
|
||||
.word 0xb3e30, 0xb3e30 // 1000
|
||||
.word 0xb3e30, 0xb3e30 // 1001
|
||||
.word 0xb3e30, 0xb3e30 // 1010
|
||||
.word 0xb3e30, 0xb3e30 // 1011
|
||||
.word 0xb3e30, 0xb3e30 // 1100
|
||||
.word 0xb3e30, 0xb3e30 // 1101
|
||||
.word 0xb3e30, 0xb3e30 // 1110
|
||||
.word 0xb3e30, 0xb3e30 // 1111
|
||||
// background, foreground = 10, 11
|
||||
.word 0xb3e30, 0xb3e30 // 0000
|
||||
.word 0xb3e03, 0xb3e30 // 0001
|
||||
.word 0xbf230, 0xb3e30 // 0010
|
||||
.word 0xbf203, 0xb3e30 // 0011
|
||||
.word 0xb3e30, 0xb3e03 // 0100
|
||||
.word 0xb3e03, 0xb3e03 // 0101
|
||||
.word 0xbf230, 0xb3e03 // 0110
|
||||
.word 0xbf203, 0xb3e03 // 0111
|
||||
.word 0xb3e30, 0xbf230 // 1000
|
||||
.word 0xb3e03, 0xbf230 // 1001
|
||||
.word 0xbf230, 0xbf230 // 1010
|
||||
.word 0xbf203, 0xbf230 // 1011
|
||||
.word 0xb3e30, 0xbf203 // 1100
|
||||
.word 0xb3e03, 0xbf203 // 1101
|
||||
.word 0xbf230, 0xbf203 // 1110
|
||||
.word 0xbf203, 0xbf203 // 1111
|
||||
// background, foreground = 11, 00
|
||||
.word 0xbf203, 0xbf203 // 0000
|
||||
.word 0xbf103, 0xbf203 // 0001
|
||||
.word 0x7f203, 0xbf203 // 0010
|
||||
.word 0x7f103, 0xbf203 // 0011
|
||||
.word 0xbf203, 0xbf103 // 0100
|
||||
.word 0xbf103, 0xbf103 // 0101
|
||||
.word 0x7f203, 0xbf103 // 0110
|
||||
.word 0x7f103, 0xbf103 // 0111
|
||||
.word 0xbf203, 0x7f203 // 1000
|
||||
.word 0xbf103, 0x7f203 // 1001
|
||||
.word 0x7f203, 0x7f203 // 1010
|
||||
.word 0x7f103, 0x7f203 // 1011
|
||||
.word 0xbf203, 0x7f103 // 1100
|
||||
.word 0xbf103, 0x7f103 // 1101
|
||||
.word 0x7f203, 0x7f103 // 1110
|
||||
.word 0x7f103, 0x7f103 // 1111
|
||||
// background, foreground = 11, 01
|
||||
.word 0xbf203, 0xbf203 // 0000
|
||||
.word 0xbf130, 0xbf203 // 0001
|
||||
.word 0x73e03, 0xbf203 // 0010
|
||||
.word 0x73d30, 0xbf203 // 0011
|
||||
.word 0xbf203, 0xbf130 // 0100
|
||||
.word 0xbf130, 0xbf130 // 0101
|
||||
.word 0x73e03, 0xbf130 // 0110
|
||||
.word 0x73d30, 0xbf130 // 0111
|
||||
.word 0xbf203, 0x73e03 // 1000
|
||||
.word 0xbf130, 0x73e03 // 1001
|
||||
.word 0x73e03, 0x73e03 // 1010
|
||||
.word 0x73d30, 0x73e03 // 1011
|
||||
.word 0xbf203, 0x73d30 // 1100
|
||||
.word 0xbf130, 0x73d30 // 1101
|
||||
.word 0x73e03, 0x73d30 // 1110
|
||||
.word 0x73d30, 0x73d30 // 1111
|
||||
// background, foreground = 11, 10
|
||||
.word 0xbf203, 0xbf203 // 0000
|
||||
.word 0xbf230, 0xbf203 // 0001
|
||||
.word 0xb3e03, 0xbf203 // 0010
|
||||
.word 0xb3e30, 0xbf203 // 0011
|
||||
.word 0xbf203, 0xbf230 // 0100
|
||||
.word 0xbf230, 0xbf230 // 0101
|
||||
.word 0xb3e03, 0xbf230 // 0110
|
||||
.word 0xb3e30, 0xbf230 // 0111
|
||||
.word 0xbf203, 0xb3e03 // 1000
|
||||
.word 0xbf230, 0xb3e03 // 1001
|
||||
.word 0xb3e03, 0xb3e03 // 1010
|
||||
.word 0xb3e30, 0xb3e03 // 1011
|
||||
.word 0xbf203, 0xb3e30 // 1100
|
||||
.word 0xbf230, 0xb3e30 // 1101
|
||||
.word 0xb3e03, 0xb3e30 // 1110
|
||||
.word 0xb3e30, 0xb3e30 // 1111
|
||||
// background, foreground = 11, 11
|
||||
.word 0xbf203, 0xbf203 // 0000
|
||||
.word 0xbf203, 0xbf203 // 0001
|
||||
.word 0xbf203, 0xbf203 // 0010
|
||||
.word 0xbf203, 0xbf203 // 0011
|
||||
.word 0xbf203, 0xbf203 // 0100
|
||||
.word 0xbf203, 0xbf203 // 0101
|
||||
.word 0xbf203, 0xbf203 // 0110
|
||||
.word 0xbf203, 0xbf203 // 0111
|
||||
.word 0xbf203, 0xbf203 // 1000
|
||||
.word 0xbf203, 0xbf203 // 1001
|
||||
.word 0xbf203, 0xbf203 // 1010
|
||||
.word 0xbf203, 0xbf203 // 1011
|
||||
.word 0xbf203, 0xbf203 // 1100
|
||||
.word 0xbf203, 0xbf203 // 1101
|
||||
.word 0xbf203, 0xbf203 // 1110
|
||||
.word 0xbf203, 0xbf203 // 1111
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _TMDS_ENCODE_FONT_2BPP_H
|
||||
#define _TMDS_ENCODE_FONT_2BPP_H
|
||||
|
||||
#include "pico/types.h"
|
||||
|
||||
// Render characters using an 8px-wide font and a per-character 2bpp
|
||||
// foreground/background colour. This function is fast enough to run 3 times
|
||||
// per scanline on one core, so RGB222 coloured text can be rendered (with
|
||||
// separate R/G/B colour planes).
|
||||
//
|
||||
// charbuf: pointer to the row of characters (8 bits each) for the current
|
||||
// scanline (byte-aligned)
|
||||
//
|
||||
// colourbuf: pointer to a list of 2bpp foreground/background colour pairs for
|
||||
// each character (word-aligned, least-significant first within each word)
|
||||
//
|
||||
// font_line: pointer to list of 8 pixel bitmaps, each representing the
|
||||
// intersection of a font character with the current scanline. (byte-aligned)
|
||||
|
||||
void tmds_encode_font_2bpp(const uint8_t *charbuf, const uint32_t *colourbuf,
|
||||
uint32_t *tmdsbuf, uint n_pix, const uint8_t *font_line);
|
||||
|
||||
#endif
|
|
@ -9,7 +9,7 @@ add_executable(terminal
|
|||
# TODO this should work ok with DVI_N_TMDS_BUFFERS=2 (perhaps need to
|
||||
# rearrange some pushes/pops) and also as we are monochrome the buffers are 3x
|
||||
# as big as they need to be
|
||||
target_compile_definitions(terminal PRIVATE DVI_VERTICAL_REPEAT=1 DVI_N_TMDS_BUFFERS=3 DVI_MONOCHROME_TMDS)
|
||||
target_compile_definitions(terminal PRIVATE DVI_VERTICAL_REPEAT=1 DVI_N_TMDS_BUFFERS=3 DVI_MONOCHROME_TMDS=1)
|
||||
|
||||
target_link_libraries(terminal
|
||||
pico_stdlib
|
||||
|
|
Ładowanie…
Reference in New Issue