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 > I don't know...

#25870 - anoneem - Mon Aug 30, 2004 10:22 am

Damn, it's me again! :) I was writing a stupid program, wich i would like to draw for me some nice colours on the screen. Here it goes...

Code:
@textarea

loop:

ldr r1,=0x4000000      ;screen conrol

ldr r2,=0x403         ;Mode 3, BG2

str r2,[r1]         ;OKAY!

;Tryb 3 ON

ldr r0,=0x0FF         ;it is colour

ldr r1,=0         ;x position

ldr r2,=0         ;y position

ldr r3,=240         ;well... 240 value :) r3 is counter

ldr r4,=0x06000000      ;vram

ldr r5,=0         ;

ldr r6,=240         ;wide

ldr r7,=160         ;height

testx:

cmp r3,0         ;is line drawn?

beq wiersz:         ;if yes, draw next

mla r5,r2,r6,r1         ;if no, y*240+x

add r4,r4,r5         ;vram+position

str r0,[r4]         ;and draw dot

add r1,r1,1         ;inc x

sub r3,r3,1         ;counter - 1

add r0,r0,1         ;inc colour

b testx:

wiersz:

add r3,r3,240         ;240 - x position is 0, so set counter of x line

cmp r7,0         ;is last point of screen drawn? (240,160)

beq loop:         ;if yes, loop

sub r7,r7,1         ;if no, dec counter

b testx            ;and branch

label1
b label1

@pool
@endarea


But it's drawing a... colourfull starfield? What am I doing bad here? Please, if You are boring, or if You want to educate a little dummy coder, fix it! I will be thankfull!

PS. Sory for english, if it's bad.

#25871 - pan69 - Mon Aug 30, 2004 12:22 pm

Hi,

In Mode 3, isn't a pixel supposed to be 16bits (2 bytes). I think you need to multiply the y*240+x by 2 somewhere to determine to offset.

- Pan

#25874 - anoneem - Mon Aug 30, 2004 4:13 pm

So, is it going to be something like...

mla r5,r2,r6,r1 ;y*240+x

mul r5,r5,r8 ;r8 is equ 2

???

I also changed values in incrementer - from 1 to 2, also i did it with counter. Effect is... some of dots, wich were changing colours, aren't doin' it any more. :)

BTW: Have You got some piece of code realizing that operation (colour of every next line should be ++)?

Greetz

#25902 - f(DarkAngel) - Tue Aug 31, 2004 8:33 am

Using shifting for div/mul by powers of two will be much faster. To multiply by 2, you could at least add the register to itself...
_________________
death scream...

#25904 - [mRg] - Tue Aug 31, 2004 11:17 am

Note: This could be the blind leading the blind but ill have a go !

As I understand from your code you are trying to increase the colour for each line on the screen.

I think the problem is how you are incrementing the colour. Its not as easy as adding or subtracting 1 from the colour .. because the format is BGR adding one means you will cycle through the red range a bunch of times as you increase the other colours.

the colour can be constructed with : ((R)+((G)<<5)+((B)<<10)) where the << is a LSL and the maximum in each channel can be 31 (ie 0->31 so 32 values)

Code:


mov r1, #31 @ (Red)
mov r2, #31 @ (Green)
mov r3, #31 @ (Blue)
add r1, r1, r2, lsl #5    @ Shift left 5 for green
add r1, r1, r3, lsl #10  @ Shift left 10 for blue



r1 now contains your colour !! (In this example its white)

I made a quick example (its not great code as im a newbie too but I hope you understand what Im trying to do and its all good practice for me :P )

Hope this helps in some way (investigating opened my eyes to a few things anyway :)

Regards

[mRg]

Code:


.arm
.align
.text
.global main

@-------------------------------------------------------
@ Include header with standard GBA definitions                         
@-------------------------------------------------------

.include "includes/gba.h"

@-------------------------------------------------------
@ Main program label                       
@-------------------------------------------------------

main:

@--------------------------------------------------------
@ Setup screen
@--------------------------------------------------------

          ldr r0, =REG_DISPCNT         @ Display register      
          ldr r1, =(MODE_3|BG2_ENABLE)   @ OR the options we want
          strh r1, [r0]               @ Store in the register
         
          mov r0, #0x6000000      @ VRAM Screen buffer
          mov r1, #0x1F         @ Red - ((31)+((0)<<5)+((0)<<10)) - Colour format = ((R)+((G)<<5)+((B)<<10))
         
          mov r2, #0x9600      @ Number of writes to fill the screen (240*160) in hex
          mov r3, #240         @ Counter to check horizontal line has been drawn (there are better ways to detect this)
          ldr r4, =0x7FFF       @ Final colour we want (white - ((31)+((31)<<5)+((31)<<10))) - Colour format = ((R)+((G)<<5)+((B)<<10))
         
@--------------------------------------------------------
@ Fill Screen
@--------------------------------------------------------
         
loop1:    strh r1, [r0], #2      @ Save colour in screen buffer and move pointer along ready for the next colour
          subs r3, r3, #1      @ Subtract 1 from r3 and check if its 0 (ie end of the line)
          bleq addCol         @ If it is then jump to increment colour routine
          subs r2, r2, #1      @ Subtract 1 from r2 is it 0 then screen has finished drawing
          bne loop1             @ If it hasnt finished then loop back !
         
infin:      
         b infin               @ infinite loop

addCol:
         ldr r5, =((0)+((1)<<5)+((1)<<10)) @ Here we are loading 1 into the G+B areas so we can move from the red colour -> white (r4)
         cmp r1, r4                    @ Check if we match the white colour yet
         movge r15, r14                 @ If so then exit routine (ie do nothing)
         add r1, r1, r5                 @ If not add increase the G+B areas in r1 by adding r5
         mov r3, #240                 @ Reset r3
         mov r15, r14                 @ Exit routine
         
.align
.pool

#25922 - anoneem - Tue Aug 31, 2004 5:51 pm

Great! Thank You for that! You're my asm guru. :)