/* 2x4 Decoder
   Syntax: Decoder2x4 <x,y> c[1..0] | s[3..0];
*/
Define Decoder2x4 c[1..0] | s[3..0];
 Not 1a c[1] not-c1; Not 2a c[0] not-c0;
 And 2a c[1] c[0] s[3];
 And 2b c[1] not-c0 s[2];
 And 2c not-c1 c[0] s[1];
 And 2d not-c1 not-c0 s[0];
Endef;

/* Full adder.
   Syntax: Full_Adder a b c-in | c-out s;
   Effect: Adds binary numbers a + b with carry.
*/
Define Full_Adder CarryIn a b | CarryOut Sum;
  Xor aa a b x;
  Xor ab x CarryIn Sum;
  And bb a b y;
  And cb CarryIn x z;
  Or bc-cc y z CarryOut;
Endef;




/* 1 bit ALU 
   Syntax: One_Bit_ALU a b carry-in sel1 sel0 | z carry-out;
   sel1 = 0, sel0 = 0 -> Add a, b carry-in
   sel1 = 0, sel0 = 1 -> Not a
   sel1 = 1, sel0 = 0 -> a Or b
   sel1 = 1, sel0 = 1 -> a AND b
*/
Define One_Bit_ALU a b c-in s[1..0] | z c-out;
 And 1a a b Out-And2;
 Or 1a a b Out-Or;
 Not 1a a Out-Not;
 Full_Adder 1a a b c-in | c-out1 Out-Sum;
 Decoder2x4 2a s[1] s[0] | l3 l2 l1 l0;
 And 2c l3 Out-And2 Out-And1;
 And 2c l2 Out-Or Out-Or1;
 And 2c l1 Out-Not Out-Not1;
 And 2c l0 Out-Sum Out-Sum1;
 And 2c l0 c-out1  c-out;
 Or 2c  Out-And1 Out-Or1 Out-Not1 Out-Sum1 z;
Endef;


/* Main */
One_Bit_ALU "Bit0" ce a0 b0 ZERO control1 control0| z0 c1;
One_Bit_ALU "Bit1" cd a1 b1 c1 control1 control0| z1 c2;
One_Bit_ALU "Bit2" cc a2 b2 c2 control1 control0| z2 c3;
One_Bit_ALU "Bit3" cb a3 b3 c3 control1 control0| z3 c-out;

/* Number a */
Switch "0:a0" ae a0 ZERO;
Switch "1:a1" ad a1 ZERO;
Switch "2:a2" ac a2 ZERO;
Switch "3:a3" ab a3 ZERO;

/* Number b */
Switch "4:b0" be b0 ZERO;
Switch "5:b1" bd b1 ZERO;
Switch "6:b2" bc b2 ZERO;
Switch "7:b3" bb b3 ZERO;

/* Probes */
Probe "Carry" ca c-out;
Probe "z0" de z0;
Probe "z1" dd z1;
Probe "z2" dc z2;
Probe "z3" db z3;

/* Controls */
Switch "8:Contr1" ea control1 ZERO;
Switch "9:Contr0" eb control0 ZERO;

