Logicielsmoto.com

Nous sommes le 28 Mar 2024, 12:15

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 69 messages ]  Aller à la page 1, 2, 3, 4, 5  Suivante
Auteur Message
 Sujet du message: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 01:47 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Il y a quelques temps je suis tombé sur la vidéo de Neotenien au sujet de Slap Fight
phpBB [video]


Comme il le fait remarquer l'affichage est très coloré et pas mal rapide. Aussi j'ai voulu l'étudier pour évaluer sa vitesse de rafraichissement.

Pour ce faire, j'ai mis un point d'arrêt en écriture au milieu de la première ligne écran ($4014) sous DCMOTO et utilisé la fonction de comptage de cycle entre deux arrêts. Je crois qu'il est aussi possible de faire cela sous TEO, mais j'ai fait avec ce que j'avais sous le coude en dépit de quelques surprises qui m'ont aussi pas mal amusées, mais c'est une autre histoire.

J'ai alors observé ceci
  • 1ère écriture au bout de ~103330 cycles (PC=$C0A7 Page 2000 -> forme)
  • 2eme écriture au bout de 579 cycles (PC=$C0D4 Page 000 -> fond)

L'une des deux écritures est la vidéo de forme et l'autre de fond. Le total (environ 104ms) nous donne le temps moyen de rafraichissement de l'ensemble de l'écran à ce moment là du jeu (le tout début, quand il n'y a que le sprite du vaisseau). Cela nous fait environ 9.6fps, c'est pas mal du tout. :bien:

Vous me connaissez, j'ai poussé l'étude un peu plus loin pour voir s'il était possible d'améliorer cela un petit peu. J'ai quelques résultats et plutôt que de tout donner d'un coup, ce qui serait assez indigeste, je vous propose de suivre ici, dans ce fil, pas à pas, mes avancées sur ce jeu.

A plus tard.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 02:06 
Hors ligne

Inscription: 06 Avr 2010, 01:59
Messages: 478
Je trouve ce jeu est très jouable, avec un scrolling pas mal du tout par rapport la surface de scroll full graphisme. intéressant de décortiquer ça. :bien:

_________________
Image


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 06:34 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 433
Localisation: Var
Je vais suivre cette analyse avec attention car j’ai bcp joué a ce jeu (difficile), et je suis curieux de savoir ce qu’il y a « derrière ».
Très bonne idée Sam :bien:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 12:31 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Ok allons-y:
Samuel Devulder a écrit:
J'ai alors observé ceci
  • 1ère écriture au bout de ~103330 cycles (PC=$C0A7 Page 2000 -> forme)

Le compteur programme ($C0A7) nous indique où se déroule la première partie du rafraichissement écran.
Code:
C08F ECA4       LDD    ,Y                  5
C091 EDC4       STD    ,U                  5
C093 EC22       LDD    $02,Y               6
C095 ED42       STD    $02,U               6
C097 EC24       LDD    $04,Y               6
C099 ED44       STD    $04,U               6
C09B EC26       LDD    $06,Y               6
C09D ED46       STD    $06,U               6
C09F EC28       LDD    $08,Y               6
C0A1 ED48       STD    $08,U               6
C0A3 EC2A       LDD    $0A,Y               6
C0A5 ED4A       STD    $0A,U               6
C0A7 EC2C       LDD    $0C,Y               6 <==
C0A9 ED4C       STD    $0C,U               6
C0AB EC2E       LDD    $0E,Y               6
C0AD ED4E       STD    $0E,U               6
C0AF ECA810     LDD    $10,Y               6
C0B2 EDC810     STD    $10,U               6
C0B5 ECA812     LDD    $12,Y               6
C0B8 EDC812     STD    $12,U               6
C0BB 39         RTS                        5
Cela recopie $14 (20) octets de Y ($7912) à U ($400A) via D. Vingt octets c'est exactement une ligne du terrain jeu, et cela se fait en 3*5+18*6=123 cycles.

Si on regarde où est utilisé cette recopie on tombe sur ceci:
Code:
C06B 3440       PSHS   U                   7
C06D 8604       LDA    #$04                2 (*)
C06F 3402       PSHS   A                   6 (*)
C071 7AC024     DEC    $C024               7
C074 2D0F       BLT    $C085               3
C076 BDC08F     JSR    $C08F               8
C079 33C828     LEAU   $28,U               5
C07C 6AE4       DEC    ,S                  6 (*)
C07E 26F1       BNE    $C071               3 (*)
C080 3502       PULS   A                   6
C082 3540       PULS   U                   7
C084 39         RTS                        5
C085 860F       LDA    #$0F                2
C087 B7C024     STA    $C024               5
C08A 31A818     LEAY   $18,Y               5
C08D 20E7       BRA    $C076               3
On peut en déduire que le bout de code plus haut est appelé 4 fois dans le rang (*) et qu'à chaque tour on décrémente le compteur $C024 qui va de 15 à 0, et qui fait avancer Y de $18 (24) toutes les 16 lignes.

Cela correspond à ce qu'on voit à l'écran de la structure de l'espace de jeu: les couleurs sont identiques durant 16 lignes, et le scroll avance par "petit pas" de 4 lignes. L'affichage met à jour 4 lignes fond puis 4 lignes de forme histoire ne réduire le nombre d'appel aux routines de commutation $E7C3.

Le temps entre les appels à $C06B varie entre 1269 et 1284 cycles dont entre 621 et 663 cycles sont utilisés pour mettre à jour les 4 lignes de fond.

Le temps n'est pas le même suivant que le compteur $C024 tombe à -1 durant l'appel ou pas. C'est d'ailleurs une complication de cet algorithme le fait qu'il faille tester $C024 pour chaque ligne alors que tant qu'on est entre 4 et 15, c'est à dire 75% du temps on sait qu'on a pas à modifier Y durant les 4 lignes qui suivent. :voyons:

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 12:57 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Samuel Devulder a écrit:
Le temps n'est pas le même suivant que le compteur $C024 tombe à -1 durant l'appel ou pas. C'est d'ailleurs une complication de cet algorithme le fait qu'il faille tester $C024 pour chaque ligne alors que tant qu'on est entre 4 et 15, c'est à dire 75% du temps, on sait qu'on a pas à modifier Y durant les 4 lignes qui suivent. :voyons:
Voyons ce que donne cette version:
Code:
C06B 3450       PSHS   U,X                 9
C06D 33C814     LEAU   $14,U               5
C070 B6C024     LDA    $C024               5 (**)
C073 8004       SUBA   #$04                2 (**)
C075 2C0A       BGE    $C081               3 (**)

C077 8D12       BSR    $C08B               7 (*)
C079 8D10       BSR    $C08B               7 (*)
C07B 8D0E       BSR    $C08B               7 (*)
C07D 8D0C       BSR    $C08B               7 (*)
C07F 35D0       PULS   X,U,PC             11

C081 8D12       BSR    $C095               7 (+)
C083 8D13       BSR    $C098               7 (+)
C085 8D11       BSR    $C098               7 (+)
C087 8D0F       BSR    $C098               7 (+)
C089 35D0       PULS   X,U,PC             11

C08B 7AC024     DEC    $C024               7
C08E 2C08       BGE    $C098               3
C090 31A818     LEAY   $18,Y               5
C093 860F       LDA    #$0F                2
C095 B7C024     STA    $C024               5 (**)

C098 ECA810     LDD    $10,Y               6
C09B AEA812     LDX    $12,Y               6
C09E 3616       PSHU   X,B,A               9
C0A0 EC2C       LDD    $0C,Y               6
C0A2 AE2E       LDX    $0E,Y               6
C0A4 3616       PSHU   X,B,A               9
C0A6 EC28       LDD    $08,Y               6
C0A8 AE2A       LDX    $0A,Y               6
C0AA 3616       PSHU   X,B,A               9
C0AC EC24       LDD    $04,Y               6
C0AE AE26       LDX    $06,Y               6
C0B0 3616       PSHU   X,B,A               9
C0B2 ECA4       LDD    ,Y                  5
C0B4 AE22       LDX    $02,Y               6
C0B6 3616       PSHU   X,B,A               9
C0B8 33C83C     LEAU   $3C,U               5
C0BB 39         RTS                        5
Bon déjà on voit qu'elle occupe la même zone mémoire. :bien:

Ensuite la recopie ne se fait plus seulement sur D
Code:
C097 EC24       LDD    $04,Y               6
C099 ED44       STD    $04,U               6
C09B EC26       LDD    $06,Y               6
C09D ED46       STD    $06,U               6
mais sur D et X avec un PUSHU
Code:
C098 ECA810     LDD    $04,Y               6
C09B AEA812     LDX    $06,Y               6
C09E 3616       PSHU   X,B,A               9
On recopie 4 octets non plus en 24 cycles, mais en 21 cycles. Ca fait déjà 3 cycles de gagné tous les 4 octets, soit 15 cycles par ligne sur les 123 d'origine. C'est déjà ca de gagné. :oui:

Ensuite cet algo est essentiellement une version "déroulée" de la boucle "DEC ,S" ci-dessus, avec plein de "BSR XXXX" à la place (voir les (*) et (+)).

Cependant elle détecte le cas général (**) où il ne faut pas faire avancer Y quelque part au milieu. L'algo copie alors les 4 lignes d'un coup (+) sans faire de "DEC $C024", lesquels sont assez couteux pour pas grand chose puisque le test de négativité qui suit dans l'algo d'origine est forcément à faux. Ici on gagne du temps en étant malin (PSHU) et en ne faisant rien qui soit inutile (**). :sol:

Samuel Devulder a écrit:
Le temps entre les appels à $C06B varie entre 1269 et 1284 cycles dont entre 621 et 663 cycles sont utilisés pour mettre à jour les 4 lignes de fond.
Avec la version présentée dans ce message le temps entre 2 appels $C06B tombe entre 1140 et 1187 cycles. On est donc environ entre 7 et 10% plus rapide sur cette partie, et au niveau global le temps entre 2 rafraichissements écran se fait à présent en 98ms au lieu de 104ms, soit autour de 5% plus rapidement, et on passe au dessus des 10 fps psychologiques ! :bien: On les dépasse de peu et c'est pas très visible, certes, mais c'est déjà ca pour la partie couleur/fond. :)


Fichiers joints:
Commentaire: Patch à charger entre $C06B et $C0BB
C06B_C0BB.zip [1.64 Kio]
Téléchargé 356 fois

_________________
Good morning, that's a nice Tnetennba
Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 13:48 
Hors ligne

Inscription: 06 Avr 2010, 01:59
Messages: 478
Je monte une vidéo que je vais poster dans qque minute, on voit bien la différence de vitesse entre normal et patché ...

[EDIT]
Image
https://oxustudio.com/to8/forum/slapfight/slapFight-20210515.mp4

_________________
Image


Dernière édition par adnz le 15 Mai 2021, 14:10, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 13:50 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 433
Localisation: Var
Bien joué ! Avec pour contrainte de réutiliser le même espace mémoire, un gain de 5% sur cette partie c'est déjà pas mal.
J'ai hâte de voir la suite ...

Du coup je me suis refait une petite partie avec cette version patchée ...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 14:59 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
adnz a écrit:
Je monte une vidéo que je vais poster dans qque minute, on voit bien la différence de vitesse entre normal et patché ...
Bentoc a écrit:
J'ai hâte de voir la suite ...
Si on gagne 5% en ne touchant qu'à la gestion de la mémoire vidéo Fond, on peut monter à combien si on optimise la gestion de mémoire forme ?

