From 3616d6dad729f3fece86fa86c0cfb2bca398b96e Mon Sep 17 00:00:00 2001 From: geijoenr Date: Thu, 8 Jun 2017 20:43:35 +0200 Subject: [PATCH] msx2: add multiple vt support support for 4 vt's --- Kernel/dev/v99xx.h | 2 + Kernel/platform-msx2/config.h | 7 +++- Kernel/platform-msx2/devtty.c | 70 +++++++++++++++++++++++++++-------- Kernel/platform-msx2/vdp.c | 59 +++++++++++++++++++++++------ 4 files changed, 109 insertions(+), 29 deletions(-) diff --git a/Kernel/dev/v99xx.h b/Kernel/dev/v99xx.h index 9fbe33cd..5fc0a88b 100644 --- a/Kernel/dev/v99xx.h +++ b/Kernel/dev/v99xx.h @@ -67,6 +67,8 @@ #define MODE_EXTEND_CMD 0x40 +#define V99xx_VRAM_PAGE_SIZE 0x4000 + /* vram access flags */ #define REG_VRAM_ADDR_MASK 1 #define REG_VRAM_WRITE_FLAG 0x40 diff --git a/Kernel/platform-msx2/config.h b/Kernel/platform-msx2/config.h index 2e56d96b..1e94d6cd 100644 --- a/Kernel/platform-msx2/config.h +++ b/Kernel/platform-msx2/config.h @@ -10,6 +10,7 @@ #undef CONFIG_SINGLETASK /* Video terminal, not a serial tty */ #define CONFIG_VT +#define CONFIG_VT_MULTI /* 16K banking so use the helper */ #define CONFIG_BANK16 #define MAX_MAPS 255 @@ -25,6 +26,9 @@ #define VT_RIGHT 79 #define VT_BOTTOM 23 +/* MODE TEXT2 supports up to 16 VT's */ +#define MAX_VT 4 + #define TICKSPERSEC 60 /* default value, it will be upated on device_init */ #define PROGBASE 0x0000 /* also data base */ #define PROGLOAD 0x0100 @@ -38,7 +42,8 @@ #define CMDLINE NULL /* Location of root dev name */ /* Device parameters */ -#define NUM_DEV_TTY 2 +#define NUM_DEV_TTY 5 +#define TTYSIZ 64 #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ #define NBUFS 10 /* Number of block buffers */ #define NMOUNTS 4 /* Number of mounts at a time */ diff --git a/Kernel/platform-msx2/devtty.c b/Kernel/platform-msx2/devtty.c index cdbbb92d..f711432e 100644 --- a/Kernel/platform-msx2/devtty.c +++ b/Kernel/platform-msx2/devtty.c @@ -9,13 +9,22 @@ #undef DEBUG /* UNdefine to delete debug code sequences */ +extern void set_active_vt(uint8_t curtty); +extern void set_visible_vt(uint8_t curtty); + __sfr __at 0x2F tty_debug2; __sfr __at 0xAA kbd_row_set; __sfr __at 0xA9 kbd_row_read; char tbuf1[TTYSIZ]; char tbuf2[TTYSIZ]; +char tbuf3[TTYSIZ]; +char tbuf4[TTYSIZ]; +char tbuf5[TTYSIZ]; +uint8_t curtty; +uint8_t inputtty; +static struct vt_switch ttysave[5]; struct vt_repeat keyrepeat; uint8_t vtattr_cap; static uint8_t kbd_timer; @@ -23,37 +32,59 @@ static uint8_t kbd_timer; struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ {NULL, NULL, NULL, 0, 0, 0}, {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, - {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2} + {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2}, + {tbuf3, tbuf3, tbuf3, TTYSIZ, 0, TTYSIZ / 2}, + {tbuf4, tbuf4, tbuf4, TTYSIZ, 0, TTYSIZ / 2}, + {tbuf5, tbuf5, tbuf5, TTYSIZ, 0, TTYSIZ / 2}, }; uint8_t keyboard[11][8]; uint8_t shiftkeyboard[11][8]; -/* tty1 is the screen tty2 is the debug port */ +/* tty1 to tty4 is the screen tty5 is the debug port */ /* Output for the system console (kprintf etc) */ void kputchar(char c) { /* Debug port for bringup */ if (c == '\n') - tty_putc(2, '\r'); - tty_putc(2, c); + tty_putc(5, '\r'); + tty_putc(5, c); } -/* Both console and debug port are always ready */ +/* All tty are always ready */ ttyready_t tty_writeready(uint8_t minor) { minor; + // tty are ready to write return TTY_READY_NOW; } -void tty_putc(uint8_t minor, unsigned char c) +void vtexchange() { - minor; + vt_save(&ttysave[curtty]); + cursor_off(); + set_visible_vt(inputtty); + cursor_on(ttysave[inputtty].cursory, ttysave[inputtty].cursorx); +} - vtoutput(&c, 1); - tty_debug2 = c; +void tty_putc(uint8_t minor, unsigned char c) +{ + irqflags_t irq; + if (minor == 5) + tty_debug2 = c; + else { + irq = di(); + if (curtty != minor -1) { + vt_save(&ttysave[curtty]); + curtty = minor - 1; + vt_load(&ttysave[curtty]); + set_active_vt(curtty); + } + vtoutput(&c, 1); + irqrestore(irq); + } } int tty_carrier(uint8_t minor) @@ -67,9 +98,9 @@ void tty_setup(uint8_t minor) minor; /* setup termios to use msx keys */ - ttydata[1].termios.c_cc[VERASE] = KEY_BS; - ttydata[1].termios.c_cc[VSTOP] = KEY_STOP; - ttydata[1].termios.c_cc[VSTART] = KEY_STOP; + ttydata[minor].termios.c_cc[VERASE] = KEY_BS; + ttydata[minor].termios.c_cc[VSTOP] = KEY_STOP; + ttydata[minor].termios.c_cc[VSTART] = KEY_STOP; } uint8_t keymap[11]; @@ -122,9 +153,17 @@ static void keydecode(void) return; } - if (keymap[6] & 3 ) /* shift or control */ + if (keymap[6] & 3 ) { /* shift or control */ c = shiftkeyboard[keybyte][keybit]; - else + /* VT switcher */ + if (c == KEY_F1 || c == KEY_F2 || c == KEY_F3 || c == KEY_F4) { + if (inputtty != c - KEY_F1) { + inputtty = c - KEY_F1; + vtexchange(); /* Exchange the video and backing buffer */ + } + return; + } + } else c = keyboard[keybyte][keybit]; if (keymap[6] & 2) { /* control */ @@ -137,7 +176,7 @@ static void keydecode(void) /* TODO: function keys (F1-F10), graph, code */ - vt_inproc(1, c); + vt_inproc(inputtty +1, c); } void update_keyboard() @@ -178,4 +217,3 @@ void tty_sleeping(uint8_t minor) /* This is used by the vt asm code, but needs to live in the kernel */ uint16_t cursorpos; - diff --git a/Kernel/platform-msx2/vdp.c b/Kernel/platform-msx2/vdp.c index d8cba76e..124955a7 100644 --- a/Kernel/platform-msx2/vdp.c +++ b/Kernel/platform-msx2/vdp.c @@ -5,33 +5,46 @@ #include #include #include +#include -/* TODO: extend to support multiple VT (or scrollable history) - * possible to keep up to 31 pages in VRAM */ #define VT_BASE 0x0000 #define VT_BASE_FONT 0x1000 #define VT_BASE_BLINK 0x800 #define VT_BUFSIZE 80 +#define VT_OFFSET 0x2000 extern void *fontdata_6x8; static uint8_t vt_buff[VT_BUFSIZE]; static uint16_t cur_blink_addr = 0; +static uint16_t vt_offset; void vdpinit() { + uint8_t i; + v99xx_set_mode(MODE_TEXT2); v99xx_set_color(15, 4); v99xx_copy_to_vram(VT_BASE_FONT + 32*8, (uint8_t *)&fontdata_6x8, 768); v99xx_set_blink_color(15, 8); v99xx_set_blink_period(4, 4); + + /* clean vram for all vt's */ + for (i = 0; i < MAX_VT; i++) { + v99xx_set_vram_page(i/2); + v99xx_memset_vram(VT_BASE + i * VT_OFFSET, ' ', VT_HEIGHT * VT_WIDTH); + v99xx_memset_vram(VT_BASE_BLINK + i * VT_OFFSET, 0, + VT_HEIGHT * VT_WIDTH / 8); + } + vt_offset = 0; } void clear_lines(int8_t y, int8_t ct) { uint16_t addr; - addr = VT_BASE + y * VT_WIDTH; + addr = VT_BASE + vt_offset + y * VT_WIDTH; + v99xx_set_vram_page(addr / V99xx_VRAM_PAGE_SIZE); v99xx_memset_vram(addr, ' ', ct * VT_WIDTH); } @@ -39,12 +52,14 @@ void clear_across(int8_t y, int8_t x, int16_t l) { uint16_t addr; - addr = VT_BASE + y * VT_WIDTH + x; + addr = VT_BASE + vt_offset + y * VT_WIDTH + x; + v99xx_set_vram_page(addr / V99xx_VRAM_PAGE_SIZE); v99xx_memset_vram(addr, ' ', l); } void cursor_off(void) { + v99xx_set_vram_page(cur_blink_addr / V99xx_VRAM_PAGE_SIZE); v99xx_write_vram(cur_blink_addr, 0); } @@ -53,9 +68,9 @@ void cursor_on(int8_t y, int8_t x) uint16_t blink_addr; uint8_t bit; - blink_addr = VT_BASE_BLINK + y * 10 + (x >> 3); + blink_addr = VT_BASE_BLINK + vt_offset + y * 10 + (x >> 3); bit = 7 - (x & 0x7); - + v99xx_set_vram_page(blink_addr / V99xx_VRAM_PAGE_SIZE); v99xx_write_vram(blink_addr, 1 << bit); cur_blink_addr = blink_addr; } @@ -63,31 +78,51 @@ void cursor_on(int8_t y, int8_t x) void memcpy_vram(uint16_t dst, uint16_t src, uint16_t size) { uint16_t i; - + v99xx_set_vram_page(dst / V99xx_VRAM_PAGE_SIZE); for (i = 0; i < size; i += VT_BUFSIZE) { v99xx_copy_from_vram(vt_buff, src + i, VT_BUFSIZE); v99xx_copy_to_vram(dst + i, vt_buff, VT_BUFSIZE); - } +} } void scroll_up(void) { - memcpy_vram(VT_BASE, VT_WIDTH, VT_WIDTH * VT_BOTTOM); + memcpy_vram(VT_BASE + vt_offset , VT_WIDTH + vt_offset, VT_WIDTH * VT_BOTTOM); } void scroll_down(void) { - memcpy_vram(VT_WIDTH, VT_BASE, VT_WIDTH * VT_BOTTOM); + memcpy_vram(VT_WIDTH + vt_offset , VT_BASE + vt_offset , VT_WIDTH * VT_BOTTOM); } void plot_char(int8_t y, int8_t x, uint16_t c) { uint16_t addr; - - addr = VT_BASE + y * VT_WIDTH + x; + addr = VT_BASE + vt_offset + y * VT_WIDTH + x; + v99xx_set_vram_page(addr / V99xx_VRAM_PAGE_SIZE); v99xx_write_vram(addr, c); } void vtattr_notify(void) { } + +void set_active_vt(uint8_t vt) +{ + vt_offset = vt * VT_OFFSET; +} + +void set_visible_vt(uint8_t vt) +{ + uint8_t val; + uint16_t offset = vt * VT_OFFSET; + + val = (uint8_t)(((VT_BASE + offset & 0xF800) >> 10) | 0x03); + v99xx_write_reg(V99xx_REG_PTRN_LAYOUT_BASE, val); + + val = (uint8_t)(((VT_BASE_BLINK + offset & 0x3F00) >> 6) | 0x07); + v99xx_write_reg(V99xx_REG_COLOR_BASE_H, val); + + val = (uint8_t)(((VT_BASE_BLINK + offset & 0xC000) >> 14) & 0x07); + v99xx_write_reg(V99xx_REG_COLOR_BASE_L, val); +} -- 2.34.1