summaryrefslogtreecommitdiff
path: root/Startup.S
diff options
context:
space:
mode:
Diffstat (limited to 'Startup.S')
-rw-r--r--Startup.S406
1 files changed, 406 insertions, 0 deletions
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