14983
UTILITAIRE -> Divers
© _Public_Domain_ (2007)
 
 
 
Pucrunch
cpc
 
 

NOTICE / MANUAL

TXT (3)

NOTICE TEXTE n° 1 (12.83 Ko)

PUCRUNCH, l'ultime compacteur ? ------------------------------ Cet archive contient plusieurs sources de routines a utiliser pour decompacter un fichier compacte avec PUCRUNCH. Il contient aussi la version Windows de PUCRUNCH. Comme d'habitude, pas d'accent dans cet article. Version 1.0 * Tom et Jerry/GPA le 02/07/2007 C'est quoi PUCRUNCH ? --------------------- PUCRUNCH est un compacteur cree par un programmeur sur Commodore C64, Pasi Ojala, qui presente la particularite de fonctionner sur PC. Le programme est capable de generer des executables pour tous les Commodore 8bits, mais permet egalement de creer des fichiers de donnees simples. Beneficiant de la puissance de calcul apportee par une plateforme materielle recente, PUCRUNCH compacte de facon quasiment instantanee tout fichier de taille modeste et utilise des techniques de recherches complexes pour produire un taux de compression excellent, meilleur que tout ce qui existe a ce jour sur CPC. Des programmeurs Z80 se sont penches sur ce produit et ont cree des routines permettant de decompresser un fichier PUCRUNCHed. Le premier source diffuse semble avoir ete fait pour la Nintendo Gameboy en ... 1999 (qui a dit que les consoles ne servent a rien :-) ). D'autres routine sont depuis sorties, mais aucune a ce jour n'avait ete adaptee pour le l'Amstrad CPC. Cette injustice est desormais reparee ! Les sources : ------------- Site officiel de PUCRUNCH : http://www.cs.tut.fi/~albert/Dev/pucrunch/ Routine GB par Jeff Frohwein : http://www.cs.tut.fi/~albert/Dev/pucrunch/uncrunch-z80.asm Routine Z80 par Jussi Pitkänen : http://bree.homeunix.net/~ccfg/pucrunch/ Routine Sega Master System par Maxim : http://www.smspower.org/maxim/smssoftware/pucrunch.html L'archive ci-joint contient des versions CPC de ces routines plus deux versions inedites. Tous les sources sont compilables avec Maxam, l'ultime assembleur sur CPC :-). GB.ASM Port Gameboy Z80.ASM Port "Z80" GB_CPC.ASM Version optimisee du port Gameboy BASIC.ASM Source Maxam du port Gameboy optimise avec passage des parametres via un CALL sous Basic GB.ASM Taille en octets : &1C0 Le premier source est present a titre "historique". C'est celui qui est le plus commente (en anglais) et le plus lisible car il n'utilise pas d'astuce de programmation. Z80.ASM Taile en octets : &129 Le second source est une version tres particuliere, utilisant les registres secondaires du Z80 pour eviter de couteuses operations de lecture/ecriture de variables en memoire. C'est la routine la plus rapide a la decompression et la plus courte. J'ai du modifier un peu le source pour qu'il fonctionne sous BASIC (sauvegarde des registres secondaires BC, DE et HL). Autre particularite, le source ne stocke pas dans une table les 31 octets necessaires a la decompression. Il va les lire dans l'en-tete du code compacte. Si cette zone est ecrasee lors du decompactage, plantage assure ! Il est bien evidemment facile de rajouter une copie de cette table dans la routine, mais du coup, sa taille augmente un peu. GB-CPC.ASM Taille en octets : &18D Une version optimisee du source Gameboy. La routine est un peu plus courte, et environ 10% plus rapide a la decompression. Elle est moins performante que Z80.ASM, mais travaille sans probleme sous interruption. BASIC.ASM Taille en octets : &19C Une version de GB-CPC.ASM permettant de passer sous Basic les parametres necessaires au decompactage par un simple CALL. Quelques considerations techniques sur le decompactage ------------------------------------------------------ L'implantation en memoire du code compacte ****************************************** En fonction de la taille du programme original et du code compacte, il existe deux options pour determiner ou stocker en memoire le fichier compacte. Sur de petits fichiers, on peut implanter le code compacte dans une zone qui n'est pas utilisee par le programme d'origine. Un exemple : On compacte un programme utilisant la memoire entre &1000 et &5000. Le code compacte fait &3000 de longueur. On pourra sans risque implanter le code compacte en &5000, car cette zone ne sera jamais ecrite par la routine de decompactage et le code compacte n'est pas assez long pour "endommager" les zones memoire reservees au systeme (grossierement, au dessus de &A67B pour un CPC6128). On pourrait aussi par exemple implanter le code compacte en memoire video (&C000). Sur un programme plus gros, il n'y aura pas assez de memoire "libre" pour utiliser cette technique. On utilise alors le principe de la "zone tampon". Le programme compacte est implante dans la zone memoire du programme normal, mais avec un decalage suffisant pour que la fin du programme compacte ne soit pas ecrasee lors du decompactage. Comment determiner la taille de cette zone tampon ? Eh bien, cela depend de la memoire qui reste disponible et du programme compacte. On peut considerer qu'une zone tampon de &0100 est dans la plupart des cas suffisante. Si on reprend notre exemple : Programme standard utilisant la memoire entre &1000 et &5000 Code compacte de longueur &3000 Zone "tampon" : entre &5000 et &5100 Implantation du code compacte : &5100-&3000 = &2100 Si le decompactage plante, il faut augmenter la taille de la zone tampon. Pourquoi Utiliser PUCRUNCH plutot qu'un autre compacteur ? ********************************************************** La performance : PUCRUNCH est selon mes tests de 10 a 20% plus performant que CPCT 3.0 (desole Yves !), la reference sur CPC. La vitesse : le compactage d'un programme est tres rapide. Plus besoin d'attendre une demi-heure pour compacter un jeu ! La souplesse : PUCRUNCH etant un programme PC, la taille du programme a compacter n'a pas d'importance. On peut ainsi compacter de tres gros programmes, que seuls quelques rares compacteurs comme le Crown Cruncher peuvent traiter. PUCRUNCH a t'il des defauts ? ***************************** Il faut disposer d'un PC. Je suppose que la plupart des utilisateurs de CPC en sont equipes... Par rapport a certains compacteurs qui s'occupent de tout, il est necessaires d'avoir un minimum de bases sur l'organisation de la memoire du CPC pour bien s'en servir. Le decompactage est plus lent que la majorite des autres crunchers sur CPC. Cela reste neanmoins tout a fait correct au regard de la taille des fichiers compactes. Il n'y a pas de front-end, de programme qui vous prend en charge, et vous evite de penibles calculs :-). D'un autre cote, l'usage d'un source garantit une totale adaptabilite a vos besoin. Exemple de compactage d'un ecran de presentation 17k ---------------------------------------------------- Dans l'archive DSK, vous trouverez le fichier BUGGY.SCR (transfert de la page ecran C64 d'un jeu connu, Buggy Boy), qui nous servira pour ce petit didacticiel. 1ere etape : transferer le fichier sur votre PC. ************ On peut par exemple utiliser ManageDsk de Demoniak. Seule regle IMPERATIVE, le fichier doit etre exporte SANS EN-TETE. Si vous avez correctement fait le transfert, le fichier sur PC doit avoir une taille de 16384 octets (soit &4000). 2eme etape : le compactage. ************ Copier le fichier BUGGY.SCR dans le meme repertoire que PCRUNCH.EXE. Ouvrir une fenetre de commande en mode texte. Taper la commande : PCRUNCH.EXE -C0 -D BUGGY.SCR BUGGY.CRU Si tout se passe bien, vous devez voir dans le repertoire de travail un nouveau fichier BUGGY.CRU, de 4500 octets (soit 1194 !). 3eme etape : le transfert vers le CPC. ************ Vous reprenez votre outil prefere, et vous importez sur une disquette CPC le fichier BUGGY.CRU en mode BINAIRE. Le fichier n'a aucune adresse d'implantation ni d'execution par defaut. 4eme etape : Determiner les adresses d'implantation en memoire du fichier compacte et du decompacteur. ************ Une page ecran etant implante en memoire video (&C000-&FFFF), nous avons a notre disposition toute la ram "systeme" (&0040-&A67B pour un CPC 6128). Le fichier compacte peut donc etre charge ou bon vous semble dans cette zone. Dans notre exemple, nous allons charger l'ecran en &4000. La routine de decompactage utilisee sera celle utilisable directement en Basic. Par defaut, elle est implantee en &A000. 5eme etape : Compiler le decompacteur. ************ Lancer Maxam. Charger avec la commande L (Load) le source BASIC.ASM. Passer en mode edition avec la commande T (Text). Compiler le source avec la commande A (Assemble). >> Le programme BASIC.BIN est cree sur la disquette. 6eme etape : Creer un chargeur Basic pour l'image. ************ Le programme devra charger en memoire l'image compactee, la routine de decompactage, puis lancer le decompactage. En pratique, cela nous donne : 10 OPENOUT"D":MEMORY &3FFF 20 LOAD "BUGGY.CRU",&4000 30 LOAD "BASIC.BIN",&A000 40 CALL &A000,&4000,&C000 La ligne 40 contient l'appel a la routine. On lui transmet deux informations : - L'adresse de depart de l'ecran compacte - L'adresse de depart ou decompacter l'image (soit le debut de la memoire video) Simple, non ? Exemple de compactage de programme, Boulder Dash ------------------------------------------------ Basiquement, la methode est identique au compactage d'une page ecran. Il faudra simplement personnaliser la routine de decompactage et bien veiller a ce que le code compacte ne soit pas corrompu lors de la decompression. Dans cet exemple, nous travaillerons avec le jeu Boulder Dash. La version la plus courante de ce programme se presente sous la forme d'un fichier BOULDER.BIN de 29ko dont les caracteristiques sont : Adresse d'implantation : &0200 Longueur : &7025 Adresse d'execution : &1F52 1ere etape : transferer le fichier sur votre PC. ************ On peut par exemple utiliser ManageDsk de Demoniak. Seule regle IMPERATIVE, le fichier doit etre exporte SANS EN-TETE. Si vous avez correctement fait le transfert, le fichier sur PC doit avoir une taille de 28709 octets (soit &7025) 2eme etape : le compactage. ************ Copier le fichier BOULDER.BIN dans le meme repertoire que PCRUNCH.EXE Ouvrir une fenetre de commande en mode texte. Taper la commande PCRUNCH.EXE -C0 -D BOULDER.BIN BOULDER.CRU Si tout se passe bien, vous devez voir dans le repertoire de travail un nouveau fichier BOULDER.CRU, de taille 11532 (soit &2D0C !). 3eme etape : le transfert vers le CPC. ************ Vous reprenez votre outil prefere, et vous importez sur une disquette CPC le fichier BOULDER.CRU en mode BINAIRE. Le fichier n'a aucune adresse d'implantation ni d'execution par defaut. 4eme etape : Determiner les adresses d'implantation en memoire du fichier compacte et du decompacteur. ************ Soyez attentif, cela devient un peu plus technique (mais pas complexe pour autant). Comme nous l'avons vu dans le paragraphe precedent, pour etre sur que le decompactage ne se traduise pas par un plantage, il est necessaire de faire en sorte que les dernieres donnees compactees chargees en memoire ne soient pas ecrasees par le code decompacte. Pour BOULDER DASH, la fin du programme "normal" se trouve en (&200 + &7025) -1, soit &7224. Il nous reste donc beaucoup de memoire pour loger la routine de decompactage et la zone "tampon". Dans notre exemple, nous allons implanter la routine de decompactage en &7800. Le fichier compacte sera charge juste en dessous, soit : &7800 - longueur du fichier compacte &7800 - &2D0C = &4AF4 5eme etape : compiler une version specifique du decompacteur. ************ BOULDER DASH etant implante assez bas en memoire, il n'est pas tres pratique d'utiliser un chargeur Basic. L'appel a la routine de decompactage devra donc etre immediatement enchaine par l'execution du jeu, sans revenir au Basic. Pour ce faire, il faut juste rajouter au debut de la routine que vous avez choisie (GB.ASM, Z80.ASM ou GB_CPC.ASM) LD HL,&4AF4 LD DE,&0200 CALL routine JP &1F52 Compiler ensuite le source. Vous devez obtenir un fichier GB.BIN, GB-CPC.BIN ou Z80.BIN. Si les fichiers n'ont pas ete modifies, ils doivent avoir la taille suivante : GB.BIN Z80.BIN GB-CPC.BIN A ces longueur, il faudra rajouter celle du code que nous avons rajoute, soit 12 octets. 6eme etape : On fusionne tout ce bazar ! ************ Nous devons d'abord determiner la longueur finale du programme avec le decompacteur integre. Le calcul est donc le suivant : longueur du fichier compacte + longueur de la routine de decompactage Pour Boulder Dash, on obtient (exemple avec source GB-CPC) : &2D0C + (&18D + 12) = &2EA5 Maintenant, un simple petit programme Basic nous permettra de creer enfin un fichier unique. 10 OPENOUT"D":MEMORY &4AF9 20 LOAD "BOULDER.CRU",&4AFA 30 LOAD "GB_CPC.BIN",&8000 40 SAVE "BOULDER.BIN",B,&4AF9,&2EA5,&8000 Au final, on se retrouve avec un executable de 12Ko au lieu de 29 !
 

