diff options
Diffstat (limited to 'ShowIFF')
-rw-r--r-- | ShowIFF/ArgsStartup20.S | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/ShowIFF/ArgsStartup20.S b/ShowIFF/ArgsStartup20.S new file mode 100644 index 0000000..021e6a9 --- /dev/null +++ b/ShowIFF/ArgsStartup20.S @@ -0,0 +1,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 |