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 + -
显示快捷键?