C'est pas bo ca???
c'est de l'arm 9 demandé par yAro, il est complet, toutes combinaisons de suffixes y son, et donc ca peut demander un minimum de temps pour un source long comme ca!
Pour les personnes qui ne connaissent pas, dans chaque gba, le processeur est un arm, donc ca devrait ravir les programmeurs gba, voilou
;--------------------------------------------
;--------------------------------------------
;--------------------------------------------
; MODE 7 style background using interrupts
;--------------------------------------------
; Written by Shaun Southern 2002 in ARM assembler
; using goldroad ARM assembler
;--------------------------------------------
;--------------------------------------------
;--------------------------------------------
@define gfxram $06000000 ;pointer to graphics memory
@define palram $05000000 ;pointer to palette memory
@define ioregs $04000000 ;pointer to io/graphic/sound registers
;--------------------------------------------
; This is the 192 bytes space for the standard gameboy header. I use a tool
; called gbarm.exe to set up the header with the correct checksum
; so the program runs correctly on Gameboy Advance hardware
;--------------------------------------------
b afterh ;skip header
@dup dcd 47,0
afterh
;--------------------------------------------
; Copy the whole program and variabless to internal workram (03000000h)
; and run from there. You can't have variables in Rom, after all. This
; process is made simple by the goldroad assembler.
;--------------------------------------------
mov r1,startcode
mov r2,startcopy ;$3000000
mov r3,finiscopy
clp:
ldr r0,[r1],4
str r0,[r2],4
cmp r2,r3
bmi clp
mov r2,startcopy ; jump to start of code in ram
bx r2
startcode
@textarea $03000000
startcopy
mov r10,palram
mov r3,0 ;red
lpr3:
mov r2,0 ;green
lpr2:
mov r1,0 ;blue
lpr1:
mov r0,r1 ;red
add r0,r0,r2,lsl #5 ;shift green and add
add r0,r0,r3,lsl #10 ;shift blue and add
strh r0,[r10],2 ;store colour
add r1,r1,4
cmp r1,32
bne lpr1 ;red
add r2,r2,4
cmp r2,32
bne lpr2 ;green
add r3,r3,8
cmp r3,32
bne lpr3 ;blue
mov r0,gfxram
mov r2,$00 ;black/see thro
mov r1,64
lpt1 strb r2,[r0],1
subs r1,r1,1
bne lpt1
mov r2,0 ;pattern
mov r1,64
lpt2 strb r2,[r0],1
add r2,r2,1
subs r1,r1,1
bne lpt2
mov r0,gfxram
add r0,r0,$1000
mov r2,0 ;count 128 lines, 2 at a time
lpc1c
mov r1,$0001 ;two tiles, 0 and 1
mov r3,0
lpc2c strh r1,[r0],2 ;write a word into video memory
add r3,r3,2 ;64 times
cmp r3,128
bne lpc2c
mov r1,$0100 ;two tiles 1 and 0 this time, to form chequerboard
mov r3,0
lpc3c strh r1,[r0],2 ;write a word into video memory
add r3,r3,2 ;64 times
cmp r3,128
bne lpc3c
add r2,r2,2 ; next 2 lines
cmp r2,128
bne lpc1c
mov r0,ioregs
mov r1,3 ;map size 00-03 - 3 means 128*128 tiles
mov r2,0 ;tile gfx ptr 00-03 - 0 means $6000000
mov r3,1 ;palette flag 00-01 - 1 means 256 colrs
mov r4,2 ;map ptr 00-31 - 2 means $6001000
mov r5,0 ;priority 00-03 - 0 means hi
mov r1,r1,lsl #14 ;shift bits into position
mov r2,r2,lsl #2
mov r3,r3,lsl #7
mov r4,r4,lsl #8
orr r1,r1,r2
orr r1,r1,r3
orr r1,r1,r4
orr r1,r1,r5
strh r1,[r0,12] ;store bg2 flags, etc
mov r1,inthandler ;store the address of our interrupt handler
mov r2,$3000000 ;in address $3007ffc which is where the
add r2,r2,$7f00 ;GBA jumps to on servicing an interrupt
add r2,r2,$fc ;Dont ask me why, it just does.
str r1,[r2]
mov r9,ioregs ;set up addresses to use as bases
mov r10,ioregs
add r10,r10,$200
mov r1,1
str r1,[r10,08] ;Enable master interrupts
mov r1,8
strh r1,[r9,4] ;Enable hardware to cause vblank interrupts
mov r1,1
strh r1,[r10,00] ;Enable vblank interrupts themselves
waitint
b waitint ;Sit in a loop and do nothing
inthandler
mov r1,ioregs
add r1,r1,$200
ldrh r3,[r1,02] ;read interrupt status register
ands r1,r3,1 ;is it vblank
bne int_vbl
ands r1,r3,2 ;is it hblank
bne int_hbl
ands r1,r3,4 ;is it vcount
bne int_vco
strh r3,[r1,02] ;clear anyway
bx lr ;return
int_vbl:
ldr r1,[introt] ;This is the only 'real' bit of code that
add r1,r1,$0400000 ;the interrupts call. The variable introt
str r1,[introt] ;is added to, rotating the grid.
mov r1,ioregs ;disable all screen/background/sprites
mov r0,$0000 ;just a quick way of making everything
str r0,[r1,0] ;black for the top half of the screen
mov r1,ioregs
mov r0,$5400 ;line 84
orr r0,r0,$20 ;enable vcount to trigger an interrupt
strh r0,[r1,4]
add r1,r1,$200
mov r0,4 ;enable vcount interrupt to happen
strh r0,[r1]
ldr r2,[introt]
mov r1,incsintab ;get sin and cos for this frame
mov r0,r2,lsr #22
ldr r2,[r1,r0,lsl #2] ;sin
add r0,r0,256
bic r0,r0,1024
ldr r3,[r1,r0,lsl #2] ;cos
mov r2,r2,lsl #11
mov r3,r3,lsl #11 ;we shift this up so that +1 is
str r2,[intsin] ;represented by $ 8000000
str r3,[intcos]
mov r1,ioregs ;clear vbl interrupt
add r1,r1,$200
mov r3,1
strh r3,[r1,02]
bx lr
int_vco:
mov r0,$54
str r0,[intline]
mov r1,ioregs
mov r0,$10
strh r0,[r1,4] ;enable the hardware to trigger hblank interrupts
mov r0,2
add r1,r1,$200
strh r0,[r1] ;enable hblank interrupts to occur
mov r1,ioregs
add r1,r1,$200
strh r3,[r1,02] ;clear the vcount interrupt
bx lr
int_hbl:
ldr r0,[intline]
add r0,r0,1
str r0,[intline]
mov r1,ioregs
mov r0,$0400 ;background 2
orr r0,r0,1 ;screen mode 1
str r0,[r1,0]
stmfd r13!,{r0-r12}
ldr r2,[intsin]
ldr r3,[intcos]
mov r10,ioregs
ldr r0,[intline] ;yline
sub r0,r0,80 ;yscn
mov r1,incdivtab
ldr r8,[r1,r0,lsl #2] ;$1000000/yscn
;x'=x sin a + z cos a
;z'=z sin a - x cos a
smull r0,r1,r8,r2 ;x3d rot = z3dcentre * sin
add r7,r1,256*512 ;add centre x
mov r11,r1,asr #7 ;+zsin/128
rsb r11,r11,0 ;-zsin/128
strh r11,[r10,36] ;STORE delta z
smull r0,r1,r8,r3 ;z3d rot = z3dcentre * cos
add r9,r1,256*512 ;add centre z
mov r12,r1,asr #7 ;zcos/128
strh r12,[r10,32] ;STORE delta x
rsb r1,r12,r12,lsl #4 ;15*
mov r1,r1,lsl #3 ;120*
sub r7,r7,r1 ;add centre x
str r7,[r10,40] ;STORE x start position
rsb r1,r11,r11,lsl #4 ;15*
mov r1,r1,lsl #3 ;120*
sub r9,r9,r1 ;add centre z
str r9,[r10,44] ;STORE z start position
;sl3
ldmfd r13!,{r0-r12}
ldr r0,[intline]
cmp r0,160
bmi int_hbl_1
mov r1,ioregs
mov r0,8
strh r0,[r1,4] ;enable the hardware to trigger vblank interrupts
mov r0,1
add r1,r1,$200
strh r0,[r1] ;enable vblank interrupts to occur
int_hbl_1:
mov r1,ioregs ;clear the hblank interrupt
add r1,r1,$200
strh r3,[r1,02]
bx lr
;--------------------------------------------
; These are the only variables used in this routine
;--------------------------------------------
intline @dcd 0 ;counter for which line the next interrupt is on
intsin @dcd 0 ;sin value read in once a frame and used on each line
intcos @dcd 0 ;cos value read in once a frame and used on each line
introt @dcd 0 ;rotation value for the grid, incremented each frame
@ltorg
finiscopy
@endarea ;this ensures all literals point to correct place
incdivtab
@dcd $00000000,$01000000,$00800000,$00555555
@dcd $00400000,$00333333,$002aaaaa,$00249249
@dcd $00200000,$001c71c7,$00199999,$001745d1
@dcd $00155555,$0013b13b,$00124924,$00111111
@dcd $00100000,$000f0f0f,$000e38e3,$000d7943
@dcd $000ccc0c,$000c30c3,$000ba2e8,$000b2164
@dcd $000aaaaa,$000a3d70,$0009d89d,$00097b42
@dcd $00092492,$0008d3dc,$00088888,$00084210
@dcd $00080000,$0007c1f0,$00078787,$00075075
@dcd $00071c71,$0006eb3e,$0006bca1,$00069069
@dcd $00066666,$00063e70,$00061861,$0005f417
@dcd $0005d174,$0005b05b,$000590b2,$00057262
@dcd $00055555,$00053978,$00051eb8,$00050505
@dcd $0004ec4e,$0004d487,$0004bda1,$0004a790
@dcd $00049249,$00047dc1,$000469ee,$000456c7
@dcd $00044444,$0004325c,$00042108,$00041041
@dcd $00040000,$0003f03f,$0003e0f8,$0003d226
@dcd $0003c3c3,$0003b5cc,$0003a83a,$00039b0a
@dcd $00038e38,$000381c0,$0003759f,$000369d0
@dcd $00035e50,$0003531d,$00034834,$00033d91
@dcd $00033333,$00032916,$00031f38,$00031597
@dcd $00030c30,$00030303,$0002fa0b,$0002f149
@dcd $0002e8ba,$0002e05c,$0002d82d,$0002d02d
@dcd $0002c859,$0002c0b0,$0002b931,$0002b1da
@dcd $0002aaaa,$0002a3a0,$00029cbc,$000295fa
@dcd $00028f5c,$000288df,$00028282,$00027c45
@dcd $00027627,$00027027,$00026a43,$0002647c
@dcd $00025ed0,$0002593f,$000253c8,$00024e6a
@dcd $00024924,$000243f6,$00023ee0,$000239e0
@dcd $000234f7,$00023023,$00022b63,$000226b9
@dcd $00022222,$00021d9e,$0002192e,$000214d0
@dcd $00021084,$00020c49,$00020820,$00020408
;--------------------------------------------
; This is a sin table stored in long words with +1 represented
; by $10000. There are 1024 values representing 360 degrees of rotation
;--------------------------------------------
; blablabla ...