Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 43 +---------------------------- src/block.c | 1 + src/blockcmd.h | 2 + src/boot.c | 6 +-- src/cdrom.c | 84 ++++++++++++++++++++++++++++---------------------------- src/coreboot.c | 3 +- src/disk.c | 75 +++++++++++++++++++++---------------------------- src/disk.h | 38 ++++++++++++++++++++++++- 8 files changed, 118 insertions(+), 134 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 6521acf..4d62df1 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -8,8 +8,7 @@
#include "types.h" // u8 #include "farptr.h" // GET_FARVAR -#include "config.h" // CONFIG_* -#include "disk.h" // struct chs_s +#include "config.h" // SEG_BDA
/**************************************************************** @@ -149,37 +148,6 @@ struct bios_data_area_s { * Extended Bios Data Area (EBDA) ****************************************************************/
-// DPTE definition -struct dpte_s { - u16 iobase1; - u16 iobase2; - u8 prefix; - u8 unused; - u8 irq; - u8 blkcount; - u8 dma; - u8 pio; - u16 options; - u16 reserved; - u8 revision; - u8 checksum; -}; - -// ElTorito Device Emulation data -struct cdemu_s { - struct drive_s *emulated_drive_gf; - u32 ilba; - u16 buffer_segment; - u16 load_segment; - u16 sector_count; - u8 active; - u8 media; - u8 emulated_extdrive; - - // Virtual device - struct chs_s lchs; -}; - struct fdpt_s { u16 cylinders; u8 heads; @@ -212,15 +180,6 @@ struct extended_bios_data_area_s { u8 other2[0xC4];
// 0x121 - Begin custom storage. - - // El Torito Emulation data - struct cdemu_s cdemu; - - // Buffer for disk DPTE table - struct dpte_s dpte; - - // Locks for removable devices - u8 cdrom_locks[CONFIG_MAX_EXTDRIVE]; } PACKED;
// The initial size and location of EBDA diff --git a/src/block.c b/src/block.c index 194d6f2..44ba9bd 100644 --- a/src/block.c +++ b/src/block.c @@ -18,6 +18,7 @@ u8 FloppyCount VAR16VISIBLE; u8 CDCount; struct drive_s *IDMap[3][CONFIG_MAX_EXTDRIVE] VAR16VISIBLE; u8 *bounce_buf_fl VAR16VISIBLE; +struct dpte_s DefaultDPTE VARLOW;
struct drive_s * getDrive(u8 exttype, u8 extdriveoffset) diff --git a/src/blockcmd.h b/src/blockcmd.h index 8459d3e..b45bbb7 100644 --- a/src/blockcmd.h +++ b/src/blockcmd.h @@ -101,6 +101,7 @@ struct cdbres_mode_sense_geom {
// blockcmd.c int cdb_is_read(u8 *cdbcmd, u16 blocksize); +struct disk_op_s; int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data); int cdb_test_unit_ready(struct disk_op_s *op); @@ -111,6 +112,7 @@ int cdb_read(struct disk_op_s *op); int cdb_write(struct disk_op_s *op);
int scsi_is_ready(struct disk_op_s *op); +struct drive_s; int scsi_init_drive(struct drive_s *drive, const char *s, int prio);
#endif // blockcmd.h diff --git a/src/boot.c b/src/boot.c index ef21fe4..7676eb7 100644 --- a/src/boot.c +++ b/src/boot.c @@ -6,7 +6,6 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA #include "config.h" // CONFIG_* #include "disk.h" // cdrom_boot #include "bregs.h" // struct bregs @@ -585,9 +584,8 @@ boot_cdrom(struct drive_s *drive_g) return; }
- u16 ebda_seg = get_ebda_seg(); - u8 bootdrv = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); - u16 bootseg = GET_EBDA2(ebda_seg, cdemu.load_segment); + u8 bootdrv = CDEmu.emulated_extdrive; + u16 bootseg = CDEmu.load_segment; /* Canonicalize bootseg:bootip */ u16 bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; diff --git a/src/cdrom.c b/src/cdrom.c index 170ffc4..f3208b5 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -8,27 +8,30 @@ #include "disk.h" // cdrom_13 #include "util.h" // memset #include "bregs.h" // struct bregs -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_GLOBAL #include "ata.h" // ATA_CMD_REQUEST_SENSE #include "blockcmd.h" // CDB_CMD_REQUEST_SENSE
+// Locks for removable devices +u8 CDRom_locks[CONFIG_MAX_EXTDRIVE] VARLOW; +
/**************************************************************** * CD emulation ****************************************************************/
+struct cdemu_s CDEmu VARLOW; struct drive_s *cdemu_drive_gf VAR16VISIBLE;
static int cdemu_read(struct disk_op_s *op) { - u16 ebda_seg = get_ebda_seg(); struct drive_s *drive_g; - drive_g = GLOBALFLAT2GLOBAL(GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf)); + drive_g = GLOBALFLAT2GLOBAL(GET_LOW(CDEmu.emulated_drive_gf)); struct disk_op_s dop; dop.drive_g = drive_g; dop.command = op->command; - dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) + op->lba / 4; + dop.lba = GET_LOW(CDEmu.ilba) + op->lba / 4;
int count = op->count; op->count = 0; @@ -149,29 +152,27 @@ void cdemu_134b(struct bregs *regs) { // FIXME ElTorito Hardcoded - u16 ebda_seg = get_ebda_seg(); SET_INT13ET(regs, size, 0x13); - SET_INT13ET(regs, media, GET_EBDA2(ebda_seg, cdemu.media)); - SET_INT13ET(regs, emulated_drive - , GET_EBDA2(ebda_seg, cdemu.emulated_extdrive)); - struct drive_s *drive_gf = GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf); + SET_INT13ET(regs, media, GET_LOW(CDEmu.media)); + SET_INT13ET(regs, emulated_drive, GET_LOW(CDEmu.emulated_extdrive)); + struct drive_s *drive_gf = GET_LOW(CDEmu.emulated_drive_gf); u8 cntl_id = 0; if (drive_gf) cntl_id = GET_GLOBALFLAT(drive_gf->cntl_id); SET_INT13ET(regs, controller_index, cntl_id / 2); SET_INT13ET(regs, device_spec, cntl_id % 2); - SET_INT13ET(regs, ilba, GET_EBDA2(ebda_seg, cdemu.ilba)); - SET_INT13ET(regs, buffer_segment, GET_EBDA2(ebda_seg, cdemu.buffer_segment)); - SET_INT13ET(regs, load_segment, GET_EBDA2(ebda_seg, cdemu.load_segment)); - SET_INT13ET(regs, sector_count, GET_EBDA2(ebda_seg, cdemu.sector_count)); - SET_INT13ET(regs, cylinders, GET_EBDA2(ebda_seg, cdemu.lchs.cylinders)); - SET_INT13ET(regs, sectors, GET_EBDA2(ebda_seg, cdemu.lchs.spt)); - SET_INT13ET(regs, heads, GET_EBDA2(ebda_seg, cdemu.lchs.heads)); + SET_INT13ET(regs, ilba, GET_LOW(CDEmu.ilba)); + SET_INT13ET(regs, buffer_segment, GET_LOW(CDEmu.buffer_segment)); + SET_INT13ET(regs, load_segment, GET_LOW(CDEmu.load_segment)); + SET_INT13ET(regs, sector_count, GET_LOW(CDEmu.sector_count)); + SET_INT13ET(regs, cylinders, GET_LOW(CDEmu.lchs.cylinders)); + SET_INT13ET(regs, sectors, GET_LOW(CDEmu.lchs.spt)); + SET_INT13ET(regs, heads, GET_LOW(CDEmu.lchs.heads));
// If we have to terminate emulation if (regs->al == 0x00) { // FIXME ElTorito Various. Should be handled accordingly to spec - SET_EBDA2(ebda_seg, cdemu.active, 0x00); // bye bye + SET_LOW(CDEmu.active, 0x00); // bye bye
// XXX - update floppy/hd count. } @@ -187,6 +188,7 @@ cdemu_134b(struct bregs *regs) int cdrom_boot(struct drive_s *drive_g) { + ASSERT32FLAT(); struct disk_op_s dop; int cdid = getDriveId(EXTTYPE_CD, drive_g); memset(&dop, 0, sizeof(dop)); @@ -202,7 +204,7 @@ cdrom_boot(struct drive_s *drive_g) u8 buffer[2048]; dop.lba = 0x11; dop.count = 1; - dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer); + dop.buf_fl = buffer; ret = cdb_read(&dop); if (ret) return 3; @@ -237,23 +239,22 @@ cdrom_boot(struct drive_s *drive_g) if (buffer[0x20] != 0x88) return 11; // Bootable
- u16 ebda_seg = get_ebda_seg(); u8 media = buffer[0x21]; - SET_EBDA2(ebda_seg, cdemu.media, media); + CDEmu.media = media;
- SET_EBDA2(ebda_seg, cdemu.emulated_drive_gf, dop.drive_g); + CDEmu.emulated_drive_gf = dop.drive_g;
u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) boot_segment = 0x07C0; - SET_EBDA2(ebda_seg, cdemu.load_segment, boot_segment); - SET_EBDA2(ebda_seg, cdemu.buffer_segment, 0x0000); + CDEmu.load_segment = boot_segment; + CDEmu.buffer_segment = 0x0000;
u16 nbsectors = *(u16*)&buffer[0x26]; - SET_EBDA2(ebda_seg, cdemu.sector_count, nbsectors); + CDEmu.sector_count = nbsectors;
lba = *(u32*)&buffer[0x28]; - SET_EBDA2(ebda_seg, cdemu.ilba, lba); + CDEmu.ilba = lba;
// And we read the image in memory dop.lba = lba; @@ -265,7 +266,7 @@ cdrom_boot(struct drive_s *drive_g)
if (media == 0) { // No emulation requested - return success. - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, EXTSTART_CD + cdid); + CDEmu.emulated_extdrive = EXTSTART_CD + cdid; return 0; }
@@ -277,30 +278,30 @@ cdrom_boot(struct drive_s *drive_g) // number of devices if (media < 4) { // Floppy emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x00); + CDEmu.emulated_extdrive = 0x00; // XXX - get and set actual floppy count. SETBITS_BDA(equipment_list_flags, 0x41);
switch (media) { case 0x01: // 1.2M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 15); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 15; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; case 0x02: // 1.44M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 18); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 18; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; case 0x03: // 2.88M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 36); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 36; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; } } else { // Harddrive emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x80); + CDEmu.emulated_extdrive = 0x80; SET_BDA(hdcount, GET_BDA(hdcount) + 1);
// Peak at partition table to get chs. @@ -309,14 +310,13 @@ cdrom_boot(struct drive_s *drive_g) u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow); u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads);
- SET_EBDA2(ebda_seg, cdemu.lchs.spt, sptcyl & 0x3f); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders - , ((sptcyl<<2)&0x300) + cyllow + 1); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, heads + 1); + CDEmu.lchs.spt = sptcyl & 0x3f; + CDEmu.lchs.cylinders = ((sptcyl<<2)&0x300) + cyllow + 1; + CDEmu.lchs.heads = heads + 1; }
// everything is ok, so from now on, the emulation is active - SET_EBDA2(ebda_seg, cdemu.active, 0x01); + CDEmu.active = 0x01; dprintf(6, "cdemu media=%d\n", media);
return 0; diff --git a/src/coreboot.c b/src/coreboot.c index 4ae44e5..e116a14 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -6,10 +6,11 @@
#include "memmap.h" // add_e820 #include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA #include "lzmadecode.h" // LzmaDecode #include "smbios.h" // smbios_init #include "boot.h" // boot_add_cbfs +#include "disk.h" // MAXDESCSIZE +#include "config.h" // CONFIG_*
/**************************************************************** diff --git a/src/disk.c b/src/disk.c index 706b9f4..9f02a21 100644 --- a/src/disk.c +++ b/src/disk.c @@ -60,14 +60,13 @@ fillLCHS(struct drive_s *drive_g, u16 *nlc, u16 *nlh, u16 *nlspt) { if (CONFIG_CDROM_EMU && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) { - // Emulated drive - get info from ebda. (It's not possible to + // Emulated drive - get info from CDEmu. (It's not possible to // populate the geometry directly in the driveid because the // geometry is only known after the bios segment is made // read-only). - u16 ebda_seg = get_ebda_seg(); - *nlc = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders); - *nlh = GET_EBDA2(ebda_seg, cdemu.lchs.heads); - *nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt); + *nlc = GET_LOW(CDEmu.lchs.cylinders); + *nlh = GET_LOW(CDEmu.lchs.heads); + *nlspt = GET_LOW(CDEmu.lchs.spt); return; } *nlc = GET_GLOBAL(drive_g->lchs.cylinders); @@ -231,7 +230,6 @@ disk_1305(struct bregs *regs, struct drive_s *drive_g) static void noinline disk_1308(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); // Get logical geometry from table u16 nlc, nlh, nlspt; fillLCHS(drive_g, &nlc, &nlh, &nlspt); @@ -244,7 +242,7 @@ disk_1308(struct bregs *regs, struct drive_s *drive_g)
if (CONFIG_CDROM_EMU && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) - regs->bx = GET_EBDA2(ebda_seg, cdemu.media) * 2; + regs->bx = GET_LOW(CDEmu.media) * 2; else regs->bx = GET_GLOBAL(drive_g->floppy_type);
@@ -261,8 +259,8 @@ disk_1308(struct bregs *regs, struct drive_s *drive_g) return; }
- if (CONFIG_CDROM_EMU && GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); + if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.active)) { + u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); if (((emudrive ^ regs->dl) & 0x80) == 0) // Note extra drive due to emulation. count++; @@ -397,15 +395,14 @@ disk_1344(struct bregs *regs, struct drive_s *drive_g) static void disk_134500(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks == 0xff) { regs->al = 1; disk_ret(regs, DISK_RET_ETOOMANYLOCKS); return; } - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks + 1); + SET_LOW(CDRom_locks[cdid], locks + 1); regs->al = 1; disk_ret(regs, DISK_RET_SUCCESS); } @@ -414,16 +411,15 @@ disk_134500(struct bregs *regs, struct drive_s *drive_g) static void disk_134501(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks == 0x00) { regs->al = 0; disk_ret(regs, DISK_RET_ENOTLOCKED); return; } locks--; - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks); + SET_LOW(CDRom_locks[cdid], locks); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -433,7 +429,7 @@ static void disk_134502(struct bregs *regs, struct drive_s *drive_g) { int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -473,7 +469,7 @@ disk_1346(struct bregs *regs, struct drive_s *drive_g) }
int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks != 0) { disk_ret(regs, DISK_RET_ELOCKED); return; @@ -565,11 +561,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) u8 channel = 0; SET_INT13DPT(regs, size, 30); if (type == DTYPE_ATA || type == DTYPE_ATAPI) { - u16 ebda_seg = get_ebda_seg(); - - SET_INT13DPT(regs, dpte_segment, ebda_seg); - SET_INT13DPT(regs, dpte_offset - , offsetof(struct extended_bios_data_area_s, dpte)); + SET_INT13DPT(regs, dpte, SEGOFF(SEG_LOW, (u32)&DefaultDPTE));
// Fill in dpte struct atadrive_s *adrive_g = container_of( @@ -602,25 +594,23 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) if (CONFIG_ATA_PIO32) options |= 1<<7;
- SET_EBDA2(ebda_seg, dpte.iobase1, iobase1); - SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC); - SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) - | ATA_CB_DH_LBA)); - SET_EBDA2(ebda_seg, dpte.unused, 0xcb); - SET_EBDA2(ebda_seg, dpte.irq, irq); - SET_EBDA2(ebda_seg, dpte.blkcount, 1); - SET_EBDA2(ebda_seg, dpte.dma, 0); - SET_EBDA2(ebda_seg, dpte.pio, 0); - SET_EBDA2(ebda_seg, dpte.options, options); - SET_EBDA2(ebda_seg, dpte.reserved, 0); - SET_EBDA2(ebda_seg, dpte.revision, 0x11); - - u8 sum = checksum_far( - ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); - SET_EBDA2(ebda_seg, dpte.checksum, -sum); + SET_LOW(DefaultDPTE.iobase1, iobase1); + SET_LOW(DefaultDPTE.iobase2, iobase2 + ATA_CB_DC); + SET_LOW(DefaultDPTE.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) + | ATA_CB_DH_LBA)); + SET_LOW(DefaultDPTE.unused, 0xcb); + SET_LOW(DefaultDPTE.irq, irq); + SET_LOW(DefaultDPTE.blkcount, 1); + SET_LOW(DefaultDPTE.dma, 0); + SET_LOW(DefaultDPTE.pio, 0); + SET_LOW(DefaultDPTE.options, options); + SET_LOW(DefaultDPTE.reserved, 0); + SET_LOW(DefaultDPTE.revision, 0x11); + + u8 sum = checksum_far(SEG_LOW, &DefaultDPTE, 15); + SET_LOW(DefaultDPTE.checksum, -sum); } else { - SET_INT13DPT(regs, dpte_segment, 0); - SET_INT13DPT(regs, dpte_offset, 0); + SET_INT13DPT(regs, dpte.segoff, 0); bdf = GET_GLOBAL(drive_g->cntl_id); }
@@ -866,9 +856,8 @@ handle_13(struct bregs *regs) cdemu_134b(regs); return; } - u16 ebda_seg = get_ebda_seg(); - if (GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); + if (GET_LOW(CDEmu.active)) { + u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); if (extdrive == emudrive) { // Access to an emulated drive. struct drive_s *cdemu_g; diff --git a/src/disk.h b/src/disk.h index a675aeb..6c7d8fe 100644 --- a/src/disk.h +++ b/src/disk.h @@ -45,6 +45,24 @@ struct int13ext_s { #define SET_INT13EXT(regs,var,val) \ SET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var, (val))
+// DPTE definition +struct dpte_s { + u16 iobase1; + u16 iobase2; + u8 prefix; + u8 unused; + u8 irq; + u8 blkcount; + u8 dma; + u8 pio; + u16 options; + u16 reserved; + u8 revision; + u8 checksum; +}; + +extern struct dpte_s DefaultDPTE; + // Disk Physical Table definition struct int13dpt_s { u16 size; @@ -54,8 +72,7 @@ struct int13dpt_s { u32 spt; u64 sector_count; u16 blksize; - u16 dpte_offset; - u16 dpte_segment; + struct segoff_s dpte; u16 key; u8 dpi_length; u8 reserved1; @@ -181,6 +198,21 @@ struct chs_s { u16 spt; // # sectors / track };
+// ElTorito Device Emulation data +struct cdemu_s { + struct drive_s *emulated_drive_gf; + u32 ilba; + u16 buffer_segment; + u16 load_segment; + u16 sector_count; + u8 active; + u8 media; + u8 emulated_extdrive; + + // Virtual device + struct chs_s lchs; +}; + struct drive_s { u8 type; // Driver type (DTYPE_*) u8 floppy_type; // Type of floppy (only for floppy drives). @@ -249,6 +281,8 @@ int process_floppy_op(struct disk_op_s *op); void floppy_tick(void);
// cdrom.c +extern u8 CDRom_locks[]; +extern struct cdemu_s CDEmu; extern struct drive_s *cdemu_drive_gf; int process_cdemu_op(struct disk_op_s *op); void cdemu_setup(void);