summaryrefslogtreecommitdiff
path: root/Source/DecompressBlock.S
blob: b3c2764bd9c3c8333b467cc17b8cb34582a66ffb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
**
**	$Id: DecompressBlock.S,v 21.2 92/05/17 03:27:44 chris Exp $
**	$Revision: 21.2 $
**
**	$Filename: DecompressBlock.S $
**	$Author: chris $
**	$Date: 92/05/17 03:27:44 $
**
**	iff.library/IFFL_DecompressBlock
**
**	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	IFFL_DecompressBlock
		SECTION	text,CODE

		INCLUDE	"IffLib.i"

		XREF	SetError
		XDEF	DecompressBlockFunc

		XREF	Compress_NONE
		XDEF	Decompress_BYTERUN1 ;,Decompress_FIBDELTA


******* iff.library/IFFL_DecompressBlock ************************************
*
*    NAME
*	IFFL_DecompressBlock -- Decompress a memory block
*
*    SYNOPSIS
*	result = IFFL_DecompressBlock( source, destination, size, mode )
*	                               A0      A1           D0    D1
*
*	ULONG IFFL_DecompressBlock( APTR, APTR, ULONG, ULONG )
*
*    FUNCTION
*	Decompress the memory block using the appropriate Decompression mode.
*	If the Decompressed data would become longer than the unDecompressed,
*	an error is returned.
*
*    INPUTS
*	source      - Pointer to data to decompress
*	destination - Target address for decompression
*	size        - Number of _DECOMPRESSED_ data bytes
*	mode        - Compression mode. Currently, the following modes
*	              are supported:
*
*	              IFFL_COMPR_NONE     - Vanilla copy
*	              IFFL_COMPR_BYTERUN1 - CmpByteRun1 (ILBM BODY data)
*	              IFFL_COMPR_FIBDELTA - Fibonacci Delta (8SVX BODY data)
*
*    RESULTS
*	Length of uncompressed data or 0 if an error occurred.
*	IFFL_IFFError() returns IFFL_ERROR_BADCOMPRESSION if you ask for
*	an unsupported compression mode.
*
*    SEE ALSO
*	IFFL_CompressBlock()
*
*****************************************************************************

DecompressBlockFunc:
		subq.l	#1,d1
		beq.b	Decompress_BYTERUN1	; Modus == 1
		bmi	Compress_NONE		; Modus == 0

	*** Unbekannter Modus --> Error setzen

		movem.l	a5-a6,-(SP)
		movea.l	a6,a5			; A5 :  IFFBase für SetError()
		moveq.l	#IFFL_ERROR_BADCOMPRESSION,d0
		bsr	SetError		; Setzt auch D0 auf 0
		movem.l	(SP)+,a5-a6
		rts

*****************************************************************************
**	CmpByteRun1 dekomprimieren

Decompress_BYTERUN1:
		movem.l	d0/d2,-(SP)

1$:		moveq.l	#0,d1
		move.b	(a0)+,d1	; D1 :  nächstes Kommando-Byte
		bmi.b	2$		; crunched --->

.CopyLoop:	move.b	(a0)+,(a1)+	; D1+1 Bytes normal kopieren
		subq.l	#1,d0		; DEC length counter
		dble	d1,.CopyLoop
		bra.b	3$		; --->
2$:
		neg.b	d1
		bmi.b	3$		; ~$80 (== $80) ist 'NOP'
		move.b	(a0)+,d2	; Zu repetierender Wert
.RepLoop:	move.b	d2,(a1)+
		subq.l	#1,d0		; DEC length counter
		dble	d1,.RepLoop
3$:
		tst.l	d0		; Linie fertig ? (Braucht's das tst??)
		bgt.b	1$		; noch nicht ---> Loop

		movem.l	(SP)+,d0/d2
		rts


		END