mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-20 06:25:01 +00:00
Implement MOVE.
This commit is contained in:
parent
1b3acf9cd8
commit
c73021cf3c
@ -176,10 +176,10 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler {
|
|||||||
// @"link_unlk.json",
|
// @"link_unlk.json",
|
||||||
// @"lslr_aslr_roxlr_rolr.json",
|
// @"lslr_aslr_roxlr_rolr.json",
|
||||||
@"move_tofrom_srccr.json",
|
@"move_tofrom_srccr.json",
|
||||||
// @"move.json",
|
@"move.json",
|
||||||
@"movem.json",
|
@"movem.json",
|
||||||
@"movep.json",
|
@"movep.json",
|
||||||
// @"moveq.json",
|
@"moveq.json",
|
||||||
@"mulu_muls.json",
|
@"mulu_muls.json",
|
||||||
@"nbcd_pea.json",
|
@"nbcd_pea.json",
|
||||||
@"neg_not.json",
|
@"neg_not.json",
|
||||||
|
@ -104,11 +104,10 @@ enum ExecutionState: int {
|
|||||||
Perform_np_n,
|
Perform_np_n,
|
||||||
Perform_np_nn,
|
Perform_np_nn,
|
||||||
|
|
||||||
// MOVE has unique bus usage, so has specialised states.
|
MOVE,
|
||||||
|
MOVE_predec,
|
||||||
MOVEw,
|
MOVE_complete,
|
||||||
MOVEwRegisterDirect,
|
MOVE_complete_l,
|
||||||
MOVEwAddressRegisterIndirectWithPostincrement,
|
|
||||||
|
|
||||||
TwoOp_Predec_bw,
|
TwoOp_Predec_bw,
|
||||||
TwoOp_Predec_l,
|
TwoOp_Predec_l,
|
||||||
@ -482,7 +481,9 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
StdCASE(EXTbtow, perform_state_ = Perform_np);
|
StdCASE(EXTbtow, perform_state_ = Perform_np);
|
||||||
StdCASE(EXTwtol, perform_state_ = Perform_np);
|
StdCASE(EXTwtol, perform_state_ = Perform_np);
|
||||||
|
|
||||||
StdCASE(MOVEw, perform_state_ = MOVEw);
|
StdCASE(MOVEb, perform_state_ = MOVE);
|
||||||
|
StdCASE(MOVEw, perform_state_ = MOVE);
|
||||||
|
StdCASE(MOVEl, perform_state_ = MOVE);
|
||||||
|
|
||||||
StdCASE(CMPb, perform_state_ = Perform_np);
|
StdCASE(CMPb, perform_state_ = Perform_np);
|
||||||
StdCASE(CMPw, perform_state_ = Perform_np);
|
StdCASE(CMPw, perform_state_ = Perform_np);
|
||||||
@ -1219,11 +1220,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
|
|
||||||
// MARK: - Store.
|
// MARK: - Store.
|
||||||
|
|
||||||
#define MoveToNextOperand(x) \
|
#define MoveToNextOperand(x) \
|
||||||
++next_operand_; \
|
++next_operand_; \
|
||||||
if(next_operand_ == 2) { \
|
if(next_operand_ == 2) { \
|
||||||
MoveToStateSpecific(Decode); \
|
MoveToStateSpecific(Decode); \
|
||||||
} \
|
} \
|
||||||
MoveToStateSpecific(x)
|
MoveToStateSpecific(x)
|
||||||
|
|
||||||
// Store operand is a lot simpler: only one operand is ever stored, and its address
|
// Store operand is a lot simpler: only one operand is ever stored, and its address
|
||||||
@ -1335,27 +1336,62 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
// Specific forms of perform...
|
// Specific forms of perform...
|
||||||
//
|
//
|
||||||
|
|
||||||
BeginState(MOVEw):
|
BeginState(MOVE):
|
||||||
|
PerformDynamic();
|
||||||
|
|
||||||
|
// In all cases except predecrement mode: do the usual address
|
||||||
|
// calculate and storage, then do the next prefetch and decode.
|
||||||
|
//
|
||||||
|
// In predecrement mode: do the prefetch, then write the result.
|
||||||
|
//
|
||||||
|
// For here, lump data and address register direct in with predec,
|
||||||
|
// so that all that's left is modes that write to memory and then
|
||||||
|
// prefetch.
|
||||||
switch(instruction_.mode(1)) {
|
switch(instruction_.mode(1)) {
|
||||||
case Mode::DataRegisterDirect:
|
|
||||||
case Mode::AddressRegisterDirect:
|
case Mode::AddressRegisterDirect:
|
||||||
MoveToStateSpecific(MOVEwRegisterDirect);
|
case Mode::DataRegisterDirect:
|
||||||
|
case Mode::AddressRegisterIndirectWithPredecrement:
|
||||||
|
MoveToStateSpecific(MOVE_predec);
|
||||||
|
|
||||||
case Mode::AddressRegisterIndirectWithPostincrement:
|
default: break;
|
||||||
MoveToStateSpecific(MOVEwAddressRegisterIndirectWithPostincrement);
|
|
||||||
|
|
||||||
default: assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginState(MOVEwRegisterDirect):
|
next_operand_ = 1;
|
||||||
registers_[instruction_.lreg(1)].w = operand_[1].w;
|
post_ea_state_ = MOVE_complete;
|
||||||
Prefetch(); // np
|
MoveToStateSpecific(CalcEffectiveAddress);
|
||||||
|
|
||||||
|
BeginState(MOVE_predec):
|
||||||
|
Prefetch();
|
||||||
|
next_operand_ = 1;
|
||||||
|
post_ea_state_ = StoreOperand;
|
||||||
|
MoveToStateSpecific(CalcEffectiveAddress);
|
||||||
|
|
||||||
|
BeginState(MOVE_complete):
|
||||||
|
SetDataAddress(effective_address_[1].l);
|
||||||
|
|
||||||
|
switch(instruction_.operand_size()) {
|
||||||
|
case InstructionSet::M68k::DataSize::LongWord:
|
||||||
|
SetupDataAccess(0, Microcycle::SelectWord);
|
||||||
|
MoveToStateSpecific(MOVE_complete_l);
|
||||||
|
|
||||||
|
case InstructionSet::M68k::DataSize::Word:
|
||||||
|
SetupDataAccess(0, Microcycle::SelectWord);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InstructionSet::M68k::DataSize::Byte:
|
||||||
|
SetupDataAccess(0, Microcycle::SelectByte);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Access(operand_[1].low);
|
||||||
|
Prefetch();
|
||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
BeginState(MOVEwAddressRegisterIndirectWithPostincrement):
|
BeginState(MOVE_complete_l):
|
||||||
// TODO: nw
|
Access(operand_[1].high);
|
||||||
assert(false);
|
effective_address_[1].l += 2;
|
||||||
Prefetch() // np
|
Access(operand_[1].low);
|
||||||
|
Prefetch();
|
||||||
MoveToStateSpecific(Decode);
|
MoveToStateSpecific(Decode);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user