diff --git a/src/mame/namco/namcos1_v.cpp b/src/mame/namco/namcos1_v.cpp index 72e9cd5afd6..b8ce4399293 100644 --- a/src/mame/namco/namcos1_v.cpp +++ b/src/mame/namco/namcos1_v.cpp @@ -68,15 +68,15 @@ void namcos1_state::TilemapCB(u16 code, int &tile, int &mask) void namcos1_state::video_start() { - /* set table for sprite color == 0x7f */ + // set table for sprite color == 0x7f for (int i = 0; i < 15; i++) m_drawmode_table[i] = DRAWMODE_SHADOW; m_drawmode_table[15] = DRAWMODE_NONE; - /* all palette entries are not affected by shadow sprites... */ + // all palette entries are not affected by shadow sprites... for (int i = 0; i < 0x2000; i++) m_c116->shadow_table()[i] = i; - /* ... except for tilemap colors */ + // ... except for tilemap colors for (int i = 0x0800; i < 0x1000; i++) m_c116->shadow_table()[i] = i + 0x0800; @@ -95,11 +95,11 @@ void namcos1_state::video_start() void namcos1_state::spriteram_w(offs_t offset, u8 data) { - /* 0000-07ff work ram */ - /* 0800-0fff sprite ram */ + // 0000-07ff work ram + // 0800-0fff sprite ram m_spriteram[offset] = data; - /* a write to this offset tells the sprite chip to buffer the sprite list */ + // a write to this offset tells the sprite chip to buffer the sprite list if (offset == 0x0ff2) m_copy_sprites = true; } @@ -135,7 +135,7 @@ sprite format: void namcos1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { u8 *spriteram = m_spriteram + 0x800; - const u8 *source = &spriteram[0x800-0x20]; /* the last is NOT a sprite */ + const u8 *source = &spriteram[0x800-0x20]; // the last is NOT a sprite const u8 *finish = &spriteram[0]; gfx_element *gfx = m_gfxdecode->gfx(0); @@ -175,7 +175,7 @@ void namcos1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co flipy = !flipy; } - sy++; /* sprites are buffered and delayed by one scanline */ + sy++; // sprites are buffered and delayed by one scanline gfx->set_source_clip(tx, sizex, ty, sizey); if (color != 0x7f) @@ -207,13 +207,13 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co { rectangle new_clip = cliprect; - /* flip screen is embedded in the sprite control registers */ + // flip screen is embedded in the sprite control registers flip_screen_set(m_spriteram[0x0ff6] & 1); - /* background color */ + // background color bitmap.fill(m_c116->black_pen(), cliprect); - /* berabohm uses asymmetrical visibility windows to iris on the character */ + // berabohm uses asymmetrical visibility windows to iris on the character int i = m_c116->get_reg(0) - 1; // min x if (new_clip.min_x < i) new_clip.min_x = i; i = m_c116->get_reg(1) - 1 - 1; // max x @@ -230,8 +230,8 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co screen.priority().fill(0, new_clip); - /* bit 0-2 priority */ - /* bit 3 disable */ + // bit 0-2 priority + // bit 3 disable for (int priority = 0; priority < 8; priority++) { m_c123tmap->draw(screen, bitmap, new_clip, priority, priority, 0); @@ -244,9 +244,9 @@ u32 namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co void namcos1_state::screen_vblank(int state) { - // rising edge if (state) { + // rising edge if (m_copy_sprites) { u8 *spriteram = m_spriteram + 0x800; @@ -265,6 +265,8 @@ void namcos1_state::screen_vblank(int state) } else { + // falling edge + // splatter 2nd bossfight music fails if audiocpu irq is at the same time as main/sub irq m_audiocpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE); m_mcu->set_input_line(HD6301_IRQ1_LINE, ASSERT_LINE); } diff --git a/src/mame/orca/espial.cpp b/src/mame/orca/espial.cpp index 1432286213b..500efa83f76 100644 --- a/src/mame/orca/espial.cpp +++ b/src/mame/orca/espial.cpp @@ -3,7 +3,10 @@ /*************************************************************************** - Espial hardware games +Espial hardware games + +2 XTALS (12.0MHz and 18.432MHz), both CPUs are 3.0MHz and the AY is 1.5MHz. +18.432MHz XTAL is probably for the pixel clock. Espial: The Orca logo is displayed, but looks to be "blacked out" via the color PROMs by having 0x1c & 0x1d set to black. @@ -43,7 +46,6 @@ Stephh's notes (based on the games Z80 code and some tests) : #include "cpu/z80/z80.h" #include "machine/gen_latch.h" -#include "machine/timer.h" #include "machine/watchdog.h" #include "sound/ay8910.h" @@ -67,9 +69,11 @@ public: m_colorram(*this, "colorram"), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), + m_screen(*this, "screen"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), - m_soundlatch(*this, "soundlatch") + m_soundlatch(*this, "soundlatch%u", 0), + m_aysnd(*this, "aysnd") { } void espial(machine_config &config); @@ -88,22 +92,29 @@ protected: // video-related tilemap_t *m_bg_tilemap = nullptr; - uint8_t m_flipscreen = 0U; + uint8_t m_flipscreen = 0; // sound-related - uint8_t m_main_nmi_enabled = 0U; - uint8_t m_sound_nmi_enabled = 0U; + uint8_t m_main_nmi_enabled = 0; + uint8_t m_sound_nmi_enabled = 0; + uint8_t m_sound_nmi_freq = 0; + emu_timer *sound_nmi_timer; // devices required_device m_maincpu; required_device m_audiocpu; + required_device m_screen; required_device m_gfxdecode; required_device m_palette; - required_device m_soundlatch; + required_device_array m_soundlatch; + required_device m_aysnd; void master_interrupt_mask_w(uint8_t data); - void master_soundlatch_w(uint8_t data); void sound_nmi_mask_w(uint8_t data); + void porta_w(offs_t offset, uint8_t data, uint8_t mem_mask); + TIMER_CALLBACK_MEMBER(sound_nmi_gen); + void vblank(int state); + void videoram_w(offs_t offset, uint8_t data); void colorram_w(offs_t offset, uint8_t data); void attributeram_w(offs_t offset, uint8_t data); @@ -112,9 +123,8 @@ protected: TILE_GET_INFO_MEMBER(get_tile_info); void palette(palette_device &palette) const; uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(sound_nmi_gen); - TIMER_DEVICE_CALLBACK_MEMBER(scanline); void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + void main_map(address_map &map) ATTR_COLD; void sound_io_map(address_map &map) ATTR_COLD; void sound_map(address_map &map) ATTR_COLD; @@ -123,7 +133,9 @@ protected: class netwars_state : public espial_state { public: - using espial_state::espial_state; + netwars_state(const machine_config &mconfig, device_type type, const char *tag) : + espial_state(mconfig, type, tag) + { } void netwars(machine_config &config); @@ -135,7 +147,32 @@ private: }; -/*************************************************************************** + +/************************************* + * + * Machine initialization + * + *************************************/ + +void espial_state::machine_start() +{ + save_item(NAME(m_flipscreen)); + save_item(NAME(m_main_nmi_enabled)); + save_item(NAME(m_sound_nmi_enabled)); + save_item(NAME(m_sound_nmi_freq)); + + sound_nmi_timer = timer_alloc(FUNC(espial_state::sound_nmi_gen), this); +} + +void espial_state::machine_reset() +{ + m_main_nmi_enabled = false; + m_sound_nmi_enabled = false; +} + + + +/************************************* Convert the color PROMs into a more useable format. @@ -153,7 +190,7 @@ private: -- 470 ohm resistor -- RED bit 0 -- 1 kohm resistor -- RED -***************************************************************************/ +*************************************/ void espial_state::palette(palette_device &palette) const { @@ -168,11 +205,13 @@ void espial_state::palette(palette_device &palette) const bit1 = BIT(color_prom[i], 1); bit2 = BIT(color_prom[i], 2); int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + // green component bit0 = BIT(color_prom[i], 3); bit1 = BIT(color_prom[i + palette.entries()], 0); bit2 = BIT(color_prom[i + palette.entries()], 1); int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + // blue component bit0 = 0; bit1 = BIT(color_prom[i + palette.entries()], 2); @@ -185,23 +224,6 @@ void espial_state::palette(palette_device &palette) const -/*************************************************************************** - - Callbacks for the TileMap code - -***************************************************************************/ - -TILE_GET_INFO_MEMBER(espial_state::get_tile_info) -{ - uint8_t const code = m_videoram[tile_index]; - uint8_t const col = m_colorram[tile_index]; - uint8_t const attr = m_attributeram[tile_index]; - - tileinfo.set(0, code | ((attr & 0x03) << 8), col & 0x3f, TILE_FLIPYX(attr >> 2)); -} - - - /************************************* * * Video system start @@ -212,61 +234,25 @@ void espial_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(espial_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); m_bg_tilemap->set_scroll_cols(32); - - save_item(NAME(m_flipscreen)); } void netwars_state::video_start() { // Net Wars has a tile map that's twice as big as Espial's m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(netwars_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 64); - m_bg_tilemap->set_scroll_cols(32); - - save_item(NAME(m_flipscreen)); } - -/************************************* - * - * Memory handlers - * - *************************************/ - -void espial_state::videoram_w(offs_t offset, uint8_t data) +TILE_GET_INFO_MEMBER(espial_state::get_tile_info) { - m_videoram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); + uint8_t const code = m_videoram[tile_index]; + uint8_t const col = m_colorram[tile_index]; + uint8_t const attr = m_attributeram[tile_index]; + + tileinfo.set(0, code | ((attr & 0x03) << 8), col & 0x3f, TILE_FLIPYX(attr >> 2)); } -void espial_state::colorram_w(offs_t offset, uint8_t data) -{ - m_colorram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); -} - - -void espial_state::attributeram_w(offs_t offset, uint8_t data) -{ - m_attributeram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); -} - - -void espial_state::scrollram_w(offs_t offset, uint8_t data) -{ - m_scrollram[offset] = data; - m_bg_tilemap->set_scrolly(offset, data); -} - - -void espial_state::flipscreen_w(uint8_t data) -{ - m_flipscreen = data; - m_bg_tilemap->set_flip(m_flipscreen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0); -} - /************************************* * @@ -333,7 +319,6 @@ void espial_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) } } - uint32_t espial_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); @@ -342,20 +327,66 @@ uint32_t espial_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap } -void espial_state::machine_reset() -{ - m_flipscreen = 0; - m_main_nmi_enabled = false; - m_sound_nmi_enabled = false; +/************************************* + * + * Memory handlers + * + *************************************/ + +void espial_state::vblank(int state) +{ + // vblank irq + if (state && m_main_nmi_enabled) + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + + // timer irq, checks soundlatch port then updates some sound related work RAM buffers + if (state) + m_maincpu->set_input_line(0, HOLD_LINE); } -void espial_state::machine_start() + +TIMER_CALLBACK_MEMBER(espial_state::sound_nmi_gen) { - save_item(NAME(m_sound_nmi_enabled)); + if (m_sound_nmi_enabled) + m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); } +void espial_state::videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); +} + + +void espial_state::colorram_w(offs_t offset, uint8_t data) +{ + m_colorram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); +} + + +void espial_state::attributeram_w(offs_t offset, uint8_t data) +{ + m_attributeram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); +} + + +void espial_state::scrollram_w(offs_t offset, uint8_t data) +{ + m_scrollram[offset] = data; + m_bg_tilemap->set_scrolly(offset, data); +} + + +void espial_state::flipscreen_w(uint8_t data) +{ + m_flipscreen = data; + m_bg_tilemap->set_flip(m_flipscreen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0); +} + void espial_state::master_interrupt_mask_w(uint8_t data) { m_main_nmi_enabled = ~(data & 1); @@ -367,31 +398,46 @@ void espial_state::sound_nmi_mask_w(uint8_t data) m_sound_nmi_enabled = data & 1; } -TIMER_DEVICE_CALLBACK_MEMBER(espial_state::scanline) +void espial_state::porta_w(offs_t offset, uint8_t data, uint8_t mem_mask) { - int const scanline = param; + if (mem_mask && data != m_sound_nmi_freq) + { + // sound NMI frequency + m_sound_nmi_freq = data; + attotime period; - if (scanline == 240 && m_main_nmi_enabled) // vblank-out irq - m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + // netwars writes 0xf8 and expects 32 NMIs per frame + // espial writes 0xfe and expects 4 NMIs per frame + switch (data) + { + case 0: + period = attotime::never; + break; - if (scanline == 16) // timer irq, checks soundlatch port then updates some sound related work RAM buffers - m_maincpu->set_input_line(0, HOLD_LINE); + case 0xfe: + period = m_screen->frame_period() / 4; + break; + + case 0xf8: + period = m_screen->frame_period() / 32; + break; + + default: + logerror("%s: unknown sound NMI frequency %02X", machine().describe_context(), data); + return; + } + + sound_nmi_timer->adjust(period, 0, period); + } } -INTERRUPT_GEN_MEMBER(espial_state::sound_nmi_gen) -{ - if (m_sound_nmi_enabled) - m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); -} - - -void espial_state::master_soundlatch_w(uint8_t data) -{ - m_soundlatch->write(data); - m_audiocpu->set_input_line(0, HOLD_LINE); -} +/************************************* + * + * Address maps + * + *************************************/ void espial_state::main_map(address_map &map) { @@ -401,7 +447,7 @@ void espial_state::main_map(address_map &map) map(0x6082, 0x6082).portr("DSW1"); map(0x6083, 0x6083).portr("IN1"); map(0x6084, 0x6084).portr("IN2"); - map(0x6090, 0x6090).r("soundlatch2", FUNC(generic_latch_8_device::read)).w(FUNC(espial_state::master_soundlatch_w)); + map(0x6090, 0x6090).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(m_soundlatch[0], FUNC(generic_latch_8_device::write)); map(0x7000, 0x7000).rw("watchdog", FUNC(watchdog_timer_device::reset_r), FUNC(watchdog_timer_device::reset_w)); map(0x7100, 0x7100).w(FUNC(espial_state::master_interrupt_mask_w)); map(0x7200, 0x7200).w(FUNC(espial_state::flipscreen_w)); @@ -427,7 +473,7 @@ void netwars_state::main_map(address_map &map) map(0x6082, 0x6082).portr("DSW1"); map(0x6083, 0x6083).portr("IN1"); map(0x6084, 0x6084).portr("IN2"); - map(0x6090, 0x6090).r("soundlatch2", FUNC(generic_latch_8_device::read)).w(FUNC(netwars_state::master_soundlatch_w)); + map(0x6090, 0x6090).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(m_soundlatch[0], FUNC(generic_latch_8_device::write)); map(0x7000, 0x7000).rw("watchdog", FUNC(watchdog_timer_device::reset_r), FUNC(watchdog_timer_device::reset_w)); map(0x7100, 0x7100).w(FUNC(netwars_state::master_interrupt_mask_w)); map(0x7200, 0x7200).w(FUNC(netwars_state::flipscreen_w)); @@ -446,16 +492,23 @@ void espial_state::sound_map(address_map &map) map(0x0000, 0x1fff).rom(); map(0x2000, 0x23ff).ram(); map(0x4000, 0x4000).w(FUNC(espial_state::sound_nmi_mask_w)); - map(0x6000, 0x6000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w("soundlatch2", FUNC(generic_latch_8_device::write)); + map(0x6000, 0x6000).r(m_soundlatch[0], FUNC(generic_latch_8_device::read)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write)); } void espial_state::sound_io_map(address_map &map) { map.global_mask(0xff); - map(0x00, 0x01).w("aysnd", FUNC(ay8910_device::address_data_w)); + map(0x00, 0x01).w(m_aysnd, FUNC(ay8910_device::address_data_w)); } + +/************************************* + * + * Input ports + * + *************************************/ + // verified from Z80 code static INPUT_PORTS_START( espial ) PORT_START("IN0") @@ -580,6 +633,13 @@ static INPUT_PORTS_START( netwars ) INPUT_PORTS_END + +/************************************* + * + * GFX layouts + * + *************************************/ + static const gfx_layout charlayout = { 8,8, @@ -610,29 +670,35 @@ GFXDECODE_END +/************************************* + * + * Machine configs + * + *************************************/ void espial_state::espial(machine_config &config) { // basic machine hardware - Z80(config, m_maincpu, 3'072'000); // 3.072 MHz + Z80(config, m_maincpu, 12_MHz_XTAL / 4); m_maincpu->set_addrmap(AS_PROGRAM, &espial_state::main_map); - TIMER(config, "scantimer").configure_scanline(FUNC(espial_state::scanline), "screen", 0, 1); - Z80(config, m_audiocpu, 3'072'000); // 2 MHz?????? + Z80(config, m_audiocpu, 12_MHz_XTAL / 4); m_audiocpu->set_addrmap(AS_PROGRAM, &espial_state::sound_map); m_audiocpu->set_addrmap(AS_IO, &espial_state::sound_io_map); - m_audiocpu->set_periodic_int(FUNC(espial_state::sound_nmi_gen), attotime::from_hz(4 * 60)); + + config.set_maximum_quantum(attotime::from_hz(600)); WATCHDOG_TIMER(config, "watchdog"); // video hardware - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate - screen.set_size(32*8, 32*8); - screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1); - screen.set_screen_update(FUNC(espial_state::screen_update)); - screen.set_palette(m_palette); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(59); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate + m_screen->set_size(32*8, 32*8); + m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1); + m_screen->set_screen_update(FUNC(espial_state::screen_update)); + m_screen->set_palette(m_palette); + m_screen->screen_vblank().set(FUNC(espial_state::vblank)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_espial); PALETTE(config, m_palette, FUNC(espial_state::palette), 256); @@ -640,10 +706,14 @@ void espial_state::espial(machine_config &config) // sound hardware SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - GENERIC_LATCH_8(config, "soundlatch2"); + GENERIC_LATCH_8(config, m_soundlatch[0]); + m_soundlatch[0]->data_pending_callback().set_inputline(m_audiocpu, 0); - AY8910(config, "aysnd", 1'500'000).add_route(ALL_OUTPUTS, "mono", 0.50); + GENERIC_LATCH_8(config, m_soundlatch[1]); + + AY8910(config, m_aysnd, 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.50); + m_aysnd->port_a_write_callback().set(FUNC(espial_state::porta_w)); + m_aysnd->port_b_write_callback().set_nop(); // spams 0x00 } void netwars_state::netwars(machine_config &config) @@ -652,18 +722,15 @@ void netwars_state::netwars(machine_config &config) // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &netwars_state::main_map); - - // video hardware - subdevice("screen")->set_size(32*8, 64*8); } -/*************************************************************************** - - Game driver(s) - -***************************************************************************/ +/************************************* + * + * ROM definitions + * + *************************************/ ROM_START( espial ) ROM_REGION( 0x10000, "maincpu", 0 ) @@ -786,6 +853,13 @@ ROM_END } // anonymous namespace + +/************************************* + * + * Game driver(s) + * + *************************************/ + GAME( 1983, espial, 0, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Europe)", MACHINE_SUPPORTS_SAVE ) GAME( 1983, espialj, espial, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1983, espialn, espial, espial, espial, espial_state, empty_init, ROT0, "Orca / Thunderbolt", "Espial (Nova Apparate license)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/orca/orca40c.cpp b/src/mame/orca/orca40c.cpp index bd5ebac0b26..d694ae68524 100644 --- a/src/mame/orca/orca40c.cpp +++ b/src/mame/orca/orca40c.cpp @@ -28,17 +28,17 @@ DEFINE_DEVICE_TYPE(ORCA_OVG_40C, orca_ovg_40c_device, "orca_ovg_40c", "Orca OVG 40c video PCB") -orca_ovg_40c_device::orca_ovg_40c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, ORCA_OVG_40C, tag, owner, clock), - device_gfx_interface(mconfig, *this, nullptr, "palette"), - device_video_interface(mconfig, *this), - m_videoram(*this, "videoram"), - m_videoram_2(*this,"videoram_2"), - m_attributeram(*this, "attributeram"), - m_spriteram(*this, "spriteram"), - m_bulletsram(*this, "bulletsram"), - m_percuss_hardware(false), - m_flip_screen(false) +orca_ovg_40c_device::orca_ovg_40c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, ORCA_OVG_40C, tag, owner, clock), + device_gfx_interface(mconfig, *this, nullptr, "palette"), + device_video_interface(mconfig, *this), + m_videoram(*this, "videoram"), + m_videoram_2(*this,"videoram_2"), + m_attributeram(*this, "attributeram"), + m_spriteram(*this, "spriteram"), + m_bulletsram(*this, "bulletsram"), + m_percuss_hardware(false), + m_flip_screen(false) { } diff --git a/src/mame/orca/vastar.cpp b/src/mame/orca/vastar.cpp index 56b1e11bc7b..f3b679129f5 100644 --- a/src/mame/orca/vastar.cpp +++ b/src/mame/orca/vastar.cpp @@ -700,7 +700,7 @@ ROM_START( dogfightp ) // all 2732 ROM_LOAD( "10.7p", 0x1800, 0x1000, CRC(2cb51793) SHA1(d90177ef28730774202a04a0846281537a1883df) ) ROM_REGION( 0x0040, "videopcb:proms", 0 ) // on ORCA OVG-40c sub board - ROM_LOAD( "blue.2a.82s123", 0x0000, 0x0020, CRC(aa839a24) SHA1(9b8217e1c257d24e873888fd083c099fc93c7878) ) //doesn't match parent + ROM_LOAD( "blue.2a.82s123", 0x0000, 0x0020, CRC(aa839a24) SHA1(9b8217e1c257d24e873888fd083c099fc93c7878) ) // doesn't match parent ROM_LOAD( "pink.2b.82s123", 0x0020, 0x0020, CRC(596ae457) SHA1(1c1a3130d88c5fd5c66ce9f91d97a09c0a0b535f) ) ROM_END diff --git a/src/mame/orca/zodiack.cpp b/src/mame/orca/zodiack.cpp index 5620f974d64..5bdbdc55089 100644 --- a/src/mame/orca/zodiack.cpp +++ b/src/mame/orca/zodiack.cpp @@ -117,11 +117,12 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), - m_soundlatch(*this, "soundlatch%u", 0) + m_screen(*this, "screen"), + m_soundlatch(*this, "soundlatch%u", 0), + m_aysnd(*this, "aysnd") { } void zodiack(machine_config &config); - void dogfight(machine_config &config); void percuss(machine_config &config); protected: @@ -133,18 +134,23 @@ private: void irq_mask_w(uint8_t data); void sound_nmi_enable_w(uint8_t data); void control_w(uint8_t data); + void porta_w(offs_t offset, uint8_t data, uint8_t mem_mask); // devices required_device m_maincpu; required_device m_audiocpu; + required_device m_screen; required_device_array m_soundlatch; + required_device m_aysnd; // state uint8_t m_main_nmi_enabled = 0; uint8_t m_main_irq_enabled = 0; uint8_t m_sound_nmi_enabled = 0; + uint8_t m_sound_nmi_freq = 0; + emu_timer *sound_nmi_timer; - INTERRUPT_GEN_MEMBER(sound_nmi_gen); + TIMER_CALLBACK_MEMBER(sound_nmi_gen); void vblank(int state); void io_map(address_map &map) ATTR_COLD; @@ -152,6 +158,39 @@ private: void sound_map(address_map &map) ATTR_COLD; }; + + +/************************************* + * + * Machine initialization + * + *************************************/ + +void zodiack_state::machine_start() +{ + save_item(NAME(m_main_nmi_enabled)); + save_item(NAME(m_main_irq_enabled)); + save_item(NAME(m_sound_nmi_enabled)); + save_item(NAME(m_sound_nmi_freq)); + + sound_nmi_timer = timer_alloc(FUNC(zodiack_state::sound_nmi_gen), this); +} + +void zodiack_state::machine_reset() +{ + m_main_nmi_enabled = 0; + m_main_irq_enabled = 0; + m_sound_nmi_enabled = 0; +} + + + +/************************************* + * + * Memory handlers + * + *************************************/ + void zodiack_state::nmi_mask_w(uint8_t data) { m_main_nmi_enabled = (data & 1) ^ 1; @@ -176,7 +215,7 @@ void zodiack_state::vblank(int state) m_maincpu->set_input_line(0, HOLD_LINE); } -INTERRUPT_GEN_MEMBER(zodiack_state::sound_nmi_gen) +TIMER_CALLBACK_MEMBER(zodiack_state::sound_nmi_gen) { if (m_sound_nmi_enabled) m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); @@ -190,6 +229,46 @@ void zodiack_state::control_w(uint8_t data) // Bit 2 - ???? } +void zodiack_state::porta_w(offs_t offset, uint8_t data, uint8_t mem_mask) +{ + if (mem_mask && data != m_sound_nmi_freq) + { + // sound NMI frequency + m_sound_nmi_freq = data; + attotime period; + + // dogfight writes 0xc0 and expects 4 NMIs per frame + // others write 0xe0 and expect 8 NMIs per frame + switch (data) + { + case 0: + period = attotime::never; + break; + + case 0xc0: + period = m_screen->frame_period() / 4; + break; + + case 0xe0: + period = m_screen->frame_period() / 8; + break; + + default: + logerror("%s: unknown sound NMI frequency %02X", machine().describe_context(), data); + return; + } + + sound_nmi_timer->adjust(period, 0, period); + } +} + + + +/************************************* + * + * Address maps + * + *************************************/ void zodiack_state::main_map(address_map &map) { @@ -224,11 +303,17 @@ void zodiack_state::sound_map(address_map &map) void zodiack_state::io_map(address_map &map) { map.global_mask(0xff); - map(0x00, 0x01).w("aysnd", FUNC(ay8910_device::address_data_w)); + map(0x00, 0x01).w(m_aysnd, FUNC(ay8910_device::address_data_w)); } +/************************************* + * + * Input ports + * + *************************************/ + static INPUT_PORTS_START( zodiack ) PORT_START("DSW0") // never read in this game PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) @@ -540,39 +625,30 @@ static INPUT_PORTS_START( bounty ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY INPUT_PORTS_END -void zodiack_state::machine_start() -{ - save_item(NAME(m_main_nmi_enabled)); - save_item(NAME(m_main_irq_enabled)); - save_item(NAME(m_sound_nmi_enabled)); -} - -void zodiack_state::machine_reset() -{ - m_main_nmi_enabled = 0; - m_main_irq_enabled = 0; - m_sound_nmi_enabled = 0; -} +/************************************* + * + * Machine configs + * + *************************************/ void zodiack_state::zodiack(machine_config &config) { // basic machine hardware - Z80(config, m_maincpu, XTAL(18'432'000) / 6); + Z80(config, m_maincpu, 18.432_MHz_XTAL / 6); m_maincpu->set_addrmap(AS_PROGRAM, &zodiack_state::main_map); - Z80(config, m_audiocpu, XTAL(18'432'000) / 6); + Z80(config, m_audiocpu, 18.432_MHz_XTAL / 6); m_audiocpu->set_addrmap(AS_PROGRAM, &zodiack_state::sound_map); m_audiocpu->set_addrmap(AS_IO, &zodiack_state::io_map); - m_audiocpu->set_periodic_int(FUNC(zodiack_state::sound_nmi_gen), attotime::from_hz(8 * 60)); // sound tempo - unknown source, timing is guessed config.set_maximum_quantum(attotime::from_hz(600)); WATCHDOG_TIMER(config, "watchdog"); // video hardware - SCREEN(config, "screen", SCREEN_TYPE_RASTER).screen_vblank().set(FUNC(zodiack_state::vblank)); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER).screen_vblank().set(FUNC(zodiack_state::vblank)); orca_ovg_40c_device &videopcb(ORCA_OVG_40C(config, "videopcb", 0)); videopcb.set_screen("screen"); @@ -585,7 +661,8 @@ void zodiack_state::zodiack(machine_config &config) GENERIC_LATCH_8(config, m_soundlatch[1]); - AY8910(config, "aysnd", XTAL(18'432'000) / 12).add_route(ALL_OUTPUTS, "mono", 0.50); + AY8910(config, m_aysnd, 18.432_MHz_XTAL / 12).add_route(ALL_OUTPUTS, "mono", 0.50); + m_aysnd->port_a_write_callback().set(FUNC(zodiack_state::porta_w)); } void zodiack_state::percuss(machine_config &config) @@ -596,19 +673,13 @@ void zodiack_state::percuss(machine_config &config) videopcb.set_percuss_hardware(true); } -void zodiack_state::dogfight(machine_config &config) -{ - zodiack(config); - - m_audiocpu->set_periodic_int(FUNC(zodiack_state::sound_nmi_gen), attotime::from_hz(4 * 60)); // 4 interrupts per frame -} -/*************************************************************************** - - Game driver(s) - -***************************************************************************/ +/************************************* + * + * ROM definitions + * + *************************************/ ROM_START( zodiack ) ROM_REGION( 0x10000, "maincpu", 0 ) @@ -735,9 +806,16 @@ ROM_END } // anonymous namespace -GAME( 1983, zodiack, 0, zodiack, zodiack, zodiack_state, empty_init, ROT270, "Orca (Esco Trading Co., Inc. license)", "Zodiack", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) // bullet color needs to be verified -GAME( 1983, dogfight, 0, dogfight, dogfight, zodiack_state, empty_init, ROT270, "Orca / Thunderbolt", "Dog Fight (Thunderbolt)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, moguchan, 0, percuss, moguchan, zodiack_state, empty_init, ROT270, "Orca (Eastern Commerce Inc. license)", "Mogu Chan (bootleg?)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // license copyright taken from ROM string at $0b5c -GAME( 1981, percuss, 0, percuss, percuss, zodiack_state, empty_init, ROT270, "Orca", "The Percussor", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, bounty, 0, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, bounty2, bounty, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // seems to use a different memory map + +/************************************* + * + * Game driver(s) + * + *************************************/ + +GAME( 1983, zodiack, 0, zodiack, zodiack, zodiack_state, empty_init, ROT270, "Orca (Esco Trading Co., Inc. license)", "Zodiack", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) // bullet color needs to be verified +GAME( 1983, dogfight, 0, zodiack, dogfight, zodiack_state, empty_init, ROT270, "Orca / Thunderbolt", "Dog Fight (Thunderbolt)", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, moguchan, 0, percuss, moguchan, zodiack_state, empty_init, ROT270, "Orca (Eastern Commerce Inc. license)", "Mogu Chan (bootleg?)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // license copyright taken from ROM string at $0b5c +GAME( 1981, percuss, 0, percuss, percuss, zodiack_state, empty_init, ROT270, "Orca", "The Percussor", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, bounty, 0, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1982, bounty2, bounty, percuss, bounty, zodiack_state, empty_init, ROT180, "Orca", "The Bounty (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // seems to use a different memory map