.arm                            @ C'est du code ARM
.global EffetCouleur            @ Définit la routine EffetCouleur

@include vars.h

@ Macro pour stocker le contenu d'un registre dans une variable (ou un emplacement RAM)
.macro STOCKE_REG variable,registre
    ldr r10,=\variable          @ Charge dans r10 l'adresse de la variable
    str \registre,[r10]         @ Stocke le registre à l'adresse chargée
.endm

@ Lit un registre
.macro LIT_REG variable,registre
    ldr r10,=\variable          @ Charge dans r10 l'adresse de la variable
    ldr \registre,[r10]         @ Charge la valeur depuis l'adresse
.endm

@ Pour le débogage
.macro STOP
ici:
    b ici
.endm

@.section .iwram                 @ Le code qui suit va se placer en IWRAM histoire d'être exécuté rapidement
.section .text

@ Notre routine de départ!
EffetCouleur:
    @Sauvegarde des registres sur la pile
    stmfd   sp!, {r0,r1,r2,r3,r10,lr}      @ Les registres que j'utilise (+lr)

    @ Passe en mode graphique n°3 (BITMAP 16 bits 240x160 1 plan)
    mov r0, #0x4000000          @ r0=REG_DISPCNT
    ldr r1, =0x403              @ r1=VIDEO_BG2_ENABLED | VIDEO_MODE3
    str r1, [r0]                @ *r0=r1
    
    @ La couleur. Incrémentée à chaque boucle
    LIT_REG var,r3
__boucle:
    @ Pointeur sur la mémoire vidéo
    mov r0, #0x6000000          @ r0=MEMOIRE_VIDEO
    @ Boucle for (r2=0x9600;r2!=0;r2--)
    mov r2, #0x9600
__remplit_ecran:
    strh r3, [r0], #2           @ *r0=r3 puis r0+=2 (16 bits)
    subs r2, r2, #1             @ r2=r2-1 et écrit r2 dans le registre de statut pour utiliser bne ensuite!
    bne __remplit_ecran         @ if (r2!=0) goto remplit_ecran

    add r3, r3, #1              @ r3++  -- incrémente d'un la couleur

    STOCKE_REG var,r3           @ Utilise ma macro pour stocker r3 en RAM. On peut la voir à l'adresse 0x2000000
    STOCKE_REG var_c,r3         @ Variable définie dans le fichier vars.h

	stmfd sp!, {r3,lr}          @ Sauvegarde r3 (important) sur la pile sans oublier lr ;)
    bl test                     @ Branche sur la routine test (fichier test.c)
    movs r0,r0                  @ La valeur retournée est inscrite dans r0. On la place dans le registre de statut.
	ldmfd sp!, {r3,lr}          @ Restaure r3. Sans lui, notre programme ne tourne pas.

    @ Les conditions sont évaluées en soustrayant deux opérandes. 8=8 car 8-8=0.
    @ Donc là si la valeur retournée (r0) que j'ai placée dans le registre de statut est nulle,
    @ on peut considérer que la condition est "égale". Donc dans ce cas là (r0=0, =touche start
    @ pas appuyée), on continue notre boucle.
    beq __boucle

    @ Restauration des registres à partir de la pile
    ldmfd   sp!, {r0,r1,r2,r3,r10,lr}
    bx lr                       @ Retour. Plantage garanti si lr n'est pas sauvé.


@ Routine de dessin de pixels en mode 3
@ Prototype: DessinePixel(u32 x, u32 y, u32 couleur);
.global DessinePixel

DessinePixel:
    stmfd   sp!, {r3}           @ Sauvegarde r3
    mov r3, #0x6000000          @ r0=MEMOIRE_VIDEO
    @ Calcul de l'offset y (r3=r3+r1*480)
    rsb r1, r1, r1, asl #4      @ r1=r1*16-r1 -- r1=r1*15
    add r3, r3, r1, asl #5      @ r3=r3+r1*32 -- r1*15*32=r1*480
    @ Offset x
    add r3, r3, r0, asl #1      @ r3=r3+r0*2
    @Stockage
    strh r2,[r3]                @ *r3=r2
    ldmfd   sp!, {r3}           @ Restauration r3
    bx lr                       @ Retour


.global LaRoutineDeLaMort
LaRoutineDeLaMort:
    stmfd   sp!, {r0-r5, lr}
    mov r5, #0
__boucleY:
    mov r4, #0
__boucleX:
    mov r0, r4
    mov r1, r5
    add r2, r0, r1, asl # 10
    bl DessinePixel
    add r4, r4, #1
    cmp r4, #240
    bne __boucleX
    add r5, r5, #1
    cmp r5, #160
    blt __boucleY
    ldmfd   sp!, {r0-r5, lr}
    bx lr

@ Les variables (ouais enfin ici il n'y en a qu'une). Je les mets volontairement en EWRAM (lente).
.section .ewram
var:                            @ Variable standard...
    .word 0                     @ ... de type long (32 bits)...
    .global var                 @ ... et globale!


