Added emulation of Cardex ET4000/W32p with ICS/SDAC RAMDAC;

Fixed ET4000/W32p clock (for non-Diamond variants) and banking extension;
Brought the code on par with the mainline;
Fixed names of the two Cardex ET4000/W32p variants per the BIOS'es;
Brought ET4000AX unknown RAMDAC back in line with the mainline (reverted bogus "fix" by Win9xFan);
Made 15bpp and 16bpp colors more accurate.
This commit is contained in:
OBattler
2016-07-23 01:48:47 +02:00
parent 0d1e5c7439
commit f41bbb6ba8
16 changed files with 452 additions and 119 deletions

View File

@@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -funroll-l
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \
device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
scat.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \

View File

@@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -funroll-l
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \
device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
scat.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \

View File

@@ -7,8 +7,10 @@
#include "timer.h"
#include "gameport.h"
#include "joystick_ch_flightstick_pro.h"
#include "joystick_standard.h"
#include "joystick_sw_pad.h"
#include "joystick_tm_fcs.h"
int joystick_type;
@@ -18,7 +20,9 @@ static joystick_if_t *joystick_list[] =
&joystick_standard_4button,
&joystick_standard_6button,
&joystick_standard_8button,
&joystick_ch_flightstick_pro,
&joystick_sw_pad,
&joystick_tm_fcs,
NULL
};
@@ -44,7 +48,12 @@ int joystick_get_button_count(int joystick)
return joystick_list[joystick]->button_count;
}
char *joystick_get_axis_name(int joystick, int id)
int joystick_get_pov_count(int joystick)
{
return joystick_list[joystick]->pov_count;
}
char *joystick_get_axis_name(int joystick, int id)
{
return joystick_list[joystick]->axis_names[id];
}
@@ -54,6 +63,11 @@ char *joystick_get_button_name(int joystick, int id)
return joystick_list[joystick]->button_names[id];
}
char *joystick_get_pov_name(int joystick, int id)
{
return joystick_list[joystick]->pov_names[id];
}
typedef struct gameport_axis_t
{
int64_t count;

View File

@@ -10,10 +10,11 @@ typedef struct
void (*write)(void *p);
int (*read_axis)(void *p, int axis);
void (*a0_over)(void *p);
int axis_count, button_count;
int axis_count, button_count, pov_count;
int max_joysticks;
char axis_names[8][32];
char button_names[32][32];
char pov_names[4][32];
} joystick_if_t;
extern int joystick_type;
@@ -21,8 +22,10 @@ char *joystick_get_name(int joystick);
int joystick_get_max_joysticks(int joystick);
int joystick_get_axis_count(int joystick);
int joystick_get_button_count(int joystick);
int joystick_get_pov_count(int joystick);
char *joystick_get_axis_name(int joystick, int id);
char *joystick_get_button_name(int joystick, int id);
char *joystick_get_pov_name(int joystick, int id);
void gameport_update_joystick_type();

View File

@@ -386,7 +386,7 @@ enum
GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/
GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/
GFX_INCOLOR, /* Hercules InColor */
GFX_ET4000W32C, /*Tseng ET4000/W32p (Cardex) */
GFX_ET4000W32C, /*Tseng ET4000/W32p (Cardex) (STG RAMDAC) */
GFX_COMPAQ_EGA, /*Compaq EGA*/
GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/
GFX_COMPAQ_VGA, /*Compaq/Paradise VGA*/
@@ -395,6 +395,7 @@ enum
GFX_VGAWONDERXL, /*Compaq ATI VGA Wonder XL (28800-5)*/
GFX_WD90C11, /*Paradise WD90C11 Standalone*/
GFX_OTI077, /*Oak OTI-077*/
GFX_ET4000W32CS, /*Tseng ET4000/W32p (Cardex) (ICS RAMDAC) */
GFX_MAX
};

View File

@@ -704,6 +704,13 @@ void loadconfig(char *fn)
sprintf(s, "joystick_%i_button_%i", c, d);
joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d);
}
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
{
sprintf(s, "joystick_%i_pov_%i_x", c, d);
joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d);
sprintf(s, "joystick_%i_pov_%i_y", c, d);
joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d);
}
}
}
}
@@ -793,6 +800,13 @@ void saveconfig()
sprintf(s, "joystick_%i_button_%i", c, d);
config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]);
}
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
{
sprintf(s, "joystick_%i_pov_%i_x", c, d);
config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]);
sprintf(s, "joystick_%i_pov_%i_y", c, d);
config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]);
}
}
}

View File

@@ -53,6 +53,7 @@ extern "C" {
int plat_joystick_nr;
int axis_mapping[8];
int button_mapping[32];
int pov_mapping[4][2];
} joystick_t;
#define MAX_JOYSTICKS 4

View File

@@ -81,8 +81,11 @@ void cga_write(uint32_t addr, uint8_t val, void *p)
cga_t *cga = (cga_t *)p;
// pclog("CGA_WRITE %04X %02X\n", addr, val);
cga->vram[addr & 0x3fff] = val;
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
if (cga->snow_enabled)
{
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
}
egawrites++;
cycles -= 4;
}
@@ -91,8 +94,11 @@ uint8_t cga_read(uint32_t addr, void *p)
{
cga_t *cga = (cga_t *)p;
cycles -= 4;
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
if (cga->snow_enabled)
{
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
}
egareads++;
// pclog("CGA_READ %04X\n", addr);
return cga->vram[addr & 0x3fff];
@@ -443,6 +449,7 @@ void *cga_standalone_init()
display_type = device_get_config_int("display_type");
cga->composite = (display_type != CGA_RGB);
cga->revision = device_get_config_int("composite_type");
cga->snow_enabled = device_get_config_int("snow_enabled");
cga->vram = malloc(0x4000);
@@ -513,6 +520,12 @@ static device_config_t cga_config[] =
},
.default_int = COMPOSITE_OLD
},
{
.name = "snow_enabled",
.description = "Snow emulation",
.type = CONFIG_BINARY,
.default_int = 1
},
{
.type = -1
}

View File

