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