1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-20 06:25:01 +00:00

Implement MOVE.

This commit is contained in:
Thomas Harte 2022-05-23 08:46:06 -04:00
parent 1b3acf9cd8
commit c73021cf3c
2 changed files with 63 additions and 27 deletions

View File

@ -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",

View File

@ -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);
// //