]> wirehaze git hosting - BOS.git/blob - kernel/fat12/fat12.asm

wirehaze git hosting

new indentation style
[BOS.git] / kernel / fat12 / fat12.asm
1 ;----------------------------------------------------------;
2 ; BOS kernel Christoffer Bubach, 2012-2015. ;
3 ;----------------------------------------------------------;
4 ; ;
5 ; FAT12 driver. ;
6 ; ;
7 ;----------------------------------------------------------;
8
9 ;---------------------------------------------;
10 ; FAT12 calltable and structure pointer ;
11 ;---------------------------------------------;
12 FAT12:
13 .data_pointer dd 0 ; internal driver data
14 .FSname db 'FAT12' ; 5 char filesystem name
15 .init dd init_fat12 ; pointer to init
16 .deinit dd 0 ; remove driver
17 .format dd 0 ; format drive
18 .mount dd 0 ; mount drive
19 .unmount dd 0 ; unmount drive
20 .find dd 0 ; find file
21 .findnext dd 0 ; get next match
22 .open dd 0 ; open file, get handle
23 .close dd 0 ; close file from handle
24 .attrib dd 0 ; get/set attrib. and time
25 .read dd 0 ; read file from handle
26 .write dd 0 ; write file from handle
27 .seek dd 0 ; seek from handle
28 .rename dd 0 ; rename file
29 .remove dd 0 ; remove file/dir
30 .create dd 0 ; create file/dir
31 .ioctl dd 0 ; extra calls if exists
32
33 ;---------------------------------------------;
34 ; FAT12 main info structure ;
35 ;---------------------------------------------;
36 struc fat12_data
37 {
38 .disk_number db 0 ; which VFS disk number
39 .root_dir dw 0 ; position of rootdir
40 .disk_size dd 0 ; total storage size
41 .free_space dd 0 ; free space available
42 .fat_1 dd 0 ; position of fat1
43 .fat_2 dd 0 ; position of fat2
44 .data_area dw 0 ; position of dataarea
45 .boot: times sizeof.bootsector db 0 ; copy of FAT12 bootsector
46 .dir_entries:
47 times 16 * sizeof.dir_entry db 0 ; 512b dir entry buffer
48 .fat_buffer: times 512 db 0 ; 512b FAT cluster info buffer
49 .foundfile:
50 times 1 * sizeof.search db 0 ; "DTA" like structure
51 .filehandles: ; "System File Table"
52 times 32 * sizeof.filehandle db 0 ; for now, max opened files is 32
53 }
54
55 virtual at 0 ; could use "at esi" instead
56 fat12_data fat12_data
57 sizeof.fat12_data = $-$$
58 end virtual
59
60 ;---------------------------------------------;
61 ; FAT12 bootsector structure ;
62 ;---------------------------------------------;
63 struc bootsector ; 512 bytes
64 {
65 .jumper db 0,0,0
66 .oem db 0,0,0,0,0,0,0,0
67 .sectorsize dw 0
68 .sect_per_clust db 0
69 .reserved_sect dw 0 ; reserved sectors, 1 for bootsector.
70 .fats_per_drive db 0
71 .root_entries dw 0
72 .small_sectors dw 0 ; total sectors on small disk
73 .media_describtor db 0 ; 240 / 0xF0 = 1.44MB, 3.5"
74 .sectors_per_fat dw 0 ; 9 on 1.44MB, 3,5"
75 .sect_per_track dw 0 ; 18 on 1.44MB, 3,5"
76 .heads dw 0 ; 2 on 1.44MB, 3,5"
77 .hidden_sectors dd 0 ; sectors before bootsector
78 .large_sectors dd 0 ; total sectors if large disk
79 .drive_no db 0
80 .reserved_field db 0
81 .bpb_signature db 0 ; 41=3 more (win NT req.), 0=end.
82 .disk_id dd 0 ; random ident number on format.
83 .volume_label db 0,0,0,0,0,0,0,0,0,0,0
84 .filesystem db 0,0,0,0,0,0,0,0 ; "FAT12 " or "FAT16 "
85 .code: times 448 db 0
86 .boot_signature db 0,0 ; 0x55,0xAA
87 }
88
89 virtual at 0
90 bootsector bootsector
91 sizeof.bootsector = $-$$
92 end virtual
93
94 ;---------------------------------------------;
95 ; FAT12 directory entry structure ;
96 ;---------------------------------------------;
97 struc dir_entry
98 {
99 .filename db 0,0,0,0,0,0,0,0
100 .extension db 0,0,0
101 .attributes db 0 ; 0x10 = dir for example.
102 .reserved db 0,0,0,0,0,0,0,0,0,0
103 .changed_time dw 0
104 .changed_date dw 0
105 .start_cluster dw 0
106 .filesize dd 0
107 }
108
109 virtual at 0
110 dir_entry dir_entry
111 sizeof.dir_entry = $-$$
112 end virtual
113
114 ;---------------------------------------------;
115 ; FAT12 directory entry for LFN ;
116 ;---------------------------------------------;
117 struc lfn_entry
118 {
119 .order db 0 ; LFN entry in sequence, never 0x00 or 0xE5.
120 .namefirst dw 0,0,0,0,0 ; 5 first unicode (2byte) chars
121 .attribute db 0 ; 0x0F for Long File Name identification.
122 .reserved db 0
123 .checksum db 0 ; 8.3 name checksum
124 .namemiddle dw 0,0,0,0,0,0 ; middle 6 unicode (2byte) chars
125 .zero_cluster dw 0 ; always zero on LNF entries
126 .namelast dw 0,0 ; last 2 unicode (2byte) characters.
127 }
128
129 virtual at 0
130 lfn_entry lfn_entry
131 sizeof.lfn_entry = $-$$
132 end virtual
133
134 ;---------------------------------------------;
135 ; FAT12 file search/DTA structure ;
136 ;---------------------------------------------;
137 struc search
138 {
139 .searchname:
140 times 255 db 0 ; file search pattern.
141 .attribute db 0 ; search attribute.
142 .direntry dw 0 ; directory entry number, 0 based
143 .dircluster dw 0 ; starting cluster of dir, 0 root
144 .foundattrib db 0 ; attribute of matching file
145 .foundtime dw 0 ; file time
146 .founddate dw 0 ; file date
147 .foundsize dw 0 ; file size
148 }
149
150 virtual at 0
151 search search
152 sizeof.search = $-$$
153 end virtual
154
155 ;---------------------------------------------;
156 ; FAT12 file-handle structure ;
157 ;---------------------------------------------;
158 struc filehandle
159 {
160 .handles db 0 ; reference count or or zero for unused
161 .mode db 0 ; open mode. 0=read, 1=write, 2=r/w.
162 .lfn_entry dw 0 ; file LFN directory entry position
163 .direntry dw 0 ; file directory entry position
164 .cluster dw 0 ; file first cluster
165 .attribute db 0 ; file attributes
166 .filetime dw 0 ; last modified time
167 .filedate dw 0 ; last modified date
168 .filesize dd 0 ; filesize
169 .position dd 0 ; R/W position in file
170 .clusterpos dw 0 ; cluster number of last cluster read
171 .shortname:
172 times 11 db 0 ; short name
173 .fullname:
174 times 255 db 0 ; the full LFN
175 }
176
177 virtual at 0
178 filehandle filehandle
179 sizeof.filehandle = $-$$
180 end virtual
181
182 ;------------------------------------------;
183 ; FAT cluster constants used ;
184 ;------------------------------------------;
185 cluster_free = 0x000 ; up for grabs.
186 cluster_reserved = 0xFF0 ; 0xFF0-0xFF6. 0xFF7=bad.
187 cluster_last = 0xFF8 ; 0xFF8-0xFFF last cluster.
188
189 ;------------------------------------------;
190 ; Directory entry first char constants ;
191 ;------------------------------------------;
192 entry_free = 0xE5 ; up for grabs.
193 entry_last = 0x00 ; this and remaining is free
194 entry_japan_kludge = 0x0E ; should be outputed as 0xE5.
195 entry_dot = 0x2E ; ASCII dot, check for "." or ".." dirs
196
197 ;------------------------------------------;
198 ; Directory entry attribute masks ;
199 ;------------------------------------------;
200 mask_readonly = 0x01
201 mask_hidden = 0x02
202 mask_system = 0x04
203 mask_volume_label = 0x08
204 mask_subdirectory = 0x10
205 mask_archive = 0x20
206
207 ;------------------------------------------;
208 ; Long File Name entry constants ;
209 ;------------------------------------------;
210 lfn_last_entry_mask = 0x40 ; LFN sequence-order mask for last
211 attribute_lfn = 0x0F ; attrb. byte value for LFN dir entry
212
213
214 ;--------------------------------------------------------------;
215 ; init_fat12 - detect if drive fs is fat12 and init ;
216 ;--------------------------------------------------------------;
217 ; ;
218 ; in: reg = pointer to VFS drive info ;
219 ; ;
220 ; out: reg = pointer to struct(s) if FAT12 found ;
221 ; ;
222 ;--------------------------------------------------------------;
223 init_fat12:
224 push eax
225 ;...
226
227 ;-----------------------------;
228 ; calculate root location ;
229 ;-----------------------------;
230 xor eax, eax
231 mov al, byte [fd0.boot.fats_per_drive]
232 mul word [fd0.boot.sectors_per_fat]
233 add ax, word [fd0.boot.reserved_sect]
234 mov [fd0.root_dir], ax
235
236 ; working with
237 ;mov si, [drive]
238 ;mov ax, [si+fat12.boot.sectorssize]
239
240 ; a bit more code here
241 pop eax
242 ret
243
244 ;--------------------------------------------------------------;
245 ; calc_lfn_chksum - get long file name checksum ;
246 ;--------------------------------------------------------------;
247 ; ;
248 ; in: esi = pointer to 11 byte 8.3 filename ;
249 ; ;
250 ; out: ax = checksum ;
251 ; ;
252 ;--------------------------------------------------------------;
253 calc_lfn_chksum:
254 push cx
255 push esi
256
257 mov cx, 11
258 xor ax, ax ; return value start with null
259 .l1:
260 push cx
261 movzx cx, byte [esi] ; add next char to sum
262 add ax, cx
263 pop cx
264 shr ax, 1 ; shift sum right by 1
265 inc esi ; prepare for next character
266 loop .l1
267
268 pop esi
269 pop cx
270 ret
271
272 ;--------------------------------------------------------------;
273 ; get_dir_entry - get a directory entry or amount ;
274 ;--------------------------------------------------------------;
275 ; ;
276 ; in: esi = pointer to prev dir entry or 0 for root ;
277 ; cx = entry no. to extract or 0 for none ;
278 ; ;
279 ; out: cx = number of entries or unchanged if set ;
280 ; edi = pointer to dir entry or unchanged if cx=0 ;
281 ;--------------------------------------------------------------;
282 get_dir_entry:
283 ;......
284 ret
285
286 ;--------------------------------------------------------------;
287 ; get_fat_entry - get a fat entry/cluster number ;
288 ;--------------------------------------------------------------;
289 ; ;
290 ; in: cx = fat entry/cluster number ;
291 ; ;
292 ; out: cx = next fat entry/cluster no. or 0 if none ;
293 ;--------------------------------------------------------------;
294 get_fat_entry:
295 ;...
296 ret
297
298 ;--------------------------------------------------------------;
299 ; get_cluster - get a cluster ;
300 ;--------------------------------------------------------------;
301 ; ;
302 ; in: cx = fat entry/cluster number ;
303 ; ;
304 ; out: edi = pointer to cluster or zero if none ;
305 ;--------------------------------------------------------------;
306 get_cluster:
307 ;...
308 ret