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

Last change on this file since 54 was 51, checked in by Ben Rietbroek, 12 years ago

AiR-BOOT v1.0.8-rc3 build-20120909 [2012-09-10]

With Git one can easily hop-skip-and-jump between branches.
So I use Git for my local repos and make use of this easy branching.
Because SVN can only handle lineair history, these branches had to be
rebased before committing them to Netlabs. So, this commit contains a
multitude of changes which makes it a bit hairy.

New

o Display LVM drive-letters in the main menu

A populair request was to show drive-letter information in the menu.
Drive-letters however, are OS specific and AiR-BOOT cannot
accurately predict what drive-letter other operating systems would
assign to what partition. eCS LVM drive-letters however are stored
in the LVM-record and can thus be displayed.

o Added 'Show LVM Drive Letters' option in SETUP/BASIC

This will toggle the display of LVM drive-letters in the main menu.
By default this option is enabled.

o Show popup message when BIOS INT13X extensions are not available

The system is halted.

o Show 'DEL to Power Off' in the bottom left corner

This tries to power-off the system, but it may not work for you.

o Simple interactive debugger

Outputs to the serial port with a few one-letter commands to dump
internal tables and state. (Only available in debug builds)

o Enhanced drive-letter feature

Enable multiple eCS installations using the same drive-letter.
This makes it possible to clone a system with the command
'XCOPY /h /o /t /s /e /r /v /e' to another drive and have that boot
from the same drive-letter.
(Or installing to the same drive by hiding the other system)

Changes

o Reduced MBR protection-image from 1024 to 768 bytes

Luckily the MBR Protection Image code does not exceed 768 bytes,
so that gives us another 256 bytes of precious code-space.
Now the non-EN versions are happy again.
Note that the alignment for the image changed from 512 to 256 bytes.
MBR-PROT.ASM, FIXCODE.C, PARTMAIN.ASM and AIR-BOOT.ASM have been
adjusted for this change.
The fight for code-space continues...

o Updating from v1.06 now also copies over drive-letters

When the user has forced drive-letters in v1.06 these will be copied
over to the v1.0.8 configuration when upgrading.
Because the drive-letter feature is broken in v1.07,
the drive-letter table does not get copied over when upgrading
from v1.07.

o Made FX-code optional to compile in

The FX-code supplies the shifting screen-effects when 'Cooper Bars'
is enabled in the setup. With the current enhancements made however,
there is a continuous lack of code-space, especially when debug-code
is included during development. The FX-code occupies some
1200 bytes, a space that can be put to better use. Therefore the
inclusion of the FX-code has been made conditional to make room for
either debugging or future new features.

o Also rewrite PBR on HPFS

Earlier, a fix was made to write a modified PBR back in case JFS was
used. This was done to enable the drive-letter feature on JFS, since
the PBR JFS-bootcode does not use the supplied PBR in memory.
With the enhancements in the drive-letter feature, the HPFS PBR
needs to be updated on disk also, to cope with zero drive-letters in
the HPFS PBR. This potentially fixes a missing drive-letter in the
PBR when the system is restored from an archive. You might need the
drive-letter feature to force the correct drive-letter on the first
boot, after which the feature can be disabled.

o Added extra MBR protection

When AiR-BOOT is active, it is only AiR-BOOT that writes to the MBR.
To protect the MBR from programming errors, like the one below,
any write to the MBR is now checked for validity.
In essence this is protecting your MBR from bad programming done
by me...

Fixes

o Fixed a minor bug with displaying LVM drive-letters

When more partitions that can be displayed were present, scrolling
the menu would not scroll the drive-letter. Fixed.

o Fixed a bug with regard to the drive-letter feature

When partitions were deleted, and some partitions above the deleted
partition(s) had a drive-letter forced, these partitions would lose
this assignment. This bug is also present in v1.06.

Note

The AIRBOOT.HIS file mentions a DOCU directory with the AiR-BOOT
documentation etc. However, this is not present in this commit and
will be provided at a later time.

File size: 12.4 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 MODULE_NAMES
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
106 push di
107 mov cx, 11
108 repe cmpsb ; Compare total 11-bytes
109 pop di
110 pop si
111 je FAT16SE_EntryFound
112 add di, 32 ; Skip 1 FAT16-Entry now :)
113 dec bx
114 jnz FAT16SE_SearchLoop
115 FAT16SE_NoEntries:
116 ret
117
118 FAT16SE_EntryFound:
119 mov dx, wptr es:[di+26] ; Starting Cluster of Entry
120 ret
121FAT16_SearchEntry EndP
122
123; Reads a Cluster and gets Next-Cluster as well...
124; In: DX - Cluster-Number to load, DAP_Transfer-Offset filled out
125; ES - Segment, where to read Cluster to
126; DI - Offset, where to read Cluster to
127; Out: DX - Cluster that follows this one, es:[DI] filled out
128; DI - Offset, adjusted
129; Destroyed: None
130FAT16_ReadCluster Proc Near Uses eax bx
131 push dx
132 ; First read Cluster into buffer...
133 mov ax, es
134 shl eax, 16
135 mov ax, di
136 mov DriveIO_DAP_Transfer, eax ; Read to 9000:DI
137 mov ax, dx
138 sub ax, 2 ; Everything starts at Cluster 2
139 ;movzx bx, FAT16_SecsPerCluster
140 mov bl,FAT16_SecsPerCluster
141 mov bh,0
142
143 mul bx
144 shl edx, 16
145 mov dx, ax ; EDX - Relative to Cluster-Start
146 add edx, FAT16_AbsClusterBegin ; EDX - Absolute Sector Count
147 mov DriveIO_DAP_Absolute, edx
148 mov DriveIO_DAP_NumBlocks, bx ; Get a whole cluster
149 call FAT16_LoadSectors ; DONE.
150 pop dx
151 ; Update DI to next position...
152 mov al, FAT16_SecsPerCluster
153 shl ax, 9
154 add di, ax
155 ; Finally, look for next Cluster following to this one...
156 ;movzx bx, dl
157 mov bl,dl
158 mov bh,0
159
160 shl bx, 1 ; BX - Offset within FAT-Table
161 shr dx, 8 ; DX - FAT-Sector
162 cmp dl, FAT16_FATCacheSector
163 je FAT16RC_GotFATsectorAlready
164 ; Load FAT-Sector, because the required one is not in Cache
165 mov FAT16_FATCacheSector, dl
166 mov ax, cs
167 shl eax, 16
168 mov ax, offset FAT16_FATCache
169 mov DriveIO_DAP_Transfer, eax ; Transfer to FAT-Cache Area
170 movzx edx, dx
171 mov eax, FAT16_AbsFATBegin
172 add eax, edx
173 mov DriveIO_DAP_Absolute, eax ; Read in Boot-Record of partition
174 mov DriveIO_DAP_NumBlocks, 1 ; 1 Sector to load
175 call FAT16_LoadSectors ; DONE.
176 FAT16RC_GotFATsectorAlready:
177 mov dx, wptr cs:[FAT16_FATCache+bx] ; Get Next-Cluster Pointer
178 ret
179FAT16_ReadCluster EndP
180
181; Preserves all registers, help routine for LoadKernel
182; supports more than 1 sector read (unlike MBR_IO_LoadSector)
183FAT16_LoadSectors Proc Near Uses eax dx ds si
184 push cs
185 pop ds
186 mov si, offset DriveIO_DAP
187 mov dl, ds:[FAT16_Drive]
188 mov ah, 42h ; Extended Read
189 int 13h
190 jnc FAT16LS_Success
191 call MBR_LoadError
192
193 FAT16LS_Success:
194 movzx eax, wptr ds:[DriveIO_DAP_NumBlocks]
195 add dptr ds:[DriveIO_DAP_Absolute+0], eax ; Adjust Absolute Offset
196 ret
197FAT16_LoadSectors EndP
198
199; Will Pre-Process Directory loaded to 9000:0, remove directory and VFAT
200; entries for display purpose in window
201; In: DI - Ending-Offset of Directory
202; ES == CS
203; Out: None
204; Destroyed: None
205FAT16_ProcessKrnlDirectory Proc Near Uses ds si es di
206 mov dx, di ; DX - Ending-Offset of Directory
207 mov ax, 9000h
208 mov ds, ax ; DS == 9000h
209 xor si, si ; SI - Current Pos in Directory
210 mov di, offset LINUX_KernelEntries ; DI - Array of Kernel-Entries
211 mov cs:[LINUX_KernelNo], 0
212 FAT16PPD_DirectoryLoop:
213 mov al, ds:[si] ; +0 -> First char of Basename
214 or al, al
215 jz FAT16PPD_IgnoreEntry ; == 0, empty
216 cmp al, 0E5h
217 je FAT16PPD_IgnoreEntry ; == E5, deleted
218 mov al, ds:[si+11] ; +11 -> Flags of Entry
219 cmp al, 0Fh ; 0F as flags -> VFAT Entry
220 je FAT16PPD_IgnoreEntry
221 test al, 18h ; Bit 4 -> Directory
222 jnz FAT16PPD_IgnoreEntry ; Bit 3 -> Volume
223
224 ; Set Size-Entry in KernelSizeTable
225 push ds
226 push si
227 push di
228 mov bx, ds:[si+30]
229 mov ax, ds:[si+28] ; BX:AX - Size of file in Bytes
230
231 mov dx, bx
232 and dx, 511 ; My crazy way of dividing a 32-bit
233 shr ax, 9 ; value through 512 using 16-bit
234 shr bx, 9 ; instructions... :)
235 shl dx, 7 ; (dont ever ever use a DIV)
236 or ax, dx ; BX:AX - Size of file in 512-blocks
237
238 push cs
239 pop ds ; DS==CS for GetSizeElementPtr
240 push ax
241 mov ax, di
242 call PART_GetSizeElementPointer ; SI - Pointer to Size Element
243 pop ax
244 mov di, si
245 call PART_FillOutSizeElement ; BX:AX -> ES:DI (Size Element)
246 pop di
247 pop si
248 pop ds
249
250 ; Copy entry and make append extension to basename
251 ; "TEST TMP" -> "TESTTMP "
252 mov bx, 7
253 FAT16PPD_GetLenOfBasename:
254 cmp bptr ds:[si+bx], ' '
255 jne FAT16PPD_EndOfBasename
256 dec bx
257 jnz FAT16PPD_GetLenOfBasename
258 FAT16PPD_EndOfBasename:
259 mov ah, bl
260 inc ah ; AH - Count of Basename Chars (max 8)
261 mov bx, 10
262 FAT16PPD_GetLenOfExtension:
263 cmp bptr ds:[si+bx], ' '
264 jne FAT16PPD_EndOfExtension
265 dec bl
266 cmp bl, 7
267 ja FAT16PPD_GetLenOfExtension
268 FAT16PPD_EndOfExtension:
269 sub bl, 7 ; BL - Count of Extension Chars (max 3)
270 ; Now we will copy&fill out 11 characters (Basename&Extension)
271 push dx
272 push ax
273 xor eax, eax
274 stosd ; +0 [DWORD] Empty Serial
275 pop ax
276 mov dx, si
277 ;movzx cx, ah
278 mov cl,ah
279 mov ch,0
280
281 rep movsb
282 mov si, dx ; Restore SI
283 add si, 8
284 or bl, bl
285 jz FAT16PPD_NoExtensionCopy
286 mov cl, bl
287 rep movsb
288 FAT16PPD_NoExtensionCopy:
289 add ah, bl ; AH - Total Bytes of BaseName
290 mov cl, 11
291 mov al, ' '
292 sub cl, ah
293 jz FAT16PPD_NoFillUpName
294 rep stosb ; +4 [STR*11] Label
295 FAT16PPD_NoFillUpName:
296 mov si, dx ; Restore SI
297
298 mov al, FAT16_Drive
299 mov ah, 0FDh
300 stosw ; +15 [BYTE/BYTE] Drive, SystemID
301 xor ax, ax
302 stosb ; +17 [BYTE] Flags
303 stosw ; +18 [WORD] CRC
304 mov ax, wptr ds:[si+26] ; Starting Cluster of File
305 stosw
306 xor ax, ax
307 stosb ; +20 [BYTE/BYTE/BYTE] Location Begin
308 stosw
309 stosb ; +23 [BYTE/BYTE/BYTE] Location Part
310 mov cx, 4
311 rep stosw ; +26 [DWORD/DWORD] Abs Locations
312 pop dx
313 inc cs:[LINUX_KernelNo]
314 FAT16PPD_IgnoreEntry:
315 add si, 32
316 cmp si, dx ; We are at Ending-Offset ?
317 jb FAT16PPD_DirectoryLoop
318 ; Done, now we got a maximum of 20 kernels in LINUX_KernelEntries-Array.
319 ret
320FAT16_ProcessKrnlDirectory EndP
Note: See TracBrowser for help on using the repository browser.