Exemplo n.º 1
0
        public void ExecuteJumpReturn(byte instruction, AddressModes addressMode, int signature)
        {
            RegisterBankNumber fakeBank = new RegisterBankNumber
            {
                Value = cpu.PC >> 16
            };
            int addr = GetAddress(addressMode, signature, fakeBank);

            switch (instruction)
            {
            case OpcodeList.JSR_Absolute:
            case OpcodeList.JSR_AbsoluteIndexedIndirectWithX:
                cpu.Push(cpu.PC - 1, 2);
                cpu.JumpLong(addr);
                return;

            case OpcodeList.JSR_AbsoluteLong:
                cpu.Push(cpu.PC - 1, 3);
                cpu.JumpLong(addr);
                return;

            case OpcodeList.JMP_Absolute:
            case OpcodeList.JMP_AbsoluteLong:
            case OpcodeList.JMP_AbsoluteIndirect:
            case OpcodeList.JMP_AbsoluteIndexedIndirectWithX:
            case OpcodeList.JMP_AbsoluteIndirectLong:
                cpu.JumpLong(addr);
                return;

            // RTS, RTL, RTI
            case OpcodeList.RTI_StackImplied:
                cpu.Flags.SetFlags(cpu.Pull(1));
                cpu.SyncFlags();
                if (cpu.Flags.Emulation)
                {
                    cpu.JumpShort(cpu.Pull(2));
                }
                else
                {
                    cpu.JumpLong(cpu.Pull(3));
                }
                return;

            case OpcodeList.RTS_StackImplied:
                cpu.JumpShort(cpu.Pull(2) + 1);
                return;

            case OpcodeList.RTL_StackImplied:
                addr = cpu.Pull(3);
                cpu.JumpLong(addr + 1);
                return;

            default:
                throw new NotImplementedException("ExecuteJumpReturn() opcode not implemented: " + instruction.ToString("X2"));
            }
        }
Exemplo n.º 2
0
        private int GetAddress(AddressModes addressMode, int SignatureBytes, RegisterBankNumber Bank)
        {
            int addr = 0;
            int ptr  = 0;

            switch (addressMode)
            {
            // The address will not be used in Immediate or Implied mode, but
            case AddressModes.Immediate:
                return(ADDRESS_IMMEDIATE);

            case AddressModes.Implied:
                return(ADDRESS_IMPLIED);

            case AddressModes.Absolute:
                return(Bank.GetLongAddress(SignatureBytes));

            case AddressModes.AbsoluteLong:
                return(SignatureBytes);

            case AddressModes.AbsoluteIndexedWithX:
                return(Bank.GetLongAddress(SignatureBytes + cpu.X.Value));

            case AddressModes.AbsoluteLongIndexedWithX:
                return(SignatureBytes + cpu.X.Value);

            case AddressModes.AbsoluteIndexedWithY:
                return(Bank.GetLongAddress(SignatureBytes + cpu.Y.Value));

            case AddressModes.AbsoluteLongIndexedWithY:
                return(Bank.GetLongAddress(SignatureBytes + cpu.X.Value));

            case AddressModes.DirectPage:
                return(cpu.DirectPage.GetLongAddress(SignatureBytes));

            case AddressModes.DirectPageIndexedWithX:
                return(cpu.DirectPage.GetLongAddress(SignatureBytes + cpu.X.Value));

            case AddressModes.DirectPageIndexedWithY:
                return(cpu.DirectPage.GetLongAddress(SignatureBytes + cpu.Y.Value));

            case AddressModes.DirectPageIndexedIndirectWithX:
                addr = cpu.DirectPage.GetLongAddress(SignatureBytes) + cpu.X.Value;
                ptr  = cpu.MemMgr.ReadWord(addr);
                //return cpu.ProgramBank.GetLongAddress(ptr);
                return((cpu.PC & 0xFF_0000) + ptr);

            case AddressModes.DirectPageIndirect:
                addr = cpu.DirectPage.GetLongAddress(SignatureBytes);
                ptr  = cpu.MemMgr.ReadWord(addr);
                return(cpu.DataBank.GetLongAddress(ptr));

            case AddressModes.DirectPageIndirectIndexedWithY:
                addr = cpu.DirectPage.GetLongAddress(SignatureBytes);
                ptr  = cpu.MemMgr.ReadWord(addr) + cpu.Y.Value;
                //return cpu.ProgramBank.GetLongAddress(ptr);
                return((cpu.PC & 0xFF_0000) + ptr);

            case AddressModes.DirectPageIndirectLong:
                addr = cpu.DirectPage.GetLongAddress(SignatureBytes);
                ptr  = cpu.MemMgr.ReadLong(addr);
                return(ptr);

            case AddressModes.DirectPageIndirectLongIndexedWithY:
                addr = cpu.DirectPage.GetLongAddress(SignatureBytes);
                ptr  = cpu.MemMgr.ReadLong(addr) + cpu.Y.Value;
                return(ptr);

            case AddressModes.ProgramCounterRelative:
                ptr  = MakeSignedByte((byte)SignatureBytes);
                addr = cpu.PC + ptr;
                return(addr);

            case AddressModes.ProgramCounterRelativeLong:
                ptr  = MakeSignedInt((UInt16)SignatureBytes);
                addr = cpu.PC + ptr;
                return(addr);

            case AddressModes.StackImplied:
                //case AddressModes.StackAbsolute:
                return(0);

            case AddressModes.StackDirectPageIndirect:
                return(cpu.DirectPage.GetLongAddress(SignatureBytes));

            case AddressModes.StackRelative:
                return(cpu.Stack.Value + SignatureBytes);

            case AddressModes.StackRelativeIndirectIndexedWithY:
                int bankOffset = Bank.Value << 16;
                addr = bankOffset + (cpu.Stack.Value + SignatureBytes);
                return(bankOffset + cpu.MemMgr.ReadWord(addr) + cpu.Y.Value);

            case AddressModes.StackProgramCounterRelativeLong:
                return(SignatureBytes);

            // Jump and JSR indirect references vectors located in Bank 0
            case AddressModes.JmpAbsoluteIndirect:
                addr = SignatureBytes;
                ptr  = cpu.MemMgr.ReadWord(addr);
                //return cpu.ProgramBank.GetLongAddress(ptr);
                return((cpu.PC & 0xFF_0000) + ptr);

            case AddressModes.JmpAbsoluteIndirectLong:
                addr = SignatureBytes;
                ptr  = cpu.MemMgr.ReadLong(addr);
                return(ptr);

            case AddressModes.JmpAbsoluteIndexedIndirectWithX:
                addr = SignatureBytes + cpu.X.Value;
                //ptr = cpu.Memory.ReadWord(cpu.ProgramBank.GetLongAddress(addr));
                ptr = cpu.MemMgr.ReadWord((cpu.PC & 0xFF_0000) + addr);
                //return cpu.ProgramBank.GetLongAddress(ptr);
                return((cpu.PC & 0xFF_0000) + ptr);

            case AddressModes.Accumulator:
                return(0);

            default:
                throw new NotImplementedException("GetAddress() Address mode not implemented: " + addressMode.ToString());
            }
        }