MEMPTR is really only a concept of Intel style processors.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-03-18 22:40:23 +00:00
parent 97a121b8d4
commit d818095815
7 changed files with 93 additions and 108 deletions

View File

@ -529,8 +529,7 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
case 3: // Assorted operations case 3: // Assorted operations
switch (y) { switch (y) {
case 0: // JP nn case 0: // JP nn
MEMPTR() = fetchWord(); jump(MEMPTR() = fetchWord());
jump();
addCycles(10); addCycles(10);
break; break;
case 2: // OUT (n),A case 2: // OUT (n),A
@ -573,8 +572,7 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
case 1: case 1:
switch (p) { switch (p) {
case 0: // CALL nn case 0: // CALL nn
MEMPTR() = fetchWord(); call(MEMPTR() = fetchWord());
call();
addCycles(17); addCycles(17);
break; break;
} }

View File

@ -74,59 +74,54 @@ namespace EightBit {
// Address resolution // Address resolution
void Address_Absolute() { register16_t Address_Absolute() {
MEMPTR() = fetchWord(); return fetchWord();
} }
void Address_ZeroPage() { uint8_t Address_ZeroPage() {
MEMPTR().low = fetchByte(); return fetchByte();
MEMPTR().high = 0;
} }
void Address_ZeroPageIndirect() { register16_t Address_ZeroPageIndirect() {
Address_ZeroPage(); return getWordPaged(0, Address_ZeroPage());
MEMPTR() = getWordPaged(0, MEMPTR().low);
} }
void Address_Indirect() { register16_t Address_Indirect() {
Address_Absolute(); const auto address = Address_Absolute();
MEMPTR() = getWordPaged(MEMPTR().high, MEMPTR().low); return getWordPaged(address.high, address.low);
} }
void Address_ZeroPageX() { uint8_t Address_ZeroPageX() {
Address_ZeroPage(); return Address_ZeroPage() + X();
MEMPTR().low += X();
} }
void Address_ZeroPageY() { uint8_t Address_ZeroPageY() {
Address_ZeroPage(); return Address_ZeroPage() + Y();
MEMPTR().low += Y();
} }
bool Address_AbsoluteX() { std::tuple<register16_t, bool> Address_AbsoluteX() {
Address_Absolute(); auto address = Address_Absolute();
const auto page = MEMPTR().high; const auto page = address.high;
MEMPTR().word += X(); address.word += X();
return MEMPTR().high != page; return std::tuple<register16_t, bool>(address, address.high != page);
} }
bool Address_AbsoluteY() { std::tuple<register16_t, bool> Address_AbsoluteY() {
Address_Absolute(); auto address = Address_Absolute();
const auto page = MEMPTR().high; const auto page = address.high;
MEMPTR().word += Y(); address.word += Y();
return MEMPTR().high != page; return std::tuple<register16_t, bool>(address, address.high != page);
} }
void Address_IndexedIndirectX() { register16_t Address_IndexedIndirectX() {
Address_ZeroPageX(); return getWordPaged(0, Address_ZeroPageX());
MEMPTR() = getWordPaged(0, MEMPTR().low);
} }
bool Address_IndirectIndexedY() { std::tuple<register16_t, bool> Address_IndirectIndexedY() {
Address_ZeroPageIndirect(); auto address = Address_ZeroPageIndirect();
const auto page = MEMPTR().high; const auto page = address.high;
MEMPTR().word += Y(); address.word += Y();
return MEMPTR().high != page; return std::tuple<register16_t, bool>(address, address.high != page);
} }
// Addressing modes, read // Addressing modes, read
@ -136,88 +131,78 @@ namespace EightBit {
} }
uint8_t AM_Absolute() { uint8_t AM_Absolute() {
Address_Absolute(); return BUS().read(Address_Absolute());
return BUS().read(MEMPTR());
} }
uint8_t AM_ZeroPage() { uint8_t AM_ZeroPage() {
Address_ZeroPage(); return BUS().read(Address_ZeroPage());
return BUS().read(MEMPTR());
} }
uint8_t AM_AbsoluteX() { uint8_t AM_AbsoluteX() {
if (UNLIKELY(Address_AbsoluteX())) const auto ap = Address_AbsoluteX();
if (UNLIKELY(std::get<1>(ap)))
addCycle(); addCycle();
return BUS().read(MEMPTR()); return BUS().read(std::get<0>(ap));
} }
uint8_t AM_AbsoluteY() { uint8_t AM_AbsoluteY() {
if (UNLIKELY(Address_AbsoluteY())) const auto ap = Address_AbsoluteY();
if (UNLIKELY(std::get<1>(ap)))
addCycle(); addCycle();
return BUS().read(MEMPTR()); return BUS().read(std::get<0>(ap));
} }
uint8_t AM_ZeroPageX() { uint8_t AM_ZeroPageX() {
Address_ZeroPageX(); return BUS().read(Address_ZeroPageX());
return BUS().read(MEMPTR());
} }
uint8_t AM_ZeroPageY() { uint8_t AM_ZeroPageY() {
Address_ZeroPageY(); return BUS().read(Address_ZeroPageY());
return BUS().read(MEMPTR());
} }
uint8_t AM_IndexedIndirectX() { uint8_t AM_IndexedIndirectX() {
Address_IndexedIndirectX(); return BUS().read(Address_IndexedIndirectX());
return BUS().read(MEMPTR());
} }
uint8_t AM_IndirectIndexedY() { uint8_t AM_IndirectIndexedY() {
if (UNLIKELY(Address_IndirectIndexedY())) const auto ap = Address_IndirectIndexedY();
if (UNLIKELY(std::get<1>(ap)))
addCycle(); addCycle();
return BUS().read(MEMPTR()); return BUS().read(std::get<0>(ap));
} }
// Addressing modes, write // Addressing modes, write
void AM_Absolute(uint8_t value) { void AM_Absolute(uint8_t value) {
Address_Absolute(); BUS().write(Address_Absolute(), value);
BUS().write(MEMPTR(), value);
} }
void AM_ZeroPage(uint8_t value) { void AM_ZeroPage(uint8_t value) {
Address_ZeroPage(); BUS().write(Address_ZeroPage(), value);
BUS().write(MEMPTR(), value);
} }
void AM_AbsoluteX(uint8_t value) { void AM_AbsoluteX(uint8_t value) {
Address_AbsoluteX(); BUS().write(std::get<0>(Address_AbsoluteX()), value);
BUS().write(MEMPTR(), value);
} }
void AM_AbsoluteY(uint8_t value) { void AM_AbsoluteY(uint8_t value) {
Address_AbsoluteY(); BUS().write(std::get<0>(Address_AbsoluteY()), value);
BUS().write(MEMPTR(), value);
} }
void AM_ZeroPageX(uint8_t value) { void AM_ZeroPageX(uint8_t value) {
Address_ZeroPageX(); BUS().write(Address_ZeroPageX(), value);
BUS().write(MEMPTR(), value);
} }
void AM_ZeroPageY(uint8_t value) { void AM_ZeroPageY(uint8_t value) {
Address_ZeroPageY(); BUS().write(Address_ZeroPageY(), value);
BUS().write(MEMPTR(), value);
} }
void AM_IndexedIndirectX(uint8_t value) { void AM_IndexedIndirectX(uint8_t value) {
Address_IndexedIndirectX(); BUS().write(Address_IndexedIndirectX(), value);
BUS().write(MEMPTR(), value);
} }
void AM_IndirectIndexedY(uint8_t value) { void AM_IndirectIndexedY(uint8_t value) {
Address_IndirectIndexedY(); BUS().write(std::get<0>(Address_IndirectIndexedY()), value);
BUS().write(MEMPTR(), value);
} }
// Operations // Operations
@ -344,5 +329,7 @@ namespace EightBit {
uint8_t p = 0; // processor status uint8_t p = 0; // processor status
PinLevel m_soLine = Low; PinLevel m_soLine = Low;
register16_t m_intermediate = { { 0, 0 } };;
}; };
} }

