예제 #1
0
        public ExecutionResult Execute(Processor cpu, InstructionPackage package)
        {
            Instruction     instruction = package.Instruction;
            InstructionData data        = package.Data;
            Flags           flags       = cpu.Flags;
            Registers       r           = cpu.Registers;

            sbyte        offset        = (sbyte)(data.Argument1);
            ByteRegister register      = instruction.Target.AsByteRegister();
            bool         previousCarry = flags.Carry;

            byte original, shifted;

            if (register != ByteRegister.None)
            {
                original = r[register];
                shifted  = (byte)(original >> 1);
                shifted  = shifted.SetBit(7, previousCarry);
                setFlags(original, shifted, original.GetBit(0));
                r[register] = shifted;
            }
            else
            {
                ushort address = instruction.Prefix switch
                {
                    0xCB => r.HL,
                    0xDDCB => (ushort)(r.IX + offset),
                    0xFDCB => (ushort)(r.IY + offset),
                    _ => (ushort)0xFFFF
                };
                original = cpu.Memory.Timed.ReadByteAt(address);
                shifted  = (byte)(original >> 1);
                shifted  = shifted.SetBit(7, previousCarry);
                setFlags(original, shifted, original.GetBit(0));
                if (instruction.IsIndexed)
                {
                    cpu.Timing.InternalOperationCycle(4);
                }
                cpu.Memory.Timed.WriteByteAt(address, shifted);
                if (instruction.CopyResultTo != ByteRegister.None)
                {
                    r[instruction.CopyResultTo.Value] = shifted;
                }
            }

            void setFlags(byte original, byte shifted, bool overflowBit)
            {
                flags           = FlagLookup.BitwiseFlags(original, BitwiseOperation.RotateRightThroughCarry, previousCarry);
                flags.Carry     = overflowBit;
                flags.HalfCarry = false;
                flags.Subtract  = false;
            }

            return(new ExecutionResult(package, flags));
        }
예제 #2
0
        public ExecutionResult Execute(Processor cpu, InstructionPackage package)
        {
            Instruction     instruction = package.Instruction;
            InstructionData data        = package.Data;
            Registers       r           = cpu.Registers;
            Flags           flags       = cpu.Flags;

            int result = 0x00 - r.A;

            flags = FlagLookup.ByteArithmeticFlags(0x00, r.A, false, true);
            flags.ParityOverflow = r.A == 0x80;
            flags.Carry          = r.A != 0x00;
            r.A = (byte)result;

            return(new ExecutionResult(package, flags));
        }
예제 #3
0
파일: SLL.cs 프로젝트: neilhewitt/Zem80
        public ExecutionResult Execute(Processor cpu, InstructionPackage package)
        {
            Instruction instruction = package.Instruction;
            InstructionData data = package.Data;
            Flags flags = cpu.Flags;
            Registers r = cpu.Registers;
            sbyte offset = (sbyte)(data.Argument1);
            ByteRegister register = instruction.Target.AsByteRegister();

            void setFlags(byte original)
            {
                flags = FlagLookup.BitwiseFlags(original, BitwiseOperation.ShiftLeftSetBit0, flags.Carry);
                flags.Carry = original.GetBit(7);
                flags.HalfCarry = false;
                flags.Subtract = false;
            }

            byte original, shifted;
            if (register != ByteRegister.None)
            {
                original = r[register];
                shifted = (byte)((original << 1) + 1); // bit 0 is always set, adding 1 does this quicker than calling SetBit
                setFlags(original);
                r[register] = shifted;
            }
            else
            {
                ushort address = instruction.Prefix switch
                {
                    0xCB => r.HL,
                    0xDDCB => (ushort)(r.IX + offset),
                    0xFDCB => (ushort)(r.IY + offset),
                    _ => (ushort)0xFFFF
                };
                original = cpu.Memory.Timed.ReadByteAt(address);
                shifted = (byte)((original << 1) + 1);
                setFlags(original);
                cpu.Memory.Timed.WriteByteAt(address, shifted);
                if (instruction.CopyResultTo != ByteRegister.None)
                {
                    r[instruction.CopyResultTo.Value] = shifted;
                }
            }

            return new ExecutionResult(package, flags);
        }
예제 #4
0
        public ExecutionResult Execute(Processor cpu, InstructionPackage package)
        {
            Instruction     instruction = package.Instruction;
            InstructionData data        = package.Data;
            Registers       r           = cpu.Registers;
            byte            offset      = data.Argument1;
            Flags           flags       = cpu.Flags;

            if (instruction.TargetsWordRegister)
            {
                // inc 16-bit
                WordRegister register = instruction.Target.AsWordRegister();
                ushort       value    = r[register];
                r[register] = (ushort)(value + 1);
            }
            else
            {
                byte value = 0;
                if (instruction.TargetsByteInMemory)
                {
                    // inc byte in memory
                    if (instruction.IsIndexed)
                    {
                        cpu.Timing.InternalOperationCycle(5);
                    }
                    value = instruction.MarshalSourceByte(data, cpu, out ushort address, out ByteRegister source);
                    cpu.Memory.Timed.WriteByteAt(address, (byte)(value + 1));
                }
                else
                {
                    // it's an 8-bit inc
                    ByteRegister register = instruction.Target.AsByteRegister();
                    value       = r[register];
                    r[register] = (byte)(value + 1);
                }

                bool carry = flags.Carry;
                flags = FlagLookup.ByteArithmeticFlags(value, 1, false, false);
                flags.ParityOverflow = (value == 0x7F);
                flags.Carry          = carry; // always unaffected
                flags.Subtract       = false;
            }

            return(new ExecutionResult(package, flags));
        }
예제 #5
0
파일: OR.cs 프로젝트: neilhewitt/Zem80
        public ExecutionResult Execute(Processor cpu, InstructionPackage package)
        {
            Instruction     instruction = package.Instruction;
            InstructionData data        = package.Data;
            Flags           flags       = cpu.Flags;
            Registers       r           = cpu.Registers;

            if (instruction.IsIndexed)
            {
                cpu.Timing.InternalOperationCycle(5);
            }
            byte operand = instruction.MarshalSourceByte(data, cpu, out ushort address, out ByteRegister source);
            int  result  = (r.A | operand);

            flags = FlagLookup.LogicalFlags(r.A, operand, LogicalOperation.Or);
            r.A   = (byte)result;

            return(new ExecutionResult(package, flags));
        }
예제 #6
0
        public static (byte Result, Flags Flags) Add(byte left, byte right, bool carry)
        {
            Flags flags = FlagLookup.ByteArithmeticFlags(left, right, carry, false);

            return((byte)(left + right + (carry ? 1 : 0)), flags);
        }
예제 #7
0
        public static (ushort Result, Flags Flags) Subtract(ushort left, ushort right, bool carry, bool setSZPV, Flags currentFlags)
        {
            Flags flags = FlagLookup.WordArithmeticFlags(currentFlags, left, right, carry, setSZPV, true);

            return((ushort)(left - right - (carry ? 1 : 0)), flags);
        }
예제 #8
0
        public static (ushort Result, Flags Flags) Add(ushort left, ushort right, bool carry, bool setSZPV, Flags currentFlags)
        {
            Flags flags = FlagLookup.WordArithmeticFlags(currentFlags, left, right, carry, setSZPV, false);

            return((ushort)(left + right + (carry ? 1 : 0)), flags);
        }
예제 #9
0
        public static (byte Result, Flags Flags) Subtract(byte left, byte right, bool carry)
        {
            Flags flags = FlagLookup.ByteArithmeticFlags(left, right, carry, true);

            return((byte)(left - right - (carry ? 1 : 0)), flags);
        }