#pragma once //Motorola M68000 namespace Processor { struct M68K { struct Bus { virtual auto readByte(uint24 addr) -> uint16 = 0; virtual auto readWord(uint24 addr) -> uint16 = 0; virtual auto writeByte(uint24 addr, uint16 data) -> void = 0; virtual auto writeWord(uint24 addr, uint16 data) -> void = 0; }; virtual auto step(uint clocks) -> void = 0; enum : bool { User, Supervisor }; enum : uint { Byte, Word, Long }; enum : bool { Reverse = 1, Extend = 1, Hold = 1 }; enum : uint { DataRegisterDirect, AddressRegisterDirect, AddressRegisterIndirect, AddressRegisterIndirectWithPostIncrement, AddressRegisterIndirectWithPreDecrement, AddressRegisterIndirectWithDisplacement, AddressRegisterIndirectWithIndex, AbsoluteShortIndirect, AbsoluteLongIndirect, ProgramCounterIndirectWithDisplacement, ProgramCounterIndirectWithIndex, Immediate, }; struct Exception { enum : uint { Illegal, DivisionByZero, BoundsCheck, Overflow, Unprivileged, Trap, Interrupt, };}; struct Vector { enum : uint { Illegal = 4, DivisionByZero = 5, BoundsCheck = 6, Overflow = 7, Unprivileged = 8, IllegalLineA = 10, IllegalLineF = 11, HorizontalBlank = 28, VerticalBlank = 30, };}; M68K(); auto power() -> void; auto reset() -> void; auto supervisor() -> bool; auto exception(uint exception, uint vector, uint priority = 7) -> void; //registers.cpp struct DataRegister { explicit DataRegister(uint number_) : number(number_) {} uint3 number; }; template auto read(DataRegister reg) -> uint32; template auto write(DataRegister reg, uint32 data) -> void; struct AddressRegister { explicit AddressRegister(uint number_) : number(number_) {} uint3 number; }; template auto read(AddressRegister reg) -> uint32; template auto write(AddressRegister reg, uint32 data) -> void; auto readCCR() -> uint8; auto readSR() -> uint16; auto writeCCR(uint8 ccr) -> void; auto writeSR(uint16 sr) -> void; //memory.cpp template auto read(uint32 addr) -> uint32; template auto write(uint32 addr, uint32 data) -> void; template auto readPC() -> uint32; template auto pop() -> uint32; template auto push(uint32 data) -> void; //effective-address.cpp struct EffectiveAddress { explicit EffectiveAddress(uint mode_, uint reg_) : mode(mode_), reg(reg_) { if(mode == 7) mode += reg; //optimization: convert modes {7; 0-4} to {8-11} } uint4 mode; uint3 reg; boolean valid; uint32 address; }; template auto fetch(EffectiveAddress& ea) -> uint32; template auto read(EffectiveAddress& ea) -> uint32; template auto write(EffectiveAddress& ea, uint32 data) -> void; //instruction.cpp auto instruction() -> void; //instructions.cpp auto testCondition(uint4 condition) -> bool; template auto bytes() -> uint; template auto bits() -> uint; template auto lsb() -> uint32; template auto msb() -> uint32; template auto mask() -> uint32; template auto clip(uint32 data) -> uint32; template auto sign(uint32 data) -> int32; auto instructionABCD(EffectiveAddress with, EffectiveAddress from) -> void; template auto ADD(uint32 source, uint32 target) -> uint32; template auto instructionADD(EffectiveAddress from, DataRegister with) -> void; template auto instructionADD(DataRegister from, EffectiveAddress with) -> void; template auto instructionADDA(AddressRegister ar, EffectiveAddress ea) -> void; template auto instructionADDI(EffectiveAddress modify) -> void; template auto instructionADDQ(uint4 immediate, EffectiveAddress with) -> void; template auto instructionADDQ(uint4 immediate, AddressRegister with) -> void; template auto instructionADDX(EffectiveAddress with, EffectiveAddress from) -> void; template auto AND(uint32 source, uint32 target) -> uint32; template auto instructionAND(EffectiveAddress from, DataRegister with) -> void; template auto instructionAND(DataRegister from, EffectiveAddress with) -> void; template auto instructionANDI(EffectiveAddress with) -> void; auto instructionANDI_TO_CCR() -> void; auto instructionANDI_TO_SR() -> void; template auto ASL(uint32 result, uint shift) -> uint32; template auto instructionASL(uint4 shift, DataRegister modify) -> void; template auto instructionASL(DataRegister shift, DataRegister modify) -> void; auto instructionASL(EffectiveAddress modify) -> void; template auto ASR(uint32 result, uint shift) -> uint32; template auto instructionASR(uint4 shift, DataRegister modify) -> void; template auto instructionASR(DataRegister shift, DataRegister modify) -> void; auto instructionASR(EffectiveAddress modify) -> void; auto instructionBCC(uint4 condition, uint8 displacement) -> void; template auto instructionBCHG(DataRegister bit, EffectiveAddress with) -> void; template auto instructionBCHG(EffectiveAddress with) -> void; template auto instructionBCLR(DataRegister bit, EffectiveAddress with) -> void; template auto instructionBCLR(EffectiveAddress with) -> void; template auto instructionBSET(DataRegister bit, EffectiveAddress with) -> void; template auto instructionBSET(EffectiveAddress with) -> void; template auto instructionBTST(DataRegister bit, EffectiveAddress with) -> void; template auto instructionBTST(EffectiveAddress with) -> void; auto instructionCHK(DataRegister compare, EffectiveAddress maximum) -> void; template auto instructionCLR(EffectiveAddress ea) -> void; template auto CMP(uint32 source, uint32 target) -> uint32; template auto instructionCMP(DataRegister dr, EffectiveAddress ea) -> void; template auto instructionCMPA(AddressRegister ar, EffectiveAddress ea) -> void; template auto instructionCMPI(EffectiveAddress ea) -> void; template auto instructionCMPM(EffectiveAddress ax, EffectiveAddress ay) -> void; auto instructionDBCC(uint4 condition, DataRegister dr) -> void; template auto DIV(uint16 divisor, DataRegister with) -> void; auto instructionDIVS(DataRegister with, EffectiveAddress from) -> void; auto instructionDIVU(DataRegister with, EffectiveAddress from) -> void; template auto EOR(uint32 source, uint32 target) -> uint32; template auto instructionEOR(DataRegister from, EffectiveAddress with) -> void; template auto instructionEORI(EffectiveAddress with) -> void; auto instructionEORI_TO_CCR() -> void; auto instructionEORI_TO_SR() -> void; auto instructionEXG(DataRegister x, DataRegister y) -> void; auto instructionEXG(AddressRegister x, AddressRegister y) -> void; auto instructionEXG(DataRegister x, AddressRegister y) -> void; template auto instructionEXT(DataRegister with) -> void; auto instructionILLEGAL() -> void; auto instructionJMP(EffectiveAddress target) -> void; auto instructionJSR(EffectiveAddress target) -> void; auto instructionLEA(AddressRegister ar, EffectiveAddress ea) -> void; auto instructionLINK(AddressRegister with) -> void; template auto LSL(uint32 result, uint shift) -> uint32; template auto instructionLSL(uint4 immediate, DataRegister dr) -> void; template auto instructionLSL(DataRegister sr, DataRegister dr) -> void; auto instructionLSL(EffectiveAddress ea) -> void; template auto LSR(uint32 result, uint shift) -> uint32; template auto instructionLSR(uint4 immediate, DataRegister dr) -> void; template auto instructionLSR(DataRegister shift, DataRegister dr) -> void; auto instructionLSR(EffectiveAddress ea) -> void; template auto instructionMOVE(EffectiveAddress to, EffectiveAddress from) -> void; template auto instructionMOVEA(AddressRegister ar, EffectiveAddress ea) -> void; template auto instructionMOVEM_TO_MEM(EffectiveAddress to) -> void; template auto instructionMOVEM_TO_REG(EffectiveAddress from) -> void; template auto instructionMOVEP(DataRegister from, EffectiveAddress to) -> void; template auto instructionMOVEP(EffectiveAddress from, DataRegister to) -> void; auto instructionMOVEQ(DataRegister dr, uint8 immediate) -> void; auto instructionMOVE_FROM_SR(EffectiveAddress ea) -> void; auto instructionMOVE_TO_CCR(EffectiveAddress ea) -> void; auto instructionMOVE_TO_SR(EffectiveAddress ea) -> void; auto instructionMOVE_FROM_USP(AddressRegister to) -> void; auto instructionMOVE_TO_USP(AddressRegister from) -> void; auto instructionMULS(DataRegister with, EffectiveAddress from) -> void; auto instructionMULU(DataRegister with, EffectiveAddress from) -> void; auto instructionNBCD(EffectiveAddress with) -> void; template auto instructionNEG(EffectiveAddress with) -> void; template auto instructionNEGX(EffectiveAddress with) -> void; auto instructionNOP() -> void; template auto instructionNOT(EffectiveAddress with) -> void; template auto OR(uint32 source, uint32 target) -> uint32; template auto instructionOR(EffectiveAddress from, DataRegister with) -> void; template auto instructionOR(DataRegister from, EffectiveAddress with) -> void; template auto instructionORI(EffectiveAddress with) -> void; auto instructionORI_TO_CCR() -> void; auto instructionORI_TO_SR() -> void; auto instructionPEA(EffectiveAddress from) -> void; auto instructionRESET() -> void; template auto ROL(uint32 result, uint shift) -> uint32; template auto instructionROL(uint4 shift, DataRegister modify) -> void; template auto instructionROL(DataRegister shift, DataRegister modify) -> void; auto instructionROL(EffectiveAddress modify) -> void; template auto ROR(uint32 result, uint shift) -> uint32; template auto instructionROR(uint4 shift, DataRegister modify) -> void; template auto instructionROR(DataRegister shift, DataRegister modify) -> void; auto instructionROR(EffectiveAddress modify) -> void; template auto ROXL(uint32 result, uint shift) -> uint32; template auto instructionROXL(uint4 shift, DataRegister modify) -> void; template auto instructionROXL(DataRegister shift, DataRegister modify) -> void; auto instructionROXL(EffectiveAddress modify) -> void; template auto ROXR(uint32 result, uint shift) -> uint32; template auto instructionROXR(uint4 shift, DataRegister modify) -> void; template auto instructionROXR(DataRegister shift, DataRegister modify) -> void; auto instructionROXR(EffectiveAddress modify) -> void; auto instructionRTE() -> void; auto instructionRTR() -> void; auto instructionRTS() -> void; auto instructionSBCD(EffectiveAddress with, EffectiveAddress from) -> void; auto instructionSCC(uint4 condition, EffectiveAddress to) -> void; auto instructionSTOP() -> void; template auto SUB(uint32 source, uint32 target) -> uint32; template auto instructionSUB(EffectiveAddress source, DataRegister target) -> void; template auto instructionSUB(DataRegister source, EffectiveAddress target) -> void; template auto instructionSUBA(AddressRegister to, EffectiveAddress from) -> void; template auto instructionSUBI(EffectiveAddress with) -> void; template auto instructionSUBQ(uint4 immediate, EffectiveAddress with) -> void; template auto instructionSUBQ(uint4 immediate, AddressRegister with) -> void; template auto instructionSUBX(EffectiveAddress with, EffectiveAddress from) -> void; auto instructionSWAP(DataRegister with) -> void; auto instructionTAS(EffectiveAddress with) -> void; auto instructionTRAP(uint4 vector) -> void; auto instructionTRAPV() -> void; template auto instructionTST(EffectiveAddress ea) -> void; auto instructionUNLK(AddressRegister with) -> void; //disassembler.cpp auto disassemble(uint32 pc) -> string; auto disassembleRegisters() -> string; struct Registers { uint32 d[8]; //data registers uint32 a[8]; //address registers (a7 = s ? ssp : usp) uint32 sp; //inactive stack pointer (s ? usp : ssp) uint32 pc; //program counter bool c; //carry bool v; //overflow bool z; //zero bool n; //negative bool x; //extend uint3 i; //interrupt mask bool s; //supervisor mode bool t; //trace mode bool stop; bool reset; } r; uint16 opcode = 0; uint instructionsExecuted = 0; function instructionTable[65536]; Bus* bus = nullptr; private: //disassembler.cpp auto disassembleABCD(EffectiveAddress with, EffectiveAddress from) -> string; template auto disassembleADD(EffectiveAddress from, DataRegister with) -> string; template auto disassembleADD(DataRegister from, EffectiveAddress with) -> string; template auto disassembleADDA(AddressRegister ar, EffectiveAddress ea) -> string; template auto disassembleADDI(EffectiveAddress modify) -> string; template auto disassembleADDQ(uint4 immediate, EffectiveAddress with) -> string; template auto disassembleADDQ(uint4 immediate, AddressRegister with) -> string; template auto disassembleADDX(EffectiveAddress with, EffectiveAddress from) -> string; template auto disassembleAND(EffectiveAddress from, DataRegister with) -> string; template auto disassembleAND(DataRegister from, EffectiveAddress with) -> string; template auto disassembleANDI(EffectiveAddress with) -> string; auto disassembleANDI_TO_CCR() -> string; auto disassembleANDI_TO_SR() -> string; template auto disassembleASL(uint4 shift, DataRegister modify) -> string; template auto disassembleASL(DataRegister shift, DataRegister modify) -> string; auto disassembleASL(EffectiveAddress modify) -> string; template auto disassembleASR(uint4 shift, DataRegister modify) -> string; template auto disassembleASR(DataRegister shift, DataRegister modify) -> string; auto disassembleASR(EffectiveAddress modify) -> string; auto disassembleBCC(uint4 condition, uint8 displacement) -> string; template auto disassembleBCHG(DataRegister bit, EffectiveAddress with) -> string; template auto disassembleBCHG(EffectiveAddress with) -> string; template auto disassembleBCLR(DataRegister bit, EffectiveAddress with) -> string; template auto disassembleBCLR(EffectiveAddress with) -> string; template auto disassembleBSET(DataRegister bit, EffectiveAddress with) -> string; template auto disassembleBSET(EffectiveAddress with) -> string; template auto disassembleBTST(DataRegister bit, EffectiveAddress with) -> string; template auto disassembleBTST(EffectiveAddress with) -> string; auto disassembleCHK(DataRegister compare, EffectiveAddress maximum) -> string; template auto disassembleCLR(EffectiveAddress ea) -> string; template auto disassembleCMP(DataRegister dr, EffectiveAddress ea) -> string; template auto disassembleCMPA(AddressRegister ar, EffectiveAddress ea) -> string; template auto disassembleCMPI(EffectiveAddress ea) -> string; template auto disassembleCMPM(EffectiveAddress ax, EffectiveAddress ay) -> string; auto disassembleDBCC(uint4 condition, DataRegister dr) -> string; auto disassembleDIVS(DataRegister with, EffectiveAddress from) -> string; auto disassembleDIVU(DataRegister with, EffectiveAddress from) -> string; template auto disassembleEOR(DataRegister from, EffectiveAddress with) -> string; template auto disassembleEORI(EffectiveAddress with) -> string; auto disassembleEORI_TO_CCR() -> string; auto disassembleEORI_TO_SR() -> string; auto disassembleEXG(DataRegister x, DataRegister y) -> string; auto disassembleEXG(AddressRegister x, AddressRegister y) -> string; auto disassembleEXG(DataRegister x, AddressRegister y) -> string; template auto disassembleEXT(DataRegister with) -> string; auto disassembleILLEGAL() -> string; auto disassembleJMP(EffectiveAddress target) -> string; auto disassembleJSR(EffectiveAddress target) -> string; auto disassembleLEA(AddressRegister ar, EffectiveAddress ea) -> string; auto disassembleLINK(AddressRegister with) -> string; template auto disassembleLSL(uint4 immediate, DataRegister dr) -> string; template auto disassembleLSL(DataRegister sr, DataRegister dr) -> string; auto disassembleLSL(EffectiveAddress ea) -> string; template auto disassembleLSR(uint4 immediate, DataRegister dr) -> string; template auto disassembleLSR(DataRegister shift, DataRegister dr) -> string; auto disassembleLSR(EffectiveAddress ea) -> string; template auto disassembleMOVE(EffectiveAddress to, EffectiveAddress from) -> string; template auto disassembleMOVEA(AddressRegister ar, EffectiveAddress ea) -> string; template auto disassembleMOVEM_TO_MEM(EffectiveAddress to) -> string; template auto disassembleMOVEM_TO_REG(EffectiveAddress from) -> string; template auto disassembleMOVEP(DataRegister from, EffectiveAddress to) -> string; template auto disassembleMOVEP(EffectiveAddress from, DataRegister to) -> string; auto disassembleMOVEQ(DataRegister dr, uint8 immediate) -> string; auto disassembleMOVE_FROM_SR(EffectiveAddress ea) -> string; auto disassembleMOVE_TO_CCR(EffectiveAddress ea) -> string; auto disassembleMOVE_TO_SR(EffectiveAddress ea) -> string; auto disassembleMOVE_FROM_USP(AddressRegister to) -> string; auto disassembleMOVE_TO_USP(AddressRegister from) -> string; auto disassembleMULS(DataRegister with, EffectiveAddress from) -> string; auto disassembleMULU(DataRegister with, EffectiveAddress from) -> string; auto disassembleNBCD(EffectiveAddress with) -> string; template auto disassembleNEG(EffectiveAddress with) -> string; template auto disassembleNEGX(EffectiveAddress with) -> string; auto disassembleNOP() -> string; template auto disassembleNOT(EffectiveAddress with) -> string; template auto disassembleOR(EffectiveAddress from, DataRegister with) -> string; template auto disassembleOR(DataRegister from, EffectiveAddress with) -> string; template auto disassembleORI(EffectiveAddress with) -> string; auto disassembleORI_TO_CCR() -> string; auto disassembleORI_TO_SR() -> string; auto disassemblePEA(EffectiveAddress from) -> string; auto disassembleRESET() -> string; template auto disassembleROL(uint4 shift, DataRegister modify) -> string; template auto disassembleROL(DataRegister shift, DataRegister modify) -> string; auto disassembleROL(EffectiveAddress modify) -> string; template auto disassembleROR(uint4 shift, DataRegister modify) -> string; template auto disassembleROR(DataRegister shift, DataRegister modify) -> string; auto disassembleROR(EffectiveAddress modify) -> string; template auto disassembleROXL(uint4 shift, DataRegister modify) -> string; template auto disassembleROXL(DataRegister shift, DataRegister modify) -> string; auto disassembleROXL(EffectiveAddress modify) -> string; template auto disassembleROXR(uint4 shift, DataRegister modify) -> string; template auto disassembleROXR(DataRegister shift, DataRegister modify) -> string; auto disassembleROXR(EffectiveAddress modify) -> string; auto disassembleRTE() -> string; auto disassembleRTR() -> string; auto disassembleRTS() -> string; auto disassembleSBCD(EffectiveAddress with, EffectiveAddress from) -> string; auto disassembleSCC(uint4 condition, EffectiveAddress to) -> string; auto disassembleSTOP() -> string; template auto disassembleSUB(EffectiveAddress source, DataRegister target) -> string; template auto disassembleSUB(DataRegister source, EffectiveAddress target) -> string; template auto disassembleSUBA(AddressRegister to, EffectiveAddress from) -> string; template auto disassembleSUBI(EffectiveAddress with) -> string; template auto disassembleSUBQ(uint4 immediate, EffectiveAddress with) -> string; template auto disassembleSUBQ(uint4 immediate, AddressRegister with) -> string; template auto disassembleSUBX(EffectiveAddress with, EffectiveAddress from) -> string; auto disassembleSWAP(DataRegister with) -> string; auto disassembleTAS(EffectiveAddress with) -> string; auto disassembleTRAP(uint4 vector) -> string; auto disassembleTRAPV() -> string; template auto disassembleTST(EffectiveAddress ea) -> string; auto disassembleUNLK(AddressRegister with) -> string; template auto _read(uint32 addr) -> uint32; template auto _readPC() -> uint32; auto _readDisplacement(uint32 base) -> uint32; auto _readIndex(uint32 base) -> uint32; auto _dataRegister(DataRegister dr) -> string; auto _addressRegister(AddressRegister ar) -> string; template auto _immediate() -> string; template auto _address(EffectiveAddress& ea) -> string; template auto _effectiveAddress(EffectiveAddress& ea) -> string; auto _branch(uint8 displacement) -> string; template auto _suffix() -> string; auto _condition(uint4 condition) -> string; uint32 _pc; function disassembleTable[65536]; }; }