quasar: fix soundlatch, irq vector, 'effect' colors, added dipswitch locations

This commit is contained in:
hap 2024-11-24 19:38:18 +01:00
parent dfe0e5ec7b
commit 105774648d
4 changed files with 177 additions and 175 deletions

View File

@ -97,7 +97,6 @@ Todo & FIXME:
***************************************************************************/
#include "emu.h"
#include "cvs_base.h"
#include "speaker.h"

View File

@ -25,6 +25,19 @@
class cvs_base_state : public driver_device
{
protected:
cvs_base_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_bullet_ram(*this, "bullet_ram")
, m_maincpu(*this, "maincpu")
, m_s2636(*this, "s2636%u", 0U)
, m_gfxdecode(*this, "gfxdecode")
, m_screen(*this, "screen")
, m_palette(*this, "palette")
, m_video_ram(*this, "video_ram", 0x400, ENDIANNESS_BIG)
, m_color_ram(*this, "color_ram", 0x400, ENDIANNESS_BIG)
, m_ram_view(*this, "video_color_ram_view")
{ }
static inline constexpr uint8_t CVS_MAX_STARS = 250;
static inline constexpr int8_t CVS_S2636_Y_OFFSET = -5;
static inline constexpr int8_t CVS_S2636_X_OFFSET = -26;
@ -57,19 +70,6 @@ protected:
memory_view m_ram_view;
cvs_base_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_bullet_ram(*this, "bullet_ram")
, m_maincpu(*this, "maincpu")
, m_s2636(*this, "s2636%u", 0U)
, m_gfxdecode(*this, "gfxdecode")
, m_screen(*this, "screen")
, m_palette(*this, "palette")
, m_video_ram(*this, "video_ram", 0x400, ENDIANNESS_BIG)
, m_color_ram(*this, "color_ram", 0x400, ENDIANNESS_BIG)
, m_ram_view(*this, "video_color_ram_view")
{ }
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;

View File

@ -77,7 +77,6 @@ TODO:
*/
#include "emu.h"
#include "cvs_base.h"
#include "speaker.h"
@ -140,6 +139,12 @@ private:
};
/***************************************************************************
Video
***************************************************************************/
static constexpr uint8_t SPRITE_PEN_BASE = 0x10;
static constexpr uint8_t STAR_PEN = 0x18;
static constexpr uint8_t BULLET_PEN = 0x19;
@ -568,7 +573,7 @@ GFXDECODE_END
void galaxia_state::galaxia(machine_config &config)
{
// basic machine hardware
S2650(config, m_maincpu, XTAL(14'318'181) / 8);
S2650(config, m_maincpu, 14.318181_MHz_XTAL / 8);
m_maincpu->set_addrmap(AS_PROGRAM, &galaxia_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &galaxia_state::io_map);
m_maincpu->set_addrmap(AS_DATA, &galaxia_state::data_map);
@ -609,7 +614,7 @@ void galaxia_state::galaxia(machine_config &config)
void astrowar_state::astrowar(machine_config &config)
{
// basic machine hardware
S2650(config, m_maincpu, XTAL(14'318'181) / 8);
S2650(config, m_maincpu, 14.318181_MHz_XTAL / 8);
m_maincpu->set_addrmap(AS_PROGRAM, &astrowar_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &astrowar_state::io_map);
m_maincpu->set_addrmap(AS_DATA, &astrowar_state::data_map);

View File

@ -1,20 +1,20 @@
// license:BSD-3-Clause
// copyright-holders: Mike Coates, Pierpaolo Prazzoli
/************************************************************************
/*******************************************************************************
Zaccaria Quasar
Driver by Mike Coates and Pierpaolo Prazzoli
TODO:
- Sound (missing invader effect - still not sure all noise in correct places)
- Phase 3 - seems awfully hard - dip settings ?
- Hook up Coin Counter
- Test/Service Mode - not working?
- No attract demo? is this correct?
- Missing enemy shooting sound effect, needs netlist?
- Where is the flipscreen signal?
- Phase 3 seems awfully hard, or is it normal? Even with cheats enabled, it is
very hard to complete this level.
- Test/service input isn't working?
*************************************************************************
********************************************************************************
Quasar by Zaccaria (1980)
@ -26,11 +26,10 @@ Quasar by Zaccaria (1980)
I8085 Sound Board
************************************************************************/
*******************************************************************************/
#include "emu.h"
#include "cvs_base.h"
#include "cpu/mcs48/mcs48.h"
@ -45,6 +44,7 @@ class quasar_state : public cvs_base_state
public:
quasar_state(const machine_config &mconfig, device_type type, const char *tag)
: cvs_base_state(mconfig, type, tag)
, m_audiocpu(*this, "audiocpu")
, m_soundlatch(*this, "soundlatch")
, m_in(*this, "IN%u", 0U)
, m_dsw(*this, "DSW%u", 0U)
@ -53,12 +53,16 @@ public:
void quasar(machine_config &config) ATTR_COLD;
// sound test switch is tied to mcu interrupt pin
DECLARE_INPUT_CHANGED_MEMBER(soundtest_switch) { m_audiocpu->set_input_line(0, newval ? CLEAR_LINE : ASSERT_LINE); }
protected:
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
virtual void video_start() override ATTR_COLD;
private:
required_device<i8035_device> m_audiocpu;
required_device<generic_latch_8_device> m_soundlatch;
required_ioport_array<2> m_in;
@ -88,8 +92,27 @@ private:
void sound_portmap(address_map &map) ATTR_COLD;
};
void quasar_state::machine_start()
{
cvs_base_state::machine_start();
/***************************************************************************
// register state save
save_item(NAME(m_effectcontrol));
save_item(NAME(m_page));
save_item(NAME(m_io_page));
}
void quasar_state::machine_reset()
{
cvs_base_state::machine_reset();
m_effectcontrol = 0;
m_page = 0;
m_io_page = 8;
}
/*******************************************************************************
Zaccaria S2650 games share various levels of design with the Century Video
System (CVS) games, and hence some routines are shared from there.
@ -99,7 +122,7 @@ private:
Zaccaria are an Italian company, Century were based in Manchester UK
***************************************************************************/
*******************************************************************************/
void quasar_state::palette(palette_device &palette) const
{
@ -115,33 +138,29 @@ void quasar_state::palette(palette_device &palette) const
int bit0, bit1, bit2;
// red component
bit0 = BIT(i, 0);
bit1 = BIT(i, 1);
bit2 = BIT(i, 2);
bit0 = BIT(i, 7);
bit1 = BIT(i, 6);
bit2 = BIT(i, 5);
int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
// green component
bit0 = BIT(i, 3);
bit1 = BIT(i, 4);
bit2 = BIT(i, 5);
bit0 = BIT(i, 4);
bit1 = BIT(i, 3);
bit2 = BIT(i, 2);
int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
// blue component
bit0 = BIT(i, 6);
bit1 = BIT(i, 7);
int const b = 0x52 * bit0 + 0xad * bit1;
bit0 = BIT(i, 1);
bit1 = BIT(i, 0);
int const b = 0x4f * bit0 + 0xa8 * bit1;
// intensity 0
palette.set_indirect_color(0x100 + i, rgb_t::black());
// intensity 1
palette.set_indirect_color(0x200 + i, rgb_t(r >> 2, g >> 2, b >> 2));
// intensity 2
palette.set_indirect_color(0x300 + i, rgb_t((r >> 2) + (r >> 3), (g >> 2) + (g >> 3), (b >> 2) + (b >> 2)));
// intensity 3
palette.set_indirect_color(0x400 + i, rgb_t(r >> 1, g >> 1, b >> 1));
// 4 intensities
float level = 0.0f;
for (int j = 0; j < 4; j++)
{
palette.set_indirect_color(0x100 * (j + 1) + i, rgb_t(r * level, g * level, b * level));
level += 0.2f;
}
}
// Address 0-2 from graphic ROM
@ -181,7 +200,6 @@ uint32_t quasar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
// While we have the current character code, draw the effects layer
// intensity / on and off controlled by latch
int const forecolor = 0x208 + m_effectram[offs] + (256 * (((m_effectcontrol >> 4) ^ 3) & 3));
for (int ox = 0; ox < 8; ox++)
@ -195,7 +213,6 @@ uint32_t quasar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
0, 0,
x, y, 0);
// background for Collision Detection (it can only hit certain items)
if ((m_color_ram[offs] & 7) == 0)
{
@ -230,7 +247,6 @@ uint32_t quasar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
}
}
// mix and copy the S2636 images into the main bitmap, also check for collision
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
@ -260,15 +276,14 @@ uint32_t quasar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
}
/************************************************************************
/*******************************************************************************
Quasar memory layout
Paging for screen is controlled by OUT to 0,1,2 or 3
Paging for IO ports is controlled by OUT to 8,9,A or B
************************************************************************/
*******************************************************************************/
void quasar_state::video_page_select_w(offs_t offset, uint8_t data)
{
@ -278,6 +293,13 @@ void quasar_state::video_page_select_w(offs_t offset, uint8_t data)
void quasar_state::io_page_select_w(offs_t offset, uint8_t data)
{
m_io_page = offset & 0x03;
if (offset == 0)
{
// coincounters are here, they keep triggering if the coin is held active (hence the PORT_IMPULSE)
machine().bookkeeping().coin_counter_w(0, BIT(~data, 3));
machine().bookkeeping().coin_counter_w(1, BIT(~data, 2));
}
}
void quasar_state::video_w(offs_t offset, uint8_t data)
@ -308,28 +330,7 @@ uint8_t quasar_state::io_r()
void quasar_state::bullet_w(offs_t offset, uint8_t data)
{
m_bullet_ram[offset] = (data ^ 0xff);
}
void quasar_state::sh_command_w(uint8_t data)
{
// bit 4 = Sound Invader : Linked to an NE555V circuit
// Not handled yet
// lower nibble = command to I8035
// not necessarily like this, but it seems to work better than direct mapping
// (although schematics has it as direct - but then the schematics are wrong elsewhere to!)
m_soundlatch->write(bitswap<4>(data,3,0,2,1));
}
uint8_t quasar_state::sh_command_r()
{
return m_soundlatch->read() + (m_dsw[2]->read() & 0x30);
}
int quasar_state::audio_t1_r()
{
return m_soundlatch->read() == 0;
m_bullet_ram[offset] = data ^ 0xff;
}
// memory map taken from the manual
@ -360,11 +361,32 @@ void quasar_state::data(address_map &map)
map(S2650_DATA_PORT, S2650_DATA_PORT).rw(FUNC(quasar_state::collision_clear), FUNC(quasar_state::sh_command_w));
}
/*************************************
*
* Sound board memory handlers
*
*************************************/
/*******************************************************************************
Sound board memory handlers
*******************************************************************************/
void quasar_state::sh_command_w(uint8_t data)
{
// bit 4 = Sound Invader : Linked to an NE555V circuit
// Not handled yet
// lower nibble = command to I8035
m_soundlatch->write(data & 0xf);
}
uint8_t quasar_state::sh_command_r()
{
return m_soundlatch->read() | (m_dsw[2]->read() & 0x30);
}
int quasar_state::audio_t1_r()
{
// all 4 sound bits are NANDed together
return m_soundlatch->read() == 0;
}
void quasar_state::sound_map(address_map &map)
{
@ -377,104 +399,91 @@ void quasar_state::sound_portmap(address_map &map)
map(0x80, 0x80).r(FUNC(quasar_state::sh_command_r));
}
/************************************************************************
Inputs
/*******************************************************************************
************************************************************************/
Input Ports
*******************************************************************************/
static INPUT_PORTS_START( quasar )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(1)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) // test switch
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 ) // test switch?
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // table (from manual)
PORT_CONFNAME( 0x01, 0x01, DEF_STR( Cabinet ) )
PORT_CONFSETTING( 0x01, DEF_STR( Upright ) )
PORT_CONFSETTING( 0x00, DEF_STR( Cocktail ) )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // count enable (from manual)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // count enable (from manual)
PORT_START("DSW0")
PORT_DIPNAME( 0x0c, 0x04, DEF_STR( Coin_A ) ) // confirmed
PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_3C ) )
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_B ) ) // confirmed
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_5C ) )
PORT_DIPNAME( 0x30, 0x00, "Number of Rockets" ) // confirmed
PORT_DIPNAME( 0x0c, 0x04, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:3,4")
PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_3C ) )
PORT_DIPNAME( 0x30, 0x10, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:5,6")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x10, "4" )
PORT_DIPSETTING( 0x20, "5" )
PORT_DIPSETTING( 0x30, "6" )
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Free_Play ) ) // requires initial coin, but doesn't decrease coins on game over
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Free_Play ) ) PORT_DIPLOCATION("SW1:7") // requires initial coin, but doesn't decrease coins on game over
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x40, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Test Mode" ) // confirmed
PORT_DIPSETTING( 0x00, "Collisions excluded" )
PORT_DIPSETTING( 0x80, "Collisions included" )
PORT_DIPNAME( 0x80, 0x80, "Collision Detection" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START("DSW1")
PORT_DIPNAME( 0x07, 0x01, "High Score" )
PORT_DIPSETTING( 0x00, "No H.S." ) // this option only wants bit 0 OFF
PORT_DIPSETTING( 0x01, "Normal H.S." )
PORT_DIPSETTING( 0x03, "Low H.S." )
PORT_DIPSETTING( 0x05, "Medium H.S." )
PORT_DIPSETTING( 0x07, "High H.S." )
PORT_DIPNAME( 0x18, 0x10, DEF_STR( Difficulty ) )
PORT_DIPSETTING( 0x18, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x10, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x08, DEF_STR( Difficult ) )
PORT_DIPSETTING( 0x00, DEF_STR( Very_Difficult ) )
PORT_DIPNAME( 0x60, 0x20, "Extended Play" )
PORT_DIPSETTING( 0x20, "5500" ) // confirmed
PORT_DIPNAME( 0x01, 0x01, "High Score" ) PORT_DIPLOCATION("SW2:1")
PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x01, "Random" )
PORT_DIPNAME( 0x06, 0x04, "Random H.S." ) PORT_DIPLOCATION("SW2:2,3") // only if high score is set to random
PORT_DIPSETTING( 0x02, DEF_STR( Low ) )
PORT_DIPSETTING( 0x04, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x06, "Medium-High" )
PORT_DIPSETTING( 0x00, DEF_STR( High ) )
PORT_DIPNAME( 0x18, 0x08, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2: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( 0x60, 0x40, "Extended Play" ) PORT_DIPLOCATION("SW2:6,7")
PORT_DIPSETTING( 0x00, DEF_STR( None ) )
PORT_DIPSETTING( 0x20, "5500" )
PORT_DIPSETTING( 0x40, "7500" )
PORT_DIPSETTING( 0x60, "9500" )
PORT_DIPSETTING( 0x00, "17500" )
PORT_DIPNAME( 0x80, 0x80, "Full Screen Rocket" ) // confirmed
PORT_DIPSETTING( 0x80, "Stop at edge" )
PORT_DIPSETTING( 0x00, "Wrap Around" )
PORT_DIPNAME( 0x80, 0x80, "Rocket At Edge" ) PORT_DIPLOCATION("SW2:8") // only for phase 2 (the Asteroids style level)
PORT_DIPSETTING( 0x80, "Stop" )
PORT_DIPSETTING( 0x00, "Wrap" )
PORT_START("DSW2")
#if 0
PORT_DIPNAME( 0x0f, 0x00, "Noise to play" )
PORT_DIPSETTING( 0x00, "00" )
PORT_DIPSETTING( 0x01, "01" )
PORT_DIPSETTING( 0x02, "02" )
PORT_DIPSETTING( 0x03, "03" )
PORT_DIPSETTING( 0x04, "04" )
PORT_DIPSETTING( 0x05, "05" )
PORT_DIPSETTING( 0x06, "06" )
PORT_DIPSETTING( 0x07, "07" )
PORT_DIPSETTING( 0x08, "08" )
PORT_DIPSETTING( 0x09, "09" )
PORT_DIPSETTING( 0x0a, "0A" )
PORT_DIPSETTING( 0x0b, "0B" )
PORT_DIPSETTING( 0x0c, "0C" )
PORT_DIPSETTING( 0x0d, "0D" )
PORT_DIPSETTING( 0x0e, "0E" )
PORT_DIPSETTING( 0x0f, "0F" )
#endif
PORT_DIPNAME( 0x10, 0x10, "Sound Test" )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPNAME( 0x01, 0x01, "Sound Test" ) PORT_DIPLOCATION("SOUND:1") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(quasar_state::soundtest_switch), 0)
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x30, 0x20, "Sound Program" ) PORT_DIPLOCATION("SOUND:3,4")
PORT_DIPSETTING( 0x00, "Invalid 1" )
// PORT_DIPSETTING( 0x10, "Invalid 1" )
PORT_DIPSETTING( 0x30, "Invalid 2" )
PORT_DIPSETTING( 0x20, "Quasar" )
INPUT_PORTS_END
static const gfx_layout charlayout =
@ -494,47 +503,29 @@ static GFXDECODE_START( gfx_quasar )
GFXDECODE_ENTRY( "tiles", 0x0000, charlayout, 0, 64+1 )
GFXDECODE_END
// ****************************************
// Quasar S2650 Main CPU, I8035 sound board
// ****************************************
void quasar_state::machine_start()
{
cvs_base_state::machine_start();
/*******************************************************************************
// register state save
save_item(NAME(m_effectcontrol));
save_item(NAME(m_page));
save_item(NAME(m_io_page));
}
Machine Configuration
void quasar_state::machine_reset()
{
cvs_base_state::machine_reset();
m_effectcontrol = 0;
m_page = 0;
m_io_page = 8;
}
*******************************************************************************/
void quasar_state::quasar(machine_config &config)
{
// basic machine hardware
S2650(config, m_maincpu, 14'318'000 / 4); // 14 mhz crystal divide by 4 on board
S2650(config, m_maincpu, 14.318181_MHz_XTAL / 4); // 14.31818 MHz crystal divide by 4 on board
m_maincpu->set_addrmap(AS_PROGRAM, &quasar_state::program);
m_maincpu->set_addrmap(AS_IO, &quasar_state::io);
m_maincpu->set_addrmap(AS_DATA, &quasar_state::data);
m_maincpu->set_vblank_int("screen", FUNC(quasar_state::irq0_line_assert));
m_maincpu->sense_handler().set("screen", FUNC(screen_device::vblank));
m_maincpu->intack_handler().set([this]() { m_maincpu->set_input_line(0, CLEAR_LINE); return 0x03; });
m_maincpu->intack_handler().set([this]() { m_maincpu->set_input_line(0, CLEAR_LINE); return 0x0a; });
i8035_device &soundcpu(I8035(config, "soundcpu", 6'000'000)); // 6MHz crystal divide by 15 in CPU
soundcpu.set_addrmap(AS_PROGRAM, &quasar_state::sound_map);
soundcpu.set_addrmap(AS_IO, &quasar_state::sound_portmap);
soundcpu.t1_in_cb().set(FUNC(quasar_state::audio_t1_r));
soundcpu.p1_out_cb().set("dac", FUNC(dac_byte_interface::data_w));
config.set_maximum_quantum(attotime::from_hz(6000));
i8035_device &audiocpu(I8035(config, "audiocpu", 6_MHz_XTAL)); // 6 MHz crystal divide by 15 in CPU
audiocpu.set_addrmap(AS_PROGRAM, &quasar_state::sound_map);
audiocpu.set_addrmap(AS_IO, &quasar_state::sound_portmap);
audiocpu.t1_in_cb().set(FUNC(quasar_state::audio_t1_r));
audiocpu.p1_out_cb().set("dac", FUNC(dac_byte_interface::data_w));
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
@ -562,9 +553,16 @@ void quasar_state::quasar(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
SPEAKER(config, "speaker").front_center();
DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC
DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.5); // LM1408
}
/*******************************************************************************
ROM Definitions
*******************************************************************************/
ROM_START( quasar )
ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "7b_01.bin", 0x0000, 0x0400, CRC(20a7feaf) SHA1(ab89087efca2fcb9568f49ba117755ae2c1bd3a3) )
@ -583,7 +581,7 @@ ROM_START( quasar )
ROM_LOAD( "3c_09.bin", 0x2c00, 0x0400, CRC(ef87c2cb) SHA1(1ba10dd3996c047e595c54a37c1abb44df3b63c6) )
ROM_LOAD( "2c_10.bin", 0x3000, 0x0400, CRC(be6c4f84) SHA1(b3a779457bd0d33ccb23c21a7e7cd4a6fc78bb7f) )
ROM_REGION( 0x1000, "soundcpu", 0 )
ROM_REGION( 0x1000, "audiocpu", 0 )
ROM_LOAD( "quasar.snd", 0x0000, 0x0800, CRC(9e489768) SHA1(a9f01ef0a6512543bbdfec56037f37a0440b2b94) )
ROM_REGION( 0x1800, "tiles", 0 )
@ -613,7 +611,7 @@ ROM_START( quasara )
ROM_LOAD( "3c_09.bin", 0x2c00, 0x0400, CRC(ef87c2cb) SHA1(1ba10dd3996c047e595c54a37c1abb44df3b63c6) )
ROM_LOAD( "2c_10a.bin", 0x3000, 0x0400, CRC(a31c0435) SHA1(48e1c5da455610145310dfe4c6b6e4302b531876) ) // different from quasar set
ROM_REGION( 0x1000, "soundcpu", 0 )
ROM_REGION( 0x1000, "audiocpu", 0 )
ROM_LOAD( "quasar.snd", 0x0000, 0x0800, CRC(9e489768) SHA1(a9f01ef0a6512543bbdfec56037f37a0440b2b94) )
ROM_REGION( 0x1800, "tiles", 0 )
@ -628,5 +626,5 @@ ROM_END
} // anonymous namespace
GAME( 1980, quasar, 0, quasar, quasar, quasar_state, empty_init, ROT90, "Zaccaria / Zelco", "Quasar (set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, quasara, quasar, quasar, quasar, quasar_state, empty_init, ROT90, "Zaccaria / Zelco", "Quasar (set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, quasar, 0, quasar, quasar, quasar_state, empty_init, ROT90, "Zaccaria / Zelco", "Quasar (set 1)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1980, quasara, quasar, quasar, quasar, quasar_state, empty_init, ROT90, "Zaccaria / Zelco", "Quasar (set 2)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )