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 > problem with red dot!

#23234 - Darmstadium - Thu Jul 08, 2004 6:04 am

Yo, I'm a real noob to ASM, I just started today. I got a problem with this code that is supposed to display two red dots of 0xF > 0xE:
Code:

@include screen.h
@textarea

;set mode, enable bg2
ldr r0,=REG_DISPCNT
ldr r1,=(MODE_3 | BG2_ENABLE)
str r1,[r0]

ldr r0,=0xF
ldr r1,=0xE
cmp r0,r1
bgt drawreddots

;main loop
mainloop
B mainloop

drawreddots
ldr r0,=0xFF
ldr r1,=(vram+(40+100*240))
str r0,[r1]
ldr r1,=(vram+(43+100*240))
str r0,[r1]

@pool
@endarea

The first dot appears but the second doesn't.

And I got a question about branching to a different label: if I want to go back to where I branched from in the drawreddots label after the code there is done being executed, do I have to make a label back where I branched from and then branch back to there like this?:
Code:

@include screen.h
@textarea

;set mode, enable bg2
ldr r0,=REG_DISPCNT
ldr r1,=(MODE_3 | BG2_ENABLE)
str r1,[r0]

ldr r0,=0xF
ldr r1,=0xE
cmp r0,r1
bgt drawreddots
returnfromdrawing

;main loop
mainloop
b mainloop

drawreddots
ldr r0,=0xFF
ldr r1,=(vram+(40+100*240))
str r0,[r1]
ldr r1,=(vram+(43+100*240))
str r0,[r1]
b returnfromdrawing

@pool
@endarea


thanks

#23236 - DekuTree64 - Thu Jul 08, 2004 7:11 am

What's happening is that the first of your dots is placed at byte 40, and the second is at 43, but because of how the ARM deals with non-word-aligned str instructions, it's writing ot the same place. The lower byte makes no difference at all, and writing to an odd halfword causes it to write the lower 2 bytes of the word to that odd address, and the upper 2 bytes to the 2 bytes BELOW that, so they're swapped. Normally you don't want that to happen.
So, your second dot is being drawn in the next pixel over, but also covering over the previous dot. To fix this, use strh, which stores 2 bytes instead of 4. Also, you need to multiply your addresses by 2 for mode3, because ARM instructions operate in bytes always, and mode3 is 2 bytes per pixel.

Also, use strh for writing the value to REG_DISPCNT, because it's a 16-bit register. The upper 2 bytes aren't used, so it won't cause problems here, but for the future, you could overwrite another register without knowing it.

For getting back to where you were, use bl instead of just b. That copies the old r15 (also called the program counter, or pc), into r14 (link register, lr), and then branches. Then use bx lr (or bx r14, same thing) to get back to where you were.
Watch out though, when you do that it overwrites the old value of lr, so you need to store it first. Since this is your. That's done by pushing it onto the stack with stmfd sp!, {lr}. sp is the stack pointer, also known as r13. Do this at the start of your function so you don't have to worry about it, and then when returning use ldmfd sp!, {lr} to get it back, and then bx lr to whoever called you.

You don't need to worry about all that for this though, since you're going into an infinite loop. You can just bgtl (or blgt? I forget which) to drawreddots and then bx lr to get back.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#23245 - Darmstadium - Thu Jul 08, 2004 5:12 pm

I did all the stuff you said and the two red dots draw where I want em, but the green dot doesn't draw at all. I can't figure out why not. Could you take a look?:
Code:

@include screen.h
@textarea

ldr r0,=REG_DISPCNT
ldr r1,=(MODE_3 | BG2_ENABLE)
strh r1,[r0]

ldr r0,=0xF
ldr r1,=0xE
cmp r0,r1
stmfd sp!,{lr}
bgtl drawreddots

ldr r0,=0x5
ldr r1,=0x5
sub r2,r0,r1
cmp r2,0x0
stmfd sp!,{lr}

;main loop
mainloop
b mainloop

drawreddots
ldmfd sp!,{lr}
ldr r0,=0xFF
ldr r1,=(vram+(40*2+100*2*240))
strh r0,[r1]
ldr r1,=(vram+(42*2+100*2*240))
strh r0,[r1]
bx lr

drawgreendot
ldmfd sp!,{lr}
ldr r0,=0xF0F
ldr r1,=(vram+(8*2+8*2*240))
strh r0,[r1]
bx lr
@pool
@endarea


thanks for your help

#23252 - dagamer34 - Thu Jul 08, 2004 7:38 pm

I never did understand ARM ASM. I guess I should learn it now. Some one needs to make another assembly tutorial. I would if I could but I can't so I guess I won't. :)
_________________
Little kids and Playstation 2's don't mix. :(

#23256 - johnny_north - Thu Jul 08, 2004 9:59 pm

Are you missing a branch to drawgreendots?

#23265 - Darmstadium - Fri Jul 09, 2004 12:30 am

yes, it appears i am. wow, I really have no idea how I could have missed that...thanks man