Skip to content

Commit b455273

Browse files
committed
Fast load last rom and prevent pico's flash wearoff
1 parent fd6550f commit b455273

File tree

2 files changed

+50
-50
lines changed

2 files changed

+50
-50
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
release
1+
# v0.6.1
2+
3+
Fast load previous rom after reboot, prevents PICO flash wearoff also

src/main.cpp

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
* Game Boy DMG ROM size ranges from 32768 bytes (e.g. Tetris) to 1,048,576 bytes (e.g. Pokemod Red)
7777
*/
7878
#define FLASH_TARGET_OFFSET (1024 * 1024)
79-
const uint8_t *rom = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);
79+
const char *rom_filename = (const char*) (XIP_BASE + FLASH_TARGET_OFFSET);
80+
const uint8_t *rom = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET)+4096;
8081
static unsigned char rom_bank0[65535];
8182

8283
static uint8_t ram[32768];
@@ -86,7 +87,7 @@ struct semaphore vga_start_semaphore;
8687

8788
struct gb_s gb;
8889

89-
uint8_t screen[LCD_HEIGHT][LCD_WIDTH];
90+
uint8_t SCREEN[LCD_HEIGHT][LCD_WIDTH];
9091
char textmode[30][80];
9192
uint8_t colors[30][80];
9293

