This commit is contained in:
Scott Stone 2023-07-08 19:44:07 -04:00
commit 88691d5f89
6 changed files with 131 additions and 120 deletions

View File

@ -131,7 +131,6 @@ public:
void timer_w(int state) { m_timer.timer_w(state); }
protected:
// state index constants
enum
{
@ -162,6 +161,7 @@ protected:
M68705_MOR
};
protected:
static unsigned const PORT_COUNT = 4;
m6805_hmos_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, device_type type, u32 addr_width, unsigned ram_size);

View File

@ -626,6 +626,7 @@ void qix_state::qix_base(machine_config &config)
m_pia2->readpa_handler().set_ioport("P2");
m_pia2->set_port_a_input_overrides_output_mask(0xff);
m_pia2->writepb_handler().set(FUNC(qix_state::qix_coinctl_w));
m_pia2->tspb_handler().set_constant(0);
/* video hardware */
qix_video(config);
@ -694,7 +695,7 @@ void zookeep_state::zookeepbl(machine_config &config)
***************************************************************************/
void qix_state::slither(machine_config &config)
void slither_state::slither(machine_config &config)
{
qix_base(config);
@ -702,12 +703,13 @@ void qix_state::slither(machine_config &config)
m_maincpu->set_clock(SLITHER_CLOCK_OSC/4/4); /* 1.34 MHz */
m_pia1->readpa_handler().set(FUNC(qix_state::slither_trak_lr_r));
m_pia1->writepb_handler().set(FUNC(qix_state::slither_76489_0_w));
m_pia1->readpa_handler().set(FUNC(slither_state::trak_lr_r));
m_pia1->cb2_handler().set(FUNC(slither_state::sn76489_0_ctrl_w));
m_pia1->readpb_handler().set_constant(0);
m_pia2->readpa_handler().set(FUNC(qix_state::slither_trak_ud_r));
m_pia2->writepb_handler().set(FUNC(qix_state::slither_76489_1_w));
m_pia2->readpa_handler().set(FUNC(slither_state::trak_ud_r));
m_pia2->writepb_handler().set_nop();
m_pia2->cb2_handler().set(FUNC(slither_state::sn76489_1_ctrl_w));
m_pia2->readpb_handler().set_constant(0);
/* video hardware */
@ -1481,7 +1483,7 @@ GAME( 1982, zookeep2, zookeep, zookeep, zookeep, zookeep_state, empty_init,
GAME( 1982, zookeep3, zookeep, zookeep, zookeep, zookeep_state, empty_init, ROT0, "Taito America Corporation", "Zoo Keeper (set 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1982, zookeepbl, zookeep, zookeepbl, zookeep, zookeep_state, empty_init, ROT0, "bootleg", "Zoo Keeper (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1982, slither, 0, slither, slither, qix_state, empty_init, ROT270, "Century II (GDI license)", "Slither (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1982, slithera, slither, slither, slither, qix_state, empty_init, ROT270, "Century II (GDI license)", "Slither (set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1982, slither, 0, slither, slither, slither_state, empty_init, ROT270, "Century II (GDI license)", "Slither (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1982, slithera, slither, slither, slither, slither_state, empty_init, ROT270, "Century II (GDI license)", "Slither (set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1984, complexx, 0, qix, complexx, qix_state, empty_init, ROT270, "Taito America Corporation", "Complex X", MACHINE_SUPPORTS_SAVE )

View File

@ -45,8 +45,6 @@ public:
m_sndpia0(*this, "sndpia0"),
m_sndpia1(*this, "sndpia1"),
m_sndpia2(*this, "sndpia2"),
m_sn1(*this, "sn1"),
m_sn2(*this, "sn2"),
m_discrete(*this, "discrete"),
m_paletteram(*this, "paletteram"),
m_videoram(*this, "videoram", 0x10000, ENDIANNESS_BIG),
@ -64,9 +62,6 @@ public:
void qix_audio(machine_config &config);
void kram3(machine_config &config);
void kram3_video(machine_config &config);
void slither(machine_config &config);
void slither_video(machine_config &config);
void slither_audio(machine_config &config);
void init_kram3();
@ -84,8 +79,6 @@ protected:
required_device<pia6821_device> m_sndpia0;
optional_device<pia6821_device> m_sndpia1;
optional_device<pia6821_device> m_sndpia2;
optional_device<sn76489_device> m_sn1;
optional_device<sn76489_device> m_sn2;
optional_device<discrete_sound_device> m_discrete;
/* video state */
@ -115,10 +108,8 @@ protected:
uint8_t qix_video_firq_ack_r(address_space &space);
uint8_t qix_videoram_r(offs_t offset);
void qix_videoram_w(offs_t offset, uint8_t data);
void slither_videoram_w(offs_t offset, uint8_t data);
uint8_t qix_addresslatch_r(offs_t offset);
void qix_addresslatch_w(offs_t offset, uint8_t data);
void slither_addresslatch_w(offs_t offset, uint8_t data);
void qix_paletteram_w(offs_t offset, uint8_t data);
void qix_palettebank_w(uint8_t data);
@ -127,19 +118,12 @@ protected:
void qix_vsync_changed(int state);
void qix_pia_w(offs_t offset, uint8_t data);
void qix_coinctl_w(uint8_t data);
void slither_76489_0_w(uint8_t data);
void slither_76489_1_w(uint8_t data);
uint8_t slither_trak_lr_r();
uint8_t slither_trak_ud_r();
void display_enable_changed(int state);
void qix_flip_screen_w(int state);
void qix_dac_w(uint8_t data);
void qix_vol_w(uint8_t data);
void sndpia_2_warning_w(uint8_t data);
void sync_sndpia1_porta_w(uint8_t data);
void slither_coinctl_w(uint8_t data);
void qix_pia_dint(int state);
void qix_pia_sint(int state);
MC6845_BEGIN_UPDATE(crtc_begin_update);
MC6845_UPDATE_ROW(crtc_update_row);
void set_pen(int offs);
@ -154,7 +138,39 @@ protected:
void kram3_video_map(address_map &map);
void main_map(address_map &map);
void qix_video_map(address_map &map);
};
class slither_state : public qix_state
{
public:
slither_state(const machine_config &mconfig, device_type type, const char *tag) :
qix_state(mconfig, type, tag),
m_sn(*this, "sn%u", 1U),
m_trak(*this, "AN%u", 0U)
{ }
void slither(machine_config &config);
void slither_video(machine_config &config);
void slither_audio(machine_config &config);
protected:
virtual void machine_start() override;
private:
uint8_t trak_lr_r();
uint8_t trak_ud_r();
void sn76489_0_ctrl_w(int state);
void sn76489_1_ctrl_w(int state);
void slither_coinctl_w(uint8_t data);
void slither_videoram_w(offs_t offset, uint8_t data);
void slither_addresslatch_w(offs_t offset, uint8_t data);
void slither_video_map(address_map &map);
required_device_array<sn76489_device, 2> m_sn;
required_ioport_array<4> m_trak;
bool m_sn76489_ctrl[2] = { false, false };
};
class qixmcu_state : public qix_state
@ -162,7 +178,8 @@ class qixmcu_state : public qix_state
public:
qixmcu_state(const machine_config &mconfig, device_type type, const char *tag) :
qix_state(mconfig, type, tag),
m_mcu(*this, "mcu")
m_mcu(*this, "mcu"),
m_coin(*this, "COIN")
{ }
void mcu(machine_config &config);
@ -171,6 +188,7 @@ protected:
virtual void machine_start() override;
optional_device<m68705p_device> m_mcu;
required_ioport m_coin;
private:
uint8_t coin_r();
@ -180,7 +198,7 @@ private:
uint8_t mcu_portb_r();
uint8_t mcu_portc_r();
void mcu_porta_w(uint8_t data);
void mcu_portb_w(uint8_t data);
void mcu_portb_w(offs_t offset, uint8_t data, uint8_t mem_mask);
/* machine state */
uint8_t m_68705_porta_out = 0;

View File

@ -10,9 +10,8 @@
#include "qix.h"
#include "cpu/m6800/m6800.h"
#include "cpu/m6809/m6809.h"
#include "machine/input_merger.h"
#include "sound/discrete.h"
#include "sound/sn76496.h"
#include "speaker.h"
@ -117,38 +116,6 @@ void qix_state::sync_sndpia1_porta_w(uint8_t data)
}
void qix_state::slither_coinctl_w(uint8_t data)
{
machine().bookkeeping().coin_lockout_w(0, (~data >> 6) & 1);
machine().bookkeeping().coin_counter_w(0, (data >> 5) & 1);
}
/*************************************
*
* IRQ generation
*
*************************************/
void qix_state::qix_pia_dint(int state)
{
int combined_state = m_sndpia0->irq_a_state() | m_sndpia0->irq_b_state();
/* DINT is connected to the data CPU's IRQ line */
m_maincpu->set_input_line(M6809_IRQ_LINE, combined_state ? ASSERT_LINE : CLEAR_LINE);
}
void qix_state::qix_pia_sint(int state)
{
int combined_state = m_sndpia1->irq_a_state() | m_sndpia1->irq_b_state();
/* SINT is connected to the sound CPU's IRQ line */
m_audiocpu->set_input_line(M6802_IRQ_LINE, combined_state ? ASSERT_LINE : CLEAR_LINE);
}
/*************************************
*
@ -177,20 +144,28 @@ void qix_state::qix_audio(machine_config &config)
M6802(config, m_audiocpu, SOUND_CLOCK_OSC/2); /* 0.92 MHz */
m_audiocpu->set_addrmap(AS_PROGRAM, &qix_state::audio_map);
// DINT is connected to the data CPU's IRQ line
INPUT_MERGER_ANY_HIGH(config, "dint").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
// SINT is connected to the sound CPU's IRQ line
INPUT_MERGER_ANY_HIGH(config, "sint").output_handler().set_inputline(m_audiocpu, M6802_IRQ_LINE);
PIA6821(config, m_sndpia0, 0);
m_sndpia0->writepa_handler().set(FUNC(qix_state::sync_sndpia1_porta_w));
m_sndpia0->writepb_handler().set(FUNC(qix_state::qix_vol_w));
m_sndpia0->tspb_handler().set_constant(0xff);
m_sndpia0->ca2_handler().set("sndpia1", FUNC(pia6821_device::ca1_w));
m_sndpia0->cb2_handler().set(FUNC(qix_state::qix_flip_screen_w));
m_sndpia0->irqa_handler().set(FUNC(qix_state::qix_pia_dint));
m_sndpia0->irqb_handler().set(FUNC(qix_state::qix_pia_dint));
m_sndpia0->irqa_handler().set("dint", FUNC(input_merger_device::in_w<0>));
m_sndpia0->irqb_handler().set("dint", FUNC(input_merger_device::in_w<1>));
PIA6821(config, m_sndpia1, 0);
m_sndpia1->writepa_handler().set("sndpia0", FUNC(pia6821_device::porta_w));
m_sndpia1->writepb_handler().set(FUNC(qix_state::qix_dac_w));
m_sndpia1->tspb_handler().set_constant(0);
m_sndpia1->ca2_handler().set("sndpia0", FUNC(pia6821_device::ca1_w));
m_sndpia1->irqa_handler().set(FUNC(qix_state::qix_pia_sint));
m_sndpia1->irqb_handler().set(FUNC(qix_state::qix_pia_sint));
m_sndpia1->irqa_handler().set("sint", FUNC(input_merger_device::in_w<0>));
m_sndpia1->irqb_handler().set("sint", FUNC(input_merger_device::in_w<1>));
PIA6821(config, m_sndpia2, 0);
m_sndpia2->writepa_handler().set(FUNC(qix_state::sndpia_2_warning_w));
@ -206,20 +181,26 @@ void qix_state::qix_audio(machine_config &config)
m_discrete->add_route(1, "rspeaker", 1.0);
}
void qix_state::slither_audio(machine_config &config)
void slither_state::slither_audio(machine_config &config)
{
// DINT is connected to the data CPU's IRQ line
INPUT_MERGER_ANY_HIGH(config, "dint").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
PIA6821(config, m_sndpia0, 0);
m_sndpia0->readpa_handler().set_ioport("P2");
m_sndpia0->writepb_handler().set(FUNC(qix_state::slither_coinctl_w));
m_sndpia0->cb2_handler().set(FUNC(qix_state::qix_flip_screen_w));
m_sndpia0->irqa_handler().set(FUNC(qix_state::qix_pia_dint));
m_sndpia0->irqb_handler().set(FUNC(qix_state::qix_pia_dint));
m_sndpia0->writepb_handler().set(FUNC(slither_state::slither_coinctl_w));
m_sndpia0->tspb_handler().set_constant(0x0f);
m_sndpia0->cb2_handler().set(FUNC(slither_state::qix_flip_screen_w));
m_sndpia0->irqa_handler().set("dint", FUNC(input_merger_device::in_w<0>));
m_sndpia0->irqb_handler().set("dint", FUNC(input_merger_device::in_w<1>));
SPEAKER(config, "mono").front_center();
SN76489(config, m_sn1, SLITHER_CLOCK_OSC/4/4);
m_sn1->add_route(ALL_OUTPUTS, "mono", 0.50);
SN76489(config, m_sn[0], SLITHER_CLOCK_OSC/4/4);
m_sn[0]->add_route(ALL_OUTPUTS, "mono", 0.50);
m_sn[0]->ready_cb().set(m_pia1, FUNC(pia6821_device::cb1_w));
SN76489(config, m_sn2, SLITHER_CLOCK_OSC/4/4);
m_sn2->add_route(ALL_OUTPUTS, "mono", 0.50);
SN76489(config, m_sn[1], SLITHER_CLOCK_OSC/4/4);
m_sn[1]->add_route(ALL_OUTPUTS, "mono", 0.50);
m_sn[1]->ready_cb().set(m_pia2, FUNC(pia6821_device::cb1_w));
}

View File

@ -10,8 +10,6 @@
#include "emu.h"
#include "qix.h"
#include "cpu/m6800/m6800.h"
/*************************************
*
@ -19,14 +17,24 @@
*
*************************************/
void slither_state::machine_start()
{
qix_state::machine_start();
save_item(NAME(m_sn76489_ctrl));
}
void qixmcu_state::machine_start()
{
qix_state::machine_start();
/* reset the coin counter register */
// HACK: force port B latch to zero to avoid spurious coin counter pulses because the MCU program initializes DDRB before the latch
m_mcu->set_state_int(m68705_device::M68705_LATCHB, 0);
// reset the coin counter register
m_coinctrl = 0x00;
/* set up save states */
// set up save states
save_item(NAME(m_68705_porta_out));
save_item(NAME(m_coinctrl));
}
@ -38,7 +46,7 @@ void zookeep_state::machine_start()
else
qix_state::machine_start();
/* configure the banking */
// configure the banking
m_vidbank->configure_entry(0, memregion("videocpu")->base() + 0xa000);
m_vidbank->configure_entry(1, memregion("videocpu")->base() + 0x10000);
m_vidbank->set_entry(0);
@ -66,7 +74,7 @@ void qix_state::qix_vsync_changed(int state)
void zookeep_state::bankswitch_w(uint8_t data)
{
m_vidbank->set_entry(BIT(data, 2));
/* not necessary, but technically correct */
// not necessary, but technically correct
qix_palettebank_w(data);
}
@ -158,8 +166,8 @@ uint8_t qixmcu_state::coin_r()
void qixmcu_state::coin_w(uint8_t data)
{
logerror("qixmcu_state, coin_w = %02X\n", data);
/* this is a callback called by pia6821_device::write(), so I don't need to synchronize */
/* the CPUs - they have already been synchronized by qix_pia_w() */
// this is a callback called by pia6821_device::write(), so I don't need to synchronize
// the CPUs - they have already been synchronized by qix_pia_w()
m_mcu->pa_w(data);
}
@ -169,8 +177,8 @@ void qixmcu_state::coinctrl_w(uint8_t data)
if (BIT(data, 2))
{
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
/* temporarily boost the interleave to sync things up */
/* note: I'm using 50 because 30 is not enough for space dungeon at game over */
// temporarily boost the interleave to sync things up
// note: I'm using 50 because 30 is not enough for space dungeon at game over
machine().scheduler().perfect_quantum(attotime::from_usec(50));
}
else
@ -178,8 +186,8 @@ void qixmcu_state::coinctrl_w(uint8_t data)
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
/* this is a callback called by pia6821_device::write(), so I don't need to synchronize */
/* the CPUs - they have already been synchronized by qix_pia_w() */
// this is a callback called by pia6821_device::write(), so I don't need to synchronize
// the CPUs - they have already been synchronized by qix_pia_w()
m_coinctrl = data;
logerror("qixmcu_state, coinctrl_w = %02X\n", data);
}
@ -194,13 +202,13 @@ void qixmcu_state::coinctrl_w(uint8_t data)
uint8_t qixmcu_state::mcu_portb_r()
{
return (ioport("COIN")->read() & 0x0f) | ((ioport("COIN")->read() & 0x80) >> 3);
return (m_coin->read() & 0x0f) | ((m_coin->read() & 0x80) >> 3);
}
uint8_t qixmcu_state::mcu_portc_r()
{
return (m_coinctrl & 0x08) | ((ioport("COIN")->read() & 0x70) >> 4);
return (m_coinctrl & 0x08) | ((m_coin->read() & 0x70) >> 4);
}
@ -218,8 +226,9 @@ void qixmcu_state::mcu_porta_w(uint8_t data)
}
void qixmcu_state::mcu_portb_w(uint8_t data)
void qixmcu_state::mcu_portb_w(offs_t offset, uint8_t data, uint8_t mem_mask)
{
data &= mem_mask;
machine().bookkeeping().coin_lockout_w(0, (~data >> 6) & 1);
machine().bookkeeping().coin_counter_w(0, (data >> 7) & 1);
}
@ -240,8 +249,8 @@ TIMER_CALLBACK_MEMBER(qix_state::pia_w_callback)
void qix_state::qix_pia_w(offs_t offset, uint8_t data)
{
/* make all the CPUs synchronize, and only AFTER that write the command to the PIA */
/* otherwise the 68705 will miss commands */
// make all the CPUs synchronize, and only AFTER that write the command to the PIA
// otherwise the 68705 will miss commands
machine().scheduler().synchronize(timer_expired_delegate(FUNC(qix_state::pia_w_callback), this), data | (offset << 8));
}
@ -259,6 +268,12 @@ void qix_state::qix_coinctl_w(uint8_t data)
machine().bookkeeping().coin_counter_w(0, (data >> 1) & 1);
}
void slither_state::slither_coinctl_w(uint8_t data)
{
machine().bookkeeping().coin_lockout_w(0, (~data >> 6) & 1);
machine().bookkeeping().coin_counter_w(0, (data >> 5) & 1);
}
/*************************************
@ -267,25 +282,23 @@ void qix_state::qix_coinctl_w(uint8_t data)
*
*************************************/
void qix_state::slither_76489_0_w(uint8_t data)
void slither_state::sn76489_0_ctrl_w(int state)
{
/* write to the sound chip */
m_sn1->write(data);
// write to the sound chip
if (!state && m_sn76489_ctrl[0])
m_sn[0]->write(m_pia1->b_output());
/* clock the ready line going back into CB1 */
m_pia1->cb1_w(0);
m_pia1->cb1_w(1);
m_sn76489_ctrl[0] = bool(state);
}
void qix_state::slither_76489_1_w(uint8_t data)
void slither_state::sn76489_1_ctrl_w(int state)
{
/* write to the sound chip */
m_sn2->write(data);
// write to the sound chip
if (!state && m_sn76489_ctrl[1])
m_sn[1]->write(m_pia2->b_output());
/* clock the ready line going back into CB1 */
m_pia2->cb1_w(0);
m_pia2->cb1_w(1);
m_sn76489_ctrl[1] = bool(state);
}
@ -296,13 +309,13 @@ void qix_state::slither_76489_1_w(uint8_t data)
*
*************************************/
uint8_t qix_state::slither_trak_lr_r()
uint8_t slither_state::trak_lr_r()
{
return ioport(m_flip ? "AN3" : "AN1")->read();
return m_trak[m_flip ? 3 : 1]->read();
}
uint8_t qix_state::slither_trak_ud_r()
uint8_t slither_state::trak_ud_r()
{
return ioport(m_flip ? "AN2" : "AN0")->read();
return m_trak[m_flip ? 2 : 0]->read();
}

