Пример #1
0
 private void toolStripButton3_Click(object sender, EventArgs e)
 {
     // Initialize the OpenFileDialog to look for SPU files.
     openFileDialog1.Reset(); //resets it
     openFileDialog1.DefaultExt = "*.SPU";
     openFileDialog1.Filter     = "SPU Files|*.SPU";
     if (openFileDialog1.ShowDialog() == DialogResult.OK)//opens the dialog with OK button
     {
         spu = new SPU();
         string scriptFile = openFileDialog1.FileName;                                                                                                      //open scriptfile with name
         FileLoader.LoadScriptFile(scriptFile, spu);                                                                                                        //loads it
         spu.buildLocalStorageCommands();                                                                                                                   //the buildlocal storage function
         findKnownFunctions();                                                                                                                              //looks for known functions in folder
         toolStripButton1.Enabled = toolStripButton2.Enabled = toolStripButton4.Enabled = toolStripButton5.Enabled
                                                                                              = toolStripButton6.Enabled = toolStripButton7.Enabled = true; //enables other toolstrip items that were disable
         toolStripButton8.Enabled = false;
         updateUI();
         Emulating.Text = "Emulating";
         {
             if (Emulating.Text == "Emulating...")
             {
                 ;
             }
             {
                 MessageBox.Show("EMULATING", "EMULATING",
                                 MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
             }
         }
     }
 }
Пример #2
0
 public static void float_to_reg(SPU spu, int r, float[] d)
 {
     for (int i = 0; i < 4; i++)
     {
         spu.Register[r, i] = ConversionUtil.byteToUInt(BitConverter.GetBytes(d[i]));
     }
 }
Пример #3
0
        public static void LoadElf(string FileName, SPU spu, bool setProgramCounter)
        {
            BinaryReader br = new BinaryReader(File.OpenRead(FileName));
            // GetElfHeader
            byte[] elfMagic = new byte[4];
            br.Read(elfMagic, 0, 4);
            if (elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F)
            {
                MessageBox.Show("Elf Magic Wrong (" + FileName + ")");
                return;
            }
            br.BaseStream.Seek(0, SeekOrigin.Begin);
            byte[] eHDR = new byte[0x34];
            br.Read(eHDR, 0, eHDR.Length);
            uint phdr_offset = ConversionUtil.byteToUInt(eHDR, 0x1C);
            ushort n_phdrs = ConversionUtil.byteToUShort(eHDR, 0x2C);
            for (ushort i = 0; i < n_phdrs; i++)
            {
                int error = LoadElfPHDR(br, spu, phdr_offset, i);
                if (error == 1)
                    MessageBox.Show("Didn't Load phdr " + i + " of File " + FileName);
                else if (error == 2)
                    MessageBox.Show("Local Storage Overflow!");
            }

            if (setProgramCounter)
                spu.IP = ConversionUtil.byteToUInt(eHDR, 0x18);
            br.Close();
        }
Пример #4
0
        public void CallStackDump(SPU spu, long oldIP, long newIP)
        {
            StreamWriter fs = new StreamWriter(new FileStream("spucallstack.txt", FileMode.Append));

            string newFunc  = spu.LocalStorageCommands[(newIP) >> 2].functionName;
            string oldFunc  = spu.LocalStorageCommands[(oldIP) >> 2].functionName;
            string oldIPStr = "00000000" + oldIP.ToString("X");
            string newIPStr = "00000000" + newIP.ToString("X");

            oldIPStr = oldIPStr.Substring(oldIPStr.Length - 8);
            newIPStr = newIPStr.Substring(newIPStr.Length - 8);
            string r3Str = "";

            for (int i = 0; i < 4; i++)
            {
                uint   r3v    = spu.Register[3, 1];
                string r3vStr = "00000000" + r3v.ToString("X");
                r3vStr = r3vStr.Substring(r3vStr.Length - 8);
                if (r3Str != "")
                {
                    r3Str += ", ";
                }
                r3Str += r3v + "(0x" + r3vStr + ")";
            }
            fs.Write("'" + oldFunc + "' 0x" + oldIPStr + " -> '" + newFunc + "' 0x" + newIPStr + " --- r3:" + r3Str + "\n");

            fs.Close();
        }
Пример #5
0
 public CodeWatcher(SPU spu, formspu CodeListing)
 {
     this.spu = spu;
     this.CodeListing = CodeListing;
     ls = new LoadingScreen();
     InitializeComponent();
 }
Пример #6
0
 public void execute(SPU spu)
 {
     StreamWriter fs = new StreamWriter(new FileStream("spudumper.txt", FileMode.Append));
     switch (Command)
     {
         case "print": // print, 0x12345678, [string]
             fs.Write(Parameter[0].Replace("\\n", "\r\n"));
             break;
         case "print_r": // print_r, 0x12345678, [register]
             uint register = ParseUInt(Parameter[0], spu);
             uint registerPart = ParseUInt(Parameter[1], spu);
             fs.Write(To32BitHex(spu.Register[register, registerPart]));
             break;
         case "print_ls": // print_ls, 0x12345678, [spezial_addr], [spezial_size]
             uint addr = ParseUInt(Parameter[0], spu);
             uint size = ParseUInt(Parameter[1], spu);
             for (uint i = 0; i < size && (i + addr) < spu.LocalStorage.Length; i++)
             {
                 if ((i & 0xF) == 0x0)
                     fs.Write("0x" + To32BitHex(i + addr) + ": ");
                 fs.Write(To8BitHex(spu.LocalStorage[i + addr]) + " ");
                 if ((i & 0xF) == 0xF)
                     fs.Write("\n");
             }
             break;
         case "print_dma": // print_ls, 0x12345678, [spezial_eah], [spezial_eal], [spezial_size]
             System.Windows.Forms.MessageBox.Show("DMA Dumping not implemented yet.");
             break;
     }
     fs.Close();
 }
Пример #7
0
 public CodeWatcher(SPU spu, formspu CodeListing)
 {
     this.spu         = spu;
     this.CodeListing = CodeListing;
     ls = new LoadingScreen();
     InitializeComponent();
 }
Пример #8
0
 public static float[] reg_to_float(SPU spu, int r)
 {
     float[] d = new float[4];
     for (int i = 0; i < 4; i++)
     {
         d[i] = BitConverter.ToSingle(ConversionUtil.uintToByte(spu.Register[r, i]), 0);
     }
     return(d);
 }
Пример #9
0
 public static void byte_to_reg(SPU spu, int r, byte[] b)
 {
     int i, j;
     for (i = 0; i < 4; ++i)
     {
         spu.Register[r, i] = 0;
         for (j = 0; j < 4; ++j)
             spu.Register[r, i] |= ((uint) b[i * 4 + j]) << (24 - j*8);
     }
 }
Пример #10
0
 public static void half_to_reg(SPU spu, int r, ushort[] d)
 {
     int i, j;
     for (i = 0; i < 4; ++i)
     {
         spu.Register[r, i] = 0;
         for (j = 0; j < 2; ++j)
             spu.Register[r, i] |= ((uint)d[i * 2 + j]) << (16 - j * 16);
     }
 }
Пример #11
0
        public void Dump(SPU spu)
        {
            uint addr = (uint)spu.IP;

            if (commands.ContainsKey(addr))
            {
                foreach (SPUDumperCmd cmd in commands[addr])
                {
                    cmd.execute(spu);
                }
            }
        }
Пример #12
0
 public static void double_to_reg(SPU spu, int r, double[] d)
 {
     byte[] b;
     byte[] b2 = new byte[4];
     b     = BitConverter.GetBytes(d[0]);
     b2[0] = b[4]; b2[1] = b[5]; b2[2] = b[6]; b2[3] = b[7];
     spu.Register[r, 1] = ConversionUtil.byteToUInt(b);
     spu.Register[r, 0] = ConversionUtil.byteToUInt(b2);
     b     = BitConverter.GetBytes(d[1]);
     b2[0] = b[4]; b2[1] = b[5]; b2[2] = b[6]; b2[3] = b[7];
     spu.Register[r, 3] = ConversionUtil.byteToUInt(b);
     spu.Register[r, 2] = ConversionUtil.byteToUInt(b2);
 }
Пример #13
0
 public static void Bits_to_reg(SPU spu, int r, byte[] d)
 {
     int i, j;
     for (i = 0; i < 4; ++i)
     {
         spu.Register[r, i] = 0;
         for (j = 0; j < 32; ++j)
         {
             d[i * 32 + j] &= 0x01;
             spu.Register[r, i] |= ((uint) d[i * 32 + j]) << (31 - j);
         }
     }
 }
Пример #14
0
 public static void double_to_reg(SPU spu, int r, double[] d)
 {
     byte[] b;
     byte[] b2 = new byte[4];
     b = BitConverter.GetBytes(d[0]);
     b2[0] = b[4]; b2[1] = b[5]; b2[2] = b[6]; b2[3] = b[7];
     spu.Register[r, 1] = ConversionUtil.byteToUInt(b);
     spu.Register[r, 0] = ConversionUtil.byteToUInt(b2);
     b = BitConverter.GetBytes(d[1]);
     b2[0] = b[4]; b2[1] = b[5]; b2[2] = b[6]; b2[3] = b[7];
     spu.Register[r, 3] = ConversionUtil.byteToUInt(b);
     spu.Register[r, 2] = ConversionUtil.byteToUInt(b2);
 }
Пример #15
0
        public static void half_to_reg(SPU spu, int r, ushort[] d)
        {
            int i, j;

            for (i = 0; i < 4; ++i)
            {
                spu.Register[r, i] = 0;
                for (j = 0; j < 2; ++j)
                {
                    spu.Register[r, i] |= ((uint)d[i * 2 + j]) << (16 - j * 16);
                }
            }
        }
Пример #16
0
 public static void ls2reg(SPU spu, int r, uint addr)
 {
     addr &= SPUCommandHelper.LSLR & 0xfffffff0;
     byte[] ls = new byte[4];
     System.Array.Copy(spu.LocalStorage, addr, ls, 0, 4);
     spu.Register[r, 0] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 4, ls, 0, 4);
     spu.Register[r, 1] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 8, ls, 0, 4);
     spu.Register[r, 2] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 12, ls, 0, 4);
     spu.Register[r, 3] = ConversionUtil.byteToUInt(ls);
 }
Пример #17
0
 public static void ls2reg(SPU spu, int r, uint addr)
 {
     addr &= SPUCommandHelper.LSLR & 0xfffffff0;
     byte[] ls = new byte[4];
     System.Array.Copy(spu.LocalStorage, addr, ls, 0, 4);
     spu.Register[r, 0] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 4, ls, 0, 4);
     spu.Register[r, 1] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 8, ls, 0, 4);
     spu.Register[r, 2] = ConversionUtil.byteToUInt(ls);
     System.Array.Copy(spu.LocalStorage, addr + 12, ls, 0, 4);
     spu.Register[r, 3] = ConversionUtil.byteToUInt(ls);
 }
Пример #18
0
        public static void byte_to_reg(SPU spu, int r, byte[] b)
        {
            int i, j;

            for (i = 0; i < 4; ++i)
            {
                spu.Register[r, i] = 0;
                for (j = 0; j < 4; ++j)
                {
                    spu.Register[r, i] |= ((uint)b[i * 4 + j]) << (24 - j * 8);
                }
            }
        }
Пример #19
0
        public static void LoadBin(int lsStart, string FileName, SPU spu)
        {
            BinaryReader br = new BinaryReader(File.OpenRead(FileName));
            br.BaseStream.Seek(0, SeekOrigin.Begin);

            int len = (int) br.BaseStream.Length;
            byte[] buf = new byte[len];
            br.Read(buf, 0, len);

            for (int i = 0; i < len; i++)
                spu.LocalStorage[lsStart + i] = buf[i];

            br.Close();
        }
Пример #20
0
        public static void Bits_to_reg(SPU spu, int r, byte[] d)
        {
            int i, j;

            for (i = 0; i < 4; ++i)
            {
                spu.Register[r, i] = 0;
                for (j = 0; j < 32; ++j)
                {
                    d[i * 32 + j]      &= 0x01;
                    spu.Register[r, i] |= ((uint)d[i * 32 + j]) << (31 - j);
                }
            }
        }
Пример #21
0
        public static byte[] reg_to_byte(SPU spu, int r)
        {
            int i, j;

            byte[] b = new byte[16];
            for (i = 0; i < 4; ++i)
            {
                for (j = 0; j < 4; ++j)
                {
                    b[i * 4 + j] = (byte)((spu.Register[r, i] >> (24 - j * 8)) & 0xFF);
                }
            }
            return(b);
        }
