Beispiel #1
0
        public static void SetValueOnProcessor(this WideRegister register, Z80Cpu cpu, ushort value)
        {
            switch (register)
            {
            case WideRegister.AF:
                cpu.A     = (byte)((value & 0xff00) >> 8);
                cpu.Flags = (Z80Flags)(value & 0xff);
                break;

            case WideRegister.BC:
                cpu.B = (byte)((value & 0xff00) >> 8);
                cpu.C = (byte)(value & 0xff);
                break;

            case WideRegister.DE:
                cpu.D = (byte)((value & 0xff00) >> 8);
                cpu.E = (byte)(value & 0xff);
                break;

            case WideRegister.HL:
                cpu.H = (byte)((value & 0xff00) >> 8);
                cpu.L = (byte)(value & 0xff);
                break;

            case WideRegister.SP:
                cpu.SP = value;
                break;

            case WideRegister.IX:
                cpu.IX = value;
                break;

            case WideRegister.IY:
                cpu.IY = value;
                break;

            case WideRegister.AF_:
                cpu.AF_ = value;
                break;

            case WideRegister.BC_:
                cpu.BC_ = value;
                break;

            case WideRegister.DE_:
                cpu.DE_ = value;
                break;

            case WideRegister.HL_:
                cpu.HL_ = value;
                break;

            case WideRegister.PC:
                cpu.PC = value;
                break;

            default:
                throw new InvalidOperationException($"Invalid register value: {register}");
            }
        }
Beispiel #2
0
        private WideRegister GetExchangeRegister(WideRegister register)
        {
            if (_exchangeRegister != WideRegister.None)
            {
                return(_exchangeRegister);
            }

            switch (register)
            {
            case WideRegister.AF:
                return(WideRegister.AF_);

            case WideRegister.BC:
                return(WideRegister.BC_);

            case WideRegister.DE:
                return(WideRegister.DE_);

            case WideRegister.HL:
                return(WideRegister.HL_);

            default:
                throw new InvalidOperationException("Unexpected register value for exchange");
            }
        }
Beispiel #3
0
 public Indexed(Z80Cpu cpu, WideRegister register, int internalCycleLength = 5, bool additionalCycleOnRead = false)
 {
     if (register != WideRegister.IX && register != WideRegister.IY)
     {
         throw new InvalidOperationException("Invald index register specified");
     }
     _register              = register;
     _cpu                   = cpu;
     _offsetReadCycle       = new MemReadCycle(cpu);
     _internalCycle         = new InternalCycle(internalCycleLength);
     _additionalCycleOnRead = additionalCycleOnRead;
 }
Beispiel #4
0
        public static ushort GetValue(this WideRegister register, Z80Cpu cpu)
        {
            switch (register)
            {
            case WideRegister.AF:
                return((ushort)(cpu.A << 8 | (byte)cpu.Flags));

            case WideRegister.BC:
                return((ushort)(cpu.B << 8 | cpu.C));

            case WideRegister.DE:
                return((ushort)(cpu.D << 8 | cpu.E));

            case WideRegister.HL:
                return((ushort)(cpu.H << 8 | cpu.L));

            case WideRegister.AF_:
                return(cpu.AF_);

            case WideRegister.BC_:
                return(cpu.BC_);

            case WideRegister.DE_:
                return(cpu.DE_);

            case WideRegister.HL_:
                return(cpu.HL_);

            case WideRegister.SP:
                return(cpu.SP);

            case WideRegister.IX:
                return(cpu.IX);

            case WideRegister.IY:
                return(cpu.IY);

            case WideRegister.PC:
                return(cpu.PC);

            default:
                throw new InvalidOperationException($"Invalid register value: {register}");
            }
        }
Beispiel #5
0
        public void LoadRegisterToRegisterPointer()
        {
            // Arrange
            WideRegister pointerRegister = WideRegister.BC;
            Register     source          = Register.A;
            byte         opcode          = 0x02;

            byte   loadValue = 0xe3;
            ushort pointer   = 0xdead;

            pointerRegister.SetValueOnProcessor(_cpu, pointer);
            source.SetValueOnProcessor(_cpu, loadValue);
            _ram[0] = opcode;

            // Act
            RunUntil(2);

            // Assert
            Assert.That(_ram[pointer], Is.EqualTo(loadValue));
        }
