Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pc bit1 "undefined" state on GBA not properly emulated #2964

Closed
JoaoBaptMG opened this issue Jun 26, 2023 · 4 comments
Closed

pc bit1 "undefined" state on GBA not properly emulated #2964

JoaoBaptMG opened this issue Jun 26, 2023 · 4 comments

Comments

@JoaoBaptMG
Copy link

After some discussion on the gbadev Discord server, it was found that pc has a "weird" behaviour when a bx instruction is executed to ARM state with a mis-aligned address (aka bit 1 set): while the CPU is able to "internally" align the address to fetch an instruction with correct alignment, on pc the bit1 keeps set, which can lead to miscalculations in any instruction that uses it as an operand (such as pc-relative loads and stores).

We can check the vaildity of this hypothesis with a very simple subroutine that gets the pc on such a state:

08001708 <getMisalignedPC>:
 8001708:	46c0      	nop			@ (mov r8, r8)
 800170a:	4778      	bx	pc      @ this will branch to pc = 0800170e
 800170c:	e1a0000f 	mov	r0, pc  @ this will set r0 = mis-aligned pc: 08001716
 8001710:	e12fff1e 	bx	lr

(the source file is like this)

    .section .rom, "ax", %progbits
    .align 2
    .thumb_func
    .global getMisalignedPC
    .type getMisalignedPC STT_FUNC
getMisalignedPC:
    nop             ; to ensure mis-alignment (with the .align 2 up there)
    bx      pc      ; this instruction will fetch a pc whose set bit is 1
    .arm
    mov     r0, pc  ; this pc should be misaligned as well
    bx      lr

(I tried to upload a GBA ROM here, but GitHub doesn't let me)

On the hardware (tested by @evanbowman), the returned PC is what is expected by the above hypothesis:
Photo of a GBA hardware running the test. PC: 0x8001716, PC is mis-aligned

On mGBA, however, the returned PC is aligned to the lowest word (08001714), contradicting the result on hardware.
Screenshot of mGBA running the test. PC: 0x8001714, PC is aligned

This aligns with what the ARM7TDMI Technical Reference says about bits 1 and 0 of pc on ARM state:
Excerpt of the ARM7TDMI Technical Reference: "in ARM state, bits 1 and 0 of r15 are undefined and must be ignored."

Whether or not instructions having pc as an operand will correctly use the "correct" (aligned) program counter value is not tested (though I doubt, since bl in Thumb sets bit 1 of lr).

@endrift
Copy link
Member

endrift commented Jun 26, 2023

I'm pretty sure I correctly implemented part of this a few versions ago, but clearly not all of it. I'd have to dig through the log. It's related to some weirdness with an Emerald ACE payload misbehaving that merrp brought to my attention.

@endrift
Copy link
Member

endrift commented Jun 26, 2023

Can you upload the ROM zipped? You can't upload .gba files but you can upload .zip files with .gba files in them.

I think the specific issue is actually in the implementation of the Thumb BX instruction--I'm pretty sure the ARM BX instruction would work as intended here, but having an easy way to test would be much appreciated.

@JoaoBaptMG
Copy link
Author

Here it is: game.zip

I could try to write more tests, but I don't have a GBA (I have an NDS-Lite though, but no flashcart), and also I have no idea what I should try to test.

@endrift
Copy link
Member

endrift commented Jun 26, 2023

It looks like this bug was only present in the single specific case tested: bx pc from Thumb on a misaligned address. Good catch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants