3. The VM
All state data is maintained inside of a struct called
trig_vm
.
3.1. VM Data
typedef struct trig_vm trig_vm;
<<trig_state>>
struct trig_vm {
<<trig_vm>>
};
A trig_vm
is initialized with trig_vm_init
.
void trig_vm_init(trig_vm *vm);
void trig_vm_init(trig_vm *vm)
{
<<trig_vm_init>>
}
No destroy function needed, as there is no memory allocation.
3.2. VM struct size
size_t trig_vm_size(void);
size_t trig_vm_size(void)
{
return sizeof(trig_vm);
}
3.3. The Cell Pool
Cells are managed in a pool of exactly 32. This fits into a 8x4 rectangle.
trig_cell cell[32];
{
int i;
for (i = 0; i < 32; i++) {
vm->cell[i].cmd = 0;
vm->cell[i].data = 0;
}
}
3.4. Internal State
Internal state variables that can be swapped out. Used to have multiple readers happening at once.
trig_state *state;
trig_state istate;
vm->state = &vm->istate;
trig_state_init(&vm->istate);
3.5. Goto
Sets the cell position of the internal struct.
void trig_vm_goto(trig_vm *vm, int pos);
void trig_vm_goto(trig_vm *vm, int pos)
{
vm->istate.pos = pos;
}
3.5.1. Counter
A global counter is used by certain kinds of cells for performing patterns.
void trig_vm_counter_reset(trig_vm *vm);
Just the main counter. Other states will have to be reset another way (inside a graforge node... re-compilation).
void trig_vm_counter_reset(trig_vm *vm)
{
vm->istate.counter = -1;
}
3.6. Wires
"Wires" are floating point variables that can be used for input or output. The VM doesn't really make a distinction.
The number of wires can be set with the TRIG_NWIRES
macro,
which for now is set to be 8 by default.
#ifndef TRIG_NWIRES
#define TRIG_NWIRES 8
#endif
float wires[TRIG_NWIRES];
{
int i;
for (i = 0; i < TRIG_NWIRES; i++) {
vm->wires[i] = 0;
}
}
A value of a wire can be retrieved using the function
trig_vm_wire_get
.
float trig_vm_wire_get(trig_vm *vm, int wire);
float trig_vm_wire_get(trig_vm *vm, int wire)
{
return vm->wires[wire];
}
A value of a wire can be set using the function
trig_vm_wire_set
.
void trig_vm_wire_set(trig_vm *vm, int wire, float val);
void trig_vm_wire_set(trig_vm *vm, int wire, float val)
{
vm->wires[wire] = val;
if (vm->set != NULL) {
vm->set(vm, vm->ud, wire, val);
}
}
The pointer reference of the wire can be retrieved with
trig_vm_wire_ref
float* trig_vm_wire_ref(trig_vm *vm, int wire);
float* trig_vm_wire_ref(trig_vm *vm, int wire)
{
return &vm->wires[wire];
}
3.7. Wire Callback
In order to integrate wires with Graforge, a callback interface is provided. This gets called anytime a cable value is set.
typedef void (*trig_setter) (trig_vm *, void *, int, float);
trig_setter set;
void *ud;
vm->set = NULL;
vm->ud = NULL;
It can be set with the callback with
trig_vm_setter
.
void trig_vm_setter(trig_vm *vm, trig_setter fun, void *ud);
void trig_vm_setter(trig_vm *vm, trig_setter fun, void *ud)
{
vm->set = fun;
vm->ud = ud;
}
3.8. Run Flag
This flag is set at the beginning of a step, and will cause the program to step through the system until a cell flips it off.
int running;
vm->running = 0;
3.9. Get Cell
trig_cell * trig_vm_cell_get(trig_vm *vm, int cell);
trig_cell * trig_vm_cell_get(trig_vm *vm, int cell)
{
return &vm->cell[cell];
}
prev | home | next