diff --git a/README.md b/README.md index cdfa288..912ad7e 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ The following cartridge types are currently supported: The following file types are currently supported: * Cartridge (CRT) -* C128 external function ROM (ROM, BIN) +* C64/C128 Generic cartridge (ROM, BIN) * Disk image (D64, D71, D81) * Tape image (T64) * Program (PRG, P00) diff --git a/firmware/menu.c b/firmware/menu.c index 6b8519a..1dc3d4b 100644 --- a/firmware/menu.c +++ b/firmware/menu.c @@ -215,8 +215,9 @@ static u8 handle_file_options(const char *file_name, u8 file_type, u8 element_no break; case FILE_CRT: - select_text = "Run"; vic_text = "Run (VIC-II/C128 mode)"; + case FILE_ROM: + select_text = "Run"; break; case FILE_P00: diff --git a/firmware/menu_sd.c b/firmware/menu_sd.c index 29f5339..21a8a7a 100644 --- a/firmware/menu_sd.c +++ b/firmware/menu_sd.c @@ -569,31 +569,69 @@ static u8 sd_handle_load(SD_STATE *state, const char *file_name, u8 file_type, FIL file; sd_file_open(&file, file_name); - if (!rom_load_file(&file) || - // Look for C128 CRT identifier - memcmp("CBM", &dat_buffer[0x0007], 3) != 0 || - memcmp("CBM", &dat_buffer[0x4007], 3) != 0) + u16 len = rom_load_file(&file); + if (len && // Look for C128 CRT identifier + (memcmp("CBM", &dat_buffer[0x0007], 3) == 0 || + memcmp("CBM", &dat_buffer[0x4007], 3) == 0)) { - return handle_unsupported(file_name); - } + dat_file.crt.type = CRT_C128_NORMAL_CARTRIDGE; + dat_file.crt.exrom = 1; + dat_file.crt.game = 1; + + if (!crt_is_supported(dat_file.crt.type)) + { + return sd_handle_crt_unsupported(dat_file.crt.type); + } - u32 type = CRT_C128_NORMAL_CARTRIDGE; - if (!crt_is_supported(type)) + if (sd_c128_only_warning(flags)) + { + return sd_handle_c128_only_warning(file_name, element); + } + } + else if (len && len <= 16*1024) { - return sd_handle_crt_unsupported(type); + dat_file.crt.type = CRT_NORMAL_CARTRIDGE; + dat_file.crt.exrom = 0; + dat_file.crt.game = 0; + // Look for C64 CRT identifier "CBM80" + if (memcmp("\xc3""\xc2""\xcd""80", &dat_buffer[0x0004], 5) == 0) + { + if (len <= 8*1024) + { + dat_file.crt.game = 1; + } + } + else // Assume Ultimax + { + dat_file.crt.exrom = 1; + // Mirror the first 4k + if (len <= 4*1024) + { + memcpy(&dat_buffer[4*1024], dat_buffer, 4*1024); + } + + // Mirror the first 8k + if (len <= 8*1024) + { + memcpy(&dat_buffer[8*1024], dat_buffer, 8*1024); + } + + // Validate reset vector + u8 reset_hi = dat_buffer[0x3ffd]; + if (reset_hi < 0x80 || (reset_hi >= 0xa0 && reset_hi < 0xe0)) + { + return handle_unsupported(file_name); + } + } } - - if (sd_c128_only_warning(flags)) + else { - return sd_handle_c128_only_warning(file_name, element); + return handle_unsupported(file_name); } u8 banks = 4; u32 flash_hash = crt_calc_flash_crc(banks); - dat_file.crt.type = type; dat_file.crt.hw_rev = 0; - dat_file.crt.exrom = 1; - dat_file.crt.game = 1; dat_file.crt.banks = banks; dat_file.crt.flags = CRT_FLAG_VIC; dat_file.crt.flash_hash = flash_hash;