coco2cart: Initial patches from Brett Gordon for cocosdc
authorAlan Cox <alan@linux.intel.com>
Mon, 19 Dec 2016 20:46:16 +0000 (20:46 +0000)
committerAlan Cox <alan@linux.intel.com>
Mon, 19 Dec 2016 20:46:16 +0000 (20:46 +0000)
Kernel/Makefile
Kernel/platform-coco2cart/Makefile
Kernel/platform-coco2cart/README
Kernel/platform-coco2cart/bootstrap_sdc.s [new file with mode: 0644]
Kernel/platform-coco2cart/config.h
Kernel/platform-coco2cart/devices.c
Kernel/platform-coco2cart/devsdc.c [new file with mode: 0644]
Kernel/platform-coco2cart/devsdc.h [new file with mode: 0644]
Kernel/platform-coco2cart/drivewire.s
Kernel/platform-coco2cart/sdc.s [new file with mode: 0644]

index 62de301..8807045 100644 (file)
@@ -6,7 +6,7 @@ TARGET_LIST = platform-nc100 platform-micropack platform-pcw8256 platform-socz80
 #export TARGET = bbcmicro
 #export TARGET = dragon
 #export TARGET = coco2
-#export TARGET = coco2cart
+export TARGET = coco2cart
 #export TARGET = coco3
 #export TARGET = dragon-nx32
 #export TARGET = multicomp09
@@ -28,7 +28,7 @@ TARGET_LIST = platform-nc100 platform-micropack platform-pcw8256 platform-socz80
 #export TARGET = v65
 #export TARGET = v68
 #export TARGET = v68-banked
-export TARGET = z80pack
+#export TARGET = z80pack
 #export TARGET = z80pack-lite
 #export TARGET = zeta-v2
 #export TARGET = zx128
index 116aefe..79c46ed 100644 (file)
@@ -2,7 +2,7 @@
 CSRCS = devices.c main.c
 
 # Code that must be present for the bootstrap
-CISRCS = mini_ide.c
+CISRCS = mini_ide.c devsdc.c
 
 C3SRCS = libc.c devtty.c
 
@@ -10,7 +10,8 @@ CDSRCS = discard.c mini_ide_discard.c
 
 DSRCS = ../dev/devdw.c
 
-ASRCS = crt0.s coco2.s ide.s usermem.s bootstrap.s
+ASRCS = crt0.s coco2.s ide.s usermem.s sdc.s
+ASRCS += bootstrap.s bootstrap_sdc.s bootstrap_dw.s
 ASRCS += tricks.s commonmem.s drivewire.s video.s
 
 COBJS = $(CSRCS:.c=$(BINEXT))
@@ -54,7 +55,7 @@ clean:
 image:
        $(CROSS_LD) -o ../fuzix.bin -Map=../fuzix.map --script=fuzix.link \
        --oformat=decb \
-       crt0.o bootstrap.o commonmem.o coco2.o discard.o ../simple.o \
+       crt0.o bootstrap_sdc.o commonmem.o coco2.o discard.o ../simple.o \
        ../start.o ../version.o ../lowlevel-6809.o \
        tricks.o main.o ../timer.o ../kdata.o devices.o \
        drivewire.o devdw.o mini_ide.o mini_ide_discard.o ide.o \
@@ -62,7 +63,7 @@ image:
        ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \
        ../tty.o ../devsys.o ../usermem.o usermem.o ../syscall_fs2.o \
        ../syscall_exec16.o devtty.o libc.o ../vt.o video.o  ../syscall_fs3.o \
-       ../font8x8.o
+       ../font8x8.o devsdc.o sdc.o
        ../tools/decb-image <../fuzix.bin fuzix.img
        dd if=fuzix.img of=fuzix.rom bs=1024 skip=48 count=16
        dd if=fuzix.img of=fuzix.ide bs=256 skip=26 count=102
index 576dbf6..daf5e06 100644 (file)
@@ -8,6 +8,7 @@ COCO or Dragon 64 with an IDE port, cartridge and 64K of RAM
 Supported hardware:
        IDE (Cloud9 or compatible set at FF50) with either built in
                cartridge RAM or separate cartridge
+       COCO SDC (in progress)
 
 Disk Layout
 ===========
@@ -56,8 +57,11 @@ Needs the IDE patches
 TODO
 ====
 
+Fix use of CONFIG_LEGACY_EXEC in the devsdc driver
+
 Make the boot loader robust (timeout handling)
 Add hash of code not just simple magic - so we know bits match