Пример #22
0
        public static ushort[] reg_to_half(SPU spu, int r)
        {
            int i, j;

            ushort[] d = new ushort[8];
            for (i = 0; i < 4; ++i)
            {
                for (j = 0; j < 2; ++j)
                {
                    d[i * 2 + j] = (ushort)((spu.Register[r, i] >> (16 - j * 16)) & 0xFFFF);
                }
            }
            return(d);
        }
Пример #23
0
        public static byte[] reg_to_Bits(SPU spu, int r)
        {
            byte[] d = new byte[128];
            int    i, j;

            for (i = 0; i < 4; ++i)
            {
                for (j = 0; j < 32; ++j)
                {
                    d[i * 32 + j] &= 0x01;
                    d[i * 32 + j]  = (byte)((spu.Register[r, i] >> (31 - j)) & 0x01);
                }
            }
            return(d);
        }
Пример #24
0
        public static void LoadBin(int lsStart, string FileName, SPU spu)
        {
            BinaryReader br = new BinaryReader(File.OpenRead(FileName));

            br.BaseStream.Seek(0, SeekOrigin.Begin);

            int len = (int)br.BaseStream.Length;

            byte[] buf = new byte[len];
            br.Read(buf, 0, len);

            for (int i = 0; i < len; i++)
            {
                spu.LocalStorage[lsStart + i] = buf[i];
            }

            br.Close();
        }
Пример #25
0
        public static int LoadElfPHDR(BinaryReader br, SPU spu, uint phdr_offset, uint i)
        {
            byte[] phdr = new byte[0x20];
            uint offset, paddr, size;

            br.BaseStream.Seek(phdr_offset + 0x20 * i, SeekOrigin.Begin);
            br.Read(phdr, 0, phdr.Length);
            if (ConversionUtil.byteToUInt(phdr) != 1)
                return 1;
            offset = ConversionUtil.byteToUInt(phdr, 0x04);
            paddr = ConversionUtil.byteToUInt(phdr, 0x0C);
            size = ConversionUtil.byteToUInt(phdr, 0x10);

            if ((offset + size) > spu.LocalStorage.Length)
                return 2;
            br.BaseStream.Seek(offset, SeekOrigin.Begin);
            br.Read(spu.LocalStorage, (int)paddr, (int)size);
            return 0;
        }
Пример #26
0
 public uint ParseUInt(string value, SPU spu)
 {
     if (value.StartsWith("0x"))
     {
         value = value.Substring(2);
         return(Convert.ToUInt32(value, 16));
     }
     else if (value.StartsWith("0b"))
     {
         value = value.Substring(2);
         return(Convert.ToUInt32(value, 2));
     }
     else if (value.StartsWith("r["))
     {
         value = value.Substring(2, value.Length - 3);
         string[] p = value.Split(new string[] { "][" }, StringSplitOptions.RemoveEmptyEntries);
         return(spu.Register[ParseUInt(p[0], spu), ParseUInt(p[1], spu)]);
     }
     return(Convert.ToUInt32(value));
 }
Пример #27
0
 public uint ParseUInt(string value, SPU spu)
 {
     if (value.StartsWith("0x"))
     {
         value = value.Substring(2);
         return Convert.ToUInt32(value, 16);
     }
     else if (value.StartsWith("0b"))
     {
         value = value.Substring(2);
         return Convert.ToUInt32(value, 2);
     }
     else if (value.StartsWith("r["))
     {
         value = value.Substring(2, value.Length - 3);
         string[] p = value.Split(new string[] { "][" }, StringSplitOptions.RemoveEmptyEntries);
         return spu.Register[ParseUInt(p[0], spu), ParseUInt(p[1], spu)];
     }
     return Convert.ToUInt32(value);
 }
Пример #28
0
        private int findYourselfCheckDeeper(SPU spu, int foundFirstMnemonic)
        {
            int ii, iii;

            for (ii = 0, iii = foundFirstMnemonic; ii < mnemonics.Length; ii++, iii++)
            {
                while (spu.LocalStorageCommands[iii].mnemonics.StartsWith("hb") || spu.LocalStorageCommands[iii].mnemonics == "nop" || spu.LocalStorageCommands[iii].mnemonics == "lnop")
                {
                    iii++;
                }
                while (mnemonics[ii].StartsWith("hb") || mnemonics[ii] == "nop" || mnemonics[ii] == "lnop")
                {
                    ii++;
                }
                if (spu.LocalStorageCommands[iii].mnemonics != mnemonics[ii])
                {
                    return(-1);
                }
            }
            return(iii);
        }
Пример #29
0
 public void findYourself(SPU spu, LoadingScreen ls)
 {
     for (int i = 0; i < spu.LocalStorageCommands.Length; i++)
     {
         if (spu.LocalStorageCommands[i].mnemonics == mnemonics[0])
         {
             int end = findYourselfCheckDeeper(spu, i);
             if (end != -1)
             {
                 SPUDumper.Instance.FunctionFoundDump(i<<2, end<<2, name);
                 for (; i < end; i++)
                     spu.LocalStorageCommands[i].functionName = name;
             }
         }
         if ((i & 0xFF) == 0)
         {
             ls.progressBar1.Value = i;
             ls.Refresh();
         }
     }
 }
Пример #30
0
        public static void LoadElf(string FileName, SPU spu, bool setProgramCounter)
        {
            BinaryReader br = new BinaryReader(File.OpenRead(FileName));

            // GetElfHeader
            byte[] elfMagic = new byte[4];
            br.Read(elfMagic, 0, 4);
            if (elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F ||
                elfMagic[0] != 0x7F)
            {
                MessageBox.Show("Elf Magic Wrong (" + FileName + ")");
                return;
            }
            br.BaseStream.Seek(0, SeekOrigin.Begin);
            byte[] eHDR = new byte[0x34];
            br.Read(eHDR, 0, eHDR.Length);
            uint   phdr_offset = ConversionUtil.byteToUInt(eHDR, 0x1C);
            ushort n_phdrs     = ConversionUtil.byteToUShort(eHDR, 0x2C);

            for (ushort i = 0; i < n_phdrs; i++)
            {
                int error = LoadElfPHDR(br, spu, phdr_offset, i);
                if (error == 1)
                {
                    MessageBox.Show("Didn't Load phdr " + i + " of File " + FileName);
                }
                else if (error == 2)
                {
                    MessageBox.Show("Local Storage Overflow!");
                }
            }

            if (setProgramCounter)
            {
                spu.IP = ConversionUtil.byteToUInt(eHDR, 0x18);
            }
            br.Close();
        }
Пример #31
0
        public void execute(SPU spu)
        {
            StreamWriter fs = new StreamWriter(new FileStream("spudumper.txt", FileMode.Append));

            switch (Command)
            {
            case "print":     // print, 0x12345678, [string]
                fs.Write(Parameter[0].Replace("\\n", "\r\n"));
                break;

            case "print_r":     // print_r, 0x12345678, [register]
                uint register     = ParseUInt(Parameter[0], spu);
                uint registerPart = ParseUInt(Parameter[1], spu);
                fs.Write(To32BitHex(spu.Register[register, registerPart]));
                break;

            case "print_ls":     // print_ls, 0x12345678, [spezial_addr], [spezial_size]
                uint addr = ParseUInt(Parameter[0], spu);
                uint size = ParseUInt(Parameter[1], spu);
                for (uint i = 0; i < size && (i + addr) < spu.LocalStorage.Length; i++)
                {
                    if ((i & 0xF) == 0x0)
                    {
                        fs.Write("0x" + To32BitHex(i + addr) + ": ");
                    }
                    fs.Write(To8BitHex(spu.LocalStorage[i + addr]) + " ");
                    if ((i & 0xF) == 0xF)
                    {
                        fs.Write("\n");
                    }
                }
                break;

            case "print_dma":     // print_ls, 0x12345678, [spezial_eah], [spezial_eal], [spezial_size]
                System.Windows.Forms.MessageBox.Show("DMA Dumping not implemented yet.");
                break;
            }
            fs.Close();
        }
Пример #32
0
        public static void reg2ls(SPU spu, int r, uint addr)
        {
            addr &= SPUCommandHelper.LSLR & 0xfffffff0;
            byte[] r0 = ConversionUtil.uintToByte(spu.Register[r, 0]);
            byte[] r1 = ConversionUtil.uintToByte(spu.Register[r, 1]);
            byte[] r2 = ConversionUtil.uintToByte(spu.Register[r, 2]);
            byte[] r3 = ConversionUtil.uintToByte(spu.Register[r, 3]);


            for (int i = 0; i < 4; i++)
            {
                spu.LocalStorage[addr + i]      = r0[i];
                spu.LocalStorage[addr + 4 + i]  = r1[i];
                spu.LocalStorage[addr + 8 + i]  = r2[i];
                spu.LocalStorage[addr + 12 + i] = r3[i];
            }

            for (uint i = 0; i < 16; i += 4)
            {
                uint cmdI = (addr + i) >> 2;
                spu.LocalStorageCommands[cmdI] = new SPUCommand(spu.LocalStorage, (int)(cmdI << 2));
            }
        }
Пример #33
0
        public static int LoadElfPHDR(BinaryReader br, SPU spu, uint phdr_offset, uint i)
        {
            byte[] phdr = new byte[0x20];
            uint   offset, paddr, size;

            br.BaseStream.Seek(phdr_offset + 0x20 * i, SeekOrigin.Begin);
            br.Read(phdr, 0, phdr.Length);
            if (ConversionUtil.byteToUInt(phdr) != 1)
            {
                return(1);
            }
            offset = ConversionUtil.byteToUInt(phdr, 0x04);
            paddr  = ConversionUtil.byteToUInt(phdr, 0x0C);
            size   = ConversionUtil.byteToUInt(phdr, 0x10);

            if ((offset + size) > spu.LocalStorage.Length)
            {
                return(2);
            }
            br.BaseStream.Seek(offset, SeekOrigin.Begin);
            br.Read(spu.LocalStorage, (int)paddr, (int)size);
            return(0);
        }
Пример #34
0
 public void findYourself(SPU spu, LoadingScreen ls)
 {
     for (int i = 0; i < spu.LocalStorageCommands.Length; i++)
     {
         if (spu.LocalStorageCommands[i].mnemonics == mnemonics[0])
         {
             int end = findYourselfCheckDeeper(spu, i);
             if (end != -1)
             {
                 SPUDumper.Instance.FunctionFoundDump(i << 2, end << 2, name);
                 for (; i < end; i++)
                 {
                     spu.LocalStorageCommands[i].functionName = name;
                 }
             }
         }
         if ((i & 0xFF) == 0)
         {
             ls.progressBar1.Value = i;
             ls.Refresh();
         }
     }
 }
Пример #35
0
        public void CallStackDump(SPU spu, long oldIP, long newIP)
        {
            StreamWriter fs = new StreamWriter(new FileStream("spucallstack.txt", FileMode.Append));

            string newFunc = spu.LocalStorageCommands[(newIP) >> 2].functionName;
            string oldFunc = spu.LocalStorageCommands[(oldIP) >> 2].functionName;
            string oldIPStr = "00000000" + oldIP.ToString("X");
            string newIPStr = "00000000" + newIP.ToString("X");
            oldIPStr = oldIPStr.Substring(oldIPStr.Length - 8);
            newIPStr = newIPStr.Substring(newIPStr.Length - 8);
            string r3Str = "";
            for (int i = 0; i < 4; i++)
            {
                uint r3v = spu.Register[3, 1];
                string r3vStr = "00000000" + r3v.ToString("X");
                r3vStr = r3vStr.Substring(r3vStr.Length - 8);
                if (r3Str != "")
                    r3Str += ", ";
                r3Str += r3v + "(0x" + r3vStr + ")";
            }
            fs.Write("'" + oldFunc + "' 0x" + oldIPStr + " -> '" + newFunc + "' 0x" + newIPStr + " --- r3:" + r3Str + "\n");

            fs.Close();
        }
Пример #36
0
 public static double[] reg_to_double(SPU spu, int r)
 {
     byte[]   b  = new byte[4];
     byte[]   b2 = new byte[4];
     double[] d  = new double[2];
     byte[]   db = new byte[8];
     b  = ConversionUtil.uintToByte(spu.Register[r, 1]);
     b2 = ConversionUtil.uintToByte(spu.Register[r, 0]);
     for (int i = 0; i < 4; i++)
     {
         db[i]     = b[i];
         db[i + 4] = b2[i];
     }
     d[0] = BitConverter.ToDouble(db, 0);
     b    = ConversionUtil.uintToByte(spu.Register[r, 3]);
     b2   = ConversionUtil.uintToByte(spu.Register[r, 2]);
     for (int i = 0; i < 4; i++)
     {
         db[i]     = b[i];
         db[i + 4] = b2[i];
     }
     d[1] = BitConverter.ToDouble(db, 0);
     return(d);
 }
Пример #37
0
 public SPUMFC(SPU spu)
 {
     TagStat  = TagID = TagMask = LSA = EAH = EAL = Size = 0;
     this.spu = spu;
     Memory   = new Dictionary <uint, Dictionary <uint, byte> >();
 }
Пример #38
0
 private void toolStripButton3_Click(object sender, EventArgs e)
 {
     // Initialize the OpenFileDialog to look for SPU files.
     openFileDialog1.Reset(); //resets it
     openFileDialog1.DefaultExt = "*.SPU";
     openFileDialog1.Filter = "SPU Files|*.SPU";
     if (openFileDialog1.ShowDialog() == DialogResult.OK)//opens the dialog with OK button
     {
         spu = new SPU();
         string scriptFile = openFileDialog1.FileName;//open scriptfile with name
         FileLoader.LoadScriptFile(scriptFile, spu);//loads it
         spu.buildLocalStorageCommands();//the buildlocal storage function
         findKnownFunctions();//looks for known functions in folder
         toolStripButton1.Enabled = toolStripButton2.Enabled = toolStripButton4.Enabled = toolStripButton5.Enabled
             = toolStripButton6.Enabled = toolStripButton7.Enabled = true; //enables other toolstrip items that were disable
         toolStripButton8.Enabled = false;
         updateUI();
         Emulating.Text = "Emulating";
         {
             if (Emulating.Text == "Emulating...");
             {
                 MessageBox.Show("EMULATING", "EMULATING",
                 MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
             }
         }
     }
 }
Пример #39
0
        public static void reg2ls(SPU spu, int r, uint addr)
        {
            addr &= SPUCommandHelper.LSLR & 0xfffffff0;
            byte[] r0 = ConversionUtil.uintToByte(spu.Register[r, 0]);
            byte[] r1 = ConversionUtil.uintToByte(spu.Register[r, 1]);
            byte[] r2 = ConversionUtil.uintToByte(spu.Register[r, 2]);
            byte[] r3 = ConversionUtil.uintToByte(spu.Register[r, 3]);

            for(int i = 0; i < 4; i++)
            {
                spu.LocalStorage[addr + i] = r0[i];
                spu.LocalStorage[addr + 4 + i] = r1[i];
                spu.LocalStorage[addr + 8 + i] = r2[i];
                spu.LocalStorage[addr + 12 + i] = r3[i];
            }

            for(uint i = 0; i < 16; i+=4)
            {
                uint cmdI = (addr + i) >> 2;
                spu.LocalStorageCommands[cmdI] = new SPUCommand(spu.LocalStorage, (int) (cmdI << 2));
            }
        }
Пример #40
0
 public SPUMFC(SPU spu)
 {
     TagStat = TagID = TagMask = LSA = EAH = EAL = Size = 0;
     this.spu = spu;
     Memory = new Dictionary<uint, Dictionary<uint, byte>>();
 }
Пример #41
0
 public static void LoadScriptFile(string FileName, SPU spu)
 {
     StreamReader fs = new StreamReader(File.OpenRead(FileName));
     string input;
     char[] tokens = { ',' };
     while((input = fs.ReadLine()) != null)
     {
         string unModdedInput = input;
         input = input.Trim();
         input = input.Replace("\t", " ");
         input = input.Replace(" ", "");
         string inputLower = input.ToLower();
         if(input != "")
         {
             SPUDumperCmd dcmd;
             string[] token = input.Split(tokens);
             switch (token[0])
             {
                 case "r": // r,0,1,0xAFCE
                     int registerSelect = int.Parse(token[1]);
                     int registerByteSelect = int.Parse(token[2]);
                     uint valueSelect = ParseUInt(token[3]);
                     spu.Register[registerSelect, registerByteSelect] = valueSelect;
                     break;
                 case "elf": // elf,blub.elf,true
                     FileLoader.LoadElf(token[1], spu, (token.Length > 2 && token[2] == "true"));
                     break;
                 case "bin":
                     int lsStart = (int) ParseUInt(token[1]);
                     FileLoader.LoadBin(lsStart, token[2], spu);
                     break;
                 case "mfc":
                     byte[] data = FileLoader.LoadBin(token[3]);
                     uint EAH = ParseUInt(token[1]);
                     uint EAL = ParseUInt(token[2]);
                     spu.MFC.WriteMemory(EAH, EAL, data);
                     break;
                 case "ip": // ip,0x400
                     spu.IP = ParseUInt(token[1]);
                     break;
                 case "mBox": // mBox, 0x0000
                     spu.mBox.Push(ParseUInt(token[1]));
                     break;
                 case "print": // print, 0x12345678, [string]
                     string[] printToken = unModdedInput.Split(tokens, 3);
                     dcmd = new SPUDumperCmd(token[0], new string[] { printToken[2] });
                     SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                     break;
                 case "print_r": // print_r, 0x12345678, [register], [register_part]
                 case "print_ls": // print_ls, 0x12345678, [spezial_addr], [spezial_size]
                     dcmd = new SPUDumperCmd(token[0], new string[] { token[2], token[3] });
                     SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                     break;
                 case "print_dma": // print_ls, 0x12345678, [spezial_eah], [spezial_eal], [spezial_size]
                     dcmd = new SPUDumperCmd(token[0], new string[] { token[2], token[3], token[4] });
                     SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                     break;
                 case "setls":
                     byte b = (byte)ParseUInt(token[2]);
                     spu.LocalStorage[ParseUInt(token[1])] = b;
                     break;
                 case "setls32":
                     uint val = ParseUInt(token[2]);
                     uint addr = ParseUInt(token[1]);
                     byte[] bb = ConversionUtil.uintToByte(val);
                     for(int i = 0; i < 4; i++)
                         spu.LocalStorage[addr+i] = bb[i];
                     break;
             }
         }
     }
     fs.Close();
 }
Пример #42
0
        public static void LoadScriptFile(string FileName, SPU spu)
        {
            StreamReader fs = new StreamReader(File.OpenRead(FileName));
            string       input;

            char[] tokens = { ',' };
            while ((input = fs.ReadLine()) != null)
            {
                string unModdedInput = input;
                input = input.Trim();
                input = input.Replace("\t", " ");
                input = input.Replace(" ", "");
                string inputLower = input.ToLower();
                if (input != "")
                {
                    SPUDumperCmd dcmd;
                    string[]     token = input.Split(tokens);
                    switch (token[0])
                    {
                    case "r":     // r,0,1,0xAFCE
                        int  registerSelect     = int.Parse(token[1]);
                        int  registerByteSelect = int.Parse(token[2]);
                        uint valueSelect        = ParseUInt(token[3]);
                        spu.Register[registerSelect, registerByteSelect] = valueSelect;
                        break;

                    case "elf":     // elf,blub.elf,true
                        FileLoader.LoadElf(token[1], spu, (token.Length > 2 && token[2] == "true"));
                        break;

                    case "bin":
                        int lsStart = (int)ParseUInt(token[1]);
                        FileLoader.LoadBin(lsStart, token[2], spu);
                        break;

                    case "mfc":
                        byte[] data = FileLoader.LoadBin(token[3]);
                        uint   EAH  = ParseUInt(token[1]);
                        uint   EAL  = ParseUInt(token[2]);
                        spu.MFC.WriteMemory(EAH, EAL, data);
                        break;

                    case "ip":     // ip,0x400
                        spu.IP = ParseUInt(token[1]);
                        break;

                    case "mBox":     // mBox, 0x0000
                        spu.mBox.Push(ParseUInt(token[1]));
                        break;

                    case "print":     // print, 0x12345678, [string]
                        string[] printToken = unModdedInput.Split(tokens, 3);
                        dcmd = new SPUDumperCmd(token[0], new string[] { printToken[2] });
                        SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                        break;

                    case "print_r":     // print_r, 0x12345678, [register], [register_part]
                    case "print_ls":    // print_ls, 0x12345678, [spezial_addr], [spezial_size]
                        dcmd = new SPUDumperCmd(token[0], new string[] { token[2], token[3] });
                        SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                        break;

                    case "print_dma":     // print_ls, 0x12345678, [spezial_eah], [spezial_eal], [spezial_size]
                        dcmd = new SPUDumperCmd(token[0], new string[] { token[2], token[3], token[4] });
                        SPUDumper.Instance.Add(ParseUInt(token[1]), dcmd);
                        break;

                    case "setls":
                        byte b = (byte)ParseUInt(token[2]);
                        spu.LocalStorage[ParseUInt(token[1])] = b;
                        break;

                    case "setls32":
                        uint   val  = ParseUInt(token[2]);
                        uint   addr = ParseUInt(token[1]);
                        byte[] bb   = ConversionUtil.uintToByte(val);
                        for (int i = 0; i < 4; i++)
                        {
                            spu.LocalStorage[addr + i] = bb[i];
                        }
                        break;
                    }
                }
            }
            fs.Close();
        }
Пример #43
0
        public LocalStorageWatcher(SPU spu)
        {
            InitializeComponent();

            this.spu = spu;
        }
Пример #44
0
 public static ushort[] reg_to_half(SPU spu, int r)
 {
     int i, j;
     ushort[] d = new ushort[8];
     for (i = 0; i < 4; ++i)
         for (j = 0; j < 2; ++j)
             d[i * 2 + j] = (ushort)((spu.Register[r, i] >> (16 - j * 16)) & 0xFFFF);
     return d;
 }
Пример #45
0
        public int execute(SPU spu)
        {
            spu.LastIP = spu.IP;
            SPUDumper.Instance.Dump(spu);
            uint addr = 0;
            int t;
            byte[] rab, rbb, rcb, rtb;
            ushort[] rah, rbh, rch, rth;
            uint s;
            int stop = 0;
            ulong r;
            long res;
            int se;
            int b;
            byte[] raB, rbB, rcB, rtB;
            float[] raf, rbf, rcf, rtf;

            if (type == SPUOpcodeType.Special)
            {
                /* 00000000000,special,stop,stop,trap
                {
                if ((opcode & 0xFF00) == 0x2100)
                {
                u32 sel = be32(ctx->ls + ctx->pc + 4);
                u32 arg = sel & 0xFFFFFF;
                sel >>= 24;

                printf("CELL SDK __send_to_ppe(0x%04x, 0x%02x, 0x%06x);\n", opcode & 0xFF, sel, arg);
                } else
                printf("####### stop instruction reached: %08x\n", opcode);
                }

                00101000000,rr,stopd,stop,trap
                {
                printf("####### stopd instruction reached\n");
                printf("ra: %08x %08x %08x %08x\n",
                raw[0],
                raw[1],
                raw[2],
                raw[3]);
                printf("rb: %08x %08x %08x %08x\n",
                rbw[0],
                rbw[1],
                rbw[2],
                rbw[3]);
                printf("rc: %08x %08x %08x %08x\n",
                rtw[0],
                rtw[1],
                rtw[2],
                rtw[3]);
                }
                                00000001100,rr,mfspr
                                {
                                printf("########## WARNING #################\n");
                                printf(" mfspr $%d, $%d not implemented!\n", rb, rt);
                                printf("####################################\n");
                                }

                                00100001100,rr,mtspr
                                {
                                printf("########## WARNING #################\n");
                                printf(" mtspr $%d, $%d not implemented!\n", rb, rt);
                                printf("####################################\n");
                                }

                 */
                if (mnemonics == "stop")
                    stop = 1;
                return stop;
            }
            switch (mnemonics)
            {
                case "lqd":
                    addr = (uint)(idx + spu.Register[ra, 0]);
                    SPUCommandHelper.ls2reg(spu, rt, addr);
                    break;
                case "lqx":
                    addr = (uint)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                    SPUCommandHelper.ls2reg(spu, rt, addr);
                    break;
                case "lqa":
                    SPUCommandHelper.ls2reg(spu, rt, (uint) idx);
                    break;
                case "lqr":
                    SPUCommandHelper.ls2reg(spu, rt, (uint)(spu.IP + idx));
                    break;
                case "stqd":
                    SPUCommandHelper.reg2ls(spu, rt, (uint)(spu.Register[ra, 0] + idx));
                    break;
                case "stqx":
                    addr = spu.Register[ra, 0] + spu.Register[rb, 0];
                    SPUCommandHelper.reg2ls(spu, rt, addr);
                    break;
                case "stqa":
                    SPUCommandHelper.reg2ls(spu, rt, (uint) idx);
                    break;
                case "stqr":
                    SPUCommandHelper.reg2ls(spu, rt, (uint)(spu.IP + idx));
                    break;
                case "cbd":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    t = ((int)spu.Register[ra, 0] + idx) & 0xF;
                    for (int i = 0; i < 16; i++)
                        rtb[i] = (byte) ((i == t) ? 0x03 : (i | 0x10));
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "cbx":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    t = (int) ((spu.Register[ra, 0] + spu.Register[rb, 0]) & 0xF);
                    for (int i = 0; i < 16; ++i)
                        rtb[i] = (byte) ((i == t) ? 0x03 : (i | 0x10));
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "chd":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    t = (int) spu.Register[ra, 0] + idx;
                    t >>= 1;
                    t &= 7;

                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort) ((i == t) ? 0x0203 : (i * 2 * 0x0101 + 0x1011));
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "chx":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    t = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                    t >>= 1;
                    t &= 7;

                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort)((i == t) ? 0x0203 : (i * 2 * 0x0101 + 0x1011));
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "cwd":
                    t = (int) (spu.Register[ra, 0] + idx);
                    t >>= 2;
                    t &= 3;
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (0x01010101 * (i * 4) + 0x10111213));
                    break;
                case "cwx":
                    t = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                    t >>= 2;
                    t &= 3;
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (0x01010101 * (i * 4) + 0x10111213));
                    break;
                case "cdd":
                    t = (int) (spu.Register[ra, 0] + idx);
                    t >>= 2;
                    t &= 2;
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint) ((i == t) ? 0x00010203 : (i == (t + 1)) ? 0x04050607 : (0x01010101 * (i * 4) + 0x10111213));
                    break;
                case "cdx":
                    t = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                    t >>= 2;
                    t &= 2;
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (i == (t + 1)) ? 0x04050607 : (0x01010101 * (i * 4) + 0x10111213));
                    break;
                case "ilh":
                    s = (uint) ((idx << 16) | idx);
                    spu.Register[rt, 0] = s;
                    spu.Register[rt, 1] = s;
                    spu.Register[rt, 2] = s;
                    spu.Register[rt, 3] = s;
                    break;
                case "ilhu":
                    s = (uint)(idx << 16);
                    spu.Register[rt, 0] = s;
                    spu.Register[rt, 1] = s;
                    spu.Register[rt, 2] = s;
                    spu.Register[rt, 3] = s;
                    break;
                case "il":
                case "ila":
                    spu.Register[rt, 0] = (uint)idx;
                    spu.Register[rt, 1] = (uint)idx;
                    spu.Register[rt, 2] = (uint)idx;
                    spu.Register[rt, 3] = (uint)idx;
                    break;
                case "iohl":
                    spu.Register[rt, 0] |= (uint)idx;
                    spu.Register[rt, 1] |= (uint)idx;
                    spu.Register[rt, 2] |= (uint)idx;
                    spu.Register[rt, 3] |= (uint)idx;
                    break;
                case "fsmbi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    for (int i = 0; i < 16; ++i)
                        rtb[i] = (byte) (((idx & (1 << (15 - i))) != 0) ? 0xFF : 0x00);
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "hequi":
                    if (idx == spu.Register[ra, 0])
                        stop = 1;
                    break;
                case "bra":
                    spu.IP = idx - 4;
                    break;
                case "br":
                    spu.IP += idx - 4;
                    break;
                case "brz":
                    if (spu.Register[rt, 0] == 0)
                        spu.IP += idx - 4;
                    break;
                case "brnz":
                    if (spu.Register[rt, 0] != 0)
                        spu.IP += idx - 4;
                    break;
                case "bisl":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = 0;
                    spu.Register[rt, 0] = (uint) (spu.IP + 4);
                    spu.IP = spu.Register[ra, 0] - 4;
                    break;
                case "brsl":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = 0;
                    spu.Register[rt, 0] = (uint)(spu.IP + 4);
                    spu.IP += idx - 4;
                    break;
                case "brasl":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = 0;
                    spu.Register[rt, 0] = (uint)(spu.IP + 4);
                    spu.IP = idx - 4;
                    break;
                case "bihnz":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    if (rth[1] != 0)
                        spu.IP = (spu.Register[ra, 0] << 2) - 4;
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "bihz":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    if (rth[1] == 0)
                        spu.IP = (spu.Register[ra, 0] << 2) - 4;
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "brhnz":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    if (rth[1] != 0)
                        spu.IP += idx - 4;
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "brhz":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    if (rth[1] == 0)
                        spu.IP += idx - 4;
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "bi":
                    spu.IP = spu.Register[ra, 0] - 4;
                    break;
                case "biz":
                    if(spu.Register[rt, 0] == 0)
                        spu.IP = spu.Register[ra, 0] - 4;
                    break;
                case "binz":
                    if (spu.Register[rt, 0] != 0)
                        spu.IP = spu.Register[ra, 0] - 4;
                    break;
                case "ah":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    rbh = SPUCommandHelper.reg_to_half(spu, rb);
                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort) (rah[i] + rbh[i]);
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "ahi":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort)(rah[i] + idx);
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "a":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = spu.Register[ra, i] + spu.Register[rb, i];
                    break;
                case "ai":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint) (spu.Register[ra, i] + idx);
                    break;
                case "sfh":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    rbh = SPUCommandHelper.reg_to_half(spu, rb);
                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort)(rbh[i] - rah[i]);
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "sfhi":
                    rth = SPUCommandHelper.reg_to_half(spu, rt);
                    rah = SPUCommandHelper.reg_to_half(spu, ra);
                    for (int i = 0; i < 8; ++i)
                        rth[i] = (ushort)(idx - rah[i]);
                    SPUCommandHelper.half_to_reg(spu, rt, rth);
                    break;
                case "sf":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = spu.Register[rb, i] - spu.Register[ra, i];
                    break;
                case "sfi":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint)(idx - spu.Register[ra, i]);
                    break;
                case "addx":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (spu.Register[rt, i] & 1) + spu.Register[ra, i] + spu.Register[rb, i];
                    break;
                case "cg":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint) (((spu.Register[ra, i] + spu.Register[rb, i]) < spu.Register[ra, i]) ? 1 : 0);
                    break;
                case "cgx":
                    for (int i = 0; i < 4; ++i)
                    {
                        r = spu.Register[ra, i] + (spu.Register[rt, i] & 1) + spu.Register[rb, i];
                        spu.Register[rt, i] = (uint)(r >> 32) & 1;
                    }
                    break;
                case "sfx":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint) (spu.Register[rb, i] - spu.Register[ra, i] - (((spu.Register[rt, i] & 1) != 0) ? 0 : 1));
                    break;
                case "bg":
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = (uint) ((spu.Register[ra, i] > spu.Register[rb, i]) ? 0 : 1);
                    break;
                case "bgx":
                    for (int i = 0; i < 4; ++i)
                    {
                        res = (long) (((ulong)spu.Register[ra, i]) - ((ulong)spu.Register[rb, i]) - (ulong)(spu.Register[rt, i] & 1));
                        spu.Register[rt, i] = (uint)((res < 0) ? 1 : 0);
                    }
                    break;
                case "mpyu":
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * (spu.Register[rb, i] & 0xFFFF));
                    }
                    break;
                case "mpyi":
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * idx);
                    }
                    break;
                case "mpyui":
                    idx &= 0xFFFF;
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * idx);
                    }
                    break;
                case "mpyh":
                    idx &= 0xFFFF;
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)(((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] & 0xFFFF)) << 16);
                    }
                    break;
                case "mpys":
                    for (int i = 0; i < 4; ++i)
                    {
                        se = (int) (((spu.Register[ra, i] & 0xFFFF) * (spu.Register[rb, i] & 0xFFFF)) >> 16);
                        se <<= 32 - 16;
                        se >>= 32 - 16;
                        spu.Register[rt, i] = (uint) se;
                    }
                    break;
                case "mpyhh":
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] >> 16));
                    }
                    break;
                case "mpyhhu":
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = (uint)((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] >> 16));
                    }
                    break;
                case "clz":
                    for (int i = 0; i < 4; ++i)
                    {
                        for (b = 0; b < 32; ++b)
                            if ((spu.Register[ra, i] & (1 << (31 - b))) != 0)
                                break;
                        spu.Register[rt, i] = (uint) b;
                    }
                    break;
                case "fsm":
                    for (int i = 0; i < 4; ++i)
                    {
                        spu.Register[rt, i] = ((spu.Register[ra, 0] & (8 >> i)) != 0) ? 0xFFFFFFFF : 0;
                    }
                    break;
                case "gbb":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    for (int i = 0; i < 16; ++i)
                        rtb[i] = 0;
                    for (int i = 0; i < 16; ++i)
                        rtb[2 + (i / 8)] |= (byte) ((rab[i]&1) << ((~i)&7));
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "gb":
                    spu.Register[rt, 0] = ((spu.Register[ra, 0] & 1) << 3) | ((spu.Register[ra, 1] & 1) << 2) | ((spu.Register[ra, 2] & 1) << 1) | (spu.Register[ra, 3] & 1);
                    spu.Register[rt, 1] = spu.Register[rt, 2] = spu.Register[rt, 3] = 0;
                    break;
                case "ori":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (uint) ((int) spu.Register[ra, i] | idx);
                    break;
                case "shlqbi":
                    rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                    raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                    int shift_count = (int) spu.Register[rb, 0] & 7;
                    for(int i = 0; i < 128; i++)
                    {
                        if(i + shift_count < 128)
                            rtB[i] = raB[i + shift_count];
                        else
                            rtB[i] = 0;
                    }
                    SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                    break;
                case "shlqbyi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    idx &= 0x1F;

                    for (int i = 0; i < 16; i++)
                        rtb[i] = (byte) ((i + idx) >= 16 ? 0 : rab[i + idx]);
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "rotqby":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    int shift = (int) (spu.Register[rb, 0] & 0xF);

                    for(int i = 0; i < 16; i++)
                        rtb[i] = rab[(i + shift) & 15];
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "ceqi":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[ra, i] == (uint) idx) ? 0xFFFFFFFF : 0x0;
                    break;
                case "ceq":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[ra, i] == spu.Register[rb, i]) ? 0xFFFFFFFF : 0x0;
                    break;
                case "ceqbi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    for(int i = 0; i < 16; i++)
                        rtb[i] = (byte) ((rab[i] == (idx & 0xFF)) ? 0xFF : 0x00);
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "xsbh":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    for (int i = 0; i < 16; i += 2)
                    {
                        rtb[i] = (byte) (((rab[i + 1] & 0x80) != 0) ? 0xFF : 0);
                        rtb[i + 1] = rab[i + 1];
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "hbra":
                case "hbrr":
                    break;
                case "shufb":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rcb = SPUCommandHelper.reg_to_byte(spu, rc);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    for (int i = 0; i < 16; i++)
                    {
                        if ((rcb[i] & 0xC0) == 0x80)
                            rtb[i] = 0;
                        else if ((rcb[i] & 0xE0) == 0xC0)
                            rtb[i] = 0xFF;
                        else if ((rcb[i] & 0xE0) == 0xE0)
                            rtb[i] = 0x80;
                        else
                        {
                            b = rcb[i] & 0x1F;
                            if (b < 16)
                                rtb[i] = rab[b];
                            else
                                rtb[i] = rbb[b-16];
                        }
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "and":
                    for (int i = 0; i < 4; i++)
                        spu.Register[rt, i] = spu.Register[ra, i] & spu.Register[rb, i];
                    break;
                case "andi":
                    for (int i = 0; i < 4; i++)
                        spu.Register[rt, i] = spu.Register[ra, i] & (uint) idx;
                    break;
                case "rchcnt":
                    for (int i = 1; i < 4; ++i)
                        spu.Register[rt, i] = 0;

                    spu.Register[rt, 0] = spu.ReadChannelCount(ra);
                    break;
                case "rdch":
                    spu.ReadChannel(ra, rt);
                    break;
                case "wrch":
                    spu.WriteChannel(ra, rt);
                    break;
                case "or": //rotqmbyi rotqbyi
                    for (int i = 0; i < 4; ++i)
                        spu.Register[rt, i] = spu.Register[ra, i] | spu.Register[rb, i];
                    break;
                case "rotqbyi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    idx &= 0x1F;

                    for(int i = 0; i < 16; i++)
                        rtb[i] = rab[(i + idx) & 15];
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "rotqmbyi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    shift_count = (-idx) & 0x1F;

                    for (int i = 0; i < 16; i++)
                    {
                        if (i >= shift_count)
                            rtb[i] = rab[i - shift_count];
                        else
                            rtb[i] = 0;
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "rotqmbybi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    shift_count = (0 - ((rbb[3]) >> 3)) & 0x1f;

                    for (int i = 0; i < 16; i++)
                    {
                        if (i >= shift_count)
                            rtb[i] = rab[i - shift_count];
                        else
                            rtb[i] = 0;
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "xswd":
                    spu.Register[rt, 0] = ((spu.Register[ra, 1] & 0x80000000) != 0) ? 0xFFFFFFFF : 0;
                    spu.Register[rt, 1] = spu.Register[ra, 1];
                    spu.Register[rt, 2] = ((spu.Register[ra, 3] & 0x80000000) != 0) ? 0xFFFFFFFF : 0;
                    spu.Register[rt, 3] = spu.Register[ra, 3];
                    break;
                case "cgti":
                    for (int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (((int)spu.Register[ra, i]) > ((int)idx)) ? 0xFFFFFFFF : 0;
                    break;
                case "clgti":
                    for (int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[ra, i] > idx) ? 0xFFFFFFFF : 0;
                    break;
                case "shlqby":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    shift = (int) (spu.Register[rb, 0] & 0x1F);

                    for(int i = 0; i < 16; i++)
                        rtb[i] = ((i+shift) < 16) ? rab[i+shift] : (byte) 0;
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "selb":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[rc, i] & spu.Register[rb, i]) | ((~spu.Register[rc, i]) & spu.Register[ra, i]);
                    break;
                case "shli":
                    shift_count = idx & 0x3F;
                    for(int i = 0; i < 4; i++)
                    {
                        if (shift_count > 31)
                            spu.Register[rt, i] = 0;
                        else
                            spu.Register[rt, i] = spu.Register[ra, i] << shift_count;
                    }
                    break;
                case "clgt":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[ra, i] > spu.Register[rb, i]) ? 0xFFFFFFFF : 0;
                    break;
                case "rotm":
                    for(int i = 0; i < 4; i++)
                    {
                        shift_count = (-(int) spu.Register[rb, i]) & 63;
                        if (shift_count < 32)
                            spu.Register[rt, i] = spu.Register[ra, i] >> shift_count;
                        else
                            spu.Register[rt, i] = 0;
                    }
                    break;
                case "nor":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = ~(spu.Register[ra, i] | spu.Register[rb, i]);
                    break;
                case "shl":
                    for(int i = 0; i < 4; i++)
                    {
                        shift_count = (int) spu.Register[rb, i] & 0x3f;
                        if (shift_count > 31)
                            spu.Register[rt, i] = 0;
                        else
                            spu.Register[rt, i] = spu.Register[ra, i] << shift_count;
                    }
                    break;
                case "rotqmby":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);
                    s = (uint) (-((int) spu.Register[rb, 0]) & 0x1F);

                    for(int i = 0; i < 16; i++)
                    {
                        if(i >= s)
                            rtb[i] = rab[i - s];
                        else
                            rtb[i] = 0;
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "andbi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);

                    for(int i = 0; i < 16; i++)
                    {
                        rtb[i] = (byte) (rab[i] & (byte)idx);
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "rotmi":
                    shift_count = (-idx) & 63;
                    for(int i = 0; i < 4; i++)
                    {
                        if(shift_count < 32)
                            spu.Register[rt, i] = spu.Register[ra, i] >> shift_count;
                        else
                            spu.Register[rt, i] = 0;
                    }
                    break;
                case "rotmai":
                    shift_count = (-idx) & 63;
                    for(int i = 0; i < 4; i++)
                    {
                        if(shift_count < 32)
                            spu.Register[rt, i] = (uint)((int)spu.Register[ra, i] >> shift_count);
                        else
                            spu.Register[rt, i] = (uint) ((int)spu.Register[ra, i] >> 31);
                    }
                    break;
                case "clgtbi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);

                    for(int i = 0; i < 16; i++)
                    {
                        rtb[i] = (rab[i] > (byte)idx) ? (byte) 0xFF : (byte) 0x00;
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "andc":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = spu.Register[ra, i] &~ spu.Register[rb, i];
                    break;
                case "xor":
                    for(int i = 0; i < 4; i++)
                    {
                        spu.Register[rt, i] = spu.Register[ra, i] ^ spu.Register[rb, i];
                    }
                    break;
                case "xorbi":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);

                    for(int i = 0; i < 16; i++)
                    {
                        rtb[i] = (byte) (rab[i] ^ (byte)idx);
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "shlqbii":
                    rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                    raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                    shift_count = idx & 7;
                    for(int i = 0; i < 128; i++)
                    {
                        if(i + shift_count < 128)
                            rtB[i] = raB[i + shift_count];
                        else
                            rtB[i] = 0;
                    }
                    SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                    break;
                case "rotqmbii":
                    rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                    raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                    shift_count = -idx & 7;
                    for(int i = 0; i < 128; i++)
                    {
                        if(i >= shift_count)
                            rtB[i] = raB[i - shift_count];
                        else
                            rtB[i] = 0;
                    }
                    SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                    break;
                case "rotqbii":
                    rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                    raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                    shift_count = idx & 7;
                    for(int i = 0; i < 128; i++)
                    {
                        rtB[i] = raB[(i + shift_count) & 127];
                    }
                    SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                    break;
                case "fms":
                    rtf = SPUCommandHelper.reg_to_float(spu, rt);
                    rcf = SPUCommandHelper.reg_to_float(spu, rc);
                    rbf = SPUCommandHelper.reg_to_float(spu, rb);
                    raf = SPUCommandHelper.reg_to_float(spu, ra);

                    for(int i = 0; i < 4; i++)
                        rtf[i] = (raf[i] * rbf[i]) - rcf[i];

                    SPUCommandHelper.float_to_reg(spu, rt, rtf);
                    break;
                case "cgt":
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (((int)spu.Register[ra, i]) > ((int)spu.Register[rb, i])) ? 0xFFFFFFFF : 0x0;
                    break;
                case "ceqb":
                    rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                    rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                    rab = SPUCommandHelper.reg_to_byte(spu, ra);

                    for(int i = 0; i < 16; i++)
                    {
                        rtb[i] = (rab[i] == rbb[i]) ? (byte) 0xFF : (byte) 0x00;
                    }
                    SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                    break;
                case "roti":
                    shift_count = idx & 0x1F;
                    for(int i = 0; i < 4; i++)
                        spu.Register[rt, i] = (spu.Register[ra, i] << shift_count) | (spu.Register[ra, i] >> (32 - shift_count));
                    break;
                case "rotqmbi":
                    rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                    raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                    shift_count = (- (int) spu.Register[rb, 0]) & 7;
                    for(int i = 0; i < 128; i++)
                    {
                        if( i >= shift_count)
                            rtB[i] = raB[i - shift_count];
                        else
                            rtB[i] = 0;
                    }
                    SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                    break;

                /*
            01010101110,rr,xshw,half
            {
            int i;
            for (i = 0; i < 8; i += 2)
            {
            rth[i] = (rah[i + 1] & 0x8000) ? 0xFFFF : 0;
            rth[i + 1] = rah[i + 1];
            }
            }

            00010101,ri10,andhi,half,signed
            {
            int i;
            for (i = 0; i < 8; ++i)
            rth[i] &= i10;
            }

            01011001001,rr,orc
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtw[i] = raw[i] |~ rbw[i];
            }

            01000100,ri10,xori,signed
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtw[i] = raw[i] ^ i10;
            }

            01001001001,rr,eqv

            # shift and rotate instruction

            00111001111,rr,shlqbybi,byte
            {
            int i;
            int shift_count = ((rbb[3])>>3) & 0x1f;

            for (i = 0; i < 16; ++i)
            {
            if ((i + shift_count) < 16)
            rtb[i] = rab[i + shift_count];
            else
            rtb[i] = 0;
            }
            }

            00001111101,ri7,rothmi,half
            {
            int shift_count = (-i7) & 31;
            int i;
            for (i = 0; i < 8; ++i)
            if (shift_count < 16)
            rth[i] = rah[i] >> shift_count;
            else
            rth[i] = 0;
            }

            000001011010,rr,rotma
            {
            int i,shift_count;
            for (i = 0; i < 4; ++i){
            shift_count = (-rbw[i]) & 63;
            if (shift_count < 32)
            rtw[i] = ((s32)raw[i]) >> shift_count;
            else
            rtw[i] = ((s32)raw[i]) >> 31;
            }
            }

            # compare, branch and halt instructions

            01111101,ri10,ceqhi,signed,half
            {
            int i;

            for (i = 0; i < 8; ++i)
            rth[i] = -(rah[i] == i10);
            }
            01111001000,rr,ceqh,half
            {
            int i;

            for (i = 0; i < 8; ++i)
            rth[i] = -(rah[i] == rbh[i]);
            }

            01011010000,rr,clgtb,byte
            {
            int i;
            for (i = 0; i < 16; ++i)
            rtb[i] = -(rab[i] > rbb[i]);
            }

            01001101,ri10,cgthi,signed,half
            {
            int i;
            for (i = 0; i < 8; ++i)
            rth[i] = -(((s16)rah[i]) > ((s16)i10));
            }

            01011101,ri10,clgthi,signed,half
            {
            int i;
            for (i = 0; i < 8; ++i)
            rth[i] = -(rah[i] > i10);
            }
            01011001000,rr,clgth,half
            {
            int i;
            for (i = 0; i < 8; ++i)
            rth[i] = -(rah[i] > rbh[i]);
            }

            01011000100,rr,fa,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = raf[i] + rbf[i];
            }
            01011000101,rr,fs,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = raf[i] - rbf[i];
            }
            01011000110,rr,fm,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = raf[i] * rbf[i];

            }
            1110,rrr,fma,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = rcf[i] + (raf[i] * rbf[i]);
            }

            1101,rrr,fnms,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = rcf[i] - (raf[i] * rbf[i]);
            }
            01011000010,rr,fcgt,float
            {
            int itrue = 0xffffffff;
            float ftrue = *(float*)&itrue;
            int i;
            for (i = 0; i < 4; ++i)
            rtf[i] = raf[i]>rbf[i]?ftrue:0.0;

            }
            01111000010,rr,fceq,float
            {
            //note: floats are not accurately modeled!
            int i;
            int itrue = 0xffffffff;
            float ftrue = *(float*)&itrue;
            for (i = 0; i < 4; ++i)
            rtf[i] = raf[i]==rbf[i]?ftrue:0.0;
            }
            00110111000,rr,frest,float
            {
            int i;
            // not quite right, but assume this is followed by a 'fi'
            for (i = 0; i < 4; ++i)
            rtf[i] = 1/raf[1];
            }
            00110111001,rr,frsqest,float
            {
            int i;
            // not quite right, but assume this is followed by a 'fi'
            for (i = 0; i < 4; ++i)
            rtf[i] = 1/sqrt(fabs(raf[i]));
            }
            01111010100,rr,fi,float
            {
            int i;
            // not quite right, but assume this was preceeded by a 'fr*est'
            for (i = 0; i < 4; ++i)
            rtf[i] = rbf[i];
            }
            01110111000,rr,fesd,float
            {
            double result = raf[0];
            float *tmp = (float*)&result;
            rtf[0] = tmp[1];
            rtf[1] = tmp[0];
            result = raf[2];
            rtf[2] = tmp[1];
            rtf[3] = tmp[0];
            }
            01110111001,rr,frds,double
            {
            double dtmp = rad[0];
            float ftmp = dtmp;
            float *ptmp = (float*)&dtmp;
            ptmp[1] = ftmp;
            ptmp[0] = 0.0;
            rtd[0]=dtmp;

            dtmp = rad[1];
            ftmp = dtmp;
            ptmp[0] = ftmp;
            ptmp[1] = 0.0;
            rtd[1] = dtmp;
            }

            0111011010,ri8,csflt,float
            {
            int i;
            for (i = 0; i < 4; ++i){
            int val = raw[i];
            // let's hope the x86s float HW does the right thing here...
            rtf[i] = (float)val;
            }
            }
            0111011000,ri8,cflts,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtw[i] = (int)raf[i];
            }
            0111011001,ri8,cfltu,float
            {
            int i;
            for (i = 0; i < 4; ++i)
            rtw[i] = (u32)raf[i];
            }
            01011001110,rr,dfm,double
            {
            rtd[0] = rad[0]*rbd[0];
            rtd[1] = rad[1]*rbd[1];
            }
            01011001101,rr,dfs,double
            {
            rtd[0] = rad[0]-rbd[0];
            rtd[1] = rad[1]-rbd[1];
            }
            01011001100,rr,dfa,double
            {
            rtd[0] = rad[0]+rbd[0];
            rtd[1] = rad[1]+rbd[1];
            }
            01101011101,rr,dfms,double
            {
            rtd[0] = (rad[0]*rbd[0])-rtd[0];
            rtd[1] = (rad[1]*rbd[1])-rtd[1];
            }
            01101011110,rr,dfnms,double
            {
            // almost same as dfms. This is missing in SPU_ISA_1.2. See v.1.1
            rtd[0] = (rad[0]*rbd[0])-rtd[0];
            rtd[1] = (rad[1]*rbd[1])-rtd[1];
            }
            01101011100,rr,dfma,double
            {
            rtd[0] = (rad[0]*rbd[0])+rtd[0];
            rtd[1] = (rad[1]*rbd[1])+rtd[1];
            }

            NOT IMPLEMENTED:
            01111000100,rr,mpy
            1100,rrr,mpya
            01101000110,rr,mpyhha
            01101001110,rr,mpyhhau
            01010110100,rr,cntb
            00110110110,rr,fsmb
            00110110101,rr,fsmh
            00110110001,rr,gbh
            00011010011,rr,avgb
            00001010011,rr,absdb
            01001010011,rr,sumb
            01000101,ri10,xorhi
            00011001001,rr,nand
            00111110000,rr,orx
            00000110,ri10,orbi
            00000101,ri10,orhi
                 */
                default:
                    System.Windows.Forms.MessageBox.Show(mnemonics + " not implemented yet!");
                    return 3;
            }
            if (spu.LastIP != spu.IP)
            {
                string newFunc = spu.LocalStorageCommands[(spu.IP + 4) >> 2].functionName;
                string oldFunc = spu.LocalStorageCommands[(spu.LastIP) >> 2].functionName;
                if (newFunc != oldFunc)
                {
                    SPUDumper.Instance.CallStackDump(spu, spu.LastIP, spu.IP + 4);
                }
            }
            return stop;
        }
Пример #46
0
 public static float[] reg_to_float(SPU spu, int r)
 {
     float[] d = new float[4];
     for (int i = 0; i < 4; i++)
         d[i] = BitConverter.ToSingle(ConversionUtil.uintToByte(spu.Register[r, i]), 0);
     return d;
 }
Пример #47
0
 public static double[] reg_to_double(SPU spu, int r)
 {
     byte[] b = new byte[4];
     byte[] b2 = new byte[4];
     double[] d = new double[2];
     byte[] db = new byte[8];
     b = ConversionUtil.uintToByte(spu.Register[r, 1]);
     b2 = ConversionUtil.uintToByte(spu.Register[r, 0]);
     for (int i = 0; i < 4; i++)
     {
         db[i] = b[i];
         db[i + 4] = b2[i];
     }
     d[0] = BitConverter.ToDouble(db, 0);
     b = ConversionUtil.uintToByte(spu.Register[r, 3]);
     b2 = ConversionUtil.uintToByte(spu.Register[r, 2]);
     for (int i = 0; i < 4; i++)
     {
         db[i] = b[i];
         db[i + 4] = b2[i];
     }
     d[1] = BitConverter.ToDouble(db, 0);
     return d;
 }
Пример #48
0
 public static byte[] reg_to_byte(SPU spu, int r)
 {
     int i, j;
     byte[] b = new byte[16];
     for (i = 0; i < 4; ++i)
         for (j = 0; j < 4; ++j)
             b[i * 4 + j] = (byte) ((spu.Register[r, i] >> (24 - j*8)) & 0xFF);
     return b;
 }
Пример #49
0
 public static byte[] reg_to_Bits(SPU spu, int r)
 {
     byte[] d = new byte[128];
     int i, j;
     for (i = 0; i < 4; ++i)
         for (j = 0; j < 32; ++j)
         {
             d[i * 32 + j] &= 0x01;
             d[i * 32 + j] = (byte) ((spu.Register[r, i] >> (31 - j)) & 0x01);
         }
     return d;
 }
Пример #50
0
        public int execute(SPU spu)
        {
            spu.LastIP = spu.IP;
            SPUDumper.Instance.Dump(spu);
            uint addr = 0;
            int  t;

            byte[]   rab, rbb, rcb, rtb;
            ushort[] rah, rbh, rch, rth;
            uint     s;
            int      stop = 0;
            ulong    r;
            long     res;
            int      se;
            int      b;

            byte[]  raB, rbB, rcB, rtB;
            float[] raf, rbf, rcf, rtf;

            if (type == SPUOpcodeType.Special)
            {
                /* 00000000000,special,stop,stop,trap
                 * {
                 * if ((opcode & 0xFF00) == 0x2100)
                 * {
                 * u32 sel = be32(ctx->ls + ctx->pc + 4);
                 * u32 arg = sel & 0xFFFFFF;
                 * sel >>= 24;
                 *
                 * printf("CELL SDK __send_to_ppe(0x%04x, 0x%02x, 0x%06x);\n", opcode & 0xFF, sel, arg);
                 * } else
                 * printf("####### stop instruction reached: %08x\n", opcode);
                 * }
                 *
                 *
                 * 00101000000,rr,stopd,stop,trap
                 * {
                 * printf("####### stopd instruction reached\n");
                 * printf("ra: %08x %08x %08x %08x\n",
                 * raw[0],
                 * raw[1],
                 * raw[2],
                 * raw[3]);
                 * printf("rb: %08x %08x %08x %08x\n",
                 * rbw[0],
                 * rbw[1],
                 * rbw[2],
                 * rbw[3]);
                 * printf("rc: %08x %08x %08x %08x\n",
                 * rtw[0],
                 * rtw[1],
                 * rtw[2],
                 * rtw[3]);
                 * }
                 *              00000001100,rr,mfspr
                 *              {
                 *              printf("########## WARNING #################\n");
                 *              printf(" mfspr $%d, $%d not implemented!\n", rb, rt);
                 *              printf("####################################\n");
                 *              }
                 *
                 *              00100001100,rr,mtspr
                 *              {
                 *              printf("########## WARNING #################\n");
                 *              printf(" mtspr $%d, $%d not implemented!\n", rb, rt);
                 *              printf("####################################\n");
                 *              }
                 *
                 */
                if (mnemonics == "stop")
                {
                    stop = 1;
                }
                return(stop);
            }
            switch (mnemonics)
            {
            case "lqd":
                addr = (uint)(idx + spu.Register[ra, 0]);
                SPUCommandHelper.ls2reg(spu, rt, addr);
                break;

            case "lqx":
                addr = (uint)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                SPUCommandHelper.ls2reg(spu, rt, addr);
                break;

            case "lqa":
                SPUCommandHelper.ls2reg(spu, rt, (uint)idx);
                break;

            case "lqr":
                SPUCommandHelper.ls2reg(spu, rt, (uint)(spu.IP + idx));
                break;

            case "stqd":
                SPUCommandHelper.reg2ls(spu, rt, (uint)(spu.Register[ra, 0] + idx));
                break;

            case "stqx":
                addr = spu.Register[ra, 0] + spu.Register[rb, 0];
                SPUCommandHelper.reg2ls(spu, rt, addr);
                break;

            case "stqa":
                SPUCommandHelper.reg2ls(spu, rt, (uint)idx);
                break;

            case "stqr":
                SPUCommandHelper.reg2ls(spu, rt, (uint)(spu.IP + idx));
                break;

            case "cbd":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                t   = ((int)spu.Register[ra, 0] + idx) & 0xF;
                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (byte)((i == t) ? 0x03 : (i | 0x10));
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "cbx":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                t   = (int)((spu.Register[ra, 0] + spu.Register[rb, 0]) & 0xF);
                for (int i = 0; i < 16; ++i)
                {
                    rtb[i] = (byte)((i == t) ? 0x03 : (i | 0x10));
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "chd":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                t   = (int)spu.Register[ra, 0] + idx;
                t >>= 1;
                t  &= 7;

                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)((i == t) ? 0x0203 : (i * 2 * 0x0101 + 0x1011));
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "chx":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                t   = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                t >>= 1;
                t  &= 7;

                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)((i == t) ? 0x0203 : (i * 2 * 0x0101 + 0x1011));
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "cwd":
                t   = (int)(spu.Register[ra, 0] + idx);
                t >>= 2;
                t  &= 3;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (0x01010101 * (i * 4) + 0x10111213));
                }
                break;

            case "cwx":
                t   = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                t >>= 2;
                t  &= 3;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (0x01010101 * (i * 4) + 0x10111213));
                }
                break;

            case "cdd":
                t   = (int)(spu.Register[ra, 0] + idx);
                t >>= 2;
                t  &= 2;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (i == (t + 1)) ? 0x04050607 : (0x01010101 * (i * 4) + 0x10111213));
                }
                break;

            case "cdx":
                t   = (int)(spu.Register[ra, 0] + spu.Register[rb, 0]);
                t >>= 2;
                t  &= 2;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((i == t) ? 0x00010203 : (i == (t + 1)) ? 0x04050607 : (0x01010101 * (i * 4) + 0x10111213));
                }
                break;

            case "ilh":
                s = (uint)((idx << 16) | idx);
                spu.Register[rt, 0] = s;
                spu.Register[rt, 1] = s;
                spu.Register[rt, 2] = s;
                spu.Register[rt, 3] = s;
                break;

            case "ilhu":
                s = (uint)(idx << 16);
                spu.Register[rt, 0] = s;
                spu.Register[rt, 1] = s;
                spu.Register[rt, 2] = s;
                spu.Register[rt, 3] = s;
                break;

            case "il":
            case "ila":
                spu.Register[rt, 0] = (uint)idx;
                spu.Register[rt, 1] = (uint)idx;
                spu.Register[rt, 2] = (uint)idx;
                spu.Register[rt, 3] = (uint)idx;
                break;

            case "iohl":
                spu.Register[rt, 0] |= (uint)idx;
                spu.Register[rt, 1] |= (uint)idx;
                spu.Register[rt, 2] |= (uint)idx;
                spu.Register[rt, 3] |= (uint)idx;
                break;

            case "fsmbi":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                for (int i = 0; i < 16; ++i)
                {
                    rtb[i] = (byte)(((idx & (1 << (15 - i))) != 0) ? 0xFF : 0x00);
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "hequi":
                if (idx == spu.Register[ra, 0])
                {
                    stop = 1;
                }
                break;

            case "bra":
                spu.IP = idx - 4;
                break;

            case "br":
                spu.IP += idx - 4;
                break;

            case "brz":
                if (spu.Register[rt, 0] == 0)
                {
                    spu.IP += idx - 4;
                }
                break;

            case "brnz":
                if (spu.Register[rt, 0] != 0)
                {
                    spu.IP += idx - 4;
                }
                break;

            case "bisl":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = 0;
                }
                spu.Register[rt, 0] = (uint)(spu.IP + 4);
                spu.IP = spu.Register[ra, 0] - 4;
                break;

            case "brsl":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = 0;
                }
                spu.Register[rt, 0] = (uint)(spu.IP + 4);
                spu.IP += idx - 4;
                break;

            case "brasl":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = 0;
                }
                spu.Register[rt, 0] = (uint)(spu.IP + 4);
                spu.IP = idx - 4;
                break;

            case "bihnz":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                if (rth[1] != 0)
                {
                    spu.IP = (spu.Register[ra, 0] << 2) - 4;
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "bihz":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                if (rth[1] == 0)
                {
                    spu.IP = (spu.Register[ra, 0] << 2) - 4;
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "brhnz":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                if (rth[1] != 0)
                {
                    spu.IP += idx - 4;
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "brhz":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                if (rth[1] == 0)
                {
                    spu.IP += idx - 4;
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "bi":
                spu.IP = spu.Register[ra, 0] - 4;
                break;

            case "biz":
                if (spu.Register[rt, 0] == 0)
                {
                    spu.IP = spu.Register[ra, 0] - 4;
                }
                break;

            case "binz":
                if (spu.Register[rt, 0] != 0)
                {
                    spu.IP = spu.Register[ra, 0] - 4;
                }
                break;

            case "ah":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                rbh = SPUCommandHelper.reg_to_half(spu, rb);
                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)(rah[i] + rbh[i]);
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "ahi":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)(rah[i] + idx);
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "a":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] + spu.Register[rb, i];
                }
                break;

            case "ai":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)(spu.Register[ra, i] + idx);
                }
                break;

            case "sfh":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                rbh = SPUCommandHelper.reg_to_half(spu, rb);
                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)(rbh[i] - rah[i]);
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "sfhi":
                rth = SPUCommandHelper.reg_to_half(spu, rt);
                rah = SPUCommandHelper.reg_to_half(spu, ra);
                for (int i = 0; i < 8; ++i)
                {
                    rth[i] = (ushort)(idx - rah[i]);
                }
                SPUCommandHelper.half_to_reg(spu, rt, rth);
                break;

            case "sf":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = spu.Register[rb, i] - spu.Register[ra, i];
                }
                break;

            case "sfi":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)(idx - spu.Register[ra, i]);
                }
                break;

            case "addx":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (spu.Register[rt, i] & 1) + spu.Register[ra, i] + spu.Register[rb, i];
                }
                break;

            case "cg":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)(((spu.Register[ra, i] + spu.Register[rb, i]) < spu.Register[ra, i]) ? 1 : 0);
                }
                break;

            case "cgx":
                for (int i = 0; i < 4; ++i)
                {
                    r = spu.Register[ra, i] + (spu.Register[rt, i] & 1) + spu.Register[rb, i];
                    spu.Register[rt, i] = (uint)(r >> 32) & 1;
                }
                break;

            case "sfx":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)(spu.Register[rb, i] - spu.Register[ra, i] - (((spu.Register[rt, i] & 1) != 0) ? 0 : 1));
                }
                break;

            case "bg":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] > spu.Register[rb, i]) ? 0 : 1);
                }
                break;

            case "bgx":
                for (int i = 0; i < 4; ++i)
                {
                    res = (long)(((ulong)spu.Register[ra, i]) - ((ulong)spu.Register[rb, i]) - (ulong)(spu.Register[rt, i] & 1));
                    spu.Register[rt, i] = (uint)((res < 0) ? 1 : 0);
                }
                break;

            case "mpyu":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * (spu.Register[rb, i] & 0xFFFF));
                }
                break;

            case "mpyi":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * idx);
                }
                break;

            case "mpyui":
                idx &= 0xFFFF;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] & 0xFFFF) * idx);
                }
                break;

            case "mpyh":
                idx &= 0xFFFF;
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)(((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] & 0xFFFF)) << 16);
                }
                break;

            case "mpys":
                for (int i = 0; i < 4; ++i)
                {
                    se   = (int)(((spu.Register[ra, i] & 0xFFFF) * (spu.Register[rb, i] & 0xFFFF)) >> 16);
                    se <<= 32 - 16;
                    se >>= 32 - 16;
                    spu.Register[rt, i] = (uint)se;
                }
                break;

            case "mpyhh":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] >> 16));
                }
                break;

            case "mpyhhu":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = (uint)((spu.Register[ra, i] >> 16) * (spu.Register[rb, i] >> 16));
                }
                break;

            case "clz":
                for (int i = 0; i < 4; ++i)
                {
                    for (b = 0; b < 32; ++b)
                    {
                        if ((spu.Register[ra, i] & (1 << (31 - b))) != 0)
                        {
                            break;
                        }
                    }
                    spu.Register[rt, i] = (uint)b;
                }
                break;

            case "fsm":
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = ((spu.Register[ra, 0] & (8 >> i)) != 0) ? 0xFFFFFFFF : 0;
                }
                break;

            case "gbb":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                for (int i = 0; i < 16; ++i)
                {
                    rtb[i] = 0;
                }
                for (int i = 0; i < 16; ++i)
                {
                    rtb[2 + (i / 8)] |= (byte)((rab[i] & 1) << ((~i) & 7));
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "gb":
                spu.Register[rt, 0] = ((spu.Register[ra, 0] & 1) << 3) | ((spu.Register[ra, 1] & 1) << 2) | ((spu.Register[ra, 2] & 1) << 1) | (spu.Register[ra, 3] & 1);
                spu.Register[rt, 1] = spu.Register[rt, 2] = spu.Register[rt, 3] = 0;
                break;

            case "ori":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (uint)((int)spu.Register[ra, i] | idx);
                }
                break;

            case "shlqbi":
                rtB = SPUCommandHelper.reg_to_Bits(spu, rt);
                raB = SPUCommandHelper.reg_to_Bits(spu, ra);
                int shift_count = (int)spu.Register[rb, 0] & 7;
                for (int i = 0; i < 128; i++)
                {
                    if (i + shift_count < 128)
                    {
                        rtB[i] = raB[i + shift_count];
                    }
                    else
                    {
                        rtB[i] = 0;
                    }
                }
                SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                break;

            case "shlqbyi":
                rtb  = SPUCommandHelper.reg_to_byte(spu, rt);
                rab  = SPUCommandHelper.reg_to_byte(spu, ra);
                idx &= 0x1F;

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (byte)((i + idx) >= 16 ? 0 : rab[i + idx]);
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "rotqby":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                int shift = (int)(spu.Register[rb, 0] & 0xF);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = rab[(i + shift) & 15];
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "ceqi":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[ra, i] == (uint)idx) ? 0xFFFFFFFF : 0x0;
                }
                break;

            case "ceq":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[ra, i] == spu.Register[rb, i]) ? 0xFFFFFFFF : 0x0;
                }
                break;

            case "ceqbi":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (byte)((rab[i] == (idx & 0xFF)) ? 0xFF : 0x00);
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "xsbh":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                for (int i = 0; i < 16; i += 2)
                {
                    rtb[i]     = (byte)(((rab[i + 1] & 0x80) != 0) ? 0xFF : 0);
                    rtb[i + 1] = rab[i + 1];
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "hbra":
            case "hbrr":
                break;

            case "shufb":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rcb = SPUCommandHelper.reg_to_byte(spu, rc);
                rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                for (int i = 0; i < 16; i++)
                {
                    if ((rcb[i] & 0xC0) == 0x80)
                    {
                        rtb[i] = 0;
                    }
                    else if ((rcb[i] & 0xE0) == 0xC0)
                    {
                        rtb[i] = 0xFF;
                    }
                    else if ((rcb[i] & 0xE0) == 0xE0)
                    {
                        rtb[i] = 0x80;
                    }
                    else
                    {
                        b = rcb[i] & 0x1F;
                        if (b < 16)
                        {
                            rtb[i] = rab[b];
                        }
                        else
                        {
                            rtb[i] = rbb[b - 16];
                        }
                    }
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "and":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] & spu.Register[rb, i];
                }
                break;

            case "andi":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] & (uint)idx;
                }
                break;

            case "rchcnt":
                for (int i = 1; i < 4; ++i)
                {
                    spu.Register[rt, i] = 0;
                }

                spu.Register[rt, 0] = spu.ReadChannelCount(ra);
                break;

            case "rdch":
                spu.ReadChannel(ra, rt);
                break;

            case "wrch":
                spu.WriteChannel(ra, rt);
                break;

            case "or":     //rotqmbyi rotqbyi
                for (int i = 0; i < 4; ++i)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] | spu.Register[rb, i];
                }
                break;

            case "rotqbyi":
                rtb  = SPUCommandHelper.reg_to_byte(spu, rt);
                rab  = SPUCommandHelper.reg_to_byte(spu, ra);
                idx &= 0x1F;

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = rab[(i + idx) & 15];
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "rotqmbyi":
                rtb         = SPUCommandHelper.reg_to_byte(spu, rt);
                rab         = SPUCommandHelper.reg_to_byte(spu, ra);
                shift_count = (-idx) & 0x1F;

                for (int i = 0; i < 16; i++)
                {
                    if (i >= shift_count)
                    {
                        rtb[i] = rab[i - shift_count];
                    }
                    else
                    {
                        rtb[i] = 0;
                    }
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "rotqmbybi":
                rtb         = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb         = SPUCommandHelper.reg_to_byte(spu, rb);
                rab         = SPUCommandHelper.reg_to_byte(spu, ra);
                shift_count = (0 - ((rbb[3]) >> 3)) & 0x1f;

                for (int i = 0; i < 16; i++)
                {
                    if (i >= shift_count)
                    {
                        rtb[i] = rab[i - shift_count];
                    }
                    else
                    {
                        rtb[i] = 0;
                    }
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "xswd":
                spu.Register[rt, 0] = ((spu.Register[ra, 1] & 0x80000000) != 0) ? 0xFFFFFFFF : 0;
                spu.Register[rt, 1] = spu.Register[ra, 1];
                spu.Register[rt, 2] = ((spu.Register[ra, 3] & 0x80000000) != 0) ? 0xFFFFFFFF : 0;
                spu.Register[rt, 3] = spu.Register[ra, 3];
                break;

            case "cgti":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (((int)spu.Register[ra, i]) > ((int)idx)) ? 0xFFFFFFFF : 0;
                }
                break;

            case "clgti":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[ra, i] > idx) ? 0xFFFFFFFF : 0;
                }
                break;

            case "shlqby":
                rtb   = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb   = SPUCommandHelper.reg_to_byte(spu, rb);
                rab   = SPUCommandHelper.reg_to_byte(spu, ra);
                shift = (int)(spu.Register[rb, 0] & 0x1F);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = ((i + shift) < 16) ? rab[i + shift] : (byte)0;
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "selb":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[rc, i] & spu.Register[rb, i]) | ((~spu.Register[rc, i]) & spu.Register[ra, i]);
                }
                break;

            case "shli":
                shift_count = idx & 0x3F;
                for (int i = 0; i < 4; i++)
                {
                    if (shift_count > 31)
                    {
                        spu.Register[rt, i] = 0;
                    }
                    else
                    {
                        spu.Register[rt, i] = spu.Register[ra, i] << shift_count;
                    }
                }
                break;

            case "clgt":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[ra, i] > spu.Register[rb, i]) ? 0xFFFFFFFF : 0;
                }
                break;

            case "rotm":
                for (int i = 0; i < 4; i++)
                {
                    shift_count = (-(int)spu.Register[rb, i]) & 63;
                    if (shift_count < 32)
                    {
                        spu.Register[rt, i] = spu.Register[ra, i] >> shift_count;
                    }
                    else
                    {
                        spu.Register[rt, i] = 0;
                    }
                }
                break;

            case "nor":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = ~(spu.Register[ra, i] | spu.Register[rb, i]);
                }
                break;

            case "shl":
                for (int i = 0; i < 4; i++)
                {
                    shift_count = (int)spu.Register[rb, i] & 0x3f;
                    if (shift_count > 31)
                    {
                        spu.Register[rt, i] = 0;
                    }
                    else
                    {
                        spu.Register[rt, i] = spu.Register[ra, i] << shift_count;
                    }
                }
                break;

            case "rotqmby":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);
                s   = (uint)(-((int)spu.Register[rb, 0]) & 0x1F);

                for (int i = 0; i < 16; i++)
                {
                    if (i >= s)
                    {
                        rtb[i] = rab[i - s];
                    }
                    else
                    {
                        rtb[i] = 0;
                    }
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "andbi":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (byte)(rab[i] & (byte)idx);
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "rotmi":
                shift_count = (-idx) & 63;
                for (int i = 0; i < 4; i++)
                {
                    if (shift_count < 32)
                    {
                        spu.Register[rt, i] = spu.Register[ra, i] >> shift_count;
                    }
                    else
                    {
                        spu.Register[rt, i] = 0;
                    }
                }
                break;

            case "rotmai":
                shift_count = (-idx) & 63;
                for (int i = 0; i < 4; i++)
                {
                    if (shift_count < 32)
                    {
                        spu.Register[rt, i] = (uint)((int)spu.Register[ra, i] >> shift_count);
                    }
                    else
                    {
                        spu.Register[rt, i] = (uint)((int)spu.Register[ra, i] >> 31);
                    }
                }
                break;

            case "clgtbi":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (rab[i] > (byte)idx) ? (byte)0xFF : (byte)0x00;
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "andc":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] & ~spu.Register[rb, i];
                }
                break;

            case "xor":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = spu.Register[ra, i] ^ spu.Register[rb, i];
                }
                break;

            case "xorbi":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (byte)(rab[i] ^ (byte)idx);
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "shlqbii":
                rtB         = SPUCommandHelper.reg_to_Bits(spu, rt);
                raB         = SPUCommandHelper.reg_to_Bits(spu, ra);
                shift_count = idx & 7;
                for (int i = 0; i < 128; i++)
                {
                    if (i + shift_count < 128)
                    {
                        rtB[i] = raB[i + shift_count];
                    }
                    else
                    {
                        rtB[i] = 0;
                    }
                }
                SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                break;

            case "rotqmbii":
                rtB         = SPUCommandHelper.reg_to_Bits(spu, rt);
                raB         = SPUCommandHelper.reg_to_Bits(spu, ra);
                shift_count = -idx & 7;
                for (int i = 0; i < 128; i++)
                {
                    if (i >= shift_count)
                    {
                        rtB[i] = raB[i - shift_count];
                    }
                    else
                    {
                        rtB[i] = 0;
                    }
                }
                SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                break;

            case "rotqbii":
                rtB         = SPUCommandHelper.reg_to_Bits(spu, rt);
                raB         = SPUCommandHelper.reg_to_Bits(spu, ra);
                shift_count = idx & 7;
                for (int i = 0; i < 128; i++)
                {
                    rtB[i] = raB[(i + shift_count) & 127];
                }
                SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                break;

            case "fms":
                rtf = SPUCommandHelper.reg_to_float(spu, rt);
                rcf = SPUCommandHelper.reg_to_float(spu, rc);
                rbf = SPUCommandHelper.reg_to_float(spu, rb);
                raf = SPUCommandHelper.reg_to_float(spu, ra);

                for (int i = 0; i < 4; i++)
                {
                    rtf[i] = (raf[i] * rbf[i]) - rcf[i];
                }

                SPUCommandHelper.float_to_reg(spu, rt, rtf);
                break;

            case "cgt":
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (((int)spu.Register[ra, i]) > ((int)spu.Register[rb, i])) ? 0xFFFFFFFF : 0x0;
                }
                break;

            case "ceqb":
                rtb = SPUCommandHelper.reg_to_byte(spu, rt);
                rbb = SPUCommandHelper.reg_to_byte(spu, rb);
                rab = SPUCommandHelper.reg_to_byte(spu, ra);

                for (int i = 0; i < 16; i++)
                {
                    rtb[i] = (rab[i] == rbb[i]) ? (byte)0xFF : (byte)0x00;
                }
                SPUCommandHelper.byte_to_reg(spu, rt, rtb);
                break;

            case "roti":
                shift_count = idx & 0x1F;
                for (int i = 0; i < 4; i++)
                {
                    spu.Register[rt, i] = (spu.Register[ra, i] << shift_count) | (spu.Register[ra, i] >> (32 - shift_count));
                }
                break;

            case "rotqmbi":
                rtB         = SPUCommandHelper.reg_to_Bits(spu, rt);
                raB         = SPUCommandHelper.reg_to_Bits(spu, ra);
                shift_count = (-(int)spu.Register[rb, 0]) & 7;
                for (int i = 0; i < 128; i++)
                {
                    if (i >= shift_count)
                    {
                        rtB[i] = raB[i - shift_count];
                    }
                    else
                    {
                        rtB[i] = 0;
                    }
                }
                SPUCommandHelper.Bits_to_reg(spu, rt, rtB);
                break;

            /*
             * 01010101110,rr,xshw,half
             * {
             * int i;
             * for (i = 0; i < 8; i += 2)
             * {
             * rth[i] = (rah[i + 1] & 0x8000) ? 0xFFFF : 0;
             * rth[i + 1] = rah[i + 1];
             * }
             * }
             *
             * 00010101,ri10,andhi,half,signed
             * {
             * int i;
             * for (i = 0; i < 8; ++i)
             * rth[i] &= i10;
             * }
             *
             * 01011001001,rr,orc
             * {
             * int i;
             * for (i = 0; i < 4; ++i)
             * rtw[i] = raw[i] |~ rbw[i];
             * }
             *
             * 01000100,ri10,xori,signed
             * {
             * int i;
             * for (i = 0; i < 4; ++i)
             * rtw[i] = raw[i] ^ i10;
             * }
             *
             * 01001001001,rr,eqv
             *
             # shift and rotate instruction
             #
             # 00111001111,rr,shlqbybi,byte
             # {
             # int i;
             # int shift_count = ((rbb[3])>>3) & 0x1f;
             #
             # for (i = 0; i < 16; ++i)
             # {
             # if ((i + shift_count) < 16)
             # rtb[i] = rab[i + shift_count];
             # else
             # rtb[i] = 0;
             # }
             # }
             #
             # 00001111101,ri7,rothmi,half
             # {
             # int shift_count = (-i7) & 31;
             # int i;
             # for (i = 0; i < 8; ++i)
             # if (shift_count < 16)
             # rth[i] = rah[i] >> shift_count;
             # else
             # rth[i] = 0;
             # }
             #
             # 000001011010,rr,rotma
             # {
             # int i,shift_count;
             # for (i = 0; i < 4; ++i){
             # shift_count = (-rbw[i]) & 63;
             # if (shift_count < 32)
             # rtw[i] = ((s32)raw[i]) >> shift_count;
             # else
             # rtw[i] = ((s32)raw[i]) >> 31;
             # }
             # }
             #
             # compare, branch and halt instructions
             #
             # 01111101,ri10,ceqhi,signed,half
             # {
             # int i;
             #
             # for (i = 0; i < 8; ++i)
             # rth[i] = -(rah[i] == i10);
             # }
             # 01111001000,rr,ceqh,half
             # {
             # int i;
             #
             # for (i = 0; i < 8; ++i)
             # rth[i] = -(rah[i] == rbh[i]);
             # }
             #
             # 01011010000,rr,clgtb,byte
             # {
             # int i;
             # for (i = 0; i < 16; ++i)
             # rtb[i] = -(rab[i] > rbb[i]);
             # }
             #
             # 01001101,ri10,cgthi,signed,half
             # {
             # int i;
             # for (i = 0; i < 8; ++i)
             # rth[i] = -(((s16)rah[i]) > ((s16)i10));
             # }
             #
             # 01011101,ri10,clgthi,signed,half
             # {
             # int i;
             # for (i = 0; i < 8; ++i)
             # rth[i] = -(rah[i] > i10);
             # }
             # 01011001000,rr,clgth,half
             # {
             # int i;
             # for (i = 0; i < 8; ++i)
             # rth[i] = -(rah[i] > rbh[i]);
             # }
             #
             # 01011000100,rr,fa,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = raf[i] + rbf[i];
             # }
             # 01011000101,rr,fs,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = raf[i] - rbf[i];
             # }
             # 01011000110,rr,fm,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = raf[i] * rbf[i];
             #
             # }
             # 1110,rrr,fma,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = rcf[i] + (raf[i] * rbf[i]);
             # }
             #
             # 1101,rrr,fnms,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = rcf[i] - (raf[i] * rbf[i]);
             # }
             # 01011000010,rr,fcgt,float
             # {
             # int itrue = 0xffffffff;
             # float ftrue = *(float*)&itrue;
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = raf[i]>rbf[i]?ftrue:0.0;
             #
             # }
             # 01111000010,rr,fceq,float
             # {
             # //note: floats are not accurately modeled!
             # int i;
             # int itrue = 0xffffffff;
             # float ftrue = *(float*)&itrue;
             # for (i = 0; i < 4; ++i)
             # rtf[i] = raf[i]==rbf[i]?ftrue:0.0;
             # }
             # 00110111000,rr,frest,float
             # {
             # int i;
             # // not quite right, but assume this is followed by a 'fi'
             # for (i = 0; i < 4; ++i)
             # rtf[i] = 1/raf[1];
             # }
             # 00110111001,rr,frsqest,float
             # {
             # int i;
             # // not quite right, but assume this is followed by a 'fi'
             # for (i = 0; i < 4; ++i)
             # rtf[i] = 1/sqrt(fabs(raf[i]));
             # }
             # 01111010100,rr,fi,float
             # {
             # int i;
             # // not quite right, but assume this was preceeded by a 'fr*est'
             # for (i = 0; i < 4; ++i)
             # rtf[i] = rbf[i];
             # }
             # 01110111000,rr,fesd,float
             # {
             # double result = raf[0];
             # float *tmp = (float*)&result;
             # rtf[0] = tmp[1];
             # rtf[1] = tmp[0];
             # result = raf[2];
             # rtf[2] = tmp[1];
             # rtf[3] = tmp[0];
             # }
             # 01110111001,rr,frds,double
             # {
             # double dtmp = rad[0];
             # float ftmp = dtmp;
             # float *ptmp = (float*)&dtmp;
             # ptmp[1] = ftmp;
             # ptmp[0] = 0.0;
             # rtd[0]=dtmp;
             #
             # dtmp = rad[1];
             # ftmp = dtmp;
             # ptmp[0] = ftmp;
             # ptmp[1] = 0.0;
             # rtd[1] = dtmp;
             # }
             #
             # 0111011010,ri8,csflt,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i){
             # int val = raw[i];
             # // let's hope the x86s float HW does the right thing here...
             # rtf[i] = (float)val;
             # }
             # }
             # 0111011000,ri8,cflts,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtw[i] = (int)raf[i];
             # }
             # 0111011001,ri8,cfltu,float
             # {
             # int i;
             # for (i = 0; i < 4; ++i)
             # rtw[i] = (u32)raf[i];
             # }
             # 01011001110,rr,dfm,double
             # {
             # rtd[0] = rad[0]*rbd[0];
             # rtd[1] = rad[1]*rbd[1];
             # }
             # 01011001101,rr,dfs,double
             # {
             # rtd[0] = rad[0]-rbd[0];
             # rtd[1] = rad[1]-rbd[1];
             # }
             # 01011001100,rr,dfa,double
             # {
             # rtd[0] = rad[0]+rbd[0];
             # rtd[1] = rad[1]+rbd[1];
             # }
             # 01101011101,rr,dfms,double
             # {
             # rtd[0] = (rad[0]*rbd[0])-rtd[0];
             # rtd[1] = (rad[1]*rbd[1])-rtd[1];
             # }
             # 01101011110,rr,dfnms,double
             # {
             # // almost same as dfms. This is missing in SPU_ISA_1.2. See v.1.1
             # rtd[0] = (rad[0]*rbd[0])-rtd[0];
             # rtd[1] = (rad[1]*rbd[1])-rtd[1];
             # }
             # 01101011100,rr,dfma,double
             # {
             # rtd[0] = (rad[0]*rbd[0])+rtd[0];
             # rtd[1] = (rad[1]*rbd[1])+rtd[1];
             # }
             #
             # NOT IMPLEMENTED:
             # 01111000100,rr,mpy
             # 1100,rrr,mpya
             # 01101000110,rr,mpyhha
             # 01101001110,rr,mpyhhau
             # 01010110100,rr,cntb
             # 00110110110,rr,fsmb
             # 00110110101,rr,fsmh
             # 00110110001,rr,gbh
             # 00011010011,rr,avgb
             # 00001010011,rr,absdb
             # 01001010011,rr,sumb
             # 01000101,ri10,xorhi
             # 00011001001,rr,nand
             # 00111110000,rr,orx
             # 00000110,ri10,orbi
             # 00000101,ri10,orhi
             */
            default:
                System.Windows.Forms.MessageBox.Show(mnemonics + " not implemented yet!");
                return(3);
            }
            if (spu.LastIP != spu.IP)
            {
                string newFunc = spu.LocalStorageCommands[(spu.IP + 4) >> 2].functionName;
                string oldFunc = spu.LocalStorageCommands[(spu.LastIP) >> 2].functionName;
                if (newFunc != oldFunc)
                {
                    SPUDumper.Instance.CallStackDump(spu, spu.LastIP, spu.IP + 4);
                }
            }
            return(stop);
        }
