1 #pragma once 2 3 #include "Types.h" 4 #include "MemoryMap.h" 5 #include "MipsExecutor.h" 6 #include "MIPSArchitecture.h" 7 #include "MIPSCoprocessor.h" 8 #include "MIPSAnalysis.h" 9 #include "MIPSTags.h" 10 #include "uint128.h" 11 #include <set> 12 13 struct REGISTER_PIPELINE 14 { 15 uint32 counter; 16 uint32 heldValue; 17 }; 18 19 enum 20 { 21 //Must be a power of 2 22 FLAG_PIPELINE_SLOTS = 8, 23 }; 24 25 //Invariants: 26 //- Pipe times are sorted when iterating from index to index + PIPELINE_SLOTS 27 //- The value at index - 1 is the latest value 28 struct FLAG_PIPELINE 29 { 30 uint32 index; 31 uint32 values[FLAG_PIPELINE_SLOTS]; 32 uint32 pipeTimes[FLAG_PIPELINE_SLOTS]; 33 }; 34 35 enum 36 { 37 MIPS_EXCEPTION_NONE = 0, 38 MIPS_EXCEPTION_SYSCALL, 39 MIPS_EXCEPTION_CHECKPENDINGINT, 40 MIPS_EXCEPTION_IDLE, 41 MIPS_EXCEPTION_RETURNFROMEXCEPTION, 42 MIPS_EXCEPTION_CALLMS, 43 MIPS_EXCEPTION_BREAKPOINT, 44 MIPS_EXCEPTION_TLB, 45 }; 46 47 struct TLBENTRY 48 { 49 uint32 entryLo0; 50 uint32 entryLo1; 51 uint32 entryHi; 52 uint32 pageMask; 53 }; 54 55 #define MIPS_EXECUTION_STATUS_QUOTADONE 0x80 56 57 struct MIPSSTATE 58 { 59 uint32 nPC; 60 uint32 nDelayedJumpAddr; 61 uint32 nHasException; 62 int32 cycleQuota; 63 64 #ifdef _WIN32 65 __declspec(align(16)) 66 #else 67 __attribute__((aligned(16))) 68 #endif 69 uint128 nGPR[32]; 70 71 uint32 nHI[2]; 72 uint32 nLO[2]; 73 uint32 nHI1[2]; 74 uint32 nLO1[2]; 75 uint32 nSA; 76 77 //COP0 78 uint32 nCOP0[32]; 79 80 uint32 cop0_pccr; 81 uint32 cop0_pcr[2]; 82 83 //COP1 84 uint32 nCOP1[32]; 85 uint32 nCOP1A; 86 uint32 nFCSR; 87 88 //COP2 89 #ifdef _WIN32 90 __declspec(align(16)) 91 #else 92 __attribute__((aligned(16))) 93 #endif 94 uint128 nCOP2[33]; 95 96 uint128 nCOP2A; 97 98 uint128 nCOP2VF_PreUp; 99 uint128 nCOP2VF_UpRes; 100 101 uint32 nCOP2Q; 102 uint32 nCOP2I; 103 uint32 nCOP2P; 104 uint32 nCOP2R; 105 uint32 nCOP2CF; //Mirror of CLIP flag (computed with values from pipeClip) 106 uint32 nCOP2MF; //Mirror of MACflag (computed with values from pipeMac) 107 uint32 nCOP2SF; //Sticky values of sign and zero MACflag (ie.: SxSySzSw ZxZyZzZw) 108 uint32 nCOP2DF; //Division by 0 flag from DIV operations 109 uint32 nCOP2T; 110 111 uint32 nCOP2VI[16]; 112 113 REGISTER_PIPELINE pipeQ; 114 REGISTER_PIPELINE pipeP; 115 FLAG_PIPELINE pipeMac; 116 FLAG_PIPELINE pipeSticky; 117 FLAG_PIPELINE pipeClip; 118 119 uint32 pipeTime; 120 121 uint32 cmsar0; 122 uint32 callMsEnabled; 123 uint32 callMsAddr; 124 125 uint32 savedIntReg; 126 uint32 savedIntRegTemp; 127 uint32 xgkickAddress; 128 129 enum 130 { 131 TLB_ENTRY_MAX = 48, 132 }; 133 134 TLBENTRY tlbEntries[TLB_ENTRY_MAX]; 135 }; 136 137 #define MIPS_INVALID_PC (0x00000001) 138 #define MIPS_PAGE_SIZE (0x1000) 139 140 class CMIPS 141 { 142 public: 143 typedef uint32 (*AddressTranslator)(CMIPS*, uint32); 144 typedef uint32 (*TLBExceptionChecker)(CMIPS*, uint32, uint32); 145 146 typedef std::set<uint32> BreakpointSet; 147 148 CMIPS(MEMORYMAP_ENDIANESS, bool usePageTable = false); 149 ~CMIPS(); 150 void ToggleBreakpoint(uint32); 151 bool HasBreakpointInRange(uint32, uint32) const; 152 bool IsBranch(uint32); 153 static int32 GetBranch(uint16); 154 static uint32 TranslateAddress64(CMIPS*, uint32); 155 156 void Reset(); 157 158 bool CanGenerateInterrupt() const; 159 bool GenerateInterrupt(uint32); 160 bool GenerateException(uint32); 161 162 void MapPages(uint32, uint32, uint8*); 163 164 MIPSSTATE m_State; 165 166 void* m_vuMem = nullptr; 167 void** m_pageLookup = nullptr; 168 169 std::function<void(CMIPS*)> m_emptyBlockHandler; 170 171 CMIPSArchitecture* m_pArch = nullptr; 172 CMIPSCoprocessor* m_pCOP[4]; 173 CMemoryMap* m_pMemoryMap = nullptr; 174 std::unique_ptr<CMipsExecutor> m_executor; 175 BreakpointSet m_breakpoints; 176 177 CMIPSAnalysis* m_analysis = nullptr; 178 CMIPSTags m_Comments; 179 CMIPSTags m_Functions; 180 181 AddressTranslator m_pAddrTranslator = nullptr; 182 TLBExceptionChecker m_TLBExceptionChecker = nullptr; 183 184 enum REGISTER 185 { 186 R0 = 0, 187 AT, 188 V0, 189 V1, 190 A0, 191 A1, 192 A2, 193 A3, 194 T0, 195 T1, 196 T2, 197 T3, 198 T4, 199 T5, 200 T6, 201 T7, 202 S0, 203 S1, 204 S2, 205 S3, 206 S4, 207 S5, 208 S6, 209 S7, 210 T8, 211 T9, 212 K0, 213 K1, 214 GP, 215 SP, 216 FP, 217 RA 218 }; 219 220 enum 221 { 222 STATUS_IE = (1 << 0), 223 STATUS_EXL = (1 << 1), 224 STATUS_ERL = (1 << 2), 225 STATUS_EIE = (1 << 16), //PS2 EE specific 226 }; 227 228 static const char* m_sGPRName[]; 229 }; 230