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