Réponse plus tard... (je la connais, et même au delà, mais ménageons le suspens :p )

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 15:13 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 433
Localisation: Var
Tout dépend de l'algo, et du talent du codeur :)
Du coup je suis plein d'espoir !!!!


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 15 Mai 2021, 22:41 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Samuel Devulder a écrit:
on peut monter à combien si on optimise la gestion de mémoire forme ?
Ben voyons alors. :voyons: On avait
Citation:
  • 2eme écriture... (PC=$C0D4 Page 000 -> fond)
Cela nous amène à ce bout de code
Code:
C0BC EC84       LDD    ,X                  5
C0BE EDC4       STD    ,U                  5
C0C0 EC02       LDD    $02,X               6
C0C2 ED42       STD    $02,U               6
C0C4 EC04       LDD    $04,X               6
C0C6 ED44       STD    $04,U               6
C0C8 EC06       LDD    $06,X               6
C0CA ED46       STD    $06,U               6
C0CC EC08       LDD    $08,X               6
C0CE ED48       STD    $08,U               6
C0D0 EC0A       LDD    $0A,X               6
C0D2 ED4A       STD    $0A,U               6
C0D4 EC0C       LDD    $0C,X               6 <== ICI
C0D6 ED4C       STD    $0C,U               6
C0D8 EC0E       LDD    $0E,X               6
C0DA ED4E       STD    $0E,U               6
C0DC EC8810     LDD    $10,X               6
C0DF EDC810     STD    $10,U               6
C0E2 EC8812     LDD    $12,X               6
C0E5 EDC812     STD    $12,U               6

C0E8 EC8818     LDD    $18,X               6
C0EB EDC828     STD    $28,U               6
C0EE EC881A     LDD    $1A,X               6
C0F1 EDC82A     STD    $2A,U               6
C0F4 EC881C     LDD    $1C,X               6
C0F7 EDC82C     STD    $2C,U               6
C0FA EC881E     LDD    $1E,X               6
C0FD EDC82E     STD    $2E,U               6
C100 EC8820     LDD    $20,X               6
C103 EDC830     STD    $30,U               6
C106 EC8822     LDD    $22,X               6
C109 EDC832     STD    $32,U               6
C10C EC8824     LDD    $24,X               6
C10F EDC834     STD    $34,U               6
C112 EC8826     LDD    $26,X               6
C115 EDC836     STD    $36,U               6
C118 EC8828     LDD    $28,X               6
C11B EDC838     STD    $38,U               6
C11E EC882A     LDD    $2A,X               6
C121 EDC83A     STD    $3A,U               6

C124 EC8830     LDD    $30,X               6
C127 EDC850     STD    $50,U               6
C12A EC8832     LDD    $32,X               6
C12D EDC852     STD    $52,U               6
C130 EC8834     LDD    $34,X               6
C133 EDC854     STD    $54,U               6
C136 EC8836     LDD    $36,X               6
C139 EDC856     STD    $56,U               6
C13C EC8838     LDD    $38,X               6
C13F EDC858     STD    $58,U               6
C142 EC883A     LDD    $3A,X               6
C145 EDC85A     STD    $5A,U               6
C148 EC883C     LDD    $3C,X               6
C14B EDC85C     STD    $5C,U               6
C14E EC883E     LDD    $3E,X               6
C151 EDC85E     STD    $5E,U               6
C154 EC8840     LDD    $40,X               6
C157 EDC860     STD    $60,U               6
C15A EC8842     LDD    $42,X               6
C15D EDC862     STD    $62,U               6

C160 EC8848     LDD    $48,X               6
C163 EDC878     STD    $78,U               6
C166 EC884A     LDD    $4A,X               6
C169 EDC87A     STD    $7A,U               6
C16C EC884C     LDD    $4C,X               6
C16F EDC87C     STD    $7C,U               6
C172 EC884E     LDD    $4E,X               6
C175 EDC87E     STD    $7E,U               6
C178 EC8850     LDD    $50,X               6
C17B EDC90080   STD    $0080,U             9
C17F EC8852     LDD    $52,X               6
C182 EDC90082   STD    $0082,U             9
C186 EC8854     LDD    $54,X               6
C189 EDC90084   STD    $0084,U             9
C18D EC8856     LDD    $56,X               6
C190 EDC90086   STD    $0086,U             9
C194 EC8858     LDD    $58,X               6
C197 EDC90088   STD    $0088,U             9
C19B EC885A     LDD    $5A,X               6
C19E EDC9008A   STD    $008A,U             9
C1A2 39         RTS                        5
Bon on voit tout de suite ( :beuh: humm.. enfin si vous êtes des aliens, sinon croyez moi sur parole) que ce code est la répétition de 4 fois la même partie qui recopie 20 octets entre X et U via le registre D. L'ensemble se fait en 496 cycles ce qui est assez rapide (en moyenne 6.2 cycles par octet recopié). Cependant, ma grande expérience de codeur génial (NDLR: :evil: ca va les chevilles ?), heu mon petit doigt me dit que c'est peut-être sub-optimal car cela n'utilise pas les instructions de pile qui sont les plus rapide pour lire/écrire des octets en mémoire sur mc6809.

