;
;; 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 |