--- /dev/null
+
+CSRCS = devtty.c
+CSRCS += devices.c main.c libc.c
+
+ASRCS = p68000.S crt0.S
+ASRCS += tricks.S
+
+DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c ../dev/devide_discard.c
+DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS))
+
+COBJS = $(CSRCS:.c=$(BINEXT))
+AOBJS = $(ASRCS:.S=.o)
+OBJS = $(COBJS) $(AOBJS)
+
+CROSS_CCOPTS += -I../dev/
+
+JUNK = $(CSRCS:.c=.o) $(ASRCS:.S=.o)
+
+all: $(OBJS)
+
+$(COBJS): %.o: %.c
+ $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+$(AOBJS): %.o: %.S
+ $(CROSS_AS) $(ASOPTS) $< -o $*.o
+
+$(DOBJS): %.rel: ../dev/%.c
+ $(CROSS_CC) $(CROSS_CCOPTS) -c $<
+
+clean:
+ rm -f $(OBJS) $(JUNK) core *~
+
+image:
+ $(CROSS_LD) -M -o ../fuzix.bin \
+ crt0.o \
+ p68000.o ../start.o ../version.o ../lowlevel-68000.o \
+ tricks.o main.o ../timer.o ../kdata.o devices.o \
+ ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o ../buddy.o \
+ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o \
+ ../syscall_fs3.o ../syscall_exec32.o \
+ ../usermem_std-68000.o devtty.o libc.o ../malloc.o > ../fuzix.map
--- /dev/null
+Development subtree for the v68 virtual platform and general 68000
+bootstrap work. There is a lot to do before anything remotely useful will
+happen.
--- /dev/null
+/* Enable to make ^Z dump the inode table for debug */
+#define 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 - for now while we get it booting */
+#undef CONFIG_SINGLETASK
+/* Buddy based MMU */
+#define CONFIG_BUDDY_MMU
+#define BUDDY_NUMLEVEL 9 /* 1 MByte */
+#define BUDDY_BLOCKBITS 12 /* 4K pages */
+#define BUDDY_BLOCKSIZE 4096
+/* FIXME: these should be dynamic */
+#define BUDDY_BASE ((uint8_t *)0x00000) /* Manage the low 1MB */
+#define BUDDY_START ((uint8_t *)0x10000) /* First usable 64K */
+#define BUDDY_TOP ((uint8_t *)0x80000) /* End at 512K - should be 7FFFF ? */
+#define BUDDY_TABLE BUDDY_START /* Pull the table from the pool */
+#define BUDDY_TREESIZE 511 /* 1MB in 4K pages */
+
+#define CONFIG_32BIT
+#define CONFIG_BANKS 1 /* FIXME */
+#define CONFIG_USERMEM_BUDDY /* TODO */
+
+#define TICKSPERSEC 100 /* Ticks per second */
+
+#define BOOT_TTY (512 + 1) /* 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 1
+#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
+#define NBUFS 20 /* Number of block buffers */
+#define NMOUNTS 6 /* Number of mounts at a time */
+
+/* Programs run under MMU with zero base */
+#define PROGBASE 0
--- /dev/null
+/*
+ * Need to wipe BSS etc once we figure out our preferred boot method
+ *
+ * On entry we are loaded at $2000 with the loader and the loaders
+ * supervisor stack below us. We are in supervisor mode and the rest
+ * is our problem.
+ */
+ .globl _start
+.mri 1
+
+start:
+ or #$0700,sr
+ /* FIXME: hard coded ugly */
+ move.l #uarea_block+508,a7
+ bsr init_early
+ bsr init_hardware
+ bsr fuzix_main
+ or #$0700,sr
+stop: bra 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 <devide.h>
+#include <blkdev.h>
+#include <devsys.h>
+#include <tty.h>
+#include <vt.h>
+
+struct devsw dev_tab[] = /* The device driver switch table */
+{
+// minor open close read write ioctl
+// -----------------------------------------------------------------
+ /* 0: /dev/hd Disc block devices */
+ { blkdev_open, no_close, blkdev_read, blkdev_write, blkdev_ioctl },
+ /* 1: /dev/fd 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) + 255)
+ return false;
+ else
+ return true;
+}
+
+void device_init(void)
+{
+ devide_init();
+}
--- /dev/null
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <devtty.h>
+#include <device.h>
+#include <tty.h>
+
+volatile uint8_t *uart_data = (volatile uint8_t *)0xF03000; /* UART data */
+volatile uint8_t *uart_status = (volatile uint8_t *)0xF03010; /* UART status */
+
+unsigned char tbuf1[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},
+};
+
+/* 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 = *uart_status;
+ return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+ *uart_data = c; /* Data */
+}
+
+void tty_setup(uint8_t minor)
+{
+}
+
+int tty_carrier(uint8_t minor)
+{
+ return 1;
+}
+
+void tty_sleeping(uint8_t minor)
+{
+}
+
+/* Currently run off the timer */
+void tty_interrupt(void)
+{
+ uint8_t r = *uart_status;
+ if (r & 0x2) {
+ r = *uart_data;
+ tty_inproc(2,r);
+ }
+}
+
+void platform_interrupt(void)
+{
+ timer_interrupt();
+ tty_interrupt();
+}
--- /dev/null
+#ifndef __DEVTTY_DOT_H__
+#define __DEVTTY_DOT_H__
+
+#define KEY_ROWS 8
+#define KEY_COLS 7
+extern uint8_t keymap[8];
+extern uint8_t keyboard[8][7];
+extern uint8_t shiftkeyboard[8][7];
+
+#endif
--- /dev/null
+#include "cpu.h"
+
+void *memcpy(void *d, const void *s, size_t sz)
+{
+ unsigned char *dp = d;
+ const unsigned char *sp = s;
+ while(sz--)
+ *dp++=*sp++;
+ return d;
+}
+
+void *memset(void *d, int c, size_t sz)
+{
+ unsigned char *p = d;
+ while(sz--)
+ *p++ = c;
+ return d;
+}
+
+size_t strlen(const char *p)
+{
+ const char *e = p;
+ while(*e++);
+ return e-p-1;
+}
+
+int memcmp(const void *a, const void *b, size_t n)
+{
+ const uint8_t *ap = a;
+ const uint8_t *bp = b;
+ while(n--) {
+ if (*ap < *bp)
+ return -1;
+ if (*ap != *bp)
+ return 1;
+ ap++;
+ bp++;
+ }
+ return 0;
+}
--- /dev/null
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+
+void platform_idle(void)
+{
+ /* FIXME: disable IRQ, run tty interrupt, re-enable ? */
+}
+
+void do_beep(void)
+{
+}
+
+/*
+ * MMU initialize
+ */
+
+void pagemap_init(void)
+{
+ /* Allocate the buddy tables and init them */
+ buddy_init();
+}
+
+void map_init(void)
+{
+}
+
+u_block uarea_block[PTABSIZE];
+uaddr_t ramtop;
+
+/* Offsets into the buddy map for each level, byte aligned */
+const uint16_t buddy_level[BUDDY_NUMLEVEL] = {
+ 0, /* 256 4K pages */
+ 256, /* 128 8K pages */
+ 384, /* 64 16K pages */
+ 448, /* 32 32K pages */
+ 480, /* 16 64K pages */
+ 496, /* 8 128K pages */
+ 504, /* 4 256K pages */
+ 508, /* 2 512K pages */
+ 510, /* 1 1MB page */
+};
+
+/*
+ * We can do our fork handling in C for once. The only oddity here is
+ * the fixups to run parent first and avoid needless memory thrashing
+ */
+int16_t dofork(ptptr p)
+{
+ /* Child and parent udata pointers */
+ struct u_data *uc = &uarea_block[p - ptab].u_d;
+ struct u_data *up = udata_ptr;
+ uint32_t *csp = (uint32_t *)(uc + 1);
+ uint32_t *psp = up->u_sp;
+ /* Duplicate the memory maps */
+ if (pagemap_fork(p))
+ return -1;
+ /* Duplicate the udata */
+ memcpy(&uc, &up, sizeof(struct u_data));
+ /* Use the child udata for initializing the child */
+ udata_ptr = uc;
+ newproc(p);
+ udata_ptr = up;
+ /* And return as the parent. The child will return via the
+ fork return path */
+ /* FIXME: stack setup needs correcting */
+//FIXME *--csp = fork_return;
+ uc->u_sp = csp;
+ /* Copy the saved register state over - must match switchin */
+ memcpy(csp - 14, psp - 14, 4 * 14);
+ /* Return as the parent and run it first (backwards to most ports) */
+ p->p_status = P_READY;
+ udata.u_ptab->p_status = P_RUNNING;
+ return p->p_pid;
+}
--- /dev/null
+/*
+ * Lots left to fill in
+ */
+
+ .globl trap_reboot
+ .globl init_early
+ .globl init_hardware
+ .globl program_vectors
+ .globl outchar
+ .globl trap_monitor
+ .globl uarea_block
+
+.mri 1
+trap_reboot:
+trap_monitor:
+ or #0700,sr
+ bra trap_monitor
+
+init_early:
+ lea.l uarea_block,a5 ; udata ptr
+ rts
+
+init_hardware:
+ ; set system RAM size(hadcode hacks for now)
+ move.w #512,d0
+ move.w d0,ramsize
+ sub.w #64,d0 ; Guess for kernel
+ move.w d0,procmem ; guesses for now
+ rts
+
+;
+; Nothing to do in 68000 - all set up once at boot
+;
+program_vectors:
+ rts
+
+;
+; TODO
+;
+map_process_always:
+map_process:
+map_kernel:
+map_restore:
+map_save:
+ rts
+
+; outchar: Wait for UART TX idle, then print the char in d0
+
+outchar:
+ move.w d0,-(sp)
+outcharw:
+ move.b $00F03010,d0
+ btst #1,d0
+ beq outcharw
+ move.w (sp)+,d0
+ move.b d0,$00F03000
+ rts
+
+.section data
+
+kernel_flag: byte 1
--- /dev/null
+#define IDE_IS_MMIO 1 /* MMIO IDE */
+
+#define IDE_REG_DATA 0x00F01000
+#define IDE_REG_ERROR 0x00F01002
+#define IDE_REG_FEATURES 0x00F01002
+#define IDE_REG_SEC_COUNT 0x00F01004
+#define IDE_REG_LBA_0 0x00F01006
+#define IDE_REG_LBA_1 0x00F01008
+#define IDE_REG_LBA_2 0x00F0100A
+#define IDE_REG_LBA_3 0x00F0100C
+#define IDE_REG_DEVHEAD 0x00F0100C
+#define IDE_REG_STATUS 0x00F0100E
+#define IDE_REG_COMMAND 0x00F0100E
+#define IDE_REG_ALTSTATUS 0x00F01010
+#define IDE_REG_CONTROL 0x00F01010
+
+#define ide_select(x)
+#define ide_deselect()
--- /dev/null
+export CPU = 68000
--- /dev/null
+#include "../kernel-68000.def"
+
+
+.globl switchout,switchin,dofork
+
+.mri 1
+
+; 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().
+;
+; This function can have no arguments or auto variables.
+switchout:
+ or #$0700,sr
+ bsr chksigs
+ ; save machine state
+
+ clr.w -(sp) ; 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:
+ movem.l a0-a4/a6/d0-d7,-(sp) ; FIXME: trim to callee saves
+ move.l sp,U_DATA__U_SP(a5) ; this is where the SP is restored in _switchin
+
+ ; set _inint to false
+ clr.b inint
+
+ ; find another process to run (may select this one again)
+ bsr getproc
+
+ move.l a0,-(sp) ; CHECK compiler call/return rules
+ bsr switchin
+
+ ; we should never get here
+ bra trap_monitor
+
+badswitchmsg: ascii "_switchin: FAIL"
+ byte 13,10,0
+swapped: ascii "_switchin: SWAPPED"
+ byte 13,10,0
+
+switchin:
+ or #$0700,sr
+ move.l 4(sp),a0 ; task to switch to
+ move.l P_TAB__P_UDATA_OFFSET(a0),a5
+
+ ; check u_data->u_ptab matches what we wanted
+ move.l 4(sp),d0
+ cmp.l U_DATA__U_PTAB(a5),d0
+ bne switchinfail
+
+ ; wants optimising up a bit
+ move.b #P_RUNNING,P_TAB__P_STATUS_OFFSET(a0)
+
+ ; runticks = 0
+ clr.w runticks
+
+ ; restore machine state
+ move.l U_DATA__U_SP(a5),sp
+ movem.l (sp)+,a0-a4/a6/d0-d7 ; FIXME: trim to callee saves here too
+
+ tst.b inint
+ beq keepoff ; in ISR, leave interrupts off
+ and #$F8FF,sr
+keepoff:
+ rts ; return with interrupts on
+
+switchinfail:
+ bsr outa0hex
+ lea badswitchmsg,a0
+ bsr outstring
+ ; something went wrong and we didn't switch in what we asked for
+ bra trap_monitor