mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Corrects performer storage, RMW/W confusion, implicit casts, port readback.
This commit is contained in:
parent
e8e604dc3c
commit
8789ffda15
@ -93,7 +93,7 @@ template <
|
||||
// Storage for the statically-allocated list of performers. It's a bit more
|
||||
// work for executors to fill this array, but subsequently performers can be
|
||||
// indexed by array position, which is a lot more compact than a generic pointer.
|
||||
std::array<Performer, max_performer_count> performers_;
|
||||
std::array<Performer, max_performer_count+1> performers_;
|
||||
ProgramCounterType program_counter_;
|
||||
|
||||
/*!
|
||||
@ -149,10 +149,12 @@ template <
|
||||
|
||||
while(remaining_duration_ > 0) {
|
||||
has_branched_ = false;
|
||||
Executor *const executor = static_cast<Executor *>(this);
|
||||
while(remaining_duration_ > 0 && !has_branched_) {
|
||||
const auto performer = performers_[program_[program_index_]];
|
||||
++program_index_;
|
||||
(static_cast<Executor *>(this)->*performer)();
|
||||
|
||||
(executor->*performer)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,9 +305,9 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
|
||||
// sequence below that wraps the address and checks whether
|
||||
// a write is valid [if required].
|
||||
|
||||
int address;
|
||||
unsigned int address;
|
||||
#define next8() memory_[(program_counter_ + 1) & 0x1fff]
|
||||
#define next16() (memory_[(program_counter_ + 1) & 0x1fff] | (memory_[(program_counter_ + 2) & 0x1fff] << 8))
|
||||
#define next16() uint16_t(memory_[(program_counter_ + 1) & 0x1fff] | (memory_[(program_counter_ + 2) & 0x1fff] << 8))
|
||||
|
||||
// Underlying assumption below: the instruction stream will never
|
||||
// overlap with IO ports.
|
||||
@ -333,7 +333,7 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
|
||||
// Special-purpose addressing modes.
|
||||
|
||||
case AddressingMode::Relative:
|
||||
address = program_counter_ + 1 + size(addressing_mode) + int8_t(next8());
|
||||
address = unsigned(program_counter_ + 1 + size(addressing_mode) + int8_t(next8()));
|
||||
break;
|
||||
|
||||
case AddressingMode::SpecialPage: address = 0x1f00 | next8(); break;
|
||||
@ -350,16 +350,16 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
|
||||
uint8_t value;
|
||||
if constexpr (addressing_mode == AddressingMode::AccumulatorRelative) {
|
||||
value = a_;
|
||||
address = program_counter_ + 1 + size(addressing_mode) + int8_t(next8());
|
||||
address = unsigned(program_counter_ + 1 + size(addressing_mode) + int8_t(next8()));
|
||||
} else {
|
||||
value = read(next8());
|
||||
address = program_counter_ + 1 + size(addressing_mode) + int8_t(memory_[(program_counter_+2)&0x1fff]);
|
||||
address = unsigned(program_counter_ + 1 + size(addressing_mode) + int8_t(memory_[(program_counter_+2)&0x1fff]));
|
||||
}
|
||||
program_counter_ += 1 + size(addressing_mode);
|
||||
switch(operation) {
|
||||
case Operation::BBS0: case Operation::BBS1: case Operation::BBS2: case Operation::BBS3:
|
||||
case Operation::BBS4: case Operation::BBS5: case Operation::BBS6: case Operation::BBS7:
|
||||
if constexpr (operation >= Operation::BBS0 && operation < Operation::BBS7) {
|
||||
if constexpr (operation >= Operation::BBS0 && operation <= Operation::BBS7) {
|
||||
if(value & (1 << (int(operation) - int(Operation::BBS0)))) {
|
||||
set_program_counter(uint16_t(address));
|
||||
subtract_duration(2);
|
||||
@ -368,7 +368,7 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
|
||||
return;
|
||||
case Operation::BBC0: case Operation::BBC1: case Operation::BBC2: case Operation::BBC3:
|
||||
case Operation::BBC4: case Operation::BBC5: case Operation::BBC6: case Operation::BBC7:
|
||||
if constexpr (operation >= Operation::BBC0 && operation < Operation::BBS7) {
|
||||
if constexpr (operation >= Operation::BBC0 && operation <= Operation::BBS7) {
|
||||
if(value & (1 << (int(operation) - int(Operation::BBC0)))) {
|
||||
set_program_counter(uint16_t(address));
|
||||
subtract_duration(2);
|
||||
@ -390,21 +390,21 @@ template <Operation operation, AddressingMode addressing_mode> void Executor::pe
|
||||
|
||||
case AddressingMode::ZeroPageIndirect:
|
||||
address = next8();
|
||||
address = memory_[address] | (memory_[(address + 1) & 0xff] << 8);
|
||||
address = unsigned(memory_[address] | (memory_[(address + 1) & 0xff] << 8));
|
||||
break;
|
||||
|
||||
case AddressingMode::XIndirect:
|
||||
address = (next8() + x_) & 0xff;
|
||||
address = memory_[address] | (memory_[(address + 1)&0xff] << 8);
|
||||
address = unsigned(memory_[address] | (memory_[(address + 1)&0xff] << 8));
|
||||
break;
|
||||
|
||||
case AddressingMode::IndirectY:
|
||||
address = (memory_[next8()] | (memory_[(next8()+1)&0xff] << 8)) + y_;
|
||||
address = unsigned((memory_[next8()] | (memory_[(next8()+1)&0xff] << 8)) + y_);
|
||||
break;
|
||||
|
||||
case AddressingMode::AbsoluteIndirect:
|
||||
address = next16();
|
||||
address = memory_[address] | (memory_[(address + 1) & 0x1fff] << 8);
|
||||
address = unsigned(memory_[address] | (memory_[(address + 1) & 0x1fff] << 8));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -488,11 +488,15 @@ template <Operation operation> void Executor::perform(uint8_t *operand [[maybe_u
|
||||
|
||||
case Operation::SEB0: case Operation::SEB1: case Operation::SEB2: case Operation::SEB3:
|
||||
case Operation::SEB4: case Operation::SEB5: case Operation::SEB6: case Operation::SEB7:
|
||||
*operand |= 1 << (int(operation) - int(Operation::SEB0));
|
||||
if constexpr(operation >= Operation::SEB0 && operation <= Operation::SEB7) {
|
||||
*operand |= 1 << (int(operation) - int(Operation::SEB0));
|
||||
}
|
||||
break;
|
||||
case Operation::CLB0: case Operation::CLB1: case Operation::CLB2: case Operation::CLB3:
|
||||
case Operation::CLB4: case Operation::CLB5: case Operation::CLB6: case Operation::CLB7:
|
||||
*operand &= ~(1 << (int(operation) - int(Operation::CLB0)));
|
||||
if constexpr(operation >= Operation::CLB0 && operation <= Operation::CLB7) {
|
||||
*operand &= ~(1 << (int(operation) - int(Operation::CLB0)));
|
||||
}
|
||||
break;
|
||||
|
||||
case Operation::CLI: interrupt_disable_ = 0x00; break;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../CachingExecutor.hpp"
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@ -63,7 +64,7 @@ class Executor: public CachingExecutor {
|
||||
*/
|
||||
inline void parse(uint16_t start, uint16_t closing_bound) {
|
||||
Parser<Executor, false> parser;
|
||||
parser.parse(*this, memory_, start & 0x1fff, closing_bound);
|
||||
parser.parse(*this, &memory_[0], start & 0x1fff, closing_bound);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -121,7 +122,7 @@ class Executor: public CachingExecutor {
|
||||
// MARK: - Instruction set state.
|
||||
|
||||
// Memory.
|
||||
uint8_t memory_[0x2000];
|
||||
std::array<uint8_t, 0x2000> memory_;
|
||||
|
||||
// Registers.
|
||||
uint8_t a_, x_, y_, s_;
|
||||
|
@ -94,8 +94,8 @@ static constexpr auto MinOperation = int(Operation::BBC0);
|
||||
constexpr AccessType access_type(Operation operation) {
|
||||
if(operation < Operation::ADC) return AccessType::None;
|
||||
if(operation < Operation::ASL) return AccessType::Read;
|
||||
if(operation < Operation::LDM) return AccessType::Write;
|
||||
return AccessType::ReadModifyWrite;
|
||||
if(operation < Operation::LDM) return AccessType::ReadModifyWrite;
|
||||
return AccessType::Write;
|
||||
}
|
||||
|
||||
constexpr bool uses_index_mode(Operation operation) {
|
||||
|
@ -226,6 +226,7 @@ void GLU::run_for(Cycles cycles) {
|
||||
// MARK: - M50470 port handler
|
||||
|
||||
void GLU::set_port_output(int port, uint8_t value) {
|
||||
ports_[port] = value;
|
||||
switch(port) {
|
||||
case 0:
|
||||
printf("Set R%d: %02x\n", register_address_, value);
|
||||
@ -261,10 +262,10 @@ uint8_t GLU::get_port_input(int port) {
|
||||
return 0x06;
|
||||
case 2:
|
||||
printf("ADB data line input, etc\n");
|
||||
return 0xff;
|
||||
return ports_[2];
|
||||
case 3:
|
||||
// printf("ADB data line output, etc\n");
|
||||
break;
|
||||
return ports_[3];
|
||||
|
||||
default: assert(false);
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ class GLU: public InstructionSet::M50740::PortHandler {
|
||||
|
||||
uint8_t registers_[16];
|
||||
uint8_t register_address_;
|
||||
uint8_t ports_[4];
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user