From: Alan Cox Date: Wed, 6 Feb 2019 14:00:41 +0000 (+0000) Subject: v8080: initial bits for 8080 support X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=68be44536b5c3bd1a94dc80a75fa553b33d99663;p=FUZIX.git v8080: initial bits for 8080 support --- diff --git a/Kernel/platform-v8080/Makefile b/Kernel/platform-v8080/Makefile new file mode 100644 index 00000000..3ffcf46c --- /dev/null +++ b/Kernel/platform-v8080/Makefile @@ -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 index 00000000..9450d49e --- /dev/null +++ b/Kernel/platform-v8080/README @@ -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 index 00000000..12fa6f00 --- /dev/null +++ b/Kernel/platform-v8080/commonmem.s @@ -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 index 00000000..948290af --- /dev/null +++ b/Kernel/platform-v8080/config.h @@ -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 index 00000000..f8fdfef3 --- /dev/null +++ b/Kernel/platform-v8080/crt0.s @@ -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 index 00000000..cd58a3aa --- /dev/null +++ b/Kernel/platform-v8080/devices.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +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 index 00000000..0a00c0a6 --- /dev/null +++ b/Kernel/platform-v8080/devtty.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + +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 index 00000000..721ffb18 --- /dev/null +++ b/Kernel/platform-v8080/devtty.h @@ -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 index 00000000..a25f6c4c --- /dev/null +++ b/Kernel/platform-v8080/end.s @@ -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 index 00000000..59ab3678 --- /dev/null +++ b/Kernel/platform-v8080/kernel.def @@ -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 index 00000000..0fda5ca2 --- /dev/null +++ b/Kernel/platform-v8080/main.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +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 index 00000000..2173acaf --- /dev/null +++ b/Kernel/platform-v8080/target.mk @@ -0,0 +1 @@ +export CPU = 8080 diff --git a/Kernel/platform-v8080/tricks.s b/Kernel/platform-v8080/tricks.s new file mode 100644 index 00000000..c05301bf --- /dev/null +++ b/Kernel/platform-v8080/tricks.s @@ -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 index 00000000..1ca06d54 --- /dev/null +++ b/Kernel/platform-v8080/v8080.s @@ -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 +