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

📄 cirrus_vga.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    blt_rop = s->gr[0x32];#ifdef DEBUG_BITBLT    printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",           blt_rop,            s->cirrus_blt_mode,           s->cirrus_blt_modeext,           s->cirrus_blt_width,           s->cirrus_blt_height,           s->cirrus_blt_dstpitch,           s->cirrus_blt_srcpitch,           s->cirrus_blt_dstaddr,           s->cirrus_blt_srcaddr,           s->gr[0x2f]);#endif    switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {    case CIRRUS_BLTMODE_PIXELWIDTH8:	s->cirrus_blt_pixelwidth = 1;	break;    case CIRRUS_BLTMODE_PIXELWIDTH16:	s->cirrus_blt_pixelwidth = 2;	break;    case CIRRUS_BLTMODE_PIXELWIDTH24:	s->cirrus_blt_pixelwidth = 3;	break;    case CIRRUS_BLTMODE_PIXELWIDTH32:	s->cirrus_blt_pixelwidth = 4;	break;    default:#ifdef DEBUG_BITBLT	printf("cirrus: bitblt - pixel width is unknown\n");#endif	goto bitblt_ignore;    }    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;    if ((s->	 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |			    CIRRUS_BLTMODE_MEMSYSDEST))	== (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {#ifdef DEBUG_BITBLT	printf("cirrus: bitblt - memory-to-memory copy is requested\n");#endif	goto bitblt_ignore;    }    if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&        (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |                                CIRRUS_BLTMODE_TRANSPARENTCOMP |                               CIRRUS_BLTMODE_PATTERNCOPY |                                CIRRUS_BLTMODE_COLOREXPAND)) ==          (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {        cirrus_bitblt_fgcol(s);        cirrus_bitblt_solidfill(s, blt_rop);    } else {        if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |                                    CIRRUS_BLTMODE_PATTERNCOPY)) ==             CIRRUS_BLTMODE_COLOREXPAND) {            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {                if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)                    cirrus_bitblt_bgcol(s);                else                    cirrus_bitblt_fgcol(s);                s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];            } else {                cirrus_bitblt_fgcol(s);                cirrus_bitblt_bgcol(s);                s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];            }        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {                    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)                        cirrus_bitblt_bgcol(s);                    else                        cirrus_bitblt_fgcol(s);                    s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];                } else {                    cirrus_bitblt_fgcol(s);                    cirrus_bitblt_bgcol(s);                    s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];                }            } else {                s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];            }        } else {            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {                s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;                s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;                s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];            } else {                s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];            }        }                // setup bitblt engine.        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {            if (!cirrus_bitblt_cputovideo(s))                goto bitblt_ignore;        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {            if (!cirrus_bitblt_videotocpu(s))                goto bitblt_ignore;        } else {            if (!cirrus_bitblt_videotovideo(s))                goto bitblt_ignore;        }    }    return;  bitblt_ignore:;    cirrus_bitblt_reset(s);}static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value){    unsigned old_value;    old_value = s->gr[0x31];    s->gr[0x31] = reg_value;    if (((old_value & CIRRUS_BLT_RESET) != 0) &&	((reg_value & CIRRUS_BLT_RESET) == 0)) {	cirrus_bitblt_reset(s);    } else if (((old_value & CIRRUS_BLT_START) == 0) &&	       ((reg_value & CIRRUS_BLT_START) != 0)) {	cirrus_bitblt_start(s);    }}/*************************************** * *  basic parameters * ***************************************/static void cirrus_get_offsets(VGAState *s1,                                    uint32_t *pline_offset,                                   uint32_t *pstart_addr){    CirrusVGAState * s = (CirrusVGAState *)s1;    uint32_t start_addr;    uint32_t line_offset;    line_offset = s->cr[0x13]	| ((s->cr[0x1b] & 0x10) << 4);    line_offset <<= 3;    *pline_offset = line_offset;    start_addr = (s->cr[0x0c] << 8)	| s->cr[0x0d]	| ((s->cr[0x1b] & 0x01) << 16)	| ((s->cr[0x1b] & 0x0c) << 15)	| ((s->cr[0x1d] & 0x80) << 12);    *pstart_addr = start_addr;}static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s){    uint32_t ret = 16;    switch (s->cirrus_hidden_dac_data & 0xf) {    case 0:	ret = 15;	break;			/* Sierra HiColor */    case 1:	ret = 16;	break;			/* XGA HiColor */    default:#ifdef DEBUG_CIRRUS	printf("cirrus: invalid DAC value %x in 16bpp\n",	       (s->cirrus_hidden_dac_data & 0xf));#endif	ret = 15;		/* XXX */	break;    }    return ret;}static int cirrus_get_bpp(VGAState *s1){    CirrusVGAState * s = (CirrusVGAState *)s1;    uint32_t ret = 8;    if ((s->sr[0x07] & 0x01) != 0) {	/* Cirrus SVGA */	switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {	case CIRRUS_SR7_BPP_8:	    ret = 8;	    break;	case CIRRUS_SR7_BPP_16_DOUBLEVCLK:	    ret = cirrus_get_bpp16_depth(s);	    break;	case CIRRUS_SR7_BPP_24:	    ret = 24;	    break;	case CIRRUS_SR7_BPP_16:	    ret = cirrus_get_bpp16_depth(s);	    break;	case CIRRUS_SR7_BPP_32:	    ret = 32;	    break;	default:#ifdef DEBUG_CIRRUS	    printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);#endif	    ret = 8;	    break;	}    } else {	/* VGA */	ret = 0;    }    return ret;}static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight){    int width, height;        width = (s->cr[0x01] + 1) * 8;    height = s->cr[0x12] |         ((s->cr[0x07] & 0x02) << 7) |         ((s->cr[0x07] & 0x40) << 3);    height = (height + 1);    /* interlace support */    if (s->cr[0x1a] & 0x01)        height = height * 2;    *pwidth = width;    *pheight = height;}/*************************************** * * bank memory * ***************************************/static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index){    unsigned offset;    unsigned limit;    if ((s->gr[0x0b] & 0x01) != 0)	/* dual bank */	offset = s->gr[0x09 + bank_index];    else			/* single bank */	offset = s->gr[0x09];    if ((s->gr[0x0b] & 0x20) != 0)	offset <<= 14;    else	offset <<= 12;    if (s->real_vram_size <= offset)	limit = 0;    else	limit = s->real_vram_size - offset;    if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {	if (limit > 0x8000) {	    offset += 0x8000;	    limit -= 0x8000;	} else {	    limit = 0;	}    }    if (limit > 0) {	s->cirrus_bank_base[bank_index] = offset;	s->cirrus_bank_limit[bank_index] = limit;    } else {	s->cirrus_bank_base[bank_index] = 0;	s->cirrus_bank_limit[bank_index] = 0;    }}/*************************************** * *  I/O access between 0x3c4-0x3c5 * ***************************************/static intcirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value){    switch (reg_index) {    case 0x00:			// Standard VGA    case 0x01:			// Standard VGA    case 0x02:			// Standard VGA    case 0x03:			// Standard VGA    case 0x04:			// Standard VGA	return CIRRUS_HOOK_NOT_HANDLED;    case 0x06:			// Unlock Cirrus extensions	*reg_value = s->sr[reg_index];	break;    case 0x10:    case 0x30:    case 0x50:    case 0x70:			// Graphics Cursor X    case 0x90:    case 0xb0:    case 0xd0:    case 0xf0:			// Graphics Cursor X	*reg_value = s->sr[0x10];	break;    case 0x11:    case 0x31:    case 0x51:    case 0x71:			// Graphics Cursor Y    case 0x91:    case 0xb1:    case 0xd1:    case 0xf1:			// Graphics Cursor Y	*reg_value = s->sr[0x11];	break;    case 0x05:			// ???    case 0x07:			// Extended Sequencer Mode    case 0x08:			// EEPROM Control    case 0x09:			// Scratch Register 0    case 0x0a:			// Scratch Register 1    case 0x0b:			// VCLK 0    case 0x0c:			// VCLK 1    case 0x0d:			// VCLK 2    case 0x0e:			// VCLK 3    case 0x0f:			// DRAM Control    case 0x12:			// Graphics Cursor Attribute    case 0x13:			// Graphics Cursor Pattern Address    case 0x14:			// Scratch Register 2    case 0x15:			// Scratch Register 3    case 0x16:			// Performance Tuning Register    case 0x17:			// Configuration Readback and Extended Control    case 0x18:			// Signature Generator Control    case 0x19:			// Signal Generator Result    case 0x1a:			// Signal Generator Result    case 0x1b:			// VCLK 0 Denominator & Post    case 0x1c:			// VCLK 1 Denominator & Post    case 0x1d:			// VCLK 2 Denominator & Post    case 0x1e:			// VCLK 3 Denominator & Post    case 0x1f:			// BIOS Write Enable and MCLK select#ifdef DEBUG_CIRRUS	printf("cirrus: handled inport sr_index %02x\n", reg_index);#endif	*reg_value = s->sr[reg_index];	break;    default:#ifdef DEBUG_CIRRUS	printf("cirrus: inport sr_index %02x\n", reg_index);#endif	*reg_value = 0xff;	break;    }    return CIRRUS_HOOK_HANDLED;}static intcirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value){    switch (reg_index) {    case 0x00:			// Standard VGA    case 0x01:			// Standard VGA    case 0x02:			// Standard VGA    case 0x03:			// Standard VGA    case 0x04:			// Standard VGA	return CIRRUS_HOOK_NOT_HANDLED;    case 0x06:			// Unlock Cirrus extensions	reg_value &= 0x17;	if (reg_value == 0x12) {	    s->sr[reg_index] = 0x12;	} else {	    s->sr[reg_index] = 0x0f;	}	break;    case 0x10:    case 0x30:    case 0x50:    case 0x70:			// Graphics Cursor X    case 0x90:    case 0xb0:    case 0xd0:    case 0xf0:			// Graphics Cursor X	s->sr[0x10] = reg_value;	s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);	break;    case 0x11:    case 0x31:    case 0x51:    case 0x71:			// Graphics Cursor Y    case 0x91:    case 0xb1:    case 0xd1:    case 0xf1:			// Graphics Cursor Y	s->sr[0x11] = reg_value;	s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);	break;    case 0x07:			// Extended Sequencer Mode    case 0x08:			// EEPROM Control    case 0x09:			// Scratch Register 0    case 0x0a:			// Scratch Register 1    case 0x0b:			// VCLK 0    case 0x0c:			// VCLK 1    case 0x0d:			// VCLK 2    case 0x0e:			// VCLK 3    case 0x0f:			// DRAM Control    case 0x12:			// Graphics Cursor Attribute    case 0x13:			// Graphics Cursor Pattern Address    case 0x14:			// Scratch Register 2    case 0x15:			// Scratch Register 3    case 0x16:			// Performance Tuning Register    case 0x18:			// Signature Generator Control    case 0x19:			// Signature Generator Result    case 0x1a:			// Signature Generator Result    case 0x1b:			// VCLK 0 Denominator & Post    case 0x1c:			// VCLK 1 Denominator & Post    case 0x1d:			// VCLK 2 Denominator & Post    case 0x1e:			// VCLK 3 Denominator & Post    case 0x1f:			// BIOS Write Enable and MCLK select	s->sr[reg_index] = reg_value;#ifdef DEBUG_CIRRUS	printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",	       reg_index, reg_value);#endif	break;    case 0x17:			// Configuration Readback and Extended Control	s->sr[reg_index] = (s->sr[reg_index] & 0x38) | (reg_value & 0xc7);        cirrus_update_memory_access(s);        break;    default:#ifdef DEBUG_CIRRUS	printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,

⌨️ 快捷键说明

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