mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-10 10:29:43 +00:00
Use a z80 style instruction decoder for the i8080 emulator.
This commit is contained in:
parent
ad9d37237f
commit
c0c969c560
@ -38,18 +38,30 @@ namespace EightBit {
|
||||
|
||||
const std::array<Instruction, 0x100>& getInstructions() const { return instructions; }
|
||||
|
||||
virtual register16_t& AF() override { return af; }
|
||||
virtual register16_t& BC() override { return bc; }
|
||||
virtual register16_t& DE() override { return de; }
|
||||
virtual register16_t& HL() override { return hl; }
|
||||
|
||||
bool isInterruptable() const;
|
||||
|
||||
int interrupt(uint8_t value);
|
||||
|
||||
virtual void initialise();
|
||||
int step();
|
||||
|
||||
virtual register16_t& AF() override {
|
||||
return af;
|
||||
}
|
||||
|
||||
virtual register16_t& BC() override {
|
||||
return bc;
|
||||
}
|
||||
|
||||
virtual register16_t& DE() override {
|
||||
return de;
|
||||
}
|
||||
|
||||
virtual register16_t& HL() override {
|
||||
return hl;
|
||||
}
|
||||
|
||||
virtual void initialise();
|
||||
|
||||
private:
|
||||
InputOutput& m_ports;
|
||||
|
||||
@ -62,9 +74,66 @@ namespace EightBit {
|
||||
|
||||
bool m_interrupt;
|
||||
|
||||
int execute(uint8_t opcode);
|
||||
uint8_t& R(int r) {
|
||||
__assume(r < 8);
|
||||
__assume(r >= 0);
|
||||
switch (r) {
|
||||
case 0b000:
|
||||
return B();
|
||||
case 0b001:
|
||||
return C();
|
||||
case 0b010:
|
||||
return D();
|
||||
case 0b011:
|
||||
return E();
|
||||
case 0b100:
|
||||
return H();
|
||||
case 0b101:
|
||||
return L();
|
||||
case 0b110:
|
||||
m_memory.ADDRESS() = HL();
|
||||
return m_memory.reference();
|
||||
case 0b111:
|
||||
return A();
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
throw std::logic_error("Unhandled registry mechanism");
|
||||
}
|
||||
|
||||
int execute(const Instruction& instruction);
|
||||
register16_t& RP(int rp) {
|
||||
__assume(rp < 4);
|
||||
__assume(rp >= 0);
|
||||
switch (rp) {
|
||||
case 0b00:
|
||||
return BC();
|
||||
case 0b01:
|
||||
return DE();
|
||||
case 0b10:
|
||||
return HL();
|
||||
case 0b11:
|
||||
return SP();
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
register16_t& RP2(int rp) {
|
||||
__assume(rp < 4);
|
||||
__assume(rp >= 0);
|
||||
switch (rp) {
|
||||
case 0b00:
|
||||
return BC();
|
||||
case 0b01:
|
||||
return DE();
|
||||
case 0b10:
|
||||
return HL();
|
||||
case 0b11:
|
||||
return AF();
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
void adjustReservedFlags() {
|
||||
F() = (F() | Bit1) & ~(Bit5 | Bit3);
|
||||
@ -78,448 +147,41 @@ namespace EightBit {
|
||||
clearFlag(f, AC, calculateHalfCarrySub(before, value, calculation));
|
||||
}
|
||||
|
||||
static void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
|
||||
|
||||
int execute(uint8_t opcode);
|
||||
void execute(int x, int y, int z, int p, int q);
|
||||
|
||||
static void increment(uint8_t& f, uint8_t& operand);
|
||||
|
||||
static void decrement(uint8_t& f, uint8_t& operand);
|
||||
|
||||
static Instruction INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles);
|
||||
Instruction UNKNOWN();
|
||||
|
||||
void installInstructions();
|
||||
|
||||
//
|
||||
|
||||
void compare(uint8_t& f, uint8_t check, uint8_t value);
|
||||
void anda(uint8_t value);
|
||||
void ora(uint8_t value);
|
||||
void xra(uint8_t value);
|
||||
|
||||
void add(uint8_t value, int carry = 0);
|
||||
void adc(uint8_t value);
|
||||
bool returnConditionalFlag(uint8_t& f, int flag);
|
||||
bool jumpConditionalFlag(uint8_t& f, int flag);
|
||||
bool callConditionalFlag(uint8_t& f, int flag);
|
||||
|
||||
void dad(uint16_t value);
|
||||
|
||||
void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
|
||||
void add(uint8_t value, int carry = 0);
|
||||
void adc(uint8_t value);
|
||||
void sbb(uint8_t value);
|
||||
|
||||
void mov_m_r(uint8_t value) {
|
||||
m_memory.ADDRESS() = HL();
|
||||
m_memory.reference() = value;
|
||||
}
|
||||
|
||||
uint8_t mov_r_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void ___();
|
||||
|
||||
// Move, load, and store
|
||||
|
||||
void mov_a_a() { }
|
||||
void mov_a_b() { A() = B(); }
|
||||
void mov_a_c() { A() = C(); }
|
||||
void mov_a_d() { A() = D(); }
|
||||
void mov_a_e() { A() = E(); }
|
||||
void mov_a_h() { A() = H(); }
|
||||
void mov_a_l() { A() = L(); }
|
||||
|
||||
void mov_b_a() { B() = A(); }
|
||||
void mov_b_b() { }
|
||||
void mov_b_c() { B() = C(); }
|
||||
void mov_b_d() { B() = D(); }
|
||||
void mov_b_e() { B() = E(); }
|
||||
void mov_b_h() { B() = H(); }
|
||||
void mov_b_l() { B() = L(); }
|
||||
|
||||
void mov_c_a() { C() = A(); }
|
||||
void mov_c_b() { C() = B(); }
|
||||
void mov_c_c() { }
|
||||
void mov_c_d() { C() = D(); }
|
||||
void mov_c_e() { C() = E(); }
|
||||
void mov_c_h() { C() = H(); }
|
||||
void mov_c_l() { C() = L(); }
|
||||
|
||||
void mov_d_a() { D() = A(); }
|
||||
void mov_d_b() { D() = B(); }
|
||||
void mov_d_c() { D() = C(); }
|
||||
void mov_d_d() { }
|
||||
void mov_d_e() { D() = E(); }
|
||||
void mov_d_h() { D() = H(); }
|
||||
void mov_d_l() { D() = L(); }
|
||||
|
||||
void mov_e_a() { E() = A(); }
|
||||
void mov_e_b() { E() = B(); }
|
||||
void mov_e_c() { E() = C(); }
|
||||
void mov_e_d() { E() = D(); }
|
||||
void mov_e_e() { }
|
||||
void mov_e_h() { E() = H(); }
|
||||
void mov_e_l() { E() = L(); }
|
||||
|
||||
void mov_h_a() { H() = A(); }
|
||||
void mov_h_b() { H() = B(); }
|
||||
void mov_h_c() { H() = C(); }
|
||||
void mov_h_d() { H() = D(); }
|
||||
void mov_h_e() { H() = E(); }
|
||||
void mov_h_h() { }
|
||||
void mov_h_l() { H() = L(); }
|
||||
|
||||
void mov_l_a() { L() = A(); }
|
||||
void mov_l_b() { L() = B(); }
|
||||
void mov_l_c() { L() = C(); }
|
||||
void mov_l_d() { L() = D(); }
|
||||
void mov_l_e() { L() = E(); }
|
||||
void mov_l_h() { L() = H(); }
|
||||
void mov_l_l() { }
|
||||
|
||||
void mov_m_a() { mov_m_r(A()); }
|
||||
void mov_m_b() { mov_m_r(B()); }
|
||||
void mov_m_c() { mov_m_r(C()); }
|
||||
void mov_m_d() { mov_m_r(D()); }
|
||||
void mov_m_e() { mov_m_r(E()); }
|
||||
void mov_m_h() { mov_m_r(H()); }
|
||||
void mov_m_l() { mov_m_r(L()); }
|
||||
|
||||
void mov_a_m() { A() = mov_r_m(); }
|
||||
void mov_b_m() { B() = mov_r_m(); }
|
||||
void mov_c_m() { C() = mov_r_m(); }
|
||||
void mov_d_m() { D() = mov_r_m(); }
|
||||
void mov_e_m() { E() = mov_r_m(); }
|
||||
void mov_h_m() { H() = mov_r_m(); }
|
||||
void mov_l_m() { L() = mov_r_m(); }
|
||||
|
||||
void mvi_a() { A() = fetchByte(); }
|
||||
void mvi_b() { B() = fetchByte(); }
|
||||
void mvi_c() { C() = fetchByte(); }
|
||||
void mvi_d() { D() = fetchByte(); }
|
||||
void mvi_e() { E() = fetchByte(); }
|
||||
void mvi_h() { H() = fetchByte(); }
|
||||
void mvi_l() { L() = fetchByte(); }
|
||||
|
||||
void mvi_m() {
|
||||
auto data = fetchByte();
|
||||
m_memory.ADDRESS() = HL();
|
||||
m_memory.reference() = data;
|
||||
}
|
||||
|
||||
void lxi_b() { fetchWord(BC()); }
|
||||
void lxi_d() { fetchWord(DE()); }
|
||||
void lxi_h() { fetchWord(HL()); }
|
||||
|
||||
void stax_r(register16_t& destination) {
|
||||
m_memory.ADDRESS() = destination;
|
||||
m_memory.reference() = A();
|
||||
}
|
||||
|
||||
void stax_b() { stax_r(BC()); }
|
||||
void stax_d() { stax_r(DE()); }
|
||||
|
||||
void ldax_r(register16_t& source) {
|
||||
m_memory.ADDRESS() = source;
|
||||
A() = m_memory.reference();
|
||||
}
|
||||
|
||||
void ldax_b() { ldax_r(BC()); }
|
||||
void ldax_d() { ldax_r(DE()); }
|
||||
|
||||
void sta() {
|
||||
fetchWord();
|
||||
memptrReference() = A();
|
||||
}
|
||||
|
||||
void lda() {
|
||||
fetchWord();
|
||||
A() = memptrReference();
|
||||
}
|
||||
|
||||
void shld() {
|
||||
fetchWord();
|
||||
setWordViaMemptr(HL());
|
||||
}
|
||||
|
||||
void lhld() {
|
||||
fetchWord();
|
||||
getWordViaMemptr(HL());
|
||||
}
|
||||
|
||||
void xchg() {
|
||||
std::swap(DE(), HL());
|
||||
}
|
||||
|
||||
// stack ops
|
||||
|
||||
void push_b() { pushWord(BC()); }
|
||||
void push_d() { pushWord(DE()); }
|
||||
void push_h() { pushWord(HL()); }
|
||||
void push_psw() { pushWord(AF()); }
|
||||
|
||||
void pop_b() { popWord(BC()); }
|
||||
void pop_d() { popWord(DE()); }
|
||||
void pop_h() { popWord(HL()); }
|
||||
|
||||
void pop_psw() {
|
||||
popWord(AF());
|
||||
adjustReservedFlags();
|
||||
}
|
||||
|
||||
void xhtl();
|
||||
|
||||
void sphl() {
|
||||
SP() = HL();
|
||||
}
|
||||
|
||||
void lxi_sp() {
|
||||
fetchWord(SP());
|
||||
}
|
||||
|
||||
void inx_sp() { ++SP().word; }
|
||||
void dcx_sp() { --SP().word; }
|
||||
|
||||
// jump
|
||||
|
||||
void jmp();
|
||||
|
||||
void jc();
|
||||
void jnc();
|
||||
|
||||
void jz();
|
||||
void jnz();
|
||||
|
||||
void jpe();
|
||||
void jpo();
|
||||
|
||||
void jm();
|
||||
void jp();
|
||||
|
||||
void pchl();
|
||||
|
||||
// call
|
||||
|
||||
void callDirect();
|
||||
|
||||
void cc();
|
||||
void cnc();
|
||||
|
||||
void cpe();
|
||||
void cpo();
|
||||
|
||||
void cz();
|
||||
void cnz();
|
||||
|
||||
void cm();
|
||||
void cp();
|
||||
|
||||
// return
|
||||
|
||||
void rc();
|
||||
void rnc();
|
||||
|
||||
void rz();
|
||||
void rnz();
|
||||
|
||||
void rpe();
|
||||
void rpo();
|
||||
|
||||
void rm();
|
||||
void rp();
|
||||
|
||||
// restart
|
||||
|
||||
void rst_0() { restart(0 << 3); }
|
||||
void rst_1() { restart(1 << 3); }
|
||||
void rst_2() { restart(2 << 3); }
|
||||
void rst_3() { restart(3 << 3); }
|
||||
void rst_4() { restart(4 << 3); }
|
||||
void rst_5() { restart(5 << 3); }
|
||||
void rst_6() { restart(6 << 3); }
|
||||
void rst_7() { restart(7 << 3); }
|
||||
|
||||
// increment and decrement
|
||||
|
||||
void inr_a() { increment(F(), A()); }
|
||||
void inr_b() { increment(F(), B()); }
|
||||
void inr_c() { increment(F(), C()); }
|
||||
void inr_d() { increment(F(), D()); }
|
||||
void inr_e() { increment(F(), E()); }
|
||||
void inr_h() { increment(F(), H()); }
|
||||
void inr_l() { increment(F(), L()); }
|
||||
|
||||
void inr_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
increment(F(), m_memory.reference());
|
||||
}
|
||||
|
||||
void dcr_a() { decrement(F(), A()); }
|
||||
void dcr_b() { decrement(F(), B()); }
|
||||
void dcr_c() { decrement(F(), C()); }
|
||||
void dcr_d() { decrement(F(), D()); }
|
||||
void dcr_e() { decrement(F(), E()); }
|
||||
void dcr_h() { decrement(F(), H()); }
|
||||
void dcr_l() { decrement(F(), L()); }
|
||||
|
||||
void dcr_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
decrement(F(), m_memory.reference());
|
||||
}
|
||||
|
||||
void inx_b() { ++BC().word; }
|
||||
void inx_d() { ++DE().word; }
|
||||
void inx_h() { ++HL().word; }
|
||||
|
||||
void dcx_b() { --BC().word; }
|
||||
void dcx_d() { --DE().word; }
|
||||
void dcx_h() { --HL().word; }
|
||||
|
||||
// add
|
||||
|
||||
void add_a() { add(A()); }
|
||||
void add_b() { add(B()); }
|
||||
void add_c() { add(C()); }
|
||||
void add_d() { add(D()); }
|
||||
void add_e() { add(E()); }
|
||||
void add_h() { add(H()); }
|
||||
void add_l() { add(L()); }
|
||||
|
||||
void add_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
add(m_memory.reference());
|
||||
}
|
||||
|
||||
void adi() { add(fetchByte()); }
|
||||
|
||||
void adc_a() { adc(A()); }
|
||||
void adc_b() { adc(B()); }
|
||||
void adc_c() { adc(C()); }
|
||||
void adc_d() { adc(D()); }
|
||||
void adc_e() { adc(E()); }
|
||||
void adc_h() { adc(H()); }
|
||||
void adc_l() { adc(L()); }
|
||||
|
||||
void adc_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
adc(m_memory.reference());
|
||||
}
|
||||
|
||||
void aci() { adc(fetchByte()); }
|
||||
|
||||
void dad_b() { dad(BC().word); }
|
||||
void dad_d() { dad(DE().word); }
|
||||
void dad_h() { dad(HL().word); }
|
||||
void dad_sp() { dad(SP().word); }
|
||||
|
||||
// subtract
|
||||
|
||||
void sub_a() { subtract(F(), A(), A()); }
|
||||
void sub_b() { subtract(F(), A(), B()); }
|
||||
void sub_c() { subtract(F(), A(), C()); }
|
||||
void sub_d() { subtract(F(), A(), D()); }
|
||||
void sub_e() { subtract(F(), A(), E()); }
|
||||
void sub_h() { subtract(F(), A(), H()); }
|
||||
void sub_l() { subtract(F(), A(), L()); }
|
||||
|
||||
void sub_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
subtract(F(), A(), m_memory.reference());
|
||||
}
|
||||
|
||||
void sbb_a() { sbb(A()); }
|
||||
void sbb_b() { sbb(B()); }
|
||||
void sbb_c() { sbb(C()); }
|
||||
void sbb_d() { sbb(D()); }
|
||||
void sbb_e() { sbb(E()); }
|
||||
void sbb_h() { sbb(H()); }
|
||||
void sbb_l() { sbb(L()); }
|
||||
|
||||
void sbb_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
sbb(m_memory.reference());
|
||||
}
|
||||
|
||||
void sbi() {
|
||||
sbb(fetchByte());
|
||||
}
|
||||
|
||||
void sui() {
|
||||
subtract(F(), A(), fetchByte());
|
||||
}
|
||||
|
||||
// logical
|
||||
|
||||
void ana_a() { anda(A()); }
|
||||
void ana_b() { anda(B()); }
|
||||
void ana_c() { anda(C()); }
|
||||
void ana_d() { anda(D()); }
|
||||
void ana_e() { anda(E()); }
|
||||
void ana_h() { anda(H()); }
|
||||
void ana_l() { anda(L()); }
|
||||
|
||||
void ana_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
anda(m_memory.reference());
|
||||
}
|
||||
|
||||
void ani() { anda(fetchByte()); }
|
||||
|
||||
void xra_a() { xra(A()); }
|
||||
void xra_b() { xra(B()); }
|
||||
void xra_c() { xra(C()); }
|
||||
void xra_d() { xra(D()); }
|
||||
void xra_e() { xra(E()); }
|
||||
void xra_h() { xra(H()); }
|
||||
void xra_l() { xra(L()); }
|
||||
|
||||
void xra_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
xra(m_memory.reference());
|
||||
}
|
||||
|
||||
void xri() { xra(fetchByte()); }
|
||||
|
||||
void ora_a() { ora(A()); }
|
||||
void ora_b() { ora(B()); }
|
||||
void ora_c() { ora(C()); }
|
||||
void ora_d() { ora(D()); }
|
||||
void ora_e() { ora(E()); }
|
||||
void ora_h() { ora(H()); }
|
||||
void ora_l() { ora(L()); }
|
||||
|
||||
void ora_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
ora(m_memory.reference());
|
||||
}
|
||||
|
||||
void ori() { ora(fetchByte()); }
|
||||
|
||||
void cmp_a() { compare(F(), A(), A()); }
|
||||
void cmp_b() { compare(F(), A(), B()); }
|
||||
void cmp_c() { compare(F(), A(), C()); }
|
||||
void cmp_d() { compare(F(), A(), D()); }
|
||||
void cmp_e() { compare(F(), A(), E()); }
|
||||
void cmp_h() { compare(F(), A(), H()); }
|
||||
void cmp_l() { compare(F(), A(), L()); }
|
||||
|
||||
void cmp_m() {
|
||||
m_memory.ADDRESS() = HL();
|
||||
compare(F(), A(), m_memory.reference());
|
||||
}
|
||||
|
||||
void cpi() { compare(F(), A(), fetchByte()); }
|
||||
|
||||
// rotate
|
||||
void anda(uint8_t value);
|
||||
void xra(uint8_t value);
|
||||
void ora(uint8_t value);
|
||||
void compare(uint8_t& f, uint8_t check, uint8_t value);
|
||||
|
||||
void rlc();
|
||||
void rrc();
|
||||
void ral();
|
||||
void rar();
|
||||
|
||||
// specials
|
||||
void daa();
|
||||
|
||||
void cma();
|
||||
void stc();
|
||||
void cmc();
|
||||
void daa();
|
||||
|
||||
void xhtl();
|
||||
|
||||
// input/output
|
||||
|
||||
@ -531,8 +193,13 @@ namespace EightBit {
|
||||
void ei();
|
||||
void di();
|
||||
|
||||
//
|
||||
|
||||
void ___();
|
||||
void nop() {}
|
||||
|
||||
void hlt() { halt(); }
|
||||
static Instruction INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles);
|
||||
Instruction UNKNOWN();
|
||||
void installInstructions();
|
||||
};
|
||||
}
|
@ -12,53 +12,8 @@ EightBit::Intel8080::Intel8080(Memory& memory, InputOutput& ports)
|
||||
installInstructions();
|
||||
}
|
||||
|
||||
EightBit::Intel8080::Instruction EightBit::Intel8080::INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles) {
|
||||
Intel8080::Instruction returnValue;
|
||||
returnValue.vector = method;
|
||||
returnValue.mode = mode;
|
||||
returnValue.disassembly = disassembly;
|
||||
returnValue.count = cycles;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
EightBit::Intel8080::Instruction EightBit::Intel8080::UNKNOWN() {
|
||||
Intel8080::Instruction returnValue;
|
||||
returnValue.vector = std::bind(&Intel8080::___, this);
|
||||
returnValue.mode = Unknown;
|
||||
returnValue.disassembly = "";
|
||||
returnValue.count = 0;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#define BIND(method) std::bind(&Intel8080:: method, this)
|
||||
|
||||
void EightBit::Intel8080::installInstructions() {
|
||||
instructions = {
|
||||
//// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
/* 0 */ INS(BIND(nop), Implied, "NOP", 4), INS(BIND(lxi_b), Absolute, "LXI B,", 10), INS(BIND(stax_b), Implied, "STAX B", 7), INS(BIND(inx_b), Implied, "INX B", 5), INS(BIND(inr_b), Implied, "INR B", 5), INS(BIND(dcr_b), Implied, "DCR B", 5), INS(BIND(mvi_b), Immediate, "MVI B,", 7), INS(BIND(rlc), Implied, "RLC", 4), UNKNOWN(), INS(BIND(dad_b), Implied, "DAD B", 10), INS(BIND(ldax_b), Implied, "LDAX B", 7), INS(BIND(dcx_b), Implied, "DCX B", 5), INS(BIND(inr_c), Implied, "INR C", 5), INS(BIND(dcr_c), Implied, "DCR C", 5), INS(BIND(mvi_c), Immediate, "MVI C,", 7), INS(BIND(rrc), Implied, "RRC", 4), // 0
|
||||
/* 1 */ UNKNOWN(), INS(BIND(lxi_d), Absolute, "LXI D,", 10), INS(BIND(stax_d), Implied, "STAX D", 7), INS(BIND(inx_d), Implied, "INX D", 5), INS(BIND(inr_d), Implied, "INR D", 5), INS(BIND(dcr_d), Implied, "DCR D", 5), INS(BIND(mvi_d), Immediate, "MVI D,", 7), INS(BIND(ral), Implied, "RAL", 4), UNKNOWN(), INS(BIND(dad_d), Implied, "DAD D", 10), INS(BIND(ldax_d), Implied, "LDAX D", 7), INS(BIND(dcx_d), Implied, "DCX D", 5), INS(BIND(inr_e), Implied, "INR E", 5), INS(BIND(dcr_e), Implied, "DCR E", 5), INS(BIND(mvi_e), Immediate, "MVI E,", 7), INS(BIND(rar), Implied, "RAR", 4), // 1
|
||||
/* 2 */ UNKNOWN(), INS(BIND(lxi_h), Absolute, "LXI H,", 10), INS(BIND(shld), Absolute, "SHLD", 16), INS(BIND(inx_h), Implied, "INX H", 5), INS(BIND(inr_h), Implied, "INR H", 5), INS(BIND(dcr_h), Implied, "DCR H", 5), INS(BIND(mvi_h), Immediate, "MVI H,",7), INS(BIND(daa), Implied, "DAA", 4), UNKNOWN(), INS(BIND(dad_h), Implied, "DAD H", 10), INS(BIND(lhld), Absolute, "LHLD ", 16), INS(BIND(dcx_h), Implied, "DCX H", 5), INS(BIND(inr_l), Implied, "INR L", 5), INS(BIND(dcr_l), Implied, "DCR L", 5), INS(BIND(mvi_l), Immediate, "MVI L,", 7), INS(BIND(cma), Implied, "CMA", 4), // 2
|
||||
/* 3 */ UNKNOWN(), INS(BIND(lxi_sp), Absolute, "LXI SP,", 10), INS(BIND(sta), Absolute, "STA ", 13), INS(BIND(inx_sp), Implied, "INX SP", 5), INS(BIND(inr_m), Implied, "INR M", 10), INS(BIND(dcr_m), Implied, "DCR M", 10), INS(BIND(mvi_m), Immediate, "MVI M,", 10), INS(BIND(stc), Implied, "STC", 4), UNKNOWN(), INS(BIND(dad_sp), Implied, "DAD SP", 10), INS(BIND(lda), Absolute, "LDA ", 13), INS(BIND(dcx_sp), Implied, "DCX SP", 5), INS(BIND(inr_a), Implied, "INR A", 5), INS(BIND(dcr_a), Implied, "DCR A", 5), INS(BIND(mvi_a), Immediate, "MVI A,", 7), INS(BIND(cmc), Implied, "CMC", 4), // 3
|
||||
|
||||
/* 4 */ INS(BIND(mov_b_b), Implied, "MOV B,B", 5), INS(BIND(mov_b_c), Implied, "MOV B,C", 5), INS(BIND(mov_b_d), Implied, "MOV B,D", 5), INS(BIND(mov_b_e), Implied, "MOV B,E", 5), INS(BIND(mov_b_h), Implied, "MOV B,H", 5), INS(BIND(mov_b_l), Implied, "MOV B,L", 5), INS(BIND(mov_b_m), Implied, "MOV B,M", 7), INS(BIND(mov_b_a), Implied, "MOV B,A", 5), INS(BIND(mov_c_b), Implied, "MOV C,B", 5), INS(BIND(mov_c_c), Implied, "MOV C,C", 5), INS(BIND(mov_c_d), Implied, "MOV C,D", 5), INS(BIND(mov_c_e), Implied, "MOV C,E", 5), INS(BIND(mov_c_h), Implied, "MOV C,H", 5), INS(BIND(mov_c_l), Implied, "MOV C,L", 5), INS(BIND(mov_c_m), Implied, "MOV C,M", 7), INS(BIND(mov_c_a), Implied, "MOV C,A", 5), // 4
|
||||
/* 5 */ INS(BIND(mov_d_b), Implied, "MOV D,B", 5), INS(BIND(mov_d_c), Implied, "MOV D,C", 5), INS(BIND(mov_d_d), Implied, "MOV D,D", 5), INS(BIND(mov_d_e), Implied, "MOV D,E", 5), INS(BIND(mov_d_h), Implied, "MOV D,H", 5), INS(BIND(mov_d_l), Implied, "MOV D,L", 5), INS(BIND(mov_d_m), Implied, "MOV D,M", 7), INS(BIND(mov_d_a), Implied, "MOV D,A", 5), INS(BIND(mov_e_b), Implied, "MOV E,B", 5), INS(BIND(mov_e_c), Implied, "MOV E,C", 5), INS(BIND(mov_e_d), Implied, "MOV E,D", 5), INS(BIND(mov_e_e), Implied, "MOV E,E", 5), INS(BIND(mov_e_h), Implied, "MOV E,H", 5), INS(BIND(mov_e_l), Implied, "MOV E,L", 5), INS(BIND(mov_e_m), Implied, "MOV E,M", 7), INS(BIND(mov_e_a), Implied, "MOV E,A", 5), // 5
|
||||
/* 6 */ INS(BIND(mov_h_b), Implied, "MOV H,B", 5), INS(BIND(mov_h_c), Implied, "MOV H,C", 5), INS(BIND(mov_h_d), Implied, "MOV H,D", 5), INS(BIND(mov_h_e), Implied, "MOV H,E", 5), INS(BIND(mov_h_h), Implied, "MOV H,H", 5), INS(BIND(mov_h_l), Implied, "MOV H,L", 5), INS(BIND(mov_h_m), Implied, "MOV H,M", 7), INS(BIND(mov_h_a), Implied, "MOV H,A", 5), INS(BIND(mov_l_b), Implied, "MOV L,B", 5), INS(BIND(mov_l_c), Implied, "MOV L,C", 5), INS(BIND(mov_l_d), Implied, "MOV L,D", 5), INS(BIND(mov_l_e), Implied, "MOV L,E", 5), INS(BIND(mov_l_h), Implied, "MOV L,H", 5), INS(BIND(mov_l_l), Implied, "MOV L,L", 5), INS(BIND(mov_l_m), Implied, "MOV L,M", 7), INS(BIND(mov_l_a), Implied, "MOV L,A", 5), // 6
|
||||
/* 7 */ INS(BIND(mov_m_b), Implied, "MOV M,B", 7), INS(BIND(mov_m_c), Implied, "MOV M,C", 7), INS(BIND(mov_m_d), Implied, "MOV M,D", 7), INS(BIND(mov_m_e), Implied, "MOV M,E", 7), INS(BIND(mov_m_h), Implied, "MOV M,H", 7), INS(BIND(mov_m_l), Implied, "MOV M,L", 7), INS(BIND(hlt), Implied, "HLT", 7), INS(BIND(mov_m_a), Implied, "MOV M,A", 7), INS(BIND(mov_a_b), Implied, "MOV A,B", 5), INS(BIND(mov_a_c), Implied, "MOV A,C", 5), INS(BIND(mov_a_d), Implied, "MOV A,D", 5), INS(BIND(mov_a_e), Implied, "MOV A,E", 5), INS(BIND(mov_a_h), Implied, "MOV A,H", 5), INS(BIND(mov_a_l), Implied, "MOV A,L", 5), INS(BIND(mov_a_m), Implied, "MOV A,M", 7), INS(BIND(mov_a_a), Implied, "MOV A,A", 5), // 7
|
||||
|
||||
/* 8 */ INS(BIND(add_b), Implied, "ADD B", 4), INS(BIND(add_c), Implied, "ADD C", 4), INS(BIND(add_d), Implied, "ADD D", 4), INS(BIND(add_e), Implied, "ADD E", 4), INS(BIND(add_h), Implied, "ADD H", 4), INS(BIND(add_l), Implied, "ADD L", 4), INS(BIND(add_m), Implied, "ADD M", 7), INS(BIND(add_a), Implied, "ADD A", 4), INS(BIND(adc_b), Implied, "ADC B", 4), INS(BIND(adc_c), Implied, "ADC C", 4), INS(BIND(adc_d), Implied, "ADC D", 4), INS(BIND(adc_e), Implied, "ADC E", 4), INS(BIND(adc_h), Implied, "ADC H", 4), INS(BIND(adc_l), Implied, "ADC L", 4), INS(BIND(adc_m), Implied, "ADC M", 4), INS(BIND(adc_a), Implied, "ADC A", 4), // 8
|
||||
/* 9 */ INS(BIND(sub_b), Implied, "SUB B", 4), INS(BIND(sub_c), Implied, "SUB C", 4), INS(BIND(sub_d), Implied, "SUB D", 4), INS(BIND(sub_e), Implied, "SUB E", 4), INS(BIND(sub_h), Implied, "SUB H", 4), INS(BIND(sub_l), Implied, "SUB L", 4), INS(BIND(sub_m), Implied, "SUB M", 7), INS(BIND(sub_a), Implied, "SUB A", 4), INS(BIND(sbb_b), Implied, "SBB B", 4), INS(BIND(sbb_c), Implied, "SBB C", 4), INS(BIND(sbb_d), Implied, "SBB D", 4), INS(BIND(sbb_e), Implied, "SBB E", 4), INS(BIND(sbb_h), Implied, "SBB H", 4), INS(BIND(sbb_l), Implied, "SBB L", 4), INS(BIND(sbb_m), Implied, "SBB M", 4), INS(BIND(sbb_a), Implied, "SBB A", 4), // 9
|
||||
/* A */ INS(BIND(ana_b), Implied, "ANA B", 4), INS(BIND(ana_c), Implied, "ANA C", 4), INS(BIND(ana_d), Implied, "ANA D", 4), INS(BIND(ana_e), Implied, "ANA E", 4), INS(BIND(ana_h), Implied, "ANA H", 4), INS(BIND(ana_l), Implied, "ANA L", 4), INS(BIND(ana_m), Implied, "ANA M", 7), INS(BIND(ana_a), Implied, "ANA A", 4), INS(BIND(xra_b), Implied, "XRA B", 4), INS(BIND(xra_c), Implied, "XRA C", 4), INS(BIND(xra_d), Implied, "XRA D", 4), INS(BIND(xra_e), Implied, "XRA E", 4), INS(BIND(xra_h), Implied, "XRA H", 4), INS(BIND(xra_l), Implied, "XRA L", 4), INS(BIND(xra_m), Implied, "XRA M", 4), INS(BIND(xra_a), Implied, "XRA A", 4), // A
|
||||
/* B */ INS(BIND(ora_b), Implied, "ORA B", 4), INS(BIND(ora_c), Implied, "ORA C", 4), INS(BIND(ora_d), Implied, "ORA D", 4), INS(BIND(ora_e), Implied, "ORA E", 4), INS(BIND(ora_h), Implied, "ORA H", 4), INS(BIND(ora_l), Implied, "ORA L", 4), INS(BIND(ora_m), Implied, "ORA M", 7), INS(BIND(ora_a), Implied, "ORA A", 4), INS(BIND(cmp_b), Implied, "CMP B", 4), INS(BIND(cmp_c), Implied, "CMP C", 4), INS(BIND(cmp_d), Implied, "CMP D", 4), INS(BIND(cmp_e), Implied, "CMP E", 4), INS(BIND(cmp_h), Implied, "CMP H", 4), INS(BIND(cmp_l), Implied, "CMP L", 4), INS(BIND(cmp_m), Implied, "CMP M", 4), INS(BIND(cmp_a), Implied, "CMP A", 4), // B
|
||||
|
||||
/* C */ INS(BIND(rnz), Implied, "RNZ", 5), INS(BIND(pop_b), Implied, "POP B", 10), INS(BIND(jnz), Absolute, "JNZ ", 10), INS(BIND(jmp), Absolute, "JMP ", 10), INS(BIND(cnz), Absolute, "CNZ ", 11), INS(BIND(push_b), Implied, "PUSH B", 11), INS(BIND(adi), Immediate, "ADI ", 7), INS(BIND(rst_0), Implied, "RST 0", 11), INS(BIND(rz), Implied, "RZ", 11), INS(BIND(ret), Implied, "RET", 10), INS(BIND(jz), Absolute, "JZ ", 10), UNKNOWN(), INS(BIND(cz), Absolute, "CZ ", 11), INS(BIND(callDirect), Absolute, "CALL ", 17), INS(BIND(aci), Immediate, "ACI ", 7), INS(BIND(rst_1), Implied, "RST 1", 11), // C
|
||||
/* D */ INS(BIND(rnc), Implied, "RNC", 5), INS(BIND(pop_d), Implied, "POP D", 10), INS(BIND(jnc), Absolute, "JNC ", 10), INS(BIND(out), Immediate, "OUT ", 10), INS(BIND(cnc), Absolute, "CNC ", 11), INS(BIND(push_d), Implied, "PUSH D", 11), INS(BIND(sui), Immediate, "SUI ", 7), INS(BIND(rst_2), Implied, "RST 2", 11), INS(BIND(rc), Implied, "RC", 11), UNKNOWN(), INS(BIND(jc), Absolute, "JC ", 10), INS(BIND(in), Immediate, "IN ", 10), INS(BIND(cc), Absolute, "CC ", 11), UNKNOWN(), INS(BIND(sbi), Immediate, "SBI ", 7), INS(BIND(rst_3), Implied, "RST 3", 11), // D
|
||||
/* E */ INS(BIND(rpo), Implied, "RPO", 5), INS(BIND(pop_h), Implied, "POP H", 10), INS(BIND(jpo), Absolute, "JPO ", 10), INS(BIND(xhtl), Implied, "XHTL", 18), INS(BIND(cpo), Absolute, "CPO ", 11), INS(BIND(push_h), Implied, "PUSH H", 11), INS(BIND(ani), Immediate, "ANI ", 7), INS(BIND(rst_4), Implied, "RST 4", 11), INS(BIND(rpe), Implied, "RPE", 11), INS(BIND(pchl), Implied, "PCHL", 5), INS(BIND(jpe), Absolute, "JPE ", 10), INS(BIND(xchg), Implied, "XCHG", 4), INS(BIND(cpe), Absolute, "CPE ", 11), UNKNOWN(), INS(BIND(xri), Immediate, "XRI ", 7), INS(BIND(rst_5), Implied, "RST 5", 11), // E
|
||||
/* F */ INS(BIND(rp), Implied, "RP", 5), INS(BIND(pop_psw), Implied, "POP PSW", 10), INS(BIND(jp), Absolute, "JP ", 10), INS(BIND(di), Implied, "DI ", 4), INS(BIND(cp), Absolute, "CP ", 11), INS(BIND(push_psw), Implied, "PUSH PSW", 11), INS(BIND(ori), Immediate, "ORI ", 7), INS(BIND(rst_6), Implied, "RST 6", 11), INS(BIND(rm), Implied, "RM", 11), INS(BIND(sphl), Implied, "SPHL", 5), INS(BIND(jm), Absolute, "JM ", 10), INS(BIND(ei), Implied, "EI", 4), INS(BIND(cm), Absolute, "CM ", 11), UNKNOWN(), INS(BIND(cpi), Immediate, "CPI ", 7), INS(BIND(rst_7), Implied, "RST 7", 11), // F
|
||||
};
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::initialise() {
|
||||
Processor::initialise();
|
||||
IntelProcessor::initialise();
|
||||
AF().word = BC().word = DE().word = HL().word = 0;
|
||||
}
|
||||
|
||||
@ -102,129 +57,76 @@ void EightBit::Intel8080::decrement(uint8_t& f, uint8_t& operand) {
|
||||
|
||||
#pragma region PC manipulation: call/ret/jp/jr
|
||||
|
||||
void EightBit::Intel8080::jmp() {
|
||||
jumpConditional(true);
|
||||
bool EightBit::Intel8080::jumpConditionalFlag(uint8_t& f, int flag) {
|
||||
switch (flag) {
|
||||
case 0: // NZ
|
||||
return jumpConditional(!(f & ZF));
|
||||
case 1: // Z
|
||||
return jumpConditional(f & ZF);
|
||||
case 2: // NC
|
||||
return jumpConditional(!(f & CF));
|
||||
case 3: // C
|
||||
return jumpConditional(f & CF);
|
||||
case 4: // PO
|
||||
return jumpConditional(!(f & PF));
|
||||
case 5: // PE
|
||||
return jumpConditional(f & PF);
|
||||
case 6: // P
|
||||
return jumpConditional(!(f & SF));
|
||||
case 7: // M
|
||||
return jumpConditional(f & SF);
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
throw std::logic_error("Unhandled JP conditional");
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jc() {
|
||||
jumpConditional(F() & CF);
|
||||
bool EightBit::Intel8080::returnConditionalFlag(uint8_t& f, int flag) {
|
||||
switch (flag) {
|
||||
case 0: // NZ
|
||||
return returnConditional(!(f & ZF));
|
||||
case 1: // Z
|
||||
return returnConditional(f & ZF);
|
||||
case 2: // NC
|
||||
return returnConditional(!(f & CF));
|
||||
case 3: // C
|
||||
return returnConditional(f & CF);
|
||||
case 4: // PO
|
||||
return returnConditional(!(f & PF));
|
||||
case 5: // PE
|
||||
return returnConditional(f & PF);
|
||||
case 6: // P
|
||||
return returnConditional(!(f & SF));
|
||||
case 7: // M
|
||||
return returnConditional(f & SF);
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
throw std::logic_error("Unhandled RET conditional");
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jnc() {
|
||||
jumpConditional(!(F() & CF));
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jz() {
|
||||
jumpConditional(F() & ZF);
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jnz() {
|
||||
jumpConditional(!(F() & ZF));
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jpe() {
|
||||
jumpConditional(F() & PF);
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jpo() {
|
||||
jumpConditional(!(F() & PF));
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jm() {
|
||||
jumpConditional(F() & SF);
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::jp() {
|
||||
jumpConditional(!(F() & SF));
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::pchl() {
|
||||
PC() = HL();
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rc() {
|
||||
if (returnConditional(F() & CF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rnc() {
|
||||
if (returnConditional(!(F() & CF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rz() {
|
||||
if (returnConditional(F() & ZF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rnz() {
|
||||
if (returnConditional(!(F() & ZF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rpe() {
|
||||
if (returnConditional(F() & PF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rpo() {
|
||||
if (returnConditional(!(F() & PF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rm() {
|
||||
if (returnConditional(F() & SF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::rp() {
|
||||
if (returnConditional(!(F() & SF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::callDirect() {
|
||||
fetchWord();
|
||||
call();
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cc() {
|
||||
if (callConditional(F() & CF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cnc() {
|
||||
if (callConditional(!(F() & CF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cpe() {
|
||||
if (callConditional(F() & PF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cpo() {
|
||||
if (callConditional(!(F() & PF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cz() {
|
||||
if (callConditional(F() & ZF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cnz() {
|
||||
if (callConditional(!(F() & ZF)))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cm() {
|
||||
if (callConditional(F() & SF))
|
||||
cycles += 6;
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cp() {
|
||||
if (callConditional(!(F() & SF)))
|
||||
cycles += 6;
|
||||
bool EightBit::Intel8080::callConditionalFlag(uint8_t& f, int flag) {
|
||||
switch (flag) {
|
||||
case 0: // NZ
|
||||
return callConditional(!(f & ZF));
|
||||
case 1: // Z
|
||||
return callConditional(f & ZF);
|
||||
case 2: // NC
|
||||
return callConditional(!(f & CF));
|
||||
case 3: // C
|
||||
return callConditional(f & CF);
|
||||
case 4: // PO
|
||||
return callConditional(!(f & PF));
|
||||
case 5: // PE
|
||||
return callConditional(f & PF);
|
||||
case 6: // P
|
||||
return callConditional(!(f & SF));
|
||||
case 7: // M
|
||||
return callConditional(f & SF);
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
throw std::logic_error("Unhandled CALL conditional");
|
||||
}
|
||||
|
||||
#pragma endregion PC manipulation: call/ret/jp/jr
|
||||
@ -353,7 +255,7 @@ void EightBit::Intel8080::daa() {
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::cma() {
|
||||
A() ^= Mask8;
|
||||
A() = ~A();
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::stc() {
|
||||
@ -391,25 +293,437 @@ void EightBit::Intel8080::in() {
|
||||
|
||||
int EightBit::Intel8080::step() {
|
||||
ExecutingInstruction.fire(*this);
|
||||
cycles = 0;
|
||||
return execute(fetchByte());
|
||||
}
|
||||
|
||||
int EightBit::Intel8080::execute(uint8_t opcode) {
|
||||
const auto& instruction = instructions[opcode];
|
||||
return execute(instruction);
|
||||
|
||||
const auto& decoded = getDecodedOpcode(opcode);
|
||||
|
||||
auto x = decoded.x;
|
||||
auto y = decoded.y;
|
||||
auto z = decoded.z;
|
||||
|
||||
auto p = decoded.p;
|
||||
auto q = decoded.q;
|
||||
|
||||
execute(x, y, z, p, q);
|
||||
|
||||
if (cycles == 0)
|
||||
throw std::logic_error("Unhandled opcode");
|
||||
|
||||
return cycles;
|
||||
}
|
||||
|
||||
int EightBit::Intel8080::execute(const Instruction& instruction) {
|
||||
cycles = 0;
|
||||
instruction.vector();
|
||||
return cycles + instruction.count;
|
||||
void EightBit::Intel8080::execute(int x, int y, int z, int p, int q) {
|
||||
auto& a = A();
|
||||
auto& f = F();
|
||||
switch (x) {
|
||||
case 0:
|
||||
switch (z) {
|
||||
case 0: // Relative jumps and assorted ops
|
||||
switch (y) {
|
||||
case 0: // NOP
|
||||
cycles += 4;
|
||||
break;
|
||||
case 1: // EX AF AF'
|
||||
break;
|
||||
case 2: // DJNZ d
|
||||
break;
|
||||
case 3: // JR d
|
||||
break;
|
||||
case 4: // JR cc,d
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 1: // 16-bit load immediate/add
|
||||
switch (q) {
|
||||
case 0: // LD rp,nn
|
||||
fetchWord(RP(p));
|
||||
cycles += 10;
|
||||
break;
|
||||
case 1: // ADD HL,rp
|
||||
dad(RP(p).word);
|
||||
cycles += 11;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // Indirect loading
|
||||
switch (q) {
|
||||
case 0:
|
||||
switch (p) {
|
||||
case 0: // LD (BC),A
|
||||
MEMPTR() = BC();
|
||||
MEMPTR().high = memptrReference() = a;
|
||||
cycles += 7;
|
||||
break;
|
||||
case 1: // LD (DE),A
|
||||
MEMPTR() = DE();
|
||||
MEMPTR().high = memptrReference() = a;
|
||||
cycles += 7;
|
||||
break;
|
||||
case 2: // LD (nn),HL
|
||||
fetchWord();
|
||||
setWordViaMemptr(HL());
|
||||
cycles += 16;
|
||||
break;
|
||||
case 3: // LD (nn),A
|
||||
fetchWord();
|
||||
MEMPTR().high = memptrReference() = a;
|
||||
cycles += 13;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (p) {
|
||||
case 0: // LD A,(BC)
|
||||
MEMPTR() = BC();
|
||||
a = memptrReference();
|
||||
cycles += 7;
|
||||
break;
|
||||
case 1: // LD A,(DE)
|
||||
MEMPTR() = DE();
|
||||
a = memptrReference();
|
||||
cycles += 7;
|
||||
break;
|
||||
case 2: // LD HL,(nn)
|
||||
fetchWord();
|
||||
getWordViaMemptr(HL());
|
||||
cycles += 16;
|
||||
break;
|
||||
case 3: // LD A,(nn)
|
||||
fetchWord();
|
||||
a = memptrReference();
|
||||
cycles += 13;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 3: // 16-bit INC/DEC
|
||||
switch (q) {
|
||||
case 0: // INC rp
|
||||
++RP(p).word;
|
||||
break;
|
||||
case 1: // DEC rp
|
||||
--RP(p).word;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
cycles += 6;
|
||||
break;
|
||||
case 4: // 8-bit INC
|
||||
increment(f, R(y)); // INC r
|
||||
cycles += 4;
|
||||
break;
|
||||
case 5: // 8-bit DEC
|
||||
decrement(f, R(y)); // DEC r
|
||||
cycles += 4;
|
||||
if (y == 6)
|
||||
cycles += 7;
|
||||
break;
|
||||
case 6: { // 8-bit load immediate
|
||||
auto& r = R(y); // LD r,n
|
||||
r = fetchByte();
|
||||
cycles += 7;
|
||||
if (y == 6)
|
||||
cycles += 3;
|
||||
break;
|
||||
}
|
||||
case 7: // Assorted operations on accumulator/flags
|
||||
switch (y) {
|
||||
case 0:
|
||||
rlc();
|
||||
break;
|
||||
case 1:
|
||||
rrc();
|
||||
break;
|
||||
case 2:
|
||||
ral();
|
||||
break;
|
||||
case 3:
|
||||
rar();
|
||||
break;
|
||||
case 4:
|
||||
daa();
|
||||
break;
|
||||
case 5:
|
||||
cma();
|
||||
break;
|
||||
case 6:
|
||||
stc();
|
||||
break;
|
||||
case 7:
|
||||
cmc();
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
cycles += 4;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 1: // 8-bit loading
|
||||
if (z == 6 && y == 6) { // Exception (replaces LD (HL), (HL))
|
||||
halt();
|
||||
} else {
|
||||
R(y) = R(z);
|
||||
if ((y == 6) || (z == 6)) // M operations
|
||||
cycles += 3;
|
||||
}
|
||||
cycles += 4;
|
||||
break;
|
||||
case 2: // Operate on accumulator and register/memory location
|
||||
switch (y) {
|
||||
case 0: // ADD A,r
|
||||
add(R(z));
|
||||
break;
|
||||
case 1: // ADC A,r
|
||||
adc(R(z));
|
||||
break;
|
||||
case 2: // SUB r
|
||||
subtract(f, a, R(z));
|
||||
break;
|
||||
case 3: // SBC A,r
|
||||
sbb(R(z));
|
||||
break;
|
||||
case 4: // AND r
|
||||
anda(R(z));
|
||||
break;
|
||||
case 5: // XOR r
|
||||
xra(R(z));
|
||||
break;
|
||||
case 6: // OR r
|
||||
ora(R(z));
|
||||
break;
|
||||
case 7: // CP r
|
||||
compare(f, a, R(z));
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
cycles += 4;
|
||||
if (z == 6)
|
||||
cycles += 3;
|
||||
break;
|
||||
case 3:
|
||||
switch (z) {
|
||||
case 0: // Conditional return
|
||||
if (returnConditionalFlag(f, y))
|
||||
cycles += 6;
|
||||
cycles += 5;
|
||||
break;
|
||||
case 1: // POP & various ops
|
||||
switch (q) {
|
||||
case 0: // POP rp2[p]
|
||||
popWord(RP2(p));
|
||||
adjustReservedFlags();
|
||||
cycles += 10;
|
||||
break;
|
||||
case 1:
|
||||
switch (p) {
|
||||
case 0: // RET
|
||||
ret();
|
||||
cycles += 10;
|
||||
break;
|
||||
case 1: // EXX
|
||||
break;
|
||||
case 2: // JP HL
|
||||
PC() = HL();
|
||||
cycles += 4;
|
||||
break;
|
||||
case 3: // LD SP,HL
|
||||
SP() = HL();
|
||||
cycles += 4;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 2: // Conditional jump
|
||||
jumpConditionalFlag(f, y);
|
||||
cycles += 10;
|
||||
break;
|
||||
case 3: // Assorted operations
|
||||
switch (y) {
|
||||
case 0: // JP nn
|
||||
fetchWord();
|
||||
jump();
|
||||
cycles += 10;
|
||||
break;
|
||||
case 1: // CB prefix
|
||||
break;
|
||||
case 2: // OUT (n),A
|
||||
out();
|
||||
cycles += 11;
|
||||
break;
|
||||
case 3: // IN A,(n)
|
||||
in();
|
||||
cycles += 11;
|
||||
break;
|
||||
case 4: // EX (SP),HL
|
||||
xhtl();
|
||||
cycles += 19;
|
||||
break;
|
||||
case 5: // EX DE,HL
|
||||
std::swap(DE(), HL());
|
||||
cycles += 4;
|
||||
break;
|
||||
case 6: // DI
|
||||
di();
|
||||
cycles += 4;
|
||||
break;
|
||||
case 7: // EI
|
||||
ei();
|
||||
cycles += 4;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 4: // Conditional call: CALL cc[y], nn
|
||||
if (callConditionalFlag(f, y))
|
||||
cycles += 7;
|
||||
cycles += 10;
|
||||
break;
|
||||
case 5: // PUSH & various ops
|
||||
switch (q) {
|
||||
case 0: // PUSH rp2[p]
|
||||
pushWord(RP2(p));
|
||||
cycles += 11;
|
||||
break;
|
||||
case 1:
|
||||
switch (p) {
|
||||
case 0: // CALL nn
|
||||
fetchWord();
|
||||
call();
|
||||
cycles += 17;
|
||||
break;
|
||||
case 1: // DD prefix
|
||||
break;
|
||||
case 2: // ED prefix
|
||||
break;
|
||||
case 3: // FD prefix
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 6: // Operate on accumulator and immediate operand: alu[y] n
|
||||
switch (y) {
|
||||
case 0: // ADD A,n
|
||||
add(fetchByte());
|
||||
break;
|
||||
case 1: // ADC A,n
|
||||
adc(fetchByte());
|
||||
break;
|
||||
case 2: // SUB n
|
||||
subtract(f, a, fetchByte());
|
||||
break;
|
||||
case 3: // SBC A,n
|
||||
sbb(fetchByte());
|
||||
break;
|
||||
case 4: // AND n
|
||||
anda(fetchByte());
|
||||
break;
|
||||
case 5: // XOR n
|
||||
xra(fetchByte());
|
||||
break;
|
||||
case 6: // OR n
|
||||
ora(fetchByte());
|
||||
break;
|
||||
case 7: // CP n
|
||||
compare(f, a, fetchByte());
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
cycles += 7;
|
||||
break;
|
||||
case 7: // Restart: RST y * 8
|
||||
restart(y << 3);
|
||||
cycles += 11;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
EightBit::Intel8080::Instruction EightBit::Intel8080::INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles) {
|
||||
Intel8080::Instruction returnValue;
|
||||
returnValue.vector = method;
|
||||
returnValue.mode = mode;
|
||||
returnValue.disassembly = disassembly;
|
||||
returnValue.count = cycles;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
EightBit::Intel8080::Instruction EightBit::Intel8080::UNKNOWN() {
|
||||
Intel8080::Instruction returnValue;
|
||||
returnValue.vector = std::bind(&Intel8080::___, this);
|
||||
returnValue.mode = Unknown;
|
||||
returnValue.disassembly = "";
|
||||
returnValue.count = 0;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#define BIND(method) std::bind(&Intel8080:: method, this)
|
||||
|
||||
void EightBit::Intel8080::installInstructions() {
|
||||
instructions = {
|
||||
//// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
/* 0 */ INS(BIND(nop), Implied, "NOP", 4), INS(BIND(nop), Absolute, "LXI B,", 10), INS(BIND(nop), Implied, "STAX B", 7), INS(BIND(nop), Implied, "INX B", 5), INS(BIND(nop), Implied, "INR B", 5), INS(BIND(nop), Implied, "DCR B", 5), INS(BIND(nop), Immediate, "MVI B,", 7), INS(BIND(nop), Implied, "RLC", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD B", 10), INS(BIND(nop), Implied, "LDAX B", 7), INS(BIND(nop), Implied, "DCX B", 5), INS(BIND(nop), Implied, "INR C", 5), INS(BIND(nop), Implied, "DCR C", 5), INS(BIND(nop), Immediate, "MVI C,", 7), INS(BIND(nop), Implied, "RRC", 4), // 0
|
||||
/* 1 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI D,", 10), INS(BIND(nop), Implied, "STAX D", 7), INS(BIND(nop), Implied, "INX D", 5), INS(BIND(nop), Implied, "INR D", 5), INS(BIND(nop), Implied, "DCR D", 5), INS(BIND(nop), Immediate, "MVI D,", 7), INS(BIND(nop), Implied, "RAL", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD D", 10), INS(BIND(nop), Implied, "LDAX D", 7), INS(BIND(nop), Implied, "DCX D", 5), INS(BIND(nop), Implied, "INR E", 5), INS(BIND(nop), Implied, "DCR E", 5), INS(BIND(nop), Immediate, "MVI E,", 7), INS(BIND(nop), Implied, "RAR", 4), // 1
|
||||
/* 2 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI H,", 10), INS(BIND(nop), Absolute, "SHLD", 16), INS(BIND(nop), Implied, "INX H", 5), INS(BIND(nop), Implied, "INR H", 5), INS(BIND(nop), Implied, "DCR H", 5), INS(BIND(nop), Immediate, "MVI H,",7), INS(BIND(nop), Implied, "DAA", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD H", 10), INS(BIND(nop), Absolute, "LHLD ", 16), INS(BIND(nop), Implied, "DCX H", 5), INS(BIND(nop), Implied, "INR L", 5), INS(BIND(nop), Implied, "DCR L", 5), INS(BIND(nop), Immediate, "MVI L,", 7), INS(BIND(nop), Implied, "CMA", 4), // 2
|
||||
/* 3 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI SP,", 10), INS(BIND(nop), Absolute, "STA ", 13), INS(BIND(nop), Implied, "INX SP", 5), INS(BIND(nop), Implied, "INR M", 10), INS(BIND(nop), Implied, "DCR M", 10), INS(BIND(nop), Immediate, "MVI M,", 10), INS(BIND(nop), Implied, "STC", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD SP", 10), INS(BIND(nop), Absolute, "LDA ", 13), INS(BIND(nop), Implied, "DCX SP", 5), INS(BIND(nop), Implied, "INR A", 5), INS(BIND(nop), Implied, "DCR A", 5), INS(BIND(nop), Immediate, "MVI A,", 7), INS(BIND(nop), Implied, "CMC", 4), // 3
|
||||
|
||||
/* 4 */ INS(BIND(nop), Implied, "MOV B,B", 5), INS(BIND(nop), Implied, "MOV B,C", 5), INS(BIND(nop), Implied, "MOV B,D", 5), INS(BIND(nop), Implied, "MOV B,E", 5), INS(BIND(nop), Implied, "MOV B,H", 5), INS(BIND(nop), Implied, "MOV B,L", 5), INS(BIND(nop), Implied, "MOV B,M", 7), INS(BIND(nop), Implied, "MOV B,A", 5), INS(BIND(nop), Implied, "MOV C,B", 5), INS(BIND(nop), Implied, "MOV C,C", 5), INS(BIND(nop), Implied, "MOV C,D", 5), INS(BIND(nop), Implied, "MOV C,E", 5), INS(BIND(nop), Implied, "MOV C,H", 5), INS(BIND(nop), Implied, "MOV C,L", 5), INS(BIND(nop), Implied, "MOV C,M", 7), INS(BIND(nop), Implied, "MOV C,A", 5), // 4
|
||||
/* 5 */ INS(BIND(nop), Implied, "MOV D,B", 5), INS(BIND(nop), Implied, "MOV D,C", 5), INS(BIND(nop), Implied, "MOV D,D", 5), INS(BIND(nop), Implied, "MOV D,E", 5), INS(BIND(nop), Implied, "MOV D,H", 5), INS(BIND(nop), Implied, "MOV D,L", 5), INS(BIND(nop), Implied, "MOV D,M", 7), INS(BIND(nop), Implied, "MOV D,A", 5), INS(BIND(nop), Implied, "MOV E,B", 5), INS(BIND(nop), Implied, "MOV E,C", 5), INS(BIND(nop), Implied, "MOV E,D", 5), INS(BIND(nop), Implied, "MOV E,E", 5), INS(BIND(nop), Implied, "MOV E,H", 5), INS(BIND(nop), Implied, "MOV E,L", 5), INS(BIND(nop), Implied, "MOV E,M", 7), INS(BIND(nop), Implied, "MOV E,A", 5), // 5
|
||||
/* 6 */ INS(BIND(nop), Implied, "MOV H,B", 5), INS(BIND(nop), Implied, "MOV H,C", 5), INS(BIND(nop), Implied, "MOV H,D", 5), INS(BIND(nop), Implied, "MOV H,E", 5), INS(BIND(nop), Implied, "MOV H,H", 5), INS(BIND(nop), Implied, "MOV H,L", 5), INS(BIND(nop), Implied, "MOV H,M", 7), INS(BIND(nop), Implied, "MOV H,A", 5), INS(BIND(nop), Implied, "MOV L,B", 5), INS(BIND(nop), Implied, "MOV L,C", 5), INS(BIND(nop), Implied, "MOV L,D", 5), INS(BIND(nop), Implied, "MOV L,E", 5), INS(BIND(nop), Implied, "MOV L,H", 5), INS(BIND(nop), Implied, "MOV L,L", 5), INS(BIND(nop), Implied, "MOV L,M", 7), INS(BIND(nop), Implied, "MOV L,A", 5), // 6
|
||||
/* 7 */ INS(BIND(nop), Implied, "MOV M,B", 7), INS(BIND(nop), Implied, "MOV M,C", 7), INS(BIND(nop), Implied, "MOV M,D", 7), INS(BIND(nop), Implied, "MOV M,E", 7), INS(BIND(nop), Implied, "MOV M,H", 7), INS(BIND(nop), Implied, "MOV M,L", 7), INS(BIND(nop), Implied, "HLT", 7), INS(BIND(nop), Implied, "MOV M,A", 7), INS(BIND(nop), Implied, "MOV A,B", 5), INS(BIND(nop), Implied, "MOV A,C", 5), INS(BIND(nop), Implied, "MOV A,D", 5), INS(BIND(nop), Implied, "MOV A,E", 5), INS(BIND(nop), Implied, "MOV A,H", 5), INS(BIND(nop), Implied, "MOV A,L", 5), INS(BIND(nop), Implied, "MOV A,M", 7), INS(BIND(nop), Implied, "MOV A,A", 5), // 7
|
||||
|
||||
/* 8 */ INS(BIND(nop), Implied, "ADD B", 4), INS(BIND(nop), Implied, "ADD C", 4), INS(BIND(nop), Implied, "ADD D", 4), INS(BIND(nop), Implied, "ADD E", 4), INS(BIND(nop), Implied, "ADD H", 4), INS(BIND(nop), Implied, "ADD L", 4), INS(BIND(nop), Implied, "ADD M", 7), INS(BIND(nop), Implied, "ADD A", 4), INS(BIND(nop), Implied, "ADC B", 4), INS(BIND(nop), Implied, "ADC C", 4), INS(BIND(nop), Implied, "ADC D", 4), INS(BIND(nop), Implied, "ADC E", 4), INS(BIND(nop), Implied, "ADC H", 4), INS(BIND(nop), Implied, "ADC L", 4), INS(BIND(nop), Implied, "ADC M", 4), INS(BIND(nop), Implied, "ADC A", 4), // 8
|
||||
/* 9 */ INS(BIND(nop), Implied, "SUB B", 4), INS(BIND(nop), Implied, "SUB C", 4), INS(BIND(nop), Implied, "SUB D", 4), INS(BIND(nop), Implied, "SUB E", 4), INS(BIND(nop), Implied, "SUB H", 4), INS(BIND(nop), Implied, "SUB L", 4), INS(BIND(nop), Implied, "SUB M", 7), INS(BIND(nop), Implied, "SUB A", 4), INS(BIND(nop), Implied, "SBB B", 4), INS(BIND(nop), Implied, "SBB C", 4), INS(BIND(nop), Implied, "SBB D", 4), INS(BIND(nop), Implied, "SBB E", 4), INS(BIND(nop), Implied, "SBB H", 4), INS(BIND(nop), Implied, "SBB L", 4), INS(BIND(nop), Implied, "SBB M", 4), INS(BIND(nop), Implied, "SBB A", 4), // 9
|
||||
/* A */ INS(BIND(nop), Implied, "ANA B", 4), INS(BIND(nop), Implied, "ANA C", 4), INS(BIND(nop), Implied, "ANA D", 4), INS(BIND(nop), Implied, "ANA E", 4), INS(BIND(nop), Implied, "ANA H", 4), INS(BIND(nop), Implied, "ANA L", 4), INS(BIND(nop), Implied, "ANA M", 7), INS(BIND(nop), Implied, "ANA A", 4), INS(BIND(nop), Implied, "XRA B", 4), INS(BIND(nop), Implied, "XRA C", 4), INS(BIND(nop), Implied, "XRA D", 4), INS(BIND(nop), Implied, "XRA E", 4), INS(BIND(nop), Implied, "XRA H", 4), INS(BIND(nop), Implied, "XRA L", 4), INS(BIND(nop), Implied, "XRA M", 4), INS(BIND(nop), Implied, "XRA A", 4), // A
|
||||
/* B */ INS(BIND(nop), Implied, "ORA B", 4), INS(BIND(nop), Implied, "ORA C", 4), INS(BIND(nop), Implied, "ORA D", 4), INS(BIND(nop), Implied, "ORA E", 4), INS(BIND(nop), Implied, "ORA H", 4), INS(BIND(nop), Implied, "ORA L", 4), INS(BIND(nop), Implied, "ORA M", 7), INS(BIND(nop), Implied, "ORA A", 4), INS(BIND(nop), Implied, "CMP B", 4), INS(BIND(nop), Implied, "CMP C", 4), INS(BIND(nop), Implied, "CMP D", 4), INS(BIND(nop), Implied, "CMP E", 4), INS(BIND(nop), Implied, "CMP H", 4), INS(BIND(nop), Implied, "CMP L", 4), INS(BIND(nop), Implied, "CMP M", 4), INS(BIND(nop), Implied, "CMP A", 4), // B
|
||||
|
||||
/* C */ INS(BIND(nop), Implied, "RNZ", 5), INS(BIND(nop), Implied, "POP B", 10), INS(BIND(nop), Absolute, "JNZ ", 10), INS(BIND(nop), Absolute, "JMP ", 10), INS(BIND(nop), Absolute, "CNZ ", 11), INS(BIND(nop), Implied, "PUSH B", 11), INS(BIND(nop), Immediate, "ADI ", 7), INS(BIND(nop), Implied, "RST 0", 11), INS(BIND(nop), Implied, "RZ", 11), INS(BIND(nop), Implied, "RET", 10), INS(BIND(nop), Absolute, "JZ ", 10), UNKNOWN(), INS(BIND(nop), Absolute, "CZ ", 11), INS(BIND(nop), Absolute, "CALL ", 17), INS(BIND(nop), Immediate, "ACI ", 7), INS(BIND(nop), Implied, "RST 1", 11), // C
|
||||
/* D */ INS(BIND(nop), Implied, "RNC", 5), INS(BIND(nop), Implied, "POP D", 10), INS(BIND(nop), Absolute, "JNC ", 10), INS(BIND(nop), Immediate, "OUT ", 10), INS(BIND(nop), Absolute, "CNC ", 11), INS(BIND(nop), Implied, "PUSH D", 11), INS(BIND(nop), Immediate, "SUI ", 7), INS(BIND(nop), Implied, "RST 2", 11), INS(BIND(nop), Implied, "RC", 11), UNKNOWN(), INS(BIND(nop), Absolute, "JC ", 10), INS(BIND(nop), Immediate, "IN ", 10), INS(BIND(nop), Absolute, "CC ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "SBI ", 7), INS(BIND(nop), Implied, "RST 3", 11), // D
|
||||
/* E */ INS(BIND(nop), Implied, "RPO", 5), INS(BIND(nop), Implied, "POP H", 10), INS(BIND(nop), Absolute, "JPO ", 10), INS(BIND(nop), Implied, "XHTL", 18), INS(BIND(nop), Absolute, "CPO ", 11), INS(BIND(nop), Implied, "PUSH H", 11), INS(BIND(nop), Immediate, "ANI ", 7), INS(BIND(nop), Implied, "RST 4", 11), INS(BIND(nop), Implied, "RPE", 11), INS(BIND(nop), Implied, "PCHL", 5), INS(BIND(nop), Absolute, "JPE ", 10), INS(BIND(nop), Implied, "XCHG", 4), INS(BIND(nop), Absolute, "CPE ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "XRI ", 7), INS(BIND(nop), Implied, "RST 5", 11), // E
|
||||
/* F */ INS(BIND(nop), Implied, "RP", 5), INS(BIND(nop), Implied, "POP PSW", 10), INS(BIND(nop), Absolute, "JP ", 10), INS(BIND(nop), Implied, "DI ", 4), INS(BIND(nop), Absolute, "CP ", 11), INS(BIND(nop), Implied, "PUSH PSW", 11), INS(BIND(nop), Immediate, "ORI ", 7), INS(BIND(nop), Implied, "RST 6", 11), INS(BIND(nop), Implied, "RM", 11), INS(BIND(nop), Implied, "SPHL", 5), INS(BIND(nop), Absolute, "JM ", 10), INS(BIND(nop), Implied, "EI", 4), INS(BIND(nop), Absolute, "CM ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "CPI ", 7), INS(BIND(nop), Implied, "RST 7", 11), // F
|
||||
};
|
||||
}
|
||||
|
||||
void EightBit::Intel8080::___() {
|
||||
m_memory.ADDRESS().word = PC().word - 1;
|
||||
auto opcode = m_memory.reference();
|
||||
auto message = Disassembler::invalid(opcode);
|
||||
throw std::domain_error(message);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user