test framework update

This commit is contained in:
edmccard 2012-03-25 04:25:41 -04:00
parent a5334508e2
commit a2af6f0bd2
4 changed files with 1266 additions and 126 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
-unittest -I.. -I../src -inline -release -O
-unittest -I.. -I../src -g

View File

@ -213,10 +213,13 @@ if (isCpu!T)
}
auto cpu = makeCpu!T(mem);
cpu.programCounter = 0x8000;
setPC(cpu, 0x8000);
runUntilBRK(cpu);
if (mem[0x8003])
{
// TODO: check data block to find out what failed exactly
throw new TestException("failed decimal mode " ~ T.stringof);
}
}

158
test/wrap6502.d Normal file
View File

@ -0,0 +1,158 @@
module test.wrap6502;
public import d6502.nmosundoc : NmosUndoc;
public import d6502.cmos : Cmos;
import test.base;
// True if T is the type of a cpu.
template isCpu(T)
{
enum isCpu = __traits(hasMember, T, "_isCpuBase");
}
// True if the cpu type T represents a 6502.
template isNMOS(T)
{
enum isNMOS = __traits(hasMember, T, "_isNMOS");
}
// True if the cpu type T represents a 65C02.
template isCMOS(T)
{
enum isCMOS = __traits(hasMember, T, "_isCMOS");
}
// True if the cpu type T accesses memory on every cycle.
template isStrict(T)
{
enum isStrict = __traits(hasMember, T, "_isStrict");
}
// True if the cpu type T
template isCumulative(T)
{
enum isCumulative = __traits(hasMember, T, "_isCumulative");
}
template CPU(string type, bool strict, bool cumulative)
{
static if (type == "65c02" || type == "65C02")
alias Cmos!(strict, cumulative) CPU;
else static if (type == "6502")
alias NmosUndoc!(strict, cumulative) CPU;
else static assert(0);
}
/*
* Connects a cpu and memory.
*/
void connectCpu(T)(T cpu, ref TestMemory mem)
if (isCpu!T)
{
static if (isCumulative!T)
void tick(int cycles) {}
else
void tick() {}
cpu.memoryRead = &mem.read;
cpu.memoryWrite = &mem.write;
cpu.tick = &tick;
}
class StopException : Exception { this(string msg) { super(msg); } }
void runUntilBRK(T)(T cpu)
if (isCpu!T)
{
assert(cpu.memoryRead !is null);
auto wrappedRead = cpu.memoryRead;
ubyte read(ushort addr)
{
if (addr == 0xFFFE) throw new StopException("BRK");
return wrappedRead(addr);
}
cpu.memoryRead = &read;
try { cpu.run(true); } catch (StopException e) {}
}
void runOneOpcode(T)(T cpu)
if (isCpu!T)
{
cpu.run(false);
}
void setPC(T)(T cpu, int addr)
if (isCpu!T)
{
cpu.programCounter = cast(ushort)addr;
}
ushort getPC(T)(T cpu)
if (isCpu!T)
{
return cpu.programCounter;
}
void setSP(T)(T cpu, int val)
if (isCpu!T)
{
cpu.stackPointer = cast(ubyte)val;
}
ushort getSP(T)(T cpu)
if (isCpu!T)
{
return 0x100 | cpu.stackPointer;
}
void setX(T)(T cpu, int val)
if (isCpu!T)
{
cpu.xIndex = cast(ubyte)val;
}
ubyte getX(T)(T cpu)
if (isCpu!T)
{
return cpu.xIndex;
}
void setY(T)(T cpu, int val)
if (isCpu!T)
{
cpu.yIndex = cast(ubyte)val;
}
ubyte getY(T)(T cpu)
if (isCpu!T)
{
return cpu.yIndex;
}
void setFlag(T)(T cpu, Flag f)
if (isCpu!T)
{
cpu.flag.fromByte(cpu.flag.toByte() | f);
}
void clearFlag(T)(T cpu, Flag f)
if (isCpu!T)
{
cpu.flag.fromByte(cpu.flag.toByte() & ~f);
}
bool getFlag(T)(T cpu, Flag f)
if (isCpu!T)
{
return (cpu.flag.toByte() & f) != 0;
}