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);
case GB_IO_JOYP:
GB_timing_sync(gb);
return gb->io_registers[addr & 0xFF] | 0xC0;
case GB_IO_TMA:
case GB_IO_LCDC:
case GB_IO_SCY:

View File

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

View File

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

View File

@ -27,9 +27,8 @@ auto ICD::apuWrite(float left, float right) -> void {
auto ICD::joypWrite(bool p14, bool p15) -> void {
//joypad handling
if(p14 == 1 && p15 == 1) {
if(joyp14Lock == 0 && joyp15Lock == 0) {
joyp14Lock = 1;
joyp15Lock = 1;
if(joypLock == 0) {
joypLock = 1;
joypID++;
if(mltReq == 0) joypID &= 0; //1-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);
if(p14 == 0 && p15 == 1) joyp14Lock = 0;
if(p14 == 1 && p15 == 0) joyp15Lock = 0;
if(p14 == 0 && p15 == 1);
if(p14 == 1 && p15 == 0) joypLock ^= 1;
//packet handling
if(p14 == 0 && p15 == 0) { //pulse
pulseLock = false;
pulseLock = 0;
packetOffset = 0;
bitOffset = 0;
strobeLock = true;
packetLock = false;
strobeLock = 1;
packetLock = 0;
return;
}
if(pulseLock) return;
if(pulseLock == 1) return;
if(p14 == 1 && p15 == 1) {
strobeLock = false;
strobeLock = 0;
return;
}
if(strobeLock) {
if(strobeLock == 1) {
if(p14 == 1 || p15 == 1) { //malformed packet
packetLock = false;
pulseLock = true;
packetLock = 0;
pulseLock = 1;
bitOffset = 0;
packetOffset = 0;
} else {
@ -85,18 +84,21 @@ auto ICD::joypWrite(bool p14, bool p15) -> void {
//p14:0, p15:1 = 0
//p14:1, p15:0 = 1
bool bit = p15 == 0;
strobeLock = true;
strobeLock = 1;
if(packetLock) {
if(packetLock == 1) {
if(p14 == 0 && p15 == 1) {
if((joypPacket[0] >> 3) == 0x11) {
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;
packetLock = false;
pulseLock = true;
packetLock = 0;
pulseLock = 1;
}
return;
}
@ -107,5 +109,5 @@ auto ICD::joypWrite(bool p14, bool p15) -> void {
joypPacket[packetOffset] = bitData;
if(++packetOffset) return;
packetLock = true;
packetLock = 1;
}

View File

@ -16,8 +16,7 @@ auto ICD::serialize(serializer& s) -> void {
s.integer(packetSize);
s.integer(joypID);
s.integer(joyp14Lock);
s.integer(joyp15Lock);
s.integer(joypLock);
s.integer(pulseLock);
s.integer(strobeLock);
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) << 0;
if(headered) offset -= 512;
if(offset < 0 || offset > 16_MiB) return false; //sanity check
uint16_t length = 0;
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);
while(repeat--) data(offset++) = fill;
while(repeat--) {
if(offset >= 0) data(offset) = fill;
offset++;
}
} else {
while(length--) data(offset++) = patch(index++, 0);
while(length--) {
if(offset >= 0) data(offset) = patch(index, 0);
offset++;
index++;
}
}
}