#export CPU = 6502
#export TARGET=atarist
#export CPU = 68000
+#export TARGET = 8086test
+#export CPU = 8086
+
export VERSION = "0.1"
export SUBVERSION = "ac1"
export ASMEXT = .s
export BINEXT = .o
export BITS=16
-else
+else ifeq ($(CPU),68000)
export CROSS_LD=m68k-linux-gnu-ld
export CROSS_CC = m68k-linux-gnu-gcc
export CROSS_CCOPTS=-c -fno-builtin -Wall -Os -m68000 -mshort -I$(ROOT_DIR)/cpu-68000 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
export ASMEXT = .S
export BINEXT = .o
export BITS=32
+else
+export CROSS_LD=ld86
+export CROSS_CC = bcc
+export CROSS_CCOPTS=-c -ansi -0 -O -I$(ROOT_DIR)/cpu-8086 -I$(ROOT_DIR)/platform-$(TARGET) -I$(ROOT_DIR)/include
+export CROSS_AS=$(CROSS_CC) $(CROSS_CCOPTS)
+export CROSS_CC_SEG1=
+export CROSS_CC_SEG2=
+export CROSS_CC_SEG3=
+# Fixme: we should split discard off
+export CROSS_CC_SEGDISC=
+export CROSS_CC_VIDEO=
+export ASOPTS=
+export ASMEXT = .S
+export BINEXT = .o
+export BITS=16
endif
ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
--- /dev/null
+typedef unsigned long uint32_t;
+typedef signed long int32_t;
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef signed int size_t;
+
+typedef uint8_t irqflags_t;
+
+typedef int16_t arg_t;
+typedef uint16_t uarg_t; /* Holds arguments */
+typedef uint16_t usize_t; /* Largest value passed by userspace */
+typedef int16_t susize_t;
+typedef uint16_t uaddr_t;
+
+#define __fastcall__
+extern void ei(void);
+extern irqflags_t di(void);
+extern void irqrestore(irqflags_t f);
+
+extern void * memcpy(void *, void *, size_t);
+extern void * memset(void *, int, size_t);
+extern size_t strlen(const char *);
+
+#define EMAGIC 0x4C /* Header of executable (JMP) */
+#define EMAGIC_2 0x38 /* SEC BCS foo */
+/* We use SEC BCS not CLC BCC because CLC is 0x18 which is the Z80 JR header
+ so the two would be identical - not good! */
+
+
+/* High byte is saved, low byte is a mystery so take worst case. Also allow
+ a bit less as C stack is not return stack */
+#define brk_limit() ((((uint16_t)udata.u_syscall_sp) | 0xFF) - 384)
+
+#define staticfast static
+
+/* User's structure for times() system call */
+typedef unsigned long clock_t;
+
+typedef struct {
+ uint32_t low;
+ uint32_t high;
+} time_t;
+
+typedef union { /* this structure is endian dependent */
+ clock_t full; /* 32-bit count of ticks since boot */
+ struct {
+ uint16_t low; /* 16-bit count of ticks since boot */
+ uint16_t high;
+ } h;
+} ticks_t;
+
+/* Sane behaviour for unused parameters */
+#define used(x)
+
+/* We don't yet have bank attributes and banking for 6502 */
+#define CODE1
+#define CODE2
+#define COMMON
+#define VIDEO
+#define DISCARD
+
+
+#define const
--- /dev/null
+#ifndef __STDBOOL_H
+#define __STDBOOL_H
+
+typedef unsigned char bool;
+
+#define true 1
+#define false 0
+#endif
--- /dev/null
+
+CSRCS = devlpr.c devtty.c devrd.c
+CSRCS += devices.c main.c libc.c
+
+#ASRCS = p8086.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 -0 -i crt0.o commonmem.o \
+ p8086.o ../start.o ../version.o ../lowlevel-8086.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
+8086 test sketching out
+
+Getting the bcc compiler bits working. Ideally we'll switch to pcc once it
+works
--- /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
+#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 (dptr & 0x1FF) {
+ 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);
+}
+
+bool tty_writeready(uint8_t minor)
+{
+ uint8_t c;
+ if (minor == 1)
+ return 1;
+ c = *uartb;
+ return c & 1;
+}
+
+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 void kbd_interrupt(void);
+extern void tty_interrupt(void);
+
+#define KEY_ROWS 8
+#define KEY_COLS 10
+
+extern uint16_t keymap[8];
+extern uint8_t keyboard[8][10];
+extern uint8_t shiftkeyboard[8][10];
+
+
+#endif
--- /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)
+{
+}