-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdetree.s
259 lines (227 loc) · 10.9 KB
/
detree.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
; @*************************************************
; @ "DeTree" deallocates blocks from tree files.
; @
; @ It is assumed that the device preselected and the 'genBuf' may be used.
; @
; @ On entry the following values must be set:
; @ storType = storage type in upper nibble, lower nibble is undisturbed.
; @ firstBlkL & firstBlkH = first block of file (index or data)
; @ deBlock = 0 (see below)
; @ dTree = ptr to 1st block with stuff to be deallocated at tree level.
; @ dSap = ptr to 1st block at sapling level
; @ dSeed = byte (0-511) position to be zeroed from (inclusive).
; @ NB. There is 2 special cases when dSeed = 512
; @ Case 1) when EOF is set at a block boundary
; @ Case 2) when file is destroyed
; @
; @ On exit:
; @ storType = modified result of storage type (if applicable)
; @ firstBlkL & H = modified if storage type changed.
; @ deBlock = total number of blocks freed at all levels.
; @ dTree, dSap, dSeed unchanged.
; @
; @ To trim a tree to a seed file, both dTree and dSap must be zero.
; @ To go from tree to sapling, dTree alone must be zero.
DeTree LDA storType ;Which flavor of tree?
CMP #sapling*16 ;Is it a 'seed' (<=$1F)
BCC SeedDeAlloc ;Yes
CMP #tree*16 ;Maybe a 'sapling'?
BCC SapDeAlloc
CMP #(tree+1)*16 ;Well, at least be certain it's a 'tree'
BCC TreeDeAlloc ;Branch if it is
LDA #badBlockErr ;Block allocation error
JSR SysDeath ;Should never have been called
SeedDeAlloc LDA dSap
ORA dTree
BNE BummErr
JMP SeedDeAlloc0 ;Trim to a seed
SapDeAlloc LDA dTree
BNE BummErr
JMP SapDeAlloc0 ;Trim to a sapling
TreeDeAlloc LDA #128
STA topDest ;For tree top, start at end, work backwards
@loop1 JSR RdKeyBlk ;Read specified first block into genBuf
BCS BummErr ;Return all errors
LDY topDest ;Get current pointer to top indexes
CPY dTree ;Have enough sapling indexes been deallocated?
BEQ TreeDel17 ;Yes, now deallocate top guys!
LDX #$07 ;Buffer up to 8 sapling index block addrs
@loop2 LDA genBuf,Y ;Fetch low block address
STA deAlocBufL,X ; and save it
ORA genBuf+$100,Y ;Is it a real block that is allocated?
BEQ @1 ;It's a phantom block
LDA genBuf+$100,Y ;Fetch hi block addr
STA deAlocBufH,X ; and save it
DEX ;Decrement and test for dealoc buf filled
BMI @2 ;Branch if we've fetched 8 addresses
@1 DEY ;Look now for end of deallocation limit
CPY dTree ;Is this the last position on tree level?
BNE @loop2 ;No
INY
LDA #$00 ;Fill rest of deAloc buffer with NULL addresses
@loop3 STA deAlocBufL,X
STA deAlocBufH,X
DEX
BPL @loop3 ;Loop until filled
@2 DEY ;Decrement to prepare for next time
STY topDest ;save index
LDX #$07
@loop4 STX dTempX ;Save index to deAloc buf
LDA deAlocBufL,X
STA blockNum
ORA deAlocBufH,X ;Are we finished?
BEQ @loop1 ;Branch if done with this level
LDA deAlocBufH,X ;Complete address with hi byte
STA blockNum+1
JSR RdGBuf ;Read sapling level into genBuf
BCS BummErr ;Return any errors
JSR DeAllocBlk ;Go free all data indexes in this block
BCS BummErr
JSR WrtGBuf
BCS BummErr
LDX dTempX ;Restore index to dealloc buff
DEX ;Are there more to free?
BPL @loop4 ;Branch if there are
BMI @loop1 ;Branch always to do next bunch
deAlocTreeDone EQU *
deAlocSapDone EQU *
BummErr RTS
TreeDel17 LDY dTree ;Now deallocate all tree level
INY ; blocks greater than specified block
JSR DeAlocBlkZ ;(tree top in genBuf)
BCS BummErr ;Report any errors
JSR WrtGBuf ;Write updated top back to disk
BCS BummErr
LDY dTree ;Now figure out if tree can become sapling
BEQ @11 ;Branch if it can!
LDA genBuf,Y ;Otherwise, continue with partial
STA blockNum ; deallocation of last sapling index
ORA genBuf+$100,Y ;Is there such a sapling index block?
BEQ deAlocTreeDone ;All done if not!
LDA genBuf+$100,Y ;Read in sapling level to be modified
STA blockNum+1
JSR RdGBuf ;Read 'highest' sapling index into genBuf
BCC SapDeAllocZ
RTS
@11 JSR Shrink ;Shrink tree to sapling
BCS BummErr
; @ Deallocate a sapling file
SapDeAlloc0 JSR RdKeyBlk ;Read specified only sapling level index into gbuf
BCS BummErr
SapDeAllocZ LDY dSap ;fetch pointer to last of desirable indexes
INY ;Bump to the first undesirable
BEQ @21 ;branch if all are desirable
JSR DeAlocBlkZ ;Deallocate all indexes above appointed
BCS BummErr
JSR WrtGBuf ;Update disk with remaining indexes
BCS BummErr
@21 LDY dSap ;Now prepare to cleanup last data block
BEQ @22 ;Branch if there is a posiblity of making it a seed
@loop LDA genBuf,Y ;Fetch low order data block addr
STA blockNum
ORA genBuf+$100,Y ;Is it a real block?
BEQ deAlocSapDone ;We're done if not
LDA genBuf+$100,Y
STA blockNum+1
JSR RdGBuf ;Go read data block into gbuf
BCC SeedDeAllocZ ;Branch if good read
RTS ;Otherwise return error
@22 LDA dTree ;Are both tree and sap levels zero?
BNE @loop ;Branch if not.
JSR Shrink ;Reduce this sap to a seed
BCS BumErr1
; @ If no error, drop into SeedDeAlloc0
SeedDeAlloc0 JSR RdKeyBlk ;Go read only data block
BCS BumErr1 ;Report any errors
SeedDeAllocZ LDY dSeed+1 ;Check hi byte for no deletion
BEQ @31 ;Branch if all of second page is to be deleted
DEY ;If dseed>$200 then were all done!
BNE BumErr1 ;Branch if that's the case
LDY dSeed ;Clear only bytes >= dseed
@31 LDA #$00
@loop1 STA genBuf+$100,Y ;Zero out unwanted data
INY
BNE @loop1
LDY dSeed+1 ;Was that all?
BNE @32 ;Branch if it was
LDY dSeed
@loop2 STA genBuf,Y
INY
BNE @loop2
@32 JMP WrtGBuf ;Update data block to disk
BumErr1 RTS
RdKeyBlk LDA firstBlkL ;Read specified first
LDX firstBlkH ; block into genBbuf
JMP RdBlkAX ;Go do it!
; @*************************************************
; @ Beware that dealloc may bring in a new bitmap block
; @ and may destroy locations 46 and 47 which use to
; @ point to the current index block.
; @*************************************************
Shrink LDX firstBlkH ;First deallocate top block
TXA
PHA
LDA firstBlkL
PHA ;Save block address of this index block
JSR Dealloc ;Go do it
PLA
STA blockNum ;Set master of sapling index block address
PLA
STA blockNum+1
BCS @Ret ;report any errors
LDA genBuf ;Get first block at lower level
STA firstBlkL
LDA genBuf+$100
STA firstBlkH
LDY #$00
JSR SwapMe
SEC ;Now change file type, from
LDA storType ; tree to sapling,
SBC #$10 ; or from sapling to seed!
STA storType
JSR WrtGBuf
@Ret RTS
; @-------------------------------------------------
; @ Free master index/index block entries
; @ If DeAlockBlkZ is used, (Y) must be set correctly
DeAllocBlk LDY #$00 ;Start at the beginning
DeAlocBlkZ LDA blockNum ;Save disk address
PHA ; of genBuf's data
LDA blockNum+1
PHA
@loop STY sapPtr ;Save current index
LDA genBuf,Y ;Get address (low) of block to be deallocated
CMP #$01 ;Test for NULL block
LDX genBuf+$100,Y ;Get the rest of the block address
BNE @1 ;Branch if not NULL
BCC @2 ;Skip it if NULL
@1 JSR Dealloc ;Free it up on volume bitMap
BCS @3 ;Return any error
LDY sapPtr ;Get index to sapling level index block again
JSR SwapMe
@2 INY ;Point at next block address
BNE @loop ;Branch if more to deallocate (or test)
CLC ;Indicate no error
@3 TAX ;Save error code, if any
PLA
STA blockNum+1
PLA
STA blockNum
TXA ;Restore return code
RTS
; @*************************************************
; @ delFlag = 0 - Not called by Destroy
; @ delFlag = 1 - Called Destroy ie swapping
; @ Swap the Lo & Hi indices making up a disk addr
; @ so that disk recovery programs may be able
; @ to undelete a destroyed file
SwapMe LDA delFlag ;Are we swapping or zeroing ?
BNE @1 ;Skip if swapping
TAX ;Make X a 0
BEQ @2 ;0 the index (always taken)
@1 LDX genBuf+$100,Y ;Get index, hi
LDA genBuf,Y ;Get index, lo
@2 STA genBuf+$100,Y ;Save index, hi
TXA
STA genBuf,Y ;Save index, lo
RTS ;We're done