home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / lib_examples / sample.library.asm < prev    next >
Encoding:
Assembly Source File  |  1992-08-21  |  9.4 KB  |  305 lines

  1. *******************************************************************************************
  2. *   sample.library.asm -- Example run-time library source code
  3. *
  4. *   Assemble and link, without startup code, to create Sample.library,
  5. *     a LIBS: drawer run-time shared library
  6. *
  7. *  Linkage Info:
  8. *  FROM     sample.library.o
  9. *  LIBRARY  LIB:Amiga.lib
  10. *  TO       sample.library
  11. *******************************************************************************************
  12.  
  13.    SECTION   code
  14.  
  15.    NOLIST
  16.    INCLUDE "exec/types.i"
  17.    INCLUDE "exec/initializers.i"
  18.    INCLUDE "exec/libraries.i"
  19.    INCLUDE "exec/lists.i"
  20.    INCLUDE "exec/alerts.i"
  21.    INCLUDE "exec/resident.i"
  22.    INCLUDE "libraries/dos.i"
  23.  
  24.    INCLUDE "sampleinclude/asmsupp.i"
  25.    INCLUDE "sampleinclude/samplebase.i"
  26.    INCLUDE "sampleinclude/sample_rev.i"
  27.  
  28.    LIST
  29.  
  30.    XDEF   InitTable                    ;------ These don't have to be external but it helps
  31.    XDEF   Open                         ;------ some debuggers to have them globally visible
  32.    XDEF   Close
  33.    XDEF   Expunge
  34.    XDEF   Null
  35.    XDEF   LibName
  36.    XDEF   Double
  37.    XDEF   AddThese
  38.  
  39.    XREF   _AbsExecBase
  40.  
  41.    XLIB   OpenLibrary
  42.    XLIB   CloseLibrary
  43.    XLIB   Alert
  44.    XLIB   FreeMem
  45.    XLIB   Remove
  46.  
  47.    ; The first executable location.  This should return an error in case someone tried to
  48.    ; run you as a program (instead of loading you as a library).
  49. Start:
  50.    MOVEQ   #-1,d0
  51.    rts
  52.  
  53. ;------------------------------------------------------------------------------------------
  54. ; A romtag structure.  Both "exec" and "ramlib" look for this structure to discover magic
  55. ; constants about you (such as where to start running you from...).  The include file
  56. ; sample_rev.i (created by hand or preferable with the developer tool ``bumprev''
  57. ; resolves the VERSION, REVISION, and VSTRING.
  58. ;------------------------------------------------------------------------------------------
  59.    ; Few people will need a priority and should leave it at zero.  The RT_PRI field is used
  60.    ; in configuring the ROMs.  Use "mods" from wack to look at other romtags in the system.
  61. MYPRI   EQU   0
  62.  
  63. RomTag:
  64.                ;STRUCTURE RT,0
  65.      DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
  66.      DC.L    RomTag             ; APTR  RT_MATCHTAG
  67.      DC.L    EndCode            ; APTR  RT_ENDSKIP
  68.      DC.B    RTF_AUTOINIT       ; UBYTE RT_FLAGS
  69.      DC.B    VERSION            ; UBYTE RT_VERSION  (defined in sample_rev.i)
  70.      DC.B    NT_LIBRARY         ; UBYTE RT_TYPE
  71.      DC.B    MYPRI              ; BYTE  RT_PRI
  72.      DC.L    LibName            ; APTR  RT_NAME
  73.      DC.L    IDString           ; APTR  RT_IDSTRING
  74.      DC.L    InitTable          ; APTR  RT_INIT  table for InitResident()
  75.  
  76.    ; this is the name that the library will have
  77. LibName:   SAMPLENAME
  78.    ; standard name/version/date ID string from bumprev-created sample_rev.i
  79. IDString:  VSTRING
  80.  
  81. dosName:   DOSNAME
  82.  
  83.    ; force word alignment
  84.    ds.w   0
  85.  
  86.    ; The romtag specified that we were "RTF_AUTOINIT".  This means that the RT_INIT
  87.    ; structure member points to one of these tables below.  If the AUTOINIT bit was not
  88.    ; set then RT_INIT would point to a routine to run.
  89.  
  90. InitTable:
  91.    DC.L   SampleBase_SIZEOF ; size of library base data space
  92.    DC.L   funcTable         ; pointer to function initializers
  93.    DC.L   dataTable         ; pointer to data initializers
  94.    DC.L   initRoutine       ; routine to run
  95.  
  96.  
  97. funcTable:
  98.  
  99.    ;------ standard system routines
  100.    dc.l   Open
  101.    dc.l   Close
  102.    dc.l   Expunge
  103.    dc.l   Null
  104.  
  105.    ;------ my libraries definitions
  106.    dc.l   Double
  107.    dc.l   AddThese
  108.  
  109.    ;------ function table end marker
  110.    dc.l   -1
  111.  
  112.  
  113.    ; The data table initializes static data structures.  The format is specified in
  114.    ; exec/InitStruct routine's manual pages.  The INITBYTE/INITWORD/INITLONG routines are
  115.    ; in the file "exec/initializers.i".  The first argument is the offset from the library
  116.    ; base for this byte/word/long.  The second argument is the value to put in that cell.
  117.    ; The table is null terminated.
  118.    ; NOTE - LN_TYPE below is a correction - old example had LH_TYPE.
  119.  
  120. dataTable:
  121.         INITBYTE        LN_TYPE,NT_LIBRARY
  122.         INITLONG        LN_NAME,LibName
  123.         INITBYTE        LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  124.         INITWORD        LIB_VERSION,VERSION
  125.         INITWORD        LIB_REVISION,REVISION
  126.         INITLONG        LIB_IDSTRING,IDString
  127.         DC.L   0
  128.  
  129.    ; This routine gets called after the library has been allocated.  The library pointer is
  130.    ; in D0.  The segment list is in A0.  If it returns non-zero then the library will be
  131.    ; linked into the library list.
  132.  
  133. initRoutine:
  134.  
  135.    ;------ get the library pointer into a convenient A register
  136.    move.l   a5,-(sp)
  137.    move.l   d0,a5
  138.  
  139.    ;------ save a pointer to exec
  140.    move.l   a6,sb_SysLib(a5)
  141.  
  142.    ;------ save a pointer to our loaded code
  143.    move.l   a0,sb_SegList(a5)
  144.  
  145.    ;------ open the dos library
  146.    lea   dosName(pc),a1
  147.    CLEAR   d0
  148.    CALLSYS   OpenLibrary
  149.  
  150.    move.l   d0,sb_DosLib(a5)
  151.    bne.s   1$
  152.  
  153.    ;------ can't open the dos!  what gives
  154.    ALERT   AG_OpenLib!AO_DOSLib
  155.  
  156. 1$:
  157.    ;------ now build the static data that we need
  158.    ;
  159.    ; put your initialization here...
  160.    ;
  161.  
  162.    move.l   a5,d0
  163.    move.l   (sp)+,a5
  164.    rts
  165.  
  166. ;------------------------------------------------------------------------------------------
  167. ; here begins the system interface commands.  When the user calls OpenLibrary/CloseLibrary/
  168. ; RemoveLibrary, this eventually gets translated into a call to the following routines
  169. ; (Open/Close/Expunge).  Exec has already put our library pointer in A6 for us.  Exec has
  170. ; turned off task switching while in these routines (via Forbid/Permit), so we should not
  171. ; take too long in them.
  172. ;------------------------------------------------------------------------------------------
  173.  
  174.    ; Open returns the library pointer in d0 if the open was successful.  If the open failed
  175.    ; then null is returned.  It might fail if we allocated memory on each open, or if only
  176.    ; open application could have the library open at a time...
  177.  
  178. Open:      ; ( libptr:a6, version:d0 )
  179.  
  180.    ;------ mark us as having another opener
  181.    addq.w   #1,LIB_OPENCNT(a6)
  182.  
  183.    ;------ prevent delayed expunges
  184.    bclr   #LIBB_DELEXP,sb_Flags(a6)
  185.  
  186.    move.l   a6,d0
  187.    rts
  188.  
  189.    ; There are two different things that might be returned from the Close routine.  If the
  190.    ; library is no longer open and there is a delayed expunge then Close should return the
  191.    ; segment list (as given to Init).  Otherwise close should return NULL.
  192.  
  193. Close:      ; ( libptr:a6 )
  194.  
  195.    ;------ set the return value
  196.    CLEAR   d0
  197.  
  198.    ;------ mark us as having one fewer openers
  199.    subq.w   #1,LIB_OPENCNT(a6)
  200.  
  201.    ;------ see if there is anyone left with us open
  202.    bne.s   1$
  203.  
  204.    ;------ see if we have a delayed expunge pending
  205.    btst   #LIBB_DELEXP,sb_Flags(a6)
  206.    beq.s   1$
  207.  
  208.    ;------ do the expunge
  209.    bsr   Expunge
  210. 1$:
  211.    rts
  212.  
  213.    ; There are two different things that might be returned from the Expunge routine.  If
  214.    ; the library is no longer open then Expunge should return the segment list (as given
  215.    ; to Init).  Otherwise Expunge should set the delayed expunge flag and return NULL.
  216.    ;
  217.    ; One other important note: because Expunge is called from the memory allocator, it may
  218.    ; NEVER Wait() or otherwise take long time to complete.
  219.  
  220. Expunge:   ; ( libptr: a6 )
  221.  
  222.    movem.l   d2/a5/a6,-(sp)
  223.    move.l   a6,a5
  224.    move.l   sb_SysLib(a5),a6
  225.  
  226.    ;------ see if anyone has us open
  227.    tst.w   LIB_OPENCNT(a5)
  228.    beq   1$
  229.  
  230.    ;------ it is still open.  set the delayed expunge flag
  231.    bset   #LIBB_DELEXP,sb_Flags(a5)
  232.    CLEAR   d0
  233.    bra.s   Expunge_End
  234.  
  235. 1$:
  236.    ;------ go ahead and get rid of us.  Store our seglist in d2
  237.    move.l   sb_SegList(a5),d2
  238.  
  239.    ;------ unlink from library list
  240.    move.l   a5,a1
  241.    CALLSYS   Remove
  242.  
  243.    ;
  244.    ; device specific closings here...
  245.    ;
  246.  
  247.    ;------ close the dos library
  248.    move.l   sb_DosLib(a5),a1
  249.    CALLSYS   CloseLibrary
  250.  
  251.    ;------ free our memory
  252.    CLEAR   d0
  253.    move.l   a5,a1
  254.    move.w   LIB_NEGSIZE(a5),d0
  255.  
  256.    sub.l   d0,a1
  257.    add.w   LIB_POSSIZE(a5),d0
  258.  
  259.    CALLSYS   FreeMem
  260.  
  261.    ;------ set up our return value
  262.    move.l   d2,d0
  263.  
  264. Expunge_End:
  265.    movem.l   (sp)+,d2/a5/a6
  266.    rts
  267.  
  268. Null:
  269.    CLEAR   d0
  270.    rts
  271.  
  272. ;------------------------------------------------------------------------------------------
  273. ; Here begins the library specific functions.  Both of these simple functions are entirely
  274. ; in assembler, but you can write your functions in C if you wish and interface to them
  275. ; here.  If, for instance, the bulk of the AddThese function was written in C, you could
  276. ; interface to it as follows:
  277. ;
  278. ;   - write a C function  addTheseC(n1,n2) and compile it
  279. ;   - XDEF _addThese C  in this library code
  280. ;   - change the AddThese function code below to:
  281. ;       move.l d1,-(sp)     ;push rightmost C arg first
  282. ;       move.l d0,-(sp)     ;push other C arg(s), right to left
  283. ;       jsr    _addTheseC   ;call the C code
  284. ;       addq   #8,sp        ;fix stack
  285. ;       rts                 ;return with result in d0
  286. ;------------------------------------------------------------------------------------------
  287.  
  288. *----- Double(d0)
  289. Double:
  290.    lsl     #1,d0
  291.    rts
  292.  
  293. *----- AddThese(d0,d1)
  294. AddThese:
  295.    add.l   d1,d0
  296.    rts
  297.  
  298.    ; EndCode is a marker that show the end of your code.  Make sure it does not span
  299.    ; sections nor is before the rom tag in memory!  It is ok to put it right after the ROM
  300.    ; tag--that way you are always safe.  I put it here because it happens to be the "right"
  301.    ; thing to do, and I know that it is safe in this case.
  302. EndCode:
  303.  
  304.    END
  305.