diff options
Diffstat (limited to 'src/mess/machine/nes_unif.c')
-rw-r--r-- | src/mess/machine/nes_unif.c | 490 |
1 files changed, 447 insertions, 43 deletions
diff --git a/src/mess/machine/nes_unif.c b/src/mess/machine/nes_unif.c index cf801d6ac85..11016f6e33d 100644 --- a/src/mess/machine/nes_unif.c +++ b/src/mess/machine/nes_unif.c @@ -9,6 +9,21 @@ ****************************************************************************************/ + +/* Set to generate prg & chr files when the cart is loaded */ +#define SPLIT_PRG 0 +#define SPLIT_CHR 0 + + +/************************************************************* + + unif_list + + Supported UNIF boards and corresponding handlers + + *************************************************************/ + + struct unif { const char *board; /* UNIF board */ @@ -20,12 +35,6 @@ struct unif }; -/************************************************************* - - Constants - -*************************************************************/ - /* CHRRAM sizes */ enum { @@ -39,14 +48,6 @@ enum CHRRAM_32 }; -/************************************************************* - - unif_list - - Supported UNIF boards and corresponding handlers - -*************************************************************/ - static const unif unif_list[] = { /* UNIF NVW WRAM CRAM IDX*/ @@ -57,14 +58,14 @@ static const unif unif_list[] = { "NES-NROM", 0, 0, CHRRAM_0, STD_NROM}, { "NES-NROM-128", 0, 0, CHRRAM_0, STD_NROM}, { "NES-NROM-256", 0, 0, CHRRAM_0, STD_NROM}, - { "NES-NTBROM", 8, 0, CHRRAM_0, STD_NXROM}, + { "NES-NTBROM", 8, 0, CHRRAM_0, SUNSOFT_DCS}, { "NES-SLROM", 0, 0, CHRRAM_0, STD_SXROM}, { "NES-TBROM", 0, 0, CHRRAM_0, STD_TXROM}, { "NES-TFROM", 0, 0, CHRRAM_0, STD_TXROM}, { "NES-TKROM", 8, 0, CHRRAM_0, STD_TXROM}, { "NES-TLROM", 0, 0, CHRRAM_0, STD_TXROM}, { "NES-UOROM", 0, 0, CHRRAM_8, STD_UXROM}, - { "UNL-22211", 0, 0, CHRRAM_0, TXC_22211A}, + { "UNL-22211", 0, 0, CHRRAM_0, TXC_22211}, // mapper 172 & 173 are variant of this one... no UNIF? { "UNL-KOF97", 0, 0, CHRRAM_0, UNL_KOF97}, { "UNL-SA-NROM", 0, 0, CHRRAM_0, SACHEN_TCA01}, @@ -85,57 +86,58 @@ static const unif unif_list[] = { "UNL-SA-72008", 0, 0, CHRRAM_0, SACHEN_SA72008}, { "UNL-SA-0037", 0, 0, CHRRAM_0, SACHEN_SA0037}, { "UNL-SA-0036", 0, 0, CHRRAM_0, SACHEN_SA0036}, - { "UNL-SA-9602B", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, + { "UNL-SA-9602B", 0, 0, CHRRAM_0, SACHEN_SA9602B}, { "UNL-SACHEN-8259A", 0, 0, CHRRAM_0, SACHEN_8259A}, { "UNL-SACHEN-8259B", 0, 0, CHRRAM_0, SACHEN_8259B}, { "BMC-190IN1", 0, 0, CHRRAM_0, BMC_190IN1}, { "BMC-64IN1NOREPEAT", 0, 0, CHRRAM_0, BMC_64IN1NR}, //UNIF only! { "BMC-A65AS", 0, 0, CHRRAM_8, BMC_A65AS}, //UNIF only! - { "BMC-GS-2004", 0, 0, CHRRAM_8, BMC_GS2004}, //UNIF only! - { "BMC-GS-2013", 0, 0, CHRRAM_8, BMC_GS2013}, //UNIF only! - { "BMC-NOVELDIAMOND9999999IN1", 0, 0, CHRRAM_0, BMC_NOVELDIAMOND}, + { "BMC-GS-2004", 0, 0, CHRRAM_8, RCM_GS2004}, //UNIF only! + { "BMC-GS-2013", 0, 0, CHRRAM_8, RCM_GS2013}, //UNIF only! + { "BMC-NOVELDIAMOND9999999IN1", 0, 0, CHRRAM_0, BMC_NOVEL1}, { "BMC-SUPER24IN1SC03", 8, 0, CHRRAM_8, BMC_S24IN1SC03}, { "BMC-SUPERHIK8IN1", 8, 0, CHRRAM_0, BMC_HIK8IN1}, { "BMC-T-262", 0, 0, CHRRAM_8, BMC_T262}, //UNIF only! { "BMC-WS", 0, 0, CHRRAM_0, BMC_WS}, //UNIF only! { "BMC-N625092", 0, 0, CHRRAM_0, UNL_N625092}, // below are boards which are not yet supported, but are used by some UNIF files. they are here as a reminder to what is missing to be added - { "UNL-TEK90", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // related to JY Company? (i.e. mappers 90, 209, 211?) - { "UNL-KS7017", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, + { "UNL-TEK90", 0, 0, CHRRAM_0, JYCOMPANY_A}, // JY Company A (is TEK90 the real PCB name?) + { "UNL-KS7017", 0, 0, CHRRAM_0, KAISER_KS7017}, { "UNL-KS7032", 0, 0, CHRRAM_0, KAISER_KS7032}, // mapper 142 - { "UNL-DANCE", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, { "UNL-603-5052", 0, 0, CHRRAM_0, UNL_603_5052}, // mapper 238? { "UNL-EDU2000", 32, 0, CHRRAM_8, UNL_EDU2K}, { "UNL-H2288", 0, 0, CHRRAM_0, UNL_H2288}, // mapper 123 - { "UNL-SHERO", 0, 0, CHRRAM_8, UNSUPPORTED_BOARD /*SACHEN_SHERO*/}, - { "UNL-TF1201", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD /*UNL_TF1201*/}, - { "UNL-DRIPGAME", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // [by Quietust - we need more info]} - { "UNL-OneBus", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "UNL-YOKO", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // similar to mapper 83, but not the same - { "UNL-FS304", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // used in Zelda 3 by Waixing (support missing atm) - { "UNL-43272", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // used in Gaau Hok Gwong Cheung (support missing atm) - { "BTL-MARIO1-MALEE2", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 55? + { "UNL-SHERO", 0, 0, CHRRAM_8, SACHEN_SHERO}, + { "UNL-YOKO", 0, 0, CHRRAM_0, YOKO_BOARD}, // similar to mapper 83, but not the same + { "UNL-FS304", 0, 8, CHRRAM_8, WAIXING_FS304}, // used in Zelda 3 by Waixing + { "UNL-43272", 0, 0, CHRRAM_0, UNL_43272}, // used in Gaau Hok Gwong Cheung + { "BTL-MARIO1-MALEE2", 0, 0, CHRRAM_0, UNL_MMALEE}, // mapper 55? { "BMC-FK23C", 0, 0, CHRRAM_0, BMC_FK23C}, { "BMC-FK23CA", 0, 0, CHRRAM_0, BMC_FK23CA}, { "BMC-GHOSTBUSTERS63IN1", 0, 0, CHRRAM_8, BMC_G63IN1 }, - { "BMC-BS-5", 0, 0, CHRRAM_0, BMC_BENSHENG_BS5}, + { "BMC-BS-5", 0, 0, CHRRAM_0, BMC_BENSHIENG}, { "BMC-810544-C-A1", 0, 0, CHRRAM_0, BMC_810544}, - { "BMC-411120-C", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "BMC-8157", 0, 0, CHRRAM_8, UNSUPPORTED_BOARD /*BMC_8157*/}, - { "BMC-42IN1RESETSWITCH", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 60? - { "BMC-830118C", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, + { "BMC-411120-C", 0, 0, CHRRAM_0, BMC_411120C}, + { "BMC-8157", 0, 0, CHRRAM_8, BMC_8157}, + { "BMC-830118C", 0, 0, CHRRAM_0, BMC_830118C}, { "BMC-D1038", 0, 0, CHRRAM_0, BMC_VT5201}, // mapper 60? + { "BMC-SUPERVISION16IN1", 0, 0, CHRRAM_0, SVISION16_BOARD}, // mapper 53 + { "BMC-NTD-03", 0, 0, CHRRAM_0, BMC_NTD_03}, + { "UNL-AC08", 0, 0, CHRRAM_0, UNL_AC08}, + { "UNL-BB", 0, 0, CHRRAM_0, UNL_BB}, + { "UNL-LH32", 0, 0, CHRRAM_0, UNL_LH32}, + { "BMC-G-146", 0, 0, CHRRAM_0, BMC_G146}, + { "BMC-11160", 0, 0, CHRRAM_0, BMC_11160}, + { "UNL-MALISB", 0, 0, CHRRAM_0, UNL_MALISB}, + { "UNL-TF1201", 0, 0, CHRRAM_0, UNL_TF1201}, { "BMC-12-IN-1", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, { "BMC-70IN1", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 236? { "BMC-70IN1B", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 236? - { "BMC-SUPERVISION16IN1", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 53 - { "BMC-NTD-03", 0, 0, CHRRAM_0, BMC_NTD_03}, - { "UNL-AC08", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "UNL-BB", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "UNL-LH32", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, + { "BMC-42IN1RESETSWITCH", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // mapper 60? + { "UNL-DANCE", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, + { "UNL-DRIPGAME", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, // [by Quietust - we need more info] { "UNL-CITYFIGHT", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "BMC-G-146", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD}, - { "BMC-11160", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD} + { "UNL-OneBus", 0, 0, CHRRAM_0, UNSUPPORTED_BOARD} }; const unif *nes_unif_lookup( const char *board ) @@ -175,3 +177,405 @@ void unif_mapr_setup( const char *board, int *pcb_id, int *battery, int *prgram, else if (unif_board->chrram == CHRRAM_32) *vram_chunks = 4; } + + +/************************************************************* + + call_load_unif + + *************************************************************/ + +void nes_cart_slot_device::call_load_unif() +{ + UINT32 vram_size = 0, prgram_size = 0, battery_size = 0, mapper_sram_size = 0; + // SETUP step 1: running through the file and getting PRG, VROM sizes + UINT32 unif_ver = 0, chunk_length = 0, read_length = 0x20; + UINT32 prg_start = 0, chr_start = 0; + UINT32 size = length(), prg_size = 0, vrom_size = 0; + UINT8 buffer[4], mirror = 0; + char magic2[4]; + char unif_mapr[32]; // here we should store MAPR chunks + bool mapr_chunk_found = FALSE, small_prg = FALSE; + + // allocate space to temporarily store PRG & CHR banks + UINT8 *temp_prg = auto_alloc_array(machine(), UINT8, 256 * 0x4000); + UINT8 *temp_chr = auto_alloc_array(machine(), UINT8, 256 * 0x2000); + UINT8 temp_byte = 0; + + fseek(4, SEEK_SET); + fread(&buffer, 4); + unif_ver = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + logerror("Loaded game in UNIF format, version %d\n", unif_ver); + + do + { + fseek(read_length, SEEK_SET); + + memset(magic2, '\0', sizeof(magic2)); + fread(&magic2, 4); + + /* We first run through the whole image to find a [MAPR] chunk. This is needed + because, unfortunately, the MAPR chunk is not always the first chunk (see + Super 24-in-1). When such a chunk is found, we set mapr_chunk_found=1 and + we go back to load other chunks! */ + if (!mapr_chunk_found) + { + if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R')) + { + mapr_chunk_found = TRUE; + logerror("[MAPR] chunk found: "); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + if (chunk_length <= 0x20) + fread(&unif_mapr, chunk_length); + logerror("%s\n", unif_mapr); + + /* now that we found the MAPR chunk, we can go back to load other chunks */ + fseek(0x20, SEEK_SET); + read_length = 0x20; + } + else + { + logerror("Skip this chunk. We need a [MAPR] chunk before anything else.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + } + else + { + /* What kind of chunk do we have here? */ + if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R')) + { + /* The [MAPR] chunk has already been read, so we skip it */ + /* TO DO: it would be nice to check if more than one MAPR chunk is present */ + logerror("[MAPR] chunk found (in the 2nd run). Already loaded.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'R') && (magic2[1] == 'E') && (magic2[2] == 'A') && (magic2[3] == 'D')) + { + logerror("[READ] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'N') && (magic2[1] == 'A') && (magic2[2] == 'M') && (magic2[3] == 'E')) + { + logerror("[NAME] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'W') && (magic2[1] == 'R') && (magic2[2] == 'T') && (magic2[3] == 'R')) + { + logerror("[WRTR] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'C') && (magic2[3] == 'I')) + { + logerror("[TVCI] chunk found.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + fread(&temp_byte, 1); + logerror("Television Standard : %s\n", (temp_byte == 0) ? "NTSC" : (temp_byte == 1) ? "PAL" : "Does not matter"); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'S') && (magic2[3] == 'C')) // is this the same as TVCI?? + { + logerror("[TVSC] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'D') && (magic2[1] == 'I') && (magic2[2] == 'N') && (magic2[3] == 'F')) + { + logerror("[DINF] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'C') && (magic2[1] == 'T') && (magic2[2] == 'R') && (magic2[3] == 'L')) + { + logerror("[CTRL] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'B') && (magic2[1] == 'A') && (magic2[2] == 'T') && (magic2[3] == 'R')) + { + logerror("[BATR] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'V') && (magic2[1] == 'R') && (magic2[2] == 'O') && (magic2[3] == 'R')) + { + logerror("[VROR] chunk found. No support yet.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'M') && (magic2[1] == 'I') && (magic2[2] == 'R') && (magic2[3] == 'R')) + { + logerror("[MIRR] chunk found.\n"); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + fread(&mirror, 1); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'P') && (magic2[1] == 'C') && (magic2[2] == 'K')) + { + logerror("[PCK%c] chunk found. No support yet.\n", magic2[3]); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'C') && (magic2[1] == 'C') && (magic2[2] == 'K')) + { + logerror("[CCK%c] chunk found. No support yet.\n", magic2[3]); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'P') && (magic2[1] == 'R') && (magic2[2] == 'G')) + { + logerror("[PRG%c] chunk found. ", magic2[3]); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + prg_size += chunk_length; + + if (chunk_length / 0x4000) + logerror("It consists of %d 16K-blocks.\n", chunk_length / 0x4000); + else + { + small_prg = TRUE; + logerror("This chunk is smaller than 16K: the emulation might have issues. Please report this file to the MESS forums.\n"); + } + + /* Read in the program chunks */ + fread(&temp_prg[prg_start], chunk_length); + + prg_start += chunk_length; + read_length += (chunk_length + 8); + } + else if ((magic2[0] == 'C') && (magic2[1] == 'H') && (magic2[2] == 'R')) + { + logerror("[CHR%c] chunk found. ", magic2[3]); + fread(&buffer, 4); + chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + vrom_size += chunk_length; + + logerror("It consists of %d 8K-blocks.\n", chunk_length / 0x2000); + + /* Read in the vrom chunks */ + fread(&temp_chr[chr_start], chunk_length); + + chr_start += chunk_length; + read_length += (chunk_length + 8); + } + else + { + logerror("Unsupported UNIF chunk or corrupted header. Please report the problem at MESS Board.\n"); + read_length = size; + } + } + } while (size > read_length); + + if (!mapr_chunk_found) + { + auto_free(machine(), temp_prg); + auto_free(machine(), temp_chr); + fatalerror("UNIF should have a [MAPR] chunk to work. Check if your image has been corrupted\n"); + } + + if (!prg_start) + { + auto_free(machine(), temp_prg); + auto_free(machine(), temp_chr); + fatalerror("No PRG found. Please report the problem at MESS Board.\n"); + } + + // SETUP step 2: getting PCB and other settings + int pcb_id = 0, battery = 0, prgram = 0, vram_chunks = 0; + unif_mapr_setup(unif_mapr, &pcb_id, &battery, &prgram, &vram_chunks); + + // SETUP step 3: storing the info needed for emulation + m_pcb_id = pcb_id; + if (battery) + battery_size = NES_BATTERY_SIZE; // we should allow for smaller battery! + prgram_size = prgram * 0x2000; + vram_size = vram_chunks * 0x2000; + + m_cart->set_four_screen_vram(FALSE); + switch (mirror) + { + case 0: // Horizontal Mirroring (Hard Wired) + m_cart->set_mirroring(PPU_MIRROR_HORZ); + break; + case 1: // Vertical Mirroring (Hard Wired) + m_cart->set_mirroring(PPU_MIRROR_VERT); + break; + case 2: // Mirror All Pages From $2000 (Hard Wired) + m_cart->set_mirroring(PPU_MIRROR_LOW); + break; + case 3: // Mirror All Pages From $2400 (Hard Wired) + m_cart->set_mirroring(PPU_MIRROR_HIGH); + break; + case 4: // Four Screens of VRAM (Hard Wired) + m_cart->set_four_screen_vram(TRUE); + m_cart->set_mirroring(PPU_MIRROR_4SCREEN); + break; + case 5: // Mirroring Controlled By Mapper Hardware + logerror("Mirroring handled by the board hardware.\n"); + // default to horizontal at start + m_cart->set_mirroring(PPU_MIRROR_HORZ); + break; + default: + logerror("Undocumented mirroring value.\n"); + // default to horizontal + m_cart->set_mirroring(PPU_MIRROR_HORZ); + break; + } + + // SETUP step 4: logging what we have found + logerror("-- Board %s\n", unif_mapr); + logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000); + logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000); + logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000); + + // SETUP steps 5/6: allocate pointers for PRG/VROM and load the data! + if (prg_size == 0x4000) + { + m_cart->prg_alloc(machine(), 0x8000); + memcpy(m_cart->get_prg_base(), temp_prg, 0x4000); + memcpy(m_cart->get_prg_base() + 0x4000, m_cart->get_prg_base(), 0x4000); + } + else + { + m_cart->prg_alloc(machine(), prg_size); + memcpy(m_cart->get_prg_base(), temp_prg, prg_size); + } + + if (small_prg) // This is not supported yet, so warn users about this + mame_printf_error("Loaded UNIF file with non-16k PRG chunk. This is not supported in MESS yet."); + + if (vrom_size) + { + m_cart->vrom_alloc(machine(), vrom_size); + memcpy(m_cart->get_vrom_base(), temp_chr, vrom_size); + } + +#if SPLIT_PRG + { + FILE *prgout; + char outname[255]; + + sprintf(outname, "%s.prg", filename()); + prgout = fopen(outname, "wb"); + if (prgout) + { + fwrite(m_cart->get_prg_base(), 1, 0x4000 * m_cart->get_prg_size(), prgout); + mame_printf_error("Created PRG chunk\n"); + } + + fclose(prgout); + } +#endif + +#if SPLIT_CHR + if (state->m_chr_chunks > 0) + { + FILE *chrout; + char outname[255]; + + sprintf(outname, "%s.chr", filename()); + chrout= fopen(outname, "wb"); + if (chrout) + { + fwrite(m_cart->get_vrom_base(), 1, m_cart->get_vrom_size(), chrout); + mame_printf_error("Created CHR chunk\n"); + } + fclose(chrout); + } +#endif + // free the temporary copy of PRG/CHR + auto_free(machine(), temp_prg); + auto_free(machine(), temp_chr); + + // SETUP steps 7: allocate the remaining pointer, when needed + if (vram_size) + m_cart->vram_alloc(machine(), vram_size); + if (prgram_size) + m_cart->prgram_alloc(machine(), prgram_size); + + // Attempt to load a battery file for this ROM + // A few boards have internal RAM with a battery (MMC6, Taito X1-005 & X1-017, etc.) + if (battery_size || mapper_sram_size) + { + UINT32 tot_size = battery_size + mapper_sram_size; + UINT8 *temp_nvram = auto_alloc_array(machine(), UINT8, tot_size); + battery_load(temp_nvram, tot_size, 0x00); + if (battery_size) + { + m_cart->battery_alloc(machine(), battery_size); + memcpy(m_cart->get_battery_base(), temp_nvram, battery_size); + } + if (mapper_sram_size) + memcpy(m_cart->get_mapper_sram_base(), temp_nvram + battery_size, mapper_sram_size); + + if (temp_nvram) + auto_free(machine(), temp_nvram); + } + + logerror("UNIF support is only very preliminary.\n"); +} + +const char * nes_cart_slot_device::get_default_card_unif(UINT8 *ROM, UINT32 len) +{ + UINT32 chunk_length = 0, read_length = 0x20; + int pcb_id = 0, battery = 0, prgram = 0, vram_chunks = 0; + char unif_mapr[32]; + + do + { + if ((ROM[read_length + 0] == 'M') && (ROM[read_length + 1] == 'A') && (ROM[read_length + 2] == 'P') && (ROM[read_length + 3] == 'R')) + { + chunk_length = ROM[read_length + 4] | (ROM[read_length + 5] << 8) | (ROM[read_length + 6] << 16) | (ROM[read_length + 7] << 24); + + if (chunk_length <= 0x20) + memcpy(unif_mapr, ROM + read_length + 8, chunk_length); + + read_length += (chunk_length + 8); + } + else + { + chunk_length = ROM[read_length + 4] | (ROM[read_length + 5] << 8) | (ROM[read_length + 6] << 16) | (ROM[read_length + 7] << 24); + read_length += (chunk_length + 8); + } + } while (len > read_length); + + unif_mapr_setup(unif_mapr, &pcb_id, &battery, &prgram, &vram_chunks); + + return nes_get_slot(pcb_id); +} |