+Merge coco and IDE boot code so it works out which is present
 
 Support for a real time clock and clock locking
 
@@ -68,6 +72,8 @@ We have about 2K left to try and jam those bits in which might just about be
 enough to add support for very minimal MBR parsing and offsets. That would
 be a big improvement.
 
+Automatically pick swap according to whether IDE or SDC is present.
+
 
 To Test
 =======
diff --git a/Kernel/platform-coco2cart/bootstrap_sdc.s b/Kernel/platform-coco2cart/bootstrap_sdc.s
new file mode 100644 (file)
index 0000000..1dd1715
--- /dev/null
@@ -0,0 +1,119 @@
+;;; The ROM-resident fuzix loader for the CoCoSDC drive.  Mostly copied from
+;;; Alan's IDE booter.
+
+;
+;      Bootstrap for cartridge start up. For now load from block 1 (second
+;      block). We can refine this later. We do 51 block loads from block 1
+;      for 1A00 to 7FFF and then copy 1A00 to 0100 for vectors
+;
+;      Needs some kind of global timeout -> error handling
+;
+;
+;      Load block b
+;
+       .module bootstrap
+
+       .globl load_image
+
+       .area .text
+
+;;; Load a sector from SDC
+;;;   takes: B - sector number, X = dest address
+;;;   returns: nothing
+load_block:
+       clr <$ff49              ; put lba to sdc
+       clr <$ff4a              ;
+       stb <$ff4b              ;
+       ldb #$80                ; read sector op
+       stb <$ff48              ; 
+       exg x,x                 ; wait a few cycles for sdc status reg
+       exg x,x                 ;   to be valid. - 2 long noops
+       ldb #$2                 ; wait till sdc is ready
+       ;; FIXME: test for failure in this loop 
+a@     bitb <$ff48             ;
+       beq a@                  ;
+       ;; tranfer data
+       lda #128                ; 128 x 16 bits = 256 byte sectors
+       pshs a                  ; push count on stack
+c@     ldd <$ff4a              ; get 16bit data from drive
+       std ,x++                ; stick it in memory
+       dec ,s                  ; bump counter
+       bne c@                  ; repeat
+       leas 1,s                ; drop counter
+       ;; wait for return value
+       ldb #$1
+       ;; FIXME: test for failure in the loop, also.
+b@     bitb <$ff48             ;
+       bne b@                  ; wait for busy
+       ;; FIXME: get return status here and test?
+       puls pc                 ; return
+
+
+
+load_image:
+       orcc #$50
+       ldy #$0400              ; display at this point
+       lda #'G'                ;
+       sta ,y+                 ;
+       ldd #$ff43              ; set DP to io page
+       tfr a,dp                ; good for size + speed
+       stb <$ff40              ; turn on SDC's LBA mode 
+       ;; we have to wait maybe 12us before doing anything
+       ;; with the SDC now, but the code below should
+       ;; delay SDC access enough.
+       ;; load kernel
+       ldb #0                  ; start block no (* 2 for 256 byte sectors)
+       lda #102                ; number of blocks (* 2 for 256 bytes sectors)
+       ldx #$1A00              ; dest address
+load_loop:
+       pshs a,b
+       bsr load_block
+       lda #'*'
+       sta ,y+
+       puls a,b
+       incb
+       deca
+       bne load_loop
+       ldx #$1A00
+       ldu #$0100
+vec_copy:
+       ldd ,x++
+       std ,u++
+       cmpu #$0200
+       bne vec_copy
+
+       ldx #$1A00
+       clra
+       clrb
+ud_wipe:
+       std ,x++
+       cmpx #$1C00
+       bne ud_wipe
+       lda ,x+
+       cmpa #$15
+       bne wrong_err
+       lda ,x+
+       cmpa #$C0
+       bne wrong_err
+       rts
+
+wrong_err:
+       ldu #wrong
+       bra l2
+load_error:
+       ldu #fail
+l2:    bsr copy_str
+l1:    bra l1
+
+copy_str:
+       lda ,u+
+       beq endstr
+       sta ,y+
+       bra copy_str
+endstr:        rts
+fail:
+       .ascii "Fail"
+       .db 0
+wrong:
+       .ascii "Wrong image"
+       .db 0
index fbd2960..f566efa 100644 (file)
@@ -15,7 +15,7 @@
 
 #define CONFIG_BANKS   1
 /* And swapping */
