trs80m1: sort out all the multi-console fun
authorAlan Cox <alan@linux.intel.com>
Mon, 2 Jul 2018 21:19:07 +0000 (22:19 +0100)
committerAlan Cox <alan@linux.intel.com>
Mon, 2 Jul 2018 21:19:07 +0000 (22:19 +0100)
Shift left arrow and shift right arrow switch consoles (2 for now but we could
easily do 4 as the exchange buffers are banked)

Kernel/platform-trs80m1/Makefile
Kernel/platform-trs80m1/config.h
Kernel/platform-trs80m1/crt0.s
Kernel/platform-trs80m1/devtty.c
Kernel/platform-trs80m1/devtty.h
Kernel/platform-trs80m1/fuzix.lnk
Kernel/platform-trs80m1/trs80-bank.s
Kernel/platform-trs80m1/vtsupport.s [new file with mode: 0644]
Kernel/platform-trs80m1/vtswap.s [deleted file]

index 301b199..fb75cdb 100644 (file)
@@ -3,7 +3,7 @@ CSRCS = devlpr.c devtty.c devfd.c devfd3.c devhd.c devgfx.c
 CSRCS += devices.c main.c
 DISCARD_CSRCS = discard.c devhd_discard.c
 
-ASRCS = trs80.s trs80-bank.s crt0.s vtswap.s
+ASRCS = trs80.s trs80-bank.s crt0.s vtsupport.s
 ASRCS += tricks.s commonmem.s floppy.s floppy3.s
 
 COBJS = $(CSRCS:.c=.rel)
index dcadfd1..e680de3 100644 (file)
@@ -12,8 +12,7 @@
 #undef CONFIG_SINGLETASK
 /* Video terminal, not a serial tty */
 #define CONFIG_VT
-/* Simple character addressed device */
-#define CONFIG_VT_SIMPLE
+/* Switchable console */
 #define CONFIG_VT_MULTI
 /* Banked memory set up */
 #define CONFIG_BANK_FIXED
@@ -27,7 +26,6 @@
 #define CONFIG_BANKS   2       /* 2 x 32K */
 
 /* Vt definitions */
-#define VT_BASE                ((uint8_t *)0x3C00)
 #define VT_WIDTH       64
 #define VT_HEIGHT      16
 #define VT_RIGHT       63
index 23171d6..2e7f84c 100644 (file)
@@ -5,6 +5,7 @@
                .area _CODE
                .area _CODE1
                .area _CODE2
+               .area _DATA2
                .area _DISCARD2
                .area _VIDEO
                .area _COMMONMEM
index ff36b45..06e9c2b 100644 (file)
@@ -11,13 +11,11 @@ static char tbuf1[TTYSIZ];
 static char tbuf2[TTYSIZ];
 static char tbuf3[TTYSIZ];
 
-static uint8_t curtty;         /* output side */
+uint8_t curtty;                        /* output side */
 static uint8_t inputtty;       /* input side */
 static struct vt_switch ttysave[2];
-static uint8_t vtbackbuf[VT_WIDTH * VT_HEIGHT];
 struct vt_repeat keyrepeat;
-
-uint8_t *vtbase[2] = { 0xF800, vtbackbuf };
+extern uint8_t *vtbase[2];
 
 __sfr __at 0xE8 tr1865_ctrl;
 __sfr __at 0xE9 tr1865_baud;
@@ -42,7 +40,7 @@ void kputchar(char c)
 ttyready_t tty_writeready(uint8_t minor)
 {
     uint8_t reg;
-    if (minor != 2)
+    if (minor != 3)
         return TTY_READY_NOW;
     /* TODO: check model status & 0x80 for CTS flow control if appropriate */
     reg = tr1865_status;
@@ -82,7 +80,7 @@ static void vtexchange(void)
 void tty_putc(uint8_t minor, unsigned char c)
 {
     irqflags_t irq;
-    if (minor == 2)
+    if (minor == 3)
         tr1865_rxtx = c;
     else {
         irq = di();
@@ -91,13 +89,13 @@ void tty_putc(uint8_t minor, unsigned char c)
                we don't do this the next cursor_off will hit the wrong
                buffer */
             vtflush();
-            cursor_off();
+//          cursor_off();
             vt_save(&ttysave[curtty]);
             curtty = minor - 1;
             vt_load(&ttysave[curtty]);
             /* Fix up the cursor */
-            if (!ttysave[curtty].cursorhide)
-                cursor_on(ttysave[curtty].cursory, ttysave[curtty].cursorx);
+//            if (!ttysave[inputtty].cursorhide)
+//                cursor_on(ttysave[inputtty].cursory, ttysave[inputtty].cursorx);
         }
         else if (vtq == vtbuf + sizeof(vtbuf))
             vtflush();
@@ -254,9 +252,11 @@ static void keydecode(void)
        if (keymap[7] & 3) {    /* shift (left/right) */
                c = shiftkeyboard[keybyte][keybit];
                /* VT switcher */
-               if (c == KEY_F1 || c == KEY_F2) {
-                        if (inputtty != c - KEY_F1) {
-                                inputtty = c - KEY_F1;
+               if (c == KEY_LEFT || c == KEY_RIGHT) {
+                       c -= KEY_RIGHT;
+                       c ^= 1;
+                        if (inputtty != c) {
+                                inputtty = c;
                                 vtexchange();  /* Exchange the video and backing buffer */
                         }
                         return;
@@ -293,7 +293,7 @@ static void keydecode(void)
                c -= 'a' - 'A';
        if (c) {
 //         kprintf("Typed %d:%c\n", c, c);
-               vt_inproc(1, c);
+               vt_inproc(inputtty + 1, c);
             }
 }
 
index 1d4bc75..5c66f23 100644 (file)
@@ -16,4 +16,5 @@ extern uint8_t keyboard[8][8];
 extern uint8_t shiftkeyboard[8][8];
 
 extern uint8_t *vtbase[2];
+extern uint8_t curtty;
 #endif
index 43db9d7..b07417c 100644 (file)
@@ -46,6 +46,6 @@ vt.rel
 devsys.rel
 platform-trs80m1/devlpr.rel
 platform-trs80m1/devtty.rel
-platform-trs80m1/vtswap.rel
+platform-trs80m1/vtsupport.rel
 platform-trs80m1/discard.rel
 -e
index 6cdb8c9..149cb93 100644 (file)
@@ -22,6 +22,7 @@
            .globl _program_vectors     
             .globl _ramsize
             .globl _procmem
+           .globl vtbufinit
 
            .globl s__COMMONMEM
            .globl l__COMMONMEM
@@ -35,6 +36,9 @@
             .area _BOOT
 
 init_hardware:
+           push af
+           call vtbufinit
+           pop af
             ; set system RAM size
            ld hl,#0xFFFF               ; FFFF is free in all our pages
            ld bc,#0xFF43               ; kernel included
diff --git a/Kernel/platform-trs80m1/vtsupport.s b/Kernel/platform-trs80m1/vtsupport.s
new file mode 100644 (file)
index 0000000..bd59ef3
--- /dev/null
@@ -0,0 +1,205 @@
+;
+;      Do this in assembler so we can keep the vtbackbuf banked
+;
+;      Must be in the same bank as vt
+;
+               .module vtswap
+
+
+               .globl _vtswap
+               .globl vtbufinit
+               .globl _vtbase
+
+               .globl _vtbase
+               .globl _curtty
+
+               .globl _cursor_off
+               .globl _cursor_disable
+               .globl _cursor_on
+               .globl _plot_char
+               .globl _clear_lines
+               .globl _clear_across
+               .globl _vtattr_notify
+               .globl _scroll_up
+               .globl _scroll_down
+
+               .area _DATA2
+
+_vtbackbuf:
+               .ds 1024
+
+               .area _COMMONMEM
+_vtbase:
+               .dw     0x3C00
+               .dw     _vtbackbuf
+
+               .area _CODE2
+_vtswap:
+                ld hl, #0x3C00
+                ld de, #_vtbackbuf
+                ld bc, #1024   ; 64 * 16
+        exchit:
+                push bc
+                ld a, (de)     ; Could be optimised but its only 1K
+                ld c, (hl)     ; Probably worth doing eventuallly
+                ex de, hl
+                ld (hl), c
+                ld (de), a
+                inc hl
+                inc de
+                pop bc
+                dec bc
+                ld a, b
+                or c
+                jr nz, exchit
+                ret
+vtbufinit:
+               ld hl,#_vtbackbuf
+               ld de,#_vtbackbuf+1
+               ld bc,#1023
+               ld (hl),#' '
+               ldir
+               ret
+
+;
+;      This is basically VT_SIMPLE but done in asm so we know all our
+;      I/O happens with the right things banked
+;
+
+vtbase:                ld hl,(_vtbase)
+               ld a,(_curtty)
+               or a
+               ret z
+               ld hl,(_vtbase + 2)
+               call debughook
+               ret
+
+;
+;      Must preserve BC
+;      Turn D,E into a display address
+;
+addr:          call vtbase
+               ld a,d          ; save X
+               ld d,e
+               ld e,#0
+               srl d           ;  DE = Y * 64
+               rr  e
+               srl d
+               rr  e
+               add e           ; add in X
+               ld  e,a
+               add hl,de       ; add in base
+               ret
+
+_cursor_off:
+               ld hl,(cpos)
+               ld a,h
+               or a    ;       00xx isn't valid so no need to check l
+               ret z
+               ld a,(csave)
+               ld (hl),a
+               xor a
+               ld (cpos+1),a
+_cursor_disable:
+               ret
+
+_cursor_on:
+               pop hl
+               pop bc
+               pop de
+               push de
+               push bc
+               push hl
+               call addr
+               ld a,(hl)
+               ld (hl),#'_'
+               ld (csave),a
+               ld (cpos),hl
+               ret
+
+_plot_char:
+               pop ix
+               pop hl
+               pop de
+               pop bc
+               push bc
+               push de
+               push hl
+               push ix
+               call addr
+               ld (hl),c
+               ret
+
+_clear_lines:
+               pop hl
+               pop bc
+               pop de                  ; E = y D = count
+               push de
+               push bc
+               push hl
+               ld c,d
+               ld d,#0
+               call addr
+               ld a,#32
+clear0:
+               ld b,#64                ; line width
+clear1:
+               ld (hl),a
+               inc hl
+               djnz clear1
+               dec c
+               jr nz, clear0
+               ret
+
+_clear_across:
+               pop ix
+               pop hl
+               pop de          ; E = y, D = x
+               pop bc          ; C = count
+               push bc
+               push de
+               push hl
+               push ix
+               call addr
+               ld a,#32
+               ld b,c
+clear2:                ld (hl),a
+               inc hl
+               djnz clear2
+_vtattr_notify:
+               ret
+
+_scroll_up:
+               call vtbase             ; HL now the base of the video
+               push hl
+               ld de,#64
+               add hl,de               ; HL is now the video second line
+               pop de                  ; top of video (destination)
+               ld bc,#1024-64
+               ldir
+               ret
+
+_scroll_down:
+               ret
+               call vtbase
+               ld de,#1024-64          
+               add hl,de               ; points to start of last line
+               dec hl                  ; end of line before last
+               push hl
+               ld de,#64
+               add hl,de               ; last char
+               pop de
+               ex de,hl
+               ld bc,#1024
+               lddr
+               ret
+
+csave:         .byte   0
+cpos:          .word   0
+
+
+               .area _COMMONMEM
+
+               .globl debughook
+debughook:
+               ret
diff --git a/Kernel/platform-trs80m1/vtswap.s b/Kernel/platform-trs80m1/vtswap.s
deleted file mode 100644 (file)
index 1ab78b0..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-;
-;      Do this in assembler so we can keep the vtbackbuf banked
-;
-               .module vtswap
-
-               .area _CODE2
-
-               .globl _vtswap
-               .globl _vtbackbuf
-
-_vtbackbuf:
-               .ds 1024
-
-_vtswap:
-                ld hl, #0xf800
-                ld de, #_vtbackbuf
-                ld bc, #1024   ; 64 * 16
-        exchit:
-                push bc
-                ld a, (de)     ; Could be optimised but its only 1K
-                ld c, (hl)     ; Probably worth doing eventuallly
-                ex de, hl
-                ld (hl), c
-                ld (de), a
-                inc hl
-                inc de
-                pop bc
-                dec bc
-                ld a, b
-                or c
-                jr nz, exchit
-                ret