mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 15:39:08 +00:00
Improve commentary; use specialised types for TAS.
This commit is contained in:
parent
5b43ea82f3
commit
c266639a0c
@ -35,7 +35,8 @@ static constexpr OperationT SelectWord = 1 << 1;
|
||||
/// If set, indicates a read. Otherwise, a write.
|
||||
static constexpr OperationT Read = 1 << 2;
|
||||
|
||||
// Two-bit gap deliberately left here for PermitRead/Write below.
|
||||
// Two-bit gap deliberately left here for PermitRead/Write below; these are not
|
||||
// real 68000 signals, they're to do with internal manipulation only.
|
||||
|
||||
/// A NewAddress cycle is one in which the address strobe is initially low but becomes high;
|
||||
/// this correlates to states 0 to 5 of a standard read/write cycle.
|
||||
@ -65,9 +66,7 @@ static constexpr OperationT IsPeripheral = 1 << 11;
|
||||
/// Provides the 68000's bus grant line — indicating whether a bus request has been acknowledged.
|
||||
static constexpr OperationT BusGrant = 1 << 12;
|
||||
|
||||
/// An otherwise invalid combination; used as the operaiton template parameter to @c perform_bus_operation if
|
||||
/// the operation wasn't knowable in advance and the receiver should decode dynamically using the microcycle's
|
||||
/// .operation field.
|
||||
/// An otherwise invalid combination; used as an implementation detail elsewhere. Shouldn't be exposed.
|
||||
static constexpr OperationT DecodeDynamically = NewAddress | SameAddress;
|
||||
|
||||
// PermitRead and PermitWrite are used as part of the read/write mask
|
||||
@ -339,7 +338,7 @@ struct Microcycle: public MicrocycleOperationStorage<op> {
|
||||
|
||||
/*!
|
||||
Assuming this to be a cycle with a data select active, applies it to @c target
|
||||
subject to the read_write_mask, where 'applies' means:
|
||||
subject to the @c read_write_mask, where 'applies' means:
|
||||
|
||||
* if this is a byte read, reads a single byte from @c target;
|
||||
* if this is a word read, reads a word (in the host platform's endianness) from @c target; and
|
||||
@ -348,7 +347,10 @@ struct Microcycle: public MicrocycleOperationStorage<op> {
|
||||
forceinline void apply(uint8_t *target, OperationT read_write_mask = Operation::PermitRead | Operation::PermitWrite) const {
|
||||
assert( (this->operation & (Operation::SelectWord | Operation::SelectByte)) != (Operation::SelectWord | Operation::SelectByte));
|
||||
|
||||
switch((this->operation | read_write_mask) & (Operation::SelectWord | Operation::SelectByte | Operation::Read | Operation::PermitRead | Operation::PermitWrite)) {
|
||||
switch(
|
||||
(this->operation | read_write_mask) &
|
||||
(Operation::SelectWord | Operation::SelectByte | Operation::Read | Operation::PermitRead | Operation::PermitWrite)
|
||||
) {
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -382,11 +384,10 @@ class BusHandler {
|
||||
Provides the bus handler with a single Microcycle to 'perform'.
|
||||
|
||||
FC0 and FC1 are provided inside the microcycle as the IsData and IsProgram
|
||||
flags; FC2 is provided here as is_supervisor — it'll be either 0 or 1.
|
||||
flags; FC2 is provided here as @c is_supervisor — it'll be either 0 or 1.
|
||||
|
||||
If @c operation is any value other than Microcycle::DecodeDynamically then it
|
||||
can be used to select an appropriate execution path at compile time. Otherwise
|
||||
cycle.operation must be inspected at runtime.
|
||||
The @c Microcycle might be any instantiation of @c Microcycle above;
|
||||
whether with a static constexpr operation or with a runtime-selected one.
|
||||
*/
|
||||
template <typename Microcycle>
|
||||
HalfCycles perform_bus_operation(const Microcycle &, [[maybe_unused]] int is_supervisor) {
|
||||
|
@ -2625,20 +2625,20 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
||||
//
|
||||
BeginState(TAS):
|
||||
// Populate all addresses.
|
||||
tas_cycles[0].address = tas_cycles[1].address =
|
||||
tas_cycles[2].address =
|
||||
tas_cycles[3].address = tas_cycles[4].address = &effective_address_[0].l;
|
||||
tas_cycle0.address = tas_cycle1.address =
|
||||
tas_cycle2.address =
|
||||
tas_cycle3.address = tas_cycle4.address = &effective_address_[0].l;
|
||||
|
||||
// Populate values to the relevant subset.
|
||||
tas_cycles[0].value = tas_cycles[1].value =
|
||||
tas_cycles[3].value = tas_cycles[4].value = &operand_[0].low;
|
||||
tas_cycle0.value = tas_cycle1.value =
|
||||
tas_cycle3.value = tas_cycle4.value = &operand_[0].low;
|
||||
|
||||
// First two parts: the read.
|
||||
PerformBusOperation(tas_cycles[0]);
|
||||
CompleteAccess(tas_cycles[1]);
|
||||
PerformBusOperation(tas_cycle0);
|
||||
CompleteAccess(tas_cycle1);
|
||||
|
||||
// Third part: processing time.
|
||||
PerformBusOperation(tas_cycles[2]);
|
||||
PerformBusOperation(tas_cycle2);
|
||||
|
||||
// Do the actual TAS operation.
|
||||
status_.overflow_flag = status_.carry_flag = 0;
|
||||
@ -2647,8 +2647,8 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
||||
|
||||
// Final parts: write back.
|
||||
operand_[0].b |= 0x80;
|
||||
PerformBusOperation(tas_cycles[3]);
|
||||
CompleteAccess(tas_cycles[4]);
|
||||
PerformBusOperation(tas_cycle3);
|
||||
CompleteAccess(tas_cycle4);
|
||||
|
||||
Prefetch();
|
||||
MoveToStateSpecific(Decode);
|
||||
|
@ -208,13 +208,11 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController {
|
||||
Operation::SameAddress | Operation::IsData,
|
||||
Operation::SameAddress | Operation::IsData | Operation::SelectByte,
|
||||
};
|
||||
Microcycle<Operation::DecodeDynamically> tas_cycles[5] = {
|
||||
{ TASOperations[0] },
|
||||
{ TASOperations[1] },
|
||||
{ TASOperations[2] },
|
||||
{ TASOperations[3] },
|
||||
{ TASOperations[4] },
|
||||
};
|
||||
Microcycle<TASOperations[0]> tas_cycle0;
|
||||
Microcycle<TASOperations[1]> tas_cycle1;
|
||||
Microcycle<TASOperations[2]> tas_cycle2;
|
||||
Microcycle<TASOperations[3]> tas_cycle3;
|
||||
Microcycle<TASOperations[4]> tas_cycle4;
|
||||
|
||||
// Reset.
|
||||
static constexpr OperationT ResetOperation = CPU::MC68000::Operation::Reset;
|
||||
|
Loading…
x
Reference in New Issue
Block a user