home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / cbm / nduk-v37.lha / V37 / startups / startup.asm < prev    next >
Assembly Source File  |  1991-11-12  |  27KB  |  800 lines

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