blob: 1801d22f6107c386caba64f1ba3da80b508cf042 [file] [log] [blame]
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -05001// 16bit code to access cdrom drives.
2//
Kevin O'Connorc892b132009-08-11 21:59:37 -04003// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -05004// Copyright (C) 2002 MandrakeSoft S.A.
5//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05006// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -05007
8#include "disk.h" // cdrom_13
9#include "util.h" // memset
Kevin O'Connor9521e262008-07-04 13:04:29 -040010#include "bregs.h" // struct bregs
11#include "biosvar.h" // GET_EBDA
Kevin O'Connorc892b132009-08-11 21:59:37 -040012#include "ata.h" // ATA_CMD_REQUEST_SENSE
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050013
14
15/****************************************************************
Kevin O'Connor51cfbe72009-08-18 22:38:49 -040016 * CD emulation
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050017 ****************************************************************/
18
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050019static void
Kevin O'Connor51cfbe72009-08-18 22:38:49 -040020cdemu_wp(struct bregs *regs, u8 driveid)
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050021{
22 disk_ret(regs, DISK_RET_EWRITEPROTECT);
23}
24
Kevin O'Connor1625a752009-08-09 13:08:21 -040025static void
Kevin O'Connor707298a2009-08-11 22:27:51 -040026cdemu_1302(struct bregs *regs, u8 driveid)
Kevin O'Connor1625a752009-08-09 13:08:21 -040027{
Kevin O'Connor707298a2009-08-11 22:27:51 -040028 cdemu_access(regs, driveid, CMD_READ);
Kevin O'Connor1625a752009-08-09 13:08:21 -040029}
30
31static void
Kevin O'Connor707298a2009-08-11 22:27:51 -040032cdemu_1304(struct bregs *regs, u8 driveid)
Kevin O'Connor1625a752009-08-09 13:08:21 -040033{
Kevin O'Connor707298a2009-08-11 22:27:51 -040034 cdemu_access(regs, driveid, CMD_VERIFY);
Kevin O'Connor1625a752009-08-09 13:08:21 -040035}
36
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050037// read disk drive parameters
38static void
Kevin O'Connor707298a2009-08-11 22:27:51 -040039cdemu_1308(struct bregs *regs, u8 driveid)
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050040{
Kevin O'Connor4a16ef62008-12-31 00:09:28 -050041 u16 ebda_seg = get_ebda_seg();
Kevin O'Connorb68ac712009-08-09 17:25:19 -040042 u16 nlc = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders) - 1;
43 u16 nlh = GET_EBDA2(ebda_seg, cdemu.lchs.heads) - 1;
44 u16 nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt);
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050045
46 regs->al = 0x00;
47 regs->bl = 0x00;
48 regs->ch = nlc & 0xff;
Kevin O'Connor4c0c85a2009-04-11 23:31:29 -040049 regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f);
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050050 regs->dh = nlh;
51 // FIXME ElTorito Various. should send the real count of drives 1 or 2
52 // FIXME ElTorito Harddisk. should send the HD count
53 regs->dl = 0x02;
Kevin O'Connor4a16ef62008-12-31 00:09:28 -050054 u8 media = GET_EBDA2(ebda_seg, cdemu.media);
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050055 if (media <= 3)
56 regs->bl = media * 2;
57
58 regs->es = SEG_BIOS;
Kevin O'Connor117fc212008-04-13 18:17:02 -040059 regs->di = (u32)&diskette_param_table2;
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050060
61 disk_ret(regs, DISK_RET_SUCCESS);
62}
63
64void
65cdemu_13(struct bregs *regs)
66{
67 //debug_stub(regs);
68
Kevin O'Connor4a16ef62008-12-31 00:09:28 -050069 u16 ebda_seg = get_ebda_seg();
Kevin O'Connor669e6442009-08-11 22:36:30 -040070 u8 driveid = GET_EBDA2(ebda_seg, cdemu.emulated_driveid);
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050071
72 switch (regs->ah) {
Kevin O'Connor707298a2009-08-11 22:27:51 -040073 case 0x02: cdemu_1302(regs, driveid); break;
74 case 0x04: cdemu_1304(regs, driveid); break;
75 case 0x08: cdemu_1308(regs, driveid); break;
Kevin O'Connoraa2590c2008-03-22 23:13:24 -040076
Kevin O'Connor51cfbe72009-08-18 22:38:49 -040077 case 0x03:
78 case 0x05:
79 cdemu_wp(regs, driveid);
80 break;
81
Kevin O'Connoraa7ddd72008-03-22 23:58:26 -040082 // These functions are the same as standard CDROM.
83 case 0x00:
84 case 0x01:
Kevin O'Connoraa7ddd72008-03-22 23:58:26 -040085 case 0x09:
86 case 0x0c:
87 case 0x0d:
88 case 0x10:
89 case 0x11:
90 case 0x14:
91 case 0x15:
92 case 0x16:
Kevin O'Connor51cfbe72009-08-18 22:38:49 -040093 disk_13(regs, driveid);
Kevin O'Connoraa7ddd72008-03-22 23:58:26 -040094 break;
95
Kevin O'Connor707298a2009-08-11 22:27:51 -040096 default: disk_13XX(regs, driveid); break;
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -050097 }
98}
99
100struct eltorito_s {
101 u8 size;
102 u8 media;
103 u8 emulated_drive;
104 u8 controller_index;
105 u32 ilba;
106 u16 device_spec;
107 u16 buffer_segment;
108 u16 load_segment;
109 u16 sector_count;
110 u8 cylinders;
111 u8 sectors;
112 u8 heads;
113};
114
115#define SET_INT13ET(regs,var,val) \
116 SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val))
117
118// ElTorito - Terminate disk emu
119void
120cdemu_134b(struct bregs *regs)
121{
122 // FIXME ElTorito Hardcoded
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500123 u16 ebda_seg = get_ebda_seg();
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -0500124 SET_INT13ET(regs, size, 0x13);
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500125 SET_INT13ET(regs, media, GET_EBDA2(ebda_seg, cdemu.media));
Kevin O'Connor669e6442009-08-11 22:36:30 -0400126 SET_INT13ET(regs, emulated_drive
127 , GET_EBDA2(ebda_seg, cdemu.emulated_extdrive));
128 u8 driveid = GET_EBDA2(ebda_seg, cdemu.emulated_driveid);
129 u8 cntl_id = GET_GLOBAL(Drives.drives[driveid].cntl_id);
130 SET_INT13ET(regs, controller_index, cntl_id / 2);
131 SET_INT13ET(regs, device_spec, cntl_id % 2);
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500132 SET_INT13ET(regs, ilba, GET_EBDA2(ebda_seg, cdemu.ilba));
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500133 SET_INT13ET(regs, buffer_segment, GET_EBDA2(ebda_seg, cdemu.buffer_segment));
134 SET_INT13ET(regs, load_segment, GET_EBDA2(ebda_seg, cdemu.load_segment));
135 SET_INT13ET(regs, sector_count, GET_EBDA2(ebda_seg, cdemu.sector_count));
Kevin O'Connorb68ac712009-08-09 17:25:19 -0400136 SET_INT13ET(regs, cylinders, GET_EBDA2(ebda_seg, cdemu.lchs.cylinders));
137 SET_INT13ET(regs, sectors, GET_EBDA2(ebda_seg, cdemu.lchs.spt));
138 SET_INT13ET(regs, heads, GET_EBDA2(ebda_seg, cdemu.lchs.heads));
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -0500139
140 // If we have to terminate emulation
141 if (regs->al == 0x00) {
142 // FIXME ElTorito Various. Should be handled accordingly to spec
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500143 SET_EBDA2(ebda_seg, cdemu.active, 0x00); // bye bye
Kevin O'Connor31d8c8a2008-03-04 19:56:41 -0500144 }
145
146 disk_ret(regs, DISK_RET_SUCCESS);
147}
Kevin O'Connor180a9592008-03-04 22:50:53 -0500148
149
150/****************************************************************
151 * CD booting
152 ****************************************************************/
153
154// Request SENSE
Kevin O'Connora05223c2008-06-28 12:15:57 -0400155static int
Kevin O'Connor707298a2009-08-11 22:27:51 -0400156atapi_get_sense(int driveid, u8 *asc, u8 *ascq)
Kevin O'Connor180a9592008-03-04 22:50:53 -0500157{
Kevin O'Connora0c68792009-02-12 20:47:59 -0500158 u8 atacmd[12], buffer[18];
Kevin O'Connor180a9592008-03-04 22:50:53 -0500159 memset(atacmd, 0, sizeof(atacmd));
160 atacmd[0] = ATA_CMD_REQUEST_SENSE;
161 atacmd[4] = sizeof(buffer);
Kevin O'Connor707298a2009-08-11 22:27:51 -0400162 int ret = ata_cmd_packet(driveid, atacmd, sizeof(atacmd), sizeof(buffer)
Kevin O'Connor35ae7262009-01-19 15:44:44 -0500163 , MAKE_FLATPTR(GET_SEG(SS), buffer));
Kevin O'Connora0c68792009-02-12 20:47:59 -0500164 if (ret)
Kevin O'Connora05223c2008-06-28 12:15:57 -0400165 return ret;
Kevin O'Connor180a9592008-03-04 22:50:53 -0500166
167 *asc = buffer[12];
168 *ascq = buffer[13];
169
170 return 0;
171}
172
Kevin O'Connora0c68792009-02-12 20:47:59 -0500173// Request capacity
174static int
Kevin O'Connor707298a2009-08-11 22:27:51 -0400175atapi_read_capacity(int driveid, u32 *blksize, u32 *sectors)
Kevin O'Connora0c68792009-02-12 20:47:59 -0500176{
177 u8 packet[12], buf[8];
178 memset(packet, 0, sizeof(packet));
179 packet[0] = 0x25; /* READ CAPACITY */
Kevin O'Connor707298a2009-08-11 22:27:51 -0400180 int ret = ata_cmd_packet(driveid, packet, sizeof(packet), sizeof(buf)
Kevin O'Connora0c68792009-02-12 20:47:59 -0500181 , MAKE_FLATPTR(GET_SEG(SS), buf));
182 if (ret)
183 return ret;
184
185 *blksize = (((u32)buf[4] << 24) | ((u32)buf[5] << 16)
186 | ((u32)buf[6] << 8) | ((u32)buf[7] << 0));
187 *sectors = (((u32)buf[0] << 24) | ((u32)buf[1] << 16)
188 | ((u32)buf[2] << 8) | ((u32)buf[3] << 0));
189
190 return 0;
191}
192
Kevin O'Connora05223c2008-06-28 12:15:57 -0400193static int
Kevin O'Connor707298a2009-08-11 22:27:51 -0400194atapi_is_ready(u16 driveid)
Kevin O'Connor180a9592008-03-04 22:50:53 -0500195{
Kevin O'Connor707298a2009-08-11 22:27:51 -0400196 dprintf(6, "atapi_is_ready (driveid=%d)\n", driveid);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500197
Kevin O'Connora0c68792009-02-12 20:47:59 -0500198 /* Retry READ CAPACITY for 5 seconds unless MEDIUM NOT PRESENT is
199 * reported by the device. If the device reports "IN PROGRESS",
Kevin O'Connor180a9592008-03-04 22:50:53 -0500200 * 30 seconds is added. */
Kevin O'Connora0c68792009-02-12 20:47:59 -0500201 u32 blksize, sectors;
202 int in_progress = 0;
203 u64 end = calc_future_tsc(5000);
204 for (;;) {
205 if (rdtscll() > end) {
Kevin O'Connora05223c2008-06-28 12:15:57 -0400206 dprintf(1, "read capacity failed\n");
Kevin O'Connor180a9592008-03-04 22:50:53 -0500207 return -1;
208 }
Kevin O'Connora0c68792009-02-12 20:47:59 -0500209
Kevin O'Connor707298a2009-08-11 22:27:51 -0400210 int ret = atapi_read_capacity(driveid, &blksize, &sectors);
Kevin O'Connora0c68792009-02-12 20:47:59 -0500211 if (!ret)
212 // Success
Kevin O'Connor180a9592008-03-04 22:50:53 -0500213 break;
214
Kevin O'Connora0c68792009-02-12 20:47:59 -0500215 u8 asc, ascq;
Kevin O'Connor707298a2009-08-11 22:27:51 -0400216 ret = atapi_get_sense(driveid, &asc, &ascq);
Kevin O'Connora0c68792009-02-12 20:47:59 -0500217 if (ret)
218 // Error - retry.
Kevin O'Connor180a9592008-03-04 22:50:53 -0500219 continue;
220
Kevin O'Connora0c68792009-02-12 20:47:59 -0500221 // Sense succeeded.
Kevin O'Connor180a9592008-03-04 22:50:53 -0500222 if (asc == 0x3a) { /* MEDIUM NOT PRESENT */
Kevin O'Connora05223c2008-06-28 12:15:57 -0400223 dprintf(1, "Device reports MEDIUM NOT PRESENT\n");
Kevin O'Connor180a9592008-03-04 22:50:53 -0500224 return -1;
225 }
226
227 if (asc == 0x04 && ascq == 0x01 && !in_progress) {
228 /* IN PROGRESS OF BECOMING READY */
229 printf("Waiting for device to detect medium... ");
230 /* Allow 30 seconds more */
Kevin O'Connora0c68792009-02-12 20:47:59 -0500231 end = calc_future_tsc(30000);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500232 in_progress = 1;
233 }
234 }
235
Kevin O'Connor707298a2009-08-11 22:27:51 -0400236 if (blksize != GET_GLOBAL(Drives.drives[driveid].blksize)) {
Kevin O'Connora0c68792009-02-12 20:47:59 -0500237 printf("Unsupported sector size %u\n", blksize);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500238 return -1;
239 }
Kevin O'Connor180a9592008-03-04 22:50:53 -0500240
Kevin O'Connora05223c2008-06-28 12:15:57 -0400241 dprintf(6, "sectors=%u\n", sectors);
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500242 printf("%dMB medium detected\n", sectors>>(20-11));
Kevin O'Connor180a9592008-03-04 22:50:53 -0500243 return 0;
244}
245
Kevin O'Connora05223c2008-06-28 12:15:57 -0400246int
Kevin O'Connor7da1dcd2009-02-16 10:51:24 -0500247cdrom_boot(int cdid)
Kevin O'Connor180a9592008-03-04 22:50:53 -0500248{
Kevin O'Connor7da1dcd2009-02-16 10:51:24 -0500249 // Verify device is a cdrom.
Kevin O'Connorc892b132009-08-11 21:59:37 -0400250 if (cdid >= Drives.cdcount)
Kevin O'Connor7da1dcd2009-02-16 10:51:24 -0500251 return 1;
Kevin O'Connor0a0e42e2009-08-16 12:09:44 -0400252 int driveid = GET_GLOBAL(Drives.idmap[EXTTYPE_CD][cdid]);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500253
Kevin O'Connor7da1dcd2009-02-16 10:51:24 -0500254 int ret = atapi_is_ready(driveid);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500255 if (ret)
Kevin O'Connor65e63422008-07-19 14:12:32 -0400256 dprintf(1, "atapi_is_ready returned %d\n", ret);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500257
258 // Read the Boot Record Volume Descriptor
259 u8 buffer[2048];
Kevin O'Connor4524bf72008-12-31 00:31:03 -0500260 struct disk_op_s dop;
Kevin O'Connor3f6c2782009-08-09 19:17:11 -0400261 memset(&dop, 0, sizeof(dop));
Kevin O'Connor7da1dcd2009-02-16 10:51:24 -0500262 dop.driveid = driveid;
Kevin O'Connor4524bf72008-12-31 00:31:03 -0500263 dop.lba = 0x11;
264 dop.count = 1;
Kevin O'Connor35ae7262009-01-19 15:44:44 -0500265 dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
Kevin O'Connor4524bf72008-12-31 00:31:03 -0500266 ret = cdrom_read(&dop);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500267 if (ret)
268 return 3;
269
270 // Validity checks
271 if (buffer[0])
272 return 4;
Kevin O'Connor38d1a342009-04-18 16:59:47 -0400273 if (strcmp((char*)&buffer[1], "CD001\001EL TORITO SPECIFICATION") != 0)
Kevin O'Connor180a9592008-03-04 22:50:53 -0500274 return 5;
275
276 // ok, now we calculate the Boot catalog address
277 u32 lba = *(u32*)&buffer[0x47];
278
279 // And we read the Boot Catalog
Kevin O'Connor4524bf72008-12-31 00:31:03 -0500280 dop.lba = lba;
281 ret = cdrom_read(&dop);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500282 if (ret)
283 return 7;
284
285 // Validation entry
286 if (buffer[0x00] != 0x01)
287 return 8; // Header
288 if (buffer[0x01] != 0x00)
289 return 9; // Platform
290 if (buffer[0x1E] != 0x55)
291 return 10; // key 1
292 if (buffer[0x1F] != 0xAA)
293 return 10; // key 2
294
295 // Initial/Default Entry
296 if (buffer[0x20] != 0x88)
297 return 11; // Bootable
298
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500299 u16 ebda_seg = get_ebda_seg();
Kevin O'Connordfa16502008-03-22 20:13:08 -0400300 u8 media = buffer[0x21];
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500301 SET_EBDA2(ebda_seg, cdemu.media, media);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500302
Kevin O'Connor669e6442009-08-11 22:36:30 -0400303 SET_EBDA2(ebda_seg, cdemu.emulated_driveid, driveid);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500304
305 u16 boot_segment = *(u16*)&buffer[0x22];
306 if (!boot_segment)
307 boot_segment = 0x07C0;
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500308 SET_EBDA2(ebda_seg, cdemu.load_segment, boot_segment);
309 SET_EBDA2(ebda_seg, cdemu.buffer_segment, 0x0000);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500310
311 u16 nbsectors = *(u16*)&buffer[0x26];
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500312 SET_EBDA2(ebda_seg, cdemu.sector_count, nbsectors);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500313
314 lba = *(u32*)&buffer[0x28];
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500315 SET_EBDA2(ebda_seg, cdemu.ilba, lba);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500316
317 // And we read the image in memory
Kevin O'Connora4d70aa2009-08-09 11:32:00 -0400318 dop.lba = lba;
319 dop.count = DIV_ROUND_UP(nbsectors, 4);
Kevin O'Connor35ae7262009-01-19 15:44:44 -0500320 dop.buf_fl = MAKE_FLATPTR(boot_segment, 0);
Kevin O'Connora4d70aa2009-08-09 11:32:00 -0400321 ret = cdrom_read(&dop);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500322 if (ret)
323 return 12;
324
Kevin O'Connordfa16502008-03-22 20:13:08 -0400325 if (media == 0) {
326 // No emulation requested - return success.
Kevin O'Connor51cfbe72009-08-18 22:38:49 -0400327 SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, EXTSTART_CD + cdid);
Kevin O'Connordfa16502008-03-22 20:13:08 -0400328 return 0;
329 }
330
331 // Emulation of a floppy/harddisk requested
332 if (! CONFIG_CDROM_EMU)
333 return 13;
334
335 // Set emulated drive id and increase bios installed hardware
336 // number of devices
337 if (media < 4) {
338 // Floppy emulation
Kevin O'Connor669e6442009-08-11 22:36:30 -0400339 SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x00);
Kevin O'Connordfa16502008-03-22 20:13:08 -0400340 SETBITS_BDA(equipment_list_flags, 0x41);
Kevin O'Connor95827c42009-02-07 00:04:57 -0500341
342 switch (media) {
343 case 0x01: // 1.2M floppy
Kevin O'Connorb68ac712009-08-09 17:25:19 -0400344 SET_EBDA2(ebda_seg, cdemu.lchs.spt, 15);
345 SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80);
346 SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2);
Kevin O'Connor95827c42009-02-07 00:04:57 -0500347 break;
348 case 0x02: // 1.44M floppy
Kevin O'Connorb68ac712009-08-09 17:25:19 -0400349 SET_EBDA2(ebda_seg, cdemu.lchs.spt, 18);
350 SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80);
351 SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2);
Kevin O'Connor95827c42009-02-07 00:04:57 -0500352 break;
353 case 0x03: // 2.88M floppy
Kevin O'Connorb68ac712009-08-09 17:25:19 -0400354 SET_EBDA2(ebda_seg, cdemu.lchs.spt, 36);
355 SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80);
356 SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2);
Kevin O'Connor95827c42009-02-07 00:04:57 -0500357 break;
358 }
Kevin O'Connordfa16502008-03-22 20:13:08 -0400359 } else {
360 // Harddrive emulation
Kevin O'Connor669e6442009-08-11 22:36:30 -0400361 SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x80);
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500362 SET_BDA(hdcount, GET_BDA(hdcount) + 1);
Kevin O'Connordfa16502008-03-22 20:13:08 -0400363
Kevin O'Connor95827c42009-02-07 00:04:57 -0500364 // Peak at partition table to get chs.
365 struct mbr_s *mbr = (void*)0;
366 u8 sptcyl = GET_FARVAR(boot_segment, mbr->partitions[0].last.sptcyl);
367 u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow);
368 u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads);
369
Kevin O'Connorb68ac712009-08-09 17:25:19 -0400370 SET_EBDA2(ebda_seg, cdemu.lchs.spt, sptcyl & 0x3f);
371 SET_EBDA2(ebda_seg, cdemu.lchs.cylinders
372 , ((sptcyl<<2)&0x300) + cyllow + 1);
373 SET_EBDA2(ebda_seg, cdemu.lchs.heads, heads + 1);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500374 }
375
Kevin O'Connordfa16502008-03-22 20:13:08 -0400376 // everything is ok, so from now on, the emulation is active
Kevin O'Connor4a16ef62008-12-31 00:09:28 -0500377 SET_EBDA2(ebda_seg, cdemu.active, 0x01);
Kevin O'Connora05223c2008-06-28 12:15:57 -0400378 dprintf(6, "cdemu media=%d\n", media);
Kevin O'Connor180a9592008-03-04 22:50:53 -0500379
380 return 0;
381}