Logicielsmoto.com

Nous sommes le 28 Mar 2024, 16:29

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 66 messages ]  Aller à la page Précédente  1, 2, 3, 4, 5  Suivante
Auteur Message
 Sujet du message:
MessagePosté: 16 Aoû 2011, 09:46 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Retour de vacances ... je vous livre la version qui (vient d'être) sera contribuée à la prochaine release du projet Exomizer. Elle fait 179 (était 181) (était 183) octets, mais pourrait être encore un petit peu raccourcie. Je crois qu'aucun compilateur ne peut rivaliser :ange: Merci à Sam et PrehisTO pour les optimisations de tueur et les critiques très constructives.

Code:
; Exomizer2 algorithm, backward with litterals for 6809
; by Fool-DupleX, PrehisTO and Sam from PULS (www.pulsdemos.com)
;
; This routine decrunches data compressed with Exomizer2 in raw mode,
; backward with litterals.
; This routine was developed and tested on a Thomson MO5 in July 2011.

   
; The Exomizer2 decruncher starts here.
; call with a JSR exo2 or equivalent.
;
; Input    : U = pointer to end of compressed data
;            Y = pointer to end of output buffer
; Output   : Y = pointer to first byte of decompressed data
; Modifies : Y.
;
; All registers are preserved except Y.
; This code self modifies and cannot be run in ROM.
; This code must be contained within a single page (makes use of DP), but may
; be located anywhere in RAM.

exo2    pshs    u,y,x,dp,d,cc           ; Save context
        tfr     pc,d                    ; Set direct page
        tfr     a,dp
        leay    biba,pcr                ; Set ptr to bits and base table
        clrb
        stb     <bitbuf+1               ; Init bit buffer

nxt     clra
        pshs    a,b
        bitb    #$0f                    ; if (i&15==0)
        bne     skp
        ldx     #$0001                  ; b2 = 1
skp     ldb     #4                      ; Fetch 4 bits
        bsr     getbits
        stb     ,y+                     ; bits[i] = b1
        comb                            ; CC=1
roll    rol     ,s
        rola
        incb
        bmi     roll
        ldb     ,s         
        stx     ,y++                    ; base[i] = b2
        leax    d,x                     ; b2 += accu1
        puls    a,b
        incb   
        cmpb    #52                     ; 52 times ?
        bne     nxt
   
go      ldy     6,s                     ; Y = ptr to output
mloop   ldb     #1                      ; for(;;)
        bsr     getbits                 ; Fetch 1 bit
        bne     cpy                     ; is 1 ?
        stb     <idx+1                  ; B always 0 here
        fcb     $8c                     ; (CMPX) to skip first iteration
rbl     inc     <idx+1                  ; Compute index
        incb
        bsr     getbits
        beq     rbl

idx     ldb     #$00                    ; Self-modified code
        cmpb    #$10                    ; index = 16 ?
        beq     endr
        blo     coffs                   ; index < 16 ?
        decb                            ; index = 17
        bsr     getbits                 ; Get size

cpy     tfr     d,x                     ; Copy litteral
cpyl    lda     ,-u
        sta     ,-y
        leax    -1,x
        bne     cpyl
        bra     mloop

coffs   bsr     cook                    ; Compute length
        pshs    d
        leax    <tab1,pcr
        cmpd    #$03
        bhs     scof
        abx
scof    bsr     getbix
        addb    3,x
        bsr     cook
        std     <offs+2
        puls    x

cpy2    leay    -1,y                    ; Copy non litteral
offs    lda     $1234,y                 ; Self-modified code
        sta     ,y
        leax    -1,x
        bne     cpy2
        bra     mloop

endr    sty     6,s                     ; End
        puls    cc,d,dp,x,y,u,pc        ; Restore context and set Y

; getbits  : get 0 to 16 bits from input stream
; Input    : B = bit count, U points to input buffer
; Output   : D = bits
; Modifies : D,U.

getbix  ldb     ,x
getbits clr     ,-s                     ; Clear local bits
        clr     ,-s         
bitbuf  lda     #$12                    ; Self-modified code
        bra     get3
get1    lda     ,-u
get2    rora
        beq     get1                    ; Bit buffer = 1 ?
        rol     1,s
        rol     ,s
get3    decb
        bpl     get2
        sta     <bitbuf+1               ; Save buffer
        ldd     ,s++
        rts                             ; Retrieve bits and return
   
; cook     : computes base[index] + readbits(&in, bits[index])
; Input    : B = index
; Output   : D = base[index] + readbits(&in, bits[index])
; Modifies : D,X,U.

cook    leax    biba,pcr
        abx                             ; bits+base = 3 bytes
        aslb                            ; times 2
        abx
        bsr     getbix                  ; fetch base[index] and read bits
        addd    1,x                     ; add base[index]
        rts

; Values used in the switch (index)   
tab1    fcb     4,2,4
        fcb     16,48,32

biba    rmb     156                     ; Bits and base are interleaved

Une discussion entre nous s'est développée autour de la pertinence d'utiliser DP dans le code. PrehisTO a proposé une version sans DP qui prend meme 1 octet de moins.

J'ai décidé pour cette première release de conserver la version avec DP qui est en fait pas mal plus rapide dans la boucle principale. Le côté négatif de DP est que le code ne doit pas être a cheval sur une page. Ce n'est pas une grosse contrainte.


Dernière édition par Fool-DupleX le 18 Aoû 2011, 13:46, édité 20 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 16 Aoû 2011, 10:46 
Hors ligne

Inscription: 21 Avr 2010, 10:59
Messages: 253
Cool, je testerai sur des images TO8.
C'est clair que les compilateurs vont rarement sur la piste du code auto modifiant ;)

_________________
http://www.alternative-system.com


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 16 Aoû 2011, 11:36 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Même sans code auto-modifiant et sans se forcer, mais en comprenant bien l'algorithme à coder, on pouvait faire moins de 200 octets, ce qui reste inatteignable pour un compilateur. Ma toute premiere version, sans bien comprendre l'algorithme et en ecrivant mon code assembleur comme il me venait en tête, faisait dans les 250 octets, ce qui reste toujours inatteignable pour un compilateur.

Comme disait un de mes professeurs, à la fin des années 90, "Je n'aime pas trop le C et ce genre de langages qui vous éloignent de la machine" ... :lol:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 16 Aoû 2011, 18:02 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
gilles a écrit:
Cool, je testerai sur des images TO8.

Pour info en compression d'image j'ai déjà expérimenté des trucs avec EXOMIZER2, et sur la collection des TruC40, Truc70, Truc216 (et les nombreuses autres images MAP que je possède), je tourne autour de 10Ko/image au lieu de 16Ko (en MAP je dois être à 15Ko de moyenne, mais je dis ca au pif, je n'ai pas fait les comptes en MAP). Bref avec cette compression on gagne facilement un facteur 2 sur des images pas spécialement simples.

Bon par contre vu le temps qu'il met à compresser sur PC 2Go (1sec/fichier MAP), ca n'est pas une compression à tenter sur thomson si on veut voir le travail terminé dans la journée!

@fool: dommage que le mode "code" casse complètement la mise en page. Personne ne sait comment améliorer le rendu du mode à police supposée fixe?

edit: en fait j'ai fait une erreur dans mes tests, je ne compressais que la partie FORME.. du coup le gain est trop spectaculaire. Si je compresse FORME+FOND, alors j'obtiens 14Ko de moyenne pour les fichiers images au format MAP, et 10Ko (et pas 6) pour une compression avec EXOMIZER.


Dernière édition par Samuel Devulder le 18 Aoû 2011, 23:03, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 16 Aoû 2011, 18:12 
Hors ligne

Inscription: 21 Avr 2010, 10:59
Messages: 253
je ne compte pas forcément compresser sur le TO. J'ai commencé à me bricoler quelques outils win32/linux pour prévisualiser (et editer) en palette TO8, je pense y ajouter la compression.

_________________
http://www.alternative-system.com


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 16 Aoû 2011, 19:24 
Hors ligne

Inscription: 24 Juil 2010, 16:08
Messages: 454
Localisation: France
Fool-DupleX a écrit:
; This routine was developed and tested on a Thomson MO5


Tiens donc ? Content de voir que je ne serai pas le seul à cofder sur cette machine :)
En tout cas merci pour le code, ça va probablement resservir ! :)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 17 Aoû 2011, 03:18 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 492
Samuel Devulder a écrit:
gilles a écrit:
Cool, je
@fool: dommage que le mode "code" casse complètement la mise en page. Personne ne sait comment améliorer le rendu du mode à police supposée fixe?


