--- /dev/null
+LIBPATH=../../Library/libs
+LIBC=$(LIBPATH)/libc8080.a $(ACK_ROOT)/share/ack/cpm/libem.a
+
+CSRCS += devices.c main.c devtty.c
+
+ASRCS = crt0.s commonmem.s v8080.s tricks.s end.s
+
+AOBJS = $(ASRCS:.s=.o)
+COBJS = $(CSRCS:.c=.o)
+
+OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(NOBJS)
+
+JUNK = *.o *.lst *.asm *.sym *.rst
+
+all: $(OBJS)
+
+$(AOBJS): %.o: %.s
+ $(CROSS_AS) $(ASOPTS) $<
+
+$(COBJS): %.o: %.c
+ $(CROSS_CC) $(CROSS_CCOPTS) $<
+
+clean:
+ rm -f $(OBJS) $(JUNK) core *~
+
+image:
+ $(CROSS_LD) -o fuzix.bin crt0.o devices.o main.o \
+ commonmem.o tricks.o v8080.o devtty.o \
+ ../start.o ../version.o ../lowlevel-8080.o \
+ ../bankfixed.o ../timer.o ../kdata.o \
+ ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \
+ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o \
+ ../syscall_fs3.o ../syscall_exec16.o \
+ ../usermem_std-8080.o $(LIBC) end.o
+ ack -o fuzix.raw crt0.o devices.o main.o \
+ commonmem.o tricks.o v8080.o devtty.o \
+ ../start.o ../version.o ../lowlevel-8080.o \
+ ../bankfixed.o ../timer.o ../kdata.o \
+ ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
+ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \
+ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o \
+ ../syscall_fs3.o ../syscall_exec16.o \
+ ../usermem_std-8080.o $(LIBC) end.o
--- /dev/null
+Some initial development code for 8080 support
+
+This is not finished (the block copiers for forking, udata and usermem all
+need writing). In addition
+
+- The C compiler bombs on the adventure game builds
+- The preprocessor can't handle netd or fforth
+- We need signal handler code and kernel IRQ code to save memory temporaries
+ that make the code non-reentrant
+- The asm code for switching needs to save and restore BC
+- The adapted Z80 code in lowlevel and elsewhere assumes that HL is the return
+ but ack uses DE
+- The compiler is too verbose at the moment. In particular it needs
+ - helpers for stack relative fetch and put of 16bits
+ - sub hl,de
+ - the tail code
+ - function entry
+ and
+ - use the call to a jp (hl) trick for indirect calls
+ - not generate pointless entry/exit code when not needed
+ - generate optimized code for and/or where one byte of the 16bits is
+ zero
+ - generate a helper for setting the frame pointer
+
+ More generally it sucks because
+ - it uses BC as a frame pointer instead of tracking HL and using BC
+ as a register variable temporary
+ - it's obsessed with 8 to 16 bit conversion of anything it works on
+ internally
+ - it doesn't know anything about passing the top of arguments in a
+ register (trickier because you put a hole in the frame if you are
+ not careful)
+
+SDCC can almost generate 8080 code so is another possibility if we can't hack
+up. However its codegen isn't that much better although it could also be coaxed
+(and probably more easily) into using helpers. At least it knows how to optimize
+8bit operations and also to use bc and top of stack as temporaries.
+
--- /dev/null
+#
+!
+! Common on z80pack is at 0xF000 as defined by hardware.
+!
+.sect .common
+
+#include "../cpu-8080/std-commonmem.s"
--- /dev/null
+/* We have an RTC */
+#undef CONFIG_RTC
+/* And we can read ToD from it */
+#undef CONFIG_RTC_FULL
+/* 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
+/* Multiple processes in memory at once */
+#define CONFIG_MULTI
+/* Single tasking */
+#undef CONFIG_SINGLETASK
+/* Fixed banking */
+#define CONFIG_BANK_FIXED
+/* 8 48K banks, 1 is kernel */
+#define MAX_MAPS 7
+#define MAP_SIZE 0xC000U
+
+/* Read processes and big I/O direct into process space */
+#define CONFIG_LARGE_IO_DIRECT(x) 1
+
+/* Banks as reported to user space */
+#define CONFIG_BANKS 1
+
+#define TICKSPERSEC 100 /* Ticks per second */
+#define PROGBASE 0x0000 /* also data base */
+#define PROGLOAD 0x0100 /* also data base */
+#define PROGTOP 0xBE00 /* Top of program, base of U_DATA copy */
+#define PROC_SIZE 60 /* Memory needed per process */
+
+#define SWAP_SIZE 0x60 /* 48K in blocks (we actually don't need the low 256) */
+#define SWAPBASE 0x0000 /* We swap the lot in one, include the */
+#define SWAPTOP 0xC000 /* vectors so its a round number of sectors */
+#define MAX_SWAPS 16 /* The full drive would actually be 85! */
+
+#define swap_map(x) ((uint8_t *)(x)) /* Simple zero based mapping */
+
+#define BOOT_TTY (512 + 1)/* Set this to default device for stdio, stderr */
+ /* In this case, the default is the first TTY device */
+
+/* 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 2
+
+#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
+#define SWAPDEV (256 + 1) /* Device for swapping. (FIXME) */
+#define NBUFS 8 /* Number of block buffers */
+#define NMOUNTS 4 /* Number of mounts at a time */
+
+#define platform_discard()
+#define platform_copyright()
--- /dev/null
+.sect .text
+.sect .data
+datastart:
+.sect .bss
+bssstart:
+.sect .common
+commonstart:
+
+.sect .text
+
+.define init
+
+init:
+ di
+ lxi sp,kstack_top
+
+ call init_early
+
+ lxi h,commonend
+ lxi d,commonstart
+ call calcsize
+
+ lxi h,datastart
+ lxi d,commonstart
+
+nextbyte:
+ mov a,m
+ stax d
+ inx h
+ inx d
+ dcx b
+ mov a,b
+ ora c
+ jnz nextbyte
+
+ lxi h,bssstart
+ lxi d,datastart
+ call calcsize
+
+ lxi h,datastart
+ xra a
+wipe:
+ mov m,a
+ inx h
+ dcx b
+ mov a,b
+ ora c
+ jnz wipe
+
+ call init_hardware
+ call _fuzix_main
+ di
+stop: hlt
+ jmp stop
+
+calcsize:
+ mov a,l
+ sub e
+ mov c,a
+ mov a,h
+ sbb d
+ mov b,a
+ ret
--- /dev/null
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <tty.h>
+#include <devsys.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 */
+ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl },
+ /* 1: /dev/hd Hard disc block devices (absent) */
+ { no_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, sys_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)
+{
+ int i;
+ /* Add 64 swaps (4MB) to use the entire J drive */
+ for (i = 0; i < MAX_SWAPS; i++)
+ swapmap_init(i);
+}
--- /dev/null
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <tty.h>
+#include <devtty.h>
+
+static char tbuf1[TTYSIZ];
+static char tbuf2[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 },
+ { tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ/2 },
+};
+
+static tcflag_t console_mask[4] = {
+ _ISYS,
+ _OSYS,
+ _CSYS,
+ _LSYS
+};
+
+/* TODO: stty support for the Z180 ports */
+tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
+ NULL,
+ console_mask,
+ console_mask,
+};
+
+void tty_setup(uint8_t minor, uint8_t flags)
+{
+ minor;
+}
+
+/* For the moment */
+int tty_carrier(uint8_t minor)
+{
+ minor;
+ return 1;
+}
+
+void tty_pollirq(void)
+{
+/* while(ASCI_STAT0 & 0x80)
+ tty_inproc(1, ASCI_RDR0); */
+}
+
+void tty_putc(uint8_t minor, unsigned char c)
+{
+ switch(minor){
+ case 1:
+/* while(!(ASCI_STAT0 & 2));
+ ASCI_TDR0 = c; */
+ break;
+ case 2:
+/* while(!(ASCI_STAT1 & 2));
+ ASCI_TDR1 = c; */
+ break;
+ }
+}
+
+void tty_sleeping(uint8_t minor)
+{
+ minor;
+}
+
+void tty_data_consumed(uint8_t minor)
+{
+}
+
+ttyready_t tty_writeready(uint8_t minor)
+{
+ minor;
+ return TTY_READY_NOW;
+}
+
+/* kernel writes to system console -- never sleep! */
+void kputchar(char c)
+{
+ tty_putc(TTYDEV & 0xFF, c);
+ if(c == '\n')
+ tty_putc(TTYDEV & 0xFF, '\r');
+}
--- /dev/null
+extern void tty_pollirq(void);
--- /dev/null
+.sect .common
+
+.define commonend
+
+commonend:
--- /dev/null
+! UZI mnemonics for memory addresses etc
+
+U_DATA = 0xF400 ! (this is struct u_data from kernel.h)
+U_DATA__TOTALSIZE = 0x200 ! 256+256 bytes.
+
+U_DATA_STASH = 0xEE00 ! EE00-EFFF
+
+PROGBASE = 0x0000
+PROGLOAD = 0x0100
+
+CONFIG_SWAP = 1
--- /dev/null
+#include <kernel.h>
+#include <timer.h>
+#include <kdata.h>
+#include <printf.h>
+#include <devtty.h>
+
+uaddr_t ramtop = PROGTOP;
+
+void pagemap_init(void)
+{
+ int i;
+ for (i = 1; i < 8; i++)
+ pagemap_add(i);
+}
+
+/* On idle we spin checking for the terminals. Gives us more responsiveness
+ for the polled ports */
+void platform_idle(void)
+{
+ /* We don't want an idle poll and IRQ driven tty poll at the same moment */
+ irqflags_t irq = di();
+ tty_pollirq();
+ irqrestore(irq);
+}
+
+void platform_interrupt(void)
+{
+ tty_pollirq();
+ timer_interrupt();
+// netat_poll();
+// netz_poll();
+}
+
+/* Nothing to do for the map of init */
+void map_init(void)
+{
+}
+
+uint8_t platform_param(char *p)
+{
+ used(p);
+ return 0;
+}
+
--- /dev/null
+export CPU = 8080
--- /dev/null
+#
+
+#include "../kernel-8080.def"
+#include "../lib/8080fixedbank.s"
--- /dev/null
+#
+!
+! Low level platform support for v8080
+!
+
+ #include "../kernel-8080.def"
+
+.sect .common
+
+.define _platform_monitor
+.define _platform_reboot
+
+_platform_monitor:
+_platform_reboot:
+ di
+ hlt
+
+.define platform_interrupt_all
+
+platform_interrupt_all:
+ ret
+
+.sect .code
+
+.define init_early
+
+init_early:
+ ret
+
+.define init_hardware
+
+init_hardware:
+ ! Hack for now
+ lxi h,256
+ shld _ramsize
+ lxi h,192
+ shld _procmem
+
+ mvi a,1
+ out 8 ! Timer on
+
+ jmp _program_vectors_k
+
+
+.sect .common
+
+.define _int_disabled
+_int_disabled:
+ .data1 1
+
+.define _program_vectors
+
+_program_vectors:
+ di
+ pop d
+ pop h
+ push h
+ push d
+ call map_process
+ call _program_vectors_k
+ call map_kernel_di
+ ret
+
+_program_vectors_k:
+ mvi a,0xc3
+ sta 0
+ sta 0x30
+ sta 0x66
+ lxi h,null_handler
+ shld 1
+ lxi h,unix_syscall_entry
+ shld 0x31
+ lxi h,nmi_handler
+ shld 0x67
+ ret
+
+!
+! Memory mapping
+!
+.define map_kernel
+.define map_kernel_di
+
+map_kernel:
+map_kernel_di:
+ push psw
+ xra a
+ out 0x40
+ pop psw
+ ret
+
+.define map_process
+.define map_process_di
+.define map_process_a
+
+map_process:
+map_process_di:
+ mov a,h
+ ora l
+ jz map_kernel
+ mov a,m
+map_process_a:
+ out 0x40
+ ret
+
+.define map_process_always
+.define map_process_always_di
+
+map_process_always:
+map_process_always_di:
+ push psw
+ lda U_DATA__U_PAGE
+ out 0x40
+ pop psw
+ ret
+
+.define map_save_kernel
+
+map_save_kernel:
+ push psw
+ in 0x40
+ sta map_save
+ xra a
+ out 0x40
+ pop psw
+ ret
+
+.define map_restore
+
+map_restore:
+ push psw
+ lda map_save
+ out 0x40
+ pop psw
+ ret
+
+map_save:
+ .data1 0
+
+.define outchar
+
+outchar:
+ push psw
+outcharw:
+ in 0
+ rar
+ jnc outcharw
+ pop psw
+ out 0
+ ret
+