2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::readAPU(uint24 addr, uint8 data) -> uint8 {
|
2016-03-26 01:56:15 +00:00
|
|
|
synchronizeSMP();
|
|
|
|
return smp.portRead(addr.bits(0,1));
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::readCPU(uint24 addr, uint8 data) -> uint8 {
|
|
|
|
switch((uint16)addr) {
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//WMDATA
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x2180: {
|
|
|
|
return bus.read(0x7e0000 | status.wramAddress++, r.mdr);
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//JOYSER0
|
|
|
|
//7-2 = MDR
|
|
|
|
//1-0 = Joypad serial data
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4016: {
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
uint8 v = r.mdr & 0xfc;
|
|
|
|
v |= SuperFamicom::peripherals.controllerPort1->data();
|
|
|
|
return v;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//JOYSER1
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4017: {
|
2016-03-26 01:56:15 +00:00
|
|
|
//7-5 = MDR
|
|
|
|
//4-2 = Always 1 (pins are connected to GND)
|
|
|
|
//1-0 = Joypad serial data
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
uint8 v = (r.mdr & 0xe0) | 0x1c;
|
|
|
|
v |= SuperFamicom::peripherals.controllerPort2->data();
|
|
|
|
return v;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//RDNMI
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4210: {
|
2016-03-26 01:56:15 +00:00
|
|
|
//7 = NMI acknowledge
|
|
|
|
//6-4 = MDR
|
|
|
|
//3-0 = CPU (5a22) version
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
uint8 v = (r.mdr & 0x70);
|
|
|
|
v |= (uint8)(rdnmi()) << 7;
|
2016-06-17 13:03:54 +00:00
|
|
|
v |= (version & 0x0f);
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
return v;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//TIMEUP
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4211: {
|
2016-03-26 01:56:15 +00:00
|
|
|
//7 = IRQ acknowledge
|
|
|
|
//6-0 = MDR
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
uint8 v = (r.mdr & 0x7f);
|
|
|
|
v |= (uint8)(timeup()) << 7;
|
|
|
|
return v;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//HVBJOY
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4212: {
|
2016-03-26 01:56:15 +00:00
|
|
|
//7 = VBLANK acknowledge
|
|
|
|
//6 = HBLANK acknowledge
|
|
|
|
//5-1 = MDR
|
|
|
|
//0 = JOYPAD acknowledge
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
uint8 v = (r.mdr & 0x3e);
|
2016-06-17 13:03:54 +00:00
|
|
|
if(status.autoJoypadActive) v |= 0x01;
|
Update to v098r11 release.
byuu says:
Changelog:
- fixed nall/path.hpp compilation issue
- fixed ruby/audio/xaudio header declaration compilation issue (again)
- cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the
file was whitespace overkill)
- added null terminator entry to nall/windows/utf8.hpp argc[] array
- nall/windows/guid.hpp uses the Windows API for generating the GUID
- this should stop all the bug reports where two nall users were
generating GUIDs at the exact same second
- fixed hiro/cocoa compilation issue with uint# types
- fixed major higan/sfc Super Game Boy audio latency issue
- fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions
- major cleanups to higan/processor/r65816 core
- merged emulation/native-mode opcodes
- use camel-case naming on memory.hpp functions
- simplify address masking code for memory.hpp functions
- simplify a few opcodes themselves (avoid redundant copies, etc)
- rename regs.* to r.* to match modern convention of other CPU cores
- removed device.order<> concept from Emulator::Interface
- cores will now do the translation to make the job of the UI easier
- fixed plurality naming of arrays in Emulator::Interface
- example: emulator.ports[p].devices[d].inputs[i]
- example: vector<Medium> media
- probably more surprises
Major show-stoppers to the next official release:
- we need to work on GB core improvements: LY=153/0 case, multiple STAT
IRQs case, GBC audio output regs, etc.
- we need to re-add software cursors for light guns (Super Scope,
Justifier)
- after the above, we need to fix the turbo button for the Super Scope
I really have no idea how I want to implement the light guns. Ideally,
we'd want it in higan/video, so we can support the NES Zapper with the
same code. But this isn't going to be easy, because only the SNES knows
when its output is interlaced, and its resolutions can vary as
{256,512}x{224,240,448,480} which requires pixel doubling that was
hard-coded to the SNES-specific behavior, but isn't appropriate to be
exposed in higan/video.
2016-05-25 11:13:02 +00:00
|
|
|
if(hcounter() <= 2 || hcounter() >= 1096) v |= 0x40; //hblank
|
|
|
|
if(vcounter() >= ppu.vdisp()) v |= 0x80; //vblank
|
|
|
|
return v;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//RDIO
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4213: {
|
2016-03-26 01:56:15 +00:00
|
|
|
return status.pio;
|
|
|
|
}
|
|
|
|
|
|
|
|
//RDDIVL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4214: {
|
2016-03-26 01:56:15 +00:00
|
|
|
return status.rddiv.byte(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//RDDIVH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4215: {
|
2016-03-26 01:56:15 +00:00
|
|
|
return status.rddiv.byte(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//RDMPYL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4216: {
|
2016-03-26 01:56:15 +00:00
|
|
|
return status.rdmpy.byte(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//RDMPYH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4217: {
|
2016-03-26 01:56:15 +00:00
|
|
|
return status.rdmpy.byte(1);
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4218: return status.joy1.byte(0); //JOY1L
|
|
|
|
case 0x4219: return status.joy1.byte(1); //JOY1H
|
|
|
|
case 0x421a: return status.joy2.byte(0); //JOY2L
|
|
|
|
case 0x421b: return status.joy2.byte(1); //JOY2H
|
|
|
|
case 0x421c: return status.joy3.byte(0); //JOY3L
|
|
|
|
case 0x421d: return status.joy3.byte(1); //JOY3H
|
|
|
|
case 0x421e: return status.joy4.byte(0); //JOY4L
|
|
|
|
case 0x421f: return status.joy4.byte(1); //JOY4H
|
|
|
|
|
|
|
|
}
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::readDMA(uint24 addr, uint8 data) -> uint8 {
|
2016-03-26 01:56:15 +00:00
|
|
|
auto& channel = this->channel[addr.bits(4,6)];
|
2016-06-17 13:03:54 +00:00
|
|
|
|
|
|
|
switch(addr & 0xff0f) {
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//DMAPx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4300: return (
|
|
|
|
channel.transferMode << 0
|
|
|
|
| channel.fixedTransfer << 3
|
|
|
|
| channel.reverseTransfer << 4
|
|
|
|
| channel.unused << 5
|
|
|
|
| channel.indirect << 6
|
|
|
|
| channel.direction << 7
|
2016-03-26 01:56:15 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
//BBADx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4301: return channel.targetAddress;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1TxL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4302: return channel.sourceAddress >> 0;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1TxH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4303: return channel.sourceAddress >> 8;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1Bx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4304: return channel.sourceBank;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
//DASxL -- union { uint16 transferSize; uint16 indirectAddress; };
|
|
|
|
case 0x4305: return channel.transferSize.byte(0);
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
//DASxH -- union { uint16 transferSize; uint16 indirectAddress; };
|
|
|
|
case 0x4306: return channel.transferSize.byte(1);
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//DASBx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4307: return channel.indirectBank;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A2AxL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4308: return channel.hdmaAddress.byte(0);
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A2AxH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4309: return channel.hdmaAddress.byte(1);
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//NTRLx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x430a: return channel.lineCounter;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//???
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x430b:
|
|
|
|
case 0x430f: return channel.unknown;
|
|
|
|
|
|
|
|
}
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::writeAPU(uint24 addr, uint8 data) -> void {
|
2016-03-26 01:56:15 +00:00
|
|
|
synchronizeSMP();
|
|
|
|
return portWrite(addr.bits(0,1), data);
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::writeCPU(uint24 addr, uint8 data) -> void {
|
|
|
|
switch((uint16)addr) {
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//WMDATA
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x2180: {
|
|
|
|
return bus.write(0x7e0000 | status.wramAddress++, data);
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x2181: status.wramAddress.bits( 0, 7) = data; return; //WMADDL
|
|
|
|
case 0x2182: status.wramAddress.bits( 8,15) = data; return; //WMADDM
|
|
|
|
case 0x2183: status.wramAddress.bit (16 ) = data.bit(0); return; //WMADDH
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//JOYSER0
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4016: {
|
2016-03-26 01:56:15 +00:00
|
|
|
//bit 0 is shared between JOYSER0 and JOYSER1, therefore
|
|
|
|
//strobing $4016.d0 affects both controller port latches.
|
|
|
|
//$4017 bit 0 writes are ignored.
|
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
|
|
|
SuperFamicom::peripherals.controllerPort1->latch(data.bit(0));
|
|
|
|
SuperFamicom::peripherals.controllerPort2->latch(data.bit(0));
|
2016-06-17 13:03:54 +00:00
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//NMITIMEN
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4200: {
|
|
|
|
status.autoJoypadPoll = data.bit(0);
|
2016-03-26 01:56:15 +00:00
|
|
|
nmitimenUpdate(data);
|
2016-06-17 13:03:54 +00:00
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//WRIO
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4201: {
|
2016-04-09 05:20:41 +00:00
|
|
|
if(status.pio.bit(7) && !data.bit(7)) ppu.latchCounters();
|
2016-03-26 01:56:15 +00:00
|
|
|
status.pio = data;
|
2016-06-17 13:03:54 +00:00
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//WRMPYA
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4202: status.wrmpya = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//WRMPYB
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4203: {
|
2016-03-26 01:56:15 +00:00
|
|
|
status.rdmpy = 0;
|
|
|
|
if(alu.mpyctr || alu.divctr) return;
|
|
|
|
|
|
|
|
status.wrmpyb = data;
|
|
|
|
status.rddiv = (status.wrmpyb << 8) | status.wrmpya;
|
|
|
|
|
|
|
|
alu.mpyctr = 8; //perform multiplication over the next eight cycles
|
|
|
|
alu.shift = status.wrmpyb;
|
2016-06-17 13:03:54 +00:00
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4204: { status.wrdiva.byte(0) = data; return; } //WRDIVL
|
|
|
|
case 0x4205: { status.wrdiva.byte(1) = data; return; } //WRDIVH
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//WRDIVB
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4206: {
|
2016-03-26 01:56:15 +00:00
|
|
|
status.rdmpy = status.wrdiva;
|
|
|
|
if(alu.mpyctr || alu.divctr) return;
|
|
|
|
|
|
|
|
status.wrdivb = data;
|
|
|
|
|
|
|
|
alu.divctr = 16; //perform division over the next sixteen cycles
|
|
|
|
alu.shift = status.wrdivb << 16;
|
2016-06-17 13:03:54 +00:00
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4207: status.hirqPos.bits(0,7) = data; return; //HTIMEL
|
|
|
|
case 0x4208: status.hirqPos.bit (8 ) = data.bit(0); return; //HTIMEH
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4209: status.virqPos.bits(0,7) = data; return; //VTIMEL
|
|
|
|
case 0x420a: status.virqPos.bit (8 ) = data.bit(0); return; //VTIMEH
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//DMAEN
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x420b: {
|
|
|
|
for(auto n : range(8)) channel[n].dmaEnabled = data.bit(n);
|
|
|
|
if(data) status.dmaPending = true;
|
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//HDMAEN
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x420c: {
|
|
|
|
for(auto n : range(8)) channel[n].hdmaEnabled = data.bit(n);
|
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//MEMSEL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x420d: {
|
|
|
|
status.romSpeed = data.bit(0) ? 6 : 8;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
auto CPU::writeDMA(uint24 addr, uint8 data) -> void {
|
2016-03-26 01:56:15 +00:00
|
|
|
auto& channel = this->channel[addr.bits(4,6)];
|
2016-06-17 13:03:54 +00:00
|
|
|
|
|
|
|
switch(addr & 0xff0f) {
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//DMAPx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4300: {
|
|
|
|
channel.transferMode = data.bits(0,2);
|
|
|
|
channel.fixedTransfer = data.bit (3);
|
|
|
|
channel.reverseTransfer = data.bit (4);
|
|
|
|
channel.unused = data.bit (5);
|
|
|
|
channel.indirect = data.bit (6);
|
|
|
|
channel.direction = data.bit (7);
|
|
|
|
return;
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//DDBADx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4301: channel.targetAddress = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1TxL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4302: channel.sourceAddress.byte(0) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1TxH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4303: channel.sourceAddress.byte(1) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A1Bx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4304: channel.sourceBank = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
//DASxL -- union { uint16 transferSize; uint16 indirectAddress; };
|
|
|
|
case 0x4305: channel.transferSize.byte(0) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2016-06-17 13:03:54 +00:00
|
|
|
//DASxH -- union { uint16 transferSize; uint16 indirectAddress; };
|
|
|
|
case 0x4306: channel.transferSize.byte(1) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//DASBx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4307: channel.indirectBank = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A2AxL
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4308: channel.hdmaAddress.byte(0) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//A2AxH
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x4309: channel.hdmaAddress.byte(1) = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//NTRLx
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x430a: channel.lineCounter = data; return;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//???
|
2016-06-17 13:03:54 +00:00
|
|
|
case 0x430b:
|
|
|
|
case 0x430f: channel.unknown = data; return;
|
|
|
|
|
2016-03-26 01:56:15 +00:00
|
|
|
}
|
|
|
|
}
|