コード例 #1
0
ファイル: deff.c プロジェクト: Mole23/freewpc
/**
 * Scan the display effect table to see if any pending requests
 * can now be satisfied.
 *
 * This is called anytime the running display effect exits or is
 * stopped.
 */
void deff_queue_service (void)
{
	/* Find the highest priority effect in the queue.
	If there is such, start it if its priority exceeds that
	of the currently display effect. */
	struct deff_queue_entry *dq = deff_queue_find_priority ();
	if (dq)
	{
		const deff_t *deff = &deff_table[dq->id];
		if (deff_prio < deff->prio)
		{
			dbprintf ("deff_queue_service starting %d\n", dq->id);
			deff_running = dq->id;
			dq->id = dq->timeout = 0;
			deff_start_task (deff);
			return;
		}
	}

	/* Delay updating background effect briefly, to allow
	synchronous callers to do something else */
	if (task_getgid () == GID_DEFF_EXITING)
	{
		dbprintf ("deff_update delayed on exit\n");
		task_sleep (TIME_133MS);
	}

	/* No queued effect can run now, so try a background update */
	deff_update ();
}
コード例 #2
0
ファイル: device.c プロジェクト: Dmilo/freewpc
/** Request that a device eject 1 ball */
void device_request_kick (device_t *dev)
{
	task_gid_t gid = DEVICE_GID (device_devno (dev));
	task_kill_gid (gid);
	if (device_kickable_count (dev) > 0)
	{
		dev->kicks_needed++;
		dev->kick_errors = 0;
		/* TODO - this logic probably belongs somewhere else.
		We're increment live balls very early here, before the
		balls are actually added to play. */
		if (!trough_dev_p (dev))
			live_balls++;
	}
	else if (switch_stress_enable && trough_dev_p (dev))
	{
		missing_balls++;
		device_add_live ();
	}
	else
	{
		dbprintf ("Kick request invalid\n");
	}
	if (gid != task_getgid ())
		task_recreate_gid_while (gid, device_update, TASK_DURATION_INF);
}
コード例 #3
0
ファイル: leff.c プロジェクト: Dmilo/freewpc
const leff_t *leff_get_current (void)
{
	task_gid_t gid;
	U8 idx;
	U8 id;

	gid = task_getgid ();
	idx = gid - GID_LEFF_BASE;
	id = leff_running_list[idx];
	return &leff_table[id];
}
コード例 #4
0
ファイル: error.c プロジェクト: CardonaPinball/freewpc
/**
 * Entry point for errors that are recoverable.
 * error_code is one of the values in include/system/errno.h.
 * This function simply logs the error, but the system continues on.
 */
void nonfatal (errcode_t error_code)
{
	audit_increment (&system_audits.non_fatal_errors);
#ifdef DEBUGGER
	last_nonfatal_error_code = error_code;
	last_nonfatal_error_gid = task_getgid ();
	if (!in_test)
		deff_start (DEFF_NONFATAL_ERROR);
	dbprintf ("Nonfatal error %d\n", error_code);
#endif
	log_event (SEV_ERROR, MOD_SYSTEM, EV_SYSTEM_NONFATAL, error_code);
}
コード例 #5
0
ファイル: deff.c プロジェクト: Mole23/freewpc
/** Lower the priority of the currently running display effect.
This may cause it to be preempted by something more important. */
void deff_nice (enum _priority prio)
{
	/* Verify that this is called from the running effect */
	if (task_getgid () != GID_DEFF)
		return;

	/* Change the current priority */
	deff_prio = prio;

	/* Force an update: this task may not be the best anymore */
	deff_queue_service ();
}
コード例 #6
0
ファイル: device.c プロジェクト: Dmilo/freewpc
/** Gets the current task's GID and makes sure (optionally) that it is
 * in the range of valid GIDs for devices. */
static inline U8 device_getgid (void)
{
	U8 gid = task_getgid ();
#ifdef PARANOID
	if ((gid < DEVICE_GID_BASE) || (gid >= DEVICE_GID_BASE + NUM_DEVICES))
	{
		dbprintf ("Bad GID %02X for device\n", gid);
		abort ();
	}
#endif
	return gid;
}
コード例 #7
0
ファイル: leffs.c プロジェクト: SonnyJim/freewpc
void clock_target_leff (void)
{
	U8 i;

	leff_create_peer (gi_cycle_leff);
	for (i = 0; i < 12; i++)
	{
		flasher_pulse (FLASH_CLOCK_TARGET);
		task_sleep (TIME_100MS);
	}
	task_kill_gid (task_getgid ());
	leff_exit ();
}
コード例 #8
0
ファイル: leff.c プロジェクト: Dmilo/freewpc
/**
 * Exit from a running lamp effect.
 */
