Example #1
0
File: node.c Project: hydra/freewpc
/* Insert an unbound ball into a node. */
void node_insert (struct ball_node *node, struct ball *ball)
{
    unsigned int offset;

    if (ball->node)
    {
        simlog (SLC_DEBUG, "node_insert: %s already at %s",
                ball->name, ball->node->name);
        return;
    }

    if (node_full_p (node) || !node->type)
    {
        simlog (SLC_DEBUG, "node_insert: %s not allowed", node->name);
        return;
    }

    offset = (node->head + node->count) % node->size;
    node->ball_queue[offset] = ball;
    node->count++;
    ball->node = node;
    ball->pos = offset;
    if (node->type->insert)
        node->type->insert (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, node->name);
#endif
    simlog (SLC_DEBUG, "node_insert: added %s to %s, count=%d", ball->name, node->name, node->count);

    if (node->unlocked && !node_full_p (node->next))
        sim_time_register (100, FALSE, (time_handler_t)node_kick_delayed, node);
}
Example #2
0
/**
 * Update the state machine for a coil.
 *
 * The complexity here is that software can pulse the solenoid rapidly
 * between on and off; the goal is to detect when a single 'kick' operation
 * has occurred.  That requires ignoring brief off-periods and only
 * considering that it is been on a majority of the time in the recent past.
 *
 * Also, once a kick has occurred, it is not considered to kick again until
 * it has returned to the resting position (in reality, to allow another ball
 * to enter the kicking area).
 *
 * This function uses periodic callbacks to keep the solenoid state updated
 * even when no writes are emitted from the CPU; the power driver board
 * latches state.
 */
static void sim_coil_update (struct sim_coil_state *c)
{
	struct sim_coil_state *m = c->master;

	if (c->master == NULL)
		return;

	/* If the IO is on and the coil has not reached its maximum,
	move it forward. */
	if (c->on && m->pos < m->type->max_pos)
	{
		m->pos += c->type->on_step;
		if (m->pos >= m->type->max_pos && !m->at_max)
		{
			m->pos = m->type->max_pos;
			m->at_max = 1;
			simlog (SLC_DEBUG, "Coil %d on", m - coil_states);
			if (m->type->at_max)
				m->type->at_max (c);
		}
	}
	/* Else, if the IO is off and the coil has not reached its rest state,
	move it backward. */
	else if (!c->on && m->pos > 0)
	{
		m->pos += c->type->off_step;
		if (m->pos <= 0)
		{
			m->pos = 0;
			m->at_max = 0;
			simlog (SLC_DEBUG, "Coil %d off", m - coil_states);
			if (m->type->at_rest)
				m->type->at_rest (c);
		}
	}

	if (c->chain)
		sim_coil_update (c->chain);

#if 0
	simlog (SLC_DEBUG, "Coil %d on=%d pos=%d of %d", m - coil_states,
		c->on, m->pos, m->type->max_pos);
#endif
	/* If the coil requires monitoring, and it is not at rest, then reschedule.
	Else, we are done until the CPU modifies it again. */
	if (!c->type->unmonitored && m->pos != 0)
		sim_time_register (1, FALSE, (time_handler_t)sim_coil_update, c);
	else
	{
		c->scheduled = 0;
	}
}
Example #3
0
File: node.c Project: hydra/freewpc
void switch_type_insert_or_remove (struct ball_node *node, struct ball *ball)
{
    simlog (SLC_DEBUG, "Switch %d holds %d balls", node->index, node->count);
#ifdef CONFIG_TZ
    if (ball->flags & 0x01)
    {
        simlog (SLC_DEBUG, "Slot prox ignored by Powerball");
        sim_switch_set (node->index, 0);
    }
    else
#endif
        sim_switch_set (node->index, node->count);
}
Example #4
0
File: log.c Project: 1uk3/contiki
/*-----------------------------------------------------------------------------------*/
int
puts(const char* s)
{
  simlog(s);
  simlog_char('\n');
  return 0;
}
Example #5
0
File: node.c Project: hydra/freewpc
void device_type_remove (struct ball_node *node, struct ball *ball)
{
    const device_properties_t *props = &device_properties_table[node->index];
    simlog (SLC_DEBUG, "Device %d remove, count=%d", node->index, node->count);
    /* Clear the switch that just opened */
    sim_switch_set (props->sw[node->size - node->count - 1], 0);
}
Example #6
0
File: node.c Project: hydra/freewpc
void device_type_insert (struct ball_node *node, struct ball *ball)
{
    const device_properties_t *props = &device_properties_table[node->index];
    simlog (SLC_DEBUG, "Device %d insert, count=%d", node->index, node->count);
    /* Set the switch that just closed */
    sim_switch_set (props->sw[node->size - node->count], 1);
}
Example #7
0
const char *tstring (void)
{
	const char *t;
	char *c;

	t = tnext ();
	if (!t)
		return NULL;
	if (*t != '"')
		return t;

	strcpy (tstringbuf, t+1);
	do {
		t = tnext ();
		if (!t)
		{
			simlog (SLC_DEBUG, "Parse error after '%s'", tstringbuf);
			return NULL;
		}
		strcat (tstringbuf, " ");
		strcat (tstringbuf, t);
		c = strchr (tstringbuf, '"');
	} while (c == NULL);
	*c = '\0';
	return tstringbuf;
}
Example #8
0
/** Register a function to be called after N_TICKS have elapsed from now.
 * PERIOIDIC_P is nonzero if the timer function should be called repeatedly,
 * every time that much time has elapsed.
 * FN is the function to be called and DATA can be anything at all, passed to
 * the handler. */
