toratora: improve timing, add color overlay, small cleanups,

konmedal: assume z80b is 6mhz
This commit is contained in:
hap 2023-07-23 21:02:53 +02:00
parent d9f2803516
commit ccfc971107
7 changed files with 328 additions and 304 deletions

View File

@ -79,24 +79,24 @@ void tourtabl_state::main_map(address_map &map)
static INPUT_PORTS_START( tourtabl )
PORT_START("PADDLE1")
PORT_START("PADDLE1") // P1 white
PORT_BIT( 0xff, 0x8f, IPT_PADDLE ) PORT_MINMAX(0x1f, 0xff) PORT_SENSITIVITY(40) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(1)
PORT_START("PADDLE2")
PORT_START("PADDLE2") // P2 black
PORT_BIT( 0xff, 0x8f, IPT_PADDLE ) PORT_MINMAX(0x1f, 0xff) PORT_SENSITIVITY(40) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(2)
PORT_START("PADDLE3")
PORT_START("PADDLE3") // P3 white, or Breakout P2
PORT_BIT( 0xff, 0x8f, IPT_PADDLE ) PORT_MINMAX(0x1f, 0xff) PORT_SENSITIVITY(40) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(3)
PORT_START("PADDLE4")
PORT_START("PADDLE4") // P4 black, or Breakout P1
PORT_BIT( 0xff, 0x8f, IPT_PADDLE ) PORT_MINMAX(0x1f, 0xff) PORT_SENSITIVITY(40) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(4)
PORT_START("TIA_IN4") // TIA INPT4
PORT_START("TIA_IN4") // TIA INPT4
PORT_DIPNAME( 0x80, 0x80, "Breakout Replay" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ))
PORT_DIPSETTING( 0x80, DEF_STR( On ))
PORT_START("TIA_IN5") // TIA INPT5
PORT_START("TIA_IN5") // TIA INPT5
PORT_DIPNAME( 0x80, 0x80, "Game Length" )
PORT_DIPSETTING( 0x00, "11 points (3 balls)" )
PORT_DIPSETTING( 0x80, "15 points (5 balls)" )

View File

