Assembleur 6502 - VCS2600

Cette catégorie traite de développements récents destinés à nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
snsv6502
Messages : 172
Inscription : 12 oct. 2018 21:28
Localisation : Nantes

Re: Assembleur 6502 - VCS2600

Message par snsv6502 »

Beh la page 0, c'est l'ensemble des adresses de $00 à $ff. Comme l'opérande est sur un octet seulement (au lieu de 2 octets pour une adresse 'normale') et que l'opcode correspondant à l'instruction est différent (ce qui permet au 6502 de savoir que l'adresse concernée est sur un octet seulement) , c'est un peu le Speedy Gonzales du 6502 et en plus le code est plus compact puisque ça bouffe un octet de moins :mrgreen:
Le code bidouillé ne sert pas à grand chose sauf à montrer qu'une partie des datas ne sert pas et qu'il y a moyen d'avoir une démarcation 'propre' entre le noir et le ciel en haut en patientant quelques cycles comme un bourrin à coup d'instruction BIT (gourmande en cycles si ma mémoire est bonne, c'est sans filet, pas de doc sous la main... :lol: ).
J'ai l'impression qu'il devrait y avoir 2 'passes' puisque c'est entrelacé et que pour une raison inconnue (moi pas comprendre atari 2600), la deuxième passe ne se fait pas.
Ça va être rigolo demain à potasser 'l'architecture du vcs 2600 pour les nuls' :mrgreen: mais je jetterai un œil avec plaisir, j'ai fini de peaufiner mon apple //e enhanced et je n'ai plus grand chose à bidouiller sous le coude.

[edit] : après avoir lu ton [edit] :mrgreen: t'as tout compris !... je suis sûr que tu as free :lol:
call-151
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Merci de tes explications qui confirment mon analyse !

Cette page est également assez claire au niveau explications.

Pour la partie NTSC et PAL, l'émulateur doit compter les lignes pour savoir en quel mode passer. Pour la question de l'entrelacement on en parle ici :
A little side-track, here. Although I stated that the vertical resolution of a TV image is 625 lines (PAL) and 525 lines (NTSC), television employs another 'trick' called interlacing. Interlacing involves building up an image out of two separate 'frames'—each frame being either the odd scanlines, or the even scanlines of that image. Each frame is displayed every 1/30th of a second (30Hz) for NTSC, or every 1/25th of a second (25Hz) for PAL. By offsetting the vertical position of the start of the first scanline by half a scanline, and due to the persistence of the phosphor coating on the TV, the eye/brain combines these frames displaying alternate lines into a single image of greater vertical resolution than each frame. It's tricky and messy, but a glorious 'hack' solution to the problem of lack of bandwidth in a TV signal.

The upshot of this is that a single FRAME of a TV image is actually only half of the vertical resolution of the image. Thus, a NTSC frame is 525/2 = 262.5 lines deep, and a PAL frame is 625/2 = 312.5 lines deep. The extra .5 of a line is used to indicate to the TV if a frame is the first (even lines) or second (odd lines) of an image. An aside: about a year ago, the #stella community discussed this very aspect of TV images, and if it would be possible for the Atari to exploit this to generate a fully interlaced TV frame—and, in fact, it is possible. So some 25 years after the machine was first released, some clever programmers discovered how to double the resolution of the graphics.

Back to basics, though. We just worked out that a single frame on a TV is 262.5 (NTSC) and 312.5 (PAL) lines deep. And that extra .5 scanline was used to tell the TV if the frame was odd or even. So the actual depth of a single frame is 262 (NTSC) and 312 (PAL) lines. Now, if TV's aren't told that a frame is odd, they don't offset the first scanline by half a scanline's depth—and so, scanlines on successive frames are exactly aligned. We have a non-interlaced image, displayed at 60Hz (NTSC) or 50Hz (PAL). And this is the 'standard' format of an Atari 2600 frame sent to a TV.
De ce que j'analyse, vu que le système n'envoie pas la demi-ligne indiquant qu'on est demi-décalés, on est systématiquement en mode "pair", donc pas d'entrelacement.

Ce qui est logique vis à vis de mes premiers essais (code en PJ) où j’appliquai ligne par ligne les valeurs des registres sans passer par une table, et ça marchait impec !

Donc en résumé je suis pas plus avancé... :roll:

Mais merci pour le sourire :)
smile.png
smile.png (7.99 Kio) Consulté 4122 fois
Pièces jointes
yoruk.zip
(3.75 Kio) Téléchargé 104 fois
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Bon, fin mot de l'histoire, voici l'explication du problème :

