Exemple #1
0
        private Instruction InterruptHandler(Interrupts interrupt)
        {
            // Handle interrupt with a CALL instruction to the interrupt handler
            Instruction instruction = new Instruction();
            instruction.OpCode = 0xCD; // CALL!
            byte lowOpcode = (byte)instruction.OpCode;
            instruction.Length = CPUInstructionLengths.Get(lowOpcode);
            instruction.Literal = this.interruptHandlers[(Interrupts)interrupt];
            instruction.Ticks = CPUInstructionPreClocks.Get(lowOpcode);
            instruction.Name = CPUInstructionNames.Get(lowOpcode);
            instruction.Description = CPUInstructionDescriptions.Get(lowOpcode);

            // Disable interrupts during interrupt handling and clear the current one
            this._interruptController.InterruptMasterEnable = false;
            byte IF = this._memory.LowLevelRead((ushort)MMR.IF);
            IF &= (byte)~(byte)interrupt;
            this._memory.LowLevelWrite((ushort)MMR.IF, IF);
            return instruction;
        }
Exemple #2
0
        /// <summary>
        /// Sets the initial values for the cpu registers and memory mapped registers.
        /// This is the equivalent to run the BIOS rom.
        /// </summary>
        internal void Reset()
        {
            // Reset the clock state
            _state.Clock = 0;

            _state.Halted = false;
            _state.HaltLoad = false;
            _state.Stopped = false;

            // Magic CPU initial values (after bios execution).
            _state.Registers.A = 1;
            _state.Registers.BC = 0x0013;
            _state.Registers.DE = 0x00D8;
            _state.Registers.HL = 0x014D;
            _state.Registers.PC = 0x0100;
            _state.Registers.SP = 0xFFFE;

            // We restart the timer
            _state.DivCounter = 0xABFF;
            _state.TimaCounter = 0;
            _state.TacCounter = 0;
            _state.TacMask = 0;
            _state.TmaValue = 0;

            // Initialize memory mapped registers
            this._memory.LowLevelWrite(0xFF04, 0xAB); // DIV
            this._memory.LowLevelWrite(0xFF05, 0x00); // TIMA
            this._memory.LowLevelWrite(0xFF06, 0x00); // TMA
            this._memory.LowLevelWrite(0xFF07, 0x00); // TAC
            this._memory.LowLevelWrite(0xFF10, 0x80); // NR10
            this._memory.LowLevelWrite(0xFF11, 0xBF); // NR11
            this._memory.LowLevelWrite(0xFF12, 0xF3); // NR12
            this._memory.LowLevelWrite(0xFF14, 0xBF); // NR14
            this._memory.LowLevelWrite(0xFF16, 0x3F); // NR21
            this._memory.LowLevelWrite(0xFF17, 0x00); // NR22
            this._memory.LowLevelWrite(0xFF19, 0xBF); // NR24
            this._memory.LowLevelWrite(0xFF1A, 0x7F); // NR30
            this._memory.LowLevelWrite(0xFF1B, 0xFF); // NR31
            this._memory.LowLevelWrite(0xFF1C, 0x9F); // NR32
            this._memory.LowLevelWrite(0xFF1E, 0xBF); // NR33
            this._memory.LowLevelWrite(0xFF20, 0xFF); // NR41
            this._memory.LowLevelWrite(0xFF21, 0x00); // NR42
            this._memory.LowLevelWrite(0xFF22, 0x00); // NR43
            this._memory.LowLevelWrite(0xFF23, 0xBF); // NR30
            this._memory.LowLevelWrite(0xFF24, 0x77); // NR50
            this._memory.LowLevelWrite(0xFF25, 0xF3); // NR51
            this._memory.LowLevelWrite(0xFF26, 0xF1); // NR52 GB: 0xF1, SGB: 0xF0
            this._memory.LowLevelWrite(0xFF40, 0x91); // LCDC
            this._memory.LowLevelWrite(0xFF42, 0x00); // SCY
            this._memory.LowLevelWrite(0xFF43, 0x00); // SCX
            this._memory.LowLevelWrite(0xFF45, 0x00); // LYC
            this._memory.LowLevelWrite(0xFF47, 0xFC); // BGP
            this._memory.LowLevelWrite(0xFF48, 0xFF); // OBP0
            this._memory.LowLevelWrite(0xFF49, 0xFF); // OBP1
            this._memory.LowLevelWrite(0xFF4A, 0x00); // WY
            this._memory.LowLevelWrite(0xFF4B, 0x00); // WX
            this._memory.LowLevelWrite(0xFFFF, 0x00); // IE

            _state.CurrentInstruction = new Instruction();
            _exportInstruction = new Instruction();
        }
        internal void Reset()
        {
            _disInstructions = new List<IInstruction>();
              _disVisitedAddresses = new HashSet<ushort>();
              _disAddressToVisit = new Stack<ushort>();

              _disassembledMatrix = new byte[0xFFFF][];
              for (int i = 0; i < 0xFFFF; ++i)
              {
            _disassembledMatrix[i] = new byte[5];
              }

              _tempInstruction = new Instruction();
        }
