v65c816-big: A development configuration for a 65C816 with loads of RAM
authorAlan Cox <alan@linux.intel.com>
Fri, 15 Dec 2017 00:09:49 +0000 (00:09 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 15 Dec 2017 00:09:49 +0000 (00:09 +0000)
8MB RAM testing work.

Lots to do here (plus some of the core code like the scheduler doesn't really
scale to 128 processes!)

17 files changed:
Kernel/platform-v65c816-big/Makefile [new file with mode: 0644]
Kernel/platform-v65c816-big/README [new file with mode: 0644]
Kernel/platform-v65c816-big/commonmem.s [new file with mode: 0644]
Kernel/platform-v65c816-big/config.h [new file with mode: 0644]
Kernel/platform-v65c816-big/crt0.s [new file with mode: 0644]
Kernel/platform-v65c816-big/devhd.c [new file with mode: 0644]
Kernel/platform-v65c816-big/devhd.h [new file with mode: 0644]
Kernel/platform-v65c816-big/device.h [new file with mode: 0644]
Kernel/platform-v65c816-big/devices.c [new file with mode: 0644]
Kernel/platform-v65c816-big/devtty.c [new file with mode: 0644]
Kernel/platform-v65c816-big/devtty.h [new file with mode: 0644]
Kernel/platform-v65c816-big/kernel.def [new file with mode: 0644]
Kernel/platform-v65c816-big/ld65.cfg [new file with mode: 0644]
Kernel/platform-v65c816-big/main.c [new file with mode: 0644]
Kernel/platform-v65c816-big/target.mk [new file with mode: 0644]
Kernel/platform-v65c816-big/v65.s [new file with mode: 0644]
Kernel/platform-v65c816-big/zeropage.inc [new file with mode: 0644]

diff --git a/Kernel/platform-v65c816-big/Makefile b/Kernel/platform-v65c816-big/Makefile
new file mode 100644 (file)
index 0000000..08bf4ec
--- /dev/null
@@ -0,0 +1,49 @@
+
+CSRCS = devtty.c devhd.c
+CSRCS += devices.c main.c
+
+LSRCS = ../lib/65c816.s
+LOBJS = $(patsubst ../lib/%.s,%.o, $(LSRCS))
+
+NSRCS = ../dev/net/net_native.c
+NOBJS = $(patsubst ../dev/net/%.c,%.o, $(NSRCS))
+
+ASRCS = v65.s crt0.s
+ASRCS += commonmem.s
+
+COBJS = $(CSRCS:.c=$(BINEXT))
+AOBJS = $(ASRCS:.s=$(BINEXT))
+OBJS  = $(COBJS) $(AOBJS) $(LOBJS) $(NOBJS)
+
+JUNK = $(CSRCS:.c=.o) $(CSRCS:.c=.s) $(ASRCS:.s=.o)
+
+all:   $(OBJS)
+
+$(COBJS): %$(BINEXT): %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG1) $<
+
+$(NOBJS): %$(BINEXT): ../dev/net/%.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG1) -o $@ $<
+
+$(AOBJS): %$(BINEXT): %.s
+       $(CROSS_AS) $(ASOPTS) $< -o $*$(BINEXT)
+
+$(LOBJS): %$(BINEXT): ../lib/%.s
+       $(CROSS_AS) $(ASOPTS) $< -o $*$(BINEXT)
+
+clean:
+       rm -f $(OBJS) $(JUNK)  core *~ 
+
+image:
+       $(CROSS_LD) -o ../fuzix.bin --mapfile ../fuzix.map -C ld65.cfg \
+       crt0.o commonmem.o \
+       v65.o ../start.o ../version.o ../lowlevel-65c816.o \
+       65c816.o main.o ../timer.o ../kdata.o devhd.o devices.o \
+       ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+       ../syscall_proc.o ../syscall_other.o ../mm.o ../bank65c816.o \
+       ../tty.o ../devsys.o ../syscall_fs2.o ../syscall_fs3.o \
+       ../syscall_exec16.o ../usermem.o ../usermem_std-65c816.o devtty.o \
+       ../syscall_net.o net_native.o ../level2.o ../syscall_level2.o \
+       ../select.o
+       dd if=../fuzix.bin of=fuzix.img bs=256 skip=255 count=1
+       dd if=../fuzix.bin of=fuzix.img bs=256 seek=1 skip=1 conv=notrunc
\ No newline at end of file
diff --git a/Kernel/platform-v65c816-big/README b/Kernel/platform-v65c816-big/README
new file mode 100644 (file)
index 0000000..735b6ff
--- /dev/null
@@ -0,0 +1,65 @@
+Use a modern cc65 from https://github.com/cc65/cc65
+
+Prototyping for 'large model' kernels for bigger memory maps. This set up uses
+a split I/D arrangement for the kernel with bank 0 holding kernel DP/S IRQ S
+and IRQ DP plus the I/O window and vectors. Bank 1 holds kernel code which with
+the room available can be built optimized better. Bank 2 holds the kernel data
+including 32K of buffer cache and the other buffers tuned to match the 2BSD
+Unix recommendations for a 16 user system.
+
+
+Our memory mapping looks like this
+
+Bank 0:
+       0x0000          Kernel DP
+       0x0100          Kernel Stack (CPU)
+       0x0200          IRQ stack
+       0x0400          First user DP/Stack
+       0xFE00          I/O Window
+       0xFF00          Vectors and IRQ DP
+
+Bank 1:
+       ...             Kernel image
+
+Bank 2:
+       ...             Kernel data and C stacks
+
+
+Bank 3+
+
+And in user space
+
+       0x0000          Unused
+       0x00FE          syscall vector
+       0x0100          Program (CPU stack is in bank 0)
+       0xFC00          Udata copy (512 bytes)
+       0xFE00          Spare
+       0xFF00          Stubs [signal return etc]
+                       (keep in 0 page ?)
+
+We don't yet allow for a split I/D user program using two banks and having 64K
+code and 64K data. We also then need to track 'texts' as V7 does so that we
+can share code segments when possible (often).
+
+To build:
+Set the platform/target
+make clean
+make
+
+
+TODO
+----
+- Rewrite crt0.s to set up the banks correctly and clear the data not code
+- Set memory size etc correctly
+- Add code to copy vectors from the right bank to each user bank
+- Stubs in bank 0 to long jump vectors into bank 2 (65C816 pushes the bank
+  so we just need to jump long into the right universe)
+- Rework KERNEL_BANK/KERNEL_FAR according to whether it is data or code
+- Fix compiler generated and helper stubs that self modify code (jmpvec in
+  particular must be modified to force kernel code bank and link itself into
+  kernel code)
+- See 65c816 port for general notes
+
+Optimisations We Need To Do
+--------------------------------------------------------------
+- Only copy the needed memory when forking, not 64K ?
diff --git a/Kernel/platform-v65c816-big/commonmem.s b/Kernel/platform-v65c816-big/commonmem.s
new file mode 100644 (file)
index 0000000..923393c
--- /dev/null
@@ -0,0 +1,52 @@
+;
+;      We keep our common area right down low, with the ZP and stack
+;
+;
+        ; exported symbols
+        .export _ub
+        .export _udata
+        .export kstack_top
+       .export kstackc_top
+        .export istack_top
+       .export istackc_top
+        .export istack_switched_sp
+
+        .segment "COMMONDATA"
+       .include "zeropage.inc"
+
+       .p816
+       .a8
+       .i8
+
+;
+;      The udata for 65C816 is a bit different to 6502 as we have both a C
+;      stack and a small CPU stack in the banking
+;
+;      Our current layout is
+;      [udata][cpu stack]              in 256 bytes
+;      [C stack]                       in 256 (will it be sufficient ?)
+;
+;      There is a separate IRQ DP, stack and C stack.
+;
+_ub:    ; first 512 bytes: starts with struct u_block, with the kernel stack working down from above
+_udata:
+kstack_base:
+       .res 256,0
+kstack_top:
+kstackc_base:
+       .res 256,0
+kstackc_top:
+
+;
+;      We have a single istack so we can stuff that anywhere we like
+;
+       .bss
+
+istack_base:
+       .res 64,0                       ; should be tons
+istack_top:
+istackc_base:
+       .res 254,0                      ; overkill - tune me
+istackc_top:
+istack_switched_sp:
+       .word 0
diff --git a/Kernel/platform-v65c816-big/config.h b/Kernel/platform-v65c816-big/config.h
new file mode 100644 (file)
index 0000000..b73d08e
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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
+/* Acct syscall support */
+#undef CONFIG_ACCT
+/* Multiple processes in memory at once */
+#define CONFIG_MULTI
+/* Use fixed banks for now. It's simplest and we've got so much memory ! */
+#define CONFIG_BANKS   1
+
+#define CONFIG_CALL_R2L                /* Runtime stacks arguments backwards */
+
+/* Networking (not usable yet but for debug/development) */
+#define CONFIG_NET
+#define CONFIG_NET_NATIVE
+/* Level 2 feature set */
+#define CONFIG_LEVEL_2
+
+/*
+ *     We have 8MB of RAM and have to allocate it in banks due to the CPU
+ *     bank granularity. That gives us 125 processes plus kernel and more
+ *     if we add swap.
+ */
+#define CONFIG_BANK_65C816
+#define KERNEL_BANK    0
+#define MAX_MAPS       125
+#define MAP_SIZE    0xFC00  /* 0-FBFF */
+
+/* 0xEE because our first bank is 1 and 0xEE + 2 * 1 = 0xF0 */
+#define STACK_BANKOFF  0x00    /* 0400-FDFF */
+
+#define TICKSPERSEC 100            /* Ticks per second */
+#define MAPBASE            0x0000  /* We map from 0 */
+#define PROGBASE    0x0100  /* also data base */
+#define PROGLOAD    0x0100
+#define PROGTOP     0xFC00  /* Top of program. If we fixed a few things we
+                               could go to FE00 */
+
+#define BOOT_TTY 513        /* Set this to default device for stdio, stderr */
+
+/* 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 1
+#define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
+#define NBUFS    64       /* Number of block buffers */
+#define NMOUNTS         8        /* Number of mounts at a time */
+
+#define platform_discard()     /* for now - wants fixing */
+
+/* Override defaults for a big system */
+
+/* Note: select() in the level 2 code will not work on this configuration
+   at the moment as select is limited to 16 processes. FIXME - support a
+   hash ELKS style for bigger systems where wakeup aliasing is cheaper */
+
+#define PTABSIZE       125
+#define UFTSIZE                16
+#define OFTSIZE                160
+#define ITABSIZE       176
diff --git a/Kernel/platform-v65c816-big/crt0.s b/Kernel/platform-v65c816-big/crt0.s
new file mode 100644 (file)
index 0000000..09d59d0
--- /dev/null
@@ -0,0 +1,149 @@
+       ; imported symbols
+       .import init_early
+       .import init_hardware
+       .import _fuzix_main
+       .import kstack_top
+       .import kstackc_top
+       .import vector
+       .import nmi_handler
+       .import interrupt_handler
+       .import emulation
+       .import illegal_inst
+       .import trap_inst
+       .import abort_inst
+
+       .import  __BSS_RUN__, __BSS_SIZE__
+       .importzp       ptr1, ptr2, tmp1
+
+       ; startup code @0200
+        .include "kernel.def"
+        .include "../kernel816.def"
+       .include "zeropage.inc"
+
+;
+;      So we end up first in the image
+;
+       .segment "START"
+       .byte 65
+       .byte 81
+
+       .p816
+       .a8
+       .i8
+
+entry:
+;
+;      We are entered at $0102 just after the required magic number
+;
+;      We get run from bank 0, our I/O writes would otherwise need to be
+;      24bit
+;
+       sep     #$30            ; ensure we are in 8bit mode
+       lda     #'F'
+       sta     $FE20           ; signal our arrival
+
+       sei                     ; interrupts off
+       cld                     ; decimal off
+
+
+       ; vectors is packed in DP, move it to FF00
+       rep     #$30
+       .a16
+       .i16
+       lda     #255
+       ldx     #0
+       ldy     #$FF00
+       mvn     KERNEL_BANK,KERNEL_BANK
+
+       sep     #$30
+       .a8
+       .i8
+
+
+       lda     #'u'
+       sta     $FE20
+
+       rep     #$10
+       .i16
+
+       ldx     #kstack_top-1
+       txs                     ; Stack (6502 not C)
+
+       lda     #'z'
+       sta     $FE20
+
+       ldx     #kstackc_top-1  ; C stack
+       stx     sp
+
+       ldx     #__BSS_RUN__
+
+       lda     #'i'
+       sta     $FE20
+
+       txy
+       iny
+
+       ; Wipe the BSS
+
+       rep #$20
+       .a16
+
+       lda     #__BSS_SIZE__-2 ; must be >=2  bytes or else
+       stz     a:0,x
+       mvn     0,0
+               
+       sep #$30
+       .a8
+       .i8
+
+       lda     #'x'
+       sta     $FE20
+
+       jsr     init_early
+       lda     #'.'
+       sta     $FE20
+       jsr     init_hardware
+       jmp     code
+
+       .code
+
+       .a8
+       .i8
+code:
+       lda     #13
+       sta     $FE20
+       lda     #10
+       sta     $FE20
+       jsr     _fuzix_main     ; Should never return
+       sei                     ; Spin
+stop:  bra stop
+
+
+;
+;      Processor vector table (0xFFE0)
+;
+       .segment "VECTORS"
+
+
+       .word   0               ; unused
+       .word   0               ; unused
+       .word   illegal_inst    ; COP
+       .word   trap_inst       ; BRK
+       .word   abort_inst      ; ABORT
+       .word   nmi_handler     ; NMI
+       .word   0               ; Unused (native reset)
+       .word   interrupt_handler
+
+       ;
+       ;       Emulation mode vectors. If called badness occurred
+       ;
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+       .word   emulation
+
+
diff --git a/Kernel/platform-v65c816-big/devhd.c b/Kernel/platform-v65c816-big/devhd.c
new file mode 100644 (file)
index 0000000..0a730d8
--- /dev/null
@@ -0,0 +1,81 @@
+/* 
+ * ROMdisc hack for testing
+ */
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devhd.h>
+
+extern uint8_t hd_kmap;
+
+extern void hd_read_data(uint16_t addr);
+extern void hd_write_data(uint16_t addr);
+
+volatile uint8_t *disknum  = (volatile uint8_t *)0xFE30;
+volatile uint8_t *diskcylh = (volatile uint8_t *)0xFE31;
+volatile uint8_t *diskcyll = (volatile uint8_t *)0xFE32;
+volatile uint8_t *diskcmd  = (volatile uint8_t *)0xFE33;
+volatile uint8_t *diskstat = (volatile uint8_t *)0xFE35;
+
+static int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
+{
+    uint16_t dptr, nb;
+    irqflags_t irq;
+    uint8_t err;
+
+    /* FIXME: add swap */
+    if(rawflag == 1 && d_blkoff(9))
+        return -1;
+
+    /* For swap it'll be the swap bank passed */
+    hd_kmap = rawflag ? udata.u_page : KERNEL_BANK;
+
+    dptr = (uint16_t)udata.u_dptr;
+    nb = udata.u_nblock;
+        
+    while (udata.u_nblock--) {
+        *disknum = minor;
+        *diskcylh = udata.u_block >> 8;
+        *diskcyll = udata.u_block;
+        *diskcmd = 1;
+        if ((err = *diskstat) != 0) {
+            kprintf("hd%d: disk error %x\n", err);
+            udata.u_error = EIO;
+            return -1;
+        }
+        /* We shouldn't need the di any more */        
+        irq = di();
+        if (is_read)
+            hd_read_data(dptr);
+        else
+            hd_write_data(dptr);
+        irqrestore(irq);
+        udata.u_block++;
+        dptr += 512;
+    }
+    return nb << BLKSHIFT;
+}
+
+int hd_open(uint8_t minor, uint16_t flag)
+{
+    used(flag);
+    if(minor != 0) {
+        udata.u_error = ENODEV;
+        return -1;
+    }
+    return 0;
+}
+
+int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    used(flag);
+    return hd_transfer(minor, true, rawflag);
+}
+
+int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    used(flag);
+    return hd_transfer(minor, false, rawflag);
+}
+
diff --git a/Kernel/platform-v65c816-big/devhd.h b/Kernel/platform-v65c816-big/devhd.h
new file mode 100644 (file)
index 0000000..5b99f00
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __DEVHD_DOT_H__
+#define __DEVHD_DOT_H__
+
+/* public interface */
+int hd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int hd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+int hd_open(uint8_t minor, uint16_t flag);
+
+#endif /* __DEVHD_DOT_H__ */
diff --git a/Kernel/platform-v65c816-big/device.h b/Kernel/platform-v65c816-big/device.h
new file mode 100644 (file)
index 0000000..6f4c1e2
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __DEVICE_DOT_H__
+#define __DEVICE_DOT_H__
+
+extern void mod_control(uint8_t set, uint8_t clr);
+
+#endif /* __DEVICE_DOT_H__ */
diff --git a/Kernel/platform-v65c816-big/devices.c b/Kernel/platform-v65c816-big/devices.c
new file mode 100644 (file)
index 0000000..8f2563d
--- /dev/null
@@ -0,0 +1,39 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <devhd.h>
+#include <devsys.h>
+#include <tty.h>
+#include <devtty.h>
+
+struct devsw dev_tab[] =  /* The device driver switch table */
+{
+// minor    open         close        read      write       ioctl
+// -----------------------------------------------------------------
+  /* 0: /dev/fd                Floppy disc block devices  */
+  {  hd_open,     no_close,    hd_read,   hd_write,   no_ioctl },
+  /* 1: /dev/hd                Hard disc block devices (absent) */
+  {  nxio_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  },
+  /* 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)
+{
+}
+
diff --git a/Kernel/platform-v65c816-big/devtty.c b/Kernel/platform-v65c816-big/devtty.c
new file mode 100644 (file)
index 0000000..abc9c33
--- /dev/null
@@ -0,0 +1,76 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <vt.h>
+#include <tty.h>
+
+static volatile uint8_t *uart = (volatile uint8_t *)0xFE20;
+static volatile uint8_t *timer = (volatile uint8_t *)0xFE10;
+
+static char tbuf1[TTYSIZ];
+PTY_BUFFERS;
+
+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},
+       PTY_QUEUES
+};
+
+/* Output for the system console (kprintf etc) */
+void kputchar(uint8_t c)
+{
+       if (c == '\n')
+               tty_putc(1, '\r');
+       tty_putc(1, c);
+}
+
+ttyready_t tty_writeready(uint8_t minor)
+{
+        return TTY_READY_NOW;
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+       minor;
+       uart[0] = c;
+}
+
+void tty_setup(uint8_t minor)
+{
+       minor;
+}
+
+void tty_sleeping(uint8_t minor)
+{
+       minor;
+}
+
+/* For the moment */
+int tty_carrier(uint8_t minor)
+{
+       minor;
+       return 1;
+}
+
+void tty_poll(void)
+{
+        uint8_t x;
+        
+        x = uart[1] & 1;
+        if (x) {
+               x = uart[0];
+               tty_inproc(1, x);
+       }
+}
+                
+void platform_interrupt(void)
+{
+       uint8_t t = *timer;
+       tty_poll();
+       while(t--) {
+               timer_interrupt();
+       }
+}
diff --git a/Kernel/platform-v65c816-big/devtty.h b/Kernel/platform-v65c816-big/devtty.h
new file mode 100644 (file)
index 0000000..da0afba
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __DEVTTY_DOT_H__
+#define __DEVTTY_DOT_H__
+
+extern void tty_poll(void);
+
+#endif
diff --git a/Kernel/platform-v65c816-big/kernel.def b/Kernel/platform-v65c816-big/kernel.def
new file mode 100644 (file)
index 0000000..a86dd42
--- /dev/null
@@ -0,0 +1,26 @@
+; UZI mnemonics for memory addresses etc
+
+; (this is struct u_data from kernel.h)
+U_DATA                  .set $0100     ; stomps over bootstrap
+; 256+256              (U, kstack copy, k C stack copy)
+U_DATA__TOTALSIZE       .set $0200
+U_DATA_STASH           .set $FC00      ; leaves FFxx for vectors and stubs
+
+PROGLOAD               .set $0100
+ZPBASE                 .set $0
+
+KERNEL_BANK            .set $2         ; bank number (data)
+KERNEL_FAR             .set $020000    ; 24 bit
+
+; Add this to twice the bank number to get the high 8bits of the 16bit CPU stack
+; for this process
+STACK_BANKOFF          .set $00        ; 0400-FDFF
+; Direct page for IRQ processing (saves us saving/restoring DP registers)
+; Can probably use the same page as the IRQ CPU stack... FIXME
+; FIXME clashes with end of stack banks
+IRQ_DP                 .set $FF00      ; FF00-FF3F
+KERNEL_DP              .set $00        ; We use the real ZP for kernel DP
+
+MAP_SIZE               .set $FC00
+
+PROGBASE               .set $0100
diff --git a/Kernel/platform-v65c816-big/ld65.cfg b/Kernel/platform-v65c816-big/ld65.cfg
new file mode 100644 (file)
index 0000000..d15411e
--- /dev/null
@@ -0,0 +1,45 @@
+#
+#      We map the various bank into different files as if they were at the
+#      bank 0 addresses. We don't want any far references but to rely upon
+#      bank registers
+#
+
+MEMORY {
+#Bank0
+       RAMZ:   start = $0000, size = $0100, type = rw, fill = yes;
+       USEG:   start = $0400, size = $FA00, type = rw, fill = yes;
+       IO:     start = $FE00, size = $0100, type = rw, fill = yes;
+       STUB:   start = $FF00, size = $00E0, type = rw, fill = yes;
+       VECTOR: start = $FFE0, size = $0020, type = rw, fill = yes;
+#Bank1
+       MAIN:   file = "fuzix.i", start = $0200, size = $10000, type = rw, fill = yes;
+#Bank2
+       UDATA:  file = "fuzix.d", start = $0000, size = $0200, type = rw, fill = yes;
+       BSEG:   file = "fuzix.d", start = $0200, size = $FE000, type = rw, fill = yes;
+}
+
+SEGMENTS {
+       ZEROPAGE:       load = RAMZ, type = zp, define = yes;
+
+       COMMONDATA:     load = UDATA, type = bss;
+
+       START:          load = MAIN, type = ro;
+       CODE:           load = MAIN, type = ro, define = yes;
+
+       RODATA:         load = BSEG, type = ro;
+
+       DATA:           load = BSEG, type = rw, define = yes;
+       BSS:            load = BSEG, type = bss, define = yes;
+
+       DISCARD:        load = MAIN, type = ro;
+       DISCARDDATA:    load = BSEG, type = ro;
+
+       STUBS:          load = STUB, type = ro;
+       VECTORS:        load = VECTOR, type = ro;
+}
+
+FILES {
+       %O: format = bin;
+       "fuzix.i": format = bin;
+       "fuzix.d": format = bin;
+}
diff --git a/Kernel/platform-v65c816-big/main.c b/Kernel/platform-v65c816-big/main.c
new file mode 100644 (file)
index 0000000..da471b7
--- /dev/null
@@ -0,0 +1,50 @@
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+
+uint8_t kernel_flag = 1;
+uint16_t ramtop = PROGTOP;
+
+void platform_idle(void)
+{
+    irqflags_t flags = di();
+    tty_poll();
+    irqrestore(flags);
+}
+
+void do_beep(void)
+{
+}
+
+/*
+ * 7 banks, kernel in bank 0
+ */
+
+void pagemap_init(void)
+{
+    int i;
+    /* Bank 0 is the kernel */
+    for (i = MAX_MAPS ; i > 0; i--)
+        pagemap_add(i);
+}
+
+void map_init(void)
+{
+}
+
+uint8_t platform_param(char *p)
+{
+    return 0;
+}
+
+char *pathbuf(void)
+{
+    return tmpbuf();
+}
+
+void pathfree(char *p)
+{
+    tmpfree(p);
+}
diff --git a/Kernel/platform-v65c816-big/target.mk b/Kernel/platform-v65c816-big/target.mk
new file mode 100644 (file)
index 0000000..54adb1b
--- /dev/null
@@ -0,0 +1,3 @@
+export CPU = 65c816
+export USERCPU = 6502
+
diff --git a/Kernel/platform-v65c816-big/v65.s b/Kernel/platform-v65c816-big/v65.s
new file mode 100644 (file)
index 0000000..0b27b76
--- /dev/null
@@ -0,0 +1,214 @@
+;
+;          v65 platform functions
+;
+
+            .export init_early
+            .export init_hardware
+            .export _program_vectors
+
+            ; exported debugging tools
+            .export _trap_monitor
+           .export _trap_reboot
+            .export outchar
+           .export ___hard_di
+           .export ___hard_ei
+           .export ___hard_irqrestore
+
+           .import _ramsize
+           .import _procmem
+           .import nmi_handler
+           .import syscall_vector
+           .import kstack_top
+           .import istack_switched_sp
+           .import istack_top
+           .import _kernel_flag
+           .import pushax
+
+           .import outcharhex
+           .import outxa
+           .import incaxy
+
+            .include "kernel.def"
+            .include "../kernel816.def"
+           .include "zeropage.inc"
+
+       .p816
+       .a8
+       .i8
+;
+;      syscall is jsr [$00fe]
+;
+syscall        =  $FE
+
+        .code
+
+_trap_monitor:
+       jmp     _trap_monitor
+
+_trap_reboot:
+       sep     #$30
+       .a8
+       .i8
+       lda     #$A5
+       sta     $FE40           ; Off
+       jmp     _trap_reboot    ; FIXME: original ROM map and jmp
+
+___hard_di:
+       php
+       sei                     ; Save old state in return to C
+       pla                     ; Old status
+       rts
+
+___hard_ei:
+       cli                     ; on 6502 cli enables IRQs!!!
+       rts
+
+___hard_irqrestore:
+       and     #4              ; IRQ flag
+       beq     irq_on
+       sei
+       rts
+irq_on:
+       cli
+       rts
+
+;
+;      This could go in discard once we make that useful FIXME
+;
+init_early:
+       lda     #1
+       sep     #$30
+       .a8
+       .i8
+
+init_loop:
+       sta     common_patch+1          ; destination bank
+       phb                             ; save our bank (mvn will mess it)
+       pha                             ; and count
+
+       rep     #$30
+       .a16
+       .i16
+
+       ldx     #$FF00
+       txy
+       lda     #$00FE
+common_patch:
+       mvn     KERNEL_BANK,0           ; copy the block
+
+       sep     #$30
+       .a8
+       .i8
+
+       pla
+       plb                             ; bank to kernel bank
+       inc
+       cmp     #8
+       bne     init_loop
+        rts
+
+       .a8
+       .i8
+
+init_hardware:
+        ; set system RAM size  (FIXME: dynamic probe)
+       rep #$10
+       .i16
+       ldx #512
+       stx _ramsize
+       ldx #512-64
+       stx _procmem
+
+       sep #$10
+       .i8
+
+       rts
+;
+;      We did this at early boot when we set up the vectors and copied
+;      stubs everywhere. Only thing we needed in each bank vector wise
+;      was syscall (if we keep to 6502 style syscall)
+;
+_program_vectors:
+       rts
+
+; outchar: Wait for UART TX idle, then print the char in a without
+; corrupting other registers
+outchar:
+       sta $0000FE20
+       rts
+
+
+;
+;      I/O logic
+;
+
+       .export _hd_kmap
+       .export _hd_read_data
+       .export _hd_write_data
+
+;
+;      Disk copier (needs to be in common), call with ints off
+;      for now
+;
+;      AX = ptr, length always 512, page in globals
+;
+
+_hd_read_data:
+       sta ptr3
+       stx ptr3+1
+       phd
+       phb
+       rep #$10
+       .i16
+       ldx ptr3                ; buffer address
+       lda _hd_kmap            ; page number
+       pha
+       plb                     ; data now points into user app
+       ldy #$FE00
+       phy
+       pld                     ; DP is now the I/O space
+       
+       ldy #512
+hd_read:
+       lda $34                 ; I/O data via DP
+       sta a:$0000,x           ; stores into data (user) bank
+       inx
+       dey
+       bne hd_read
+       plb                     ; restore bank registers
+       pld
+       sep #$10
+       .i8                     ; restore expected CPU state
+       rts
+
+_hd_write_data:
+       sta ptr3
+       stx ptr3+1
+       phd
+       phb
+       rep #$10
+       .i16
+       ldx ptr3                ; buffer address
+       lda _hd_kmap            ; page number
+       pha
+       plb                     ; data now points into user app
+       ldy #$FE00
+       phy
+       pld                     ; DP is now the I/O space
+       
+       ldy #512
+hd_write:
+       lda a:$0000,x           ; load from data (user) bank
+       sta $34                 ; I/O data via DP
+       inx
+       dey
+       bne hd_write
+       plb                     ; restore bank registers
+       pld
+       sep #$10
+       .i8                     ; restore expected CPU state
+       rts
+
+       .bss
+_hd_kmap:
+       .res 1
diff --git a/Kernel/platform-v65c816-big/zeropage.inc b/Kernel/platform-v65c816-big/zeropage.inc
new file mode 100644 (file)
index 0000000..1ba0358
--- /dev/null
@@ -0,0 +1,26 @@
+;
+; zeropage.inc
+;
+; (C) Copyright 2002-2012, Ullrich von Bassewitz (uz@cc65.org)
+;
+
+; Assembler include file that imports the runtime zero page locations used
+; by the compiler, ready for usage in asm code.
+
+
+        .globalzp       sp, sreg, regsave
+        .globalzp       ptr1, ptr2, ptr3, ptr4
+        .globalzp       tmp1, tmp2, tmp3, tmp4
+        .globalzp       regbank
+  
+; The size of the register bank
+regbanksize     = 6
+
+; The total amount of zero page space used
+zpspace         = 26
+
+; The amount of space that needs to be saved by an interrupt handler that
+; calls C code (does not include the register bank, which is saved by the
+; generated C code if required).
+zpsavespace     = zpspace - regbanksize
+