@@ -257,7 +258,7 @@ void __time_critical_func(render_loop)() {
257258
case RESOLUTION_4X3:
258259
if (y >= 24 && y < (24 + LCD_HEIGHT * 3)) {
259260
for (int x = 0; x < LCD_WIDTH * 4; x += 4) {
260-
pixel = screen[(y - 24) / 3][x / 4];
261+
pixel = SCREEN[(y - 24) / 3][x / 4];
261262
(uint32_t &) linebuf->line[x] = X4(palette[(pixel & LCD_PALETTE_ALL) >> 4][pixel & 3]);
262263
}
263264
} else {
@@ -268,7 +269,7 @@ void __time_critical_func(render_loop)() {
268269
if (y >= 24 && y < (24 + LCD_HEIGHT * 3)) {
269270
for (int x = 0; x < LCD_WIDTH; x++) {
270271
uint16_t x3 = 80 + (x << 1) + x;
271-
pixel = screen[(y - 24) / 3][x];
272+
pixel = SCREEN[(y - 24) / 3][x];
272273
color = palette[(pixel & LCD_PALETTE_ALL) >> 4][pixel & 3];
273274
linebuf->line[x3] = color;
274275
linebuf->line[x3 + 1] = color;
@@ -282,7 +283,7 @@ void __time_critical_func(render_loop)() {
282283
//if (y >= 48 && y < 48 + LCD_HEIGHT) {
283284
if (y >= 96 && y < (96 + LCD_HEIGHT * 2)) {
284285
for (int x = 0; x < LCD_WIDTH * 2; x += 2) {
285-
pixel = screen[(y - 96) / 2][x / 2];
286+
pixel = SCREEN[(y - 96) / 2][x / 2];
286287
(uint16_t &) linebuf->line[160 + x] = X2(palette[(pixel & LCD_PALETTE_ALL) >> 4][pixel & 3]);
287288
}
288289
} else {
@@ -307,7 +308,7 @@ void __time_critical_func(render_loop)() {
307308
break;
308309
case RESOLUTION_NATIVE:
309310
if (y >= 168 && y < 168 + LCD_HEIGHT) {
310-
memcpy(&linebuf->line[240], &screen[y - 168][0], LCD_WIDTH);
311+
memcpy(&linebuf->line[240], &SCREEN[y - 168][0], LCD_WIDTH);
311312
} else {
312313
memset(linebuf->line, 0, 640);
313314
}
@@ -325,7 +326,7 @@ void __time_critical_func(render_loop)() {
325326
* Draws scanline into framebuffer.
326327
*/
327328
void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[160], const uint_fast8_t y) {
328-
memcpy((uint32_t *)screen[y], (uint32_t *)pixels, 160);
329+
memcpy((uint32_t *)SCREEN[y], (uint32_t *)pixels, 160);
329330
// screen[y][x] = palette[(pixels[x] & LCD_PALETTE_ALL) >> 4][pixels[x] & 3];
330331
//for (unsigned int x = 0; x < LCD_WIDTH; x++)
331332
// screen[y][x] = palette[(pixels[x] & LCD_PALETTE_ALL) >> 4][pixels[x] & 3];
@@ -403,62 +404,59 @@ void write_cart_ram_file(struct gb_s *gb) {
403404
printf("I write_cart_ram_file(%s) COMPLETE (%u bytes)\n", filename, save_size);
404405
}
405406

406-
/**
407-
* Load a .gb rom file in flash from the SD card
408-
*/
409407
void load_cart_rom_file(char *filename) {
410-
UINT br = 0;
411-
uint8_t buffer[FLASH_SECTOR_SIZE];
412-
bool mismatch = false;
413-
414-
FRESULT fr = f_mount(&fs, "", 1);
415-
if (FR_OK != fr) {
416-
printf("E f_mount error: %s (%d)\n", FRESULT_str(fr), fr);
408+
if (strcmp(rom_filename, filename) == 0) {
409+
printf("Launching last rom");
417410
return;
418411
}
412+
419413
FIL fil;
414+
FRESULT fr;
415+
416+
size_t bufsize = sizeof(SCREEN);
417+
BYTE *buffer = (BYTE *) SCREEN;
418+
auto ofs = FLASH_TARGET_OFFSET;
419+
printf("Writing %s rom to flash %x\r\n", filename, ofs);
420420
fr = f_open(&fil, filename, FA_READ);
421+
422+
UINT bytesRead;
421423
if (fr == FR_OK) {
422-
multicore_lockout_start_blocking();
423424
uint32_t ints = save_and_disable_interrupts();
424-
uint32_t flash_target_offset = FLASH_TARGET_OFFSET;
425+
multicore_lockout_start_blocking();
426+
427+
// TODO: Save it after success loading to prevent corruptions
428+
printf("Flashing %d bytes to flash address %x\r\n", 256, ofs);
429+
flash_range_erase(ofs, 4096);
430+
flash_range_program(ofs, reinterpret_cast<const uint8_t *>(filename), 256);
431+
432+
ofs += 4096;
425433
for (;;) {
426-
f_read(&fil, buffer, sizeof buffer, &br);
427-
if (br == 0)
428-
break; /* end of file */
429-
430-
printf("I Erasing target region...\n");
431-
flash_range_erase(flash_target_offset, FLASH_SECTOR_SIZE);
432-
printf("I Programming target region...\n");
433-
flash_range_program(flash_target_offset, buffer, FLASH_SECTOR_SIZE);
434-
/* Read back target region and check programming */
435-
printf("I Done. Reading back target region...\n");
436-
for (uint32_t i = 0; i < FLASH_SECTOR_SIZE; i++) {
437-
if (rom[flash_target_offset + i] != buffer[i]) {
438-
mismatch = true;
434+
fr = f_read(&fil, buffer, bufsize, &bytesRead);
435+
if (fr == FR_OK) {
436+
if (bytesRead == 0) {
437+
break;
439438
}
440-
}
441439

442-
/* Next sector */
443-
flash_target_offset += FLASH_SECTOR_SIZE;
440+
printf("Flashing %d bytes to flash address %x\r\n", bytesRead, ofs);
441+
442+
printf("Erasing...");
443+
// Disable interupts, erase, flash and enable interrupts
444+
flash_range_erase(ofs, bufsize);
445+
printf(" -> Flashing...\r\n");
446+
flash_range_program(ofs, buffer, bufsize);
447+
448+
ofs += bufsize;
449+
} else {
450+
printf("Error reading rom: %d\n", fr);
451+
break;
452+
}
444453
}
454+
455+
456+
f_close(&fil);
445457
restore_interrupts(ints);
446458
multicore_lockout_end_blocking();
447-
if (mismatch) {
448-
printf("I Programming successful!\n");
449-
} else {
450-
printf("E Programming failed!\n");
451-
}
452-
} else {
453-
printf("E f_open(%s) error: %s (%d)\n", filename, FRESULT_str(fr), fr);
454459
}
455-
456-
fr = f_close(&fil);
457-
if (fr != FR_OK) {
458-
printf("E f_close error: %s (%d)\n", FRESULT_str(fr), fr);
459-
}
460-
461-
printf("I load_cart_rom_file(%s) COMPLETE (%u bytes)\n", filename, br);
462460
}
463461

464462
/**

0 commit comments

Comments
 (0)