summaryrefslogtreecommitdiff
path: root/RAMLib.S
blob: 55c62de3727bc27cae0e5290bd0a5b81b0e1938f (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
****************************************************************************
**                                                                        **
**       R A M L I B  -  Automatisches FileBuffern                        **
**                                                                        **
****************************************************************************
**                                                                        **
**   Modification History                                                 **
**   --------------------                                                 **
**                                                                        **
**   20-Nov-90  CHH  Created this file                                    **
**   21-Nov-90  CHH  NoMemHandler eingebaut. Löscht erstes File in der    **
**                   Liste                                                **
**   11-Feb-91  CHH  BufReadFile eingebaut                                **
**                                                                        **
****************************************************************************

		IDNT	RAMLib
		SECTION	text,CODE


		XDEF	InitRAMLib
		XDEF	BufLoadFileFunc,DeleteFileNodeFunc
		XDEF	DeleteFileListFunc,MyNoMemHandler
		XDEF	BufReadFileFunc

		INCLUDE "myexec.i"

	     STRUCTURE  LoadEntry,0
		STRUCT	le_Node,ln_SIZEOF
		APTR	le_FileBuffer
		LONG	le_Len
		LABEL	le_SIZEOF


NT_DISKNODE:	EQU	$80
NT_RAMNODE:	EQU	$81

******************************************************************************

InitRAMLib:	lea	meb_FileList(a6),a0
		jsr	meb_NewList(a6)

		bset.b	#EXECB_BUFENABLE,meb_ExecFlags(a6)
		tst.l	meb_FastMRHeader+mh_Free(a6)
		bne.s	.EnoughRam
		cmp.l	#$80000,meb_ChipMRHeader+mh_Free(a6)
		bhi.s	.EnoughRam
		bclr.b	#EXECB_BUFENABLE,meb_ExecFlags(a6)
.EnoughRam:
		rts

******************************************************************************

	***  Ein File laden und im FastRam buffern

BufLoadFileFunc:
		btst.b	#EXECB_BUFENABLE,meb_ExecFlags(a6)
		bne.s	0$
		jmp	meb_LoadFile(a6)
0$:
		move.l	d0,ActName

	** Zuerst schauen ob File bereits in der Liste ist

		movem.l	d1-d7/a0-a4,-(SP)
		lea	meb_FileList(a6),a0
		move.l	lh_Head(a0),a0		; Ersten Eintrag holen
.SearchLoop:	tst.l	ln_Succ(a0)		; Listen-Ende ?
		beq	.NormLoad		; wenn ja -> File normal laden
		cmp.l	ln_Name(a0),d0		; gesuchter FileNode ?
		beq.s	.FileFound
		move.l	ln_Succ(a0),a0
		bra	.SearchLoop


.FileFound:	movea.l	a0,a3			; A3 : FileNode

		move.l	le_Len(a3),d0
		jsr	meb_AllocMem(a6)
		move.l	d0,a2


	** jetzt testen ob wir immer noch in der Liste sind 
	** (jaja, letztes AllocMem könnte uns rausgeschmissen haben)

		lea	meb_FileList(a6),a4
		move.l	lh_Head(a4),a4		; erster Node
.NochDrinLoop:	tst.l	ln_Succ(a4)		; kein Eintrag mehr ?
		beq	.NormLoad2		; wenn ja -> tja, wir wurden soeben entfernt und muessen das file nochmal laden
		cmp.l	a3,a4			; sind wir das ?
		beq.s	.NochDrin		; ja -> File aus Ram laden
		move.l	ln_Succ(A4),a4
		bra	.NochDrinLoop


.NochDrin:	move.l	le_FileBuffer(a3),a0	; A0 : RamAdresse
		move.l	a2,a1			; A1 : LadeAdresse
		move.l	le_Len(a3),d0		; D0 : FileLänge
		jsr	meb_CopyMem(a6)		; File aus Ram laden

		move.l	a2,d0			; D0 : Ergebnis

		movem.l	(SP)+,d1-d7/a0-a4
		rts


	** Den vergebens reservierten Speicher wieder freigeben

.NormLoad2:	movea.l	a2,a1
		jsr	meb_FreeMem(a6)


	** File normal laden

.NormLoad:	movem.l	(SP)+,d1-d7/a0-a4
		move.l	ActName,d0		; D0 : FileName
		jsr	meb_LoadFile(a6)	; File von Disk einladen

	** File in Liste einbinden

		movem.l	d0-d7/a0-a4,-(SP)
		move.l	d0,a2			; A2 : Zeiger auf geladenes File

		move.l	#le_SIZEOF,d0			; Platz für
		jsr	meb_AllocFastClearMem(a6)	; Node reservieren

		move.l	d0,a4			; a4 = Node

	** NodeType entspechend dem FileNamen festlegen (nur zum debugen)

		moveq.l	#NT_DISKNODE,d0
		tst.b	ActName			; Igitt! So nicht!
		bne.s	1$
		moveq.l	#NT_RAMNODE,d0
1$:		move.b	d0,ln_Type(a4)		; NodeType eintragen
		move.l	ActName,ln_Name(a4)	; FileName eintragen

		move.l	-4(a2),d0		; D0 : Länge des zu buffernden Files
		subq.l	#4,d0
		move.l	d0,le_Len(a4)

		jsr	meb_AllocFastMem(a6)	; Speicher dafür reservieren
		move.l	d0,le_FileBuffer(a4)
		move.l	d0,a3

		move.l	a2,a0			; File
		move.l	a3,a1			; in Buffer
		move.l	le_Len(a4),d0
		jsr	meb_CopyMem(a6)		; kopieren

		lea	meb_FileList(a6),a0	; FileNode
		move.l	a4,a1			; in Liste
		jsr	meb_Enqueue(a6)		; einbinden

		movem.l	(SP)+,d0-d7/a0-a4
		rts

******************************************************************************


	** D0 : FileName / A0 : Address

BufReadFileFunc:
		btst.b	#EXECB_BUFENABLE,meb_ExecFlags(a6)
		bne.s	0$
		jmp	meb_ReadFile(a6)
0$:
		move.l	d0,ActName

	** Zuerst schauen ob File bereits in der Liste ist

		movem.l	d1-d7/a0-a4,-(SP)
		move.l	a0,a1
		lea	meb_FileList(a6),a0
		move.l	lh_Head(a0),a0		; Ersten Eintrag holen
.SearchLoop:	tst.l	ln_Succ(a0)		; Listen-Ende ?
		beq	.NormLoad		; wenn ja -> File normal laden
		cmp.l	ln_Name(a0),d0		; gesuchter FileNode ?
		beq.s	.FileFound
		move.l	ln_Succ(a0),a0
		bra	.SearchLoop


.FileFound:	movea.l	a0,a3			; A3 : FileNode
		move.l	le_Len(a3),d0
		move.l	le_FileBuffer(A3),a0
		jsr	meb_CopyMem(a6)
		movem.l	(SP)+,d1-d7/a0-a4
		rts


	** File normal laden

.NormLoad:	movem.l	(SP)+,d1-d7/a0-a4
		move.l	ActName,d0		; D0 : FileName
		move.l	a0,a1
		jsr	meb_LoadFastFile(a6)	; File von Disk einladen

	** File in Liste einbinden

		movem.l	d0-d7/a0-a4,-(SP)
		move.l	d0,a2			; A2 : Zeiger auf geladenes File

		move.l	#le_SIZEOF,d0			; Platz für
		jsr	meb_AllocFastClearMem(a6)	; Node reservieren

		move.l	d0,a4			; a4 = Node

		moveq.l	#NT_DISKNODE,d0
		tst.b	ActName			; Igitt! So nicht!
		bne.s	1$
		moveq.l	#NT_RAMNODE,d0
1$:		move.b	d0,ln_Type(a4)		; NodeType eintragen
		move.l	ActName,ln_Name(a4)	; FileName eintragen

		move.l	-4(a2),d0		; D0 : Länge des zu buffernden Files
		subq.l	#4,d0
		move.l	d0,le_Len(a4)

		move.l	a2,le_FileBuffer(a4)

		move.l	a2,a0			; File
		move.l	le_Len(a4),d0
		jsr	meb_CopyMem(a6)		; kopieren

		lea	meb_FileList(a6),a0	; FileNode
		move.l	a4,a1			; in Liste
		jsr	meb_Enqueue(a6)		; einbinden

		movem.l	(SP)+,d0-d7/a0-a4
		rts

******************************************************************************



	** Ein FileNode löschen / D0 = FileName

DeleteFileNodeFunc:
		move.l	a0,-(SP)
		lea	meb_FileList(a6),a0
		move.l	lh_Head(A0),a0		; A0 : erster Eintrag
.SearchLoop:	tst.l	ln_Succ(a0)		; ListenEnde ?
		beq	.EndDel
		cmp.l	ln_Name(A0),d0		; File gefunden ?
		beq	.FileFound		; ja ->
		move.l	ln_Succ(a0),a0		; sonst nächsten
		bra	.SearchLoop		; Eintrag holen

.FileFound:	bsr.s	DeleteNode		; Node und File freigeben 

.EndDel:	movea.l	(SP)+,a0
		rts



	** Node (A0) und File freigeben

DeleteNode:	movem.l	d0/a0-a2,-(SP)
		move.l	a0,a2			; File
		move.l	le_FileBuffer(a0),a1
		jsr	meb_FreeMem(a6)		; freigeben

		move.l	a2,a1			; Node aus Liste
		jsr	meb_Remove(a6)		; entfernen

		move.l	a2,a1			; Node Speicher
		jsr	meb_FreeMem(a6)		; freigeben

		movem.l	(SP)+,d0/a0-a2
		rts



	** Ganze FileListe freigeben


DeleteFileListFunc:
		move.l	a0,-(SP)
.DelLoop:	lea	meb_FileList(a6),a0
		move.l	lh_Head(a0),a0
		tst.l	ln_Succ(a0)
		beq	.EndDel
		bsr.s	DeleteNode
		bra.s	.DelLoop
.EndDel:	movea.l	(SP)+,a0
		rts

******************************************************************************

	** Wenn kein Speicher mehr vorhanden ist, erstes File in Buffer-
	** Liste freigeben und nochmal AllocMem() probieren
	** (Wird von AllocMem aufgerufen)

MyNoMemHandler:	movem.l	a0-a1,-(SP)
		lea	meb_FileList(a6),a0
		move.l	lh_Head(a0),a1		; A1 : Zeiger auf ersten Node 
		tst.l	ln_Succ(a1)		; Listen Ende ? 
		beq.s	.ListEmpty		; ja -> Guru
		movea.l	a1,a0			; sonst ersten
		bsr.s	DeleteNode		; Node freigeben
		movem.l	(SP)+,a0-a1
		moveq.l	#-1,d0			; Noch einmal probieren
		rts

.ListEmpty:	movem.l	(SP)+,a0-a1
		moveq.l	#0,d0			; Kein Speicher mehr
		rts


******************************************************************************

		SECTION	BSS,BSS

ActName:	ds.l	1