Store the fields necessary to export the "el-torito" spec information directly in an internal copy of the "el-torito" struct. This simplifies the interface and obviates the need for an internal home grown struct with the same info.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/block.h | 15 ------------ src/boot.c | 2 +- src/cdrom.c | 72 ++++++++++++++++++++-------------------------------------- src/disk.c | 15 ++++++------ src/std/disk.h | 8 +++---- src/util.h | 2 +- 6 files changed, 38 insertions(+), 76 deletions(-)
diff --git a/src/block.h b/src/block.h index c870e13..945e6fe 100644 --- a/src/block.h +++ b/src/block.h @@ -36,21 +36,6 @@ struct chs_s { u16 pad; };
-// 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). diff --git a/src/boot.c b/src/boot.c index 133e206..9be8b2a 100644 --- a/src/boot.c +++ b/src/boot.c @@ -643,7 +643,7 @@ boot_cdrom(struct drive_s *drive_g) return; }
- u8 bootdrv = CDEmu.emulated_extdrive; + u8 bootdrv = CDEmu.emulated_drive; u16 bootseg = CDEmu.load_segment; /* Canonicalize bootseg:bootip */ u16 bootip = (bootseg & 0x0fff) << 4; diff --git a/src/cdrom.c b/src/cdrom.c index ff419c0..f0d8a1a 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -24,13 +24,14 @@ u8 CDRom_locks[BUILD_MAX_EXTDRIVE] VARLOW; * CD emulation ****************************************************************/
-struct cdemu_s CDEmu VARLOW; +struct eltorito_s CDEmu VARLOW = { .size=sizeof(CDEmu) }; +struct drive_s *emulated_drive_gf VARLOW; struct drive_s *cdemu_drive_gf VARFSEG;
static int cdemu_read(struct disk_op_s *op) { - struct drive_s *drive_gf = GET_LOW(CDEmu.emulated_drive_gf); + struct drive_s *drive_gf = GET_LOW(emulated_drive_gf); struct disk_op_s dop; dop.drive_gf = drive_gf; dop.command = op->command; @@ -131,35 +132,16 @@ cdrom_prepboot(void) drive->sectors = (u64)-1; }
-#define SET_INT13ET(regs,var,val) \ - SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val)) - // ElTorito - Terminate disk emu void cdemu_134b(struct bregs *regs) { - // FIXME ElTorito Hardcoded - SET_INT13ET(regs, size, 0x13); - 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_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.cylinder)); - SET_INT13ET(regs, sectors, GET_LOW(CDEmu.lchs.sector)); - SET_INT13ET(regs, heads, GET_LOW(CDEmu.lchs.head)); + memcpy_far(regs->ds, (void*)(regs->si+0), SEG_LOW, &CDEmu, sizeof(CDEmu));
// If we have to terminate emulation if (regs->al == 0x00) { // FIXME ElTorito Various. Should be handled accordingly to spec - SET_LOW(CDEmu.active, 0x00); // bye bye + SET_LOW(CDEmu.media, 0x00); // bye bye
// XXX - update floppy/hd count. } @@ -226,10 +208,9 @@ cdrom_boot(struct drive_s *drive) if (buffer[0x20] != 0x88) return 11; // Bootable
+ // Fill in el-torito cdrom emulation fields. + emulated_drive_gf = drive; u8 media = buffer[0x21]; - CDEmu.media = media; - - CDEmu.emulated_drive_gf = dop.drive_gf;
u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) @@ -243,6 +224,9 @@ cdrom_boot(struct drive_s *drive) lba = *(u32*)&buffer[0x28]; CDEmu.ilba = lba;
+ CDEmu.controller_index = drive->cntl_id / 2; + CDEmu.device_spec = drive->cntl_id % 2; + // And we read the image in memory dop.lba = lba; dop.count = DIV_ROUND_UP(nbsectors, 4); @@ -253,7 +237,7 @@ cdrom_boot(struct drive_s *drive)
if (media == 0) { // No emulation requested - return success. - CDEmu.emulated_extdrive = EXTSTART_CD + cdid; + CDEmu.emulated_drive = EXTSTART_CD + cdid; return 0; }
@@ -265,45 +249,39 @@ cdrom_boot(struct drive_s *drive) // number of devices if (media < 4) { // Floppy emulation - CDEmu.emulated_extdrive = 0x00; + CDEmu.emulated_drive = 0x00; // XXX - get and set actual floppy count. set_equipment_flags(0x41, 0x41);
switch (media) { case 0x01: // 1.2M floppy - CDEmu.lchs.sector = 15; - CDEmu.lchs.cylinder = 80; - CDEmu.lchs.head = 2; + CDEmu.chs.sptcyl = 15; + CDEmu.chs.cyllow = 79; + CDEmu.chs.heads = 1; break; case 0x02: // 1.44M floppy - CDEmu.lchs.sector = 18; - CDEmu.lchs.cylinder = 80; - CDEmu.lchs.head = 2; + CDEmu.chs.sptcyl = 18; + CDEmu.chs.cyllow = 79; + CDEmu.chs.heads = 1; break; case 0x03: // 2.88M floppy - CDEmu.lchs.sector = 36; - CDEmu.lchs.cylinder = 80; - CDEmu.lchs.head = 2; + CDEmu.chs.sptcyl = 36; + CDEmu.chs.cyllow = 79; + CDEmu.chs.heads = 1; break; } } else { // Harddrive emulation - CDEmu.emulated_extdrive = 0x80; + CDEmu.emulated_drive = 0x80; SET_BDA(hdcount, GET_BDA(hdcount) + 1);
// Peak at partition table to get chs. - struct mbr_s *mbr = (void*)0; - u8 sptcyl = GET_FARVAR(boot_segment, mbr->partitions[0].last.sptcyl); - u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow); - u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads); - - CDEmu.lchs.sector = sptcyl & 0x3f; - CDEmu.lchs.cylinder = ((sptcyl<<2)&0x300) + cyllow + 1; - CDEmu.lchs.head = heads + 1; + struct mbr_s *mbr = MAKE_FLATPTR(boot_segment, 0); + CDEmu.chs = mbr->partitions[0].last; }
// everything is ok, so from now on, the emulation is active - CDEmu.active = 0x01; + CDEmu.media = media; dprintf(6, "cdemu media=%d\n", media);
return 0; diff --git a/src/disk.c b/src/disk.c index 7e42103..635d7b9 100644 --- a/src/disk.c +++ b/src/disk.c @@ -41,9 +41,10 @@ getLCHS(struct drive_s *drive_gf) // populate the geometry directly in the driveid because the // geometry is only known after the bios segment is made // read-only). - res.cylinder = GET_LOW(CDEmu.lchs.cylinder); - res.head = GET_LOW(CDEmu.lchs.head); - res.sector = GET_LOW(CDEmu.lchs.sector); + u8 sptcyl = GET_LOW(CDEmu.chs.sptcyl); + res.cylinder = GET_LOW(CDEmu.chs.cyllow) + ((sptcyl << 2) & 0x300) + 1; + res.head = GET_LOW(CDEmu.chs.heads) + 1; + res.sector = sptcyl & 0x3f; return res; } res.cylinder = GET_GLOBALFLAT(drive_gf->lchs.cylinder); @@ -238,8 +239,8 @@ disk_1308(struct bregs *regs, struct drive_s *drive_gf) return; }
- if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.active)) { - u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); + if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)) { + u8 emudrive = GET_LOW(CDEmu.emulated_drive); if (((emudrive ^ regs->dl) & 0x80) == 0) // Note extra drive due to emulation. count++; @@ -663,8 +664,8 @@ handle_13(struct bregs *regs) cdemu_134b(regs); return; } - if (GET_LOW(CDEmu.active)) { - u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); + if (GET_LOW(CDEmu.media)) { + u8 emudrive = GET_LOW(CDEmu.emulated_drive); if (extdrive == emudrive) { // Access to an emulated drive. struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf); diff --git a/src/std/disk.h b/src/std/disk.h index b2576d9..6397108 100644 --- a/src/std/disk.h +++ b/src/std/disk.h @@ -129,7 +129,7 @@ struct packed_chs_s { u8 heads; u8 sptcyl; u8 cyllow; -}; +} PACKED;
struct partition_s { u8 status; @@ -169,9 +169,7 @@ struct eltorito_s { u16 buffer_segment; u16 load_segment; u16 sector_count; - u8 cylinders; - u8 sectors; - u8 heads; -}; + struct packed_chs_s chs; +} PACKED;
#endif // disk.h diff --git a/src/util.h b/src/util.h index b54271b..74b58f4 100644 --- a/src/util.h +++ b/src/util.h @@ -44,7 +44,7 @@ void disable_bootsplash(void);
// cdrom.c extern u8 CDRom_locks[]; -extern struct cdemu_s CDEmu; +extern struct eltorito_s CDEmu; extern struct drive_s *cdemu_drive_gf; struct disk_op_s; int process_cdemu_op(struct disk_op_s *op);