bsnes/higan/sfc/smp/smp.cpp

43 lines
758 B
C++
Raw Normal View History

#include <sfc/sfc.hpp>
namespace SuperFamicom {
SMP smp;
#include "memory.cpp"
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
#include "io.cpp"
#include "timing.cpp"
#include "serialization.cpp"
auto SMP::Enter() -> void {
while(true) scheduler.synchronize(), smp.main();
}
auto SMP::main() -> void {
Update to v103r03 release. byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads.
2017-06-28 07:24:46 +00:00
if(r.wait) return instructionWait();
if(r.stop) return instructionStop();
instruction();
}
Update to 20180726 release. byuu says: Once again, I wasn't able to complete a full WIP revision. This WIP-WIP adds very sophisticated emulation of the Sega Genesis Lock-On and Game Genie cartridges ... essentially, through recursion and a linked list, higan supports an infinite nesting of cartridges. Of course, on real hardware, after you stack more than three or four cartridges, the power draw gets too high and things start glitching out more and more as you keep stacking. I've heard that someone chained up to ten Sonic & Knuckles cartridges before it finally became completely unplayable. And so of course, higan emulates this limitation as well ^-^. On the fourth cartridge and beyond, it will become more and more likely that address and/or data lines "glitch" out randomly, causing various glitches. It's a completely silly easter egg that requires no speed impact whatsoever beyond the impact of the new linked list cartridge system. I also designed the successor to Emulator::Interface::cap,get,set. Those were holdovers from the older, since-removed ruby-style accessors. In its place is the new Emulator::Interface::configuration,configure API. There's the usual per-property access, and there's also access to read and write all configurable options at once. In essence, this enables introspection into core-specific features. So far, you can control processor version#s, PPU VRAM size, video settings, and hacks. As such, the .sys/manifest.bml files are no longer necessary. Instead, it all goes into .sys/configuration.bml, which is generated by the emulator if it's missing. higan is going to take this even further and allow each option under "Systems" to have its own editable configuration file. So if you wanted, you could have a 1/1/1 SNES menu option, and a 2/1/3 SNES menu option. Or a Model 1 Genesis option, and a Model 2 Genesis option. Or the various Game Boy model revisions. Or an "SNES-Fast" and "SNES-Accurate" option. I've not fully settled on the syntax of the new configuration API. I feel it might be useful to provide type information, but I really quite passionately hate any<T> container objects. For now it's all string-based, because strings can hold anything in nall. I might also change the access rules. Right now it's like: emulator→configure("video/blurEmulation", true); but it might be nicer as "Video::Blur Emulation", or "Video.BlurEmulation", or something like that.
2018-07-26 10:36:43 +00:00
auto SMP::load() -> bool {
if(auto fp = platform->open(ID::System, "ipl.rom", File::Read, File::Required)) {
fp->read(iplrom, 64);
return true;
}
return false;
}
Update to v105r1 release. byuu says: Changelog: - higan: readded support for soft-reset to Famicom, Super Famicom, Mega Drive cores (work in progress) - handhelds lack soft reset obviously - the PC Engine also lacks a physical reset button - the Master System's reset button acts like a gamepad button, so can't show up in the menu - Mega Drive: power cycle wasn't initializing CPU (M68K) or APU (Z80) RAM - Super Famicom: fix SPC700 opcode 0x3b regression; fixes Majuu Ou [Jonas Quinn] - Super Famicom: fix SharpRTC save regression; fixes Dai Kaijuu Monogatari II's real-time clock [Talarubi] - Super Famicom: fix EpsonRTC save regression; fixes Tengai Makyou Zero's real-time clock [Talarubi] - Super Famicom: removed `*::init()` functions, as they were never used - Super Famicom: removed all but two `*::load()` functions, as they were not used - higan: added option to auto-save backup RAM every five seconds (enabled by default) - this is in case the emulator crashes, or there's a power outage; turn it off under advanced settings if you want - libco: updated license from public domain to ISC, for consistency with nall, ruby, hiro - nall: Linux compiler defaults to g++; override with g++-version if g++ is <= 4.8 - FreeBSD compiler default is going to remain g++49 until my dev box OS ships with g++ >= 4.9 Errata: I have weird RAM initialization constants, thanks to hex_usr and onethirdxcubed for both finding this: http://wiki.nesdev.com/w/index.php?title=CPU_power_up_state&diff=11711&oldid=11184 I'll remove this in the next WIP.
2017-11-06 22:05:54 +00:00
auto SMP::power(bool reset) -> void {
SPC700::power();
Update to v103r06 release. byuu says: Changelog: - processor/spc700: restored fetch/load/store/pull/push shorthand functions - processor/spc700: split functions that tested the algorithm used (`op != &SPC700:...`) to separate instructions - mostly for code clarity over code size: it was awkward having cycle counts change based on a function parameter - processor/spc700: implemented Overload's new findings on which cycles are truly internal (no bus reads) - sfc/smp: TEST register emulation has been vastly improved¹ ¹: it turns out that TEST.d4,d5 is the external clock divider (used when accessing RAM through the DSP), and TEST.d6,d7 is the internal clock divider (used when accessing IPLROM, IO registers, or during idle cycles.) The DSP (24576khz) feeds its clock / 12 through to the SMP (2048khz). The clock divider setting further divides the clock by 2, 4, 8, or 16. Since 8 and 16 are not cleanly divislbe by 12, the SMP cycle count glitches out and seems to take 10 and 2 clocks instead of 8 or 16. This can on real hardware either cause the SMP to run very slowly, or more likely, crash the SMP completely until reset. What's even stranger is the timers aren't affected by this. They still clock by 2, 4, 8, or 16. Note that technically I could divide my own clock counters by 24 and reduce these to {1,2,5,10} and {1,2,4,8}, I instead chose to divide by 12 to better illustrate this hardware issue and better model that the SMP clock runs at 2048khz and not 1024khz. Further, note that things aren't 100% perfect yet. This seems to throw off some tests, such as blargg's `test_timer_speed`. I can't tell how far off I am because blargg's test tragically doesn't print out fail values. But you can see the improvements in that higan is now passing all of Revenant's tests that were obviously completely wrong before.
2017-07-03 07:24:47 +00:00
create(Enter, system.apuFrequency() / 12.0);
r.pc.byte.l = iplrom[62];
r.pc.byte.h = iplrom[63];
Update to v106r49 release. byuu says: This is a fairly radical WIP with extreme changes to lots of very important parts. The result is a ~7% emulation speedup (with bsnes, unsure how much it helps higan), but it's quite possible there are regressions. As such, I would really appreciate testing as many games as possible ... especially the old finnicky games that had issues with DMA and/or interrupts. One thing to note is that I removed an edge case test that suppresses IRQs from firing on the very last dot of every field, which is a behavior I've verified on real hardware in the past. I feel that the main interrupt polling function (the hottest portion of the entire emulator) is not the appropriate place for it, and I should instead factor it into assignment of NMITIMEN/VTIME/HTIME using the new io.irqEnable (==virqEnable||hirqEnable) flag. But since I haven't done that yet ... there's an old IRQ test ROM of mine that'll fail for this WIP. No commercial games will ever rely on this, so it's fine for testing. Changelog: - sfc/cpu.smp: inlined the global status functions - sfc/cpu: added readRAM, writeRAM to use a function pointer instead of a lambda for WRAM access - sfc/cpu,smp,ppu/counter: updated reset functionality to new style using class inline initializers - sfc/cpu: fixed power(false) to invoke the reset vector properly - sfc/cpu: completely rewrote DMA handling to have per-channel functions - sfc/cpu: removed unused joylatch(), io.joypadStrobeLatch - sfc/cpu: cleaned up io.cpp handlers - sfc/cpu: simplified interrupt polling code using nall::boolean::flip(),raise(),lower() functions - sfc/ppu/counter: cleaned up the class significantly and also optimized things for efficiency - sfc/ppu/counter: emulated PAL 1368-clock long scanline when interlace=1, field=1, vcounter=311 - sfc/smp: factored out the I/O and port handlers to io.cpp
2018-07-19 09:01:44 +00:00
io = {};
timer0 = {};
timer1 = {};
timer2 = {};
}
}