Added configurable VRAM for Mach64, ET4000/w32p, Oak and Trident graphics cards.

This commit is contained in:
TomW 2014-07-14 21:56:10 +01:00
commit 4657e9f2c5
6 changed files with 241 additions and 36 deletions

View file

@ -35,6 +35,9 @@ typedef struct mach64_t
int bank_r[2];
int bank_w[2];
uint32_t vram_size;
uint32_t vram_mask;
uint32_t config_cntl;
@ -386,8 +389,18 @@ void mach64_updatemapping(mach64_t *mach64)
}
if (mach64->linear_base)
{
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
if ((mach64->config_cntl & 3) == 2)
{
/*8 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
}
else
{
/*4 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000);
}
}
else
{
@ -606,9 +619,9 @@ void mach64_start_line(mach64_t *mach64)
mach64->accel.op = OP_LINE;
}
#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & 0x7fffff]; \
else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff]; \
else dat = *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff];
#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \
else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \
else dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask];
#define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \
{ \
@ -632,18 +645,18 @@ void mach64_start_line(mach64_t *mach64)
#define WRITE(addr, width) if (width == 0) \
{ \
svga->vram[(addr) & 0x7fffff] = dest_dat; \
svga->changedvram[((addr) & 0x7fffff) >> 12] = changeframecount; \
svga->vram[(addr) & mach64->vram_mask] = dest_dat; \
svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \
} \
else if (width == 1) \
{ \
*(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff] = dest_dat; \
svga->changedvram[(((addr) << 1) & 0x7fffff) >> 12] = changeframecount; \
*(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \
} \
else \
{ \
*(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff] = dest_dat; \
svga->changedvram[(((addr) << 2) & 0x7fffff) >> 12] = changeframecount; \
*(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \
}
void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
@ -979,7 +992,7 @@ void mach64_load_context(mach64_t *mach64)
while (mach64->context_load_cntl & 0x30000)
{
addr = (0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256;
addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask;
mach64->context_mask = *(uint32_t *)&svga->vram[addr];
#ifdef MACH64_DEBUG
pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask);
@ -1823,7 +1836,6 @@ uint8_t mach64_ext_inb(uint16_t port, void *p)
case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4);
mach64->config_cntl = (mach64->config_cntl & ~3) | 2;
READ8(port, mach64->config_cntl);
break;
@ -1988,6 +2000,7 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p)
case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
WRITE8(port, mach64->config_cntl, val);
mach64_updatemapping(mach64);
break;
}
}
@ -2201,7 +2214,10 @@ void *mach64gx_init()
mach64_t *mach64 = malloc(sizeof(mach64_t));
memset(mach64, 0, sizeof(mach64_t));
svga_init(&mach64->svga, mach64, 1 << 22, /*4mb*/
mach64->vram_size = device_get_config_int("memory");
mach64->vram_mask = (mach64->vram_size << 20) - 1;
svga_init(&mach64->svga, mach64, mach64->vram_size << 20,
mach64_recalctimings,
mach64_in, mach64_out,
mach64_hwcursor_draw,
@ -2309,6 +2325,37 @@ int mach64_add_status_info(char *s, int max_len, void *p)
}
}
static device_config_t mach64gx_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "1 MB",
.value = 1
},
{
.description = "2 MB",
.value = 2
},
{
.description = "4 MB",
.value = 4
},
{
.description = ""
}
},
.default_int = 4
},
{
.type = -1
}
};
device_t mach64gx_device =
{
"ATI Mach64GX",
@ -2318,5 +2365,6 @@ device_t mach64gx_device =
mach64gx_available,
mach64_speed_changed,
mach64_force_redraw,
mach64_add_status_info
mach64_add_status_info,
mach64gx_config
};

View file

