mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Moved the calls on cpu lines from hardcoded in the vdp to callbacks the drivers can provide. This sllows us to connect the correct line for vblank in segac2 without the previous hack. Also looking to untangle the screen timing a bit. From Haze (nw)
This commit is contained in:
parent
40759800a0
commit
9b06eb16c6
@ -1278,6 +1278,30 @@ static SCREEN_UPDATE_RGB32(segac2_new)
|
||||
}
|
||||
|
||||
|
||||
// the main interrupt on C2 comes from the vdp line used to drive the z80 interrupt on a regular genesis(!)
|
||||
void genesis_vdp_sndirqline_callback_segac2(running_machine &machine, bool state)
|
||||
{
|
||||
if (state==true)
|
||||
cputag_set_input_line(machine, "maincpu", 6, HOLD_LINE);
|
||||
}
|
||||
|
||||
// the line usually used to drive irq6 is not connected
|
||||
void genesis_vdp_lv6irqline_callback_segac2(running_machine &machine, bool state)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// the scanline interrupt seems connected as usual
|
||||
void genesis_vdp_lv4irqline_callback_segac2(running_machine &machine, bool state)
|
||||
{
|
||||
if (state==true)
|
||||
cputag_set_input_line(machine, "maincpu", 4, HOLD_LINE);
|
||||
else
|
||||
cputag_set_input_line(machine, "maincpu", 4, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( segac, segac2_state )
|
||||
|
||||
/* basic machine hardware */
|
||||
@ -1291,6 +1315,9 @@ static MACHINE_CONFIG_START( segac, segac2_state )
|
||||
MCFG_FRAGMENT_ADD(megadriv_timers)
|
||||
|
||||
MCFG_DEVICE_ADD("gen_vdp", SEGA_GEN_VDP, 0)
|
||||
sega_genesis_vdp_device::set_genesis_vdp_sndirqline_callback(*device, genesis_vdp_sndirqline_callback_segac2);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv6irqline_callback(*device, genesis_vdp_lv6irqline_callback_segac2);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv4irqline_callback(*device, genesis_vdp_lv4irqline_callback_segac2);
|
||||
|
||||
MCFG_SCREEN_ADD("megadriv", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
@ -1762,7 +1789,6 @@ void segac2_state::segac2_common_init(running_machine& machine, int (*func)(int
|
||||
state->m_prot_func = func;
|
||||
|
||||
genvdp_use_cram = 0;
|
||||
genesis_always_irq6 = 1;
|
||||
genesis_other_hacks = 0;
|
||||
|
||||
if (upd != NULL)
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "machine/nvram.h"
|
||||
#include "cpu/ssp1601/ssp1601.h"
|
||||
|
||||
#include "machine/megavdp.h"
|
||||
|
||||
#define MASTER_CLOCK_NTSC 53693175
|
||||
#define MASTER_CLOCK_PAL 53203424
|
||||
#define SEGACD_CLOCK 12500000
|
||||
@ -98,7 +100,6 @@ extern int segac2_bg_pal_lookup[4];
|
||||
extern int segac2_sp_pal_lookup[4];
|
||||
|
||||
extern int genvdp_use_cram;
|
||||
extern int genesis_always_irq6;
|
||||
extern int genesis_other_hacks;
|
||||
|
||||
extern int megadrive_6buttons_pad;
|
||||
@ -115,8 +116,11 @@ class md_base_state : public driver_device
|
||||
{
|
||||
public:
|
||||
md_base_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag) { }
|
||||
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_vdp(*this,"gen_vdp")
|
||||
{ }
|
||||
required_device<sega_genesis_vdp_device> m_vdp;
|
||||
|
||||
DECLARE_DRIVER_INIT(megadriv_c2);
|
||||
DECLARE_DRIVER_INIT(megadrie);
|
||||
DECLARE_DRIVER_INIT(megadriv);
|
||||
|
@ -53,11 +53,9 @@ Known Non-Issues (confirmed on Real Genesis)
|
||||
|
||||
|
||||
static cpu_device *_genesis_snd_z80_cpu;
|
||||
int genesis_other_hacks = 0; // misc hacks
|
||||
|
||||
timer_device* megadriv_scanline_timer;
|
||||
timer_device* irq6_on_timer;
|
||||
timer_device* irq4_on_timer;
|
||||
//emu_timer* vblankirq_off_timer;
|
||||
|
||||
|
||||
genesis_z80_vars genz80;
|
||||
@ -955,11 +953,6 @@ SCREEN_UPDATE_RGB32(megadriv)
|
||||
|
||||
|
||||
|
||||
static TIMER_DEVICE_CALLBACK( irq4_on_callback )
|
||||
{
|
||||
//mame_printf_debug("irq4 active on %d\n",genesis_scanline_counter);
|
||||
cputag_set_input_line(timer.machine(), "maincpu", 4, HOLD_LINE);
|
||||
}
|
||||
|
||||
/*****************************************************************************************/
|
||||
|
||||
@ -992,10 +985,7 @@ MACHINE_RESET( megadriv )
|
||||
megadrive_reset_io(machine);
|
||||
|
||||
megadriv_scanline_timer = machine.device<timer_device>("md_scan_timer");
|
||||
megadriv_render_timer = machine.device<timer_device>("md_render_timer");
|
||||
|
||||
irq6_on_timer = machine.device<timer_device>("irq6_timer");
|
||||
irq4_on_timer = machine.device<timer_device>("irq4_timer");
|
||||
|
||||
megadriv_scanline_timer->adjust(attotime::zero);
|
||||
|
||||
@ -1039,15 +1029,6 @@ void megadriv_stop_scanline_timer(void)
|
||||
megadriv_scanline_timer->reset();
|
||||
}
|
||||
|
||||
/*
|
||||
999999999999999960
|
||||
1000000000000000000 subseconds = 1 second
|
||||
|
||||
/ 60
|
||||
|
||||
*/
|
||||
|
||||
/* VIDEO_EOF is used to resync the scanline counters */
|
||||
|
||||
|
||||
UINT16* megadriv_backupram;
|
||||
@ -1076,11 +1057,43 @@ static NVRAM_HANDLER( megadriv )
|
||||
}
|
||||
|
||||
|
||||
// this comes from the VDP on lines 240 (on) 241 (off) and is connected to the z80 irq 0
|
||||
void genesis_vdp_sndirqline_callback_genesis_z80(running_machine &machine, bool state)
|
||||
{
|
||||
if (machine.device(":genesis_snd_z80") != NULL)
|
||||
{
|
||||
if (state == true)
|
||||
{
|
||||
megadriv_z80_hold(machine);
|
||||
}
|
||||
else if (state == false)
|
||||
{
|
||||
megadriv_z80_clear(machine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this comes from the vdp, and is connected to 68k irq level 6 (main vbl interrupt)
|
||||
void genesis_vdp_lv6irqline_callback_genesis_68k(running_machine &machine, bool state)
|
||||
{
|
||||
if (state==true)
|
||||
cputag_set_input_line(machine, "maincpu", 6, HOLD_LINE);
|
||||
else
|
||||
cputag_set_input_line(machine, "maincpu", 6, CLEAR_LINE);
|
||||
}
|
||||
|
||||
// this comes from the vdp, and is connected to 68k irq level 4 (raster interrupt)
|
||||
void genesis_vdp_lv4irqline_callback_genesis_68k(running_machine &machine, bool state)
|
||||
{
|
||||
if (state==true)
|
||||
cputag_set_input_line(machine, "maincpu", 4, HOLD_LINE);
|
||||
else
|
||||
cputag_set_input_line(machine, "maincpu", 4, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
MACHINE_CONFIG_FRAGMENT( megadriv_timers )
|
||||
MCFG_TIMER_ADD("md_scan_timer", megadriv_scanline_timer_callback)
|
||||
MCFG_TIMER_ADD("md_render_timer", megadriv_render_timer_callback)
|
||||
MCFG_TIMER_ADD("irq6_timer", irq6_on_callback)
|
||||
MCFG_TIMER_ADD("irq4_timer", irq4_on_callback)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -1100,6 +1113,11 @@ MACHINE_CONFIG_FRAGMENT( md_ntsc )
|
||||
MCFG_FRAGMENT_ADD(megadriv_timers)
|
||||
|
||||
MCFG_DEVICE_ADD("gen_vdp", SEGA_GEN_VDP, 0)
|
||||
sega_genesis_vdp_device::set_genesis_vdp_sndirqline_callback(*device, genesis_vdp_sndirqline_callback_genesis_z80);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv6irqline_callback(*device, genesis_vdp_lv6irqline_callback_genesis_68k);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv4irqline_callback(*device, genesis_vdp_lv4irqline_callback_genesis_68k);
|
||||
|
||||
|
||||
|
||||
MCFG_SCREEN_ADD("megadriv", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
@ -1150,6 +1168,9 @@ MACHINE_CONFIG_FRAGMENT( md_pal )
|
||||
MCFG_FRAGMENT_ADD(megadriv_timers)
|
||||
|
||||
MCFG_DEVICE_ADD("gen_vdp", SEGA_GEN_VDP, 0)
|
||||
sega_genesis_vdp_device::set_genesis_vdp_sndirqline_callback(*device, genesis_vdp_sndirqline_callback_genesis_z80);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv6irqline_callback(*device, genesis_vdp_lv6irqline_callback_genesis_68k);
|
||||
sega_genesis_vdp_device::set_genesis_vdp_lv4irqline_callback(*device, genesis_vdp_lv4irqline_callback_genesis_68k);
|
||||
|
||||
MCFG_SCREEN_ADD("megadriv", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(50)
|
||||
@ -1489,7 +1510,6 @@ static void megadriv_init_common(running_machine &machine)
|
||||
DRIVER_INIT_MEMBER(md_base_state,megadriv_c2)
|
||||
{
|
||||
genvdp_use_cram = 0;
|
||||
genesis_always_irq6 = 1;
|
||||
genesis_other_hacks = 0;
|
||||
|
||||
megadriv_init_common(machine());
|
||||
@ -1503,7 +1523,6 @@ DRIVER_INIT_MEMBER(md_base_state,megadriv_c2)
|
||||
DRIVER_INIT_MEMBER(md_base_state,megadriv)
|
||||
{
|
||||
genvdp_use_cram = 1;
|
||||
genesis_always_irq6 = 0;
|
||||
genesis_other_hacks = 1;
|
||||
|
||||
megadriv_init_common(machine());
|
||||
@ -1515,7 +1534,6 @@ DRIVER_INIT_MEMBER(md_base_state,megadriv)
|
||||
DRIVER_INIT_MEMBER(md_base_state,megadrij)
|
||||
{
|
||||
genvdp_use_cram = 1;
|
||||
genesis_always_irq6 = 0;
|
||||
genesis_other_hacks = 1;
|
||||
|
||||
megadriv_init_common(machine());
|
||||
@ -1527,7 +1545,6 @@ DRIVER_INIT_MEMBER(md_base_state,megadrij)
|
||||
DRIVER_INIT_MEMBER(md_base_state,megadrie)
|
||||
{
|
||||
genvdp_use_cram = 1;
|
||||
genesis_always_irq6 = 0;
|
||||
genesis_other_hacks = 1;
|
||||
|
||||
megadriv_init_common(machine());
|
||||
@ -1585,9 +1602,6 @@ void megatech_set_megadrive_z80_as_megadrive_z80(running_machine &machine, const
|
||||
machine.device(tag)->memory().space(AS_PROGRAM)->install_ram(0x0000, 0x1fff, genz80.z80_prgram);
|
||||
|
||||
|
||||
// not allowed??
|
||||
// machine.device(tag)->memory().space(AS_PROGRAM)->install_readwrite_bank(0x2000, 0x3fff, "bank1");
|
||||
|
||||
machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(*ym, 0x4000, 0x4003, FUNC(ym2612_r), FUNC(ym2612_w));
|
||||
machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_write_handler (0x6000, 0x6000, FUNC(megadriv_z80_z80_bank_w));
|
||||
machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_write_handler (0x6001, 0x6001, FUNC(megadriv_z80_z80_bank_w));
|
||||
@ -1596,6 +1610,31 @@ void megatech_set_megadrive_z80_as_megadrive_z80(running_machine &machine, const
|
||||
machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x8000, 0xffff, FUNC(z80_read_68k_banked_data), FUNC(z80_write_68k_banked_data));
|
||||
}
|
||||
|
||||
// these are tests for 'special case' hardware to make sure I don't break anything while rearranging things
|
||||
//
|
||||
|
||||
// called at the start of each scanline
|
||||
TIMER_DEVICE_CALLBACK( megadriv_scanline_timer_callback )
|
||||
{
|
||||
md_base_state *state = timer.machine().driver_data<md_base_state>();
|
||||
|
||||
timer.machine().scheduler().synchronize();
|
||||
state->m_vdp->vdp_handle_scanline_callback(timer.machine(), param);
|
||||
|
||||
megadriv_scanline_timer->adjust(attotime::from_hz(megadriv_framerate) / megadrive_total_scanlines);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SCREEN_VBLANK(megadriv)
|
||||
{
|
||||
md_base_state *state = screen.machine().driver_data<md_base_state>();
|
||||
|
||||
if (screen.machine().root_device().ioport(":RESET")->read_safe(0x00) & 0x01)
|
||||
cputag_set_input_line(screen.machine(), ":maincpu", INPUT_LINE_RESET, PULSE_LINE);
|
||||
|
||||
// rising edge
|
||||
if (vblank_on)
|
||||
{
|
||||
state->m_vdp->vdp_handle_vblank(screen);
|
||||
megadriv_scanline_timer->adjust(attotime::zero);
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ extern int megadrive_irq6_scanline;
|
||||
extern cpu_device *_svp_cpu;
|
||||
extern int segacd_wordram_mapped;
|
||||
extern timer_device* megadriv_scanline_timer;
|
||||
extern timer_device* irq6_on_timer;
|
||||
extern timer_device* irq4_on_timer;
|
||||
|
||||
extern UINT32* _32x_render_videobuffer_to_screenbuffer_helper(running_machine &machine, int scanline);
|
||||
extern void _32x_scanline_cb0(running_machine& machine);
|
||||
@ -26,8 +24,6 @@ extern int _32x_displaymode;
|
||||
extern int _32x_videopriority;
|
||||
extern int _32x_is_connected;
|
||||
|
||||
extern void megadriv_z80_hold(running_machine &machine);
|
||||
extern void megadriv_z80_clear(running_machine &machine);
|
||||
|
||||
#define MAX_HPOSITION 480
|
||||
|
||||
@ -37,7 +33,6 @@ extern void megadriv_z80_clear(running_machine &machine);
|
||||
int megadrive_visible_scanlines;
|
||||
int megadrive_irq6_scanline;
|
||||
int megadrive_z80irq_scanline;
|
||||
int megadrive_imode = 0;
|
||||
int megadriv_framerate;
|
||||
int megadrive_total_scanlines;
|
||||
int megadrive_vblank_flag = 0;
|
||||
@ -50,8 +45,6 @@ int segac2_sp_pal_lookup[4];
|
||||
|
||||
// hacks for C2
|
||||
int genvdp_use_cram = 0; // c2 uses it's own palette ram
|
||||
int genesis_always_irq6 = 0; // c2 never enables the irq6, different source??
|
||||
int genesis_other_hacks = 0; // misc hacks
|
||||
|
||||
UINT16* megadrive_vdp_palette_lookup;
|
||||
UINT16* megadrive_vdp_palette_lookup_sprite; // for C2
|
||||
@ -62,23 +55,90 @@ UINT16* megadrive_ram;
|
||||
|
||||
int megadrive_region_export;
|
||||
int megadrive_region_pal;
|
||||
timer_device* megadriv_render_timer;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void genesis_vdp_sndirqline_callback_default(running_machine &machine, bool state)
|
||||
{
|
||||
// if you haven't actually hooked this up....
|
||||
fatalerror("m_genesis_vdp_sndirqline_callback should be connected to something!\n");
|
||||
}
|
||||
|
||||
void genesis_vdp_lv6irqline_callback_default(running_machine &machine, bool state)
|
||||
{
|
||||
// or this...
|
||||
fatalerror("m_genesis_vdp_lv6irqline_callback should be connected to something!\n");
|
||||
}
|
||||
|
||||
void genesis_vdp_lv4irqline_callback_default(running_machine &machine, bool state)
|
||||
{
|
||||
// or this...
|
||||
fatalerror("m_genesis_vdp_lv4irqline_callback should be connected to something!\n");
|
||||
}
|
||||
|
||||
const device_type SEGA_GEN_VDP = &device_creator<sega_genesis_vdp_device>;
|
||||
|
||||
sega_genesis_vdp_device::sega_genesis_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SEGA_GEN_VDP, "sega_genesis_vdp_device", tag, owner, clock)
|
||||
{
|
||||
m_genesis_vdp_sndirqline_callback = genesis_vdp_sndirqline_callback_default;
|
||||
m_genesis_vdp_lv6irqline_callback = genesis_vdp_lv6irqline_callback_default;
|
||||
m_genesis_vdp_lv4irqline_callback = genesis_vdp_lv4irqline_callback_default;
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( megadriv_render_timer_callback )
|
||||
{
|
||||
sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr;
|
||||
vdp->genesis_render_scanline(machine);
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::vdp_handle_irq6_on_timer_callback(running_machine &machine, int param)
|
||||
{
|
||||
// megadrive_irq6_pending = 1;
|
||||
if (MEGADRIVE_REG01_IRQ6_ENABLE)
|
||||
m_genesis_vdp_lv6irqline_callback(machine, true);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( irq6_on_timer_callback )
|
||||
{
|
||||
sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr;
|
||||
vdp->vdp_handle_irq6_on_timer_callback(machine, param);
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::vdp_handle_irq4_on_timer_callback(running_machine &machine, int param)
|
||||
{
|
||||
m_genesis_vdp_lv4irqline_callback(machine, true);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( irq4_on_timer_callback )
|
||||
{
|
||||
sega_genesis_vdp_device* vdp = (sega_genesis_vdp_device*)ptr;
|
||||
vdp->vdp_handle_irq4_on_timer_callback(machine, param);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void sega_genesis_vdp_device::set_genesis_vdp_sndirqline_callback(device_t &device, genesis_vdp_sndirqline_callback_func callback)
|
||||
{
|
||||
sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device);
|
||||
dev.m_genesis_vdp_sndirqline_callback = callback;
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::set_genesis_vdp_lv6irqline_callback(device_t &device, genesis_vdp_lv6irqline_callback_func callback)
|
||||
{
|
||||
sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device);
|
||||
dev.m_genesis_vdp_lv6irqline_callback = callback;
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::set_genesis_vdp_lv4irqline_callback(device_t &device, genesis_vdp_lv4irqline_callback_func callback)
|
||||
{
|
||||
sega_genesis_vdp_device &dev = downcast<sega_genesis_vdp_device &>(device);
|
||||
dev.m_genesis_vdp_lv4irqline_callback = callback;
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::device_start()
|
||||
{
|
||||
|
||||
@ -111,6 +171,7 @@ void sega_genesis_vdp_device::device_start()
|
||||
save_item(NAME(m_irq4counter));
|
||||
save_item(NAME(m_imode_odd_frame));
|
||||
save_item(NAME(m_sprite_collision));
|
||||
save_item(NAME(megadrive_imode));
|
||||
|
||||
|
||||
|
||||
@ -120,6 +181,9 @@ void sega_genesis_vdp_device::device_start()
|
||||
|
||||
m_render_bitmap = auto_bitmap_ind16_alloc(machine(), machine().primary_screen->width(), machine().primary_screen->height());
|
||||
|
||||
irq6_on_timer = machine().scheduler().timer_alloc(FUNC(irq6_on_timer_callback), (void*)this);
|
||||
irq4_on_timer = machine().scheduler().timer_alloc(FUNC(irq4_on_timer_callback), (void*)this);
|
||||
megadriv_render_timer = machine().scheduler().timer_alloc(FUNC(megadriv_render_timer_callback), (void*)this);
|
||||
|
||||
}
|
||||
|
||||
@ -132,17 +196,16 @@ void sega_genesis_vdp_device::device_reset()
|
||||
m_vdp_address = 0;
|
||||
m_vram_fill_pending = 0;
|
||||
m_vram_fill_length = 0;
|
||||
m_irq4counter = 0;
|
||||
m_irq4counter = -1;
|
||||
m_imode_odd_frame = 0;
|
||||
m_sprite_collision = 0;
|
||||
megadrive_imode = 0;
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::device_reset_old()
|
||||
{
|
||||
// other stuff, are we sure we want to set some of these every reset?
|
||||
// it's called from MACHIN_RESET( megadriv )
|
||||
megadrive_imode = 0;
|
||||
m_irq4counter = -1;
|
||||
// it's called from MACHINE_RESET( megadriv )
|
||||
megadrive_total_scanlines = 262;
|
||||
megadrive_visible_scanlines = 224;
|
||||
megadrive_irq6_scanline = 224;
|
||||
@ -335,9 +398,9 @@ void sega_genesis_vdp_device::megadrive_vdp_set_register(running_machine &machin
|
||||
if (megadrive_irq4_pending)
|
||||
{
|
||||
if (MEGADRIVE_REG0_IRQ4_ENABLE)
|
||||
cputag_set_input_line(machine, ":maincpu", 4, HOLD_LINE);
|
||||
m_genesis_vdp_lv4irqline_callback(machine, true);
|
||||
else
|
||||
cputag_set_input_line(machine, ":maincpu", 4, CLEAR_LINE);
|
||||
m_genesis_vdp_lv4irqline_callback(machine, false);
|
||||
}
|
||||
|
||||
/* ??? Fatal Rewind needs this but I'm not sure it's accurate behavior
|
||||
@ -352,9 +415,10 @@ void sega_genesis_vdp_device::megadrive_vdp_set_register(running_machine &machin
|
||||
if (megadrive_irq6_pending)
|
||||
{
|
||||
if (MEGADRIVE_REG01_IRQ6_ENABLE )
|
||||
cputag_set_input_line(machine, ":maincpu", 6, HOLD_LINE);
|
||||
m_genesis_vdp_lv6irqline_callback(machine, true);
|
||||
else
|
||||
cputag_set_input_line(machine, ":maincpu", 6, CLEAR_LINE);
|
||||
m_genesis_vdp_lv6irqline_callback(machine, false);
|
||||
|
||||
}
|
||||
|
||||
/* ??? */
|
||||
@ -2587,21 +2651,21 @@ void sega_genesis_vdp_device::genesis_render_videobuffer_to_screenbuffer(running
|
||||
}
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::genesis_render_scanline(running_machine &machine, int scanline)
|
||||
void sega_genesis_vdp_device::genesis_render_scanline(running_machine &machine)
|
||||
{
|
||||
//if (MEGADRIVE_REG01_DMA_ENABLE==0) mame_printf_debug("off\n");
|
||||
genesis_render_spriteline_to_spritebuffer(genesis_scanline_counter);
|
||||
genesis_render_videoline_to_videobuffer(scanline);
|
||||
genesis_render_videobuffer_to_screenbuffer(machine, scanline);
|
||||
int scanline = genesis_scanline_counter;
|
||||
if (scanline>=0 && scanline<megadrive_visible_scanlines)
|
||||
{
|
||||
//if (MEGADRIVE_REG01_DMA_ENABLE==0) mame_printf_debug("off\n");
|
||||
genesis_render_spriteline_to_spritebuffer(genesis_scanline_counter);
|
||||
genesis_render_videoline_to_videobuffer(scanline);
|
||||
genesis_render_videobuffer_to_screenbuffer(machine, scanline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VIDEO_START(megadriv)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
megadrive_vdp_palette_lookup = auto_alloc_array(machine, UINT16, 0x40);
|
||||
megadrive_vdp_palette_lookup_sprite = auto_alloc_array(machine, UINT16, 0x40);
|
||||
|
||||
@ -2640,7 +2704,6 @@ void sega_genesis_vdp_device::vdp_handle_scanline_callback(running_machine &mach
|
||||
{
|
||||
genesis_scanline_counter++;
|
||||
// mame_printf_debug("scanline %d\n",genesis_scanline_counter);
|
||||
megadriv_scanline_timer->adjust(attotime::from_hz(megadriv_framerate) / megadrive_total_scanlines);
|
||||
megadriv_render_timer->adjust(attotime::from_usec(1));
|
||||
|
||||
if (genesis_scanline_counter==megadrive_irq6_scanline )
|
||||
@ -2697,19 +2760,14 @@ void sega_genesis_vdp_device::vdp_handle_scanline_callback(running_machine &mach
|
||||
_32x_scanline_cb1();
|
||||
}
|
||||
|
||||
|
||||
if (machine.device(":genesis_snd_z80") != NULL)
|
||||
if (genesis_scanline_counter == megadrive_z80irq_scanline)
|
||||
{
|
||||
if (genesis_scanline_counter == megadrive_z80irq_scanline)
|
||||
{
|
||||
megadriv_z80_hold(machine);
|
||||
}
|
||||
if (genesis_scanline_counter == megadrive_z80irq_scanline + 1)
|
||||
{
|
||||
megadriv_z80_clear(machine);
|
||||
}
|
||||
m_genesis_vdp_sndirqline_callback(machine, true);
|
||||
}
|
||||
if (genesis_scanline_counter == megadrive_z80irq_scanline + 1)
|
||||
{
|
||||
m_genesis_vdp_sndirqline_callback(machine, false);
|
||||
}
|
||||
|
||||
}
|
||||
else /* pretend we're still on the same scanline to compensate for rounding errors */
|
||||
{
|
||||
@ -2718,35 +2776,8 @@ void sega_genesis_vdp_device::vdp_handle_scanline_callback(running_machine &mach
|
||||
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK( megadriv_scanline_timer_callback )
|
||||
{
|
||||
sega_genesis_vdp_device *vdp = timer.machine().device<sega_genesis_vdp_device>("gen_vdp"); // yuck
|
||||
|
||||
/* This function is called at the very start of every scanline starting at the very
|
||||
top-left of the screen. The first scanline is scanline 0 (we set scanline to -1 in
|
||||
VIDEO_EOF) */
|
||||
|
||||
timer.machine().scheduler().synchronize();
|
||||
vdp->vdp_handle_scanline_callback(timer.machine(), param);
|
||||
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::vdp_handle_irq6_on_callback(running_machine &machine, int param)
|
||||
{
|
||||
//mame_printf_debug("irq6 active on %d\n",genesis_scanline_counter);
|
||||
|
||||
{
|
||||
// megadrive_irq6_pending = 1;
|
||||
if (MEGADRIVE_REG01_IRQ6_ENABLE || genesis_always_irq6)
|
||||
cputag_set_input_line(machine, ":maincpu", 6, HOLD_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK( irq6_on_callback )
|
||||
{
|
||||
sega_genesis_vdp_device *vdp = timer.machine().device<sega_genesis_vdp_device>("gen_vdp"); // yuck
|
||||
vdp->vdp_handle_irq6_on_callback(timer.machine(), param);
|
||||
}
|
||||
|
||||
void sega_genesis_vdp_device::vdp_handle_vblank(screen_device &screen)
|
||||
{
|
||||
@ -2763,8 +2794,6 @@ void sega_genesis_vdp_device::vdp_handle_vblank(screen_device &screen)
|
||||
m_imode_odd_frame^=1;
|
||||
// cputag_set_input_line(machine, "genesis_snd_z80", 0, CLEAR_LINE); // if the z80 interrupt hasn't happened by now, clear it..
|
||||
|
||||
if (screen.machine().root_device().ioport(":RESET")->read_safe(0x00) & 0x01)
|
||||
cputag_set_input_line(screen.machine(), ":maincpu", INPUT_LINE_RESET, PULSE_LINE);
|
||||
|
||||
|
||||
if (MEGADRIVE_REG01_240_LINE)
|
||||
@ -2827,7 +2856,6 @@ void sega_genesis_vdp_device::vdp_handle_vblank(screen_device &screen)
|
||||
|
||||
screen.machine().primary_screen->configure(scr_width, megadrive_visible_scanlines, visarea, HZ_TO_ATTOSECONDS(megadriv_framerate));
|
||||
|
||||
megadriv_scanline_timer->adjust(attotime::zero);
|
||||
|
||||
if(_32x_is_connected)
|
||||
_32x_hcount_compare_val = -1;
|
||||
@ -2835,28 +2863,8 @@ void sega_genesis_vdp_device::vdp_handle_vblank(screen_device &screen)
|
||||
|
||||
|
||||
|
||||
SCREEN_VBLANK(megadriv)
|
||||
{
|
||||
// rising edge
|
||||
if (vblank_on)
|
||||
{
|
||||
sega_genesis_vdp_device *vdp = screen.machine().device<sega_genesis_vdp_device>("gen_vdp"); // yuck
|
||||
vdp->vdp_handle_vblank(screen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TIMER_DEVICE_CALLBACK( megadriv_render_timer_callback )
|
||||
{
|
||||
sega_genesis_vdp_device *vdp = timer.machine().device<sega_genesis_vdp_device>("gen_vdp"); // yuck
|
||||
|
||||
if (genesis_scanline_counter>=0 && genesis_scanline_counter<megadrive_visible_scanlines)
|
||||
{
|
||||
|
||||
vdp->genesis_render_scanline(timer.machine(), genesis_scanline_counter);
|
||||
}
|
||||
}
|
||||
|
||||
void megadriv_reset_vdp(running_machine &machine)
|
||||
{
|
||||
sega_genesis_vdp_device *vdp = machine.device<sega_genesis_vdp_device>("gen_vdp"); // yuck
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Sega Megadrive / Genesis VDP */
|
||||
|
||||
#pragma once
|
||||
|
||||
/* The VDP occupies addresses C00000h to C0001Fh.
|
||||
|
||||
@ -141,19 +142,27 @@
|
||||
#define MEGADRIVE_REG17_UNUSED ((m_vdp_regs[0x17]&0x3f)>>0)
|
||||
|
||||
|
||||
|
||||
typedef void (*genesis_vdp_sndirqline_callback_func)(running_machine &machine, bool state);
|
||||
typedef void (*genesis_vdp_lv6irqline_callback_func)(running_machine &machine, bool state);
|
||||
typedef void (*genesis_vdp_lv4irqline_callback_func)(running_machine &machine, bool state);
|
||||
|
||||
class sega_genesis_vdp_device : public device_t
|
||||
{
|
||||
public:
|
||||
sega_genesis_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
static void set_genesis_vdp_sndirqline_callback(device_t &device, genesis_vdp_sndirqline_callback_func callback);
|
||||
static void set_genesis_vdp_lv6irqline_callback(device_t &device, genesis_vdp_lv6irqline_callback_func callback);
|
||||
static void set_genesis_vdp_lv4irqline_callback(device_t &device, genesis_vdp_lv4irqline_callback_func callback);
|
||||
|
||||
DECLARE_READ16_MEMBER( megadriv_vdp_r );
|
||||
DECLARE_WRITE16_MEMBER( megadriv_vdp_w );
|
||||
|
||||
void genesis_render_scanline(running_machine &machine, int scanline);
|
||||
|
||||
void genesis_render_scanline(running_machine &machine);
|
||||
void vdp_handle_scanline_callback(running_machine &machine, int scanline);
|
||||
void vdp_handle_irq6_on_callback(running_machine &machine, int param);
|
||||
void vdp_handle_irq6_on_timer_callback(running_machine &machine, int param);
|
||||
void vdp_handle_irq4_on_timer_callback(running_machine &machine, int param);
|
||||
void vdp_handle_vblank(screen_device &screen);
|
||||
void device_reset_old();
|
||||
|
||||
@ -163,6 +172,10 @@ protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// called when we hit 240 and 241 (used to control the z80 irq line on genesis, or the main irq on c2)
|
||||
genesis_vdp_sndirqline_callback_func m_genesis_vdp_sndirqline_callback;
|
||||
genesis_vdp_lv6irqline_callback_func m_genesis_vdp_lv6irqline_callback;
|
||||
genesis_vdp_lv6irqline_callback_func m_genesis_vdp_lv4irqline_callback;
|
||||
|
||||
private:
|
||||
|
||||
@ -177,6 +190,8 @@ private:
|
||||
int m_imode_odd_frame;
|
||||
int m_sprite_collision;
|
||||
|
||||
int megadrive_imode;
|
||||
|
||||
UINT16* m_vdp_regs;
|
||||
UINT16* m_vram;
|
||||
UINT16* m_cram;
|
||||
@ -185,6 +200,13 @@ private:
|
||||
to speed up processing, Castlevania Bloodlines abuses this on the upside down level */
|
||||
UINT16* m_internal_sprite_attribute_table;
|
||||
|
||||
// these are used internally by the VDP to schedule when after the start of a scanline
|
||||
// to trigger the various interrupts / rendering to our bitmap, bit of a hack really
|
||||
emu_timer* irq6_on_timer;
|
||||
emu_timer* irq4_on_timer;
|
||||
emu_timer* megadriv_render_timer;
|
||||
|
||||
|
||||
|
||||
UINT16 vdp_vram_r(void);
|
||||
UINT16 vdp_vsram_r(void);
|
||||
|
Loading…
Reference in New Issue
Block a user