Playing with cpu/world interface

This commit is contained in:
edmccard 2012-04-06 20:44:58 -04:00
parent 9a758781b5
commit 700722c5de
4 changed files with 52 additions and 40 deletions

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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) {}
}