View File

@ -408,7 +408,7 @@ uint8_t EightBit::MOS6502::SBC(const uint8_t operand, const uint8_t data) {
const auto returned = SUB(operand, data, ~P() & CF); const auto returned = SUB(operand, data, ~P() & CF);
const register16_t& difference = MEMPTR(); const register16_t& difference = m_intermediate;
adjustNZ(difference.low); adjustNZ(difference.low);
setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF); setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
clearFlag(P(), CF, difference.high); clearFlag(P(), CF, difference.high);
@ -421,12 +421,12 @@ uint8_t EightBit::MOS6502::SUB(const uint8_t operand, const uint8_t data, const
} }
uint8_t EightBit::MOS6502::SUB_b(const uint8_t operand, const uint8_t data, const int borrow) { uint8_t EightBit::MOS6502::SUB_b(const uint8_t operand, const uint8_t data, const int borrow) {
MEMPTR().word = operand - data - borrow; m_intermediate.word = operand - data - borrow;
return MEMPTR().low; return m_intermediate.low;
} }
uint8_t EightBit::MOS6502::SUB_d(const uint8_t operand, const uint8_t data, const int borrow) { uint8_t EightBit::MOS6502::SUB_d(const uint8_t operand, const uint8_t data, const int borrow) {
MEMPTR().word = operand - data - borrow; m_intermediate.word = operand - data - borrow;
uint8_t low = lowNibble(operand) - lowNibble(data) - borrow; uint8_t low = lowNibble(operand) - lowNibble(data) - borrow;
const auto lowNegative = low & NF; const auto lowNegative = low & NF;
@ -450,7 +450,7 @@ void EightBit::MOS6502::CMP(uint8_t first, uint8_t second) {
uint8_t EightBit::MOS6502::ADC(const uint8_t operand, const uint8_t data) { uint8_t EightBit::MOS6502::ADC(const uint8_t operand, const uint8_t data) {
const auto returned = ADD(operand, data, P() & CF); const auto returned = ADD(operand, data, P() & CF);
adjustNZ(MEMPTR().low); adjustNZ(m_intermediate.low);
return returned; return returned;
} }
@ -459,17 +459,17 @@ uint8_t EightBit::MOS6502::ADD(uint8_t operand, uint8_t data, int carry) {
} }
uint8_t EightBit::MOS6502::ADD_b(uint8_t operand, uint8_t data, int carry) { uint8_t EightBit::MOS6502::ADD_b(uint8_t operand, uint8_t data, int carry) {
MEMPTR().word = operand + data + carry; m_intermediate.word = operand + data + carry;
setFlag(P(), VF, ~(operand ^ data) & (operand ^ MEMPTR().low) & NF); setFlag(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
setFlag(P(), CF, MEMPTR().high & CF); setFlag(P(), CF, m_intermediate.high & CF);
return MEMPTR().low; return m_intermediate.low;
} }
uint8_t EightBit::MOS6502::ADD_d(uint8_t operand, uint8_t data, int carry) { uint8_t EightBit::MOS6502::ADD_d(uint8_t operand, uint8_t data, int carry) {
MEMPTR().word = operand + data + carry; m_intermediate.word = operand + data + carry;
uint8_t low = lowNibble(operand) + lowNibble(data) + carry; uint8_t low = lowNibble(operand) + lowNibble(data) + carry;
if (low > 9) if (low > 9)
@ -515,9 +515,9 @@ void EightBit::MOS6502::PLP() {
// //
void EightBit::MOS6502::JSR_abs() { void EightBit::MOS6502::JSR_abs() {
Address_Absolute(); const auto address = Address_Absolute();
--PC().word; --PC().word;
call(); call(address);
} }
void EightBit::MOS6502::RTI() { void EightBit::MOS6502::RTI() {
@ -531,13 +531,11 @@ void EightBit::MOS6502::RTS() {
} }
void EightBit::MOS6502::JMP_abs() { void EightBit::MOS6502::JMP_abs() {
Address_Absolute(); jump(Address_Absolute());
jump();
} }
void EightBit::MOS6502::JMP_ind() { void EightBit::MOS6502::JMP_ind() {
Address_Indirect(); jump(Address_Indirect());
jump();
} }
void EightBit::MOS6502::BRK() { void EightBit::MOS6502::BRK() {

View File

@ -117,6 +117,7 @@ bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
void EightBit::Z80::retn() { void EightBit::Z80::retn() {
ret(); ret();
MEMPTR() = PC();
IFF1() = IFF2(); IFF1() = IFF2();
} }
@ -685,7 +686,7 @@ int EightBit::Z80::step() {
case 2: case 2:
MEMPTR().low = BUS().DATA(); MEMPTR().low = BUS().DATA();
MEMPTR().high = IV(); MEMPTR().high = IV();
call(); call(MEMPTR());
addCycles(19); addCycles(19);
return cycles(); return cycles();
default: default:
@ -1373,6 +1374,7 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
switch (p) { switch (p) {
case 0: // RET case 0: // RET
ret(); ret();
MEMPTR() = PC();
addCycles(10); addCycles(10);
break; break;
case 1: // EXX case 1: // EXX
@ -1402,8 +1404,7 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
case 3: // Assorted operations case 3: // Assorted operations
switch (y) { switch (y) {
case 0: // JP nn case 0: // JP nn
MEMPTR() = fetchWord(); jump(MEMPTR() = fetchWord());
jump();
addCycles(10); addCycles(10);
break; break;
case 1: // CB prefix case 1: // CB prefix
@ -1455,8 +1456,7 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
case 1: case 1:
switch (p) { switch (p) {
case 0: // CALL nn case 0: // CALL nn
MEMPTR() = fetchWord(); call(MEMPTR() = fetchWord());
call();
addCycles(17); addCycles(17);
break; break;
case 1: // DD prefix case 1: // DD prefix

View File

@ -36,6 +36,8 @@ namespace EightBit {
return m_decodedOpcodes[i]; return m_decodedOpcodes[i];
} }
register16_t& MEMPTR() { return m_memptr; }
register16_t& SP() { return m_sp; } register16_t& SP() { return m_sp; }
virtual register16_t& AF() = 0; virtual register16_t& AF() = 0;
@ -128,32 +130,34 @@ namespace EightBit {
void restart(uint8_t address) { void restart(uint8_t address) {
MEMPTR().low = address; MEMPTR().low = address;
MEMPTR().high = 0; MEMPTR().high = 0;
call(); call(MEMPTR());
} }
bool callConditional(int condition) { bool callConditional(int condition) {
MEMPTR() = fetchWord(); MEMPTR() = fetchWord();
if (condition) if (condition)
call(); call(MEMPTR());
return condition != 0; return condition != 0;
} }
bool jumpConditional(int conditional) { bool jumpConditional(int conditional) {
MEMPTR() = fetchWord(); MEMPTR() = fetchWord();
if (conditional) if (conditional)
jump(); jump(MEMPTR());
return conditional != 0; return conditional != 0;
} }
bool returnConditional(int condition) { bool returnConditional(int condition) {
if (condition) if (condition) {
ret(); ret();
MEMPTR() = PC();
}
return condition != 0; return condition != 0;
} }
void jr(int8_t offset) { void jr(int8_t offset) {
MEMPTR().word = PC().word + offset; MEMPTR().word = PC().word + offset;
jump(); jump(MEMPTR());
} }
bool jrConditional(int conditional) { bool jrConditional(int conditional) {
@ -166,5 +170,6 @@ namespace EightBit {
private: private:
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes; std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
register16_t m_sp = { { 0xff, 0xff } }; register16_t m_sp = { { 0xff, 0xff } };
register16_t m_memptr = { { 0, 0 } };
}; };
} }

View File

@ -67,7 +67,6 @@ namespace EightBit {
Bus& BUS() { return m_bus; } Bus& BUS() { return m_bus; }
register16_t& PC() { return m_pc; } register16_t& PC() { return m_pc; }
register16_t& MEMPTR() { return m_memptr; }
PinLevel& RESET() { return m_resetLine; } // In PinLevel& RESET() { return m_resetLine; } // In
PinLevel& HALT() { return m_haltLine; } // Out PinLevel& HALT() { return m_haltLine; } // Out
@ -132,18 +131,17 @@ namespace EightBit {
return returned; return returned;
} }
void jump() { void jump(register16_t destination) {
PC() = MEMPTR(); PC() = destination;
} }
void call() { void call(register16_t destination) {
pushWord(PC()); pushWord(PC());
jump(); jump(destination);
} }
void ret() { void ret() {
MEMPTR() = popWord(); jump(popWord());
jump();
} }
int cycles() const { return m_cycles; } int cycles() const { return m_cycles; }
@ -155,7 +153,6 @@ namespace EightBit {
Bus& m_bus; Bus& m_bus;
int m_cycles = 0; int m_cycles = 0;
register16_t m_pc = { { 0, 0 } }; register16_t m_pc = { { 0, 0 } };
register16_t m_memptr = { { 0, 0 } };
PinLevel m_intLine = Low; PinLevel m_intLine = Low;
PinLevel m_nmiLine = Low; PinLevel m_nmiLine = Low;

View File

@ -11,7 +11,7 @@ void EightBit::Processor::reset() {
raise(INT()); raise(INT());
raise(NMI()); raise(NMI());
raise(RESET()); raise(RESET());
PC().word = MEMPTR().word = 0; PC().word = 0;
} }
int EightBit::Processor::run(int limit) { int EightBit::Processor::run(int limit) {