diff --git a/InstructionSets/68k/Decoder.cpp b/InstructionSets/68k/Decoder.cpp index bb8f47b8e..0604f0461 100644 --- a/InstructionSets/68k/Decoder.cpp +++ b/InstructionSets/68k/Decoder.cpp @@ -41,7 +41,7 @@ template Preinstruction Predecoder::decode(uint16_t instru // // MARK: ABCD, SBCD. // - case Operation::ABCD: case Operation::SBCD: { + case Operation::ABCD: case Operation::SBCD: { const auto addressing_mode = (instruction & 8) ? AddressingMode::AddressRegisterIndirectWithPredecrement : AddressingMode::DataRegisterDirect; @@ -55,7 +55,7 @@ template Preinstruction Predecoder::decode(uint16_t instru // case Operation::ANDb: case Operation::ANDw: case Operation::ANDl: case Operation::ORb: case Operation::ORw: case Operation::ORl: - case Operation::EORb: case Operation::EORw: case Operation::EORl: { + case Operation::EORb: case Operation::EORw: case Operation::EORl: { // Opmode 7 is illegal. if(opmode == 7) { return Preinstruction(); @@ -99,7 +99,7 @@ template Preinstruction Predecoder::decode(uint16_t instru // case Operation::EXG: switch((instruction >> 3)&31) { - default: return Preinstruction(); + default: return Preinstruction(); case 0x08: return Preinstruction(operation, AddressingMode::DataRegisterDirect, ea_register, @@ -127,7 +127,38 @@ template Preinstruction Predecoder::decode(uint16_t instru ea_combined_mode, ea_register, AddressingMode::DataRegisterDirect, data_register); + // + // MARK: ORItoCCR, ORItoSR, ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR + // + case Operation::ORItoSR: case Operation::ORItoCCR: + case Operation::ANDItoSR: case Operation::ANDItoCCR: + case Operation::EORItoSR: case Operation::EORItoCCR: + return Preinstruction(operation, + AddressingMode::ImmediateData, 0, + operation == Operation::ORItoSR || operation == Operation::ANDItoSR || operation == Operation::EORItoSR); + // + // MARK: MOVEPtoRw, MOVEPtoRl + // + case Operation::MOVEPtoRw: case Operation::MOVEPtoRl: + return Preinstruction(operation, + AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register, + AddressingMode::DataRegisterDirect, data_register); + + case Operation::MOVEPtoMw: case Operation::MOVEPtoMl: + return Preinstruction(operation, + AddressingMode::DataRegisterDirect, data_register, + AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register); + + // TODO: there's no need for separate toR and toM given that source and dest are specified overtly. + // Between this and the ANDI/etc case, probably this template needs to take a type other than Operation? + // That'll be a slight hassle because it couldn't inherit from Operation and therefore would either need + // to duplicate it or in some potentially-fragile way avoid collisions with it. Not to mention all the + // casting that'd have to be around. So probably duplicate? + + // + // MARK: Impossible error case. + // default: // Should be unreachable. assert(false); @@ -142,71 +173,73 @@ template Preinstruction Predecoder::decode(uint16_t instru // MARK: - Page decoders. Preinstruction Predecoder::decode0(uint16_t instruction) { - switch(instruction) { - case 0x003c: return decode(instruction); - case 0x007c: return decode(instruction); - case 0x023c: return decode(instruction); - case 0x027c: return decode(instruction); - case 0x0a3c: return decode(instruction); - case 0x0a7c: return decode(instruction); + switch(instruction & 0xfff) { + case 0x03c: return decode(instruction); // 4-155 (p259) + case 0x07c: return decode(instruction); // 6-27 (p646) + case 0x23c: return decode(instruction); // 4-20 (p124) + case 0x27c: return decode(instruction); // 6-2 (p456) + case 0xa3c: return decode(instruction); // 4-104 (p208) + case 0xa7c: return decode(instruction); // 6-10 (p464) - default: break; + default: break; } + // TODO: determine whether it's useful to be able to flag these as immediate + // versions here, rather than having it determined dynamically in decode. switch(instruction & 0xfc0) { // 4-153 (p257) - case 0x000: return decode(instruction); - case 0x040: return decode(instruction); - case 0x080: return decode(instruction); + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); // 4-18 (p122) - case 0x200: return decode(instruction); - case 0x240: return decode(instruction); - case 0x280: return decode(instruction); + case 0x200: return decode(instruction); + case 0x240: return decode(instruction); + case 0x280: return decode(instruction); // 4-179 (p283) - case 0x400: return decode(instruction); - case 0x440: return decode(instruction); - case 0x480: return decode(instruction); + case 0x400: return decode(instruction); + case 0x440: return decode(instruction); + case 0x480: return decode(instruction); // 4-9 (p113) - case 0x600: return decode(instruction); - case 0x640: return decode(instruction); - case 0x680: return decode(instruction); + case 0x600: return decode(instruction); + case 0x640: return decode(instruction); + case 0x680: return decode(instruction); // 4-63 (p167) - case 0x800: return decode(instruction); + case 0x800: return decode(instruction); // 4-29 (p133) - case 0x840: return decode(instruction); + case 0x840: return decode(instruction); // 4-32 (p136) - case 0x880: return decode(instruction); + case 0x880: return decode(instruction); // 4-58 (p162) - case 0x8c0: return decode(instruction); + case 0x8c0: return decode(instruction); // 4-102 (p206) - case 0xa00: return decode(instruction); - case 0xa40: return decode(instruction); - case 0xa80: return decode(instruction); + case 0xa00: return decode(instruction); + case 0xa40: return decode(instruction); + case 0xa80: return decode(instruction); // 4-79 (p183) - case 0xc00: return decode(instruction); - case 0xc40: return decode(instruction); - case 0xc80: return decode(instruction); + case 0xc00: return decode(instruction); + case 0xc40: return decode(instruction); + case 0xc80: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { - case 0x100: return decode(instruction); // 4-62 (p166) - case 0x180: return decode(instruction); // 4-31 (p135) + case 0x100: return decode(instruction); // 4-62 (p166) + case 0x180: return decode(instruction); // 4-31 (p135) - case 0x140: return decode(instruction); // 4-28 (p132) - case 0x1c0: return decode(instruction); // 4-57 (p161) + case 0x140: return decode(instruction); // 4-28 (p132) + case 0x1c0: return decode(instruction); // 4-57 (p161) - default: break; + default: break; } switch(instruction & 0x1f8) { @@ -216,7 +249,7 @@ Preinstruction Predecoder::decode0(uint16_t instruction) { case 0x188: return decode(instruction); case 0x1c8: return decode(instruction); - default: break; + default: break; } return Preinstruction(); @@ -242,44 +275,44 @@ Preinstruction Predecoder::decode4(uint16_t instruction) { 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; + default: break; } switch(instruction & 0xfc0) { // 4-146 (p250) - case 0x000: return decode(instruction); - case 0x040: return decode(instruction); - case 0x080: return decode(instruction); + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); // 6-17 (p471) - case 0x0c0: return decode(instruction); + case 0x0c0: return decode(instruction); // 4-73 (p177) - case 0x200: return decode(instruction); - case 0x240: return decode(instruction); - case 0x280: return decode(instruction); + 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); + case 0x400: return decode(instruction); + case 0x440: return decode(instruction); + case 0x480: return decode(instruction); // 4-123 (p227) - case 0x4c0: return decode(instruction); + case 0x4c0: return decode(instruction); // 4-148 (p250) - case 0x600: return decode(instruction); - case 0x640: return decode(instruction); - case 0x680: return decode(instruction); + case 0x600: return decode(instruction); + case 0x640: return decode(instruction); + case 0x680: return decode(instruction); // 4-123 (p227) - case 0x6c0: return decode(instruction); + case 0x6c0: return decode(instruction); // 4-142 (p246) - case 0x800: return decode(instruction); + case 0x800: return decode(instruction); // 4-159 (p263) - case 0x840: return decode(instruction); + case 0x840: return decode(instruction); // 4-128 (p232) case 0x880: return decode(instruction); @@ -288,42 +321,42 @@ Preinstruction Predecoder::decode4(uint16_t instruction) { case 0xcc0: return decode(instruction); // 4-192 (p296) - case 0xa00: return decode(instruction); - case 0xa40: return decode(instruction); - case 0xa80: return decode(instruction); + case 0xa00: return decode(instruction); + case 0xa40: return decode(instruction); + case 0xa80: return decode(instruction); // 4-186 (p290) - case 0xac0: return decode(instruction); + case 0xac0: return decode(instruction); // 4-109 (p213) - case 0xe80: return decode(instruction); + case 0xe80: return decode(instruction); // 4-108 (p212) - case 0xec0: return decode(instruction); + case 0xec0: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { - case 0x1c0: return decode(instruction); // 4-110 (p214) - case 0x180: return decode(instruction); // 4-69 (p173) - default: break; + 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) - default: break; + case 0xe40: return decode(instruction); // 4-188 (p292) + default: break; } switch(instruction & 0xff8) { - case 0x860: 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) - case 0xe60: return decode(instruction); // 6-21 (p475) - case 0xe68: return decode(instruction); // 6-21 (p475) - default: break; + case 0x860: 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) + case 0xe60: return decode(instruction); // 6-21 (p475) + case 0xe68: return decode(instruction); // 6-21 (p475) + default: break; } return Preinstruction(); @@ -332,23 +365,23 @@ Preinstruction Predecoder::decode4(uint16_t instruction) { Preinstruction Predecoder::decode5(uint16_t instruction) { switch(instruction & 0x1c0) { // 4-11 (p115) - case 0x000: return decode(instruction); - case 0x040: return decode(instruction); - case 0x080: return decode(instruction); + case 0x000: return decode(instruction); + case 0x040: return decode(instruction); + case 0x080: return decode(instruction); // 4-181 (p285) - case 0x100: return decode(instruction); - case 0x140: return decode(instruction); - case 0x180: return decode(instruction); + case 0x100: return decode(instruction); + case 0x140: return decode(instruction); + case 0x180: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x0c0) { // 4-173 (p276), though this'll also hit DBcc 4-91 (p195) - case 0x0c0: return decode(instruction); + case 0x0c0: return decode(instruction); - default: break; + default: break; } return Preinstruction(); } @@ -372,13 +405,13 @@ Preinstruction Predecoder::decode8(uint16_t instruction) { case 0x00: return decode(instruction); case 0x40: return decode(instruction); case 0x80: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { case 0x0c0: return decode(instruction); // 4-97 (p201) case 0x1c0: return decode(instruction); // 4-93 (p197) - default: break; + default: break; } return Preinstruction(); @@ -391,7 +424,7 @@ Preinstruction Predecoder::decode9(uint16_t instruction) { case 0x40: return decode(instruction); case 0x80: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { @@ -399,7 +432,7 @@ Preinstruction Predecoder::decode9(uint16_t instruction) { case 0x0c0: return decode(instruction); case 0x1c0: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1f0) { @@ -408,7 +441,7 @@ Preinstruction Predecoder::decode9(uint16_t instruction) { case 0x140: return decode(instruction); case 0x180: return decode(instruction); - default: break; + default: break; } return Preinstruction(); @@ -424,7 +457,7 @@ Preinstruction Predecoder::decodeB(uint16_t instruction) { case 0x000: return decode(instruction); case 0x040: return decode(instruction); case 0x080: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { @@ -437,7 +470,7 @@ Preinstruction Predecoder::decodeB(uint16_t instruction) { case 0x0c0: return decode(instruction); case 0x1c0: return decode(instruction); - default: break; + default: break; } return Preinstruction(); @@ -445,8 +478,8 @@ Preinstruction Predecoder::decodeB(uint16_t instruction) { Preinstruction Predecoder::decodeC(uint16_t instruction) { switch(instruction & 0x1f0) { - case 0x100: return decode(instruction); // 4-3 (p107) - default: break; + case 0x100: return decode(instruction); // 4-3 (p107) + default: break; } switch(instruction & 0x0c0) { @@ -454,13 +487,13 @@ Preinstruction Predecoder::decodeC(uint16_t instruction) { case 0x00: return decode(instruction); case 0x40: return decode(instruction); case 0x80: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { case 0x0c0: return decode(instruction); // 4-139 (p243) case 0x1c0: return decode(instruction); // 4-136 (p240) - default: break; + default: break; } // 4-105 (p209) @@ -468,7 +501,7 @@ Preinstruction Predecoder::decodeC(uint16_t instruction) { case 0x140: case 0x148: case 0x188: return decode(instruction); - default: break; + default: break; } return Preinstruction(); @@ -481,7 +514,7 @@ Preinstruction Predecoder::decodeD(uint16_t instruction) { case 0x040: return decode(instruction); case 0x080: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1c0) { @@ -489,7 +522,7 @@ Preinstruction Predecoder::decodeD(uint16_t instruction) { case 0x0c0: return decode(instruction); case 0x1c0: return decode(instruction); - default: break; + default: break; } switch(instruction & 0x1f0) { @@ -498,7 +531,7 @@ Preinstruction Predecoder::decodeD(uint16_t instruction) { case 0x140: return decode(instruction); case 0x180: return decode(instruction); - default: break; + default: break; } return Preinstruction(); @@ -546,7 +579,7 @@ Preinstruction Predecoder::decodeE(uint16_t instruction) { case 0x158: return decode(instruction); case 0x198: return decode(instruction); - default: break; + default: break; } switch(instruction & 0xfc0) { @@ -559,7 +592,7 @@ Preinstruction Predecoder::decodeE(uint16_t instruction) { case 0x6c0: return decode(instruction); // 4-160 (p264) case 0x7c0: return decode(instruction); // 4-160 (p264) - default: break; + default: break; } return Preinstruction(); @@ -591,7 +624,7 @@ Preinstruction Predecoder::decode(uint16_t instruction) { case 0xe000: return decodeE(instruction); case 0xf000: return decodeF(instruction); - default: break; + default: break; } return Preinstruction(); diff --git a/InstructionSets/68k/Instruction.hpp b/InstructionSets/68k/Instruction.hpp index 2924adc15..122e7430c 100644 --- a/InstructionSets/68k/Instruction.hpp +++ b/InstructionSets/68k/Instruction.hpp @@ -131,7 +131,7 @@ enum class AddressingMode: uint8_t { DataRegisterDirect = 0b00'000, /// An - AddressRegisterDirect = 0b11'000, + AddressRegisterDirect = 0b00'001, /// (An) AddressRegisterIndirect = 0b00'010, /// (An)+ @@ -213,12 +213,21 @@ class Preinstruction { Preinstruction( Operation operation, AddressingMode op1_mode, int op1_reg, - AddressingMode op2_mode, int op2_reg) : operation(operation) + AddressingMode op2_mode, int op2_reg, + [[maybe_unused]] bool is_supervisor = false) : operation(operation) { operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5); operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5); } + Preinstruction(Operation operation, [[maybe_unused]] bool is_supervisor = false) : operation(operation) {} + + Preinstruction(Operation operation, AddressingMode op1_mode, int op1_reg, [[maybe_unused]] bool is_supervisor = false) : operation(operation) { + operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5); + } + + // TODO: record is_supervisor. + Preinstruction() {} };