2012-04-29 06:16:44 +00:00
|
|
|
struct CPU : Processor::R65816, Thread, public PPUcounter {
|
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
|
|
|
uint8 wram[128 * 1024];
|
|
|
|
|
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 };
|
2012-04-29 06:16:44 +00:00
|
|
|
vector<Thread*> coprocessors;
|
2010-08-09 13:28:56 +00:00
|
|
|
alwaysinline void step(unsigned clocks);
|
2015-12-05 05:44:49 +00:00
|
|
|
alwaysinline void synchronizeSMP();
|
|
|
|
void synchronizePPU();
|
|
|
|
void synchronizeCoprocessors();
|
|
|
|
void synchronizeDevices();
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2010-08-09 13:33:44 +00:00
|
|
|
uint8 pio();
|
|
|
|
bool joylatch();
|
2010-08-11 00:40:59 +00:00
|
|
|
bool interrupt_pending();
|
|
|
|
uint8 port_read(uint8 port);
|
|
|
|
void port_write(uint8 port, uint8 data);
|
|
|
|
uint8 mmio_read(unsigned addr);
|
|
|
|
void mmio_write(unsigned addr, uint8 data);
|
|
|
|
|
|
|
|
void op_io();
|
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
|
|
|
uint8 op_read(unsigned addr);
|
|
|
|
void op_write(unsigned addr, uint8 data);
|
2010-08-09 13:28:56 +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
|
|
|
void enter();
|
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 enable();
|
2010-08-09 13:33:44 +00:00
|
|
|
void power();
|
|
|
|
void reset();
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2010-08-09 13:33:44 +00:00
|
|
|
void serialize(serializer&);
|
|
|
|
CPU();
|
|
|
|
~CPU();
|
|
|
|
|
|
|
|
private:
|
2010-08-11 00:40:59 +00:00
|
|
|
//cpu
|
|
|
|
static void Enter();
|
|
|
|
|
|
|
|
//timing
|
2010-08-12 00:39:41 +00:00
|
|
|
struct QueueEvent {
|
|
|
|
enum : unsigned {
|
|
|
|
DramRefresh,
|
|
|
|
HdmaRun,
|
|
|
|
};
|
|
|
|
};
|
2010-08-11 00:40:59 +00:00
|
|
|
nall::priority_queue<unsigned> queue;
|
|
|
|
void queue_event(unsigned id);
|
|
|
|
void last_cycle();
|
|
|
|
void add_clocks(unsigned clocks);
|
|
|
|
void scanline();
|
|
|
|
void run_auto_joypad_poll();
|
|
|
|
|
|
|
|
//memory
|
|
|
|
unsigned speed(unsigned addr) const;
|
|
|
|
|
|
|
|
//dma
|
|
|
|
bool dma_transfer_valid(uint8 bbus, unsigned abus);
|
|
|
|
bool dma_addr_valid(unsigned abus);
|
|
|
|
uint8 dma_read(unsigned abus);
|
|
|
|
void dma_write(bool valid, unsigned addr, uint8 data);
|
|
|
|
void dma_transfer(bool direction, uint8 bbus, unsigned abus);
|
|
|
|
uint8 dma_bbus(unsigned i, unsigned index);
|
|
|
|
unsigned dma_addr(unsigned i);
|
|
|
|
unsigned hdma_addr(unsigned i);
|
|
|
|
unsigned hdma_iaddr(unsigned i);
|
|
|
|
void dma_run();
|
2010-08-12 00:39:41 +00:00
|
|
|
bool hdma_active_after(unsigned i);
|
2010-08-11 00:40:59 +00:00
|
|
|
void hdma_update(unsigned i);
|
|
|
|
void hdma_run();
|
|
|
|
void hdma_init();
|
|
|
|
void dma_reset();
|
|
|
|
|
|
|
|
//registers
|
|
|
|
uint8 port_data[4];
|
|
|
|
|
|
|
|
struct Channel {
|
|
|
|
bool dma_enabled;
|
|
|
|
bool hdma_enabled;
|
|
|
|
|
|
|
|
bool direction;
|
|
|
|
bool indirect;
|
|
|
|
bool unused;
|
|
|
|
bool reverse_transfer;
|
|
|
|
bool fixed_transfer;
|
|
|
|
uint8 transfer_mode;
|
|
|
|
|
|
|
|
uint8 dest_addr;
|
|
|
|
uint16 source_addr;
|
|
|
|
uint8 source_bank;
|
|
|
|
|
|
|
|
union {
|
|
|
|
uint16 transfer_size;
|
|
|
|
uint16 indirect_addr;
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8 indirect_bank;
|
|
|
|
uint16 hdma_addr;
|
|
|
|
uint8 line_counter;
|
|
|
|
uint8 unknown;
|
|
|
|
|
|
|
|
bool hdma_completed;
|
|
|
|
bool hdma_do_transfer;
|
|
|
|
} channel[8];
|
2010-08-09 13:33:44 +00:00
|
|
|
|
2010-08-09 13:31:09 +00:00
|
|
|
struct Status {
|
|
|
|
bool nmi_valid;
|
|
|
|
bool nmi_line;
|
|
|
|
bool nmi_transition;
|
|
|
|
bool nmi_pending;
|
|
|
|
|
|
|
|
bool irq_valid;
|
|
|
|
bool irq_line;
|
|
|
|
bool irq_transition;
|
|
|
|
bool irq_pending;
|
|
|
|
|
2010-08-12 00:39:41 +00:00
|
|
|
bool irq_lock;
|
2010-08-09 13:31:09 +00:00
|
|
|
bool hdma_pending;
|
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
unsigned wram_addr;
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2010-08-09 13:31:09 +00:00
|
|
|
bool joypad_strobe_latch;
|
|
|
|
|
|
|
|
bool nmi_enabled;
|
2010-08-11 00:40:59 +00:00
|
|
|
bool virq_enabled;
|
|
|
|
bool hirq_enabled;
|
|
|
|
bool auto_joypad_poll_enabled;
|
2010-08-09 13:31:09 +00:00
|
|
|
|
|
|
|
uint8 pio;
|
|
|
|
|
|
|
|
uint8 wrmpya;
|
|
|
|
uint8 wrmpyb;
|
|
|
|
uint16 wrdiva;
|
2010-08-11 00:40:59 +00:00
|
|
|
uint8 wrdivb;
|
2010-08-09 13:31:09 +00:00
|
|
|
|
2010-08-11 00:40:59 +00:00
|
|
|
uint16 htime;
|
|
|
|
uint16 vtime;
|
2010-08-09 13:31:09 +00:00
|
|
|
|
|
|
|
unsigned rom_speed;
|
|
|
|
|
|
|
|
uint16 rddiv;
|
|
|
|
uint16 rdmpy;
|
|
|
|
|
|
|
|
uint8 joy1l, joy1h;
|
|
|
|
uint8 joy2l, joy2h;
|
|
|
|
uint8 joy3l, joy3h;
|
|
|
|
uint8 joy4l, joy4h;
|
|
|
|
} status;
|
2010-08-09 13:28:56 +00:00
|
|
|
};
|
2010-08-09 13:31:09 +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
|
|
|
extern CPU cpu;
|