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

@ -528,9 +528,8 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
break;
case 3: // Assorted operations
switch (y) {
case 0: // JP nn
MEMPTR() = fetchWord();
jump();
case 0: // JP nn
jump(MEMPTR() = fetchWord());
addCycles(10);
break;
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:
switch (p) {
case 0: // CALL nn
MEMPTR() = fetchWord();
call();
call(MEMPTR() = fetchWord());
addCycles(17);
break;
}

View File

@ -74,59 +74,54 @@ namespace EightBit {
// Address resolution
void Address_Absolute() {
MEMPTR() = fetchWord();
register16_t Address_Absolute() {
return fetchWord();
}
void Address_ZeroPage() {
MEMPTR().low = fetchByte();
MEMPTR().high = 0;
uint8_t Address_ZeroPage() {
return fetchByte();
}
void Address_ZeroPageIndirect() {
Address_ZeroPage();
MEMPTR() = getWordPaged(0, MEMPTR().low);
register16_t Address_ZeroPageIndirect() {
return getWordPaged(0, Address_ZeroPage());
}
void Address_Indirect() {
Address_Absolute();
MEMPTR() = getWordPaged(MEMPTR().high, MEMPTR().low);
register16_t Address_Indirect() {
const auto address = Address_Absolute();
return getWordPaged(address.high, address.low);
}
void Address_ZeroPageX() {
Address_ZeroPage();
MEMPTR().low += X();
uint8_t Address_ZeroPageX() {
return Address_ZeroPage() + X();
}
void Address_ZeroPageY() {
Address_ZeroPage();
MEMPTR().low += Y();
uint8_t Address_ZeroPageY() {
return Address_ZeroPage() + Y();
}
bool Address_AbsoluteX() {
Address_Absolute();
const auto page = MEMPTR().high;
MEMPTR().word += X();
return MEMPTR().high != page;
std::tuple<register16_t, bool> Address_AbsoluteX() {
auto address = Address_Absolute();
const auto page = address.high;
address.word += X();
return std::tuple<register16_t, bool>(address, address.high != page);
}
bool Address_AbsoluteY() {
Address_Absolute();
const auto page = MEMPTR().high;
MEMPTR().word += Y();
return MEMPTR().high != page;
std::tuple<register16_t, bool> Address_AbsoluteY() {
auto address = Address_Absolute();
const auto page = address.high;
address.word += Y();
return std::tuple<register16_t, bool>(address, address.high != page);
}
void Address_IndexedIndirectX() {
Address_ZeroPageX();
MEMPTR() = getWordPaged(0, MEMPTR().low);
register16_t Address_IndexedIndirectX() {
return getWordPaged(0, Address_ZeroPageX());
}
bool Address_IndirectIndexedY() {
Address_ZeroPageIndirect();
const auto page = MEMPTR().high;
MEMPTR().word += Y();
return MEMPTR().high != page;
std::tuple<register16_t, bool> Address_IndirectIndexedY() {
auto address = Address_ZeroPageIndirect();
const auto page = address.high;
address.word += Y();
return std::tuple<register16_t, bool>(address, address.high != page);
}
// Addressing modes, read
@ -136,88 +131,78 @@ namespace EightBit {
}
uint8_t AM_Absolute() {
Address_Absolute();
return BUS().read(MEMPTR());
return BUS().read(Address_Absolute());
}
uint8_t AM_ZeroPage() {
Address_ZeroPage();
return BUS().read(MEMPTR());
return BUS().read(Address_ZeroPage());
}
uint8_t AM_AbsoluteX() {
if (UNLIKELY(Address_AbsoluteX()))
const auto ap = Address_AbsoluteX();
if (UNLIKELY(std::get<1>(ap)))
addCycle();
return BUS().read(MEMPTR());
return BUS().read(std::get<0>(ap));
}
uint8_t AM_AbsoluteY() {
if (UNLIKELY(Address_AbsoluteY()))
const auto ap = Address_AbsoluteY();
if (UNLIKELY(std::get<1>(ap)))
addCycle();
return BUS().read(MEMPTR());
return BUS().read(std::get<0>(ap));
}
uint8_t AM_ZeroPageX() {
Address_ZeroPageX();
return BUS().read(MEMPTR());
return BUS().read(Address_ZeroPageX());
}
uint8_t AM_ZeroPageY() {
Address_ZeroPageY();
return BUS().read(MEMPTR());
return BUS().read(Address_ZeroPageY());
}
uint8_t AM_IndexedIndirectX() {
Address_IndexedIndirectX();
return BUS().read(MEMPTR());
return BUS().read(Address_IndexedIndirectX());
}
uint8_t AM_IndirectIndexedY() {
if (UNLIKELY(Address_IndirectIndexedY()))
const auto ap = Address_IndirectIndexedY();
if (UNLIKELY(std::get<1>(ap)))
addCycle();
return BUS().read(MEMPTR());
return BUS().read(std::get<0>(ap));
}
// Addressing modes, write
void AM_Absolute(uint8_t value) {
Address_Absolute();
BUS().write(MEMPTR(), value);
BUS().write(Address_Absolute(), value);
}
void AM_ZeroPage(uint8_t value) {
Address_ZeroPage();
BUS().write(MEMPTR(), value);
BUS().write(Address_ZeroPage(), value);
}
void AM_AbsoluteX(uint8_t value) {
Address_AbsoluteX();
BUS().write(MEMPTR(), value);
BUS().write(std::get<0>(Address_AbsoluteX()), value);
}
void AM_AbsoluteY(uint8_t value) {
Address_AbsoluteY();
BUS().write(MEMPTR(), value);
BUS().write(std::get<0>(Address_AbsoluteY()), value);
}
void AM_ZeroPageX(uint8_t value) {
Address_ZeroPageX();
BUS().write(MEMPTR(), value);
BUS().write(Address_ZeroPageX(), value);
}
void AM_ZeroPageY(uint8_t value) {
Address_ZeroPageY();
BUS().write(MEMPTR(), value);
BUS().write(Address_ZeroPageY(), value);
}
void AM_IndexedIndirectX(uint8_t value) {
Address_IndexedIndirectX();
BUS().write(MEMPTR(), value);
BUS().write(Address_IndexedIndirectX(), value);
}
void AM_IndirectIndexedY(uint8_t value) {
Address_IndirectIndexedY();
BUS().write(MEMPTR(), value);
BUS().write(std::get<0>(Address_IndirectIndexedY()), value);
}
// Operations
@ -344,5 +329,7 @@ namespace EightBit {
uint8_t p = 0; // processor status
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 register16_t& difference = MEMPTR();
const register16_t& difference = m_intermediate;
adjustNZ(difference.low);
setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
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) {
MEMPTR().word = operand - data - borrow;
return MEMPTR().low;
m_intermediate.word = operand - data - borrow;
return m_intermediate.low;
}
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;
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) {
const auto returned = ADD(operand, data, P() & CF);
adjustNZ(MEMPTR().low);
adjustNZ(m_intermediate.low);
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) {
MEMPTR().word = operand + data + carry;
m_intermediate.word = operand + data + carry;
setFlag(P(), VF, ~(operand ^ data) & (operand ^ MEMPTR().low) & NF);
setFlag(P(), CF, MEMPTR().high & CF);
setFlag(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
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) {
MEMPTR().word = operand + data + carry;
m_intermediate.word = operand + data + carry;
uint8_t low = lowNibble(operand) + lowNibble(data) + carry;
if (low > 9)
@ -515,9 +515,9 @@ void EightBit::MOS6502::PLP() {
//
void EightBit::MOS6502::JSR_abs() {
Address_Absolute();
const auto address = Address_Absolute();
--PC().word;
call();
call(address);
}
void EightBit::MOS6502::RTI() {
@ -531,13 +531,11 @@ void EightBit::MOS6502::RTS() {
}
void EightBit::MOS6502::JMP_abs() {
Address_Absolute();
jump();
jump(Address_Absolute());
}
void EightBit::MOS6502::JMP_ind() {
Address_Indirect();
jump();
jump(Address_Indirect());
}
void EightBit::MOS6502::BRK() {

View File

@ -117,6 +117,7 @@ bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
void EightBit::Z80::retn() {
ret();
MEMPTR() = PC();
IFF1() = IFF2();
}
@ -685,7 +686,7 @@ int EightBit::Z80::step() {
case 2:
MEMPTR().low = BUS().DATA();
MEMPTR().high = IV();
call();
call(MEMPTR());
addCycles(19);
return cycles();
default:
@ -891,7 +892,7 @@ void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y,
break;
case 3: // Retrieve/store register pair from/to immediate address
switch (q) {
case 0: // LD (nn), rp[p]
case 0: // LD (nn), rp[p]
MEMPTR() = fetchWord();
setWord(RP(p));
break;
@ -1373,6 +1374,7 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
switch (p) {
case 0: // RET
ret();
MEMPTR() = PC();
addCycles(10);
break;
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
switch (y) {
case 0: // JP nn
MEMPTR() = fetchWord();
jump();
jump(MEMPTR() = fetchWord());
addCycles(10);
break;
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:
switch (p) {
case 0: // CALL nn
MEMPTR() = fetchWord();
call();
call(MEMPTR() = fetchWord());
addCycles(17);
break;
case 1: // DD prefix

View File

@ -36,6 +36,8 @@ namespace EightBit {
return m_decodedOpcodes[i];
}
register16_t& MEMPTR() { return m_memptr; }
register16_t& SP() { return m_sp; }
virtual register16_t& AF() = 0;
@ -128,32 +130,34 @@ namespace EightBit {
void restart(uint8_t address) {
MEMPTR().low = address;
MEMPTR().high = 0;
call();
call(MEMPTR());
}
bool callConditional(int condition) {
MEMPTR() = fetchWord();
if (condition)
call();
call(MEMPTR());
return condition != 0;
}
bool jumpConditional(int conditional) {
MEMPTR() = fetchWord();
if (conditional)
jump();
jump(MEMPTR());
return conditional != 0;
}
bool returnConditional(int condition) {
if (condition)
if (condition) {
ret();
MEMPTR() = PC();
}
return condition != 0;
}
void jr(int8_t offset) {
MEMPTR().word = PC().word + offset;
jump();
jump(MEMPTR());
}
bool jrConditional(int conditional) {
@ -166,5 +170,6 @@ namespace EightBit {
private:
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
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; }
register16_t& PC() { return m_pc; }
register16_t& MEMPTR() { return m_memptr; }
PinLevel& RESET() { return m_resetLine; } // In
PinLevel& HALT() { return m_haltLine; } // Out
@ -132,18 +131,17 @@ namespace EightBit {
return returned;
}
void jump() {
PC() = MEMPTR();
void jump(register16_t destination) {
PC() = destination;
}
void call() {
void call(register16_t destination) {
pushWord(PC());
jump();
jump(destination);
}
void ret() {
MEMPTR() = popWord();
jump();
jump(popWord());
}
int cycles() const { return m_cycles; }
@ -155,7 +153,6 @@ namespace EightBit {
Bus& m_bus;
int m_cycles = 0;
register16_t m_pc = { { 0, 0 } };
register16_t m_memptr = { { 0, 0 } };
PinLevel m_intLine = Low;
PinLevel m_nmiLine = Low;

View File

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