rm x86 and ppc dynarec remains
[pcsx_rearmed.git] / libpcsxcore / ppc / pR3000A.c
diff --git a/libpcsxcore/ppc/pR3000A.c b/libpcsxcore/ppc/pR3000A.c
deleted file mode 100644 (file)
index 93745f8..0000000
+++ /dev/null
@@ -1,3540 +0,0 @@
-/*  Pcsx - Pc Psx Emulator
- *  Copyright (C) 1999-2003  Pcsx Team
- *
- *  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; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  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 for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA
- */
-
-#ifdef _MSC_VER_
-#pragma warning(disable:4244)
-#pragma warning(disable:4761)
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#include "../psxcommon.h"
-#include "ppc.h"
-#include "reguse.h"
-#include "../r3000a.h"
-#include "../psxhle.h"
-
-//#define NO_CONSTANT
-
-u32 *psxRecLUT;
-
-#undef _Op_
-#define _Op_     _fOp_(psxRegs.code)
-#undef _Funct_
-#define _Funct_  _fFunct_(psxRegs.code)
-#undef _Rd_
-#define _Rd_     _fRd_(psxRegs.code)
-#undef _Rt_
-#define _Rt_     _fRt_(psxRegs.code)
-#undef _Rs_
-#define _Rs_     _fRs_(psxRegs.code)
-#undef _Sa_
-#define _Sa_     _fSa_(psxRegs.code)
-#undef _Im_
-#define _Im_     _fIm_(psxRegs.code)
-#undef _Target_
-#define _Target_ _fTarget_(psxRegs.code)
-
-#undef _Imm_
-#define _Imm_   _fImm_(psxRegs.code)
-#undef _ImmU_
-#define _ImmU_  _fImmU_(psxRegs.code)
-
-#undef PC_REC
-#undef PC_REC8
-#undef PC_REC16
-#undef PC_REC32
-#define PC_REC(x)      (psxRecLUT[x >> 16] + (x & 0xffff))
-#define PC_REC8(x)     (*(u8 *)PC_REC(x))
-#define PC_REC16(x) (*(u16*)PC_REC(x))
-#define PC_REC32(x) (*(u32*)PC_REC(x))
-
-#define OFFSET(X,Y) ((u32)(Y)-(u32)(X))
-
-#define RECMEM_SIZE            (12*1024*1024)
-
-static char *recMem;   /* the recompiled blocks will be here */
-static char *recRAM;   /* and the ptr to the blocks here */
-static char *recROM;   /* and here */
-
-static u32 pc;                 /* recompiler pc */
-static u32 pcold;              /* recompiler oldpc */
-static int count;              /* recompiler intruction count */
-static int branch;             /* set for branch */
-static u32 target;             /* branch target */
-static u32 resp;
-
-u32 cop2readypc = 0;
-u32 idlecyclecount = 0;
-
-#define NUM_REGISTERS  34
-typedef struct {
-       int state;
-       u32 k;
-       int reg;
-} iRegisters;
-
-static iRegisters iRegs[34];
-
-#define ST_UNK      0x00
-#define ST_CONST    0x01
-#define ST_MAPPED   0x02
-
-#ifdef NO_CONSTANT
-#define IsConst(reg) 0
-#else
-#define IsConst(reg)  (iRegs[reg].state & ST_CONST)
-#endif
-#define IsMapped(reg) (iRegs[reg].state & ST_MAPPED)
-
-static void (*recBSC[64])();
-static void (*recSPC[64])();
-static void (*recREG[32])();
-static void (*recCP0[32])();
-static void (*recCP2[64])();
-static void (*recCP2BSC[32])();
-
-#define REG_LO                 32
-#define REG_HI                 33
-
-// Hardware register usage
-#define HWUSAGE_NONE     0x00
-
-#define HWUSAGE_READ     0x01
-#define HWUSAGE_WRITE    0x02
-#define HWUSAGE_CONST    0x04
-#define HWUSAGE_ARG      0x08  /* used as an argument for a function call */
-
-#define HWUSAGE_RESERVED 0x10  /* won't get flushed when flushing all regs */
-#define HWUSAGE_SPECIAL  0x20  /* special purpose register */
-#define HWUSAGE_HARDWIRED 0x40 /* specific hardware register mapping that is never disposed */
-#define HWUSAGE_INITED    0x80
-#define HWUSAGE_PSXREG    0x100
-
-// Remember to invalidate the special registers if they are modified by compiler
-enum {
-    ARG1 = 3,
-    ARG2 = 4,
-    ARG3 = 5,
-    PSXREGS,   // ptr
-        PSXMEM,                // ptr
-    CYCLECOUNT,        // ptr
-    PSXPC,     // ptr
-    TARGETPTR, // ptr
-    TARGET,    // ptr
-    RETVAL,
-    REG_RZERO,
-    REG_WZERO
-};
-
-typedef struct {
-    int code;
-    u32 k;
-    int usage;
-    int lastUsed;
-    
-    void (*flush)(int hwreg);
-    int private;
-} HWRegister;
-static HWRegister HWRegisters[NUM_HW_REGISTERS];
-static int HWRegUseCount;
-static int DstCPUReg;
-static int UniqueRegAlloc;
-
-static int GetFreeHWReg();
-static void InvalidateCPURegs();
-static void DisposeHWReg(int index);
-static void FlushHWReg(int index);
-static void FlushAllHWReg();
-static void MapPsxReg32(int reg);
-static void FlushPsxReg32(int hwreg);
-static int UpdateHWRegUsage(int hwreg, int usage);
-static int GetHWReg32(int reg);
-static int PutHWReg32(int reg);
-static int GetSpecialIndexFromHWRegs(int which);
-static int GetHWRegFromCPUReg(int cpureg);
-static int MapRegSpecial(int which);
-static void FlushRegSpecial(int hwreg);
-static int GetHWRegSpecial(int which);
-static int PutHWRegSpecial(int which);
-static void recRecompile();
-static void recError();
-
-#pragma mark --- Generic register mapping ---
-
-static int GetFreeHWReg()
-{
-       int i, least, index;
-       
-       if (DstCPUReg != -1) {
-               index = GetHWRegFromCPUReg(DstCPUReg);
-               DstCPUReg = -1;
-       } else {
-           // LRU algorith with a twist ;)
-           for (i=0; i<NUM_HW_REGISTERS; i++) {
-                   if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
-                           break;
-                   }
-           }
-    
-           least = HWRegisters[i].lastUsed; index = i;
-           for (; i<NUM_HW_REGISTERS; i++) {
-                   if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
-                           if (HWRegisters[i].usage == HWUSAGE_NONE && HWRegisters[i].code >= 13) {
-                                   index = i;
-                                   break;
-                           }
-                           else if (HWRegisters[i].lastUsed < least) {
-                                   least = HWRegisters[i].lastUsed;
-                                   index = i;
-                           }
-                   }
-           }
-                
-                // Cycle the registers
-                if (HWRegisters[index].usage == HWUSAGE_NONE) {
-                       for (; i<NUM_HW_REGISTERS; i++) {
-                               if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
-                                       if (HWRegisters[i].usage == HWUSAGE_NONE && 
-                                                HWRegisters[i].code >= 13 && 
-                                                HWRegisters[i].lastUsed < least) {
-                                               least = HWRegisters[i].lastUsed;
-                                               index = i;
-                                               break;
-                                       }
-                               }
-                       }
-                }
-       }
-       
-/*     if (HWRegisters[index].code < 13 && HWRegisters[index].code > 3) {
-               SysPrintf("Allocating volatile register %i\n", HWRegisters[index].code);
-       }
-       if (HWRegisters[index].usage != HWUSAGE_NONE) {
-               SysPrintf("RegUse too big. Flushing %i\n", HWRegisters[index].code);
-       }*/
-       if (HWRegisters[index].usage & (HWUSAGE_RESERVED | HWUSAGE_HARDWIRED)) {
-               if (HWRegisters[index].usage & HWUSAGE_RESERVED) {
-                       SysPrintf("Error! Trying to map a new register to a reserved register (r%i)", 
-                                               HWRegisters[index].code);
-               }
-               if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) {
-                       SysPrintf("Error! Trying to map a new register to a hardwired register (r%i)", 
-                                               HWRegisters[index].code);
-               }
-       }
-       
-       if (HWRegisters[index].lastUsed != 0) {
-               UniqueRegAlloc = 0;
-       }
-       
-       // Make sure the register is really flushed!
-       FlushHWReg(index);
-       HWRegisters[index].usage = HWUSAGE_NONE;
-       HWRegisters[index].flush = NULL;
-       
-       return index;
-}
-
-static void FlushHWReg(int index)
-{
-       if (index < 0) return;
-       if (HWRegisters[index].usage == HWUSAGE_NONE) return;
-       
-       if (HWRegisters[index].flush) {
-               HWRegisters[index].usage |= HWUSAGE_RESERVED;
-               HWRegisters[index].flush(index);
-               HWRegisters[index].flush = NULL;
-       }
-       
-       if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) {
-               HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE);
-       } else {
-               HWRegisters[index].usage = HWUSAGE_NONE;
-       }
-}
-
-// get rid of a mapped register without flushing the contents to the memory
-static void DisposeHWReg(int index)
-{
-       if (index < 0) return;
-       if (HWRegisters[index].usage == HWUSAGE_NONE) return;
-       
-       HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE);
-       if (HWRegisters[index].usage == HWUSAGE_NONE) {
-               SysPrintf("Error! not correctly disposing register (r%i)", HWRegisters[index].code);
-       }
-       
-       FlushHWReg(index);
-}
-
-// operated on cpu registers
-__inline static void FlushCPURegRange(int start, int end)
-{
-       int i;
-       
-       if (end <= 0) end = 31;
-       if (start <= 0) start = 0;
-       
-       for (i=0; i<NUM_HW_REGISTERS; i++) {
-               if (HWRegisters[i].code >= start && HWRegisters[i].code <= end)
-                       if (HWRegisters[i].flush)
-                               FlushHWReg(i);
-       }
-
-       for (i=0; i<NUM_HW_REGISTERS; i++) {
-               if (HWRegisters[i].code >= start && HWRegisters[i].code <= end)
-                       FlushHWReg(i);
-       }
-}
-
-static void FlushAllHWReg()
-{
-       FlushCPURegRange(0,31);
-}
-
-static void InvalidateCPURegs()
-{
-       FlushCPURegRange(0,12);
-}
-
-#pragma mark --- Mapping utility functions ---
-
-static void MoveHWRegToCPUReg(int cpureg, int hwreg)
-{
-       int dstreg;
-       
-       if (HWRegisters[hwreg].code == cpureg)
-               return;
-       
-       dstreg = GetHWRegFromCPUReg(cpureg);
-       
-       HWRegisters[dstreg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG);
-       if (HWRegisters[hwreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) {
-               FlushHWReg(dstreg);
-               MR(HWRegisters[dstreg].code, HWRegisters[hwreg].code);
-       } else {
-               if (HWRegisters[dstreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) {
-                       MR(HWRegisters[hwreg].code, HWRegisters[dstreg].code);
-               }
-               else if (HWRegisters[dstreg].usage != HWUSAGE_NONE) {
-                       FlushHWReg(dstreg);
-               }
-       }
-       
-       HWRegisters[dstreg].code = HWRegisters[hwreg].code;
-       HWRegisters[hwreg].code = cpureg;
-}
-
-static int UpdateHWRegUsage(int hwreg, int usage)
-{
-       HWRegisters[hwreg].lastUsed = ++HWRegUseCount;    
-       if (usage & HWUSAGE_WRITE) {
-               HWRegisters[hwreg].usage &= ~HWUSAGE_CONST;
-       }
-       if (!(usage & HWUSAGE_INITED)) {
-               HWRegisters[hwreg].usage &= ~HWUSAGE_INITED;
-       }
-       HWRegisters[hwreg].usage |= usage;
-       
-       return HWRegisters[hwreg].code;
-}
-
-static int GetHWRegFromCPUReg(int cpureg)
-{
-       int i;
-       for (i=0; i<NUM_HW_REGISTERS; i++) {
-               if (HWRegisters[i].code == cpureg) {
-                       return i;
-               }
-       }
-       
-       SysPrintf("Error! Register location failure (r%i)", cpureg);
-       return 0;
-}
-
-// this function operates on cpu registers
-void SetDstCPUReg(int cpureg)
-{
-       DstCPUReg = cpureg;
-}
-
-static void ReserveArgs(int args)
-{
-       int index, i;
-       
-       for (i=0; i<args; i++) {
-               index = GetHWRegFromCPUReg(3+i);
-               HWRegisters[index].usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG;
-       }
-}
-
-static void ReleaseArgs()
-{
-       int i;
-       
-       for (i=0; i<NUM_HW_REGISTERS; i++) {
-               if (HWRegisters[i].usage & HWUSAGE_ARG) {
-                       //HWRegisters[i].usage = HWUSAGE_NONE;
-                       //HWRegisters[i].flush = NULL;
-                       HWRegisters[i].usage &= ~(HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG);
-                       FlushHWReg(i);
-               }
-       }
-}
-
-#pragma mark --- Psx register mapping ---
-
-static void MapPsxReg32(int reg)
-{
-    int hwreg = GetFreeHWReg();
-    HWRegisters[hwreg].flush = FlushPsxReg32;
-    HWRegisters[hwreg].private = reg;
-    
-    if (iRegs[reg].reg != -1) {
-        SysPrintf("error: double mapped psx register");
-    }
-    
-    iRegs[reg].reg = hwreg;
-    iRegs[reg].state |= ST_MAPPED;
-}
-
-static void FlushPsxReg32(int hwreg)
-{
-       int reg = HWRegisters[hwreg].private;
-       
-       if (iRegs[reg].reg == -1) {
-               SysPrintf("error: flushing unmapped psx register");
-       }
-       
-       if (HWRegisters[hwreg].usage & HWUSAGE_WRITE) {
-               if (branch) {
-                       /*int reguse = nextPsxRegUse(pc-8, reg);
-                       if (reguse == REGUSE_NONE || (reguse & REGUSE_READ))*/ {
-                               STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
-                       }
-               } else {
-                       int reguse = nextPsxRegUse(pc-4, reg);
-                       if (reguse == REGUSE_NONE || (reguse & REGUSE_READ)) {
-                               STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
-                       }
-               }
-       }
-       
-       iRegs[reg].reg = -1;
-       iRegs[reg].state = ST_UNK;
-}
-
-static int GetHWReg32(int reg)
-{
-       int usage = HWUSAGE_PSXREG | HWUSAGE_READ;
-       
-       if (reg == 0) {
-               return GetHWRegSpecial(REG_RZERO);
-       }
-       if (!IsMapped(reg)) {
-               usage |= HWUSAGE_INITED;
-               MapPsxReg32(reg);
-               
-               HWRegisters[iRegs[reg].reg].usage |= HWUSAGE_RESERVED;
-               if (IsConst(reg)) {
-                       LIW(HWRegisters[iRegs[reg].reg].code, iRegs[reg].k);
-                       usage |= HWUSAGE_WRITE | HWUSAGE_CONST;
-                       //iRegs[reg].state &= ~ST_CONST;
-               }
-               else {
-                       LWZ(HWRegisters[iRegs[reg].reg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
-               }
-               HWRegisters[iRegs[reg].reg].usage &= ~HWUSAGE_RESERVED;
-       }
-       else if (DstCPUReg != -1) {
-               int dst = DstCPUReg;
-               DstCPUReg = -1;
-               
-               if (HWRegisters[iRegs[reg].reg].code < 13) {
-                       MoveHWRegToCPUReg(dst, iRegs[reg].reg);
-               } else {
-                       MR(DstCPUReg, HWRegisters[iRegs[reg].reg].code);
-               }
-       }
-       
-       DstCPUReg = -1;
-       
-       return UpdateHWRegUsage(iRegs[reg].reg, usage);
-}
-
-static int PutHWReg32(int reg)
-{
-       int usage = HWUSAGE_PSXREG | HWUSAGE_WRITE;
-       if (reg == 0) {
-               return PutHWRegSpecial(REG_WZERO);
-       }
-       
-       if (DstCPUReg != -1 && IsMapped(reg)) {
-               if (HWRegisters[iRegs[reg].reg].code != DstCPUReg) {
-                       int tmp = DstCPUReg;
-                       DstCPUReg = -1;
-                       DisposeHWReg(iRegs[reg].reg);
-                       DstCPUReg = tmp;
-               }
-       }
-       if (!IsMapped(reg)) {
-               usage |= HWUSAGE_INITED;
-               MapPsxReg32(reg);
-       }
-       
-       DstCPUReg = -1;
-       iRegs[reg].state &= ~ST_CONST;
-
-       return UpdateHWRegUsage(iRegs[reg].reg, usage);
-}
-
-#pragma mark --- Special register mapping ---
-
-static int GetSpecialIndexFromHWRegs(int which)
-{
-       int i;
-       for (i=0; i<NUM_HW_REGISTERS; i++) {
-               if (HWRegisters[i].usage & HWUSAGE_SPECIAL) {
-                       if (HWRegisters[i].private == which) {
-                               return i;
-                       }
-               }
-       }
-       return -1;
-}
-
-static int MapRegSpecial(int which)
-{
-       int hwreg = GetFreeHWReg();
-       HWRegisters[hwreg].flush = FlushRegSpecial;
-       HWRegisters[hwreg].private = which;
-       
-       return hwreg;
-}
-
-static void FlushRegSpecial(int hwreg)
-{
-       int which = HWRegisters[hwreg].private;
-       
-       if (!(HWRegisters[hwreg].usage & HWUSAGE_WRITE))
-               return;
-       
-       switch (which) {
-               case CYCLECOUNT:
-                       STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS));
-                       break;
-               case PSXPC:
-                       STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS));
-                       break;
-               case TARGET:
-                       STW(HWRegisters[hwreg].code, 0, GetHWRegSpecial(TARGETPTR));
-                       break;
-       }
-}
-
-static int GetHWRegSpecial(int which)
-{
-       int index = GetSpecialIndexFromHWRegs(which);
-       int usage = HWUSAGE_READ | HWUSAGE_SPECIAL;
-       
-       if (index == -1) {
-               usage |= HWUSAGE_INITED;
-               index = MapRegSpecial(which);
-               
-               HWRegisters[index].usage |= HWUSAGE_RESERVED;
-               switch (which) {
-                       case PSXREGS:
-                       case PSXMEM:
-                               SysPrintf("error! shouldn't be here!\n");
-                               //HWRegisters[index].flush = NULL;
-                               //LIW(HWRegisters[index].code, (u32)&psxRegs);
-                               break;
-                       case TARGETPTR:
-                               HWRegisters[index].flush = NULL;
-                               LIW(HWRegisters[index].code, (u32)&target);
-                               break;
-                       case REG_RZERO:
-                               HWRegisters[index].flush = NULL;
-                               LIW(HWRegisters[index].code, 0);
-                               break;
-                       case RETVAL:
-                               MoveHWRegToCPUReg(3, index);
-                               /*reg = GetHWRegFromCPUReg(3);
-                               HWRegisters[reg].code = HWRegisters[index].code;
-                               HWRegisters[index].code = 3;*/
-                               HWRegisters[index].flush = NULL;
-                               
-                               usage |= HWUSAGE_RESERVED;
-                               break;
-
-                       case CYCLECOUNT:
-                               LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS));
-                               break;
-                       case PSXPC:
-                               LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS));
-                               break;
-                       case TARGET:
-                               LWZ(HWRegisters[index].code, 0, GetHWRegSpecial(TARGETPTR));
-                               break;
-                       default:
-                               SysPrintf("Error: Unknown special register in GetHWRegSpecial()\n");
-                               break;
-               }
-               HWRegisters[index].usage &= ~HWUSAGE_RESERVED;
-       }
-       else if (DstCPUReg != -1) {
-               int dst = DstCPUReg;
-               DstCPUReg = -1;
-               
-               MoveHWRegToCPUReg(dst, index);
-       }
-
-       return UpdateHWRegUsage(index, usage);
-}
-
-static int PutHWRegSpecial(int which)
-{
-       int index = GetSpecialIndexFromHWRegs(which);
-       int usage = HWUSAGE_WRITE | HWUSAGE_SPECIAL;
-       
-       if (DstCPUReg != -1 && index != -1) {
-               if (HWRegisters[index].code != DstCPUReg) {
-                       int tmp = DstCPUReg;
-                       DstCPUReg = -1;
-                       DisposeHWReg(index);
-                       DstCPUReg = tmp;
-               }
-       }
-       switch (which) {
-               case PSXREGS:
-               case TARGETPTR:
-                       SysPrintf("Error: Read-only special register in PutHWRegSpecial()\n");
-               case REG_WZERO:
-                       if (index >= 0) {
-                                       if (HWRegisters[index].usage & HWUSAGE_WRITE)
-                                               break;
-                       }
-                       index = MapRegSpecial(which);
-                       HWRegisters[index].flush = NULL;
-                       break;
-               default:
-                       if (index == -1) {
-                               usage |= HWUSAGE_INITED;
-                               index = MapRegSpecial(which);
-                               
-                               HWRegisters[index].usage |= HWUSAGE_RESERVED;
-                               switch (which) {
-                                       case ARG1:
-                                       case ARG2:
-                                       case ARG3:
-                                               MoveHWRegToCPUReg(3+(which-ARG1), index);
-                                               /*reg = GetHWRegFromCPUReg(3+(which-ARG1));
-                                               
-                                               if (HWRegisters[reg].usage != HWUSAGE_NONE) {
-                                                       HWRegisters[reg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG);
-                                                       if (HWRegisters[reg].flush != NULL && HWRegisters[reg].usage & (HWUSAGE_WRITE | HWUSAGE_READ)) {
-                                                               MR(HWRegisters[index].code, HWRegisters[reg].code);
-                                                       } else {
-                                                               FlushHWReg(reg);
-                                                       }
-                                               }
-                                               HWRegisters[reg].code = HWRegisters[index].code;
-                                               if (!(HWRegisters[index].code >= 3 && HWRegisters[index].code <=31))
-                                                       SysPrintf("Error! Register allocation");
-                                               HWRegisters[index].code = 3+(which-ARG1);*/
-                                               HWRegisters[index].flush = NULL;
-                                               
-                                               usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG;
-                                               break;
-                               }
-                       }
-                       HWRegisters[index].usage &= ~HWUSAGE_RESERVED;
-                       break;
-       }
-       
-       DstCPUReg = -1;
-
-       return UpdateHWRegUsage(index, usage);
-}
-
-#pragma mark --- ---
-
-static void MapConst(int reg, u32 _const) {
-       if (reg == 0)
-               return;
-       if (IsConst(reg) && iRegs[reg].k == _const)
-               return;
-       
-       DisposeHWReg(iRegs[reg].reg);
-       iRegs[reg].k = _const;
-       iRegs[reg].state = ST_CONST;
-}
-
-static void MapCopy(int dst, int src)
-{
-    // do it the lazy way for now
-    MR(PutHWReg32(dst), GetHWReg32(src));
-}
-
-static void iFlushReg(u32 nextpc, int reg) {
-       if (!IsMapped(reg) && IsConst(reg)) {
-               GetHWReg32(reg);
-       }
-       if (IsMapped(reg)) {
-               if (nextpc) {
-                       int use = nextPsxRegUse(nextpc, reg);
-                       if ((use & REGUSE_RW) == REGUSE_WRITE) {
-                               DisposeHWReg(iRegs[reg].reg);
-                       } else {
-                               FlushHWReg(iRegs[reg].reg);
-                       }
-               } else {
-                       FlushHWReg(iRegs[reg].reg);
-               }
-       }
-}
-
-static void iFlushRegs(u32 nextpc) {
-       int i;
-
-       for (i=1; i<NUM_REGISTERS; i++) {
-               iFlushReg(nextpc, i);
-       }
-}
-
-static void Return()
-{
-       iFlushRegs(0);
-       FlushAllHWReg();
-       if (((u32)returnPC & 0x1fffffc) == (u32)returnPC) {
-               BA((u32)returnPC);
-       }
-       else {
-               LIW(0, (u32)returnPC);
-               MTLR(0);
-               BLR();
-       }
-}
-
-static void iRet() {
-    /* store cycle */
-    count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-    ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-    Return();
-}
-
-static int iLoadTest() {
-       u32 tmp;
-
-       // check for load delay
-       tmp = psxRegs.code >> 26;
-       switch (tmp) {
-               case 0x10: // COP0
-                       switch (_Rs_) {
-                               case 0x00: // MFC0
-                               case 0x02: // CFC0
-                                       return 1;
-                       }
-                       break;
-               case 0x12: // COP2
-                       switch (_Funct_) {
-                               case 0x00:
-                                       switch (_Rs_) {
-                                               case 0x00: // MFC2
-                                               case 0x02: // CFC2
-                                                       return 1;
-                                       }
-                                       break;
-                       }
-                       break;
-               case 0x32: // LWC2
-                       return 1;
-               default:
-                       if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
-                               return 1;
-                       }
-                       break;
-       }
-       return 0;
-}
-
-/* set a pending branch */
-static void SetBranch() {
-       int treg;
-       branch = 1;
-       psxRegs.code = PSXMu32(pc);
-       pc+=4;
-
-       if (iLoadTest() == 1) {
-               iFlushRegs(0);
-               LIW(0, psxRegs.code);
-               STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
-               /* store cycle */
-               count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-               ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-               
-               treg = GetHWRegSpecial(TARGET);
-               MR(PutHWRegSpecial(ARG2), treg);
-               DisposeHWReg(GetHWRegFromCPUReg(treg));
-               LIW(PutHWRegSpecial(ARG1), _Rt_);
-                LIW(GetHWRegSpecial(PSXPC), pc);
-               FlushAllHWReg();
-               CALLFunc((u32)psxDelayTest);
-
-               Return();
-               return;
-       }
-
-       recBSC[psxRegs.code>>26]();
-
-       iFlushRegs(0);
-       treg = GetHWRegSpecial(TARGET);
-       MR(PutHWRegSpecial(PSXPC), GetHWRegSpecial(TARGET)); // FIXME: this line should not be needed
-       DisposeHWReg(GetHWRegFromCPUReg(treg));
-       FlushAllHWReg();
-
-       count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-        ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-       FlushAllHWReg();
-       CALLFunc((u32)psxBranchTest);
-       
-       // TODO: don't return if target is compiled
-       Return();
-}
-
-static void iJump(u32 branchPC) {
-       u32 *b1, *b2;
-       branch = 1;
-       psxRegs.code = PSXMu32(pc);
-       pc+=4;
-
-       if (iLoadTest() == 1) {
-               iFlushRegs(0);
-               LIW(0, psxRegs.code);
-               STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
-               /* store cycle */
-               count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-               ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-
-               LIW(PutHWRegSpecial(ARG2), branchPC);
-               LIW(PutHWRegSpecial(ARG1), _Rt_);
-               LIW(GetHWRegSpecial(PSXPC), pc);
-               FlushAllHWReg();
-               CALLFunc((u32)psxDelayTest);
-                
-               Return();
-               return;
-       }
-
-       recBSC[psxRegs.code>>26]();
-
-       iFlushRegs(branchPC);
-       LIW(PutHWRegSpecial(PSXPC), branchPC);
-       FlushAllHWReg();
-
-       count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-        //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) {
-        //    LIW(PutHWRegSpecial(CYCLECOUNT), 0);
-        //} else {
-            ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-        //}
-       FlushAllHWReg();
-       CALLFunc((u32)psxBranchTest);
-
-       if (!Config.HLE && Config.PsxOut &&
-           ((branchPC & 0x1fffff) == 0xa0 ||
-            (branchPC & 0x1fffff) == 0xb0 ||
-            (branchPC & 0x1fffff) == 0xc0))
-         CALLFunc((u32)psxJumpTest);
-
-       // always return for now...
-       //Return();
-               
-       // maybe just happened an interruption, check so
-       LIW(0, branchPC);
-       CMPLW(GetHWRegSpecial(PSXPC), 0);
-       BNE_L(b1);
-       
-       LIW(3, PC_REC(branchPC));
-       LWZ(3, 0, 3);
-       CMPLWI(3, 0);
-       BNE_L(b2);
-       
-       B_DST(b1);
-       Return();
-       
-       // next bit is already compiled - jump right to it
-       B_DST(b2);
-       MTCTR(3);
-       BCTR();
-}
-
-static void iBranch(u32 branchPC, int savectx) {
-       HWRegister HWRegistersS[NUM_HW_REGISTERS];
-       iRegisters iRegsS[NUM_REGISTERS];
-       int HWRegUseCountS = 0;
-       u32 respold=0;
-       u32 *b1, *b2;
-
-       if (savectx) {
-               respold = resp;
-               memcpy(iRegsS, iRegs, sizeof(iRegs));
-               memcpy(HWRegistersS, HWRegisters, sizeof(HWRegisters));
-               HWRegUseCountS = HWRegUseCount;
-       }
-       
-       branch = 1;
-       psxRegs.code = PSXMu32(pc);
-
-       // the delay test is only made when the branch is taken
-       // savectx == 0 will mean that :)
-       if (savectx == 0 && iLoadTest() == 1) {
-               iFlushRegs(0);
-               LIW(0, psxRegs.code);
-               STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
-               /* store cycle */
-               count = (idlecyclecount + ((pc+4) - pcold) / 4) * BIAS;
-               ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-
-               LIW(PutHWRegSpecial(ARG2), branchPC);
-               LIW(PutHWRegSpecial(ARG1), _Rt_);
-                LIW(GetHWRegSpecial(PSXPC), pc);
-               FlushAllHWReg();
-               CALLFunc((u32)psxDelayTest);
-
-               Return();
-               return;
-       }
-
-       pc+= 4;
-       recBSC[psxRegs.code>>26]();
-       
-       iFlushRegs(branchPC);
-       LIW(PutHWRegSpecial(PSXPC), branchPC);
-       FlushAllHWReg();
-
-       /* store cycle */
-       count = (idlecyclecount + (pc - pcold) / 4) * BIAS;
-        //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) {
-        //    LIW(PutHWRegSpecial(CYCLECOUNT), 0);
-        //} else {
-            ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-        //}
-       FlushAllHWReg();
-       CALLFunc((u32)psxBranchTest);
-       
-       // always return for now...
-       //Return();
-
-       LIW(0, branchPC);
-       CMPLW(GetHWRegSpecial(PSXPC), 0);
-       BNE_L(b1);
-       
-       LIW(3, PC_REC(branchPC));
-       LWZ(3, 0, 3);
-       CMPLWI(3, 0);
-       BNE_L(b2);
-       
-       B_DST(b1);
-       Return();
-       
-       B_DST(b2);
-       MTCTR(3);
-       BCTR();
-
-       // maybe just happened an interruption, check so
-/*     CMP32ItoM((u32)&psxRegs.pc, branchPC);
-       j8Ptr[1] = JE8(0);
-       RET();
-
-       x86SetJ8(j8Ptr[1]);
-       MOV32MtoR(EAX, PC_REC(branchPC));
-       TEST32RtoR(EAX, EAX);
-       j8Ptr[2] = JNE8(0);
-       RET();
-
-       x86SetJ8(j8Ptr[2]);
-       JMP32R(EAX);*/
-
-       pc-= 4;
-       if (savectx) {
-               resp = respold;
-               memcpy(iRegs, iRegsS, sizeof(iRegs));
-               memcpy(HWRegisters, HWRegistersS, sizeof(HWRegisters));
-               HWRegUseCount = HWRegUseCountS;
-       }
-}
-
-
-static void iDumpRegs() {
-       int i, j;
-
-       printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle);
-       for (i=0; i<4; i++) {
-               for (j=0; j<8; j++)
-                       printf("%lx ", psxRegs.GPR.r[j*i]);
-               printf("\n");
-       }
-}
-
-void iDumpBlock(char *ptr) {
-/*     FILE *f;
-       u32 i;
-
-       SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxCurrentCycle);
-
-       for (i = psxRegs.pc; i < pc; i+=4)
-               SysPrintf("%s\n", disR3000AF(PSXMu32(i), i));
-
-       fflush(stdout);
-       f = fopen("dump1", "w");
-       fwrite(ptr, 1, (u32)x86Ptr - (u32)ptr, f);
-       fclose(f);
-       system("ndisasmw -u dump1");
-       fflush(stdout);*/
-}
-
-#define REC_FUNC(f) \
-void psx##f(); \
-static void rec##f() { \
-       iFlushRegs(0); \
-       LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
-       STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
-       LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
-       FlushAllHWReg(); \
-       CALLFunc((u32)psx##f); \
-/*     branch = 2; */\
-}
-
-#define REC_SYS(f) \
-void psx##f(); \
-static void rec##f() { \
-       iFlushRegs(0); \
-        LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
-        STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
-        LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
-        FlushAllHWReg(); \
-       CALLFunc((u32)psx##f); \
-       branch = 2; \
-       iRet(); \
-}
-
-#define REC_BRANCH(f) \
-void psx##f(); \
-static void rec##f() { \
-       iFlushRegs(0); \
-        LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
-        STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
-        LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
-        FlushAllHWReg(); \
-       CALLFunc((u32)psx##f); \
-       branch = 2; \
-       iRet(); \
-}
-
-static void freeMem(int all)
-{
-    if (recMem) free(recMem);
-    if (recRAM) free(recRAM);
-    if (recROM) free(recROM);
-    recMem = recRAM = recROM = 0;
-    
-    if (all && psxRecLUT) {
-        free(psxRecLUT); psxRecLUT = NULL;
-    }
-}
-
-static int allocMem() {
-       int i;
-
-       freeMem(0);
-        
-       if (psxRecLUT==NULL)
-               psxRecLUT = (u32*) malloc(0x010000 * 4);
-
-       recMem = (char*) malloc(RECMEM_SIZE);
-        //recMem = mmap(NULL, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1,  0);
-       recRAM = (char*) malloc(0x200000);
-       recROM = (char*) malloc(0x080000);
-       if (recRAM == NULL || recROM == NULL || recMem == NULL/*(void *)-1*/ || psxRecLUT == NULL) {
-                freeMem(1);
-               SysMessage("Error allocating memory"); return -1;
-       }
-
-       for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16];
-       memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * 4);
-       memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * 4);
-
-       for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (u32)&recROM[i << 16];
-       
-       return 0;
-}
-
-static int recInit() {
-       return allocMem();
-}
-
-static void recReset() {
-       memset(recRAM, 0, 0x200000);
-       memset(recROM, 0, 0x080000);
-
-       ppcInit();
-       ppcSetPtr((u32 *)recMem);
-
-       branch = 0;
-       memset(iRegs, 0, sizeof(iRegs));
-       iRegs[0].state = ST_CONST;
-       iRegs[0].k     = 0;
-}
-
-static void recShutdown() {
-        freeMem(1);
-       ppcShutdown();
-}
-
-static void recError() {
-       SysReset();
-       ClosePlugins();
-       SysMessage("Unrecoverable error while running recompiler\n");
-       SysRunGui();
-}
-
-__inline static void execute() {
-       void (**recFunc)();
-       char *p;
-
-       p =     (char*)PC_REC(psxRegs.pc);
-       /*if (p != NULL)*/ recFunc = (void (**)()) (u32)p;
-       /*else { recError(); return; }*/
-
-       if (*recFunc == 0) {
-               recRecompile();
-       }
-       recRun(*recFunc, (u32)&psxRegs, (u32)&psxM);
-}
-
-static void recExecute() {
-       for (;;) execute();
-}
-
-static void recExecuteBlock() {
-       execute();
-}
-
-static void recClear(u32 Addr, u32 Size) {
-       memset((void*)PC_REC(Addr), 0, Size * 4);
-}
-
-static void recNULL() {
-//     SysMessage("recUNK: %8.8x\n", psxRegs.code);
-}
-
-/*********************************************************
-* goes to opcodes tables...                              *
-* Format:  table[something....]                          *
-*********************************************************/
-
-//REC_SYS(SPECIAL);
-static void recSPECIAL() {
-       recSPC[_Funct_]();
-}
-
-static void recREGIMM() {
-       recREG[_Rt_]();
-}
-
-static void recCOP0() {
-       recCP0[_Rs_]();
-}
-
-//REC_SYS(COP2);
-static void recCOP2() {
-       recCP2[_Funct_]();
-}
-
-static void recBASIC() {
-       recCP2BSC[_Rs_]();
-}
-
-//end of Tables opcodes...
-
-#pragma mark - Arithmetic with immediate operand -
-/*********************************************************
-* Arithmetic with immediate operand                      *
-* Format:  OP rt, rs, immediate                          *
-*********************************************************/
-
-#if 0
-/*REC_FUNC(ADDI);
-REC_FUNC(ADDIU);
-REC_FUNC(ANDI);
-REC_FUNC(ORI);
-REC_FUNC(XORI);
-REC_FUNC(SLTI);
-REC_FUNC(SLTIU);*/
-#else
-static void recADDIU()  {
-// Rt = Rs + Im
-       if (!_Rt_) return;
-
-       if (IsConst(_Rs_)) {
-               MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
-       } else {
-               if (_Imm_ == 0) {
-                       MapCopy(_Rt_, _Rs_);
-               } else {
-                       ADDI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _Imm_);
-               }
-       }
-}
-
-static void recADDI()  {
-// Rt = Rs + Im
-       recADDIU();
-}
-
-//REC_FUNC(SLTI);
-//REC_FUNC(SLTIU);
-//CR0: SIGN      | POSITIVE | ZERO  | SOVERFLOW | SOVERFLOW | OVERFLOW | CARRY
-static void recSLTI() {
-// Rt = Rs < Im (signed)
-       if (!_Rt_) return;
-
-       if (IsConst(_Rs_)) {
-               MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
-       } else {
-               if (_Imm_ == 0) {
-                       SRWI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), 31);
-               } else {
-                       int reg;
-                       CMPWI(GetHWReg32(_Rs_), _Imm_);
-                       reg = PutHWReg32(_Rt_);
-                       LI(reg, 1);
-                       BLT(1);
-                       LI(reg, 0);
-               }
-       }
-}
-
-static void recSLTIU() {
-// Rt = Rs < Im (unsigned)
-       if (!_Rt_) return;
-
-       if (IsConst(_Rs_)) {
-               MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
-       } else {
-               int reg;
-               CMPLWI(GetHWReg32(_Rs_), _Imm_);
-               reg = PutHWReg32(_Rt_);
-               LI(reg, 1);
-               BLT(1);
-               LI(reg, 0);
-       }
-}
-
-static void recANDI() {
-// Rt = Rs And Im
-    if (!_Rt_) return;
-
-    if (IsConst(_Rs_)) {
-        MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
-    } else {
-        ANDI_(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
-    }
-}
-
-static void recORI() {
-// Rt = Rs Or Im
-       if (!_Rt_) return;
-
-       if (IsConst(_Rs_)) {
-               MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
-       } else {
-               if (_Imm_ == 0) {
-                       MapCopy(_Rt_, _Rs_);
-               } else {
-                       ORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
-               }
-       }
-}
-
-static void recXORI() {
-// Rt = Rs Xor Im
-    if (!_Rt_) return;
-
-    if (IsConst(_Rs_)) {
-        MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
-    } else {
-        XORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
-    }
-}
-#endif
-//end of * Arithmetic with immediate operand  
-
-/*********************************************************
-* Load higher 16 bits of the first word in GPR with imm  *
-* Format:  OP rt, immediate                              *
-*********************************************************/
-//REC_FUNC(LUI);
-//#if 0*/
-static void recLUI()  {
-// Rt = Imm << 16
-       if (!_Rt_) return;
-
-       MapConst(_Rt_, psxRegs.code << 16);
-}
-//#endif
-//End of Load Higher .....
-
-#pragma mark - Register arithmetic -
-/*********************************************************
-* Register arithmetic                                    *
-* Format:  OP rd, rs, rt                                 *
-*********************************************************/
-
-#if 0
-/*REC_FUNC(ADD);
-REC_FUNC(ADDU);
-REC_FUNC(SUB);
-REC_FUNC(SUBU);
-REC_FUNC(AND);
-REC_FUNC(OR);
-REC_FUNC(XOR);
-REC_FUNC(NOR);
-REC_FUNC(SLT);
-REC_FUNC(SLTU);*/
-#else
-static void recADDU() {
-// Rd = Rs + Rt 
-       if (!_Rd_) return;
-
-       if (IsConst(_Rs_) && IsConst(_Rt_)) {
-               MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
-       } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-               if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
-                       ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), (s16)iRegs[_Rs_].k);
-               } else if ((iRegs[_Rs_].k & 0xffff) == 0) {
-                       ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k>>16);
-               } else {
-                       ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-       } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-               if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
-                       ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (s16)iRegs[_Rt_].k);
-               } else if ((iRegs[_Rt_].k & 0xffff) == 0) {
-                       ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k>>16);
-               } else {
-                       ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-       } else {
-               ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-       }
-}
-
-static void recADD() {
-// Rd = Rs + Rt
-       recADDU();
-}
-
-static void recSUBU() {
-// Rd = Rs - Rt
-    if (!_Rd_) return;
-
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
-    } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-        if ((s32)(s16)(-iRegs[_Rt_].k) == (s32)(-iRegs[_Rt_].k)) {
-            ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), -iRegs[_Rt_].k);
-        } else if (((-iRegs[_Rt_].k) & 0xffff) == 0) {
-            ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (-iRegs[_Rt_].k)>>16);
-        } else {
-            SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else {
-        SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-    }
-}   
-
-static void recSUB() {
-// Rd = Rs - Rt
-       recSUBU();
-}
-
-static void recAND() {
-// Rd = Rs And Rt
-    if (!_Rd_) return;
-    
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
-    } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-        // TODO: implement shifted (ANDIS) versions of these
-        if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-            ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-        } else {
-            AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-        if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-            ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
-        } else {
-            AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else {
-        AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-    }
-}   
-
-static void recOR() {
-// Rd = Rs Or Rt
-    if (!_Rd_) return;
-    
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
-    }
-    else {
-        if (_Rs_ == _Rt_) {
-            MapCopy(_Rd_, _Rs_);
-        }
-        else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-            if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-                ORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-            } else {
-                OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-            }
-        }
-        else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-            if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-                ORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
-            } else {
-                OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-            }
-        } else {
-            OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    }
-}
-
-static void recXOR() {
-// Rd = Rs Xor Rt
-    if (!_Rd_) return;
-    
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
-    } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-        if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-            XORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-        } else {
-            XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-        if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-            XORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
-        } else {
-            XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else {
-        XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-    }
-}
-
-static void recNOR() {
-// Rd = Rs Nor Rt
-    if (!_Rd_) return;
-    
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
-    } /*else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-        if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-            NORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-        } else {
-            NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-        if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-            NORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
-        } else {
-            NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        }
-    } */else {
-        NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-    }
-}
-
-static void recSLT() {
-// Rd = Rs < Rt (signed)
-    if (!_Rd_) return;
-
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
-    } else { // TODO: add immidiate cases
-        int reg;
-        CMPW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-        reg = PutHWReg32(_Rd_);
-        LI(reg, 1);
-        BLT(1);
-        LI(reg, 0);
-    }
-}
-
-static void recSLTU() { 
-// Rd = Rs < Rt (unsigned)
-    if (!_Rd_) return;
-
-    if (IsConst(_Rs_) && IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
-    } else { // TODO: add immidiate cases
-        SUBFC(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
-        SUBFE(PutHWReg32(_Rd_), GetHWReg32(_Rd_), GetHWReg32(_Rd_));
-        NEG(PutHWReg32(_Rd_), GetHWReg32(_Rd_));
-    }
-}
-#endif
-//End of * Register arithmetic
-
-#pragma mark - mult/div & Register trap logic -
-/*********************************************************
-* Register mult/div & Register trap logic                *
-* Format:  OP rs, rt                                     *
-*********************************************************/
-
-#if 0
-REC_FUNC(MULT);
-REC_FUNC(MULTU);
-REC_FUNC(DIV);
-REC_FUNC(DIVU);
-#else
-
-int DoShift(u32 k)
-{
-       u32 i;
-       for (i=0; i<30; i++) {
-               if (k == (1ul << i))
-                       return i;
-       }
-       return -1;
-}
-
-//REC_FUNC(MULT);
-
-// FIXME: doesn't work in GT - wrong way marker
-static void recMULT() {
-// Lo/Hi = Rs * Rt (signed)
-       s32 k; int r;
-       int usehi, uselo;
-       
-       if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
-               (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
-               MapConst(REG_LO, 0);
-               MapConst(REG_HI, 0);
-               return;
-       }
-       
-       if (IsConst(_Rs_) && IsConst(_Rt_)) {
-               u64 res = (s64)((s64)(s32)iRegs[_Rs_].k * (s64)(s32)iRegs[_Rt_].k);
-               MapConst(REG_LO, (res & 0xffffffff));
-               MapConst(REG_HI, ((res >> 32) & 0xffffffff));
-               return;
-       }
-       
-       if (IsConst(_Rs_)) {
-               k = (s32)iRegs[_Rs_].k;
-               r = _Rt_;
-       } else if (IsConst(_Rt_)) {
-               k = (s32)iRegs[_Rt_].k;
-               r = _Rs_;
-       } else {
-               r = -1;
-               k = 0;
-       }
-       
-       // FIXME: this should not be needed!!!
-//     uselo = isPsxRegUsed(pc, REG_LO);
-//     usehi = isPsxRegUsed(pc, REG_HI);
-       uselo = 1; //isPsxRegUsed(pc, REG_LO);
-       usehi = 1; //isPsxRegUsed(pc, REG_HI);
-
-
-       if (r != -1) {
-               int shift = DoShift(k);
-               if (shift != -1) {
-                       if (uselo) {
-                               SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift)
-                       }
-                       if (usehi) {
-                               SRAWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift);
-                       }
-               } else {
-                       //if ((s32)(s16)k == k) {
-                       //      MULLWI(PutHWReg32(REG_LO), GetHWReg32(r), k);
-                       //      MULHWI(PutHWReg32(REG_HI), GetHWReg32(r), k);
-                       //} else
-                       {
-                               if (uselo) {
-                                       MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                               }
-                               if (usehi) {
-                                       MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                               }
-                       }
-               }
-       } else {
-               if (uselo) {
-                       MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-               if (usehi) {
-                       MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-       }
-}
-
-static void recMULTU() {
-// Lo/Hi = Rs * Rt (unsigned)
-       u32 k; int r;
-       int usehi, uselo;
-       
-       if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
-               (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
-               MapConst(REG_LO, 0);
-               MapConst(REG_HI, 0);
-               return;
-       }
-       
-       if (IsConst(_Rs_) && IsConst(_Rt_)) {
-               u64 res = (u64)((u64)(u32)iRegs[_Rs_].k * (u64)(u32)iRegs[_Rt_].k);
-               MapConst(REG_LO, (res & 0xffffffff));
-               MapConst(REG_HI, ((res >> 32) & 0xffffffff));
-               return;
-       }
-       
-       if (IsConst(_Rs_)) {
-               k = (s32)iRegs[_Rs_].k;
-               r = _Rt_;
-       } else if (IsConst(_Rt_)) {
-               k = (s32)iRegs[_Rt_].k;
-               r = _Rs_;
-       } else {
-               r = -1;
-               k = 0;
-       }
-       
-       uselo = isPsxRegUsed(pc, REG_LO);
-       usehi = isPsxRegUsed(pc, REG_HI);
-
-       if (r != -1) {
-               int shift = DoShift(k);
-               if (shift != -1) {
-                       if (uselo) {
-                               SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift);
-                       }
-                       if (usehi) {
-                               SRWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift);
-                       }
-               } else {
-                       {
-                               if (uselo) {
-                                       MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                               }
-                               if (usehi) {
-                                       MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                               }
-                       }
-               }
-       } else {
-               if (uselo) {
-                       MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-               if (usehi) {
-                       MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-       }
-}
-
-static void recDIV() {
-// Lo/Hi = Rs / Rt (signed)
-       int usehi;
-
-       if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) {
-               MapConst(REG_LO, 0);
-               MapConst(REG_HI, 0);
-               return;
-       }
-       if (IsConst(_Rt_) && IsConst(_Rs_)) {
-               MapConst(REG_LO, (s32)iRegs[_Rs_].k / (s32)iRegs[_Rt_].k);
-               MapConst(REG_HI, (s32)iRegs[_Rs_].k % (s32)iRegs[_Rt_].k);
-               return;
-       }
-       
-       usehi = isPsxRegUsed(pc, REG_HI);
-       
-       if (IsConst(_Rt_)) {
-               int shift = DoShift(iRegs[_Rt_].k);
-               if (shift != -1) {
-                       SRAWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift);
-                       ADDZE(PutHWReg32(REG_LO), GetHWReg32(REG_LO));
-                       if (usehi) {
-                               RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31);
-                       }
-               } else if (iRegs[_Rt_].k == 3) {
-                       // http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html
-                       LIS(PutHWReg32(REG_HI), 0x5555);
-                       ADDI(PutHWReg32(REG_HI), GetHWReg32(REG_HI), 0x5556);
-                       MULHW(PutHWReg32(REG_LO), GetHWReg32(REG_HI), GetHWReg32(_Rs_));
-                       SRWI(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 31);
-                       ADD(PutHWReg32(REG_LO), GetHWReg32(REG_LO), GetHWReg32(REG_HI));
-                       if (usehi) {
-                               MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), 3);
-                               SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
-                       }
-               } else {
-                       DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       if (usehi) {
-                               if ((iRegs[_Rt_].k & 0x7fff) == iRegs[_Rt_].k) {
-                                       MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), iRegs[_Rt_].k);
-                               } else {
-                                       MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_));
-                               }
-                               SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
-                       }
-               }
-       } else {
-               DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               if (usehi) {
-                       MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_));
-                       SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
-               }
-       }
-}
-
-static void recDIVU() {
-// Lo/Hi = Rs / Rt (unsigned)
-       int usehi;
-
-       if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) {
-               MapConst(REG_LO, 0);
-               MapConst(REG_HI, 0);
-               return;
-       }
-       if (IsConst(_Rt_) && IsConst(_Rs_)) {
-               MapConst(REG_LO, (u32)iRegs[_Rs_].k / (u32)iRegs[_Rt_].k);
-               MapConst(REG_HI, (u32)iRegs[_Rs_].k % (u32)iRegs[_Rt_].k);
-               return;
-       }
-       
-       usehi = isPsxRegUsed(pc, REG_HI);
-
-       if (IsConst(_Rt_)) {
-               int shift = DoShift(iRegs[_Rt_].k);
-               if (shift != -1) {
-                       SRWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift);
-                       if (usehi) {
-                               RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31);
-                       }
-               } else {
-                       DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       if (usehi) {
-                               MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO));
-                               SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
-                       }
-               }
-       } else {
-               DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               if (usehi) {
-                       MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO));
-                       SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
-               }
-       }
-}
-#endif
-//End of * Register mult/div & Register trap logic  
-
-#pragma mark - memory access -
-
-#if 0
-REC_FUNC(LB);
-REC_FUNC(LBU);
-REC_FUNC(LH);
-REC_FUNC(LHU);
-REC_FUNC(LW);
-
-REC_FUNC(SB);
-REC_FUNC(SH);
-REC_FUNC(SW);
-
-REC_FUNC(LWL);
-REC_FUNC(LWR);
-REC_FUNC(SWL);
-REC_FUNC(SWR);
-#else
-static void preMemRead()
-{
-       int rs;
-       
-       ReserveArgs(1);
-       if (_Rs_ != _Rt_) {
-               DisposeHWReg(iRegs[_Rt_].reg);
-       }
-       rs = GetHWReg32(_Rs_);
-       if (rs != 3 || _Imm_ != 0) {
-               ADDI(PutHWRegSpecial(ARG1), rs, _Imm_);
-       }
-       if (_Rs_ == _Rt_) {
-               DisposeHWReg(iRegs[_Rt_].reg);
-       }
-       InvalidateCPURegs();
-       //FlushAllHWReg();
-}
-
-static void preMemWrite(int size)
-{
-       int rs;
-       
-       ReserveArgs(2);
-       rs = GetHWReg32(_Rs_);
-       if (rs != 3 || _Imm_ != 0) {
-               ADDI(PutHWRegSpecial(ARG1), rs, _Imm_);
-       }
-       if (size == 1) {
-               RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 24, 31);
-               //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xff);
-       } else if (size == 2) {
-               RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 16, 31);
-               //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xffff);
-       } else {
-               MR(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_));
-       }
-       
-       InvalidateCPURegs();
-       //FlushAllHWReg();
-}
-
-static void recLB() {
-// Rt = mem[Rs + Im] (signed)
-       
-    /*if (IsConst(_Rs_)) {
-        u32 addr = iRegs[_Rs_].k + _Imm_;
-        int t = addr >> 16;
-    
-        if ((t & 0xfff0)  == 0xbfc0) {
-            if (!_Rt_) return;
-            // since bios is readonly it won't change
-            MapConst(_Rt_, psxRs8(addr));
-            return;
-        }
-        if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-            if (!_Rt_) return;
-                
-            addr = (u32)&psxM[addr & 0x1fffff];
-            LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
-            LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
-            EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
-            return;
-        }
-        if (t == 0x1f80 && addr < 0x1f801000) {
-            if (!_Rt_) return;
-    
-            addr = (u32)&psxH[addr & 0xfff];
-            LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
-            LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
-            EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
-            return;
-        }
-    // SysPrintf("unhandled r8 %x\n", addr);
-    }*/
-       
-       preMemRead();
-       CALLFunc((u32)psxMemRead8);
-       if (_Rt_) {
-               EXTSB(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL));
-               DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL));
-       }
-}
-
-static void recLBU() {
-// Rt = mem[Rs + Im] (unsigned)
-
-    /*if (IsConst(_Rs_)) {
-        u32 addr = iRegs[_Rs_].k + _Imm_;
-        int t = addr >> 16;
-    
-        if ((t & 0xfff0)  == 0xbfc0) {
-            if (!_Rt_) return;
-            // since bios is readonly it won't change
-            MapConst(_Rt_, psxRu8(addr));
-            return;
-        }
-        if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-            if (!_Rt_) return;
-                
-            addr = (u32)&psxM[addr & 0x1fffff];
-            LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
-            LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
-            return;
-        }
-        if (t == 0x1f80 && addr < 0x1f801000) {
-            if (!_Rt_) return;
-    
-            addr = (u32)&psxH[addr & 0xfff];
-            LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
-            LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
-            return;
-        }
-    // SysPrintf("unhandled r8 %x\n", addr);
-    }*/
-        
-       preMemRead();
-       CALLFunc((u32)psxMemRead8);
-       
-       if (_Rt_) {
-               SetDstCPUReg(3);
-               PutHWReg32(_Rt_);
-       }
-}
-
-static void recLH() {
-// Rt = mem[Rs + Im] (signed)
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-       
-               if ((t & 0xfff0)  == 0xbfc0) {
-                       if (!_Rt_) return;
-                       // since bios is readonly it won't change
-                       MapConst(_Rt_, psxRs16(addr));
-                       return;
-               }
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
-                       LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
-                       LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
-                       return;
-               }
-       //      SysPrintf("unhandled r16 %x\n", addr);
-       }
-    
-       preMemRead();
-       CALLFunc((u32)psxMemRead16);
-       if (_Rt_) {
-               EXTSH(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL));
-               DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL));
-       }
-}
-
-static void recLHU() {
-// Rt = mem[Rs + Im] (unsigned)
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-       
-               if ((t & 0xfff0) == 0xbfc0) {
-                       if (!_Rt_) return;
-                       // since bios is readonly it won't change
-                       MapConst(_Rt_, psxRu16(addr));
-                       return;
-               }
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
-                       LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
-                       LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       return;
-               }
-               if (t == 0x1f80) {
-                       if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
-                                       if (!_Rt_) return;
-                                       
-                                       ReserveArgs(1);
-                                       LIW(PutHWRegSpecial(ARG1), addr);
-                                       DisposeHWReg(iRegs[_Rt_].reg);
-                                       InvalidateCPURegs();
-                                       CALLFunc((u32)SPU_readRegister);
-                                       
-                                       SetDstCPUReg(3);
-                                       PutHWReg32(_Rt_);
-                                       return;
-                       }
-                       switch (addr) {
-                                       case 0x1f801100: case 0x1f801110: case 0x1f801120:
-                                               if (!_Rt_) return;
-                                               
-                                               ReserveArgs(1);
-                                               LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3);
-                                               DisposeHWReg(iRegs[_Rt_].reg);
-                                               InvalidateCPURegs();
-                                               CALLFunc((u32)psxRcntRcount);
-                                               
-                                               SetDstCPUReg(3);
-                                               PutHWReg32(_Rt_);
-                                               return;
-
-                                       case 0x1f801104: case 0x1f801114: case 0x1f801124:
-                                               if (!_Rt_) return;
-                                               
-                        ReserveArgs(1);
-                        LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3);
-                        DisposeHWReg(iRegs[_Rt_].reg);
-                        InvalidateCPURegs();
-                        CALLFunc((u32)psxRcntRmode);
-                        
-                        SetDstCPUReg(3);
-                        PutHWReg32(_Rt_);
-                                               return;
-       
-                                       case 0x1f801108: case 0x1f801118: case 0x1f801128:
-                                               if (!_Rt_) return;
-
-                        ReserveArgs(1);
-                        LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3);
-                        DisposeHWReg(iRegs[_Rt_].reg);
-                        InvalidateCPURegs();
-                        CALLFunc((u32)psxRcntRtarget);
-                        
-                        SetDstCPUReg(3);
-                        PutHWReg32(_Rt_);
-                                               return;
-                                       }
-               }
-       //      SysPrintf("unhandled r16u %x\n", addr);
-       }
-       
-       preMemRead();
-       CALLFunc((u32)psxMemRead16);
-       if (_Rt_) {
-               SetDstCPUReg(3);
-               PutHWReg32(_Rt_);
-       }
-}
-
-static void recLW() {
-// Rt = mem[Rs + Im] (unsigned)
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0xfff0) == 0xbfc0) {
-                       if (!_Rt_) return;
-                       // since bios is readonly it won't change
-                       MapConst(_Rt_, psxRu32(addr));
-                       return;
-               }
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
-                       LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       if (!_Rt_) return;
-
-                       LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
-                       LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                       return;
-               }
-               if (t == 0x1f80) {
-                       switch (addr) {
-                               case 0x1f801080: case 0x1f801084: case 0x1f801088: 
-                               case 0x1f801090: case 0x1f801094: case 0x1f801098: 
-                               case 0x1f8010a0: case 0x1f8010a4: case 0x1f8010a8: 
-                               case 0x1f8010b0: case 0x1f8010b4: case 0x1f8010b8: 
-                               case 0x1f8010c0: case 0x1f8010c4: case 0x1f8010c8: 
-                               case 0x1f8010d0: case 0x1f8010d4: case 0x1f8010d8: 
-                               case 0x1f8010e0: case 0x1f8010e4: case 0x1f8010e8: 
-                               case 0x1f801070: case 0x1f801074:
-                               case 0x1f8010f0: case 0x1f8010f4:
-                                       if (!_Rt_) return;
-                                       
-                                       LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xffff]);
-                                       LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
-                                       return;
-
-                               case 0x1f801810:
-                                       if (!_Rt_) return;
-
-                                       DisposeHWReg(iRegs[_Rt_].reg);
-                                       InvalidateCPURegs();
-                                       CALLFunc((u32)GPU_readData);
-                                       
-                                       SetDstCPUReg(3);
-                                       PutHWReg32(_Rt_);
-                                       return;
-
-                               case 0x1f801814:
-                                       if (!_Rt_) return;
-
-                                       DisposeHWReg(iRegs[_Rt_].reg);
-                                       InvalidateCPURegs();
-                                       CALLFunc((u32)GPU_readStatus);
-                                       
-                                       SetDstCPUReg(3);
-                                       PutHWReg32(_Rt_);
-                                       return;
-                       }
-               }
-//             SysPrintf("unhandled r32 %x\n", addr);
-       }
-
-       preMemRead();
-       CALLFunc((u32)psxMemRead32);
-       if (_Rt_) {
-               SetDstCPUReg(3);
-               PutHWReg32(_Rt_);
-       }
-}
-
-REC_FUNC(LWL);
-REC_FUNC(LWR);
-REC_FUNC(SWL);
-REC_FUNC(SWR);
-/*extern u32 LWL_MASK[4];
-extern u32 LWL_SHIFT[4];
-
-void iLWLk(u32 shift) {
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(ECX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       AND32ItoR(ECX, LWL_MASK[shift]);
-       SHL32ItoR(EAX, LWL_SHIFT[shift]);
-       OR32RtoR (EAX, ECX);
-}
-
-void recLWL() {
-// Rt = Rt Merge mem[Rs + Im]
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
-                       iLWLk(addr & 3);
-
-                       iRegs[_Rt_].state = ST_UNK;
-                       MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
-                       iLWLk(addr & 3);
-
-                       iRegs[_Rt_].state = ST_UNK;
-                       MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-                       return;
-               }
-       }
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       PUSH32R  (EAX);
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-       CALLFunc((u32)psxMemRead32);
-
-       if (_Rt_) {
-               ADD32ItoR(ESP, 4);
-               POP32R   (EDX);
-               AND32ItoR(EDX, 0x3); // shift = addr & 3;
-
-               MOV32ItoR(ECX, (u32)LWL_SHIFT);
-               MOV32RmStoR(ECX, ECX, EDX, 2);
-               SHL32CLtoR(EAX); // mem(EAX) << LWL_SHIFT[shift]
-
-               MOV32ItoR(ECX, (u32)LWL_MASK);
-               MOV32RmStoR(ECX, ECX, EDX, 2);
-               if (IsConst(_Rt_)) {
-                       MOV32ItoR(EDX, iRegs[_Rt_].k);
-               } else {
-                       MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
-               }
-               AND32RtoR(EDX, ECX); // _rRt_ & LWL_MASK[shift]
-
-               OR32RtoR(EAX, EDX);
-
-               iRegs[_Rt_].state = ST_UNK;
-               MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-       } else {
-//             ADD32ItoR(ESP, 8);
-               resp+= 8;
-       }
-}
-
-static void recLWBlock(int count) {
-       u32 *code = PSXM(pc);
-       int i, respsave;
-// Rt = mem[Rs + Im] (unsigned)
-
-//     iFlushRegs(0);
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0xfff0) == 0xbfc0) {
-                       // since bios is readonly it won't change
-                       for (i=0; i<count; i++, code++, addr+=4) {
-                               if (_fRt_(*code)) {
-                                       MapConst(_fRt_(*code), psxRu32(addr));
-                               }
-                       }
-                       return;
-               }
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       for (i=0; i<count; i++, code++, addr+=4) {
-                               if (!_fRt_(*code)) return;
-                               iRegs[_fRt_(*code)].state = ST_UNK;
-
-                               MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
-                               MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
-                       }
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       for (i=0; i<count; i++, code++, addr+=4) {
-                               if (!_fRt_(*code)) return;
-                               iRegs[_fRt_(*code)].state = ST_UNK;
-
-                               MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
-                               MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
-                       }
-                       return;
-               }
-       }
-
-       SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_));
-       iPushOfB();
-       CALLFunc((u32)psxMemPointer);
-//     ADD32ItoR(ESP, 4);
-       resp+= 4;
-
-       respsave = resp; resp = 0;
-       TEST32RtoR(EAX, EAX);
-       j32Ptr[4] = JZ32(0);
-       XOR32RtoR(ECX, ECX);
-       for (i=0; i<count; i++, code++) {
-               if (_fRt_(*code)) {
-                       iRegs[_fRt_(*code)].state = ST_UNK;
-                       
-                       MOV32RmStoR(EDX, EAX, ECX, 2);
-                       MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EDX);
-               }
-               if (i != (count-1)) INC32R(ECX);
-       }
-       j32Ptr[5] = JMP32(0);
-       x86SetJ32(j32Ptr[4]);
-       for (i=0, code = PSXM(pc); i<count; i++, code++) {
-               psxRegs.code = *code;
-               recLW();
-       }
-       ADD32ItoR(ESP, resp);
-       x86SetJ32(j32Ptr[5]);
-       resp = respsave;
-}
-
-extern u32 LWR_MASK[4];
-extern u32 LWR_SHIFT[4];
-
-void iLWRk(u32 shift) {
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(ECX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       AND32ItoR(ECX, LWR_MASK[shift]);
-       SHR32ItoR(EAX, LWR_SHIFT[shift]);
-       OR32RtoR (EAX, ECX);
-}
-
-void recLWR() {
-// Rt = Rt Merge mem[Rs + Im]
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
-                       iLWRk(addr & 3);
-
-                       iRegs[_Rt_].state = ST_UNK;
-                       MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
-                       iLWRk(addr & 3);
-
-                       iRegs[_Rt_].state = ST_UNK;
-                       MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-                       return;
-               }
-       }
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       PUSH32R  (EAX);
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-       CALLFunc((u32)psxMemRead32);
-
-       if (_Rt_) {
-               ADD32ItoR(ESP, 4);
-               POP32R   (EDX);
-               AND32ItoR(EDX, 0x3); // shift = addr & 3;
-
-               MOV32ItoR(ECX, (u32)LWR_SHIFT);
-               MOV32RmStoR(ECX, ECX, EDX, 2);
-               SHR32CLtoR(EAX); // mem(EAX) >> LWR_SHIFT[shift]
-
-               MOV32ItoR(ECX, (u32)LWR_MASK);
-               MOV32RmStoR(ECX, ECX, EDX, 2);
-
-               if (IsConst(_Rt_)) {
-                       MOV32ItoR(EDX, iRegs[_Rt_].k);
-               } else {
-                       MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
-               }
-               AND32RtoR(EDX, ECX); // _rRt_ & LWR_MASK[shift]
-
-               OR32RtoR(EAX, EDX);
-
-               iRegs[_Rt_].state = ST_UNK;
-               MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-       } else {
-//             ADD32ItoR(ESP, 8);
-               resp+= 8;
-       }
-}*/
-
-static void recSB() {
-// mem[Rs + Im] = Rt
-
-       /*if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       if (IsConst(_Rt_)) {
-                               MOV8ItoM((u32)&psxM[addr & 0x1fffff], (u8)iRegs[_Rt_].k);
-                       } else {
-                               MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
-                               MOV8RtoM((u32)&psxM[addr & 0x1fffff], EAX);
-                       }
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       if (IsConst(_Rt_)) {
-                               MOV8ItoM((u32)&psxH[addr & 0xfff], (u8)iRegs[_Rt_].k);
-                       } else {
-                               MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
-                               MOV8RtoM((u32)&psxH[addr & 0xfff], EAX);
-                       }
-                       return;
-               }
-//             SysPrintf("unhandled w8 %x\n", addr);
-       }*/
-
-       preMemWrite(1);
-       CALLFunc((u32)psxMemWrite8);
-}
-
-static void recSH() {
-// mem[Rs + Im] = Rt
-
-       /*if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       if (IsConst(_Rt_)) {
-                               MOV16ItoM((u32)&psxM[addr & 0x1fffff], (u16)iRegs[_Rt_].k);
-                       } else {
-                               MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
-                               MOV16RtoM((u32)&psxM[addr & 0x1fffff], EAX);
-                       }
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       if (IsConst(_Rt_)) {
-                               MOV16ItoM((u32)&psxH[addr & 0xfff], (u16)iRegs[_Rt_].k);
-                       } else {
-                               MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
-                               MOV16RtoM((u32)&psxH[addr & 0xfff], EAX);
-                       }
-                       return;
-               }
-               if (t == 0x1f80) {
-                       if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
-                               if (IsConst(_Rt_)) {
-                                       PUSH32I(iRegs[_Rt_].k);
-                               } else {
-                                       PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
-                               }
-                               PUSH32I  (addr);
-                               CALL32M  ((u32)&SPU_writeRegister);
-#ifndef __WIN32__
-                               resp+= 8;
-#endif
-                               return;
-                       }
-               }
-//             SysPrintf("unhandled w16 %x\n", addr);
-       }*/
-
-       preMemWrite(2);
-       CALLFunc((u32)psxMemWrite16);
-}
-
-static void recSW() {
-// mem[Rs + Im] = Rt
-       u32 *b1, *b2;
-#if 0
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       LIW(0, addr & 0x1fffff);
-                       STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0);
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       LIW(0, (u32)&psxH[addr & 0xfff]);
-                       STWBRX(GetHWReg32(_Rt_), 0, 0);
-                       return;
-               }
-               if (t == 0x1f80) {
-                       switch (addr) {
-                               case 0x1f801080: case 0x1f801084: 
-                               case 0x1f801090: case 0x1f801094: 
-                               case 0x1f8010a0: case 0x1f8010a4: 
-                               case 0x1f8010b0: case 0x1f8010b4: 
-                               case 0x1f8010c0: case 0x1f8010c4: 
-                               case 0x1f8010d0: case 0x1f8010d4: 
-                               case 0x1f8010e0: case 0x1f8010e4: 
-                               case 0x1f801074:
-                               case 0x1f8010f0:
-                                       LIW(0, (u32)&psxH[addr & 0xffff]);
-                                       STWBRX(GetHWReg32(_Rt_), 0, 0);
-                                       return;
-
-/*                             case 0x1f801810:
-                                       if (IsConst(_Rt_)) {
-                                               PUSH32I(iRegs[_Rt_].k);
-                                       } else {
-                                               PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
-                                       }
-                                       CALL32M((u32)&GPU_writeData);
-#ifndef __WIN32__
-                                       resp+= 4;
-#endif
-                                       return;
-
-                               case 0x1f801814:
-                                       if (IsConst(_Rt_)) {
-                                               PUSH32I(iRegs[_Rt_].k);
-                                       } else {
-                                               PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
-                                       }
-                                       CALL32M((u32)&GPU_writeStatus);
-#ifndef __WIN32__
-                                       resp+= 4;
-#endif*/
-                       }
-               }
-//             SysPrintf("unhandled w32 %x\n", addr);
-       }
-       
-/*     LIS(0, 0x0079 + ((_Imm_ <= 0) ? 1 : 0));
-       CMPLW(GetHWReg32(_Rs_), 0);
-       BGE_L(b1);
-       
-       //SaveContext();
-       ADDI(0, GetHWReg32(_Rs_), _Imm_);
-       RLWINM(0, GetHWReg32(_Rs_), 0, 11, 31);
-       STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0);
-       B_L(b2);
-       
-       B_DST(b1);*/
-#endif
-       preMemWrite(4);
-       CALLFunc((u32)psxMemWrite32);
-       
-       //B_DST(b2);
-}
-
-/*
-static void recSWBlock(int count) {
-       u32 *code;
-       int i, respsave;
-// mem[Rs + Im] = Rt
-
-//     iFlushRegs();
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-               code = PSXM(pc);
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       for (i=0; i<count; i++, code++, addr+=4) {
-                               if (IsConst(_fRt_(*code))) {
-                                       MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_fRt_(*code)].k);
-                               } else {
-                                       MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
-                                       MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
-                               }
-                       }
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       for (i=0; i<count; i++, code++, addr+=4) {
-                               if (!_fRt_(*code)) return;
-                               iRegs[_fRt_(*code)].state = ST_UNK;
-
-                               MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
-                               MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
-                       }
-                       return;
-               }
-       }
-
-       SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_));
-       iPushOfB();
-       CALLFunc((u32)psxMemPointer);
-//     ADD32ItoR(ESP, 4);
-       resp+= 4;
-
-       respsave = resp; resp = 0;
-       TEST32RtoR(EAX, EAX);
-       j32Ptr[4] = JZ32(0);
-       XOR32RtoR(ECX, ECX);
-       for (i=0, code = PSXM(pc); i<count; i++, code++) {
-               if (IsConst(_fRt_(*code))) {
-                       MOV32ItoR(EDX, iRegs[_fRt_(*code)].k);
-               } else {
-                       MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
-               }
-               MOV32RtoRmS(EAX, ECX, 2, EDX);
-               if (i != (count-1)) INC32R(ECX);
-       }
-       j32Ptr[5] = JMP32(0);
-       x86SetJ32(j32Ptr[4]);
-       for (i=0, code = PSXM(pc); i<count; i++, code++) {
-               psxRegs.code = *code;
-               recSW();
-       }
-       ADD32ItoR(ESP, resp);
-       x86SetJ32(j32Ptr[5]);
-       resp = respsave;
-}
-
-extern u32 SWL_MASK[4];
-extern u32 SWL_SHIFT[4];
-
-void iSWLk(u32 shift) {
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(ECX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       SHR32ItoR(ECX, SWL_SHIFT[shift]);
-       AND32ItoR(EAX, SWL_MASK[shift]);
-       OR32RtoR (EAX, ECX);
-}
-
-void recSWL() {
-// mem[Rs + Im] = Rt Merge mem[Rs + Im]
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
-                       iSWLk(addr & 3);
-                       MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
-                       iSWLk(addr & 3);
-                       MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
-                       return;
-               }
-       }
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       PUSH32R  (EAX);
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-
-       CALLFunc((u32)psxMemRead32);
-
-       ADD32ItoR(ESP, 4);
-       POP32R   (EDX);
-       AND32ItoR(EDX, 0x3); // shift = addr & 3;
-
-       MOV32ItoR(ECX, (u32)SWL_MASK);
-       MOV32RmStoR(ECX, ECX, EDX, 2);
-       AND32RtoR(EAX, ECX); // mem & SWL_MASK[shift]
-
-       MOV32ItoR(ECX, (u32)SWL_SHIFT);
-       MOV32RmStoR(ECX, ECX, EDX, 2);
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(EDX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
-
-       OR32RtoR (EAX, EDX);
-       PUSH32R  (EAX);
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-
-       CALLFunc((u32)psxMemWrite32);
-//     ADD32ItoR(ESP, 8);
-       resp+= 8;
-}
-
-extern u32 SWR_MASK[4];
-extern u32 SWR_SHIFT[4];
-
-void iSWRk(u32 shift) {
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(ECX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       SHL32ItoR(ECX, SWR_SHIFT[shift]);
-       AND32ItoR(EAX, SWR_MASK[shift]);
-       OR32RtoR (EAX, ECX);
-}
-
-void recSWR() {
-// mem[Rs + Im] = Rt Merge mem[Rs + Im]
-
-       if (IsConst(_Rs_)) {
-               u32 addr = iRegs[_Rs_].k + _Imm_;
-               int t = addr >> 16;
-
-               if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
-                       MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
-                       iSWRk(addr & 3);
-                       MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
-                       return;
-               }
-               if (t == 0x1f80 && addr < 0x1f801000) {
-                       MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
-                       iSWRk(addr & 3);
-                       MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
-                       return;
-               }
-       }
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       PUSH32R  (EAX);
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-
-       CALLFunc((u32)psxMemRead32);
-
-       ADD32ItoR(ESP, 4);
-       POP32R   (EDX);
-       AND32ItoR(EDX, 0x3); // shift = addr & 3;
-
-       MOV32ItoR(ECX, (u32)SWR_MASK);
-       MOV32RmStoR(ECX, ECX, EDX, 2);
-       AND32RtoR(EAX, ECX); // mem & SWR_MASK[shift]
-
-       MOV32ItoR(ECX, (u32)SWR_SHIFT);
-       MOV32RmStoR(ECX, ECX, EDX, 2);
-       if (IsConst(_Rt_)) {
-               MOV32ItoR(EDX, iRegs[_Rt_].k);
-       } else {
-               MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
-       }
-       SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
-
-       OR32RtoR (EAX, EDX);
-       PUSH32R  (EAX);
-
-       if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
-       else {
-               MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
-               if (_Imm_) ADD32ItoR(EAX, _Imm_);
-       }
-       AND32ItoR(EAX, ~3);
-       PUSH32R  (EAX);
-
-       CALLFunc((u32)psxMemWrite32);
-//     ADD32ItoR(ESP, 8);
-       resp+= 8;
-}*/
-#endif
-
-#if 0
-/*REC_FUNC(SLL);
-REC_FUNC(SRL);
-REC_FUNC(SRA);*/
-#else
-static void recSLL() {
-// Rd = Rt << Sa
-    if (!_Rd_) return;
-
-    if (IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
-    } else {
-        SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
-    }
-}
-
-static void recSRL() {
-// Rd = Rt >> Sa
-    if (!_Rd_) return;
-
-    if (IsConst(_Rt_)) {
-        MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
-    } else {
-        SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
-    }
-}
-
-static void recSRA() {
-// Rd = Rt >> Sa
-    if (!_Rd_) return;
-
-    if (IsConst(_Rt_)) {
-        MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
-    } else {
-        SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
-    }
-}
-#endif
-
-#pragma mark - shift ops -
-#if 0
-/*REC_FUNC(SLLV);
-REC_FUNC(SRLV);
-REC_FUNC(SRAV);*/
-#else
-static void recSLLV() {
-// Rd = Rt << Rs
-       if (!_Rd_) return;
-
-       if (IsConst(_Rt_) && IsConst(_Rs_)) {
-               MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
-       } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-               SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-       } else {
-               SLW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
-       }
-}
-
-static void recSRLV() {
-// Rd = Rt >> Rs
-       if (!_Rd_) return;
-
-       if (IsConst(_Rt_) && IsConst(_Rs_)) {
-               MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
-       } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-               SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-       } else {
-               SRW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
-       }
-}
-
-static void recSRAV() {
-// Rd = Rt >> Rs
-       if (!_Rd_) return;
-
-       if (IsConst(_Rt_) && IsConst(_Rs_)) {
-               MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
-       } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-               SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
-       } else {
-               SRAW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
-       }
-}
-#endif
-
-//REC_SYS(SYSCALL);
-//REC_SYS(BREAK);
-
-//#if 0*/
-/*int dump;*/
-static void recSYSCALL() {
-//     dump=1;
-       iFlushRegs(0);
-       
-       ReserveArgs(2);
-       LIW(PutHWRegSpecial(PSXPC), pc - 4);
-       LIW(PutHWRegSpecial(ARG1), 0x20);
-       LIW(PutHWRegSpecial(ARG2), (branch == 1 ? 1 : 0));
-       FlushAllHWReg();
-       CALLFunc ((u32)psxException);
-
-       branch = 2;
-       iRet();
-}
-
-static void recBREAK() {
-}
-//#endif
-
-#if 0
-/*REC_FUNC(MFHI);
-REC_FUNC(MTHI);
-REC_FUNC(MFLO);
-REC_FUNC(MTLO);*/
-#else
-static void recMFHI() {
-// Rd = Hi
-       if (!_Rd_) return;
-       
-       if (IsConst(REG_HI)) {
-               MapConst(_Rd_, iRegs[REG_HI].k);
-       } else {
-               MapCopy(_Rd_, REG_HI);
-       }
-}
-
-static void recMTHI() {
-// Hi = Rs
-
-       if (IsConst(_Rs_)) {
-               MapConst(REG_HI, iRegs[_Rs_].k);
-       } else {
-               MapCopy(REG_HI, _Rs_);
-       }
-}
-
-static void recMFLO() {
-// Rd = Lo
-       if (!_Rd_) return;
-
-       if (IsConst(REG_LO)) {
-               MapConst(_Rd_, iRegs[REG_LO].k);
-       } else {
-               MapCopy(_Rd_, REG_LO);
-       }
-}
-
-static void recMTLO() {
-// Lo = Rs
-
-       if (IsConst(_Rs_)) {
-               MapConst(REG_LO, iRegs[_Rs_].k);
-       } else {
-               MapCopy(REG_LO, _Rs_);
-       }
-}
-#endif
-
-#pragma mark - branch ops -
-#if 0
-/*REC_BRANCH(J);
-REC_BRANCH(JR);
-REC_BRANCH(JAL);
-REC_BRANCH(JALR);
-REC_BRANCH(BLTZ);
-REC_BRANCH(BGTZ);
-REC_BRANCH(BLTZAL);
-REC_BRANCH(BGEZAL);
-REC_BRANCH(BNE);
-REC_BRANCH(BEQ);
-REC_BRANCH(BLEZ);
-REC_BRANCH(BGEZ);*/
-#else
-static void recBLTZ() {
-// Branch if Rs < 0
-       u32 bpc = _Imm_ * 4 + pc;
-       u32 *b;
-
-       if (IsConst(_Rs_)) {
-               if ((s32)iRegs[_Rs_].k < 0) {
-                       iJump(bpc); return;
-               } else {
-                       iJump(pc+4); return;
-               }
-       }
-
-       CMPWI(GetHWReg32(_Rs_), 0);
-       BLT_L(b);
-       
-       iBranch(pc+4, 1);
-
-       B_DST(b);
-       
-       iBranch(bpc, 0);
-       pc+=4;
-}
-
-static void recBGTZ() {
-// Branch if Rs > 0
-    u32 bpc = _Imm_ * 4 + pc;
-    u32 *b;
-
-    if (IsConst(_Rs_)) {
-        if ((s32)iRegs[_Rs_].k > 0) {
-            iJump(bpc); return;
-        } else {
-            iJump(pc+4); return;
-        }
-    }
-
-    CMPWI(GetHWReg32(_Rs_), 0);
-    BGT_L(b);
-    
-    iBranch(pc+4, 1);
-
-    B_DST(b);
-
-    iBranch(bpc, 0);
-    pc+=4;
-}
-
-static void recBLTZAL() {
-// Branch if Rs < 0
-    u32 bpc = _Imm_ * 4 + pc;
-    u32 *b;
-
-    if (IsConst(_Rs_)) {
-        if ((s32)iRegs[_Rs_].k < 0) {
-            MapConst(31, pc + 4);
-
-            iJump(bpc); return;
-        } else {
-            iJump(pc+4); return;
-        }
-    }
-
-    CMPWI(GetHWReg32(_Rs_), 0);
-    BLT_L(b);
-    
-    iBranch(pc+4, 1);
-
-    B_DST(b);
-    
-    MapConst(31, pc + 4);
-
-    iBranch(bpc, 0);
-    pc+=4;
-}
-
-static void recBGEZAL() {
-// Branch if Rs >= 0
-    u32 bpc = _Imm_ * 4 + pc;
-    u32 *b;
-
-    if (IsConst(_Rs_)) {
-        if ((s32)iRegs[_Rs_].k >= 0) {
-            MapConst(31, pc + 4);
-
-            iJump(bpc); return;
-        } else {
-            iJump(pc+4); return;
-        }
-    }
-
-    CMPWI(GetHWReg32(_Rs_), 0);
-    BGE_L(b);
-    
-    iBranch(pc+4, 1);
-
-    B_DST(b);
-    
-    MapConst(31, pc + 4);
-
-    iBranch(bpc, 0);
-    pc+=4;
-}
-
-static void recJ() {
-// j target
-
-       iJump(_Target_ * 4 + (pc & 0xf0000000));
-}
-
-static void recJAL() {
-// jal target
-       MapConst(31, pc + 4);
-
-       iJump(_Target_ * 4 + (pc & 0xf0000000));
-}
-
-static void recJR() {
-// jr Rs
-
-       if (IsConst(_Rs_)) {
-               iJump(iRegs[_Rs_].k);
-               //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k);
-       } else {
-               MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_));
-               SetBranch();
-       }
-}
-
-static void recJALR() {
-// jalr Rs
-
-       if (_Rd_) {
-               MapConst(_Rd_, pc + 4);
-       }
-       
-       if (IsConst(_Rs_)) {
-               iJump(iRegs[_Rs_].k);
-               //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k);
-       } else {
-               MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_));
-               SetBranch();
-       }
-}
-
-static void recBEQ() {
-// Branch if Rs == Rt
-       u32 bpc = _Imm_ * 4 + pc;
-       u32 *b;
-
-       if (_Rs_ == _Rt_) {
-               iJump(bpc);
-       }
-       else {
-               if (IsConst(_Rs_) && IsConst(_Rt_)) {
-                       if (iRegs[_Rs_].k == iRegs[_Rt_].k) {
-                               iJump(bpc); return;
-                       } else {
-                               iJump(pc+4); return;
-                       }
-               }
-               else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-                       if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-                               CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
-                       }
-                       else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
-                               CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
-                       }
-                       else {
-                               CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       }
-               }
-               else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-                       if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-                               CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
-                       }
-                       else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
-                               CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
-                       }
-                       else {
-                               CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       }
-               }
-               else {
-                       CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-               
-               BEQ_L(b);
-               
-               iBranch(pc+4, 1);
-       
-               B_DST(b);
-               
-               iBranch(bpc, 0);
-               pc+=4;
-       }
-}
-
-static void recBNE() {
-// Branch if Rs != Rt
-       u32 bpc = _Imm_ * 4 + pc;
-       u32 *b;
-
-       if (_Rs_ == _Rt_) {
-               iJump(pc+4);
-       }
-       else {
-               if (IsConst(_Rs_) && IsConst(_Rt_)) {
-                       if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
-                               iJump(bpc); return;
-                       } else {
-                               iJump(pc+4); return;
-                       }
-               }
-               else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
-                       if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
-                               CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
-                       }
-                       else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
-                               CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
-                       }
-                       else {
-                               CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       }
-               }
-               else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
-                       if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
-                               CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
-                       }
-                       else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
-                               CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
-                       }
-                       else {
-                               CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-                       }
-               }
-               else {
-                       CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
-               }
-               
-               BNE_L(b);
-               
-               iBranch(pc+4, 1);
-       
-               B_DST(b);
-               
-               iBranch(bpc, 0);
-               pc+=4;
-       }
-}
-
-static void recBLEZ() {
-// Branch if Rs <= 0
-       u32 bpc = _Imm_ * 4 + pc;
-       u32 *b;
-
-       if (IsConst(_Rs_)) {
-               if ((s32)iRegs[_Rs_].k <= 0) {
-                       iJump(bpc); return;
-               } else {
-                       iJump(pc+4); return;
-               }
-       }
-
-       CMPWI(GetHWReg32(_Rs_), 0);
-       BLE_L(b);
-       
-       iBranch(pc+4, 1);
-
-       B_DST(b);
-       
-       iBranch(bpc, 0);
-       pc+=4;
-}
-
-static void recBGEZ() {
-// Branch if Rs >= 0
-       u32 bpc = _Imm_ * 4 + pc;
-       u32 *b;
-
-       if (IsConst(_Rs_)) {
-               if ((s32)iRegs[_Rs_].k >= 0) {
-                       iJump(bpc); return;
-               } else {
-                       iJump(pc+4); return;
-               }
-       }
-
-       CMPWI(GetHWReg32(_Rs_), 0);
-       BGE_L(b);
-       
-       iBranch(pc+4, 1);
-
-       B_DST(b);
-       
-       iBranch(bpc, 0);
-       pc+=4;
-}
-#endif
-
-#if 1
-//REC_FUNC(MFC0);
-//REC_SYS(MTC0);
-//REC_FUNC(CFC0);
-//REC_SYS(CTC0);
-REC_FUNC(RFE);
-//#else
-static void recMFC0() {
-// Rt = Cop0->Rd
-       if (!_Rt_) return;
-       
-       LWZ(PutHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
-}
-
-static void recCFC0() {
-// Rt = Cop0->Rd
-
-       recMFC0();
-}
-
-static void recMTC0() {
-// Cop0->Rd = Rt
-
-       /*if (IsConst(_Rt_)) {
-               switch (_Rd_) {
-                       case 12:
-                               MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
-                               break;
-                       case 13:
-                               MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k & ~(0xfc00));
-                               break;
-                       default:
-                               MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
-                               break;
-               }
-       } else*/ {
-               switch (_Rd_) {
-                       case 13:
-                               RLWINM(0,GetHWReg32(_Rt_),0,22,15); // & ~(0xfc00)
-                               STW(0, OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
-                               break;
-                       default:
-                               STW(GetHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
-                               break;
-               }
-       }
-
-       if (_Rd_ == 12 || _Rd_ == 13) {
-               iFlushRegs(0);
-               LIW(PutHWRegSpecial(PSXPC), (u32)pc);
-               FlushAllHWReg();
-               CALLFunc((u32)psxTestSWInts);
-               if(_Rd_ == 12) {
-                 LWZ(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS));
-                 ORIS(0, 0, 0x8000);
-                 STW(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS));
-               }
-               branch = 2;
-               iRet();
-       }
-}
-
-static void recCTC0() {
-// Cop0->Rd = Rt
-
-       recMTC0();
-}
-#else
-static void recRFE() {
-       // TODO: implement multiple temp registers or cop0 registers
-       RLWINM(t1,Status,0,0,27);
-       RLWINM(Status,Status,30,28,31);
-       OR(Status,t1,Status);
-       
-       MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
-       MOV32RtoR(ECX, EAX);
-       AND32ItoR(EAX, 0xfffffff0);
-       AND32ItoR(ECX, 0x3c);
-       SHR32ItoR(ECX, 2);
-       OR32RtoR (EAX, ECX);
-       MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX);
-       CALLFunc((u32)psxExceptionTest);
-}
-#endif
-
-#if 0
-#define CP2_FUNC(f) \
-void gte##f(); \
-static void rec##f() { \
-       iFlushRegs(0); \
-       LIW(0, (u32)psxRegs.code); \
-       STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
-       FlushAllHWReg(); \
-       CALLFunc ((u32)gte##f); \
-}
-CP2_FUNC(LWC2);
-CP2_FUNC(SWC2);
-
-#else
-#include "pGte.h"
-#endif
-//
-
-static void recHLE() {
-       iFlushRegs(0);
-       FlushAllHWReg();
-       
-       if ((psxRegs.code & 0x3ffffff) == (psxRegs.code & 0x7)) {
-               CALLFunc((u32)psxHLEt[psxRegs.code & 0x7]);
-       } else {
-               // somebody else must have written to current opcode for this to happen!!!!
-               CALLFunc((u32)psxHLEt[0]); // call dummy function
-       }
-       
-       count = (idlecyclecount + (pc - pcold) / 4 + 20) * BIAS;
-       ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
-       FlushAllHWReg();
-       CALLFunc((u32)psxBranchTest);
-       Return();
-       
-       branch = 2;
-}
-
-//
-
-static void (*recBSC[64])() = {
-       recSPECIAL, recREGIMM, recJ   , recJAL  , recBEQ , recBNE , recBLEZ, recBGTZ,
-       recADDI   , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
-       recCOP0   , recNULL  , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
-       recNULL   , recNULL  , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
-       recLB     , recLH    , recLWL , recLW   , recLBU , recLHU , recLWR , recNULL,
-       recSB     , recSH    , recSWL , recSW   , recNULL, recNULL, recSWR , recNULL,
-       recNULL   , recNULL  , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
-       recNULL   , recNULL  , recSWC2, recHLE  , recNULL, recNULL, recNULL, recNULL
-};
-
-static void (*recSPC[64])() = {
-       recSLL , recNULL, recSRL , recSRA , recSLLV   , recNULL , recSRLV, recSRAV,
-       recJR  , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
-       recMFHI, recMTHI, recMFLO, recMTLO, recNULL   , recNULL , recNULL, recNULL,
-       recMULT, recMULTU, recDIV, recDIVU, recNULL   , recNULL , recNULL, recNULL,
-       recADD , recADDU, recSUB , recSUBU, recAND    , recOR   , recXOR , recNOR ,
-       recNULL, recNULL, recSLT , recSLTU, recNULL   , recNULL , recNULL, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL   , recNULL , recNULL, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL   , recNULL , recNULL, recNULL
-};
-
-static void (*recREG[32])() = {
-       recBLTZ  , recBGEZ  , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recNULL  , recNULL  , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recNULL  , recNULL  , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
-};
-
-static void (*recCP0[32])() = {
-       recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
-};
-
-static void (*recCP2[64])() = {
-       recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00
-       recNULL , recNULL , recNULL , recNULL, recOP  , recNULL , recNULL , recNULL, // 08
-       recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10
-       recNULL , recNULL , recNULL , recNCCS, recCC  , recNULL , recNCS  , recNULL, // 18
-       recNCT  , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20
-       recSQR  , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28 
-       recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30
-       recNULL , recNULL , recNULL , recNULL, recNULL, recGPF  , recGPL  , recNCCT  // 38
-};
-
-static void (*recCP2BSC[32])() = {
-       recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
-       recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
-};
-
-static void recRecompile() {
-       //static int recCount = 0;
-       char *p;
-       u32 *ptr;
-       int i;
-       
-       cop2readypc = 0;
-       idlecyclecount = 0;
-
-       // initialize state variables
-       UniqueRegAlloc = 1;
-       HWRegUseCount = 0;
-       DstCPUReg = -1;
-       memset(HWRegisters, 0, sizeof(HWRegisters));
-       for (i=0; i<NUM_HW_REGISTERS; i++)
-               HWRegisters[i].code = cpuHWRegisters[NUM_HW_REGISTERS-i-1];
-       
-       // reserve the special psxReg register
-       HWRegisters[0].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
-       HWRegisters[0].private = PSXREGS;
-       HWRegisters[0].k = (u32)&psxRegs;
-
-       HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
-       HWRegisters[1].private = PSXMEM;
-       HWRegisters[1].k = (u32)&psxM;
-
-       // reserve the special psxRegs.cycle register
-       //HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
-       //HWRegisters[1].private = CYCLECOUNT;
-       
-       //memset(iRegs, 0, sizeof(iRegs));
-       for (i=0; i<NUM_REGISTERS; i++) {
-               iRegs[i].state = ST_UNK;
-               iRegs[i].reg = -1;
-       }
-       iRegs[0].k = 0;
-       iRegs[0].state = ST_CONST;
-       
-       /* if ppcPtr reached the mem limit reset whole mem */
-       if (((u32)ppcPtr - (u32)recMem) >= (RECMEM_SIZE - 0x10000))
-               recReset();
-
-       ppcAlign(/*32*/4);
-       ptr = ppcPtr;
-       
-       // give us write access
-       //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE);
-       
-       // tell the LUT where to find us
-       PC_REC32(psxRegs.pc) = (u32)ppcPtr;
-
-       pcold = pc = psxRegs.pc;
-       
-       //SysPrintf("RecCount: %i\n", recCount++);
-       
-       for (count=0; count<500;) {
-               p = (char *)PSXM(pc);
-               if (p == NULL) recError();
-               psxRegs.code = SWAP32(*(u32 *)p);
-/*
-               if ((psxRegs.code >> 26) == 0x23) { // LW
-                       int i;
-                       u32 code;
-
-                       for (i=1;; i++) {
-                               p = (char *)PSXM(pc+i*4);
-                               if (p == NULL) recError();
-                               code = *(u32 *)p;
-
-                               if ((code >> 26) != 0x23 ||
-                                       _fRs_(code)  != _Rs_ ||
-                                       _fImm_(code) != (_Imm_+i*4))
-                                       break;
-                       }
-                       if (i > 1) {
-                               recLWBlock(i);
-                               pc = pc + i*4; continue;
-                       }
-               }
-
-               if ((psxRegs.code >> 26) == 0x2b) { // SW
-                       int i;
-                       u32 code;
-
-                       for (i=1;; i++) {
-                               p = (char *)PSXM(pc+i*4);
-                               if (p == NULL) recError();
-                               code = *(u32 *)p;
-
-                               if ((code >> 26) != 0x2b ||
-                                       _fRs_(code)  != _Rs_ ||
-                                       _fImm_(code) != (_Imm_+i*4))
-                                       break;
-                       }
-                       if (i > 1) {
-                               recSWBlock(i);
-                               pc = pc + i*4; continue;
-                       }
-               }*/
-
-               pc+=4; count++;
-//             iFlushRegs(0); // test
-               recBSC[psxRegs.code>>26]();
-
-               if (branch) {
-                       branch = 0;
-                       //if (dump) iDumpBlock(ptr);
-                       goto done;
-               }
-       }
-
-       iFlushRegs(pc);
-       
-       LIW(PutHWRegSpecial(PSXPC), pc);
-
-       iRet();
-
-done:;
-#if 0
-       MakeDataExecutable(ptr, ((u8*)ppcPtr)-((u8*)ptr));
-#else
-       u32 a = (u32)(u8*)ptr;
-       while(a < (u32)(u8*)ppcPtr) {
-         __asm__ __volatile__("icbi 0,%0" : : "r" (a));
-         __asm__ __volatile__("dcbst 0,%0" : : "r" (a));
-         a += 4;
-       }
-       __asm__ __volatile__("sync");
-       __asm__ __volatile__("isync");
-#endif
-       
-#if 1
-       sprintf((char *)ppcPtr, "PC=%08x", pcold);
-       ppcPtr += strlen((char *)ppcPtr);
-#endif
-
-       //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ/*|PROT_WRITE*/);
-}
-
-
-R3000Acpu psxRec = {
-       recInit,
-       recReset,
-       recExecute,
-       recExecuteBlock,
-       recClear,
-       recShutdown
-};
-