NOTICE TEXTE n° 2 (8.1 Ko)

; Version CPC par T&J/GPA * 07/2007 ! ; Petites optimisations diverses, sans toucher le corps de la routine. ; Voir la routine non modifiee pour essayer de comprendre son fonctionnement ! ; Liste des modifications : ; - Remplacement de boucles de copies par des LDIR / LDI ; - Integration dans le code des variables MaxGamma et consors, gain en ; place et en temps machine ! ; Utilisation du registre IX pour pointer sur TablePu (faible gain en place ; et en temps machine ; Remplacement de quelques JP par des JR ;* PUCRUNCH unpacker for GB ;* Modeled after Pasi Ojala's C64 code. ;* ;* Written in RGBDS ;* ;* V1.0 - Ported to GB by Jeff Frohwein, started 22-Jul-99 ;* V1.1 - Various optimizations, 23-Jul-99 ;* V1.2 - Even more optimizations, 23-Jul-99 ;* V1.3 - Fixed a bug in the code. 256 byte copy didn't work. 24-Feb-00 ;* ORG &A000 NOLIST WRITE "BASIC.BIN" ; Read CALL datas transmitted from Basic booter CP &2 RET NZ LD E,(IX+&0) LD D,(IX+&1) LD L,(IX+&2) LD H,(IX+&3) ; ****** Unpack pucrunch data ****** ; Entry HL = Source packed data ; DE = Destination for unpacked data Unpack LD (OutPtr+1),DE ; Read the file header & setup variables LD BC,6 ADD HL,BC LD A,(HL) INC HL LD (escPu +1),A INC HL INC HL LD A,(HL) INC HL LD (main +1),A ; EscBits LD B,A LD A,8 SUB B LD (noesc +1),A ; Esc8Bits LD A,(HL) INC HL LD (MaxGamma +1),A DEC A LD B,A LD A,8 SUB B LD (Max8Gamma +1),A LD A,(HL) INC HL LD (Max1Gamma +1),A ADD A,A DEC A LD (Max2Gamma +1),A LD A,(HL) INC HL LD (ExtraBits +1),A INC HL INC HL LD A,(HL) INC HL LD C,A LD DE,tablePu-1 PUSH DE POP IX INC DE ; DE = TablePu, IX=TablePu-1 (useful for chrcode optimization) ; Copy the RLE table (maximum of 31 bytes) to RAM LD B,&0 LDIR LD D,&80 JR main tablepu ds 31,&0 newesc LD B,A LD A,(escPu +1) LD (regy +1),A LD A,(main +1) LD E,A LD A,B INC E CALL getchk LD (escPu +1),A LD A,(regy +1) ; Fall through and get the rest of the bits. noesc LD E,&00 INC E CALL getchk ; Write out the escaped/normal byte OutPtr LD BC,&0000 LD (BC),A INC BC LD (OutPtr+1),BC ; Fall through and check the escape bits again main LD A,&00 ; changed LD A,(EscBits) LD E,A XOR A ; A = 0 LD (regy +1),A INC E CALL getchk ; X=2 -> X=0 LD B,A escPu LD A,&00 CP B LD A,B JR NZ,noesc ; Not the escape code -> get the rest of the byte ; Fall through to packed code CALL getval ; X=0 -> X=0 LD (lzpos +1),A ; xstore - save the length for a later time SRL A ; cmp #1 ; LEN == 2 ? (A is never 0) JR NZ,lz77 ; LEN != 2 -> LZ77 CALL get1bit ; X=0 -> X=0 SRL A ; bit -> C, A = 0 JR NC,lz77_2 ; A=0 -> LZPOS+1 LZ77, len=2 ; e..e01 CALL get1bit ; X=0 -> X=0 SRL A ; bit -> C, A = 0 JR NC,newesc ; e..e010 New Escape ; e..e011 Short/Long RLE regy LD A,&00 ; Y is 1 bigger than MSB loops INC A LD (regy +1),a CALL getval ; Y is 1, get len, X=0 -> X=0 LD (lzpos +1),A ; xstore - Save length LSB Max1Gamma LD B,&00 CP B ; ** PARAMETER 63-64 -> C set, 64-64 -> C clear.. JR C,chrcode ; short RLE, get bytecode ; Otherwise it's long RLE longrle LD B,A Max8Gamma LD A,&00 LD E,A ; ** PARAMETER 111111xxxxxx LD A,B CALL getbits ; get 3/2/1 more bits to get a full byte, X=2 -> X=0 LD (lzpos +1),A ; xstore - Save length LSB CALL getval ; length MSB, X=0 -> X=0 LD (regy +1),A ; Y is 1 bigger than MSB loops chrcode CALL getval ; Byte Code, X=0 -> X=0 LD E,A LD (cpc1+2),A CP 32 ; 31-32 -> C set, 32-32 -> C clear.. cpc1 LD A,(IX + &00) JR C,less32 ; 1..31 ; Not ranks 1..31, -> 111110xxxxx (32..64), get byte.. LD A,E ; get back the value (5 valid bits) LD E,3 CALL getbits ; get 3 more bits to get a full byte, X=3 -> X=0 less32 PUSH HL PUSH AF LD A,(lzpos +1) LD E,A ; xstore - get length LSB LD B,E INC B ; adjust for cpx#$ff;bne -> bne LD A,(regy +1) LD C,A LD HL,(OutPtr +1) POP AF dorle LD (HL),A INC HL DEC B JR NZ,dorle ; xstore 0..255 -> 1..256 DEC C JR NZ,dorle ; Y was 1 bigger than wanted originally LD (OutPtr +1),HL POP HL JP main lz77 CALL getval ; X=0 -> X=0 LD B,A Max2Gamma LD A,&00 CP B ; end of file ? RET Z ; yes, exit ExtraBits LD A,&00 ; ** PARAMETER (more bits to get) LD E,A LD A,B DEC A ; subtract 1 (1..126 -> 0..125) INC E CALL getchk ;f ; clears Carry, X=0 -> X=0 lz77_2 LD (lzpos +2),A ; offset MSB LD E,8 CALL getbits ; clears Carry, X=8 -> X=0 ; Note Already eored in the compressor.. LD B,A LD A,(lzpos +1) LD E,A ; xstore - LZLEN (read before it's overwritten) LD A,(OutPtr +1) ADD A,B ; -offset -1 + curpos (C is clear) LD (lzpos +1),A LD A,(lzpos +2) LD B,A LD A,(OutPtr+2) CCF SBC B LD (lzpos +2),A ; copy X+1 number of chars from LZPOS to OUTPOS INC E ; adjust for cpx#$ff;bne -> bne ; Write decompressed bytes out to RAM LD B,E PUSH DE PUSH HL lzpos LD HL,&0000 LD DE,(OutPtr +1) ; Modification GPA pour utilisation de LDI ; du coup, on libere le registre A LD A,B OR A ; Is it zero? JR Z,zero ; yes INC A SRL A JR NC,olzloop ; optimisable en LDI INC BC lzloop LDI ; Note Must be copied forward olzloop LDI ; Note Must be copied forward DEC A JR NZ,lzloop ; X loops, (256,1..255) LD (OutPtr+1),DE POP HL POP DE JP main zero LD A,128 JR lzloop ; getval Gets a 'static huffman coded' value ; ** Scratches X, returns the value in A ** getval LD A,1 ; X must be 0 when called! LD E,A loop0 SLA D JR NZ,loop1 LD D,(HL) INC HL RL D ; Shift in C=1 (last bit marker) ; bitstr initial value = $80 == empty loop1 JR NC,getchk ; got 0-bit INC E LD B,A ; save a MaxGamma LD A,&00 CP E LD A,B ; restore a JR NZ,loop0 JR getchk ; getbits Gets X bits from the stream ; ** Scratches X, returns the value in A ** get1bit INC E getbits SLA D JR NZ,loop3 LD D,(HL) INC HL RL D ; Shift in C=1 (last bit marker) ; bitstr initial value = &80 == empty loop3 RLA getchk DEC E JR NZ,getbits OR A ; clear carry flag RET
 

NOTICE TEXTE n° 3 (4.65 Ko)

; Porte sous Maxam par T&J/GPA en juin 2007 ;### uncrunch.asm -- Standalone Pucrunch decompressor ;### Based on C64 code by Pasi Ojala ;### Ported to Z80 by Jussi Pitkdnen <ccfgàpp.inet.fi> ;### ;### Thanks to Jeff Frohwein for his GB-Z80 port. ;### ;## Decompress a pucrunched file. ;## In HL = source address ;## DE = destination address ;## Destroy AF, BC, DE, HL, AF', BC', DE', HL' ORG &A000 WRITE "Z80.BIN" NOLIST ; Rajout pour pouvoir utiliser sous Basic la routine sur un CPC ; On preserve les vecteurs secondaires (en particulier BC, utilise pour ; gerer l'etat de la memoire). ; On a CPC, it is necessary to save secondary registers if the routine ; has to be used under Basic. main DI EXX PUSH HL PUSH DE PUSH BC EXX CALL uncrunch EXX POP BC POP DE POP HL EXX EI RET uncrunch: push de ; destination pointer to 2nd register exx ; set pop de exx inc hl ; read the header self-modifying the inc hl ; parameters straight into the code inc hl ; skip useless data inc hl inc hl inc hl ld a, (hl) ; starting escape inc hl ld (esc+1), a inc hl ; skip useless data inc hl ld a, (hl) ; number of escape bits inc hl ld (escb0+1), a ld (escb1+1), a ld b, a ; 8 - escape bits ld a, 8 sub b ld (noesc+1), a ld a, (hl) ; maxGamma + 1 inc hl ld (mg+1), a ld b, a ; 8 - maxGamma ld a, 9 sub b ld (longrle+1), a ld a, (hl) ; (1 << maxGamma) inc hl ld (mg1+1), a add a, a ; (2 << maxGamma) - 1 dec a ld (mg21+1), a ld a, (hl) ; extra LZ77 position bits inc hl ld (elzpb+1), a inc hl ; skip useless data inc hl ld e, (hl) ; RLE table length ld (rlet+1), hl ; RLE table pointer inc hl ld d, 0 add hl, de ld c, 128 ; start decompression jp loop newesc ld a, (esc+1) ; save old escape code ld d, a escb0 ld b, 2 ; ** parameter xor a ; get new escape code call get_bits ld (esc+1), a ld a, d noesc ld b, 6 ; ** parameter call get_bits ; get more bits to complete a byte exx ; output the byte ld (de), a inc de exx loop xor a escb1 ld b, 2 ; ** parameter call get_bits ; get escape code esc cp 0 ; ** parameter jp nz, noesc call get_gamma ; get length exx ld b, 0 ld c, a exx cp 1 jp nz, lz77 ; LZ77 xor a call get_bit jp nc, lz77_2 ; 2-byte LZ77 call get_bit jp nc, newesc ; escaped literal byte call get_gamma ; get length exx ld b, 1 ld c, a exx mg1 cp 64 ; ** parameter jp c, chrcode ; short RLE, get bytecode longrle ld b, 2 ; ** parameter call get_bits ; complete length LSB ex af, af' call get_gamma ; length MSB exx ld b, a ex af, af' ld c, a exx chrcode call get_gamma ; get byte to repeat push hl rlet ld hl, 0000 ; ** parameter ld d, 0 ld e, a add hl, de cp 32 ld a, (hl) pop hl jp c, dorle ld a, e ; get 3 more bits to complete the ld b, 3 ; byte call get_bits dorle exx ; output the byte n times inc c dorlei ld (de), a inc de dec c jp nz, dorlei dec b jp nz, dorlei exx jp loop lz77 call get_gamma ; offset MSB mg21 cp 127 ; ** parameter ret z ; EOF, return dec a ; (1...126 -> 0...125) elzpb ld b, 0 ; ** parameter call get_bits ; complete offset MSB lz77_2 ex af, af' ld b, 8 ; offset LSB call get_bits cpl ; xor'ed by the compressor exx ; combine them into offset ld l, a ex af, af' ld h, a inc hl xor a ; CF = 0 push de ; (current output position) - (offset) ex de, hl sbc hl, de pop de inc bc ldir ; copy exx jp loop ;## Get a bit from the source stream. ;## Return CF = result get_bit: sla c ; shift next bit into CF ret nz ld c, (hl) ; get next byte inc hl ; increase source stream pointer rl c ; shift next bit into CF, bit0 = 1 ret ;## Get multiple bits from the source stream. ;## In B = number of bits to get ;## Return A = result get_bits dec b ret m sla c ; shift next bit into CF jp nz, gb1 ld c, (hl) ; get next byte inc hl ; increase source stream pointer rl c ; shift next bit into CF, bit0 = 1 gb1 rla ; rotate next bit into A jp get_bits ;## Get an Elias Gamma coded value from the source stream. ;## Return A = result get_gamma ld b, 1 mg ld a, 7 ; ** parameter gg1 call get_bit ; get bits until 0-bit or max jr nc, gg2 inc b cp b jp nz, gg1 gg2 ld a, 1 ; get the actual value dec b jp get_bits
 



Goto Top

CPC-POWER/CPCSOFTS, programmation par Kukulcan © 2007-2026 tous droits réservés.
Reproduction sans autorisation interdite. Tous les titres utilisés appartiennent à leurs propriétaires respectifs.
Hébergement Web, Mail et serveurs de jeux haute performance