Merge pull request #3959 from Cacodemon345/mga-millennium-ii
MGA: Add Matrox Millennium II video adapter
This commit is contained in:
@@ -438,6 +438,7 @@ extern const device_t pgc_device;
|
||||
extern const device_t millennium_device;
|
||||
extern const device_t mystique_device;
|
||||
extern const device_t mystique_220_device;
|
||||
extern const device_t millennium_ii_device;
|
||||
|
||||
/* Oak OTI-0x7 */
|
||||
extern const device_t oti037c_device;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -36,9 +37,10 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN"
|
||||
#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI"
|
||||
#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi"
|
||||
#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN"
|
||||
#define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN"
|
||||
#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI"
|
||||
#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi"
|
||||
|
||||
#define FIFO_SIZE 65536
|
||||
#define FIFO_MASK (FIFO_SIZE - 1)
|
||||
@@ -111,6 +113,13 @@
|
||||
#define REG_DR14 0x1cf8
|
||||
#define REG_DR15 0x1cfc
|
||||
|
||||
#define REG_DR0_Z32LSB 0x2c50
|
||||
#define REG_DR0_Z32MSB 0x2c54
|
||||
#define REG_DR2_Z32LSB 0x2c60
|
||||
#define REG_DR2_Z32MSB 0x2c64
|
||||
#define REG_DR3_Z32LSB 0x2c68
|
||||
#define REG_DR3_Z32MSB 0x2c6c
|
||||
|
||||
#define REG_FIFOSTATUS 0x1e10
|
||||
#define REG_STATUS 0x1e14
|
||||
#define REG_ICLEAR 0x1e18
|
||||
@@ -309,6 +318,7 @@
|
||||
#define MACCESS_PWIDTH_16 (1 << 0)
|
||||
#define MACCESS_PWIDTH_32 (2 << 0)
|
||||
#define MACCESS_PWIDTH_24 (3 << 0)
|
||||
#define MACCESS_ZWIDTH (1 << 3)
|
||||
#define MACCESS_TLUTLOAD (1 << 29)
|
||||
#define MACCESS_NODITHER (1 << 30)
|
||||
#define MACCESS_DIT555 (1 << 31)
|
||||
@@ -383,6 +393,7 @@ enum {
|
||||
MGA_2064W, /*Millennium*/
|
||||
MGA_1064SG, /*Mystique*/
|
||||
MGA_1164SG, /*Mystique 220*/
|
||||
MGA_2164W, /*Millennium II*/
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -488,6 +499,8 @@ typedef struct mystique_t {
|
||||
uint32_t src[4], ar[7],
|
||||
dr[16], tmr[9];
|
||||
|
||||
uint64_t extended_dr[4];
|
||||
|
||||
struct
|
||||
{
|
||||
int sdydxl, scanleft, sdxl, sdy,
|
||||
@@ -675,7 +688,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x3c6:
|
||||
case 0x3c7:
|
||||
case 0x3c9:
|
||||
if (mystique->type == MGA_2064W) {
|
||||
if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) {
|
||||
tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga);
|
||||
return;
|
||||
}
|
||||
@@ -723,22 +736,57 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x3df:
|
||||
if (mystique->crtcext_idx == 1)
|
||||
svga->dpms = !!(val & 0x30);
|
||||
old = mystique->crtcext_regs[mystique->crtcext_idx];
|
||||
if (mystique->crtcext_idx < 6)
|
||||
mystique->crtcext_regs[mystique->crtcext_idx] = val;
|
||||
|
||||
|
||||
if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) &&
|
||||
(mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) {
|
||||
svga->rowoffset = svga->crtc[0x13] |
|
||||
((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4);
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) |
|
||||
(svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) {
|
||||
if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) {
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
|
||||
svga->ma_latch <<= 1;
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->ma_latch <<= 1;
|
||||
|
||||
if (mystique->type == MGA_2164W)
|
||||
{
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
if (svga->dispend >= 1024)
|
||||
svga->rowoffset <<= 1;
|
||||
break;
|
||||
case 24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
if (svga->hdisp >= 1024)
|
||||
svga->rowoffset <<= 1;
|
||||
break;
|
||||
case 32:
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
svga->rowoffset <<= 1;
|
||||
if (svga->hdisp >= 1024) {
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->ma_latch != mystique->ma_latch_old) {
|
||||
if (svga->interlace && svga->oddeven)
|
||||
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) +
|
||||
@@ -753,12 +801,22 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
|
||||
if (mystique->crtcext_idx == 4) {
|
||||
if (svga->gdcreg[6] & 0xc) {
|
||||
/*64k banks*/
|
||||
svga->read_bank = (val & 0x7f) << 16;
|
||||
svga->write_bank = (val & 0x7f) << 16;
|
||||
if (mystique->type >= MGA_2164W) {
|
||||
svga->read_bank = val << 16;
|
||||
svga->write_bank = val << 16;
|
||||
} else {
|
||||
svga->read_bank = (val & 0x7f) << 16;
|
||||
svga->write_bank = (val & 0x7f) << 16;
|
||||
}
|
||||
} else {
|
||||
/*128k banks*/
|
||||
svga->read_bank = (val & 0x7e) << 16;
|
||||
svga->write_bank = (val & 0x7e) << 16;
|
||||
if (mystique->type >= MGA_2164W) {
|
||||
svga->read_bank = (val & 0xfe) << 16;
|
||||
svga->write_bank = (val & 0xfe) << 16;
|
||||
} else {
|
||||
svga->read_bank = (val & 0x7e) << 16;
|
||||
svga->write_bank = (val & 0x7e) << 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -792,7 +850,7 @@ mystique_in(uint16_t addr, void *priv)
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
if (mystique->type == MGA_2064W)
|
||||
if (mystique->type == MGA_2064W || mystique->type == MGA_2164W)
|
||||
temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga);
|
||||
else
|
||||
temp = svga_in(addr, svga);
|
||||
@@ -906,7 +964,7 @@ mystique_recalctimings(svga_t *svga)
|
||||
if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10)
|
||||
svga->split |= 0x400;
|
||||
|
||||
if (mystique->type == MGA_2064W) {
|
||||
if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) {
|
||||
tvp3026_recalctimings(svga->ramdac, svga);
|
||||
svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80);
|
||||
} else
|
||||
@@ -922,7 +980,7 @@ mystique_recalctimings(svga_t *svga)
|
||||
if (mystique->type >= MGA_1064SG)
|
||||
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
|
||||
|
||||
if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) {
|
||||
if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) {
|
||||
svga->rowoffset <<= 1;
|
||||
if (mystique->type >= MGA_1064SG)
|
||||
svga->ma_latch <<= 1;
|
||||
@@ -931,7 +989,8 @@ mystique_recalctimings(svga_t *svga)
|
||||
if (mystique->type >= MGA_1064SG) {
|
||||
/*Mystique, unlike most SVGA cards, allows display start to take
|
||||
effect mid-screen*/
|
||||
svga->ma_latch <<= 1;
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->ma_latch <<= 1;
|
||||
/* Only change maback so the new display start will take effect on the next
|
||||
horizontal retrace. */
|
||||
if (svga->ma_latch != mystique->ma_latch_old) {
|
||||
@@ -944,34 +1003,63 @@ mystique_recalctimings(svga_t *svga)
|
||||
mystique->ma_latch_old = svga->ma_latch;
|
||||
}
|
||||
|
||||
svga->rowoffset <<= 1;
|
||||
switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) {
|
||||
case XMULCTRL_DEPTH_8:
|
||||
case XMULCTRL_DEPTH_2G8V16:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_15:
|
||||
case XMULCTRL_DEPTH_G16V16:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_32:
|
||||
case XMULCTRL_DEPTH_32_OVERLAYED:
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
if (!(mystique->type >= MGA_2164W))
|
||||
svga->rowoffset <<= 1;
|
||||
if (mystique->type != MGA_2164W) {
|
||||
switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) {
|
||||
case XMULCTRL_DEPTH_8:
|
||||
case XMULCTRL_DEPTH_2G8V16:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_15:
|
||||
case XMULCTRL_DEPTH_G16V16:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case XMULCTRL_DEPTH_32:
|
||||
case XMULCTRL_DEPTH_32_OVERLAYED:
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
if (svga->dispend >= 1024)
|
||||
svga->rowoffset <<= 1;
|
||||
break;
|
||||
case 24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
if (svga->hdisp >= 1024)
|
||||
svga->rowoffset <<= 1;
|
||||
break;
|
||||
case 32:
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
svga->rowoffset <<= 1;
|
||||
if (svga->hdisp >= 1024) {
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (svga->bpp) {
|
||||
@@ -1037,7 +1125,7 @@ mystique_recalc_mapping(mystique_t *mystique)
|
||||
mem_mapping_disable(&mystique->ctrl_mapping);
|
||||
|
||||
if (mystique->lfb_base)
|
||||
mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000);
|
||||
mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, (mystique->type >= MGA_2164W) ? 0x1000000 : 0x800000);
|
||||
else
|
||||
mem_mapping_disable(&mystique->lfb_mapping);
|
||||
|
||||
@@ -1441,7 +1529,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv)
|
||||
int rs2 = 0;
|
||||
int rs3 = 0;
|
||||
|
||||
if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) {
|
||||
if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) {
|
||||
/*RAMDAC*/
|
||||
addr_0x0f = addr & 0x0f;
|
||||
|
||||
@@ -1675,6 +1763,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv)
|
||||
case REG_MACCESS + 3:
|
||||
WRITE8(addr, mystique->maccess, val);
|
||||
mystique->dwgreg.dither = mystique->maccess >> 30;
|
||||
mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg;
|
||||
break;
|
||||
|
||||
case REG_MCTLWTST:
|
||||
@@ -1811,7 +1900,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv)
|
||||
case REG_YDSTORG + 2:
|
||||
case REG_YDSTORG + 3:
|
||||
WRITE8(addr, mystique->dwgreg.ydstorg, val);
|
||||
mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg;
|
||||
mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg;
|
||||
break;
|
||||
case REG_YTOP:
|
||||
case REG_YTOP + 1:
|
||||
@@ -2007,7 +2096,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv)
|
||||
int rs2 = 0;
|
||||
int rs3 = 0;
|
||||
|
||||
if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) {
|
||||
if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) {
|
||||
/*RAMDAC*/
|
||||
addr_0x0f = addr & 0x0f;
|
||||
|
||||
@@ -2290,7 +2379,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
|
||||
case REG_ZORG:
|
||||
mystique->dwgreg.zorg = val;
|
||||
mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg;
|
||||
mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg;
|
||||
break;
|
||||
|
||||
case REG_PLNWT:
|
||||
@@ -2417,14 +2506,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
mystique->dwgreg.ar[6] = val;
|
||||
break;
|
||||
|
||||
case REG_DR0_Z32LSB:
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFFFFF) | val;
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR0_Z32MSB:
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull);
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR2_Z32LSB:
|
||||
mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFFFFF) | val;
|
||||
mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR2_Z32MSB:
|
||||
mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull);
|
||||
mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR3_Z32LSB:
|
||||
mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFFFFF) | val;
|
||||
mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR3_Z32MSB:
|
||||
mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull);
|
||||
mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
case REG_DR0:
|
||||
mystique->dwgreg.dr[0] = val;
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)val << 16ull);
|
||||
break;
|
||||
case REG_DR2:
|
||||
mystique->dwgreg.dr[2] = val;
|
||||
mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFull) | ((uint64_t)val << 16ull);
|
||||
break;
|
||||
case REG_DR3:
|
||||
mystique->dwgreg.dr[3] = val;
|
||||
mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFull) | ((uint64_t)val << 16ull);
|
||||
break;
|
||||
case REG_DR4:
|
||||
mystique->dwgreg.dr[4] = val;
|
||||
@@ -2503,6 +2625,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
case REG_PRIMEND:
|
||||
thread_wait_mutex(mystique->dma.lock);
|
||||
mystique->dma.primend = val;
|
||||
//pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend);
|
||||
if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) {
|
||||
mystique->endprdmasts_pending = 0;
|
||||
mystique->status &= ~STATUS_ENDPRDMASTS;
|
||||
@@ -4113,6 +4236,29 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK)
|
||||
{
|
||||
switch (z_mode) {
|
||||
case DWGCTRL_ZMODE_ZE:
|
||||
return (z == old_z);
|
||||
case DWGCTRL_ZMODE_ZNE:
|
||||
return (z != old_z);
|
||||
case DWGCTRL_ZMODE_ZLT:
|
||||
return (z < old_z);
|
||||
case DWGCTRL_ZMODE_ZLTE:
|
||||
return (z <= old_z);
|
||||
case DWGCTRL_ZMODE_ZGT:
|
||||
return (z > old_z);
|
||||
case DWGCTRL_ZMODE_ZGTE:
|
||||
return (z >= old_z);
|
||||
|
||||
case DWGCTRL_ZMODE_NOZCMP:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blit_line(mystique_t *mystique, int closed)
|
||||
{
|
||||
@@ -4216,18 +4362,30 @@ blit_line(mystique_t *mystique, int closed)
|
||||
x = mystique->dwgreg.xdst;
|
||||
while (mystique->dwgreg.length > 0) {
|
||||
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
uint16_t old_z = z_p[x];
|
||||
bool z_check_pass = false;
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull);
|
||||
uint32_t *z_p = (uint32_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 4 + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
uint32_t old_z = z_p[x];
|
||||
z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
if (z_write && z_check_pass) {
|
||||
z_p[x] = z;
|
||||
}
|
||||
} else {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
uint16_t old_z = z_p[x];
|
||||
z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
if (z_write && z_check_pass) {
|
||||
z_p[x] = z;
|
||||
}
|
||||
}
|
||||
|
||||
if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) {
|
||||
if (z_check_pass) {
|
||||
int r = 0;
|
||||
int g = 0;
|
||||
int b = 0;
|
||||
|
||||
if (z_write)
|
||||
z_p[x] = z;
|
||||
|
||||
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
|
||||
case MACCESS_PWIDTH_16:
|
||||
if (!(mystique->dwgreg.dr[4] & (1 << 23)))
|
||||
@@ -4253,7 +4411,13 @@ blit_line(mystique_t *mystique, int closed)
|
||||
else
|
||||
mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK));
|
||||
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6];
|
||||
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10];
|
||||
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14];
|
||||
@@ -4266,7 +4430,13 @@ blit_line(mystique_t *mystique, int closed)
|
||||
else
|
||||
x += (mystique->dwgreg.sgn.sdxl ? -1 : 1);
|
||||
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[3];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7];
|
||||
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11];
|
||||
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15];
|
||||
@@ -4326,6 +4496,7 @@ static void
|
||||
blit_trap(mystique_t *mystique)
|
||||
{
|
||||
svga_t *svga = &mystique->svga;
|
||||
uint64_t z_back_32;
|
||||
uint32_t z_back;
|
||||
uint32_t r_back;
|
||||
uint32_t g_back;
|
||||
@@ -4491,12 +4662,14 @@ blit_trap(mystique_t *mystique)
|
||||
|
||||
for (y = 0; y < mystique->dwgreg.length; y++) {
|
||||
uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4];
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
int16_t x_l = mystique->dwgreg.fxleft & 0xffff;
|
||||
int16_t x_r = mystique->dwgreg.fxright & 0xffff;
|
||||
int16_t old_x_l = x_l;
|
||||
int dx;
|
||||
|
||||
z_back_32 = mystique->dwgreg.extended_dr[0];
|
||||
|
||||
z_back = mystique->dwgreg.dr[0];
|
||||
r_back = mystique->dwgreg.dr[4];
|
||||
g_back = mystique->dwgreg.dr[8];
|
||||
@@ -4504,10 +4677,18 @@ blit_trap(mystique_t *mystique)
|
||||
|
||||
while (x_l != x_r) {
|
||||
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t old_z = z_p[x_l];
|
||||
bool z_check_pass = false;
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull);
|
||||
uint32_t old_z = *(uint32_t*)&z_p[x_l * 2];
|
||||
z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
} else {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t old_z = z_p[x_l];
|
||||
z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
}
|
||||
|
||||
if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) {
|
||||
if (z_check_pass) {
|
||||
uint32_t dst = 0;
|
||||
uint32_t old_dst;
|
||||
int r = 0;
|
||||
@@ -4521,8 +4702,13 @@ blit_trap(mystique_t *mystique)
|
||||
if (!(mystique->dwgreg.dr[12] & (1 << 23)))
|
||||
b = (mystique->dwgreg.dr[12] >> 15) & 0xff;
|
||||
|
||||
if (z_write)
|
||||
z_p[x_l] = z;
|
||||
if (z_write) {
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
*(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull);
|
||||
}
|
||||
else
|
||||
z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
}
|
||||
|
||||
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
|
||||
case MACCESS_PWIDTH_8:
|
||||
@@ -4553,7 +4739,13 @@ blit_trap(mystique_t *mystique)
|
||||
}
|
||||
}
|
||||
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6];
|
||||
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10];
|
||||
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14];
|
||||
@@ -4566,7 +4758,13 @@ blit_trap(mystique_t *mystique)
|
||||
mystique->pixel_count++;
|
||||
}
|
||||
|
||||
mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7];
|
||||
mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11];
|
||||
mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15];
|
||||
@@ -4584,7 +4782,13 @@ blit_trap(mystique_t *mystique)
|
||||
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5];
|
||||
|
||||
dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff);
|
||||
mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6];
|
||||
mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10];
|
||||
mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14];
|
||||
@@ -4715,12 +4919,14 @@ blit_texture_trap(mystique_t *mystique)
|
||||
|
||||
for (y = 0; y < mystique->dwgreg.length; y++) {
|
||||
uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4];
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask];
|
||||
int16_t x_l = mystique->dwgreg.fxleft & 0xffff;
|
||||
int16_t x_r = mystique->dwgreg.fxright & 0xffff;
|
||||
int16_t old_x_l = x_l;
|
||||
int dx;
|
||||
|
||||
uint64_t z_back_32 = mystique->dwgreg.extended_dr[0];
|
||||
|
||||
uint32_t z_back = mystique->dwgreg.dr[0];
|
||||
uint32_t r_back = mystique->dwgreg.dr[4];
|
||||
uint32_t g_back = mystique->dwgreg.dr[8];
|
||||
@@ -4731,10 +4937,18 @@ blit_texture_trap(mystique_t *mystique)
|
||||
|
||||
while (x_l != x_r) {
|
||||
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t old_z = z_p[x_l];
|
||||
bool z_check_pass = false;
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull);
|
||||
uint32_t old_z = *(uint32_t*)&z_p[x_l * 2];
|
||||
z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
} else {
|
||||
uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
uint16_t old_z = z_p[x_l];
|
||||
z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK);
|
||||
}
|
||||
|
||||
if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) {
|
||||
if (z_check_pass) {
|
||||
int tex_r = 0;
|
||||
int tex_g = 0;
|
||||
int tex_b = 0;
|
||||
@@ -4808,8 +5022,13 @@ blit_texture_trap(mystique_t *mystique)
|
||||
((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1);
|
||||
svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount;
|
||||
}
|
||||
if (z_write)
|
||||
z_p[x_l] = z;
|
||||
if (z_write) {
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
*(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull);
|
||||
}
|
||||
else
|
||||
z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
skip_pixel:
|
||||
@@ -4820,7 +5039,13 @@ skip_pixel:
|
||||
|
||||
mystique->pixel_count++;
|
||||
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6];
|
||||
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10];
|
||||
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14];
|
||||
@@ -4829,7 +5054,13 @@ skip_pixel:
|
||||
mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4];
|
||||
}
|
||||
|
||||
mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7];
|
||||
mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11];
|
||||
mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15];
|
||||
@@ -4850,7 +5081,13 @@ skip_pixel:
|
||||
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5];
|
||||
|
||||
dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff);
|
||||
mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2];
|
||||
if (mystique->maccess_running & MACCESS_ZWIDTH) {
|
||||
mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2];
|
||||
mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF;
|
||||
} else {
|
||||
mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2];
|
||||
mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull);
|
||||
}
|
||||
mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6];
|
||||
mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10];
|
||||
mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14];
|
||||
@@ -4888,6 +5125,7 @@ blit_bitblt(mystique_t *mystique)
|
||||
case DWGCTRL_ATYPE_BLK:
|
||||
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) {
|
||||
case DWGCTRL_BLTMOD_BMONOLEF:
|
||||
case DWGCTRL_BLTMOD_BMONOWF:
|
||||
src_addr = mystique->dwgreg.ar[3];
|
||||
|
||||
for (y = 0; y < mystique->dwgreg.length; y++) {
|
||||
@@ -4896,7 +5134,7 @@ blit_bitblt(mystique_t *mystique)
|
||||
while (1) {
|
||||
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) {
|
||||
uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask;
|
||||
int bit_offset = src_addr & 7;
|
||||
int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7);
|
||||
uint32_t old_dst;
|
||||
|
||||
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
|
||||
@@ -4994,6 +5232,7 @@ blit_bitblt(mystique_t *mystique)
|
||||
case DWGCTRL_ATYPE_RSTR:
|
||||
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) {
|
||||
case DWGCTRL_BLTMOD_BMONOLEF:
|
||||
case DWGCTRL_BLTMOD_BMONOWF:
|
||||
if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN)
|
||||
fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n");
|
||||
|
||||
@@ -5005,7 +5244,7 @@ blit_bitblt(mystique_t *mystique)
|
||||
|
||||
while (1) {
|
||||
uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask;
|
||||
int bit_offset = src_addr & 7;
|
||||
int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7);
|
||||
|
||||
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) {
|
||||
uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol;
|
||||
@@ -5474,6 +5713,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
|
||||
mystique_t *mystique = (mystique_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
if (mystique->type >= MGA_2164W)
|
||||
{
|
||||
/* Millennium II and later Matrox cards swap MGABASE1 and 2. */
|
||||
if (addr >= 0x10 && addr <= 0x13)
|
||||
addr += 0x4;
|
||||
else if (addr >= 0x14 && addr <= 0x17)
|
||||
addr -= 0x4;
|
||||
}
|
||||
|
||||
if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40))
|
||||
ret = 0x00;
|
||||
else
|
||||
@@ -5486,7 +5734,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a;
|
||||
ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a);
|
||||
break; /*MGA*/
|
||||
case 0x03:
|
||||
ret = 0x05;
|
||||
@@ -5537,7 +5785,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
|
||||
ret = 0x00;
|
||||
break; /*Linear frame buffer*/
|
||||
case 0x16:
|
||||
ret = (mystique->lfb_base >> 16) & 0x80;
|
||||
ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80);
|
||||
break;
|
||||
case 0x17:
|
||||
ret = mystique->lfb_base >> 24;
|
||||
@@ -5626,6 +5874,15 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
mystique_t *mystique = (mystique_t *) priv;
|
||||
|
||||
if (mystique->type >= MGA_2164W)
|
||||
{
|
||||
/* Millennium II and later Matrox cards swap MGABASE1 and 2. */
|
||||
if (addr >= 0x10 && addr <= 0x13)
|
||||
addr += 0x4;
|
||||
else if (addr >= 0x14 && addr <= 0x17)
|
||||
addr -= 0x4;
|
||||
}
|
||||
|
||||
switch (addr) {
|
||||
case PCI_REG_COMMAND:
|
||||
mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80;
|
||||
@@ -5654,11 +5911,13 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x16:
|
||||
if (mystique->type >= MGA_2164W)
|
||||
break;
|
||||
mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16);
|
||||
mystique_recalc_mapping(mystique);
|
||||
break;
|
||||
case 0x17:
|
||||
mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24);
|
||||
mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24);
|
||||
mystique_recalc_mapping(mystique);
|
||||
break;
|
||||
|
||||
@@ -5785,6 +6044,8 @@ mystique_init(const device_t *info)
|
||||
|
||||
if (mystique->type == MGA_2064W)
|
||||
romfn = ROM_MILLENNIUM;
|
||||
else if (mystique->type == MGA_2164W)
|
||||
romfn = ROM_MILLENNIUM_II;
|
||||
else if (mystique->type == MGA_1064SG)
|
||||
romfn = ROM_MYSTIQUE;
|
||||
else
|
||||
@@ -5800,8 +6061,8 @@ mystique_init(const device_t *info)
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique);
|
||||
|
||||
if (mystique->type == MGA_2064W) {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium);
|
||||
if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, (mystique->type == MGA_2164W) ? &timing_matrox_mystique : &timing_matrox_millennium);
|
||||
svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20,
|
||||
mystique_recalctimings,
|
||||
mystique_in, mystique_out,
|
||||
@@ -5811,6 +6072,8 @@ mystique_init(const device_t *info)
|
||||
mystique->svga.ramdac = device_add(&tvp3026_ramdac_device);
|
||||
mystique->svga.clock_gen = mystique->svga.ramdac;
|
||||
mystique->svga.getclock = tvp3026_getclock;
|
||||
if (mystique->vram_size >= 16)
|
||||
mystique->svga.decode_mask = mystique->svga.vram_mask;
|
||||
tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac);
|
||||
} else {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique);
|
||||
@@ -5945,6 +6208,12 @@ mystique_220_available(void)
|
||||
return rom_present(ROM_MYSTIQUE_220);
|
||||
}
|
||||
|
||||
static int
|
||||
millennium_ii_available(void)
|
||||
{
|
||||
return rom_present(ROM_MILLENNIUM_II);
|
||||
}
|
||||
|
||||
static void
|
||||
mystique_speed_changed(void *priv)
|
||||
{
|
||||
@@ -5993,6 +6262,38 @@ static const device_config_t mystique_config[] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t millennium_ii_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "4 MB",
|
||||
.value = 4
|
||||
},
|
||||
{
|
||||
.description = "8 MB",
|
||||
.value = 8
|
||||
},
|
||||
{
|
||||
.description = "16 MB",
|
||||
.value = 16
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 8
|
||||
},
|
||||
{
|
||||
.type = CONFIG_END
|
||||
}
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t millennium_device = {
|
||||
.name = "Matrox Millennium",
|
||||
.internal_name = "millennium",
|
||||
@@ -6034,3 +6335,17 @@ const device_t mystique_220_device = {
|
||||
.force_redraw = mystique_force_redraw,
|
||||
.config = mystique_config
|
||||
};
|
||||
|
||||
const device_t millennium_ii_device = {
|
||||
.name = "Matrox Millennium II",
|
||||
.internal_name = "millennium_ii",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = MGA_2164W,
|
||||
.init = mystique_init,
|
||||
.close = mystique_close,
|
||||
.reset = NULL,
|
||||
{ .available = millennium_ii_available },
|
||||
.speed_changed = mystique_speed_changed,
|
||||
.force_redraw = mystique_force_redraw,
|
||||
.config = millennium_ii_config
|
||||
};
|
||||
|
||||
@@ -205,6 +205,7 @@ video_cards[] = {
|
||||
{ &s3_diamond_stealth_4000_pci_device },
|
||||
{ &s3_trio3d2x_pci_device },
|
||||
{ &millennium_device },
|
||||
{ &millennium_ii_device },
|
||||
{ &mystique_device },
|
||||
{ &mystique_220_device },
|
||||
{ &tgui9440_pci_device },
|
||||
|
||||
Reference in New Issue
Block a user