comment faire du double buffering sur vg5000 ?
Modérateurs : Papy.G, fneck, Carl
- z80¯\_(ツ)_/¯
- Messages : 77
- Inscription : 06 oct. 2020 13:15
- Localisation : Bourgogne
comment faire du double buffering sur vg5000 ?
Bonjour,
J'affiche actuellement des caractères avec la routine ($0092).
Je me demande s'il est possible de préparer l'affichage offscreen et de tout afficher d'un coup avec des routines utilisables avec Z88dk sans utiliser la mémoire mappée en $4000 qui d'après ce que j'ai compris n'est ce qu'il y a de plus rapide.
Il est sûrement possible de créer un tableau en C et de tout copier car par car avec "$0092" mais ça ne me parait pas optimal. Il faudrait qqch du genre je copie les 2000 octets de l'écran d'un coup.
Bon j'ai peut être mal formulé la question et j'espère que c'est plus ou moins clair. Si vous avez de quoi m'aider, n'hésitez pas.
J'affiche actuellement des caractères avec la routine ($0092).
Je me demande s'il est possible de préparer l'affichage offscreen et de tout afficher d'un coup avec des routines utilisables avec Z88dk sans utiliser la mémoire mappée en $4000 qui d'après ce que j'ai compris n'est ce qu'il y a de plus rapide.
Il est sûrement possible de créer un tableau en C et de tout copier car par car avec "$0092" mais ça ne me parait pas optimal. Il faudrait qqch du genre je copie les 2000 octets de l'écran d'un coup.
Bon j'ai peut être mal formulé la question et j'espère que c'est plus ou moins clair. Si vous avez de quoi m'aider, n'hésitez pas.
- Mokona
- Messages : 1041
- Inscription : 17 déc. 2016 22:01
- Localisation : Nord Est des Yvelines
- Contact :
Re: comment faire du double buffering sur vg5000 ?
Hello,
le système par défaut du BASIC pour l'affichage fait globalement la copie du contenu présent en $4000 vers le processeur graphique (EF9345 / VDP). Pour référence, ça commence en $00d3 avec HL qui prend la valeur $4000.
Il y a une petite subtilité avec la ligne 0 ($00e0), qui est la "ligne d'état" qui est séparée de la suite ($00ff).
On ne peut par contre pas copier directement de la RAM principale vers la RAM spécifique du VDP. Cette dernière n'est pas présente sur le BUS de données principal, elle est connectée directement au VDP. Il est donc nécessaire d'effectuer la copie via l'envoie de commandes au VDP, ce qui n'est pas bien rapide...
Je vois deux manières générales d'optimiser cela, mais je n'ai pour le moment vraiment essayée aucune des deux :
- optimiser la copie en entrelaçant un autre traitement. En effet, la copie à certains endroits que le VDP soit prêt pour recevoir de nouvelles commande (les boucles "in a,($cf) ; or a ; jp m,..." comme par exemple en $0115. On pourrait imaginer faire autre chose d'utile en attendant... Pas facile à mettre en oeuvre cependant.
(si on ne change pas les attributs, on peut aussi peut-être se contenter de n'envoyer qu'un octet sur deux...)
- utiliser un système de liste de commandes. Préparer les changements à faire en direct sur l'écran, puis n'exécuter que ceux-ci au moment de l'IRQ. Il y a différentes manières d'implémenter ça plus ou moins complexes (une liste de données tranformées en commandes, la construction du code assembleur nécessaire dynamiquement, un patron de code assembleur où on injecte les données uniquement,...)
le système par défaut du BASIC pour l'affichage fait globalement la copie du contenu présent en $4000 vers le processeur graphique (EF9345 / VDP). Pour référence, ça commence en $00d3 avec HL qui prend la valeur $4000.
Il y a une petite subtilité avec la ligne 0 ($00e0), qui est la "ligne d'état" qui est séparée de la suite ($00ff).
On ne peut par contre pas copier directement de la RAM principale vers la RAM spécifique du VDP. Cette dernière n'est pas présente sur le BUS de données principal, elle est connectée directement au VDP. Il est donc nécessaire d'effectuer la copie via l'envoie de commandes au VDP, ce qui n'est pas bien rapide...
Je vois deux manières générales d'optimiser cela, mais je n'ai pour le moment vraiment essayée aucune des deux :
- optimiser la copie en entrelaçant un autre traitement. En effet, la copie à certains endroits que le VDP soit prêt pour recevoir de nouvelles commande (les boucles "in a,($cf) ; or a ; jp m,..." comme par exemple en $0115. On pourrait imaginer faire autre chose d'utile en attendant... Pas facile à mettre en oeuvre cependant.
(si on ne change pas les attributs, on peut aussi peut-être se contenter de n'envoyer qu'un octet sur deux...)
- utiliser un système de liste de commandes. Préparer les changements à faire en direct sur l'écran, puis n'exécuter que ceux-ci au moment de l'IRQ. Il y a différentes manières d'implémenter ça plus ou moins complexes (une liste de données tranformées en commandes, la construction du code assembleur nécessaire dynamiquement, un patron de code assembleur où on injecte les données uniquement,...)
Re: comment faire du double buffering sur vg5000 ?
J'ai l'intention de coupler le Z80 avec un Z80-DMA qui se partageront le même socle du CPU. La raison est que LDI ou OUTI prend 16 cycles à transférer un octet. Avec le DMA ça prendra sans doute 4 fois moins de cycles pour le transfert. Pour que cela soit intéressant, il faut que les blocs soient suffisamment long pour que le prologue (le paramétrage des registres du DMA - 6 en tout) soit négligeable.
Cependant, je doute que le DMA donnera un avantage avec le VDP puisque ce dernier semble avoir des temps de latence qui annuleront les bénéfices du DMA. Dommage.
Cependant, je doute que le DMA donnera un avantage avec le VDP puisque ce dernier semble avoir des temps de latence qui annuleront les bénéfices du DMA. Dommage.
- Papy.G
- Modérateur
- Messages : 3051
- Inscription : 10 juin 2014 13:40
- Localisation : Haute-Garonne/Gers
Re: comment faire du double buffering sur vg5000 ?
z80¯\_(ツ)_/¯ > Tu peux envoyer des octets de façon arbitraire où tu le souhaites dans la VRAM (via la BAL du VDP toutefois), et tu peux aussi afficher comme page-écran une zone de la VRAM (par "blocs"), mais il faut faire attention aux routines que tu utilises à cet effet, et le retour au BASIC risque de mettre le bazar dans tout cela. Regardes bien les routines que tu utilises, et la doc du EF9345, pour voir ce qui fonctionnera ou pas. Daniel a fait une démo multicolore, sur Alice il me semble, qui utilisait le double "buffering", sur ce même VDP.
Hlide > Si c'est pour gagner du temps, il te faudrait un gestionnaire permettant l'accès mémoire sur une zone en commun depuis le CPU, et depuis le VDP de façon entrelacée (voir architecture du AppleII ), il existe des chips de ram à double bus, aussi, c'est une possibilité intéressante, si c'est une machine que tu crées de zéro.
Hlide > Si c'est pour gagner du temps, il te faudrait un gestionnaire permettant l'accès mémoire sur une zone en commun depuis le CPU, et depuis le VDP de façon entrelacée (voir architecture du AppleII ), il existe des chips de ram à double bus, aussi, c'est une possibilité intéressante, si c'est une machine que tu crées de zéro.
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Demandez-en plus, ou faites-le vous-même.
Re: comment faire du double buffering sur vg5000 ?
C'est sur VG5000 : http://dcvg5k.free.fr/programmes/demo-2 ... index.html
En affichant alternativement deux écrans différents on peut mélanger deux couleurs pour donner l'illusion d'une troisième.
Daniel
L'obstacle augmente mon ardeur.
L'obstacle augmente mon ardeur.
Re: comment faire du double buffering sur vg5000 ?
A condition d'être sur un écran cathodique ? parce que ça fonctionne très mal avec les écrans modernes qui ont leur fréquence d'affichage propre.
Re: comment faire du double buffering sur vg5000 ?
@Papy.G
c'est surtout pour des machines existantes à base de Z80. Le couple DRAM + CPU sera vu comme un CPU par le reste. Le CPU pourra explicitement déléguer les transferts de mémoires ou I/O au DMA qui prendra la main via le /BUSREQ et /BUSACK pour arbitrer l'accès au reste. Si le transfert par DMA est 4 fois plus rapide alors ça donne des ressources supplémentaires au CPU pour faire autre chose que de transférer sur les 3/4 restant de temps après que la DMA ait fini de transférer. La RAM dual-port c'est cool pour les accès en parallèle mais c'est très cher et c'est intrusif au niveau hardware.
c'est surtout pour des machines existantes à base de Z80. Le couple DRAM + CPU sera vu comme un CPU par le reste. Le CPU pourra explicitement déléguer les transferts de mémoires ou I/O au DMA qui prendra la main via le /BUSREQ et /BUSACK pour arbitrer l'accès au reste. Si le transfert par DMA est 4 fois plus rapide alors ça donne des ressources supplémentaires au CPU pour faire autre chose que de transférer sur les 3/4 restant de temps après que la DMA ait fini de transférer. La RAM dual-port c'est cool pour les accès en parallèle mais c'est très cher et c'est intrusif au niveau hardware.
- Mokona
- Messages : 1041
- Inscription : 17 déc. 2016 22:01
- Localisation : Nord Est des Yvelines
- Contact :
Re: comment faire du double buffering sur vg5000 ?
On s'éloigne un peu du sujet initial.
Sur le VG5000, il faudra aller récupérer /BUSAK. Il n'est pas branché (il ne l'est pas sur le schéma de principe et d'après mes notes, il ne l'est pas physiquement non plus, mais je ne me souviens pas si j'étais allé vérifier).
/BUSREQ lui est maintenu à l'état haut via la résistance 3313.
Sur le VG5000, il faudra aller récupérer /BUSAK. Il n'est pas branché (il ne l'est pas sur le schéma de principe et d'après mes notes, il ne l'est pas physiquement non plus, mais je ne me souviens pas si j'étais allé vérifier).
/BUSREQ lui est maintenu à l'état haut via la résistance 3313.
Re: comment faire du double buffering sur vg5000 ?
Argh, on va encore s'éloigner un peu :
[Œuf-topic]
on s'en fiche un peu que /BUSACK et /BUSREQ ne soient pas utilisés sur la carte-mère parce que ça se passera alors uniquement entre le Z80-CPU et le Z80-DMA sur leur carte qui s'enfiche sur le socle Z80 et donc l'arbitrage se fera à minima entre ces deux-là.
[/Œuf-topic]
[Œuf-topic]
on s'en fiche un peu que /BUSACK et /BUSREQ ne soient pas utilisés sur la carte-mère parce que ça se passera alors uniquement entre le Z80-CPU et le Z80-DMA sur leur carte qui s'enfiche sur le socle Z80 et donc l'arbitrage se fera à minima entre ces deux-là.
[/Œuf-topic]
- Papy.G
- Modérateur
- Messages : 3051
- Inscription : 10 juin 2014 13:40
- Localisation : Haute-Garonne/Gers
Re: comment faire du double buffering sur vg5000 ?
La "Boîte Aux Lettres", par laquelle on communique avec le VDP, c'était pour rappeler que dans les machines existantes fonctionnant avec un 9345, on ne peut écrire directement en VRAM.
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Demandez-en plus, ou faites-le vous-même.
Re: comment faire du double buffering sur vg5000 ?
OK merci bien. C'est clair