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

📄 vga.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);    }}static inline int cmp_vram(VGAState *s, int offset, int n){    long *vp, *sp;    if (s->vram_shadow == NULL)        return 1;    vp = (long *)(s->vram_ptr + offset);    sp = (long *)(s->vram_shadow + offset);    while ((n -= sizeof(*vp)) >= 0) {        if (*vp++ != *sp++) {            memcpy(sp - 1, vp - 1, n + sizeof(*vp));            return 1;        }    }    return 0;}#ifdef USE_SSE2#include <signal.h>#include <setjmp.h>#include <emmintrin.h>int sse2_ok = 1;static inline unsigned int cpuid_edx(unsigned int op){    unsigned int eax, edx;#ifdef __x86_64__#define __bx "rbx"#else#define __bx "ebx"#endif    __asm__("push %%"__bx"; cpuid; pop %%"__bx            : "=a" (eax), "=d" (edx)            : "0" (op)            : "cx");#undef __bx    return edx;}jmp_buf sse_jbuf;void intr(int sig){    sse2_ok = 0;    longjmp(sse_jbuf, 1);}void check_sse2(void){    /* Check 1: What does CPUID say? */    if ((cpuid_edx(1) & 0x4000000) == 0) {        sse2_ok = 0;        return;    }    /* Check 2: Can we use SSE2 in anger? */    signal(SIGILL, intr);    if (setjmp(sse_jbuf) == 0)        __asm__("xorps %xmm0,%xmm0\n");}int vram_dirty(VGAState *s, int offset, int n){    __m128i *sp, *vp;    if (s->vram_shadow == NULL)        return 1;    if (sse2_ok == 0)        return cmp_vram(s, offset, n);    vp = (__m128i *)(s->vram_ptr + offset);    sp = (__m128i *)(s->vram_shadow + offset);    while ((n -= sizeof(*vp)) >= 0) {        if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {            while (n >= 0) {                _mm_store_si128(sp++, _mm_load_si128(vp++));                n -= sizeof(*vp);            }            return 1;        }        sp++;        vp++;    }    return 0;}#else /* !USE_SSE2 */int vram_dirty(VGAState *s, int offset, int n){    return cmp_vram(s, offset, n);}void check_sse2(void){}#endif /* !USE_SSE2 *//*  * graphic modes */static void vga_draw_graphic(VGAState *s, int full_update){    int y1, y, update, linesize, y_start, double_scan, mask;    int width, height, shift_control, line_offset, bwidth;    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;    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 == 0) {        full_update |= update_palette16(s);        if (s->sr[0x01] & 8) {            v = VGA_DRAW_LINE4D2;            disp_width <<= 1;        } else {            v = VGA_DRAW_LINE4;        }    } else if (shift_control == 1) {        full_update |= update_palette16(s);        if (s->sr[0x01] & 8) {            v = VGA_DRAW_LINE2D2;            disp_width <<= 1;        } else {            v = VGA_DRAW_LINE2;        }    } else {        switch(s->get_bpp(s)) {        default:        case 0:            full_update |= update_palette256(s);            v = VGA_DRAW_LINE8D2;            break;        case 8:            full_update |= update_palette256(s);            v = VGA_DRAW_LINE8;            break;        case 15:            v = VGA_DRAW_LINE15;            break;        case 16:            v = VGA_DRAW_LINE16;            break;        case 24:            v = VGA_DRAW_LINE24;            break;        case 32:            v = VGA_DRAW_LINE32;            break;        }    }    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];    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;    }    if (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    for (y = 0; y < s->vram_size; y += TARGET_PAGE_SIZE)        if (vram_dirty(s, y, TARGET_PAGE_SIZE))            cpu_physical_memory_set_dirty(s->vram_offset + y);    addr1 = (s->start_addr * 4);    bwidth = width * 4;    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;            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;    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 {        s->rgb_to_pixel =             rgb_to_pixel_dup_table[get_depth_index(s->ds)];                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)            return ret;    }    qemu_get_be32s(f, &s->latch);    qemu_get_8s(f, &s->sr_index);    qemu_get_buffer(f, s->sr, 8);    qemu_get_8s(f, &s->gr_index);    qemu_get_buffer(f, s->gr, 16);    qemu_get_8s(f, &s->ar_index);    qemu_get_buffer(f, s->ar, 21);    qemu_get_be32s(f, &s->ar_flip_flop);    qemu_get_8s(f, &s->cr_index);    qemu_get_buffer(f, s->cr, 256);    qemu_get_8s(f, &s->msr);    qemu_get_8s(f, &s->fcr);    qemu_get_8s(f, &s->st00);    qemu_get_8s(f, &s->st01);    qemu_get_8s(f, &s->dac_state);    qemu_get_8s(f, &s->dac_sub_index);    qemu_get_8s(f, &s->dac_read_index);    qemu_get_8s(f, &s->dac_write_index);

⌨️ 快捷键说明

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