Non-working Millennium II

This commit is contained in:
Cacodemon345
2023-12-29 02:13:40 +06:00
parent 137581c080
commit 277581daea
3 changed files with 274 additions and 42 deletions

View File

@@ -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;

View File

@@ -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;
}
@@ -792,7 +805,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 +919,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
@@ -1037,7 +1050,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 +1454,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;
@@ -1811,7 +1824,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 +2020,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 +2303,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 +2430,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;
@@ -4113,6 +4159,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 +4285,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 +4334,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 +4353,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 +4419,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 +4585,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 +4600,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 +4625,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 +4662,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 +4681,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 +4705,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 +4842,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 +4860,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 +4945,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 +4962,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 +4977,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 +5004,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];
@@ -5474,6 +5634,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 +5655,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 +5706,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 +5795,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 +5832,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 +5965,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,7 +5982,7 @@ mystique_init(const device_t *info)
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique);
if (mystique->type == MGA_2064W) {
if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) {
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium);
svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20,
mystique_recalctimings,
@@ -5945,6 +6127,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 +6181,34 @@ 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 = ""
}
},
.default_int = 8
},
{
.type = CONFIG_END
}
// clang-format on
};
const device_t millennium_device = {
.name = "Matrox Millennium",
.internal_name = "millennium",
@@ -6034,3 +6250,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 = mystique_config
};

View File

@@ -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 },