-#define SWAPDEV     0x0                /* Uses part of IDE slice 0 */
+#define SWAPDEV     0x900              /* Uses part of IDE slice 0 */
 #define SWAP_SIZE   0x40       /* 32K in 512 byte blocks */
 #define SWAPBASE    0x8000     /* We swap the lot */
 #define SWAPTOP     0xFE00     /* so it's a round number of 512 byte sectors */
@@ -24,6 +24,7 @@
 
 /* Permit large I/O requests to bypass cache and go direct to userspace */
 #define CONFIG_LARGE_IO_DIRECT
+#define CONFIG_LEGACY_EXEC
 
 /* Video terminal, not a serial tty */
 #define CONFIG_VT
index 5c3689b..3bcb457 100644 (file)
@@ -9,6 +9,7 @@
 #include <vt.h>
 #include <devtty.h>
 #include <mini_ide.h>
+#include <devsdc.h>
 #include <device.h>
 
 struct devsw dev_tab[] =  /* The device driver switch table */
@@ -31,6 +32,7 @@ struct devsw dev_tab[] =  /* The device driver switch table */
   {  nxio_open,     no_close,    no_rdwr,   no_rdwr,   no_ioctl },
   /* 8: /dev/dw                DriveWire remote disk images */
   {  dw_open,       no_close,    dw_read,   dw_write,  no_ioctl },
+  {  no_open,       no_close,    sdc_read,  sdc_write, no_ioctl },
 };
 
 bool validdev(uint16_t dev)
@@ -46,4 +48,5 @@ bool validdev(uint16_t dev)
 void device_init(void)
 {
     ide_probe();
+    devsdc_init();
 }
