summaryrefslogtreecommitdiff
path: root/Startup.S
blob: 503bc3f897053d45679071b0c67c2b50777f70a1 (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
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
*****************************************************************************
**                                                                         **
**   S T A R T U P  -  Universeller Startup-Code für Workbench und CLI     **
**                                                                         **
**              by Christian A. Weber, Zürich/Switzwerland                 **
**                                                                         **
*****************************************************************************
**                                                                         **
**   Universeller Startup-Code für CLI und WorkBench, öffnet die dos-      **
**   library (DOSBase), schreibt Adresse unseres Tasks nach 'Process-      **
**   Base'. Falls wir von der WorkBench gestartet wurden, wird die         **
**   WorkBenchStartupMessage abgeholt und auf unser Directory ein Cur-     **
**   rentDir() gemacht. Alle Register  bleiben erhalten (BCPL...),         **
**   z.B. steht bei Start vom CLI in D0 die Länge der Argument-Zeile,      **
**   und in A0 steht ein Zeiger darauf. Bei Start von der WorkBench        **
**   steht in D0 eine 0 und in A0 ein Zeiger auf die WBStartupMessage.     **
**                                                                         **
**   Das Programm kann durch RTS beendet werden (ReturnCode D0) oder       **
**   mittels der Routinen '@Exit' oder '@exit' (auch ReturnCode D0).       **
**                                                                         **
*****************************************************************************
**                                                                         **
**   Es existieren zur Zeit 3 verschiedene Versionen:                      **
**                                                                         **
**   Startup.o         -   Standard Startup-Code                           **
**                                                                         **
**   DetachStartup.o   -   Hängt sich vom CLI ab                           **
**                         Die Stacksize des Prozesses kann beim Linken    **
**                         mit DEFINE _STACKSIZE=12345 angegeben werden.   **
**                                                                         **
**   TinyStartup.o     -   Öffnet keine Windows, kein StdIn/Out/Err        **
**                                                                         **
*****************************************************************************
**                                                                         **
**   Modification History                                                  **
**   --------------------                                                  **
**                                                                         **
**   07-Sep-87   V1.0   Project started                                    **
**                                                                         **
**   01-Feb-88   V1.5   Versteht nun Strings in Gänsefüßchen (tnx JMH)     **
**   17-Jun-88   V1.6   'dos.library' moved from data to code segment      **
**   12-Jul-88   V2.0   _CliParse extracted to separate file, no stack     **
**   16-Nov-88   V2.1   Gründlich aufgeräumt, ist jetzt nur in chw.lib     **
**   21-Nov-88   V2.2   Default-StdWindowName added                        **
**   02-Jan-88   V2.3   Default-StdWindowName wieder rausgeworfen          **
**   06-Feb-89   V2.4   An neues Library-Konzept angepasst (Labelnamen)    **
**   10-Feb-89   V2.5   Läuft nun auch mit Lattice asm und C               **
**   12-Feb-89   V2.6   Läuft nun auch mit SmallCode Aztec C               **
**   18-Mar-89   V3.0   Detach added (tnx CHH!)                            **
**   02-Apr-89   V3.1   Lattice exit() has now registerized parameters     **
**   25-Jun-89   V3.2   An Genim2 angepasst und gekürzt, Detach besser     **
**   16-Jul-89   V3.3   Prozessname bei Detach stimmt wieder               **
**   12-Aug-89   V3.4   stderr implementiert                               **
**   25-Sep-89   V3.5   ARP version implementiert                          **
**   03-Nov-89   V3.6   Tiny-Version (ohne stdin/out/err/window) impl.     **
**   12-Jan-90   V3.7   ARP-Version von Exit rettet D2 (für result2)       **
**   15-Jan-90   V3.8   ARP-Version in separaten Source verlegt            **
**   21-Jul-90   V3.9   NewOS-Flag added (nicht im TinyStartup)            **
**   22-Jul-90   V4.0   Öffnet GfxBase und IntuitionBase                   **
**   05-May-91   V4.1   NewOS erst ab V37 (früher V36)                     **
**   30-May-91   V4.2   _STACKSIZE von ARPStartup auch hier eingebaut      **
**   21-Jul-91   V4.3   BSS-Bereich wird gelöscht -> kürzere Programme     **
**   02-Apr-92   V4.4   Genam statt asm -> Detach läuft wieder             **
**                                                                         **
*****************************************************************************

		IDNT	Startup
		SECTION	text,CODE

		INCLUDE	"exec/types.i"
		INCLUDE	"exec/macros.i"
		INCLUDE	"exec/execbase.i"
		INCLUDE	"dos/dosextens.i"
		INCLUDE	"workbench/startup.i"

*****************************************************************************
**  Referenzen

		XREF	@Main		; Hauptprogramm, das aufgerufen wird

		XREF	_LinkerDB	; Start des Datenbereichs
		XREF	__BSSBAS	; Start des __MERGED BSS-Bereichs
		XREF	__BSSLEN	; Länge in LONGS des __MERGED BSS-Bereichs

	IFD DETACH
		XREF	_STACKSIZE	; Grösse des Stapels
	ENDC

	IFND TINY
		XREF	_StdWindowName	; Workbench-Window-Name, z.B. 'NIL:'
	ENDC

*****************************************************************************
**  Definitionen

		XDEF	_geta4		; A4 holen für Small Data
		XDEF	@exit,@Exit	; Fehler-Ausgang
		XDEF	_SysBase
		XDEF	_DOSBase
		XDEF	_ProcessBase	; Zeiger auf unseren Prozess
	IFND TINY
		XDEF	StdErr,_StdErr	; Immer CLI-Window oder WB-Window
		XDEF	NewOS,_NewOS	; Flag ob Kick 2.x
	ENDC

*****************************************************************************
**  Einsprung

FirstByte:
		bra.b	_WbStartup
	;;	dc.w	$4AFC			; ARP Magic
	;;	dc.l	_STACKSIZE		; ARP StackSize
	;;	dc.l	0			; ARP data size if resident

		dc.b	"CHW",0			; Für mein Ego :-)
		dc.b	"4.4",0			; Startup-Version

