laserbat.cpp: DIP and input cleanup, stuff from manual

This commit is contained in:
Vas Crabb 2015-12-30 03:24:08 +11:00
parent 685c4defbc
commit 0a9a292f68
4 changed files with 66 additions and 93 deletions

View File

@ -268,32 +268,36 @@ WRITE8_MEMBER(laserbat_state::csound2_w)
The game board sends commands to the sound board over a 16-bit
unidirectional data bus. The CPU cannot write all sixteen lines
atomically, it write to lines 1-8 as one group and 9-16 as another
group. Not all bit functions are known:
group. However only seven lines are actually connected to the sound
board:
+-----+----------------------------------------------------------+
| Bit | Function |
+-----+----------------------------------------------------------+
| 1 | PSG1 IOB0 |
| 2 | PSG1 IOB1 |
| 3 | PSG1 IOB2 |
| 4 | PSG1 IOB3 |
| 5 | PSG1 IOB4 |
| 6 | PIA CA1 |
| 7 | |
| 8 | |
| 9 | Used but unknown purpose |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | Used but unknown purpose |
+-----+----------------------------------------------------------+
+-----+----------+-------------+
| Bit | Name | Connection |
+-----+----------+-------------+
| 1 | SOUND 0 | PSG1 IOB0 |
| 2 | SOUND 1 | PSG1 IOB1 |
| 3 | SOUND 2 | PSG1 IOB2 |
| 4 | SOUND 3 | PSG1 IOB3 |
| 5 | SOUND 4 | PSG1 IOB4 |
| 6 | SOUND 5 | PIA CA1 |
| 7 | | |
| 8 | | |
| 9 | | |
| 10 | | |
| 11 | | |
| 12 | | |
| 13 | | |
| 14 | | |
| 15 | | |
| 16 | RESET | Unknown |
+-----+----------+-------------+
There could well be other connections on the sound board - these are
just what can be deduced by tracing the sound program.
The game board makes the the audio output from the first S2636 PVI
(5E) available on a pin at the sound board interface connector, but
it may or may not be routed anywhere.
it isn't routed anywhere.
*/
WRITE8_MEMBER(catnmous_state::csound1_w)
@ -302,6 +306,13 @@ WRITE8_MEMBER(catnmous_state::csound1_w)
m_csound1 = data;
}
WRITE8_MEMBER(catnmous_state::csound2_w)
{
// the top bit is called RESET on the wiring diagram - assume it resets the sound CPU
m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
m_csound2 = data;
}
READ8_MEMBER(catnmous_state::pia_porta_r)
{
UINT8 const control = m_pia->b_output();
@ -365,8 +376,9 @@ WRITE8_MEMBER(catnmous_state::psg1_porta_w)
READ8_MEMBER(catnmous_state::psg1_portb_r)
{
// the program masks out the three high bits - no clue what they're connected to
return m_csound1 & 0x1f;
// the sound program masks out the three most significant bits
// assume they're not connected and read high from the internal pull-ups
return m_csound1 | 0xe0;
}
INTERRUPT_GEN_MEMBER(catnmous_state::cb1_toggle)

View File

@ -30,6 +30,8 @@
bidirectional interface on J7.
Laser Battle/Lazarian notes:
* Manuals clearly indicate the controls to fire in four directions
are four buttons arranged in a diamond, not a four-way joystick
* Cocktail cabinet has an additional "image commutation board"
consuming the screen flip output, presumably flipping the image by
reversing the deflection coil connections
@ -46,7 +48,6 @@
TODO:
- work out where all the magic layer offsets come from
- second bank of DIP switches in laserbat and catnmous
- sound in laserbat (with schematics) and in catnmous
*/
@ -223,9 +224,9 @@ static INPUT_PORTS_START( laserbat_base )
PORT_DIPNAME( 0x20, 0x20, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-1:6")
PORT_DIPSETTING( 0x20, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-1:7")
PORT_DIPSETTING( 0x40, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x40, 0x00, "Infinite Lives" ) PORT_DIPLOCATION("SW-1:7")
PORT_DIPSETTING( 0x00, DEF_STR(Off) )
PORT_DIPSETTING( 0x40, DEF_STR(On) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-1:8")
PORT_DIPSETTING( 0x80, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
@ -240,12 +241,11 @@ static INPUT_PORTS_START( laserbat_base )
PORT_DIPNAME( 0x04, 0x04, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-2:3")
PORT_DIPSETTING( 0x04, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-2:4")
PORT_DIPSETTING( 0x08, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-2:5")
PORT_DIPSETTING( 0x10, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x18, 0x08, DEF_STR(Difficulty) ) PORT_DIPLOCATION("SW-2:4,5")
PORT_DIPSETTING( 0x00, DEF_STR(Easy) )
PORT_DIPSETTING( 0x08, DEF_STR(Medium) )
PORT_DIPSETTING( 0x10, DEF_STR(Difficult) )
PORT_DIPSETTING( 0x18, DEF_STR(Very_Difficult) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW-2:6")
PORT_DIPSETTING( 0x20, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
@ -264,28 +264,12 @@ INPUT_PORTS_END
static INPUT_PORTS_START( laserbat )
PORT_INCLUDE(laserbat_base)
PORT_MODIFY("ROW0")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Fire Left")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Fire Right")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Fire Up")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Fire Down")
PORT_MODIFY("ROW1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Fire Left")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Fire Right")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Fire Up")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Fire Down")
PORT_MODIFY("SW1")
PORT_DIPNAME( 0x70, 0x10, DEF_STR(Lives) ) PORT_DIPLOCATION("SW-1:5,6,7")
PORT_DIPNAME( 0x30, 0x10, DEF_STR(Lives) ) PORT_DIPLOCATION("SW-1:5,6")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPSETTING( 0x20, "5" )
PORT_DIPSETTING( 0x30, "6" )
PORT_DIPSETTING( 0x40, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x50, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x60, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x70, DEF_STR(Infinite) )
PORT_DIPNAME( 0x80, 0x80, "Collision Detection" ) PORT_DIPLOCATION("SW-1:8")
PORT_DIPSETTING( 0x00, DEF_STR(Off) )
PORT_DIPSETTING( 0x80, DEF_STR(On) )
@ -326,11 +310,6 @@ static INPUT_PORTS_START( lazarian )
PORT_DIPNAME( 0x04, 0x00, "Freeze" ) PORT_DIPLOCATION("SW-2:3")
PORT_DIPSETTING( 0x00, DEF_STR(Off) )
PORT_DIPSETTING( 0x04, DEF_STR(On) )
PORT_DIPNAME( 0x18, 0x08, DEF_STR(Difficulty) ) PORT_DIPLOCATION("SW-2:4,5")
PORT_DIPSETTING( 0x00, DEF_STR(Easy) )
PORT_DIPSETTING( 0x08, DEF_STR(Medium) )
PORT_DIPSETTING( 0x10, DEF_STR(Difficult) )
PORT_DIPSETTING( 0x18, DEF_STR(Very_Difficult) )
INPUT_PORTS_END
static INPUT_PORTS_START( catnmous )
@ -349,18 +328,30 @@ static INPUT_PORTS_START( catnmous )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_MODIFY("SW1")
PORT_DIPNAME( 0x70, 0x10, DEF_STR(Lives) ) PORT_DIPLOCATION("SW-1:5,6,7")
PORT_DIPNAME( 0x30, 0x10, DEF_STR(Lives) ) PORT_DIPLOCATION("SW-1:5,6")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPSETTING( 0x20, "4" )
PORT_DIPSETTING( 0x30, "5" )
PORT_DIPSETTING( 0x40, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x50, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x60, DEF_STR(Infinite) )
// PORT_DIPSETTING( 0x70, DEF_STR(Infinite) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW-1:8")
PORT_DIPSETTING( 0x00, DEF_STR(Off) )
PORT_DIPSETTING( 0x80, DEF_STR(On) )
PORT_MODIFY("SW2")
PORT_DIPNAME( 0x01, 0x01, "Free Play" ) PORT_DIPLOCATION("SW-2:1") // taken from manual, assuming poor translation
PORT_DIPSETTING( 0x01, "Win Play" )
PORT_DIPSETTING( 0x00, "No Win Play" )
PORT_DIPNAME( 0x02, 0x02, DEF_STR(Unused) ) PORT_DIPLOCATION("SW-2:2") // manual says not used
PORT_DIPSETTING( 0x02, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR(Unused) ) PORT_DIPLOCATION("SW-2:3") // manual says not used
PORT_DIPSETTING( 0x04, DEF_STR(Off) )
PORT_DIPSETTING( 0x00, DEF_STR(On) )
PORT_DIPNAME( 0x60, 0x40, DEF_STR(Bonus_Life) ) PORT_DIPLOCATION("SW-2:6,7")
PORT_DIPSETTING( 0x00, DEF_STR(Off) )
PORT_DIPSETTING( 0x20, "20,000" )
PORT_DIPSETTING( 0x40, "24,000" )
PORT_DIPSETTING( 0x60, "28,000" )
INPUT_PORTS_END
static const gfx_layout charlayout =
@ -735,4 +726,4 @@ ROM_END
GAME( 1981, laserbat, 0, laserbat, laserbat, laserbat_state_base, laserbat, ROT0, "Zaccaria", "Laser Battle", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1981, lazarian, laserbat, laserbat, lazarian, laserbat_state_base, laserbat, ROT0, "Zaccaria (Bally Midway license)", "Lazarian", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1982, catnmous, 0, catnmous, catnmous, laserbat_state_base, laserbat, ROT90, "Zaccaria", "Cat and Mouse (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1982, catnmousa, catnmous, catnmous, catnmous, laserbat_state_base, laserbat, ROT90, "Zaccaria", "Cat and Mouse (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1982, catnmousa, catnmous, catnmous, catnmous, laserbat_state_base, laserbat, ROT90, "Zaccaria", "Cat and Mouse (set 2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )

View File

@ -195,6 +195,7 @@ public:
// sound control ports
virtual DECLARE_WRITE8_MEMBER(csound1_w) override;
virtual DECLARE_WRITE8_MEMBER(csound2_w) override;
// PIA handlers
DECLARE_READ8_MEMBER(pia_porta_r);

View File

@ -69,8 +69,6 @@
#include "includes/laserbat.h"
#define PLA_DEBUG 0
PALETTE_INIT_MEMBER(laserbat_state_base, laserbat)
{
@ -200,35 +198,6 @@ WRITE8_MEMBER(laserbat_state_base::cnt_nav_w)
void laserbat_state_base::video_start()
{
// extract product and sum terms from video mixing PAL
if (PLA_DEBUG)
{
UINT8 const *bitstream = memregion("gfxmix")->base() + 4;
UINT32 products[48];
UINT8 sums[48];
for (unsigned term = 0; 48 > term; term++)
{
products[term] = 0;
for (unsigned byte = 0; 4 > byte; byte++)
{
UINT8 bits = *bitstream++;
for (unsigned bit = 0; 4 > bit; bit++, bits >>= 2)
{
products[term] >>= 1;
if (bits & 0x01) products[term] |= 0x80000000;
if (bits & 0x02) products[term] |= 0x00008000;
}
}
sums[term] = ~*bitstream++;
UINT32 const sensitive = ((products[term] >> 16) ^ products[term]) & 0x0000ffff;
UINT32 const required = ~products[term] & sensitive & 0x0000ffff;
UINT32 const inactive = ~((products[term] >> 16) | products[term]) & 0x0000ffff;
printf("if (!0x%04x && ((x & 0x%04x) == 0x%04x)) y |= %02x; /* %u */\n", inactive, sensitive, required, sums[term], term);
}
UINT8 const mask = *bitstream;
printf("y ^= %02x;\n", mask);
}
// we render straight from ROM
m_gfx1 = memregion("gfx1")->base();
m_gfx2 = memregion("gfx2")->base();