Beispiel #6
0
        public void LoadRegisterPointerToRegister()
        {
            // Arrange
            // Again these 3 can be parameterized
            Register     destination = Register.A;
            WideRegister source      = WideRegister.HL;
            byte         opcode      = 0x7e;

            byte   value   = 0x1f;
            ushort pointer = 0x0bad;

            source.SetValueOnProcessor(_cpu, pointer);
            _ram[0]       = opcode;
            _ram[pointer] = value;

            // Act
            RunUntil(2);

            // Assert
            Assert.That(destination.GetValue(_cpu), Is.EqualTo(value));
        }
Beispiel #7
0
        public void LoadImmediateToIndexedPointer()
        {
            // Arrange
            WideRegister indexRegister    = WideRegister.IX;
            byte         instructionByte1 = 0xdd;
            byte         instructionByte2 = 0x36;

            byte   loadValue = 0x86;
            ushort pointer   = 0xb00b;

            indexRegister.SetValueOnProcessor(_cpu, pointer);
            _ram[0] = instructionByte1;
            _ram[1] = instructionByte2;
            _ram[2] = 0xf;
            _ram[3] = loadValue;

            // Act
            RunUntil(5);

            // Assert
            Assert.That(_ram[pointer + 0xf], Is.EqualTo(loadValue));
        }
Beispiel #8
0
        public void LoadRegisterToIndexedPointer()
        {
            // Arrange
            WideRegister indexRegister    = WideRegister.IY;
            Register     source           = Register.E;
            byte         instructionByte1 = 0xfd;
            byte         instructionByte2 = 0x73;

            byte   loadValue = 0x28;
            ushort pointer   = 0xdeaf;

            indexRegister.SetValueOnProcessor(_cpu, pointer);
            source.SetValueOnProcessor(_cpu, loadValue);
            _ram[0] = instructionByte1;
            _ram[1] = instructionByte2;
            _ram[2] = 0x10;

            // Act
            RunUntil(4);

            // Assert
            Assert.That(_ram[pointer + 0x10], Is.EqualTo(loadValue));
        }
Beispiel #9
0
 public RegIndirect(Z80Cpu cpu, WideRegister register, bool additionalCycleOnRead = false)
 {
     _cpu      = cpu;
     _register = register;
     _additonalCycleOnReader = additionalCycleOnRead;
 }
Beispiel #10
0
 public ExchangeStack(Z80Cpu cpu, WideRegister exchangeRegister)
 {
     _cpu            = cpu;
     _targetRegister = exchangeRegister;
 }
Beispiel #11
0
 public Exchange(Z80Cpu cpu, WideRegister register, WideRegister exchangeRegister = WideRegister.None) : this(cpu, new[] { register })
 {
     _exchangeRegister = exchangeRegister;
 }
Beispiel #12
0
 public RegIndirectWide(Z80Cpu cpu, WideRegister register, bool decreasingAddress)
 {
     _decreasingAddress = decreasingAddress;
     _cpu      = cpu;
     _register = register;
 }
 public Action LD_D16(WideRegister p0, int duration) => () =>
 {
     var arg = Memory.FetchD16();
     Registers.Set(p0, arg);
     AddTicks(duration);
 };
Beispiel #14
0
 public POP(Z80Cpu cpu, WideRegister register) : base(cpu, new RegAddrMode16Bit(cpu, register), new RegIndirectWide(cpu, WideRegister.SP, false), additionalM1TCycles: 0)
 {
 }
Beispiel #15
0
 public PUSH(Z80Cpu cpu, WideRegister register, int additionalM1TCycles = 1) : base(cpu, new RegIndirectWide(cpu, WideRegister.SP, true), new RegAddrMode16Bit(cpu, register), additionalM1TCycles: additionalM1TCycles)
 {
 }
 public IndexedInstructionLookup(Z80Cpu cpu, WideRegister register)
 {
     _cpu                   = cpu;
     _addressMode           = new Indexed(cpu, register);
     _instructionTypeReader = new MemoryByteReader(cpu);
 }