vigilant.cpp, shisen.cpp: Cleanups & modernization

- Replace legacy interrupt generators with vertical blank and scanline timer callbacks
- Add presumed raw timing parameters for all games, based on known XTAL values
- Correct maincpu XTAL value for Buccaneers
This commit is contained in:
AJR 2022-05-11 23:06:31 -04:00
parent 86f44c6d35
commit 5a129ead17
3 changed files with 67 additions and 55 deletions

View File

@ -15,6 +15,7 @@ driver by Nicola Salmoria
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "machine/rstbuf.h"
#include "machine/timer.h"
#include "sound/ymopm.h"
#include "emupal.h"
@ -31,6 +32,7 @@ public:
shisen_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_soundcpu(*this, "soundcpu"),
m_audio(*this, "m72"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
@ -47,6 +49,7 @@ protected:
private:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<m72_audio_device> m_audio;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@ -69,6 +72,8 @@ private:
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(sound_nmi);
void main_io_map(address_map &map);
void main_prg_map(address_map &map);
void sound_io_map(address_map &map);
@ -130,6 +135,11 @@ void shisen_state::video_start()
save_item(NAME(m_gfxbank));
}
TIMER_DEVICE_CALLBACK_MEMBER(shisen_state::sound_nmi)
{
m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
uint32_t shisen_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// on Irem boards, screen flip is handled in both hardware and software.
@ -324,23 +334,21 @@ void shisen_state::shisen(machine_config &config)
Z80(config, m_maincpu, 3.579545_MHz_XTAL ); // Verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &shisen_state::main_prg_map);
m_maincpu->set_addrmap(AS_IO, &shisen_state::main_io_map);
m_maincpu->set_vblank_int("screen", FUNC(shisen_state::irq0_line_hold));
z80_device &soundcpu(Z80(config, "soundcpu", 3.579545_MHz_XTAL )); // Verified on PCB
z80_device &soundcpu(Z80(config, m_soundcpu, 3.579545_MHz_XTAL )); // Verified on PCB
soundcpu.set_addrmap(AS_PROGRAM, &shisen_state::sound_prg_map);
soundcpu.set_addrmap(AS_IO, &shisen_state::sound_io_map);
soundcpu.set_periodic_int(FUNC(shisen_state::nmi_line_pulse), attotime::from_hz(128*55)); // clocked by V1? (Vigilante)
// IRQs are generated by main Z80 and YM2151
soundcpu.set_irq_acknowledge_callback("soundirq", FUNC(rst_neg_buffer_device::inta_cb));
TIMER(config, "v1").configure_scanline(FUNC(shisen_state::sound_nmi), "screen", 1, 2); // clocked by V1? (Vigilante)
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(55);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(64*8, 32*8);
screen.set_visarea(0*8, 64*8-1, 0*8, 32*8-1);
screen.set_raw(24_MHz_XTAL / 2, 96*8, 0*8, 64*8, 284, 0, 256); // sync rates not verified
screen.set_screen_update(FUNC(shisen_state::screen_update));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, 0, HOLD_LINE);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_shisen);
PALETTE(config, m_palette).set_entries(256);
@ -353,7 +361,7 @@ void shisen_state::shisen(machine_config &config)
soundlatch.data_pending_callback().set("soundirq", FUNC(rst_neg_buffer_device::rst18_w));
soundlatch.set_separate_acknowledge(true);
RST_NEG_BUFFER(config, "soundirq", 0).int_callback().set_inputline("soundcpu", 0);
RST_NEG_BUFFER(config, "soundirq").int_callback().set_inputline(m_soundcpu, 0);
IREM_M72_AUDIO(config, m_audio);
m_audio->set_dac_tag("dac");

View File

