private void setInterrupt(InterruptFlags IF) { m_IFR |= (byte)IF; if ((m_IFR & m_IER) > 0) { m_IFR |= 0x80; } }
private void clearInterrupt(InterruptFlags IF) { m_IFR = (byte)((m_IFR & (byte)~IF) & 0x7F); if ((m_IFR & m_IER) > 0) { m_IFR |= 0x80; } }
public void setInterruptFlag(InterruptFlags flag) { int bitAdress = decodeInterruptFlag(flag); if (isInterruptEnabled(bitAdress)) { int intCon = memory.getFile(0xb); intCon |= (1 << bitAdress); memory.setFile(0xb, intCon); } }
private int decodeInterruptFlag(InterruptFlags flag) { switch (flag) { case InterruptFlags.T0IF: return(2); case InterruptFlags.INTF: return(1); case InterruptFlags.RBIF: return(0); default: return(0); } }
/// <summary> /// Resets the bank to its begin state. /// </summary> public void Reset() { A = B = C = D = E = F = H = L = 0; IE = IF = InterruptFlags.None; IME = false; }
/// <summary> /// Checks whether the given spell can be casted by the casting Unit. /// Does not do range checks. /// </summary> public SpellFailedReason CheckCasterConstraints(Unit caster) { // check for combat if (caster.IsInCombat && RequiresCasterOutOfCombat) { return(SpellFailedReason.AffectingCombat); } if (!caster.CanDoHarm && HasHarmfulEffects) { return(SpellFailedReason.Pacified); } // Not while silenced if (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced) && caster.Class == ClassId.AtackMage && caster.Class == ClassId.SupportMage && caster.Class == ClassId.HealMage) { return(SpellFailedReason.Silenced); } // Check if castable while stunned if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.CantDoThatRightNow); } // Not while silenced else if (!caster.CanCastSpells && (!IsPhysicalAbility || (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced))) && caster.Class == ClassId.AtackMage && caster.Class == ClassId.SupportMage && caster.Class == ClassId.HealMage) { return(SpellFailedReason.Silenced); } // cannot use physical ability or not do harm at all else if ((!caster.CanDoPhysicalActivity && IsPhysicalAbility) || (!caster.CanDoHarm && HasHarmfulEffects)) { return(SpellFailedReason.Pacified); } else if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.Stunned); } // Combo points else if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // AuraStates if (RequiredCasterAuraState != 0 || ExcludeCasterAuraState != 0) { // check AuraStates var state = caster.AuraState; if ((RequiredCasterAuraState != 0 && !state.HasAnyFlag(RequiredCasterAuraState)) || (ExcludeCasterAuraState != 0 && state.HasAnyFlag(ExcludeCasterAuraState))) { return(SpellFailedReason.CasterAurastate); } } // Required Auras if ((ExcludeCasterAuraId != 0 && caster.Auras.Contains(ExcludeCasterAuraId)) || (RequiredCasterAuraId != 0 && !caster.Auras.Contains(RequiredCasterAuraId))) { return(SpellFailedReason.CasterAurastate); } var spells = caster.Spells; // check cooldown and power cost if (spells != null && caster.CastingTill > System.DateTime.Now && !spells.IsReady(this)) { return(SpellFailedReason.NotReady); } if (caster is NPC && caster.Target != null && Range.MaxDist < caster.GetDistance(caster.Target)) { return(SpellFailedReason.OutOfRange); } if (!IsPassive) { if (!caster.HasEnoughPowerToCast(this, null)) { return(SpellFailedReason.NoPower); } } return(SpellFailedReason.Ok); }
/// <summary> /// Checks whether the given spell can be casted by the casting Unit. /// Does not do range checks. /// </summary> public SpellFailedReason CheckCasterConstraints(Unit caster) { // check for combat if (caster.IsInCombat && RequiresCasterOutOfCombat) { return(SpellFailedReason.AffectingCombat); } // Power Type if (CostsPower && PowerType != caster.PowerType && PowerType != PowerType.Health && !AttributesExB.HasFlag(SpellAttributesExB.DoesNotNeedShapeshift)) { return(SpellFailedReason.OnlyShapeshift); } if (!caster.CanDoHarm && HasHarmfulEffects) { return(SpellFailedReason.Pacified); } // Not while silenced if (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced)) { return(SpellFailedReason.Silenced); } // Check if castable while stunned if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.CantDoThatRightNow); } // Combo points if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // spell focus if (!CheckSpellFocus(caster)) { return(SpellFailedReason.RequiresSpellFocus); } // Not while silenced else if (!caster.CanCastSpells && (!IsPhysicalAbility || (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced)))) { return(SpellFailedReason.Silenced); } // cannot use physical ability or not do harm at all else if ((!caster.CanDoPhysicalActivity && IsPhysicalAbility) || (!caster.CanDoHarm && HasHarmfulEffects)) { return(SpellFailedReason.Pacified); } else if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.Stunned); } // Combo points else if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // AuraStates if (RequiredCasterAuraState != 0 || ExcludeCasterAuraState != 0) { // check AuraStates var state = caster.AuraState; if ((RequiredCasterAuraState != 0 && !state.HasAnyFlag(RequiredCasterAuraState)) || (ExcludeCasterAuraState != 0 && state.HasAnyFlag(ExcludeCasterAuraState))) { return(SpellFailedReason.CasterAurastate); } } // Required Auras if ((ExcludeCasterAuraId != 0 && caster.Auras.Contains(ExcludeCasterAuraId)) || (RequiredCasterAuraId != 0 && !caster.Auras.Contains(RequiredCasterAuraId))) { return(SpellFailedReason.CasterAurastate); } // Shapeshift var shapeshiftMask = caster.ShapeshiftMask; bool ignoreShapeshiftRequirement = false; // use this to allow for lazy requirement lookup if (ExcludeShapeshiftMask.HasAnyFlag(shapeshiftMask)) { if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { return(SpellFailedReason.NotShapeshift); } } else if (!RequiredShapeshiftMask.HasAnyFlag(shapeshiftMask)) { // our mask did not pass -> do the default checks var shapeshiftEntry = caster.ShapeshiftEntry; var shapeshifted = shapeshiftEntry != null && (shapeshiftEntry.Flags & ShapeshiftInfoFlags.NotActualShapeshift) == 0; if (shapeshifted) { if (RequiredShapeshiftMask != 0) { // When shapeshifted, can only use spells that allow this form if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { return(SpellFailedReason.OnlyShapeshift); } } else if (Attributes.HasAnyFlag(SpellAttributes.NotWhileShapeshifted)) { if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { // cannot cast this spell when shapeshifted return(SpellFailedReason.NotShapeshift); } } } if (Attributes.HasFlag(SpellAttributes.RequiresStealth) && caster.Stealthed < 1) { if (!caster.Auras.IsShapeshiftRequirementIgnored(this)) { // Stealth Required, but not stealthed and not ignored by a SPELL_AURA_MOD_IGNORE_SHAPESHIFT aura return(SpellFailedReason.OnlyStealthed); } } } var spells = caster.Spells as PlayerSpellCollection; // check cooldown and power cost if (spells != null && !spells.IsReady(this)) { return(SpellFailedReason.NotReady); } if (!IsPassive) { if (!caster.HasEnoughPowerToCast(this, null)) { return(SpellFailedReason.NoPower); } } return(SpellFailedReason.Ok); }
public byte this[int address] { get { address &= 0xFFFF; // Mostly just a sanity check if (address >= 0xFF80 && address < 0xFFFF) // HRAM { return(HRAM[address & 0x7F]); } // During DMA, only HRAM is accessable else if (DMAInProcess) { return(0); } if (address >= 0xF000) { if (address >= 0xFF00) // IO Registers { switch (address & 0xF0) { default: return(0); case 0: switch (address & 0x0F) { case 0: return(Joypad.P1Register); case 1: return(SerialTxReg); case 2: return(SerialControlReg); // 3: unused case 4: return(Timer.DivisionRegister); case 5: return(Timer.CountRegister); case 6: return(Timer.ModuloRegister); case 7: return(Timer.ControlRegister); // 8 - 14 unused case 15: return((byte)IFlagsReg); } return(0); case 0x10: // Sound Registers case 0x20: case 0x30: return(0); //su.ReadByte(address); case 0x40: // LCD registers switch (address & 0x0F) { case 0: return(GraphicsUnit.LCDCReg); case 1: return(GraphicsUnit.STATReg); case 2: return(GraphicsUnit.SCY); case 3: return(GraphicsUnit.SCX); case 4: return(GraphicsUnit.LCDYCoord); case 5: return(GraphicsUnit.LYC); case 6: return(DMAStart); case 7: return(GraphicsUnit.BGPallet); case 8: return(GraphicsUnit.ObjPallets[0]); case 9: return(GraphicsUnit.ObjPallets[1]); case 10: return(GraphicsUnit.WY); case 11: return(GraphicsUnit.WX); } return(0); case 0xF0: return((byte)IEnableReg); } } // Addresses 0xFE00 - 0xFE9A is reserved for the graphics OAM. // The rest is intentionally empty and should not be used. else if (address >= 0xFEA0) { return(0); } else if (address >= 0xFE00) { return(GraphicsUnit.ReadOAM(address)); } // F000-FDFF echos D000-DDFF return(InternalRAM[(address & 0x1FFF)]); } else if (address >= 0xC000) // C000 - EFFF: Internal RAM and Internal RAM Echo { // C000 ~ DFFF is the actual internal RAM // E000 ~ FDFF is an echo of the RAM, so we just read from the same place return(InternalRAM[(address & 0x1FFF)]); } else if (address >= 0xA000) // A000 - BFFF: Switchable RAM bank, i.e. External/Cartridge RAM { return(Cartridge.ReadRAM(address)); } else if (address >= 0x8000) // Graphics VRAM { return(GraphicsUnit.ReadVRAM(address)); } // Cartidge ROM else if ((address < 0x100) && BIOSLoaded) { return(BIOS[address]); } return(Cartridge.ReadROM(address)); } set { address &= 0xFFFF; // Sanity check again if (address >= 0xFF80 && address < 0xFFFF) // HRAM { HRAM[address & 0x7F] = value; } // During DMA, only HRAM is accessable else if (DMAInProcess) { return; } if (address >= 0xF000) { if (address >= 0xFF00) // IO Registers { switch (address & 0xF0) { case 0: switch (address & 0x0F) { case 0: Joypad.P1Register = value; break; case 1: SerialTxReg = value; break; case 2: SerialControlReg = value; break; // 3: unused case 4: Timer.DivisionRegister = value; break; case 5: Timer.CountRegister = value; break; case 6: Timer.ModuloRegister = value; break; case 7: Timer.ControlRegister = value; break; // 8 - 14 unused case 15: IFlagsReg = (InterruptFlags)value; break; } return; case 0x10: // Sound Registers case 0x20: case 0x30: return; //su.WriteByte(address, value); case 0x40: // LCD registers switch (address & 0x0F) { case 0: GraphicsUnit.LCDCReg = value; break; case 1: GraphicsUnit.STATReg = value; break; case 2: GraphicsUnit.SCY = value; break; case 3: GraphicsUnit.SCX = value; break; // 4: LY (read-only) case 5: GraphicsUnit.LYC = value; break; case 6: DMAStart = value; StartDMATransfer(); break; case 7: GraphicsUnit.BGPallet = value; break; case 8: GraphicsUnit.ObjPallets[0] = value; break; case 9: GraphicsUnit.ObjPallets[1] = value; break; case 10: GraphicsUnit.WY = value; break; case 11: GraphicsUnit.WX = value; break; } return; case 0x50: if (BIOSLoaded) { BIOSLoaded = value == 0; } break; case 0xF0: if (address == 0xFFFF) { IEnableReg = (InterruptFlags)value; } break; } } // Addresses 0xFE00 - 0xFE9A is reserved for the graphics OAM. // The rest is intentionally empty and should not be used. else if (address >= 0xFE00 && address < 0xFEA0) { GraphicsUnit.WriteOAM(address, value); } // F000-FDFF echos D000-DDFF and is read-only } else if (address >= 0xC000 && address < 0xE000) // C000-DFFF - Internal RAM { switch (address) { case 0xc004: break; } InternalRAM[address & 0x1FFF] = value; } else if (address >= 0xA000 && address < 0xC000) // A000-BFFF : External/Cartridge RAM { Cartridge.WriteRAM(address, value); } else if (address >= 0x8000 && address < 0xA000) // Graphics VRAM { GraphicsUnit.WriteVRAM(address, value); } else if (address < 0x8000) { Cartridge.WriteToRegister(address, value); } } }
private void Gu_VBlankInterrupt() { IFlagsReg |= InterruptFlags.VerticalBlank; }
private void Gu_LCDCInterrupt() { IFlagsReg |= InterruptFlags.LCDCStatus; }
private void Timer_TimerOverflow() { IFlagsReg |= InterruptFlags.TimerOverflow; }
private void Joypad_JoypadInterrupt() { IFlagsReg |= InterruptFlags.InputSignalLow; }