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
|