diff options
Diffstat (limited to 'src/lib/formats/cbm_crt.cpp')
-rw-r--r-- | src/lib/formats/cbm_crt.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/lib/formats/cbm_crt.cpp b/src/lib/formats/cbm_crt.cpp new file mode 100644 index 00000000000..d169d0c2fd7 --- /dev/null +++ b/src/lib/formats/cbm_crt.cpp @@ -0,0 +1,229 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + cbm_crt.c + + Commodore C64 cartridge images in .CRT format + + This format was introduced in the CCS64 emulator by Per Hakan + Sundell. + + Header info based on the VICE manual chapter 15.11, which in turn + is based on CRT.txt rev 1.14 compiled by Peter Schepers, with + additional contributions by Per Hakan Sundell, Markus Brenner, + and Marco Van Den Heuvel. + Relevant links: + http://vice-emu.sourceforge.net/vice_15.html#SEC300 + http://ist.uwaterloo.ca/~schepers/formats/CRT.TXT (version 1.13, outdated) + + Header Contents (bytes $0000-003F): + Bytes $0000-000F - 16-byte cartridge signature "C64 CARTRIDGE" (padded with spaces) + $0010-0013 - File header length + $0014-0015 - Cartridge version (high/low, presently 01.00) + $0016-0017 - Cartridge hardware type ($0000, high/low), see below + $0018 - Cartridge port EXROM line status (0 = inactive, 1 = active) + $0019 - Cartridge port GAME line status (0 = inactive, 1 = active) + $001A-001F - Reserved for future use + $0020-003F - 32-byte cartridge name (uppercase, padded with null characters) + + CHIP Packet Contents (starting from $0040; there can be multiple CHIP packets + in a single CRT file): + Bytes $0040-0043 - Contained ROM signature "CHIP" + $0044-0047 - Total packet length (ROM image size and header combined) (high/low format) + $0048-0049 - Chip type (0 = ROM, 1 = RAM (no ROM data), 2 = Flash ROM) + $004A-004B - Bank number + $004C-004D - Starting load address (high/low format) + $004E-004F - ROM image size in bytes (high/low format, typically $2000 or $4000) + $0050-xxxx - ROM data + +*********************************************************************/ + +#include "emu.h" // fatalerror +#include "corefile.h" +#include "cbm_crt.h" + + +//************************************************************************** +// MACROS/CONSTANTS +//************************************************************************** + +#define LOG 0 + + +// slot names for the C64 cartridge types +static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] = +{ + "standard", // 0 - Normal cartridge + UNSUPPORTED, // 1 - Action Replay + UNSUPPORTED, // 2 - KCS Power Cartridge + "final3", // 3 - Final Cartridge III + "simons_basic", // 4 - Simons' BASIC + "ocean", // 5 - Ocean type 1 + UNSUPPORTED, // 6 - Expert Cartridge + "fun_play", // 7 - Fun Play, Power Play + "super_games", // 8 - Super Games + UNSUPPORTED, // 9 - Atomic Power + "epyxfastload", // 10 - Epyx Fastload + "westermann", // 11 - Westermann Learning + "rex", // 12 - Rex Utility + "final", // 13 - Final Cartridge I + "magic_formel", // 14 - Magic Formel + "system3", // 15 - C64 Game System, System 3 + "warp_speed", // 16 - Warp Speed + "dinamic", // 17 - Dinamic + "zaxxon", // 18 - Zaxxon, Super Zaxxon (SEGA) + "magic_desk", // 19 - Magic Desk, Domark, HES Australia + UNSUPPORTED, // 20 - Super Snapshot V5 + "comal80", // 21 - Comal-80 + "struct_basic", // 22 - Structured BASIC + "ross", // 23 - Ross + "ep64", // 24 - Dela EP64 + "ep7x8", // 25 - Dela EP7x8 + "dela_ep256", // 26 - Dela EP256 + "rex_ep256", // 27 - Rex EP256 + "mikroasm", // 28 - Mikro Assembler + UNSUPPORTED, // 29 - Final Cartridge Plus + UNSUPPORTED, // 30 - Action Replay 4 + "stardos", // 31 - Stardos + "easyflash", // 32 - EasyFlash + UNSUPPORTED, // 33 - EasyFlash Xbank + UNSUPPORTED, // 34 - Capture + UNSUPPORTED, // 35 - Action Replay 3 + UNSUPPORTED, // 36 - Retro Replay + UNSUPPORTED, // 37 - MMC64 + UNSUPPORTED, // 38 - MMC Replay + "ide64", // 39 - IDE64 + UNSUPPORTED, // 40 - Super Snapshot V4 + "ieee488", // 41 - IEEE-488 + UNSUPPORTED, // 42 - Game Killer + "prophet64", // 43 - Prophet64 + "exos", // 44 - EXOS + UNSUPPORTED, // 45 - Freeze Frame + UNSUPPORTED, // 46 - Freeze Machine + UNSUPPORTED, // 47 - Snapshot64 + "super_explode", // 48 - Super Explode V5.0 + "magic_voice", // 49 - Magic Voice + UNSUPPORTED, // 50 - Action Replay 2 + "mach5", // 51 - MACH 5 + UNSUPPORTED, // 52 - Diashow-Maker + "pagefox", // 53 - Pagefox + UNSUPPORTED, // 54 - ? + "silverrock" // 55 - Silverrock +}; + + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// cbm_crt_get_card - get slot interface card +//------------------------------------------------- + +void cbm_crt_get_card(std::string &result, core_file *file) +{ + // read the header + cbm_crt_header header; + core_fread(file, &header, CRT_HEADER_LENGTH); + + if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0) + { + UINT16 hardware = pick_integer_be(header.hardware, 0, 2); + + result.assign(CRT_C64_SLOT_NAMES[hardware]); + return; + } + + result.clear(); +} + + +//------------------------------------------------- +// cbm_crt_read_header - read cartridge header +//------------------------------------------------- + +bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game) +{ + // read the header + cbm_crt_header header; + core_fread(file, &header, CRT_HEADER_LENGTH); + + if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0) + return false; + + UINT16 hardware = pick_integer_be(header.hardware, 0, 2); + *exrom = header.exrom; + *game = header.game; + + if (LOG) + { + osd_printf_verbose("Name: %s\n", header.name); + osd_printf_verbose("Hardware: %04x\n", hardware); + osd_printf_verbose("Slot device: %s\n", CRT_C64_SLOT_NAMES[hardware]); + osd_printf_verbose("EXROM: %u\n", header.exrom); + osd_printf_verbose("GAME: %u\n", header.game); + } + + // determine ROM region lengths + while (!core_feof(file)) + { + cbm_crt_chip chip; + core_fread(file, &chip, CRT_CHIP_LENGTH); + + UINT16 address = pick_integer_be(chip.start_address, 0, 2); + UINT16 size = pick_integer_be(chip.image_size, 0, 2); + UINT16 type = pick_integer_be(chip.chip_type, 0, 2); + + if (LOG) + { + osd_printf_verbose("CHIP Address: %04x\n", address); + osd_printf_verbose("CHIP Size: %04x\n", size); + osd_printf_verbose("CHIP Type: %04x\n", type); + } + + switch (address) + { + case 0x8000: *roml_size += size; break; + case 0xa000: *romh_size += size; break; + case 0xe000: *romh_size += size; break; + default: osd_printf_verbose("Invalid CHIP loading address!\n"); break; + } + + core_fseek(file, size, SEEK_CUR); + } + + return true; +} + + +//------------------------------------------------- +// cbm_crt_read_data - read cartridge data +//------------------------------------------------- + +bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh) +{ + UINT32 roml_offset = 0; + UINT32 romh_offset = 0; + + core_fseek(file, CRT_HEADER_LENGTH, SEEK_SET); + + while (!core_feof(file)) + { + cbm_crt_chip chip; + core_fread(file, &chip, CRT_CHIP_LENGTH); + + UINT16 address = pick_integer_be(chip.start_address, 0, 2); + UINT16 size = pick_integer_be(chip.image_size, 0, 2); + + switch (address) + { + case 0x8000: core_fread(file, roml + roml_offset, size); roml_offset += size; break; + case 0xa000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; + case 0xe000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; + } + } + + return true; +} |