void sim_time_register (int n_ticks, int periodic_p, time_handler_t fn, void *data)
{
	unsigned int ring = ring_later (n_ticks);

	struct time_handler *elem = ring_malloc ();
	if (!elem)
		simlog (SLC_DEBUG, "can't alloc ring");

	if (n_ticks > RING_COUNT)
		simlog (SLC_DEBUG, "can't schedule timer that far out");

	elem->next = time_handler_ring[ring];
	elem->periodicity = periodic_p ? n_ticks : 0;
	elem->fn = fn;
	elem->data = data;
	time_handler_ring[ring] = elem;
}
Example #9
0
/* Handle parallel/serial port reads and writes */
static void wpc_write_debug (struct wpc_debug_port *port, unsigned int addr, U8 val)
{
	*(port->outptr)++ = val;
	if (val == '\n')
	{
		*--port->outptr = '\0';
		simlog (SLC_DEBUG_PORT, "%s", port->outbuf);
		port->outptr = port->outbuf;
	}
}
Example #10
0
static void fliptronic_coil_init (U8 power_sol)
{
	struct sim_coil_state *power_coil = coil_states + power_sol;
	struct sim_coil_state *hold_coil = power_coil + 1;

	power_coil->type = &flipper_power_type_coil;
	hold_coil->type = &flipper_hold_type_coil;
	hold_coil->master = power_coil;
	simlog (SLC_DEBUG, "Hold coil %d linked to power coil %d",
		power_coil - coil_states, hold_coil - coil_states);
}
Example #11
0
/**
 * Execute a series of script commands in the named file.
 */
void exec_script_file (const char *filename)
{
	FILE *in;
	char buf[256];

	in = fopen (filename, "r");
	if (!in)
		return;
	simlog (SLC_DEBUG, "Reading commands from '%s'", filename);
	for (;;)
	{
		if (!fgets (buf, 255, in))
			break;
		if (feof (in))
			break;
		exec_script (buf);
	}
	simlog (SLC_DEBUG, "Closing '%s'", filename);
	fclose (in);
}
Example #12
0
/*-----------------------------------------------------------------------------------*/
int
printf(const char *fmt, ...)
{
  int res;
  static char buf[MAX_LOG_LENGTH];
  va_list ap;
  va_start(ap, fmt);
  res = vsnprintf(buf, MAX_LOG_LENGTH, fmt, ap);
  va_end(ap);

  simlog(buf);
  return res;
}
Example #13
0
File: node.c Project: hydra/freewpc
/* Move a ball from one location to another.  The two nodes do not
	have to be connected via the default topology. */
void node_move (struct ball_node *dst, struct ball_node *src)
{
    struct ball *ball;

    if (!dst || !src)
        return;

    /* If there are already too many balls in the destination, then
    don't allow the operation: it must remain where it is. */
    if (node_full_p (dst))
    {
        simlog (SLC_DEBUG, "node_kick %s: destination %s is full", src->name, dst->name);
        return;
    }

    ball = node_remove (src);
    if (!ball)
    {
        simlog (SLC_DEBUG, "node_kick: no balls in %s", src->name);
        return;
    }

    simlog (SLC_DEBUG, "node_kick: %s -> %s", src->name, dst->name);
    /* If no delay is associated with a movement from the source, then
    the move is instantaneous.  Otherwise, it will be performed later; in
    the meantime the ball is not associated with any node. */
    if (src->delay == 0)
        node_insert (dst, ball);
    else
    {
#ifdef CONFIG_UI
        ui_update_ball_tracker (ball->index, src->name);
#endif
        node_insert_delay (dst, ball, src->delay);
    }
}
Example #14
0
File: node.c Project: hydra/freewpc
/* Remove the head of the node queue. */
struct ball *node_remove (struct ball_node *node)
{
    unsigned int offset;
    struct ball *ball;

    if (node->count == 0)
    {
        simlog (SLC_DEBUG, "node_remove: no balls in %s", node->name);
        return NULL;
    }

    offset = node->head % node->size;
    ball = node->ball_queue[offset];
    if (!ball)
    {
        simlog (SLC_DEBUG, "node_remove: count=%d but ball is null?", node->count);
        return NULL;
    }

    node->head++;
    node->count--;
    ball->node = NULL;
    if (node->type->remove)
        node->type->remove (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, "Free");
#endif
    simlog (SLC_DEBUG, "node_remove: took %s from %s", ball->name, node->name);

    if (node->prev && node->prev->unlocked && node->prev->count != 0)
    {
        node_kick (node->prev);
    }

    return ball;
}
Example #15
0
void generic_coil_at_max (struct sim_coil_state *c)
{
	unsigned int solno = c - coil_states;

#ifdef SOL_OUTHOLE
	if (solno == SOL_OUTHOLE)
		node_kick (&switch_nodes[MACHINE_OUTHOLE_SWITCH]);
#endif

#ifdef MACHINE_LAUNCH_SOLENOID
	if (solno == MACHINE_LAUNCH_SOLENOID)
		node_kick (&switch_nodes[MACHINE_SHOOTER_SWITCH]);
#endif

#ifdef MACHINE_KNOCKER_SOLENOID
	if (solno == MACHINE_KNOCKER_SOLENOID)
		simlog (SLC_DEBUG, "Thwack!");
#endif
}
Example #16
0
/**
 * Move a ball to a specific location.
 */
void sim_ball_move (unsigned int ballno, unsigned int location)
{
	unsigned int prev_location;

	if (ballno == -1)
		return;

	/* Remove the ball from its previous location */
	prev_location = sim_ball_location[ballno];
	if (prev_location != SIM_LOCATION_NONE)
	{
		sim_location_toggle (prev_location);
		sim_location_ball[location] = SIM_NO_BALL_HERE;
	}

	/* Set the ball at the new location */
	sim_location_toggle (location);
	sim_ball_location[ballno] = location;
	sim_location_ball[location] = ballno;
#ifdef CONFIG_UI
	ui_update_ball_tracker (ballno, location);
#endif
	simlog (SLC_DEBUG, "Ball %d @ %s", ballno, sim_ball_location_name (location));
}
Example #17
0
/**
 * Parse a complex expression and return a
 * signal_expression that describes it.
 */
struct signal_expression *texpr (void)
{
	struct signal_expression *ex, *ex1, *ex2;
	const char *t;

	t = tnext ();
	if (!t)
		return NULL;

	ex = expr_alloc ();
	if (teq (t, "at"))
	{
		ex->op = SIG_TIME;
		ex->u.timer = tconst ();
	}
	else if (teq (t, "after"))
	{
		ex->op = SIG_TIMEDIFF;
		ex->u.timer = tconst ();
	}
	else
	{
		tunget (t);
		ex->op = SIG_SIGNO;
		ex->u.signo = tsigno ();
		simlog (SLC_DEBUG, "Signo changed = 0x%X\n", ex->u.signo);

		t = tnext ();
		if (t)
		{
			if (teq (t, "is"))
			{
				ex1 = ex;

				ex2 = expr_alloc ();
				ex2->op = SIG_CONST;
				ex2->u.value = tconst ();

				ex = expr_alloc ();
				ex->op = SIG_EQ;
				ex->u.binary.left = ex1;
				ex->u.binary.right = ex2;
			}
		}
	}