Exemple #4
0
        /// <summary>
        /// Fetches and Decodes an instruction
        /// </summary>
        /// <param name="instruction">
        /// As FetchAndDecode gets called *several* times a frame (and many times during
        /// disassembly), it is better to have a pre-allocated instruction and to replace
        /// the values, instead of getting the overhead of allocating a new Instrucion
        /// everytime.
        /// </param>
        /// <param name="instructionAddress"></param>
        /// <param name="haltLoad"></param>
        /// <returns></returns>
        internal Instruction FetchAndDecode(ref Instruction instruction,
            ushort instructionAddress, bool haltLoad = false)
        {
            instruction.Address = instructionAddress;
            byte opcode = this._memory.LowLevelRead(instructionAddress);
            instruction.OpCode = opcode;

            if (instruction.OpCode != 0xCB)
            {
                instruction.CB = false;
                byte lowOpcode = (byte)instruction.OpCode;
                if (_instructionHistogram[lowOpcode] < ushort.MaxValue)
                    _instructionHistogram[lowOpcode]++;
                // Normal instructions
                instruction.Length = CPUInstructionLengths.Get(lowOpcode);

                // Extract literal
                if (instruction.Length == 2)
                {
                    // 8 bit literal
                    instruction.Operands[0] = this._memory.LowLevelRead((ushort)(instructionAddress + 1));
                    if (haltLoad)
                    {
                        instruction.Operands[0] = opcode;
                    }
                    instruction.Literal = (byte)instruction.Operands[0];
                }
                else if (instruction.Length == 3)
                {
                    // 16 bit literal, little endian
                    instruction.Operands[0] = this._memory.LowLevelRead((ushort)(instructionAddress + 2));
                    instruction.Operands[1] = this._memory.LowLevelRead((ushort)(instructionAddress + 1));

                    if (haltLoad)
                    {
                        instruction.Operands[1] = instruction.Operands[0];
                        instruction.Operands[0] = opcode;
                    }

                    instruction.Literal = (byte)instruction.Operands[1];
                    instruction.Literal += (ushort)(instruction.Operands[0] << 8);
                }

                instruction.Ticks = CPUInstructionPreClocks.Get(lowOpcode);
                instruction.Name = CPUInstructionNames.Get(lowOpcode);
                instruction.Description = CPUInstructionDescriptions.Get(lowOpcode);
            }
            else
            {
                instruction.CB = true;
                // CB instructions block
                instruction.OpCode <<= 8;
                if (!haltLoad)
                {
                    instruction.OpCode += this._memory.LowLevelRead((ushort)(instructionAddress + 1));
                }
                else
                {
                    instruction.OpCode += 0xCB; // The first byte is duplicated
                }

                byte lowOpcode = (byte)instruction.OpCode;

                if (_cbInstructionHistogram[lowOpcode] < ushort.MaxValue)
                {
                    _cbInstructionHistogram[lowOpcode]++;
                }
                instruction.Length = CPUCBInstructionLengths.Get(lowOpcode);
                // There is no literal in CB instructions!

                //instruction.Lambda = this.CBInstructionLambdas[lowOpcode];
                instruction.Ticks = CPUCBInstructionPreClocks.Get(lowOpcode);
                instruction.Name = CPUCBInstructionNames.Get(lowOpcode);
                instruction.Description = CPUCBInstructionDescriptions.Get(lowOpcode);
            }

            // NOTE(Cristian): On haltLoad (HALT with IME disabled), the next byte after the HALT opcode
            //                 is "duplicated". This is a hardware bug.
            if (haltLoad)
            {
                instruction.Length--;
            }

            return instruction;
        }
 public IInstruction FetchAndDecode(ushort address)
 {
     Instruction inst = new Instruction();
       _cpu.FetchAndDecode(ref inst, address);
       return inst;
 }