Added configurable VRAM for Mach64, ET4000/w32p, Oak and Trident graphics cards.
This commit is contained in:
parent
8283d3ee73
commit
4657e9f2c5
6 changed files with 241 additions and 36 deletions
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue