1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-19 08:31:11 +00:00

Adds some extra commentary and distinguishes X/Y sizing from M.

This commit is contained in:
Thomas Harte 2020-10-31 10:21:13 -04:00
parent 1ae2f6f449
commit e8943618dc
2 changed files with 22 additions and 2 deletions

View File

@ -23,6 +23,9 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
Read, Write Read, Write
}; };
/// Divides memory-accessing instructions by whether they read or write.
/// Read-modify-writes are documented with completely distinct bus programs,
/// so there's no real ambiguity there.
constexpr static AccessType access_type_for_operation(Operation operation) { constexpr static AccessType access_type_for_operation(Operation operation) {
switch(operation) { switch(operation) {
case ADC: case AND: case BIT: case CMP: case ADC: case AND: case BIT: case CMP:
@ -41,6 +44,21 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
} }
} }
/// Indicates which of the memory-accessing instructions take their cue from the current
/// size of the index registers, rather than 'memory'[/accumulator].
constexpr static bool operation_is_index_sized(Operation operation) {
switch(operation) {
case CPX: case CPY:
case LDX: case LDY:
case STX: case STY:
return true;
default:
return false;
}
return false;
}
typedef void (* Generator)(AccessType, bool, const std::function<void(MicroOp)>&); typedef void (* Generator)(AccessType, bool, const std::function<void(MicroOp)>&);
using GeneratorKey = std::tuple<AccessType, Generator>; using GeneratorKey = std::tuple<AccessType, Generator>;
using PatternTable = std::map<GeneratorKey, std::pair<size_t, size_t>>; using PatternTable = std::map<GeneratorKey, std::pair<size_t, size_t>>;
@ -66,6 +84,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
storage_.instructions[opcode].program_offsets[0] = (access_mode == AccessMode::Always8Bit) ? uint16_t(micro_op_location_8) : uint16_t(micro_op_location_16); storage_.instructions[opcode].program_offsets[0] = (access_mode == AccessMode::Always8Bit) ? uint16_t(micro_op_location_8) : uint16_t(micro_op_location_16);
storage_.instructions[opcode].program_offsets[1] = (access_mode == AccessMode::Always16Bit) ? uint16_t(micro_op_location_16) : uint16_t(micro_op_location_8); storage_.instructions[opcode].program_offsets[1] = (access_mode == AccessMode::Always16Bit) ? uint16_t(micro_op_location_16) : uint16_t(micro_op_location_8);
storage_.instructions[opcode].operation = operation; storage_.instructions[opcode].operation = operation;
storage_.instructions[opcode].size_field = operation_is_index_sized(operation);
++opcode; ++opcode;
} }

View File

@ -237,8 +237,9 @@ struct ProcessorStorage {
uint16_t program_offsets[2] = {0xffff, 0xffff}; uint16_t program_offsets[2] = {0xffff, 0xffff};
/// The operation to perform upon an OperationPerform. /// The operation to perform upon an OperationPerform.
Operation operation = NOP; Operation operation = NOP;
/// An index into the mx field indicating which of M or X affects whether this is an 8-bit or 16-bit field. /// An index into the mx field indicating which of M or X affects whether this is an 8-bit or 16-bit field;
/// So the program to perform is that at @c program_offsets[mx_flags[size_field]] /// if this is 0 then this instruction picks its size based on the M flag; otherwise it does so based on X.
/// So the program to perform is that at @c program_offsets[mx_flags[size_field]] .
uint8_t size_field = 0; uint8_t size_field = 0;
}; };
Instruction instructions[256 + 3]; // Arranged as: Instruction instructions[256 + 3]; // Arranged as: