Bring LR35902 a little closer to the Z80

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-07-20 12:37:54 +01:00
parent d0e98fa585
commit 7c3fc469a8
2 changed files with 45 additions and 39 deletions

View File

@ -184,17 +184,17 @@ namespace EightBit {
static void orr(uint8_t& f, uint8_t& operand, uint8_t value); static void orr(uint8_t& f, uint8_t& operand, uint8_t value);
static void compare(uint8_t& f, uint8_t check, uint8_t value); static void compare(uint8_t& f, uint8_t check, uint8_t value);
static void rlc(uint8_t& f, uint8_t& operand); static uint8_t& rlc(uint8_t& f, uint8_t& operand);
static void rrc(uint8_t& f, uint8_t& operand); static uint8_t& rrc(uint8_t& f, uint8_t& operand);
static void rl(uint8_t& f, uint8_t& operand); static uint8_t& rl(uint8_t& f, uint8_t& operand);
static void rr(uint8_t& f, uint8_t& operand); static uint8_t& rr(uint8_t& f, uint8_t& operand);
static void sla(uint8_t& f, uint8_t& operand); static uint8_t& sla(uint8_t& f, uint8_t& operand);
static void sra(uint8_t& f, uint8_t& operand); static uint8_t& sra(uint8_t& f, uint8_t& operand);
static void srl(uint8_t& f, uint8_t& operand); static uint8_t& srl(uint8_t& f, uint8_t& operand);
static void bit(uint8_t& f, int n, uint8_t& operand); static uint8_t& bit(uint8_t& f, int n, uint8_t& operand);
static void res(int n, uint8_t& operand); static uint8_t& res(int n, uint8_t& operand);
static void set(int n, uint8_t& operand); static uint8_t& set(int n, uint8_t& operand);
static void daa(uint8_t& a, uint8_t& f); static void daa(uint8_t& a, uint8_t& f);
@ -202,6 +202,6 @@ namespace EightBit {
static void ccf(uint8_t& a, uint8_t& f); static void ccf(uint8_t& a, uint8_t& f);
static void cpl(uint8_t& a, uint8_t& f); static void cpl(uint8_t& a, uint8_t& f);
void swap(uint8_t& f, uint8_t& operand); uint8_t& swap(uint8_t& f, uint8_t& operand);
}; };
} }

View File