	t = tnext ();
	if (t)
	{
		ex1 = ex;
		ex2 = texpr ();
		ex = expr_alloc ();
		ex->u.binary.left = ex1;
		ex->u.binary.right = ex2;
		if (teq (t, "and"))
			ex->op = SIG_AND;
		else if (teq (t, "or"))
			ex->op = SIG_OR;
	}

	return ex;
}
Example #18
0
File: log.c Project: EDAyele/ptunes
/*-----------------------------------------------------------------------------------*/
int
puts(const char* s)
{
  simlog(s);
  return 0;
}
Example #19
0
/** Main loop for handling the user interface. */
static void sim_interface_thread (void)
{
	char inbuf[2];
	struct key_binding *kb;
	int simulator_keys = 1;
	int toggle_mode = 1;

#ifndef CONFIG_UI_SDL
	/* Put stdin in raw mode so that 'enter' doesn't have to
	be pressed after each keystroke. */
	keybuffering (0);

	/* Let the system initialize before accepting keystrokes */
	task_sleep_sec (3);
#endif

	if (exec_file && exec_late_flag)
		exec_script_file (exec_file);

	for (;;)
	{
		task_yield ();
#ifdef CONFIG_GTK
		gtk_poll ();
#endif
#ifdef CONFIG_UI_SDL
		ui_refresh_all ();
		*inbuf = ui_poll_events ();
#else
		*inbuf = sim_getchar ();
#endif

		/* Try again if no character was read */
		if (*inbuf == '\0')
			continue;

		/* If switch simulation is turned off, then keystrokes
		are fed into the simulated serial port... meaning it is interpreted
		by the game program itself, and not the simulator.  Use the
		tilde to toggle between the two modes. */
		if (simulator_keys == 0)
		{
			/* Except tilde turns it off as usual. */
			if (*inbuf == '`')
			{
				simlog (SLC_DEBUG, "Input directed to switch matrix.");
				simulator_keys ^= 1;
			}
			else
			{
				wpc_key_press (*inbuf);
			}
			continue;
		}

		switch (*inbuf)
		{
			/* Carriage returns and line feeds are ignored so that you can
			put these commands into a script file. */
			case '\r':
			case '\n':
				break;

			case ':':
			{
				/* Read and execute a script command */
				char cmd[128];
				char *p = cmd;

				memset (p, 0, 128);
				ui_print_command (" ");
				for (;;)
				{
					*p = sim_getchar ();
					if (*p == '\x1B')
					{
						break;
					}
					else if (*p == '\010')
					{
						*p = '\0';
						p--;
					}
					else if ((*p == '\r') || (*p == '\n'))
					{
						*p = '\0';
						exec_script (cmd);
						break;
					}
					ui_print_command (cmd);
					p++;
				}
				ui_print_command ("");
				break;
			}

			case 'C':
				gdb_break ();
				break;

			case '{':
				signal_trace_start (signo_under_trace);
				break;

			case '}':
				signal_trace_stop (signo_under_trace);
				break;

			case 'q':
				node_kick (&open_node);
				break;

			case '`':
				/* The tilde toggles between keystrokes being treated as switches,
				and as input into the runtime debugger. */
				simulator_keys ^= 1;
				simlog (SLC_DEBUG, "Input directed to built-in debugger.");
				break;

			case '\x1b':
				sim_exit (0);
				break;

			case 'T':
				task_dump ();
				break;

			case '#':
				/* Treat '#' as a comment until end of line.
				This is useful for creating scripts. */
				do {
					*inbuf = sim_getchar ();
				} while (*inbuf != '\n');
				break;

			case '"':
				simlog (SLC_DEBUG, "next key will toggle, not press");
				toggle_mode = 0;
				break;

			default:
				/* For all other keystrokes, use the keymap table
				to turn the keystroke into a switch trigger. */
				kb = &keymaps[(int)*inbuf];
#ifdef MACHINE_SHOOTER_SWITCH
				if (kb->flags & KEY_SHOOTER)
				{
					node_kick (&shooter_node);
				}
				else
#endif
				if (kb->flags & KEY_NODE)
				{
					node_move (kb->node, &open_node);
				}
				else if (kb->flags & KEY_SW)
				{
					if ((switch_table[kb->sw].flags & SW_EDGE) || !toggle_mode)
					{
						simlog (SLC_DEBUG, "switch %d toggled", kb->sw);
						sim_switch_toggle (kb->sw);
						toggle_mode = 1;
					}
#if (MACHINE_FLIPTRONIC == 1)
					else if (kb->sw >= 72)
					{
						flipper_button_depress (kb->sw);
					}
#endif
					else
					{
						sim_switch_depress (kb->sw);
					}
				}
				else
					simlog (SLC_DEBUG, "invalid key '%c' pressed (0x%02X)",
						*inbuf, *inbuf);
			}
	}
}
Example #20
0
File: log.c Project: 1uk3/contiki
/*-----------------------------------------------------------------------------------*/
void
log_message(const char *part1, const char *part2)
{
  simlog(part1);
  simlog(part2);
}
Example #21
0
void flasher_coil_at_max (struct sim_coil_state *c)
{
	unsigned int solno = c - coil_states;
	simlog (SLC_DEBUG, "Flasher %d pulse", solno);
}
Example #22
0
/**
 * Parse and execute a script command.
 */
