mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-21 05:29:13 +00:00
Implement MOVEM to memory.
This commit is contained in:
parent
47f4bbeec6
commit
d7d0a5c15e
@ -440,11 +440,51 @@ void Executor<model, BusHandler>::movep(Preinstruction instruction, uint32_t sou
|
||||
template <Model model, typename BusHandler>
|
||||
template <typename IntT>
|
||||
void Executor<model, BusHandler>::movem(Preinstruction instruction, uint32_t source, uint32_t dest) {
|
||||
if(instruction.mode<0>() == AddressingMode::DataRegisterDirect) {
|
||||
// Move registers to memory.
|
||||
// NB:
|
||||
//
|
||||
// "For the MC68020, MC68030, MC68040, and CPU32, if the addressing register is also
|
||||
// moved to memory, the value written is the initial register value decremented by the
|
||||
// size of the operation. The MC68000 and MC68010 write the initial register value
|
||||
// (not decremented)."
|
||||
|
||||
if(instruction.mode<0>() == AddressingMode::ImmediateData) {
|
||||
// Move registers to memory. This is the only permitted use of the predecrement mode,
|
||||
// which reverses output order.
|
||||
if(instruction.mode<1>() == AddressingMode::AddressRegisterIndirectWithPredecrement) {
|
||||
} else {
|
||||
// The structure of the code in the mainline part of the executor is such
|
||||
// that the address register will already have been predecremented before
|
||||
// reaching here, and it'll have been by two bytes per the operand size
|
||||
// rather than according to the instruction size. That's not wanted, so undo it.
|
||||
//
|
||||
// (TODO: with the caveat that the 68020+ have different behaviour.).
|
||||
registers_[8 + instruction.reg<1>()].l += 2;
|
||||
|
||||
uint32_t reg = registers_[8 + instruction.reg<1>()].l;
|
||||
int index = 15;
|
||||
|
||||
while(source) {
|
||||
if(source & 1) {
|
||||
reg -= sizeof(IntT);
|
||||
bus_handler_.template write<IntT>(reg, IntT(registers_[index].l));
|
||||
}
|
||||
--index;
|
||||
source >>= 1;
|
||||
}
|
||||
|
||||
registers_[8 + instruction.reg<1>()].l = reg;
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
while(source) {
|
||||
if(source & 1) {
|
||||
bus_handler_.template write<IntT>(dest, IntT(registers_[index].l));
|
||||
dest += sizeof(IntT);
|
||||
}
|
||||
++index;
|
||||
source >>= 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Move memory to registers.
|
||||
}
|
||||
|
@ -127,6 +127,10 @@ enum class DataSize {
|
||||
};
|
||||
|
||||
/// Classifies operations by the size of their memory accesses, if any.
|
||||
///
|
||||
/// For any operations that don't fit the neat model of reading one or two operands,
|
||||
/// then writing zero or one, the size determines the data size of the operands only,
|
||||
/// not any other accesses.
|
||||
constexpr DataSize size(Operation operation) {
|
||||
switch(operation) {
|
||||
// These are given a value arbitrarily, to
|
||||
@ -188,7 +192,7 @@ constexpr DataSize size(Operation operation) {
|
||||
case Operation::RORw: case Operation::RORm:
|
||||
case Operation::ROXLw: case Operation::ROXLm:
|
||||
case Operation::ROXRw: case Operation::ROXRm:
|
||||
case Operation::MOVEMw:
|
||||
case Operation::MOVEMw: case Operation::MOVEMl:
|
||||
case Operation::MOVEPw:
|
||||
case Operation::ANDw: case Operation::EORw:
|
||||
case Operation::NOTw: case Operation::ORw:
|
||||
@ -217,7 +221,6 @@ constexpr DataSize size(Operation operation) {
|
||||
case Operation::LSLl: case Operation::LSRl:
|
||||
case Operation::ROLl: case Operation::RORl:
|
||||
case Operation::ROXLl: case Operation::ROXRl:
|
||||
case Operation::MOVEMl:
|
||||
case Operation::MOVEPl:
|
||||
case Operation::ANDl: case Operation::EORl:
|
||||
case Operation::NOTl: case Operation::ORl:
|
||||
|
@ -72,8 +72,8 @@
|
||||
|
||||
- (void)setUp {
|
||||
// To limit tests run to a subset of files and/or of tests, uncomment and fill in below.
|
||||
_fileSet = [NSSet setWithArray:@[@"move.json"]];
|
||||
// _testSet = [NSSet setWithArray:@[@"MOVE[A] 0148"]];
|
||||
_fileSet = [NSSet setWithArray:@[@"movem.json"]];
|
||||
// _testSet = [NSSet setWithArray:@[@"MOVEM 0060 (0)"]];
|
||||
// _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]];
|
||||
// _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user