1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 23:25:00 +00:00

Route reads and writes through a common path.

This commit is contained in:
Thomas Harte
2022-05-08 17:17:46 -04:00
parent 0818fd7828
commit e35de357fa
2 changed files with 59 additions and 46 deletions

View File

@@ -18,6 +18,14 @@
namespace InstructionSet { namespace InstructionSet {
namespace M68k { namespace M68k {
enum class FunctionCode {
UserData = 0b001,
UserProgram = 0b010,
SupervisorData = 0b101,
SupervisorProgram = 0b110,
InterruptAcknowledge = 0b111,
};
struct BusHandler { struct BusHandler {
template <typename IntT> void write(uint32_t address, IntT value); template <typename IntT> void write(uint32_t address, IntT value);
template <typename IntT> IntT read(uint32_t address); template <typename IntT> IntT read(uint32_t address);
@@ -84,7 +92,11 @@ template <Model model, typename BusHandler> class Executor {
void read(DataSize size, uint32_t address, CPU::SlicedInt32 &value); void read(DataSize size, uint32_t address, CPU::SlicedInt32 &value);
void write(DataSize size, uint32_t address, CPU::SlicedInt32 value); void write(DataSize size, uint32_t address, CPU::SlicedInt32 value);
template <typename IntT> IntT read(uint32_t address);
template <typename IntT> void write(uint32_t address, IntT value);
template <typename IntT> IntT read_pc(); template <typename IntT> IntT read_pc();
uint32_t index_8bitdisplacement(); uint32_t index_8bitdisplacement();
// Processor state. // Processor state.

View File

@@ -31,43 +31,44 @@ void Executor<model, BusHandler>::reset() {
did_update_status(); did_update_status();
// Seed stack pointer and program counter. // Seed stack pointer and program counter.
sp.l = bus_handler_.template read<uint32_t>(0); sp.l = read<uint32_t>(0);
program_counter_.l = bus_handler_.template read<uint32_t>(4); program_counter_.l = read<uint32_t>(4);
}
template <Model model, typename BusHandler>
template <typename IntT>
IntT Executor<model, BusHandler>::read(uint32_t address) {
// TODO: check for an alignment exception, both here and in write.
return bus_handler_.template read<IntT>(address);
}
template <Model model, typename BusHandler>
template <typename IntT>
void Executor<model, BusHandler>::write(uint32_t address, IntT value) {
bus_handler_.template write<IntT>(address, value);
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::read(DataSize size, uint32_t address, CPU::SlicedInt32 &value) { void Executor<model, BusHandler>::read(DataSize size, uint32_t address, CPU::SlicedInt32 &value) {
switch(size) { switch(size) {
case DataSize::Byte: case DataSize::Byte: value.b = read<uint8_t>(address); break;
value.b = bus_handler_.template read<uint8_t>(address); case DataSize::Word: value.w = read<uint16_t>(address); break;
break; case DataSize::LongWord: value.l = read<uint32_t>(address); break;
case DataSize::Word:
value.w = bus_handler_.template read<uint16_t>(address);
break;
case DataSize::LongWord:
value.l = bus_handler_.template read<uint32_t>(address);
break;
} }
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::write(DataSize size, uint32_t address, CPU::SlicedInt32 value) { void Executor<model, BusHandler>::write(DataSize size, uint32_t address, CPU::SlicedInt32 value) {
switch(size) { switch(size) {
case DataSize::Byte: case DataSize::Byte: write<uint8_t>(address, value.b); break;
bus_handler_.template write<uint8_t>(address, value.b); case DataSize::Word: write<uint16_t>(address, value.w); break;
break; case DataSize::LongWord: write<uint32_t>(address, value.l); break;
case DataSize::Word:
bus_handler_.template write<uint16_t>(address, value.w);
break;
case DataSize::LongWord:
bus_handler_.template write<uint32_t>(address, value.l);
break;
} }
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
template <typename IntT> IntT Executor<model, BusHandler>::read_pc() { template <typename IntT> IntT Executor<model, BusHandler>::read_pc() {
const IntT result = bus_handler_.template read<IntT>(program_counter_.l); const IntT result = read<IntT>(program_counter_.l);
if constexpr (sizeof(IntT) == 4) { if constexpr (sizeof(IntT) == 4) {
program_counter_.l += 4; program_counter_.l += 4;
@@ -339,12 +340,12 @@ void Executor<model, BusHandler>::raise_exception(int index, bool use_current_in
did_update_status(); did_update_status();
// Push status and the program counter at instruction start. // Push status and the program counter at instruction start.
bus_handler_.template write<uint32_t>(sp.l - 4, use_current_instruction_pc ? instruction_address_ : program_counter_.l); write<uint32_t>(sp.l - 4, use_current_instruction_pc ? instruction_address_ : program_counter_.l);
bus_handler_.template write<uint16_t>(sp.l - 6, status); write<uint16_t>(sp.l - 6, status);
sp.l -= 6; sp.l -= 6;
// Fetch the new program counter. // Fetch the new program counter.
program_counter_.l = bus_handler_.template read<uint32_t>(address); program_counter_.l = read<uint32_t>(address);
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
@@ -371,14 +372,14 @@ void Executor<model, BusHandler>::add_pc(uint32_t offset) {
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::bsr(uint32_t offset) { void Executor<model, BusHandler>::bsr(uint32_t offset) {
sp.l -= 4; sp.l -= 4;
bus_handler_.template write<uint32_t>(sp.l, program_counter_.l); write<uint32_t>(sp.l, program_counter_.l);
program_counter_.l = instruction_address_ + offset; program_counter_.l = instruction_address_ + offset;
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::jsr(uint32_t address) { void Executor<model, BusHandler>::jsr(uint32_t address) {
sp.l -= 4; sp.l -= 4;
bus_handler_.template write<uint32_t>(sp.l, program_counter_.l); write<uint32_t>(sp.l, program_counter_.l);
program_counter_.l = address; program_counter_.l = address;
} }
@@ -387,7 +388,7 @@ void Executor<model, BusHandler>::link(Preinstruction instruction, uint32_t offs
const auto reg = 8 + instruction.reg<0>(); const auto reg = 8 + instruction.reg<0>();
sp.l -= 4; sp.l -= 4;
bus_handler_.template write<uint32_t>(sp.l, Dn(reg).l); write<uint32_t>(sp.l, Dn(reg).l);
Dn(reg) = sp; Dn(reg) = sp;
sp.l += offset; sp.l += offset;
} }
@@ -395,33 +396,33 @@ void Executor<model, BusHandler>::link(Preinstruction instruction, uint32_t offs
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::unlink(uint32_t &address) { void Executor<model, BusHandler>::unlink(uint32_t &address) {
sp.l = address; sp.l = address;
address = bus_handler_.template read<uint32_t>(sp.l); address = read<uint32_t>(sp.l);
sp.l += 4; sp.l += 4;
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::pea(uint32_t address) { void Executor<model, BusHandler>::pea(uint32_t address) {
sp.l -= 4; sp.l -= 4;
bus_handler_.template write<uint32_t>(sp.l, address); write<uint32_t>(sp.l, address);
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::rtr() { void Executor<model, BusHandler>::rtr() {
status_.set_ccr(bus_handler_.template read<uint16_t>(sp.l)); status_.set_ccr(read<uint16_t>(sp.l));
sp.l += 2; sp.l += 2;
rts(); rts();
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::rte() { void Executor<model, BusHandler>::rte() {
status_.set_status(bus_handler_.template read<uint16_t>(sp.l)); status_.set_status(read<uint16_t>(sp.l));
sp.l += 2; sp.l += 2;
rts(); rts();
} }
template <Model model, typename BusHandler> template <Model model, typename BusHandler>
void Executor<model, BusHandler>::rts() { void Executor<model, BusHandler>::rts() {
program_counter_.l = bus_handler_.template read<uint32_t>(sp.l); program_counter_.l = read<uint32_t>(sp.l);
sp.l += 4; sp.l += 4;
} }
@@ -429,8 +430,8 @@ template <Model model, typename BusHandler>
void Executor<model, BusHandler>::tas(Preinstruction instruction, uint32_t address) { void Executor<model, BusHandler>::tas(Preinstruction instruction, uint32_t address) {
uint8_t value; uint8_t value;
if(instruction.mode<0>() != AddressingMode::DataRegisterDirect) { if(instruction.mode<0>() != AddressingMode::DataRegisterDirect) {
value = bus_handler_.template read<uint8_t>(address); value = read<uint8_t>(address);
bus_handler_.template write<uint8_t>(address, value | 0x80); write<uint8_t>(address, value | 0x80);
} else { } else {
value = uint8_t(address); value = uint8_t(address);
Dn(instruction.reg<0>()).b = uint8_t(address | 0x80); Dn(instruction.reg<0>()).b = uint8_t(address | 0x80);
@@ -450,36 +451,36 @@ void Executor<model, BusHandler>::movep(Preinstruction instruction, uint32_t sou
uint32_t address = dest; uint32_t address = dest;
if constexpr (sizeof(IntT) == 4) { if constexpr (sizeof(IntT) == 4) {
bus_handler_.template write<uint8_t>(address, uint8_t(reg >> 24)); write<uint8_t>(address, uint8_t(reg >> 24));
address += 2; address += 2;
bus_handler_.template write<uint8_t>(address, uint8_t(reg >> 16)); write<uint8_t>(address, uint8_t(reg >> 16));
address += 2; address += 2;
} }
bus_handler_.template write<uint8_t>(address, uint8_t(reg >> 8)); write<uint8_t>(address, uint8_t(reg >> 8));
address += 2; address += 2;
bus_handler_.template write<uint8_t>(address, uint8_t(reg)); write<uint8_t>(address, uint8_t(reg));
} else { } else {
// Move memory to register. // Move memory to register.
uint32_t &reg = Dn(instruction.reg<1>()).l; uint32_t &reg = Dn(instruction.reg<1>()).l;
uint32_t address = source; uint32_t address = source;
if constexpr (sizeof(IntT) == 4) { if constexpr (sizeof(IntT) == 4) {
reg = bus_handler_.template read<uint8_t>(address) << 24; reg = read<uint8_t>(address) << 24;
address += 2; address += 2;
reg |= bus_handler_.template read<uint8_t>(address) << 16; reg |= read<uint8_t>(address) << 16;
address += 2; address += 2;
} else { } else {
reg &= 0xffff0000; reg &= 0xffff0000;
} }
reg |= bus_handler_.template read<uint8_t>(address) << 8; reg |= read<uint8_t>(address) << 8;
address += 2; address += 2;
reg |= bus_handler_.template read<uint8_t>(address); reg |= read<uint8_t>(address);
} }
} }
@@ -509,7 +510,7 @@ void Executor<model, BusHandler>::movem_toM(Preinstruction instruction, uint32_t
while(source) { while(source) {
if(source & 1) { if(source & 1) {
address -= sizeof(IntT); address -= sizeof(IntT);
bus_handler_.template write<IntT>(address, IntT(registers_[index].l)); write<IntT>(address, IntT(registers_[index].l));
} }
--index; --index;
source >>= 1; source >>= 1;
@@ -522,7 +523,7 @@ void Executor<model, BusHandler>::movem_toM(Preinstruction instruction, uint32_t
int index = 0; int index = 0;
while(source) { while(source) {
if(source & 1) { if(source & 1) {
bus_handler_.template write<IntT>(dest, IntT(registers_[index].l)); write<IntT>(dest, IntT(registers_[index].l));
dest += sizeof(IntT); dest += sizeof(IntT);
} }
++index; ++index;
@@ -544,9 +545,9 @@ void Executor<model, BusHandler>::movem_toR(Preinstruction instruction, uint32_t
while(source) { while(source) {
if(source & 1) { if(source & 1) {
if constexpr (sizeof(IntT) == 2) { if constexpr (sizeof(IntT) == 2) {
registers_[index].l = int16_t(bus_handler_.template read<uint16_t>(dest)); registers_[index].l = int16_t(read<uint16_t>(dest));
} else { } else {
registers_[index].l = bus_handler_.template read<uint32_t>(dest); registers_[index].l = read<uint32_t>(dest);
} }
dest += sizeof(IntT); dest += sizeof(IntT);
} }