Implement stable undocumented opcodes

This commit is contained in:
edmccard 2012-04-11 22:05:29 -04:00
parent 8085dc61a0
commit 216ba9b6f3
3 changed files with 153 additions and 42 deletions

View File

@ -198,7 +198,8 @@ struct Env
string OpBody(int op, string chip, bool s, bool c) string OpBody(int op, string chip, bool s, bool c)
{ {
auto env = Env(op, chip, s, 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)) final switch (opName(op, chip))
{ {
case "BRK": case "BRK":
@ -415,19 +416,29 @@ string OpBody(int op, string chip, bool s, bool c)
ret ~= RMW(TestSet(), env); ret ~= RMW(TestSet(), env);
break; break;
case "LAS": case "LAS":
return ""; ret ~= LAS_Undoc(env);
break;
case "LAX": case "LAX":
return ""; // address modes if (op != 0xAB)
ret ~= Load(_A ~ " = " ~ _X, env);
else
return "";
break;
case "SAX": case "SAX":
return ""; ret ~= Store(_A ~ " & " ~ _X, env);
break;
case "ANC": case "ANC":
return ""; ret ~= ANC_Undoc(env);
break;
case "ALR": case "ALR":
return ""; ret ~= ALR_Undoc(env);
break;
case "ARR": case "ARR":
return ""; ret ~= ARR_Undoc(env);
break;
case "AXS": case "AXS":
return ""; ret ~= AXS_Undoc(env);
break;
case "AHX": case "AHX":
return ""; return "";
case "SHY": case "SHY":
@ -439,17 +450,26 @@ string OpBody(int op, string chip, bool s, bool c)
case "XAA": case "XAA":
return ""; return "";
case "SLO": case "SLO":
return ""; ret ~= RMW_Undoc(ShiftLeft("data"),
SetNZ(_A ~ " |= data"), env);
break;
case "RLA": case "RLA":
return ""; ret ~= RMW_Undoc(RotateLeft("data"),
SetNZ(_A ~ " &= data"), env);
break;
case "SRE": case "SRE":
return ""; ret ~= RMW_Undoc(ShiftRight("data"),
SetNZ(_A ~ " ^= data"), env);
break;
case "RRA": case "RRA":
return ""; ret ~= RMW_Undoc(RotateRight("data"), AddBase(env), env);
break;
case "DCP": case "DCP":
return ""; ret ~= RMW_Undoc(Dec("data"), CompareBase(_A, env), env);
break;
case "ISC": case "ISC":
return ""; ret ~= RMW_Undoc(Inc("data"), SubBase(env), env);
break;
} }
return ret ~ Done(env); return ret ~ Done(env);
} }
@ -497,8 +517,7 @@ string Jump(Env env)
bool nmos = env.nmos; bool nmos = env.nmos;
if (env.op == 0x4c) if (env.op == 0x4c)
return Address(env) ~ return _PC ~ " = address;\n";
_PC ~ " = address;\n";
else if (env.op == 0x6c) else if (env.op == 0x6c)
return ReadWordOp("ushort", "base", env) ~ return ReadWordOp("ushort", "base", env) ~
If!(cmos)( If!(cmos)(
@ -531,10 +550,9 @@ string Branch(string check, Env env)
string Nop(Env env) string Nop(Env env)
{ {
if (env.mode == IMP || env.mode == NP1 || env.mode == NP8) if (env.mode == IMP || env.mode == NP1 || env.mode == NP8)
return Address(env); return ""; // XXX add np1/np8 stuff
else else
return Address(env) ~ return PreAccess(env) ~
PreAccess(env) ~
ReadRaw("address") ~ ";\n"; ReadRaw("address") ~ ";\n";
} }
@ -562,24 +580,26 @@ string PushReg(string reg, Env env)
string Load(string reg, Env env) string Load(string reg, Env env)
{ {
return Address(env) ~ return ReadInto(reg, "address", env) ~
ReadInto(reg, "address", env) ~
SetNZ(reg); SetNZ(reg);
} }
string Store(string reg, Env env) string Store(string reg, Env env)
{ {
return Address(env) ~ return Write("address", reg, env);
Write("address", reg, env);
} }
string Compare(string reg, Env env) string Compare(string reg, Env env)
{ {
return Address(env) ~ return ReadInto(Local("ubyte", "data"), "address", env) ~
ReadInto(Local("ubyte", "data"), "address", env) ~ CompareBase(reg, env);
UpdateFlag(_C, reg ~ " >= data") ~ }
string CompareBase(string reg, Env env)
{
return UpdateFlag(_C, reg ~ " >= data") ~
SetNZ("cast(ubyte)(" ~ reg ~ " - data)"); SetNZ("cast(ubyte)(" ~ reg ~ " - data)");
} }
@ -588,8 +608,7 @@ string Bit(Env env)
{ {
bool notImm = (env.mode != IMM); bool notImm = (env.mode != IMM);
return Address(env) ~ return ReadInto(Local("ubyte", "data"), "address", env) ~
ReadInto(Local("ubyte", "data"), "address", env) ~
If!(notImm)( If!(notImm)(
_N ~ " = data;\n" ~ _N ~ " = data;\n" ~
_V ~ " = ((data & 0x40) != 0);\n") ~ _V ~ " = ((data & 0x40) != 0);\n") ~
@ -599,17 +618,20 @@ string Bit(Env env)
string Logic(string action, Env env) string Logic(string action, Env env)
{ {
return Address(env) ~ return ReadInto(_A, action, "address", env) ~
ReadInto(_A, action, "address", env) ~
SetNZ(_A); SetNZ(_A);
} }
string Add(Env env) string Add(Env env)
{ {
return Address(env) ~ return ReadInto(Local("ubyte", "data"), "address", env) ~
ReadInto(Local("ubyte", "data"), "address", env) ~ AddBase(env);
"if (" ~ _D ~ ")\n{\n" ~ }
string AddBase(Env env)
{
return "if (" ~ _D ~ ")\n{\n" ~
DecAdd(env) ~ DecAdd(env) ~
"}\nelse\n{\n" ~ "}\nelse\n{\n" ~
HexAdd(env) ~ HexAdd(env) ~
@ -649,12 +671,16 @@ string DecAdd(Env env)
string Sub(Env env) string Sub(Env env)
{
return ReadInto(Local("ubyte", "data"), "address", env) ~
SubBase(env);
}
string SubBase(Env env)
{ {
bool nmos = env.nmos; bool nmos = env.nmos;
return Address(env) ~ return "if (" ~ _D ~ ")\n{\n" ~
ReadInto(Local("ubyte", "data"), "address", env) ~
"if (" ~ _D ~ ")\n{\n" ~
If!(nmos)(DecSubNMOS(), DecSubCMOS(env)) ~ If!(nmos)(DecSubNMOS(), DecSubCMOS(env)) ~
"}\nelse\n{\n" ~ "}\nelse\n{\n" ~
HexSub() ~ HexSub() ~
@ -768,8 +794,7 @@ string RMW(string action, Env env)
{ {
bool nmos = env.nmos; bool nmos = env.nmos;
return Address(env) ~ return ReadInto(Local("ubyte", "data"), "address", env) ~
ReadInto(Local("ubyte", "data"), "address", env) ~
If!(nmos)(Poke("address", "data", env), If!(nmos)(Poke("address", "data", env),
Peek("address", env)) ~ Peek("address", env)) ~
action ~ 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) string Local(string type)
{ {
version(OpFunctions) version(OpFunctions)
@ -823,7 +916,7 @@ string Address(Env env)
final switch (env.mode) final switch (env.mode)
{ {
case IMP: case IMP:
return ""; return AddrIMP(env);
case IMM: case IMM:
return AddrIMM(env); return AddrIMM(env);
case ZP: case ZP:
@ -853,7 +946,7 @@ string Address(Env env)
case NP1: case NP1:
return ""; return "";
case NP8: case NP8:
return Local("ushort", "address") ~ " = 0;"; return AddrNP8(env);
case KIL: case KIL:
return ""; return "";
} }
@ -926,6 +1019,18 @@ string AddrZPI(Env env)
ReadWordZP("ushort", "address", "base", 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) string CheckShortcut(string base, string addr, Env env)
{ {
bool nmos = env.nmos; bool nmos = env.nmos;

View File

@ -180,6 +180,6 @@ version(OpFunctions) mixin(OpBodies("65C02", vStrict, vCumulative));
void main() void main()
{ {
import std.stdio; import std.stdio;
writeln(OpBody(0x11, "65C02", true, false)); writeln(OpBody(0x11, "6502", true, false));
} }
+/ +/

View File

@ -55,5 +55,11 @@ void main()
0xb4, 0x94, 0x01, 0x21, 0x41, 0x61, 0xe1, 0xc1, 0xa1, 0x81, 0xb4, 0x94, 0x01, 0x21, 0x41, 0x61, 0xe1, 0xc1, 0xa1, 0x81,
0x11, 0x31, 0x51, 0x71, 0xf1, 0xd1, 0xb1, 0x91, 0xda, 0x5a, 0x11, 0x31, 0x51, 0x71, 0xf1, 0xd1, 0xb1, 0x91, 0xda, 0x5a,
0x7a, 0xfa, 0x89, 0x34, 0x3c, 0x1a, 0x3a, 0x80, 0x64, 0x74, 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]);
} }