Make testing use same memory/clock interface as normal operation.

This commit is contained in:
edmccard 2012-04-14 03:07:02 -04:00
parent cf369d4d2b
commit a4af7191be
4 changed files with 39 additions and 51 deletions

View File

@ -54,29 +54,8 @@ if (__traits(compiles, {
enum _isCpu = true; enum _isCpu = true;
enum _chip = (chip == "6502" ? "6502" : "65C02"); enum _chip = (chip == "6502" ? "6502" : "65C02");
version(RunTest)
{
struct _Mem
{
ubyte delegate(ushort addr) read;
void delegate(ushort addr, ubyte val) write;
}
_Mem memory;
struct _Clock
{
version(Cumulative)
void delegate(int cycles) tick;
else
void delegate() tick;
}
_Clock clock;
}
else
{
MEM memory; MEM memory;
CLK clock; CLK clock;
}
ubyte A, X, Y, S; ubyte A, X, Y, S;
ushort PC; ushort PC;
@ -95,12 +74,9 @@ else
this(MEM memory, CLK clock) this(MEM memory, CLK clock)
{ {
version(RunTest) {} this.memory = memory;
else this.clock = clock;
{
this.memory = memory;
this.clock = clock;
}
version(OpDelegates) mixin(OpArrayInit()); version(OpDelegates) mixin(OpArrayInit());
} }

View File

@ -32,29 +32,41 @@ template isCMOS(T)
} }
// Not used in test mode, but needed to instantiate a cpu. class TestIO
class DummyMem
{ {
ubyte read(ushort) { return 0; } ubyte delegate(ushort) dread;
void write(ushort, ubyte) {} ubyte read(ushort addr) { return dread(addr); }
static if (cumulative) { void tick(int) {} }
else { void tick() {} } void delegate(ushort, ubyte) dwrite;
void write(ushort addr, ubyte val) { dwrite(addr, val); }
static if (cumulative)
{
void delegate(int) dtick;
void tick(int cycles) { dtick(cycles); }
}
else
{
void delegate() dtick;
void tick() { dtick(); }
}
} }
/* /*
* The type of a cpu, based on its architecture (6502 or 65C02). * The type of a cpu, based on its architecture (6502 or 65C02).
*/ */
template CPU(string arch, M = DummyMem, C = DummyMem) template CPU(string arch, M = TestIO, C = TestIO)
{ {
alias Cpu!(arch, M, C) CPU; alias Cpu!(arch, M, C) CPU;
} }
auto makeCpu(T)(CpuInfo info) auto makeCpu(T)(CpuInfo info = CpuInfo())
if (isCpu!T) if (isCpu!T)
{ {
auto cpu = new T(null, null); auto tio = new TestIO();
auto cpu = new T(tio, tio);
cpu.PC = info.PC; cpu.PC = info.PC;
cpu.S = info.SP; cpu.S = info.SP;
cpu.statusFromByte(info.S); cpu.statusFromByte(info.S);
@ -73,9 +85,9 @@ if (isCpu!T)
else else
void tick() {} void tick() {}
cpu.memory.read = &mem.read; cpu.memory.dread = &mem.read;
cpu.memory.write = &mem.write; cpu.memory.dwrite = &mem.write;
cpu.clock.tick = &tick; cpu.clock.dtick = &tick;
} }
@ -92,7 +104,7 @@ auto recordCycles(T)(T cpu)
if (isCpu!T) if (isCpu!T)
{ {
auto cycles = new int; auto cycles = new int;
auto wrappedTick = cpu.clock.tick; auto wrappedTick = cpu.clock.dtick;
static if (cumulative) static if (cumulative)
{ {
@ -110,7 +122,7 @@ if (isCpu!T)
wrappedTick(); wrappedTick();
} }
} }
cpu.clock.tick = &tick; cpu.clock.dtick = &tick;
return constRef(cycles); return constRef(cycles);
} }
@ -148,9 +160,9 @@ if (isCpu!T)
auto record = new Bus[actions]; auto record = new Bus[actions];
int c; int c;
enforce(cpu.memory.read !is null && cpu.memory.write !is null); enforce(cpu.memory.dread !is null && cpu.memory.dwrite !is null);
auto wrappedRead = cpu.memory.read; auto wrappedRead = cpu.memory.dread;
auto wrappedWrite = cpu.memory.write; auto wrappedWrite = cpu.memory.dwrite;
ubyte read(ushort addr) ubyte read(ushort addr)
{ {
@ -170,8 +182,8 @@ if (isCpu!T)
wrappedWrite(addr, val); wrappedWrite(addr, val);
} }
cpu.memory.read = &read; cpu.memory.dread = &read;
cpu.memory.write = &write; cpu.memory.dwrite = &write;
return record; return record;
} }
@ -203,8 +215,8 @@ enum Action : ushort { NONE, READ, WRITE }
void runUntilBRK(T)(T cpu) void runUntilBRK(T)(T cpu)
if (isCpu!T) if (isCpu!T)
{ {
assert(cpu.memory.read !is null); assert(cpu.memory.dread !is null);
auto wrappedRead = cpu.memory.read; auto wrappedRead = cpu.memory.dread;
ubyte read(ushort addr) ubyte read(ushort addr)
{ {
@ -212,7 +224,7 @@ if (isCpu!T)
return wrappedRead(addr); return wrappedRead(addr);
} }
cpu.memory.read = &read; cpu.memory.dread = &read;
try { cpu.run(true); } catch (StopException e) {} try { cpu.run(true); } catch (StopException e) {}
} }

View File

@ -134,7 +134,7 @@ void runTest(OpDefs def, Tests test, string[] args)
writeln("With strict=", s, " cumulative=", c); writeln("With strict=", s, " cumulative=", c);
string cmdline = defStrings[def] ~ stStrings[s] ~ cmStrings[c] ~ string cmdline = defStrings[def] ~ stStrings[s] ~ cmStrings[c] ~
fNames[test] ~ join(args, " "); fNames[test] ~ join(args, " ");
system("rdmd --force -I.. -I../src -version=RunTest" ~ cmdline); system("rdmd --force -I.. -I../src -version=RunTest " ~ cmdline);
} }
} }
} }

View File

@ -224,7 +224,7 @@ version(Benchmark)
} }
else else
{ {
auto cpu = new T(null, null); auto cpu = makeCpu!T();
setPC(cpu, 0x8000); setPC(cpu, 0x8000);
connectMem(cpu, mem); connectMem(cpu, mem);
runUntilBRK(cpu); runUntilBRK(cpu);