@ -33,6 +33,8 @@ typedef struct et4000w32p_t
uint8_t banking, banking2;
uint8_t pci_regs[256];
int interleaved;
/*Accelerator*/
struct
@ -142,7 +144,7 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
// pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val);
et4000w32p_recalcmapping(et4000);
}
if (svga->crtcreg == 0x36)
if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36)
et4000w32p_recalcmapping(et4000);
break;
@ -330,6 +332,9 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000)
// pclog("ET4K map %02X\n", map);
}
et4000->linearbase_old = et4000->linearbase;
if (!et4000->interleaved && (et4000->svga.crtc[0x32] & 0x80))
mem_mapping_disable(&svga->mapping);
}
#define ACL_WRST 1
@ -1010,10 +1015,15 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p)
void *et4000w32p_init()
{
int vram_size;
et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t));
memset(et4000, 0, sizeof(et4000w32p_t));
svga_init(&et4000->svga, et4000, 1 << 21, /*2mb*/
vram_size = device_get_config_int("memory");
et4000->interleaved = (vram_size == 2) ? 1 : 0;
svga_init(&et4000->svga, et4000, vram_size << 20,
et4000w32p_recalctimings,
et4000w32p_in, et4000w32p_out,
et4000w32p_hwcursor_draw,
@ -1074,6 +1084,33 @@ int et4000w32p_add_status_info(char *s, int max_len, void *p)
return svga_add_status_info(s, max_len, &et4000w32p->svga);
}
static device_config_t et4000w32p_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "1 MB",
.value = 1
},
{
.description = "2 MB",
.value = 2
},
{
.description = ""
}
},
.default_int = 2
},
{
.type = -1
}
};
device_t et4000w32p_device =
{
"Tseng Labs ET4000/w32p",
@ -1083,5 +1120,6 @@ device_t et4000w32p_device =
et4000w32p_available,
et4000w32p_speed_changed,
et4000w32p_force_redraw,
et4000w32p_add_status_info
et4000w32p_add_status_info,
et4000w32p_config
};

View file

@ -17,6 +17,9 @@ typedef struct oti067_t
int index;
uint8_t regs[32];
uint32_t vram_size;
uint32_t vram_mask;
} oti067_t;
void oti067_out(uint16_t addr, uint8_t val, void *p)
@ -56,7 +59,13 @@ void oti067_out(uint16_t addr, uint8_t val, void *p)
switch (oti067->index)
{
case 0xD:
svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff;
svga->vrammask = (val & 0xc) ? oti067->vram_mask : 0x3ffff;
if ((val & 0x80) && oti067->vram_size == 256)
mem_mapping_disable(&svga->mapping);
else
mem_mapping_enable(&svga->mapping);
if (!(val & 0x80))
svga->vrammask = 0x3ffff;
break;
case 0x11:
svga->read_bank = (val & 0xf) * 65536;
@ -92,7 +101,6 @@ uint8_t oti067_in(uint16_t addr, void *p)
break;
case 0x3DF:
if (oti067->index==0x10) temp = 0x18;
else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0;
else temp = oti067->regs[oti067->index];
break;
@ -113,14 +121,17 @@ void oti067_recalctimings(svga_t *svga)
svga->interlace = oti067->regs[0x14] & 0x80;
}
void *oti067_common_init(char *bios_fn)
void *oti067_common_init(char *bios_fn, int vram_size)
{
oti067_t *oti067 = malloc(sizeof(oti067_t));
memset(oti067, 0, sizeof(oti067_t));
rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, 0);
svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
oti067->vram_size = vram_size;
oti067->vram_mask = (vram_size << 10) - 1;
svga_init(&oti067->svga, oti067, vram_size << 10,
oti067_recalctimings,
oti067_in, oti067_out,
NULL,
@ -134,12 +145,13 @@ void *oti067_common_init(char *bios_fn)
void *oti067_init()
{
return oti067_common_init("roms/oti067/bios.bin");
int vram_size = device_get_config_int("memory");
return oti067_common_init("roms/oti067/bios.bin", vram_size);
}
void *oti067_acer386_init()
{
oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin");
oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512);
if (oti067)
oti067->bios_rom.rom[0x5d] = 0x74;
@ -182,6 +194,33 @@ int oti067_add_status_info(char *s, int max_len, void *p)
return svga_add_status_info(s, max_len, &oti067->svga);
}
static device_config_t oti067_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "256 kB",
.value = 256
},
{
.description = "512 kB",
.value = 512
},
{
.description = ""
}
},
.default_int = 512
},
{
.type = -1
}
};
device_t oti067_device =
{
"Oak OTI-067",
@ -191,7 +230,8 @@ device_t oti067_device =
oti067_available,
oti067_speed_changed,
oti067_force_redraw,
oti067_add_status_info
oti067_add_status_info,
oti067_config
};
device_t oti067_acer386_device =
{

View file

@ -66,6 +66,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
// pclog("Set mono handler\n");
io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
}
svga_recalctimings(svga);
break;
case 0x3C4:
svga->seqaddr = val;

