v8080: initial bits for 8080 support
authorAlan Cox <alan@linux.intel.com>
Wed, 6 Feb 2019 14:00:41 +0000 (14:00 +0000)
committerAlan Cox <alan@linux.intel.com>
Wed, 6 Feb 2019 14:00:41 +0000 (14:00 +0000)
14 files changed:
Kernel/platform-v8080/Makefile [new file with mode: 0644]
Kernel/platform-v8080/README [new file with mode: 0644]
Kernel/platform-v8080/commonmem.s [new file with mode: 0644]
Kernel/platform-v8080/config.h [new file with mode: 0644]
Kernel/platform-v8080/crt0.s [new file with mode: 0644]
Kernel/platform-v8080/devices.c [new file with mode: 0644]
Kernel/platform-v8080/devtty.c [new file with mode: 0644]
Kernel/platform-v8080/devtty.h [new file with mode: 0644]
Kernel/platform-v8080/end.s [new file with mode: 0644]
Kernel/platform-v8080/kernel.def [new file with mode: 0644]
Kernel/platform-v8080/main.c [new file with mode: 0644]
Kernel/platform-v8080/target.mk [new file with mode: 0644]
Kernel/platform-v8080/tricks.s [new file with mode: 0644]
Kernel/platform-v8080/v8080.s [new file with mode: 0644]

diff --git a/Kernel/platform-v8080/Makefile b/Kernel/platform-v8080/Makefile
new file mode 100644 (file)
index 0000000..3ffcf46
--- /dev/null
@@ -0,0 +1,44 @@
+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
diff --git a/Kernel/platform-v8080/README b/Kernel/platform-v8080/README
new file mode 100644 (file)
index 0000000..9450d49
--- /dev/null
@@ -0,0 +1,38 @@
+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.
+
diff --git a/Kernel/platform-v8080/commonmem.s b/Kernel/platform-v8080/commonmem.s
new file mode 100644 (file)
index 0000000..12fa6f0
--- /dev/null
@@ -0,0 +1,7 @@
+#
+!
+!      Common on z80pack is at 0xF000 as defined by hardware.
+!
+.sect .common
+
+#include "../cpu-8080/std-commonmem.s"
diff --git a/Kernel/platform-v8080/config.h b/Kernel/platform-v8080/config.h
new file mode 100644 (file)
index 0000000..948290a
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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()
diff --git a/Kernel/platform-v8080/crt0.s b/Kernel/platform-v8080/crt0.s
new file mode 100644 (file)
index 0000000..f8fdfef
--- /dev/null
@@ -0,0 +1,63 @@
+.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
diff --git a/Kernel/platform-v8080/devices.c b/Kernel/platform-v8080/devices.c
new file mode 100644 (file)
index 0000000..cd58a3a
--- /dev/null
@@ -0,0 +1,41 @@
+#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);
+}
diff --git a/Kernel/platform-v8080/devtty.c b/Kernel/platform-v8080/devtty.c
new file mode 100644 (file)
index 0000000..0a00c0a
--- /dev/null
@@ -0,0 +1,84 @@
+#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');
+}
diff --git a/Kernel/platform-v8080/devtty.h b/Kernel/platform-v8080/devtty.h
new file mode 100644 (file)
index 0000000..721ffb1
--- /dev/null
@@ -0,0 +1 @@
+extern void tty_pollirq(void);
diff --git a/Kernel/platform-v8080/end.s b/Kernel/platform-v8080/end.s
new file mode 100644 (file)
index 0000000..a25f6c4
--- /dev/null
@@ -0,0 +1,5 @@
+.sect .common
+
+.define commonend
+
+commonend:
diff --git a/Kernel/platform-v8080/kernel.def b/Kernel/platform-v8080/kernel.def
new file mode 100644 (file)
index 0000000..59ab367
--- /dev/null
@@ -0,0 +1,11 @@
+! 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
diff --git a/Kernel/platform-v8080/main.c b/Kernel/platform-v8080/main.c
new file mode 100644 (file)
index 0000000..0fda5ca
--- /dev/null
@@ -0,0 +1,44 @@
+#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;
+}
+
diff --git a/Kernel/platform-v8080/target.mk b/Kernel/platform-v8080/target.mk
new file mode 100644 (file)
index 0000000..2173aca
--- /dev/null
@@ -0,0 +1 @@
+export CPU = 8080
diff --git a/Kernel/platform-v8080/tricks.s b/Kernel/platform-v8080/tricks.s
new file mode 100644 (file)
index 0000000..c05301b
--- /dev/null
@@ -0,0 +1,4 @@
+#
+
+#include "../kernel-8080.def"
+#include "../lib/8080fixedbank.s"
diff --git a/Kernel/platform-v8080/v8080.s b/Kernel/platform-v8080/v8080.s
new file mode 100644 (file)
index 0000000..1ca06d5
--- /dev/null
@@ -0,0 +1,150 @@
+#
+!
+!      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
+