mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-22 11:29:20 +00:00
Abort address error-causing exceptions before they begin.
This commit is contained in:
parent
8cbf929671
commit
079c3fd263
@ -241,6 +241,19 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
|
|
||||||
// Helper macros for common bus transactions:
|
// Helper macros for common bus transactions:
|
||||||
|
|
||||||
|
// Raises the exception with integer vector x. x is the vector identifier,
|
||||||
|
// not its address.
|
||||||
|
#define RaiseException(x) \
|
||||||
|
exception_vector_ = x; \
|
||||||
|
MoveToStateSpecific(StandardException);
|
||||||
|
|
||||||
|
// Raises a bus/address error with integer vector x for access v.
|
||||||
|
// x is the vector identifier, not its address.
|
||||||
|
#define RaiseBusOrAddressError(x, v) \
|
||||||
|
exception_vector_ = InstructionSet::M68k::x; \
|
||||||
|
bus_error_ = v; \
|
||||||
|
MoveToStateSpecific(BusOrAddressErrorException);
|
||||||
|
|
||||||
// Performs the bus operation and then applies a `Spend` of its length
|
// Performs the bus operation and then applies a `Spend` of its length
|
||||||
// plus any additional length returned by the bus handler.
|
// plus any additional length returned by the bus handler.
|
||||||
#define PerformBusOperation(x) \
|
#define PerformBusOperation(x) \
|
||||||
@ -274,10 +287,8 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
// (1) wait until end of current 10-cycle window;
|
// (1) wait until end of current 10-cycle window;
|
||||||
// (2) run for the next 10-cycle window.
|
// (2) run for the next 10-cycle window.
|
||||||
#define CompleteAccess(x) \
|
#define CompleteAccess(x) \
|
||||||
if(berr_ || (*x.address & (x.operation >> 1) & 1)) { \
|
if(berr_) { \
|
||||||
bus_error_ = x; \
|
RaiseBusOrAddressError(AccessFault, x); \
|
||||||
exception_vector_ = berr_ ? InstructionSet::M68k::AccessFault : InstructionSet::M68k::AddressError; \
|
|
||||||
MoveToStateSpecific(BusOrAddressErrorException); \
|
|
||||||
} \
|
} \
|
||||||
if(vpa_) { \
|
if(vpa_) { \
|
||||||
x.length = HalfCycles(20) + (HalfCycles(20) + (e_clock_phase_ - time_remaining_) % HalfCycles(20)) % HalfCycles(20); \
|
x.length = HalfCycles(20) + (HalfCycles(20) + (e_clock_phase_ - time_remaining_) % HalfCycles(20)) % HalfCycles(20); \
|
||||||
@ -288,13 +299,16 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
|
|
||||||
// Performs the memory access implied by the announce, perform pair,
|
// Performs the memory access implied by the announce, perform pair,
|
||||||
// honouring DTACK, BERR and VPA as necessary.
|
// honouring DTACK, BERR and VPA as necessary.
|
||||||
#define AccessPair(val, announce, perform) \
|
#define AccessPair(val, announce, perform) \
|
||||||
perform.value = &val; \
|
perform.value = &val; \
|
||||||
if constexpr (!dtack_is_implicit) { \
|
if constexpr (!dtack_is_implicit) { \
|
||||||
announce.length = HalfCycles(4); \
|
announce.length = HalfCycles(4); \
|
||||||
} \
|
} \
|
||||||
PerformBusOperation(announce); \
|
if(*perform.address & (perform.operation >> 1) & 1) { \
|
||||||
WaitForDTACK(announce); \
|
RaiseBusOrAddressError(AddressError, perform); \
|
||||||
|
} \
|
||||||
|
PerformBusOperation(announce); \
|
||||||
|
WaitForDTACK(announce); \
|
||||||
CompleteAccess(perform);
|
CompleteAccess(perform);
|
||||||
|
|
||||||
// Sets up the next data access size and read flags.
|
// Sets up the next data access size and read flags.
|
||||||
@ -322,12 +336,6 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
ReadProgramWord(prefetch_.low) \
|
ReadProgramWord(prefetch_.low) \
|
||||||
captured_interrupt_level_ = bus_interrupt_level_;
|
captured_interrupt_level_ = bus_interrupt_level_;
|
||||||
|
|
||||||
// Raises the exception with integer vector x — x is the vector identifier,
|
|
||||||
// not its address.
|
|
||||||
#define RaiseException(x) \
|
|
||||||
exception_vector_ = x; \
|
|
||||||
MoveToStateSpecific(StandardException);
|
|
||||||
|
|
||||||
// Copies the current program counter, adjusted to allow for the prefetch queue,
|
// Copies the current program counter, adjusted to allow for the prefetch queue,
|
||||||
// into the instruction_address_ latch, which is the source of the value written
|
// into the instruction_address_ latch, which is the source of the value written
|
||||||
// during exceptions.
|
// during exceptions.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user