Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 24 additions & 7 deletions src/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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])
Expand Down
10 changes: 8 additions & 2 deletions src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand All @@ -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;
Expand Down Expand Up @@ -457,14 +460,17 @@ 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;
}
}
}

slowsd = true;

f_close(&fd);
reset_superchis_normap();
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down