Пример #51
0
        public LocalStorageWatcher(SPU spu)
        {
            InitializeComponent();

            this.spu = spu;
        }
Пример #52
0
 public void Dump(SPU spu)
 {
     uint addr = (uint) spu.IP;
     if (commands.ContainsKey(addr))
     {
         foreach (SPUDumperCmd cmd in commands[addr])
             cmd.execute(spu);
     }
 }
Пример #53
0
 private int findYourselfCheckDeeper(SPU spu, int foundFirstMnemonic)
 {
     int ii, iii;
     for (ii = 0, iii = foundFirstMnemonic; ii < mnemonics.Length; ii++, iii++)
     {
         while (spu.LocalStorageCommands[iii].mnemonics.StartsWith("hb") || spu.LocalStorageCommands[iii].mnemonics == "nop" || spu.LocalStorageCommands[iii].mnemonics == "lnop")
             iii++;
         while (mnemonics[ii].StartsWith("hb") || mnemonics[ii] == "nop" || mnemonics[ii] == "lnop")
             ii++;
         if (spu.LocalStorageCommands[iii].mnemonics != mnemonics[ii])
             return -1;
     }
     return iii;
 }
Пример #54
0
 public formspu()
 {
     InitializeComponent();
     ls = new LoadingScreen();
     spu = new SPU();
 }
Пример #55
0
 public formspu()
 {
     InitializeComponent();
     ls  = new LoadingScreen();
     spu = new SPU();
 }
Пример #56
0
 public static void float_to_reg(SPU spu, int r, float[] d)
 {
     for(int i = 0; i < 4; i++)
         spu.Register[r, i] = ConversionUtil.byteToUInt(BitConverter.GetBytes(d[i]));
 }