Pour ce qui est de la NES (et du SNES surtout), voici un aperçu de base. Je n'ai écrit aucun jeu NES, mais un émulateur NES (Graybox) et fait pas mal d'ingénierie de révision de vieux chariots.
En ce qui concerne le langage de programmation: oui, tout était assemblé. Programmer la NES signifiait travailler directement avec les interruptions matérielles, les ports DMA, la commutation de banque, etc. Heureusement, programmer le 6502 (ou plutôt le 2A03) est assez simple [1]:
- il y a peu de registres: A, X et Y principalement, les deux derniers n'étant utilisables que pour l'indexation et l'itération
- le jeu d'instructions est petit et la plupart du temps simple
- pas beaucoup de mémoire vive: la mémoire vive principale est de 2 Ko, avec une extension optionnelle de 8 Ko sauvegardée par batterie. Sur ces 2 Ko, 256 octets sont réservés pour la pile et la page 0 (les 256 premiers octets) est l'endroit où vous souhaitez stocker vos pointeurs et valeurs les plus utilisés en raison de certains modes d'adressage spéciaux.
Ces trois éléments réunis permettent de créer un environnement assez facile à mémoriser pour l’utiliser. Oui, vous gérez vous-même toute la mémoire, mais cela signifiait essentiellement que vous créiez une carte complète de tout ce qui se passe devant vous et que cette carte n’est pas très grande, car vous devez vous préoccuper uniquement de la distance de 2K. papier quadrillé. Vous deviez planifier un peu plus et affecter statiquement des variables et des constantes aux emplacements de RAM et de ROM (sur des cartouches).
Cela devient un peu plus compliqué une fois que les données de votre cartouche dépassent les limites adressables du processeur. Il s’agit de 64 Ko, dont les 32 Ko inférieurs sont gravés dans la pierre et mappés sur toutes sortes de ports matériels et de RAM. C’est là que la commutation de banque entre en jeu, ce qui implique de mapper une partie de la ROM sur l’espace adresse supérieur (32 Ko).
Ceci peut être utilisé comme le souhaite le programmeur, mais un exemple d'utilisation pourrait être un jeu à 3 niveaux, avec toutes les données de niveau, métadonnées et code pour chaque niveau entassés dans des zones de mémoire distinctes de 8 Ko sur la cartouche. Le niveau peut avoir des rappels pour, par exemple, l’initialisation, la mise à jour par image, etc. Le "chargement" du niveau signifie le mappage de ce bloc de mémoire de 8 Ko à 0xC000, par exemple. Vous pouvez ensuite spécifier que la routine d'initialisation est toujours à 0xC000, que la routine de mise à jour de trame est à 0xC200 et que les données de niveau commencent à 0xC800. Le code principal du jeu, hébergé dans une autre partie de la mémoire, contrôle ensuite les changements de niveau en échangeant simplement la bonne partie et en passant aux adresses absolues 0xC000 et 0xC200 aux moments appropriés.
Wrt graphical data: les données de tuiles de la NES sont des cartes 2 bits 8x8 pixels. Pour le fond, elles sont combinées avec une couche 2 bits à résolution 1/4. Ces valeurs 4 bits ont ensuite été indexées dans une palette de 16 entrées, avec 53 couleurs uniques effectives disponibles. Les sprites ont également utilisé les données de pixel à 2 bits et chaque sprite a spécifié son propre index de groupe à 2 bits, formant à nouveau un index PAL à 4 bits. L'image BG à l'écran est un tableau 32x30 de numéros d'index.
Essentiellement, en ayant une tonne de répétitions et d'index dans les index, vous pouvez garder les données très petites. Les données de niveau étaient souvent stockées sous forme de barres verticales d'index de mosaïques et, comme ces barres verticales étaient également réutilisées, elles étaient également indexées et stockées une seule fois sur la cartouche. Les techniques simples de compression de données fonctionnent de la même manière. Cela a permis à Mario 1 de disposer de 32 Ko de données (avec suffisamment d’espace disponible) et de 8 Ko de données bitmap.
En ce qui concerne les environnements de développement, j'ai vu des photos où des personnes travaillaient sur des ordinateurs certes anciens connectés aux graveurs EEPROM. Le débogage assisté par outil n’était vraiment possible qu’après l’âge SNES [2]. C’est la raison principale pour laquelle tant de vieux jeux contiennent des bugs "évidents" et pourquoi des choses comme Gameshark pourraient faire ce qu’elles font; la santé du joueur sera toujours au mem-location X, vous pouvez donc le forcer à 100 à tout moment.
Si vous trouvez ces choses intéressantes, je vous encourage à consulter, par exemple, http://wiki.nesdev.com/w/index.php/Nesdev_Wiki
Il existe assez peu de cours de programmation pour NES également disponibles en ligne.
J'espère que cette vue d'ensemble simplifiée a permis de mieux comprendre le développement de jeux datant des années 80.
[1] Relativement parlant. De plus, je suis partial lorsque j'ai écrit Graybox elle-même dans un assemblage PowerPC d'environ 85%. [2] Voir l'article de FF6: http://www.edge-online.com/features/the-making-of-final-fantasy-vi/.