Beispiel #1
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 6:
                //read jump address lsb
                _jumpAddress = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 5:
                //read jump address msb
                _jumpAddress |= (ushort)(mainMemory.ReadByte(cpuState.ProgramCounter++) << 8);
                break;

            case 3:
                //write msb of program counter to stack
                mainMemory.WriteByte(--cpuState.StackPointer, (byte)(cpuState.ProgramCounter >> 8));
                break;

            case 2:
                //write lsb of program counter to stack
                mainMemory.WriteByte(--cpuState.StackPointer, (byte)(cpuState.ProgramCounter & 0x00FF));
                break;

            case 1:
                //do the jump
                cpuState.ProgramCounter = _jumpAddress;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #2
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 4:
                //read jump address lsb
                _jumpAddress = mainMemory.ReadByte(cpuState.StackPointer++);
                break;

            case 3:
                //read jump address msb
                _jumpAddress |= (ushort)(mainMemory.ReadByte(cpuState.StackPointer++) << 8);
                break;

            case 2:
                cpuState.ImeScheduled = true;
                break;

            case 1:
                //do the jump
                cpuState.ProgramCounter = _jumpAddress;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #3
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 5:
                _writeAddress = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 4:
                _writeAddress |= (ushort)(mainMemory.ReadByte(cpuState.ProgramCounter++) << 8);
                break;

            case 3:
                //write lsb of stack pointer
                mainMemory.WriteByte(_writeAddress, (byte)cpuState.StackPointer);
                break;

            case 2:
                //write msb of stack pointer
                mainMemory.WriteByte((ushort)(_writeAddress + 1), (byte)(cpuState.StackPointer >> 8));
                break;

            case 1:
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #4
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 5:
                if (!IsConditionMet(cpuState))
                {
                    _remainingCycles = 2;
                }
                break;

            case 4:
                //read jump address lsb
                _jumpAddress = mainMemory.ReadByte(cpuState.StackPointer++);
                break;

            case 3:
                //read jump address msb
                _jumpAddress |= (ushort)(mainMemory.ReadByte(cpuState.StackPointer++) << 8);
                break;

            case 2:
                //do the jump
                cpuState.ProgramCounter = _jumpAddress;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
        internal void RequestVBlankInterrupt()
        {
            var currentIf = _mainMemory.ReadByte(MiscRegisters.InterruptFlags);

            _mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(currentIf | 0x01));

            NotifyNextFrameReady();

            SwapBuffers();
        }
Beispiel #6
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _addressLsb = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 2:
                cpuState.Registers.A = mainMemory.ReadByte((ushort)((0xFF << 8) | _addressLsb));
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #7
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                //read jump address lsb
                _relativeAddress = (sbyte)mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 2:
                //set last cycle if condition is not met
                if (!IsConditionMet(cpuState))
                {
                    _remainingCycles = 1;
                }
                break;

            case 1:
                //do the jump
                cpuState.ProgramCounter = (ushort)(cpuState.ProgramCounter + _relativeAddress);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #8
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _addData = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 1:
                var oldValue = cpuState.Registers.A;

                int result = cpuState.Registers.A + _addData;
                if (cpuState.Registers.CarryFlag)
                {
                    result++;
                }

                cpuState.Registers.A = (byte)result;

                cpuState.Registers.SubtractionFlag = false;
                cpuState.Registers.ZeroFlag        = cpuState.Registers.A == 0;
                cpuState.Registers.HalfCarryFlag   = (((oldValue & 0xF) + (_addData & 0xF)
                                                       + (cpuState.Registers.CarryFlag ? 1 : 0)) & 0x10) == 0x10;
                cpuState.Registers.CarryFlag = result > 0xFF;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #9
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            var interruptEnable = mainMemory.ReadByte(MiscRegisters.InterruptEnable);
            var interruptFlags  = mainMemory.ReadByte(MiscRegisters.InterruptFlags);

            if (!cpuState.InterruptMasterEnable && (interruptEnable & interruptFlags & 0x1F) != 0)
            {
                cpuState.HaltBug = true;
            }
            else
            {
                cpuState.HaltMode = true;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #10
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _currentData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 2:
                byte lowNibble  = (byte)(_currentData & 0x0F);
                byte highNibble = (byte)(_currentData & 0xF0);

                _writeData = (byte)((lowNibble << 4) | (highNibble >> 4));

                mainMemory.WriteByte(cpuState.Registers.HL, _writeData);

                cpuState.Registers.ZeroFlag        = _writeData == 0;
                cpuState.Registers.HalfCarryFlag   = false;
                cpuState.Registers.SubtractionFlag = false;
                cpuState.Registers.CarryFlag       = false;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #11
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 4:
                _signedValue = (sbyte)mainMemory.ReadByte(cpuState.ProgramCounter++);
                _oldValue    = cpuState.StackPointer;
                break;

            case 3:
                cpuState.StackPointer = (ushort)(cpuState.StackPointer + _signedValue);
                break;

            case 1:
                if (_signedValue >= 0)
                {
                    cpuState.Registers.CarryFlag     = ((_oldValue & 0xFF) + (_signedValue)) > 0xFF;
                    cpuState.Registers.HalfCarryFlag = ((_oldValue & 0xF) + (_signedValue & 0xF)) > 0xF;
                }
                else
                {
                    cpuState.Registers.CarryFlag     = (cpuState.StackPointer & 0xFF) <= (_oldValue & 0xFF);
                    cpuState.Registers.HalfCarryFlag = (cpuState.StackPointer & 0xF) <= (_oldValue & 0xF);
                }

                cpuState.Registers.ZeroFlag        = false;
                cpuState.Registers.SubtractionFlag = false;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #12
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _currentData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 2:
                _hiBit = _currentData & 0x80;
                _loBit = _currentData & 0x01;

                _writeData  = (byte)(_currentData >> 1);
                _writeData |= (byte)_hiBit;

                mainMemory.WriteByte(cpuState.Registers.HL, _writeData);

                cpuState.Registers.CarryFlag       = _loBit == 0x01;
                cpuState.Registers.ZeroFlag        = _writeData == 0;
                cpuState.Registers.HalfCarryFlag   = false;
                cpuState.Registers.SubtractionFlag = false;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #13
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _subData = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 1:
                var oldValue = cpuState.Registers.A;

                cpuState.Registers.A -= _subData;

                if (cpuState.Registers.CarryFlag)
                {
                    cpuState.Registers.A--;
                }

                cpuState.Registers.SubtractionFlag = true;
                cpuState.Registers.ZeroFlag        = cpuState.Registers.A == 0;
                cpuState.Registers.HalfCarryFlag   = ((_subData & 0x0F)
                                                      + (cpuState.Registers.CarryFlag ? 1 : 0)) > (oldValue & 0xF);
                cpuState.Registers.CarryFlag = (_subData + (cpuState.Registers.CarryFlag ? 1 : 0)) > oldValue;

                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #14
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 4:
                _address = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 3:
                _address |= (ushort)(mainMemory.ReadByte(cpuState.ProgramCounter++) << 8);
                break;

            case 2:
                mainMemory.WriteByte(_address, cpuState.Registers.A);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #15
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _registerBits = (byte)((_opcode >> 4) & 0x03);

                var lsbData = mainMemory.ReadByte(cpuState.StackPointer++);
                WriteToRegister(cpuState, lsbData, true);
                break;

            case 2:
                var msbData = mainMemory.ReadByte(cpuState.StackPointer++);
                WriteToRegister(cpuState, msbData, false);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #16
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                cpuState.Registers.A = mainMemory.ReadByte((ushort)((0xFF << 8) | cpuState.Registers.C));
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #17
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _registerBits = (byte)((_opcode >> 4) & 0x03);

                _loadData = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 2:
                _loadData |= (ushort)(mainMemory.ReadByte(cpuState.ProgramCounter++) << 8);
                break;

            case 1:
                switch (_registerBits)
                {
                case 0b00:
                    cpuState.Registers.BC = _loadData;
                    break;

                case 0b01:
                    cpuState.Registers.DE = _loadData;
                    break;

                case 0b10:
                    cpuState.Registers.HL = _loadData;
                    break;

                case 0b11:
                    cpuState.StackPointer = _loadData;
                    break;
                }
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #18
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _loadData = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 2:
                mainMemory.WriteByte(cpuState.Registers.HL, _loadData);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #19
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _loadData = mainMemory.ReadByte(cpuState.Registers.BC);
                break;

            case 1:
                cpuState.Registers.A = _loadData;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #20
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _registerIndex = (_opcode >> 3) & 0x07;

                _loadData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 1:
                cpuState.Registers[_registerIndex] = _loadData;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #21
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                //read jump address lsb
                _relativeAddress = (sbyte)mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 1:
                //do the jump
                cpuState.ProgramCounter = (ushort)(cpuState.ProgramCounter + _relativeAddress);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #22
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _currentData = mainMemory.ReadByte(cpuState.Registers.HL);

                var bitIndex = (_opcode & 0x38) >> 3;
                _writeData = (byte)(_currentData & ~(0x01 << bitIndex));
                break;

            case 2:
                mainMemory.WriteByte(cpuState.Registers.HL, _writeData);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #23
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _currentData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 1:
                var bitIndex = (_opcode & 0x38) >> 3;
                cpuState.Registers.ZeroFlag = ((byte)(_currentData >> bitIndex) & 0x01) == 0;

                cpuState.Registers.HalfCarryFlag   = true;
                cpuState.Registers.SubtractionFlag = false;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #24
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _subData = mainMemory.ReadByte(cpuState.ProgramCounter++);
                break;

            case 1:
                cpuState.Registers.SubtractionFlag = true;
                cpuState.Registers.ZeroFlag        = cpuState.Registers.A - _subData == 0;
                cpuState.Registers.HalfCarryFlag   = ((cpuState.Registers.A & 0xF) - (_subData & 0xF)) < 0;
                cpuState.Registers.CarryFlag       = _subData > cpuState.Registers.A;

                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #25
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _data = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 1:
                cpuState.Registers.A |= _data;
                break;
            }

            cpuState.Registers.SubtractionFlag = false;
            cpuState.Registers.ZeroFlag        = cpuState.Registers.A == 0;
            cpuState.Registers.HalfCarryFlag   = false;
            cpuState.Registers.CarryFlag       = false;

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #26
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                _currentData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 2:
                _decrementedData = (byte)(_currentData - 1);
                mainMemory.WriteByte(cpuState.Registers.HL, _decrementedData);
                break;

            case 1:
                cpuState.Registers.ZeroFlag        = _decrementedData == 0;
                cpuState.Registers.SubtractionFlag = true;
                cpuState.Registers.HalfCarryFlag   = (_currentData & 0x0F) == 0;
                break;
            }
            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #27
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _addData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 1:
                var oldValue = cpuState.Registers.A;

                cpuState.Registers.A += _addData;

                cpuState.Registers.SubtractionFlag = false;
                cpuState.Registers.ZeroFlag        = cpuState.Registers.A == 0;
                cpuState.Registers.HalfCarryFlag   = (((oldValue & 0xF) + (_addData & 0xF)) & 0x10) == 0x10;
                cpuState.Registers.CarryFlag       = cpuState.Registers.A < oldValue;

                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #28
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _subData = mainMemory.ReadByte(cpuState.Registers.HL);
                break;

            case 1:
                var oldValue = cpuState.Registers.A;

                cpuState.Registers.A -= _subData;

                cpuState.Registers.SubtractionFlag = true;
                cpuState.Registers.ZeroFlag        = cpuState.Registers.A == 0;
                cpuState.Registers.HalfCarryFlag   = ((oldValue & 0xF) - (_subData & 0xF)) < 0;
                cpuState.Registers.CarryFlag       = _subData > oldValue;

                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
Beispiel #29
0
 public byte MemoryRead(ushort address)
 {
     return(_mainMemory.ReadByte(address));
 }
Beispiel #30
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 3:
                mainMemory.WriteByte(--cpuState.StackPointer, (byte)(cpuState.ProgramCounter >> 8));
                break;

            case 2:
                mainMemory.WriteByte(--cpuState.StackPointer, (byte)(cpuState.ProgramCounter & 0x00FF));
                break;

            case 1:
                var interruptFlags = mainMemory.ReadByte(MiscRegisters.InterruptFlags);

                //vblank interrupt
                if ((_readyInterrupts & 0x01) == 0x01)
                {
                    //Console.WriteLine("Loading vblank isr...");

                    cpuState.ProgramCounter = InterruptAddresses.VblankInterrupt;

                    mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(interruptFlags & 0xFE));
                }

                //lcd stat interrupt
                else if ((_readyInterrupts & 0x02) == 0x02)
                {
                    //Console.WriteLine("Loading lcd stat isr...");

                    cpuState.ProgramCounter = InterruptAddresses.LcdInterrupt;

                    //clear interrupt flag
                    mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(interruptFlags & 0xFD));
                }

                //timer interrupt
                else if ((_readyInterrupts & 0x04) == 0x04)
                {
                    //Console.WriteLine("Loading timer isr...");

                    cpuState.ProgramCounter = InterruptAddresses.TimerInterrupt;

                    //clear interrupt flag
                    mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(interruptFlags & 0xFB));
                }

                //serial interrupt
                else if ((_readyInterrupts & 0x08) == 0x08)
                {
                    cpuState.ProgramCounter = InterruptAddresses.SerialInterrupt;

                    //clear interrupt flag
                    mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(interruptFlags & 0xF7));
                }

                //joypad interrupt
                else if ((_readyInterrupts & 0x10) == 0x10)
                {
                    cpuState.ProgramCounter = InterruptAddresses.JoypadInterrupt;

                    //clear interrupt flag
                    mainMemory.WriteByte(MiscRegisters.InterruptFlags, (byte)(interruptFlags & 0x0F));
                }

                cpuState.InterruptMasterEnable = false;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }