image_init_result ekara_cart_slot_device::call_load() { if (m_cart) { uint8_t *ROM; uint32_t len = !loaded_through_softlist() ? length() : get_software_region_length("rom"); m_cart->rom_alloc(len, tag()); ROM = m_cart->get_rom_base(); if (!loaded_through_softlist()) fread(ROM, len); else memcpy(ROM, get_software_region("rom"), len); if (!loaded_through_softlist()) { // attempt to detect cart type without softlist assistance m_type = get_cart_type(ROM, len); } else { // or for softlist loading, use the type specified const char *pcb_name = get_feature("slot"); if (pcb_name) m_type = ekara_get_pcb_id(pcb_name); } return image_init_result::PASS; } return image_init_result::PASS; }
uint32_t generic_slot_device::common_get_size(const char *region) { // if we are loading from softlist, you have to specify a region assert(!loaded_through_softlist() || (region != nullptr)); return !loaded_through_softlist() ? length() : get_software_region_length(region); }
void generic_slot_device::common_load_rom(uint8_t *ROM, uint32_t len, const char *region) { // basic sanity check assert((ROM != nullptr) && (len > 0)); // if we are loading from softlist, you have to specify a region assert(!loaded_through_softlist() || (region != nullptr)); if (!loaded_through_softlist()) fread(ROM, len); else memcpy(ROM, get_software_region(region), len); }
image_init_result iq151cart_slot_device::call_load() { if (m_cart) { offs_t read_length; uint8_t *cart_base = m_cart->get_cart_base(); if (cart_base != nullptr) { if (!loaded_through_softlist()) { read_length = length(); fread(m_cart->get_cart_base(), read_length); } else { read_length = get_software_region_length("rom"); memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length); } } else return image_init_result::FAIL; } return image_init_result::PASS; }
image_init_result z88cart_slot_device::call_load() { if (m_cart) { uint8_t *cart_base = m_cart->get_cart_base(); if (cart_base != nullptr) { if (!loaded_through_softlist()) { offs_t read_length = length(); fread(cart_base + (m_cart->get_cart_size() - read_length), read_length); } else { offs_t read_length = get_software_region_length("rom"); memcpy(cart_base + (m_cart->get_cart_size() - read_length), get_software_region("rom"), read_length); } } else { return image_init_result::FAIL; } } // open the flap m_out_flp_cb(ASSERT_LINE); // setup the timer for close the flap m_flp_timer->adjust(CLOSE_FLAP_TIME); return image_init_result::PASS; }
image_init_result nes_datach_slot_device::call_load() { if (m_cart) { uint8_t *ROM = m_cart->get_cart_base(); if (!ROM) return image_init_result::FAIL; // Existing Datach carts are all 256K, so we only load files of this size if (!loaded_through_softlist()) { if (length() != 0x40000 && length() != 0x40010) return image_init_result::FAIL; int shift = length() - 0x40000; uint8_t temp[0x40010]; fread(&temp, length()); memcpy(ROM, temp + shift, 0x40000); // double check that iNES files are really mapper 157 // (or 16, since some older .nes files marked Datach as mapper 16) if (length() == 0x40010) { uint8_t mapper = (temp[6] & 0xf0) >> 4; mapper |= temp[7] & 0xf0; if (mapper != 157 && mapper != 16) { return image_init_result::FAIL; } } } else { if (get_software_region_length("rom") != 0x40000)
image_init_result nes_kstudio_slot_device::call_load() { if (m_cart) { uint8_t *ROM = m_cart->get_cart_base(); if (!ROM) return image_init_result::FAIL; // Existing expansion carts are all 128K, so we only load files of this size if (!loaded_through_softlist()) { if (length() != 0x20000) return image_init_result::FAIL; fread(&ROM, 0x20000); } else { if (get_software_region_length("rom") != 0x20000) return image_init_result::FAIL; memcpy(ROM, get_software_region("rom"), 0x20000); } } return image_init_result::PASS; }
image_init_result nes_ntb_slot_device::call_load() { if (m_cart) { uint8_t *ROM = m_cart->get_cart_base(); if (!ROM) return image_init_result::FAIL; if (!loaded_through_softlist()) { if (length() != 0x4000) return image_init_result::FAIL; fread(&ROM, 0x4000); } else { if (get_software_region_length("rom") != 0x4000) return image_init_result::FAIL; memcpy(ROM, get_software_region("rom"), 0x4000); } } return image_init_result::PASS; }
image_init_result sat_cart_slot_device::call_load() { if (m_cart) { bool is_rom = (!loaded_through_softlist() || (loaded_through_softlist() && get_software_region("rom"))); if (is_rom) { // from fullpath, only ROM carts uint32_t len = loaded_through_softlist() ? get_software_region_length("rom") : length(); uint32_t *ROM; m_cart->rom_alloc(len, tag()); ROM = m_cart->get_rom_base(); if (loaded_through_softlist()) memcpy(ROM, get_software_region("rom"), len); else fread(ROM, len); // fix endianness.... for (int i = 0; i < len/4; i ++) ROM[i] = bitswap<32>(ROM[i],7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,23,22,21,20,19,18,17,16,31,30,29,28,27,26,25,24); // { // uint8_t tempa = ROM[i+0]; // uint8_t tempb = ROM[i+1]; // ROM[i+1] = ROM[i+2]; // ROM[i+0] = ROM[i+3]; // ROM[i+3] = tempa; // ROM[i+2] = tempb; // } } else { // DRAM or BRAM carts from softlist if (get_software_region("bram")) m_cart->bram_alloc(get_software_region_length("bram")); if (get_software_region("dram0")) m_cart->dram0_alloc(get_software_region_length("dram0")); if (get_software_region("dram1")) m_cart->dram1_alloc(get_software_region_length("dram1")); } return image_init_result::PASS; } return image_init_result::PASS; }
image_init_result vsmile_cart_slot_device::call_load() { if (m_cart) { uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length(); if (size > 0x1000000) { seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 16MB"); return image_init_result::FAIL; } m_cart->rom_alloc(size, tag()); uint8_t *rom = (uint8_t *)m_cart->get_rom_base(); if (!loaded_through_softlist()) { fread(rom, size); m_type = VSMILE_STD; } else { const char *pcb_name = get_feature("slot"); memcpy(rom, get_software_region("rom"), size); if (pcb_name) m_type = vsmile_get_pcb_id(pcb_name); osd_printf_info("V.Smile: Detected (XML) %s\n", pcb_name ? pcb_name : "NONE"); } if (m_type == VSMILE_NVRAM) { m_cart->nvram_alloc(0x200000); } if (m_cart->get_nvram_size()) { battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0x00); } return image_init_result::PASS; } return image_init_result::PASS; }
image_init_result hp_optrom_slot_device::call_load() { logerror("hp_optrom: call_load\n"); if (m_cart == nullptr || !loaded_through_softlist()) { logerror("hp_optrom: must be loaded from sw list\n"); return image_init_result::FAIL; } const char *base_feature = get_feature("base"); if (base_feature == nullptr) { logerror("hp_optrom: no 'base' feature\n"); return image_init_result::FAIL; } offs_t base_addr; if (base_feature[ 0 ] != '0' || base_feature[ 1 ] != 'x' || sscanf(&base_feature[ 2 ] , "%x" , &base_addr) != 1) { logerror("hp_optrom: can't parse 'base' feature\n"); return image_init_result::FAIL; } // Valid BSC values for ROMs on LPU drawer: 0x07 0x0b .... 0x3b // Valid BSC values for ROMs on PPU drawer: 0x09 0x0d .... 0x3d // (BSC is field in bits 16..21 of base address) // Bit 15 of base address must be 0 // Base address must be multiple of 0x1000 if ((base_addr & ~0x3f7000UL) != 0 || ((base_addr & 0x30000) != 0x10000 && (base_addr & 0x30000) != 0x30000) || base_addr < 0x70000) { logerror("hp_optrom: illegal base address (%x)\n" , base_addr); return image_init_result::FAIL; } auto length = get_software_region_length("rom") / 2; if (length < 0x1000 || length > 0x8000 || (length & 0xfff) != 0 || ((base_addr & 0x7000) + length) > 0x8000) { logerror("hp_optrom: illegal region length (%x)\n" , length); return image_init_result::FAIL; } offs_t end_addr = base_addr + length - 1; logerror("hp_optrom: base_addr = %06x end_addr = %06x\n" , base_addr , end_addr); m_content.resize(length * 2); uint8_t *buffer = m_content.data(); memcpy(buffer , get_software_region("rom") , length * 2); // Install ROM in address space of every CPU for (hp_hybrid_cpu_device& cpu : device_interface_iterator<hp_hybrid_cpu_device>(machine().root_device())) { logerror("hp_optrom: install in %s AS\n" , cpu.tag()); cpu.space(AS_PROGRAM).install_rom(base_addr , end_addr , buffer); } m_base_addr = base_addr; m_end_addr = end_addr; return image_init_result::PASS; }
bool device_image_interface::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) { const software_list_loader &loader = get_software_list_loader(); bool result = loader.load_software(*this, swlist, swname, start_entry); // this is a hook that seems to only be used by TI99 if (result) loaded_through_softlist(); return result; }
image_init_result cococart_slot_device::call_load() { if (m_cart) { offs_t read_length; if (!loaded_through_softlist()) { read_length = fread(m_cart->get_cart_base(), 0x8000); } else { read_length = get_software_region_length("rom"); memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length); } while(read_length < 0x8000) { offs_t len = std::min(read_length, 0x8000 - read_length); memcpy(m_cart->get_cart_base() + read_length, m_cart->get_cart_base(), len); read_length += len; } } return image_init_result::PASS; }
image_init_result electron_cartslot_device::call_load() { if (m_cart) { if (!loaded_through_softlist()) { uint32_t size = length(); if (size % 0x2000) { seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); return image_init_result::FAIL; } m_cart->rom_alloc(size, tag()); fread(m_cart->get_rom_base(), size); } else { // standard 2x16K ROMs cartridges uint32_t upsize = get_software_region_length("uprom"); uint32_t losize = get_software_region_length("lorom"); // other RAM/ROM device cartridges uint32_t romsize = get_software_region_length("rom"); uint32_t ramsize = get_software_region_length("ram"); uint32_t nvramsize = get_software_region_length("nvram"); if ((upsize % 0x2000 && upsize != 0) || (losize % 0x2000 && losize != 0) || (romsize % 0x2000 && romsize != 0)) { seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); return image_init_result::FAIL; } // load standard 2x16K ROM cartridges if (losize != 0 || upsize != 0) { m_cart->rom_alloc(0x8000, tag()); if (losize) memcpy(m_cart->get_rom_base() + 0x0000, get_software_region("lorom"), losize); if (upsize) memcpy(m_cart->get_rom_base() + 0x4000, get_software_region("uprom"), upsize); } // load ROM region of device cartridge if (romsize != 0) { m_cart->rom_alloc(romsize, tag()); memcpy(m_cart->get_rom_base(), get_software_region("rom"), romsize); } // load RAM region of device cartridge if (ramsize != 0) { m_cart->ram_alloc(ramsize); memcpy(m_cart->get_ram_base(), get_software_region("ram"), ramsize); } // load NVRAM region of device cartridge if (nvramsize != 0) { std::vector<uint8_t> default_nvram(nvramsize); memcpy(&default_nvram[0], get_software_region("nvram"), nvramsize); // load NVRAM (using default if no NVRAM exists) std::vector<uint8_t> temp_nvram(nvramsize); battery_load(&temp_nvram[0], nvramsize, &default_nvram[0]); // copy NVRAM into cartridge m_cart->nvram_alloc(nvramsize); memcpy(m_cart->get_nvram_base(), &temp_nvram[0], nvramsize); } } } return image_init_result::PASS; }
image_init_result gba_cart_slot_device::call_load() { if (m_cart) { uint8_t *ROM; uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length(); if (size > 0x4000000) { seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 64MB"); return image_init_result::FAIL; } m_cart->rom_alloc(size, tag()); ROM = (uint8_t *)m_cart->get_rom_base(); if (!loaded_through_softlist()) { fread(ROM, size); m_type = get_cart_type(ROM, size); } else { const char *pcb_name = get_feature("slot"); memcpy(ROM, get_software_region("rom"), size); if (pcb_name) m_type = gba_get_pcb_id(pcb_name); //printf("Type: %s\n", gba_get_slot(m_type)); osd_printf_info("GBA: Detected (XML) %s\n", pcb_name ? pcb_name : "NONE"); } if (m_type == GBA_SRAM || m_type == GBA_DRILLDOZ || m_type == GBA_WARIOTWS) m_cart->nvram_alloc(0x10000); // mirror the ROM switch (size) { case 2 * 1024 * 1024: memcpy(ROM + 0x200000, ROM, 0x200000); // intentional fall-through case 4 * 1024 * 1024: memcpy(ROM + 0x400000, ROM, 0x400000); // intentional fall-through case 8 * 1024 * 1024: memcpy(ROM + 0x800000, ROM, 0x800000); // intentional fall-through case 16 * 1024 * 1024: memcpy(ROM + 0x1000000, ROM, 0x1000000); break; } if (size == 0x4000000) { memcpy((uint8_t *)m_cart->get_romhlp_base(), ROM, 0x2000000); for (uint32_t i = 0; i < 16; i++) { memcpy((uint8_t *)m_cart->get_romhlp_base() + i * 0x1000, ROM + 0x200, 0x1000); } memcpy((uint8_t *)m_cart->get_romhlp_base(), ROM, 0x180); } if (m_cart->get_nvram_size()) battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0x00); return image_init_result::PASS; } return image_init_result::PASS; }
void sega8_cart_slot_device::internal_header_logging(uint8_t *ROM, uint32_t len, uint32_t nvram_len) { static const char *const system_region[] = { "", "", "", "Master System Japan", "Master System Export", "Game Gear Japan", "Game Gear Export", "Game Gear International", "", "", "", "", "", "", "", "" }; static int csum_length[] = { 0x40000, 0x80000, 0x100000, 0, 0, 0, 0, 0, 0, 0, 0x1ff0, 0x3ff0, 0x7ff0, 0xcff0, 0x10000, 0x20000, }; char reserved[10]; uint8_t version, csum_size, region, serial[3]; uint16_t checksum, csum = 0; uint32_t csum_end; // LOG FILE DETAILS logerror("FILE DETAILS\n" ); logerror("============\n" ); logerror("Name: %s\n", basename()); logerror("File Size: 0x%08x\n", !loaded_through_softlist() ? (int)length() : (int)get_software_region_length("rom")); logerror("Detected type: %s\n", sega8_get_slot(m_type)); logerror("ROM (Allocated) Size: 0x%X\n", len); logerror("RAM: %s\n", nvram_len ? "Yes" : "No"); if (nvram_len) logerror("RAM (Allocated) Size: 0x%X - Battery: %s\n", nvram_len, m_cart->get_has_battery() ? "Yes" : "No"); logerror("\n" ); // LOG HEADER DETAILS if (len < 0x8000) return; for (int i = 0; i < 10; i++) reserved[i] = ROM[0x7ff0 + i]; checksum = ROM[0x7ffa] | (ROM[0x7ffb] << 8); for (int i = 0; i < 3; i++) serial[i] = ROM[0x7ffc + i]; serial[2] &= 0x0f; version = (ROM[0x7ffe] & 0xf0) >> 4; csum_size = ROM[0x7fff] & 0x0f; csum_end = csum_length[csum_size]; if (!csum_end || csum_end > len) csum_end = len; region = (ROM[0x7fff] & 0xf0) >> 4; // compute cart checksum to compare with expected one for (int i = 0; i < csum_end; i++) { if (i < 0x7ff0 || i >= 0x8000) { csum += ROM[i]; csum &= 0xffff; } } logerror("INTERNAL HEADER\n" ); logerror("===============\n" ); logerror("Reserved String: %.10s\n", reserved); logerror("Region: %s\n", system_region[region]); logerror("Checksum: (Expected) 0x%x - (Computed) 0x%x\n", checksum, csum); logerror(" [checksum over 0x%X bytes]\n", csum_length[csum_size]); logerror("Serial String: %X\n", serial[0] | (serial[1] << 8) | (serial[2] << 16)); logerror("Software Revision: %x\n", version); logerror("\n" ); if (m_type == SEGA8_CODEMASTERS) { uint8_t day, month, year, hour, minute; csum = 0; day = ROM[0x7fe1]; month = ROM[0x7fe2]; year = ROM[0x7fe3]; hour = ROM[0x7fe4]; minute = ROM[0x7fe5]; checksum = ROM[0x7fe6] | (ROM[0x7fe7] << 8); csum_size = ROM[0x7fe0]; // compute cart checksum to compare with expected one for (int i = 0; i < len; i += 2) { if (i < 0x7ff0 || i >= 0x8000) { csum += (ROM[i] | (ROM[i + 1] << 8)); csum &= 0xffff; } } logerror("CODEMASTERS HEADER\n" ); logerror("==================\n" ); logerror("Build date & time: %x/%x/%x %.2x:%.2x\n", day, month, year, hour, minute); logerror("Checksum: (Expected) 0x%x - (Computed) 0x%x\n", checksum, csum); logerror(" [checksum over 0x%X bytes]\n", csum_size * 0x4000); logerror("\n" ); } }
image_init_result sega8_cart_slot_device::call_load() { if (m_cart) { uint32_t len = !loaded_through_softlist() ? length() : get_software_region_length("rom"); uint32_t offset = 0; uint8_t *ROM; if (m_is_card && len > 0x8000) { seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a card larger than 32KB"); return image_init_result::FAIL; } // check for header if ((len % 0x4000) == 512) { offset = 512; len -= 512; } // make sure that we only get complete (0x4000) rom banks if (len & 0x3fff) len = ((len >> 14) + 1) << 14; m_cart->rom_alloc(len, tag()); ROM = m_cart->get_rom_base(); if (!loaded_through_softlist()) { fseek(offset, SEEK_SET); fread(ROM, len); } else memcpy(ROM, get_software_region("rom"), get_software_region_length("rom")); /* check the image */ if (verify_cart(ROM, len) != image_verify_result::PASS) logerror("Warning loading image: verify_cart failed\n"); if (loaded_through_softlist()) m_type = sega8_get_pcb_id(get_feature("slot") ? get_feature("slot") : "rom"); else m_type = get_cart_type(ROM, len); set_lphaser_xoffset(ROM, len); setup_ram(); // Check for gamegear cartridges with PIN 42 set to SMS mode if (loaded_through_softlist()) { const char *pin_42 = get_feature("pin_42"); if (pin_42 && !strcmp(pin_42, "sms_mode")) m_cart->set_sms_mode(1); } // when loading from fullpath m_late_battery_enable can be true and in that case // we attempt to load a battery because the game might have it! if (m_cart->get_ram_size() && (m_cart->get_has_battery() || m_cart->get_late_battery())) battery_load(m_cart->get_ram_base(), m_cart->get_ram_size(), 0x00); //printf("Type: %s\n", sega8_get_slot(type)); internal_header_logging(ROM + offset, len, m_cart->get_ram_size()); return image_init_result::PASS; } return image_init_result::PASS; }
image_init_result vcs_cart_slot_device::call_load() { if (m_cart) { uint8_t *ROM; uint32_t len; if (loaded_through_softlist()) len = get_software_region_length("rom"); else len = length(); //printf("Size: 0x%X\n", len); // check that filesize is among the supported ones switch (len) { case 0x00800: case 0x01000: case 0x02000: case 0x028ff: case 0x02900: case 0x03000: case 0x04000: case 0x08000: case 0x10000: case 0x80000: break; default: seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" ); return image_init_result::FAIL; } m_cart->rom_alloc(len, tag()); ROM = m_cart->get_rom_base(); if (loaded_through_softlist()) { const char *pcb_name; bool has_ram = get_software_region("ram") ? true : false; memcpy(ROM, get_software_region("rom"), len); if ((pcb_name = get_feature("slot")) != nullptr) m_type = vcs_get_pcb_id(pcb_name); else { // identify type based on size switch (len) { case 0x800: m_type = A26_2K; break; case 0x1000: m_type = A26_4K; break; case 0x2000: m_type = A26_F8; break; case 0x28ff: case 0x2900: m_type = A26_DPC; break; case 0x3000: m_type = A26_FA; break; case 0x4000: m_type = A26_F6; break; case 0x8000: m_type = A26_F4; break; case 0x10000: m_type = A26_32IN1; break; case 0x80000: m_type = A26_3F; break; default: m_type = A26_4K; printf("Unrecognized cart type!\n"); break; } } if (has_ram) m_cart->ram_alloc(get_software_region_length("ram")); } else { fread(ROM, len); m_type = identify_cart_type(ROM, len); // check for Special Chip (128bytes of RAM) if (len == 0x2000 || len == 0x4000 || len == 0x8000) if (detect_super_chip(ROM, len)) { m_cart->ram_alloc(0x80); //printf("Super Chip detected!\n"); } // Super chip games: // dig dig, crystal castles, millipede, stargate, defender ii, jr. Pac Man, // desert falcon, dark chambers, super football, sprintmaster, fatal run, // off the wall, shooting arcade, secret quest, radar lock, save mary, klax // add CBS RAM+ (256bytes of RAM) if (m_type == A26_FA) m_cart->ram_alloc(0x100); // add M Network RAM else if (m_type == A26_E7) m_cart->ram_alloc(0x800); // add Commavid RAM else if (m_type == A26_CV) m_cart->ram_alloc(0x400); // add Starpath Superchager RAM else if (m_type == A26_SS) m_cart->ram_alloc(0x1800); // add Boulder Dash RAM else if (m_type == A26_3E) m_cart->ram_alloc(0x8000); } //printf("Type: %s\n", vcs_get_slot(m_type)); // pass a pointer to the now allocated ROM for the DPC chip if (m_type == A26_DPC) m_cart->setup_addon_ptr((uint8_t *)m_cart->get_rom_base() + 0x2000); return image_init_result::PASS; } return image_init_result::PASS; }
void sega8_cart_slot_device::setup_ram() { if (!loaded_through_softlist()) { if (m_type == SEGA8_CASTLE) { m_cart->ram_alloc(0x2000); m_cart->set_has_battery(false); } else if (m_type == SEGA8_OTHELLO) { m_cart->ram_alloc(0x800); m_cart->set_has_battery(false); } else if (m_type == SEGA8_BASIC_L3 || m_type == SEGA8_MULTICART || m_type == SEGA8_MEGACART) { m_cart->ram_alloc(0x8000); m_cart->set_has_battery(false); } else if (m_type == SEGA8_MUSIC_EDITOR) { m_cart->ram_alloc(0x2800); m_cart->set_has_battery(false); } else if (m_type == SEGA8_DAHJEE_TYPEA) { m_cart->ram_alloc(0x2400); m_cart->set_has_battery(false); } else if (m_type == SEGA8_DAHJEE_TYPEB) { m_cart->ram_alloc(0x2000); m_cart->set_has_battery(false); } else if (m_type == SEGA8_CODEMASTERS) { // Codemasters cart can have 64KB of RAM (Ernie Els Golf? or 8KB?) and no battery m_cart->ram_alloc(0x10000); m_cart->set_has_battery(false); } else { // for generic carts loaded from fullpath we have no way to know exactly if there was RAM, // how much RAM was in the cart and if there was a battery so we always alloc 32KB and // we save its content only if the game enable the RAM m_cart->set_late_battery(true); m_cart->ram_alloc(0x08000); } } else { // from softlist we rely on the xml to only allocate the correct amount of RAM and to save it only if a battery was present const char *battery = get_feature("battery"); m_cart->set_late_battery(false); if (get_software_region_length("ram")) m_cart->ram_alloc(get_software_region_length("ram")); if (battery && !strcmp(battery, "yes")) m_cart->set_has_battery(true); } }