📄 cirrus_vga.c
字号:
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; 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; 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 = s->gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { *(s->vram_ptr + bank_offset) = mem_value; cpu_physical_memory_set_dirty(s->vram_offset + bank_offset); } else { if ((s->gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, bank_offset, mem_value); } else { cirrus_mem_writeb_mode4and5_16bpp(s, mode, bank_offset, mem_value); } } } } } else if (addr >= 0x18000 && addr < 0x18100) { /* memory-mapped I/O */ if ((s->sr[0x17] & 0x44) == 0x04) { cirrus_mmio_blt_write(s, addr & 0xff, mem_value); } } else {#ifdef DEBUG_CIRRUS printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);#endif }}static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val){#ifdef TARGET_WORDS_BIGENDIAN cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);#else cirrus_vga_mem_writeb(opaque, addr, val & 0xff); cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);#endif}static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val){#ifdef TARGET_WORDS_BIGENDIAN cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);#else cirrus_vga_mem_writeb(opaque, addr, val & 0xff); cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);#endif}static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = { cirrus_vga_mem_readb, cirrus_vga_mem_readw, cirrus_vga_mem_readl,};static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = { cirrus_vga_mem_writeb, cirrus_vga_mem_writew, cirrus_vga_mem_writel,};/*************************************** * * hardware cursor * ***************************************/static inline void invalidate_cursor1(CirrusVGAState *s){ if (s->last_hw_cursor_size) { vga_invalidate_scanlines((VGAState *)s, s->last_hw_cursor_y + s->last_hw_cursor_y_start, s->last_hw_cursor_y + s->last_hw_cursor_y_end); }}static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s){ const uint8_t *src; uint32_t content; int y, y_min, y_max; src = s->vram_ptr + s->real_vram_size - 16 * 1024; if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) { src += (s->sr[0x13] & 0x3c) * 256; y_min = 64; y_max = -1; for(y = 0; y < 64; y++) { content = ((uint32_t *)src)[0] | ((uint32_t *)src)[1] | ((uint32_t *)src)[2] | ((uint32_t *)src)[3]; if (content) { if (y < y_min) y_min = y; if (y > y_max) y_max = y; } src += 16; } } else { src += (s->sr[0x13] & 0x3f) * 256; y_min = 32; y_max = -1; for(y = 0; y < 32; y++) { content = ((uint32_t *)src)[0] | ((uint32_t *)(src + 128))[0]; if (content) { if (y < y_min) y_min = y; if (y > y_max) y_max = y; } src += 4; } } if (y_min > y_max) { s->last_hw_cursor_y_start = 0; s->last_hw_cursor_y_end = 0; } else { s->last_hw_cursor_y_start = y_min; s->last_hw_cursor_y_end = y_max + 1; }}/* NOTE: we do not currently handle the cursor bitmap change, so we update the cursor only if it moves. */static void cirrus_cursor_invalidate(VGAState *s1){ CirrusVGAState *s = (CirrusVGAState *)s1; int size; if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) { size = 0; } else { if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) size = 64; else size = 32; } /* invalidate last cursor and new cursor if any change */ if (s->last_hw_cursor_size != size || s->last_hw_cursor_x != s->hw_cursor_x || s->last_hw_cursor_y != s->hw_cursor_y) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -