mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-02 18:29:41 +00:00
MEMPTR is really only a concept of Intel style processors.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
97a121b8d4
commit
d818095815
@ -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;
|
||||
}
|
||||
|
@ -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 } };;
|
||||
};
|
||||
}
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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 } };
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user