void vga_out(uint16_t addr, uint8_t val, void *p) { vga_t *vga = (vga_t *)p; svga_t *svga = &vga->svga; uint8_t old; // pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3D4: svga->crtcreg = val & 0x1f; return; case 0x3D5: if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; svga_recalctimings(svga); } } break; } svga_out(addr, val, svga); }
void cirrus_do_copy(gd5446_t *gd5446, svga_t *svga, int dst, int src, int w, int h) { int sx = 0, sy = 0; int dx = 0, dy = 0; int depth = 0; int notify = 0; /* make sure to onyl copy if it's a plain copy ROP */ if (*cirrus_rop == cirrus_bitblt_rop_fwd_src || *cirrus_rop == cirrus_bitblt_rop_bkwd_src) { int width, height; depth = cirrus_get_bpp(gd5446, svga) / 8; width = svga->video_res_x; height = svga->video_res_y; /* extra x, y */ sx = (src % ABS(gd5446->blt.src_pitch)) / depth; sy = (src / ABS(gd5446->blt.src_pitch)); dx = (dst % ABS(gd5446->blt.dst_pitch)) / depth; dy = (dst / ABS(gd5446->blt.dst_pitch)); /* normalize width */ w /= depth; /* if we're doing a backward copy, we have to adjust our x/y to be the upper left corner (instead of the lower right corner) */ if (gd5446->blt.dst_pitch < 0) { sx -= (gd5446->blt.width / depth) - 1; dx -= (gd5446->blt.width / depth) - 1; sy -= gd5446->blt.height - 1; dy -= gd5446->blt.height - 1; } /* are we in the visible portion of memory? */ if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && (sx + w) <= width && (sy + h) <= height && (dx + w) <= width && (dy + h) <= height) { notify = 1; } } /* we have to flush all prending changes so that the copy is generated at the appropriate moment in time */ if (notify) { svga->fullchange = changeframecount; svga_recalctimings(svga); } /* we don't have to notify the display that this portion has changed since qemu_console_copy implies this */ cirrus_invalidate_region(gd5446, svga, gd5446->blt.dst_addr, gd5446->blt.dst_pitch, gd5446->blt.width, gd5446->blt.height); }
void tvga_out(uint16_t addr, uint8_t val, void *p) { tvga_t *tvga = (tvga_t *)p; svga_t *svga = &tvga->svga; uint8_t old; // pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3C5: switch (svga->seqaddr & 0xf) { case 0xB: tvga->oldmode=1; break; case 0xC: if (svga->seqregs[0xe] & 0x80) svga->seqregs[0xc] = val; break; case 0xd: if (tvga->oldmode) tvga->oldctrl2 = val; else { tvga->newctrl2 = val; svga_recalctimings(svga); } break; case 0xE: if (tvga->oldmode) tvga->oldctrl1 = val; else { svga->seqregs[0xe] = val ^ 2; svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; if (!(svga->gdcreg[0xf] & 1)) svga->read_bank = svga->write_bank; } return; } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); return; case 0x3CF: switch (svga->gdcaddr & 15) { case 0xE: svga->gdcreg[0xe] = val ^ 2; if ((svga->gdcreg[0xf] & 1) == 1) svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; break; case 0xF: if (val & 1) svga->read_bank = (svga->gdcreg[0xe] & 0xf) *65536; else svga->read_bank = (svga->seqregs[0xe] & 0xf) *65536; svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; break; } break; case 0x3D4: svga->crtcreg = val & 0x3f; return; case 0x3D5: if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; // if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X %04X:%04X\n", svga->crtcreg, val, CS, pc); if (old != val) { if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; svga_recalctimings(svga); } } switch (svga->crtcreg) { case 0x1e: svga->vrammask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; break; } return; case 0x3D8: tvga->tvga_3d8 = val; if (svga->gdcreg[0xf] & 4) { svga->write_bank = (val & 0x1f) * 65536; // pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc); if (!(svga->gdcreg[0xf] & 1)) { svga->read_bank = (val & 0x1f) * 65536; // pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc); } } return; case 0x3D9: tvga->tvga_3d9=val; if ((svga->gdcreg[0xf] & 5) == 5) { svga->read_bank = (val & 0x1F) * 65536; // pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc); } return; } svga_out(addr, val, svga); }
void vga_speed_changed(void *p) { vga_t *vga = (vga_t *)p; svga_recalctimings(&vga->svga); }