chiark / gitweb /
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