msx1: the big rework
authorAlan Cox <alan@linux.intel.com>
Sat, 6 Apr 2019 21:35:34 +0000 (22:35 +0100)
committerAlan Cox <alan@linux.intel.com>
Sat, 6 Apr 2019 21:35:34 +0000 (22:35 +0100)
- Pull common and discard etc from ROM into C000-FFFF RAM
- Fix missing interrupt disables in mapping functions
- Various mapping bugfixes
- Turn on sunrise (hardcoded location for now for testing)
- Fix the memory layout

With this lot done and some tool updates we can get the point init makes
syscalls although it doesn't end well shortly after that

Kernel/platform-msx1/README.md
Kernel/platform-msx1/cartridge.s
Kernel/platform-msx1/config.h
Kernel/platform-msx1/crt0.s
Kernel/platform-msx1/devices.c
Kernel/platform-msx1/discard.c
Kernel/platform-msx1/msx1.s
Kernel/platform-msx1/rules.mk
Kernel/platform-msx1/slots.s

index 789104e..8ee91bb 100644 (file)
@@ -11,26 +11,25 @@ Cartridge
 
 0000-3FFF      Fuzix
 4000-7FFF      Fuzix
-8000-BFFF      Fuzix + Bootstrap
-C000-FFFF      Bootloader data
-
+8000-BFFF      Fuzix
+C000-FFFF      Copy of common and other areas for C000-FFFF in RAM
 
 Running
 
 Kernel mode
 
-0000-BFFF      Fuzix
-C000-FFFF      Kernel data + RAM helpers if needed
+0000-BFFF      Fuzix(Cartridge)
+C000-FFFF      Kernel common and data
 
 User mode
 
-0000-BFFF      Process bank
-C000-FFFF      Kernel data + RAM helpers
+0000-BFFF      Process bank (with stubs in spare low bytes)
+C000-FFFF      Kernel common and data
 
 Difficulties
 - Have to map 0x4000-7FFF to a device for some I/O devices so we can't
   always directly do I/O to user space. Kernel buffers are high so ok.
-  Kernel I/O routines can live in other 16K chunks
+  Kernel I/O routines can live in other 16K chunks or common.
 
 - We have to load the cartridge header at 0x4000 or 0x8000 - neither is at
   all convenient!
@@ -51,15 +50,15 @@ Disk I/O routines need bounce buffers for 4000-7FFF range due to the
 limited mapping system.
 Speed up all the ei/di mess by just keeping a private variable for irqoff
 state
+Get common and discard and initialized in C000-FFFF of the ROM and copied
+out
 
 In Progress
 
 Move the switch helper into both banks so we can fix the FIXME in map_kernel
-
 Work out how map/unmap an I/O device needs to work to be usable. Do we grab
 the live map and just edit it for 4000-7FFF then set that map ? Do we
 precompute and save kernel and user maps for the device ?
-
 Sunrise IDE support
 
 To do
@@ -69,10 +68,6 @@ Sensible user copy routines: We know kernel data is always in common except
 some awkward corner cases (constants) going K->U. So we can spot the to user
 case of a 'low' source and bounce it or similar, while just doing a user
 map and ldir for the others. We badly need the cached path walk though!
-Get common and discard and initialized in C000-FFFF of the ROM
-Then on boot up move SP to BFFF, map the ROM in the top 16K, copy it into
-8000-Bxxx and then restore the RAM, and copy it up. Then do the normal maps.
-Otherwise we are going to run out of space at some point.
 Remember current map for kernel/user so we can fast track map_save/restore
 map_kernel etc by knowing if we are mapping k->k u->u or a transition and
 we can label all other cases with a value meaning 'other' as we don't need
index 5364e74..5d3944f 100644 (file)
@@ -21,8 +21,8 @@
                .globl kstack_top
 
 ;
