Tidy up MMU code and comments.
authorNeal Andrew Crook <neal@pippaluk.org.uk>
Thu, 7 Jul 2016 22:08:57 +0000 (23:08 +0100)
committerNeal Andrew Crook <neal@pippaluk.org.uk>
Thu, 7 Jul 2016 22:08:57 +0000 (23:08 +0100)
Kernel/platform-multicomp09/README
Kernel/platform-multicomp09/devsdc.h
Kernel/platform-multicomp09/devtty.c
Kernel/platform-multicomp09/multicomp09.s
Kernel/platform-multicomp09/tricks.s
Kernel/platform-multicomp09/usermem_gime.s

index 5fe4376..d6edb0f 100644 (file)
@@ -108,7 +108,9 @@ When control passes to the boot-loader, it locates the kernel, parses the DECB
 format to load the kernel to RAM and pass control to it at its start address
 (which is encoded into the DECB file).
 
+The emulator is started like this:
 
+./m6809-run -s multicomp09 -b ../6809M.bin -I 240000 -m 100000000
 
 *************************
 KEYBOARD
@@ -123,8 +125,8 @@ DEVICES (so far)
 *************************
 
 node       major   minor     description
-/dev/tty1  2       1                console
-/dev/tty2  2       2         RS232 port
+/dev/tty1  2       1                VGA/PS2 console  <-+-- swappable by VDUFFD0
+/dev/tty2  2       2         RS232 port       <-+             jumper
 /dev/tty3  2       3         USB virtual RS232 port
 /dev/tty4  2       4         Drivewire Virtual Window #0  (coming soon..)
 /dev/dw?   8       0-256     Drivewire Block Drives       (coming soon..)
index 7a848d6..2afe991 100644 (file)
@@ -1,4 +1,4 @@
 
 
-void devsd_read( char *addr );
-void devsd_write( char *addr );
+void devsd_read( void *addr );
+void devsd_write( void *addr );
index a0d3a07..0d68e42 100644 (file)
 #undef  DEBUG                  /* UNdefine to delete debug code sequences */
 #undef  MC09_VIRTUAL_IN
 
+/* Hardware Registers */
+#define TIMER  (0xffdd)
+#define timer_reg  *((volatile uint8_t *)TIMER)
+
 
 /* Multicomp has 3 serial ports. Each is a cut-down 6850, with fixed BAUD rate and word size.
    Port 0 is, by default, a virtual UART interface to a VGA output and PS/2 keyboard
    Port 0 is used for tty1, Port 1 for tty2.
 */
 static uint8_t *uart[] = {
-    0,      0,                               /* Unused */
-    (volatile uint8_t *)0xFFD1, (volatile uint8_t *)0xFFD0,    /* Virtual UART Data, Status port0, tty1 */
-    (volatile uint8_t *)0xFFD3, (volatile uint8_t *)0xFFD2,    /*         UART Data, Status port1, tty2 */
-    (volatile uint8_t *)0xFFD5, (volatile uint8_t *)0xFFD4,    /*         UART Data, Status port2, tty3 */
+       0,      0,                               /* Unused */
+       (uint8_t *)0xFFD1, (uint8_t *)0xFFD0,    /* Virtual UART Data, Status port0, tty1 */
+       (uint8_t *)0xFFD3, (uint8_t *)0xFFD2,    /*         UART Data, Status port1, tty2 */
+       (uint8_t *)0xFFD5, (uint8_t *)0xFFD4,    /*         UART Data, Status port2, tty3 */
 };
 
 #ifdef MC09_VIRTUAL_IN
@@ -38,7 +42,8 @@ static int icount = 0;
 static int imatch = 100;
 /* X represents a pause at end-of-line*/
 /* Without pauses, the input streams ahead of the output */
-static uint8_t input[] = "ls -al\nXpwd\nXps\nX\x04root\nXtime ls\nX\nfforth /usr/src/fforth/fforth_tests.fth\nX";
+/*static uint8_t input[] = "ls -al\nXpwd\nXps\nX\x04root\nXtime ls\nX\nfforth /usr/src/fforth/fforth_tests.fth\nX"; */
+static uint8_t input[] = "ls -al\nXpwd\nX";
 static int ccount = 0;
 #endif
 
@@ -85,7 +90,6 @@ struct s_queue ttyinq[NUM_DEV_TTY + 1] = {
 
 
 
-
 /* A wrapper for tty_close that closes the DW port properly */
 int my_tty_close(uint8_t minor)
 {
@@ -98,16 +102,28 @@ int my_tty_close(uint8_t minor)
 /* Output for the system console (kprintf etc) */
 void kputchar(char c)
 {
-       if (c == '\n')
-            tty_putc(minor(TTYDEV), '\r');
-       tty_putc(minor(TTYDEV), c);
+       uint8_t minor = minor(TTYDEV);
+
+       while ((*(uart[minor*2 + 1]) & 2) != 2) {
+               /* UART is busy */
+       }
+
+       /* convert from CR to CRLF */
+       if (c == '\n') {
+               tty_putc(minor, '\r');
+               while ((*(uart[minor*2 + 1]) & 2) != 2) {
+                       /* UART is busy */
+               }
+       }
+
+       tty_putc(minor, c);
 }
 
 ttyready_t tty_writeready(uint8_t minor)
 {
        uint8_t c;
         if ((minor < 1) || (minor > 3)) {
-            return TTY_READY_NOW;
+               return TTY_READY_NOW;
         }
        c = *(uart[minor*2 + 1]); /* 2 entries per UART, +1 to get STATUS */
        return (c & 2) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
@@ -180,12 +196,10 @@ void platform_interrupt(void)
        if (c & 0x01) { tty_inproc(3, *(uart[3*2])); } */
 #endif
 
-       /* [NAC HACK 2016May07] need defines for the timer */
-       c = *((volatile uint8_t *)0xFFDD);
+       c = timer_reg;
        if (c & 0x80) {
-               *((volatile uint8_t *)0xFFDD) = c; /* service the hardware */
-               /* tell the OS it happened */
-               timer_interrupt();
+               timer_reg = c;       /* service the hardware */
+               timer_interrupt();   /* tell the OS it happened */
        }
 
         //     dw_vpoll();
index 6852099..bf1c773 100644 (file)
@@ -22,9 +22,9 @@
 ;;; $ffb0   video colour
 
 ;;; coco3 MMU
-;;; accessed through registers $ff91 and $ffa0-$ffa7
+;;; accessed through registers $ff91 and $ffa0-$ffaf
 ;;; 2 possible memory maps: map0, map1 selected by $ff91[0]
-;;; map0 is used for Kernel mode, map1 is used for User mode.
+;;; map0 is used for User mode, map1 is used for Kernel mode.
 ;;; map1 is selected at boot (ie, now).
 ;;; when 0, select map0 using pages stored in $ffa0-$ffa7
 ;;; when 1, select map1 using pages stored in $ffa8-$ffaf
 ;;; multicomp09 MMU
 ;;; accessed through two WRITE-ONLY registers MMUADR, MMUDAT
 ;;; 2 possible memory maps: map0, map1 selected by MMUADR[6]
-;;; map0 is used for Kernel mode, map1 is used for User mode.
+;;; map0 is used for User mode, map1 is used for Kernel mode.
 ;;; map0 is selected at boot (ie, now)
-;;; [NAC HACK 2016Apr23] to avoid pointless divergence from
-;;; coco3, the first hardware setup step will be to flip to
-;;; map1.
+;;; .. to avoid pointless divergence from coco3, the first
+;;; hardware setup step will be to flip to map1.
 ;;; [NAC HACK 2016Apr23] in the future, may handle this in
 ;;; forth or in the bootstrap
 ;;; when 0, select map0 using MAPSEL values 0-7
@@ -137,9 +136,9 @@ _need_resched
 ;;; The values of 0-7 set here for _usr_mmu_map reflect how the user mappings
 ;;; are set up when the kernel is started - so don't change them either!
 _krn_mmu_map
-       .db     0,1,2,3,4,5,6,7
+       .db     0,1,2,3,4,5,6,7 ; mmu registers 8-f
 _usr_mmu_map
-       .db     0,1,2,3,4,5,6,7
+       .db     0,1,2,3,4,5,6,7 ; mmu registers 0-7
 
 
 _trap_monitor:
@@ -317,7 +316,8 @@ _program_vectors:
        ldy     #MMUADR
 
        ;; setup the null pointer / sentinal bytes in low process memory
-       lda     #(MMU_MAP1|8)   ; stay in MAP1, select block 8
+       lda     curr_tr         ; Select MMU register associated with
+       ora     #8              ; block 8
        sta     ,y
 
        lda     ,x              ; get process's blk address for address 0
@@ -326,9 +326,9 @@ _program_vectors:
        sta     0
 
        ;; restore the MMU mapping that we trampled on
-       ;; MMUADR still has MAP1, block 8 so no need to re-write it.
+       ;; MMUADR still has block 8 selected so no need to re-write it.
 
-       ;; retrieve value that used to be in MAP1, block 8
+       ;; retrieve value that used to be in block 8
        lda     _krn_mmu_map
        ;; and restore it
        sta     1,y             ; MMUDAT
index dc70e86..811fc9b 100644 (file)
@@ -1,7 +1,6 @@
 ;;;
 ;;; CoCo3 ghoulish tricks (boo!) ported to multicomp09
 ;;;
-
         .module tricks
 
        ;; imported
@@ -79,8 +78,7 @@ _switchin:
        stx     _swapstack      ; save passed page table *
 
 ;;; [NAC HACK 2016May03] this is only flipping in top 8K .. as is coco3.
-       lda     curr_tr         ; [NAC HACK 2016May07] I assume we're running in krn but
-                               ; I'm not 100% sure..
+       lda     curr_tr         ; Select MMU register associated with
        ora     #7              ; top 8K of usr map
        sta     MMUADR
 
@@ -90,8 +88,7 @@ _switchin:
        sta     MMUDAT
        sta     _usr_mmu_map+7  ; keep the mirror in sync.
 
-       lda     curr_tr         ; [NAC HACK 2016May07] I assume we're running in krn but
-                               ; I'm not 100% sure..
+       lda     curr_tr         ; Select MMU register associated with
        ora     #$f             ; top 8K of krn map
        sta     MMUADR
 
@@ -228,15 +225,13 @@ skip2@    incb
         ;;
         ;;     stb     0xffaf
         ;;     stb     0xffa7
-       lda     curr_tr         ; [NAC HACK 2016May07] I assume we're running in krn but
-                               ; I'm not 100% sure..
+       lda     curr_tr         ; Select MMU register associated with
        ora     #$f             ; top 8K of krn map
         sta     MMUADR
         stb     MMUDAT
        stb     _krn_mmu_map+7  ; keep the mirror in sync.
 
-       lda     curr_tr         ; [NAC HACK 2016May07] I assume we're running in krn but
-                               ; I'm not 100% sure..
+       lda     curr_tr         ; Select MMU register associated with
        ora     #7              ; top 8K of usr map
         sta     MMUADR
         stb     MMUDAT
@@ -253,7 +248,8 @@ copybank
        pshs    d,x,u,y         ; changing this will affect "ldb 0,s" below
        ;; map in dest
        ldx     #MMUADR         ; for storing
-       lda     #(MMU_MAP1+8)   ; mapsel=8, for dest, in B
+       lda     curr_tr         ; Select MMU register associated with
+       ora     #8              ; mapsel=8, for dest, in B
        std     ,x              ; mapsel=8, page in B
        inca                    ; mapsel=9
        incb                    ; adjacent page
@@ -290,7 +286,8 @@ a@  ldd     ,u++
        ;; restore mmu
        ldy     #_krn_mmu_map   ; kernel's mmu ptr.. for reading
        ldx     #MMUADR         ; for storing
-       lda     #(MMU_MAP1+8)
+       lda     curr_tr         ; Select MMU register associated with
+       ora     #8              ; mapsel=8, for dest, in B
        ldb     ,y+             ; page from krn_mmu_map
        std     ,x              ; Write A to MMUADR to set MAPSEL=8, then write B to MMUDAT
        inca                    ; next mapsel
index 54db90f..307ebed 100644 (file)
@@ -209,7 +209,6 @@ a@  std     ,u
 ;;; remapping the mmu, copies those bytes, *then* re-computes the
 ;;; mmu banking and repeats until all bytes are transfered.
 ;;;
-;;; assume: map0 (kernel map) is in use.
 ;;; "borrow" the low 4 kernel MMU mappings; treating them as 2, 16K
 ;;; windows, map kernel space into the lower and user space into the
 ;;; upper, then copy from one to the other. At the end of the routine,
@@ -243,14 +242,16 @@ b@        ldd     krn             ; calc max byte copyable from source
        ;;
        ;;
        ;;
-       ldb     #(MMU_MAP1|8)
+       ldb     curr_tr
+       orb     #8
        stb     0,y             ; MMUADR set mapsel=8
        ;;
        ldb     a,x             ; get mmu entry
        stb     1,y             ; MMUDAT store in mmu
         ;;
        ;;
-       ldb     #(MMU_MAP1|9)
+       ldb     curr_tr
+        orb     #9
        stb     0,y             ; MMUADR set mapsel=9
        ;;
         inca                    ; increment index [NAC HACK 2016May07] or a,x+ above and omit this??
@@ -268,14 +269,16 @@ b@        ldd     krn             ; calc max byte copyable from source
        anda    #3              ; mask off junk [NAC HACK 2016May03] why not 7??
        ldx     #U_DATA__U_PAGE ; X = ptr to user page table
        ;;
-       ldb     #(MMU_MAP1|10)
+       ldb     curr_tr
+        orb     #10
        stb     0,y             ; MMUADR set mapsel=10
        ;;
        ldb     a,x             ; B = page table entry
        stb     1,y             ; MMUDAT store in MMU
        incb                    ; increment for next page no [NAC HACK 2016May03] coz we use page pairs?
        ;;
-       lda     #(MMU_MAP1|11)  ; use A because B is busy this time
+       lda     curr_tr         ; use A because B is busy this time
+       ora     #11
        sta     0,y             ; MMUADR set mapsel=11
        ;;
        stb     1,y             ; MMUDAT store in mmu
@@ -297,7 +300,8 @@ a@  lda     ,u+             ; get a byte
        ;; clean up kernel mmu's for next mapping or returning
        ldx     #MMUADR
        ldy     #_krn_mmu_map
-       lda     #(MMU_MAP1|8)
+       lda     curr_tr         ; Select MMU register associated with
+        ora     #8              ; mapsel=8
         ldb     ,y+             ; page from _krn_mmu_map
         std     ,x              ; Write A to MMUADR to set MAPSEL=8, then write B to MMUDAT
         inca                    ; next mapsel