/
storage.asm
272 lines (216 loc) · 4.87 KB
/
storage.asm
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
260
261
262
263
264
265
266
267
268
269
270
271
272
;;; IDE
; run the trivial command in 'a', assuming other params are setup
simpleidecomm: ldb #0b11100000
stb IDEHEADS
sta IDECOMMAND
clra
rts
idewaitnotbusy: lda IDESTATUS
anda #0x80
bne idewaitnotbusy
rts
idewaitfordata: lda IDESTATUS
anda #0x08
beq idewaitfordata
rts
idellread: ldy #512
lbsr idewaitnotbusy
lbsr idewaitfordata
readwordloop: lda IDEDATA
ldb IDEHIGH
std ,x++
leay -2,y
bne readwordloop
rts
idellreadr: ldy #512
lbsr idewaitnotbusy
lbsr idewaitfordata
readwordloopr: ldb IDEDATA
lda IDEHIGH
std ,x++
leay -2,y
bne readwordloopr
rts
idellwrite: ldy #512
lbsr idewaitnotbusy
writewordloop: ldd ,x++
stb IDEHIGH
sta IDEDATA
leay -2,y
bne writewordloop
rts
partstartmsg: .asciz 'Partition starts at: '
nombrmsg: .asciz 'No MBR found, assuming single partition\r\n'
idemount: clr IDELBA0
clr IDELBA1
clr IDELBA2
clr IDELBA3
lda #1
sta IDECOUNT
lda #0x20
lbsr simpleidecomm
ldx #idescratchsec
lbsr idellread
ldx #idescratchsec+0x01fe
lbsr wordswap
ldd idescratchsec+0x01fe
cmpd #0xaa55
beq idemountmbr
ldx #nombrmsg
lbsr ioputstr
clra
clrb
std firstpartsects
rts
idemountmbr: ldx #idescratchsec+0x01be+0x08
lbsr wordswap
ldd idescratchsec+0x01be+0x08
std firstpartsects
ldx #partstartmsg
ldy #firstpartsects
lbsr ioputlab
rts
;;; FS
; readblk - reads 1k block at y into block buffer at x
fsreadblk: pshs d
tfr y,d
lslb
rola ; multiple x by 2->sectors
addd firstpartsects ; add sector offset for the partition
stb IDELBA0
sta IDELBA1
clr IDELBA2
clr IDELBA3
lda #2
sta IDECOUNT
lda #0x20
lbsr simpleidecomm
lbsr idellread
lbsr idellread
puls d
rts
; reads an inode y into memory at x
fsreadinode: pshs x,y,d
stx inodeptr
tfr y,d
subd #1 ; inodes start from 1
pshs b
lbsr div32
addd startofinodes
ldx #scratchblk
tfr d,y
lbsr fsreadblk
ldx inodeptr
ldy #scratchblk
clra
puls b ; get original (low byte) inode back
andb #0b00011111 ; mask off the inode position in block
lbsr mul32 ; d now has byte offset start of inode
leay d,y
ldb #0x20 ; copy 20 bytes
moreinode: lda ,y+
sta ,x+
decb
bne moreinode
ldx inodeptr ; type+mode
lbsr wordswap
leax 4,x ; low word of size
lbsr wordswap
ldx inodeptr
leax 14,x
ldb #8
datawordswaps: lbsr wordswap
leax 2,x
decb
bne datawordswaps
puls x,y,d
rts
; reads all (upto 7 direct + 32 indirect blocks) the data for the current
; inode into x
fsreaddata: ldb #7 ; 7 direct blocks
ldu #inode+14 ; direct pointers start 14 bytes in
moredatablks: ldy ,u++ ; get the first block number
beq fsreaddataout ; zero? end of array
lbsr fsreadblk ; read the block into x
decb ; next block
bne moredatablks ; read upto 7 blocks
; following the direct blocks we have indirect blocks
pshs x ; save how far we have got so far
ldx #scratchblk ; this is a block of pointers
ldy ,u++ ; get the first (and only) indirect
beq fsreaddataout ; if not set, skip indirect stuff
lbsr fsreadblk ; read the block of direct pointers
ldb #0x20 ; we will swap the first 32 pointers
ldx #scratchblk ; we don't care about the rest
swapindir: lbsr wordswap ; swap a pointer
leax 1,x ; next pointer
decb ; and one less to swap
bne swapindir ; go back and swap
ldu #scratchblk ; now we need to load each block
ldb #0x20 ; upto only 32 additional blocks
puls x ; pop the stashed file block pointer
moreindirblks: ldy ,u++ ; y is the block of real file data
beq fsreaddataout ; it might be not set
lbsr fsreadblk ; if it is, read it all in to x
decb ; see....
bne moreindirblks ; if there are more indirect blocks
fsreaddataout: rts
; reads the file at inode y into x, using the inode and data read functions
fsreadfile: pshs x ; save our param for where to write
ldx #inode ; set up the inode pointer
lbsr fsreadinode ; read inode y
puls x ; get the parm back
lbsr fsreaddata ; read the data
rts
; outputs a file listing for the inode at dirinode
fsshowdirlist: ldx #dirinode
lbsr fsreadinode
ldd dirinode
anda #0x40
cmpa #0x40
beq showdirisdir
lda #1
rts
showdirisdir: ldb #7
ldu #dirinode+14
nextdirblk: ldy ,u++
beq fsshowdirlisto
ldx #scratchdirblk
lbsr fsreadblk
lbsr fsshowdirblk
decb
bne nextdirblk
fsshowdirlisto: rts
fsshowdirblk: pshs d,x,y,u
ldu #scratchdirblk
nextdirent: leax ,u++
lbsr wordswap
ldd ,x
beq skipdir
ldx #inode
tfr d,y
lbsr fsreadinode
ldx #outputbuffer
lbsr wordtoaschex ; convert it to ascii
lda #0x20 ; space char
sta ,x+
ldd inode
lbsr wordtoaschex
lda #0x20
sta ,x+
ldd inode+4
lbsr wordtoaschex
lda #0x20
sta ,x+
tfr u,y
lbsr concatstr
ldy #newlinemsg
lbsr concatstr
clr ,x+
ldx #outputbuffer
lbsr ioputstr
skipdir: leau 30,u
cmpu #scratchdirblk+1024
bne nextdirent
puls d,x,y,u
rts