diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index 7f4e2ff..c836e37 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -77,6 +77,9 @@ namespace EightBit { protected: virtual void reset() final; + virtual void push(uint8_t value) final { pushS(value); } + virtual uint8_t pop() final { return popS(); } + private: const uint8_t RESETvector = 0xfe; // RESET vector const uint8_t NMIvector = 0xfc; // NMI vector @@ -87,6 +90,33 @@ namespace EightBit { const uint8_t SWI3vector = 0xf2; // SWI3 vector const uint8_t RESERVEDvector = 0xf0; // RESERVED vector + // Stack manipulation + + void push(register16_t& stack, uint8_t value); + void pushS(uint8_t value) { push(S(), value); } + void pushU(uint8_t value) { push(U(), value); } + + void pushWord(register16_t& stack, register16_t value) { + push(stack, value.low); + push(stack, value.high); + } + + void pushWordS(register16_t value) { pushWord(S(), value); } + void pushWordU(register16_t value) { pushWord(U(), value); } + + uint8_t pop(register16_t& stack); + uint8_t popS() { return pop(S()); } + uint8_t popU() { return pop(U()); } + + register16_t popWord(register16_t& stack) { + const auto high = pop(stack); + const auto low = pop(stack); + return register16_t(low, high); + } + + register16_t popWordS() { popWord(S()); } + register16_t popWordU() { popWord(U()); } + // Execution helpers int executeUnprefixed(uint8_t opcode); @@ -216,6 +246,10 @@ namespace EightBit { register16_t mul(uint8_t first, uint8_t second); uint8_t neg(uint8_t operand); uint8_t orr(uint8_t operand, uint8_t data); + void pshs(uint8_t data); + void pshu(uint8_t data); + void puls(uint8_t data); + void pulu(uint8_t data); register16_t m_d; register16_t m_x; diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index a0c9e67..5185fe7 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -272,6 +272,14 @@ int EightBit::mc6809::executeUnprefixed(uint8_t opcode) { // ORCC case 0x1a: addCycles(3); CC() |= AM_immediate_byte(); break; // OR (ORCC immediate) + // PSH + case 0x34: addCycles(5); pshs(AM_immediate_byte()); break; // PSH (PSHS immediate) + case 0x36: addCycles(5); pshu(AM_immediate_byte()); break; // PSH (PSHU immediate) + + // PUL + case 0x35: addCycles(5); puls(AM_immediate_byte()); break; // PUL (PULS immediate) + case 0x37: addCycles(5); pulu(AM_immediate_byte()); break; // PUL (PULU immediate) + default: UNREACHABLE; } @@ -364,6 +372,16 @@ int EightBit::mc6809::execute11(uint8_t opcode) { // +void EightBit::mc6809::push(register16_t& stack, uint8_t value) { + BUS().write(stack--, value); +} + +uint8_t EightBit::mc6809::pop(register16_t& stack) { + return BUS().read(++stack); +} + +// + EightBit::register16_t& EightBit::mc6809::RR(int which) { ASSUME(which >= 0); ASSUME(which <= 3); @@ -564,14 +582,14 @@ uint8_t EightBit::mc6809::com(uint8_t operand) { void EightBit::mc6809::cwai(uint8_t data) { CC() &= data; - pushWord(PC()); - pushWord(U()); - pushWord(Y()); - pushWord(X()); - push(DP()); - push(B()); - push(A()); - push(CC()); + pushWordS(PC()); + pushWordS(U()); + pushWordS(Y()); + pushWordS(X()); + pushS(DP()); + pushS(B()); + pushS(A()); + pushS(CC()); halt(); } @@ -698,3 +716,79 @@ uint8_t EightBit::mc6809::orr(uint8_t operand, uint8_t data) { adjustNZ(operand |= data); return operand; } + +void EightBit::mc6809::pshs(uint8_t data) { + if (data & Bit7) + pushWordS(PC()); + if (data & Bit6) + pushWordS(U()); + if (data & Bit5) + pushWordS(Y()); + if (data & Bit4) + pushWordS(X()); + if (data & Bit3) + pushS(DP()); + if (data & Bit2) + pushS(B()); + if (data & Bit1) + pushS(A()); + if (data & Bit0) + pushS(CC()); +} + +void EightBit::mc6809::pshu(uint8_t data) { + if (data & Bit7) + pushWordS(PC()); + if (data & Bit6) + pushWordS(S()); + if (data & Bit5) + pushWordS(Y()); + if (data & Bit4) + pushWordS(X()); + if (data & Bit3) + pushS(DP()); + if (data & Bit2) + pushS(B()); + if (data & Bit1) + pushS(A()); + if (data & Bit0) + pushS(CC()); +} + +void EightBit::mc6809::puls(uint8_t data) { + if (data & Bit0) + pushS(CC()); + if (data & Bit1) + pushS(A()); + if (data & Bit2) + pushS(B()); + if (data & Bit3) + pushS(DP()); + if (data & Bit4) + pushWordS(X()); + if (data & Bit5) + pushWordS(Y()); + if (data & Bit6) + pushWordS(U()); + if (data & Bit7) + pushWordS(PC()); +} + +void EightBit::mc6809::pulu(uint8_t data) { + if (data & Bit0) + pushS(CC()); + if (data & Bit1) + pushS(A()); + if (data & Bit2) + pushS(B()); + if (data & Bit3) + pushS(DP()); + if (data & Bit4) + pushWordS(X()); + if (data & Bit5) + pushWordS(Y()); + if (data & Bit6) + pushWordS(S()); + if (data & Bit7) + pushWordS(PC()); +}