diff options
author | Tomasz Slanina <tomasz@slanina.pl> | 2017-01-21 22:07:17 +0100 |
---|---|---|
committer | Tomasz Slanina <tomasz@slanina.pl> | 2017-01-21 22:07:17 +0100 |
commit | 70897a5e5b3a3ff626245a3f5d3bd23fe581c02f (patch) | |
tree | d13695c36daea7f44a14b30b2e1be8f42a6f10f0 | |
parent | b500e53625f0df40b88211c718133a964a84d97a (diff) |
Machines promotes to working:
--------
Future Flash [Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen, Tomasz Slanina]
Laser Base (set 1) [Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen, Tomasz Slanina]
Laser Base (set 2) [Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen, Tomasz Slanina]
-rw-r--r-- | src/mame/drivers/laserbas.cpp | 404 |
1 files changed, 275 insertions, 129 deletions
diff --git a/src/mame/drivers/laserbas.cpp b/src/mame/drivers/laserbas.cpp index b612920396b..81303422ff9 100644 --- a/src/mame/drivers/laserbas.cpp +++ b/src/mame/drivers/laserbas.cpp @@ -1,22 +1,32 @@ // license:BSD-3-Clause -// copyright-holders:Tomasz Slanina +// copyright-holders: Tomasz Slanina, Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen + /******************************************** Laser Base / Future Flash driver - IC marked as Z1 is probably protection device - mapped in memory region f800-fbff - (similar to the one used in Parallel Turn) - - Reads form this device depends on previous - writes (adr, data), address and previous - operation (read or write). - Pinout is almost identical to 2716 - type EPROM, - except separated /RD and /WR signals and lacks - of /CS - - Tomasz Slanina analog [at] op.pl - ============================================ +TODO: +- Video: weird palette changes, Laserbase colors, missing bg scrolling between stages (CRT address lines + m_hset ( or m_vset ?)) +- Sound: sound related i/o writes ( out_w handler ) +- Interrupts - NMI/Int timing is wrong, it's based on measures of broken PCB +TS 20.01.2017 + +There's incomplete schematics available. It's missing a couple of important elements (analog sound, interrupts). +PCB contains big analog sound section, currently only partially emulated ( timers + counters + xors + dacs). There's many capacitors, +resistors and few ICs, including: + +7B LM2902N - Op Amps +4B LM2902N +2B LM2902N +1B LM2902N +6B LM1496N - Balanced Modulator-Demodulator +3B CA3080E - Op Amp +6C NE555P - Timer +4A NE555P - Timer +6A SN94560AN - ? a tone generator (similar to SN76477 ?) +3A MB84013B - Dual D flip-flop +2A MN3008 - 2048-stage long delay low noise BBD (reverb effect generator) +1C MB3712 - Power Amp. DASM notes: @@ -53,127 +63,180 @@ expected: 43 FB CC 9A D4 23 6C 01 3E <- From ROM 4 #include "cpu/z80/z80.h" #include "video/mc6845.h" #include "machine/pit8253.h" +#include "sound/dac.h" +#include "sound/volt_reg.h" class laserbas_state : public driver_device { public: laserbas_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_protram(*this, "protram"), - m_maincpu(*this, "maincpu") { } + m_maincpu(*this, "maincpu"), + m_palette(*this, "palette"), + m_dac1(*this, "dac1"), + m_dac2(*this, "dac2"), + m_dac3(*this, "dac3"), + m_dac4(*this, "dac4"), + m_dac5(*this, "dac5"), + m_dac6(*this, "dac6") + { } /* misc */ - int m_count; - + int m_dac_data; + int m_counter[6]; + int m_cnt_out[6]; + int m_nmi; /* video-related */ int m_vrambank; - uint8_t m_vram1[0x8000]; - uint8_t m_vram2[0x8000]; + uint8_t m_vram[0x10000]; + int m_hset, m_vset; + int m_bset; + int m_scl; bool m_flipscreen; - required_shared_ptr<uint8_t> m_protram; + uint16_t m_z1data[4]; + void write_pit_out(int num, int state); DECLARE_READ8_MEMBER(vram_r); DECLARE_WRITE8_MEMBER(vram_w); - DECLARE_WRITE8_MEMBER(vrambank_w); - DECLARE_READ8_MEMBER(protram_r); - DECLARE_WRITE8_MEMBER(protram_w); + DECLARE_WRITE8_MEMBER(videoctrl_w); + DECLARE_READ8_MEMBER(z1_r); DECLARE_READ8_MEMBER(track_lo_r); DECLARE_READ8_MEMBER(track_hi_r); DECLARE_WRITE8_MEMBER(out_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_0_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_1_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_2_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_3_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_4_w); + DECLARE_WRITE_LINE_MEMBER(pit_out_5_w); + TIMER_DEVICE_CALLBACK_MEMBER(laserbas_scanline); + MC6845_UPDATE_ROW(crtc_update_row); + virtual void machine_start() override; virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_laserbas(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + required_device<cpu_device> m_maincpu; + required_device<palette_device> m_palette; + required_device<dac_byte_interface> m_dac1; + required_device<dac_byte_interface> m_dac2; + required_device<dac_byte_interface> m_dac3; + required_device<dac_byte_interface> m_dac4; + required_device<dac_byte_interface> m_dac5; + required_device<dac_byte_interface> m_dac6; }; -void laserbas_state::video_start() +TIMER_DEVICE_CALLBACK_MEMBER( laserbas_state::laserbas_scanline ) { - save_item(NAME(m_vram1)); - save_item(NAME(m_vram2)); - save_item(NAME(m_flipscreen)); + int scanline = param; + + if(scanline == 0 || scanline == 135) + { + m_maincpu->set_input_line(0, HOLD_LINE ); + } + + if(scanline == 240 && m_nmi) + { + m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); + } } -uint32_t laserbas_state::screen_update_laserbas(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +MC6845_UPDATE_ROW( laserbas_state::crtc_update_row ) { - int x,y, x0,y0, x1,y1, delta; - + int x, x_max, dx, pixaddr; + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix32(y); + if (m_flipscreen) { - delta = -1; - x0 = 256-1; x1 = -1; - y0 = 256-1; y1 = -1; + y=0x100-y-1-0x20; + dx = -1; + x = 0x100-1; + x_max = -1; } else { - delta = 1; - x0 = 0; x1 = 256; - y0 = 0; y1 = 256; + dx = 1; + x = 0; + x_max = 0x100; } - int pixaddr = 0; - for (y = y0; y != y1; y += delta) + pixaddr=y<<8; + { - for (x = x0; x != x1; x += delta) + while ( x != x_max ) { - uint8_t p1 = m_vram1[pixaddr/2]; - uint8_t p2 = m_vram2[pixaddr/2]; - uint8_t mask = (pixaddr & 1) ? 0xf0 : 0x0f; - uint8_t shift = (pixaddr & 1) ? 4 : 0; + uint32_t offset = (pixaddr>>1)&0x7fff; + uint8_t p1 = m_vram[offset]; + uint8_t p2 = m_vram[offset+0x8000]; // 0x10000 VRAM, two 4 bit layers 0x8000 bytes each - if (p2 & mask) - bitmap.pix16(y, x) = (p2 & mask) >> shift; - else - bitmap.pix16(y, x) = ((p1 & mask) >> shift) + 16; + uint8_t shift = (pixaddr & 1)?4:0; // two 4 bit pixels in one byte + p1 = (p1>>shift) & 0xf; + p2 = (p2>>shift) & 0xf; - pixaddr++; + p[x] = palette[p2?:(p1?(p1+16):m_bset)]; // layer 2 | layer 1 | bg pen + + ++pixaddr; + x += dx; } } - - return 0; } READ8_MEMBER(laserbas_state::vram_r) { - if(!m_vrambank) - return m_vram1[offset]; - else - return m_vram2[offset]; + return m_vram[offset+(m_vrambank?0x8000:0)]; } WRITE8_MEMBER(laserbas_state::vram_w) { - if(!m_vrambank) - m_vram1[offset] = data; - else - m_vram2[offset] = data; + m_vram[offset+(m_vrambank?0x8000:0)] = data; } -#if 0 -READ8_MEMBER(laserbas_state::read_unk) +WRITE8_MEMBER(laserbas_state::videoctrl_w) { - m_count ^= 0x80; - return m_count | 0x7f; -} -#endif - -WRITE8_MEMBER(laserbas_state::vrambank_w) -{ - m_vrambank = data & 0x40; - m_flipscreen = !(data & 0x80); -} - -READ8_MEMBER(laserbas_state::protram_r) -{ - uint8_t prot = m_protram[offset]; -// prot = machine().rand(); -// logerror("%s: Z1 read %03x = %02x\n", machine().describe_context(), offset, prot); - return prot; + if(!(offset&1)) + { + m_vrambank = data & 0x40; // layer select + m_flipscreen = !(data & 0x80); + m_vset = (data>>3)&7; // inc-ed on interrupts ( 8 ints / frame ?) + m_hset = data&7; + } + else + { + data^=0xff; + m_bset = data>>4; // bg pen + m_scl = (data&8)>>3; // unknown + m_nmi=data&1; // nmi enable (not on schematics, traced) + } } -WRITE8_MEMBER(laserbas_state::protram_w) +READ8_MEMBER(laserbas_state::z1_r) { -// logerror("%s: Z1 write %03x = %02x\n", machine().describe_context(), offset, data); - m_protram[offset] = data; + uint8_t res = 0; + + m_z1data[0] = m_z1data[1]; + m_z1data[1] = m_z1data[2]; + m_z1data[2] = m_z1data[3]; + m_z1data[3] = offset; + +#define x(o) (1 & (m_z1data[o / 10] >> (o % 10))) +#define nx(o) (1 & ~(m_z1data[o / 10] >> (o % 10))) +#define MUX2(s, a, b) ((s) ? (a) : (b)) + + res = + MUX2(x(36) & x(33), x(31) ^ x(35), (nx(33) & (nx(20) | nx(36))) | (nx(36) & x(24))) << 7 + | MUX2(x(36), MUX2(x(33), x(29), nx(23) | x(30)), x(33) & x(15)) << 6 + | MUX2(x(36), nx(33) & x(27), x(32) | x(33)) << 5 + | MUX2(x(36), MUX2(x(33), nx(24), nx(35)), MUX2(nx(33), x(4), MUX2(nx(26), x(5) & x(23), MUX2(x(23), x(19), nx(13) | x(20))))) << 4 + | MUX2(x(36), x(33) & x(11), MUX2(x(33), x(25) | nx(31), x(24))) << 3 + | MUX2(x(33), MUX2(x(36), x(28), x(20)), MUX2(x(36), nx(11), nx(39))) << 2 + | MUX2(x(36), MUX2(x(23), MUX2(x(26), nx(18), nx(10)) | x(33), MUX2(x(26), x(1), x(29)) & nx(33)), MUX2(x(33), x(7), x(17))) << 1 + | MUX2(x(33), MUX2(x(36), x(22), nx(26)), MUX2(x(36), x(14), x(21))) << 0 + ; + +#undef MUX2 +#undef nx +#undef x + + return res; } READ8_MEMBER(laserbas_state::track_lo_r) @@ -181,29 +244,103 @@ READ8_MEMBER(laserbas_state::track_lo_r) uint8_t dx = ioport("TRACK_X")->read(); uint8_t dy = ioport("TRACK_Y")->read(); if (dx & 0x10) - dx ^= 0x0f; + dx ^= 0xf; if (dy & 0x10) dy ^= 0x0f; - return (dx & 0x0f) | ((dy & 0x0f) << 4); + int data = (dx & 0x0f) | ((dy & 0x0f) << 4); + return data; } + READ8_MEMBER(laserbas_state::track_hi_r) { - return ((ioport("TRACK_X")->read() & 0x10) >> 4) | ((ioport("TRACK_Y")->read() & 0x10) >> 3); + int data = ((ioport("TRACK_X")->read() & 0x10) >> 4) | ((ioport("TRACK_Y")->read() & 0x10) >> 3); + return data; } WRITE8_MEMBER(laserbas_state::out_w) { - static uint8_t out[4]; - out[offset] = data; - // port 20: mask 01 = service1, mask 02 = pulsed (no delay) waiting for start1, mask 08 = coin2, mask 40 = coin1 - popmessage("OUT 20: %02x %02x - %02x %02x", out[0], out[1], out[2], out[3]); + /* sound related , maybe also lamps */ +} + +void laserbas_state::machine_start() +{ + save_item(NAME(m_vram)); + save_item(NAME(m_flipscreen)); + save_item(NAME(m_vrambank)); + save_item(NAME(m_hset)); + save_item(NAME(m_vset)); + save_item(NAME(m_bset)); + save_item(NAME(m_scl)); + save_item(NAME(m_nmi)); + save_item(NAME(m_dac_data)); + save_item(NAME(m_counter)); + save_item(NAME(m_cnt_out)); + save_item(NAME(m_z1data)); +} + +void laserbas_state::machine_reset() +{ + m_vrambank = 0; + m_flipscreen = false; + m_nmi=0; + m_bset = 0; + m_hset = 0; + m_vset = 0; + m_scl = 0; +} + +void laserbas_state::write_pit_out(int num, int state) +{ + state^=1; // 7404 (6G) + if((!state)& m_cnt_out[num]){ // 0->1 rising edge CLK + m_counter[num] = (m_counter[num]+1)&0x0f; // 4 bit counters 74393 + } + int data =(state) | ((m_counter[num]&7)<<1); // combine output from 8253 with counter bits 0-3 + data<<=4; + if(m_counter[num]&8) data^=0x0f; // counter bit 4 xors the data ( 7486 x 6) + switch(num){ + case 0: m_dac1->write(data);break; // 4 resistor packs : 47k, 100k, 220k, 470k + case 1: m_dac2->write(data);break; + case 2: m_dac3->write(data);break; + case 3: m_dac4->write(data);break; + case 4: m_dac5->write(data);break; + case 5: m_dac6->write(data);break; + } + + m_cnt_out[num]=state; +} + +WRITE_LINE_MEMBER(laserbas_state::pit_out_0_w) +{ + write_pit_out(0,state); +} + +WRITE_LINE_MEMBER(laserbas_state::pit_out_1_w) +{ + write_pit_out(1,state); +} +WRITE_LINE_MEMBER(laserbas_state::pit_out_2_w) +{ + write_pit_out(2,state); +} +WRITE_LINE_MEMBER(laserbas_state::pit_out_3_w) +{ + write_pit_out(3,state); +} +WRITE_LINE_MEMBER(laserbas_state::pit_out_4_w) +{ + write_pit_out(4,state); +} +WRITE_LINE_MEMBER(laserbas_state::pit_out_5_w) +{ + write_pit_out(5,state); } static ADDRESS_MAP_START( laserbas_memory, AS_PROGRAM, 8, laserbas_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0xbfff) AM_READWRITE(vram_r, vram_w) - AM_RANGE(0xc000, 0xf7ff) AM_ROM - AM_RANGE(0xf800, 0xfbff) AM_READWRITE(protram_r, protram_w) AM_SHARE("protram") /* protection device */ + AM_RANGE(0xc000, 0xf7ff) AM_ROM AM_WRITENOP + AM_RANGE(0xf800, 0xfbff) AM_READ(z1_r) AM_WRITENOP /* protection device */ AM_RANGE(0xfc00, 0xffff) AM_RAM ADDRESS_MAP_END @@ -211,11 +348,11 @@ static ADDRESS_MAP_START( laserbas_io, AS_IO, 8, laserbas_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x00) AM_DEVWRITE("crtc", mc6845_device, address_w) AM_RANGE(0x01, 0x01) AM_DEVWRITE("crtc", mc6845_device, register_w) - AM_RANGE(0x10, 0x10) AM_WRITE(vrambank_w) + AM_RANGE(0x10, 0x11) AM_WRITE(videoctrl_w) AM_RANGE(0x20, 0x20) AM_READ_PORT("DSW") AM_RANGE(0x21, 0x21) AM_READ_PORT("INPUTS") AM_RANGE(0x22, 0x22) AM_READ(track_hi_r) - AM_RANGE(0x23, 0x23) AM_READ(track_lo_r) // AM_WRITE(test_w) + AM_RANGE(0x23, 0x23) AM_READ(track_lo_r) AM_RANGE(0x20, 0x23) AM_WRITE(out_w) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("pit0", pit8253_device, read, write) AM_RANGE(0x44, 0x47) AM_DEVREADWRITE("pit1", pit8253_device, read, write) @@ -234,8 +371,8 @@ static INPUT_PORTS_START( laserbas ) PORT_DIPSETTING( 0x04, "10k" ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) PORT_DIPSETTING( 0x00, "30k" ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) PORT_DIPNAME( 0x08, 0x08, DEF_STR( Demo_Sounds ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_B ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) PORT_DIPSETTING( 0x10, DEF_STR( 3C_1C ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) PORT_DIPSETTING( 0x20, DEF_STR( 2C_1C ) ) PORT_CONDITION("INPUTS", 0x20, EQUALS, 0x20) @@ -259,7 +396,7 @@ static INPUT_PORTS_START( laserbas ) PORT_START("INPUTS") // $21 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_PLAYER(2) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 ) @@ -268,58 +405,67 @@ static INPUT_PORTS_START( laserbas ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 ) // service coin PORT_START("TRACK_X") - PORT_BIT( 0x1f, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(10) PORT_KEYDELTA(1) PORT_RESET + PORT_BIT( 0x01f, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_RESET PORT_START("TRACK_Y") - PORT_BIT( 0x1f, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(10) PORT_KEYDELTA(1) PORT_RESET PORT_REVERSE + PORT_BIT( 0x01f, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_RESET PORT_REVERSE INPUT_PORTS_END -void laserbas_state::machine_start() -{ - save_item(NAME(m_vrambank)); - save_item(NAME(m_count)); -} - -void laserbas_state::machine_reset() -{ - m_vrambank = 0; - m_flipscreen = false; - m_count = 0; -} +#define CLOCK 16680000 +#define PIT_CLOCK (CLOCK/16) // 12 divider ? static MACHINE_CONFIG_START( laserbas, laserbas_state ) - MCFG_CPU_ADD("maincpu", Z80, 4000000) + MCFG_CPU_ADD("maincpu", Z80, CLOCK*4) MCFG_CPU_PROGRAM_MAP(laserbas_memory) MCFG_CPU_IO_MAP(laserbas_io) - MCFG_CPU_VBLANK_INT_DRIVER("screen", laserbas_state, irq0_line_hold) -// MCFG_TIMER_DRIVER_ADD_PERIODIC("nmi", laserbas_state, nmi_line_pulse, attotime::from_hz(60)) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", laserbas_state, laserbas_scanline, "screen", 0, 1) /* TODO: clocks aren't known */ MCFG_DEVICE_ADD("pit0", PIT8253, 0) - MCFG_PIT8253_CLK0(31250) - MCFG_PIT8253_CLK1(31250) - MCFG_PIT8253_CLK2(31250) + MCFG_PIT8253_CLK0(PIT_CLOCK) + MCFG_PIT8253_CLK1(PIT_CLOCK) + MCFG_PIT8253_CLK2(PIT_CLOCK) + MCFG_PIT8253_OUT0_HANDLER(WRITELINE(laserbas_state, pit_out_0_w)) + MCFG_PIT8253_OUT1_HANDLER(WRITELINE(laserbas_state, pit_out_1_w)) + MCFG_PIT8253_OUT2_HANDLER(WRITELINE(laserbas_state, pit_out_2_w)) MCFG_DEVICE_ADD("pit1", PIT8253, 0) - MCFG_PIT8253_CLK0(31250) - MCFG_PIT8253_CLK1(31250) - MCFG_PIT8253_CLK2(31250) + MCFG_PIT8253_CLK0(PIT_CLOCK) + MCFG_PIT8253_CLK1(PIT_CLOCK) + MCFG_PIT8253_CLK2(PIT_CLOCK) + MCFG_PIT8253_OUT0_HANDLER(WRITELINE(laserbas_state, pit_out_3_w)) + MCFG_PIT8253_OUT1_HANDLER(WRITELINE(laserbas_state, pit_out_4_w)) + MCFG_PIT8253_OUT2_HANDLER(WRITELINE(laserbas_state, pit_out_5_w)) MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) - MCFG_SCREEN_UPDATE_DRIVER(laserbas_state, screen_update_laserbas) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_RAW_PARAMS(4000000, 256, 0, 256, 256, 0, 256) /* temporary, CRTC will configure screen */ + MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) MCFG_MC6845_ADD("crtc", H46505, "screen", 3000000/4) /* unknown clock, hand tuned to get ~60 fps */ MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(8) + MCFG_MC6845_UPDATE_ROW_CB(laserbas_state, crtc_update_row) MCFG_PALETTE_ADD("palette", 32) MCFG_PALETTE_FORMAT(RRRGGGBB) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("speaker") + MCFG_SOUND_ADD("dac1", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_SOUND_ADD("dac2", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_SOUND_ADD("dac3", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_SOUND_ADD("dac4", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_SOUND_ADD("dac5", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_SOUND_ADD("dac6", DAC_4BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.16) + MCFG_DEVICE_ADD("vref", VOLTAGE_REGULATOR, 0) MCFG_VOLTAGE_REGULATOR_OUTPUT(5.0) + MCFG_SOUND_ROUTE_EX(0, "dac1", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac1", -1.0, DAC_VREF_NEG_INPUT) + MCFG_SOUND_ROUTE_EX(0, "dac2", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac2", -1.0, DAC_VREF_NEG_INPUT) + MCFG_SOUND_ROUTE_EX(0, "dac3", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac3", -1.0, DAC_VREF_NEG_INPUT) + MCFG_SOUND_ROUTE_EX(0, "dac4", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac4", -1.0, DAC_VREF_NEG_INPUT) + MCFG_SOUND_ROUTE_EX(0, "dac5", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac5", -1.0, DAC_VREF_NEG_INPUT) + MCFG_SOUND_ROUTE_EX(0, "dac6", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac6", -1.0, DAC_VREF_NEG_INPUT) + MACHINE_CONFIG_END /* @@ -410,6 +556,6 @@ ROM_START( futflash ) ROM_LOAD( "ff.8", 0xf000, 0x0800, CRC(623f558f) SHA1(be6c6565df658555f21c43a8c2459cf399794a84) ) ROM_END -GAME( 1981, laserbas, 0, laserbas, laserbas, driver_device, 0, ROT270, "Hoei (Amstar license)", "Laser Base (set 1)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -GAME( 1981, laserbasa,laserbas, laserbas, laserbas, driver_device, 0, ROT270, "Hoei (Amstar license)", "Laser Base (set 2)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -GAME( 1981, futflash, laserbas, laserbas, laserbas, driver_device, 0, ROT270, "Hoei", "Future Flash", MACHINE_NO_SOUND | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, futflash, 0, laserbas, laserbas, driver_device, 0, ROT270, "Hoei", "Future Flash", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1981, laserbas, futflash, laserbas, laserbas, driver_device, 0, ROT270, "Hoei (Amstar license)", "Laser Base (set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1981, laserbasa,futflash, laserbas, laserbas, driver_device, 0, ROT270, "Hoei (Amstar license)", "Laser Base (set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) |