summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2021-08-31 23:44:44 +0200
committer hap <happppp@users.noreply.github.com>2021-08-31 23:45:14 +0200
commitf99b3f756ee917caf7c68a18d12799fbdfcb2af4 (patch)
treea6c1d2930e7b2b8c35839cc9cc2d1e823d520b1a
parentf3b2d781dee579cf6e816cbefff3b15340a02073 (diff)
segac2: decouple driver class from md_base_state
-rw-r--r--src/mame/drivers/segac2.cpp214
-rw-r--r--src/mame/includes/megadriv.h1
-rw-r--r--src/mame/machine/megadriv.cpp14
3 files changed, 110 insertions, 119 deletions
diff --git a/src/mame/drivers/segac2.cpp b/src/mame/drivers/segac2.cpp
index 4a35a56d4e3..1be460ff039 100644
--- a/src/mame/drivers/segac2.cpp
+++ b/src/mame/drivers/segac2.cpp
@@ -70,24 +70,24 @@
Razoola & Antiriad .. for helping teach me some 68k ASM needed to work out just why
the games were crashing :)
Sega for producing some Fantastic Games...
- The Japanese magazine that proudly previewed OOParts as "FARTS"
+ The Japanese magazine that proudly previewed OOPArts as "FARTS"
and anyone else who knows they've contributed :)
***********************************************************************************************/
-
#include "emu.h"
-#include "includes/megadriv.h"
#include "includes/segaipt.h"
#include "cpu/m68000/m68000.h"
#include "machine/nvram.h"
#include "machine/315_5296.h"
-#include "sound/okim6295.h"
#include "sound/sn76496.h"
#include "sound/upd7759.h"
#include "sound/ymopn.h"
+#include "video/315_5313.h"
+
#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
@@ -103,20 +103,21 @@ namespace {
typedef device_delegate<int (int in)> segac2_prot_delegate;
-// does this need to inherit from md_base? really we only need the VDP and some basics like the maincpu
-class segac2_state : public md_base_state
+class segac2_state : public driver_device
{
public:
segac2_state(const machine_config &mconfig, device_type type, const char *tag)
- : md_base_state(mconfig, type, tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
, m_paletteram(*this, "paletteram")
+ , m_vdp(*this, "gen_vdp")
+ , m_screen(*this, "screen")
, m_upd_region(*this, "upd")
- , m_prot_func(*this)
- , m_sound_banks(0)
, m_upd7759(*this, "upd")
- , m_screen(*this, "screen")
+ , m_ymsnd(*this, "ymsnd")
, m_palette(*this, "palette")
, m_io(*this, "io")
+ , m_prot_func(*this)
{ }
void segac2(machine_config &config);
@@ -152,8 +153,15 @@ protected:
int m_segac2_enable_display;
+ required_device<m68000_base_device> m_maincpu;
required_shared_ptr<uint16_t> m_paletteram;
+ required_device<sega315_5313_device> m_vdp;
+ required_device<screen_device> m_screen;
optional_memory_region m_upd_region;
+ optional_device<upd7759_device> m_upd7759;
+ required_device<ym3438_device> m_ymsnd;
+ required_device<palette_device> m_palette;
+ required_device<sega_315_5296_device> m_io;
/* protection-related tracking */
segac2_prot_delegate m_prot_func; /* emulation of protection chip */
@@ -169,7 +177,7 @@ protected:
/* sound-related variables */
uint8_t m_sound_banks; /* number of sound banks */
- void segac2_common_init(segac2_prot_delegate prot_func);
+ void set_prot_func(segac2_prot_delegate prot_func) { m_prot_func = prot_func; }
uint32_t screen_update_segac2_new(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
int m_segac2_bg_pal_lookup[4];
@@ -179,12 +187,13 @@ protected:
DECLARE_WRITE_LINE_MEMBER(vdp_sndirqline_callback_c2);
DECLARE_WRITE_LINE_MEMBER(vdp_lv6irqline_callback_c2);
DECLARE_WRITE_LINE_MEMBER(vdp_lv4irqline_callback_c2);
+ IRQ_CALLBACK_MEMBER(int_callback);
uint8_t io_portc_r();
void io_portd_w(uint8_t data);
void io_porth_w(uint8_t data);
- void segac2_upd7759_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ void segac2_upd7759_w(uint8_t data);
uint16_t palette_r(offs_t offset);
void palette_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void control_w(uint8_t data);
@@ -193,10 +202,6 @@ protected:
void counter_timer_w(uint8_t data);
uint16_t ichirjbl_prot_r();
DECLARE_WRITE_LINE_MEMBER(segac2_irq2_interrupt);
- optional_device<upd7759_device> m_upd7759;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
- required_device<sega_315_5296_device> m_io;
int prot_func_dummy(int in);
int prot_func_columns(int in);
@@ -217,7 +222,8 @@ protected:
int prot_func_puyopuy2(int in);
int prot_func_zunkyou(int in);
- void main_map(address_map &map);
+ void segac_map(address_map &map);
+ void segac2_map(address_map &map);
};
@@ -265,12 +271,7 @@ private:
/******************************************************************************
- Machine init
-*******************************************************************************
-
- This is called at init time, when it's safe to create a timer. We use
- it to prime the scanline interrupt timer.
-
+ Machine start/reset
******************************************************************************/
void segac2_state::machine_start()
@@ -278,14 +279,23 @@ void segac2_state::machine_start()
save_item(NAME(m_prot_write_buf));
save_item(NAME(m_prot_read_buf));
+ // determine how many sound banks
+ if (m_upd_region != nullptr)
+ m_sound_banks = m_upd_region->bytes() / 0x20000;
+ else
+ m_sound_banks = 0;
+
+ // init the VDP
+ m_vdp->set_use_cram(0); // C2 uses its own palette ram
+ m_vdp->set_vdp_pal(false);
+ m_vdp->set_framerate(60);
+ m_vdp->set_total_scanlines(262);
m_vdp->stop_timers();
}
void segac2_state::machine_reset()
{
-// megadriv_scanline_timer = machine().device<timer_device>("md_scan_timer");
-// megadriv_scanline_timer->adjust(attotime::zero);
m_segac2_bg_pal_lookup[0] = 0x00;
m_segac2_bg_pal_lookup[1] = 0x10;
m_segac2_bg_pal_lookup[2] = 0x20;
@@ -298,13 +308,6 @@ void segac2_state::machine_reset()
m_vdp->device_reset_old();
- /* determine how many sound banks */
- m_sound_banks = 0;
- if (m_upd_region != nullptr)
- {
- m_sound_banks = m_upd_region->bytes() / 0x20000;
- }
-
/* reset the protection */
m_prot_write_buf = 0;
m_prot_read_buf = 0;
@@ -332,19 +335,11 @@ void segac2_state::machine_reset()
******************************************************************************/
/* handle writes to the UPD7759 */
-void segac2_state::segac2_upd7759_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+void segac2_state::segac2_upd7759_w(uint8_t data)
{
- /* make sure we have a UPD chip */
- if (m_upd7759 == nullptr)
- return;
-
- /* only works if we're accessing the low byte */
- if (ACCESSING_BITS_0_7)
- {
- m_upd7759->port_w(data & 0xff);
- m_upd7759->start_w(0);
- m_upd7759->start_w(1);
- }
+ m_upd7759->port_w(data);
+ m_upd7759->start_w(0);
+ m_upd7759->start_w(1);
}
@@ -676,7 +671,7 @@ void pclub_state::print_club_camera_w(uint16_t data)
******************************************************************************/
-void segac2_state::main_map(address_map &map)
+void segac2_state::segac_map(address_map &map)
{
map(0x000000, 0x1fffff).rom();
map(0x800001, 0x800001).mirror(0x13fdfe).rw(FUNC(segac2_state::prot_r), FUNC(segac2_state::prot_w));
@@ -689,6 +684,12 @@ void segac2_state::main_map(address_map &map)
map(0xe00000, 0xe0ffff).mirror(0x1f0000).ram().share("nvram");
}
+void segac2_state::segac2_map(address_map &map)
+{
+ segac_map(map);
+ map(0x880000, 0x880001).mirror(0x13fefe).w(FUNC(segac2_state::segac2_upd7759_w)).umask16(0x00ff);
+}
+
/******************************************************************************
Input Ports
@@ -1647,30 +1648,14 @@ INPUT_PORTS_END
/******************************************************************************
- Sound interfaces
-******************************************************************************/
-
-WRITE_LINE_MEMBER(segac2_state::segac2_irq2_interrupt)
-{
- //printf("sound irq %d\n", state);
- m_maincpu->set_input_line(2, state ? ASSERT_LINE : CLEAR_LINE);
-}
-
-
-/******************************************************************************
- Machine Drivers
+ Screen update
*******************************************************************************
- General Overview
- M68000 @ 10MHz (Main Processor)
- YM3438 (Fm Sound)
- SN76489 (PSG, Noise, Part of the VDP)
- UPD7759 (Sample Playback, C-2 Only)
+ C2 doesn't use the internal VDP CRAM, instead it uses the digital
+ output of the chip and applies it's own external colour circuity.
******************************************************************************/
-// C2 doesn't use the internal VDP CRAM, instead it uses the digital output of the chip
-// and applies it's own external colour circuity
uint32_t segac2_state::screen_update_segac2_new(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
const pen_t *paldata = m_palette->pens();
@@ -1728,6 +1713,16 @@ uint32_t segac2_state::screen_update_segac2_new(screen_device &screen, bitmap_rg
}
+/******************************************************************************
+ Interrupt handling
+******************************************************************************/
+
+WRITE_LINE_MEMBER(segac2_state::segac2_irq2_interrupt)
+{
+ //printf("sound irq %d\n", state);
+ m_maincpu->set_input_line(2, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
// the main interrupt on C2 comes from the vdp line used to drive the z80 interrupt on a regular genesis(!)
WRITE_LINE_MEMBER(segac2_state::vdp_sndirqline_callback_c2)
{
@@ -1750,18 +1745,39 @@ WRITE_LINE_MEMBER(segac2_state::vdp_lv4irqline_callback_c2)
m_maincpu->set_input_line(4, CLEAR_LINE);
}
-/*
+/* Callback when the 68k takes an IRQ */
+IRQ_CALLBACK_MEMBER(segac2_state::int_callback)
+{
+ if (irqline == 4)
+ m_vdp->vdp_clear_irq4_pending();
+
+ return (0x60 + irqline * 4) / 4; // vector address
+}
+
+
+/******************************************************************************
+ Machine Drivers
+*******************************************************************************
+
+ General Overview
+ M68000 @ 10MHz (Main Processor)
+ YM3438 (Fm Sound)
+ SN76489 (PSG, Noise, Part of the VDP)
+ UPD7759 (Sample Playback, C-2 Only)
+
sound output balance (tfrceac)
reference 1: https://youtu.be/AOmeWp9qe5E
reference 2: https://youtu.be/Tq8VkJYmij8
reference 3: https://youtu.be/VId_HWdNuyA
-*/
+
+******************************************************************************/
+
void segac2_state::segac(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XL2_CLOCK/6);
- m_maincpu->set_addrmap(AS_PROGRAM, &segac2_state::main_map);
- m_maincpu->set_irq_acknowledge_callback(FUNC(md_base_state::genesis_int_callback));
+ m_maincpu->set_addrmap(AS_PROGRAM, &segac2_state::segac_map);
+ m_maincpu->set_irq_acknowledge_callback(FUNC(segac2_state::int_callback));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1); // borencha requires 0xff fill or there is no sound (it lacks some of the init code of the borench set)
@@ -1794,16 +1810,15 @@ void segac2_state::segac(machine_config &config)
m_screen->set_size(512, 262);
m_screen->set_visarea(0, 32*8-1, 0, 28*8-1);
m_screen->set_screen_update(FUNC(segac2_state::screen_update_segac2_new));
- m_screen->screen_vblank().set(FUNC(segac2_state::screen_vblank_megadriv));
PALETTE(config, m_palette).set_entries(2048*3);
/* sound hardware */
SPEAKER(config, "mono").front_center();
- ym3438_device &ymsnd(YM3438(config, "ymsnd", XL2_CLOCK/7));
- ymsnd.irq_handler().set(FUNC(segac2_state::segac2_irq2_interrupt));
- ymsnd.add_route(0, "mono", 0.50);
+ YM3438(config, m_ymsnd, XL2_CLOCK/7);
+ m_ymsnd->irq_handler().set(FUNC(segac2_state::segac2_irq2_interrupt));
+ m_ymsnd->add_route(0, "mono", 0.50);
/* right channel not connected */
}
@@ -1812,6 +1827,7 @@ void segac2_state::segac2(machine_config &config)
segac(config);
/* basic machine hardware */
+ m_maincpu->set_addrmap(AS_PROGRAM, &segac2_state::segac2_map);
subdevice<sega_315_5296_device>("io")->out_cnt1_callback().set(m_upd7759, FUNC(upd7759_device::reset_w));
/* sound hardware */
@@ -2435,15 +2451,6 @@ it should be, otherwise I don't see how the formula could be computed.
******************************************************************************/
-void segac2_state::segac2_common_init(segac2_prot_delegate prot_func)
-{
- init_megadriv_c2();
- m_prot_func = prot_func;
-
- if (m_upd7759 != nullptr)
- m_maincpu->space(AS_PROGRAM).install_write_handler(0x880000, 0x880001, 0, 0x13fefe, 0, write16s_delegate(*this, FUNC(segac2_state::segac2_upd7759_w)));
-}
-
int segac2_state::prot_func_dummy(int in)
{
return 0x0;
@@ -2671,25 +2678,24 @@ int pclub_state::prot_func_pclubjv5(int in)
}
-
void segac2_state::init_noprot()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_dummy)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_dummy)));
}
void segac2_state::init_columns()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_columns)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_columns)));
}
void segac2_state::init_columns2()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_columns2)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_columns2)));
}
void segac2_state::init_tfrceac()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tfrceac)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tfrceac)));
}
void segac2_state::init_tfrceacb()
@@ -2702,62 +2708,62 @@ void segac2_state::init_tfrceacb()
void segac2_state::init_borench()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_borench)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_borench)));
}
void segac2_state::init_twinsqua()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_twinsqua)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_twinsqua)));
}
void segac2_state::init_ribbit()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ribbit)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ribbit)));
}
void segac2_state::init_puyo()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_puyo)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_puyo)));
}
void segac2_state::init_tantr()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tantr)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tantr)));
}
void segac2_state::init_tantrkor()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tantrkor)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_tantrkor)));
}
void segac2_state::init_potopoto()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_potopoto)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_potopoto)));
}
void segac2_state::init_stkclmns()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_stkclmns)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_stkclmns)));
}
void segac2_state::init_stkclmnj()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_stkclmnj)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_stkclmnj)));
}
void segac2_state::init_ichir()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichir)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichir)));
}
void segac2_state::init_ichirk()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichirk)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichirk)));
}
void segac2_state::init_ichirj()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichirj)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_ichirj)));
}
uint16_t segac2_state::ichirjbl_prot_r()
@@ -2774,12 +2780,12 @@ void segac2_state::init_ichirjbl()
void segac2_state::init_puyopuy2()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_puyopuy2)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_puyopuy2)));
}
void segac2_state::init_zunkyou()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_zunkyou)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(segac2_state::prot_func_zunkyou)));
}
void pclub_state::init_pclub()
@@ -2791,25 +2797,25 @@ void pclub_state::init_pclub()
void pclub_state::init_pclubj()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclub)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclub)));
init_pclub();
}
void pclub_state::init_pclubjv2()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv2)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv2)));
init_pclub();
}
void pclub_state::init_pclubjv4()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv4)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv4)));
init_pclub();
}
void pclub_state::init_pclubjv5()
{
- segac2_common_init(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv5)));
+ set_prot_func(segac2_prot_delegate(*this, FUNC(pclub_state::prot_func_pclubjv5)));
init_pclub();
}
diff --git a/src/mame/includes/megadriv.h b/src/mame/includes/megadriv.h
index 35217cf5bc7..ddaecb717e8 100644
--- a/src/mame/includes/megadriv.h
+++ b/src/mame/includes/megadriv.h
@@ -73,7 +73,6 @@ struct genesis_z80_vars
genesis_z80_vars m_genz80;
int m_version_hi_nibble;
- void init_megadriv_c2();
void init_megadrie();
void init_megadriv();
void init_megadrij();
diff --git a/src/mame/machine/megadriv.cpp b/src/mame/machine/megadriv.cpp
index b1f609a2d6f..320fd0677fb 100644
--- a/src/mame/machine/megadriv.cpp
+++ b/src/mame/machine/megadriv.cpp
@@ -1033,20 +1033,6 @@ void md_base_state::megadriv_init_common()
m_megadrive_io_write_data_port_ptr = write16sm_delegate(*this, FUNC(md_base_state::megadrive_io_write_data_port_3button));
}
-void md_base_state::init_megadriv_c2()
-{
- megadriv_init_common();
-
- m_vdp->set_use_cram(0); // C2 uses its own palette ram
- m_vdp->set_vdp_pal(false);
- m_vdp->set_framerate(60);
- m_vdp->set_total_scanlines(262);
-
- m_version_hi_nibble = 0x20; // JPN NTSC no-SCD
-}
-
-
-
void md_base_state::init_megadriv()
{
megadriv_init_common();