mirror of https://github.com/bsnes-emu/bsnes.git
implement additional latch logic
fixes tests 06, 07, 08, 09, 13... mostly at least
This commit is contained in:
parent
420146929c
commit
ed21294992
|
@ -122,6 +122,9 @@ private:
|
||||||
|
|
||||||
uint2 autoJoypadPort0 = 0;
|
uint2 autoJoypadPort0 = 0;
|
||||||
uint2 autoJoypadPort1 = 0;
|
uint2 autoJoypadPort1 = 0;
|
||||||
|
|
||||||
|
bool cpuLatch = false;
|
||||||
|
bool autoJoypadLatch = false;
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
struct IO {
|
struct IO {
|
||||||
|
|
|
@ -130,18 +130,20 @@ auto CPU::writeCPU(uint addr, uint8 data) -> void {
|
||||||
//bit 0 is shared between JOYSER0 and JOYSER1:
|
//bit 0 is shared between JOYSER0 and JOYSER1:
|
||||||
//strobing $4016.d0 affects both controller port latches.
|
//strobing $4016.d0 affects both controller port latches.
|
||||||
//$4017 bit 0 writes are ignored.
|
//$4017 bit 0 writes are ignored.
|
||||||
controllerPort1.device->latch(data & 1);
|
status.cpuLatch = data & 1;
|
||||||
controllerPort2.device->latch(data & 1);
|
controllerPort1.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
|
controllerPort2.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x4200: //NMITIMEN
|
case 0x4200: //NMITIMEN
|
||||||
io.autoJoypadPoll = data & 1;
|
io.autoJoypadPoll = data & 1;
|
||||||
if(status.autoJoypadCounter < 2) {
|
if(status.autoJoypadCounter == 0) {
|
||||||
// allow controller latches during this time
|
// allow controller latches during this time
|
||||||
controllerPort1.device->latch(io.autoJoypadPoll);
|
status.autoJoypadLatch = io.autoJoypadPoll;
|
||||||
controllerPort2.device->latch(io.autoJoypadPoll);
|
controllerPort1.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
}else if (!io.autoJoypadPoll) {
|
controllerPort2.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
status.autoJoypadCounter = 33; // Disable auto-joypad read
|
} else if (!io.autoJoypadPoll && status.autoJoypadCounter >= 2) {
|
||||||
|
status.autoJoypadCounter = 33;
|
||||||
}
|
}
|
||||||
|
|
||||||
nmitimenUpdate(data);
|
nmitimenUpdate(data);
|
||||||
|
|
|
@ -48,6 +48,9 @@ auto CPU::serialize(serializer& s) -> void {
|
||||||
s.integer(status.autoJoypadPort0);
|
s.integer(status.autoJoypadPort0);
|
||||||
s.integer(status.autoJoypadPort1);
|
s.integer(status.autoJoypadPort1);
|
||||||
|
|
||||||
|
s.boolean(status.cpuLatch);
|
||||||
|
s.boolean(status.autoJoypadLatch);
|
||||||
|
|
||||||
s.integer(io.wramAddress);
|
s.integer(io.wramAddress);
|
||||||
|
|
||||||
s.boolean(io.hirqEnable);
|
s.boolean(io.hirqEnable);
|
||||||
|
|
|
@ -214,15 +214,9 @@ auto CPU::joypadEdge() -> void {
|
||||||
|
|
||||||
if(status.autoJoypadCounter == 0) {
|
if(status.autoJoypadCounter == 0) {
|
||||||
//latch controller states on the first polling cycle
|
//latch controller states on the first polling cycle
|
||||||
controllerPort1.device->latch(io.autoJoypadPoll);
|
status.autoJoypadLatch = io.autoJoypadPoll;
|
||||||
controllerPort2.device->latch(io.autoJoypadPoll);
|
controllerPort1.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
}
|
controllerPort2.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
|
|
||||||
if(status.autoJoypadCounter == 1) {
|
|
||||||
//release latch and begin reading on the second cycle
|
|
||||||
controllerPort1.device->latch(0);
|
|
||||||
controllerPort2.device->latch(0);
|
|
||||||
|
|
||||||
if(io.autoJoypadPoll) {
|
if(io.autoJoypadPoll) {
|
||||||
//shift registers are cleared to zero at start of auto-joypad polling
|
//shift registers are cleared to zero at start of auto-joypad polling
|
||||||
io.joy1 = 0;
|
io.joy1 = 0;
|
||||||
|
@ -232,13 +226,20 @@ auto CPU::joypadEdge() -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status.autoJoypadCounter >= 2) {
|
if(status.autoJoypadCounter == 1) {
|
||||||
if (!io.autoJoypadPoll) {
|
//release latch and begin reading on the second cycle
|
||||||
// if auto-joypad polling is disabled at this point skip the rest of the polling
|
status.autoJoypadLatch = 0;
|
||||||
status.autoJoypadCounter = 33;
|
controllerPort1.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
return;
|
controllerPort2.device->latch(status.autoJoypadLatch | status.cpuLatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(status.autoJoypadCounter != 1 && !io.autoJoypadPoll) {
|
||||||
|
// if auto-joypad polling is disabled at this point skip the rest of the polling
|
||||||
|
status.autoJoypadCounter = 33;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(status.autoJoypadCounter >= 2) {
|
||||||
//sixteen bits are shifted into joy{1-4}, one bit per 256 clocks
|
//sixteen bits are shifted into joy{1-4}, one bit per 256 clocks
|
||||||
//the bits are read on one 128-clock cycle and written on the next
|
//the bits are read on one 128-clock cycle and written on the next
|
||||||
if ((status.autoJoypadCounter & 1) == 0) {
|
if ((status.autoJoypadCounter & 1) == 0) {
|
||||||
|
|
Loading…
Reference in New Issue