-;      We are running in an unknown subslot of an unknown bank and
-;      have 4000-BFFF mapped to us, BIOS (0:0) in the low 16K and
+;      We are running in an unknown subslot of an unknown slot and
+;      have 4000-7FFF mapped to us, BIOS (0:0) in the low 16K and
 ;      RAM ought to be in the top 16K because the BIOS needs it. We
 ;      can't btw even assume that all the RAM is in the same bank - what a
 ;      mess!
@@ -38,7 +38,6 @@ EXPTBL                .equ 0xFCC1
 SLTTBL         .equ 0xFCC5
 SLTATR         .equ 0xFCC9
 
-
 pstring:
                ld a,(hl)
                or a
@@ -102,7 +101,7 @@ ripple:
 
 expan:         .asciz 'expanded'
                
-wtfami:                ld sp,#0xF000           ; random free space in known RAM
+wtfami:                ld sp,#0xF380           ; below system variables
                ;
                ;       Initialize the debug port
                ;
@@ -114,7 +113,86 @@ wtfami:            ld sp,#0xF000           ; random free space in known RAM
                ld hl,#hello
                call pstring
 
+               ; We'd like the use the ROM services but unfortunately they
+               ; don't actually work for the top 16K in MSX
+
+               ld ix,#0xffff           ; subslot control byte
+
                di
