home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / ftp.vapor.com / microdot-1 / md1_src_02.lzx / c.a < prev    next >
Text File  |  1989-08-24  |  12KB  |  417 lines

  1. *
  2.         IFD  CATCH
  3.           IFND NOREQ
  4. AUTOREQ         set        1
  5.           ENDC
  6.         ENDC
  7.  
  8.         INCLUDE        "exec/types.i"
  9.         INCLUDE        "exec/alerts.i"
  10.         INCLUDE        "exec/nodes.i"
  11.         INCLUDE        "exec/lists.i"
  12.         INCLUDE        "exec/ports.i"
  13.         INCLUDE        "exec/libraries.i"
  14.         INCLUDE        "exec/tasks.i"
  15.         INCLUDE        "exec/memory.i"
  16.         INCLUDE        "exec/execbase.i"
  17.         INCLUDE        "libraries/dos.i"
  18.         INCLUDE        "libraries/dosextens.i"
  19.         INCLUDE        "workbench/startup.i"
  20.         INCLUDE        "exec/funcdef.i"
  21.         INCLUDE        "exec/exec_lib.i"
  22.         INCLUDE        "libraries/dos_lib.i"
  23.  
  24.         IFD   CATCH
  25.         INCLUDE        "intuition/intuition.i"
  26. VERSION  equ    1
  27. REVISION equ    0
  28.         ENDC
  29.         
  30. MEMFLAGS        EQU        MEMF_CLEAR+MEMF_PUBLIC
  31. AbsExecBase     EQU        4
  32.  
  33. ;;;
  34. ;;;   Stack map.
  35. ;;;
  36.       OFFSET  0
  37.            ds.b    4
  38. savereg    ds.b    13*4
  39. stackbtm   ds.b    4
  40.  
  41.  
  42.  
  43. ; some usefull macros:
  44.  
  45. callsys macro
  46.         CALLLIB _LVO\1
  47.         endm
  48.         
  49.         xdef        _XCEXIT                * exit(code) is standard way to leave C.
  50.         xdef        @_XCEXIT
  51.         
  52.         xref        LinkerDB        * linker defined base value
  53.         xref        _BSSBAS                * linker defined base of BSS
  54.         xref        _BSSLEN                * linker defined length of BSS
  55.         xref        __stack
  56.  
  57.        IFD          RESIDENT
  58.         xref        RESLEN
  59.         xref        RESBASE
  60.         xref        NEWDATAL
  61.        ENDC
  62.         
  63. *       library references
  64.  
  65.         section text,code
  66.  
  67.         xref    __main                  * Name of C program to start with.
  68.         xref    __fpinit                * initialize floating point
  69.         xref    __fpterm                * terminate floating point
  70.  
  71.         xdef    firstseg
  72.  
  73. firstseg:
  74. *start:
  75.         movem.l d1-d6/a0-a6,-(a7)       * save registers
  76.  
  77.         move.l  a0,a2                   * save command pointer
  78.         move.l  d0,d2                   * and command length
  79.         lea     LinkerDB,a4             * load base register
  80.         move.l  AbsExecBase.W,a6
  81.  
  82.         IFND        RESIDENT
  83.  
  84.         cmpi.w        #36,$14(a6)
  85.         bge.s         noneedtoclr
  86.         lea     _BSSBAS,a3              * get base of BSS
  87.         moveq   #0,d1
  88.         move.l  #_BSSLEN,d0             * get length of BSS in longwords
  89.         bra.s   clr_lp                  * and clear for length given
  90. clr_bss move.l  d1,(a3)+
  91. clr_lp  dbf     d0,clr_bss
  92.  
  93. noneedtoclr:
  94.         move.l  a7,_StackPtr(A4)        * Save stack ptr
  95.         move.l  a6,SysBase(A4)
  96.         movem.l    d2/a2,_CLICmdLen(a4)    * store CLI args
  97.  
  98. *------ get the size of the stack, if CLI use cli_DefaultStack
  99. *------                                 if WB use a7 - TC_SPLOWER
  100.         move.l        ThisTask(a6),A3
  101.         move.l        pr_CLI(A3),d0
  102.         beq.s         fromwb
  103.         lsl.l         #2,d0
  104.         move.l        d0,a0
  105.         move.l        cli_DefaultStack(a0),d0
  106.         lsl.l         #2,d0             * # longwords -> # bytes
  107.         bra.s         dostack
  108.  
  109. fromwb:
  110.         move.l        a7,d0                         
  111.         sub.l         TC_SPLOWER(a3),d0
  112. dostack:
  113.  
  114. *------ Set __base for stack checking
  115.         move.l       a7,d1
  116.         sub.l        d0,d1               * get top of stack
  117.         add.l        #128,D1             * allow for parms overflow
  118.         move.l       D1,__base(A4)       * save for stack checking
  119.         
  120.         cmp.l        __stack(a4),d0
  121.         bcc.s        nochange        
  122.  
  123. *-- current stack is not as big as __stack says it needs
  124. *-- to be. Allocate a new one.
  125.         move.l        __stack(a4),d0
  126.         add.l         #128,d0           * extra room
  127.         move.l        d0,newstacksize(a4)
  128.  
  129.         move.l        #MEMFLAGS,d1
  130.         callsys       AllocMem
  131.         tst.l         d0
  132.         beq.w         return
  133.         
  134.         move.l        d0,newstack(a4)
  135.         add.l         #128,d0           * extra room
  136.         move.l        d0,__base(a4)
  137.         
  138.         add.l         __stack(a4),d0
  139.         move.l        d0,d1
  140.         
  141. *-- If we're running under 2.0, call StackSwap to set up
  142. *-- the new stack. Otherwise, just jam the new value into
  143. *-- A7.        
  144.         cmpi.w        #36,$14(a6)
  145.         blt.s         no20
  146.  
  147.         move.l        d0,mystk_Pointer(a4)
  148.         move.l        d1,mystk_Upper(a4)
  149.         sub.l         newstacksize(a4),d1
  150.         lea           mystk_Lower(a4),a0
  151.         move.l        d1,(a0)
  152.         callsys       StackSwap
  153.  
  154.         bra.s         nochange
  155.            
  156. no20:   move.l        d0,a7
  157.  
  158. nochange:
  159.  
  160.         ENDC
  161.  
  162. clrwb:
  163.         clr.l        _WBenchMsg(A4)
  164.  
  165. *-----  clear any pending signals
  166.         moveq         #0,d0
  167.         move.l        #$00003000,d1
  168.         callsys       SetSignal
  169.         move.l        ThisTask(a6),A3
  170.  
  171. *------ attempt to open DOS library:
  172.         lea           DOSName(PC),A1
  173.         callsys       OldOpenLibrary
  174.         move.l        D0,DOSBase(A4)
  175.         bne.s         ok2
  176.         moveq.l       #100,d0
  177.         bra.w         exit2
  178.  
  179. ok2:
  180.  
  181. *------ are we running as a son of Workbench?
  182. ;        move.l        pr_CurrentDir(A3),__curdir(A4)
  183.         tst.l         pr_CLI(A3)
  184.         beq.w         fromWorkbench
  185.         
  186. *=======================================================================
  187. *====== CLI Startup Code ===============================================
  188. *=======================================================================
  189. *
  190. * Entry: D2 = command length
  191. *        A2 = Command pointer
  192. fromCLI:
  193. *------ find command name:
  194.         move.l      pr_CLI(a3),a0
  195.         add.l       a0,a0                   * bcpl pointer conversion
  196.         add.l       a0,a0
  197.         move.l      cli_CommandName(a0),a1
  198.  
  199.         add.l       a1,a1                   * bcpl pointer conversion
  200.         add.l       a1,a1
  201.  
  202. *------ collect parameters:
  203.         move.l      d2,d0                   * get command line length
  204.         moveq.l     #0,d1
  205.         move.b      (a1)+,d1
  206.         move.l      a1,_ProgramName(A4)
  207.         add.l       d1,d0                   * add length of command name
  208.         addq.l      #7,d0                   * allow for space after command, quotes
  209.                                             * and null terminator, as well as 
  210.         andi.w      #$fffc,D0               * force to long word boundary
  211.         move.l      d0,Commandlen(a4)
  212.    
  213.         movem.l     d1/a1,-(a7)
  214.         move.l      #MEMFLAGS,d1
  215.         callsys     AllocMem
  216.         movem.l     (a7)+,d1/a1
  217.         tst.l       d0
  218.         bne.s       ok_copy
  219.    
  220.         moveq.l     #20,d0                  * what should the return code be for out of mem?
  221.         move.l      d0,-(a7)                * put a return code on the stack
  222.         beq.w       nodofree                * Was exitToDOS
  223.    
  224. ok_copy:
  225.         move.l      d0,a0
  226.         move.l      d0,Commandbuf(a4)
  227.          
  228. *------ copy command line into memory
  229.         move.l     d2,d0                    * get command line length
  230.         subq.l     #1,d0
  231.         add.l      d1,d2
  232.    
  233. copy_line:
  234.         move.b     0(A2,D0.W),2(A0,D2.W)    * copy command line to stack
  235.         subq.l     #1,d2
  236.         dbf        d0,copy_line
  237.         move.b     #' ',2(a0,d2.w)          * add space between command and parms
  238.         subq.l     #1,d2
  239.         move.b     #'"',2(a0,d2.w)          * add end quote
  240.    
  241. copy_cmd:
  242.         move.b     0(a1,d2.w),1(a0,d2.w)    * copy command name to stack
  243.         dbf        d2,copy_cmd
  244.         move.b     #'"',(a0)
  245.         move.l     A0,-(A7)                 * push command line address
  246.         bra.s      main                     * call C entrypoint
  247.  
  248. *=======================================================================
  249. *====== Workbench Startup Code =========================================
  250. *=======================================================================
  251.  
  252. fromWorkbench:
  253.  
  254. *------ we are now set up.  wait for a message from our starter
  255.         lea        pr_MsgPort(A3),a0         * our process base
  256.         callsys    WaitPort
  257.         lea        pr_MsgPort(A3),a0         * our process base
  258.         callsys    GetMsg
  259.         move.l     d0,_WBenchMsg(a4)
  260.         move.l     d0,-(SP)
  261.  
  262.         move.l     d0,a2                     * get first argument
  263.         move.l     sm_ArgList(a2),d0
  264.         beq.s      do_main
  265.         move.l     DOSBase(a4),a6
  266.         move.l     d0,a0
  267.         move.l     wa_Lock(a0),d1
  268.         callsys    DupLock
  269. ;        move.l     d0,__curdir(A4)
  270.         move.l     d0,d1
  271.         callsys    CurrentDir
  272.         move.l        d0,wblock(a4)
  273.  
  274. do_main:
  275.         move.l     _WBenchMsg(A4),a0         * get address of workbench message
  276.         move.l     a0,-(a7)                  * push argv
  277.         pea        NULL(a4)                  * push argc
  278.         move.l     sm_ArgList(a0),a0         * get address of arguments
  279.         move.l     wa_Name(a0),_ProgramName(A4) * get name of program
  280.  
  281. *=============================================
  282. *------ common code --------
  283. *=============================================
  284.  
  285. main    jsr        __fpinit(PC)   * Initialize floating point and constructors
  286.         tst.l      d0
  287.         bne.s      exit2
  288.         jsr        __main(PC)     * call C entrypoint
  289.         moveq.l    #0,d0                     * set successful status
  290.         bra.s      exit2
  291. *
  292.  
  293. XCEXIT:
  294. _XCEXIT:
  295.         move.l     4(SP),d0                  * extract return code
  296. @XCEXIT:
  297. @_XCEXIT:
  298. exit2:
  299.  
  300. *-- Save Return Code
  301.         move.l     _StackPtr(a4),a2
  302.         move.l     d0,-(a2)
  303.  
  304. *-- Swap back to original stack
  305. *-- If we're running under 2.0, call StackSwap
  306. *-- Otherwise, just jam the new value into a7
  307.         move.l     AbsExecBase.W,A6
  308.  
  309.         cmpi.w     #36,$14(a6)
  310.         blt.s      noswap
  311.  
  312.         tst.l      mystk_Lower(a4)
  313.         beq.s      noswap
  314.  
  315.         lea        mystk_Lower(a4),a0
  316.         subq.l     #4,mystk_Pointer(a4)      * make room for the ret code  
  317.         callsys    StackSwap
  318.            
  319. noswap:  
  320.  
  321.         movea.l    a2,a7                     * restore stack ptr
  322.                 
  323.         move.l     _ONEXIT(A4),d0            * exit trap function?
  324.         beq.s      exit3
  325.         move.l     d0,a0
  326.         jsr        (a0)
  327. exit3:
  328.         jsr        __fpterm(PC)              * clean up any floating point
  329.  
  330.         ifnd       RESIDENT
  331. *------ free the stack if we allocated one
  332.         move.l     newstacksize(a4),d0
  333.         beq.s      exit4
  334.         move.l     newstack(a4),a1
  335.         move.l     AbsExecBase.W,A6
  336.         callsys    FreeMem
  337.         endc
  338.  
  339. exit4:
  340. *------ if we ran from CLI, skip workbench cleanup:
  341.         tst.l      _WBenchMsg(A4)
  342.         beq.s      exitToDOS
  343.         move.l     DOSBase(A4),a6
  344.         move.l        wblock(a4),d1
  345.         callsys        CurrentDir
  346.         move.l    d0,d1
  347.         callsys    UnLock
  348. done_5:
  349. *------ return the startup message to our parent
  350. *       we forbid so workbench can't UnLoadSeg() us
  351. *       before we are done:
  352.         move.l     AbsExecBase.W,A6
  353.         callsys    Forbid
  354.         move.l     _WBenchMsg(a4),a1
  355.         callsys    ReplyMsg
  356.         bra.s      nodofree
  357.  
  358. exitToDOS:
  359.         move.l     AbsExecBase.W,a6
  360.  
  361. *------ free the command line buffer
  362.         move.l     Commandlen(a4),d0
  363.         beq.s      nodofree
  364.         move.l     Commandbuf(a4),a1
  365.         callsys    FreeMem
  366.    
  367. *------ this rts sends us back to DOS:
  368. nodofree:
  369.         move.l     DOSBase(A4),a1
  370.         callsys    CloseLibrary              * close Dos library
  371.  
  372.         move.l     (a7)+,d0
  373.  
  374. return:        
  375.         movem.l    (a7)+,d1-d6/a0-a6
  376.         rts
  377.  
  378. DOSName dc.b    'dos.library',0
  379.  
  380.         section __MERGED,BSS
  381.  
  382.         xdef    NULL,SysBase,DOSBase
  383.     xref    _FPERR
  384.  
  385.         xref    _WBenchMsg
  386.         xref    _OSERR,_SIGFPE,_ONERR,_ONEXIT,_ONBREAK
  387.         xref    _SIGINT
  388.         xref    _ProgramName,_StackPtr,__base
  389.  
  390.         ifd        CATCH
  391.         xdef        _ONGURU,_FMEM,_STAKOffset
  392.         endc
  393.  
  394. wblock        ds.b    4
  395.  
  396. NULL          ds.b    4        
  397. DOSBase       ds.b    4
  398. SysBase       ds.b    4
  399. Commandbuf    ds.b    4
  400. Commandlen    ds.b    4
  401. mystk_Lower   ds.b    4
  402. mystk_Upper   ds.b    4
  403. mystk_Pointer ds.b    4
  404.  
  405. newstack     ds.b    4                   * pointer to new stack (if needed)
  406. newstacksize ds.b    4                   * size of new stack
  407.  
  408.     xdef    _CLICmdLen
  409.     xdef    _CLICmd
  410.  
  411.  
  412. _CLICmdLen:    ds.b    4
  413. _CLICmd:    ds.b    4
  414.  
  415.  
  416.              END
  417.