Пример #1
0
void timer_device::device_reset()
{
	// type based configuration
	switch (m_config.m_type)
	{
		case timer_device_config::TIMER_TYPE_GENERIC:
		case timer_device_config::TIMER_TYPE_PERIODIC:
		{
			// convert the period into attotime
			attotime period = attotime_never;
			if (m_config.m_period > 0)
			{
				period = UINT64_ATTOTIME_TO_ATTOTIME(m_config.m_period);

				// convert the start_delay into attotime
				attotime start_delay = attotime_zero;
				if (m_config.m_start_delay > 0)
					start_delay = UINT64_ATTOTIME_TO_ATTOTIME(m_config.m_start_delay);

				// allocate and start the backing timer
				timer_adjust_periodic(m_timer, start_delay, m_config.m_param, period);
			}
			break;
		}

		case timer_device_config::TIMER_TYPE_SCANLINE:
			if (m_screen == NULL)
				fatalerror("timer '%s': unable to find screen '%s'\n", tag(), m_config.m_screen);

			// set the timer to to fire immediately
			m_first_time = true;
			timer_adjust_oneshot(m_timer, attotime_zero, m_config.m_param);
			break;
	}
}
Пример #2
0
static DEVICE_START( timer )
{
	timer_state *state = get_safe_token(device);
	char unique_tag[50];
	timer_config *config;
	void *param;

	/* validate some basic stuff */
	assert(device != NULL);
	assert(device->static_config == NULL);
	assert(device->inline_config != NULL);
	assert(device->machine != NULL);
	assert(device->machine->config != NULL);

	/* get and validate the configuration */
	config = device->inline_config;
	assert((config->type == TIMER_TYPE_PERIODIC) || (config->type == TIMER_TYPE_SCANLINE));
	assert(config->callback != NULL);

	/* copy the pointer parameter */
	state->ptr = config->ptr;

	/* create the name for save states */
	assert(strlen(device->tag) < 30);
	state_save_combine_module_and_tag(unique_tag, "timer_device", device->tag);

	/* type based configuration */
	switch (config->type)
	{
		case TIMER_TYPE_PERIODIC:
			/* make sure that only the applicable parameters are filled in */
			assert(config->screen == NULL);
			assert(config->first_vpos == 0);
			assert(config->increment == 0);

			/* validate that we have at least a start_delay or period */
			assert(config->period > 0);

			/* copy the optional integer parameter */
			state->param = config->param;

			/* convert the start_delay and period into attotime */
			state->period = UINT64_ATTOTIME_TO_ATTOTIME(config->period);

			if (config->start_delay > 0)
				state->start_delay = UINT64_ATTOTIME_TO_ATTOTIME(config->start_delay);
			else
				state->start_delay = attotime_zero;

			/* register for state saves */
			state_save_register_item(unique_tag, 0, state->start_delay.seconds);
			state_save_register_item(unique_tag, 0, state->start_delay.attoseconds);
			state_save_register_item(unique_tag, 0, state->period.seconds);
			state_save_register_item(unique_tag, 0, state->period.attoseconds);
			state_save_register_item(unique_tag, 0, state->param);

			/* allocate the backing timer */
			param = (void *)device;
			state->timer = timer_alloc(periodic_timer_device_timer_callback, param);

			/* finally, start the timer */
			timer_adjust_periodic(state->timer, state->start_delay, 0, state->period);
			break;

		case TIMER_TYPE_SCANLINE:
			/* make sure that only the applicable parameters are filled in */
			assert(config->start_delay == 0);
			assert(config->period == 0);
			assert(config->param == 0);

			assert(config->first_vpos >= 0);
			assert(config->increment >= 0);

			/* allocate the backing timer */
			param = (void *)device;
			state->timer = timer_alloc(scanline_timer_device_timer_callback, param);

			/* indicate that this will be the first call */
			state->first_time = TRUE;

			/* register for state saves */
			state_save_register_item(unique_tag, 0, state->first_time);

			/* fire it as soon as the emulation starts */
			timer_adjust_oneshot(state->timer, attotime_zero, 0);
			break;

		default:
			/* we will never get here */
			fatalerror("Unknown timer device type");
			break;
	}
}
Пример #3
0
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);
}
Пример #4
0
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--;
}