diff --git a/src/cpu/ctfe_d6502.d b/src/cpu/ctfe_d6502.d index 441c5db..ced851d 100644 --- a/src/cpu/ctfe_d6502.d +++ b/src/cpu/ctfe_d6502.d @@ -198,7 +198,8 @@ struct Env string OpBody(int op, string chip, bool s, bool c) { auto env = Env(op, chip, s, c); - string ret = ((env.mode == IMP) ? AddrIMP(env) : ""); + string ret = ((op == 0x20) ? "" : Address(env)); + final switch (opName(op, chip)) { case "BRK": @@ -415,19 +416,29 @@ string OpBody(int op, string chip, bool s, bool c) ret ~= RMW(TestSet(), env); break; case "LAS": - return ""; + ret ~= LAS_Undoc(env); + break; case "LAX": - return ""; // address modes + if (op != 0xAB) + ret ~= Load(_A ~ " = " ~ _X, env); + else + return ""; + break; case "SAX": - return ""; + ret ~= Store(_A ~ " & " ~ _X, env); + break; case "ANC": - return ""; + ret ~= ANC_Undoc(env); + break; case "ALR": - return ""; + ret ~= ALR_Undoc(env); + break; case "ARR": - return ""; + ret ~= ARR_Undoc(env); + break; case "AXS": - return ""; + ret ~= AXS_Undoc(env); + break; case "AHX": return ""; case "SHY": @@ -439,17 +450,26 @@ string OpBody(int op, string chip, bool s, bool c) case "XAA": return ""; case "SLO": - return ""; + ret ~= RMW_Undoc(ShiftLeft("data"), + SetNZ(_A ~ " |= data"), env); + break; case "RLA": - return ""; + ret ~= RMW_Undoc(RotateLeft("data"), + SetNZ(_A ~ " &= data"), env); + break; case "SRE": - return ""; + ret ~= RMW_Undoc(ShiftRight("data"), + SetNZ(_A ~ " ^= data"), env); + break; case "RRA": - return ""; + ret ~= RMW_Undoc(RotateRight("data"), AddBase(env), env); + break; case "DCP": - return ""; + ret ~= RMW_Undoc(Dec("data"), CompareBase(_A, env), env); + break; case "ISC": - return ""; + ret ~= RMW_Undoc(Inc("data"), SubBase(env), env); + break; } return ret ~ Done(env); } @@ -497,8 +517,7 @@ string Jump(Env env) bool nmos = env.nmos; if (env.op == 0x4c) - return Address(env) ~ - _PC ~ " = address;\n"; + return _PC ~ " = address;\n"; else if (env.op == 0x6c) return ReadWordOp("ushort", "base", env) ~ If!(cmos)( @@ -531,10 +550,9 @@ string Branch(string check, Env env) string Nop(Env env) { if (env.mode == IMP || env.mode == NP1 || env.mode == NP8) - return Address(env); + return ""; // XXX add np1/np8 stuff else - return Address(env) ~ - PreAccess(env) ~ + return PreAccess(env) ~ ReadRaw("address") ~ ";\n"; } @@ -562,24 +580,26 @@ string PushReg(string reg, Env env) string Load(string reg, Env env) { - return Address(env) ~ - ReadInto(reg, "address", env) ~ + return ReadInto(reg, "address", env) ~ SetNZ(reg); } string Store(string reg, Env env) { - return Address(env) ~ - Write("address", reg, env); + return Write("address", reg, env); } string Compare(string reg, Env env) { - return Address(env) ~ - ReadInto(Local("ubyte", "data"), "address", env) ~ - UpdateFlag(_C, reg ~ " >= data") ~ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + CompareBase(reg, env); +} + +string CompareBase(string reg, Env env) +{ + return UpdateFlag(_C, reg ~ " >= data") ~ SetNZ("cast(ubyte)(" ~ reg ~ " - data)"); } @@ -588,8 +608,7 @@ string Bit(Env env) { bool notImm = (env.mode != IMM); - return Address(env) ~ - ReadInto(Local("ubyte", "data"), "address", env) ~ + return ReadInto(Local("ubyte", "data"), "address", env) ~ If!(notImm)( _N ~ " = data;\n" ~ _V ~ " = ((data & 0x40) != 0);\n") ~ @@ -599,17 +618,20 @@ string Bit(Env env) string Logic(string action, Env env) { - return Address(env) ~ - ReadInto(_A, action, "address", env) ~ + return ReadInto(_A, action, "address", env) ~ SetNZ(_A); } string Add(Env env) { - return Address(env) ~ - ReadInto(Local("ubyte", "data"), "address", env) ~ - "if (" ~ _D ~ ")\n{\n" ~ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + AddBase(env); +} + +string AddBase(Env env) +{ + return "if (" ~ _D ~ ")\n{\n" ~ DecAdd(env) ~ "}\nelse\n{\n" ~ HexAdd(env) ~ @@ -649,12 +671,16 @@ string DecAdd(Env env) string Sub(Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + SubBase(env); +} + +string SubBase(Env env) { bool nmos = env.nmos; - return Address(env) ~ - ReadInto(Local("ubyte", "data"), "address", env) ~ - "if (" ~ _D ~ ")\n{\n" ~ + return "if (" ~ _D ~ ")\n{\n" ~ If!(nmos)(DecSubNMOS(), DecSubCMOS(env)) ~ "}\nelse\n{\n" ~ HexSub() ~ @@ -768,8 +794,7 @@ string RMW(string action, Env env) { bool nmos = env.nmos; - return Address(env) ~ - ReadInto(Local("ubyte", "data"), "address", env) ~ + return ReadInto(Local("ubyte", "data"), "address", env) ~ If!(nmos)(Poke("address", "data", env), Peek("address", env)) ~ action ~ @@ -777,6 +802,74 @@ string RMW(string action, Env env) } +string RMW_Undoc(string action1, string action2, Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + Poke("address", "data", env) ~ + action1 ~ + Write("address", "data", env) ~ + action2; +} + + +string LAS_Undoc(Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + SetNZ(_X ~ " = " ~ _A ~ " = (" ~ _S ~ " & data)"); +} + + +string ARR_Undoc(Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + "ubyte tmp1 = data & " ~ _A ~ ";\n" ~ + "if (" ~ _D ~ ")\n{\n" ~ + "ubyte tmp2 = cast(ubyte)((tmp1 >> 1) + (" ~ + _C ~ " ? 0x80 : 0));\n" ~ + _N ~ " = " ~ _Z ~ " = tmp2;\n" ~ + _V ~ " = (((tmp2 ^ tmp1) & 0x40) != 0);\n" ~ + "if ((data & 0x0F) + (tmp1 & 0x01) > 5)\n" ~ + "tmp2 = (tmp2 & 0xF0) + ((tmp2 + 0x6) & 0x0F);\n" ~ + "if (tmp1 + (tmp1 & 0x10) >= 0x60)\n{\n" ~ + "tmp2 += 0x60;\n" ~ + SetFlag(_C) ~ + "}\nelse\n" ~ + ClearFlag(_C) ~ + _A ~ " = tmp2;\n" ~ + "}\nelse{\n" ~ + _A ~ " = cast(ubyte)((tmp1 >> 1) + (" ~ + _C ~ " ? 0x80 : 0));\n" ~ + _N ~ " = " ~ _Z ~ " = " ~_A ~ ";\n" ~ + "tmp1 >>= 7;\n" ~ + _C ~ " = (tmp1 != 0);\n" ~ + _V ~ " = ((tmp1 ^ ((" ~ _A ~ " >> 5) & 1)) != 0);\n}"; +} + + +string ANC_Undoc(Env env) +{ + return ReadInto(_A, "address", env) ~ + SetNZ(_A) ~ + _C ~ " = (" ~ _A ~ " > 0x7f);\n"; +} + + +string ALR_Undoc(Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + _A ~ " &= data;\n" ~ + ShiftRight(_A); +} + + +string AXS_Undoc(Env env) +{ + return ReadInto(Local("ubyte", "data"), "address", env) ~ + _X ~ " &= " ~ _A ~ ";\n" ~ + CompareBase(_X, env); +} + + string Local(string type) { version(OpFunctions) @@ -823,7 +916,7 @@ string Address(Env env) final switch (env.mode) { case IMP: - return ""; + return AddrIMP(env); case IMM: return AddrIMM(env); case ZP: @@ -853,7 +946,7 @@ string Address(Env env) case NP1: return ""; case NP8: - return Local("ushort", "address") ~ " = 0;"; + return AddrNP8(env); case KIL: return ""; } @@ -926,6 +1019,18 @@ string AddrZPI(Env env) ReadWordZP("ushort", "address", "base", env); } +string AddrNP8(Env env) +{ + return ReadOp(Local("ushort", "base"), env) ~ + Peek(_PC, env) ~ + IncPC() ~ + Peek("0xff00 | base", env) ~ + Peek("0xffff", env) ~ + Peek("0xffff", env) ~ + Peek("0xffff", env) ~ + Peek("0xffff", env); +} + string CheckShortcut(string base, string addr, Env env) { bool nmos = env.nmos; diff --git a/src/cpu/d6502.d b/src/cpu/d6502.d index 0aef333..365675e 100644 --- a/src/cpu/d6502.d +++ b/src/cpu/d6502.d @@ -180,6 +180,6 @@ version(OpFunctions) mixin(OpBodies("65C02", vStrict, vCumulative)); void main() { import std.stdio; - writeln(OpBody(0x11, "65C02", true, false)); + writeln(OpBody(0x11, "6502", true, false)); } +/ diff --git a/test/test_new_cpu.d b/test/test_new_cpu.d index 5cf5c6e..7bfc9fa 100644 --- a/test/test_new_cpu.d +++ b/test/test_new_cpu.d @@ -55,5 +55,11 @@ void main() 0xb4, 0x94, 0x01, 0x21, 0x41, 0x61, 0xe1, 0xc1, 0xa1, 0x81, 0x11, 0x31, 0x51, 0x71, 0xf1, 0xd1, 0xb1, 0x91, 0xda, 0x5a, 0x7a, 0xfa, 0x89, 0x34, 0x3c, 0x1a, 0x3a, 0x80, 0x64, 0x74, - 0x14, 0x1c, 0x04, 0x0c, 0x40]); + 0x14, 0x1c, 0x04, 0x0c, 0x40, 0x03, 0x07, 0x0f, 0x13, 0x17, + 0x1b, 0x1f, 0x23, 0x27, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, + 0x47, 0x4f, 0x53, 0x57, 0x5b, 0x5f, 0x5c, 0x63, 0x67, 0x6f, + 0x73, 0x77, 0x7b, 0x7f, 0xc3, 0xc7, 0xcf, 0xd3, 0xd7, 0xdb, + 0xdf, 0xe3, 0xe7, 0xe7, 0xf3, 0xf7, 0xfb, 0xff, 0xbb, 0x83, + 0x87, 0x8f, 0x97, 0xa3, 0xa7, 0xaf, 0xb3, 0xb7, 0xbf, 0x6b, + 0x0b, 0x2b, 0x4b, 0xeb, 0xcb]); }