# HG changeset patch # User TomW # Date 1404938742 -3600 # Node ID 47132154ffe78f5aeadccc9d66cf379374800c51 # Parent e4da69090d0542b17d7c99c4901f4af129ee44ef Added emulation of Phoenix Trio32. Based on patch from Battler. Paradise Bahamas 64, Number Nine 9FX and Phoenix Trio32 now have configurable memory sizes. diff -r e4da69090d05 -r 47132154ffe7 src/ibm.h --- a/src/ibm.h Wed Jul 09 19:21:16 2014 +0100 +++ b/src/ibm.h Wed Jul 09 21:45:42 2014 +0100 @@ -346,6 +346,7 @@ GFX_MACH64GX, /*ATI Graphics Pro Turbo (Mach64)*/ GFX_CL_GD5429, /*Cirrus Logic CL-GD5429*/ GFX_VIRGEDX, /*S3 Virge/DX*/ + GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ GFX_MAX }; diff -r e4da69090d05 -r 47132154ffe7 src/vid_s3.c --- a/src/vid_s3.c Wed Jul 09 19:21:16 2014 +0100 +++ b/src/vid_s3.c Wed Jul 09 21:45:42 2014 +0100 @@ -12,6 +12,22 @@ #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" +enum +{ + S3_VISION864, + S3_TRIO32, + S3_TRIO64 +}; + +enum +{ + VRAM_4MB = 0, + VRAM_8MB = 3, + VRAM_2MB = 4, + VRAM_1MB = 6, + VRAM_512KB = 7 +}; + typedef struct s3_t { mem_mapping_t linear_mapping; @@ -27,7 +43,9 @@ int width; int bpp; - uint8_t id, id_ext; + int chip; + + uint8_t id, id_ext, id_ext_pci; int packed_mmio; @@ -35,6 +53,8 @@ uint8_t pci_regs[256]; + uint32_t vram_mask; + float (*getclock)(int clock, void *p); void *getclock_p; @@ -90,7 +110,7 @@ if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// pclog("S3 out %04X %02X\n", addr, val); +// pclog("S3 out %04X %02X %04x:%08x\n", addr, val, CS, pc); switch (addr) { @@ -121,7 +141,6 @@ svga->crtcreg = val & 0x7f; return; case 0x3D5: -// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val); if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return; if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return; old = svga->crtc[svga->crtcreg]; @@ -130,7 +149,7 @@ { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); - svga->vrammask = /*(val & 8) ? */0x3fffff/* : 0x3ffff*/; + svga->vrammask = /*(val & 8) ? */s3->vram_mask/* : 0x3ffff*/; break; case 0x50: @@ -184,7 +203,7 @@ svga->hwcursor.xoff = svga->crtc[0x4e] & 63; svga->hwcursor.yoff = svga->crtc[0x4f] & 63; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if (gfxcard == GFX_N9_9FX && svga->bpp == 32) /*Trio64*/ + if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) svga->hwcursor.x <<= 1; break; @@ -194,7 +213,7 @@ break; case 0x67: - if (gfxcard == GFX_N9_9FX) /*Trio64*/ + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) { switch (val >> 4) { @@ -230,7 +249,7 @@ if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// if (addr != 0x3da) pclog("S3 in %04X\n", addr); +// if (addr != 0x3da) pclog("S3 in %04X %08x:%02x\n", addr, CS, pc); switch (addr) { case 0x3c5: @@ -245,11 +264,12 @@ case 0x3d4: return svga->crtcreg; case 0x3d5: -// pclog("Read CRTC R%02X %04X:%04X\n", svga->crtcreg, CS, pc); +// pclog("Read CRTC R%02X %02x %04X:%04X\n", svga->crtcreg, svga->crtc[svga->crtcreg], CS, pc); switch (svga->crtcreg) { case 0x2d: return 0x88; /*Extended chip ID*/ case 0x2e: return s3->id_ext; /*New chip ID*/ + case 0x2f: return 0; /*Revision level*/ case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); @@ -317,7 +337,7 @@ break; case 32: svga->render = svga_render_32bpp_highres; - if (gfxcard != GFX_N9_9FX) /*Trio64*/ + if (s3->chip != S3_TRIO32 && s3->chip != S3_TRIO64) svga->hdisp /= 4; break; } @@ -1084,9 +1104,9 @@ return 0; } -#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & 0x3fffff]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & 0x1fffff]; \ - else dat = vram_l[(addr) & 0x0fffff]; +#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ + else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; #define MIX switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ { \ @@ -1109,20 +1129,20 @@ } -#define WRITE(addr) if (s3->bpp == 0) \ +#define WRITE(addr) if (s3->bpp == 0) \ { \ - svga->vram[(addr) & 0x3fffff] = dest_dat; \ - svga->changedvram[((addr) & 0x3fffff) >> 12] = changeframecount; \ + svga->vram[(addr) & s3->vram_mask] = dest_dat; \ + svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ } \ - else if (s3->bpp == 1) \ + else if (s3->bpp == 1) \ { \ - vram_w[(addr) & 0x1fffff] = dest_dat; \ - svga->changedvram[((addr) & 0x1fffff) >> 11] = changeframecount; \ + vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \ + svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ } \ else \ { \ - vram_l[(addr) & 0xfffff] = dest_dat; \ - svga->changedvram[((addr) & 0xfffff) >> 10] = changeframecount; \ + vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \ + svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) @@ -1795,7 +1815,7 @@ case 0x00: return 0x33; /*'S3'*/ case 0x01: return 0x53; - case 0x02: return s3->id_ext; + case 0x02: return s3->id_ext_pci; case 0x03: return 0x88; case PCI_REG_COMMAND: @@ -1826,7 +1846,7 @@ { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); +// pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); switch (addr) { case PCI_REG_COMMAND: @@ -1852,23 +1872,46 @@ if (s3->pci_regs[0x30] & 0x01) { uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); - pclog("S3 bios_rom enabled at %08x\n", addr); +// pclog("S3 bios_rom enabled at %08x\n", addr); mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); } else { - pclog("S3 bios_rom disabled\n"); +// pclog("S3 bios_rom disabled\n"); mem_mapping_disable(&s3->bios_rom.mapping); } return; } } -static void *s3_init(char *bios_fn) +static int vram_sizes[] = +{ + 7, /*512 kB*/ + 6, /*1 MB*/ + 4, /*2 MB*/ + 0, + 0, /*4 MB*/ + 0, + 0, + 0, + 3 /*8 MB*/ +}; + +static void *s3_init(char *bios_fn, int chip) { s3_t *s3 = malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; + int vram; + uint32_t vram_size; + memset(s3, 0, sizeof(s3_t)); + + vram = device_get_config_int("memory"); + if (vram) + vram_size = vram << 20; + else + vram_size = 512 << 10; + s3->vram_mask = vram_size - 1; rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -1878,13 +1921,16 @@ mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, s3); mem_mapping_disable(&s3->mmio_mapping); - svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ + svga_init(&s3->svga, s3, vram_size, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ s3_recalctimings, s3_in, s3_out, s3_hwcursor_draw, NULL); - svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); + if (PCI) + svga->crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (vram_sizes[vram] << 5); + else + svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x37] = 1 | (7 << 5); s3_io_set(s3); @@ -1896,16 +1942,18 @@ s3->pci_regs[0x30] = 0x00; s3->pci_regs[0x32] = 0x0c; s3->pci_regs[0x33] = 0x00; + + s3->chip = chip; return s3; } void *s3_bahamas64_init() { - s3_t *s3 = s3_init("roms/bahamas64.bin"); + s3_t *s3 = s3_init("roms/bahamas64.bin", S3_VISION864); s3->id = 0xc1; /*Vision864P*/ - s3->id_ext = 0xc1; + s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; s3->getclock = sdac_getclock; @@ -1921,10 +1969,10 @@ void *s3_9fx_init() { - s3_t *s3 = s3_init("roms/s3_764.bin"); + s3_t *s3 = s3_init("roms/s3_764.bin", S3_TRIO64); s3->id = 0xe1; /*Trio64*/ - s3->id_ext = 0x11; + s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; s3->getclock = s3_trio64_getclock; @@ -1938,6 +1986,26 @@ return rom_present("roms/s3_764.bin"); } +void *s3_phoenix_trio32_init() +{ + s3_t *s3 = s3_init("roms/86C732P.bin", S3_TRIO32); + svga_t *svga = &s3->svga; + + s3->id = 0xe1; /*Trio32*/ + s3->id_ext = 0x10; + s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; + + s3->getclock = s3_trio64_getclock; + s3->getclock_p = s3; + + return s3; +} + +int s3_phoenix_trio32_available() +{ + return rom_present("roms/86C732P.bin"); +} void s3_close(void *p) { @@ -1969,6 +2037,97 @@ return svga_add_status_info(s, max_len, &s3->svga); } +static device_config_t s3_bahamas64_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 + }, + /*Vision864 also supports 8 MB, however the Paradise BIOS is buggy (VESA modes don't work correctly)*/ + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; + +static device_config_t s3_9fx_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { + .description = "" + } + }, + .default_int = 2 + }, + { + .type = -1 + } +}; + +static device_config_t s3_phoenix_trio32_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "512 KB", + .value = 0 + }, + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, + { + .type = -1 + } +}; + device_t s3_bahamas64_device = { "Paradise Bahamas 64 (S3 Vision864)", @@ -1978,7 +2137,8 @@ s3_bahamas64_available, s3_speed_changed, s3_force_redraw, - s3_add_status_info + s3_add_status_info, + s3_bahamas64_config }; device_t s3_9fx_device = @@ -1990,5 +2150,19 @@ s3_9fx_available, s3_speed_changed, s3_force_redraw, - s3_add_status_info + s3_add_status_info, + s3_9fx_config }; + +device_t s3_phoenix_trio32_device = +{ + "Phoenix S3 Trio32", + 0, + s3_phoenix_trio32_init, + s3_close, + s3_phoenix_trio32_available, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + s3_phoenix_trio32_config +}; diff -r e4da69090d05 -r 47132154ffe7 src/vid_s3.h --- a/src/vid_s3.h Wed Jul 09 19:21:16 2014 +0100 +++ b/src/vid_s3.h Wed Jul 09 21:45:42 2014 +0100 @@ -1,2 +1,3 @@ device_t s3_bahamas64_device; device_t s3_9fx_device; +device_t s3_phoenix_trio32_device; diff -r e4da69090d05 -r 47132154ffe7 src/video.c --- a/src/video.c Wed Jul 09 19:21:16 2014 +0100 +++ b/src/video.c Wed Jul 09 21:45:42 2014 +0100 @@ -44,25 +44,26 @@ static VIDEO_CARD video_cards[] = { - {"CGA", &cga_device, GFX_CGA}, - {"MDA", &mda_device, GFX_MDA}, - {"Hercules", &hercules_device, GFX_HERCULES}, - {"EGA", &ega_device, GFX_EGA}, - {"Trident TVGA8900D", &tvga8900d_device, GFX_TVGA}, - {"Tseng ET4000AX", &et4000_device, GFX_ET4000}, - {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32}, - {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64}, - {"Number Nine 9FX (S3 Trio64)", &s3_9fx_device, GFX_N9_9FX}, - {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, - {"S3 ViRGE/DX", &s3_virge_375_device, GFX_VIRGEDX}, - {"Trident TGUI9440", &tgui9440_device, GFX_TGUI9440}, - {"VGA", &vga_device, GFX_VGA}, - {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, - {"ATI VGA Charger", &ati28800_device, GFX_VGACHARGER}, - {"OAK OTI-067", &oti067_device, GFX_OTI067}, - {"ATI Graphics Pro Turbo (Mach64 GX)", &mach64gx_device, GFX_MACH64GX}, - {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429}, - {"", NULL, 0} + {"ATI Graphics Pro Turbo (Mach64 GX)", &mach64gx_device, GFX_MACH64GX}, + {"ATI VGA Charger (ATI-28800)", &ati28800_device, GFX_VGACHARGER}, + {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, + {"CGA", &cga_device, GFX_CGA}, + {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429}, + {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32}, + {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, + {"EGA", &ega_device, GFX_EGA}, + {"Hercules", &hercules_device, GFX_HERCULES}, + {"MDA", &mda_device, GFX_MDA}, + {"Number Nine 9FX (S3 Trio64)", &s3_9fx_device, GFX_N9_9FX}, + {"OAK OTI-067", &oti067_device, GFX_OTI067}, + {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64}, + {"Phoenix S3 Trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32}, + {"S3 ViRGE/DX", &s3_virge_375_device, GFX_VIRGEDX}, + {"Trident TVGA8900D", &tvga8900d_device, GFX_TVGA}, + {"Tseng ET4000AX", &et4000_device, GFX_ET4000}, + {"Trident TGUI9440", &tgui9440_device, GFX_TGUI9440}, + {"VGA", &vga_device, GFX_VGA}, + {"", NULL, 0} }; int video_card_available(int card)