home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 451.lha / SType / Arg.asm next >
Assembly Source File  |  1990-12-08  |  9KB  |  377 lines

  1. *
  2. * C initial startup procedure under AmigaDOS
  3. * Adapted by Jorrit Tyberghein
  4. * Use the following command line to make the cli/workbench startup
  5. * asm -iINCLUDE: Arg.asm
  6. *
  7. * Use the following command line to make the resident startup
  8. * asm -dRESIDENT -iINCLUDE: -oArgR.o Arg.asm
  9. *
  10. * Use the following command line to make the cli startup
  11. * asm -dCLI -iINCLUDE: Arg.asm
  12. *
  13.     INCLUDE    "exec/types.i"
  14.     INCLUDE    "exec/alerts.i"
  15.     INCLUDE    "exec/nodes.i"
  16.     INCLUDE    "exec/lists.i"
  17.     INCLUDE    "exec/ports.i"
  18.     INCLUDE    "exec/libraries.i"
  19.     INCLUDE    "exec/tasks.i"
  20.     INCLUDE    "exec/memory.i"
  21.     INCLUDE    "exec/execbase.i"
  22.     INCLUDE    "libraries/dos.i"
  23.     INCLUDE    "libraries/dosextens.i"
  24.     INCLUDE    "workbench/startup.i"
  25.     INCLUDE    "exec/funcdef.i"
  26.     INCLUDE    "exec/exec_lib.i"
  27.     INCLUDE    "libraries/dos_lib.i"
  28.  
  29. MEMFLAGS            EQU    MEMF_CLEAR+MEMF_PUBLIC
  30. AbsExecBase        EQU    4
  31.  
  32. * some usefull macros:
  33.  
  34. callsys    macro
  35.             CALLLIB _LVO\1
  36.             endm
  37.     
  38.         xdef        _XCEXIT                * exit(code) is standard way to leave C.
  39.         xdef        _@XCEXIT
  40.     
  41.         xref        _LinkerDB            * linker defined base value
  42.         xref        __BSSBAS                * linker defined base of BSS
  43.         xref        __BSSLEN                * linker defined length of BSS
  44.     IFD RESIDENT
  45.         xref        _RESLEN
  46.         xref        _RESBASE
  47.         xref        _NEWDATAL
  48.         xref        __stack
  49.     ENDC
  50.     
  51. *       library references
  52.  
  53.         section text,code
  54.  
  55.         xref        _argmain                * Name of C program to start with.
  56.     
  57. start:
  58.         movem.l d1-d6/a0-a6,-(a7)
  59.  
  60.         move.l    a0,a2                    * save command pointer
  61.         move.l    d0,d2                    * and command length
  62.         lea        _LinkerDB,a4        * load base register
  63.         move.l    AbsExecBase.W,a6
  64.  
  65.     IFND RESIDENT
  66. ;We do not have to clear BSS because AmigaDOS 2.0 does this for us.
  67. ;        lea        __BSSBAS,a3            * get base of BSS
  68. ;        moveq        #0,d1
  69. ;        move.l    #__BSSLEN,d0        * get length of BSS in longwords
  70. ;        bra.s        clr_lp                * and clear for length given
  71. ;clr_bss:
  72. ;        move.l    d1,(a3)+
  73. ;clr_lp:
  74. ;        dbf        d0,clr_bss
  75.         move.l    a7,__StackPtr(A4)    * Save stack ptr
  76.         move.l    a6,_SysBase(A4)
  77.     ENDC
  78.     
  79.  
  80.     IFD RESIDENT
  81.         movem.l    d2,-(a7)
  82.         movem.l    a0-a2,-(a7)
  83.  
  84. *------ get the size of the stack,    if CLI use cli_DefaultStack
  85. *------                                        if WB use a7 - TC_SPLOWER
  86.         move.l    ThisTask(a6),A3
  87.         move.l    pr_CLI(A3),d1
  88.     IFND CLI
  89.         beq.s        fromwb
  90.     ENDC
  91.         lsl.l        #2,d1
  92.         move.l    d1,a0
  93.         move.l    cli_DefaultStack(a0),d1
  94.         lsl.l        #2,d1                    * # longwords -> # bytes
  95.     IFND CLI
  96.         bra.s        dostack
  97. fromwb:
  98.         move.l    a7,d1             
  99.         sub.l        TC_SPLOWER(a3),d1     
  100.     ENDC
  101. dostack:
  102.         moveq        #0,d2                    * use d2 as flag for newstack or not
  103.         move.l    #_RESLEN,d0
  104.         cmp.l        __stack(a4),d1        * This a4 is in the original 
  105.                     * set of data
  106.         bcc.s        nochange    
  107.         move.l    __stack(a4),d1
  108.         add.l        d1,d0                    * increase size of mem for new stack
  109.         moveq        #1,d2                    * set flag
  110.         
  111. nochange:
  112.         move.l    d1,a3                    * save stacksize to set up stack checking
  113.         move.l    #MEMFLAGS,d1
  114.         callsys    AllocMem
  115.         tst.l        d0
  116.         bne.s        ok1
  117.         movem.l    (a7)+,d2/a0-a2
  118.         rts
  119.  
  120. ok1:    move.l    d0,a0
  121.         move.l    d0,a2
  122.  
  123. ;a2 now has difference
  124.         move.l    d0,a1
  125.         move.l    #_NEWDATAL,d0
  126.         sub.l        #_RESBASE,a4
  127. ;copy data over
  128. cpy:
  129.         move.l    (a4)+,(a0)+
  130.         subq.l    #1,d0
  131.         bne.s        cpy
  132. ;a4 now points at number of relocs
  133.         move.l    (a4)+,d0
  134. reloc:
  135.         beq.s        nreloc
  136.         move.l    a1,a0
  137.         add.l        (a4)+,a0                * a0 now has add of reloc
  138.         add.l        (a0),a2
  139.         move.l    a2,(a0) 
  140.         move.l    a1,a2                    * restore offset
  141.         subq.l    #1,d0
  142.         bra.s        reloc
  143.  
  144. nreloc:
  145.         move.l    a1,a4                    * set up new base register
  146.         add.l        #_RESBASE,a4
  147.  
  148.         move.l    #_RESLEN,realdatasize(a4)
  149.         movem.l    (a7)+,a0-a2
  150.  
  151.         move.l    a6,_SysBase(A4)
  152.         tst.b        d2
  153.         movem.l    (a7)+,d2                * restore d2 
  154.         movem.l    a7,__StackPtr(A4)    * Save stack ptr (movem doesn't
  155.                                             * change flags)
  156.         beq.s        nochg2
  157.  
  158. *------ set up new stack
  159.         move.l    a4,d0
  160.         sub.l        #_RESBASE,d0
  161.         add.l        #_RESLEN,d0
  162.         add.l        __stack(a4),d0        * here a4 will be pointing at the
  163.                                             * new data, but _stack will be the
  164.                                             * same if all goes well
  165.  
  166.         sub.l        #128,d0                * 128 down for good measure
  167.         move.l    d0,a7
  168.         move.l    __stack(a4),d0
  169.         move.l    d0,4(a7)                * fill in size of new stack    
  170.         add.l        d0,realdatasize(a4)* need to know how much to free later
  171.  
  172. nochg2:
  173.  
  174.     ENDC
  175.  
  176. clrwb:
  177.     IFND CLI
  178.         clr.l        _WBenchMsg(A4)
  179.     ENDC
  180.  
  181. *-----  clear any pending signals
  182.         moveq        #0,d0
  183.         move.l    #$00003000,d1
  184.         callsys    SetSignal
  185.     
  186. *------ attempt to open DOS library:
  187.         lea        DOSName(PC),A1
  188.         moveq.l    #0,D0
  189.         callsys    OpenLibrary
  190.         move.l    D0,_DOSBase(A4)
  191.         bne.s        ok2
  192.         moveq.l    #100,d0
  193.         bra.w        exit2
  194.  
  195. ok2:
  196. *------ are we running as a son of Workbench?
  197.         move.l    ThisTask(a6),A3
  198.     IFND CLI
  199.         tst.l        pr_CLI(A3)
  200.         beq.s        fromWorkbench
  201.     ENDC
  202.     
  203. *=======================================================================
  204. *====== CLI Startup Code ===============================================
  205. *=======================================================================
  206. *
  207. * Entry: D2 = command length
  208. *            A2 = Command pointer
  209. fromCLI:
  210.     
  211. *------ find command name:
  212.         move.l    pr_CLI(a3),a0
  213.         add.l        a0,a0                    * bcpl pointer conversion
  214.         add.l        a0,a0
  215.         move.l    cli_CommandName(a0),a1
  216.         add.l        a1,a1                    * bcpl pointer conversion
  217.         add.l        a1,a1
  218.  
  219. *------ collect parameters:
  220.         move.l    d2,d0                    * get command line length
  221.         moveq.l    #0,d1
  222.         move.b    (a1)+,d1
  223.         move.l    a1,_ProgramName(A4)
  224.         add.l        d1,d0                    * add length of command name
  225.         addq.l    #1,d0                    * allow for space after command 
  226.  
  227.         clr.w        -(A7)                    * set null terminator for command line
  228.         addq.l    #3,D0                    * force to longword alligned number of bytes
  229.         andi.w    #$fffc,D0            * (round up)
  230.         addq.l    #2,d0                    * one extra word
  231.         sub.l        D0,A7                    * make room on stack for command line
  232.         subq.l    #6,D0
  233.         clr.l        0(A7,D0)
  234.  
  235. *------ copy command line onto stack
  236.         move.l    d2,d0                    * get command line length
  237.         subq.l    #1,d0
  238.         add.l        d1,d2
  239.  
  240. copy_line:
  241.         move.b    0(A2,D0.W),0(A7,D2.W)    * copy command line to stack
  242.         subq.l    #1,d2
  243.         dbf        d0,copy_line
  244.         move.b    #' ',0(a7,d2.w)    * add space between command and parms
  245.         subq.l    #1,d2
  246.  
  247. copy_cmd:
  248.         move.b    0(a1,d2.w),0(a7,d2.w)    * copy command name to stack
  249.         dbf        d2,copy_cmd
  250.         move.l    A7,A1
  251.         move.l    A1,-(A7)                * push command line address
  252.     IFND CLI
  253.         bra.s        main                    * call C entrypoint
  254.  
  255. *=======================================================================
  256. *====== Workbench Startup Code =========================================
  257. *=======================================================================
  258.  
  259. fromWorkbench:
  260.  
  261. *------ we are now set up.  wait for a message from our starter
  262.         lea        pr_MsgPort(A3),a0    * our process base
  263.         callsys    WaitPort
  264.         lea        pr_MsgPort(A3),a0    * our process base
  265.         callsys    GetMsg
  266.         move.l    d0,_WBenchMsg(a4)
  267.         move.l    d0,-(SP)
  268. *
  269.         move.l    d0,a2                    * get first argument
  270.         move.l    sm_ArgList(a2),d0
  271.         beq.s        do_cons
  272.         move.l    _DOSBase(a4),a6
  273.         move.l    d0,a0
  274.         move.l    wa_Lock(a0),d1
  275.         callsys    CurrentDir
  276. do_cons:
  277.         move.l    sm_ToolWindow(a2),d1    * get the window argument
  278.         beq.s        do_main
  279.         move.l    #MODE_OLDFILE,d2
  280.         callsys    Open
  281.         move.l    d0,stdin(a4)
  282.         beq.s        do_main
  283.         lsl.l        #2,d0
  284.         move.l    d0,a0
  285.         move.l    fh_Type(a0),pr_ConsoleTask(A3)
  286. do_main:
  287.         move.l    _WBenchMsg(A4),a0    * get address of workbench message
  288.         move.l    a0,-(a7)                * push argv
  289.         moveq        #0,d0
  290.         move.l    d0,-(a7)                * push argc
  291.         move.l    sm_ArgList(a0),a0    * get address of arguments
  292.         move.l    wa_Name(a0),_ProgramName(A4)    * get name of program
  293.     ENDC
  294.  
  295. *=============================================
  296. *------ common code --------
  297. *=============================================
  298.  
  299. main
  300.         jsr        _argmain(PC)        * call C entrypoint
  301.         moveq.l    #0,d0                    * set successful status
  302.         bra.s        exit2
  303. *
  304.  
  305. _XCEXIT:
  306.         move.l    4(SP),d0                * extract return code
  307. _@XCEXIT:
  308. exit2:
  309.         move.l    d0,-(a7)
  310.         move.l    AbsExecBase.W,a6
  311.         move.l    _DOSBase(A4),a1
  312.         callsys    CloseLibrary        * close Dos library
  313.  
  314. done_1c:
  315. *------ if we ran from CLI, skip workbench cleanup:
  316.     IFND CLI
  317.         tst.l        _WBenchMsg(A4)
  318.         beq.s        exitToDOS
  319.         move.l    stdin(a4),d1
  320.         beq.s        done_4
  321.         callsys    Close
  322. done_4:
  323.  
  324. *------ return the startup message to our parent
  325. *       we forbid so workbench can't UnLoadSeg() us
  326. *       before we are done:
  327.         move.l    AbsExecBase.W,A6
  328.         callsys    Forbid
  329.         move.l    _WBenchMsg(a4),a1
  330.         callsys    ReplyMsg
  331.     ENDC
  332.  
  333. *------ this rts sends us back to DOS:
  334. exitToDOS:
  335.     IFD RESIDENT
  336.         move.l    realdatasize(a4),d0
  337.         move.l    a4,a1
  338.         sub.l        #_RESBASE,a1
  339.         move.l    AbsExecBase.W,a6
  340.         move.l    (A7)+,d6
  341.         movea.l    __StackPtr(a4),a5
  342.         callsys    FreeMem
  343.         move.l    d6,d0
  344.         movea.l    a5,sp
  345.     ELSE
  346.         move.l    (A7)+,D0
  347.         movea.l    __StackPtr(a4),SP    * restore stack ptr
  348.     ENDC
  349.  
  350.         movem.l    (a7)+,d1-d6/a0-a6
  351.         rts
  352.  
  353.  
  354. DOSName
  355.         dc.b        'dos.library',0
  356.  
  357.         section __MERGED,BSS
  358. *
  359.         xdef        _SysBase,_WBenchMsg
  360.         xdef        _ProgramName,__StackPtr,_DOSBase
  361.  
  362. *
  363.     ifd RESIDENT
  364. realdatasize
  365.         ds.b        4                        * size of memory allocated for data +
  366.                                             * possible stack
  367.     endc
  368.  
  369. _SysBase            ds.b    4
  370. _WBenchMsg        ds.b    4
  371. __StackPtr        ds.b    4
  372. stdin                ds.b    4
  373. _DOSBase            ds.b    4
  374. _ProgramName    ds.b    4
  375.         END
  376.