bool32 input bit
int32.positive x position (column selector)
int32.positive y position (row selector)
int32.positive see value format in local data
bool32.rising shift the selected row left by one position and insert the input bit on the right
bool32.rising shift the selected row right by one position and insert the input bit on the left
bool32.rising shift the selected column up by one position and insert the input bit on the bottom
bool32.rising shift the selected column down by one position and insert the input bit on the top
bool32.rising reset the register to the default value
bool32 output at (x,y)
int32.positive value of the register
/* REGISTER VARIABLE FORMAT
* / 16 bits \ /4 bits\ /4 bits\ /4 bits\ /4 bits\
* reg = [unused bloat] [row1] [row2] [row3] [row4]
*
* you can see it as a 4x4 matrix like this:
* [Row1 MSB] [bit] [bit] [Row1 LSB]
* [Row2 MSB] [bit] [bit] [Row2 LSB]
* [Row3 MSB] [bit] [bit] [Row3 LSB]
* [Row4 MSB] [bit] [bit] [Row4 LSB]
*/
bool rtrig = 0; // reset trigger
bool strig = 0; // shift trigger
// these are bitmasks used for operations
int32_t row[4] = {0b1111000000000000, 0b0000111100000000, 0b0000000011110000,
0b0000000000001111};
int32_t col[4] = {0b1000100010001000, 0b0100010001000100, 0b0010001000100010,
0b0001000100010001};
int32_t reg = 0; // register in which to hold values
int32_t tmp = 0; // temp variable for operations
// saturate (well, actually overflow) inputs to the correct range
int32_t def = inlet_default & 65535;
int32_t x = inlet_x & 3;
int32_t y = inlet_y & 3;
// temporary variable
tmp = reg;
// shifting operations
if (inlet_left & !strig) {
reg = ((reg & row[y]) << 1) & row[y];
if (inlet_in)
reg = reg | (row[y] & col[3]);
tmp = tmp & (~row[y]);
reg = reg | tmp;
strig = 1;
}
if (inlet_right & !strig) {
reg = ((reg & row[y]) >> 1) & row[y];
if (inlet_in)
reg = reg | (row[y] & col[0]);
tmp = tmp & (~row[y]);
reg = reg | tmp;
strig = 1;
}
if (inlet_up & !strig) {
reg = ((reg & col[x]) << 4) & col[x];
if (inlet_in)
reg = reg | (col[x] & row[3]);
tmp = tmp & (~col[x]);
reg = reg | tmp;
strig = 1;
}
if (inlet_down & !strig) {
reg = ((reg & col[x]) >> 4) & col[x];
if (inlet_in)
reg = reg | (col[x] & row[0]);
tmp = tmp & (~col[x]);
reg = reg | tmp;
strig = 1;
}
if (!(inlet_left | inlet_right | inlet_up | inlet_down)) {
strig = 0;
}
// reset operations
if (inlet_reset && !rtrig) {
reg = def;
rtrig = 1;
} else if (!inlet_reset) {
rtrig = 0;
}
// outputs
outlet_reg = reg;
outlet_out = reg & col[x] & row[y];