// Perform read/write/verify using new-style "int13ext" accesses. static void noinline extended_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; // Get lba and check. dop.lba = GET_INT13EXT(regs, lba); dop.command = command; dop.drive_g = drive_g; if (dop.lba >= GET_GLOBAL(drive_g->sectors)) { warn_invalid(regs); disk_ret(regs, DISK_RET_EPARAM); return; } dop.buf_fl = SEGOFF_TO_FLATPTR(GET_INT13EXT(regs, data)); dop.count = GET_INT13EXT(regs, count); if (! dop.count) { // Nothing to do. disk_ret(regs, DISK_RET_SUCCESS); return; } int status = send_disk_op(&dop); SET_INT13EXT(regs, count, dop.count); disk_ret(regs, status); }
// format disk track static void disk_1305(struct bregs *regs, struct drive_s *drive_g) { debug_stub(regs); u16 nlc, nlh, nlspt; fillLCHS(drive_g, &nlc, &nlh, &nlspt); u8 num_sectors = regs->al; u8 head = regs->dh; if (head >= nlh || num_sectors == 0 || num_sectors > nlspt) { disk_ret(regs, DISK_RET_EPARAM); return; } struct disk_op_s dop; dop.drive_g = drive_g; dop.command = CMD_FORMAT; dop.lba = head; dop.count = num_sectors; dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); int status = send_disk_op(&dop); disk_ret(regs, status); }
// format disk track static void noinline disk_1305(struct bregs *regs, struct drive_s *drive_gf) { debug_stub(regs); struct chs_s chs = getLCHS(drive_gf); u16 nlc=chs.cylinder, nlh=chs.head, nls=chs.sector; u8 count = regs->al; u8 cylinder = regs->ch; u8 head = regs->dh; if (cylinder >= nlc || head >= nlh || count == 0 || count > nls) { disk_ret(regs, DISK_RET_EPARAM); return; } struct disk_op_s dop; dop.drive_gf = drive_gf; dop.command = CMD_FORMAT; dop.lba = (((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nls; dop.count = count; dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); int status = send_disk_op(&dop); disk_ret(regs, status); }
// Perform read/write/verify using new-style "int13ext" accesses. static void noinline extended_access(struct bregs *regs, struct drive_s *drive_gf, u16 command) { struct disk_op_s dop; struct int13ext_s *param_far = (struct int13ext_s*)(regs->si+0); // Get lba and check. dop.lba = GET_FARVAR(regs->ds, param_far->lba); dop.command = command; dop.drive_gf = drive_gf; if (dop.lba >= GET_GLOBALFLAT(drive_gf->sectors)) { warn_invalid(regs); disk_ret(regs, DISK_RET_EPARAM); return; } dop.buf_fl = SEGOFF_TO_FLATPTR(GET_FARVAR(regs->ds, param_far->data)); dop.count = GET_FARVAR(regs->ds, param_far->count); if (! dop.count) { // Nothing to do. disk_ret(regs, DISK_RET_SUCCESS); return; } int status = send_disk_op(&dop); SET_FARVAR(regs->ds, param_far->count, dop.count); disk_ret(regs, status); }
// disk controller reset static void disk_1300(struct bregs *regs, struct drive_s *drive_g) { struct disk_op_s dop; dop.drive_g = drive_g; dop.command = CMD_RESET; int status = send_disk_op(&dop); disk_ret(regs, status); }
// check drive ready static void disk_1310(struct bregs *regs, struct drive_s *drive_g) { // should look at 40:8E also??? struct disk_op_s dop; dop.drive_g = drive_g; dop.command = CMD_ISREADY; int status = send_disk_op(&dop); disk_ret(regs, status); }
// Perform read/write/verify using old-style chs accesses static void basic_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; dop.drive_g = drive_g; dop.command = command; u8 count = regs->al; u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300); u16 sector = regs->cl & 0x3f; u16 head = regs->dh; if (count > 128 || count == 0 || sector == 0) { dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n" , regs->ah); disk_ret(regs, DISK_RET_EPARAM); return; } dop.count = count; u16 nlc, nlh, nlspt; fillLCHS(drive_g, &nlc, &nlh, &nlspt); // sanity check on cyl heads, sec if (cylinder >= nlc || head >= nlh || sector > nlspt) { dprintf(1, "int13_harddisk: function %02x, parameters out of" " range %04x/%04x/%04x!\n" , regs->ah, cylinder, head, sector); disk_ret(regs, DISK_RET_EPARAM); return; } // translate lchs to lba dop.lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt) + (u32)sector - 1); dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); int status = send_disk_op(&dop); regs->al = dop.count; disk_ret(regs, status); }
// Perform read/write/verify using old-style chs accesses static void noinline basic_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; dop.drive_g = drive_g; dop.command = command; u8 count = regs->al; u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300); u16 sector = regs->cl & 0x3f; u16 head = regs->dh; if (count > 128 || count == 0 || sector == 0) { warn_invalid(regs); disk_ret(regs, DISK_RET_EPARAM); return; } dop.count = count; u16 nlc, nlh, nlspt; fillLCHS(drive_g, &nlc, &nlh, &nlspt); // sanity check on cyl heads, sec if (cylinder >= nlc || head >= nlh || sector > nlspt) { warn_invalid(regs); disk_ret(regs, DISK_RET_EPARAM); return; } // translate lchs to lba dop.lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt) + (u32)sector - 1); dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); int status = send_disk_op(&dop); regs->al = dop.count; disk_ret(regs, status); }
// Perform read/write/verify using new-style "int13ext" accesses. static void extended_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; // Get lba and check. dop.lba = GET_INT13EXT(regs, lba); dop.command = command; dop.drive_g = drive_g; if (dop.lba >= GET_GLOBAL(drive_g->sectors)) { dprintf(1, "int13_harddisk: function %02x. LBA out of range\n" , regs->ah); disk_ret(regs, DISK_RET_EPARAM); return; } dop.buf_fl = SEGOFF_TO_FLATPTR(GET_INT13EXT(regs, data)); dop.count = GET_INT13EXT(regs, count); int status = send_disk_op(&dop); SET_INT13EXT(regs, count, dop.count); disk_ret(regs, status); }