home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff396.lha / resident / Resident.asm < prev    next >
Assembly Source File  |  1990-10-29  |  9KB  |  319 lines

  1. *--------------------------------------------------------------------*
  2. *    Startup code to create reentrant program files using the
  3. *    Manx Aztec 'C' compiler (any version).
  4. *
  5. *    Created by:    Olaf Barthel, MXM
  6. *            Brabeckstrasse 35
  7. *            D-3000 Hannover 71
  8. *
  9. *            Federal Republic of Germany
  10. *
  11. *
  12. *            Z-Net: O.BARTHEL@A-Link-H
  13. *            Fido:  Olaf Barthel@2:247/200
  14. *            Sub:   olsen@veeble.uucp
  15. *            UUCP:  olsen%veeble@horga.as.sub.org
  16. *
  17. *    Copyright (C) 1990 by MXM, all rights reserved.
  18. *
  19. *--------------------------------------------------------------------*
  20. *
  21. *    This startup code permits to create 100% reentrant programs.
  22. *    Neither is arp.library required, nor is the program to be
  23. *    terminated via exit() (such as with Lattice/SAS 'C').
  24. *
  25. *    The following conditions must be met for the program to
  26. *    work properly:
  27. *
  28. *    1) The program MUST not use the large code/large data model.
  29. *
  30. *    2) The program MUST not use scatter loading or overlays.
  31. *
  32. *    Since the entire data segment, containing initialized
  33. *    and uninitialized data (bss), is cloned both data types
  34. *    will reside in the same type of memory (chip/public).
  35. *    This may not be a problem since it already is the default
  36. *    with the small memory/small data model.
  37. *
  38. *    Important! Your program MUST not perform a segment split
  39. *               using the detach.o?? module or its segment list
  40. *               will be deallocated. Should this happen the next
  41. *               call to your resident program will crash your
  42. *               Amiga!
  43. *
  44. *    Should you discover any 'undocumented features' or errors
  45. *    in this program, please DO inform me ASAP!
  46. *
  47. *--------------------------------------------------------------------*
  48. *
  49. *    To create a resident program, use the following sequence:
  50. *
  51. *    AS Resident.asm
  52. *    CC <Programm.c>
  53. *
  54. *    LN <Programm.o> Resident.o -Lc
  55. *
  56. *--------------------------------------------------------------------*
  57.  
  58.     include    "exec/types.i"
  59.     include    "exec/tasks.i"
  60.     include    "exec/alerts.i"
  61.     include    "exec/memory.i"
  62.     include    "exec/execbase.i"
  63.     include    "libraries/dosextens.i"
  64.  
  65. *--------------------------------------------------------------------*
  66. *
  67. *    Global macro definitions (doesn't use asmsupp.i).
  68. *
  69. *--------------------------------------------------------------------*
  70.  
  71. CALL    macro
  72.     xref    _LVO\1
  73.     jsr    _LVO\1(a6)
  74.     endm
  75.  
  76. AbsExecBase    equ    (4).w
  77.  
  78. *--------------------------------------------------------------------*
  79. *
  80. *    Global static and shared data.
  81. *
  82. *--------------------------------------------------------------------*
  83.  
  84.     dseg
  85.  
  86. DosName:
  87.     dc.b    'dos.library',0            ; Name of dos.library.
  88.  
  89. MemName:
  90.     dc.b    'MXM',0                ; Identification of the
  91.                         ; cloned data segment.
  92.  
  93.     public    __H1_org,__H1_end,__H2_org,__H2_end
  94.     public    __savsp,_SysBase,_DOSBase
  95.  
  96. *--------------------------------------------------------------------*
  97.  
  98.     cseg
  99.  
  100.     entry    .begin
  101.  
  102.     public    .begin,_geta4,__main
  103.  
  104.     mc68881
  105.  
  106. *--------------------------------------------------------------------*
  107. *
  108. *    Global entry point of the program to follow.
  109. *
  110. *--------------------------------------------------------------------*
  111.  
  112. .begin
  113.     move.l    sp,a3                ; Remember stackpointer.
  114.  
  115.     far    data
  116.     lea    __H1_org+32766,a4        ; Get the data base register.
  117.     near    data
  118.  
  119.     lea    __H1_end,a1
  120.     lea    __H2_org,a2
  121.  
  122.     cmp.l    a1,a2                ; Small code/small data?
  123.     bne    Error1                ; Obviously not!
  124.  
  125.     movem.l    d0/a0,-(sp)            ; Remember command line.
  126.  
  127.     lea    __H1_org,a1            ; Where's the data segment?
  128.     move.l    AbsExecBase,a6            ; SysBase.
  129.  
  130.     CALL    TypeOfMem            ; Check memory type
  131.  
  132.     bset    #MEMB_CLEAR,d0            ; We want clear memory.
  133.     bclr    #MEMB_FAST,d0            ; Not necessarily fast mem!
  134.  
  135. *--------------------------------------------------------------------*
  136. *
  137. *    We will create a MemEntry structure right on the stack and
  138. *    will copy the contents of the data segment to the allocated
  139. *    block of memory.
  140. *
  141. *--------------------------------------------------------------------*
  142.  
  143.     pea    (__H2_end-__H1_org).w        ; Length of data segment.
  144.     move.l    d0,-(sp)            ; Type of memory.
  145.     pea    (1).w                ; Number of entries (1).
  146.     clr.l    -(sp)                ; Node...
  147.     clr.l    -(sp)                ; Still node...
  148.     clr.l    -(sp)                ; Ever still node...
  149.  
  150.     lea    (sp),a0                ; Start of MemEntry.
  151.  
  152.     CALL    AllocEntry            ; Allocate!
  153.  
  154.     add.w    #24,sp                ; Fix the stack.
  155.  
  156.     move.l    d0,a1                ; Did we get an entry?
  157.     beq    Error2                ; Fix the stack and quit!
  158.  
  159.     pea    (a1)                ; Put it on the stack.
  160.  
  161. *--------------------------------------------------------------------*
  162. *
  163. *    To help geta4() to identify the MemEntry we will give it
  164. *    a unique name.
  165. *
  166. *--------------------------------------------------------------------*
  167.  
  168.     lea    MemName,a0            ; Get the node name.
  169.  
  170.     move.l    a0,LN_NAME(a1)            ; Put it in the MemEntry.
  171.  
  172.     move.l    ThisTask(a6),a0            ; Get current task.
  173.  
  174.     lea    TC_MEMENTRY(a0),a0        ; Look for MemList.
  175.  
  176.     CALL    AddTail                ; Add the MemEntry.
  177.  
  178.     move.l    (sp)+,a1            ; Get the MemEntry.
  179.     move.l    ML_SIZE+ME_ADDR(a1),a1        ; Remember memory block.
  180.  
  181.     lea    __H1_org,a0            ; Get start of data segment.
  182.  
  183.     move.l    #((__H1_end-__H1_org)/4)-1,d0    ; Remember its length.
  184.  
  185. *--------------------------------------------------------------------*
  186. *
  187. *    This loop will copy the contents of the data segment to
  188. *    our 'fake' segment.
  189. *
  190. *--------------------------------------------------------------------*
  191.  
  192. 1$    move.l    (a0)+,(a1)+            ; Copy data.
  193.     dbra    d0,1$
  194.  
  195. *--------------------------------------------------------------------*
  196. *
  197. *    Do the last setups for the main program.
  198. *
  199. *--------------------------------------------------------------------*
  200.  
  201. start    bsr    _geta4                ; Load the base register.
  202.     move.l    a3,__savsp            ; Set the original stack
  203.                         ; pointer.
  204.     lea    DosName,a1            ; Name of dos.library.
  205.     moveq    #0,d0                ; No special version.
  206.     CALL    OpenLibrary            ; Open the tin...
  207.     move.l    d0,_DOSBase            ; Successful?
  208.     bne    2$                ; Start the main program.
  209.  
  210.     move.l    #AG_OpenLib!AO_DOSLib,d7    ; Blast!
  211.     lea    ThisTask(a6),a5            ; Current task.
  212.     CALL    Alert                ; Call Mr.Guru.
  213.     bra    Error2                ; Finish it.
  214.  
  215. 2$    move.l    a6,_SysBase            ; Set SysBase.
  216.  
  217.     andi.w    #AFF_68881,AttnFlags(a6)    ; FPU present?
  218.     beq    3$
  219.  
  220.     lea    Restore,a5
  221.     CALL    Supervisor            ; Reset FPU.
  222.  
  223. 3$    jsr    __main                ; Call main routine.
  224.     addq.l    #8,sp                ; Fix the stack.
  225.  
  226. *--------------------------------------------------------------------*
  227. *
  228. *    If __main simply 'drops through' dos.library won't have been
  229. *    closed. To keep the counts even, we will test if DOS is still
  230. *    open and close it if necessary.
  231. *
  232. *--------------------------------------------------------------------*
  233.  
  234.     move.l    _DOSBase,a1
  235.     move.l    a1,d0                ; dos.library still open?
  236.     beq    4$                ; Don't think so.
  237.  
  238.     move.l    AbsExecBase,a6            ; SysBase.
  239.     CALL    CloseLibrary            ; Close the library.
  240.  
  241. 4$    rts                    ; Back to shell.
  242.  
  243. *--------------------------------------------------------------------*
  244.  
  245. Error2:    addq.l    #8,sp                ; Fix the stack.
  246.  
  247.     move.l    AbsExecBase,a6            ; SysBase.
  248.  
  249. *--------------------------------------------------------------------*
  250. *
  251. *    This part handles early startup failure. If this program was
  252. *    started from Workbench the startup message will probably
  253. *    be roaming around. We will intercept it and send it back
  254. *    to the caller.
  255. *
  256. *--------------------------------------------------------------------*
  257.  
  258.     move.l    ThisTask(a6),a0            ; Get current task.
  259.     tst.l    pr_CLI(a0)            ; Started from Workbench?
  260.     bne    Error1
  261.  
  262.     lea    pr_MsgPort(a0),a0        ; Remember our MsgPort.
  263.     move.l    a0,a3
  264.  
  265.     CALL    WaitPort            ; Wait for WBenchStartup.
  266.  
  267.     move.l    a3,a0                ; Return MsgPort.
  268.  
  269.     CALL    GetMsg                ; Pick up WBenchMsg.
  270.  
  271.     move.l    d0,a3                ; Remember Message.
  272.  
  273.     CALL    Forbid                ; Turn off multitasking.
  274.  
  275.     move.l    a3,a1                ; Return the message.
  276.  
  277.     CALL    ReplyMsg            ; And reply it.
  278.  
  279. Error1:    moveq    #-1,d0                ; Failed!
  280.     rts
  281.  
  282. *--------------------------------------------------------------------*
  283. *
  284. *    This subroutine will reset the FPU (if any)!
  285. *
  286. *--------------------------------------------------------------------*
  287.  
  288. Restore:
  289.     clr.l    -(sp)
  290.     frestore (sp)+                ; Reset the FPU.
  291.     rte
  292.  
  293. *--------------------------------------------------------------------*
  294. *
  295. *    One of the most important routines of this file. Sets
  296. *    the global data segment pointer to a defined value.
  297. *
  298. *--------------------------------------------------------------------*
  299.  
  300. _geta4:
  301.     movem.l    d0-d1/a0-a1/a6,-(sp)        ; Save some registers.
  302.     move.l    AbsExecBase,a6            ; SysBase.
  303.     move.l    ThisTask(a6),a0            ; Get current task.
  304.     lea    TC_MEMENTRY(a0),a0        ; Remember MemList.
  305.     lea    MemName,a1            ; Get name of MemEntry.
  306.  
  307.     CALL    FindName            ; Scan the list...
  308.  
  309.     move.l    d0,a1
  310.     move.l    ML_SIZE+ME_ADDR(a1),a4        ; Start of data segment.
  311.     lea    32766(a4),a4            ; Add the offset.
  312.  
  313.     movem.l    (sp)+,d0-d1/a0-a1/a6        ; Restore all registers.
  314.     rts
  315.  
  316. *--------------------------------------------------------------------*
  317.  
  318.     end
  319.