diff --git a/test/cpu.d b/test/cpu.d index 85f5bbd..3ba9e9a 100644 --- a/test/cpu.d +++ b/test/cpu.d @@ -8,38 +8,37 @@ module test.cpu; import std.conv, std.exception, std.random, std.string, std.traits; -public import d6502.nmosundoc : NmosUndoc; -public import d6502.cmos : Cmos; +public import cpu6502 : Cpu, is6502, is65C02; // True if T is the type of a cpu. template isCpu(T) { - enum isCpu = __traits(hasMember, T, "_isCpuBase"); + enum isCpu = __traits(hasMember, T, "_isCpu"); } // True if the cpu type T represents a 6502. template isNMOS(T) { - enum isNMOS = __traits(hasMember, T, "_isNMOS"); + enum isNMOS = is6502!T; } // True if the cpu type T represents a 65C02. template isCMOS(T) { - enum isCMOS = __traits(hasMember, T, "_isCMOS"); + enum isCMOS = is65C02!T; } // True if the cpu type T accesses memory on every cycle. template isStrict(T) { - enum isStrict = __traits(hasMember, T, "_isStrict"); + enum isStrict = isCpu!T && __traits(getMember, T, "_isStrict"); } // True if the cpu type T aggregates ticks. template isCumulative(T) { - enum isCumulative = __traits(hasMember, T, "_isCumulative"); + enum isCumulative = isCpu!T && __traits(getMember, T, "_isCumulative"); } @@ -50,11 +49,7 @@ template isCumulative(T) */ template CPU(string arch, bool strict, bool cumulative) { - static if (arch == "65c02" || arch == "65C02") - alias Cmos!(strict, cumulative) CPU; - else static if (arch == "6502") - alias NmosUndoc!(strict, cumulative) CPU; - else static assert(0); + alias Cpu!(arch, strict, cumulative) CPU; } @@ -62,12 +57,12 @@ auto makeCpu(T)(CpuInfo info) if (isCpu!T) { auto cpu = new T(); - cpu.programCounter = info.PC; - cpu.stackPointer = info.SP; - cpu.flag.fromByte(info.S); - cpu.accumulator = info.A; - cpu.xIndex = info.X; - cpu.yIndex = info.Y; + cpu.PC = info.PC; + cpu.S = info.SP; + cpu.statusFromByte(info.S); + cpu.A = info.A; + cpu.X = info.X; + cpu.Y = info.Y; return cpu; } @@ -251,25 +246,20 @@ struct CpuInfo static CpuInfo fromCpu(T)(T cpu) { CpuInfo info; - info.PC = cpu.programCounter; - info.SP = cpu.stackPointer; - info.A = cpu.accumulator; - info.X = cpu.xIndex; - info.Y = cpu.yIndex; - info.S = cpu.flag.toByte(); + info.PC = cpu.PC; + info.SP = cpu.S; + info.A = cpu.A; + info.X = cpu.X; + info.Y = cpu.Y; + info.S = cpu.statusToByte(); return info; } } // Sets the program counter. -void setPC(T)(T cpu, int addr) -if (isCpu!T) -{ - cpu.programCounter = cast(ushort)addr; -} - -void setPC(T : CpuInfo)(ref T cpu, int addr) +void setPC(T)(ref T cpu, int addr) +if (isCpu!T || is(T == CpuInfo)) { cpu.PC = cast(ushort)addr; } @@ -279,14 +269,10 @@ void incPC(T : CpuInfo)(ref T cpu, int amt = 1) cpu.PC = pageCrossAdd(cpu.PC, amt); } -// Returns the program counter. -ushort getPC(T)(T cpu) -if (isCpu!T) -{ - return cpu.programCounter; -} -ushort getPC(T : CpuInfo)(ref T cpu) +// Returns the program counter. +ushort getPC(T)(ref T cpu) +if (isCpu!T || is(T == CpuInfo)) { return cpu.PC; } @@ -302,7 +288,7 @@ void setSP(T)(T cpu, int val) if (isCpu!T) { assert(val < 0x0200); - cpu.stackPointer = cast(ubyte)val; + cpu.S = cast(ubyte)val; } void setSP(T : CpuInfo)(ref T cpu, int val) @@ -329,7 +315,7 @@ void decSP(T : CpuInfo)(ref T cpu, int amt = -1) ushort getSP(T)(T cpu) if (isCpu!T) { - return 0x100 | cpu.stackPointer; + return 0x100 | cpu.S; } ushort getSP(T : CpuInfo)(ref T cpu) @@ -369,75 +355,48 @@ if (isCpu!T || is(T == CpuInfo)) } // Sets the A register. -void setA(T)(T cpu, int val) -if (isCpu!T) -{ - cpu.accumulator = cast(ubyte)val; -} - -void setA(T : CpuInfo)(ref T cpu, int val) +void setA(T)(ref T cpu, int val) +if (isCpu!T || is(T == CpuInfo)) { cpu.A = cast(ubyte)val; } -// Returns the A register. -ubyte getA(T)(T cpu, int val) -if (isCpu!T) -{ - return cpu.accumulator; -} -ubyte getA(T : CpuInfo)(ref T cpu) +// Returns the A register. +ubyte getA(T)(ref T cpu) +if (isCpu!T || is(T == CpuInfo)) { return cpu.A; } // Sets the X register. -void setX(T)(T cpu, int val) -if (isCpu!T) -{ - cpu.xIndex = cast(ubyte)val; -} - -void setX(T : CpuInfo)(ref T cpu, int val) +void setX(T)(ref T cpu, int val) +if (isCpu!T || is(T == CpuInfo)) { cpu.X = cast(ubyte)val; } -// Returns the X register. -ubyte getX(T)(T cpu) -if (isCpu!T) -{ - return cpu.xIndex; -} -ubyte getX(T : CpuInfo)(ref T cpu) +// Returns the X register. +ubyte getX(T)(ref T cpu) +if (isCpu!T || is(T == CpuInfo)) { return cpu.X; } // Sets the Y register. -void setY(T)(T cpu, int val) -if (isCpu!T) -{ - cpu.yIndex = cast(ubyte)val; -} - -void setY(T : CpuInfo)(ref T cpu, int val) +void setY(T)(ref T cpu, int val) +if (isCpu!T || is(T == CpuInfo)) { cpu.Y = cast(ubyte)val; } -// Returns the Y register. -ubyte getY(T)(T cpu) -if (isCpu!T) -{ - return cpu.yIndex; -} -ubyte getY(T : CpuInfo)(ref T cpu) +// Returns the Y register. +ubyte getY(T)(ref T cpu) +if (isCpu!T || is(T == CpuInfo)) { return cpu.Y; } @@ -472,9 +431,9 @@ string flagToString(Flag f) void setFlag(T)(T cpu, Flag[] flags...) if (isCpu!T) { - auto reg = cpu.flag.toByte(); + auto reg = cpu.statusToByte(); foreach (flag; flags) reg |= flag; - cpu.flag.fromByte(reg); + cpu.statusFromByte(reg); } void setFlag(T : CpuInfo)(ref T cpu, Flag[] flags...) @@ -486,9 +445,9 @@ void setFlag(T : CpuInfo)(ref T cpu, Flag[] flags...) void clearFlag(T)(T cpu, Flag[] flags...) if (isCpu!T) { - auto reg = cpu.flag.toByte(); + auto reg = cpu.statusToByte(); foreach (flag; flags) reg &= ~flag; - cpu.flag.fromByte(reg); + cpu.statusFromByte(reg); } void clearFlag(T : CpuInfo)(ref T cpu, Flag[] flags...) @@ -500,7 +459,8 @@ void clearFlag(T : CpuInfo)(ref T cpu, Flag[] flags...) bool getFlag(T)(T cpu, Flag f) if (isCpu!T) { - return (cpu.flag.toByte() & f) != 0; + return (cpu.statusToByte() & f) != 0; + return false; } bool getFlag(T : CpuInfo)(ref T cpu, Flag f) @@ -513,7 +473,7 @@ bool getFlag(T : CpuInfo)(ref T cpu, Flag f) void setStatus(T)(T cpu, int val) if (isCpu!T) { - cpu.flag.fromByte(cast(ubyte)val); + cpu.statusFromByte(cast(ubyte)val); } void setStatus(T : CpuInfo)(ref T cpu, int val) @@ -525,7 +485,8 @@ void setStatus(T : CpuInfo)(ref T cpu, int val) ubyte getStatus(T)(T cpu) if (isCpu!T) { - return cpu.flag.toByte(); + return cpu.statusToByte(); + return 0; } ubyte getStatus(T : CpuInfo)(ref T cpu) @@ -604,8 +565,6 @@ if (isCpu!T || is(T == CpuInfo)) case /*BNE*/ 0xD0: setFlag(cpu, Flag.Z); break; case /*BEQ*/ 0xF0: clearFlag(cpu, Flag.Z); break; default: - if (isCMOS!T) - enforce(opcode != 0x80, "BRA can never not branch"); enforce(0, format("not a branching opcpde %0.2X", opcode)); } }