View File

@ -10,9 +10,6 @@
#include "emu.h"
#include "qix.h"
#include "cpu/m6809/m6809.h"
#include "video/mc6845.h"
/*************************************
*
@ -107,7 +104,7 @@ void qix_state::qix_videoram_w(offs_t offset, uint8_t data)
}
void qix_state::slither_videoram_w(offs_t offset, uint8_t data)
void slither_state::slither_videoram_w(offs_t offset, uint8_t data)
{
/* update the screen in case the game is writing "behind" the beam -
Zookeeper likes to do this */
@ -160,7 +157,7 @@ void qix_state::qix_addresslatch_w(offs_t offset, uint8_t data)
}
void qix_state::slither_addresslatch_w(offs_t offset, uint8_t data)
void slither_state::slither_addresslatch_w(offs_t offset, uint8_t data)
{
/* update the screen in case the game is writing "behind" the beam */
// m_screen->update_now();
@ -352,16 +349,16 @@ void zookeep_state::video_map(address_map &map)
}
void qix_state::slither_video_map(address_map &map)
void slither_state::slither_video_map(address_map &map)
{
map(0x0000, 0x7fff).rw(FUNC(qix_state::qix_videoram_r), FUNC(qix_state::slither_videoram_w));
map(0x0000, 0x7fff).rw(FUNC(slither_state::qix_videoram_r), FUNC(slither_state::slither_videoram_w));
map(0x8000, 0x83ff).ram().share("share1");
map(0x8400, 0x87ff).ram().share("nvram");
map(0x8800, 0x8800).mirror(0x03ff).w(FUNC(qix_state::qix_palettebank_w));
map(0x8c00, 0x8c00).mirror(0x03fe).rw(FUNC(qix_state::qix_data_firq_r), FUNC(qix_state::qix_data_firq_w));
map(0x8c01, 0x8c01).mirror(0x03fe).rw(FUNC(qix_state::qix_video_firq_ack_r), FUNC(qix_state::qix_video_firq_ack_w));
map(0x9000, 0x93ff).ram().w(FUNC(qix_state::qix_paletteram_w)).share("paletteram");
map(0x9400, 0x9400).mirror(0x03fc).rw(FUNC(qix_state::qix_addresslatch_r), FUNC(qix_state::slither_addresslatch_w));
map(0x8800, 0x8800).mirror(0x03ff).w(FUNC(slither_state::qix_palettebank_w));
map(0x8c00, 0x8c00).mirror(0x03fe).rw(FUNC(slither_state::qix_data_firq_r), FUNC(slither_state::qix_data_firq_w));
map(0x8c01, 0x8c01).mirror(0x03fe).rw(FUNC(slither_state::qix_video_firq_ack_r), FUNC(slither_state::qix_video_firq_ack_w));
map(0x9000, 0x93ff).ram().w(FUNC(slither_state::qix_paletteram_w)).share("paletteram");
map(0x9400, 0x9400).mirror(0x03fc).rw(FUNC(slither_state::qix_addresslatch_r), FUNC(slither_state::slither_addresslatch_w));
map(0x9401, 0x9401).mirror(0x03fc).writeonly().share("videoram_mask");
map(0x9402, 0x9403).mirror(0x03fc).writeonly().share("videoram_addr");
map(0x9800, 0x9800).mirror(0x03ff).readonly().share("scanline_latch");
@ -408,8 +405,8 @@ void zookeep_state::video(machine_config &config)
m_videocpu->set_addrmap(AS_PROGRAM, &zookeep_state::video_map);
}
void qix_state::slither_video(machine_config &config)
void slither_state::slither_video(machine_config &config)
{
m_videocpu->set_clock(SLITHER_CLOCK_OSC/4/4); /* 1.34 MHz */
m_videocpu->set_addrmap(AS_PROGRAM, &qix_state::slither_video_map);
m_videocpu->set_addrmap(AS_PROGRAM, &slither_state::slither_video_map);
}