Implement SEX/SWI/SWI2/SWI3/SYNC/TFR instructions for the 6809

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-08-23 14:09:46 +01:00
parent e555fe335f
commit 1e32514e1d
2 changed files with 66 additions and 15 deletions

View File

@ -254,6 +254,10 @@ namespace EightBit {
return branch(Address_relative_word(), condition);
}
// Miscellaneous
void saveEntireRegisterState();
// Instruction implementations
uint8_t adc(uint8_t operand, uint8_t data);
@ -286,6 +290,11 @@ namespace EightBit {
uint8_t ror(uint8_t operand);
void rti();
void rts();
uint8_t sex(uint8_t from);
void swi();
void swi2();
void swi3();
void tfr(uint8_t data);
register16_t m_d;
register16_t m_x;

View File

@ -315,7 +315,7 @@ int EightBit::mc6809::executeUnprefixed(uint8_t opcode) {
case 0xf2: addCycles(5); break; // SBC (SBCB extended)
// SEX
case 0x1d: addCycles(2); break; // SEX (inherent)
case 0x1d: addCycles(2); A() = sex(B()); break; // SEX (inherent)
// ST
@ -365,13 +365,13 @@ int EightBit::mc6809::executeUnprefixed(uint8_t opcode) {
case 0xb3: addCycles(7); break; // SUB (SUBD extended)
// SWI
case 0x3f: addCycles(19); break; // SWI (inherent)
case 0x3f: addCycles(19); swi(); break; // SWI (inherent)
// SYNC
case 0x13: addCycles(4); break; // SYNC (inherent)
case 0x13: addCycles(4); halt(); break; // SYNC (inherent)
// TFR
case 0x1f: addCycles(6); break; // TFR (direct)
case 0x1f: addCycles(6); tfr(AM_immediate_byte()); break; // TFR (immediate)
// TST
case 0x0d: addCycles(6); break; // TST (direct)
@ -480,7 +480,7 @@ int EightBit::mc6809::execute10(uint8_t opcode) {
case 0xbf: addCycles(7); break; // ST (STY extended)
// SWI
case 0x3f: addCycles(20); break; // SWI (SWI2 inherent)
case 0x3f: addCycles(20); swi2(); break; // SWI (SWI2 inherent)
default:
UNREACHABLE;
@ -515,7 +515,7 @@ int EightBit::mc6809::execute11(uint8_t opcode) {
case 0xbc: addCycles(8); cmp(S(), AM_extended_word()); break; // CMP (CMPS, extended)
// SWI
case 0x3f: addCycles(20); break; // SWI (SWI3 inherent)
case 0x3f: addCycles(20); swi3(); break; // SWI (SWI3 inherent)
default:
UNREACHABLE;
@ -685,6 +685,20 @@ EightBit::register16_t EightBit::mc6809::AM_extended_word() {
//
void EightBit::mc6809::saveEntireRegisterState() {
CC() |= EF;
pushWordS(PC());
pushWordS(U());
pushWordS(Y());
pushWordS(X());
pushS(DP());
pushS(B());
pushS(A());
pushS(CC());
}
//
uint8_t EightBit::mc6809::adc(uint8_t operand, uint8_t data) {
return add(operand, data, CC() & CF);
}
@ -747,15 +761,7 @@ uint8_t EightBit::mc6809::com(uint8_t operand) {
void EightBit::mc6809::cwai(uint8_t data) {
CC() &= data;
CC() |= EF;
pushWordS(PC());
pushWordS(U());
pushWordS(Y());
pushWordS(X());
pushS(DP());
pushS(B());
pushS(A());
pushS(CC());
saveEntireRegisterState();
halt();
}
@ -1059,3 +1065,39 @@ void EightBit::mc6809::rti() {
void EightBit::mc6809::rts() {
ret();
}
void EightBit::mc6809::swi() {
saveEntireRegisterState();
setFlag(CC(), (IF | FF));
jump(getWordPaged(0xff, SWIvector));
}
void EightBit::mc6809::swi2() {
saveEntireRegisterState();
jump(getWordPaged(0xff, SWI2vector));
}
void EightBit::mc6809::swi3() {
saveEntireRegisterState();
jump(getWordPaged(0xff, SWI3vector));
}
uint8_t EightBit::mc6809::sex(uint8_t from) {
const uint8_t result = from & Bit7 ? Mask8 : 0;
adjustNZ(from);
return result;
}
void EightBit::mc6809::tfr(uint8_t data) {
const auto reg1 = highNibble(data);
const auto reg2 = lowNibble(data);
const bool type16 = !!(reg1 & Bit3); // 16 bit transfer?
ASSUME(type16 == !!(reg2 & Bit3)); // Regardless, the register transfer must be equivalent
if (type16)
referenceTransfer16(reg2) = referenceTransfer16(reg1);
else
referenceTransfer8(reg2) = referenceTransfer8(reg1);
}