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__
#define __CPU_H__
#ifndef _SETJMP_H
#include <setjmp.h>
#endif
#undef PC
class CPU: public Checkpointable {
public:
virtual void run(unsigned instructions) =0;
virtual void reset () =0;
virtual void raise (int level) =0;
virtual char *status () =0;
typedef void (*statfn) (const char *, ...);
virtual void reset() =0;
virtual void raise(int level) =0;
virtual char *status(char *buf, size_t n) =0;
virtual void checkpoint(Stream &s) = 0;
virtual void restore(Stream &s) = 0;
void debug() { _debug = !_debug; }
inline void debug() { _debug = !_debug; }
inline bool halted() { return _halted; }
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::address PC;
jmp_buf &_err;
statfn _status;
bool _debug;
bool _debug, _halted;
};
#endif

View File

@ -5,29 +5,14 @@
#include "ports.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;
while (clocks--) {
byte op = _mem[PC];
PC++;
(this->*_ops[op])();
if (_halted)
break;
}
#endif
while (clocks--)
step();
}
void i8080::reset() {
@ -35,6 +20,7 @@ void i8080::reset() {
_sr(0);
BC = DE = HL = PC = SP = 0;
_irq_pending = 0;
_halted = false;
}
void i8080::raise(int level) {
@ -53,10 +39,12 @@ void i8080::ei() {
raise(_irq_pending);
}
char *i8080::status() {
static char buf[128];
char *i8080::status(char *buf, size_t n) {
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;
}
@ -94,11 +82,6 @@ void i8080::daa() {
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,
@ -118,7 +101,7 @@ int i8080::parity_table[] = {
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;

View File

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

138
r6502.cpp
View File

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

403
r6502.h
View File

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

55
z80.cpp
View File

@ -5,12 +5,9 @@
#include "CPU.h"
#include "z80.h"
#define CPU_STATE_FMT
char *z80::status() {
static char buf[256];
char *z80::status(char *buf, size_t n) {
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"
"%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",
@ -67,7 +64,7 @@ byte z80::_fetch_op() {
_mc(PC, 4);
byte op = _mem[PC];
#if defined(CPU_DEBUG)
_status("%5d MR %04x %02x\n", _ts, PC, op);
printf("%5d MR %04x %02x\n", _ts, PC, op);
#endif
PC++;
R++;
@ -76,15 +73,11 @@ byte z80::_fetch_op() {
void z80::run(unsigned clocks) {
while (clocks--) {
step();
#if !defined(CPU_DEBUG)
if (_halted) {
_status("CPU halted at %04x\r\n%s", PC, status());
longjmp(_err, 1);
}
#endif
if (_irq_pending && _iff1)
if (_irq_pending)
_handle_interrupt();
step();
if (_halted)
break;
}
}
@ -100,19 +93,25 @@ void z80::reset() {
}
void z80::_handle_interrupt() {
_iff1 = false;
_push(PC);
if (_irq_pending < 0) { // NMI
PC = 0x0066;
ts(11);
} else {
_iff2 = false;
R++;
if (_im == 0 || _im == 1)
PC = 0x0038;
else if (_im == 2)
PC = _rw(_irq_pending + (0x100 * I));
ts(7);
if (_irq_pending < 0 || _iff1) {
if (_halted) {
_halted = false;
PC++;
}
_push(PC);
if (_irq_pending < 0) { // NMI
_iff2 = _iff1;
PC = 0x0066;
ts(11);
} else {
_iff1 = _iff2 = false;
R++;
if (_im == 0 || _im == 1)
PC = 0x0038;
else if (_im == 2)
PC = _rw(_irq_pending + (0x100 * I));
ts(7);
}
}
_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,
};
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;
_debug = false;

6
z80.h
View File

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