rabbit: initial work on the JackRabbit (BL18x0) boards
authorAlan Cox <alan@linux.intel.com>
Thu, 7 Feb 2019 23:39:59 +0000 (23:39 +0000)
committerAlan Cox <alan@linux.intel.com>
Thu, 7 Feb 2019 23:39:59 +0000 (23:39 +0000)
Not yet anything fully build and bootable

16 files changed:
Kernel/platform-rabbit2000/Makefile [new file with mode: 0644]
Kernel/platform-rabbit2000/README [new file with mode: 0644]
Kernel/platform-rabbit2000/commonmem.s [new file with mode: 0644]
Kernel/platform-rabbit2000/config.h [new file with mode: 0644]
Kernel/platform-rabbit2000/crt0.s [new file with mode: 0644]
Kernel/platform-rabbit2000/devices.c [new file with mode: 0644]
Kernel/platform-rabbit2000/devtty.c [new file with mode: 0644]
Kernel/platform-rabbit2000/devtty.h [new file with mode: 0644]
Kernel/platform-rabbit2000/fuzix.lnk [new file with mode: 0644]
Kernel/platform-rabbit2000/interrupt.s [new file with mode: 0644]
Kernel/platform-rabbit2000/kernel.def [new file with mode: 0644]
Kernel/platform-rabbit2000/main.c [new file with mode: 0644]
Kernel/platform-rabbit2000/rabbit.h [new file with mode: 0644]
Kernel/platform-rabbit2000/rabbit.s [new file with mode: 0644]
Kernel/platform-rabbit2000/target.mk [new file with mode: 0644]
Kernel/platform-rabbit2000/tricks.s [new file with mode: 0644]

