Initial commit.
[amiga/xmodule.git] / RomTag.asm
1 ******************************************************************************
2 *
3 * $VER: RomTag.asm (1.21.97)
4 *
5 * Copyright (C) 1995,96,97 by Bernardo Innocenti
6 *
7 ******************************************************************************
8 *
9 * This source is based on the RomTag.asm source I've found somewhere :-)
10 *
11 *
12         INCLUDE "exec/types.i"
13         INCLUDE "exec/macros.i"
14         INCLUDE "exec/libraries.i"
15         INCLUDE "exec/lists.i"
16         INCLUDE "exec/alerts.i"
17         INCLUDE "exec/initializers.i"
18         INCLUDE "exec/resident.i"
19         INCLUDE "exec/execbase.i"
20         INCLUDE "libraries/dos.i"
21
22 ; BOOPSI class libraries should use this structure as the base for their
23 ; library data.  This allows developers to obtain the class pointer for
24 ; performing object-less inquiries.
25
26         STRUCTURE ClassBase,0
27         STRUCT   cl_Lib,LIB_SIZE        ; Embedded library
28         UWORD    cl_Pad                 ; Align the structure
29         APTR     cl_Class               ; Class pointer
30         APTR     cl_SegList             ; SegList pointer
31         LABEL    ClassLibrary_SIZEOF
32
33 ;---------------------------------------------------------------------------
34
35         XDEF    _LibFuncTable
36         XDEF    _LibDataTable
37
38         XREF    _LibName
39         XREF    _LibId
40         XREF    __UserLibInit
41         XREF    __UserLibCleanup
42
43         XREF    __GetEngine
44
45         IFD             XMHOOK
46         XREF    __SetupXMHook
47         ENDC
48
49 ;---------------------------------------------------------------------------
50
51         SECTION Code
52
53 ; First executable location, must return an error to the caller
54
55         moveq   #-1,d0
56         rts
57
58 ;---------------------------------------------------------------------------
59
60 _ROMTAG
61         DC.W    RTC_MATCHWORD   ; UWORD RT_MATCHWORD
62         DC.L    _ROMTAG         ; APTR  RT_MATCHTAG
63         DC.L    _ENDCODE        ; APTR  RT_ENDSKIP
64         DC.B    RTF_AUTOINIT    ; UBYTE RT_FLAGS
65         DC.B    LIBVERSION      ; UBYTE RT_VERSION
66         DC.B    NT_LIBRARY      ; UBYTE RT_TYPE
67         DC.B    0               ; BYTE  RT_PRI  <--- WARNING: Using negative values here will cause trouble!
68         DC.L    _LibName        ; APTR  RT_NAME
69         DC.L    _LibId          ; APTR  RT_IDSTRING
70         DC.L    _LibInitTable   ; APTR  RT_INIT
71
72
73 * The RomTag specified that we were RTF_AUTOINIT. This means that rt_Init
74 * points to the table below. (Without RTF_AUTOINIT it would point to a
75 * routine to run.)
76 *
77 * Our library base is a standard struct Library, followed by a WORD
78 * padding, a pointer to the boopsi Class structure of the external
79 * boopsi class and a pointer to our SegList.  The SegList pointer
80 * will be returned by LibExpunge() in order to have our code UnloadSeg()'ed
81 * The Class pointer should be initialized by UserLibInit().
82
83 _LibInitTable
84         dc.l    ClassLibrary_SIZEOF
85         dc.l    _LibFuncTable
86         dc.l    _LibDataTable
87         dc.l    _LibInit
88
89
90
91 * Table of functions included in this library; the first 4 are the same
92 * for any library and for internal Exec use only.
93
94 V_DEF   MACRO
95         dc.w    \1 + (* - _LibFuncTable)
96         ENDM
97
98 _LibFuncTable
99 *       dc.w    -1              ; It's weird... The cool way didn't work for me 8-(
100 *       V_DEF   _LibOpen
101 *       V_DEF   _LibClose
102 *       V_DEF   _LibExpunge
103 *       V_DEF   _LibExtFunc
104 *       V_DEF   __GetEngine
105 *       IFD     XMHOOK
106 *       V_DEF   __SetupXMHook
107 *       ENDC
108 *       dc.w    -1
109
110         dc.l    _LibOpen
111         dc.l    _LibClose
112         dc.l    _LibExpunge
113         dc.l    _LibExtFunc
114         dc.l    __GetEngine
115         IFD     XMHOOK
116         dc.l    __SetupXMHook
117         ENDC
118         dc.l    -1
119
120
121 _LibDataTable
122         INITBYTE        LN_TYPE,NT_LIBRARY
123         INITLONG        LN_NAME,_LibName
124         INITBYTE        LN_PRI,-5
125         INITBYTE        LIB_FLAGS,(LIBF_SUMUSED!LIBF_CHANGED)
126         INITWORD        LIB_VERSION,LIBVERSION
127         INITWORD        LIB_REVISION,LIBREVISION
128         INITLONG        LIB_IDSTRING,_LibId
129         dc.w            0
130
131
132         CNOP    0,4
133
134
135 * The following function will be called at startup time.
136 *
137 * Inputs:
138 *       LibPtr (d0) - Pointer to the library base, initialized due to the
139 *                       specifications in DataTable
140 *       SegList (a0) - BPTR to the segment list
141 *       _SysBase (a6) - The usual ExecBase pointer
142 *
143 * Result:
144 *       LibPtr, if all was okay and the library may be linked into the
145 *       system library list. NULL otherwise.
146 *
147 _LibInit:
148         move.l  d0,a1
149         move.l  a0,cl_SegList(a1)               ; Save SegList
150
151 ; Check CPU for 68020 or better
152         IFD             _MC68020_
153         move.w  AttnFlags(a6),d1
154         btst.w  #AFB_68020,d1
155         beq.s   fail$
156         ENDC
157
158         move.l  a6,-(sp)                        ; Save SysBase
159         move.l  d0,a6                           ; Put our base in a6
160         jsr     __UserLibInit                   ; Call user init
161         move.l  a6,a1                           ; save our base to a1
162         move.l  (sp)+,a6                        ; Retrieve SysBase
163         tst.l   d0
164         beq.s   fail$
165         rts
166
167 fail$
168         bsr     FreeBase                        ; Free library base
169         moveq   #0,d0
170         rts
171
172
173 * The following functions are called from exec.library/OpenLibrary(),
174 * exec.library/CloseLibrary() and exec.library/ExpungeLibrary(),
175 * respectively. Exec passes our library base pointer in A6.
176 *
177 * Task switching will be turned off while these functions are being
178 * executed, so they must be as short as possible.  As the data inside
179 * the library base is protected with Forbid(), these functions must
180 * not make calls which would explicitly or implicitly turn on multitasking.
181 * This includes opening other disk based libraries.  The problem may be
182 * overcame by protecting the library base with a SignalSemaphore.
183 *
184
185
186 * This function is called from exec.library/OpenLibrary().
187 *
188 * Inputs:
189 *       LibPtr (a6) - Pointer to the library base
190 *       Version (d0) - The suggested version number
191 *
192 * Result:
193 *       LibPtr, if successful, NULL otherwise
194 *
195
196 _LibOpen:
197         addq.w  #1,LIB_OPENCNT(a6)
198         bclr.b  #LIBB_DELEXP,LIB_FLAGS(a6)      ; Prevent delayed expunge
199         move.l  a6,d0
200         rts
201
202
203
204 * This function is called from exec/CloseLibrary().
205 *
206 * Inputs:
207 *       LibPtr (A6) - pointer to the library base as returned from OpenLibrary().
208 *
209 * Result:
210 *       Segment list of the library (see arguments of _LibInit), if there
211 *       was a delayed expunge and the library is no longer open, NULL
212 *       otherwise.
213 *
214 _LibClose:
215         subq.w  #1,LIB_OPENCNT(a6)
216         tst.w   LIB_OPENCNT(a6)
217         bne.s   .NoExpunge
218         btst.b  #LIBB_DELEXP,LIB_FLAGS(a6)
219         beq.s   .NoExpunge
220
221         bra.s   _LibExpunge
222
223 .NoExpunge
224         moveq.l #0,d0
225         rts
226
227
228
229 * This function is called from exec.library/RemoveLibrary().
230 *
231 * Inputs:
232 *       LibPtr (A6) - pointer to the library base.
233 *
234 * Result:
235 *       Segment list of the library (see arguments of _LibInit()),
236 *       if the library isn't opened currently, NULL otherwise.
237 *
238
239 _LibExpunge:
240
241         ; Flag library base for delayed expunge
242         bset.b  #LIBB_DELEXP,LIB_FLAGS(a6)
243         tst.w   LIB_OPENCNT(a6)         ; Only expunge if OpenCnt == 0
244         bne.s   .DoNotExpunge
245
246 .NotOpen
247
248         jsr     __UserLibCleanup        ; Call user cleanup code
249         tst.l   d0
250         beq.s   .DoNotExpunge
251
252         move.l  cl_SegList(a6),-(sp)    ; Save SegList pointer
253
254         move.l  a6,a1
255         REMOVE                          ; Remove us from Exec library list.
256
257
258 ; Free the library base
259
260         move.l  a6,a1                   ; LibBase
261         move.l  a6,-(sp)                ; Save A6
262         move.l  4.w,a6                  ; Load SysBase
263         bsr             FreeBase                ; Free our library base
264         move.l  (sp)+,a6                ; Restore A6
265
266         move.l  (sp)+,d0                ; Return our SegList
267         rts
268
269 .DoNotExpunge
270
271 ; NOTE: I'm falling in _LibExtFunc from here!
272
273
274
275 * Dummy function to return 0
276
277 _LibExtFunc:
278         moveq   #0,d0
279         rts
280
281
282 * Frees our library base
283 *
284 * Inputs:
285 *       LibBase (a1) - Pointer to Library structure.
286 *       SysBase (a6) - Pointer to SysBase
287 *
288 FreeBase:
289         moveq.l #0,d0
290         move.l  a1,a0
291         move.w  LIB_NEGSIZE(a0),d0
292         suba.l  d0,a1                   ; Get pointer to real start of library base
293         add.w   LIB_POSSIZE(a0),d0      ; Total library size (LIB_POSSIZE + LIB_NEGSIZE)
294         JSRLIB  FreeMem
295         rts
296
297 ;-----------------------------------------------------------------------
298
299 _ENDCODE
300
301         END