;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exercice d'assembleur dans le cours de systeme d'exploitation 2 de Louis 
; Marchand.
; PacMan en assembleur NES
; Création: Marie-Michèle Fauteux
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;; Entète de la rom ;;;;;;;;;;;
	.inesprg 1 ; 1 banque de 16KB (2 banque de 8KB) pour le programme
	.ineschr 1 ; 1 banque de 8KB pour les image (2 tables de motifs)
	.inesmap 0 ; mapper 0 = NROM, Banque par défaut
	.inesmir 1 ; Mirroir vertical de l'image de fond

	.code
	
	.bank 0   ; Banque 0 (8KB de $C000 à $DFFF
	.org $C000  ; goto location $C000.

Start:
	SEI         ; Arreter les interruption, Met le bit I du registre P (etat du processeur) a 1
	CLD         ; Arrete le mode decimal. Met le bit D du registre P à 0
	LDX #$40
	STX $4017  ;  Met $40 dans le registre de controle de l'APU pour arreter les interruptions de l'APU
	LDX #$FF
	TXS         ; Initialise la pile. Place X ($FF$ comme octet moins significatif de l'adresse de la pile). La pile est toujours entre $0100 et $01FF.
	INX         ; Lorsqu'on incremente X qui contient $FF, C tombe à 0
	STX $2000  ;  Arrete les interruption NMI (Bit 7 du registre Contrôle PPU)
	STX $2001  ;  N'affiche rien (Voir bits 3 à 7 du registre Masque PPU)
	STX $4010  ;  Arrete les interruption logiciel

	JSR vblankwait	; Place l'adresse en cour sur la pile et branche vers la routine "vblankwait"

clrmem:
	LDA #$00
	STA $0000,  x		; Place tous les octets à 0 (", x" correspond a l'adressage indexe avec le registre x)
	STA $0100,  x
	STA $0300,  x
	STA $0400,  x
	STA $0500,  x
	STA $0600,  x
	STA $0700, x
	LDA #$FE
	STA $0200, x		; Placer tous les sprite en dehors de l'écran (Je place mes sprites dans les adresses $0200 à $02FF)
	INX					; Prochaine itération
	BNE clrmem		; Branche si non zero (lorsque x a fait le tour des valeurs de $00 à $FF)

	JSR vblankwait	; Place l'adresse en cour sur la pile et branche vers la routine "vblankwait"

;;;;  Initialise le PPU  ;;;;

LoadPalettes:
 	LDA $2002    		; Lire le registre d'etat du PPU ou annuler le latch de $2006 (s'il y a lieu)
	LDA #$3F	
	STA $2006    		; Place les 8 bits les plus significatifs de l'adresse $3F00 dans $2006
	LDA #$00
	STA $2006    		; Place les 8 bits les moins significatifs de l'adresse $3F00 dans $2006
	LDX #$00
LoadPalettesLoop:
	LDA palettes, x		; Charge les donnees de la palette (", x" correspond a l'adressage indexe avec le registre x)
	STA $2007		; Place les informations du PPU (l'adresse d'écriture de $2007 incrémente automatiquement de 1 octet après chaque ecriture)
	INX			; Prochain index a aller chercher dans la palette en memoire rom (etiquette palette+x)
	CPX #32            
	BNE LoadPalettesLoop 	; La palette est completement copiees si x est à 32=16x2

LoadName:
	LDA #$20	; Nous utiliserons la table de nom 0 (Adr $2000)
	STA $2006
	LDA #$00
	STA $2006
	LDX #0	; x sera notre index de largeur
	LDY #0	; y sera notre index de hauteur
LoadNameLoop:
	STA $2007	; Mettre la tuille no 0 dans la table
	INX
	CPX #32
	BNE LoadNameLoop	; Lorsque x=32, on a une ligne pleine
	LDX #0
	INY
	CPY #30
	BNE LoadNameLoop	; lorsque y=30, on a terminer (32x30 tuiles)

	LDX #0
	LDA #0	; Changer cette valeur pour changer la sous-palette de couleur à utiliser (2 bits par 2x2 tuiles)
LoadAttribute:
	STA $2007
	INX
	CPX #64
	BNE LoadAttribute ; Il y a 64 attribut
	
	JSR vblankwait	; Place l'adresse en cour sur la pile et branche vers la routine "vblankwait"

	JSR activePPU
	
Forever:
  JMP Forever     ;Boucle sans fin, le processus se fera lors d'interruption

NMI:
	RTI             ; retourne de l'interruption
  
vblankwait:			; Routine qui attend que l'écran ait terminé de s'afficher (pour éviter les problèmes visuels)
	BIT $2002		; Bit place les Code de condition N, V, Z.
	BPL vblankwait	; Si le bit 7 est allumé, on a un vblank (BPL = N flag clear, le bit de negatif = bit 7)
	RTS	
	
	
activePPU:
	LDA #%10010100		; Active les interruption NMI, table de motif: sprite = 0 et image de fond = 1
	STA $2000
	LDA #%11111110		; Active l'image de fond, mais pas les sprites
	STA $2001
	LDA #$00		;Ne pas faire de defilement d'image
	STA $2005
	STA $2005
	RTS
	
;;;;;;Espace mémoire pour stocker les palettes;;;;;;;;;;;;;;;;;;;;;;;
	bank 1
	.org $E000 
	
	palettes:
        .db $01, $37, $35, $31, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; palette du fond d'écran
		.db $30, $30, $24, $31, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00; palettes des sprites
	
	
	.org $FFFA	; vecteur d'interruption commence à $FFFA

	.dw NMI		; Interruption NMI (vblank). Adresse $FFFA
	.dw Start	; Interruption Reset (demarrage). Adresse $FFFC
	.dw 0		; Interruption logiciel (instruction BRK). Adresse $FFFE


	.bank 2        ; change to bank 2 (banque de 16kb du ROM inclue dans la PPU au démarrage)
	.org $0000

	; Ici, on place les tuile pour le sprite

	.org $1000	; Motif de background
	
BackgroundMotif10:	; Tuile 0
	.db %10000001, %10000001
	.db %01000010, %01000010
	.db %00100100, %00100100
	.db %00011000, %00000000
	.db %00011000, %00000000
	.db %00100100, %00100100
	.db %01000010, %01000010
	.db %10000001, %10000001

BackgroundMotif1:	; Tuile 1
	.db %10000001		; Bit le moins significatif de la premiere ligne de la tile
	.db %01000010		; Bit le moins significatif de la deuxieme ligne de la tile
	.db %00000000		; Bit le moins significatif de la troisieme ligne de la tile
	.db %00000000		; Bit le moins significatif de la quatrieme ligne de la tile
	.db %00000000		; Bit le moins significatif de la cinquieme ligne de la tile
	.db %00000000		; Bit le moins significatif de la cixieme ligne de la tile
	.db %01000010		; Bit le moins significatif de la septieme ligne de la tile
	.db %10000001		; Bit le moins significatif de la huitieme ligne de la tile

	.db %10000000		; 2e Bit le moins significatif de la premiere ligne de la tile
	.db %00000000		; 2e Bit le moins significatif de la deuxieme ligne de la tile
	.db %00010000		; 2e Bit le moins significatif de la troisieme ligne de la tile
	.db %00000000		; 2e Bit le moins significatif de la quatrieme ligne de la tile
	.db %00000000		; 2e Bit le moins significatif de la cinquieme ligne de la tile
	.db %00000000		; 2e Bit le moins significatif de la cixieme ligne de la tile
	.db %00001000		; 2e Bit le moins significatif de la septieme ligne de la tile
	.db %00000000		; 2e Bit le moins significatif de la huitieme ligne de la tile
