cromemco: very slow but working
authorAlan Cox <alan@linux.intel.com>
Tue, 11 Dec 2018 22:35:29 +0000 (22:35 +0000)
committerAlan Cox <alan@linux.intel.com>
Tue, 11 Dec 2018 22:35:29 +0000 (22:35 +0000)
Lots of optimizations needed and the small matter of having no hard disk
emulation

Kernel/platform-cromemco/Makefile
Kernel/platform-cromemco/README
Kernel/platform-cromemco/config.h
Kernel/platform-cromemco/cromemco.s
Kernel/platform-cromemco/crt0.s
Kernel/platform-cromemco/devfd.c
Kernel/platform-cromemco/discard.c [new file with mode: 0644]
Kernel/platform-cromemco/fuzix.lnk
Kernel/platform-cromemco/kernel.def
Kernel/platform-cromemco/main.c

index 6ca489a..6adaab7 100644 (file)
@@ -1,16 +1,14 @@
 
-CSRCS = devtty.c devfd.c interrupt.c
-CSRCS += devices.c main.c
+CSRCS = devtty.c devfd.c interrupt.c devices.c main.c
+CDSRCS = discard.c
 
-ASRCS = crt0.s cromemco.s usermem.s
-ASRCS += tricks.s commonmem.s vector.s
+ASRCS = crt0.s cromemco.s usermem.s tricks.s commonmem.s vector.s
 
 AOBJS = $(ASRCS:.s=.rel)
 COBJS = $(CSRCS:.c=.rel)
+CDOBJS = $(CDSRCS:.c=.rel)
 
-OBJS  = $(AOBJS) $(COBJS)
-
-
+OBJS  = $(AOBJS) $(COBJS) $(CDOBJS)
 
 all:   $(OBJS)
 
@@ -20,6 +18,9 @@ $(AOBJS): %.rel: %.s
 $(COBJS): %.rel: %.c
        $(CROSS_CC) $(CROSS_CCOPTS) -c $<
 
+$(CDOBJS): %.rel: %.c
+       $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<
+
 clean:
        rm -f *.rel *.lst *.asm *.sym *.rst core *~
        rm -f cloader-16fdc.ihx cloader-16fdc.tmp
index 975d0f1..640cb65 100644 (file)
@@ -1,7 +1,4 @@
-FUZIX on a Cromenco (no hard disk support right now - need docs for that and
-suitable emulation!)
-
-The mapping model is intended to be
+An initial port of Fuzix to the Cromemco Z1 and similar systems.
 
 Bank 0         Kernel
                0000-00FF, F200-FFFF are propogated into the other banks
@@ -18,35 +15,68 @@ The kstack and istack exist in each bank. We'll normally only use the kernel
 one but there are cases we switch and borrow a bit of the other bank copy.
 It's easier to arrange this way anyhow.
 
-TODO
-DONE   -               Debug a loader (seems to work)
-IP     -               An awful lot of early kernel boot debugging
-HACK   -               Interrupts properly (and IM2)
-                       not yet doing tty interrupts nicely with buffer
-                       and queues
+Limitations
+
+-      Very slow at fork() because we need to optimize ldir_far extensively
+       for this machine and for the SC108
+-      Only supports floppy disks and currently only supports DS/DD eight
+       inch media for the filesystems
+-      The IM2 support for the initial serial console is an ugly hack and
+       a proper serial driver is needed with queues for each port.
+-      Memory size is not probed
+-      Only the console port is enabled
 
+Notes
 
+-      The emulator appears to be very flaky when it comes to serial emulation
+       but pretty decent on the floppy side. However it needs patching to
+       make it understand Fuzix DS/DD media as opposed to the weird Cromemco
+       SD/DD mixed formats.
 
+Bugs
 
-We expect
 
-0              tuart / 4 FDC
-4              fdc aux
-5-9            times
-32             tuart / parallel 36
-48             fdc
-64             mmu
-80             tuart / parallel 84
-255            front panel
+TODO
+HACK   -               Interrupts properly (and IM2)
+                       not yet doing tty interrupts nicely with buffer
+                       and queues
+       -               Eject support for floppies
+       -               Floppy ioctls, mode set etc
+       -               Auto probe
+       -               Disk names (so you can say 'fd1' not 257)
+       -               Disk interleave enable (need a block shuffling tool)
+       -               5.25" disks (plus hack emulator to also allow for
+                       sane 5.25" formats including PC)
+       -               fast 512 byte and fork interbank copier
+
+Testing
+-      Build the kernel and get a fuzix.dsk (SS/SD)
+-      Build user space
+-      cd Standalone/filesystem-src
+       ./build-mini-filesystem fs.dsk 64 2464
+-      Install fuzix.dsk as drivea.dsk and fs.dsk as driveb.dsk
+-      Fire up the patched cromemco simulator
+       cromemcosim -x rdos252.hex
+-      Hit power, hit run, hit return a few times to get a Booting
+       message
+-      At the boot prompt reply '257'
 
 
+Hardware supported
 
