mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-11 02:29:50 +00:00
Refactor the 6809 a little to shift large blocks of code from the header.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
a7835b943a
commit
cca7453e35
@ -12,26 +12,42 @@ namespace EightBit {
|
||||
class mc6809 : public BigEndianProcessor {
|
||||
public:
|
||||
enum StatusBits {
|
||||
EF = Bit7, // Entire flag: set if the complete machine state was saved in the stack.
|
||||
// If this bit is not set then only program counter and condition code
|
||||
// registers were saved in the stack. This bit is used by interrupt
|
||||
// handling routines only.
|
||||
// The bit is cleared by fast interrupts, and set by all other interrupts.
|
||||
FF = Bit6, // Fast interrupt mask: set if the FIRQ interrupt is disabled.
|
||||
HF = Bit5, // Half carry: set if there was a carry from bit 3 to bit 4 of the result
|
||||
// during the last add operation.
|
||||
IF = Bit4, // Interrupt mask: set if the IRQ interrupt is disabled.
|
||||
NF = Bit3, // Negative: set if the most significant bit of the result is set.
|
||||
// This bit can be set not only by arithmetic and logical operations,
|
||||
// but also by load / store operations.
|
||||
ZF = Bit2, // Zero: set if the result is zero. Like the N bit, this bit can be
|
||||
// set not only by arithmetic and logical operations, but also
|
||||
// by load / store operations.
|
||||
VF = Bit1, // Overflow: set if there was an overflow during last result calculation.
|
||||
// Logical, load and store operations clear this bit.
|
||||
CF = Bit0, // Carry: set if there was a carry from the bit 7 during last add
|
||||
// operation, or if there was a borrow from last subtract operation,
|
||||
// or if bit 7 of the A register was set during last MUL operation.
|
||||
|
||||
// Entire flag: set if the complete machine state was saved in the stack.
|
||||
// If this bit is not set then only program counter and condition code
|
||||
// registers were saved in the stack. This bit is used by interrupt
|
||||
// handling routines only.
|
||||
// The bit is cleared by fast interrupts, and set by all other interrupts.
|
||||
EF = Bit7,
|
||||
|
||||
// Fast interrupt mask: set if the FIRQ interrupt is disabled.
|
||||
FF = Bit6,
|
||||
|
||||
// Half carry: set if there was a carry from bit 3 to bit 4 of the result
|
||||
// during the last add operation.
|
||||
HF = Bit5,
|
||||
|
||||
// Interrupt mask: set if the IRQ interrupt is disabled.
|
||||
IF = Bit4,
|
||||
|
||||
// Negative: set if the most significant bit of the result is set.
|
||||
// This bit can be set not only by arithmetic and logical operations,
|
||||
// but also by load / store operations.
|
||||
NF = Bit3,
|
||||
|
||||
// Zero: set if the result is zero. Like the N bit, this bit can be
|
||||
// set not only by arithmetic and logical operations, but also
|
||||
// by load / store operations.
|
||||
ZF = Bit2,
|
||||
|
||||
// Overflow: set if there was an overflow during last result calculation.
|
||||
// Logical, load and store operations clear this bit.
|
||||
VF = Bit1,
|
||||
|
||||
// Carry: set if there was a carry from the bit 7 during last add
|
||||
// operation, or if there was a borrow from last subtract operation,
|
||||
// or if bit 7 of the A register was set during last MUL operation.
|
||||
CF = Bit0,
|
||||
};
|
||||
|
||||
mc6809(Bus& bus);
|
||||
@ -71,131 +87,19 @@ namespace EightBit {
|
||||
const uint8_t SWI3vector = 0xf2;
|
||||
const uint8_t RESERVEDvector = 0xf0;
|
||||
|
||||
//
|
||||
// Register selection for "indexed"
|
||||
register16_t& RR(int which);
|
||||
|
||||
void Address_direct() {
|
||||
BUS().ADDRESS() = register16_t(fetchByte(), DP());
|
||||
}
|
||||
// Addressing modes
|
||||
void Address_direct();
|
||||
void Address_indexed();
|
||||
void Address_extended();
|
||||
|
||||
register16_t& RR(int which) {
|
||||
ASSUME(which >= 0);
|
||||
ASSUME(which <= 3);
|
||||
switch (which) {
|
||||
case 0b00:
|
||||
return X();
|
||||
case 0b01:
|
||||
return Y();
|
||||
case 0b10:
|
||||
return U();
|
||||
case 0b11:
|
||||
return S();
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void Address_indexed() {
|
||||
const auto type = fetchByte();
|
||||
auto& rr = RR(type & (Bit6 | Bit5));
|
||||
switch (type & Bit7) {
|
||||
case 0: // EA = ,R + 5-bit offset
|
||||
addCycle();
|
||||
BUS().ADDRESS() = rr + (type & Mask5);
|
||||
break;
|
||||
case Bit7: {
|
||||
const auto indirect = type & Bit4;
|
||||
switch (type & Mask4) {
|
||||
case 0b0000: // , R+
|
||||
ASSUME(!indirect);
|
||||
addCycles(2);
|
||||
BUS().ADDRESS() = rr++;
|
||||
break;
|
||||
case 0b0001: // , R++
|
||||
addCycles(3);
|
||||
BUS().ADDRESS() = rr;
|
||||
rr += 2;
|
||||
break;
|
||||
case 0b0010: // , -R
|
||||
ASSUME(!indirect);
|
||||
addCycles(2);
|
||||
BUS().ADDRESS() = --rr;
|
||||
break;
|
||||
case 0b0011: // , --R
|
||||
addCycles(3);
|
||||
rr -= 2;
|
||||
BUS().ADDRESS() = rr;
|
||||
break;
|
||||
case 0b0100: // , R
|
||||
BUS().ADDRESS() = rr;
|
||||
break;
|
||||
case 0b0101: // B, R
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = rr + (int8_t)B();
|
||||
break;
|
||||
case 0b0110: // A, R
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = rr + (int8_t)A();
|
||||
break;
|
||||
case 0b1000: // n, R (eight-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = rr + (int8_t)fetchByte();
|
||||
break;
|
||||
case 0b1001: // n, R (sixteen-bit)
|
||||
addCycles(4);
|
||||
BUS().ADDRESS() = rr + fetchWord();
|
||||
break;
|
||||
case 0b1011: // D, R
|
||||
addCycles(4);
|
||||
BUS().ADDRESS() = rr + D();
|
||||
break;
|
||||
case 0b1100: // n, PCR (eight-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = PC() + (int8_t)fetchByte();
|
||||
break;
|
||||
case 0b1101: // n, PCR (sixteen-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = PC() + (int16_t)fetchWord().word;
|
||||
break;
|
||||
default:
|
||||
ASSUME(false);
|
||||
}
|
||||
if (indirect) {
|
||||
addCycles(3);
|
||||
BUS().ADDRESS() = fetchWord();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void Address_extended() {
|
||||
BUS().ADDRESS() = fetchWord();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint8_t AM_immediate() {
|
||||
return fetchByte();
|
||||
}
|
||||
|
||||
uint8_t AM_direct() {
|
||||
Address_direct();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
uint8_t AM_indexed() {
|
||||
Address_indexed();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
uint8_t AM_extended() {
|
||||
Address_extended();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
//
|
||||
// Addressing mode readers
|
||||
uint8_t AM_immediate();
|
||||
uint8_t AM_direct();
|
||||
uint8_t AM_indexed();
|
||||
uint8_t AM_extended();
|
||||
|
||||
void abx();
|
||||
uint8_t adc(uint8_t operand, uint8_t data);
|
||||
|
@ -51,7 +51,7 @@ int EightBit::mc6809::execute(uint8_t cell) {
|
||||
case 0x70: addCycles(7); BUS().write(neg(AM_extended())); break; // NEG (extended)
|
||||
|
||||
default:
|
||||
ASSUME(false);
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
ASSUME(cycles() > 0);
|
||||
@ -60,6 +60,126 @@ int EightBit::mc6809::execute(uint8_t cell) {
|
||||
|
||||
//
|
||||
|
||||
EightBit::register16_t& EightBit::mc6809::RR(int which) {
|
||||
ASSUME(which >= 0);
|
||||
ASSUME(which <= 3);
|
||||
switch (which) {
|
||||
case 0b00:
|
||||
return X();
|
||||
case 0b01:
|
||||
return Y();
|
||||
case 0b10:
|
||||
return U();
|
||||
case 0b11:
|
||||
return S();
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::mc6809::Address_direct() {
|
||||
BUS().ADDRESS() = register16_t(fetchByte(), DP());
|
||||
}
|
||||
|
||||
void EightBit::mc6809::Address_indexed() {
|
||||
const auto type = fetchByte();
|
||||
auto& r = RR((type & (Bit6 | Bit5)) >> 5);
|
||||
|
||||
if (type & Bit7) {
|
||||
const auto indirect = type & Bit4;
|
||||
switch (type & Mask4) {
|
||||
case 0b0000: // ,R+
|
||||
ASSUME(!indirect);
|
||||
addCycles(2);
|
||||
BUS().ADDRESS() = r++;
|
||||
break;
|
||||
case 0b0001: // ,R++
|
||||
addCycles(3);
|
||||
BUS().ADDRESS() = r;
|
||||
r += 2;
|
||||
break;
|
||||
case 0b0010: // ,-R
|
||||
ASSUME(!indirect);
|
||||
addCycles(2);
|
||||
BUS().ADDRESS() = --r;
|
||||
break;
|
||||
case 0b0011: // ,--R
|
||||
addCycles(3);
|
||||
r -= 2;
|
||||
BUS().ADDRESS() = r;
|
||||
break;
|
||||
case 0b0100: // ,R
|
||||
BUS().ADDRESS() = r;
|
||||
break;
|
||||
case 0b0101: // B,R
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = r + (int8_t)B();
|
||||
break;
|
||||
case 0b0110: // A,R
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = r + (int8_t)A();
|
||||
break;
|
||||
case 0b1000: // n,R (eight-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = r + (int8_t)fetchByte();
|
||||
break;
|
||||
case 0b1001: // n,R (sixteen-bit)
|
||||
addCycles(4);
|
||||
BUS().ADDRESS() = r + (int16_t)fetchWord().word;
|
||||
break;
|
||||
case 0b1011: // D,R
|
||||
addCycles(4);
|
||||
BUS().ADDRESS() = r + D();
|
||||
break;
|
||||
case 0b1100: // n,PCR (eight-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = PC() + (int8_t)fetchByte();
|
||||
break;
|
||||
case 0b1101: // n,PCR (sixteen-bit)
|
||||
addCycles(1);
|
||||
BUS().ADDRESS() = PC() + (int16_t)fetchWord().word;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
if (indirect) {
|
||||
addCycles(3);
|
||||
BUS().ADDRESS() = fetchWord();
|
||||
}
|
||||
} else {
|
||||
// EA = ,R + 5-bit offset
|
||||
addCycle();
|
||||
BUS().ADDRESS() = r + (type & Mask5);
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::mc6809::Address_extended() {
|
||||
BUS().ADDRESS() = fetchWord();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint8_t EightBit::mc6809::AM_immediate() {
|
||||
return fetchByte();
|
||||
}
|
||||
|
||||
uint8_t EightBit::mc6809::AM_direct() {
|
||||
Address_direct();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
uint8_t EightBit::mc6809::AM_indexed() {
|
||||
Address_indexed();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
uint8_t EightBit::mc6809::AM_extended() {
|
||||
Address_extended();
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void EightBit::mc6809::abx() {
|
||||
X() += B();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user