"Homebrew Channel F serait comme programmer des sprites via des cavaliers matériels ..."
/ chadtower, forum atariage /
La console de jeu
Fairchild Channel F , également connue sous le nom de VES, est apparue en novembre 1976. Contrairement à ses prédécesseurs, tels que Ping-Pong, Tennis (dans la même rangée - le "Sport vidéo" soviétique), il y avait une différence très importante - la présence d'un microprocesseur et de cartouches avec des programmes. Avant cela, les jeux dans les consoles étaient implémentés selon une logique stricte - le programme, au sens moderne, y était absent.
Fairchild Channel F est sorti jusqu'en 1983. Pendant cette période, plus d'un quart de million de ces consoles ont été vendues et environ 30 à 40
jeux ont été lancés , dont
certains étaient déjà dans les années 2000.
Parlant de la supériorité en termes d'utilisation d'un microprocesseur, il convient de noter que le RCA Studio II, dont j'ai parlé dans un article précédent, n'avait que quelques mois de retard, mais s'est avéré être beaucoup plus faible que le canal F, c'est pourquoi il a échoué dans les ventes. Cependant, l'apparition, moins d'un an plus tard, Atari VCS - et remplacé Channel F. du marché.
Le développement de Fairchild_Channel_F, en tant que tel, ne l'était pas. Dans System II et plusieurs clones, comme Saba Videoplay 2 (1979), les différences étaient principalement dans le corps, les joysticks (en passant, ils ont tous compris, sauf pour les positions habituelles, la rotation du bouton) et le nombre de puces. Sur le plan architectural, tout était presque identique.
Qu'est-ce que le canal F?
CPU
Le processeur, dans les traditions de l'époque, a été produit par la même société Fairchild que la console elle-même et s'appelle F8
en.wikipedia.org/wiki/Fairchild_F8 . Il s'agit d'un processeur 8 bits de 1974, fonctionnant à une fréquence de 1,8 MHz (une instruction prend de 1 à 6 cycles d'horloge).
Cependant, il peut être appelé un microprocesseur uniquement avec un tronçon, car ce processeur se compose de deux puces - un dispositif informatique 3850CPU contenant ALU, une batterie, 64 octets de SRAM, la logique nécessaire pour exécuter les instructions, deux ports (il n'y a pas de bus d'adresse!) Et 3851PSU (programmable Storage Unit), qui contient 1 Ko de ROM (utilisé pour le BIOS), un pointeur d’instruction, des schémas d’adressage de mémoire, des interruptions, un temporisateur (les interruptions et un temporisateur ne sont pas utilisés spécifiquement dans le canal F).
Plus tard, la puce F3859 est apparue, qui combinait le CPU et le PSU sur la même puce et le Mostek 3870 - une version légèrement améliorée, publiée jusqu'aux années 1990. Mais c'est une autre histoire. Fait intéressant, le F8 est parfois appelé microcontrôleur (en particulier, en raison de la présence d'une minuterie et de ports) et est considéré comme l'ancêtre de la famille Intel MCS-48 (8048).
En plus du canal F, le processeur F8 était également utilisé dans l'ordinateur
VideoBrain et dans l'ordinateur d'échecs
CompuChess . En général, il est surprenant qu'il y ait très peu d'informations sur ce processeur. À l'exception de quelques descriptions de Fairchild et du code source de plusieurs jeux et exemples spécifiquement pour Channel F, il n'y a rien de plus. Il semble que ce processeur n'ait été utilisé nulle part ailleurs, ce qui semble incroyable (étant donné que ses versions avancées sont sorties depuis un certain temps). Je suppose que tous les autres appareils où ils ont été utilisés étaient à des fins militaires.
Maintenant, un peu sur les fonctionnalités du processeur. Réfléchissez sur l'ensemble et les fonctions de ses registres. Je pense que c'est l'une des architectures les plus confuses qui existaient à l'époque (probablement les modernes peuvent s'étirer, mais la comparaison sera incorrecte, car elles sont conçues pour les compilateurs. Les personnes vivantes ont travaillé avec F8).
Il y a beaucoup de registres dans le processeur. En plus de la batterie 8 bits A et du registre d'indicateur W (I, O, Z, C, S), il existe également un «bloc-notes» - 64 cellules de huit bits avec diverses fonctions.
Les neuf premières cellules sont utilisées comme registres à usage général R0-R8 dans des commandes comme 'lr a, 7 "(chargez le contenu du registre R7 dans la batterie). Notez que la lettre R n'est pas indiquée - seul le numéro de registre est écrit. Que signifie exactement le nombre ou le nombre doit être clair d'après le contexte. Disons que dans le cas de l'instruction lr, il ne peut tout simplement pas y avoir de nombres. Et si, par exemple, "li 7" (charge une constante dans la batterie), alors c'est exactement un nombre, pas un registre.
Les cellules 9, 10-11 (H), 12-13 (K), 14-15 (Q) sont conçues pour enregistrer d'autres registres dans différentes situations, telles que l'appel de sous-programmes.
Les registres R16-R63 ne sont accessibles que via un registre d'index ISAR spécial (registre d'adresse Scratchpad indirect), sous forme de six tampons de huit octets formés à partir des cellules 16-23, 24-31, 32-39, 40-47, 48-55, 56-63 .
L'ISAR à six bits est divisé en deux parties de 3 bits. Lorsque vous augmentez ou diminuez ISAR de un, seuls les 3 bits inférieurs sont affectés - c'est-à-dire l'adressage est effectué dans l'un des six tampons de huit octets mentionnés (en même temps, la fin du tampon peut être tracée par les instructions spéciales de branchement conditionnel br7).
clr ; 0 -> A ; set ISAR to full address Ox27 (octal 27) lisu 2 ; buffer N2 lisl 7 ; index within buffer N2 loop: lr d,a ; A-> buffer N2[index], than decrement ISAR (27, 26, 25, ... ) br7 loop ; go further if low part of ISAR contains 7 (end of buffer N2). if not, go loop again
Dans ce cas, «d» dans l'instruction «lr d, a» n'est pas le nom du registre, mais un signe que l'ISAR devra être réduit («i» - augmenter, «s» - laisser inchangé).
Il existe un autre moyen d'adressage indirect - via le registre DC0 (Data Counter):
dci data_addr ; data_addr -> DC0 lm ; [data_addr] -> A, DC0 + 1 -> DC0 ... data_addr: db 0,1,2,3,...
Si vous devez transférer des données d'une zone mémoire à une autre, la commande xdc est en outre utilisée, qui permute le contenu des registres DC0 et DC1. C'est-à-dire nous lisons à partir de l'adresse pointée par DC0, puis faisons xdc et écrivons à l'adresse vers laquelle DC1 pointe maintenant. Puis à nouveau xdc, etc. C'est-à-dire DC1 est une sorte de registre fantôme pour stocker une copie de DC0. Il est impossible d'y accéder directement (sauf pour la commande xdc).
Les exemples ci-dessus n'illustrent qu'une partie des possibilités en termes d'adressage, en fait, il y en a plus.
Toujours dans F8, il y a quatre ports - 0,1,4,5, dans lesquels vous pouvez écrire avec la commande out et lire avec la commande in. Dans le canal F, les ports sont utilisés pour produire des graphiques, du son et lire l'état du joystick.
Je ne m'attarderai pas sur d'autres instructions telles que l'arithmétique, les transitions, etc. - elles sont assez standard. Je note seulement que le choix des registres sur lesquels vous pouvez effectuer des actions est très limité, de sorte que le code se développe rapidement en raison de la nécessité de déplacer constamment les valeurs d'avant en arrière.
Il n'y a pas de soustraction (il n'y a que l'addition). Les instructions de décrémentation (ds) et d'incrémentation (inc) par unité sont asymétriques. ds ne fonctionne qu'avec les registres r0-r8, inc - uniquement avec la batterie.
Un saut inconditionnel gâche la batterie.
Un exemple de boucle régulière:
li 25 ; (r4) number of iterations lr 4,a next: ds 4 ; r4-- bnz next ; until r4 == 0
Routines
Étant donné que F8 n'a pas de pile matérielle, il existe des problèmes avec les appels de sous-programme imbriqués. Un appel et un retour normaux ressemblent à ceci:
; ...code pi sub ; Pushes address of next instruction to PC1 ; address of sub is stored in PC0 (jump to subroutine) ; ...code continues sub: ; ... often used code pop ; Move return address from PC1 to PC0
Ici PC0 est un pointeur d'instruction régulier. PC1 - le soi-disant "registre de pile". Cela n'a rien à voir avec la pile, seul PC0 y est enregistré lorsque le sous-programme est appelé.
Si un autre sous-programme est appelé depuis sub, l'adresse de retour est écrasée et doit être compliquée (enregistrer la première adresse de retour dans le registre K):
prog: ; ...do something... pi sub1 ; Address of next instruction stored in PC1 ; sub1 is stored in PC0 (jump to subroutine) ; ...do more... sub1: lr k,p ; Copy PC1 to K, original jump address to K ; ...do something... pi sub2 ; Pushes address of next instruction to PC1 ; sub1 is stored in PC0 (jump to subroutine) ; ...do more... pk ; Store address of next instruction in PC1 ; Copy value in K to PC0 (jump back to main) sub2: ; ...do something... pop ; Move return address from PC1 to PC0
Si vous avez également besoin d'un troisième niveau d'imbrication, tout devient complètement triste (dans le BIOS, il existe même deux routines spéciales - pushk et popk).
La recommandation générale est d'essayer de remplacer les appels de sous-programme par des macros. Bien sûr, s'il n'y a pas de restrictions strictes sur la taille du code.
Il n'y a pas de pile matérielle dans F8. Si nécessaire, il est implémenté par programme - via ISAR et des tampons.
L'écriture dans la RAM n'est pas très pertinente (faute d'en avoir une), mais elle ressemble à ceci:
li $FF ; set value dci $3800 ; set target address st ; write
La mémoire
Bien que cela semble un peu étrange, il n'y a pas de RAM dans Fairchild Channel F. Les deux kilo-octets existants de mémoire vidéo (MK4027) ne sont pas affichés dans l'espace d'adressage, et en effet ils ne sont pas lisibles, ils sont écrits sur des ports. Les registres du microprocesseur, même jusqu'à 64, sont à peine considérés comme corrects pour la RAM.
Le programme exécutable est stocké dans des cartouches ROM amovibles, ayant le plus souvent une capacité de 2 ko (certains jeux modernes utilisent des cartouches 3 k, 4 k et 5 k). De plus, il y a une puce de processeur intégrée, 1KB BIOS ROM, contenant un jeu simple tel que Tennis, quelques routines utiles et des images de plusieurs personnages.
Dans l'espace d'adressage, le BIOS se situe de 0000 $ à 07 $ fff, la cartouche ROM - à partir de 0800 $.
Graphisme
Les capacités graphiques du canal F sont très primitives, car il n'y a tout simplement pas de contrôleur vidéo sous la forme d'une puce séparée - tout est implémenté sur la logique habituelle, comme les registres à décalage, les portes et les amplificateurs opérationnels. Il est assez inhabituel que différentes sources mentionnent différentes résolutions, et il existe de nombreuses options. Le fait est que les 2 kilo-octets de mémoire vidéo disponibles impliquent une résolution de 128 x 64, mais en réalité c'est loin d'être le cas. Tout d'abord, cela dépend beaucoup de la zone de l'image en cours de formation sur ce téléviseur particulier (à cause de laquelle les 4 premières colonnes ne sont pas du tout officiellement utilisées). Deuxièmement, les dernières colonnes sont utilisées sous la palette. Troisièmement, une partie de la mémoire n'est pas utilisée du tout.
En conséquence, la résolution réelle peut être estimée à environ 95 x 58 pixels avec 8 couleurs (ce qui, cependant, est bien meilleur que RCA Studio II avec ses 64x32 noir et blanc).
La plupart des consoles sont publiées dans la version NTSC, mais PAL existe également. Il n'y a pas de différences pratiques, comme on dit (le nombre de lignes est le même).
Essentiellement, un fer aussi simple vous permet uniquement de dessiner des points sur l'écran. Bien que le nombre total de couleurs affichées soit de 8, seules quatre peuvent être affichées sur une même ligne (vous pouvez appeler arbitrairement cette palette). La palette est définie individuellement pour chaque ligne et est stockée dans un endroit plutôt étrange - dans les colonnes 125 et 126 de chacune des lignes (qui sont en tout cas en dehors de la zone visible). Changer la palette se fait, respectivement, en dessinant des pixels dans ces deux colonnes.
(la zone de mémoire vidéo qui est réellement visible à l'écran et la zone où la palette est définie sont surlignées en jaune)
Comme indiqué ci-dessus, il n'y a qu'une seule façon d'écrire des données sur VRAM - via les ports. Cela indique la couleur, la colonne, la ligne:
X est écrit sur le port 4, Y sur le port 5, la couleur sur le port 1, après quoi les données sont transférées en écrivant une constante sur le port 0:
; set color (2 bit per pixel) li $00 ; color ($00 = green, $40 = red, $80 = blue, $C0 = background) outs 1 li 104 ; X com outs 4 ; set the row li 61 ; Y com outs 5 ; transfer data to VRAM li $60 outs 0 li $50 outs 0 ; wait for update lis 6 delay: ai $ff bnz delay
Un délai est nécessaire pour que tout puisse être enregistré, sinon le point suivant risque de ne pas être tracé. Dans la version officielle, 4 est toujours ajouté à la colonne et à la ligne (omis pour plus de simplicité)
Remplir tout l'écran de points (en boucle) prend donc environ une seconde. Il est important de noter qu'en plus de la mise à jour d'écran extrêmement lente, il y a aussi le fait qu'il n'y a aucun moyen d'attendre que le faisceau revienne à travers le cadre. En conséquence, même un petit redessin est inévitablement accompagné d'un scintillement.
Maintenant sur la palette. À strictement parler, pour chaque ligne, il existe deux modes - noir et blanc (lorsque l'arrière-plan est noir et le premier plan est uniquement blanc, quel que soit le pixel dessiné) et la couleur.
Dans le mode de couleur de premier plan, il y en a toujours trois - rouge, vert, bleu (rgb). Plus l'une des trois couleurs de fond - gris, bleu clair, vert clair.
Pour définir la palette dans les colonnes 125 et 126, écrivez les valeurs suivantes:
x=125 x=126 palette --------------------------------------------------------------------- 00 00 COLOR: rgb, light green bg 00 ff COLOR: rgb, light blue bg ff 00 COLOR: rgb, gray bg ff ff B/W: www, black bg
Dans les jeux typiques, ils le font généralement: ils définissent d'abord un certain contexte général, pour lequel vous pouvez utiliser la procédure BIOS prête à l'emploi:
li $c6 ; $21 - b/w palette, fill with black. $c6 - color palette, fill with gray lr 3, A pi clrscrn ; clrscrn BIOS call
Ensuite, si nécessaire, faites une bande avec une palette en noir et blanc (par exemple, pour afficher le score du jeu avec des chiffres blancs sur fond noir)
Et puis ils mettent des pixels dans l'une des trois couleurs (si l'arrière-plan est gris, respectivement - r, g, b). En conséquence, il y a bien sûr 8 couleurs, mais pour mettre à un endroit spécifique un point d'une couleur arbitraire est si facile - c'est impossible.
Voici un ensemble d'images qui donnent une idée des couleurs et de leurs combinaisons.
En fait, sur cela, tous les graphiques, en tant que tels, se terminent - tout ce que vous voulez faire se fait en dessinant des pixels, et manuellement. À partir de routines utiles, le BIOS a une sortie de caractères. Cependant, pour des raisons d'économie d'espace, dans la ROM, il n'y a que des images de chiffres et de caractères individuels, de taille 5x8 pixels:
Cependant, la procédure de retrait est utile et peut être utilisée comme suit:
li 25 ; column lr 1,a li 25 ; row lr 2,a li %11000000 ; eg $c0 - green "0" lr 0,a ; a -> r0 pi drawchar ; call subroutine
Dans la version ci-dessus, les deux chiffres supérieurs du registre r0 déterminent la couleur (10 - rouge, 11 - vert, 01 - bleu, 00 - transparent), le reste - le numéro de série du caractère (0 1 2 3 4 5 6 7 8 9 G? T SPACE MX BLOC: - centre || gauche || `), à partir de zéro. Les registres r1 et r2 sont placés, respectivement, une colonne et une ligne.
Une option plus pratique est de ne pas penser aux bits:
li 20 ; x lr 1,a ; a -> r1 li 10 ; y lr 2,a ; a -> r2 li $40 ; char color in bits 6,7: $80 (%10000000) - red, $c0 (%11000000) - green, $40 (%01000000) - blue, $00 (%00000000) - transparent oi 1 ; index of char ( eg 3 for "3" ) lr 0,a ; combined color + char index -> r0 pi drawchar ; call subroutine
Pour avoir une idée de la plate-forme, j'ai écrit une
introduction de 256 octets pour le petit concours d'introduction à
Chaos Constructions'2019 . Rien de spécial, mais faites attention à la raison pour laquelle le changement de palette ligne par ligne est utilisé. Une bande horizontale rampante, pour ainsi dire, met en évidence la ligne qui est en dessous, remplaçant temporairement tout l'arrière-plan par du noir et tous les pixels par du blanc. Comme vous n'avez pas besoin d'écraser les pixels eux-mêmes (et que vous n'avez pas besoin de les restaurer plus tard), vous pouvez créer un tel «rétro-éclairage» très rapidement et sans scintillement.
Le deuxième point concerne les lettres "CC". Étant donné que les lettres «C» ne sont pas dans le BIOS, le chevauchement des lettres GG et le chiffre 1 sont utilisés pour obtenir l'inverse «CC».
Son
Le son est mauvais. Officiellement, il y a trois sons - 120 Hz, 500 Hz et 1 KHz. En fait, obtenir autre chose que des clics et un grincement étouffé est problématique. De plus, ils disent qu'entre les machines PAL et NTSC, ainsi qu'entre les anciennes et les nouvelles versions, le son est également différent. Cependant, pour les jeux typiques - c'est suffisant. Son activé et désactivé via les ports:
li %01000000 ; 1khz beep $40 outs 5 li %10000000 ; 500hz beep $80 outs 5 li %11000000 ; 120hz beep $c0 outs 5 ; some pause clr outs 5 ; turn off sound
Les gens s'amusaient même à jouer de la musique.
Les meilleurs échantillons ressemblent à distance à un PC-Speaker. Certes, il n'y a aucun sens pratique de toute façon - toutes les ressources du processeur vont à la musique, rien de spécial ne peut être fait.
Outils de développement
Actuellement, il existe une
sélection prête à l'emploi des logiciels nécessaires appelés «Development Pack».
Cela inclut l'assembleur DASM, le désassembleur, l'émulateur MESS (avec débogueur). Tout cela fonctionne sans problème au moins sous Windows 7.
Paramètres d'assemblage et de démarrage:
dasm.exe test.asm -f3 -otest.bin messd channelf -cartridge %cartPath%\test.bin -w -effect sharp -r 640x480 -ka
L'émulateur est assez bon, bien que le débogueur soit extrêmement étrange. Je n'ai pas pu configurer la nouvelle version de MAME / MESS tout de suite (j'ai remarqué que la configuration de MAME pour une plate-forme impopulaire qu'elle prend en charge supposément est une tâche non triviale à chaque fois).
L'émulateur suppose que la résolution de la région visible correspond à minx = 5, minY = 5, maxX = 105, maxY = 61
Puisqu'il n'y a aucun plaisir à écrire quelque chose sous l'émulateur sans avoir testé le résultat en direct, j'ai dû résoudre le problème avec l'émulateur ROM. À ma demande,
tnt23 a fabriqué une cartouche spéciale (Alexander Novozhilov a imprimé un étui pour celle-ci) dans laquelle l'EEPROM 28C16A est insérée. En raison des particularités de l'adressage F8, je devais encore acheter une ancienne puce Fairchild 3853 sur eBay. En conséquence, il est devenu possible, en programmant l'EEPROM, de voir à quoi ressemble le code sur une machine en direct.
De plus, le tnt23 a attaché une sortie S-Vidéo du canal F (normalement, il ne pouvait être connecté à un téléviseur via l'entrée d'antenne), ce qui a considérablement amélioré la qualité d'image et la reproduction des couleurs.
Histoire de Fairchild Channel F:
Les ressources