예제 #1
0
        public void ScheduledUpdate()
        {
            /*
             * // You cannot support this until you are cycle accurate otherwise dma's mess up
             * if (DelayTransfer > 0)
             * {
             *  DelayTransfer--;
             *  return;
             * }
             */

            ScheduledUpdateOnCycle = 0xFFFFFFFF;

            if (DmaCnt.ChannelEnabled == false)
            {
                return;
            }

            //if(DmaCnt.StartTiming != DmaControlRegister.DmaStartTiming.Special)
            //{
            //    gba.LogMessage(String.Format("DMA: Ch: {0} Source 0x{1:X} Dest 0x{2:X} Size 0x{3:X}", channelNumber, SourceAddress, DestAddress, WordCount));
            //}

            switch (DmaCnt.StartTiming)
            {
            case DmaControlRegister.DmaStartTiming.Immediate:
                Transfer();
                break;

            case DmaControlRegister.DmaStartTiming.VBblank:
                throw new ArgumentException("vblank dma");

            case DmaControlRegister.DmaStartTiming.HBlank:
                if (Started)
                {
                    Transfer();
                    Started = false;
                }
                break;

            case DmaControlRegister.DmaStartTiming.Special:

                if (channelNumber == 1 || channelNumber == 2)
                {
                    //Transfer();
                }
                else
                {
                    gba.LogMessage("WARNING: Invalid DmaStartTiming.Special");
                }
                break;

            default:
                throw new ArgumentException("Bad Dma start timing");
            }
        }
예제 #2
0
파일: Memory.cs 프로젝트: Y2JB/Y2Gba
        public byte ReadByte(UInt32 address)
        {
            // ROM
            //if (address >= 0x08000000 && address <= 0x0DFFFFFF)
            // E???????
            if (address >= 0x08000000 && address <= 0x9FFFEFF)
            {
                address &= 0x1FFFFFF;
                if (address < gba.Rom.RomSize)
                {
                    return(gba.Rom.ReadByte(address));
                }
                else
                {
                    //throw new NotImplementedException();
                    return(0);
                    //return open_bus(cpu->pc);
                }
            }
            // BIOS
            else if (address >= 0x00000000 && address <= 0x00003FFF)
            {
                return(gba.Bios.ReadByte(address));
            }
            // IO Registers
            else if (address >= 0x04000000 && address <= 0x040003FE)
            {
                IMemoryRegister8 register;
                if (IoRegisters8Read.TryGetValue(address, out register))
                {
                    return(register.Value);
                }
                else
                {
                    // TODO: this should throw?
                    return(ioReg[address - 0x04000000]);
                }
            }
            // Fast Cpu linked RAM
            else if (address >= 0x03000000 && address <= 0x03FFFFFF)
            {
                address &= 0x7FFF;
                return(IWRam[address]);
            }
            // RAM
            else if (address >= 0x02000000 && address <= 0x02FFFFFF)
            {
                address &= 0x3FFFF;
                return(EWRam[address]);
            }
            // Palette Ram
            else if (address >= 0x05000000 && address <= 0x050003FF)
            {
                // TODO : Mirroring!
                return(gba.LcdController.Palettes.PaletteRam[address - 0x05000000]);
            }
            // VRam
            //else if (address >= 0x06000000 && address <= 0x06017FFF)
            else if (address >= 0x06000000 && address <= 0x06FFFFFF)
            {
                address = address & (0x17FFF | (~address & 0x10000) >> 1);
                return(vram[address]);
            }
            // OAM Ram
            else if (address >= 0x07000000 && address <= 0x07FFFFFF)
            {
                address &= 0x3FF;
                return(OamRam[address]);
            }

            else if ((address >= 0xD000000) && (address <= 0xDFFFFFF))
            {
                if (address == 0xDFFFF00)
                {
                    return(1);
                }
                return(0xFF);
            }

            // Flash & SRAM
            else if (address >= 0x0E000000 && address <= 0x0E00FFFF)
            {
                // SRAM
                if (gba.Rom.SaveGameBackupType == Rom.BackupType.SRAM)
                {
                    return(gba.Rom.SRam[address - 0xE000000]);
                }
                // Flash
                else
                {
                    // Specifically to get Pokemon Emerald to run without flash ram support ....
                    // In your memory bus, simply return the following values on 8 - bit reads to the specified addresses.
                    // 8 - bit read address  Value Meaning
                    // 0x0E000000  0x62    Sanyo manufacturer ID
                    // 0x0E000001  0x13    Sanyo device ID
                    if (address == 0x0E000000)
                    {
                        return(0x62);
                    }
                    else if (address == 0x0E000001)
                    {
                        return(0x13);
                    }

                    // If a game does not support SRAM, it should return 0xFF if an access is attempted. Some games try this as a form of copy protection!
                    return(0xFF);
                }
            }

            else
            {
                gba.LogMessage(String.Format("BAD MEMORY READ - Unknown address {0:X}", address));
                // Bad memory reads resolve to an Open Bus read. See Gbatek section on 'unpredictable things'
                // The open bus value is resolved in the 'checked' functions below
                return(0);

                /*
                 * int instructionPtr = gba.Cpu.NextPipelineInsturction + 2;
                 * if (instructionPtr >= Cpu.Pipeline_Size) instructionPtr -= Cpu.Pipeline_Size;
                 *
                 * if (gba.Cpu.State == Cpu.CpuState.Arm)
                 * {
                 *      // Accessing unused memory at 00004000h - 01FFFFFFh, and 10000000h - FFFFFFFFh(and 02000000h - 03FFFFFFh when RAM is disabled via
                 *      // Port 4000800h) returns the recently pre-fetched opcode.For ARM code this is simply:
                 *      // WORD = [$+8]
                 *
                 *      // This is untested!
                 *      UInt32 byteNumber = address % 4;
                 *      byte b = (byte)(gba.Cpu.InstructionPipeline[instructionPtr] >> (int)(byteNumber * 8));
                 *      return (byte) (b & 0xFF);
                 * }
                 * else
                 * {
                 *      // There are multiple cases for resiolving this for thuimb. FOr now i've gone with the main one:
                 *      // For THUMB code in Main RAM, Palette Memory, VRAM, and Cartridge ROM this is:
                 *      // LSW = [$+4], MSW = [$+4]
                 *      // When code is executing in Palette ram (wtf) and other crazy places, we will need to revisit this
                 *
                 *      UInt32 byteNumber = address % 2;
                 *      byte b = (byte)(gba.Cpu.InstructionPipeline[instructionPtr] >> (int)(byteNumber * 8));
                 *      return (byte)(b & 0xFF);
                 * }
                 *
                 * throw new ArgumentException("Bad Memory Read");
                 */
            }
        }