예제 #1
0
        private void executeCommandSIGNAL(PspGeList list)
        {
            int args     = NativeUtils.getCoreCmdArray(GeCommands.SIGNAL) & 0x00FFFFFF;
            int behavior = (args >> 16) & 0xFF;
            int signal   = args & 0xFFFF;

            //if (log.DebugEnabled)
            {
                Console.WriteLine(string.Format("SIGNAL (behavior={0:D}, signal=0x{1:X})",behavior,signal));
            }

            switch (behavior)
            {
            case sceGe_user.PSP_GE_SIGNAL_SYNC:
            {
                // Skip FINISH / END
                Memory mem = Memory.Instance;
                if (command(mem.read32(list.Pc)) == FINISH)
                {
                    list.readNextInstruction();
                    if (command(mem.read32(list.Pc)) == END)
                    {
                        list.readNextInstruction();
                    }
                }
                //if (log.DebugEnabled)
                {
                    Console.WriteLine(string.Format("PSP_GE_SIGNAL_SYNC ignored PC: 0x{0:X8}", list.Pc));
                }
                break;
            }

            case sceGe_user.PSP_GE_SIGNAL_CALL:
            {
                // Call list using absolute address from SIGNAL + END.
                int hi16  = signal & 0x0FFF;
                int lo16  = NativeUtils.getCoreCmdArray(GeCommands.END) & 0xFFFF;
                int addr  = (hi16 << 16) | lo16;
                int oldPc = list.Pc;
                list.callAbsolute(addr);
                int newPc = list.Pc;
                //if (log.DebugEnabled)
                {
                    Console.WriteLine(string.Format("PSP_GE_SIGNAL_CALL old PC: 0x{0:X8}, new PC: 0x{1:X8}", oldPc, newPc));
                }
                break;
            }

            case sceGe_user.PSP_GE_SIGNAL_RETURN:
            {
                // Return from PSP_GE_SIGNAL_CALL.
                int oldPc = list.Pc;
                list.ret();
                int newPc = list.Pc;
                //if (log.DebugEnabled)
                {
                    Console.WriteLine(string.Format("PSP_GE_SIGNAL_RETURN old PC: 0x{0:X8}, new PC: 0x{1:X8}", oldPc, newPc));
                }
                break;
            }

            case sceGe_user.PSP_GE_SIGNAL_TBP0_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP1_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP2_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP3_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP4_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP5_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP6_REL:
            case sceGe_user.PSP_GE_SIGNAL_TBP7_REL:
            {
                // Overwrite TBPn and TBPw with SIGNAL + END (uses relative address only).
                int hi16     = signal & 0xFFFF;
                int end      = NativeUtils.getCoreCmdArray(GeCommands.END);
                int lo16     = end & 0xFFFF;
                int width    = (end >> 16) & 0xFF;
                int addr     = list.getAddressRel((hi16 << 16) | lo16);
                int tbpValue = (behavior - sceGe_user.PSP_GE_SIGNAL_TBP0_REL + GeCommands.TBP0) << 24 | (addr & 0x00FFFFFF);
                int tbwValue = (behavior - sceGe_user.PSP_GE_SIGNAL_TBP0_REL + GeCommands.TBW0) << 24 | ((addr >> 8) & 0x00FF0000) | (width & 0xFFFF);
                NativeUtils.interpretCoreCmd(command(tbpValue), tbpValue, NativeUtils.CoreMadr);
                NativeUtils.interpretCoreCmd(command(tbwValue), tbwValue, NativeUtils.CoreMadr);
                break;
            }

            case sceGe_user.PSP_GE_SIGNAL_TBP0_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP1_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP2_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP3_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP4_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP5_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP6_REL_OFFSET:
            case sceGe_user.PSP_GE_SIGNAL_TBP7_REL_OFFSET:
            {
                // Overwrite TBPn and TBPw with SIGNAL + END (uses relative address with offset).
                int hi16 = signal & 0xFFFF;
                // Read & skip END
                int end      = NativeUtils.getCoreCmdArray(GeCommands.END);
                int lo16     = end & 0xFFFF;
                int width    = (end >> 16) & 0xFF;
                int addr     = list.getAddressRelOffset((hi16 << 16) | lo16);
                int tbpValue = (behavior - sceGe_user.PSP_GE_SIGNAL_TBP0_REL + GeCommands.TBP0) << 24 | (addr & 0x00FFFFFF);
                int tbwValue = (behavior - sceGe_user.PSP_GE_SIGNAL_TBP0_REL + GeCommands.TBW0) << 24 | ((addr >> 8) & 0x00FF0000) | (width & 0xFFFF);
                NativeUtils.interpretCoreCmd(command(tbpValue), tbpValue, NativeUtils.CoreMadr);
                NativeUtils.interpretCoreCmd(command(tbwValue), tbwValue, NativeUtils.CoreMadr);
                break;
            }

            case sceGe_user.PSP_GE_SIGNAL_HANDLER_SUSPEND:
            case sceGe_user.PSP_GE_SIGNAL_HANDLER_CONTINUE:
            case sceGe_user.PSP_GE_SIGNAL_HANDLER_PAUSE:
            {
                list.clearRestart();
                list.pushSignalCallback(list.id, behavior, signal);
                list.endList();
                list.status = sceGe_user.PSP_GE_LIST_END_REACHED;
                break;
            }

            default:
            {
                if (log.InfoEnabled)
                {
                    Console.WriteLine(string.Format("SIGNAL (behavior={0:D}, signal=0x{1:X}) unknown behavior at 0x{2:X8}", behavior, signal, list.Pc - 4));
                }
            }
            break;
            }

            if (list.Drawing)
            {
                list.sync();
                NativeUtils.setCoreCtrlActive();
            }
        }
예제 #2
0
 public static void interpretCmd(int cmd, int value)
 {
     NativeUtils.interpretCoreCmd(cmd, value, NativeUtils.CoreMadr);
 }