Karoshi MSX Community

Desarrollo MSX => Rutinas - Snipets => Mensaje iniciado por: pitpan en 29 de Septiembre de 2010, 05:21:39 pm



Título: BitBuster "Extreme" asMSX version
Publicado por: pitpan en 29 de Septiembre de 2010, 05:21:39 pm
Note: *UNTESTED AS IS*

Código:
;In: HL: source

;    DE: destination

depack: ;inc    hl        ;skip original file length

;    inc    hl        ;which is stored in 4 bytes

;    inc    hl

;    inc    hl



    ld    a,128

   

    exx

    ld    de,1

    exx

   

depack_loop:

    call getbits

    jr    c,output_compressed    ;if set, we got lz77 compression

    ldi                ;copy byte from compressed data to destination [literal byte]

    jr    depack_loop

   



;handle compressed data

output_compressed:

    ld    c,[hl]        ;get lowest 7 bits of offset, plus offset extension bit

    inc    hl        ;to next byte in compressed data



output_match:

    ld    b,0

    bit    7,c

    jr    z,output_match1    ;no need to get extra bits if carry not set



    call getbits

    call rlbgetbits

    call rlbgetbits

    call rlbgetbits



    jr    c,output_match1    ;since extension mark already makes bit 7 set

    res    7,c        ;only clear it if the bit should be cleared

output_match1:

    inc    bc

   

   

;return a gamma-encoded value

;length returned in HL

    exx            ;to second register set!

    ld    h,d

    ld    l,e             ;initial length to 1

    ld    b,e        ;bitcount to 1



;determine number of bits used to encode value

get_gamma_value_size:

    exx

    call getbits

    exx

    jr    nc,get_gamma_value_size_end    ;if bit not set, bitlength of remaining is known

    inc    b                ;increase bitcount

    jr    get_gamma_value_size        ;repeat...



get_gamma_value_bits:

    exx

    call getbits

    exx

   

    adc    hl,hl                ;insert new bit in HL

get_gamma_value_size_end:

    djnz    get_gamma_value_bits        ;repeat if more bits to go



get_gamma_value_end:

    inc    hl        ;length was stored as length-2 so correct this

    exx            ;back to normal register set

   

    ret    c

;HL' = length



    push    hl        ;address compressed data on stack



    exx

    push    hl        ;match length on stack

    exx



    ld    h,d

    ld    l,e        ;destination address in HL...

    sbc    hl,bc        ;calculate source address



    pop    bc        ;match length from stack



    ldir            ;transfer data



    pop    hl        ;address compressed data back from stack



    jr    depack_loop



rlbgetbits:

    rl b

getbits:

    add    a,a

    ret    nz

    ld    a,[hl]

    inc    hl

    rla

    ret