From 69eb71751c8b0590eec939b140cb9bd825940473 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 27 Jul 2018 21:56:27 +0100 Subject: [PATCH] rc2014: do a pile of cleanup work - Start working on tty autodetect - Sort out non standard SIO layouts Still need to look further into the CTC usage and tidy up the boot logic so we can do a handy boot from CP/M --- Kernel/platform-rc2014/Makefile | 10 +- Kernel/platform-rc2014/README | 65 ++++++-- Kernel/platform-rc2014/config.h | 48 ++---- Kernel/platform-rc2014/devtty.c | 159 ++++++++---------- Kernel/platform-rc2014/devtty.h | 8 +- Kernel/platform-rc2014/devtty_discard.c | 21 --- Kernel/platform-rc2014/discard.c | 6 - Kernel/platform-rc2014/fuzix.lnk | 3 +- Kernel/platform-rc2014/kernel.def | 19 +-- Kernel/platform-rc2014/main.c | 66 ++++---- Kernel/platform-rc2014/platform_ide.h | 40 +---- Kernel/platform-rc2014/rc2014.h | 17 +- Kernel/platform-rc2014/rc2014.s | 211 +++++++++++++----------- 13 files changed, 307 insertions(+), 366 deletions(-) delete mode 100644 Kernel/platform-rc2014/devtty_discard.c diff --git a/Kernel/platform-rc2014/Makefile b/Kernel/platform-rc2014/Makefile index 8dfd7142..bbc02fc8 100644 --- a/Kernel/platform-rc2014/Makefile +++ b/Kernel/platform-rc2014/Makefile @@ -1,9 +1,10 @@ ASRCS = crt0.s tricks.s commonmem.s rc2014.s monitor.s vfdterm.s ASRCS += devrd_zeta2_hw.s CSRCS = devices.c main.c devtty.c devrd_zeta2.c vfd-debug.c vfd-term.c -DISCARD_CSRCS = discard.c devtty_discard.c -DISCARD_DSRCS = -DSRCS = ../dev/devfd.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c +CSRCS += devinput.c +DISCARD_CSRCS = discard.c +DISCARD_DSRCS = ../dev/devide_discard.c +DSRCS = ../dev/devfd.c ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c DSRCS += ../dev/devrd.c DASRCS = ../dev/devfd_hw.s ../dev/devrd_hw.s @@ -59,6 +60,3 @@ image: ../cpm-loader/makecpmloader ../cpm-loader/cpmload.bin ../fuzix.bin 0x88 fuzix.com ../cpm-loader/makecpmloader ../cpm-loader/fuzixload.bin ../fuzix.bin 0x88 fuzix -cleanup_sio_acia: - rm -f devtty.asm devtty.rel main.asm main.rel rc2014.rel - rm -f devtty_discard.asm devtty_discard.rel discard.asm discard.rel diff --git a/Kernel/platform-rc2014/README b/Kernel/platform-rc2014/README index 32b53847..9424d390 100644 --- a/Kernel/platform-rc2014/README +++ b/Kernel/platform-rc2014/README @@ -1,4 +1,3 @@ ---- README for RC2014 --- This is Fuzix for the RC2014 Imported into the current tree from Scott Baker's git tree and adjusted to @@ -11,18 +10,25 @@ Sergey Kiselev , and others. Supported Hardware - * The Flash ROM / RAM board is required. This board is basically a clone of - the memory management subsystem of the Zeta V2. It replaces the RC2014's - default ROM and RAM boards. + RC2014 Z80 card or compatible + 512K ROM / RAM board. This board is basically a clone of the memory + management subsystem of the Zeta V2. It replaces the RC2014's + default ROM and RAM boards. + A serial IO board. Either an RC2014 SIO/2 board or a 68B50 ACIA board. + If you have a Scott Baker SIO/2 card you'll need to see config.h + CTC board at 0x90 - * A serial IO board is required. This can either be an SIO/2 board or a - 68B50 ACIA board. The 68B50 ACIA is the one that comes standard with the - RC2014 kit. + Options: - * VFD Display. If config.h:CONFIG_VFD_TERM is defined, then the VFD Terminal - will be supported. This will display all output to the serial port on the - VFD. If it's defined and you don't have a VFD, then it probably won't hurt - anything, other than some useless io to ports 0-3. + VFD Display. If config.h:CONFIG_VFD_TERM is defined, then the VFD + Terminal will be supported. This will display all output to the serial + port on the VFD. + + The RC2014 CF card interface, or compatible at 0x10. + + Floppy Drive Interface + + RC2014 Joystick Notes @@ -32,17 +38,40 @@ Notes Configuration - * Make sure to edit config.h and kernel.def to specify whether you are - using SIO/2 or ACIA. - * The Makefile assumes a file system image exists in ../rc2014_root_fs. See the Zeta V2 instructions for building a filesystem. Things that don't work - * The RC2014 doesn't come with a clock. I added fakeclock.c, which is a - clock that always returns 0. - - * I couldn't get the WD37C65 floppy to work. + * The RC2014 doesn't come with a clock. * Flow control isn't yet enabled for the serial port. + +Stuff To Do + + * Rework the CTCs if we can so we use CTC0 as a timer for the CTC clock and + use CTC1 to count CTC0 overflows. That way we can use the CTC0 interrupt + and the CTC1 value together in order to a) spot missed events and b) allow + us to run without using IM2 given the poor IM2 support on RC2014. That + then still allows us to use CTC for UART speed, and hopefully CTC3 for + single step debugging. + + * Can we detect which kind of SIO and CTC we have and where + + * Other tty options - can we autodetect 16550A at 0x80. Detect SIO at 0x84. + + * Probe both 0x10 and 0xE0 for CF ? + + * How to represent a Z80 PIO usefully to Fuzix (similar issues with Nascom) + both raw and hosting an interface (eg /dev/lp or even floppy) + + * Better boot story - native and from CP/M plus support partition tables ? + + * Work out how to co-exist better and maybe even modify ROMWBW so we can + use it + + * Swap + + * TMS9918A support once there is a suitable card + + * Sound support once we have the core sound layer diff --git a/Kernel/platform-rc2014/config.h b/Kernel/platform-rc2014/config.h index e560250f..a1323850 100644 --- a/Kernel/platform-rc2014/config.h +++ b/Kernel/platform-rc2014/config.h @@ -29,10 +29,11 @@ /* WRS: this is probably wrong -- we want to swap the full 64K minus the common code */ /* For now let's just use something and fix this up later when we have a swap device */ -#define SWAP_SIZE 0x7F /* 63.5K in blocks (which is the wrong number) */ +#define SWAP_SIZE 0x79 /* 60.5K in blocks (prog + udata) */ #define SWAPBASE 0x0000 /* start at the base of user mem */ -#define SWAPTOP 0xFF00 /* can we stop at the top? not sure how. let's stop short. */ -#define MAX_SWAPS 10 /* Well, that depends really, hmmmmmm. Pick a number, any number. */ +#define SWAPTOP 0xF200 /* Swap out udata and program */ +/* FIXME: do this off partition tables */ +#define MAX_SWAPS 10 /* Well, that depends really, hmmmmmm. Pick a number, any number. */ /* We need a tidier way to do this from the loader */ #define CMDLINE NULL /* Location of root dev name */ @@ -43,7 +44,7 @@ #define NBUFS 4 /* Number of block buffers, keep in line with space reserved in zeta-v2.s */ #define NMOUNTS 4 /* Number of mounts at a time */ -#define MAX_BLKDEV 4 /* 1 ROM disk, 1 RAM disk, 1 floppy, 1 PPIDE */ +#define MAX_BLKDEV 4 /* 1 ROM disk, 1 RAM disk, 1 floppy, 1 IDE */ #if 0 /* for now */ /* On-board DS1302, we can read the time of day from it */ @@ -53,21 +54,13 @@ /* Floppy support */ #define CONFIG_FLOPPY /* #define CONFIG_FLOPPY to enable floppy */ - -/* Optional ParPortProp board connected to PPI */ -//#define CONFIG_PPP /* #define CONFIG_PPP to enable as tty3 */ - -#define CONFIG_SIO /* #define CONFIG_SIO to enable SIO support */ -//#define CONFIG_ACIA /* #define CONFIG_SIO to enable ACIA support */ +/* IDE/CF support */ +#define CONFIG_IDE #define CONFIG_VFD_TERM /* #define CONFIG_VFD_TERM to show console output on VFD display */ -// sanity check -#ifdef CONFIG_SIO -#ifdef CONFIG_ACIA -#error "please define either CONFIG_SIO or CONFIG_ACIA but not both" -#endif -#endif +#define CONFIG_INPUT /* Input device for joystick */ +#define CONFIG_INPUT_GRABMAX 0 /* No keyboard to grab */ /* Device parameters */ #define CONFIG_DEV_MEM /* enable /dev/mem driver */ @@ -81,20 +74,15 @@ #define DEV_RD_ROM_SIZE ((uint32_t)DEV_RD_ROM_PAGES << 14) /* size of the ROM disk */ #define DEV_RD_RAM_SIZE ((uint32_t)DEV_RD_RAM_PAGES << 14) /* size of the RAM disk */ -#ifdef CONFIG_PPP - /* SD card in ParPortProp */ - #define CONFIG_SD - #define SD_DRIVE_COUNT 1 - #define NUM_DEV_TTY 3 +#define NUM_DEV_TTY 2 - /* ParPortProp as the console */ - #define BOOT_TTY (512 + 3) -#else - #define NUM_DEV_TTY 2 - - /* UART0 as the console */ - #define BOOT_TTY (512 + 1) - #define TTY_INIT_BAUD B38400 -#endif +/* UART0 as the console */ +#define BOOT_TTY (512 + 1) +#define TTY_INIT_BAUD B115200 /* Hardwired generally */ #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ + +/* The Scott Baker SIO has a non-standard layout (it predates the official one) */ +/* You'll need to define this if you have a Scott Baker SIO2 card, or submit + a fancier autodetect! Also you'll need to change rc2014.s */ +#undef CONFIG_SIO_BAKER diff --git a/Kernel/platform-rc2014/devtty.c b/Kernel/platform-rc2014/devtty.c index e7bf9b4d..01a8be17 100644 --- a/Kernel/platform-rc2014/devtty.c +++ b/Kernel/platform-rc2014/devtty.c @@ -11,33 +11,26 @@ char tbuf1[TTYSIZ]; char tbuf2[TTYSIZ]; -#ifdef CONFIG_PPP -char tbufp[TTYSIZ]; -#endif - -unsigned char sio_type; +uint8_t ser_type; -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}, -#ifdef CONFIG_PPP - {tbufp, tbufp, tbufp, TTYSIZ, 0, TTYSIZ/2}, -#endif +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}, }; void tty_setup(uint8_t minor) { - if (minor == 1) { - } + if (minor == 1) { + } } int tty_carrier(uint8_t minor) { -// uint8_t c; +// uint8_t c; if (minor == 1) { -// c = UART0_MSR; -// return (c & 0x80) ? 1 : 0; /* test DCD */ +// c = UART0_MSR; +// return (c & 0x80) ? 1 : 0; /* test DCD */ } return 1; } @@ -46,102 +39,84 @@ void tty_pollirq_sio(void) { uint8_t ca, cb; - SIOA_C = 0; // read register 0 - ca = SIOA_C; - if (ca & 1) { - tty_inproc(1, SIOA_D); - } - if (ca & 4) { - tty_outproc(1); - SIOA_C = 5 << 3; // reg 0 CMD 5 - reset transmit interrupt pending - } + SIOA_C = 0; // read register 0 + ca = SIOA_C; + if (ca & 1) { + tty_inproc(1, SIOA_D); + } + if (ca & 4) { + tty_outproc(1); + SIOA_C = 5 << 3; // reg 0 CMD 5 - reset transmit interrupt pending + } - SIOB_C = 0; // read register 0 - cb = SIOB_C; - if (cb & 1) { - tty_inproc(2, SIOB_D); - } - if (cb & 4) { - tty_outproc(2); - SIOB_C = 5 << 3; // reg 0 CMD 5 - reset transmit interrupt pending - } + SIOB_C = 0; // read register 0 + cb = SIOB_C; + if (cb & 1) { + tty_inproc(2, SIOB_D); + } + if (cb & 4) { + tty_outproc(2); + SIOB_C = 5 << 3; // reg 0 CMD 5 - reset transmit interrupt pending + } } void tty_pollirq_acia(void) { uint8_t ca; - ca = ACIA_C; - if (ca & 1) { - tty_inproc(1, ACIA_D); - } - if (ca & 2) { - tty_outproc(1); - } -} - -#ifdef CONFIG_PPP -void tty_poll_ppp(void) -{ - while(PROPIO2_STAT & 0x20) - tty_inproc(3, PROPIO2_TERM); + ca = ACIA_C; + if (ca & 1) { + tty_inproc(1, ACIA_D); + } + if (ca & 2) { + tty_outproc(1); + } } -#endif void tty_putc(uint8_t minor, unsigned char c) { -// while (tty_writeready(minor) != TTY_READY_NOW) ; - if (minor == 1) { -#ifdef CONFIG_SIO - SIOA_D = c; -#endif -#ifdef CONFIG_ACIA - ACIA_D = c; -#endif + if (ser_type == 1) { + if (minor == 1) { + SIOA_D = c; #ifdef CONFIG_VFD_TERM - vfd_term_write(c); + vfd_term_write(c); #endif - } else if (minor == 2) { - SIOB_D = c; -#ifdef CONFIG_PPP - } else if (minor = 3) { + } else if (minor == 2) + SIOB_D = c; + } else if (minor == 1) + ACIA_D = c; + else if (minor = 3) { /* FIXME: implement */ -#endif } } +/* We will need this for SIO once we implement flow control signals */ void tty_sleeping(uint8_t minor) { - if (minor == 1) { -// UART0_IER = 0x0B; /* enable all but LSR interrupt */ - } } ttyready_t tty_writeready(uint8_t minor) { uint8_t c; - if (minor == 1) { -#ifdef CONFIG_SIO - SIOA_C = 0; // read register 0 - c = SIOA_C; - if (c & 0x04) /* THRE? */ - return TTY_READY_NOW; - return TTY_READY_SOON; -#endif -#ifdef CONFIG_ACIA - c = ACIA_C; - if (c & 0x02) /* THRE? */ - return TTY_READY_NOW; - return TTY_READY_SOON; -#endif - } else if (minor == 2) { -#ifdef CONFIG_SIO - SIOB_C = 0; // read register 0 - c = SIOB_C; - if (c & 0x04) /* THRE? */ - return TTY_READY_NOW; - return TTY_READY_SOON; -#endif + if (ser_type == 1) { + if (minor == 1) { + SIOA_C = 0; /* read register 0 */ + c = SIOA_C; + if (c & 0x04) /* THRE? */ + return TTY_READY_NOW; + return TTY_READY_SOON; + } else if (minor == 2) { + SIOB_C = 0; /* read register 0 */ + c = SIOB_C; + if (c & 0x04) /* THRE? */ + return TTY_READY_NOW; + return TTY_READY_SOON; + } + } else if (ser_type == 2 && minor == 1) { + c = ACIA_C; + if (c & 0x02) /* THRE? */ + return TTY_READY_NOW; + return TTY_READY_SOON; } return TTY_READY_NOW; } @@ -153,7 +128,7 @@ void tty_data_consumed(uint8_t minor) /* kernel writes to system console -- never sleep! */ void kputchar(char c) { - tty_putc(TTYDEV - 512, c); - if(c == '\n') - tty_putc(TTYDEV - 512, '\r'); + tty_putc(TTYDEV - 512, c); + if (c == '\n') + tty_putc(TTYDEV - 512, '\r'); } diff --git a/Kernel/platform-rc2014/devtty.h b/Kernel/platform-rc2014/devtty.h index e88fb5ef..518450e6 100644 --- a/Kernel/platform-rc2014/devtty.h +++ b/Kernel/platform-rc2014/devtty.h @@ -1,16 +1,10 @@ #ifndef __DEVTTY_DOT_H__ #define __DEVTTY_DOT_H__ -#define SIO_SIO 1 - void tty_putc(uint8_t minor, unsigned char c); void tty_pollirq_sio(void); void tty_pollirq_acia(void); -void sio_init(void); -void acia_init(void); +extern uint8_t ser_type; -#ifdef CONFIG_PPP -void tty_poll_ppp(void); -#endif #endif diff --git a/Kernel/platform-rc2014/devtty_discard.c b/Kernel/platform-rc2014/devtty_discard.c deleted file mode 100644 index 989d99f6..00000000 --- a/Kernel/platform-rc2014/devtty_discard.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -extern unsigned char sio_type; - -/* uart0_init - detect UART type, print it, enable FIFO if present - */ -void sio_init(void) { - kprintf("UART0 type: SIO/2.\n"); -} - -void acia_init(void) { - kprintf("UART0 type: ACIA.\n"); -} - - diff --git a/Kernel/platform-rc2014/discard.c b/Kernel/platform-rc2014/discard.c index bbc6fcae..b953c2c7 100644 --- a/Kernel/platform-rc2014/discard.c +++ b/Kernel/platform-rc2014/discard.c @@ -49,12 +49,6 @@ void map_init(void) void device_init(void) { -#ifdef CONFIG_SIO - sio_init(); -#endif -#ifdef CONFIG_ACIA - acia_init(); -#endif #ifdef CONFIG_PPIDE ppide_init(); devide_init(); diff --git a/Kernel/platform-rc2014/fuzix.lnk b/Kernel/platform-rc2014/fuzix.lnk index 890d55c4..8137f34a 100644 --- a/Kernel/platform-rc2014/fuzix.lnk +++ b/Kernel/platform-rc2014/fuzix.lnk @@ -39,12 +39,13 @@ swap.rel bank16k.rel tty.rel devsys.rel +devinput.rel usermem.rel usermem_std-z80.rel platform-rc2014/discard.rel platform-rc2014/devtty.rel -platform-rc2014/devtty_discard.rel platform-rc2014/mbr.rel platform-rc2014/blkdev.rel platform-rc2014/monitor.rel +platform-rc2014/devinput.rel -e diff --git a/Kernel/platform-rc2014/kernel.def b/Kernel/platform-rc2014/kernel.def index 2b2864eb..131c6762 100644 --- a/Kernel/platform-rc2014/kernel.def +++ b/Kernel/platform-rc2014/kernel.def @@ -1,4 +1,4 @@ -; UZI mnemonics for memory addresses etc +; FUZIX mnemonics for memory addresses etc U_DATA .equ 0xF000 ; (this is struct u_data from kernel.h) U_DATA__TOTALSIZE .equ 0x300 ; 256+256+256 bytes. @@ -10,21 +10,21 @@ Z80_MMU_HOOKS .equ 0 PROGBASE .equ 0x0000 PROGLOAD .equ 0x0100 -; Zeta SBC V2 mnemonics for I/O ports etc +; Mnemonics for I/O ports etc -CONSOLE_RATE .equ 38400 +CONSOLE_RATE .equ 115200 CPU_CLOCK_KHZ .equ 7372 -; VFD Debugging +; VFD Debugging (clashes with Joystick port) VFD_C .EQU 0 ; control register VFD_D .EQU 1 ; data register ; Z80 CTC ports CTC_CH0 .equ 0x90 ; CTC channel 0 and interrupt vector CTC_CH1 .equ 0x91 ; CTC channel 1 (periodic interrupts) -CTC_CH2 .equ 0x92 ; CTC channel 2 (UART interrupt) -CTC_CH3 .equ 0x93 ; CTC channel 3 (PPI interrupt) +CTC_CH2 .equ 0x92 ; CTC channel 2 +CTC_CH3 .equ 0x93 ; CTC channel 3 ; 37C65 FDC ports FDC_CCR .equ 0x48 ; Configuration Control Register (W/O) @@ -39,10 +39,3 @@ MPGSEL_1 .equ 0x79 ; Bank_1 page select register (W/O) MPGSEL_2 .equ 0x7A ; Bank_2 page select register (W/O) MPGSEL_3 .equ 0x7B ; Bank_3 page select register (W/O) MPGENA .equ 0x7C ; memory paging enable register, bit 0 (W/O) - -; Define which serial device to use -; NOTE: Make sure this agrees with CONFIG_SIO and CONFIG_ACIA -; in config.h -CONFIG_SIO .equ 1 -CONFIG_ACIA .equ 0 - diff --git a/Kernel/platform-rc2014/main.c b/Kernel/platform-rc2014/main.c index f8dcd70b..987203ad 100644 --- a/Kernel/platform-rc2014/main.c +++ b/Kernel/platform-rc2014/main.c @@ -2,24 +2,22 @@ #include #include #include -#include "config.h" -#ifdef CONFIG_FLOPPY #include -#endif +#include extern unsigned char irqvector; -struct blkbuf *bufpool_end = bufpool + NBUFS; /* minimal for boot -- expanded after we're done with _DISCARD */ +struct blkbuf *bufpool_end = bufpool + NBUFS; /* minimal for boot -- expanded after we're done with _DISCARD */ void platform_discard(void) { - while(bufpool_end < (struct blkbuf*)(KERNTOP - sizeof(struct blkbuf))){ - memset(bufpool_end, 0, sizeof(struct blkbuf)); + while (bufpool_end < (struct blkbuf *) (KERNTOP - sizeof(struct blkbuf))) { + memset(bufpool_end, 0, sizeof(struct blkbuf)); #if BF_FREE != 0 - bufpool_end->bf_busy = BF_FREE; /* redundant when BF_FREE == 0 */ + bufpool_end->bf_busy = BF_FREE; /* redundant when BF_FREE == 0 */ #endif - bufpool_end->bf_dev = NO_DEVICE; - bufpool_end++; - } + bufpool_end->bf_dev = NO_DEVICE; + bufpool_end++; + } } void platform_idle(void) @@ -28,41 +26,39 @@ void platform_idle(void) fake up appopriate timer events */ /* Let's go to sleep while we wait for something to interrupt us; * Makes the HALT LED go yellow, which amuses me greatly. */ - __asm - halt - __endasm; + __asm halt __endasm; } uint8_t platform_param(unsigned char *p) { - used(p); - return 0; + used(p); + return 0; } void platform_interrupt(void) { - switch(irqvector) { - case 1: -#ifdef CONFIG_PPP - tty_poll_ppp() -#endif + switch (irqvector) { + case 1: #ifdef CONFIG_FLOPPY - fd_tick(); + fd_tick(); #endif - timer_interrupt(); - return; - - case 4: -#ifdef CONFIG_SIO + poll_input(); + timer_interrupt(); + return; + case 4: + tty_pollirq_sio(); + return; + /* + * Means we are in IM1 because we have a non Z80 + * device present. + */ + case 0x38: + if (ser_type == 1) tty_pollirq_sio(); -#endif - return; - case 0x38: -#ifdef CONFIG_ACIA - tty_pollirq_acia(); -#endif - return; - default: - return; + if (ser_type == 2) + tty_pollirq_acia(); + return; + default: + return; } } diff --git a/Kernel/platform-rc2014/platform_ide.h b/Kernel/platform-rc2014/platform_ide.h index 95d67e15..8343e588 100644 --- a/Kernel/platform-rc2014/platform_ide.h +++ b/Kernel/platform-rc2014/platform_ide.h @@ -1,38 +1,6 @@ -#ifdef CONFIG_PPIDE -#define PPIDE_BASE 0x60 /* Base address of 8255A */ -#define IDE_REG_INDIRECT /* IDE registers are not directly connected to the CPU bus */ - -/* IDE control signal to 8255 port C mapping */ -#define PPIDE_A0_LINE 0x01 // Direct from 8255 to IDE interface -#define PPIDE_A1_LINE 0x02 // Direct from 8255 to IDE interface -#define PPIDE_A2_LINE 0x04 // Direct from 8255 to IDE interface -#define PPIDE_CS0_LINE 0x08 // Inverter between 8255 and IDE interface -#define PPIDE_CS1_LINE 0x10 // Inverter between 8255 and IDE interface -#define PPIDE_WR_LINE 0x20 // Inverter between 8255 and IDE interface -#define PPIDE_WR_BIT 5 // (1 << PPIDE_WR_BIT) = PPIDE_WR_LINE -#define PPIDE_RD_LINE 0x40 // Inverter between 8255 and IDE interface -#define PPIDE_RD_BIT 6 // (1 << PPIDE_RD_BIT) = PPIDE_RD_LINE -#define PPIDE_RST_LINE 0x80 // Inverter between 8255 and IDE interface - -/* 8255 configuration */ -#define PPIDE_PPI_BUS_READ 0x92 -#define PPIDE_PPI_BUS_WRITE 0x80 - -/* IDE register addresses */ -#define ide_reg_data (PPIDE_CS0_LINE) -#define ide_reg_error (PPIDE_CS0_LINE | PPIDE_A0_LINE) -#define ide_reg_features (PPIDE_CS0_LINE | PPIDE_A0_LINE) -#define ide_reg_sec_count (PPIDE_CS0_LINE | PPIDE_A1_LINE) -#define ide_reg_lba_0 (PPIDE_CS0_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE) -#define ide_reg_lba_1 (PPIDE_CS0_LINE | PPIDE_A2_LINE) -#define ide_reg_lba_2 (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A0_LINE) -#define ide_reg_lba_3 (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE) -#define ide_reg_devhead (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE) -#define ide_reg_command (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE) -#define ide_reg_status (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE) -#define ide_reg_altstatus (PPIDE_CS1_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE) -#define ide_reg_control (PPIDE_CS1_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE) -#endif /* CONFIG_PPIDE */ - #define ide_select(x) #define ide_deselect() + +/*8bit, no altstatus/control */ +#define IDE_8BIT_ONLY +#define IDE_REG_CS1_BASE 0x10 diff --git a/Kernel/platform-rc2014/rc2014.h b/Kernel/platform-rc2014/rc2014.h index 1cb65e6d..b7429886 100644 --- a/Kernel/platform-rc2014/rc2014.h +++ b/Kernel/platform-rc2014/rc2014.h @@ -5,15 +5,22 @@ #define SIO0_IVT 8 +#ifdef CONFIG_SIO_BAKER #define SIO0_BASE 0x80 -__sfr __at (SIO0_BASE + 0) SIOA_D; __sfr __at (SIO0_BASE + 2) SIOA_C; -__sfr __at (SIO0_BASE + 1) SIOB_D; +__sfr __at (SIO0_BASE + 0) SIOA_D; __sfr __at (SIO0_BASE + 3) SIOB_C; +__sfr __at (SIO0_BASE + 1) SIOB_D; +#else +/* Standard RC2014 */ +#define SIO0_BASE 0x80 +__sfr __at (SIO0_BASE + 0) SIOA_C; +__sfr __at (SIO0_BASE + 1) SIOA_D; +__sfr __at (SIO0_BASE + 2) SIOB_C; +__sfr __at (SIO0_BASE + 3) SIOB_D; +#endif -/* ACIA is at same address as SIO. Assume CONFIG_ACIA or CONFIG_SIO has been - defined in config.h, but not both. -*/ +/* ACIA is at same address as SIO but we autodetect */ #define ACIA_BASE 0x80 __sfr __at (ACIA_BASE + 0) ACIA_C; diff --git a/Kernel/platform-rc2014/rc2014.s b/Kernel/platform-rc2014/rc2014.s index 0cdbfe15..295e754e 100644 --- a/Kernel/platform-rc2014/rc2014.s +++ b/Kernel/platform-rc2014/rc2014.s @@ -29,6 +29,7 @@ .globl nmi_handler .globl null_handler .globl _boot_from_rom + .globl _ser_type ; exported debugging tools .globl inchar @@ -47,10 +48,12 @@ CONSOLE_DIVISOR_LOW .equ (CONSOLE_DIVISOR & 0xFF) RTS_HIGH .EQU 0xE8 RTS_LOW .EQU 0xEA -SIOA_D .EQU 0x80 ; Base address of SIO/2 chip -SIOA_C .EQU SIOA_D+2 -SIOB_D .EQU SIOA_D+1 -SIOB_C .EQU SIOA_D+3 +; Base address of SIO/2 chip 0x80 +; For the Scott Baker SIO card adjust the order to match rc2014.h +SIOA_C .EQU 0x80 +SIOA_D .EQU SIOA_D+1 +SIOB_C .EQU SIOA_D+2 +SIOB_D .EQU SIOA_D+3 SIO_IV .EQU 8 ; Interrupt vector table entry to use @@ -73,6 +76,43 @@ _bufpool: ;========================================================================= .area _DISCARD init_hardware: + ; Play guess the serial port + ld bc,#0x80 + ; If writing to 0x80 changes the data we see on an input then + ; it's most likely an SIO and not the 68B50 + out (c),b + in d,(c) + inc b + out (c),b + in a,(c) + sub e + jr z, is_sio + ; We have however pooped on the 68B50 setup so put it back into + ; a sensible state. + ld a,#0x03 + out (c),a + in a,(c) + or a + jr nz, not_acia_either + ld a, #ACIA_RTS_LOW_A + out (c),a ; Initialise ACIA + ld a,#2 + ld (_ser_type),a + jp serial_up + + ; + ; Doomed I say .... doomed, we're all doomed + ; + ; At least until RC2014 grows a nice keyboard/display card! + ; +not_acia_either: + xor a + ld (_ser_type),a + jp serial_up + +is_sio: ld a,b + ld (_ser_type),a + ; program vectors for the kernel ld hl, #0 push hl @@ -90,61 +130,60 @@ init_hardware: ; nothing to do here yet init_partial_uart: -.if CONFIG_SIO - LD A,#0x00 - OUT (SIOA_C),A - LD A,#0x18 - OUT (SIOA_C),A - - LD A,#0x04 - OUT (SIOA_C),A - LD A,#0xC4 - OUT (SIOA_C),A - - LD A,#0x01 - OUT (SIOA_C),A - LD A,#0x1A ; Receive int mode 11, tx int enable (was $18) - OUT (SIOA_C),A - - LD A,#0x03 - OUT (SIOA_C),A - LD A,#0xE1 - OUT (SIOA_C),A - - LD A,#0x05 - OUT (SIOA_C),A - LD A,#RTS_LOW - OUT (SIOA_C),A - - LD A,#0x00 - OUT (SIOB_C),A - LD A,#0x18 - OUT (SIOB_C),A - - LD A,#0x04 - OUT (SIOB_C),A - LD A,#0xC4 - OUT (SIOB_C),A - - LD A,#0x01 - OUT (SIOB_C),A - LD A, #0x1A ; Receive int mode 11, tx int enable (was $18) - OUT (SIOB_C),A - - LD A,#0x02 - OUT (SIOB_C),A - LD A,#SIO_IV ; INTERRUPT VECTOR ADDRESS - OUT (SIOB_C),A - - LD A,#0x03 - OUT (SIOB_C),A - LD A,#0xE1 - OUT (SIOB_C),A - - LD A,#0x05 - OUT (SIOB_C),A - LD A,#RTS_LOW - OUT (SIOB_C),A + ld a,#0x00 + out (SIOA_C),a + ld a,#0x18 + out (SIOA_C),a + + ld a,#0x04 + out (SIOA_C),a + ld a,#0xC4 + out (SIOA_C),a + + ld a,#0x01 + out (SIOA_C),a + ld a,#0x1A ; Receive int mode 11, tx int enable (was $18) + out (SIOA_C),a + + ld a,#0x03 + out (SIOA_C),a + ld a,#0xE1 + out (SIOA_C),a + + ld a,#0x05 + out (SIOA_C),a + ld a,#RTS_LOW + out (SIOA_C),a + + ld a,#0x00 + out (SIOB_C),a + ld a,#0x18 + out (SIOB_C),a + + ld a,#0x04 + out (SIOB_C),a + ld a,#0xC4 + out (SIOB_C),a + + ld a,#0x01 + out (SIOB_C),a + ld a, #0x1A ; Receive int mode 11, tx int enable (was $18) + out (SIOB_C),a + + ld a,#0x02 + out (SIOB_C),a + ld a,#SIO_IV ; INTERRUPT VECTOR ADDRESS + out (SIOB_C),a + + ld a,#0x03 + out (SIOB_C),a + ld a,#0xE1 + out (SIOB_C),a + + ld a,#0x05 + out (SIOB_C),a + ld a,#RTS_LOW + out (SIOB_C),a ; --------------------------------------------------------------------- ; Initialize CTC @@ -161,17 +200,6 @@ init_partial_uart: ld a,#180 ; time constant = 180 out (CTC_CH1),a ; set CH1 time constant -; ld a,#0xD7 ; counter mode, rising edge -; ; enable interrupts -; out (CTC_CH2),a ; set CH2 mode -; ld a,#1 ; time constant = 1 -; out (CTC_CH2),a ; set CH2 time constant -; ; FIXME: should use interrupts when PPP firmware allows it -; ld a,#0x37 ; timer mode for now, disable interrupts -; out (CTC_CH3),a -; ld a,#0 ; time constant = 256 -; out (CTC_CH3),a ; set CH3 time constant - ld hl,#intvectors ld a,l and #0xF8 ; get bits 7-3 of int. vectors table @@ -184,17 +212,7 @@ init_partial_uart: ld a,h ; get bits 15-8 of int. vectors table ld i,a ; load to I register im 2 ; set Z80 CPU interrupt mode 2 -.endif - -.if CONFIG_ACIA - LD A, #ACIA_RESET - OUT (ACIA_C),A - LD A, #ACIA_RTS_LOW_A - OUT (ACIA_C),A ; Initialise ACIA - - im 1 -.endif - +serial_up: jp _init_hardware_c ; pass control to C, which returns for us ;========================================================================= @@ -280,8 +298,8 @@ sio_int: ; For ACIA, serial interrupt handler will execute int38h_int: push af - LD A, #'B' - OUT (VFD_D),A + ld a, #'B' + out (VFD_D),a ld a,#0x38 ; not a real vector, just a signal that the 0x38h occurred ld (_irqvector),a ; store it pop af @@ -443,8 +461,11 @@ map_savearea: ;========================================================================= outchar: -.if CONFIG_SIO push af + ld a,(_ser_type) + cp #2 + jr z, ocloop_acia + ; wait for transmitter to be idle ocloop_sio: xor a ; read register 0 @@ -455,10 +476,8 @@ ocloop_sio: ; now output the char to serial port pop af out (SIOA_D),a -.endif + jr out_done -.if CONFIG_ACIA - push af ; wait for transmitter to be idle ocloop_acia: in a,(ACIA_C) ; read Line Status Register @@ -467,8 +486,7 @@ ocloop_acia: ; now output the char to serial port pop af out (ACIA_D),a -.endif - +out_done: out (VFD_D),a ret @@ -478,19 +496,20 @@ ocloop_acia: ; Outputs: A - received character, F destroyed ;========================================================================= inchar: -.if CONFIG_SIO + ld a,(_ser_type) + cp #2 + jr z,inchar_acia +inchar_s: xor a ; read register 0 out (SIOA_C), a in a,(SIOA_C) ; read Line Status Register and #0x01 ; test if data is in receive buffer - jp z,inchar ; no data, wait + jr z,inchar_s ; no data, wait in a,(SIOA_D) ; read the character from the UART -.endif - -.if CONFIG_ACIA + ret +inchar_acia: in a,(ACIA_C) ; read Line Status Register and #0x01 ; test if data is in receive buffer - jp z,inchar ; no data, wait + jr z,inchar_acia ; no data, wait in a,(ACIA_D) ; read the character from the UART -.endif ret -- 2.34.1