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
|
*****************************************************************************
** **
** Startup20 - Startup-Code für Workbench und CLI ab Kickstart 2.0 **
** **
** by Christian A. Weber, Zürich/Switzwerland **
** **
*****************************************************************************
** **
** Universeller Startup-Code für CLI und WorkBench. **
** library (DOSBase), schreibt Adresse unseres Tasks nach 'Process- **
** Falls wir von der WorkBench gestartet wurden, wird die StartupMessage **
** abgeholt und auf unser Directory ein CurrentDir() gemacht. **
** Unter Kickstart 1.3 wird ein Requester ausgegeben und das Programm **
** beendet. **
** Bei ArgsStartup20.o und DetachArgsStartup20.o wird die CLI-Zeile **
** mittels ReadArgs() geparst. **
** **
*****************************************************************************
** **
** Folgende Variablen werden zur Verfügung gestellt: **
** **
** _SysBase - Zeiger auf Exec library base **
** _DOSBase - Zeiger auf DOS library base **
** _ProcessBase - Zeiger auf unseren Prozess **
** _CommandName - Zeiger auf Kommando-Namen (Null-terminated) **
** _geta4 - Routine zum Laden von A4 auf den Datenbereich **
** **
** **
** Folgende Variablen werden referenziert: **
** **
** @Main - Hauptprogramm, erhält folgende Registerwerte: **
** A0 = Argument-Zeile, D0 = Länge der Argumentzeile **
** A0 = WB-StartupMsg, D0 = 0 (bei Workbench-Start) **
** _StdWindowName - Window für WB-Start, z.b. "NIL:" oder "CON:blabla" **
** **
** _STACKSIZE - Größe des Stacks in Bytes für Detach startups **
** **
** **
** bei ArgsStartup20 und DetachArgsStartup zusätzlich benötigt: **
** **
** _CLI_Template - Das Template für ReadArgs(), z.b. "NAME/A,DELAY/N" **
** _argv - Genug Platz für alle Argumente (1 Long pro arg) **
** **
** **
** Das Programm kann durch RTS beendet werden (ReturnCode in D0) oder **
** mittels der Routinen '@Exit' oder '@exit' (ReturnCode in D0). **
** **
*****************************************************************************
** **
** Es existieren zur Zeit 5 verschiedene Versionen: **
** **
** Startup20.o - Standard Startup-Code **
** DetachStartup20.o - Hängt sich vom CLI ab **
** ArgsStartup20.o - Standard Startup-Code, mit ReadArgs() **
** ArgsDetachStartup20.o - Hängt sich vom CLI ab, mit ReadArgs() **
** **
*****************************************************************************
** **
** Modification History **
** -------------------- **
** **
** 01-Jul-91 CHW Created this file from Startup.S **
** 02-Jul-91 CHW Detach bug fixed **
** 16-Jul-91 CHW ReadArgs() implemented **
** 05-Apr-92 CHW Genam statt asm, Änderungen von Startup.S V4.4 **
** 28-May-93 CHW TINY Version gibt's nicht mehr V4.5 **
** **
*****************************************************************************
IDNT Startup20
SECTION text,CODE
INCLUDE "exec/types.i"
INCLUDE "exec/macros.i"
INCLUDE "exec/execbase.i"
INCLUDE "dos/dosextens.i"
INCLUDE "dos/dostags.i"
INCLUDE "workbench/startup.i"
ARGS
*****************************************************************************
** 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öss des Stapels
ENDC
XREF _StdWindowName ; Workbench-Window-Name, z.B. "NIL:"
IFD ARGS
XREF _CLI_Template ; Template-String für ReadArgs()
XREF _argv ; Ziel-Array für ReadArgs()
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
XDEF _CommandName ; Name unter dem das Prg gestartet wurde
*****************************************************************************
** Einsprung
FirstByte: bra.b _WbStartup
dc.b "CHW",0 ; Für mein Ego :-)
dc.b "4.5",20 ; Startup-Version
DOSName: dc.b "dos.library",0
*** A4 holen, BSS-Bereich löschen, D0/A0/SP retten
_WbStartup: bsr _geta4
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
movem.l d0/a0/a7,InitRegs(a4)
*** ExecBase(A6), ThisTask(A3) und CLI(A2) holen
movea.l (4).W,a6 ; A6: SysBase
move.l a6,_SysBase(a4)
movea.l ThisTask(a6),a3 ; A3: Task/Process pointer
move.l pr_CLI(a3),d0
lsl.l #2,d0 ; BPTR to APTR
movea.l d0,a2 ; A2: CLI oder NULL
*** Command-Name von BCPL nach CSTR konvertieren nach _CommandName
GetCmdName: moveq.l #-1,d0 ; -1 für DBF
lea _CommandName(a4),a1 ; Destination
movea.l LN_NAME(a3),a0 ; Default: Prozessname
move.l a2,d1 ; Vom CLI aufgerufen ?
beq.b 1$ ; nein --->
move.l cli_CommandName(a2),d1 ; PrgName holen
beq.b 3$ ; kein Name --->
lsl.l #2,d1 ; BSTR to APTR
movea.l d1,a0
add.b (a0)+,d0 ; Länge des Strings -1
1$: move.b (a0)+,(a1)+ ; D0+1 bytes kopieren
2$: dbeq d0,1$ ; Nicht '\0' ---> Loop
3$:
*** DOS library öffnen, Test ob Kick 2.x
lea DOSName(PC),a1
JSRLIB OldOpenLibrary ; DOS-Bibliothek öffnen
movea.l d0,a6 ; A6 : DOSBase
move.l a6,_DOSBase(a4) ; und in _DOSBase speichern
cmpi.w #37,LIB_VERSION(a6) ; Laufen wir unter >= 2.04 ?
bcc.b .KickOK ; ja --->
*** Wir laufen unter < 2.x: Requester ausgeben und RTS
lea _CommandName(a4),a0
move.l a0,d1 ; Source-APTR
moveq.l #40,d2 ; Destination-BSTR
add.l d1,d2
lsr.l #2,d2 ; BSTR
moveq.l #-31,d0 ; GV: String -> BSTR
jsr -28(a6) ; Gibt BSTR in D1
lea Kick20Text(a4),a0 ; "requires Kickstart 2.x"
move.l a0,d2
lsr.l #2,d2 ; APTR -> BPTR
moveq.l #0,d3 ; Textzeile 2
moveq.l #$34,d0 ; AutoRequest-GV-Nummer
jmp -28(a6) ; GV-Routine ausführen, RTS
.KickOK:
*** Verzweigung WorkBench/CLI
move.l a2,d0 ; Vom CLI aufgerufen ?
beq.b FromWorkBench ; nein --->
***************** *****************************************************
** Start vom CLI
*** Falls erwünscht CLI-Args parsen
IFD ARGS
lea _CLI_Template(a4),a0
move.l a0,d1
lea _argv(a4),a0
move.l a0,d2
moveq.l #0,d3 ; No user-supplied struct RDArgs *
JSRLIB ReadArgs
move.l d0,RDArgs(a4)
bne.b .RdArgsOK ; OK --->
JSRLIB IoErr
move.l d0,d1 ; Fault value
lea _CommandName(a4),a0
move.l a0,d2 ; Header for PrintFault()
JSRLIB PrintFault ; Error-Grund ausgeben
moveq.l #RETURN_FAIL,d0 ; Return-Code
bra @Exit ; Error --->
.RdArgsOK:
ENDC
*** Falls erwünscht detachen
IFD DETACH
move.l cli_Module(a2),CliSegList(a4) ; SegList retten
clr.l cli_Module(a2) ; für CLI löschen
*** Prozess erzeugen und zurück zum CLI
lea NewProcTags(a4),a0
move.l a0,d1 ; TagItems für CreateNewProc()
;; move.l pr_StackSize(a3),d0 ; StackSize
;; lsl.l #2,d0 ; hmm, ist scheinbar in LONGs
;; move.l d0,20(a0) ; in TagArray eintragen
move.l InitialA0(a4),28(a0) ; Commandline eintragen
JSRLIB CreateNewProc ; Neuen prozess starten
moveq.l #0,d0 ; Return-Code
rts ; Zum CLI zurück
ELSE ; nicht DETACH
bra.b StartMain ; --->
ENDC
*****************************************************************************
** Einsprung des neuen Prozesses von CreateNewProc()
IFD DETACH
NewProcEntry: bsr.b _geta4
move.l SP,InitialSP(a4)
movea.l _SysBase(a4),a6
movea.l ThisTask(a6),a3 ; Neue ProcessBase holen
movea.l _DOSBase(a4),a6 ; jaja
bra.b Windy ; --->
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:
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()
move.l d0,pr_CIS(a3) ; für Input()
move.l d0,pr_COS(a3) ; für Output()
move.l d0,pr_CES(a3) ; Error-Stream
lsl.l #2,d0 ; BPTR to APTR
movea.l d0,a0
move.l fh_Type(a0),pr_ConsoleTask(a3) ; für Open("CONSOLE:",mode);
**************** *****************************************************
** Hauptprogramm starten
StartMain: move.l a3,_ProcessBase(a4) ; für die Aussenwelt
movem.l InitRegs(a4),d0/a0
lea -128(SP),SP ;; $$$$ DEBUG
jsr @Main(PC) ; PROGRAMM AUSFÜHREN!
*** Programm-Terminierung 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
movea.l _DOSBase(a4),a6
move.l OurWindow(a4),d1 ; Fenster oder 0
beq.b 1$
JSRLIB Close ; Fenster schliessen
1$:
IFD ARGS
move.l RDArgs(a4),d1
beq.b 2$
JSRLIB FreeArgs
2$:
ENDC
movea.l _SysBase(a4),a6
move.l WBenchMsg(a4),d2 ; gibt's was zu beantworten?
beq.b 3$ ; nein, CLI --->
JSRLIB Forbid ; sonst werden wir 'entladen' !
movea.l d2,a1
JSRLIB ReplyMsg
IFD DETACH
bra.b QuitnDie ; ---> raus!
ENDC
3$:
**************** *****************************************************
* Uns selber freigeben falls degetacht (CLI)
IFD DETACH
movea.l _DOSBase(a4),a6
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!
*****************************************************************************
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: ds.l 1 ; wird hier geöffnet & geschlossen
CNOP 0,4
Kick20Text: dc.b 19,"needs Kickstart 2.x!",0 ; BSTR (EVEN LENGTH!)
IFD DETACH
NewProcTags: dc.l NP_Entry,NewProcEntry ; 0 4
dc.l NP_Name,_CommandName ; 8 12
dc.l NP_StackSize,_STACKSIZE ; 16 20
dc.l NP_Arguments,0 ; 24 28:Will be patched
dc.l NP_Input,OurWindow
dc.l NP_Output,OurWindow
dc.l NP_Error,OurWindow
dc.l NP_CloseInput,0
dc.l NP_CloseOutput,0
dc.l NP_CloseError,0
dc.l TAG_DONE
ENDC
SECTION __MERGED,BSS
_SysBase: ds.l 1
_ProcessBase: ds.l 1 ; Address of this process
WBenchMsg: ds.l 1 ; Startup-Message oder NULL
OurWindow: ds.l 1 ; Zeiger auf unser Window oder NULL
IFD ARGS
RDArgs: ds.l 1 ; Zeiger auf RDArgs-Struktur
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
ENDC
_CommandName: ds.b 80
END
|