mirror of https://github.com/mgba-emu/mgba.git
GBA BIOS: Implement BitUnPack
This commit is contained in:
parent
e5a9f8a030
commit
8fd14f40c0
1
CHANGES
1
CHANGES
|
@ -30,6 +30,7 @@ Bugfixes:
|
||||||
- Qt: Fix Qt Multimedia audio driver on big endian
|
- Qt: Fix Qt Multimedia audio driver on big endian
|
||||||
- GBA: Fix IRQs firing after already being cleared
|
- GBA: Fix IRQs firing after already being cleared
|
||||||
- All: Fix fullscreen config option being ignored
|
- All: Fix fullscreen config option being ignored
|
||||||
|
- GBA BIOS: Implement BitUnPack
|
||||||
Misc:
|
Misc:
|
||||||
- SDL: Remove scancode key input
|
- SDL: Remove scancode key input
|
||||||
- GBA Video: Clean up unused timers
|
- GBA Video: Clean up unused timers
|
||||||
|
|
|
@ -20,6 +20,7 @@ static void _unLz77(struct GBA* gba, int width);
|
||||||
static void _unHuffman(struct GBA* gba);
|
static void _unHuffman(struct GBA* gba);
|
||||||
static void _unRl(struct GBA* gba, int width);
|
static void _unRl(struct GBA* gba, int width);
|
||||||
static void _unFilter(struct GBA* gba, int inwidth, int outwidth);
|
static void _unFilter(struct GBA* gba, int inwidth, int outwidth);
|
||||||
|
static void _unBitPack(struct GBA* gba);
|
||||||
|
|
||||||
static void _SoftReset(struct GBA* gba) {
|
static void _SoftReset(struct GBA* gba) {
|
||||||
struct ARMCore* cpu = gba->cpu;
|
struct ARMCore* cpu = gba->cpu;
|
||||||
|
@ -385,6 +386,22 @@ void GBASwi16(struct ARMCore* cpu, int immediate) {
|
||||||
case 0xF:
|
case 0xF:
|
||||||
_ObjAffineSet(gba);
|
_ObjAffineSet(gba);
|
||||||
break;
|
break;
|
||||||
|
case 0x10:
|
||||||
|
if (cpu->gprs[0] < BASE_WORKING_RAM) {
|
||||||
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack source");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (cpu->gprs[1] >> BASE_OFFSET) {
|
||||||
|
default:
|
||||||
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack destination");
|
||||||
|
// Fall through
|
||||||
|
case REGION_WORKING_RAM:
|
||||||
|
case REGION_WORKING_IRAM:
|
||||||
|
case REGION_VRAM:
|
||||||
|
_unBitPack(gba);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
case 0x12:
|
case 0x12:
|
||||||
if (cpu->gprs[0] < BASE_WORKING_RAM) {
|
if (cpu->gprs[0] < BASE_WORKING_RAM) {
|
||||||
|
@ -736,3 +753,63 @@ static void _unFilter(struct GBA* gba, int inwidth, int outwidth) {
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _unBitPack(struct GBA* gba) {
|
||||||
|
struct ARMCore* cpu = gba->cpu;
|
||||||
|
uint32_t source = cpu->gprs[0];
|
||||||
|
uint32_t dest = cpu->gprs[1];
|
||||||
|
uint32_t info = cpu->gprs[2];
|
||||||
|
unsigned sourceLen = cpu->memory.load16(cpu, info, 0);
|
||||||
|
unsigned sourceWidth = cpu->memory.load8(cpu, info + 2, 0);
|
||||||
|
unsigned destWidth = cpu->memory.load8(cpu, info + 3, 0);
|
||||||
|
switch (sourceWidth) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack source width: %u", sourceWidth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (destWidth) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
case 16:
|
||||||
|
case 32:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack destination width: %u", destWidth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t bias = cpu->memory.load32(cpu, info + 4, 0);
|
||||||
|
uint8_t in = 0;
|
||||||
|
uint32_t out = 0;
|
||||||
|
int bitsRemaining = 0;
|
||||||
|
int bitsEaten = 0;
|
||||||
|
while (sourceLen > 0) {
|
||||||
|
if (!bitsRemaining) {
|
||||||
|
in = cpu->memory.load8(cpu, source, 0);
|
||||||
|
bitsRemaining = 8;
|
||||||
|
++source;
|
||||||
|
--sourceLen;
|
||||||
|
}
|
||||||
|
unsigned scaled = in & ((1 << sourceWidth) - 1);
|
||||||
|
in >>= sourceWidth;
|
||||||
|
if (scaled || bias & 0x80000000) {
|
||||||
|
scaled += bias & 0x7FFFFFFF;
|
||||||
|
scaled &= (1 << destWidth) - 1;
|
||||||
|
}
|
||||||
|
bitsRemaining -= sourceWidth;
|
||||||
|
out |= scaled << bitsEaten;
|
||||||
|
bitsEaten += destWidth;
|
||||||
|
if (bitsEaten == 32) {
|
||||||
|
cpu->memory.store32(cpu, dest, out, 0);
|
||||||
|
bitsEaten = 0;
|
||||||
|
out = 0;
|
||||||
|
dest += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue