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