all repos — mgba @ 6867400ca875277929f8aec1964c99d85cb0e1a9

mGBA Game Boy Advance Emulator

GBA BIOS: Use custom ArcTan, not relying on OS
Jeffrey Pfau jeffrey@endrift.com
Sat, 13 Aug 2016 14:10:51 -0700
commit

6867400ca875277929f8aec1964c99d85cb0e1a9

parent

74013710168a85f4390ea2478dd50e8f1ecef74f

2 files changed, 50 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -51,6 +51,7 @@ - PSP2: Add rumble for PS TV

- PSP2: Add fit-to-height screen mode - GBA Video: Remove old slow path fallback - GBA Video: Optimize sprite drawing + - GBA BIOS: Use custom ArcTan, not relying on OS 0.4.1: (2016-07-11) Bugfixes:
M src/gba/bios.csrc/gba/bios.c

@@ -265,6 +265,52 @@ cpu->gprs[3] = 1;

} } +static int16_t _ArcTan(int16_t i) { + int32_t a = -((i * i) >> 14); + int32_t b = ((0xA9 * a) >> 14) + 0x390; + b = ((b * a) >> 14) + 0x91C; + b = ((b * a) >> 14) + 0xFB6; + b = ((b * a) >> 14) + 0x16AA; + b = ((b * a) >> 14) + 0x2081; + b = ((b * a) >> 14) + 0x3651; + b = ((b * a) >> 14) + 0xA2F9; + return (i * b) >> 16; +} + +static int16_t _ArcTan2(int16_t x, int16_t y) { + if (!y) { + if (x >= 0) { + return 0; + } + return 0x8000; + } + if (!x) { + if (y >= 0) { + return 0x4000; + } + return 0xC000; + } + if (y >= 0) { + if (x >= 0) { + if (x >= y) { + return _ArcTan((y << 14)/ x); + } + } else if (-x >= y) { + return _ArcTan((y << 14) / x) + 0x8000; + } + return 0x4000 - _ArcTan((x << 14) / y); + } else { + if (x <= 0) { + if (-x > -y) { + return _ArcTan((y << 14) / x) + 0x8000; + } + } else if (x >= -y) { + return _ArcTan((y << 14) / x) + 0x10000; + } + return 0xC000 - _ArcTan((x << 14 / y)); + } +} + void GBASwi16(struct ARMCore* cpu, int immediate) { struct GBA* gba = (struct GBA*) cpu->master; mLOG(GBA_BIOS, DEBUG, "SWI: %02X r0: %08X r1: %08X r2: %08X r3: %08X",

@@ -303,8 +349,10 @@ break;

case 0x8: cpu->gprs[0] = sqrt((uint32_t) cpu->gprs[0]); break; + case 0x9: + cpu->gprs[0] = _ArcTan(cpu->gprs[0]); case 0xA: - cpu->gprs[0] = (uint16_t) (atan2f(cpu->gprs[1] / 16384.f, cpu->gprs[0] / 16384.f) / (2 * M_PI) * 0x10001); + cpu->gprs[0] = _ArcTan2(cpu->gprs[0], cpu->gprs[1]); break; case 0xB: case 0xC: