Initial revision
[ssr] / StraySrc / Dynamite / dynamite / s / dynArea
1 ;
2 ; dynArea.s
3 ;
4 ; The handling of the dynamic area itself
5 ;
6 ; © 1994-1998 Straylight
7 ;
8 ;----- Licensing note -------------------------------------------------------
9 ;
10 ; This file is part of Straylight's Dynamite
11 ;
12 ; Dynamite is free software; you can redistribute it and/or modify
13 ; it under the terms of the GNU General Public License as published by
14 ; the Free Software Foundation; either version 2, or (at your option)
15 ; any later version.
16 ;
17 ; Dynamite is distributed in the hope that it will be useful,
18 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ; GNU General Public License for more details.
21 ;
22 ; You should have received a copy of the GNU General Public License
23 ; along with Dynamite. If not, write to the Free Software Foundation,
24 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 GET libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36 GET sh.wSpace
37
38 ;----- Main code ------------------------------------------------------------
39
40 AREA |Dynamite$$Code|,CODE,READONLY
41
42 ; --- da_findPage ---
43 ;
44 ; On entry: R2 == address of the page
45 ;
46 ; On exit: R0 == page number
47 ;
48 ; Use: Finds the page number of the page with the address given.
49
50 EXPORT da_findPage
51 da_findPage ROUT
52
53 STMFD R13!,{R1,R7-R9,R14} ;Stack the link
54 LDR R14,dyn_machine ;Load the machine type
55 CMP R14,#&A3 ;RISC OS 3?
56 BCS %10da_findPage ;Yes -- jump ahead then
57
58 LDR R9,dyn_pageCount ;Load number of pages-1
59 MOV R14,#&164 ;Find CAM map (RO 2 and 3!)
60 ADD R9,R14,R9,LSL #2 ;Last valid entry
61 MOV R8,R2,LSL #4 ;The address of interest << 4
62 SUB R7,R14,#4 ;We're pre-indexing
63 00da_findPage CMP R7,R9 ;Have we finished?
64 LDRNE R1,[R7,#4]! ;Load out the entry
65 TEQNE R8,R1,LSL #4 ;Is this a match?
66 BNE %00da_findPage ;No -- keep on looking
67 TEQ R8,R1,LSL #4 ;Was that a match?
68 SUBEQ R7,R7,R14 ;Yes -- get offset from base
69 MOVEQ R0,R7,LSR #2 ;And turn into page number
70 MOVNE R0,#-1 ;Otherwise return -1
71 LDMFD R13!,{R1,R7-R9,PC}^ ;Return to caller
72
73 ; --- We are on RISC OS 3 ---
74
75 10da_findPage MOV R1,#0 ;Start at this page
76 MOV R14,#-1 ;Get a terminator
77 STMDB R13!,{R1,R2,R3,R14} ;Store that in block
78 MOV R0,R13 ;Point to the block
79 SWI OS_FindMemMapEntries ;Find the page number
80 LDR R0,[R13],#16 ;Load the page number
81 LDMFD R13!,{R1,R7-R9,PC}^ ;Return to caller
82
83 LTORG
84
85 ; --- da_addPages ---
86 ;
87 ; On entry: R0 == number of pages to add
88 ; R12 == workspace address
89 ;
90 ; On exit: Possible error returned
91 ;
92 ; Use: Increases the size of the dynamic area by the number of
93 ; pages given in R0
94
95 EXPORT da_addPages
96 da_addPages ROUT
97
98 STMFD R13!,{R0-R9,R14} ;Save some registers
99
100 LDR R9,dyn_machine ;What machine are we on?
101 CMP R9,#&A5 ;Is it a RISC PC?
102 BGE %50da_addPages ;Yes -- do things differently
103
104 MOVS R9,R0 ;Remember this value
105 BEQ %10da_addPages ;Nothing to do -- return
106 LDR R14,dyn_sprSize ;Get address of spr area size
107 LDR R14,[R14] ;Get the size out
108 LDR R1,dyn_areaSize ;Find our area size
109 SUB R4,R14,R1 ;Find top of system sprites
110 ADD R2,R4,#&01400000 ;Top of sprite area
111
112 LDR R3,dyn_log2PageSize ;Find page size of machine
113 MOV R5,R9,LSL R3 ;Find size in bytes
114 LDR R3,dyn_pageSize ;Find real page size
115 MOV R1,R5 ;We want this in R1 too
116 MOV R0,#3 ;Change sprite area size
117 SWI XOS_ChangeDynamicArea ;Yes... do it now!
118 BVS %99da_addPages ;Error -- return
119
120 ; --- Make sure system sprite size remains the same ---
121
122 MOV R14,#&01400000 ;Get address of sprite area
123 STR R4,[R14,#0] ;Get system sprite size
124
125 ; --- Work out how big dynamite area is now ---
126
127 LDR R14,dyn_areaSize ;Get the previous size
128 RSB R8,R14,#&01800000 ;Put new blocks here
129 ADD R14,R14,R5 ;The new size
130 STR R14,dyn_areaSize ;Save this size back
131
132 ; --- Now we need to map up the area ---
133
134 SUB R13,R13,#16 ;Get me a mem map block
135 MOV R14,#0 ;A nice 0 thing
136 STR R14,[R13,#8] ;Protection level
137 MOV R14,#-1 ;The terminator
138 STR R14,[R13,#12] ;Put that in the block
139 00da_addPages SUB R8,R8,R3 ;Next page goes here
140 BL da_findPage ;Find page number of R2
141 STR R0,[R13,#0] ;Store the page number
142 STR R8,[R13,#4] ;Put that page here please
143 MOV R0,R13 ;Point to the block
144 SWI XOS_SetMemMapEntries ;Set mem map entries
145 SUBS R9,R9,#1 ;Reduce page count
146 ADD R2,R2,R3 ;Now move next page
147 BGT %00da_addPages ;Keep doing that then
148 ADD R13,R13,#16 ;Get the block back
149
150 ; --- Phew! -- almost there ---
151
152 CMP R4,#0 ;Is there a sprite area?
153 MOVNE R4,#&01400000 ;Yes -- get its address
154 MOV R14,#&1000 ;VDU driver workspace
155 STR R4,[R14,#1364] ;And store as sprite area ptr
156
157 10da_addPages LDMFD R13!,{R0-R9,PC}^ ;Return to caller
158
159 ; --- We are on a RISC PC ---
160
161 50da_addPages LDR R1,dyn_log2PageSize ;Get the log 2 page size
162 MOV R1,R0,LSL R1 ;Work out increment
163 LDR R0,dyn_areaHandle ;Load the area handle
164 SWI XOS_ChangeDynamicArea ;And increase appropriately
165 LDRVC R14,dyn_areaSize ;Load the old area size
166 ADDVC R14,R14,R1 ;Apply our increment to it
167 STRVC R14,dyn_areaSize ;And save it back again
168 LDMVCFD R13!,{R0-R9,PC}^ ;Return to caller
169
170 99da_addPages LDMFD R13!,{R0-R9,R14} ;Load back registers
171 ADR R0,da__noMem ;Point to error
172 ORRS PC,R14,#V_flag ;Return with error
173
174 da__noMem DCD 1
175 DCB "No pages left",0
176
177 ; --- da_removePages ---
178 ;
179 ; On entry: R0 == number of pages to remove
180 ;
181 ; On exit: --
182 ;
183 ; Use: Removes the given number of pages from the dynamite
184 ; area. If the number of pages to remove is greater than
185 ; the actual number of pages allocated, as many as possible
186 ; are removed
187
188 EXPORT da_removePages
189 da_removePages ROUT
190
191 STMFD R13!,{R0-R10,R14} ;Stack some registers
192
193 LDR R9,dyn_machine ;What machine are we on?
194 CMP R9,#&A5 ;Is it a RISC PC?
195 BGE %50da_removePages ;Yes -- do things differently
196
197 MOV R9,R0 ;Remember this value
198 LDR R8,dyn_areaSize ;Get my area size
199 RSB R2,R8,#&01800000 ;The lowest page
200
201 LDR R5,dyn_log2PageSize ;Get the page size
202 MOV R7,R8,LSR R5 ;Number of dynamite pages
203 CMP R9,R7 ;Are we in range?
204 MOVGT R9,R7 ;No -- we are now
205 CMP R9,#0 ;Are we removing 0 pages?
206 BEQ %99da_removePages ;Yes -- return now
207
208 LDR R14,dyn_sprSize ;Get address of spr area size
209 LDR R14,[R14] ;Get the size out
210 LDR R1,dyn_areaSize ;Find our area size
211 SUB R10,R14,R1 ;Find top of system sprites
212 ADD R6,R10,#&01400000 ;Top of sprite area
213
214 SUB R14,R8,R9,LSL R5 ;The new dynamite size
215 STR R14,dyn_areaSize ;Store this away nicely
216
217 ; --- Now we need to map down the area ---
218
219 LDR R3,dyn_pageSize ;Get the page size
220 MOV R4,R9 ;Look after the page count
221 SUB R13,R13,#16 ;Get me a mem map block
222 MOV R14,#0 ;A nice 0 thing
223 STR R14,[R13,#8] ;Protection level
224 MOV R14,#-1 ;The terminator
225 STR R14,[R13,#12] ;Put that in the block
226 00 BL da_findPage ;Find page number of R2
227 STR R0,[R13,#0] ;Store the page number
228 STR R6,[R13,#4] ;Put that page here please
229 MOV R0,R13 ;Point to the block
230 SWI XOS_SetMemMapEntries ;Set mem map entries
231 ADD R2,R2,R3 ;Now move next page
232 ADD R6,R6,R3 ;Put the next one here
233 SUBS R9,R9,#1 ;Reduce page count
234 BGT %00da_removePages ;Keep doing that then
235 ADD R13,R13,#16 ;Get the block back
236
237 CMP R10,#0 ;Was there an area before
238 BNE %10da_removePages ;Yes -- all ok then
239 LDR R6,dyn_sprSize ;Get address of spr area size
240 LDR R6,[R6] ;Get the size out
241 MOV R7,#0 ;Sprite area header
242 MOV R8,#16
243 MOV R9,#16
244 MOV R2,#&1400000 ;Point to sprite area
245 STMIA R2,{R6-R9} ;Store the header
246
247 10 MOV R1,R4,LSL R5 ;We reduce by this amount
248 RSB R1,R1,#0 ;Make it negative
249 MOV R0,#3 ;Change sprite area size
250 SWI XOS_ChangeDynamicArea ;Remove those damn pages
251 B %99da_removePages ;Return to caller
252
253 ; --- We're on a RISC PC ---
254
255 50 LDR R1,dyn_log2PageSize ;Get the log 2 page size
256 MOV R1,R0,LSL R1 ;Work out increment
257 RSB R1,R1,#0 ;Negate it nicely
258 LDR R0,dyn_areaHandle ;Load the area handle
259 SWI XOS_ChangeDynamicArea ;And increase appropriately
260 LDR R14,dyn_areaSize ;Load the current size
261 SUB R14,R14,R1 ;How much was it altered by?
262 STR R14,dyn_areaSize ;And save that back
263
264 99 LDMFD R13!,{R0-R10,PC}^ ;Return to caller
265
266 LTORG
267
268
269 ; --- da_readSize ---
270 ;
271 ; On entry: --
272 ;
273 ; On exit: R0 == size of area
274 ;
275 ; Use: Returns the size of the sprite area (including the
276 ; dynamite area).
277
278 EXPORT da_readSize
279 da_readSize ROUT
280
281 LDR R0,dyn_machine ;What machine are we on?
282 CMP R0,#&A5 ;Is it a RISC PC?
283 BGE %50da_readSize ;Yes -- do other things
284
285 LDR R0,dyn_sprSize ;Get spr area size pointer
286 LDR R0,[R0,#0] ;Load out the size
287 MOVS PC,R14 ;And return to caller
288
289 ; --- We're on a RISC PC ---
290
291 50da_readSize STMFD R13!,{R1,R14} ;Stack some registers
292 MOV R0,#3 ;Read size of sprite area
293 SWI XOS_ReadDynamicArea ;Read things out then
294 MOV R0,R1 ;Put size in R0
295 LDMFD R13!,{R1,PC}^ ;Return to caller
296
297 LTORG
298
299 ; --- da_describe ---
300 ;
301 ; On entry: --
302 ;
303 ; On exit: R0 == dynamic area number (3 == sprite area)
304 ; R1 == size of area
305 ; R2 == total free in area
306 ;
307 ; Use: Gives back som information on the dynamite area.
308
309 EXPORT da_describe
310 da_describe ROUT
311
312 LDR R0,dyn_machine ;Load out the machine type
313 CMP R0,#&A5 ;Is it a RISC PC?
314 LDRGE R0,dyn_areaHandle ;Yes -- load dynamic area hnd
315 MOVLT R0,#-1 ;No -- return a silly value
316 LDR R1,dyn_areaSize ;Put area size in R1
317 LDR R2,dyn_heapSize ;And heap size in R2
318 SUB R2,R1,R2 ;Get size of unused area
319 MOVS PC,R14 ;Return to caller
320
321 LTORG
322
323 ;----- That's all, folks ----------------------------------------------------
324
325 END