# HG changeset patch # User TomW # Date 1405371370 -3600 # Node ID 614f796ff7ed7e6ae40993b24308d3b26b737b2c # Parent 42d0b879eb9e11b3790cdeaf94991e9c95af44b5 Added configurable VRAM for Mach64, ET4000/w32p, Oak and Trident graphics cards. diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_ati_mach64.c --- a/src/vid_ati_mach64.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_ati_mach64.c Mon Jul 14 21:56:10 2014 +0100 @@ -35,6 +35,9 @@ int bank_r[2]; int bank_w[2]; + + uint32_t vram_size; + uint32_t vram_mask; uint32_t config_cntl; @@ -386,8 +389,18 @@ } 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: WRITE8(port, mach64->config_cntl, val); + mach64_updatemapping(mach64); break; } } @@ -2201,7 +2214,10 @@ 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 @@ } } +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 @@ mach64gx_available, mach64_speed_changed, mach64_force_redraw, - mach64_add_status_info + mach64_add_status_info, + mach64gx_config }; diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_et4000w32.c --- a/src/vid_et4000w32.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_et4000w32.c Mon Jul 14 21:56:10 2014 +0100 @@ -33,6 +33,8 @@ uint8_t banking, banking2; uint8_t pci_regs[256]; + + int interleaved; /*Accelerator*/ struct @@ -142,7 +144,7 @@ // 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 @@ // 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_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 @@ 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 @@ et4000w32p_available, et4000w32p_speed_changed, et4000w32p_force_redraw, - et4000w32p_add_status_info + et4000w32p_add_status_info, + et4000w32p_config }; diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_oti067.c --- a/src/vid_oti067.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_oti067.c Mon Jul 14 21:56:10 2014 +0100 @@ -17,6 +17,9 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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 @@ oti067_available, oti067_speed_changed, oti067_force_redraw, - oti067_add_status_info + oti067_add_status_info, + oti067_config }; device_t oti067_acer386_device = { diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_svga.c --- a/src/vid_svga.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_svga.c Mon Jul 14 21:56:10 2014 +0100 @@ -66,6 +66,7 @@ // 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; diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_tgui9440.c --- a/src/vid_tgui9440.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_tgui9440.c Mon Jul 14 21:56:10 2014 +0100 @@ -53,6 +53,8 @@ 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 @@ 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 @@ 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 @@ tgui9440_available, tgui_speed_changed, tgui_force_redraw, - tgui_add_status_info + tgui_add_status_info, + tgui9440_config }; diff -r 42d0b879eb9e -r 614f796ff7ed src/vid_tvga.c --- a/src/vid_tvga.c Sat Jul 12 14:22:54 2014 +0100 +++ b/src/vid_tvga.c Mon Jul 14 21:56:10 2014 +0100 @@ -25,6 +25,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ tvga8900d_available, tvga_speed_changed, tvga_force_redraw, - tvga_add_status_info + tvga_add_status_info, + tvga_config };