Code : Tout sélectionner

PF0Table  ; table 0  
        .byte  #%10000000,
        .byte  #%10000000,
        .byte  #%10000000,
        .byte  #%11000000,
Le problème venait...des virgules ! Dans cette configuration le système attendait deux valeurs par ligne, et il venait donc ajouter des octets vides après chaque ligne. (C'est apparemment plus ou moins un bug)

Du coup il faut :

Code : Tout sélectionner

PF0Table  ; table 0  
        .byte  %10000000
        .byte  %10000000
        .byte  %10000000
        .byte  %11000000
(...)
Un merci aux gens d'AtariAge qui m'ont dépanné ! :)

Suite : ajouter un sprite qui bouge :P
Avatar de l’utilisateur
snsv6502
Messages : 172
Inscription : 12 oct. 2018 21:28
Localisation : Nantes

Re: Assembleur 6502 - VCS2600

Message par snsv6502 »

:lol: c'est surpuissant !
Ça me rappelle un peu le point virgule de la mort en Cobol sur Mini6... il en manquait un et on avait 272000 erreurs de compilation :mrgreen: sauf que là, ça ne génère pas d'erreur et c'est bien plus vicelard.
C'est super d'avoir trouvé, amuse-toi bien.
call-151
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Bon en tâtonnant j'ai réussi à placer un sprite :
spriteOK.png
spriteOK.png (6.91 Kio) Consulté 4066 fois
(que j'ai dessiné moi même :-) )

La philosophie est similaire à l'utilisation du "playfield"; il est en effet nécessaire d'attendre la bonne scanline pour écrire la géométrie du sprite à la ligne qui va bien. Pour la ligne L+1 il faut aller chercher la géométrie L+1 également, et tout pareil pour la couleur. Couleur évidemment uniforme le long de la scanline ! L’utilisation de "tables" comme pour le playfield est à priori très conseillé. Attention à remettre la géométrie du sprite à zéro avant et après lui sous peine d'avoir une grosse bande verticale !

Souci toutefois: mon code est trop lent ! On ne le voit pas directement en regardant l'illustration mais le sprite perturbe la scanline qui est parfois doublée (cf le bord des nuages).

Voici le code utilisé :

Code : Tout sélectionner

; test si X (mon compteur de ligne) est dans l'intervalle n <  x <  m.   n est la position Y de départ du sprite et m = n+8
	txa
	CLC    ; clear carry for add           
	ADC #$FF-m	; make m = $FF
	ADC #m-n+1	; carry set if in range n to m
	BCs SetSprite     ; si oui je passe dans "SetSprite"

	jmp ResetSprite

SetSprite
	;soustraction de X avec n pour avoir une valeur variant de 0 à 7
	txa
        sec ;set carry	
        sbc #n
        tay   ; sockage de cette valeur dans Y

	lda Frame0,y; #$FF ;Frame0,y ;#$FF ; dessine une ligne
        sta GRP0  ; ecriture registre sprite
        
        lda ColorFrame0,y; #$FF ;Frame0,y ;#$FF ; dessine une ligne
        sta COLUP0  ; ecriture registre sprite
                
	jmp Exit

ResetSprite
      lda #$00   ;RAZ pour toutes les lignes ou on a pas de sprite !
      sta GRP0 
              
Exit   
Je n'ai pas compté le nombre de cycles nécessaires à l’exécution de tout cela mais je dois certainement exploser le maximum autorisé pour une ligne. :? Et attention, je n'ai pas encore placé le sprite à la bonne position horizontale ! (il faut compter les cycles !!)

Je suis plus que sûr qu'il est possible de simplifier ce code, mais ce qu'il me manque maintenant c'est une vue globale sur comment structurer efficacement ma boucle d'affichage. Afficher le playfield c'est bon, afficher un sprite tout seul c'est bon, maintenant la difficulté est de mêler les deux de façon intelligente... :P

Je trouve des exemples de code pour faire facilement l'un ou l'autre, mais les deux sont difficilement mélangeables ^^.
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: Assembleur 6502 - VCS2600

Message par 6502man »

C'est déjà pas mal du tout pour un début :)

Après pour la vitesse il faut que les décors soient très simples pour réduire le nombre d'écritures dans les registres ou alors faire des décors plus grossiers :wink:
La machine ne permet pas d'avoir trop de détails car sinon tu vas sauter des lignes d'affichage par rapport au processeur graphique :roll:

Après je me rappelle plus mais je suis pas sûr qu'il faille mettre à zéro GRP0 sur toutes les lignes mais seulement à la fin de la définition d'un sprite ???
A vérifier dans les docs ...

La ou tu vas gagner le plus c'est sur le nombre d'écritures dans les registres graphiques donc il faut faire des décors épurés et simplistes le plus possible .
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Hmmm oui maintenant que tu le dis c'est effectivement pas utile de remettre 50 fois GRP0 à 0... Je vais corriger ça :)


EDIT : Petite question soustraction pour les experts...

J'ai bien compris que l'instruction SBC fonctionne via l'addition du complément à deux, et donc en interne le système effectue une inversion des bits (première opération pour obtenir le complément à 2) et que le bit de "Carry" (retenue ?) doit être à un car il est ajouté à l'opération ( A - M - ~C --> A ) pour terminer le calcul du complément à 2.

Est-il possible d'enchainer les soustractions (SEC SBC $xx SBC $xx) sans remettre le bit à 1, ou existe-il des cas où il peut être remis à zéro ?


Au passage, petite pub pour cette fiche résumé de l'assembleur que je trouve claire et assez complète : https://dwheeler.com/6502/oneelkruns/asm1step.html
Avatar de l’utilisateur
hlide
Messages : 3470
Inscription : 29 nov. 2017 10:23

Re: Assembleur 6502 - VCS2600

Message par hlide »

J'imagine que SBC comme dans n'importe quelle architecture où elle est implémentée permet de soustraire des mots sur N octets en enchaînant plusieurs SBC parce que cette instruction devrait modifier la retenue suite à l'opération et donc de propager la retenue sur l'octet suivant. Mais dans ton cas tu sembles indiquer que tu fais la soustraction sur le même accumulateur : la retenue appliquée par le second SBC $XX dépendra du résultat du premier. Donc si tu veux juste faire des soustractions sans retenue sur un seul octet (l'accumulateur) ben SEC SBC $xx SEC SBC $xx.
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Merci pour tes précisions. Oui voilà je n'ai pas encore regardé les opération sur 16 bits mais on peut effectivement enchainer comme ça. :)
p0ke
Messages : 180
Inscription : 20 mai 2018 20:29

Re: Assembleur 6502 - VCS2600

Message par p0ke »

Salut Falkor,

https://8bitworkshop.com/v3.5.1/?file=e ... atform=vcs est super,
mais je reste un fanatique de stella, sur une seule page tu as a peu près tout pour débugger.

Pour compiler j'utilise Dasm, mais d'autres membres du groupe préfère K65 ou encore L65 ou même C.
L'avantage de dasm c'est qu'il y a beaucoup de resources associées, tracker de musique, exemple etc ...

ça fait un baille que j'ai pas touché à la vcs, mais de mémoire il faut éviter les gros calculs.
Il vaut mieux pré-calculer et déplacer un index ce sera souvent moins coûteux.
Parfois au lieu de faire un saut conditionnel il vaut mieux répéter 10 fois la même ligne, ça évite à avoir à faire un calcul de cycle tortueux !

bref, bienvenu à bord :D

Il y a pas mal de démo atari vcs disponible sur pouet.net, et souvent avec leurs sources.

https://www.pouet.net/prodlist.php?plat ... tari%20VCS
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

Suite des expérimentations...

Mon ressenti est de dire que globalement développer sur la VCS est en théorie peu compliqué : quelques notions d'assembleur suffisent pour remplir les bons registres au bons moments pour dessiner un arrière plan et des sprites. Ensuite, quelques comparaisons avec les registres gérant les joysticks et hop notre personnage bouge. Pour les collisions aucun souci le TIA (le chip graphique) s'occupe de tout, on a juste à interroger les bons registres :)

Là où ça commence à se compliquer c'est quand on veut tout faire en même temps. On arrive alors (si on optimise pas assez son code) à dépasser le nombre de cycles autorisés par ligne, et là l'affichage commence à baver. :(

En pratique, les développeurs utilisaient des noyaux "double ligne" ou en gros chaque ligne était affichée deux fois de façon identique. Perte en résolution sur Y, mais gain de temps.

Même avec ça tout se complique. Les tutos présentant des scènes complètes montent vraiment d'un cran au niveau assembleur, allant jusqu'à utiliser dès les tutos de base des "illégal opcodes" permettant de gratter quelques précieux cycles, au prix d'une complexité de compréhension du code pour les débutants comme moi. :roll:

Un bon intermédiaire est d'utiliser le batari basic : un basic spécifique à la machine avec un compilateur faisant la conversion en assembleur pour gagner en praticité. Ce compilateur est utilisé conjointement avec l'IDE Visual bB qui pour le coup ne m'a pas du tout convaincu (bugs divers...).

Ce basic est articulé autour de noyaux pré-codés permettant de choisir le type de features utilisé. En gros ajouter une fonctionnalité (sprite multicolore, arrière plan "haute résolution"...) va à l'encontre d'une autre (missiles...). Tout est résumé dans ce tableau.

Par contre, une fois qu'on a compris ce système de "pour et contre" et les limitations qui vont avec, coder un jeu va vraiment tout seul. Voyez mon projet en cours :
040520helico.png
040520helico.png (34.05 Kio) Consulté 3967 fois
C'est très primaire comme concept (dégommer les ennemis avec un missile :mrgreen: ) mais ça se programme vraiment facilement. Avec quelques comparaisons on arrive à animer des sprites, gérer de l'aléatoire, le son... J'ai donc ici fait le choix d'avoir un seul joueur multicolore (l'ennemi) et un arrière plan coloré. Si je souhaitais ajouter de la couleur à mon hélico, je n'aurais plus eu le missile... :roll:

Après il est évident que programmer un jeu dont le but consiste à se tirer dessus avec des missiles constitue la base des jeux de cette machine, mais certains jeux codés sont très impressionnants !


EDIT @Poke : nos messages se sont croisés. J'utilise aussi bien DASM offline et l'éditeur en ligne pour l'édition. Ce dernier est plus rapide mais j'ai noté quelques soucis à l'émulation, Stella semble mieux (c'est aussi ce qu'utilise batariBasic). Comme tu l'as souligné, compter le nombre de cycles par opération est d'une grande aide, mais je n'ai pas encore la souplesse d'arriver à remplacer tel bout de code par tel autre ! Ca viendra certainement avec l'expérience... 8). On voit bien dans les exemples des tutos qu'il faut maximiser les calculs (moteur du jeu) dans les zones de "vertical blank" et "overscan" : (là où il n'y a pas de tracé) :
picture.png
picture.png (250.79 Kio) Consulté 3965 fois
Mais la boucle graphique principale (l'affichage proprement dit) reste extrêmement compliquée, même si elle ne consiste qu'à aller chercher les éléments graphiques qui vont bien !
p0ke
Messages : 180
Inscription : 20 mai 2018 20:29

Re: Assembleur 6502 - VCS2600

Message par p0ke »

Oui, le calcul doit se faire dans les v&hblank.
D'ou le "racing the beam".
Joli travail en tout cas, félicitations.
Avatar de l’utilisateur
snsv6502
Messages : 172
Inscription : 12 oct. 2018 21:28
Localisation : Nantes

Re: Assembleur 6502 - VCS2600

Message par snsv6502 »

Eheheh, génial le coup des 'faux opcodes' pour optimiser le nombre de cycles, un vrai truc de furieux cette machine :mrgreen:
En tout cas tu as bien avancé, c'est chouette 8)
call-151
Avatar de l’utilisateur
Falkor
Messages : 1701
Inscription : 28 juin 2010 12:09
Localisation : Cluny, Saône et Loire

Re: Assembleur 6502 - VCS2600

Message par Falkor »

"DCP" est l'une des instructions miracle utilisée. Elle combine une décrémentation et une comparaison. :)

Ajouté une page de titre :
image.thumb.png.410d27ce45301e41b00975a1f087a941.png
image.thumb.png.410d27ce45301e41b00975a1f087a941.png (34.59 Kio) Consulté 3923 fois

J'ai utilisé l'excellent utilitaire JavE pour éditer le titre. Possibilité aussi de l’utiliser pour l'édition des sprites...
Répondre