remove stupid jscript dependency in core emulator
This commit is contained in:
parent
3c9cb66523
commit
35f339149c
|
@ -115,8 +115,6 @@
|
|||
<Compile Include="CPUs\ARM\ARM.ExecuteCore.cs" />
|
||||
<Compile Include="CPUs\ARM\ARM.ExecuteThumb.cs" />
|
||||
<Compile Include="CPUs\ARM\ARM.Pseudocode.cs" />
|
||||
<Compile Include="CPUs\ARM\decoder\decoder.cs" />
|
||||
<Compile Include="CPUs\ARM\decoder\scripting.cs" />
|
||||
<Compile Include="CPUs\ARM\_.cs" />
|
||||
<Compile Include="CPUs\HuC6280\Disassembler.cs" />
|
||||
<Compile Include="CPUs\HuC6280\Execute.cs" />
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -752,33 +752,83 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return ExecuteCore_ADD_SP_plus_immedate(Encoding.T1, d, setflags, imm32);
|
||||
}
|
||||
|
||||
Decoder decoder_ExecuteThumb_Misc16 = new Decoder();
|
||||
uint ExecuteThumb_Misc16()
|
||||
{
|
||||
decoder_ExecuteThumb_Misc16.Ensure(() => decoder_ExecuteThumb_Misc16
|
||||
.d("opcode", 7)
|
||||
.r("opcode == #0110010", () => Execute_Unhandled("SETEND on page A8-314"))
|
||||
.r("opcode == #0110011", () => Execute_Unhandled("CPS on page B6-3"))
|
||||
.r("opcode == #00000xx", () => Execute_ADD_SP_plus_immediate_T2())
|
||||
.r("opcode == #00001xx", () => Execute_SUB_SP_minus_immediate_T1())
|
||||
.r("opcode == #0001xxx", () => Execute_Unhandled("CBNZ,CBZ on page A8-66 [v6T2]"))
|
||||
.r("opcode == #001000x", () => Execute_Unhandled("SXTH on page A8-444"))
|
||||
.r("opcode == #001001x", () => Execute_Unhandled("SXTB on page A8-440"))
|
||||
.r("opcode == #001010x", () => Execute_UXTH_T1())
|
||||
.r("opcode == #001011x", () => Execute_UXTB_T1())
|
||||
.r("opcode == #0011xxx", () => Execute_Unhandled("CBNZ,CBZ on page A8-66 [v6T2]"))
|
||||
.r("opcode == #010xxxx", () => Execute_PUSH_T1())
|
||||
.r("opcode == #1001xxx", () => Execute_Unhandled("CBNZ,CBZ on page A8-66 [v6T2]"))
|
||||
.r("opcode == #101000x", () => Execute_Unhandled("REV on page A8-272"))
|
||||
.r("opcode == #101001x", () => Execute_Unhandled("REV16 on page A8-274"))
|
||||
.r("opcode == #101011x", () => Execute_Unhandled("REVSH on page A8-276"))
|
||||
.r("opcode == #110xxxx", () => Execute_POP_T1())
|
||||
.r("opcode == #1110xxx", () => Execute_Unhandled("BKPT on page A8-56"))
|
||||
.r("opcode == #1111xxx", () => Execute_Unhandled("If-Then and hints on page A6-12"))
|
||||
);
|
||||
|
||||
uint opcode = (instruction >> 5) & 0x7F;
|
||||
decoder_ExecuteThumb_Misc16.Evaluate(opcode);
|
||||
|
||||
//ThumbMisc
|
||||
switch((opcode<<0)) {
|
||||
//opcode == #0110010
|
||||
case 50:
|
||||
Execute_Unhandled("SETEND on page A8-314");
|
||||
break;
|
||||
//opcode == #0110011
|
||||
case 51:
|
||||
Execute_Unhandled("CPS on page B6-3");
|
||||
break;
|
||||
//opcode == #00000xx
|
||||
case 0: case 1: case 2: case 3:
|
||||
Execute_ADD_SP_plus_immediate_T2();
|
||||
break;
|
||||
//opcode == #00001xx
|
||||
case 4: case 5: case 6: case 7:
|
||||
Execute_SUB_SP_minus_immediate_T1();
|
||||
break;
|
||||
//opcode == #0001xxx
|
||||
//opcode == #0011xxx
|
||||
//opcode == #1001xxx
|
||||
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79:
|
||||
Execute_Unhandled("CBNZ,CBZ on page A8-66 [v6T2]");
|
||||
break;
|
||||
//opcode == #001000x
|
||||
case 16: case 17:
|
||||
Execute_Unhandled("SXTH on page A8-444");
|
||||
break;
|
||||
//opcode == #001001x
|
||||
case 18: case 19:
|
||||
Execute_Unhandled("SXTB on page A8-440");
|
||||
break;
|
||||
//opcode == #001010x
|
||||
case 20: case 21:
|
||||
Execute_UXTH_T1();
|
||||
break;
|
||||
//opcode == #001011x
|
||||
case 22: case 23:
|
||||
Execute_UXTB_T1();
|
||||
break;
|
||||
//opcode == #010xxxx
|
||||
case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47:
|
||||
Execute_PUSH_T1();
|
||||
break;
|
||||
//opcode == #101000x
|
||||
case 80: case 81:
|
||||
Execute_Unhandled("REV on page A8-272");
|
||||
break;
|
||||
//opcode == #101001x
|
||||
case 82: case 83:
|
||||
Execute_Unhandled("REV16 on page A8-274");
|
||||
break;
|
||||
//opcode == #101011x
|
||||
case 86: case 87:
|
||||
Execute_Unhandled("REVSH on page A8-276");
|
||||
break;
|
||||
//opcode == #110xxxx
|
||||
case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: case 110: case 111:
|
||||
Execute_POP_T1();
|
||||
break;
|
||||
//opcode == #1110xxx
|
||||
case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119:
|
||||
Execute_Unhandled("BKPT on page A8-56");
|
||||
break;
|
||||
//opcode == #1111xxx
|
||||
case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127:
|
||||
Execute_Unhandled("If-Then and hints on page A6-12");
|
||||
break;
|
||||
default: throw new InvalidOperationException("unhandled case for switch ThumbMisc");
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class BS
|
||||
{
|
||||
public BS(string str)
|
||||
{
|
||||
ca = str.ToCharArray();
|
||||
Array.Reverse(ca);
|
||||
}
|
||||
char[] ca;
|
||||
public static bool operator ==(uint lhs, BS rhs) { return rhs == lhs; }
|
||||
public static bool operator !=(uint lhs, BS rhs) { return rhs != lhs; }
|
||||
public static bool operator ==(int lhs, BS rhs) { return rhs == (uint)lhs; }
|
||||
public static bool operator !=(int lhs, BS rhs) { return rhs != (uint)lhs; }
|
||||
public static bool operator ==(BS lhs, int rhs) { return (uint)rhs == lhs; }
|
||||
public static bool operator !=(BS lhs, int rhs) { return (uint)rhs != lhs; }
|
||||
public static bool operator ==(BS lhs, uint rhs)
|
||||
{
|
||||
foreach (char c in lhs.ca)
|
||||
{
|
||||
uint bit = rhs & 1;
|
||||
switch (c)
|
||||
{
|
||||
case '0': if (bit != 0) return false; break;
|
||||
case '1': if (bit != 1) return false; break;
|
||||
}
|
||||
rhs >>= 1;
|
||||
}
|
||||
if(rhs != 0) return false;
|
||||
return true;
|
||||
}
|
||||
public static bool operator !=(BS lhs, uint rhs) { return !(lhs == rhs); }
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is uint) return this == (uint)obj;
|
||||
if (obj is int) return this == (int)obj;
|
||||
if (obj is BS) throw new InvalidOperationException();
|
||||
return false;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ca.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
class Decoder
|
||||
{
|
||||
bool constructed = false;
|
||||
public void Ensure(Action constructor)
|
||||
{
|
||||
if (constructed) return;
|
||||
constructed = true;
|
||||
constructor();
|
||||
Compile();
|
||||
}
|
||||
|
||||
//public Decoder(params object[] args)
|
||||
//{
|
||||
// if(args.Length %2 != 0) throw new ArgumentException("need odd params to Decoder");
|
||||
|
||||
// for(int i=0;i<args.Length/2;i++)
|
||||
// {
|
||||
// string str = (string)args[i * 2];
|
||||
// object o = args[i * 2 + 1];
|
||||
// if (o is int)
|
||||
// Declare(str, (int)o);
|
||||
// else AddRule(str, (Action)o);
|
||||
// }
|
||||
//}
|
||||
|
||||
class Rule
|
||||
{
|
||||
public Rule(string program,Action action)
|
||||
{
|
||||
this.program = program;
|
||||
this.action = action;
|
||||
}
|
||||
public string program;
|
||||
public Action action;
|
||||
}
|
||||
public void AddRule(string rule, Action action)
|
||||
{
|
||||
rules.Add(new Rule(rule,action));
|
||||
}
|
||||
public Decoder r(string rule, Action action)
|
||||
{
|
||||
AddRule(rule, action);
|
||||
return this;
|
||||
}
|
||||
|
||||
List<Rule> rules = new List<Rule>();
|
||||
|
||||
class Variable
|
||||
{
|
||||
public Variable(string name, int bits)
|
||||
{
|
||||
this.name = name;
|
||||
this.bits = bits;
|
||||
}
|
||||
public string name;
|
||||
public int bits;
|
||||
}
|
||||
List<Variable> variables = new List<Variable>();
|
||||
|
||||
public void Declare(string name, int bits)
|
||||
{
|
||||
variables.Add(new Variable(name, bits));
|
||||
}
|
||||
public Decoder d(string name, int bits)
|
||||
{
|
||||
Declare(name, bits);
|
||||
return this;
|
||||
}
|
||||
|
||||
static Regex rxBits = new Regex(@"(\#([01xX]*))", RegexOptions.Compiled);
|
||||
bool compiled = false;
|
||||
|
||||
public void Compile()
|
||||
{
|
||||
if (compiled) return;
|
||||
compiled = true;
|
||||
int numbits = 0;
|
||||
ScriptEngine se = new ScriptEngine();
|
||||
foreach (Variable v in variables) numbits += v.bits;
|
||||
int cases = 1 << numbits;
|
||||
for (uint i = 0; i < cases; i++)
|
||||
{
|
||||
//split apart key
|
||||
uint itemp = i;
|
||||
for (int j = 0; j < variables.Count; j++)
|
||||
{
|
||||
Variable v = variables[j];
|
||||
uint x = (uint)(itemp & ((1 << v.bits)-1));
|
||||
itemp >>= v.bits;
|
||||
se.variables[v.name] = x;
|
||||
}
|
||||
|
||||
//default table value is an exception
|
||||
table[i] = () => { throw new InvalidOperationException("auto-decoder fail (missing case)"); };
|
||||
|
||||
foreach (Rule rule in rules)
|
||||
{
|
||||
string program = rule.program;
|
||||
foreach (Match m in rxBits.Matches(program))
|
||||
program = program.Replace(m.Value, "new BS(\"" + m.Groups[2].Value + "\")");
|
||||
object o = se.Eval(program);
|
||||
bool? b = o as bool?;
|
||||
if(!b.HasValue) throw new InvalidOperationException();
|
||||
if (b.Value)
|
||||
{
|
||||
table[i] = rule.action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
se.Dispose();
|
||||
}
|
||||
|
||||
//TODO - make overloads for different param number (array create overhead will be high)
|
||||
public void Evaluate(params uint[] args)
|
||||
{
|
||||
Compile();
|
||||
uint key = 0;
|
||||
for (int i = variables.Count-1; i >= 0; i--)
|
||||
{
|
||||
Variable v = variables[i];
|
||||
key <<= v.bits;
|
||||
if (args[i] > (1 << v.bits))
|
||||
throw new ArgumentException();
|
||||
key |= args[i];
|
||||
}
|
||||
table[key]();
|
||||
}
|
||||
|
||||
Dictionary<uint, Action> table = new Dictionary<uint, Action>();
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Microsoft.JScript;
|
||||
using Microsoft.JScript.Vsa;
|
||||
using Microsoft.Vsa;
|
||||
|
||||
#pragma warning disable 0618
|
||||
|
||||
class ScriptEngine : IDisposable
|
||||
{
|
||||
string[] commonNamespaces =
|
||||
{
|
||||
"System"
|
||||
};
|
||||
|
||||
string[] commonAssemblies =
|
||||
{
|
||||
"mscorlib.dll",
|
||||
"System.dll",
|
||||
System.Reflection.Assembly.GetExecutingAssembly().Location
|
||||
};
|
||||
|
||||
|
||||
VsaEngine engine;
|
||||
//Microsoft.JScript.GlobalScope jscriptGlobalScope = null;
|
||||
|
||||
public Dictionary<string, object> variables = new Dictionary<string, object>();
|
||||
|
||||
class MySite : Microsoft.Vsa.BaseVsaSite
|
||||
{
|
||||
ScriptEngine se;
|
||||
public MySite(ScriptEngine se)
|
||||
{
|
||||
this.se = se;
|
||||
}
|
||||
public override object GetGlobalInstance(string name)
|
||||
{
|
||||
return se.variables[name];
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptEngine()
|
||||
{
|
||||
InitializeJScriptDotNetEngine();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UninitializeJScriptDotNetEngine();
|
||||
}
|
||||
|
||||
bool hasVariables = false;
|
||||
public object Eval(string script)
|
||||
{
|
||||
if (!hasVariables)
|
||||
{
|
||||
hasVariables = true;
|
||||
foreach (KeyValuePair<string, object> kvp in variables)
|
||||
{
|
||||
IVsaGlobalItem globItem = (IVsaGlobalItem)engine.Items.CreateItem(kvp.Key, VsaItemType.AppGlobal, VsaItemFlag.None);
|
||||
globItem.TypeString = kvp.Value.GetType().FullName;
|
||||
}
|
||||
engine.CompileEmpty();
|
||||
engine.RunEmpty();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (KeyValuePair<string, object> kvp in variables)
|
||||
sb.AppendFormat("{0} = {1};\n",kvp.Key,kvp.Value);
|
||||
sb.AppendLine(script);
|
||||
|
||||
object o = Microsoft.JScript.Eval.JScriptEvaluate(sb.ToString(), engine);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
private void UninitializeJScriptDotNetEngine()
|
||||
{
|
||||
|
||||
//if (jscriptGlobalScope != null)
|
||||
|
||||
// jscriptGlobalScope.engine.Close();
|
||||
|
||||
//jscriptGlobalScope = null;
|
||||
if(engine != null)
|
||||
engine.Close();
|
||||
engine = null;
|
||||
}
|
||||
|
||||
private void InitializeJScriptDotNetEngine()
|
||||
{
|
||||
|
||||
if (engine == null)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
engine = new VsaEngine();
|
||||
engine.InitVsaEngine("blah://x",new MySite(this));
|
||||
foreach (string str in commonAssemblies)
|
||||
{
|
||||
IVsaReferenceItem reference = (IVsaReferenceItem)engine.Items.CreateItem(str, VsaItemType.Reference, VsaItemFlag.None);
|
||||
reference.AssemblyName = str;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
catch { }
|
||||
|
||||
foreach (string ns in commonNamespaces)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if ((ns != null) && (ns != String.Empty))
|
||||
|
||||
Microsoft.JScript.Import.JScriptImport(ns, engine);
|
||||
|
||||
}
|
||||
|
||||
catch { }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue