gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > GBA ARM CPU instruction set, quick question

#167115 - wildex999 - Mon Mar 02, 2009 12:36 am

Hello,
I'm trying to code a basic GBA Emulator in C, and I just have a quick question on something that has bothered me a little while.

I have come to the part where I have to study the ARM technical documents(http://infocenter.arm.com/help/topic/com.arm.doc.ddi0210c/DDI0210B.pdf page 1-12) and learn the instruction set, and while I get how they work and are set up(And have tried some asm coding using them) I met a kind of wall when it came to disassembling or decoding them when writing an AMR7tdmi cpu emulator.
The way I see it the instructions in binary form do not contain a specific opcode that can be directly read to find out wich instruction I'm looking at.
Looking at the Instruction set format it seems like one have to figure out what instruction it is by masking and checking pre-set bit patterns.
So my question is, is this right? Is there some part I have overlooked?
I looked in at some open source emulators, but most people seem to have optimised so much I can not tell what they actually check, or if there's a pattern to it.

I tried to set up the bit patterns from the ARM documentation:
xxxx00xxxxxxxxxxxxxxxxxxxxxxxxxx Data processing/ PSR Transfer
xxxx000000xxxxxxxxxxxxxx1001xxxx Multiply
xxxx00001xxxxxxxxxxxxxxx1001xxxx Multiply long
xxxx00010x00xxxxxxxx00001001xxxx Single Data Swap
xxxx000100101111111111110001xxxx Branch and Exchange(BX)
xxxx000xx0xxxxxxxxxx00001xx1xxxx Halfword Data Transfer: register offset
xxxx01xxxxxxxxxxxxxxxxxxxxxxxxxx Single Data Transfer
xxxx011xxxxxxxxxxxxxxxxxxxx1xxxx Undefined
xxxx100xxxxxxxxxxxxxxxxxxxxxxxxx Block Data Transfer
xxxx101xxxxxxxxxxxxxxxxxxxxxxxxx Branch
xxxx110xxxxxxxxxxxxxxxxxxxxxxxxx Coprocessor Data Transfer
xxxx1110xxxxxxxxxxxxxxxxxxx0xxxx Coprocessor Data Operation
xxxx1110xxxxxxxxxxxxxxxxxxx1xxxx Coprocessor Register Transfer
xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx Software Interrupt

Where x is a variable(or undefined) and the numbers are the set bit's for the instructions.
Am I right in that checking the bit patterns is the right way to determine the instruction?

Thanks in advance =)
_________________
EZ Flash III - Flashme V7 - NDS V1 xD - NDS Tunneling, anyone?

#167117 - Dwedit - Mon Mar 02, 2009 1:46 am

You can also look at the source code to VisualBoyAdvance to see how they did it.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#167118 - wildex999 - Mon Mar 02, 2009 2:34 am

Ah, thanks, I didn't know vba was open source =D
They had EXACTLY the source I needed to look at(armdis.cpp) ^^

And it does exactly what I was thinking of doing =)

They list up an outer mask(To figure out the main type of instruction) and then an inner mask to figure out what instruction it is inside the main type.
And then check to see if the 32 bit code read in &(and) outer mask equals the inner mask for all possible instructions.

0x0de00000, 0x00800000, add <-- add instruction

0x0de00000 = main mask = data processing
0x00800000 = inner mask = add

From documentation
xxxx00xccccxxxxxxxxxxxxxxxxxxxxx Data processing/ PSR Transfer
cccc=opcode(inner mask)

Thus:
0x0de00000 = 1101111000000000000000000000
0x00800000 = 100000000000000000000000
the opcode for add = 0100

Example add instruction:
00?0100?????????????????????????
? = a variable


(I wrote that just to get my own head around it =P)
Hm... maybe this will help others later on, I dunno =P

Anyway, thansk a lot for the help =)
If anyone has anything to add(or correct) feel free to post it here. :)
_________________
EZ Flash III - Flashme V7 - NDS V1 xD - NDS Tunneling, anyone?