46c3116cc585b0baa8d56173bd907df8d3f03d7d
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / i386disk.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "freeldr.h"
21 #include "disk.h"
22 #include "rtl.h"
23 #include "arch.h"
24 #include "debug.h"
25 #include "portio.h"
26 #include "machine.h"
27
28
29 /////////////////////////////////////////////////////////////////////////////////////////////
30 // FUNCTIONS
31 /////////////////////////////////////////////////////////////////////////////////////////////
32
33 #ifdef __i386__
34
35 BOOL DiskResetController(U32 DriveNumber)
36 {
37 REGS RegsIn;
38 REGS RegsOut;
39
40 DbgPrint((DPRINT_DISK, "DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
41
42 // BIOS Int 13h, function 0 - Reset disk system
43 // AH = 00h
44 // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
45 // Return:
46 // AH = status
47 // CF clear if successful
48 // CF set on error
49 RegsIn.b.ah = 0x00;
50 RegsIn.b.dl = DriveNumber;
51
52 // Reset the disk controller
53 Int386(0x13, &RegsIn, &RegsOut);
54
55 return INT386_SUCCESS(RegsOut);
56 }
57
58 BOOL DiskInt13ExtensionsSupported(U32 DriveNumber)
59 {
60 REGS RegsIn;
61 REGS RegsOut;
62
63 DbgPrint((DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"));
64
65 // IBM/MS INT 13 Extensions - INSTALLATION CHECK
66 // AH = 41h
67 // BX = 55AAh
68 // DL = drive (80h-FFh)
69 // Return:
70 // CF set on error (extensions not supported)
71 // AH = 01h (invalid function)
72 // CF clear if successful
73 // BX = AA55h if installed
74 // AH = major version of extensions
75 // 01h = 1.x
76 // 20h = 2.0 / EDD-1.0
77 // 21h = 2.1 / EDD-1.1
78 // 30h = EDD-3.0
79 // AL = internal use
80 // CX = API subset support bitmap
81 // DH = extension version (v2.0+ ??? -- not present in 1.x)
82 //
83 // Bitfields for IBM/MS INT 13 Extensions API support bitmap
84 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
85 // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
86 // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
87 // extended drive parameter table is valid
88 // Bits 3-15 reserved
89 RegsIn.b.ah = 0x41;
90 RegsIn.w.bx = 0x55AA;
91 RegsIn.b.dl = DriveNumber;
92
93 // Reset the disk controller
94 Int386(0x13, &RegsIn, &RegsOut);
95
96 if (!INT386_SUCCESS(RegsOut))
97 {
98 // CF set on error (extensions not supported)
99 return FALSE;
100 }
101
102 if (RegsOut.w.bx != 0xAA55)
103 {
104 // BX = AA55h if installed
105 return FALSE;
106 }
107
108 // Note:
109 // The original check is too strict because some BIOSes report that
110 // extended disk access functions are not suported when booting
111 // from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
112 #if 0
113 if (!(RegsOut.w.cx & 0x0001))
114 {
115 // CX = API subset support bitmap
116 // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
117 return FALSE;
118 }
119 #endif
120
121 // Use this relaxed check instead
122 if (RegsOut.w.cx == 0x0000)
123 {
124 // CX = API subset support bitmap
125 return FALSE;
126 }
127
128 return TRUE;
129 }
130
131 VOID DiskStopFloppyMotor(VOID)
132 {
133 WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
134 }
135
136 BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize)
137 {
138 REGS RegsIn;
139 REGS RegsOut;
140 PU16 Ptr = (PU16)(BIOSCALLBUFFER);
141
142 DbgPrint((DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"));
143
144 // Initialize transfer buffer
145 *Ptr = BufferSize;
146
147 // BIOS Int 13h, function 48h - Get drive parameters
148 // AH = 48h
149 // DL = drive (bit 7 set for hard disk)
150 // DS:SI = result buffer
151 // Return:
152 // CF set on error
153 // AH = status (07h)
154 // CF clear if successful
155 // AH = 00h
156 // DS:SI -> result buffer
157 RegsIn.b.ah = 0x48;
158 RegsIn.b.dl = DriveNumber;
159 RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
160 RegsIn.w.si = BIOSCALLBUFOFFSET;
161
162 // Get drive parameters
163 Int386(0x13, &RegsIn, &RegsOut);
164
165 if (!INT386_SUCCESS(RegsOut))
166 {
167 return FALSE;
168 }
169
170 memcpy(Buffer, Ptr, BufferSize);
171
172 return TRUE;
173 }
174
175 #endif // defined __i386__