?? cirrus_vga.c
字號:
/* XXX: check for 24 bpp */ s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; } s->cirrus_srccounter = s->cirrus_blt_srcpitch; } else { if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth; if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) s->cirrus_blt_srcpitch = ((w + 31) >> 5); else s->cirrus_blt_srcpitch = ((w + 7) >> 3); } else { /* always align input size to 32 bits */ s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3; } s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; } s->cirrus_srcptr = s->cirrus_bltbuf; s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; cirrus_update_memory_access(s); return 1;}static int cirrus_bitblt_videotocpu(CirrusVGAState * s){ /* XXX */#ifdef DEBUG_BITBLT printf("cirrus: bitblt (video to cpu) is not implemented yet\n");#endif return 0;}static int cirrus_bitblt_videotovideo(CirrusVGAState * s){ int ret; if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { ret = cirrus_bitblt_videotovideo_patterncopy(s); } else { ret = cirrus_bitblt_videotovideo_copy(s); } if (ret) cirrus_bitblt_reset(s); return ret;}static void cirrus_bitblt_start(CirrusVGAState * s){ uint8_t blt_rop; s->gr[0x31] |= CIRRUS_BLT_BUSY; s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1; s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1; s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8)); s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8)); s->cirrus_blt_dstaddr = (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16)); s->cirrus_blt_srcaddr = (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16)); s->cirrus_blt_mode = s->gr[0x30]; s->cirrus_blt_modeext = s->gr[0x33]; 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_TRANSPARENTCOMP) { if (s->cirrus_blt_pixelwidth > 2) { printf("src transparent without colorexpand must be 8bpp or 16bpp\n"); goto bitblt_ignore; } 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_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; } else { s->cirrus_rop = cirrus_fwd_transp_rop[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, uint32_t *pline_compare){ CirrusVGAState * s = (CirrusVGAState *)s1; uint32_t start_addr, line_offset, line_compare; 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; line_compare = s->cr[0x18] | ((s->cr[0x07] & 0x10) << 4) | ((s->cr[0x09] & 0x40) << 3); *pline_compare = line_compare;}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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -