shift register 2d

A 2D shift register. Can be used for cartesian sequencers.
Author: Sputnki
License: BSD
Github: sptnk/logic/shift register 2d.axo

Inlets

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

Outlets

bool32 output at (x,y)

int32.positive value of the register

Declaration
/*	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
Control Rate
// 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];

Privacy

© 2024 Zrna Research