home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377b.lha / libraries / samplelibrary / library / sample.library.asm < prev    next >
Encoding:
Assembly Source File  |  1980-02-03  |  11.0 KB  |  370 lines

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