@ -240,78 +240,84 @@ void EightBit::LR35902::compare(uint8_t& f, uint8_t check, uint8_t value) {
#pragma region Shift and rotate #pragma region Shift and rotate
void EightBit::LR35902::rlc(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::rlc(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit7); setFlag(f, CF, operand & Bit7);
operand = _rotl8(operand, 1); operand = _rotl8(operand, 1);
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
void EightBit::LR35902::rrc(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::rrc(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0); setFlag(f, CF, operand & Bit0);
operand = _rotr8(operand, 1); operand = _rotr8(operand, 1);
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
void EightBit::LR35902::rl(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::rl(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
const auto carry = (f & CF) >> 4; const auto carry = (f & CF) >> 4;
setFlag(f, CF, operand & Bit7); setFlag(f, CF, operand & Bit7);
operand = (operand << 1) | carry; operand = (operand << 1) | carry;
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
void EightBit::LR35902::rr(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::rr(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
const auto carry = (f & CF) >> 4; const auto carry = (f & CF) >> 4;
setFlag(f, CF, operand & Bit0); setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) | (carry << 7); operand = (operand >> 1) | (carry << 7);
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
// //
void EightBit::LR35902::sla(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::sla(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit7); setFlag(f, CF, operand & Bit7);
operand <<= 1; operand <<= 1;
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
void EightBit::LR35902::sra(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::sra(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0); setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) | operand & Bit7; operand = (operand >> 1) | operand & Bit7;
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
void EightBit::LR35902::srl(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::srl(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0); setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) & ~Bit7; operand = (operand >> 1) & ~Bit7;
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
return operand;
} }
#pragma endregion Shift and rotate #pragma endregion Shift and rotate
#pragma region BIT/SET/RES #pragma region BIT/SET/RES
void EightBit::LR35902::bit(uint8_t& f, int n, uint8_t& operand) { uint8_t& EightBit::LR35902::bit(uint8_t& f, int n, uint8_t& operand) {
auto carry = f & CF; auto carry = f & CF;
uint8_t discarded = operand; uint8_t discarded = operand;
andr(f, discarded, 1 << n); andr(f, discarded, 1 << n);
setFlag(f, CF, carry); setFlag(f, CF, carry);
return operand;
} }
void EightBit::LR35902::res(int n, uint8_t& operand) { uint8_t& EightBit::LR35902::res(int n, uint8_t& operand) {
auto bit = 1 << n; return operand &= ~(1 << n);
operand &= ~bit;
} }
void EightBit::LR35902::set(int n, uint8_t& operand) { uint8_t& EightBit::LR35902::set(int n, uint8_t& operand) {
auto bit = 1 << n; return operand |= (1 << n);
operand |= bit;
} }
#pragma endregion BIT/SET/RES #pragma endregion BIT/SET/RES
@ -357,12 +363,13 @@ void EightBit::LR35902::ccf(uint8_t& a, uint8_t& f) {
clearFlag(f, NF | HC); clearFlag(f, NF | HC);
} }
void EightBit::LR35902::swap(uint8_t& f, uint8_t& operand) { uint8_t& EightBit::LR35902::swap(uint8_t& f, uint8_t& operand) {
auto low = lowNibble(operand); auto low = lowNibble(operand);
auto high = highNibble(operand); auto high = highNibble(operand);
operand = promoteNibble(low) | demoteNibble(high); operand = promoteNibble(low) | demoteNibble(high);
adjustZero<LR35902>(f, operand); adjustZero<LR35902>(f, operand);
clearFlag(f, NF | HC | CF); clearFlag(f, NF | HC | CF);
return operand;
} }
#pragma endregion Miscellaneous instructions #pragma endregion Miscellaneous instructions
@ -401,31 +408,30 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
case 0: // rot[y] r[z] case 0: // rot[y] r[z]
switch (y) { switch (y) {
case 0: case 0:
rlc(f, R(z, a)); adjustZero<LR35902>(f, rlc(f, R(z, a)));
break; break;
case 1: case 1:
rrc(f, R(z, a)); adjustZero<LR35902>(f, rrc(f, R(z, a)));
break; break;
case 2: case 2:
rl(f, R(z, a)); adjustZero<LR35902>(f, rl(f, R(z, a)));
break; break;
case 3: case 3:
rr(f, R(z, a)); adjustZero<LR35902>(f, rr(f, R(z, a)));
break; break;
case 4: case 4:
sla(f, R(z, a)); adjustZero<LR35902>(f, sla(f, R(z, a)));
break; break;
case 5: case 5:
sra(f, R(z, a)); adjustZero<LR35902>(f, sra(f, R(z, a)));
break; break;
case 6: case 6:
swap(f, R(z, a)); adjustZero<LR35902>(f, swap(f, R(z, a)));
break; break;
case 7: case 7:
srl(f, R(z, a)); adjustZero<LR35902>(f, srl(f, R(z, a)));
break; break;
} }
adjustZero<LR35902>(f, R(z, a));
cycles += 2; cycles += 2;
if (z == 6) { if (z == 6) {
m_bus.fireWriteBusEvent(); m_bus.fireWriteBusEvent();
@ -585,16 +591,16 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 7: // Assorted operations on accumulator/flags case 7: // Assorted operations on accumulator/flags
switch (y) { switch (y) {
case 0: case 0:
rlc(f, a); adjustZero<LR35902>(f, rlc(f, a));
break; break;
case 1: case 1:
rrc(f, a); adjustZero<LR35902>(f, rrc(f, a));
break; break;
case 2: case 2:
rl(f, a); adjustZero<LR35902>(f, rl(f, a));
break; break;
case 3: case 3:
rr(f, a); adjustZero<LR35902>(f, rr(f, a));
break; break;
case 4: case 4:
daa(a, f); daa(a, f);