trs80m1: make trs80-bank more flexible
authorAlan Cox <alan@linux.intel.com>
Thu, 5 Jul 2018 12:01:40 +0000 (13:01 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 5 Jul 2018 12:01:40 +0000 (13:01 +0100)
Rework trs80-bank so that anything that can be represented by

out someport, someconst - kernel bank 1
out someport, someconst - kernel bank 2

out someport, value - user banks

Can be handled with ease.

This code also adds selector support as the second bank type and others can now
be added without much trouble. It's not the whole story as the fork() code
also needs changing and the fast copier is a bit trickier.

Kernel/platform-trs80m1/discard.c
Kernel/platform-trs80m1/trs80-bank.s
Kernel/platform-trs80m1/trs80.h
Kernel/platform-trs80m1/trs80.s

index f80f909..99733a5 100644 (file)
@@ -5,6 +5,7 @@
 #include <kdata.h>
 #include "devfd3.h"
 #include "devgfx.h"
+#include "trs80.h"
 
 void device_init(void)
 {
@@ -22,9 +23,9 @@ void map_init(void)
 {
 }
 
-uint8_t nbanks = 2;    /* Default 2 banks, unless port 94 probe updates */
+uint8_t nbanks;
 
-void pagemap_init(void)
+static void pagemap_init_supermem(void)
 {
  int i = procmem / 32; /* How many banks do we have */
  if (i > MAX_MAPS)
@@ -35,3 +36,27 @@ void pagemap_init(void)
   i--;
  }
 }
+
+/* We have 128K available in the selector, of which 32K is taken up by
+   a bank of kernel, leaving 3 user banks with 192K. For the LNW80 where
+   there will be 64K in the base it's a different story and probably a
+   different port ? */
+static void pagemap_init_selector(void)
+{
+ int i = procmem / 32;
+ if (i > MAX_MAPS)
+  i = MAX_MAPS;
+ while(i) {
+  /* 32K bank i, map 0 (I/O in low 16K bank in top 32), banking on */
+  pagemap_add(i << 4 + 8);
+  i--;
+ }
+}
+
+void pagemap_init(void)
+{
+ if (trs80_mapper == MAP_SELECTOR)
+  pagemap_init_selector();
+ else
+  pagemap_init_supermem();
+}
index 67965ff..ad3a10e 100644 (file)
@@ -1,5 +1,5 @@
 ;
-;          TRS 80 banking logic for the Model1 with Supermem
+;          TRS 80 banking logic for the selector board
 ;
 
             .module trs80bank
            .globl map_save_kmap
            .globl map_restore_kmap
            .globl fork_mapsave
+           .globl mapper_init
 
             ; imported symbols
            .globl _program_vectors     
             .globl _ramsize
             .globl _procmem
            .globl vtbufinit
+           .globl _trs80_mapper
 
            .globl s__COMMONMEM
            .globl l__COMMONMEM
@@ -39,6 +41,9 @@ init_hardware:
            push af
            call vtbufinit
            pop af
+           ld a,(_trs80_mapper)
+           or a
+           jr nz, memsize_selector
             ; set system RAM size
            ld hl,#0xFFFF               ; FFFF is free in all our pages
            ld bc,#0xFF43               ; kernel included
@@ -60,9 +65,44 @@ scan_pages_l:
            jr nz, scan_pages_l
 mismatch:                              ; B holds the first page above
                                        ; the limit (4 for 128K etc)
-           dec b
-           dec b                       ; remove kernel
-           ld h,b
+           ld e,b
+           dec e
+           jr scan_done
+
+memsize_selector:
+            ; set system RAM size
+           ld bc,#0x381f
+           ld hl,#0xFFFF               ; free space
+           ld e,#4                     ; only 4 pages to test
+mark_up:
+           out (c),b
+           ld (hl),e
+           ld a,#0xF0                  ; subtract 0x10
+           add b
+           ld b,a
+           dec e
+           jr nz, mark_up
+           ld bc,#0x081f
+           ld e,#1
+scan:
+           out (c),b
+           ld a,(hl)
+           cp e
+           jr nz,scan_done
+           ld a,#0x10
+           add b
+           ld b,a
+           inc e
+           ld a,#5
+           cp e
+           jr nz,scan
+           dec e
+scan_done:
+;
+;      At this point E is the number of external banks we have
+;
+           dec e                       ; one holds kernel code
+           ld h,e
            ld l,#0                     ; effectively * 256
            srl h
            rr  l                       ; * 128
@@ -84,16 +124,43 @@ mismatch:                          ; B holds the first page above
             im 1 ; set CPU interrupt mode
             ret
 
+;
+;      Must live here as we need the mapper set up before we make any
+;      banked calls.
+;
+mapper_init:
+           ld (_trs80_mapper),a
+           or a
+           jr nz, mapper_selector
+           ld hl,#0x0043
+           ld (ksave_map),hl
+           ld (map_reg),hl
+           ld (map_bank1),hl
+           inc h
+           ld (map_bank2),hl
+mapper_selector:
+           ret
 
 ;------------------------------------------------------------------------------
 ; COMMON MEMORY PROCEDURES FOLLOW
 
             .area _COMMONMEM
 
-ksave_map:  .db 0x00   ; saved kernel map version
-map_port:   .db 0x43   ; cheap hack so we can ld bc and out (c),b
-map_reg:    .db 0x00   ; current value written to map register
-map_store:  .db 0x00   ; save value from map_save
+_trs80_mapper:
+           .db 0x01    ; Tell kernel mapper is Selector
+ksave_map:  .db 0x1f
+           .db 0x00    ; saved kernel map version
+map_reg:    .db 0x1f   ; so we can write a reg pair into map_reg
+           .db 0x00    ; current value written to map register
+map_bank1:  .db 0x1f   ; port
+           .db 0x00    ; kernel map using system RAM, assuming no low 16K
+                       ; and high banking with I/O mapped
+map_bank2:  .db 0x1f   ; port
+           .db 0x08    ; kernel map using first 32K of expansion memory
+                       ; and high banking with I/O mapper
+map_store:  .db 0x1f
+           .db 0x00    ; save value from map_save
+
 ;
 ;      Map in the kernel. We are in common and all kernel entry points are
 ;      in common. Thus someone will always have banked in the right page
@@ -102,16 +169,18 @@ map_store:  .db 0x00      ; save value from map_save
 ;
 map_kernel:
 map_kernel_restore:
-           push af
-           ld a, (ksave_map)
-           ld (map_reg), a
-           out (0x43), a
-           pop af
+           push bc
+           ld bc, (ksave_map)
+           ld (map_reg), bc
+           out (c), b
+           pop bc
            ret
 
 fork_mapsave:
-           ld a,(map_reg)
-           ld (ksave_map),a
+           push bc
+           ld bc,(map_reg)
+           ld (ksave_map),bc
+           pop bc
            ret
 ;
 ;      Select the bank for the relevant process. Update the ksave_map so we
@@ -122,54 +191,61 @@ map_process:
            or l
            jr z, map_kernel
 map_process_hl:
-            ld a, (map_reg)
-           ld (ksave_map),   ; for map_kernel_restore
-           ld a,(hl)           ; udata page
-           ld (map_reg),a
-           out (0x43), a
+            ld bc, (map_reg)
+           ld (ksave_map),bc   ; for map_kernel_restore
+           ld b,(hl)           ; udata page
+           ld (map_reg),bc
+           out (c), b
             ret
 
 map_process_a:                 ; used by bankfork
-           push af
-           ld a, (map_reg)
-           ld (ksave_map), a
-           pop af
-           ld (map_reg), a
-           out (0x43), a
+           push bc
+           ld bc, (map_reg)
+           ld (ksave_map), bc
+           ld b, a
+           ld (map_reg), bc
+           out (c), b
+           pop bc
            ret
 
 map_process_save:
 map_process_always:
            push af
-           ld a, (map_reg)
-           ld (ksave_map), a
+           push bc
+           ld bc, (map_reg)
+           ld (ksave_map), bc
            ld a,(U_DATA__U_PAGE)
-           ld (map_reg),a
-           out (0x43),a
+           ld b,a
+           ld (map_reg),bc
+           out (c),b
+           pop bc
            pop af
            ret
 
-map_save:   push af
-           ld a, (map_reg)
-           ld (map_store), a
-           pop af
+map_save:   push bc
+           ld bc, (map_reg)
+           ld (map_store), bc
+           pop bc
            ret
 
 map_restore:
-           push af
-           ld a, (map_store)
-           ld (map_reg), a
-           out (0x43), a
-           pop af
+           push bc
+           ld bc, (map_store)
+           ld (map_reg), bc
+           out (c), b
+           pop bc
            ret
 
 map_save_kmap:
-           ld a,(map_reg)
+           ld a,(map_reg + 1)
            ret
 
 map_restore_kmap:
-           ld (map_reg),a
-           out (0x43),a
+           ld (map_reg + 1),a
+           push bc
+           ld bc, (map_reg)
+           out (c),b
+           pop bc
            ret
 
 ;
@@ -206,10 +282,10 @@ map_restore_kmap:
 ;      space we have to do the restore as we return.
 ;
 __bank_0_2:                    ; Call from common to bank 2
-       ld a,#1
+       ld bc,(map_bank2)
        jr bankina
 __bank_0_1:                    ; Call from common to bank 1
-       xor a
+       ld bc,(map_bank1)
 bankina:
        pop hl                  ; Get the return address
        ld e,(hl)               ; The two bytes following it are the true
@@ -217,59 +293,56 @@ bankina:
        ld d,(hl)
        inc hl
        push hl
-       ld bc,(map_port)
-       ld (map_reg),a
-       out (c),a
+       ld (map_reg),bc
+       out (c),b
        ex de,hl
-       ld a,b
-       or a
+       ld a,(map_bank1 + 1)
+       cp b
        jr z, retbank1          ; Arrange that we put the banks back as they
        call callhl             ; were before the call. Needed because calls
-       ld a,#1                 ; to common routines don't do banking so
-       ld (map_reg),         ; the return won't either.
-       out (0x43),a
+       ld bc,(map_bank2)       ; to common routines don't do banking so
+       ld (map_reg),bc         ; the return won't either.
+       out (c),b
        ret
 retbank1:
        call callhl
-       xor a
-       ld (map_reg),a
-       out (0x43),a
+       ld bc,(map_bank1)
+       ld (map_reg),bc
+       out (c),b
        ret
 
 __bank_1_2:
-       ld a,#1
+       ld bc,(map_bank2)
        pop hl                  ; Get the return address
        ld e,(hl)               ; The two bytes following it are the true
        inc hl                  ; function to call
        ld d,(hl)
        inc hl
        push hl
-       ld bc,(map_port)
-       ld (map_reg),a
-       out (c),a
+       ld (map_reg),bc
+       out (c),b
        ex de,hl
        call callhl
-       xor a
-       ld (map_reg),a
-       out (0x43),a
+       ld bc,(map_bank1)
+       ld (map_reg),bc
+       out (c),b
        ret
 
 __bank_2_1:
-       xor a
+       ld bc,(map_bank1)
        pop hl                  ; Get the return address
        ld e,(hl)               ; The two bytes following it are the true
        inc hl                  ; function to call
        ld d,(hl)
        inc hl
        push hl
-       ld bc,(map_port)
-       ld (map_reg),a
-       out (c),a
+       ld (map_reg),bc
+       out (c),b
        ex de,hl
        call callhl
-       ld a,#1
-       ld (map_reg),a
-       out (0x43),a
+       ld bc,(map_bank2)
+       ld (map_reg),bc
+       out (c),b
        ret
 
 ;
@@ -284,29 +357,29 @@ __bank_2_1:
 ;      banking setup.
 ;
 __stub_0_1:
-       xor a
+       ld bc,(map_bank1)
        jr stub_call
 __stub_0_2:
-       ld a,#1
+       ld bc,(map_bank2)
 stub_call:
        pop hl                  ; return address
        ex (sp),hl              ; swap the junk word for the return
-       ld bc,(map_port)
-       ld (map_reg),a
-       out (c),a
+       ld a,(map_reg+1)        ; where are we going back to ?
+       ld (map_reg),bc
+       out (c),b
        ex de,hl
-       ld a,b
-       or a
+       ld bc,(map_bank1)
+       cp b
        jr z, stub_ret_1
        call callhl
-       ld a,#1
+       ld bc,(map_bank2)
        jr stub_ret
 stub_ret_1:
        call callhl             ; invoke code in other bank
-       xor a                   ; and back to bank 1
+       ld bc,(map_bank1)       ; and back to bank 1
 stub_ret:
-       ld (map_reg),a
-       out (0x43),a
+       ld (map_reg),bc
+       out (c),b
        pop bc                  ; bc is now the return
        push bc                 ; stack it twice
        push bc
index 3aadcaa..6865409 100644 (file)
@@ -5,6 +5,9 @@ extern uint8_t trs80_model;
 #define LNW80          2       /* Need to handle LNW80 model II.. */
 #define VIDEOGENIE     3       /* But colour genie may be too different.. */
 
+extern uint8_t trs80_mapper;
+#define MAP_SUPERMEM   0       /* Alpha Supermem and compatibles */
+#define MAP_SELECTOR   1       /* Selector */
 
 /*
  *     Differences versus model 1
@@ -27,4 +30,4 @@ extern uint8_t trs80_model;
  *
  *     Note that the Colour Genie is a very different beast.
  *     
- */
\ No newline at end of file
+ */
index 22cc4e8..85b7e51 100644 (file)
@@ -49,6 +49,7 @@
            .globl null_handler
            .globl fd_nmi_handler
            .globl _vtflush
+           .globl mapper_init
 
             .include "kernel.def"
             .include "../kernel.def"
@@ -88,6 +89,7 @@ _platform_reboot:
 
 
 init_early:
+           call mapper_init    ; A is the mapper type passed from crt0.s
            ld a,(4)
            cp #0x30
            jr nz, not_m3