[ZX81:TUTO] L'affichage... compression & co.
Bonjour à tous,
J'aimerai partager avec vous une réflexion sur l'affichage écran du ZX81.
Présentation du ZX81:
Le Zx81 est un ordinateur muni d'un Zilog (clone du 8080) avec 1k octets en version de base.
La rom de 8K possède un basic qui gère une taille mémoire de 16k maximum (limitation constructeur). Il est à noter que Sinclair n'a JAMAIS fabriqué ou fait fabriquer d'extension mémoire supérieur à 16k, de peur que les utilisateurs ne lui reproche cette limitation due au test mémoire de la ROM !
L'affichage est simple, et ne possède pas d'UDG (redéfinition graphique), mais une police de caractère de 63 symboles (alpha et graphique).
Cette police de caractère peut être affichée en vidéo inversé en activant le bit 7 à l'affichage.
Le Bit 6 des caractères n'est utilisé qu'en basic pour afficher les commandes et les fonctions Basic.
Le Zx81 a la particularité d'avoir sa mémoire vidéo juste après le programme Basic, ce qui rend son emplacement "flottant", imposé par la taille du programme basic!
Mais une valeur D_File système permet de connaître la valeur de l'offset du premier caractère de la mémoire vidéo.
Pour l'affichage, il suffit de poker directement dans cette mémoire, en évitant de supprimer un caractère de retour à la ligne... fatale au basic, car cela désorganise l'affichage... et fini par afficher le VARS (mémoire des variable, ainsi que le reste de la mémoire, jusqu'en haut des 16k ou se trouve les piles du CPU)...Donc, plantage!
Structure vidéo (16K):
32 caractères + $76 (retour à la ligne)
32 caractères + $76 (retour à la ligne)...
... 24 fois, puis l'on trouve le VARS, où sont stockés les variables.
En version 1k, la rom "compresse" l'écran en éliminant le espaces jusqu'en fin de
ligne:
BONJOUR+$76
$76
$76
... 24 fois
Ce qui permet de ne pas encombrer la mémoire!
Avec une extension mémoire, la taille de la mémoire écran est fixe, avec ses 32 caractère x24 lignes+24 retour à la ligne = 792 octets.
Si l'on veut sauvegarder un dessin, il faut donc 792 octets... ou 768 octets si l'on ne sauvegarde pas les retours à la ligne.
Donc, 16k (16384 octets) peuvent contenir un certain nombre d'écrans... mais combien?
Soit un RAM de 16384 octets:
- 130 octets système.
- 792 octets mémoire vidéo.
- 255 octets pour la pile.
- 2 octets pour les variable (on travail en langage machine)
- 30 octets de Basic.
- 30 octets de langage machine.
= 15145 octets pour les images.
\768 = 19 images plein écran.
L'objet de cette étude est de compresser les images pour que le stockage soit moins gourmand!
Compression par élimination de redondances:
Donc, j'ai encodé les images comme suit:
Soit "XXXXXXAAAAABA..." à l'écran sur la même ligne.
Donc, j'ai 6*"X";5*"A";1*"B";1*"A" = 13 octets.
Vu que le bit6 n'est pas utilisé pour l'affichage, je l'utilise pour "Taguer" le caractère pour indiquer qu'il est répéter * fois.
X!6 A!5 B A (pas de tag pour les lettres non répétées)
Vu que le codage ce fait sur deux octets un DATA et un Multiplicateur, le second est limité à $FF, donc 255 fois.
Un écran blanc (768*" " ou 768*CHR$(0)) est encodé comme suit:
(0 or BIT6) x 255;(0 or BIT6) x 255;(0 or BIT6) x 255
Donc:$40$FF$40$FF$40$FF (6 octets au lieu de 768 octets)
C'est un exemple, car stocker un écran vide est inutile.
Image exemple:
Non codée:
Codée:
Donc, cet encodage évitera les répétitions inutiles.
Tout va dépendre de la complexité de l'image, car si aucune redondance n'est possible, la taille codée et décodée sera identique.
Il est à noter que ce codage ne fonctionne pas avec les données binaires, mais seulement avec les textes, et les images.
Routines ASM et fichier 'P'(compression et décompression sans buffer):
http://zx81.ordi5.free.fr/xavsnap/xpict ... i_zx81.zip
Compression LZ:
On pourrai s'arrêter là, mais j'ai trouvé une routine Z80 pour décoder les fichiers LZ sur Amstrad CPC et Game Boy... Cette routine n'est pas trop lourde et pèse moins de 300 octets... mais permet de réduire les images.
Cette méthode est basée sur le logiciel "PUcrunch" sous PC DOS, et en important les fichiers générés, il est possible de les stocker en mémoire pour une décompression ultérieur.
Pour 16K d'images, je récupère 3K d'espace libre en comptant la routine LZ. (ce qui est non négligeable!)
Routines ASM et fichier 'P':
http://zx81.ordi5.free.fr/xavsnap/xpict ... Z_ZX81.zip
Seul problème, nous avons besoin d'un buffer de décompression pour pouvoir décoder les datas avec le système précédent... donc au pire, 768 octets en moins.
Il serait donc intéressant de décompresser directement en mémoire vidéo, mais cela implique une taille des fichiers compactés "DATAs" plus important qu'avec les deux méthodes de compression.
Routines ASM d'une démo avec pas moins de 30 images en "full screen" et fichier 'P' exécutable sur émulateur:
(seront ajoutées par la suite)
L'ensemble du travail n'est pas encore effectué, mais cela plante le décor pour la suite...
[ZX81:TUTO] L'affichage... compression & co.
Modérateurs : Papy.G, fneck, Carl
-
- Messages : 7983
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: [ZX81:TUTO] L'affichage... compression & co.
Regarde du coté de la compression EXOMIZER2. Elle utilise seulement 156 octets de buffer et occupe (sur 6809) environ 181 octets pour le decompresseur (mais le 6809 produit du code hyper compact).
==> http://hem.bredband.net/magli143/exo/
Discussion pour le 6809 + code: http://www.logicielsmoto.com/phpBB/view ... 3201#p3201
==> http://hem.bredband.net/magli143/exo/
Discussion pour le 6809 + code: http://www.logicielsmoto.com/phpBB/view ... 3201#p3201
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: [ZX81:TUTO] L'affichage... compression & co.
Oui, j'ai...
Je passe au test dès la fin de la démo!
Mais, il semble un peu plus lourd...
Je passe au test dès la fin de la démo!
Mais, il semble un peu plus lourd...
Code : Tout sélectionner
; ******************************************************
; ** Librería de rutinas para Amstrad CPC **
; ** Raúl Simarro, Artaburu 2007 **
; ******************************************************
XLIB cpc_UnExo
.cpc_UnExo
;Exomizer 2 Z80 decoder
; by Metalbrain
;
; compression algorithm by Magnus Lind
;input hl=compressed data start
; de=uncompressed destination start
;
; you may change exo_mapbasebits to point to any free buffer
pop af
pop de
pop hl
push af
di
call deexo
ei
ret
.deexo
ld ixh,128
ld b,52
ld iy,exo_mapbasebits
push de
.exo_initbits
ld a,b
sub 4
and 15
jr nz,exo_node1
ld de,1 ;DE=b2
.exo_node1
ld c,16
.exo_get4bits
call exo_getbit
rl c
jr nc,exo_get4bits
ld (iy+0),c ;bits(i)=b1
push hl
inc c
ld hl,0
scf
.exo_setbit
adc hl,hl
dec c
jr nz,exo_setbit
ld (iy+52),e
ld (iy+104),d ;base(i)=b2
add hl,de
ex de,hl
inc iy
pop hl
djnz exo_initbits
inc c
.exo_literalseq
pop de
.exo_literalcopy
ldir ;copy literal(s)
.exo_mainloop
ld c,1
call exo_getbit ;literal?
jr c,exo_literalcopy
ld c,255
.exo_getindex
inc c
call exo_getbit
jr nc,exo_getindex
ld a,c ;C=index
cp 16
ret z
jr c,exo_continue
push de
ld d,16
call exo_getbits
jr exo_literalseq
.exo_continue
push de
call exo_getpair
push bc
pop af
ex af,af' ;lenght in AF'
ld de,512+48 ;1?
dec bc
ld a,b
or c
jr z,exo_goforit
ld de,1024+32
dec bc ;2?
ld a,b
or c
jr z,exo_goforit
ld e,16
.exo_goforit
call exo_getbits
ld a,e
add a,c
ld c,a
call exo_getpair ;bc=offset
pop de ;de=destination
push hl
ld h,d
ld l,e
sbc hl,bc ;hl=origin
ex af,af'
push af
pop bc ;bc=lenght
ldir
pop hl ;Keep HL, DE is updated
jr exo_mainloop ;Next!
.exo_getpair
ld iy,exo_mapbasebits
ld b,0
add iy,bc
ld d,(iy+0)
call exo_getbits
ld a,c
add a,(iy+52)
ld c,a
ld a,b
adc a,(iy+104)
ld b,a
ret
.exo_getbits
ld bc,0 ;get D bits in BC
.exo_gettingbits
dec d
ret m
call exo_getbit
rl c
rl b
jr exo_gettingbits
.exo_getbit
ld a,ixh ;get one bit
add a,a
ld ixh,a
ret nz
ld a,(hl)
inc hl
rla
ld ixh,a
ret
.exo_mapbasebits
defs 156 ;tables for bits, baseL, baseH
Re: [ZX81:TUTO] L'affichage... compression & co.
Entre nous, le plus long c'est de dessiner les 30 images pour la démo !!!
Même avec le "Easy-draw" du Xur, il faut les retravailler sur deux niveaux de compression...
côté émulateur:
"Heighty-one"=Rigoureux.
"Xur"=Ludique pour la programmation et la création.
"Sz81"=Pour le son et la jouabilité au joystick.
"Eighty-one" (win32): ftp://ftp.worldofspectrum.org/pub/sincl ... One1.0.zip
le "Xur"(win32): http://zx81.vb81.free.fr
"Sz81"(win32/linux): http://sz81.sourceforge.net/
Même avec le "Easy-draw" du Xur, il faut les retravailler sur deux niveaux de compression...
côté émulateur:
"Heighty-one"=Rigoureux.
"Xur"=Ludique pour la programmation et la création.
"Sz81"=Pour le son et la jouabilité au joystick.
"Eighty-one" (win32): ftp://ftp.worldofspectrum.org/pub/sincl ... One1.0.zip
le "Xur"(win32): http://zx81.vb81.free.fr
"Sz81"(win32/linux): http://sz81.sourceforge.net/
Dernière modification par Xavier le 05 mars 2020 01:57, modifié 1 fois.
Re: [ZX81:TUTO] L'affichage... compression & co.
J'ai porté exomizer sur hector HRX et il est très petit et rapide à la décompression.
Je pense que sur Zx-81 ca doit être faisable, mais pas sur que cela permette de gagner énormément sur 768 octets
Je pense que sur Zx-81 ca doit être faisable, mais pas sur que cela permette de gagner énormément sur 768 octets
Re: [ZX81:TUTO] L'affichage... compression & co.
Au pire, on gagne un tiers de l'image, mais la taille des fichiers imposent une compression multiple des images, donc la répétition des headers... à moins de décompresser un binaire unique à partir d'un point précis! idée à approfondir, mais la décompression sera plus lente car il faudra tester l'ensemble du fichier pour en récupérer un petite partie! (texte de description, décore...)