Skip to content

Commit

Permalink
Matrox Productiva G100 working (expect maybe alpha stipple)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed Dec 31, 2023
1 parent bd1a5e0 commit ca21ea5
Showing 1 changed file with 161 additions and 41 deletions.
202 changes: 161 additions & 41 deletions src/video/vid_mga.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
#define REG_DR2_Z32MSB 0x2c64
#define REG_DR3_Z32LSB 0x2c68
#define REG_DR3_Z32MSB 0x2c6c
#define REG_TEXFILTER 0x2c58

#define REG_FIFOSTATUS 0x1e10
#define REG_STATUS 0x1e14
Expand Down Expand Up @@ -510,7 +511,8 @@ typedef struct mystique_t {
texctl, textrans, zorg, ydst_lin,
src_addr, z_base, iload_rem_data, highv_data,
fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24,
alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24;
alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24,
texfilter;

uint32_t src[4], ar[7],
dr[16], tmr[9];
Expand Down Expand Up @@ -658,6 +660,15 @@ static const uint8_t trans_masks[16][16] = {

static int8_t dither5[256][2][2];
static int8_t dither6[256][2][2];
static double bayer_mat[4][4] =
{
{ 0.0, 8. / 16., 2. / 16., 10. / 16.},
{ 12. / 16., 4. / 16., 14. / 16., 6. / 16.},
{ 3. / 16., 11. / 16., 1. / 16., 9. / 16.},
{ 15. / 16., 7. / 16., 13. / 16., 5. / 16.},
};

static const int grey_lut[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239 };

static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 };
static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 };
Expand Down Expand Up @@ -2608,6 +2619,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
mystique->dwgreg.fogyinc = val;
break;

case REG_TEXFILTER:
mystique->dwgreg.texfilter = val;
break;

default:
mystique_accel_ctrl_write_b(addr, val & 0xff, priv);
mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv);
Expand Down Expand Up @@ -4828,45 +4843,18 @@ blit_trap(mystique_t *mystique)
mystique->blitter_complete_refcount++;
}

static int
texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a)
static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *tex_a, int *atransp, int s, int t, int tex_pitch)
{
svga_t *svga = &mystique->svga;

const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT);
const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK;
const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK;
const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT;
const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT;
const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT;
uint16_t src = 0;
int s;
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) {
const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK);
const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK);
const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK;
svga_t* svga = &mystique->svga;
uint16_t src = 0x0;

s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift;
t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift;
} else {
const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK);
const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK);
int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8] /*>> 16*/) : 0;
int atransp_dummy = 0;

s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q /*<< 8*/) >> s_shift; /*((16+20)-12);*/
t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q /*<< 8*/) >> t_shift; /*((16+20)-9);*/
}
if (!atransp)
atransp = &atransp_dummy;

if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) {
if (s < 0)
Expand Down Expand Up @@ -4915,10 +4903,11 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
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;
*tex_r = ((src >> 8) & 0xf) << 4;
*tex_g = ((src >> 4) & 0xf) << 4;
*tex_b = (src & 0xf) << 4;
*tex_a = ((src >> 12) & 0xf) << 4;
pclog("TEXFORMAT_TW12\n");
if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) {
*atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key;
} else {
Expand All @@ -4938,6 +4927,114 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra
fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK);
break;
}
return src;
}

static double lerp(double v0, double v1, double t) {
return (1. - t) * v0 + t * v1;
}

static int
texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a)
{
svga_t *svga = &mystique->svga;

const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT);
const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK;
const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK;
const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT;
const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT;
const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT;
uint16_t src = 0;
int s;
int t;
int tex_pitch = 1 << tex_shift;
double s_frac = 0;
double t_frac = 0;

*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) {
const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK);
const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK);

s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift;
t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift;
s_frac = (((int32_t) mystique->dwgreg.tmr[6] >> s_shift) & ((1 << s_shift) - 1)) / (double)(1 << s_shift);
t_frac = (((int32_t) mystique->dwgreg.tmr[7] >> t_shift) & ((1 << t_shift) - 1)) / (double)(1 << t_shift);
} else {
const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK);
const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK);
int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8]) : 0;

s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) >> s_shift;
t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) >> t_shift;
s_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << s_shift) - 1)) / (double)(1 << s_shift);
t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift);
}

if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) {
if (s < 0)
s = 0;
else if (s > w_mask)
s = w_mask;
} else
s &= w_mask;

if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) {
if (t < 0)
t = 0;
else if (t > h_mask)
t = h_mask;
} else
t &= h_mask;

src = texture_texel_fetch(mystique, tex_r, tex_g, tex_b, tex_a, atransp, s, t, tex_pitch);
switch (mystique->dwgreg.texfilter & 3)
{
case 0:
s_frac = t_frac = 0;
break;
case 1:
case 2:
break;
case 3:
s_frac = t_frac = .25;
break;
}
if (s_frac && s != w_mask)
{
int s_tex_r = 0, s_tex_g = 0, s_tex_b = 0, s_tex_a = 255;
texture_texel_fetch(mystique, &s_tex_r, &s_tex_g, &s_tex_b, &s_tex_a, NULL, s + 1, t, tex_pitch);
*tex_r = (int)lerp(*tex_r, s_tex_r, s_frac);
*tex_g = (int)lerp(*tex_g, s_tex_g, s_frac);
*tex_b = (int)lerp(*tex_b, s_tex_b, s_frac);
*tex_a = (int)lerp(*tex_a, s_tex_a, s_frac);
if (*tex_r > 255) *tex_r = 255;
if (*tex_g > 255) *tex_g = 255;
if (*tex_b > 255) *tex_b = 255;
if (*tex_a > 255) *tex_a = 255;
}
if (t_frac && t != h_mask)
{
int t_tex_r = 0, t_tex_g = 0, t_tex_b = 0, t_tex_a = 255;
texture_texel_fetch(mystique, &t_tex_r, &t_tex_g, &t_tex_b, &t_tex_a, NULL, s, t + 1, tex_pitch);
*tex_r = (int)lerp(*tex_r, t_tex_r, t_frac);
*tex_g = (int)lerp(*tex_g, t_tex_g, t_frac);
*tex_b = (int)lerp(*tex_b, t_tex_b, t_frac);
*tex_a = (int)lerp(*tex_a, t_tex_a, t_frac);
if (*tex_r > 255) *tex_r = 255;
if (*tex_g > 255) *tex_g = 255;
if (*tex_b > 255) *tex_b = 255;
if (*tex_a > 255) *tex_a = 255;
}

return ((src & tkmask) == tckey);
}
Expand Down Expand Up @@ -4995,7 +5092,7 @@ blit_texture_trap(mystique_t *mystique)
int tex_r = 0;
int tex_g = 0;
int tex_b = 0;
int tex_a = 0;
int tex_a = 255;
int ctransp;
int atransp = 0;
int i_r = 0;
Expand Down Expand Up @@ -5107,6 +5204,25 @@ blit_texture_trap(mystique_t *mystique)

if (final_a != 255)
{
/* Does this actually work? I'm not sure. */
if (final_a & 0xf) {
double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3];
double final_a_frac = (final_a & 0xf) / 16.;
if (final_a_frac >= threshold) {
if ((final_a >> 4) == 0x0)
final_a = grey_lut[1];
else if ((final_a >> 4) == 0xf)
final_a = 255;
else
final_a = grey_lut[final_a >> 4];
} else {
if ((final_a >> 4) == 0x0)
final_a = 0;
else
final_a = grey_lut[(final_a >> 4) - 1];
}
}

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;
Expand Down Expand Up @@ -6480,7 +6596,11 @@ static const device_config_t millennium_ii_config[] = {
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
{
.description = "4 MB",
.value = 4
},
{
.description = "8 MB",
.value = 8
Expand Down

0 comments on commit ca21ea5

Please sign in to comment.