⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vga.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
        ret = 0;    }    return ret;}static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight){    int width, height;    #ifdef CONFIG_BOCHS_VBE    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];    } else #endif    {        width = (s->cr[0x01] + 1) * 8;        height = s->cr[0x12] |             ((s->cr[0x07] & 0x02) << 7) |             ((s->cr[0x07] & 0x40) << 3);        height = (height + 1);    }    *pwidth = width;    *pheight = height;}void vga_invalidate_scanlines(VGAState *s, int y1, int y2){    int y;    if (y1 >= VGA_MAX_HEIGHT)        return;    if (y2 >= VGA_MAX_HEIGHT)        y2 = VGA_MAX_HEIGHT;    for(y = y1; y < y2; y++) {        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);    }}/*  * graphic modes */static void vga_draw_graphic(VGAState *s, int full_update){    int y1, y, update, linesize, y_start, double_scan, mask, depth;    int width, height, shift_control, line_offset, bwidth, ds_depth, bits;    ram_addr_t page0, page1;    int disp_width, multi_scan, multi_run;    uint8_t *d;    uint32_t v, addr1, addr;    vga_draw_line_func *vga_draw_line;    ram_addr_t page_min, page_max;    unsigned long start, end;    full_update |= update_basic_params(s);    s->get_resolution(s, &width, &height);    disp_width = width;    shift_control = (s->gr[0x05] >> 5) & 3;    double_scan = (s->cr[0x09] >> 7);    if (shift_control != 1) {        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;    } else {        /* in CGA modes, multi_scan is ignored */        /* XXX: is it correct ? */        multi_scan = double_scan;    }    multi_run = multi_scan;    if (shift_control != s->shift_control ||        double_scan != s->double_scan) {        full_update = 1;        s->shift_control = shift_control;        s->double_scan = double_scan;    }    if (shift_control == 1 && (s->sr[0x01] & 8)) {        disp_width <<= 1;    }    ds_depth = s->ds->depth;    depth = s->get_bpp(s);    if (s->ds->dpy_resize_shared) {        if (s->line_offset != s->last_line_offset ||             disp_width != s->last_width ||            height != s->last_height ||            s->last_depth != depth) {            dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));            s->last_scr_width = disp_width;            s->last_scr_height = height;            s->last_width = disp_width;            s->last_height = height;            s->last_line_offset = s->line_offset;            s->last_depth = depth;            full_update = 1;        } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));    } else if (disp_width != s->last_width ||               height != s->last_height) {        dpy_resize(s->ds, disp_width, height);        s->last_scr_width = disp_width;        s->last_scr_height = height;        s->last_width = disp_width;        s->last_height = height;        full_update = 1;    }    s->rgb_to_pixel =         rgb_to_pixel_dup_table[get_depth_index(s->ds)];    if (shift_control == 0) {        full_update |= update_palette16(s);        if (s->sr[0x01] & 8) {            v = VGA_DRAW_LINE4D2;        } else {            v = VGA_DRAW_LINE4;        }        bits = 4;    } else if (shift_control == 1) {        full_update |= update_palette16(s);        if (s->sr[0x01] & 8) {            v = VGA_DRAW_LINE2D2;        } else {            v = VGA_DRAW_LINE2;        }        bits = 4;    } else {        switch(s->get_bpp(s)) {        default:        case 0:            full_update |= update_palette256(s);            v = VGA_DRAW_LINE8D2;            bits = 4;            break;        case 8:            full_update |= update_palette256(s);            v = VGA_DRAW_LINE8;            bits = 8;            break;        case 15:            v = VGA_DRAW_LINE15;            bits = 16;            break;        case 16:            v = VGA_DRAW_LINE16;            bits = 16;            break;        case 24:            v = VGA_DRAW_LINE24;            bits = 24;            break;        case 32:            v = VGA_DRAW_LINE32;            bits = 32;            break;        }    }    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];    if (!s->ds->shared_buf && s->cursor_invalidate)        s->cursor_invalidate(s);        line_offset = s->line_offset;#if 0    printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",           width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);#endif    if (s->lfb_addr) {        if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3) {            /* Tricky things happen, just track all video memory */            start = 0;            end = s->vram_size;        } else {            /* Tricky things won't have any effect, i.e. we are in the very simple             * (and very usual) case of a linear buffer. */            /* use page table dirty bit tracking for the LFB plus border */            start = (s->start_addr * 4) & TARGET_PAGE_MASK;            end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;        }        for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)            /* We will not read that anyway. */            cpu_physical_memory_set_dirty(s->vram_offset + y);        {            unsigned long npages = (end - y) / TARGET_PAGE_SIZE;            const int width = sizeof(unsigned long) * 8;            unsigned long bitmap[(npages + width - 1) / width];            int err;            if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,                        (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {                int i, j;                for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {                    unsigned long map = bitmap[i];                    for (j = i * width; map && j < npages; map >>= 1, j++)                        if (map & 1)                            cpu_physical_memory_set_dirty(s->vram_offset + y                                + j * TARGET_PAGE_SIZE);                }                y += npages * TARGET_PAGE_SIZE;            } else {                /* ENODATA just means we have changed mode and will succeed                 * next time */                if (errno != ENODATA)                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d, %d)\n", s->lfb_addr + y, npages, err, errno);            }        }        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)            /* We will not read that anyway. */            cpu_physical_memory_set_dirty(s->vram_offset + y);    }    addr1 = (s->start_addr * 4);    bwidth = (width * bits + 7) / 8;    y_start = -1;    page_min = 0;    page_max = 0;    d = s->ds->data;    linesize = s->ds->linesize;    y1 = 0;    for(y = 0; y < height; y++) {        addr = addr1;        if (!(s->cr[0x17] & 1)) {            int shift;            /* CGA compatibility handling */            shift = 14 + ((s->cr[0x17] >> 6) & 1);            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);        }        if (!(s->cr[0x17] & 2)) {            addr = (addr & ~0x8000) | ((y1 & 2) << 14);        }        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);        update = full_update |             cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);        if ((page1 - page0) > TARGET_PAGE_SIZE) {            /* if wide line, can use another page */            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,                                                     VGA_DIRTY_FLAG);        }        /* explicit invalidation for the hardware cursor */        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;        if (update) {            if (y_start < 0)                y_start = y;            if (page_min == 0 || page0 < page_min)                page_min = page0;            if (page_max == 0 || page1 > page_max)                page_max = page1;            if (!s->ds->shared_buf) {                vga_draw_line(s, d, s->vram_ptr + addr, width);                if (s->cursor_draw_line)                    s->cursor_draw_line(s, d, y);            }        } else {            if (y_start >= 0) {                /* flush to display */                dpy_update(s->ds, 0, y_start,                            disp_width, y - y_start);                y_start = -1;            }        }        if (!multi_run) {            mask = (s->cr[0x17] & 3) ^ 3;            if ((y1 & mask) == mask)                addr1 += line_offset;            y1++;            multi_run = multi_scan;        } else {            multi_run--;        }        /* line compare acts on the displayed lines */        if (y == s->line_compare)            addr1 = 0;        d += linesize;    }    if (y_start >= 0) {        /* flush to display */        dpy_update(s->ds, 0, y_start,                    disp_width, y - y_start);    }    /* reset modified pages */    if (page_max != -1) {        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,                                        VGA_DIRTY_FLAG);    }    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);}static void vga_draw_blank(VGAState *s, int full_update){    int i, w, val;    uint8_t *d;    if (!full_update)        return;    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)        return;    /* Disable dirty bit tracking */    xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);    s->rgb_to_pixel =         rgb_to_pixel_dup_table[get_depth_index(s->ds)];    if (s->ds->depth == 8)         val = s->rgb_to_pixel(0, 0, 0);    else        val = 0;    w = s->last_scr_width * ((s->ds->depth + 7) >> 3);    d = s->ds->data;    for(i = 0; i < s->last_scr_height; i++) {        memset(d, val, w);        d += s->ds->linesize;    }    dpy_update(s->ds, 0, 0,                s->last_scr_width, s->last_scr_height);}#define GMODE_TEXT     0#define GMODE_GRAPH    1#define GMODE_BLANK 2 static void vga_update_display(void *opaque){    VGAState *s = (VGAState *)opaque;    int full_update, graphic_mode;    if (s->ds->depth == 0) {        /* nothing to do */    } else {        full_update = 0;        if (!(s->ar_index & 0x20)) {            graphic_mode = GMODE_BLANK;        } else {            graphic_mode = s->gr[6] & 1;        }        if (graphic_mode != s->graphic_mode) {            s->graphic_mode = graphic_mode;            full_update = 1;        }        switch(graphic_mode) {        case GMODE_TEXT:            vga_draw_text(s, full_update);            break;        case GMODE_GRAPH:            vga_draw_graphic(s, full_update);            break;        case GMODE_BLANK:        default:            vga_draw_blank(s, full_update);            break;        }    }}/* force a full display refresh */static void vga_invalidate_display(void *opaque){    VGAState *s = (VGAState *)opaque;        s->last_width = -1;    s->last_height = -1;}static void vga_reset(VGAState *s){    memset(s, 0, sizeof(VGAState));    s->graphic_mode = -1; /* force full update */}static CPUReadMemoryFunc *vga_mem_read[3] = {    vga_mem_readb,    vga_mem_readw,    vga_mem_readl,};static CPUWriteMemoryFunc *vga_mem_write[3] = {    vga_mem_writeb,    vga_mem_writew,    vga_mem_writel,};static void vga_save(QEMUFile *f, void *opaque){    VGAState *s = opaque;    uint32_t vram_size;#ifdef CONFIG_BOCHS_VBE    int i;#endif    if (s->pci_dev)        pci_device_save(s->pci_dev, f);    qemu_put_be32s(f, &s->latch);    qemu_put_8s(f, &s->sr_index);    qemu_put_buffer(f, s->sr, 8);    qemu_put_8s(f, &s->gr_index);    qemu_put_buffer(f, s->gr, 16);    qemu_put_8s(f, &s->ar_index);    qemu_put_buffer(f, s->ar, 21);    qemu_put_be32s(f, &s->ar_flip_flop);    qemu_put_8s(f, &s->cr_index);    qemu_put_buffer(f, s->cr, 256);    qemu_put_8s(f, &s->msr);    qemu_put_8s(f, &s->fcr);    qemu_put_8s(f, &s->st00);    qemu_put_8s(f, &s->st01);    qemu_put_8s(f, &s->dac_state);    qemu_put_8s(f, &s->dac_sub_index);    qemu_put_8s(f, &s->dac_read_index);    qemu_put_8s(f, &s->dac_write_index);    qemu_put_buffer(f, s->dac_cache, 3);    qemu_put_buffer(f, s->palette, 768);    qemu_put_be32s(f, &s->bank_offset);#ifdef CONFIG_BOCHS_VBE    qemu_put_byte(f, 1);    qemu_put_be16s(f, &s->vbe_index);    for(i = 0; i < VBE_DISPI_INDEX_NB; i++)        qemu_put_be16s(f, &s->vbe_regs[i]);    qemu_put_be32s(f, &s->vbe_start_addr);    qemu_put_be32s(f, &s->vbe_line_offset);    qemu_put_be32s(f, &s->vbe_bank_mask);#else    qemu_put_byte(f, 0);#endif    vram_size = s->vram_size;    qemu_put_be32s(f, &vram_size);     qemu_put_buffer(f, s->vram_ptr, s->vram_size); }static int vga_load(QEMUFile *f, void *opaque, int version_id){    VGAState *s = opaque;    int is_vbe, ret;    uint32_t vram_size;#ifdef CONFIG_BOCHS_VBE    int i;#endif    if (version_id > 3)        return -EINVAL;    if (s->pci_dev && version_id >= 2) {        ret = pci_device_load(s->pci_dev, f);        if (ret < 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -