1
0
mirror of https://github.com/jscrane/r65emu.git synced 2024-06-11 13:29:34 +00:00

remove cruft

This commit is contained in:
Stephen Crane 2016-01-23 21:15:14 +00:00
parent 6f44a9e17b
commit 8dbba19309
7 changed files with 315 additions and 359 deletions

21
CPU.h
View File

@ -1,32 +1,25 @@
#ifndef __CPU_H__ #ifndef __CPU_H__
#define __CPU_H__ #define __CPU_H__
#ifndef _SETJMP_H
#include <setjmp.h>
#endif
#undef PC #undef PC
class CPU: public Checkpointable { class CPU: public Checkpointable {
public: public:
virtual void run(unsigned instructions) =0; virtual void run(unsigned instructions) =0;
virtual void reset () =0; virtual void reset() =0;
virtual void raise (int level) =0; virtual void raise(int level) =0;
virtual char *status () =0; virtual char *status(char *buf, size_t n) =0;
typedef void (*statfn) (const char *, ...);
virtual void checkpoint(Stream &s) = 0; virtual void checkpoint(Stream &s) = 0;
virtual void restore(Stream &s) = 0; virtual void restore(Stream &s) = 0;
void debug() { _debug = !_debug; } inline void debug() { _debug = !_debug; }
inline bool halted() { return _halted; }
protected: protected:
CPU (Memory &mem, jmp_buf &e, statfn s): _mem(mem), _err(e), _status(s), _debug(false) {} CPU(Memory &mem): _mem(mem), _debug(false), _halted(false) {}
Memory &_mem; Memory &_mem;
Memory::address PC; Memory::address PC;
jmp_buf &_err; bool _debug, _halted;
statfn _status;
bool _debug;
}; };
#endif #endif

View File

@ -5,29 +5,14 @@
#include "ports.h" #include "ports.h"
#include "i8080.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) { void i8080::run(unsigned clocks) {
#if defined(CPU_DEBUG) while (clocks--) {
if (_debug) { byte op = _mem[PC];
step(); PC++;
return; (this->*_ops[op])();
if (_halted)
break;
} }
#endif
while (clocks--)
step();
} }
void i8080::reset() { void i8080::reset() {
@ -35,6 +20,7 @@ void i8080::reset() {
_sr(0); _sr(0);
BC = DE = HL = PC = SP = 0; BC = DE = HL = PC = SP = 0;
_irq_pending = 0; _irq_pending = 0;
_halted = false;
} }
void i8080::raise(int level) { void i8080::raise(int level) {
@ -53,10 +39,12 @@ void i8080::ei() {
raise(_irq_pending); raise(_irq_pending);
} }
char *i8080::status() { char *i8080::status(char *buf, size_t n) {
static char buf[128];
byte op = _mem[PC]; byte op = _mem[PC];
sprintf(buf, "_pc_ op aa _bc_ _de_ _hl_ _sp_ szih_p_c\r" CPU_STATE_FMT); snprintf(buf, n, "_pc_ op aa _bc_ _de_ _hl_ _sp_ szih_p_c\r"
"%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);
return buf; return buf;
} }
@ -94,11 +82,6 @@ void i8080::daa() {
flags.C = c; flags.C = c;
} }
void i8080::hlt() {
_status("CPU halted at %04x\r%s", (PC-1), status());
longjmp(_err, 1);
}
int i8080::parity_table[] = { int i8080::parity_table[] = {
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,
@ -118,7 +101,7 @@ int i8080::parity_table[] = {
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,
}; };
i8080::i8080(Memory &m, jmp_buf &jb, CPU::statfn s, PortDevice<i8080> &d): CPU(m, jb, s) i8080::i8080(Memory &m, PortDevice<i8080> &d): CPU(m)
{ {
_ports = &d; _ports = &d;

View File

@ -6,12 +6,12 @@
class i8080: public CPU { class i8080: public CPU {
public: public:
i8080(Memory &, jmp_buf &, CPU::statfn, PortDevice<i8080> &); i8080(Memory &, PortDevice<i8080> &);
void run(unsigned); void run(unsigned);
void reset(); void reset();
void raise(int); void raise(int);
char *status(); char *status(char *buf, size_t n);
void checkpoint(Stream &); void checkpoint(Stream &);
void restore(Stream &); void restore(Stream &);
@ -29,8 +29,6 @@ public:
inline byte sr() { return SR; } inline byte sr() { return SR; }
private: private:
inline void step();
byte A; byte A;
union { union {
struct { byte C, B; }; struct { byte C, B; };
@ -232,7 +230,7 @@ private:
void movme() { _mem[HL] = E; } void movme() { _mem[HL] = E; }
void movmh() { _mem[HL] = H; } void movmh() { _mem[HL] = H; }
void movml() { _mem[HL] = L; } void movml() { _mem[HL] = L; }
void hlt(); void hlt() { _halted = true; PC--; }
void movma() { _mem[HL] = A; } void movma() { _mem[HL] = A; }
void movab() { A = B; } void movab() { A = B; }

138
r6502.cpp
View File

@ -5,31 +5,14 @@
#include "CPU.h" #include "CPU.h"
#include "r6502.h" #include "r6502.h"
#define CPU_STATE_FMT "%02x %02x %02x %02x %d%d%d%d%d%d%d%d %04x\r",\
A,X,Y,S,P.bits.N,P.bits.V,P.bits._,P.bits.B,\
P.bits.D,P.bits.I,P.bits.Z,P.bits.C,PC
inline void r6502::step() {
byte op = _mem[PC];
#ifdef CPU_DEBUG
if (_debug) {
flags();
_status(CPU_STATE_FMT);
}
#endif
PC++;
(this->*_ops[op])();
}
void r6502::run(unsigned clocks) { void r6502::run(unsigned clocks) {
#ifdef CPU_DEBUG while (clocks--) {
if (_debug) { byte op = _mem[PC];
step(); PC++;
return; (this->*_ops[op])();
if (_halted)
break;
} }
#endif
while (clocks--)
step();
} }
byte r6502::flags() { byte r6502::flags() {
@ -38,13 +21,16 @@ byte r6502::flags() {
P.bits.Z = !Z; P.bits.Z = !Z;
P.bits.C = C; P.bits.C = C;
P.bits._ = 1; P.bits._ = 1;
return P.value; return P.flags;
} }
char *r6502::status () { char *r6502::status(char *buf, size_t n) {
static char buf[128];
flags(); flags();
sprintf (buf, "aa xx yy sp nv_bdizc _pc_\r" CPU_STATE_FMT); snprintf(buf, n, "aa xx yy sp nv_bdizc _pc_\r"
"%02x %02x %02x %02x %d%d%d%d%d%d%d%d %04x\r",
A, X, Y, S, P.bits.N, P.bits.V, P.bits._, P.bits.B,
P.bits.D, P.bits.I, P.bits.Z, P.bits.C, PC);
return buf; return buf;
} }
@ -52,18 +38,18 @@ void r6502::checkpoint(Stream &s)
{ {
s.write(PC / 0xff); s.write(PC / 0xff);
s.write(PC % 0xff); s.write(PC % 0xff);
s.write(S); s.write(S);
s.write(A); s.write(A);
s.write(X); s.write(X);
s.write(Y); s.write(Y);
s.write(N); s.write(N);
s.write(V); s.write(V);
s.write(B); s.write(B);
s.write(D); s.write(D);
s.write(I); s.write(I);
s.write(Z); s.write(Z);
s.write(C); s.write(C);
s.write(P.value); s.write(P.flags);
} }
void r6502::restore(Stream &s) void r6502::restore(Stream &s)
@ -81,83 +67,83 @@ void r6502::restore(Stream &s)
I = s.read(); I = s.read();
Z = s.read(); Z = s.read();
C = s.read(); C = s.read();
P.value = s.read(); P.flags = s.read();
} }
void r6502::raise (int level) { void r6502::raise(int level) {
if (level < 0) if (level < 0)
nmi (); nmi();
else if (!P.bits.I) else if (!P.bits.I)
irq (); irq();
else else
_irq = true; _irq = true;
} }
void r6502::irq () { void r6502::irq() {
pusha (PC); pusha(PC);
P.bits.B = 0; P.bits.B = 0;
pushb (flags ()); pushb(flags());
P.bits.B = 1; P.bits.B = 1;
P.bits.I = 1; P.bits.I = 1;
PC = vector (ibvec); PC = vector(ibvec);
_irq = false; _irq = false;
} }
void r6502::brk () { void r6502::brk() {
if (!P.bits.I) { if (!P.bits.I) {
pusha (PC); pusha(PC);
P.bits.B = 1; P.bits.B = 1;
php (); php();
P.bits.I = 1; P.bits.I = 1;
PC = vector (ibvec); PC = vector(ibvec);
} }
P.bits.B = 1; P.bits.B = 1;
P.bits._ = 1; P.bits._ = 1;
} }
void r6502::rti () { void r6502::rti() {
plp (); plp();
PC = popa (); PC = popa();
} }
void r6502::cli () { void r6502::cli() {
P.bits.I = 0; P.bits.I = 0;
if (_irq) if (_irq)
irq(); irq();
} }
void r6502::nmi () { void r6502::nmi() {
pusha (PC); pusha(PC);
php (); php();
P.bits.I = 1; P.bits.I = 1;
PC = vector (nmivec); PC = vector(nmivec);
} }
// php and plp are complicated by the representation // php and plp are complicated by the representation
// of the processor state for efficient normal operation // of the processor state for efficient normal operation
void r6502::php () { void r6502::php() {
P.bits.B = 1; P.bits.B = 1;
pushb (flags ()); pushb(flags());
} }
void r6502::plp () { void r6502::plp() {
P.value = popb (); P.flags = popb();
N = P.bits.N? 0x80: 0; N = P.bits.N? 0x80: 0;
V = P.bits.V; V = P.bits.V;
Z = !P.bits.Z; Z = !P.bits.Z;
C = P.bits.C; C = P.bits.C;
} }
void r6502::rts () { void r6502::rts() {
PC = popa ()+1; PC = popa()+1;
} }
void r6502::jsr () { void r6502::jsr() {
pusha (PC+1); pusha(PC+1);
PC = vector (PC); PC = vector(PC);
} }
void r6502::_adc (byte d) { void r6502::_adc(byte d) {
if (P.bits.D) { if (P.bits.D) {
int r = _fromBCD[A] + _fromBCD[d] + C; int r = _fromBCD[A] + _fromBCD[d] + C;
C = (r > 99); C = (r > 99);
@ -174,7 +160,7 @@ void r6502::_adc (byte d) {
Z = A; Z = A;
} }
void r6502::sbcd (byte d) { void r6502::sbcd(byte d) {
int r = _fromBCD[A] - _fromBCD[d] - !C; int r = _fromBCD[A] - _fromBCD[d] - !C;
C = (r >= 0); C = (r >= 0);
if (r < 0) r += 100; if (r < 0) r += 100;
@ -185,14 +171,14 @@ void r6502::sbcd (byte d) {
} }
void r6502::ill() { void r6502::ill() {
_status("Illegal instruction at %04x!\r\n%s", (PC-1), status()); --PC;
longjmp(_err, 1); _halted = true;
} }
void r6502::reset() void r6502::reset()
{ {
_debug = false; _debug = _halted = false;
P.value = 0; P.flags = 0;
P.bits._ = 1; P.bits._ = 1;
P.bits.B = 1; P.bits.B = 1;
_irq = false; _irq = false;
@ -200,13 +186,13 @@ void r6502::reset()
PC = vector(resvec); PC = vector(resvec);
} }
r6502::r6502 (Memory &m, jmp_buf &e, CPU::statfn s): CPU (m,e,s) { r6502::r6502(Memory &m): CPU(m) {
for (int i=0; i < 256; i++) { for (int i=0; i < 256; i++) {
_fromBCD[i] = ((i >> 4) & 0x0f)*10 + (i & 0x0f); _fromBCD[i] = ((i >> 4) & 0x0f)*10 + (i & 0x0f);
_toBCD[i] = (((i % 100) / 10) << 4) | (i % 10); _toBCD[i] = (((i % 100) / 10) << 4) | (i % 10);
} }
OP *p = _ops; OP *p = _ops;
*p++=&r6502::brk; *p++=&r6502::ora_ix; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::brk; *p++=&r6502::ora_ix; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::ora_z; *p++=&r6502::asl_z; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::ora_z; *p++=&r6502::asl_z; *p++=&r6502::ill;

403
r6502.h
View File

@ -9,11 +9,11 @@ public:
void raise(int); void raise(int);
void reset(); void reset();
void run(unsigned); void run(unsigned);
char *status(); char *status(char *buf, size_t n);
void checkpoint(Stream &); void checkpoint(Stream &);
void restore(Stream &); void restore(Stream &);
r6502 (Memory &, jmp_buf &, CPU::statfn); r6502(Memory &);
private: private:
/* registers */ /* registers */
byte S, A, X, Y; byte S, A, X, Y;
@ -29,33 +29,32 @@ private:
unsigned V:1; unsigned V:1;
unsigned N:1; unsigned N:1;
} bits; } bits;
byte value; byte flags;
} P; } P;
byte _toBCD[256], _fromBCD[256]; // BCD maps byte _toBCD[256], _fromBCD[256]; // BCD maps
bool _irq; // interrupt pending? bool _irq; // interrupt pending?
void step();
void irq(); void irq();
void nmi(); void nmi();
byte flags(); byte flags();
/* stack */ /* stack */
inline void pusha (Memory::address ret) { inline void pusha(Memory::address ret) {
_mem[0x0100+S--] = ret >> 8; _mem[0x0100+S--] = ret >> 8;
_mem[0x0100+S--] = ret & 0xff; _mem[0x0100+S--] = ret & 0xff;
} }
inline void pushb (byte b) { inline void pushb(byte b) {
_mem[0x0100+S--] = b; _mem[0x0100+S--] = b;
} }
inline byte popb () { inline byte popb() {
return _mem[++S+0x0100]; return _mem[++S+0x0100];
} }
inline Memory::address popa () { inline Memory::address popa() {
byte b = popb (); byte b = popb();
return ((popb () << 8) | b); return (popb() << 8) | b;
} }
static const Memory::address nmivec = 0xfffa; static const Memory::address nmivec = 0xfffa;
@ -67,63 +66,63 @@ private:
} }
/* operators */ /* operators */
inline void _cmp (byte a) { Z=N=A-a; C=(A>=a); } inline void _cmp(byte a) { Z=N=A-a; C=(A>=a); }
inline void _cpx (byte a) { Z=N=X-a; C=(X>=a); } inline void _cpx(byte a) { Z=N=X-a; C=(X>=a); }
inline void _cpy (byte a) { Z=N=Y-a; C=(Y>=a); } inline void _cpy(byte a) { Z=N=Y-a; C=(Y>=a); }
inline void _and (byte a) { Z=N=A&=a; } inline void _and(byte a) { Z=N=A&=a; }
inline void _eor (byte a) { Z=N=A^=a; } inline void _eor(byte a) { Z=N=A^=a; }
inline void _ora (byte a) { Z=N=A|=a; } inline void _ora(byte a) { Z=N=A|=a; }
inline void _lda (byte a) { Z=N=A=a; } inline void _lda(byte a) { Z=N=A=a; }
inline void _ldx (byte a) { Z=N=X=a; } inline void _ldx(byte a) { Z=N=X=a; }
inline void _ldy (byte a) { Z=N=Y=a; } inline void _ldy(byte a) { Z=N=Y=a; }
/* modes */ /* modes */
inline Memory::address _a () { inline Memory::address _a() {
Memory::address a = _mem[PC++]; Memory::address a = _mem[PC++];
return a | (_mem[PC++] << 8); return a | (_mem[PC++] << 8);
} }
inline Memory::address _ax () { return _a()+X; } inline Memory::address _ax() { return _a()+X; }
inline Memory::address _ay () { return _a()+Y; } inline Memory::address _ay() { return _a()+Y; }
inline Memory::address _z () { return _mem[PC++]; } inline Memory::address _z() { return _mem[PC++]; }
inline Memory::address _zx () { return (_z()+X) & 0xff; } inline Memory::address _zx() { return (_z()+X) & 0xff; }
inline Memory::address _zy () { return (_z()+Y) & 0xff; } inline Memory::address _zy() { return (_z()+Y) & 0xff; }
inline Memory::address _i (Memory::address a) { inline Memory::address _i(Memory::address a) {
return (_mem[a+1]<<8)|_mem[a]; return (_mem[a+1]<<8)|_mem[a];
} }
inline Memory::address _ix () { return _i(_zx()); } inline Memory::address _ix() { return _i(_zx()); }
inline Memory::address _iy () { return _i(_mem[PC++])+Y; } inline Memory::address _iy() { return _i(_mem[PC++])+Y; }
void _adc (byte a); void _adc(byte a);
void _sbc (byte a) { if (P.bits.D) sbcd(a); else _adc(~a); } void _sbc(byte a) { if (P.bits.D) sbcd(a); else _adc(~a); }
void sbcd (byte a); void sbcd(byte a);
inline byte __ror (byte b) { inline byte __ror(byte b) {
N=b>>1; if (C) N|=0x80; C=b&1; return Z=N; N=b>>1; if (C) N|=0x80; C=b&1; return Z=N;
} }
inline void _ror (Memory::address a) { inline void _ror(Memory::address a) {
_mem[a] = __ror(_mem[a]); _mem[a] = __ror(_mem[a]);
} }
inline byte __rol (byte b) { inline byte __rol(byte b) {
N=b<<1; if (C) N|=1; C=(b&0x80)!=0; return Z=N; N=b<<1; if (C) N|=1; C=(b&0x80)!=0; return Z=N;
} }
inline void _rol (Memory::address a) { inline void _rol(Memory::address a) {
_mem[a] = __rol(_mem[a]); _mem[a] = __rol(_mem[a]);
} }
inline byte __asl (byte b) { C=(b&0x80)!=0; return Z=N=b<<1; } inline byte __asl(byte b) { C=(b&0x80)!=0; return Z=N=b<<1; }
inline void _asl (Memory::address a) { inline void _asl(Memory::address a) {
_mem[a] = __asl(_mem[a]); _mem[a] = __asl(_mem[a]);
} }
inline byte __lsr (byte b) { C=b&1; Z=b>>1; N=0; return Z; } inline byte __lsr(byte b) { C=b&1; Z=b>>1; N=0; return Z; }
inline void _lsr (Memory::address a) { inline void _lsr(Memory::address a) {
_mem[a] = __lsr(_mem[a]); _mem[a] = __lsr(_mem[a]);
} }
inline void _inc (Memory::address a) { inline void _inc(Memory::address a) {
Z=N=1+_mem[a]; _mem[a]=Z; Z=N=1+_mem[a]; _mem[a]=Z;
} }
inline void _dec (Memory::address a) { inline void _dec(Memory::address a) {
Z=N=_mem[a]-1; _mem[a]=Z; Z=N=_mem[a]-1; _mem[a]=Z;
} }
inline void _bit (byte z) { V=((z & 0x40)!=0); N=(z & 0x80); Z=(A & z); } inline void _bit(byte z) { V=((z & 0x40)!=0); N=(z & 0x80); Z=(A & z); }
inline void _bra() { inline void _bra() {
byte b = _mem[PC]; byte b = _mem[PC];
PC += b; PC += b;
@ -134,180 +133,180 @@ private:
typedef void (r6502::*OP)(); OP _ops[256]; typedef void (r6502::*OP)(); OP _ops[256];
/* operations */ /* operations */
void brk (); void brk();
void ora_ix () { _ora (_mem[_ix()]); } void ora_ix() { _ora(_mem[_ix()]); }
void ill (); void ill();
void nop2 () { PC++; } void nop2() { PC++; }
void ora_z () { _ora (_mem[_z()]); } void ora_z() { _ora(_mem[_z()]); }
void asl_z () { _asl (_z()); } void asl_z() { _asl(_z()); }
void php (); void php();
void ora_ () { _ora (_mem[PC++]); } void ora_() { _ora(_mem[PC++]); }
void asl () { C=(A&0x80)!=0; Z=N=A<<=1; } void asl() { C=(A&0x80)!=0; Z=N=A<<=1; }
void nop3 () { PC+=2; } void nop3() { PC+=2; }
void ora_a () { _ora (_mem[_a()]); } void ora_a() { _ora(_mem[_a()]); }
void asl_a () { _asl (_a()); } void asl_a() { _asl(_a()); }
// 10 // 10
void bpl () { if (!(N & 0x80)) _bra(); PC++; } void bpl() { if (!(N & 0x80)) _bra(); PC++; }
void ora_iy () { _ora (_mem[_iy()]); } void ora_iy() { _ora(_mem[_iy()]); }
void ora_zx () { _ora (_mem[_zx()]); } void ora_zx() { _ora(_mem[_zx()]); }
void asl_zx () { _asl (_zx()); } void asl_zx() { _asl(_zx()); }
void clc () { C=0; } void clc() { C=0; }
void ora_ay () { _ora (_mem[_ay()]); } void ora_ay() { _ora(_mem[_ay()]); }
void nop () { } void nop() {}
void ora_ax () { _ora (_mem[_ax()]); } void ora_ax() { _ora(_mem[_ax()]); }
void asl_ax () { _asl (_ax()); } void asl_ax() { _asl(_ax()); }
// 20 // 20
void jsr (); void jsr();
void and_ix () { _and (_mem[_ix()]); } void and_ix() { _and(_mem[_ix()]); }
void bit_z () { _bit (_mem[_z()]); } void bit_z() { _bit(_mem[_z()]); }
void and_z () { _and (_mem[_z()]); } void and_z() { _and(_mem[_z()]); }
void rol_z () { _rol (_z()); } void rol_z() { _rol(_z()); }
void plp (); void plp();
void and_ () { _and (_mem[PC++]); } void and_() { _and(_mem[PC++]); }
void rol () { A=__rol (A); } void rol() { A=__rol(A); }
void bit_a () { _bit (_mem[_a()]); } void bit_a() { _bit(_mem[_a()]); }
void and_a () { _and (_mem[_a()]); } void and_a() { _and(_mem[_a()]); }
void rol_a () { _rol (_a()); } void rol_a() { _rol(_a()); }
// 30 // 30
void bmi () { if (N & 0x80) _bra(); PC++; } void bmi() { if (N & 0x80) _bra(); PC++; }
void and_iy () { _and (_mem[_iy()]); } void and_iy() { _and(_mem[_iy()]); }
void and_zx () { _and (_mem[_zx()]); } void and_zx() { _and(_mem[_zx()]); }
void rol_zx () { _rol (_zx()); } void rol_zx() { _rol(_zx()); }
void sec () { C=1; } void sec() { C=1; }
void and_ay () { _and (_mem[_ay()]); } void and_ay() { _and(_mem[_ay()]); }
void and_ax () { _and (_mem[_ax()]); } void and_ax() { _and(_mem[_ax()]); }
void rol_ax () { _rol (_ax()); } void rol_ax() { _rol(_ax()); }
// 40 // 40
void rti (); void rti();
void eor_ix () { _eor (_mem[_ix()]); } void eor_ix() { _eor(_mem[_ix()]); }
void eor_z () { _eor (_mem[_z()]); } void eor_z() { _eor(_mem[_z()]); }
void lsr_z () { _lsr (_z()); } void lsr_z() { _lsr(_z()); }
void pha () { pushb (A); } void pha() { pushb(A); }
void eor_ () { _eor (_mem[PC++]); } void eor_() { _eor(_mem[PC++]); }
void lsr_ () { A=__lsr(A); } void lsr_() { A=__lsr(A); }
void jmp () { PC = _a (); } void jmp() { PC = _a(); }
void eor_a () { _eor (_mem[_a()]); } void eor_a() { _eor(_mem[_a()]); }
void lsr_a () { _lsr (_a()); } void lsr_a() { _lsr(_a()); }
// 50 // 50
void bvc () { if (!V) _bra(); PC++; } void bvc() { if (!V) _bra(); PC++; }
void eor_iy () { _eor (_mem[_iy()]); } void eor_iy() { _eor(_mem[_iy()]); }
void eor_zx () { _eor (_mem[_zx()]); } void eor_zx() { _eor(_mem[_zx()]); }
void lsr_zx () { _lsr (_zx()); } void lsr_zx() { _lsr(_zx()); }
void cli (); void cli();
void eor_ay () { _eor (_mem[_ay()]); } void eor_ay() { _eor(_mem[_ay()]); }
void eor_ax () { _eor (_mem[_ax()]); } void eor_ax() { _eor(_mem[_ax()]); }
void lsr_ax () { _lsr (_ax()); } void lsr_ax() { _lsr(_ax()); }
// 60 // 60
void rts (); void rts();
void adc_ix () { _adc (_mem[_ix()]); } void adc_ix() { _adc(_mem[_ix()]); }
void adc_z () { _adc (_mem[_z()]); } void adc_z() { _adc(_mem[_z()]); }
void ror_z () { _ror (_z()); } void ror_z() { _ror(_z()); }
void pla () { Z=N=A=popb (); } void pla() { Z=N=A=popb(); }
void adc_ () { _adc (_mem[PC++]); } void adc_() { _adc(_mem[PC++]); }
void ror_ () { A=__ror (A); } void ror_() { A=__ror(A); }
void jmp_i () { PC = _i(_a()); } void jmp_i() { PC = _i(_a()); }
void adc_a () { _adc (_mem[_a()]); } void adc_a() { _adc(_mem[_a()]); }
void ror_a () { _ror (_a()); } void ror_a() { _ror(_a()); }
// 70 // 70
void bvs () { if (V) _bra(); PC++; } void bvs() { if (V) _bra(); PC++; }
void adc_iy () { _adc (_mem[_iy()]); } void adc_iy() { _adc(_mem[_iy()]); }
void adc_zx () { _adc (_mem[_zx()]); } void adc_zx() { _adc(_mem[_zx()]); }
void ror_zx () { _ror (_zx ()); } void ror_zx() { _ror(_zx()); }
void sei () { P.bits.I = 1; } void sei() { P.bits.I = 1; }
void adc_ay () { _adc (_mem[_ay()]); } void adc_ay() { _adc(_mem[_ay()]); }
void adc_ax () { _adc (_mem[_ax()]); } void adc_ax() { _adc(_mem[_ax()]); }
void ror_ax () { _ror (_ax ()); } void ror_ax() { _ror(_ax()); }
// 80 // 80
void sta_ix () { _mem[_ix()] = A; } void sta_ix() { _mem[_ix()] = A; }
void sty_z () { _mem[_z()] = Y; } void sty_z() { _mem[_z()] = Y; }
void sta_z () { _mem[_z()] = A; } void sta_z() { _mem[_z()] = A; }
void stx_z () { _mem[_z()] = X; } void stx_z() { _mem[_z()] = X; }
void dey () { Z=N=--Y; } void dey() { Z=N=--Y; }
void txa () { Z=N=A=X; } void txa() { Z=N=A=X; }
void sty_a () { _mem[_a()] = Y; } void sty_a() { _mem[_a()] = Y; }
void sta_a () { _mem[_a()] = A; } void sta_a() { _mem[_a()] = A; }
void stx_a () { _mem[_a()] = X; } void stx_a() { _mem[_a()] = X; }
// 90 // 90
void bcc () { if (!C) _bra(); PC++; } void bcc() { if (!C) _bra(); PC++; }
void sta_iy () { _mem[_iy()] = A; } void sta_iy() { _mem[_iy()] = A; }
void sty_zx () { _mem[_zx()] = Y; } void sty_zx() { _mem[_zx()] = Y; }
void sta_zx () { _mem[_zx()] = A; } void sta_zx() { _mem[_zx()] = A; }
void stx_zy () { _mem[_zy()] = X; } void stx_zy() { _mem[_zy()] = X; }
void tya () { Z=N=A=Y; } void tya() { Z=N=A=Y; }
void sta_ay () { _mem[_ay()] = A; } void sta_ay() { _mem[_ay()] = A; }
void txs () { S=X; } void txs() { S=X; }
void sta_ax () { _mem[_ax()] = A; } void sta_ax() { _mem[_ax()] = A; }
// a0 // a0
void ldy_ () { _ldy (_mem[PC++]); } void ldy_() { _ldy(_mem[PC++]); }
void lda_ix () { _lda (_mem[_ix()]); } void lda_ix() { _lda(_mem[_ix()]); }
void ldx_ () { _ldx (_mem[PC++]); } void ldx_() { _ldx(_mem[PC++]); }
void lax_ix () { lda_ix (); X=A; } void lax_ix() { lda_ix(); X=A; }
void ldy_z () { _ldy (_mem[_z()]); } void ldy_z() { _ldy(_mem[_z()]); }
void lda_z () { _lda (_mem[_z()]); } void lda_z() { _lda(_mem[_z()]); }
void ldx_z () { _ldx (_mem[_z()]); } void ldx_z() { _ldx(_mem[_z()]); }
void lax_z () { lda_z (); X=A; } void lax_z() { lda_z(); X=A; }
void tay () { Z=N=Y=A; } void tay() { Z=N=Y=A; }
void lda_ () { _lda (_mem[PC++]); } void lda_() { _lda(_mem[PC++]); }
void tax () { Z=N=X=A; } void tax() { Z=N=X=A; }
void ldy_a () { _ldy (_mem[_a()]); } void ldy_a() { _ldy(_mem[_a()]); }
void lda_a () { _lda (_mem[_a()]); } void lda_a() { _lda(_mem[_a()]); }
void ldx_a () { _ldx (_mem[_a()]); } void ldx_a() { _ldx(_mem[_a()]); }
void lax_a () { lda_a (); X=A; } void lax_a() { lda_a(); X=A; }
// b0 // b0
void bcs () { if (C) _bra(); PC++; } void bcs() { if (C) _bra(); PC++; }
void lda_iy () { _lda (_mem[_iy()]); } void lda_iy() { _lda(_mem[_iy()]); }
void lax_iy () { lda_iy (); X=A; } void lax_iy() { lda_iy(); X=A; }
void ldy_zx () { _ldy (_mem[_zx()]); } void ldy_zx() { _ldy(_mem[_zx()]); }
void lda_zx () { _lda (_mem[_zx()]); } void lda_zx() { _lda(_mem[_zx()]); }
void ldx_zy () { _ldx (_mem[_zy()]); } void ldx_zy() { _ldx(_mem[_zy()]); }
void lax_zy () { ldx_zy (); A=X; } void lax_zy() { ldx_zy(); A=X; }
void clv () { V=0; } void clv() { V=0; }
void lda_ay () { _lda (_mem[_ay()]); } void lda_ay() { _lda(_mem[_ay()]); }
void tsx () { Z=N=X=S; } void tsx() { Z=N=X=S; }
void ldy_ax () { _ldy (_mem[_ax()]); } void ldy_ax() { _ldy(_mem[_ax()]); }
void lda_ax () { _lda (_mem[_ax()]); } void lda_ax() { _lda(_mem[_ax()]); }
void ldx_ay () { _ldx (_mem[_ay()]); } void ldx_ay() { _ldx(_mem[_ay()]); }
void lax_ay () { ldx_ay (); A=X; } void lax_ay() { ldx_ay(); A=X; }
// c0 // c0
void cpy_ () { _cpy (_mem[PC++]); } void cpy_() { _cpy(_mem[PC++]); }
void cmp_ix () { _cmp (_mem[_ix()]); } void cmp_ix() { _cmp(_mem[_ix()]); }
void cpy_z () { _cpy (_mem[_z()]); } void cpy_z() { _cpy(_mem[_z()]); }
void cmp_z () { _cmp (_mem[_z()]); } void cmp_z() { _cmp(_mem[_z()]); }
void dec_z () { _dec (_z()); } void dec_z() { _dec(_z()); }
void iny () { Z=N=++Y; } void iny() { Z=N=++Y; }
void cmp_ () { _cmp (_mem[PC++]); } void cmp_() { _cmp(_mem[PC++]); }
void dex () { Z=N=--X; } void dex() { Z=N=--X; }
void cpy_a () { _cpy (_mem[_a()]); } void cpy_a() { _cpy(_mem[_a()]); }
void cmp_a () { _cmp (_mem[_a()]); } void cmp_a() { _cmp(_mem[_a()]); }
void dec_a () { _dec (_a()); } void dec_a() { _dec(_a()); }
// d0 // d0
void bne () { if (Z) _bra(); PC++; } void bne() { if (Z) _bra(); PC++; }
void cmp_iy () { _cmp (_mem[_iy()]); } void cmp_iy() { _cmp(_mem[_iy()]); }
void cmp_zx () { _cmp (_mem[_zx()]); } void cmp_zx() { _cmp(_mem[_zx()]); }
void dec_zx () { _dec (_zx()); } void dec_zx() { _dec(_zx()); }
void cld () { P.bits.D = 0; } void cld() { P.bits.D = 0; }
void cmp_ay () { _cmp (_mem[_ay()]); } void cmp_ay() { _cmp(_mem[_ay()]); }
void cmp_ax () { _cmp (_mem[_ax()]); } void cmp_ax() { _cmp(_mem[_ax()]); }
void dec_ax () { _dec (_ax()); } void dec_ax() { _dec(_ax()); }
// e0 // e0
void cpx_ () { _cpx (_mem[PC++]); } void cpx_() { _cpx(_mem[PC++]); }
void sbc_ix () { _sbc (_mem[_ix()]); } void sbc_ix() { _sbc(_mem[_ix()]); }
void cpx_z () { _cpx (_mem[_z()]); } void cpx_z() { _cpx(_mem[_z()]); }
void sbc_z () { _sbc (_mem[_z()]); } void sbc_z() { _sbc(_mem[_z()]); }
void inc_z () { _inc (_z()); } void inc_z() { _inc(_z()); }
void inx () { Z=N=++X; } void inx() { Z=N=++X; }
void sbc_ () { _sbc (_mem[PC++]); } void sbc_() { _sbc(_mem[PC++]); }
void cpx_a () { _cpx (_mem[_a()]); } void cpx_a() { _cpx(_mem[_a()]); }
void sbc_a () { _sbc (_mem[_a()]); } void sbc_a() { _sbc(_mem[_a()]); }
void inc_a () { _inc (_a()); } void inc_a() { _inc(_a()); }
// f0 // f0
void beq () { if (!Z) _bra(); PC++; } void beq() { if (!Z) _bra(); PC++; }
void sbc_iy () { _sbc (_mem[_iy()]); } void sbc_iy() { _sbc(_mem[_iy()]); }
void sbc_zx () { _sbc (_mem[_zx()]); } void sbc_zx() { _sbc(_mem[_zx()]); }
void inc_zx () { _inc (_zx()); } void inc_zx() { _inc(_zx()); }
void sed () { P.bits.D = 1; } void sed() { P.bits.D = 1; }
void sbc_ay () { _sbc (_mem[_ay()]); } void sbc_ay() { _sbc(_mem[_ay()]); }
void sbc_ax () { _sbc (_mem[_ax()]); } void sbc_ax() { _sbc(_mem[_ax()]); }
void inc_ax () { _inc (_ax()); } void inc_ax() { _inc(_ax()); }
}; };
#endif #endif

55
z80.cpp
View File

@ -5,12 +5,9 @@
#include "CPU.h" #include "CPU.h"
#include "z80.h" #include "z80.h"
#define CPU_STATE_FMT char *z80::status(char *buf, size_t n) {
char *z80::status() {
static char buf[256];
byte op = _mem[PC]; byte op = _mem[PC];
sprintf(buf, "_pc_ op _af_ _bc_ _de_ _hl_ _af' _bc' _de' _hl' _ir_ imff " snprintf(buf, n, "_pc_ op _af_ _bc_ _de_ _hl_ _af' _bc' _de' _hl' _ir_ imff "
"_sp_ sz5h3pnc\r\n" "_sp_ sz5h3pnc\r\n"
"%04x %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %d%d%d " "%04x %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %d%d%d "
"%04x %d%d%d%d%d%d%d%d\r\n", "%04x %d%d%d%d%d%d%d%d\r\n",
@ -67,7 +64,7 @@ byte z80::_fetch_op() {
_mc(PC, 4); _mc(PC, 4);
byte op = _mem[PC]; byte op = _mem[PC];
#if defined(CPU_DEBUG) #if defined(CPU_DEBUG)
_status("%5d MR %04x %02x\n", _ts, PC, op); printf("%5d MR %04x %02x\n", _ts, PC, op);
#endif #endif
PC++; PC++;
R++; R++;
@ -76,15 +73,11 @@ byte z80::_fetch_op() {
void z80::run(unsigned clocks) { void z80::run(unsigned clocks) {
while (clocks--) { while (clocks--) {
step(); if (_irq_pending)
#if !defined(CPU_DEBUG)
if (_halted) {
_status("CPU halted at %04x\r\n%s", PC, status());
longjmp(_err, 1);
}
#endif
if (_irq_pending && _iff1)
_handle_interrupt(); _handle_interrupt();
step();
if (_halted)
break;
} }
} }
@ -100,19 +93,25 @@ void z80::reset() {
} }
void z80::_handle_interrupt() { void z80::_handle_interrupt() {
_iff1 = false; if (_irq_pending < 0 || _iff1) {
_push(PC); if (_halted) {
if (_irq_pending < 0) { // NMI _halted = false;
PC = 0x0066; PC++;
ts(11); }
} else { _push(PC);
_iff2 = false; if (_irq_pending < 0) { // NMI
R++; _iff2 = _iff1;
if (_im == 0 || _im == 1) PC = 0x0066;
PC = 0x0038; ts(11);
else if (_im == 2) } else {
PC = _rw(_irq_pending + (0x100 * I)); _iff1 = _iff2 = false;
ts(7); R++;
if (_im == 0 || _im == 1)
PC = 0x0038;
else if (_im == 2)
PC = _rw(_irq_pending + (0x100 * I));
ts(7);
}
} }
_irq_pending = 0; _irq_pending = 0;
} }
@ -871,7 +870,7 @@ int z80::parity_table[] = {
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,
}; };
z80::z80(Memory &m, jmp_buf &jb, CPU::statfn s, PortDevice<z80> &ports): CPU(m, jb, s) z80::z80(Memory &m, PortDevice<z80> &ports): CPU(m)
{ {
_ports = &ports; _ports = &ports;
_debug = false; _debug = false;

6
z80.h
View File

@ -6,12 +6,12 @@
class z80: public CPU { class z80: public CPU {
public: public:
z80(Memory &, jmp_buf &, CPU::statfn, PortDevice<z80> &); z80(Memory &, PortDevice<z80> &);
void run(unsigned); void run(unsigned);
void reset(); void reset();
void raise(int level) { _irq_pending = level; } void raise(int level) { _irq_pending = level; }
char *status(); char *status(char *buf, size_t n);
void checkpoint(Stream &); void checkpoint(Stream &);
void restore(Stream &); void restore(Stream &);
@ -38,7 +38,6 @@ public:
inline word iy() { return IY; } inline word iy() { return IY; }
inline word sp() { return SP; } inline word sp() { return SP; }
inline word pc() { return PC; } inline word pc() { return PC; }
inline bool halted() { return _halted; }
inline bool iff1() { return _iff1; } inline bool iff1() { return _iff1; }
inline bool iff2() { return _iff2; } inline bool iff2() { return _iff2; }
inline byte im() { return _im; } inline byte im() { return _im; }
@ -137,7 +136,6 @@ private:
bool _iff1, _iff2; bool _iff1, _iff2;
unsigned long _ts; unsigned long _ts;
bool _halted;
int _irq_pending; int _irq_pending;
PortDevice<z80> *_ports; PortDevice<z80> *_ports;