Beispiel #1
0
        /// @brief Execute a PASM instruction in this cog.
        /// @returns TRUE if it is the opportunity to trigger a breakpoint, or FALSE if not.
        override public bool DoInstruction()
        {
            switch (State)
            {
            // Delay State
            case CogRunState.WAIT_CYCLES:
                if (--StateCount == 1)
                {
                    WriteBackResult();
                }
                return(true);

            // Clocked, but not executed
            case CogRunState.WAIT_PREWAIT:
                if (--StateCount == 1)
                {
                    State = NextState;
                }
                return(true);

            // Execute State
            case CogRunState.STATE_EXECUTE:
                break;

            case CogRunState.WAIT_PNE:
            {
                uint maskedIn = (Carry ? Hub.INB : Hub.INA) & SourceValue;
                if (maskedIn != DestinationValue)
                {
                    DataResult = maskedIn;
                    Zero       = (maskedIn == 0);
                    // TODO: DETERMINE CARRY
                    WriteBackResult();
                }
                return(true);
            }

            case CogRunState.WAIT_PEQ:
            {
                uint maskedIn = (Carry ? Hub.INB : Hub.INA) & SourceValue;
                if (maskedIn == DestinationValue)
                {
                    DataResult = maskedIn;
                    Zero       = (maskedIn == 0);
                    // TODO: DETERMINE CARRY
                    WriteBackResult();
                    return(true);
                }
                return(true);
            }

            case CogRunState.WAIT_CNT:
            {
                long target = Hub.Counter;

                if (DestinationValue == target)
                {
                    target     += SourceValue;
                    DataResult  = (uint)target;
                    CarryResult = target > 0xFFFFFFFF;
                    ZeroResult  = (DataResult == 0);
                    WriteBackResult();
                    return(true);
                }
                return(true);
            }

            case CogRunState.WAIT_VID:
                if (Video.Ready)
                {
                    Video.Feed(DestinationValue, SourceValue);
                    // TODO: Determine carry, zero, and result
                    WriteBackResult();
                }
                return(true);

            // Non-execute states are ignored
            default:
                return(true);
            }

            PC = (PC + 1) & 0x1FF;

            InstructionCode = (CogInstructionCodes)(Operation & 0xFC000000);
            ConditionCode   = (CogConditionCodes)((Operation & 0x003C0000) >> 18);

            WriteZero      = (Operation & 0x02000000) != 0;
            WriteCarry     = (Operation & 0x01000000) != 0;
            WriteResult    = (Operation & 0x00800000) != 0;
            ImmediateValue = (Operation & 0x00400000) != 0;

            SourceValue = Operation & 0x1FF;

            if (!ImmediateValue)
            {
                SourceValue = ReadLong(SourceValue);
            }

            Destination      = (Operation >> 9) & 0x1FF;
            DestinationValue = ReadLong(Destination);

            if (ConditionCompare(ConditionCode, Zero, Carry))
            {
                Operation  = ReadLong(PC);
                State      = CogRunState.WAIT_PREWAIT;
                NextState  = CogRunState.STATE_EXECUTE;
                StateCount = 4;
                return(true);
            }

            switch (InstructionCode)
            {
            // RESERVED FOR FUTURE EXPANSION
            case CogInstructionCodes.MUL:
            case CogInstructionCodes.MULS:
            case CogInstructionCodes.ENC:
            case CogInstructionCodes.ONES:
                // TODO: RAISE INVALID OP CODE HERE

                DataResult = 0;
                Carry      = true;
                Zero       = true;

                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            // HUB Operations (6 cycles for instruction decode... 1-15 cycles for operation)
            case CogInstructionCodes.RWBYTE:
                State      = CogRunState.WAIT_PREWAIT;
                NextState  = CogRunState.HUB_RDBYTE;
                StateCount = 6;
                break;

            case CogInstructionCodes.RWWORD:
                State      = CogRunState.WAIT_PREWAIT;
                NextState  = CogRunState.HUB_RDWORD;
                StateCount = 6;
                break;

            case CogInstructionCodes.RWLONG:
                State      = CogRunState.WAIT_PREWAIT;
                NextState  = CogRunState.HUB_RDLONG;
                StateCount = 6;
                break;

            case CogInstructionCodes.HUBOP:
                State      = CogRunState.WAIT_PREWAIT;
                NextState  = CogRunState.HUB_HUBOP;
                StateCount = 6;
                break;

            // Standard operations (4 cycles)
            case CogInstructionCodes.ROR:
                InstructionROR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ROL:
                InstructionROL();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.RCR:
                InstructionRCR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.RCL:
                InstructionRCL();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SHR:
                InstructionSHR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SHL:
                InstructionSHL();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SAR:
                InstructionSAR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.OR:
                InstructionOR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.XOR:
                InstructionXOR();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.AND:
                InstructionAND();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ANDN:
                InstructionANDN();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MUXC:
                InstructionMUXC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MUXNC:
                InstructionMUXNC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MUXZ:
                InstructionMUXZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MUXNZ:
                InstructionMUXNZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.REV:
                InstructionREV();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.NEG:
                InstructionNEG();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ABS:
                InstructionABS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ABSNEG:
                InstructionABSNEG();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.NEGC:
                InstructionNEGC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.NEGNC:
                InstructionNEGNC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.NEGZ:
                InstructionNEGZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.NEGNZ:
                InstructionNEGNZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MOV:
                InstructionMOV();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MOVS:
                InstructionMOVS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MOVD:
                InstructionMOVD();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MOVI:
                InstructionMOVI();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.JMPRET:
                InstructionJMPRET();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MINS:
                InstructionMINS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MAXS:
                InstructionMAXS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MIN:
                InstructionMIN();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.MAX:
                InstructionMAX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ADD:
                InstructionADD();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ADDABS:
                InstructionADDABS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ADDX:
                InstructionADDX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ADDS:
                InstructionADDS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.ADDSX:
                InstructionADDSX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUB:
                InstructionSUB();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUBABS:
                InstructionSUBABS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUBX:
                InstructionSUBX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUBS:
                InstructionSUBS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUBSX:
                InstructionSUBSX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUMC:
                InstructionSUMC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUMNC:
                InstructionSUMNC();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUMZ:
                InstructionSUMZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.SUMNZ:
                InstructionSUMNZ();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.CMPS:
                InstructionCMPS();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.CMPSX:
                InstructionCMPSX();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            case CogInstructionCodes.CMPSUB:
                InstructionCMPSUB();
                State      = CogRunState.WAIT_CYCLES;
                StateCount = 4;
                break;

            // Decrement and continue instructions ( 4/8 cycles )
            case CogInstructionCodes.DJNZ:
                StateCount = InstructionDJNZ() ? 4 : 8;
                State      = CogRunState.WAIT_CYCLES;
                break;

            case CogInstructionCodes.TJNZ:
                StateCount = InstructionTJNZ() ? 4 : 8;
                State      = CogRunState.WAIT_CYCLES;
                break;

            case CogInstructionCodes.TJZ:
                StateCount = InstructionTJZ() ? 4 : 8;
                State      = CogRunState.WAIT_CYCLES;
                break;

            // Delay execution instructions ( 4 cycles for instruction decode, 1+ for instruction )
            case CogInstructionCodes.WAITPEQ:
                NextState  = CogRunState.WAIT_PEQ;
                State      = CogRunState.WAIT_PREWAIT;
                StateCount = 4;
                break;

            case CogInstructionCodes.WAITPNE:
                NextState  = CogRunState.WAIT_PNE;
                State      = CogRunState.WAIT_PREWAIT;
                StateCount = 4;
                break;

            case CogInstructionCodes.WAITCNT:
                NextState  = CogRunState.WAIT_CNT;
                State      = CogRunState.WAIT_PREWAIT;
                StateCount = 4;
                break;

            case CogInstructionCodes.WAITVID:
                NextState  = CogRunState.WAIT_VID;
                State      = CogRunState.WAIT_PREWAIT;
                StateCount = 4;
                break;
            }

            // Prefetch instruction
            Operation = ReadLong(PC);
            // Check if it's time to trigger a breakpoint
            return(PC != BreakPointCogCursor);
        }
Beispiel #2
0
        /// @todo Document method Gear.EmulationCore.Cog.ConditionCompare.
        ///
        public static bool ConditionCompare(CogConditionCodes condition, bool a, bool b)
        {
            switch (condition)
            {
            case CogConditionCodes.IF_NEVER:
                break;

            case CogConditionCodes.IF_NZ_AND_NC:
                if (!a && !b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_NC_AND_Z:
                if (a && !b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_NC:
                if (!b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C_AND_NZ:
                if (!a && b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_NZ:
                if (!a)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C_NE_Z:
                if (a != b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_NC_OR_NZ:
                if (!a || !b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C_AND_Z:
                if (a && b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C_EQ_Z:
                if (a == b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_Z:
                if (a)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_NC_OR_Z:
                if (a || !b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C:
                if (b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_C_OR_NZ:
                if (!a || b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_Z_OR_C:
                if (a || b)
                {
                    return(false);
                }
                break;

            case CogConditionCodes.IF_ALWAYS:
                return(false);
            }

            return(true);
        }