예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
0
        private void LoadWriteData(ICpuState cpuState)
        {
            switch (_registerBits)
            {
            case 0b00:
                _msbData = cpuState.Registers.B;
                _lsbData = cpuState.Registers.C;
                break;

            case 0b01:
                _msbData = cpuState.Registers.D;
                _lsbData = cpuState.Registers.E;
                break;

            case 0b10:
                _msbData = cpuState.Registers.H;
                _lsbData = cpuState.Registers.L;
                break;

            case 0b11:
                _msbData = cpuState.Registers.A;
                _lsbData = cpuState.Registers.F;
                break;
            }
        }
예제 #8
0
파일: DI.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            cpuState.InterruptMasterEnable = false;
            cpuState.ImeScheduled          = false;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #9
0
파일: RST.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 4:
                //calculate jump address
                _jumpAddress = (ushort)(_opcode & 0x38);
                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);
        }
예제 #10
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                _registerBits = (byte)((_opcode >> 4) & 0x03);
                break;

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

                case 0b01:
                    cpuState.Registers.DE++;
                    break;

                case 0b10:
                    cpuState.Registers.HL++;
                    break;

                case 0b11:
                    cpuState.StackPointer++;
                    break;
                }
                break;
            }
            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #11
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            //set prefix flag in cpu state
            cpuState.InstructionPrefix = true;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #12
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);
        }
예제 #13
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);
        }
예제 #14
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            if (!cpuState.Registers.SubtractionFlag)
            {
                if (cpuState.Registers.CarryFlag || cpuState.Registers.A > 0x99)
                {
                    cpuState.Registers.A        += 0x60;
                    cpuState.Registers.CarryFlag = true;
                }

                if (cpuState.Registers.HalfCarryFlag || (cpuState.Registers.A & 0x0f) > 0x09)
                {
                    cpuState.Registers.A += 0x6;
                }
            }
            else
            {
                if (cpuState.Registers.CarryFlag)
                {
                    cpuState.Registers.A -= 0x60;
                }

                if (cpuState.Registers.HalfCarryFlag)
                {
                    cpuState.Registers.A -= 0x6;
                }
            }

            cpuState.Registers.HalfCarryFlag = false;
            cpuState.Registers.ZeroFlag      = cpuState.Registers.A == 0;
            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #15
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);
        }
예제 #16
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);
        }
예제 #17
0
파일: SCF.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            cpuState.Registers.CarryFlag       = true;
            cpuState.Registers.HalfCarryFlag   = false;
            cpuState.Registers.SubtractionFlag = false;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #18
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            //decode register and bit
            var bitIndex      = (_opcode & 0x38) >> 3;
            var registerIndex = _opcode & 0x07;

            cpuState.Registers[registerIndex] = (ushort)(cpuState.Registers[registerIndex] & ~(0x01 << bitIndex));

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #19
0
파일: DECR8.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            var registerIndex = _opcode >> 3;
            var oldValue      = cpuState.Registers[registerIndex]--;

            cpuState.Registers.SubtractionFlag = true;
            cpuState.Registers.ZeroFlag        = cpuState.Registers[registerIndex] == 0;
            cpuState.Registers.HalfCarryFlag   = (oldValue & 0x0F) == 0;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #20
0
파일: CPAR8.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            var registerIndex = _opcode & 0x07;

            cpuState.Registers.SubtractionFlag = true;
            cpuState.Registers.ZeroFlag        = cpuState.Registers.A - (byte)cpuState.Registers[registerIndex] == 0;
            cpuState.Registers.HalfCarryFlag   = ((cpuState.Registers.A & 0xF) - (cpuState.Registers[registerIndex] & 0xF)) < 0;
            cpuState.Registers.CarryFlag       = (byte)cpuState.Registers[registerIndex] > cpuState.Registers.A;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #21
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 1:
                cpuState.StackPointer = cpuState.Registers.HL;
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #22
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);
        }
예제 #23
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            //register decoding
            var sourceIndex = _opcode & 0x07;
            var targetIndex = (_opcode >> 3) & 0x07;

            //load
            cpuState.Registers[targetIndex] = cpuState.Registers[sourceIndex];

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #24
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                mainMemory.WriteByte(cpuState.Registers.BC, cpuState.Registers.A);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #25
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            switch (_remainingCycles)
            {
            case 2:
                var registerIndex = _opcode & 0x07;
                mainMemory.WriteByte(cpuState.Registers.HL, (byte)cpuState.Registers[registerIndex]);
                break;
            }

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #26
0
        protected bool IsConditionMet(ICpuState cpuState)
        {
            var condition = _opcode & 0x18;

            return(condition switch
            {
                0x00 => !cpuState.Registers.ZeroFlag,
                0x08 => cpuState.Registers.ZeroFlag,
                0x10 => !cpuState.Registers.CarryFlag,
                0x18 => cpuState.Registers.CarryFlag,
                _ => throw new InvalidOperationException($"Unexpected behavior for conditional opcode 0x{_opcode:X2} with condition 0x{condition:X2}"),
            });
예제 #27
0
파일: ORAR8.cs 프로젝트: Briensturm/BremuGb
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            var registerIndex = _opcode & 0x07;

            cpuState.Registers.A |= (byte)cpuState.Registers[registerIndex];

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

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #28
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            cpuState.Registers.HalfCarryFlag   = true;
            cpuState.Registers.SubtractionFlag = false;

            //decode register and bit
            var bitIndex      = (_opcode & 0x38) >> 3;
            var registerIndex = _opcode & 0x07;

            cpuState.Registers.ZeroFlag = ((byte)(cpuState.Registers[registerIndex] >> bitIndex) & 0x01) == 0;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #29
0
        public override void ExecuteCycle(ICpuState cpuState, IRandomAccessMemory mainMemory)
        {
            cpuState.Registers.HalfCarryFlag   = false;
            cpuState.Registers.SubtractionFlag = false;

            var bit = cpuState.Registers[_opcode] >> 7;

            cpuState.Registers.CarryFlag = bit == 1;

            cpuState.Registers[_opcode] = (ushort)((cpuState.Registers[_opcode] << 1) | bit);
            cpuState.Registers.ZeroFlag = cpuState.Registers[_opcode] == 0;

            base.ExecuteCycle(cpuState, mainMemory);
        }
예제 #30
0
        private void WriteToRegister(ICpuState cpuState, byte data, bool isLsb)
        {
            switch (_registerBits)
            {
            case 0b00:
                if (isLsb)
                {
                    cpuState.Registers.C = data;
                }
                else
                {
                    cpuState.Registers.B = data;
                }
                break;

            case 0b01:
                if (isLsb)
                {
                    cpuState.Registers.E = data;
                }
                else
                {
                    cpuState.Registers.D = data;
                }
                break;

            case 0b10:
                if (isLsb)
                {
                    cpuState.Registers.L = data;
                }
                else
                {
                    cpuState.Registers.H = data;
                }
                break;

            case 0b11:
                if (isLsb)
                {
                    cpuState.Registers.F = data;
                }
                else
                {
                    cpuState.Registers.A = data;
                }
                break;
            }
        }