2012-04-29 06:16:44 +00:00
|
|
|
#include <sfc/sfc.hpp>
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
namespace SuperFamicom {
|
2010-08-09 13:28:56 +00:00
|
|
|
|
Update to v085r03 release.
byuu says:
Changelog:
- fixed cursor being visible under Metacity window manager (hopefully
doesn't cause regression with other WMs)
- show normal cursor when using SDL video driver
- added menu accelerators (meh, why not?)
- removed debugvirtual, ChipDebugger and chip/debugger functionality
entirely
- alt/smp disassembler moved up
- fixed alt/smp incw/decw instructions (unsigned->uint16 for internal
variables)
My plan going forward for a debugger is not to hardcode functionality
that causes the 10-15% slowdown right into the emulator itself.
Instead, I'm going to make a callback class, which will be a specialized
version of nall::function:
- can call function even if not assigned (results in no-op, return type
must have a trivial default constructor)
- if compiled without #define DEBUGGER, the entire thing turns into
a huge no-op; and will be eliminated entirely when compiled
- strategically place the functions: cb_step, cb_read, cb_write, etc.
From here, the ui-debugger GUI will bind the callbacks, implement
breakpoint checking, usage table generation, etc itself.
I'll probably have to add some breakout commands to exit the emulation
core prior to a frame event in some cases as well.
I didn't initially want any debugger-related stuff in the base cores,
but the #if debugger sCPUDebugger #else sCPU #endif stuff was already
more of a burden than this will be.
2012-02-04 09:23:53 +00:00
|
|
|
SMP smp;
|
2012-04-29 06:16:44 +00:00
|
|
|
#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"
|
2012-04-29 06:16:44 +00:00
|
|
|
#include "timing.cpp"
|
2010-08-09 13:28:56 +00:00
|
|
|
#include "serialization.cpp"
|
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
auto SMP::Enter() -> void {
|
|
|
|
while(true) scheduler.synchronize(), smp.main();
|
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
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();
|
2016-06-05 04:52:43 +00:00
|
|
|
instruction();
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
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;
|
2016-06-25 08:53:11 +00:00
|
|
|
}
|
|
|
|
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 {
|
Update to v102r26 release.
byuu says:
Changelog:
- md/ym2612: initialize DAC sample to center volume [Cydrak]
- processor/arm: add accumulate mode extra cycle to mlal [Jonas
Quinn]
- processor/huc6280: split off algorithms, improve naming of functions
- processor/mos6502: split off algorithms
- processor/spc700: major revamp of entire core (~50% completed)
- processor/wdc65816: fixed several bugs introduced by rewrite
For the SPC700, this turns out to be very old code as well, with global
object state variables, those annoying `{Boolean,Natural}BitField` types,
`under_case` naming conventions, heavily abbreviated function names, etc.
I'm working to get the code to be in the same design as the MOS6502,
HuC6280, WDC65816 cores, since they're all extremely similar in terms of
architectural design (the SPC700 is more of an off-label
reimplementation of a 6502 core, but still.)
The main thing left is that about 90% of the actual instructions still
need to be adapted to not use the internal state (`aa`, `rd`, `dp`,
`sp`, `bit` variables.) I wanted to finish this today, but ran out of
time before work.
I wouldn't suggest too much testing just yet. We should wait until the
SPC700 core is finished for that. However, if some does want to and
spots regressions, please let me know.
2017-06-16 00:06:17 +00:00
|
|
|
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);
|
2010-08-09 13:28:56 +00:00
|
|
|
|
Update to v102r26 release.
byuu says:
Changelog:
- md/ym2612: initialize DAC sample to center volume [Cydrak]
- processor/arm: add accumulate mode extra cycle to mlal [Jonas
Quinn]
- processor/huc6280: split off algorithms, improve naming of functions
- processor/mos6502: split off algorithms
- processor/spc700: major revamp of entire core (~50% completed)
- processor/wdc65816: fixed several bugs introduced by rewrite
For the SPC700, this turns out to be very old code as well, with global
object state variables, those annoying `{Boolean,Natural}BitField` types,
`under_case` naming conventions, heavily abbreviated function names, etc.
I'm working to get the code to be in the same design as the MOS6502,
HuC6280, WDC65816 cores, since they're all extremely similar in terms of
architectural design (the SPC700 is more of an off-label
reimplementation of a 6502 core, but still.)
The main thing left is that about 90% of the actual instructions still
need to be adapted to not use the internal state (`aa`, `rd`, `dp`,
`sp`, `bit` variables.) I wanted to finish this today, but ran out of
time before work.
I wouldn't suggest too much testing just yet. We should wait until the
SPC700 core is finished for that. However, if some does want to and
spots regressions, please let me know.
2017-06-16 00:06:17 +00:00
|
|
|
r.pc.byte.l = iplrom[62];
|
|
|
|
r.pc.byte.h = iplrom[63];
|
2010-08-09 13:28:56 +00:00
|
|
|
|
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 = {};
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|