J'ai force la fonte Courier dans le CSS pour le style "code". Cependant, il ne semble pas reconnaitre les tabulations correctement. J'ai modifie le tier du programme en remettant les espaces qui vont bien a la place.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 17 Aoû 2011, 08:34 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Merci pour la police à espacement fixe ! Je me suis posé exactement la même question quand j'ai posté. Ca fait du bien.

Le compresseur n'est pas destiné à tourner sur nos machines. Exomizer a été développé exactement pour cela: une bonne compression, quitte à nécessiter de la puissance de calcul, avec un algo de décompression rapide destiné aux 8/16 bits. C'est une des raisons qui m'ont poussé à l'étudier à la place de upx, mon choix initial, qui est plus orienté Intel.

Quant au MO5, je code depuis l'âge de 8 ans sur cette machine et je n'ai jamais arrêté :love:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 17 Aoû 2011, 14:34 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Une amélioration (j'ai déjà modifié le code ci-dessus):

- faire un 1,x dans cook au lieu de ,x+ fait gagner un cycle d'execution, pas negligeable vu le nombre d'appels a cook (contribué par PrehisTO)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 17 Aoû 2011, 16:49 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 492
Fool-DupleX a écrit:
Quant au MO5, je code depuis l'âge de 8 ans sur cette machine et je n'ai jamais arrêté :love:


C'est fou cette relation homme-premiere machine que l'on peut avoir. Mon premier ordi a la maison a ete un MO6 et c'est celui que je prefere, meme si a cette epoque, je maudissais mes parents de ne pas m'avoir offert un TO8D a la place, comme mes potes, pour qu'on s'echange les disquettes, tout en revant sur le catalogue Thomson presentant le dernier TO9+ tout beau tout scintillant.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 18 Aoû 2011, 08:34 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Tu as raison, il y a définitivement quelque chose ...

Contribué par sam et déjà rajouté dans le code ci-dessus : en factorisant un ldb ,x avant le call a getbits, on gagne 2 octets :)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 18 Aoû 2011, 12:15 
Hors ligne

