From: Alan Cox Date: Fri, 15 Dec 2017 00:09:49 +0000 (+0000) Subject: v65c816-big: A development configuration for a 65C816 with loads of RAM X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=946999b5414e490f89207bf7a0ad1de6e97ab378;p=FUZIX.git v65c816-big: A development configuration for a 65C816 with loads of RAM 8MB RAM testing work. Lots to do here (plus some of the core code like the scheduler doesn't really scale to 128 processes!) --- diff --git a/Kernel/platform-v65c816-big/Makefile b/Kernel/platform-v65c816-big/Makefile new file mode 100644 index 00000000..08bf4ec9 --- /dev/null +++ b/Kernel/platform-v65c816-big/Makefile @@ -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 index 00000000..735b6ff1 --- /dev/null +++ b/Kernel/platform-v65c816-big/README @@ -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 index 00000000..923393cf --- /dev/null +++ b/Kernel/platform-v65c816-big/commonmem.s @@ -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 index 00000000..b73d08e3 --- /dev/null +++ b/Kernel/platform-v65c816-big/config.h @@ -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 index 00000000..09d59d07 --- /dev/null +++ b/Kernel/platform-v65c816-big/crt0.s @@ -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 index 00000000..0a730d89 --- /dev/null +++ b/Kernel/platform-v65c816-big/devhd.c @@ -0,0 +1,81 @@ +/* + * ROMdisc hack for testing + */ + +#include +#include +#include +#include + +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 index 00000000..5b99f00f --- /dev/null +++ b/Kernel/platform-v65c816-big/devhd.h @@ -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 index 00000000..6f4c1e26 --- /dev/null +++ b/Kernel/platform-v65c816-big/device.h @@ -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 index 00000000..8f2563d7 --- /dev/null +++ b/Kernel/platform-v65c816-big/devices.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000..abc9c33a --- /dev/null +++ b/Kernel/platform-v65c816-big/devtty.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 00000000..da0afba5 --- /dev/null +++ b/Kernel/platform-v65c816-big/devtty.h @@ -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 index 00000000..a86dd420 --- /dev/null +++ b/Kernel/platform-v65c816-big/kernel.def @@ -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 index 00000000..d15411e0 --- /dev/null +++ b/Kernel/platform-v65c816-big/ld65.cfg @@ -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 index 00000000..da471b73 --- /dev/null +++ b/Kernel/platform-v65c816-big/main.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +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 index 00000000..54adb1b5 --- /dev/null +++ b/Kernel/platform-v65c816-big/target.mk @@ -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 index 00000000..0b27b76f --- /dev/null +++ b/Kernel/platform-v65c816-big/v65.s @@ -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 index 00000000..1ba03586 --- /dev/null +++ b/Kernel/platform-v65c816-big/zeropage.inc @@ -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 +