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.

ASM > Picture Problems

#172923 - nathanpc - Thu Mar 11, 2010 7:36 pm

Hello,
I was trying to do some tests with pictures and Assembly with this code:
Code:
.arm
.text
.global main
main:
   mov r0, #0x4000000  @ the usual set up routine
   mov r1, #0x400   @ 0x403 is BG 2 enable, and mode 3.
   add r1, r1, #3
   strh r1, [r0]   @ the memory I/O value we're setting is actually 16bits, let's not mess
         @ something else up by writting 32.
   
   mov r0, #0x6000000  @ address of VRAM
   ldr r1, =pic        @ using this form of LDR with a label will put the address of the label into r1.
   mov r2, #0x960     @ the amount of 32 BYTE writes to fill the screen (we'll be using a new instruction)
loop1:
   ldmia r1!, { r3,r4,r5,r6,r7,r8,r9,r10 } @ will start with the address in r1, it will load each listed register
            @ with 32bits from memory, incrementing the address by 4 each time. The final address used +4
            @ will be written back into r1 (because of the !). Note this instruction doesn't use
            @ brackets around the register used for the address.
   stmia r0!, { r3,r4,r5,r6,r7,r8,r9,r10 } @ will start with the address in r1, it will store each listed register
            @ into memory (32bit write), adding 4 to the address. The final address used +4 will
            @ be written back.
   @ These instructions are a fast(er) way to do block memory copying, they are only useful when you have alot of
   @ registers available (registers 3-10 were used here, but I could have said r2,r4, they don't have to be in order
   @ just don't use the address register in the destination list.

   subs r2, r2, #1  @ subtraction setting the flags
   bne loop1  @ will loop if r2 wasn't zero.

infin:
   b infin  @ infinite loop

.ltorg   @ give the assembler a place to put the immediate value "pool", needed for the ldr REG,= (s).
pic:   @ a label to indicate the address  of the included data.
   .incbin "pic.bin"  @ include the binary file

But when I tried to emulate it, I got this:
[Images not permitted - Click here to view it]
What can I do?

PS: I've used the sample image povided with Bimbo.

Best Regards,
Nathan Paulino Campos

#172927 - Dwedit - Thu Mar 11, 2010 8:45 pm

The code looks correct. The data file is probably bad. Look at the data file with a hex editor or something, it will probably just be a repeating sequence of words or something.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#172932 - nathanpc - Thu Mar 11, 2010 11:24 pm

I've exported the hex to a TXT file. Take a look at it and on the bin file.

#172933 - Dwedit - Thu Mar 11, 2010 11:48 pm

Code worked fine when I tested it.

Which version of DevKitArm are you using?
If you are using the example makefiles, there is an issue with the toolchain where the starting directory is actually "build\" instead of what you would expect. So incbin will fail to find the file. You need to .incbin "../source/pic.bin" instead of just "pic.bin" (assuming your .bin file is in the "source" directory)

Edit: You mentioned you aren't using devkitarm.
Make sure your memory map is correct. It sounds like your compiler is generating code running from 0x00000000, and it tries to load an absolute address from there. It only ran correctly up to this point because all other code was position independent. The start address should be 0x08000000.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#172934 - nathanpc - Fri Mar 12, 2010 12:02 am

Dwedit wrote:
Edit: You mentioned you aren't using devkitarm.
Make sure your memory map is correct. It sounds like your compiler is generating code running from 0x00000000, and it tries to load an absolute address from there. It only ran correctly up to this point because all other code was position independent. The start address should be 0x08000000.

How can I do this?

#172938 - Dwedit - Fri Mar 12, 2010 6:32 am

Use the makefiles, specs, linkscripts, and crt0 files that come with devkitpro, and stuff will just work.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#172955 - nathanpc - Fri Mar 12, 2010 6:22 pm

Now I've compiled the DevKit Advance binutils and tried to compile the sources with it. Like this:
Code:
arm-agb-elf-as -mthumb-interwork test.S
arm-agb-elf-objcopy -O binary a.out pic.gba

And now I got a black screen only.

What I need to do now?

#172958 - Dwedit - Fri Mar 12, 2010 8:28 pm

Devkitadvance is really old, avoid it.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#172960 - nathanpc - Fri Mar 12, 2010 8:34 pm

Ok, but I want to use it and what I can do?

#172961 - Cearn - Fri Mar 12, 2010 9:31 pm

nathanpc wrote:
Ok, but I want to use it and what I can do?
You can use assembly just as well with devkitArm as devkitAdv. Probably better, actually, because the distribution also contains template makefiles that can manage your assembly files pretty much automatically.

For example, assuming you've got devkitArm and its examples:
  • Grab the gba template from the examples (examples/gba/template), copy it somewhere and rename it to ... whatever.
  • Remove the template.c file from the source folder.
  • Create a main.s file in the source folder.
  • Fill it with the following code:
Code:
//
// main.s : example assembly file.
//

// main function. Entry point.
// Notice the boilerplate directives for a function. While not always
// required, it is recommended.
    .text                       @ Text (=code) section
    .arm                        @ ARM code (Thumb uses ".thumb_func")
    .align 2                    @ Align to 4-byte boundary.
    .global main                @ Make a symbol out of the function name.
main:
    @ Enable bg-mode 3 and BG 2
    ldr     r0,=0x04000000      @ = REG_DISPCNT
    ldr     r1,=0x0403          @ = DCNT_MODE3 | DCNT_BG2
    str     r1, [r0]

    @ Draw a red rectangle.
    ldr     r0,=0x001F                  @ Red color
    ldr     r1,=(0x06000000+10*240+20)  @ position (20,10)

    mov     r2, #32                     @ Height
.Ly_loop:
        mov     r3, #40                 @ Width
.Lx_loop:
            strh    r0, [r1], #2        @ Plot 1 pixel, advance pointer
            subs    r3, r3, #1          @ Advance x-index and test.
            bne     .Lx_loop
            @ End x_loop
        add     r1, #(240-40)*2         @ Advance pointer to the next line of the rect.
        subs    r2, #1                  @ Advance y-index and test.
        bne     .Ly_loop
        @ End y_loop
   
.Lloop:                         @ Infinite loop.
    b   .Lloop
This code will produce a red rectangle in video mode 3. It's not very efficient, but it works. The indentation is optional, but it can be useful to indicate loop-blocks and such.
  • Now to assemble and link the code: just run make in the project's directory. For convenience, you can do it from within an IDE or programmer's editor (like PN2 which comes with the devkitArm. Open the pnproj file and hit Alt+1.

    with devkitArm and it's template projects, all the set-up stuff is taken care of. Yes, you can use devkitAdv if you really want to, but all that does is make thing harder unnecessarily.

    Tonc also contains a rudimentary guide to ARM assembly (tonc:asm). It can tell you the most important instructions, things to watch out for, and where you can get more information (in particular, instruction quick-references).

    One nice trick is to write some C code and compile with -save-temps. With this, GCC will put the generated assembly code in a file, and you can look at it and see what functional ARM assembly looks like.