- [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 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)
|
||||
{
|
||||
@@ -204,11 +204,11 @@ namespace z80
|
||||
rF |= (value & (fY | fX));
|
||||
}
|
||||
|
||||
inline void SET_PARITY_FLAG()
|
||||
inline void SET_PARITY_FLAG(const uint8_t value)
|
||||
{
|
||||
uint8_t count=0;
|
||||
uint8_t f = rF;
|
||||
while (f>0) { count+=(f&1); f=f>>1; }
|
||||
uint8_t v = value;
|
||||
while (v>0) { count+=(v&1); v=v>>1; }
|
||||
if (!(count&1)) rF |= fP;
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ namespace z80
|
||||
rA = rA & b;
|
||||
rF=0;
|
||||
FLAGS_SZXY(rA);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
SET_FLAGS(fH);
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ namespace z80
|
||||
rA = rA ^ b;
|
||||
rF=0;
|
||||
FLAGS_SZXY(rA);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
}
|
||||
|
||||
void OR(uint8_t b)
|
||||
@@ -399,7 +399,7 @@ namespace z80
|
||||
rA = rA | b;
|
||||
rF=0;
|
||||
FLAGS_SZXY(rA);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
}
|
||||
|
||||
void CP(uint8_t b)
|
||||
@@ -462,7 +462,7 @@ namespace z80
|
||||
WRITE_MEM_8(rHL, hl);
|
||||
KEEP_FLAGS(fC);
|
||||
FLAGS_SZXY(rA);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
t+=4;
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ namespace z80
|
||||
WRITE_MEM_8(rHL, hl);
|
||||
KEEP_FLAGS(fC);
|
||||
FLAGS_SZXY(rA);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
t+=4;
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ namespace z80
|
||||
FLAGS_SZXY(rA);
|
||||
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
||||
if (carry_set) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(rA);
|
||||
}
|
||||
|
||||
void CPL()
|
||||
@@ -654,7 +654,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (res&1) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -664,7 +664,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (res&0x80) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&0x80) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&1) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -694,7 +694,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&0x80) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -704,7 +704,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&1) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -714,7 +714,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&0x80) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -724,7 +724,7 @@ namespace z80
|
||||
rF=0;
|
||||
FLAGS_SZXY(res);
|
||||
if (v&1) SET_FLAGS(fC);
|
||||
SET_PARITY_FLAG();
|
||||
SET_PARITY_FLAG(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -793,14 +793,15 @@ namespace z80
|
||||
|
||||
void CPI()
|
||||
{
|
||||
uint8_t old_fC = rF & fC;
|
||||
bool keep_fC = (rF & fC);
|
||||
CP(READ_MEM_8(rHL));
|
||||
rHL++;
|
||||
rBC--;
|
||||
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 (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
||||
//if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
||||
}
|
||||
|
||||
void CPIR()
|
||||
@@ -815,14 +816,14 @@ namespace z80
|
||||
|
||||
void CPD()
|
||||
{
|
||||
uint8_t old_fC = rF & fC;
|
||||
bool keep_fC = (rF & fC);
|
||||
CP(READ_MEM_8(rHL));
|
||||
rHL--;
|
||||
rBC--;
|
||||
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 (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
||||
}
|
||||
|
||||
void CPDR()
|
||||
@@ -837,22 +838,26 @@ namespace z80
|
||||
|
||||
const uint8_t IN(int port = 0x10000)
|
||||
{
|
||||
bool set_flags=true;
|
||||
t+=4;
|
||||
|
||||
if (port == 0x10000) {
|
||||
port = rBC;
|
||||
// [TODO] set flags acordingly
|
||||
} else {
|
||||
set_flags=false;
|
||||
port = (rA<<8) | port;
|
||||
// don't touch flags
|
||||
}
|
||||
|
||||
if (in_ports[port&0xff]) {
|
||||
const uint8_t val = (uint8_t)in_ports[port&0xff](port);
|
||||
if (val != 0xff)
|
||||
return val;
|
||||
else
|
||||
return 0xff;
|
||||
if (set_flags) {
|
||||
KEEP_FLAGS(fC);
|
||||
SET_PARITY_FLAG(val);
|
||||
FLAGS_SZXY(val);
|
||||
}
|
||||
return val;
|
||||
} else
|
||||
return 0x00;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void OUT(uint8_t val, int port = 0x10000)
|
||||
@@ -866,9 +871,17 @@ namespace z80
|
||||
|
||||
void INI()
|
||||
{
|
||||
WRITE_MEM_8(rHL, IN());
|
||||
rHL++;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -884,9 +897,17 @@ namespace z80
|
||||
|
||||
void IND()
|
||||
{
|
||||
WRITE_MEM_8(rHL, IN());
|
||||
rHL--;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -902,9 +923,15 @@ namespace z80
|
||||
|
||||
void OUTI()
|
||||
{
|
||||
OUT(READ_MEM_8(rHL));
|
||||
const uint8_t val = READ_MEM_8(rHL);
|
||||
OUT(val);
|
||||
rHL++;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -919,9 +946,15 @@ namespace z80
|
||||
}
|
||||
|
||||
void OUTD() {
|
||||
OUT(READ_MEM_8(rHL));
|
||||
const uint8_t val = READ_MEM_8(rHL);
|
||||
OUT(val);
|
||||
rHL--;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -982,7 +1015,7 @@ namespace z80
|
||||
case 0x05: DEC8(_rB); break;
|
||||
case 0x06: rB = READ_MEM_8(); break;
|
||||
case 0x07: RLCA(); break;
|
||||
case 0x08: SWAP(rAF, rAF2); break;
|
||||
case 0x08: EX(rAF, rAF2); break;
|
||||
case 0x09: ADD16(_rHL, rBC); break;
|
||||
case 0x0A: rA = READ_MEM_8(rBC); break;
|
||||
case 0x0B: DEC16(_rBC); break;
|
||||
@@ -1204,7 +1237,7 @@ namespace z80
|
||||
case 0xD6: SUB8(READ_MEM_8()); break;
|
||||
case 0xD7: RST(0x10); 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 0xDB: rA = IN(READ_MEM_8()); break;
|
||||
case 0xDC: CALL(cC, READ_MEM_16()); break;
|
||||
@@ -1223,7 +1256,7 @@ namespace z80
|
||||
case 0xE8: RET(cPE); break;
|
||||
case 0xE9: JP(cNO, rHL); 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 0xED: MISC_INSTRUCTIONS(); break;
|
||||
case 0xEE: XOR(READ_MEM_8()); break;
|
||||
|
||||
Reference in New Issue
Block a user