+               ld a,(ix)
+               cpl                     ; remember the old subslot mapping
+                                       ; for the RAM top 16K
+               ld e,a
+               in a,(0xA8)
+               ld d,a                  ; Remember the old slot mapping
+               and #0x0C               ; This is the mapping for the cartridge
+               rla
+               rla
+               rla                     ; move it to the top 2 bits
+               rla
+               ld b,a
+               in a,(0xA8)
+               and #0x3F
+               or b
+               ld b,a
+               out (0xA8),a            ; cartridge mapped in top 16K not stack
+               ld a,(ix)
+               cpl
+               and #0x0c               ; cartridge subslot if any
+               rla
+               rla
+               rla
+               rla
+               ld c,a                  ; save the bits
+               ld a,(0xffff)
+               cpl
+               and #0x3f               ; mask off top 16K map
+               or c
+               ld c,a
+
+               ; At this point D/E get us the RAM mapping
+               ; C/B the ROM mapping
+               ; We could both be in the same slot so we have to do all the
+               ; painful stupid stuff 8(
+
+               ld a,d
+               out (0xA8),a
+               ld (ix),e
+
+               ld a,d
+               call phex
+               ld a,e
+               call phex
+               ld a,b
+               call phex
+               ld a,c
+               call phex
+               exx
+
+               ld hl,#0xC000
+               ld bc,#0x3300
+
+copy_common_loop:
+               exx                     ; Paging values
+               ld a,b                  ; Map cartridge
+               out (0xA8),a
+               ld (ix),c
+               exx                     ; Work values
+               ld e,(hl)               ; Fetch byte
+               exx                     ; Paging values
+               ld a,d                  ; Map RAM
+               out (0xA8),a
+               ld (ix),e
+               exx                     ; Work values
+               ld (hl),e               ; Save to RAM
+               inc hl                  ; Move on
+               dec bc
+               ld a,b
+               or c
+               jr nz, copy_common_loop
+
+               ; RAM is what is left mapped
+
                ;
                ;       Save a few things before we give the ROM the boot
                ;       We keep them in the alt registers
@@ -184,23 +262,23 @@ mapped:
 
                ; Begin by setting up our RAM as a normal ROM based SDCC
                ; process (for a change!)
-               ld hl,#s__INITIALIZER
-               ld de,#s__INITIALIZED
-               ld bc,#l__INITIALIZER
-               ldir
-               ; Now unpack the common space
-               ld de,#s__COMMONMEM
-               ld bc,#l__COMMONMEM
-               ldir
-               ; Wipe the BSS area
-               ld hl,#s__DATA
-               ld d,h
-               ld e,l
-               ld (hl),#0
-               ld bc,#l__DATA
-               inc de
-               dec bc
-               ldir
+;              ld hl,#s__INITIALIZER
+;              ld de,#s__INITIALIZED
+;              ld bc,#l__INITIALIZER
+;              ldir
+;              ; Now unpack the common space
+;              ld de,#s__COMMONMEM
+;              ld bc,#l__COMMONMEM
+;              ldir
+;              ; Wipe the BSS area
+;              ld hl,#s__DATA
+;              ld d,h
+;              ld e,l
+;              ld (hl),#0
+;              ld bc,#l__DATA
+;              inc de
+;              dec bc
+;              ldir
                ; Switch to the right stack
                ld sp,#kstack_top
                call init_early
index 53f0694..4826818 100644 (file)
@@ -56,7 +56,7 @@ extern unsigned int swap_dev;
 #define BOOTDEVICENAMES "hd#,fd,,rd"
 
 //#define CONFIG_DYNAMIC_BUFPOOL /* we expand bufpool to overwrite the _DISCARD segment at boot */
-#define NBUFS    6        /* Number of block buffers, keep in line with space reserved in zeta-v2.s */
+#define NBUFS    5        /* Number of block buffers, keep in line with space reserved in zeta-v2.s */
 #define NMOUNTS         2        /* Number of mounts at a time */
 
 #define MAX_BLKDEV 2       /* IDE or SD ?? */
index 9831e26..6867cad 100644 (file)
@@ -7,10 +7,7 @@
                .area _HOME
                .area _VIDEO
                .area _CONST
-               .area _DISCARD
-               ; ROM section must end with the initializer
-               .area _INITIALIZER
-               ; These are unpacked
+               ; RAM based
                .area _COMMONMEM
                .area _INITIALIZED
                .area _GSINIT
                .area _BSS
                .area _HEAP
                .area _DATA
+               ; Need to do dynamic buffers yet
+               .area _DISCARD
+               .area _INITIALIZER
 
-               ; imported symbols
-               .globl _fuzix_main
-               .globl init_early
-               .globl init_hardware
-               .globl s__DATA
-               .globl l__DATA
-               .globl s__DISCARD
-               .globl l__DISCARD
-               .globl s__COMMONMEM
-               .globl l__COMMONMEM
-               .globl s__INITIALIZER
-               .globl kstack_top
                .globl interrupt_handler
                .globl null_handler
 
+               .globl do_set_sub_slot
+               .globl do_get_sub_slot
+
                .globl rst38            ; for checking
 ;
 ;      First _CODE section
 ;
-;      We need to put the bank switch stub in here and matching in RAM
+;      We put the bank switch stub in here and matching in RAM
 ;
                .area _CODE
 
 start:         jp null_handler
                .ds 0x35
 rst38:         jp interrupt_handler
-               ; FIXME NMI etc ?
+               ; We only have 0x3B-0x4F free
+do_set_sub_slot:
+               in e,(c)                ; Get bank map
+               out (c),b               ; Set bank map
+               ld (hl),a               ; Set slots
+               jr do_get_sub_slot_2
+do_get_sub_slot:
+               in e,(c)
+               out (c),b
+do_get_sub_slot_2:                     ; Get complemented slot bits
+               ld a,(hl)
+               out (c),e
+               ret
+               ; 4A-4F free
+
+; Just so we don't pack the binary
+
+               .area _PAGE0
index 8bd58b1..3de288a 100644 (file)
@@ -104,5 +104,5 @@ void device_init(void)
     keyrepeat.first = 2 * ticks_per_dsecond;
     keyrepeat.continual = 1 * ticks_per_dsecond;
 
-//    sunrise_probe(2,3);
+    sunrise_probe(1,0xFF);
 }
index c0ad3ec..95223dd 100644 (file)
@@ -23,15 +23,20 @@ void map_init(void)
   uint8_t *rp;
   uint8_t i;
   uint8_t pp;
+  uint8_t cp;
   const char *vdpname = "??";
   
   if (vdptype < 3)
     vdpname = vdpnametab[vdptype];
 
