bool device_config_memory_interface::interface_process_token(UINT32 entrytype, const machine_config_token *&tokens) { UINT32 data32; switch (entrytype) { // specify device address map case MCONFIG_TOKEN_DIMEMORY_MAP: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, data32, 8); assert(data32 < ARRAY_LENGTH(m_address_map)); m_address_map[data32] = TOKEN_GET_PTR(tokens, addrmap); return true; } return false; }
static void machine_config_detokenize(machine_config *config, const machine_config_token *tokens, const device_config *owner, int depth) { UINT32 entrytype = MCONFIG_TOKEN_INVALID; astring *tempstring = astring_alloc(); device_config *device = NULL; /* loop over tokens until we hit the end */ while (entrytype != MCONFIG_TOKEN_END) { device_custom_config_func custom; int size, offset, bits; UINT32 data32, clock; device_type devtype; const char *tag; UINT64 data64; /* unpack the token from the first entry */ TOKEN_GET_UINT32_UNPACK1(tokens, entrytype, 8); switch (entrytype) { /* end */ case MCONFIG_TOKEN_END: break; /* including */ case MCONFIG_TOKEN_INCLUDE: machine_config_detokenize(config, TOKEN_GET_PTR(tokens, tokenptr), owner, depth + 1); break; /* device management */ case MCONFIG_TOKEN_DEVICE_ADD: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, clock, 32); devtype = TOKEN_GET_PTR(tokens, devtype); tag = TOKEN_GET_STRING(tokens); device = device_list_add(&config->devicelist, owner, devtype, device_build_tag(tempstring, owner, tag), clock); break; case MCONFIG_TOKEN_DEVICE_REMOVE: tag = TOKEN_GET_STRING(tokens); remove_device(&config->devicelist, device_build_tag(tempstring, owner, tag)); device = NULL; break; case MCONFIG_TOKEN_DEVICE_MODIFY: tag = TOKEN_GET_STRING(tokens); device = (device_config *)device_list_find_by_tag(config->devicelist, device_build_tag(tempstring, owner, tag)); if (device == NULL) fatalerror("Unable to find device: tag=%s\n", astring_c(tempstring)); break; case MCONFIG_TOKEN_DEVICE_CLOCK: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, device->clock, 32); break; case MCONFIG_TOKEN_DEVICE_MAP: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, data32, 8); device->address_map[data32] = TOKEN_GET_PTR(tokens, addrmap); break; case MCONFIG_TOKEN_DEVICE_CONFIG: assert(device != NULL); device->static_config = TOKEN_GET_PTR(tokens, voidptr); break; case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_2: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_3: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_4: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_5: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_6: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_7: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_8: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_9: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE: assert(device != NULL); custom = (device_custom_config_func)devtype_get_info_fct(device->type, DEVINFO_FCT_CUSTOM_CONFIG); assert(custom != NULL); tokens = (*custom)(device, entrytype, tokens); break; case MCONFIG_TOKEN_DEVICE_CONFIG_DATA32: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 4, offset, 12); data32 = TOKEN_GET_UINT32(tokens); switch (size) { case 1: *(UINT8 *) ((UINT8 *)device->inline_config + offset) = data32; break; case 2: *(UINT16 *)((UINT8 *)device->inline_config + offset) = data32; break; case 4: *(UINT32 *)((UINT8 *)device->inline_config + offset) = data32; break; } break; case MCONFIG_TOKEN_DEVICE_CONFIG_DATA64: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 4, offset, 12); TOKEN_EXTRACT_UINT64(tokens, data64); switch (size) { case 1: *(UINT8 *) ((UINT8 *)device->inline_config + offset) = data64; break; case 2: *(UINT16 *)((UINT8 *)device->inline_config + offset) = data64; break; case 4: *(UINT32 *)((UINT8 *)device->inline_config + offset) = data64; break; case 8: *(UINT64 *)((UINT8 *)device->inline_config + offset) = data64; break; } break; case MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, size, 4, bits, 6, offset, 12); data32 = TOKEN_GET_UINT32(tokens); switch (size) { case 4: *(float *)((UINT8 *)device->inline_config + offset) = (float)(INT32)data32 / (float)(1 << bits); break; case 8: *(double *)((UINT8 *)device->inline_config + offset) = (double)(INT32)data32 / (double)(1 << bits); break; } break; /* core parameters */ case MCONFIG_TOKEN_DRIVER_DATA: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, config->driver_data_size, 24); break; case MCONFIG_TOKEN_QUANTUM_TIME: TOKEN_EXTRACT_UINT64(tokens, data64); config->minimum_quantum = UINT64_ATTOTIME_TO_ATTOTIME(data64); break; case MCONFIG_TOKEN_QUANTUM_PERFECT_CPU: config->perfect_cpu_quantum = TOKEN_GET_STRING(tokens); break; case MCONFIG_TOKEN_WATCHDOG_VBLANK: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, config->watchdog_vblank_count, 24); break; case MCONFIG_TOKEN_WATCHDOG_TIME: TOKEN_EXTRACT_UINT64(tokens, data64); config->watchdog_time = UINT64_ATTOTIME_TO_ATTOTIME(data64); break; /* core functions */ case MCONFIG_TOKEN_MACHINE_START: config->machine_start = TOKEN_GET_PTR(tokens, machine_start); break; case MCONFIG_TOKEN_MACHINE_RESET: config->machine_reset = TOKEN_GET_PTR(tokens, machine_reset); break; case MCONFIG_TOKEN_NVRAM_HANDLER: config->nvram_handler = TOKEN_GET_PTR(tokens, nvram_handler); break; case MCONFIG_TOKEN_MEMCARD_HANDLER: config->memcard_handler = TOKEN_GET_PTR(tokens, memcard_handler); break; /* core video parameters */ case MCONFIG_TOKEN_VIDEO_ATTRIBUTES: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, config->video_attributes, 24); break; case MCONFIG_TOKEN_GFXDECODE: config->gfxdecodeinfo = TOKEN_GET_PTR(tokens, gfxdecode); break; case MCONFIG_TOKEN_PALETTE_LENGTH: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, config->total_colors, 24); break; case MCONFIG_TOKEN_DEFAULT_LAYOUT: config->default_layout = TOKEN_GET_STRING(tokens); break; /* core video functions */ case MCONFIG_TOKEN_PALETTE_INIT: config->init_palette = TOKEN_GET_PTR(tokens, palette_init); break; case MCONFIG_TOKEN_VIDEO_START: config->video_start = TOKEN_GET_PTR(tokens, video_start); break; case MCONFIG_TOKEN_VIDEO_RESET: config->video_reset = TOKEN_GET_PTR(tokens, video_reset); break; case MCONFIG_TOKEN_VIDEO_EOF: config->video_eof = TOKEN_GET_PTR(tokens, video_eof); break; case MCONFIG_TOKEN_VIDEO_UPDATE: config->video_update = TOKEN_GET_PTR(tokens, video_update); break; /* core sound functions */ case MCONFIG_TOKEN_SOUND_START: config->sound_start = TOKEN_GET_PTR(tokens, sound_start); break; case MCONFIG_TOKEN_SOUND_RESET: config->sound_reset = TOKEN_GET_PTR(tokens, sound_reset); break; default: fatalerror("Invalid token %d in machine config\n", entrytype); break; } } /* if we are the outermost level, process any device-specific machine configurations */ if (depth == 0) for (device = config->devicelist; device != NULL; device = device->next) { tokens = (const machine_config_token *)device_get_info_ptr(device, DEVINFO_PTR_MACHINE_CONFIG); if (tokens != NULL) machine_config_detokenize(config, tokens, device, depth + 1); } astring_free(tempstring); }
void machine_config::detokenize(const machine_config_token *tokens, const device_config *owner) { device_config *device = NULL; astring tempstring; // increase the parse level m_parse_level++; // loop over tokens until we hit the end UINT32 entrytype = MCONFIG_TOKEN_INVALID; while (entrytype != MCONFIG_TOKEN_END) { device_type devtype; const char *tag; UINT64 data64; UINT32 clock; // unpack the token from the first entry TOKEN_GET_UINT32_UNPACK1(tokens, entrytype, 8); switch (entrytype) { // end case MCONFIG_TOKEN_END: break; // including case MCONFIG_TOKEN_INCLUDE: detokenize(TOKEN_GET_PTR(tokens, tokenptr), owner); break; // device management case MCONFIG_TOKEN_DEVICE_ADD: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, clock, 32); devtype = TOKEN_GET_PTR(tokens, devtype); tag = owner->subtag(tempstring, TOKEN_GET_STRING(tokens)); device = m_devicelist.append(tag, (*devtype)(*this, tag, owner, clock)); break; case MCONFIG_TOKEN_DEVICE_REPLACE: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, clock, 32); devtype = TOKEN_GET_PTR(tokens, devtype); tag = owner->subtag(tempstring, TOKEN_GET_STRING(tokens)); device = m_devicelist.replace(tag, (*devtype)(*this, tag, owner, clock)); break; case MCONFIG_TOKEN_DEVICE_REMOVE: tag = TOKEN_GET_STRING(tokens); m_devicelist.remove(owner->subtag(tempstring, tag)); device = NULL; break; case MCONFIG_TOKEN_DEVICE_MODIFY: tag = TOKEN_GET_STRING(tokens); device = m_devicelist.find(owner->subtag(tempstring, tag)); if (device == NULL) fatalerror("Unable to find device: tag=%s\n", tempstring.cstr()); break; case MCONFIG_TOKEN_DEVICE_CLOCK: case MCONFIG_TOKEN_DEVICE_CONFIG: case MCONFIG_TOKEN_DEVICE_INLINE_DATA16: case MCONFIG_TOKEN_DEVICE_INLINE_DATA32: case MCONFIG_TOKEN_DEVICE_INLINE_DATA64: case MCONFIG_TOKEN_DIEXEC_DISABLE: case MCONFIG_TOKEN_DIEXEC_VBLANK_INT: case MCONFIG_TOKEN_DIEXEC_PERIODIC_INT: case MCONFIG_TOKEN_DIMEMORY_MAP: case MCONFIG_TOKEN_DISOUND_ROUTE: case MCONFIG_TOKEN_DISOUND_RESET: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_2: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_3: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_4: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_5: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_6: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_7: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_8: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_9: case MCONFIG_TOKEN_DEVICE_CONFIG_DATA32: case MCONFIG_TOKEN_DEVICE_CONFIG_DATA64: case MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32: case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE: assert(device != NULL); device->process_token(entrytype, tokens); break; // core parameters case MCONFIG_TOKEN_DRIVER_DATA: m_driver_data_alloc = TOKEN_GET_PTR(tokens, driver_data_alloc); break; case MCONFIG_TOKEN_QUANTUM_TIME: TOKEN_EXTRACT_UINT64(tokens, data64); m_minimum_quantum = UINT64_ATTOTIME_TO_ATTOTIME(data64); break; case MCONFIG_TOKEN_QUANTUM_PERFECT_CPU: m_perfect_cpu_quantum = TOKEN_GET_STRING(tokens); break; case MCONFIG_TOKEN_WATCHDOG_VBLANK: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, m_watchdog_vblank_count, 24); break; case MCONFIG_TOKEN_WATCHDOG_TIME: TOKEN_EXTRACT_UINT64(tokens, data64); m_watchdog_time = UINT64_ATTOTIME_TO_ATTOTIME(data64); break; // core functions case MCONFIG_TOKEN_MACHINE_START: m_machine_start = TOKEN_GET_PTR(tokens, machine_start); break; case MCONFIG_TOKEN_MACHINE_RESET: m_machine_reset = TOKEN_GET_PTR(tokens, machine_reset); break; case MCONFIG_TOKEN_NVRAM_HANDLER: m_nvram_handler = TOKEN_GET_PTR(tokens, nvram_handler); break; case MCONFIG_TOKEN_MEMCARD_HANDLER: m_memcard_handler = TOKEN_GET_PTR(tokens, memcard_handler); break; // core video parameters case MCONFIG_TOKEN_VIDEO_ATTRIBUTES: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, m_video_attributes, 24); break; case MCONFIG_TOKEN_GFXDECODE: m_gfxdecodeinfo = TOKEN_GET_PTR(tokens, gfxdecode); break; case MCONFIG_TOKEN_PALETTE_LENGTH: TOKEN_UNGET_UINT32(tokens); TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, m_total_colors, 24); break; case MCONFIG_TOKEN_DEFAULT_LAYOUT: m_default_layout = TOKEN_GET_STRING(tokens); break; // core video functions case MCONFIG_TOKEN_PALETTE_INIT: m_init_palette = TOKEN_GET_PTR(tokens, palette_init); break; case MCONFIG_TOKEN_VIDEO_START: m_video_start = TOKEN_GET_PTR(tokens, video_start); break; case MCONFIG_TOKEN_VIDEO_RESET: m_video_reset = TOKEN_GET_PTR(tokens, video_reset); break; case MCONFIG_TOKEN_VIDEO_EOF: m_video_eof = TOKEN_GET_PTR(tokens, video_eof); break; case MCONFIG_TOKEN_VIDEO_UPDATE: m_video_update = TOKEN_GET_PTR(tokens, video_update); break; // core sound functions case MCONFIG_TOKEN_SOUND_START: m_sound_start = TOKEN_GET_PTR(tokens, sound_start); break; case MCONFIG_TOKEN_SOUND_RESET: m_sound_reset = TOKEN_GET_PTR(tokens, sound_reset); break; default: fatalerror("Invalid token %d in machine config\n", entrytype); break; } } // if we started at parse level 0 (and are thus at level 1), do post-processing if (m_parse_level == 1) { // process any device-specific machine configurations for (const device_config *devconfig = m_devicelist.first(); devconfig != NULL; devconfig = devconfig->next()) if (!devconfig->m_config_complete) { tokens = devconfig->machine_config_tokens(); if (tokens != NULL) detokenize(tokens, devconfig); } // then notify all devices that their configuration is complete for (device_config *devconfig = m_devicelist.first(); devconfig != NULL; devconfig = devconfig->next()) if (!devconfig->m_config_complete) { devconfig->config_complete(); devconfig->m_config_complete = true; } } // bump down the parse level m_parse_level--; }