Playing with cpu/world interface
This commit is contained in:
parent
9a758781b5
commit
700722c5de
|
@ -135,14 +135,26 @@ class CpuBase(bool strict, bool cumulative)
|
||||||
restore([0, 0, 0, 0, 0, 0xFF, 0, 0, 0, 0, 0, 1]);
|
restore([0, 0, 0, 0, 0, 0xFF, 0, 0, 0, 0, 0, 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte delegate(ushort addr) memoryRead;
|
struct _Mem
|
||||||
void delegate(ushort addr, ubyte val) memoryWrite;
|
{
|
||||||
|
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)
|
debug(disassemble)
|
||||||
{
|
{
|
||||||
string delegate(ushort addr) memoryName;
|
string delegate(ushort addr) memoryName;
|
||||||
}
|
}
|
||||||
static if (cumulative) void delegate(int cycles) tick;
|
|
||||||
else void delegate() tick;
|
|
||||||
|
|
||||||
abstract void run(bool continuous);
|
abstract void run(bool continuous);
|
||||||
abstract void stop();
|
abstract void stop();
|
||||||
|
|
|
@ -60,8 +60,8 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
}
|
}
|
||||||
final override void run(bool continuous)
|
final override void run(bool continuous)
|
||||||
{
|
{
|
||||||
assert ((memoryRead !is null) && (memoryWrite !is null));
|
assert ((memory.read !is null) && (memory.write !is null));
|
||||||
assert (tick !is null);
|
assert (clock.tick !is null);
|
||||||
|
|
||||||
continueExecution = continuous;
|
continueExecution = continuous;
|
||||||
do
|
do
|
||||||
|
@ -139,7 +139,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
push(statusByte);
|
push(statusByte);
|
||||||
flag.interrupt = true;
|
flag.interrupt = true;
|
||||||
programCounter = readWord(vector, cast(ushort)(vector + 1));
|
programCounter = readWord(vector, cast(ushort)(vector + 1));
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doReset()
|
void doReset()
|
||||||
|
@ -150,7 +150,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tick(); tick();
|
clock.tick(); clock.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
peek(STACK_BASE + stackPointer);
|
peek(STACK_BASE + stackPointer);
|
||||||
|
@ -165,35 +165,35 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
signalActive = testSignals();
|
signalActive = testSignals();
|
||||||
|
|
||||||
programCounter = readWord(RESET_VECTOR, RESET_VECTOR + 1);
|
programCounter = readWord(RESET_VECTOR, RESET_VECTOR + 1);
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ubyte read(ushort addr)
|
final ubyte read(ushort addr)
|
||||||
{
|
{
|
||||||
static if (cumulative) ++totalCycles;
|
static if (cumulative) ++totalCycles;
|
||||||
else tick();
|
else clock.tick();
|
||||||
return memoryRead(addr);
|
return memory.read(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
final void write(ushort addr, ubyte val)
|
final void write(ushort addr, ubyte val)
|
||||||
{
|
{
|
||||||
static if (cumulative) ++totalCycles;
|
static if (cumulative) ++totalCycles;
|
||||||
else tick();
|
else clock.tick();
|
||||||
memoryWrite(addr, val);
|
memory.write(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
final void peek(ushort addr)
|
final void peek(ushort addr)
|
||||||
{
|
{
|
||||||
static if (cumulative) ++totalCycles;
|
static if (cumulative) ++totalCycles;
|
||||||
else tick();
|
else clock.tick();
|
||||||
static if (strict) memoryRead(addr);
|
static if (strict) memory.read(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
final void poke(ushort addr, ubyte val)
|
final void poke(ushort addr, ubyte val)
|
||||||
{
|
{
|
||||||
static if (cumulative) ++totalCycles;
|
static if (cumulative) ++totalCycles;
|
||||||
else tick();
|
else clock.tick();
|
||||||
static if (strict) memoryWrite(addr, val);
|
static if (strict) memory.write(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ubyte readFinal(ushort addr)
|
final ubyte readFinal(ushort addr)
|
||||||
|
@ -461,7 +461,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
{
|
{
|
||||||
string code = "peek(programCounter);\n";
|
string code = "peek(programCounter);\n";
|
||||||
code ~= (action == "") ? "" : (action ~ ";");
|
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";
|
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";
|
string code = "peek(programCounter);\n";
|
||||||
code ~= UpdateNZ(action);
|
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";
|
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" ~
|
string code = "readByteOperand();\n" ~
|
||||||
"if (" ~ action ~ ") addrRelative(cast(byte)operand1);\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";
|
return "override void opcode" ~ opcode ~ "()\n{\n" ~ code ~ "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,7 +719,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
pushWord(programCounter);
|
pushWord(programCounter);
|
||||||
|
|
||||||
finalAddress |= ((operand2 = read(programCounter)) << 8);
|
finalAddress |= ((operand2 = read(programCounter)) << 8);
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
programCounter = finalAddress;
|
programCounter = finalAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,14 +729,14 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
peek(programCounter);
|
peek(programCounter);
|
||||||
flag.fromByte(pull());
|
flag.fromByte(pull());
|
||||||
programCounter = readStack() | (readStack() << 8);
|
programCounter = readStack() | (readStack() << 8);
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* JMP $$$$ */
|
/* JMP $$$$ */
|
||||||
final override void opcode4C()
|
final override void opcode4C()
|
||||||
{
|
{
|
||||||
programCounter = readWordOperand();
|
programCounter = readWordOperand();
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RTS */
|
/* RTS */
|
||||||
|
@ -745,7 +745,7 @@ class Cpu(bool strict, bool cumulative) : CpuBase!(strict, cumulative)
|
||||||
peek(programCounter);
|
peek(programCounter);
|
||||||
programCounter = pullWord();
|
programCounter = pullWord();
|
||||||
peek(programCounter);
|
peek(programCounter);
|
||||||
static if (cumulative) tick(totalCycles);
|
static if (cumulative) clock.tick(totalCycles);
|
||||||
++programCounter;
|
++programCounter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,10 +133,10 @@ class System
|
||||||
{
|
{
|
||||||
cpu = newCpu();
|
cpu = newCpu();
|
||||||
debug(disassemble) cpu.memoryName = &decoder.memoryReadName;
|
debug(disassemble) cpu.memoryName = &decoder.memoryReadName;
|
||||||
cpu.tick = &timer.tick;
|
cpu.clock.tick = &timer.tick;
|
||||||
timer.onPrimaryStop(&primaryStop);
|
timer.onPrimaryStop(&primaryStop);
|
||||||
cpu.memoryRead = &decoder.read;
|
cpu.memory.read = &decoder.read;
|
||||||
cpu.memoryWrite = &decoder.write;
|
cpu.memory.write = &decoder.write;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initIO(ubyte[] vidRom)
|
void initIO(ubyte[] vidRom)
|
||||||
|
|
26
test/cpu.d
26
test/cpu.d
|
@ -80,9 +80,9 @@ if (isCpu!T)
|
||||||
else
|
else
|
||||||
void tick() {}
|
void tick() {}
|
||||||
|
|
||||||
cpu.memoryRead = &mem.read;
|
cpu.memory.read = &mem.read;
|
||||||
cpu.memoryWrite = &mem.write;
|
cpu.memory.write = &mem.write;
|
||||||
cpu.tick = &tick;
|
cpu.clock.tick = &tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ auto recordCycles(T)(T cpu)
|
||||||
if (isCpu!T)
|
if (isCpu!T)
|
||||||
{
|
{
|
||||||
auto cycles = new int;
|
auto cycles = new int;
|
||||||
auto wrappedTick = cpu.tick;
|
auto wrappedTick = cpu.clock.tick;
|
||||||
|
|
||||||
static if (isCumulative!T)
|
static if (isCumulative!T)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ if (isCpu!T)
|
||||||
wrappedTick();
|
wrappedTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpu.tick = &tick;
|
cpu.clock.tick = &tick;
|
||||||
|
|
||||||
return constRef(cycles);
|
return constRef(cycles);
|
||||||
}
|
}
|
||||||
|
@ -155,9 +155,9 @@ if (isCpu!T)
|
||||||
auto record = new Bus[actions];
|
auto record = new Bus[actions];
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
enforce(cpu.memoryRead !is null && cpu.memoryWrite !is null);
|
enforce(cpu.memory.read !is null && cpu.memory.write !is null);
|
||||||
auto wrappedRead = cpu.memoryRead;
|
auto wrappedRead = cpu.memory.read;
|
||||||
auto wrappedWrite = cpu.memoryWrite;
|
auto wrappedWrite = cpu.memory.write;
|
||||||
|
|
||||||
ubyte read(ushort addr)
|
ubyte read(ushort addr)
|
||||||
{
|
{
|
||||||
|
@ -177,8 +177,8 @@ if (isCpu!T)
|
||||||
wrappedWrite(addr, val);
|
wrappedWrite(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.memoryRead = &read;
|
cpu.memory.read = &read;
|
||||||
cpu.memoryWrite = &write;
|
cpu.memory.write = &write;
|
||||||
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
@ -210,8 +210,8 @@ enum Action : ushort { NONE, READ, WRITE }
|
||||||
void runUntilBRK(T)(T cpu)
|
void runUntilBRK(T)(T cpu)
|
||||||
if (isCpu!T)
|
if (isCpu!T)
|
||||||
{
|
{
|
||||||
assert(cpu.memoryRead !is null);
|
assert(cpu.memory.read !is null);
|
||||||
auto wrappedRead = cpu.memoryRead;
|
auto wrappedRead = cpu.memory.read;
|
||||||
|
|
||||||
ubyte read(ushort addr)
|
ubyte read(ushort addr)
|
||||||
{
|
{
|
||||||
|
@ -219,7 +219,7 @@ if (isCpu!T)
|
||||||
return wrappedRead(addr);
|
return wrappedRead(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.memoryRead = &read;
|
cpu.memory.read = &read;
|
||||||
|
|
||||||
try { cpu.run(true); } catch (StopException e) {}
|
try { cpu.run(true); } catch (StopException e) {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue