From 35738e6ae3c8775dc9652c06b20973b87889ce72 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 1 Jan 2015 21:25:15 +0000 Subject: [PATCH] zx128: Preparatory work for banked kernel The goal is to use this as the debug base for getting a bankable kernel image running. --- Kernel/platform-zx128/Makefile | 20 +++++++++------- Kernel/platform-zx128/README | 38 ++++++++++++++++++++++++++++++ Kernel/platform-zx128/commonmem.s | 5 ++-- Kernel/platform-zx128/config.h | 16 ++++++++++++- Kernel/platform-zx128/crt0.s | 39 ++++++++++++++++++++----------- Kernel/platform-zx128/devices.c | 11 +++++++-- Kernel/platform-zx128/fuzix.lnk | 9 +++++-- Kernel/platform-zx128/tricks.s | 19 ++++++++------- Kernel/platform-zx128/zx128.s | 30 +++++++++--------------- 9 files changed, 130 insertions(+), 57 deletions(-) diff --git a/Kernel/platform-zx128/Makefile b/Kernel/platform-zx128/Makefile index 0692ddc5..9f41fa78 100644 --- a/Kernel/platform-zx128/Makefile +++ b/Kernel/platform-zx128/Makefile @@ -1,25 +1,27 @@ -CSRCS = devtty.c - -CSRCS2 = bankzx128.c -CSRCS2 += devices.c main.c devmdv.c +CSRCS = devtty.c bankzx128.c devices.c main.c devmdv.c +DSRCS = ../dev/devide.c ../dev/mbr.c ASRCS = crt0.s zx128.s zxvideo.s microdrive.s ASRCS += tricks.s commonmem.s COBJS = $(CSRCS:.c=.rel) -COBJS2 = $(CSRCS2:.c=.rel) AOBJS = $(ASRCS:.s=.rel) -OBJS = $(COBJS) $(COBJS2) $(AOBJS) +DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS)) +OBJS = $(COBJS) $(AOBJS) $(DOBJS) + +CROSS_CCOPTS += -I../dev/ + +CROSS_CC_SEG3 = --codeseg CODE3 JUNK = $(CSRCS:.c=.lst) $(CSRCS:.c=.asm) $(CSRCS:.c=.sym) $(ASRCS:.s=.lst) $(ASRCS:.s=.sym) $(CSRCS:.c=.rst) $(ASRCS:.s=.rst) all: $(OBJS) $(COBJS): %.rel: %.c - $(CROSS_CC) $(CROSS_CCOPTS) -c $< + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< -$(COBJS2): %.rel: %.c - $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG2) -c $< +$(DOBJS): %.rel: ../dev/%.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEG3) -c $< $(AOBJS): %.rel: %.s $(CROSS_AS) $(ASOPTS) $< diff --git a/Kernel/platform-zx128/README b/Kernel/platform-zx128/README index 41f7651d..afacafd1 100644 --- a/Kernel/platform-zx128/README +++ b/Kernel/platform-zx128/README @@ -1,5 +1,43 @@ An FUZIX target for ZX Spectrum 128. +This is mid rework as a banked platform test be warned. + +The new memory layout looks like this + + +0000-3FFF ROM (we hack it a bit to allow for our RST and IRQ vectors + but in theory we can avoid that) +4000-7FFF Kernel data, common read/write space, constants, common read + only, plenty of space +8000-BFFF _DISCARD area - blown away when we exec init +C000-FFFF + 0: Kernel CODE (full) + 1: Kernel CODE2 (full) + 2: Mapped at 0x8000-0xBFFF + 3: User process + 4: User process + 5: Mapped at 0x4000-0x7FFF + 6: User process + 7: CODE3, Display + Video, Font (fairly full) + +Which gives us the ability to run 16K and 32K processes although we'd need +to do bank exchanges to keep 2 x32K in memory at once (one in 2/3 one in +4/7 and doing a block exchange of the memory). + +Making the base kernel use the low ROM space is surprisingly pointless. We +could just about squash it in with screen at 0x4000 and claim back page 7. + +Moving the entire kernel into a banked cartridge gets us more banks for user +processes but leaves us with common at 0x4000 so its tight below 0x8000 + +The other half of the problem on the ZX Spectrum128 is the fact binaries +must be linked with a different base (0xC000 for 16K, 0x8000 for 32K). + + + + + + Big part of the code was taken from z80pack and msx1 ports. ZX Spectrum has a memory layout like follows: diff --git a/Kernel/platform-zx128/commonmem.s b/Kernel/platform-zx128/commonmem.s index b11fc22d..dc31c24e 100644 --- a/Kernel/platform-zx128/commonmem.s +++ b/Kernel/platform-zx128/commonmem.s @@ -1,7 +1,8 @@ ; -; We need to put commonmem above 0xC000 for multi tasking. +; Multiple app sizes and the fact the kernel and apps share the same banks +; means we need to put this somewhere low ; .module commonmem - .area _COMMONMEM + .area _COMMONDATA .include "../cpu-z80/std-commonmem.s" diff --git a/Kernel/platform-zx128/config.h b/Kernel/platform-zx128/config.h index 69dea05c..fc7b15f0 100644 --- a/Kernel/platform-zx128/config.h +++ b/Kernel/platform-zx128/config.h @@ -1,3 +1,17 @@ +/* Simple IDE interface */ +#define CONFIG_IDE +#define IDE_REG_DATA 0xA3 +#define IDE_REG_ERROR 0xA7 +#define IDE_REG_FEATURES 0xA7 +#define IDE_REG_SEC_COUNT 0xAB +#define IDE_REG_LBA_0 0xAF +#define IDE_REG_LBA_1 0xB3 +#define IDE_REG_LBA_2 0xB7 +#define IDE_REG_LBA_3 0xBB +#define IDE_REG_DEVHEAD 0xBB +#define IDE_REG_STATUS 0xBF +#define IDE_REG_COMMAND 0xBF + /* Enable to make ^Z dump the inode table for debug */ #undef CONFIG_IDUMP /* Enable to make ^A drop back into the monitor */ @@ -37,7 +51,7 @@ #define VT_BOTTOM 23 #define TICKSPERSEC 50 /* Ticks per second */ -#define PROGBASE 0xC000 /* also data base */ +#define PROGBASE 0x8000 /* also data base */ #define PROGLOAD 0xC000 /* also data base */ #define PROGTOP 0xFD00 /* Top of program, base of U_DATA copy */ #define PROC_SIZE 16 /* Memory needed per process */ diff --git a/Kernel/platform-zx128/crt0.s b/Kernel/platform-zx128/crt0.s index 6ac76f8c..9c1f0e12 100644 --- a/Kernel/platform-zx128/crt0.s +++ b/Kernel/platform-zx128/crt0.s @@ -1,29 +1,37 @@ -; 2013-12-18 William R Sowerbutts - .module crt0 - ; Ordering of segments for the linker. - ; WRS: Note we list all our segments here, even though - ; we don't use them all, because their ordering is set - ; when they are first seen. - .area _CODE - .area _COMMONMEM - .area _DATA - .area _VIDEO - .area _CONST - .area _FONT + ; Loaded at 0x4000 and the lowest available RAM (the display we keep + ; in bank 7 and mapped high). + .area _COMMONDATA .area _INITIALIZED + .area _DATA .area _BSEG .area _BSS + ; These are loaded as low as we can in memory. If we are using an + ; interface 1 cartridge then _CONST to the end of _STUBS can live in + ; ROM. Right now we still need to fiddle with RO as we don't use the + ; IM2 hack and we'll need to modify SDCC and the bank linker not to + ; use RST to avoid this. + .area _CONST + .area _COMMONMEM + .area _STUBS .area _HEAP ; note that areas below here may be overwritten by the heap at runtime, so ; put initialisation stuff in here .area _INITIALIZER .area _GSINIT .area _GSFINAL + .area _CODE + .area _CODE2 + ; + ; Code3 sits above the display area along with the font and video + ; code so that they can access the display easily. + ; + .area _CODE3 + .area _VIDEO + .area _FONT + ; Discard is dumped in at 0x8000 and will be blown away later. .area _DISCARD - ; In high space - .area _CODE2 ; imported symbols .globl _fuzix_main @@ -143,3 +151,6 @@ boot_stack .equ 0xc000 stop: halt jr stop + .area _STUBS +stubs: + .ds 384 diff --git a/Kernel/platform-zx128/devices.c b/Kernel/platform-zx128/devices.c index f95fde5e..faa08211 100644 --- a/Kernel/platform-zx128/devices.c +++ b/Kernel/platform-zx128/devices.c @@ -5,13 +5,18 @@ #include #include #include +#include struct devsw dev_tab[] = /* The device driver switch table */ { /* 0: /dev/fd Floppy disc block devices, or microdrive etc */ { mdv_open, mdv_close, mdv_read, mdv_write, no_ioctl }, +#ifdef CONFIG_IDE /* 1: /dev/hd Hard disc block devices */ - { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + { devide_open, no_close, devide_read, devide_write, no_ioctl }, +#else + { no_open, no_close, no_read, no_write, no_ioctl }, +#endif /* 2: /dev/tty TTY devices */ { tty_open, tty_close, tty_read, tty_write, vt_ioctl }, /* 3: /dev/lpr Printer devices */ @@ -33,5 +38,7 @@ bool validdev(uint16_t dev) void device_init(void) { - +#ifdef CONFIG_IDE + devide_init(); +#endif } diff --git a/Kernel/platform-zx128/fuzix.lnk b/Kernel/platform-zx128/fuzix.lnk index 2fcc88b0..2acb80c6 100644 --- a/Kernel/platform-zx128/fuzix.lnk +++ b/Kernel/platform-zx128/fuzix.lnk @@ -1,8 +1,11 @@ -mwxuy +-r -i fuzix.ihx --b _CODE=0x0000 --b _COMMONMEM=0x5B00 +-b _COMMONDATA=0x4000 +-b _CODE=0xC000 -b _CODE2=0xC000 +-b _CODE3=0xDB00 +-b _DISCARD=0x8000 -l z80 platform-zx128/crt0.rel platform-zx128/commonmem.rel @@ -37,4 +40,6 @@ platform-zx128/bankzx128.rel swap.rel devsys.rel platform-zx128/devtty.rel +platform-zx128/devide.rel +platform-zx128/mbr.rel -e diff --git a/Kernel/platform-zx128/tricks.s b/Kernel/platform-zx128/tricks.s index c290a27d..b562fc29 100644 --- a/Kernel/platform-zx128/tricks.s +++ b/Kernel/platform-zx128/tricks.s @@ -251,13 +251,6 @@ _dofork: ; to be the live uarea. The parent is frozen in time and space as ; if it had done a switchout(). ret -; -; We can keep a stack in common because we will complete our -; use of it before we switch common block. In this case we have -; a true common so it's even easier. -; - .ds 128 -_swapstack: ; ; This is related so we will keep it here. Copy the process memory @@ -267,12 +260,16 @@ _swapstack: ; ; Assumption - fits into a fixed number of whole 256 byte blocks ; +; +; Note: this needs reviewing. We now have a lot more program memory +; we can use with a lazy copying model +; bankfork: ; ld bc, #(0x4000 - 768) ; 16K minus the uarea stash ld b, #0x3D ; 40 x 256 minus 3 sets for the uarea stash - ld hl, #0xC000 ; base of memory to fork (vectors included) bankfork_1: + ld hl, #0xC000 ; base of memory to fork (vectors included) push bc ; Save our counter and also child offset push hl ld bc, #0x7ffd @@ -302,5 +299,11 @@ bankfork_1: ; ; For the moment ; + .area _COMMONDATA bouncebuffer: .ds 256 +; We can keep a stack in common because we will complete our +; use of it before we switch common block. In this case we have +; a true common so it's even easier. We never use both at once +; so share with bouncebuffer +_swapstack: diff --git a/Kernel/platform-zx128/zx128.s b/Kernel/platform-zx128/zx128.s index 1699fd11..12d3c4e0 100644 --- a/Kernel/platform-zx128/zx128.s +++ b/Kernel/platform-zx128/zx128.s @@ -1,15 +1,7 @@ ; ; ZX Spectrum 128 hardware support -; -; -; This goes straight after udata for common. Because of that the first -; 256 bytes get swapped to and from disk with the uarea (512 byte disk -; blocks). This isn't a problem but don't put any variables in here. -; -; If you make this module any shorter, check what follows next ; - .module zx128 ; exported symbols @@ -44,7 +36,7 @@ .include "../kernel.def" ; ----------------------------------------------------------------------------- -; COMMON MEMORY BANK (0xF000 upwards) +; COMMON MEMORY BANK (below 0xC000) ; ----------------------------------------------------------------------------- .area _COMMONMEM @@ -52,8 +44,6 @@ _trap_monitor: di halt - ld a, #128 - ; out (29), a ; TODO: go where? BASIC48? platform_interrupt_all: ret @@ -61,7 +51,7 @@ _trap_reboot: rst 0 ; ----------------------------------------------------------------------------- -; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped) +; KERNEL MEMORY BANK (above 0xC000, only accessible when the kernel is mapped) ; ----------------------------------------------------------------------------- .area _CODE @@ -157,6 +147,15 @@ map_restore: ld a, (map_store) jr switch_bank + +; outchar: TODO: add something here (char in A). Current port #15 is emulator stub +outchar: + out (#0x15), A + ret +_kernel_flag: + .db 1 + + .area _COMMONDATA current_map: ; place to store current page number. Is needed .db 0 ; because we have no ability to read 7ffd port ; to detect what page is mapped currently @@ -169,10 +168,3 @@ place_for_b: ; And BC - here .db 0 place_for_c: .db 0 - -; outchar: TODO: add something here (char in A). Current port #15 is emulator stub -outchar: - out (#0x15), A - ret -_kernel_flag: - .db 1 \ No newline at end of file -- 2.34.1