switch to the new vt emulator (untested)
This commit is contained in:
parent
c7d87d4cf9
commit
e430750beb
5 changed files with 49 additions and 187 deletions
|
|
@ -13,7 +13,15 @@ pico_sdk_init()
|
|||
|
||||
project(pico-cr100)
|
||||
|
||||
add_executable(cr100 chargen.c vt.c keyboard.c)
|
||||
add_executable(cr100
|
||||
chargen.c
|
||||
vt.c
|
||||
keyboard.c
|
||||
hl-vt100/src/lw_terminal_parser.c
|
||||
hl-vt100/src/lw_terminal_vt100.c
|
||||
)
|
||||
|
||||
target_include_directories(cr100 PRIVATE hl-vt100/src)
|
||||
|
||||
pico_enable_stdio_usb(cr100 1)
|
||||
|
||||
|
|
|
|||
10
atkbd.pio
10
atkbd.pio
|
|
@ -44,8 +44,8 @@ send_bit:
|
|||
|
||||
% c-sdk {
|
||||
#include "hardware/clocks.h"
|
||||
void atkbd_program_init(PIO pio, int sm, int base_pin) {
|
||||
pio_sm_config c = vga_660x400_70_program_get_default_config(offset);
|
||||
void atkbd_program_init(PIO pio, int sm, int offset, int base_pin) {
|
||||
pio_sm_config c = atkbd_program_get_default_config(offset);
|
||||
|
||||
sm_config_set_in_pins(&c, base_pin);
|
||||
sm_config_set_in_shift(&c, 1, 1, 10);
|
||||
|
|
@ -57,14 +57,14 @@ void atkbd_program_init(PIO pio, int sm, int base_pin) {
|
|||
|
||||
sm_config_set_jmp_pin(&c, base_pin + 1);
|
||||
|
||||
sm_config_set_clkdiv(&c, clock_get_hz(clk_sys() / 8000000); // 8 MHz
|
||||
sm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / 8000000); // 8 MHz
|
||||
|
||||
// Set this pin's GPIO function (connect PIO to the pad)
|
||||
pio_gpio_init(pio, base_pin);
|
||||
pio_gpio_init(pio, base_pin+1);
|
||||
|
||||
// make sure the pins are outputs
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 2, false);
|
||||
// make sure the pins are initially inputs
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, base_pin, 2, false);
|
||||
|
||||
// Load our configuration, and jump to the start of the program
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
|
|
|
|||
202
chargen.c
202
chargen.c
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "vga_660x477_60.pio.h"
|
||||
|
||||
#include "vt.h"
|
||||
#include "lw_terminal_vt100.h"
|
||||
|
||||
int pixels_sm;
|
||||
|
||||
|
|
@ -26,6 +26,8 @@ int pixels_sm;
|
|||
#define CHAR_Y (9)
|
||||
#define FB_HEIGHT_PIXEL (FB_HEIGHT_CHAR * CHAR_Y)
|
||||
|
||||
struct lw_terminal_vt100 *vt100;
|
||||
|
||||
void __not_in_flash_func(scan_convert)(const uint32_t * restrict cptr32, const uint16_t * restrict cgptr, const uint16_t * restrict shade) {
|
||||
#define READ_CHARDATA \
|
||||
(ch = *cptr32++)
|
||||
|
|
@ -83,67 +85,8 @@ uint16_t chargen[256*CHAR_Y] = {
|
|||
int cx, cy, attr = 0x300;
|
||||
|
||||
_Static_assert(FB_WIDTH_CHAR % 6 == 0);
|
||||
uint32_t chardata32[FB_WIDTH_CHAR * FB_HEIGHT_CHAR / 2];
|
||||
|
||||
int readchar(int cx, int cy) {
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
int i = cx + cy * FB_WIDTH_CHAR;
|
||||
return chardata[i] & 0xff;
|
||||
}
|
||||
int readattr(int cx, int cy) {
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
int i = cx + cy * FB_WIDTH_CHAR;
|
||||
return chardata[i] & 0xff00;
|
||||
}
|
||||
|
||||
void setchar(int cx, int cy, int ch) {
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
int i = cx + cy * FB_WIDTH_CHAR;
|
||||
chardata[i] = (chardata[i] & 0xff00) | ch;
|
||||
}
|
||||
void setattr(int cx, int cy, int attr) {
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
int i = cx + cy * FB_WIDTH_CHAR;
|
||||
chardata[i] = (chardata[i] & 0xff) | attr;
|
||||
}
|
||||
|
||||
void scroll_terminal() {
|
||||
|
||||
memmove(chardata32, chardata32 + FB_WIDTH_CHAR / 2, FB_WIDTH_CHAR * (FB_HEIGHT_CHAR - 1) * 2);
|
||||
uint32_t mask = attr | (attr << 16);
|
||||
for(size_t i=0; i<FB_WIDTH_CHAR / 2; i++) {
|
||||
chardata32[(FB_HEIGHT_CHAR-1) * FB_WIDTH_CHAR / 2 + i] = mask;
|
||||
}
|
||||
}
|
||||
void increase_y() {
|
||||
cy = (cy + 1);
|
||||
if (cy == FB_HEIGHT_CHAR) {
|
||||
scroll_terminal();
|
||||
cy = FB_HEIGHT_CHAR - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int writefn(void *cookie, const char *data, int n) {
|
||||
uint16_t *chardata = cookie;
|
||||
for(; n; data++, n--) {
|
||||
switch(*data) {
|
||||
case '\r':
|
||||
cx = 0;
|
||||
break;
|
||||
case '\n':
|
||||
increase_y();
|
||||
break;
|
||||
default:
|
||||
if(*data >= 32) {
|
||||
if(cx == FB_WIDTH_CHAR) {
|
||||
cx = 0;
|
||||
increase_y();
|
||||
}
|
||||
chardata[cx + cy * FB_WIDTH_CHAR] = *data | attr;
|
||||
cx ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +96,7 @@ int scrnprintf(const char *fmt, ...) {
|
|||
va_start(ap, fmt);
|
||||
int n = vasprintf(&ptr, fmt, ap);
|
||||
va_end(ap);
|
||||
writefn((void*)chardata32, ptr, n);
|
||||
lw_terminal_vt100_read_buf(vt100, ptr, n);
|
||||
free(ptr);
|
||||
return n;
|
||||
}
|
||||
|
|
@ -199,8 +142,9 @@ void __not_in_flash_func(core1_entry)() {
|
|||
|
||||
while(true) {
|
||||
for(int row = 0; row < FB_HEIGHT_CHAR; row++) {
|
||||
uint32_t *chardata = (uint32_t*)lw_terminal_vt100_getline(vt100, row);
|
||||
for(int j=0; j<CHAR_Y; j++) {
|
||||
scan_convert(&chardata32[FB_WIDTH_CHAR * row / 2],
|
||||
scan_convert(chardata,
|
||||
&chargen[256 * j], frameno & 0x20 ? base_shade : base_shade + 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -213,147 +157,43 @@ void __not_in_flash_func(core1_entry)() {
|
|||
#define BG_ATTR(x) ((x) << 11)
|
||||
#define FG_ATTR(x) ((x) << 8)
|
||||
|
||||
int saved_attr;
|
||||
void show_cursor() {
|
||||
int xx = cx == FB_WIDTH_CHAR ? FB_WIDTH_CHAR - 1 : cx;
|
||||
saved_attr = readattr(xx, cy);
|
||||
setattr(xx, cy, saved_attr ^ BG_ATTR(7));
|
||||
}
|
||||
|
||||
void hide_cursor() {
|
||||
int xx = cx == FB_WIDTH_CHAR ? FB_WIDTH_CHAR - 1 : cx;
|
||||
setattr(xx, cy, saved_attr);
|
||||
}
|
||||
|
||||
#define MAKE_ATTR(fg, bg) ((fg) ^ (((bg) * 9) & 073))
|
||||
|
||||
esc_state vt_st;
|
||||
|
||||
void invert_screen() {
|
||||
for(size_t i=0; i<count_of(chardata32); i++) { chardata32[i] ^= 0x18001800; }
|
||||
}
|
||||
|
||||
void clear_eol(int ps) {
|
||||
size_t start = cx + cy * FB_WIDTH_CHAR, end = (cx+1) * FB_WIDTH_CHAR;
|
||||
if(ps == 1) { end = start+1; }
|
||||
if(ps > 0) { start = cy * FB_WIDTH_CHAR; }
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
for(size_t i = start; i< end; i++) { chardata[i] = 32 | attr; }
|
||||
}
|
||||
|
||||
void clear_screen(int ps) {
|
||||
size_t start = cx + cy * FB_WIDTH_CHAR, end = FB_HEIGHT_CHAR * FB_WIDTH_CHAR;
|
||||
if(ps == 1) { end = start+1; }
|
||||
if(ps > 0) { start = 0; }
|
||||
uint16_t *chardata = (void*)chardata32;
|
||||
for(size_t i = start; i< end; i++) { chardata[i] = 32 | attr; }
|
||||
}
|
||||
|
||||
void cursor_left() {
|
||||
if(cx > 0) cx -= 1;
|
||||
}
|
||||
|
||||
void cursor_position(esc_state *st) {
|
||||
// param 1 is row (cy), 1-bsaed
|
||||
if(st->esc_param[1] > 0 && st->esc_param[1] < FB_WIDTH_CHAR) {
|
||||
cx = st->esc_param[1] - 1;
|
||||
}
|
||||
// param 1 is column (cx), 1-bsaed
|
||||
if(st->esc_param[0] > 0 && st->esc_param[0] < FB_HEIGHT_CHAR) {
|
||||
cy = st->esc_param[0] - 1;
|
||||
}
|
||||
}
|
||||
#define MAKE_ATTR(fg, bg) (((fg) ^ (((bg) * 9) & 073)) << 8)
|
||||
|
||||
int map_one(int i) {
|
||||
return (i > 0) + (i > 6);
|
||||
}
|
||||
|
||||
void char_attr(esc_state *st) {
|
||||
int new_fg = 2;
|
||||
int new_bg = 0;
|
||||
|
||||
for(int i= 0; i<count_of(st->esc_param); i++) {
|
||||
int p = st->esc_param[i];
|
||||
if (30 <= p && p <= 37) new_fg = map_one(p - 30);
|
||||
if (90 <= p && p <= 97) new_fg = map_one(p - 90);
|
||||
if (40 <= p && p <= 47) new_fg = map_one(p - 40);
|
||||
if (100 <= p && p <= 107) new_fg = map_one(p - 100);
|
||||
lw_cell_t char_attr(void *user_data, const struct lw_parsed_attr *attr) {
|
||||
int fg = map_one(attr->fg);
|
||||
int bg = map_one(attr->bg);
|
||||
if(attr->bold) fg = 3;
|
||||
if(attr->blink) fg ^= 4;
|
||||
if(attr->inverse) {
|
||||
return MAKE_ATTR(bg, fg);
|
||||
}
|
||||
attr = MAKE_ATTR(new_fg, new_bg) << 8;
|
||||
return MAKE_ATTR(fg, bg);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
#if !STANDALONE
|
||||
set_sys_clock_khz(vga_660x477_60_sys_clock_khz, false);
|
||||
stdio_init_all();
|
||||
#endif
|
||||
|
||||
vt100 = lw_terminal_vt100_init(NULL, NULL, char_attr, FB_WIDTH_CHAR, FB_HEIGHT_CHAR);
|
||||
multicore_launch_core1(core1_entry);
|
||||
|
||||
scrnprintf(
|
||||
"(line 0)\r\n"
|
||||
"CR100 terminal demo...\r\n"
|
||||
);
|
||||
|
||||
for(int bg = 0; bg < 8; bg++) {
|
||||
for(int fg = 0; fg < 8; fg++) {
|
||||
attr = MAKE_ATTR(fg, bg) << 8;
|
||||
scrnprintf(" %o%o ", bg, fg);
|
||||
attr = 0x300;
|
||||
scrnprintf(" ");
|
||||
}
|
||||
scrnprintf("\r\n");
|
||||
}
|
||||
|
||||
multicore_launch_core1(core1_entry);
|
||||
keyboard_setup();
|
||||
|
||||
attr = 0x300;
|
||||
show_cursor();
|
||||
while (true) {
|
||||
int c = getchar();
|
||||
if (c == EOF) { continue; }
|
||||
|
||||
vt_action action = vt_process_code(&vt_st, c);
|
||||
|
||||
if (action == NO_OUTPUT) { continue; }
|
||||
|
||||
hide_cursor();
|
||||
switch(action) {
|
||||
case NO_OUTPUT:
|
||||
__builtin_unreachable();
|
||||
|
||||
case PRINTABLE:
|
||||
scrnprintf("%c", c);
|
||||
if(0 && c == '\r')
|
||||
scrnprintf("\n");
|
||||
break;
|
||||
|
||||
case BELL:
|
||||
invert_screen();
|
||||
sleep_ms(100);
|
||||
invert_screen();
|
||||
break;
|
||||
|
||||
case CLEAR_EOL:
|
||||
clear_eol(vt_st.esc_param[0]);
|
||||
break;
|
||||
|
||||
case CLEAR_SCREEN:
|
||||
clear_screen(vt_st.esc_param[0]);
|
||||
break;
|
||||
|
||||
case CURSOR_LEFT:
|
||||
cursor_left();
|
||||
break;
|
||||
|
||||
case CURSOR_POSITION:
|
||||
cursor_position(&vt_st);
|
||||
break;
|
||||
|
||||
case CHAR_ATTR:
|
||||
char_attr(&vt_st);
|
||||
break;
|
||||
}
|
||||
show_cursor();
|
||||
char cc = c;
|
||||
lw_terminal_vt100_read_buf(vt100, &cc, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
12
hl-vt100/vt_dump.py
Normal file
12
hl-vt100/vt_dump.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import hl_vt100
|
||||
import sys
|
||||
|
||||
vt100 = hl_vt100.vt100_headless()
|
||||
vt100.fork(sys.argv[1], sys.argv[1:])
|
||||
vt100.main_loop()
|
||||
print(*vt100.getlines(), sep="\n")
|
||||
|
||||
print()
|
||||
for a in vt100.getattrlines()[:8]:
|
||||
s = " ".join(f"{c >> 8:02x}" for c in a[:20])
|
||||
print(s)
|
||||
2
run-gdb.sh
Executable file
2
run-gdb.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec gdb-multiarch --eval-command "target extended-remote :3333" build/cr100.elf "$@"
|
||||
Loading…
Reference in a new issue