2011-01-08 09:58:41 +00:00
|
|
|
#include <snes/snes.hpp>
|
2010-08-09 13:28:56 +00:00
|
|
|
|
|
|
|
#define CPU_CPP
|
|
|
|
namespace SNES {
|
|
|
|
|
Updated to v067r25 release.
byuu says:
Removed snes_spc, and the fast/smp + fast/dsp wrappers around it.
Cloned dsp to fast/dsp, and re-added the state machine, affects
Compatibility and Performance cores.
Added debugger support to fast/cpu, with full properties list and Qt
debugger functionality.
Rewrote all debugger property functions to return data directly:
- this avoids some annoying conflicts where ChipDebugger::foo()
overshadows Chip::foo()
- this removes the need for an extra 20-200 functions per debugger
core
- this makes the overall code size a good bit smaller
- this currently makes PPU::oam_basesize() inaccessible, so the OAM
viewer will show wrong sprite sizes
Used an evil trick to simplify MMIO read/write address decoding:
- MMIO *mmio[0x8000], where only 0x2000-5fff are used, allows direct
indexing without -0x2000 adjust
So end result: both save states and debugger support work on all three
cores now. Dual Orb II sound is fixed. The speed hit was worse than
I thought, -7% for compatibility, and -10% for performance. At this
point, the compatibility core is the exact same code and speed as v067
official, and the performance core is now only ~36-40% faster than the
compatibility core. Sigh, so much for my dream of using this on my
netbook. At 53fps average now, compared to 39fps before. Profiling will
only get that to ~58fps, and that's way too low for the more intensive
scenes (Zelda 3 rain, CT black omen, etc.)
It would probably be a good idea to find out why my DSP is so much
slower than blargg's, given that it's based upon the same code. The
simple ring buffer stuff can't possibly slow things down that much.
More precisely, it would probably be best to leave blargg's DSP in the
performance core since it's a pretty minor issue, but then I'd have to
have three DSPs: accuracy=threaded, compatibility=state-machine,
performance=blargg. Too much hassle.
Only code in the core emulator now that wasn't at the very least
rewritten for bsnes would be the DSP-3 and DSP-4 modules, which are
really, really lazily done #define hacks around the original C code.
2010-08-19 06:54:15 +00:00
|
|
|
#if defined(DEBUGGER)
|
|
|
|
#include "debugger/debugger.cpp"
|
|
|
|
CPUDebugger cpu;
|
|
|
|
#else
|
|
|
|
CPU cpu;
|
|
|
|
#endif
|
2010-08-11 00:40:59 +00:00
|
|
|
|
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
|
|
|
#include "serialization.cpp"
|
2010-08-11 00:40:59 +00:00
|
|
|
#include "dma.cpp"
|
|
|
|
#include "memory.cpp"
|
|
|
|
#include "mmio.cpp"
|
|
|
|
#include "timing.cpp"
|
2010-08-09 13:31:09 +00:00
|
|
|
|
|
|
|
void CPU::step(unsigned clocks) {
|
|
|
|
smp.clock -= clocks * (uint64)smp.frequency;
|
|
|
|
ppu.clock -= clocks;
|
|
|
|
for(unsigned i = 0; i < coprocessors.size(); i++) {
|
|
|
|
Processor &chip = *coprocessors[i];
|
|
|
|
chip.clock -= clocks * (uint64)chip.frequency;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPU::synchronize_smp() {
|
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
|
|
|
if(SMP::Threaded == true) {
|
|
|
|
if(smp.clock < 0) co_switch(smp.thread);
|
|
|
|
} else {
|
|
|
|
while(smp.clock < 0) smp.enter();
|
|
|
|
}
|
2010-08-09 13:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPU::synchronize_ppu() {
|
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
|
|
|
if(PPU::Threaded == true) {
|
|
|
|
if(ppu.clock < 0) co_switch(ppu.thread);
|
|
|
|
} else {
|
|
|
|
while(ppu.clock < 0) ppu.enter();
|
|
|
|
}
|
2010-08-09 13:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPU::synchronize_coprocessor() {
|
|
|
|
for(unsigned i = 0; i < coprocessors.size(); i++) {
|
|
|
|
Processor &chip = *coprocessors[i];
|
|
|
|
if(chip.clock < 0) co_switch(chip.thread);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-09 13:28:56 +00:00
|
|
|
void CPU::Enter() { cpu.enter(); }
|
|
|
|
|
2010-08-09 13:31:09 +00:00
|
|
|
void CPU::enter() {
|
|
|
|
while(true) {
|
|
|
|
if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
|
|
|
|
scheduler.sync = Scheduler::SynchronizeMode::All;
|
|
|
|
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
|
|
|
}
|
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
if(status.nmi_pending) {
|
|
|
|
status.nmi_pending = false;
|
|
|
|
op_irq(regs.e == false ? 0xffea : 0xfffa);
|
2010-08-09 13:31:09 +00:00
|
|
|
}
|
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
if(status.irq_pending) {
|
|
|
|
status.irq_pending = false;
|
|
|
|
op_irq(regs.e == false ? 0xffee : 0xfffe);
|
|
|
|
}
|
2010-08-09 13:31:09 +00:00
|
|
|
|
Updated to v067r25 release.
byuu says:
Removed snes_spc, and the fast/smp + fast/dsp wrappers around it.
Cloned dsp to fast/dsp, and re-added the state machine, affects
Compatibility and Performance cores.
Added debugger support to fast/cpu, with full properties list and Qt
debugger functionality.
Rewrote all debugger property functions to return data directly:
- this avoids some annoying conflicts where ChipDebugger::foo()
overshadows Chip::foo()
- this removes the need for an extra 20-200 functions per debugger
core
- this makes the overall code size a good bit smaller
- this currently makes PPU::oam_basesize() inaccessible, so the OAM
viewer will show wrong sprite sizes
Used an evil trick to simplify MMIO read/write address decoding:
- MMIO *mmio[0x8000], where only 0x2000-5fff are used, allows direct
indexing without -0x2000 adjust
So end result: both save states and debugger support work on all three
cores now. Dual Orb II sound is fixed. The speed hit was worse than
I thought, -7% for compatibility, and -10% for performance. At this
point, the compatibility core is the exact same code and speed as v067
official, and the performance core is now only ~36-40% faster than the
compatibility core. Sigh, so much for my dream of using this on my
netbook. At 53fps average now, compared to 39fps before. Profiling will
only get that to ~58fps, and that's way too low for the more intensive
scenes (Zelda 3 rain, CT black omen, etc.)
It would probably be a good idea to find out why my DSP is so much
slower than blargg's, given that it's based upon the same code. The
simple ring buffer stuff can't possibly slow things down that much.
More precisely, it would probably be best to leave blargg's DSP in the
performance core since it's a pretty minor issue, but then I'd have to
have three DSPs: accuracy=threaded, compatibility=state-machine,
performance=blargg. Too much hassle.
Only code in the core emulator now that wasn't at the very least
rewritten for bsnes would be the DSP-3 and DSP-4 modules, which are
really, really lazily done #define hacks around the original C code.
2010-08-19 06:54:15 +00:00
|
|
|
op_step();
|
2010-08-11 00:40:59 +00:00
|
|
|
}
|
2010-08-09 13:31:09 +00:00
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
Updated to v067r25 release.
byuu says:
Removed snes_spc, and the fast/smp + fast/dsp wrappers around it.
Cloned dsp to fast/dsp, and re-added the state machine, affects
Compatibility and Performance cores.
Added debugger support to fast/cpu, with full properties list and Qt
debugger functionality.
Rewrote all debugger property functions to return data directly:
- this avoids some annoying conflicts where ChipDebugger::foo()
overshadows Chip::foo()
- this removes the need for an extra 20-200 functions per debugger
core
- this makes the overall code size a good bit smaller
- this currently makes PPU::oam_basesize() inaccessible, so the OAM
viewer will show wrong sprite sizes
Used an evil trick to simplify MMIO read/write address decoding:
- MMIO *mmio[0x8000], where only 0x2000-5fff are used, allows direct
indexing without -0x2000 adjust
So end result: both save states and debugger support work on all three
cores now. Dual Orb II sound is fixed. The speed hit was worse than
I thought, -7% for compatibility, and -10% for performance. At this
point, the compatibility core is the exact same code and speed as v067
official, and the performance core is now only ~36-40% faster than the
compatibility core. Sigh, so much for my dream of using this on my
netbook. At 53fps average now, compared to 39fps before. Profiling will
only get that to ~58fps, and that's way too low for the more intensive
scenes (Zelda 3 rain, CT black omen, etc.)
It would probably be a good idea to find out why my DSP is so much
slower than blargg's, given that it's based upon the same code. The
simple ring buffer stuff can't possibly slow things down that much.
More precisely, it would probably be best to leave blargg's DSP in the
performance core since it's a pretty minor issue, but then I'd have to
have three DSPs: accuracy=threaded, compatibility=state-machine,
performance=blargg. Too much hassle.
Only code in the core emulator now that wasn't at the very least
rewritten for bsnes would be the DSP-3 and DSP-4 modules, which are
really, really lazily done #define hacks around the original C code.
2010-08-19 06:54:15 +00:00
|
|
|
alwaysinline void CPU::op_step() {
|
|
|
|
(this->*opcode_table[op_readpc()])();
|
|
|
|
}
|
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
void CPU::op_irq(uint16 vector) {
|
2010-08-09 13:31:09 +00:00
|
|
|
op_read(regs.pc.d);
|
|
|
|
op_io();
|
|
|
|
if(!regs.e) op_writestack(regs.pc.b);
|
|
|
|
op_writestack(regs.pc.h);
|
|
|
|
op_writestack(regs.pc.l);
|
|
|
|
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
2010-08-11 00:40:59 +00:00
|
|
|
rd.l = op_read(vector + 0);
|
2010-08-09 13:31:09 +00:00
|
|
|
regs.pc.b = 0x00;
|
2010-08-11 00:40:59 +00:00
|
|
|
regs.p.i = 1;
|
|
|
|
regs.p.d = 0;
|
|
|
|
rd.h = op_read(vector + 1);
|
2010-08-09 13:31:09 +00:00
|
|
|
regs.pc.w = rd.w;
|
|
|
|
}
|
|
|
|
|
Update to v074r10 release.
byuu says:
Major WIP, countless changes. I really went to town on cleaning up the
source today with all kinds of new ideas. I'll post the ones I remember,
use diff -ru to get the rest.
What I like the most is my new within template:
template<unsigned lo, unsigned hi>
alwaysinline bool within(unsigned addr) {
static const unsigned mask = ~(hi ^ lo);
return (addr & mask) == lo;
}
Before, you would see code like this:
if((addr & 0xe0e000) == 0x206000) { //$20-3f:6000-7fff
The comment is basically necessary, and you have to trust that the mask
is right, or do the math yourself.
Now, it looks like this:
if(within<0x20, 0x3f, 0x6000, 0x7fff>(addr)) {
That's the same as within<0x206000, 0x3f7fff>, I just made an
SNES-variant to more closely simulate my XML mapping style:
20-3f:6000-7fff.
Now obviously this has limitations, it only works in base-2 and it can't
manage some tricky edge cases like (addr & 0x408000) == 0x008000 for
00-3f|80-bf:8000-ffff. But for the most part, I'll be using this where
I can. The Game Boy is fully ported over to it (via the MBCs), but the
SNES only has the BS-X town cartridge moved over so far. SuperFX and
SA-1 at the very least could benefit.
Next up, since the memory map is now static, there's really no reason to
remap the entire thing at power-on and reset. So it is now set up at
cartridge load and that's it. I moved the CPU/PPU/WRAM mapping out of
memory.cpp and into their respective processors. A bit of duplication
only because there are multiple processor cores for the different
profiles, but I'm not worried about that. This is also going to be
necessary to fix the debugger.
Next, Coprocessor::enable() actually does what I initially intended it
to now: it is called once to turn a chip on after cartridge load. It's
not called on power cycle anymore. This should help fix power-cycle on
my serial simulation code, and was needed to map the bus exactly one
time. Although most stuff is mapped through XML, some chips still need
some manual hooks for monitoring and such (eg S-DD1.)
Next, I've started killing off memory::, it was initially an
over-reaction to the question of where to put APURAM (in the SMP or
DSP?). The idea was to have this namespace that contained all memory for
everything. But it was very annoying and tedious, and various chips
ignored the convention anyway like ST-0011 RAM, which couldn't work
anyway since it is natively uint16 and not uint8. Cx4 will need 24-bit
RAM eventually, too. There's 8->24-bit functions in there now, because
the HLE code is hideous.
So far, all the cartridge.cpp memory:: types have been destroyed.
memory::cartrom, memory::cartram become cartridge.rom and cartridge.ram.
memory::cartrtc was moved into the SRTC and SPC7110 classes directly.
memory::bsxflash was moved into BSXFlash. memory::bsxram and
memory::bsxpram were moved into BSXCartridge (the town cartridge).
memory::st[AB](rom|ram) were moved into a new area,
snes/chip/sufamiturbo. The snes/chip moniker really doesn't work so
well, since it also has base units, and the serial communications stuff
which is through the controller port, but oh well, now it also has the
base structure for the Sufami Turbo cartridge too. So now we have
sufamiturbo.slotA.rom, sufamiturbo.slotB.ram, etc.
Next, the ST-0010/ST-0011 actually save the data RAM to disk. This
wasn't at all compatible with my old system, and I didn't want to keep
adding memory types to check inside the main UI cartridge RAM loading
and saving routines.
So I built a NonVolatileRAM vector inside SNES::Cartridge, and any chip
that has memory it wants to save and load from disk can append onto it
: data, size, id ("srm", "rtc", "nec", etc) and slot (0 = cartridge,
1 = slot A, 2 = slot B)
To load and save memory, we just do a simple: foreach(memory,
SNES::cartridge.nvram) load/saveMemory(memory).
As a result, you can now keep your save games in F1 Race of Champions II
and Hayazashi Nidan Morita Shougi. Technically I think Metal Combat
should work this way as well, having the RAM being part of the chip
itself, but for now that chip just writes directly into cartridge.ram,
so it also technically saves to disk for now.
To avoid a potential conflict with a manipulated memory map, BS-X SRAM
and PSRAM are now .bss and .bsp, and not .srm and .psr. Honestly I don't
like .srm as an extension either, but it doesn't bother me enough to
break save RAM compatibility with other emulators, so don't worry about
that changing.
I finally killed off MappedRAM initializing size to ~0 (-1U). A size of
zero means there is no memory there just the same. This was an old
holdover for handling MMIO mapping, if I recall correctly. Something
about a size of zero on MMIO-Memory objects causing it to wrap the
address, so ~0 would let it map direct addresses ... or something.
Whatever, that's not needed at all anymore.
BSXBase becomes BSXSatellaview, and I've defaulted the device to being
attached since it won't affect non-BSX games anyway. Eventually the GUI
needs to make that an option. BSXCart becomes BSXCartridge. BSXFlash
remains unchanged.
I probably need to make Coprocessor::disable() functions now to free up
memory on unload, but it shouldn't hurt anything the way it is.
libsnes is most definitely broken to all hell and back now, and the
debugger is still shot. I suppose we'll need some tricky code to work
with the old ID system, and we'll need to add some more IDs for the new
memory types.
2011-01-24 08:59:45 +00:00
|
|
|
void CPU::enable() {
|
Update to v074r11 release.
byuu says:
Changelog:
- debugger compiles on all three profiles
- libsnes compiles on all three platforms (no API changes to libsnes)
- memory.cpp : namespace memory removed (wram -> cpu, apuram -> smp,
vram, oam, cgram -> ppu)
- sa1.cpp : namespace memory removed (SA-1 specific functions merged
inline to SA1::bus_read,write)
- GameBoy: added serial link support with interrupts and proper 8192hz
timing, but obviously it acts as if no other GB is connected to it
- GameBoy: added STAT OAM interrupt, and better STAT d1,d0 mode values
- UI: since Qt is dead, I've renamed the config files back to bsnes.cfg
and bsnes-geometry.cfg
- SA1: IRAM was not syncing to CPU on SA-1 side
- PPU/Accuracy and PPU/Performance needed Sprite oam renamed to Sprite
sprite; so that I could add uint8 oam[544]
- makes more sense anyway, OAM = object attribute memory, obj or
sprite are better names for Sprite rendering class
- more cleanup
2011-01-24 09:03:17 +00:00
|
|
|
function<uint8 (unsigned)> read = { &CPU::mmio_read, (CPU*)&cpu };
|
|
|
|
function<void (unsigned, uint8)> write = { &CPU::mmio_write, (CPU*)&cpu };
|
|
|
|
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write);
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write);
|
|
|
|
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write);
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write);
|
|
|
|
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write);
|
|
|
|
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write);
|
|
|
|
|
|
|
|
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; };
|
|
|
|
|
|
|
|
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);
|
|
|
|
bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write);
|
Update to v074r10 release.
byuu says:
Major WIP, countless changes. I really went to town on cleaning up the
source today with all kinds of new ideas. I'll post the ones I remember,
use diff -ru to get the rest.
What I like the most is my new within template:
template<unsigned lo, unsigned hi>
alwaysinline bool within(unsigned addr) {
static const unsigned mask = ~(hi ^ lo);
return (addr & mask) == lo;
}
Before, you would see code like this:
if((addr & 0xe0e000) == 0x206000) { //$20-3f:6000-7fff
The comment is basically necessary, and you have to trust that the mask
is right, or do the math yourself.
Now, it looks like this:
if(within<0x20, 0x3f, 0x6000, 0x7fff>(addr)) {
That's the same as within<0x206000, 0x3f7fff>, I just made an
SNES-variant to more closely simulate my XML mapping style:
20-3f:6000-7fff.
Now obviously this has limitations, it only works in base-2 and it can't
manage some tricky edge cases like (addr & 0x408000) == 0x008000 for
00-3f|80-bf:8000-ffff. But for the most part, I'll be using this where
I can. The Game Boy is fully ported over to it (via the MBCs), but the
SNES only has the BS-X town cartridge moved over so far. SuperFX and
SA-1 at the very least could benefit.
Next up, since the memory map is now static, there's really no reason to
remap the entire thing at power-on and reset. So it is now set up at
cartridge load and that's it. I moved the CPU/PPU/WRAM mapping out of
memory.cpp and into their respective processors. A bit of duplication
only because there are multiple processor cores for the different
profiles, but I'm not worried about that. This is also going to be
necessary to fix the debugger.
Next, Coprocessor::enable() actually does what I initially intended it
to now: it is called once to turn a chip on after cartridge load. It's
not called on power cycle anymore. This should help fix power-cycle on
my serial simulation code, and was needed to map the bus exactly one
time. Although most stuff is mapped through XML, some chips still need
some manual hooks for monitoring and such (eg S-DD1.)
Next, I've started killing off memory::, it was initially an
over-reaction to the question of where to put APURAM (in the SMP or
DSP?). The idea was to have this namespace that contained all memory for
everything. But it was very annoying and tedious, and various chips
ignored the convention anyway like ST-0011 RAM, which couldn't work
anyway since it is natively uint16 and not uint8. Cx4 will need 24-bit
RAM eventually, too. There's 8->24-bit functions in there now, because
the HLE code is hideous.
So far, all the cartridge.cpp memory:: types have been destroyed.
memory::cartrom, memory::cartram become cartridge.rom and cartridge.ram.
memory::cartrtc was moved into the SRTC and SPC7110 classes directly.
memory::bsxflash was moved into BSXFlash. memory::bsxram and
memory::bsxpram were moved into BSXCartridge (the town cartridge).
memory::st[AB](rom|ram) were moved into a new area,
snes/chip/sufamiturbo. The snes/chip moniker really doesn't work so
well, since it also has base units, and the serial communications stuff
which is through the controller port, but oh well, now it also has the
base structure for the Sufami Turbo cartridge too. So now we have
sufamiturbo.slotA.rom, sufamiturbo.slotB.ram, etc.
Next, the ST-0010/ST-0011 actually save the data RAM to disk. This
wasn't at all compatible with my old system, and I didn't want to keep
adding memory types to check inside the main UI cartridge RAM loading
and saving routines.
So I built a NonVolatileRAM vector inside SNES::Cartridge, and any chip
that has memory it wants to save and load from disk can append onto it
: data, size, id ("srm", "rtc", "nec", etc) and slot (0 = cartridge,
1 = slot A, 2 = slot B)
To load and save memory, we just do a simple: foreach(memory,
SNES::cartridge.nvram) load/saveMemory(memory).
As a result, you can now keep your save games in F1 Race of Champions II
and Hayazashi Nidan Morita Shougi. Technically I think Metal Combat
should work this way as well, having the RAM being part of the chip
itself, but for now that chip just writes directly into cartridge.ram,
so it also technically saves to disk for now.
To avoid a potential conflict with a manipulated memory map, BS-X SRAM
and PSRAM are now .bss and .bsp, and not .srm and .psr. Honestly I don't
like .srm as an extension either, but it doesn't bother me enough to
break save RAM compatibility with other emulators, so don't worry about
that changing.
I finally killed off MappedRAM initializing size to ~0 (-1U). A size of
zero means there is no memory there just the same. This was an old
holdover for handling MMIO mapping, if I recall correctly. Something
about a size of zero on MMIO-Memory objects causing it to wrap the
address, so ~0 would let it map direct addresses ... or something.
Whatever, that's not needed at all anymore.
BSXBase becomes BSXSatellaview, and I've defaulted the device to being
attached since it won't affect non-BSX games anyway. Eventually the GUI
needs to make that an option. BSXCart becomes BSXCartridge. BSXFlash
remains unchanged.
I probably need to make Coprocessor::disable() functions now to free up
memory on unload, but it shouldn't hurt anything the way it is.
libsnes is most definitely broken to all hell and back now, and the
debugger is still shot. I suppose we'll need some tricky code to work
with the old ID system, and we'll need to add some more IDs for the new
memory types.
2011-01-24 08:59:45 +00:00
|
|
|
}
|
|
|
|
|
2010-08-09 13:31:09 +00:00
|
|
|
void CPU::power() {
|
2010-08-11 00:40:59 +00:00
|
|
|
regs.a = 0x0000;
|
|
|
|
regs.x = 0x0000;
|
|
|
|
regs.y = 0x0000;
|
2010-08-09 13:31:09 +00:00
|
|
|
regs.s = 0x01ff;
|
|
|
|
|
|
|
|
reset();
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPU::reset() {
|
2010-08-09 13:31:09 +00:00
|
|
|
create(Enter, system.cpu_frequency());
|
2010-08-09 13:28:56 +00:00
|
|
|
coprocessors.reset();
|
2010-08-09 13:33:44 +00:00
|
|
|
PPUcounter::reset();
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
regs.pc = 0x000000;
|
|
|
|
regs.x.h = 0x00;
|
|
|
|
regs.y.h = 0x00;
|
|
|
|
regs.s.h = 0x01;
|
|
|
|
regs.d = 0x0000;
|
|
|
|
regs.db = 0x00;
|
|
|
|
regs.p = 0x34;
|
|
|
|
regs.e = 1;
|
|
|
|
regs.mdr = 0x00;
|
|
|
|
regs.wai = false;
|
2010-08-09 13:31:09 +00:00
|
|
|
update_table();
|
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
regs.pc.l = bus.read(0xfffc);
|
|
|
|
regs.pc.h = bus.read(0xfffd);
|
|
|
|
regs.pc.b = 0x00;
|
|
|
|
|
|
|
|
status.nmi_valid = false;
|
|
|
|
status.nmi_line = false;
|
|
|
|
status.nmi_transition = false;
|
|
|
|
status.nmi_pending = false;
|
|
|
|
|
|
|
|
status.irq_valid = false;
|
|
|
|
status.irq_line = false;
|
|
|
|
status.irq_transition = false;
|
|
|
|
status.irq_pending = false;
|
|
|
|
|
2010-08-12 00:39:41 +00:00
|
|
|
status.irq_lock = false;
|
2010-08-11 00:40:59 +00:00
|
|
|
status.hdma_pending = false;
|
|
|
|
|
|
|
|
status.wram_addr = 0x000000;
|
|
|
|
|
|
|
|
status.joypad_strobe_latch = 0;
|
|
|
|
|
|
|
|
status.nmi_enabled = false;
|
|
|
|
status.virq_enabled = false;
|
|
|
|
status.hirq_enabled = false;
|
|
|
|
status.auto_joypad_poll_enabled = false;
|
|
|
|
|
|
|
|
status.pio = 0xff;
|
|
|
|
|
|
|
|
status.htime = 0x0000;
|
|
|
|
status.vtime = 0x0000;
|
|
|
|
|
|
|
|
status.rom_speed = 8;
|
|
|
|
|
|
|
|
status.joy1l = status.joy1h = 0x00;
|
|
|
|
status.joy2l = status.joy2h = 0x00;
|
|
|
|
status.joy3l = status.joy3h = 0x00;
|
|
|
|
status.joy4l = status.joy4h = 0x00;
|
|
|
|
|
2010-08-09 13:31:09 +00:00
|
|
|
dma_reset();
|
2010-08-11 00:40:59 +00:00
|
|
|
}
|
2010-08-09 13:31:09 +00:00
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
CPU::CPU() : queue(512, { &CPU::queue_event, this }) {
|
2010-08-09 13:33:44 +00:00
|
|
|
PPUcounter::scanline = { &CPU::scanline, this };
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CPU::~CPU() {
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|