private void MakeTrace(IntPtr _s) { int[] s = new int[14]; System.Runtime.InteropServices.Marshal.Copy(_s, s, 0, 14); ushort unused; Tracer.Put(new TraceInfo { Disassembly = LR35902.Disassemble((ushort)s[1], addr => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused) .PadRight(36), RegisterInfo = string.Format( "A:{3:x2} B:{4:x2} C:{5:x2} D:{6:x2} E:{7:x2} F:{8:x2} H:{9:x2} L:{10:x2} LY:{13:x2} SP:{2:x2} {11} Cy:{0}", s[0], s[1] & 0xffff, s[2] & 0xffff, s[3] & 0xff, s[4] & 0xff, s[5] & 0xff, s[6] & 0xff, s[7] & 0xff, s[8] & 0xff, s[9] & 0xff, s[10] & 0xff, s[11] != 0 ? "skip" : "", s[12] & 0xff, s[13] & 0xff) }); }
/// <summary> /// set up callback /// </summary> /// <param name="line">scanline. -1 = end of frame, -2 = RIGHT NOW</param> public void SetScanlineCallback(ScanlineCallback callback, int line) { if (GambatteState == IntPtr.Zero) { return; // not sure how this is being reached. tried the debugger... } endofframecallback = null; if (callback == null || line == -1 || line == -2) { scanlinecb = null; LibGambatte.gambatte_setscanlinecallback(GambatteState, null, 0); if (line == -1) { endofframecallback = callback; } else if (line == -2) { callback(LibGambatte.gambatte_cpuread(GambatteState, 0xff40)); } } else if (line >= 0 && line <= 153) { scanlinecb = delegate { callback(LibGambatte.gambatte_cpuread(GambatteState, 0xff40)); }; LibGambatte.gambatte_setscanlinecallback(GambatteState, scanlinecb, line); } else { throw new ArgumentOutOfRangeException(nameof(line), "line must be in [0, 153]"); } }
void InitMemoryDomains() { CreateMemoryDomain(LibGambatte.MemoryAreas.wram, "WRAM"); CreateMemoryDomain(LibGambatte.MemoryAreas.rom, "ROM"); CreateMemoryDomain(LibGambatte.MemoryAreas.vram, "VRAM"); CreateMemoryDomain(LibGambatte.MemoryAreas.cartram, "Cart RAM"); CreateMemoryDomain(LibGambatte.MemoryAreas.oam, "OAM"); CreateMemoryDomain(LibGambatte.MemoryAreas.hram, "HRAM"); // also add a special memory domain for the system bus, where calls get sent directly to the core each time _MemoryDomains.Add(new MemoryDomain("System Bus", 65536, MemoryDomain.Endian.Little, delegate(int addr) { if (addr < 0 || addr >= 65536) { throw new ArgumentOutOfRangeException(); } return(LibGambatte.gambatte_cpuread(GambatteState, (ushort)addr)); }, delegate(int addr, byte val) { if (addr < 0 || addr >= 65536) { throw new ArgumentOutOfRangeException(); } LibGambatte.gambatte_cpuwrite(GambatteState, (ushort)addr, val); })); MemoryDomains = new MemoryDomainList(_MemoryDomains); }
internal void FrameAdvancePost() { if (IsLagFrame) { LagCount++; } endofframecallback?.Invoke(LibGambatte.gambatte_cpuread(GambatteState, 0xff40)); }
internal void FrameAdvancePost() { if (IsLagFrame) { LagCount++; } if (endofframecallback != null) { endofframecallback(LibGambatte.gambatte_cpuread(GambatteState, 0xff40)); } }
private void MakeTrace(IntPtr _s) { int[] s = new int[13]; System.Runtime.InteropServices.Marshal.Copy(_s, s, 0, 13); ushort unused; Tracer.Put(string.Format( "{13} SP:{2:x2} A:{3:x2} B:{4:x2} C:{5:x2} D:{6:x2} E:{7:x2} F:{8:x2} H:{9:x2} L:{10:x2} {11} Cy:{0}", s[0], s[1] & 0xffff, s[2] & 0xffff, s[3] & 0xff, s[4] & 0xff, s[5] & 0xff, s[6] & 0xff, s[7] & 0xff, s[8] & 0xff, s[9] & 0xff, s[10] & 0xff, s[11] != 0 ? "skip" : "", s[12] & 0xff, Common.Components.Z80GB.NewDisassembler.Disassemble((ushort)s[1], (addr) => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused).PadRight(30) )); }
private LibGambatte.MemoryCallback CreateCallback(MemoryCallbackFlags flags, Func <bool> getHasCBOfType, string which = "") { var rawFlags = (uint)flags; return((address, cycleOffset) => { callbackCycleCount = _cycleCount + cycleOffset; if (getHasCBOfType()) { MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "System Bus"); if (address < 0x4000u) // always rom bank 0 for most mbcs (todo: edge mbcs where this doesn't apply) { MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM"); } else if (address < 0x8000u) // rom bank x { var bank = LibGambatte.gambatte_getrombank(GambatteState); // this will return 1 in case there is no mbc (0 is valid for some mbcs too) address += (uint)(bank * 0x4000); address -= 0x4000u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM"); } else if (address < 0xA000u) // vram (may be banked on CGB in CGB enhanced mode) { if (IsCGBMode() && !IsCGBDMGMode()) { var bank = LibGambatte.gambatte_cpuread(GambatteState, 0xFF4F) & 1; address += (uint)(bank * 0x2000); } address -= 0x8000u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "VRAM"); } else if (address < 0xC000u) // sram (may be banked) { var bank = LibGambatte.gambatte_getsrambank(GambatteState); // this will return 0 in case there is only one bank address += (uint)(bank * 0x2000); address -= 0xA000u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "SRAM"); } else if (address < 0xD000u) // wram bank 0 { address -= 0xC000u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "WRAM"); } else if (address < 0xE000u) // wram bank x (always one for dmg/cgb in dmg mode) { if (IsCGBMode() && !IsCGBDMGMode()) { var bank = Math.Max(LibGambatte.gambatte_cpuread(GambatteState, 0xFF70) & 7, 1); address += (uint)(bank * 0x1000); } address -= 0xD000u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "WRAM"); } else if (address < 0xFE00u) // echo ram { // do we do something here? } else if (address < 0xFEA0u) // oam { address -= 0xFE00u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "OAM"); } else if (address < 0xFF00u) // "extra" oam { // do we do something here? } else if (address < 0xFF80u) // mmio { // do we do something here? } else if (address < 0xFFFF) // hram { address -= 0xFF80u; MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "HRAM"); } else if (address == 0xFFFF) // ie reg { // do we do something here? } else { throw new InvalidOperationException("Core accessed invalid address???"); } } }); }