summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Alex W. Jackson <alex.w.jackson@gmail.com>2014-04-22 17:09:12 +0000
committer Alex W. Jackson <alex.w.jackson@gmail.com>2014-04-22 17:09:12 +0000
commit69e99a89f232bcd07be576192f0460e0173d7efd (patch)
treeac9c91797913899e7cb04e4f6d8bbcbe6e661122 /src
parent94fc4f582a6ae7974935d66eeed2fdfa83ea4bc0 (diff)
m68000: implement TAS callback (currently only used by megadrive) in a more sensible and versatile way [Alex Jackson]
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/m68000/m68000.h17
-rw-r--r--src/emu/cpu/m68000/m68k_in.c17
-rw-r--r--src/emu/cpu/m68000/m68kcpu.c4
-rw-r--r--src/mame/includes/megadriv.h2
-rw-r--r--src/mame/machine/megadriv.c6
5 files changed, 23 insertions, 23 deletions
diff --git a/src/emu/cpu/m68000/m68000.h b/src/emu/cpu/m68000/m68000.h
index 5e3ab5e0803..f5b89789da8 100644
--- a/src/emu/cpu/m68000/m68000.h
+++ b/src/emu/cpu/m68000/m68000.h
@@ -171,7 +171,7 @@ public:
void set_reset_callback(write_line_delegate callback);
void set_cmpild_callback(write32_delegate callback);
void set_rte_callback(write_line_delegate callback);
- void set_tas_callback(read_line_delegate callback);
+ void set_tas_write_callback(write8_delegate callback);
UINT16 get_fc();
void set_encrypted_opcode_range(offs_t start, offs_t end);
void set_hmmu_enable(int enable);
@@ -252,16 +252,17 @@ public:
const UINT8* cyc_exception;
/* Callbacks to host */
- device_irq_acknowledge_callback int_ack_callback; /* Interrupt Acknowledge */
- write32_delegate bkpt_ack_callback; /* Breakpoint Acknowledge */
- write_line_delegate reset_instr_callback; /* Called when a RESET instruction is encountered */
- write32_delegate cmpild_instr_callback; /* Called when a CMPI.L #v, Dn instruction is encountered */
- write_line_delegate rte_instr_callback; /* Called when a RTE instruction is encountered */
- read_line_delegate tas_instr_callback; /* Called when a TAS instruction is encountered, allows / disallows writeback */
+ device_irq_acknowledge_callback int_ack_callback; /* Interrupt Acknowledge */
+ write32_delegate bkpt_ack_callback; /* Breakpoint Acknowledge */
+ write_line_delegate reset_instr_callback; /* Called when a RESET instruction is encountered */
+ write32_delegate cmpild_instr_callback; /* Called when a CMPI.L #v, Dn instruction is encountered */
+ write_line_delegate rte_instr_callback; /* Called when a RTE instruction is encountered */
+ write8_delegate tas_write_callback; /* Called instead of normal write8 by the TAS instruction,
+ allowing writeback to be disabled globally or selectively
+ or other side effects to be implemented */
address_space *program;
-
/* Redirect memory calls */
typedef delegate<UINT8 (offs_t)> m68k_read8_delegate;
diff --git a/src/emu/cpu/m68000/m68k_in.c b/src/emu/cpu/m68000/m68k_in.c
index a5809607138..29ff095350c 100644
--- a/src/emu/cpu/m68000/m68k_in.c
+++ b/src/emu/cpu/m68000/m68k_in.c
@@ -10015,21 +10015,20 @@ M68KMAKE_OP(tas, 8, ., .)
{
UINT32 ea = M68KMAKE_GET_EA_AY_8;
UINT32 dst = m68ki_read_8((mc68kcpu), ea);
- UINT32 allow_writeback = TRUE;
(mc68kcpu)->not_z_flag = dst;
(mc68kcpu)->n_flag = NFLAG_8(dst);
(mc68kcpu)->v_flag = VFLAG_CLEAR;
(mc68kcpu)->c_flag = CFLAG_CLEAR;
- /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback
- disabled in order to function properly. Some Amiga software may also rely
- on this, but only when accessing specific addresses so additional functionality
- will be needed. */
- if (!(mc68kcpu)->tas_instr_callback.isnull())
- allow_writeback = ((mc68kcpu)->tas_instr_callback)();
-
- if (allow_writeback)
+ /* On the 68000 and 68010, the TAS instruction uses a unique bus cycle that may have
+ side effects (e.g. delaying DMA) or may fail to write back at all depending on the
+ bus implementation.
+ In particular, the Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS
+ to fail to write back in order to function properly. */
+ if (CPU_TYPE_IS_010_LESS((mc68kcpu)->cpu_type) && !(mc68kcpu)->tas_write_callback.isnull())
+ ((mc68kcpu)->tas_write_callback)(*(mc68kcpu)->program, ea, dst | 0x80, 0xff);
+ else
m68ki_write_8((mc68kcpu), ea, dst | 0x80);
}
diff --git a/src/emu/cpu/m68000/m68kcpu.c b/src/emu/cpu/m68000/m68kcpu.c
index 4b0d7258dd4..8c18ce2f47e 100644
--- a/src/emu/cpu/m68000/m68kcpu.c
+++ b/src/emu/cpu/m68000/m68kcpu.c
@@ -1696,9 +1696,9 @@ void m68000_base_device::set_rte_callback(write_line_delegate callback)
rte_instr_callback = callback;
}
-void m68000_base_device::set_tas_callback(read_line_delegate callback)
+void m68000_base_device::set_tas_write_callback(write8_delegate callback)
{
- tas_instr_callback = callback;
+ tas_write_callback = callback;
}
UINT16 m68000_base_device::get_fc()
diff --git a/src/mame/includes/megadriv.h b/src/mame/includes/megadriv.h
index 0368baee464..e76c55d82ee 100644
--- a/src/mame/includes/megadriv.h
+++ b/src/mame/includes/megadriv.h
@@ -123,7 +123,7 @@ public:
UINT32 screen_update_megadriv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void screen_eof_megadriv(screen_device &screen, bool state);
- READ_LINE_MEMBER(megadriv_tas_callback);
+ DECLARE_WRITE8_MEMBER(megadriv_tas_callback);
};
diff --git a/src/mame/machine/megadriv.c b/src/mame/machine/megadriv.c
index 7ec6c30dc53..182a2d97ec2 100644
--- a/src/mame/machine/megadriv.c
+++ b/src/mame/machine/megadriv.c
@@ -1017,9 +1017,9 @@ MACHINE_CONFIG_FRAGMENT( md_pal )
MACHINE_CONFIG_END
-READ_LINE_MEMBER(md_base_state::megadriv_tas_callback)
+WRITE8_MEMBER(md_base_state::megadriv_tas_callback)
{
- return 0; // writeback not allowed
+ return; // writeback not allowed
}
void md_base_state::megadriv_init_common()
@@ -1034,7 +1034,7 @@ void md_base_state::megadriv_init_common()
m_maincpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(md_base_state::genesis_int_callback),this));
- m_maincpu->set_tas_callback(read_line_delegate(FUNC(md_base_state::megadriv_tas_callback),this));
+ m_maincpu->set_tas_write_callback(write8_delegate(FUNC(md_base_state::megadriv_tas_callback),this));
m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_base_state::megadrive_io_read_data_port_3button),this);
m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_base_state::megadrive_io_write_data_port_3button),this);