Rev 3935 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3935 | Rev 4066 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Contains ext2 structures, and macros. ;; |
3 | ;; Contains ext2 structures, and macros. ;; |
4 | ;; ;; |
4 | ;; ;; |
5 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
5 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
6 | ;; Distributed under the terms of the new BSD license. ;; |
6 | ;; Distributed under the terms of the new BSD license. ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
- | 9 | ||
- | 10 | ; Future jobs for driver, in order of preference: |
|
- | 11 | ; * clean up existing extents support. |
|
- | 12 | ; * add b-tree directories support. |
|
- | 13 | ; * add long file support. |
|
- | 14 | ; * add journal support. |
|
- | 15 | ; * add minor features that come with ext3/4. |
|
9 | 16 | ||
10 | ; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course). |
17 | ; Recommended move to some kernel-wide bitmap handling code (with a bit of abstraction, of course). |
11 | 18 | ||
12 | ;--------------------------------------------------------------------- |
19 | ;--------------------------------------------------------------------- |
13 | ; Clears a bit. |
20 | ; Clears a bit. |
14 | ; Input: eax = index into bitmap. |
21 | ; Input: eax = index into bitmap. |
15 | ; [EXTFS.ext2_save_block] = address of bitmap. |
22 | ; [EXTFS.ext2_save_block] = address of bitmap. |
16 | ; ebp = address of EXTFS. |
23 | ; ebp = address of EXTFS. |
17 | ; Output: Bit cleared. |
24 | ; Output: Bit cleared. |
18 | ; eax = non-zero, if already cleared. |
25 | ; eax = non-zero, if already cleared. |
19 | ;--------------------------------------------------------------------- |
26 | ;--------------------------------------------------------------------- |
20 | bitmap_clear_bit: |
27 | bitmap_clear_bit: |
21 | push ebx ecx edx |
28 | push ebx ecx edx |
22 | 29 | ||
23 | xor edx, edx |
30 | xor edx, edx |
24 | mov ecx, 8 |
31 | mov ecx, 8 |
25 | div ecx |
32 | div ecx |
26 | 33 | ||
27 | add eax, [ebp + EXTFS.ext2_save_block] |
34 | add eax, [ebp + EXTFS.ext2_save_block] |
28 | 35 | ||
29 | ; Get the mask. |
36 | ; Get the mask. |
30 | mov ebx, 1 |
37 | mov ebx, 1 |
31 | mov ecx, edx |
38 | mov ecx, edx |
32 | shl ebx, cl |
39 | shl ebx, cl |
33 | 40 | ||
34 | test [eax], ebx |
41 | test [eax], ebx |
35 | jz .cleared |
42 | jz .cleared |
36 | 43 | ||
37 | not ebx |
44 | not ebx |
38 | and [eax], ebx |
45 | and [eax], ebx |
39 | 46 | ||
40 | xor eax, eax |
47 | xor eax, eax |
41 | .return: |
48 | .return: |
42 | pop edx ecx ebx |
49 | pop edx ecx ebx |
43 | ret |
50 | ret |
44 | 51 | ||
45 | ; Already cleared. |
52 | ; Already cleared. |
46 | .cleared: |
53 | .cleared: |
47 | xor eax, eax |
54 | xor eax, eax |
48 | not eax |
55 | not eax |
49 | jmp .return |
56 | jmp .return |
50 | 57 | ||
51 | ;--------------------------------------------------------------------- |
58 | ;--------------------------------------------------------------------- |
52 | ; Finds free bit in the bitmap. |
59 | ; Finds free bit in the bitmap. |
53 | ; Input: ecx = number of bits in the bitmap. |
60 | ; Input: ecx = number of bits in the bitmap. |
54 | ; [EXTFS.ext2_save_block] = address of bitmap. |
61 | ; [EXTFS.ext2_save_block] = address of bitmap. |
55 | ; ebp = address of EXTFS. |
62 | ; ebp = address of EXTFS. |
56 | ; Output: eax = index of free bit in the bitmap; marked set. |
63 | ; Output: eax = index of free bit in the bitmap; marked set. |
57 | ; 0xFFFFFFFF if no free bit found. |
64 | ; 0xFFFFFFFF if no free bit found. |
58 | ;--------------------------------------------------------------------- |
65 | ;--------------------------------------------------------------------- |
59 | ext2_find_free_bit: |
66 | ext2_find_free_bit: |
60 | bitmap_find_free_bit: |
67 | bitmap_find_free_bit: |
61 | push esi ebx ecx edx |
68 | push esi ebx ecx edx |
62 | mov esi, [ebp + EXTFS.ext2_save_block] |
69 | mov esi, [ebp + EXTFS.ext2_save_block] |
63 | 70 | ||
64 | ; Get total DWORDS in eax; total bits in last dword, if any, in edx. |
71 | ; Get total DWORDS in eax; total bits in last dword, if any, in edx. |
65 | xor edx, edx |
72 | xor edx, edx |
66 | mov eax, ecx |
73 | mov eax, ecx |
67 | mov ecx, 32 |
74 | mov ecx, 32 |
68 | div ecx |
75 | div ecx |
69 | 76 | ||
70 | mov ecx, eax |
77 | mov ecx, eax |
71 | xor eax, eax |
78 | xor eax, eax |
72 | push edx |
79 | push edx |
73 | 80 | ||
74 | test ecx, ecx |
81 | test ecx, ecx |
75 | jz .last_bits |
82 | jz .last_bits |
76 | 83 | ||
77 | ; Check in the DWORDS. |
84 | ; Check in the DWORDS. |
78 | .dwords: |
85 | .dwords: |
79 | mov ebx, [esi] |
86 | mov ebx, [esi] |
80 | not ebx |
87 | not ebx |
81 | 88 | ||
82 | bsf edx, ebx |
89 | bsf edx, ebx |
83 | 90 | ||
84 | ; If 0, then the original value would be 0xFFFFFFFF, hence no free bits. |
91 | ; If 0, then the original value would be 0xFFFFFFFF, hence no free bits. |
85 | jz @F |
92 | jz @F |
86 | 93 | ||
87 | ; We found the value. Let's return with it. |
94 | ; We found the value. Let's return with it. |
88 | add esp, 4 |
95 | add esp, 4 |
- | 96 | ||
89 | add eax, edx |
97 | add eax, edx |
90 | jmp .return |
98 | jmp .return |
91 | 99 | ||
92 | @@: |
100 | @@: |
93 | add esi, 4 |
101 | add esi, 4 |
94 | add eax, 32 |
102 | add eax, 32 |
95 | loop .dwords |
103 | loop .dwords |
96 | 104 | ||
97 | .last_bits: |
105 | .last_bits: |
98 | ; Check in the last few bits. |
106 | ; Check in the last few bits. |
99 | pop ecx |
107 | pop ecx |
100 | test ecx, ecx |
108 | test ecx, ecx |
101 | jz @F |
109 | jz @F |
102 | 110 | ||
103 | mov ebx, [esi] |
111 | mov ebx, [esi] |
104 | not ebx |
112 | not ebx |
105 | bsf ebx, edx |
113 | bsf ebx, edx |
106 | 114 | ||
107 | ; If 0, no free bits. |
115 | ; If 0, no free bits. |
108 | jz @F |
116 | jz @F |
109 | 117 | ||
110 | ; If free bit is greater than the last known bit, then error. |
118 | ; If free bit is greater than the last known bit, then error. |
111 | cmp edx, ecx |
119 | cmp edx, ecx |
112 | jg @F |
120 | jg @F |
113 | 121 | ||
114 | add eax, edx |
122 | add eax, edx |
115 | jmp .return |
123 | jmp .return |
116 | 124 | ||
117 | @@: |
125 | @@: |
118 | ; Didn't find any free bits. |
126 | ; Didn't find any free bits. |
119 | xor eax, eax |
127 | xor eax, eax |
120 | not eax |
128 | not eax |
121 | jmp @F |
129 | jmp @F |
122 | 130 | ||
123 | .return: |
131 | .return: |
124 | mov ecx, edx |
132 | mov ecx, edx |
125 | mov edx, 1 |
133 | mov edx, 1 |
126 | shl edx, cl |
134 | shl edx, cl |
127 | or [esi], edx |
135 | or [esi], edx |
128 | 136 | ||
129 | @@: |
137 | @@: |
130 | pop edx ecx ebx esi |
138 | pop edx ecx ebx esi |
131 | ret |
139 | ret |
132 | 140 | ||
133 | ; Recommended move to some kernel-wide string handling code. |
141 | ; Recommended move to some kernel-wide string handling code. |
134 | ;--------------------------------------------------------------------- |
142 | ;--------------------------------------------------------------------- |
135 | ; Find the length of a string. |
143 | ; Find the length of a string. |
136 | ; Input: esi = source. |
144 | ; Input: esi = source. |
137 | ; Output: length in ecx |
145 | ; Output: length in ecx |
138 | ;--------------------------------------------------------------------- |
146 | ;--------------------------------------------------------------------- |
139 | strlen: |
147 | strlen: |
140 | push eax esi |
148 | push eax esi |
141 | xor ecx, ecx |
149 | xor ecx, ecx |
142 | 150 | ||
143 | @@: |
151 | @@: |
144 | lodsb |
152 | lodsb |
145 | test al, al |
153 | test al, al |
146 | jz .ret |
154 | jz .ret |
147 | 155 | ||
148 | inc ecx |
156 | inc ecx |
149 | jmp @B |
157 | jmp @B |
150 | 158 | ||
151 | .ret: |
159 | .ret: |
152 | pop esi eax |
160 | pop esi eax |
153 | ret |
161 | ret |
154 | 162 | ||
155 | ;--------------------------------------------------------------------- |
163 | ;--------------------------------------------------------------------- |
156 | ; Convert UTF-8 string to ASCII-string (codepage 866) |
164 | ; Convert UTF-8 string to ASCII-string (codepage 866) |
157 | ; Input: esi = source. |
165 | ; Input: esi = source. |
158 | ; edi = buffer. |
166 | ; edi = buffer. |
159 | ; ecx = length of source. |
167 | ; ecx = length of source. |
160 | ; Output: destroys eax, esi, edi |
168 | ; Output: destroys eax, esi, edi |
161 | ;--------------------------------------------------------------------- |
169 | ;--------------------------------------------------------------------- |
162 | utf8_to_cp866: |
170 | utf8_to_cp866: |
163 | ; Check for zero-length string. |
171 | ; Check for zero-length string. |
164 | jecxz .return |
172 | jecxz .return |
165 | 173 | ||
166 | .start: |
174 | .start: |
167 | lodsw |
175 | lodsw |
168 | cmp al, 0x80 |
176 | cmp al, 0x80 |
169 | jb .ascii |
177 | jb .ascii |
170 | 178 | ||
171 | xchg al, ah ; Big-endian. |
179 | xchg al, ah ; Big-endian. |
172 | cmp ax, 0xd080 |
180 | cmp ax, 0xd080 |
173 | jz .yo1 |
181 | jz .yo1 |
174 | 182 | ||
175 | cmp ax, 0xd191 |
183 | cmp ax, 0xd191 |
176 | jz .yo2 |
184 | jz .yo2 |
177 | 185 | ||
178 | cmp ax, 0xd090 |
186 | cmp ax, 0xd090 |
179 | jb .unk |
187 | jb .unk |
180 | 188 | ||
181 | cmp ax, 0xd180 |
189 | cmp ax, 0xd180 |
182 | jb .rus1 |
190 | jb .rus1 |
183 | 191 | ||
184 | cmp ax, 0xd190 |
192 | cmp ax, 0xd190 |
185 | jb .rus2 |
193 | jb .rus2 |
186 | 194 | ||
187 | .unk: |
195 | .unk: |
188 | mov al, '_' |
196 | mov al, '_' |
189 | jmp .doit |
197 | jmp .doit |
190 | 198 | ||
191 | .yo1: |
199 | .yo1: |
192 | mov al, 0xf0 ; Ё capital. |
200 | mov al, 0xf0 ; Ё capital. |
193 | jmp .doit |
201 | jmp .doit |
194 | 202 | ||
195 | .yo2: |
203 | .yo2: |
196 | mov al, 0xf1 ; ё small. |
204 | mov al, 0xf1 ; ё small. |
197 | jmp .doit |
205 | jmp .doit |
198 | 206 | ||
199 | .rus1: |
207 | .rus1: |
200 | sub ax, 0xd090 - 0x80 |
208 | sub ax, 0xd090 - 0x80 |
201 | jmp .doit |
209 | jmp .doit |
202 | 210 | ||
203 | .rus2: |
211 | .rus2: |
204 | sub ax, 0xd18f - 0xEF |
212 | sub ax, 0xd18f - 0xEF |
205 | 213 | ||
206 | .doit: |
214 | .doit: |
207 | stosb |
215 | stosb |
208 | sub ecx, 2 |
216 | sub ecx, 2 |
209 | ja .start |
217 | ja .start |
210 | ret |
218 | ret |
211 | 219 | ||
212 | .ascii: |
220 | .ascii: |
213 | stosb |
221 | stosb |
214 | dec esi |
222 | dec esi |
215 | dec ecx |
223 | dec ecx |
216 | jnz .start |
224 | jnz .start |
217 | 225 | ||
218 | .return: |
226 | .return: |
219 | ret |
227 | ret |
220 | 228 | ||
221 | ; Recommended move to some kernel-wide time handling code. |
229 | ; Recommended move to some kernel-wide time handling code. |
222 | 230 | ||
223 | ; Total cumulative seconds till each month. |
231 | ; Total cumulative seconds till each month. |
224 | cumulative_seconds_in_month: |
232 | cumulative_seconds_in_month: |
225 | .january: dd 0 * (60 * 60 * 24) |
233 | .january: dd 0 * (60 * 60 * 24) |
226 | .february: dd 31 * (60 * 60 * 24) |
234 | .february: dd 31 * (60 * 60 * 24) |
227 | .march: dd 59 * (60 * 60 * 24) |
235 | .march: dd 59 * (60 * 60 * 24) |
228 | .april: dd 90 * (60 * 60 * 24) |
236 | .april: dd 90 * (60 * 60 * 24) |
229 | .may: dd 120 * (60 * 60 * 24) |
237 | .may: dd 120 * (60 * 60 * 24) |
230 | .june: dd 151 * (60 * 60 * 24) |
238 | .june: dd 151 * (60 * 60 * 24) |
231 | .july: dd 181 * (60 * 60 * 24) |
239 | .july: dd 181 * (60 * 60 * 24) |
232 | .august: dd 212 * (60 * 60 * 24) |
240 | .august: dd 212 * (60 * 60 * 24) |
233 | .september: dd 243 * (60 * 60 * 24) |
241 | .september: dd 243 * (60 * 60 * 24) |
234 | .october: dd 273 * (60 * 60 * 24) |
242 | .october: dd 273 * (60 * 60 * 24) |
235 | .november: dd 304 * (60 * 60 * 24) |
243 | .november: dd 304 * (60 * 60 * 24) |
236 | .december: dd 334 * (60 * 60 * 24) |
244 | .december: dd 334 * (60 * 60 * 24) |
237 | 245 | ||
238 | current_bdfe_time: |
246 | current_bdfe_time: |
239 | dd 0 |
247 | dd 0 |
240 | current_bdfe_date: |
248 | current_bdfe_date: |
241 | dd 0 |
249 | dd 0 |
242 | 250 | ||
243 | ;--------------------------------------------------------------------- |
251 | ;--------------------------------------------------------------------- |
244 | ; Stores current unix time. |
252 | ; Stores current unix time. |
245 | ; Input: edi = buffer to output Unix time. |
253 | ; Input: edi = buffer to output Unix time. |
246 | ;--------------------------------------------------------------------- |
254 | ;--------------------------------------------------------------------- |
247 | current_unix_time: |
255 | current_unix_time: |
248 | push eax esi |
256 | push eax esi |
249 | mov esi, current_bdfe_time |
257 | mov esi, current_bdfe_time |
250 | 258 | ||
251 | ; Just a small observation: |
259 | ; Just a small observation: |
252 | ; The CMOS is a pretty bad source to get time from. One shouldn't rely on it, |
260 | ; The CMOS is a pretty bad source to get time from. One shouldn't rely on it, |
253 | ; since it messes up the time by tiny bits. Of course, this is all technical, |
261 | ; since it messes up the time by tiny bits. Of course, this is all technical, |
254 | ; but one can look it up on the osdev wiki. What is better is to get the time |
262 | ; but one can look it up on the osdev wiki. What is better is to get the time |
255 | ; from CMOS during boot, then update system time using a more accurate timer. |
263 | ; from CMOS during boot, then update system time using a more accurate timer. |
256 | ; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!. |
264 | ; I'll probably add that after the Summer of Code, so TODO! TODO! TODO!. |
257 | 265 | ||
258 | ; Get time from CMOS. |
266 | ; Get time from CMOS. |
259 | ; Seconds. |
267 | ; Seconds. |
260 | mov al, 0x00 |
268 | mov al, 0x00 |
261 | out 0x70, al |
269 | out 0x70, al |
262 | in al, 0x71 |
270 | in al, 0x71 |
263 | call bcd2bin |
271 | call bcd2bin |
264 | mov [esi + 0], al |
272 | mov [esi + 0], al |
265 | 273 | ||
266 | ; Minute. |
274 | ; Minute. |
267 | mov al, 0x02 |
275 | mov al, 0x02 |
268 | out 0x70, al |
276 | out 0x70, al |
269 | in al, 0x71 |
277 | in al, 0x71 |
270 | call bcd2bin |
278 | call bcd2bin |
271 | mov [esi + 1], al |
279 | mov [esi + 1], al |
272 | 280 | ||
273 | ; Hour. |
281 | ; Hour. |
274 | mov al, 0x04 |
282 | mov al, 0x04 |
275 | out 0x70, al |
283 | out 0x70, al |
276 | in al, 0x71 |
284 | in al, 0x71 |
277 | call bcd2bin |
285 | call bcd2bin |
278 | mov [esi + 2], al |
286 | mov [esi + 2], al |
279 | 287 | ||
280 | ; Get date. |
288 | ; Get date. |
281 | 289 | ||
282 | ; Day. |
290 | ; Day. |
283 | mov al, 0x7 |
291 | mov al, 0x7 |
284 | out 0x70, al |
292 | out 0x70, al |
285 | in al, 0x71 |
293 | in al, 0x71 |
286 | call bcd2bin |
294 | call bcd2bin |
287 | mov [esi + 4], al |
295 | mov [esi + 4], al |
288 | 296 | ||
289 | ; Month. |
297 | ; Month. |
290 | mov al, 0x8 |
298 | mov al, 0x8 |
291 | out 0x70, al |
299 | out 0x70, al |
292 | in al, 0x71 |
300 | in al, 0x71 |
293 | call bcd2bin |
301 | call bcd2bin |
294 | mov [esi + 5], al |
302 | mov [esi + 5], al |
295 | 303 | ||
296 | ; Year. |
304 | ; Year. |
297 | mov al, 0x9 |
305 | mov al, 0x9 |
298 | out 0x70, al |
306 | out 0x70, al |
299 | in al, 0x71 |
307 | in al, 0x71 |
300 | call bcd2bin |
308 | call bcd2bin |
301 | add ax, 2000 ; CMOS only returns last two digits. |
309 | add ax, 2000 ; CMOS only returns last two digits. |
302 | ; Note that everywhere in KolibriOS this is used. |
310 | ; Note that everywhere in KolibriOS this is used. |
303 | ; This is hacky, since the RTC can be incorrectly set |
311 | ; This is hacky, since the RTC can be incorrectly set |
304 | ; to something before 2000. |
312 | ; to something before 2000. |
305 | mov [esi + 6], ax |
313 | mov [esi + 6], ax |
306 | 314 | ||
307 | call bdfe_to_unix_time |
315 | call bdfe_to_unix_time |
308 | pop esi eax |
316 | pop esi eax |
309 | ret |
317 | ret |
310 | 318 | ||
311 | ;--------------------------------------------------------------------- |
319 | ;--------------------------------------------------------------------- |
312 | ; Convert time+date from BDFE to Unix time. |
320 | ; Convert time+date from BDFE to Unix time. |
313 | ; Input: esi = pointer to BDFE time+date. |
321 | ; Input: esi = pointer to BDFE time+date. |
314 | ; edi = buffer to output Unix time. |
322 | ; edi = buffer to output Unix time. |
315 | ;--------------------------------------------------------------------- |
323 | ;--------------------------------------------------------------------- |
316 | bdfe_to_unix_time: |
324 | bdfe_to_unix_time: |
317 | push eax ebx ecx edx |
325 | push eax ebx ecx edx |
318 | mov dword[edi], 0x00000000 |
326 | mov dword[edi], 0x00000000 |
319 | 327 | ||
320 | ; The minimum representable time is 1901-12-13. |
328 | ; The minimum representable time is 1901-12-13. |
321 | cmp word[esi + 6], 1901 |
329 | cmp word[esi + 6], 1901 |
322 | jb .ret |
330 | jb .ret |
323 | jg .max |
331 | jg .max |
324 | 332 | ||
325 | cmp byte[esi + 5], 12 |
333 | cmp byte[esi + 5], 12 |
326 | jb .ret |
334 | jb .ret |
327 | 335 | ||
328 | cmp byte[esi + 4], 13 |
336 | cmp byte[esi + 4], 13 |
329 | jbe .ret |
337 | jbe .ret |
330 | jg .convert |
338 | jg .convert |
331 | 339 | ||
332 | ; Check if it is more than the maximum representable time. |
340 | ; Check if it is more than the maximum representable time. |
333 | .max: |
341 | .max: |
334 | ; The maximum representable time is 2038-01-19. |
342 | ; The maximum representable time is 2038-01-19. |
335 | cmp word[esi + 6], 2038 |
343 | cmp word[esi + 6], 2038 |
336 | jg .ret |
344 | jg .ret |
337 | jb .convert |
345 | jb .convert |
338 | 346 | ||
339 | cmp byte[esi + 5], 1 |
347 | cmp byte[esi + 5], 1 |
340 | jg .ret |
348 | jg .ret |
341 | 349 | ||
342 | cmp byte[esi + 4], 19 |
350 | cmp byte[esi + 4], 19 |
343 | jge .ret |
351 | jge .ret |
344 | 352 | ||
345 | ; Convert the time. |
353 | ; Convert the time. |
346 | .convert: |
354 | .convert: |
347 | ; Get if current year is leap year in ECX. |
355 | ; Get if current year is leap year in ECX. |
348 | xor ecx, ecx |
356 | xor ecx, ecx |
349 | mov ebx, 4 |
357 | mov ebx, 4 |
350 | xor edx, edx |
358 | xor edx, edx |
351 | 359 | ||
352 | cmp word[esi + 6], 1970 |
360 | cmp word[esi + 6], 1970 |
353 | jb .negative |
361 | jb .negative |
354 | 362 | ||
355 | movzx eax, word[esi + 6] ; Year. |
363 | movzx eax, word[esi + 6] ; Year. |
356 | cmp byte[esi + 5], 3 ; If the month is less than March, than that year doesn't matter. |
364 | cmp byte[esi + 5], 3 ; If the month is less than March, than that year doesn't matter. |
357 | jge @F |
365 | jge @F |
358 | 366 | ||
359 | test eax, 3 |
367 | test eax, 3 |
360 | ; Not a leap year. |
368 | ; Not a leap year. |
361 | jnz @F |
369 | jnz @F |
362 | 370 | ||
363 | inc ecx |
371 | inc ecx |
364 | @@: |
372 | @@: |
365 | ; Number of leap years between two years = ((end date - 1)/4) - (1970/4) |
373 | ; Number of leap years between two years = ((end date - 1)/4) - (1970/4) |
366 | dec eax |
374 | dec eax |
367 | div ebx |
375 | div ebx |
368 | sub eax, 1970/4 |
376 | sub eax, 1970/4 |
369 | 377 | ||
370 | ; EAX is the number of leap years. |
378 | ; EAX is the number of leap years. |
371 | add eax, ecx |
379 | add eax, ecx |
372 | mov ecx, (60 * 60 * 24) ; Seconds in a day. |
380 | mov ecx, (60 * 60 * 24) ; Seconds in a day. |
373 | mul ecx |
381 | mul ecx |
374 | 382 | ||
375 | ; Account for leap years, i.e., one day extra for each. |
383 | ; Account for leap years, i.e., one day extra for each. |
376 | add [edi], eax |
384 | add [edi], eax |
377 | 385 | ||
378 | ; Get total days in EAX. |
386 | ; Get total days in EAX. |
379 | movzx eax, byte[esi + 4] |
387 | movzx eax, byte[esi + 4] |
380 | dec eax |
388 | dec eax |
381 | mul ecx |
389 | mul ecx |
382 | 390 | ||
383 | ; Account for days. |
391 | ; Account for days. |
384 | add [edi], eax |
392 | add [edi], eax |
385 | 393 | ||
386 | ; Account for month. |
394 | ; Account for month. |
387 | movzx eax, byte[esi + 5] |
395 | movzx eax, byte[esi + 5] |
388 | dec eax |
396 | dec eax |
389 | mov eax, [cumulative_seconds_in_month + (eax * 4)] |
397 | mov eax, [cumulative_seconds_in_month + (eax * 4)] |
390 | add [edi], eax |
398 | add [edi], eax |
391 | 399 | ||
392 | ; Account for year. |
400 | ; Account for year. |
393 | movzx eax, word[esi + 6] |
401 | movzx eax, word[esi + 6] |
394 | sub eax, 1970 |
402 | sub eax, 1970 |
395 | mov ecx, (60 * 60 * 24) * 365 ; Seconds in a year. |
403 | mov ecx, (60 * 60 * 24) * 365 ; Seconds in a year. |
396 | mul ecx |
404 | mul ecx |
397 | add [edi], eax |
405 | add [edi], eax |
398 | 406 | ||
399 | ; Seconds. |
407 | ; Seconds. |
400 | movzx eax, byte[esi + 0] |
408 | movzx eax, byte[esi + 0] |
401 | add [edi], eax |
409 | add [edi], eax |
402 | 410 | ||
403 | ; Minutes. |
411 | ; Minutes. |
404 | movzx eax, byte[esi + 1] |
412 | movzx eax, byte[esi + 1] |
405 | mov ecx, 60 |
413 | mov ecx, 60 |
406 | mul ecx |
414 | mul ecx |
407 | add [edi], eax |
415 | add [edi], eax |
408 | 416 | ||
409 | ; Hours. |
417 | ; Hours. |
410 | movzx eax, byte[esi + 2] |
418 | movzx eax, byte[esi + 2] |
411 | mov ecx, (60 * 60) |
419 | mov ecx, (60 * 60) |
412 | mul ecx |
420 | mul ecx |
413 | add [edi], eax |
421 | add [edi], eax |
414 | 422 | ||
415 | ; The time wanted is before the epoch; handle it here. |
423 | ; The time wanted is before the epoch; handle it here. |
416 | .negative: |
424 | .negative: |
417 | ; TODO. |
425 | ; TODO. |
418 | 426 | ||
419 | .ret: |
427 | .ret: |
420 | pop edx ecx ebx eax |
428 | pop edx ecx ebx eax |
421 | ret |
429 | ret |
422 | 430 | ||
423 | ; Recommended move to some kernel-wide alloc handling code. |
431 | ; Recommended move to some kernel-wide alloc handling code. |
424 | macro KERNEL_ALLOC store, label |
432 | macro KERNEL_ALLOC store, label |
425 | { |
433 | { |
426 | call kernel_alloc |
434 | call kernel_alloc |
427 | mov store, eax |
435 | mov store, eax |
428 | test eax, eax |
436 | test eax, eax |
429 | jz label |
437 | jz label |
430 | } |
438 | } |
431 | 439 | ||
432 | macro KERNEL_FREE data, label |
440 | macro KERNEL_FREE data, label |
433 | { |
441 | { |
434 | cmp data, 0 |
442 | cmp data, 0 |
435 | jz label |
443 | jz label |
436 | push data |
444 | push data |
437 | call kernel_free |
445 | call kernel_free |
438 | } |
446 | } |
439 | 447 | ||
440 | struct EXTFS PARTITION |
448 | struct EXTFS PARTITION |
441 | lock MUTEX |
449 | lock MUTEX |
442 | partition_flags dd ? |
450 | partition_flags dd ? |
443 | log_block_size dd ? |
451 | log_block_size dd ? |
444 | block_size dd ? |
452 | block_size dd ? |
445 | count_block_in_block dd ? |
453 | count_block_in_block dd ? |
446 | blocks_per_group dd ? |
454 | blocks_per_group dd ? |
447 | global_desc_table dd ? |
455 | global_desc_table dd ? |
448 | root_inode dd ? ; Pointer to root inode in memory. |
456 | root_inode dd ? ; Pointer to root inode in memory. |
449 | inode_size dd ? |
457 | inode_size dd ? |
450 | count_pointer_in_block dd ? ; (block_size / 4) |
458 | count_pointer_in_block dd ? ; (block_size / 4) |
451 | count_pointer_in_block_square dd ? ; (block_size / 4)**2 |
459 | count_pointer_in_block_square dd ? ; (block_size / 4)**2 |
452 | ext2_save_block dd ? ; Block for 1 global procedure. |
460 | ext2_save_block dd ? ; Block for 1 global procedure. |
453 | ext2_temp_block dd ? ; Block for small procedures. |
461 | ext2_temp_block dd ? ; Block for small procedures. |
454 | ext2_save_inode dd ? ; inode for global procedures. |
462 | ext2_save_inode dd ? ; inode for global procedures. |
455 | ext2_temp_inode dd ? ; inode for small procedures. |
463 | ext2_temp_inode dd ? ; inode for small procedures. |
456 | groups_count dd ? |
464 | groups_count dd ? |
457 | superblock rd 1024/4 |
465 | superblock rd 1024/4 |
458 | ends |
466 | ends |
459 | 467 | ||
460 | ; EXT2 revisions. |
468 | ; EXT2 revisions. |
461 | EXT2_GOOD_OLD_REV = 0 |
469 | EXT2_GOOD_OLD_REV = 0 |
462 | 470 | ||
463 | ; For fs_type. |
471 | ; For fs_type. |
464 | FS_TYPE_UNDEFINED = 0 |
472 | FS_TYPE_UNDEFINED = 0 |
465 | FS_TYPE_EXT = 2 |
473 | FS_TYPE_EXT = 2 |
466 | 474 | ||
467 | ; Some set inodes. |
475 | ; Some set inodes. |
468 | EXT2_BAD_INO = 1 |
476 | EXT2_BAD_INO = 1 |
469 | EXT2_ROOT_INO = 2 |
477 | EXT2_ROOT_INO = 2 |
470 | EXT2_ACL_IDX_INO = 3 |
478 | EXT2_ACL_IDX_INO = 3 |
471 | EXT2_ACL_DATA_INO = 4 |
479 | EXT2_ACL_DATA_INO = 4 |
472 | EXT2_BOOT_LOADER_INO = 5 |
480 | EXT2_BOOT_LOADER_INO = 5 |
473 | EXT2_UNDEL_DIR_INO = 6 |
481 | EXT2_UNDEL_DIR_INO = 6 |
474 | 482 | ||
475 | ; EXT2_SUPER_MAGIC. |
483 | ; EXT2_SUPER_MAGIC. |
476 | EXT2_SUPER_MAGIC = 0xEF53 |
484 | EXT2_SUPER_MAGIC = 0xEF53 |
477 | EXT2_VALID_FS = 1 |
485 | EXT2_VALID_FS = 1 |
478 | 486 | ||
479 | ; Flags defining i_mode values. |
487 | ; Flags defining i_mode values. |
480 | EXT2_S_IFMT = 0xF000 ; Mask for file type. |
488 | EXT2_S_IFMT = 0xF000 ; Mask for file type. |
481 | 489 | ||
482 | EXT2_S_IFREG = 0x8000 ; Regular file. |
490 | EXT2_S_IFREG = 0x8000 ; Regular file. |
483 | EXT2_S_IFDIR = 0x4000 ; Directory. |
491 | EXT2_S_IFDIR = 0x4000 ; Directory. |
484 | 492 | ||
485 | ; File type defining values in directory entry. |
493 | ; File type defining values in directory entry. |
486 | EXT2_FT_REG_FILE = 1 ; Regular file. |
494 | EXT2_FT_REG_FILE = 1 ; Regular file. |
487 | EXT2_FT_DIR = 2 ; Directory. |
495 | EXT2_FT_DIR = 2 ; Directory. |
488 | 496 | ||
489 | ; Flags used by KolibriOS. |
497 | ; Flags used by KolibriOS. |
490 | FS_FT_HIDDEN = 2 |
498 | FS_FT_HIDDEN = 2 |
491 | FS_FT_DIR = 0x10 ; Directory. |
499 | FS_FT_DIR = 0x10 ; Directory. |
492 | 500 | ||
493 | ; ext2 partition flags. |
501 | ; ext2 partition flags. |
494 | EXT2_RO = 0x01 |
502 | EXT2_RO = 0x01 |
495 | 503 | ||
496 | FS_FT_ASCII = 0 ; Name in ASCII. |
504 | FS_FT_ASCII = 0 ; Name in ASCII. |
497 | FS_FT_UNICODE = 1 ; Name in Unicode. |
505 | FS_FT_UNICODE = 1 ; Name in Unicode. |
498 | 506 | ||
499 | EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry. |
507 | EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ; Have file type in directory entry. |
500 | EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ; Extents. |
508 | EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ; Extents. |
501 | EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ; Flexible block groups. |
509 | EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ; Flexible block groups. |
502 | 510 | ||
503 | EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock |
511 | EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001 ; Sparse Superblock |
504 | EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x0002 ; Large file support (64-bit file size) |
512 | EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x0002 ; Large file support (64-bit file size) |
505 | 513 | ||
506 | ; Implemented ext[2,3,4] features. |
514 | ; Implemented ext[2,3,4] features. |
507 | EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \ |
515 | EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \ |
508 | or EXT4_FEATURE_INCOMPAT_EXTENTS \ |
516 | or EXT4_FEATURE_INCOMPAT_EXTENTS \ |
509 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
517 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
510 | 518 | ||
511 | ; Implemented features which otherwise require "read-only" mount. |
519 | ; Implemented features which otherwise require "read-only" mount. |
512 | EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \ |
520 | EXT2_FEATURE_RO_COMPAT_SUPP = EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER \ |
513 | or EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
521 | or EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
514 | 522 | ||
515 | ; ext4 features not support for write. |
523 | ; ext4 features not support for write. |
516 | EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \ |
524 | EXT4_FEATURE_INCOMPAT_W_NOT_SUPP = EXT4_FEATURE_INCOMPAT_EXTENTS \ |
517 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
525 | or EXT4_FEATURE_INCOMPAT_FLEX_BG |
518 | 526 | ||
519 | ; Flags specified in i_flags. |
527 | ; Flags specified in i_flags. |
520 | EXT2_EXTENTS_FL = 0x00080000 ; Extents. |
528 | EXT2_EXTENTS_FL = 0x00080000 ; Extents. |
521 | 529 | ||
522 | struct EXT2_INODE_STRUC |
530 | struct EXT2_INODE_STRUC |
523 | i_mode dw ? |
531 | i_mode dw ? |
524 | i_uid dw ? |
532 | i_uid dw ? |
525 | i_size dd ? |
533 | i_size dd ? |
526 | i_atime dd ? |
534 | i_atime dd ? |
527 | i_ctime dd ? |
535 | i_ctime dd ? |
528 | i_mtime dd ? |
536 | i_mtime dd ? |
529 | i_dtime dd ? |
537 | i_dtime dd ? |
530 | i_gid dw ? |
538 | i_gid dw ? |
531 | i_links_count dw ? |
539 | i_links_count dw ? |
532 | i_blocks dd ? |
540 | i_blocks dd ? |
533 | i_flags dd ? |
541 | i_flags dd ? |
534 | i_osd1 dd ? |
542 | i_osd1 dd ? |
535 | i_block rd 15 |
543 | i_block rd 15 |
536 | i_generation dd ? |
544 | i_generation dd ? |
537 | i_file_acl dd ? |
545 | i_file_acl dd ? |
538 | i_dir_acl dd ? |
546 | i_dir_acl dd ? |
539 | i_faddr dd ? |
547 | i_faddr dd ? |
540 | i_osd2 dd ? ; 12 bytes. |
548 | i_osd2 dd ? ; 12 bytes. |
541 | ends |
549 | ends |
542 | 550 | ||
543 | struct EXT2_DIR_STRUC |
551 | struct EXT2_DIR_STRUC |
544 | inode dd ? |
552 | inode dd ? |
545 | rec_len dw ? |
553 | rec_len dw ? |
546 | name_len db ? |
554 | name_len db ? |
547 | file_type db ? |
555 | file_type db ? |
548 | name db ? ; 255 (max) bytes. |
556 | name db ? ; 255 (max) bytes. |
549 | ends |
557 | ends |
550 | 558 | ||
551 | struct EXT2_BLOCK_GROUP_DESC |
559 | struct EXT2_BLOCK_GROUP_DESC |
552 | block_bitmap dd ? ; +0 |
560 | block_bitmap dd ? ; +0 |
553 | inode_bitmap dd ? ; +4 |
561 | inode_bitmap dd ? ; +4 |
554 | inode_table dd ? ; +8 |
562 | inode_table dd ? ; +8 |
555 | free_blocks_count dw ? ; +12 |
563 | free_blocks_count dw ? ; +12 |
556 | free_inodes_count dw ? ; +14 |
564 | free_inodes_count dw ? ; +14 |
557 | used_dirs_count dw ? ; +16 |
565 | used_dirs_count dw ? ; +16 |
558 | pad dw ? ; +18 |
566 | pad dw ? ; +18 |
559 | reserved rb 12 ; +20 |
567 | reserved rb 12 ; +20 |
560 | ends |
568 | ends |
561 | 569 | ||
562 | struct EXT2_SB_STRUC |
570 | struct EXT2_SB_STRUC |
563 | inodes_count dd ? ; +0 |
571 | inodes_count dd ? ; +0 |
564 | blocks_count dd ? ; +4 |
572 | blocks_count dd ? ; +4 |
565 | r_block_count dd ? ; +8 |
573 | r_block_count dd ? ; +8 |
566 | free_block_count dd ? ; +12 |
574 | free_block_count dd ? ; +12 |
567 | free_inodes_count dd ? ; +16 |
575 | free_inodes_count dd ? ; +16 |
568 | first_data_block dd ? ; +20 |
576 | first_data_block dd ? ; +20 |
569 | log_block_size dd ? ; +24 |
577 | log_block_size dd ? ; +24 |
570 | log_frag_size dd ? ; +28 |
578 | log_frag_size dd ? ; +28 |
571 | blocks_per_group dd ? ; +32 |
579 | blocks_per_group dd ? ; +32 |
572 | frags_per_group dd ? ; +36 |
580 | frags_per_group dd ? ; +36 |
573 | inodes_per_group dd ? ; +40 |
581 | inodes_per_group dd ? ; +40 |
574 | mtime dd ? ; +44 |
582 | mtime dd ? ; +44 |
575 | wtime dd ? ; +48 |
583 | wtime dd ? ; +48 |
576 | mnt_count dw ? ; +52 |
584 | mnt_count dw ? ; +52 |
577 | max_mnt_count dw ? ; +54 |
585 | max_mnt_count dw ? ; +54 |
578 | magic dw ? ; +56 |
586 | magic dw ? ; +56 |
579 | state dw ? ; +58 |
587 | state dw ? ; +58 |
580 | errors dw ? ; +60 |
588 | errors dw ? ; +60 |
581 | minor_rev_level dw ? ; +62 |
589 | minor_rev_level dw ? ; +62 |
582 | lastcheck dd ? ; +64 |
590 | lastcheck dd ? ; +64 |
583 | check_intervals dd ? ; +68 |
591 | check_intervals dd ? ; +68 |
584 | creator_os dd ? ; +72 |
592 | creator_os dd ? ; +72 |
585 | rev_level dd ? ; +76 |
593 | rev_level dd ? ; +76 |
586 | def_resuid dw ? ; +80 |
594 | def_resuid dw ? ; +80 |
587 | def_resgid dw ? ; +82 |
595 | def_resgid dw ? ; +82 |
588 | first_ino dd ? ; +84 |
596 | first_ino dd ? ; +84 |
589 | inode_size dw ? ; +88 |
597 | inode_size dw ? ; +88 |
590 | block_group_nr dw ? ; +90 |
598 | block_group_nr dw ? ; +90 |
591 | feature_compat dd ? ; +92 |
599 | feature_compat dd ? ; +92 |
592 | feature_incompat dd ? ; +96 |
600 | feature_incompat dd ? ; +96 |
593 | feature_ro_compat dd ? ; +100 |
601 | feature_ro_compat dd ? ; +100 |
594 | uuid rb 16 ; +104 |
602 | uuid rb 16 ; +104 |
595 | volume_name rb 16 ; +120 |
603 | volume_name rb 16 ; +120 |
596 | last_mounted rb 64 ; +136 |
604 | last_mounted rb 64 ; +136 |
597 | algo_bitmap dd ? ; +200 |
605 | algo_bitmap dd ? ; +200 |
598 | prealloc_blocks db ? ; +204 |
606 | prealloc_blocks db ? ; +204 |
599 | preallock_dir_blocks db ? ; +205 |
607 | preallock_dir_blocks db ? ; +205 |
600 | reserved_gdt_blocks dw ? ; +206 |
608 | reserved_gdt_blocks dw ? ; +206 |
601 | journal_uuid rb 16 ; +208 |
609 | journal_uuid rb 16 ; +208 |
602 | journal_inum dd ? ; +224 |
610 | journal_inum dd ? ; +224 |
603 | journal_dev dd ? ; +228 |
611 | journal_dev dd ? ; +228 |
604 | last_orphan dd ? ; +232 |
612 | last_orphan dd ? ; +232 |
605 | hash_seed rd 4 ; +236 |
613 | hash_seed rd 4 ; +236 |
606 | def_hash_version db ? ; +252 |
614 | def_hash_version db ? ; +252 |
607 | reserved rb 3 ; +253 (reserved) |
615 | reserved rb 3 ; +253 (reserved) |
608 | default_mount_options dd ? ; +256 |
616 | default_mount_options dd ? ; +256 |
609 | first_meta_bg dd ? ; +260 |
617 | first_meta_bg dd ? ; +260 |
610 | mkfs_time dd ? ; +264 |
618 | mkfs_time dd ? ; +264 |
611 | jnl_blocks rd 17 ; +268 |
619 | jnl_blocks rd 17 ; +268 |
612 | blocks_count_hi dd ? ; +336 |
620 | blocks_count_hi dd ? ; +336 |
613 | r_blocks_count_hi dd ? ; +340 |
621 | r_blocks_count_hi dd ? ; +340 |
614 | free_blocks_count_hi dd ? ; +344 |
622 | free_blocks_count_hi dd ? ; +344 |
615 | min_extra_isize dw ? ; +348 |
623 | min_extra_isize dw ? ; +348 |
616 | want_extra_isize dw ? ; +350 |
624 | want_extra_isize dw ? ; +350 |
617 | flags dd ? ; +352 |
625 | flags dd ? ; +352 |
618 | raid_stride dw ? ; +356 |
626 | raid_stride dw ? ; +356 |
619 | mmp_interval dw ? ; +358 |
627 | mmp_interval dw ? ; +358 |
620 | mmp_block dq ? ; +360 |
628 | mmp_block dq ? ; +360 |
621 | raid_stripe_width dd ? ; +368 |
629 | raid_stripe_width dd ? ; +368 |
622 | log_groups_per_flex db ? ; +372 |
630 | log_groups_per_flex db ? ; +372 |
623 | ends |
631 | ends |
624 | 632 | ||
625 | ; Header block extents. |
633 | ; Header block extents. |
626 | struct EXT4_EXTENT_HEADER |
634 | struct EXT4_EXTENT_HEADER |
627 | eh_magic dw ? ; Magic value of 0xF30A, for ext4. |
635 | eh_magic dw ? ; Magic value of 0xF30A, for ext4. |
628 | eh_entries dw ? ; Number of blocks covered by the extent. |
636 | eh_entries dw ? ; Number of blocks covered by the extent. |
629 | eh_max dw ? ; Capacity of entries. |
637 | eh_max dw ? ; Capacity of entries. |
630 | eh_depth dw ? ; Tree depth (if 0, extents in the array are not extent indexes) |
638 | eh_depth dw ? ; Tree depth (if 0, extents in the array are not extent indexes) |
631 | eh_generation dd ? ; ??? |
639 | eh_generation dd ? ; ??? |
632 | ends |
640 | ends |
633 | 641 | ||
634 | ; Extent. |
642 | ; Extent. |
635 | struct EXT4_EXTENT |
643 | struct EXT4_EXTENT |
636 | ee_block dd ? ; First logical block extent covers. |
644 | ee_block dd ? ; First logical block extent covers. |
637 | ee_len dw ? ; Number of blocks covered by extent. |
645 | ee_len dw ? ; Number of blocks covered by extent. |
638 | ee_start_hi dw ? ; Upper 16 bits of 48-bit address (unused in KOS) |
646 | ee_start_hi dw ? ; Upper 16 bits of 48-bit address (unused in KOS) |
639 | ee_start_lo dd ? ; Lower 32 bits of 48-bit address. |
647 | ee_start_lo dd ? ; Lower 32 bits of 48-bit address. |
640 | ends |
648 | ends |
641 | 649 | ||
642 | ; Index on-disk structure; pointer to block of extents/indexes. |
650 | ; Index on-disk structure; pointer to block of extents/indexes. |
643 | struct EXT4_EXTENT_IDX |
651 | struct EXT4_EXTENT_IDX |
644 | ei_block dd ? ; Covers logical blocks from here. |
652 | ei_block dd ? ; Covers logical blocks from here. |
645 | ei_leaf_lo dd ? ; Lower 32-bits of pointer to the physical block of the next level. |
653 | ei_leaf_lo dd ? ; Lower 32-bits of pointer to the physical block of the next level. |
646 | ei_leaf_hi dw ? ; Higher 16-bits (unused in KOS). |
654 | ei_leaf_hi dw ? ; Higher 16-bits (unused in KOS). |
647 | ei_unused dw ? ; Reserved. |
655 | ei_unused dw ? ; Reserved. |
648 | ends |
656 | ends |