Skip to content

Instantly share code, notes, and snippets.

@Blecki
Created October 24, 2013 21:53
Show Gist options
  • Select an option

  • Save Blecki/7145711 to your computer and use it in GitHub Desktop.

Select an option

Save Blecki/7145711 to your computer and use it in GitHub Desktop.
Code-generating code for an IN8 Emulator
<<(nop
(set @globals "instruction-table" (record))
(defun fittab ((arg string) (arg tab-size))
(if (> (strlen string) tab-size)
(substr string 0 tab-size)
(strcat string $(array (- tab-size (strlen string)) (" ")))
)
)
(defun "instruction" ((arg c)(arg n)(arg name)(arg codeblock))
(set @globals.instruction-table (n) "\/* (fittab name 7) */ { CLOCK+=(c); (codeblock) break; }")
)
(defun "operand-name" ((arg n))
(if (= n 0) "A"
(if (= n 1) "B"
(if (= n 2) "C"
(if (= n 3) "D"
(if (= n 4) "E"
(if (= n 5) "H"
(if (= n 6) "L"
(if (= n 7) "N" )))))))))
(defun "math-set" ((arg c)(arg n)(arg name)(arg-lazy operation))
(nop
(fori i 0 8 (math-instruction c name (+ n i) 0 i operation))
(fori i 0 8 (math-instruction c name (+ n i 8) 1 i operation))
)
)
(defun "math-instruction" ((arg c)(arg name)(arg n)(arg first-operand)(arg second-operand)(arg operation))
(let
(
("_1" (operand-name first-operand))
("_2" (operand-name second-operand))
)
(set @globals.instruction-table (n) "\/* (fittab "(name) (_1) (_2)" 7) */ { CLOCK+=(c); (capture (eval operation)) break; }")
)
)
(defun "operand-set" ((arg c)(arg n)(arg name)(arg-lazy operation))
(fori i 0 8 (operand-instruction c name (+ n i) i operation))
)
(defun "operand-instruction" ((arg c)(arg name)(arg n)(arg operand)(arg operation))
(let
(
("_1" (operand-name operand))
)
(set @globals.instruction-table (n) "\/* (fittab "(name) (_1)" 7) */ { CLOCK+=(c); (capture (eval operation)) break; }")
)
)
(math-set 1 0b00000000 "MTA" (write "(_1) = (_2);"))
(instruction 4 0b00000000 "CAL" $"MEM[--SP] = (byte)IP; MEM[--SP] = (byte)(IP \>> 8); IP = HL;") /* Replaces MTA A A */
(instruction 4 0b00001001 "RET" $"H = MEM[SP++]; L = MEM[SP++]; IP = HL;") /* Replaces MTA B B */
(math-set 1 0b00010000 "MFA" (write "(_2) = (_1);"))
(instruction 1 0b00010000 "" "") /* Replaces MFA A A */
(instruction 1 0b00010001 "" "") /* Replaces MFA A B */
(instruction 1 0b00011000 "" "") /* Replaces MFA B A */
(instruction 1 0b00011001 "" "") /* Replaces MFA B B */
(instruction 2 0b00010111 "NOT A" "A = !A;") /* Replaces MFA A N */
(instruction 2 0b00011111 "NOT B" "B = !B;") /* Replaces MFA B N */
(math-set 2 0b00100000 "ADD" (write "(_1) += (_2); O = \(byte)\(\(\(ushort)_1 + \(ushort)_2) & 0xFF00) \>> 8;"))
(math-set 2 0b00110000 "SUB" (write "(_1) -= (_2); O = \(byte)\(\(ushort)_1 << 8) - \(\(ushort)_2 << 8);"))
(math-set 8 0b01000000 "MUL" (write "(_1) *= (_2); O = \(byte)\(\(\(ushort)_1 * \(ushort)_2) & 0xFF00) \>> 8;"))
(math-set 32 0b01010000 "DIV" (write "(_1) /= (_2); O = 0;"))
(math-set 32 0b01100000 "MOD" (write "(_1) %= (_2); O = 0;"))
(math-set 2 0b01110000 "AND" (write "(_1) &= (_2); O = 0;"))
(instruction 1 0b01110000 "OVA" "A = O;") /* Replaces AND A A */
(instruction 1 0b01111001 "OVB" "B = O;") /* Replaces AND B B */
(math-set 2 0b10000000 "BOR" (write "(_1) |= (_2); O = 0;"))
(instruction 8 0b10000000 "MUS" $"B = (byte)((sbyte)A * (sbyte)B); O = (byte)(((sbyte)A * (sbyte)B) \>> 8);") /* Reps BOR A A */
(instruction 32 0b10001001 "DIS" $"B = (byte)((sbyte)A / (sbyte)B); O = 0;") /* Replaces BOR B B */
(math-set 2 0b10010000 "XOR" (write "(_1) ^= (_2); O = 0;"))
(operand-set 4 0b10100000 "PSH" (write "MEM[--SP] = (_1);"))
(operand-set 4 0b10101000 "POP" (write "(_1) = MEM[SP++];"))
(instruction 2 0b10101111 "RSP" $"H = (byte)(SP \>> 8); L = (byte)SP;") /* Replaces POP N */
(operand-set 2 0b10110000 "PEK" (write "(_1) = MEM[SP];"))
(instruction 2 0b10110111 "SSP" $"SP = HL;") /* Replaces PEK N */
(operand-set 8 0b10111000 "LOD" (write "(_1) = MEM[HL];"))
(instruction 2 0b10111111 "LLT" $"H = N; L = N;") /* Replaces LOD N */
(operand-set 8 0b11000000 "STR" (write "MEM[HL] = (_1);"))
(instruction 12 0b11001000 "LDW" $"if (HL%2 == 1) ALIGN_FAULT(); A = MEM[HL]; B = MEM[HL + 1];")
(instruction 12 0b11001001 "SDW" $"if (HL%2 == 1) ALIGN_FAULT(); MEM[HL] = A; MEM[HL + 1] = B;")
(instruction 1 0b11001010 "STP" $"STOP();")
(instruction 2 0b11001011 "CFP" $"H = D; L = E;")
(instruction 2 0b11001100 "SWP" $"var T = D; D = H; H = T; T = E; E = L; L = T;")
(instruction 2 0b11001101 "RIP" $"H = (byte)(IP \>> 8); L = (byte)IP;")
(instruction 2 0b11001110 "JMP" $"IP = HL;")
(instruction 2 0b11001111 "JPL" $"H = N; L = N; IP = HL;")
(instruction 8 0b11010000 "BIE" $"if (A == B) IP = HL;")
(instruction 8 0b11010001 "BNE" $"if (A != B) IP = HL;")
(instruction 8 0b11010010 "BGT" $"if (A > B) IP = HL;")
(instruction 8 0b11010011 "BLT" $"if (A < B) IP = HL;")
(instruction 8 0b11010100 "BEG" $"if (A >= B) IP = HL;")
(instruction 8 0b11010101 "BEL" $"if (A <= B) IP = HL;")
(instruction 8 0b11010110 "BSL" $"if ((sbyte)A < (sbyte)B) IP = HL;")
(instruction 8 0b11010111 "BSG" $"if ((sbyte)A > (sbyte)B) IP = HL;")
(operand-set 4 0b11011000 "CAD" (write "var T = HL; T += (_1); L = \(byte)T; H = \(byte)\(T \>> 8);"))
(operand-set 4 0b11100000 "CSB" (write "var T = HL; T -= (_1); L = \(byte)T; H = \(byte)\(T \>> 8);"))
(operand-set 4 0b11101000 "ADS" (write "SP += (_1);"))
(operand-set 4 0b11110000 "SBS" (write "SP -= (_1);"))
(instruction 2 0b11111000 "OUT" $"PORT[A] = B;")
(instruction 2 0b11111001 "IIN" $"B = PORT[A];")
(instruction 1 0b11111010 "" "")
(instruction 1 0b11111011 "" "")
(instruction 1 0b11111100 "" "")
(instruction 4 0b11111101 "CLK" $"D = (byte)(CLOCK\>>24); E = (byte)(CLOCK\>>16); H = (byte)(CLOCK\>>8); L = (byte)CLOCK;")
(instruction 2 0b11111110 "SFJ" $"IP += N;")
(instruction 2 0b11111111 "SBJ" $"IP -= N;")
)>>
//Setup memory and registers
byte[] MEM = new byte[0xFFFF];
byte A, B, C, D, E, H, L = 0;
ushort IP, SP = 0;
byte O = 0;
uint CLOCK = 0;
byte[] PORT = new byte[0xFF];
byte N { get { CLOCK++; return MEM[IP++]; } }
byte HL { get { return ((ushort)H \<< 8) + (ushort)L; }}
while (true)
{
switch (N)
{
<<(fori n 0 256
(write "\t\tcase (fittab "(n)" 3): (@globals.instruction-table.(n)) \n")
)>>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment