Somewhat-working Matrox Productiva G100

This commit is contained in:
Cacodemon345
2023-12-31 02:19:11 +06:00
parent 8f087d0cf1
commit bd1a5e03b0
3 changed files with 270 additions and 19 deletions

View File

@@ -439,6 +439,7 @@ extern const device_t millennium_device;
extern const device_t mystique_device; extern const device_t mystique_device;
extern const device_t mystique_220_device; extern const device_t mystique_220_device;
extern const device_t millennium_ii_device; extern const device_t millennium_ii_device;
extern const device_t productiva_g100_device;
/* Oak OTI-0x7 */ /* Oak OTI-0x7 */
extern const device_t oti037c_device; extern const device_t oti037c_device;

View File

@@ -41,6 +41,7 @@
#define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" #define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN"
#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" #define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI"
#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" #define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi"
#define ROM_G100 "roms/video/matrox/productiva8mbsdr.BIN"
#define FIFO_SIZE 65536 #define FIFO_SIZE 65536
#define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_MASK (FIFO_SIZE - 1)
@@ -166,6 +167,14 @@
#define REG_SECADDRESS 0x2c40 #define REG_SECADDRESS 0x2c40
#define REG_SECEND 0x2c44 #define REG_SECEND 0x2c44
#define REG_SOFTRAP 0x2c48 #define REG_SOFTRAP 0x2c48
#define REG_ALPHASTART 0x2c70
#define REG_ALPHACTRL 0x2c7c
#define REG_ALPHAXINC 0x2c74
#define REG_ALPHAYINC 0x2c78
#define REG_FOGSTART 0x1cc4
#define REG_FOGXINC 0x1cd4
#define REG_FOGYINC 0x1ce4
#define REG_FOGCOL 0x1cf4
/*Mystique only*/ /*Mystique only*/
#define REG_PALWTADD 0x3c00 #define REG_PALWTADD 0x3c00
@@ -319,6 +328,7 @@
#define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_32 (2 << 0)
#define MACCESS_PWIDTH_24 (3 << 0) #define MACCESS_PWIDTH_24 (3 << 0)
#define MACCESS_ZWIDTH (1 << 3) #define MACCESS_ZWIDTH (1 << 3)
#define MACCESS_FOGEN (1 << 26)
#define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_TLUTLOAD (1 << 29)
#define MACCESS_NODITHER (1 << 30) #define MACCESS_NODITHER (1 << 30)
#define MACCESS_DIT555 (1 << 31) #define MACCESS_DIT555 (1 << 31)
@@ -359,7 +369,10 @@
#define TEXCTL_PALSEL_MASK (0xf << 4) #define TEXCTL_PALSEL_MASK (0xf << 4)
#define TEXCTL_TPITCH_SHIFT (16) #define TEXCTL_TPITCH_SHIFT (16)
#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) #define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT)
#define TEXCTL_TPITCHLIN (1 << 8)
#define TEXCTL_TPITCHEXT_MASK (0x7ff << 9)
#define TEXCTL_NPCEN (1 << 21) #define TEXCTL_NPCEN (1 << 21)
#define TEXCTL_AZEROEXTEND (1 << 23)
#define TEXCTL_DECALCKEY (1 << 24) #define TEXCTL_DECALCKEY (1 << 24)
#define TEXCTL_TAKEY (1 << 25) #define TEXCTL_TAKEY (1 << 25)
#define TEXCTL_TAMASK (1 << 26) #define TEXCTL_TAMASK (1 << 26)
@@ -394,6 +407,7 @@ enum {
MGA_1064SG, /*Mystique*/ MGA_1064SG, /*Mystique*/
MGA_1164SG, /*Mystique 220*/ MGA_1164SG, /*Mystique 220*/
MGA_2164W, /*Millennium II*/ MGA_2164W, /*Millennium II*/
MGA_G100, /*Productiva G100*/
}; };
enum { enum {
@@ -494,7 +508,9 @@ typedef struct mystique_t {
pitch, plnwt, ybot, ydstorg, pitch, plnwt, ybot, ydstorg,
ytop, texorg, texwidth, texheight, ytop, texorg, texwidth, texheight,
texctl, textrans, zorg, ydst_lin, texctl, textrans, zorg, ydst_lin,
src_addr, z_base, iload_rem_data, highv_data; src_addr, z_base, iload_rem_data, highv_data,
fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24,
alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24;
uint32_t src[4], ar[7], uint32_t src[4], ar[7],
dr[16], tmr[9]; dr[16], tmr[9];
@@ -2560,6 +2576,38 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
mystique->softrap_pending += 1; mystique->softrap_pending += 1;
break; break;
case REG_ALPHACTRL:
mystique->dwgreg.alphactrl = val;
break;
case REG_ALPHASTART:
mystique->dwgreg.alphastart = val;
break;
case REG_ALPHAXINC:
mystique->dwgreg.alphaxinc = val;
break;
case REG_ALPHAYINC:
mystique->dwgreg.alphayinc = val;
break;
case REG_FOGCOL:
mystique->dwgreg.fogcol = val;
break;
case REG_FOGSTART:
mystique->dwgreg.fogstart = val;
break;
case REG_FOGXINC:
mystique->dwgreg.fogxinc = val;
break;
case REG_FOGYINC:
mystique->dwgreg.fogyinc = val;
break;
default: default:
mystique_accel_ctrl_write_b(addr, val & 0xff, priv); mystique_accel_ctrl_write_b(addr, val & 0xff, priv);
mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv);
@@ -4781,7 +4829,7 @@ blit_trap(mystique_t *mystique)
} }
static int static int
texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a)
{ {
svga_t *svga = &mystique->svga; svga_t *svga = &mystique->svga;
@@ -4794,6 +4842,16 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
uint16_t src = 0; uint16_t src = 0;
int s; int s;
int t; int t;
int tex_pitch = 1 << tex_shift;
*tex_a = 255;
if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN))
{
tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9;
if (tex_pitch == 0)
tex_pitch = 2048;
}
if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { if (mystique->dwgreg.texctl & TEXCTL_NPCEN) {
const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK);
@@ -4828,7 +4886,7 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) {
case TEXCTL_TEXFORMAT_TW4: case TEXCTL_TEXFORMAT_TW4:
src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; src = svga->vram[(mystique->dwgreg.texorg + (((t * tex_pitch) + s) >> 1)) & mystique->vram_mask];
if (s & 1) if (s & 1)
src >>= 4; src >>= 4;
else else
@@ -4839,14 +4897,14 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
*atransp = 0; *atransp = 0;
break; break;
case TEXCTL_TEXFORMAT_TW8: case TEXCTL_TEXFORMAT_TW8:
src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; src = svga->vram[(mystique->dwgreg.texorg + (t * tex_pitch) + s) & mystique->vram_mask];
*tex_r = mystique->lut[src].r; *tex_r = mystique->lut[src].r;
*tex_g = mystique->lut[src].g; *tex_g = mystique->lut[src].g;
*tex_b = mystique->lut[src].b; *tex_b = mystique->lut[src].b;
*atransp = 0; *atransp = 0;
break; break;
case TEXCTL_TEXFORMAT_TW15: case TEXCTL_TEXFORMAT_TW15:
src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w];
*tex_r = ((src >> 10) & 0x1f) << 3; *tex_r = ((src >> 10) & 0x1f) << 3;
*tex_g = ((src >> 5) & 0x1f) << 3; *tex_g = ((src >> 5) & 0x1f) << 3;
*tex_b = (src & 0x1f) << 3; *tex_b = (src & 0x1f) << 3;
@@ -4855,8 +4913,22 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
else else
*atransp = 0; *atransp = 0;
break; break;
case TEXCTL_TEXFORMAT_TW12:
src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w];
*tex_r = ((src >> 8) & 0xf) << 3;
*tex_g = ((src >> 4) & 0xf) << 3;
*tex_b = (src & 0xf) << 3;
*tex_a = ((src >> 12) & 0xf) << 3;
if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) {
*atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key;
} else {
uint8_t ta_mask = mystique->dwgreg.ta_mask ? 0xf : 0x0;
uint8_t ta_key = mystique->dwgreg.ta_key ? 0xf : 0x0;
*atransp = (((src >> 12) & 0xf) & ta_mask) == ta_key;
}
break;
case TEXCTL_TEXFORMAT_TW16: case TEXCTL_TEXFORMAT_TW16:
src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w];
*tex_r = (src >> 11) << 3; *tex_r = (src >> 11) << 3;
*tex_g = ((src >> 5) & 0x3f) << 2; *tex_g = ((src >> 5) & 0x3f) << 2;
*tex_b = (src & 0x1f) << 3; *tex_b = (src & 0x1f) << 3;
@@ -4903,6 +4975,8 @@ blit_texture_trap(mystique_t *mystique)
uint32_t s_back = mystique->dwgreg.tmr[6]; uint32_t s_back = mystique->dwgreg.tmr[6];
uint32_t t_back = mystique->dwgreg.tmr[7]; uint32_t t_back = mystique->dwgreg.tmr[7];
uint32_t q_back = mystique->dwgreg.tmr[8]; uint32_t q_back = mystique->dwgreg.tmr[8];
uint32_t a_back = mystique->dwgreg.alphastart;
uint32_t fog_back = mystique->dwgreg.fogstart;
while (x_l != x_r) { 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]) { 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]) {
@@ -4921,11 +4995,15 @@ blit_texture_trap(mystique_t *mystique)
int tex_r = 0; int tex_r = 0;
int tex_g = 0; int tex_g = 0;
int tex_b = 0; int tex_b = 0;
int tex_a = 0;
int ctransp; int ctransp;
int atransp = 0; int atransp = 0;
int i_r = 0; int i_r = 0;
int i_g = 0; int i_g = 0;
int i_b = 0; int i_b = 0;
int i_a = 255;
int i_fog = 0;
uint8_t final_a = 255;
if (!(mystique->dwgreg.dr[4] & (1 << 23))) if (!(mystique->dwgreg.dr[4] & (1 << 23)))
i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff;
@@ -4934,7 +5012,43 @@ blit_texture_trap(mystique_t *mystique)
if (!(mystique->dwgreg.dr[12] & (1 << 23))) if (!(mystique->dwgreg.dr[12] & (1 << 23)))
i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff;
ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); if (mystique->type >= MGA_G100)
{
if (!(mystique->dwgreg.alphastart & (1 << 23)))
i_a = (mystique->dwgreg.alphastart >> 15) & 0xff;
else
i_a = 0;
if (!(mystique->dwgreg.fogstart & (1 << 23)))
i_fog = (mystique->dwgreg.fogstart >> 15) & 0xff;
else
i_fog = 0;
}
ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp, &tex_a);
if (mystique->type >= MGA_G100)
{
uint8_t alpha_sel = (mystique->dwgreg.alphactrl >> 24) & 3;
switch (alpha_sel)
{
case 0x0: /* alpha from texture */
final_a = tex_a;
break;
default:
case 0x1: /* interpolated alpha */
if ((mystique->dwgreg.alphactrl & (1 << 11)))
final_a = i_a;
break;
case 0x2: /* modulated alpha */
if (!(mystique->dwgreg.alphactrl & (1 << 11)))
final_a = tex_a;
else
final_a = ((i_a * tex_a) >> 8) & 0xFF;
break;
}
}
switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) {
case 0: case 0:
@@ -4984,6 +5098,36 @@ blit_texture_trap(mystique_t *mystique)
fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY));
} }
if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN))
{
tex_r = (tex_r * ((255 - i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * (i_fog / 255.);
tex_g = (tex_g * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * (i_fog / 255.);
tex_b = (tex_b * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * (i_fog / 255.);
}
if (final_a != 255)
{
if (dest32) {
uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l];
uint8_t dst_b = dst_col & 0xFF;
uint8_t dst_g = (dst_col >> 8) & 0xFF;
uint8_t dst_r = (dst_col >> 16) & 0xFF;
tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.);
tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.);
tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.);
} else {
uint16_t dst_col = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w];
uint8_t dst_b = (dst_col & 0x1f) << 3;
uint8_t dst_g = (dst_col & 0x7e0) >> 3;
uint8_t dst_r = (dst_col & 0xf800) >> 8;
tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.);
tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.);
tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.);
}
}
if (dest32) { if (dest32) {
((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16);
svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount;
@@ -5021,6 +5165,10 @@ skip_pixel:
mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0];
mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2];
mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4];
mystique->dwgreg.fogstart += mystique->dwgreg.fogxinc;
mystique->dwgreg.alphastart += mystique->dwgreg.alphaxinc;
mystique->dwgreg.fogstart &= 0xFFFFFF;
mystique->dwgreg.alphastart &= 0xFFFFFF;
} }
if (mystique->maccess_running & MACCESS_ZWIDTH) { if (mystique->maccess_running & MACCESS_ZWIDTH) {
@@ -5030,12 +5178,16 @@ skip_pixel:
mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; 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.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[4] = r_back + mystique->dwgreg.dr[7];
mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11];
mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15];
mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1];
mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3];
mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5];
mystique->dwgreg.fogstart = fog_back + mystique->dwgreg.fogyinc;
mystique->dwgreg.alphastart = a_back + mystique->dwgreg.alphayinc;
mystique->dwgreg.fogstart &= 0xFFFFFF;
mystique->dwgreg.alphastart &= 0xFFFFFF;
while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) {
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0];
@@ -5063,6 +5215,10 @@ skip_pixel:
mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0];
mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2];
mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4];
mystique->dwgreg.fogstart += dx * mystique->dwgreg.fogxinc;
mystique->dwgreg.alphastart += dx * mystique->dwgreg.alphaxinc;
mystique->dwgreg.fogstart &= 0xFFFFFF;
mystique->dwgreg.alphastart &= 0xFFFFFF;
mystique->dwgreg.ydst++; mystique->dwgreg.ydst++;
mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst &= 0x7fffff;
@@ -5703,10 +5859,16 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
break; break;
case 0x02: case 0x02:
ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); if (mystique->type == MGA_G100)
ret = 0x01;
else
ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a);
break; /*MGA*/ break; /*MGA*/
case 0x03: case 0x03:
ret = 0x05; if (mystique->type == MGA_G100)
ret = 0x10;
else
ret = 0x05;
break; break;
case PCI_REG_COMMAND: case PCI_REG_COMMAND:
@@ -5795,6 +5957,10 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0x33: case 0x33:
ret = mystique->pci_regs[0x33]; ret = mystique->pci_regs[0x33];
break; break;
case 0x34:
ret = mystique->type == MGA_G100 ? 0xdc : 0x00;
break;
case 0x3c: case 0x3c:
ret = mystique->int_line; ret = mystique->int_line;
@@ -5831,6 +5997,59 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
ret = mystique_ctrl_read_b(addr, mystique); ret = mystique_ctrl_read_b(addr, mystique);
break; break;
case 0xdc:
ret = 0x01;
break;
case 0xdd:
ret = 0xf0;
break;
case 0xde:
ret = 0x21;
break;
/* No support for turning off the video adapter yet. */
case 0xe0:
ret = 0x0;
break;
case 0xf0:
ret = 0x02;
break;
case 0xf1:
ret = 0x00;
break;
case 0xf2:
ret = 0x10;
break;
case 0xf4:
ret = 0x1;
break;
case 0xf5:
ret = 0x2;
break;
case 0xf7:
ret = 0x1;
break;
case 0xf8:
ret = mystique->pci_regs[0xf8] & 0x7;
break;
case 0xf9:
ret = mystique->pci_regs[0xf9] & 0x3;
break;
case 0xfb:
ret = mystique->pci_regs[0xfb];
break;
default: default:
break; break;
} }
@@ -5964,6 +6183,18 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
mystique_ctrl_write_b(addr, val, mystique); mystique_ctrl_write_b(addr, val, mystique);
break; break;
case 0xf8:
mystique->pci_regs[0xf8] = val & 0x7;
break;
case 0xf9:
mystique->pci_regs[0xf9] = val & 0x3;
break;
case 0xfb:
mystique->pci_regs[0xfb] = val;
break;
default: default:
break; break;
} }
@@ -6017,6 +6248,8 @@ mystique_init(const device_t *info)
romfn = ROM_MILLENNIUM_II; romfn = ROM_MILLENNIUM_II;
else if (mystique->type == MGA_1064SG) else if (mystique->type == MGA_1064SG)
romfn = ROM_MYSTIQUE; romfn = ROM_MYSTIQUE;
else if (mystique->type == MGA_G100)
romfn = ROM_G100;
else else
romfn = ROM_MYSTIQUE_220; romfn = ROM_MYSTIQUE_220;
@@ -6186,6 +6419,12 @@ millennium_ii_available(void)
return rom_present(ROM_MILLENNIUM_II); return rom_present(ROM_MILLENNIUM_II);
} }
static int
matrox_g100_available(void)
{
return rom_present(ROM_G100);
}
static void static void
mystique_speed_changed(void *priv) mystique_speed_changed(void *priv)
{ {
@@ -6242,10 +6481,6 @@ static const device_config_t millennium_ii_config[] = {
.type = CONFIG_SELECTION, .type = CONFIG_SELECTION,
.selection = .selection =
{ {
{
.description = "4 MB",
.value = 4
},
{ {
.description = "8 MB", .description = "8 MB",
.value = 8 .value = 8
@@ -6321,3 +6556,17 @@ const device_t millennium_ii_device = {
.force_redraw = mystique_force_redraw, .force_redraw = mystique_force_redraw,
.config = millennium_ii_config .config = millennium_ii_config
}; };
const device_t productiva_g100_device = {
.name = "Matrox Productiva G100",
.internal_name = "productiva_g100",
.flags = DEVICE_AGP,
.local = MGA_G100,
.init = mystique_init,
.close = mystique_close,
.reset = NULL,
{ .available = matrox_g100_available },
.speed_changed = mystique_speed_changed,
.force_redraw = mystique_force_redraw,
.config = millennium_ii_config
};

View File

@@ -257,6 +257,7 @@ video_cards[] = {
{ &s3_virge_357_agp_device }, { &s3_virge_357_agp_device },
{ &s3_diamond_stealth_4000_agp_device }, { &s3_diamond_stealth_4000_agp_device },
{ &s3_trio3d2x_agp_device }, { &s3_trio3d2x_agp_device },
{ &productiva_g100_device },
{ &velocity_100_agp_device }, { &velocity_100_agp_device },
{ &velocity_200_agp_device }, { &velocity_200_agp_device },
{ &voodoo_3_1000_agp_device }, { &voodoo_3_1000_agp_device },