zx128: Preparatory work for banked kernel
authorAlan Cox <alan@linux.intel.com>
Thu, 1 Jan 2015 21:25:15 +0000 (21:25 +0000)
committerAlan Cox <alan@linux.intel.com>
Thu, 1 Jan 2015 21:25:15 +0000 (21:25 +0000)
The goal is to use this as the debug base for getting a bankable kernel
image running.

Kernel/platform-zx128/Makefile
Kernel/platform-zx128/README
Kernel/platform-zx128/commonmem.s
Kernel/platform-zx128/config.h
Kernel/platform-zx128/crt0.s
Kernel/platform-zx128/devices.c
Kernel/platform-zx128/fuzix.lnk
Kernel/platform-zx128/tricks.s
Kernel/platform-zx128/zx128.s

index 0692ddc..9f41fa7 100644 (file)
@@ -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) $<
index 41f7651..afacafd 100644 (file)
@@ -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:
index b11fc22..dc31c24 100644 (file)
@@ -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"
index 69dea05..fc7b15f 100644 (file)
@@ -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 */
index 6ac76f8..9c1f0e1 100644 (file)
@@ -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
index f95fde5..faa0821 100644 (file)
@@ -5,13 +5,18 @@
 #include <devsys.h>
 #include <vt.h>
 #include <devmdv.h>
+#include <devide.h>
 
 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
 }
index 2fcc88b..2acb80c 100644 (file)
@@ -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
index c290a27..b562fc2 100644 (file)
@@ -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:
index 1699fd1..12d3c4e 100644 (file)
@@ -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