Exemplo n.º 1
0
Arquivo: disk.c Projeto: joshsyu/PQEMU
// 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);
}
Exemplo n.º 2
0
// 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;
}
Exemplo n.º 3
0
Arquivo: disk.c Projeto: joshsyu/PQEMU
// 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);
}
Exemplo n.º 4
0
// 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);
}
Exemplo n.º 5
0
Arquivo: disk.c Projeto: joshsyu/PQEMU
// read disk drive size
static void
disk_1315(struct bregs *regs, struct drive_s *drive_g)
{
    disk_ret(regs, DISK_RET_SUCCESS);
    if (regs->dl < EXTSTART_HD || regs->dl >= EXTSTART_CD) {
        // Floppy or cdrom
        regs->ah = 1;
        return;
    }
    // Hard drive

    // Get logical geometry from table
    u16 nlc, nlh, nlspt;
    fillLCHS(drive_g, &nlc, &nlh, &nlspt);

    // Compute sector count seen by int13
    u32 lba = (u32)(nlc - 1) * (u32)nlh * (u32)nlspt;
    regs->cx = lba >> 16;
    regs->dx = lba & 0xffff;
    regs->ah = 3; // hard disk accessible
}