std::string a5200_cart_slot_device::get_default_card_software() { if (open_image_file(mconfig().options())) { const char *slot_string; std::vector<uint8_t> head(0x10); uint32_t len = m_file->size(); int type = A5200_8K; // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { m_file->read(&head[0], 0x10); type = identify_cart_type(&head[0]); } else { std::string info; if (hashfile_extrainfo(*this, info) && info.compare("A13MIRRORING")==0) type = A5200_16K_2CHIPS; } if (type < A5200_4K) osd_printf_info("This game is not designed for A5200. You might want to run it in A800 or A800XL.\n"); slot_string = a800_get_slot(type); clear(); return std::string(slot_string); } else return software_get_default_slot("a5200"); }
void a5200_cart_slot_device::get_default_card_software(std::string &result) { if (open_image_file(mconfig().options())) { const char *slot_string = "a5200"; dynamic_buffer head(0x10); UINT32 len = core_fsize(m_file); int type = A5200_8K; // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { core_fread(m_file, &head[0], 0x10); type = identify_cart_type(&head[0]); std::string info; if (hashfile_extrainfo(*this, info) && info.compare("A13MIRRORING")==0) type = A5200_16K_2CHIPS; } if (type < A5200_4K) osd_printf_info("This game is not designed for A5200. You might want to run it in A800 or A800XL.\n"); slot_string = a800_get_slot(type); clear(); result.assign(slot_string); } else software_get_default_slot(result, "a5200"); }
void nes_cart_slot_device::call_load_ines() { UINT32 vram_size = 0, prgram_size = 0, battery_size = 0, mapper_sram_size = 0; UINT32 prg_size, vrom_size; UINT8 header[0x10]; UINT8 mapper, local_options; bool ines20 = FALSE, prg16k; const char *mapinfo = NULL; int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; int crc_hack = 0; // check if the image is recognized by nes.hsi mapinfo = hashfile_extrainfo(*this); // read out the header fseek(0, SEEK_SET); fread(&header, 0x10); // SETUP step 1: getting PRG, VROM, VRAM sizes prg16k = (header[4] == 1); prg_size = prg16k ? 2 * 0x4000 : header[4] * 0x4000; vrom_size = header[5] * 0x2000; vram_size = 0x4000; // SETUP step 2: getting PCB and other settings mapper = (header[6] & 0xf0) >> 4; local_options = header[6] & 0x0f; switch (header[7] & 0xc) { case 0x4: case 0xc: // probably the header got corrupted: don't trust upper bits for mapper break; case 0x8: // it's iNES 2.0 format ines20 = TRUE; case 0x0: default: mapper |= header[7] & 0xf0; break; } // use info from nes.hsi if available! if (mapinfo) { if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4)) { /* image is present in nes.hsi: overwrite the header settings with these */ mapper = mapint1; local_options = mapint2 & 0x0f; crc_hack = (mapint2 & 0xf0) >> 4; // this is used to differentiate among variants of the same Mapper (see below) prg16k = (mapint3 == 1); prg_size = prg16k ? 2 * 0x4000 : mapint3 * 0x4000; vrom_size = mapint4 * 0x2000; logerror("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4); } else {
bool hashfile_extrainfo(device_image_interface &image, std::string &result) { return hashfile_extrainfo( image.device().mconfig().options().hash_path(), image.device().mconfig().gamedrv(), image.hash(), result); }
image_init_result a800_cart_slot_device::call_load() { if (m_cart) { uint32_t len; if (software_entry() != nullptr) { const char *pcb_name; len = get_software_region_length("rom"); m_cart->rom_alloc(len, tag()); memcpy(m_cart->get_rom_base(), get_software_region("rom"), len); if ((pcb_name = get_feature("slot")) != nullptr) m_type = a800_get_pcb_id(pcb_name); else m_type = A800_8K; } else { len = length(); // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { uint8_t header[16]; fread(header, 0x10); m_type = identify_cart_type(header); len -= 0x10; // in identify_cart_type the first 0x10 bytes are read, so we need to adjust here } else // otherwise try to guess based on size { if (len == 0x8000) m_type = A5200_32K; if (len == 0x4000) m_type = A800_16K; if (len == 0x2000) m_type = A800_8K; if (len == 0x1000) m_type = A5200_4K; // also make a try with .hsi file (for .a52 files) std::string info; if (hashfile_extrainfo(*this, info) && info.compare("A13MIRRORING")==0) m_type = A5200_16K_2CHIPS; } m_cart->rom_alloc(len, tag()); fread(m_cart->get_rom_base(), len); } if (m_type == A800_TELELINK2) m_cart->nvram_alloc(0x100); logerror("%s loaded cartridge '%s' size %dK\n", machine().system().name, filename(), len/1024); } return image_init_result::PASS; }
void msx_slot_cartridge_device::get_default_card_software(std::string &result) { if (open_image_file(mconfig().options())) { const char *slot_string = "nomapper"; UINT32 length = core_fsize(m_file); dynamic_buffer rom(length); int type = NOMAPPER; // Check if there's some mapper related information in the hashfiles std::string extrainfo; if (hashfile_extrainfo(*this, extrainfo)) { int extrainfo_type = -1; if (1 == sscanf(extrainfo.c_str(), "%d", &extrainfo_type)) { static const struct { int extrainfo; int mapper; } extrainfo_map[] = { //{ 0, NOMAPPER }, { 1, MSXDOS2 }, { 2, KONAMI_SCC }, { 3, KONAMI }, { 4, ASCII8 }, { 5, ASCII16 }, { 6, GAMEMASTER2 }, { 7, ASCII8_SRAM }, { 8, ASCII16_SRAM }, { 9, RTYPE }, { 10, MAJUTSUSHI }, { 11, FMPAC }, { 12, SUPERLODERUNNER }, { 13, SYNTHESIZER }, { 14, CROSSBLAIM }, { 15, DISK_ROM }, { 16, KOREAN_80IN1 }, { 17, KOREAN_126IN1 } }; for (int i = 0; i < ARRAY_LENGTH(extrainfo_map); i++) { if (extrainfo_map[i].extrainfo == extrainfo_type) { type = extrainfo_map[i].mapper; } } } } if (type == NOMAPPER) { // Not identified through hashfile, try automatic detection type = get_cart_type(&rom[0], length); } if (type > NOMAPPER) { slot_string = msx_cart_get_slot_option(type); } result.assign(slot_string); return; } software_get_default_slot(result, "nomapper"); }
bool msx_slot_cartridge_device::call_load() { if ( m_cartridge ) { if ( software_entry() ) { UINT32 length; // Allocate and copy rom contents length = get_software_region_length("rom"); m_cartridge->rom_alloc( length ); if (length > 0) { UINT8 *rom_base = m_cartridge->get_rom_base(); memcpy(rom_base, get_software_region("rom"), length); } // Allocate and copy vlm5030 rom contents length = get_software_region_length("vlm5030"); m_cartridge->rom_vlm5030_alloc(length); if (length > 0) { UINT8 *rom_base = m_cartridge->get_rom_vlm5030_base(); memcpy(rom_base, get_software_region("vlm5030"), length); } // Allocate ram length = get_software_region_length("ram"); m_cartridge->ram_alloc( length ); // Allocate sram length = get_software_region_length("sram"); m_cartridge->sram_alloc( length ); } else { UINT32 length = this->length(); // determine how much space to allocate UINT32 length_aligned = 0x10000; if (length <= 0x2000) length_aligned = 0x2000; else if (length <= 0x4000) length_aligned = 0x4000; else if (length <= 0x8000) length_aligned = 0x8000; else if (length <= 0xc000) length_aligned = 0xc000; else { while (length_aligned < length ) length_aligned *= 2; } m_cartridge->rom_alloc(length_aligned); m_cartridge->ram_alloc(0); m_cartridge->sram_alloc(0); if (fread(m_cartridge->get_rom_base(), length) != length) { seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read file"); return IMAGE_INIT_FAIL; } // Check if there's some mapper related std::string extrainfo; if (hashfile_extrainfo(*this, extrainfo)) { } } m_cartridge->set_out_irq_cb(DEVCB_WRITELINE(msx_slot_cartridge_device, irq_out)); m_cartridge->initialize_cartridge(); if (m_cartridge->get_sram_size() > 0) { battery_load(m_cartridge->get_sram_base(), m_cartridge->get_sram_size(), 0x00); } } return IMAGE_INIT_PASS; }
DEVICE_IMAGE_LOAD_MEMBER(msx_state,msx_cart) { int size; int size_aligned; UINT8 *mem; int type = -1; const char *extra = NULL; char *sramfile; slot_state *st; int id = -1; if (strcmp(image.device().tag(),":cart1")==0) id = 0; if (strcmp(image.device().tag(),":cart2")==0) id = 1; if( id == -1 ) { //logerror ("error: invalid cart tag '%s'\n", image->tag); return IMAGE_INIT_FAIL; } if ( image.software_entry() != NULL ) { /* Load software from software list */ /* TODO: Add proper SRAM (size) handling */ const char *mapper = image.get_feature("mapper"); if (mapper != NULL) { static const struct { const char *mapper_name; int mapper_type; } mapper_types[] = { { "NOMAPPER", SLOT_EMPTY }, { "M60002-0125SP", SLOT_ASCII8 }, { "LZ93A13", SLOT_ASCII8 }, { "NEOS MR6401", SLOT_ASCII8 }, { "BS6202", SLOT_ASCII8 }, { "BS6101", SLOT_ASCII8 }, { "M60002-0125SP-16", SLOT_ASCII16 }, { "LZ93A13-16", SLOT_ASCII16 }, { "BS6101-16", SLOT_ASCII16 }, { "MR6401", SLOT_ASCII16 }, { "CROSS-BLAIM", SLOT_CROSS_BLAIM }, { "GMASTER2", SLOT_GAMEMASTER2 }, { "80IN1", SLOT_KOREAN_80IN1 }, { "90IN1", SLOT_KOREAN_90IN1 }, { "126IN1", SLOT_KOREAN_126IN1 }, { "FM-PAC", SLOT_FMPAC }, { "IREM TAM-S1", SLOT_RTYPE }, { "KONAMI", SLOT_KONAMI }, { "KONAMI-SCC", SLOT_KONAMI_SCC }, { "SUPERLODE", SLOT_SUPERLODERUNNER }, { "MAJUTSUSHI", SLOT_MAJUTSUSHI }, }; for (int i = 0; i < ARRAY_LENGTH(mapper_types) && type < 0; i++) { if (!mame_stricmp(mapper, mapper_types[i].mapper_name)) type = mapper_types[i].mapper_type; } if (-1 == type) logerror("Mapper '%s' not recognized!\n", mapper); } UINT8 *tmp_sram = image.get_software_region("sram"); if (tmp_sram) { if (type == SLOT_ASCII8) type = SLOT_ASCII8_SRAM; if (type == SLOT_ASCII16) type = SLOT_ASCII16_SRAM; } UINT8 *rom_region = image.get_software_region("rom"); size = size_aligned = image.get_software_region_length("rom"); mem = auto_alloc_array(machine(), UINT8, size_aligned); memcpy(mem, rom_region, size_aligned); } else { /* Old style image loading */ size = image.length (); if (size < 0x2000) { logerror ("cart #%d: error: file is smaller than 2kb, too small to be true!\n", id); return IMAGE_INIT_FAIL; } /* allocate memory and load */ size_aligned = 0x2000; while (size_aligned < size) size_aligned *= 2; mem = auto_alloc_array(machine(),UINT8,size_aligned); if (!mem) { logerror ("cart #%d: error: failed to allocate memory for cartridge\n", id); return IMAGE_INIT_FAIL; } if (size < size_aligned) memset (mem, 0xff, size_aligned); if (image.fread(mem, size) != size) { logerror ("cart #%d: %s: can't read full %d bytes\n", id, image.filename (), size); return IMAGE_INIT_FAIL; } /* see if msx.crc will tell us more */ extra = hashfile_extrainfo(image); if (!extra) { logerror("cart #%d: warning: no information in crc file\n", id); type = -1; } else if ((1 != sscanf(extra, "%d", &type) ) || type < 0 || type > SLOT_LAST_CARTRIDGE_TYPE) { logerror("cart #%d: warning: information in crc file not valid\n", id); type = -1; } else logerror ("cart #%d: info: cart extra info: '%s' = %s\n", id, extra, msx_slot_list[type].name); /* if not, attempt autodetection */ if (type < 0) { type = msx_probe_type (mem, size); if (mem[0] != 'A' || mem[1] != 'B') logerror("cart #%d: %s: May not be a valid ROM file\n", id, image.filename ()); logerror("cart #%d: Probed cartridge mapper %d/%s\n", id, type, msx_slot_list[type].name); } } /* mapper type 0 always needs 64kB */ if (!type && size_aligned != 0x10000) { UINT8 *old_mem = mem; int old_size_aligned = size_aligned; size_aligned = 0x10000; mem = auto_alloc_array(machine(),UINT8, 0x10000); if (!mem) { auto_free(machine(),old_mem); logerror ("cart #%d: error: cannot allocate memory\n", id); return IMAGE_INIT_FAIL; } if (size < 0x10000) memset (mem + size, 0xff, 0x10000 - size); if (size > 0x10000) { logerror ("cart #%d: warning: rom truncated to 64kb due to mapperless type (possibly detected)\n", id); size = 0x10000; } /* Copy old contents to newly claimed memory */ memcpy(mem,old_mem,old_size_aligned); auto_free(machine(),old_mem); } /* mapper type 0 (ROM) might need moving around a bit */ if (!type) { int i, page = 1; /* find the correct page */ if (mem[0] == 'A' && mem[1] == 'B') { for (i=2; i<=8; i += 2) { if (mem[i] || mem[i+1]) { page = mem[i+1] / 0x40; break; } } } if (size <= 0x4000) { if (page == 1 || page == 2) { /* copy to the respective page */ memcpy (mem + (page * 0x4000), mem, 0x4000); memset (mem, 0xff, 0x4000); } else { /* memory is repeated 4 times */ page = -1; memcpy (mem + 0x4000, mem, 0x4000); memcpy (mem + 0x8000, mem, 0x4000); memcpy (mem + 0xc000, mem, 0x4000); } } else /*if (size <= 0xc000) */ { if (page) { /* shift up 16kB; custom memcpy so overlapping memory isn't corrupted. ROM starts in page 1 (0x4000) */ UINT8 *m; page = 1; i = 0xc000; m = mem + 0xffff; while (i--) { *m = *(m - 0x4000); m--; } memset (mem, 0xff, 0x4000); } } if (page) logerror ("cart #%d: info: rom in page %d\n", id, page); else logerror ("cart #%d: info: rom duplicted in all pages\n", id); } /* kludge */ if (type == 0) type = SLOT_ROM; /* allocate and set slot_state for this cartridge */ st = auto_alloc(machine(),slot_state); if (!st) { logerror ("cart #%d: error: cannot allocate memory for cartridge state\n", id); return IMAGE_INIT_FAIL; } memset (st, 0, sizeof (slot_state)); st->m_type = type; sramfile = auto_alloc_array(machine(), char, strlen (image.filename () + 1)); if (sramfile) { char *ext; strcpy (sramfile, image.basename ()); ext = strrchr (sramfile, '.'); if (ext) *ext = 0; st->m_sramfile = sramfile; } if (msx_slot_list[type].init (machine(), st, 0, mem, size_aligned)) return IMAGE_INIT_FAIL; if (msx_slot_list[type].loadsram) msx_slot_list[type].loadsram (machine(), st); m_cart_state[id] = st; msx_memory_set_carts(); return IMAGE_INIT_PASS; }