move nes into the sources/NES directory
This commit is contained in:
865
docs/nesdoc2.txt
Normal file
865
docs/nesdoc2.txt
Normal file
@@ -0,0 +1,865 @@
|
||||
|
||||
Vous êtes déjà arrivé jusqu'ici?? Wow mes féliciations!!
|
||||
Maintenant ça risque de devenir un peu plus corsé...
|
||||
|
||||
|
||||
Fonctionnement de la PPU (Picture Processing Unit):
|
||||
--------------------------------------------------
|
||||
|
||||
Petite intro:
|
||||
|
||||
Comprendre le fonctionnement de la PPU c'est un peu une manière de comprendre
|
||||
comment une console fonctionne, à savoir décharger le maximum de tâches à
|
||||
ses coprocesseurs. Dans le cas présent de toute façon la NES a un fonctionnement
|
||||
extrèmement simple puisque la PPU est le seul véritable coprocesseur.
|
||||
|
||||
1. Partage de la VRAM:
|
||||
|
||||
La NES dispose de 16 ko de mémoire video (et pas 32 ko comme on peut le voir souvent).
|
||||
D'ailleurs n'essayez absolument pas de donner au registre d'adresse de la PPU
|
||||
une adresse sur plus de 14 bits, car les $C000 octets suivants sont juste des
|
||||
miroirs.
|
||||
Cette mémoire est complétement dédiée au fonctionnement de la PPU, et n'est pas
|
||||
directement accessible par le processeur central. Par conséquent, pour pouvoir
|
||||
accéder à cette mémoire, on dispose de toute une batterie de pseudo-registres qui
|
||||
sont en fait utilisés tels des adresses en mémoire centrale. Ces pseudo-registres
|
||||
permettent en fait de piloter la PPU pour l'affichage des sprites, faire des scrollings,
|
||||
régler les couleurs, ect...
|
||||
|
||||
Voilà comment est partagée la mémoire:
|
||||
$0 -> $FFF : Table des graphismes #0 (Pattern Table) d'une taille de $1000 (4096)
|
||||
$1000 -> $1FFF : Table des graphismes #1 d'une taille de $1000 (4096)
|
||||
-> Remarque: si la rom à un mapper particulier (défini dans l'header),
|
||||
il y a moyen que ces tables de graphismes soient en fait 2 banques de la rom (CHR-ROM),
|
||||
ou plus, ce sera expliqué plus loin avec l'utilisation du Multi-Memory Controller.
|
||||
Quoi qu'il en soit ca n'affectera que les $2000 premiers octets de la VRAM.
|
||||
$2000 -> $23BF : Table de nommage #0 (Name Table) d'une taille de $3C0 (960)
|
||||
$23C0 -> $23FF : Table d'attribution #0 (Attribute Table) d'une taille de $40 (64)
|
||||
$2400 -> $27BF : Table de nommage #1 d'une taille de $3C0
|
||||
$27C0 -> $27FF : Table d'attribution #1 d'une taille de $40
|
||||
$2800 -> $2BBF : Table de nommage #2 d'une taille de $3C0
|
||||
$2BC0 -> $2BFF : Table d'attribution #2 d'une taille de $40
|
||||
$2C00 -> $2FBF : Table de nommage #3 d'une taille de $3C0
|
||||
$2FC0 -> $2FFF : Table d'attribution #3 d'une taille de $40
|
||||
$3000 -> $3EFF : Non utilisé
|
||||
$3F00 -> $3F0F : Palette des images d'une taille de $10 (16)
|
||||
$3F10 -> $3F1F : Palette des sprites d'une taille de $10
|
||||
$3F20 -> $3FFF : Miroir des palettes d'une taille de $EO (224)
|
||||
|
||||
Au total $4000 octets soit 16384 octets.
|
||||
|
||||
Quelques détails au niveau des miroirs utilisés dans la VRAM:
|
||||
- les tables de nommage sont soumis à un effet de miroir, qui sera expliqué plus loin.
|
||||
- même chose pour les palettes.
|
||||
|
||||
2. Tables des graphismes:
|
||||
|
||||
Il s'agit en fait d'abord d'expliquer comment sont stockées les données graphiques en
|
||||
mémoire video. Les données sont organisées en "tiles", de 8x8 pixels.
|
||||
Pour chaque tile les couleurs sont codées sur 2 bits, ainsi pour chaque tile on a
|
||||
besoin de $10 octets (16).
|
||||
On se sert des 8 premiers octets pour code le premier bit de chaque pixel et du second
|
||||
pour le deuxieme bit. Voilà ce que ça donne plus concrètement:
|
||||
|
||||
Premier bit Deuxième bit Représentation de la tile
|
||||
|
||||
1. #00011000b -> $18 9. #10000001b -> $81 2 . . 1 1 . . 2
|
||||
2. #01000010b -> $42 10. #00000000b -> $00 . 1 . . . . 1 .
|
||||
3. #10100101b -> $A5 11. #00100100b -> $24 1 . 3 . . 3 . 1
|
||||
4. #10000001b -> $81 12. #00000000b -> $00 1 . . . . . . 1
|
||||
5. #01000010b -> $42 13. #00011000b -> $18 . 1 . 2 2 . 1 .
|
||||
6. #01000010b -> $42 14. #00000000b -> $00 . 1 . . . . 1 .
|
||||
7. #00111100b -> $3C 15. #00000000b -> $00 . . 1 1 1 1 . .
|
||||
8. #00000000b -> $00 16. #00011000b -> $18 . . . 2 2 . . .
|
||||
|
||||
Donc la VRAM contient 2 tables des graphismes pouvant chacune contenir 256 tiles (4096 octets).
|
||||
Soit un total de 512 tiles stockables possibles en mémoire.
|
||||
Pour pouvoir les afficher on va avoir recours aux tables de nommage.
|
||||
|
||||
3. Tables de nommage:
|
||||
|
||||
Les tables de nommage sont en fait des matrices de tiles, et vont constituer la base de l'affichage.
|
||||
La NES a en effet un affichage de 32*30 tiles (soit en pixels 256*240).
|
||||
Donc 32*30=960 soit la mémoire disponible pour une table de nommage. Chaque octet codé dans la table de nommage
|
||||
sera un index vers une tile dans la table des graphismes.
|
||||
Remarque: sur la version NTSC de la NES, les 8 premières et dernières lignes ne sont pas affichées.
|
||||
|
||||
4. Tables d'attribution:
|
||||
|
||||
Le rôle des tables d'attribution est complémentaire à celui des tables de nommage.
|
||||
Comme vu précedemment les couleurs des tiles sont codées sur 2 bits. Mais le système de couleur
|
||||
de la PPU permet un affichage en 16 couleurs, donc codage 4 bits.
|
||||
Pour pouvoir accéder à ces 16 couleurs on a recours aux tables d'attribution.
|
||||
Voilà comment ces tables fonctionnent:
|
||||
|
||||
-Chaque octet dans la table d'attribution retient les 2 bits de poids fort de chaque couleur
|
||||
dans un groupe 4*4 tiles. Pour un groupe de 4 tiles on a ainsi 2 bits dans un octet de la table d'attribution.
|
||||
On peut controler cette equivalence:
|
||||
taille de la table d'attribution -> 64 octets
|
||||
nombre de tiles stockables dans une table de nommage -> 960
|
||||
|
||||
Cela donne shématiquement:
|
||||
octet de la table d'attribution #0
|
||||
33221100
|
||||
||||||+--------- tiles #0 à #3
|
||||
||||+----------- tiles #4 à #7
|
||||
||+------------- tiles #8 à #B
|
||||
+--------------- tiles #C à #F
|
||||
|
||||
Remarque: le numero de tile #? ne correspond pas à l'index de la tile dans la table de nommage
|
||||
car en réalité les couleurs ne sont pas attribuées séquentiellement mais par blocs de 4 tiles.
|
||||
|
||||
|
||||
Complété avec les 2 bits de poids faibles situés dans la table des graphismes on obtient la couleur de la palette qui
|
||||
sera alors affichée à l'écran.
|
||||
|
||||
5. Fonctionnement des palettes:
|
||||
|
||||
La PPU utilise 2 palettes :
|
||||
-la palette des images déstinées à l'affichage des objets statiques d'arrière plan.
|
||||
-la palette des sprites déstinée comme son nom l'indique à l'affichage des sprites.
|
||||
|
||||
Chacune des palette à une taille de 16 octets. Il ne s'agit pas de réelles valeurs RGB
|
||||
mais une référence à une palette interne d'une variété de 52 couleurs possibles.
|
||||
D'autre part les palettes ne sont pas réellement de 16 octets, car les adresses $3F00,
|
||||
$3F04, $3F08 ect... tous les 4 octets renvois en fait à la même couleur!
|
||||
Une couleurs très particulière car c'est elle qui va définir la transparence.
|
||||
Ce qui limite la palette au nombre de couleurs effectif de 13 couleurs
|
||||
Comme on dispose de 13 couleurs en réalité on peut en afficher jusqu'a 25 (une couleur étant commune aux 2 palettes)
|
||||
à l'ecran en même temps (fond d'écran + sprites)
|
||||
|
||||
Pour chaque octet de la palette voilà comment proceder:
|
||||
uullhhhh
|
||||
||||||||
|
||||
||||+----- 4 premiers bits -> défini la valeur chromatique de la couleur:
|
||||
|||| -> attention cette valeur doit être comprise entre 1 et C (12) (sinon -> couleur noire)
|
||||
|||| -> mettre 0 permet d'afficher une nuance de gris selon la luminance choisie
|
||||
||+------- ces 2 bits définissent la luminance, niveau de luminosité choisi
|
||||
+--------- ces derniers bits ne sont pas utilisés
|
||||
|
||||
Voilà les codes correspondant aux couleurs pour les valeur chromatiques:
|
||||
$00 = gris $05 = rose $0A = vert
|
||||
$01 = bleu clair $06 = rouge $0B = vert foncé
|
||||
$02 = bleu cyan $07 = ocre $0C = bleu ardoise
|
||||
$03 = bleu foncé $08 = marron
|
||||
$04 = violet $09 = vert clair
|
||||
Les niveaux de luminosité peuvent semblibement faire varier ces couleurs
|
||||
Il existe un très bon tableau pour voir chaque couleur associée à chaque code sur ce site:
|
||||
http://www.sfu.ca/~ccovell/NESTechFAQ.html
|
||||
|
||||
6. Fonctionnement des miroirs:
|
||||
|
||||
En réalité la VRAM de la NES dispose d'assez de mémoire pour seulement 2 tables de nommage et 2 tables d'attribution.
|
||||
Il en résulte que 2 tables sont en fait des "miroirs" des 2 autres tables.
|
||||
Chaque entrée dans une table est automatiquement alors faites dans l'autre.
|
||||
|
||||
On dispose de 3 modes pour les miroirs (ils sont définis dans l'header pour une rom) :
|
||||
-le premier mode désactive simplement cet effet, et autorise l'utilisation d'une seule table de nommage (et d'attribution).
|
||||
-le second mode, le mode "horizontal", permet d'utiliser les tables #0 et #2, la table #1 est un miroir de la table #0
|
||||
et la table #3 est un miroir de la table #2.
|
||||
-le dernier mode, le mode "vertical", permet d'utiliser les tables #0 et #1, la table #2 est un miroir de la table #0
|
||||
et la table #3 est un miroir de la table #1.
|
||||
|
||||
Les palettes aussi disposent de miroirs, et chaque intervalle à partir de l'adresse $3F20 jusqu'a $3FFF sont des miroirs
|
||||
respectifs des 2 palettes tous les $10 octets (16).
|
||||
|
||||
7. Scrolling de l'arrière plan:
|
||||
|
||||
Comme toute bonne console la NES dispose d'une fonction de scrolling cablée en hardware, ce qui permet un scrolling
|
||||
irréprochable, contrairement à ce que l'on peut obtenir sur un PC.
|
||||
Etant donnée qu'une table de nommage équivaut à la taille d'un ecran, il va falloir utiliser la deuxieme table de
|
||||
nommage à notre disposition.
|
||||
On peut faire scroller l'arrière plan sur 2 axes seulement: horizontalement et verticalement.
|
||||
La résolution est de toute facon de 256*240.
|
||||
Voila shématiquement ce que l'on obtient:
|
||||
|
||||
Horizontal: Vertical:
|
||||
0 512 -> 256*2 +---------+0
|
||||
+---------+---------+ | |
|
||||
| | | | A |
|
||||
| A | B | | |
|
||||
| | | +---------+
|
||||
| | | | |
|
||||
+---------+---------+ | B |
|
||||
| |
|
||||
+---------+480 -> 240*2
|
||||
|
||||
Pour définir quelle table de nommage on utilise pour "A" on a recours aux bits 0 et 1 du registre $2000 qui sera expliqué
|
||||
plus loin. Logiquement "B" sera l'autre table de nommage.
|
||||
Le type de miroir utilisé est défini dans l'header:
|
||||
Horizontal: Table #0 -> Miroir Table #1
|
||||
Table #2 -> Miroir Table #3
|
||||
Vertical: Table #0 -> Miroir Table #2
|
||||
Table #1 -> Miroir Table #3
|
||||
|
||||
Le shéma pour le scrolling des tables est le suivant:
|
||||
|
||||
Table de nommage #2 Table de nommage #3
|
||||
|
||||
|
||||
Table de nommage #0 Table de nommage #1
|
||||
|
||||
L'utilisation du scrolling s'effectue par l'écriture successive de valeurs 8 bits dans le registre $2005.
|
||||
La première valeur ecrite correspond au scrolling vertical, par conséquent elle doit être impérativement
|
||||
inférieure ou égale 239 (du fait de la limitation de la résolution de la NES).
|
||||
La seconde valeur écrite juste après correspond au scrolling horizontal.
|
||||
|
||||
8. Fonctionnement des sprites:
|
||||
|
||||
La PPU dispose de capacités particulières pour la gestion des sprites. Cela va permettre de simplifier l'affichage
|
||||
de sprites à l'écran puisqu'ils seront complètement independant de l'arrière plan sur lequel ils vont apparaitre.
|
||||
|
||||
Il y a une mémoire incluse permettant de stocker les informations de 64 sprites, qui peuvent être d'une taille de 8*8
|
||||
ou 8*16 pixels (8->largeur, 16->longueur). Les données des sprites sont contenues dans la table des graphismes.
|
||||
Pour permettre le stockage de ces informations la NES dispose d'un espace mémoire complétement indépendant de la
|
||||
VRAM et de la mémoire centrale. Cette mémoire est de 256 octets, à raison de 4 octets par sprite (donc capacité pour 64).
|
||||
|
||||
-----------------------------------------------------
|
||||
Pour un sprite:
|
||||
-Octet 0 -> Coordonnée Y du point où le sprite se trouve, c'est à dire l'ordonnée.
|
||||
Ce point est le point du coin haut-gauche du sprite:
|
||||
|
||||
point ->+-------+
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+-------+
|
||||
|
||||
-Octet 1 -> Il s'agit de l'index dans la table des graphismes des données du sprite.
|
||||
S'utilise de la même façon que la table de nommage.
|
||||
Attention les sprites en 8*16 ont une particularité -> voir plus bas.
|
||||
|
||||
-Octet 2 -> Cet octet contient une série de flags qu'il convient d'expliciter:
|
||||
vhp000cc -> octet divisé par flags
|
||||
|
||||
flag v: Flip Vertical -> mis à 1 active le flip vertical (mouvement rapide), sinon désactivé.
|
||||
flag h: Flip Horizontal -> même chose horizontalement.
|
||||
flag p: Priorité d'arrière-plan -> mis à 1 si le sprite doit être caché derrière, sinon laisser à 0.
|
||||
flag 0: Inutilisé
|
||||
flag c: Les 2 bits de poids forts de la couleur, car on ne dispose pas ici des tables d'attributions...
|
||||
Ce flag fonctionne comme les tables d'attribution (voir précédemment).
|
||||
|
||||
-Octet 3 -> Coordonnée X du point où le sprite se trouve, c'est à dire l'abcisse.
|
||||
|
||||
-----------------------------------------------------
|
||||
|
||||
L'utilisation des sprites d'une taille de 8*16 est différente car leur taille fait le double d'une tile normale (8*8).
|
||||
Par conséquent l'adressage par le biais de l'octet d'index dans une valeur de sprite sera interprété différement
|
||||
et on accedera ainsi soit à la première table des graphismes (Pattern #0 à l'adresse en VRAM $0000) ou bien
|
||||
à la seconde table des graphismes (Pattern #1 à l'adresse en VRAM $1000).
|
||||
|
||||
On peut uniquement afficher 8 sprites à la fois sur une "ligne" (scanline), c'est à dire si les sprites ont
|
||||
les mêmes coordonnées en abcisse(X). Techniquement la PPU peut cependant difficilement gérer plus de sprites que cela.
|
||||
|
||||
9. VBlank et HBlank:
|
||||
|
||||
VBlank est pour Vertical Blanking, et HBlank pour Horizontal Blanking. Le blanking c'est le scintillement emis par
|
||||
chaque projection de pixels par le cannon à electrons sur l'écran. La PPU a comme chaque périphérique d'affichage de
|
||||
console un taux de rafraichissement. Ce taux est de 60 hertz (60x/secondes) pour une NES NTSC et 50 hertz pour une PAL.
|
||||
|
||||
Shématiquement le cannon à élecron va ecrire sur la TV les lignes de gauche à droite et une fois arrivé au bout de
|
||||
la ligne il doit revenir à gauche pour ecrire la ligne suivante -> cette période est appelée HBlank.
|
||||
|
||||
Une fois tout l'écran complété il doit revenir tout en haut de l'écran pour procéder à l'affichage de l'écran suivant.
|
||||
Cette période est appelé VBlank.
|
||||
|
||||
On peut voir si la PPU est en période de VBlank en controlant le bit #7 du registre $2002(il est alors à 1), tout comme
|
||||
on peut mettre celui ci à zero. Celui ci est remis à 0 à la fin du VBlank.
|
||||
|
||||
Le bit #6 du registre $2002 est appelé Hit Flag, et sert a controler à l'affichage d'un sprite quand
|
||||
est-ce que l'on va ecrire la première ligne du sprite (il sera alors mis à 1). Si la coordonnée en ordonnée (Y)
|
||||
du sprite est 12, ce flag sera mis à 1 lors de l'écriture de la ligne 12. Il est automatiquement remis à 0
|
||||
lors du VBlank.
|
||||
|
||||
On utilise souvent le contrôle du VBlank comme un timer, à défaut d'y avoir une quelquonque horloge sur la NES.
|
||||
|
||||
Fonctionnement des autres peripheriques:
|
||||
---------------------------------------
|
||||
|
||||
1. Pseudo-Audio Processing Unit:
|
||||
|
||||
Comme son nom l'indique la Pseudo-Audio Processing Unit (pAPU) permet à la NES de sortir du son.
|
||||
Le "Pseudo" vient du fait qu'en réalité il n'existe pas de véritable composant indépendant ayant en charge
|
||||
le traitement du son (à la différence de la SUPERNES et de son SPC700).
|
||||
Le son est en fait traité directement par le processeur et une série de composants de base, les synthèses
|
||||
étant transmises par des registres commandés directement depuis le processeur.
|
||||
|
||||
La NES dispose de 4 voix de synthèses FM et une voix pour le son digital (PCM).
|
||||
Parmi les voies de synthèses, on compte 2 voix de rythme (pulse), une voix de triangle, et
|
||||
un canal de bruit.
|
||||
|
||||
Les voix de rythme ont la possibilité de produire du son dans les fréquences de 54,6 Hz à 12,4 Khz.
|
||||
Il y a possibilité de régler la fréquence de sifflement et la durée du cycle.
|
||||
|
||||
La voix de triangle peut produire du son entre les fréquences 27.3 Hz et 55.9 Khz dans une
|
||||
résolution de 4-bits (donc 16 tonalitées différentes). Ce canal dispose d'un compteur linéaire
|
||||
ce qui permet de le désactiver après une certaine période d'utilisation.
|
||||
|
||||
Le canal de bruit lui a la faculté de produire des sons à des fréquences aléatoires entre 29.3
|
||||
Hz et 447 KHz. On peut l'utiliser pour produire des nombres aléatoires en sortie du canal (utile
|
||||
pour les jeux).
|
||||
|
||||
Fonctionnement du canal digital (DMC):
|
||||
Le canal DMC répond à un fonctionnement bien particulier en comparaison des autres canaux sonores de la pAPU.
|
||||
|
||||
3. Joypads
|
||||
|
||||
Je ne m'interesserais ici qu'au fonctionnement des 2 joypads de base. Les autres périphériques pourraient
|
||||
éventuellement être interessants au cas où vous travaillerez sur un émulateur, auquel cas le contenu de
|
||||
cette documentation se révelerait bien insuffisante.
|
||||
|
||||
La NES supporte donc 2 joypads à la fois (ou un joypad et le Zapper, le pistolet à laser).
|
||||
Ces 2 joypads correspondent respectivement aux registres $4016 et $4017. Le fonctionnement
|
||||
des joypads est particulier en comparaison des autres registres de périphérique.
|
||||
Pour pouvoir utiliser ces registres ont doit d'abord les remettre à l'état initial
|
||||
en écrivant successivement 1 puis 0 dans le registre adéquate.
|
||||
Ensuite on doit réalisé le nombre de lecture nécessaire pour accéder à la touche
|
||||
qui nous interesse de vérifier qu'elle a été préssé.
|
||||
Nombre de lectures défini comme suit:
|
||||
|
||||
Pour chaque registre (soit $4016 ou $4017):
|
||||
$4016:
|
||||
|
||||
Joypad #1 Joypad #3 (*)
|
||||
1 -> A 9 -> A 17 ->----+
|
||||
2 -> B 10 -> B 18 -> |___ ces 4 valeurs sont utilisées pour
|
||||
3 -> SELECT 11 -> SELECT 19 -> | définir quel manette est connectée ("signature")
|
||||
4 -> START 12 -> START 20 ->----+
|
||||
5 -> HAUT 13 -> HAUT 21 -> 0
|
||||
6 -> BAS 14 -> BAS 22 -> 0
|
||||
7 -> GAUCHE 15 -> GAUCHE 23 -> 0
|
||||
8 -> DROITE 16 -> DROITE 24 -> 0
|
||||
|
||||
* -> le joypad #3 est ici uniquement possible si on utilise l'adaptateur 4 manettes.
|
||||
Pareil pour le registre $4017, le Joypad #1 équivaut au Joypad #2
|
||||
" " " " , le Joypad #3 équivaut au Joypad #4
|
||||
Si on utilise pas l'adaptateur 4 manettes les valeurs 9 à 16 sont inutiles.
|
||||
|
||||
Imaginons que nous devions voir si la touche SELECT a été préssée sur le joypad #2,
|
||||
on aura alors le code assembleur suivant:
|
||||
|
||||
LDA #$01 --|
|
||||
STA $4017 |---> remise à 0 du port #2
|
||||
LDA #$00 --|
|
||||
STA $4017
|
||||
LDA $4017 --|
|
||||
LDA $4017 |---> 3 lectures pour SELECT
|
||||
LDA $4017 --|
|
||||
AND #$01 ------> on ne récupère que le bit #0 (voir details dans "Détails sur les registres de periphériques")
|
||||
|
||||
Si la valeur contenue dans l'accumulateur est à 1 alors la touche SELECT a été cochée.
|
||||
|
||||
Signature:
|
||||
On peut vérifier en effectuant un certain nombre de lecture (17)
|
||||
le nombre de joypads connectés. Ainsi on procède comme suit:
|
||||
%0000 -> aucun joypad ou périphérique connecté
|
||||
%0001 -> joypad connecté au port #1 ($4016)
|
||||
#0010 -> joypad connecté au port #2 ($4017)
|
||||
Remarque: les 4 bits correspondent aux valeurs de 17 à 20.
|
||||
On obtient cette valeur après 17 lectures dans le registre $4016 ou $4017
|
||||
|
||||
C'est a peu près tout ce qu'il faut savoir pour les joypads. D'autres types de périphériques d'entrée ont
|
||||
un fonctionnement légèrement différent cependant ils utilisent quoi qu'il arrive les ports $4016 et $4017.
|
||||
|
||||
|
||||
Détails sur les registres de periphériques:
|
||||
------------------------------------------
|
||||
|
||||
On a pas directement accès aux périphériques comme la PPU ou bien les joypads, il faut trouver en moyen à partir de la
|
||||
programmation du processeur central pour piloter ces périphériques. Pour cela on utilise une série de pseudo-registres
|
||||
qui sont en fait des adresses mémoire. Ces adresses sont données en 16 bits.
|
||||
Selon le périphérique on va devoir ecrire (cas de la PPU) ou bien lire (généralement pour la pAPU).
|
||||
On va aussi devoir parfois proceder a une ecriture successive de 2 valeurs.
|
||||
|
||||
|
||||
1. Registres PPU:
|
||||
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2000: Registre de contrôle de la PPU #1 (Ecriture seulement)
|
||||
| masque: vmsbpiNN
|
||||
|
|
||||
| v = Mis à 1 ce bit éxecute automatique une routine NMI (Non Maskable Interrupt) lors d'un VBlank
|
||||
| Rappel: l'adresse de cette routine se trouve en $FFFA dans la PRG-ROM.
|
||||
|
|
||||
| m = Selection PPU
|
||||
| Positionné à Maitre à 0, Esclave à 1. (inutilisé apparament)
|
||||
|
|
||||
| s = Taille des sprites
|
||||
| Si le bit est à 0 -> sprites en 8x8 (taille standard d'une tile)
|
||||
| " " " -> sprites en 8x16
|
||||
|
|
||||
| b = Adresse de la table des graphismes utilisée pour l'arrière plan en VRAM
|
||||
| 0 = $0000
|
||||
| 1 = $1000
|
||||
|
|
||||
| p = Adresse de la table des graphismes utilisée pour les sprites en VRAM
|
||||
| 0 = $0000
|
||||
| 1 = $1000
|
||||
|
|
||||
| i = Incrémentation d'adresse PPU
|
||||
| 0 = incrémentation de 1
|
||||
| 1 = incrémentation de 32
|
||||
|
|
||||
| NN = Adresse de la table de nommage (Name Table) utilisée en VRAM
|
||||
| 00 = $2000
|
||||
| 01 = $2400
|
||||
| 10 = $2800
|
||||
| 11 = $2C00
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2001: Registre de contrôle de la PPU (Ecriture seulement)
|
||||
| masque: fffvVsbt
|
||||
|
|
||||
| fff = Couleur de teint utilisée par defaut ("Colour Emphasis")
|
||||
| 000 = Noir (pas de teint)
|
||||
| 001 = Rouge
|
||||
| 010 = Bleu
|
||||
| 100 = Vert
|
||||
| Remarque: ce n'est pas encore correctement émulé sur certains émulateurs.
|
||||
|
|
||||
| v = Visibilité des sprites (mettre à 1 par défaut pour pouvoir afficher des sprites)
|
||||
|
|
||||
| V = Visibilité de l'arrière plan (mettre à 1 par défaut pour pouvoir afficher l'arrière plan)
|
||||
|
|
||||
| s = Clipping des sprites
|
||||
| 0 = les sprites ne sont pas affichés sur les 8 pixels gauches
|
||||
| 1 = pas de clipping
|
||||
|
|
||||
| b = Clipping de l'arrière-plan
|
||||
| 0 = l'arrière-plan n'est pas affiché sur les 8 pixels gauches
|
||||
| 1 = pas de clipping
|
||||
|
|
||||
| t = Type d'affichage
|
||||
| 0 = affichage couleur
|
||||
| 1 = affichage noir et blanc
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2002: Registre de Status de la PPU (Lecture seulement)
|
||||
| masque: vhsw---- (-> 4 bits de poids faibles non utilisés)
|
||||
|
|
||||
| v = Période de VBlank
|
||||
| Ce bit est mis à 1 durant une période de VBlank.
|
||||
| Il est mis à 0 dès qu'on fait une lecture de ce registre pour
|
||||
| éviter de reéxecuter une routine dans un même VBlank.
|
||||
| Remarque: très utile pour s'en servir comme timer.
|
||||
|
|
||||
| h = Occurence Sprite #0
|
||||
| Ce bit est mis à 1 dès que le VBlank à atteint la position
|
||||
| du sprite #0 (du moins le premier pixel non transparent).
|
||||
| Il est mis à 0 après chaque VBlank.
|
||||
| Voir l'excellente FAQ de Chris Covell pour en savoir d'avantage.
|
||||
|
|
||||
| s = Compteur de sprites par ligne
|
||||
| 0 = 8 ou moins de 8 sprites par ligne
|
||||
| 1 = plus de 8 sprites par ligne
|
||||
|
|
||||
| w = Flag d'ecriture en VRAM
|
||||
| Ce bit mis à 1 indique que la PPU ignore les ecritures faites en VRAM.
|
||||
|
|
||||
| Remarque: Utilisez ce registre SYSTEMATIQUEMENT pour ecrire des données en VRAM.
|
||||
| Il n'est pas conseillé d'ecrire des données hors d'un VBlank durant l'execution.
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2003: Registre d'adresse en SPR-RAM (Ecriture seulement)
|
||||
|
|
||||
| Permet d'écrire l'adresse 8 bits utilisée par le registre $2004
|
||||
| pour accéder à une case mémoire en SPR-RAM.
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2004: Registre d'entrée-sortie en SPR-RAM (Lecture-Ecriture)
|
||||
|
|
||||
| Permet d'écrire ou de lire la case d'adresse définie par le registre $2003.
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2005: Registre de Scrolling d'arrière-plan (Ecriture seulement)
|
||||
|
|
||||
| L'utilisation de ce registre se fait par 2 écritures successives.
|
||||
|
|
||||
| 1ère valeur: Scrolling horizontal
|
||||
| 2ème valeur: Scrolling vertical
|
||||
| Voir la partie sur les scrollings pour plus d'informations
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2006: Registre d'adresse VRAM (Ecriture seulement)
|
||||
|
|
||||
| Il s'agit de l'adresse en VRAM que va utiliser le registre $2007.
|
||||
| L'écriture dans ce registre doit s'effectuer par 2 écritures successives
|
||||
| étant donné la limitation des bus à 8 bits encore une fois.
|
||||
|
|
||||
| 1ère valeur: 8 bits de poids fort de l'adresse
|
||||
| 2ème valeur: 8 bits de poids faible de l'adresse
|
||||
|
|
||||
| REMARQUE: Attention à l'incrémentation d'adresse PPU! A chaque ecriture dans le registre
|
||||
| $2007, l'adresse du registre $2006 est incrémentée soit de 1 ou de 32 (selon le registre PPU #1)
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $2007: Registre d'entrée-sortie en VRAM (Lecture-Ecriture)
|
||||
|
|
||||
| C'est le registre d'accès à la PPU le plus utilisé.
|
||||
| C'est par celui ce que vont passer toutes les ecritures pour les tables des graphismes,
|
||||
| de nommage ou d'attribution, bref toutes les données contenues en VRAM.
|
||||
| Il s'utilise de paire avec le registre $2006 qui défini l'offset en VRAM.
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Gardez à l'esprit que tous les transferts sont efféctués en 8 bits, ce qui inclue de nombreuses boucles si vous
|
||||
avez des données conséquentes à copier. Ainsi pour la SPR-RAM une autre solution gagne en facilité, expliqué
|
||||
juste en dessous.
|
||||
|
||||
Registre spécial:
|
||||
Pour accéder à la SPR-RAM on dispose d'une autre alternative qui facilite grandement les transferts car il
|
||||
permet de copier un bloc fixe de 256 octets de données qu'on aurait par exemple stocké en RAM ou en PRG-ROM.
|
||||
Il s'agit d'un registre DMA (Direct Memory Access) semblabe à ceux utilisés pour le son digital.
|
||||
Ce registre est à l'adresse $4014.
|
||||
La formule est simple:
|
||||
$100 * (opérande stockée dans le registre $4014) = adresse de début du bloc de 256 octets ($100)
|
||||
|
||||
Il est conseillé d'utiliser ce registre pour améliorer les performances du programme.
|
||||
|
||||
2. Registres pAPU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4000: Registre de contrôle #1 de la voix de rythme #1 (Ecriture seulement)
|
||||
|
|
||||
| masque:%ccvessss
|
||||
| ||||+---- Taux d'echantillonage en lecture
|
||||
| |||+----- Selection d'envellope (0 = variée, 1 = fixée)
|
||||
| ||+------ Vague maintenue: répétion automatique (0 = non, 1 = oui)
|
||||
| +-------- Accomplissement du cycle
|
||||
| 00 = 87,5 %
|
||||
| 00 = 75,0 %
|
||||
| 00 = 50,0 %
|
||||
| 00 = 25,0 %
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4001: Registre de contrôle #2 de la voix de rythme #1 (Ecriture seulement)
|
||||
|
|
||||
| masque:%fsssmrrr
|
||||
| |||||+--- étalement de la fréquence: 0 est le minimum, 7 le maximum
|
||||
| ||||| Remarque: voir selon bit #3 pour basse ou haute fréquence
|
||||
| ||||+---- méthode de fréquence (0 -> de haut vers bas, 1-> de bas vers haut)
|
||||
| |+------- vitesse de changement de fréquence
|
||||
| +-------- fréquence de sifflement
|
||||
| 0 -> les bits #0 à #6 sont ignorés
|
||||
| 1 -> les bits #0 à #6 sont pris en compte
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4002: Registre de fréquence #1 de la voix de rythme #1 (Ecriture seulement)
|
||||
|
|
||||
| Note: la fréquence des voix de rythme sont étalées sur 11 bits.
|
||||
| Ce registre permet de déterminer la valeur des 8 bits de
|
||||
| poids faible de la fréquence.
|
||||
|
|
||||
| masque:%ffffffff -> 8 bits de poids faible de la fréquence
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4003: Registre de fréquence #2 de la voix de rythme #1 (Ecriture seulement)
|
||||
|
|
||||
| masque: %tttttfff
|
||||
| |||||+--- les 3 bits de poids fort de la fréquence de la voix de rythme #2
|
||||
| +-------- temps d'activité de la voix
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4004: Registre de contrôle #1 de la voix de rythme #2 (Ecriture seulement)
|
||||
|
|
||||
| Son fonctionnement est identique à la voix de rythme #1 (voir registre $4000)
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4005: Registre de contrôle #2 de la voix de rythme #2 (Ecriture seulement)
|
||||
|
|
||||
| Son fonctionnement est identique à la voix de rythme #1 (voir registre $4001)
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4006: Registre de fréquence #1 de la voix de rythme #2 (Ecriture seulement)
|
||||
|
|
||||
| Son fonctionnement est identique à la voix de rythme #1 (voir registre $4002)
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4007: Registre de fréquence #2 de la voix de rythme #2 (Ecriture seulement)
|
||||
|
|
||||
| Son fonctionnement est identique à la voix de rythme #1 (voir registre $4003)
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4008: Registre de contrôle #1 de la voix de triangle (Ecriture seulement)
|
||||
|
|
||||
| masque:%vccccccc
|
||||
| |+------- compteur linéaire de chargement du registre (voir précision précedemment)
|
||||
| +-------- 0 = longueur d'horloge désactivé
|
||||
| 1 = démarrage linéaire du compteur
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4009: Registre de contrôle #2 de la voix de triangle (Ecriture seulement)
|
||||
|
|
||||
| Ce registre n'est pas utilisé.
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400A: Registre de fréquence #1 de la voix de triangle (Ecriture seulement)
|
||||
|
|
||||
| Note: la fréquence de la voix de triangle s'étale sur 11 bits.
|
||||
| Ce registre permet de déterminer la valeur des 8 bits de
|
||||
| poids faible de la fréquence.
|
||||
|
|
||||
| masque:%ffffffff -> 8 bits de poids faible de la fréquence
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400B: Registre de fréquence #2 de la voix de triangle (Ecriture seulement)
|
||||
|
|
||||
| masque: %tttttfff
|
||||
| |||||+--- les 3 bits de poids fort de la fréquence de la voix de triangle
|
||||
| +-------- temps d'activité de la voix
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400C: Registre de contrôle #1 du canal de bruit (Ecriture seulement)
|
||||
|
|
||||
| masque:%00vessss
|
||||
| ||||+---- Taux d'echantillonage en lecture
|
||||
| |||+----- Selection d'envellope (0 = variée, 1 = fixée)
|
||||
| ||+------ Vague maintenue: répétion automatique (0 = non, 1 = oui)
|
||||
| +-------- Non utilisés
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400D: Registre de contrôle #2 du canal de bruit (Ecriture seulement)
|
||||
|
|
||||
| Ce registre n'est pas utilisé.
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400E: Registre de fréquence #1 du canal de bruit (Ecriture seulement)
|
||||
|
|
||||
| Note: la fréquence du canal de bruit s'étale sur 11 bits.
|
||||
| Ce registre permet de déterminer la valeur des 8 bits de
|
||||
| poids faible de la fréquence.
|
||||
|
|
||||
| masque:%ffffffff -> 8 bits de poids faible de la fréquence
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $400F: Registre de fréquence #2 du canal de bruit (Ecriture seulement)
|
||||
|
|
||||
| masque: %tttttfff
|
||||
| |||||+--- les 3 bits de poids fort de la fréquence du canal de bruit
|
||||
| +-------- temps d'activité de la voix
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4010: Registre de contrôle du canal de son digital (DMC) (Ecriture seulement)
|
||||
|
|
||||
| masque:%i???ssss
|
||||
| ||||+---- fréquence d'échantillonage utilisée
|
||||
| |+------- fonction inconnue
|
||||
| +-------- génére une interruption de type IRQ à l'execution (peut être masquée)
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4011: Registre du volume du canal de son digital DMC (Ecriture seulement)
|
||||
|
|
||||
| Les 8 bits sont utilisés pour définir le volume du canal.
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4012: Registre d'adresse des données digitales du canal DMC (Ecriture seulement)
|
||||
|
|
||||
| Ces 8 bits détermine l'endroit où on doit lire les données pour
|
||||
| le canal DMC.
|
||||
| Les données seront lues dans la 2ème banque de PRG-ROM, c'est à dire de $C000 à $FFFF.
|
||||
| La formule pour trouver l'adresse est la suivante:
|
||||
| ((valeur 8 bits stockée dans $4012) * 64) + $C000
|
||||
| Rappel: 64 = $40
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4013: Registre de longueur des données digitales (Ecriture seulement)
|
||||
|
|
||||
| Définit la longueur de l'échantillon digital à lire à l'adresse $4012
|
||||
| La formule pour calculer sa taille est:
|
||||
| ((valeur 8 bits stockée dans $4013) * 16) + 1
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4014: Registre d'accès direct à la mémoire (DMA) SPR-RAM (Ecriture seulement)
|
||||
|
|
||||
| Voir PPU - Registre spécial.
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4015: Registre d'état de la PPU (Lecture-Ecriture)
|
||||
|
|
||||
| En lecture, ce registre à seulement une fonction:
|
||||
| Seul le bit #0 est important, si il est à 1 c'est que la PPU est en cours d'utilisation
|
||||
|
|
||||
| En écriture:
|
||||
| masque:%000edcba
|
||||
| |||||||+- voix de rythme #1 (0 = désactivée, 1 = activée)
|
||||
| ||||||+-- voix de rythme #2 (0 = désactivée, 1 = activée)
|
||||
| |||||+--- voix de triangle (0 = désactivée, 1 = activée)
|
||||
| ||||+---- canal de bruit (0 = désactivée, 1 = activée)
|
||||
| |||+----- canal digital (0 = désactivée, 1 = activée)
|
||||
| +-------- bits non utilisés
|
||||
|
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Les registres de contrôle des canaux sonores servent juste à configurer les canaux (généralement ceci est fait
|
||||
une seule fois avant de jouer la chanson). Les "notes" sont envoyées par le biais des registres de fréquences
|
||||
avec la fréquence utilisée ainsi que la durée.
|
||||
Le mieux que je puisse vous conseiller c'est de tester ces canaux et d'essayer d'implémenter des partitions
|
||||
récupérées dans des fichiers NSF. Il existe de nombreuses documentations qui expliquent comment procéder. Il
|
||||
existe également un logiciel sur le site NES Development permettant facilement d'écrire une musique et de
|
||||
l'implémenter ensuite dans une rom.
|
||||
|
||||
|
||||
3. Registres Joypads
|
||||
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4016: Registre de contrôle du Joypad #1 (Lecture-Ecriture)
|
||||
|
|
||||
| En lecture:
|
||||
| %???zteed
|
||||
| |||||||+----- donnée du joypad (voir détails périphériques)
|
||||
| |||||+------- lire des données du port d'expansion (utilisé par certains périphériques)
|
||||
| ||||+-------- indique la gachette du Zapper a été préssée
|
||||
| |||+--------- indique qu'un sprite se trouve devant le viseur du Zapper
|
||||
| +------------ utilisation inconnue
|
||||
|
|
||||
| En écriture:
|
||||
| %?????ees
|
||||
| |||||||+----- Mise à jour état des touches du joypad (nécessaire pour lecture des touches)
|
||||
| ||||||| 0 = efface l'état
|
||||
| ||||||| 1 = reset l'état
|
||||
| ||||||| Voir détails précedemment.
|
||||
| |||||+------- écriture de données dans le port d'expansion
|
||||
| +------------ utisation inconnue
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Registre $4017: Registre de contrôle du Joypad #2 (Lecture-Ecriture)
|
||||
|
|
||||
| Son fonctionnement est identique à celui du registre précedent.
|
||||
|
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Autres choses utiles:
|
||||
--------------------
|
||||
|
||||
1. Structure iNes:
|
||||
|
||||
Ici ne sera abordé que la structure iNes, qui utilise un header de 16 octets des fichiers .NES.
|
||||
Cet header ne fait pas vraiment parti de la rom mais contient des informations indispensables
|
||||
à son fonctionnement pour un emulateur (notamment si on utilise un mapper particulier).
|
||||
C'est un standart de fait et il existe d'autres formats (voir meilleurs).
|
||||
|
||||
L'header iNes est de 16 octets($10):
|
||||
|
||||
Adresse |Taille |Contenu
|
||||
| |
|
||||
0 |3 |Contient les 3 caractères ASCII 'NES'
|
||||
| |
|
||||
3 |1 |Contient la valeur $1A
|
||||
| |
|
||||
4 |1 |Nombre de pages de PRG-ROM de 16 ko dans la rom
|
||||
| |
|
||||
5 |1 |Nombre de pages de CHR-ROM de 8 ko dans la rom
|
||||
| |
|
||||
6 |1 |Octet de controle de la ROM #1:
|
||||
| |masque: %mmmmvtsm
|
||||
| | |||||||+-- Miroir utilisé en VRAM (0=horizontal,1=vertical)
|
||||
| | ||||||+--- utilisation de SRAM ou non pour les sauvegardes (1=oui)
|
||||
| | |||||+---- presence d'un trainer de 512 octets
|
||||
| | ||||+----- Possibilité d'utiliser 4 Name Table indépendantes en VRAM
|
||||
| | +--------- 4 bits de poids faible du mapper utilisé
|
||||
| |
|
||||
7 |1 |Octet de controle de la ROM #2:
|
||||
| |masque: %mmmm0000
|
||||
| | ||||+------ ces 4 bits sont toujours à 0
|
||||
| | +---------- 4 bits de poids faible du mapper utilisé
|
||||
| |
|
||||
| |
|
||||
| |Remarque: les octets suivants sont ignorés par la plupart des émulateurs et doivent rester à 0
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Normalement il est d'usage de faire suivre le code (PRG-ROM) juste après l'header.
|
||||
Les pages CHR-ROM suivront donc logiquement et seront automatiquement chargées dans
|
||||
les tables des graphismes. L'utilisation de la CHR-ROM annihile toute possibilité
|
||||
d'écrire dans la VRAM de $0000 à $2000 sous peine de provoquer une erreur de bus,
|
||||
cette mémoire étant dorénavant considérée comme en disponible en lecture seule.
|
||||
On peut ne mettre le code qu'en utilisant que la deuxième page également.
|
||||
Si vous utilisez +de 2 page de PRG-ROM et +de 2 pages de CHR-ROM il vous
|
||||
faudra utiliser un mapper.
|
||||
Si vous n'utilisez qu'une page de PRG-ROM il s'agit toujours de la page commençant en $C000.
|
||||
|
||||
2. Multi-Memory Controler:
|
||||
|
||||
L'utilisation du Multi-Memory Controller est indispensable pour obtenir une taille de rom >40 ko.
|
||||
Son utilisation va de paire avec ce que l'on appele un mapper. Le mapper utilisé est défini dans l'header.
|
||||
Son support par les émulateurs fut longtemps un problème. Il n'y aura pas beaucoup de détails sur cette
|
||||
partie car la mémoire disponible en standard par une rom est largement suffisante pour une démo.
|
||||
|
||||
Tous les mappers sont détaillés à cette adresse:
|
||||
|
||||
http://free.prohosting.com/~nintendo/mappers.nfo
|
||||
|
||||
|
||||
Détails sur les méthodes d'assemblage:
|
||||
-------------------------------------
|
||||
|
||||
La NES est une machine très ancienne et relativement limitée, néanmoins en assembleur il est possible de tirer d'une
|
||||
machine de nombreuses ressources puisque l'on travaille directement avec le matériel.
|
||||
Mais il convient alors t'integrer des méthodes de programmation particulières, ainsi que d'autres propres
|
||||
au système proprement dit.
|
||||
|
||||
Il ne faut surtout pas hésiter à ménager la mémoire disponible en utilisant abondamment le masquage de bit pour les
|
||||
valeurs ne nécéssitant pas beaucoup de combinaisons. C'est à dire utiliser un octet pour définir sur des plages de
|
||||
bits (flags) des valeurs.
|
||||
|
||||
On peut procéder ainsi:
|
||||
|
||||
Si le monstre reponds masque suivant:
|
||||
____________
|
||||
| | | |
|
||||
bbbb bbb b
|
||||
| | +---- bit de vérification d'activation du monstre
|
||||
| +------- flag de 3 bits pour la vie du monstre
|
||||
+----------- flag de 4 bits pour le type de monstre
|
||||
|
||||
;on veut coder un monstre
|
||||
;le nombre maximum de point de vie possible pour un monstre dans mon jeu est 3
|
||||
;il y a 15 monstres différents et on doit aussi avoir une valeur pour voir si il est actif ou non
|
||||
LDA monstre_1
|
||||
AND #$F0
|
||||
LSR A
|
||||
LSR A
|
||||
LSR A
|
||||
LSR A
|
||||
PHA
|
||||
JSR type_monstre ;routine pour identifier le monstre
|
||||
LDA monstre_1
|
||||
AND #$0E
|
||||
LSR A
|
||||
PHA
|
||||
JSR degats_monstre
|
||||
|
||||
|
||||
|
||||
Sur NES notamment, on ne dispose pas d'horloge intégré comme sur un micro-ordinateur (du moins à partir de 1990 la plupart
|
||||
en ont été équipé). Par contre pour palier à ce défaut, on peut utiliser le signal VBlank cablé en hardware répondant
|
||||
à partir d'un registre particulier et d'un routine d'interruption.
|
||||
Deux moyens répondant toutes deux à des besoins différents. Il faut savoir que sur la NES réelle écrire en mémoire vidéo
|
||||
hors que lors du déroulement du VBlank est une source de bug innérante. Par conséquent on est obligé de s'imposer une
|
||||
certaine rigueur de programmation. Rigueur qui n'est pas obligatoirement reproductible lorsque l'on n'a comme seul moyen
|
||||
de test un émulateur.
|
||||
|
||||
Il existe 2 moyens pour utiliser le VBlank:
|
||||
-soit activer le bit #7 du registre $2000 de la PPU pour generer automatique une interruption non masquable et donc
|
||||
appeler la sous routine d'adresse définie par le vecteur situé en $FFFA. Ceci fait vous pouvez placer absolument tout
|
||||
le code que vous voulez du moment que ca n'excede pas la durée du VBlank en éxecution qui est d'environ 16 millisecondes.
|
||||
Ca suffit normalement pour placer une quantité de code relativement suffisante.
|
||||
Il faut bien réaliser que cette routine sera éxécuté 60x par seconde (pour une machine NTSC, par défaut sur la plupart
|
||||
des émulateurs).
|
||||
|
||||
-l'autre moyen c'est de controler lorsqu'un VBlank survient par le biais du bit #7 du registre $2002. Il suffit de créer
|
||||
une routine qui boucle indéfinimment tant que cette condition n'est pas satisfaite. Normalement cela ne pose pas de problème.
|
||||
Attention si vous utilisez également les NMI ainsi que cette méthode car la NMI sera toujours satisfaite d'abord et
|
||||
ensuite uniquement votre routine sera éxecuté.
|
||||
En outre après la lecture du registre $2002 le bit #7 sera automatiquement remis à 0. Un détail qui a une importance
|
||||
majeure puisqu'il va éviter de réexecuter une seconde fois la routine, ce qui fausserait complétement le programme.
|
||||
|
||||
|
||||
|
||||
Epilogue:
|
||||
--------
|
||||
|
||||
Je tiens à remercier tous les auteurs des documentations déjà disponibles en anglais, notamment Y0shi, Chris Covell
|
||||
dont la plupart de ce document à été constitué, ainsi que la plupart des auteurs de documentations disponibles
|
||||
sur l'excellent site NES Development: http://nesdev.parodius.com.
|
||||
Sans eux rien n'aurait été possible.
|
||||
Je tiens également à remercier ceux qui vont utiliser et distribuer ce document, et j'encourage vivement ce type
|
||||
d'initiatives. J'éspère sincérement qu'il vous sera utile autant qu'il m'a été agréable de l'écrire.
|
||||
|
||||
Détails et remarques: crispysix@wanadoo.fr
|
||||
|
||||
------------------------- c'est ------------------ terminé ---------------------------
|
||||
|
||||
Reference in New Issue
Block a user