Le langage PGOL

Pinup
ASSEMULATOR

SYSTEM 1 et PROM de jeu

Présentation du système et du langage de programmation utilisé dans ces flippers.

Introduction

Les flippers de la séries SYSTEM 1 utilisaient une carte CPU révolutionnaire à l'époque, dont le principe consistait à séparer les fonctions "standard" communes à toute les machines , des fonctions spécifique pour un modèle particulier. La carte CPU était équipée d'une PROM de jeu, différente pour chaque flipper et que l'on pouvait programmer à l'aide d'un language évolué dénommé PGOL (Pinball Game Oriented Language).

Cette invention à fait l'objet d'un brevet déposé au Canada sous la référence 1-141-861.

Brevet CA1141861:
Documentation

Les fonctions de base (affichage, gestion des crédits, tilt, mode test/bookeeping, etc...) sont gérées par un système d'exploitation programmé d'usine dans les circuits PPS-4 (spiders). Cette partie ne peut pas être modifiée et est identique pour tous les flippers SYSTEM 1. La PROM de jeu en revanche, est modifiable. On dispose d'un espace de 1 K x 4 bits programmable en PGOL, pour personnaliser le fonctionnement du flipper.

Ce système a été développé par Rockwell pour Gottlieb, trés probablement sur un ASSEMULATOR: Rockwell Assemulator

Ce module était l'équipement standard de développement pour les systèmes à base de processeur Rockwell PPS-4: Rockwell Assemulator

Attention: le brevet comporte quelques erreurs et ne doit donc pas être considéré comme une référence technique.

Structure et adressage de la PROM de jeu

Sa capacité est de seulement 1024 x 4 bits, elle est intégralement programmée en PGOL et contient également une zone de paramétrage standardisée. Il n'y a pas non plus de checksum pour s'assurer de l'intégrité du contenu de la PROM, ni de signature permettant d'identifier la version. L'espace d'adressage va de $100 à $4FF (soit un offset de $100 par rapport à l'adresse interne du composant).

La technique utilisée est celle d'une programmation événementielle. Chaque contact déclenche l'éxecution d'un traitement à une adresse spécifique, sauf pour les cinq premiers (contacts de service):

SW10 - $120SW20 - $140SW30 - $160SW40 - $180SW50 - $1A0SW60 - $1C0SW70 - $1E0
SW11 - $124SW21 - $144SW31 - $164SW41 - $184SW51 - $1A4SW61 - $1C4SW71 - $1E4
SW12 - $128SW22 - $148SW32 - $168SW42 - $188SW52 - $1A8SW62 - $1C8SW72 - $1E8
SW13 - $12CSW23 - $14CSW33 - $16CSW43 - $18CSW53 - $1ACSW63 - $1CCSW73 - $1EC
SW14 - $130SW24 - $150SW34 - $170SW44 - $190SW54 - $1B0SW64 - $1D0SW74 - $1F0

Deux adresses sont également réservées au début de la PROM:

  • $100 - Executé au début d'une bille.
  • $104 - Executé à la fin d'une bille.

La première permet d'initialiser des éléments au départ, par exemple, pour allumers des lampes de couloirs. La seconde permet de traiter la perte de la bille, par exemple, pour réaliser le décompte des bonus en fin de jeu.

Configuration

Les zones $108 à $10B sont utilisées pour paramètrer le comportement du flipper, elles sont communes à tous les SYSTEM 1:

  • $108 - ?
  • $109 - ?
  • $10A - ?
  • $10B - Nombre maximal de joueurs (de 1 à 4, habituellement 4, mais à 1 sur le Asteroid Annie).

Le langage PGOL

Il s'agit d'un langage interprété trés simple dont les instructions sont codées sur 4 bits. Il n'y a que 16 instructions, chacune pouvant éventuellement êtres suivie de paramètres, codés sur 4, 8, ou 12 bits. PGOL

Certaines instructions sont conditionnelles et ne sont exécutées que si le "control bit" est à 1. Ce "control bit" est initialisé à 1 par défaut avant le traitement d'un contact. Il est ensuite positionné par certaines instructions, pour tester par exemple, l'état d'une lampe ou d'une cible.

L'instruction STOP (opcode 'C') termine le traitement en cours. On l'utilise à la fin du traitement d'un contact, pour dire au système d'exploitation de se mettre en attente du contact suivant.

L'instruction DELAY (opcode 'F') provoque une attente de 150 ms. Elle peut aussi être utilisée pour remplir des zones inutilisées (FILL).

Les instructions GOTO (opcode 'E') et CGOTO (opcode '3'), sont suivies de l'adresse de branchement (de $100 à $4FF), sur 3 x 4 bits.

Attention: comme on peut le constater, le tableau ci-dessus est érroné. En effet, les adresses qui suivent un GOTO sont bien sur 3 x 4 bits (et non 2 x 4 bits comme mentionnées dans ce tableau). De même, dans la pratique, les scores ne peuvent qu'êtres additonnés (alors que le brevet indique qu'ils peuvent également êtres soustraits).

