1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-06 10:38:16 +00:00

Add bus and address error, and VPA checks.

This commit is contained in:
Thomas Harte 2022-05-24 09:08:31 -04:00
parent b037c76da6
commit 523cdd859b
2 changed files with 45 additions and 5 deletions

View File

@ -400,8 +400,37 @@ class Processor: private ProcessorBase {
CPU::MC68000Mk2::State get_state();
void set_state(const CPU::MC68000Mk2::State &);
// TODO: DTACK, VPA, BERR, interrupt input, bus ack/grant, halt,
// get E clock phase (and the E clock in general).
// TODO: bus ack/grant, halt,
/// Sets the DTack line — @c true for active, @c false for inactive.
inline void set_dtack(bool dtack) {
dtack_ = dtack;
}
/// Sets the VPA (valid peripheral address) line — @c true for active, @c false for inactive.
inline void set_is_peripheral_address(bool is_peripheral_address) {
vpa_ = is_peripheral_address;
}
/// Sets the bus error line — @c true for active, @c false for inactive.
inline void set_bus_error(bool bus_error) {
berr_ = bus_error;
}
/// Sets the interrupt lines, IPL0, IPL1 and IPL2.
inline void set_interrupt_level(int interrupt_level) {
bus_interrupt_level_ = interrupt_level;
}
/// @returns The current phase of the E clock; this will be a number of
/// half-cycles between 0 and 19 inclusive, indicating how far the 68000
/// is into the current E cycle.
///
/// This is guaranteed to be 0 at initial 68000 construction. It is not guaranteed
/// to return the correct result if called during a bus transaction.
HalfCycles get_e_clock_phase() {
return e_clock_phase_;
}
private:
BusHandler &bus_handler_;

View File

@ -188,6 +188,7 @@ enum ExecutionState: int {
template <class BusHandler, bool dtack_is_implicit, bool permit_overrun, bool signal_will_perform>
void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perform>::run_for(HalfCycles duration) {
// Accumulate the newly paid-in cycles. If this instance remains in deficit, exit.
e_clock_phase_ += duration;
time_remaining_ += duration;
if(time_remaining_ < HalfCycles(0)) return;
@ -262,12 +263,22 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
// Performs the bus operation provided, which will be one with a
// SelectWord or SelectByte operation, stretching it to match the E
// bus if VPA is currently asserted.
// bus if VPA is currently asserted or seguing elsewhere if a bus
// error is signalled or an adress error observed.
//
// TODO: If BERR is asserted, stop here and perform a bus error exception.
// E clock behaviour implemented, which I think is correct:
//
// TODO: If VPA is asserted, stretch this cycle.
// (1) wait until end of current 10-cycle window;
// (2) run for the next 10-cycle window.
#define CompleteAccess(x) \
if(berr_ || (*x.address & (x.operation >> 1) & 1)) { \
MoveToStateSpecific(BusOrAddressErrorException); \
} \
if(vpa_) { \
x.length = HalfCycles(20) + (HalfCycles(20) + (e_clock_phase_ - time_remaining_) % HalfCycles(20)) % HalfCycles(20); \
} else { \
x.length = HalfCycles(4); \
} \
PerformBusOperation(x)
// Performs the memory access implied by the announce, perform pair,