// INT 13h Fixed Disk Services Entry Point void VISIBLE16 handle_13(struct bregs *regs) { debug_enter(regs, DEBUG_HDL_13); u8 extdrive = regs->dl; if (CONFIG_CDROM_EMU) { if (regs->ah == 0x4b) { 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 (extdrive == emudrive) { // Access to an emulated drive. struct drive_s *cdemu = GET_GLOBAL(cdemu_drive); if (regs->ah > 0x16) { // Only old-style commands supported. disk_13XX(regs, cdemu); return; } disk_13(regs, cdemu); return; } if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) // Adjust id to make room for emulated drive. extdrive--; } } handle_legacy_disk(regs, extdrive); }
// read disk drive parameters 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); nlc--; nlh--; u8 count; if (regs->dl < EXTSTART_HD) { // Floppy count = GET_GLOBAL(FloppyCount); if (CONFIG_CDROM_EMU && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) regs->bx = GET_EBDA2(ebda_seg, cdemu.media) * 2; else regs->bx = GET_GLOBAL(drive_g->floppy_type); // set es & di to point to 11 byte diskette param table in ROM regs->es = SEG_BIOS; regs->di = (u32)&diskette_param_table2; } else if (regs->dl < EXTSTART_CD) { // Hard drive count = GET_BDA(hdcount); nlc--; // last sector reserved } else { // Not supported on CDROM disk_ret(regs, DISK_RET_EPARAM); return; } if (CONFIG_CDROM_EMU && GET_EBDA2(ebda_seg, cdemu.active)) { u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); if (((emudrive ^ regs->dl) & 0x80) == 0) // Note extra drive due to emulation. count++; if (regs->dl < EXTSTART_HD && count > 2) // Max of two floppy drives. count = 2; } regs->al = 0; regs->ch = nlc & 0xff; regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f); regs->dh = nlh; disk_ret(regs, DISK_RET_SUCCESS); regs->dl = count; }
static void fillLCHS(struct drive_s *drive_g, u16 *nlc, u16 *nlh, u16 *nlspt) { if (CONFIG_CDROM_EMU && drive_g == GET_GLOBAL(cdemu_drive)) { // Emulated drive - get info from ebda. (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); return; } *nlc = GET_GLOBAL(drive_g->lchs.cylinders); *nlh = GET_GLOBAL(drive_g->lchs.heads); *nlspt = GET_GLOBAL(drive_g->lchs.spt); }
// lock 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]); if (locks == 0xff) { regs->al = 1; disk_ret(regs, DISK_RET_ETOOMANYLOCKS); return; } SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks + 1); regs->al = 1; disk_ret(regs, DISK_RET_SUCCESS); }
// unlock 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]); if (locks == 0x00) { regs->al = 0; disk_ret(regs, DISK_RET_ENOTLOCKED); return; } locks--; SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); }