@@ -14,6 +14,7 @@
#include "video.h"
#include "vid_svga.h"
#include "vid_icd2061.h"
#include "vid_sdac_ramdac.h"
#include "vid_stg_ramdac.h"
#define FIFO_SIZE 65536
@@ -49,6 +50,7 @@ typedef struct et4000w32p_t
svga_t svga;
stg_ramdac_t ramdac;
sdac_ramdac_t sdac_ramdac;
icd2061_t icd2061;
int index;
@@ -95,6 +97,7 @@ typedef struct et4000w32p_t
{
uint32_t base[3];
uint8_t ctrl;
uint8_t unk[2];
} mmu;
fifo_entry_t fifo[FIFO_SIZE];
@@ -142,12 +145,19 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
stg_ramdac_out(addr, val, &et4000->ramdac, svga);
if (gfxcard == GFX_ET4000W32CS)
{
sdac_ramdac_out(addr, val, &et4000->sdac_ramdac, svga);
}
else
{
stg_ramdac_out(addr, val, &et4000->ramdac, svga);
}
return;
case 0x3CB: /*Banking extension*/
svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20);
svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16);
svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 3) << 20);
svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x30) << 16);
et4000->banking2 = val;
return;
case 0x3CD: /*Banking*/
@@ -242,7 +252,14 @@ uint8_t et4000w32p_in(uint16_t addr, void *p)
break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
return stg_ramdac_in(addr, &et4000->ramdac, svga);
if (gfxcard == GFX_ET4000W32CS)
{
return sdac_ramdac_in(addr, &et4000->sdac_ramdac, svga);
}
else
{
return stg_ramdac_in(addr, &et4000->ramdac, svga);
}
case 0x3CB:
return et4000->banking2;
@@ -304,10 +321,23 @@ void et4000w32p_recalctimings(svga_t *svga)
case 2: case 3: svga->clock = cpuclock / icd2061_getfreq(&et4000->icd2061, 2); break;
}
}
else
else if (gfxcard == GFX_ET4000W32C)
{
svga->clock = cpuclock / stg_getclock((svga->miscout >> 2) & 3, &et4000->ramdac);
}
else
{
svga->clock = cpuclock / sdac_getclock((svga->miscout >> 2) & 3, &et4000->sdac_ramdac);
switch (sdac_get_clock_divider(&et4000->sdac_ramdac))
{
case 2:
svga->clock /= 2.0;
break;
case 3:
svga->clock /= 3.0;
break;
}
}
switch (svga->bpp)
{
@@ -580,6 +610,7 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
if ((addr & 0x7fff) >= 0x7f80)
{
et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_BYTE);
pclog("MMU queue: %04X: %02X\n", addr, val);
}
else switch (addr & 0x7fff)
{
@@ -596,6 +627,8 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break;
case 0x7f0d: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break;
case 0x7f13: et4000->mmu.ctrl=val; break;
case 0x7f30: et4000->mmu.unk[0] = val; pclog("MMU Unknown 0 = %02X\n", et4000->mmu.unk[0]); break;
case 0x7f32: et4000->mmu.unk[1] = val; pclog("MMU Unknown 1 = %02X\n", et4000->mmu.unk[1]); break;
}
break;
}
@@ -651,6 +684,8 @@ uint8_t et4000w32p_mmu_read(uint32_t addr, void *p)
case 0x7f0a: return et4000->mmu.base[2] >> 16;
case 0x7f0b: return et4000->mmu.base[2] >> 24;
case 0x7f13: return et4000->mmu.ctrl;
case 0x7f30: return et4000->mmu.unk[0];
case 0x7f32: return et4000->mmu.unk[1];
case 0x7f36:
temp = et4000->acl.status;
@@ -1224,8 +1259,11 @@ void *et4000w32p_common_init(char *biosfile)
}
else
{
pclog("No known BIOS detected or BIOS already set to 1 MB DRAM modules, maximum VRAM is 2 MB\n");
vram_size == 2;
if (gfxcard != GFX_ET4000W32CS)
{
pclog("No known BIOS detected or BIOS already set to 1 MB DRAM modules, maximum VRAM is 2 MB\n");
vram_size == 2;
}
}
}
if (PCI)
@@ -1261,6 +1299,11 @@ void *et4000w32pc_init()
return et4000w32p_common_init("roms/cardex.vbi");
}
void *et4000w32pcs_init()
{
return et4000w32p_common_init("roms/TSENG.BIN");
}
int et4000w32p_available()
{
return rom_present("roms/et4000w32.bin");
@@ -1271,6 +1314,11 @@ int et4000w32pc_available()
return rom_present("roms/cardex.vbi");
}
int et4000w32pcs_available()
{
return rom_present("roms/TSENG.BIN");
}
void et4000w32p_close(void *p)
{
et4000w32p_t *et4000 = (et4000w32p_t *)p;
@@ -1439,7 +1487,7 @@ device_t et4000w32p_device =
device_t et4000w32pc_device =
{
"Cardex Tseng Labs ET4000/w32p",
"Cardex 1703-DDC (ET4000/W32P)",
0,
et4000w32pc_init,
et4000w32p_close,
@@ -1449,3 +1497,16 @@ device_t et4000w32pc_device =
et4000w32p_add_status_info,
et4000w32pc_config
};
device_t et4000w32pcs_device =
{
"Cardex ICS5341 (ET4000/W32P)",
0,
et4000w32pcs_init,
et4000w32p_close,
et4000w32pcs_available,
et4000w32p_speed_changed,
et4000w32p_force_redraw,
et4000w32p_add_status_info,
et4000w32pc_config
};

View File

@@ -1,2 +1,3 @@
extern device_t et4000w32p_device;
extern device_t et4000w32pc_device;
extern device_t et4000w32pcs_device;

View File

@@ -6,6 +6,17 @@
#include "vid_svga.h"
#include "vid_sdac_ramdac.h"
int sdac_get_clock_divider(sdac_ramdac_t *ramdac)
{
switch (ramdac->command >> 4)
{
case 0x0: case 0x3: case 0x5: return 1;
case 0x1: case 0x2: case 0x6: case 0x7: case 0xa: case 0xc: return 2;
case 0x4: case 0xe: return 3;
default: return 1;
}
}
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga)
{
// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2);
@@ -23,45 +34,16 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *
{
ramdac->command = val;
// pclog("RAMDAC command reg now %02X\n", val);
// 0, 1 = 15 bpp
if (gfxcard == GFX_ET4000W32C)
{
if (ramdac->command & 8)
{
switch (ramdac->regs[3])
{
case 0: case 5: case 7: svga->bpp = 8; break;
case 1: case 2: case 8: svga->bpp = 15; break;
case 3: case 6: svga->bpp = 16; break;
case 4: case 9: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
else
{
switch (ramdac->command >> 5)
{
case 0: svga->bpp = 8; break;
case 5: svga->bpp = 15; break;
case 6: svga->bpp = 16; break;
case 7: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
}
else
{
switch (val >> 4)
{
case 0x2: case 0x3: case 0xa: svga->bpp = 15; break;
case 0x4: case 0xe: svga->bpp = 24; break;
case 0x5: case 0x6: case 0xc: svga->bpp = 16; break;
case 0x7: svga->bpp = 32; break;
switch (val >> 4)
{
case 0x2: case 0x3: case 0xa: svga->bpp = 15; break;
case 0x4: case 0xe: svga->bpp = 24; break;
case 0x5: case 0x6: case 0xc: svga->bpp = 16; break;
case 0x7: svga->bpp = 32; break;
case 0: case 1: default: svga->bpp = 8; break;
}
}
pclog("SDAC: Value %02X/%02X set to %i bpp\n", val >> 4, val, svga->bpp);
case 0: case 1: default: svga->bpp = 8; break;
}
svga_recalctimings(svga);
}
//ramdac->magic_count = 0;
break;

View File

@@ -7,10 +7,39 @@
static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
static int stg_state_write[8] = {0,0,0,0,0,6,7,7};
static int stg_state_indexed = 0;
void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
{
int oldbpp = svga->bpp;
if (ramdac->command & 0x8)
{
switch (ramdac->regs[3])
{
case 0: case 5: case 7: svga->bpp = 8; break;
case 1: case 2: case 8: svga->bpp = 15; break;
case 3: case 6: svga->bpp = 16; break;
case 4: case 9: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
else
{
switch (ramdac->command >> 5)
{
case 0: svga->bpp = 8; break;
case 5: svga->bpp = 15; break;
case 6: svga->bpp = 16; break;
case 7: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
svga_recalctimings(svga);
}
void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga)
{
int didwrite;
int didwrite, old;
//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
switch (addr)
{
@@ -20,8 +49,20 @@ void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *sv
case 0: case 1: case 2: case 3:
break;
case 4:
old = ramdac->command;
ramdac->command = val;
/*pclog("Write RAMDAC command %02X\n",val);*/
if ((old ^ val) & 8)
{
stg_ramdac_set_bpp(svga, ramdac);
}
else
{
if ((old ^ val) & 0xE0)
{
stg_ramdac_set_bpp(svga, ramdac);
}
}
// pclog("Write RAMDAC command %02X\n",val);
break;
case 5:
ramdac->index = (ramdac->index & 0xff00) | val;
@@ -30,38 +71,17 @@ void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *sv
ramdac->index = (ramdac->index & 0xff) | (val << 8);
break;
case 7:
#ifndef RELEASE_BUILD
pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
#endif
if (ramdac->index < 0x100)
// pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
if (ramdac->index < 0x100)
{
ramdac->regs[ramdac->index] = val;
}
if ((ramdac->index == 3) && (ramdac->command & 8)) stg_ramdac_set_bpp(svga, ramdac);
ramdac->index++;
break;
}
didwrite = (ramdac->magic_count >= 4);
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
if (ramdac->command & 8)
{
switch (ramdac->regs[3])
{
case 0: case 5: case 7: svga->bpp = 8; break;
case 1: case 2: case 8: svga->bpp = 15; break;
case 3: case 6: svga->bpp = 16; break;
case 4: case 9: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
else
{
switch (ramdac->command >> 5)
{
case 0: svga->bpp = 8; break;
case 5: svga->bpp = 15; break;
case 6: svga->bpp = 16; break;
case 7: svga->bpp = 24; break;
default: svga->bpp = 8; break;
}
}
if (didwrite) return;
break;
case 0x3c7: case 0x3c8: case 0x3c9:
@@ -93,15 +113,18 @@ uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga)
temp = ramdac->index >> 8;
break;
case 7:
// pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
// pclog("Read RAMDAC index %04X\n",ramdac->index);
switch (ramdac->index)
{
case 0:
temp = 0x44;
break;
case 1:
temp = 0x02;
temp = 0x03;
break;
case 7:
temp = 0x88;
break;
default:
if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index];
else temp = 0xff;
@@ -112,7 +135,7 @@ uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga)
}
ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
return temp;
case 0x3c8: case 0x3c9:
case 0x3c7: case 0x3c8: case 0x3c9:
ramdac->magic_count=0;
break;
}
@@ -124,14 +147,31 @@ float stg_getclock(int clock, void *p)
stg_ramdac_t *ramdac = (stg_ramdac_t *)p;
float t;
int m, n1, n2;
float d;
// pclog("STG_Getclock %i %04X\n", clock, ramdac->regs[clock]);
if (clock == 0) return 25175000.0;
if (clock == 1) return 28322000.0;
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
m = (ramdac->regs[clock] & 0x7f) + 2;
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
n2 = ((ramdac->regs[clock] >> 13) & 0x07);
t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
m = (ramdac->regs[clock] & 0x7f) + 2; /* B+2 */
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; /* N1+2 */
n2 = ((ramdac->regs[clock] >> 13) & 0x07); /* D */
switch (n2)
{
case 0:
d = 1.0;
break;
case 1:
d = 2.0;
break;
case 2:
d = 4.0;
break;
case 3:
d = 8.0;
break;
}
// t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
t = (14318184.0 * ((float)m / d)) / (float)n1;
// pclog("STG clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2);
return t;
}

View File

@@ -22,16 +22,21 @@ void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *sv
case 0: case 1: case 2: case 3:
svga->bpp = 8;
break;
case 4: case 5:
svga->bpp = 32; /* Per the spec. */
break;
case 6: case 7:
svga->bpp = 15;
break;
case 8: case 9: case 0xA: case 0xB:
svga->bpp = 16;
break;
case 0xC: case 0xD: case 0xE: case 0xF:
svga->bpp = 24;
break;
case 8: case 9: case 0xA: case 0xB:
svga->bpp = 15;
break;
case 0xC: case 0xD: case 0xE: case 0xF:
svga->bpp = 16;
break;
}
svga_recalctimings(svga);
pclog("unk_ramdac: set to %02X, %i bpp\n", (val&1)|((val&0xE0)>>4), svga->bpp);
return;
}
ramdac->state = 0;

View File

@@ -52,7 +52,8 @@ static VIDEO_CARD video_cards[] =
{"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},
{"Cardex Tseng ET4000/w32p", &et4000w32pc_device, GFX_ET4000W32C},
{"Cardex 1703-DDC (ET4000/W32P)", &et4000w32pc_device, GFX_ET4000W32C},
{"Cardex ICS5341 (ET4000/W32P)", &et4000w32pcs_device, GFX_ET4000W32CS},
{"CGA", &cga_device, GFX_CGA},
{"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429},
{"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32},
@@ -388,6 +389,38 @@ static struct
static void blit_thread(void *param);
int calc_15to32(int c)
{
int b, g, r;
double db, dg, dr;
b = (c & 31);
g = ((c >> 5) & 31);
r = ((c >> 10) & 31);
db = (((double) b) / 31.0) * 255.0;
dg = (((double) g) / 31.0) * 255.0;
dr = (((double) r) / 31.0) * 255.0;
b = (int) db;
g = ((int) dg) << 8;
r = ((int) dr) << 16;
return (b | g | r);
}
int calc_16to32(int c)
{
int b, g, r;
double db, dg, dr;
b = (c & 31);
g = ((c >> 5) & 63);
r = ((c >> 11) & 31);
db = (((double) b) / 31.0) * 255.0;
dg = (((double) g) / 63.0) * 255.0;
dr = (((double) r) / 31.0) * 255.0;
b = (int) db;
g = ((int) dg) << 8;
r = ((int) dr) << 16;
return (b | g | r);
}
void initvideo()
{
int c, d, e;
@@ -435,12 +468,20 @@ void initvideo()
}
video_15to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_15to32[c] = calc_15to32(c);
video_16to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_16to32[c] = calc_16to32(c);
blit_data.wake_blit_thread = thread_create_event();
blit_data.blit_complete = thread_create_event();

View File

@@ -175,6 +175,30 @@ void joystick_close()
}
}
static int joystick_get_axis(int joystick_nr, int mapping)
{
if (mapping & POV_X)
{
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
if (LOWORD(pov) == 0xFFFF)
return 0;
else
return sin((2*M_PI * (double)pov) / 36000.0) * 32767;
}
else if (mapping & POV_Y)
{
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
if (LOWORD(pov) == 0xFFFF)
return 0;
else
return -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
}
else
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
}
void joystick_poll()
{
int c, d;
@@ -218,30 +242,26 @@ void joystick_poll()
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
{
if (joystick_state[c].axis_mapping[d] & POV_X)
{
int pov = plat_joystick_state[joystick_nr].p[joystick_state[c].axis_mapping[d] & 3];
if (LOWORD(pov) == 0xFFFF)
joystick_state[c].axis[d] = 0;
else
joystick_state[c].axis[d] = sin((2*M_PI * (double)pov) / 36000.0) * 32767;
}
else if (joystick_state[c].axis_mapping[d] & POV_Y)
{
int pov = plat_joystick_state[joystick_nr].p[joystick_state[c].axis_mapping[d] & 3];
if (LOWORD(pov) == 0xFFFF)
joystick_state[c].axis[d] = 0;
else
joystick_state[c].axis[d] = -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
}
else
joystick_state[c].axis[d] = plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[joystick_state[c].axis_mapping[d]].id];
}
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
{
int x, y;
double angle, magnitude;
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI);
magnitude = sqrt((double)x*(double)x + (double)y*(double)y);
if (magnitude < 16384)
joystick_state[c].pov[d] = -1;
else
joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360;
}
}
else
{
@@ -249,6 +269,8 @@ void joystick_poll()
joystick_state[c].axis[d] = 0;
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
joystick_state[c].button[d] = 0;
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
joystick_state[c].pov[d] = -1;
}
}
}

View File

@@ -79,6 +79,38 @@ static void rebuild_axis_button_selections(HWND hdlg)
id += 2;
}
for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++)
{
int sel = c;
h = GetDlgItem(hdlg, id);
SendMessage(h, CB_RESETCONTENT, 0, 0);
if (joystick)
{
for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++)
{
char s[80];
sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
}
for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++)
{
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name);
}
SendMessage(h, CB_SETCURSEL, sel, 0);
EnableWindow(h, TRUE);
}
else
EnableWindow(h, FALSE);
id += 2;
}
}
static int get_axis(HWND hdlg, int id)
@@ -97,6 +129,23 @@ static int get_axis(HWND hdlg, int id)
return POV_X | (axis_sel >> 1);
}
static int get_pov(HWND hdlg, int id)
{
HWND h = GetDlgItem(hdlg, id);
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2;
if (axis_sel < nr_povs)
{
if (axis_sel & 1)
return POV_Y | (axis_sel >> 1);
else
return POV_X | (axis_sel >> 1);
}
return axis_sel - nr_povs;
}
static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
@@ -120,6 +169,7 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar
if (joystick_state[joystick_nr].plat_joystick_nr)
{
int nr_axes = plat_joystick_state[joystick-1].nr_axes;
int nr_povs = plat_joystick_state[joystick-1].nr_povs;
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
{
int mapping = joystick_state[joystick_nr].axis_mapping[c];
@@ -139,6 +189,29 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar
SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0);
id += 2;
}
for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++)
{
int mapping;
h = GetDlgItem(hdlg, id);
mapping = joystick_state[joystick_nr].pov_mapping[c][0];
if (mapping & POV_X)
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
else if (mapping & POV_Y)
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
else
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
id += 2;
h = GetDlgItem(hdlg, id);
mapping = joystick_state[joystick_nr].pov_mapping[c][1];
if (mapping & POV_X)
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
else if (mapping & POV_Y)
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
else
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
id += 2;
}
}
}
return TRUE;
@@ -174,6 +247,15 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar
joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0);
id += 2;
}
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
{
h = GetDlgItem(hdlg, id);
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id);
id += 2;
h = GetDlgItem(hdlg, id);
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id);
id += 2;
}
}
}
case IDCANCEL:
@@ -358,6 +440,59 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type)
y += 20;
}
for (c = 0; c < joystick_get_pov_count(type)*2; c++)
{
char s[80];
/*Combo box*/
item = (DLGITEMTEMPLATE *)data;
item->x = 70;
item->y = y;
item->id = id++;
item->cx = 140;
item->cy = 150;
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
data = (uint16_t *)(item + 1);
*data++ = 0xFFFF;
*data++ = 0x0085; // combo box class
if (c & 1)
sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2));
else
sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2));
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
*data++ = 0; // no creation data
if (((unsigned long)data) & 2)
data++;
/*Static text*/
item = (DLGITEMTEMPLATE *)data;
item->x = 10;
item->y = y;
item->id = id++;
item->cx = 60;
item->cy = 15;
item->style = WS_CHILD | WS_VISIBLE;
data = (uint16_t *)(item + 1);
*data++ = 0xFFFF;
*data++ = 0x0082; // static class
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
*data++ = 0; // no creation data
if (((unsigned long)data) & 2)
data++;
y += 20;
}
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;