Exemple #1
0
 private void setInterrupt(InterruptFlags IF)
 {
     m_IFR |= (byte)IF;
     if ((m_IFR & m_IER) > 0)
     {
         m_IFR |= 0x80;
     }
 }
Exemple #2
0
 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);
            }
        }
Exemple #5
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;
 }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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;
 }