2013-01-23 08:28:35 +00:00
|
|
|
#include <sfc/sfc.hpp>
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2013-01-23 08:28:35 +00:00
|
|
|
namespace SuperFamicom {
|
2010-08-09 13:28:56 +00:00
|
|
|
|
Update to v098r03 release.
byuu says:
It took several hours, but I've rebuilt much of the SNES' bus memory
mapping architecture.
The new design unifies the cartridge string-based mapping
("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function
now has an accompanying unmap() function, and instead of a fixed 256
callbacks, it'll scan to find the first available slot. unmap() will
free slots up when zero addresses reference a given slot.
The controllers and expansion port are now both entirely dynamic.
Instead of load/unload/power/reset, they only have the constructor
(power/reset/load) and destructor (unload). What this means is you can
now dynamically change even expansion port devices after the system is
loaded.
Note that this is incredibly dangerous and stupid, but ... oh well. The
whole point of this was for 21fx. There's no way to change the expansion
port device prior to loading a game, but if the 21fx isn't active, then
the reset vector hijack won't work. Now you can load a 21fx game, change
the expansion port device, and simply reset the system to active the
device.
The unification of design between controller port devices and expansion
port devices is nice, and overall this results in a reduction of code
(all of the Mapping stuff in Cartridge is gone, replaced with direct bus
mapping.) And there's always the potential to expand this system more in
the future now.
The big missing feature right now is the ability to push/pop mappings.
So if you look at how the 21fx does the reset vector, you might vomit
a little bit. But ... it works.
Also changed exit(0) to _exit(0) in the POSIX version of nall::execute.
[The _exit(0) thing is an attempt to make higan not crash when it tries
to launch icarus and it's not on $PATH. The theory is that higan forks,
then the child tries to exec icarus and fails, so it exits, all the
unique_ptrs clean up their resources and tell the X server to free
things the parent process is still using. Calling _exit() prevents
destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
|
|
|
Satellaview::Satellaview() {
|
|
|
|
bus.map({&Satellaview::read, this}, {&Satellaview::write, this}, "00-3f,80-bf:2188-219f");
|
|
|
|
memory::fill(®s, sizeof regs);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
Update to v098r03 release.
byuu says:
It took several hours, but I've rebuilt much of the SNES' bus memory
mapping architecture.
The new design unifies the cartridge string-based mapping
("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function
now has an accompanying unmap() function, and instead of a fixed 256
callbacks, it'll scan to find the first available slot. unmap() will
free slots up when zero addresses reference a given slot.
The controllers and expansion port are now both entirely dynamic.
Instead of load/unload/power/reset, they only have the constructor
(power/reset/load) and destructor (unload). What this means is you can
now dynamically change even expansion port devices after the system is
loaded.
Note that this is incredibly dangerous and stupid, but ... oh well. The
whole point of this was for 21fx. There's no way to change the expansion
port device prior to loading a game, but if the 21fx isn't active, then
the reset vector hijack won't work. Now you can load a 21fx game, change
the expansion port device, and simply reset the system to active the
device.
The unification of design between controller port devices and expansion
port devices is nice, and overall this results in a reduction of code
(all of the Mapping stuff in Cartridge is gone, replaced with direct bus
mapping.) And there's always the potential to expand this system more in
the future now.
The big missing feature right now is the ability to push/pop mappings.
So if you look at how the 21fx does the reset vector, you might vomit
a little bit. But ... it works.
Also changed exit(0) to _exit(0) in the POSIX version of nall::execute.
[The _exit(0) thing is an attempt to make higan not crash when it tries
to launch icarus and it's not on $PATH. The theory is that higan forks,
then the child tries to exec icarus and fails, so it exits, all the
unique_ptrs clean up their resources and tell the X server to free
things the parent process is still using. Calling _exit() prevents
destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
|
|
|
Satellaview::~Satellaview() {
|
|
|
|
bus.unmap("00-3f,80-bf:2188-219f");
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 09:32:49 +00:00
|
|
|
auto Satellaview::read(uint24 addr, uint8 data) -> uint8 {
|
Update to v098r03 release.
byuu says:
It took several hours, but I've rebuilt much of the SNES' bus memory
mapping architecture.
The new design unifies the cartridge string-based mapping
("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function
now has an accompanying unmap() function, and instead of a fixed 256
callbacks, it'll scan to find the first available slot. unmap() will
free slots up when zero addresses reference a given slot.
The controllers and expansion port are now both entirely dynamic.
Instead of load/unload/power/reset, they only have the constructor
(power/reset/load) and destructor (unload). What this means is you can
now dynamically change even expansion port devices after the system is
loaded.
Note that this is incredibly dangerous and stupid, but ... oh well. The
whole point of this was for 21fx. There's no way to change the expansion
port device prior to loading a game, but if the 21fx isn't active, then
the reset vector hijack won't work. Now you can load a 21fx game, change
the expansion port device, and simply reset the system to active the
device.
The unification of design between controller port devices and expansion
port devices is nice, and overall this results in a reduction of code
(all of the Mapping stuff in Cartridge is gone, replaced with direct bus
mapping.) And there's always the potential to expand this system more in
the future now.
The big missing feature right now is the ability to push/pop mappings.
So if you look at how the 21fx does the reset vector, you might vomit
a little bit. But ... it works.
Also changed exit(0) to _exit(0) in the POSIX version of nall::execute.
[The _exit(0) thing is an attempt to make higan not crash when it tries
to launch icarus and it's not on $PATH. The theory is that higan forks,
then the child tries to exec icarus and fails, so it exits, all the
unique_ptrs clean up their resources and tell the X server to free
things the parent process is still using. Calling _exit() prevents
destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
|
|
|
switch(addr &= 0xffff) {
|
2013-05-05 09:21:30 +00:00
|
|
|
case 0x2188: return regs.r2188;
|
|
|
|
case 0x2189: return regs.r2189;
|
|
|
|
case 0x218a: return regs.r218a;
|
|
|
|
case 0x218c: return regs.r218c;
|
|
|
|
case 0x218e: return regs.r218e;
|
|
|
|
case 0x218f: return regs.r218f;
|
|
|
|
case 0x2190: return regs.r2190;
|
|
|
|
|
|
|
|
case 0x2192: {
|
Update to v095r05 release.
byuu says:
Changelog:
- GBA: lots of emulation improvements
- PPU PRAM is 16-bits wide
- DMA masks &~1/Half, &~3/Word
- VRAM OBJ 8-bit writes are ignored
- OAM 8-bit writes are ignored
- BGnCNT unused bits are writable*
- BG(0,1)CNT can't set the d13
- BLDALPHA is readable (fixes Donkey Kong Country, etc)
- SNES: lots of code cleanups
- sfc/chip => sfc/coprocessor
- UI: save most recent controller selection
GBA test scores: 1552/1552, 37/38, 1020/1260
(* forgot to add the value to the read function, so endrift's I/O tests
for them will fail. Fixed locally.)
Note: SNES is the only system with multiple controller/expansion port
options, and as such is the only one with a "None" option. Because it's
shared by the controller and expansion port, it ends up sorted first in
the list. This means that on your first run, you'll need to go to Super
Famicom->Controller Port 1 and select "Gamepad", otherwise input won't
work.
Also note that changing the expansion port device requires loading a new
cart. Unlike controllers, you aren't meant to hotplug expansion port
devices.
2015-11-12 10:15:03 +00:00
|
|
|
uint counter = regs.r2192_counter++;
|
2013-05-05 09:21:30 +00:00
|
|
|
if(regs.r2192_counter >= 18) regs.r2192_counter = 0;
|
|
|
|
|
|
|
|
if(counter == 0) {
|
|
|
|
time_t rawtime;
|
|
|
|
time(&rawtime);
|
|
|
|
tm* t = localtime(&rawtime);
|
|
|
|
|
|
|
|
regs.r2192_hour = t->tm_hour;
|
|
|
|
regs.r2192_minute = t->tm_min;
|
|
|
|
regs.r2192_second = t->tm_sec;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(counter) {
|
|
|
|
case 0: return 0x00; //???
|
|
|
|
case 1: return 0x00; //???
|
|
|
|
case 2: return 0x00; //???
|
|
|
|
case 3: return 0x00; //???
|
|
|
|
case 4: return 0x00; //???
|
|
|
|
case 5: return 0x01;
|
|
|
|
case 6: return 0x01;
|
|
|
|
case 7: return 0x00;
|
|
|
|
case 8: return 0x00;
|
|
|
|
case 9: return 0x00;
|
|
|
|
case 10: return regs.r2192_second;
|
|
|
|
case 11: return regs.r2192_minute;
|
|
|
|
case 12: return regs.r2192_hour;
|
|
|
|
case 13: return 0x00; //???
|
|
|
|
case 14: return 0x00; //???
|
|
|
|
case 15: return 0x00; //???
|
|
|
|
case 16: return 0x00; //???
|
|
|
|
case 17: return 0x00; //???
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2193: return regs.r2193 & ~0x0c;
|
|
|
|
case 0x2194: return regs.r2194;
|
|
|
|
case 0x2196: return regs.r2196;
|
|
|
|
case 0x2197: return regs.r2197;
|
|
|
|
case 0x2199: return regs.r2199;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2015-12-14 09:41:06 +00:00
|
|
|
return data;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 09:32:49 +00:00
|
|
|
auto Satellaview::write(uint24 addr, uint8 data) -> void {
|
Update to v098r03 release.
byuu says:
It took several hours, but I've rebuilt much of the SNES' bus memory
mapping architecture.
The new design unifies the cartridge string-based mapping
("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function
now has an accompanying unmap() function, and instead of a fixed 256
callbacks, it'll scan to find the first available slot. unmap() will
free slots up when zero addresses reference a given slot.
The controllers and expansion port are now both entirely dynamic.
Instead of load/unload/power/reset, they only have the constructor
(power/reset/load) and destructor (unload). What this means is you can
now dynamically change even expansion port devices after the system is
loaded.
Note that this is incredibly dangerous and stupid, but ... oh well. The
whole point of this was for 21fx. There's no way to change the expansion
port device prior to loading a game, but if the 21fx isn't active, then
the reset vector hijack won't work. Now you can load a 21fx game, change
the expansion port device, and simply reset the system to active the
device.
The unification of design between controller port devices and expansion
port devices is nice, and overall this results in a reduction of code
(all of the Mapping stuff in Cartridge is gone, replaced with direct bus
mapping.) And there's always the potential to expand this system more in
the future now.
The big missing feature right now is the ability to push/pop mappings.
So if you look at how the 21fx does the reset vector, you might vomit
a little bit. But ... it works.
Also changed exit(0) to _exit(0) in the POSIX version of nall::execute.
[The _exit(0) thing is an attempt to make higan not crash when it tries
to launch icarus and it's not on $PATH. The theory is that higan forks,
then the child tries to exec icarus and fails, so it exits, all the
unique_ptrs clean up their resources and tell the X server to free
things the parent process is still using. Calling _exit() prevents
destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
|
|
|
switch(addr &= 0xffff) {
|
2013-05-05 09:21:30 +00:00
|
|
|
case 0x2188: {
|
|
|
|
regs.r2188 = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2189: {
|
|
|
|
regs.r2189 = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x218a: {
|
|
|
|
regs.r218a = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x218b: {
|
|
|
|
regs.r218b = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x218c: {
|
|
|
|
regs.r218c = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x218e: {
|
|
|
|
regs.r218e = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x218f: {
|
|
|
|
regs.r218e >>= 1;
|
|
|
|
regs.r218e = regs.r218f - regs.r218e;
|
|
|
|
regs.r218f >>= 1;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2191: {
|
|
|
|
regs.r2191 = data;
|
|
|
|
regs.r2192_counter = 0;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2192: {
|
|
|
|
regs.r2190 = 0x80;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2193: {
|
|
|
|
regs.r2193 = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2194: {
|
|
|
|
regs.r2194 = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2197: {
|
|
|
|
regs.r2197 = data;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 0x2199: {
|
|
|
|
regs.r2199 = data;
|
|
|
|
} break;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-23 08:28:35 +00:00
|
|
|
}
|