Initial revision
[ssr] / StraySrc / Libraries / Quartz / s / kernel
1 ;
2 ; kernel.s
3 ;
4 ; Quartz module support library kernel (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Quartz library.
12 ;
13 ; Quartz is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Quartz is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Quartz. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:swis
30 GET libs:header
31
32 ;----- External dependencies ------------------------------------------------
33
34 ; --- User supplied symbols ---
35
36 IMPORT quartz_name ;The module's name string
37 IMPORT quartz_help ;The help and version string
38
39 IMPORT quartz_swiChunk,WEAK ;SWI chunk number
40 IMPORT quartz_swiNames,WEAK ;SWI name table
41 IMPORT quartz_swiTrans,WEAK ;SWI name/number convert code
42 IMPORT quartz_swiCode,WEAK ;Main SWI handling code
43
44 IMPORT quartz_appCode,WEAK ;Any application code
45
46 IMPORT |Quartz$$Commands$$Base|,WEAK
47
48 ; --- Other important objects ---
49
50 IMPORT |Quartz$$Table$$Base|,WEAK
51 IMPORT |Quartz$$Table$$Limit|,WEAK
52
53 IMPORT |Quartz$$Service$$Base|,WEAK
54 IMPORT |Quartz$$Service$$Limit|,WEAK
55
56 ;----- The actual module header ---------------------------------------------
57
58 AREA |!!!Module$$Header|,CODE,READONLY
59
60 quartz__base DCD quartz_appCode ;The start entry point
61 DCD quartz__init ;Main initialisation
62 DCD quartz__closeDown ;Close down code
63 DCD quartz__service ;Service call handling
64 DCD quartz_name ;The module name string
65 DCD quartz_help ;Help/version (use setdate!)
66 DCD |Quartz$$Commands$$Base| ;The command table
67 DCD quartz_swiChunk ;The SWI chunk number
68 DCD quartz_swiCode ;The SWI entry point code
69 DCD quartz_swiNames ;The SWI name table
70 DCD quartz_swiTrans ;SWI name/number translation
71
72 ;----- Initialisation and finalisation code ---------------------------------
73
74 ; --- quartz_base ---
75 ;
76 ; On entry: --
77 ;
78 ; On exit: R0 == pointer to module base
79 ;
80 ; Use: Returns a pointer to the module's base
81
82 EXPORT quartz_base
83 quartz_base ROUT
84
85 ADR R0,quartz__base ;Point to the module base
86 MOVS PC,R14 ;And return to caller
87
88 LTORG
89
90 ; --- quartz__init ---
91 ;
92 ; On entry: R12 == pointer too where to store private word
93 ;
94 ; On exit: --
95 ;
96 ; Use: Initialises Quartz library and any client modules which feel
97 ; they want to use this mechanism.
98
99 quartz__init ROUT
100
101 STMFD R13!,{R0-R9,R14} ;Save some registers
102
103 MOV R5,R12 ;Keep private word address
104
105 ; --- Find the amount of workspace we need ---
106
107 ADR R9,quartz__base ;Find the module base address
108 LDR R7,=|Quartz$$Table$$Base|
109 LDR R8,=|Quartz$$Table$$Limit|
110 ADD R7,R9,R7 ;Convert to actual addresses
111 ADD R8,R9,R8
112
113 MOV R0,R7 ;Point at the table start
114 MOV R3,#quartz__wSize ;Get my workspace size
115
116 00quartz__init CMP R0,R8 ;Have we finished yet?
117 BGE %05quartz__init ;Yes -- exit this loop
118 LDMIA R0!,{R1,R2,R4,R6} ;Get initialisation stuff
119 ADD R3,R3,R1 ;Add on the workspace size
120 B %00quartz__init ;And loop round again
121
122 ; --- Allocate the workspace nicely ---
123
124 05quartz__init CMP R3,#0 ;Do we want any workspace?
125 BEQ %09quartz__init ;No -- don't allocate any
126
127 MOV R0,#6 ;Allocate memory from RMA
128 SWI XOS_Module ;Get the memory nicely
129 BVS %99quartz__init ;If it failed, skip to end
130 STR R2,[R12,#0] ;Store the workspace address
131 MOV R12,R2 ;Remember this address
132 STR R12,quartz__wSpace ;Save this address for later
133
134 ; --- Now initialise the first words ---
135
136 09quartz__init MOV R0,R7 ;Point to the table base
137 MOV R6,R12 ;Keep the workspace address
138 MOV R14,#0 ;For zeroing things
139
140 10quartz__init CMP R0,R8 ;Have we finished yet?
141 BGE %19quartz__init ;Yes -- exit the loop then
142 LDMIA R0!,{R1-R4} ;Load the table entries
143 CMP R1,#0 ;Does he have any workspace?
144 STRNE R6,[R9,R2] ;Yes -- store workspace addr
145 STRNE R14,[R6,#0] ;And initialise first word
146 ADD R6,R6,R1 ;Move the workspace addr on
147 B %10quartz__init ;Now go round for the rest
148
149 ; --- Finally initialise all the other sections ---
150
151 19quartz__init MOV R6,R7 ;Get the start pointer nicely
152 20quartz__init CMP R6,R8 ;Have we finished yet?
153 BGE %30quartz__init ;Yes -- wrap it all up
154 LDMIA R6!,{R1-R4} ;Load the initialisation info
155 CMP R3,#0 ;Does he want initialising?
156 MOVNE R14,PC ;Yes -- set up return address
157 ADDNE PC,R9,R3 ;And call his routine
158 BVS %95quartz__init ;Tidy up if it failed
159 ADD R12,R12,R1 ;Move on the workspace addr
160 B %20quartz__init ;Go round for the rest
161 30quartz__init LDMFD R13!,{R0-R9,PC}^ ;I declare this module open
162
163 ; --- Tidy up -- it all failed ---
164
165 95quartz__init MOV R12,R5 ;Point at private word
166 BL quartz__closeDown ;Close down other sections
167
168 99quartz__init ADD R13,R13,#4 ;Don't restore R0 on exit
169 LDMFD R13!,{R1-R9,R14} ;Unstack all the registers
170 ORRS PC,R14,#V_flag ;Return the error to system
171
172 quartz__wSpace DCD 0
173
174 LTORG
175
176 ; --- quartz__closeDown ---
177 ;
178 ; On entry: R12 == pointer to private word
179 ;
180 ; On exit: --
181 ;
182 ; Use: Closes down a module.
183
184 quartz__closeDown ROUT
185
186 STMFD R13!,{R0-R9,R14} ;Save some registers
187 MOV R5,R12 ;Keep private word pointer
188 LDR R12,[R12,#0] ;Load workspace base address
189
190 ADR R9,quartz__base ;Find the module base address
191 LDR R7,=|Quartz$$Table$$Base|
192 LDR R8,=|Quartz$$Table$$Limit|
193 ADD R7,R9,R7 ;Convert to actual addresses
194 ADD R8,R9,R8
195
196 MOV R6,R7 ;Get the start pointer again
197 LDR R12,quartz__wSpace ;Find the workspace base
198
199 10 CMP R6,R8 ;Have we finished yet?
200 BGE %40quartz__closeDown ;Yes -- deallocate memory
201 LDMIA R6!,{R1-R4} ;Load the initialisation info
202 CMP R4,#0 ;Does he want closing down?
203 BEQ %30quartz__closeDown ;No -- ignore it then
204 CMP R1,#0 ;Did he want workspace?
205 BEQ %20quartz__closeDown ;No -- close him down anyway
206 LDR R14,[R12,#0] ;Yes -- load first word
207 CMP R14,#0 ;Has he started up yet?
208 20 MOVNE R14,PC ;Yes -- set up return address
209 ADDNE PC,R9,R4 ;And call the routine nicely
210 30 ADD R12,R12,R1 ;Move on the workspace addr
211 B %10quartz__closeDown ;Go round and do some more
212
213 40 MOV R0,#7 ;Deallocate workspace
214 LDR R2,[R5,#0] ;Load workspace base address
215 SWI XOS_Module ;Free all my workspace
216 MOV R14,#0 ;Don't have workspace no more
217 STR R14,[R5,#0] ;So zero my private word
218
219 LDMFD R13!,{R0-R9,PC}^ ;Return to caller
220
221 LTORG
222
223 ; --- quartz__service ---
224 ;
225 ; On entry: R1 == service call number
226 ;
227 ; On exit: As returned by service call handlers
228 ;
229 ; Use: Handles service calls
230
231 quartz__service ROUT
232
233 STMFD R13!,{R9-R11,R14} ;Save far too few registers
234 ADR R9,quartz__base ;Find module base
235 LDR R10,=|Quartz$$Service$$Base|
236 LDR R11,=|Quartz$$Service$$Limit|
237 ADD R10,R9,R10 ;Convert to actual addresses
238 ADD R11,R9,R11
239
240 10 CMP R10,R11 ;Have we finished yet?
241 LDMEQFD R13!,{R9-R11,PC}^ ;Yes -- return (whew)
242 LDMIA R10!,{R12,R14} ;Get the service handler
243 CMP R1,R14 ;Does he want this service?
244 MOVEQ R14,PC ;Yes -- set up return addr
245 ADDEQ PC,R9,R12 ;And call his handler
246 B %10quartz__service ;And go round again
247
248 LTORG
249
250 AREA |Quartz$$Commands_|,CODE,READONLY
251
252 DCD 0 ;Terminate command table
253
254 ;----- Workspace ------------------------------------------------------------
255
256 ^ 0,R12
257 quartz__wStart # 0
258 quartz__wSize EQU {VAR}-quartz__wStart
259
260 ;----- That's all, folks ----------------------------------------------------
261
262 END