// Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once #include "../../Globals.h" #include "../CPU.h" enum { MIPS_REG_ZERO=0, MIPS_REG_COMPILER_SCRATCH=1, MIPS_REG_V0=2, MIPS_REG_V1=3, MIPS_REG_A0=4, MIPS_REG_A1=5, MIPS_REG_A2=6, MIPS_REG_A3=7, MIPS_REG_A4=8, // Seems to be N32 register calling convention - there are 8 args instead of 4. MIPS_REG_A5=9, MIPS_REG_S0=16, MIPS_REG_S1=17, MIPS_REG_S2=18, MIPS_REG_S3=19, MIPS_REG_S4=20, MIPS_REG_S5=21, MIPS_REG_S6=22, MIPS_REG_S7=23, MIPS_REG_K0=26, MIPS_REG_K1=27, MIPS_REG_GP=28, MIPS_REG_SP=29, MIPS_REG_FP=30, MIPS_REG_RA=31, // ID for mipscall "callback" is stored here - from JPCSP MIPS_REG_CALL_ID=MIPS_REG_S0, }; enum { VFPU_CTRL_SPREFIX, VFPU_CTRL_TPREFIX, VFPU_CTRL_DPREFIX, VFPU_CTRL_CC, VFPU_CTRL_INF4, VFPU_CTRL_RSV5, VFPU_CTRL_RSV6, VFPU_CTRL_REV, VFPU_CTRL_RCX0, VFPU_CTRL_RCX1, VFPU_CTRL_RCX2, VFPU_CTRL_RCX3, VFPU_CTRL_RCX4, VFPU_CTRL_RCX5, VFPU_CTRL_RCX6, VFPU_CTRL_RCX7, VFPU_CTRL_MAX, //unknown.... }; // George Marsaglia-style random number generator. class GMRng { public: void Init(int seed) { m_w = seed ^ (seed << 16); if (!m_w) m_w = 1337; m_z = ~seed; if (!m_z) m_z = 31337; } u32 R32() { m_z = 36969 * (m_z & 65535) + (m_z >> 16); m_w = 18000 * (m_w & 65535) + (m_w >> 16); return (m_z << 16) + m_w; } private: u32 m_w; u32 m_z; }; class MIPSState : public CPU { public: MIPSState(); ~MIPSState(); void Reset(); u32 r[32]; float f[32]; float v[128]; u32 vfpuCtrl[16]; bool vfpuWriteMask[4]; u32 pc; u32 nextPC; u32 hi; u32 lo; u32 fpcond; //separate for speed - TODO: not worth it u32 fcr0; u32 fcr31; //fpu control register GMRng rng; // VFPU hardware random number generator. Probably not the right type. bool inDelaySlot; int llBit; // ll/sc CPUType cpuType; // TODO: How do we handle exceptions? u32 exceptions; enum { BREAKING_EXCEPTIONS = 1 }; // Debug stuff u32 debugCount; // can be used to count basic blocks before crashes, etc. void WriteFCR(int reg, int value); u32 ReadFCR(int reg); void SetWriteMask(const bool wm[4]); void Irq(); void SWI(); void Abort(); void SingleStep(); int RunLoopUntil(u64 globalTicks); }; class MIPSDebugInterface; //The one we are compiling or running currently extern MIPSState *currentMIPS; extern MIPSDebugInterface *currentDebugMIPS; extern MIPSState mipsr4k; void MIPS_Init(); int MIPS_SingleStep(); void MIPS_Shutdown(); void MIPS_Irq(); void MIPS_SWI();