fuzix path
authorBrett Gordon <beretta42@gmail.com>
Sun, 12 Jul 2015 15:48:45 +0000 (11:48 -0400)
committerAlan Cox <alan@linux.intel.com>
Sun, 12 Jul 2015 19:39:22 +0000 (20:39 +0100)
--001a113d2c22535242051aaf8a38
Content-Type: text/plain; charset=UTF-8

* preliminary CoCoSDC "enhanced" mode drivers written.

--
Brett M. Gordon,
beretta42@gmail.com

<div dir="ltr">* preliminary CoCoSDC &quot;enhanced&quot; mode drivers written.<br clear="all"><div><br></div>-- <br><div class="gmail_signature">Brett M. Gordon,<br><a href="mailto:beretta42@gmail.com" target="_blank">beretta42@gmail.com</a></div>
</div>

Kernel/platform-coco3/Makefile
Kernel/platform-coco3/config.h
Kernel/platform-coco3/devices.c
Kernel/platform-coco3/devsdc.c [new file with mode: 0644]
Kernel/platform-coco3/devsdc.h [new file with mode: 0644]
Kernel/platform-coco3/sdc.s [new file with mode: 0644]

index 1dbb7fa..a356f36 100644 (file)
@@ -1,12 +1,12 @@
 
 CSRCS = devtty.c ttydw.c mbr.c
-CSRCS += devices.c main.c libc.c
+CSRCS += devices.c main.c libc.c devsdc.c
 
 DSRCS = ../dev/devdw.c ../dev/blkdev.c ../dev/devide.c
 DSRCS += ../dev/devide_discard.c
 
 ASRCS = coco3.s crt0.s ../platform-dragon-nx32/ide.s
-ASRCS += tricks.s commonmem.s usermem_gime.s drivewire.s
+ASRCS += tricks.s commonmem.s usermem_gime.s drivewire.s sdc.s
 
 COBJS = $(CSRCS:.c=$(BINEXT))
 AOBJS = $(ASRCS:.s=$(BINEXT))
@@ -39,7 +39,7 @@ image:
        coco3.o ../start.o ../version.o ../lowlevel-6809.o \
        tricks.o main.o ../timer.o ../kdata.o devices.o \
        drivewire.o devdw.o ttydw.o blkdev.o mbr.o devide.o devide_discard.o \
-       ../platform-dragon-nx32/ide.o \
+       ../platform-dragon-nx32/ide.o devsdc.o sdc.o \
        ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \
        ../syscall_proc.o ../syscall_other.o ../mm.o ../bank16k.o ../swap.o \
        ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \
index 66d4437..ce19aa5 100644 (file)
@@ -82,7 +82,7 @@ extern unsigned char vt_map( unsigned char c );
 #define DW_MIN_OFF  3     /* Minor number offset */
 
 /* Block device define */
-#define MAX_BLKDEV  2     /* IDE */
+#define MAX_BLKDEV  4     /* 2 IDE + 2 SDC */
 #define DEVICE_IDE        /* enable if IDE interface present */
 #define IDE_REG_CS1_BASE 0xFF50
 #define IDE_IS_MMIO  1         /* MMIO IDE */
index e518900..12b5845 100644 (file)
@@ -42,5 +42,6 @@ bool validdev(uint16_t dev)
 void device_init(void)
 {
        devide_init( );
+       devsdc_init( );
 }
 
diff --git a/Kernel/platform-coco3/devsdc.c b/Kernel/platform-coco3/devsdc.c
new file mode 100644 (file)
index 0000000..a7e1942
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+
+ 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)
+
+
+/* a "simple" internal function pointer to which transfer
+   routine to use.
+*/
+typedef void (*sdc_transfer_function_t)( void *addr);
+
+
+
+/* blkdev method: flush drive */
+int devsdc_flush( void )
+{
+       return 0;
+}
+
+
+/* blkdev method: transfer sectors */
+uint8_t devsdc_transfer(void)
+{
+               uint8_t ret=0;            /* our return value, preset to failure */
+       uint8_t *ptr;             /* points to 32 bit lba in blk op */
+       int i;                    /* iterator */
+       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 */
+
+       /* test for raw mode */
+       blk_op.
+          
+
+       /* turn on uber-secret SDC LBA mode*/
+       sdc_reg_ctl = 0x43; 
+
+       /* we get 256 bytes per lba in SDC so convert */
+       blk_op.lba*=2;
+
+       /* setup cmd pointer and command value from blk_op */
+       if( blk_op.is_read ){
+               cmd = 0x80;
+               fptr = devsdc_read;
+       }
+       else{
+               cmd = 0xa0;
+               fptr = devsdc_write;
+       }
+
+       /* or in our drive value */
+       cmd |= blk_op.blkdev->driver_data;
+
+       /* get/send two sectors (512 bytes) of data */
+       for( i=0; i<2; i++){
+               /* load up registers */
+               ptr=((uint8_t *)(&blk_op.lba))+1;
+               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( blk_op.addr );
+               /* 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 */
+               blk_op.lba++;
+               blk_op.addr+=256;
+       }
+       /*  Huzzah!  success! */
+       ret=1;    
+       /* Boo!  failure */
+ fail: sdc_reg_ctl = 0x00;
+       return ret;
+}
+
+
+/* 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;
+}
+
+
+/* Call this to initialize SDC/blkdev interface */
+void devsdc_init()
+{
+       blkdev_t *blk;
+
+       if( devsdc_exist() ){
+               /* register first drive */
+               blk=blkdev_alloc();
+               blk->driver_data = 0 ;
+               blk->transfer = devsdc_transfer;
+               blk->flush = devsdc_flush;
+               blk->drive_lba_count=-1;
+               /* register second drive */
+               blk=blkdev_alloc();
+               blk->driver_data = 1 ;
+               blk->transfer = devsdc_transfer;
+               blk->flush = devsdc_flush;
+               blk->drive_lba_count=-1;
+               kprintf("SDC: ok.\n");
+       }
+
+}
+
diff --git a/Kernel/platform-coco3/devsdc.h b/Kernel/platform-coco3/devsdc.h
new file mode 100644 (file)
index 0000000..b0f1e83
--- /dev/null
@@ -0,0 +1,4 @@
+
+
+void devsdc_read( char *addr );
+void devsdc_write( char *addr );
diff --git a/Kernel/platform-coco3/sdc.s b/Kernel/platform-coco3/sdc.s
new file mode 100644 (file)
index 0000000..0193e00
--- /dev/null
@@ -0,0 +1,72 @@
+;;;
+;;;  The CoCoSDC Driver
+;;;    Big thanks for Darren Atkinson for good documentation
+;;;    and help with autodetection in the init method
+;;;
+;;; 
+
+;;; imported
+       .globl blk_op           ; blk operation arguments
+
+;;; exported
+       .globl _devsdc_write
+       .globl _devsdc_read
+
+;;; dev
+
+*********************************************************************
+***    Hardware Addressing
+*********************************************************************
+CTRLATCH    equ    $FF40          ; controller latch (write)
+CMDREG      equ    $FF48          ; command register (write)
+STATREG     equ    $FF48          ; status register (read)
+PREG1       equ    $FF49          ; param register 1
+PREG2       equ    $FF4A          ; param register 2
+PREG3       equ    $FF4B          ; param register 3
+DATREGA     equ    PREG2          ; first data register
+DATREGB     equ    PREG3          ; second data register
+
+
+
+       section .common
+
+
+
+;;; Write 256 bytes from SDC
+_devsdc_write
+       pshs    y,u
+       ldy     #PREG2          ; set Y to point at data reg a
+       ldd     #64*256+4       ; A = chunk count (64), B = bytes per chunk (4)
+wrChnk  ldu            ,x              ; get 2 data bytes from source
+       stu     ,y              ; send data to controller
+       ldu     2,x             ; two more bytes..
+       stu     ,y              ; ..for this chunk
+       abx                     ; increment X by chunk size (4)
+       deca                    ; decrement loop counter
+       bne     wrChnk          ; loop until all chunks written
+       puls    y,u,pc          ; return
+
+;;; Reads 256 bytes from SDC
+_devsdc_read
+       pshs    y,u
+       ldy     #PREG2          ; set Y to point to data reg a
+       ldd     #32*256+8       ; A = chunk count (32), B = bytes per chunk (8)
+rdChnk         ldu     ,y              ; read 1st pair of bytes for the chunk
+       stu     ,x              ; store to buffer
+       ldu     ,y              ; bytes 3 and 4 of..
+       stu     2,x             ; ..the chunk
+       ldu     ,y              ; bytes 5 and 6 of..
+       stu     4,x             ; ..the chunk
+       ldu     ,y              ; bytes 7 and 8 of..
+       stu     6,x             ; ..the chunk
+       abx                     ; increment X by chunk size (8)
+       deca                    ; decrement loop counter
+       bne     rdChnk          ; loop if more chunks to read
+       puls    y,u,pc          ; return
+       
+
+
+
+
+
+