mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Codify the existence of special cases, implement NOP and RESET.
This commit is contained in:
parent
e2f4db3e45
commit
e0a279344c
@ -121,6 +121,7 @@ struct Microcycle {
|
|||||||
SlicedInt16 *value = nullptr;
|
SlicedInt16 *value = nullptr;
|
||||||
|
|
||||||
Microcycle(OperationT operation) : operation(operation) {}
|
Microcycle(OperationT operation) : operation(operation) {}
|
||||||
|
Microcycle(OperationT operation, HalfCycles length) : operation(operation), length(length) {}
|
||||||
Microcycle() {}
|
Microcycle() {}
|
||||||
|
|
||||||
/// @returns @c true if two Microcycles are equal; @c false otherwise.
|
/// @returns @c true if two Microcycles are equal; @c false otherwise.
|
||||||
|
@ -20,7 +20,7 @@ namespace MC68000Mk2 {
|
|||||||
// TODO: VPA, BERR, interrupt inputs, etc.
|
// TODO: VPA, BERR, interrupt inputs, etc.
|
||||||
// Also, from Instruction.hpp:
|
// Also, from Instruction.hpp:
|
||||||
//
|
//
|
||||||
// NOP, MOVEAw, MOVEAl, MOVE[to/from]USP, STOP, RESET
|
// MOVEAw, MOVEAl, MOVE[to/from]USP, STOP
|
||||||
//
|
//
|
||||||
// Not provided by a 68000: Bccl, BSRl
|
// Not provided by a 68000: Bccl, BSRl
|
||||||
|
|
||||||
@ -134,11 +134,11 @@ enum ExecutionState: int {
|
|||||||
DBcc_condition_true,
|
DBcc_condition_true,
|
||||||
DBcc_counter_overflow,
|
DBcc_counter_overflow,
|
||||||
|
|
||||||
Bcc_b,
|
Bccb,
|
||||||
Bcc_w,
|
Bccw,
|
||||||
Bcc_branch_taken,
|
Bcc_branch_taken,
|
||||||
Bcc_b_branch_not_taken,
|
Bccb_branch_not_taken,
|
||||||
Bcc_w_branch_not_taken,
|
Bccw_branch_not_taken,
|
||||||
|
|
||||||
BSR,
|
BSR,
|
||||||
|
|
||||||
@ -177,8 +177,10 @@ enum ExecutionState: int {
|
|||||||
RTR,
|
RTR,
|
||||||
RTE,
|
RTE,
|
||||||
RTS,
|
RTS,
|
||||||
LINK,
|
LINKw,
|
||||||
UNLINK,
|
UNLINK,
|
||||||
|
RESET,
|
||||||
|
NOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
// MARK: - The state machine.
|
// MARK: - The state machine.
|
||||||
@ -461,6 +463,8 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
); \
|
); \
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
|
#define SpecialCASE(x) case InstructionSet::M68k::Operation::x: MoveToStateSpecific(x)
|
||||||
|
|
||||||
switch(instruction_.operation) {
|
switch(instruction_.operation) {
|
||||||
StdCASE(NBCD, {
|
StdCASE(NBCD, {
|
||||||
if(instruction_.mode(0) == Mode::DataRegisterDirect) {
|
if(instruction_.mode(0) == Mode::DataRegisterDirect) {
|
||||||
@ -612,10 +616,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
StdCASE(DBcc, MoveToStateSpecific(DBcc));
|
SpecialCASE(DBcc);
|
||||||
|
|
||||||
StdCASE(Bccb, MoveToStateSpecific(Bcc_b));
|
SpecialCASE(Bccb);
|
||||||
StdCASE(Bccw, MoveToStateSpecific(Bcc_w));
|
SpecialCASE(Bccw);
|
||||||
|
|
||||||
StdCASE(BSRb, perform_state_ = BSR);
|
StdCASE(BSRb, perform_state_ = BSR);
|
||||||
StdCASE(BSRw, perform_state_ = BSR);
|
StdCASE(BSRw, perform_state_ = BSR);
|
||||||
@ -756,9 +760,9 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
MoveToStateSpecific(CalcEffectiveAddress);
|
MoveToStateSpecific(CalcEffectiveAddress);
|
||||||
});
|
});
|
||||||
|
|
||||||
StdCASE(RTR, MoveToStateSpecific(RTR));
|
SpecialCASE(RTR);
|
||||||
StdCASE(RTE, MoveToStateSpecific(RTE));
|
SpecialCASE(RTE);
|
||||||
StdCASE(RTS, MoveToStateSpecific(RTS));
|
SpecialCASE(RTS);
|
||||||
|
|
||||||
#define ShiftGroup(suffix, state) \
|
#define ShiftGroup(suffix, state) \
|
||||||
Duplicate(ASL##suffix, ASR##suffix); \
|
Duplicate(ASL##suffix, ASR##suffix); \
|
||||||
@ -776,8 +780,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
ShiftGroup(l, Perform_idle_dyamic_Dn)
|
ShiftGroup(l, Perform_idle_dyamic_Dn)
|
||||||
#undef ShiftGroup
|
#undef ShiftGroup
|
||||||
|
|
||||||
StdCASE(LINKw, MoveToStateSpecific(LINK));
|
SpecialCASE(LINKw);
|
||||||
StdCASE(UNLINK, MoveToStateSpecific(UNLINK));
|
SpecialCASE(UNLINK);
|
||||||
|
|
||||||
|
SpecialCASE(RESET);
|
||||||
|
SpecialCASE(NOP);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -786,6 +793,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
#undef Duplicate
|
#undef Duplicate
|
||||||
#undef StdCASE
|
#undef StdCASE
|
||||||
#undef CASE
|
#undef CASE
|
||||||
|
#undef SpecialCASE
|
||||||
|
|
||||||
// MARK: - Fetch, dispatch.
|
// MARK: - Fetch, dispatch.
|
||||||
|
|
||||||
@ -1563,14 +1571,14 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
//
|
//
|
||||||
// Bcc [.b and .w]
|
// Bcc [.b and .w]
|
||||||
//
|
//
|
||||||
BeginState(Bcc_b):
|
BeginState(Bccb):
|
||||||
operand_[0].b = uint8_t(opcode_);
|
operand_[0].b = uint8_t(opcode_);
|
||||||
PerformSpecific(Bccb);
|
PerformSpecific(Bccb);
|
||||||
|
|
||||||
// Next state was set by complete_bcc.
|
// Next state was set by complete_bcc.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BeginState(Bcc_w):
|
BeginState(Bccw):
|
||||||
operand_[0].w = prefetch_.w;
|
operand_[0].w = prefetch_.w;
|
||||||
PerformSpecific(Bccw);
|
PerformSpecific(Bccw);
|
||||||
|
|
||||||
@ -1583,12 +1591,12 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
Prefetch(); // np
|
Prefetch(); // np
|
||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
BeginState(Bcc_b_branch_not_taken):
|
BeginState(Bccb_branch_not_taken):
|
||||||
IdleBus(2); // nn
|
IdleBus(2); // nn
|
||||||
Prefetch(); // np
|
Prefetch(); // np
|
||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
BeginState(Bcc_w_branch_not_taken):
|
BeginState(Bccw_branch_not_taken):
|
||||||
IdleBus(2); // nn
|
IdleBus(2); // nn
|
||||||
Prefetch(); // np
|
Prefetch(); // np
|
||||||
Prefetch(); // np
|
Prefetch(); // np
|
||||||
@ -2124,9 +2132,9 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
//
|
//
|
||||||
// LINK and UNLINK
|
// LINK[.w] and UNLINK
|
||||||
//
|
//
|
||||||
BeginState(LINK):
|
BeginState(LINKw):
|
||||||
Prefetch();
|
Prefetch();
|
||||||
|
|
||||||
// Ensure that the stack pointer is [seemingly] captured after
|
// Ensure that the stack pointer is [seemingly] captured after
|
||||||
@ -2152,6 +2160,22 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
Prefetch();
|
Prefetch();
|
||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// RESET
|
||||||
|
//
|
||||||
|
BeginState(RESET):
|
||||||
|
IdleBus(2);
|
||||||
|
PerformBusOperation(reset_cycle);
|
||||||
|
Prefetch();
|
||||||
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// NOP
|
||||||
|
//
|
||||||
|
BeginState(NOP):
|
||||||
|
Prefetch();
|
||||||
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Various states TODO.
|
// Various states TODO.
|
||||||
//
|
//
|
||||||
@ -2232,7 +2256,7 @@ template <typename IntT> void ProcessorBase::complete_bcc(bool take_branch, IntT
|
|||||||
|
|
||||||
state_ =
|
state_ =
|
||||||
(instruction_.operation == InstructionSet::M68k::Operation::Bccb) ?
|
(instruction_.operation == InstructionSet::M68k::Operation::Bccb) ?
|
||||||
Bcc_b_branch_not_taken : Bcc_w_branch_not_taken;
|
Bccb_branch_not_taken : Bccw_branch_not_taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessorBase::bsr(uint32_t offset) {
|
void ProcessorBase::bsr(uint32_t offset) {
|
||||||
|
@ -141,7 +141,6 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController {
|
|||||||
inline void complete_dbcc(bool, bool, int16_t);
|
inline void complete_dbcc(bool, bool, int16_t);
|
||||||
inline void bsr(uint32_t);
|
inline void bsr(uint32_t);
|
||||||
inline void stop() {} // TODO
|
inline void stop() {} // TODO
|
||||||
inline void reset() {} // TODO
|
|
||||||
inline void move_to_usp(uint32_t) {} // TODO
|
inline void move_to_usp(uint32_t) {} // TODO
|
||||||
inline void move_from_usp(uint32_t &) {} // TODO
|
inline void move_from_usp(uint32_t &) {} // TODO
|
||||||
inline void tas(Preinstruction, uint32_t);
|
inline void tas(Preinstruction, uint32_t);
|
||||||
@ -160,6 +159,7 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController {
|
|||||||
inline void rtr() {}
|
inline void rtr() {}
|
||||||
inline void rte() {}
|
inline void rte() {}
|
||||||
inline void rts() {}
|
inline void rts() {}
|
||||||
|
inline void reset() {}
|
||||||
|
|
||||||
// Some microcycles that will be modified as required and used in the main loop;
|
// Some microcycles that will be modified as required and used in the main loop;
|
||||||
// the semantics of a switch statement make in-place declarations awkward and
|
// the semantics of a switch statement make in-place declarations awkward and
|
||||||
@ -191,6 +191,9 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController {
|
|||||||
{ Microcycle::SameAddress | Microcycle::IsData | Microcycle::SelectByte },
|
{ Microcycle::SameAddress | Microcycle::IsData | Microcycle::SelectByte },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Reset.
|
||||||
|
Microcycle reset_cycle { Microcycle::Reset, HalfCycles(248) };
|
||||||
|
|
||||||
// Holding spot when awaiting DTACK/etc.
|
// Holding spot when awaiting DTACK/etc.
|
||||||
Microcycle awaiting_dtack;
|
Microcycle awaiting_dtack;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user