From 62e509e9c90d728c9f65145947276f79112ab48c Mon Sep 17 00:00:00 2001 From: "Christian A. Weber" Date: Tue, 2 Nov 1993 18:53:33 +0000 Subject: Initial revision --- Startup.S | 406 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 Startup.S (limited to 'Startup.S') diff --git a/Startup.S b/Startup.S new file mode 100644 index 0000000..503bc3f --- /dev/null +++ b/Startup.S @@ -0,0 +1,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 -- cgit v1.2.3