mirror of
https://github.com/jscrane/r65emu.git
synced 2025-08-05 05:26:24 +00:00
Z80 bugfixes
Work-in-progress merging z80 fixes
This commit is contained in:
17
src/CPU.h
17
src/CPU.h
@@ -3,17 +3,24 @@
|
||||
|
||||
#undef PC
|
||||
|
||||
#define O(o, e) case o: e(); break
|
||||
#define A(o, e, a) case o: e(a); break
|
||||
#define C(o) case o:
|
||||
#define D(e) default: e(); break
|
||||
#define E(op, expr) case op: expr; break
|
||||
#define O(op, fn) E(op, fn())
|
||||
#define A(op, e, a) E(op, e(a))
|
||||
#define C(op) case op:
|
||||
#define D(fn) default: fn(); break
|
||||
|
||||
#if defined(UNDOCUMENTED_OPS)
|
||||
#define U(op, expr) case op: expr; break
|
||||
#else
|
||||
#define U(op, expr)
|
||||
#endif
|
||||
|
||||
class CPU: public Checkpointable {
|
||||
public:
|
||||
virtual ~CPU() {}
|
||||
virtual void run(unsigned instructions) =0;
|
||||
virtual void reset() =0;
|
||||
virtual void raise(uint8_t level) =0;
|
||||
virtual void raise(int level) =0;
|
||||
virtual char *status(char *buf, size_t n, bool hdr = false) =0;
|
||||
|
||||
virtual void checkpoint(Stream &s) = 0;
|
||||
|
@@ -24,7 +24,7 @@ void i8080::reset() {
|
||||
_halted = false;
|
||||
}
|
||||
|
||||
void i8080::raise(uint8_t level) {
|
||||
void i8080::raise(int level) {
|
||||
if (flags.I) {
|
||||
flags.I = 0;
|
||||
_irq_pending = 0;
|
||||
|
@@ -13,7 +13,7 @@ public:
|
||||
|
||||
void run(unsigned);
|
||||
void reset();
|
||||
void raise(uint8_t);
|
||||
void raise(int);
|
||||
char *status(char *buf, size_t n, bool hdr=false);
|
||||
|
||||
void checkpoint(Stream &);
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
} flags;
|
||||
uint8_t SR;
|
||||
};
|
||||
uint8_t _irq_pending;
|
||||
int _irq_pending;
|
||||
PortDevice &_ports;
|
||||
|
||||
void _op(uint8_t op);
|
||||
|
@@ -76,7 +76,7 @@ void r6502::restore(Stream &s)
|
||||
#endif
|
||||
}
|
||||
|
||||
void r6502::raise(uint8_t level) {
|
||||
void r6502::raise(int level) {
|
||||
if (level < 0)
|
||||
nmi();
|
||||
else if (!P.bits.I)
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
class r6502: public CPU {
|
||||
public:
|
||||
void raise(uint8_t);
|
||||
void raise(int);
|
||||
void reset();
|
||||
void run(unsigned);
|
||||
char *status(char *buf, size_t n, bool hdr=false);
|
||||
|
469
src/z80.cpp
469
src/z80.cpp
@@ -8,13 +8,26 @@
|
||||
|
||||
char *z80::status(char *buf, size_t n, bool hdr) {
|
||||
#if DEBUGGING & DEBUG_CPU
|
||||
uint8_t op = _mem[PC];
|
||||
static bool first = true;
|
||||
snprintf(buf, n,
|
||||
"%s%04x %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %d%d%d "
|
||||
"%04x %d%d%d%d%d%d%d%d",
|
||||
hdr? "_pc_ op _af_ _bc_ _de_ _hl_ _af' _bc' _de' _hl' _ir_ imff _sp_ sz5h3pnc\r\n": "",
|
||||
PC, op, AF, BC, DE, HL, AF_, BC_, DE_, HL_, IR, _im, _iff1, _iff2,
|
||||
SP, flags.S, flags.Z, flags._5, flags.H, flags._3, flags.P, flags.N, flags.C);
|
||||
"%s%04x %02x %d%d%d%d%d%d %02x %02x %d%d %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ",
|
||||
hdr || first? "PC A SZHPNC I R IFF BC DE HL A'F' B'C' D'E' H'L' IX IY SP OP\r\n": "",
|
||||
PC, A, flags.S, flags.Z, flags.H, flags.P, flags.N, flags.C, I, R & 0x7f, _iff1, _iff2,
|
||||
BC, DE, HL, AF_, BC_, DE_, HL_, IX, IY, SP);
|
||||
first = false;
|
||||
|
||||
uint8_t op = _mem[PC], op1 = _mem[PC+1];
|
||||
char obuf[16];
|
||||
if (op == 0xdd || op == 0xfd) {
|
||||
if (op1 == 0xcb)
|
||||
snprintf(obuf, sizeof(obuf), "%02x cb %02x %02x", op, (byte)_mem[PC+2], (byte)_mem[PC+3]);
|
||||
else
|
||||
snprintf(obuf, sizeof(obuf), "%02x %02x", op, op1);
|
||||
} else if (op == 0xed)
|
||||
snprintf(obuf, sizeof(obuf), "ed %02x", op1);
|
||||
else
|
||||
snprintf(obuf, sizeof(obuf), "%02x", op);
|
||||
strncat(buf, obuf, n);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
@@ -98,27 +111,47 @@ void z80::reset() {
|
||||
}
|
||||
|
||||
void z80::_handle_interrupt() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int irq = _irq_pending;
|
||||
_irq_pending = 0;
|
||||
|
||||
if (!irq && !_iff1) {
|
||||
DBG_CPU(println("No interrupt!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_halted) {
|
||||
_halted = false;
|
||||
PC++;
|
||||
}
|
||||
_push(PC);
|
||||
if (irq < 0) { // NMI
|
||||
DBG_CPU(println("NMI"));
|
||||
_iff2 = _iff1;
|
||||
PC = 0x66;
|
||||
ts(11);
|
||||
return;
|
||||
}
|
||||
_iff1 = _iff2 = false;
|
||||
R++;
|
||||
if (_im == 0)
|
||||
switch (irq) {
|
||||
case 0xc7: PC = 0x00; break;
|
||||
case 0xcf: PC = 0x08; break;
|
||||
case 0xd7: PC = 0x10; break;
|
||||
case 0xdf: PC = 0x18; break;
|
||||
case 0xe7: PC = 0x20; break;
|
||||
case 0xef: PC = 0x28; break;
|
||||
case 0xf7: PC = 0x30; break;
|
||||
case 0xff: PC = 0x38; break;
|
||||
}
|
||||
else if (_im == 1)
|
||||
PC = 0x38;
|
||||
else if (_im == 2)
|
||||
PC = _rw(irq + (0x100 * I));
|
||||
ts(7);
|
||||
|
||||
DBG_CPU(printf("IM: %d PC: %04x\r\n", _im, PC));
|
||||
}
|
||||
|
||||
void z80::daa() {
|
||||
@@ -154,272 +187,129 @@ void z80::_step_idx(EXT_OP f) {
|
||||
}
|
||||
|
||||
void z80::_ddfd(uint16_t &ix, uint8_t &ixL, uint8_t &ixH, EXT_OP op) {
|
||||
switch (_fetch_op()) {
|
||||
case 0x09:
|
||||
_add16(ix, BC);
|
||||
break;
|
||||
case 0x19:
|
||||
_add16(ix, DE);
|
||||
break;
|
||||
case 0x21:
|
||||
ix = _rwpc();
|
||||
break;
|
||||
case 0x22:
|
||||
_swPC(ix);
|
||||
break;
|
||||
case 0x23:
|
||||
ix++;
|
||||
_mc(IR, 1); _mc(IR, 1);
|
||||
break;
|
||||
case 0x24:
|
||||
_inc(ixH);
|
||||
break;
|
||||
case 0x25:
|
||||
_dec(ixH);
|
||||
break;
|
||||
case 0x26:
|
||||
ixH = _rb(PC++);
|
||||
break;
|
||||
case 0x29:
|
||||
_add16(ix, ix);
|
||||
break;
|
||||
case 0x2a:
|
||||
ix = _rwPC();
|
||||
break;
|
||||
case 0x2b:
|
||||
ix--;
|
||||
_mc(IR, 1); _mc(IR, 1);
|
||||
break;
|
||||
case 0x2c:
|
||||
_inc(ixL);
|
||||
break;
|
||||
case 0x2d:
|
||||
_dec(ixL);
|
||||
break;
|
||||
case 0x2e:
|
||||
ixL = _rb(PC++);
|
||||
break;
|
||||
case 0x34:
|
||||
_incO(ix);
|
||||
break;
|
||||
case 0x35:
|
||||
_decO(ix);
|
||||
break;
|
||||
case 0x36:
|
||||
_sbO(ix);
|
||||
break;
|
||||
case 0x39:
|
||||
_add16(ix, SP);
|
||||
break;
|
||||
case 0x44:
|
||||
B = ixH;
|
||||
break;
|
||||
case 0x45:
|
||||
B = ixL;
|
||||
break;
|
||||
case 0x46:
|
||||
B = _rbO(ix);
|
||||
break;
|
||||
case 0x4c:
|
||||
C = ixH;
|
||||
break;
|
||||
case 0x4d:
|
||||
C = ixL;
|
||||
break;
|
||||
case 0x4e:
|
||||
C = _rbO(ix);
|
||||
break;
|
||||
case 0x54:
|
||||
D = ixH;
|
||||
break;
|
||||
case 0x55:
|
||||
D = ixL;
|
||||
break;
|
||||
case 0x56:
|
||||
D = _rbO(ix);
|
||||
break;
|
||||
case 0x5c:
|
||||
E = ixH;
|
||||
break;
|
||||
case 0x5d:
|
||||
E = ixL;
|
||||
break;
|
||||
case 0x5e:
|
||||
E = _rbO(ix);
|
||||
break;
|
||||
case 0x60:
|
||||
ixH = B;
|
||||
break;
|
||||
case 0x61:
|
||||
ixH = C;
|
||||
break;
|
||||
case 0x62:
|
||||
ixH = D;
|
||||
break;
|
||||
case 0x63:
|
||||
ixH = E;
|
||||
break;
|
||||
case 0x64:
|
||||
break;
|
||||
case 0x65:
|
||||
ixH = ixL;
|
||||
break;
|
||||
case 0x66:
|
||||
H = _rbO(ix);
|
||||
break;
|
||||
case 0x67:
|
||||
ixH = A;
|
||||
break;
|
||||
case 0x68:
|
||||
ixL = B;
|
||||
break;
|
||||
case 0x69:
|
||||
ixL = C;
|
||||
break;
|
||||
case 0x6a:
|
||||
ixL = D;
|
||||
break;
|
||||
case 0x6b:
|
||||
ixL = E;
|
||||
break;
|
||||
case 0x6c:
|
||||
ixL = ixH;
|
||||
break;
|
||||
case 0x6d:
|
||||
break;
|
||||
case 0x6e:
|
||||
L = _rbO(ix);
|
||||
break;
|
||||
case 0x6f:
|
||||
ixL = A;
|
||||
break;
|
||||
case 0x70:
|
||||
_sbO(ix, B);
|
||||
break;
|
||||
case 0x71:
|
||||
_sbO(ix, C);
|
||||
break;
|
||||
case 0x72:
|
||||
_sbO(ix, D);
|
||||
break;
|
||||
case 0x73:
|
||||
_sbO(ix, E);
|
||||
break;
|
||||
case 0x74:
|
||||
_sbO(ix, H);
|
||||
break;
|
||||
case 0x75:
|
||||
_sbO(ix, L);
|
||||
break;
|
||||
case 0x77:
|
||||
_sbO(ix, A);
|
||||
break;
|
||||
case 0x7c:
|
||||
A = ixH;
|
||||
break;
|
||||
case 0x7d:
|
||||
A = ixL;
|
||||
break;
|
||||
case 0x7e:
|
||||
A = _rbO(ix);
|
||||
break;
|
||||
case 0x84:
|
||||
_add(ixH);
|
||||
break;
|
||||
case 0x85:
|
||||
_add(ixL);
|
||||
break;
|
||||
case 0x86:
|
||||
_add(_rbO(ix));
|
||||
break;
|
||||
case 0x8c:
|
||||
_adc(ixH);
|
||||
break;
|
||||
case 0x8d:
|
||||
_adc(ixL);
|
||||
break;
|
||||
case 0x8e:
|
||||
_adc(_rbO(ix));
|
||||
break;
|
||||
case 0x94:
|
||||
_sub(ixH);
|
||||
break;
|
||||
case 0x95:
|
||||
_sub(ixL);
|
||||
break;
|
||||
case 0x96:
|
||||
_sub(_rbO(ix));
|
||||
break;
|
||||
case 0x9c:
|
||||
_sbc(ixH);
|
||||
break;
|
||||
case 0x9d:
|
||||
_sbc(ixL);
|
||||
break;
|
||||
case 0x9e:
|
||||
_sbc(_rbO(ix));
|
||||
break;
|
||||
case 0xa4:
|
||||
_and(ixH);
|
||||
break;
|
||||
case 0xa5:
|
||||
_and(ixL);
|
||||
break;
|
||||
case 0xa6:
|
||||
_and(_rbO(ix));
|
||||
break;
|
||||
case 0xac:
|
||||
_xor(ixH);
|
||||
break;
|
||||
case 0xad:
|
||||
_xor(ixL);
|
||||
break;
|
||||
case 0xae:
|
||||
_xor(_rbO(ix));
|
||||
break;
|
||||
case 0xb4:
|
||||
_or(ixH);
|
||||
break;
|
||||
case 0xb5:
|
||||
_or(ixL);
|
||||
break;
|
||||
case 0xb6:
|
||||
_or(_rbO(ix));
|
||||
break;
|
||||
case 0xbc:
|
||||
_cmp(ixH);
|
||||
break;
|
||||
case 0xbd:
|
||||
_cmp(ixL);
|
||||
break;
|
||||
case 0xbe:
|
||||
_cmp(_rbO(ix));
|
||||
break;
|
||||
case 0xcb:
|
||||
_step_idx(op);
|
||||
break;
|
||||
case 0xe1:
|
||||
ix = _pop();
|
||||
break;
|
||||
case 0xe3:
|
||||
_exSP(ix);
|
||||
break;
|
||||
case 0xe5:
|
||||
_mc(IR, 1);
|
||||
_push(ix);
|
||||
break;
|
||||
case 0xe9:
|
||||
PC = ix;
|
||||
break;
|
||||
case 0xf9:
|
||||
_mc(IR, 1); _mc(IR, 1);
|
||||
SP = ix;
|
||||
break;
|
||||
|
||||
uint8_t o = _fetch_op();
|
||||
switch (o) {
|
||||
E(0x09, _add16(ix, BC));
|
||||
E(0x19, _add16(ix, DE));
|
||||
|
||||
E(0x21, ix = _rwpc());
|
||||
E(0x22, _swPC(ix));
|
||||
E(0x23, ix++; _mc(IR, 1); _mc(IR, 1));
|
||||
|
||||
U(0x24, _inc(ixH));
|
||||
U(0x25, _dec(ixH));
|
||||
U(0x26, ixH = _rb(PC++));
|
||||
|
||||
E(0x29, _add16(ix, ix));
|
||||
E(0x2a, ix = _rwPC());
|
||||
E(0x2b, ix--; _mc(IR, 1); _mc(IR, 1));
|
||||
|
||||
U(0x2c, _inc(ixL));
|
||||
U(0x2d, _dec(ixL));
|
||||
U(0x2e, ixL = _rb(PC++));
|
||||
|
||||
E(0x34, _incO(ix));
|
||||
E(0x35, _decO(ix));
|
||||
E(0x36, _sbO(ix));
|
||||
|
||||
E(0x39, _add16(ix, SP));
|
||||
|
||||
U(0x44, B = ixH);
|
||||
U(0x45, B = ixL);
|
||||
E(0x46, B = _rbO(ix));
|
||||
|
||||
U(0x4c, C = ixH);
|
||||
U(0x4d, C = ixL);
|
||||
E(0x4e, C = _rbO(ix));
|
||||
|
||||
U(0x54, D = ixH);
|
||||
U(0x55, D = ixL);
|
||||
E(0x56, D = _rbO(ix));
|
||||
|
||||
U(0x5c, E = ixH);
|
||||
U(0x5d, E = ixL);
|
||||
E(0x5e, E = _rbO(ix));
|
||||
|
||||
U(0x60, ixH = B);
|
||||
U(0x61, ixH = C);
|
||||
U(0x62, ixH = D);
|
||||
U(0x63, ixH = E);
|
||||
U(0x64, /* FIXME */);
|
||||
U(0x65, ixH = ixL);
|
||||
E(0x66, H = _rbO(ix));
|
||||
U(0x67, ixH = A);
|
||||
U(0x68, ixL = B);
|
||||
U(0x69, ixL = C);
|
||||
U(0x6a, ixL = D);
|
||||
U(0x6b, ixL = E);
|
||||
U(0x6c, ixL = ixH);
|
||||
U(0x6d, /* FIXME */);
|
||||
E(0x6e, L = _rbO(ix));
|
||||
U(0x6f, ixL = A);
|
||||
E(0x70, _sbO(ix, B));
|
||||
E(0x71, _sbO(ix, C));
|
||||
E(0x72, _sbO(ix, D));
|
||||
E(0x73, _sbO(ix, E));
|
||||
E(0x74, _sbO(ix, H));
|
||||
E(0x75, _sbO(ix, L));
|
||||
|
||||
E(0x77, _sbO(ix, A));
|
||||
|
||||
U(0x7c, A = ixH);
|
||||
U(0x7d, A = ixL);
|
||||
E(0x7e, A = _rbO(ix));
|
||||
|
||||
U(0x84, _add(ixH));
|
||||
U(0x85, _add(ixL));
|
||||
E(0x86, _add(_rbO(ix)));
|
||||
|
||||
U(0x8c, _adc(ixH));
|
||||
U(0x8d, _adc(ixL));
|
||||
E(0x8e, _adc(_rbO(ix)));
|
||||
|
||||
U(0x94, _sub(ixH));
|
||||
U(0x95, _sub(ixL));
|
||||
E(0x96, _sub(_rbO(ix)));
|
||||
|
||||
U(0x9c, _sbc(ixH));
|
||||
U(0x9d, _sbc(ixL));
|
||||
E(0x9e, _sbc(_rbO(ix)));
|
||||
|
||||
U(0xa4, _and(ixH));
|
||||
U(0xa5, _and(ixL));
|
||||
E(0xa6, _and(_rbO(ix)));
|
||||
|
||||
U(0xac, _xor(ixH));
|
||||
U(0xad, _xor(ixL));
|
||||
E(0xae, _xor(_rbO(ix)));
|
||||
|
||||
U(0xb4, _or(ixH));
|
||||
U(0xb5, _or(ixL));
|
||||
E(0xb6, _or(_rbO(ix)));
|
||||
|
||||
U(0xbc, _cmp(ixH));
|
||||
U(0xbd, _cmp(ixL));
|
||||
E(0xbe, _cmp(_rbO(ix)));
|
||||
|
||||
E(0xcb, _step_idx(op));
|
||||
|
||||
E(0xe1, ix = _pop());
|
||||
E(0xe3, _exSP(ix));
|
||||
E(0xe5, _mc(IR, 1); _push(ix));
|
||||
E(0xe9, PC = ix);
|
||||
|
||||
E(0xf9, _mc(IR, 1); _mc(IR, 1); SP = ix);
|
||||
|
||||
default:
|
||||
ERR(printf("unimplemented dd/fd op: %02x\r\n", o));
|
||||
}
|
||||
}
|
||||
|
||||
void z80::ed() {
|
||||
switch (_fetch_op()) {
|
||||
|
||||
uint8_t op = _fetch_op();
|
||||
switch (op) {
|
||||
O(0x40, inB);
|
||||
O(0x41, outB);
|
||||
O(0x42, sbcBC);
|
||||
@@ -507,6 +397,9 @@ void z80::ed() {
|
||||
O(0xb9, cpdr);
|
||||
O(0xba, indr);
|
||||
O(0xbb, outdr);
|
||||
|
||||
default:
|
||||
ERR(printf("unimplemented ed op: %02x\r\n", op));
|
||||
}
|
||||
}
|
||||
|
||||
|
152
src/z80.h
152
src/z80.h
@@ -11,7 +11,7 @@ public:
|
||||
|
||||
void run(unsigned);
|
||||
void reset();
|
||||
void raise(uint8_t level) { _irq_pending = level; }
|
||||
void raise(int level) { _irq_pending = level; }
|
||||
char *status(char *buf, size_t n, bool hdr=false);
|
||||
|
||||
void checkpoint(Stream &);
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
|
||||
unsigned long _ts;
|
||||
|
||||
uint8_t _irq_pending;
|
||||
int _irq_pending;
|
||||
PortDevice &_ports;
|
||||
|
||||
uint8_t parity(uint8_t);
|
||||
@@ -403,7 +403,11 @@ private:
|
||||
inline void incb() { _inc(B); }
|
||||
inline void decb() { _dec(B); }
|
||||
inline void ldb() { B = _rb(PC++); }
|
||||
inline void rlca() { flags.C = ((A & 0x80) >> 7); A = (A << 1) | flags.C; }
|
||||
inline void rlca() {
|
||||
flags.H = flags.N = 0;
|
||||
flags.C = ((A & 0x80) >> 7);
|
||||
A = (A << 1) | flags.C;
|
||||
}
|
||||
|
||||
// 0x08
|
||||
inline void exaf() { _exch(AF, AF_); }
|
||||
@@ -431,6 +435,7 @@ private:
|
||||
inline void rla() {
|
||||
uint8_t b = (A << 1) | flags.C;
|
||||
flags.C = (A & 0x80) >> 7;
|
||||
flags.H = flags.N = 0;
|
||||
A = b;
|
||||
}
|
||||
|
||||
@@ -449,6 +454,7 @@ private:
|
||||
inline void rra() {
|
||||
uint8_t b = (A >> 1) | (flags.C << 7);
|
||||
flags.C = (A & 1);
|
||||
flags.H = flags.N = 0;
|
||||
A = b;
|
||||
}
|
||||
|
||||
@@ -490,7 +496,17 @@ private:
|
||||
inline void inca() { _inc(A); }
|
||||
inline void deca() { _dec(A); }
|
||||
inline void lda() { A = _rb(PC++); }
|
||||
inline void ccf() { flags.H = flags.C; flags.C = flags.N = 0; _35(A); }
|
||||
inline void ccf() {
|
||||
if (flags.C) {
|
||||
flags.C = 0;
|
||||
flags.H = 1;
|
||||
} else {
|
||||
flags.H = 0;
|
||||
flags.C = 1;
|
||||
}
|
||||
flags.N = 0;
|
||||
_35(A);
|
||||
}
|
||||
|
||||
// 0x40
|
||||
inline void ldbb() {}
|
||||
@@ -1271,19 +1287,15 @@ private:
|
||||
}
|
||||
inline void cpi() {
|
||||
uint8_t b = _rb(HL);
|
||||
flags.H = ((b & 0x0f) > (A & 0x0f));
|
||||
b = A - b;
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
uint8_t c = A;
|
||||
uint8_t f = (flags.C != 0);
|
||||
_sub(b);
|
||||
HL++;
|
||||
BC--;
|
||||
b = A;
|
||||
A = c;
|
||||
if (flags.H) b--;
|
||||
flags.C = f;
|
||||
flags.N = 1;
|
||||
flags.P = (BC != 0);
|
||||
_35(b);
|
||||
_sz35(b);
|
||||
flags._5 = ((b & 0x02) != 0);
|
||||
_memptr++;
|
||||
}
|
||||
@@ -1327,17 +1339,17 @@ private:
|
||||
}
|
||||
inline void cpd_() {
|
||||
uint8_t b = _rb(HL);
|
||||
uint8_t c = A - b - flags.H;
|
||||
flags.H = ((b & 0x0f) > (A & 0x0f));
|
||||
b = A - b;
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
HL--;
|
||||
BC--;
|
||||
flags.N = 1;
|
||||
flags.P = (BC != 0);
|
||||
_sz35(c);
|
||||
flags._5 = ((c & 0x02) != 0);
|
||||
_sz35(b);
|
||||
flags._5 = ((b & 0x02) != 0);
|
||||
_memptr--;
|
||||
// FIXME: flag H
|
||||
}
|
||||
inline void ind() {
|
||||
_mc(IR, 1);
|
||||
@@ -1366,48 +1378,33 @@ private:
|
||||
_sz35(B);
|
||||
}
|
||||
inline void ldir() {
|
||||
uint8_t b = _rb(HL);
|
||||
BC--;
|
||||
_sb(DE, b);
|
||||
_mc(DE, 1);
|
||||
_mc(DE, 1);
|
||||
uint8_t b;
|
||||
do {
|
||||
b = _rb(HL);
|
||||
_sb(DE, b);
|
||||
_mc(DE, 1);
|
||||
_mc(DE, 1);
|
||||
DE++;
|
||||
HL++;
|
||||
} while (--BC);
|
||||
b += A;
|
||||
flags.P = (BC != 0);
|
||||
_35(b);
|
||||
flags._5 = ((b & 0x02) != 0);
|
||||
flags.N = flags.H = 0;
|
||||
if (BC) {
|
||||
_mc(DE, 1); _mc(DE, 1); _mc(DE, 1);
|
||||
_mc(DE, 1); _mc(DE, 1);
|
||||
PC -= 2;
|
||||
_memptr = PC+1;
|
||||
}
|
||||
DE++;
|
||||
HL++;
|
||||
flags.N = flags.P = flags.H = 0;
|
||||
}
|
||||
inline void cpir() {
|
||||
uint8_t b = _rb(HL);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
uint8_t c = A;
|
||||
uint8_t f = (flags.C != 0);
|
||||
_sub(b);
|
||||
BC--;
|
||||
b -= A;
|
||||
A = c;
|
||||
flags.C = f;
|
||||
flags.P = (BC != 0);
|
||||
if (flags.H) b--;
|
||||
_35(b);
|
||||
flags._5 = ((b & 0x02) != 0);
|
||||
_memptr++;
|
||||
if (!flags.Z) {
|
||||
uint8_t d;
|
||||
do {
|
||||
uint8_t b = _rb(HL++);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
PC -= 2;
|
||||
_memptr = PC+1;
|
||||
}
|
||||
HL++;
|
||||
flags.H = ((b & 0x0f) > (A & 0xf));
|
||||
d = A - b;
|
||||
} while (--BC && d);
|
||||
flags.N = 1;
|
||||
flags.P = (BC != 0);
|
||||
_sz35(d);
|
||||
flags._5 = ((d & 0x02) != 0);
|
||||
}
|
||||
inline void inir() {
|
||||
_mc(IR, 1);
|
||||
@@ -1444,44 +1441,33 @@ private:
|
||||
}
|
||||
}
|
||||
inline void lddr() {
|
||||
uint8_t b = _rb(HL);
|
||||
BC--;
|
||||
_sb(DE, b);
|
||||
_mc(DE, 1);
|
||||
_mc(DE, 1);
|
||||
uint8_t b;
|
||||
do {
|
||||
b = _rb(HL);
|
||||
_sb(DE, b);
|
||||
_mc(DE, 1);
|
||||
_mc(DE, 1);
|
||||
DE--;
|
||||
HL--;
|
||||
} while (--BC);
|
||||
b += A;
|
||||
flags.P = (BC != 0);
|
||||
_35(b);
|
||||
flags._5 = ((b & 0x02) != 0);
|
||||
flags.N = flags.H = 0;
|
||||
if (BC) {
|
||||
_mc(DE, 1); _mc(DE, 1); _mc(DE, 1);
|
||||
_mc(DE, 1); _mc(DE, 1);
|
||||
PC -= 2;
|
||||
_memptr = PC+1;
|
||||
}
|
||||
DE--;
|
||||
HL--;
|
||||
flags.N = flags.H = flags.P = 0;
|
||||
}
|
||||
inline void cpdr() {
|
||||
uint8_t b = _rb(HL);
|
||||
uint8_t c = A - b;
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
BC--;
|
||||
flags.N = 1;
|
||||
flags.P = (BC != 0);
|
||||
_sz35(c);
|
||||
flags._5 = ((c & 0x02) != 0);
|
||||
// FIXME: flag H
|
||||
_memptr--;
|
||||
if (BC) {
|
||||
uint8_t d;
|
||||
do {
|
||||
uint8_t b = _rb(HL--);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
PC -= 2;
|
||||
_memptr = PC+1;
|
||||
}
|
||||
HL--;
|
||||
flags.H = ((b & 0x0f) > (A & 0xf));
|
||||
d = A - b;
|
||||
} while (--BC && d);
|
||||
flags.N = 1;
|
||||
flags.P = (BC != 0);
|
||||
_sz35(d);
|
||||
flags._5 = ((d & 0x02) != 0);
|
||||
}
|
||||
inline void indr() {
|
||||
_mc(IR, 1);
|
||||
@@ -1519,8 +1505,8 @@ private:
|
||||
PC -= 2;
|
||||
}
|
||||
}
|
||||
// 0xDDCB extended instructions
|
||||
|
||||
// 0xDDCB extended instructions
|
||||
inline uint16_t _rbIX(uint8_t &b, uint8_t o) {
|
||||
uint16_t a = _ads(IX, o);
|
||||
_memptr = a;
|
||||
|
Reference in New Issue
Block a user