diff --git a/BizHawk.Emulation.Common/CodeDataLog.cs b/BizHawk.Emulation.Common/CodeDataLog.cs index fba4e2a00e..4ce09f858c 100644 --- a/BizHawk.Emulation.Common/CodeDataLog.cs +++ b/BizHawk.Emulation.Common/CodeDataLog.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; using System.Text; @@ -13,6 +14,40 @@ namespace BizHawk.Emulation.Common { } + /// + /// Pins the managed arrays. Not that we expect them to be allocated, but in case we do, seeing thish ere will remind us to check for the pin condition and abort + /// + public void Pin() + { + if (Pins.Count != 0) + throw new InvalidOperationException("incremental astrological examination"); + foreach (var kvp in this) + Pins[kvp.Key] = GCHandle.Alloc(kvp.Value, GCHandleType.Pinned); + } + + /// + /// Unpins the managed arrays, to be paired with calls to Pin() + /// + public void Unpin() + { + foreach (var pin in Pins.Values) + pin.Free(); + Pins.Clear(); + } + + /// + /// Retrieves the pointer to a managed array + /// + public IntPtr GetPin(string key) + { + return Pins[key].AddrOfPinnedObject(); + } + + /// + /// Pinned managed arrays + /// + Dictionary Pins = new Dictionary(); + /// /// This is just a hook, if needed, to readily suspend logging, without having to rewire the core /// diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs index 0faf37d3dc..05136dcc62 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -151,6 +151,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public int MessageCounter; + void WritePipeInt(int n) + { + } + + void WritePipePointer(IntPtr ptr, bool flush = true) + { + bwPipe.Write(ptr.ToInt32()); + if(flush) bwPipe.Flush(); + } + void WritePipeMessage(eMessage msg) { if(!bufio) MessageCounter++; @@ -191,6 +201,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public Action ReadHook, ExecHook; public Action WriteHook; + public enum eCDLog_AddrType + { + CARTROM, CARTRAM, WRAM, APURAM, + NUM + }; + + public enum eCDLog_Flags + { + ExecFirst = 0x01, + ExecOperand = 0x02, + CPUData = 0x04, + DMAData = 0x08, //not supported yet + BRR = 0x80, + }; + Dictionary SharedMemoryBlocks = new Dictionary(); Dictionary DeallocatedMemoryBlocks = new Dictionary(); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs index a1d30bef5c..affb989217 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_Enums.cs @@ -41,6 +41,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES eMessage_QUERY_set_backdropColor, eMessage_QUERY_peek_logical_register, eMessage_QUERY_peek_cpu_regs, + eMessage_QUERY_set_cdl, eMessage_CMD_FIRST, eMessage_CMD_init, diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs index 493a1afa05..392f88b995 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using BizHawk.Common; +using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Nintendo.SNES { @@ -180,7 +181,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { public uint pc; public ushort a, x, y, z, s, d, vector; //7x - public byte p, nothing; + public byte p, nothing; public uint aa, rd; public byte sp, dp, db, mdr; public const int SIZEOF = 32; @@ -195,6 +196,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES fixed(CpuRegs* ptr = &ret) Marshal.Copy(temp, 0, new IntPtr(ptr), CpuRegs.SIZEOF); } + + public void QUERY_set_cdl(CodeDataLog cdl) + { + WritePipeMessage(eMessage.eMessage_QUERY_set_cdl); + if (cdl == null) + { + for(int i=0;i<4*2;i++) + WritePipePointer(IntPtr.Zero); + } + else + { + WritePipePointer(cdl.GetPin("CARTROM"),false); + bwPipe.Write(cdl["CARTROM"].Length); + + WritePipePointer(cdl.GetPin("CARTRAM"), false); + bwPipe.Write(cdl["CARTRAM"].Length); + + WritePipePointer(cdl.GetPin("WRAM")); + bwPipe.Write(cdl["WRAM"].Length); + + WritePipePointer(cdl.GetPin("APURAM"), false); + bwPipe.Write(cdl["APURAM"].Length); + bwPipe.Flush(); + } + } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index 0078b9c861..3f0ed40510 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -30,7 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES portedUrl: "http://byuu.org/" )] [ServiceNotApplicable(typeof(IDriveLight))] - public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISaveRam, IStatable, IInputPollable, IRegionable, + public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ICodeDataLogger, IDebuggable, ISettable { public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings) @@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES this.Settings = (SnesSettings)Settings ?? new SnesSettings(); this.SyncSettings = (SnesSyncSettings)SyncSettings ?? new SnesSyncSettings(); - api = new LibsnesApi(GetExePath()); + api = new LibsnesApi(GetDllPath()); api.ReadHook = ReadHook; api.ExecHook = ExecHook; api.WriteHook = WriteHook; @@ -170,6 +170,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } } + CodeDataLog currCdl; + + public void SetCDL(CodeDataLog cdl) + { + if(currCdl != null) currCdl.Unpin(); + currCdl = cdl; + if(currCdl != null) currCdl.Pin(); + + //set it no matter what. if its null, the cdl will be unhooked from libsnes internally + api.QUERY_set_cdl(currCdl); + } + + public void NewCDL(CodeDataLog cdl) + { + cdl["CARTROM"] = new byte[MemoryDomains["CARTROM"].Size]; + cdl["CARTRAM"] = new byte[MemoryDomains["CARTRAM"].Size]; + cdl["WRAM"] = new byte[MemoryDomains["WRAM"].Size]; + cdl["APURAM"] = new byte[MemoryDomains["APURAM"].Size]; + + cdl.SubType = "SNES"; + cdl.SubVer = 0; + } + + public void DisassembleCDL(Stream s, CodeDataLog cdl) + { + //not supported yet + } + public IEmulatorServiceProvider ServiceProvider { get; private set; } private GameInfo _game; @@ -204,6 +232,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES resampler.Dispose(); api.Dispose(); + + if (currCdl != null) currCdl.Unpin(); } public IDictionary GetCpuFlagsAndRegisters() @@ -376,21 +406,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public LibsnesApi api; System.Xml.XmlDocument romxml; - string GetExePath() + string GetDllPath() { - const string bits = "32"; - // disabled til it works - // if (Win32.Is64BitOperatingSystem) - // bits = "64"; + var exename = "libsneshawk-32-" + CurrentProfile.ToLower() + ".dll"; - var exename = "libsneshawk-" + bits + "-" + CurrentProfile.ToLower() + ".dll"; + string dllPath = Path.Combine(CoreComm.CoreFileProvider.DllPath(), exename); - string exePath = Path.Combine(CoreComm.CoreFileProvider.DllPath(), exename); + if (!File.Exists(dllPath)) + throw new InvalidOperationException("Couldn't locate the DLL for SNES emulation for profile: " + CurrentProfile + ". Please make sure you're using a fresh dearchive of a BizHawk distribution."); - if (!File.Exists(exePath)) - throw new InvalidOperationException("Couldn't locate the executable for SNES emulation for profile: " + CurrentProfile + ". Please make sure you're using a fresh dearchive of a BizHawk distribution."); - - return exePath; + return dllPath; } void ReadHook(uint addr) diff --git a/libsnes/bsnes/base/base.cpp b/libsnes/bsnes/base/base.cpp new file mode 100644 index 0000000000..f2ff271d74 --- /dev/null +++ b/libsnes/bsnes/base/base.cpp @@ -0,0 +1,3 @@ +#include "base.hpp" + +CDLInfo cdlInfo; diff --git a/libsnes/bsnes/base/base.hpp b/libsnes/bsnes/base/base.hpp index 7d8c181a8d..2eab46894a 100644 --- a/libsnes/bsnes/base/base.hpp +++ b/libsnes/bsnes/base/base.hpp @@ -55,6 +55,39 @@ template struct hook { #define privileged private #endif +enum eCDLog_AddrType +{ + eCDLog_AddrType_CARTROM, eCDLog_AddrType_CARTRAM, eCDLog_AddrType_WRAM, eCDLog_AddrType_APURAM, + eCDLog_AddrType_NUM +}; + +enum eCDLog_Flags +{ + eCDLog_Flags_None = 0x00, + eCDLog_Flags_ExecFirst = 0x01, + eCDLog_Flags_ExecOperand = 0x02, + eCDLog_Flags_CPUData = 0x04, + eCDLog_Flags_DMAData = 0x08, //not supported yet + eCDLog_Flags_BRR = 0x80 +}; + +struct CDLInfo +{ + eCDLog_Flags currFlags; + uint8_t* blocks[eCDLog_AddrType_NUM]; //[0]==nullptr -> disabled + uint32_t blockSizes[eCDLog_AddrType_NUM]; + void set(eCDLog_AddrType addrType, uint32_t addr) + { + if(!blocks[0]) return; + if(addr >= blockSizes[addrType]) + return; + blocks[addrType][addr] |= currFlags; + } +}; + +extern CDLInfo cdlInfo; +inline bool wantCDL() { return cdlInfo.blocks[0] != nullptr; } + typedef int1_t int1; typedef int2_t int2; typedef int3_t int3; diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.cpp b/libsnes/bsnes/snes/alt/cpu/cpu.cpp index e86ca58e95..9b67166be0 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.cpp +++ b/libsnes/bsnes/snes/alt/cpu/cpu.cpp @@ -77,7 +77,7 @@ void CPU::enter() { } alwaysinline void CPU::op_step() { - (this->*opcode_table[op_readpc()])(); + (this->*opcode_table[op_readpcfirst()])(); } void CPU::enable() { @@ -96,8 +96,8 @@ void CPU::enable() { bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); - read = [](unsigned addr) { return cpu.wram[addr]; }; - write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; + read = [](unsigned addr) { cdlInfo.set(eCDLog_AddrType_WRAM, addr); return cpu.wram[addr]; }; + write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.hpp b/libsnes/bsnes/snes/alt/cpu/cpu.hpp index f3105ad622..e03d2cc358 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.hpp +++ b/libsnes/bsnes/snes/alt/cpu/cpu.hpp @@ -19,7 +19,7 @@ public: void mmio_write(unsigned addr, uint8 data); void op_io(); - uint8 op_read(unsigned addr); + uint8 op_read(unsigned addr, eCDLog_Flags = eCDLog_Flags_CPUData); void op_write(unsigned addr, uint8 data); void enter(); diff --git a/libsnes/bsnes/snes/alt/cpu/memory.cpp b/libsnes/bsnes/snes/alt/cpu/memory.cpp index fed9870af0..2e1a4a11a1 100644 --- a/libsnes/bsnes/snes/alt/cpu/memory.cpp +++ b/libsnes/bsnes/snes/alt/cpu/memory.cpp @@ -24,7 +24,8 @@ void CPU::op_io() { add_clocks(6); } -uint8 CPU::op_read(unsigned addr) { +uint8 CPU::op_read(unsigned addr, eCDLog_Flags flags) { + cdlInfo.currFlags = flags; regs.mdr = bus.read(addr); add_clocks(speed(addr)); return regs.mdr; diff --git a/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp b/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp index b012140782..12752a8431 100644 --- a/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp +++ b/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp @@ -526,6 +526,11 @@ VOICE_CLOCK( V4 ) m.t_looped = v->vbit; } v->brr_offset = 1; + + //assume we're going to access the whole block + cdlInfo.currFlags = eCDLog_Flags_BRR; + for(int i=0;i<9;i++) + cdlInfo.set(eCDLog_AddrType_APURAM, (v->brr_addr+i) & 0xFFFF); } } diff --git a/libsnes/bsnes/snes/alt/smp/core.cpp b/libsnes/bsnes/snes/alt/smp/core.cpp index 21bf5bf225..6a79e71d8e 100644 --- a/libsnes/bsnes/snes/alt/smp/core.cpp +++ b/libsnes/bsnes/snes/alt/smp/core.cpp @@ -14,12 +14,14 @@ void SMP::op_io() { #endif } -uint8 SMP::op_read(uint16 addr) { +uint8 SMP::op_read(uint16 addr, eCDLog_Flags flags) { #if defined(CYCLE_ACCURATE) tick(); #endif if((addr & 0xfff0) == 0x00f0) return mmio_read(addr); if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; + cdlInfo.currFlags = flags; + cdlInfo.set(eCDLog_AddrType_APURAM, addr); return apuram[addr]; } @@ -32,18 +34,19 @@ void SMP::op_write(uint16 addr, uint8 data) { } void SMP::op_step() { - #define op_readpc() op_read(regs.pc++) - #define op_readdp(addr) op_read((regs.p.p << 8) + addr) + #define op_readpcfirst() op_read(regs.pc++,eCDLog_Flags_ExecFirst) + #define op_readpc() op_read(regs.pc++,eCDLog_Flags_ExecOperand) + #define op_readdp(addr) op_read((regs.p.p << 8) + addr,eCDLog_Flags_CPUData) #define op_writedp(addr, data) op_write((regs.p.p << 8) + addr, data) - #define op_readaddr(addr) op_read(addr) + #define op_readaddr(addr) op_read(addr,eCDLog_Flags_CPUData) #define op_writeaddr(addr, data) op_write(addr, data) - #define op_readstack() op_read(0x0100 | ++regs.sp) + #define op_readstack() op_read(0x0100 | ++regs.sp,eCDLog_Flags_CPUData) #define op_writestack(data) op_write(0x0100 | regs.sp--, data) #if defined(CYCLE_ACCURATE) if(opcode_cycle == 0) { - opcode_number = op_readpc(); + opcode_number = op_readpcfirst(); opcode_cycle++; } else switch(opcode_number) { #include "core/opcycle_misc.cpp" @@ -55,7 +58,7 @@ void SMP::op_step() { #else - unsigned opcode = op_readpc(); + unsigned opcode = op_readpcfirst(); switch(opcode) { #include "core/op_misc.cpp" #include "core/op_mov.cpp" diff --git a/libsnes/bsnes/snes/alt/smp/smp.hpp b/libsnes/bsnes/snes/alt/smp/smp.hpp index 39b4562e61..f50184446c 100644 --- a/libsnes/bsnes/snes/alt/smp/smp.hpp +++ b/libsnes/bsnes/snes/alt/smp/smp.hpp @@ -90,7 +90,7 @@ public: void tick(); alwaysinline void op_io(); - alwaysinline uint8 op_read(uint16 addr); + alwaysinline uint8 op_read(uint16 addr, eCDLog_Flags flags); alwaysinline void op_write(uint16 addr, uint8 data); alwaysinline void op_step(); static const unsigned cycle_count_table[256]; diff --git a/libsnes/bsnes/snes/cartridge/cartridge.hpp b/libsnes/bsnes/snes/cartridge/cartridge.hpp index a108d8ba70..958aabd2c1 100644 --- a/libsnes/bsnes/snes/cartridge/cartridge.hpp +++ b/libsnes/bsnes/snes/cartridge/cartridge.hpp @@ -110,6 +110,11 @@ private: void parse_markup_obc1(XML::Node&); void parse_markup_msu1(XML::Node&); void parse_markup_link(XML::Node&); + + inline uint8 rom_read(unsigned addr); + inline void rom_write(unsigned addr, uint8 n); + inline uint8 ram_read(unsigned addr); + inline void ram_write(unsigned addr, uint8 n); }; extern Cartridge cartridge; diff --git a/libsnes/bsnes/snes/cartridge/markup.cpp b/libsnes/bsnes/snes/cartridge/markup.cpp index dd46cb2c13..a4ac63bb8c 100644 --- a/libsnes/bsnes/snes/cartridge/markup.cpp +++ b/libsnes/bsnes/snes/cartridge/markup.cpp @@ -62,13 +62,31 @@ void Cartridge::parse_markup_map(Mapping &m, XML::Node &map) { } } -// +uint8 Cartridge::rom_read(unsigned addr) +{ + cdlInfo.set(eCDLog_AddrType_CARTROM, addr); + return rom.read(addr); +} +void Cartridge::rom_write(unsigned addr, uint8 n) +{ + rom.write(addr,n); +} + +uint8 Cartridge::ram_read(unsigned addr) +{ + cdlInfo.set(eCDLog_AddrType_CARTRAM, addr); + return ram.read(addr); +} +void Cartridge::ram_write(unsigned addr, uint8 n) +{ + ram.write(addr, n); +} void Cartridge::parse_markup_rom(XML::Node &root) { if(root.exists() == false) return; for(auto &node : root) { if(node.name != "map") continue; - Mapping m(rom); + Mapping m({&Cartridge::rom_read, this}, {&Cartridge::rom_write, this}); parse_markup_map(m, node); if(m.size == 0) m.size = rom.size(); mapping.append(m); @@ -79,7 +97,7 @@ void Cartridge::parse_markup_ram(XML::Node &root) { if(root.exists() == false) return; ram_size = numeral(root["size"].data); for(auto &node : root) { - Mapping m(ram); + Mapping m({ &Cartridge::ram_read, this }, { &Cartridge::ram_write, this }); parse_markup_map(m, node); if(m.size == 0) m.size = ram_size; mapping.append(m); diff --git a/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp b/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp index d13ac92991..e7da7add13 100644 --- a/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp +++ b/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp @@ -107,7 +107,8 @@ void SA1::op_io() { tick(); } -uint8 SA1::op_read(unsigned addr) { +uint8 SA1::op_read(unsigned addr, eCDLog_Flags flags) { + (void)flags; //this was needed for inheritance purposes, as SA-1 is derived from the main CPU class tick(); if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); return bus_read(addr); diff --git a/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp b/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp index ffb9e9f6ea..6e627057c0 100644 --- a/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp +++ b/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp @@ -3,7 +3,7 @@ void bus_write(unsigned addr, uint8 data); uint8 vbr_read(unsigned addr); alwaysinline void op_io(); -alwaysinline uint8 op_read(unsigned addr); +alwaysinline uint8 op_read(unsigned addr, eCDLog_Flags = eCDLog_Flags_CPUData); alwaysinline void op_write(unsigned addr, uint8 data); uint8 mmc_read(unsigned addr); diff --git a/libsnes/bsnes/snes/cpu/core/core.hpp b/libsnes/bsnes/snes/cpu/core/core.hpp index 964bd12889..65c5fa9bc3 100644 --- a/libsnes/bsnes/snes/cpu/core/core.hpp +++ b/libsnes/bsnes/snes/cpu/core/core.hpp @@ -8,7 +8,7 @@ struct CPUcore { uint8_t sp, dp; virtual void op_io() = 0; - virtual uint8_t op_read(uint32_t addr) = 0; + virtual uint8_t op_read(uint32_t addr, eCDLog_Flags flags = eCDLog_Flags_CPUData) = 0; virtual void op_write(uint32_t addr, uint8_t data) = 0; virtual void last_cycle() = 0; virtual bool interrupt_pending() = 0; diff --git a/libsnes/bsnes/snes/cpu/core/memory.hpp b/libsnes/bsnes/snes/cpu/core/memory.hpp index 4992657869..c6347dc296 100644 --- a/libsnes/bsnes/snes/cpu/core/memory.hpp +++ b/libsnes/bsnes/snes/cpu/core/memory.hpp @@ -1,33 +1,44 @@ +alwaysinline uint8_t op_readpcfirst() { + return op_read((regs.pc.b << 16) + regs.pc.w++, eCDLog_Flags_ExecFirst); +} + alwaysinline uint8_t op_readpc() { - return op_read((regs.pc.b << 16) + regs.pc.w++); + return op_read((regs.pc.b << 16) + regs.pc.w++, eCDLog_Flags_ExecOperand); } alwaysinline uint8_t op_readstack() { + cdlInfo.currFlags = eCDLog_Flags_CPUData; regs.e ? regs.s.l++ : regs.s.w++; return op_read(regs.s.w); } alwaysinline uint8_t op_readstackn() { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read(++regs.s.w); } alwaysinline uint8_t op_readaddr(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read(addr & 0xffff); } alwaysinline uint8_t op_readlong(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read(addr & 0xffffff); } alwaysinline uint8_t op_readdbr(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read(((regs.db << 16) + addr) & 0xffffff); } alwaysinline uint8_t op_readpbr(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read((regs.pc.b << 16) + (addr & 0xffff)); } alwaysinline uint8_t op_readdp(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; if(regs.e && regs.d.l == 0x00) { return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff)); } else { @@ -36,6 +47,7 @@ alwaysinline uint8_t op_readdp(uint32_t addr) { } alwaysinline uint8_t op_readsp(uint32_t addr) { + cdlInfo.currFlags = eCDLog_Flags_CPUData; return op_read((regs.s + (addr & 0xffff)) & 0xffff); } diff --git a/libsnes/bsnes/snes/cpu/cpu.cpp b/libsnes/bsnes/snes/cpu/cpu.cpp index 8457b79740..8ecd3c9e7d 100644 --- a/libsnes/bsnes/snes/cpu/cpu.cpp +++ b/libsnes/bsnes/snes/cpu/cpu.cpp @@ -99,7 +99,7 @@ void CPU::op_step() { interface()->cpuTrace(tmp); } - (this->*opcode_table[op_readpc()])(); + (this->*opcode_table[op_readpcfirst()])(); } void CPU::enable() { @@ -118,7 +118,7 @@ void CPU::enable() { bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); - read = [](unsigned addr) { return cpu.wram[addr]; }; + read = [](unsigned addr) { cdlInfo.set(eCDLog_AddrType_WRAM, addr); return cpu.wram[addr]; }; write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); diff --git a/libsnes/bsnes/snes/cpu/cpu.hpp b/libsnes/bsnes/snes/cpu/cpu.hpp index 11c3620438..bb70ac78b4 100644 --- a/libsnes/bsnes/snes/cpu/cpu.hpp +++ b/libsnes/bsnes/snes/cpu/cpu.hpp @@ -1,5 +1,8 @@ struct CPU : public Processor, public CPUcore, public PPUcounter { uint8 *wram; //[128 * 1024]; + + function read_wram; + function write_wram; enum : bool { Threaded = true }; array coprocessors; diff --git a/libsnes/bsnes/snes/cpu/memory/memory.cpp b/libsnes/bsnes/snes/cpu/memory/memory.cpp index 7e5c0c691d..bc4ab661fe 100644 --- a/libsnes/bsnes/snes/cpu/memory/memory.cpp +++ b/libsnes/bsnes/snes/cpu/memory/memory.cpp @@ -10,12 +10,13 @@ void CPU::op_io() { alu_edge(); } -uint8 CPU::op_read(uint32 addr) { +uint8 CPU::op_read(uint32 addr, eCDLog_Flags flags) { debugger.op_read(addr); status.clock_count = speed(addr); dma_edge(); add_clocks(status.clock_count - 4); + cdlInfo.currFlags = flags; regs.mdr = bus.read(addr); add_clocks(4); alu_edge(); diff --git a/libsnes/bsnes/snes/cpu/memory/memory.hpp b/libsnes/bsnes/snes/cpu/memory/memory.hpp index c732969060..638e892231 100644 --- a/libsnes/bsnes/snes/cpu/memory/memory.hpp +++ b/libsnes/bsnes/snes/cpu/memory/memory.hpp @@ -1,4 +1,4 @@ void op_io(); -uint8 op_read(uint32 addr); +uint8 op_read(uint32 addr, eCDLog_Flags flags = eCDLog_Flags_CPUData); void op_write(uint32 addr, uint8 data); alwaysinline unsigned speed(unsigned addr) const; diff --git a/libsnes/bsnes/snes/interface/interface.hpp b/libsnes/bsnes/snes/interface/interface.hpp index 85e413d1b6..9760893aae 100644 --- a/libsnes/bsnes/snes/interface/interface.hpp +++ b/libsnes/bsnes/snes/interface/interface.hpp @@ -1,3 +1,4 @@ + struct Interface { Interface(); virtual void videoRefresh(const uint32_t *data, bool hires, bool interlace, bool overscan); diff --git a/libsnes/bsnes/snes/smp/core/core.hpp b/libsnes/bsnes/snes/smp/core/core.hpp index 2d47bfb132..0b3da3f330 100644 --- a/libsnes/bsnes/snes/smp/core/core.hpp +++ b/libsnes/bsnes/snes/smp/core/core.hpp @@ -1,6 +1,6 @@ struct SMPcore { virtual void op_io() = 0; - virtual uint8 op_read(uint16 addr) = 0; + virtual uint8 op_read(uint16 addr, eCDLog_Flags flags = eCDLog_Flags_CPUData) = 0; virtual void op_write(uint16 addr, uint8 data) = 0; void op_step(); diff --git a/libsnes/bsnes/snes/smp/core/memory.hpp b/libsnes/bsnes/snes/smp/core/memory.hpp index 4e40af4d8a..ac33f22232 100644 --- a/libsnes/bsnes/snes/smp/core/memory.hpp +++ b/libsnes/bsnes/snes/smp/core/memory.hpp @@ -1,5 +1,9 @@ +alwaysinline uint8 op_readpcfirst() { + return op_read(regs.pc++, eCDLog_Flags_ExecFirst); +} + alwaysinline uint8 op_readpc() { - return op_read(regs.pc++); + return op_read(regs.pc++, eCDLog_Flags_ExecOperand); } alwaysinline uint8 op_readsp() { @@ -19,7 +23,7 @@ alwaysinline void op_writedp(uint8 addr, uint8 data) { } alwaysinline void op_next() { - opcode = op_readpc(); + opcode = op_readpcfirst(); uindex = -1; } diff --git a/libsnes/bsnes/snes/smp/memory/memory.cpp b/libsnes/bsnes/snes/smp/memory/memory.cpp index 49c8895795..7a53df5df1 100644 --- a/libsnes/bsnes/snes/smp/memory/memory.cpp +++ b/libsnes/bsnes/snes/smp/memory/memory.cpp @@ -70,6 +70,7 @@ uint8 SMP::op_busread(uint16 addr) { return result; } + cdlInfo.set(eCDLog_AddrType_APURAM, addr); return ram_read(addr); } @@ -180,10 +181,11 @@ void SMP::op_io() { cycle_edge(); } -uint8 SMP::op_read(uint16 addr) { +uint8 SMP::op_read(uint16 addr, eCDLog_Flags flags) { debugger.op_read(addr); add_clocks(12); + cdlInfo.currFlags = flags; uint8 r = op_busread(addr); add_clocks(12); cycle_edge(); diff --git a/libsnes/bsnes/snes/smp/memory/memory.hpp b/libsnes/bsnes/snes/smp/memory/memory.hpp index 72691f0e4c..717947abef 100644 --- a/libsnes/bsnes/snes/smp/memory/memory.hpp +++ b/libsnes/bsnes/snes/smp/memory/memory.hpp @@ -5,5 +5,5 @@ uint8 op_busread(uint16 addr); void op_buswrite(uint16 addr, uint8 data); void op_io(); -uint8 op_read(uint16 addr); +uint8 op_read(uint16 addr, eCDLog_Flags flags = eCDLog_Flags_CPUData); void op_write(uint16 addr, uint8 data); diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/libsnes/bsnes/target-libsnes/libsnes.cpp index e83189f83e..72c3ad13b1 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -131,6 +131,7 @@ struct Interface : public SNES::Interface { { buffer = new uint32_t[512 * 480]; palette = new uint32_t[16 * 32768]; + memset(&cdlInfo,0,sizeof(cdlInfo)); } ~Interface() { @@ -140,7 +141,7 @@ struct Interface : public SNES::Interface { }; void pwrap_init(); -static Interface *iface = nullptr; +Interface *iface = nullptr; namespace SNES { SNES::Interface *interface() { diff --git a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp index 41554e3625..9ff8c34e27 100644 --- a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp @@ -33,6 +33,8 @@ #include #include +extern SNES::Interface *iface; + typedef uint8 u8; typedef int32 s32; typedef uint32 u32; @@ -73,7 +75,8 @@ enum eMessage : int32 eMessage_QUERY_set_backdropColor, eMessage_QUERY_peek_logical_register, eMessage_QUERY_peek_cpu_regs, - + eMessage_QUERY_set_cdl, + eMessage_CMD_FIRST, eMessage_CMD_init, eMessage_CMD_power, @@ -883,6 +886,15 @@ bool Handle_QUERY(eMessage msg) case eMessage_QUERY_state_hook_irq: SNES::cpu.debugger.op_irq = ReadPipe() ? debug_op_irq : hook(); break; + + case eMessage_QUERY_set_cdl: + for (int i = 0; i(); + cdlInfo.blockSizes[i] = ReadPipe(); + } + break; + } return true; } diff --git a/libsnes/vs2015/libsnes.vcxproj b/libsnes/vs2015/libsnes.vcxproj index fc4d162fd9..668837a1fe 100644 --- a/libsnes/vs2015/libsnes.vcxproj +++ b/libsnes/vs2015/libsnes.vcxproj @@ -167,13 +167,147 @@ + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + @@ -188,7 +322,49 @@ true true + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true true @@ -197,11 +373,125 @@ true true + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true true + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + @@ -220,19 +510,133 @@ + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true false true false + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true true true true + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + @@ -241,18 +645,110 @@ true true + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true false true false + + true + true + true + true + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + diff --git a/libsnes/vs2015/libsnes.vcxproj.filters b/libsnes/vs2015/libsnes.vcxproj.filters index 6e53abe88f..b60aa69a48 100644 --- a/libsnes/vs2015/libsnes.vcxproj.filters +++ b/libsnes/vs2015/libsnes.vcxproj.filters @@ -151,6 +151,21 @@ {f06ef20e-c749-4f16-81d3-f88d96b659bc} + + {abb9e273-8335-47ae-b389-76395d57844c} + + + {b17bd430-7d56-4e93-b78c-d41b2c6f3d85} + + + {1e74e41b-9992-4e18-b2a9-91827d350402} + + + {f1711f3e-853c-4ec3-bd3d-2c21d85c65bd} + + + {a2db2d0e-68ec-4fa0-91fc-2bcc8ac33d32} + @@ -180,6 +195,75 @@ target-libsnes + + snes\interface + + + snes\cpu\core\disassembler + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu + + + snes\cartridge + + + snes\cpu\memory + + + snes\alt\cpu + + + snes\alt\smp + + + snes\smp\core + + + snes\smp\core + + + snes\smp\core + + + snes\smp\memory + + + snes\smp\timing + + + snes\smp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\dsp + @@ -320,5 +404,190 @@ snes\smp\core + + snes\cpu\core\disassembler + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu\core + + + snes\cpu + + + snes\cartridge + + + snes\cartridge + + + base + + + snes\cpu\memory + + + snes\alt\cpu + + + snes\alt\cpu + + + snes\alt\cpu + + + snes\alt\cpu + + + snes\alt\cpu + + + snes\alt\smp + + + snes\alt\smp + + + snes\alt\smp + + + snes\alt\smp + + + snes\alt\smp + + + snes\alt\smp + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\smp\core + + + snes\smp\core + + + snes\smp\core + + + snes\smp\core + + + snes\smp\core + + + snes\smp\memory + + + snes\smp\timing + + + snes\smp + + + snes\smp + + + snes\alt\dsp + + + snes\alt\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + snes\dsp + + + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + + + snes\alt\smp\core + \ No newline at end of file diff --git a/output/dll/libsneshawk-32-compatibility.dll b/output/dll/libsneshawk-32-compatibility.dll index 7e91cbd937..2f41379eb2 100644 Binary files a/output/dll/libsneshawk-32-compatibility.dll and b/output/dll/libsneshawk-32-compatibility.dll differ diff --git a/output/dll/libsneshawk-32-performance.dll b/output/dll/libsneshawk-32-performance.dll index 29758965e9..4effa733ba 100644 Binary files a/output/dll/libsneshawk-32-performance.dll and b/output/dll/libsneshawk-32-performance.dll differ