Пример #1
0
static void command_trace(void)
{
#if defined(MAME_DEBUG) && defined(NEW_DEBUGGER)
	int cpunum;
	FILE *file;
	char filename[256];

	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		if (cpu_gettotalcpu() == 1)
			snprintf(filename, sizeof(filename) / sizeof(filename[0]), "_%s.tr", current_testcase.name);
		else
			snprintf(filename, sizeof(filename) / sizeof(filename[0]), "_%s.%d.tr", current_testcase.name, cpunum);

		file = fopen(filename, "w");
		if (file)
		{
			report_message(MSG_INFO, "Tracing CPU #%d: %s", cpunum, filename);
			debug_cpu_trace(cpunum, file, FALSE, NULL);
		}
	}
#else
	state = STATE_ABORTED;
	report_message(MSG_FAILURE, "Cannot trace; debugger not present");
#endif
}
Пример #2
0
int cpuint_init(void)
{
	int cpunum;
	int irqline;

	/* loop over all CPUs */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		/* reset the IRQ lines */
		for (irqline = 0; irqline < MAX_IRQ_LINES; irqline++)
		{
			irq_line_state[cpunum][irqline] = CLEAR_LINE;
			interrupt_vector[cpunum][irqline] =
			irq_line_vector[cpunum][irqline] = cpunum_default_irq_vector(cpunum);
		}
		
		/* reset the IRQ event queues */
		irq_event_index[cpunum] = 0;
	}

	/* set up some stuff to save */
	state_save_set_current_tag(0);
	state_save_register_UINT8("cpu", 0, "irq enable",     interrupt_enable,  cpu_gettotalcpu());
	state_save_register_INT32("cpu", 0, "irq vector",     &interrupt_vector[0][0],cpu_gettotalcpu() * MAX_IRQ_LINES);
	state_save_register_UINT8("cpu", 0, "irqline state",  &irq_line_state[0][0],  cpu_gettotalcpu() * MAX_IRQ_LINES);
	state_save_register_INT32("cpu", 0, "irqline vector", &irq_line_vector[0][0], cpu_gettotalcpu() * MAX_IRQ_LINES);

	return 0;
}
Пример #3
0
static void cpu_pre_run(void)
{
	int cpunum;

	logerror("Machine reset\n");

	begin_resource_tracking();

	/* read hi scores information from hiscore.dat */
	hs_open(Machine->gamedrv->name);
	hs_init();

	/* initialize the various timers (suspends all CPUs at startup) */
	cpu_inittimers();
	watchdog_counter = -1;

	/* reset sound chips */
	sound_reset();

	/* first pass over CPUs */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		/* enable all CPUs (except for audio CPUs if the sound is off) */
		if (!(Machine->drv->cpu[cpunum].cpu_flags & CPU_AUDIO_CPU) || Machine->sample_rate != 0)
			cpunum_resume(cpunum, SUSPEND_ANY_REASON);
		else
			cpunum_suspend(cpunum, SUSPEND_REASON_DISABLE, 1);

		/* reset the interrupt state */
		cpuint_reset_cpu(cpunum);

		/* reset the total number of cycles */
		cpu[cpunum].totalcycles = 0;
		cpu[cpunum].localtime = 0;
	}

	vblank = 0;

	/* do this AFTER the above so machine_init() can use cpu_halt() to hold the */
	/* execution of some CPUs, or disable interrupts */
	if (Machine->drv->machine_init)
		(*Machine->drv->machine_init)();

	/* now reset each CPU */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		cpunum_reset(cpunum, Machine->drv->cpu[cpunum].reset_param, cpu_irq_callbacks[cpunum]);

	/* reset the globals */
	cpu_vblankreset();
	current_frame = 0;
	state_save_dump_registry();
}
Пример #4
0
void gottlieb_sh_w(int offset,int data)
{
	data &= 0xff;

	if (data != 0xff)
	{
		if (Machine->gamedrv->samplenames)
		{
			/* if we have loaded samples, we must be Q*Bert */
			switch(data ^ 0xff)
			{
				case 0x12:
					/* play a sample here (until Votrax speech is emulated) */
					sample_start (0, 0, 0);
					break;

				case 0x14:
					/* play a sample here (until Votrax speech is emulated) */
					sample_start (0, 1, 0);
					break;

				case 0x16:
					/* play a sample here (until Votrax speech is emulated) */
					sample_start (0, 2, 0);
					break;

				case 0x11:
					/* play a sample here (until Votrax speech is emulated) */
					sample_start (0, 3, 0);
					break;
			}
		}

		soundlatch_w(offset,data);

		switch (cpu_gettotalcpu())
		{
		case 2:
			/* Revision 1 sound board */
			cpu_cause_interrupt(1,M6502_INT_IRQ);
			break;
		case 3:
		case 4:
			/* Revision 2 & 3 sound board */
			cpu_cause_interrupt(cpu_gettotalcpu()-1,M6502_INT_IRQ);
			cpu_cause_interrupt(cpu_gettotalcpu()-2,M6502_INT_IRQ);
			break;
		}
	}
}
Пример #5
0
void cpuint_init(running_machine *machine)
{
	int cpunum;
	int line;

	/* loop over all CPUs and input lines */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		/* reset any driver hooks into the IRQ acknowledge callbacks */
		drv_irq_callbacks[cpunum] = NULL;

		/* clear out all the CPU states */
		for (line = 0; line < MAX_INPUT_LINES; line++)
		{
			input_line_state[cpunum][line] = CLEAR_LINE;
			interrupt_vector[cpunum][line] =
			input_line_vector[cpunum][line] = cputype_default_irq_vector(Machine->drv->cpu[cpunum].type);
			input_event_index[cpunum][line] = 0;
		}
	}

	/* set up some stuff to save */
	state_save_push_tag(0);
	state_save_register_item_2d_array("cpu", 0, interrupt_vector);
	state_save_register_item_2d_array("cpu", 0, input_line_state);
	state_save_register_item_2d_array("cpu", 0, input_line_vector);
	state_save_pop_tag();
}
Пример #6
0
static void cpu_vblankcallback(int param)
{
	int cpunum;

   if (vblank_countdown == 1)
      vblank = 1;

	/* loop over CPUs */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		/* if the interrupt multiplier is valid */
		if (cpu[cpunum].vblankint_multiplier != -1)
		{
			/* decrement; if we hit zero, generate the interrupt and reset the countdown */
			if (!--cpu[cpunum].vblankint_countdown)
			{
				/* a param of -1 means don't call any callbacks */
				if (param != -1)
				{
					/* if the CPU has a VBLANK handler, call it */
					if (Machine->drv->cpu[cpunum].vblank_interrupt && cpu_getstatus(cpunum))
					{
						cpuintrf_push_context(cpunum);
						(*Machine->drv->cpu[cpunum].vblank_interrupt)();
						cpuintrf_pop_context();
					}

					/* update the counters */
					cpu[cpunum].iloops--;
				}

				/* reset the countdown and timer */
				cpu[cpunum].vblankint_countdown = cpu[cpunum].vblankint_multiplier;
				timer_adjust(cpu[cpunum].vblankint_timer, TIME_NEVER, 0, 0);
			}
		}

		/* else reset the VBLANK timer if this is going to be a real VBLANK */
		else if (vblank_countdown == 1)
			timer_adjust(cpu[cpunum].vblankint_timer, TIME_NEVER, 0, 0);
	}

	/* is it a real VBLANK? */
	if (!--vblank_countdown)
	{
		/* do we update the screen now? */
		if (!(Machine->drv->video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
			time_to_quit = updatescreen();

		/* Set the timer to update the screen */
		timer_set(TIME_IN_USEC(Machine->drv->vblank_duration), 0, cpu_updatecallback);

		/* reset the globals */
		cpu_vblankreset();

		/* reset the counter */
		vblank_countdown = vblank_multiplier;
	}
}
Пример #7
0
void cpu_exit(void)
{
	int cpunum;

	/* shut down the CPU cores */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		cpuintrf_exit_cpu(cpunum);
}
Пример #8
0
static void interrupt_reset(running_machine *machine)
{
	int cpunum;

	/* on a reset, enable all interrupts */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		interrupt_enable[cpunum] = 1;
}
Пример #9
0
void cpunum_set_input_line_vector(int cpunum, int line, int vector)
{
	if (cpunum < cpu_gettotalcpu() && line >= 0 && line < MAX_INPUT_LINES)
	{
		LOG(("cpunum_set_input_line_vector(%d,%d,$%04x)\n",cpunum,line,vector));
		interrupt_vector[cpunum][line] = vector;
		return;
	}
	LOG(("cpunum_set_input_line_vector CPU#%d line %d > max input lines\n", cpunum, line));
}
Пример #10
0
void cpu_irq_line_vector_w(int cpunum, int irqline, int vector)
{
	if (cpunum < cpu_gettotalcpu() && irqline >= 0 && irqline < MAX_IRQ_LINES)
	{
		LOG(("cpu_irq_line_vector_w(%d,%d,$%04x)\n",cpunum,irqline,vector));
		interrupt_vector[cpunum][irqline] = vector;
		return;
	}
	LOG(("cpu_irq_line_vector_w CPU#%d irqline %d > max irq lines\n", cpunum, irqline));
}
Пример #11
0
void cpu_interrupt_enable(int cpunum, int enabled)
{
	assert_always(cpunum >= 0 && cpunum < cpu_gettotalcpu(), "cpu_interrupt_enable() called for invalid cpu num!");

	/* set the new state */
	interrupt_enable[cpunum] = enabled;

	/* make sure there are no queued interrupts */
	if (enabled == 0)
		timer_call_after_resynch(NULL, cpunum, clear_all_lines);
}
Пример #12
0
int debug_comment_init(void)
{
	/* allocate enough comment groups for the total # of cpu's */
	debug_comments = (comment_group*) malloc(cpu_gettotalcpu() * sizeof(comment_group));

	/* automatically load em up */
	debug_comment_load();

	add_exit_callback(debug_comment_exit);

	return 1;
}
Пример #13
0
void cpuint_reset(void)
{
	int cpunum, line;

	/* loop over CPUs */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		for (line = 0; line < MAX_INPUT_LINES; line++)
		{
			interrupt_vector[cpunum][line] = cpunum_default_irq_vector(cpunum);
			input_event_index[cpunum][line] = 0;
		}
}
Пример #14
0
static void debug_comment_free(void)
{
	int i, j;

	for (i = 0; i < cpu_gettotalcpu(); i++)
	{
		for (j = 0; j < debug_comments[i].comment_count; j++)
		{
			free(debug_comments[i].comment_info[j]);
		}

		debug_comments[i].comment_count = 0;
	}

	free(debug_comments);
}
Пример #15
0
static void cpu_vblankreset(void)
{
	int cpunum;

	/* read hi scores from disk */
	hs_update();

	/* read keyboard & update the status of the input ports */
	update_input_ports();

	/* reset the cycle counters */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		if (!(cpu[cpunum].suspend & SUSPEND_REASON_DISABLE))
			cpu[cpunum].iloops = Machine->drv->cpu[cpunum].vblank_interrupts_per_frame - 1;
		else
			cpu[cpunum].iloops = -1;
	}
}
Пример #16
0
bool retro_serialize(void *data, size_t size)
{
   int cpunum;
	if(retro_serialize_size() && data && size)
	{
		/* write the save state */
		state_save_save_begin(data);

		/* write tag 0 */
		state_save_set_current_tag(0);
		if(state_save_save_continue())
		{
		    return false;
		}

		/* loop over CPUs */
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			cpuintrf_push_context(cpunum);

			/* make sure banking is set */
			activecpu_reset_banking();

			/* save the CPU data */
			state_save_set_current_tag(cpunum + 1);
			if(state_save_save_continue())
			    return false;

			cpuintrf_pop_context();
		}

		/* finish and close */
		state_save_save_finish();
		
		return true;
	}

	return false;
}
Пример #17
0
bool retro_unserialize(const void * data, size_t size)
{
    int cpunum;
	/* if successful, load it */
	if (retro_serialize_size() && data && size && !state_save_load_begin((void*)data, size))
	{
        /* read tag 0 */
        state_save_set_current_tag(0);
        if(state_save_load_continue())
            return false;

        /* loop over CPUs */
        for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
        {
            cpuintrf_push_context(cpunum);

            /* make sure banking is set */
            activecpu_reset_banking();

            /* load the CPU data */
            state_save_set_current_tag(cpunum + 1);
            if(state_save_load_continue())
                return false;

            cpuintrf_pop_context();
        }

        /* finish and close */
        state_save_load_finish();

        
        return true;
	}

	return false;
}
Пример #18
0
void osd_update_video_and_audio(mame_display *display)
{
	int i;
	double time_limit;
	double current_time;
	int cpunum;

	/* if the visible area has changed, update it */
	if (display->changed_flags & GAME_VISIBLE_AREA_CHANGED)
	{
		ui_set_visible_area(display->game_visible_area.min_x, display->game_visible_area.min_y,
			display->game_visible_area.max_x, display->game_visible_area.max_y);
	}

	/* is this the first update?  if so, eat it */
	if (!seen_first_update)
	{
		seen_first_update = TRUE;
		return;
	}

	/* if we have already aborted or completed, our work is done */
	if ((state == STATE_ABORTED) || (state == STATE_DONE))
		return;

	/* have we hit the time limit? */
	current_time = timer_get_time();
	time_limit = (current_testcase.time_limit != 0.0) ? current_testcase.time_limit
		: TIME_IN_SEC(600);
	if (current_time > time_limit)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Time limit of %.2f seconds exceeded", time_limit);
		return;
	}

	/* update the runtime hash */
	if (0)
	{
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			runtime_hash *= 57;
			runtime_hash ^= cpunum_get_reg(cpunum, REG_PC);	/* TODO - Add more registers? */
		}
	}

	for (i = 0; i < sizeof(commands) / sizeof(commands[i]); i++)
	{
		if (current_command->command_type == commands[i].command_type)
		{
			commands[i].proc();
			break;
		}
	}

	/* if we are ready for the next command, advance to it */
	if (state == STATE_READY)
	{
		/* if we are at the end, and we are dumping screenshots, and we didn't
		 * just dump a screenshot, dump one now
		 */
		if ((test_flags & MESSTEST_ALWAYS_DUMP_SCREENSHOT) &&
			(current_command[0].command_type != MESSTEST_COMMAND_SCREENSHOT) &&
			(current_command[1].command_type == MESSTEST_COMMAND_END))
		{
			dump_screenshot(TRUE);
		}

		current_command++;
	}
}
Пример #19
0
/* callback for the timer */
static void nmi_callback(int param)
{
	cpu_cause_interrupt(cpu_gettotalcpu()-1, M6502_INT_NMI);
}
Пример #20
0
int debug_comment_save(void)
{
	int i, j;
	char crc_buf[20];
	xml_data_node *root = xml_file_create();
	xml_data_node *commentnode, *systemnode;
	int total_comments = 0;

	/* if we don't have a root, bail */
	if (!root)
		return 0;

	/* create a comment node */
	commentnode = xml_add_child(root, "mamecommentfile", NULL);
	if (!commentnode)
		goto error;
	xml_set_attribute_int(commentnode, "version", COMMENT_VERSION);

	/* create a system node */
	systemnode = xml_add_child(commentnode, "system", NULL);
	if (!systemnode)
		goto error;
	xml_set_attribute(systemnode, "name", Machine->gamedrv->name);

	/* for each cpu */
	for (i = 0; i < cpu_gettotalcpu(); i++)
	{
		xml_data_node *curnode = xml_add_child(systemnode, "cpu", NULL);
		if (!curnode)
			goto error;
		xml_set_attribute_int(curnode, "num", i);

		for (j = 0; j < debug_comments[i].comment_count; j++)
		{
			xml_data_node *datanode = xml_add_child(curnode, "comment", debug_comments[i].comment_info[j]->text);
			if (!datanode)
				goto error;
			xml_set_attribute_int(datanode, "address", debug_comments[i].comment_info[j]->address);
			xml_set_attribute_int(datanode, "color", debug_comments[i].comment_info[j]->color);
			sprintf(crc_buf, "%08X", debug_comments[i].comment_info[j]->crc);
			xml_set_attribute(datanode, "crc", crc_buf);
			total_comments++;
		}
	}

	/* flush the file */
	if (total_comments > 0)
	{
 		mame_file *fp = mame_fopen(Machine->gamedrv->name, 0, FILETYPE_COMMENT, 1);
 		xml_file_write(root, fp);
		mame_fclose(fp);
	}

	/* free and get out of here */
	xml_file_free(root);
	return 1;

error:
	xml_file_free(root);
	return 0;
}
Пример #21
0
static void cpu_inittimers(void)
{
	double first_time;
	int cpunum, max, ipf;

	/* allocate a dummy timer at the minimum frequency to break things up */
	ipf = Machine->drv->cpu_slices_per_frame;
	if (ipf <= 0)
		ipf = 1;
	timeslice_period = TIME_IN_HZ(Machine->drv->frames_per_second * ipf);
	timeslice_timer = timer_alloc(cpu_timeslicecallback);
	timer_adjust(timeslice_timer, timeslice_period, 0, timeslice_period);
	
	/* allocate timers to handle interleave boosts */
	interleave_boost_timer = timer_alloc(NULL);
	interleave_boost_timer_end = timer_alloc(end_interleave_boost);

	/*
	 *	The following code finds all the CPUs that are interrupting in sync with the VBLANK
	 *	and sets up the VBLANK timer to run at the minimum number of cycles per frame in
	 *	order to service all the synced interrupts
	 */

	/* find the CPU with the maximum interrupts per frame */
	max = 1;
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		ipf = Machine->drv->cpu[cpunum].vblank_interrupts_per_frame;
		if (ipf > max)
			max = ipf;
	}

	/* now find the LCD with the rest of the CPUs (brute force - these numbers aren't huge) */
	vblank_multiplier = max;
	while (1)
	{
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			ipf = Machine->drv->cpu[cpunum].vblank_interrupts_per_frame;
			if (ipf > 0 && (vblank_multiplier % ipf) != 0)
				break;
		}
		if (cpunum == cpu_gettotalcpu())
			break;
		vblank_multiplier += max;
	}

	/* initialize the countdown timers and intervals */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		ipf = Machine->drv->cpu[cpunum].vblank_interrupts_per_frame;
		if (ipf > 0)
			cpu[cpunum].vblankint_countdown = cpu[cpunum].vblankint_multiplier = vblank_multiplier / ipf;
		else
			cpu[cpunum].vblankint_countdown = cpu[cpunum].vblankint_multiplier = -1;
	}

	/* allocate a vblank timer at the frame rate * the LCD number of interrupts per frame */
	vblank_period = TIME_IN_HZ(Machine->drv->frames_per_second * vblank_multiplier);
	vblank_timer = timer_alloc(cpu_vblankcallback);
	vblank_countdown = vblank_multiplier;

	/*
	 *		The following code creates individual timers for each CPU whose interrupts are not
	 *		synced to the VBLANK, and computes the typical number of cycles per interrupt
	 */

	/* start the CPU interrupt timers */
	for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
	{
		ipf = Machine->drv->cpu[cpunum].vblank_interrupts_per_frame;

		/* compute the average number of cycles per interrupt */
		if (ipf <= 0)
			ipf = 1;
		cpu[cpunum].vblankint_period = TIME_IN_HZ(Machine->drv->frames_per_second * ipf);
		cpu[cpunum].vblankint_timer = timer_alloc(NULL);

		/* see if we need to allocate a CPU timer */
		ipf = Machine->drv->cpu[cpunum].timed_interrupts_per_second;
		if (ipf)
		{
			cpu[cpunum].timedint_period = cpu_computerate(ipf);
			cpu[cpunum].timedint_timer = timer_alloc(cpu_timedintcallback);
			timer_adjust(cpu[cpunum].timedint_timer, cpu[cpunum].timedint_period, cpunum, cpu[cpunum].timedint_period);
		}
	}

	/* note that since we start the first frame on the refresh, we can't pulse starting
	   immediately; instead, we back up one VBLANK period, and inch forward until we hit
	   positive time. That time will be the time of the first VBLANK timer callback */
	first_time = -TIME_IN_USEC(Machine->drv->vblank_duration) + vblank_period;
	while (first_time < 0)
	{
		cpu_vblankcallback(-1);
		first_time += vblank_period;
	}
	timer_set(first_time, 0, cpu_firstvblankcallback);
}
Пример #22
0
static void handle_load(running_machine *machine)
{
	mame_private *mame = machine->mame_data;
	mame_file_error filerr;
	mame_file *file;

	/* if no name, bail */
	if (mame->saveload_pending_file == NULL)
	{
		mame->saveload_schedule_callback = NULL;
		return;
	}

	/* if there are anonymous timers, we can't load just yet because the timers might */
	/* overwrite data we have loaded */
	if (timer_count_anonymous() > 0)
	{
		/* if more than a second has passed, we're probably screwed */
		if (sub_mame_times(mame_timer_get_time(), mame->saveload_schedule_time).seconds > 0)
		{
			popmessage("Unable to load due to pending anonymous timers. See error.log for details.");
			goto cancel;
		}
		return;
	}

	/* open the file */
	filerr = mame_fopen(SEARCHPATH_STATE, mame->saveload_pending_file, OPEN_FLAG_READ, &file);
	if (filerr == FILERR_NONE)
	{
		/* start loading */
		if (state_save_load_begin(file) == 0)
		{
			int cpunum;

			/* read tag 0 */
			state_save_push_tag(0);
			state_save_load_continue();
			state_save_pop_tag();

			/* loop over CPUs */
			for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
			{
				cpuintrf_push_context(cpunum);

				/* make sure banking is set */
				activecpu_reset_banking();

				/* load the CPU data */
				state_save_push_tag(cpunum + 1);
				state_save_load_continue();
				state_save_pop_tag();

				/* make sure banking is set */
				activecpu_reset_banking();

				cpuintrf_pop_context();
			}

			/* finish and close */
			state_save_load_finish();
			popmessage("State successfully loaded.");
		}
		else
			popmessage("Error: Failed to load state");
		mame_fclose(file);
	}
	else
		popmessage("Error: Failed to load state");

cancel:
	/* unschedule the load */
	free(mame->saveload_pending_file);
	mame->saveload_pending_file = NULL;
	mame->saveload_schedule_callback = NULL;
}
Пример #23
0
static void handle_save(running_machine *machine)
{
	mame_private *mame = machine->mame_data;
	mame_file_error filerr;
	mame_file *file;

	/* if no name, bail */
	if (mame->saveload_pending_file == NULL)
	{
		mame->saveload_schedule_callback = NULL;
		return;
	}

	/* if there are anonymous timers, we can't save just yet */
	if (timer_count_anonymous() > 0)
	{
		/* if more than a second has passed, we're probably screwed */
		if (sub_mame_times(mame_timer_get_time(), mame->saveload_schedule_time).seconds > 0)
		{
			popmessage("Unable to save due to pending anonymous timers. See error.log for details.");
			goto cancel;
		}
		return;
	}

	/* open the file */
	filerr = mame_fopen(SEARCHPATH_STATE, mame->saveload_pending_file, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &file);
	if (filerr == FILERR_NONE)
	{
		int cpunum;

		/* write the save state */
		if (state_save_save_begin(file) != 0)
		{
			popmessage("Error: Unable to save state due to illegal registrations. See error.log for details.");
			mame_fclose(file);
			goto cancel;
		}

		/* write the default tag */
		state_save_push_tag(0);
		state_save_save_continue();
		state_save_pop_tag();

		/* loop over CPUs */
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			cpuintrf_push_context(cpunum);

			/* make sure banking is set */
			activecpu_reset_banking();

			/* save the CPU data */
			state_save_push_tag(cpunum + 1);
			state_save_save_continue();
			state_save_pop_tag();

			cpuintrf_pop_context();
		}

		/* finish and close */
		state_save_save_finish();
		mame_fclose(file);

		/* pop a warning if the game doesn't support saves */
		if (!(machine->gamedrv->flags & GAME_SUPPORTS_SAVE))
			popmessage("State successfully saved.\nWarning: Save states are not officially supported for this game.");
		else
			popmessage("State successfully saved.");
	}
	else
		popmessage("Error: Failed to save state");

