private void OnExecMemory(ushort addr) { uint flags = (uint)(MemoryCallbackFlags.AccessExecute); MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); }
private void ExecFetch(ushort addr) { uint flags = (uint)MemoryCallbackFlags.AccessExecute; MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); }
public void WriteMemory(ushort addr, byte value) { if (MemoryCallbacks.HasWrites) { uint flags = (uint)Common.MemoryCallbackFlags.AccessWrite; MemoryCallbacks.CallMemoryCallbacks(addr, value, flags, "System Bus"); } if ((addr & 0xFCE0) == 0) { // return TIA registers or control register if it is still unlocked if ((A7800_control_register & 0x1) == 0) { A7800_control_register = value; } else { slow_access = true; tia.WriteMemory((ushort)(addr & 0x1F), value, false); } } else if ((addr & 0xFCE0) == 0x20) { if ((A7800_control_register & 0x2) > 0) { // register 8 is read only and controlled by Maria var temp = addr & 0x1F; if (temp != 8) { Maria_regs[temp] = value; } if (temp == 4) // WSYNC { cpu.RDY = false; } /* * for (int i = 0; i < 0x20; i++) * { * Console.Write(Maria_regs[i]); * Console.Write(" "); * } * Console.WriteLine(maria.scanline); */ } else { // TODO: What if Maria is off? } } else if ((addr & 0xFF80) == 0x280) { slow_access = true; m6532.WriteMemory(addr, value); } else if ((addr & 0xFE80) == 0x480) { slow_access = true; RAM_6532[addr & 0x7F] = value; } else if ((addr >= 0x1800) && (addr < 0x2800)) { RAM[addr - 0x1800] = value; } else if ((addr >= 0x40) && (addr < 0x100)) { // RAM block 0 RAM[addr - 0x40 + 0x840] = value; } else if ((addr >= 0x140) && (addr < 0x200)) { // RAM block 1 RAM[addr - 0x140 + 0x940] = value; } else if ((addr >= 0x2800) && (addr < 0x3000)) { // this mirror evidently does not exist on hardware despite being in the documentation //RAM[(addr & 0x7FF) + 0x800] = value; } else if ((addr >= 0x3000) && (addr < 0x4000)) { // could be either RAM mirror or ROM mapper.WriteMemory(addr, value); } else if ((addr >= 0x400) && (addr < 0x480)) { // cartridge space available mapper.WriteMemory(addr, value); } else if ((addr >= 0x500) && (addr < 0x1800)) { // cartridge space available mapper.WriteMemory(addr, value); } else { mapper.WriteMemory(addr, value); } }
public byte ReadMemory(ushort addr) { if (MemoryCallbacks.HasReads) { uint flags = (uint)Common.MemoryCallbackFlags.AccessRead; MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); } if ((addr & 0xFCE0) == 0) { // return TIA registers or control register if it is still unlocked if ((A7800_control_register & 0x1) == 0) { return(0xFF); // TODO: what to return here? } slow_access = true; return(tia.ReadMemory((ushort)(addr & 0x1F), false)); } if ((addr & 0xFCE0) == 0x20) { if ((A7800_control_register & 0x2) > 0) { return(Maria_regs[addr & 0x1F]); } else { return(0x80); // TODO: What if Maria is off? } } if ((addr & 0xFF80) == 0x280) { slow_access = true; return(m6532.ReadMemory(addr, false)); } if ((addr & 0xFE80) == 0x480) { slow_access = true; return(RAM_6532[addr & 0x7F]); } if ((addr >= 0x1800) && (addr < 0x2800)) { return(RAM[addr - 0x1800]); } if ((addr >= 0x40) && (addr < 0x100)) { // RAM block 0 return(RAM[addr - 0x40 + 0x840]); } if ((addr >= 0x140) && (addr < 0x200)) { // RAM block 1 return(RAM[addr - 0x140 + 0x940]); } if ((addr >= 0x2800) && (addr < 0x3000)) { // this mirror evidently does not exist on hardware despite being in the documentation // must return 0 or Summer Games will deadlock at event start screen return(0x0); // RAM[(addr & 0x7FF) + 0x800]; } if ((addr >= 0x3000) && (addr < 0x4000)) { // could be either RAM mirror or ROM return(mapper.ReadMemory(addr)); } if ((addr >= 0x400) && (addr < 0x480)) { // cartridge space available return(mapper.ReadMemory(addr)); } if ((addr >= 0x500) && (addr < 0x1800)) { // cartridge space available return(mapper.ReadMemory(addr)); } return(mapper.ReadMemory(addr)); }
private void WriteHook_SMP(uint addr, byte val) { uint flags = (uint)(MemoryCallbackFlags.AccessWrite); MemoryCallbacks.CallMemoryCallbacks(addr, val, flags, "SMP"); }
private void ExecHook_SMP(uint addr) { uint flags = (uint)(MemoryCallbackFlags.AccessExecute); MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "SMP"); }
private void ReadHook_SMP(uint addr) { uint flags = (uint)(MemoryCallbackFlags.AccessRead); MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "SMP"); }
public byte ReadMemory(ushort addr) { if (MemoryCallbacks.HasReads) { uint flags = (uint)MemoryCallbackFlags.AccessRead; MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); } addr_access = addr; if (ppu.DMA_start) { // some of gekkio's tests require these to be accessible during DMA if (addr < 0x8000) { if (ppu.DMA_addr < 0x80) { return(0xFF); } return(mapper.ReadMemoryLow(addr)); } if (addr >= 0xA000 && addr < 0xC000 && is_GBC) { // on GBC only, cart is accessible during DMA return(mapper.ReadMemoryHigh(addr)); } if (addr >= 0xE000 && addr < 0xF000) { return(RAM[addr - 0xE000]); } if (addr >= 0xF000 && addr < 0xFE00) { return(RAM[(RAM_Bank * 0x1000) + (addr - 0xF000)]); } if (addr >= 0xFE00 && addr < 0xFEA0) { if (ppu.DMA_OAM_access) { return(OAM[addr - 0xFE00]); } else { return(0xFF); } } if (addr >= 0xFF00 && addr < 0xFF80) // The game GOAL! Requires Hardware Regs to be accessible { return(Read_Registers(addr)); } if (addr >= 0xFF80) { if (addr != 0xFFFF) { return(ZP_RAM[addr - 0xFF80]); } else { return(Read_Registers(addr)); } } return(ppu.DMA_byte); } if (addr < 0x8000) { if (addr >= 0x900) { return(mapper.ReadMemoryLow(addr)); } if (addr < 0x100) { // return Either BIOS ROM or Game ROM if ((GB_bios_register & 0x1) == 0) { return(_bios[addr]); // Return BIOS } return(mapper.ReadMemoryLow(addr)); } if (addr >= 0x200) { // return Either BIOS ROM or Game ROM if (((GB_bios_register & 0x1) == 0) && is_GBC) { return(_bios[addr]); // Return BIOS } return(mapper.ReadMemoryLow(addr)); } return(mapper.ReadMemoryLow(addr)); } if (addr < 0xA000) { if (ppu.VRAM_access_read) { return(VRAM[VRAM_Bank * 0x2000 + (addr - 0x8000)]); } if (ppu.pixel_counter == 160) { return(ppu.bus_return); } return(0xFF); } if (addr < 0xC000) { return(mapper.ReadMemoryHigh(addr)); } if (addr < 0xFE00) { addr = (ushort)(RAM_Bank * (addr & 0x1000) + (addr & 0xFFF)); return(RAM[addr]); } if (addr < 0xFF00) { if (addr < 0xFEA0) { if (ppu.OAM_access_read) { return(OAM[addr - 0xFE00]); } return(0xFF); } // unmapped memory, return depends on console and rendering if (is_GBC) { if (_syncSettings.GBACGB) { // in GBA mode, it returns a reflection of the address somehow if (ppu.OAM_access_read) { return((byte)((addr & 0xF0) | ((addr & 0xF0) >> 4))); } return(0xFF); } else { // in a normal gbc it returns something from the upper two rows of OAM, still needs work if (ppu.OAM_access_read) { return(OAM[(addr & 0xF) | 0x80]); } return(0xFF); } } else { if (ppu.OAM_access_read) { return(0); } return(0xFF); } } if (addr < 0xFF80) { return(Read_Registers(addr)); } if (addr < 0xFFFF) { return(ZP_RAM[addr - 0xFF80]); } return(Read_Registers(addr)); }
public void WriteMemory(ushort addr, byte value) { if (MemoryCallbacks.HasWrites) { uint flags = (uint)MemoryCallbackFlags.AccessWrite; MemoryCallbacks.CallMemoryCallbacks(addr, value, flags, "System Bus"); } addr_access = addr; if (ppu.DMA_start) { // some of gekkio's tests require this to be accessible during DMA if (addr >= 0xA000 && addr < 0xC000 && is_GBC) { // on GBC only, cart is accessible during DMA mapper.WriteMemory(addr, value); } if (addr >= 0xE000 && addr < 0xF000) { RAM[addr - 0xE000] = value; } else if (addr >= 0xF000 && addr < 0xFE00) { RAM[RAM_Bank * 0x1000 + (addr - 0xF000)] = value; } else if (addr >= 0xFE00 && addr < 0xFEA0 && ppu.DMA_OAM_access) { OAM[addr - 0xFE00] = value; } else if (addr >= 0xFF00 && addr < 0xFF80) // The game GOAL! Requires Hardware Regs to be accessible { Write_Registers(addr, value); } else if (addr >= 0xFF80) { if (addr != 0xFFFF) { ZP_RAM[addr - 0xFF80] = value; } else { Write_Registers(addr, value); } } return; } // Writes are more likely from the top down if (addr >= 0xFF00) { if (addr < 0xFF80) { Write_Registers(addr, value); } else if (addr < 0xFFFF) { ZP_RAM[addr - 0xFF80] = value; } else { Write_Registers(addr, value); } } else if (addr >= 0xFE00) { if (addr < 0xFEA0) { if (ppu.OAM_access_write) { OAM[addr - 0xFE00] = value; } } // unmapped memory writes depend on console else { if (is_GBC) { if (_syncSettings.GBACGB) { // in GBA mode, writes have no effect as far as tested, might need more thorough tests } else { // in a normal gbc it writes the value to upper two rows of OAM, still needs work if (ppu.OAM_access_write) { OAM[(addr & 0xF) | 0x80] = value; } } } else { if (ppu.OAM_access_write) { OAM[addr - 0xFEA0 + 0x40] = 0; } } } } else if (addr >= 0xC000) { addr = (ushort)(RAM_Bank * (addr & 0x1000) + (addr & 0xFFF)); RAM[addr] = value; } else if (addr >= 0xA000) { mapper.WriteMemory(addr, value); } else if (addr >= 0x8000) { if (ppu.VRAM_access_write) { VRAM[(VRAM_Bank * 0x2000) + (addr - 0x8000)] = value; } } else { if (addr >= 0x900) { mapper.WriteMemory(addr, value); } else { if (addr < 0x100) { if ((GB_bios_register & 0x1) == 0) { // No Writing to BIOS } else { mapper.WriteMemory(addr, value); } } else if (addr >= 0x200) { if ((GB_bios_register & 0x1) == 0 && is_GBC) { // No Writing to BIOS } else { mapper.WriteMemory(addr, value); } } else { mapper.WriteMemory(addr, value); } } } }