bsnes/higan/sfc/smp/smp.hpp

93 lines
1.8 KiB
C++
Raw Normal View History

//Sony CXP1100Q-1
struct SMP : Processor::SPC700, Thread {
Updated to v067r21 release. byuu says: This moves toward a profile-selection mode. Right now, it is incomplete. There are three binaries, one for each profile. The GUI selection doesn't actually do anything yet. There will be a launcher in a future release that loads each profile's respective binary. I reverted away from blargg's SMP library for the time being, in favor of my own. This will fix most of the csnes/bsnes-performance bugs. This causes a 10% speed hit on 64-bit platforms, and a 15% speed hit on 32-bit platforms. I hope to be able to regain that speed in the future, I may also experiment with creating my own fast-SMP core which drops bus hold delays and TEST register support (never used by anything, ever.) Save states now work in all three cores, but they are not cross-compatible. The profile name is stored in the description field of the save states, and it won't load a state if the profile name doesn't match. The debugger only works on the research target for now. Give it time and it will return for the other targets. Other than that, let's please resume testing on all three once again. See how far we get this time :) I can confirm the following games have issues on the performance profile: - Armored Police Metal Jacket (minor logo flickering, not a big deal) - Chou Aniki (won't start, so obviously unplayable) - Robocop vs The Terminator (major in-game flickering, unplayable) Anyone still have that gigantic bsnes thread archive from the ZSNES forum? Maybe I posted about how to fix those two broken games in there, heh. I really want to release this as v1.0, but my better judgment says we need to give it another week. Damn.
2010-10-20 11:22:44 +00:00
enum : bool { Threaded = true };
alwaysinline auto step(uint clocks) -> void;
alwaysinline auto synchronizeCPU() -> void;
alwaysinline auto synchronizeDSP() -> void;
auto portRead(uint2 port) const -> uint8;
auto portWrite(uint2 port, uint8 data) -> void;
auto enter() -> void;
auto power() -> void;
auto reset() -> void;
auto serialize(serializer&) -> void;
uint8 iplrom[64] = {0};
uint8 apuram[64 * 1024] = {0};
privileged:
struct {
//timing
uint clockCounter;
uint dspCounter;
uint timerStep;
//$00f0
uint8 clockSpeed;
uint8 timerSpeed;
bool timersEnable;
bool ramDisable;
bool ramWritable;
bool timersDisable;
//$00f1
bool iplromEnable;
//$00f2
uint8 dspAddr;
//$00f8,$00f9
uint8 ram00f8;
uint8 ram00f9;
} status;
static auto Enter() -> void;
struct Debugger {
hook<void (uint16)> op_exec;
Update to v094r05 release. byuu says: Commands can be prefixed with: (cpu|smp|ppu|dsp|apu|vram|oam|cgram)/ to set their source. Eg "vram/hex 0800" or "smp/breakpoints.append execute ffc0"; default is cpu. These overlap a little bit in odd ways, but that's just the way the SNES works: it's not a very orthogonal system. CPU is both a processor and the main bus (ROM, RAM, WRAM, etc), APU is the shared memory by the SMP+DSP (eg use it to catch writes from either chip); PPU probably won't ever be used since it's broken down into three separate buses (VRAM, OAM, CGRAM), but DSP could be useful for tracking bugs like we found in Koushien 2 with the DSP echo buffer corrupting SMP opcodes. Technically the PPU memory pools are only ever tripped by the CPU poking at them, as the PPU doesn't ever write. I now have run.for, run.to, step.for, step.to. The difference is that run only prints the next instruction after running, whereas step prints all of the instructions along the way as well. run.to acts the same as "step over" here. Although it's not quite as nice, since you have to specify the address of the next instruction. Logging the Field/Vcounter/Hcounter on instruction listings now, good for timing information. Added in the tracer mask, as well as memory export, as well as VRAM/OAM/CGRAM/SMP read/write/execute breakpoints, as well as an APU usage map (it tracks DSP reads/writes separately, although I don't currently have debugger callbacks on DSP accesses just yet.) Have not hooked up actual SMP debugging just yet, but I plan to soon. Still thinking about how I want to allow / block interleaving of instructions (terminal output and tracing.) So ... remaining tasks at this point: - full SMP debugging - CPU+SMP interleave support - aliases - hotkeys - save states (will be kind of tricky ... will have to suppress breakpoints during synchronization, or abort a save in a break event.) - keep track of window geometry between runs
2014-02-05 11:30:08 +00:00
hook<void (uint16, uint8)> op_read;
hook<void (uint16, uint8)> op_write;
} debugger;
//memory.cpp
auto ramRead(uint16 addr) -> uint8;
auto ramWrite(uint16 addr, uint8 data) -> void;
auto busRead(uint16 addr) -> uint8;
auto busWrite(uint16 addr, uint8 data) -> void;
auto op_io() -> void;
auto op_read(uint16 addr) -> uint8;
auto op_write(uint16 addr, uint8 data) -> void;
auto disassembler_read(uint16 addr) -> uint8;
//timing.cpp
template<unsigned Frequency>
struct Timer {
uint8 stage0;
uint8 stage1;
uint8 stage2;
uint4 stage3;
bool line;
bool enable;
uint8 target;
auto tick() -> void;
auto synchronizeStage1() -> void;
};
Timer<192> timer0;
Timer<192> timer1;
Timer< 24> timer2;
alwaysinline auto addClocks(uint clocks) -> void;
alwaysinline auto cycleEdge() -> void;
};
extern SMP smp;