+  cp = bp[5] & 3;
+
   kprintf("VDP %s@%x\n", vdpname, vdpport);  
   kprintf("Subslots %x\n", subslots);
-
-  kprintf("Kernel map %x %x %x %x %x %x\n",
+  kprintf("Cartridge in slot %d", cp);
+  if (subslots &  (1 << cp))
+    kprintf(".%d", bp[cp] & 3);
+  kprintf("\nKernel map %x %x %x %x %x %x\n",
     *bp, bp[1], bp[2], bp[3], bp[4], bp[5]);
     
   bp = current_map;
@@ -75,6 +80,8 @@ void map_init(void)
 void platform_discard(void)
 {
     /* Until we tackle the buffers */
+    /* Use the old discard space to bounce the vectors to user pages */
+    copy_vectors();
 }
 
 /*
index bb32b43..c427b3d 100644 (file)
@@ -9,6 +9,7 @@
             .globl init_hardware
             .globl interrupt_handler
             .globl _program_vectors
+           .globl _copy_vectors
            .globl _set_initial_map
            .globl _need_resched
 
@@ -23,7 +24,7 @@
             .globl _platform_reboot
            .globl nmi_handler
            .globl null_handler
-           .globl map_process
+           .globl map_process_always
            .globl map_kernel
            .globl _vdp_load_font
 
@@ -48,6 +49,8 @@
            ;
            .globl vdpinit
 
+           .globl s__DISCARD
+
             .include "kernel.def"
             .include "../kernel-z80.def"
 
@@ -84,6 +87,8 @@ _need_resched:
 init_early:
            ld a, #'*'
            out (0x2F), a
+           ld a, #'-'
+           call outchar
            ; called with e'=vdp d'=machine type
            ; HL info bits
            exx
@@ -112,7 +117,7 @@ init_hardware:
            ; Program the video engine
 
            ld bc,(_vdpport)
-           ; Play with statius register 2
+           ; Play with status register 2
            dec c
            ld a,#0x8F
            out (c),a
@@ -161,52 +166,13 @@ vdp_setup:
 
             ret
 
+_program_vectors:
+           ret
 
 ;------------------------------------------------------------------------------
 ; COMMON MEMORY PROCEDURES FOLLOW
 
             .area _COMMONMEM
-
-_program_vectors:
-            ; we are called, with interrupts disabled, by both newproc() and crt0
-           ; will exit with interrupts off
-            di ; just to be sure
-            pop de ; temporarily store return address
-            pop hl ; function argument -- base page number
-            push hl ; put stack back as it was
-            push de
-
-           ; At this point the common block has already been copied
-           call map_process
-
-            ; write zeroes across all vectors
-           ; on MSX this is probably the wrong thing to do!!! FIXME
-            ld hl, #0
-            ld de, #1
-            ld bc, #0x007f ; program first 0x80 bytes only
-            ld (hl), #0x00
-            ldir
-
-            ; now install the interrupt vector at 0x0038
-            ld a, #0xC3 ; JP instruction
-            ld (0x0038), a
-            ld hl, #interrupt_handler
-            ld (0x0039), hl
-
-            ; set restart vector for Fuzix system calls
-            ld (0x0030), a   ;  (rst 30h is unix function call vector)
-            ld hl, #unix_syscall_entry
-            ld (0x0031), hl
-
-            ld (0x0000), a   
-            ld hl, #null_handler   ;   to Our Trap Handler
-            ld (0x0001), hl
-
-            ld (0x0066), a  ; Set vector for NMI
-            ld hl, #nmi_handler
-            ld (0x0067), hl
-           jp map_kernel
-
 ; emulator debug port for now
 outchar:
            push af
@@ -214,3 +180,15 @@ outchar:
            pop af
             ret
 
+_copy_vectors:
+           ld hl,#0
+           ld de,#s__DISCARD
+           ld bc,#256
+           ldir
+           call map_process_always
+           dec h               ; pointers back
+           dec d
+           inc b               ; bc = 256
+           ex de,hl            ; swap so we copy back
+           ldir                ; into user
+           jp map_kernel
index 0513d8d..3d92a17 100644 (file)
@@ -1,16 +1,15 @@
 #
-# Push the execve code high to make room
-#
 export CROSS_CC_SEG1=--codeseg CODE2
-export CROSS_CC_SEG2=--codeseg CODE
+export CROSS_CC_SEG2=--codeseg CODE2
 export CROSS_CC_SEG3=--codeseg CODE
-export CROSS_CC_VIDEO=--codeseg CODE
-export CROSS_CC_FONT=--codeseg CODE
+export CROSS_CC_VIDEO=--codeseg CODE2
+# We load the font at start up
+export CROSS_CC_FONT=--codeseg DISCARD --constseg DISCARD
 #
 export CROSS_CC_SYS1=--codeseg CODE
-export CROSS_CC_SYS2=--codeseg CODE2
+export CROSS_CC_SYS2=--codeseg CODE
 export CROSS_CC_SYS3=--codeseg CODE2
 export CROSS_CC_SYS4=--codeseg CODE2
-export CROSS_CC_SYS5=--codeseg COMMONMEM
+export CROSS_CC_SYS5=--codeseg CODE
 export CROSS_CC_SEGDISC=--codeseg DISCARD
 
index a2ffe3f..7618eb1 100644 (file)
         .globl _ramsize
         .globl _procmem
        .globl ___hard_di
+       .globl outcharhex
+
+;
+;      Our helpers put the top bank back before returning so the rest
+;      can be generalized in common space
+;
+       .area _COMMONMEM
+
+       .globl _switch_map
+       .globl _current_map
+       .globl map_kernel
+       .globl map_kernel_di
+       .globl map_process_always
+       .globl map_process_always_di
+       .globl map_process
+       .globl map_save_kernel
+       .globl map_restore
+       .globl _set_initial_map
+       .globl _map_slot1_kernel
+       .globl _map_slot1_user
+       .globl find_ram
+       .globl _ramtab
+       .globl _kernel_map
+       .globl _user_map
+       .globl _current_map
+
+       .globl _subslots
+       .globl _int_disabled
+
+       .globl do_set_sub_slot
+       .globl do_get_sub_slot
 
 ;
 ;      Memory banking for a 'simple' MSX 1 system. We have Fuzix in a
@@ -21,8 +52,8 @@
 ;      other non MSX2 style mappers. (For an MSX2 mapper it would I think
 ;      be better to teach the MSX2 code about different VDP options).
 ;
-;      This is our little helper that needs to live low down. It expects
-;      interrupts to be *off*
+;      Call our little helper who lives low down. It expects interrupts to be
+;      *off*. The stack will be in the top 16K so care is neeed.
 ;
 ;      Entry
 ;      B = computed slot mask
 ;      Return
 ;      A = result of subslot set
 ;
-
-       .area _LOW
+;
 
 set_sub_slot:
        push bc
        push de
+       push hl
        ld c,#0xA8
-       in e,(c)
-       out (c),b               ; map the thing we need to set subslots for
-                               ; into the top 16K
-       ld (0xFFFF),a           ; subslot info
-       ld a,(0xFFFF)           ; report back the effect
-       cpl                     ; remembering it's complemented
-       out (c),e
+       ld hl,#0xffff
+       call do_set_sub_slot
+       cpl
+       pop hl
        pop de
        pop bc
        ret
@@ -52,43 +80,17 @@ set_sub_slot:
 get_sub_slot:
        push bc
        push de
+       push hl
        ld c,#0xA8
-       in e,(c)
-       out (c),b               ; map the thing we need to set subslots for
-                               ; into the top 16K
-       ld a,(0xFFFF)           ; report back the effect
-       cpl                     ; remembering it's complemented
-       out (c),e
+       ld hl,#0xffff
+       call do_get_sub_slot
+       cpl
+       pop hl
        pop de
        pop bc
        ret
 
-;
-;      Our helpers put the top bank back before returning so the rest
-;      can be generalized in common space
-;
-       .area _COMMONMEM
-
-       .globl _switch_map
-       .globl _current_map
-       .globl map_kernel
-       .globl map_kernel_di
-       .globl map_process_always
-       .globl map_process_always_di
-       .globl map_process
-       .globl map_save_kernel
-       .globl map_restore
-       .globl _set_initial_map
-       .globl _map_slot1_kernel
-       .globl _map_slot1_user
-       .globl find_ram
-       .globl _ramtab
-       .globl _kernel_map
-       .globl _user_map
-       .globl _current_map
 
-       .globl _subslots
-       .globl _int_disabled
 
 ;
 ;      Switch to the map pointed to by HL.
@@ -119,7 +121,7 @@ _switch_map:
        push bc
        push de
        ld a,#'['
-       out (0x2F),a
+;      out (0x2F),a
        in a,(0xA8)
        and #0x3F                       ;       Keep the lower selections
        ld b,a                          ;       the same
@@ -134,9 +136,9 @@ subslot_next:
        cp (hl)
        jr z, subslot_done              ;       same subslots
        ld a,b
-       call phex
+;      call outcharhex
        ld a,(hl)
-       call phex
+;      call outcharhex
        ; Do set
        call set_sub_slot
        ld (de),a                       ;       update map
@@ -157,7 +159,7 @@ subslot_done:
        ld (de),a
        out (0xA8),a
        ld a,#']'
-       out (0x2F),a
+;      out (0x2F),a
        pop de
        pop bc
        pop af
@@ -290,9 +292,6 @@ map_save_kernel:
        call map_kernel_di              ; FIXME: fast path this later
        ret
 
-; This is messy because of the NMOS Z80 IRQ bug. It might be worth
-; revisiting all the logic that uses this and just keeping a software flag
-; instead.
 ;
 ; The expensive bank switching also means we need to write some custom
 ; usermem copiers.
@@ -303,6 +302,7 @@ map_save_kernel:
 map_kernel:
        push af
        push hl
+       di
        ld a,(_int_disabled)
        push af
        xor a
@@ -333,6 +333,7 @@ map_kernel_di:
        ; kernel low mapping back. FIXME: if the kernel cartridge and
        ; RAM are in the same subslot this will break. Need to put the flip
        ; code in the low 256 bytes of both.
+       ; (DONE OK now I think)
        ld a,(_kernel_map+5)
        out (0xA8),a
        ld hl,#_kernel_map
@@ -349,6 +350,7 @@ map_process:
 map_process_always:
        push af
        push hl
+       di
        ld a,(_int_disabled)
        push af
        ld a,#1
@@ -391,13 +393,13 @@ map_slot_1:
        ld a,l
        ; First step: Update the slot register in the map
        and #0x03                       ; slot
-       rlca
-       rlca
+       rla
+       rla
        ld e,a
-       ld a, (_scratch_map + 4)        ; slot register
+       ld a, (_scratch_map + 5)        ; slot register
        and #0xF3
        or e
-       ld (_scratch_map + 4),a         ; slot register with us in bank 1
+       ld (_scratch_map + 5),a         ; slot register with us in bank 1
        ld e,a                          ; Save it in E
        ld a,l
        bit 7,a
@@ -639,29 +641,3 @@ testram:
 
 _ramtab:
        .ds 6
-
-dophex:                ld c,a
-               and #0xf0
-               rrca
-               rrca
-               rrca
-               rrca
-               call pdigit
-               ld a,c
-               and #0x0f
-pdigit:                cp #10
-               jr c,isl
-               add #7
-isl:           add #'0'
-               out (0x2F),a
-               ret
-
-phex:
-               push af
-               push bc
-               call dophex
-               ld a,#' '
-               out (0x2f),a
-               pop bc
-               pop af
-               ret