diff --git a/src/common.h b/src/common.h index 3b15300..938b9dd 100644 --- a/src/common.h +++ b/src/common.h @@ -385,7 +385,7 @@ bool flash_erase_sectors(uint32_t baseaddr, unsigned sectsize, unsigned sectcoun void flash_read(uint32_t baseaddr, uint8_t *buf, unsigned size); bool flash_check_erased(uintptr_t addr, unsigned size); bool flash_program(uint32_t baseaddr, const uint8_t *buf, unsigned size); -bool flash_program_buffered(uint32_t baseaddr, const uint8_t *buf, unsigned size, unsigned bufsize); +bool flash_program_buffered(uint32_t baseaddr, const uint8_t *buf, unsigned size, unsigned bufsize, bool precopy); bool flash_verify(uint32_t baseaddr, const uint8_t *buf, unsigned size); void flash_erase_fsm_start(t_flash_erase_state *st, uint32_t baseaddr, unsigned sectsize, unsigned sectorcnt); int flash_erase_fsm_step(t_flash_erase_state *st); diff --git a/src/flash.c b/src/flash.c index 3c3cc76..7a9f0c8 100644 --- a/src/flash.c +++ b/src/flash.c @@ -336,20 +336,28 @@ bool flash_program(uint32_t baseaddr, const uint8_t *buf, unsigned size) { } // Programs the built-in flash memory using the internal write buffer. -bool flash_program_buffered(uint32_t baseaddr, const uint8_t *buf, unsigned size, unsigned bufsize) { +bool flash_program_buffered(uint32_t baseaddr, const uint8_t *buf, unsigned size, unsigned bufsize, bool precopy) { // Reset any previous command that might be ongoing. FLASH_WE_MODE(); SLOT2_BASE_U16[0] = 0x00F0; const unsigned wrsize = MIN(bufsize, 512); + union { + uint16_t b16[256]; + uint32_t b32[128]; + } tmp; - for (unsigned i = 0; i < size; i += 512) { - union { - uint16_t b16[256]; - uint32_t b32[128]; - } tmp; + if (precopy) { set_supercard_mode(MAPPED_SDRAM, true, true); - dma_memcpy32(tmp.b32, &buf[i], sizeof(tmp) / 4); + dma_memcpy32(tmp.b32, &buf[0], sizeof(tmp) / 4); FLASH_WE_MODE(); + } + + for (unsigned i = 0; i < size; i += 512) { + if (!precopy) { + set_supercard_mode(MAPPED_SDRAM, true, true); + dma_memcpy32(tmp.b32, &buf[i], sizeof(tmp) / 4); + FLASH_WE_MODE(); + } for (unsigned off = 0; off < 512 && i+off < size; off += wrsize) { const uint32_t toff = (i + off); @@ -366,6 +374,15 @@ bool flash_program_buffered(uint32_t baseaddr, const uint8_t *buf, unsigned size *(ptr-1) = 0x29; // Confirm write buffer operation. + if (precopy) { + set_supercard_mode(MAPPED_SDRAM, true, true); + // off, off+wrsize is programmed, copy next chunk off, off+wrsize + unsigned next_chunk = i + 512; + if (next_chunk < size) { + dma_memcpy32(tmp.b32+(off/4), &buf[next_chunk + off], wrsize / 4); + } + FLASH_WE_MODE(); + } // Wait a bit for the operation to finish. for (unsigned j = 0; j < 32*1024; j++) { if (SLOT2_BASE_U16[0] == SLOT2_BASE_U16[0]) diff --git a/src/loader.c b/src/loader.c index c5d3b09..b0a9993 100644 --- a/src/loader.c +++ b/src/loader.c @@ -400,6 +400,8 @@ unsigned flash_gba_nor( // Map the game to the base 32MiB address space. set_superchis_normap(blkmap); + slowsd = use_slowld; + t_flash_erase_state erst; for (uint32_t bigoff = 0; bigoff < fs; bigoff += ssize) { // Start clearing the flash block we will be writing to! @@ -412,13 +414,14 @@ unsigned flash_gba_nor( if (progress) progress((bigoff + offset / 4) >> 8, fs >> 8); - flash_erase_fsm_step(&erst); + if (!slowsd) flash_erase_fsm_step(&erst); } unsigned toread = MIN(LOAD_BS, fs - absoff); UINT rdbytes; uint32_t tmp[LOAD_BS/4]; if (FR_OK != f_read(&fd, tmp, toread, &rdbytes)) { + slowsd = true; f_close(&fd); reset_superchis_normap(); return ERR_LOAD_BADROM; @@ -457,7 +460,7 @@ unsigned flash_gba_nor( progress((bigoff + ssize / 4 + offset * 3/4) >> 8, fs >> 8); unsigned toflash = MIN(flashinfo.blksize, fs - absoff); - if (!flash_program_buffered(flashaddr, &scratch[offset], toflash, flashinfo.blkwrite)) { + if (!flash_program_buffered(flashaddr, &scratch[offset], toflash, flashinfo.blkwrite, !slowsd)) { f_close(&fd); reset_superchis_normap(); return ERR_FLASH_OP; @@ -465,6 +468,9 @@ unsigned flash_gba_nor( } } + slowsd = true; + + f_close(&fd); reset_superchis_normap(); return 0; } diff --git a/src/menu.c b/src/menu.c index fd352ad..5d077c2 100644 --- a/src/menu.c +++ b/src/menu.c @@ -2279,7 +2279,7 @@ void start_flash_update(const char *fn, unsigned fwsize, bool validate_superfw) bool programmed_ok; #ifdef SUPPORT_NORGAMES if (flashinfo.size && flashinfo.blksize && flashinfo.blkcount && flashinfo.blkwrite) - programmed_ok = flash_program_buffered(ROM_FLASHFIRMW_ADDR, sdr_state->scratch, fwsize, flashinfo.blkwrite); + programmed_ok = flash_program_buffered(ROM_FLASHFIRMW_ADDR, sdr_state->scratch, fwsize, flashinfo.blkwrite, !use_slowld); else #endif programmed_ok = flash_program(ROM_FLASHFIRMW_ADDR, sdr_state->scratch, fwsize);