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"); } }
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"); */ } }