Exemple de programme en PGOL

Voici le listing du code utilisé pour le cleopatra (#409):

  • Cleopatra - Page 1
  • Cleopatra - Page 2
  • Cleopatra - Page 3
  • Cleopatra - Page 4
  • Cleopatra - Page 5
  • Cleopatra - Page 6
  • Cleopatra - Page 7
  • Cleopatra - Page 8
  • Cleopatra - Page 9
  • Cleopatra - Page 10
  • Cleopatra - Page 11
  • Cleopatra - Page 12

Dans ce listing, la première colonne correspond à l'adresse mémoire ($100 à $4FF). Les quatres suivantes (W1 W2 W2 W4) aux mots de 4 bits, selon la taille des instructions. Viennent ensuite, le n° de ligne, les labels (ou * pour les commentaires) et l'instruction en clair.

Le langage PGOL apparait a première vue relativement abscond, bien qu'il soit en réalité trés simple. Ceci est dû aux limitations techniques de l'époque et il serait aujourd'hui possible de l'écrire de façon beaucoup lisible. En effet, les noms de label étaient limités à 4 caractéres, de même que les paramètres passés aux instructions, ce qui rend le listing peu compréhensible.

Pour les paramètres (instructions de test et positionnement), une codification simple a été utilisée.

  • Le premier caractère indique l'état qui doit être testé ou positionné:
    • T pour True (ou allumé pour les lampes)
    • F pour False (ou éteint pour les lampes)
  • Le deuxième caractère indique ce qui doit être testé ou positionné:
    • L pour Lamp (pour les lampes commandées par la CPU)
    • F pour Flag (indicateurs internes)
    • S pour Solenoid (bobines, relais ou xylophone)
  • Les deux derniers caractères indique le n° de lampe, flag ou solénoïde concerné.

Quelques exemples: TL30 pour allumer la lampe n°30, FL30 pour l'éteindre, TS8 pour activer le solénoïde 8, FF20 pour mettre l'indicateur n° 20 à zéro.

Certaines instructions utilisent par ailleurs un nom peu adapté, par exemple COPY qui n'est autre qu'un TEST.

Codage des paramètres

Les instructions COPY, SET et OR utilisent le même format pour les paramètres (2 x 4 bits). Ces instructions peuvent également êtres utilisées en cascade afin de réaliser des opérations logique (AND/OR). Par exemple, pour tester si un groupe de lampes est allumé.

En SYSTEM 1, il est possible de commander:

  • 8 solénoïdes (knocker, outhole, xylophone, bancs de cibles...)
  • 36 lampes

Le nombre de lampes est réduit à 36 à cause de la carte driver, mais en réalité la carte CPU est prévue d'origine pour en commander jusqu'à 44. Il serait même possible avec quelques modifications de porter ce nombre jusqu'a 64.

Il est également possible de positionner/tester des indicateurs (flags) afin de mémoriser certaines séquences, comme par exemple, pour garder trace du passage de la bille dans les couloirs. Ces flags au nombre de 36 sont libres d'utilisation. On peut également utiliser certains indicateurs spéciaux, comme par exemple le flag 38 qui indique la configuration 3/5 billes.

Structure des paramètres:

  • 1 bit pour indiquer le status (0 = false, 1 = true) à positionner ou tester
  • 1 bit pour indiquer le type d'objet (0 = flag ou solénoide, 1 = lampe)
  • les 6 bits restant indiquent le n° de flag, solénoide ou lampe

Codage pour les lampes (2ème bit = 1):

Les deux premiers bits sont ceux de plus faible poids. Ils utilisent une numérotation un peu inhabituelle, mais logique. Cette numérotation commence à 1 (01) et se termine à 4 (00). Ainsi les codes binaires correspondant à la séquence 1, 2, 3, 4 seront "01", "10", "11" et "00". Les quatre autres bits sont ceux de plus fort poids et correspondent à un numéro de groupe, lequel commence également à 1. Par exemple, la lampe L1 sera codée xx01 0001, la lampe L4 sera codée xx00 0001. La lampe L33 sera codée xx01 1001 et la lampe L36 sera codée xx00 1001.

Codage pour les flags et les solénoïdes (2ème bit = 0):

Le codage est similaire à celui utilisé pour les lampes, à la différence que les flags utilisent les groupes 0 à B et les solénoïdes les groupes C et D. Le flag F1 sera codé xx01 0000, le flag F36 sera codé xx00 1000. Les 8 solénoides sont dans les groupes C et D, le S1 sera donc codé xx01 1100 et le S8 sera codé xx00 1101.

Scores

Contrairement à ce qui est indiqué dans le brevet, les scores ne peuvent êtres qu'additionnés et non soustraits. Les paramètres de l'instruction SCORE sont codés de la façon suivante:

  • 1 bit pour indiquer le mode (toujours à 1 pour addition)
  • 3 bits pour indiquer le multiplicateur
  • 4 bits pour indiquer la valeur

Le score est augmenté de : valeur * multiplicateur. Il est possible d'utiliser les valeurs 0 à 15 et de choisir les multiplicateurs suivants:

  • 0 0 0 ---> 100.000 points
  • 0 0 1 --->  10.000 points
  • 0 1 0 --->   1.000 points
  • 0 1 1 --->     100 points
  • 1 0 0 --->      10 points
  • 1 0 1 --->       1 point

La valeur zéro n'a pas d'intérêt puisque le score ne changera pas. Les multiplicateurs 1 1 0 et 1 1 1 ne doivent pas êtres utilisés, bien qu'ils semblent fonctionner (0,5 point et 0,25 point).

Il est possible de coder certains scores de deux façons, par exemple 1000 points peuvent êtres codés "1000 x 1" ou "100 x 10". Dans le premier cas le comptage sera instantanné, dans le second cas il sera progressif.

Les flags

Ces indicateurs binaires ont plusieurs fonctions: certains sont libres d'utilisation, d'autres servent pour lire la configuration, d'autres encore déclenchent des actions lorsqu'ils sont positionnés.

Le groupe de dix indicateurs F11 à F20 peut également être décalé vers la gauche avec l'instruction RFLG, afin par exemple de gérer des animations de bonus, couloirs, etc...

  • F1...F3   ---> Libres
  • F4        ---> Commande le SPECIAL si positionné à ON
  • F5...F10  ---> Libres
  • F11...F20 ---> Libres (réservés pour les rotations)
  • F21       ---> Commande l'EXTRA BALL si postionné à ON
  • F22...F36 ---> Libres
  • F37       ---> ?
  • F38       ---> Configuration: mode 3/5 balls [ON = 3 balls]
  • F39       ---> Configuration: mode 3/5 balls [ON = 5 balls]
  • F40       ---> ?
  • F41...F44 ---> Libres
  • F45       ---> Configuration: mode 3/5 balls [ON = 3 balls] (idem F38)
  • F46       ---> Configuration: match feature [ON = loterie activée]
  • F47       ---> Configuration: game mode [ON = replay, OFF = extra-ball]
  • F48       ---> Configuration: tilt effect [ON = ball only, OFF = game]

On peut constater que certains flags font double emploi (F38, F39 et F45).

Le positionnement de F21 à ON donne l'extra-ball, la lampe L4 (same player shoot again) est automatiquement allumée.

Le positionnement de F4 à ON donne le spécial, le knocker S2 est automatiquement activé. Selon la configuration, une bille ou une partie supplémentaire (dans la limite du nombre maximal configuré) sont gagnées.

Le registre d'index

C'est un simple compteur sur 4 bits que l'on peut utiliser à discretion (par exemple pour des boucles). Il est remis à zéro au début de chaque bille.

Seules trois opérations sont possibles avec ce compteur:

  • Incrémenter le compteur avec l'instruction INCR
  • Décrémenter le compteur avec l'instruction DECR
  • Tester la valeur du compteur avec l'instruction REQL

Le bonus

Son principe de fonctionnement repose sur l'utilisation de dix lampes réservées (L23 à L32). Chaque lampe s'allume et s'éteint successivement en fonction de l'évolution du bonus. Il n'y a pas de remise à zéro à chaque bille, il convient de décompter correctement le bonus dans la routine prévue à cet effet (en $104).

Deux opérations sont possibles pour les bonus:

  • Incrémenter le bonus avec l'instruction RBUP
  • Décrémenter le bonus avec l'instruction RBDN

La première lampe (L23) n'est pas allumée à l'origine, puis quand le bonus est incrémenté, la lampe suivante (L24) s'allume. Si on utilise le système du bonus, il faut donc allumer manuellement la première lampe (L23) en début de partie. En revanche, quand le bonus est décrémenté, cette lampe s'allume normalement lorsque l'on repasse de L24 à L23.

Lors du décompte de fin de partie, le seul moyen de savoir si on est arrivé à la fin est de tester l'état de la lampe L23. Si cette lampe est allumée, alors on est à la fin du décompte.

Remarques et astuces

Comme on peut le voir pour le cleopatra, la première instruction à l'adresse $100 est exécutée à l'initialisation (nouvelle bille). On fait un GOTO INIT (vers l'adresse $415), où on positionne un certain nombre de variables. De même en fin de bille, l'instruction à l'adresse $104 est un GOTO BONUS (vers l'adresse $26B), où l'on va faire le décompte du bonus.

Dans certains flippers, le positionnement des contacts dans la matrice est choisit judicieusement afin d'optimiser la programmation. Par exemple, pour les bancs de cibles, le traitement est cascadé à l'aide du control bit (via les instructions TOGL et FLAG) afin d'utiliser ensuite une séquence commune.

Nous avons écrit quelques outils afin de faciliter l'étude et le développement dans le langage PGOL, que vous pouvez retrouver sur cette page.

Dernière mise à jour de cette page: 7 Août 2018