source: trunk/BOOTCODE/SPECIAL/FAT16.ASM@ 32

Last change on this file since 32 was 30, checked in by Ben Rietbroek, 15 years ago

AiR-BOOT v1.07 -- As released with eCS v2.1. [2011-05-06]
Signature-date: 2006-03-13. (incorrect)
Trunk contains buildable v1.07 version as distributed with eCS v2.1.
Directory 'tags' contains v1.06 & v1.07 reference versions
built for all languages. Note that language ID for 'Dutch' changed
from 'DT' to 'NL' in v1.07 and that the v1.06 reference version also
uses 'NL' for 'Dutch'.
Also note that helper programs like the installer and setaboot are
are only modified for the OS/2 versions in v1.07.
The signature-date for v1.07 incorrectly states the same
date as for v1.06. The signature-version is correct.
Removed other binaries. (cd-rom images, old releases, etc.)
The tags serve as reference versions:

  • v1.06: rebuilt from source. (tags/v1.06r)
  • v1.07: built as released with eCS v2.1. (tags/v1.07r)
File size: 12.3 KB
Line 
1; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2;
3; This file is part of AiR-BOOT
4;
5; AiR-BOOT is free software: you can redistribute it and/or modify it under
6; the terms of the GNU General Public License as published by the Free
7; Software Foundation, either version 3 of the License, or (at your option)
8; any later version.
9;
10; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11; WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13; details.
14;
15; You should have received a copy of the GNU General Public License along with
16; AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17;
18;---------------------------------------------------------------------------
19; AiR-BOOT / FAT-16 SUPPORT
20;---------------------------------------------------------------------------
21
22IFDEF ModuleNames
23DB 'FAT16',0
24ENDIF
25
26; Here is access code for accessing FAT-16 partitions. It's not a complete
27; File-API and only for simple readonly-access.
28; It's currently only used by SPECIAL\LINUX.ASM for Linux Kernel Loading.
29;
30; Note: This code will ONLY WORK on computers with INT 13h Extension.
31; I did not want to code silly cylinder stuff here. I have also used
32; i386 code in here, because Linux requires so as well. Please note that
33; I don't use i386 code anywhere (!) else in AiR-BOOT. ; Rousseau: yes you did, movezx is 386-only :-)
34; ; Replaced by 286 instructions.
35; Initialize FAT-16 access on specified partition (required for following xs)
36; In: DS:SI - IPT-Entry that contains a FAT-16 partition
37; Out: None
38; Destroyed: None
39FAT16_InitAccess Proc Near Uses eax bx edx
40 mov al, bptr ds:[si+LocIPT_Drive]
41 mov FAT16_Drive, al
42 mov edx, dptr ds:[si+LocIPT_AbsoluteBegin]
43 mov FAT16_AbsPartitionBegin, edx
44 mov DriveIO_DAP_Absolute, edx ; Read in Boot-Record of partition
45 mov DriveIO_DAP_NumBlocks, 1 ; 1 Sector to load
46 mov FAT16_FATCacheSector, 255 ; Sector 255 - So nothing cached
47 mov ax, ds
48 shl eax, 16
49 mov ax, offset FAT16_FATCache
50 mov DriveIO_DAP_Transfer, eax ; Transfer to FAT-Cache Area
51 call FAT16_LoadSectors
52 mov al, bptr [FAT16_FATCache+13]
53 mov FAT16_SecsPerCluster, al
54 movzx eax, wptr [FAT16_FATCache+14] ; +14 -> ReservedSectors
55 add edx, eax ; EDX = AbsPartitionPos+ReservedSectors
56 mov FAT16_AbsFATBegin, edx ; Is Absolute-FAT-Begin
57 movzx ax, bptr [FAT16_FATCache+16] ; +16 -> FAT-Copies Count
58 mov bx, wptr [FAT16_FATCache+22] ; +22 -> Sectors Per FAT
59 mov FAT16_SecsPerFAT, bx
60 push dx
61 mul bx
62 pop dx
63 movzx eax, ax
64 add edx, eax
65 mov FAT16_AbsRootBegin, edx ; Is Absolute-Root-Begin
66 movzx eax, wptr [FAT16_FATCache+17] ; +17 -> Number of Root Entries
67 mov FAT16_NumOfRootEntries, ax
68 shr eax, 4 ; NumOfRootEntries/16
69 add edx, eax
70 mov FAT16_AbsClusterBegin, edx ; Is Absolute-Cluster-Begin
71 ret
72FAT16_InitAccess EndP
73
74; Reads Root-Entries to 9000:0 for further processing...
75; In: None
76; Out: None
77; Destroyed: None
78FAT16_ReadRoot Proc Near Uses eax
79 mov ax, 9000h
80 shl eax, 16 ; 9000:0 -> Space for Root
81 mov DriveIO_DAP_Transfer, eax ; Transfer to that segment
82 mov eax, FAT16_AbsRootBegin
83 mov DriveIO_DAP_Absolute, eax ; Read in Root-Entries...
84 mov ax, FAT16_NumOfRootEntries
85 shr ax, 4 ; NumOfRootEntries/16
86 mov DriveIO_DAP_NumBlocks, ax ; -> Sectors of Root-Entries
87 call FAT16_LoadSectors ; DONE.
88 ret
89FAT16_ReadRoot EndP
90
91; Searches a FAT16-File-Entry in specified memory block
92; In: CX - Total Count of File-Entries to search
93; SI - Offset, what to search for Segment CS (11-Byte block)
94; Out: DX - Cluster, where the data starts...
95; Destroyed: None
96FAT16_SearchEntry Proc Near Uses ax bx es di
97 xor dx, dx ; No Result as default
98 or cx, cx
99 jz FAT16SE_NoEntries
100 mov bx, cx
101 mov ax, 9000h
102 mov es, ax
103 xor di, di
104 FAT16SE_SearchLoop:
105 push si di
106 mov cx, 11
107 repe cmpsb ; Compare total 11-bytes
108 pop di si
109 je FAT16SE_EntryFound
110 add di, 32 ; Skip 1 FAT16-Entry now :)
111 dec bx
112 jnz FAT16SE_SearchLoop
113 FAT16SE_NoEntries:
114 ret
115
116 FAT16SE_EntryFound:
117 mov dx, wptr es:[di+26] ; Starting Cluster of Entry
118 ret
119FAT16_SearchEntry EndP
120
121; Reads a Cluster and gets Next-Cluster as well...
122; In: DX - Cluster-Number to load, DAP_Transfer-Offset filled out
123; ES - Segment, where to read Cluster to
124; DI - Offset, where to read Cluster to
125; Out: DX - Cluster that follows this one, [ES:DI] filled out
126; DI - Offset, adjusted
127; Destroyed: None
128FAT16_ReadCluster Proc Near Uses eax bx
129 push dx
130 ; First read Cluster into buffer...
131 mov ax, es
132 shl eax, 16
133 mov ax, di
134 mov DriveIO_DAP_Transfer, eax ; Read to 9000:DI
135 mov ax, dx
136 sub ax, 2 ; Everything starts at Cluster 2
137 ;movzx bx, FAT16_SecsPerCluster
138 mov bl,FAT16_SecsPerCluster
139 mov bh,0
140
141 mul bx
142 shl edx, 16
143 mov dx, ax ; EDX - Relative to Cluster-Start
144 add edx, FAT16_AbsClusterBegin ; EDX - Absolute Sector Count
145 mov DriveIO_DAP_Absolute, edx
146 mov DriveIO_DAP_NumBlocks, bx ; Get a whole cluster
147 call FAT16_LoadSectors ; DONE.
148 pop dx
149 ; Update DI to next position...
150 mov al, FAT16_SecsPerCluster
151 shl ax, 9
152 add di, ax
153 ; Finally, look for next Cluster following to this one...
154 ;movzx bx, dl
155 mov bl,dl
156 mov bh,0
157
158 shl bx, 1 ; BX - Offset within FAT-Table
159 shr dx, 8 ; DX - FAT-Sector
160 cmp dl, FAT16_FATCacheSector
161 je FAT16RC_GotFATsectorAlready
162 ; Load FAT-Sector, because the required one is not in Cache
163 mov FAT16_FATCacheSector, dl
164 mov ax, cs
165 shl eax, 16
166 mov ax, offset FAT16_FATCache
167 mov DriveIO_DAP_Transfer, eax ; Transfer to FAT-Cache Area
168 movzx edx, dx
169 mov eax, FAT16_AbsFATBegin
170 add eax, edx
171 mov DriveIO_DAP_Absolute, eax ; Read in Boot-Record of partition
172 mov DriveIO_DAP_NumBlocks, 1 ; 1 Sector to load
173 call FAT16_LoadSectors ; DONE.
174 FAT16RC_GotFATsectorAlready:
175 mov dx, wptr cs:[FAT16_FATCache+bx] ; Get Next-Cluster Pointer
176 ret
177FAT16_ReadCluster EndP
178
179; Preserves all registers, help routine for LoadKernel
180; supports more than 1 sector read (unlike MBR_IO_LoadSector)
181FAT16_LoadSectors Proc Near Uses eax dx ds si
182 push cs
183 pop ds
184 mov si, offset DriveIO_DAP
185 mov dl, ds:[FAT16_Drive]
186 mov ah, 42h ; Extended Read
187 int 13h
188 jnc FAT16LS_Success
189 call MBR_LoadError
190
191 FAT16LS_Success:
192 movzx eax, wptr ds:[DriveIO_DAP_NumBlocks]
193 add dptr ds:[DriveIO_DAP_Absolute+0], eax ; Adjust Absolute Offset
194 ret
195FAT16_LoadSectors EndP
196
197; Will Pre-Process Directory loaded to 9000:0, remove directory and VFAT
198; entries for display purpose in window
199; In: DI - Ending-Offset of Directory
200; ES == CS
201; Out: None
202; Destroyed: None
203FAT16_ProcessKrnlDirectory Proc Near Uses ds si es di
204 mov dx, di ; DX - Ending-Offset of Directory
205 mov ax, 9000h
206 mov ds, ax ; DS == 9000h
207 xor si, si ; SI - Current Pos in Directory
208 mov di, offset LINUX_KernelEntries ; DI - Array of Kernel-Entries
209 mov cs:[LINUX_KernelNo], 0
210 FAT16PPD_DirectoryLoop:
211 mov al, ds:[si] ; +0 -> First char of Basename
212 or al, al
213 jz FAT16PPD_IgnoreEntry ; == 0, empty
214 cmp al, 0E5h
215 je FAT16PPD_IgnoreEntry ; == E5, deleted
216 mov al, ds:[si+11] ; +11 -> Flags of Entry
217 cmp al, 0Fh ; 0F as flags -> VFAT Entry
218 je FAT16PPD_IgnoreEntry
219 test al, 18h ; Bit 4 -> Directory
220 jnz FAT16PPD_IgnoreEntry ; Bit 3 -> Volume
221
222 ; Set Size-Entry in KernelSizeTable
223 push ds si di
224 mov bx, ds:[si+30]
225 mov ax, ds:[si+28] ; BX:AX - Size of file in Bytes
226
227 mov dx, bx
228 and dx, 511 ; My crazy way of dividing a 32-bit
229 shr ax, 9 ; value through 512 using 16-bit
230 shr bx, 9 ; instructions... :)
231 shl dx, 7 ; (dont ever ever use a DIV)
232 or ax, dx ; BX:AX - Size of file in 512-blocks
233
234 push cs
235 pop ds ; DS==CS for GetSizeElementPtr
236 push ax
237 mov ax, di
238 call PART_GetSizeElementPointer ; SI - Pointer to Size Element
239 pop ax
240 mov di, si
241 call PART_FillOutSizeElement ; BX:AX -> ES:DI (Size Element)
242 pop di si ds
243
244 ; Copy entry and make append extension to basename
245 ; "TEST TMP" -> "TESTTMP "
246 mov bx, 7
247 FAT16PPD_GetLenOfBasename:
248 cmp bptr ds:[si+bx], ' '
249 jne FAT16PPD_EndOfBasename
250 dec bx
251 jnz FAT16PPD_GetLenOfBasename
252 FAT16PPD_EndOfBasename:
253 mov ah, bl
254 inc ah ; AH - Count of Basename Chars (max 8)
255 mov bx, 10
256 FAT16PPD_GetLenOfExtension:
257 cmp bptr ds:[si+bx], ' '
258 jne FAT16PPD_EndOfExtension
259 dec bl
260 cmp bl, 7
261 ja FAT16PPD_GetLenOfExtension
262 FAT16PPD_EndOfExtension:
263 sub bl, 7 ; BL - Count of Extension Chars (max 3)
264 ; Now we will copy&fill out 11 characters (Basename&Extension)
265 push dx
266 push ax
267 xor eax, eax
268 stosd ; +0 [DWORD] Empty Serial
269 pop ax
270 mov dx, si
271 ;movzx cx, ah
272 mov cl,ah
273 mov ch,0
274
275 rep movsb
276 mov si, dx ; Restore SI
277 add si, 8
278 or bl, bl
279 jz FAT16PPD_NoExtensionCopy
280 mov cl, bl
281 rep movsb
282 FAT16PPD_NoExtensionCopy:
283 add ah, bl ; AH - Total Bytes of BaseName
284 mov cl, 11
285 mov al, ' '
286 sub cl, ah
287 jz FAT16PPD_NoFillUpName
288 rep stosb ; +4 [STR*11] Label
289 FAT16PPD_NoFillUpName:
290 mov si, dx ; Restore SI
291
292 mov al, FAT16_Drive
293 mov ah, 0FDh
294 stosw ; +15 [BYTE/BYTE] Drive, SystemID
295 xor ax, ax
296 stosb ; +17 [BYTE] Flags
297 stosw ; +18 [WORD] CRC
298 mov ax, wptr ds:[si+26] ; Starting Cluster of File
299 stosw
300 xor ax, ax
301 stosb ; +20 [BYTE/BYTE/BYTE] Location Begin
302 stosw
303 stosb ; +23 [BYTE/BYTE/BYTE] Location Part
304 mov cx, 4
305 rep stosw ; +26 [DWORD/DWORD] Abs Locations
306 pop dx
307 inc cs:[LINUX_KernelNo]
308 FAT16PPD_IgnoreEntry:
309 add si, 32
310 cmp si, dx ; We are at Ending-Offset ?
311 jb FAT16PPD_DirectoryLoop
312 ; Done, now we got a maximum of 20 kernels in LINUX_KernelEntries-Array.
313 ret
314FAT16_ProcessKrnlDirectory EndP
Note: See TracBrowser for help on using the repository browser.