Chameleon

Chameleon Svn Source Tree

Root/branches/rewrite/i386/modules/BiosDisk/BiosDisk.cpp

Source at commit 1079 created 9 years 14 days 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
51extern "C"
52{
53#include "libsaio.h"
54#include "stdio.h"
55}
56
57BiosDisk::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
90BiosDisk::~BiosDisk()
91{
92
93}
94
95IOReturn BiosDisk::Read(UInt64 sector, UInt64 size, UInt8* buffer)
96{
97 if(!isValid()) return kIOReturnNoDevice;
98 return kIOReturnSuccess;
99}
100
101
102IOReturn BiosDisk::Write(UInt64 sector, UInt64 size, UInt8* buffer)
103{
104 if(!isValid()) return kIOReturnNoDevice;
105 return kIOReturnNotWritable;
106}
107
108
109UInt8 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
144UInt8 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
188UInt8 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
233UInt8 BiosDisk::GetDriveInfo()
234{
235 return 0; // TODO: finish this
236}
237
238

Archive Download this file

Revision: 1079