@ -16438,7 +16438,7 @@ GAME( 1983, ozon1, 0, ozon1, ozon1, galaxian_state, init_
GAME( 1981, ckongs, ckong, ckongs, ckongs, galaxian_state, init_ckongs, ROT90, "bootleg", "Crazy Kong (bootleg on Scramble hardware)", MACHINE_SUPPORTS_SAVE )
// Konami L-1200-2 base board with custom Subelectro 113 rom board
GAME( 1981, jungsub, jungler, jungsub, jungsub, galaxian_state, init_jungsub, ROT90, "bootleg (Subelectro)", "Jungler (Subelectro, bootleg on Scramble hardware)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // mostly works, bad GFX ROM causes lots of glitches
GAME( 1981, jungsub, jungler, jungsub, jungsub, galaxian_state, init_jungsub, ROT90, "bootleg (Subelectro)", "Jungler (Subelectro, bootleg on Scramble hardware)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // mostly works, bad GFX ROM causes lots of glitches
// Scorpion hardware; based on Scramble but with a 3rd AY-8910 and a speech chip
GAME( 1982, scorpion, 0, scorpion, scorpion, zac_scorpion_state, init_scorpion, ROT90, "Zaccaria", "Scorpion (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE)

View File

@ -2,7 +2,7 @@
// copyright-holders:Pierpaolo Prazzoli, Tomasz Slanina
/********************************************************************
Enigma 2 (C) Game Plan / Zilec Electronics
Enigma 2 (C) Zilec Electronics / Game Plan
driver by Pierpaolo Prazzoli and Tomasz Slanina
@ -170,13 +170,13 @@ class enigma2_state : public driver_device
public:
enigma2_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_colors(*this, "colors"),
m_stars(*this, "stars")
m_stars(*this, "stars"),
m_videoram(*this, "videoram")
{ }
void enigma2(machine_config &config);
@ -187,11 +187,19 @@ public:
DECLARE_CUSTOM_INPUT_MEMBER(p1_controls_r);
DECLARE_CUSTOM_INPUT_MEMBER(p2_controls_r);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
/* memory pointers */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<screen_device> m_screen;
optional_device<palette_device> m_palette;
optional_region_ptr<uint8_t> m_colors;
optional_region_ptr<uint8_t> m_stars;
required_shared_ptr<uint8_t> m_videoram;
/* misc */
int m_blink_count = 0;
uint8_t m_sound_latch = 0;
uint8_t m_last_sound_data = 0;
@ -201,29 +209,20 @@ private:
emu_timer *m_interrupt_clear_timer = nullptr;
emu_timer *m_interrupt_assert_timer = nullptr;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<screen_device> m_screen;
optional_device<palette_device> m_palette;
optional_region_ptr<uint8_t> m_colors;
optional_region_ptr<uint8_t> m_stars;
uint8_t dip_switch_r(offs_t offset);
void sound_data_w(uint8_t data);
void enigma2_flip_screen_w(uint8_t data);
uint8_t sound_latch_r();
void protection_data_w(uint8_t data);
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_enigma2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_enigma2a(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(interrupt_clear_callback);
TIMER_CALLBACK_MEMBER(interrupt_assert_callback);
inline uint16_t vpos_to_vysnc_chain_counter( int vpos );
inline int vysnc_chain_counter_to_vpos( uint16_t counter );
void create_interrupt_timers( );
void start_interrupt_timers( );
void create_interrupt_timers();
void start_interrupt_timers();
void enigma2_audio_cpu_map(address_map &map);
void enigma2_main_cpu_map(address_map &map);
void enigma2a_main_cpu_io_map(address_map &map);
@ -298,7 +297,6 @@ void enigma2_state::machine_start()
{
create_interrupt_timers();
save_item(NAME(m_blink_count));
save_item(NAME(m_sound_latch));
save_item(NAME(m_last_sound_data));
@ -722,7 +720,6 @@ void enigma2_state::enigma2(machine_config &config)
m_audiocpu->set_addrmap(AS_PROGRAM, &enigma2_state::enigma2_audio_cpu_map);
m_audiocpu->set_periodic_int(FUNC(enigma2_state::irq0_line_hold), attotime::from_hz(8*52));
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);
@ -751,7 +748,6 @@ void enigma2_state::enigma2a(machine_config &config)
m_audiocpu->set_addrmap(AS_PROGRAM, &enigma2_state::enigma2_audio_cpu_map);
m_audiocpu->set_periodic_int(FUNC(enigma2_state::irq0_line_hold), attotime::from_hz(8*52));
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);

View File

@ -1,37 +1,38 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************
/*******************************************************************************
Tora Tora (c) 1980 Game Plan
driver by Nicola Salmoria, qwijibo
deviations from schematics verified on set 2 pcb:
main pcb:
- U33.3 connected to /IRQ line via inverter U67.9,
providing timer IRQ for input polling.
main pcb:
- U33.3 connected to /IRQ line via inverter U67.9,
providing timer IRQ for input polling.
- U43 removed from timer circuit, U52.9 wired directly to
U32.5, increasing timer frequency to 250 Hz.
- U43 removed from timer circuit, U52.9 wired directly to
U32.5, increasing timer frequency to 250 Hz.
audio pcb:
- U6.10 wired to U14.21, cut from R14/16
- R16 wired to R1 in series, R1 cut from GND
- R14 wired to GND instead of U6.10
audio pcb:
- U6.10 wired to U14.21, cut from R14/16
- R16 wired to R1 in series, R1 cut from GND
- R14 wired to GND instead of U6.10
- U5.10 wired to U15.21, cut from R13/15
- R15 wired to R2 in series, R2 cut from GND
- R13 wired to GND instead of U5.10
- U5.10 wired to U15.21, cut from R13/15
- R15 wired to R2 in series, R2 cut from GND
- R13 wired to GND instead of U5.10
- EXT VCO DACs (U11, U12) and surrounding logic not placed
- Numerous changes to SN74677 timing component R & C values
- EXT VCO DACs (U11, U12) and surrounding logic not placed
- Numerous changes to SN74677 timing component R & C values
TODO:
- The game reads some unmapped memory addresses, missing ROMs? There's an empty
socket for U3 on the board, which should map at 5000-57ff, however the
game reads mostly from 4800-4fff, which would be U6 according to the
schematics.
socket for U3 on the board, which should map at 5000-57ff, however the game
reads mostly from 4800-4fff, which would be U6 according to the schematics.
- The manual mentions dip switch settings and the schematics show the switches,
the game reads them but ignores them, forcing 1C/1C and 3 lives.
@ -40,64 +41,74 @@ TODO:
- Bullet and explosion audio frequencies seem incorrect
***************************************************************************/
- Who designed/developed the game? Taiyo System is mentioned online, but there's
no solid proof. It's more likely an American game. At the end of tora.u11,
there's "EMS INC.,1979".
*******************************************************************************/
#include "emu.h"
#include "cpu/m6800/m6800.h"
#include "machine/6821pia.h"
#include "machine/input_merger.h"
#include "sound/sn76477.h"
#include "screen.h"
#include "speaker.h"
#include "toratora.lh"
namespace {
class toratora_state : public driver_device
{
public:
toratora_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_videoram(*this, "videoram"),
toratora_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_sn1(*this, "sn1"),
m_sn2(*this, "sn2"),
m_pia_u1(*this, "pia_u1"),
m_pia_u2(*this, "pia_u2"),
m_pia_u3(*this, "pia_u3") { }
m_irq(*this, "irq"),
m_pia(*this, "pia%u", 1U),
m_screen(*this, "screen"),
m_sn(*this, "sn%u", 1U),
m_videoram(*this, "videoram"),
m_dsw(*this, "DSW")
{ }
void toratora(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
/* memory pointers */
required_shared_ptr<uint8_t> m_videoram;
/* video-related */
int m_timer = 0;
uint8_t m_clear_tv = 0;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<sn76477_device> m_sn1;
required_device<sn76477_device> m_sn2;
required_device<pia6821_device> m_pia_u1;
required_device<pia6821_device> m_pia_u2;
required_device<pia6821_device> m_pia_u3;
required_device<input_merger_device> m_irq;
required_device_array<pia6821_device, 3> m_pia;
required_device<screen_device> m_screen;
required_device_array<sn76477_device, 2> m_sn;
required_shared_ptr<uint8_t> m_videoram;
required_ioport m_dsw;
emu_timer *m_timer;
uint8_t m_timer_count = 0;
bool m_timer_clk = false;
bool m_clear_tv = false;
bool m_dsw_enable = true;
void clear_tv_w(uint8_t data);
uint8_t timer_r();
void clear_timer_w(uint8_t data);
void cb2_u2_w(int state);
void port_b_u1_w(uint8_t data);
void main_cpu_irq(int state);
void sn1_port_a_u3_w(uint8_t data);
void sn1_port_b_u3_w(uint8_t data);
void sn1_ca2_u3_w(int state);
void sn2_port_a_u2_w(uint8_t data);
void sn2_port_b_u2_w(uint8_t data);
void sn2_ca2_u2_w(int state);
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_toratora(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(toratora_timer);
uint8_t dsw_r();
void dsw_enable_w(int state);
void coin_w(offs_t offset, uint8_t data, uint8_t mem_mask);
template<int N> void sn_vco_voltage_w(uint8_t data);
void sn1_w(uint8_t data);
void sn2_w(uint8_t data);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(toratora_timer);
void main_map(address_map &map);
};
@ -105,15 +116,32 @@ private:
/*************************************
*
* Input handling
* Initialization
*
*************************************/
void toratora_state::cb2_u2_w(int state)
void toratora_state::machine_start()
{
logerror("DIP tristate %sactive\n",(state & 1) ? "in" : "");
// 500Hz timer from 2*9602
m_timer = timer_alloc(FUNC(toratora_state::toratora_timer), this);
m_timer->adjust(attotime::from_hz(500), 0, attotime::from_hz(500));
m_pia[0]->ca1_w(0);
m_pia[0]->ca2_w(0);
save_item(NAME(m_timer_count));
save_item(NAME(m_timer_clk));
save_item(NAME(m_clear_tv));
save_item(NAME(m_dsw_enable));
}
void toratora_state::machine_reset()
{
m_timer_count = 0;
m_clear_tv = false;
}
/*************************************
*
@ -121,7 +149,7 @@ void toratora_state::cb2_u2_w(int state)
*
*************************************/
uint32_t toratora_state::screen_update_toratora(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t toratora_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_videoram.bytes(); offs++)
{
@ -132,89 +160,29 @@ uint32_t toratora_state::screen_update_toratora(screen_device &screen, bitmap_rg
for (int i = 0; i < 8; i++)
{
pen_t pen = (data & 0x80) ? rgb_t::white() : rgb_t::black();
bitmap.pix(y, x) = pen;
if (cliprect.contains(x, y))
bitmap.pix(y, x) = pen;
data = data << 1;
x = x + 1;
}
/* the video system clears as it writes out the pixels */
// the video system clears as it writes out the pixels
if (m_clear_tv)
m_videoram[offs] = 0;
}
m_clear_tv = 0;
m_clear_tv = false;
return 0;
}
void toratora_state::clear_tv_w(uint8_t data)
{
m_clear_tv = 1;
m_clear_tv = true;
}
/*************************************
*
* Coin counter
*
*************************************/
void toratora_state::port_b_u1_w(uint8_t data)
{
if (m_pia_u1->port_b_z_mask() & 0x20)
machine().bookkeeping().coin_counter_w(0, 1);
else
machine().bookkeeping().coin_counter_w(0, data & 0x20);
}
/*************************************
*
* Interrupt generation
*
*************************************/
void toratora_state::main_cpu_irq(int state)
{
int combined_state = m_pia_u1->irq_a_state() | m_pia_u1->irq_b_state();
logerror("GEN IRQ: %x\n", combined_state);
m_maincpu->set_input_line(0, combined_state ? ASSERT_LINE : CLEAR_LINE);
}
INTERRUPT_GEN_MEMBER(toratora_state::toratora_timer)
{
/* timer counting at 250 Hz. (500 Hz / 2 via U52.9).
* U43 removed from circuit, U52.9 wired to U32.5) */
m_timer++;
/* U33 bit 0 routed to /IRQ line after inverting through U67.9 */
if(m_timer & 0x10)
m_maincpu->set_input_line(0, ASSERT_LINE);
/* also, when the timer overflows (16 seconds) watchdog would kick in */
if (m_timer & 0x100)
popmessage("watchdog!");
m_pia_u1->porta_w(ioport("INPUT")->read() & 0x0f);
m_pia_u1->ca1_w(ioport("INPUT")->read() & 0x10);
m_pia_u1->ca2_w(ioport("INPUT")->read() & 0x20);
}
uint8_t toratora_state::timer_r()
{
return m_timer;
}
void toratora_state::clear_timer_w(uint8_t data)
{
m_timer = 0;
m_maincpu->set_input_line(0, CLEAR_LINE);
}
/*************************************
*
@ -222,20 +190,20 @@ void toratora_state::clear_timer_w(uint8_t data)
*
*************************************/
void toratora_state::sn1_port_a_u3_w(uint8_t data)
template<int N>
void toratora_state::sn_vco_voltage_w(uint8_t data)
{
m_sn1->vco_voltage_w(2.35 * (data & 0x7f) / 128.0);
m_sn1->enable_w((data >> 7) & 0x01);
m_sn[N]->vco_voltage_w(2.35 * (data & 0x7f) / 128.0);
m_sn[N]->enable_w(BIT(data, 7));
}
void toratora_state::sn1_port_b_u3_w(uint8_t data)
// U14
void toratora_state::sn1_w(uint8_t data)
{
static const double resistances[] =
{
RES_INF, /* N/C */
RES_INF, /* R39 not placed */
RES_INF, // N/C
RES_INF, // R39 not placed
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51) + RES_K(100) + RES_K(240),
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51) + RES_K(100),
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51),
@ -244,41 +212,26 @@ void toratora_state::sn1_port_b_u3_w(uint8_t data)
RES_INF
};
m_sn1->mixer_a_w ((data >> 0) & 0x01);
m_sn1->mixer_b_w ((data >> 1) & 0x01);
m_sn1->mixer_c_w ((data >> 2) & 0x01);
m_sn1->envelope_1_w ((data >> 3) & 0x01);
m_sn1->envelope_2_w ((data >> 4) & 0x01);
m_sn1->slf_res_w(resistances[(data >> 5)]);
m_sn[0]->mixer_a_w(BIT(data, 0));
m_sn[0]->mixer_b_w(BIT(data, 1));
m_sn[0]->mixer_c_w(BIT(data, 2));
m_sn[0]->envelope_1_w(BIT(data, 3));
m_sn[0]->envelope_2_w(BIT(data, 4));
/*
* TODO: Determine proper 7441 output voltage here.
* Datasheet lists 2.5 V max under worst conditions,
* probably much lower in reality?
* However, shot audio is muted if V < 1.0, as mixer state
* is set to SLF & VCO. Should SLF FF state be inverted?
*/
m_sn1->slf_cap_voltage_w((data >> 5) == 0x7 ? 2.5 : sn76477_device::EXTERNAL_VOLTAGE_DISCONNECT);
uint8_t res = data >> 5 & 0x7;
m_sn[0]->slf_res_w(resistances[res]);
m_sn[0]->slf_cap_voltage_w(res == 0x7 ? 2.5 : sn76477_device::EXTERNAL_VOLTAGE_DISCONNECT);
// Seems like the output should be muted when res == 0, but unsure of exact mechanism
m_sn[0]->amplitude_res_w(resistances[res]);
}
void toratora_state::sn1_ca2_u3_w(int state)
{
m_sn1->vco_w(state);
}
void toratora_state::sn2_port_a_u2_w(uint8_t data)
{
m_sn2->vco_voltage_w(2.35 * (data & 0x7f) / 128.0);
m_sn2->enable_w((data >> 7) & 0x01);
}
void toratora_state::sn2_port_b_u2_w(uint8_t data)
// U15
void toratora_state::sn2_w(uint8_t data)
{
static const double resistances[] =
{
RES_INF, /* N/C */
RES_INF, // N/C
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51) + RES_K(100) + RES_M(240) + RES_M(2),
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51) + RES_K(100) + RES_K(240),
RES_K(10) + RES_K(10) + RES_K(24) + RES_K(51) + RES_K(100),
@ -288,24 +241,88 @@ void toratora_state::sn2_port_b_u2_w(uint8_t data)
RES_INF
};
m_sn2->mixer_a_w ((data >> 0) & 0x01);
m_sn2->mixer_b_w ((data >> 1) & 0x01);
m_sn2->mixer_c_w ((data >> 2) & 0x01);
m_sn2->envelope_1_w ((data >> 3) & 0x01);
m_sn2->envelope_2_w ((data >> 4) & 0x01);
m_sn2->slf_res_w(resistances[(data >> 5)]);
m_sn2->slf_cap_voltage_w((data >> 5) == 0x7 ? 2.5 : sn76477_device::EXTERNAL_VOLTAGE_DISCONNECT);
m_sn[1]->mixer_a_w(BIT(data, 0));
m_sn[1]->mixer_b_w(BIT(data, 1));
m_sn[1]->mixer_c_w(BIT(data, 2));
m_sn[1]->envelope_1_w(BIT(data, 3));
m_sn[1]->envelope_2_w(BIT(data, 4));
/* Seems like the output should be muted in this case, but unsure of exact mechanism */
m_sn2->amplitude_res_w((data >> 5) == 0x0 ? RES_INF : RES_K(47));
uint8_t res = data >> 5 & 0x7;
m_sn[1]->slf_res_w(resistances[res]);
// TODO: Determine proper 7441 output voltage here.
// Datasheet lists 2.5 V max under worst conditions, probably much lower in reality?
// However, shot audio is muted if V < 1.0, as mixer state is set to SLF & VCO.
// Should SLF FF state be inverted?
m_sn[1]->slf_cap_voltage_w(res == 0x7 ? 2.5 : sn76477_device::EXTERNAL_VOLTAGE_DISCONNECT);
}
void toratora_state::sn2_ca2_u2_w(int state)
/*************************************
*
* Timer
*
*************************************/
TIMER_CALLBACK_MEMBER(toratora_state::toratora_timer)
{
m_sn2->vco_w(state);
// RAM refresh circuit halts the cpu for 64 cycles
m_maincpu->adjust_icount(-64);
m_timer_clk = !m_timer_clk;
if (m_timer_clk)
{
// timer counting at 250 Hz. (500 Hz / 2 via U52.9)
// U43 removed from circuit, U52.9 wired to U32.5)
m_timer_count++;
// U33 bit 0 routed to /IRQ line after inverting through U67.9
m_irq->in_w<0>(BIT(m_timer_count, 4));
// also, when the timer overflows, watchdog would kick in
if (m_timer_count == 0)
machine().schedule_soft_reset();
}
}
uint8_t toratora_state::timer_r()
{
return m_timer_count;
}
void toratora_state::clear_timer_w(uint8_t data)
{
m_timer_count = 0;
m_irq->in_w<0>(0);
}
/*************************************
*
* Misc. I/O
*
*************************************/
void toratora_state::dsw_enable_w(int state)
{
m_dsw_enable = !state;
}
uint8_t toratora_state::dsw_r()
{
return m_dsw_enable ? m_dsw->read() : 0;
}
void toratora_state::coin_w(offs_t offset, uint8_t data, uint8_t mem_mask)
{
data |= ~mem_mask;
machine().bookkeeping().coin_counter_w(0, data & 0x20);
}
/*************************************
*
@ -319,16 +336,16 @@ void toratora_state::sn2_ca2_u2_w(int state)
void toratora_state::main_map(address_map &map)
{
map(0x0000, 0x0fff).ram();
map(0x1000, 0x7fff).rom(); /* not fully populated */
map(0x8000, 0x9fff).ram().share("videoram");
map(0x1000, 0x7fff).rom(); // not fully populated
map(0x8000, 0x9fff).ram().share(m_videoram);
map(0xa000, 0xf047).noprw();
map(0xf048, 0xf049).noprw();
map(0xf04a, 0xf04a).w(FUNC(toratora_state::clear_tv_w)); /* the read is mark *LEDEN, but not used */
map(0xf04a, 0xf04a).w(FUNC(toratora_state::clear_tv_w)); // the read is mark !LEDEN, but not used
map(0xf04b, 0xf04b).rw(FUNC(toratora_state::timer_r), FUNC(toratora_state::clear_timer_w));
map(0xf04c, 0xf09f).noprw();
map(0xf0a0, 0xf0a3).rw(m_pia_u1, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0a4, 0xf0a7).rw(m_pia_u2, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0a8, 0xf0ab).rw(m_pia_u3, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0a0, 0xf0a3).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0a4, 0xf0a7).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0a8, 0xf0ab).rw(m_pia[2], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xf0ac, 0xf7ff).noprw();
map(0xf800, 0xffff).rom();
}
@ -343,32 +360,33 @@ void toratora_state::main_map(address_map &map)
static INPUT_PORTS_START( toratora )
PORT_START("INPUT")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("COIN")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_WRITE_LINE_DEVICE_MEMBER("pia1", pia6821_device, ca2_w)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_WRITE_LINE_DEVICE_MEMBER("pia1", pia6821_device, ca1_w)
PORT_START("DSW")
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x03, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_3C ) )
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("U13:!1,!2")
PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:3,4")
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_5C ) )
PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("U13:!3,!4")
PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:5")
PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) )
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unused ) ) PORT_DIPLOCATION("U13:!5")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:6")
PORT_DIPSETTING( 0x20, "4" )
PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("U13:!6")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x20, "4" )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
@ -381,81 +399,60 @@ INPUT_PORTS_END
*
*************************************/
void toratora_state::machine_start()
{
save_item(NAME(m_timer));
save_item(NAME(m_clear_tv));
}
void toratora_state::machine_reset()
{
m_timer = 0xff;
m_clear_tv = 0;
}
void toratora_state::toratora(machine_config &config)
{
/* basic machine hardware */
M6800(config, m_maincpu, 5.185_MHz_XTAL / 8); /* 5.185 MHz XTAL divided by 8 (@ U94.12) */
// basic machine hardware
M6800(config, m_maincpu, 5.185_MHz_XTAL / 8); // 5.185 MHz XTAL divided by 8 (@ U94.12)
m_maincpu->set_addrmap(AS_PROGRAM, &toratora_state::main_map);
m_maincpu->set_periodic_int(FUNC(toratora_state::toratora_timer), attotime::from_hz(250)); /* timer counting at 250 Hz */
PIA6821(config, m_pia_u1);
m_pia_u1->writepb_handler().set(FUNC(toratora_state::port_b_u1_w));
m_pia_u1->irqa_handler().set(FUNC(toratora_state::main_cpu_irq));
m_pia_u1->irqb_handler().set(FUNC(toratora_state::main_cpu_irq));
INPUT_MERGER_ANY_HIGH(config, m_irq);
m_irq->output_handler().set_inputline(m_maincpu, 0);
PIA6821(config, m_pia_u3);
m_pia_u3->writepa_handler().set(FUNC(toratora_state::sn1_port_a_u3_w));
m_pia_u3->writepb_handler().set(FUNC(toratora_state::sn1_port_b_u3_w));
m_pia_u3->ca2_handler().set(FUNC(toratora_state::sn1_ca2_u3_w));
PIA6821(config, m_pia[0]); // U1
m_pia[0]->readpa_handler().set_ioport("INPUT");
m_pia[0]->writepb_handler().set(FUNC(toratora_state::coin_w));
m_pia[0]->irqa_handler().set(m_irq, FUNC(input_merger_device::in_w<1>));
m_pia[0]->irqb_handler().set(m_irq, FUNC(input_merger_device::in_w<2>));
PIA6821(config, m_pia_u2);
m_pia_u2->readpb_handler().set_ioport("DSW");
m_pia_u2->writepa_handler().set(FUNC(toratora_state::sn2_port_a_u2_w));
m_pia_u2->writepb_handler().set(FUNC(toratora_state::sn2_port_b_u2_w));
m_pia_u2->ca2_handler().set(FUNC(toratora_state::sn2_ca2_u2_w));
m_pia_u2->cb2_handler().set(FUNC(toratora_state::cb2_u2_w));
PIA6821(config, m_pia[1]); // U2
m_pia[1]->writepa_handler().set(FUNC(toratora_state::sn_vco_voltage_w<0>));
m_pia[1]->readpb_handler().set(FUNC(toratora_state::dsw_r));
m_pia[1]->writepb_handler().set(FUNC(toratora_state::sn1_w));
m_pia[1]->ca2_handler().set(m_sn[0], FUNC(sn76477_device::vco_w));
m_pia[1]->cb2_handler().set(FUNC(toratora_state::dsw_enable_w));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(5.185_MHz_XTAL, 320, 0, 256, 287, 8, 248);
screen.set_screen_update(FUNC(toratora_state::screen_update_toratora));
PIA6821(config, m_pia[2]); // U3
m_pia[2]->writepa_handler().set(FUNC(toratora_state::sn_vco_voltage_w<1>));
m_pia[2]->writepb_handler().set(FUNC(toratora_state::sn2_w));
m_pia[2]->ca2_handler().set(m_sn[1], FUNC(sn76477_device::vco_w));
/* audio hardware */
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE);
m_screen->set_raw(5.185_MHz_XTAL, 256+40, 0, 256, 256+31+4, 8, 248);
m_screen->set_screen_update(FUNC(toratora_state::screen_update));
// audio hardware
SPEAKER(config, "mono").front_center();
SN76477(config, m_sn1);
m_sn1->set_noise_params(RES_K(47), RES_K(470), CAP_P(470));
m_sn1->set_decay_res(RES_M(2));
m_sn1->set_attack_params(CAP_U(0.2), RES_K(3.3));
m_sn1->set_amp_res(RES_K(47));
m_sn1->set_feedback_res(RES_K(50));
m_sn1->set_vco_params(0, CAP_U(0.1), RES_K(51));
m_sn1->set_pitch_voltage(5.0);
m_sn1->set_slf_params(CAP_U(1.0), RES_K(10));
m_sn1->set_oneshot_params(CAP_U(0.1), RES_K(100));
m_sn1->set_vco_mode(0);
m_sn1->set_mixer_params(0, 0, 0);
m_sn1->set_envelope_params(0, 0);
m_sn1->set_enable(1);
m_sn1->add_route(ALL_OUTPUTS, "mono", 0.50);
SN76477(config, m_sn2);
m_sn2->set_noise_params(RES_K(47), RES_K(470), CAP_P(470));
m_sn2->set_decay_res(RES_M(2));
m_sn2->set_attack_params(CAP_U(0.2), RES_K(3.3));
m_sn2->set_amp_res(RES_K(47));
m_sn2->set_feedback_res(RES_K(50));
m_sn2->set_vco_params(0, CAP_U(0.1), RES_K(51));
m_sn2->set_pitch_voltage(5.0);
m_sn2->set_slf_params(CAP_U(1.0), RES_K(10));
m_sn2->set_oneshot_params(CAP_U(0.1), RES_K(100));
m_sn2->set_vco_mode(0);
m_sn2->set_mixer_params(0, 0, 0);
m_sn2->set_envelope_params(0, 0);
m_sn2->set_enable(1);
m_sn2->add_route(ALL_OUTPUTS, "mono", 0.50);
for (int i = 0; i < 2; i++)
{
SN76477(config, m_sn[i]);
m_sn[i]->set_noise_params(RES_K(47), RES_K(470), CAP_P(470));
m_sn[i]->set_decay_res(RES_M(2));
m_sn[i]->set_attack_params(CAP_U(0.2), RES_K(3.3));
m_sn[i]->set_amp_res(RES_K(47));
m_sn[i]->set_feedback_res(RES_K(50));
m_sn[i]->set_vco_params(0, CAP_U(0.1), RES_K(51));
m_sn[i]->set_pitch_voltage(5.0);
m_sn[i]->set_slf_params(CAP_U(1.0), RES_K(10));
m_sn[i]->set_oneshot_params(CAP_U(0.1), RES_K(100));
m_sn[i]->set_vco_mode(0);
m_sn[i]->set_mixer_params(0, 0, 0);
m_sn[i]->set_envelope_params(0, 0);
m_sn[i]->set_enable(1);
m_sn[i]->add_route(ALL_OUTPUTS, "mono", 0.50);
}
}
@ -475,39 +472,40 @@ ROM_START( toratora )
ROM_LOAD( "tora.u11", 0xf800, 0x0800, CRC(55135d6f) SHA1(c48f180a9d6e894aafe87b2daf74e9a082f4600e) )
ROM_END
/* Tora Tora? Game Plan?
Etched in copper on top of board 20-00047C
20-10051A
Etched in copper on top of board 20-00047C
20-10051A
Etched in copper on back of daughter board 20-00048C
20-10052A
20-10052A
ROM text showed TORA TOR* * was A with bit 7 set
1980 GAME PLAN,INC
ROM text showed TORA TOR* * was A with bit 7 set
1980 GAME PLAN,INC
and war stuff (PLANE, BOMB, SQUAD, etc)
and war stuff (PLANE, BOMB, SQUAD, etc)
.u2 2716 handwritten sticker U-2
.u9 2716 handwritten sticker U-9
.u10 2716 handwritten sticker U-10
.u11 2716 handwritten sticker U-11
.u2 2716 handwritten sticker U-2
.u9 2716 handwritten sticker U-9
.u10 2716 handwritten sticker U-10
.u11 2716 handwritten sticker U-11
open 24 pin socket @ U1 and U3
open 40 pin socket @ U42
Main board
crystal with 5 185 on the top
5280 x8
5280 x8
socketed ds8833 x2
socketed ds8t28 x2
Daughter board
open 40 pin socket @ U3 @ U2
76477 X2 */
76477 x2 */
ROM_START( toratorab )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "1027.u1", 0x1000, 0x0800, BAD_DUMP CRC(413c743a) SHA1(a887dfaaee557327a1699bb424488b934dab8612) ) /* rom u1 is missing in this set, using the toratora one */
ROM_LOAD( "1027.u1", 0x1000, 0x0800, BAD_DUMP CRC(413c743a) SHA1(a887dfaaee557327a1699bb424488b934dab8612) ) // rom u1 is missing in this set, using the toratora one
ROM_LOAD( "1027.u10", 0x1800, 0x0800, CRC(6a906292) SHA1(4ceff91b7dcd398e57cd19a91d2199c09cb37c39) )
ROM_LOAD( "1027.u2", 0x2000, 0x0800, CRC(c1331648) SHA1(379101c6c1b8dab3e043ece01579cc96f6bb18a9) )
ROM_LOAD( "1027.u9", 0x2800, 0x0800, CRC(59b021b5) SHA1(ea5a0c1f58c0e08231969ad161b79af6e1ae4431) )
@ -517,11 +515,12 @@ ROM_END
} // anonymous namespace
/*************************************
*
* Game driver
*
*************************************/
GAME( 1980, toratora, 0, toratora, toratora, toratora_state, empty_init, ROT90, "Game Plan", "Tora Tora (prototype?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, toratorab,toratora, toratora, toratora, toratora_state, empty_init, ROT90, "Game Plan", "Tora Tora (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAMEL( 1980, toratora, 0, toratora, toratora, toratora_state, empty_init, ROT90, "Game Plan", "Tora Tora (prototype?)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_toratora )
GAMEL( 1980, toratorab, toratora, toratora, toratora, toratora_state, empty_init, ROT90, "Game Plan", "Tora Tora (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_toratora )

View File

@ -1013,7 +1013,7 @@ void konmedal_state::mario_scrollhack_w(uint8_t data)
void konmedal_state::shuriboy(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, XTAL(24'000'000) / 3); // divisor unknown
Z80(config, m_maincpu, XTAL(24'000'000) / 4); // divisor unknown
m_maincpu->set_addrmap(AS_PROGRAM, &konmedal_state::shuriboy_main);
TIMER(config, "scantimer").configure_scanline(FUNC(konmedal_state::shuri_scanline), "screen", 0, 1);
@ -1031,8 +1031,8 @@ void konmedal_state::shuriboy(machine_config &config)
screen.set_palette(m_palette);
PALETTE(config, m_palette, FUNC(konmedal_state::konmedal_palette)).set_format(palette_device::xRGB_444, 256); // not verified
// m_palette->enable_shadows();
// m_palette->enable_hilights();
//m_palette->enable_shadows();
//m_palette->enable_hilights();
K052109(config, m_k052109, 0);
m_k052109->set_palette(m_palette);

View File

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<!--
license:CC0-1.0
-->
<mamelayout version="2">
<element name="overlay">
<rect>
<bounds left="0" top="0" right="240" bottom="240" />
<color red="1" green="1" blue="0.25" />
</rect>
<rect>
<bounds left="0" top="176" right="240" bottom="240" />
<color red="0.0" green="0.9" blue="0.5" />
</rect>
<rect>
<bounds left="0" top="223" right="240" bottom="256" />
<color red="0.2" green="0.5" blue="1" />
</rect>
</element>
<view name="Color Overlay">
<screen index="0">
<bounds left="0" top="0" right="3" bottom="4" />
</screen>
<element ref="overlay" blend="multiply">
<bounds left="0" top="0" right="3" bottom="4" />
</element>
</view>
</mamelayout>

View File

@ -62,7 +62,7 @@ protected:
virtual void video_start() override;
private:
// devices/pointers
// devices
required_device<cpu_device> m_maincpu;
required_device<m68705p_device> m_mcu;
required_device<screen_device> m_screen;
@ -120,7 +120,7 @@ private:
u8 m_prev_value_31 = 0;
u8 m_dir_31 = 0;
// devices
// handlers
u8 mcu_r();
void mcu_w(u8 data);
void changela_68705_port_a_w(u8 data);