diff options
| author | Christian A. Weber <chris@gna.ch> | 1992-05-18 02:16:29 +0000 | 
|---|---|---|
| committer | Christian A. Weber <chris@gna.ch> | 1992-05-18 02:16:29 +0000 | 
| commit | fd511a54203c311434a04a58d377545566728833 (patch) | |
| tree | 2eabf5c3517e80e407ff89c884dcd96cd462a46b | |
| parent | c1e64671473be2fa467fe2e2063226bc5cd3bebf (diff) | |
| download | iff-library-fd511a54203c311434a04a58d377545566728833.tar.gz iff-library-fd511a54203c311434a04a58d377545566728833.tar.bz2 iff-library-fd511a54203c311434a04a58d377545566728833.zip | |
Total neu geschrieben. I/O ist jetzt gebuffert, und benutzt die neuen
PushChunk/WriteChunkBytes/PopChunk-Routinen.
Braucht jetzt nur noch etwa 100 Bytes Stack statt 650.
Farben der CMAP werden jetzt richtig berechnet (*17 statt geshiftet).
| -rw-r--r-- | Source/SaveClip.S | 681 | 
1 files changed, 271 insertions, 410 deletions
| diff --git a/Source/SaveClip.S b/Source/SaveClip.S index ecc4925..f8e81ad 100644 --- a/Source/SaveClip.S +++ b/Source/SaveClip.S @@ -1,11 +1,11 @@  ** -**	$Id: SaveClip.S,v 1.1 92/05/12 22:26:45 chris Exp $ -**	$Revision: 1.1 $ +**	$Id: SaveClip.S,v 21.1 92/05/15 03:22:11 chris Exp $ +**	$Revision: 21.1 $  **  **	$Filename: SaveClip.S $  **	$Author: chris $  **	$Release: 19.1 $ -**	$Date: 92/05/12 22:26:45 $ +**	$Date: 92/05/15 03:22:11 $  **  **	iff.library/IFFL_SaveClip  ** @@ -54,14 +54,14 @@  *	height      - height in lines of the rectangle  *  *    RESULTS -*	Non-zero if successful, 0 if error, Call IFFL_IFFError() to -*	know more about the reason of the failure +*	Non-zero if successful, 0 if an error occurred. You can then call +*	IFFL_IFFError() to know more about the reason of the failure.  *  *    NOTE -*	This routine needs 650 bytes of stack space +*	Up to V19 this routine needs at least 650 bytes of stack space  *  *    BUGS -*	The width of the rectangle will be rounded to WORD boundaries, +*	The width of the rectangle will be truncated to WORD boundaries,  *	because DPAINT wants it!  *  *    SEE ALSO @@ -69,423 +69,284 @@  *  ***************************************************************************** -MAXPLANES:	EQU	24			; Höchstens 24 Bitplanes +MAXPLANES	EQU	32			; Höchstens 32 Bitplanes +BUFFERSIZE	EQU	10240			; Write-Buffer +BUFFERFULL	EQU	BUFFERSIZE-2048		; naja... -iffhd:		equ	0			; FORM -iffsize:	equ	4			; .... ILBM +   STRUCTURE Stack,0 +	STRUCT	stk_BMHD,bmh_SIZEOF		; Muss am Anfang sein +	ULONG	stk_CAMG +	STRUCT	stk_Planes,4*MAXPLANES +	LABEL	stk_SIZEOF -bmhdchunk:	equ	iffsize+8		; BMHD -bmhdsize:	equ	bmhdchunk+4		; .... -bmhd:		equ	bmhdsize+4		; bmhd-Struktur - -camgchunk:	equ	bmhd+bmh_SIZEOF		; CAMG -camgsize:	equ	camgchunk+4		; .... -camg:		equ	camgsize+4		; 0000ViewModes - -cmapchunk:	equ	camg+4			; CMAP -cmapsize:	equ	cmapchunk+4		; .... -cmap:		equ	cmapsize+4		; Farbwerte - -bodychunk:	equ	cmap+(3*512)		; BODY -bodysize:	equ	bodychunk+4		; .... +SaveClipFunc:	movem.l	d2-d7/a2-a6,-(SP) +		suba.w	#stk_SIZEOF,SP		; Platz schaffen +		move.l	d0,d6			; D6 :  Flags +		move.l	a2,d5			; D5 :  Farbtabelle oder NULL +		move.l	a0,a2			; A2 :  Filename +		movea.l	a6,a5			; A5 :  IFFBase +		movea.l	a1,a4			; A4 :  BitMap -xoffset:	equ	bodysize+4 -yoffset:	equ	xoffset+2 -width:		equ	yoffset+2 -height:		equ	width+2 +	*** BMHD erstellen auf dem Stack und Parameter eintragen -sb_datasize:	equ	height+2		; Gesamt-Datengrösse +		andi.w	#15,d0			; A rough guess :-) +		move.b	d0,bmh_Compression(SP) +		lsl.w	#3,d1			; Aus Bytes mach Pixel +		movem.w	d1/d2,bmh_XPos(SP)	; X und Y-Position -SaveClipFunc:	movem.l	d2-d7/a2-a6,-(SP) -		suba.w	#sb_datasize,SP		; Speicher reservieren -		movea.l	a6,a5			; IFFBase -		move.l	a0,d6			; D6 :  Filename -		movea.l	a1,a3			; A3 :  BitMap -		movea.l	SP,a4			; A4 :  wird BitMapHeader - -		move.w	d1,xoffset(SP) -		move.w	d2,yoffset(SP)  		bclr	#0,d3			; Breite WORD align für DPaint -		move.w	d3,width(SP) -		move.w	d4,height(SP) - -	*** FORM....ILBM-Header & BMHD-Chunk initialisieren (im Speicher) - -		move.l	#'FORM',(a4)+		; Ein IFF-Formular -		moveq.l	#cmap,d7		; 'ILBM'+BMHD+CAMG+CMAP+BODY -		move.l	d7,(a4)+		; eintragen -		move.l	#'ILBM',(a4)+		; File-Typ - -		move.l	#'BMHD',(a4)+		; Chunk-Name eintragen -		moveq.l	#bmh_SIZEOF,d7 -		move.l	d7,(a4)+		; Chunk-Size eintragen -		move.b	d0,bmh_Compression(a4)	; Cruncher-Typ merken - -		clr.b	bmh_Masking(a4) -		clr.b	bmh_Pad1(a4) -		clr.w	bmh_TranspCol(a4) -		move.w	xoffset(SP),d0 -		lsl.w	#3,d0			; Pixel -		move.w	d0,bmh_XPos(a4)		; X-Position -		move.w	yoffset(SP),bmh_YPos(a4) ; X-Position -		move.w	#$0A0B,bmh_XAspect(a4)	; X- und Y-Aspect zusammen! -		move.b	bm_Depth(a3),bmh_nPlanes(a4) - -		lsl.w	#3,d3			; Breite mal 8 -		move.w	d3,bmh_Width(a4)	; gibt Breite in Pixel -		move.w	d3,bmh_PageWidth(a4) - -		move.w	d4,bmh_Height(a4)	; Bildhöhe eintragen -		move.w	d4,bmh_PageHeight(a4) - -	*** CAMG-Chunk generieren (immer) - -		move.l	#'CAMG',camgchunk(SP)	; Chunk-Name -		moveq	#4,d7 -		move.l	d7,camgsize(SP)		; Chunk-Size -		movea.l	a4,a0			; struct BitMapHeader -		bsr	CalcViewModes		; ViewModes nach d0 -		bclr.b	#7,bmh_Compression(a4)	; HAM gewünscht ? -		beq.s	1$			; nein ---> -		bset	#11,d0			; HAM-Bit setzen -1$:		move.l	d0,camg(SP)		; ViewModes eintragen - -	*** CMAP-Chunk generieren, falls notwendig (im Speicher) - -		move.l	#-8,cmapsize(SP)	; falls no CMAP: -'CMAP....' - -		move.l	a2,d0			; tst.l a2 -		beq.s	nocmap - -		lea	cmapchunk(SP),a1	; Hierhin will ich den Chunk -		move.l	#'CMAP',(a1)+		; Chunkname -		moveq	#1,d0 -		moveq	#0,d1 -		move.b	bm_Depth(a3),d1 -		cmpi.b	#24,d1			; Ist's ein 24-Bitplane-Bild ? -		bne.s	.No24			; nein ---> -		moveq	#8,d1			; Sonst immer 256 Farben +		lsl.w	#3,d3			; Aus Bytes mach Pixel +		movem.w	d3/d4,bmh_Width(SP)	; Breite und Höhe +		movem.w	d3/d4,bmh_XAspect(SP)	; Aspect ratio + +		move.w	bm_BytesPerRow(a4),d0 +		lsl.w	#3,d0 +		move.w	d0,bmh_PageWidth(SP) +		move.w	bm_Rows(a4),bmh_PageHeight(SP) + +		move.w	bm_Depth(a4),bmh_nPlanes(SP) + +		clr.b	bmh_Masking(SP) +		clr.b	bmh_Pad1(SP) +		clr.w	bmh_TranspCol(SP) + +	*** Puffer für Body-Daten (und CMAP) allozieren + +		moveq.l	#IFFL_ERROR_NOMEM,d4	; D4 :  Default-Error-Code +		move.l	#BUFFERSIZE,d0 +		moveq.l	#MEMF_PUBLIC,d1		; No VMem! :-) +		movea.l	iffb_SysBase(a5),a6 +		JSRLIB	AllocMem +		tst.l	d0 +		beq	.NoMemory +		movea.l	d0,a3			; A3 :  Buffer + +	*** IFF-File zum Schreiben öffnen + +		moveq.l	#IFFL_ERROR_WRITE,d4	; D4 :  Default-Error-Code +		movea.l	a2,a0			; Filename +		moveq.l	#IFFL_MODE_WRITE,d0 +		movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_OpenIFF +		tst.l	d0 +		beq	.OpenError +		movea.l	d0,a2			; A2 :  IFF-Handle + +	*** BMHD-Chunk schreiben + +		move.l	#ID_ILBM,d0 +		move.l	#ID_BMHD,d1 +		moveq.l	#bmh_SIZEOF,d2 +		movea.l	SP,a1			; BMHD-Struktur +		bsr	WriteChunk +		beq	.WriteError + +	*** CAMG-Chunk generieren + +		movea.l	SP,a0			; BMHD-Struktur +		bsr	CalcViewModes		; ViewModes nach D0 + +		btst.l	#7,d6			; HAM gewünscht ? +		beq.b	.NoHAM			; nein ---> +		bset.l	#11,d0			; HAM-Bit setzen +.NoHAM:		move.l	d0,stk_CAMG(SP)		; ViewModes auf Stack + +	*** CAMG-Chunk schreiben + +	;;	move.l	#ID_ILBM,d0 +		move.l	#ID_CAMG,d1 +		moveq.l	#4,d2			; 1 LONG +		lea	stk_CAMG(SP),a1		; CAMG-Langwort +		bsr	WriteChunk +		beq	.WriteError + +	*** CMAP-Chunk generieren und schreiben, falls notwendig + +		tst.l	d5			; CMAP vorhanden ? +		beq	.NoCMap			; nein ---> + +		moveq.l	#0,d0 +		move.b	bm_Depth(a4),d0		; Anzahl Planes +		cmpi.b	#8,d0			; Mehr als 256 Farben (z.b. 24 bit)? +		blo.b	.No24			; nein ---> +		moveq	#8,d0			; Sonst maximal 256 Farben  .No24: -		lsl.w	d1,d0			; d0 := 2 ^ D1 = Anzahl Farben -		move.w	d0,d2			; D2 : Anzahl Farben -		mulu.w	#3,d0			; 3 Bytes pro Farbe -		addq.l	#2,d0 -		andi.w	#~3,d0			; auf LONG alignen -		move.l	d0,(a1)+		; Chunklänge - -		subq.w	#1,d2			; für dbf -3$:		move.w	(a2)+,d0 -		lsl.w	#4,d0 -		move.b	d0,2(a1)		; blau -		lsr.w	#4,d0 -		andi.b	#$f0,d0 -		move.b	d0,1(a1)		; grün -		lsr.w	#4,d0 -		andi.b	#$f0,d0 -		move.b	d0,(a1)			; rot -		addq.w	#3,a1 -		dbf	d2,3$ - -	*** File öffnen, IFF-Header auf Disk schreiben (vorläufig!) - -nocmap:		move.l	d6,d1			; FileName -		move.l	#MODE_NEWFILE,d2 -		movea.l	iffb_DOSBase(a5),a6 -		JSRLIB	Open -		move.l	d0,d7			; D7 :  FileHandle -		beq	writeerror - -		move.l	cmapsize(SP),d0		; CMAP-Grösse -		add.l	d0,iffsize(SP)		; zu Header-Grösse dazu - -		move.l	d7,d1			; File -		move.l	SP,d2			; Adr :  IFF-Header -		moveq	#cmap+8,d3		; Länge des Headers + 8 -		add.l	cmapsize(SP),d3		; Plus Länge des CMAP-Chunks -		JSRLIB	Write			; schreiben -		tst.l	d0			; Fehler ? -		bmi.s	writeerror		; ja! - -	*** BODY-Daten schreiben, evtl. komprimiert - -		tst.b	bmh_Compression(a4)	; compacten ? -		bne.s	1$			; ja! -		bsr	VanillaSave -		bra.s	2$ -1$:		bsr	CrunchSave -2$:		tst.l	d0			; Fehler ? -		bmi.s	writeerror		; ja! - -		move.l	d0,d3			; Body-Länge -		addq.l	#3,d3			; auf nächstes LONG aufrunden -		and.b	#%11111100,d3		; und LONG-alignen -		move.l	d3,bodysize(SP)		; aligned BODY-Grösse -		add.l	d3,iffsize(SP)		; zu Header-Grösse dazu -		sub.l	d0,d3			; D3 := Wieviele Bytes zuviel - -		tst.l	d3			; Align-Grösse = 0 ? -		beq.s	3$			; ja -> nichts schreiben -		move.l	d7,d1			; File -		clr.l	-(SP)			; Nullen machen -		move.l	SP,d2			; adr -		JSRLIB	Write			; schreiben -		addq.l	#4,SP			; Stack cleanen -		tst.l	d0			; Fehler ? -		bmi.s	writeerror		; ja! - -	*** IFF-Header nochmals schreiben & BODY-Header, diesmal korrekt - -3$:		move.l	d7,d1			; File -		moveq.l	#0,d2			; Position -		moveq.l	#OFFSET_BEGINNING,d3	; Modus -		JSRLIB	Seek - -		move.l	d7,d1			; File -		move.l	SP,d2			; Adr :  IFF-Header -		moveq.l	#cmap,d3		; Länge des Headers -		add.l	cmapsize(SP),d3		; Plus Länge des CMAP-Chunks -		JSRLIB	Write			; schreiben -		tst.l	d0			; Fehler ? -		bmi.s	writeerror		; ja! - -		lea	bodychunk(SP),a0 -		move.l	#'BODY',(a0)		; Chunk-Namen eintragen -		move.l	d7,d1			; File -		move.l	a0,d2			; Adr -		moveq	#8,d3			; Len -		JSRLIB	Write			; Body-Header schreiben -		tst.l	d0			; Fehler ? -		bmi.s	writeerror		; ja! - -		move.l	d7,d1			; File -		JSRLIB	Close -	;;	moveq.l #0,d7			; File ungültig - -		bsr	ClearError		; Error löschen, D0 := 1 -		bra.s	SaveClip_End - -writeerror:	move.l	d7,d1			; File -		beq.s	1$			; schon / nochzu! -		JSRLIB	Close -1$:		moveq	#IFFL_ERROR_WRITE,d0 +		moveq.l	#1,d1			; Bit-Maske zum Shiften +		lsl.w	d0,d1			; D1 := 2^D0 = Anzahl Farben +		move.l	d1,d2			; D2 :  Anzahl Farben + +		movea.l	d5,a0			; Amiga-Farbpalette +		movea.l	a3,a1			; Destination-Buffer +		bra.b	.CMapDBF		; ---> für DBF +.CMapLoop:	move.w	(a0),d0 +		lsr.w	#8,d0			; Rot-Anteil +		mulu.w	#17,d0			; aus 0n mach nn +		move.b	d0,(a1)+ + +		move.w	(a0),d0 +		lsr.w	#4,d0			; Grün-Anteil +		andi.w	#15,d0 +		mulu.w	#17,d0			; aus 0n mach nn +		move.b	d0,(a1)+ + +		move.w	(a0)+,d0 +	;;	lsr.w	#0,d0			; Blau-Anteil +		andi.w	#15,d0 +		mulu.w	#17,d0			; aus 0n mach nn +		move.b	d0,(a1)+ + +.CMapDBF:	dbf	d1,.CMapLoop + +	;;	move.l	#ID_ILBM,d0 +		move.l	#ID_CMAP,d1 +		mulu.w	#3,d2			; 3 Bytes pro Farbe gibt Size +		movea.l	a3,a1			; CMAP-Daten +	;;	movea.l	a5,a6			; IFFBase +		bsr	WriteChunk +		tst.l	d0 +		beq	.WriteError +.NoCMap: + +	*** BODY-Chunk eröffnen + +		movea.l	a2,a0			; IFF-Handle +	;;	move.l	#ID_ILBM,d0 +		move.l	#ID_BODY,d1 +		movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_PushChunk +		tst.l	d0 +		beq	.WriteError + +	*** PlanePtrs auf den Stack kopieren & X,Y-Offsets dazuaddieren + +		moveq.l	#0,d0			; D1 nicht nötig wegen mulu +		movem.w	bmh_XPos(SP),d0/d1	; X- und Y-Offset +		lsr.w	#3,d0			; X: aus Pixel mach Bytes +		mulu.w	bm_BytesPerRow(a4),d1	; Y mal Bildbreite +		add.l	d0,d1			; D1 :  Total-Offset + +		lea	bm_Planes(a4),a0	; Source +		lea	stk_Planes(SP),a1	; Destination +		moveq.l	#MAXPLANES-1,d2		; Alle PlanePtrs (naja...) +.CopyPlanes:	move.l	(a0)+,d0		; PlanePtr +		add.l	d1,d0			; Offset dazu +		move.l	d0,(a1)+		; speichern +		dbf	d2,.CopyPlanes + +	*** Tada! BODY-Daten schreiben + +		movem.w	bmh_Width(SP),d3/d4	; Breite & Höhe +		lsr.w	#3,d3			; D3 : Bytes per row to write +		moveq.l	#0,d5 +		move.b	bm_Depth(a4),d5 +		subq.w	#1,d5			; D5 : Depth-1 (für dbf) +		move.w	bm_BytesPerRow(a4),d6	; D6 : BytesPerRow der BitMap +		moveq.l	#0,d7			; D7 : Buffer-Füllstand +		bra.b	.RowDBF + +.RowLoop:	lea	stk_Planes(SP),a4	; A4 :  Plane-Array +		move.l	d5,d2			; Depth-1 + +.PlaneLoop:	cmpi.w	#BUFFERFULL,d7		; Zeit den Puffer zu leeren ? +		blo.b	.NoDump			; noch nicht ---> +		movea.l	a2,a0			; IFF-Handle +		movea.l	a3,a1			; Buffer +		move.l	d7,d0			; Len +	;;	movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_WriteChunkBytes +		tst.l	d0 +		beq.b	.WriteError +		moveq.l	#0,d7			; Buffer ist wieder leer +.NoDump: +		movea.l	(a4),a0			; Source: Nächste Linie/Plane +		lea	0(a3,d7.l),a1		; Destination: Buffer +		move.l	d3,d0			; Len +		moveq.l	#0,d1 +		move.b	bmh_Compression(SP),d1 +	;;	movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_CompressBlock +		tst.l	d0 +		beq.b	.WriteError +		add.l	d0,d7			; Buffersize += komprimierte Länge +		add.l	d6,(a4)+		; auf nächste Linie + +		dbf	d2,.PlaneLoop		; ---> Loop +.RowDBF:	dbf	d4,.RowLoop		; ---> Loop + +	*** Buffer ein letztes Mal leeren + +		movea.l	a2,a0			; IFF-Handle +		movea.l	a3,a1			; Buffer +		move.l	d7,d0			; Len +	;;	movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_WriteChunkBytes +		tst.l	d0 +		beq.b	.WriteError + +	*** BODY-Chunk abschliessen + +		movea.l	a2,a0			; IFF-Handle +	;;	movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_PopChunk +		tst.l	d0 +		beq.b	.WriteError + +		moveq.l	#0,d4			; D4 :  Error-Code: OK!! + +	*** IFF-File schliessen + +.WriteError:	movea.l	a2,a1			; IFF-Handle +	;;	movea.l	a5,a6			; IFFBase +		JSRLIB	IFFL_CloseIFF + +	*** Buffer freigeben + +.OpenError:	move.l	#BUFFERSIZE,d0 +		movea.l	a3,a1 +		movea.l	iffb_SysBase(a5),a6 +		JSRLIB	FreeMem + +	*** Fehlerkode setzen falls nötig + +.NoMemory:	move.l	d4,d0			; Error ? +		beq.b	.Okay			; noe --->  		bsr	SetError		; Error setzen, D0 := 0 +		bra.b	.End +.Okay:		bsr	ClearError -SaveClip_End:	adda.w	#sb_datasize,SP		; Speicher wirder freigeben -		movem.l	(SP)+,d2-d7/a2-a6 -		rts - +	*** Routine beenden -*************************************************************************** -**************  V A N I L L A S A V E  ************************************ -*************************************************************************** - -vs_planes:	equ	0			; ARRAY[0..MAXPLANES-1] OF PlanePtr -vs_chunksize:	equ	vs_planes+4*MAXPLANES -vs_linksize:	equ	vs_chunksize+4 - -VanillaSave:	movem.l	d2-d6/a2-a4,-(SP)	; 8 Register retten -		lea	8*4+4(SP),a4		; A4 : Global data Ptr -		suba.w	#vs_linksize,SP		; lokalen Datenraum schaffen - -	*** Chunk-Grösse berechnen und merken - -		move.w	width(a4),d0		; Breite in Bytes -		moveq	#0,d1 -		move.b	bm_Depth(a3),d1 -		mulu	d1,d0			; mal Anzahl Planes -		move.w	height(a4),d1 -		mulu	d1,d0			; mal Anzahl Linien -		move.l	d0,vs_chunksize(SP)	; merken - -	*** PlanePtrs kopieren & X,Y-Offsets dazuaddieren - -		move.w	yoffset(a4),d1		; Y-Offset im Bild -		mulu	bm_BytesPerRow(a3),d1	; mal Bildbreite -		moveq	#0,d0 -		move.w	xoffset(a4),d0 -		add.l	d0,d1			; plus X-Offset - -		lea	bm_Planes(a3),a0	; Source -		move.l	SP,a1			; Destination -		moveq	#MAXPLANES-1,d0		; Alle PlanePtrs -1$:		move.l	(a0)+,d2		; PlanePtr -		add.l	d1,d2			; Offset dazu -		move.l	d2,(a1)+		; speichern -		dbf	d0,1$ - -		moveq	#0,d3 -		moveq	#0,d4 -		moveq	#0,d5 -		move.w	bm_BytesPerRow(a3),d5	; D5 : BytesPerRow (linesize) -		move.b	bm_Depth(a3),d3		; move.b ea,Ax geht ja nicht -		move.w	d3,a3			; A3 : Depth (lieber D8 als A3) -		move.w	width(a4),d3		; D3 : BytesPerRow (to write) -		move.w	height(a4),d4		; D4 : Rows (to write) - -		subq.w	#1,d4			; für dbf -		subq.w	#1,a3			; für dbf -vs_loop1:	movea.l	SP,a2			; Zeiger auf Planes -		move.l	a3,d6			; d6 : Depth für dbf - -vs_loop2:	move.l	d7,d1			; File -		move.l	(a2),d2			; Adr  : Nächste Linie/Plane -		JSRLIB	Write			; (len ist schon in D3) -		tst.l	d0			; Fehler ? -		bmi.s	vs_error		; ja! -		add.l	d5,(a2)+		; auf nächste Linie -		dbf	d6,vs_loop2		; next plane -		dbf	d4,vs_loop1		; next row - -		move.l	vs_chunksize(SP),d0	; Return-Wert: Chunk-Länge -vs_error:	adda.w	#vs_linksize,SP		; Datenraum freigeben -		movem.l	(SP)+,d2-d6/a2-a4 -		rts - - -*************************************************************************** -**************  C R U N C H S A V E  ************************************** -*************************************************************************** - -cs_planes:	equ	0			; ARRAY[0..MAXPLANES-1] OF PlanePtr -cs_buffer:	equ	cs_planes+4*MAXPLANES	; ARRAY[0..511] OF BYTE -cs_bodysize:	equ	cs_buffer+512		; LONG bodysize -cs_linksize:	equ	cs_bodysize+4 - -CrunchSave:	movem.l	d2-d6/a2-a4,-(SP)	; 8 Register retten -		lea	8*4+4(SP),a4		; A4 : Global data Ptr -		suba.w	#cs_linksize,SP		; lokalen Datenraum schaffen - -		clr.l	cs_bodysize(SP) - -	*** PlanePtrs kopieren & X,Y-Offsets dazuaddieren - -		move.w	yoffset(a4),d1		; Y-Offset im Bild -		mulu	bm_BytesPerRow(a3),d1	; mal Bildbreite -		moveq	#0,d0 -		move.w	xoffset(a4),d0 -		add.l	d0,d1			; plus X-Offset - -		lea	bm_Planes(a3),a0	; Source -		movea.l	SP,a1			; Destination (unsauber!) -		moveq	#MAXPLANES-1,d0		; Alle Planeptrs -1$:		move.l	(a0)+,d2		; PlanePtr -		add.l	d1,d2			; Offset dazu -		move.l	d2,(a1)+		; speichern -		dbf	d0,1$ - -		moveq	#0,d3 -		moveq	#0,d4 -		moveq	#0,d5 -		move.w	bm_BytesPerRow(a3),d5	; D5 : BytesPerRow (linesize) -		move.b	bm_Depth(a3),d3		; move.b ea,Ax geht ja nicht -		move.l	d3,a3			; A3 : Depth (lieber D8 als A3) -		move.w	width(a4),d3		; D3 : BytesPerRow (to write) -		move.w	height(a4),d4		; D4 : Rows (to write) - -		subq.w	#1,d4			; für dbf -		subq.l	#1,a3			; für dbf - -cs_loop1:	move.l	SP,a2			; PlanePtr -		move.l	a3,d6			; d6 : Depth für dbf - -cs_loop2:	move.w	d3,d0			; Len für CrunchRow() -		move.l	(a2),a0			; Source für CrunchRow() -		lea	cs_buffer(SP),a1	; Destination für CrunchRow() -		bsr.s	CrunchRow -		add.l	d0,cs_bodysize(SP)	; für calcbodysize() - -		move.l	d7,d1			; File -		lea	cs_buffer(SP),a1	; Daten-Puffer -		move.l	a1,d2			; Adr :  cs_buffer(SP) -		move.l	d3,-(SP) -		move.l	d0,d3			; Länge, von CrunchRow() -		JSRLIB	Write -		move.l	(SP)+,d3 -		tst.l	d0			; Fehler ? -		bmi.s	cs_error		; ja! - -		add.l	d5,(a2)+		; auf nächste Linie -		dbf	d6,cs_loop2		; next plane -		dbf	d4,cs_loop1		; next row - -		move.l	cs_bodysize(SP),d0	; return-value -cs_error:	adda.w	#cs_linksize,SP		; Speicher freigeben -		movem.l	(SP)+,d2-d6/a2-a4 +.End:		adda.w	#stk_SIZEOF,SP		; Stack aufräumen +		movem.l	(SP)+,d2-d7/a2-a6  		rts -********************************************************************* -**                                                                 ** -**   C R U N C H R O W  -  eine Zeile CmpByteRun1 crunchen         ** -**                                                                 ** -**   Parameter :  A0.L :  Zeiger auf Source-Adresse in Plane       ** -**                A1.L :  Zeiger auf Destination-Buffer            ** -**                D0.W :  Anzahl Bytes einer Source-Linie          ** -**   Resultat  :  D0.L :  Anzahl gecrunchte Bytes                  ** -**                                                                 ** -********************************************************************* - -CrunchRow:	movem.l	d2-d3/a2-a3,-(SP) -		lea	(a0,d0.w),a2	; A2 : Source-Endadresse der Linie -		moveq	#0,d3		; Byte-Zähler - -crunchloop:	bsr.s	CountEq		; wieviele gleiche Bytes folgen ? -		cmp.w	#3,d0		; genug gleiche Bytes zum runnen ? -		blt.s	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.s	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.s	2$		; höchstens 127 Bytes pro Block -		addq.l	#1,a0 -		cmpa.l	a2,a0		; Ende der Linie erreicht ? -		bge.s	3$		; ja -> abbrechen -		bsr.s	CountEq -		cmp.w	#3,d0		; Ende des Dump-Blocks ? -		blt.s	1$		; noch nicht -		bra.s	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.s	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.s	3$		; nein -> abbrechen -		cmp.w	#128,d0 -		bge.s	3$		; höchstens 128 gleiche -		addq.w	#1,d0		; Anzahl erhöhen -		cmpa.l	a2,a0		; Ende der Linie erreicht ? -		blt.s	2$		; noch nicht -> weiterzählen -3$:		move.l	(SP)+,a0 -		rts +***************************************************************************** +**	Chunk in File schreiben: +**	A1=Adresse, A2=Handle, D0=TYPE, D1=ID, D2=Size, A6=IFFBase +**	Zerstört D0/D1/A0/A1. +**	Resultat: D0>0 und Z=0 falls OK, D0=0 und Z=1 falls Error + +WriteChunk:	move.l	a1,-(SP)		; Adresse retten +		movea.l	a2,a0			; IFF-Handle +		JSRLIB	IFFL_PushChunk +		movea.l	(SP)+,a1 +		tst.l	d0 +		beq.b	.Error + +		movea.l	a2,a0			; IFF-Handle +		move.l	d2,d0			; Grösse +		JSRLIB	IFFL_WriteChunkBytes +		tst.l	d0 +		beq.b	.Error + +		movea.l	a2,a0			; IFF-Handle +		JSRLIB	IFFL_PopChunk +		tst.l	d0 +	;;	beq.b	.Error + +.Error:		rts  		END | 
