remove stupid jscript dependency in core emulator

This commit is contained in:
zeromus 2011-04-17 08:49:49 +00:00
parent 3c9cb66523
commit 35f339149c
5 changed files with 302 additions and 428 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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>();
}

View File

@ -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 { }
}
}
}
}