trs80m1: big set of somewhat intertwined updates
authorAlan Cox <alan@linux.intel.com>
Fri, 13 Jul 2018 22:49:23 +0000 (23:49 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 13 Jul 2018 22:49:23 +0000 (23:49 +0100)
- Move the video genie serial to tty4 - you can after all have either type
  on a VG system
- Add RTC support
- Dynamically sized external buffers

The buffer bouncing logic is still crap and as a result it sucks performance
wise but that's a follow up item.

Kernel/platform-trs80m1/buffers.c
Kernel/platform-trs80m1/config.h
Kernel/platform-trs80m1/crt0.s
Kernel/platform-trs80m1/devices.c
Kernel/platform-trs80m1/devtty.c
Kernel/platform-trs80m1/devtty.h
Kernel/platform-trs80m1/discard.c
Kernel/platform-trs80m1/main.c
Kernel/platform-trs80m1/trs80.s

index d6fccbe..ca1439f 100644 (file)
@@ -1,5 +1,6 @@
 #include <kernel.h>
 #include <kdata.h>
+#include <printf.h>
 
 /*
  *     Must live in CODE2
@@ -50,18 +51,23 @@ void blkzero(struct blkbuf *buf)
 
 extern uint8_t bufdata[];
 
+/* This is called at start up to assign data to the first buffers, and then
+   again to assign data to the extra allocated buffers */
+
+static bufptr bnext = bufpool;
+
 void bufsetup(void)
 {
-    uint8_t *p = bufdata;
-    bufptr bp = bufpool;
+    extern uint8_t *bdnext;
+    bufptr bp;
 
-    for(bp = bufpool; bp < bufpool_end; ++bp) {
-        bp->__bf_data = p;
-        p += BLKSIZE;
+    for(bp = bnext; bp < bufpool_end; ++bp) {
+        bp->__bf_data = bdnext;
+        bdnext += BLKSIZE;
     }
+    bnext = bp;
 }
 
-
 /*
  *     Scratch buffers for syscall arguments - until we can rework
  *     execve and realloc to avoid this need
index f1b1803..4a08ed7 100644 (file)
@@ -25,6 +25,8 @@
 #define CONFIG_INPUT_GRABMAX   3
 /* External buffers (so we can balance things better) */
 #define CONFIG_BLKBUF_EXTERNAL
+/* And our buffer pool is dynamically sized */
+#define CONFIG_DYNAMIC_BUFPOOL
 
 #define MAX_MAPS       16      /* 512K */
 
 #define CMDLINE        NULL      /* Location of root dev name */
 
 /* Device parameters */
-#define NUM_DEV_TTY 3
+#define NUM_DEV_TTY 4
 #define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
 #define SWAPDEV  (swap_dev)  /* Device for swapping (dynamic). */
-#define NBUFS    10        /* Number of block buffers - keep in sync with asm! */
+#define NBUFS            /* Number of block buffers - keep in sync with asm! */
 #define NMOUNTS         3         /* Number of mounts at a time */
 
 extern void platform_discard(void);
index 3722ae8..f544370 100644 (file)
@@ -5,9 +5,12 @@
                .area _CODE
                .area _CODE1
                .area _CODE2
+               .area _VIDEO
                .area _DATA2
+               ; We want the DISCARD2 area last as we eventually want to
+               ; expand all over it for buffers
+               .area _BUFFERS2
                .area _DISCARD2
-               .area _VIDEO
                .area _COMMONMEM
                .area _STUBS
                .area _CONST
index 16d5829..76cc4f2 100644 (file)
@@ -21,7 +21,7 @@ struct devsw dev_tab[] =  /* The device driver switch table */
   /* 1: /dev/fd                Floppy disc block devices */
   {  fd_open,     no_close,     fd_read,   fd_write,   no_ioctl  },
   /* 2: /dev/tty       TTY devices */
-  {  tty_open,    trstty_close, tty_read,  tty_write,  gfx_ioctl },
+  {  trstty_open, trstty_close, tty_read,  tty_write,  gfx_ioctl },
   /* 3: /dev/lpr       Printer devices */
   {  lpr_open,    lpr_close,    no_rdwr,   lpr_write,  no_ioctl  },
   /* 4: /dev/mem etc   System devices (one offs) */
index f01550a..8e7e1fc 100644 (file)
 #include <stdarg.h>
 #include <trs80.h>
 
+/* FIXME: move to external tty buffers and bank them */
 static char tbuf1[TTYSIZ];
 static char tbuf2[TTYSIZ];
 static char tbuf3[TTYSIZ];
+static char tbuf4[TTYSIZ];
 
 uint8_t curtty;                        /* output side */
 static uint8_t inputtty;       /* input side */
@@ -21,12 +23,17 @@ static struct vt_switch ttysave[2];
 struct vt_repeat keyrepeat;
 extern uint8_t *vtbase[2];
 
+/* Default to having /dev/tty and the two consoles openable. Our probe
+   routine will add tty3/tty4 as appropriate */
+
+static uint8_t ports = 7;
+
 /* The Video Genie EG3020 is similar but the TR1865 is
    data in: F8, status out F8, data out: F9 status in F9,
    baud by switches.
 
    Or at least it probably does. In theory you can use an adapter
-   cable and Tandy bits with the Genie and then for serial we break... */
+   cable and Tandy bits so we treat them as two ports */
 
 __sfr __at 0xE8 tr1865_ctrl;
 __sfr __at 0xE9 tr1865_baud;
@@ -40,7 +47,8 @@ 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 },
-    {   tbuf3,   tbuf3,   tbuf3,   TTYSIZ,   0,   TTYSIZ/2 }
+    {   tbuf3,   tbuf3,   tbuf3,   TTYSIZ,   0,   TTYSIZ/2 },
+    {   tbuf4,   tbuf4,   tbuf4,   TTYSIZ,   0,   TTYSIZ/2 }
 };
 
 /* Write to system console */
