mirror of https://github.com/jscrane/r65emu.git
z80 updates
This commit is contained in:
parent
cd4b280410
commit
0489c1d283
7
CPU.h
7
CPU.h
|
@ -5,11 +5,14 @@
|
||||||
|
|
||||||
class Stream;
|
class Stream;
|
||||||
|
|
||||||
#define O(o, e) case o: e(); break;
|
#define O(o, e) case o: e(); break
|
||||||
#define D(e) default: e(); break;
|
#define A(o, e, a) case o: e(a); break
|
||||||
|
#define C(o) case o:
|
||||||
|
#define D(e) default: e(); break
|
||||||
|
|
||||||
class CPU: public Checkpointable {
|
class CPU: public Checkpointable {
|
||||||
public:
|
public:
|
||||||
|
virtual ~CPU() {}
|
||||||
virtual void run(unsigned instructions) =0;
|
virtual void run(unsigned instructions) =0;
|
||||||
virtual void reset() =0;
|
virtual void reset() =0;
|
||||||
virtual void raise(uint8_t level) =0;
|
virtual void raise(uint8_t level) =0;
|
||||||
|
|
545
z80.cpp
545
z80.cpp
|
@ -425,463 +425,94 @@ void z80::_ddfd(uint16_t &ix, uint8_t &ixL, uint8_t &ixH, EXT_OP op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void z80::ed() {
|
void z80::ed() {
|
||||||
uint8_t b, c, f;
|
|
||||||
switch (_fetch_op()) {
|
switch (_fetch_op()) {
|
||||||
case 0x40:
|
O(0x40, inB);
|
||||||
B = _inr(BC);
|
O(0x41, outB);
|
||||||
break;
|
O(0x42, sbcBC);
|
||||||
case 0x41:
|
O(0x43, ldPCbc);
|
||||||
_outr(BC, B);
|
|
||||||
break;
|
C(0x44);
|
||||||
case 0x42:
|
C(0x54);
|
||||||
_sbc16(BC);
|
C(0x64);
|
||||||
break;
|
C(0x74);
|
||||||
case 0x43:
|
C(0x4c);
|
||||||
_swPC(BC);
|
C(0x5c);
|
||||||
break;
|
C(0x6c);
|
||||||
case 0x44:
|
O(0x7c, neg);
|
||||||
case 0x54:
|
|
||||||
case 0x64:
|
C(0x45);
|
||||||
case 0x74:
|
C(0x4d);
|
||||||
case 0x4c:
|
C(0x55);
|
||||||
case 0x5c:
|
C(0x5d);
|
||||||
case 0x6c:
|
C(0x65);
|
||||||
case 0x7c:
|
C(0x6d);
|
||||||
b = A;
|
C(0x75);
|
||||||
A = 0;
|
O(0x7d, retn);
|
||||||
_sub(b);
|
|
||||||
break;
|
C(0x46);
|
||||||
case 0x45:
|
C(0x4e);
|
||||||
case 0x4d:
|
C(0x66);
|
||||||
case 0x55:
|
A(0x6e, im, 0);
|
||||||
case 0x5d:
|
O(0x47, ldia);
|
||||||
case 0x65:
|
O(0x48, inC);
|
||||||
case 0x6d:
|
O(0x49, outC);
|
||||||
case 0x75:
|
O(0x4a, adcBC);
|
||||||
case 0x7d:
|
O(0x4b, ldbcPC);
|
||||||
_iff1 = _iff2;
|
O(0x4f, ldra);
|
||||||
ret();
|
O(0x50, inD);
|
||||||
break;
|
O(0x51, outD);
|
||||||
case 0x46:
|
O(0x52, sbcDE);
|
||||||
case 0x4e:
|
O(0x53, ldPCde);
|
||||||
case 0x66:
|
|
||||||
case 0x6e:
|
C(0x56);
|
||||||
_im = 0;
|
A(0x76, im, 1);
|
||||||
break;
|
|
||||||
case 0x47:
|
O(0x57, ldai);
|
||||||
_mc(IR, 1);
|
O(0x58, inE);
|
||||||
I = A;
|
O(0x59, outE);
|
||||||
break;
|
O(0x5a, adcDE);
|
||||||
case 0x48:
|
O(0x5b, lddePC);
|
||||||
C = _inr(BC);
|
C(0x5e);
|
||||||
break;
|
A(0x7e, im, 2);
|
||||||
case 0x49:
|
O(0x5f, ldar);
|
||||||
_outr(BC, C);
|
|
||||||
break;
|
O(0x60, inH);
|
||||||
case 0x4a:
|
O(0x61, outH);
|
||||||
_adc16(BC);
|
O(0x62, sbcHL);
|
||||||
break;
|
O(0x63, ldPChl);
|
||||||
case 0x4b:
|
O(0x67, rrd);
|
||||||
BC = _rwPC();
|
O(0x68, inL);
|
||||||
break;
|
O(0x69, outL);
|
||||||
case 0x4f:
|
O(0x6a, adcHL);
|
||||||
_mc(IR, 1);
|
O(0x6b, ldhlPC);
|
||||||
R = A;
|
O(0x6f, rld);
|
||||||
break;
|
|
||||||
case 0x50:
|
O(0x70, _inr);
|
||||||
D = _inr(BC);
|
A(0x71, _outr, 0);
|
||||||
break;
|
O(0x72, sbcSP);
|
||||||
case 0x51:
|
O(0x73, ldPCsp);
|
||||||
_outr(BC, D);
|
O(0x78, inA);
|
||||||
break;
|
O(0x79, outA);
|
||||||
case 0x52:
|
O(0x7a, adcSP);
|
||||||
_sbc16(DE);
|
O(0x7b, ldspPC);
|
||||||
break;
|
|
||||||
case 0x53:
|
O(0xa0, ldi);
|
||||||
_swPC(DE);
|
O(0xa1, cpi);
|
||||||
break;
|
O(0xa2, ini);
|
||||||
case 0x56:
|
O(0xa3, outi);
|
||||||
case 0x76:
|
O(0xa8, ldd_);
|
||||||
_im = 1;
|
O(0xa9, cpd_);
|
||||||
break;
|
O(0xaa, ind);
|
||||||
case 0x57:
|
O(0xab, outd);
|
||||||
_mc(IR, 1);
|
|
||||||
A = I;
|
O(0xb0, ldir);
|
||||||
_sz35(A);
|
O(0xb1, cpir);
|
||||||
flags.P = _iff2;
|
O(0xb2, inir);
|
||||||
flags.H = flags.N = 0;
|
O(0xb3, outir);
|
||||||
break;
|
O(0xb8, lddr);
|
||||||
case 0x58:
|
O(0xb9, cpdr);
|
||||||
E = _inr(BC);
|
O(0xba, indr);
|
||||||
break;
|
O(0xbb, outdr);
|
||||||
case 0x59:
|
|
||||||
_outr(BC, E);
|
|
||||||
break;
|
|
||||||
case 0x5a:
|
|
||||||
_adc16(DE);
|
|
||||||
break;
|
|
||||||
case 0x5b:
|
|
||||||
DE = _rwPC();
|
|
||||||
break;
|
|
||||||
case 0x5e:
|
|
||||||
case 0x7e:
|
|
||||||
_im = 2;
|
|
||||||
break;
|
|
||||||
case 0x5f:
|
|
||||||
_mc(IR, 1);
|
|
||||||
A = R;
|
|
||||||
_sz35(A);
|
|
||||||
flags.P = _iff2;
|
|
||||||
flags.H = flags.N = 0;
|
|
||||||
break;
|
|
||||||
case 0x60:
|
|
||||||
H = _inr(BC);
|
|
||||||
break;
|
|
||||||
case 0x61:
|
|
||||||
_outr(BC, H);
|
|
||||||
break;
|
|
||||||
case 0x62:
|
|
||||||
_sbc16(HL);
|
|
||||||
break;
|
|
||||||
case 0x63:
|
|
||||||
_swPC(HL);
|
|
||||||
break;
|
|
||||||
case 0x67:
|
|
||||||
_memptr = HL+1;
|
|
||||||
b = _rb(HL);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
_sb(HL, (A << 4) | (b >> 4));
|
|
||||||
A = (A & 0xf0) | (b & 0x0f);
|
|
||||||
_szp35(A);
|
|
||||||
flags.H = flags.N = 0;
|
|
||||||
break;
|
|
||||||
case 0x68:
|
|
||||||
L = _inr(BC);
|
|
||||||
break;
|
|
||||||
case 0x69:
|
|
||||||
_outr(BC, L);
|
|
||||||
break;
|
|
||||||
case 0x6a:
|
|
||||||
_adc16(HL);
|
|
||||||
break;
|
|
||||||
case 0x6b:
|
|
||||||
HL = _rwPC();
|
|
||||||
break;
|
|
||||||
case 0x6f:
|
|
||||||
_memptr = HL+1;
|
|
||||||
b = _rb(HL);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
_sb(HL, (A & 0x0f) | (b << 4));
|
|
||||||
A = (A & 0xf0) | (b >> 4);
|
|
||||||
_szp35(A);
|
|
||||||
flags.N = flags.H = 0;
|
|
||||||
break;
|
|
||||||
case 0x70:
|
|
||||||
_inr(BC);
|
|
||||||
break;
|
|
||||||
case 0x71:
|
|
||||||
_outr(BC, 0);
|
|
||||||
break;
|
|
||||||
case 0x72:
|
|
||||||
_sbc16(SP);
|
|
||||||
break;
|
|
||||||
case 0x73:
|
|
||||||
_swPC(SP);
|
|
||||||
break;
|
|
||||||
case 0x78:
|
|
||||||
A = _inr(BC);
|
|
||||||
break;
|
|
||||||
case 0x79:
|
|
||||||
_outr(BC, A);
|
|
||||||
break;
|
|
||||||
case 0x7a:
|
|
||||||
_adc16(SP);
|
|
||||||
break;
|
|
||||||
case 0x7b:
|
|
||||||
SP = _rwPC();
|
|
||||||
break;
|
|
||||||
case 0xa0:
|
|
||||||
// ldi
|
|
||||||
b = _rb(HL);
|
|
||||||
BC--;
|
|
||||||
_sb(DE, b);
|
|
||||||
_mc(DE, 1);
|
|
||||||
_mc(DE, 1);
|
|
||||||
DE++;
|
|
||||||
HL++;
|
|
||||||
b += A;
|
|
||||||
flags.P = (BC != 0);
|
|
||||||
_35(b);
|
|
||||||
flags._5 = ((b & 0x02) != 0);
|
|
||||||
flags.N = flags.H = 0;
|
|
||||||
break;
|
|
||||||
case 0xa1:
|
|
||||||
// cpi
|
|
||||||
b = _rb(HL);
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
c = A;
|
|
||||||
f = (flags.C != 0);
|
|
||||||
_sub(b);
|
|
||||||
HL++;
|
|
||||||
BC--;
|
|
||||||
b = A;
|
|
||||||
A = c;
|
|
||||||
if (flags.H) b--;
|
|
||||||
flags.C = f;
|
|
||||||
flags.P = (BC != 0);
|
|
||||||
_35(b);
|
|
||||||
flags._5 = ((b & 0x02) != 0);
|
|
||||||
_memptr++;
|
|
||||||
break;
|
|
||||||
case 0xa2:
|
|
||||||
// ini
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _inr(BC);
|
|
||||||
_sb(HL, b);
|
|
||||||
B--;
|
|
||||||
HL++;
|
|
||||||
c = b + C + 1;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
break;
|
|
||||||
case 0xa3:
|
|
||||||
// outi
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _rb(HL);
|
|
||||||
B--;
|
|
||||||
_outr(BC, b);
|
|
||||||
HL++;
|
|
||||||
c = b + L;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
break;
|
|
||||||
case 0xa8:
|
|
||||||
// ldd
|
|
||||||
b = _rb(HL);
|
|
||||||
BC--;
|
|
||||||
_sb(DE, b);
|
|
||||||
_mc(DE, 1);
|
|
||||||
_mc(DE, 1);
|
|
||||||
DE--;
|
|
||||||
HL--;
|
|
||||||
b += A;
|
|
||||||
flags.P = (BC != 0);
|
|
||||||
_35(b);
|
|
||||||
flags._5 = ((b & 0x02) != 0);
|
|
||||||
flags.N = flags.H = 0;
|
|
||||||
break;
|
|
||||||
case 0xa9:
|
|
||||||
// cpd
|
|
||||||
b = _rb(HL);
|
|
||||||
c = A - b - flags.H;
|
|
||||||
_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);
|
|
||||||
_memptr--;
|
|
||||||
// FIXME: flag H
|
|
||||||
break;
|
|
||||||
case 0xaa:
|
|
||||||
// ind
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _inr(BC);
|
|
||||||
_memptr = BC-1;
|
|
||||||
_sb(HL, b);
|
|
||||||
B--;
|
|
||||||
HL--;
|
|
||||||
c = b + C - 1;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
break;
|
|
||||||
case 0xab:
|
|
||||||
// outd
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _rb(HL);
|
|
||||||
B--;
|
|
||||||
_outr(BC, b);
|
|
||||||
_memptr = BC-1;
|
|
||||||
HL--;
|
|
||||||
c = b + L;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
break;
|
|
||||||
case 0xb0:
|
|
||||||
// ldir
|
|
||||||
b = _rb(HL);
|
|
||||||
BC--;
|
|
||||||
_sb(DE, b);
|
|
||||||
_mc(DE, 1);
|
|
||||||
_mc(DE, 1);
|
|
||||||
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++;
|
|
||||||
break;
|
|
||||||
case 0xb1:
|
|
||||||
// cpir
|
|
||||||
b = _rb(HL);
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
c = A;
|
|
||||||
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) {
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
PC -= 2;
|
|
||||||
_memptr = PC+1;
|
|
||||||
}
|
|
||||||
HL++;
|
|
||||||
break;
|
|
||||||
case 0xb2:
|
|
||||||
// inir
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _inr(BC);
|
|
||||||
_sb(HL, b);
|
|
||||||
B--;
|
|
||||||
c = b + flags.C + 1;
|
|
||||||
flags.N = (c & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
if (B) {
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
PC -= 2;
|
|
||||||
}
|
|
||||||
HL++;
|
|
||||||
break;
|
|
||||||
case 0xb3:
|
|
||||||
// outir
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _rb(HL);
|
|
||||||
B--;
|
|
||||||
_outr(BC, b);
|
|
||||||
HL++;
|
|
||||||
c = b + L;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
if (B) {
|
|
||||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
|
||||||
_mc(BC, 1); _mc(BC, 1);
|
|
||||||
PC -= 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0xb8:
|
|
||||||
// lddr
|
|
||||||
b = _rb(HL);
|
|
||||||
BC--;
|
|
||||||
_sb(DE, b);
|
|
||||||
_mc(DE, 1);
|
|
||||||
_mc(DE, 1);
|
|
||||||
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--;
|
|
||||||
break;
|
|
||||||
case 0xb9:
|
|
||||||
// cpdr
|
|
||||||
b = _rb(HL);
|
|
||||||
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) {
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
PC -= 2;
|
|
||||||
_memptr = PC+1;
|
|
||||||
}
|
|
||||||
HL--;
|
|
||||||
break;
|
|
||||||
case 0xba:
|
|
||||||
// indr
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _inr(BC);
|
|
||||||
_memptr = BC-1;
|
|
||||||
_sb(HL, b);
|
|
||||||
B--;
|
|
||||||
c = b + flags.C + 1;
|
|
||||||
flags.N = (c & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
if (B) {
|
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
|
||||||
PC -= 2;
|
|
||||||
}
|
|
||||||
HL--;
|
|
||||||
break;
|
|
||||||
case 0xbb:
|
|
||||||
// outdr
|
|
||||||
_mc(IR, 1);
|
|
||||||
b = _rb(HL);
|
|
||||||
B--;
|
|
||||||
_outr(BC, b);
|
|
||||||
_memptr = BC-1;
|
|
||||||
HL--;
|
|
||||||
c = b + L;
|
|
||||||
flags.N = (b & 0x80) != 0;
|
|
||||||
flags.C = flags.H = (c < b);
|
|
||||||
flags.P = parity((c & 0x07) ^ B);
|
|
||||||
_sz35(B);
|
|
||||||
if (B) {
|
|
||||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
|
||||||
_mc(BC, 1); _mc(BC, 1);
|
|
||||||
PC -= 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,8 +823,6 @@ void z80::op(uint8_t op) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define A(o, e, a) case o: e(a); break;
|
|
||||||
|
|
||||||
void z80::fdcb(uint8_t op, uint8_t a) {
|
void z80::fdcb(uint8_t op, uint8_t a) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
A(0x00, rlcIYB, a); A(0x01, rlcIYC, a);
|
A(0x00, rlcIYB, a); A(0x01, rlcIYC, a);
|
||||||
|
|
343
z80.h
343
z80.h
|
@ -745,16 +745,16 @@ private:
|
||||||
inline void rst20() { _mc(IR, 1); _push(PC); _memptr = PC = 0x20; }
|
inline void rst20() { _mc(IR, 1); _push(PC); _memptr = PC = 0x20; }
|
||||||
|
|
||||||
// 0xe8
|
// 0xe8
|
||||||
inline uint8_t _inr(uint16_t p) {
|
inline uint8_t _inr() {
|
||||||
_memptr = p+1;
|
_memptr = BC+1;
|
||||||
uint8_t b = _ports->in(p, this);
|
uint8_t b = _ports->in(BC, this);
|
||||||
_szp35(b);
|
_szp35(b);
|
||||||
flags.N = flags.H = 0;
|
flags.N = flags.H = 0;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
inline void _outr(uint16_t p, uint8_t b) {
|
inline void _outr(uint8_t b) {
|
||||||
_memptr = p+1;
|
_memptr = BC+1;
|
||||||
_ports->out(p, b, this);
|
_ports->out(BC, b, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void retpe() { _ret(flags.P); }
|
inline void retpe() { _ret(flags.P); }
|
||||||
|
@ -1198,6 +1198,337 @@ private:
|
||||||
_35(a >> 8);
|
_35(a >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0xED extended instructions
|
||||||
|
inline void inB() { B = _inr(); }
|
||||||
|
inline void inC() { C = _inr(); }
|
||||||
|
inline void inD() { D = _inr(); }
|
||||||
|
inline void inE() { E = _inr(); }
|
||||||
|
inline void inH() { H = _inr(); }
|
||||||
|
inline void inL() { L = _inr(); }
|
||||||
|
inline void inA() { A = _inr(); }
|
||||||
|
inline void outB() { _outr(B); }
|
||||||
|
inline void outC() { _outr(C); }
|
||||||
|
inline void outD() { _outr(D); }
|
||||||
|
inline void outE() { _outr(E); }
|
||||||
|
inline void outH() { _outr(H); }
|
||||||
|
inline void outL() { _outr(L); }
|
||||||
|
inline void outA() { _outr(A); }
|
||||||
|
inline void sbcBC() { _sbc16(BC); }
|
||||||
|
inline void sbcDE() { _sbc16(DE); }
|
||||||
|
inline void sbcHL() { _sbc16(HL); }
|
||||||
|
inline void sbcSP() { _sbc16(SP); }
|
||||||
|
inline void adcBC() { _adc16(BC); }
|
||||||
|
inline void adcDE() { _adc16(DE); }
|
||||||
|
inline void adcHL() { _adc16(HL); }
|
||||||
|
inline void adcSP() { _adc16(SP); }
|
||||||
|
inline void ldPCbc() { _swPC(BC); }
|
||||||
|
inline void ldPCde() { _swPC(DE); }
|
||||||
|
inline void ldPCsp() { _swPC(SP); }
|
||||||
|
inline void ldbcPC() { BC = _rwPC(); }
|
||||||
|
inline void lddePC() { DE = _rwPC(); }
|
||||||
|
inline void ldspPC() { SP = _rwPC(); }
|
||||||
|
inline void neg() { uint8_t b = A; A = 0; _sub(b); }
|
||||||
|
inline void retn() { _iff1 = _iff2; ret(); }
|
||||||
|
inline void ldia() { _mc(IR, 1); I = A; }
|
||||||
|
inline void ldra() { _mc(IR, 1); R = A; }
|
||||||
|
inline void ldai() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
A = I;
|
||||||
|
_sz35(A);
|
||||||
|
flags.P = _iff2;
|
||||||
|
flags.H = flags.N = 0;
|
||||||
|
}
|
||||||
|
inline void ldar() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
A = R;
|
||||||
|
_sz35(A);
|
||||||
|
flags.P = _iff2;
|
||||||
|
flags.H = flags.N = 0;
|
||||||
|
}
|
||||||
|
inline void rrd() {
|
||||||
|
_memptr = HL+1;
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
_sb(HL, (A << 4) | (b >> 4));
|
||||||
|
A = (A & 0xf0) | (b & 0x0f);
|
||||||
|
_szp35(A);
|
||||||
|
flags.H = flags.N = 0;
|
||||||
|
}
|
||||||
|
inline void rld() {
|
||||||
|
_memptr = HL+1;
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
_sb(HL, (A & 0x0f) | (b << 4));
|
||||||
|
A = (A & 0xf0) | (b >> 4);
|
||||||
|
_szp35(A);
|
||||||
|
flags.N = flags.H = 0;
|
||||||
|
}
|
||||||
|
inline void ldi() {
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
BC--;
|
||||||
|
_sb(DE, b);
|
||||||
|
_mc(DE, 1);
|
||||||
|
_mc(DE, 1);
|
||||||
|
DE++;
|
||||||
|
HL++;
|
||||||
|
b += A;
|
||||||
|
flags.P = (BC != 0);
|
||||||
|
_35(b);
|
||||||
|
flags._5 = ((b & 0x02) != 0);
|
||||||
|
flags.N = flags.H = 0;
|
||||||
|
}
|
||||||
|
inline void cpi() {
|
||||||
|
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);
|
||||||
|
HL++;
|
||||||
|
BC--;
|
||||||
|
b = A;
|
||||||
|
A = c;
|
||||||
|
if (flags.H) b--;
|
||||||
|
flags.C = f;
|
||||||
|
flags.P = (BC != 0);
|
||||||
|
_35(b);
|
||||||
|
flags._5 = ((b & 0x02) != 0);
|
||||||
|
_memptr++;
|
||||||
|
}
|
||||||
|
inline void ini() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _inr();
|
||||||
|
_sb(HL, b);
|
||||||
|
B--;
|
||||||
|
HL++;
|
||||||
|
uint8_t c = b + C + 1;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
}
|
||||||
|
inline void outi() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
B--;
|
||||||
|
_outr(b);
|
||||||
|
HL++;
|
||||||
|
uint8_t c = b + L;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
}
|
||||||
|
inline void ldd_() {
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
BC--;
|
||||||
|
_sb(DE, b);
|
||||||
|
_mc(DE, 1);
|
||||||
|
_mc(DE, 1);
|
||||||
|
DE--;
|
||||||
|
HL--;
|
||||||
|
b += A;
|
||||||
|
flags.P = (BC != 0);
|
||||||
|
_35(b);
|
||||||
|
flags._5 = ((b & 0x02) != 0);
|
||||||
|
flags.N = flags.H = 0;
|
||||||
|
}
|
||||||
|
inline void cpd_() {
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
uint8_t c = A - b - flags.H;
|
||||||
|
_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);
|
||||||
|
_memptr--;
|
||||||
|
// FIXME: flag H
|
||||||
|
}
|
||||||
|
inline void ind() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _inr();
|
||||||
|
_memptr = BC-1;
|
||||||
|
_sb(HL, b);
|
||||||
|
B--;
|
||||||
|
HL--;
|
||||||
|
uint8_t c = b + C - 1;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
}
|
||||||
|
inline void outd() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
B--;
|
||||||
|
_outr(b);
|
||||||
|
_memptr = BC-1;
|
||||||
|
HL--;
|
||||||
|
uint8_t c = b + L;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
}
|
||||||
|
inline void ldir() {
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
BC--;
|
||||||
|
_sb(DE, b);
|
||||||
|
_mc(DE, 1);
|
||||||
|
_mc(DE, 1);
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
PC -= 2;
|
||||||
|
_memptr = PC+1;
|
||||||
|
}
|
||||||
|
HL++;
|
||||||
|
}
|
||||||
|
inline void inir() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _inr();
|
||||||
|
_sb(HL, b);
|
||||||
|
B--;
|
||||||
|
uint8_t c = b + flags.C + 1;
|
||||||
|
flags.N = (c & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
if (B) {
|
||||||
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
PC -= 2;
|
||||||
|
}
|
||||||
|
HL++;
|
||||||
|
}
|
||||||
|
inline void outir() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
B--;
|
||||||
|
_outr(b);
|
||||||
|
HL++;
|
||||||
|
uint8_t c = b + L;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
if (B) {
|
||||||
|
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||||
|
_mc(BC, 1); _mc(BC, 1);
|
||||||
|
PC -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void lddr() {
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
BC--;
|
||||||
|
_sb(DE, b);
|
||||||
|
_mc(DE, 1);
|
||||||
|
_mc(DE, 1);
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
PC -= 2;
|
||||||
|
_memptr = PC+1;
|
||||||
|
}
|
||||||
|
HL--;
|
||||||
|
}
|
||||||
|
inline void indr() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _inr();
|
||||||
|
_memptr = BC-1;
|
||||||
|
_sb(HL, b);
|
||||||
|
B--;
|
||||||
|
uint8_t c = b + flags.C + 1;
|
||||||
|
flags.N = (c & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
if (B) {
|
||||||
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
PC -= 2;
|
||||||
|
}
|
||||||
|
HL--;
|
||||||
|
}
|
||||||
|
inline void outdr() {
|
||||||
|
_mc(IR, 1);
|
||||||
|
uint8_t b = _rb(HL);
|
||||||
|
B--;
|
||||||
|
_outr(b);
|
||||||
|
_memptr = BC-1;
|
||||||
|
HL--;
|
||||||
|
uint8_t c = b + L;
|
||||||
|
flags.N = (b & 0x80) != 0;
|
||||||
|
flags.C = flags.H = (c < b);
|
||||||
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
|
_sz35(B);
|
||||||
|
if (B) {
|
||||||
|
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||||
|
_mc(BC, 1); _mc(BC, 1);
|
||||||
|
PC -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 0xDDCB extended instructions
|
// 0xDDCB extended instructions
|
||||||
|
|
||||||
inline uint16_t _rbIX(uint8_t &b, uint8_t o) {
|
inline uint16_t _rbIX(uint8_t &b, uint8_t o) {
|
||||||
|
|
Loading…
Reference in New Issue