cancel:
	/* unschedule the save */
	free(mame->saveload_pending_file);
	mame->saveload_pending_file = NULL;
	mame->saveload_schedule_callback = NULL;
}
Пример #24
0
int osd_update(mame_time emutime)
{
	int i;
	double time_limit;
	double current_time;
	int cpunum;

	render_target_get_primitives(target);

	/* is this the first update?  if so, eat it */
	if (!seen_first_update)
	{
		seen_first_update = TRUE;
		goto done;
	}

	/* if we have already aborted or completed, our work is done */
	if ((state == STATE_ABORTED) || (state == STATE_DONE))
	{
		mame_schedule_exit(Machine);
		goto done;
	}

	/* have we hit the time limit? */
	current_time = timer_get_time();
	time_limit = (current_testcase.time_limit != 0.0) ? current_testcase.time_limit
		: TIME_IN_SEC(600);
	if (current_time > time_limit)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Time limit of %.2f seconds exceeded", time_limit);
		goto done;
	}

	/* update the runtime hash */
	if (0)
	{
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			runtime_hash *= 57;
			runtime_hash ^= cpunum_get_reg(cpunum, REG_PC);	/* TODO - Add more registers? */
		}
	}

	for (i = 0; i < sizeof(commands) / sizeof(commands[i]); i++)
	{
		if (current_command->command_type == commands[i].command_type)
		{
			commands[i].proc();
			break;
		}
	}

	/* if we are ready for the next command, advance to it */
	if (state == STATE_READY)
	{
		/* if we are at the end, and we are dumping screenshots, and we didn't
		 * just dump a screenshot, dump one now
		 */
		if ((test_flags & MESSTEST_ALWAYS_DUMP_SCREENSHOT) &&
			(current_command[0].command_type != MESSTEST_COMMAND_SCREENSHOT) &&
			(current_command[1].command_type == MESSTEST_COMMAND_END))
		{
			dump_screenshot(TRUE);
		}

		current_command++;
	}

done:
	return FALSE;
}
Пример #25
0
static WRITE8_HANDLER( mcu_reset_w )
{
	/* the bootlegs don't have a MCU, so make sure it's there before trying to reset it */
	if (cpu_gettotalcpu() >= 4)
		cpunum_set_input_line(3, INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE);
}