Add PSH/PUL instructions to the 6809 processor

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-08-22 00:34:16 +01:00
parent 905e7d3d44
commit 86c9ade43f
2 changed files with 136 additions and 8 deletions

View File

@ -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;

View File

@ -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());
}