; ROM de test pour cartouche flash, Gameboy Color uniquement ; Pedobear en 4 couleurs avec "displacement map" X/Y ; CC-BY-NC 2010 - furrtek.org .ROMGBC ; WLA-DX s'arrangera pour mettre $C0 à $0143, flag CGB .COMPUTEGBCHECKSUM ; WLA-DX écrira le checksum lui-même (nécessaire sur une vraie GB) .NAME "PEDOBEAR " ; Nom du ROM inscrit dans le header .EMPTYFILL $00 ; Padding avec des 0 .CARTRIDGETYPE 3 ; ROM+MBC1+RAM+BATT, pas critique .LICENSEECODENEW "ED" ; Code de license Nintendo, j'en ai pas donc... .COMPUTEGBCOMPLEMENTCHECK ; WLA-DX écrira le code de verif du header (nécessaire sur une vraie GB) .MEMORYMAP SLOTSIZE $4000 ; Deux banks de 16Ko DEFAULTSLOT 0 SLOT 0 $0000 SLOT 1 $4000 .ENDME .ROMBANKSIZE $4000 .ROMBANKS 2 .BANK 0 SLOT 0 .org $0000 .db "BANK 0" ; Chaîne de test, utile que pour tester les EEPROMS .define DISPLACESTART $C000 ; Variable en RAM (ligne de départ de l'effet) .org $0040 call VBlank ; L'interruption VBlank tombe ici reti .org $0048 call HBlank ; L'interruption HBlank tombe ici reti .org $0050 reti .org $0058 reti .org $0060 reti .org $0100 nop jp start ; Entry point (nop recommandé) .org $0104 ; Logo Nintendo, obligatoire .db $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C .db $00,$0D,$00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6 .db $DD,$DD,$D9,$99,$BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC .db $99,$9F,$BB,$B9,$33,$3E .org $014C .db $00 ; Version .org $0150 start: di ; Interruption désactivées ld sp,$fff4 ; Début du stack à $FFF4 parce que Nintendo le veut xor a ld hl,DISPLACESTART ldi (hl),a ; Init de la variable à 0 ldh ($26),a ; Coupe le circuit son call waitvbl ; Attend d'être dans le VBlank ld a,%00010001 ; Éteint l'écran ldh ($40),a ld de,$9108 ; Charge $91 tiles depuis "tiles" vers la VRAM (OAM) ld bc,tiles ld hl,$8000 call loadtiles2bit ld de,$120E ; Charge la map à "map" de taille $21x$0E en VRAM ld hl,$9800+5 ld bc,map call map_tiles ld a,%10000000 ; Selectionne la palette 0, et active l'auto-incrémentation ldh ($68),a ld b,$08 ; Charge 4 couleurs depuis "palette" (2 octets/couleur) ld hl,palette loadpalette: ldi a,(hl) ldh ($69),a dec b jr nz,loadpalette ld a,%10010001 ; Allume l'écran, BG on, tiles à $8000 ldh ($40),a ld a,%00011000 ; Interruptions HBlank et VBlank activées ldh ($41),a ld a,%00000011 ; Interruptions LCD STAT et VBlank activées (double activation à la con) ldh ($FF),a ei loop: jr loop HBlank: ldh a,($44) ; Teste si on dépasse de la table ($80 octets de long) ld hl,DISPLACESTART ; Si n° de ligne actuelle + départ > $80, on dépasse add (hl) cp $80 ;$80 jr nc,ok xor a ; Si on la dépasse, laisser les scrolls à 0 ok: and %01111111 ; Astuce pour limiter la valeur à la largeur de la table ($80-1) ld hl,displace ; A=(displace+A) ld d,$00 ld e,a add hl,de ld a,(hl) ldh ($43),a ; Nouvelle valeur du scroll X ld b,a ld a,$FF sub b ; A=255-A (l'origine de Y est inversée) ldh ($42),a ; Nouvelle valeur du scroll Y ret VBlank: ld hl,DISPLACESTART ; Incrémente la variable (défilement de l'effet) ld a,(hl) inc a ld (hl),a ret ; ROUTINES waitvbl: ldh a,($44) ; Attend le début d'un VBL (première ligne hors de l'écran, Y>144) cp 144 jr c, waitvbl ret loadtiles2bit: ;DE=Tiles08 ;BC=Début données ;HL=Début VRAM call waitforvramaccess push de ; Stocke DE pour reinitialiser E plus tard lp2: ld a, (bc) ; Chope la ligne de pixels (bitplane 1) ldi (hl), a inc bc ld a, (bc) ; Chope la ligne de pixels (bitplane 2) ldi (hl), a inc bc ; Prochaine ligne dec e ; Une ligne en moins à faire jr nz, lp2 ; Pas la dernière ? pop de ; Récupère le E d'origine dec d ; Un tile en moins à faire push de ; Restocke DE jr nz, lp2 ; Pas le dernier tile ? pop de ; Rend SP heureux ret map_tiles: ;DE=LargeurHauteur ;HL=Début VRAM ;BC=Début Map call waitforvramaccess push de ; Stocke DE pour reinitialiser E plus tard lpm: ld a,(bc) ; Chope le numéro de tile inc bc ; Prochain tile ldi (hl),a ; Le stocke en VRAM dec e ; Un tile de moins à faire jr nz,lpm ; Pas le dernier ? pop de ; Récupère le E d'origine ld a,$20 ; Calcule ce qu'il faut ajouter à HL pour passer à la ligne suivante sub e ; Ajouter 32-largeur ($20-E) à HL fillhl: inc hl dec a jr nz,fillhl ; INC bouclé plutot qu'un ADD 16 bits et des PUSH/POP dec d ; Une ligne en moins à faire push de ; Restocke DE jr nz,lpm ; Pas la derniere ligne ? pop de ; Rend SP heureux ret waitforvramaccess: push af push hl ld hl,$FF41 waitvram: bit 1,(hl) jr nz,waitvram ; Attend d'être dans un mode d'accès qui permet d'écrire en VRAM pop hl pop af ret tiles: .include "code/pedobear_tiles.inc" map: .include "code/pedobear_map.inc" palette: ; vvvrrrrr 0bbbbbVV .db %11111111,%11111111 ; Blanc .db %10001111,%00000001 ; Marron clair .db %01100110,%00000000 ; Marron foncé .db %00000000,%00000000 ; Noir ; Moyenne de deux sinus, sur 128 octets displace: .db $06,$07,$08,$09,$0A,$0B,$0C,$0D .db $0E,$0F,$10,$11,$12,$13,$13,$14 .db $15,$15,$16,$16,$16,$16,$17,$17 .db $17,$16,$16,$16,$16,$15,$15,$15 .db $14,$14,$13,$13,$12,$12,$11,$11 .db $10,$10,$10,$10,$0F,$0F,$0F,$0F .db $0F,$0F,$10,$10,$10,$11,$11,$12 .db $13,$14,$14,$15,$16,$17,$18,$19 .db $1A,$1B,$1C,$1D,$1E,$1E,$1F,$20 .db $21,$21,$22,$22,$23,$23,$23,$23 .db $23,$23,$22,$22,$21,$21,$20,$1F .db $1E,$1D,$1C,$1B,$1A,$18,$17,$16 .db $14,$13,$11,$10,$0E,$0D,$0C,$0A .db $09,$08,$06,$05,$04,$03,$03,$02 .db $01,$01,$00,$00,$00,$00,$00,$00 .db $00,$01,$01,$02,$02,$03,$04,$05