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

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