Share some implementation details on the MC6809, where possible. Somewhat closer to how I imagine the hardware is implemented...

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-10-18 22:25:52 +01:00
parent 966a07b018
commit 83497b0b9e
2 changed files with 41 additions and 49 deletions

View File

@ -300,9 +300,26 @@ namespace EightBit {
// Miscellaneous
void saveEntireRegisterState();
void savePartialRegisterState();
void saveRegisterState();
void restoreRegisterState();
// Instruction implementations
template <class T> T through(const T data) {
clearFlag(CC(), VF);
adjustNZ(data);
return data;
}
template <class T> T ld(const T data) {
return through(data);
}
template <class T> T st(const T data) {
return through(data);
}
uint8_t adc(uint8_t operand, uint8_t data);
uint8_t add(uint8_t operand, uint8_t data, uint8_t carry = 0);
register16_t add(register16_t operand, register16_t data);
@ -320,8 +337,6 @@ namespace EightBit {
void exg(uint8_t data);
uint8_t inc(uint8_t operand);
void jsr(register16_t address);
uint8_t ld(uint8_t data);
register16_t ld(register16_t data);
uint8_t lsr(uint8_t operand);
register16_t mul(uint8_t first, uint8_t second);
uint8_t neg(uint8_t operand);
@ -339,8 +354,6 @@ namespace EightBit {
void swi();
void swi2();
void swi3();
uint8_t st(uint8_t data);
register16_t st(register16_t data);
void tfr(uint8_t data);
void tst(uint8_t data);

View File

@ -78,9 +78,7 @@ void EightBit::mc6809::handleFIRQ() {
raise(FIRQ());
lower(BA());
raise(BS());
clearFlag(CC(), EF);
pushWordS(PC());
pushS(CC());
savePartialRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, FIRQvector));
@ -670,16 +668,16 @@ EightBit::register16_t EightBit::mc6809::Address_indexed() {
break;
case 0b1100: // n,PCR (eight-bit)
addCycles(1);
address = PC() + (int8_t)fetchByte();
address = Address_relative_byte();
break;
case 0b1101: // n,PCR (sixteen-bit)
addCycles(2);
address = PC() + (int16_t)fetchWord().word;
address = Address_relative_word();
break;
case 0b1111: // [n]
assert(indirect);
addCycles(2);
address = fetchWord();
address = Address_extended();
break;
default:
UNREACHABLE;
@ -739,8 +737,21 @@ EightBit::register16_t EightBit::mc6809::AM_extended_word() {
//
void EightBit::mc6809::saveEntireRegisterState() {
setFlag(CC(), EF); // Entire flag set saved
psh(S(), 0xff);
setFlag(CC(), EF);
saveRegisterState();
}
void EightBit::mc6809::savePartialRegisterState() {
clearFlag(CC(), EF);
saveRegisterState();
}
void EightBit::mc6809::saveRegisterState() {
psh(S(), CC() & EF ? 0xff : 0b10000001);
}
void EightBit::mc6809::restoreRegisterState() {
pul(S(), CC() & EF ? 0xff : 0b10000001);
}
//
@ -761,10 +772,8 @@ EightBit::register16_t EightBit::mc6809::add(const register16_t operand, const r
return addition & Mask16;
}
uint8_t EightBit::mc6809::andr(uint8_t operand, const uint8_t data) {
clearFlag(CC(), VF);
adjustNZ(operand &= data);
return operand;
uint8_t EightBit::mc6809::andr(const uint8_t operand, const uint8_t data) {
return through((uint8_t)(operand & data));
}
uint8_t EightBit::mc6809::asl(uint8_t operand) {
@ -798,11 +807,8 @@ void EightBit::mc6809::cmp(const register16_t operand, const register16_t data)
}
uint8_t EightBit::mc6809::com(const uint8_t operand) {
const uint8_t result = ~operand;
adjustNZ(result);
clearFlag(CC(), VF);
setFlag(CC(), CF);
return result;
return through((uint8_t)~operand);
}
void EightBit::mc6809::cwai(const uint8_t data) {
@ -813,7 +819,6 @@ void EightBit::mc6809::cwai(const uint8_t data) {
uint8_t EightBit::mc6809::da(uint8_t operand) {
clearFlag(CC(), VF);
setFlag(CC(), CF, operand > 0x99);
const auto lowAdjust = halfCarry() || (lowNibble(operand) > 9);
@ -824,9 +829,7 @@ uint8_t EightBit::mc6809::da(uint8_t operand) {
if (highAdjust)
operand += 0x60;
adjustNZ(operand);
return operand;
return through(operand);
}
uint8_t EightBit::mc6809::dec(const uint8_t operand) {
@ -904,18 +907,6 @@ void EightBit::mc6809::jsr(const register16_t address) {
call(address);
}
uint8_t EightBit::mc6809::ld(const uint8_t data) {
clearFlag(CC(), VF);
adjustNZ(data);
return data;
}
EightBit::register16_t EightBit::mc6809::ld(const register16_t data) {
clearFlag(CC(), VF);
adjustNZ(data);
return data;
}
uint8_t EightBit::mc6809::lsr(uint8_t operand) {
setFlag(CC(), CF, operand & Bit0);
adjustNZ(operand >>= 1);
@ -1036,7 +1027,7 @@ uint8_t EightBit::mc6809::ror(uint8_t operand) {
}
void EightBit::mc6809::rti() {
pul(S(), CC() & EF ? 0xff : 0b10000001);
restoreRegisterState();
}
void EightBit::mc6809::rts() {
@ -1079,18 +1070,6 @@ void EightBit::mc6809::tfr(const uint8_t data) {
referenceTransfer16(reg2) = referenceTransfer16(reg1);
}
uint8_t EightBit::mc6809::st(const uint8_t data) {
clearFlag(CC(), VF);
adjustNZ(data);
return data;
}
EightBit::register16_t EightBit::mc6809::st(const register16_t data) {
clearFlag(CC(), VF);
adjustNZ(data);
return data;
}
uint8_t EightBit::mc6809::sbc(const uint8_t operand, const uint8_t data) {
return sub(operand, data, carry());
}