1 // 16bit code to access cdrom drives.
3 // Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002 MandrakeSoft S.A.
6 // This file may be distributed under the terms of the GNU GPLv3 license.
8 #include "disk.h" // cdrom_13
9 #include "util.h" // memset
10 #include "ata.h" // ATA_CMD_READ_SECTORS
13 /****************************************************************
15 ****************************************************************/
17 // read disk drive size
19 cdrom_1315(struct bregs *regs, u8 device)
21 disk_ret(regs, DISK_RET_EADDRNOTFOUND);
26 cdrom_134500(struct bregs *regs, u8 device)
28 u8 locks = GET_EBDA(ata.devices[device].lock);
31 disk_ret(regs, DISK_RET_ETOOMANYLOCKS);
34 SET_EBDA(ata.devices[device].lock, locks + 1);
36 disk_ret(regs, DISK_RET_SUCCESS);
41 cdrom_134501(struct bregs *regs, u8 device)
43 u8 locks = GET_EBDA(ata.devices[device].lock);
46 disk_ret(regs, DISK_RET_ENOTLOCKED);
50 SET_EBDA(ata.devices[device].lock, locks);
51 regs->al = (locks ? 1 : 0);
52 disk_ret(regs, DISK_RET_SUCCESS);
57 cdrom_134502(struct bregs *regs, u8 device)
59 u8 locks = GET_EBDA(ata.devices[device].lock);
60 regs->al = (locks ? 1 : 0);
61 disk_ret(regs, DISK_RET_SUCCESS);
65 cdrom_1345XX(struct bregs *regs, u8 device)
67 disk_ret(regs, DISK_RET_EPARAM);
70 // IBM/MS lock/unlock drive
72 cdrom_1345(struct bregs *regs, u8 device)
75 case 0x00: cdrom_134500(regs, device); break;
76 case 0x01: cdrom_134501(regs, device); break;
77 case 0x02: cdrom_134502(regs, device); break;
78 default: cdrom_1345XX(regs, device); break;
84 cdrom_1346(struct bregs *regs, u8 device)
86 u8 locks = GET_EBDA(ata.devices[device].lock);
88 disk_ret(regs, DISK_RET_ELOCKED);
92 // FIXME should handle 0x31 no media in device
93 // FIXME should handle 0xb5 valid request failed
95 // Call removable media eject
97 memset(&br, 0, sizeof(br));
99 call16_int(0x15, &br);
101 if (br.ah || br.flags & F_CF) {
102 disk_ret(regs, DISK_RET_ELOCKED);
105 disk_ret(regs, DISK_RET_SUCCESS);
108 // IBM/MS extended media change
110 cdrom_1349(struct bregs *regs, u8 device)
112 // always send changed ??
113 regs->ah = DISK_RET_ECHANGED;
118 cdrom_ok(struct bregs *regs, u8 device)
120 disk_ret(regs, DISK_RET_SUCCESS);
124 cdrom_wp(struct bregs *regs, u8 device)
126 disk_ret(regs, DISK_RET_EWRITEPROTECT);
130 cdrom_13(struct bregs *regs, u8 device)
135 case 0x15: cdrom_1315(regs, device); break;
136 case 0x45: cdrom_1345(regs, device); break;
137 case 0x46: cdrom_1346(regs, device); break;
138 case 0x49: cdrom_1349(regs, device); break;
140 // These functions are the same as for hard disks
148 disk_13(regs, device);
151 // all these functions return SUCCESS
152 case 0x00: // disk controller reset
153 case 0x09: // initialize drive parameters
154 case 0x0c: // seek to specified cylinder
155 case 0x0d: // alternate disk reset
156 case 0x10: // check drive ready
157 case 0x11: // recalibrate
158 case 0x14: // controller internal diagnostic
159 case 0x16: // detect disk change
160 cdrom_ok(regs, device);
163 // all these functions return disk write-protected
164 case 0x03: // write disk sectors
165 case 0x05: // format disk track
166 case 0x43: // IBM/MS extended write
167 cdrom_wp(regs, device);
170 default: disk_13XX(regs, device); break;
175 /****************************************************************
177 ****************************************************************/
181 cdemu_1302(struct bregs *regs, u8 device)
183 emu_access(regs, device, ATA_CMD_READ_SECTORS);
186 // verify disk sectors
188 cdemu_1304(struct bregs *regs, u8 device)
190 emu_access(regs, device, 0);
193 // read disk drive parameters
195 cdemu_1308(struct bregs *regs, u8 device)
197 u16 nlc = GET_EBDA(cdemu.vdevice.cylinders) - 1;
198 u16 nlh = GET_EBDA(cdemu.vdevice.heads) - 1;
199 u16 nlspt = GET_EBDA(cdemu.vdevice.spt);
203 regs->ch = nlc & 0xff;
204 regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f);
206 // FIXME ElTorito Various. should send the real count of drives 1 or 2
207 // FIXME ElTorito Harddisk. should send the HD count
209 u8 media = GET_EBDA(cdemu.media);
211 regs->bl = media * 2;
214 regs->di = (u16)&diskette_param_table2;
216 disk_ret(regs, DISK_RET_SUCCESS);
220 cdemu_13(struct bregs *regs)
224 u8 device = GET_EBDA(cdemu.controller_index) * 2;
225 device += GET_EBDA(cdemu.device_spec);
228 case 0x02: cdemu_1302(regs, device); break;
229 case 0x04: cdemu_1304(regs, device); break;
230 case 0x08: cdemu_1308(regs, device); break;
231 // XXX - All other calls get passed to standard CDROM functions.
232 default: cdrom_13(regs, device); break;
251 #define SET_INT13ET(regs,var,val) \
252 SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val))
254 // ElTorito - Terminate disk emu
256 cdemu_134b(struct bregs *regs)
258 // FIXME ElTorito Hardcoded
259 SET_INT13ET(regs, size, 0x13);
260 SET_INT13ET(regs, media, GET_EBDA(cdemu.media));
261 SET_INT13ET(regs, emulated_drive, GET_EBDA(cdemu.emulated_drive));
262 SET_INT13ET(regs, controller_index, GET_EBDA(cdemu.controller_index));
263 SET_INT13ET(regs, ilba, GET_EBDA(cdemu.ilba));
264 SET_INT13ET(regs, device_spec, GET_EBDA(cdemu.device_spec));
265 SET_INT13ET(regs, buffer_segment, GET_EBDA(cdemu.buffer_segment));
266 SET_INT13ET(regs, load_segment, GET_EBDA(cdemu.load_segment));
267 SET_INT13ET(regs, sector_count, GET_EBDA(cdemu.sector_count));
268 SET_INT13ET(regs, cylinders, GET_EBDA(cdemu.vdevice.cylinders));
269 SET_INT13ET(regs, sectors, GET_EBDA(cdemu.vdevice.spt));
270 SET_INT13ET(regs, heads, GET_EBDA(cdemu.vdevice.heads));
272 // If we have to terminate emulation
273 if (regs->al == 0x00) {
274 // FIXME ElTorito Various. Should be handled accordingly to spec
275 SET_EBDA(cdemu.active, 0x00); // bye bye
278 disk_ret(regs, DISK_RET_SUCCESS);