Esempio n. 1
0
// get extended keyboard status
static void
handle_1612(struct bregs *regs)
{
    yield();
    regs->ax = ((GET_BDA(kbd_flag0) & ~((KF1_RCTRL|KF1_RALT) << 8))
                | ((GET_BDA(kbd_flag1) & (KF1_RCTRL|KF1_RALT)) << 8));
    //BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX);
}
Esempio n. 2
0
// get extended keyboard status
static void
handle_1612(struct bregs *regs)
{
    regs->al = GET_BDA(kbd_flag0);
    regs->ah = ((GET_BDA(kbd_flag1) & ~(KF2_RCTRL|KF2_RALT))
                | (GET_BDA(kbd_flag2) & (KF2_RCTRL|KF2_RALT)));
    //BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX);
}
Esempio n. 3
0
static void
dequeue_key(struct bregs *regs, int incr, int extended)
{
    yield();
    u16 buffer_head;
    u16 buffer_tail;
    for (;;) {
        buffer_head = GET_BDA(kbd_buf_head);
        buffer_tail = GET_BDA(kbd_buf_tail);

        if (buffer_head != buffer_tail)
            break;
        if (!incr) {
            regs->flags |= F_ZF;
            return;
        }
        yield_toirq();
    }

    u16 keycode = GET_FARVAR(SEG_BDA, *(u16*)(buffer_head+0));
    u8 ascii = keycode & 0xff;
    if (!extended) {
        // Translate extended keys
        if (ascii == 0xe0 && keycode & 0xff00)
            keycode &= 0xff00;
        else if (keycode == 0xe00d || keycode == 0xe00a)
            // Extended enter key
            keycode = 0x1c00 | ascii;
        else if (keycode == 0xe02f)
            // Extended '/' key
            keycode = 0x352f;
        // Technically, if the ascii value is 0xf0 or if the
        // 'scancode' is greater than 0x84 then the key should be
        // discarded.  However, there seems no harm in passing on the
        // extended values in these cases.
    }
    if (ascii == 0xf0 && keycode & 0xff00)
        keycode &= 0xff00;
    regs->ax = keycode;

    if (!incr) {
        regs->flags &= ~F_ZF;
        return;
    }
    u16 buffer_start = GET_BDA(kbd_buf_start_offset);
    u16 buffer_end   = GET_BDA(kbd_buf_end_offset);

    buffer_head += 2;
    if (buffer_head >= buffer_end)
        buffer_head = buffer_start;
    SET_BDA(kbd_buf_head, buffer_head);
}
Esempio n. 4
0
File: disk.c Progetto: joshsyu/PQEMU
// read disk status
static void
disk_1301(struct bregs *regs, struct drive_s *drive_g)
{
    u8 v;
    if (regs->dl < EXTSTART_HD)
        // Floppy
        v = GET_BDA(floppy_last_status);
    else
        v = GET_BDA(disk_last_status);
    regs->ah = v;
    set_cf(regs, v);
    // XXX - clear disk_last_status?
}
Esempio n. 5
0
void VISIBLE16
vbe_104f05(struct bregs *regs)
{
    if (regs->bh > 1 || regs->bl > 1)
        goto fail;
    if (GET_BDA(vbe_mode) & MF_LINEARFB) {
        regs->ah = VBE_RETURN_STATUS_INVALID;
        return;
    }
    struct vgamode_s *vmode_g = get_current_mode();
    if (! vmode_g)
        goto fail;
    if (regs->bh) {
        int ret = vgahw_get_window(vmode_g, regs->bl);
        if (ret < 0)
            goto fail;
        regs->dx = ret;
        regs->ax = 0x004f;
        return;
    }
    int ret = vgahw_set_window(vmode_g, regs->bl, regs->dx);
    if (ret)
        goto fail;
    regs->ax = 0x004f;
    return;
fail:
    regs->ax = 0x014f;
}
Esempio n. 6
0
static void
vbe_104f03(struct bregs *regs)
{
    regs->bx = GET_BDA(vbe_mode);
    dprintf(1, "VBE current mode=%x\n", regs->bx);
    regs->ax = 0x004f;
}
Esempio n. 7
0
static u8
enqueue_key(u16 keycode)
{
    u16 buffer_start = GET_BDA(kbd_buf_start_offset);
    u16 buffer_end   = GET_BDA(kbd_buf_end_offset);

    u16 buffer_head = GET_BDA(kbd_buf_head);
    u16 buffer_tail = GET_BDA(kbd_buf_tail);

    u16 temp_tail = buffer_tail;
    buffer_tail += 2;
    if (buffer_tail >= buffer_end)
        buffer_tail = buffer_start;

    if (buffer_tail == buffer_head)
        return 0;

    SET_FARVAR(SEG_BDA, *(u16*)(temp_tail+0), keycode);
    SET_BDA(kbd_buf_tail, buffer_tail);
    return 1;
}
Esempio n. 8
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. 9
0
static void
dequeue_key(struct bregs *regs, int incr, int extended)
{
    yield();
    u16 buffer_head;
    u16 buffer_tail;
    for (;;) {
        buffer_head = GET_BDA(kbd_buf_head);
        buffer_tail = GET_BDA(kbd_buf_tail);

        if (buffer_head != buffer_tail)
            break;
        if (!incr) {
            regs->flags |= F_ZF;
            return;
        }
        yield_toirq();
    }

    u8 ascii_code = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+0));
    u8 scan_code  = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+1));
    if ((ascii_code == 0xF0 && scan_code != 0)
        || (ascii_code == 0xE0 && !extended))
        ascii_code = 0;
    regs->ax = (scan_code << 8) | ascii_code;

    if (!incr) {
        regs->flags &= ~F_ZF;
        return;
    }
    u16 buffer_start = GET_BDA(kbd_buf_start_offset);
    u16 buffer_end   = GET_BDA(kbd_buf_end_offset);

    buffer_head += 2;
    if (buffer_head >= buffer_end)
        buffer_head = buffer_start;
    SET_BDA(kbd_buf_head, buffer_head);
}
Esempio n. 10
0
static void
vbe_104f10(struct bregs *regs)
{
    switch (regs->bl) {
    case 0x00:
        regs->bx = 0x0f30;
        break;
    case 0x01:
        SET_BDA(vbe_flag, regs->bh);
        break;
    case 0x02:
        regs->bh = GET_BDA(vbe_flag);
        break;
    default:
        regs->ax = 0x014f;
        return;
    }
    regs->ax = 0x004f;
}
Esempio n. 11
0
int
cdrom_boot(struct drive_s *drive_g)
{
    ASSERT32FLAT();
    struct disk_op_s dop;
    int cdid = getDriveId(EXTTYPE_CD, drive_g);
    memset(&dop, 0, sizeof(dop));
    dop.drive_g = drive_g;
    if (!dop.drive_g || cdid < 0)
        return 1;

    int ret = scsi_is_ready(&dop);
    if (ret)
        dprintf(1, "scsi_is_ready returned %d\n", ret);

    // Read the Boot Record Volume Descriptor
    u8 buffer[CDROM_SECTOR_SIZE];
    dop.lba = 0x11;
    dop.count = 1;
    dop.buf_fl = buffer;
    ret = cdb_read(&dop);
    if (ret)
        return 3;

    // Validity checks
    if (buffer[0])
        return 4;
    if (strcmp((char*)&buffer[1], "CD001\001EL TORITO SPECIFICATION") != 0)
        return 5;

    // ok, now we calculate the Boot catalog address
    u32 lba = *(u32*)&buffer[0x47];

    // And we read the Boot Catalog
    dop.lba = lba;
    dop.count = 1;
    ret = cdb_read(&dop);
    if (ret)
        return 7;

    // Validation entry
    if (buffer[0x00] != 0x01)
        return 8;   // Header
    if (buffer[0x01] != 0x00)
        return 9;   // Platform
    if (buffer[0x1E] != 0x55)
        return 10;  // key 1
    if (buffer[0x1F] != 0xAA)
        return 10;  // key 2

    // Initial/Default Entry
    if (buffer[0x20] != 0x88)
        return 11; // Bootable

    u8 media = buffer[0x21];
    CDEmu.media = media;

    CDEmu.emulated_drive_gf = dop.drive_g;

    u16 boot_segment = *(u16*)&buffer[0x22];
    if (!boot_segment)
        boot_segment = 0x07C0;
    CDEmu.load_segment = boot_segment;
    CDEmu.buffer_segment = 0x0000;

    u16 nbsectors = *(u16*)&buffer[0x26];
    CDEmu.sector_count = nbsectors;

    lba = *(u32*)&buffer[0x28];
    CDEmu.ilba = lba;

    // And we read the image in memory
    dop.lba = lba;
    dop.count = DIV_ROUND_UP(nbsectors, 4);
    dop.buf_fl = MAKE_FLATPTR(boot_segment, 0);
    ret = cdb_read(&dop);
    if (ret)
        return 12;

    if (media == 0) {
        // No emulation requested - return success.
        CDEmu.emulated_extdrive = EXTSTART_CD + cdid;
        return 0;
    }

    // Emulation of a floppy/harddisk requested
    if (! CONFIG_CDROM_EMU || !cdemu_drive_gf)
        return 13;

    // Set emulated drive id and increase bios installed hardware
    // number of devices
    if (media < 4) {
        // Floppy emulation
        CDEmu.emulated_extdrive = 0x00;
        // XXX - get and set actual floppy count.
        set_equipment_flags(0x41, 0x41);

        switch (media) {
        case 0x01:  // 1.2M floppy
            CDEmu.lchs.spt = 15;
            CDEmu.lchs.cylinders = 80;
            CDEmu.lchs.heads = 2;
            break;
        case 0x02:  // 1.44M floppy
            CDEmu.lchs.spt = 18;
            CDEmu.lchs.cylinders = 80;
            CDEmu.lchs.heads = 2;
            break;
        case 0x03:  // 2.88M floppy
            CDEmu.lchs.spt = 36;
            CDEmu.lchs.cylinders = 80;
            CDEmu.lchs.heads = 2;
            break;
        }
    } else {
        // Harddrive emulation
        CDEmu.emulated_extdrive = 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.spt = sptcyl & 0x3f;
        CDEmu.lchs.cylinders = ((sptcyl<<2)&0x300) + cyllow + 1;
        CDEmu.lchs.heads = heads + 1;
    }

    // everything is ok, so from now on, the emulation is active
    CDEmu.active = 0x01;
    dprintf(6, "cdemu media=%d\n", media);

    return 0;
}
Esempio n. 12
0
// get shift flag status
static void
handle_1602(struct bregs *regs)
{
    yield();
    regs->al = GET_BDA(kbd_flag0);
}
Esempio n. 13
0
handle_16a2(struct bregs *regs)
{
    // don't change AH : function int16 ah=0x20-0x22 NOT supported
}

static void
handle_16XX(struct bregs *regs)
{
    warn_unimplemented(regs);
}

static void noinline
set_leds(void)
{
    u8 shift_flags = (GET_BDA(kbd_flag0) >> 4) & 0x07;
    u8 kbd_led = GET_BDA(kbd_led);
    u8 led_flags = kbd_led & 0x07;
    if (shift_flags == led_flags)
        return;

    int ret = kbd_command(ATKBD_CMD_SETLEDS, &shift_flags);
    if (ret)
        // Error
        return;
    kbd_led = (kbd_led & ~0x07) | shift_flags;
    SET_BDA(kbd_led, kbd_led);
}

// INT 16h Keyboard Service Entry Point
void VISIBLE16
handle_16(struct bregs *regs)