Initial commit
[amiga/OpenBoopsi.git] / common / ClassLib.s
1 ******************************************************************************
2 *
3 * $VER: ClassLib.asm (5.9.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         INCLUDE "exec/funcdef.i"
23         INCLUDE "exec/exec_lib.i"
24
25
26 ; BOOPSI class libraries should use this structure as the base for their
27 ; library data.  This allows developers to obtain the class pointer for
28 ; performing object-less inquiries.
29
30         STRUCTURE ClassBase,0
31         STRUCT   cl_Lib,LIB_SIZE        ; Embedded library
32         UWORD    cl_Pad                 ; Align the structure
33         APTR     cl_Class               ; Class pointer
34         APTR     cl_SegList             ; SegList pointer
35         LABEL    ClassLibrary_SIZEOF
36
37 ;---------------------------------------------------------------------------
38
39         XDEF    _LibFuncTable
40         XDEF    _LibDataTable
41
42         XREF    _LibName
43         XREF    _LibId
44         XREF    __UserLibInit
45         XREF    __UserLibCleanup
46
47         XREF    __GetEngine
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 * pad, 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 will 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
95 _LibFuncTable:
96         dc.l    _LibOpen
97         dc.l    _LibClose
98         dc.l    _LibExpunge
99         dc.l    _LibExtFunc
100         dc.l    __GetEngine
101         dc.l    -1
102
103 ;V_DEF  MACRO
104 ;       dc.w    \1 + (* - _LibFuncTable)
105 ;       ENDM
106 ;
107 ;_LibFuncTable:
108 ;       dc.w    -1              ; It's weird: the cool way didn't work for me :-(
109 ;       V_DEF   _LibOpen
110 ;       V_DEF   _LibClose
111 ;       V_DEF   _LibExpunge
112 ;       V_DEF   _LibExtFunc
113 ;       V_DEF   __GetEngine
114 ;       dc.w    -1
115
116
117
118 _LibDataTable
119         INITBYTE        LN_TYPE,NT_LIBRARY
120         INITLONG        LN_NAME,_LibName
121         INITBYTE        LN_PRI,-5
122         INITBYTE        LIB_FLAGS,(LIBF_SUMUSED!LIBF_CHANGED)
123         INITWORD        LIB_VERSION,LIBVERSION
124         INITWORD        LIB_REVISION,LIBREVISION
125         INITLONG        LIB_IDSTRING,_LibId
126         dc.w            0
127
128
129         CNOP    0,4
130
131
132 * The following function will be called at startup time.
133 *
134 * Inputs:
135 *       LibPtr (d0) - Pointer to the library base, initialized due to the
136 *                       specifications in DataTable
137 *       SegList (a0) - BPTR to the segment list
138 *       _SysBase (a6) - The usual ExecBase pointer
139 *
140 * Result:
141 *       LibPtr, if all was okay and the library may be linked into the
142 *       system library list. NULL otherwise.
143 *
144 _LibInit:
145         move.l  d0,a1
146         move.l  a0,cl_SegList(a1)               ; Save SegList
147
148 ; Check CPU for 68020 or better
149         IFD             _MC68020_
150         move.w  AttnFlags(a6),d1
151         btst.w  #AFB_68020,d1
152         beq.s   fail$
153         ENDC
154
155         move.l  a6,-(sp)                        ; Save SysBase
156         move.l  d0,a6                           ; Put our base in a6
157         jsr     __UserLibInit                   ; Call user init
158         move.l  a6,a1                           ; save our base to a1
159         move.l  (sp)+,a6                        ; Retrieve SysBase
160         tst.l   d0
161         beq.s   fail$
162         rts
163
164 fail$
165         bsr     FreeBase                        ; Free library base
166         moveq   #0,d0
167         rts
168
169
170 * The following functions are called from exec.library/OpenLibrary(),
171 * exec.library/CloseLibrary() and exec.library/ExpungeLibrary(),
172 * respectively. Exec passes our library base pointer in A6.
173 *
174 * Task switching will be turned off while these functions are being
175 * executed, so they must be as short as possible.  As the data inside
176 * the library base is protected with Forbid(), these functions must
177 * not make calls which would explicitly or implicitly turn on multitasking.
178 * This includes opening other disk based libraries.  The problem may be
179 * overcame by protecting the library base with a SignalSemaphore.
180 *
181
182
183 * This function is called from exec.library/OpenLibrary().
184 *
185 * Inputs:
186 *       LibPtr (a6) - Pointer to the library base
187 *       Version (d0) - The suggested version number
188 *
189 * Result:
190 *       LibPtr, if successful, NULL otherwise
191 *
192
193 _LibOpen:
194         addq.w  #1,LIB_OPENCNT(a6)
195         bclr.b  #LIBB_DELEXP,LIB_FLAGS(a6)      ; Prevent delayed expunge
196         move.l  a6,d0
197         rts
198
199
200
201 * This function is called from exec/CloseLibrary().
202 *
203 * Inputs:
204 *       LibPtr (A6) - pointer to the library base as returned from OpenLibrary().
205 *
206 * Result:
207 *       Segment list of the library (see arguments of _LibInit), if there
208 *       was a delayed expunge and the library is no longer open, NULL
209 *       otherwise.
210 *
211 _LibClose:
212         subq.w  #1,LIB_OPENCNT(a6)
213         tst.w   LIB_OPENCNT(a6)
214         bne.s   .NoExpunge
215         btst.b  #LIBB_DELEXP,LIB_FLAGS(a6)
216         beq.s   .NoExpunge
217
218         bra.s   _LibExpunge
219
220 .NoExpunge
221         moveq.l #0,d0
222         rts
223
224
225
226 * This function is called from exec.library/RemoveLibrary().
227 *
228 * Inputs:
229 *       LibPtr (A6) - pointer to the library base.
230 *
231 * Result:
232 *       Segment list of the library (see arguments of _LibInit()),
233 *       if the library isn't opened currently, NULL otherwise.
234 *
235
236 _LibExpunge:
237
238         ; Flag library base for delayed expunge
239         bset.b  #LIBB_DELEXP,LIB_FLAGS(a6)
240         tst.w   LIB_OPENCNT(a6)         ; Only expunge if OpenCnt == 0
241         bne.s   .DoNotExpunge
242
243 .NotOpen
244
245         jsr     __UserLibCleanup        ; Call user cleanup code
246         tst.l   d0
247         beq.s   .DoNotExpunge
248
249         move.l  cl_SegList(a6),-(sp)    ; Save SegList pointer
250
251         move.l  a6,a1
252         REMOVE                          ; Remove us from Exec library list.
253
254
255 ; Free the library base
256
257         move.l  a6,a1                   ; LibBase
258         move.l  a6,-(sp)                ; Save A6
259         move.l  4.w,a6                  ; Load SysBase
260         bsr             FreeBase                ; Free our library base
261         move.l  (sp)+,a6                ; Restore A6
262
263         move.l  (sp)+,d0                ; Return our SegList
264         rts
265
266 .DoNotExpunge
267
268 ; NOTE: I'm falling in _LibExtFunc from here!
269
270
271
272 * Dummy function to return 0
273
274 _LibExtFunc:
275         moveq   #0,d0
276         rts
277
278
279 * Frees our library base
280 *
281 * Inputs:
282 *       LibBase (a1) - Pointer to Library structure.
283 *       SysBase (a6) - Pointer to SysBase
284 *
285 FreeBase:
286         moveq.l #0,d0
287         move.l  a1,a0
288         move.w  LIB_NEGSIZE(a0),d0
289         suba.l  d0,a1                   ; Get pointer to real start of library base
290         add.w   LIB_POSSIZE(a0),d0      ; Total library size (LIB_POSSIZE + LIB_NEGSIZE)
291         jsr             _LVOFreeMem(a6)
292         rts
293
294 ;-----------------------------------------------------------------------
295
296 _ENDCODE
297
298         END