void exec_script (char *cmd)
{
	const char *t;
	uint32_t v, count;

	tlast = NULL;

	/* Blank lines and comments are ignored */
	t = tfirst (cmd);
	if (!t)
		return;
	if (*t == '#')
		return;

	/*********** capture [subcommand] [args...] ***************/
	if (teq (t, "capture"))
	{
		struct signal_expression *ex;

		t = tnext ();
		if (teq (t, "start"))
		{
			ex = texpr ();
			signal_capture_start (ex);
		}
		else if (teq (t, "stop"))
		{
			ex = texpr ();
			signal_capture_stop (ex);
		}
		else if (teq (t, "debug"))
		{
		}
		else if (teq (t, "file"))
		{
			t = tnext ();
			signal_capture_set_file (t);
		}
		else if (teq (t, "add"))
		{
			signal_capture_add (tsigno ());
		}
		else if (teq (t, "del"))
		{
			signal_capture_del (tsigno ());
		}
	}

	/*********** set [var] [value] ***************/
	else if (teq (t, "set"))
	{
		t = tnext ();
		v = tconst ();
		conf_write (t, v);
	}
	/*********** p/print [var] ***************/
	else if (teq (t, "p") || teq (t, "print"))
	{
		v = tconst ();
		simlog (SLC_DEBUG, "%d", v);
	}
	/*********** include [filename] ***************/
	else if (teq (t, "include"))
	{
		t = tnext ();
		exec_script_file (t);
	}
	/*********** sw [id] ***************/
	else if (teq (t, "sw"))
	{
		v = tsw ();
		count = tconst ();
		if (count == 0)
			count = 1;
		while (count > 0)
		{
			sim_switch_depress (v);
			count--;
		}
	}
	/*********** swtoggle [id] ***************/
	else if (teq (t, "swtoggle"))
	{
		v = tsw ();
		count = tconst ();
		if (count == 0)
			count = 1;
		while (count > 0)
		{
			sim_switch_toggle (v);
			count--;
		}
	}
	/*********** key [keyname] [switch] ***************/
	else if (teq (t, "key"))
	{
		t = tnext ();
		v = tsw ();
		simlog (SLC_DEBUG, "Key '%c' = %s", *t, names_of_switches[v]);
		sim_key_install (*t, v);
	}
	/*********** push [value] ***************/
	else if (teq (t, "push"))
	{
		v = tconst ();
		conf_push (v);
	}
	/*********** pop [argcount] ***************/
	else if (teq (t, "pop"))
	{
		v = tconst ();
		conf_pop (v);
	}
	/*********** sleep [time] ***************/
	else if (teq (t, "sleep"))
	{
		v = tconst ();
		simlog (SLC_DEBUG, "Sleeping for %d ms", v);
		v /= IRQS_PER_TICK;
		do {
			task_sleep (TIME_16MS);
		} while (--v > 0);
		simlog (SLC_DEBUG, "Awake again.", v);
	}
	/*********** exit ***************/
	else if (teq (t, "exit"))
	{
		sim_exit (0);
	}
}
Example #23
0
void motor_coil_at_rest (struct sim_coil_state *c)
{
	unsigned int solno = c - coil_states;
	c->pos = c->type->max_pos;
	simlog (SLC_DEBUG, "Motor %d @ %d", solno, c->pos);
}
Example #24
0
void motor_coil_at_max (struct sim_coil_state *c)
{
	unsigned int solno = c - coil_states;
	c->pos = 0;
	simlog (SLC_DEBUG, "Motor %d @ %d", solno, c->pos);
}