@@ -54,12 +62,13 @@ void kputchar(char c)
 ttyready_t tty_writeready(uint8_t minor)
 {
     uint8_t reg;
-    if (minor != 3)
+    if (minor < 3)
         return TTY_READY_NOW;
-    if (trs80_model == VIDEOGENIE)
-        reg = vg_tr1865_wrst;
-    else
+    /* FIXME RTS/CTS is supported by the hardware */
+    if (minor == 3)
        reg = tr1865_status;
+    else
+        reg = vg_tr1865_wrst;
     return (reg & 0x40) ? TTY_READY_NOW : TTY_READY_SOON;
 }
 
@@ -96,12 +105,12 @@ static void vtexchange(void)
 void tty_putc(uint8_t minor, unsigned char c)
 {
     irqflags_t irq;
-    if (minor == 3) {
-        if (trs80_model == VIDEOGENIE)
-           vg_tr1865_wrst = c;
-       else
-           tr1865_rxtx = c;
-    else {
+
+    if (minor == 3)
+        tr1865_rxtx = c;
+    else if (minor == 4)
+       vg_tr1865_wrst = c;
+    else {
         if (video_mode == 2)   /* Micrografyx */
           return;
         irq = di();
@@ -135,12 +144,23 @@ void tty_interrupt(void)
     }
 }
 
-void tty_vg_poll(void)
+void tty_poll(void)
 {
-    uint8_t reg = vg_tr1865_wrst;
-    if (reg & 0x80) {
-        reg = vg_tr1865_ctrd;
-        tty_inproc(3, reg);
+    uint8_t reg;
+
+    if (ports & 0x10) {
+           reg = vg_tr1865_wrst;
+           if (reg & 0x80) {
+               reg = vg_tr1865_ctrd;
+               tty_inproc(4, reg);
+           }
+    }
+    if (ports & 0x08) {
+           reg = tr1865_status;
+           if (reg & 0x80) {
+               reg = vg_tr1865_ctrd;
+               tty_inproc(3, reg);
+           }
     }
 }
 
@@ -157,8 +177,10 @@ void tty_setup(uint8_t minor)
 {
     uint8_t baud;
     uint8_t ctrl;
-    if (minor != 3 || trs80_model == VIDEOGENIE || trs80_model == LNW80)
+
+    if (minor != 3 || trs80_model == LNW80)
         return;
+
     baud = ttydata[3].termios.c_cflag & CBAUD;
     if (baud > B19200) {
         ttydata[3].termios.c_cflag &= ~CBAUD;
@@ -178,6 +200,16 @@ void tty_setup(uint8_t minor)
     tr1865_ctrl = ctrl;
 }
 
+int trstty_open(uint8_t minor, uint16_t flags)
+{
+    /* Serial port cards are optional */
+    if (minor < 8 && !(ports & (1 << minor))) {
+        udata.u_error = ENODEV;
+        return -1;
+    }
+    return tty_open(minor, flags);
+}
+
 int trstty_close(uint8_t minor)
 {
     if (minor == 3 && ttydata[3].users == 0) {
@@ -206,6 +238,14 @@ void tty_sleeping(uint8_t minor)
         used(minor);
 }
 
+void trstty_probe(void)
+{
+       if (vg_tr1865_wrst != 0xFF)
+               ports |= (1 << 4);
+       if (tr1865_status != 0xFF)
+               ports |= (1 << 3);
+}
+
 uint8_t keymap[8];
 static uint8_t keyin[8];
 static uint8_t keybyte, keybit;
index 89abc3b..f85d2db 100644 (file)
@@ -2,9 +2,11 @@
 #define _DEVTTY_H
 
 extern void tty_interrupt(void);
-extern void tty_vg_poll(void);
+extern void tty_poll(void);
 extern void kbd_interrupt(void);
+extern int trstty_open(uint8_t minor, uint16_t flags);
 extern int trstty_close(uint8_t minor);
+extern void trstty_probe(void);
 extern void vtbuf_init(void);
 
 /* And from the asm helper */
index 4e999c4..8eb29ac 100644 (file)
@@ -17,6 +17,7 @@ void device_init(void)
 #endif
   floppy_setup();
   hd_probe();
+  trstty_probe();
   gfx_init();
   tape_init();
 }
index ec229ef..d86f60b 100644 (file)
@@ -26,13 +26,9 @@ void platform_idle(void)
     return;
   }
   /* The others .. do not. For the model I and LNW80 we just poll the
-     port as if it interrupted, for the Video Genie we have a different
-     helper */
+     port as if it interrupted, likewise check the Video Genie port */
   irq = di();
-  if (trs80_model == VIDEOGENIE)
-    tty_vg_poll();
-  else
-    tty_interrupt();
+  tty_poll();
   irqrestore(irq);
 }
 
@@ -87,6 +83,12 @@ void platform_interrupt(void)
   }
 }
 
+/* We allow for up to 36 buffers (18K) */
+#define MAX_BUFS       36
+
+struct blkbuf bufpool[MAX_BUFS];
+struct blkbuf *bufpool_end = &bufpool[NBUFS];
+
 /*
  *     We can't recover discard space usefully... yet. I have a cunning plan
  *     involving external buffers in the spare bank space 8)
@@ -94,6 +96,23 @@ void platform_interrupt(void)
 
 void platform_discard(void)
 {
+        extern uint8_t bufdata_end[];
+       /* The buffers are the last kept thing in segment 2, so we can blow
+          away from the buffers end to FFFF */
+       bufptr bp;
+       uint16_t space = 0xFFFF - bufdata_end;
+       space /= BLKSIZE;
+       if (space > MAX_BUFS - NBUFS)
+               space = MAX_BUFS - NBUFS;
+       bufpool_end += space;
+       kprintf("Reclaiming memory.. total buffers %d\n",
+         bufpool_end - bufpool);
+       for( bp = bufpool + NBUFS; bp < bufpool_end; ++bp ){
+               bp->bf_dev = NO_DEVICE;
+               bp->bf_busy = BF_FREE;
+       }
+       /* Assign data to the extra buffers */
+       bufsetup();
 }
 
 #ifdef CONFIG_RTC
@@ -127,11 +146,11 @@ uint8_t platform_rtc_secs(void)
     return rv;
 }
 
+/* If the compiler segfaults here you need at least SDCC #10471 */
+
 int platform_rtc_read(void)
 {
-#if 0
-    /* We need SDCC bug 2770 fixed first */
-    uint16_t len;
+    uint16_t len = sizeof(struct cmos_rtc);
     struct cmos_rtc cmos;
     uint8_t *p;
     uint8_t r, y;
@@ -167,10 +186,6 @@ int platform_rtc_read(void)
     if (uput(&cmos, udata.u_base, len) == -1)
         return -1;
     return len;
-#else
-       udata.u_error = EOPNOTSUPP;
-       return -1;
-#endif    
 }
 
 /* Yes I'm a slacker .. this wants adding but it's ugly
index 90f95f2..1db0bcb 100644 (file)
@@ -234,7 +234,14 @@ _hd_xfer_out:
 ;
 ;      Storage for buffers. Must be banked with CODE2
 ;
-           .area _DATA2
+           .area _BUFFERS2
            .globl _bufdata
+           .globl _bufdata_end
+           .globl _bdnext
 _bufdata:
-           .ds 512 * 10
+           .ds 512 * 5
+_bufdata_end:
+
+           .area _COMMONMEM
+_bdnext:
+           .dw _bufdata