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 > Why can't I branch? :(

#11399 - davewelsh - Sat Oct 04, 2003 4:26 pm

I was following gbaguy's tutorials (although I'm using as instead of goldroad), and I've managed to get things working well, figuring out .EQU instead of @define, .text instead of @textarea, etc.

What I'm having trouble with is loops.

Here is code that works:
Code:
        .include "consts.s"
                                                                                                         
        .ARM
        .ALIGN
                                                                                                         
        LDR r1,=REG_DISPCNT             @ load into r1 ??
        LDR r2,=(MODE_3|BG2_ENABLE)     @ load graphics mode into into r2
        STR r2, [r1]                    @ store r2 into [r1] (init graphics)
                                                                                                         
        LDR r1, =0xff00ff               @ load colour into r1 (2 x red)
        LDR r2, =VRAM+2400              @ load initial location into r2 (0, 10)
        STR r1, [r2]                    @ plot two pixels at [r2]
                                                                                                         
        ADD r2, r2, #4                  @ move forward
        STR r1, [r2]                    @ plot two pixels at [r2]
                                                                                                         
        ADD r2, r2, #4                  @ move forward
        STR r1, [r2]                    @ plot two pixels at [r2]
                                                                                                         
        ADD r2, r2, #4                  @ move forward
        STR r1, [r2]                    @ plot two pixels at [r2]
                                                                                                         
        ADD r2, r2, #4                  @ move forward
        STR r1, [r2]                    @ plot two pixels at [r2]
                                                                                                         
wait:   B wait                          @ loop forever


I'm not sure if the "B wait" works, but I assume it does for now.

Here is code that doesn't seem to work for me. The loop only executes once:
Code:
        .include "consts.s"
                                                                                                         
        .ARM
        .ALIGN
                                                                                                         
        LDR r1,=REG_DISPCNT             @ load into r1 ??
        LDR r2,=(MODE_3|BG2_ENABLE)     @ load graphics mode into into r2
        STR r2, [r1]                    @ store r2 into [r1] (init graphics)
                                                                                                         
        LDR r1, =0xff00ff               @ load colour into r1 (2 red pixels)
        LDR r2, =VRAM+2400              @ load initial location into r2 (0, 10)
                                                                                                         
        MOV r3, #5
                                                                                                         
loop:   STR r1, [r2]                    @ plot two pixels at [r2]
        ADD r2, r2, #4                  @ move forward
        SUBS r3, r3, #1                 @ decrement loop register
        BPL loop                        @ loop while positive
                                                                                                         
wait:   B wait                          @ loop forever


When I run this in VirtualBoyAdvance I get two red pixels at (0, 10) and (1, 10) but I figure I should get 8 more. I've also tried this with the labels on their own lines.

#11400 - sajiimori - Sat Oct 04, 2003 8:07 pm

Code:

LDR r1, =0xff00ff               @ load colour into r1 (2 red pixels)

Actually, 0x1f is red, but close enough. :-)
Code:

LDR r2, =VRAM+2400              @ load initial location into r2 (0, 10)

That would actually be (0, 5), because it's 2 bytes per pixel.

But more importantly:
Code:

loop:   STR r1, [r2]                    @ plot two pixels at [r2]

You can only write 16 bits at a time to VRAM (that's one pixel in mode 3). Use strh instead.

#11401 - tom - Sat Oct 04, 2003 9:49 pm

sajiimori wrote:
You can only write 16 bits at a time to VRAM (that's one pixel in mode 3). Use strh instead.


nope. although the vram's bus width is only 16 bits, you can do 32 bit reads/writes.

#11402 - davewelsh - Sat Oct 04, 2003 10:14 pm

Thanks for the info. I still don't see why I'm not getting more pixels. It seems to me the loop should run through a few times and draw more pixels.

#11403 - sajiimori - Sat Oct 04, 2003 10:29 pm

I must be confused. Maybe it was just that you can't write 8 bits at a time...

#11404 - davewelsh - Sat Oct 04, 2003 11:23 pm

Well it was working with 32-bit writes, but I changed it to 16-bit ones. There's still the problem that no braching works for me. The following code only draws one pixel but it should draw a lot more:

Code:
        LDR r6, =0x04000000             @ load ?? into r6
        LDR r5, =(0x3|0x400)            @ load graphics mode into into r5
        STR r5, [r6]                    @ store r5 into [r6] (init graphics)
                                                                                                       
        LDR r6, =0x06000960             @ load initial draw location into r6
        LDR r5, =0x060012c0             @ load final draw location into r5
        LDR r4, =0x001f                 @ load colour into r4 (2 red pixels)
                                                                                                       
test:
        STRH r4, [r6], #2
        CMP r6, r5
        BLT test                        @ loop while r6 less than r5
                                                                                                       
wait:
        B wait                          @ loop forever


For example, if I add the line
Code:
B test
just before the test label, then no pixels are drawn. Even though execution should simply go down to the next line and continue on.

#11405 - davewelsh - Sun Oct 05, 2003 1:20 am

I found and downloaded souce code for some assembly-only projects. When I compiled them they didn't work, so I figure that's where my problem is.

I have been using
Code:
arm-thumb-elf-as -o output.elf input.s
Is this correct or not?

#11406 - DekuTree64 - Sun Oct 05, 2003 3:20 am

Try replacing the arm-thumb-elf-as with gcc and see if it works.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#11407 - davewelsh - Sun Oct 05, 2003 4:10 am

Thanks for all your help. My problem was I wasn't setting up my header and entry point correctly. Once I added
Code:
.TEXT
.ARM
.GLOBAL AgbMain

AgbMain:
I was fine.

I copiled crt0.s into crt0.o and new2.s into new2.o by
Code:
arm-thumb-elf-gcc -c <inputfile>


Then I linked them using
Code:
arm-thumb-elf-gcc -o output.elf crt0.o new2.o -nostartfiles -nostdlib -T lnkscript


And then the standard
Code:
arm-thumb-elf-objcopy -O binary output.elf output.gba