Logicielsmoto.com http://www.logicielsmoto.com/phpBB/ |
|
Exomizer http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=421 |
Page 2 sur 5 |
Auteur: | Fool-DupleX [ 16 Aoû 2011, 09:46 ] |
Sujet du message: | |
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 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. |
Auteur: | gilles [ 16 Aoû 2011, 10:46 ] |
Sujet du message: | |
Cool, je testerai sur des images TO8. C'est clair que les compilateurs vont rarement sur la piste du code auto modifiant |
Auteur: | Fool-DupleX [ 16 Aoû 2011, 11:36 ] |
Sujet du message: | |
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" ... |
Auteur: | Samuel Devulder [ 16 Aoû 2011, 18:02 ] |
Sujet du message: | |
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. |
Auteur: | gilles [ 16 Aoû 2011, 18:12 ] |
Sujet du message: | |
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. |
Auteur: | PulkoMandy [ 16 Aoû 2011, 19:24 ] |
Sujet du message: | |
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 ! |
Auteur: | Yoann Riou [ 17 Aoû 2011, 03:18 ] |
Sujet du message: | |
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. |
Auteur: | Fool-DupleX [ 17 Aoû 2011, 08:34 ] |
Sujet du message: | |
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é |
Auteur: | Fool-DupleX [ 17 Aoû 2011, 14:34 ] |
Sujet du message: | |
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) |
Auteur: | Yoann Riou [ 17 Aoû 2011, 16:49 ] |
Sujet du message: | |
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é
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. |
Auteur: | Fool-DupleX [ 18 Aoû 2011, 08:34 ] |
Sujet du message: | |
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 |
Auteur: | Fool-DupleX [ 18 Aoû 2011, 12:15 ] |
Sujet du message: | |
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 ? |
Auteur: | megar [ 26 Oct 2011, 18:13 ] |
Sujet du message: | |
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. |
Auteur: | megar [ 27 Oct 2011, 15:39 ] |
Sujet du message: | Doutes |
(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. |
Auteur: | Daniel Coulom [ 27 Oct 2011, 18:07 ] |
Sujet du message: | |
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. |
Page 2 sur 5 | Heures au format UTC + 1 heure |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |