diff --git a/InstructionSets/68k/Decoder.cpp b/InstructionSets/68k/Decoder.cpp index b4c201c23..76f7b40e0 100644 --- a/InstructionSets/68k/Decoder.cpp +++ b/InstructionSets/68k/Decoder.cpp @@ -8,6 +8,8 @@ #include "Decoder.hpp" +#include + using namespace InstructionSet::M68k; namespace { @@ -121,11 +123,111 @@ template Preinstruction Predecoder::decode(uint16_t instru ea_combined_mode, ea_register, AddressingMode::DataRegisterDirect, data_register); + + default: + // Should be unreachable. + assert(false); } } // MARK: - Page decoders. +Preinstruction Predecoder::decode4(uint16_t instruction) { + switch(instruction & 0xfff) { + case 0xe70: return decode(instruction); // 6-83 (p537) + case 0xe71: return decode(instruction); // 8-13 (p469) + case 0xe73: return decode(instruction); // 6-84 (p538) + case 0xe75: return decode(instruction); // 4-169 (p273) + case 0xe76: return decode(instruction); // 4-191 (p295) + case 0xe77: return decode(instruction); // 4-168 (p272) + default: break; + } + + switch(instruction & 0xfc0) { + // 4-146 (p250) + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); + + // 6-17 (p471) + case 0x0c0: return decode(instruction); + + // 4-73 (p177) + case 0x200: return decode(instruction); + case 0x240: return decode(instruction); + case 0x280: return decode(instruction); + + // 4-144 (p248) + case 0x400: return decode(instruction); + case 0x440: return decode(instruction); + case 0x480: return decode(instruction); + + // 4-123 (p227) + case 0x4c0: return decode(instruction); + + // 4-148 (p250) + case 0x600: return decode(instruction); + case 0x640: return decode(instruction); + case 0x680: return decode(instruction); + + // 4-123 (p227) + case 0x6c0: return decode(instruction); + + // 4-142 (p246) + case 0x800: return decode(instruction); + + // 4-159 (p263) + case 0x840: return decode(instruction); + + // 4-128 (p232) + case 0x880: return decode(instruction); + case 0x8c0: return decode(instruction); + case 0xc80: return decode(instruction); + case 0xcc0: return decode(instruction); + + // 4-192 (p296) + case 0xa00: return decode(instruction); + case 0xa40: return decode(instruction); + case 0xa80: return decode(instruction); + + // 4-186 (p290) + case 0xac0: return decode(instruction); + + // 4-109 (p213) + case 0xe80: return decode(instruction); + + // 4-108 (p212) + case 0xec0: return decode(instruction); + + default: break; + } + + switch(instruction & 0x1c0) { + case 0x1c0: return decode(instruction); // 4-110 (p214) + case 0x180: return decode(instruction); // 4-69 (p173) + default: break; + } + + switch(instruction & 0xff0) { + case 0xe40: return decode(instruction); // 4-188 (p292) +// case 0xe60: return decode(instruction); // 6-21 (p475) + default: break; + } + + // TODO: determine MOVEtoUSP and MOVEfromUSP. + + switch(instruction & 0xff8) { + case 0xe60: return decode(instruction); // 4-185 (p289) + case 0x880: return decode(instruction); // 4-106 (p210) + case 0x8c0: return decode(instruction); // 4-106 (p210) + case 0xe50: return decode(instruction); // 4-111 (p215) + case 0xe58: return decode(instruction); // 4-194 (p298) + default: break; + } + + return Preinstruction(); +} + Preinstruction Predecoder::decode8(uint16_t instruction) { // 4-171 (p275) if((instruction & 0x1f0) == 0x100) return decode(instruction); @@ -147,6 +249,31 @@ Preinstruction Predecoder::decode8(uint16_t instruction) { return Preinstruction(); } +Preinstruction Predecoder::decodeB(uint16_t instruction) { + // 4-100 (p204) + switch(instruction & 0x0c0) { + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); + default: break; + } + + // 4-75 (p179) + switch(instruction & 0x1c0) { + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); + + // 4-77 (p181) + case 0x0c0: return decode(instruction); + case 0x1c0: return decode(instruction); + + default: break; + } + + return Preinstruction(); +} + Preinstruction Predecoder::decodeC(uint16_t instruction) { // 4-3 (p107) if((instruction & 0x1f0) == 0x100) return decode(instruction); @@ -171,6 +298,7 @@ Preinstruction Predecoder::decodeC(uint16_t instruction) { case 0x148: case 0x188: return decode(instruction); } + return Preinstruction(); } @@ -179,7 +307,9 @@ Preinstruction Predecoder::decodeC(uint16_t instruction) { Preinstruction Predecoder::decode(uint16_t instruction) { // Divide first based on line. switch(instruction & 0xf000) { + case 0x4000: return decode4(instruction); case 0x8000: return decode8(instruction); + case 0xb000: return decodeB(instruction); case 0xc000: return decodeC(instruction); default: break; diff --git a/InstructionSets/68k/Decoder.hpp b/InstructionSets/68k/Decoder.hpp index d9bd2e86c..16ef91505 100644 --- a/InstructionSets/68k/Decoder.hpp +++ b/InstructionSets/68k/Decoder.hpp @@ -26,7 +26,9 @@ class Predecoder { private: // Page by page decoders; each gets a bit ad hoc so // it is neater to separate them. + Preinstruction decode4(uint16_t instruction); Preinstruction decode8(uint16_t instruction); + Preinstruction decodeB(uint16_t instruction); Preinstruction decodeC(uint16_t instruction); // Specific instruction decoders. diff --git a/InstructionSets/68k/Instruction.hpp b/InstructionSets/68k/Instruction.hpp index 3f687edd8..53ba68fea 100644 --- a/InstructionSets/68k/Instruction.hpp +++ b/InstructionSets/68k/Instruction.hpp @@ -17,6 +17,8 @@ namespace M68k { enum class Operation: uint8_t { Undefined, + NOP, + ABCD, SBCD, NBCD, ADDb, ADDw, ADDl, @@ -37,6 +39,7 @@ enum class Operation: uint8_t { MOVEtoSR, MOVEfromSR, MOVEtoCCR, + MOVEtoUSP, MOVEfromUSP, ORItoSR, ORItoCCR, ANDItoSR, ANDItoCCR, @@ -45,10 +48,10 @@ enum class Operation: uint8_t { BTSTb, BTSTl, BCLRl, BCLRb, CMPb, CMPw, CMPl, - CMPAw, + CMPAw, CMPAl, TSTb, TSTw, TSTl, - JMP, RTS, + JMP, JSR, RTS, BRA, Bcc, DBcc, Scc, @@ -80,7 +83,7 @@ enum class Operation: uint8_t { MULU, MULS, DIVU, DIVS, - RTE_RTR, + RTE, RTR, TRAP, TRAPV, CHK, @@ -96,7 +99,7 @@ enum class Operation: uint8_t { LINK, UNLINK, - STOP, + STOP, RESET, }; /// Indicates the addressing mode applicable to an operand.