msx2: add multiple vt support
authorgeijoenr <geijoenr@gmail.com>
Thu, 8 Jun 2017 18:43:35 +0000 (20:43 +0200)
committergeijoenr <geijoenr@gmail.com>
Fri, 9 Jun 2017 15:28:20 +0000 (17:28 +0200)
support for 4 vt's

Kernel/dev/v99xx.h
Kernel/platform-msx2/config.h
Kernel/platform-msx2/devtty.c
Kernel/platform-msx2/vdp.c

index 9fbe33c..5fc0a88 100644 (file)
@@ -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
index 2e56d96..1e94d6c 100644 (file)
@@ -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 */
index cdbbb92..f711432 100644 (file)
@@ -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;
-
index d8cba76..124955a 100644 (file)
@@ -5,33 +5,46 @@
 #include <kernel.h>
 #include <vt.h>
 #include <v99xx.h>
+#include <printf.h>
 
-/* 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);
+}