home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / dev / rkrm.lha / RKRM / Workbench / startup2.0 / startup.asm < prev   
Encoding:
Assembly Source File  |  1992-09-03  |  27.7 KB  |  831 lines

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