Fix SGB JOYP incrementing behavior [endrift]

Fix GB JOYP read setting d6+d7 in SameBoy
Improve headered IPS patch handling
This commit is contained in:
byuu
2019-09-03 17:55:54 +09:00
parent 2bb1606552
commit 90f094b931
6 changed files with 35 additions and 29 deletions

View File

@@ -310,6 +310,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
(gb->apu.is_active[GB_WAVE] ? (gb->apu.samples[GB_WAVE]) : 0); (gb->apu.is_active[GB_WAVE] ? (gb->apu.samples[GB_WAVE]) : 0);
case GB_IO_JOYP: case GB_IO_JOYP:
GB_timing_sync(gb); GB_timing_sync(gb);
return gb->io_registers[addr & 0xFF] | 0xC0;
case GB_IO_TMA: case GB_IO_TMA:
case GB_IO_LCDC: case GB_IO_LCDC:
case GB_IO_SCY: case GB_IO_SCY:

View File

@@ -147,9 +147,8 @@ auto ICD::power(bool reset) -> void {
for(auto& packet : this->packet) packet = {}; for(auto& packet : this->packet) packet = {};
packetSize = 0; packetSize = 0;
joypID = 3; joypID = 0;
joyp14Lock = 0; joypLock = 1;
joyp15Lock = 0;
pulseLock = 1; pulseLock = 1;
strobeLock = 0; strobeLock = 0;
packetLock = 0; packetLock = 0;

View File

@@ -44,8 +44,7 @@ private:
uint7 packetSize; uint7 packetSize;
uint2 joypID; uint2 joypID;
uint1 joyp14Lock; uint1 joypLock;
uint1 joyp15Lock;
uint1 pulseLock; uint1 pulseLock;
uint1 strobeLock; uint1 strobeLock;
uint1 packetLock; uint1 packetLock;

View File

@@ -27,9 +27,8 @@ auto ICD::apuWrite(float left, float right) -> void {
auto ICD::joypWrite(bool p14, bool p15) -> void { auto ICD::joypWrite(bool p14, bool p15) -> void {
//joypad handling //joypad handling
if(p14 == 1 && p15 == 1) { if(p14 == 1 && p15 == 1) {
if(joyp14Lock == 0 && joyp15Lock == 0) { if(joypLock == 0) {
joyp14Lock = 1; joypLock = 1;
joyp15Lock = 1;
joypID++; joypID++;
if(mltReq == 0) joypID &= 0; //1-player mode if(mltReq == 0) joypID &= 0; //1-player mode
if(mltReq == 1) joypID &= 1; //2-player mode if(mltReq == 1) joypID &= 1; //2-player mode
@@ -51,30 +50,30 @@ auto ICD::joypWrite(bool p14, bool p15) -> void {
GB_icd_set_joyp(&sameboy, input); GB_icd_set_joyp(&sameboy, input);
if(p14 == 0 && p15 == 1) joyp14Lock = 0; if(p14 == 0 && p15 == 1);
if(p14 == 1 && p15 == 0) joyp15Lock = 0; if(p14 == 1 && p15 == 0) joypLock ^= 1;
//packet handling //packet handling
if(p14 == 0 && p15 == 0) { //pulse if(p14 == 0 && p15 == 0) { //pulse
pulseLock = false; pulseLock = 0;
packetOffset = 0; packetOffset = 0;
bitOffset = 0; bitOffset = 0;
strobeLock = true; strobeLock = 1;
packetLock = false; packetLock = 0;
return; return;
} }
if(pulseLock) return; if(pulseLock == 1) return;
if(p14 == 1 && p15 == 1) { if(p14 == 1 && p15 == 1) {
strobeLock = false; strobeLock = 0;
return; return;
} }
if(strobeLock) { if(strobeLock == 1) {
if(p14 == 1 || p15 == 1) { //malformed packet if(p14 == 1 || p15 == 1) { //malformed packet
packetLock = false; packetLock = 0;
pulseLock = true; pulseLock = 1;
bitOffset = 0; bitOffset = 0;
packetOffset = 0; packetOffset = 0;
} else { } else {
@@ -85,18 +84,21 @@ auto ICD::joypWrite(bool p14, bool p15) -> void {
//p14:0, p15:1 = 0 //p14:0, p15:1 = 0
//p14:1, p15:0 = 1 //p14:1, p15:0 = 1
bool bit = p15 == 0; bool bit = p15 == 0;
strobeLock = true; strobeLock = 1;
if(packetLock) { if(packetLock == 1) {
if(p14 == 0 && p15 == 1) { if(p14 == 0 && p15 == 1) {
if((joypPacket[0] >> 3) == 0x11) { if((joypPacket[0] >> 3) == 0x11) {
mltReq = joypPacket[1] & 3; mltReq = joypPacket[1] & 3;
joypID = 3; if(mltReq == 0) joypID &= 0; //1-player mode
if(mltReq == 1) joypID &= 1; //2-player mode
if(mltReq == 2) joypID &= 3; //4-player mode (unverified; but the most likely behavior)
if(mltReq == 3) joypID &= 3; //4-player mode
} }
if(packetSize < 64) packet[packetSize++] = joypPacket; if(packetSize < 64) packet[packetSize++] = joypPacket;
packetLock = false; packetLock = 0;
pulseLock = true; pulseLock = 1;
} }
return; return;
} }
@@ -107,5 +109,5 @@ auto ICD::joypWrite(bool p14, bool p15) -> void {
joypPacket[packetOffset] = bitData; joypPacket[packetOffset] = bitData;
if(++packetOffset) return; if(++packetOffset) return;
packetLock = true; packetLock = 1;
} }

View File

@@ -16,8 +16,7 @@ auto ICD::serialize(serializer& s) -> void {
s.integer(packetSize); s.integer(packetSize);
s.integer(joypID); s.integer(joypID);
s.integer(joyp14Lock); s.integer(joypLock);
s.integer(joyp15Lock);
s.integer(pulseLock); s.integer(pulseLock);
s.integer(strobeLock); s.integer(strobeLock);
s.integer(packetLock); s.integer(packetLock);

View File

@@ -71,7 +71,6 @@ auto Program::applyPatchIPS(vector<uint8_t>& data, string location) -> bool {
offset |= patch(index++, 0) << 8; offset |= patch(index++, 0) << 8;
offset |= patch(index++, 0) << 0; offset |= patch(index++, 0) << 0;
if(headered) offset -= 512; if(headered) offset -= 512;
if(offset < 0 || offset > 16_MiB) return false; //sanity check
uint16_t length = 0; uint16_t length = 0;
length |= patch(index++, 0) << 8; length |= patch(index++, 0) << 8;
@@ -84,9 +83,16 @@ auto Program::applyPatchIPS(vector<uint8_t>& data, string location) -> bool {
uint8_t fill = patch(index++, 0); uint8_t fill = patch(index++, 0);
while(repeat--) data(offset++) = fill; while(repeat--) {
if(offset >= 0) data(offset) = fill;
offset++;
}
} else { } else {
while(length--) data(offset++) = patch(index++, 0); while(length--) {
if(offset >= 0) data(offset) = patch(index, 0);
offset++;
index++;
}
} }
} }