From a4b4ef9af8a93dcfe21dcab3cc2e603189b24f58 Mon Sep 17 00:00:00 2001 From: hap Date: Wed, 1 Jan 2025 20:48:58 +0100 Subject: scyclone: small cleanup (no functional changes), konamim2: clarify gun switch --- src/mame/konami/konamim2.cpp | 9 +- src/mame/taito/scyclone.cpp | 478 ++++++++++++++++++++++++------------------- 2 files changed, 275 insertions(+), 212 deletions(-) diff --git a/src/mame/konami/konamim2.cpp b/src/mame/konami/konamim2.cpp index 10449202150..6cfb2cd5c5d 100644 --- a/src/mame/konami/konamim2.cpp +++ b/src/mame/konami/konamim2.cpp @@ -288,7 +288,7 @@ public: void init_btltryst(); void init_hellngt(); - template ioport_value evilngt_aim_up() { return m_guny[N]->read() ? 0 : 1; } + template ioport_value evilngt_aim_up(); protected: virtual void machine_start() override ATTR_COLD; @@ -425,6 +425,13 @@ void konamim2_state::ata_int(int state) * *************************************/ +template +ioport_value konamim2_state::evilngt_aim_up() +{ + // when P1/P3 gun is aimed up, it triggers a mercury switch inside the gun + return (m_guny[N]->read() > 0) ? 0 : 1; +} + uint16_t konamim2_state::konami_io0_r(offs_t offset) { // printf("IO R: %08X\n", offset); diff --git a/src/mame/taito/scyclone.cpp b/src/mame/taito/scyclone.cpp index 34d5326c53d..02f4345f915 100644 --- a/src/mame/taito/scyclone.cpp +++ b/src/mame/taito/scyclone.cpp @@ -59,10 +59,13 @@ public: scyclone_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_subcpu(*this, "subcpu"), m_gfxdecode(*this, "gfxdecode"), m_stars(*this, "stars"), m_gfx1pal(*this, "gfx1pal"), m_palette(*this, "palette"), + m_snsnd(*this, "snsnd%u", 0), + m_dac(*this, "dac%u", 0), m_soundlatch(*this, "soundlatch") { } @@ -70,47 +73,32 @@ public: int collision_r(); -private: - void vidctrl_w(uint8_t data); - - void sprite_xpos_w(uint8_t data); - void sprite_ypos_w(uint8_t data); - void sprite_colour_w(uint8_t data); - void sprite_tile_w(uint8_t data); - void starscroll_w(uint8_t data); - void port0e_w(uint8_t data); - void port06_w(uint8_t data); - void videomask1_w(uint8_t data); - void videomask2_w(uint8_t data); - void vram_w(offs_t offset, uint8_t data); - uint8_t vram_r(offs_t offset); - void snd_3001_w(uint8_t data); -// void snd_3003_w(uint8_t data); -// void snd_3004_w(uint8_t data); - void snd_3005_w(uint8_t data); - - uint32_t screen_update_scyclone(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - INTERRUPT_GEN_MEMBER(irq); - - - void scyclone_iomap(address_map &map) ATTR_COLD; - void scyclone_map(address_map &map) ATTR_COLD; - void scyclone_sub_iomap(address_map &map) ATTR_COLD; - void scyclone_sub_map(address_map &map) ATTR_COLD; - +protected: virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; virtual void video_start() override ATTR_COLD; +private: + // devices required_device m_maincpu; + required_device m_subcpu; required_device m_gfxdecode; required_region_ptr m_stars; required_region_ptr m_gfx1pal; required_device m_palette; + required_device_array m_snsnd; + required_device_array m_dac; required_device m_soundlatch; - /* memory pointers */ + void scyclone_iomap(address_map &map) ATTR_COLD; + void scyclone_map(address_map &map) ATTR_COLD; + void scyclone_sub_iomap(address_map &map) ATTR_COLD; + void scyclone_sub_map(address_map &map) ATTR_COLD; + + INTERRUPT_GEN_MEMBER(main_irq); + INTERRUPT_GEN_MEMBER(sound_irq); + + // video-related std::unique_ptr m_vram; uint8_t m_videowritemask = 0; @@ -126,18 +114,38 @@ private: uint8_t m_hascollided = 0; - /* video-related */ const uint8_t get_sprite_pixel(int x, int y); const uint8_t get_bitmap_pixel(int x, int y); uint32_t draw_starfield(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t draw_bitmap_and_sprite(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + uint32_t screen_update_scyclone(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void vidctrl_w(uint8_t data); + void sprite_xpos_w(uint8_t data); + void sprite_ypos_w(uint8_t data); + void sprite_colour_w(uint8_t data); + void sprite_tile_w(uint8_t data); + void starscroll_w(uint8_t data); + void port0e_w(uint8_t data); + void port06_w(uint8_t data); + void videomask1_w(uint8_t data); + void videomask2_w(uint8_t data); + void vram_w(offs_t offset, uint8_t data); + uint8_t vram_r(offs_t offset); + + // sound related + void snd_3001_w(uint8_t data); + void snd_3003_w(uint8_t data); + void snd_3004_w(uint8_t data); + void snd_3005_w(uint8_t data); }; /*************************************************************************** - Start the video hardware emulation. + Video hardware ***************************************************************************/ @@ -146,9 +154,6 @@ void scyclone_state::video_start() m_vram = std::make_unique(0x3800*3); save_pointer(&m_vram[0], "m_vram", 0x3800*3); - m_videowritemask = 0x00; - m_videowritemask2 = 0x00; - for (int i = 0; i < 8; i++) m_palette->set_pen_color(i, rgb_t(pal1bit(i >> 0), pal1bit(i >> 1), pal1bit(i >> 2))); @@ -161,15 +166,15 @@ void scyclone_state::video_start() const uint8_t scyclone_state::get_sprite_pixel(int x, int y) { - int minx = 0xe0-m_sprite_xpos; - int miny = 0xe0-m_sprite_ypos; + int minx = 0xe0 - m_sprite_xpos; + int miny = 0xe0 - m_sprite_ypos; int col = m_sprite_colour & 3; int code = m_sprite_tile & 7; int maxx = minx + 32; int maxy = miny + 32; - /* if we're not even inside the sprite, return nothing */ + // if we're not even inside the sprite, return nothing if (x < minx || x >= maxx) return 0; @@ -181,7 +186,7 @@ const uint8_t scyclone_state::get_sprite_pixel(int x, int y) const uint8_t* srcdata = m_gfxdecode->gfx(0)->get_data(code); - uint8_t pix = srcdata[spry*32 + sprx] + col*4; + uint8_t pix = srcdata[spry * 32 + sprx] + col * 4; return pix; } @@ -189,9 +194,9 @@ const uint8_t scyclone_state::get_sprite_pixel(int x, int y) const uint8_t scyclone_state::get_bitmap_pixel(int x, int y) { - const uint8_t video_data0 = m_vram[(y*32+(x/8))]; - const uint8_t video_data1 = m_vram[(y*32+(x/8))+0x3800]; - const uint8_t video_data2 = m_vram[(y*32+(x/8))+0x3800+0x3800]; + const uint8_t video_data0 = m_vram[(y * 32 + (x / 8))]; + const uint8_t video_data1 = m_vram[(y * 32 + (x / 8)) + 0x3800]; + const uint8_t video_data2 = m_vram[(y * 32 + (x / 8)) + 0x3800 + 0x3800]; int const bit(x & 0x07); @@ -199,7 +204,7 @@ const uint8_t scyclone_state::get_bitmap_pixel(int x, int y) const uint8_t plane1(BIT(video_data1, bit)); const uint8_t plane2(BIT(video_data2, bit)); - const uint8_t pal = plane0 | (plane1<<1) | (plane2<<2); + const uint8_t pal = plane0 | (plane1 << 1) | (plane2 << 2); return pal; } @@ -208,23 +213,21 @@ uint32_t scyclone_state::draw_starfield(screen_device &screen, bitmap_rgb32 &bit { const pen_t *paldata = m_palette->pens(); - // this is not correct, but the first 0x80 bytes of the PROM are blank suggesting that this - // part is for the non-visible 32 rows at least, so it should be something like this - // blinking and colours are not understood at all - - + // This is not correct, but the first 0x80 bytes of the PROM are blank suggesting that this + // part is for the non-visible 32 rows at least, so it should be something like this. + // Blinking and colours are not understood at all. - for (int strip=0;strip<16;strip++) + for (int strip = 0; strip < 16; strip++) { - for (int x=0;x<256;x++) + for (int x = 0; x < 256; x++) { - const uint8_t star = m_stars[((x+m_starscroll) & 0x3f)+(strip*0x40)]; + const uint8_t star = m_stars[((x + m_starscroll) & 0x3f) + (strip * 0x40)]; - for (int y=0;y<16;y++) + for (int y = 0; y < 16; y++) { - const int ypos = (y+16*strip)-32; + const int ypos = (y + 16 * strip) - 32; - if (ypos>=0 && ypos<256) + if (ypos >= 0 && ypos < 256) { int noclipped = 0; @@ -233,7 +236,6 @@ uint32_t scyclone_state::draw_starfield(screen_device &screen, bitmap_rgb32 &bit else noclipped = x >= 64; - if (y == star && star != 0 && noclipped) bitmap.pix(ypos, x) = paldata[7]; else @@ -251,19 +253,19 @@ uint32_t scyclone_state::draw_bitmap_and_sprite(screen_device &screen, bitmap_rg const pen_t *paldata = m_palette->pens(); m_hascollided = 0; - for (int y=0;y<256-32;y++) + for (int y = 0; y < 256-32; y++) { - for (int x=0;x<256/8;x++) + for (int x = 0; x < 256/8; x++) { - for (int i=0;i<8;i++) + for (int i = 0; i < 8; i++) { int realx = 0; int realy = 0; if (m_vidctrl & 0x08) { - realx = 255 - ((x*8)+i); - realy = 255-32-y; + realx = 255 - ((x*8) + i); + realy = 255 - 32 - y; } else { @@ -271,16 +273,15 @@ uint32_t scyclone_state::draw_bitmap_and_sprite(screen_device &screen, bitmap_rg realy = y; } - uint8_t pal = get_bitmap_pixel(realx, realy); - if (pal) bitmap.pix(y, (x*8)+i) = paldata[pal]; + if (pal) bitmap.pix(y, (x*8) + i) = paldata[pal]; uint8_t pal2 = get_sprite_pixel(realx, realy); if (pal2 & 0x3) { - bitmap.pix(y, (x*8)+i) = paldata[8+pal2]; + bitmap.pix(y, (x*8) + i) = paldata[8 + pal2]; if (pal == 0x7) m_hascollided = 1; } } @@ -302,113 +303,16 @@ uint32_t scyclone_state::screen_update_scyclone(screen_device &screen, bitmap_rg } - -void scyclone_state::scyclone_map(address_map &map) -{ - map(0x0000, 0x2fff).rom(); - map(0x4000, 0x43ff).ram(); - map(0x4400, 0x5fff).rw(FUNC(scyclone_state::vram_r), FUNC(scyclone_state::vram_w)); - map(0x6000, 0x60ff).noprw(); // this just seems to be overflow from the VRAM writes, probably goes nowhere -} - - -void scyclone_state::scyclone_iomap(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x00).r("mb14241", FUNC(mb14241_device::shift_result_r)).w("mb14241", FUNC(mb14241_device::shift_count_w)); - map(0x01, 0x01).portr("IN0").w("mb14241", FUNC(mb14241_device::shift_data_w)); - map(0x02, 0x02).portr("IN1"); - map(0x03, 0x03).portr("DSW0").w(FUNC(scyclone_state::vidctrl_w)); - map(0x04, 0x04).w(FUNC(scyclone_state::sprite_xpos_w)); - map(0x05, 0x05).w(FUNC(scyclone_state::sprite_ypos_w)); - map(0x06, 0x06).w(FUNC(scyclone_state::port06_w)); // possible watchdog, unlikely to be twinkle related. - map(0x08, 0x08).w(FUNC(scyclone_state::sprite_colour_w)); - map(0x09, 0x09).w(FUNC(scyclone_state::sprite_tile_w)); - map(0x0a, 0x0a).w(FUNC(scyclone_state::starscroll_w)); - map(0x0e, 0x0e).w(FUNC(scyclone_state::port0e_w)); - map(0x0f, 0x0f).w(m_soundlatch, FUNC(generic_latch_8_device::write)); - map(0x40, 0x40).w(FUNC(scyclone_state::videomask1_w)); - map(0x80, 0x80).w(FUNC(scyclone_state::videomask2_w)); -} - - -void scyclone_state::scyclone_sub_map(address_map &map) -{ - map(0x0000, 0x1fff).rom(); - map(0x2000, 0x23ff).ram(); - - map(0x3000, 0x3000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w("dac", FUNC(dac_byte_interface::data_w)); // music - map(0x3001, 0x3001).w(FUNC(scyclone_state::snd_3001_w)); // written at the same time, with the same data as 0x3005 - map(0x3002, 0x3002).w("dac2", FUNC(dac_byte_interface::data_w)); // speech -// map(0x3003, 0x3003).w(FUNC(scyclone_state::snd_3003_w)); // writes 02 or 00 -// map(0x3004, 0x3004).w(FUNC(scyclone_state::snd_3004_w)); // always writes 00? - map(0x3005, 0x3005).w(FUNC(scyclone_state::snd_3005_w)); // written at the same time, with the same data as 0x3001 -} - -void scyclone_state::scyclone_sub_iomap(address_map &map) -{ - map.global_mask(0xff); -} - - -// appears to be when a white bitmap pixel (col 0x7) collides with a large sprite? -// if you simply set it to 1 and shoot in the left corner, the game gets stuck -// but if you have it set to 0 there are no collisions with large objects -int scyclone_state::collision_r() -{ - return m_hascollided; -} - - -static INPUT_PORTS_START( scyclone ) - PORT_START("IN0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_TILT ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY - - PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(FUNC(scyclone_state::collision_r)) // hw collision? - // maybe these 4 are the 4xdsw bank? - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL PORT_CONDITION("DSW0",0x04,EQUALS,0x00) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_COCKTAIL PORT_CONDITION("DSW0",0x04,EQUALS,0x00) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_COCKTAIL PORT_CONDITION("DSW0",0x04,EQUALS,0x00) - - PORT_START("DSW0") - PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("DSW0:1,2") - PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPSETTING( 0x01, "3" ) - PORT_DIPSETTING( 0x02, "4" ) - PORT_DIPSETTING( 0x03, "5" ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("DSW0:3") - PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) - PORT_DIPSETTING( 0x04, DEF_STR( Upright ) ) - PORT_DIPNAME( 0x08, 0x00, "Disable Collision (Buggy!)" ) PORT_DIPLOCATION("DSW0:4") // this causes the game to malfunction, likely leftover debug feature - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, "Show Copyright Date" ) PORT_DIPLOCATION("DSW0:5") - PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "DSW0:6" ) - PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "DSW0:7" ) - PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "DSW0:8" ) -INPUT_PORTS_END +// Memory handlers uint8_t scyclone_state::vram_r(offs_t offset) { uint8_t ret = 0; + // not sure, collisions depend on readback ret |= m_vram[offset]; - ret |= m_vram[offset+0x3800]; - ret |= m_vram[offset+0x3800+0x3800]; + ret |= m_vram[offset + 0x3800]; + ret |= m_vram[offset + 0x3800 + 0x3800]; return ret; } @@ -421,12 +325,12 @@ void scyclone_state::vram_w(offs_t offset, uint8_t data) // this is used when drawing the pointing stick, need closeup reference // 0x40 and 0x80 ports always seem equal tho - if ((m_videowritemask & 0xf) != ((m_videowritemask>>4) & 0xf)) + if ((m_videowritemask & 0xf) != ((m_videowritemask >> 4) & 0xf)) { logerror("m_videowritemask halves not equal %02x\n", m_videowritemask); } - if ((m_videowritemask2 & 0xf) != ((m_videowritemask2>>4) & 0xf)) + if ((m_videowritemask2 & 0xf) != ((m_videowritemask2 >> 4) & 0xf)) { logerror("m_videowritemask2 halves not equal %02x\n", m_videowritemask2); } @@ -437,27 +341,26 @@ void scyclone_state::vram_w(offs_t offset, uint8_t data) } #endif - - for (int i=0; i<8; i++) + for (int i = 0; i < 8; i++) { - const uint8_t databit = data & (1<=6) videowritemask = (m_videowritemask>>4) & 0x0f; - else if (i>=4) videowritemask = (m_videowritemask>>0) & 0x0f; - else if (i>=2) videowritemask = (m_videowritemask2>>4) & 0x0f; - else videowritemask = (m_videowritemask2>>0) & 0x0f; + if (i >= 6) videowritemask = (m_videowritemask >> 4) & 0x0f; + else if (i >= 4) videowritemask = (m_videowritemask >> 0) & 0x0f; + else if (i >= 2) videowritemask = (m_videowritemask2 >> 4) & 0x0f; + else videowritemask = (m_videowritemask2 >> 0) & 0x0f; if (!(videowritemask & 1) && databit) m_vram[offset] |= databit; else m_vram[offset] &= ~nodatabit; - if (!(videowritemask & 2) && databit) m_vram[offset+0x3800] |= databit; - else m_vram[offset+0x3800] &= ~nodatabit; + if (!(videowritemask & 2) && databit) m_vram[offset + 0x3800] |= databit; + else m_vram[offset + 0x3800] &= ~nodatabit; - if (!(videowritemask & 4) && databit) m_vram[offset+0x3800+0x3800] |= databit; - else m_vram[offset+0x3800+0x3800] &= ~nodatabit; + if (!(videowritemask & 4) && databit) m_vram[offset + 0x3800 + 0x3800] |= databit; + else m_vram[offset + 0x3800 + 0x3800] &= ~nodatabit; } } @@ -528,7 +431,22 @@ void scyclone_state::videomask2_w(uint8_t data) m_videowritemask2 = data; } -// Sound CPU handlers + +int scyclone_state::collision_r() +{ + // Appears to be when a white bitmap pixel (col 0x7) collides with a large sprite? + // If you simply set it to 1 and shoot in the left corner, the game gets stuck, + // but if you have it set to 0 there are no collisions with large objects. + return m_hascollided; +} + + + +/*************************************************************************** + + Sound hardware + +***************************************************************************/ void scyclone_state::snd_3001_w(uint8_t data) { @@ -538,32 +456,156 @@ void scyclone_state::snd_3001_w(uint8_t data) m_soundlatch->clear_w(); } -/* void scyclone_state::snd_3003_w(uint8_t data) { -// m_soundlatch->clear_w(); } void scyclone_state::snd_3004_w(uint8_t data) { -// m_soundlatch->clear_w(); + // always writes 00? } -*/ void scyclone_state::snd_3005_w(uint8_t data) { -// m_soundlatch->clear_w(); + // written at the same time, with the same data as 0x3001 +} + +INTERRUPT_GEN_MEMBER(scyclone_state::sound_irq) +{ + m_subcpu->set_input_line(0, HOLD_LINE); +} + + + +/*************************************************************************** + + Address maps + +***************************************************************************/ + +void scyclone_state::scyclone_map(address_map &map) +{ + map(0x0000, 0x2fff).rom(); + map(0x4000, 0x43ff).ram(); + map(0x4400, 0x5fff).rw(FUNC(scyclone_state::vram_r), FUNC(scyclone_state::vram_w)); + map(0x6000, 0x60ff).noprw(); // this just seems to be overflow from the VRAM writes, probably goes nowhere } +void scyclone_state::scyclone_iomap(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x00).r("mb14241", FUNC(mb14241_device::shift_result_r)).w("mb14241", FUNC(mb14241_device::shift_count_w)); + map(0x01, 0x01).portr("IN0").w("mb14241", FUNC(mb14241_device::shift_data_w)); + map(0x02, 0x02).portr("IN1"); + map(0x03, 0x03).portr("DSW0").w(FUNC(scyclone_state::vidctrl_w)); + map(0x04, 0x04).w(FUNC(scyclone_state::sprite_xpos_w)); + map(0x05, 0x05).w(FUNC(scyclone_state::sprite_ypos_w)); + map(0x06, 0x06).w(FUNC(scyclone_state::port06_w)); // possible watchdog, unlikely to be twinkle related. + map(0x08, 0x08).w(FUNC(scyclone_state::sprite_colour_w)); + map(0x09, 0x09).w(FUNC(scyclone_state::sprite_tile_w)); + map(0x0a, 0x0a).w(FUNC(scyclone_state::starscroll_w)); + map(0x0e, 0x0e).w(FUNC(scyclone_state::port0e_w)); + map(0x0f, 0x0f).w(m_soundlatch, FUNC(generic_latch_8_device::write)); + map(0x40, 0x40).w(FUNC(scyclone_state::videomask1_w)); + map(0x80, 0x80).w(FUNC(scyclone_state::videomask2_w)); +} + + +void scyclone_state::scyclone_sub_map(address_map &map) +{ + map(0x0000, 0x1fff).rom(); + map(0x2000, 0x23ff).ram(); + + map(0x3000, 0x3000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w(m_dac[0], FUNC(dac_byte_interface::data_w)); // music + map(0x3001, 0x3001).w(FUNC(scyclone_state::snd_3001_w)); + map(0x3002, 0x3002).w(m_dac[1], FUNC(dac_byte_interface::data_w)); // speech + map(0x3003, 0x3003).w(FUNC(scyclone_state::snd_3003_w)); + map(0x3004, 0x3004).w(FUNC(scyclone_state::snd_3004_w)); + map(0x3005, 0x3005).w(FUNC(scyclone_state::snd_3005_w)); +} + +void scyclone_state::scyclone_sub_iomap(address_map &map) +{ + map.global_mask(0xff); +} + + + +/*************************************************************************** + + Input ports + +***************************************************************************/ + +static INPUT_PORTS_START( scyclone ) + PORT_START("IN0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_TILT ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY + + PORT_START("IN1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(FUNC(scyclone_state::collision_r)) // hw collision? + // maybe these 4 are the 4xdsw bank? + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL PORT_CONDITION("DSW0", 0x04, EQUALS, 0x00) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_COCKTAIL PORT_CONDITION("DSW0", 0x04, EQUALS, 0x00) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_COCKTAIL PORT_CONDITION("DSW0", 0x04, EQUALS, 0x00) + + PORT_START("DSW0") + PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("DSW0:1,2") + PORT_DIPSETTING( 0x00, "2" ) + PORT_DIPSETTING( 0x01, "3" ) + PORT_DIPSETTING( 0x02, "4" ) + PORT_DIPSETTING( 0x03, "5" ) + PORT_DIPNAME( 0x04, 0x04, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("DSW0:3") + PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Upright ) ) + PORT_DIPNAME( 0x08, 0x00, "Disable Collision (Buggy!)" ) PORT_DIPLOCATION("DSW0:4") // this causes the game to malfunction, likely leftover debug feature + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPNAME( 0x10, 0x00, "Show Copyright Date" ) PORT_DIPLOCATION("DSW0:5") + PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "DSW0:6" ) + PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "DSW0:7" ) + PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "DSW0:8" ) +INPUT_PORTS_END + + + +/*************************************************************************** + + GFX Layouts + +***************************************************************************/ + static const gfx_layout tiles32x32_layout = { 32,32, RGN_FRAC(1,1), 2, { 0, 4 }, - { 0, 1, 2, 3, 256+0, 256+1, 256+2, 256+3, 512+0, 512+1, 512+2, 512+3, 768+0, 768+1, 768+2, 768+3, 1024+0, 1024+1, 1024+2, 1024+3, 1280+0, 1280+1, 1280+2, 1280+3, 1536+0, 1536+1, 1536+2, 1536+3, 1792+0, 1792+1, 1792+2, 1792+3 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8, 16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8, 24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8 }, + { + 0, 1, 2, 3, 256+0, 256+1, 256+2, 256+3, + 512+0, 512+1, 512+2, 512+3, 768+0, 768+1, 768+2, 768+3, + 1024+0, 1024+1, 1024+2, 1024+3, 1280+0, 1280+1, 1280+2, 1280+3, + 1536+0, 1536+1, 1536+2, 1536+3, 1792+0, 1792+1, 1792+2, 1792+3 + }, + { + 0*8, 1*8, 2*8 , 3*8, 4*8, 5*8, 6*8, 7*8, + 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8, + 16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8, + 24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8 + }, 8*32*8 }; @@ -573,6 +615,12 @@ GFXDECODE_END +/*************************************************************************** + + Machine initialization + +***************************************************************************/ + void scyclone_state::machine_start() { save_item(NAME(m_videowritemask)); @@ -601,34 +649,37 @@ void scyclone_state::machine_reset() -INTERRUPT_GEN_MEMBER(scyclone_state::irq) +/*************************************************************************** + + Machine configs + +***************************************************************************/ + +INTERRUPT_GEN_MEMBER(scyclone_state::main_irq) { // CPU runs in IM0 - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); /* Z80 - RST 10h */ + m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); // Z80 - RST 10h } - void scyclone_state::scyclone(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, 5000000/2); // MOSTEK Z80-CPU ? MHz (there's also a 9.987MHz XTAL) intermissions seem driven directly by CPU speed for reference + // basic machine hardware + Z80(config, m_maincpu, 5_MHz_XTAL/2); // MOSTEK Z80-CPU 2.5MHz? (there's also a 9.987MHz XTAL), intermissions seem driven directly by CPU speed for reference m_maincpu->set_addrmap(AS_PROGRAM, &scyclone_state::scyclone_map); m_maincpu->set_addrmap(AS_IO, &scyclone_state::scyclone_iomap); - m_maincpu->set_vblank_int("screen", FUNC(scyclone_state::irq)); + m_maincpu->set_vblank_int("screen", FUNC(scyclone_state::main_irq)); - // sound ? - z80_device &subcpu(Z80(config, "subcpu", 5000000/2)); // LH0080 Z80-CPU SHARP ? MHz (5Mhz XTAL on this sub-pcb) - subcpu.set_addrmap(AS_PROGRAM, &scyclone_state::scyclone_sub_map); - subcpu.set_addrmap(AS_IO, &scyclone_state::scyclone_sub_iomap); + Z80(config, m_subcpu, 5_MHz_XTAL/2); // LH0080 Z80-CPU SHARP 2.5MHz (5Mhz XTAL on this sub-pcb) + m_subcpu->set_addrmap(AS_PROGRAM, &scyclone_state::scyclone_sub_map); + m_subcpu->set_addrmap(AS_IO, &scyclone_state::scyclone_sub_iomap); // no idea, but it does wait on an irq in places, irq0 increases a register checked in the wait loop so without it sound dies after a while - subcpu.set_periodic_int(FUNC(scyclone_state::irq0_line_hold), attotime::from_hz(400*60)); + m_subcpu->set_periodic_int(FUNC(scyclone_state::sound_irq), attotime::from_hz(400*60)); GENERIC_LATCH_8(config, m_soundlatch); - /* add shifter */ MB14241(config, "mb14241"); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); @@ -640,23 +691,28 @@ void scyclone_state::scyclone(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_scyclone); PALETTE(config, m_palette).set_entries(8 + 4*4); - /* sound hardware */ + // sound hardware SPEAKER(config, "speaker").front_center(); - sn76477_device &snsnd0(SN76477(config, "snsnd0")); - snsnd0.set_enable(1); - snsnd0.add_route(ALL_OUTPUTS, "speaker", 0.2); + SN76477(config, m_snsnd[0]); + m_snsnd[0]->set_enable(1); + m_snsnd[0]->add_route(ALL_OUTPUTS, "speaker", 0.2); + + SN76477(config, m_snsnd[1]); + m_snsnd[1]->set_enable(1); + m_snsnd[1]->add_route(ALL_OUTPUTS, "speaker", 0.2); - sn76477_device &snsnd1(SN76477(config, "snsnd1")); - snsnd1.set_enable(1); - snsnd1.add_route(ALL_OUTPUTS, "speaker", 0.2); + DAC_8BIT_R2R(config, m_dac[0]).add_route(ALL_OUTPUTS, "speaker", 0.25); // unknown DAC + DAC_8BIT_R2R(config, m_dac[1]).add_route(ALL_OUTPUTS, "speaker", 0.25); // unknown DAC +} - // this is just taken from route16.cpp - DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25); // unknown DAC - DAC_8BIT_R2R(config, "dac2", 0).add_route(ALL_OUTPUTS, "speaker", 0.25); // unknown DAC -} +/*************************************************************************** + + ROM definitions + +***************************************************************************/ ROM_START( scyclone ) ROM_REGION( 0x3000, "maincpu", 0 ) @@ -690,4 +746,4 @@ ROM_END } // anonymous namespace -GAME( 1980, scyclone, 0, scyclone, scyclone, scyclone_state, empty_init, ROT270, "Taito Corporation", "Space Cyclone", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, scyclone, 0, scyclone, scyclone, scyclone_state, empty_init, ROT270, "Taito Corporation", "Space Cyclone", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -- cgit v1.2.3