chiark / gitweb /
Initial revision
[ssr] / StraySrc / Dynamite / dynamite / s / dynAnchor
1 ;
2 ; dynAnchor.s
3 ;
4 ; Useful handle RMA allocation for dynamite
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 ;----- External dependencies ------------------------------------------------
33
34                 GET     sh.wSpace
35
36 ;----- Constants ------------------------------------------------------------
37
38 danc__chunk     EQU     16                      ;Number of handles to get
39
40 ;----- Main code ------------------------------------------------------------
41
42                 AREA    |Dynamite$$Code|,CODE,READONLY
43
44 ; --- danc_alloc ---
45 ;
46 ; On entry:     --
47 ;
48 ; On exit:      R0 == pointer to block allocated, or V set and pointer to
49 ;                     error
50 ;
51 ; Use:          Allocates an anchor to use with dynamite from the RMA,
52 ;               in a very quick way indeed.
53
54                 EXPORT  danc_alloc
55 danc_alloc      ROUT
56
57                 STMFD   R13!,{R1-R3,R14}
58
59                 ; --- Are there any free blocks? ---
60
61                 LDR     R2,dyn_ancTable         ;Get the free list offset
62                 CMP     R2,#0                   ;Are there any free blocks?
63                 BEQ     %01danc_alloc           ;No -- better allocate some
64
65                 ; --- Mess about with the free list and return ---
66
67 00danc_alloc    LDR     R3,[R2]                 ;Get next pointer from block
68                 STR     R3,dyn_ancTable         ;This is now first free block
69                 MOV     R0,R2                   ;Point to the block
70                 LDMFD   R13!,{R1-R3,PC}^        ;Restore registers and return
71
72                 ; --- Create a big block ---
73
74 01danc_alloc    MOV     R0,#6                   ;Allocate memory please
75                 MOV     R3,#danc__chunk*4+4     ;Get the chunk size
76                 SWI     XOS_Module              ;Allocate the big block then
77                 LDMVSFD R13!,{R1-R3,PC}         ;If it failed, return error
78
79                 LDR     R14,dyn_ancList         ;Load current list head
80                 STR     R2,dyn_ancList          ;Save this as new list head
81                 STR     R14,[R2],#4             ;And save old list head
82
83                 ; --- Now set up the links for the free list ---
84
85                 MOV     R0,#0                   ;Next free pointer start at 0
86                 SUB     R3,R3,#8                ;Offset to next field of sub
87 02danc_alloc    STR     R0,[R2,R3]              ;Store in next field
88                 ADD     R0,R2,R3                ;Point to that block
89                 SUBS    R3,R3,#4                ;Point to previous block
90                 BGE     %02danc_alloc           ;If more to do, continue...
91
92                 ; --- The links are set up -- now take off a block ---
93
94                 B       %00danc_alloc           ;Then allocate as normal
95
96                 LTORG
97
98 ; --- danc_free ---
99 ;
100 ; On entry:     R0 == pointer to block
101 ;
102 ; On exit:      Registers preserved
103 ;
104 ; Use:          Frees an anchor allocated using danc_alloc.
105
106                 EXPORT  danc_free
107 danc_free       ROUT
108
109                 STMFD   R13!,{R0,R1,R14}        ;Preserve registers
110
111                 ; --- Mess about with the list ---
112
113                 LDR     R1,dyn_ancTable         ;Get current first block
114                 STR     R1,[R0]                 ;Store in newly freed block
115                 STR     R0,dyn_ancTable         ;And insert new block in list
116                 LDMFD   R13!,{R0,R1,PC}^        ;Oh, and return to caller
117
118                 LTORG
119
120 ; --- danc_quit ---
121 ;
122 ; On entry:     --
123 ;
124 ; On exit:      --
125 ;
126 ; Use:          Frees everyone's anchors nicely when the module quits.
127
128                 EXPORT  danc_quit
129 danc_quit       ROUT
130
131                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
132                 LDR     R2,dyn_ancList          ;Load the list head
133                 CMP     R2,#0                   ;Is there anything to do?
134                 LDMEQFD R13!,{R0-R2,PC}^        ;No -- return then
135                 MOV     R0,#7                   ;Free RMA block
136 00danc_quit     LDR     R1,[R2,#0]              ;Load the next pointer
137                 SWI     XOS_Module              ;Free the block
138                 MOVS    R2,R1                   ;Point to next one
139                 BNE     %00danc_quit            ;And loop round for more
140                 LDMFD   R13!,{R0-R2,PC}^        ;Return when all done
141
142                 LTORG
143
144 ;----- That's all, folks ----------------------------------------------------
145
146                 END