File: _ice.s - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

;********************************************* Unpackroutine von ICE-PACK
; Eingabe: a0 = Adresse gepackter Daten
; Ausgabe: a1 = Adresse entpackter Daten
ice_decrunch:
        movem.l d0-a6,-(sp)
        bsr.s   getinfo         ; ein Langwort holen
        cmpi.l  #'ICE!',d0      ; Kennung gefunden?
        bne     not_packed      ; nein: nicht gepackt
        bsr.s   getinfo         ; gepackte L�nge holen
        lea.l   -8(a0,d0.l),a5  ; a5 = Ende der gepackten Daten
        bsr.s   getinfo         ; ungepackte L�nge holen (original)
        move.l  d0,(sp)         ; Originall�nge: sp�ter nach d0
        move.l  a1,a4           ; a4 = Zielpuffer
        move.l  a1,a6
        adda.l  d0,a6           ; a6 = Ende entpackte Daten
        move.l  a6,a3           ; merken f�r Picture decrunch
        move.b  -(a5),d7                ; erstes Informationsbyte
        bsr     normal_bytes

        bsr     get_1_bit       ;; Picture decrunch!
        bcc.s   not_packed      ;; These marked lines may be
        move.w  #$0f9f,d7       ;; removed in your own sources
ice_00: moveq   #3,d6           ;; if you do not use the
ice_01: move.w  -(a3),d4                ;; additional algorithm.
        moveq   #3,d5           ;;
ice_02: add.w   d4,d4           ;;
        addx.w  d0,d0           ;;
        add.w   d4,d4           ;;
        addx.w  d1,d1           ;;
        add.w   d4,d4           ;;
        addx.w  d2,d2           ;;
        add.w   d4,d4           ;;
        addx.w  d3,d3           ;;
        dbra    d5,ice_02       ;;
        dbra    d6,ice_01       ;;
        movem.w d0-d3,(a3)      ;;
        dbra    d7,ice_00       ;;

not_packed:
        movem.l (sp)+,d0-a6
        rts

getinfo:        moveq   #3,d1           ; ein Langwort vom Anfang
getbytes: lsl.l #8,d0           ; der Daten lesen
        move.b  (a0)+,d0
        dbf     d1,getbytes
        rts

normal_bytes:  
        bsr.s   get_1_bit
        bcc.s   test_if_end     ; Bit %0: keine Daten
        moveq.l #0,d1           ; falls zu copy_direkt
        bsr.s   get_1_bit
        bcc.s   copy_direkt     ; Bitfolge: %10: 1 Byte direkt kop.
        lea.l   direkt_tab+20(pc),a1
        moveq.l #4,d3
nextgb: move.l  -(a1),d0                ; d0.w Bytes lesen
        bsr.s   get_d0_bits
        swap.w  d0
        cmp.w   d0,d1           ; alle gelesenen Bits gesetzt?
        dbne    d3,nextgb       ; ja: dann weiter Bits lesen
no_more:        add.l   20(a1),d1       ; Anzahl der zu �bertragenen Bytes
copy_direkt:    
        move.b  -(a5),-(a6)     ; Daten direkt kopieren
        dbf     d1,copy_direkt  ; noch ein Byte
test_if_end:    
        cmpa.l  a4,a6           ; Fertig?
        bgt.s   strings         ; Weiter wenn Ende nicht erreicht
        rts    

;************************** Unterroutinen: wegen Optimierung nicht am Schlu�

get_1_bit:add.b d7,d7           ; hole ein bit
        bne.s   bitfound                ; quellfeld leer
        move.b  -(a5),d7                ; hole Informationsbyte
        addx.b  d7,d7
bitfound:       rts    

get_d0_bits:    
        add.w   #$3,$f00402+(32*15)

        moveq.l #0,d1           ; ergebnisfeld vorbereiten
hole_bit_loop:  
        add.b   d7,d7           ; hole ein bit
        bne.s   on_d0           ; in d7 steht noch Information
        move.b  -(a5),d7                ; hole Informationsbyte
        addx.b  d7,d7
on_d0:  addx.w  d1,d1           ; und �bernimm es
        dbf     d0,hole_bit_loop        ; bis alle Bits geholt wurden
        rts    

;************************************ Ende der Unterroutinen


strings:        lea.l   length_tab(pc),a1       ; a1 = Zeiger auf Tabelle
        moveq.l #3,d2           ; d2 = Zeiger in Tabelle
get_length_bit:
        bsr.s   get_1_bit
        dbcc    d2,get_length_bit       ; n�chstes Bit holen
no_length_bit:  
        moveq.l #0,d4           ; d4 = �berschu�-L�nge
        moveq.l #0,d1
        move.b  1(a1,d2.w),d0   ; d2: zw. -1 und 3; d3+1: Bits lesen
        ext.w   d0              ; als Wort behandeln
        bmi.s   no_ber          ; kein �berschu� n�tig
get_ber: bsr.s  get_d0_bits
no_ber: move.b  6(a1,d2.w),d4   ; Standard-L�nge zu �berschu� add.
        add.w   d1,d4           ; d4 = String-L�nge-2
        beq.s   get_offset_2    ; L�nge = 2: Spezielle Offset-Routine


        lea.l   more_offset(pc),a1      ; a1 = Zeiger auf Tabelle
        moveq.l #1,d2
getoffs:        bsr.s   get_1_bit
        dbcc    d2,getoffs
        moveq.l #0,d1           ; Offset-�berschu�
        move.b  1(a1,d2.w),d0   ; request d0 Bits
        ext.w   d0              ; als Wort
        bsr.s   get_d0_bits
        add.w   d2,d2           ; ab jetzt: Pointer auf Worte
        add.w   6(a1,d2.w),d1   ; Standard-Offset zu �berschu� add.
        bpl.s   depack_bytes    ; keine gleiche Bytes: String kop.
        sub.w   d4,d1           ; gleiche Bytes
        bra.s   depack_bytes


get_offset_2:  
        moveq.l #0,d1           ; �berschu�-Offset auf 0 setzen
        moveq.l #5,d0           ; standard: 6 Bits holen
        moveq.l #-1,d2          ; Standard-Offset auf -1
        bsr.s   get_1_bit
        bcc.s   less_40         ; Bit = %0
        moveq.l #8,d0           ; quenty fourty: 9 Bits holen
        moveq.l #$3f,d2         ; Standard-Offset: $3f
less_40:        bsr.s   get_d0_bits
        add.w   d2,d1           ; Standard-Offset + �ber-Offset

depack_bytes:                   ; d1 = Offset, d4 = Anzahl Bytes
        lea.l   2(a6,d4.w),a1   ; Hier stehen die Originaldaten
        adda.w  d1,a1           ; Dazu der Offset
        move.b  -(a1),-(a6)     ; ein Byte auf jeden Fall kopieren
dep_b:  move.b  -(a1),-(a6)     ; mehr Bytes kopieren
        dbf     d4,dep_b                ; und noch ein Mal
        bra     normal_bytes    ; Jetzt kommen wieder normale Bytes


direkt_tab:
        dc.l $7fff000e,$00ff0007,$00070002,$00030001,$00030001  ; Anzahl 1-Bits
        dc.l     270-1, 15-1,    8-1,    5-1,    2-1    ; Anz. Bytes

length_tab:
        dc.b 9,1,0,-1,-1                ; Bits lesen
        dc.b 8,4,2,1,0          ; Standard-L�nge - 2 (!!!)

more_offset:
        dc.b      11,   4,   7,  0      ; Bits lesen
        dc.w    $11f,  -1, $1f  ; Standard Offset

;*************************************************** Ende der Unpackroutine