diff --git a/Kernel/platform-rabbit2000/Makefile b/Kernel/platform-rabbit2000/Makefile
new file mode 100644 (file)
index 0000000..fc94afb
--- /dev/null
@@ -0,0 +1,47 @@
+ASRCS = crt0.s tricks.s commonmem.s rabbit.s
+CSRCS = devices.c main.c devtty.c
+DISCARD_CSRCS =
+DISCARD_DSRCS = ../dev/devsd_discard.c
+DSRCS = ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c
+
+AOBJS = $(ASRCS:.s=.rel)
+COBJS = $(CSRCS:.c=.rel)
+DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel)
+DISCARD_DOBJS = $(patsubst ../dev/%.c,%.rel, $(DISCARD_DSRCS))
+DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS))
+DAOBJS = $(patsubst ../dev/%.s,%.rel, $(DASRCS))
+
+OBJS  = $(AOBJS) $(COBJS) $(DOBJS) $(DAOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS)
+
+CROSS_CCOPTS += -I../dev/
+
+JUNK = *.rel *.lst *.asm *.sym *.rst *.map *.ihx *.bin
+
+all:   $(OBJS)
+
+$(AOBJS): %.rel: %.s
+       $(CROSS_AS) $(ASOPTS) $<
+
+$(COBJS): %.rel: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) --codeseg COMMONMEM -c $<
+
+$(DOBJS): %.rel: ../dev/%.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+$(DAOBJS): %.rel: ../dev/%.s
+       $(CROSS_AS) $(ASOPTS) $@ $<
+
+$(DISCARD_COBJS): %.rel: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<
+
+$(DISCARD_DOBJS): %.rel: ../dev/%.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<
+
+clean:
+       rm -f $(OBJS) $(JUNK)  core *~ fuzix.com
+
+#
+#      Compile up the boot block
+#
+image:
+
diff --git a/Kernel/platform-rabbit2000/README b/Kernel/platform-rabbit2000/README
new file mode 100644 (file)
index 0000000..0fbfd63
--- /dev/null
@@ -0,0 +1,115 @@
+First sketches for the Rabbit 2000
+
+Hardware  BL18x0 'Jackrabbit' boards
+
+       Rabbit 2000 @29.5 or 14.74MHz
+       128K or 256K flash (256K on the 1800 only)
+       128K SRAM (factory option for 512K)
+
+       Serial A: control cable
+       Serial B: (we use for SPI instead) RS232
+       Serial C: RS232
+       Serial D: RS485
+
+       RTC and SRAM have battery backup
+
+PA0-PA7                Parallel I/O (Free unless doing slave stuff)
+PB0/PB1                Serial clock  (CLKA is connected to programming port)
+               CLKB is needed for SPI
+PB2-7          Free if not using slave
+PC0-PC7                Serial port outputs
+               0-1     D to RS485
+               2-5     B and C to RS232
+               6-7     A to programming port
+PD0-PD7
+               1-2     Control DA0
+               4       Control D1 (alt port B TX)
+               5       RS485 data enable (alt port B RX)
+               6-7     (Alt port A)
+PE0-PE7
+               0       HV0 output control
+               1       HV1 output control
+               2       HV2 output control
+               3       HV3 output control
+               4-5     (INT0B/INT1B)
+               6       A/D comparator output
+               7       A/D comparator output
+
+
+
+
+
+The memory map of the R2K is fairly similar to the Z180 but not quite
+
+0000   Base segment
+x000   Data segment
+y000   Stack segment
+E000   XPC
+
+The stack and data segment boundaries can be adjusted and the root segment
+can even be vanished entirely as can stack or data. The E000-FFFF window
+is however fixed and controlled by its own register (XPC)
+
+For simplicity try and get running with E000-FFFF as common. There are better
+layouts but they are more complex.
+
+There are two further complications however
+
+1. The 20bit physical address gets fed into a memory interface unit which
+in theory just sets the wait states and chip selects. However once you get
+more than 1MB it starts getting used for other games as you can route all the
+address lines to each RAM and use the chip selects as a kind of A20/A21
+address line and do further banking this way from software. For now we will
+ignore this as it's usually on Rabbbit 3000 stuff that hits this.
+
+2. All but the early Rabbit 2000 chips support split I/D. In split I/D mode
+the physical address can have either bit 16 or bit 19 inverted when accessing
+data. bit 16 effectively requires a 128K chunk of memory suitably aligned. Bit
+19 is intended for code from flash and data from RAM so is not of interest.
+
+
+Rabbit 2000 CPU bugs/differences
+
+2000           No split ID, no 9bit serial helper
+               Must nop after some I/O operations
+               Cannot start tx/rx together for SPI
+               Wait state bugs (notably in LDxR)
+
+2000A          Split I/D supported, 9bit serial added
+               Most instruction bugs fixed
+               Can start tx/rx together for SPI
+               LDIR broken differently (do not use with split I/D)
+
+2000B          Rare special run. Differently buggy LDIR
+
+2000C          Later edition. Adds early I/O enable
+               Fixes LDIR split I/D and breaks it differently
+
+In general then
+- nop after I/O operations using ioo foo (HL) - all the logic ops and LD
+- don't use LDxR
+
+
+
+Badly Documented Stuff
+
+GCSR register
+
+(0x10->0x9 is done going from 32Khz to main clock)
+Write 0x10 to turn on the main oscillator   00010000
+Write 0x09 to switch the CPU onto it       00001001    
+Write 0x05 to switch on /8 clock divider    00000101
+Write 0x14 to switch to 32Khz osc and disable 2Khz tick
+                                           00011000
+
+So my guess is
+
+bit 0 - set enabbles the tick
+bit 4 - set enables the CPU to run on 32Khz
+bit 3-2 control the clock
+
+
+Serial oddity
+
+- to send a break switch the tty port off (disconnect from the port C/D) and
+use the I/O bit interface to set/lower the bit!
diff --git a/Kernel/platform-rabbit2000/commonmem.s b/Kernel/platform-rabbit2000/commonmem.s
new file mode 100644 (file)
index 0000000..309b8b6
--- /dev/null
@@ -0,0 +1,9 @@
+;
+;      Common on z80pack is at 0xF000 as defined by hardware.
+;
+
+        .module commonmem
+
+        .area _COMMONMEM
+
+       .include "../cpu-r2k/std-commonmem.s"
diff --git a/Kernel/platform-rabbit2000/config.h b/Kernel/platform-rabbit2000/config.h
new file mode 100644 (file)
index 0000000..65a9cc4
--- /dev/null
@@ -0,0 +1,60 @@
+/* We have an RTC */
+#undef CONFIG_RTC
+/* And we can read ToD from it */
+#undef CONFIG_RTC_FULL
+/* Enable to make ^Z dump the inode table for debug */
+#undef CONFIG_IDUMP
+/* Enable to make ^A drop back into the monitor */
+#undef CONFIG_MONITOR
+/* Profil syscall support (not yet complete) */
+#undef CONFIG_PROFIL
+/* Multiple processes in memory at once */
+#define CONFIG_MULTI
+/* Single tasking */
+#undef CONFIG_SINGLETASK
+/* Fixed banking */
+#define CONFIG_BANK_FIXED
+/* 2 32K banks, + 64K is kernel */
+/* When we run from flash we'll fix this to 2 x 64K */
+#define MAX_MAPS       2
+#define MAP_SIZE       0x8000U
+
+#define CONFIG_SD
+#define SD_DRIVE_COUNT 1
+#define MAX_BLKDEV     1
+
+/* Read processes and big I/O direct into process space */
+#define CONFIG_LARGE_IO_DIRECT(x)      1
+
+/* Banks as reported to user space */
+#define CONFIG_BANKS   1
+
+#define TICKSPERSEC 200   /* Ticks per second */
+#define PROGBASE    0x0000  /* also data base */
+#define PROGLOAD    0x0100  /* also data base */
+#define PROGTOP     0x7E00  /* Top of program, base of U_DATA copy */
+#define PROC_SIZE   40   /* Memory needed per process */
+
+#define SWAP_SIZE   0x40       /* 48K in blocks (we actually don't need the low 256) */
+#define SWAPBASE    0x0000     /* We swap the lot in one, include the */
+#define SWAPTOP            0x8000      /* vectors so its a round number of sectors */
+#define MAX_SWAPS   16         /* The full drive would actually be 85! */
+
+#define swap_map(x)    ((uint8_t *)(x)) /* Simple zero based mapping */
+
+#define BOOT_TTY (512 + 1)/* Set this to default device for stdio, stderr */
+                          /* In this case, the default is the first TTY device */
+
+/* We need a tidier way to do this from the loader */
+#define CMDLINE        NULL      /* Location of root dev name */
+
+/* Device parameters */
+#define NUM_DEV_TTY 3
+
+#define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
+#define SWAPDEV  (256 + 1)  /* Device for swapping. (FIXME) */
+#define NBUFS    8       /* Number of block buffers */
+#define NMOUNTS         4        /* Number of mounts at a time */
+
+#define platform_discard()
+#define platform_copyright()
diff --git a/Kernel/platform-rabbit2000/crt0.s b/Kernel/platform-rabbit2000/crt0.s
new file mode 100644 (file)
index 0000000..a40a691
--- /dev/null
@@ -0,0 +1,107 @@
+        .module crt0
+
+       ; Segment order
+       ; Note: the code segments may be in flash
+        .area _CODE
+        .area _CODE2
+        .area _CONST
+        .area _INITIALIZED
+        .area _DATA
+        .area _BSEG
+        .area _BSS
+        .area _HEAP
+        ; note that areas below here may be overwritten by the heap at runtime, so
+        ; put initialisation stuff in here
+        .area _INITIALIZER
+        .area _GSINIT
+        .area _GSFINAL
+       .area _DISCARD
+        .area _COMMONMEM
+
+        ; imported symbols
+        .globl _fuzix_main
+        .globl init_early
+        .globl init_hardware
+        .globl s__INITIALIZER
+        .globl s__COMMONMEM
+        .globl l__COMMONMEM
+        .globl s__DISCARD
+        .globl l__DISCARD
+        .globl s__DATA
+        .globl l__DATA
+        .globl kstack_top
+       .globl _kdataseg
+
+        ; startup code
+        .area _CODE
+
+       .include "kernel.def"
+       .include "../kernel-rabbit.def"
+;
+;      For a RAM startup our configuration is
+;
+;      Interrupts off
+;      Stack undefined
+;
+;      DATASEG set from 0-DFFF
+;      XPC segment undefined but will be somewhere in the bootstrap
+;      as it will jump to 0
+;
+;      Physically mapped so that the kernel starts at ram address 0x0000
+;
+;      Serial console is configured, wait states and cs are set up validly
+;
+init:
+        ld sp, #kstack_top
+
+       ; Learn our banks
+
+       ; Will need extending when we start to run from flash
+       ioi
+       ld a,(DATASEG)
+       ld (_kdataseg),a
+       add a,#14               ; 56K on (our E000)
+       ld xpc,a                ; We now have 64K linear physical
+                               ; space         
+       ; For now we don't move XPC, that will change eventually
+
+       ;
+       ; our stack pointer is now valid (we can't do the above in
+       ; init_early as we have no sane stack)
+       ;
+
+        ; Configure memory map
+        call init_early
+
+       ; move the common memory where it belongs (our XPC is now valid) 
+       ld hl, #s__DATA
+       ld de, #s__COMMONMEM
+       ld bc, #l__COMMONMEM
+       call doldir
+       ; and the discard
+       ld de, #s__DISCARD
+       ld bc, #l__DISCARD
+       call doldir
+       ; then zero the data area
+       ld hl, #s__DATA
+       ld de, #s__DATA + 1
+       ld bc, #l__DATA - 1
+       ld (hl), #0
+       call doldir
+
+        ; Hardware setup
+        call init_hardware
+
+        ; Call the C main routine
+        call _fuzix_main
+    
+        ; main shouldn't return, but if it does...
+stop:   jr stop
+
+doldir:
+       ; the ldir instruction is broken in Rabbit 2000 series CPU
+       ; in differing ways depending upon the chip version. So just
+       ; skip using it.
+       ldi
+       jp lo,doldir
+       ret
diff --git a/Kernel/platform-rabbit2000/devices.c b/Kernel/platform-rabbit2000/devices.c
new file mode 100644 (file)
index 0000000..707b664
--- /dev/null
@@ -0,0 +1,40 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <tty.h>
+#include <devsys.h>
+#include <devtty.h>
+#include <blkdev.h>
+#include <devsd.h>
+
+struct devsw dev_tab[] =  /* The device driver switch table */
+{
+  /* 0: /dev/hd                Hard disc block devices */
+  {  blkdev_open,  no_close,     blkdev_read,   blkdev_write,  blkdev_ioctl },
+  /* 1: /dev/fd        Floppy disc block devices: nope */
+  {  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 },
+  /* 3: /dev/lpr       Printer devices */
+  {  no_open,      no_close,     no_rdwr,       no_rdwr,       no_ioctl  },
+  /* 4: /dev/mem etc   System devices (one offs) */
+  {  no_open,      no_close,     sys_read,      sys_write,     sys_ioctl  },
+  /* 5: Pack to 7 with nxio if adding private devices and start at 8 */
+};
+
+bool validdev(uint16_t dev)
+{
+    /* This is a bit uglier than needed but the right hand side is
+       a constant this way */
+    if(dev > ((sizeof(dev_tab)/sizeof(struct devsw)) << 8) - 1)
+       return false;
+    else
+        return true;
+}
+
+void device_init(void)
+{
+#ifdef CONFIG_SD
+  devsd_init();
+#endif
+}
diff --git a/Kernel/platform-rabbit2000/devtty.c b/Kernel/platform-rabbit2000/devtty.c
new file mode 100644 (file)
index 0000000..d223518
--- /dev/null
@@ -0,0 +1,97 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <tty.h>
+#include <devtty.h>
+
+#include "rabbit.h"
+
+static char tbuf1[TTYSIZ];
+static char tbuf2[TTYSIZ];
+static char tbuf3[TTYSIZ];
+
+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 },
+};
+
+static tcflag_t console_mask[4] = {
+       _ISYS,
+       _OSYS,
+       _CSYS,
+       _LSYS
+};
+
+/* Port B is owned by our SPI code */
+static uint8_t serial_map[4] = { 0, SADR-SADR, SCDR-SADR, SDDR-SADR };
+
+/* TODO: stty support for  the r2k ports */
+tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
+       NULL,
+       console_mask,
+       console_mask,
+};
+
+void tty_setup(uint8_t minor, uint8_t flags)
+{
+    minor;
+}
+
+/* For the moment */
+int tty_carrier(uint8_t minor)
+{
+    minor;
+    return 1;
+}
+
+/*
+ *     Drain the interrupt queue
+ */
+void tty_pollirq(void)
+{
+    uint16_t c;
+    while((c = sera_get()) != 0xFF)
+            tty_inproc(1, c);
+    while((c = serc_get()) != 0xFF)
+            tty_inproc(2, c);
+    while((c = serd_get()) != 0xFF)
+            tty_inproc(3, c);
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+    out(SADR + serial_map[minor], c);
+}
+
+void tty_sleeping(uint8_t minor)
+{
+    minor;
+}
+
+void tty_data_consumed(uint8_t minor)
+{
+}
+
+ttyready_t tty_writeready(uint8_t minor)
+{
+    uint8_t r = in(SASR + serial_map[minor]);
+    /* FIXME: should go IRQ driven */
+    if (r & 4)
+        return TTY_READY_SOON;
+    else
+        return TTY_READY_NOW;
+}
+
+/* kernel writes to system console -- never sleep! */
+void kputchar(char c)
+{
+    while(tty_writeready(TTYDEV) != TTY_READY_NOW);
+    tty_putc(TTYDEV & 0xFF, c);
+    if(c == '\n') {
+        while(tty_writeready(TTYDEV) != TTY_READY_NOW);
+        tty_putc(TTYDEV & 0xFF, '\r');
+    }
+}
diff --git a/Kernel/platform-rabbit2000/devtty.h b/Kernel/platform-rabbit2000/devtty.h
new file mode 100644 (file)
index 0000000..64a8d3d
--- /dev/null
@@ -0,0 +1,10 @@
+extern void tty_pollirq(void);
+
+extern uint16_t sera_get(void);
+extern void sera_setup(uint8_t set) __z88dk_fastcall;
+
+extern uint16_t serc_get(void);
+extern void serc_setup(uint8_t set) __z88dk_fastcall;
+
+extern uint16_t serd_get(void);
+extern void serd_setup(uint8_t set) __z88dk_fastcall;
diff --git a/Kernel/platform-rabbit2000/fuzix.lnk b/Kernel/platform-rabbit2000/fuzix.lnk
new file mode 100644 (file)
index 0000000..96b7913
--- /dev/null
@@ -0,0 +1,40 @@
+-mwxuy
+-i fuzix.ihx
+-l r2k
+-b _CODE=0x0100
+-b _COMMONMEM=0xF000
+-b _DISCARD=0xD800
+platform-rabbit2000/crt0.rel
+platform-rabbit2000/commonmem.rel
+platform-rabbit2000/rabbit.rel
+platform-rabbit2000/main.rel
+start.rel
+version.rel
+lowlevel-r2k.rel
+usermem_std-r2k.rel
+platform-rabbit2000/tricks.rel
+timer.rel
+kdata.rel
+usermem.rel
+platform-rabbit2000/devices.rel
+devio.rel
+filesys.rel
+process.rel
+inode.rel
+syscall_exec16.rel
+syscall_fs.rel
+syscall_fs2.rel
+syscall_fs3.rel
+syscall_proc.rel
+syscall_other.rel
+tty.rel
+mm.rel
+bankfixed.rel
+swap.rel
+devsys.rel
+platform-rabbit2000/devtty.rel
+platform-rabbit2000/devsd.rel
+platform-rabbit2000/devsd_discard.rel
+platform-rabbit2000/mbr.rel
+platform-rabbit2000/blkdev.rel
+-e
diff --git a/Kernel/platform-rabbit2000/interrupt.s b/Kernel/platform-rabbit2000/interrupt.s
new file mode 100644 (file)
index 0000000..a518805
--- /dev/null
@@ -0,0 +1,120 @@
+;
+;      The interrupt page. We fold IIR and EIR together
+;
+;      For interrupts we should never get we do the required
+;      irq clearing reads.
+;
+               .module iir
+
+               .area _IIR
+
+               .globl unix_syscall_entry
+               .globl ticktock
+
+periodic:
+eir0:                          ; If we use both we'll need to do some
+                               ; thinking and maybe split this
+       jp ticktock
+
+       .bndry 16
+eir1:
+       ipres
+       ret
+
+       .bndry 16
+
+rst10:
+       ret
+
+       .bndry 16
+
+rst18:
+       ret
+
+       .bndry 16
+
+rst20:
+       ret
+
+       .bndry 16
+
+rst28:
+       jp unix_syscall_entry
+
+       .bndry 16
+
+spare:
+       ret
+       .bindry 16
+
+rst38:
+       ret
+
+       .bndry 16
+
+slave:
+       ipres
+       ret
+
+       .bndry 16
+
+spare2:
+       ret
+
+       .bndry 16
+
+timera:
+       push af
+       ioi ld a,(TACSR)
+       pop af
+       ipres
+       ret
+
+       .bndry 16
+
+timerb:
+       push af
+       ioi ld a,(TBCSR)
+       pop af
+       ipres
+       ret
+
+       .bndry 16
+
+seriala:
+       push af
+       ioi ld a,(SASR)
+       or a
+       jp m,sera_rx
+       jp sera_tx
+
+       .bndry 16
+
+;
+;      B is our SPI
+;
+serialb:
+       ipres
+       ret
+
+       .bndry 16
+
+serialc:
+       push af
+       ioi ld a,(SCSR)
+       or a
+       jp m,serc_rx
+       jp serc_tx
+
+
+       .bndry 16
+
+seriald:
+       push af
+       ioi ld a,(SDSR)
+       or a
+       jp m,serd_rx
+       jp serd_tx
+
+
+       .bndry 16
diff --git a/Kernel/platform-rabbit2000/kernel.def b/Kernel/platform-rabbit2000/kernel.def
new file mode 100644 (file)
index 0000000..718bf95
--- /dev/null
@@ -0,0 +1,11 @@
+; UZI mnemonics for memory addresses etc
+
+U_DATA                      .equ 0xE000       ; (this is struct u_data from kernel.h)
+U_DATA__TOTALSIZE           .equ 0x200        ; 256+256 bytes.
+
+U_DATA_STASH               .equ 0xBE00       ; BE00-BFFF
+
+PROGBASE                   .equ 0x0000
+PROGLOAD                   .equ 0x0100
+
+CONFIG_SWAP                .equ 1
diff --git a/Kernel/platform-rabbit2000/main.c b/Kernel/platform-rabbit2000/main.c
new file mode 100644 (file)
index 0000000..f727031
--- /dev/null
@@ -0,0 +1,43 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+#include <rabbit.h>
+
+uaddr_t ramtop = PROGTOP;
+
+void pagemap_init(void)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+  pagemap_add(kdataseg + 16 + i << 3); /* In 32K chunks to get us going */
+}
+
+/* On idle we spin checking for the terminals. Gives us more responsiveness
+   for the polled ports */
+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(); 
+  irqrestore(irq);
+}
+
+void platform_interrupt(void)
+{
+ tty_pollirq();
+ timer_interrupt();
+}
+
+/* Nothing to do for the map of init */
+void map_init(void)
+{
+}
+
+uint8_t platform_param(char *p)
+{
+ used(p);
+ return 0;
+}
+
diff --git a/Kernel/platform-rabbit2000/rabbit.h b/Kernel/platform-rabbit2000/rabbit.h
new file mode 100644 (file)
index 0000000..fcfd700
--- /dev/null
@@ -0,0 +1,119 @@
+extern uint8_t kdataseg;
+
+extern void rabbit_spi_tx(uint8_t c) __z88dk_fastcall;
+extern uint8_t rabbit_spi_rx(void);
+extern void rabbit_spi_slow(void);
+extern void rabbit_spi_fast(void);
+extern void rabbit_read_rtc(uint8_t *ptr) __z88dk_fastcall;
+extern void rabbit_bop_watchdog(uint8_t code) __z88dk_fastcall;
+
+#define GCSR           0x00
+#define RTCCR          0x01
+#define RTC0R          0x02
+#define RTC1R          0x03
+#define RTC2R          0x04
+#define RTC3R          0x05
+#define RTC4R          0x06
+#define RTC5R          0x07
+#define WDTCR          0x08
+#define WDTTR          0x09
+#define GCM0R          0x0A
+#define GCM1R          0x0B
+#define GOCR           0x0E
+#define GCDR           0x0F
+#define MMIDR          0x10
+#define STACKSEG       0x11
+#define DATASEG                0x12
+#define SEGSIZE                0x13
+#define MB0CR          0x14
+#define MB1CR          0x15
+#define MB2CR          0x16
+#define MB3CR          0x17
+#define SPD0R          0x20
+#define SPD1R          0x21
+#define SPD2R          0x22
+#define SPSR           0x23
+#define SPCR           0x24
+#define GCPU           0x2E
+#define GREV           0x2F
+#define PADR           0x30
+#define PBDR           0x40
+#define PCDR           0x50
+#define PCFR           0x55
+#define PDDR           0x60
+#define PDCR           0x64
+#define PDFR           0x65
+#define PDDCR          0x66
+#define PDDDR          0x67
+#define PDB0R          0x68
+#define PDB1R          0x69
+#define PDB2R          0x6A
+#define PDB3R          0x6B
+#define PDB4R          0x6C
+#define PDB5R          0x6D
+#define PDB6R          0x6E
+#define PDB7R          0x6F
+#define PEDR           0x70
+#define PECR           0x74
+#define PEFR           0x75
+#define PEDDR          0x77
+#define PEB0R          0x78
+#define PEB1R          0x79
+#define PEB2R          0x7A
+#define PEB3R          0x7B
+#define PEB4R          0x7C
+#define PEB5R          0x7D
+#define PEB6R          0x7E
+#define PEB7R          0x7F
+#define IB0CR          0x80
+#define IB1CR          0x81
+#define IB2CR          0x82
+#define IB3CR          0x83
+#define IB4CR          0x84
+#define IB5CR          0x85
+#define IB6CR          0x86
+#define IB7CR          0x87
+#define I0CR           0x98
+#define I1CR           0x99
+#define TACSR          0xA0
+#define TACR           0xA2
+#define TAT1R          0xA3
+#define TAT4R          0xA9
+#define TAT5R          0xAB
+#define TAT6R          0xAD
+#define TAT7R          0xAF
+#define TBCSR          0xB0
+#define TBCR           0xB1
+#define TBM1R          0xB2
+#define TBL1R          0xB3
+#define TBM2R          0xB4
+#define TBL2R          0xB5
+#define TBCMR          0xBE
+#define TBCLR          0xBF
+#define SADR           0xC0
+#define SAAR           0xC1
+#define SALR           0xC2
+#define SASR           0xC3
+#define SACR           0xC4
+#define SBDR           0xD0
+#define SBAR           0xD1
+#define SBLR           0xD2
+#define SBSR           0xD3
+#define SBCR           0xD4
+#define SCDR           0xE0
+#define SCAR           0xE1
+#define SCLR           0xE2
+#define SCSR           0xE3
+#define SCCR           0xE4
+#define SDDR           0xF0
+#define SDAR           0xF1
+#define SDLR           0xF2
+#define SDSR           0xF3
+#define SDCR           0xF4
+
+#define GREV_R2000                     0x00
+#define GREV_R2000A                    0x01
+#define GREV_R2000B                    0x02
+#define GREV_R2000C                    0x03
+
+#define GCPU_R2000                     0x01
diff --git a/Kernel/platform-rabbit2000/rabbit.s b/Kernel/platform-rabbit2000/rabbit.s
new file mode 100644 (file)
index 0000000..779b767
--- /dev/null
@@ -0,0 +1,390 @@
+;
+;      Skeleton for Rabbit 2000
+;
+               .module rabbit
+
+               .area _COMMONMEM
+
+               .globl _platform_reboot
+               .globl _platform_monitor
+
+               .include 'kernel.def'
+               .include '../kernel-rabbit.def'
+
+_platform_reboot:
+_platform_monitor:
+               ; Force a hardware level reset using the watchdog
+               ld a,#0x53
+               ioi
+               ld (WDTCR),a
+               jr _platform_monitor
+
+               .globl platform_interrupt_all
+
+platform_interrupt_all:
+               ret
+
+               .area _COMMONDATA
+
+               .globl _int_disabled
+
+_int_disabled:
+               .db 1
+
+
+               .area _CODE
+
+               .globl init_early
+               .globl init_hardware
+
+               .globl _ramsize
+               .globl _procmem
+
+init_early:
+               ret
+
+init_hardware:
+               ; FIXME: should get this from firmware
+               ld hl,#128
+               ld (_ramsize),hl
+               ld de,#64
+               or a,a
+               sbc hl,de
+               ld (_procmem),hl
+               ret
+
+               .area _COMMONMEM
+
+               .globl _program_vectors
+
+_program_vectors:
+               ret
+
+
+               .globl map_process
+               .globl map_process_always
+               .globl map_process_always_di
+               .globl map_process_a
+               .globl map_kernel
+               .globl map_kernel_di
+               .globl map_save_kernel
+               .globl map_restore
+
+               .globl _kdataseg
+
+map_kernel:
+map_kernel_di:
+               push af
+               ld a,(_kdataseg)
+               ioi
+               ld (DATASEG),a
+               pop af
+               ret
+
+map_process:
+map_process_di:
+               ld a,h
+               or a,l
+               jr z, map_kernel
+               ld a,(hl)
+map_process_a:
+               ioi
+               ld (DATASEG),a
+               ret
+map_process_always:
+map_process_always_di:
+               push af
+               ld a,(U_DATA__U_PAGE)
+               ioi
+               ld (DATASEG),a
+               pop af
+               ret
+map_save_kernel:
+               push af
+               ioi
+               ld a, (DATASEG)
+               ld (map_store),a
+               ld a,(_kdataseg)
+               ioi
+               ld (DATASEG),a  ; Must match map_kernel
+               pop af
+               ret
+map_restore:
+               push af
+               ld a,(map_store)
+               ioi
+               ld (DATASEG),a
+               pop af
+               ret
+map_store:
+               .db 0
+_kdataseg:
+               .db 0
+
+               .globl outchar
+
+outchar:
+               push af
+outwait:
+               ioi
+               ld a, (SASR)
+               bit 2,a
+               jr nz,outwait
+               pop af
+               ioi
+               ld (SADR),a
+               ret
+
+               .globl _spi_tx
+;
+;      Low level Rabbit 2000 primitives to use Port B for SPI.
+;
+;      Assumptions: The port is configured and the clock is set up
+;      properly. That is you have the serial pins enabled and you have
+;      timer A5 programmed and running.
+;
+;      We don't support simultaneous rx/tx although the R2000 can do it
+;      at lower speeds with some mucking about. SD doesn't need the full
+;      duplex behaviour.
+;
+;      Remember the bit ordering !
+
+
+               .area _CODE
+
+               .globl _rabbit_spi_tx
+               .globl _rabbit_spi_rx
+               .globl _rabbit_spi_slow
+               .globl _rabbit_spi_fast
+;
+_rabbit_spi_tx:
+               ; Finish any previous transaction activity
+               ioi
+               ld a,(SBSR)
+               bit 7,a
+               jr nz,_rabbit_spi_tx
+               ld a,l
+               ioi
+               ld (SBDR),a
+               ld a, #0x8C             ; send, our clock (ie master)
+               ioi
+               ld (SBCR),a
+txwait:                ioi
+               ld a,(SBSR)
+               bit 3,a
+               jr nz,txwait
+txwait2:       ioi
+               ld a,(SBSR)
+               bit 2,a
+               jr nz,txwait2
+               ret
+
+_rabbit_spi_rx:
+               ; Fire up the receiver and clock
+               ld a,#0x4C              ; receive (using PC4, 0x5C is PD4)
+               ioi
+               ld (SBCR),a
+               ; Wait for the data byte to appear
+               ; This is bounded by the synchronous clock
+rxwait:
+               ioi
+               ld a,(SBSR)
+               and a,#0x80
+               jr z,rxwait
+               ioi
+               ld a,(SBDR)
+               ld l,a
+               ret
+
+
+;
+;      Slow speed for probing
+;
+_rabbit_spi_slow:
+               ld a,#30                ; about 25KHz with a 29.5MHz clock
+               ioi
+               ld (TAT5R),a
+               ret
+
+;
+;      Set the timer for fast SPI.
+;
+;      We are limited to about 7.5MHz
+;
+_rabbit_spi_fast:
+               xor a,a
+               ioi
+               ld(TAT5R),a
+               ret
+
+;
+;      Real time clock interface. This is a 48bit counter running at 32KHz
+;
+;      Convention is that clock 0 is Jan 1 1980
+;
+;      The caller needs to ensure that they get two identical copies
+;
+
+               .globl _rabbit_read_rtc
+
+_rabbit_read_rtc:
+               ex de,hl                ; C argument is the buffer
+               ld hl,#RTC0R
+               ioi
+               ld (hl),#0
+               nop                     ; R2000 erratum
+               ipset3
+               ioi
+               ldi
+               ioi
+               ldi
+               ioi
+               ldi
+               ioi
+               ldi
+               ioi
+               ldi
+               ioi
+               ldi
+               ipres
+               ret
+
+;
+;      Watchdog timer
+;
+;      0x5A = 2 second, 0x57 = 1 second, 0x59 = 500m, 0x53 = 250ms
+;
+               .globl _rabbit_bop_watchdog
+
+_rabbit_bop_watchdog:
+               ld a,l
+               ioi
+               ld (WDTCR),a
+               ret
+;
+;      Periodic interrupt. Annoyingly fixed at 2KHz it seems
+;      This is the same for all rabbit 2k so maybe it belongs in the
+;      lowlevel-rabbit code ?
+;
+               .globl ticktock
+
+               .globl _ticker
+               .globl interrupt_handler
+ticktock:
+               push af
+               ioi
+               ld a,(GCSR)
+               push hl
+               ld hl,#_ticker
+               inc (hl)
+               jr z,tickwrap
+               pop hl
+               pop af
+               ipres
+               ret
+tickwrap:      ld (hl),#11     ; slightly off for 200/second but the rtc
+                               ; will compensate just fine. We need the
+                               ; speed for the serial queues
+               jp interrupt_handler            
+
+;
+;      Serial queues. The basic logic for them is given in the manual
+;      We do a simple optimization - our queues never cross a page. With
+;      the free d we then read the char early
+;
+;      Our platform interrupt will pick up the queue each timer tick
+;
+
+.macro serial  X Y
+
+               .area _COMMONMEM
+
+               .globl _ser'X'_q
+               .globl _ser'X'_rxbuf
+
+ser'X'_rx:
+               push hl
+               push de
+               ioi
+               ld a,(S'Y'DR)
+               ld d,a
+               ld hl,#_ser'X'_q
+               ld a,(hl)
+               ld e,a
+               inc hl
+               cp a,(hl)
+               jr z,ser'X'_rx_over
+               inc a
+               and a, #63
+               dec hl
+               ld (hl),a
+               ipres
+               ; work around stupid linker bug
+               ld hl, #_ser'X'_rxbuf
+               ld l,e
+               ld (hl),d
+ser'X'_rx_over:                ; for now do nothing clever
+               pop de
+               pop hl
+               pop af
+               ret
+
+ser'X'_tx:             ; really 'transmit and other...'
+                       ; we don't do transmit interrupts yet but we
+                       ; can't turn them off alone 8(
+               ioi
+               ld (S'Y'SR),a
+               pop af
+               ipres
+               ret
+
+               .globl _ser'X'_setup
+               .globl _ser'X'_get
+
+;
+;      00PPMMII
+;
+;      PP 00 port C 01 port D 1X off
+;      MM 00 8bit 01 7bit 10 clocked ext, 11 clocked int
+;      II 00 no int 01 pri 1 10 pri 2 11 pri 3
+;
+_ser'X'_setup:
+               ld a,l
+               ioi
+               ld (S'Y'CR),a
+               ret
+
+_ser'X'_get:
+               ld hl,#_ser'X'_q
+               ld a,(hl)               ; out ptr
+               ld e,a
+               inc hl
+               inc a
+               cp a,(hl)               ; in ptr
+               jr nz, ser'X'_empty
+               dec hl
+               ipset3
+               ld (hl),a
+               ld hl,#_ser'X'_rxbuf    ; work around dumb linker limit
+               ld l,e
+               ld l,(hl)
+               ld h,#0
+               ipres
+               ret
+ser'X'_empty:
+               ld hl,#0xffff
+               ret
+_ser'X'_q:
+               .db 0
+               .db 1
+
+               .area _SERIALBUF
+
+_ser'X'_rxbuf: .ds 64
+
+               .area _COMMONMEM
+.endm
+
+serial a A
+serial c C
+serial d D
diff --git a/Kernel/platform-rabbit2000/target.mk b/Kernel/platform-rabbit2000/target.mk
new file mode 100644 (file)
index 0000000..6c5c8de
--- /dev/null
@@ -0,0 +1,2 @@
+export CPU = r2k
+
diff --git a/Kernel/platform-rabbit2000/tricks.s b/Kernel/platform-rabbit2000/tricks.s
new file mode 100644 (file)
index 0000000..4aaa98a
--- /dev/null
@@ -0,0 +1,5 @@
+
+       .include "../kernel.def"
+       .include "kernel.def"
+
+       .include "../lib/r2kfixedbank.s"