mirror of
https://github.com/edmccard/twoapple-reboot.git
synced 2024-05-28 20:41:28 +00:00
test framework update
This commit is contained in:
parent
a5334508e2
commit
a2af6f0bd2
1227
test/base.d
1227
test/base.d
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +1,2 @@
|
||||||
-unittest -I.. -I../src -inline -release -O
|
-unittest -I.. -I../src -g
|
||||||
|
|
||||||
|
|
|
@ -213,10 +213,13 @@ if (isCpu!T)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cpu = makeCpu!T(mem);
|
auto cpu = makeCpu!T(mem);
|
||||||
cpu.programCounter = 0x8000;
|
setPC(cpu, 0x8000);
|
||||||
runUntilBRK(cpu);
|
runUntilBRK(cpu);
|
||||||
if (mem[0x8003])
|
if (mem[0x8003])
|
||||||
|
{
|
||||||
|
// TODO: check data block to find out what failed exactly
|
||||||
throw new TestException("failed decimal mode " ~ T.stringof);
|
throw new TestException("failed decimal mode " ~ T.stringof);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
158
test/wrap6502.d
Normal file
158
test/wrap6502.d
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user