mirror of
https://github.com/holub/mame
synced 2025-05-23 14:19:01 +03:00

Use standard uint64_t, uint32_t, uint16_t or uint8_t instead of UINT64, UINT32, UINT16 or UINT8 also use standard int64_t, int32_t, int16_t or int8_t instead of INT64, INT32, INT16 or INT8
229 lines
7.6 KiB
C++
229 lines
7.6 KiB
C++
// 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
|
|
//-------------------------------------------------
|
|
|
|
std::string cbm_crt_get_card(util::core_file &file)
|
|
{
|
|
// read the header
|
|
cbm_crt_header header;
|
|
file.read(&header, CRT_HEADER_LENGTH);
|
|
|
|
if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0)
|
|
{
|
|
uint16_t hardware = pick_integer_be(header.hardware, 0, 2);
|
|
|
|
return std::string(CRT_C64_SLOT_NAMES[hardware]);
|
|
}
|
|
|
|
return std::string();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// cbm_crt_read_header - read cartridge header
|
|
//-------------------------------------------------
|
|
|
|
bool cbm_crt_read_header(util::core_file &file, size_t *roml_size, size_t *romh_size, int *exrom, int *game)
|
|
{
|
|
// read the header
|
|
cbm_crt_header header;
|
|
file.read(&header, CRT_HEADER_LENGTH);
|
|
|
|
if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0)
|
|
return false;
|
|
|
|
uint16_t 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 (!file.eof())
|
|
{
|
|
cbm_crt_chip chip;
|
|
file.read(&chip, CRT_CHIP_LENGTH);
|
|
|
|
uint16_t address = pick_integer_be(chip.start_address, 0, 2);
|
|
uint16_t size = pick_integer_be(chip.image_size, 0, 2);
|
|
uint16_t 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;
|
|
}
|
|
|
|
file.seek(size, SEEK_CUR);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// cbm_crt_read_data - read cartridge data
|
|
//-------------------------------------------------
|
|
|
|
bool cbm_crt_read_data(util::core_file &file, uint8_t *roml, uint8_t *romh)
|
|
{
|
|
uint32_t roml_offset = 0;
|
|
uint32_t romh_offset = 0;
|
|
|
|
file.seek(CRT_HEADER_LENGTH, SEEK_SET);
|
|
|
|
while (!file.eof())
|
|
{
|
|
cbm_crt_chip chip;
|
|
file.read(&chip, CRT_CHIP_LENGTH);
|
|
|
|
uint16_t address = pick_integer_be(chip.start_address, 0, 2);
|
|
uint16_t size = pick_integer_be(chip.image_size, 0, 2);
|
|
|
|
switch (address)
|
|
{
|
|
case 0x8000: file.read(roml + roml_offset, size); roml_offset += size; break;
|
|
case 0xa000: file.read(romh + romh_offset, size); romh_offset += size; break;
|
|
case 0xe000: file.read(romh + romh_offset, size); romh_offset += size; break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|