From 005833a530ec48ec7f149e74c65957a43c764264 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 14 Dec 2014 18:26:09 +0000 Subject: [PATCH] mtx: Fix up the consoles and serial We now have four tty devices, 1 is the 6845, 2 is the VDP, 3 and 4 the serial ports. The serial isn't finished and the IRQ logic hasn't been tackled. The keyboard works. --- Kernel/platform-mtx/config.h | 8 ++- Kernel/platform-mtx/devtty.c | 115 ++++++++++++++++++++++++++++++----- Kernel/platform-mtx/devtty.h | 4 ++ Kernel/platform-mtx/mtx.s | 31 +++++++++- Kernel/platform-mtx/vdp.s | 113 ++++++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 21 deletions(-) diff --git a/Kernel/platform-mtx/config.h b/Kernel/platform-mtx/config.h index e4364b58..a17889d3 100644 --- a/Kernel/platform-mtx/config.h +++ b/Kernel/platform-mtx/config.h @@ -12,6 +12,8 @@ #define CONFIG_CPM_EMU /* Video terminal, not a serial tty */ #define CONFIG_VT +/* Multiple VT support */ +#define CONFIG_VT_MULTI /* Fixed banking */ #define CONFIG_BANK_FIXED /* 10 48K banks, 1 is kernel */ @@ -39,7 +41,7 @@ #define CMDLINE NULL /* Location of root dev name */ /* Device parameters */ -#define NUM_DEV_TTY 2 /* Will be 4 two monitors, two serial */ +#define NUM_DEV_TTY 4 /* Will be 4 two monitors, two serial */ #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ #define SWAPDEV ((8*256) + 0) /* Device for swapping. - first silicon disk */ @@ -47,7 +49,7 @@ #define NMOUNTS 4 /* Number of mounts at a time */ /* Terminal definitions */ -#define VT_WIDTH 40 +#define VT_WIDTH vt_twidth[curtty] #define VT_HEIGHT 24 -#define VT_RIGHT 39 +#define VT_RIGHT vt_tright[curtty] #define VT_BOTTOM 23 diff --git a/Kernel/platform-mtx/devtty.c b/Kernel/platform-mtx/devtty.c index 12ae04b1..2b59a3ca 100644 --- a/Kernel/platform-mtx/devtty.c +++ b/Kernel/platform-mtx/devtty.c @@ -9,17 +9,30 @@ #undef DEBUG /* UNdefine to delete debug code sequences */ __sfr __at 0x0C serialAd; -__sfr __at 0x0D serialAc; -__sfr __at 0x0E serialBd; +__sfr __at 0x0D serialBd; +__sfr __at 0x0E serialAc; __sfr __at 0x0F serialBc; +__sfr __at 0x09 ctc1; +__sfr __at 0x0A ctc2; + +signed char vt_twidth[2] = { 80, 40 }; +signed char vt_tright[2] = { 79, 39 }; +uint8_t curtty; /* output side */ +uint8_t inputtty; /* input side */ +static struct vt_switch ttysave[2]; + char tbuf1[TTYSIZ]; char tbuf2[TTYSIZ]; +char tbuf3[TTYSIZ]; +char tbuf4[TTYSIZ]; 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} }; /* tty1 is the screen tty2 is the debug port */ @@ -29,39 +42,81 @@ void kputchar(char c) { /* Debug port for bringup */ if (c == '\n') - tty_putc(2, '\r'); - tty_putc(2, c); + tty_putc(1, '\r'); + tty_putc(1, c); } -/* Both console and debug port are always ready */ bool tty_writeready(uint8_t minor) { - minor; - return 1; + uint8_t reg = 0xFF; + if (minor == 3) + reg = serialAc; + if (minor == 4) + reg = serialBc; + return reg & 4; } void tty_putc(uint8_t minor, unsigned char c) { minor; - if (minor == 1) { + if (minor < 3) { + if (curtty != minor - 1) { + vt_save(&ttysave[curtty]); + curtty = minor - 1; + vt_load(&ttysave[curtty]); + } vtoutput(&c, 1); return; } - serialAd = c; + if (minor == 3) + serialAd = c; + else + serialBd = c; } int tty_carrier(uint8_t minor) { - minor; - return 1; + uint8_t reg = 0xFF; + if (minor == 3) + reg = serialAc; + if (minor == 4) + reg = serialBc; + return (reg & 8) ? 1 : 0; } +static uint8_t dart_setup[] = { + 1, 0x19, + 2, 0x00, + 3, 0xC1, /* 8bit */ + 4, 0x04, /* 8N1 */ + 5, 0x72, /* Tx 8bit, enabled, rts on */ +}; + void tty_setup(uint8_t minor) { - minor; + irqflags_t flags; + int i; + char *p = dart_setup; + + if (minor == 1) { + ctc1 = 0x7F; + ctc1 = 0x02; /* FIXME set by baud rate */ + } else { + ctc2 = 0x7F; + ctc2 = 0x02; + } + flags = di(); + for (i = 0; i < 10; i++) { + if (minor == 3) + serialAc = *p++; + else + serialBc = *p++; + } + irqrestore(flags); } + static uint16_t keymap[8]; static uint16_t keyin[8]; static uint8_t keybyte, keybit; @@ -108,9 +163,9 @@ static void keyproc(void) } static uint8_t keyboard[8][10] = { - {'1', '3', '5', '7', '9' , '-', '\\', 0/*page */, 3/*brk*/, 0/*f1*/}, + {'1', '3', '5', '7', '9' , '-', '\\', 0/*page */, 3/*brk*/, 0xF1/*f1*/}, { 27, '2', '4', '6', '8', '0', '^', 0/*eol*/, 8, 0/*f5*/}, - { 0/*ctrl*/, 'w', 'r', 'y', 'i', 'p', '[', 0/*up*/, 9, 0/*f2*/ }, + { 0/*ctrl*/, 'w', 'r', 'y', 'i', 'p', '[', 0/*up*/, 9, 0xF2/*f2*/ }, {'q', 'e', 't' , 'u', 'o', '@', 10, 8/*left*/, 127, 0 /* f6 */ }, { 0/*capsl*/, 's', 'f', 'h', 'k', ';', ']', 0/*right*/, 0, 0/*f7*/ }, { 'a', 'd', 'g', 'j', 'l', ':', 13, 12/*home*/, 0, 0 /*f3 */ }, @@ -135,6 +190,13 @@ static void keydecode(void) { uint8_t c; + if ((keybyte == 0xF1 || keybyte == 0xF2) + && inputtty != keybyte - 0xF1) { + inputtty = keybyte - 0xF1; + vt_save(&ttysave[inputtty]); + vt_load(&ttysave[inputtty]); + return; + } if (keybyte == 4 && keybit == 0) { capslock = 1 - capslock; return; @@ -150,7 +212,7 @@ static void keydecode(void) } if (capslock && c >= 'a' && c <= 'z') c -= 'a' - 'A'; - tty_inproc(1, c); + tty_inproc(inputtty + 1, c); } void kbd_interrupt(void) @@ -161,6 +223,27 @@ void kbd_interrupt(void) keydecode(); } +void serial_interrupt(void) +{ + uint8_t r; + + r = serialAc; + if (r & 0x02) { + while (r & 0x01) { + r = serialAd; + tty_inproc(3, r); + r = serialAc; + } + r = serialBc; + while (r & 0x01) { + r = serialBd; + tty_inproc(4, r); + r = serialBc; + } + } + serialAc = 0x07 << 3; /* Return from interrupt */ +} + /* This is used by the vt asm code, but needs to live in the kernel */ uint16_t cursorpos; diff --git a/Kernel/platform-mtx/devtty.h b/Kernel/platform-mtx/devtty.h index f3fa2582..dc0e2a6c 100644 --- a/Kernel/platform-mtx/devtty.h +++ b/Kernel/platform-mtx/devtty.h @@ -3,4 +3,8 @@ extern void kbd_interrupt(void); +extern signed char vt_twidth[2]; +extern signed char vt_tright[2]; +extern uint8_t curtty; + #endif diff --git a/Kernel/platform-mtx/mtx.s b/Kernel/platform-mtx/mtx.s index d8fbcf1c..5a14ec8b 100644 --- a/Kernel/platform-mtx/mtx.s +++ b/Kernel/platform-mtx/mtx.s @@ -65,9 +65,28 @@ _trap_reboot: ; ----------------------------------------------------------------------------- ; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped) ; ----------------------------------------------------------------------------- + + .area _CONST +crtcmap: + .db 0x77, 0x50, 0x5c, 0x09, 0x1e, 0x03, 0x18, 0x1b + .db 0x00, 0x09, 0x60, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 + .area _CODE init_early: +; +; Bring up the 80 column card early so it can be used for debug +; + ld hl, #crtcmap + xor a + ld bc, #0x1139 ; 17 commands to port 0x38/39 +init6845: + dec c + out (c), a + inc c + inc a + outi + jr nz, init6845 ret init_hardware: @@ -92,7 +111,15 @@ init_hardware: ; 09 is channel 1, output for DART ser 0 } fed 4MHz/13 ; 0A is channel 2, output for DATA ser 1 } ; 0B is channel 3, counting CSTTE edges (cpu clocks) at 4MHz - ; 0C-0F are A data, B data, A ctrl, B ctrl + + xor a + out (0x08), a ; vector 0 + ld a, #0x97 + out (0x08), a ; CTC 0 as our IRQ source + ld a, #0x05 + out (0x08), a ; Timer constant (gives us 10Hz) + ; should be 0x06 for NTSC boxes + ; FIXME - how to tell ? im 1 ; set CPU interrupt mode @@ -185,7 +212,7 @@ map_kernel: push af ld a, #0x80 ; ROM off bank 0 ; the map port is write only, so keep a local stash - ld (map_save), a + ld (map_copy), a out (0), a pop af ret diff --git a/Kernel/platform-mtx/vdp.s b/Kernel/platform-mtx/vdp.s index dd7dd3be..44c6b8f5 100644 --- a/Kernel/platform-mtx/vdp.s +++ b/Kernel/platform-mtx/vdp.s @@ -5,9 +5,122 @@ .include "../dev/vdp1.s" + .globl _curtty + .globl _scroll_up + .globl _scroll_down + .globl _clear_across + .globl _clear_lines + .globl _cursor_off + .globl _cursor_on + .globl _plot_char + + +; +; Don't provide the global vt hooks in vdp1.s, we want to wrap them +; for our dual monitor setup +; +VDP_DIRECT equ 0 .area _COMMONMEM +; +; Turn co-ordinates D,E into offset HL +; +videopos6: + ld a, e + add a + add a + add a ; x 8 (max 24 x 8 - 192) + ld l, a + ld h, #0 + add hl, hl ; x 16 + push hl + add hl, hl ; x 32 + add hl, hl ; x 64 + ld a, d + pop de ; + x 16 = x 80 + add hl, de + ld e, a + ld d, #0 + add hl, de ; and X + ret + + +; +; This is a bit different as we support both the vdp1 and the 6845 +; port +; + +_cursor_on: ld a, (_curtty) + or a + jp nz, cursor_on ; VDP + pop hl + pop de + push de + push hl + call videopos6 + ld a, #14 + ld c, #0x39 + out (0x38), a + out (c), h + inc a + out (0x38), a + out (c), l + ret + +_cursor_off: ld a, (_curtty) + or a + jp nz, cursor_off ; VDP + ret + +_clear_across: + ld a, (_curtty) + or a + jp nz, clear_across + ret + +_clear_lines: + ld a, (_curtty) + or a + jp nz, clear_lines + ret + +_scroll_up: ld a, (_curtty) + or a + jp nz, scroll_up + ret + +_scroll_down: + ld a, (_curtty) + or a + jp nz, scroll_down + ret + +_plot_char: + ld a, (_curtty) + or a + jp nz, plot_char + ; Plot via 6845 + pop hl + pop de ; D = x E = y + pop bc + push bc + push de + push hl + ld a, c ; char + out (0x32), a + ld a, #0x7 ; white on black + out (0x33), a + call videopos6 + ld a, h + or #0xE0 ; write + out (0x31), a + ld a,l + out (0x30), a + ret + + +; ; ; FIXME: should use vdpport, but right now vdpport is in data not ; common space. -- 2.34.1