Initial revision
[ssr] / StraySrc / Libraries / Sapphire / sail / _s / strBucket
1 ;
2 ; strBucket.s
3 ;
4 ; String bucket handling
5 ;
6 ; © 1995 Straylight
7 ;
8
9 ;----- Standard header ------------------------------------------------------
10
11 GET libs:header
12 GET libs:swis
13
14 GET libs:stream
15
16 ;----- External dependencies ------------------------------------------------
17
18 GET sh.anchor
19 GET sh.mem
20
21 ;----- Main code ------------------------------------------------------------
22
23 AREA |TermScript$$Code|,CODE,READONLY
24
25 ; --- strBucket_init ---
26 ;
27 ; On entry: --
28 ;
29 ; On exit: --
30 ;
31 ; Use: Initialises the string bucket.
32
33 EXPORT strBucket_init
34 strBucket_init ROUT
35
36 STMFD R13!,{R0-R2,R14} ;Save some registers
37
38 ; --- Allocate the string bucket block ---
39
40 MOV R0,#1024 ;Start off nice and big
41 BL mem_alloc ;Allocate the block
42 MOV R1,#256 ;Reserve space for the table
43 MOV R2,#1024 ;Remember starting size
44 ADR R14,tsc_bucket ;Find the workspace part
45 STMIA R14,{R0-R2} ;Save this information away
46
47 ; --- Now initialise the bucket table ---
48
49 LDR R0,[R0] ;Load actual block address
50 MOV R1,#64 ;We have 64 buckets to handle
51 MOV R14,#0 ;Clear them all to zero
52 00 STR R14,[R0],#4 ;Save the initial value
53 SUBS R1,R1,#1 ;Decrement the counter
54 BNE %00strBucket_init ;And loop
55
56 LDMFD R13!,{R0-R2,PC}^ ;Now return to caller
57
58 LTORG
59
60 ; --- strBucket_alloc ---
61 ;
62 ; On entry: R0 == size of string to allocate
63 ;
64 ; On exit: R0 == pointer to area to use (length at [R0,#-1])
65 ; R1 == offset to that (for storing)
66 ;
67 ; Use: Allocates space for a string of the given size.
68
69 EXPORT strBucket_alloc
70 strBucket_alloc ROUT
71
72 ; --- Quick optimisation ---
73
74 SUBS R1,R0,#0 ;Is this a null string?
75 MOVEQS PC,R14 ;Yes -- return zero then
76
77 STMFD R13!,{R2,R3,R14} ;Save some registers
78 MOV R2,R0 ;Look after length
79
80 ; --- Find the actual block length ---
81
82 ADD R3,R2,#4 ;Add 1 byte for len, and...
83 BIC R3,R3,#3 ;...word align
84
85 LDR R0,tsc_bucket ;Find the bucket anchor
86 LDR R14,[R0] ;WimpExt? Bollocks more like
87 LDR R1,[R14,R3] ;Load the free list head
88 CMP R1,#0 ;Is this empty?
89 LDRNE R0,[R14,R1] ;Load the link from this blk
90 STRNE R0,[R14,R3] ;And stuff it in list head
91 ADDNE R0,R14,R1 ;No -- work out address
92 BNE %20strBucket_alloc ;And skip ahead
93
94 ; --- Need to allocate more space ---
95
96 ADR R14,tsc_bktPtr ;Find the free pointer
97 LDMIA R14,{R1,R14} ;Load free ptr and size
98 ADD R1,R1,R3 ;Add on the space we need
99 STR R1,tsc_bktPtr ;Store modified pointer
100 SUB R3,R1,R3 ;Look after old offset
101 CMP R1,R14 ;Do we have enough?
102 BGT %50strBucket_alloc ;No -- get some more then
103 10 MOV R1,R3 ;Find start of string space
104 LDR R0,[R0] ;This is getting IRRITATING
105 ADD R0,R0,R1 ;Get string block address
106
107 ; --- Set up the string ready for caller ---
108
109 20 STRB R2,[R0],#1 ;Save the length byte
110 ADD R1,R1,#1 ;Bump the offset on
111 LDMFD R13!,{R2,R3,PC}^ ;And return to caller
112
113 ; --- Extend the bucket area ---
114
115 50 MOV R14,#&FF ;Build up 1023
116 ORR R14,R14,#&300
117 ADD R1,R1,R14 ;Add on chunking size
118 BIC R1,R1,R14 ;And align nicely
119 BL mem_realloc ;Reallocate the area
120 STR R1,tsc_bktSize ;And save the new size
121 B %10strBucket_alloc ;And leap back again
122
123 LTORG
124
125 ; --- strBucket_free ---
126 ;
127 ; On entry: R0 == offset of string to free
128 ;
129 ; On exit: --
130 ;
131 ; Use: Frees the memory the string took up.
132
133 EXPORT strBucket_free
134 strBucket_free ROUT
135
136 CMP R0,#0 ;Is this a bogus offset
137 MOVEQS PC,R14 ;Yes -- ignore it then
138
139 STMFD R13!,{R0-R2,R14} ;Save some registers
140 LDR R1,tsc_bucket ;Load the bucket anchor
141 LDR R1,[R1] ;Spotted the pattern yet?
142 SUB R0,R0,#1 ;Find the actual start offset
143 LDRB R2,[R1,R0] ;Load the length byte
144 ADD R2,R2,#4 ;Add length byte and align
145 BIC R2,R2,#3
146 LDR R14,[R1,R2] ;Load the list head
147 STR R14,[R1,R0] ;Save this in freed block
148 STR R0,[R1,R2] ;And make this the new head
149 LDMFD R13!,{R0-R2,PC}^ ;And return to caller
150
151 LTORG
152
153 ;----- That's all, folks ----------------------------------------------------
154
155 END