Move to an event driven clock tick event for all CPUs

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-01-09 23:24:33 +00:00
parent 8b187e7614
commit 68030610d8
7 changed files with 502 additions and 499 deletions

View File

@ -26,7 +26,7 @@ EightBit::register16_t& EightBit::Intel8080::HL() {
void EightBit::Intel8080::handleRESET() { void EightBit::Intel8080::handleRESET() {
IntelProcessor::handleRESET(); IntelProcessor::handleRESET();
di(); di();
addCycles(3); tick(3);
} }
@ -37,7 +37,7 @@ void EightBit::Intel8080::handleINT() {
di(); di();
Processor::execute(BUS().DATA()); Processor::execute(BUS().DATA());
} }
addCycles(3); tick(3);
} }
void EightBit::Intel8080::di() { void EightBit::Intel8080::di() {
@ -308,7 +308,7 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
case 0: // Relative jumps and assorted ops case 0: // Relative jumps and assorted ops
switch (y) { switch (y) {
case 0: // NOP case 0: // NOP
addCycles(4); tick(4);
break; break;
} }
break; break;
@ -316,11 +316,11 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
switch (q) { switch (q) {
case 0: // LD rp,nn case 0: // LD rp,nn
RP(p) = fetchWord(); RP(p) = fetchWord();
addCycles(10); tick(10);
break; break;
case 1: // ADD HL,rp case 1: // ADD HL,rp
add(RP(p)); add(RP(p));
addCycles(11); tick(11);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -332,21 +332,21 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
switch (p) { switch (p) {
case 0: // LD (BC),A case 0: // LD (BC),A
BUS().write(BC(), A()); BUS().write(BC(), A());
addCycles(7); tick(7);
break; break;
case 1: // LD (DE),A case 1: // LD (DE),A
BUS().write(DE(), A()); BUS().write(DE(), A());
addCycles(7); tick(7);
break; break;
case 2: // LD (nn),HL case 2: // LD (nn),HL
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
setWord(HL()); setWord(HL());
addCycles(16); tick(16);
break; break;
case 3: // LD (nn),A case 3: // LD (nn),A
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
BUS().write(A()); BUS().write(A());
addCycles(13); tick(13);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -356,21 +356,21 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
switch (p) { switch (p) {
case 0: // LD A,(BC) case 0: // LD A,(BC)
A() = BUS().read(BC()); A() = BUS().read(BC());
addCycles(7); tick(7);
break; break;
case 1: // LD A,(DE) case 1: // LD A,(DE)
A() = BUS().read(DE()); A() = BUS().read(DE());
addCycles(7); tick(7);
break; break;
case 2: // LD HL,(nn) case 2: // LD HL,(nn)
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
HL() = getWord(); HL() = getWord();
addCycles(16); tick(16);
break; break;
case 3: // LD A,(nn) case 3: // LD A,(nn)
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
A() = BUS().read(); A() = BUS().read();
addCycles(13); tick(13);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -391,27 +391,27 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(6); tick(6);
break; break;
case 4: { // 8-bit INC case 4: { // 8-bit INC
auto operand = R(y); auto operand = R(y);
increment(operand); increment(operand);
R(y, operand); R(y, operand);
addCycles(4); tick(4);
break; break;
} case 5: { // 8-bit DEC } case 5: { // 8-bit DEC
auto operand = R(y); auto operand = R(y);
decrement(operand); decrement(operand);
R(y, operand); R(y, operand);
addCycles(4); tick(4);
if (UNLIKELY(y == 6)) if (UNLIKELY(y == 6))
addCycles(7); tick(7);
break; break;
} case 6: // 8-bit load immediate } case 6: // 8-bit load immediate
R(y, fetchByte()); R(y, fetchByte());
addCycles(7); tick(7);
if (UNLIKELY(y == 6)) if (UNLIKELY(y == 6))
addCycles(3); tick(3);
break; break;
case 7: // Assorted operations on accumulator/flags case 7: // Assorted operations on accumulator/flags
switch (y) { switch (y) {
@ -442,7 +442,7 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -454,9 +454,9 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
} else { } else {
R(y, R(z)); R(y, R(z));
if (UNLIKELY((y == 6) || (z == 6))) // M operations if (UNLIKELY((y == 6) || (z == 6))) // M operations
addCycles(3); tick(3);
} }
addCycles(4); tick(4);
break; break;
case 2: // Operate on accumulator and register/memory location case 2: // Operate on accumulator and register/memory location
switch (y) { switch (y) {
@ -487,36 +487,36 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(4); tick(4);
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycles(3); tick(3);
break; break;
case 3: case 3:
switch (z) { switch (z) {
case 0: // Conditional return case 0: // Conditional return
if (returnConditionalFlag(y)) if (returnConditionalFlag(y))
addCycles(6); tick(6);
addCycles(5); tick(5);
break; break;
case 1: // POP & various ops case 1: // POP & various ops
switch (q) { switch (q) {
case 0: // POP rp2[p] case 0: // POP rp2[p]
RP2(p) = popWord(); RP2(p) = popWord();
addCycles(10); tick(10);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // RET case 0: // RET
ret(); ret();
addCycles(10); tick(10);
break; break;
case 2: // JP HL case 2: // JP HL
jump(HL()); jump(HL());
addCycles(4); tick(4);
break; break;
case 3: // LD SP,HL case 3: // LD SP,HL
SP() = HL(); SP() = HL();
addCycles(4); tick(4);
break; break;
} }
break; break;
@ -526,56 +526,56 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
break; break;
case 2: // Conditional jump case 2: // Conditional jump
jumpConditionalFlag(y); jumpConditionalFlag(y);
addCycles(10); tick(10);
break; break;
case 3: // Assorted operations case 3: // Assorted operations
switch (y) { switch (y) {
case 0: // JP nn case 0: // JP nn
jump(fetchWord()); jump(fetchWord());
addCycles(10); tick(10);
break; break;
case 2: // OUT (n),A case 2: // OUT (n),A
writePort(fetchByte()); writePort(fetchByte());
addCycles(11); tick(11);
break; break;
case 3: // IN A,(n) case 3: // IN A,(n)
A() = readPort(fetchByte()); A() = readPort(fetchByte());
addCycles(11); tick(11);
break; break;
case 4: // EX (SP),HL case 4: // EX (SP),HL
xhtl(); xhtl();
addCycles(19); tick(19);
break; break;
case 5: // EX DE,HL case 5: // EX DE,HL
std::swap(DE(), HL()); std::swap(DE(), HL());
addCycles(4); tick(4);
break; break;
case 6: // DI case 6: // DI
di(); di();
addCycles(4); tick(4);
break; break;
case 7: // EI case 7: // EI
ei(); ei();
addCycles(4); tick(4);
break; break;
} }
break; break;
case 4: // Conditional call: CALL cc[y], nn case 4: // Conditional call: CALL cc[y], nn
if (callConditionalFlag(y)) if (callConditionalFlag(y))
addCycles(7); tick(7);
addCycles(10); tick(10);
break; break;
case 5: // PUSH & various ops case 5: // PUSH & various ops
switch (q) { switch (q) {
case 0: // PUSH rp2[p] case 0: // PUSH rp2[p]
pushWord(RP2(p)); pushWord(RP2(p));
addCycles(11); tick(11);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // CALL nn case 0: // CALL nn
call(fetchWord()); call(fetchWord());
addCycles(17); tick(17);
break; break;
} }
break; break;
@ -612,11 +612,11 @@ void EightBit::Intel8080::execute(const int x, const int y, const int z, const i
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(7); tick(7);
break; break;
case 7: // Restart: RST y * 8 case 7: // Restart: RST y * 8
restart(y << 3); restart(y << 3);
addCycles(11); tick(11);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;

View File

@ -30,7 +30,7 @@ void EightBit::GameBoy::LR35902::handleRESET() {
IntelProcessor::handleRESET(); IntelProcessor::handleRESET();
di(); di();
SP() = Mask16 - 1; SP() = Mask16 - 1;
addCycles(4); tick(4);
} }
void EightBit::GameBoy::LR35902::handleINT() { void EightBit::GameBoy::LR35902::handleINT() {
@ -38,7 +38,7 @@ void EightBit::GameBoy::LR35902::handleINT() {
raise(HALT()); raise(HALT());
di(); di();
restart(BUS().DATA()); restart(BUS().DATA());
addCycles(4); tick(4);
} }
void EightBit::GameBoy::LR35902::di() { void EightBit::GameBoy::LR35902::di() {
@ -393,29 +393,29 @@ void EightBit::GameBoy::LR35902::executeCB(const int x, const int y, const int z
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(2); tick(2);
R(z, operand); R(z, operand);
adjustZero<LR35902>(F(), operand); adjustZero<LR35902>(F(), operand);
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycles(2); tick(2);
break; break;
} case 1: // BIT y, r[z] } case 1: // BIT y, r[z]
bit(y, R(z)); bit(y, R(z));
addCycles(2); tick(2);
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycles(2); tick(2);
break; break;
case 2: // RES y, r[z] case 2: // RES y, r[z]
R(z, res(y, R(z))); R(z, res(y, R(z)));
addCycles(2); tick(2);
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycles(2); tick(2);
break; break;
case 3: // SET y, r[z] case 3: // SET y, r[z]
R(z, set(y, R(z))); R(z, set(y, R(z)));
addCycles(2); tick(2);
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -429,28 +429,28 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
case 0: // Relative jumps and assorted ops case 0: // Relative jumps and assorted ops
switch (y) { switch (y) {
case 0: // NOP case 0: // NOP
addCycle(); tick();
break; break;
case 1: // GB: LD (nn),SP case 1: // GB: LD (nn),SP
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
setWord(SP()); setWord(SP());
addCycles(5); tick(5);
break; break;
case 2: // GB: STOP case 2: // GB: STOP
stop(); stop();
addCycle(); tick();
break; break;
case 3: // JR d case 3: // JR d
jr(fetchByte()); jr(fetchByte());
addCycles(4); tick(4);
break; break;
case 4: // JR cc,d case 4: // JR cc,d
case 5: case 5:
case 6: case 6:
case 7: case 7:
if (jrConditionalFlag(y - 4)) if (jrConditionalFlag(y - 4))
addCycle(); tick();
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -460,11 +460,11 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
switch (q) { switch (q) {
case 0: // LD rp,nn case 0: // LD rp,nn
RP(p) = fetchWord(); RP(p) = fetchWord();
addCycles(3); tick(3);
break; break;
case 1: // ADD HL,rp case 1: // ADD HL,rp
add(HL(), RP(p)); add(HL(), RP(p));
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -476,19 +476,19 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
switch (p) { switch (p) {
case 0: // LD (BC),A case 0: // LD (BC),A
BUS().write(BC(), A()); BUS().write(BC(), A());
addCycles(2); tick(2);
break; break;
case 1: // LD (DE),A case 1: // LD (DE),A
BUS().write(DE(), A()); BUS().write(DE(), A());
addCycles(2); tick(2);
break; break;
case 2: // GB: LDI (HL),A case 2: // GB: LDI (HL),A
BUS().write(HL()++, A()); BUS().write(HL()++, A());
addCycles(2); tick(2);
break; break;
case 3: // GB: LDD (HL),A case 3: // GB: LDD (HL),A
BUS().write(HL()--, A()); BUS().write(HL()--, A());
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -498,19 +498,19 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
switch (p) { switch (p) {
case 0: // LD A,(BC) case 0: // LD A,(BC)
A() = BUS().read(BC()); A() = BUS().read(BC());
addCycles(2); tick(2);
break; break;
case 1: // LD A,(DE) case 1: // LD A,(DE)
A() = BUS().read(DE()); A() = BUS().read(DE());
addCycles(2); tick(2);
break; break;
case 2: // GB: LDI A,(HL) case 2: // GB: LDI A,(HL)
A() = BUS().read(HL()++); A() = BUS().read(HL()++);
addCycles(2); tick(2);
break; break;
case 3: // GB: LDD A,(HL) case 3: // GB: LDD A,(HL)
A() = BUS().read(HL()--); A() = BUS().read(HL()--);
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -531,27 +531,27 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(2); tick(2);
break; break;
case 4: { // 8-bit INC case 4: { // 8-bit INC
auto operand = R(y); auto operand = R(y);
increment(operand); increment(operand);
R(y, operand); R(y, operand);
addCycle(); tick();
if (UNLIKELY(y == 6)) if (UNLIKELY(y == 6))
addCycles(2); tick(2);
break; break;
} case 5: { // 8-bit DEC } case 5: { // 8-bit DEC
auto operand = R(y); auto operand = R(y);
decrement(operand); decrement(operand);
R(y, operand); R(y, operand);
addCycle(); tick();
if (UNLIKELY(y == 6)) if (UNLIKELY(y == 6))
addCycles(2); tick(2);
break; break;
} case 6: // 8-bit load immediate } case 6: // 8-bit load immediate
R(y, fetchByte()); // LD r,n R(y, fetchByte()); // LD r,n
addCycles(2); tick(2);
break; break;
case 7: // Assorted operations on accumulator/flags case 7: // Assorted operations on accumulator/flags
switch (y) { switch (y) {
@ -582,7 +582,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycle(); tick();
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -594,9 +594,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
} else { } else {
R(y, R(z)); R(y, R(z));
if (UNLIKELY((y == 6) || (z == 6))) // M operations if (UNLIKELY((y == 6) || (z == 6))) // M operations
addCycle(); tick();
} }
addCycle(); tick();
break; break;
case 2: // Operate on accumulator and register/memory location case 2: // Operate on accumulator and register/memory location
switch (y) { switch (y) {
@ -627,9 +627,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycle(); tick();
if (UNLIKELY(z == 6)) if (UNLIKELY(z == 6))
addCycle(); tick();
break; break;
case 3: case 3:
switch (z) { switch (z) {
@ -640,12 +640,12 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
case 2: case 2:
case 3: case 3:
if (returnConditionalFlag(y)) if (returnConditionalFlag(y))
addCycles(3); tick(3);
addCycles(2); tick(2);
break; break;
case 4: // GB: LD (FF00 + n),A case 4: // GB: LD (FF00 + n),A
BUS().write(IoRegisters::BASE + fetchByte(), A()); BUS().write(IoRegisters::BASE + fetchByte(), A());
addCycles(3); tick(3);
break; break;
case 5: { // GB: ADD SP,dd case 5: { // GB: ADD SP,dd
const auto before = SP().word; const auto before = SP().word;
@ -657,11 +657,11 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
setFlag(F(), CF, carried & Bit8); setFlag(F(), CF, carried & Bit8);
setFlag(F(), HC, carried & Bit4); setFlag(F(), HC, carried & Bit4);
} }
addCycles(4); tick(4);
break; break;
case 6: // GB: LD A,(FF00 + n) case 6: // GB: LD A,(FF00 + n)
A() = BUS().read(IoRegisters::BASE + fetchByte()); A() = BUS().read(IoRegisters::BASE + fetchByte());
addCycles(3); tick(3);
break; break;
case 7: { // GB: LD HL,SP + dd case 7: { // GB: LD HL,SP + dd
const auto before = SP().word; const auto before = SP().word;
@ -673,7 +673,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
setFlag(F(), CF, carried & Bit8); setFlag(F(), CF, carried & Bit8);
setFlag(F(), HC, carried & Bit4); setFlag(F(), HC, carried & Bit4);
} }
addCycles(3); tick(3);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -683,25 +683,25 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
switch (q) { switch (q) {
case 0: // POP rp2[p] case 0: // POP rp2[p]
RP2(p) = popWord(); RP2(p) = popWord();
addCycles(3); tick(3);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // RET case 0: // RET
ret(); ret();
addCycles(4); tick(4);
break; break;
case 1: // GB: RETI case 1: // GB: RETI
reti(); reti();
addCycles(4); tick(4);
break; break;
case 2: // JP HL case 2: // JP HL
jump(HL()); jump(HL());
addCycle(); tick();
break; break;
case 3: // LD SP,HL case 3: // LD SP,HL
SP() = HL(); SP() = HL();
addCycles(2); tick(2);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -718,25 +718,25 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
case 2: case 2:
case 3: case 3:
jumpConditionalFlag(y); jumpConditionalFlag(y);
addCycles(3); tick(3);
break; break;
case 4: // GB: LD (FF00 + C),A case 4: // GB: LD (FF00 + C),A
BUS().write(IoRegisters::BASE + C(), A()); BUS().write(IoRegisters::BASE + C(), A());
addCycles(2); tick(2);
break; break;
case 5: // GB: LD (nn),A case 5: // GB: LD (nn),A
BUS().ADDRESS() = MEMPTR() = fetchWord(); BUS().ADDRESS() = MEMPTR() = fetchWord();
BUS().write(A()); BUS().write(A());
addCycles(4); tick(4);
break; break;
case 6: // GB: LD A,(FF00 + C) case 6: // GB: LD A,(FF00 + C)
A() = BUS().read(IoRegisters::BASE + C()); A() = BUS().read(IoRegisters::BASE + C());
addCycles(2); tick(2);
break; break;
case 7: // GB: LD A,(nn) case 7: // GB: LD A,(nn)
BUS().ADDRESS() = MEMPTR() = fetchWord(); BUS().ADDRESS() = MEMPTR() = fetchWord();
A() = BUS().read(); A() = BUS().read();
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -746,7 +746,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
switch (y) { switch (y) {
case 0: // JP nn case 0: // JP nn
jump(MEMPTR() = fetchWord()); jump(MEMPTR() = fetchWord());
addCycles(4); tick(4);
break; break;
case 1: // CB prefix case 1: // CB prefix
m_prefixCB = true; m_prefixCB = true;
@ -754,30 +754,30 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
break; break;
case 6: // DI case 6: // DI
di(); di();
addCycle(); tick();
break; break;
case 7: // EI case 7: // EI
ei(); ei();
addCycle(); tick();
break; break;
} }
break; break;
case 4: // Conditional call: CALL cc[y], nn case 4: // Conditional call: CALL cc[y], nn
if (callConditionalFlag(y)) if (callConditionalFlag(y))
addCycles(3); tick(3);
addCycles(3); tick(3);
break; break;
case 5: // PUSH & various ops case 5: // PUSH & various ops
switch (q) { switch (q) {
case 0: // PUSH rp2[p] case 0: // PUSH rp2[p]
pushWord(RP2(p)); pushWord(RP2(p));
addCycles(4); tick(4);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // CALL nn case 0: // CALL nn
call(MEMPTR() = fetchWord()); call(MEMPTR() = fetchWord());
addCycles(6); tick(6);
break; break;
} }
break; break;
@ -814,11 +814,11 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(2); tick(2);
break; break;
case 7: // Restart: RST y * 8 case 7: // Restart: RST y * 8
restart(y << 3); restart(y << 3);
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;

View File

@ -23,7 +23,7 @@ int EightBit::MOS6502::step() {
resetCycles(); resetCycles();
ExecutingInstruction.fire(*this); ExecutingInstruction.fire(*this);
if (LIKELY(powered())) { if (LIKELY(powered())) {
addCycle(); tick();
if (UNLIKELY(lowered(SO()))) if (UNLIKELY(lowered(SO())))
handleSO(); handleSO();
if (LIKELY(raised(RDY()))) { if (LIKELY(raised(RDY()))) {
@ -91,12 +91,12 @@ void EightBit::MOS6502::interrupt() {
// //
void EightBit::MOS6502::busWrite() { void EightBit::MOS6502::busWrite() {
addCycle(); tick();
Processor::busWrite(); Processor::busWrite();
} }
uint8_t EightBit::MOS6502::busRead() { uint8_t EightBit::MOS6502::busRead() {
addCycle(); tick();
return Processor::busRead(); return Processor::busRead();
} }
@ -396,7 +396,7 @@ uint8_t EightBit::MOS6502::pop() {
} }
void EightBit::MOS6502::dummyPush(const uint8_t value) { void EightBit::MOS6502::dummyPush(const uint8_t value) {
addCycle(); tick();
BUS().DATA() = value; BUS().DATA() = value;
BUS().ADDRESS() = register16_t(S()--, 1); BUS().ADDRESS() = register16_t(S()--, 1);
} }

View File

@ -295,7 +295,7 @@ namespace EightBit {
void branchLong(const int condition) { void branchLong(const int condition) {
if (branch(Address_relative_word(), condition)) if (branch(Address_relative_word(), condition))
addCycle(); tick();
} }
// Miscellaneous // Miscellaneous

View File

@ -51,7 +51,7 @@ void EightBit::mc6809::handleRESET() {
setFlag(CC(), IF); // Disable IRQ setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ setFlag(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, RESETvector)); jump(getWordPaged(0xff, RESETvector));
addCycles(10); tick(10);
} }
void EightBit::mc6809::handleNMI() { void EightBit::mc6809::handleNMI() {
@ -62,7 +62,7 @@ void EightBit::mc6809::handleNMI() {
setFlag(CC(), IF); // Disable IRQ setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ setFlag(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, NMIvector)); jump(getWordPaged(0xff, NMIvector));
addCycles(12); tick(12);
} }
void EightBit::mc6809::handleIRQ() { void EightBit::mc6809::handleIRQ() {
@ -72,7 +72,7 @@ void EightBit::mc6809::handleIRQ() {
saveEntireRegisterState(); saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ setFlag(CC(), IF); // Disable IRQ
jump(getWordPaged(0xff, IRQvector)); jump(getWordPaged(0xff, IRQvector));
addCycles(12); tick(12);
} }
void EightBit::mc6809::handleFIRQ() { void EightBit::mc6809::handleFIRQ() {
@ -83,7 +83,7 @@ void EightBit::mc6809::handleFIRQ() {
setFlag(CC(), IF); // Disable IRQ setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ setFlag(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, FIRQvector)); jump(getWordPaged(0xff, FIRQvector));
addCycles(12); tick(12);
} }
// //
@ -116,359 +116,359 @@ void EightBit::mc6809::executeUnprefixed() {
case 0x11: m_prefix11 = true; Processor::execute(fetchByte()); break; case 0x11: m_prefix11 = true; Processor::execute(fetchByte()); break;
// ABX // ABX
case 0x3a: addCycles(3); X() += B(); break; // ABX (inherent) case 0x3a: tick(3); X() += B(); break; // ABX (inherent)
// ADC // ADC
case 0x89: addCycles(2); A() = adc(A(), AM_immediate_byte()); break; // ADC (ADCA immediate) case 0x89: tick(2); A() = adc(A(), AM_immediate_byte()); break; // ADC (ADCA immediate)
case 0x99: addCycles(4); A() = adc(A(), AM_direct_byte()); break; // ADC (ADCA direct) case 0x99: tick(4); A() = adc(A(), AM_direct_byte()); break; // ADC (ADCA direct)
case 0xa9: addCycles(4); A() = adc(A(), AM_indexed_byte()); break; // ADC (ADCA indexed) case 0xa9: tick(4); A() = adc(A(), AM_indexed_byte()); break; // ADC (ADCA indexed)
case 0xb9: addCycles(4); A() = adc(A(), AM_extended_byte()); break; // ADC (ADCA extended) case 0xb9: tick(4); A() = adc(A(), AM_extended_byte()); break; // ADC (ADCA extended)
case 0xc9: addCycles(2); B() = adc(B(), AM_immediate_byte()); break; // ADC (ADCB immediate) case 0xc9: tick(2); B() = adc(B(), AM_immediate_byte()); break; // ADC (ADCB immediate)
case 0xd9: addCycles(4); B() = adc(B(), AM_direct_byte()); break; // ADC (ADCB direct) case 0xd9: tick(4); B() = adc(B(), AM_direct_byte()); break; // ADC (ADCB direct)
case 0xe9: addCycles(4); B() = adc(B(), AM_indexed_byte()); break; // ADC (ADCB indexed) case 0xe9: tick(4); B() = adc(B(), AM_indexed_byte()); break; // ADC (ADCB indexed)
case 0xf9: addCycles(4); B() = adc(B(), AM_extended_byte()); break; // ADC (ADCB extended) case 0xf9: tick(4); B() = adc(B(), AM_extended_byte()); break; // ADC (ADCB extended)
// ADD // ADD
case 0x8b: addCycles(2); A() = add(A(), AM_immediate_byte()); break; // ADD (ADDA immediate) case 0x8b: tick(2); A() = add(A(), AM_immediate_byte()); break; // ADD (ADDA immediate)
case 0x9b: addCycles(4); A() = add(A(), AM_direct_byte()); break; // ADD (ADDA direct) case 0x9b: tick(4); A() = add(A(), AM_direct_byte()); break; // ADD (ADDA direct)
case 0xab: addCycles(4); A() = add(A(), AM_indexed_byte()); break; // ADD (ADDA indexed) case 0xab: tick(4); A() = add(A(), AM_indexed_byte()); break; // ADD (ADDA indexed)
case 0xbb: addCycles(5); A() = add(A(), AM_extended_byte()); break; // ADD (ADDA extended) case 0xbb: tick(5); A() = add(A(), AM_extended_byte()); break; // ADD (ADDA extended)
case 0xcb: addCycles(2); B() = add(B(), AM_immediate_byte()); break; // ADD (ADDB immediate) case 0xcb: tick(2); B() = add(B(), AM_immediate_byte()); break; // ADD (ADDB immediate)
case 0xdb: addCycles(4); B() = add(B(), AM_direct_byte()); break; // ADD (ADDB direct) case 0xdb: tick(4); B() = add(B(), AM_direct_byte()); break; // ADD (ADDB direct)
case 0xeb: addCycles(4); B() = add(B(), AM_indexed_byte()); break; // ADD (ADDB indexed) case 0xeb: tick(4); B() = add(B(), AM_indexed_byte()); break; // ADD (ADDB indexed)
case 0xfb: addCycles(5); B() = add(B(), AM_extended_byte()); break; // ADD (ADDB extended) case 0xfb: tick(5); B() = add(B(), AM_extended_byte()); break; // ADD (ADDB extended)
case 0xc3: addCycles(4); D() = add(D(), AM_immediate_word()); break; // ADD (ADDD immediate) case 0xc3: tick(4); D() = add(D(), AM_immediate_word()); break; // ADD (ADDD immediate)
case 0xd3: addCycles(6); D() = add(D(), AM_direct_word()); break; // ADD (ADDD direct) case 0xd3: tick(6); D() = add(D(), AM_direct_word()); break; // ADD (ADDD direct)
case 0xe3: addCycles(6); D() = add(D(), AM_indexed_word()); break; // ADD (ADDD indexed) case 0xe3: tick(6); D() = add(D(), AM_indexed_word()); break; // ADD (ADDD indexed)
case 0xf3: addCycles(7); D() = add(D(), AM_extended_word()); break; // ADD (ADDD extended) case 0xf3: tick(7); D() = add(D(), AM_extended_word()); break; // ADD (ADDD extended)
// AND // AND
case 0x84: addCycles(2); A() = andr(A(), AM_immediate_byte()); break; // AND (ANDA immediate) case 0x84: tick(2); A() = andr(A(), AM_immediate_byte()); break; // AND (ANDA immediate)
case 0x94: addCycles(4); A() = andr(A(), AM_direct_byte()); break; // AND (ANDA direct) case 0x94: tick(4); A() = andr(A(), AM_direct_byte()); break; // AND (ANDA direct)
case 0xa4: addCycles(4); A() = andr(A(), AM_indexed_byte()); break; // AND (ANDA indexed) case 0xa4: tick(4); A() = andr(A(), AM_indexed_byte()); break; // AND (ANDA indexed)
case 0xb4: addCycles(5); A() = andr(A(), AM_extended_byte()); break; // AND (ANDA extended) case 0xb4: tick(5); A() = andr(A(), AM_extended_byte()); break; // AND (ANDA extended)
case 0xc4: addCycles(2); B() = andr(B(), AM_immediate_byte()); break; // AND (ANDB immediate) case 0xc4: tick(2); B() = andr(B(), AM_immediate_byte()); break; // AND (ANDB immediate)
case 0xd4: addCycles(4); B() = andr(B(), AM_direct_byte()); break; // AND (ANDB direct) case 0xd4: tick(4); B() = andr(B(), AM_direct_byte()); break; // AND (ANDB direct)
case 0xe4: addCycles(4); B() = andr(B(), AM_indexed_byte()); break; // AND (ANDB indexed) case 0xe4: tick(4); B() = andr(B(), AM_indexed_byte()); break; // AND (ANDB indexed)
case 0xf4: addCycles(5); B() = andr(B(), AM_extended_byte()); break; // AND (ANDB extended) case 0xf4: tick(5); B() = andr(B(), AM_extended_byte()); break; // AND (ANDB extended)
case 0x1c: addCycles(3); CC() &= AM_immediate_byte(); break; // AND (ANDCC immediate) case 0x1c: tick(3); CC() &= AM_immediate_byte(); break; // AND (ANDCC immediate)
// ASL/LSL // ASL/LSL
case 0x08: addCycles(6); BUS().write(asl(AM_direct_byte())); break; // ASL (direct) case 0x08: tick(6); BUS().write(asl(AM_direct_byte())); break; // ASL (direct)
case 0x48: addCycles(2); A() = asl(A()); break; // ASL (ASLA inherent) case 0x48: tick(2); A() = asl(A()); break; // ASL (ASLA inherent)
case 0x58: addCycles(2); B() = asl(B()); break; // ASL (ASLB inherent) case 0x58: tick(2); B() = asl(B()); break; // ASL (ASLB inherent)
case 0x68: addCycles(6); BUS().write(asl(AM_indexed_byte())); break; // ASL (indexed) case 0x68: tick(6); BUS().write(asl(AM_indexed_byte())); break; // ASL (indexed)
case 0x78: addCycles(7); BUS().write(asl(AM_extended_byte())); break; // ASL (extended) case 0x78: tick(7); BUS().write(asl(AM_extended_byte())); break; // ASL (extended)
// ASR // ASR
case 0x07: addCycles(6); BUS().write(asr(AM_direct_byte())); break; // ASR (direct) case 0x07: tick(6); BUS().write(asr(AM_direct_byte())); break; // ASR (direct)
case 0x47: addCycles(2); A() = asr(A()); break; // ASR (ASRA inherent) case 0x47: tick(2); A() = asr(A()); break; // ASR (ASRA inherent)
case 0x57: addCycles(2); B() = asr(B()); break; // ASR (ASRB inherent) case 0x57: tick(2); B() = asr(B()); break; // ASR (ASRB inherent)
case 0x67: addCycles(6); BUS().write(asr(AM_indexed_byte())); break; // ASR (indexed) case 0x67: tick(6); BUS().write(asr(AM_indexed_byte())); break; // ASR (indexed)
case 0x77: addCycles(7); BUS().write(asr(AM_extended_byte())); break; // ASR (extended) case 0x77: tick(7); BUS().write(asr(AM_extended_byte())); break; // ASR (extended)
// BIT // BIT
case 0x85: addCycles(2); bit(A(), AM_immediate_byte()); break; // BIT (BITA immediate) case 0x85: tick(2); bit(A(), AM_immediate_byte()); break; // BIT (BITA immediate)
case 0x95: addCycles(4); bit(A(), AM_direct_byte()); break; // BIT (BITA direct) case 0x95: tick(4); bit(A(), AM_direct_byte()); break; // BIT (BITA direct)
case 0xa5: addCycles(4); bit(A(), AM_indexed_byte()); break; // BIT (BITA indexed) case 0xa5: tick(4); bit(A(), AM_indexed_byte()); break; // BIT (BITA indexed)
case 0xb5: addCycles(5); bit(A(), AM_extended_byte()); break; // BIT (BITA extended) case 0xb5: tick(5); bit(A(), AM_extended_byte()); break; // BIT (BITA extended)
case 0xc5: addCycles(2); bit(B(), AM_immediate_byte()); break; // BIT (BITB immediate) case 0xc5: tick(2); bit(B(), AM_immediate_byte()); break; // BIT (BITB immediate)
case 0xd5: addCycles(4); bit(B(), AM_direct_byte()); break; // BIT (BITB direct) case 0xd5: tick(4); bit(B(), AM_direct_byte()); break; // BIT (BITB direct)
case 0xe5: addCycles(4); bit(B(), AM_indexed_byte()); break; // BIT (BITB indexed) case 0xe5: tick(4); bit(B(), AM_indexed_byte()); break; // BIT (BITB indexed)
case 0xf5: addCycles(5); bit(B(), AM_extended_byte()); break; // BIT (BITB extended) case 0xf5: tick(5); bit(B(), AM_extended_byte()); break; // BIT (BITB extended)
// CLR // CLR
case 0x0f: addCycles(6); BUS().write(Address_direct(), clr()); break; // CLR (direct) case 0x0f: tick(6); BUS().write(Address_direct(), clr()); break; // CLR (direct)
case 0x4f: addCycles(2); A() = clr(); break; // CLR (CLRA implied) case 0x4f: tick(2); A() = clr(); break; // CLR (CLRA implied)
case 0x5f: addCycles(2); B() = clr(); break; // CLR (CLRB implied) case 0x5f: tick(2); B() = clr(); break; // CLR (CLRB implied)
case 0x6f: addCycles(6); BUS().write(Address_indexed(), clr()); break; // CLR (indexed) case 0x6f: tick(6); BUS().write(Address_indexed(), clr()); break; // CLR (indexed)
case 0x7f: addCycles(7); BUS().write(Address_extended(), clr()); break; // CLR (extended) case 0x7f: tick(7); BUS().write(Address_extended(), clr()); break; // CLR (extended)
// CMP // CMP
// CMPA // CMPA
case 0x81: addCycles(2); cmp(A(), AM_immediate_byte()); break; // CMP (CMPA, immediate) case 0x81: tick(2); cmp(A(), AM_immediate_byte()); break; // CMP (CMPA, immediate)
case 0x91: addCycles(4); cmp(A(), AM_direct_byte()); break; // CMP (CMPA, direct) case 0x91: tick(4); cmp(A(), AM_direct_byte()); break; // CMP (CMPA, direct)
case 0xa1: addCycles(4); cmp(A(), AM_indexed_byte()); break; // CMP (CMPA, indexed) case 0xa1: tick(4); cmp(A(), AM_indexed_byte()); break; // CMP (CMPA, indexed)
case 0xb1: addCycles(5); cmp(A(), AM_extended_byte()); break; // CMP (CMPA, extended) case 0xb1: tick(5); cmp(A(), AM_extended_byte()); break; // CMP (CMPA, extended)
// CMPB // CMPB
case 0xc1: addCycles(2); cmp(B(), AM_immediate_byte()); break; // CMP (CMPB, immediate) case 0xc1: tick(2); cmp(B(), AM_immediate_byte()); break; // CMP (CMPB, immediate)
case 0xd1: addCycles(4); cmp(B(), AM_direct_byte()); break; // CMP (CMPB, direct) case 0xd1: tick(4); cmp(B(), AM_direct_byte()); break; // CMP (CMPB, direct)
case 0xe1: addCycles(4); cmp(B(), AM_indexed_byte()); break; // CMP (CMPB, indexed) case 0xe1: tick(4); cmp(B(), AM_indexed_byte()); break; // CMP (CMPB, indexed)
case 0xf1: addCycles(5); cmp(B(), AM_extended_byte()); break; // CMP (CMPB, extended) case 0xf1: tick(5); cmp(B(), AM_extended_byte()); break; // CMP (CMPB, extended)
// CMPX // CMPX
case 0x8c: addCycles(4); cmp(X(), AM_immediate_word()); break; // CMP (CMPX, immediate) case 0x8c: tick(4); cmp(X(), AM_immediate_word()); break; // CMP (CMPX, immediate)
case 0x9c: addCycles(6); cmp(X(), AM_direct_word()); break; // CMP (CMPX, direct) case 0x9c: tick(6); cmp(X(), AM_direct_word()); break; // CMP (CMPX, direct)
case 0xac: addCycles(6); cmp(X(), AM_indexed_word()); break; // CMP (CMPX, indexed) case 0xac: tick(6); cmp(X(), AM_indexed_word()); break; // CMP (CMPX, indexed)
case 0xbc: addCycles(7); cmp(X(), AM_extended_word()); break; // CMP (CMPX, extended) case 0xbc: tick(7); cmp(X(), AM_extended_word()); break; // CMP (CMPX, extended)
// COM // COM
case 0x03: addCycles(6); BUS().write(com(AM_direct_byte())); break; // COM (direct) case 0x03: tick(6); BUS().write(com(AM_direct_byte())); break; // COM (direct)
case 0x43: addCycles(2); A() = com(A()); break; // COM (COMA inherent) case 0x43: tick(2); A() = com(A()); break; // COM (COMA inherent)
case 0x53: addCycles(2); B() = com(B()); break; // COM (COMB inherent) case 0x53: tick(2); B() = com(B()); break; // COM (COMB inherent)
case 0x63: addCycles(6); BUS().write(com(AM_indexed_byte())); break; // COM (indexed) case 0x63: tick(6); BUS().write(com(AM_indexed_byte())); break; // COM (indexed)
case 0x73: addCycles(7); BUS().write(com(AM_extended_byte())); break; // COM (extended) case 0x73: tick(7); BUS().write(com(AM_extended_byte())); break; // COM (extended)
// CWAI // CWAI
case 0x3c: addCycles(11); cwai(AM_direct_byte()); break; // CWAI (direct) case 0x3c: tick(11); cwai(AM_direct_byte()); break; // CWAI (direct)
// DAA // DAA
case 0x19: addCycles(2); A() = da(A()); break; // DAA (inherent) case 0x19: tick(2); A() = da(A()); break; // DAA (inherent)
// DEC // DEC
case 0x0a: addCycles(6); BUS().write(dec(AM_direct_byte())); break; // DEC (direct) case 0x0a: tick(6); BUS().write(dec(AM_direct_byte())); break; // DEC (direct)
case 0x4a: addCycles(2); A() = dec(A()); break; // DEC (DECA inherent) case 0x4a: tick(2); A() = dec(A()); break; // DEC (DECA inherent)
case 0x5a: addCycles(2); B() = dec(B()); break; // DEC (DECB inherent) case 0x5a: tick(2); B() = dec(B()); break; // DEC (DECB inherent)
case 0x6a: addCycles(6); BUS().write(dec(AM_indexed_byte())); break; // DEC (indexed) case 0x6a: tick(6); BUS().write(dec(AM_indexed_byte())); break; // DEC (indexed)
case 0x7a: addCycles(7); BUS().write(dec(AM_extended_byte())); break; // DEC (extended) case 0x7a: tick(7); BUS().write(dec(AM_extended_byte())); break; // DEC (extended)
// EOR // EOR
// EORA // EORA
case 0x88: addCycles(2); A() = eorr(A(), AM_immediate_byte()); break; // EOR (EORA immediate) case 0x88: tick(2); A() = eorr(A(), AM_immediate_byte()); break; // EOR (EORA immediate)
case 0x98: addCycles(4); A() = eorr(A(), AM_direct_byte()); break; // EOR (EORA direct) case 0x98: tick(4); A() = eorr(A(), AM_direct_byte()); break; // EOR (EORA direct)
case 0xa8: addCycles(4); A() = eorr(A(), AM_indexed_byte()); break; // EOR (EORA indexed) case 0xa8: tick(4); A() = eorr(A(), AM_indexed_byte()); break; // EOR (EORA indexed)
case 0xb8: addCycles(5); A() = eorr(A(), AM_extended_byte()); break; // EOR (EORA extended) case 0xb8: tick(5); A() = eorr(A(), AM_extended_byte()); break; // EOR (EORA extended)
// EORB // EORB
case 0xc8: addCycles(2); B() = eorr(B(), AM_immediate_byte()); break; // EOR (EORB immediate) case 0xc8: tick(2); B() = eorr(B(), AM_immediate_byte()); break; // EOR (EORB immediate)
case 0xd8: addCycles(4); B() = eorr(B(), AM_direct_byte()); break; // EOR (EORB direct) case 0xd8: tick(4); B() = eorr(B(), AM_direct_byte()); break; // EOR (EORB direct)
case 0xe8: addCycles(4); B() = eorr(B(), AM_indexed_byte()); break; // EOR (EORB indexed) case 0xe8: tick(4); B() = eorr(B(), AM_indexed_byte()); break; // EOR (EORB indexed)
case 0xf8: addCycles(5); B() = eorr(B(), AM_extended_byte()); break; // EOR (EORB extended) case 0xf8: tick(5); B() = eorr(B(), AM_extended_byte()); break; // EOR (EORB extended)
// EXG // EXG
case 0x1e: addCycles(8); exg(AM_immediate_byte()); break; // EXG (R1,R2 immediate) case 0x1e: tick(8); exg(AM_immediate_byte()); break; // EXG (R1,R2 immediate)
// INC // INC
case 0x0c: addCycles(6); BUS().write(inc(AM_direct_byte())); break; // INC (direct) case 0x0c: tick(6); BUS().write(inc(AM_direct_byte())); break; // INC (direct)
case 0x4c: addCycles(2); A() = inc(A()); break; // INC (INCA inherent) case 0x4c: tick(2); A() = inc(A()); break; // INC (INCA inherent)
case 0x5c: addCycles(2); B() = inc(B()); break; // INC (INCB inherent) case 0x5c: tick(2); B() = inc(B()); break; // INC (INCB inherent)
case 0x6c: addCycles(6); BUS().write(inc(AM_indexed_byte())); break; // INC (indexed) case 0x6c: tick(6); BUS().write(inc(AM_indexed_byte())); break; // INC (indexed)
case 0x7c: addCycles(7); BUS().write(inc(AM_extended_byte())); break; // INC (extended) case 0x7c: tick(7); BUS().write(inc(AM_extended_byte())); break; // INC (extended)
// JMP // JMP
case 0x0e: addCycles(6); jump(Address_direct()); break; // JMP (direct) case 0x0e: tick(6); jump(Address_direct()); break; // JMP (direct)
case 0x6e: addCycles(6); jump(Address_indexed()); break; // JMP (indexed) case 0x6e: tick(6); jump(Address_indexed()); break; // JMP (indexed)
case 0x7e: addCycles(7); jump(Address_extended()); break; // JMP (extended) case 0x7e: tick(7); jump(Address_extended()); break; // JMP (extended)
// JSR // JSR
case 0x9d: addCycles(6); jsr(Address_direct()); break; // JSR (direct) case 0x9d: tick(6); jsr(Address_direct()); break; // JSR (direct)
case 0xad: addCycles(6); jsr(Address_indexed()); break; // JSR (indexed) case 0xad: tick(6); jsr(Address_indexed()); break; // JSR (indexed)
case 0xbd: addCycles(7); jsr(Address_extended()); break; // JSR (extended) case 0xbd: tick(7); jsr(Address_extended()); break; // JSR (extended)
// LD // LD
// LDA // LDA
case 0x86: addCycles(2); A() = ld(AM_immediate_byte()); break; // LD (LDA immediate) case 0x86: tick(2); A() = ld(AM_immediate_byte()); break; // LD (LDA immediate)
case 0x96: addCycles(4); A() = ld(AM_direct_byte()); break; // LD (LDA direct) case 0x96: tick(4); A() = ld(AM_direct_byte()); break; // LD (LDA direct)
case 0xa6: addCycles(4); A() = ld(AM_indexed_byte()); break; // LD (LDA indexed) case 0xa6: tick(4); A() = ld(AM_indexed_byte()); break; // LD (LDA indexed)
case 0xb6: addCycles(5); A() = ld(AM_extended_byte()); break; // LD (LDA extended) case 0xb6: tick(5); A() = ld(AM_extended_byte()); break; // LD (LDA extended)
// LDB // LDB
case 0xc6: addCycles(2); B() = ld(AM_immediate_byte()); break; // LD (LDB immediate) case 0xc6: tick(2); B() = ld(AM_immediate_byte()); break; // LD (LDB immediate)
case 0xd6: addCycles(4); B() = ld(AM_direct_byte()); break; // LD (LDB direct) case 0xd6: tick(4); B() = ld(AM_direct_byte()); break; // LD (LDB direct)
case 0xe6: addCycles(4); B() = ld(AM_indexed_byte()); break; // LD (LDB indexed) case 0xe6: tick(4); B() = ld(AM_indexed_byte()); break; // LD (LDB indexed)
case 0xf6: addCycles(5); B() = ld(AM_extended_byte()); break; // LD (LDB extended) case 0xf6: tick(5); B() = ld(AM_extended_byte()); break; // LD (LDB extended)
// LDD // LDD
case 0xcc: addCycles(3); D() = ld(AM_immediate_word()); break; // LD (LDD immediate) case 0xcc: tick(3); D() = ld(AM_immediate_word()); break; // LD (LDD immediate)
case 0xdc: addCycles(5); D() = ld(AM_direct_word()); break; // LD (LDD direct) case 0xdc: tick(5); D() = ld(AM_direct_word()); break; // LD (LDD direct)
case 0xec: addCycles(5); D() = ld(AM_indexed_word()); break; // LD (LDD indexed) case 0xec: tick(5); D() = ld(AM_indexed_word()); break; // LD (LDD indexed)
case 0xfc: addCycles(6); D() = ld(AM_extended_word()); break; // LD (LDD extended) case 0xfc: tick(6); D() = ld(AM_extended_word()); break; // LD (LDD extended)
// LDU // LDU
case 0xce: addCycles(3); U() = ld(AM_immediate_word()); break; // LD (LDU immediate) case 0xce: tick(3); U() = ld(AM_immediate_word()); break; // LD (LDU immediate)
case 0xde: addCycles(5); U() = ld(AM_direct_word()); break; // LD (LDU direct) case 0xde: tick(5); U() = ld(AM_direct_word()); break; // LD (LDU direct)
case 0xee: addCycles(5); U() = ld(AM_indexed_word()); break; // LD (LDU indexed) case 0xee: tick(5); U() = ld(AM_indexed_word()); break; // LD (LDU indexed)
case 0xfe: addCycles(6); U() = ld(AM_extended_word()); break; // LD (LDU extended) case 0xfe: tick(6); U() = ld(AM_extended_word()); break; // LD (LDU extended)
// LDX // LDX
case 0x8e: addCycles(3); X() = ld(AM_immediate_word()); break; // LD (LDX immediate) case 0x8e: tick(3); X() = ld(AM_immediate_word()); break; // LD (LDX immediate)
case 0x9e: addCycles(5); X() = ld(AM_direct_word()); break; // LD (LDX direct) case 0x9e: tick(5); X() = ld(AM_direct_word()); break; // LD (LDX direct)
case 0xae: addCycles(5); X() = ld(AM_indexed_word()); break; // LD (LDX indexed) case 0xae: tick(5); X() = ld(AM_indexed_word()); break; // LD (LDX indexed)
case 0xbe: addCycles(6); X() = ld(AM_extended_word()); break; // LD (LDX extended) case 0xbe: tick(6); X() = ld(AM_extended_word()); break; // LD (LDX extended)
// LEA // LEA
case 0x30: addCycles(4); adjustZero(X() = Address_indexed()); break; // LEA (LEAX indexed) case 0x30: tick(4); adjustZero(X() = Address_indexed()); break; // LEA (LEAX indexed)
case 0x31: addCycles(4); adjustZero(Y() = Address_indexed()); break; // LEA (LEAY indexed) case 0x31: tick(4); adjustZero(Y() = Address_indexed()); break; // LEA (LEAY indexed)
case 0x32: addCycles(4); S() = Address_indexed(); break; // LEA (LEAS indexed) case 0x32: tick(4); S() = Address_indexed(); break; // LEA (LEAS indexed)
case 0x33: addCycles(4); U() = Address_indexed(); break; // LEA (LEAU indexed) case 0x33: tick(4); U() = Address_indexed(); break; // LEA (LEAU indexed)
// LSR // LSR
case 0x04: addCycles(6); BUS().write(lsr(AM_direct_byte())); break; // LSR (direct) case 0x04: tick(6); BUS().write(lsr(AM_direct_byte())); break; // LSR (direct)
case 0x44: addCycles(2); A() = lsr(A()); break; // LSR (LSRA inherent) case 0x44: tick(2); A() = lsr(A()); break; // LSR (LSRA inherent)
case 0x54: addCycles(2); B() = lsr(B()); break; // LSR (LSRB inherent) case 0x54: tick(2); B() = lsr(B()); break; // LSR (LSRB inherent)
case 0x64: addCycles(6); BUS().write(lsr(AM_indexed_byte())); break; // LSR (indexed) case 0x64: tick(6); BUS().write(lsr(AM_indexed_byte())); break; // LSR (indexed)
case 0x74: addCycles(7); BUS().write(lsr(AM_extended_byte())); break; // LSR (extended) case 0x74: tick(7); BUS().write(lsr(AM_extended_byte())); break; // LSR (extended)
// MUL // MUL
case 0x3d: addCycles(11); D() = mul(A(), B()); break; // MUL (inherent) case 0x3d: tick(11); D() = mul(A(), B()); break; // MUL (inherent)
// NEG // NEG
case 0x00: addCycles(6); BUS().write(neg(AM_direct_byte())); break; // NEG (direct) case 0x00: tick(6); BUS().write(neg(AM_direct_byte())); break; // NEG (direct)
case 0x40: addCycles(2); A() = neg(A()); break; // NEG (NEGA, inherent) case 0x40: tick(2); A() = neg(A()); break; // NEG (NEGA, inherent)
case 0x50: addCycles(2); B() = neg(B()); break; // NEG (NEGB, inherent) case 0x50: tick(2); B() = neg(B()); break; // NEG (NEGB, inherent)
case 0x60: addCycles(6); BUS().write(neg(AM_indexed_byte())); break; // NEG (indexed) case 0x60: tick(6); BUS().write(neg(AM_indexed_byte())); break; // NEG (indexed)
case 0x70: addCycles(7); BUS().write(neg(AM_extended_byte())); break; // NEG (extended) case 0x70: tick(7); BUS().write(neg(AM_extended_byte())); break; // NEG (extended)
// NOP // NOP
case 0x12: addCycles(2); break; // NOP (inherent) case 0x12: tick(2); break; // NOP (inherent)
// OR // OR
// ORA // ORA
case 0x8a: addCycles(2); A() = orr(A(), AM_immediate_byte()); break; // OR (ORA immediate) case 0x8a: tick(2); A() = orr(A(), AM_immediate_byte()); break; // OR (ORA immediate)
case 0x9a: addCycles(4); A() = orr(A(), AM_direct_byte()); break; // OR (ORA direct) case 0x9a: tick(4); A() = orr(A(), AM_direct_byte()); break; // OR (ORA direct)
case 0xaa: addCycles(4); A() = orr(A(), AM_indexed_byte()); break; // OR (ORA indexed) case 0xaa: tick(4); A() = orr(A(), AM_indexed_byte()); break; // OR (ORA indexed)
case 0xba: addCycles(5); A() = orr(A(), AM_extended_byte()); break; // OR (ORA extended) case 0xba: tick(5); A() = orr(A(), AM_extended_byte()); break; // OR (ORA extended)
// ORB // ORB
case 0xca: addCycles(2); B() = orr(B(), AM_immediate_byte()); break; // OR (ORB immediate) case 0xca: tick(2); B() = orr(B(), AM_immediate_byte()); break; // OR (ORB immediate)
case 0xda: addCycles(4); B() = orr(B(), AM_direct_byte()); break; // OR (ORB direct) case 0xda: tick(4); B() = orr(B(), AM_direct_byte()); break; // OR (ORB direct)
case 0xea: addCycles(4); B() = orr(B(), AM_indexed_byte()); break; // OR (ORB indexed) case 0xea: tick(4); B() = orr(B(), AM_indexed_byte()); break; // OR (ORB indexed)
case 0xfa: addCycles(5); B() = orr(B(), AM_extended_byte()); break; // OR (ORB extended) case 0xfa: tick(5); B() = orr(B(), AM_extended_byte()); break; // OR (ORB extended)
// ORCC // ORCC
case 0x1a: addCycles(3); CC() |= AM_immediate_byte(); break; // OR (ORCC immediate) case 0x1a: tick(3); CC() |= AM_immediate_byte(); break; // OR (ORCC immediate)
// PSH // PSH
case 0x34: addCycles(5); psh(S(), AM_immediate_byte()); break; // PSH (PSHS immediate) case 0x34: tick(5); psh(S(), AM_immediate_byte()); break; // PSH (PSHS immediate)
case 0x36: addCycles(5); psh(U(), AM_immediate_byte()); break; // PSH (PSHU immediate) case 0x36: tick(5); psh(U(), AM_immediate_byte()); break; // PSH (PSHU immediate)
// PUL // PUL
case 0x35: addCycles(5); pul(S(), AM_immediate_byte()); break; // PUL (PULS immediate) case 0x35: tick(5); pul(S(), AM_immediate_byte()); break; // PUL (PULS immediate)
case 0x37: addCycles(5); pul(U(), AM_immediate_byte()); break; // PUL (PULU immediate) case 0x37: tick(5); pul(U(), AM_immediate_byte()); break; // PUL (PULU immediate)
// ROL // ROL
case 0x09: addCycles(6); BUS().write(rol(AM_direct_byte())); break; // ROL (direct) case 0x09: tick(6); BUS().write(rol(AM_direct_byte())); break; // ROL (direct)
case 0x49: addCycles(2); A() = rol(A()); break; // ROL (ROLA inherent) case 0x49: tick(2); A() = rol(A()); break; // ROL (ROLA inherent)
case 0x59: addCycles(2); B() = rol(B()); break; // ROL (ROLB inherent) case 0x59: tick(2); B() = rol(B()); break; // ROL (ROLB inherent)
case 0x69: addCycles(6); BUS().write(rol(AM_indexed_byte())); break; // ROL (indexed) case 0x69: tick(6); BUS().write(rol(AM_indexed_byte())); break; // ROL (indexed)
case 0x79: addCycles(7); BUS().write(rol(AM_extended_byte())); break; // ROL (extended) case 0x79: tick(7); BUS().write(rol(AM_extended_byte())); break; // ROL (extended)
// ROR // ROR
case 0x06: addCycles(6); BUS().write(ror(AM_direct_byte())); break; // ROR (direct) case 0x06: tick(6); BUS().write(ror(AM_direct_byte())); break; // ROR (direct)
case 0x46: addCycles(2); A() = ror(A()); break; // ROR (RORA inherent) case 0x46: tick(2); A() = ror(A()); break; // ROR (RORA inherent)
case 0x56: addCycles(2); B() = ror(B()); break; // ROR (RORB inherent) case 0x56: tick(2); B() = ror(B()); break; // ROR (RORB inherent)
case 0x66: addCycles(6); BUS().write(ror(AM_indexed_byte())); break; // ROR (indexed) case 0x66: tick(6); BUS().write(ror(AM_indexed_byte())); break; // ROR (indexed)
case 0x76: addCycles(7); BUS().write(ror(AM_extended_byte())); break; // ROR (extended) case 0x76: tick(7); BUS().write(ror(AM_extended_byte())); break; // ROR (extended)
// RTI // RTI
case 0x3B: addCycles(6); rti(); break; // RTI (inherent) case 0x3B: tick(6); rti(); break; // RTI (inherent)
// RTS // RTS
case 0x39: addCycles(5); rts(); break; // RTS (inherent) case 0x39: tick(5); rts(); break; // RTS (inherent)
// SBC // SBC
// SBCA // SBCA
case 0x82: addCycles(4); A() = sbc(A(), AM_immediate_byte()); break; // SBC (SBCA immediate) case 0x82: tick(4); A() = sbc(A(), AM_immediate_byte()); break; // SBC (SBCA immediate)
case 0x92: addCycles(4); A() = sbc(A(), AM_direct_byte()); break; // SBC (SBCA direct) case 0x92: tick(4); A() = sbc(A(), AM_direct_byte()); break; // SBC (SBCA direct)
case 0xa2: addCycles(4); A() = sbc(A(), AM_indexed_byte()); break; // SBC (SBCA indexed) case 0xa2: tick(4); A() = sbc(A(), AM_indexed_byte()); break; // SBC (SBCA indexed)
case 0xb2: addCycles(5); A() = sbc(A(), AM_extended_byte()); break; // SBC (SBCB extended) case 0xb2: tick(5); A() = sbc(A(), AM_extended_byte()); break; // SBC (SBCB extended)
// SBCB // SBCB
case 0xc2: addCycles(4); B() = sbc(B(), AM_immediate_byte()); break; // SBC (SBCB immediate) case 0xc2: tick(4); B() = sbc(B(), AM_immediate_byte()); break; // SBC (SBCB immediate)
case 0xd2: addCycles(4); B() = sbc(B(), AM_direct_byte()); break; // SBC (SBCB direct) case 0xd2: tick(4); B() = sbc(B(), AM_direct_byte()); break; // SBC (SBCB direct)
case 0xe2: addCycles(4); B() = sbc(B(), AM_indexed_byte()); break; // SBC (SBCB indexed) case 0xe2: tick(4); B() = sbc(B(), AM_indexed_byte()); break; // SBC (SBCB indexed)
case 0xf2: addCycles(5); B() = sbc(B(), AM_extended_byte()); break; // SBC (SBCB extended) case 0xf2: tick(5); B() = sbc(B(), AM_extended_byte()); break; // SBC (SBCB extended)
// SEX // SEX
case 0x1d: addCycles(2); A() = sex(B()); break; // SEX (inherent) case 0x1d: tick(2); A() = sex(B()); break; // SEX (inherent)
// ST // ST
// STA // STA
case 0x97: addCycles(4); BUS().write(Address_direct(), st(A())); break; // ST (STA direct) case 0x97: tick(4); BUS().write(Address_direct(), st(A())); break; // ST (STA direct)
case 0xa7: addCycles(4); BUS().write(Address_indexed(), st(A())); break; // ST (STA indexed) case 0xa7: tick(4); BUS().write(Address_indexed(), st(A())); break; // ST (STA indexed)
case 0xb7: addCycles(5); BUS().write(Address_extended(), st(A())); break; // ST (STA extended) case 0xb7: tick(5); BUS().write(Address_extended(), st(A())); break; // ST (STA extended)
// STB // STB
case 0xd7: addCycles(4); BUS().write(Address_direct(), st(B())); break; // ST (STB direct) case 0xd7: tick(4); BUS().write(Address_direct(), st(B())); break; // ST (STB direct)
case 0xe7: addCycles(4); BUS().write(Address_indexed(), st(B())); break; // ST (STB indexed) case 0xe7: tick(4); BUS().write(Address_indexed(), st(B())); break; // ST (STB indexed)
case 0xf7: addCycles(5); BUS().write(Address_extended(), st(B())); break; // ST (STB extended) case 0xf7: tick(5); BUS().write(Address_extended(), st(B())); break; // ST (STB extended)
// STD // STD
case 0xdd: addCycles(5); Processor::setWord(Address_direct(), st(D())); break; // ST (STD direct) case 0xdd: tick(5); Processor::setWord(Address_direct(), st(D())); break; // ST (STD direct)
case 0xed: addCycles(5); Processor::setWord(Address_indexed(), st(D())); break; // ST (STD indexed) case 0xed: tick(5); Processor::setWord(Address_indexed(), st(D())); break; // ST (STD indexed)
case 0xfd: addCycles(6); Processor::setWord(Address_extended(), st(D())); break; // ST (STD extended) case 0xfd: tick(6); Processor::setWord(Address_extended(), st(D())); break; // ST (STD extended)
// STU // STU
case 0xdf: addCycles(5); Processor::setWord(Address_direct(), st(U())); break; // ST (STU direct) case 0xdf: tick(5); Processor::setWord(Address_direct(), st(U())); break; // ST (STU direct)
case 0xef: addCycles(5); Processor::setWord(Address_indexed(), st(U())); break; // ST (STU indexed) case 0xef: tick(5); Processor::setWord(Address_indexed(), st(U())); break; // ST (STU indexed)
case 0xff: addCycles(6); Processor::setWord(Address_extended(), st(U())); break; // ST (STU extended) case 0xff: tick(6); Processor::setWord(Address_extended(), st(U())); break; // ST (STU extended)
// STX // STX
case 0x9f: addCycles(5); Processor::setWord(Address_direct(), st(X())); break; // ST (STX direct) case 0x9f: tick(5); Processor::setWord(Address_direct(), st(X())); break; // ST (STX direct)
case 0xaf: addCycles(5); Processor::setWord(Address_indexed(), st(X())); break; // ST (STX indexed) case 0xaf: tick(5); Processor::setWord(Address_indexed(), st(X())); break; // ST (STX indexed)
case 0xbf: addCycles(6); Processor::setWord(Address_extended(), st(X())); break; // ST (STX extended) case 0xbf: tick(6); Processor::setWord(Address_extended(), st(X())); break; // ST (STX extended)
// SUB // SUB
// SUBA // SUBA
case 0x80: addCycles(2); A() = sub(A(), AM_immediate_byte()); break; // SUB (SUBA immediate) case 0x80: tick(2); A() = sub(A(), AM_immediate_byte()); break; // SUB (SUBA immediate)
case 0x90: addCycles(4); A() = sub(A(), AM_direct_byte()); break; // SUB (SUBA direct) case 0x90: tick(4); A() = sub(A(), AM_direct_byte()); break; // SUB (SUBA direct)
case 0xa0: addCycles(4); A() = sub(A(), AM_indexed_byte()); break; // SUB (SUBA indexed) case 0xa0: tick(4); A() = sub(A(), AM_indexed_byte()); break; // SUB (SUBA indexed)
case 0xb0: addCycles(5); A() = sub(A(), AM_extended_byte()); break; // SUB (SUBA extended) case 0xb0: tick(5); A() = sub(A(), AM_extended_byte()); break; // SUB (SUBA extended)
// SUBB // SUBB
case 0xc0: addCycles(2); B() = sub(B(), AM_immediate_byte()); break; // SUB (SUBB immediate) case 0xc0: tick(2); B() = sub(B(), AM_immediate_byte()); break; // SUB (SUBB immediate)
case 0xd0: addCycles(4); B() = sub(B(), AM_direct_byte()); break; // SUB (SUBB direct) case 0xd0: tick(4); B() = sub(B(), AM_direct_byte()); break; // SUB (SUBB direct)
case 0xe0: addCycles(4); B() = sub(B(), AM_indexed_byte()); break; // SUB (SUBB indexed) case 0xe0: tick(4); B() = sub(B(), AM_indexed_byte()); break; // SUB (SUBB indexed)
case 0xf0: addCycles(5); B() = sub(B(), AM_extended_byte()); break; // SUB (SUBB extended) case 0xf0: tick(5); B() = sub(B(), AM_extended_byte()); break; // SUB (SUBB extended)
// SUBD // SUBD
case 0x83: addCycles(4); D() = sub(D(), AM_immediate_word()); break; // SUB (SUBD immediate) case 0x83: tick(4); D() = sub(D(), AM_immediate_word()); break; // SUB (SUBD immediate)
case 0x93: addCycles(6); D() = sub(D(), AM_direct_word()); break; // SUB (SUBD direct) case 0x93: tick(6); D() = sub(D(), AM_direct_word()); break; // SUB (SUBD direct)
case 0xa3: addCycles(6); D() = sub(D(), AM_indexed_word()); break; // SUB (SUBD indexed) case 0xa3: tick(6); D() = sub(D(), AM_indexed_word()); break; // SUB (SUBD indexed)
case 0xb3: addCycles(7); D() = sub(D(), AM_extended_word()); break; // SUB (SUBD extended) case 0xb3: tick(7); D() = sub(D(), AM_extended_word()); break; // SUB (SUBD extended)
// SWI // SWI
case 0x3f: addCycles(10); swi(); break; // SWI (inherent) case 0x3f: tick(10); swi(); break; // SWI (inherent)
// SYNC // SYNC
case 0x13: addCycles(4); halt(); break; // SYNC (inherent) case 0x13: tick(4); halt(); break; // SYNC (inherent)
// TFR // TFR
case 0x1f: addCycles(6); tfr(AM_immediate_byte()); break; // TFR (immediate) case 0x1f: tick(6); tfr(AM_immediate_byte()); break; // TFR (immediate)
// TST // TST
case 0x0d: addCycles(6); tst(AM_direct_byte()); break; // TST (direct) case 0x0d: tick(6); tst(AM_direct_byte()); break; // TST (direct)
case 0x4d: addCycles(2); tst(A()); break; // TST (TSTA inherent) case 0x4d: tick(2); tst(A()); break; // TST (TSTA inherent)
case 0x5d: addCycles(2); tst(B()); break; // TST (TSTB inherent) case 0x5d: tick(2); tst(B()); break; // TST (TSTB inherent)
case 0x6d: addCycles(6); tst(AM_indexed_byte()); break; // TST (indexed) case 0x6d: tick(6); tst(AM_indexed_byte()); break; // TST (indexed)
case 0x7d: addCycles(7); tst(AM_extended_byte()); break; // TST (extended) case 0x7d: tick(7); tst(AM_extended_byte()); break; // TST (extended)
// Branching // Branching
case 0x16: addCycles(5); jump(Address_relative_word()); break; // BRA (LBRA relative) case 0x16: tick(5); jump(Address_relative_word()); break; // BRA (LBRA relative)
case 0x17: addCycles(9); jsr(Address_relative_word()); break; // BSR (LBSR relative) case 0x17: tick(9); jsr(Address_relative_word()); break; // BSR (LBSR relative)
case 0x20: addCycles(3); jump(Address_relative_byte()); break; // BRA (relative) case 0x20: tick(3); jump(Address_relative_byte()); break; // BRA (relative)
case 0x21: addCycles(3); Address_relative_byte(); break; // BRN (relative) case 0x21: tick(3); Address_relative_byte(); break; // BRN (relative)
case 0x22: addCycles(3); branchShort(HI()); break; // BHI (relative) case 0x22: tick(3); branchShort(HI()); break; // BHI (relative)
case 0x23: addCycles(3); branchShort(LS()); break; // BLS (relative) case 0x23: tick(3); branchShort(LS()); break; // BLS (relative)
case 0x24: addCycles(3); branchShort(!carry()); break; // BCC (relative) case 0x24: tick(3); branchShort(!carry()); break; // BCC (relative)
case 0x25: addCycles(3); branchShort(carry()); break; // BCS (relative) case 0x25: tick(3); branchShort(carry()); break; // BCS (relative)
case 0x26: addCycles(3); branchShort(!zero()); break; // BNE (relative) case 0x26: tick(3); branchShort(!zero()); break; // BNE (relative)
case 0x27: addCycles(3); branchShort(zero()); break; // BEQ (relative) case 0x27: tick(3); branchShort(zero()); break; // BEQ (relative)
case 0x28: addCycles(3); branchShort(!overflow()); break; // BVC (relative) case 0x28: tick(3); branchShort(!overflow()); break; // BVC (relative)
case 0x29: addCycles(3); branchShort(overflow()); break; // BVS (relative) case 0x29: tick(3); branchShort(overflow()); break; // BVS (relative)
case 0x2a: addCycles(3); branchShort(!negative()); break; // BPL (relative) case 0x2a: tick(3); branchShort(!negative()); break; // BPL (relative)
case 0x2b: addCycles(3); branchShort(negative()); break; // BMI (relative) case 0x2b: tick(3); branchShort(negative()); break; // BMI (relative)
case 0x2c: addCycles(3); branchShort(GE()); break; // BGE (relative) case 0x2c: tick(3); branchShort(GE()); break; // BGE (relative)
case 0x2d: addCycles(3); branchShort(LT()); break; // BLT (relative) case 0x2d: tick(3); branchShort(LT()); break; // BLT (relative)
case 0x2e: addCycles(3); branchShort(GT()); break; // BGT (relative) case 0x2e: tick(3); branchShort(GT()); break; // BGT (relative)
case 0x2f: addCycles(3); branchShort(LE()); break; // BLE (relative) case 0x2f: tick(3); branchShort(LE()); break; // BLE (relative)
case 0x8d: addCycles(7); jsr(Address_relative_byte()); break; // BSR (relative) case 0x8d: tick(7); jsr(Address_relative_byte()); break; // BSR (relative)
default: default:
UNREACHABLE; UNREACHABLE;
@ -485,61 +485,61 @@ void EightBit::mc6809::execute10() {
// CMP // CMP
// CMPD // CMPD
case 0x83: addCycles(5); cmp(D(), AM_immediate_word()); break; // CMP (CMPD, immediate) case 0x83: tick(5); cmp(D(), AM_immediate_word()); break; // CMP (CMPD, immediate)
case 0x93: addCycles(7); cmp(D(), AM_direct_word()); break; // CMP (CMPD, direct) case 0x93: tick(7); cmp(D(), AM_direct_word()); break; // CMP (CMPD, direct)
case 0xa3: addCycles(7); cmp(D(), AM_indexed_word()); break; // CMP (CMPD, indexed) case 0xa3: tick(7); cmp(D(), AM_indexed_word()); break; // CMP (CMPD, indexed)
case 0xb3: addCycles(8); cmp(D(), AM_extended_word()); break; // CMP (CMPD, extended) case 0xb3: tick(8); cmp(D(), AM_extended_word()); break; // CMP (CMPD, extended)
// CMPY // CMPY
case 0x8c: addCycles(5); cmp(Y(), AM_immediate_word()); break; // CMP (CMPY, immediate) case 0x8c: tick(5); cmp(Y(), AM_immediate_word()); break; // CMP (CMPY, immediate)
case 0x9c: addCycles(7); cmp(Y(), AM_direct_word()); break; // CMP (CMPY, direct) case 0x9c: tick(7); cmp(Y(), AM_direct_word()); break; // CMP (CMPY, direct)
case 0xac: addCycles(7); cmp(Y(), AM_indexed_word()); break; // CMP (CMPY, indexed) case 0xac: tick(7); cmp(Y(), AM_indexed_word()); break; // CMP (CMPY, indexed)
case 0xbc: addCycles(8); cmp(Y(), AM_extended_word()); break; // CMP (CMPY, extended) case 0xbc: tick(8); cmp(Y(), AM_extended_word()); break; // CMP (CMPY, extended)
// LD // LD
// LDS // LDS
case 0xce: addCycles(4); S() = ld(AM_immediate_word()); break; // LD (LDS immediate) case 0xce: tick(4); S() = ld(AM_immediate_word()); break; // LD (LDS immediate)
case 0xde: addCycles(6); S() = ld(AM_direct_word()); break; // LD (LDS direct) case 0xde: tick(6); S() = ld(AM_direct_word()); break; // LD (LDS direct)
case 0xee: addCycles(6); S() = ld(AM_indexed_word()); break; // LD (LDS indexed) case 0xee: tick(6); S() = ld(AM_indexed_word()); break; // LD (LDS indexed)
case 0xfe: addCycles(7); S() = ld(AM_extended_word()); break; // LD (LDS extended) case 0xfe: tick(7); S() = ld(AM_extended_word()); break; // LD (LDS extended)
// LDY // LDY
case 0x8e: addCycles(4); Y() = ld(AM_immediate_word()); break; // LD (LDY immediate) case 0x8e: tick(4); Y() = ld(AM_immediate_word()); break; // LD (LDY immediate)
case 0x9e: addCycles(6); Y() = ld(AM_direct_word()); break; // LD (LDY direct) case 0x9e: tick(6); Y() = ld(AM_direct_word()); break; // LD (LDY direct)
case 0xae: addCycles(6); Y() = ld(AM_indexed_word()); break; // LD (LDY indexed) case 0xae: tick(6); Y() = ld(AM_indexed_word()); break; // LD (LDY indexed)
case 0xbe: addCycles(7); Y() = ld(AM_extended_word()); break; // LD (LDY extended) case 0xbe: tick(7); Y() = ld(AM_extended_word()); break; // LD (LDY extended)
// Branching // Branching
case 0x21: addCycles(5); Address_relative_word(); break; // BRN (LBRN relative) case 0x21: tick(5); Address_relative_word(); break; // BRN (LBRN relative)
case 0x22: addCycles(5); branchLong(HI()); break; // BHI (LBHI relative) case 0x22: tick(5); branchLong(HI()); break; // BHI (LBHI relative)
case 0x23: addCycles(5); branchLong(LS()); break; // BLS (LBLS relative) case 0x23: tick(5); branchLong(LS()); break; // BLS (LBLS relative)
case 0x24: addCycles(5); branchLong(!carry()); break; // BCC (LBCC relative) case 0x24: tick(5); branchLong(!carry()); break; // BCC (LBCC relative)
case 0x25: addCycles(5); branchLong(carry()); break; // BCS (LBCS relative) case 0x25: tick(5); branchLong(carry()); break; // BCS (LBCS relative)
case 0x26: addCycles(5); branchLong(!zero()); break; // BNE (LBNE relative) case 0x26: tick(5); branchLong(!zero()); break; // BNE (LBNE relative)
case 0x27: addCycles(5); branchLong(zero()); break; // BEQ (LBEQ relative) case 0x27: tick(5); branchLong(zero()); break; // BEQ (LBEQ relative)
case 0x28: addCycles(5); branchLong(!overflow()); break; // BVC (LBVC relative) case 0x28: tick(5); branchLong(!overflow()); break; // BVC (LBVC relative)
case 0x29: addCycles(5); branchLong(overflow()); break; // BVS (LBVS relative) case 0x29: tick(5); branchLong(overflow()); break; // BVS (LBVS relative)
case 0x2a: addCycles(5); branchLong(!negative()); break; // BPL (LBPL relative) case 0x2a: tick(5); branchLong(!negative()); break; // BPL (LBPL relative)
case 0x2b: addCycles(5); branchLong(negative()); break; // BMI (LBMI relative) case 0x2b: tick(5); branchLong(negative()); break; // BMI (LBMI relative)
case 0x2c: addCycles(5); branchLong(GE()); break; // BGE (LBGE relative) case 0x2c: tick(5); branchLong(GE()); break; // BGE (LBGE relative)
case 0x2d: addCycles(5); branchLong(LT()); break; // BLT (LBLT relative) case 0x2d: tick(5); branchLong(LT()); break; // BLT (LBLT relative)
case 0x2e: addCycles(5); branchLong(GT()); break; // BGT (LBGT relative) case 0x2e: tick(5); branchLong(GT()); break; // BGT (LBGT relative)
case 0x2f: addCycles(5); branchLong(LE()); break; // BLE (LBLE relative) case 0x2f: tick(5); branchLong(LE()); break; // BLE (LBLE relative)
// STS // STS
case 0xdf: addCycles(6); Processor::setWord(Address_direct(), st(S())); break; // ST (STS direct) case 0xdf: tick(6); Processor::setWord(Address_direct(), st(S())); break; // ST (STS direct)
case 0xef: addCycles(6); Processor::setWord(Address_indexed(), st(S())); break; // ST (STS indexed) case 0xef: tick(6); Processor::setWord(Address_indexed(), st(S())); break; // ST (STS indexed)
case 0xff: addCycles(7); Processor::setWord(Address_extended(), st(S())); break; // ST (STS extended) case 0xff: tick(7); Processor::setWord(Address_extended(), st(S())); break; // ST (STS extended)
// STY // STY
case 0x9f: addCycles(6); Processor::setWord(Address_direct(), st(Y())); break; // ST (STY direct) case 0x9f: tick(6); Processor::setWord(Address_direct(), st(Y())); break; // ST (STY direct)
case 0xaf: addCycles(6); Processor::setWord(Address_indexed(), st(Y())); break; // ST (STY indexed) case 0xaf: tick(6); Processor::setWord(Address_indexed(), st(Y())); break; // ST (STY indexed)
case 0xbf: addCycles(7); Processor::setWord(Address_extended(), st(Y())); break; // ST (STY extended) case 0xbf: tick(7); Processor::setWord(Address_extended(), st(Y())); break; // ST (STY extended)
// SWI // SWI
case 0x3f: addCycles(11); swi2(); break; // SWI (SWI2 inherent) case 0x3f: tick(11); swi2(); break; // SWI (SWI2 inherent)
default: default:
UNREACHABLE; UNREACHABLE;
@ -556,19 +556,19 @@ void EightBit::mc6809::execute11() {
// CMP // CMP
// CMPU // CMPU
case 0x83: addCycles(5); cmp(U(), AM_immediate_word()); break; // CMP (CMPU, immediate) case 0x83: tick(5); cmp(U(), AM_immediate_word()); break; // CMP (CMPU, immediate)
case 0x93: addCycles(7); cmp(U(), AM_direct_word()); break; // CMP (CMPU, direct) case 0x93: tick(7); cmp(U(), AM_direct_word()); break; // CMP (CMPU, direct)
case 0xa3: addCycles(7); cmp(U(), AM_indexed_word()); break; // CMP (CMPU, indexed) case 0xa3: tick(7); cmp(U(), AM_indexed_word()); break; // CMP (CMPU, indexed)
case 0xb3: addCycles(8); cmp(U(), AM_extended_word()); break; // CMP (CMPU, extended) case 0xb3: tick(8); cmp(U(), AM_extended_word()); break; // CMP (CMPU, extended)
// CMPS // CMPS
case 0x8c: addCycles(5); cmp(S(), AM_immediate_word()); break; // CMP (CMPS, immediate) case 0x8c: tick(5); cmp(S(), AM_immediate_word()); break; // CMP (CMPS, immediate)
case 0x9c: addCycles(7); cmp(S(), AM_direct_word()); break; // CMP (CMPS, direct) case 0x9c: tick(7); cmp(S(), AM_direct_word()); break; // CMP (CMPS, direct)
case 0xac: addCycles(7); cmp(S(), AM_indexed_word()); break; // CMP (CMPS, indexed) case 0xac: tick(7); cmp(S(), AM_indexed_word()); break; // CMP (CMPS, indexed)
case 0xbc: addCycles(8); cmp(S(), AM_extended_word()); break; // CMP (CMPS, extended) case 0xbc: tick(8); cmp(S(), AM_extended_word()); break; // CMP (CMPS, extended)
// SWI // SWI
case 0x3f: addCycles(11); swi3(); break; // SWI (SWI3 inherent) case 0x3f: tick(11); swi3(); break; // SWI (SWI3 inherent)
default: default:
UNREACHABLE; UNREACHABLE;
@ -634,21 +634,21 @@ EightBit::register16_t EightBit::mc6809::Address_indexed() {
switch (type & Mask4) { switch (type & Mask4) {
case 0b0000: // ,R+ case 0b0000: // ,R+
ASSUME(!indirect); ASSUME(!indirect);
addCycles(2); tick(2);
address = r++; address = r++;
break; break;
case 0b0001: // ,R++ case 0b0001: // ,R++
addCycles(3); tick(3);
address = r; address = r;
r += 2; r += 2;
break; break;
case 0b0010: // ,-R case 0b0010: // ,-R
ASSUME(!indirect); ASSUME(!indirect);
addCycles(2); tick(2);
address = --r; address = --r;
break; break;
case 0b0011: // ,--R case 0b0011: // ,--R
addCycles(3); tick(3);
r -= 2; r -= 2;
address = r; address = r;
break; break;
@ -656,48 +656,48 @@ EightBit::register16_t EightBit::mc6809::Address_indexed() {
address = r; address = r;
break; break;
case 0b0101: // B,R case 0b0101: // B,R
addCycles(1); tick(1);
address = r + (int8_t)B(); address = r + (int8_t)B();
break; break;
case 0b0110: // A,R case 0b0110: // A,R
addCycles(1); tick(1);
address = r + (int8_t)A(); address = r + (int8_t)A();
break; break;
case 0b1000: // n,R (eight-bit) case 0b1000: // n,R (eight-bit)
addCycles(1); tick(1);
address = r + (int8_t)fetchByte(); address = r + (int8_t)fetchByte();
break; break;
case 0b1001: // n,R (sixteen-bit) case 0b1001: // n,R (sixteen-bit)
addCycles(4); tick(4);
address = r + (int16_t)fetchWord().word; address = r + (int16_t)fetchWord().word;
break; break;
case 0b1011: // D,R case 0b1011: // D,R
addCycles(4); tick(4);
address = r + D(); address = r + D();
break; break;
case 0b1100: // n,PCR (eight-bit) case 0b1100: // n,PCR (eight-bit)
addCycles(1); tick(1);
address = Address_relative_byte(); address = Address_relative_byte();
break; break;
case 0b1101: // n,PCR (sixteen-bit) case 0b1101: // n,PCR (sixteen-bit)
addCycles(2); tick(2);
address = Address_relative_word(); address = Address_relative_word();
break; break;
case 0b1111: // [n] case 0b1111: // [n]
assert(indirect); assert(indirect);
addCycles(2); tick(2);
address = Address_extended(); address = Address_extended();
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
} }
if (indirect) { if (indirect) {
addCycles(3); tick(3);
address = Processor::getWord(address); address = Processor::getWord(address);
} }
} else { } else {
// EA = ,R + 5-bit offset // EA = ,R + 5-bit offset
addCycle(); tick();
address = r + signExtend(5, type & Mask5); address = r + signExtend(5, type & Mask5);
} }
return address; return address;
@ -944,72 +944,72 @@ uint8_t EightBit::mc6809::orr(const uint8_t operand, const uint8_t data) {
void EightBit::mc6809::psh(register16_t& stack, const uint8_t data) { void EightBit::mc6809::psh(register16_t& stack, const uint8_t data) {
if (data & Bit7) { if (data & Bit7) {
addCycles(2); tick(2);
pushWord(stack, PC()); pushWord(stack, PC());
} }
if (data & Bit6) { if (data & Bit6) {
addCycles(2); tick(2);
// Pushing to the S stack means we must be pushing U // Pushing to the S stack means we must be pushing U
pushWord(stack, &stack == &S() ? U() : S()); pushWord(stack, &stack == &S() ? U() : S());
} }
if (data & Bit5) { if (data & Bit5) {
addCycles(2); tick(2);
pushWord(stack, Y()); pushWord(stack, Y());
} }
if (data & Bit4) { if (data & Bit4) {
addCycles(2); tick(2);
pushWord(stack, X()); pushWord(stack, X());
} }
if (data & Bit3) { if (data & Bit3) {
addCycle(); tick();
push(stack, DP()); push(stack, DP());
} }
if (data & Bit2) { if (data & Bit2) {
addCycle(); tick();
push(stack, B()); push(stack, B());
} }
if (data & Bit1) { if (data & Bit1) {
addCycle(); tick();
push(stack, A()); push(stack, A());
} }
if (data & Bit0) { if (data & Bit0) {
addCycle(); tick();
push(stack, CC()); push(stack, CC());
} }
} }
void EightBit::mc6809::pul(register16_t& stack, const uint8_t data) { void EightBit::mc6809::pul(register16_t& stack, const uint8_t data) {
if (data & Bit0) { if (data & Bit0) {
addCycle(); tick();
CC() = pop(stack); CC() = pop(stack);
} }
if (data & Bit1) { if (data & Bit1) {
addCycle(); tick();
A() = pop(stack); A() = pop(stack);
} }
if (data & Bit2) { if (data & Bit2) {
addCycle(); tick();
B() = pop(stack); B() = pop(stack);
} }
if (data & Bit3) { if (data & Bit3) {
addCycle(); tick();
DP() = pop(stack); DP() = pop(stack);
} }
if (data & Bit4) { if (data & Bit4) {
addCycles(2); tick(2);
X() = popWord(stack); X() = popWord(stack);
} }
if (data & Bit5) { if (data & Bit5) {
addCycles(2); tick(2);
Y() = popWord(stack); Y() = popWord(stack);
} }
if (data & Bit6) { if (data & Bit6) {
addCycles(2); tick(2);
// Pulling from the S stack means we must be pulling U // Pulling from the S stack means we must be pulling U
(&stack == &S() ? U() : S()) = popWord(stack); (&stack == &S() ? U() : S()) = popWord(stack);
} }
if (data & Bit7) { if (data & Bit7) {
addCycles(2); tick(2);
PC() = popWord(stack); PC() = popWord(stack);
} }
} }

View File

@ -49,7 +49,7 @@ void EightBit::Z80::powerOn() {
void EightBit::Z80::handleRESET() { void EightBit::Z80::handleRESET() {
IntelProcessor::handleRESET(); IntelProcessor::handleRESET();
di(); di();
addCycles(3); tick(3);
} }
void EightBit::Z80::handleNMI() { void EightBit::Z80::handleNMI() {
@ -57,7 +57,7 @@ void EightBit::Z80::handleNMI() {
raise(HALT()); raise(HALT());
IFF1() = false; IFF1() = false;
restart(0x66); restart(0x66);
addCycles(13); tick(13);
} }
void EightBit::Z80::handleINT() { void EightBit::Z80::handleINT() {
@ -71,11 +71,11 @@ void EightBit::Z80::handleINT() {
break; break;
case 1: case 1:
restart(7 << 3); restart(7 << 3);
addCycles(13); tick(13);
break; break;
case 2: case 2:
call(MEMPTR() = register16_t(BUS().DATA(), IV())); call(MEMPTR() = register16_t(BUS().DATA(), IV()));
addCycles(19); tick(19);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -758,24 +758,24 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
UNREACHABLE; UNREACHABLE;
} }
adjustSZP<Z80>(F(), operand); adjustSZP<Z80>(F(), operand);
addCycles(8); tick(8);
break; break;
} case 1: // BIT y, r[z] } case 1: // BIT y, r[z]
addCycles(8); tick(8);
bit(y, operand); bit(y, operand);
if (LIKELY(direct)) { if (LIKELY(direct)) {
adjustXY<Z80>(F(), operand); adjustXY<Z80>(F(), operand);
} else { } else {
adjustXY<Z80>(F(), MEMPTR().high); adjustXY<Z80>(F(), MEMPTR().high);
addCycles(4); tick(4);
} }
break; break;
case 2: // RES y, r[z] case 2: // RES y, r[z]
addCycles(8); tick(8);
operand = res(y, operand); operand = res(y, operand);
break; break;
case 3: // SET y, r[z] case 3: // SET y, r[z]
addCycles(8); tick(8);
operand = set(y, operand); operand = set(y, operand);
break; break;
default: default:
@ -785,11 +785,11 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
if (LIKELY(!m_displaced)) { if (LIKELY(!m_displaced)) {
R(z, operand); R(z, operand);
if (UNLIKELY(memoryZ)) if (UNLIKELY(memoryZ))
addCycles(7); tick(7);
} else { } else {
BUS().write(operand); BUS().write(operand);
R2(z, operand); R2(z, operand);
addCycles(15); tick(15);
} }
} }
} }
@ -810,7 +810,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
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
addCycles(8); tick(8);
break; break;
case 1: case 1:
switch (z) { switch (z) {
@ -821,7 +821,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
R(y, BUS().DATA()); R(y, BUS().DATA());
adjustSZPXY<Z80>(F(), BUS().DATA()); adjustSZPXY<Z80>(F(), BUS().DATA());
clearFlag(F(), NF | HC); clearFlag(F(), NF | HC);
addCycles(12); tick(12);
break; break;
case 1: // Output to port with 16-bit address case 1: // Output to port with 16-bit address
(MEMPTR() = BUS().ADDRESS() = BC())++; (MEMPTR() = BUS().ADDRESS() = BC())++;
@ -830,7 +830,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
else // OUT (C),0 else // OUT (C),0
BUS().DATA() = 0; BUS().DATA() = 0;
writePort(); writePort();
addCycles(12); tick(12);
break; break;
case 2: // 16-bit add/subtract with carry case 2: // 16-bit add/subtract with carry
switch (q) { switch (q) {
@ -843,7 +843,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(15); tick(15);
break; break;
case 3: // Retrieve/store register pair from/to immediate address case 3: // Retrieve/store register pair from/to immediate address
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
@ -857,11 +857,11 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(20); tick(20);
break; break;
case 4: // Negate accumulator case 4: // Negate accumulator
neg(); neg();
addCycles(8); tick(8);
break; break;
case 5: // Return from interrupt case 5: // Return from interrupt
switch (y) { switch (y) {
@ -872,7 +872,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
retn(); // RETN retn(); // RETN
break; break;
} }
addCycles(14); tick(14);
break; break;
case 6: // Set interrupt mode case 6: // Set interrupt mode
switch (y) { switch (y) {
@ -893,41 +893,41 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(8); tick(8);
break; break;
case 7: // Assorted ops case 7: // Assorted ops
switch (y) { switch (y) {
case 0: // LD I,A case 0: // LD I,A
IV() = A(); IV() = A();
addCycles(9); tick(9);
break; break;
case 1: // LD R,A case 1: // LD R,A
REFRESH() = A(); REFRESH() = A();
addCycles(9); tick(9);
break; break;
case 2: // LD A,I case 2: // LD A,I
adjustSZXY<Z80>(F(), A() = IV()); adjustSZXY<Z80>(F(), A() = IV());
clearFlag(F(), NF | HC); clearFlag(F(), NF | HC);
setFlag(F(), PF, IFF2()); setFlag(F(), PF, IFF2());
addCycles(9); tick(9);
break; break;
case 3: // LD A,R case 3: // LD A,R
adjustSZXY<Z80>(F(), A() = REFRESH()); adjustSZXY<Z80>(F(), A() = REFRESH());
clearFlag(F(), NF | HC); clearFlag(F(), NF | HC);
setFlag(F(), PF, IFF2()); setFlag(F(), PF, IFF2());
addCycles(9); tick(9);
break; break;
case 4: // RRD case 4: // RRD
rrd(); rrd();
addCycles(18); tick(18);
break; break;
case 5: // RLD case 5: // RLD
rld(); rld();
addCycles(18); tick(18);
break; break;
case 6: // NOP case 6: // NOP
case 7: // NOP case 7: // NOP
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -951,14 +951,14 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
if (LIKELY(ldir())) { if (LIKELY(ldir())) {
MEMPTR() = --PC(); MEMPTR() = --PC();
--PC(); --PC();
addCycles(5); tick(5);
} }
break; break;
case 7: // LDDR case 7: // LDDR
if (LIKELY(lddr())) { if (LIKELY(lddr())) {
MEMPTR() = --PC(); MEMPTR() = --PC();
--PC(); --PC();
addCycles(5); tick(5);
} }
break; break;
} }
@ -975,14 +975,14 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
if (LIKELY(cpir())) { if (LIKELY(cpir())) {
MEMPTR() = --PC(); MEMPTR() = --PC();
--PC(); --PC();
addCycles(5); tick(5);
} }
break; break;
case 7: // CPDR case 7: // CPDR
if (LIKELY(cpdr())) { if (LIKELY(cpdr())) {
MEMPTR() = --PC(); MEMPTR() = --PC();
--PC(); --PC();
addCycles(5); tick(5);
} else { } else {
MEMPTR() = PC() - 2; MEMPTR() = PC() - 2;
} }
@ -1000,13 +1000,13 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
case 6: // INIR case 6: // INIR
if (LIKELY(inir())) { if (LIKELY(inir())) {
PC() -= 2; PC() -= 2;
addCycles(5); tick(5);
} }
break; break;
case 7: // INDR case 7: // INDR
if (LIKELY(indr())) { if (LIKELY(indr())) {
PC() -= 2; PC() -= 2;
addCycles(5); tick(5);
} }
break; break;
} }
@ -1022,19 +1022,19 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
case 6: // OTIR case 6: // OTIR
if (LIKELY(otir())) { if (LIKELY(otir())) {
PC() -= 2; PC() -= 2;
addCycles(5); tick(5);
} }
break; break;
case 7: // OTDR case 7: // OTDR
if (LIKELY(otdr())) { if (LIKELY(otdr())) {
PC() -= 2; PC() -= 2;
addCycles(5); tick(5);
} }
break; break;
} }
break; break;
} }
addCycles(16); tick(16);
break; break;
} }
} }
@ -1058,28 +1058,28 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
case 0: // Relative jumps and assorted ops case 0: // Relative jumps and assorted ops
switch (y) { switch (y) {
case 0: // NOP case 0: // NOP
addCycles(4); tick(4);
break; break;
case 1: // EX AF AF' case 1: // EX AF AF'
exxAF(); exxAF();
addCycles(4); tick(4);
break; break;
case 2: // DJNZ d case 2: // DJNZ d
if (LIKELY(jrConditional(--B()))) if (LIKELY(jrConditional(--B())))
addCycles(5); tick(5);
addCycles(8); tick(8);
break; break;
case 3: // JR d case 3: // JR d
jr(fetchByte()); jr(fetchByte());
addCycles(12); tick(12);
break; break;
case 4: // JR cc,d case 4: // JR cc,d
case 5: case 5:
case 6: case 6:
case 7: case 7:
if (UNLIKELY(jrConditionalFlag(y - 4))) if (UNLIKELY(jrConditionalFlag(y - 4)))
addCycles(5); tick(5);
addCycles(5); tick(5);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1089,11 +1089,11 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
switch (q) { switch (q) {
case 0: // LD rp,nn case 0: // LD rp,nn
RP(p) = fetchWord(); RP(p) = fetchWord();
addCycles(10); tick(10);
break; break;
case 1: // ADD HL,rp case 1: // ADD HL,rp
add(RP(p)); add(RP(p));
addCycles(11); tick(11);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1107,24 +1107,24 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
(MEMPTR() = BUS().ADDRESS() = BC())++; (MEMPTR() = BUS().ADDRESS() = BC())++;
MEMPTR().high = BUS().DATA() = A(); MEMPTR().high = BUS().DATA() = A();
BUS().write(); BUS().write();
addCycles(7); tick(7);
break; break;
case 1: // LD (DE),A case 1: // LD (DE),A
(MEMPTR() = BUS().ADDRESS() = DE())++; (MEMPTR() = BUS().ADDRESS() = DE())++;
MEMPTR().high = BUS().DATA() = A(); MEMPTR().high = BUS().DATA() = A();
BUS().write(); BUS().write();
addCycles(7); tick(7);
break; break;
case 2: // LD (nn),HL case 2: // LD (nn),HL
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
setWord(HL2()); setWord(HL2());
addCycles(16); tick(16);
break; break;
case 3: // LD (nn),A case 3: // LD (nn),A
(MEMPTR() = BUS().ADDRESS() = fetchWord())++; (MEMPTR() = BUS().ADDRESS() = fetchWord())++;
MEMPTR().high = BUS().DATA() = A(); MEMPTR().high = BUS().DATA() = A();
BUS().write(); BUS().write();
addCycles(13); tick(13);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1135,22 +1135,22 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
case 0: // LD A,(BC) case 0: // LD A,(BC)
(MEMPTR() = BUS().ADDRESS() = BC())++; (MEMPTR() = BUS().ADDRESS() = BC())++;
A() = BUS().read(); A() = BUS().read();
addCycles(7); tick(7);
break; break;
case 1: // LD A,(DE) case 1: // LD A,(DE)
(MEMPTR() = BUS().ADDRESS() = DE())++; (MEMPTR() = BUS().ADDRESS() = DE())++;
A() = BUS().read(); A() = BUS().read();
addCycles(7); tick(7);
break; break;
case 2: // LD HL,(nn) case 2: // LD HL,(nn)
BUS().ADDRESS() = fetchWord(); BUS().ADDRESS() = fetchWord();
HL2() = getWord(); HL2() = getWord();
addCycles(16); tick(16);
break; break;
case 3: // LD A,(nn) case 3: // LD A,(nn)
(MEMPTR() = BUS().ADDRESS() = fetchWord())++; (MEMPTR() = BUS().ADDRESS() = fetchWord())++;
A() = BUS().read(); A() = BUS().read();
addCycles(13); tick(13);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1171,31 +1171,31 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(6); tick(6);
break; break;
case 4: // 8-bit INC case 4: // 8-bit INC
if (UNLIKELY(m_displaced && memoryY)) if (UNLIKELY(m_displaced && memoryY))
fetchDisplacement(); fetchDisplacement();
R(y, increment(R(y))); R(y, increment(R(y)));
addCycles(4); tick(4);
break; break;
case 5: // 8-bit DEC case 5: // 8-bit DEC
if (UNLIKELY(memoryY)) { if (UNLIKELY(memoryY)) {
addCycles(7); tick(7);
if (UNLIKELY(m_displaced)) if (UNLIKELY(m_displaced))
fetchDisplacement(); fetchDisplacement();
} }
R(y, decrement(R(y))); R(y, decrement(R(y)));
addCycles(4); tick(4);
break; break;
case 6: // 8-bit load immediate case 6: // 8-bit load immediate
if (UNLIKELY(memoryY)) { if (UNLIKELY(memoryY)) {
addCycles(3); tick(3);
if (UNLIKELY(m_displaced)) if (UNLIKELY(m_displaced))
fetchDisplacement(); fetchDisplacement();
} }
R(y, fetchByte()); // LD r,n R(y, fetchByte()); // LD r,n
addCycles(7); tick(7);
break; break;
case 7: // Assorted operations on accumulator/flags case 7: // Assorted operations on accumulator/flags
switch (y) { switch (y) {
@ -1226,7 +1226,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1266,15 +1266,15 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
if (LIKELY(normal)) if (LIKELY(normal))
R(y, R(z)); R(y, R(z));
if (UNLIKELY(memoryY || memoryZ)) // M operations if (UNLIKELY(memoryY || memoryZ)) // M operations
addCycles(3); tick(3);
} else { // Exception (replaces LD (HL), (HL)) } else { // Exception (replaces LD (HL), (HL))
halt(); halt();
} }
addCycles(4); tick(4);
break; break;
case 2: { // Operate on accumulator and register/memory location case 2: { // Operate on accumulator and register/memory location
if (UNLIKELY(memoryZ)) { if (UNLIKELY(memoryZ)) {
addCycles(3); tick(3);
if (UNLIKELY(m_displaced)) if (UNLIKELY(m_displaced))
fetchDisplacement(); fetchDisplacement();
} }
@ -1307,39 +1307,39 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(4); tick(4);
break; break;
} }
case 3: case 3:
switch (z) { switch (z) {
case 0: // Conditional return case 0: // Conditional return
if (UNLIKELY(returnConditionalFlag(y))) if (UNLIKELY(returnConditionalFlag(y)))
addCycles(6); tick(6);
addCycles(5); tick(5);
break; break;
case 1: // POP & various ops case 1: // POP & various ops
switch (q) { switch (q) {
case 0: // POP rp2[p] case 0: // POP rp2[p]
RP2(p) = popWord(); RP2(p) = popWord();
addCycles(10); tick(10);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // RET case 0: // RET
ret(); ret();
addCycles(10); tick(10);
break; break;
case 1: // EXX case 1: // EXX
exx(); exx();
addCycles(4); tick(4);
break; break;
case 2: // JP HL case 2: // JP HL
jump(HL2()); jump(HL2());
addCycles(4); tick(4);
break; break;
case 3: // LD SP,HL case 3: // LD SP,HL
SP() = HL2(); SP() = HL2();
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1351,13 +1351,13 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
break; break;
case 2: // Conditional jump case 2: // Conditional jump
jumpConditionalFlag(y); jumpConditionalFlag(y);
addCycles(10); tick(10);
break; break;
case 3: // Assorted operations case 3: // Assorted operations
switch (y) { switch (y) {
case 0: // JP nn case 0: // JP nn
jump(MEMPTR() = fetchWord()); jump(MEMPTR() = fetchWord());
addCycles(10); tick(10);
break; break;
case 1: // CB prefix case 1: // CB prefix
m_prefixCB = true; m_prefixCB = true;
@ -1368,27 +1368,27 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
break; break;
case 2: // OUT (n),A case 2: // OUT (n),A
writePort(fetchByte()); writePort(fetchByte());
addCycles(11); tick(11);
break; break;
case 3: // IN A,(n) case 3: // IN A,(n)
A() = readPort(fetchByte()); A() = readPort(fetchByte());
addCycles(11); tick(11);
break; break;
case 4: // EX (SP),HL case 4: // EX (SP),HL
xhtl(); xhtl();
addCycles(19); tick(19);
break; break;
case 5: // EX DE,HL case 5: // EX DE,HL
std::swap(DE(), HL()); std::swap(DE(), HL());
addCycles(4); tick(4);
break; break;
case 6: // DI case 6: // DI
di(); di();
addCycles(4); tick(4);
break; break;
case 7: // EI case 7: // EI
ei(); ei();
addCycles(4); tick(4);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;
@ -1396,20 +1396,20 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
break; break;
case 4: // Conditional call: CALL cc[y], nn case 4: // Conditional call: CALL cc[y], nn
if (UNLIKELY(callConditionalFlag(y))) if (UNLIKELY(callConditionalFlag(y)))
addCycles(7); tick(7);
addCycles(10); tick(10);
break; break;
case 5: // PUSH & various ops case 5: // PUSH & various ops
switch (q) { switch (q) {
case 0: // PUSH rp2[p] case 0: // PUSH rp2[p]
pushWord(RP2(p)); pushWord(RP2(p));
addCycles(11); tick(11);
break; break;
case 1: case 1:
switch (p) { switch (p) {
case 0: // CALL nn case 0: // CALL nn
call(MEMPTR() = fetchWord()); call(MEMPTR() = fetchWord());
addCycles(17); tick(17);
break; break;
case 1: // DD prefix case 1: // DD prefix
m_displaced = m_prefixDD = true; m_displaced = m_prefixDD = true;
@ -1464,12 +1464,12 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
default: default:
UNREACHABLE; UNREACHABLE;
} }
addCycles(7); tick(7);
break; break;
} }
case 7: // Restart: RST y * 8 case 7: // Restart: RST y * 8
restart(y << 3); restart(y << 3);
addCycles(11); tick(11);
break; break;
default: default:
UNREACHABLE; UNREACHABLE;

View File

@ -5,6 +5,7 @@
#include "Chip.h" #include "Chip.h"
#include "Bus.h" #include "Bus.h"
#include "Register.h" #include "Register.h"
#include "Signal.h"
#include "EightBitCompilerDefinitions.h" #include "EightBitCompilerDefinitions.h"
@ -17,6 +18,8 @@ namespace EightBit {
~Processor() {}; ~Processor() {};
Signal<EventArgs> Ticked;
[[nodiscard]] auto& PC() noexcept { return m_pc; } [[nodiscard]] auto& PC() noexcept { return m_pc; }
[[nodiscard]] auto& RESET() noexcept { return m_resetLine; } [[nodiscard]] auto& RESET() noexcept { return m_resetLine; }
@ -106,8 +109,8 @@ namespace EightBit {
virtual void ret(); virtual void ret();
void resetCycles() noexcept { m_cycles = 0; } void resetCycles() noexcept { m_cycles = 0; }
void addCycles(const int extra) noexcept { m_cycles += extra; } void tick(const int extra) { for (int i = 0; i < extra; ++i) tick(); }
void addCycle() noexcept { ++m_cycles; } void tick() { ++m_cycles; Ticked.fire(EventArgs::empty()); }
private: private:
Bus& m_bus; Bus& m_bus;