1145
|
1 **************************************************
|
|
2 * System Call: F$AllBit
|
|
3 *
|
|
4 * Function: Sets bits in an allocation bitmap
|
|
5 *
|
|
6 * Input: X = Address of allocation bitmap
|
|
7 * D = Number of first bit to set
|
|
8 * Y = Bit count (number of bits to set)
|
|
9 *
|
|
10 * Output: None
|
|
11 *
|
|
12 * Error: CC = C bit set; B = error code
|
|
13 *
|
|
14 FAllBit ldd R$D,u get bit # to start with
|
|
15 ldx R$X,u get address of allocation bit map
|
|
16 bsr CalcBit calculate byte & position & get first bit mask
|
1387
|
17 IFGT Level-1
|
1145
|
18 ldy <D.Proc get current task #
|
|
19 ldb P$Task,y get task number
|
1387
|
20 bra DoAllBit go do it
|
1145
|
21
|
|
22 * F$AllBit (System State)
|
|
23 FSAllBit ldd R$D,u get bit # to start with
|
|
24 ldx R$X,u get address of allocation bit map
|
|
25 bsr CalcBit calculate byte & pos & get first bit mask
|
|
26 ldb <D.SysTsk Get system task #
|
1387
|
27 ENDC
|
1145
|
28
|
|
29 * Main bit setting loop
|
1387
|
30 DoAllBit equ *
|
1145
|
31 IFNE H6309
|
|
32 ldw R$Y,u get # bits to set
|
|
33 ELSE
|
|
34 ldy R$Y,u get # bits to set
|
|
35 ENDC
|
|
36 beq BitEx nothing to set, return
|
|
37 sta ,-s preserve current mask
|
|
38 bmi SkpBit If high bit set, skip ahead
|
1387
|
39 IFGT Level-1
|
|
40 os9 F$LDABX go get original value from bit map
|
|
41 ELSE
|
|
42 lda ,x
|
|
43 ENDC
|
1145
|
44 NxtBitLp ora ,s OR it with the current mask
|
|
45 IFNE H6309
|
1387
|
46 decw dec the bit counter
|
1145
|
47 ELSE
|
|
48 leay -1,y
|
|
49 ENDC
|
1387
|
50 beq BitStEx done, go put the byte back into the task's map
|
|
51 lsr ,s shift out the lowest bit of original
|
|
52 bcc NxtBitLp if it is a 0, do next bit
|
|
53 IFGT Level-1
|
|
54 os9 F$STABX if it was a 1 (which means whole byte done),
|
|
55 ELSE
|
|
56 sta ,x
|
|
57 ENDC
|
|
58 leax 1,x store finished byte and bump ptr
|
|
59 SkpBit lda #$FF preload a finished byte
|
|
60 bra SkpBit2 skip ahead
|
1145
|
61
|
1387
|
62 StFulByt equ *
|
|
63 IFGT Level-1
|
|
64 os9 F$STABX store full byte
|
|
65 ELSE
|
|
66 sta ,x
|
|
67 ENDC
|
|
68 leax 1,x bump ptr up 1
|
1145
|
69 IFNE H6309
|
1387
|
70 subw #8 bump counter down by 8
|
|
71 SkpBit2 cmpw #8 is there at least 8 more (a full byte) to do?
|
1145
|
72 ELSE
|
|
73 leay -8,y
|
|
74 SkpBit2 cmpy #$0008
|
|
75 ENDC
|
1387
|
76 bhi StFulByt more than 1, go do current
|
|
77 beq BitStEx exactly 1 byte left, do final store & exit
|
1145
|
78
|
|
79 * Last byte: Not a full byte left loop
|
1387
|
80 L085A lsra bump out least sig. bit
|
1145
|
81 IFNE H6309
|
1387
|
82 decw dec the bit counter
|
1145
|
83 ELSE
|
|
84 leay -1,y
|
|
85 ENDC
|
1387
|
86 bne L085A keep going until last one is shifted out
|
|
87 coma invert byte to get proper result
|
|
88 sta ,s preserve a sec
|
|
89 IFGT Level-1
|
|
90 os9 F$LDABX get byte for original map
|
|
91 ELSE
|
|
92 lda ,x
|
|
93 ENDC
|
|
94 ora ,s merge with new mask
|
|
95 BitStEx equ *
|
|
96 IFGT Level-1
|
|
97 os9 F$STABX store finished byte into task
|
|
98 ELSE
|
|
99 sta ,x
|
|
100 ENDC
|
|
101 leas 1,s eat the working copy of the mask
|
|
102 BitEx clrb no error & return
|
1145
|
103 rts
|
|
104
|
|
105 * Calculate address of first byte we want, and which bit in that byte, from
|
|
106 * a bit allocation map given the address of the map & the bit # we want to
|
|
107 * point to
|
|
108 * Entry: D=Bit #
|
|
109 * X=Ptr to bit mask table
|
|
110 * Exit: A=Mask to point to bit # within byte we are starting on
|
|
111 * X=Ptr in allocation map to first byte we are starting on
|
|
112 CalcBit pshs b,y preserve registers
|
|
113 IFNE H6309
|
|
114 lsrd divide bit # by 8 to calculate byte # to start
|
|
115 lsrd allocating at
|
|
116 lsrd
|
1387
|
117 addr d,x offset that far into the map
|
1145
|
118 ELSE
|
|
119 lsra
|
|
120 rorb
|
|
121 lsra
|
|
122 rorb
|
|
123 lsra
|
|
124 rorb
|
|
125 leax d,x
|
|
126 ENDC
|
|
127 puls b restore bit position LSB
|
1387
|
128 leay <MaskTbl,pc point to mask table
|
1145
|
129 andb #7 round it down to nearest bit
|
|
130 lda b,y get bit mask
|
|
131 puls y,pc restore & return
|
|
132
|
|
133 * Bit position table (NOTE that bit #'s are done by left to right)
|
1387
|
134 MaskTbl fcb $80,$40,$20,$10,$08,$04,$02,$01
|
1145
|
135
|
|
136
|
|
137 **************************************************
|
|
138 * System Call: F$DelBit
|
|
139 *
|
|
140 * Function: Clears bits in an allocation bitmap
|
|
141 *
|
|
142 * Input: X = Address of allocation bitmap
|
|
143 * D = Number of first bit to clear
|
|
144 * Y = Bit count (number of bits to clear)
|
|
145 *
|
|
146 * Output: None
|
|
147 *
|
|
148 * Error: CC = C bit set; B = error code
|
|
149 *
|
1387
|
150 FDelBit ldd R$D,u get bit # to start with
|
|
151 ldx R$X,u get addr. of bit allocation map
|
|
152 bsr CalcBit point to starting bit
|
|
153 IFGT Level-1
|
|
154 ldy <D.Proc get current Task #
|
1145
|
155 ldb P$Task,y get task #
|
1387
|
156 bra DoDelBit do rest of 0 bits
|
1145
|
157
|
|
158 * F$DelBit entry point for system state
|
1387
|
159 FSDelBit ldd R$D,u get bit # to start with
|
|
160 ldx R$X,u get addr. of bit allocation map
|
|
161 bsr CalcBit point to starting bit
|
|
162 ldb <D.SysTsk get system task #
|
|
163 ENDC
|
1145
|
164
|
1387
|
165 DoDelBit equ *
|
1145
|
166 IFNE H6309
|
1387
|
167 ldw R$Y,u get # bits to clear
|
1145
|
168 ELSE
|
1387
|
169 ldy R$Y,u get # bits to clear
|
1145
|
170 ENDC
|
1387
|
171 beq L08E0 none, return
|
|
172 coma invert current bit mask
|
|
173 sta ,-s preserve on stack
|
|
174 bpl L08BC if high bit clear, skip ahead
|
|
175 IFGT Level-1
|
|
176 os9 F$LDABX go get byte from user's map
|
|
177 ELSE
|
|
178 lda ,x
|
|
179 ENDC
|
1145
|
180 L08AD anda ,s AND it with current mask
|
|
181 IFNE H6309
|
1387
|
182 decw dec the bits left counter
|
1145
|
183 ELSE
|
|
184 leay -1,y
|
|
185 ENDC
|
1387
|
186 beq BitDone done, store finished byte back in task's map
|
|
187 asr ,s shift out lowest bit, leaving highest alone
|
|
188 bcs L08AD if it is a 1, do next bit
|
|
189 IFGT Level-1
|
|
190 os9 F$STABX if it was a 0 (which means whole byte done),
|
|
191 ELSE
|
|
192 sta ,x
|
|
193 ENDC
|
1145
|
194 leax 1,x store finished byte & inc. ptr
|
1387
|
195 L08BC clra preload a cleared byte
|
1145
|
196 bra ChkFull skip ahead
|
1387
|
197 L08BF equ *
|
|
198 IFGT Level-1
|
|
199 os9 F$STABX store full byte
|
|
200 ELSE
|
|
201 sta ,x
|
|
202 ENDC
|
|
203 leax 1,x bump ptr up by 1
|
1145
|
204 IFNE H6309
|
1387
|
205 subw #8 dec bits left counter by 8
|
|
206 ChkFull cmpw #8 at least 1 full byte left?
|
1145
|
207 ELSE
|
|
208 leay -8,y
|
|
209 ChkFull cmpy #8
|
|
210 ENDC
|
1387
|
211 bhi L08BF yes, do a whole byte in 1 shot
|
|
212 beq BitDone exactly 1, store byte & exit
|
1145
|
213 coma < full byte left, invert bits
|
1387
|
214 L08CF lsra shift out rightmost bit
|
1145
|
215 IFNE H6309
|
1387
|
216 decw dec bits left counter
|
1145
|
217 ELSE
|
|
218 leay -1,y
|
|
219 ENDC
|
1387
|
220 bne L08CF keep doing till done
|
|
221 sta ,s save finished mask
|
|
222 IFGT Level-1
|
|
223 os9 F$LDABX get original byte from task
|
|
224 ELSE
|
|
225 lda ,x
|
|
226 ENDC
|
|
227 anda ,s merge cleared bits with it
|
|
228 BitDone equ *
|
|
229 IFGT Level-1
|
|
230 os9 F$STABX store finished byte into task
|
|
231 ELSE
|
|
232 sta ,x
|
|
233 ENDC
|
|
234 leas 1,s eat working copy of mask
|
|
235 L08E0 clrb eat error & return
|
1145
|
236 rts
|
|
237
|
|
238
|
|
239 **************************************************
|
|
240 * System Call: F$SchBit
|
|
241 *
|
|
242 * Function: Search bitmap for a free area
|
|
243 *
|
|
244 * Input: X = Address of allocation bitmap
|
|
245 * D = Starting bit number
|
|
246 * Y = Bit count (free bit block size)
|
|
247 * U = Address of end of allocation bitmap
|
|
248 *
|
|
249 * Output: D = Beginning bit number
|
|
250 * Y = Bit count
|
|
251 *
|
|
252 * Error: CC = C bit set; B = error code
|
|
253 *
|
1387
|
254 FSchBit ldd R$D,u get start bit #
|
|
255 ldx R$X,u get addr. of allocation bit map
|
|
256 bsr CalcBit point to starting bit
|
|
257 IFGT Level-1
|
|
258 ldy <D.Proc get task #
|
1145
|
259 ldb P$Task,y
|
1387
|
260 bra DoSchBit skip ahead
|
1145
|
261
|
|
262 * F$SchBit entry point for system
|
1387
|
263 FSSchBit ldd R$D,u get start bit #
|
|
264 ldx R$X,u get addr. of allocation bit map
|
|
265 lbsr CalcBit point to starting bit
|
|
266 ldb <D.SysTsk get task #
|
1145
|
267 * Stack: 0,s : byte we are working on (from original map)
|
|
268 * 1,s : Mask of which bit in current byte to start on
|
|
269 * 2,s : Task number the allocation bit map is in
|
|
270 * 3,s : Largest block found so far
|
|
271 * 5,s : Starting bit # of requested (or closest) size found
|
|
272 * 7,s : Starting bit # of current block being checked (2 bytes) (NOW IN Y)
|
1387
|
273 ENDC
|
|
274 DoSchBit equ *
|
1145
|
275 IFNE H6309
|
1387
|
276 pshs cc,d,x,y preserve task # & bit mask & reserve stack space
|
|
277 clrd faster than 2 memory clears
|
1145
|
278 ELSE
|
1387
|
279 pshs cc,d,x,y,u preserve task # & bit mask & reserve stack space
|
1145
|
280 clra
|
|
281 clrb
|
|
282 ENDC
|
1387
|
283 std 3,s preserve it
|
1145
|
284 IFNE H6309
|
1387
|
285 ldw R$D,u get start bit #
|
|
286 tfr w, y save as current block starting bit #
|
1145
|
287 ELSE
|
|
288 ldy R$D,u
|
|
289 sty 7,s
|
|
290 ENDC
|
1387
|
291 bra Skipper skip ahead
|
1145
|
292
|
|
293 * New start point for search at current location
|
|
294 RstSrch equ *
|
|
295 IFNE H6309
|
1387
|
296 tfr w,y preserve current block bit # start
|
1145
|
297 ELSE
|
|
298 sty 7,s
|
|
299 ENDC
|
|
300 * Move to next bit position, and to next byte if current byte is done
|
1387
|
301 MoveBit lsr 1,s move to next bit position
|
|
302 bcc CheckBit if not the last one, check it
|
|
303 ror 1,s move bit position marker to 1st bit again
|
|
304 leax 1,x move byte ptr (in map) to next byte
|
1145
|
305
|
|
306 * Check if we are finished allocation map
|
1387
|
307 Skipper cmpx R$U,u done entire map?
|
|
308 bhs BadNews yes, couldn't fit in 1 block, notify caller
|
|
309 ldb 2,s get task number
|
|
310 IFGT Level-1
|
|
311 os9 F$LDABX get byte from bit allocation map
|
|
312 ELSE
|
|
313 lda ,x
|
|
314 ENDC
|
|
315 sta ,s preserve in scratch area
|
1145
|
316
|
|
317 * Main checking
|
|
318 CheckBit equ *
|
|
319 IFNE H6309
|
1387
|
320 incw increment current bit #
|
1145
|
321 ELSE
|
|
322 leay 1,y
|
|
323 ENDC
|
1387
|
324 lda ,s get current byte
|
|
325 anda 1,s mask out all but current bit position
|
|
326 bne RstSrch if bit not free, restart search from next bit
|
1145
|
327 IFNE H6309
|
1387
|
328 tfr w,d dup current bit # into D
|
|
329 subr y,d calculate size we have free so far
|
1145
|
330 ELSE
|
|
331 tfr y,d
|
|
332 subd 7,s
|
|
333 ENDC
|
1387
|
334 cmpd R$Y,u as big as user requested?
|
|
335 bhs WereDone yes, we are done
|
|
336 cmpd $03,s as big as the largest one we have found so far?
|
|
337 bls MoveBit no, move to next bit and keep going
|
|
338 std $03,s it is the largest, save current size
|
1145
|
339 IFNE H6309
|
1387
|
340 sty $05,s save as start bit # of largest block found so far
|
1145
|
341 ELSE
|
|
342 ldd 7,s
|
|
343 std 5,s
|
|
344 ENDC
|
1387
|
345 bra MoveBit move to next bit and keep going
|
1145
|
346
|
|
347 * Couldn't find requested size block; tell user where the closest was found
|
|
348 * and how big it was
|
1387
|
349 BadNews ldd $03,s get size of largest block we found
|
|
350 std R$Y,u put into callers Y register
|
|
351 comb set carry to indicate we couldn't get full size
|
|
352 ldd 5,s get starting bit # of largest block we found
|
|
353 bra BadSkip skip ahead
|
1145
|
354 * Found one, tell user where it is
|
|
355 WereDone equ *
|
|
356 IFNE H6309
|
1387
|
357 tfr y,d get start bit # of the block we found
|
1145
|
358 ELSE
|
|
359 ldd 7,s
|
|
360 ENDC
|
1387
|
361 BadSkip std R$D,u put starting bit # of block into callers D register
|
1145
|
362 IFNE H6309
|
1387
|
363 leas $07,s eat our temporary stack area & return
|
1145
|
364 ELSE
|
|
365 leas $09,s
|
|
366 ENDC
|
|
367 rts
|