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
../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
---- README for RC2014 ---
This is Fuzix for the RC2014
Imported into the current tree from Scott Baker's git tree and adjusted to
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
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
/* 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 */
#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 */
/* 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 */
#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
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;
}
{
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;
}
/* 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');
}
#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
+++ /dev/null
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <stdbool.h>
-#include <tty.h>
-#include <devtty.h>
-#include <rc2014.h>
-
-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");
-}
-
-
void device_init(void)
{
-#ifdef CONFIG_SIO
- sio_init();
-#endif
-#ifdef CONFIG_ACIA
- acia_init();
-#endif
#ifdef CONFIG_PPIDE
ppide_init();
devide_init();
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
-; 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.
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)
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
-
#include <kdata.h>
#include <printf.h>
#include <devtty.h>
-#include "config.h"
-#ifdef CONFIG_FLOPPY
#include <devfd.h>
-#endif
+#include <devinput.h>
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)
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;
}
}
-#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
#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;
.globl nmi_handler
.globl null_handler
.globl _boot_from_rom
+ .globl _ser_type
; exported debugging tools
.globl inchar
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
;=========================================================================
.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
; 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
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
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\r
- LD A, #ACIA_RTS_LOW_A\r
- OUT (ACIA_C),A ; Initialise ACIA
-
- im 1
-.endif
-
+serial_up:
jp _init_hardware_c ; pass control to C, which returns for us
;=========================================================================
; 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
;=========================================================================
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
; 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
; now output the char to serial port
pop af
out (ACIA_D),a
-.endif
-
+out_done:
out (VFD_D),a
ret
; 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