mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-09-29 15:56:19 +00:00
Start refactoring CPU cores to use C++17/14 features. (This commit covers the 6502 and Z80)
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
62f3cd717b
commit
fac2da9ac4
@ -63,10 +63,10 @@ namespace EightBit {
|
|||||||
|
|
||||||
void interrupt(uint8_t vector);
|
void interrupt(uint8_t vector);
|
||||||
|
|
||||||
void adjustZero(uint8_t datum) { clearFlag(P(), ZF, datum); }
|
void adjustZero(const uint8_t datum) { clearFlag(P(), ZF, datum); }
|
||||||
void adjustNegative(uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
void adjustNegative(const uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
||||||
|
|
||||||
void adjustNZ(uint8_t datum) {
|
void adjustNZ(const uint8_t datum) {
|
||||||
adjustZero(datum);
|
adjustZero(datum);
|
||||||
adjustNegative(datum);
|
adjustNegative(datum);
|
||||||
}
|
}
|
||||||
@ -76,19 +76,19 @@ namespace EightBit {
|
|||||||
|
|
||||||
// Address resolution
|
// Address resolution
|
||||||
|
|
||||||
register16_t Address_Absolute() {
|
auto Address_Absolute() {
|
||||||
return fetchWord();
|
return fetchWord();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Address_ZeroPage() {
|
auto Address_ZeroPage() {
|
||||||
return fetchByte();
|
return fetchByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t Address_ZeroPageIndirect() {
|
auto Address_ZeroPageIndirect() {
|
||||||
return getWordPaged(0, Address_ZeroPage());
|
return getWordPaged(0, Address_ZeroPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t Address_Indirect() {
|
auto Address_Indirect() {
|
||||||
const auto address = Address_Absolute();
|
const auto address = Address_Absolute();
|
||||||
return getWordPaged(address.high, address.low);
|
return getWordPaged(address.high, address.low);
|
||||||
}
|
}
|
||||||
@ -101,110 +101,113 @@ namespace EightBit {
|
|||||||
return Address_ZeroPage() + Y();
|
return Address_ZeroPage() + Y();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<register16_t, bool> Address_AbsoluteX() {
|
auto Address_AbsoluteX() {
|
||||||
auto address = Address_Absolute();
|
auto address = Address_Absolute();
|
||||||
const auto page = address.high;
|
const auto page = address.high;
|
||||||
address += X();
|
address += X();
|
||||||
return std::tuple<register16_t, bool>(address, address.high != page);
|
return std::make_pair(address, address.high != page);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<register16_t, bool> Address_AbsoluteY() {
|
auto Address_AbsoluteY() {
|
||||||
auto address = Address_Absolute();
|
auto address = Address_Absolute();
|
||||||
const auto page = address.high;
|
const auto page = address.high;
|
||||||
address += Y();
|
address += Y();
|
||||||
return std::tuple<register16_t, bool>(address, address.high != page);
|
return std::make_pair(address, address.high != page);
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t Address_IndexedIndirectX() {
|
auto Address_IndexedIndirectX() {
|
||||||
return getWordPaged(0, Address_ZeroPageX());
|
return getWordPaged(0, Address_ZeroPageX());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<register16_t, bool> Address_IndirectIndexedY() {
|
auto Address_IndirectIndexedY() {
|
||||||
auto address = Address_ZeroPageIndirect();
|
auto address = Address_ZeroPageIndirect();
|
||||||
const auto page = address.high;
|
const auto page = address.high;
|
||||||
address += Y();
|
address += Y();
|
||||||
return std::tuple<register16_t, bool>(address, address.high != page);
|
return std::make_pair(address, address.high != page);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addressing modes, read
|
// Addressing modes, read
|
||||||
|
|
||||||
uint8_t AM_Immediate() {
|
auto AM_Immediate() {
|
||||||
return fetchByte();
|
return fetchByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_Absolute() {
|
auto AM_Absolute() {
|
||||||
return BUS().read(Address_Absolute());
|
return BUS().read(Address_Absolute());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPage() {
|
auto AM_ZeroPage() {
|
||||||
return BUS().read(Address_ZeroPage());
|
return BUS().read(Address_ZeroPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_AbsoluteX() {
|
auto AM_AbsoluteX() {
|
||||||
const auto ap = Address_AbsoluteX();
|
const auto [address, paged] = Address_AbsoluteX();
|
||||||
if (UNLIKELY(std::get<1>(ap)))
|
if (UNLIKELY(paged))
|
||||||
addCycle();
|
addCycle();
|
||||||
return BUS().read(std::get<0>(ap));
|
return BUS().read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_AbsoluteY() {
|
auto AM_AbsoluteY() {
|
||||||
const auto ap = Address_AbsoluteY();
|
const auto [address, paged] = Address_AbsoluteY();
|
||||||
if (UNLIKELY(std::get<1>(ap)))
|
if (UNLIKELY(paged))
|
||||||
addCycle();
|
addCycle();
|
||||||
return BUS().read(std::get<0>(ap));
|
return BUS().read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPageX() {
|
auto AM_ZeroPageX() {
|
||||||
return BUS().read(Address_ZeroPageX());
|
return BUS().read(Address_ZeroPageX());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPageY() {
|
auto AM_ZeroPageY() {
|
||||||
return BUS().read(Address_ZeroPageY());
|
return BUS().read(Address_ZeroPageY());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_IndexedIndirectX() {
|
auto AM_IndexedIndirectX() {
|
||||||
return BUS().read(Address_IndexedIndirectX());
|
return BUS().read(Address_IndexedIndirectX());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_IndirectIndexedY() {
|
auto AM_IndirectIndexedY() {
|
||||||
const auto ap = Address_IndirectIndexedY();
|
const auto [address, paged] = Address_IndirectIndexedY();
|
||||||
if (UNLIKELY(std::get<1>(ap)))
|
if (UNLIKELY(paged))
|
||||||
addCycle();
|
addCycle();
|
||||||
return BUS().read(std::get<0>(ap));
|
return BUS().read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addressing modes, write
|
// Addressing modes, write
|
||||||
|
|
||||||
void AM_Absolute(uint8_t value) {
|
void AM_Absolute(const uint8_t value) {
|
||||||
BUS().write(Address_Absolute(), value);
|
BUS().write(Address_Absolute(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPage(uint8_t value) {
|
void AM_ZeroPage(const uint8_t value) {
|
||||||
BUS().write(Address_ZeroPage(), value);
|
BUS().write(Address_ZeroPage(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_AbsoluteX(uint8_t value) {
|
void AM_AbsoluteX(const uint8_t value) {
|
||||||
BUS().write(std::get<0>(Address_AbsoluteX()), value);
|
const auto [address, paged] = Address_AbsoluteX();
|
||||||
|
BUS().write(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_AbsoluteY(uint8_t value) {
|
void AM_AbsoluteY(const uint8_t value) {
|
||||||
BUS().write(std::get<0>(Address_AbsoluteY()), value);
|
const auto [address, paged] = Address_AbsoluteY();
|
||||||
|
BUS().write(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPageX(uint8_t value) {
|
void AM_ZeroPageX(const uint8_t value) {
|
||||||
BUS().write(Address_ZeroPageX(), value);
|
BUS().write(Address_ZeroPageX(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPageY(uint8_t value) {
|
void AM_ZeroPageY(const uint8_t value) {
|
||||||
BUS().write(Address_ZeroPageY(), value);
|
BUS().write(Address_ZeroPageY(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_IndexedIndirectX(uint8_t value) {
|
void AM_IndexedIndirectX(const uint8_t value) {
|
||||||
BUS().write(Address_IndexedIndirectX(), value);
|
BUS().write(Address_IndexedIndirectX(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_IndirectIndexedY(uint8_t value) {
|
void AM_IndirectIndexedY(const uint8_t value) {
|
||||||
BUS().write(std::get<0>(Address_IndirectIndexedY()), value);
|
const auto [address, paged] = Address_IndirectIndexedY();
|
||||||
|
BUS().write(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operations
|
// Operations
|
||||||
@ -219,77 +222,77 @@ namespace EightBit {
|
|||||||
A() = SBC(A(), value);
|
A() = SBC(A(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SLO(uint8_t value) {
|
void SLO(const uint8_t value) {
|
||||||
const auto result = ASL(value);
|
const auto result = ASL(value);
|
||||||
BUS().write(result);
|
BUS().write(result);
|
||||||
ORA(result);
|
ORA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SRE(uint8_t value) {
|
void SRE(const uint8_t value) {
|
||||||
const auto result = LSR(value);
|
const auto result = LSR(value);
|
||||||
BUS().write(result);
|
BUS().write(result);
|
||||||
EORA(result);
|
EORA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RLA(uint8_t value) {
|
void RLA(const uint8_t value) {
|
||||||
const auto result = ROL(value);
|
const auto result = ROL(value);
|
||||||
BUS().write(result);
|
BUS().write(result);
|
||||||
ANDA(result);
|
ANDA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RRA(uint8_t value) {
|
void RRA(const uint8_t value) {
|
||||||
const auto result = ROR(value);
|
const auto result = ROR(value);
|
||||||
BUS().write(result);
|
BUS().write(result);
|
||||||
A() = ADC(A(), result);
|
A() = ADC(A(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAX(uint8_t value) {
|
void LAX(const uint8_t value) {
|
||||||
adjustNZ(X() = A() = value);
|
adjustNZ(X() = A() = value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AAC(uint8_t value) {
|
void AAC(const uint8_t value) {
|
||||||
ANDA(value);
|
ANDA(value);
|
||||||
setFlag(P(), CF, A() & Bit7);
|
setFlag(P(), CF, A() & Bit7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASR(uint8_t value) {
|
void ASR(const uint8_t value) {
|
||||||
A() = LSR(A() & value);
|
A() = LSR(A() & value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARR(uint8_t value) {
|
void ARR(const uint8_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATX(uint8_t value) {
|
void ATX(const uint8_t value) {
|
||||||
ANDA(value);
|
ANDA(value);
|
||||||
X() = A();
|
X() = A();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXS(uint8_t value) {
|
void AXS(const uint8_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
uint8_t DEC(uint8_t value) {
|
auto DEC(uint8_t value) {
|
||||||
const auto result = --value;
|
const auto result = --value;
|
||||||
adjustNZ(result);
|
adjustNZ(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t INC(uint8_t value) {
|
auto INC(uint8_t value) {
|
||||||
const auto result = ++value;
|
const auto result = ++value;
|
||||||
adjustNZ(result);
|
adjustNZ(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ORA(uint8_t value) {
|
void ORA(const uint8_t value) {
|
||||||
adjustNZ(A() |= value);
|
adjustNZ(A() |= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ANDA(uint8_t value) {
|
void ANDA(const uint8_t value) {
|
||||||
adjustNZ(A() &= value);
|
adjustNZ(A() &= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EORA(uint8_t value) {
|
void EORA(const uint8_t value) {
|
||||||
adjustNZ(A() ^= value);
|
adjustNZ(A() ^= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ uint8_t EightBit::MOS6502::SUB_d(const uint8_t operand, const uint8_t data, cons
|
|||||||
return promoteNibble(high) | lowNibble(low);
|
return promoteNibble(high) | lowNibble(low);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::CMP(uint8_t first, uint8_t second) {
|
void EightBit::MOS6502::CMP(const uint8_t first, const uint8_t second) {
|
||||||
const register16_t result = first - second;
|
const register16_t result = first - second;
|
||||||
adjustNZ(result.low);
|
adjustNZ(result.low);
|
||||||
clearFlag(P(), CF, result.high);
|
clearFlag(P(), CF, result.high);
|
||||||
@ -487,7 +487,7 @@ uint8_t EightBit::MOS6502::ADD_d(uint8_t operand, uint8_t data, int carry) {
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
void EightBit::MOS6502::Branch(int8_t displacement) {
|
void EightBit::MOS6502::Branch(const int8_t displacement) {
|
||||||
const auto page = PC().high;
|
const auto page = PC().high;
|
||||||
PC() += displacement;
|
PC() += displacement;
|
||||||
if (UNLIKELY(PC().high != page))
|
if (UNLIKELY(PC().high != page))
|
||||||
@ -495,7 +495,7 @@ void EightBit::MOS6502::Branch(int8_t displacement) {
|
|||||||
addCycle();
|
addCycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::Branch(bool flag) {
|
void EightBit::MOS6502::Branch(const bool flag) {
|
||||||
const int8_t displacement = AM_Immediate();
|
const int8_t displacement = AM_Immediate();
|
||||||
if (UNLIKELY(flag))
|
if (UNLIKELY(flag))
|
||||||
Branch(displacement);
|
Branch(displacement);
|
||||||
|
120
Z80/inc/Z80.h
120
Z80/inc/Z80.h
@ -28,7 +28,7 @@ namespace EightBit {
|
|||||||
return (high << 7) | variable;
|
return (high << 7) | variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh_t& operator++() {
|
auto& operator++() {
|
||||||
++variable;
|
++variable;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -51,8 +51,8 @@ namespace EightBit {
|
|||||||
Signal<Z80> ExecutingInstruction;
|
Signal<Z80> ExecutingInstruction;
|
||||||
Signal<Z80> ExecutedInstruction;
|
Signal<Z80> ExecutedInstruction;
|
||||||
|
|
||||||
PinLevel& NMI() { return m_nmiLine; } // In
|
auto& NMI() { return m_nmiLine; } // In
|
||||||
PinLevel& M1() { return m_m1Line; } // Out
|
auto& M1() { return m_m1Line; } // Out
|
||||||
|
|
||||||
virtual int execute(uint8_t opcode) final;
|
virtual int execute(uint8_t opcode) final;
|
||||||
virtual int step() final;
|
virtual int step() final;
|
||||||
@ -63,19 +63,19 @@ namespace EightBit {
|
|||||||
virtual register16_t& DE() final;
|
virtual register16_t& DE() final;
|
||||||
virtual register16_t& HL() final;
|
virtual register16_t& HL() final;
|
||||||
|
|
||||||
register16_t& IX() { return m_ix; }
|
auto& IX() { return m_ix; }
|
||||||
uint8_t& IXH() { return IX().high; }
|
auto& IXH() { return IX().high; }
|
||||||
uint8_t& IXL() { return IX().low; }
|
auto& IXL() { return IX().low; }
|
||||||
|
|
||||||
register16_t& IY() { return m_iy; }
|
auto& IY() { return m_iy; }
|
||||||
uint8_t& IYH() { return IY().high; }
|
auto& IYH() { return IY().high; }
|
||||||
uint8_t& IYL() { return IY().low; }
|
auto& IYL() { return IY().low; }
|
||||||
|
|
||||||
refresh_t& REFRESH() { return m_refresh; }
|
auto& REFRESH() { return m_refresh; }
|
||||||
uint8_t& IV() { return iv; }
|
auto& IV() { return iv; }
|
||||||
int& IM() { return m_interruptMode; }
|
auto& IM() { return m_interruptMode; }
|
||||||
bool& IFF1() { return m_iff1; }
|
auto& IFF1() { return m_iff1; }
|
||||||
bool& IFF2() { return m_iff2; }
|
auto& IFF2() { return m_iff2; }
|
||||||
|
|
||||||
void exx() {
|
void exx() {
|
||||||
m_registerSet ^= 1;
|
m_registerSet ^= 1;
|
||||||
@ -132,7 +132,50 @@ namespace EightBit {
|
|||||||
m_displacement = fetchByte();
|
m_displacement = fetchByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R(const int r) {
|
auto& HL2() {
|
||||||
|
if (LIKELY(!m_displaced))
|
||||||
|
return HL();
|
||||||
|
if (m_prefixDD)
|
||||||
|
return IX();
|
||||||
|
// Must be FD prefix
|
||||||
|
return IY();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& RP(const int rp) {
|
||||||
|
ASSUME(rp >= 0);
|
||||||
|
ASSUME(rp <= 3);
|
||||||
|
switch (rp) {
|
||||||
|
case 0:
|
||||||
|
return BC();
|
||||||
|
case 1:
|
||||||
|
return DE();
|
||||||
|
case 2:
|
||||||
|
return HL2();
|
||||||
|
case 3:
|
||||||
|
return SP();
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& RP2(const int rp) {
|
||||||
|
ASSUME(rp >= 0);
|
||||||
|
ASSUME(rp <= 3);
|
||||||
|
switch (rp) {
|
||||||
|
case 0:
|
||||||
|
return BC();
|
||||||
|
case 1:
|
||||||
|
return DE();
|
||||||
|
case 2:
|
||||||
|
return HL2();
|
||||||
|
case 3:
|
||||||
|
return AF();
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto R(const int r) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@ -190,7 +233,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R2(const int r) {
|
auto R2(const int r) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@ -248,49 +291,6 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t& RP(const int rp) {
|
|
||||||
ASSUME(rp >= 0);
|
|
||||||
ASSUME(rp <= 3);
|
|
||||||
switch (rp) {
|
|
||||||
case 0:
|
|
||||||
return BC();
|
|
||||||
case 1:
|
|
||||||
return DE();
|
|
||||||
case 2:
|
|
||||||
return HL2();
|
|
||||||
case 3:
|
|
||||||
return SP();
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register16_t& HL2() {
|
|
||||||
if (LIKELY(!m_displaced))
|
|
||||||
return HL();
|
|
||||||
if (m_prefixDD)
|
|
||||||
return IX();
|
|
||||||
// Must be FD prefix
|
|
||||||
return IY();
|
|
||||||
}
|
|
||||||
|
|
||||||
register16_t& RP2(const int rp) {
|
|
||||||
ASSUME(rp >= 0);
|
|
||||||
ASSUME(rp <= 3);
|
|
||||||
switch (rp) {
|
|
||||||
case 0:
|
|
||||||
return BC();
|
|
||||||
case 1:
|
|
||||||
return DE();
|
|
||||||
case 2:
|
|
||||||
return HL2();
|
|
||||||
case 3:
|
|
||||||
return AF();
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
@ -395,7 +395,7 @@ namespace EightBit {
|
|||||||
void ind();
|
void ind();
|
||||||
bool indr();
|
bool indr();
|
||||||
|
|
||||||
void blockOut(const register16_t source, register16_t& destination);
|
void blockOut(register16_t source, register16_t& destination);
|
||||||
|
|
||||||
void outi();
|
void outi();
|
||||||
bool otir();
|
bool otir();
|
||||||
|
@ -38,15 +38,16 @@ void EightBit::Z80::powerOn() {
|
|||||||
IV() = Mask8;
|
IV() = Mask8;
|
||||||
|
|
||||||
exxAF();
|
exxAF();
|
||||||
exx();
|
AF() = Mask16;
|
||||||
|
|
||||||
IX() = IY() = AF() = BC() = DE() = HL() = Mask16;
|
exx();
|
||||||
|
IX() = IY() = BC() = DE() = HL() = Mask16;
|
||||||
|
|
||||||
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::handleRESET() {
|
void EightBit::Z80::handleRESET() {
|
||||||
Processor::handleRESET();
|
IntelProcessor::handleRESET();
|
||||||
di();
|
di();
|
||||||
addCycles(3);
|
addCycles(3);
|
||||||
}
|
}
|
||||||
@ -60,7 +61,7 @@ void EightBit::Z80::handleNMI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::handleINT() {
|
void EightBit::Z80::handleINT() {
|
||||||
Processor::handleINT();
|
IntelProcessor::handleINT();
|
||||||
raise(HALT());
|
raise(HALT());
|
||||||
if (IFF1()) {
|
if (IFF1()) {
|
||||||
di();
|
di();
|
||||||
@ -73,7 +74,7 @@ void EightBit::Z80::handleINT() {
|
|||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
call(MEMPTR() = register16_t(BUS().DATA(), IV()));
|
call(MEMPTR() = { BUS().DATA(), IV() });
|
||||||
addCycles(19);
|
addCycles(19);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -599,8 +600,7 @@ bool EightBit::Z80::otdr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::rrd() {
|
void EightBit::Z80::rrd() {
|
||||||
MEMPTR() = BUS().ADDRESS() = HL();
|
MEMPTR()++ = BUS().ADDRESS() = HL();
|
||||||
++MEMPTR();
|
|
||||||
const auto memory = BUS().read();
|
const auto memory = BUS().read();
|
||||||
BUS().write(promoteNibble(A()) | highNibble(memory));
|
BUS().write(promoteNibble(A()) | highNibble(memory));
|
||||||
A() = higherNibble(A()) | lowerNibble(memory);
|
A() = higherNibble(A()) | lowerNibble(memory);
|
||||||
@ -609,8 +609,7 @@ void EightBit::Z80::rrd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::rld() {
|
void EightBit::Z80::rld() {
|
||||||
MEMPTR() = BUS().ADDRESS() = HL();
|
MEMPTR()++ = BUS().ADDRESS() = HL();
|
||||||
++MEMPTR();
|
|
||||||
const auto memory = BUS().read();
|
const auto memory = BUS().read();
|
||||||
BUS().write(promoteNibble(memory) | lowNibble(A()));
|
BUS().write(promoteNibble(memory) | lowNibble(A()));
|
||||||
A() = higherNibble(A()) | highNibble(memory);
|
A() = higherNibble(A()) | highNibble(memory);
|
||||||
@ -619,7 +618,7 @@ void EightBit::Z80::rld() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::writePort(const uint8_t port) {
|
void EightBit::Z80::writePort(const uint8_t port) {
|
||||||
MEMPTR() = BUS().ADDRESS() = register16_t(port, A());
|
MEMPTR() = BUS().ADDRESS() = { port, A() };
|
||||||
BUS().DATA() = A();
|
BUS().DATA() = A();
|
||||||
writePort();
|
writePort();
|
||||||
++MEMPTR().low;
|
++MEMPTR().low;
|
||||||
@ -630,7 +629,7 @@ void EightBit::Z80::writePort() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::readPort(const uint8_t port) {
|
uint8_t EightBit::Z80::readPort(const uint8_t port) {
|
||||||
MEMPTR() = BUS().ADDRESS() = register16_t(port, A());
|
MEMPTR() = BUS().ADDRESS() = { port, A() };
|
||||||
++MEMPTR().low;
|
++MEMPTR().low;
|
||||||
return readPort();
|
return readPort();
|
||||||
}
|
}
|
||||||
@ -814,8 +813,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
|
|||||||
case 1:
|
case 1:
|
||||||
switch (z) {
|
switch (z) {
|
||||||
case 0: // Input from port with 16-bit address
|
case 0: // Input from port with 16-bit address
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR()++ = BUS().ADDRESS() = BC();
|
||||||
++MEMPTR();
|
|
||||||
readPort();
|
readPort();
|
||||||
if (LIKELY(y != 6)) // IN r[y],(C)
|
if (LIKELY(y != 6)) // IN r[y],(C)
|
||||||
R(y, BUS().DATA());
|
R(y, BUS().DATA());
|
||||||
@ -824,8 +822,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
|
|||||||
addCycles(12);
|
addCycles(12);
|
||||||
break;
|
break;
|
||||||
case 1: // Output to port with 16-bit address
|
case 1: // Output to port with 16-bit address
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR()++ = BUS().ADDRESS() = BC();
|
||||||
++MEMPTR();
|
|
||||||
if (UNLIKELY(y == 6)) // OUT (C),0
|
if (UNLIKELY(y == 6)) // OUT (C),0
|
||||||
BUS().DATA() = 0;
|
BUS().DATA() = 0;
|
||||||
else // OUT (C),r[y]
|
else // OUT (C),r[y]
|
||||||
@ -1105,15 +1102,13 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
|||||||
case 0:
|
case 0:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD (BC),A
|
case 0: // LD (BC),A
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR()++ = BUS().ADDRESS() = BC();
|
||||||
++MEMPTR();
|
|
||||||
MEMPTR().high = BUS().DATA() = A();
|
MEMPTR().high = BUS().DATA() = A();
|
||||||
BUS().write();
|
BUS().write();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD (DE),A
|
case 1: // LD (DE),A
|
||||||
MEMPTR() = BUS().ADDRESS() = DE();
|
MEMPTR()++ = BUS().ADDRESS() = DE();
|
||||||
++MEMPTR();
|
|
||||||
MEMPTR().high = BUS().DATA() = A();
|
MEMPTR().high = BUS().DATA() = A();
|
||||||
BUS().write();
|
BUS().write();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
@ -1124,8 +1119,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD (nn),A
|
case 3: // LD (nn),A
|
||||||
MEMPTR() = BUS().ADDRESS() = fetchWord();
|
MEMPTR()++ = BUS().ADDRESS() = fetchWord();
|
||||||
++MEMPTR();
|
|
||||||
MEMPTR().high = BUS().DATA() = A();
|
MEMPTR().high = BUS().DATA() = A();
|
||||||
BUS().write();
|
BUS().write();
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
@ -1137,14 +1131,12 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
|||||||
case 1:
|
case 1:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD A,(BC)
|
case 0: // LD A,(BC)
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR()++ = BUS().ADDRESS() = BC();
|
||||||
++MEMPTR();
|
|
||||||
A() = BUS().read();
|
A() = BUS().read();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD A,(DE)
|
case 1: // LD A,(DE)
|
||||||
MEMPTR() = BUS().ADDRESS() = DE();
|
MEMPTR()++ = BUS().ADDRESS() = DE();
|
||||||
++MEMPTR();
|
|
||||||
A() = BUS().read();
|
A() = BUS().read();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
@ -1154,8 +1146,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD A,(nn)
|
case 3: // LD A,(nn)
|
||||||
MEMPTR() = BUS().ADDRESS() = fetchWord();
|
MEMPTR()++ = BUS().ADDRESS() = fetchWord();
|
||||||
++MEMPTR();
|
|
||||||
A() = BUS().read();
|
A() = BUS().read();
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user