param_t::param_t(device_t &device, const pstring &name) : device_object_t(device, device.name() + "." + name) { device.setup().register_param_t(this->name(), *this); }
device_bbc_1mhzbus_interface::device_bbc_1mhzbus_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<bbc_1mhzbus_slot_device *>(device.owner()); }
device_isbx_card_interface::device_isbx_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<isbx_slot_device *>(device.owner()); }
abc_keyboard_interface::abc_keyboard_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig,device) { m_slot = dynamic_cast<abc_keyboard_port_device *>(device.owner()); }
device_einstein_userport_interface::device_einstein_userport_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<einstein_userport_device *>(device.owner()); }
device_tiki100bus_card_interface::device_tiki100bus_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device), m_bus(nullptr), m_busak(CLEAR_LINE), m_next(nullptr) { m_slot = dynamic_cast<tiki100_bus_slot_t *>(device.owner()); }
device_newbrain_expansion_slot_interface::device_newbrain_expansion_slot_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig,device) { m_slot = dynamic_cast<newbrain_expansion_slot_t *>(device.owner()); }
std::string rom_region_name(const device_t &device, const rom_entry *romp) { return device.subtag(ROM_GETNAME(romp)); }
std::string rom_parameter_name(const device_t &device, const rom_entry *romp) { return device.subtag(romp->_name); }
device_centronics_peripheral_interface::device_centronics_peripheral_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<centronics_device *>(device.owner()); }
void rom_load_manager::load_software_part_region(device_t &device, software_list_device &swlist, const char *swname, const rom_entry *start_region) { std::string locationtag(swlist.list_name()), breakstr("%"); const rom_entry *region; std::string regiontag; m_errorstring.clear(); m_softwarningstring.clear(); m_romstotal = 0; m_romstotalsize = 0; m_romsloadedsize = 0; software_info *swinfo = swlist.find(swname); if (swinfo != nullptr) { UINT32 supported = swinfo->supported(); if (supported == SOFTWARE_SUPPORTED_PARTIAL) { m_errorstring.append(string_format("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist.list_name())); m_softwarningstring.append(string_format("Support for software %s (in list %s) is only partial\n", swname, swlist.list_name())); } if (supported == SOFTWARE_SUPPORTED_NO) { m_errorstring.append(string_format("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name())); m_softwarningstring.append(string_format("Support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name())); } // attempt reading up the chain through the parents and create a locationtag std::string in the format // " swlist % clonename % parentname " // open_rom_file contains the code to split the elements and to create paths to load from locationtag.append(breakstr); while (swinfo != nullptr) { locationtag.append(swinfo->shortname()).append(breakstr); const char *parentname = swinfo->parentname(); swinfo = (parentname != nullptr) ? swlist.find(parentname) : nullptr; } // strip the final '%' locationtag.erase(locationtag.length() - 1, 1); } /* loop until we hit the end */ for (region = start_region; region != nullptr; region = rom_next_region(region)) { UINT32 regionlength = ROMREGION_GETLENGTH(region); regiontag = device.subtag(ROMREGION_GETTAG(region)); LOG(("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength)); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); /* if this is a device region, override with the device width and endianness */ endianness_t endianness = ROMREGION_ISBIGENDIAN(region) ? ENDIANNESS_BIG : ENDIANNESS_LITTLE; UINT8 width = ROMREGION_GETWIDTH(region) / 8; memory_region *memregion = machine().root_device().memregion(regiontag.c_str()); if (memregion != nullptr) { if (machine().device(regiontag.c_str()) != nullptr) normalize_flags_for_device(machine(), regiontag.c_str(), width, endianness); /* clear old region (todo: should be moved to an image unload function) */ machine().memory().region_free(memregion->name()); } /* remember the base and length */ m_region = machine().memory().region_alloc(regiontag.c_str(), regionlength, width, endianness); LOG(("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base())); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(m_region->base(), ROMREGION_GETERASEVAL(region), m_region->bytes()); /* or if it's sufficiently small (<= 4MB) */ else if (m_region->bytes() <= 0x400000) memset(m_region->base(), 0, m_region->bytes()); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(m_region->base(), m_region->bytes()); #endif /* update total number of roms */ for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) { m_romstotal++; m_romstotalsize += rom_file_size(rom); } /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) process_rom_entries(locationtag.c_str(), region, region + 1, &device, TRUE); else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(regiontag.c_str(), region, region + 1, locationtag.c_str()); } /* now go back and post-process all the regions */ for (region = start_region; region != nullptr; region = rom_next_region(region)) { regiontag = device.subtag(ROMREGION_GETTAG(region)); region_post_process(regiontag.c_str(), ROMREGION_ISINVERTED(region)); } /* display the results and exit */ display_rom_load_results(TRUE); }
device_compis_graphics_card_interface::device_compis_graphics_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<compis_graphics_slot_t *>(device.owner()); }
param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val) : param_t(device, name) { m_param = device.setup().get_initial_param_val(this->name(),val); }
pstring param_t::get_initial(const device_t &dev, bool *found) { pstring res = dev.setup().get_initial_param_val(this->name(), ""); *found = (res != ""); return res; }
scsi_port_interface::scsi_port_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<SCSI_PORT_SLOT_device *>(device.owner()); }
device_ql_expansion_card_interface::device_ql_expansion_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device), m_romoeh(0) { m_slot = dynamic_cast<ql_expansion_slot_device *>(device.owner()); }
device_pet_datassette_port_interface::device_pet_datassette_port_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig,device) { m_slot = dynamic_cast<pet_datassette_port_device *>(device.owner()); }
device_sun_keyboard_port_interface::device_sun_keyboard_port_interface(machine_config const &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) , m_port(dynamic_cast<sun_keyboard_port_device *>(device.owner())) { }
void info_xml_creator::output_display(device_t &device, const char *root_tag) { // iterate over screens screen_device_iterator iter(device); for (const screen_device *screendev = iter.first(); screendev != NULL; screendev = iter.next()) { if (strcmp(screendev->tag(), device.tag())) { astring newtag(screendev->tag()), oldtag(":"); newtag.substr(newtag.find(oldtag.cat(root_tag)) + oldtag.len()); fprintf(m_output, "\t\t<display"); fprintf(m_output, " tag=\"%s\"", xml_normalize_string(newtag)); switch (screendev->screen_type()) { case SCREEN_TYPE_RASTER: fprintf(m_output, " type=\"raster\""); break; case SCREEN_TYPE_VECTOR: fprintf(m_output, " type=\"vector\""); break; case SCREEN_TYPE_LCD: fprintf(m_output, " type=\"lcd\""); break; default: fprintf(m_output, " type=\"unknown\""); break; } // output the orientation as a string switch (m_drivlist.driver().flags & ORIENTATION_MASK) { case ORIENTATION_FLIP_X: fprintf(m_output, " rotate=\"0\" flipx=\"yes\""); break; case ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"180\" flipx=\"yes\""); break; case ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"180\""); break; case ORIENTATION_SWAP_XY: fprintf(m_output, " rotate=\"90\" flipx=\"yes\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X: fprintf(m_output, " rotate=\"90\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"270\""); break; case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y: fprintf(m_output, " rotate=\"270\" flipx=\"yes\""); break; default: fprintf(m_output, " rotate=\"0\""); break; } // output width and height only for games that are not vector if (screendev->screen_type() != SCREEN_TYPE_VECTOR) { const rectangle &visarea = screendev->visible_area(); fprintf(m_output, " width=\"%d\"", visarea.width()); fprintf(m_output, " height=\"%d\"", visarea.height()); } // output refresh rate fprintf(m_output, " refresh=\"%f\"", ATTOSECONDS_TO_HZ(screendev->refresh_attoseconds())); // output raw video parameters only for games that are not vector // and had raw parameters specified if (screendev->screen_type() != SCREEN_TYPE_VECTOR && !screendev->oldstyle_vblank_supplied()) { int pixclock = screendev->width() * screendev->height() * ATTOSECONDS_TO_HZ(screendev->refresh_attoseconds()); fprintf(m_output, " pixclock=\"%d\"", pixclock); fprintf(m_output, " htotal=\"%d\"", screendev->width()); fprintf(m_output, " hbend=\"%d\"", screendev->visible_area().min_x); fprintf(m_output, " hbstart=\"%d\"", screendev->visible_area().max_x+1); fprintf(m_output, " vtotal=\"%d\"", screendev->height()); fprintf(m_output, " vbend=\"%d\"", screendev->visible_area().min_y); fprintf(m_output, " vbstart=\"%d\"", screendev->visible_area().max_y+1); } fprintf(m_output, " />\n"); } } }
device_abcbus_card_interface::device_abcbus_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<abcbus_slot_t *>(device.owner()); }
device_midi_port_interface::device_midi_port_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_port = dynamic_cast<midi_port_device *>(device.owner()); }
void address_map::map_validity_check(validity_checker &valid, const device_t &device, address_spacenum spacenum) const { // it's safe to assume here that the device has a memory interface and a config for this space const address_space_config &spaceconfig = *device.memory().space_config(spacenum); int datawidth = spaceconfig.m_databus_width; int alignunit = datawidth / 8; bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; // if this is an empty map, just ignore it if (m_entrylist.first() == nullptr) return; // validate the global map parameters if (m_spacenum != spacenum) osd_printf_error("Space %d has address space %d handlers!\n", spacenum, m_spacenum); if (m_databits != datawidth) osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig.m_name, datawidth, m_databits); // loop over entries and look for errors for (address_map_entry &entry : m_entrylist) { UINT32 bytestart = spaceconfig.addr2byte(entry.m_addrstart); UINT32 byteend = spaceconfig.addr2byte_end(entry.m_addrend); // look for overlapping entries if (!detected_overlap) { for (address_map_entry &scan : m_entrylist) { if (&scan == &entry) break; if (entry.m_addrstart <= scan.m_addrend && entry.m_addrend >= scan.m_addrstart && ((entry.m_read.m_type != AMH_NONE && scan.m_read.m_type != AMH_NONE) || (entry.m_write.m_type != AMH_NONE && scan.m_write.m_type != AMH_NONE))) { osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_read.m_type, entry.m_write.m_type, scan.m_addrstart, scan.m_addrend, scan.m_read.m_type, scan.m_write.m_type); detected_overlap = true; break; } } } // look for inverted start/end pairs if (byteend < bytestart) osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend); // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, alignunit); // if this is a program space, auto-assign implicit ROM entries if (entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { entry.m_region = device.tag(); entry.m_rgnoffs = entry.m_addrstart; } // if this entry references a memory region, validate it if (entry.m_region != nullptr && entry.m_share == nullptr) { // make sure we can resolve the full path to the region bool found = false; std::string entry_region = entry.m_devbase.subtag(entry.m_region); // look for the region for (device_t &dev : device_iterator(device.mconfig().root_device())) for (const rom_entry *romp = rom_first_region(dev); romp != nullptr && !found; romp = rom_next_region(romp)) { if (rom_region_name(dev, romp) == entry_region) { // verify the address range is within the region's bounds offs_t length = ROMREGION_GETLENGTH(romp); if (entry.m_rgnoffs + (byteend - bytestart + 1) > length) osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, length); found = true; } } // error if not found if (!found) osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); } // make sure all devices exist if (entry.m_read.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; switch (entry.m_read.m_bits) { case 8: devtag = entry.m_rproto8.device_name(); break; case 16: devtag = entry.m_rproto16.device_name(); break; case 32: devtag = entry.m_rproto32.device_name(); break; case 64: devtag = entry.m_rproto64.device_name(); break; } if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry reads from nonexistent device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : "<unspecified>"); } if (entry.m_write.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = nullptr; switch (entry.m_write.m_bits) { case 8: devtag = entry.m_wproto8.device_name(); break; case 16: devtag = entry.m_wproto16.device_name(); break; case 32: devtag = entry.m_wproto32.device_name(); break; case 64: devtag = entry.m_wproto64.device_name(); break; } if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry writes to nonexistent device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : "<unspecified>"); } if (entry.m_setoffsethd.m_type == AMH_DEVICE_DELEGATE) { // extract the device tag from the proto-delegate const char *devtag = entry.m_soproto.device_name(); if (entry.m_devbase.subdevice(devtag) == nullptr) osd_printf_error("%s space memory map entry references nonexistent device '%s'\n", spaceconfig.m_name, devtag != nullptr ? devtag : "<unspecified>"); } // make sure ports exist // if ((entry.m_read.m_type == AMH_PORT && entry.m_read.m_tag != nullptr && portlist.find(entry.m_read.m_tag) == nullptr) || // (entry.m_write.m_type == AMH_PORT && entry.m_write.m_tag != nullptr && portlist.find(entry.m_write.m_tag) == nullptr)) // osd_printf_error("%s space memory map entry references nonexistent port tag '%s'\n", spaceconfig.m_name, entry.m_read.m_tag); // validate bank and share tags if (entry.m_read.m_type == AMH_BANK) valid.validate_tag(entry.m_read.m_tag); if (entry.m_write.m_type == AMH_BANK) valid.validate_tag(entry.m_write.m_tag); if (entry.m_share != nullptr) valid.validate_tag(entry.m_share); } }
device_wangpcbus_card_interface::device_wangpcbus_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device), m_bus(nullptr), m_sid(0), m_next(nullptr) { m_slot = dynamic_cast<wangpcbus_slot_device *>(device.owner()); }
void address_map::uplift_submaps(running_machine &machine, device_t &device, device_t &owner, endianness_t endian) { address_map_entry *prev = 0; address_map_entry *entry = m_entrylist.first(); while (entry) { if (entry->m_read.m_type == AMH_DEVICE_SUBMAP) { astring tag; owner.subtag(tag, entry->m_read.m_tag); device_t *mapdevice = machine.device(tag); if (mapdevice == NULL) { throw emu_fatalerror("Attempted to submap a non-existent device '%s' in space %d of device '%s'\n", tag.cstr(), m_spacenum, device.basetag()); } // Grab the submap address_map submap(*mapdevice, entry); // Recursively uplift it if needed submap.uplift_submaps(machine, device, *mapdevice, endian); // Compute the unit repartition characteristics int entry_bits = entry->m_submap_bits; if (!entry_bits) entry_bits = m_databits; if (submap.m_databits != entry_bits) throw emu_fatalerror("AM_DEVICE wants a %d bits large address map and got a %d bits large one instead.\n", entry_bits, submap.m_databits); int entry_bytes = entry_bits / 8; int databytes = m_databits / 8; offs_t mirror_address_mask = (databytes - 1) & ~(entry_bytes - 1); UINT64 entry_mask = (2ULL << (entry_bits-1)) - 1; int slot_offset[8]; int slot_count = 0; int max_slot_count = m_databits / entry_bits; int slot_xor_mask = endian == ENDIANNESS_LITTLE ? 0 : max_slot_count - 1; UINT64 global_mask = entry->m_read.m_mask; // zero means all if (!global_mask) global_mask = ~global_mask; // mask consistency has already been checked in // unitmask_is_appropriate, so one bit is enough for (int slot=0; slot < max_slot_count; slot++) if (global_mask & (1ULL << ((slot ^ slot_xor_mask) * entry_bits))) slot_offset[slot_count++] = (slot ^ slot_xor_mask) * entry_bits; // Merge in all the map contents in order while (submap.m_entrylist.count()) { address_map_entry *subentry = submap.m_entrylist.detach_head(); // Remap start and end unsigned int start_offset = subentry->m_addrstart / entry_bytes; unsigned int start_slot = start_offset % slot_count; subentry->m_addrstart = entry->m_addrstart + (start_offset / slot_count) * databytes; // Drop the entry if it ends up outside the range if (subentry->m_addrstart > entry->m_addrend) { global_free(subentry); continue; } unsigned int end_offset = subentry->m_addrend / entry_bytes; unsigned int end_slot = end_offset % slot_count; subentry->m_addrend = entry->m_addrstart + (end_offset / slot_count) * databytes + databytes - 1; // Clip the entry to the end of the range if (subentry->m_addrend > entry->m_addrend || subentry->m_addrend < entry->m_addrstart) subentry->m_addrend = entry->m_addrend; // Detect special unhandled case (range straddling // slots, requiring splitting in multiple entries and // unimplemented offset-add subunit handler) if (subentry->m_addrstart + databytes - 1 != subentry->m_addrend && (start_slot != 0 || end_slot != slot_count - 1)) throw emu_fatalerror("uplift_submaps unhandled case: range straddling slots.\n"); if (entry->m_addrmask || subentry->m_addrmask) throw emu_fatalerror("uplift_submaps unhandled case: address masks.\n"); if (subentry->m_addrmirror & mirror_address_mask) throw emu_fatalerror("uplift_submaps unhandled case: address mirror bit within subentry.\n"); subentry->m_addrmirror |= entry->m_addrmirror; // Twiddle the unitmask on the data accessors that need it for (int data_entry = 0; data_entry < 3; data_entry++) { map_handler_data &mdata = (data_entry==0)? subentry->m_read : ((data_entry==1)? subentry->m_write : subentry->m_setoffsethd); if (mdata.m_type == AMH_NONE) continue; if (mdata.m_type != AMH_DEVICE_DELEGATE && mdata.m_type != AMH_NOP) throw emu_fatalerror("Only normal read/write methods are accepted in device submaps.\n"); if (mdata.m_bits == 0 && entry_bits != m_databits) mdata.m_bits = entry_bits; UINT64 mask = 0; if (mdata.m_bits != m_databits) { UINT64 unitmask = mdata.m_mask ? mdata.m_mask : entry_mask; for (int slot = start_slot; slot <= end_slot; slot++) mask |= unitmask << slot_offset[slot]; } mdata.m_mask = mask; } // Insert the entry in the map m_entrylist.insert_after(*subentry, prev); prev = subentry; } address_map_entry *to_delete = entry; entry = entry->next(); m_entrylist.remove(*to_delete); } else { prev = entry; entry = entry->next(); } } }
konami573_cassette_interface::konami573_cassette_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<konami573_cassette_slot_device *>(device.owner()); }
device_comx_expansion_card_interface::device_comx_expansion_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device), m_ds(1) { m_slot = dynamic_cast<comx_expansion_slot_device *>(device.owner()); }
device_apricot_keyboard_interface::device_apricot_keyboard_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_host = dynamic_cast<apricot_keyboard_bus_device *>(device.owner()); }
device_vip_byteio_port_interface::device_vip_byteio_port_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig,device) { m_slot = dynamic_cast<vip_byteio_port_device *>(device.owner()); }
device_electron_expansion_interface::device_electron_expansion_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { m_slot = dynamic_cast<electron_expansion_slot_device *>(device.owner()); }
finder_base::finder_base(device_t &base, const char *tag) : m_next(base.register_auto_finder(*this)) , m_base(base) , m_tag(tag) { }