cirrus_vga.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,128 行 · 第 1/5 页
C
2,128 行
case 0x18: // Standard VGA return CIRRUS_HOOK_NOT_HANDLED; case 0x19: // Interlace End case 0x1a: // Miscellaneous Control case 0x1b: // Extended Display Control case 0x1c: // Sync Adjust and Genlock case 0x1d: // Overlay Extended Control s->cr[reg_index] = reg_value;#ifdef DEBUG_CIRRUS printf("cirrus: handled outport cr_index %02x, cr_value %02x\n", reg_index, reg_value);#endif break; case 0x22: // Graphics Data Latches Readback (R) case 0x24: // Attribute Controller Toggle Readback (R) case 0x26: // Attribute Controller Index Readback (R) case 0x27: // Part ID (R) break; case 0x25: // Part Status default:#ifdef DEBUG_CIRRUS printf("cirrus: outport cr_index %02x, cr_value %02x\n", reg_index, reg_value);#endif break; } return CIRRUS_HOOK_HANDLED;}/*************************************** * * memory-mapped I/O (bitblt) * ***************************************/static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address){ int value = 0xff; switch (address) { case (CIRRUS_MMIO_BLTBGCOLOR + 0): cirrus_hook_read_gr(s, 0x00, &value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 1): cirrus_hook_read_gr(s, 0x10, &value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 2): cirrus_hook_read_gr(s, 0x12, &value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 3): cirrus_hook_read_gr(s, 0x14, &value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 0): cirrus_hook_read_gr(s, 0x01, &value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 1): cirrus_hook_read_gr(s, 0x11, &value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 2): cirrus_hook_read_gr(s, 0x13, &value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 3): cirrus_hook_read_gr(s, 0x15, &value); break; case (CIRRUS_MMIO_BLTWIDTH + 0): cirrus_hook_read_gr(s, 0x20, &value); break; case (CIRRUS_MMIO_BLTWIDTH + 1): cirrus_hook_read_gr(s, 0x21, &value); break; case (CIRRUS_MMIO_BLTHEIGHT + 0): cirrus_hook_read_gr(s, 0x22, &value); break; case (CIRRUS_MMIO_BLTHEIGHT + 1): cirrus_hook_read_gr(s, 0x23, &value); break; case (CIRRUS_MMIO_BLTDESTPITCH + 0): cirrus_hook_read_gr(s, 0x24, &value); break; case (CIRRUS_MMIO_BLTDESTPITCH + 1): cirrus_hook_read_gr(s, 0x25, &value); break; case (CIRRUS_MMIO_BLTSRCPITCH + 0): cirrus_hook_read_gr(s, 0x26, &value); break; case (CIRRUS_MMIO_BLTSRCPITCH + 1): cirrus_hook_read_gr(s, 0x27, &value); break; case (CIRRUS_MMIO_BLTDESTADDR + 0): cirrus_hook_read_gr(s, 0x28, &value); break; case (CIRRUS_MMIO_BLTDESTADDR + 1): cirrus_hook_read_gr(s, 0x29, &value); break; case (CIRRUS_MMIO_BLTDESTADDR + 2): cirrus_hook_read_gr(s, 0x2a, &value); break; case (CIRRUS_MMIO_BLTSRCADDR + 0): cirrus_hook_read_gr(s, 0x2c, &value); break; case (CIRRUS_MMIO_BLTSRCADDR + 1): cirrus_hook_read_gr(s, 0x2d, &value); break; case (CIRRUS_MMIO_BLTSRCADDR + 2): cirrus_hook_read_gr(s, 0x2e, &value); break; case CIRRUS_MMIO_BLTWRITEMASK: cirrus_hook_read_gr(s, 0x2f, &value); break; case CIRRUS_MMIO_BLTMODE: cirrus_hook_read_gr(s, 0x30, &value); break; case CIRRUS_MMIO_BLTROP: cirrus_hook_read_gr(s, 0x32, &value); break; case CIRRUS_MMIO_BLTMODEEXT: cirrus_hook_read_gr(s, 0x33, &value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): cirrus_hook_read_gr(s, 0x34, &value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): cirrus_hook_read_gr(s, 0x35, &value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): cirrus_hook_read_gr(s, 0x38, &value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): cirrus_hook_read_gr(s, 0x39, &value); break; case CIRRUS_MMIO_BLTSTATUS: cirrus_hook_read_gr(s, 0x31, &value); break; default:#ifdef DEBUG_CIRRUS printf("cirrus: mmio read - address 0x%04x\n", address);#endif break; } return (uint8_t) value;}static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, uint8_t value){ switch (address) { case (CIRRUS_MMIO_BLTBGCOLOR + 0): cirrus_hook_write_gr(s, 0x00, value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 1): cirrus_hook_write_gr(s, 0x10, value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 2): cirrus_hook_write_gr(s, 0x12, value); break; case (CIRRUS_MMIO_BLTBGCOLOR + 3): cirrus_hook_write_gr(s, 0x14, value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 0): cirrus_hook_write_gr(s, 0x01, value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 1): cirrus_hook_write_gr(s, 0x11, value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 2): cirrus_hook_write_gr(s, 0x13, value); break; case (CIRRUS_MMIO_BLTFGCOLOR + 3): cirrus_hook_write_gr(s, 0x15, value); break; case (CIRRUS_MMIO_BLTWIDTH + 0): cirrus_hook_write_gr(s, 0x20, value); break; case (CIRRUS_MMIO_BLTWIDTH + 1): cirrus_hook_write_gr(s, 0x21, value); break; case (CIRRUS_MMIO_BLTHEIGHT + 0): cirrus_hook_write_gr(s, 0x22, value); break; case (CIRRUS_MMIO_BLTHEIGHT + 1): cirrus_hook_write_gr(s, 0x23, value); break; case (CIRRUS_MMIO_BLTDESTPITCH + 0): cirrus_hook_write_gr(s, 0x24, value); break; case (CIRRUS_MMIO_BLTDESTPITCH + 1): cirrus_hook_write_gr(s, 0x25, value); break; case (CIRRUS_MMIO_BLTSRCPITCH + 0): cirrus_hook_write_gr(s, 0x26, value); break; case (CIRRUS_MMIO_BLTSRCPITCH + 1): cirrus_hook_write_gr(s, 0x27, value); break; case (CIRRUS_MMIO_BLTDESTADDR + 0): cirrus_hook_write_gr(s, 0x28, value); break; case (CIRRUS_MMIO_BLTDESTADDR + 1): cirrus_hook_write_gr(s, 0x29, value); break; case (CIRRUS_MMIO_BLTDESTADDR + 2): cirrus_hook_write_gr(s, 0x2a, value); break; case (CIRRUS_MMIO_BLTDESTADDR + 3): /* ignored */ break; case (CIRRUS_MMIO_BLTSRCADDR + 0): cirrus_hook_write_gr(s, 0x2c, value); break; case (CIRRUS_MMIO_BLTSRCADDR + 1): cirrus_hook_write_gr(s, 0x2d, value); break; case (CIRRUS_MMIO_BLTSRCADDR + 2): cirrus_hook_write_gr(s, 0x2e, value); break; case CIRRUS_MMIO_BLTWRITEMASK: cirrus_hook_write_gr(s, 0x2f, value); break; case CIRRUS_MMIO_BLTMODE: cirrus_hook_write_gr(s, 0x30, value); break; case CIRRUS_MMIO_BLTROP: cirrus_hook_write_gr(s, 0x32, value); break; case CIRRUS_MMIO_BLTMODEEXT: cirrus_hook_write_gr(s, 0x33, value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): cirrus_hook_write_gr(s, 0x34, value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): cirrus_hook_write_gr(s, 0x35, value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): cirrus_hook_write_gr(s, 0x38, value); break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): cirrus_hook_write_gr(s, 0x39, value); break; case CIRRUS_MMIO_BLTSTATUS: cirrus_hook_write_gr(s, 0x31, value); break; default:#ifdef DEBUG_CIRRUS printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", address, value);#endif break; }}/*************************************** * * write mode 4/5 * * assume TARGET_PAGE_SIZE >= 16 * ***************************************/static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, unsigned mode, unsigned offset, uint32_t mem_value){ int x; unsigned val = mem_value; uint8_t *dst; dst = s->vram_ptr + (offset &= s->cirrus_addr_mask); for (x = 0; x < 8; x++) { if (val & 0x80) { *dst = s->cirrus_shadow_gr1; } else if (mode == 5) { *dst = s->cirrus_shadow_gr0; } val <<= 1; dst++; } cpu_physical_memory_set_dirty(s->vram_offset + offset); cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);}static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, unsigned mode, unsigned offset, uint32_t mem_value){ int x; unsigned val = mem_value; uint8_t *dst; dst = s->vram_ptr + (offset &= s->cirrus_addr_mask); for (x = 0; x < 8; x++) { if (val & 0x80) { *dst = s->cirrus_shadow_gr1; *(dst + 1) = s->gr[0x11]; } else if (mode == 5) { *dst = s->cirrus_shadow_gr0; *(dst + 1) = s->gr[0x10]; } val <<= 1; dst += 2; } cpu_physical_memory_set_dirty(s->vram_offset + offset); cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);}/*************************************** * * memory access between 0xa0000-0xbffff * ***************************************/static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr){ CirrusVGAState *s = opaque; unsigned bank_index; unsigned bank_offset; uint32_t val; if ((s->sr[0x07] & 0x01) == 0) { return vga_mem_readb(s, addr); } addr &= 0x1ffff; if (addr < 0x10000) { /* XXX handle bitblt */ /* video memory */ bank_index = addr >> 15; bank_offset = addr & 0x7fff; if (bank_offset < s->cirrus_bank_limit[bank_index]) { bank_offset += s->cirrus_bank_base[bank_index]; if ((s->gr[0x0B] & 0x14) == 0x14) { bank_offset <<= 4; } else if (s->gr[0x0B] & 0x02) { bank_offset <<= 3; } bank_offset &= s->cirrus_addr_mask; val = *(s->vram_ptr + bank_offset); } else val = 0xff; } else if (addr >= 0x18000 && addr < 0x18100) { /* memory-mapped I/O */ val = 0xff; if ((s->sr[0x17] & 0x44) == 0x04) { val = cirrus_mmio_blt_read(s, addr & 0xff); } } else { val = 0xff;#ifdef DEBUG_CIRRUS printf("cirrus: mem_readb %06x\n", addr);#endif } return val;}static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr){ uint32_t v;#ifdef TARGET_WORDS_BIGENDIAN v = cirrus_vga_mem_readb(opaque, addr) << 8; v |= cirrus_vga_mem_readb(opaque, addr + 1);#else v = cirrus_vga_mem_readb(opaque, addr); v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;#endif return v;}static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr){ uint32_t v;#ifdef TARGET_WORDS_BIGENDIAN v = cirrus_vga_mem_readb(opaque, addr) << 24; v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16; v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8; v |= cirrus_vga_mem_readb(opaque, addr + 3);#else v = cirrus_vga_mem_readb(opaque, addr); v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16; v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;#endif return v;}static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t mem_value){ CirrusVGAState *s = opaque; unsigned bank_index; unsigned bank_offset; unsigned mode; if ((s->sr[0x07] & 0x01) == 0) { vga_mem_writeb(s, addr, mem_value); return; } addr &= 0x1ffff; if (addr < 0x10000) { if (s->cirrus_srcptr != s->cirrus_srcptr_end) { /* bitblt */ *s->cirrus_srcptr++ = (uint8_t) mem_value; if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { cirrus_bitblt_cputovideo_next(s); } } else { /* video memory */ bank_index = addr >> 15; bank_offset = addr & 0x7fff; if (bank_offset < s->cirrus_bank_limit[bank_index]) { bank_offset += s->cirrus_bank_base[bank_index]; if ((s->gr[0x0B] & 0x14) == 0x14) { bank_offset <<= 4; } else if (s->gr[0x0B] & 0x02) { bank_offset <<= 3; } bank_offset &= s->cirrus_addr_mask; mode =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?