diff --git a/src/d6502/base.d b/src/d6502/base.d index e33dce2..1085e19 100644 --- a/src/d6502/base.d +++ b/src/d6502/base.d @@ -135,14 +135,26 @@ class CpuBase(bool strict, bool cumulative) restore([0, 0, 0, 0, 0, 0xFF, 0, 0, 0, 0, 0, 1]); } - ubyte delegate(ushort addr) memoryRead; - void delegate(ushort addr, ubyte val) memoryWrite; + struct _Mem + { + ubyte delegate(ushort addr) read; + void delegate(ushort addr, ubyte val) write; + } + _Mem memory; + + struct _Clock + { + static if (cumulative) + void delegate(int cycles) tick; + else + void delegate() tick; + } + _Clock clock; + debug(disassemble) { string delegate(ushort addr) memoryName; } - static if (cumulative) void delegate(int cycles) tick; - else void delegate() tick; abstract void run(bool continuous); abstract void stop(); diff --git a/src/d6502/cpu.d b/src/d6502/cpu.d index 97895e5..a8e6356 100644 --- a/src/d6502/cpu.d +++ b/src/d6502/cpu.d @@ -60,8 +60,8 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) } final override void run(bool continuous) { - assert ((memoryRead !is null) && (memoryWrite !is null)); - assert (tick !is null); + assert ((memory.read !is null) && (memory.write !is null)); + assert (clock.tick !is null); continueExecution = continuous; do @@ -139,7 +139,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) push(statusByte); flag.interrupt = true; programCounter = readWord(vector, cast(ushort)(vector + 1)); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); } void doReset() @@ -150,7 +150,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) } else { - tick(); tick(); + clock.tick(); clock.tick(); } peek(STACK_BASE + stackPointer); @@ -165,35 +165,35 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) signalActive = testSignals(); programCounter = readWord(RESET_VECTOR, RESET_VECTOR + 1); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); } final ubyte read(ushort addr) { static if (cumulative) ++totalCycles; - else tick(); - return memoryRead(addr); + else clock.tick(); + return memory.read(addr); } final void write(ushort addr, ubyte val) { static if (cumulative) ++totalCycles; - else tick(); - memoryWrite(addr, val); + else clock.tick(); + memory.write(addr, val); } final void peek(ushort addr) { static if (cumulative) ++totalCycles; - else tick(); - static if (strict) memoryRead(addr); + else clock.tick(); + static if (strict) memory.read(addr); } final void poke(ushort addr, ubyte val) { static if (cumulative) ++totalCycles; - else tick(); - static if (strict) memoryWrite(addr, val); + else clock.tick(); + static if (strict) memory.write(addr, val); } final ubyte readFinal(ushort addr) @@ -461,7 +461,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) { string code = "peek(programCounter);\n"; code ~= (action == "") ? "" : (action ~ ";"); - static if (cumulative) code ~= "tick(totalCycles);\n"; + static if (cumulative) code ~= "clock.tick(totalCycles);\n"; return "override void opcode" ~ opcode ~ "()\n{\n" ~ code ~ "\n}\n"; } @@ -474,7 +474,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) { string code = "peek(programCounter);\n"; code ~= UpdateNZ(action); - static if (cumulative) code ~= "tick(totalCycles);\n"; + static if (cumulative) code ~= "clock.tick(totalCycles);\n"; return "override void opcode" ~ opcode ~ "()\n{\n" ~ code ~ "}\n"; } @@ -482,7 +482,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) { string code = "readByteOperand();\n" ~ "if (" ~ action ~ ") addrRelative(cast(byte)operand1);\n"; - static if (cumulative) code ~= "tick(totalCycles);\n"; + static if (cumulative) code ~= "clock.tick(totalCycles);\n"; return "override void opcode" ~ opcode ~ "()\n{\n" ~ code ~ "}\n"; } @@ -719,7 +719,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) pushWord(programCounter); finalAddress |= ((operand2 = read(programCounter)) << 8); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); programCounter = finalAddress; } @@ -729,14 +729,14 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) peek(programCounter); flag.fromByte(pull()); programCounter = readStack() | (readStack() << 8); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); } /* JMP $$$$ */ final override void opcode4C() { programCounter = readWordOperand(); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); } /* RTS */ @@ -745,7 +745,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative) peek(programCounter); programCounter = pullWord(); peek(programCounter); - static if (cumulative) tick(totalCycles); + static if (cumulative) clock.tick(totalCycles); ++programCounter; } } diff --git a/src/system/base.d b/src/system/base.d index b2ecda4..2e6328a 100644 --- a/src/system/base.d +++ b/src/system/base.d @@ -133,10 +133,10 @@ class System { cpu = newCpu(); debug(disassemble) cpu.memoryName = &decoder.memoryReadName; - cpu.tick = &timer.tick; + cpu.clock.tick = &timer.tick; timer.onPrimaryStop(&primaryStop); - cpu.memoryRead = &decoder.read; - cpu.memoryWrite = &decoder.write; + cpu.memory.read = &decoder.read; + cpu.memory.write = &decoder.write; } void initIO(ubyte[] vidRom) diff --git a/test/cpu.d b/test/cpu.d index 796c446..85f5bbd 100644 --- a/test/cpu.d +++ b/test/cpu.d @@ -80,9 +80,9 @@ if (isCpu!T) else void tick() {} - cpu.memoryRead = &mem.read; - cpu.memoryWrite = &mem.write; - cpu.tick = &tick; + cpu.memory.read = &mem.read; + cpu.memory.write = &mem.write; + cpu.clock.tick = &tick; } @@ -99,7 +99,7 @@ auto recordCycles(T)(T cpu) if (isCpu!T) { auto cycles = new int; - auto wrappedTick = cpu.tick; + auto wrappedTick = cpu.clock.tick; static if (isCumulative!T) { @@ -117,7 +117,7 @@ if (isCpu!T) wrappedTick(); } } - cpu.tick = &tick; + cpu.clock.tick = &tick; return constRef(cycles); } @@ -155,9 +155,9 @@ if (isCpu!T) auto record = new Bus[actions]; int c; - enforce(cpu.memoryRead !is null && cpu.memoryWrite !is null); - auto wrappedRead = cpu.memoryRead; - auto wrappedWrite = cpu.memoryWrite; + enforce(cpu.memory.read !is null && cpu.memory.write !is null); + auto wrappedRead = cpu.memory.read; + auto wrappedWrite = cpu.memory.write; ubyte read(ushort addr) { @@ -177,8 +177,8 @@ if (isCpu!T) wrappedWrite(addr, val); } - cpu.memoryRead = &read; - cpu.memoryWrite = &write; + cpu.memory.read = &read; + cpu.memory.write = &write; return record; } @@ -210,8 +210,8 @@ enum Action : ushort { NONE, READ, WRITE } void runUntilBRK(T)(T cpu) if (isCpu!T) { - assert(cpu.memoryRead !is null); - auto wrappedRead = cpu.memoryRead; + assert(cpu.memory.read !is null); + auto wrappedRead = cpu.memory.read; ubyte read(ushort addr) { @@ -219,7 +219,7 @@ if (isCpu!T) return wrappedRead(addr); } - cpu.memoryRead = &read; + cpu.memory.read = &read; try { cpu.run(true); } catch (StopException e) {} }