+-      TU-ART at 0x00 strapped for 8080 mode (typically part of an FDC card)
+-      16FDC or 64FDC with 8" DSDD drives
 
-The MMU settings we use are
+Hardware to support
 
-1 << n         That bank 0-6
+-      Additional TU-ARTs
+-      Line printer
+-      Second FDC
+-      Joystick & Sound
+-      Do something cool with the fp lights
+-      Hard disk as and if docs/emulation appears for it. Maybe also an
+       IDE driver for a modern S100 add in.
 
-0x80           Turn on comon writing (write to all banks)
 
 
 UARTs: TMS 5501 x 2 per board. These can do Z80 IM2 where the vector is
@@ -238,3 +268,12 @@ D3-1
        110     timer4
        111     timer5 (PI7)
 
+
+
+Disks
+
+256256 128     26      77              8" SS SD
+512512 128     26      77              8" DS SD
+
+1261568        512     16      77              8" DS DD
+
index 15be6e1..f485e48 100644 (file)
 #define NUM_DEV_TTY 3
 
 #define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
-#define NBUFS    8       /* Number of block buffers */
+#define NBUFS    5       /* Number of block buffers */
 #define NMOUNTS         4        /* Number of mounts at a time */
 
-#define platform_discard()
+#define CONFIG_DYNAMIC_BUFPOOL
+#define CONFIG_LARGE_IO_DIRECT
+
 #define platform_copyright()
+
+#define BOOTDEVICENAMES "hd#,fd"
index 6f95098..9b09dd9 100644 (file)
@@ -416,7 +416,19 @@ _fd_operation:
        ld      b,(hl)                  ; command
        inc     hl
        inc     hl
+       ;
+       ;       Make sure we patch across all instances
+       ;
+       ;
+       ;       We have to disable interrupts before we write the
+       ;       command register when doing a data transfer otherwise an
+       ;       interrupt can lose us bytes and break the transfer. Do it
+       ;       a spot earlier so we can also do the patching under it
+       ;
+       di
        bit     0,(hl)                  ; read or write ?
+       ld      a, #0x81                ; write all common, read kernel
+       out     (0x40),a
        ; patch patch1/2 according to the transfer direction
        ld      a,#0xA2                 ; ini
        jr      z, patchit
@@ -424,12 +436,8 @@ _fd_operation:
 patchit:
        ld      (patch1+1),a
        ld      (patch2+1),a
-       ;
-       ;       We have to disable interrupts before we write the
-       ;       command register when doing a data transfer otherwise an
-       ;       interrupt can lose us bytes and break the transfer
-       ;
-       di
+       ld      a,#0x01
+       out     (0x40),a                ; kernel map
        in      a,(0x34)                ; check head status
        bit     5,a
        jr      nz, nomod               ; loaded
@@ -477,7 +485,6 @@ issue_command:
 cmdout:
        ld      a,e
        out     (0x30),a                ; issue the command
-       ld      a,(_fd_map)
 
 
        ;       FIXME: mappings
@@ -622,7 +629,7 @@ delayhl3:
 
 _platform_doexec       .equ    0x18
 
-        .area _DISCARD
+        .area _COMMONMEM
 
        .globl rst38
        .globl stubs_low
index 1df55fb..6e524d6 100644 (file)
         .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 _BUFFERS
        .area _DISCARD
+        .area _INITIALIZER
         .area _COMMONMEM
 
         ; imported symbols
@@ -35,6 +36,9 @@
         .globl l__DATA
         .globl kstack_top
 
+       .include "../kernel.def"
+       .include "kernel.def"
+
         ; startup code
         .area _CODE
 init:
@@ -80,3 +84,15 @@ init:
 stop:   halt
         jr stop
 
+
+       .area _BUFFERS
+;
+; Buffers (we use asm to set this up as we need them in a special segment
+; so we can recover the discard memory into the buffer pool
+;
+
+       .globl _bufpool
+       .area _BUFFERS
+
+_bufpool:
+       .ds BUFSIZE * NBUFS
index 6697a5c..2df076b 100644 (file)
@@ -85,8 +85,11 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
         goto bad2;
 
     fd_map = rawflag;
-    if (rawflag && d_blkoff(BLKSHIFT))
+    if (rawflag) {
+        if (d_blkoff(BLKSHIFT))
             return -1;
+        fd_map = udata.u_page;
+    }
 
     /* Command to go to the controller after any seek is done */
     fd_cmd[0] = is_read ? FD_READ : FD_WRITE;
@@ -177,7 +180,7 @@ int fd_open(uint8_t minor, uint16_t flag)
         return -1;
     }
     /* Ensure we can't open the same physical disk in two modes at once */
-    if (*dp != 0xFF) {
+    if (*dp != 0xFF && *dp != minor) {
         udata.u_error = EBUSY;
         return -1;
     }
diff --git a/Kernel/platform-cromemco/discard.c b/Kernel/platform-cromemco/discard.c
new file mode 100644 (file)
index 0000000..1700128
--- /dev/null
@@ -0,0 +1,38 @@
+#include <kernel.h>
+#include <devtty.h>
+#include <printf.h>
+#include <irq.h>
+
+/* TODO: probe banks */
+void pagemap_init(void)
+{
+ int i;
+ /* 1 << 0 is kernel */
+ for (i = 1; i < 7; i++)
+  pagemap_add(1 << i);
+}
+
+/* Nothing to do for the map of init but we do set our vectors up here */
+void map_init(void)
+{
+ if (request_irq(0xE7, uart0a_rx) |
+ request_irq(0xEF, uart0a_txdone) |
+ request_irq(0xF7, uart0a_timer4))
+  panic("irqset");
+ /* We need to claim these in case we set one off as they are at odd vectors
+    as the base tu_uart is strapped for 8080 mode */
+ if (
+  request_irq(0xC7, spurious) |
+  request_irq(0xCF, spurious) |
+  request_irq(0xD7, spurious) |
+  request_irq(0xDF, spurious) |
+  request_irq(0xFF, spurious)
+  )
+  panic("irqset2");
+}
+
+uint8_t platform_param(char *p)
+{
+ used(p);
+ return 0;
+}
index bb13048..04e26f2 100644 (file)
@@ -9,6 +9,7 @@ platform-cromemco/commonmem.rel
 platform-cromemco/cromemco.rel
 platform-cromemco/vector.rel
 platform-cromemco/main.rel
+platform-cromemco/discard.rel
 platform-cromemco/interrupt.rel
 start.rel
 version.rel
index 939d0b7..7b32b41 100644 (file)
@@ -24,4 +24,6 @@ CONFIG_SWAP               .equ 0
 
 ; We only have a single page entry
 
-HIGHPAGE                   .equ 0
\ No newline at end of file
+HIGHPAGE                   .equ 0
+
+NBUFS                      .equ 5
index a24f1e5..8b5834a 100644 (file)
@@ -1,18 +1,11 @@
 #include <kernel.h>
+#include <kdata.h>
 #include <devtty.h>
 #include <printf.h>
 #include <irq.h>
 
 uaddr_t ramtop = PROGTOP;
 
-void pagemap_init(void)
-{
- int i;
- /* 1 << 0 is kernel */
- for (i = 1; i < 7; i++)
-  pagemap_add(1 << i);
-}
-
 void platform_idle(void)
 {
  __asm
@@ -31,29 +24,31 @@ void platform_interrupt(void)
 // tty_irq(3);
 }
 
-/* Get this into discard ... */
-
-/* Nothing to do for the map of init but we do set our vectors up here */
-void map_init(void)
+/* This points to the last buffer in the disk buffers. There must be at least
+   four buffers to avoid deadlocks. */
+struct blkbuf *bufpool_end = bufpool + NBUFS;
+
+/*
+ *     We pack discard into the memory image is if it were just normal
+ *     code but place it at the end after the buffers. When we finish up
+ *     booting we turn everything from the buffer pool to the start of
+ *     common space into buffers.
+ */
+void platform_discard(void)
 {
- if (request_irq(0xE7, uart0a_rx) |
- request_irq(0xEF, uart0a_txdone) |
- request_irq(0xF7, uart0a_timer4))
-  panic("irqset");
- /* We need to claim these in case we set one off as they are at odd vectors
-    as the base tu_uart is strapped for 8080 mode */
- if (
-  request_irq(0xC7, spurious) |
-  request_irq(0xCF, spurious) |
-  request_irq(0xD7, spurious) |
-  request_irq(0xDF, spurious) |
-  request_irq(0xFF, spurious)
-  )
-  panic("irqset2");
-}
+       uint16_t discard_size = PROGTOP - (uint16_t)bufpool_end;
+       bufptr bp = bufpool_end;
 
-uint8_t platform_param(char *p)
-{
- used(p);
- return 0;
+       discard_size /= sizeof(struct blkbuf);
+
+       kprintf("%d buffers added\n", discard_size);
+
+       bufpool_end += discard_size;
+
+       memset( bp, 0, discard_size * sizeof(struct blkbuf) );
+
+       for( bp = bufpool + NBUFS; bp < bufpool_end; ++bp ){
+               bp->bf_dev = NO_DEVICE;
+               bp->bf_busy = BF_FREE;
+       }
 }