From: Alan Cox Date: Mon, 15 Dec 2014 22:45:52 +0000 (+0000) Subject: mtx: Clean up the port and tidy loose ends X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a7acfeb9d3cb990d7b3d39659734f48d93a252d8;p=FUZIX.git mtx: Clean up the port and tidy loose ends Memory sizing DART setup Better CTC configuration Use IM2 so we can tell CTC and DART interrupts apart --- diff --git a/Kernel/platform-mtx/devfd.c b/Kernel/platform-mtx/devfd.c index 23e56589..7e124a84 100644 --- a/Kernel/platform-mtx/devfd.c +++ b/Kernel/platform-mtx/devfd.c @@ -48,7 +48,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) dptr = (uint16_t)udata.u_buf->bf_data; block = udata.u_buf->bf_blk; - kprintf("Issue command: drive %d block %d\n", minor, block); +// kprintf("Issue command: drive %d block %d\n", minor, block); cmd[0] = is_read ? FD_READ : FD_WRITE; cmd[1] = block / 16; /* 2 sectors per block */ cmd[2] = ((block & 15) << 1); /* 0 - 1 base is corrected in asm */ @@ -58,7 +58,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) while (ct < 2) { for (tries = 0; tries < 4 ; tries++) { - kprintf("Sector: %d Track %d\n", cmd[2]+1, cmd[1]); +// kprintf("Sector: %d Track %d\n", cmd[2]+1, cmd[1]); err = fd_operation(cmd, driveptr); if (err == 0) break; diff --git a/Kernel/platform-mtx/devices.c b/Kernel/platform-mtx/devices.c index 8fa0f482..48ec6d89 100644 --- a/Kernel/platform-mtx/devices.c +++ b/Kernel/platform-mtx/devices.c @@ -17,7 +17,7 @@ struct devsw dev_tab[] = /* The device driver switch table */ /* 1: /dev/hd Hard disc block devices (hdx - not supported yet) */ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 2: /dev/tty TTY devices */ - { tty_open, tty_close, tty_read, tty_write, tty_ioctl }, + { tty_open, mtxtty_close,tty_read, tty_write, tty_ioctl }, /* 3: /dev/lpr Printer devices */ { lpr_open, lpr_close, no_rdwr, lpr_write, no_ioctl }, /* 4: /dev/mem etc System devices (one offs) */ diff --git a/Kernel/platform-mtx/devtty.c b/Kernel/platform-mtx/devtty.c index 2b59a3ca..6f50f463 100644 --- a/Kernel/platform-mtx/devtty.c +++ b/Kernel/platform-mtx/devtty.c @@ -87,10 +87,20 @@ int tty_carrier(uint8_t minor) static uint8_t dart_setup[] = { 1, 0x19, - 2, 0x00, - 3, 0xC1, /* 8bit */ - 4, 0x04, /* 8N1 */ - 5, 0x72, /* Tx 8bit, enabled, rts on */ + 2, 0x04, /* Vector */ + 3, 0x00, + 4, 0x00, + 5, 0x00, +}; + +/* Baud rates for Z80 DART */ +static uint8_t dartbaud[] = { + 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x40, 0x20, + 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00 +}; + +static uint8_t dartbits[] = { + 0x00, 0x40, 0x80, 0xC0 }; void tty_setup(uint8_t minor) @@ -98,13 +108,36 @@ void tty_setup(uint8_t minor) irqflags_t flags; int i; char *p = dart_setup; + struct tty *t = &ttydata[minor]; + uint8_t cf = t->termios.c_cflag; + uint8_t r; + + if ((cf & CBAUD) < B150) { + cf &= ~CBAUD; + cf |= B150; + } + if ((cf & CBAUD) > B19200) { + cf &= ~CBAUD; + cf |= B19200; + } + r = dartbits[(cf & CSIZE) >> 4]; + dart_setup[5] = 0x01 | r; + dart_setup[9] = 0x8A | r >> 1; + r = 0x04; + if (cf & PARENB) { + r |= 1; + if (!(cf & PARODD)) + r|=2; + } + dart_setup[7] = r; + dart_setup[7] = r; if (minor == 1) { - ctc1 = 0x7F; - ctc1 = 0x02; /* FIXME set by baud rate */ + ctc1 = 0x45; + ctc1 = dartbaud[cf & CBAUD]; } else { - ctc2 = 0x7F; - ctc2 = 0x02; + ctc2 = 0x45; + ctc1 = dartbaud[cf & CBAUD]; } flags = di(); for (i = 0; i < 10; i++) { @@ -116,6 +149,23 @@ void tty_setup(uint8_t minor) irqrestore(flags); } +int mtxtty_close(uint8_t minor) +{ + irqflags_t flags; + int err = tty_close(minor); + + flags = di(); + if (minor == 3) { + serialAc = 0x05; + serialAc = 0x00; /* Drop DTR/RTS */ + } + if (minor == 4) { + serialBc = 0x05; + serialBc = 0x00; /* Drop DTR/RTS */ + } + irqrestore(flags); + return err; +} static uint16_t keymap[8]; static uint16_t keyin[8]; @@ -223,7 +273,7 @@ void kbd_interrupt(void) keydecode(); } -void serial_interrupt(void) +void tty_interrupt(void) { uint8_t r; @@ -234,14 +284,18 @@ void serial_interrupt(void) tty_inproc(3, r); r = serialAc; } + if (!(r & 0x08)) + tty_carrier_drop(3); r = serialBc; while (r & 0x01) { r = serialBd; tty_inproc(4, r); r = serialBc; } + serialAc = 0x07 << 3; /* Return from interrupt */ + if (!(r & 0x08)) + tty_carrier_drop(4); } - serialAc = 0x07 << 3; /* Return from interrupt */ } /* This is used by the vt asm code, but needs to live in the kernel */ diff --git a/Kernel/platform-mtx/devtty.h b/Kernel/platform-mtx/devtty.h index dc0e2a6c..0ddb268d 100644 --- a/Kernel/platform-mtx/devtty.h +++ b/Kernel/platform-mtx/devtty.h @@ -2,6 +2,8 @@ #define __DEVTTY_DOT_H__ extern void kbd_interrupt(void); +extern void tty_interrupt(void); +extern int mtxtty_close(uint8_t); extern signed char vt_twidth[2]; extern signed char vt_tright[2]; diff --git a/Kernel/platform-mtx/main.c b/Kernel/platform-mtx/main.c index 8557082f..0c1a7fda 100644 --- a/Kernel/platform-mtx/main.c +++ b/Kernel/platform-mtx/main.c @@ -6,29 +6,37 @@ uint16_t ramtop = PROGTOP; uint16_t vdpport = 0x02 + 256 * 40; /* port and width */ +uint8_t membanks; void pagemap_init(void) { int i; - /* Ten banks (should check memory size) FIXME */ - for (i = 0x81; i < 0x8A; i++) + /* Up to ten banks */ + for (i = 0x81; i <= membanks; i++) pagemap_add(i); } /* On idle we spin checking for the terminals. Gives us more responsiveness - for the polled ports */ + for the polled ports. We don't need this on MTX, but we probably do for + MEMU */ + void platform_idle(void) { - /* We don't want an idle poll and IRQ driven tty poll at the same moment */ irqflags_t irq = di(); -// tty_pollirq(); + tty_interrupt(); irqrestore(irq); } void platform_interrupt(void) { - kbd_interrupt(); - timer_interrupt(); + extern uint8_t irqvector; + + if (irqvector == 1) { + tty_interrupt(); + return; + } + kbd_interrupt(); + timer_interrupt(); } /* Nothing to do for the map of init */ diff --git a/Kernel/platform-mtx/mtx.s b/Kernel/platform-mtx/mtx.s index f4aa2115..789f53fa 100644 --- a/Kernel/platform-mtx/mtx.s +++ b/Kernel/platform-mtx/mtx.s @@ -22,6 +22,7 @@ .globl _sil_memcpy .globl _kernel_flag + .globl _irqvector ; exported debugging tools .globl _trap_monitor @@ -30,6 +31,7 @@ ; imported symbols .globl _ramsize .globl _procmem + .globl _membanks .globl unix_syscall_entry .globl null_handler @@ -52,6 +54,18 @@ ; COMMON MEMORY BANK (0xC000 upwards) ; ----------------------------------------------------------------------------- .area _COMMONMEM +; +; This is linked straight after the udata block so is 256 byte +; aligned. Put the im2 table first +; + .globl intvectors + +intvectors: + .dw ctc0_int ; VDP counting timer + .dw bogus_int ; Baud generator + .dw bogus_int ; Baud generator + .dw trace_int ; can be used for CPU tracing etc + .dw serial_int ; we don't use the vector mod functions _trap_monitor: di @@ -63,6 +77,54 @@ _trap_reboot: out (0),a ; ROM mode, we are in common so survive rst 0 ; kaboom +_irqvector: + .db 0 ; used to identify the vector in question + +ctc0_int: push af + xor a + ld (_irqvector), a + pop af + jp interrupt_handler +trace_int: +bogus_int: reti +serial_int: + push af + ld a, #1 + ld (_irqvector), a + pop af + jp interrupt_handler + +; Kernel is in 0x80 so we just need to count the banks that differ +size_ram: + ld hl, #0x1000 ; good as anywhere + ld bc, #0x8100 ; port 0 in c, b = 0x81 +size_next: + out (c), b + ld a, #0xA5 + ld (hl), a + cp (hl) + jr nz, size_nonram + cpl + ld (hl), a + cp (hl) + jr nz, size_nonram + inc b + ld a, #0x8B + cp b + jr nz, size_next ; All banks done +size_nonram: + ld a, #0x80 + out (c), a ; Return to kernel + res 7,b ; Clear the flag so we just have banks + dec b ; Last valid bank + ld a, b + ld (_membanks), a + ld hl, #0 + ld de, #48 +sizer: add hl, de + djnz sizer + ret + ; ----------------------------------------------------------------------------- ; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped) ; ----------------------------------------------------------------------------- @@ -91,11 +153,12 @@ init6845: ret init_hardware: + call size_ram ; FIXME: do proper size checker ; set system RAM size (hardcoded for now) - ld hl, #480 ld (_ramsize), hl - ld hl, #(480-48) ; 64K for kernel + and a + sbc hl, de ; DE will hold 48 at this point ld (_procmem), hl ; set up interrupt vectors for the kernel (also sets up common memory in page 0x000F which is unused) @@ -107,20 +170,22 @@ init_hardware: ; Program the video engine call vdpinit - ; FIXME: set up interrupt timer on the CTC - ; 08 is channel 0, which is input for vdp + ; 08 is channel 0, which is input from VDP ; 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 xor a out (0x08), a ; vector 0 - ld a, #0xA5 + ld a, #0xC5 out (0x08), a ; CTC 0 as our IRQ source - ld a, #0xFC + ld a, #0x01 out (0x08), a ; Timer constant - im 1 ; set CPU interrupt mode + ld hl, #intvectors ; Work around SDCC crappiness + ld a, h + ld i, a + im 2 ; set CPU interrupt mode call _vtinit ; init the console video