1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-15 14:27:29 +00:00

Advance permissively through the 4xxx page to LEA.

This commit is contained in:
Thomas Harte
2022-04-15 16:01:33 -04:00
parent faa35fe9fc
commit f86e455a87

View File

@@ -16,7 +16,9 @@ namespace {
/// @returns The @c AddressingMode given the specified mode and reg, subject to potential /// @returns The @c AddressingMode given the specified mode and reg, subject to potential
/// aliasing on the '020+ as described above the @c AddressingMode enum. /// aliasing on the '020+ as described above the @c AddressingMode enum.
template <bool allow_An = true, bool allow_post_inc = true> constexpr AddressingMode combined_mode(int raw_mode, int reg) { template <
bool allow_An = true, bool allow_post_inc = true
> constexpr AddressingMode combined_mode(int raw_mode, int reg) {
auto mode = AddressingMode(raw_mode); auto mode = AddressingMode(raw_mode);
if(!allow_An && mode == AddressingMode::AddressRegisterDirect) { if(!allow_An && mode == AddressingMode::AddressRegisterDirect) {
@@ -82,11 +84,9 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// isn't actually used. // isn't actually used.
const auto ea_register = instruction & 7; const auto ea_register = instruction & 7;
const auto ea_mode = (instruction >> 3) & 7; const auto ea_mode = (instruction >> 3) & 7;
const auto ea_combined_mode = combined_mode(ea_mode, ea_register);
// TODO: based on operation, limit potential outputs of combined_mode.
const auto opmode = (instruction >> 6) & 7; const auto opmode = (instruction >> 6) & 7;
const auto data_register = (instruction >> 9) & 7; const auto data_register = (instruction >> 9) & 7;
constexpr auto operation = Predecoder<model>::operation(op); constexpr auto operation = Predecoder<model>::operation(op);
switch(op) { switch(op) {
@@ -94,7 +94,6 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: ABCD, SBCD. // MARK: ABCD, SBCD.
// //
// 4-3 (p107), 4-171 (p275)
case Op(Operation::ABCD): case Op(Operation::SBCD): { case Op(Operation::ABCD): case Op(Operation::SBCD): {
const auto addressing_mode = (instruction & 8) ? const auto addressing_mode = (instruction & 8) ?
AddressingMode::AddressRegisterIndirectWithPredecrement : AddressingMode::DataRegisterDirect; AddressingMode::AddressRegisterIndirectWithPredecrement : AddressingMode::DataRegisterDirect;
@@ -120,6 +119,8 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
operation == Operation::EORw || operation == Operation::EORw ||
operation == Operation::EORl; operation == Operation::EORl;
const auto ea_combined_mode = combined_mode(ea_mode, ea_register);
if(opmode & 4) { if(opmode & 4) {
// Dn Λ < ea > → < ea > // Dn Λ < ea > → < ea >
@@ -164,7 +165,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
case BCLRI: case BSETI: case BCLRI: case BSETI:
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::ImmediateData, 0, AddressingMode::ImmediateData, 0,
ea_combined_mode, ea_register); combined_mode(ea_mode, ea_register), ea_register);
// //
@@ -174,7 +175,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
case Op(Operation::BCHG): case Op(Operation::BSET): case Op(Operation::BCHG): case Op(Operation::BSET):
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::DataRegisterDirect, data_register, AddressingMode::DataRegisterDirect, data_register,
ea_combined_mode, ea_register); combined_mode(ea_mode, ea_register), ea_register);
// //
// MARK: ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR // MARK: ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR
@@ -212,7 +213,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
case Op(Operation::DIVU): case Op(Operation::DIVS): case Op(Operation::DIVU): case Op(Operation::DIVS):
case Op(Operation::MULU): case Op(Operation::MULS): case Op(Operation::MULU): case Op(Operation::MULS):
return Preinstruction(operation, return Preinstruction(operation,
ea_combined_mode, ea_register, combined_mode(ea_mode, ea_register), ea_register,
AddressingMode::DataRegisterDirect, data_register); AddressingMode::DataRegisterDirect, data_register);
// //
@@ -233,7 +234,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
case Op(Operation::MOVEb): case Op(Operation::MOVEl): case Op(Operation::MOVEw): case Op(Operation::MOVEb): case Op(Operation::MOVEl): case Op(Operation::MOVEw):
return Preinstruction(operation, return Preinstruction(operation,
ea_combined_mode, ea_register, combined_mode(ea_mode, ea_register), ea_register,
combined_mode<false, false>(opmode, data_register), data_register); combined_mode<false, false>(opmode, data_register), data_register);
// //
@@ -244,6 +245,37 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
case Op(Operation::RTR): case Op(Operation::RTR):
return Preinstruction(operation); return Preinstruction(operation);
//
// MARK: NEGX, CLR, NEG, MOVEtoCCR, MOVEtoSR, NOT, NBCD, PEA, TST
//
case Op(Operation::CLRb): case Op(Operation::CLRw): case Op(Operation::CLRl):
case Op(Operation::JMP): case Op(Operation::JSR):
case Op(Operation::MOVEtoSR): case Op(Operation::MOVEfromSR): case Op(Operation::MOVEtoCCR):
case Op(Operation::NBCD):
case Op(Operation::NEGb): case Op(Operation::NEGw): case Op(Operation::NEGl):
case Op(Operation::NEGXb): case Op(Operation::NEGXw): case Op(Operation::NEGXl):
case Op(Operation::NOTb): case Op(Operation::NOTw): case Op(Operation::NOTl):
case Op(Operation::PEA):
case Op(Operation::TAS):
case Op(Operation::TSTb): case Op(Operation::TSTw): case Op(Operation::TSTl):
return Preinstruction(operation,
combined_mode<false, false>(ea_mode, ea_register), ea_register);
//
// MARK: MOVEMtoMw, MOVEMtoMl, MOVEMtoRw, MOVEMtoRl
//
case MOVEMtoMl: case MOVEMtoMw:
return Preinstruction(operation,
AddressingMode::ImmediateData, 0,
combined_mode(ea_mode, ea_register), ea_register);
case MOVEMtoRl: case MOVEMtoRw:
return Preinstruction(operation,
combined_mode(ea_mode, ea_register), ea_register,
AddressingMode::ImmediateData, 0);
// TODO: more validation on the above.
// //
// MARK: Impossible error case. // MARK: Impossible error case.
// //
@@ -389,7 +421,7 @@ Preinstruction Predecoder<model>::decode4(uint16_t instruction) {
case 0x240: DecodeOp(CLRw); case 0x240: DecodeOp(CLRw);
case 0x280: DecodeOp(CLRl); case 0x280: DecodeOp(CLRl);
// 4-144 (p248) // 4-144 (p247)
case 0x400: DecodeOp(NEGb); case 0x400: DecodeOp(NEGb);
case 0x440: DecodeOp(NEGw); case 0x440: DecodeOp(NEGw);
case 0x480: DecodeOp(NEGl); case 0x480: DecodeOp(NEGl);
@@ -397,7 +429,7 @@ Preinstruction Predecoder<model>::decode4(uint16_t instruction) {
// 4-123 (p227) // 4-123 (p227)
case 0x4c0: DecodeOp(MOVEtoCCR); case 0x4c0: DecodeOp(MOVEtoCCR);
// 4-148 (p250) // 4-148 (p252)
case 0x600: DecodeOp(NOTb); case 0x600: DecodeOp(NOTb);
case 0x640: DecodeOp(NOTw); case 0x640: DecodeOp(NOTw);
case 0x680: DecodeOp(NOTl); case 0x680: DecodeOp(NOTl);
@@ -435,7 +467,7 @@ Preinstruction Predecoder<model>::decode4(uint16_t instruction) {
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
case 0x1c0: DecodeOp(MOVEAl); // 4-110 (p214) case 0x1c0: DecodeOp(MOVEAl); // 4-110 (p214) TODO: In this I assume that LEA is just a special MOVEAl. Consider.
case 0x180: DecodeOp(CHK); // 4-69 (p173) case 0x180: DecodeOp(CHK); // 4-69 (p173)
default: break; default: break;
} }