From d9fbe5704d115f3f67f5457fb13ecc8f5ff465e0 Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Tue, 29 Mar 2022 20:51:02 -0700 Subject: [PATCH] Allow ROMs of any size * ROMs will be rounded up to the nearest 32KiB and filled with zeroes. * Still attempt to run the game even if the GB header info isn't valid. * Don't print any non-ascii characters in the title Partial fix for #43. --- docs/binjgb.wasm | Bin 108679 -> 108765 bytes docs/demo.js | 11 +++++++---- docs/simple.js | 11 +++++++---- src/binjgb.c | 2 +- src/common.c | 10 ++++++++-- src/common.h | 1 + src/debugger/debugger.cc | 2 +- src/emulator.c | 25 ++++++++++++++++++------- src/emulator.h | 3 +++ src/tester.c | 2 +- 10 files changed, 47 insertions(+), 20 deletions(-) diff --git a/docs/binjgb.wasm b/docs/binjgb.wasm index bf03a39fb0dd5ca896acd0d9ca445b996af2fb70..cc145748e4ccfd02ec9089e3000e3019c74bd5b0 100644 GIT binary patch delta 11270 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 I3>)G90a2x<%K!iX delta 11196 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 baU7l_Q}J>z{d?X?OyB%9Q$n2KoWuVCdata = data; - out_file_data->size = size; + out_file_data->size = aligned_size; return OK; ON_ERROR_CLOSE_FILE_AND_RETURN; } diff --git a/src/common.h b/src/common.h index 8b68109..dbd522e 100644 --- a/src/common.h +++ b/src/common.h @@ -109,6 +109,7 @@ typedef struct JoypadButtons { const char* replace_extension(const char* filename, const char* extension); Result file_read(const char* filename, FileData* out); +Result file_read_aligned(const char* filename, size_t align, FileData* out); Result file_write(const char* filename, const FileData*); void file_data_delete(FileData*); diff --git a/src/debugger/debugger.cc b/src/debugger/debugger.cc index 9d7456d..99d4cb1 100644 --- a/src/debugger/debugger.cc +++ b/src/debugger/debugger.cc @@ -117,7 +117,7 @@ bool Debugger::Init(const char* filename, int audio_frequency, int audio_frames, u32 builtin_palette, bool force_dmg, bool use_sgb_border, CgbColorCurve cgb_color_curve) { FileData rom; - if (!SUCCESS(file_read(filename, &rom))) { + if (!SUCCESS(file_read_aligned(filename, MINIMUM_ROM_SIZE, &rom))) { return false; } diff --git a/src/emulator.c b/src/emulator.c index 7249009..ac3931a 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -11,8 +11,6 @@ #include "emulator.h" -#define MAXIMUM_ROM_SIZE MEGABYTES(8) -#define MINIMUM_ROM_SIZE KILOBYTES(32) #define MAX_CART_INFOS (MAXIMUM_ROM_SIZE / MINIMUM_ROM_SIZE) #define VIDEO_RAM_SIZE KILOBYTES(16) #define WORK_RAM_SIZE KILOBYTES(32) @@ -1115,7 +1113,7 @@ static void set_cart_info(Emulator* e, u8 index) { } static Result get_cart_info(FileData* file_data, size_t offset, - CartInfo* cart_info) { + CartInfo* cart_info, Bool require_logo_checksum) { /* Simple checksum on logo data so we don't have to include it here. :) */ u8* data = file_data->data + offset; size_t i; @@ -1123,14 +1121,14 @@ static Result get_cart_info(FileData* file_data, size_t offset, for (i = LOGO_START_ADDR; i <= LOGO_END_ADDR; ++i) { logo_checksum = (logo_checksum << 1) ^ data[i]; } - CHECK(logo_checksum == 0xe06c8834); + CHECK(!require_logo_checksum || logo_checksum == 0xe06c8834); cart_info->offset = offset; cart_info->data = data; cart_info->rom_size = data[ROM_SIZE_ADDR]; /* HACK(binji): The mooneye-gb multicart test doesn't set any of the header * bits, even though multicart games all seem to. Just force the values in * reasonable defaults in that case. */ - if (offset != 0 && !is_rom_size_valid(cart_info->rom_size)) { + if (!is_rom_size_valid(cart_info->rom_size)) { cart_info->rom_size = ROM_SIZE_32K; cart_info->cgb_flag = CGB_FLAG_NONE; cart_info->sgb_flag = SGB_FLAG_NONE; @@ -1165,7 +1163,8 @@ static Result get_cart_infos(Emulator* e) { for (i = 0; i < MAX_CART_INFOS; ++i) { size_t offset = i << CART_INFO_SHIFT; if (offset + MINIMUM_ROM_SIZE > e->file_data.size) break; - if (SUCCESS(get_cart_info(&e->file_data, offset, &e->cart_infos[i]))) { + if (SUCCESS( + get_cart_info(&e->file_data, offset, &e->cart_infos[i], TRUE))) { if (s_cart_type_info[e->cart_infos[i].cart_type].mbc_type == MBC_TYPE_MMM01) { /* MMM01 has the cart header at the end. */ @@ -1175,6 +1174,11 @@ static Result get_cart_infos(Emulator* e) { e->cart_info_count++; } } + // Maybe the logo checksum failed; try again without it required. + if (e->cart_info_count == 0 && + SUCCESS(get_cart_info(&e->file_data, 0, &e->cart_infos[0], FALSE))) { + e->cart_info_count++; + } CHECK_MSG(e->cart_info_count != 0, "Invalid ROM.\n"); set_cart_info(e, 0); return OK; @@ -4647,11 +4651,18 @@ static const char* get_result_string(Result value) { } static void log_cart_info(CartInfo* cart_info) { + unsigned char title[TITLE_MAX_LENGTH + 1] = {0}; char* title_start = (char*)cart_info->data + TITLE_START_ADDR; char* title_end = memchr(title_start, '\0', TITLE_MAX_LENGTH); int title_length = (int)(title_end ? title_end - title_start : TITLE_MAX_LENGTH); - printf("title: \"%.*s\"\n", title_length, title_start); + memcpy(title, title_start, title_length); + // Change all non-ascii characters to ' '. + int i; + for (i = 0; i < title_length; ++i) { + if (title[i] < 32 || title[i] >= 128) { title[i] = ' '; } + } + printf("title: \"%s\"\n", title); printf("cgb flag: %s\n", get_cgb_flag_string(cart_info->cgb_flag)); printf("sgb flag: %s\n", get_sgb_flag_string(cart_info->sgb_flag)); printf("cart type: %s\n", get_cart_type_string(cart_info->cart_type)); diff --git a/src/emulator.h b/src/emulator.h index 701ab4e..e624499 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -13,6 +13,9 @@ extern "C" { #endif +#define MAXIMUM_ROM_SIZE MEGABYTES(8) +#define MINIMUM_ROM_SIZE KILOBYTES(32) + #define SCREEN_WIDTH 160 #define SCREEN_HEIGHT 144 #define SCREEN_HEIGHT_WITH_VBLANK 154 diff --git a/src/tester.c b/src/tester.c index 62ca2cf..2841913 100644 --- a/src/tester.c +++ b/src/tester.c @@ -435,7 +435,7 @@ int main(int argc, char** argv) { parse_options(argc, argv); FileData rom; - CHECK(SUCCESS(file_read(s_rom_filename, &rom))); + CHECK(SUCCESS(file_read_aligned(s_rom_filename, MINIMUM_ROM_SIZE, &rom))); EmulatorInit emulator_init; ZERO_MEMORY(emulator_init);