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

📄 vga.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
    uint32_t v, col, *palette;    full_update = 0;    palette = s->last_palette;    for(i = 0; i < 16; i++) {        v = s->ar[i];        if (s->ar[0x10] & 0x80)            v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);        else            v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);        v = v * 3;        col = s->rgb_to_pixel(c6_to_8(s->palette[v]),                               c6_to_8(s->palette[v + 1]),                               c6_to_8(s->palette[v + 2]));        if (col != palette[i]) {            full_update = 1;            palette[i] = col;        }    }    return full_update;}/* return true if the palette was modified */static int update_palette256(VGAState *s){    int full_update, i;    uint32_t v, col, *palette;    full_update = 0;    palette = s->last_palette;    v = 0;    for(i = 0; i < 256; i++) {        if (s->dac_8bit) {          col = s->rgb_to_pixel(s->palette[v],                                 s->palette[v + 1],                                 s->palette[v + 2]);        } else {          col = s->rgb_to_pixel(c6_to_8(s->palette[v]),                                 c6_to_8(s->palette[v + 1]),                                 c6_to_8(s->palette[v + 2]));        }        if (col != palette[i]) {            full_update = 1;            palette[i] = col;        }        v += 3;    }    return full_update;}static void vga_get_offsets(VGAState *s,                             uint32_t *pline_offset,                             uint32_t *pstart_addr,                            uint32_t *pline_compare){    uint32_t start_addr, line_offset, line_compare;#ifdef CONFIG_BOCHS_VBE    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {        line_offset = s->vbe_line_offset;        start_addr = s->vbe_start_addr;        line_compare = 65535;    } else#endif    {          /* compute line_offset in bytes */        line_offset = s->cr[0x13];        line_offset <<= 3;        /* starting address */        start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);        /* line compare */        line_compare = s->cr[0x18] |             ((s->cr[0x07] & 0x10) << 4) |            ((s->cr[0x09] & 0x40) << 3);    }    *pline_offset = line_offset;    *pstart_addr = start_addr;    *pline_compare = line_compare;}/* update start_addr and line_offset. Return TRUE if modified */static int update_basic_params(VGAState *s){    int full_update;    uint32_t start_addr, line_offset, line_compare;        full_update = 0;    s->get_offsets(s, &line_offset, &start_addr, &line_compare);    if (line_offset != s->line_offset ||        start_addr != s->start_addr ||        line_compare != s->line_compare) {        s->line_offset = line_offset;        s->start_addr = start_addr;        s->line_compare = line_compare;        full_update = 1;    }    return full_update;}#define NB_DEPTHS 5static inline int get_depth_index(DisplayState *s){    switch(s->depth) {    default:    case 8:        return 0;    case 15:        return 1;    case 16:        return 2;    case 32:        if (s->bgr)            return 4;        else            return 3;    }}static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {    vga_draw_glyph8_8,    vga_draw_glyph8_16,    vga_draw_glyph8_16,    vga_draw_glyph8_32,    vga_draw_glyph8_32,};static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {    vga_draw_glyph16_8,    vga_draw_glyph16_16,    vga_draw_glyph16_16,    vga_draw_glyph16_32,    vga_draw_glyph16_32,};static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {    vga_draw_glyph9_8,    vga_draw_glyph9_16,    vga_draw_glyph9_16,    vga_draw_glyph9_32,    vga_draw_glyph9_32,};    static const uint8_t cursor_glyph[32 * 4] = {    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,};    typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];/*  * Text mode update  * Missing: * - double scan * - double width  * - underline * - flashing */static void vga_draw_text(VGAState *s, int full_update){    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;    int cx_min, cx_max, linesize, x_incr;    uint32_t offset, fgcol, bgcol, v, cursor_offset;    uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;    const uint8_t *font_ptr, *font_base[2];    int dup9, line_offset, depth_index;    uint32_t *palette;    uint32_t *ch_attr_ptr;    vga_draw_glyph8_func *vga_draw_glyph8;    vga_draw_glyph9_func *vga_draw_glyph9;    /* Disable dirty bit tracking */    xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);    /* total width & height */    cheight = (s->cr[9] & 0x1f) + 1;    cw = 8;    if (!(s->sr[1] & 0x01))        cw = 9;    if (s->sr[1] & 0x08)        cw = 16; /* NOTE: no 18 pixel wide */    width = (s->cr[0x01] + 1);    if (s->cr[0x06] == 100) {        /* ugly hack for CGA 160x100x16 - explain me the logic */        height = 100;    } else {        height = s->cr[0x12] |             ((s->cr[0x07] & 0x02) << 7) |             ((s->cr[0x07] & 0x40) << 3);        height = (height + 1) / cheight;    }    if ((height * width) > CH_ATTR_SIZE) {        /* better than nothing: exit if transient size is too big */        return;    }    s->last_scr_width = width * cw;    s->last_scr_height = height * cheight;    if (width != s->last_width || height != s->last_height ||        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);        s->last_depth = 0;        full_update = 1;    }    s->last_width = width;    s->last_height = height;    s->last_ch = cheight;    s->last_cw = cw;    s->rgb_to_pixel =         rgb_to_pixel_dup_table[get_depth_index(s->ds)];    full_update |= update_palette16(s);    palette = s->last_palette;        x_incr = cw * ((s->ds->depth + 7) >> 3);    /* compute font data address (in plane 2) */    v = s->sr[3];    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;    if (offset != s->font_offsets[0]) {        s->font_offsets[0] = offset;        full_update = 1;    }    font_base[0] = s->vram_ptr + offset;    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;    font_base[1] = s->vram_ptr + offset;    if (offset != s->font_offsets[1]) {        s->font_offsets[1] = offset;        full_update = 1;    }    if (s->plane_updated & (1 << 2)) {        /* if the plane 2 was modified since the last display, it           indicates the font may have been modified */        s->plane_updated = 0;        full_update = 1;    }    full_update |= update_basic_params(s);    line_offset = s->line_offset;    s1 = s->vram_ptr + (s->start_addr * 4);    cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;    if (cursor_offset != s->cursor_offset ||        s->cr[0xa] != s->cursor_start ||        s->cr[0xb] != s->cursor_end) {      /* if the cursor position changed, we update the old and new         chars */        if (s->cursor_offset < CH_ATTR_SIZE)            s->last_ch_attr[s->cursor_offset] = -1;        if (cursor_offset < CH_ATTR_SIZE)            s->last_ch_attr[cursor_offset] = -1;        s->cursor_offset = cursor_offset;        s->cursor_start = s->cr[0xa];        s->cursor_end = s->cr[0xb];    }    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;        depth_index = get_depth_index(s->ds);    if (cw == 16)        vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];    else        vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];    vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];        dest = s->ds->data;    linesize = s->ds->linesize;    ch_attr_ptr = s->last_ch_attr;    for(cy = 0; cy < height; cy++) {        d1 = dest;        src = s1;        cx_min = width;        cx_max = -1;        for(cx = 0; cx < width; cx++) {            ch_attr = *(uint16_t *)src;            if (full_update || ch_attr != *ch_attr_ptr) {                if (cx < cx_min)                    cx_min = cx;                if (cx > cx_max)                    cx_max = cx;                *ch_attr_ptr = ch_attr;#ifdef WORDS_BIGENDIAN                ch = ch_attr >> 8;                cattr = ch_attr & 0xff;#else                ch = ch_attr & 0xff;                cattr = ch_attr >> 8;#endif                font_ptr = font_base[(cattr >> 3) & 1];                font_ptr += 32 * 4 * ch;                bgcol = palette[cattr >> 4];                fgcol = palette[cattr & 0x0f];                if (cw != 9) {                    vga_draw_glyph8(d1, linesize,                                     font_ptr, cheight, fgcol, bgcol);                } else {                    dup9 = 0;                    if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))                        dup9 = 1;                    vga_draw_glyph9(d1, linesize,                                     font_ptr, cheight, fgcol, bgcol, dup9);                }                if (src == cursor_ptr &&                    !(s->cr[0x0a] & 0x20)) {                    int line_start, line_last, h;                    /* draw the cursor */                    line_start = s->cr[0x0a] & 0x1f;                    line_last = s->cr[0x0b] & 0x1f;                    /* XXX: check that */                    if (line_last > cheight - 1)                        line_last = cheight - 1;                    if (line_last >= line_start && line_start < cheight) {                        h = line_last - line_start + 1;                        d = d1 + linesize * line_start;                        if (cw != 9) {                            vga_draw_glyph8(d, linesize,                                             cursor_glyph, h, fgcol, bgcol);                        } else {                            vga_draw_glyph9(d, linesize,                                             cursor_glyph, h, fgcol, bgcol, 1);                        }                    }                }            }            d1 += x_incr;            src += 4;            ch_attr_ptr++;        }        if (cx_max != -1) {            dpy_update(s->ds, cx_min * cw, cy * cheight,                        (cx_max - cx_min + 1) * cw, cheight);        }        dest += linesize * cheight;        s1 += line_offset;    }}enum {    VGA_DRAW_LINE2,    VGA_DRAW_LINE2D2,    VGA_DRAW_LINE4,    VGA_DRAW_LINE4D2,    VGA_DRAW_LINE8D2,    VGA_DRAW_LINE8,    VGA_DRAW_LINE15,    VGA_DRAW_LINE16,    VGA_DRAW_LINE24,    VGA_DRAW_LINE32,    VGA_DRAW_LINE_NB,};static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {    vga_draw_line2_8,    vga_draw_line2_16,    vga_draw_line2_16,    vga_draw_line2_32,    vga_draw_line2_32,    vga_draw_line2d2_8,    vga_draw_line2d2_16,    vga_draw_line2d2_16,    vga_draw_line2d2_32,    vga_draw_line2d2_32,    vga_draw_line4_8,    vga_draw_line4_16,    vga_draw_line4_16,    vga_draw_line4_32,    vga_draw_line4_32,    vga_draw_line4d2_8,    vga_draw_line4d2_16,    vga_draw_line4d2_16,    vga_draw_line4d2_32,    vga_draw_line4d2_32,    vga_draw_line8d2_8,    vga_draw_line8d2_16,    vga_draw_line8d2_16,    vga_draw_line8d2_32,    vga_draw_line8d2_32,    vga_draw_line8_8,    vga_draw_line8_16,    vga_draw_line8_16,    vga_draw_line8_32,    vga_draw_line8_32,    vga_draw_line15_8,    vga_draw_line15_15,    vga_draw_line15_16,    vga_draw_line15_32,    vga_draw_line15_32bgr,    vga_draw_line16_8,    vga_draw_line16_15,    vga_draw_line16_16,    vga_draw_line16_32,    vga_draw_line16_32bgr,    vga_draw_line24_8,    vga_draw_line24_15,    vga_draw_line24_16,    vga_draw_line24_32,    vga_draw_line24_32bgr,    vga_draw_line32_8,    vga_draw_line32_15,    vga_draw_line32_16,    vga_draw_line32_32,    vga_draw_line32_32bgr,};static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {    rgb_to_pixel8_dup,    rgb_to_pixel15_dup,    rgb_to_pixel16_dup,    rgb_to_pixel32_dup,    rgb_to_pixel32bgr_dup,};static int vga_get_bpp(VGAState *s){    int ret;#ifdef CONFIG_BOCHS_VBE    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];    } else #endif    {

⌨️ 快捷键说明

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