Inscription: 06 Juin 2004, 08:23
Messages: 464
Contribué par PrehisTO: en mettant 0 dans bitbuf initialement, getbits fait un tour a vide au premier appel et charge bitbuf, ce qui permet d'eviter d'explicitement charger bitbuf avec le premier octet du flux. Encore 2 octets de gagnés (j'ai modifié le code ci-dessus). Sam suggère de remplacer le CLR correspond par un STB juste après le CLRB, plus rapide.

@yoann: Y'a pas le style "texte barré" dans phpBB ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 26 Oct 2011, 18:13 
Hors ligne

Inscription: 28 Jan 2007, 14:00
Messages: 33
Bonjour.

J'ai examiné Exomizer, merci du tuyau, je ne connaissais pas.
Je travaille sur Atari ST, donc ce que je vais dire ne s'applique peut-être pas au 6809, mais j'ai des sentiments mitigés sur ce compacteur. Je le trouve moins séduisant que mon packer de prédiléction : le NRV2B.
Les raisons:
- il nécéssite une table de décodage, qui prend de la place et du temps machine. En conséquence, l'utilisation de Emomizer n'est rentable qu'à partir d'une cinquantaine d'octets compressés. NRV est rentable dès les premiers octets.
- Le décompactage est lent, et le décompacteur prend de la place. Le fait de devoir utiliser une table pour décompresser n'est pas vraiment un problème puisque je la place sur la pile.

Pour comparer, ma meilleure implémentation du décompacteur faisait du 73 KB/s, pour une taille de 256 octets.

En changeant l'ordre des bits (en changeant le compacteur), j'ai mis les bits de poids fort à gauche plutôt qu'à droite. Par exemple d'origine, l'octet "0x01" est décodé comme les bits 1,0,0,0,0,0,0,0.
En inversant, pour obtenir les mêmes bits dans le même ordre, il faut partir de l'octet "0x80".
Ca me permet d'utiliser
add.b d0,d0
plutôt que
ror.b #1,d0
qui est plus rapide sur 68000. Peut-être est-ce le cas aussi sur 6809 ?

Bref, après cette modif, je suis passé à 80 KB/s, toujours pour un code de décompression de 256 octets.

En poussant l'optimisation, j'arrive désormais à 100KB/s, pour un décompacteur de 278 octets.



Si je compare à NRV2B, je suis à 157KB/s, pour 144 octets. Et pas de table à générer, la compression est efficace dès les premiers octets. Et le compresseur est plus simple.


Pourquoi je vous parle de ça ? Parce que je pense que cet algo serait plus simple à implémenter pour la décompression temps réel depuis une K7. Pas de table à générer, pas de buffer, l'algo est utilisable dès le premier bit. Et aussi parceque la décompression est plus rapide (sur 68000 en tout cas), je pense que c'est important pour la lecteur K7. J'aimerais bien voir ce procédé utilisé en fait !


NRV2B a quand même un inconvénient : il compresse moins.
Alors que Exomizer est un LZ77, NRV est un LZW. Pour mes tests, je suis parti de 12 images de 32 Ko (384 000 octets).
Exomizer: 106 Ko
Nrv2b: 118 Ko
FreeNrv2B: 114 Ko

Quelques liens:
Page Officielle : http://www.oberhumer.com/opensource/ucl/#download
Autre implémentation, plus simple et un chouia plus efficace (et bcp plus rapide):
http://dev.laptop.org/~rsmith/LinuxBIOSv2/util/nrv2b/
Implémentation brute force: plus d'infos: http://z0mbie.host.sk/snupx.txt
http://hvorost.com/z0mbie/nrv2b.zip
http://hvorost.com/z0mbie/nrv2bde.zip (encore plus lent)

Si ma version "inversée" de exomizer vous tente, je peux la mettre ici, j'ai passé pas mal d'heure pour faire un changement que je pensais trivial.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Doutes
MessagePosté: 27 Oct 2011, 15:39 
Hors ligne

Inscription: 28 Jan 2007, 14:00
Messages: 33
(Pardon du double poste, mais le message précédent était déjà grand).

Je réfléchissais à la faisabilité d'une routine de loader K7 qui décompresserait en temps réel. Et je me dis que ce n'est probablement pas possible.
Je ne sais comment la lecture de K7 fonctionne, donc je peux me tromper complétement.

J'imagine que la lecture K7 est synchronisée avec le CPU, et que celui-ci attend un nombre de cycle determiné entre chaque byte. Or la decompression fait que l'intervalle entre chaque getbyte peut beaucoup varier, or, le moteur de la cassette continue de tourner, et on ne pourra pas se resynchroniser.

A moins que la lecture K7 se fasse par "blocs", et qu'il y a moyen de se resynchroniser entre chaque bloc. Dans ce cas, c'est faisable, mais il faudrait s'assurer que la routine de décompression ait le temps de décompresser tout le bloc avant que le suivant n'arrive sous la tête de lecture.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 27 Oct 2011, 18:07 
Hors ligne
M. DCMOTO

Inscription: 06 Juin 2004, 08:23
Messages: 681
Localisation: Provence (France)
Oui, la lecture de la cassette se fait bloc par bloc, avec un intervalle entre chaque bloc et resynchronisation sur l'entête du bloc suivant. Pendant la lecture d'un bloc les interruptions sont désactivées et les temporisations pour la lecture des bits sont des boucles courtes, rendant pratiquement impossible tout autre traitement.
Dans un enregistrement standard l'intervalle entre les blocs est tout juste suffisant pour traiter les données lues (par exemple vérifier la checksum ou déplacer le bloc en mémoire). On ne peut pas espérer faire autre chose.
Il y a toutefois une solution simple : créer des enregistrements avec des intervalles plus longs entre les blocs. C'est faisable de plusieurs façons :
- Soit on copie en ram la routine d'écriture cassette et on modifie la temporisation entre les blocs.
- Soit on utilise un éditeur de fichier .wav pour insérer des silences plus ou moins longs entre chaque bloc, et on enregistre une nouvelle cassette.


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

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 36 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