mirror of https://github.com/jscrane/r65emu.git
parity table calculation; z80 flags fixes
This commit is contained in:
parent
d33d25674f
commit
dd4a4dc23b
18
i8080.cpp
18
i8080.cpp
|
@ -84,17 +84,13 @@ void i8080::daa() {
|
||||||
flags.C = c;
|
flags.C = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t partab[] PROGMEM = {
|
uint8_t parity(uint8_t r) {
|
||||||
0x69, 0x96, 0x96, 0x69, 0x96, 0x69, 0x69, 0x96,
|
uint8_t c = 0;
|
||||||
0x96, 0x69, 0x69, 0x96, 0x69, 0x96, 0x96, 0x69,
|
while (r) {
|
||||||
0x96, 0x69, 0x69, 0x96, 0x69, 0x96, 0x96, 0x69,
|
r &= (r-1);
|
||||||
0x69, 0x96, 0x96, 0x69, 0x96, 0x69, 0x69, 0x96,
|
c++;
|
||||||
};
|
}
|
||||||
|
return !(c & 1);
|
||||||
uint8_t parity_tbl(uint8_t r) {
|
|
||||||
uint8_t i = r / 8, b = pgm_read_byte(partab + i);
|
|
||||||
uint8_t m = (1 << (r % 8));
|
|
||||||
return m == (b & m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void i8080::_op(uint8_t op) {
|
void i8080::_op(uint8_t op) {
|
||||||
|
|
4
i8080.h
4
i8080.h
|
@ -5,7 +5,7 @@
|
||||||
#undef PC
|
#undef PC
|
||||||
#undef SP
|
#undef SP
|
||||||
|
|
||||||
uint8_t parity_tbl(uint8_t);
|
uint8_t parity(uint8_t);
|
||||||
|
|
||||||
class i8080: public CPU {
|
class i8080: public CPU {
|
||||||
public:
|
public:
|
||||||
|
@ -76,7 +76,7 @@ private:
|
||||||
inline void _szp(uint8_t r) {
|
inline void _szp(uint8_t r) {
|
||||||
flags.S = ((r & 0x80) != 0);
|
flags.S = ((r & 0x80) != 0);
|
||||||
flags.Z = (r == 0);
|
flags.Z = (r == 0);
|
||||||
flags.P = parity_tbl(r);
|
flags.P = parity(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void _szhp(uint8_t b, uint8_t r) {
|
inline void _szhp(uint8_t b, uint8_t r) {
|
||||||
|
|
57
z80.cpp
57
z80.cpp
|
@ -136,7 +136,7 @@ void z80::daa() {
|
||||||
else
|
else
|
||||||
_add(a);
|
_add(a);
|
||||||
flags.C = c;
|
flags.C = c;
|
||||||
flags.P = parity_table(A);
|
flags.P = parity(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
void z80::_step_idx(EXT_OP f) {
|
void z80::_step_idx(EXT_OP f) {
|
||||||
|
@ -603,6 +603,7 @@ void z80::ed() {
|
||||||
SP = _rwPC();
|
SP = _rwPC();
|
||||||
break;
|
break;
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
|
// ldi
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
BC--;
|
BC--;
|
||||||
_sb(DE, b);
|
_sb(DE, b);
|
||||||
|
@ -617,6 +618,7 @@ void z80::ed() {
|
||||||
flags.N = flags.H = 0;
|
flags.N = flags.H = 0;
|
||||||
break;
|
break;
|
||||||
case 0xa1:
|
case 0xa1:
|
||||||
|
// cpi
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -635,6 +637,7 @@ void z80::ed() {
|
||||||
_memptr++;
|
_memptr++;
|
||||||
break;
|
break;
|
||||||
case 0xa2:
|
case 0xa2:
|
||||||
|
// ini
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _inr(BC);
|
b = _inr(BC);
|
||||||
_sb(HL, b);
|
_sb(HL, b);
|
||||||
|
@ -643,10 +646,11 @@ void z80::ed() {
|
||||||
c = b + C + 1;
|
c = b + C + 1;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
break;
|
break;
|
||||||
case 0xa3:
|
case 0xa3:
|
||||||
|
// outi
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
B--;
|
B--;
|
||||||
|
@ -655,10 +659,11 @@ void z80::ed() {
|
||||||
c = b + L;
|
c = b + L;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
break;
|
break;
|
||||||
case 0xa8:
|
case 0xa8:
|
||||||
|
// ldd
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
BC--;
|
BC--;
|
||||||
_sb(DE, b);
|
_sb(DE, b);
|
||||||
|
@ -673,6 +678,7 @@ void z80::ed() {
|
||||||
flags.N = flags.H = 0;
|
flags.N = flags.H = 0;
|
||||||
break;
|
break;
|
||||||
case 0xa9:
|
case 0xa9:
|
||||||
|
// cpd
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
c = A - b - flags.H;
|
c = A - b - flags.H;
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -687,6 +693,7 @@ void z80::ed() {
|
||||||
// FIXME: flag H
|
// FIXME: flag H
|
||||||
break;
|
break;
|
||||||
case 0xaa:
|
case 0xaa:
|
||||||
|
// ind
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _inr(BC);
|
b = _inr(BC);
|
||||||
_memptr = BC-1;
|
_memptr = BC-1;
|
||||||
|
@ -696,10 +703,11 @@ void z80::ed() {
|
||||||
c = b + C - 1;
|
c = b + C - 1;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
break;
|
break;
|
||||||
case 0xab:
|
case 0xab:
|
||||||
|
// outd
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
B--;
|
B--;
|
||||||
|
@ -709,10 +717,11 @@ void z80::ed() {
|
||||||
c = b + L;
|
c = b + L;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
break;
|
break;
|
||||||
case 0xb0:
|
case 0xb0:
|
||||||
|
// ldir
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
BC--;
|
BC--;
|
||||||
_sb(DE, b);
|
_sb(DE, b);
|
||||||
|
@ -721,6 +730,7 @@ void z80::ed() {
|
||||||
b += A;
|
b += A;
|
||||||
flags.P = (BC != 0);
|
flags.P = (BC != 0);
|
||||||
_35(b);
|
_35(b);
|
||||||
|
flags._5 = ((b & 0x02) != 0);
|
||||||
flags.N = flags.H = 0;
|
flags.N = flags.H = 0;
|
||||||
if (BC) {
|
if (BC) {
|
||||||
_mc(DE, 1); _mc(DE, 1); _mc(DE, 1);
|
_mc(DE, 1); _mc(DE, 1); _mc(DE, 1);
|
||||||
|
@ -732,6 +742,7 @@ void z80::ed() {
|
||||||
HL++;
|
HL++;
|
||||||
break;
|
break;
|
||||||
case 0xb1:
|
case 0xb1:
|
||||||
|
// cpir
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
_mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -739,12 +750,13 @@ void z80::ed() {
|
||||||
f = (flags.C != 0);
|
f = (flags.C != 0);
|
||||||
_sub(b);
|
_sub(b);
|
||||||
BC--;
|
BC--;
|
||||||
b = A;
|
b -= A;
|
||||||
A = c;
|
A = c;
|
||||||
flags.C = f;
|
flags.C = f;
|
||||||
flags.P = (BC != 0);
|
flags.P = (BC != 0);
|
||||||
if (flags.H) b--;
|
if (flags.H) b--;
|
||||||
_35(b);
|
_35(b);
|
||||||
|
flags._5 = ((b & 0x02) != 0);
|
||||||
_memptr++;
|
_memptr++;
|
||||||
if (!flags.Z) {
|
if (!flags.Z) {
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -755,6 +767,7 @@ void z80::ed() {
|
||||||
HL++;
|
HL++;
|
||||||
break;
|
break;
|
||||||
case 0xb2:
|
case 0xb2:
|
||||||
|
// inir
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _inr(BC);
|
b = _inr(BC);
|
||||||
_sb(HL, b);
|
_sb(HL, b);
|
||||||
|
@ -762,7 +775,7 @@ void z80::ed() {
|
||||||
c = b + flags.C + 1;
|
c = b + flags.C + 1;
|
||||||
flags.N = (c & 0x80) != 0;
|
flags.N = (c & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
if (B) {
|
if (B) {
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -772,6 +785,7 @@ void z80::ed() {
|
||||||
HL++;
|
HL++;
|
||||||
break;
|
break;
|
||||||
case 0xb3:
|
case 0xb3:
|
||||||
|
// outir
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
B--;
|
B--;
|
||||||
|
@ -780,7 +794,7 @@ void z80::ed() {
|
||||||
c = b + L;
|
c = b + L;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
if (B) {
|
if (B) {
|
||||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||||
|
@ -789,6 +803,7 @@ void z80::ed() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xb8:
|
case 0xb8:
|
||||||
|
// lddr
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
BC--;
|
BC--;
|
||||||
_sb(DE, b);
|
_sb(DE, b);
|
||||||
|
@ -809,6 +824,7 @@ void z80::ed() {
|
||||||
HL--;
|
HL--;
|
||||||
break;
|
break;
|
||||||
case 0xb9:
|
case 0xb9:
|
||||||
|
// cpdr
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
c = A - b;
|
c = A - b;
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -829,6 +845,7 @@ void z80::ed() {
|
||||||
HL--;
|
HL--;
|
||||||
break;
|
break;
|
||||||
case 0xba:
|
case 0xba:
|
||||||
|
// indr
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _inr(BC);
|
b = _inr(BC);
|
||||||
_memptr = BC-1;
|
_memptr = BC-1;
|
||||||
|
@ -837,7 +854,7 @@ void z80::ed() {
|
||||||
c = b + flags.C + 1;
|
c = b + flags.C + 1;
|
||||||
flags.N = (c & 0x80) != 0;
|
flags.N = (c & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
if (B) {
|
if (B) {
|
||||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||||
|
@ -847,6 +864,7 @@ void z80::ed() {
|
||||||
HL--;
|
HL--;
|
||||||
break;
|
break;
|
||||||
case 0xbb:
|
case 0xbb:
|
||||||
|
// outdr
|
||||||
_mc(IR, 1);
|
_mc(IR, 1);
|
||||||
b = _rb(HL);
|
b = _rb(HL);
|
||||||
B--;
|
B--;
|
||||||
|
@ -856,7 +874,7 @@ void z80::ed() {
|
||||||
c = b + L;
|
c = b + L;
|
||||||
flags.N = (b & 0x80) != 0;
|
flags.N = (b & 0x80) != 0;
|
||||||
flags.C = flags.H = (c < b);
|
flags.C = flags.H = (c < b);
|
||||||
flags.P = parity_table((c & 0x07) ^ B);
|
flags.P = parity((c & 0x07) ^ B);
|
||||||
_sz35(B);
|
_sz35(B);
|
||||||
if (B) {
|
if (B) {
|
||||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||||
|
@ -867,17 +885,14 @@ void z80::ed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t partab[] PROGMEM = {
|
// kernighan's algorithm
|
||||||
0x69, 0x96, 0x96, 0x69, 0x96, 0x69, 0x69, 0x96,
|
uint8_t z80::parity(uint8_t r) {
|
||||||
0x96, 0x69, 0x69, 0x96, 0x69, 0x96, 0x96, 0x69,
|
uint8_t c = 0;
|
||||||
0x96, 0x69, 0x69, 0x96, 0x69, 0x96, 0x96, 0x69,
|
while (r) {
|
||||||
0x69, 0x96, 0x96, 0x69, 0x96, 0x69, 0x69, 0x96,
|
r &= (r-1);
|
||||||
};
|
c++;
|
||||||
|
}
|
||||||
uint8_t z80::parity_table(uint8_t r) {
|
return !(c & 1);
|
||||||
uint8_t i = r / 8, b = pgm_read_byte(partab + i);
|
|
||||||
uint8_t m = (1 << (r % 8));
|
|
||||||
return m == (b & m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void z80::cb() {
|
void z80::cb() {
|
||||||
|
|
8
z80.h
8
z80.h
|
@ -148,7 +148,7 @@ private:
|
||||||
int _irq_pending;
|
int _irq_pending;
|
||||||
PortDevice<z80> *_ports;
|
PortDevice<z80> *_ports;
|
||||||
|
|
||||||
uint8_t parity_table(uint8_t);
|
uint8_t parity(uint8_t);
|
||||||
|
|
||||||
inline uint8_t _rb(Memory::address a) {
|
inline uint8_t _rb(Memory::address a) {
|
||||||
#if defined(CPU_DEBUG)
|
#if defined(CPU_DEBUG)
|
||||||
|
@ -222,7 +222,7 @@ private:
|
||||||
|
|
||||||
inline void _szp35(uint8_t r) {
|
inline void _szp35(uint8_t r) {
|
||||||
_sz35(r);
|
_sz35(r);
|
||||||
flags.P = parity_table(r);
|
flags.P = parity(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void _inc(uint8_t &b) {
|
inline void _inc(uint8_t &b) {
|
||||||
|
@ -500,7 +500,7 @@ private:
|
||||||
inline void inca() { _inc(A); }
|
inline void inca() { _inc(A); }
|
||||||
inline void deca() { _dec(A); }
|
inline void deca() { _dec(A); }
|
||||||
inline void lda() { A = _rb(PC++); }
|
inline void lda() { A = _rb(PC++); }
|
||||||
inline void ccf() { flags.C = !flags.C; flags.N = 0; _35(A); }
|
inline void ccf() { flags.H = flags.C; flags.C = flags.N = 0; _35(A); }
|
||||||
|
|
||||||
// 0x40
|
// 0x40
|
||||||
inline void ldbb() {}
|
inline void ldbb() {}
|
||||||
|
@ -937,7 +937,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void _bitHL(int i) {
|
inline void _bitHL(int i) {
|
||||||
uint8_t b = _rb(HL); _mc(HL, 1); _bit(i, b);
|
uint8_t b = _rb(HL); _mc(HL, 1); _bit(i, b); _35(MPH);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void bit0b() { _bit(0, B); }
|
inline void bit0b() { _bit(0, B); }
|
||||||
|
|
Loading…
Reference in New Issue