home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377b.lha / libraries / workbench / startup / startup.asm < prev   
Encoding:
Assembly Source File  |  1980-02-03  |  25.9 KB  |  767 lines

  1. *------ startup.asm  v 34.12
  2. *
  3. * Copyright (c) 1990 Commodore-Amiga, Inc.
  4. *
  5. * This example is provided in electronic form by Commodore-Amiga, Inc. for
  6. * use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals. 
  7. * The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
  8. * information on the correct usage of the techniques and operating system
  9. * functions presented in this example.  The source and executable code of
  10. * this example may only be distributed in free electronic form, via bulletin
  11. * board or as part of a fully non-commercial and freely redistributable
  12. * diskette.  Both the source and executable code (including comments) must
  13. * be included, without modification, in any copy.  This example may not be
  14. * published in printed form or distributed with any commercial product.
  15. * However, the programming techniques and support routines set forth in
  16. * this example may be used in the development of original executable
  17. * software products for Commodore Amiga computers.
  18. * All other rights reserved.
  19. * This example is provided "as-is" and is subject to change; no warranties
  20. * are made.  All use is at your own risk.  No liability or responsibility
  21. * is assumed.
  22. *
  23.  
  24. *------
  25. *------ Conditional assembly flags
  26. *------ ASTART:   1=Standard Globals Defined    0=Reentrant Only
  27. *------ WINDOW:   1=AppWindow for WB startup    0=No AppWindow code
  28. *------ XNIL:     1=Remove startup NIL: init    0=Default Nil: WB Output
  29. *------ NARGS:    1=Argv[0] only                0=Normal cmd line arg parse
  30. *------ DEBUG:    1=Set up old statics for Wack 0=No extra statics
  31. *------ QARG:     1=No argv                     0=Passes argc,argv
  32.  
  33. * Include the appropriate .i file to set the flags
  34.  
  35.         INCLUDE "astartup.i"
  36.  
  37. * Flags for  [A]start  AWstart  Rstart  RWstart  RXstart  QStart
  38. * ASTART         1        1       0        0        0       0
  39. * WINDOW         0        1       0        1        0       0
  40. * XNIL           0        0       0        0        1       1
  41. * NARGS          0        0       0        0        0       0
  42. * DEBUG          0        0       0        0        0       0
  43. * QARG           0        0       0        0        0       1
  44.  
  45. ;------   Flag WB output initialization
  46. WBOUT     SET   (ASTART!WINDOW!(1-XNIL))
  47.  
  48. ************************************************************************
  49. *
  50. *   startup.asm --- Reentrant C Program Startup/Exit (CLI and WB)
  51. *                   v34.12  07/25/88
  52. *
  53. *   Copyright (c) 1988 Commodore-Amiga, Inc.
  54. *
  55. *   Title to this software and all copies thereof remain vested in the
  56. *   authors indicated in the above copyright notice.  The object version
  57. *   of this code may be used in software for Commodore Amiga computers.
  58. *   All other rights are reserved.
  59. *
  60. *   NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE
  61. *   ACCURACY, RELIABILITY, PERFORMANCE OR OPERATION OF THIS SOFTWARE,
  62. *   AND ALL SUCH USE IS AT YOUR OWN RISK.  NEITHER COMMODORE NOR THE
  63. *   AUTHORS ASSUME ANY RESPONSIBILITY OR LIABILITY WHATSOEVER WITH
  64. *   RESPECT TO YOUR USE OF THIS SOFTWARE.
  65. *
  66. *
  67. *   RSTARTUP.ASM
  68. *
  69. *      This startup dynamically allocates a structure which includes
  70. *   the argv buffers.  If you use this startup, your code must return
  71. *   to this startup when it exits.  Use exit(n) or final curly brace
  72. *   (rts) to return here.  Do not use AmigaDOS Exit( ) function.
  73. *   Due to this dynamic allocation and some code consolidation, this
  74. *   startup can make executables several hundred bytes smaller.
  75. *
  76. *       Because a static initialSP variable can not be used, this
  77. *   code depends on the fact that AmigaDOS places the address of
  78. *   the top of our stack in SP and proc->pr_ReturnAddr right before
  79. *   JSR'ing to us.  This code uses pr_ReturnAddr when restoring SP.
  80. *
  81. *       Most versions of startup will initialize a Workbench process's
  82. *   input and output streams (and stdio globals if present) to NIL:
  83. *   if no other form of Workbench output (like WINDOW) is provided.
  84. *   This should help prevent crashes if a user puts an icon on a CLI
  85. *   program, and will also protect against careless stdio debugging
  86. *   or error messages left in a Workbench program.  The code for
  87. *   initializing Workbench IO streams only be removed by assembling
  88. *   startup with ASTART and WINDOW set to 0, and XNIL set to 1.
  89. *
  90. *
  91. *   Some startups which can be conditionally assembled:
  92. *
  93. *      1. Standard Astartup for non-reentrant code
  94. *      2. Reentrant Rstartup (no unshareable globals)
  95. *      3. Smaller reentrant-only RXstartup (no NIL: WB init code)
  96. *      4. Standard AWstartup (WB output window) for non-reentrant code
  97. *      5. Reentrant RWstartup (WB output window, no unshareable globals)
  98. *      6. Smallest Qstartup  (No argv - argv is ptr to NULL string)
  99. *
  100. *
  101. *   Explanation of conditional assembly flags:
  102. *
  103. *      ASTART (ASTART SET 1) startups will set up and XDEF the
  104. *   global variables _stdin, _stdout, _stderr, _errno and  _WBenchMsg.
  105. *   These startups can be used as smaller replacements for startups
  106. *   like (A)startup.obj and TWstartup.obj.  Startups with ASTART
  107. *   would generally be used for non-reentrant programs, although the
  108. *   startup code itself is still reentrant if the globals are not
  109. *   referenced.
  110. *      Reentrant (ASTART SET 0) startups will NOT set up or
  111. *   XDEF the stdio and WBenchMsg globals.  This not only makes the
  112. *   startup slightly smaller, but also lets you know if your code
  113. *   is referencing these non-reentrant globals (you will get an
  114. *   unresolved external reference when you link).  Programs
  115. *   get their input and output handles from Input( ) and Output( ),
  116. *   and the WBenchMsg is passed in argv on Workbench startup.
  117. *
  118. *      WINDOW (WINDOW SET 1) startups use an XREF'd CON: string
  119. *   named AppWindow, defined in your application, to open a stdio
  120. *   console window when your application is started from Workbench.
  121. *   For non-reentrant programs, this window can be used for normal
  122. *   stdio (printf, getchar, etc).  For reentrant programs the window
  123. *   is Input( ) and Output( ).  WINDOW is useful when adding Workbench
  124. *   capability to a stdio application, and also for debugging other
  125. *   Workbench applications.  To insure that applications requiring
  126. *   a window startup are linked with a window startup, the label
  127. *   _NeedWStartup can be externed and referenced in the application
  128. *   so that a linker error will occur if linked with a standard
  129. *   startup.
  130. *
  131. *       example:   /* Optional safety reference to NeedWStartup */
  132. *                    extern UBYTE  NeedWStartup;
  133. *                    UBYTE  *HaveWStartup = &NeedWStartup;
  134. *                  /* Required window specification */
  135. *                    char AppWindow[] = "CON:30/30/200/150/MyProgram";
  136. *                    ( OR  char AppWindow[] = "\0";  for no window )
  137. *
  138. *
  139. *      XNIL (XNIL SET 1) allows the creation of a smaller startup
  140. *   by removing the code that initializes a Workbench process's
  141. *   output streams to NIL:.  This flag can only remove the code
  142. *   if it is not required for ASTART or WINDOW.
  143. *
  144. *      NARGS (NARGS SET 1) removes the code used to parse command line
  145. *   arguments.  The command name is still passed to _main as argv[0].
  146. *   This option can take about 120 bytes off the size of any program that
  147. *   does not use command line args.
  148. *
  149. *      DEBUG (DEBUG SET 1) will cause the old startup.asm statics
  150. *   initialSP, dosCmdLen and dosCmdBuf to be defined and initialized
  151. *   by the startup code, for use as debugging symbols when using Wack.
  152. *
  153. *      QARG (QARG SET TO 1) will bypass all argument parsing.  A CLI
  154. *   startup is passed argc == 1, and a Workbench startup is passed
  155. *   argc == 0.  Argv[0] will be a pointer to a NULL string rather than
  156. *   a pointer to the command name.  This option creates a very small
  157. *   startup with no sVar structure allocation, and therefore must be used
  158. *   with XNIL (it is incompatible with default or AWindow output options).
  159. *
  160. *
  161. *   RULES FOR REENTRANT CODE
  162. *
  163. *      - Make no direct or indirect (printf, etc) references to the
  164. *        globals _stdin, _stdout, _stderr, _errno, or _WBenchMsg.
  165. *
  166. *      - For stdio use either special versions of printf and getchar
  167. *        that use Input( ) and Output( ) rather than _stdin and _stdout,
  168. *        or use fprintf and fgetc with Input( ) and Output( ) file handles.
  169. *
  170. *      - Workbench applications must get the pointer to the WBenchMsg
  171. *        from argv rather than from a global extern WBenchMsg.
  172. *
  173. *      - Use no global or static variables within your code.  Instead,
  174. *        put all former globals in a dynamically allocated structure, and
  175. *        pass around a pointer to that structure.  The only acceptable
  176. *        globals are constants (message strings, etc) and global copies
  177. *        of Library Bases to resolve Amiga.lib references.  Your code
  178. *        must return all OpenLibrary's into non-global variables,
  179. *        copy the result to the global library base only if successful,
  180. *        and use the non-globals when deciding whether to Close any
  181. *        opened libraries.
  182. *
  183. ************************************************************************
  184.  
  185.  
  186. ******* Included Files *************************************************
  187.  
  188.         INCLUDE "exec/types.i"
  189.         INCLUDE "exec/alerts.i"
  190.         INCLUDE "exec/memory.i"
  191.         INCLUDE "libraries/dos.i"
  192.         INCLUDE "libraries/dosextens.i"
  193.         INCLUDE "workbench/startup.i"
  194.  
  195.  
  196. ******* Macros *********************************************************
  197.  
  198.     section code
  199.  
  200. xlib    macro
  201.         xref    _LVO\1
  202.         endm
  203.  
  204. callsys macro
  205.         CALLLIB _LVO\1
  206.         endm
  207.  
  208. ******* Imported *******************************************************
  209.  
  210. ABSEXECBASE     EQU     4
  211.  
  212.         xref    _main           ; C code entry point
  213.  
  214.         IFGT    WINDOW
  215.         xref    _AppWindow      ; CON: spec in application for WB stdio window
  216.         xdef    _NeedWStartup   ; May be externed and referenced in application
  217.         ENDC    WINDOW
  218.  
  219.         xlib    Alert
  220.         xlib    AllocMem
  221.         xlib    FindTask
  222.         xlib    Forbid
  223.         xlib    FreeMem
  224.         xlib    GetMsg
  225.         xlib    OpenLibrary
  226.         xlib    CloseLibrary
  227.         xlib    ReplyMsg
  228.         xlib    Wait
  229.         xlib    WaitPort
  230.  
  231.         xlib    CurrentDir
  232.         xlib    Open
  233.         xlib    Close
  234.         xlib    Input
  235.         xlib    Output
  236.  
  237. ******* Exported *******************************************************
  238.  
  239. *----- These globals are set up for standard startup code only
  240.         IFGT    ASTART
  241.         xdef    _stdin
  242.         xdef    _stdout
  243.         xdef    _stderr
  244.         xdef    _errno
  245.         xdef    _WBenchMsg
  246.         ENDC    ASTART
  247.  
  248. *----- These globals available to normal and reentrant code
  249.  
  250.         xdef    _SysBase
  251.         xdef    _DOSBase
  252.         xdef    _exit           ; standard C exit function
  253.  
  254.  
  255. ***** Startup Variables structure **********************************
  256.  
  257.         IFEQ    QARG
  258. ARGVSLOTS       EQU     32
  259.  
  260.  STRUCTURE  SVar,0
  261.     LONG    sv_WbOutput
  262.     STRUCT  sv_argvArray,ARGVSLOTS*4
  263.     STRUCT  sv_argvBuffer,256
  264.     LABEL   SV_SIZEOF
  265.         ENDC    QARG
  266.  
  267. ************************************************************************
  268. *   Standard Program Entry Point
  269. ************************************************************************
  270. *
  271. *       Entered with
  272. *           d0  dosCmdLen
  273. *           a0  dosCmdBuf
  274. *       Any registers (except sp) are allowed to be modified
  275. *
  276. *       Calls
  277. *           main (argc, argv)
  278. *               int   argc;
  279. *               char *argv[];
  280. *
  281. *           For Workbench startup, argc=0, argv=WBenchMsg
  282. *
  283. ************************************************************************
  284. startup:
  285.         IFGT    DEBUG
  286.                 move.l  sp,initialSP
  287.                 move.l  d0,dosCmdLen
  288.                 move.l  a0,dosCmdBuf
  289.         ENDC    DEBUG
  290.  
  291.         IFEQ    QARG
  292.                 move.l  d0,d2
  293.                 move.l  a0,a2
  294.         ENDC    QARG
  295.  
  296.         ;------ get Exec library base pointer
  297.                 movea.l ABSEXECBASE,a6
  298.                 move.l  a6,_SysBase
  299.  
  300.         ;------ get the address of our task
  301.                 suba.l  a1,a1           ; clear a1
  302.                 callsys FindTask
  303.                 move.l  d0,a4           ; keep task address in a4
  304.  
  305.         ;------ get DOS library base pointer
  306.                 moveq   #0,d0
  307.                 lea     DOSName(pc),A1  ; dos.library
  308.                 callsys OpenLibrary
  309.  
  310.                 tst.l   d0
  311.                 beq     alertDOS        ; fail on null with alert
  312.                 move.l  d0,_DOSBase     ; Else set the global
  313.  
  314.  
  315.         IFEQ    QARG
  316.         ;------ alloc the argument structure
  317.                 move.l  #SV_SIZEOF,d0
  318.                 move.l  #(MEMF_PUBLIC!MEMF_CLEAR),d1
  319.                 callsys AllocMem
  320.                 tst.l   d0
  321.                 beq     alertMem        ; fail on null with alert
  322.                 move.l  d0,-(sp)        ; save sVar ptr on stack
  323.                 move.l  d0,a5           ; sVar ptr to a5
  324.         ENDC    QARG
  325.         IFGT    QARG
  326.                 clr.l   -(sp)
  327.         ENDC    QARG
  328.  
  329.                 clr.l   -(sp)           ; reserve space for WBenchMsg if any
  330.  
  331.         ;------ branch to Workbench startup code if not a CLI process
  332.                 move.l  pr_CLI(A4),d0
  333.                 beq     fromWorkbench
  334.  
  335. ;=======================================================================
  336. ;====== CLI Startup Code ===============================================
  337. ;=======================================================================
  338. ;       d0  process CLI BPTR (passed in), then temporary
  339. ;       d2  dos command length (passed in)
  340. ;       d3  argument count
  341. ;       a0  temporary
  342. ;       a1  argv buffer
  343. ;       a2  dos command buffer (passed in)
  344. ;       a3  argv array
  345. ;       a4  Task (passed in)
  346. ;       a5  SVar structure if not QARG (passed in)
  347. ;       a6  AbsExecBase (passed in)
  348. ;       sp  WBenchMsg (still 0), sVar or 0, then RetAddr (passed in)
  349. ;       sp  argc, argv, WBenchMsg, sVar or 0,RetAddr (at bra domain)
  350.  
  351.         IFEQ    QARG
  352.         ;------ find command name
  353.                 lsl.l   #2,d0           ; pr_CLI bcpl pointer conversion
  354.                 move.l  d0,a0
  355.                 move.l  cli_CommandName(a0),d0
  356.                 lsl.l   #2,d0           ; bcpl pointer conversion
  357.  
  358.                 ;-- start argv array
  359.                 lea     sv_argvBuffer(a5),a1
  360.                 lea     sv_argvArray(a5),a3
  361.  
  362.                 ;-- copy command name
  363.                 move.l  d0,a0
  364.                 moveq.l #0,d0
  365.                 move.b  (a0)+,d0        ; size of command name
  366.                 clr.b   0(a0,d0.l)      ; terminate the command name
  367.                 move.l  a0,(a3)+
  368.                 moveq   #1,d3           ; start counting arguments
  369.  
  370.         IFEQ    NARGS
  371.         ;------ null terminate the arguments, eat trailing control characters
  372.                 lea     0(a2,d2.l),a0
  373. stripjunk:
  374.                 cmp.b   #' ',-(a0)
  375.                 dbhi    d2,stripjunk
  376.  
  377.                 clr.b   1(a0)
  378.  
  379.         ;------ start gathering arguments into buffer
  380. newarg:
  381.                 ;-- skip spaces
  382.                 move.b  (a2)+,d1
  383.                 beq.s   parmExit
  384.                 cmp.b   #' ',d1
  385.                 beq.s   newarg
  386.                 cmp.b   #9,d1           ; tab
  387.                 beq.s   newarg
  388.  
  389.                 ;-- check for argument count overflow
  390.                 cmp.w   #ARGVSLOTS-1,d3
  391.                 beq.s   parmExit
  392.  
  393.                 ;-- push address of the next parameter
  394.                 move.l  a1,(a3)+
  395.                 addq.w  #1,d3
  396.  
  397.                 ;-- process quotes
  398.                 cmp.b   #'"',d1
  399.                 beq.s   doquote
  400.  
  401.                 ;-- copy the parameter in
  402.                 move.b  d1,(a1)+
  403.  
  404. nextchar:
  405.                 ;------ null termination check
  406.                 move.b  (a2)+,d1
  407.                 beq.s   parmExit
  408.                 cmp.b   #' ',d1
  409.                 beq.s   endarg
  410.  
  411.                 move.b  d1,(a1)+
  412.                 bra.s   nextchar
  413.  
  414. endarg:
  415.                 clr.b   (a1)+
  416.                 bra.s   newarg
  417.  
  418. doquote:
  419.         ;------ process quoted strings
  420.                 move.b  (a2)+,d1
  421.                 beq.s   parmExit
  422.                 cmp.b   #'"',d1
  423.                 beq.s   endarg
  424.  
  425.                 ;-- '*' is the BCPL escape character
  426.                 cmp.b   #'*',d1
  427.                 bne.s   addquotechar
  428.  
  429.                 move.b  (a2)+,d1
  430.                 move.b  d1,d2
  431.                 and.b   #$df,d2         ;d2 is temp toupper'd d1
  432.  
  433.                 cmp.b   #'N',d2         ;check for dos newline char
  434.                 bne.s   checkEscape
  435.  
  436.                 ;--     got a *N -- turn into a newline
  437.                 moveq   #10,d1
  438.                 bra.s   addquotechar
  439.  
  440. checkEscape:
  441.                 cmp.b   #'E',d2
  442.                 bne.s   addquotechar
  443.  
  444.                 ;--     got a *E -- turn into a escape
  445.                 moveq   #27,d1
  446.  
  447. addquotechar:
  448.                 move.b  d1,(a1)+
  449.                 bra.s   doquote
  450.  
  451. parmExit:
  452.         ;------ all done -- null terminate the arguments
  453.                 clr.b   (a1)
  454.                 clr.l   (a3)
  455.         ENDC NARGS
  456.  
  457.                 pea     sv_argvArray(a5) ; argv
  458.                 move.l  d3,-(sp)         ; argc
  459.         ENDC    QARG
  460.  
  461.         IFGT    QARG
  462.                 pea     nullArgV(pc)    ; pointer to pointer to null string
  463.                 pea     1               ; only one pointer
  464.         ENDC
  465.  
  466.         IFGT    ASTART
  467.                 movea.l _DOSBase,a6
  468.         ;------ get standard input handle:
  469.                 callsys Input
  470.                 move.l  d0,_stdin
  471.  
  472.         ;------ get standard output handle:
  473.                 callsys Output
  474.                 move.l  d0,_stdout
  475.                 move.l  d0,_stderr
  476.                 movea.l ABSEXECBASE,a6
  477.         ENDC ASTART
  478.  
  479.                 bra     domain
  480.  
  481.  
  482. ;=======================================================================
  483. ;====== Workbench Startup Code =========================================
  484. ;=======================================================================
  485. ;       a2  WBenchMsg
  486. ;       a4  Task (passed in)
  487. ;       a5  SVar structure if not QARG (passed in)
  488. ;       a6  AbsExecBase (passed in)
  489. ;       sp  WBenchMsg (still 0), sVar or 0, then RetAddr (passed in)
  490. ;       sp  argc=0,argv=WBenchMsg,WBenchMsg,sVar or 0,RetAddr (at domain)
  491.  
  492. fromWorkbench:
  493.         ;------ get the startup message that workbench will send to us.
  494.         ;       must get this message before doing any DOS calls
  495.                 bsr.s   getWbMsg
  496.  
  497.         ;------ save the message so we can return it later
  498.                 move.l  d0,(sp)
  499.         IFGT    ASTART
  500.                 move.l  d0,_WBenchMsg
  501.         ENDC    ASTART
  502.  
  503.         ;------ push the message on the stack for wbmain (as argv)
  504.                 move.l  d0,-(sp)
  505.                 clr.l   -(sp)           ; indicate run from Workbench (argc=0)
  506.  
  507.         IFNE    (1-QARG)+WBOUT
  508.         ;------ put DOSBase in a6 for next few calls
  509.                 move.l  _DOSBase,a6
  510.         ENDC    (1-QARG)+WBOUT
  511.  
  512.         IFEQ    QARG
  513.         ;------ get the first argument
  514.                 move.l  d0,a2
  515.                 move.l  sm_ArgList(a2),d0
  516.                 beq.s   doCons
  517.  
  518.         ;------ and set the current directory to the same directory
  519.                 move.l  d0,a0
  520.                 move.l  wa_Lock(a0),d1
  521.                 ;should be a  beq.s doCons  here
  522.                 callsys CurrentDir
  523. doCons:
  524.         ENDC    QARG
  525.  
  526.         IFGT    WBOUT
  527.  
  528.         ;------ Open NIL: or AppWindow for WB Input()/Output() handle
  529.         ;       Also for possible initialization of stdio globals
  530.         ;       Stdio used to be initialized to -1
  531.  
  532.  
  533.         IFGT    WINDOW
  534.         ;------ Get AppWindow defined in application
  535.                 lea     _AppWindow,a0
  536.                 cmp.b   #0,(a0)
  537.                 bne.s   doOpen          ; Open if not null string
  538.         ENDC    WINDOW
  539.  
  540.         ;------ Open NIL: if no window provided
  541.         lea     NilName(PC),a0
  542.  
  543. doOpen:
  544.         ;------ Open up the file whose name is in a0
  545.         ;       DOSBase still in a6
  546.                 move.l  a0,d1
  547.                 move.l  #MODE_OLDFILE,d2
  548.                 callsys Open
  549.         ;------ d0 now contains handle for Workbench Output
  550.         ;------ save handle for closing on exit
  551.                 move.l  d0,sv_WbOutput(a5)
  552.                 bne.s   gotOpen
  553.                 moveq.l #RETURN_FAIL,d2
  554.                 bra     exit2
  555. gotOpen:
  556.         IFGT ASTART
  557.         ;------ set the C input and output descriptors
  558.                 move.l  d0,_stdin
  559.                 move.l  d0,_stdout
  560.                 move.l  d0,_stderr
  561.         ENDC ASTART
  562.  
  563.         ;------ set the console task (so Open( "*", mode ) will work
  564.         ;       task pointer still in A4
  565.                 move.l  d0,pr_CIS(A4)
  566.                 move.l  d0,pr_COS(A4)
  567.                 lsl.l   #2,d0
  568.                 move.l  d0,a0
  569.                 move.l  fh_Type(a0),d0
  570.                 beq.s   noConTask
  571.                 move.l  d0,pr_ConsoleTask(A4)
  572. noConTask:
  573.         ENDC WBOUT
  574.  
  575.         ;------ Fall though to common WB/CLI code
  576.  
  577.  
  578. ****************************************************
  579. ** This code now used by both CLI and WB startup  **
  580. ****************************************************
  581.  
  582. domain:
  583.                 jsr     _main
  584.         ;------ main didn't use exit(n) so provide success return code
  585.                 moveq.l #RETURN_OK,d2
  586.                 bra.s   exit2
  587.  
  588.  
  589. ****************************************************
  590. **    subroutines here to allow short branches    **
  591. ****************************************************
  592.  
  593. getWbMsg:
  594.         ;------ a6 = ExecBase
  595.                 lea     pr_MsgPort(A4),a0       ; our process base
  596.                 callsys WaitPort
  597.                 lea     pr_MsgPort(A4),a0       ; our process base
  598.                 callsys GetMsg
  599.                 rts
  600.  
  601. ****************************************************
  602.  
  603. alertDOS:
  604.         ;------ do recoverable alert for no DOS and exit
  605.                 ALERT   (AG_OpenLib!AO_DOSLib)
  606.  
  607.         ;------ do recoverable alert for no memory and exit
  608.         ;------ If we got this far, DOS is open, so close it
  609.         IFEQ QARG
  610.                 bra.s   failExit
  611. alertMem:
  612.                 movea.l _DOSBase,a1
  613.                 callsys CloseLibrary
  614.                 ALERT   AG_NoMemory
  615.         ENDC QARG
  616. failExit:
  617.                 tst.l   pr_CLI(a4)
  618.                 bne.s   fail2
  619.                 bsr.s   getWbMsg
  620.                 movea.l d0,a2
  621.                 bsr.s   repWbMsg
  622. fail2:
  623.                 moveq.l #RETURN_FAIL,d0
  624.                 rts
  625.  
  626. ****************************************************
  627.  
  628. repWbMsg:
  629.         ;------ return the startup message to our parent
  630.         ;       a6 = ExecBase (passed)
  631.         ;       a2 = WBenchMsg (passed)
  632.         ;       we forbid so workbench can't UnLoadSeg() us before we are done
  633.                 callsys Forbid
  634.                 move.l  a2,a1
  635.                 callsys ReplyMsg
  636.                 rts
  637.  
  638.  
  639. *******************************************************
  640. **  C Program exit() Function, return code on stack  **
  641. **                                                   **
  642. **  pr_ReturnAddr points to our RTS addr on stack    **
  643. **  and we use this to calculate our stack ptr:      **
  644. **                                                   **
  645. **      SP ->   WBenchMsg or 0 (CLI)                 **
  646. **              sVar ptr or 0 (QARG)                 **
  647. **              Address for RTS to DOS               **
  648. *******************************************************
  649.  
  650. _exit:
  651.                 move.l  4(sp),d2        ; exit(n) return code to d2
  652.  
  653. exit2:                                  ;exit code in d2
  654.         ;------ restore initial stack ptr
  655.                 ;-- FindTask
  656.                 movea.l ABSEXECBASE,a6
  657.                 suba.l  a1,a1
  658.                 callsys FindTask
  659.                 ;-- get SP as it was prior to DOS's jsr to us
  660.                 move.l  d0,a4
  661.                 move.l  pr_ReturnAddr(a4),a5
  662.                 ;-- subtract 4 for return address, 4 for SVar, 4 for WBenchMsg
  663.                 suba.w  #12,a5
  664.  
  665.                 ;-- restore sp
  666.                 move.l  a5,sp
  667.  
  668.                 ;-- recover WBenchMsg
  669.                 move.l  (sp)+,a2
  670.                 ;-- recover SVar
  671.                 move.l  (sp)+,a5
  672.  
  673.  
  674.         IFGT    WBOUT
  675.         ;------ Close any WbOutput file before closing dos.library
  676.                 move.l  sv_WbOutput(a5),d1
  677.                 beq.s   noWbOut
  678.                 move.l  _DOSBase,a6
  679.                 callsys Close
  680. noWbOut:
  681.         ;------ Restore a6 = ExecBase
  682.                 movea.l ABSEXECBASE,a6
  683.         ENDC    WBOUT
  684.  
  685.         ;------ Close DOS library, if we got here it was opened
  686.         ;       SysBase still in a6
  687.                 movea.l _DOSBase,a1
  688.                 callsys CloseLibrary
  689.  
  690.         ;------ if we ran from CLI, skip workbench reply
  691. checkWB:
  692.                 move.l  a2,d0
  693.                 beq.s   deallocSV
  694.  
  695.                 bsr.s   repWbMsg
  696.  
  697. deallocSV:
  698.         IFEQ    QARG
  699.         ;------ deallocate the SVar structure
  700.                 move.l  a5,a1
  701.                 move.l  #SV_SIZEOF,d0
  702.                 callsys FreeMem
  703.         ENDC    QARG
  704.  
  705.         ;------ this rts sends us back to DOS:
  706.                 move.l  d2,d0
  707.                 rts
  708.  
  709.  
  710. **********************************************************************
  711.  
  712. ;----- PC relative data
  713.  
  714. DOSName         DOSNAME
  715. NilName         dc.b    'NIL:',0
  716.         IFGT    QARG
  717. nullArgV        dc.l    nullArg
  718. nullArg         dc.l    0               ; "" & the null entry after nullArgV
  719.         ENDC
  720.  
  721. **********************************************************************
  722.     section data
  723. **********************************************************************
  724.  
  725. _SysBase        dc.l    0
  726. _DOSBase        dc.l    0
  727.  
  728.         IFGT    ASTART
  729. _WBenchMsg      dc.l    0
  730. _stdin          dc.l    0
  731. _stdout         dc.l    0
  732. _stderr         dc.l    0
  733. _errno          dc.l    0
  734.         ENDC    ASTART
  735.  
  736.         IFGT    DEBUG
  737. initialSP       dc.l    0
  738. dosCmdLen       dc.l    0
  739. dosCmdBuf       dc.l    0
  740.         ENDC    DEBUG
  741.  
  742. VerRev          dc.w    34,12
  743.         IFGT    ASTART
  744.                 dc.b    'A'
  745.         ENDC    ASTART
  746.         IFEQ    ASTART
  747.                 dc.b    'R'
  748.         ENDC    ASTART
  749.         IFGT    WINDOW
  750. _NeedWStartup:
  751.                 dc.b    'W'
  752.         ENDC    WINDOW
  753.         IFEQ    WBOUT
  754.                 dc.b    'X'
  755.         ENDC    WBOUT
  756.         IFGT    NARGS
  757.                 dc.b    'N'
  758.         ENDC    NARGS
  759.         IFGT    DEBUG
  760.                 dc.b    'D'
  761.         ENDC    DEBUG
  762.         IFGT    QARG
  763.                 dc.b    'Q'
  764.         ENDC    QARG
  765.  
  766.         END
  767.