- [FIX] SET_PARITY_FLAG() should work on the result
-[NEW] Implemented flag calculation for IN(), OUT(), INI(), IND(), OUTI(), OUTD() - [FIX] Corrected flag calculation for CPI, CPD, - [CHG] Renamed SWAP to EX
This commit is contained in:
113
z80.cpp
113
z80.cpp
@@ -129,7 +129,7 @@ namespace z80
|
|||||||
|
|
||||||
#define rPC (*_rPC)
|
#define rPC (*_rPC)
|
||||||
|
|
||||||
#define SWAP(a,b) {auto temp=a;a=b;b=temp;}
|
#define EX(a,b) {auto temp=a;a=b;b=temp;}
|
||||||
|
|
||||||
uint8_t READ_MEM_8(const uint16_t addr)
|
uint8_t READ_MEM_8(const uint16_t addr)
|
||||||
{
|
{
|
||||||
@@ -204,11 +204,11 @@ namespace z80
|
|||||||
rF |= (value & (fY | fX));
|
rF |= (value & (fY | fX));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SET_PARITY_FLAG()
|
inline void SET_PARITY_FLAG(const uint8_t value)
|
||||||
{
|
{
|
||||||
uint8_t count=0;
|
uint8_t count=0;
|
||||||
uint8_t f = rF;
|
uint8_t v = value;
|
||||||
while (f>0) { count+=(f&1); f=f>>1; }
|
while (v>0) { count+=(v&1); v=v>>1; }
|
||||||
if (!(count&1)) rF |= fP;
|
if (!(count&1)) rF |= fP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ namespace z80
|
|||||||
rA = rA & b;
|
rA = rA & b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
SET_FLAGS(fH);
|
SET_FLAGS(fH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ namespace z80
|
|||||||
rA = rA ^ b;
|
rA = rA ^ b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OR(uint8_t b)
|
void OR(uint8_t b)
|
||||||
@@ -399,7 +399,7 @@ namespace z80
|
|||||||
rA = rA | b;
|
rA = rA | b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP(uint8_t b)
|
void CP(uint8_t b)
|
||||||
@@ -462,7 +462,7 @@ namespace z80
|
|||||||
WRITE_MEM_8(rHL, hl);
|
WRITE_MEM_8(rHL, hl);
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
t+=4;
|
t+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ namespace z80
|
|||||||
WRITE_MEM_8(rHL, hl);
|
WRITE_MEM_8(rHL, hl);
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
t+=4;
|
t+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +489,7 @@ namespace z80
|
|||||||
FLAGS_SZXY(rA);
|
FLAGS_SZXY(rA);
|
||||||
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
||||||
if (carry_set) SET_FLAGS(fC);
|
if (carry_set) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(rA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPL()
|
void CPL()
|
||||||
@@ -654,7 +654,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (res&1) SET_FLAGS(fC);
|
if (res&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,7 +664,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (res&0x80) SET_FLAGS(fC);
|
if (res&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,7 +674,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,7 +684,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,7 +694,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,7 +704,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,7 +714,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,7 +724,7 @@ namespace z80
|
|||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
FLAGS_SZXY(res);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG();
|
SET_PARITY_FLAG(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,14 +793,15 @@ namespace z80
|
|||||||
|
|
||||||
void CPI()
|
void CPI()
|
||||||
{
|
{
|
||||||
uint8_t old_fC = rF & fC;
|
bool keep_fC = (rF & fC);
|
||||||
CP(READ_MEM_8(rHL));
|
CP(READ_MEM_8(rHL));
|
||||||
rHL++;
|
rHL++;
|
||||||
rBC--;
|
rBC--;
|
||||||
t+=2;
|
t+=2;
|
||||||
rF = (rF & 0xFD) | old_fC;
|
KEEP_FLAGS(fS | fZ | fH | fN);
|
||||||
|
if (keep_fC) SET_FLAGS(fC);
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
if (rBC!=0) SET_FLAGS(fP);
|
||||||
if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
//if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPIR()
|
void CPIR()
|
||||||
@@ -815,14 +816,14 @@ namespace z80
|
|||||||
|
|
||||||
void CPD()
|
void CPD()
|
||||||
{
|
{
|
||||||
uint8_t old_fC = rF & fC;
|
bool keep_fC = (rF & fC);
|
||||||
CP(READ_MEM_8(rHL));
|
CP(READ_MEM_8(rHL));
|
||||||
rHL--;
|
rHL--;
|
||||||
rBC--;
|
rBC--;
|
||||||
t+=2;
|
t+=2;
|
||||||
rF = (rF & 0xFD) | old_fC;
|
KEEP_FLAGS(fS | fZ | fH | fN);
|
||||||
|
if (keep_fC) SET_FLAGS(fC);
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
if (rBC!=0) SET_FLAGS(fP);
|
||||||
if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPDR()
|
void CPDR()
|
||||||
@@ -837,22 +838,26 @@ namespace z80
|
|||||||
|
|
||||||
const uint8_t IN(int port = 0x10000)
|
const uint8_t IN(int port = 0x10000)
|
||||||
{
|
{
|
||||||
|
bool set_flags=true;
|
||||||
t+=4;
|
t+=4;
|
||||||
|
|
||||||
if (port == 0x10000) {
|
if (port == 0x10000) {
|
||||||
port = rBC;
|
port = rBC;
|
||||||
// [TODO] set flags acordingly
|
|
||||||
} else {
|
} else {
|
||||||
|
set_flags=false;
|
||||||
port = (rA<<8) | port;
|
port = (rA<<8) | port;
|
||||||
// don't touch flags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_ports[port&0xff]) {
|
if (in_ports[port&0xff]) {
|
||||||
const uint8_t val = (uint8_t)in_ports[port&0xff](port);
|
const uint8_t val = (uint8_t)in_ports[port&0xff](port);
|
||||||
if (val != 0xff)
|
if (set_flags) {
|
||||||
return val;
|
KEEP_FLAGS(fC);
|
||||||
else
|
SET_PARITY_FLAG(val);
|
||||||
return 0xff;
|
FLAGS_SZXY(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
} else
|
} else
|
||||||
return 0x00;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OUT(uint8_t val, int port = 0x10000)
|
void OUT(uint8_t val, int port = 0x10000)
|
||||||
@@ -866,9 +871,17 @@ namespace z80
|
|||||||
|
|
||||||
void INI()
|
void INI()
|
||||||
{
|
{
|
||||||
WRITE_MEM_8(rHL, IN());
|
|
||||||
rHL++;
|
|
||||||
DEC8(_rB);
|
DEC8(_rB);
|
||||||
|
const uint8_t flags_after_dec = rF;
|
||||||
|
const uint8_t val = IN();
|
||||||
|
WRITE_MEM_8(rHL, val);
|
||||||
|
rHL++;
|
||||||
|
SET_FLAGS(flags_after_dec);
|
||||||
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
||||||
|
if (val&0x80) SET_FLAGS(fN);
|
||||||
|
uint16_t k = val + ((rC+1)&255);
|
||||||
|
if (k>255) SET_FLAGS(fH | fC);
|
||||||
|
SET_PARITY_FLAG((k&7)^rB);
|
||||||
t+=5;
|
t+=5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,9 +897,17 @@ namespace z80
|
|||||||
|
|
||||||
void IND()
|
void IND()
|
||||||
{
|
{
|
||||||
WRITE_MEM_8(rHL, IN());
|
|
||||||
rHL--;
|
|
||||||
DEC8(_rB);
|
DEC8(_rB);
|
||||||
|
const uint8_t flags_after_dec = rF;
|
||||||
|
const uint8_t val = IN();
|
||||||
|
WRITE_MEM_8(rHL, val);
|
||||||
|
rHL--;
|
||||||
|
SET_FLAGS(flags_after_dec);
|
||||||
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
||||||
|
if (val&0x80) SET_FLAGS(fN);
|
||||||
|
uint16_t k = val + ((rC-1)&255);
|
||||||
|
if (k>255) SET_FLAGS(fH | fC);
|
||||||
|
SET_PARITY_FLAG((k&7)^rB);
|
||||||
t+=5;
|
t+=5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -902,9 +923,15 @@ namespace z80
|
|||||||
|
|
||||||
void OUTI()
|
void OUTI()
|
||||||
{
|
{
|
||||||
OUT(READ_MEM_8(rHL));
|
const uint8_t val = READ_MEM_8(rHL);
|
||||||
|
OUT(val);
|
||||||
rHL++;
|
rHL++;
|
||||||
DEC8(_rB);
|
DEC8(_rB);
|
||||||
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
||||||
|
if (val&0x80) SET_FLAGS(fN);
|
||||||
|
uint16_t k = rL+val;
|
||||||
|
if (k>255) SET_FLAGS(fH | fC);
|
||||||
|
SET_PARITY_FLAG((k&7)^rB);
|
||||||
t+=5;
|
t+=5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,9 +946,15 @@ namespace z80
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OUTD() {
|
void OUTD() {
|
||||||
OUT(READ_MEM_8(rHL));
|
const uint8_t val = READ_MEM_8(rHL);
|
||||||
|
OUT(val);
|
||||||
rHL--;
|
rHL--;
|
||||||
DEC8(_rB);
|
DEC8(_rB);
|
||||||
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
||||||
|
if (val&0x80) SET_FLAGS(fN);
|
||||||
|
uint16_t k = rL+val;
|
||||||
|
if (k>255) SET_FLAGS(fH | fC);
|
||||||
|
SET_PARITY_FLAG((k&7)^rB);
|
||||||
t+=5;
|
t+=5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,7 +1015,7 @@ namespace z80
|
|||||||
case 0x05: DEC8(_rB); break;
|
case 0x05: DEC8(_rB); break;
|
||||||
case 0x06: rB = READ_MEM_8(); break;
|
case 0x06: rB = READ_MEM_8(); break;
|
||||||
case 0x07: RLCA(); break;
|
case 0x07: RLCA(); break;
|
||||||
case 0x08: SWAP(rAF, rAF2); break;
|
case 0x08: EX(rAF, rAF2); break;
|
||||||
case 0x09: ADD16(_rHL, rBC); break;
|
case 0x09: ADD16(_rHL, rBC); break;
|
||||||
case 0x0A: rA = READ_MEM_8(rBC); break;
|
case 0x0A: rA = READ_MEM_8(rBC); break;
|
||||||
case 0x0B: DEC16(_rBC); break;
|
case 0x0B: DEC16(_rBC); break;
|
||||||
@@ -1204,7 +1237,7 @@ namespace z80
|
|||||||
case 0xD6: SUB8(READ_MEM_8()); break;
|
case 0xD6: SUB8(READ_MEM_8()); break;
|
||||||
case 0xD7: RST(0x10); break;
|
case 0xD7: RST(0x10); break;
|
||||||
case 0xD8: RET(cC); break;
|
case 0xD8: RET(cC); break;
|
||||||
case 0xD9: SWAP(rBC, rBC2);SWAP(rDE, rDE2);SWAP(rHL, rHL2); break;
|
case 0xD9: EX(rBC, rBC2);EX(rDE, rDE2);EX(rHL, rHL2); break;
|
||||||
case 0xDA: JP(cC, READ_MEM_16()); break;
|
case 0xDA: JP(cC, READ_MEM_16()); break;
|
||||||
case 0xDB: rA = IN(READ_MEM_8()); break;
|
case 0xDB: rA = IN(READ_MEM_8()); break;
|
||||||
case 0xDC: CALL(cC, READ_MEM_16()); break;
|
case 0xDC: CALL(cC, READ_MEM_16()); break;
|
||||||
@@ -1223,7 +1256,7 @@ namespace z80
|
|||||||
case 0xE8: RET(cPE); break;
|
case 0xE8: RET(cPE); break;
|
||||||
case 0xE9: JP(cNO, rHL); break;
|
case 0xE9: JP(cNO, rHL); break;
|
||||||
case 0xEA: JP(cPE, READ_MEM_16()); break;
|
case 0xEA: JP(cPE, READ_MEM_16()); break;
|
||||||
case 0xEB: SWAP(rDE, rHL); break;
|
case 0xEB: EX(rDE, rHL); break;
|
||||||
case 0xEC: CALL(cPE, READ_MEM_16()); break;
|
case 0xEC: CALL(cPE, READ_MEM_16()); break;
|
||||||
case 0xED: MISC_INSTRUCTIONS(); break;
|
case 0xED: MISC_INSTRUCTIONS(); break;
|
||||||
case 0xEE: XOR(READ_MEM_8()); break;
|
case 0xEE: XOR(READ_MEM_8()); break;
|
||||||
|
|||||||
Reference in New Issue
Block a user