mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-06-27 11:29:28 +00:00
Share flag adjustments across implementations using templated methods.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
529aa1bd21
commit
f776379e96
|
@ -83,21 +83,6 @@ namespace EightBit {
|
||||||
F() |= Bit1;
|
F() |= Bit1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustSign(uint8_t& f, uint8_t value) { setFlag(f, SF, value & SF); }
|
|
||||||
static void adjustZero(uint8_t& f, uint8_t value) { clearFlag(f, ZF, value); }
|
|
||||||
|
|
||||||
static void adjustParity(uint8_t& f, uint8_t value) {
|
|
||||||
static const uint8_t lookup[0x10] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
|
||||||
auto set = (lookup[highNibble(value)] + lookup[lowNibble(value)]);
|
|
||||||
clearFlag(f, PF, set % 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void adjustSZP(uint8_t& f, uint8_t value) {
|
|
||||||
adjustSign(f, value);
|
|
||||||
adjustZero(f, value);
|
|
||||||
adjustParity(f, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
||||||
setFlag(f, AC, calculateHalfCarryAdd(before, value, calculation));
|
setFlag(f, AC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
@ -107,12 +92,12 @@ namespace EightBit {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void postIncrement(uint8_t& f, uint8_t value) {
|
static void postIncrement(uint8_t& f, uint8_t value) {
|
||||||
adjustSZP(f, value);
|
adjustSZP<Intel8080>(f, value);
|
||||||
clearFlag(f, AC, lowNibble(value));
|
clearFlag(f, AC, lowNibble(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void postDecrement(uint8_t& f, uint8_t value) {
|
static void postDecrement(uint8_t& f, uint8_t value) {
|
||||||
adjustSZP(f, value);
|
adjustSZP<Intel8080>(f, value);
|
||||||
setFlag(f, AC, lowNibble(value) != Mask4);
|
setFlag(f, AC, lowNibble(value) != Mask4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +112,7 @@ namespace EightBit {
|
||||||
const auto& a = A();
|
const auto& a = A();
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
uint16_t subtraction = a - value;
|
uint16_t subtraction = a - value;
|
||||||
adjustSZP(f, (uint8_t)subtraction);
|
adjustSZP<Intel8080>(f, (uint8_t)subtraction);
|
||||||
adjustAuxiliaryCarrySub(f, a, value, subtraction);
|
adjustAuxiliaryCarrySub(f, a, value, subtraction);
|
||||||
setFlag(f, CF, subtraction & Bit8);
|
setFlag(f, CF, subtraction & Bit8);
|
||||||
}
|
}
|
||||||
|
@ -137,19 +122,19 @@ namespace EightBit {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
setFlag(f, AC, (a | value) & Bit3);
|
setFlag(f, AC, (a | value) & Bit3);
|
||||||
clearFlag(f, CF);
|
clearFlag(f, CF);
|
||||||
adjustSZP(f, a &= value);
|
adjustSZP<Intel8080>(f, a &= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ora(uint8_t value) {
|
void ora(uint8_t value) {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
clearFlag(f, AC | CF);
|
clearFlag(f, AC | CF);
|
||||||
adjustSZP(f, A() |= value);
|
adjustSZP<Intel8080>(f, A() |= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xra(uint8_t value) {
|
void xra(uint8_t value) {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
clearFlag(f, AC | CF);
|
clearFlag(f, AC | CF);
|
||||||
adjustSZP(f, A() ^= value);
|
adjustSZP<Intel8080>(f, A() ^= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(uint8_t value, int carry = 0) {
|
void add(uint8_t value, int carry = 0) {
|
||||||
|
@ -160,7 +145,7 @@ namespace EightBit {
|
||||||
adjustAuxiliaryCarryAdd(f, a, value, sum.word);
|
adjustAuxiliaryCarryAdd(f, a, value, sum.word);
|
||||||
a = sum.low;
|
a = sum.low;
|
||||||
setFlag(f, CF, sum.word & Bit8);
|
setFlag(f, CF, sum.word & Bit8);
|
||||||
adjustSZP(f, a);
|
adjustSZP<Intel8080>(f, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc(uint8_t value) {
|
void adc(uint8_t value) {
|
||||||
|
@ -182,7 +167,7 @@ namespace EightBit {
|
||||||
adjustAuxiliaryCarrySub(f, a, value, difference.word);
|
adjustAuxiliaryCarrySub(f, a, value, difference.word);
|
||||||
a = difference.low;
|
a = difference.low;
|
||||||
setFlag(f, CF, difference.word & Bit8);
|
setFlag(f, CF, difference.word & Bit8);
|
||||||
adjustSZP(f, a);
|
adjustSZP<Intel8080>(f, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbb(uint8_t value) {
|
void sbb(uint8_t value) {
|
||||||
|
|
|
@ -253,15 +253,6 @@ namespace EightBit {
|
||||||
void executeED(int x, int y, int z, int p, int q);
|
void executeED(int x, int y, int z, int p, int q);
|
||||||
void executeOther(int x, int y, int z, int p, int q);
|
void executeOther(int x, int y, int z, int p, int q);
|
||||||
|
|
||||||
static void adjustSign(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustZero(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustParity(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustSZ(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustSZP(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustXY(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustSZPXY(uint8_t& f, uint8_t value);
|
|
||||||
static void adjustSZXY(uint8_t& f, uint8_t value);
|
|
||||||
|
|
||||||
void postIncrement(uint8_t& f, uint8_t value);
|
void postIncrement(uint8_t& f, uint8_t value);
|
||||||
void postDecrement(uint8_t& f, uint8_t value);
|
void postDecrement(uint8_t& f, uint8_t value);
|
||||||
|
|
||||||
|
|
121
Z80/src/Z80.cpp
121
Z80/src/Z80.cpp
|
@ -106,54 +106,15 @@ int EightBit::Z80::interrupt(bool maskable, uint8_t value) {
|
||||||
|
|
||||||
#pragma region Flag manipulation helpers
|
#pragma region Flag manipulation helpers
|
||||||
|
|
||||||
void EightBit::Z80::adjustSign(uint8_t& f, uint8_t value) {
|
|
||||||
setFlag(f, SF, value & SF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustZero(uint8_t& f, uint8_t value) {
|
|
||||||
clearFlag(f, ZF, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustParity(uint8_t& f, uint8_t value) {
|
|
||||||
static const uint8_t lookup[0x10] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
|
||||||
auto set = lookup[highNibble(value)] + lookup[lowNibble(value)];
|
|
||||||
clearFlag(f, PF, set % 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustSZ(uint8_t& f, uint8_t value) {
|
|
||||||
adjustSign(f, value);
|
|
||||||
adjustZero(f, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustSZP(uint8_t& f, uint8_t value) {
|
|
||||||
adjustSZ(f, value);
|
|
||||||
adjustParity(f, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustXY(uint8_t& f, uint8_t value) {
|
|
||||||
setFlag(f, XF, value & XF);
|
|
||||||
setFlag(f, YF, value & YF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustSZPXY(uint8_t& f, uint8_t value) {
|
|
||||||
adjustSZP(f, value);
|
|
||||||
adjustXY(f, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::adjustSZXY(uint8_t& f, uint8_t value) {
|
|
||||||
adjustSZ(f, value);
|
|
||||||
adjustXY(f, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Z80::postIncrement(uint8_t& f, uint8_t value) {
|
void EightBit::Z80::postIncrement(uint8_t& f, uint8_t value) {
|
||||||
adjustSZXY(f, value);
|
adjustSZXY<Z80>(f, value);
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
setFlag(f, VF, value == Bit7);
|
setFlag(f, VF, value == Bit7);
|
||||||
clearFlag(f, HC, lowNibble(value));
|
clearFlag(f, HC, lowNibble(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::postDecrement(uint8_t& f, uint8_t value) {
|
void EightBit::Z80::postDecrement(uint8_t& f, uint8_t value) {
|
||||||
adjustSZXY(f, value);
|
adjustSZXY<Z80>(f, value);
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
setFlag(f, VF, value == Mask7);
|
setFlag(f, VF, value == Mask7);
|
||||||
clearFlag(f, HC, lowNibble(value + 1));
|
clearFlag(f, HC, lowNibble(value + 1));
|
||||||
|
@ -284,7 +245,7 @@ void EightBit::Z80::sbc(register16_t& operand, register16_t value) {
|
||||||
adjustOverflowSub(f, beforeNegative, valueNegative, afterNegative);
|
adjustOverflowSub(f, beforeNegative, valueNegative, afterNegative);
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
setFlag(f, CF, result & Bit16);
|
setFlag(f, CF, result & Bit16);
|
||||||
adjustXY(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::adc(register16_t& operand, register16_t value) {
|
void EightBit::Z80::adc(register16_t& operand, register16_t value) {
|
||||||
|
@ -307,7 +268,7 @@ void EightBit::Z80::adc(register16_t& operand, register16_t value) {
|
||||||
adjustOverflowAdd(f, beforeNegative, valueNegative, afterNegative);
|
adjustOverflowAdd(f, beforeNegative, valueNegative, afterNegative);
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
setFlag(f, CF, result & Bit16);
|
setFlag(f, CF, result & Bit16);
|
||||||
adjustXY(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::add(register16_t& operand, register16_t value) {
|
void EightBit::Z80::add(register16_t& operand, register16_t value) {
|
||||||
|
@ -323,7 +284,7 @@ void EightBit::Z80::add(register16_t& operand, register16_t value) {
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
setFlag(f, CF, result & Bit16);
|
setFlag(f, CF, result & Bit16);
|
||||||
adjustHalfCarryAdd(f, before.high, value.high, operand.high);
|
adjustHalfCarryAdd(f, before.high, value.high, operand.high);
|
||||||
adjustXY(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion 16-bit arithmetic
|
#pragma endregion 16-bit arithmetic
|
||||||
|
@ -344,7 +305,7 @@ void EightBit::Z80::add(uint8_t& operand, uint8_t value, int carry) {
|
||||||
|
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
setFlag(f, CF, result.word & Bit8);
|
setFlag(f, CF, result.word & Bit8);
|
||||||
adjustSZXY(f, operand);
|
adjustSZXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::adc(uint8_t& operand, uint8_t value) {
|
void EightBit::Z80::adc(uint8_t& operand, uint8_t value) {
|
||||||
|
@ -365,7 +326,7 @@ void EightBit::Z80::sub(uint8_t& operand, uint8_t value, int carry) {
|
||||||
|
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
setFlag(f, CF, result.word & Bit8);
|
setFlag(f, CF, result.word & Bit8);
|
||||||
adjustSZXY(f, operand);
|
adjustSZXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::sbc(uint8_t& operand, uint8_t value) {
|
void EightBit::Z80::sbc(uint8_t& operand, uint8_t value) {
|
||||||
|
@ -377,28 +338,28 @@ void EightBit::Z80::andr(uint8_t& operand, uint8_t value) {
|
||||||
operand &= value;
|
operand &= value;
|
||||||
setFlag(f, HC);
|
setFlag(f, HC);
|
||||||
clearFlag(f, CF | NF);
|
clearFlag(f, CF | NF);
|
||||||
adjustSZPXY(f, operand);
|
adjustSZPXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::xorr(uint8_t& operand, uint8_t value) {
|
void EightBit::Z80::xorr(uint8_t& operand, uint8_t value) {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
operand ^= value;
|
operand ^= value;
|
||||||
clearFlag(f, HC | CF | NF);
|
clearFlag(f, HC | CF | NF);
|
||||||
adjustSZPXY(f, operand);
|
adjustSZPXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::orr(uint8_t& operand, uint8_t value) {
|
void EightBit::Z80::orr(uint8_t& operand, uint8_t value) {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
operand |= value;
|
operand |= value;
|
||||||
clearFlag(f, HC | CF | NF);
|
clearFlag(f, HC | CF | NF);
|
||||||
adjustSZPXY(f, operand);
|
adjustSZPXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::compare(uint8_t value) {
|
void EightBit::Z80::compare(uint8_t value) {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
auto check = A();
|
auto check = A();
|
||||||
sub(check, value);
|
sub(check, value);
|
||||||
adjustXY(f, value);
|
adjustXY<Z80>(f, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion ALU
|
#pragma endregion ALU
|
||||||
|
@ -412,7 +373,7 @@ uint8_t& EightBit::Z80::rlc(uint8_t& operand) {
|
||||||
carry ? operand |= Bit0 : operand &= ~Bit0;
|
carry ? operand |= Bit0 : operand &= ~Bit0;
|
||||||
setFlag(f, CF, carry);
|
setFlag(f, CF, carry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +384,7 @@ uint8_t& EightBit::Z80::rrc(uint8_t& operand) {
|
||||||
carry ? operand |= Bit7 : operand &= ~Bit7;
|
carry ? operand |= Bit7 : operand &= ~Bit7;
|
||||||
setFlag(f, CF, carry);
|
setFlag(f, CF, carry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +396,7 @@ uint8_t& EightBit::Z80::rl(uint8_t& operand) {
|
||||||
oldCarry ? operand |= Bit0 : operand &= ~Bit0;
|
oldCarry ? operand |= Bit0 : operand &= ~Bit0;
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +408,7 @@ uint8_t& EightBit::Z80::rr(uint8_t& operand) {
|
||||||
operand |= oldCarry << 7;
|
operand |= oldCarry << 7;
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +420,7 @@ uint8_t& EightBit::Z80::sla(uint8_t& operand) {
|
||||||
operand <<= 1;
|
operand <<= 1;
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +432,7 @@ uint8_t& EightBit::Z80::sra(uint8_t& operand) {
|
||||||
operand |= new7;
|
operand |= new7;
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +443,7 @@ uint8_t& EightBit::Z80::sll(uint8_t& operand) {
|
||||||
operand |= 1;
|
operand |= 1;
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +454,7 @@ uint8_t& EightBit::Z80::srl(uint8_t& operand) {
|
||||||
operand &= ~Bit7; // clear bit 7
|
operand &= ~Bit7; // clear bit 7
|
||||||
setFlag(f, CF, newCarry);
|
setFlag(f, CF, newCarry);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
setFlag(f, ZF, operand);
|
setFlag(f, ZF, operand);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
@ -562,7 +523,7 @@ void EightBit::Z80::daa() {
|
||||||
|
|
||||||
f = (f & (CF | NF)) | (acc > 0x99) | ((acc ^ a) & HC);
|
f = (f & (CF | NF)) | (acc > 0x99) | ((acc ^ a) & HC);
|
||||||
|
|
||||||
adjustSZPXY(f, a);
|
adjustSZPXY<Z80>(f, a);
|
||||||
|
|
||||||
acc = a;
|
acc = a;
|
||||||
}
|
}
|
||||||
|
@ -571,14 +532,14 @@ void EightBit::Z80::cpl() {
|
||||||
auto& a = A();
|
auto& a = A();
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
a = ~a;
|
a = ~a;
|
||||||
adjustXY(f, A());
|
adjustXY<Z80>(f, A());
|
||||||
setFlag(f, HC | NF);
|
setFlag(f, HC | NF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::scf() {
|
void EightBit::Z80::scf() {
|
||||||
auto& f = F();
|
auto& f = F();
|
||||||
setFlag(f, CF);
|
setFlag(f, CF);
|
||||||
adjustXY(f, A());
|
adjustXY<Z80>(f, A());
|
||||||
clearFlag(f, HC | NF);
|
clearFlag(f, HC | NF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +549,7 @@ void EightBit::Z80::ccf() {
|
||||||
setFlag(f, HC, carry);
|
setFlag(f, HC, carry);
|
||||||
clearFlag(f, CF, carry);
|
clearFlag(f, CF, carry);
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
adjustXY(f, A());
|
adjustXY<Z80>(f, A());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::xhtl(register16_t& operand) {
|
void EightBit::Z80::xhtl(register16_t& operand) {
|
||||||
|
@ -624,7 +585,7 @@ void EightBit::Z80::blockCompare() {
|
||||||
|
|
||||||
setFlag(f, PF, --BC().word);
|
setFlag(f, PF, --BC().word);
|
||||||
|
|
||||||
adjustSZ(f, result);
|
adjustSZ<Z80>(f, result);
|
||||||
adjustHalfCarrySub(f, a, value, result);
|
adjustHalfCarrySub(f, a, value, result);
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
|
|
||||||
|
@ -760,7 +721,7 @@ void EightBit::Z80::blockOut() {
|
||||||
postDecrement(f, --B());
|
postDecrement(f, --B());
|
||||||
setFlag(f, NF, value & Bit7);
|
setFlag(f, NF, value & Bit7);
|
||||||
setFlag(f, HC | CF, (L() + value) > 0xff);
|
setFlag(f, HC | CF, (L() + value) > 0xff);
|
||||||
adjustParity(f, ((value + L()) & 7) ^ B());
|
adjustParity<Z80>(f, ((value + L()) & 7) ^ B());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::outi() {
|
void EightBit::Z80::outi() {
|
||||||
|
@ -798,7 +759,7 @@ void EightBit::Z80::rrd() {
|
||||||
auto memory = memptrReference();
|
auto memory = memptrReference();
|
||||||
m_memory.reference() = promoteNibble(a) | highNibble(memory);
|
m_memory.reference() = promoteNibble(a) | highNibble(memory);
|
||||||
a = (a & 0xf0) | lowNibble(memory);
|
a = (a & 0xf0) | lowNibble(memory);
|
||||||
adjustSZPXY(f, a);
|
adjustSZPXY<Z80>(f, a);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,7 +770,7 @@ void EightBit::Z80::rld() {
|
||||||
auto memory = memptrReference();
|
auto memory = memptrReference();
|
||||||
m_memory.reference() = promoteNibble(memory) | lowNibble(a);
|
m_memory.reference() = promoteNibble(memory) | lowNibble(a);
|
||||||
a = (a & 0xf0) | highNibble(memory);
|
a = (a & 0xf0) | highNibble(memory);
|
||||||
adjustSZPXY(f, a);
|
adjustSZPXY<Z80>(f, a);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,28 +819,28 @@ void EightBit::Z80::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:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = rlc(DISPLACED()) : rlc(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = rlc(DISPLACED()) : rlc(R(z)));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = rrc(DISPLACED()) : rrc(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = rrc(DISPLACED()) : rrc(R(z)));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = rl(DISPLACED()) : rl(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = rl(DISPLACED()) : rl(R(z)));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = rr(DISPLACED()) : rr(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = rr(DISPLACED()) : rr(R(z)));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = sla(DISPLACED()) : sla(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = sla(DISPLACED()) : sla(R(z)));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = sra(DISPLACED()) : sra(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = sra(DISPLACED()) : sra(R(z)));
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = sll(DISPLACED()) : sll(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = sll(DISPLACED()) : sll(R(z)));
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
adjustSZP(f, m_displaced ? R2(z) = srl(DISPLACED()) : srl(R(z)));
|
adjustSZP<Z80>(f, m_displaced ? R2(z) = srl(DISPLACED()) : srl(R(z)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (m_displaced) {
|
if (m_displaced) {
|
||||||
|
@ -893,16 +854,16 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) {
|
||||||
case 1: // BIT y, r[z]
|
case 1: // BIT y, r[z]
|
||||||
if (m_displaced) {
|
if (m_displaced) {
|
||||||
bit(y, DISPLACED());
|
bit(y, DISPLACED());
|
||||||
adjustXY(f, MEMPTR().high);
|
adjustXY<Z80>(f, MEMPTR().high);
|
||||||
cycles += 20;
|
cycles += 20;
|
||||||
} else {
|
} else {
|
||||||
auto operand = bit(y, R(z));
|
auto operand = bit(y, R(z));
|
||||||
cycles += 8;
|
cycles += 8;
|
||||||
if (z == 6) {
|
if (z == 6) {
|
||||||
adjustXY(f, MEMPTR().high);
|
adjustXY<Z80>(f, MEMPTR().high);
|
||||||
cycles += 4;
|
cycles += 4;
|
||||||
} else {
|
} else {
|
||||||
adjustXY(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -946,7 +907,7 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
|
||||||
readPort();
|
readPort();
|
||||||
if (y != 6) // IN r[y],(C)
|
if (y != 6) // IN r[y],(C)
|
||||||
R(y) = m_memory.DATA();
|
R(y) = m_memory.DATA();
|
||||||
adjustSZPXY(f, m_memory.DATA());
|
adjustSZPXY<Z80>(f, m_memory.DATA());
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
cycles += 12;
|
cycles += 12;
|
||||||
break;
|
break;
|
||||||
|
@ -1031,14 +992,14 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
|
||||||
break;
|
break;
|
||||||
case 2: // LD A,I
|
case 2: // LD A,I
|
||||||
A() = IV();
|
A() = IV();
|
||||||
adjustSZXY(f, A());
|
adjustSZXY<Z80>(f, A());
|
||||||
setFlag(f, PF, IFF2());
|
setFlag(f, PF, IFF2());
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
cycles += 9;
|
cycles += 9;
|
||||||
break;
|
break;
|
||||||
case 3: // LD A,R
|
case 3: // LD A,R
|
||||||
A() = REFRESH();
|
A() = REFRESH();
|
||||||
adjustSZXY(f, A());
|
adjustSZXY<Z80>(f, A());
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
setFlag(f, PF, IFF2());
|
setFlag(f, PF, IFF2());
|
||||||
cycles += 9;
|
cycles += 9;
|
||||||
|
|
|
@ -43,6 +43,49 @@ namespace EightBit {
|
||||||
static void clearFlag(uint8_t& f, int flag, uint32_t condition) { clearFlag(f, flag, condition != 0); }
|
static void clearFlag(uint8_t& f, int flag, uint32_t condition) { clearFlag(f, flag, condition != 0); }
|
||||||
static void clearFlag(uint8_t& f, int flag, bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
|
static void clearFlag(uint8_t& f, int flag, bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
template<class T> static void adjustSign(uint8_t& f, uint8_t value) {
|
||||||
|
setFlag(f, T::SF, value & T::SF);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustZero(uint8_t& f, uint8_t value) {
|
||||||
|
clearFlag(f, T::ZF, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustParity(uint8_t& f, uint8_t value) {
|
||||||
|
static const uint8_t lookup[0x10] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
||||||
|
auto set = lookup[highNibble(value)] + lookup[lowNibble(value)];
|
||||||
|
clearFlag(f, T::PF, set % 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustSZ(uint8_t& f, uint8_t value) {
|
||||||
|
adjustSign<T>(f, value);
|
||||||
|
adjustZero<T>(f, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustSZP(uint8_t& f, uint8_t value) {
|
||||||
|
adjustSZ<T>(f, value);
|
||||||
|
adjustParity<T>(f, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustXY(uint8_t& f, uint8_t value) {
|
||||||
|
setFlag(f, T::XF, value & T::XF);
|
||||||
|
setFlag(f, T::YF, value & T::YF);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustSZPXY(uint8_t& f, uint8_t value) {
|
||||||
|
adjustSZP<T>(f, value);
|
||||||
|
adjustXY<T>(f, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static void adjustSZXY(uint8_t& f, uint8_t value) {
|
||||||
|
adjustSZ<T>(f, value);
|
||||||
|
adjustXY<T>(f, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
static int buildHalfCarryIndex(uint8_t before, uint8_t value, int calculation) {
|
static int buildHalfCarryIndex(uint8_t before, uint8_t value, int calculation) {
|
||||||
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user