Sous le debugger on trouve que les drapeaux I et F du CC sont positionnés tout le long de cette routine, ce qui signifie qu'on ne sera pas soumis à l'utilisation de la pile par les interruptions en ce point là du code. On peut donc user U et "abuser" de S (void les (!) dans le code) pour faire des copies rapides. C'est ce que je vous propose dans le code suivant:
Code:
C0BC 3478       PSHS   U,Y,X,DP           12 Sauvegardes regs utilisés
C0BE 10FFC117   STS    $C117               7 (!) Sauvegarde de S pour la sortie
C0C2 3284       LEAS   ,X                  4 Plus rapide que TFR X,S.
C0C4 3347       LEAU   $07,U               5 U va marcher "en descendant", donc il faut pré-avancer de 7 places

C0C6 353E       PULS   A,B,DP,X,Y         12 Lecture rapide de 7 octets
C0C8 363E       PSHU   Y,X,DP,B,A         12 Ecriture rapide des 7 octets
C0CA 334E       LEAU   $0E,U               5 On avance aux 7 octets suivants (notez le $0E=7*2)
C0CC 353E       PULS   A,B,DP,X,Y         12 Lecture...
C0CE 363E       PSHU   Y,X,DP,B,A         12 Ecriture de 7 octets
C0D0 334D       LEAU   $0D,U               5 Avance de 7+6 octets
C0D2 3536       PULS   A,B,X,Y            11 Lecture...
C0D4 3636       PSHU   Y,X,B,A            11 Ecriture de 6 octets (7+7+6 = 20)
C0D6 3264       LEAS   $04,S               5 Avance les entrées à la ligne suivante
C0D8 33C821     LEAU   $21,U               5 Avance le pointeur écran à la ligne suivante

C0DB 353E       PULS   A,B,DP,X,Y         12
C0DD 363E       PSHU   Y,X,DP,B,A         12
C0DF 334E       LEAU   $0E,U               5
C0E1 353E       PULS   A,B,DP,X,Y         12
C0E3 363E       PSHU   Y,X,DP,B,A         12
C0E5 334D       LEAU   $0D,U               5
C0E7 3536       PULS   A,B,X,Y            11
C0E9 3636       PSHU   Y,X,B,A            11
C0EB 3264       LEAS   $04,S               5
C0ED 33C821     LEAU   $21,U               5

C0F0 353E       PULS   A,B,DP,X,Y         12
C0F2 363E       PSHU   Y,X,DP,B,A         12
C0F4 334E       LEAU   $0E,U               5
C0F6 353E       PULS   A,B,DP,X,Y         12
C0F8 363E       PSHU   Y,X,DP,B,A         12
C0FA 334D       LEAU   $0D,U               5
C0FC 3536       PULS   A,B,X,Y            11
C0FE 3636       PSHU   Y,X,B,A            11
C100 3264       LEAS   $04,S               5
C102 33C821     LEAU   $21,U               5

C105 353E       PULS   A,B,DP,X,Y         12
C107 363E       PSHU   Y,X,DP,B,A         12
C109 334E       LEAU   $0E,U               5
C10B 353E       PULS   A,B,DP,X,Y         12
C10D 363E       PSHU   Y,X,DP,B,A         12
C10F 334D       LEAU   $0D,U               5
C111 3536       PULS   A,B,X,Y            11
C113 3636       PSHU   Y,X,B,A            11

C115 10CEBC59   LDS    #$BC59              4 (!) Recuperation du S initial
C119 35F8       PULS   DP,X,Y,U,PC        14 Récupération de tous les registres modifiés
Cette version ne fait pas seulement qu'abuser de S, mais aussi du registre DP (direct-page) qui nous permet de lire ou écrire 7 octets avec une seule instruction de pile (12 cycles chaque) soit une belle moyenne de 4.1 cycles/octets-recopiés au lieu des 6.2 précédents. La recopie d'une ligne passe ainsi de 20 instructions à seulement 10 qui sont déroulées 4 fois pour s'épargner le temps des couples BSR+RTS (4*(7+5)=48 cycles, soit le temps de recopier 1/2 ligne) et surtout parce qu'on a de la place (le code d'origine est énorme avec 230 octets).

Le tout est au final plus court de 136 octets (60%) que le code d'origine et tourne en 396 cycles au lieu de 496, soit ~20% plus rapide. Globalement le rafraichissement est tombé à 464+93501=94 ms au lieu de 104ms. Donc 10% de gain après avoir optimisé la copie de la ram vidéo fond et forme (5% avec le fond, 5% avec la forme). C'est logique mais pas mal ! :bien:

On remarque aussi que ce code est juste celui qui suit notre patch précédent. Aussi on peut l'étendre pour patcher ces deux là d'un coup.
Fichier(s) joint(s):
Commentaire: Patch combiné à appliquer entre $C06B et $C11A
C06B_C11A.zip [2.16 Kio]
Téléchargé 350 fois
A noter:
  • il faut patcher le jeu quand il est hors du code devant être patché. Le plus simple pour faire cela est de mettre un point d'arrêt à l'entrée du jeu ($BE8C) où l'on voit que les flags d'interruptions sont désactivés :sol:
    Code:
    BE8C 1A50       ORCC   #$50                3
    BE8E 10CEBC65   LDS    #$BC65              4
  • La copie des lignes "fond" se fait en 109 cycles, et celles de "forme" en 90 cycles. Ne pourrait-on pas faire marcher un peu plus vite la 1ère en utilisant les 136 octets gagnés ?

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 16 Mai 2021, 06:39 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 433
Localisation: Var
Samuel Devulder a écrit:
Ne pourrait-on pas faire marcher un peu plus vite la 1ère en utilisant les 136 octets gagnés ?


:oui: :good:

Avec toute cette place libérée ça vaut le coup d'essayer !


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 16 Mai 2021, 07:15 
Hors ligne

Inscription: 13 Juin 2005, 21:50
Messages: 290
Localisation: Planete Zorg (31)
Je pense qu'en "abusant" aussi de S et en se débarrassant des BSR (puisque on a de la place) on pourrait gagner des cycles :tourne:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 16 Mai 2021, 17:05 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
La boucle principale d'affichage est celle-ci:
Code:
C028 CE400A     LDU    #$400A              3 <= pointeur ram vidéo
C02B 108E7912   LDY    #$7912              4 <= pointeur ram espace de jeu interne
C02F B6C023     LDA    $C023               5
C032 8110       CMPA   #$10                2
C034 2C2C       BGE    $C062               3
C036 B7C023     STA    $C023               5
C039 B7C024     STA    $C024               5
C03C 862C       LDA    #$2C                2  44 fois 4 lignes
C03E 3402       PSHS   A                   6   
C040 BDC009     JSR    $C009               8  <-+  FORME
C043 BDC0BC     JSR    $C0BC               8    |  Copie 4 ligne forme
C046 BDC016     JSR    $C016               8    |  FOND
C049 BDC06B     JSR    $C06B               8    |  4 lignes fond
C04C 308860     LEAX   $60,X               5    |
C04F 33C900A0   LEAU   $00A0,U             8    |
C053 6AE4       DEC    ,S                  6    |
C055 1026FFE7   LBNE   $C040               6/5 -+  Pourquoi pas BNE qui est plus court et rapide ?
C059 3502       PULS   A                   6       LEAS 1,S est plus rapide !
C05B 7CC023     INC    $C023               7 Beurk INC est lent..
C05E 7CC023     INC    $C023               7 LDA #2 / ADDA / STA fait gagner 2 cycles
C061 39         RTS                        5
C062 7FC023     CLR    $C023               7
C065 31A818     LEAY   $18,Y               5
C068 16FFCE     LBRA   $C039               5

C009 3402       PSHS   A                   6
C00B B6E7C3     LDA    $E7C3               5
C00E 8A01       ORA    #$01                2
C010 B7E7C3     STA    $E7C3               5
C013 3502       PULS   A                   6 <=== PULS A,PC est plus rapide
C015 39         RTS                        5

C016 3402       PSHS   A                   6
C018 B6E7C3     LDA    $E7C3               5
C01B 84FE       ANDA   #$FE                2
C01D B7E7C3     STA    $E7C3               5
C020 3502       PULS   A                   6 <== PULS A,PC est plus rapide
C022 39         RTS                        5
Comme on peut le voir à mes commentaires à droite, on se dit que c'est pas optimal tout ca.

Déjà les routines FORME/FOND en $C009 et $C016 sont lentes (on peu fusionner PULS A et RTS en un seul PULS A,PC et gagner 3 cycles par appel), mais aussi en cours de jeux il suffit de faire INC/DEC $E7C3 pour passer rapidement de forme à fond en s'épargnant JSR/RTS. C'est bien plus rapide ! :love:

Aussi je propose le code suivant dans un premier temps qui est plus compact et me semble plus rapide
Code:
    ORG     $C028
    BSR     $C016
    LDU     #$400A
    LDY     #$7912
    LDA     $C023
    LDB     $C023 <== LDB est plus rapide que TFR A,B
    CMPA    #16
    BMI     L1
    LEAY    $18,Y
    CLRA
L1  STD     $C023 <== écriture $C023/$C024 en une fois
    LDA     #$2C
    STA     ,-S
L2  INC     $E7C3
    BSR     $C0BC
    DEC     $E7C3
    BSR     $C06B
    LEAX    $60,X
    LEAU    $00A0,U
    DEC     ,S
    BNE     L2
    LDA     #2
    ADDA    $C023
    STA     $C023
    PULS    A,PC

Mais heuu.. :voyons: attendez, il y a pas mal de $C0XX partout dans ce code qui est juste avant le patch $C06B précédent en plus. Si on utilisait DP on gagnerait pas mal de cycles et de place dans celui-ci, mais dans tous les autres PATCHs aussi. Oh punaise!!! :coolfuck:
Code:
C028 CC2CC0     LDD    #$2CC0              3
C02B 340A       PSHS   DP,A                7
C02D 1F9B       TFR    B,DP                6
C02F F6E7C3     LDB    $E7C3               5
C032 C4FE       ANDB   #$FE                2
C034 F7E7C3     STB    $E7C3               5
C037 CE400A     LDU    #$400A              3
C03A 108E7912   LDY    #$7912              4
C03E 9623       LDA    <$23                4
C040 D623       LDB    <$23                4
C042 8110       CMPA   #$10                2
C044 2B04       BMI    $C04A               3
C046 31A818     LEAY   $18,Y               5
C049 4F         CLRA                       2
C04A DD23       STD    <$23                5
C04C 7CE7C3     INC    $E7C3               7
C04F 8D6B       BSR    $C0BC               7
C051 7AE7C3     DEC    $E7C3               7
C054 8D15       BSR    $C06B               7
C056 308860     LEAX   $60,X               5
C059 33C900A0   LEAU   $00A0,U             8
C05D 6AE4       DEC    ,S                  6
C05F 26EB       BNE    $C04C               3
C061 8602       LDA    #$02                2
C063 9B23       ADDA   <$23                4
C065 9723       STA    <$23                4
C067 358A       PULS   A,DP,PC             9

C06B 3450       PSHS   U,X                 9
C06D 33C814     LEAU   $14,U               5
C070 9624       LDA    <$24                4
C072 8004       SUBA   #$04                2
C074 2C0A       BGE    $C080               3
C076 8D12       BSR    $C08A               7
C078 8D10       BSR    $C08A               7
C07A 8D0E       BSR    $C08A               7
C07C 8D0C       BSR    $C08A               7
C07E 35D0       PULS   X,U,PC             11
C080 8D11       BSR    $C093               7
C082 8D11       BSR    $C095               7
C084 8D0F       BSR    $C095               7
C086 8D0D       BSR    $C095               7
C088 35D0       PULS   X,U,PC             11
C08A 0A24       DEC    <$24                6
C08C 2C07       BGE    $C095               3
C08E 31A818     LEAY   $18,Y               5
C091 860F       LDA    #$0F                2
C093 9724       STA    <$24                4
C095 ECA810     LDD    $10,Y               6
C098 AEA812     LDX    $12,Y               6
C09B 3616       PSHU   X,B,A               9
C09D EC2C       LDD    $0C,Y               6
C09F AE2E       LDX    $0E,Y               6
C0A1 3616       PSHU   X,B,A               9
C0A3 EC28       LDD    $08,Y               6
C0A5 AE2A       LDX    $0A,Y               6
C0A7 3616       PSHU   X,B,A               9
C0A9 EC24       LDD    $04,Y               6
C0AB AE26       LDX    $06,Y               6
C0AD 3616       PSHU   X,B,A               9
C0AF ECA4       LDD    ,Y                  5
C0B1 AE22       LDX    $02,Y               6
C0B3 3616       PSHU   X,B,A               9
C0B5 33C83C     LEAU   $3C,U               5
C0B8 39         RTS                        5

C0BC 3478       PSHS   U,Y,X,DP           12
C0BE 10EF8C55   STS    $C117,PCR           7
C0C2 3284       LEAS   ,X                  4
C0C4 3347       LEAU   $07,U               5
C0C6 353E       PULS   A,B,DP,X,Y         12
C0C8 363E       PSHU   Y,X,DP,B,A         12
C0CA 334E       LEAU   $0E,U               5
C0CC 353E       PULS   A,B,DP,X,Y         12
C0CE 363E       PSHU   Y,X,DP,B,A         12
C0D0 334D       LEAU   $0D,U               5
C0D2 3536       PULS   A,B,X,Y            11
C0D4 3636       PSHU   Y,X,B,A            11
C0D6 3264       LEAS   $04,S               5
C0D8 33C821     LEAU   $21,U               5
C0DB 353E       PULS   A,B,DP,X,Y         12
C0DD 363E       PSHU   Y,X,DP,B,A         12
C0DF 334E       LEAU   $0E,U               5
C0E1 353E       PULS   A,B,DP,X,Y         12
C0E3 363E       PSHU   Y,X,DP,B,A         12
C0E5 334D       LEAU   $0D,U               5
C0E7 3536       PULS   A,B,X,Y            11
C0E9 3636       PSHU   Y,X,B,A            11
C0EB 3264       LEAS   $04,S               5
C0ED 33C821     LEAU   $21,U               5
C0F0 353E       PULS   A,B,DP,X,Y         12
C0F2 363E       PSHU   Y,X,DP,B,A         12
C0F4 334E       LEAU   $0E,U               5
C0F6 353E       PULS   A,B,DP,X,Y         12
C0F8 363E       PSHU   Y,X,DP,B,A         12
C0FA 334D       LEAU   $0D,U               5
C0FC 3536       PULS   A,B,X,Y            11
C0FE 3636       PSHU   Y,X,B,A            11
C100 3264       LEAS   $04,S               5
C102 33C821     LEAU   $21,U               5
C105 353E       PULS   A,B,DP,X,Y         12
C107 363E       PSHU   Y,X,DP,B,A         12
C109 334E       LEAU   $0E,U               5
C10B 353E       PULS   A,B,DP,X,Y         12
C10D 363E       PSHU   Y,X,DP,B,A         12
C10F 334D       LEAU   $0D,U               5
C111 3536       PULS   A,B,X,Y            11
C113 3636       PSHU   Y,X,B,A            11
C115 10CE0000   LDS    #$0000              4
C119 35F8       PULS   DP,X,Y,U,PC        14

Si on l'applique, un refresh de l'écran se produit tous les 426+90560 = 91ms au lieu des 104ms initiaux. Bref on va 12% plus vite rien qu'en changeant 243 petits octets dans le jeu!

Ah zut! le gain n'est pas extraordinaire :L mais c'est logique car finalement ce code là n'est appelé que 10 fois par secondes max. Aussi même si je gagne 2000 cycles dedans, ce qui semble beaucoup, cela ne change la vitesse d'affichage que de 10 * 2000 = 20ms/secondes (2%). Si on veut gagner beaucoup il faut avant tout optimiser les trucs très fréquents. On a vu la recopie de ligne fond/forme... mais il y a tout l'aspect "gestion des sprites" et "construction de l'écran caché" qui doit aussi faire plein de trucs répétitifs pas forcément optimisés.... Tâchons de trouver où ils se cachent.. :cyp:


Fichiers joints:
Commentaire: Patch à appliquer entre $C028 et $C11A
C028_C11A.zip [2.94 Kio]
Téléchargé 377 fois

_________________
Good morning, that's a nice Tnetennba
Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 16 Mai 2021, 17:24 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 433
Localisation: Var
Bravo !
On voit vraiment la différence dans le jeu.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: [Etude] Slap Fight
MessagePosté: 16 Mai 2021, 18:18 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Samuel Devulder a écrit:
Tâchons de trouver où ils se cachent.. :cyp:
Une façon de trouver cela est de faire de l'échantillonnage. On laisse le jeu tourner, puis on lance le débuggeur au pif plein de fois et on note le compteur program à cet instant. On fait ca vraiment plein de fois, et on fini par trouver une zone dans laquelle, statistiquement, le compteur programme est souvent. Et cette zone là peut être un bon candidat à l'optimisation.

J'ai évidemment fait cela et suis tombé sur le code suivant entre $BF35 et $BFA5 (112 octets), que je coupe avec quelques remarques:
Code:
BF35 3450       PSHS   U,X                 9
BF37 3404       PSHS   B                   6
C'est étrange de faire 2 PSHS ici
Code:
BF39 CEA410     LDU    #$A410              3
BF3C 8620       LDA    #$20                2
BF3E 3D         MUL                       11
BF3F 33CB       LEAU   D,U                 8
(1) Ce LEAU en 8 cycles me semble couteux. Ne serait-il pas plus efficace de travailler sur l'accumulateur : ADD 3,S (car U vient d'être pushé sur la pile un peu plus haut) ? Hum.. peut être pas car il faudrait faire ensuite un TFR D,U qui à lui seul coute aussi 6 cycles, et est donc à peine plus rapide que le LEAU.. bon continuons...
Code:
BF41 ECC1       LDD    ,U++                8
BF43 ED84       STD    ,X                  5
BF45 ECC1       LDD    ,U++                8
PULS D est plus rapide !
Code:
BF47 ED8818     STD    $18,X               6
BF4A ECC1       LDD    ,U++                8
BF4C ED8830     STD    $30,X               6

BF4F ECC1       LDD    ,U++                8
BF51 ED8848     STD    $48,X               6
BF54 ECC1       LDD    ,U++                8
BF56 ED8860     STD    $60,X               6
BF59 ECC1       LDD    ,U++                8
BF5B ED8878     STD    $78,X               6
BF5E ECC1       LDD    ,U++                8
BF60 30890090   LEAX   $0090,X             8
(2) Ouch l'offset 16 bits ($0090) est couteux ! Or si on se débrouille bien on peut éviter de faire un saut > 127 en déplaçant le LEAX plus tôt. En outre si on utilise des offsets négatifs, on peut aller de -$78 à +$78 et donc on peut s'épargner ce LEAX intermédiaire je pense.
Code:
BF64 ED84       STD    ,X                  5
BF66 ECC1       LDD    ,U++                8
BF68 ED8818     STD    $18,X               6
BF6B ECC1       LDD    ,U++                8
BF6D ED8830     STD    $30,X               6

BF70 ECC1       LDD    ,U++                8
BF72 ED8848     STD    $48,X               6
BF75 ECC1       LDD    ,U++                8
BF77 ED8860     STD    $60,X               6
BF7A ECC1       LDD    ,U++                8
BF7C ED8878     STD    $78,X               6

BF7F ECC1       LDD    ,U++                8
BF81 30890090   LEAX   $0090,X             8
BF85 ED84       STD    ,X                  5
BF87 ECC1       LDD    ,U++                8
BF89 ED8818     STD    $18,X               6
BF8C ECC1       LDD    ,U++                8
BF8E ED8830     STD    $30,X               6
(3) Ok ici c'est du code de recopie classique de 6 octets déroulé à plat dans le code. C'est typiquement là qu'on peut tenter une optimisation via les opérations de pile
Code:
BF91 ECC1       LDD    ,U++                8
Plus loin U n'est plus utilisé, le "++" ne sert à rien !
Code:
BF93 ED8848     STD    $48,X               6
BF96 3504       PULS   B                   6
BF98 CEB310     LDU    #$B310              3
BF9B A6C5       LDA    B,U                 5
BF9D 1F89       TFR    A,B                 6
(4) TFR A,B est plus lent que "LDB B,U"
Code:
BF9F EDA1       STD    ,Y++                8
BFA1 3550       PULS   X,U                 9
BFA3 3002       LEAX   $02,X               5
BFA5 39         RTS                        5
Hum, ici je ferais le LEAX tout au début en décalant le X en début de code de deux places. Ainsi le PULS X,U nous donnerait un X déjà incrémenté de 2. De plus on peut fusionner ce PULS au RTS.

Bref, vu comme ca ce code semble s'occuper de la recopie des tuiles de fond d'écran (il n'y a pas de masque and/or qu'on aurait dans les sprites.) Essayons de voir si je peux le recréer "à ma sauce" en tenant compte des remarque ci-dessus.
Code:
      5        BF35                   ORG     $BF35
      6
      7  4+1   BF35 30   02           LEAX    2,X     ; On pré-avance X au début
      8  5+7   BF37 34   74           PSHS    B,X,Y,U
      9  6+1   BF39 10EF 8C 4A        STS     <BAK,PCR
     10  4+1   BF3D 31   88 76        LEAY    $78-2,X ; Ca nous permet de garder un offset sur 8 bits ici
     11
     12  2     BF40 86   20           LDA     #$20
     13  11    BF42 3D                MUL
     14  4     BF43 C3   A410         ADDD    #$A410  ; Arithmétique sur D puis
     15  6     BF46 1F   04           TFR     D,S     ; transfert sur S (au lieu de U)
     16
     17  5+6   BF48 35   56           PULS    D,X,U   ; Poum, 6 octets d'un coup !
     18  5+1   BF4A ED   A8 88        STD     -$78,Y  ; Utilisation des ST? les plus rapides sur 16 bits
     19  5+1   BF4D AF   A8 A0        STX     -$60,Y
     20  5+1   BF50 EF   A8 B8        STU     -$48,Y
     21
     22  5+6   BF53 35   56           PULS    D,X,U   ; 6 octets à nouveaux..
     23  5+1   BF55 ED   A8 D0        STD     -$30,Y
     24  5+1   BF58 AF   A8 E8        STX     -$18,Y
     25  5+0   BF5B EF   A4           STU     ,Y
     26
     27  5+6   BF5D 35   56           PULS    D,X,U   ; encore..
     28  5+1   BF5F ED   A8 18        STD     $18,Y
     29  5+1   BF62 AF   A8 30        STX     $30,Y
     30  5+1   BF65 EF   A8 48        STU     $48,Y
     31
     32  5+6   BF68 35   56           PULS    D,X,U   ; et encore... (c'est répétitif non?)
     33  5+1   BF6A ED   A8 60        STD     $60,Y
     34  4+1   BF6D 31   A8 78        LEAY    $78,Y
     35  5+0   BF70 AF   A4           STX     ,Y
     36  5+1   BF72 EF   A8 18        STU     $18,Y
     37
     38  5+6   BF75 35   56           PULS    D,X,U   ; c'est que le début ...
     39  5+1   BF77 ED   A8 30        STD     $30,Y
     40  5+1   BF7A AF   A8 48        STX     $48,Y
     41  5+1   BF7D EF   A8 60        STU     $60,Y
     42
     43  5+0   BF80 EC   E4           LDD     ,S      ; d'accord, d'acc... heu ben non: c'est fini !
     44  5+1   BF82 ED   A8 78        STD     $78,Y
     45
     46  4     BF85 10CE 0000         LDS     #0000   ; Recup de la valeur d'origine de S
     47                  BF87     BAK SET     *-2
     48  5+5   BF89 35   34           PULS    B,X,Y   ; Recup des registres utilisés
     49  3     BF8B CE   B310         LDU     #$B310
     50  4+1   BF8E A6   C5           LDA     B,U
     51  4+1   BF90 E6   C5           LDB     B,U
     52  5+3   BF92 ED   A1           STD     ,Y++    ; Ah oui Y est modifié en sortie de prog
     53  5+4   BF94 35   C0           PULS    U,PC    ; et hop: PULS et RTS fusionnés
Ah oui c'est plus court (96 octets au lieu de 112), ca utilise
  • (1) l'accumulateur pour mettre à jour le pointeur sur la tuile (S)
  • (2) les offsets négatifs -$78 à +$78 pour tirer parti au maximum de l'offset 8 bits (1 cycle vs 3 cycles pour les offsets 16 bits),
  • (3) la pile pour lire les 6 octets en une fois.
  • (4) un LDB plutôt qu'un TFR
A noter: l'échange du role de X et Y, ainsi que de U et S car STX/STU sont plus rapides (d'un cycle) que STY/STS.

Un cycles ca n'a l'air de rien mais comme c'est utilisé hyper fréquemment, avec ce patch le temps de rafraichissement écran tombe à 426+82400 cycles, soit 83ms au lieu des 104ms au début. On est 20% plus rapide (12fps) !!! (les petits ruisseaux font les grandes rivières)
Fichier(s) joint(s):
Commentaire: Patch à mettre entre $BF35 et $BF95
(8% de vitesse à lui seul à ajouter au patch précédent qui ajoute 12% de son coté.)

BF35_BF95.zip [1.69 Kio]
Téléchargé 369 fois
Je crois que là on doit commencer à sentir que le jeu commence à être un peu différent. Peut-être plus dur même (moi je ne sais pas dire: j'ai pas les reflexes de joueur). Et encore on a pas regardé du coté des routines de sprites avec les masques AND/OR.. mais il ne faudra pas trop en espérer car les sprites sont moins nombreux que les tuiles.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 69 messages ]  Aller à la page 1, 2, 3, 4, 5  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 18 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages
Vous ne pouvez pas joindre des fichiers

Rechercher:
Aller à:  
cron
Développé par phpBB® Forum Software © phpBB Group
Traduction par phpBB-fr.com