mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-10 10:29:43 +00:00
Some more rationalisation of processor execution/stepping strategies.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
5fe3d458df
commit
e70686c5de
@ -21,9 +21,9 @@ namespace EightBit {
|
|||||||
Signal<Intel8080> ExecutingInstruction;
|
Signal<Intel8080> ExecutingInstruction;
|
||||||
|
|
||||||
bool isInterruptable() const;
|
bool isInterruptable() const;
|
||||||
|
|
||||||
int interrupt(uint8_t value);
|
int interrupt(uint8_t value);
|
||||||
|
|
||||||
|
virtual int execute(uint8_t opcode);
|
||||||
int step();
|
int step();
|
||||||
|
|
||||||
virtual register16_t& AF() override {
|
virtual register16_t& AF() override {
|
||||||
@ -32,17 +32,9 @@ namespace EightBit {
|
|||||||
return af;
|
return af;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual register16_t& BC() override {
|
virtual register16_t& BC() override { return bc; }
|
||||||
return bc;
|
virtual register16_t& DE() override { return de; }
|
||||||
}
|
virtual register16_t& HL() override { return hl; }
|
||||||
|
|
||||||
virtual register16_t& DE() override {
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual register16_t& HL() override {
|
|
||||||
return hl;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void initialise();
|
virtual void initialise();
|
||||||
|
|
||||||
@ -159,11 +151,9 @@ namespace EightBit {
|
|||||||
|
|
||||||
static void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
|
static void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
|
||||||
|
|
||||||
virtual int execute(uint8_t opcode);
|
|
||||||
void execute(int x, int y, int z, int p, int q);
|
void execute(int x, int y, int z, int p, int q);
|
||||||
|
|
||||||
static void increment(uint8_t& f, uint8_t& operand);
|
static void increment(uint8_t& f, uint8_t& operand);
|
||||||
|
|
||||||
static void decrement(uint8_t& f, uint8_t& operand);
|
static void decrement(uint8_t& f, uint8_t& operand);
|
||||||
|
|
||||||
bool returnConditionalFlag(uint8_t& f, int flag);
|
bool returnConditionalFlag(uint8_t& f, int flag);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Intel8080.h"
|
#include "Intel8080.h"
|
||||||
|
|
||||||
#include "Memory.h"
|
#pragma region Reset and initialisation
|
||||||
#include "Disassembler.h"
|
|
||||||
|
|
||||||
EightBit::Intel8080::Intel8080(Memory& memory, InputOutput& ports)
|
EightBit::Intel8080::Intel8080(Memory& memory, InputOutput& ports)
|
||||||
: IntelProcessor(memory),
|
: IntelProcessor(memory),
|
||||||
@ -16,6 +15,8 @@ void EightBit::Intel8080::initialise() {
|
|||||||
AF().word = BC().word = DE().word = HL().word = 0;
|
AF().word = BC().word = DE().word = HL().word = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Reset and initialisation
|
||||||
|
|
||||||
#pragma region Interrupt routines
|
#pragma region Interrupt routines
|
||||||
|
|
||||||
void EightBit::Intel8080::di() {
|
void EightBit::Intel8080::di() {
|
||||||
@ -279,12 +280,18 @@ void EightBit::Intel8080::in() {
|
|||||||
|
|
||||||
#pragma endregion I/O instructions
|
#pragma endregion I/O instructions
|
||||||
|
|
||||||
|
#pragma region Controlled instruction execution
|
||||||
|
|
||||||
int EightBit::Intel8080::step() {
|
int EightBit::Intel8080::step() {
|
||||||
ExecutingInstruction.fire(*this);
|
ExecutingInstruction.fire(*this);
|
||||||
cycles = 0;
|
cycles = 0;
|
||||||
return fetchExecute();
|
return fetchExecute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Controlled instruction execution
|
||||||
|
|
||||||
|
#pragma region Instruction decode and execution
|
||||||
|
|
||||||
int EightBit::Intel8080::execute(uint8_t opcode) {
|
int EightBit::Intel8080::execute(uint8_t opcode) {
|
||||||
|
|
||||||
const auto& decoded = getDecodedOpcode(opcode);
|
const auto& decoded = getDecodedOpcode(opcode);
|
||||||
@ -639,3 +646,5 @@ void EightBit::Intel8080::execute(int x, int y, int z, int p, int q) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Instruction decode and execution
|
||||||
|
@ -21,31 +21,14 @@ namespace EightBit {
|
|||||||
|
|
||||||
Signal<LR35902> ExecutingInstruction;
|
Signal<LR35902> ExecutingInstruction;
|
||||||
|
|
||||||
void stop() { m_stopped = true; }
|
|
||||||
void start() { m_stopped = false; }
|
|
||||||
bool stopped() const { return m_stopped; }
|
|
||||||
|
|
||||||
bool& IME() { return m_ime; }
|
|
||||||
|
|
||||||
void di();
|
|
||||||
void ei();
|
|
||||||
|
|
||||||
virtual register16_t& AF() override {
|
virtual register16_t& AF() override {
|
||||||
af.low &= 0xf0;
|
af.low &= 0xf0;
|
||||||
return af;
|
return af;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual register16_t& BC() override {
|
virtual register16_t& BC() override { return bc; }
|
||||||
return bc;
|
virtual register16_t& DE() override { return de; }
|
||||||
}
|
virtual register16_t& HL() override { return hl; }
|
||||||
|
|
||||||
virtual register16_t& DE() override {
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual register16_t& HL() override {
|
|
||||||
return hl;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void initialise();
|
virtual void initialise();
|
||||||
@ -53,23 +36,11 @@ namespace EightBit {
|
|||||||
static int framesPerSecond() { return 60; }
|
static int framesPerSecond() { return 60; }
|
||||||
static int cyclesPerFrame() { return cyclesPerSecond() / framesPerSecond(); }
|
static int cyclesPerFrame() { return cyclesPerSecond() / framesPerSecond(); }
|
||||||
|
|
||||||
int runRasterLines() {
|
int runRasterLines();
|
||||||
m_bus.resetLY();
|
int runRasterLine();
|
||||||
int cycles = 0;
|
int runVerticalBlankLines();
|
||||||
for (int line = 0; line < Display::RasterHeight; ++line)
|
|
||||||
cycles += runRasterLine();
|
|
||||||
return cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
int runVerticalBlankLines() {
|
int singleStep();
|
||||||
m_bus.triggerInterrupt(Bus::Interrupts::VerticalBlank);
|
|
||||||
int cycles = 0;
|
|
||||||
for (int line = 0; line < (Bus::TotalLineCount - Display::RasterHeight); ++line)
|
|
||||||
cycles += runRasterLine();
|
|
||||||
return cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
int run(int limit);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int execute(uint8_t opcode);
|
virtual int execute(uint8_t opcode);
|
||||||
@ -84,21 +55,14 @@ namespace EightBit {
|
|||||||
register16_t hl;
|
register16_t hl;
|
||||||
|
|
||||||
bool m_ime;
|
bool m_ime;
|
||||||
|
bool m_stopped;
|
||||||
|
|
||||||
bool m_prefixCB;
|
bool m_prefixCB;
|
||||||
|
|
||||||
bool m_stopped;
|
|
||||||
|
|
||||||
static int cyclesPerSecond() { return 4 * 1024 * 1024; }
|
static int cyclesPerSecond() { return 4 * 1024 * 1024; }
|
||||||
static int cyclesPerLine() { return cyclesPerFrame() / Bus::TotalLineCount; }
|
static int cyclesPerLine() { return cyclesPerFrame() / Bus::TotalLineCount; }
|
||||||
|
|
||||||
int runRasterLine() {
|
bool& IME() { return m_ime; }
|
||||||
auto cycles = run(cyclesPerLine());
|
|
||||||
m_bus.incrementLY();
|
|
||||||
if ((m_bus.peekRegister(Bus::STAT) & Processor::Bit6) && (m_bus.peekRegister(Bus::LYC) == m_bus.peekRegister(Bus::LY)))
|
|
||||||
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
|
||||||
return cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t R(int r, uint8_t& a) {
|
uint8_t R(int r, uint8_t& a) {
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@ -203,6 +167,13 @@ namespace EightBit {
|
|||||||
static void increment(uint8_t& f, uint8_t& operand);
|
static void increment(uint8_t& f, uint8_t& operand);
|
||||||
static void decrement(uint8_t& f, uint8_t& operand);
|
static void decrement(uint8_t& f, uint8_t& operand);
|
||||||
|
|
||||||
|
void stop() { m_stopped = true; }
|
||||||
|
void start() { m_stopped = false; }
|
||||||
|
bool stopped() const { return m_stopped; }
|
||||||
|
|
||||||
|
void di();
|
||||||
|
void ei();
|
||||||
|
|
||||||
void reti();
|
void reti();
|
||||||
|
|
||||||
bool jrConditionalFlag(uint8_t& f, int flag);
|
bool jrConditionalFlag(uint8_t& f, int flag);
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#include "LR35902.h"
|
#include "LR35902.h"
|
||||||
|
|
||||||
// based on http://www.z80.info/decoding.htm
|
// based on http://www.z80.info/decoding.htm
|
||||||
// Half carry flag help from https://github.com/oubiwann/z80
|
|
||||||
|
#pragma region Reset and initialisation
|
||||||
|
|
||||||
EightBit::LR35902::LR35902(Bus& memory)
|
EightBit::LR35902::LR35902(Bus& memory)
|
||||||
: IntelProcessor(memory),
|
: IntelProcessor(memory),
|
||||||
@ -29,6 +30,8 @@ void EightBit::LR35902::initialise() {
|
|||||||
m_prefixCB = false;
|
m_prefixCB = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Reset and initialisation
|
||||||
|
|
||||||
#pragma region Interrupt routines
|
#pragma region Interrupt routines
|
||||||
|
|
||||||
void EightBit::LR35902::di() {
|
void EightBit::LR35902::di() {
|
||||||
@ -328,9 +331,36 @@ void EightBit::LR35902::ccf(uint8_t& a, uint8_t& f) {
|
|||||||
|
|
||||||
#pragma endregion Miscellaneous instructions
|
#pragma endregion Miscellaneous instructions
|
||||||
|
|
||||||
int EightBit::LR35902::run(int limit) {
|
#pragma region Controlled instruction execution
|
||||||
|
|
||||||
|
int EightBit::LR35902::runRasterLines() {
|
||||||
|
m_bus.resetLY();
|
||||||
|
int cycles = 0;
|
||||||
|
for (int line = 0; line < Display::RasterHeight; ++line)
|
||||||
|
cycles += runRasterLine();
|
||||||
|
return cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EightBit::LR35902::runRasterLine() {
|
||||||
|
auto cycles = run(cyclesPerLine());
|
||||||
|
m_bus.incrementLY();
|
||||||
|
if ((m_bus.peekRegister(Bus::STAT) & Processor::Bit6) && (m_bus.peekRegister(Bus::LYC) == m_bus.peekRegister(Bus::LY)))
|
||||||
|
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
||||||
|
return cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EightBit::LR35902::runVerticalBlankLines() {
|
||||||
|
m_bus.triggerInterrupt(Bus::Interrupts::VerticalBlank);
|
||||||
|
int cycles = 0;
|
||||||
|
for (int line = 0; line < (Bus::TotalLineCount - Display::RasterHeight); ++line)
|
||||||
|
cycles += runRasterLine();
|
||||||
|
return cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EightBit::LR35902::singleStep() {
|
||||||
|
|
||||||
int current = 0;
|
int current = 0;
|
||||||
do {
|
|
||||||
auto interruptEnable = m_bus.peekRegister(Bus::IE);
|
auto interruptEnable = m_bus.peekRegister(Bus::IE);
|
||||||
auto interruptFlags = m_bus.peekRegister(Bus::IF);
|
auto interruptFlags = m_bus.peekRegister(Bus::IF);
|
||||||
auto ime = IME();
|
auto ime = IME();
|
||||||
@ -361,7 +391,6 @@ int EightBit::LR35902::run(int limit) {
|
|||||||
|
|
||||||
m_bus.checkTimers(current);
|
m_bus.checkTimers(current);
|
||||||
|
|
||||||
} while (current < limit);
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,6 +401,10 @@ int EightBit::LR35902::step() {
|
|||||||
return fetchExecute();
|
return fetchExecute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Controlled instruction execution
|
||||||
|
|
||||||
|
#pragma region Instruction decode and execution
|
||||||
|
|
||||||
int EightBit::LR35902::execute(uint8_t opcode) {
|
int EightBit::LR35902::execute(uint8_t opcode) {
|
||||||
|
|
||||||
const auto& decoded = getDecodedOpcode(opcode);
|
const auto& decoded = getDecodedOpcode(opcode);
|
||||||
@ -865,3 +898,5 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Instruction decode and execution
|
||||||
|
@ -42,11 +42,16 @@ namespace EightBit {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MOS6502(Memory& memory);
|
MOS6502(Memory& memory);
|
||||||
virtual ~MOS6502();
|
|
||||||
|
|
||||||
Signal<MOS6502> ExecutingInstruction;
|
Signal<MOS6502> ExecutingInstruction;
|
||||||
Signal<MOS6502> ExecutedInstruction;
|
Signal<MOS6502> ExecutedInstruction;
|
||||||
|
|
||||||
|
virtual void triggerIRQ();
|
||||||
|
virtual void triggerNMI();
|
||||||
|
|
||||||
|
virtual int execute(uint8_t opcode);
|
||||||
|
int step();
|
||||||
|
|
||||||
uint8_t& X() { return x; }
|
uint8_t& X() { return x; }
|
||||||
uint8_t& Y() { return y; }
|
uint8_t& Y() { return y; }
|
||||||
uint8_t& A() { return a; }
|
uint8_t& A() { return a; }
|
||||||
@ -54,23 +59,8 @@ namespace EightBit {
|
|||||||
uint8_t& P() { return p; }
|
uint8_t& P() { return p; }
|
||||||
|
|
||||||
virtual void initialise();
|
virtual void initialise();
|
||||||
|
|
||||||
virtual int step();
|
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
virtual void triggerIRQ();
|
|
||||||
virtual void triggerNMI();
|
|
||||||
|
|
||||||
void getWord(register16_t& output);
|
|
||||||
void getWord(uint16_t offset, register16_t& output);
|
|
||||||
void getWord(const register16_t& offset, register16_t& output);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void interrupt(uint16_t vector);
|
|
||||||
|
|
||||||
virtual int execute(uint8_t opcode);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void adjustZero(uint8_t datum) { clearFlag(P(), ZF, datum); }
|
void adjustZero(uint8_t datum) { clearFlag(P(), ZF, datum); }
|
||||||
void adjustNegative(uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
void adjustNegative(uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
||||||
@ -80,9 +70,15 @@ namespace EightBit {
|
|||||||
adjustNegative(datum);
|
adjustNegative(datum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getWord(register16_t& output);
|
||||||
|
void getWord(uint16_t offset, register16_t& output);
|
||||||
|
void getWord(const register16_t& offset, register16_t& output);
|
||||||
|
|
||||||
virtual void push(uint8_t value) override;
|
virtual void push(uint8_t value) override;
|
||||||
virtual uint8_t pop() override;
|
virtual uint8_t pop() override;
|
||||||
|
|
||||||
|
void interrupt(uint16_t vector);
|
||||||
|
|
||||||
#pragma region 6502 addressing modes
|
#pragma region 6502 addressing modes
|
||||||
|
|
||||||
#pragma region Addresses
|
#pragma region Addresses
|
||||||
|
@ -24,9 +24,6 @@ EightBit::MOS6502::MOS6502(Memory& memory)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
EightBit::MOS6502::~MOS6502() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::initialise() {
|
void EightBit::MOS6502::initialise() {
|
||||||
|
|
||||||
Processor::initialise();
|
Processor::initialise();
|
||||||
|
@ -326,10 +326,7 @@ void Fuse::TestRunner::run() {
|
|||||||
initialise();
|
initialise();
|
||||||
auto allowedCycles = m_test.registerState.tstates;
|
auto allowedCycles = m_test.registerState.tstates;
|
||||||
try {
|
try {
|
||||||
auto cycles = 0;
|
m_cpu.run(allowedCycles);
|
||||||
do {
|
|
||||||
cycles += m_cpu.step();
|
|
||||||
} while (allowedCycles > cycles);
|
|
||||||
check();
|
check();
|
||||||
} catch (std::logic_error& error) {
|
} catch (std::logic_error& error) {
|
||||||
m_unimplemented = true;
|
m_unimplemented = true;
|
||||||
|
@ -46,9 +46,6 @@ namespace EightBit {
|
|||||||
|
|
||||||
Signal<Z80> ExecutingInstruction;
|
Signal<Z80> ExecutingInstruction;
|
||||||
|
|
||||||
void di();
|
|
||||||
void ei();
|
|
||||||
|
|
||||||
int interruptMaskable(uint8_t value) { return interrupt(true, value); }
|
int interruptMaskable(uint8_t value) { return interrupt(true, value); }
|
||||||
int interruptMaskable() { return interruptMaskable(0); }
|
int interruptMaskable() { return interruptMaskable(0); }
|
||||||
int interruptNonMaskable() { return interrupt(false, 0); }
|
int interruptNonMaskable() { return interrupt(false, 0); }
|
||||||
@ -102,6 +99,12 @@ namespace EightBit {
|
|||||||
virtual void initialise();
|
virtual void initialise();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual int fetchExecute() override {
|
||||||
|
M1() = true;
|
||||||
|
return IntelProcessor::fetchExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
InputOutput& m_ports;
|
InputOutput& m_ports;
|
||||||
|
|
||||||
enum { BC_IDX, DE_IDX, HL_IDX };
|
enum { BC_IDX, DE_IDX, HL_IDX };
|
||||||
@ -132,11 +135,6 @@ namespace EightBit {
|
|||||||
int8_t m_displacement;
|
int8_t m_displacement;
|
||||||
bool m_displaced;
|
bool m_displaced;
|
||||||
|
|
||||||
virtual int fetchExecute() override{
|
|
||||||
M1() = true;
|
|
||||||
return IntelProcessor::fetchExecute();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t displacedAddress() {
|
uint16_t displacedAddress() {
|
||||||
assert(m_displaced);
|
assert(m_displaced);
|
||||||
return MEMPTR().word = (m_prefixDD ? IX() : IY()).word + m_displacement;
|
return MEMPTR().word = (m_prefixDD ? IX() : IY()).word + m_displacement;
|
||||||
@ -326,6 +324,9 @@ namespace EightBit {
|
|||||||
static void increment(uint8_t& f, uint8_t& operand);
|
static void increment(uint8_t& f, uint8_t& operand);
|
||||||
static void decrement(uint8_t& f, uint8_t& operand);
|
static void decrement(uint8_t& f, uint8_t& operand);
|
||||||
|
|
||||||
|
void di();
|
||||||
|
void ei();
|
||||||
|
|
||||||
void retn();
|
void retn();
|
||||||
void reti();
|
void reti();
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#include "Z80.h"
|
#include "Z80.h"
|
||||||
|
|
||||||
// based on http://www.z80.info/decoding.htm
|
// based on http://www.z80.info/decoding.htm
|
||||||
// Half carry flag help from https://github.com/oubiwann/z80
|
|
||||||
|
#pragma region Reset and initialisation
|
||||||
|
|
||||||
EightBit::Z80::Z80(Memory& memory, InputOutput& ports)
|
EightBit::Z80::Z80(Memory& memory, InputOutput& ports)
|
||||||
: IntelProcessor(memory),
|
: IntelProcessor(memory),
|
||||||
@ -63,6 +64,8 @@ void EightBit::Z80::initialise() {
|
|||||||
m_prefixFD = false;
|
m_prefixFD = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Reset and initialisation
|
||||||
|
|
||||||
#pragma region Interrupt routines
|
#pragma region Interrupt routines
|
||||||
|
|
||||||
void EightBit::Z80::di() {
|
void EightBit::Z80::di() {
|
||||||
@ -748,6 +751,8 @@ void EightBit::Z80::readPort() {
|
|||||||
|
|
||||||
#pragma endregion I/O instructions
|
#pragma endregion I/O instructions
|
||||||
|
|
||||||
|
#pragma region Controlled instruction execution
|
||||||
|
|
||||||
int EightBit::Z80::step() {
|
int EightBit::Z80::step() {
|
||||||
ExecutingInstruction.fire(*this);
|
ExecutingInstruction.fire(*this);
|
||||||
m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
||||||
@ -755,6 +760,10 @@ int EightBit::Z80::step() {
|
|||||||
return fetchExecute();
|
return fetchExecute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Controlled instruction execution
|
||||||
|
|
||||||
|
#pragma region Instruction decode and execution
|
||||||
|
|
||||||
int EightBit::Z80::execute(uint8_t opcode) {
|
int EightBit::Z80::execute(uint8_t opcode) {
|
||||||
|
|
||||||
if (!M1())
|
if (!M1())
|
||||||
@ -1548,3 +1557,5 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Instruction decode and execution
|
||||||
|
@ -65,6 +65,10 @@ namespace EightBit {
|
|||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
virtual int run(int limit);
|
||||||
|
virtual int singleStep();
|
||||||
|
virtual int step() = 0;
|
||||||
|
|
||||||
virtual int execute(uint8_t opcode) = 0;
|
virtual int execute(uint8_t opcode) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -15,3 +15,15 @@ void EightBit::Processor::reset() {
|
|||||||
void EightBit::Processor::initialise() {
|
void EightBit::Processor::initialise() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EightBit::Processor::run(int limit) {
|
||||||
|
int current = 0;
|
||||||
|
do {
|
||||||
|
current += singleStep();
|
||||||
|
} while (current < limit);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EightBit::Processor::singleStep() {
|
||||||
|
return step();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user