void leff_exit (void)
{
	task_gid_t gid;
	U8 idx;
	U8 id;

	/* Find the GID (cannot be GID_NULL) */
	gid = task_getgid ();

	/* Free up the resources */
	idx = gid - GID_LEFF_BASE;
	id = leff_running_list[idx];
	leff_close (&leff_table[id], idx);
#ifdef DEBUG_LEFFS
	leff_dump ();
#endif

	/* Exit from the task */
	task_exit ();
}
コード例 #9
0
ファイル: device.c プロジェクト: Dmilo/freewpc
/** Request that a device ejects all balls */
void device_request_empty (device_t *dev)
{
	U8 can_kick;

	task_gid_t gid = DEVICE_GID (device_devno (dev));
	task_kill_gid (gid);

	/* See how many balls are in the device, and schedule that many kicks. */
	can_kick = device_kickable_count (dev);
	dev->kicks_needed += can_kick;
	dev->kick_errors = 0;

	/* TODO - this logic probably belongs somewhere else */
	if (!trough_dev_p (dev))
		live_balls += can_kick;

	/* Reset count of locked balls */
	dev->max_count = dev->props->init_max_count;
	if (gid != task_getgid ())
		task_recreate_gid_while (gid, device_update, TASK_DURATION_INF);
}
コード例 #10
0
ファイル: db.c プロジェクト: Curbfeeler/freewpc
void bpt_display (void)
{
#if (MACHINE_DMD == 1)
	dmd_alloc_low_clean ();

	sprintf ("%p", bpt_mem_addr);
	font_render_string_left (&font_bitmap8, 0, 0, sprintf_buffer);

	sprintf ("%02X %02X %02X %02X",
		bpt_mem_addr[0], bpt_mem_addr[1], bpt_mem_addr[2], bpt_mem_addr[3]);
	font_render_string_left (&font_bitmap8, 40, 0, sprintf_buffer);

	if (new_fatal_error)
	{
		sprintf ("ERR %d GID %d",
			(U8)system_audits.lockup1_addr, (U8)system_audits.lockup1_pid_lef);
		font_render_string_left (&font_bitmap8, 0, 8, sprintf_buffer);
	}
	else if (task_getpid ())
	{

		sprintf ("PID %p GID %d", task_getpid (), task_getgid ());
		font_render_string_left (&font_bitmap8, 0, 8, sprintf_buffer);
		sprintf ("%02X%02X %02X", bpt_addr[0], bpt_addr[1]-2, bpt_addr[2]);
		font_render_string_left (&font_bitmap8, 0, 16, sprintf_buffer);
	}
	else
	{
		font_render_string_left (&font_bitmap8, 0, 8, "BREAK");
	}

	sprintf ("C%04lX", prev_log_callset);
	font_render_string_left (&font_bitmap8, 0, 24, sprintf_buffer);
	dmd_show_low ();
#endif
}
コード例 #11
0
ファイル: error.c プロジェクト: CardonaPinball/freewpc
/**
 * Entry point for errors that are nonrecoverable.
 * error_code is one of the values in include/system/errno.h.
 */
__noreturn__
void fatal (errcode_t error_code)
{
	new_fatal_error = TRUE;
#ifdef __m6809__
	set_stack_pointer (6133);
#endif

	/* Don't allow any more interrupts, since they might be the
	source of the error.  Since FIRQ is disabled, we can only
	do mono display at this point.   Also note that idle
	cannot run anymore, because task scheduling can't proceed
	without the system clock moving. */
	periodic_ok = 0;
	disable_interrupts ();

	/* Reset hardware outputs */
#ifdef CONFIG_GI
	pinio_write_gi (0);
#endif

	/* TODO - this whole function needs porting to Whitestar */
	/* Maybe just call platform_init again? */
#ifdef CONFIG_PLATFORM_WPC
	if (WPC_HAS_CAP (WPC_CAP_FLIPTRONIC))
		wpc_write_flippers (0);
#endif
#ifdef CONFIG_TICKET
	pinio_write_ticket (0);
#endif
	pinio_disable_flippers ();
	pinio_write_solenoid_set (0, 0);
	pinio_write_solenoid_set (1, 0);
	pinio_write_solenoid_set (2, 0);
	pinio_write_solenoid_set (3, 0);
#ifdef MACHINE_SOL_EXTBOARD1
	pinio_write_solenoid_set (5, 0);
#endif

	/* Audit the error. */
	audit_increment (&system_audits.fatal_errors);
	audit_assign (&system_audits.lockup1_addr, error_code);
	audit_assign (&system_audits.lockup1_pid_lef, task_getgid ());
	log_event (SEV_ERROR, MOD_SYSTEM, EV_SYSTEM_FATAL, error_code);

	/* Dump all debugging information */
#ifdef DEBUGGER
	dbprintf ("Fatal error %d\n", error_code);
	db_dump_all ();
#endif

	/* In native mode, exit whenever a fatal occurs.  If the
	   simulator is compiled in, let it clean up first. */
#ifdef CONFIG_SIM
	sim_exit (error_code);
#else
#ifdef CONFIG_NATIVE
	native_exit ();
	exit (error_code);
#endif
#endif

	/* Defining STOP_ON_ERROR is helpful during debugging a problem.
	Having the machine reset makes it hard to debug after the fact. */
#ifdef STOP_ON_ERROR
	while (1);
#endif

	/* Restart the system */
	warm_reboot ();
}