Created
October 24, 2013 21:53
-
-
Save Blecki/7145711 to your computer and use it in GitHub Desktop.
Code-generating code for an IN8 Emulator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <<(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