/// @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); }
/// @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); }