4 ; Quartz module support library kernel (MDW)
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Quartz library.
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)
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.
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.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
34 ; --- User supplied symbols ---
36 IMPORT quartz_name ;The module's name string
37 IMPORT quartz_help ;The help and version string
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
44 IMPORT quartz_appCode,WEAK ;Any application code
46 IMPORT |Quartz$$Commands$$Base|,WEAK
48 ; --- Other important objects ---
50 IMPORT |Quartz$$Table$$Base|,WEAK
51 IMPORT |Quartz$$Table$$Limit|,WEAK
53 IMPORT |Quartz$$Service$$Base|,WEAK
54 IMPORT |Quartz$$Service$$Limit|,WEAK
56 ;----- The actual module header ---------------------------------------------
58 AREA |!!!Module$$Header|,CODE,READONLY
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
72 ;----- Initialisation and finalisation code ---------------------------------
78 ; On exit: R0 == pointer to module base
80 ; Use: Returns a pointer to the module's base
85 ADR R0,quartz__base ;Point to the module base
86 MOVS PC,R14 ;And return to caller
90 ; --- quartz__init ---
92 ; On entry: R12 == pointer too where to store private word
96 ; Use: Initialises Quartz library and any client modules which feel
97 ; they want to use this mechanism.
101 STMFD R13!,{R0-R9,R14} ;Save some registers
103 MOV R5,R12 ;Keep private word address
105 ; --- Find the amount of workspace we need ---
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
113 MOV R0,R7 ;Point at the table start
114 MOV R3,#quartz__wSize ;Get my workspace size
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
122 ; --- Allocate the workspace nicely ---
124 05quartz__init CMP R3,#0 ;Do we want any workspace?
125 BEQ %09quartz__init ;No -- don't allocate any
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
134 ; --- Now initialise the first words ---
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
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
149 ; --- Finally initialise all the other sections ---
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
163 ; --- Tidy up -- it all failed ---
165 95quartz__init MOV R12,R5 ;Point at private word
166 BL quartz__closeDown ;Close down other sections
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
176 ; --- quartz__closeDown ---
178 ; On entry: R12 == pointer to private word
182 ; Use: Closes down a module.
184 quartz__closeDown ROUT
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
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
196 MOV R6,R7 ;Get the start pointer again
197 LDR R12,quartz__wSpace ;Find the workspace base
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
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
219 LDMFD R13!,{R0-R9,PC}^ ;Return to caller
223 ; --- quartz__service ---
225 ; On entry: R1 == service call number
227 ; On exit: As returned by service call handlers
229 ; Use: Handles service calls
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
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
250 AREA |Quartz$$Commands_|,CODE,READONLY
252 DCD 0 ;Terminate command table
254 ;----- Workspace ------------------------------------------------------------
258 quartz__wSize EQU {VAR}-quartz__wStart
260 ;----- That's all, folks ----------------------------------------------------