#include <kernel.h>
#include <kdata.h>
+#include <printf.h>
/*
* Must live in CODE2
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
#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 5 /* Number of block buffers - keep in sync with asm! */
#define NMOUNTS 3 /* Number of mounts at a time */
extern void platform_discard(void);
.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
/* 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) */
#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 */
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;
{ 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 */
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;
}
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();
}
}
-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);
+ }
}
}
{
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;
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) {
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;
#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 */
#endif
floppy_setup();
hd_probe();
+ trstty_probe();
gfx_init();
tape_init();
}
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);
}
}
}
+/* 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)
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
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;
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
;
; 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