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