+++ /dev/null
-
-CSRCS = devlpr.c devtty.c devrd.c
-CSRCS += devices.c main.c libc.c
-
-ASRCS = p6502.s crt0.s
-ASRCS += tricks.s commonmem.s
-
-COBJS = $(CSRCS:.c=$(BINEXT))
-AOBJS = $(ASRCS:.s=$(BINEXT))
-OBJS = $(COBJS) $(AOBJS)
-
-JUNK = $(CSRCS:.c=.o) $(CSRCS:.c=.s) $(ASRCS:.s=.o)
-
-all: $(OBJS)
-
-$(COBJS): %$(BINEXT): %.c
- $(CROSS_CC) $(CROSS_CCOPTS) $<
-
-$(AOBJS): %$(BINEXT): %.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 \
- p6502.o ../start.o ../version.o ../lowlevel-6502.o \
- tricks.o main.o ../timer.o ../kdata.o devrd.o devices.o \
- ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
- ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../bank16k.o \
- ../tty.o ../devsys.o ../syscall_fs2.o ../syscall_exec.o \
- ../usermem.o devlpr.o devtty.o libc.o
+++ /dev/null
-6502 test sketching out
-
-This is not a complete port, but a sketch in progress to test that it should
-be possible to run FUZIX on a banked 6502 such as the Commodore 6509 based
-systems.
-
-The 6509 also provides an opportunity to test a very different banking
-model. There is no common area on a 6509 based system. Address 0 sets the
-64K bank to be used and swaps wholesale between banks. Address 1 set the
-bank used on two specific instructions LDA (foo),y and STA (foo),y. In other
-words the only interbank feature you have is far data pointers.
-
-
-For Fuzix this should mean we can
-
-- select fixed banks so we hand each task a bank
-- make map_kernel/map_process/map_* in general mostly no-ops. We do
- need to save address 1 on map_save/restore in case the kernel is mid
- far access
-- add a new section "STUBS" which is copied to the same spot in each bank
- and contains mini wrappers for syscall, interrupts, doexec and signal
- dispatch
-
-Interrupts simply flip bank and go via a C __interrupt wrapper which saves
-the C stack state for the kernel, then runs the IRQ handler, then returns
-back.
-
-ISSUE: need to figure where to save the __interrupt bits as we task switch
-in irq cases
-
-
-System calls far copy the syscall code and the arguments into the udata
-rather than fishing them off the stack as Z80 does. They then switch to the
-kernel stack, set up the C stack and run the system call. When it returns
-for that process context we copy back the error and return values into the
-user bank, and bankflip back.
-
-In both cases we need to also pull over the pending signal and the vector
-for it as we need to dispatch the signal from the user bank. (*TODO*)
-
-
-The other odd case is doexec. When we exec a process we don't return via
-the system call path but instead directly exit kernel mode and jump to the
-new stack/pc. This is arguably a wart and we should instead patch the return
-stack (and fix start up). For now however we need a stub of code to do the
-dispatch. Basically we set the sp in the user bank, switch to the user bank
-and jump to the target
+++ /dev/null
-;
-; Put the udata at the start of common. We have four 16K banks so we
-; keep the non .common kernel elements below C000 and then keep bank 3 as a
-; true common bank
-;
- ; exported symbols
- .export _ub
- .export _udata
- .export kstack_top
- .export istack_top
- .export istack_switched_sp
-
- .segment "COMMONMEM"
-
-;
-; In 6502 land these are the C stacks, we will need to handle the
-; hardware stack separately, and also to save sp,sp+1 etc on irqs
-;
-_ub: ; first 512 bytes: starts with struct u_block, with the kernel stack working down from above
-_udata:
-kstack_base:
- .res 512,0
-kstack_top:
-
- ; next 256 bytes: 254 byte interrupt stack, then 2 byte saved stack pointer
-istack_base:
- .res 254,0
-istack_top:
-istack_switched_sp: .word 0
+++ /dev/null
-/* 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) */
-#define CONFIG_PROFIL
-/* Acct syscall support */
-#define CONFIG_ACCT
-/* Multiple processes in memory at once */
-#define CONFIG_MULTI
-/* Single tasking - for now while we get it booting */
-#undef CONFIG_SINGLETASK
-/* Use the C language usermem helpers */
-#define CONFIG_USERMEM_C
-/* TODO: these need to be defined as the code to flip the banks over */
-#define BANK_PROCESS
-#define BANK_KERNEL
-#define CONFIG_BANKS 1
-
-/* We use flexible 16K banks so use the helper */
-#define CONFIG_BANK16
-#define MAX_MAPS 16
-/* And swapping */
-#define SWAPDEV 6 /* FIXME */
-#define SWAP_SIZE 0x80 /* 64K blocks */
-/* FIXME */
-#define SWAPBASE 0x0000 /* We swap the lot in one, include the */
-#define SWAPTOP 0xF000 /* vectors so its a round number of sectors */
-#define UDATA_BLOCKS 0 /* We swap the uarea in the data */
-#define UDATA_SWAPSIZE 0
-#define MAX_SWAPS 32
-
-
-/* Video terminal, not a serial tty */
-#define CONFIG_VT
-/* We want the 8x8 font */
-#define CONFIG_FONT_8X8
-/* Vt definitions */
-#define VT_WIDTH 64
-#define VT_HEIGHT 24
-#define VT_RIGHT 63
-#define VT_BOTTOM 23
-
-#define TICKSPERSEC 100 /* Ticks per second */
-#define PROGBASE 0x0200 /* also data base */
-#define PROGLOAD 0x0200
-#define PROGTOP 0xF000 /* Top of program, base of U_DATA */
-
-#define BOOT_TTY 513 /* Set this to default device for stdio, stderr */
- /* In this case, the default is the first TTY device */
- /* Temp FIXME set to serial port for debug ease */
-
-/* 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 NDEVS 1 /* Devices 0..NDEVS-1 are capable of being mounted */
- /* (add new mountable devices to beginning area.) */
-#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
-#define NBUFS 10 /* Number of block buffers */
-#define NMOUNTS 1 /* Number of mounts at a time - nothing mountable! */
+++ /dev/null
- ; exported symbols
- .export start
-
- ; imported symbols
- .import init_early
- .import init_hardware
- .import _fuzix_main
- .import kstack_top
-
- .import __BSS_RUN__, __BSS_SIZE__
-
-
- ; startup code @0
- .code
- .include "zeropage.inc"
-
-start:
- sei ; interrupts off
- cld ; decimal off
- ldx #$FF
- txs ; Stack (6502 not C)
-
- lda #<kstack_top ; C stack
- sta sp
- lda #>kstack_top
- sta sp+1
-
- lda #<__BSS_RUN__
- sta ptr1
- lda #>__BSS_RUN__
- sta ptr1+1
- lda #0
- tay
-
- ldx #>__BSS_SIZE__
- beq bss_wipe_tail
-bss_wiper_1: sta (ptr1),y
- iny
- bne bss_wiper_1
- inc ptr1+1
- dex
- bne bss_wiper_1
-
-bss_wipe_tail:
- cpy #<__BSS_SIZE__
- beq gogogo
- sta (ptr1),y
- iny
- bne bss_wipe_tail
-gogogo:
- jsr init_early
- jsr init_hardware
- jsr _fuzix_main ; Should never return
- sei ; Spin
-stop: jmp stop
+++ /dev/null
-#ifndef __DEVICE_DOT_H__
-#define __DEVICE_DOT_H__
-
-extern void mod_control(uint8_t set, uint8_t clr);
-
-#endif /* __DEVICE_DOT_H__ */
+++ /dev/null
-#include <kernel.h>
-#include <version.h>
-#include <kdata.h>
-#include <devrd.h>
-#include <devsys.h>
-#include <devlpr.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 */
- { rd_open, no_close, rd_read, rd_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 */
- { lpr_open, lpr_close, no_rdwr, lpr_write, 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) + 255)
- return false;
- else
- return true;
-}
-
-void device_init(void)
-{
-}
-
+++ /dev/null
-#include <kernel.h>
-#include <version.h>
-#include <kdata.h>
-#include <device.h>
-#include <devlpr.h>
-
-/* random test places */
-uint8_t *lpstat = (uint8_t *)0xFF00;
-uint8_t *lpdata = (uint8_t *)0xFF01;
-
-int lpr_open(uint8_t minor, uint16_t flag)
-{
- minor;
- flag; // shut up compiler
- return 0;
-}
-
-int lpr_close(uint8_t minor)
-{
- minor; // shut up compiler
- return 0;
-}
-
-int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
-{
- int c = udata.u_count;
- char *p = udata.u_base;
- uint16_t ct;
-
- minor;
- rawflag;
- flag; // shut up compiler
-
- while (c-- > 0) {
- ct = 0;
-
- /* Try and balance polling and sleeping */
- while (*lpstat & 2) {
- ct++;
- if (ct == 10000) {
- udata.u_ptab->p_timeout = 3;
- if (psleep_flags(NULL, flag)) {
- if (udata.u_count)
- udata.u_error = 0;
- return udata.u_count;
- }
- ct = 0;
- }
- }
- /* Data */
- *lpdata = ugetc(p++);
- }
- return udata.u_count;
-}
+++ /dev/null
-#ifndef __DEVLPR_DOT_H__
-#define __DEVLPR_DOT_H__
-
-int lpr_open(uint8_t minor, uint16_t flag);
-int lpr_close(uint8_t minor);
-int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
-
-#endif
+++ /dev/null
-/*
- * NC100 RD PCMCIA driver
- *
- */
-
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <devrd.h>
-
-static int rd_transfer(bool is_read, uint8_t rawflag)
-{
- blkno_t block;
- int block_xfer;
- uint16_t dptr;
- int dlen;
- int ct = 0;
- int map;
-
- /* FIXME: raw is broken unless nicely aligned */
- if(rawflag) {
- dlen = udata.u_count;
- dptr = (uint16_t)udata.u_base;
- if (((uint16_t)udata.u_offset|dptr) & BLKMASK) {
- udata.u_error = EIO;
- return -1;
- }
- block = udata.u_offset >> 9;
- block_xfer = dlen >> 9;
- map = 1;
- } else { /* rawflag == 0 */
- dlen = 512;
- dptr = (uint16_t)udata.u_buf->bf_data;
- block = udata.u_buf->bf_blk;
- block_xfer = 1;
- map = 0;
- }
- block += 2*320; /* ramdisc starts at 320K in */
-
- while (ct < block_xfer) {
-/* rd_memcpy(is_read, map, dptr, block); */
- block++;
- ct++;
- }
- return ct;
-}
-
-int rd_open(uint8_t minor, uint16_t flag)
-{
- flag;
- if(minor != 0) {
- udata.u_error = ENODEV;
- return -1;
- }
- return 0;
-}
-
-int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
-{
- flag;minor;
- return rd_transfer(true, rawflag);
-}
-
-int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
-{
- flag;minor;
- return rd_transfer(false, rawflag);
-}
-
+++ /dev/null
-#ifndef __DEVRD_DOT_H__
-#define __DEVRD_DOT_H__
-
-/* public interface */
-int rd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
-int rd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
-int rd_open(uint8_t minor, uint16_t flag);
-
-/* asm banking helper */
-void rd_memcpy(uint8_t isread, uint8_t map, uint16_t dptr, uint16_t block);
-
-#endif /* __DEVRD_DOT_H__ */
-
+++ /dev/null
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <stdbool.h>
-#include <devtty.h>
-#include <device.h>
-#include <vt.h>
-#include <tty.h>
-
-#undef DEBUG /* UNdefine to delete debug code sequences */
-
-uint8_t *uarta = (uint8_t *)0xFF04;
-uint8_t *uartb = (uint8_t *)0xFF05;
-
-static char tbuf1[TTYSIZ];
-static char tbuf2[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},
- {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2},
- PTY_QUEUES
-};
-
-/* tty1 is the screen tty2 is the serial port */
-
-/* Output for the system console (kprintf etc) */
-void kputchar(char c)
-{
- if (c == '\n')
- tty_putc(1, '\r');
- tty_putc(1, c);
-}
-
-ttyready_t tty_writeready(uint8_t minor)
-{
- uint8_t c;
- if (minor == 1)
- return TTY_READY_NOW;
- c = *uartb;
- return (c & 1) ? TTY_READY_NOW : TTY_READY_SOON;
-}
-
-void tty_putc(uint8_t minor, unsigned char c)
-{
- minor;
-#if 0
- if (minor == 1) {
- vtoutput(&c, 1);
- return;
- }
-#endif
- *uarta = c;
-}
-
-void tty_setup(uint8_t minor)
-{
- minor;
-}
-
-/* For the moment */
-int tty_carrier(uint8_t minor)
-{
- minor;
- return 1;
-}
-
-void platform_interrupt(void)
-{
- timer_interrupt();
-}
-
-/* This is used by the vt asm code, but needs to live at the top of the kernel */
-uint16_t cursorpos;
+++ /dev/null
-#ifndef __DEVTTY_DOT_H__
-#define __DEVTTY_DOT_H__
-
-extern int nc100_tty_open(uint8_t minor, uint16_t flag);
-extern int nc100_tty_close(uint8_t minor);
-extern void nc100_tty_init(void);
-#endif
+++ /dev/null
-; UZI mnemonics for memory addresses etc
-
-; (this is struct u_data from kernel.h)
-U_DATA .set $F000
-; 256+256+256 bytes.
-U_DATA__TOTALSIZE .set $300
-
+++ /dev/null
-MEMORY {
- RAMZ: start = $0000, size = $0100;
- RAM0: start = $0800, size = $E800;
- RAM1: start = $F000, size = $0800;
-}
-
-SEGMENTS {
- ZEROPAGE: load = RAMZ, type = rw;
- CODE: load = RAM0, type = ro;
- RODATA: load = RAM0, type = ro;
- DATA: load = RAM0, type = rw;
- BSS: load = RAM0, type = bss, define=yes;
- COMMONMEM: load = RAM1, type = rw;
-}
-
+++ /dev/null
-#include "cpu.h"
-
-void *memcpy(void *d, void *s, size_t sz)
-{
- unsigned char *dp, *sp;
- while(sz--)
- *dp++=*sp++;
- return d;
-}
-
-size_t strlen(const char *p)
-{
- const char *e = p;
- while(*e++);
- return e-p-1;
-}
-
+++ /dev/null
-#include <kernel.h>
-#include <timer.h>
-#include <kdata.h>
-#include <printf.h>
-#include <devtty.h>
-
-/* The uarea is already synched to the stash which is written with the
- process */
-uint8_t *swapout_prepare_uarea(ptptr p)
-{
- p;
- return NULL;
-}
-
-/* The switchin code will move the uarea into the process itself, we just
- need to fix up the u_page pointer */
-uint8_t *swapin_prepare_uarea(ptptr p)
-{
- p;
- return NULL;
-}
-
-void platform_idle(void)
-{
-}
-
-void do_beep(void)
-{
-}
-
-/*
- * Map handling: We have flexible paging. Each map table consists of a set of pages
- * with the last page repeated to fill any holes.
- */
-
-void pagemap_init(void)
-{
- int i;
- /* 0/1/2 image, 3/4/5 kernel 6-19 apps */
- /* Don't add page 6 yet - it's the initial common at boot */
- for (i = 0x80 + 7; i < 0x80 + 20; i++)
- pagemap_add(i);
- /*
- * The kernel boots with 0x86 as the common, list it last here so it also
- * gets given to init as the kernel kicks off the init stub. init will then
- * exec preserving this common and all forks will be copies from it.
- */
- pagemap_add(0x86);
-}
-
-void map_init(void)
-{
-}
+++ /dev/null
-;
-; 6502 Build testing
-;
-
- .export init_early
- .export init_hardware
- .export _program_vectors
- .export map_kernel
- .export map_process
- .export map_process_always
- .export map_save
- .export map_restore
-
- ; exported debugging tools
- .export _trap_monitor
- .export outchar
- .export _di
- .export _ei
- .export _irqrestore
-
- .import interrupt_handler
- .import _ramsize
- .import _procmem
- .import nmi_handler
- .import unix_syscall_entry
- .import _kernel_flag
- .import kstack_top
- .import istack_switched_sp
-
- .include "kernel.def"
- .include "../kernel02.def"
- .include "zeropage.inc"
-
-;
-; syscall is jsr [$00fe]
-;
-syscall = $FE
-; -----------------------------------------------------------------------------
-; COMMON MEMORY BANK (0xF000 upwards)
-; -----------------------------------------------------------------------------
- .segment "COMMONMEM"
-
-trapmsg: .asciiz "Trapdoor: SP="
-trapmsg2: .asciiz ", PC="
-tm_user_sp: .word 0
-
-_trap_monitor:
- sei
- jmp _trap_monitor
-
-_trap_reboot:
-; lda 0xff90
-; anda #0xfc ; map in the ROM
-; jmp 0
-
-_di:
- php
- sei ; FIXME: save old state in return to C
- pla ; Old status
- rts
-_ei:
- cli ; on 6502 cli enables IRQs!!!
- rts
-
-_irqrestore:
- and #4 ; IRQ flag
- beq irq_on
- cli
- rts
-irq_on:
- sei
- rts
-
-; -----------------------------------------------------------------------------
-; KERNEL MEMORY BANK (below 0xF000, only accessible when the kernel is mapped)
-; -----------------------------------------------------------------------------
- .code
-
-init_early:
- rts
-
-init_hardware:
- ; set system RAM size for test purposes
- lda #1
- sta _ramsize+1
- lda #0
- sta _ramsize
- sta _procmem+1
- lda #192
- sta _procmem
-
- jsr program_vectors_k
-
- rts
-
-
-;------------------------------------------------------------------------------
-; COMMON MEMORY PROCEDURES FOLLOW
-
- .segment "COMMONMEM"
-
-_program_vectors:
- ; we are called, with interrupts disabled, by both newproc() and crt0
- ; will exit with interrupts off
- sei
- ;
- ; Fixme: block copy stubs segment as well if 6509.
- ;
-
- ; our C caller will invoke us with the pointer in x,a
- ; just pass it on
- jsr map_process
-program_vectors_k:
- lda #<vector
- sta $FFFE
- lda #>vector
- sta $FFFF
- lda #<nmi_handler
- sta $FFFA
- lda #>nmi_handler
- sta $FFFB
- ; However tempting it may be to use BRK for system calls we
- ; can't do this on an NMOS 6502 because the chip has brain
- ; dead IRQ handling buts that could simply "lose" the syscall!
- lda #<syscall_entry
- sta syscall
- lda #>syscall_entry
- sta syscall+1
- jsr map_kernel
- rts
-
-;
-; On a fully switching system with far copies like the 6509 this is
-; all basically a no-op
-;
-; On a banked setup the semantics are:
-;
-; map_process_always()
-; Map the current process (ie the one with the live uarea)
-;
-; map_kernel()
-; Map the kernel
-;
-; map_process(pageptr [in X,A])
-; if pageptr = 0 then map_kernel
-; else map_process using the pageptr
-;
-; map_save
-; save the current mapping
-;
-; map_restore
-; restore the saved mapping
-;
-; save/restore are used so that the kernel can play with its internal
-; banking/mappings without having to leave interrupts off all the time
-;
-map_process_always:
- pha
- lda #<U_DATA__U_PAGE
- ldx #>U_DATA__U_PAGE
- jsr map_process_2
- pla
- rts
-;
-; X,A points to the map table of this process
-;
-map_process:
- cmp #0
- bne map_process_2
- cpx #0
- bne map_process_2
-;
-; Map in the kernel below the current common, all registers preserved
-;
-map_kernel:
- pha
- lda #1 ; for 6509 clean up any far copy ptr
- sta 1
- pla
- rts
-
-; X,A holds the map table of this process
-map_process_2:
- sta ptr1
- tya
- pha
- sty ptr1+1
- ldy #0
- lda (ptr1),y ; 4 bytes if needed
- sta map_current
- pla
- tay
- rts
-
-
-;
-; Restore the indirection register on the 6509, just in case we
-; interrupted mid far copy
-;
-map_restore:
- pha
- lda saved_map
- sta 1
- pla
- rts
-
-; Save the current mapping. For a 6509 just save the indirection
-;
-map_save:
- pha
- lda 1
- sta saved_map
- pla
- rts
-
-saved_map: .dbyt 0
-map_current: .dbyt 0
-
-; outchar: Wait for UART TX idle, then print the char in a without
-; corrupting other registers
-
-outchar:
-outcharw:
-; ldb 0xffa0
-; bitb #0x02
-; beq outcharw
-; sta 0xffa1
-; puls b,pc
- rts
-
-;
-; Code that will live in each bank at the same address and is copied
-; there on 6509 type setups. On 6502 it may well be linked once in
-; common space
-;
- .segment "STUBS"
-;
-; Interrupt vector logic. Keep this in platform for the 6502 so that
-; we can use the shorter one for the CMOS chip
-;
-; FIXME: spot BRK instructions and turn them into a synchronous
-; SIGTRAP
-;
-vector:
- pha
- txa
- pha
- tya
- pha
- cld
- tsx
- inx
- inx
- inx
- inx
- lda $0100,X
- and #$10
-;
-; FIXME: either don't care about brk or ship it somewhere like
-; kill -SIGTRAP
-;
- bne bogon
-;
-; Switch to the kernel memory mapping (stack gone away)
-;
- lda 1 ; Save the indirection vector
- pha
- lda #1 ; Kernel in bank 1
- sta 1
- sta 0
-; The next fetch will occur from the new mapping (kernel) copy
-; Stack has gone for a walk if we were not coming from kernel
- tsx
- stx istack_switched_sp ; in uarea/stacks
- ldx #$C0
- txs ; our istack
- jsr interrupt_handler
- ldx istack_switched_sp
- txs ; entry stack
- lda _kernel_flag
- beq vector_um
-;
-; Already in kernel (bank 1)
-;
- pla
- sta 1 ; restore the saved indirect
- jmp irqout
-vector_um:
- lda U_DATA__U_PAGE ; may be a new task
- sta 1 ; flip to it
- sta 0
-; leap back into user context (may be a different user context to the one
-; we left. Stack now valid again
- pla ; discard saved idirect
-
-irqout:
-bogon:
- pla
- tya
- pla
- txa
- pla
- rti
-
-
-; X, A holds the syscall block
-; Y holds the call code
-; We assume the kernel is in bank 0
-;
-syscall_entry:
- sei
- sty tmp1 ; for a moment
- sta ptr1
- stx ptr1+1
- lda #<U_DATA__U_ARGN
- sta ptr2
- lda #>U_DATA__U_ARGN
- sta ptr2+1
-
- ldy #0
-
-copy_args: lda (ptr1),y ; copy the arguments from current bank
- tax
- lda #1
- sta 1 ; bank 1 please
- txa
- sta (ptr2),y ; will write into bank 1
- lda #0
- sta 1
- iny
- cpy #8
- bne copy_args
- ldy tmp1 ; syscall code
- ;
- ; Now we need to bank and stack switch
- ;
- tsx
- lda #1
- sta 0 ; kernel banks
- sta 1
-;
-; We are now suddenly in the kernel copy of this, and our stack is
-; missing in action. Access to userspace is not available
-;
-; On a 6509 this also means our C stack is missing in action, which
-; is quite convenient as it saves us a save and restore it. On other
-; CPUs it might be a little less convenient
-;
- stx U_DATA__U_SP
- ldx #0
-;
-; FIXME: how to handle IRQ division of stack ???
-;
- txs ; Switch to the working stack
-;
-; Set up the C stack
-;
- lda #<kstack_top
- sta sp
- lda #>kstack_top
- sta sp+1
-
- cli
-;
-; Caution: We may enter here and context switch and another task
-; exit via its own syscall returning in its own memory context.
-;
-; Don't assume anything we stored statically *except* the uarea
-; will be different. The uarea is banked in and out (or copied in
-; more awkward systems).
-;
- jsr unix_syscall_entry
-
- sei
-;
-; Correct the system stack
-;
- ldx U_DATA__U_SP
- txs
- lda U_DATA__U_PAGE ; our bank
- sta 1 ; use our bank for sta (ptr), y
-;
-; Copy the return data over
-;
- ldy #8 ; write them after the argument block
-;
-; As we are a user process and making a syscall our ptr1 was saved
-; and banked out. If you had common memory this would be uglier but
-; then you've got somewhere else to put the pointer right !
-;
- lda U_DATA__U_ERROR
- sta (ptr1), y
- iny
- lda U_DATA__U_ERROR+1
- sta (ptr1),y
- iny
- lda U_DATA__U_RETVAL
- sta (ptr1),y
- iny
- lda U_DATA__U_RETVAL+1
- sta (ptr1), y
-; FIXME Also copy over needed signal information (vector, pending stuff)
-;
- lda 1 ; The sta,y redirection bank
- sta 0 ; becomes our execution bank
-;
-; We just teleported back to the copy of this code in the
-; user process bank
-;
-; Our C stack is valid as we simply bounced out of it for the 6509.
-;
-;
-; FIXME: do signal dispatch - this will need C stack fixing, and
-; basically signal dispatch is __interrupt.
-;
-
- rts
+++ /dev/null
-;
-; 6502 version
-;
- .export _switchout
- .export _switchin
- .export _dofork
- .export _ramtop
-
- .import _chksigs
- .import _trap_monitor
-
- .include "kernel.def"
- .include "../kernel02.def"
-
- .segment "COMMONMEM"
-
-; ramtop must be in common for single process swapping cases
-; and its a constant for the others from before init forks so it'll be fine
-; here
-_ramtop:
- .word 0
-
-; Switchout switches out the current process, finds another that is READY,
-; possibly the same process, and switches it in. When a process is
-; restarted after calling switchout, it thinks it has just returned
-; from switchout().
-;
-; FIXME: make sure we optimise the switch to self case higher up the stack!
-;
-; This function can have no arguments or auto variables.
-_switchout:
- sei
-
- jsr _chksigs
-;
-; ; save machine state
-; ldd #0 ; return code set here is ignored, but _switchin can
-; ; return from either _switchout OR _dofork, so they must both write
-; ; U_DATA__U_SP with the following on the stack:
-; pshs d
-; sts U_DATA__U_SP
-;
-; ; set inint to false
-; lda #0
-; sta _inint
-;
-; ; find another process to run (may select this one again) returns it
-; ; in X
-; jsr _getproc
- jsr _switchin
- ; we should never get here
- jsr _trap_monitor
-
-badswitchmsg: .asciiz "_switchin: FAIL\r\n"
-
-; new process pointer is in X
-_switchin:
-; orcc #0x10 ; irq off
-;
-; ldy P_TAB__P_PAGE_OFFSET+3,x
-; ; FIXME: can we skip the usermaps here ?
-; stx 0xffa6 ; map the process uarea we want
-; adda #1
-; stx 0xffa7
-; stx 0xffaf ; and include the kernel mapping
-;
- ; ------- No stack -------
- ; check u_data->u_ptab matches what we wanted
-; cmpx U_DATA__U_PTAB
-; bne switchinfail
-;
- ; wants optimising up a bit
-; lda #P_RUNNING
-; sta P_TAB__P_STATUS_OFFSET,x
-
-; lda #0
-; sta _runticks
-
- ; restore machine state -- note we may be returning from either
- ; _switchout or _dofork
-; lds U_DATA__U_SP
-
-; puls x ; return code
-
- ; enable interrupts, if the ISR isn't already running
-; lda _inint
-; beq swtchdone ; in ISR, leave interrupts off
-; andcc #0xef
-;swtchdone:
-; rts
-
-switchinfail:
-; jsr outx
-; ldx #badswitchmsg
-; jsr outstring
-; ; something went wrong and we didn't switch in what we asked for
-; jmp _trap_monitor
-
-fork_proc_ptr: .word 0 ; (C type is struct p_tab *) -- address of child process p_tab entry
-
-;
-; Called from _fork. We are in a syscall, the uarea is live as the
-; parent uarea. The kernel is the mapped object.
-;
-_dofork:
-; ; always disconnect the vehicle battery before performing maintenance
-; orcc #0x10 ; should already be the case ... belt and braces.
-
- ; new process in X, get parent pid into y
-
-; stx fork_proc_ptr
-; ldy P_TAB__P_PID_OFFSET,x
-
- ; Save the stack pointer and critical registers.
- ; When this process (the parent) is switched back in, it will be as if
- ; it returns with the value of the child's pid.
-; pshs y ; y has p->p_pid from above, the return value in the parent
-
- ; save kernel stack pointer -- when it comes back in the parent we'll be in
- ; _switchin which will immediately return (appearing to be _dofork()
- ; returning) and with HL (ie return code) containing the child PID.
- ; Hurray.
- ; sts U_DATA__U_SP
-
- ; now we're in a safe state for _switchin to return in the parent
- ; process.
-
- ; --------- we switch stack copies in this call -----------
-; jsr fork_copy ; copy 0x000 to udata.u_top and the
- ; uarea and return on the childs
- ; common
- ; We are now in the kernel child context
-
- ; now the copy operation is complete we can get rid of the stuff
- ; _switchin will be expecting from our copy of the stack.
-; puls y
-
-; ldx fork_proc_ptr
-; jsr _newproc
-
- ; any calls to map process will now map the childs memory
-
- ; runticks = 0;
-; clr _runticks
- ; in the child process, fork() returns zero.
- ;
- ; And we exit, with the kernel mapped, the child now being deemed
- ; to be the live uarea. The parent is frozen in time and space as
- ; if it had done a switchout().
-; rts
-
-fork_copy:
-; ldd U_DATA__U_TOP
-; addd #0x0fff ; + 0x1000 (-1 for the rounding to follow)
-; lsra
-; lsra
-; lsra
-; lsra
-; lsra ; bits 2/1 for 8K pages
-; anda #6 ; lose bit 0
-; adda #2 ; and round up to the next bank (but in 8K terms)
-;
-; ldx fork_proc_ptr
-; ldy P_TAB__P_PAGE_OFFSET,x
-; ; y now points to the child page pointers
-; ldx U_DATA__U_PAGE
-; ; and x to the parent
-;fork_next:
-; ld a,(hl)
-; out (0x11), a ; 0x4000 map the child
-; ld c, a
-; inc hl
-; ld a, (de)
-; out (0x12), a ; 0x8000 maps the parent
-; inc de
-; exx
-; ld hl, #0x8000 ; copy the bank
-; ld de, #0x4000
-; ld bc, #0x4000 ; we copy the whole bank, we could optimise
-; ; further
-; ldir
-; exx
-; call map_kernel ; put the maps back so we can look in p_tab
-; FIXME: can't map_kernel here - we've been playing with the maps, fix
-; directly
-; suba #1
-; bne fork_next
-
-; ld a, c
-; out (0x13), a ; our last bank repeats up to common
- ; --- we are now on the stack copy, parent stack is locked away ---
-; rts ; this stack is copied so safe to return on
-
-
+++ /dev/null
-;
-; 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
-