From aaea708da2c2c680fe68e77e9e9269e93d23a28a Mon Sep 17 00:00:00 2001 From: Brett Gordon Date: Sun, 12 Jul 2015 11:48:45 -0400 Subject: [PATCH] fuzix path --001a113d2c22535242051aaf8a38 Content-Type: text/plain; charset=UTF-8 * preliminary CoCoSDC "enhanced" mode drivers written. -- Brett M. Gordon, beretta42@gmail.com
* preliminary CoCoSDC "enhanced" mode drivers written.

--
Brett M. Gordon,
beretta42@gmail.com
--- Kernel/platform-coco3/Makefile | 6 +- Kernel/platform-coco3/config.h | 2 +- Kernel/platform-coco3/devices.c | 1 + Kernel/platform-coco3/devsdc.c | 161 ++++++++++++++++++++++++++++++++ Kernel/platform-coco3/devsdc.h | 4 + Kernel/platform-coco3/sdc.s | 72 ++++++++++++++ 6 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 Kernel/platform-coco3/devsdc.c create mode 100644 Kernel/platform-coco3/devsdc.h create mode 100644 Kernel/platform-coco3/sdc.s diff --git a/Kernel/platform-coco3/Makefile b/Kernel/platform-coco3/Makefile index 1dbb7fae..a356f367 100644 --- a/Kernel/platform-coco3/Makefile +++ b/Kernel/platform-coco3/Makefile @@ -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 \ diff --git a/Kernel/platform-coco3/config.h b/Kernel/platform-coco3/config.h index 66d44371..ce19aa51 100644 --- a/Kernel/platform-coco3/config.h +++ b/Kernel/platform-coco3/config.h @@ -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 */ diff --git a/Kernel/platform-coco3/devices.c b/Kernel/platform-coco3/devices.c index e5189006..12b5845c 100644 --- a/Kernel/platform-coco3/devices.c +++ b/Kernel/platform-coco3/devices.c @@ -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 index 00000000..a7e19423 --- /dev/null +++ b/Kernel/platform-coco3/devsdc.c @@ -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 +#include +#include +#include +#include +#include + + +#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 index 00000000..b0f1e838 --- /dev/null +++ b/Kernel/platform-coco3/devsdc.h @@ -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 index 00000000..0193e004 --- /dev/null +++ b/Kernel/platform-coco3/sdc.s @@ -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 + + + + + + + -- 2.34.1