@ -52,6 +52,11 @@ void vigilant_state::bank_select_w(uint8_t data)
membank("bank1")->set_entry(data & 0x07);
}
TIMER_DEVICE_CALLBACK_MEMBER(vigilant_state::sound_nmi)
{
m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
/***************************************************************************
vigilant_out2_w
**************************************************************************/
@ -610,21 +615,22 @@ void vigilant_state::vigilant(machine_config &config)
Z80(config, m_maincpu, 3.579545_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &vigilant_state::vigilant_map);
m_maincpu->set_addrmap(AS_IO, &vigilant_state::vigilant_io_map);
m_maincpu->set_vblank_int("screen", FUNC(vigilant_state::irq0_line_hold));
z80_device &soundcpu(Z80(config, "soundcpu", 3.579545_MHz_XTAL));
z80_device &soundcpu(Z80(config, m_soundcpu, 3.579545_MHz_XTAL));
soundcpu.set_addrmap(AS_PROGRAM, &vigilant_state::sound_map);
soundcpu.set_addrmap(AS_IO, &vigilant_state::sound_io_map);
soundcpu.set_periodic_int(FUNC(vigilant_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1 */
/* IRQs are generated by main Z80 and YM2151 */
soundcpu.set_irq_acknowledge_callback("soundirq", FUNC(rst_neg_buffer_device::inta_cb));
TIMER(config, "v1").configure_scanline(FUNC(vigilant_state::sound_nmi), "screen", 1, 2);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
// Screen timings measured by atrac17 and reviewed by Jose Tejada (JOTEGO)
screen.set_raw( VIDEO_CLOCK/3 /* pixel clock*/, 384 /* total H */, 128, 384, 256+28 /* total V */, 0, 256 );
screen.set_screen_update(FUNC(vigilant_state::screen_update_vigilant));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, 0, HOLD_LINE);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_vigilant);
PALETTE(config, m_palette).set_entries(512+32); /* 512 real palette, 32 virtual palette */
@ -637,7 +643,7 @@ void vigilant_state::vigilant(machine_config &config)
soundlatch.data_pending_callback().set("soundirq", FUNC(rst_neg_buffer_device::rst18_w));
soundlatch.set_separate_acknowledge(true);
RST_NEG_BUFFER(config, "soundirq", 0).int_callback().set_inputline("soundcpu", 0);
RST_NEG_BUFFER(config, "soundirq").int_callback().set_inputline(m_soundcpu, 0);
IREM_M72_AUDIO(config, m_audio);
m_audio->set_dac_tag("dac");
@ -655,26 +661,24 @@ void vigilant_state::vigilant(machine_config &config)
void vigilant_state::buccanrs(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, 5688800); /* 5.688800 MHz */
Z80(config, m_maincpu, 5.0688_MHz_XTAL); /* 5.068800 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &vigilant_state::vigilant_map);
m_maincpu->set_addrmap(AS_IO, &vigilant_state::vigilant_io_map);
m_maincpu->set_vblank_int("screen", FUNC(vigilant_state::irq0_line_hold));
z80_device &soundcpu(Z80(config, "soundcpu", 18432000/6)); /* 3.072000 MHz */
z80_device &soundcpu(Z80(config, m_soundcpu, 18.432_MHz_XTAL / 6)); /* 3.072000 MHz */
soundcpu.set_addrmap(AS_PROGRAM, &vigilant_state::sound_map);
soundcpu.set_addrmap(AS_IO, &vigilant_state::buccanrs_sound_io_map);
soundcpu.set_periodic_int(FUNC(vigilant_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1 */
/* IRQs are generated by main Z80 and YM2151 */
soundcpu.set_irq_acknowledge_callback("soundirq", FUNC(rst_neg_buffer_device::inta_cb));
TIMER(config, "v1").configure_scanline(FUNC(vigilant_state::sound_nmi), "screen", 1, 2);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(55);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(64*8, 32*8);
screen.set_visarea(16*8, (64-16)*8-1, 0*8, 32*8-1);
screen.set_raw(18.432_MHz_XTAL / 3, 384, 128, 384, 284, 0, 256); // sync rates not verified
screen.set_screen_update(FUNC(vigilant_state::screen_update_vigilant));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, 0, HOLD_LINE);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_buccanrs);
PALETTE(config, m_palette).set_entries(512+32); /* 512 real palette, 32 virtual palette */
@ -687,30 +691,30 @@ void vigilant_state::buccanrs(machine_config &config)
soundlatch.data_pending_callback().set("soundirq", FUNC(rst_neg_buffer_device::rst18_w));
soundlatch.set_separate_acknowledge(true);
RST_NEG_BUFFER(config, "soundirq", 0).int_callback().set_inputline("soundcpu", 0);
RST_NEG_BUFFER(config, "soundirq").int_callback().set_inputline(m_soundcpu, 0);
IREM_M72_AUDIO(config, m_audio);
m_audio->set_dac_tag("dac");
ym2203_device &ym1(YM2203(config, "ym1", 18432000/6));
ym2203_device &ym1(YM2203(config, "ym1", 18.432_MHz_XTAL / 6));
ym1.irq_handler().set("soundirq", FUNC(rst_neg_buffer_device::rst28_w));
ym1.add_route(0, "lspeaker", 0.35);
ym1.add_route(0, "lspeaker", 0.35);
ym1.add_route(0, "rspeaker", 0.35);
ym1.add_route(1, "lspeaker", 0.35);
ym1.add_route(1, "lspeaker", 0.35);
ym1.add_route(1, "rspeaker", 0.35);
ym1.add_route(2, "lspeaker", 0.35);
ym1.add_route(2, "lspeaker", 0.35);
ym1.add_route(2, "rspeaker", 0.35);
ym1.add_route(3, "lspeaker", 0.50);
ym1.add_route(3, "lspeaker", 0.50);
ym1.add_route(3, "rspeaker", 0.50);
ym2203_device &ym2(YM2203(config, "ym2", 18432000/6));
ym2.add_route(0, "lspeaker", 0.35);
ym2203_device &ym2(YM2203(config, "ym2", 18.432_MHz_XTAL / 6));
ym2.add_route(0, "lspeaker", 0.35);
ym2.add_route(0, "rspeaker", 0.35);
ym2.add_route(1, "lspeaker", 0.35);
ym2.add_route(1, "lspeaker", 0.35);
ym2.add_route(1, "rspeaker", 0.35);
ym2.add_route(2, "lspeaker", 0.35);
ym2.add_route(2, "lspeaker", 0.35);
ym2.add_route(2, "rspeaker", 0.35);
ym2.add_route(3, "lspeaker", 0.50);
ym2.add_route(3, "lspeaker", 0.50);
ym2.add_route(3, "rspeaker", 0.50);
dac_8bit_r2r_device &dac(DAC_8BIT_R2R(config, "dac", 0)); // unknown DAC
@ -724,23 +728,21 @@ void vigilant_state::kikcubic(machine_config &config)
Z80(config, m_maincpu, 3.579545_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &vigilant_state::kikcubic_map);
m_maincpu->set_addrmap(AS_IO, &vigilant_state::kikcubic_io_map);
m_maincpu->set_vblank_int("screen", FUNC(vigilant_state::irq0_line_hold));
z80_device &soundcpu(Z80(config, "soundcpu", 3.579545_MHz_XTAL));
z80_device &soundcpu(Z80(config, m_soundcpu, 3.579545_MHz_XTAL));
soundcpu.set_addrmap(AS_PROGRAM, &vigilant_state::sound_map);
soundcpu.set_addrmap(AS_IO, &vigilant_state::sound_io_map);
soundcpu.set_periodic_int(FUNC(vigilant_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1 */
/* IRQs are generated by main Z80 and YM2151 */
soundcpu.set_irq_acknowledge_callback("soundirq", FUNC(rst_neg_buffer_device::inta_cb));
TIMER(config, "v1").configure_scanline(FUNC(vigilant_state::sound_nmi), "screen", 1, 2);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(55);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(64*8, 32*8);
screen.set_visarea(8*8, (64-8)*8-1, 0*8, 32*8-1);
screen.set_raw(24_MHz_XTAL / 3, 64*8, 8*8, (64-8)*8, 284, 0, 256); // sync rates not verified
screen.set_screen_update(FUNC(vigilant_state::screen_update_kikcubic));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, 0, HOLD_LINE);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_kikcubic);
PALETTE(config, m_palette).set_entries(256);
@ -753,7 +755,7 @@ void vigilant_state::kikcubic(machine_config &config)
soundlatch.data_pending_callback().set("soundirq", FUNC(rst_neg_buffer_device::rst18_w));
soundlatch.set_separate_acknowledge(true);
RST_NEG_BUFFER(config, "soundirq", 0).int_callback().set_inputline("soundcpu", 0);
RST_NEG_BUFFER(config, "soundirq").int_callback().set_inputline(m_soundcpu, 0);
IREM_M72_AUDIO(config, m_audio);
m_audio->set_dac_tag("dac");
@ -775,23 +777,21 @@ void vigilant_state::bowmen(machine_config &config)
Z80(config, m_maincpu, 18_MHz_XTAL / 3); // 5.99538 MHz verified
m_maincpu->set_addrmap(AS_PROGRAM, &vigilant_state::vigilant_map);
m_maincpu->set_addrmap(AS_IO, &vigilant_state::bowmen_io_map);
m_maincpu->set_vblank_int("screen", FUNC(vigilant_state::irq0_line_hold));
z80_device &soundcpu(Z80(config, "soundcpu", 18_MHz_XTAL / 3)); // 5.99528 MHz verified
z80_device &soundcpu(Z80(config, m_soundcpu, 18_MHz_XTAL / 3)); // 5.99528 MHz verified
soundcpu.set_addrmap(AS_PROGRAM, &vigilant_state::sound_map);
soundcpu.set_addrmap(AS_IO, &vigilant_state::buccanrs_sound_io_map);
soundcpu.set_periodic_int(FUNC(vigilant_state::nmi_line_pulse), attotime::from_hz(7806.5)); // 7.80650 kHz measured
soundcpu.set_irq_acknowledge_callback("soundirq", FUNC(rst_neg_buffer_device::inta_cb));
TIMER(config, "v1").configure_scanline(FUNC(vigilant_state::sound_nmi), "screen", 1, 2); // 7.80650 kHz measured
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(55); // 54.9752 Hz verified
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
screen.set_size(64 * 8, 32 * 8);
screen.set_visarea(16 * 8, (64 - 16) * 8 - 1, 0 * 8, 32 * 8 - 1);
screen.set_raw(18_MHz_XTAL / 3, 384, 128, 384, 284, 0, 256); // 54.9752 Hz verified
screen.set_screen_update(FUNC(vigilant_state::screen_update_bowmen));
screen.set_palette(m_palette);
screen.screen_vblank().set_inputline(m_maincpu, 0, HOLD_LINE);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_bowmen);
PALETTE(config, m_palette).set_entries(512 + 32); // 512 real palette, 32 virtual palette
@ -804,30 +804,30 @@ void vigilant_state::bowmen(machine_config &config)
soundlatch.data_pending_callback().set("soundirq", FUNC(rst_neg_buffer_device::rst18_w));
soundlatch.set_separate_acknowledge(true);
RST_NEG_BUFFER(config, "soundirq", 0).int_callback().set_inputline("soundcpu", 0);
RST_NEG_BUFFER(config, "soundirq").int_callback().set_inputline(m_soundcpu, 0);
IREM_M72_AUDIO(config, m_audio);
m_audio->set_dac_tag("dac");
ym2203_device &ym1(YM2203(config, "ym1", 18_MHz_XTAL / 6));
ym1.irq_handler().set("soundirq", FUNC(rst_neg_buffer_device::rst28_w));
ym1.add_route(0, "lspeaker", 0.35);
ym1.add_route(0, "lspeaker", 0.35);
ym1.add_route(0, "rspeaker", 0.35);
ym1.add_route(1, "lspeaker", 0.35);
ym1.add_route(1, "lspeaker", 0.35);
ym1.add_route(1, "rspeaker", 0.35);
ym1.add_route(2, "lspeaker", 0.35);
ym1.add_route(2, "lspeaker", 0.35);
ym1.add_route(2, "rspeaker", 0.35);
ym1.add_route(3, "lspeaker", 0.50);
ym1.add_route(3, "lspeaker", 0.50);
ym1.add_route(3, "rspeaker", 0.50);
ym2203_device &ym2(YM2203(config, "ym2", 18_MHz_XTAL / 6));
ym2.add_route(0, "lspeaker", 0.35);
ym2.add_route(0, "lspeaker", 0.35);
ym2.add_route(0, "rspeaker", 0.35);
ym2.add_route(1, "lspeaker", 0.35);
ym2.add_route(1, "lspeaker", 0.35);
ym2.add_route(1, "rspeaker", 0.35);
ym2.add_route(2, "lspeaker", 0.35);
ym2.add_route(2, "lspeaker", 0.35);
ym2.add_route(2, "rspeaker", 0.35);
ym2.add_route(3, "lspeaker", 0.50);
ym2.add_route(3, "lspeaker", 0.50);
ym2.add_route(3, "rspeaker", 0.50);
dac_8bit_r2r_device &dac(DAC_8BIT_R2R(config, "dac", 0)); // unknown DAC

View File

@ -6,6 +6,7 @@
#pragma once
#include "audio/m72.h"
#include "machine/timer.h"
#include "emupal.h"
class vigilant_state : public driver_device
@ -14,6 +15,7 @@ public:
vigilant_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_soundcpu(*this, "soundcpu"),
m_audio(*this, "m72"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
@ -30,6 +32,7 @@ public:
private:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<m72_audio_device> m_audio;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@ -51,6 +54,7 @@ private:
// common
void bank_select_w(uint8_t data);
void paletteram_w(offs_t offset, uint8_t data);
TIMER_DEVICE_CALLBACK_MEMBER(sound_nmi);
// vigilant and buccanrs
void vigilant_out2_w(uint8_t data);