Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPC improvments #341

Merged
merged 2 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/dmd.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The table below gives the main information (PWM FPS / Display FPS / PWM pattern)
|[WPC Phantom Haus](#wpc) | 61.05 / 30.1 | 2 frames | |
|[Data East 128x16](#data-east-128x16) | 177.5 / **59.2** | 2u row | |
|[Data East 128x32](#data-east-128x32-segastern-whitestar) | 234.2 / **78.1** | 2u row | |
|Sega 192x64 | 224.2 / 74.73 | 2u row |Batman Forever seems to have CPU-DMD communication issues |
|Sega 192x64 | 224.2 / 74.73 | 2u row |Timing issues leading to seldom display of bootup screen |
|Gottlieb GTS3 | **375.9** / 125.3-37.6 | 3/6/8/10 | |
|[Alvin G. 1](#alvin-g) | 332.4 / 83.1 | 4 row |Still a little flicker on the title screen |
|[Alvin G. 2](#alvin-g) | 298.6 / **74.6** | 4 row | |
Expand Down
57 changes: 35 additions & 22 deletions src/wpc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1601,11 +1601,13 @@ int core_getSol(int solNo) {
else if (solNo <= 32) { // 29-32
if (core_gameData->gen & GEN_ALLS11)
return coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON)) ? saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + solNo - 1].value) : coreGlobals.solenoids & CORE_SOLBIT(solNo);
else if (core_gameData->gen & GEN_ALLWPC) // GI circuits
return coreGlobals.solenoids2 & (1<<(solNo-29+8)); // GameOn
else if (core_gameData->gen & GEN_ALLWPC) // WPC GameOn
return coreGlobals.solenoids2 & (1<<(solNo-29+8));
}
else if (solNo <= 36) { // 33-36 Upper flipper (WPC only)
if (core_gameData->gen & GEN_ALLWPC) {
if (coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON)))
return saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + solNo - 1].value);
int mask;
/*-- flipper coils --*/
if ((solNo == sURFlip) && (core_gameData->hw.flippers & FLIP_SOL(FLIP_UR)))
Expand All @@ -1624,6 +1626,8 @@ int core_getSol(int solNo) {
return coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON)) ? saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + 32 + solNo - 37 + 8].value) : coreGlobals.solenoids2 & (1<<(solNo - 37 + 8));
}
else if (solNo <= 48) { // 45-48 Lower flippers
if ((core_gameData->gen & GEN_ALLWPC) && (coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON))))
return saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + solNo - 1].value);
int mask = 1<<(solNo - 45);
/*-- Game must have lower flippers but for symmetry we check anyway --*/
if ((solNo == sLRFlip) /*&& (core_gameData->hw.flippers & FLIP_SOL(FLIP_LR))*/)
Expand Down Expand Up @@ -1658,7 +1662,7 @@ UINT64 core_getAllSol(void) {
UINT64 sol = coreGlobals.solenoids;
if (core_gameData->gen & GEN_ALLWPC) // 29-32 GameOn
sol = (sol & 0x0fffffff) | ((coreGlobals.solenoids2 & 0x0f00)<<20);
if (core_gameData->gen & (GEN_WPC95|GEN_WPC95DCS)) { // 37-44 WPC95 extra
if (core_gameData->gen & (GEN_WPC95|GEN_WPC95DCS)) { // 37-44 WPC95 extra, duplicated at 0x......XX........
UINT64 tmp = coreGlobals.solenoids & 0xf0000000;
sol |= (tmp<<12)|(tmp<<8);
}
Expand Down Expand Up @@ -1696,42 +1700,50 @@ void core_getAllPhysicSols(float* const state)
{
assert(coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON)));
memset(state, 0, CORE_MODOUT_SOL_MAX * sizeof(float)); // To avoid reporting garbage states for unused solenoid slots
/*-- 1..32, hardware solenoids --*/
if (core_gameData->gen & GEN_ALLWPC) {
for (int i = 0; i < 28; i++)
/*-- 1..28, hardware solenoids --*/
for (int i = 0; i < 28; i++)
state[i] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
// 29..32 GameOn (not modulated, stored in 0x0F00 of solenoids2)
// 29..32 GameOn (not modulated, stored in 0x0700 of solenoids2)
for (int i = 28; i < 32; i++)
state[i] = coreGlobals.solenoids2 & (1 << (i - 28 + 8)) ? 1.0f : 0.0f;
}
else
for (int i = 0; i < 32; i++)
/*-- 29..32, hardware solenoids --*/
for (int i = 0; i < 32; i++)
state[i] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
/*-- 33..36 upper flipper solenoids (not modulated for the time being) --*/
{
UINT8 uFlip = (coreGlobals.solenoids2 & (CORE_URFLIPSOLBITS | CORE_ULFLIPSOLBITS));
if (core_gameData->hw.flippers & FLIP_SOL(FLIP_UR))
uFlip = uFlip | ((uFlip & 0x10)<<1);
if (core_gameData->hw.flippers & FLIP_SOL(FLIP_UL))
uFlip = uFlip | ((uFlip & 0x40)<<1);
state[32] = uFlip & 0x10 ? 1.0f : 0.0f;
state[33] = uFlip & 0x20 ? 1.0f : 0.0f;
state[34] = uFlip & 0x40 ? 1.0f : 0.0f;
state[35] = uFlip & 0x80 ? 1.0f : 0.0f;
/*-- 33..36 upper flipper solenoids (WPC only) --*/
if (core_gameData->gen & GEN_ALLWPC) {
if (coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON)))
for (int i = 32; i < 36; i++)
state[i] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
else {
UINT8 uFlip = (coreGlobals.solenoids2 & (CORE_URFLIPSOLBITS | CORE_ULFLIPSOLBITS));
if (core_gameData->hw.flippers & FLIP_SOL(FLIP_UR))
uFlip = uFlip | ((uFlip & 0x10)<<1);
if (core_gameData->hw.flippers & FLIP_SOL(FLIP_UL))
uFlip = uFlip | ((uFlip & 0x40)<<1);
state[32] = uFlip & 0x10 ? 1.0f : 0.0f;
state[33] = uFlip & 0x20 ? 1.0f : 0.0f;
state[34] = uFlip & 0x40 ? 1.0f : 0.0f;
state[35] = uFlip & 0x80 ? 1.0f : 0.0f;
}
}
/*-- 37..44, extra solenoids --*/
if (core_gameData->gen & (GEN_WPC95 | GEN_WPC95DCS)) { // 37-44 WPC95 extra (duplicated 37..40 / 41..44)
for (int i = 28; i < 32; i++)
{
for (int i = 28; i < 32; i++) {
state[i + 8] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
state[i + 12] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
}
}
else if (core_gameData->gen & (GEN_ALLS11 | GEN_SAM | GEN_SPA)) // 37-44 S11, SAM extra
for (int i = 40; i < 48; i++)
state[i - 4] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
/*-- 45..48 lower flipper solenoids (not modulated for the time being) --*/
{
/*-- 45..48 lower flipper solenoids (only modulated for WPC) --*/
if ((core_gameData->gen & GEN_ALLWPC) && (coreGlobals.nSolenoids && (options.usemodsol & (CORE_MODOUT_ENABLE_PHYSOUT_SOLENOIDS | CORE_MODOUT_ENABLE_MODSOL | CORE_MODOUT_FORCE_ON))))
for (int i = 44; i < 48; i++)
state[i] = coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value;
else {
UINT8 lFlip = (coreGlobals.solenoids2 & (CORE_LRFLIPSOLBITS|CORE_LLFLIPSOLBITS));
lFlip |= (lFlip & 0x05)<<1; // hold coil is set if either coil is set
state[44] = lFlip & 0x01 ? 1.0f : 0.0f;
Expand Down Expand Up @@ -1942,6 +1954,7 @@ static MACHINE_INIT(core) {
if(((core_gameData->gen & GEN_GTS3) && GTS3locals.alphagen) || (core_gameData->gen & (GEN_WPCALPHA_1 | GEN_WPCALPHA_2)))
options.usemodsol |= CORE_MODOUT_ENABLE_PHYSOUT_ALPHASEGS; // use CORE_MODOUT_ENABLE_PHYSOUT_ALL to enable/test all physical/PWM outputs
#endif
options.usemodsol |= CORE_MODOUT_ENABLE_PHYSOUT_ALL; // For debugging

/*-- init bulb model LUTs --*/
bulb_init();
Expand Down
70 changes: 37 additions & 33 deletions src/wpc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,41 +231,45 @@ typedef struct core_dispLayout core_tLCDLayout, *core_ptLCDLayout;
#define PINMAME_VIDEO_UPDATE(name) int (name)(struct mame_bitmap *bitmap, const struct rectangle *cliprect, const struct core_dispLayout *layout)
typedef int (*ptPinMAMEvidUpdate)(struct mame_bitmap *bitmap, const struct rectangle *cliprect, const struct core_dispLayout *layout);

/*----------------------
/*---------------------------------------
/ WPC driver constants
/--------------------------------*/
/* Solenoid numbering */
/* */
/* WPC */
/* 1-28 Standard */
/* 33-36 Upper flipper solenoids */
/* 37-40 Standard (WPC95 only) */
/* 41-44 - "" - Copy of above */
/* 45-48 Lower flipper solenoids */
/* 49-50 Simulated */
/* 51-64 */
/* */
/* S9/S11 */
/* 1- 8 Standard 'A'-side */
/* 9-16 Standard */
/* 17-22 Special */
/* 23 Flipper & SS Enabled Sol (fake) */
/* 25-32 Standard 'C'-side */
/* 37-41 Sound overlay board */
/* */
/* S7 */
/* 1-16 Standard */
/* 17-24 Special */
/----------------------------------------*/
/* Solenoid numbering */
/* */
/* WPC */
/* 1-28 Standard */
/* 29-31 GameOn (3 highest bit of GI reg)*/
/* 32 Unused (always 0) */
/* 33-36 Upper flipper solenoids */
/* 37-40 LPDC WPC95 controlled outputs */
/* 41-44 Copy of 37-40 for backward comp.*/
/* 45-48 Lower flipper solenoids */
/* 49 Fake solenoid for ball shooter */
/* 50 Reserved */
/* 51-58 8 drivers Aux Board or custom */
/* 59-64 custom */
/* */
/* S9/S11 */
/* 1- 8 Standard 'A'-side */
/* 9-16 Standard */
/* 17-22 Special */
/* 23 Flipper & Switched Sol. Enable */
/* 25-32 Standard 'C'-side */
/* 37-41 Sound overlay board */
/* */
/* S7 */
/* 1-16 Standard */
/* 17-24 Special */
/* 25 Flipper & SS Enabled Sol (fake) */
/* */
/* BY17/BY35 */
/* 1-15 Standard Pulse */
/* 17-20 Standard Hold */
/* */
/* GTS80 */
/* 1- 9 Standard */
/* 10 GameOn (fake) */
/* 11 Tilt (for GI) (fake) */
/* */
/* BY17/BY35 */
/* 1-15 Standard Pulse */
/* 17-20 Standard Hold */
/* */
/* GTS80 */
/* 1- 9 Standard */
/* 10 GameOn (fake) */
/* 11 Tilt (for GI) (fake) */
#define CORE_FIRSTEXTSOL 37
#define CORE_FIRSTUFLIPSOL 33
#define CORE_FIRSTCUSTSOL 51
Expand Down
23 changes: 14 additions & 9 deletions src/wpc/dedmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,23 +266,28 @@ const struct sndbrdIntf dedmd64Intf = {

static WRITE16_HANDLER(crtc6845_msb_address_w) { cpu_set_irq_line(dmdlocals.brdData.cpuNo, MC68000_IRQ_2, CLEAR_LINE); if (ACCESSING_MSB) crtc6845_address_0_w(offset,data>>8); }
static WRITE16_HANDLER(crtc6845_msb_register_w) { cpu_set_irq_line(dmdlocals.brdData.cpuNo, MC68000_IRQ_2, CLEAR_LINE); if (ACCESSING_MSB) crtc6845_register_0_w(offset,data>>8); }
static READ16_HANDLER(crtc6845_msb_register_r) { cpu_set_irq_line(dmdlocals.brdData.cpuNo, MC68000_IRQ_2, CLEAR_LINE); return crtc6845_register_0_r(offset)<<8; }
static WRITE16_HANDLER(dmd64_status_w) { if (ACCESSING_LSB) sndbrd_ctrl_cb(dmdlocals.brdData.boardNo, dmdlocals.status = data & 0x0f); }
static READ16_HANDLER(crtc6845_msb_address_r) { cpu_set_irq_line(dmdlocals.brdData.cpuNo, MC68000_IRQ_2, CLEAR_LINE); return 0; }
static READ16_HANDLER(crtc6845_msb_register_r) { cpu_set_irq_line(dmdlocals.brdData.cpuNo, MC68000_IRQ_2, CLEAR_LINE); return ACCESSING_MSB ? crtc6845_register_0_r(offset)<<8 : 0; }
static WRITE16_HANDLER(dmd64_status_w) { if (ACCESSING_LSB) sndbrd_ctrl_cb(dmdlocals.brdData.boardNo, dmdlocals.status = data & 0xff); }
static READ16_HANDLER(dmd64_latch_r);
static READ16_HANDLER(dmd64_ram_r) { const UINT16 v = dmd64RAM[offset]; return (v >> 8) | (v << 8); }
static WRITE16_HANDLER(dmd64_ram_w) { const UINT16 rev_data = (data >> 8) | (data << 8); const UINT16 rev_mask = (mem_mask >> 8) | (mem_mask << 8); dmd64RAM[offset] = (dmd64RAM[offset] & rev_mask) | (rev_data & ~rev_mask); }

// Address decoding is performed by U26, a little PAL chip (no flip flop), using A21/A22 for RAM/ROM/Ext chip, then A3/A4 for chip select
// 00 => ROM 1Mb (can be physically switched by R1 jumper between 2 EPROM sets)
// 01 => ROM (not used, therefore not implemented)
// 10 => RAM 128kb
// 11 => Ext Chip: A3 = CRTC / A4 = Board IO (use synchronous data transfer, with VPA/VMA instead of asynchronous with DTACK)
static MEMORY_READ16_START(dmd64_readmem)
{ 0x00000000, 0x000fffff, MRA16_ROM }, /* ROM (2 X 512K)*/
//{ 0x00800000, 0x0080ffff, MRA16_RAM}, /* RAM - 0x800000 Page 0, 0x801000 Page 1 */
{ 0x00000000, 0x000fffff, MRA16_ROM}, /* ROM (2 X 512K)*/
{ 0x00800000, 0x0080ffff, dmd64_ram_r}, /* RAM - 0x800000 Page 0, 0x801000 Page 1 - Reversed endianness */
{ 0x00c00010, 0x00c00011, crtc6845_msb_register_r },
{ 0x00c00020, 0x00c00021, dmd64_latch_r }, /* Read the Latch from CPU*/
{ 0x00c00010, 0x00c00011, crtc6845_msb_address_r},
{ 0x00c00012, 0x00c00013, crtc6845_msb_register_r},
{ 0x00c00020, 0x00c00021, dmd64_latch_r}, /* Read the Latch from CPU*/
MEMORY_END

static MEMORY_WRITE16_START(dmd64_writemem)
{ 0x00000000, 0x000fffff, MWA16_ROM}, /* ROM (2 X 512K)*/
// { 0x00800000, 0x0080ffff, MWA16_RAM, &dmd64RAM}, /* RAM - 0x800000 Page 0, 0x801000 Page 1 */
{ 0x00800000, 0x0080ffff, dmd64_ram_w, &dmd64RAM}, /* RAM - 0x800000 Page 0, 0x801000 Page 1 - Reversed endianness */
{ 0x00c00010, 0x00c00011, crtc6845_msb_address_w},
{ 0x00c00012, 0x00c00013, crtc6845_msb_register_w},
Expand All @@ -299,7 +304,7 @@ static void dmd64_init(struct sndbrdData *brdData) {
memset(&dmdlocals, 0, sizeof(dmdlocals));
dmdlocals.brdData = *brdData;
crtc6845_init(0);
crtc6845_set_vsync(0, (12000000. / 4.) / 16., dmd64_vblank); // See explanation for frequency explanation (12MHz -> 3MHz -> 3MHz/16)
crtc6845_set_vsync(0, (12000000. / 4.) / 16., dmd64_vblank); // See explanation above for frequency (12MHz -> 3MHz -> 3MHz/16)
core_dmd_pwm_init(&dmdlocals.pwm_state, 192, 64, CORE_DMD_PWM_FILTER_DE_192x64, CORE_DMD_PWM_COMBINER_SUM_2_1);
}

Expand All @@ -313,7 +318,7 @@ static WRITE_HANDLER(dmd64_ctrl_w) {
sndbrd_ctrl_cb(dmdlocals.brdData.boardNo, dmdlocals.busy = 1);
dmdlocals.cmd = dmdlocals.ncmd;
}
if (dmdlocals.ctrl & ~data & 0x02) // Reset
if (dmdlocals.ctrl & ~data & 0x02) // Reset (applied at falling edge)
cpu_set_reset_line(dmdlocals.brdData.cpuNo, PULSE_LINE);
dmdlocals.ctrl = data;
}
Expand Down
9 changes: 7 additions & 2 deletions src/wpc/sims/wpc/full/ss.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ static sim_tSimData ssSimData = {
NULL /* no key conditions */
};

// Prototype 0.1 had a 16 LED Skull driver board assembly A-20781 which was not kept in production build
// This board is a simple 16 bit shift register made from 2x4094 and drivers.

static WRITE_HANDLER(parallel_0_out) {
coreGlobals.tmpLampMatrix[9] = core_revbyte(data);
core_write_pwm_output_8b(9 * 8, core_revbyte(data));
Expand All @@ -461,7 +464,9 @@ static core_tGameData ssGameData = {
GEN_WPC95, wpc_dispDMD,
{
FLIP_SW(FLIP_L | FLIP_U) | FLIP_SOL(FLIP_L),
0,2,0,0,0,1,0, // 2 extra lamp columns for the LEDs of rev. 0.1
// 2 extra lamp columns for the LEDs of rev. 0.1
// Why do we set gameSpecific1 as this is unused on WPC ?
/*swCol*/0,/*lampCol*/2,/*custSol*/0,/*soundBoard*/0,/*display*/0,/*gameSpecific1*/1,/*gameSpecific2*/0,
NULL, ss_handleMech, ss_getMech, ss_drawMech,
NULL
#ifdef ENABLE_MECHANICAL_SAMPLES
Expand All @@ -486,7 +491,7 @@ static mech_tInitData ss_wheelMech = {

static WRITE_HANDLER(ss_wpc_w) {
wpc_w(offset, data);
if (offset == WPC_SOLENOID1) {
if (offset == WPC_SOLENOID1) { // J110-3 AUX.LAMP DATA and J110-1 AUX.LAMP CLOCK
HC4094_data_w (0, GET_BIT5);
HC4094_clock_w(0, GET_BIT4);
HC4094_clock_w(1, GET_BIT4);
Expand Down
Loading
Loading