From fab9afb6b921fb40c3727cd851aadfbaa9dec59d Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 8 Dec 2014 13:22:02 +0000 Subject: [PATCH] add Intel 8080 cpu --- i8080.cpp | 285 ++++++++++++++++++++++++++++++++++ i8080.h | 457 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ r65emu.h | 1 - 3 files changed, 742 insertions(+), 1 deletion(-) create mode 100644 i8080.cpp create mode 100644 i8080.h diff --git a/i8080.cpp b/i8080.cpp new file mode 100644 index 0000000..42d7d14 --- /dev/null +++ b/i8080.cpp @@ -0,0 +1,285 @@ +#include + +#include "memory.h" +#include "cpu.h" +#include "i8080.h" + +#define CPU_STATE_FMT "%04x %02x %02x %04x %04x %04x %04x %d%d%d%d%d%d%d%d\r",\ + PC, op, A, BC, DE, HL, SP, flags.S, flags.Z,\ + flags.I, flags.H, flags._, flags.P, flags.__, flags.C + +void i8080::step() { + byte op = _mem[PC]; +#if defined(CPU_DEBUG) + if (_debug) + _status(CPU_STATE_FMT); +#endif + PC++; + (this->*_ops[op])(); +} + +void i8080::run(unsigned clocks) { +#if defined(CPU_DEBUG) + if (_debug) { + step(); + return; + } +#endif + while (clocks--) + step(); +} + +void i8080::reset() { + A = 0; + _sr(0); + BC = DE = HL = PC = SP = 0; + _irq_pending = 0; +} + +void i8080::raise(int level) { + if (flags.I) { + flags.I = 0; + _irq_pending = 0; + _push(PC); + PC = level * 8; + } else + _irq_pending = level; +} + +void i8080::ei() { + flags.I = 1; + if (_irq_pending) + raise(_irq_pending); +} + +char *i8080::status() { + static char buf[128]; + byte op = _mem[PC]; + sprintf(buf, "_pc_ op aa _bc_ _de_ _hl_ _sp_ szih_p_c\r" CPU_STATE_FMT); + return buf; +} + +void i8080::checkpoint(Stream &s) { + s.write(A); + s.write(SR); + s.write(BC); + s.write(DE); + s.write(HL); + s.write(PC); + s.write(SP); + s.write(_irq_pending); +} + +void i8080::restore(Stream &s) { + A = s.read(); + SR = s.read(); + BC = s.read(); + DE = s.read(); + HL = s.read(); + PC = s.read(); + SP = s.read(); + _irq_pending = s.read(); +} + +void i8080::daa() { + byte c = flags.C, a = 0, hi = (A & 0xf0) >> 4, lo = A & 0x0f; + if (flags.H || lo > 9) + a = 0x06; + if (flags.C || hi > 0x9 || (hi >= 0x9 && lo > 9)) { + a |= 0x60; + c = 1; + } + _add(a); + flags.C = c; +} + +void i8080::hlt() { + _status("CPU halted at %04x\r%s", (PC-1), status()); + longjmp(*_err, 1); +} + +int i8080::parity_table[] = { + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, +}; + +i8080::i8080(Memory &m, jmp_buf *jb, CPU::statfn s, Ports &d): CPU(m, jb, s) +{ + _ports = &d; + + OP *p = _ops; + + // 0x + *p++ = &i8080::nop; *p++ = &i8080::lxib; + *p++ = &i8080::staxb; *p++ = &i8080::inxb; + *p++ = &i8080::inrb; *p++ = &i8080::dcrb; + *p++ = &i8080::mvib; *p++ = &i8080::rlc; + *p++ = &i8080::nop; *p++ = &i8080::dadb; + *p++ = &i8080::ldaxb; *p++ = &i8080::dcxb; + *p++ = &i8080::inrc; *p++ = &i8080::dcrc; + *p++ = &i8080::mvic; *p++ = &i8080::rrc; + + // 1x + *p++ = &i8080::nop; *p++ = &i8080::lxid; + *p++ = &i8080::staxd; *p++ = &i8080::inxd; + *p++ = &i8080::inrd; *p++ = &i8080::dcrd; + *p++ = &i8080::mvid; *p++ = &i8080::ral; + *p++ = &i8080::nop; *p++ = &i8080::dadd; + *p++ = &i8080::ldaxd; *p++ = &i8080::dcxd; + *p++ = &i8080::inre; *p++ = &i8080::dcre; + *p++ = &i8080::mvie; *p++ = &i8080::rar; + + // 2x + *p++ = &i8080::nop; *p++ = &i8080::lxih; + *p++ = &i8080::shld; *p++ = &i8080::inxh; + *p++ = &i8080::inrh; *p++ = &i8080::dcrh; + *p++ = &i8080::mvih; *p++ = &i8080::daa; + *p++ = &i8080::nop; *p++ = &i8080::dadh; + *p++ = &i8080::lhld; *p++ = &i8080::dcxh; + *p++ = &i8080::inrl; *p++ = &i8080::dcrl; + *p++ = &i8080::mvil; *p++ = &i8080::cma; + + // 3x + *p++ = &i8080::nop; *p++ = &i8080::lxisp; + *p++ = &i8080::sta; *p++ = &i8080::inxsp; + *p++ = &i8080::inrm; *p++ = &i8080::dcrm; + *p++ = &i8080::mvim; *p++ = &i8080::stc; + *p++ = &i8080::nop; *p++ = &i8080::dadsp; + *p++ = &i8080::lda; *p++ = &i8080::dcxsp; + *p++ = &i8080::inra; *p++ = &i8080::dcra; + *p++ = &i8080::mvia; *p++ = &i8080::cmc; + + // 4x + *p++ = &i8080::movbb; *p++ = &i8080::movbc; + *p++ = &i8080::movbd; *p++ = &i8080::movbe; + *p++ = &i8080::movbh; *p++ = &i8080::movbl; + *p++ = &i8080::movbm; *p++ = &i8080::movba; + *p++ = &i8080::movcb; *p++ = &i8080::movcc; + *p++ = &i8080::movcd; *p++ = &i8080::movce; + *p++ = &i8080::movch; *p++ = &i8080::movcl; + *p++ = &i8080::movcm; *p++ = &i8080::movca; + + // 5x + *p++ = &i8080::movdb; *p++ = &i8080::movdc; + *p++ = &i8080::movdd; *p++ = &i8080::movde; + *p++ = &i8080::movdh; *p++ = &i8080::movdl; + *p++ = &i8080::movdm; *p++ = &i8080::movda; + *p++ = &i8080::moveb; *p++ = &i8080::movec; + *p++ = &i8080::moved; *p++ = &i8080::movee; + *p++ = &i8080::moveh; *p++ = &i8080::movel; + *p++ = &i8080::movem; *p++ = &i8080::movea; + + // 6x + *p++ = &i8080::movhb; *p++ = &i8080::movhc; + *p++ = &i8080::movhd; *p++ = &i8080::movhe; + *p++ = &i8080::movhh; *p++ = &i8080::movhl; + *p++ = &i8080::movhm; *p++ = &i8080::movha; + *p++ = &i8080::movlb; *p++ = &i8080::movlc; + *p++ = &i8080::movld; *p++ = &i8080::movle; + *p++ = &i8080::movlh; *p++ = &i8080::movll; + *p++ = &i8080::movlm; *p++ = &i8080::movla; + + // 7x + *p++ = &i8080::movmb; *p++ = &i8080::movmc; + *p++ = &i8080::movmd; *p++ = &i8080::movme; + *p++ = &i8080::movmh; *p++ = &i8080::movml; + *p++ = &i8080::hlt; *p++ = &i8080::movma; + *p++ = &i8080::movab; *p++ = &i8080::movac; + *p++ = &i8080::movad; *p++ = &i8080::movae; + *p++ = &i8080::movah; *p++ = &i8080::moval; + *p++ = &i8080::movam; *p++ = &i8080::movaa; + + // 8x + *p++ = &i8080::addb; *p++ = &i8080::addc; + *p++ = &i8080::addd; *p++ = &i8080::adde; + *p++ = &i8080::addh; *p++ = &i8080::addl; + *p++ = &i8080::addm; *p++ = &i8080::adda; + *p++ = &i8080::adcb; *p++ = &i8080::adcc; + *p++ = &i8080::adcd; *p++ = &i8080::adce; + *p++ = &i8080::adch; *p++ = &i8080::adcl; + *p++ = &i8080::adcm; *p++ = &i8080::adca; + + // 9x + *p++ = &i8080::subb; *p++ = &i8080::subc; + *p++ = &i8080::subd; *p++ = &i8080::sube; + *p++ = &i8080::subh; *p++ = &i8080::subl; + *p++ = &i8080::subm; *p++ = &i8080::suba; + *p++ = &i8080::sbbb; *p++ = &i8080::sbbc; + *p++ = &i8080::sbbd; *p++ = &i8080::sbbe; + *p++ = &i8080::sbbh; *p++ = &i8080::sbbl; + *p++ = &i8080::sbbm; *p++ = &i8080::sbba; + + // Ax + *p++ = &i8080::anab; *p++ = &i8080::anac; + *p++ = &i8080::anad; *p++ = &i8080::anae; + *p++ = &i8080::anah; *p++ = &i8080::anal; + *p++ = &i8080::anam; *p++ = &i8080::anaa; + *p++ = &i8080::xrab; *p++ = &i8080::xrac; + *p++ = &i8080::xrad; *p++ = &i8080::xrae; + *p++ = &i8080::xrah; *p++ = &i8080::xral; + *p++ = &i8080::xram; *p++ = &i8080::xraa; + + // Bx + *p++ = &i8080::orab; *p++ = &i8080::orac; + *p++ = &i8080::orad; *p++ = &i8080::orae; + *p++ = &i8080::orah; *p++ = &i8080::oral; + *p++ = &i8080::oram; *p++ = &i8080::oraa; + *p++ = &i8080::cmpb; *p++ = &i8080::cmpc; + *p++ = &i8080::cmpd; *p++ = &i8080::cmpe; + *p++ = &i8080::cmph; *p++ = &i8080::cmpl; + *p++ = &i8080::cmpm; *p++ = &i8080::cmpa; + + // Cx + *p++ = &i8080::rnz; *p++ = &i8080::popb; + *p++ = &i8080::jnz; *p++ = &i8080::jmp; + *p++ = &i8080::cnz; *p++ = &i8080::pushb; + *p++ = &i8080::adi; *p++ = &i8080::rst0; + *p++ = &i8080::rz; *p++ = &i8080::ret; + *p++ = &i8080::jz; *p++ = &i8080::jmp; + *p++ = &i8080::cz; *p++ = &i8080::call; + *p++ = &i8080::aci; *p++ = &i8080::rst1; + + // Dx + *p++ = &i8080::rnc; *p++ = &i8080::popd; + *p++ = &i8080::jnc; *p++ = &i8080::out; + *p++ = &i8080::cnc; *p++ = &i8080::pushd; + *p++ = &i8080::sui; *p++ = &i8080::rst2; + *p++ = &i8080::rc; *p++ = &i8080::ret; + *p++ = &i8080::jc; *p++ = &i8080::in; + *p++ = &i8080::cc; *p++ = &i8080::call; + *p++ = &i8080::sbi; *p++ = &i8080::rst3; + + // Ex + *p++ = &i8080::rpo; *p++ = &i8080::poph; + *p++ = &i8080::jpo; *p++ = &i8080::xthl; + *p++ = &i8080::cpo; *p++ = &i8080::pushh; + *p++ = &i8080::ani; *p++ = &i8080::rst4; + *p++ = &i8080::rpe; *p++ = &i8080::pchl; + *p++ = &i8080::jpe; *p++ = &i8080::xchg; + *p++ = &i8080::cpe; *p++ = &i8080::call; + *p++ = &i8080::xri; *p++ = &i8080::rst5; + + // Fx + *p++ = &i8080::rp; *p++ = &i8080::pop; + *p++ = &i8080::jp; *p++ = &i8080::di; + *p++ = &i8080::cp; *p++ = &i8080::push; + *p++ = &i8080::ori; *p++ = &i8080::rst6; + *p++ = &i8080::rm; *p++ = &i8080::sphl; + *p++ = &i8080::jm; *p++ = &i8080::ei; + *p++ = &i8080::cm; *p++ = &i8080::call; + *p++ = &i8080::cpi; *p++ = &i8080::rst7; +} diff --git a/i8080.h b/i8080.h new file mode 100644 index 0000000..5ab4be9 --- /dev/null +++ b/i8080.h @@ -0,0 +1,457 @@ +#ifndef __I8080_H__ +#define __I8080_H__ + +#undef sbi +#undef PC + +class i8080: public CPU { +public: + + class Ports { + public: + virtual void out(byte p, byte v, i8080 *cpu) =0; + virtual byte in(byte p, i8080 *cpu) =0; + }; + + i8080(Memory &, jmp_buf *, CPU::statfn, Ports &); + + void run(unsigned); + void reset(); + void raise(int); + char *status(); + + void checkpoint(Stream &); + void restore(Stream &); + + inline byte a() { return A; } + inline byte b() { return B; } + inline byte c() { return C; } + inline byte d() { return D; } + inline byte e() { return E; } + inline byte h() { return H; } + inline byte l() { return L; } + inline word bc() { return BC; } + inline word de() { return DE; } + inline word hl() { return HL; } + inline byte sr() { return SR; } + +private: + inline void step(); + + byte A; + union { + struct { byte C, B; }; + word BC; + }; + union { + struct { byte E, D; }; + word DE; + }; + union { + struct { byte L, H; }; + word HL; + }; + Memory::address PC, SP; + union { + struct { + unsigned C:1; + unsigned __:1; // always 1 + unsigned P:1; + unsigned _:1; // always 0 + unsigned H:1; + unsigned I:1; + unsigned Z:1; + unsigned S:1; + } flags; + byte SR; + }; + int _irq_pending; + Ports *_ports; + + typedef void (i8080::*OP)(); + OP _ops[256]; + + static int parity_table[256]; + + inline word _rw(Memory::address a) { + return _mem[a] + (_mem[a+1] << 8); + } + inline void _sw(Memory::address a, word w) { + _mem[a] = (w & 0xff); + _mem[a+1] = (w >> 8); + } + + inline void _szp(byte r) { + flags.S = ((r & 0x80) != 0); + flags.Z = (r == 0); + flags.P = parity_table[r]; + } + + inline void _szhp(byte b, byte r) { + _szp(r); + flags.H = ((b & 0x0f) > (r & 0x0f)); + } + + inline void _inc(byte &b) { + word w = b + 1; + byte r = w & 0xff; + _szhp(b, r); + b = r; + } + + inline void _dec(byte &b) { + word w = b - 1; + byte r = w & 0xff; + _szhp(b, r); + b = r; + } + + inline void _sr(byte b) { SR = b; flags._ = 0; flags.__ = 1; } + + inline void _dad(word w) { + unsigned long r = HL + w; + HL = (r & 0xffff); + flags.C = (r > 0xffff); + } + + void nop() {} + void lxib() { BC = _rw(PC); PC += 2; } + void staxb() { _mem[BC] = A; } + void inxb() { BC++; } + void inrb() { _inc(B); } + void dcrb() { _dec(B); } + void mvib() { B = _mem[PC++]; } + void rlc() { flags.C = ((A & 0x80) >> 7); A = (A << 1) | flags.C; } + + void dadb() { _dad(BC); } + void ldaxb() { A = _mem[BC]; } + void dcxb() { BC--; } + void inrc() { _inc(C); } + void dcrc() { _dec(C); } + void mvic() { C = _mem[PC++]; } + void rrc() { flags.C = (A & 0x01); A = (A >> 1) | (flags.C << 7); } + + void lxid() { DE = _rw(PC); PC += 2; } + void staxd() { _mem[DE] = A; } + void inxd() { DE++; } + void inrd() { _inc(D); } + void dcrd() { _dec(D); } + void mvid() { D = _mem[PC++]; } + void ral() { + byte b = (A << 1) | flags.C; + flags.C = (A & 0x80) >> 7; + A = b; + } + + void dadd() { _dad(DE); } + void ldaxd() { A = _mem[DE]; } + void dcxd() { DE--; } + void inre() { _inc(E); } + void dcre() { _dec(E); } + void mvie() { E = _mem[PC++]; } + void rar() { + byte b = (A >> 1) | (flags.C << 7); + flags.C = (A & 1); + A = b; + } + + void lxih() { HL = _rw(PC); PC += 2; } + void shld() { _sw(_rw(PC), HL); PC += 2; } + void inxh() { HL++; } + void inrh() { _inc(H); } + void dcrh() { _dec(H); } + void mvih() { H = _mem[PC++]; } + void daa(); + void dadh() { _dad(HL); } + void lhld() { HL = _rw(_rw(PC)); PC += 2; } + void dcxh() { HL--; } + void inrl() { _inc(L); } + void dcrl() { _dec(L); } + void mvil() { L = _mem[PC++]; } + void cma() { A = ~A; } + + void lxisp() { SP = _rw(PC); PC += 2; } + void sta() { _mem[_rw(PC)] = A; PC += 2; } + void inxsp() { SP++; } + void inrm() { byte b = _mem[HL]; _inc(b); _mem[HL] = b; } + void dcrm() { byte b = _mem[HL]; _dec(b); _mem[HL] = b; } + void mvim() { byte b = _mem[PC++]; _mem[HL] = b; } + void stc() { flags.C = 1; } + + void dadsp() { _dad(SP); } + void lda() { A = _mem[_rw(PC)]; PC += 2; } + void dcxsp() { SP--; } + void inra() { _inc(A); } + void dcra() { _dec(A); } + void mvia() { A = _mem[PC++]; } + void cmc() { flags.C = !flags.C; } + void movbb() {} + void movbc() { B = C; } + void movbd() { B = D; } + void movbe() { B = E; } + void movbh() { B = H; } + void movbl() { B = L; } + void movbm() { B = _mem[HL]; } + void movba() { B = A; } + void movcb() { C = B; } + void movcc() {} + void movcd() { C = D; } + void movce() { C = E; } + void movch() { C = H; } + void movcl() { C = L; } + void movcm() { C = _mem[HL]; } + void movca() { C = A; } + void movdb() { D = B; } + void movdc() { D = C; } + void movdd() {} + void movde() { D = E; } + void movdh() { D = H; } + void movdl() { D = L; } + void movdm() { D = _mem[HL]; } + void movda() { D = A; } + void moveb() { E = B; } + void movec() { E = C; } + void moved() { E = D; } + void movee() {} + void moveh() { E = H; } + void movel() { E = L; } + void movem() { E = _mem[HL]; } + void movea() { E = A; } + void movhb() { H = B; } + void movhc() { H = C; } + void movhd() { H = D; } + void movhe() { H = E; } + void movhh() {} + void movhl() { H = L; } + void movhm() { H = _mem[HL]; } + void movha() { H = A; } + void movlb() { L = B; } + void movlc() { L = C; } + void movld() { L = D; } + void movle() { L = E; } + void movlh() { L = H; } + void movll() {} + void movlm() { L = _mem[HL]; } + void movla() { L = A; } + void movmb() { _mem[HL] = B; } + void movmc() { _mem[HL] = C; } + void movmd() { _mem[HL] = D; } + void movme() { _mem[HL] = E; } + void movmh() { _mem[HL] = H; } + void movml() { _mem[HL] = L; } + void hlt(); + void movma() { _mem[HL] = A; } + + void movab() { A = B; } + void movac() { A = C; } + void movad() { A = D; } + void movae() { A = E; } + void movah() { A = H; } + void moval() { A = L; } + void movam() { A = _mem[HL]; } + void movaa() {} + + inline void _add(byte x) { + word w = A + x; + byte b = A; + A = w & 0xff; + _szhp(b, A); + flags.C = w > 0xff; + } + + void addb() { _add(B); } + void addc() { _add(C); } + void addd() { _add(D); } + void adde() { _add(E); } + void addh() { _add(H); } + void addl() { _add(L); } + void addm() { _add(_mem[HL]); } + void adda() { _add(A); } + + inline void _adc(byte x) { + word w = A + x + flags.C; + byte b = A; + A = w & 0xff; + _szhp(b, A); + flags.C = w > 0xff; + } + + void adcb() { _adc(B); } + void adcc() { _adc(C); } + void adcd() { _adc(D); } + void adce() { _adc(E); } + void adch() { _adc(H); } + void adcl() { _adc(L); } + void adcm() { _adc(_mem[HL]); } + void adca() { _adc(A); } + + inline void _sub(byte x) { + word w = A - x; + byte b = A; + A = w & 0xff; + _szhp(b, A); + flags.C = w > 0xff; + } + + void subb() { _sub(B); } + void subc() { _sub(C); } + void subd() { _sub(D); } + void sube() { _sub(E); } + void subh() { _sub(H); } + void subl() { _sub(L); } + void subm() { _sub(_mem[HL]); } + void suba() { _sub(A); } + + inline void _sbc(byte x) { + word w = A - x - flags.C; + byte b = A; + A = w & 0xff; + _szhp(b, A); + flags.C = w > 0xff; + } + + void sbbb() { _sbc(B); } + void sbbc() { _sbc(C); } + void sbbd() { _sbc(D); } + void sbbe() { _sbc(E); } + void sbbh() { _sbc(H); } + void sbbl() { _sbc(L); } + void sbbm() { _sbc(_mem[HL]); } + void sbba() { _sbc(A); } + + inline void _and(byte b) { + A = A & b; + _szp(A); + flags.C = flags.H = 0; + } + + void anab() { _and(B); } + void anac() { _and(C); } + void anad() { _and(D); } + void anae() { _and(E); } + void anah() { _and(H); } + void anal() { _and(L); } + void anam() { _and(_mem[HL]); } + void anaa() { _and(A); } + + inline void _xor(byte b) { + A = A ^ b; + _szp(A); + flags.C = flags.H = 0; + } + + void xrab() { _xor(B); } + void xrac() { _xor(C); } + void xrad() { _xor(D); } + void xrae() { _xor(E); } + void xrah() { _xor(H); } + void xral() { _xor(L); } + void xram() { _xor(_mem[HL]); } + void xraa() { _xor(A); } + + inline void _or(byte b) { + A = A | b; + _szp(A); + flags.C = flags.H = 0; + } + + void orab() { _or(B); } + void orac() { _or(C); } + void orad() { _or(D); } + void orae() { _or(E); } + void orah() { _or(H); } + void oral() { _or(L); } + void oram() { _or(_mem[HL]); } + void oraa() { _or(A); } + + inline void _cmp(byte b) { + word w = A - b; + _szhp(b, w & 0xff); + flags.C = w > 0xff; + } + + void cmpb() { _cmp(B); } + void cmpc() { _cmp(C); } + void cmpd() { _cmp(D); } + void cmpe() { _cmp(E); } + void cmph() { _cmp(H); } + void cmpl() { _cmp(L); } + void cmpm() { _cmp(_mem[HL]); } + void cmpa() { _cmp(A); } + + inline byte _popb() { return _mem[SP++]; } + inline void _pushb(byte b) { _mem[--SP] = b; } + inline word _pop() { word w = _rw(SP); SP += 2; return w; } + inline void _push(word w) { SP -= 2; _sw(SP, w); } + + inline void _jmp(byte c) { if (c) jmp(); else PC += 2; } + inline void _ret(byte c) { if (c) ret(); } + inline void _call(byte c) { if (c) call(); else PC += 2; } + + void rnz() { _ret(!flags.Z); } + void popb() { BC = _pop(); } + void jnz() { _jmp(!flags.Z); } + void jmp() { PC = _rw(PC); } + void cnz() { _call(!flags.Z); } + void pushb() { _push(BC); } + void adi() { _add(_mem[PC++]); } + void rst0() { _push(PC); PC = 0x00; } + void rz() { _ret(flags.Z); } + void ret() { PC = _pop(); } + void jz() { _jmp(flags.Z); } + + void cz() { _call(flags.Z); } + void call() { _push(PC+2); PC = _rw(PC); } + void aci() { _adc(_mem[PC++]); } + void rst1() { _push(PC); PC = 0x08; } + void rnc() { _ret(!flags.C); } + void popd() { DE = _pop(); } + void jnc() { _jmp(!flags.C); } + void out() { _ports->out(_mem[PC++], A, this); } + void cnc() { _call(!flags.C); } + void pushd() { _push(DE); } + void sui() { _sub(_mem[PC++]); } + void rst2() { _push(PC); PC = 0x10; } + void rc() { _ret(flags.C); } + + void jc() { _jmp(flags.C); } + void in() { A = _ports->in(_mem[PC++], this); } + void cc() { _call(flags.C); } + + void sbi() { _sbc(_mem[PC++]); } + void rst3() { _push(PC); PC = 0x18; } + void rpo() { _ret(!flags.P); } + void poph() { HL = _pop(); } + void jpo() { _jmp(!flags.P); } + void xthl() { word w = _pop(); _push(HL); HL = w; } + void cpo() { _call(!flags.P); } + void pushh() { _push(HL); } + void ani() { _and(_mem[PC++]); } + void rst4() { _push(PC); PC = 0x20; } + void rpe() { _ret(flags.P); } + void pchl() { PC = HL; } + void jpe() { _jmp(flags.P); } + void xchg() { word w = DE; DE = HL; HL = w; } + void cpe() { _call(flags.P); } + + void xri() { _xor(_mem[PC++]); } + void rst5() { _push(PC); PC = 0x28; } + void rp() { _ret(!flags.S); } + void pop() { _sr(_popb()); A = _popb(); } + void jp() { _jmp(!flags.S); } + void di() { flags.I = 0; } + void cp() { _call(!flags.S); } + void push() { _pushb(A); _pushb(SR); } + void ori() { _or(_mem[PC++]); } + void rst6() { _push(PC); PC = 0x30; } + void rm() { _ret(flags.S); } + void sphl() { SP = HL; } + void jm() { _jmp(flags.S); } + void ei(); + void cm() { _call(flags.S); } + + void cpi() { _cmp(_mem[PC++]); } + void rst7() { _push(PC); PC = 0x38; } +}; + +#endif diff --git a/r65emu.h b/r65emu.h index 71ef289..e1337f9 100644 --- a/r65emu.h +++ b/r65emu.h @@ -3,7 +3,6 @@ #include "memory.h" #include "cpu.h" -#include "r6502.h" #include "ram.h" #include "spiram.h" #include "prom.h"