From 4b7dc9c5a08292d247beacecb57ee15b1353fd3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sat, 11 May 2013 18:27:00 +0000 Subject: [PATCH] works pretty reliable now under MiNT --- include/bas_string.h | 1 + sources/bas_string.c | 7 ++++ sources/mmc.c | 8 ++-- sources/xhdi_sd.c | 90 +++++++++++++++++++++++++++++++------------- sources/xhdi_vec.S | 4 -- 5 files changed, 76 insertions(+), 34 deletions(-) diff --git a/include/bas_string.h b/include/bas_string.h index 7f99cad..01ffe88 100644 --- a/include/bas_string.h +++ b/include/bas_string.h @@ -12,6 +12,7 @@ extern int strncmp(const char *s1, const char *s2, int max); extern char *strcpy(char *dst, const char *src); +char *strncpy(char *dst, const char *src, int max); extern size_t strlen(const char *str); extern char *strcat(char *dst, const char *src); extern char *strncat(char *dst, const char *src, int max); diff --git a/sources/bas_string.c b/sources/bas_string.c index f8ef732..6fb19b5 100644 --- a/sources/bas_string.c +++ b/sources/bas_string.c @@ -28,6 +28,13 @@ char *strcpy(char *dst, const char *src) return ptr; } +char *strncpy(char *dst, const char *src, int max) +{ + char *ptr = dst; + + while ((*dst++ = *src++) != '\0' && max-- >= 0); + return ptr; +} int atoi(const char *c) { int value = 0; diff --git a/sources/mmc.c b/sources/mmc.c index 78ca486..f2f5479 100644 --- a/sources/mmc.c +++ b/sources/mmc.c @@ -26,9 +26,9 @@ #define CS_LOW() { dspi_fifo_val |= MCF_DSPI_DTFR_CS5; } #define SPICLK_FAST() { MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */ \ - MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 1 clock DSPICS to DSPISCK delay prescaler */ \ - MCF_DSPI_DCTAR_PASC_1CLK | /* 1 clock DSPISCK to DSPICS negation prescaler */ \ - MCF_DSPI_DCTAR_PDT_1CLK | /* 1 clock delay between DSPICS assertions prescaler */ \ + MCF_DSPI_DCTAR_PCSSCK(0b11) | /* 1 clock DSPICS to DSPISCK delay prescaler */ \ + MCF_DSPI_DCTAR_PASC_3CLK | /* 1 clock DSPISCK to DSPICS negation prescaler */ \ + MCF_DSPI_DCTAR_PDT_3CLK | /* 1 clock delay between DSPICS assertions prescaler */ \ MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock Baudrate prescaler */ \ MCF_DSPI_DCTAR_ASC(0b0000) | /* 2 */ \ MCF_DSPI_DCTAR_DT(0b0000) | /* 2 */ \ @@ -249,7 +249,7 @@ int rcvr_datablock ( /* 1:OK, 0:Error */ ) { uint8_t token; - uint32_t target = MCF_SLT_SCNT(0) - (200 * 1000L * 132); + uint32_t target = MCF_SLT_SCNT(0) - (400 * 1000L * 132); do { /* Wait for DataStart token in timeout of 200ms */ token = xchg_spi(0xFF); diff --git a/sources/xhdi_sd.c b/sources/xhdi_sd.c index f69583c..f4a6d6b 100644 --- a/sources/xhdi_sd.c +++ b/sources/xhdi_sd.c @@ -30,6 +30,9 @@ #define DRIVER_VERSION 0x130 +#define MY_MAJOR 65 +#define MY_MINOR 0 + static BPB sd_bpb[4]; /* space for four partitions on SD card */ uint16_t xhdi_version(void) @@ -41,14 +44,7 @@ uint16_t xhdi_version(void) uint32_t xhdi_inquire_target(uint16_t major, uint16_t minor, uint32_t *block_size, uint32_t *flags, char *product_name) { - xprintf("xhdi_inquire_target() called\r\n"); - if (block_size != NULL) - { - *block_size = 512; - } - *flags = XH_TARGET_REMOVABLE; /* indicate that SD card can be removed */ - - return E_OK; + return xhdi_inquire_target2(major, minor, block_size, flags, product_name, 33); } uint32_t xhdi_reserve(uint16_t major, uint16_t minor, uint16_t do_reserve, uint16_t key) @@ -83,7 +79,7 @@ uint32_t xhdi_drivemap(void) return map; } -#define MY_MAJOR 255 +#define MY_MAJOR 65 #define MY_MINOR 0 uint32_t xhdi_inquire_device(uint16_t bios_device, uint16_t *major, uint16_t *minor, @@ -100,7 +96,7 @@ uint32_t xhdi_inquire_device(uint16_t bios_device, uint16_t *major, uint16_t *mi uint32_t xhdi_inquire_driver(uint16_t bios_device, char *name, char *version, char *company, uint16_t *ahdi_version, uint16_t *maxIPL) { - xprintf("xhdi_inquire_driver() called. bios_device = %x, name = %p, version = %p,\r\n" + xprintf("xhdi_inquire_driver() called. bios_device = %d, name = %p, version = %p,\r\n" "company = %p, ahdi_version = %p, max_IPL = %p\r\n", bios_device, name, version, company, ahdi_version, maxIPL); if (bios_device == 'S' - 'A') @@ -125,28 +121,60 @@ uint32_t xhdi_new_cookie(uint32_t newcookie) uint32_t xhdi_read_write(uint16_t major, uint16_t minor, uint16_t rwflag, uint32_t recno, uint16_t count, void *buf) { - xprintf("xhdi_read_write() called: major = %x, minor = %x, rwflag = %x, \r\nrecno = %lx, count = %lx, buf = %p\r\n", + int ret; + uint16_t num_sectors; + int16_t s_count = count; + uint16_t retries; + const uint16_t max_retries = 5; + xprintf("xhdi_read_write() called: major = %d, minor = %d, rwflag = %d, \r\nrecno = %lx, count = %lx, buf = %p\r\n", major, minor, rwflag, recno, count, buf); - if (major == MY_MAJOR && minor == MY_MINOR) + if (major == MY_MAJOR) { - if (rwflag & 1) /* write */ - { - disk_write(0, buf, recno, count); - } - else if (rwflag & 1 == 0) /* read */ - { - disk_read(0, buf, recno, count); - } + do { + num_sectors = ((s_count > 1) ? 1 : s_count); + + retries = 0; + do { + ret = ((rwflag & 1) ? disk_write(0, buf, recno, num_sectors) : disk_read(0, buf, recno, num_sectors)); + if (ret != RES_OK && retries > max_retries) + { + xprintf("error: %d\r\n", ret); + return ERROR; + } + else if (ret != RES_OK) + { + retries++; + continue; + } + } while (retries < max_retries && ret != RES_OK); + + buf += num_sectors * 512; + recno += num_sectors; + s_count -= num_sectors; + } while (s_count > 0); + xprintf("call ok. %d sector(s) %s\r\n", count, ((rwflag & 1) ? "written" : "read")); + return E_OK; } - return E_OK; + return EUNDEV; } uint32_t xhdi_inquire_target2(uint16_t major, uint16_t minor, uint32_t *block_size, uint32_t *device_flags, char *product_name, uint16_t stringlen) { - xprintf("xhdi_inquire_target2() called\r\n"); - return ERROR; + xprintf("xhdi_inquire_target2(major=%d, minor=%d) called\r\n", major, minor); + + if (major == MY_MAJOR) + { + if (block_size != NULL) *block_size = 512; + if (device_flags != NULL) *device_flags = XH_TARGET_REMOVABLE; + if (product_name != NULL) strncpy(product_name, "BaS SD driver", stringlen); + + xprintf("returning block_size %d, device_flags %d, product_name %s \r\n", *block_size, *device_flags, *product_name); + return E_OK; + + } + return EUNDEV; } uint32_t xhdi_inquire_device2(uint16_t bios_device, uint16_t *major, uint16_t *minor, @@ -156,7 +184,6 @@ uint32_t xhdi_inquire_device2(uint16_t bios_device, uint16_t *major, uint16_t *m if (bios_device == 'S' - 'A') { - return E_OK; } return EUNDEV; @@ -170,8 +197,19 @@ uint32_t xhdi_driver_special(uint32_t key1, uint32_t key2, uint16_t subopcode, v uint32_t xhdi_get_capacity(uint16_t major, uint16_t minor, uint32_t *blocks, uint32_t *bs) { - xprintf("xhdi_get_capacity() called\r\n"); - return ERROR; + xprintf("xhdi_get_capacity(major=%d, minor=%d) called\r\n", major, minor); + + if (major == MY_MAJOR) + { + if (disk_ioctl(0, GET_SECTOR_COUNT, blocks) != RES_OK) + return ERROR; + if (disk_ioctl(0, GET_SECTOR_SIZE, bs) != RES_OK) + return ERROR; + *bs = 512; + xprintf("returning %d blocks with %d blocksize (%d GB)\r\n", *blocks, *bs, *blocks / 2 / 1000 / 1000); + return E_OK; + } + return EUNDEV; } uint32_t xhdi_medium_changed(uint16_t major, uint16_t minor) diff --git a/sources/xhdi_vec.S b/sources/xhdi_vec.S index faf3813..321a069 100644 --- a/sources/xhdi_vec.S +++ b/sources/xhdi_vec.S @@ -16,10 +16,6 @@ _xhdi_vec: lea -12(sp),sp // save all used registers according to XHDI spec movem.l d1/a0-a1,(sp) - move.l _drvbits,d0 - bset.l #('S'-'A'),d0 // add drive S - move.l d0,_drvbits - pea 16(sp) // forward address of parameters on stack jsr _xhdi_call // to internal routine addq.l #4,sp // correct stack