Tidy up register and static method access.

Signed-off-by: Adrian.Conlon <adrian.conlon@arup.com>
This commit is contained in:
Adrian.Conlon 2017-06-19 13:53:00 +01:00
parent 23108a8536
commit c9bf24d1fa
16 changed files with 181 additions and 171 deletions

View File

@ -79,39 +79,39 @@ namespace EightBit {
}
void adjustReservedFlags() {
AF().low &= ~(Bit5 | Bit3);
AF().low |= Bit1;
F() &= ~(Bit5 | Bit3);
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); }
void adjustParity(uint8_t& f, uint8_t 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);
}
void adjustSZP(uint8_t& f, uint8_t value) {
static void adjustSZP(uint8_t& f, uint8_t value) {
adjustSign(f, value);
adjustZero(f, value);
adjustParity(f, value);
}
void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t value, int calculation) {
setFlag(f, AC, calculateHalfCarryAdd(A(), value, calculation));
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, AC, calculateHalfCarryAdd(before, value, calculation));
}
void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t value, int calculation) {
clearFlag(f, AC, calculateHalfCarrySub(A(), value, calculation));
static void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
clearFlag(f, AC, calculateHalfCarrySub(before, value, calculation));
}
void postIncrement(uint8_t& f, uint8_t value) {
static void postIncrement(uint8_t& f, uint8_t value) {
adjustSZP(f, value);
clearFlag(f, AC, lowNibble(value));
}
void postDecrement(uint8_t& f, uint8_t value) {
static void postDecrement(uint8_t& f, uint8_t value) {
adjustSZP(f, value);
setFlag(f, AC, lowNibble(value) != Mask4);
}
@ -124,18 +124,20 @@ namespace EightBit {
//
void compare(uint8_t value) {
const auto& a = A();
auto& f = F();
uint16_t subtraction = A() - value;
uint16_t subtraction = a - value;
adjustSZP(f, (uint8_t)subtraction);
adjustAuxiliaryCarrySub(f, value, subtraction);
adjustAuxiliaryCarrySub(f, a, value, subtraction);
setFlag(f, CF, subtraction & Bit8);
}
void anda(uint8_t value) {
auto& a = A();
auto& f = F();
setFlag(f, AC, (A() | value) & Bit3);
setFlag(f, AC, (a | value) & Bit3);
clearFlag(f, CF);
adjustSZP(f, A() &= value);
adjustSZP(f, a &= value);
}
void ora(uint8_t value) {
@ -151,13 +153,14 @@ namespace EightBit {
}
void add(uint8_t value, int carry = 0) {
auto& a = A();
auto& f = F();
register16_t sum;
sum.word = A() + value + carry;
adjustAuxiliaryCarryAdd(f, value, sum.word);
A() = sum.low;
sum.word = a + value + carry;
adjustAuxiliaryCarryAdd(f, a, value, sum.word);
a = sum.low;
setFlag(f, CF, sum.word & Bit8);
adjustSZP(f, A());
adjustSZP(f, a);
}
void adc(uint8_t value) {
@ -172,13 +175,14 @@ namespace EightBit {
}
void sub(uint8_t value, int carry = 0) {
auto& a = A();
auto& f = F();
register16_t difference;
difference.word = A() - value - carry;
adjustAuxiliaryCarrySub(f, value, difference.word);
A() = difference.low;
difference.word = a - value - carry;
adjustAuxiliaryCarrySub(f, a, value, difference.word);
a = difference.low;
setFlag(f, CF, difference.word & Bit8);
adjustSZP(f, A());
adjustSZP(f, a);
}
void sbb(uint8_t value) {
@ -335,21 +339,21 @@ namespace EightBit {
}
void xhtl() {
auto tos = m_memory.getWord(sp.word);
m_memory.setWord(sp.word, HL());
auto tos = m_memory.getWord(SP().word);
m_memory.setWord(SP().word, HL());
HL() = tos;
}
void sphl() {
sp = HL();
SP() = HL();
}
void lxi_sp() {
Processor::fetchWord(sp);
Processor::fetchWord(SP());
}
void inx_sp() { ++sp.word; }
void dcx_sp() { --sp.word; }
void inx_sp() { ++SP().word; }
void dcx_sp() { --SP().word; }
// jump
@ -368,7 +372,7 @@ namespace EightBit {
void jp() { jumpConditional(!(F() & SF)); }
void pchl() {
pc = HL();
PC() = HL();
}
// call
@ -488,7 +492,7 @@ namespace EightBit {
void dad_b() { dad(BC().word); }
void dad_d() { dad(DE().word); }
void dad_h() { dad(HL().word); }
void dad_sp() { dad(sp.word); }
void dad_sp() { dad(SP().word); }
// subtract
@ -593,32 +597,36 @@ namespace EightBit {
// rotate
void rlc() {
auto carry = A() & Bit7;
A() <<= 1;
carry ? A() |= Bit0 : A() &= ~Bit0;
auto& a = A();
auto carry = a & Bit7;
a <<= 1;
carry ? a |= Bit0 : a &= ~Bit0;
setFlag(F(), CF, carry);
}
void rrc() {
auto carry = A() & Bit0;
A() >>= 1;
carry ? A() |= Bit7 : A() &= ~Bit7;
auto& a = A();
auto carry = a & Bit0;
a >>= 1;
carry ? a |= Bit7 : a &= ~Bit7;
setFlag(F(), CF, carry);
}
void ral() {
auto& a = A();
auto& f = F();
auto carry = A() & Bit7;
A() <<= 1;
A() |= (f & CF);
auto carry = a & Bit7;
a <<= 1;
a |= (f & CF);
setFlag(f, CF, carry);
}
void rar() {
auto& a = A();
auto& f = F();
auto carry = A() & 1;
A() >>= 1;
A() |= (f & CF) << 7;
auto carry = a & 1;
a >>= 1;
a |= (f & CF) << 7;
setFlag(f, CF, carry);
}
@ -629,13 +637,14 @@ namespace EightBit {
void cmc() { clearFlag(F(), CF, F() & CF); }
void daa() {
const auto& a = A();
auto& f = F();
auto carry = f & CF;
uint8_t addition = 0;
if ((f & AC) || lowNibble(A()) > 9) {
if ((f & AC) || lowNibble(a) > 9) {
addition = 0x6;
}
if ((f & CF) || highNibble(A()) > 9 || (highNibble(A()) >= 9 && lowNibble(A()) > 9)) {
if ((f & CF) || highNibble(a) > 9 || (highNibble(a) >= 9 && lowNibble(a) > 9)) {
addition |= 0x60;
carry = true;
}
@ -655,6 +664,6 @@ namespace EightBit {
void nop() {}
void hlt() { m_halted = true; }
void hlt() { halt(); }
};
}

View File

@ -13,8 +13,8 @@ EightBit::Disassembler::Disassembler() {
std::string EightBit::Disassembler::state(Intel8080& cpu) {
auto pc = cpu.getProgramCounter();
auto sp = cpu.getStackPointer();
auto pc = cpu.PC();
auto sp = cpu.SP();
auto a = cpu.A();
auto f = cpu.F();
@ -45,7 +45,7 @@ std::string EightBit::Disassembler::state(Intel8080& cpu) {
std::string EightBit::Disassembler::disassemble(Intel8080& cpu) {
const auto& memory = cpu.getMemory();
auto pc = cpu.getProgramCounter();
auto pc = cpu.PC();
auto opcode = memory.peek(pc.word);
const auto& instruction = cpu.getInstructions()[opcode];

View File

@ -75,7 +75,7 @@ int EightBit::Intel8080::execute(uint8_t opcode) {
//
void EightBit::Intel8080::___() {
auto opcode = m_memory.get(pc.word - 1);
auto opcode = m_memory.get(PC().word - 1);
auto message = Disassembler::invalid(opcode);
throw std::domain_error(message);
}

View File

@ -33,11 +33,11 @@ void Board::initialise() {
}
m_cpu.initialise();
m_cpu.setProgramCounter(m_configuration.getStartAddress());
m_cpu.PC() = m_configuration.getStartAddress();
}
void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080&) {
auto pc = m_cpu.getProgramCounter();
auto pc = m_cpu.PC();
switch (pc.word) {
case 0x0: // CP/M warm start
m_cpu.halt();
@ -69,7 +69,7 @@ void Board::bdos() {
void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Intel8080& cpu) {
const auto pc = cpu.getProgramCounter();
const auto pc = m_cpu.PC();
m_profiler.addAddress(pc.word);
m_profiler.addInstruction(m_memory.peek(pc.word));

View File

@ -98,7 +98,7 @@ namespace EightBit {
register16_t& RP(int rp) {
switch (rp) {
case 3:
return sp;
return SP();
default:
return m_registers[rp];
}
@ -113,21 +113,21 @@ namespace EightBit {
}
}
void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
static void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
}
void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
static void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
}
void executeCB(int x, int y, int z, int p, int q);
void executeOther(int x, int y, int z, int p, int q);
void adjustZero(uint8_t& f, uint8_t value);
static void adjustZero(uint8_t& f, uint8_t value);
void postIncrement(uint8_t& f, uint8_t value);
void postDecrement(uint8_t& f, uint8_t value);
static void postIncrement(uint8_t& f, uint8_t value);
static void postDecrement(uint8_t& f, uint8_t value);
void reti();

View File

@ -16,8 +16,8 @@ EightBit::Disassembler::Disassembler() {
std::string EightBit::Disassembler::state(EightBit::LR35902& cpu) {
auto pc = cpu.getProgramCounter();
auto sp = cpu.getStackPointer();
auto pc = cpu.PC();
auto sp = cpu.SP();
auto a = cpu.A();
auto f = cpu.F();
@ -142,7 +142,7 @@ std::string EightBit::Disassembler::alu(int which) {
std::string EightBit::Disassembler::disassemble(LR35902& cpu) {
m_prefixCB = false;
std::ostringstream output;
disassemble(output, cpu, cpu.getProgramCounter().word);
disassemble(output, cpu, cpu.PC().word);
return output.str();
}

View File

@ -12,7 +12,7 @@ EightBit::LR35902::LR35902(Bus& memory)
void EightBit::LR35902::reset() {
IntelProcessor::reset();
sp.word = 0xfffe;
SP().word = 0xfffe;
di();
}
@ -503,7 +503,7 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
break;
case 1: // GB: LD (nn),SP
fetchWord();
m_memory.setWord(MEMPTR().word, sp);
m_memory.setWord(MEMPTR().word, SP());
cycles += 5;
break;
case 2: // GB: STOP
@ -703,12 +703,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
break;
case 5: { // GB: ADD SP,dd
auto& f = F();
auto before = sp;
auto before = SP();
auto value = fetchByte();
sp.word += (int8_t)value;
auto result = SP().word + (int8_t)value;
SP().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, sp.word & Bit16);
adjustHalfCarryAdd(f, before.high, value, sp.high);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, SP().high);
}
cycles += 4;
break;
@ -718,11 +719,12 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
break;
case 7: { // GB: LD HL,SP + dd
auto& f = F();
auto before = sp;
auto before = HL();
auto value = fetchByte();
HL().word = before.word + (int8_t)value;
auto result = SP().word + (int8_t)value;
HL().word = result;
clearFlag(f, ZF | NF);
setFlag(f, CF, HL().word & Bit16);
setFlag(f, CF, result & Bit16);
adjustHalfCarryAdd(f, before.high, value, HL().high);
}
cycles += 3;
@ -747,11 +749,11 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
cycles += 4;
break;
case 2: // JP HL
pc = HL();
PC() = HL();
cycles += 1;
break;
case 3: // LD SP,HL
sp = HL();
SP() = HL();
cycles += 2;
break;
}

View File

@ -39,8 +39,8 @@ void Fuse::TestRunner::initialiseRegisters() {
m_cpu.IX() = inputRegisters[Fuse::RegisterState::IX];
m_cpu.IY() = inputRegisters[Fuse::RegisterState::IY];
m_cpu.setStackPointer(inputRegisters[Fuse::RegisterState::SP]);
m_cpu.setProgramCounter(inputRegisters[Fuse::RegisterState::PC]);
m_cpu.SP() = inputRegisters[Fuse::RegisterState::SP];
m_cpu.PC() = inputRegisters[Fuse::RegisterState::PC];
m_cpu.MEMPTR() = inputRegisters[Fuse::RegisterState::MEMPTR];
@ -115,8 +115,8 @@ void Fuse::TestRunner::checkregisters() {
auto ix = m_cpu.IX().word == expectedRegisters[Fuse::RegisterState::IX].word;
auto iy = m_cpu.IY().word == expectedRegisters[Fuse::RegisterState::IY].word;
auto sp = m_cpu.getStackPointer().word == expectedRegisters[Fuse::RegisterState::SP].word;
auto pc = m_cpu.getProgramCounter().word == expectedRegisters[Fuse::RegisterState::PC].word;
auto sp = m_cpu.SP().word == expectedRegisters[Fuse::RegisterState::SP].word;
auto pc = m_cpu.PC().word == expectedRegisters[Fuse::RegisterState::PC].word;
auto memptr = m_cpu.MEMPTR().word == expectedRegisters[Fuse::RegisterState::MEMPTR].word;
@ -194,13 +194,13 @@ void Fuse::TestRunner::checkregisters() {
if (!sp) {
auto expectedWord = expectedRegisters[Fuse::RegisterState::SP];
auto actualWord = m_cpu.getStackPointer();
auto actualWord = m_cpu.SP();
dumpDifference("SPH", "SPL", actualWord, expectedWord);
}
if (!pc) {
auto expectedWord = expectedRegisters[Fuse::RegisterState::PC];
auto actualWord = m_cpu.getProgramCounter();
auto actualWord = m_cpu.PC();
dumpDifference("PCH", "PCL", actualWord, expectedWord);
}

View File

@ -12,7 +12,7 @@ namespace EightBit {
Disassembler();
static std::string state(Z80& cpu);
std::string disassemble(const Z80& cpu);
std::string disassemble(Z80& cpu);
static std::string flag(uint8_t value, int flag, const std::string& represents);
static std::string flags(uint8_t value);

View File

@ -37,8 +37,6 @@ namespace EightBit {
int execute(uint8_t opcode);
int step();
bool getM1() const { return m1; }
// Mutable access to processor!!
virtual register16_t& AF() override {
@ -181,7 +179,7 @@ namespace EightBit {
register16_t& RP(int rp) {
switch (rp) {
case 3:
return sp;
return SP();
case HL_IDX:
return HL2();
default:
@ -225,28 +223,28 @@ namespace EightBit {
adc(hl, operand);
}
void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
static void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
}
void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
static void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
}
void adjustOverflowAdd(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
static void adjustOverflowAdd(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
adjustOverflowAdd(f, before & SF, value & SF, calculation & SF);
}
void adjustOverflowAdd(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
static void adjustOverflowAdd(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
setFlag(f, VF, overflow);
}
void adjustOverflowSub(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
static void adjustOverflowSub(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
adjustOverflowSub(f, before & SF, value & SF, calculation & SF);
}
void adjustOverflowSub(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
static void adjustOverflowSub(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
setFlag(f, VF, overflow);
}
@ -298,9 +296,9 @@ namespace EightBit {
uint8_t& sll(uint8_t& operand);
uint8_t& srl(uint8_t& operand);
void bit(int n, uint8_t& operand);
void res(int n, uint8_t& operand);
void set(int nit, uint8_t& operand);
uint8_t& bit(int n, uint8_t& operand);
uint8_t& res(int n, uint8_t& operand);
uint8_t& set(int nit, uint8_t& operand);
void daa();

View File

@ -15,8 +15,8 @@ EightBit::Disassembler::Disassembler() {
std::string EightBit::Disassembler::state(Z80& cpu) {
auto pc = cpu.getProgramCounter();
auto sp = cpu.getStackPointer();
auto pc = cpu.PC();
auto sp = cpu.SP();
auto a = cpu.A();
auto f = cpu.F();
@ -169,10 +169,10 @@ std::string EightBit::Disassembler::alu(int which) {
throw std::logic_error("Unhandled alu operation");
}
std::string EightBit::Disassembler::disassemble(const Z80& cpu) {
std::string EightBit::Disassembler::disassemble(Z80& cpu) {
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
std::ostringstream output;
disassemble(output, cpu, cpu.getProgramCounter().word);
disassemble(output, cpu, cpu.PC().word);
return output.str();
}

View File

@ -86,9 +86,9 @@ int EightBit::Z80::interrupt(bool maskable, uint8_t value) {
cycles += 13;
break;
case 2:
pushWord(pc);
pc.low = value;
pc.high = IV();
pushWord(PC());
PC().low = value;
PC().high = IV();
cycles += 19;
break;
}
@ -502,23 +502,26 @@ uint8_t& EightBit::Z80::srl(uint8_t& operand) {
#pragma region BIT/SET/RES
void EightBit::Z80::bit(int n, uint8_t& operand) {
uint8_t& EightBit::Z80::bit(int n, uint8_t& operand) {
auto& f = F();
auto carry = f & CF;
uint8_t discarded = operand;
andr(discarded, 1 << n);
clearFlag(f, PF, discarded);
setFlag(f, CF, carry);
return operand;
}
void EightBit::Z80::res(int n, uint8_t& operand) {
uint8_t& EightBit::Z80::res(int n, uint8_t& operand) {
auto bit = 1 << n;
operand &= ~bit;
return operand;
}
void EightBit::Z80::set(int n, uint8_t& operand) {
uint8_t& EightBit::Z80::set(int n, uint8_t& operand) {
auto bit = 1 << n;
operand |= bit;
return operand;
}
#pragma endregion BIT/SET/RES
@ -526,22 +529,24 @@ void EightBit::Z80::set(int n, uint8_t& operand) {
#pragma region Miscellaneous instructions
void EightBit::Z80::neg() {
auto& a = A();
auto& f = F();
auto original = A();
A() = 0;
sub(A(), original);
auto original = a;
a = 0;
sub(a, original);
setFlag(f, PF, original == Bit7);
setFlag(f, CF, original);
}
void EightBit::Z80::daa() {
auto& acc = A();
auto& f = F();
uint8_t a = A();
auto a = acc;
auto lowAdjust = (f & HC) | (lowNibble(A()) > 9);
auto highAdjust = (f & CF) | (A() > 0x99);
auto lowAdjust = (f & HC) | (lowNibble(acc) > 9);
auto highAdjust = (f & CF) | (acc > 0x99);
if (f & NF) {
if (lowAdjust)
@ -555,16 +560,17 @@ void EightBit::Z80::daa() {
a += 0x60;
}
f = (f & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC);
f = (f & (CF | NF)) | (acc > 0x99) | ((acc ^ a) & HC);
adjustSZPXY(f, a);
A() = a;
acc = a;
}
void EightBit::Z80::cpl() {
auto& a = A();
auto& f = F();
A() = ~A();
a = ~a;
adjustXY(f, A());
setFlag(f, HC | NF);
}
@ -586,7 +592,7 @@ void EightBit::Z80::ccf() {
}
void EightBit::Z80::xhtl(register16_t& operand) {
m_memory.ADDRESS() = sp;
m_memory.ADDRESS() = SP();
MEMPTR().low = m_memory.reference();
m_memory.reference() = operand.low;
operand.low = MEMPTR().low;
@ -608,17 +614,18 @@ void EightBit::Z80::xhtl() {
void EightBit::Z80::blockCompare() {
const auto& a = A();
auto& f = F();
m_memory.ADDRESS() = HL();
auto value = m_memory.reference();
uint8_t result = A() - value;
uint8_t result = a - value;
setFlag(f, PF, --BC().word);
adjustSZ(f, result);
adjustHalfCarrySub(f, A(), value, result);
adjustHalfCarrySub(f, a, value, result);
setFlag(f, NF);
if (f & HC)
@ -642,7 +649,7 @@ void EightBit::Z80::cpd() {
bool EightBit::Z80::cpir() {
cpi();
MEMPTR().word = pc.word;
MEMPTR() = PC();
auto again = (F() & PF) && !(F() & ZF); // See CPI
if (again)
MEMPTR().word--;
@ -651,7 +658,7 @@ bool EightBit::Z80::cpir() {
bool EightBit::Z80::cpdr() {
cpd();
MEMPTR().word = pc.word - 1;
MEMPTR().word = PC().word - 1;
auto again = (F() & PF) && !(F() & ZF); // See CPD
if (!again)
MEMPTR().word--;
@ -691,7 +698,7 @@ bool EightBit::Z80::ldir() {
ldi();
auto again = (F() & PF) != 0;
if (again) // See LDI
MEMPTR().word = pc.word - 1;
MEMPTR().word = PC().word - 1;
return again;
}
@ -699,7 +706,7 @@ bool EightBit::Z80::lddr() {
ldd();
auto again = (F() & PF) != 0;
if (again) // See LDR
MEMPTR().word = pc.word - 1;
MEMPTR().word = PC().word - 1;
return again;
}
@ -785,22 +792,24 @@ bool EightBit::Z80::otdr() {
#pragma region Nibble rotation
void EightBit::Z80::rrd() {
auto& a = A();
auto& f = F();
MEMPTR() = HL();
auto memory = memptrReference();
m_memory.reference() = promoteNibble(A()) | highNibble(memory);
A() = (A() & 0xf0) | lowNibble(memory);
m_memory.reference() = promoteNibble(a) | highNibble(memory);
a = (a & 0xf0) | lowNibble(memory);
adjustSZPXY(f, A());
clearFlag(f, NF | HC);
}
void EightBit::Z80::rld() {
auto& a = A();
auto& f = F();
MEMPTR() = HL();
auto memory = memptrReference();
m_memory.reference() = promoteNibble(memory) | lowNibble(A());
A() = (A() & 0xf0) | highNibble(memory);
adjustSZPXY(f, A());
m_memory.reference() = promoteNibble(memory) | lowNibble(a);
a = (a & 0xf0) | highNibble(memory);
adjustSZPXY(f, a);
clearFlag(f, NF | HC);
}
@ -815,7 +824,7 @@ int EightBit::Z80::step() {
int EightBit::Z80::execute(uint8_t opcode) {
if (!getM1())
if (!M1())
throw std::logic_error("M1 cannot be high");
auto x = (opcode & 0b11000000) >> 6;
@ -887,8 +896,7 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) {
adjustXY(f, MEMPTR().high);
cycles += 20;
} else {
auto operand = R(z);
bit(y, operand);
auto operand = bit(y, R(z));
cycles += 8;
if (z == 6) {
adjustXY(f, MEMPTR().high);
@ -900,8 +908,7 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) {
break;
case 2: // RES y, r[z]
if (m_displaced) {
res(y, DISPLACED());
R2(z) = DISPLACED();
R2(z) = res(y, DISPLACED());
cycles += 23;
} else {
res(y, R(z));
@ -912,8 +919,7 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) {
break;
case 3: // SET y, r[z]
if (m_displaced) {
set(y, DISPLACED());
R2(z) = DISPLACED();
R2(z) = set(y, DISPLACED());
cycles += 23;
} else {
set(y, R(z));
@ -1065,13 +1071,13 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
break;
case 6: // LDIR
if (ldir()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
case 7: // LDDR
if (lddr()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
@ -1087,13 +1093,13 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
break;
case 6: // CPIR
if (cpir()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
case 7: // CPDR
if (cpdr()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
@ -1109,13 +1115,13 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
break;
case 6: // INIR
if (inir()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
case 7: // INDR
if (indr()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
@ -1131,13 +1137,13 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) {
break;
case 6: // OTIR
if (otir()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
case 7: // OTDR
if (otdr()) {
pc.word -= 2;
PC().word -= 2;
cycles += 5;
}
break;
@ -1394,11 +1400,11 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) {
cycles += 4;
break;
case 2: // JP HL
pc = HL2();
PC() = HL2();
cycles += 4;
break;
case 3: // LD SP,HL
sp = HL2();
SP() = HL2();
cycles += 4;
break;
}

View File

@ -32,11 +32,11 @@ void Board::initialise() {
}
m_cpu.initialise();
m_cpu.setProgramCounter(m_configuration.getStartAddress());
m_cpu.PC() = m_configuration.getStartAddress();
}
void Board::Cpu_ExecutingInstruction_Cpm(const EightBit::Z80&) {
auto pc = m_cpu.getProgramCounter();
auto pc = m_cpu.PC();
switch (pc.word) {
case 0x0: // CP/M warm start
m_cpu.halt();
@ -68,7 +68,7 @@ void Board::bdos() {
void Board::Cpu_ExecutingInstruction_Profile(const EightBit::Z80& cpu) {
const auto pc = cpu.getProgramCounter();
const auto pc = m_cpu.PC();
m_profiler.addAddress(pc.word);
m_profiler.addInstruction(m_memory.peek(pc.word));
@ -79,6 +79,6 @@ void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Z80& cpu) {
std::cerr
<< EightBit::Disassembler::state(m_cpu)
<< "\t"
<< m_disassembler.disassemble(cpu)
<< m_disassembler.disassemble(m_cpu)
<< '\n';
}

View File

@ -40,25 +40,24 @@ 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, bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
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);
}
bool calculateHalfCarryAdd(uint8_t before, uint8_t value, int calculation) {
static bool calculateHalfCarryAdd(uint8_t before, uint8_t value, int calculation) {
static std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
auto index = buildHalfCarryIndex(before, value, calculation);
return m_halfCarryTableAdd[index & Mask3];
}
bool calculateHalfCarrySub(uint8_t before, uint8_t value, int calculation) {
static bool calculateHalfCarrySub(uint8_t before, uint8_t value, int calculation) {
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
auto index = buildHalfCarryIndex(before, value, calculation);
return m_halfCarryTableSub[index & Mask3];
}
void push(uint8_t value) {
m_memory.ADDRESS().word = --sp.word;
m_memory.ADDRESS().word = --SP().word;
m_memory.reference() = value;
}
@ -68,7 +67,7 @@ namespace EightBit {
}
uint8_t pop() {
m_memory.ADDRESS().word = sp.word++;
m_memory.ADDRESS().word = SP().word++;
return m_memory.reference();
}
@ -104,11 +103,11 @@ namespace EightBit {
//
void jump() {
pc = MEMPTR();
PC() = MEMPTR();
}
void call() {
pushWord(pc);
pushWord(PC());
jump();
}
@ -144,7 +143,7 @@ namespace EightBit {
}
void jr(int8_t offset) {
MEMPTR().word = pc.word + offset;
MEMPTR().word = PC().word + offset;
jump();
}

View File

@ -46,14 +46,11 @@ namespace EightBit {
const Memory& getMemory() const { return m_memory; }
register16_t getProgramCounter() const { return pc; }
void setProgramCounter(register16_t value) { pc = value; }
register16_t getStackPointer() const { return sp; }
void setStackPointer(register16_t value) { sp = value; }
register16_t& PC() { return pc; }
register16_t& SP() { return sp; }
bool isHalted() const { return m_halted; }
void halt() { --pc.word; m_halted = true; }
void halt() { --PC().word; m_halted = true; }
virtual void initialise();
@ -63,16 +60,10 @@ namespace EightBit {
Processor(Memory& memory);
Memory& m_memory;
int cycles;
register16_t pc;
register16_t sp;
bool m_halted;
uint8_t fetchByte() {
m_memory.ADDRESS().word = pc.word++;
m_memory.ADDRESS().word = PC().word++;
return m_memory.reference();
}
@ -80,5 +71,10 @@ namespace EightBit {
output.low = fetchByte();
output.high = fetchByte();
}
private:
register16_t pc;
register16_t sp;
bool m_halted;
};
}

View File

@ -5,15 +5,15 @@ EightBit::Processor::Processor(Memory& memory)
: m_memory(memory),
cycles(0),
m_halted(false) {
sp.word = 0xffff;
pc.word = 0;
SP().word = 0xffff;
PC().word = 0;
}
void EightBit::Processor::reset() {
pc.word = 0;
PC().word = 0;
}
void EightBit::Processor::initialise() {
sp.word = 0xffff;
SP().word = 0xffff;
reset();
}