From 36c824864c02f0a3f62c8a1d365d1670835c8c96 Mon Sep 17 00:00:00 2001 From: "Christian A. Weber" Date: Tue, 12 May 1992 22:26:12 +0000 Subject: Initial revision --- Source/CompressBlock.S | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 Source/CompressBlock.S (limited to 'Source/CompressBlock.S') diff --git a/Source/CompressBlock.S b/Source/CompressBlock.S new file mode 100644 index 0000000..14984ec --- /dev/null +++ b/Source/CompressBlock.S @@ -0,0 +1,144 @@ +** +** $Id: $ +** $Revision: $ +** +** $Filename: CompressBlock.S $ +** $Author: Christian A. Weber $ +** $Release: $ +** $Date: 92/05/12 22:26:30 $ +** +** iff.library/IFFLib_CompressBlock +** +** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2, +** CH-8037 ZUERICH, SWITZERLAND. ALL RIGHTS RESERVED. NO PART +** OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED +** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PER- +** MISSION OF THE AUTHOR. USE AT YOUR OWN RISK. +** + + + IDNT IFFLib_CompressBlock + SECTION text,CODE + + INCLUDE "IffLib.i" + + XREF ClearError + XDEF CompressBlockFunc + + +******* iff.library/IFFLib_CompressBlock ************************************ +* +* NAME +* IFFLib_CompressBlock -- Compress a memory block +* +* SYNOPSIS +* result = IFFLib_CompressBlock( source, destination, size, mode ) +* A0 A1 D0 D1 +* +* ULONG IFFLib_CompressBlock( APTR, APTR, ULONG, ULONG ) +* +* FUNCTION +* Compress the memory block using the appropriate compression mode. +* If the compressed data would become longer than the uncompressed, +* an error is returned. +* +* INPUTS +* source - Pointer to data to compress +* destination - Target address for compression +* size - Number of data bytes to compress +* mode - Compression mode. Currently, the following modes +* are supported: +* $$$ +* +* RESULTS +* Length of compressed data or 0 if an error occurred. +* +* SEE ALSO +* IFFLib_DecompressBlock() +* +***************************************************************************** + +CompressBlockFunc: + tst.l d1 ; Modus == 0 ? + beq.b Mode_Copy + subq.l #1,d1 ; Modus == 1 ? + beq.b Mode_CmpByteRun1 + moveq.l #0,d0 + rts + +***************************************************************************** +** Kopiermodus + +Mode_Copy: movem.l d0/a6,-(SP) + movea.l ib_SysBase(a6),a6 + JSRLIB CopyMem + movem.l (SP)+,d0/a6 + rts + +***************************************************************************** +** CmpByteRun1 komprimieren + +Mode_CmpByteRun1: + movem.l d2-d3/a2-a3,-(SP) + lea (a0,d0.l),a2 ; A2 : Source-Endadresse + moveq #0,d3 ; Byte-Zähler + +crunchloop: bsr.b CountEq ; wieviele gleiche Bytes folgen ? + cmp.w #3,d0 ; genug gleiche Bytes zum runnen ? + blt.b countdump ; nee, lohnt sich nicht -> Dumpen + + addq.l #2,d3 ; Markierbyte & Anzahl + move.b (a0),d1 ; Wert + adda.w d0,a0 ; Source anpassen + subq.w #1,d0 ; muss .w sein und nicht .b !!!!!!! + neg.b d0 ; negieren (= "Run"-Code) + move.b d0,(a1)+ ; und eintragen + move.b d1,(a1)+ ; Wert eintragen + bra.b crunchcont ; weitermachen + +countdump: movea.l a0,a3 ; Source-Pointer retten + moveq #0,d2 ; D2 : Länge des Dump-Blocks +1$: addq.b #1,d2 + bmi.b 2$ ; höchstens 127 Bytes pro Block + addq.l #1,a0 + cmpa.l a2,a0 ; Ende der Linie erreicht ? + bge.b 3$ ; ja -> abbrechen + bsr.b CountEq + cmp.w #3,d0 ; Ende des Dump-Blocks ? + blt.b 1$ ; noch nicht + bra.b 3$ ; Ende +2$: moveq #127,d2 +3$: movea.l a3,a0 ; Source-Pointer restaurieren + + add.l d2,d3 ; zur Gesamtanzahl dazuzählen + addq.l #1,d3 ; Markierbyte nicht vergessen + subq.w #1,d2 ; aus 1..128 mach 0..127 + move.b d2,(a1)+ ; Markierbyte eintragen +4$: move.b (a0)+,(a1)+ ; Datenbytes eintragen + dbf d2,4$ + + +crunchcont: cmpa.l a2,a0 ; Ende der Linie erreicht ? + blt.b crunchloop ; noch nicht! + + move.l d3,d0 ; Return: Anzahl Destination-Bytes + movem.l (SP)+,d2-d3/a2-a3 + rts + + *** Anzahl gleicher Zeichen ab (a0) zählen und nach D0 + +CountEq: move.l a0,-(SP) + moveq #1,d0 ; D0 : Anzahl gleiche Bytes +1$: move.b (a0)+,d1 ; erstes Byte +2$: cmp.b (a0)+,d1 ; Byte gleich wie letztes Byte ? + bne.b 3$ ; nein -> abbrechen + cmp.w #128,d0 + bge.b 3$ ; höchstens 128 gleiche + addq.w #1,d0 ; Anzahl erhöhen + cmpa.l a2,a0 ; Ende der Linie erreicht ? + blt.b 2$ ; noch nicht -> weiterzählen +3$: move.l (SP)+,a0 + rts + + END + -- cgit v1.2.3