Bring the various IntelProcessor derived processors a little closer together.

Signed-off-by: Adrian.Conlon <adrian.conlon@arup.com>
This commit is contained in:
Adrian.Conlon 2017-07-19 13:59:28 +01:00
parent 758574007d
commit 36fbee35fb
5 changed files with 270 additions and 314 deletions

View File

@ -107,9 +107,8 @@ namespace EightBit {
//
void compare(uint8_t value) {
auto check = A();
sub(check, value);
void compare(uint8_t& f, uint8_t check, uint8_t value) {
subtract(f, check, value);
}
void anda(uint8_t value) {
@ -154,22 +153,21 @@ namespace EightBit {
HL().word = sum;
}
void sub(uint8_t& operand, uint8_t value, int carry = 0) {
auto& f = F();
register16_t difference;
difference.word = operand - value - carry;
adjustAuxiliaryCarrySub(f, operand, value, difference.word);
operand = difference.low;
setFlag(f, CF, difference.word & Bit8);
void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0) {
register16_t result;
result.word = operand - value - carry;
adjustAuxiliaryCarrySub(f, operand, value, result.word);
operand = result.low;
setFlag(f, CF, result.word & Bit8);
adjustSZP<Intel8080>(f, operand);
}
void sub(uint8_t value, int carry = 0) {
sub(A(), value, carry);
}
void sbb(uint8_t value) {
sub(value, F() & CF);
subtract(F(), A(), value, F() & CF);
}
void mov_m_r(uint8_t value) {
@ -499,17 +497,17 @@ namespace EightBit {
// subtract
void sub_a() { sub(A()); }
void sub_b() { sub(B()); }
void sub_c() { sub(C()); }
void sub_d() { sub(D()); }
void sub_e() { sub(E()); }
void sub_h() { sub(H()); }
void sub_l() { sub(L()); }
void sub_a() { subtract(F(), A(), A()); }
void sub_b() { subtract(F(), A(), B()); }
void sub_c() { subtract(F(), A(), C()); }
void sub_d() { subtract(F(), A(), D()); }
void sub_e() { subtract(F(), A(), E()); }
void sub_h() { subtract(F(), A(), H()); }
void sub_l() { subtract(F(), A(), L()); }
void sub_m() {
m_memory.ADDRESS() = HL();
sub(m_memory.reference());
subtract(F(), A(), m_memory.reference());
}
void sbb_a() { sbb(A()); }
@ -530,7 +528,7 @@ namespace EightBit {
}
void sui() {
sub(fetchByte());
subtract(F(), A(), fetchByte());
}
// logical
@ -580,20 +578,20 @@ namespace EightBit {
void ori() { ora(fetchByte()); }
void cmp_a() { compare(A()); }
void cmp_b() { compare(B()); }
void cmp_c() { compare(C()); }
void cmp_d() { compare(D()); }
void cmp_e() { compare(E()); }
void cmp_h() { compare(H()); }
void cmp_l() { compare(L()); }
void cmp_a() { compare(F(), A(), A()); }
void cmp_b() { compare(F(), A(), B()); }
void cmp_c() { compare(F(), A(), C()); }
void cmp_d() { compare(F(), A(), D()); }
void cmp_e() { compare(F(), A(), E()); }
void cmp_h() { compare(F(), A(), H()); }
void cmp_l() { compare(F(), A(), L()); }
void cmp_m() {
m_memory.ADDRESS() = HL();
compare(m_memory.reference());
compare(F(), A(), m_memory.reference());
}
void cpi() { compare(fetchByte()); }
void cpi() { compare(F(), A(), fetchByte()); }
// rotate

View File

@ -108,7 +108,7 @@ namespace EightBit {
return execute(fetchByte());
}
uint8_t& R(int r) {
uint8_t& R(int r, uint8_t& a) {
switch (r) {
case 0:
return B();
@ -126,7 +126,7 @@ namespace EightBit {
m_memory.ADDRESS() = HL();
return m_memory.reference();
case 7:
return A();
return a;
}
throw std::logic_error("Unhandled registry mechanism");
}
@ -157,6 +157,8 @@ namespace EightBit {
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
}
static void subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
void executeCB(int x, int y, int z, int p, int q);
void executeOther(int x, int y, int z, int p, int q);
@ -165,43 +167,41 @@ namespace EightBit {
void reti();
bool jrConditionalFlag(int flag);
bool returnConditionalFlag(int flag);
bool jumpConditionalFlag(int flag);
bool callConditionalFlag(int flag);
bool jrConditionalFlag(uint8_t& f, int flag);
bool returnConditionalFlag(uint8_t& f, int flag);
bool jumpConditionalFlag(uint8_t& f, int flag);
bool callConditionalFlag(uint8_t& f, int flag);
void sbc(register16_t& operand, register16_t value);
void adc(register16_t& operand, register16_t value);
void sbc(uint8_t& f, register16_t& operand, register16_t value);
void adc(uint8_t& f, register16_t& operand, register16_t value);
void add(uint8_t& f, register16_t& operand, register16_t value);
void add(register16_t& operand, register16_t value);
static void add(uint8_t& f, uint8_t& operand, uint8_t value, int carry = 0);
static void adc(uint8_t& f, uint8_t& operand, uint8_t value);
static void sbc(uint8_t& f, uint8_t& operand, uint8_t value);
static void andr(uint8_t& f, uint8_t& operand, uint8_t value);
static void xorr(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);
void add(uint8_t& operand, uint8_t value, int carry = 0);
void adc(uint8_t& operand, uint8_t value);
void sub(uint8_t& operand, uint8_t value, int carry = 0);
void sbc(uint8_t& operand, uint8_t value);
void andr(uint8_t& operand, uint8_t value);
void xorr(uint8_t& operand, uint8_t value);
void orr(uint8_t& operand, uint8_t value);
void compare(uint8_t value);
static void rlc(uint8_t& f, uint8_t& operand);
static void rrc(uint8_t& f, uint8_t& operand);
static void rl(uint8_t& f, uint8_t& operand);
static void rr(uint8_t& f, uint8_t& operand);
static void sla(uint8_t& f, uint8_t& operand);
static void sra(uint8_t& f, uint8_t& operand);
static void srl(uint8_t& f, uint8_t& operand);
void rlc(uint8_t& operand);
void rrc(uint8_t& operand);
void rl(uint8_t& operand);
void rr(uint8_t& operand);
void sla(uint8_t& operand);
void sra(uint8_t& operand);
void srl(uint8_t& operand);
static void bit(uint8_t& f, int n, uint8_t& operand);
static void res(int n, uint8_t& operand);
static void set(int n, uint8_t& operand);
void bit(int n, uint8_t& operand);
void res(int n, uint8_t& operand);
void set(int nit, uint8_t& operand);
static void daa(uint8_t& a, uint8_t& f);
void daa();
static void scf(uint8_t& a, uint8_t& f);
static void ccf(uint8_t& a, uint8_t& f);
static void cpl(uint8_t& a, uint8_t& f);
void scf();
void ccf();
void cpl();
void swap(uint8_t& operand);
void swap(uint8_t& f, uint8_t& operand);
};
}

View File

@ -67,30 +67,30 @@ void EightBit::LR35902::postDecrement(uint8_t& f, uint8_t value) {
#pragma region PC manipulation: call/ret/jp/jr
bool EightBit::LR35902::jrConditionalFlag(int flag) {
bool EightBit::LR35902::jrConditionalFlag(uint8_t& f, int flag) {
switch (flag) {
case 0: // NZ
return jrConditional(!(F() & ZF));
return jrConditional(!(f & ZF));
case 1: // Z
return jrConditional(F() & ZF);
return jrConditional(f & ZF);
case 2: // NC
return jrConditional(!(F() & CF));
return jrConditional(!(f & CF));
case 3: // C
return jrConditional(F() & CF);
return jrConditional(f & CF);
}
throw std::logic_error("Unhandled JR conditional");
}
bool EightBit::LR35902::jumpConditionalFlag(int flag) {
bool EightBit::LR35902::jumpConditionalFlag(uint8_t& f, int flag) {
switch (flag) {
case 0: // NZ
return jumpConditional(!(F() & ZF));
return jumpConditional(!(f & ZF));
case 1: // Z
return jumpConditional(F() & ZF);
return jumpConditional(f & ZF);
case 2: // NC
return jumpConditional(!(F() & CF));
return jumpConditional(!(f & CF));
case 3: // C
return jumpConditional(F() & CF);
return jumpConditional(f & CF);
}
throw std::logic_error("Unhandled JP conditional");
}
@ -100,30 +100,30 @@ void EightBit::LR35902::reti() {
ei();
}
bool EightBit::LR35902::returnConditionalFlag(int flag) {
bool EightBit::LR35902::returnConditionalFlag(uint8_t& f, int flag) {
switch (flag) {
case 0: // NZ
return returnConditional(!(F() & ZF));
return returnConditional(!(f & ZF));
case 1: // Z
return returnConditional(F() & ZF);
return returnConditional(f & ZF);
case 2: // NC
return returnConditional(!(F() & CF));
return returnConditional(!(f & CF));
case 3: // C
return returnConditional(F() & CF);
return returnConditional(f & CF);
}
throw std::logic_error("Unhandled RET conditional");
}
bool EightBit::LR35902::callConditionalFlag(int flag) {
bool EightBit::LR35902::callConditionalFlag(uint8_t& f, int flag) {
switch (flag) {
case 0: // NZ
return callConditional(!(F() & ZF));
return callConditional(!(f & ZF));
case 1: // Z
return callConditional(F() & ZF);
return callConditional(f & ZF);
case 2: // NC
return callConditional(!(F() & CF));
return callConditional(!(f & CF));
case 3: // C
return callConditional(F() & CF);
return callConditional(f & CF);
}
throw std::logic_error("Unhandled CALL conditional");
}
@ -132,35 +132,33 @@ bool EightBit::LR35902::callConditionalFlag(int flag) {
#pragma region 16-bit arithmetic
void EightBit::LR35902::sbc(register16_t& operand, register16_t value) {
void EightBit::LR35902::sbc(uint8_t& f, register16_t& operand, register16_t value) {
auto before = operand;
auto result = before.word - value.word - (F() & CF);
auto result = before.word - value.word - (f & CF);
operand.word = result;
auto& f = F();
clearFlag(f, ZF, operand.word);
adjustHalfCarrySub(f, before.high, value.high, operand.high);
setFlag(f, NF);
setFlag(f, CF, result & Bit16);
}
void EightBit::LR35902::adc(register16_t& operand, register16_t value) {
void EightBit::LR35902::adc(uint8_t& f, register16_t& operand, register16_t value) {
auto before = operand;
auto result = before.word + value.word + (F() & CF);
auto result = before.word + value.word + (f & CF);
operand.word = result;
auto& f = F();
clearFlag(f, ZF, result);
adjustHalfCarryAdd(f, before.high, value.high, operand.high);
clearFlag(f, NF);
setFlag(f, CF, result & Bit16);
}
void EightBit::LR35902::add(register16_t& operand, register16_t value) {
void EightBit::LR35902::add(uint8_t& f, register16_t& operand, register16_t value) {
auto before = operand;
@ -168,7 +166,6 @@ void EightBit::LR35902::add(register16_t& operand, register16_t value) {
operand.word = result;
auto& f = F();
clearFlag(f, NF);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value.high, operand.high);
@ -178,9 +175,7 @@ void EightBit::LR35902::add(register16_t& operand, register16_t value) {
#pragma region ALU
void EightBit::LR35902::add(uint8_t& operand, uint8_t value, int carry) {
auto& f = F();
void EightBit::LR35902::add(uint8_t& f, uint8_t& operand, uint8_t value, int carry) {
register16_t result;
result.word = operand + value + carry;
@ -194,13 +189,11 @@ void EightBit::LR35902::add(uint8_t& operand, uint8_t value, int carry) {
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::adc(uint8_t& operand, uint8_t value) {
add(operand, value, F() & CF);
void EightBit::LR35902::adc(uint8_t& f, uint8_t& operand, uint8_t value) {
add(operand, value, f & CF);
}
void EightBit::LR35902::sub(uint8_t& operand, uint8_t value, int carry) {
auto& f = F();
void EightBit::LR35902::subtract(uint8_t& f, uint8_t& operand, uint8_t value, int carry) {
register16_t result;
result.word = operand - value - carry;
@ -214,112 +207,87 @@ void EightBit::LR35902::sub(uint8_t& operand, uint8_t value, int carry) {
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::sbc(uint8_t& operand, uint8_t value) {
sub(operand, value, F() & CF);
void EightBit::LR35902::sbc(uint8_t& f, uint8_t& operand, uint8_t value) {
subtract(operand, value, f & CF);
}
void EightBit::LR35902::andr(uint8_t& operand, uint8_t value) {
auto& f = F();
void EightBit::LR35902::andr(uint8_t& f, uint8_t& operand, uint8_t value) {
operand &= value;
setFlag(f, HC);
clearFlag(f, CF | NF);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::xorr(uint8_t& operand, uint8_t value) {
auto& f = F();
void EightBit::LR35902::xorr(uint8_t& f, uint8_t& operand, uint8_t value) {
operand ^= value;
clearFlag(f, HC | CF | NF);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::orr(uint8_t& operand, uint8_t value) {
auto& f = F();
void EightBit::LR35902::orr(uint8_t& f, uint8_t& operand, uint8_t value) {
operand |= value;
clearFlag(f, HC | CF | NF);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::compare(uint8_t value) {
auto check = A();
sub(check, value);
void EightBit::LR35902::compare(uint8_t& f, uint8_t check, uint8_t value) {
subtract(f, check, value);
}
#pragma endregion ALU
#pragma region Shift and rotate
void EightBit::LR35902::rlc(uint8_t& operand) {
auto& f = F();
auto carry = operand & Bit7;
operand <<= 1;
setFlag(f, CF, carry);
carry ? operand |= Bit0 : operand &= ~Bit0;
void EightBit::LR35902::rlc(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit7);
operand = _rotl8(operand, 1);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::rrc(uint8_t& operand) {
auto& f = F();
auto carry = operand & Bit0;
operand >>= 1;
carry ? operand |= Bit7 : operand &= ~Bit7;
setFlag(f, CF, carry);
void EightBit::LR35902::rrc(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0);
operand = _rotr8(operand, 1);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::rl(uint8_t& operand) {
auto& f = F();
auto oldCarry = f & CF;
auto newCarry = operand & Bit7;
operand <<= 1;
oldCarry ? operand |= Bit0 : operand &= ~Bit0;
setFlag(f, CF, newCarry);
void EightBit::LR35902::rl(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
const auto carry = f & CF;
setFlag(f, CF, operand & Bit7);
operand = (operand << 1) | carry;
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::rr(uint8_t& operand) {
auto& f = F();
auto oldCarry = f & CF;
auto newCarry = operand & Bit0;
operand >>= 1;
operand |= oldCarry << 7;
setFlag(f, CF, newCarry);
void EightBit::LR35902::rr(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
const auto carry = f & CF;
setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) | (carry << 7);
adjustZero<LR35902>(f, operand);
}
//
void EightBit::LR35902::sla(uint8_t& operand) {
auto& f = F();
auto newCarry = operand & Bit7;
void EightBit::LR35902::sla(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit7);
operand <<= 1;
setFlag(f, CF, newCarry);
clearFlag(f, NF | HC);
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::sra(uint8_t& operand) {
auto& f = F();
auto new7 = operand & Bit7;
auto newCarry = operand & Bit0;
operand >>= 1;
operand |= new7;
setFlag(f, CF, newCarry);
void EightBit::LR35902::sra(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) | operand & Bit7;
adjustZero<LR35902>(f, operand);
}
void EightBit::LR35902::srl(uint8_t& operand) {
auto& f = F();
auto newCarry = operand & Bit0;
operand >>= 1;
operand &= ~Bit7; // clear bit 7
setFlag(f, CF, newCarry);
void EightBit::LR35902::srl(uint8_t& f, uint8_t& operand) {
clearFlag(f, NF | HC);
setFlag(f, CF, operand & Bit0);
operand = (operand >> 1) & ~Bit7;
adjustZero<LR35902>(f, operand);
}
@ -327,11 +295,10 @@ void EightBit::LR35902::srl(uint8_t& operand) {
#pragma region BIT/SET/RES
void EightBit::LR35902::bit(int n, uint8_t& operand) {
auto& f = F();
void EightBit::LR35902::bit(uint8_t& f, int n, uint8_t& operand) {
auto carry = f & CF;
uint8_t discarded = operand;
andr(discarded, 1 << n);
andr(f, discarded, 1 << n);
setFlag(f, CF, carry);
}
@ -349,55 +316,48 @@ void EightBit::LR35902::set(int n, uint8_t& operand) {
#pragma region Miscellaneous instructions
void EightBit::LR35902::daa() {
void EightBit::LR35902::daa(uint8_t& a, uint8_t& f) {
auto& f = F();
auto updated = a;
uint8_t a = A();
auto lowAdjust = (f & HC) | (lowNibble(a) > 9);
auto highAdjust = (f & CF) | (a > 0x99);
auto lowAdjust = (f & HC) | ((A() & Mask4) > 9);
auto highAdjust = (f & CF) | (A() > 0x99);
if (F() & NF) {
if (f & NF) {
if (lowAdjust)
a -= 6;
updated -= 6;
if (highAdjust)
a -= 0x60;
updated -= 0x60;
} else {
if (lowAdjust)
a += 6;
updated += 6;
if (highAdjust)
a += 0x60;
updated += 0x60;
}
f = (f & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC);
f = (f & (CF | NF)) | (a > 0x99) | ((a ^ updated) & HC);
a = updated;
adjustZero<LR35902>(f, a);
A() = a;
}
void EightBit::LR35902::cpl() {
A() = ~A();
auto& f = F();
void EightBit::LR35902::cpl(uint8_t& a, uint8_t& f) {
a = ~a;
setFlag(f, HC | NF);
}
void EightBit::LR35902::scf() {
auto& f = F();
void EightBit::LR35902::scf(uint8_t& a, uint8_t& f) {
setFlag(f, CF);
clearFlag(f, HC | NF);
}
void EightBit::LR35902::ccf() {
auto& f = F();
void EightBit::LR35902::ccf(uint8_t& a, uint8_t& f) {
auto carry = f & CF;
clearFlag(f, CF, carry);
clearFlag(f, NF | HC);
}
void EightBit::LR35902::swap(uint8_t& operand) {
auto& f = F();
void EightBit::LR35902::swap(uint8_t& f, uint8_t& operand) {
auto low = lowNibble(operand);
auto high = highNibble(operand);
operand = promoteNibble(low) | demoteNibble(high);
@ -435,35 +395,37 @@ int EightBit::LR35902::execute(uint8_t opcode) {
}
void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
auto& a = A();
auto& f = F();
switch (x) {
case 0: // rot[y] r[z]
switch (y) {
case 0:
rlc(R(z));
rlc(f, R(z, a));
break;
case 1:
rrc(R(z));
rrc(f, R(z, a));
break;
case 2:
rl(R(z));
rl(f, R(z, a));
break;
case 3:
rr(R(z));
rr(f, R(z, a));
break;
case 4:
sla(R(z));
sla(f, R(z, a));
break;
case 5:
sra(R(z));
sra(f, R(z, a));
break;
case 6:
swap(R(z));
swap(f, R(z, a));
break;
case 7:
srl(R(z));
srl(f, R(z, a));
break;
}
adjustZero<LR35902>(F(), R(z));
adjustZero<LR35902>(f, R(z, a));
cycles += 2;
if (z == 6) {
m_bus.fireWriteBusEvent();
@ -471,7 +433,7 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
}
break;
case 1: // BIT y, r[z]
bit(y, R(z));
bit(f, y, R(z, a));
cycles += 2;
if (z == 6) {
m_bus.fireReadBusEvent();
@ -479,7 +441,7 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
}
break;
case 2: // RES y, r[z]
res(y, R(z));
res(y, R(z, a));
cycles += 2;
if (z == 6) {
m_bus.fireWriteBusEvent();
@ -487,7 +449,7 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
}
break;
case 3: // SET y, r[z]
set(y, R(z));
set(y, R(z, a));
cycles += 2;
if (z == 6) {
m_bus.fireWriteBusEvent();
@ -498,6 +460,8 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
}
void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
auto& a = A();
auto& f = F();
switch (x) {
case 0:
switch (z) {
@ -519,14 +483,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
jr(fetchByte());
cycles += 4;
break;
default: { // JR cc,d
auto condition = y - 4;
if (condition < 4) {
if (jrConditionalFlag(condition))
cycles++;
cycles += 2;
}
}
case 4: // JR cc,d
case 5:
case 6:
case 7:
if (jrConditionalFlag(f, y - 4))
cycles++;
cycles += 2;
break;
}
break;
@ -537,7 +500,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
cycles += 3;
break;
case 1: // ADD HL,rp
add(HL(), RP(p));
add(f, HL(), RP(p));
cycles += 2;
break;
}
@ -547,19 +510,19 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 0:
switch (p) {
case 0: // LD (BC),A
m_memory.write(BC().word, A());
m_memory.write(BC().word, a);
cycles += 2;
break;
case 1: // LD (DE),A
m_memory.write(DE().word, A());
m_memory.write(DE().word, a);
cycles += 2;
break;
case 2: // GB: LDI (HL),A
m_memory.write(HL().word++, A());
m_memory.write(HL().word++, a);
cycles += 2;
break;
case 3: // GB: LDD (HL),A
m_memory.write(HL().word--, A());
m_memory.write(HL().word--, a);
cycles += 2;
break;
}
@ -567,19 +530,19 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 1:
switch (p) {
case 0: // LD A,(BC)
A() = m_memory.read(BC().word);
a = m_memory.read(BC().word);
cycles += 2;
break;
case 1: // LD A,(DE)
A() = m_memory.read(DE().word);
a = m_memory.read(DE().word);
cycles += 2;
break;
case 2: // GB: LDI A,(HL)
A() = m_memory.read(HL().word++);
a = m_memory.read(HL().word++);
cycles += 2;
break;
case 3: // GB: LDD A,(HL)
A() = m_memory.read(HL().word--);
a = m_memory.read(HL().word--);
cycles += 2;
break;
}
@ -598,7 +561,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
cycles += 2;
break;
case 4: // 8-bit INC
postIncrement(F(), ++R(y)); // INC r
postIncrement(f, ++R(y, a)); // INC r
cycles++;
if (y == 6) {
m_bus.fireWriteBusEvent();
@ -606,7 +569,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
}
break;
case 5: // 8-bit DEC
postDecrement(F(), --R(y)); // DEC r
postDecrement(f, --R(y, a)); // DEC r
cycles++;
if (y == 6) {
m_bus.fireWriteBusEvent();
@ -614,7 +577,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
}
break;
case 6: // 8-bit load immediate
R(y) = fetchByte();
R(y, a) = fetchByte();
if (y == 6)
m_bus.fireWriteBusEvent();
cycles += 2;
@ -622,32 +585,28 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 7: // Assorted operations on accumulator/flags
switch (y) {
case 0:
rlc(A());
clearFlag(F(), ZF);
rlc(f, a);
break;
case 1:
rrc(A());
clearFlag(F(), ZF);
rrc(f, a);
break;
case 2:
rl(A());
clearFlag(F(), ZF);
rl(f, a);
break;
case 3:
rr(A());
clearFlag(F(), ZF);
rr(f, a);
break;
case 4:
daa();
daa(a, f);
break;
case 5:
cpl();
cpl(a, f);
break;
case 6:
scf();
scf(a, f);
break;
case 7:
ccf();
ccf(a, f);
break;
}
cycles++;
@ -658,7 +617,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
if (z == 6 && y == 6) { // Exception (replaces LD (HL), (HL))
halt();
} else {
R(y) = R(z);
R(y, a) = R(z, a);
if ((y == 6) || (z == 6)) { // M operations
if (y == 6)
m_bus.fireWriteBusEvent();
@ -672,28 +631,28 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 2: // Operate on accumulator and register/memory location
switch (y) {
case 0: // ADD A,r
add(A(), R(z));
add(f, a, R(z, a));
break;
case 1: // ADC A,r
adc(A(), R(z));
adc(f, a, R(z, a));
break;
case 2: // SUB r
sub(A(), R(z));
subtract(f, a, R(z, a));
break;
case 3: // SBC A,r
sbc(A(), R(z));
sbc(f, a, R(z, a));
break;
case 4: // AND r
andr(A(), R(z));
andr(f, a, R(z, a));
break;
case 5: // XOR r
xorr(A(), R(z));
xorr(f, a, R(z, a));
break;
case 6: // OR r
orr(A(), R(z));
orr(f, a, R(z, a));
break;
case 7: // CP r
compare(R(z));
compare(f, a, R(z, a));
break;
}
cycles++;
@ -705,45 +664,45 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 3:
switch (z) {
case 0: // Conditional return
if (y < 4) {
if (returnConditionalFlag(y))
switch (y) {
case 0:
case 1:
case 2:
case 3:
if (returnConditionalFlag(f, y))
cycles += 3;
cycles += 2;
} else {
switch (y) {
case 4: // GB: LD (FF00 + n),A
m_bus.writeRegister(fetchByte(), A());
cycles += 3;
break;
case 5: { // GB: ADD SP,dd
auto& f = F();
auto before = SP();
auto value = fetchByte();
auto result = SP().word + (int8_t)value;
SP().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, SP().high);
}
cycles += 4;
break;
case 6: // GB: LD A,(FF00 + n)
A() = m_bus.readRegister(fetchByte());
cycles += 3;
break;
case 7: { // GB: LD HL,SP + dd
auto& f = F();
auto before = HL();
auto value = fetchByte();
auto result = SP().word + (int8_t)value;
HL().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, HL().high);
}
cycles += 3;
break;
break;
case 4: // GB: LD (FF00 + n),A
m_bus.writeRegister(fetchByte(), a);
cycles += 3;
break;
case 5: { // GB: ADD SP,dd
auto before = SP();
auto value = fetchByte();
auto result = SP().word + (int8_t)value;
SP().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, SP().high);
}
cycles += 4;
break;
case 6: // GB: LD A,(FF00 + n)
a = m_bus.readRegister(fetchByte());
cycles += 3;
break;
case 7: { // GB: LD HL,SP + dd
auto before = HL();
auto value = fetchByte();
auto result = SP().word + (int8_t)value;
HL().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, HL().high);
}
cycles += 3;
break;
}
break;
case 1: // POP & various ops
@ -774,30 +733,32 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
}
break;
case 2: // Conditional jump
if (y < 4) {
jumpConditionalFlag(y);
switch (y) {
case 0:
case 1:
case 2:
case 3:
jumpConditionalFlag(f, y);
cycles += 3;
} else {
switch (y) {
case 4: // GB: LD (FF00 + C),A
m_bus.writeRegister(C(), A());
cycles += 2;
break;
case 5: // GB: LD (nn),A
fetchWord();
m_bus.write(MEMPTR().word, A());
cycles += 4;
break;
case 6: // GB: LD A,(FF00 + C)
A() = m_bus.readRegister(C());
cycles += 2;
break;
case 7: // GB: LD A,(nn)
fetchWord();
A() = m_bus.read(MEMPTR().word);
cycles += 4;
break;
}
break;
case 4: // GB: LD (FF00 + C),A
m_bus.writeRegister(C(), a);
cycles += 2;
break;
case 5: // GB: LD (nn),A
fetchWord();
m_bus.write(MEMPTR().word, a);
cycles += 4;
break;
case 6: // GB: LD A,(FF00 + C)
a = m_bus.readRegister(C());
cycles += 2;
break;
case 7: // GB: LD A,(nn)
fetchWord();
a = m_bus.read(MEMPTR().word);
cycles += 4;
break;
}
break;
case 3: // Assorted operations
@ -822,7 +783,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
}
break;
case 4: // Conditional call: CALL cc[y], nn
if (callConditionalFlag(y))
if (callConditionalFlag(f, y))
cycles += 3;
cycles += 3;
break;
@ -845,28 +806,28 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 6: // Operate on accumulator and immediate operand: alu[y] n
switch (y) {
case 0: // ADD A,n
add(A(), fetchByte());
add(f, a, fetchByte());
break;
case 1: // ADC A,n
adc(A(), fetchByte());
adc(f, a, fetchByte());
break;
case 2: // SUB n
sub(A(), fetchByte());
subtract(f, a, fetchByte());
break;
case 3: // SBC A,n
sbc(A(), fetchByte());
sbc(f, a, fetchByte());
break;
case 4: // AND n
andr(A(), fetchByte());
andr(f, a, fetchByte());
break;
case 5: // XOR n
xorr(A(), fetchByte());
xorr(f, a, fetchByte());
break;
case 6: // OR n
orr(A(), fetchByte());
orr(f, a, fetchByte());
break;
case 7: // CP n
compare(fetchByte());
compare(f, a, fetchByte());
break;
}
cycles += 2;

View File

@ -322,7 +322,7 @@ namespace EightBit {
static uint8_t& bit(uint8_t& f, int n, uint8_t& operand);
static uint8_t& res(int n, uint8_t& operand);
static uint8_t& set(int nit, uint8_t& operand);
static uint8_t& set(int n, uint8_t& operand);
static void daa(uint8_t& a, uint8_t& f);

View File

@ -140,14 +140,6 @@ bool EightBit::Z80::jrConditionalFlag(uint8_t& f, int flag) {
return jrConditional(!(f & CF));
case 3: // C
return jrConditional(f & CF);
case 4: // PO
return jrConditional(!(f & PF));
case 5: // PE
return jrConditional(f & PF);
case 6: // P
return jrConditional(!(f & SF));
case 7: // M
return jrConditional(f & SF);
default:
__assume(0);
}
@ -1149,11 +1141,16 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) {
jr(fetchByte());
cycles += 12;
break;
default: // JR cc,d
case 4: // JR cc,d
case 5:
case 6:
case 7:
if (jrConditionalFlag(f, y - 4))
cycles += 5;
cycles += 5;
break;
default:
__assume(0);
}
break;
case 1: // 16-bit load immediate/add