mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-08-09 00:25:10 +00:00
Get rid of wrappers for bus access: i.e. make it clearer where the bus is being read/written.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -62,7 +62,7 @@ namespace EightBit {
|
|||||||
case 0b101:
|
case 0b101:
|
||||||
return L();
|
return L();
|
||||||
case 0b110:
|
case 0b110:
|
||||||
return getByte(HL());
|
return BUS().read(HL());
|
||||||
case 0b111:
|
case 0b111:
|
||||||
return a;
|
return a;
|
||||||
default:
|
default:
|
||||||
@@ -92,7 +92,7 @@ namespace EightBit {
|
|||||||
L() = value;
|
L() = value;
|
||||||
break;
|
break;
|
||||||
case 0b110:
|
case 0b110:
|
||||||
setByte(HL(), value);
|
BUS().write(HL(), value);
|
||||||
break;
|
break;
|
||||||
case 0b111:
|
case 0b111:
|
||||||
a = value;
|
a = value;
|
||||||
|
@@ -231,22 +231,20 @@ void EightBit::Intel8080::cmc(uint8_t& a, uint8_t& f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::xhtl(register16_t& operand) {
|
void EightBit::Intel8080::xhtl(register16_t& operand) {
|
||||||
MEMPTR().low = getByte(SP());
|
MEMPTR().low = BUS().read(SP());
|
||||||
setByte(operand.low);
|
BUS().write(operand.low);
|
||||||
operand.low = MEMPTR().low;
|
operand.low = MEMPTR().low;
|
||||||
BUS().ADDRESS().word++;
|
BUS().ADDRESS().word++;
|
||||||
MEMPTR().high = getByte();
|
MEMPTR().high = BUS().read();
|
||||||
setByte(operand.high);
|
BUS().write(operand.high);
|
||||||
operand.high = MEMPTR().high;
|
operand.high = MEMPTR().high;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::writePort(uint8_t port, uint8_t data) {
|
void EightBit::Intel8080::writePort(uint8_t port, uint8_t data) {
|
||||||
BUS().ADDRESS().low = port;
|
BUS().ADDRESS().low = port;
|
||||||
BUS().ADDRESS().high = data;
|
BUS().ADDRESS().high = data;
|
||||||
MEMPTR() = BUS().ADDRESS();
|
|
||||||
BUS().placeDATA(data);
|
BUS().placeDATA(data);
|
||||||
writePort();
|
writePort();
|
||||||
MEMPTR().low++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::writePort() {
|
void EightBit::Intel8080::writePort() {
|
||||||
@@ -256,10 +254,8 @@ void EightBit::Intel8080::writePort() {
|
|||||||
void EightBit::Intel8080::readPort(uint8_t port, uint8_t& a) {
|
void EightBit::Intel8080::readPort(uint8_t port, uint8_t& a) {
|
||||||
BUS().ADDRESS().low = port;
|
BUS().ADDRESS().low = port;
|
||||||
BUS().ADDRESS().high = a;
|
BUS().ADDRESS().high = a;
|
||||||
MEMPTR() = BUS().ADDRESS();
|
|
||||||
readPort();
|
readPort();
|
||||||
a = BUS().DATA();
|
a = BUS().DATA();
|
||||||
MEMPTR().low++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::readPort() {
|
void EightBit::Intel8080::readPort() {
|
||||||
@@ -302,9 +298,7 @@ int EightBit::Intel8080::execute(uint8_t opcode) {
|
|||||||
|
|
||||||
execute(a, f, x, y, z, p, q);
|
execute(a, f, x, y, z, p, q);
|
||||||
|
|
||||||
if (UNLIKELY(cycles() == 0))
|
ASSUME(cycles() > 0);
|
||||||
throw std::logic_error("Unhandled opcode");
|
|
||||||
|
|
||||||
return cycles();
|
return cycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,11 +332,11 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
|
|||||||
case 0:
|
case 0:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD (BC),A
|
case 0: // LD (BC),A
|
||||||
setByte(BC(), a);
|
BUS().write(BC(), a);
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD (DE),A
|
case 1: // LD (DE),A
|
||||||
setByte(DE(), a);
|
BUS().write(DE(), a);
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 2: // LD (nn),HL
|
case 2: // LD (nn),HL
|
||||||
@@ -351,8 +345,8 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD (nn),A
|
case 3: // LD (nn),A
|
||||||
MEMPTR() = fetchWord();
|
BUS().ADDRESS() = fetchWord();
|
||||||
setByte(MEMPTR(), a);
|
BUS().write(a);
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -362,11 +356,11 @@ 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: // LD A,(BC)
|
case 0: // LD A,(BC)
|
||||||
a = getByte(BC());
|
a = BUS().read(BC());
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD A,(DE)
|
case 1: // LD A,(DE)
|
||||||
a = getByte(DE());
|
a = BUS().read(DE());
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 2: // LD HL,(nn)
|
case 2: // LD HL,(nn)
|
||||||
@@ -375,8 +369,8 @@ void EightBit::Intel8080::execute(uint8_t& a, uint8_t& f, int x, int y, int z, i
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD A,(nn)
|
case 3: // LD A,(nn)
|
||||||
MEMPTR() = fetchWord();
|
BUS().ADDRESS() = fetchWord();
|
||||||
a = getByte(MEMPTR());
|
a = BUS().read();
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -76,7 +76,7 @@ namespace EightBit {
|
|||||||
case 5:
|
case 5:
|
||||||
return L();
|
return L();
|
||||||
case 6:
|
case 6:
|
||||||
return getByte(HL());
|
return BUS().read(HL());
|
||||||
case 7:
|
case 7:
|
||||||
return a;
|
return a;
|
||||||
default:
|
default:
|
||||||
@@ -106,7 +106,7 @@ namespace EightBit {
|
|||||||
L() = value;
|
L() = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
setByte(HL(), value);
|
BUS().write(HL(), value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
a = value;
|
a = value;
|
||||||
|
@@ -467,19 +467,19 @@ void EightBit::GameBoy::LR35902::executeOther(uint8_t& a, uint8_t& f, int x, int
|
|||||||
case 0:
|
case 0:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD (BC),A
|
case 0: // LD (BC),A
|
||||||
setByte(BC(), a);
|
BUS().write(BC(), a);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 1: // LD (DE),A
|
case 1: // LD (DE),A
|
||||||
setByte(DE(), a);
|
BUS().write(DE(), a);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 2: // GB: LDI (HL),A
|
case 2: // GB: LDI (HL),A
|
||||||
setByte(HL().word++, a);
|
BUS().write(HL().word++, a);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 3: // GB: LDD (HL),A
|
case 3: // GB: LDD (HL),A
|
||||||
setByte(HL().word--, a);
|
BUS().write(HL().word--, a);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -489,19 +489,19 @@ void EightBit::GameBoy::LR35902::executeOther(uint8_t& a, uint8_t& f, int x, int
|
|||||||
case 1:
|
case 1:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD A,(BC)
|
case 0: // LD A,(BC)
|
||||||
a = getByte(BC());
|
a = BUS().read(BC());
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 1: // LD A,(DE)
|
case 1: // LD A,(DE)
|
||||||
a = getByte(DE());
|
a = BUS().read(DE());
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 2: // GB: LDI A,(HL)
|
case 2: // GB: LDI A,(HL)
|
||||||
a = getByte(HL().word++);
|
a = BUS().read(HL().word++);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
case 3: // GB: LDD A,(HL)
|
case 3: // GB: LDD A,(HL)
|
||||||
a = getByte(HL().word--);
|
a = BUS().read(HL().word--);
|
||||||
addCycles(2);
|
addCycles(2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -718,7 +718,7 @@ void EightBit::GameBoy::LR35902::executeOther(uint8_t& a, uint8_t& f, int x, int
|
|||||||
break;
|
break;
|
||||||
case 5: // GB: LD (nn),A
|
case 5: // GB: LD (nn),A
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = fetchWord();
|
||||||
setByte(MEMPTR(), a);
|
BUS().write(MEMPTR(), a);
|
||||||
addCycles(4);
|
addCycles(4);
|
||||||
break;
|
break;
|
||||||
case 6: // GB: LD A,(FF00 + C)
|
case 6: // GB: LD A,(FF00 + C)
|
||||||
@@ -727,7 +727,7 @@ void EightBit::GameBoy::LR35902::executeOther(uint8_t& a, uint8_t& f, int x, int
|
|||||||
break;
|
break;
|
||||||
case 7: // GB: LD A,(nn)
|
case 7: // GB: LD A,(nn)
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = fetchWord();
|
||||||
a = getByte(MEMPTR());
|
a = BUS().read(MEMPTR());
|
||||||
addCycles(4);
|
addCycles(4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -137,122 +137,122 @@ namespace EightBit {
|
|||||||
|
|
||||||
uint8_t AM_Absolute() {
|
uint8_t AM_Absolute() {
|
||||||
Address_Absolute();
|
Address_Absolute();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPage() {
|
uint8_t AM_ZeroPage() {
|
||||||
Address_ZeroPage();
|
Address_ZeroPage();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_AbsoluteX() {
|
uint8_t AM_AbsoluteX() {
|
||||||
if (UNLIKELY(Address_AbsoluteX()))
|
if (UNLIKELY(Address_AbsoluteX()))
|
||||||
addCycle();
|
addCycle();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_AbsoluteY() {
|
uint8_t AM_AbsoluteY() {
|
||||||
if (UNLIKELY(Address_AbsoluteY()))
|
if (UNLIKELY(Address_AbsoluteY()))
|
||||||
addCycle();
|
addCycle();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPageX() {
|
uint8_t AM_ZeroPageX() {
|
||||||
Address_ZeroPageX();
|
Address_ZeroPageX();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_ZeroPageY() {
|
uint8_t AM_ZeroPageY() {
|
||||||
Address_ZeroPageY();
|
Address_ZeroPageY();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_IndexedIndirectX() {
|
uint8_t AM_IndexedIndirectX() {
|
||||||
Address_IndexedIndirectX();
|
Address_IndexedIndirectX();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AM_IndirectIndexedY() {
|
uint8_t AM_IndirectIndexedY() {
|
||||||
if (UNLIKELY(Address_IndirectIndexedY()))
|
if (UNLIKELY(Address_IndirectIndexedY()))
|
||||||
addCycle();
|
addCycle();
|
||||||
return getByte(MEMPTR());
|
return BUS().read(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addressing modes, write
|
// Addressing modes, write
|
||||||
|
|
||||||
void AM_Absolute(uint8_t value) {
|
void AM_Absolute(uint8_t value) {
|
||||||
Address_Absolute();
|
Address_Absolute();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPage(uint8_t value) {
|
void AM_ZeroPage(uint8_t value) {
|
||||||
Address_ZeroPage();
|
Address_ZeroPage();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_AbsoluteX(uint8_t value) {
|
void AM_AbsoluteX(uint8_t value) {
|
||||||
Address_AbsoluteX();
|
Address_AbsoluteX();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_AbsoluteY(uint8_t value) {
|
void AM_AbsoluteY(uint8_t value) {
|
||||||
Address_AbsoluteY();
|
Address_AbsoluteY();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPageX(uint8_t value) {
|
void AM_ZeroPageX(uint8_t value) {
|
||||||
Address_ZeroPageX();
|
Address_ZeroPageX();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_ZeroPageY(uint8_t value) {
|
void AM_ZeroPageY(uint8_t value) {
|
||||||
Address_ZeroPageY();
|
Address_ZeroPageY();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_IndexedIndirectX(uint8_t value) {
|
void AM_IndexedIndirectX(uint8_t value) {
|
||||||
Address_IndexedIndirectX();
|
Address_IndexedIndirectX();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_IndirectIndexedY(uint8_t value) {
|
void AM_IndirectIndexedY(uint8_t value) {
|
||||||
Address_IndirectIndexedY();
|
Address_IndirectIndexedY();
|
||||||
setByte(MEMPTR(), value);
|
BUS().write(MEMPTR(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
void DCP(uint8_t value) {
|
void DCP(uint8_t value) {
|
||||||
setByte(--value);
|
BUS().write(--value);
|
||||||
CMP(A(), value);
|
CMP(A(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISB(uint8_t value) {
|
void ISB(uint8_t value) {
|
||||||
setByte(++value);
|
BUS().write(++value);
|
||||||
A() = SBC(A(), value);
|
A() = SBC(A(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SLO(uint8_t value) {
|
void SLO(uint8_t value) {
|
||||||
const auto result = ASL(value);
|
const auto result = ASL(value);
|
||||||
setByte(result);
|
BUS().write(result);
|
||||||
ORA(result);
|
ORA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SRE(uint8_t value) {
|
void SRE(uint8_t value) {
|
||||||
const auto result = LSR(value);
|
const auto result = LSR(value);
|
||||||
setByte(result);
|
BUS().write(result);
|
||||||
EORA(result);
|
EORA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RLA(uint8_t value) {
|
void RLA(uint8_t value) {
|
||||||
const auto result = ROL(value);
|
const auto result = ROL(value);
|
||||||
setByte(result);
|
BUS().write(result);
|
||||||
ANDA(result);
|
ANDA(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RRA(uint8_t value) {
|
void RRA(uint8_t value) {
|
||||||
const auto result = ROR(value);
|
const auto result = ROR(value);
|
||||||
setByte(result);
|
BUS().write(result);
|
||||||
A() = ADC(A(), result);
|
A() = ADC(A(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,20 +54,20 @@ EightBit::register16_t EightBit::MOS6502::getWordPaged(uint8_t page, uint8_t off
|
|||||||
EightBit::register16_t returned;
|
EightBit::register16_t returned;
|
||||||
returned.low = getBytePaged(page, offset);
|
returned.low = getBytePaged(page, offset);
|
||||||
BUS().ADDRESS().low++;
|
BUS().ADDRESS().low++;
|
||||||
returned.high = getByte();
|
returned.high = BUS().read();
|
||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::getBytePaged(uint8_t page, uint8_t offset) {
|
uint8_t EightBit::MOS6502::getBytePaged(uint8_t page, uint8_t offset) {
|
||||||
BUS().ADDRESS().low = offset;
|
BUS().ADDRESS().low = offset;
|
||||||
BUS().ADDRESS().high = page;
|
BUS().ADDRESS().high = page;
|
||||||
return getByte();
|
return BUS().read();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::setBytePaged(uint8_t page, uint8_t offset, uint8_t value) {
|
void EightBit::MOS6502::setBytePaged(uint8_t page, uint8_t offset, uint8_t value) {
|
||||||
BUS().ADDRESS().low = offset;
|
BUS().ADDRESS().low = offset;
|
||||||
BUS().ADDRESS().high = page;
|
BUS().ADDRESS().high = page;
|
||||||
setByte(value);
|
BUS().write(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::interrupt(uint8_t vector) {
|
void EightBit::MOS6502::interrupt(uint8_t vector) {
|
||||||
@@ -88,7 +88,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x03: addCycles(8); SLO(AM_IndexedIndirectX()); break;
|
case 0x03: addCycles(8); SLO(AM_IndexedIndirectX()); break;
|
||||||
case 0x04: addCycles(3); AM_ZeroPage(); break;
|
case 0x04: addCycles(3); AM_ZeroPage(); break;
|
||||||
case 0x05: addCycles(3); ORA(AM_ZeroPage()); break;
|
case 0x05: addCycles(3); ORA(AM_ZeroPage()); break;
|
||||||
case 0x06: addCycles(5); setByte(ASL(AM_ZeroPage())); break;
|
case 0x06: addCycles(5); BUS().write(ASL(AM_ZeroPage())); break;
|
||||||
case 0x07: addCycles(5); SLO(AM_ZeroPage()); break;
|
case 0x07: addCycles(5); SLO(AM_ZeroPage()); break;
|
||||||
case 0x08: addCycles(3); PHP(); break;
|
case 0x08: addCycles(3); PHP(); break;
|
||||||
case 0x09: addCycles(2); ORA(AM_Immediate()); break;
|
case 0x09: addCycles(2); ORA(AM_Immediate()); break;
|
||||||
@@ -96,7 +96,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x0b: addCycles(2); AAC(AM_Immediate()); break;
|
case 0x0b: addCycles(2); AAC(AM_Immediate()); break;
|
||||||
case 0x0c: addCycles(4); AM_Absolute(); break;
|
case 0x0c: addCycles(4); AM_Absolute(); break;
|
||||||
case 0x0d: addCycles(4); ORA(AM_Absolute()); break;
|
case 0x0d: addCycles(4); ORA(AM_Absolute()); break;
|
||||||
case 0x0e: addCycles(6); setByte(ASL(AM_Absolute())); break;
|
case 0x0e: addCycles(6); BUS().write(ASL(AM_Absolute())); break;
|
||||||
case 0x0f: addCycles(6); SLO(AM_Absolute()); break;
|
case 0x0f: addCycles(6); SLO(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0x10: addCycles(2); Branch(!(P() & NF)); break;
|
case 0x10: addCycles(2); Branch(!(P() & NF)); break;
|
||||||
@@ -105,7 +105,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x13: addCycles(7); SLO(AM_IndirectIndexedY()); break;
|
case 0x13: addCycles(7); SLO(AM_IndirectIndexedY()); break;
|
||||||
case 0x14: addCycles(4); AM_ZeroPageX(); break;
|
case 0x14: addCycles(4); AM_ZeroPageX(); break;
|
||||||
case 0x15: addCycles(4); ORA(AM_ZeroPageX()); break;
|
case 0x15: addCycles(4); ORA(AM_ZeroPageX()); break;
|
||||||
case 0x16: addCycles(6); setByte(ASL(AM_ZeroPageX())); break;
|
case 0x16: addCycles(6); BUS().write(ASL(AM_ZeroPageX())); break;
|
||||||
case 0x17: addCycles(6); SLO(AM_ZeroPageX()); break;
|
case 0x17: addCycles(6); SLO(AM_ZeroPageX()); break;
|
||||||
case 0x18: addCycles(2); clearFlag(P(), CF); break;
|
case 0x18: addCycles(2); clearFlag(P(), CF); break;
|
||||||
case 0x19: addCycles(4); ORA(AM_AbsoluteY()); break;
|
case 0x19: addCycles(4); ORA(AM_AbsoluteY()); break;
|
||||||
@@ -113,7 +113,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x1b: addCycles(6); SLO(AM_AbsoluteY()); break;
|
case 0x1b: addCycles(6); SLO(AM_AbsoluteY()); break;
|
||||||
case 0x1c: addCycles(4); AM_AbsoluteX(); break;
|
case 0x1c: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0x1d: addCycles(4); ORA(AM_AbsoluteX()); break;
|
case 0x1d: addCycles(4); ORA(AM_AbsoluteX()); break;
|
||||||
case 0x1e: addCycles(7); setByte(ASL(AM_AbsoluteX())); break;
|
case 0x1e: addCycles(7); BUS().write(ASL(AM_AbsoluteX())); break;
|
||||||
case 0x1f: addCycles(6); SLO(AM_AbsoluteX()); break;
|
case 0x1f: addCycles(6); SLO(AM_AbsoluteX()); break;
|
||||||
|
|
||||||
case 0x20: addCycles(6); JSR_abs(); break;
|
case 0x20: addCycles(6); JSR_abs(); break;
|
||||||
@@ -122,7 +122,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x23: addCycles(8); RLA(AM_IndexedIndirectX()); break;
|
case 0x23: addCycles(8); RLA(AM_IndexedIndirectX()); break;
|
||||||
case 0x24: addCycles(3); BIT(AM_ZeroPage()); break;
|
case 0x24: addCycles(3); BIT(AM_ZeroPage()); break;
|
||||||
case 0x25: addCycles(3); ANDA(AM_ZeroPage()); break;
|
case 0x25: addCycles(3); ANDA(AM_ZeroPage()); break;
|
||||||
case 0x26: addCycles(5); setByte(ROL(AM_ZeroPage())); break;
|
case 0x26: addCycles(5); BUS().write(ROL(AM_ZeroPage())); break;
|
||||||
case 0x27: addCycles(5); RLA(AM_ZeroPage()); break;
|
case 0x27: addCycles(5); RLA(AM_ZeroPage()); break;
|
||||||
case 0x28: addCycles(4); PLP(); break;
|
case 0x28: addCycles(4); PLP(); break;
|
||||||
case 0x29: addCycles(2); ANDA(AM_Immediate()); break;
|
case 0x29: addCycles(2); ANDA(AM_Immediate()); break;
|
||||||
@@ -130,7 +130,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x2b: addCycles(2); AAC(AM_Immediate()); break;
|
case 0x2b: addCycles(2); AAC(AM_Immediate()); break;
|
||||||
case 0x2c: addCycles(4); BIT(AM_Absolute()); break;
|
case 0x2c: addCycles(4); BIT(AM_Absolute()); break;
|
||||||
case 0x2d: addCycles(4); ANDA(AM_Absolute()); break;
|
case 0x2d: addCycles(4); ANDA(AM_Absolute()); break;
|
||||||
case 0x2e: addCycles(6); setByte(ROL(AM_Absolute())); break;
|
case 0x2e: addCycles(6); BUS().write(ROL(AM_Absolute())); break;
|
||||||
case 0x2f: addCycles(6); RLA(AM_Absolute()); break;
|
case 0x2f: addCycles(6); RLA(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0x30: addCycles(2); Branch(!!(P() & NF)); break;
|
case 0x30: addCycles(2); Branch(!!(P() & NF)); break;
|
||||||
@@ -139,7 +139,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x33: addCycles(7); RLA(AM_IndirectIndexedY()); break;
|
case 0x33: addCycles(7); RLA(AM_IndirectIndexedY()); break;
|
||||||
case 0x34: addCycles(4); AM_ZeroPageX(); break;
|
case 0x34: addCycles(4); AM_ZeroPageX(); break;
|
||||||
case 0x35: addCycles(4); ANDA(AM_ZeroPageX()); break;
|
case 0x35: addCycles(4); ANDA(AM_ZeroPageX()); break;
|
||||||
case 0x36: addCycles(6); setByte(ROL(AM_ZeroPageX())); break;
|
case 0x36: addCycles(6); BUS().write(ROL(AM_ZeroPageX())); break;
|
||||||
case 0x37: addCycles(6); RLA(AM_ZeroPageX()); break;
|
case 0x37: addCycles(6); RLA(AM_ZeroPageX()); break;
|
||||||
case 0x38: addCycles(2); setFlag(P(), CF); break;
|
case 0x38: addCycles(2); setFlag(P(), CF); break;
|
||||||
case 0x39: addCycles(4); ANDA(AM_AbsoluteY()); break;
|
case 0x39: addCycles(4); ANDA(AM_AbsoluteY()); break;
|
||||||
@@ -147,7 +147,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x3b: addCycles(6); RLA(AM_AbsoluteY()); break;
|
case 0x3b: addCycles(6); RLA(AM_AbsoluteY()); break;
|
||||||
case 0x3c: addCycles(4); AM_AbsoluteX(); break;
|
case 0x3c: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0x3d: addCycles(4); ANDA(AM_AbsoluteX()); break;
|
case 0x3d: addCycles(4); ANDA(AM_AbsoluteX()); break;
|
||||||
case 0x3e: addCycles(7); setByte(ROL(AM_AbsoluteX())); break;
|
case 0x3e: addCycles(7); BUS().write(ROL(AM_AbsoluteX())); break;
|
||||||
case 0x3f: addCycles(6); RLA(AM_AbsoluteX()); break;
|
case 0x3f: addCycles(6); RLA(AM_AbsoluteX()); break;
|
||||||
|
|
||||||
case 0x40: addCycles(6); RTI(); break;
|
case 0x40: addCycles(6); RTI(); break;
|
||||||
@@ -156,7 +156,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x43: addCycles(8); SRE(AM_IndexedIndirectX()); break;
|
case 0x43: addCycles(8); SRE(AM_IndexedIndirectX()); break;
|
||||||
case 0x44: addCycles(3); AM_ZeroPage(); break;
|
case 0x44: addCycles(3); AM_ZeroPage(); break;
|
||||||
case 0x45: addCycles(3); EORA(AM_ZeroPage()); break;
|
case 0x45: addCycles(3); EORA(AM_ZeroPage()); break;
|
||||||
case 0x46: addCycles(5); setByte(LSR(AM_ZeroPage())); break;
|
case 0x46: addCycles(5); BUS().write(LSR(AM_ZeroPage())); break;
|
||||||
case 0x47: addCycles(5); SRE(AM_ZeroPage()); break;
|
case 0x47: addCycles(5); SRE(AM_ZeroPage()); break;
|
||||||
case 0x48: addCycles(3); push(A()); break;
|
case 0x48: addCycles(3); push(A()); break;
|
||||||
case 0x49: addCycles(2); EORA(AM_Immediate()); break;
|
case 0x49: addCycles(2); EORA(AM_Immediate()); break;
|
||||||
@@ -164,7 +164,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x4b: addCycles(2); ASR(AM_Immediate()); break;
|
case 0x4b: addCycles(2); ASR(AM_Immediate()); break;
|
||||||
case 0x4c: addCycles(3); JMP_abs(); break;
|
case 0x4c: addCycles(3); JMP_abs(); break;
|
||||||
case 0x4d: addCycles(4); EORA(AM_Absolute()); break;
|
case 0x4d: addCycles(4); EORA(AM_Absolute()); break;
|
||||||
case 0x4e: addCycles(6); setByte(LSR(AM_Absolute())); break;
|
case 0x4e: addCycles(6); BUS().write(LSR(AM_Absolute())); break;
|
||||||
case 0x4f: addCycles(6); SRE(AM_Absolute()); break;
|
case 0x4f: addCycles(6); SRE(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0x50: addCycles(2); Branch(!(P() & VF)); break;
|
case 0x50: addCycles(2); Branch(!(P() & VF)); break;
|
||||||
@@ -173,7 +173,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x53: addCycles(7); SRE(AM_IndirectIndexedY()); break;
|
case 0x53: addCycles(7); SRE(AM_IndirectIndexedY()); break;
|
||||||
case 0x54: addCycles(4); AM_ZeroPage(); break;
|
case 0x54: addCycles(4); AM_ZeroPage(); break;
|
||||||
case 0x55: addCycles(4); EORA(AM_ZeroPageX()); break;
|
case 0x55: addCycles(4); EORA(AM_ZeroPageX()); break;
|
||||||
case 0x56: addCycles(6); setByte(LSR(AM_ZeroPageX())); break;
|
case 0x56: addCycles(6); BUS().write(LSR(AM_ZeroPageX())); break;
|
||||||
case 0x57: addCycles(6); SRE(AM_ZeroPageX()); break;
|
case 0x57: addCycles(6); SRE(AM_ZeroPageX()); break;
|
||||||
case 0x58: addCycles(2); clearFlag(P(), IF); break;
|
case 0x58: addCycles(2); clearFlag(P(), IF); break;
|
||||||
case 0x59: addCycles(4); EORA(AM_AbsoluteY()); break;
|
case 0x59: addCycles(4); EORA(AM_AbsoluteY()); break;
|
||||||
@@ -181,7 +181,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x5b: addCycles(6); SRE(AM_AbsoluteY()); break;
|
case 0x5b: addCycles(6); SRE(AM_AbsoluteY()); break;
|
||||||
case 0x5c: addCycles(4); AM_AbsoluteX(); break;
|
case 0x5c: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0x5d: addCycles(4); EORA(AM_AbsoluteX()); break;
|
case 0x5d: addCycles(4); EORA(AM_AbsoluteX()); break;
|
||||||
case 0x5e: addCycles(7); setByte(LSR(AM_AbsoluteX())); break;
|
case 0x5e: addCycles(7); BUS().write(LSR(AM_AbsoluteX())); break;
|
||||||
case 0x5f: addCycles(6); SRE(AM_AbsoluteX()); break;
|
case 0x5f: addCycles(6); SRE(AM_AbsoluteX()); break;
|
||||||
|
|
||||||
case 0x60: addCycles(6); RTS(); break;
|
case 0x60: addCycles(6); RTS(); break;
|
||||||
@@ -190,7 +190,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x63: addCycles(8); RRA(AM_IndexedIndirectX()); break;
|
case 0x63: addCycles(8); RRA(AM_IndexedIndirectX()); break;
|
||||||
case 0x64: addCycles(3); AM_ZeroPage(); break;
|
case 0x64: addCycles(3); AM_ZeroPage(); break;
|
||||||
case 0x65: addCycles(3); A() = ADC(A(), AM_ZeroPage()); break;
|
case 0x65: addCycles(3); A() = ADC(A(), AM_ZeroPage()); break;
|
||||||
case 0x66: addCycles(5); setByte(ROR(AM_ZeroPage())); break;
|
case 0x66: addCycles(5); BUS().write(ROR(AM_ZeroPage())); break;
|
||||||
case 0x67: addCycles(5); RRA(AM_ZeroPage()); break;
|
case 0x67: addCycles(5); RRA(AM_ZeroPage()); break;
|
||||||
case 0x68: addCycles(4); adjustNZ(A() = pop()); break;
|
case 0x68: addCycles(4); adjustNZ(A() = pop()); break;
|
||||||
case 0x69: addCycles(2); A() = ADC(A(), AM_Immediate()); break;
|
case 0x69: addCycles(2); A() = ADC(A(), AM_Immediate()); break;
|
||||||
@@ -198,7 +198,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x6b: addCycles(2); ARR(AM_Immediate()); break;
|
case 0x6b: addCycles(2); ARR(AM_Immediate()); break;
|
||||||
case 0x6c: addCycles(5); JMP_ind(); break;
|
case 0x6c: addCycles(5); JMP_ind(); break;
|
||||||
case 0x6d: addCycles(4); A() = ADC(A(), AM_Absolute()); break;
|
case 0x6d: addCycles(4); A() = ADC(A(), AM_Absolute()); break;
|
||||||
case 0x6e: addCycles(6); setByte(ROR(AM_Absolute())); break;
|
case 0x6e: addCycles(6); BUS().write(ROR(AM_Absolute())); break;
|
||||||
case 0x6f: addCycles(6); RRA(AM_Absolute()); break;
|
case 0x6f: addCycles(6); RRA(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0x70: addCycles(2); Branch(!!(P() & VF)); break;
|
case 0x70: addCycles(2); Branch(!!(P() & VF)); break;
|
||||||
@@ -207,7 +207,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x73: addCycles(7); RRA(AM_IndirectIndexedY()); break;
|
case 0x73: addCycles(7); RRA(AM_IndirectIndexedY()); break;
|
||||||
case 0x74: addCycles(4); AM_ZeroPageX(); break;
|
case 0x74: addCycles(4); AM_ZeroPageX(); break;
|
||||||
case 0x75: addCycles(4); A() = ADC(A(), AM_ZeroPageX()); break;
|
case 0x75: addCycles(4); A() = ADC(A(), AM_ZeroPageX()); break;
|
||||||
case 0x76: addCycles(6); setByte(ROR(AM_ZeroPageX())); break;
|
case 0x76: addCycles(6); BUS().write(ROR(AM_ZeroPageX())); break;
|
||||||
case 0x77: addCycles(6); RRA(AM_ZeroPageX()); break;
|
case 0x77: addCycles(6); RRA(AM_ZeroPageX()); break;
|
||||||
case 0x78: addCycles(2); setFlag(P(), IF); break;
|
case 0x78: addCycles(2); setFlag(P(), IF); break;
|
||||||
case 0x79: addCycles(4); A() = ADC(A(), AM_AbsoluteY()); break;
|
case 0x79: addCycles(4); A() = ADC(A(), AM_AbsoluteY()); break;
|
||||||
@@ -215,7 +215,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0x7b: addCycles(6); RRA(AM_AbsoluteY()); break;
|
case 0x7b: addCycles(6); RRA(AM_AbsoluteY()); break;
|
||||||
case 0x7c: addCycles(4); AM_AbsoluteX(); break;
|
case 0x7c: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0x7d: addCycles(4); A() = ADC(A(), AM_AbsoluteX()); break;
|
case 0x7d: addCycles(4); A() = ADC(A(), AM_AbsoluteX()); break;
|
||||||
case 0x7e: addCycles(7); setByte(ROR(AM_AbsoluteX())); break;
|
case 0x7e: addCycles(7); BUS().write(ROR(AM_AbsoluteX())); break;
|
||||||
case 0x7f: addCycles(6); RRA(AM_AbsoluteX()); break;
|
case 0x7f: addCycles(6); RRA(AM_AbsoluteX()); break;
|
||||||
|
|
||||||
case 0x80: addCycles(2); AM_Immediate(); break;
|
case 0x80: addCycles(2); AM_Immediate(); break;
|
||||||
@@ -292,7 +292,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xc3: addCycles(8); DCP(AM_IndexedIndirectX()); break;
|
case 0xc3: addCycles(8); DCP(AM_IndexedIndirectX()); break;
|
||||||
case 0xc4: addCycles(3); CMP(Y(), AM_ZeroPage()); break;
|
case 0xc4: addCycles(3); CMP(Y(), AM_ZeroPage()); break;
|
||||||
case 0xc5: addCycles(3); CMP(A(), AM_ZeroPage()); break;
|
case 0xc5: addCycles(3); CMP(A(), AM_ZeroPage()); break;
|
||||||
case 0xc6: addCycles(5); setByte(DEC(AM_ZeroPage())); break;
|
case 0xc6: addCycles(5); BUS().write(DEC(AM_ZeroPage())); break;
|
||||||
case 0xc7: addCycles(5); DCP(AM_ZeroPage()); break;
|
case 0xc7: addCycles(5); DCP(AM_ZeroPage()); break;
|
||||||
case 0xc8: addCycles(2); adjustNZ(++Y()); break;
|
case 0xc8: addCycles(2); adjustNZ(++Y()); break;
|
||||||
case 0xc9: addCycles(2); CMP(A(), AM_Immediate()); break;
|
case 0xc9: addCycles(2); CMP(A(), AM_Immediate()); break;
|
||||||
@@ -300,7 +300,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xcb: addCycles(2); AXS(AM_Immediate()); break;
|
case 0xcb: addCycles(2); AXS(AM_Immediate()); break;
|
||||||
case 0xcc: addCycles(4); CMP(Y(), AM_Absolute()); break;
|
case 0xcc: addCycles(4); CMP(Y(), AM_Absolute()); break;
|
||||||
case 0xcd: addCycles(4); CMP(A(), AM_Absolute()); break;
|
case 0xcd: addCycles(4); CMP(A(), AM_Absolute()); break;
|
||||||
case 0xce: addCycles(6); setByte(DEC(AM_Absolute())); break;
|
case 0xce: addCycles(6); BUS().write(DEC(AM_Absolute())); break;
|
||||||
case 0xcf: addCycles(6); DCP(AM_Absolute()); break;
|
case 0xcf: addCycles(6); DCP(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0xd0: addCycles(2); Branch(!(P() & ZF)); break;
|
case 0xd0: addCycles(2); Branch(!(P() & ZF)); break;
|
||||||
@@ -309,7 +309,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xd3: addCycles(7); DCP(AM_IndirectIndexedY()); break;
|
case 0xd3: addCycles(7); DCP(AM_IndirectIndexedY()); break;
|
||||||
case 0xd4: addCycles(4); AM_ZeroPageX(); break;
|
case 0xd4: addCycles(4); AM_ZeroPageX(); break;
|
||||||
case 0xd5: addCycles(4); CMP(A(), AM_ZeroPageX()); break;
|
case 0xd5: addCycles(4); CMP(A(), AM_ZeroPageX()); break;
|
||||||
case 0xd6: addCycles(6); setByte(DEC(AM_ZeroPageX())); break;
|
case 0xd6: addCycles(6); BUS().write(DEC(AM_ZeroPageX())); break;
|
||||||
case 0xd7: addCycles(6); DCP(AM_ZeroPageX()); break;
|
case 0xd7: addCycles(6); DCP(AM_ZeroPageX()); break;
|
||||||
case 0xd8: addCycles(2); clearFlag(P(), DF); break;
|
case 0xd8: addCycles(2); clearFlag(P(), DF); break;
|
||||||
case 0xd9: addCycles(4); CMP(A(), AM_AbsoluteY()); break;
|
case 0xd9: addCycles(4); CMP(A(), AM_AbsoluteY()); break;
|
||||||
@@ -317,7 +317,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xdb: addCycles(6); DCP(AM_AbsoluteY()); break;
|
case 0xdb: addCycles(6); DCP(AM_AbsoluteY()); break;
|
||||||
case 0xdc: addCycles(4); AM_AbsoluteX(); break;
|
case 0xdc: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0xdd: addCycles(4); CMP(A(), AM_AbsoluteX()); break;
|
case 0xdd: addCycles(4); CMP(A(), AM_AbsoluteX()); break;
|
||||||
case 0xde: addCycles(7); setByte(DEC(AM_AbsoluteX())); break;
|
case 0xde: addCycles(7); BUS().write(DEC(AM_AbsoluteX())); break;
|
||||||
case 0xdf: addCycles(6); DCP(AM_AbsoluteX()); break;
|
case 0xdf: addCycles(6); DCP(AM_AbsoluteX()); break;
|
||||||
|
|
||||||
case 0xe0: addCycles(2); CMP(X(), AM_Immediate()); break;
|
case 0xe0: addCycles(2); CMP(X(), AM_Immediate()); break;
|
||||||
@@ -326,7 +326,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xe3: addCycles(8); ISB(AM_IndexedIndirectX()); break;
|
case 0xe3: addCycles(8); ISB(AM_IndexedIndirectX()); break;
|
||||||
case 0xe4: addCycles(3); CMP(X(), AM_ZeroPage()); break;
|
case 0xe4: addCycles(3); CMP(X(), AM_ZeroPage()); break;
|
||||||
case 0xe5: addCycles(3); A() = SBC(A(), AM_ZeroPage()); break;
|
case 0xe5: addCycles(3); A() = SBC(A(), AM_ZeroPage()); break;
|
||||||
case 0xe6: addCycles(5); setByte(INC(AM_ZeroPage())); break;
|
case 0xe6: addCycles(5); BUS().write(INC(AM_ZeroPage())); break;
|
||||||
case 0xe7: addCycles(5); ISB(AM_ZeroPage()); break;
|
case 0xe7: addCycles(5); ISB(AM_ZeroPage()); break;
|
||||||
case 0xe8: addCycles(2); adjustNZ(++X()); break;
|
case 0xe8: addCycles(2); adjustNZ(++X()); break;
|
||||||
case 0xe9: addCycles(2); A() = SBC(A(), AM_Immediate()); break;
|
case 0xe9: addCycles(2); A() = SBC(A(), AM_Immediate()); break;
|
||||||
@@ -334,7 +334,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xeb: addCycles(2); A() = SBC(A(), AM_Immediate()); break;
|
case 0xeb: addCycles(2); A() = SBC(A(), AM_Immediate()); break;
|
||||||
case 0xec: addCycles(4); CMP(X(), AM_Absolute()); break;
|
case 0xec: addCycles(4); CMP(X(), AM_Absolute()); break;
|
||||||
case 0xed: addCycles(4); A() = SBC(A(), AM_Absolute()); break;
|
case 0xed: addCycles(4); A() = SBC(A(), AM_Absolute()); break;
|
||||||
case 0xee: addCycles(6); setByte(INC(AM_Absolute())); break;
|
case 0xee: addCycles(6); BUS().write(INC(AM_Absolute())); break;
|
||||||
case 0xef: addCycles(6); ISB(AM_Absolute()); break;
|
case 0xef: addCycles(6); ISB(AM_Absolute()); break;
|
||||||
|
|
||||||
case 0xf0: addCycles(2); Branch(!!(P() & ZF)); break;
|
case 0xf0: addCycles(2); Branch(!!(P() & ZF)); break;
|
||||||
@@ -343,7 +343,7 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xf3: addCycles(7); ISB(AM_IndirectIndexedY()); break;
|
case 0xf3: addCycles(7); ISB(AM_IndirectIndexedY()); break;
|
||||||
case 0xf4: addCycles(4); AM_ZeroPageX(); break;
|
case 0xf4: addCycles(4); AM_ZeroPageX(); break;
|
||||||
case 0xf5: addCycles(4); A() = SBC(A(), AM_ZeroPageX()); break;
|
case 0xf5: addCycles(4); A() = SBC(A(), AM_ZeroPageX()); break;
|
||||||
case 0xf6: addCycles(6); setByte(INC(AM_ZeroPageX())); break;
|
case 0xf6: addCycles(6); BUS().write(INC(AM_ZeroPageX())); break;
|
||||||
case 0xf7: addCycles(6); ISB(AM_ZeroPageX()); break;
|
case 0xf7: addCycles(6); ISB(AM_ZeroPageX()); break;
|
||||||
case 0xf8: addCycles(2); setFlag(P(), DF); break;
|
case 0xf8: addCycles(2); setFlag(P(), DF); break;
|
||||||
case 0xf9: addCycles(4); A() = SBC(A(), AM_AbsoluteY()); break;
|
case 0xf9: addCycles(4); A() = SBC(A(), AM_AbsoluteY()); break;
|
||||||
@@ -351,13 +351,11 @@ int EightBit::MOS6502::execute(uint8_t cell) {
|
|||||||
case 0xfb: addCycles(6); ISB(AM_AbsoluteY()); break;
|
case 0xfb: addCycles(6); ISB(AM_AbsoluteY()); break;
|
||||||
case 0xfc: addCycles(4); AM_AbsoluteX(); break;
|
case 0xfc: addCycles(4); AM_AbsoluteX(); break;
|
||||||
case 0xfd: addCycles(4); A() = SBC(A(), AM_AbsoluteX()); break;
|
case 0xfd: addCycles(4); A() = SBC(A(), AM_AbsoluteX()); break;
|
||||||
case 0xfe: addCycles(7); setByte(INC(AM_AbsoluteX())); break;
|
case 0xfe: addCycles(7); BUS().write(INC(AM_AbsoluteX())); break;
|
||||||
case 0xff: addCycles(6); ISB(AM_AbsoluteX()); break;
|
case 0xff: addCycles(6); ISB(AM_AbsoluteX()); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(cycles() == 0))
|
ASSUME(cycles() > 0);
|
||||||
throw std::logic_error("Unhandled opcode");
|
|
||||||
|
|
||||||
return cycles();
|
return cycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -126,6 +126,8 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R(int r, uint8_t a) {
|
uint8_t R(int r, uint8_t a) {
|
||||||
|
ASSUME(r >= 0);
|
||||||
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 0:
|
case 0:
|
||||||
return B();
|
return B();
|
||||||
@@ -140,16 +142,18 @@ namespace EightBit {
|
|||||||
case 5:
|
case 5:
|
||||||
return HL2().low;
|
return HL2().low;
|
||||||
case 6:
|
case 6:
|
||||||
return getByte(LIKELY(!m_displaced) ? HL().word : displacedAddress());
|
return BUS().read(LIKELY(!m_displaced) ? HL().word : displacedAddress());
|
||||||
case 7:
|
case 7:
|
||||||
return a;
|
return a;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled registry mechanism");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R(int r, uint8_t& a, uint8_t value) {
|
void R(int r, uint8_t& a, uint8_t value) {
|
||||||
|
ASSUME(r >= 0);
|
||||||
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 0:
|
case 0:
|
||||||
B() = value;
|
B() = value;
|
||||||
@@ -170,7 +174,7 @@ namespace EightBit {
|
|||||||
HL2().low = value;
|
HL2().low = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
setByte(LIKELY(!m_displaced) ? HL().word : displacedAddress(), value);
|
BUS().write(LIKELY(!m_displaced) ? HL().word : displacedAddress(), value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
a = value;
|
a = value;
|
||||||
@@ -178,9 +182,12 @@ namespace EightBit {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R2(int r, const uint8_t& a) {
|
uint8_t R2(int r, const uint8_t& a) {
|
||||||
|
ASSUME(r >= 0);
|
||||||
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 0:
|
case 0:
|
||||||
return B();
|
return B();
|
||||||
@@ -195,16 +202,18 @@ namespace EightBit {
|
|||||||
case 5:
|
case 5:
|
||||||
return L();
|
return L();
|
||||||
case 6:
|
case 6:
|
||||||
return getByte(HL());
|
return BUS().read(HL());
|
||||||
case 7:
|
case 7:
|
||||||
return a;
|
return a;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled registry mechanism");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R2(int r, uint8_t& a, uint8_t value) {
|
void R2(int r, uint8_t& a, uint8_t value) {
|
||||||
|
ASSUME(r >= 0);
|
||||||
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 0:
|
case 0:
|
||||||
B() = value;
|
B() = value;
|
||||||
@@ -225,7 +234,7 @@ namespace EightBit {
|
|||||||
L() = value;
|
L() = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
setByte(HL(), value);
|
BUS().write(HL(), value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
a = value;
|
a = value;
|
||||||
@@ -233,9 +242,12 @@ namespace EightBit {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t& RP(int rp) {
|
register16_t& RP(int rp) {
|
||||||
|
ASSUME(rp >= 0);
|
||||||
|
ASSUME(rp <= 3);
|
||||||
switch (rp) {
|
switch (rp) {
|
||||||
case 0:
|
case 0:
|
||||||
return BC();
|
return BC();
|
||||||
@@ -248,6 +260,7 @@ namespace EightBit {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t& HL2() {
|
register16_t& HL2() {
|
||||||
@@ -260,6 +273,8 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
register16_t& RP2(int rp) {
|
register16_t& RP2(int rp) {
|
||||||
|
ASSUME(rp >= 0);
|
||||||
|
ASSUME(rp <= 3);
|
||||||
switch (rp) {
|
switch (rp) {
|
||||||
case 0:
|
case 0:
|
||||||
return BC();
|
return BC();
|
||||||
@@ -272,6 +287,7 @@ namespace EightBit {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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) {
|
||||||
|
179
Z80/src/Z80.cpp
179
Z80/src/Z80.cpp
@@ -74,6 +74,8 @@ void EightBit::Z80::decrement(uint8_t& f, uint8_t& operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::jrConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::jrConditionalFlag(uint8_t f, const int flag) {
|
||||||
|
ASSUME(flag >= 0);
|
||||||
|
ASSUME(flag <= 3);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 0: // NZ
|
case 0: // NZ
|
||||||
return jrConditional(!(f & ZF));
|
return jrConditional(!(f & ZF));
|
||||||
@@ -86,10 +88,12 @@ bool EightBit::Z80::jrConditionalFlag(uint8_t f, const int flag) {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled JR conditional");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
|
||||||
|
ASSUME(flag >= 0);
|
||||||
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 0: // NZ
|
case 0: // NZ
|
||||||
return jumpConditional(!(f & ZF));
|
return jumpConditional(!(f & ZF));
|
||||||
@@ -110,7 +114,7 @@ bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled JP conditional");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::retn() {
|
void EightBit::Z80::retn() {
|
||||||
@@ -123,6 +127,8 @@ void EightBit::Z80::reti() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::returnConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::returnConditionalFlag(uint8_t f, const int flag) {
|
||||||
|
ASSUME(flag >= 0);
|
||||||
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 0: // NZ
|
case 0: // NZ
|
||||||
return returnConditional(!(f & ZF));
|
return returnConditional(!(f & ZF));
|
||||||
@@ -143,10 +149,12 @@ bool EightBit::Z80::returnConditionalFlag(uint8_t f, const int flag) {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled RET conditional");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::callConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::callConditionalFlag(uint8_t f, const int flag) {
|
||||||
|
ASSUME(flag >= 0);
|
||||||
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 0: // NZ
|
case 0: // NZ
|
||||||
return callConditional(!(f & ZF));
|
return callConditional(!(f & ZF));
|
||||||
@@ -167,7 +175,7 @@ bool EightBit::Z80::callConditionalFlag(uint8_t f, const int flag) {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
throw std::logic_error("Unhandled CALL conditional");
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::sbc(uint8_t& f, register16_t& operand, const register16_t value) {
|
void EightBit::Z80::sbc(uint8_t& f, register16_t& operand, const register16_t value) {
|
||||||
@@ -190,7 +198,7 @@ void EightBit::Z80::sbc(uint8_t& f, register16_t& operand, const register16_t va
|
|||||||
setFlag(f, CF, result & Bit16);
|
setFlag(f, CF, result & Bit16);
|
||||||
adjustXY<Z80>(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
|
|
||||||
MEMPTR().word++;
|
++MEMPTR().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::adc(uint8_t& f, register16_t& operand, const register16_t value) {
|
void EightBit::Z80::adc(uint8_t& f, register16_t& operand, const register16_t value) {
|
||||||
@@ -213,7 +221,7 @@ void EightBit::Z80::adc(uint8_t& f, register16_t& operand, const register16_t va
|
|||||||
setFlag(f, CF, result & Bit16);
|
setFlag(f, CF, result & Bit16);
|
||||||
adjustXY<Z80>(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
|
|
||||||
MEMPTR().word++;
|
++MEMPTR().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::add(uint8_t& f, register16_t& operand, const register16_t value) {
|
void EightBit::Z80::add(uint8_t& f, register16_t& operand, const register16_t value) {
|
||||||
@@ -229,7 +237,7 @@ void EightBit::Z80::add(uint8_t& f, register16_t& operand, const register16_t va
|
|||||||
adjustHalfCarryAdd(f, MEMPTR().high, value.high, operand.high);
|
adjustHalfCarryAdd(f, MEMPTR().high, value.high, operand.high);
|
||||||
adjustXY<Z80>(f, operand.high);
|
adjustXY<Z80>(f, operand.high);
|
||||||
|
|
||||||
MEMPTR().word++;
|
++MEMPTR().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::add(uint8_t& f, uint8_t& operand, const uint8_t value, const int carry) {
|
void EightBit::Z80::add(uint8_t& f, uint8_t& operand, const uint8_t value, const int carry) {
|
||||||
@@ -368,6 +376,8 @@ uint8_t EightBit::Z80::srl(uint8_t& f, uint8_t operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::bit(uint8_t& f, int n, uint8_t operand) {
|
uint8_t EightBit::Z80::bit(uint8_t& f, int n, uint8_t operand) {
|
||||||
|
ASSUME(n >= 0);
|
||||||
|
ASSUME(n <= 7);
|
||||||
setFlag(f, HC);
|
setFlag(f, HC);
|
||||||
clearFlag(f, NF);
|
clearFlag(f, NF);
|
||||||
const auto discarded = operand & (1 << n);
|
const auto discarded = operand & (1 << n);
|
||||||
@@ -377,10 +387,14 @@ uint8_t EightBit::Z80::bit(uint8_t& f, int n, uint8_t operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::res(int n, const uint8_t operand) {
|
uint8_t EightBit::Z80::res(int n, const uint8_t operand) {
|
||||||
|
ASSUME(n >= 0);
|
||||||
|
ASSUME(n <= 7);
|
||||||
return operand & ~(1 << n);
|
return operand & ~(1 << n);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::set(int n, const uint8_t operand) {
|
uint8_t EightBit::Z80::set(int n, const uint8_t operand) {
|
||||||
|
ASSUME(n >= 0);
|
||||||
|
ASSUME(n <= 7);
|
||||||
return operand | (1 << n);
|
return operand | (1 << n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,18 +459,18 @@ void EightBit::Z80::ccf(const uint8_t a, uint8_t& f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::xhtl(register16_t& operand) {
|
void EightBit::Z80::xhtl(register16_t& operand) {
|
||||||
MEMPTR().low = getByte(SP());
|
MEMPTR().low = BUS().read(SP());
|
||||||
setByte(operand.low);
|
BUS().write(operand.low);
|
||||||
operand.low = MEMPTR().low;
|
operand.low = MEMPTR().low;
|
||||||
BUS().ADDRESS().word++;
|
++BUS().ADDRESS().word;
|
||||||
MEMPTR().high = getByte();
|
MEMPTR().high = BUS().read();
|
||||||
setByte(operand.high);
|
BUS().write(operand.high);
|
||||||
operand.high = MEMPTR().high;
|
operand.high = MEMPTR().high;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockCompare(const uint8_t a, uint8_t& f) {
|
void EightBit::Z80::blockCompare(const uint8_t a, uint8_t& f) {
|
||||||
|
|
||||||
const auto value = getByte(HL());
|
const auto value = BUS().read(HL());
|
||||||
uint8_t result = a - value;
|
uint8_t result = a - value;
|
||||||
|
|
||||||
setFlag(f, PF, --BC().word);
|
setFlag(f, PF, --BC().word);
|
||||||
@@ -473,14 +487,14 @@ void EightBit::Z80::blockCompare(const uint8_t a, uint8_t& f) {
|
|||||||
|
|
||||||
void EightBit::Z80::cpi(const uint8_t a, uint8_t& f) {
|
void EightBit::Z80::cpi(const uint8_t a, uint8_t& f) {
|
||||||
blockCompare(a, f);
|
blockCompare(a, f);
|
||||||
HL().word++;
|
++HL().word;
|
||||||
MEMPTR().word++;
|
++MEMPTR().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::cpd(const uint8_t a, uint8_t& f) {
|
void EightBit::Z80::cpd(const uint8_t a, uint8_t& f) {
|
||||||
blockCompare(a, f);
|
blockCompare(a, f);
|
||||||
HL().word--;
|
--HL().word;
|
||||||
MEMPTR().word--;
|
--MEMPTR().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::cpir(const uint8_t a, uint8_t& f) {
|
bool EightBit::Z80::cpir(const uint8_t a, uint8_t& f) {
|
||||||
@@ -488,7 +502,7 @@ bool EightBit::Z80::cpir(const uint8_t a, uint8_t& f) {
|
|||||||
MEMPTR() = PC();
|
MEMPTR() = PC();
|
||||||
const auto again = (f & PF) && !(f & ZF); // See CPI
|
const auto again = (f & PF) && !(f & ZF); // See CPI
|
||||||
if (LIKELY(again))
|
if (LIKELY(again))
|
||||||
MEMPTR().word--;
|
--MEMPTR().word;
|
||||||
return again;
|
return again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,13 +511,13 @@ bool EightBit::Z80::cpdr(const uint8_t a, uint8_t& f) {
|
|||||||
MEMPTR().word = PC().word - 1;
|
MEMPTR().word = PC().word - 1;
|
||||||
const auto again = (f & PF) && !(f & ZF); // See CPD
|
const auto again = (f & PF) && !(f & ZF); // See CPD
|
||||||
if (UNLIKELY(!again))
|
if (UNLIKELY(!again))
|
||||||
MEMPTR().word--;
|
--MEMPTR().word;
|
||||||
return again;
|
return again;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockLoad(const uint8_t a, uint8_t& f, const register16_t source, const register16_t destination) {
|
void EightBit::Z80::blockLoad(const uint8_t a, uint8_t& f, const register16_t source, const register16_t destination) {
|
||||||
const auto value = getByte(source);
|
const auto value = BUS().read(source);
|
||||||
setByte(destination, value);
|
BUS().write(destination, value);
|
||||||
const auto xy = a + value;
|
const auto xy = a + value;
|
||||||
setFlag(f, XF, xy & 8);
|
setFlag(f, XF, xy & 8);
|
||||||
setFlag(f, YF, xy & 2);
|
setFlag(f, YF, xy & 2);
|
||||||
@@ -513,14 +527,14 @@ void EightBit::Z80::blockLoad(const uint8_t a, uint8_t& f, const register16_t so
|
|||||||
|
|
||||||
void EightBit::Z80::ldd(const uint8_t a, uint8_t& f) {
|
void EightBit::Z80::ldd(const uint8_t a, uint8_t& f) {
|
||||||
blockLoad(a, f, HL(), DE());
|
blockLoad(a, f, HL(), DE());
|
||||||
HL().word--;
|
--HL().word;
|
||||||
DE().word--;
|
--DE().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::ldi(const uint8_t a, uint8_t& f) {
|
void EightBit::Z80::ldi(const uint8_t a, uint8_t& f) {
|
||||||
blockLoad(a, f, HL(), DE());
|
blockLoad(a, f, HL(), DE());
|
||||||
HL().word++;
|
++HL().word;
|
||||||
DE().word++;
|
++DE().word;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::ldir(const uint8_t a, uint8_t& f) {
|
bool EightBit::Z80::ldir(const uint8_t a, uint8_t& f) {
|
||||||
@@ -541,20 +555,20 @@ bool EightBit::Z80::lddr(const uint8_t a, uint8_t& f) {
|
|||||||
|
|
||||||
void EightBit::Z80::ini(uint8_t& f) {
|
void EightBit::Z80::ini(uint8_t& f) {
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR() = BUS().ADDRESS() = BC();
|
||||||
MEMPTR().word++;
|
++MEMPTR().word;
|
||||||
readPort();
|
readPort();
|
||||||
auto value = BUS().DATA();
|
const auto value = BUS().DATA();
|
||||||
setByte(HL().word++, value);
|
BUS().write(HL().word++, value);
|
||||||
decrement(f, B());
|
decrement(f, B());
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::ind(uint8_t& f) {
|
void EightBit::Z80::ind(uint8_t& f) {
|
||||||
MEMPTR() = BUS().ADDRESS() = BC();
|
MEMPTR() = BUS().ADDRESS() = BC();
|
||||||
MEMPTR().word--;
|
--MEMPTR().word;
|
||||||
readPort();
|
readPort();
|
||||||
auto value = BUS().DATA();
|
const auto value = BUS().DATA();
|
||||||
setByte(HL().word--, value);
|
BUS().write(HL().word--, value);
|
||||||
decrement(f, B());
|
decrement(f, B());
|
||||||
setFlag(f, NF);
|
setFlag(f, NF);
|
||||||
}
|
}
|
||||||
@@ -570,7 +584,7 @@ bool EightBit::Z80::indr(uint8_t& f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockOut(uint8_t& f) {
|
void EightBit::Z80::blockOut(uint8_t& f) {
|
||||||
const auto value = getByte();
|
const auto value = BUS().read();
|
||||||
BUS().ADDRESS() = BC();
|
BUS().ADDRESS() = BC();
|
||||||
writePort();
|
writePort();
|
||||||
decrement(f, B());
|
decrement(f, B());
|
||||||
@@ -602,20 +616,20 @@ bool EightBit::Z80::otdr(uint8_t& f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::rrd(uint8_t& a, uint8_t& f) {
|
void EightBit::Z80::rrd(uint8_t& a, uint8_t& f) {
|
||||||
BUS().ADDRESS() = MEMPTR() = HL();
|
MEMPTR() = BUS().ADDRESS() = HL();
|
||||||
const auto memory = getByte();
|
++MEMPTR().word;
|
||||||
MEMPTR().word++;
|
const auto memory = BUS().read();
|
||||||
setByte(promoteNibble(a) | highNibble(memory));
|
BUS().write(promoteNibble(a) | highNibble(memory));
|
||||||
a = (a & 0xf0) | lowNibble(memory);
|
a = (a & 0xf0) | lowNibble(memory);
|
||||||
adjustSZPXY<Z80>(f, a);
|
adjustSZPXY<Z80>(f, a);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::rld(uint8_t& a, uint8_t& f) {
|
void EightBit::Z80::rld(uint8_t& a, uint8_t& f) {
|
||||||
BUS().ADDRESS() = MEMPTR() = HL();
|
MEMPTR() = BUS().ADDRESS() = HL();
|
||||||
const auto memory = getByte();
|
++MEMPTR().word;
|
||||||
MEMPTR().word++;
|
const auto memory = BUS().read();
|
||||||
setByte(promoteNibble(memory) | lowNibble(a));
|
BUS().write(promoteNibble(memory) | lowNibble(a));
|
||||||
a = (a & 0xf0) | highNibble(memory);
|
a = (a & 0xf0) | highNibble(memory);
|
||||||
adjustSZPXY<Z80>(f, a);
|
adjustSZPXY<Z80>(f, a);
|
||||||
clearFlag(f, NF | HC);
|
clearFlag(f, NF | HC);
|
||||||
@@ -627,7 +641,7 @@ void EightBit::Z80::writePort(const uint8_t port, const uint8_t data) {
|
|||||||
MEMPTR() = BUS().ADDRESS();
|
MEMPTR() = BUS().ADDRESS();
|
||||||
BUS().placeDATA(data);
|
BUS().placeDATA(data);
|
||||||
writePort();
|
writePort();
|
||||||
MEMPTR().low++;
|
++MEMPTR().low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::writePort() {
|
void EightBit::Z80::writePort() {
|
||||||
@@ -640,7 +654,7 @@ void EightBit::Z80::readPort(const uint8_t port, uint8_t& a) {
|
|||||||
MEMPTR() = BUS().ADDRESS();
|
MEMPTR() = BUS().ADDRESS();
|
||||||
readPort();
|
readPort();
|
||||||
a = BUS().DATA();
|
a = BUS().DATA();
|
||||||
MEMPTR().low++;
|
++MEMPTR().low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::readPort() {
|
void EightBit::Z80::readPort() {
|
||||||
@@ -693,8 +707,7 @@ int EightBit::Z80::step() {
|
|||||||
|
|
||||||
int EightBit::Z80::execute(const uint8_t opcode) {
|
int EightBit::Z80::execute(const uint8_t opcode) {
|
||||||
|
|
||||||
if (UNLIKELY(raised(M1())))
|
ASSUME(lowered(M1()));
|
||||||
throw std::logic_error("M1 cannot be high");
|
|
||||||
|
|
||||||
if (LIKELY(!(m_prefixCB && m_displaced))) {
|
if (LIKELY(!(m_prefixCB && m_displaced))) {
|
||||||
++REFRESH();
|
++REFRESH();
|
||||||
@@ -726,16 +739,20 @@ int EightBit::Z80::execute(const uint8_t opcode) {
|
|||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(cycles() == 0))
|
ASSUME(cycles() > 0);
|
||||||
throw std::logic_error("Unhandled opcode");
|
|
||||||
|
|
||||||
return cycles();
|
return cycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y, const int z) {
|
void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y, const int z) {
|
||||||
|
ASSUME(x >= 0);
|
||||||
|
ASSUME(x <= 3);
|
||||||
|
ASSUME(y >= 0);
|
||||||
|
ASSUME(y <= 7);
|
||||||
|
ASSUME(z >= 0);
|
||||||
|
ASSUME(z <= 7);
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case 0: { // rot[y] r[z]
|
case 0: { // rot[y] r[z]
|
||||||
auto operand = LIKELY(!m_displaced) ? R(z, a) : getByte(displacedAddress());
|
auto operand = LIKELY(!m_displaced) ? R(z, a) : BUS().read(displacedAddress());
|
||||||
switch (y) {
|
switch (y) {
|
||||||
case 0:
|
case 0:
|
||||||
operand = rlc(f, operand);
|
operand = rlc(f, operand);
|
||||||
@@ -772,7 +789,7 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
} else {
|
} else {
|
||||||
if (LIKELY(z != 6))
|
if (LIKELY(z != 6))
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
setByte(operand);
|
BUS().write(operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
}
|
}
|
||||||
addCycles(8);
|
addCycles(8);
|
||||||
@@ -788,7 +805,7 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
adjustXY<Z80>(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bit(f, y, getByte(displacedAddress()));
|
bit(f, y, BUS().read(displacedAddress()));
|
||||||
adjustXY<Z80>(f, MEMPTR().high);
|
adjustXY<Z80>(f, MEMPTR().high);
|
||||||
addCycles(12);
|
addCycles(12);
|
||||||
}
|
}
|
||||||
@@ -800,9 +817,9 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
if (UNLIKELY(z == 6))
|
if (UNLIKELY(z == 6))
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
} else {
|
} else {
|
||||||
auto operand = getByte(displacedAddress());
|
auto operand = BUS().read(displacedAddress());
|
||||||
operand = res(y, operand);
|
operand = res(y, operand);
|
||||||
setByte(operand);
|
BUS().write(operand);
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
}
|
}
|
||||||
@@ -814,9 +831,9 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
if (UNLIKELY(z == 6))
|
if (UNLIKELY(z == 6))
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
} else {
|
} else {
|
||||||
auto operand = getByte(displacedAddress());
|
auto operand = BUS().read(displacedAddress());
|
||||||
operand = set(y, operand);
|
operand = set(y, operand);
|
||||||
setByte(operand);
|
BUS().write(operand);
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
}
|
}
|
||||||
@@ -827,6 +844,16 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y, const int z, const int p, const int q) {
|
void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y, const int z, const int p, const int q) {
|
||||||
|
ASSUME(x >= 0);
|
||||||
|
ASSUME(x <= 3);
|
||||||
|
ASSUME(y >= 0);
|
||||||
|
ASSUME(y <= 7);
|
||||||
|
ASSUME(z >= 0);
|
||||||
|
ASSUME(z <= 7);
|
||||||
|
ASSUME(p >= 0);
|
||||||
|
ASSUME(p <= 3);
|
||||||
|
ASSUME(q >= 0);
|
||||||
|
ASSUME(q <= 1);
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case 0:
|
case 0:
|
||||||
case 3: // Invalid instruction, equivalent to NONI followed by NOP
|
case 3: // Invalid instruction, equivalent to NONI followed by NOP
|
||||||
@@ -836,7 +863,7 @@ void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
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().word++;
|
++MEMPTR().word;
|
||||||
readPort();
|
readPort();
|
||||||
if (LIKELY(y != 6)) // IN r[y],(C)
|
if (LIKELY(y != 6)) // IN r[y],(C)
|
||||||
R(y, a, BUS().DATA());
|
R(y, a, BUS().DATA());
|
||||||
@@ -846,7 +873,7 @@ void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
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().word++;
|
++MEMPTR().word;
|
||||||
if (UNLIKELY(y == 6)) // OUT (C),0
|
if (UNLIKELY(y == 6)) // OUT (C),0
|
||||||
BUS().placeDATA(0);
|
BUS().placeDATA(0);
|
||||||
else // OUT (C),r[y]
|
else // OUT (C),r[y]
|
||||||
@@ -1061,6 +1088,16 @@ void EightBit::Z80::executeED(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int y, const int z, const int p, const int q) {
|
void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int y, const int z, const int p, const int q) {
|
||||||
|
ASSUME(x >= 0);
|
||||||
|
ASSUME(x <= 3);
|
||||||
|
ASSUME(y >= 0);
|
||||||
|
ASSUME(y <= 7);
|
||||||
|
ASSUME(z >= 0);
|
||||||
|
ASSUME(z <= 7);
|
||||||
|
ASSUME(p >= 0);
|
||||||
|
ASSUME(p <= 3);
|
||||||
|
ASSUME(q >= 0);
|
||||||
|
ASSUME(q <= 1);
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (z) {
|
switch (z) {
|
||||||
@@ -1113,14 +1150,16 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
case 0:
|
case 0:
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: // LD (BC),A
|
case 0: // LD (BC),A
|
||||||
MEMPTR() = BC();
|
MEMPTR() = BUS().ADDRESS() = BC();
|
||||||
setByte(MEMPTR().word++, a);
|
++MEMPTR().word;
|
||||||
|
BUS().write(a);
|
||||||
MEMPTR().high = a;
|
MEMPTR().high = a;
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD (DE),A
|
case 1: // LD (DE),A
|
||||||
MEMPTR() = DE();
|
MEMPTR() = BUS().ADDRESS() = DE();
|
||||||
setByte(MEMPTR().word++, a);
|
++MEMPTR().word;
|
||||||
|
BUS().write(a);
|
||||||
MEMPTR().high = a;
|
MEMPTR().high = a;
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
@@ -1130,8 +1169,9 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD (nn),A
|
case 3: // LD (nn),A
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = BUS().ADDRESS() = fetchWord();
|
||||||
setByte(MEMPTR().word++, a);
|
++MEMPTR().word;
|
||||||
|
BUS().write(a);
|
||||||
MEMPTR().high = a;
|
MEMPTR().high = a;
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
@@ -1142,13 +1182,15 @@ 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: // LD A,(BC)
|
case 0: // LD A,(BC)
|
||||||
MEMPTR() = BC();
|
MEMPTR() = BUS().ADDRESS() = BC();
|
||||||
a = getByte(MEMPTR().word++);
|
++MEMPTR().word;
|
||||||
|
a = BUS().read();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 1: // LD A,(DE)
|
case 1: // LD A,(DE)
|
||||||
MEMPTR() = DE();
|
MEMPTR() = BUS().ADDRESS() = DE();
|
||||||
a = getByte(MEMPTR().word++);
|
++MEMPTR().word;
|
||||||
|
a = BUS().read();
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
break;
|
break;
|
||||||
case 2: // LD HL,(nn)
|
case 2: // LD HL,(nn)
|
||||||
@@ -1157,8 +1199,9 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
addCycles(16);
|
addCycles(16);
|
||||||
break;
|
break;
|
||||||
case 3: // LD A,(nn)
|
case 3: // LD A,(nn)
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = BUS().ADDRESS() = fetchWord();
|
||||||
a = getByte(MEMPTR().word++);
|
++MEMPTR().word;
|
||||||
|
a = BUS().read();
|
||||||
addCycles(13);
|
addCycles(13);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -12,6 +12,7 @@ namespace EightBit {
|
|||||||
int countBits(uint8_t value);
|
int countBits(uint8_t value);
|
||||||
bool oddParity(uint8_t value);
|
bool oddParity(uint8_t value);
|
||||||
int findFirstSet(int value);
|
int findFirstSet(int value);
|
||||||
|
void assume(int expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -47,6 +48,19 @@ inline int EightBit::findFirstSet(int value) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void EightBit::assume(int expression) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__assume(expression);
|
||||||
|
#elif defined(__GNUG__)
|
||||||
|
if (!expression)
|
||||||
|
__builtin_unreachable();
|
||||||
|
#else
|
||||||
|
assert(expression);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSUME(x) EightBit::assume(x)
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
# define LIKELY(x) (x)
|
# define LIKELY(x) (x)
|
||||||
@@ -54,7 +68,7 @@ inline int EightBit::findFirstSet(int value) {
|
|||||||
|
|
||||||
# define PARITY(x) (__popcnt(x) % 2)
|
# define PARITY(x) (__popcnt(x) % 2)
|
||||||
|
|
||||||
# define UNREACHABLE __assume(0)
|
# define UNREACHABLE ASSUME(0)
|
||||||
|
|
||||||
#elif defined(__GNUG__)
|
#elif defined(__GNUG__)
|
||||||
|
|
||||||
@@ -63,7 +77,7 @@ inline int EightBit::findFirstSet(int value) {
|
|||||||
|
|
||||||
# define PARITY(x) __builtin_parity(x)
|
# define PARITY(x) __builtin_parity(x)
|
||||||
|
|
||||||
# define UNREACHABLE __builtin_unreachable();
|
# define UNREACHABLE __builtin_unreachable();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -72,6 +86,6 @@ inline int EightBit::findFirstSet(int value) {
|
|||||||
|
|
||||||
# define PARITY(x) EightBit::oddParity(x)
|
# define PARITY(x) EightBit::oddParity(x)
|
||||||
|
|
||||||
# define UNREACHABLE
|
# define UNREACHABLE ASSUME(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -107,7 +107,7 @@ namespace EightBit {
|
|||||||
void proceed() { ++PC().word; raise(HALT()); }
|
void proceed() { ++PC().word; raise(HALT()); }
|
||||||
|
|
||||||
uint8_t fetchByte() {
|
uint8_t fetchByte() {
|
||||||
return getByte(PC().word++);
|
return BUS().read(PC().word++);
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t fetchWord() {
|
register16_t fetchWord() {
|
||||||
@@ -117,12 +117,6 @@ namespace EightBit {
|
|||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getByte() { return BUS().read(); }
|
|
||||||
template<class T> uint8_t getByte(T offset) { return BUS().read(offset); }
|
|
||||||
|
|
||||||
void setByte(uint8_t value) { BUS().write(value); }
|
|
||||||
template<class T> void setByte(T offset, uint8_t value) { BUS().write(offset, value); }
|
|
||||||
|
|
||||||
virtual void push(uint8_t value) = 0;
|
virtual void push(uint8_t value) = 0;
|
||||||
virtual uint8_t pop() = 0;
|
virtual uint8_t pop() = 0;
|
||||||
|
|
||||||
|
@@ -17,9 +17,8 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fire(const T& e) const {
|
void fire(const T& e) const {
|
||||||
if (!m_delegates.empty())
|
for (auto& delegate : m_delegates)
|
||||||
for (auto& delegate : m_delegates)
|
delegate(e);
|
||||||
delegate(e);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -13,23 +13,21 @@ void EightBit::IntelProcessor::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::push(uint8_t value) {
|
void EightBit::IntelProcessor::push(uint8_t value) {
|
||||||
setByte(--SP().word, value);
|
BUS().write(--SP().word, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::IntelProcessor::pop() {
|
uint8_t EightBit::IntelProcessor::pop() {
|
||||||
return getByte(SP().word++);
|
return BUS().read(SP().word++);
|
||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
||||||
register16_t returned;
|
register16_t returned;
|
||||||
returned.low = getByte(MEMPTR().word++);
|
returned.low = BUS().read(MEMPTR().word++);
|
||||||
BUS().ADDRESS().word++;
|
returned.high = BUS().read(++BUS().ADDRESS().word);
|
||||||
returned.high = getByte();
|
|
||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::setWord(register16_t value) {
|
void EightBit::IntelProcessor::setWord(register16_t value) {
|
||||||
setByte(MEMPTR().word++, value.low);
|
BUS().write(MEMPTR().word++, value.low);
|
||||||
BUS().ADDRESS().word++;
|
BUS().write(++BUS().ADDRESS().word, value.high);
|
||||||
setByte(value.high);
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user