View file

@ -53,6 +53,8 @@ typedef struct tgui_t
uint8_t ramdac_ctrl;
int clock_m, clock_n, clock_k;
uint32_t vram_size, vram_mask;
} tgui_t;
void tgui_recalcmapping(tgui_t *tgui);
@ -470,9 +472,12 @@ void *tgui9440_init()
tgui_t *tgui = malloc(sizeof(tgui_t));
memset(tgui, 0, sizeof(tgui_t));
tgui->vram_size = device_get_config_int("memory") << 20;
tgui->vram_mask = tgui->vram_size - 1;
rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0);
svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/
svga_init(&tgui->svga, tgui, tgui->vram_size,
tgui_recalctimings,
tgui_in, tgui_out,
tgui_hwcursor_draw,
@ -1113,6 +1118,33 @@ int tgui_add_status_info(char *s, int max_len, void *p)
return svga_add_status_info(s, max_len, &tgui->svga);
}
static device_config_t tgui9440_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "1 MB",
.value = 1
},
{
.description = "2 MB",
.value = 2
},
{
.description = ""
}
},
.default_int = 2
},
{
.type = -1
}
};
device_t tgui9440_device =
{
"Trident TGUI 9440",
@ -1122,5 +1154,6 @@ device_t tgui9440_device =
tgui9440_available,
tgui_speed_changed,
tgui_force_redraw,
tgui_add_status_info
tgui_add_status_info,
tgui9440_config
};

View file

@ -25,6 +25,9 @@ typedef struct tvga_t
int oldmode;
uint8_t oldctrl1;
uint8_t oldctrl2, newctrl2;
int vram_size;
uint32_t vram_mask;
} tvga_t;
void tvga_out(uint16_t addr, uint8_t val, void *p)
@ -47,16 +50,16 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
break;
case 0xC:
if (svga->seqregs[0xe] & 0x80)
svga->seqregs[0xc] = val;
svga->seqregs[0xc] = val;
break;
case 0xd:
if (tvga->oldmode)
tvga->oldctrl2 = val;
else
{
tvga->oldctrl2 = val;
svga->vrammask = (val & 0x10) ? 0xfffff : 0x3ffff;
tvga->newctrl2 = val;
svga_recalctimings(svga);
}
else
tvga->newctrl2 = val;
break;
case 0xE:
if (tvga->oldmode)
@ -107,6 +110,12 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
svga_recalctimings(svga);
}
}
switch (svga->crtcreg)
{
case 0x1e:
svga->vrammask = (val & 0x80) ? tvga->vram_mask : 0x3ffff;
break;
}
return;
case 0x3D8:
tvga->tvga_3d8 = val;
@ -207,7 +216,7 @@ void tvga_recalctimings(svga_t *svga)
svga->interlace = svga->crtc[0x1e] & 4;
if (svga->interlace)
svga->rowoffset >>= 1;
switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4))
{
case 2: svga->clock = cpuclock/44900000.0; break;
@ -246,10 +255,13 @@ void *tvga8900d_init()
{
tvga_t *tvga = malloc(sizeof(tvga_t));
memset(tvga, 0, sizeof(tvga_t));
tvga->vram_size = device_get_config_int("memory") << 10;
tvga->vram_mask = tvga->vram_size - 1;
rom_init(&tvga->bios_rom, "roms/trident.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
svga_init(&tvga->svga, tvga, tvga->vram_size,
tvga_recalctimings,
tvga_in, tvga_out,
NULL,
@ -295,6 +307,38 @@ int tvga_add_status_info(char *s, int max_len, void *p)
return svga_add_status_info(s, max_len, &tvga->svga);
}
static device_config_t tvga_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "256 kB",
.value = 256
},
{
.description = "512 kB",
.value = 512
},
{
.description = "1 MB",
.value = 1024
},
/*Chip supports 2mb, but drivers are buggy*/
{
.description = ""
}
},
.default_int = 1024
},
{
.type = -1
}
};
device_t tvga8900d_device =
{
"Trident TVGA 8900D",
@ -304,5 +348,6 @@ device_t tvga8900d_device =
tvga8900d_available,
tvga_speed_changed,
tvga_force_redraw,
tvga_add_status_info
tvga_add_status_info,
tvga_config
};