**************************************************************************
*                                                                        *
*       DeCompress -  routine di interfacciamento con AmigaBASIC         *
*       permette di velocizzare il caricamento di files IFF ILBM         *
*                                                                        *
*       Autore: Paolo Bozzo, via Bolzano 23 - Milano.                    *
*	giugno-luglio 1989	- 	versione 1.0			 *
*	sviluppata con HiSoft DevPac             			 *
*                                                                        *
**************************************************************************

* macro che permette di tenere sotto controllo lo stato del buffer

control	MACRO
	dbra	d4,\1
	bsr.s	ReadData
	IFEQ	NARG-3
	subq.l	#1,\3
	ENDC
	bra.s	\2
	ENDM

* macro che decrementa il contatore in d7

DecCnt	MACRO
	sub.w	d0,d7
	subq.w	#1,d7
	ENDM


	section	code,code

DeCompress:
	movem.l	d0-d7/a0-a6,-(SP)
	move.l	(4).w,a6		;ExecBase

	moveq.l	#0,d0
	lea	dosname(PC),a1
	jsr	-552(a6)		;OpenLibrary(dosname,0)
	move.l	d0,a6			;DosBase
	beq.s	exit

	moveq.l	#0,d4			;d4 dev'essere a zero
	
	move.l	68(SP),a2		;bPlane&() = array pointer
	move.l	96(SP),a3		;error pointer

	move.l	72(SP),d5		;iHeight%-1
	moveq.l	#0,d2

back	move.l	76(SP),d6		;iDepth%-1
	moveq.l	#0,d3

MainLoop				;ciclo annidato di controllo
	move.l	80(SP),d0		;scrRowBytes% in d0
	move.l	84(SP),d7		;iRowBytes%   in d7
	mulu	d2,d0
	add.l	0(a2,d3.l),d0
	move.l	d0,a5			;scrRow& in a5

******* algoritmo di decompressione ByteRun1 *************************
*                                                                    *
* ora abbiamo:                                                       *
* buffer (=sorgente) in a4                                           *
* scrRow& (=destinazione) in a5                                      *
*                                                                    *
**********************************************************************

loop	move.b	(a4)+,d0		;prendi il byte-chiave 'n'
	control	jmp0,loop		;controlla buffer
jmp0	ext.w	d0			;estensione a word con segno (n)
	bmi.s	replic			;se negativo vai a replic
	DecCnt 				;sistema contatore
copy	move.b	(a4)+,(a5)+		;copia alla lettera n+1 bytes
	control	jmp1,copy,a5		;controlla buffer
jmp1	dbra	d0,copy
next	tst.w	d7			;abbiamo finito?
	bne.s	loop			;se no, ricicla

******* se sì, continuiamo con il ciclo di controllo MainLoop ********

	addq.l	#4,d3
	dbra	d6,MainLoop		;[tutti i bitplanes?]

	addq.l	#1,d2
	dbra	d5,back			;[tutta l'immagine?]

close	move.l	a6,a1
	move.l 	(4).w,a6		
	jsr	-414(a6)		;CloseLibrary(DosBase)

exit	movem.l	(SP)+,d0-d7/a0-a6
	rts				;ritorna al basic

******* legge i dati e li mette nel buffer ********************

ReadData
	movem.l	d0-d3,-(SP)
	move.l	84(SP),d1		;fHandle&
	move.l	108(SP),d2		;picbuf&
	move.l	112(SP),d3		;picbufsize&
	jsr	-42(a6)			;Read(fHandle,buffer,BUFSIZE)
	move.l	d0,d4
	bmi.s	error			;se errore esci
	move.l	d2,a4			;buffer-pointer in a4
	movem.l	(SP)+,d0-d3
	rts

error	movem.l	(SP)+,d0-d3
	move.l	(SP)+,(SP)		;reset dello stack
	move.w	#-1,(a3)		;restituisce "errore"
	bra.s	close
	
	
******* se il byte 'n' (in d0) è negativo lo replica -n+1 volte	

replic	cmp.w	#-128,d0		;se n=-128,
	beq.s	next			;non fare nulla.
getc	move.b	(a4)+,d1		;in d1 byte da replicare
	control	jmp2,getc		;controlla buffer
jmp2	neg.w	d0			;rendi positivo 'n' 
	DecCnt				;sistema contatore
repeat	move.b	d1,(a5)+		;copia n+1 volte d1
	dbra	d0,repeat
	bra.s	next			
	

dosname	dc.b	'dos.library',0
		cnop 0,2

	END
