From: geijoenr Date: Tue, 30 May 2017 18:37:38 +0000 (+0200) Subject: msx2 megasd: handle page crossings X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=e7f78d59b3a57b41749e28411b8e4aea807bd0e8;p=FUZIX.git msx2 megasd: handle page crossings Due to PROGLOAD being 0x0100, last block read in a page overflows to the next one. --- diff --git a/Kernel/platform-msx2/devmegasd.c b/Kernel/platform-msx2/devmegasd.c index 90690f67..868b8f7e 100644 --- a/Kernel/platform-msx2/devmegasd.c +++ b/Kernel/platform-msx2/devmegasd.c @@ -128,117 +128,58 @@ uint8_t sd_spi_receive_byte(void) * Target page is always mapped to slot_page2, and the target address offset accordingly. * */ -bool sd_spi_receive_sector(void) __naked +void sd_spi_txrx_sector(bool is_read) { - __asm - - ; map sd interface - ; - ld a,(_slotmfr) - call _mapslot_bank1 - ld a, #MSD_PAGE - ld (MFR_BANKSEL0),a - - ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET) - ld de, (_blk_op+BLKPARAM_ADDR_OFFSET) - push af - or a - jr z, starttx - - ; map process target page in slot_page2 if needed - ; - ld a,d - and #0xC0 - rlca - rlca ; a contains the page to map - ld b,#0 - ld c,a - ld hl,#U_DATA__U_PAGE - add hl,bc - ld a,(hl) - out(_RAM_PAGE2),a - -starttx: - ; calculate offset address in target page - ld a,d - and #0x3F - or #0x80 - ld d,a - ld hl,#MSD_RDWR - ld bc,#512 - jp looptxrx - __endasm; + uint16_t addr, len, len2; + uint8_t *page; + uint8_t page_offset; + + addr = ((uint16_t) blk_op.addr) % 0x4000 + 0x8000; + page_offset = (((uint16_t)blk_op.addr) / 0x4000); + page = &udata.u_page; + + len = 0xC000 - addr; + sd_spi_map_interface(); + + if (blk_op.is_user) { + RAM_PAGE2 = *(page + page_offset); + if (is_read) + memcpy((uint8_t *)addr, (uint8_t *)MSD_RDWR, + len < BLKSIZE ? len : BLKSIZE); + else + memcpy((uint8_t *)MSD_RDWR, (uint8_t *)addr, + len < BLKSIZE ? len : BLKSIZE); + if (len < BLKSIZE) { + /* handle page crossing */ + len2 = BLKSIZE - len; + RAM_PAGE2 = *(page + page_offset + 1); + if (is_read) + memcpy((uint8_t *)0x8000, (uint8_t *)MSD_RDWR, len2); + else + memcpy((uint8_t *)MSD_RDWR, (uint8_t *)0x8000, len2); + } + RAM_PAGE2 = 1; + } else { + /* kernel only */ + if (is_read) + memcpy((uint8_t *)addr, (uint8_t *)MSD_RDWR, BLKSIZE); + else + memcpy((uint8_t *)MSD_RDWR, (uint8_t *)addr, BLKSIZE); + } + sd_spi_unmap_interface(); +} + + +bool sd_spi_receive_sector(void) +{ + sd_spi_txrx_sector(true); + return true; } -bool sd_spi_transmit_sector(void) __naked +bool sd_spi_transmit_sector(void) { - __asm - - ; map sd interface - ; - ld a,(_slotmfr) - call _mapslot_bank1 - ld a, #MSD_PAGE - ld (MFR_BANKSEL0),a - - ; map process target page in slot_page2 - ; - ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET) - ld de, (_blk_op+BLKPARAM_ADDR_OFFSET); - push af - or a - jr z, startrx - - ; map process target page in slot_page2 if needed - ; - ld a,d - and #0xC0 - rlca - rlca ; a contains the page to map - ld b,#0 - ld c,a - ld hl,#U_DATA__U_PAGE - add hl,bc - ld a,(hl) - out(_RAM_PAGE2),a - -startrx: - ; calculate offset address in target page - ld a,d - and #0x3F - or #0x80 - ld d,a - ld hl,#MSD_RDWR - ex de,hl - ld bc,#512 -looptxrx: - ldi ; 16x ldi: 19% faster - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - ldi - jp pe, looptxrx - - ; unmap interface - ; - ld a,(_slotram) - call _mapslot_bank1 - pop af - or a - ret z - jp _map_kernel - __endasm; + sd_spi_txrx_sector(false); + return true; } #endif