Make testing use same memory/clock interface as normal operation.
This commit is contained in:
parent
cf369d4d2b
commit
a4af7191be
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
56
test/cpu.d
56
test/cpu.d
|
@ -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) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue