Root/
Source at commit 1079 created 13 years 1 month ago. By meklort, began implimenting Bios disk changes. Code taken from biosfn.c | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
7 | * Reserved. This file contains Original Code and/or Modifications of␊ |
8 | * Original Code as defined in and that are subject to the Apple Public␊ |
9 | * Source License Version 2.0 (the "License"). You may not use this file␊ |
10 | * except in compliance with the License. Please obtain a copy of the␊ |
11 | * License at http://www.apple.com/publicsource and read it before using␊ |
12 | * this file.␊ |
13 | * ␊ |
14 | * The Original Code and all software distributed under the License are␊ |
15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the␊ |
19 | * License for the specific language governing rights and limitations␊ |
20 | * under the License.␊ |
21 | * ␊ |
22 | * @APPLE_LICENSE_HEADER_END@␊ |
23 | */␊ |
24 | /*␊ |
25 | * Copyright 1993 NeXT Computer, Inc.␊ |
26 | * All rights reserved.␊ |
27 | */␊ |
28 | ␊ |
29 | /* Copyright 2007 David Elliott␊ |
30 | 2007-12-30 dfe␊ |
31 | - Enhanced code to normalize segment/offset to huge pointers so that any␊ |
32 | linear address within the first MB of memory can be passed to BIOS␊ |
33 | functions. This allows some of the __DATA sections to span into the␊ |
34 | next segment and also allows stack variables to be used whereas the␊ |
35 | old code could only operate on static data in the first 64k.␊ |
36 | NOTE: Requires bios.s change to respect DS.␊ |
37 | */␊ |
38 | /* Copyright 2007 VMware Inc.␊ |
39 | 2007-12-29 dfe␊ |
40 | - Added ebiosEjectMedia␊ |
41 | */␊ |
42 | ␊ |
43 | /*␊ |
44 | * Copyright (c) 2011 Evan Lojewski.␊ |
45 | * - Converted to c++␊ |
46 | * - Converted to UInt* style variable types␊ |
47 | */␊ |
48 | ␊ |
49 | #include <BiosDisk.hpp>␊ |
50 | ␊ |
51 | extern "C"␊ |
52 | {␊ |
53 | #include "libsaio.h"␊ |
54 | #include "stdio.h"␊ |
55 | }␊ |
56 | ␊ |
57 | BiosDisk::BiosDisk(const char* name)␊ |
58 | {␊ |
59 | // Initialize␊ |
60 | mValid = false;␊ |
61 | mDiskID = 0;␊ |
62 | mUsesEBIOS = 0;␊ |
63 | mNoEmulation = false;␊ |
64 | mBytesPerSector = 0;␊ |
65 | ␊ |
66 | ␊ |
67 | // The correct format should be:␊ |
68 | // bios:/hdX/␊ |
69 | mBusType = "bios";␊ |
70 | ␊ |
71 | if(strncmp(mBusType, name, 4) != 0) name = NULL;␊ |
72 | ␊ |
73 | mName = name;␊ |
74 | ␊ |
75 | sscanf(name, "bios:/hd%d/", &mDiskID);␊ |
76 | mDiskID += 0x80; // 0x80 = fixed disk␊ |
77 | ␊ |
78 | ␊ |
79 | if(BIOSRead(0, 0, 1, 1) == 0 && GetDriveInfo() == 0) ␊ |
80 | {␊ |
81 | mBytesPerSector = mDriveInfo.params.phys_nbps;␊ |
82 | printf("Disk: 0x%X (%d sectors)\n", mDiskID, mBytesPerSector); ␊ |
83 | }␊ |
84 | else␊ |
85 | {␊ |
86 | mValid = 0; // force invalid.␊ |
87 | }␊ |
88 | }␊ |
89 | ␊ |
90 | BiosDisk::~BiosDisk()␊ |
91 | {␊ |
92 | ␊ |
93 | }␊ |
94 | ␊ |
95 | IOReturn BiosDisk::Read(UInt64 sector, UInt64 size, UInt8* buffer)␊ |
96 | {␊ |
97 | if(!isValid()) return kIOReturnNoDevice;␊ |
98 | return kIOReturnSuccess;␊ |
99 | }␊ |
100 | ␊ |
101 | ␊ |
102 | IOReturn BiosDisk::Write(UInt64 sector, UInt64 size, UInt8* buffer)␊ |
103 | {␊ |
104 | if(!isValid()) return kIOReturnNoDevice;␊ |
105 | return kIOReturnNotWritable;␊ |
106 | }␊ |
107 | ␊ |
108 | ␊ |
109 | UInt8 BiosDisk::BIOSRead(UInt16 cylinder, UInt8 head, UInt8 sector, UInt8 count)␊ |
110 | {␊ |
111 | if(sector == 0) return -1;␊ |
112 | ␊ |
113 | biosBuf_t bb;␊ |
114 | int i;␊ |
115 | ␊ |
116 | bb.intno = 0x13;␊ |
117 | bb.eax.r.h = 0x02;␊ |
118 | ␊ |
119 | for (i=0;;)␊ |
120 | {␊ |
121 | bb.ecx.r.h = cylinder;␊ |
122 | bb.ecx.r.l = ((cylinder & 0x300) >> 2) | (sector & 0x3F);␊ |
123 | bb.edx.r.h = head;␊ |
124 | bb.edx.r.l = mDiskID;␊ |
125 | bb.eax.r.l = count;␊ |
126 | bb.ebx.rr = OFFSET(ptov(BIOS_ADDR));␊ |
127 | bb.es = SEGMENT(ptov(BIOS_ADDR));␊ |
128 | ␊ |
129 | bios(&bb);␊ |
130 | ␊ |
131 | /* In case of a successful call, make sure we set AH (return code) to zero. */␊ |
132 | if (bb.flags.cf == 0) bb.eax.r.h = 0;␊ |
133 | ␊ |
134 | /* Now we can really check for the return code (AH) value. */␊ |
135 | if ((bb.eax.r.h == 0x00) || (i++ >= 5)) break;␊ |
136 | ␊ |
137 | /* reset disk subsystem and try again */␊ |
138 | bb.eax.r.h = 0x00;␊ |
139 | bios(&bb);␊ |
140 | }␊ |
141 | return bb.eax.r.h;␊ |
142 | }␊ |
143 | ␊ |
144 | UInt8 BiosDisk::EBIOSRead(UInt64 sector, UInt8 count)␊ |
145 | {␊ |
146 | biosBuf_t bb;␊ |
147 | ␊ |
148 | UInt8 i;␊ |
149 | struct {␊ |
150 | UInt8 size;␊ |
151 | UInt8 reserved;␊ |
152 | UInt8 numblocks;␊ |
153 | UInt8 reserved2;␊ |
154 | UInt16 bufferOffset;␊ |
155 | UInt16 bufferSegment;␊ |
156 | UInt64 startblock;␊ |
157 | } addrpacket __attribute__((aligned(16))) = {0};␊ |
158 | addrpacket.size = sizeof(addrpacket);␊ |
159 | ␊ |
160 | for (i=0;;) {␊ |
161 | bb.intno = 0x13;␊ |
162 | bb.eax.r.h = 0x42;␊ |
163 | bb.edx.r.l = mDiskID;␊ |
164 | bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);␊ |
165 | bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);␊ |
166 | addrpacket.reserved = addrpacket.reserved2 = 0;␊ |
167 | addrpacket.numblocks = count;␊ |
168 | addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));␊ |
169 | addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));␊ |
170 | addrpacket.startblock = sector;␊ |
171 | bios(&bb);␊ |
172 | ␊ |
173 | /* In case of a successful call, make sure we set AH (return code) to zero. */␊ |
174 | if (bb.flags.cf == 0)␊ |
175 | bb.eax.r.h = 0;␊ |
176 | ␊ |
177 | /* Now we can really check for the return code (AH) value. */␊ |
178 | if ((bb.eax.r.h == 0x00) || (i++ >= 5))␊ |
179 | break;␊ |
180 | ␊ |
181 | /* reset disk subsystem and try again */␊ |
182 | bb.eax.r.h = 0x00;␊ |
183 | bios(&bb);␊ |
184 | }␊ |
185 | return bb.eax.r.h;␊ |
186 | }␊ |
187 | ␊ |
188 | UInt8 BiosDisk::EBIOSWrite(UInt64 sector, UInt8 count)␊ |
189 | {␊ |
190 | biosBuf_t bb;␊ |
191 | ␊ |
192 | UInt8 i;␊ |
193 | static struct {␊ |
194 | UInt8 size;␊ |
195 | UInt8 reserved;␊ |
196 | UInt8 numblocks;␊ |
197 | UInt8 reserved2;␊ |
198 | UInt16 bufferOffset;␊ |
199 | UInt16 bufferSegment;␊ |
200 | UInt64 startblock;␊ |
201 | } addrpacket __attribute__((aligned(16))) = {0};␊ |
202 | addrpacket.size = sizeof(addrpacket);␊ |
203 | ␊ |
204 | for (i=0;;) {␊ |
205 | bb.intno = 0x13;␊ |
206 | bb.eax.r.l = 0; /* Don't verify */␊ |
207 | bb.eax.r.h = 0x43;␊ |
208 | bb.edx.r.l = mDiskID;␊ |
209 | bb.esi.rr = NORMALIZED_OFFSET((unsigned)&addrpacket);␊ |
210 | bb.ds = NORMALIZED_SEGMENT((unsigned)&addrpacket);␊ |
211 | addrpacket.reserved = addrpacket.reserved2 = 0;␊ |
212 | addrpacket.numblocks = count;␊ |
213 | addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));␊ |
214 | addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));␊ |
215 | addrpacket.startblock = sector;␊ |
216 | bios(&bb);␊ |
217 | ␊ |
218 | /* In case of a successful call, make sure we set AH (return code) to zero. */␊ |
219 | if (bb.flags.cf == 0)␊ |
220 | bb.eax.r.h = 0;␊ |
221 | ␊ |
222 | /* Now we can really check for the return code (AH) value. */␊ |
223 | if ((bb.eax.r.h == 0x00) || (i++ >= 5))␊ |
224 | break;␊ |
225 | ␊ |
226 | /* reset disk subsystem and try again */␊ |
227 | bb.eax.r.h = 0x00;␊ |
228 | bios(&bb);␊ |
229 | }␊ |
230 | return bb.eax.r.h;␊ |
231 | }␊ |
232 | ␊ |
233 | UInt8 BiosDisk::GetDriveInfo()␊ |
234 | {␊ |
235 | return 0; // TODO: finish this␊ |
236 | }␊ |
237 | ␊ |
238 |