diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 5c1260a4472..35052eae70f 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -1759,6 +1759,7 @@ files { MAME_DIR .. "src/mame/video/excellent_spr.cpp", MAME_DIR .. "src/mame/video/excellent_spr.h", MAME_DIR .. "src/mame/drivers/lastbank.cpp", + MAME_DIR .. "src/mame/includes/witch.h", MAME_DIR .. "src/mame/drivers/witch.cpp", } diff --git a/src/mame/drivers/witch.cpp b/src/mame/drivers/witch.cpp index 9963d161e71..969eff12feb 100644 --- a/src/mame/drivers/witch.cpp +++ b/src/mame/drivers/witch.cpp @@ -217,134 +217,11 @@ Interesting memory locations TODO : - Figure out the ports for the "PayOut" stuff (a006/a00c?); - Hook up the OKI M5202; - - keirinou: sprite colors, controlled by an undumped PROM? - No data in available palette RAM seems to fit; - - merge memory maps; + - lagging sprites on witch (especially noticeable when game scrolls up/down) */ #include "emu.h" - -#include "cpu/z80/z80.h" -#include "machine/i8255.h" -#include "machine/nvram.h" -#include "machine/ticket.h" -#include "sound/ay8910.h" -#include "sound/2203intf.h" -#include "sound/es8712.h" - -#include "screen.h" -#include "speaker.h" - - -#define MAIN_CLOCK XTAL(12'000'000) -#define CPU_CLOCK MAIN_CLOCK / 4 -#define YM2203_CLOCK MAIN_CLOCK / 4 -#define AY8910_CLOCK MAIN_CLOCK / 8 -#define MSM5202_CLOCK 384_kHz_XTAL - -#define HOPPER_PULSE 50 // time between hopper pulses in milliseconds (not right for attendant pay) - - -class witch_state : public driver_device -{ -public: - witch_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_subcpu(*this, "sub") - , m_gfxdecode(*this, "gfxdecode") - , m_gfx0_vram(*this, "gfx0_vram") - , m_gfx0_cram(*this, "gfx0_cram") - , m_gfx1_vram(*this, "gfx1_vram") - , m_gfx1_cram(*this, "gfx1_cram") - , m_sprite_ram(*this, "sprite_ram") - , m_palette(*this, "palette") - , m_hopper(*this, "hopper") - , m_mainbank(*this, "mainbank") - { } - - tilemap_t *m_gfx0a_tilemap; - tilemap_t *m_gfx0b_tilemap; - tilemap_t *m_gfx1_tilemap; - - required_device m_maincpu; - required_device m_subcpu; - required_device m_gfxdecode; - - required_shared_ptr m_gfx0_vram; - required_shared_ptr m_gfx0_cram; - required_shared_ptr m_gfx1_vram; - required_shared_ptr m_gfx1_cram; - required_shared_ptr m_sprite_ram; - required_device m_palette; - - required_device m_hopper; - - optional_memory_bank m_mainbank; - - int m_scrollx; - int m_scrolly; - uint8_t m_reg_a002; - uint8_t m_motor_active; - DECLARE_WRITE8_MEMBER(gfx0_vram_w); - DECLARE_WRITE8_MEMBER(gfx0_cram_w); - DECLARE_WRITE8_MEMBER(gfx1_vram_w); - DECLARE_WRITE8_MEMBER(gfx1_cram_w); - DECLARE_READ8_MEMBER(gfx1_vram_r); - DECLARE_READ8_MEMBER(gfx1_cram_r); - DECLARE_READ8_MEMBER(read_a000); - DECLARE_WRITE8_MEMBER(write_a002); - DECLARE_WRITE8_MEMBER(write_a006); - DECLARE_WRITE8_MEMBER(main_write_a008); - DECLARE_WRITE8_MEMBER(sub_write_a008); - DECLARE_READ8_MEMBER(prot_read_700x); - DECLARE_WRITE8_MEMBER(xscroll_w); - DECLARE_WRITE8_MEMBER(yscroll_w); - DECLARE_DRIVER_INIT(witch); - TILE_GET_INFO_MEMBER(get_gfx0b_tile_info); - TILE_GET_INFO_MEMBER(get_gfx0a_tile_info); - TILE_GET_INFO_MEMBER(get_gfx1_tile_info); - virtual void video_start() override; - uint32_t screen_update_witch(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); - virtual void machine_reset() override; - void witch(machine_config &config); - void map_main(address_map &map); - void map_sub(address_map &map); - -protected: - void video_common_init(); - bool has_spr_rom_bank; - uint8_t m_spr_bank; -}; - -class keirinou_state : public witch_state -{ -public: - keirinou_state(const machine_config &mconfig, device_type type, const char *tag) - : witch_state(mconfig, type, tag), - m_paletteram(*this, "paletteram") - { } - - void keirinou_main_map(address_map &map); - void keirinou_sub_map(address_map &map); - - void keirinou(machine_config &config); - DECLARE_WRITE8_MEMBER(write_keirinou_a002); - DECLARE_WRITE8_MEMBER(palette_w); - TILE_GET_INFO_MEMBER(get_keirinou_gfx1_tile_info); - -protected: - virtual void video_start() override; - -private: - uint8_t m_bg_bank; - required_shared_ptr m_paletteram; - -}; - - -#define UNBANKED_SIZE 0x800 +#include "includes/witch.h" TILE_GET_INFO_MEMBER(witch_state::get_gfx0b_tile_info) @@ -574,7 +451,6 @@ WRITE8_MEMBER(witch_state::write_a002) WRITE8_MEMBER(keirinou_state::write_keirinou_a002) { uint8_t new_bg_bank; - //A002 bit 7&6 = m_bank ???? m_reg_a002 = data; m_spr_bank = BIT(data,7); @@ -681,22 +557,36 @@ WRITE8_MEMBER(keirinou_state::palette_w) } } +/********************************************** + * + * Base address map + * + *********************************************/ -void witch_state::map_main(address_map &map) +void witch_state::common_map(address_map &map) { - map(0x0000, UNBANKED_SIZE-1).rom(); - map(UNBANKED_SIZE, 0x7fff).bankr("mainbank"); - map(0x8000, 0x8001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); - map(0x8008, 0x8009).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); map(0xa000, 0xa003).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); map(0xa004, 0xa007).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0xa008, 0xa008).w(this, FUNC(witch_state::main_write_a008)); map(0xa00c, 0xa00c).portr("SERVICE"); // stats / reset map(0xa00e, 0xa00e).portr("COINS"); // coins/attendant keys map(0xc000, 0xc3ff).ram().w(this, FUNC(witch_state::gfx0_vram_w)).share("gfx0_vram"); map(0xc400, 0xc7ff).ram().w(this, FUNC(witch_state::gfx0_cram_w)).share("gfx0_cram"); map(0xc800, 0xcbff).rw(this, FUNC(witch_state::gfx1_vram_r), FUNC(witch_state::gfx1_vram_w)).share("gfx1_vram"); map(0xcc00, 0xcfff).rw(this, FUNC(witch_state::gfx1_cram_r), FUNC(witch_state::gfx1_cram_w)).share("gfx1_cram"); +} + +/************************************ + * + * Witch address maps + * + ***********************************/ + +void witch_state::witch_common_map(address_map &map) +{ + common_map(map); + map(0x8000, 0x8001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); + map(0x8008, 0x8009).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); + map(0x8010, 0x8016).rw("essnd", FUNC(es8712_device::read), FUNC(es8712_device::write)); map(0xd000, 0xdfff).ram().share("sprite_ram"); map(0xe000, 0xe7ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); map(0xe800, 0xefff).ram().w(m_palette, FUNC(palette_device::write8_ext)).share("palette_ext"); @@ -705,55 +595,51 @@ void witch_state::map_main(address_map &map) map(0xf200, 0xffff).ram().share("share2"); } - -void witch_state::map_sub(address_map &map) +void witch_state::witch_main_map(address_map &map) { + witch_common_map(map); + map(0x0000, UNBANKED_SIZE-1).rom(); + map(UNBANKED_SIZE, 0x7fff).bankr("mainbank"); + map(0xa008, 0xa008).w(this, FUNC(witch_state::main_write_a008)); +} + + +void witch_state::witch_sub_map(address_map &map) +{ + witch_common_map(map); map(0x0000, 0x7fff).rom(); - map(0x8000, 0x8001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); - map(0x8008, 0x8009).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); - map(0x8010, 0x8016).rw("essnd", FUNC(es8712_device::read), FUNC(es8712_device::write)); - map(0xa000, 0xa003).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0xa004, 0xa007).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); map(0xa008, 0xa008).w(this, FUNC(witch_state::sub_write_a008)); - map(0xa00c, 0xa00c).portr("SERVICE"); // stats / reset - map(0xf000, 0xf0ff).ram().share("share1"); - map(0xf200, 0xffff).ram().share("share2"); +} + +/************************************ + * + * Keirin Ou address maps + * + ***********************************/ + +void keirinou_state::keirinou_common_map(address_map &map) +{ + common_map(map); + map(0x8000, 0x8001).rw("ay1", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); + map(0x8002, 0x8003).rw("ay2", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); + map(0xd000, 0xd7ff).ram().share("sprite_ram"); + map(0xd800, 0xd9ff).ram().w(this, FUNC(keirinou_state::palette_w)).share("paletteram"); + map(0xe000, 0xe7ff).ram(); + map(0xe800, 0xefff).ram().share("nvram"); // shared with sub } void keirinou_state::keirinou_main_map(address_map &map) { + keirinou_common_map(map); map(0x0000, 0x7fff).rom(); - map(0x8000, 0x8001).rw("ay1", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); - map(0x8002, 0x8003).rw("ay2", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); - map(0xa000, 0xa003).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0xa004, 0xa007).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); map(0xa008, 0xa008).w(this, FUNC(witch_state::main_write_a008)); - map(0xa00c, 0xa00c).portr("SERVICE"); // stats / reset - map(0xa00e, 0xa00e).portr("COINS"); // coins/attendant keys - map(0xc000, 0xc3ff).ram().w(this, FUNC(witch_state::gfx0_vram_w)).share("gfx0_vram"); - map(0xc400, 0xc7ff).ram().w(this, FUNC(witch_state::gfx0_cram_w)).share("gfx0_cram"); - map(0xc800, 0xcbff).rw(this, FUNC(witch_state::gfx1_vram_r), FUNC(witch_state::gfx1_vram_w)).share("gfx1_vram"); - map(0xcc00, 0xcfff).rw(this, FUNC(witch_state::gfx1_cram_r), FUNC(witch_state::gfx1_cram_w)).share("gfx1_cram"); - map(0xd000, 0xd7ff).ram().share("sprite_ram"); - map(0xd800, 0xd9ff).ram().w(this, FUNC(keirinou_state::palette_w)).share("paletteram"); - map(0xe000, 0xe7ff).ram();//.share("share1"); - map(0xe800, 0xefff).ram().share("nvram"); } void keirinou_state::keirinou_sub_map(address_map &map) { + keirinou_common_map(map); map(0x0000, 0x7fff).rom(); - map(0x8000, 0x8001).rw("ay1", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); - map(0x8002, 0x8003).rw("ay2", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w)); - map(0xa000, 0xa003).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0xa004, 0xa007).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); map(0xa008, 0xa008).w(this, FUNC(witch_state::sub_write_a008)); - map(0xa00c, 0xa00c).portr("SERVICE"); // stats / reset - // shared VRAM used for lower portion of ingame background tilemap - map(0xc800, 0xcbff).rw(this, FUNC(witch_state::gfx1_vram_r), FUNC(witch_state::gfx1_vram_w)).share("gfx1_vram"); - map(0xcc00, 0xcfff).rw(this, FUNC(witch_state::gfx1_cram_r), FUNC(witch_state::gfx1_cram_w)).share("gfx1_cram"); - map(0xe000, 0xe7ff).ram();//.share("share1"); - map(0xe800, 0xefff).ram().share("nvram"); } static INPUT_PORTS_START( witch ) @@ -956,22 +842,22 @@ static INPUT_PORTS_START( keirinou ) // TODO: dipswitches PORT_MODIFY("YM_PortA") - PORT_DIPNAME( 0x01, 0x01, "DSWA" ) - PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x07, 0x07, "Game Rate" ) + PORT_DIPSETTING( 0x02, "70%" ) + PORT_DIPSETTING( 0x07, "80%" ) + PORT_DIPSETTING( 0x06, "85%" ) + PORT_DIPSETTING( 0x05, "90%" ) + PORT_DIPSETTING( 0x04, "95%" ) + PORT_DIPSETTING( 0x03, "100%" ) +// PORT_DIPSETTING( 0x01, "80%" ) +// PORT_DIPSETTING( 0x00, "90%" ) + PORT_DIPNAME( 0x08, 0x08, "Double-Up Rate" ) + PORT_DIPSETTING( 0x08, "90%" ) + PORT_DIPSETTING( 0x00, "100%" ) PORT_DIPNAME( 0x10, 0x00, "Double-Up Game" ) PORT_DIPSETTING( 0x10, DEF_STR( No ) ) PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x20, 0x20, "DSWA" ) PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) @@ -1066,12 +952,12 @@ void witch_state::machine_reset() MACHINE_CONFIG_START(witch_state::witch) /* basic machine hardware */ MCFG_DEVICE_ADD("maincpu", Z80, CPU_CLOCK) /* 3 MHz */ - MCFG_DEVICE_PROGRAM_MAP(map_main) + MCFG_DEVICE_PROGRAM_MAP(witch_main_map) MCFG_DEVICE_VBLANK_INT_DRIVER("screen", witch_state, irq0_line_assert) /* 2nd z80 */ MCFG_DEVICE_ADD("sub", Z80, CPU_CLOCK) /* 3 MHz */ - MCFG_DEVICE_PROGRAM_MAP(map_sub) + MCFG_DEVICE_PROGRAM_MAP(witch_sub_map) MCFG_DEVICE_VBLANK_INT_DRIVER("screen", witch_state, irq0_line_assert) MCFG_QUANTUM_TIME(attotime::from_hz(6000)) diff --git a/src/mame/includes/witch.h b/src/mame/includes/witch.h new file mode 100644 index 00000000000..22cd42a8e84 --- /dev/null +++ b/src/mame/includes/witch.h @@ -0,0 +1,135 @@ +// license:BSD-3-Clause +// copyright-holders:Tomasz Slanina +/* + +Witch / Pinball Champ '95 / Keirin Ou + +*/ + +#ifndef MAME_INCLUDES_WITCH_H +#define MAME_INCLUDES_WITCH_H + + +#include "cpu/z80/z80.h" +#include "machine/i8255.h" +#include "machine/nvram.h" +#include "machine/ticket.h" +#include "sound/ay8910.h" +#include "sound/2203intf.h" +#include "sound/es8712.h" +#include "screen.h" +#include "speaker.h" + +#define MAIN_CLOCK XTAL(12'000'000) +#define CPU_CLOCK MAIN_CLOCK / 4 +#define YM2203_CLOCK MAIN_CLOCK / 4 +#define AY8910_CLOCK MAIN_CLOCK / 8 +#define MSM5202_CLOCK 384_kHz_XTAL + +#define HOPPER_PULSE 50 // time between hopper pulses in milliseconds (not right for attendant pay) +#define UNBANKED_SIZE 0x800 + + +class witch_state : public driver_device +{ +public: + witch_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_subcpu(*this, "sub") + , m_gfxdecode(*this, "gfxdecode") + , m_gfx0_vram(*this, "gfx0_vram") + , m_gfx0_cram(*this, "gfx0_cram") + , m_gfx1_vram(*this, "gfx1_vram") + , m_gfx1_cram(*this, "gfx1_cram") + , m_sprite_ram(*this, "sprite_ram") + , m_palette(*this, "palette") + , m_hopper(*this, "hopper") + , m_mainbank(*this, "mainbank") + { } + + tilemap_t *m_gfx0a_tilemap; + tilemap_t *m_gfx0b_tilemap; + tilemap_t *m_gfx1_tilemap; + + required_device m_maincpu; + required_device m_subcpu; + required_device m_gfxdecode; + + required_shared_ptr m_gfx0_vram; + required_shared_ptr m_gfx0_cram; + required_shared_ptr m_gfx1_vram; + required_shared_ptr m_gfx1_cram; + required_shared_ptr m_sprite_ram; + required_device m_palette; + + required_device m_hopper; + + optional_memory_bank m_mainbank; + + int m_scrollx; + int m_scrolly; + uint8_t m_reg_a002; + uint8_t m_motor_active; + DECLARE_WRITE8_MEMBER(gfx0_vram_w); + DECLARE_WRITE8_MEMBER(gfx0_cram_w); + DECLARE_WRITE8_MEMBER(gfx1_vram_w); + DECLARE_WRITE8_MEMBER(gfx1_cram_w); + DECLARE_READ8_MEMBER(gfx1_vram_r); + DECLARE_READ8_MEMBER(gfx1_cram_r); + DECLARE_READ8_MEMBER(read_a000); + DECLARE_WRITE8_MEMBER(write_a002); + DECLARE_WRITE8_MEMBER(write_a006); + DECLARE_WRITE8_MEMBER(main_write_a008); + DECLARE_WRITE8_MEMBER(sub_write_a008); + DECLARE_READ8_MEMBER(prot_read_700x); + DECLARE_WRITE8_MEMBER(xscroll_w); + DECLARE_WRITE8_MEMBER(yscroll_w); + DECLARE_DRIVER_INIT(witch); + TILE_GET_INFO_MEMBER(get_gfx0b_tile_info); + TILE_GET_INFO_MEMBER(get_gfx0a_tile_info); + TILE_GET_INFO_MEMBER(get_gfx1_tile_info); + virtual void video_start() override; + uint32_t screen_update_witch(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + virtual void machine_reset() override; + void witch(machine_config &config); + void common_map(address_map &map); + void witch_common_map(address_map &map); + void witch_main_map(address_map &map); + void witch_sub_map(address_map &map); + +protected: + void video_common_init(); + bool has_spr_rom_bank; + uint8_t m_spr_bank; +}; + +class keirinou_state : public witch_state +{ +public: + keirinou_state(const machine_config &mconfig, device_type type, const char *tag) + : witch_state(mconfig, type, tag), + m_paletteram(*this, "paletteram") + { } + + void keirinou_common_map(address_map &map); + void keirinou_main_map(address_map &map); + void keirinou_sub_map(address_map &map); + + void keirinou(machine_config &config); + DECLARE_WRITE8_MEMBER(write_keirinou_a002); + DECLARE_WRITE8_MEMBER(palette_w); + TILE_GET_INFO_MEMBER(get_keirinou_gfx1_tile_info); + +protected: + virtual void video_start() override; + +private: + uint8_t m_bg_bank; + required_shared_ptr m_paletteram; + +}; + + +#endif