diff --git a/Kernel/platform-coco2cart/devsdc.c b/Kernel/platform-coco2cart/devsdc.c
new file mode 100644 (file)
index 0000000..a5814a8
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+
+ CoCoSDC driver
+ (c)2015 Brett M. Gordon GPL2
+
+ * Needs work on extended SDC API stuff.
+ * init / mounting stuff really needs to set/update blkdev structure for size
+ * need to get rawmode=1 and 2 working.
+
+*/
+
+#include <kernel.h>
+#include <kdata.h>
+#include <blkdev.h>
+#include <mbr.h>
+#include <devsdc.h>
+#include <printf.h>
+
+
+#define SDC_REG_BASE 0xff40
+#define SDC_REG_CTL (SDC_REG_BASE+0x00 )
+#define SDC_REG_DATA (SDC_REG_BASE+0x02 )
+#define SDC_REG_FCTL (SDC_REG_BASE+0x03 )
+#define SDC_REG_CMD  (SDC_REG_BASE+0x08 )
+#define SDC_REG_STAT (SDC_REG_BASE+0x08 )
+#define SDC_REG_PARAM1 (SDC_REG_BASE+0x09 )
+#define SDC_REG_PARAM2 (SDC_REG_BASE+0x0a )
+#define SDC_REG_PARAM3 (SDC_REG_BASE+0x0b )
+
+#define SDC_BUSY  0x01
+#define SDC_READY 0x02
+#define SDC_FAIL  0x80
+
+
+
+#define sdc_reg_ctl *((volatile uint8_t *)SDC_REG_CTL)
+#define sdc_reg_data *((volatile uint8_t *)SDC_REG_DATA)
+#define sdc_reg_fctl *((volatile uint8_t *)SDC_REG_FCTL)
+#define sdc_reg_cmd *((volatile uint8_t *)SDC_REG_CMD)
+#define sdc_reg_stat *((volatile uint8_t *)SDC_REG_STAT)
+#define sdc_reg_param1 *((volatile uint8_t *)SDC_REG_PARAM1)
+#define sdc_reg_param2 *((volatile uint8_t *)SDC_REG_PARAM2)
+#define sdc_reg_param3 *((volatile uint8_t *)SDC_REG_PARAM3)
+
+
+/* Assembler glue */
+
+extern void sdc_read_data(uint8_t *p);
+extern void sdc_write_data(uint8_t *p);
+extern uint8_t sdcpage;
+
+/* a "simple" internal function pointer to which transfer
+   routine to use. The is_read var might be better stored
+   in a way that the asm helpers could do self modifying.
+*/
+typedef void (*sdc_transfer_function_t)( unsigned char *addr);
+
+
+
+/* blkdev method: transfer sectors */
+static uint8_t sdc_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
+{
+               uint8_t nb = udata.u_nblock;  /* our return value, preset to failure */
+       uint32_t lba;             /* holds 32 bit lsn */
+       uint8_t *ptr = ((uint8_t *)&lba)+1;      /* points to 24 bit lba in blk op */
+       uint8_t t;                /* temporarory sdc status holder */
+       uint8_t cmd;              /* holds SDC command value */
+       sdc_transfer_function_t fptr;  /* holds which xfer routine we want */
+
+       if (rawflag == 1 && d_blkoff(9) )
+               return -1;
+
+       /* pass rawflag to assembler */
+       sdcpage = rawflag;
+
+
+       /* we get 256 bytes per lba in SDC so convert */
+       udata.u_nblock *= 2;
+       lba = udata.u_block * 2;
+       ptr[0] |= (minor & 0x7f) << 1;
+
+       /* setup cmd pointer and command value from blk_op */
+       if( is_read ){
+               cmd = 0x80;
+               fptr = sdc_read_data;
+       }
+       else{
+               cmd = 0xa0;
+               fptr = sdc_write_data;
+       }
+
+       /* apply our drive value 0 or 1*/
+       if( minor & 0x80 )
+               cmd++;
+
+       while(udata.u_nblock--){
+               /* load up registers */
+               sdc_reg_param1 = ptr[0];
+               sdc_reg_param2 = ptr[1];
+               sdc_reg_param3 = ptr[2];
+               sdc_reg_cmd= cmd;
+               asm("\texg x,x\n");     /* delay 16us minimum */
+               asm("\texg x,x\n");
+               /* wait till SDC is ready */
+               do{
+                       t=sdc_reg_stat;
+                       if( t & SDC_FAIL ) goto fail;
+               } while( ! (t & SDC_READY) );
+               /* do our low-level xfer function */
+               fptr( udata.u_dptr );
+               /* and wait will ready again, and test for failure */
+               do{
+                       t=sdc_reg_stat;
+                       if( t & SDC_FAIL ) goto fail;
+               }while ( t & SDC_BUSY );
+               /* increment our blk_op values for next 256 bytes sector */
+               udata.u_dptr += 256;
+               lba++;
+       }
+       /*  Huzzah!  success! */
+       return nb;
+       /* Boo!  failure */
+ fail: sdc_reg_ctl = 0x00;
+       udata.u_error = EIO;
+       return -1;
+}
+
+
+int sdc_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    return sdc_transfer(minor, true, rawflag);
+}
+
+int sdc_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
+{
+    return sdc_transfer(minor, false, rawflag);
+}
+
+
+
+
+
+__attribute__((section(".discard")))
+/* Returns true if SDC hardware seems to exist */
+bool devsdc_exist()
+{
+       uint8_t t;
+       sdc_reg_data=0x64;
+       t=sdc_reg_fctl;
+       sdc_reg_data=0x00;
+       if( (sdc_reg_fctl ^ t) == 0x60 ) return -1;
+       else return 0;
+}
+
+__attribute__((section(".discard")))
+/* Call this to initialize SDC/blkdev interface */
+void devsdc_init()
+{
+       kputs("SDC: ");
+       if( devsdc_exist() ){
+               /* turn on uber-secret SDC LBA mode*/
+               sdc_reg_ctl = 0x43; 
+               kputs("Ok.\n");
+       }
+       else kprintf("Not Found.\n");
+}
+
diff --git a/Kernel/platform-coco2cart/devsdc.h b/Kernel/platform-coco2cart/devsdc.h
new file mode 100644 (file)
index 0000000..5c67146
--- /dev/null
@@ -0,0 +1,8 @@
+
+
+extern int sdc_open(uint8_t minor, uint16_t flag);
+extern int sdc_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
+extern int sdc_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
+extern int sdc_ioctl(uint8_t minor, uarg_t request, char *data);
+
+extern uint8_t sdc_present;
index 85962fe..1dfba90 100644 (file)
@@ -220,11 +220,11 @@ lprrtw:   .db 0x23        ; request for time
 
 ; Used by DWRead and DWWrite
 IntMasks equ   $50
-NOINTMASK equ  1
+NOINTMASK equ  0
 
 ; Hardcode these for now so that we can use below files unmodified
 H6309    equ 0
-BECKER   equ 1
+BECKER   equ 0
 ARDUINO  equ 0
 JMCPBCK  equ 0
 BAUD38400 equ 0
diff --git a/Kernel/platform-coco2cart/sdc.s b/Kernel/platform-coco2cart/sdc.s
new file mode 100644 (file)
index 0000000..e69de29