samedi 17 août 2013

Pong sur PIC10F322

Pong est le premier jeux vidéo commercialisé pour l'usage à domicile au début des années 70. Après avoir vu ce jeux réalisé sur un PIC12F1840, je me suis demandé s'il serait possible de le réaliser sur un MCU encore plus petit. Pour le savoir il fallait tenter l'expérience. Ce que j'ai fait avec succès.

démo sur youtube

Circuit électronique

matériel requis

  • 1 microcontrôleur Microchip PIC10LF322
  • 2 prise audio RCA
  • 1 condensateur céramique 100nF
  • 1 condensateur électrolytique 10µF
  • 1 commutateur ON/OFF pour l'alimentation
  • 2 piles 1,5Volt pour l'alimentation
  • 1 diode 1N4148
  • 2 transistors NPN 2N3904
  • 2 résistance 1K 1/4watt
  • 3 résistances 10K 1/4watt
  • 1 résistances 470R 1/4watt
  • 3 résistance 4k7 1/4watt
  • 1 résistance 100R 1/4watt
  • 4 boutons à contact momentané
Le circuit est conçu pour fonctionner avec une alimentation de 3 à 3,6 volt. RA0 est la sortie vidéo qui est ajoutée au signal de synchronisation NTSC qui sort sur RA1. RA2 est la sortie audio mais sert aussi d'entrée pour les boutons de contrôle qui déplacent les raquettes vers le bas. RA3 est utiliser pour les boutons qui déplacent les raquettes vers le haut. L'agencement des transistors Q1 et Q2 permet de sélectionner quel boutons sont lus puisqu'on ne dispose que de 2 entrées on doit les lire en alternance. la sortie vidéo RA0 est utilisée pour sélectionner la lecture joueur gauche/joueur droite. Lorsque la sortie RA0 est à 3 volt le transistor Q1 est en saturation alors que Q2 est bloqué. Ce qui permet seulement aux boutons de gauche de fonctionner. Lorsque la sortie RA0 est à 0 volt Q1 est bloqué et Q2 est en saturation permettant aux boutons de droite de fonctionner. Cette lecture n'interfère pas avec le signal vidéo ni la sortie audio car elle n'est effectuée que lorsqu'il n'y a pas de son et de vidéo en sortie.

Le code source

L'ensemble du projet est sur https://github.com/Picatout/pong. Le programme comprends 2 fichiers, pic10f322_m.inc est un fichier de macros d'usage général. Le programme principal est dans le fichier mini-pong.asm. Le programme est entièrement écris en assembleur et occupe presque la totalité de la mémoire flash soit 510 des 512 instructions possible. 42 octets RAM sont attribués à la mémoire bitmap vidéo. La minuterie TIMER2 est utilisée pour générer le signal de synchronisation NTSC par PWM. Une interruption se produit à la fin de chaque cycle PWM. Toute la logique du programme s'exécute à l'intérieur de cette interruption. Les tâches à exécuter sont cédulées selon le numéro de ligne conservé dans la variable ln_cnt. Au début de l'interruption la variable est incrémentée ensuite le céduleur choisi la tâche a exécuter en fonction de cette valeur. Étant donner que la tâche video_output a la plus haute priorité elle est cédulée avant toutes les autres. Les autres tâches ne sont exécutées que lorsqu'il n'y a pas de sortie vidéo. Chaque tâche doit-être complétée avant la fin du cycle PWM donc avoir une durée inférieure à 63,5µSec.

pic10f322_m.inc
mini-pong.asm

Il a fallu que le code soit analysé minutieusement en accordant la priorité à la réduction de sa taille pour réussir à le faire entrer dans cette espace limité. J'ai eu plusieurs échecs de compilation part manque d'espace avant de réussir à caser le programme dans cet espace restreint.

Au démarrage le joueur de gauche a le service. On peut identifier le joueur qui a le service par la balle placée au centre de sa raquette. Pour faire le service le joueur doit déplacer sa raquette dans une direction ou l'autre. Lors de l'échange un joueur peut modifier la trajectoire de la balle en positionnant sa raquette pour que la collision avec la balle se fasse à un endroit différent de la raquette. Les raquettes on 3 pixels en hauteur. Si la balle atteint le pixel du haut la balle repart à 45 degrés vers le haut. Si la balle frappe la raquette au centre elle repart à l'horizontal. Si elle frappe sur le pixel du bas elle repart à 45 degrés vers le bas. Pour modifier la vitesse de la balle il faut changer la valeur de BALL_DLY. Pour changer la vitesse de déplacement des raquettes il faut changer la valeur de BTN_DLY.

1 commentaire:

  1. I hope this is correct: Bien fait! That is really amazing. I had no idea it might be possible to generate any kind of NTSC on a low end MCU.

    RépondreSupprimer