Ported the latest Matrox MGA fixes from PCem.

Removed useless header.
This commit is contained in:
TC1995
2020-03-31 00:33:49 +02:00
parent cff4545082
commit e9710d4b25
4 changed files with 157 additions and 29 deletions

View File

@@ -1 +0,0 @@
void cs8230_init(void);

View File

@@ -114,6 +114,9 @@ typedef struct svga_t
vertical line interrupt*/
int (*line_compare)(struct svga_t *svga);
/*Called at the start of vertical sync*/
void (*vsync_callback)(struct svga_t *svga);
/*If set then another device is driving the monitor output and the SVGA
card should not attempt to display anything */
int override;

View File

@@ -209,6 +209,17 @@
#define XREG_XZOOMCTRL 0x38
#define XREG_XSENSETEST 0x3a
#define XREG_XCRCREML 0x3c
#define XREG_XCRCREMH 0x3d
#define XREG_XCRCBITSEL 0x3e
#define XREG_XCOLKEYMSKL 0x40
#define XREG_XCOLKEYMSKH 0x41
#define XREG_XCOLKEYL 0x42
#define XREG_XCOLKEYH 0x43
#define XREG_XPIXPLLCM 0x4c
#define XREG_XPIXPLLCN 0x4d
#define XREG_XPIXPLLCP 0x4e
@@ -230,6 +241,11 @@
#define XPIXPLLSTAT_SYSLOCK (1 << 6)
#define XCURCTRL_CURMODE_MASK (3 << 0)
#define XCURCTRL_CURMODE_3COL (1 << 0)
#define XCURCTRL_CURMODE_XGA (2 << 0)
#define XCURCTRL_CURMODE_XWIN (3 << 0)
#define DWGCTRL_OPCODE_MASK (0xf << 0)
#define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0)
#define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0)
@@ -304,6 +320,7 @@
#define DMA_MODE_VECTOR 2
#define STATUS_SOFTRAPEN (1 << 0)
#define STATUS_VSYNCPEN (1 << 4)
#define STATUS_VLINEPEN (1 << 5)
#define STATUS_DWGENGSTS (1 << 16)
#define STATUS_ENDPRDMASTS (1 << 17)
@@ -387,7 +404,10 @@ typedef struct mystique_t
xmulctrl, xgenctrl,
xmiscctrl, xpixclkctrl,
xvrefctrl, ien, dmamod,
dmadatasiz, dirdatasiz;
dmadatasiz, dirdatasiz,
xcolkeymskl, xcolkeymskh,
xcolkeyl, xcolkeyh,
xcrcbitsel;
uint8_t pci_regs[256], crtcext_regs[6],
xreg_regs[256], dmamap[16];
@@ -641,17 +661,22 @@ mystique_out(uint16_t addr, uint8_t val, void *p)
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80))
if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80))
return;
if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80))
if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg & 0x3f];
svga->crtc[svga->crtcreg & 31] = val;
svga->crtc[svga->crtcreg & 0x3f] = val;
if (old != val) {
if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) {
if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
if (svga->crtcreg == 0x11) {
if (!(val & 0x10))
mystique->status &= ~STATUS_VSYNCPEN;
mystique_update_irqs(mystique);
}
}
break;
@@ -733,6 +758,17 @@ mystique_line_compare(svga_t *svga)
return 0;
}
static void
mystique_vsync_callback(svga_t *svga)
{
mystique_t *mystique = (mystique_t *)svga->p;
if (svga->crtc[0x11] & 0x10) {
mystique->status |= STATUS_VSYNCPEN;
mystique_update_irqs(mystique);
}
}
void
mystique_recalctimings(svga_t *svga)
@@ -906,10 +942,13 @@ void mystique_recalc_mapping(mystique_t *mystique)
static void
mystique_update_irqs(mystique_t *mystique)
{
svga_t *svga = &mystique->svga;
int irq = 0;
if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN)
irq = 1;
if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10)
irq = 1;
if (irq)
pci_set_irq(mystique->card, PCI_INTA);
@@ -971,6 +1010,10 @@ mystique_read_xreg(mystique_t *mystique, int reg)
ret = mystique->xgenctrl;
break;
case XREG_XVREFCTRL:
ret = mystique->xvrefctrl;
break;
case XREG_XGENIOCTRL:
ret = mystique->xgenioctrl;
break;
@@ -992,6 +1035,39 @@ mystique_read_xreg(mystique_t *mystique, int reg)
ret = mystique->xzoomctrl;
break;
case XREG_XSENSETEST:
ret = 0;
if (mystique->svga.vgapal[0].b < 0x80)
ret |= 1;
if (mystique->svga.vgapal[0].g < 0x80)
ret |= 2;
if (mystique->svga.vgapal[0].r < 0x80)
ret |= 4;
break;
case XREG_XCRCREML: /*CRC not implemented*/
ret = 0;
break;
case XREG_XCRCREMH:
ret = 0;
break;
case XREG_XCRCBITSEL:
ret = mystique->xcrcbitsel;
break;
case XREG_XCOLKEYMSKL:
ret = mystique->xcolkeymskl;
break;
case XREG_XCOLKEYMSKH:
ret = mystique->xcolkeymskh;
break;
case XREG_XCOLKEYL:
ret = mystique->xcolkeyl;
break;
case XREG_XCOLKEYH:
ret = mystique->xcolkeyh;
break;
case XREG_XPIXCLKCTRL:
ret = mystique->xpixclkctrl;
break;
@@ -1096,6 +1172,36 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val)
mystique->xzoomctrl = val & 3;
break;
case XREG_XSENSETEST:
break;
case XREG_XCRCREML: /*CRC not implemented*/
break;
case XREG_XCRCREMH:
break;
case XREG_XCRCBITSEL:
mystique->xcrcbitsel = val & 0x1f;
break;
case XREG_XCOLKEYMSKL:
mystique->xcolkeymskl = val;
break;
case XREG_XCOLKEYMSKH:
mystique->xcolkeymskh = val;
break;
case XREG_XCOLKEYL:
mystique->xcolkeyl = val;
break;
case XREG_XCOLKEYH:
mystique->xcolkeyh = val;
break;
case XREG_XSYSPLLSTAT:
break;
case XREG_XPIXPLLSTAT:
break;
case XREG_XPIXCLKCTRL:
mystique->xpixclkctrl = val;
break;
@@ -1266,12 +1372,16 @@ mystique_ctrl_read_b(uint32_t addr, void *p)
ret = mystique_read_xreg(mystique, mystique->xreg_idx);
break;
case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53:
case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53:
case REG_ICLEAR: case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3:
case 0x2c30: case 0x2c31: case 0x2c32: case 0x2c33:
case 0x3e08:
break;
case 0x3c08: case 0x3c09: case 0x3c0b:
break;
default:
if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40)
break;
@@ -1990,9 +2100,8 @@ mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p)
break;
case DMA_MODE_BLIT:
if (!mystique->busy)
fatal("mystique_iload_write_l: !busy\n");
blit_iload_write(mystique, val, 32);
if (mystique->busy)
blit_iload_write(mystique, val, 32);
break;
/* default:
@@ -2140,10 +2249,11 @@ run_dma(mystique_t *mystique)
else
reg_addr += 0x1c00;
if ((reg_addr & 0x300) == 0x100)
if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD)
mystique->blitter_submit_dma_refcount++;
mystique_accel_ctrl_write_l(reg_addr, val, mystique);
if (reg_addr != REG_DMAPAD)
mystique_accel_ctrl_write_l(reg_addr, val, mystique);
}
mystique->dma.pri_header >>= 8;
@@ -2182,10 +2292,11 @@ run_dma(mystique_t *mystique)
else
reg_addr += 0x1c00;
if ((reg_addr & 0x300) == 0x100)
if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD)
mystique->blitter_submit_dma_refcount++;
mystique_accel_ctrl_write_l(reg_addr, val, mystique);
if (reg_addr != REG_DMAPAD)
mystique_accel_ctrl_write_l(reg_addr, val, mystique);
mystique->dma.sec_header >>= 8;
mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3;
@@ -2204,10 +2315,8 @@ run_dma(mystique_t *mystique)
uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK];
mystique->dma.secaddress += 4;
if (!mystique->busy)
fatal("mystique_iload_write_l: !busy\n");
blit_iload_write(mystique, val, 32);
if (mystique->busy)
blit_iload_write(mystique, val, 32);
words_transferred++;
if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
@@ -2608,6 +2717,7 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size)
const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC;
const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT;
uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4];
uint32_t data_mask = 1;
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
case MACCESS_PWIDTH_8:
@@ -2749,14 +2859,16 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size)
case DWGCTRL_BLTMOD_BMONOWF:
data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24);
data_mask = (1 << 31);
case DWGCTRL_BLTMOD_BMONOLEF:
while (size) {
if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright &&
mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot &&
((data & 0x80000000) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) &&
((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) &&
trans[mystique->dwgreg.xdst & 3]) {
uint32_t old_dst;
src = (data & 0x80000000) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol;
src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol;
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
case MACCESS_PWIDTH_8:
dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask];
@@ -2812,7 +2924,10 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size)
break;
} else
mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff;
data <<= 1;
if (data_mask == 1)
data >>= 1;
else
data <<= 1;
size--;
}
break;
@@ -4332,10 +4447,11 @@ blit_iload(mystique_t *mystique)
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) {
case DWGCTRL_ATYPE_RPL:
case DWGCTRL_ATYPE_RSTR:
case DWGCTRL_ATYPE_BLK:
case DWGCTRL_ATYPE_BLK:
/* pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); */
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) {
case DWGCTRL_BLTMOD_BFCOL:
case DWGCTRL_BLTMOD_BMONOLEF:
case DWGCTRL_BLTMOD_BMONOWF:
case DWGCTRL_BLTMOD_BU24RGB:
case DWGCTRL_BLTMOD_BU32RGB:
@@ -4580,6 +4696,7 @@ mystique_start_blit(mystique_t *mystique)
static void
mystique_hwcursor_draw(svga_t *svga, int displine)
{
mystique_t *mystique = (mystique_t *)svga->p;
int x;
uint64_t dat[2];
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
@@ -4590,15 +4707,19 @@ mystique_hwcursor_draw(svga_t *svga, int displine)
dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]);
dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]);
svga->hwcursor_latch.addr += 16;
for (x = 0; x < 64; x ++) {
if (!(dat[1] & (1ull << 63)))
buffer32->line[displine][offset + svga->x_add] = (dat[0] & (1ull << 63)) ? 0xffffff : 0;
else if (dat[0] & (1ull << 63))
switch (mystique->xcurctrl & XCURCTRL_CURMODE_MASK) {
case XCURCTRL_CURMODE_XGA:
for (x = 0; x < 64; x ++) {
if (!(dat[1] & (1ull << 63)))
buffer32->line[displine][offset + svga->x_add] = (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0];
else if (dat[0] & (1ull << 63))
buffer32->line[displine][offset + svga->x_add] ^= 0xffffff;
offset++;
dat[0] <<= 1;
dat[1] <<= 1;
offset++;
dat[0] <<= 1;
dat[1] <<= 1;
}
break;
}
if (svga->interlace && !svga->hwcursor_oddeven)
@@ -4885,6 +5006,8 @@ mystique_init(const device_t *info)
mystique->status = STATUS_ENDPRDMASTS;
mystique->svga.vsync_callback = mystique_vsync_callback;
return mystique;
}

View File

@@ -813,6 +813,9 @@ svga_poll(void *p)
svga->ma = (svga->ma << 2) + (skip << 2);
svga->maback = (svga->maback << 2) + (skip << 2);
svga->ca = (svga->ca << 2) + (skip << 2);
if (svga->vsync_callback)
svga->vsync_callback(svga);
}
if (svga->vc == svga->vtotal) {
svga->vc = 0;