Esempio n. 1
0
static int
cdemu_read(struct disk_op_s *op)
{
    struct drive_s *drive_g;
    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_LOW(CDEmu.ilba) + op->lba / 4;

    int count = op->count;
    op->count = 0;
    u8 *cdbuf_fl = GET_GLOBAL(bounce_buf_fl);

    if (op->lba & 3) {
        // Partial read of first block.
        dop.count = 1;
        dop.buf_fl = cdbuf_fl;
        int ret = process_op(&dop);
        if (ret)
            return ret;
        u8 thiscount = 4 - (op->lba & 3);
        if (thiscount > count)
            thiscount = count;
        count -= thiscount;
        memcpy_fl(op->buf_fl, cdbuf_fl + (op->lba & 3) * 512, thiscount * 512);
        op->buf_fl += thiscount * 512;
        op->count += thiscount;
        dop.lba++;
    }

    if (count > 3) {
        // Read n number of regular blocks.
        dop.count = count / 4;
        dop.buf_fl = op->buf_fl;
        int ret = process_op(&dop);
        op->count += dop.count * 4;
        if (ret)
            return ret;
        u8 thiscount = count & ~3;
        count &= 3;
        op->buf_fl += thiscount * 512;
        dop.lba += thiscount / 4;
    }

    if (count) {
        // Partial read on last block.
        dop.count = 1;
        dop.buf_fl = cdbuf_fl;
        int ret = process_op(&dop);
        if (ret)
            return ret;
        u8 thiscount = count;
        memcpy_fl(op->buf_fl, cdbuf_fl, thiscount * 512);
        op->count += thiscount;
    }

    return DISK_RET_SUCCESS;
}
Esempio n. 2
0
File: block.c Progetto: 3a9LL/panda
struct drive_s *
getDrive(u8 exttype, u8 extdriveoffset)
{
    if (extdriveoffset >= ARRAY_SIZE(IDMap[0]))
        return NULL;
    struct drive_s *drive_gf = GET_GLOBAL(IDMap[exttype][extdriveoffset]);
    if (!drive_gf)
        return NULL;
    return GLOBALFLAT2GLOBAL(drive_gf);
}
Esempio n. 3
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;
}
Esempio n. 4
0
// Get the cylinders/heads/sectors for the given drive.
static void
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
        // 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);
}
Esempio n. 5
0
// Get the cylinders/heads/sectors for the given drive.
static struct chs_s
getLCHS(struct drive_s *drive_g)
{
    struct chs_s res = { };
    if (CONFIG_CDROM_EMU
        && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) {
        // 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).
        res.cylinders = GET_LOW(CDEmu.lchs.cylinders);
        res.heads = GET_LOW(CDEmu.lchs.heads);
        res.spt = GET_LOW(CDEmu.lchs.spt);
        return res;
    }
    res.cylinders = GET_GLOBAL(drive_g->lchs.cylinders);
    res.heads = GET_GLOBAL(drive_g->lchs.heads);
    res.spt = GET_GLOBAL(drive_g->lchs.spt);
    return res;
}