PCem
changeset 129:614f796ff7ed
Added configurable VRAM for Mach64, ET4000/w32p, Oak and Trident graphics cards.
| author | TomW |
|---|---|
| date | Mon Jul 14 21:56:10 2014 +0100 |
| parents | 42d0b879eb9e |
| children | a10f75a7a701 |
| files | src/vid_ati_mach64.c src/vid_et4000w32.c src/vid_oti067.c src/vid_svga.c src/vid_tgui9440.c src/vid_tvga.c |
| diffstat | 6 files changed, 241 insertions(+), 36 deletions(-) [+] |
line diff
1.1 --- a/src/vid_ati_mach64.c Sat Jul 12 14:22:54 2014 +0100 1.2 +++ b/src/vid_ati_mach64.c Mon Jul 14 21:56:10 2014 +0100 1.3 @@ -35,6 +35,9 @@ 1.4 1.5 int bank_r[2]; 1.6 int bank_w[2]; 1.7 + 1.8 + uint32_t vram_size; 1.9 + uint32_t vram_mask; 1.10 1.11 uint32_t config_cntl; 1.12 1.13 @@ -386,8 +389,18 @@ 1.14 } 1.15 if (mach64->linear_base) 1.16 { 1.17 - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); 1.18 - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); 1.19 + if ((mach64->config_cntl & 3) == 2) 1.20 + { 1.21 + /*8 MB aperture*/ 1.22 + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); 1.23 + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); 1.24 + } 1.25 + else 1.26 + { 1.27 + /*4 MB aperture*/ 1.28 + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); 1.29 + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); 1.30 + } 1.31 } 1.32 else 1.33 { 1.34 @@ -606,9 +619,9 @@ 1.35 mach64->accel.op = OP_LINE; 1.36 } 1.37 1.38 -#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & 0x7fffff]; \ 1.39 - else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff]; \ 1.40 - else dat = *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff]; 1.41 +#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \ 1.42 + else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ 1.43 + else dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; 1.44 1.45 #define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ 1.46 { \ 1.47 @@ -632,18 +645,18 @@ 1.48 1.49 #define WRITE(addr, width) if (width == 0) \ 1.50 { \ 1.51 - svga->vram[(addr) & 0x7fffff] = dest_dat; \ 1.52 - svga->changedvram[((addr) & 0x7fffff) >> 12] = changeframecount; \ 1.53 + svga->vram[(addr) & mach64->vram_mask] = dest_dat; \ 1.54 + svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \ 1.55 } \ 1.56 else if (width == 1) \ 1.57 { \ 1.58 - *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff] = dest_dat; \ 1.59 - svga->changedvram[(((addr) << 1) & 0x7fffff) >> 12] = changeframecount; \ 1.60 + *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ 1.61 + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ 1.62 } \ 1.63 else \ 1.64 { \ 1.65 - *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff] = dest_dat; \ 1.66 - svga->changedvram[(((addr) << 2) & 0x7fffff) >> 12] = changeframecount; \ 1.67 + *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ 1.68 + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ 1.69 } 1.70 1.71 void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) 1.72 @@ -979,7 +992,7 @@ 1.73 1.74 while (mach64->context_load_cntl & 0x30000) 1.75 { 1.76 - addr = (0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256; 1.77 + addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; 1.78 mach64->context_mask = *(uint32_t *)&svga->vram[addr]; 1.79 #ifdef MACH64_DEBUG 1.80 pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); 1.81 @@ -1823,7 +1836,6 @@ 1.82 1.83 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: 1.84 mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); 1.85 - mach64->config_cntl = (mach64->config_cntl & ~3) | 2; 1.86 READ8(port, mach64->config_cntl); 1.87 break; 1.88 1.89 @@ -1988,6 +2000,7 @@ 1.90 1.91 case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: 1.92 WRITE8(port, mach64->config_cntl, val); 1.93 + mach64_updatemapping(mach64); 1.94 break; 1.95 } 1.96 } 1.97 @@ -2201,7 +2214,10 @@ 1.98 mach64_t *mach64 = malloc(sizeof(mach64_t)); 1.99 memset(mach64, 0, sizeof(mach64_t)); 1.100 1.101 - svga_init(&mach64->svga, mach64, 1 << 22, /*4mb*/ 1.102 + mach64->vram_size = device_get_config_int("memory"); 1.103 + mach64->vram_mask = (mach64->vram_size << 20) - 1; 1.104 + 1.105 + svga_init(&mach64->svga, mach64, mach64->vram_size << 20, 1.106 mach64_recalctimings, 1.107 mach64_in, mach64_out, 1.108 mach64_hwcursor_draw, 1.109 @@ -2309,6 +2325,37 @@ 1.110 } 1.111 } 1.112 1.113 +static device_config_t mach64gx_config[] = 1.114 +{ 1.115 + { 1.116 + .name = "memory", 1.117 + .description = "Memory size", 1.118 + .type = CONFIG_SELECTION, 1.119 + .selection = 1.120 + { 1.121 + { 1.122 + .description = "1 MB", 1.123 + .value = 1 1.124 + }, 1.125 + { 1.126 + .description = "2 MB", 1.127 + .value = 2 1.128 + }, 1.129 + { 1.130 + .description = "4 MB", 1.131 + .value = 4 1.132 + }, 1.133 + { 1.134 + .description = "" 1.135 + } 1.136 + }, 1.137 + .default_int = 4 1.138 + }, 1.139 + { 1.140 + .type = -1 1.141 + } 1.142 +}; 1.143 + 1.144 device_t mach64gx_device = 1.145 { 1.146 "ATI Mach64GX", 1.147 @@ -2318,5 +2365,6 @@ 1.148 mach64gx_available, 1.149 mach64_speed_changed, 1.150 mach64_force_redraw, 1.151 - mach64_add_status_info 1.152 + mach64_add_status_info, 1.153 + mach64gx_config 1.154 };
2.1 --- a/src/vid_et4000w32.c Sat Jul 12 14:22:54 2014 +0100 2.2 +++ b/src/vid_et4000w32.c Mon Jul 14 21:56:10 2014 +0100 2.3 @@ -33,6 +33,8 @@ 2.4 uint8_t banking, banking2; 2.5 2.6 uint8_t pci_regs[256]; 2.7 + 2.8 + int interleaved; 2.9 2.10 /*Accelerator*/ 2.11 struct 2.12 @@ -142,7 +144,7 @@ 2.13 // pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val); 2.14 et4000w32p_recalcmapping(et4000); 2.15 } 2.16 - if (svga->crtcreg == 0x36) 2.17 + if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) 2.18 et4000w32p_recalcmapping(et4000); 2.19 break; 2.20 2.21 @@ -330,6 +332,9 @@ 2.22 // pclog("ET4K map %02X\n", map); 2.23 } 2.24 et4000->linearbase_old = et4000->linearbase; 2.25 + 2.26 + if (!et4000->interleaved && (et4000->svga.crtc[0x32] & 0x80)) 2.27 + mem_mapping_disable(&svga->mapping); 2.28 } 2.29 2.30 #define ACL_WRST 1 2.31 @@ -1010,10 +1015,15 @@ 2.32 2.33 void *et4000w32p_init() 2.34 { 2.35 + int vram_size; 2.36 et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); 2.37 memset(et4000, 0, sizeof(et4000w32p_t)); 2.38 2.39 - svga_init(&et4000->svga, et4000, 1 << 21, /*2mb*/ 2.40 + vram_size = device_get_config_int("memory"); 2.41 + 2.42 + et4000->interleaved = (vram_size == 2) ? 1 : 0; 2.43 + 2.44 + svga_init(&et4000->svga, et4000, vram_size << 20, 2.45 et4000w32p_recalctimings, 2.46 et4000w32p_in, et4000w32p_out, 2.47 et4000w32p_hwcursor_draw, 2.48 @@ -1074,6 +1084,33 @@ 2.49 return svga_add_status_info(s, max_len, &et4000w32p->svga); 2.50 } 2.51 2.52 +static device_config_t et4000w32p_config[] = 2.53 +{ 2.54 + { 2.55 + .name = "memory", 2.56 + .description = "Memory size", 2.57 + .type = CONFIG_SELECTION, 2.58 + .selection = 2.59 + { 2.60 + { 2.61 + .description = "1 MB", 2.62 + .value = 1 2.63 + }, 2.64 + { 2.65 + .description = "2 MB", 2.66 + .value = 2 2.67 + }, 2.68 + { 2.69 + .description = "" 2.70 + } 2.71 + }, 2.72 + .default_int = 2 2.73 + }, 2.74 + { 2.75 + .type = -1 2.76 + } 2.77 +}; 2.78 + 2.79 device_t et4000w32p_device = 2.80 { 2.81 "Tseng Labs ET4000/w32p", 2.82 @@ -1083,5 +1120,6 @@ 2.83 et4000w32p_available, 2.84 et4000w32p_speed_changed, 2.85 et4000w32p_force_redraw, 2.86 - et4000w32p_add_status_info 2.87 + et4000w32p_add_status_info, 2.88 + et4000w32p_config 2.89 };
3.1 --- a/src/vid_oti067.c Sat Jul 12 14:22:54 2014 +0100 3.2 +++ b/src/vid_oti067.c Mon Jul 14 21:56:10 2014 +0100 3.3 @@ -17,6 +17,9 @@ 3.4 3.5 int index; 3.6 uint8_t regs[32]; 3.7 + 3.8 + uint32_t vram_size; 3.9 + uint32_t vram_mask; 3.10 } oti067_t; 3.11 3.12 void oti067_out(uint16_t addr, uint8_t val, void *p) 3.13 @@ -56,7 +59,13 @@ 3.14 switch (oti067->index) 3.15 { 3.16 case 0xD: 3.17 - svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff; 3.18 + svga->vrammask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; 3.19 + if ((val & 0x80) && oti067->vram_size == 256) 3.20 + mem_mapping_disable(&svga->mapping); 3.21 + else 3.22 + mem_mapping_enable(&svga->mapping); 3.23 + if (!(val & 0x80)) 3.24 + svga->vrammask = 0x3ffff; 3.25 break; 3.26 case 0x11: 3.27 svga->read_bank = (val & 0xf) * 65536; 3.28 @@ -92,7 +101,6 @@ 3.29 break; 3.30 case 0x3DF: 3.31 if (oti067->index==0x10) temp = 0x18; 3.32 - else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0; 3.33 else temp = oti067->regs[oti067->index]; 3.34 break; 3.35 3.36 @@ -113,14 +121,17 @@ 3.37 svga->interlace = oti067->regs[0x14] & 0x80; 3.38 } 3.39 3.40 -void *oti067_common_init(char *bios_fn) 3.41 +void *oti067_common_init(char *bios_fn, int vram_size) 3.42 { 3.43 oti067_t *oti067 = malloc(sizeof(oti067_t)); 3.44 memset(oti067, 0, sizeof(oti067_t)); 3.45 3.46 rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, 0); 3.47 3.48 - svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/ 3.49 + oti067->vram_size = vram_size; 3.50 + oti067->vram_mask = (vram_size << 10) - 1; 3.51 + 3.52 + svga_init(&oti067->svga, oti067, vram_size << 10, 3.53 oti067_recalctimings, 3.54 oti067_in, oti067_out, 3.55 NULL, 3.56 @@ -134,12 +145,13 @@ 3.57 3.58 void *oti067_init() 3.59 { 3.60 - return oti067_common_init("roms/oti067/bios.bin"); 3.61 + int vram_size = device_get_config_int("memory"); 3.62 + return oti067_common_init("roms/oti067/bios.bin", vram_size); 3.63 } 3.64 3.65 void *oti067_acer386_init() 3.66 { 3.67 - oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin"); 3.68 + oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512); 3.69 3.70 if (oti067) 3.71 oti067->bios_rom.rom[0x5d] = 0x74; 3.72 @@ -182,6 +194,33 @@ 3.73 return svga_add_status_info(s, max_len, &oti067->svga); 3.74 } 3.75 3.76 +static device_config_t oti067_config[] = 3.77 +{ 3.78 + { 3.79 + .name = "memory", 3.80 + .description = "Memory size", 3.81 + .type = CONFIG_SELECTION, 3.82 + .selection = 3.83 + { 3.84 + { 3.85 + .description = "256 kB", 3.86 + .value = 256 3.87 + }, 3.88 + { 3.89 + .description = "512 kB", 3.90 + .value = 512 3.91 + }, 3.92 + { 3.93 + .description = "" 3.94 + } 3.95 + }, 3.96 + .default_int = 512 3.97 + }, 3.98 + { 3.99 + .type = -1 3.100 + } 3.101 +}; 3.102 + 3.103 device_t oti067_device = 3.104 { 3.105 "Oak OTI-067", 3.106 @@ -191,7 +230,8 @@ 3.107 oti067_available, 3.108 oti067_speed_changed, 3.109 oti067_force_redraw, 3.110 - oti067_add_status_info 3.111 + oti067_add_status_info, 3.112 + oti067_config 3.113 }; 3.114 device_t oti067_acer386_device = 3.115 {
4.1 --- a/src/vid_svga.c Sat Jul 12 14:22:54 2014 +0100 4.2 +++ b/src/vid_svga.c Mon Jul 14 21:56:10 2014 +0100 4.3 @@ -66,6 +66,7 @@ 4.4 // pclog("Set mono handler\n"); 4.5 io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); 4.6 } 4.7 + svga_recalctimings(svga); 4.8 break; 4.9 case 0x3C4: 4.10 svga->seqaddr = val;
5.1 --- a/src/vid_tgui9440.c Sat Jul 12 14:22:54 2014 +0100 5.2 +++ b/src/vid_tgui9440.c Mon Jul 14 21:56:10 2014 +0100 5.3 @@ -53,6 +53,8 @@ 5.4 uint8_t ramdac_ctrl; 5.5 5.6 int clock_m, clock_n, clock_k; 5.7 + 5.8 + uint32_t vram_size, vram_mask; 5.9 } tgui_t; 5.10 5.11 void tgui_recalcmapping(tgui_t *tgui); 5.12 @@ -470,9 +472,12 @@ 5.13 tgui_t *tgui = malloc(sizeof(tgui_t)); 5.14 memset(tgui, 0, sizeof(tgui_t)); 5.15 5.16 + tgui->vram_size = device_get_config_int("memory") << 20; 5.17 + tgui->vram_mask = tgui->vram_size - 1; 5.18 + 5.19 rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0); 5.20 5.21 - svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/ 5.22 + svga_init(&tgui->svga, tgui, tgui->vram_size, 5.23 tgui_recalctimings, 5.24 tgui_in, tgui_out, 5.25 tgui_hwcursor_draw, 5.26 @@ -1113,6 +1118,33 @@ 5.27 return svga_add_status_info(s, max_len, &tgui->svga); 5.28 } 5.29 5.30 +static device_config_t tgui9440_config[] = 5.31 +{ 5.32 + { 5.33 + .name = "memory", 5.34 + .description = "Memory size", 5.35 + .type = CONFIG_SELECTION, 5.36 + .selection = 5.37 + { 5.38 + { 5.39 + .description = "1 MB", 5.40 + .value = 1 5.41 + }, 5.42 + { 5.43 + .description = "2 MB", 5.44 + .value = 2 5.45 + }, 5.46 + { 5.47 + .description = "" 5.48 + } 5.49 + }, 5.50 + .default_int = 2 5.51 + }, 5.52 + { 5.53 + .type = -1 5.54 + } 5.55 +}; 5.56 + 5.57 device_t tgui9440_device = 5.58 { 5.59 "Trident TGUI 9440", 5.60 @@ -1122,5 +1154,6 @@ 5.61 tgui9440_available, 5.62 tgui_speed_changed, 5.63 tgui_force_redraw, 5.64 - tgui_add_status_info 5.65 + tgui_add_status_info, 5.66 + tgui9440_config 5.67 };
6.1 --- a/src/vid_tvga.c Sat Jul 12 14:22:54 2014 +0100 6.2 +++ b/src/vid_tvga.c Mon Jul 14 21:56:10 2014 +0100 6.3 @@ -25,6 +25,9 @@ 6.4 int oldmode; 6.5 uint8_t oldctrl1; 6.6 uint8_t oldctrl2, newctrl2; 6.7 + 6.8 + int vram_size; 6.9 + uint32_t vram_mask; 6.10 } tvga_t; 6.11 6.12 void tvga_out(uint16_t addr, uint8_t val, void *p) 6.13 @@ -47,16 +50,16 @@ 6.14 break; 6.15 case 0xC: 6.16 if (svga->seqregs[0xe] & 0x80) 6.17 - svga->seqregs[0xc] = val; 6.18 + svga->seqregs[0xc] = val; 6.19 break; 6.20 case 0xd: 6.21 if (tvga->oldmode) 6.22 + tvga->oldctrl2 = val; 6.23 + else 6.24 { 6.25 - tvga->oldctrl2 = val; 6.26 - svga->vrammask = (val & 0x10) ? 0xfffff : 0x3ffff; 6.27 + tvga->newctrl2 = val; 6.28 + svga_recalctimings(svga); 6.29 } 6.30 - else 6.31 - tvga->newctrl2 = val; 6.32 break; 6.33 case 0xE: 6.34 if (tvga->oldmode) 6.35 @@ -107,6 +110,12 @@ 6.36 svga_recalctimings(svga); 6.37 } 6.38 } 6.39 + switch (svga->crtcreg) 6.40 + { 6.41 + case 0x1e: 6.42 + svga->vrammask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; 6.43 + break; 6.44 + } 6.45 return; 6.46 case 0x3D8: 6.47 tvga->tvga_3d8 = val; 6.48 @@ -207,7 +216,7 @@ 6.49 svga->interlace = svga->crtc[0x1e] & 4; 6.50 if (svga->interlace) 6.51 svga->rowoffset >>= 1; 6.52 - 6.53 + 6.54 switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) 6.55 { 6.56 case 2: svga->clock = cpuclock/44900000.0; break; 6.57 @@ -246,10 +255,13 @@ 6.58 { 6.59 tvga_t *tvga = malloc(sizeof(tvga_t)); 6.60 memset(tvga, 0, sizeof(tvga_t)); 6.61 - 6.62 + 6.63 + tvga->vram_size = device_get_config_int("memory") << 10; 6.64 + tvga->vram_mask = tvga->vram_size - 1; 6.65 + 6.66 rom_init(&tvga->bios_rom, "roms/trident.bin", 0xc0000, 0x8000, 0x7fff, 0, 0); 6.67 6.68 - svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/ 6.69 + svga_init(&tvga->svga, tvga, tvga->vram_size, 6.70 tvga_recalctimings, 6.71 tvga_in, tvga_out, 6.72 NULL, 6.73 @@ -295,6 +307,38 @@ 6.74 return svga_add_status_info(s, max_len, &tvga->svga); 6.75 } 6.76 6.77 +static device_config_t tvga_config[] = 6.78 +{ 6.79 + { 6.80 + .name = "memory", 6.81 + .description = "Memory size", 6.82 + .type = CONFIG_SELECTION, 6.83 + .selection = 6.84 + { 6.85 + { 6.86 + .description = "256 kB", 6.87 + .value = 256 6.88 + }, 6.89 + { 6.90 + .description = "512 kB", 6.91 + .value = 512 6.92 + }, 6.93 + { 6.94 + .description = "1 MB", 6.95 + .value = 1024 6.96 + }, 6.97 + /*Chip supports 2mb, but drivers are buggy*/ 6.98 + { 6.99 + .description = "" 6.100 + } 6.101 + }, 6.102 + .default_int = 1024 6.103 + }, 6.104 + { 6.105 + .type = -1 6.106 + } 6.107 +}; 6.108 + 6.109 device_t tvga8900d_device = 6.110 { 6.111 "Trident TVGA 8900D", 6.112 @@ -304,5 +348,6 @@ 6.113 tvga8900d_available, 6.114 tvga_speed_changed, 6.115 tvga_force_redraw, 6.116 - tvga_add_status_info 6.117 + tvga_add_status_info, 6.118 + tvga_config 6.119 };
