summaryrefslogtreecommitdiff
path: root/Source/PushChunk.S
blob: e645da995916bd1063cd7495dc362253797bd7a7 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
**
**	$Id: PushChunk.S,v 21.1 92/05/15 03:24:41 chris Exp $
**	$Revision: 21.1 $
**
**	$Filename: PushChunk.S $
**	$Author: chris $
**	$Date: 92/05/15 03:24:41 $
**
**	iff.library/IFFL_PushChunk
**
**	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_PushChunk
		SECTION	text,CODE

		INCLUDE	"IffLib.i"

		XREF	SetError,ClearError
		XDEF	PushChunkFunc


******* iff.library/IFFL_PushChunk ******************************************
*
*    NAME
*	IFFL_PushChunk -- Push a new context node on the context stack.
*
*    SYNOPSIS
*	success = IFFL_PushChunk( iff, type, id )
*	D0                        A0   D0    D1
*
*	BOOL IFFL_PushChunk( IFFL_HANDLE, ULONG, ULONG )
*
*    FUNCTION
*	Pushes a new context node on the context stack by reading it from the
*	stream if this is a read file, or by creating it from the passed
*	parameters if this is a write file.  Normally this function is only
*	called in write mode, where the type and id codes specify the new
*	chunk to create.  If this is a leaf chunk, i.e. a local chunk inside
*	a FORM or PROP chunk, then the type argument is ignored.
*
*    INPUTS
*	iff  - IFF handle
*	type - chunk type specifier (ex. ILBM) (ignored for read mode or
*	       leaf chunks).
*	id   - chunk id specifier (ex. CMAP) (ignored for read mode).
*
*    RESULTS
*	Non-zero if successful or 0 if not successful (call IFFL_IFFError()
*	to get an IFFL_ERROR_... error code.
*
*    NOTE
*       Currently, the level of nested FORMs is restricted to 7.
*
*    SEE ALSO
*	IFFL_PopChunk(), IFFL_WriteChunkBytes()
*
*****************************************************************************

PushChunkFunc:	movem.l	d0-d3/a2/a5-a6,-(SP)	; D0 auch (siehe unten!)
		movea.l	a6,a5			; IFFBase für ClearError()
		movea.l	a0,a2			; A2 :  IFF-Handle
		movea.l	iffb_DOSBase(a5),a6	; A6 :  DOSBase

	*** File-Type schreiben falls das FORM leer ist

		tst.l	ifffh_ChunkSize(a2)	; 1. Chunk ?
		bne.b	.NotFirstChunk		; nee --->

		move.l	ifffh_File(a2),d1	; Filehandle
		move.l	SP,d2			; Typ (D0) aufm Stack von MOVEM her
		moveq.l	#4,d3			; Länge: 1 Langwort
		JSRLIB	Write
		cmp.l	d3,d0			; OK geschrieben ?
		bne.b	.WriteError
		add.l	d3,ifffh_ChunkSize(a2)	; FORM-Grösse anpassen
.NotFirstChunk:

	*** Chunk-Stack eins nach oben rutschen

		lea	iffh_CStackEnd(a2),a1	; Destination
		lea	-8(a1),a0		; Source
		moveq	#(iffh_CStackEnd-iffh_CStack-8)/4-1,d0
.StackUp:	move.l	-(a0),-(a1)
		dbf	d0,.StackUp

	*** Chunk im IFF-Handle initialisieren

		clr.l	ifffh_ChunkSize(a2)	; Chunk-Grösse resetten

		move.l	ifffh_File(a2),d1
		moveq.l	#0,d2			; Aktuelle Position
		moveq.l	#OFFSET_CURRENT,d3
		JSRLIB	Seek
		move.l	d0,ifffh_ChunkFPos(a2)	; Chunk-Position eintragen
		bmi.b	.SeekError		; Error --->

	*** ID und provisorische Länge schreiben

		move.l	ifffh_File(a2),d1
		lea	4(SP),a0
		move.l	a0,d2			; Chunk-ID und 1 LONG garbage
		moveq.l	#8,d3			; ID und provisorische Länge
		JSRLIB	Write
		cmp.l	d3,d0			; OK geschrieben ?
		bne.b	.WriteError

	*** Okay

		bsr	ClearError		; Setzt auch D0 auf TRUE
		bra.b	.End

	*** Schreibfehler oder Seekfehler

.SeekError:
.WriteError:	moveq.l	#IFFL_ERROR_WRITE,d0
		bsr	SetError		; Setzt auch D0 auf FALSE

	*** Routine beenden

.End:		move.l	d0,(SP)			; D0 in Stack (--> wieder D0)
		movem.l	(SP)+,d0-d3/a2/a5-a6
		rts


		END