mirror of https://github.com/mgba-emu/mgba.git
GBA BIOS: Initial HLE timing estimation of UnLz77 functions (fixes #2141)
This commit is contained in:
parent
d1bc394ca3
commit
6f4398a3b9
1
CHANGES
1
CHANGES
|
@ -17,6 +17,7 @@ Emulation fixes:
|
|||
- GB Video: Draw SGB border pieces that overlap GB graphics (fixes mgba.io/i/1339)
|
||||
- GBA: Improve timing when not booting from BIOS
|
||||
- GBA BIOS: Work around IRQ handling hiccup in Mario & Luigi (fixes mgba.io/i/1059)
|
||||
- GBA BIOS: Initial HLE timing estimation of UnLz77 functions (fixes mgba.io/i/2141)
|
||||
- GBA DMA: Fix DMA source direction bits being cleared (fixes mgba.io/i/2410)
|
||||
- GBA I/O: Redo internal key input, enabling edge-based key IRQs
|
||||
- GBA I/O: Disable open bus behavior on invalid register 06A
|
||||
|
|
|
@ -536,6 +536,7 @@ void GBASwi16(struct ARMCore* cpu, int immediate) {
|
|||
case REGION_WORKING_RAM:
|
||||
case REGION_WORKING_IRAM:
|
||||
case REGION_VRAM:
|
||||
useStall = true;
|
||||
_unLz77(gba, immediate == GBA_SWI_LZ77_UNCOMP_WRAM ? 1 : 2);
|
||||
break;
|
||||
}
|
||||
|
@ -644,7 +645,8 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||
struct ARMCore* cpu = gba->cpu;
|
||||
uint32_t source = cpu->gprs[0];
|
||||
uint32_t dest = cpu->gprs[1];
|
||||
int remaining = (cpu->memory.load32(cpu, source, 0) & 0xFFFFFF00) >> 8;
|
||||
int32_t cycles = 20;
|
||||
int remaining = (cpu->memory.load32(cpu, source, &cycles) & 0xFFFFFF00) >> 8;
|
||||
// We assume the signature byte (0x10) is correct
|
||||
int blockheader = 0; // Some compilers warn if this isn't set, even though it's trivially provably always set
|
||||
source += 4;
|
||||
|
@ -654,14 +656,17 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||
int byte;
|
||||
int halfword = 0;
|
||||
while (remaining > 0) {
|
||||
cycles += 14;
|
||||
if (blocksRemaining) {
|
||||
cycles += 18;
|
||||
if (blockheader & 0x80) {
|
||||
// Compressed
|
||||
int block = cpu->memory.load8(cpu, source + 1, 0) | (cpu->memory.load8(cpu, source, 0) << 8);
|
||||
int block = cpu->memory.load8(cpu, source + 1, &cycles) | (cpu->memory.load8(cpu, source, &cycles) << 8);
|
||||
source += 2;
|
||||
disp = dest - (block & 0x0FFF) - 1;
|
||||
bytes = (block >> 12) + 3;
|
||||
while (bytes--) {
|
||||
cycles += 10;
|
||||
if (remaining) {
|
||||
--remaining;
|
||||
} else {
|
||||
|
@ -673,35 +678,36 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||
}
|
||||
}
|
||||
if (width == 2) {
|
||||
byte = (int16_t) cpu->memory.load16(cpu, disp & ~1, 0);
|
||||
byte = (int16_t) cpu->memory.load16(cpu, disp & ~1, &cycles);
|
||||
if (dest & 1) {
|
||||
byte >>= (disp & 1) * 8;
|
||||
halfword |= byte << 8;
|
||||
cpu->memory.store16(cpu, dest ^ 1, halfword, 0);
|
||||
cpu->memory.store16(cpu, dest ^ 1, halfword, &cycles);
|
||||
} else {
|
||||
byte >>= (disp & 1) * 8;
|
||||
halfword = byte & 0xFF;
|
||||
}
|
||||
cycles += 4;
|
||||
} else {
|
||||
byte = cpu->memory.load8(cpu, disp, 0);
|
||||
cpu->memory.store8(cpu, dest, byte, 0);
|
||||
byte = cpu->memory.load8(cpu, disp, &cycles);
|
||||
cpu->memory.store8(cpu, dest, byte, &cycles);
|
||||
}
|
||||
++disp;
|
||||
++dest;
|
||||
}
|
||||
} else {
|
||||
// Uncompressed
|
||||
byte = cpu->memory.load8(cpu, source, 0);
|
||||
byte = cpu->memory.load8(cpu, source, &cycles);
|
||||
++source;
|
||||
if (width == 2) {
|
||||
if (dest & 1) {
|
||||
halfword |= byte << 8;
|
||||
cpu->memory.store16(cpu, dest ^ 1, halfword, 0);
|
||||
cpu->memory.store16(cpu, dest ^ 1, halfword, &cycles);
|
||||
} else {
|
||||
halfword = byte;
|
||||
}
|
||||
} else {
|
||||
cpu->memory.store8(cpu, dest, byte, 0);
|
||||
cpu->memory.store8(cpu, dest, byte, &cycles);
|
||||
}
|
||||
++dest;
|
||||
--remaining;
|
||||
|
@ -709,7 +715,7 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||
blockheader <<= 1;
|
||||
--blocksRemaining;
|
||||
} else {
|
||||
blockheader = cpu->memory.load8(cpu, source, 0);
|
||||
blockheader = cpu->memory.load8(cpu, source, &cycles);
|
||||
++source;
|
||||
blocksRemaining = 8;
|
||||
}
|
||||
|
@ -717,6 +723,7 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||
cpu->gprs[0] = source;
|
||||
cpu->gprs[1] = dest;
|
||||
cpu->gprs[3] = 0;
|
||||
gba->biosStall = cycles;
|
||||
}
|
||||
|
||||
DECL_BITFIELD(HuffmanNode, uint8_t);
|
||||
|
|
|
@ -26,7 +26,7 @@ const uint8_t hleBios[SIZE_BIOS] = {
|
|||
0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00,
|
||||
0x48, 0x03, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00, 0x48, 0x03, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,
|
||||
0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00,
|
||||
|
|
|
@ -137,8 +137,6 @@ GetBiosChecksum:
|
|||
BgAffineSet:
|
||||
ObjAffineSet:
|
||||
BitUnPack:
|
||||
Lz77UnCompWram:
|
||||
Lz77UnCompVram:
|
||||
HuffmanUnComp:
|
||||
RlUnCompWram:
|
||||
RlUnCompVram:
|
||||
|
@ -308,6 +306,8 @@ DivArm:
|
|||
Sqrt:
|
||||
ArcTan:
|
||||
ArcTan2:
|
||||
Lz77UnCompWram:
|
||||
Lz77UnCompVram:
|
||||
|
||||
StallCall:
|
||||
subs r11, #4
|
||||
|
|
Loading…
Reference in New Issue