-uint8_t a5_1_clock(a5_1_ctx_t *c){
- return a5_1_clock_core(c, 0);
+const uint8_t parity3_lut[] PROGMEM = { 0, 1, 1, 0,
+ 1, 0, 0, 1 };
+const uint8_t clock_lut[] PROGMEM = { 0x7, 0x6, 0x5, 0x3,
+ 0x3, 0x5, 0x6, 0x7 };
+
+uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride)
+{
+ uint8_t ret, clk, fb;
+ ret = (0x04 & c->r1[2]) | (0x20 & c->r2[2]) | (0x40 & c->r3[2]);
+ ret = ret ^ (ret >> 6);
+ ret &= 0x7;
+ ret = pgm_read_byte(parity3_lut + ret);
+ clk = (0x08 & c->r1[1]) | (0x10 & c->r2[1]) | (0x20 & c->r3[1]);
+ clk >>= 3;
+ clk = pgm_read_byte(clock_lut + clk);
+ clk |= clockoverride;
+
+ if (clk & 1) {
+ fb = c->r1[2] ^ (1 & ((c->r1[1]) >> 5));
+ fb &= 0x7;
+ fb = pgm_read_byte(parity3_lut + fb);
+ shiftreg(c->r1);
+ c->r1[0] |= fb;
+ c->r1[2] &= 0x07;
+ }
+ clk >>= 1;
+ if (clk & 1) {
+ fb = c->r2[2] >> 4;
+ fb &= 0x7;
+ fb = pgm_read_byte(parity3_lut + fb);
+ shiftreg(c->r2);
+ c->r2[0] |= fb;
+ c->r2[2] &= 0x3F;
+
+ }
+ clk >>= 1;
+ if (clk & 1) {
+ fb = (c->r3[2] >> 4) ^ (1 & ((c->r3[0]) >> 7));
+ fb &= 0x7;
+ fb = pgm_read_byte(parity3_lut + fb);
+ shiftreg(c->r3);
+ c->r3[0] |= fb;
+ c->r3[2] &= 0x7F;
+ }
+ return ret;