DOSName:	dc.b	"dos.library",0

	*** A4 holen, Testen ob 2. Durchgang von Detach

_WbStartup:	bsr	_geta4

	IFD DETACH
		tst.b	FirstTime(a4)		; 1. Mal hier ?
		bne	SecondTime		; nein --->
	ENDC

	*** BSS-Bereich löschen

		lea	__BSSBAS(a4),a3		; get base of BSS
		move.l	#__BSSLEN,d3		; get length of BSS in longwords
		bra.b	.ClearDBF		; and clear for length given
.ClearLoop:	clr.l	(a3)+
.ClearDBF:	dbf	d3,.ClearLoop

	IFD DETACH
		st.b	FirstTime(a4)		; Flag setzen (jaja erst hier :-( )
	ENDC

	*** D0/A0/SP retten, ExecBase und ThisTask holen

		movem.l	d0/a0/a7,InitRegs(a4)
		movea.l	(4).W,a6
		move.l	a6,_SysBase(a4)
		movea.l	ThisTask(a6),a3		; A3 :  Task/Process pointer

	*** DOS öffnen, Verzweigung WorkBench/CLI

		lea	DOSName(PC),a1
		JSRLIB	OldOpenLibrary		; DOS-Bibliothek öffnen
		movea.l	d0,a6			; A6 :  DOSBase
		move.l	a6,_DOSBase(a4)
	IFND TINY
		cmpi.w	#36,LIB_VERSION(a6)
		scc.b	NewOS(a4)		; Flag setzen falls Kick 2.x
	ENDC
		move.l	pr_CLI(a3),d0		; Vom CLI aufgerufen ?
		beq	FromWorkBench		; nein --->

*****************       *****************************************************
**  Start vom CLI

	*** Falls erwünscht detachen

	IFD DETACH
		lsl.l	#2,d0				; BPTR to APTR
		movea.l	d0,a2				; A2 :  struct CLI
		move.l	cli_Module(a2),CliSegList(a4)	; SegList retten
		clr.l	cli_Module(a2)			; für CLI löschen

		move.l	pr_CurrentDir(a3),d1		; Unser CurrentDir
		JSRLIB	DupLock				; duplizieren
		move.l	d0,ActDir(a4)			; und merken

	*** Kommandozeile in unseren Buffer kopieren

CopyCmdLine:	movea.l	InitialA0(a4),a0		; Original-ArgLine
		lea	CommandLine,a1			; Unsere ArgLine
		move.l	a1,InitialA0(a4)		; reinpatchen
1$:		move.b	(a0),(a1)+			; char kopieren
		beq.s	2$				; ---> fertig
		cmpi.b	#10,(a0)+			; Endmarkierung ?
		bne.b	1$				; nein ---> Loop
2$:		clr.b	(a1)+				; Endmarkierung

	*** Command-Name als Prozess-Name von BCPL nach CSTR konvertieren
	*** a1 zeigt auf freien Platz für Tasknamen

GetProcName:	move.l	a1,d1			; D1: Name für CreateProc()
		move.l	cli_CommandName(a2),d0	; PrgName holen
		beq.b	3$			; kein Name --->
		lsl.l	#2,d0			; BPTR to APTR
		movea.l	d0,a0
		moveq.l	#0,d0
		move.b	(a0)+,d0		; Länge des Strings holen
		bra.b	2$			; für dbf
1$:		move.b	(a0)+,(a1)+		; kopieren
2$:		dbf	d0,1$
		clr.b	(a1)			; mit NULL abschliessen
3$:
	*** Prozess kreieren und zurück zum CLI

		moveq	#0,d2
		move.b	LN_PRI(a3),d2		; D2: Priority
		move.l	CliSegList(a4),d3	; D3: SegList, ist schon BPTR
	;;	move.l	pr_StackSize(a3),d4	; D4: StackSize
	;;	lsl.l	#2,d4			; Stimmt das ??
		move.l	#_STACKSIZE,d4
		JSRLIB	CreateProc		; Neuen prozess starten
		moveq	#0,d0			; Zum CLI zurück
EndDet:		rts

	*** Einsprung des neuen Prozesses, hat schon _geta4 gemacht

SecondTime:	move.l	SP,InitialSP(a4)
		movea.l	_SysBase(a4),a6
		movea.l	ThisTask(a6),a3		; Neue ProcessBase holen
		movea.l	_DOSBase(a4),a6
		move.l	ActDir(a4),d1		; Unser CurrentDir
		JSRLIB	CurrentDir		; setzen

		bra.b	Windy			; --->
	ELSE

	   IFND TINY
		lea	StdErrName(PC),a0
		move.l	a0,d1
		move.l	#MODE_OLDFILE,d2
		JSRLIB	Open
		move.l	d0,_StdErr(a4)
	   ENDC
		bra.b	StartMain		; --->
	ENDC

*****************************************************************************
**  Register A4 holen für small data

_geta4:		lea	_LinkerDB,a4
		rts

*****************************************************************************
**  Start von der Werkbank

FromWorkBench:	movea.l	_SysBase(a4),a6
		lea	pr_MsgPort(a3),a0
		JSRLIB	WaitPort
		lea	pr_MsgPort(a3),a0
		JSRLIB	GetMsg
		move.l	d0,WBenchMsg(a4)

		clr.l	InitialD0(a4)		; D0 :  Null
		move.l	d0,InitialA0(a4)	; A0 :  WBStartup-Message
		movea.l	d0,a0			; Workbench Startup Message
		movea.l	sm_ArgList(a0),a0	; erstes Argument: wir selbst!
		move.l	wa_Lock(a0),d1		; Lock unseres Directories
		movea.l	_DOSBase(a4),a6
		JSRLIB	CurrentDir		; als Current Dir setzen

Windy:
	IFND TINY
		move.l	#_StdWindowName,d1	; Zu öffnendes Dos-Fenster
		move.l	#MODE_OLDFILE,d2
		JSRLIB	Open			; Window öffnen
		move.l	d0,OurWindow(a4)	; für Exit()
	   IFND DETACH
		move.l	d0,_StdErr(a4)
	   ENDC
		move.l	d0,pr_CIS(a3)		; für Input()
		move.l	d0,pr_COS(a3)		; für Output()
		lsl.l	#2,d0			; BPTR to APTR
		movea.l	d0,a0
		move.l	fh_Type(a0),pr_ConsoleTask(a3) ; für Open("*",mode);
	ENDC

****************        *****************************************************
**  Hauptprogramm starten

StartMain:	move.l	a3,ProcessBase(a4)	; für die Aussenwelt
		movem.l	InitRegs(a4),d0/a0
		jsr	@Main(PC)		; PROGRAMM AUSFÜHREN!

	*** Programm-Termination durch Exit(val) oder return(val)

@exit:
@Exit:		bsr.b	_geta4
	IFND DETACH
		move.l	d0,d7			; return-code retten
	ENDC
		movea.l	InitialSP(a4),SP	; Stackpointer restaurieren

	IFND TINY
		movea.l	_DOSBase(a4),a6
		move.l	OurWindow(a4),d1	; Fenster oder 0
		beq.b	1$
		JSRLIB	Close			; Fenster schliessen
1$:
	ENDC
		move.l	WBenchMsg(a4),d2	; gibt's was zu beantworten?
		beq.b	2$			; nein, CLI --->
		movea.l	_SysBase(a4),a6
		JSRLIB	Forbid			; sonst werden wir 'entladen' !
		movea.l	d2,a1
		JSRLIB	ReplyMsg
	IFND TINY
		bra.b	QuitnDie		; ---> raus!
	ENDC
2$:
	IFND DETACH
	   IFND TINY
		move.l	_StdErr(a4),d1		; StdErr schliessen if CLI
		movea.l	_DOSBase(a4),a6
		JSRLIB	Close
	   ENDC
	ENDC

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

	*** Uns selber und unseren Lock freigeben falls degetacht (CLI)

	IFD DETACH
	;;	movea.l	ProcessBase(a4),a3
	;;	clr.l	pr_CIS(a3)		; Input handle ungültig
	;;	clr.l	pr_COS(a3)		; Output handle ungültig
		movea.l	_DOSBase(a4),a6
		move.l	ActDir(a4),d1
		JSRLIB	UnLock			; Altes CD freigeben

		move.l	CliSegList(a4),d1	; Uns selbst
		JMPLIB	UnLoadSeg		; freigeben
		* NOT REACHED
	ENDC

*****************************************************************************
**  Returncode von D7 holen und Programm beenden

QuitnDie:	move.l	d7,d0			; return-code
		rts				; ZURÜCK ZUM DOS!

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

	IFND DETACH
	   IFND TINY
StdErrName:	dc.b	"*",0
	   ENDC
	ENDC

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

		SECTION	__MERGED,DATA

; Anscheinend darf die Data-Size im __MERGED-Segment nicht 0 sein, sonst
; erzeugt der Linker einen BSS-Hunk mit Länge 0 im Hunk und Länge 20 im
; Header (?!)

_DOSBase:
DOSBase:	ds.l	1	; wird hier geöffnet & geschlossen


		SECTION	__MERGED,BSS

_SysBase:	ds.l	1

_ProcessBase:
ProcessBase:	ds.l	1	; Address of this process

WBenchMsg:	ds.l	1	; Startup-Message oder NULL


	IFND TINY
_StdErr:			; MUSS vor OurWindow stehen, weil if ..
StdErr:				; .. detach, StdErr=OurWindow
	   IFND DETACH
		ds.l	1	; Standard Error FileHandle
	   ENDC

OurWindow:	ds.l	1	; Zeiger auf unser Window oder NULL

_NewOS:
NewOS:		ds.l	1	; Flag ob Kick 2.x
	ENDC


InitRegs:			; Die 3 geretteten Register D0/A0/SP:
InitialD0:	ds.l	1
InitialA0:	ds.l	1
InitialSP:	ds.l	1

	IFD DETACH

CliSegList:	ds.l	1	; Unsere Segmentliste
ActDir:		ds.l	1	; Lock auf unser Current Directory
FirstTime:	ds.l	1	; Flag ob 1. Mal durch

	ENDC


	IFD DETACH

		SECTION	bss,BSS

CommandLine:	ds.b	2100	; Kommandozeile und Task-Name

	ENDC

		END