From 2c592e7f1409a96375f900facae772e5bcb7f273 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Wed, 7 Feb 2018 00:37:26 +0000 Subject: xavix - generate some interrupts, code runs a lot better now (nw) (#3174) * new machines marked as NOT WORKING - Play TV Ping Pong [Sean Riddle] The code on this one is much closer to Taito Nostalgia, seemingly only using the callfar / returnfar extended opcodes, this further makes me think that XaviX Tennis is a Super XaviX title instead. * some guesswork (nw) * it sure *looks* like the dma (nw) * xavix - generate some interrupts, code runs a lot better now (nw) --- src/devices/cpu/m6502/dxavix.lst | 2 +- src/devices/cpu/m6502/oxavix.lst | 47 +++++++++++++++++++++++ src/devices/cpu/m6502/xavix.cpp | 3 ++ src/devices/cpu/m6502/xavix.h | 12 ++++++ src/mame/drivers/xavix.cpp | 80 +++++++++++++++++++++++++++++++++++----- 5 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/devices/cpu/m6502/dxavix.lst b/src/devices/cpu/m6502/dxavix.lst index 82f068df805..d2d4e34d9e9 100644 --- a/src/devices/cpu/m6502/dxavix.lst +++ b/src/devices/cpu/m6502/dxavix.lst @@ -1,7 +1,7 @@ # license:BSD-3-Clause # copyright-holders:David Haywood # xavix - m6502 with custom opcodes -brk_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_imm nop_aba ora_aba asl_aba slo_aba +brk_xav_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_imm nop_aba ora_aba asl_aba slo_aba bpl_rel ora_idy kil_non slo_idy nop_zpx ora_zpx asl_zpx slo_zpx clc_imp ora_aby nop_imp slo_aby nop_abx ora_abx asl_abx slo_abx jsr_adr and_idx callf_xa3 rla_idx bit_zpg and_zpg rol_zpg rla_zpg plp_imp and_imm rol_acc anc_imm bit_aba and_aba rol_aba rla_aba bmi_rel and_idy kil_non rla_idy nop_zpx and_zpx rol_zpx rla_zpx sec_imp and_aby nop_imp rla_aby nop_abx and_abx rol_abx rla_abx diff --git a/src/devices/cpu/m6502/oxavix.lst b/src/devices/cpu/m6502/oxavix.lst index 1e787aab9f3..a4f16b2206e 100644 --- a/src/devices/cpu/m6502/oxavix.lst +++ b/src/devices/cpu/m6502/oxavix.lst @@ -28,3 +28,50 @@ retf_imp PC = set_h(PC, read(SP)); m_farbank = TMP2; prefetch(); + +brk_xav_imp + // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state) + if(irq_taken) { + read_pc_noinc(); + } else { + read_pc(); + } + write(SP, PC >> 8); + dec_SP(); + write(SP, PC); + dec_SP(); + write(SP, irq_taken ? P & ~F_B : P); + dec_SP(); + if(nmi_state) { + if (m_vector_callback.isnull()) + { + PC = read_arg(0xfffa); + PC = set_h(PC, read_arg(0xfffb)); + } + else + { + PC = m_vector_callback(0,1); + PC = set_h(PC, m_vector_callback(0,0)); + } + + nmi_state = false; + standard_irq_callback(NMI_LINE); + } else { + if (m_vector_callback.isnull()) + { + PC = read_arg(0xfffe); + PC = set_h(PC, read_arg(0xffff)); + } + else + { + PC = m_vector_callback(1,1); + PC = set_h(PC, m_vector_callback(1,0)); + } + + if(irq_taken) + standard_irq_callback(IRQ_LINE); + } + irq_taken = false; + P |= F_I; // Do *not* move after the prefetch + prefetch(); + inst_state = -1; diff --git a/src/devices/cpu/m6502/xavix.cpp b/src/devices/cpu/m6502/xavix.cpp index 9492d0fa492..1766a30aeba 100644 --- a/src/devices/cpu/m6502/xavix.cpp +++ b/src/devices/cpu/m6502/xavix.cpp @@ -39,6 +39,9 @@ void xavix_device::device_start() else mintf = std::make_unique(this); + // bind delegates + m_vector_callback.bind_relative_to(*owner()); + init(); state_add(STATE_GENPC, "GENPC", XPC).callexport().noshow(); diff --git a/src/devices/cpu/m6502/xavix.h b/src/devices/cpu/m6502/xavix.h index 557c39ecea3..4e0a76424a2 100644 --- a/src/devices/cpu/m6502/xavix.h +++ b/src/devices/cpu/m6502/xavix.h @@ -12,6 +12,9 @@ #include "m6502.h" +#define MCFG_XAVIX_VECTOR_CALLBACK(_class, _method) \ + xavix_device::set_vector_callback(*device, xavix_device::xavix_interrupt_vector_delegate(&_class::_method, #_class "::" #_method, this)); + class xavix_device : public m6502_device { public: xavix_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -25,6 +28,12 @@ public: // xaviv opcodes O(callf_xa3); O(retf_imp); + O(brk_xav_imp); + + typedef device_delegate xavix_interrupt_vector_delegate; + + static void set_vector_callback(device_t &device, xavix_interrupt_vector_delegate &&cb) { downcast(device).m_vector_callback = std::move(cb); } + #undef O @@ -63,6 +72,9 @@ protected: virtual void device_reset() override; virtual void state_export(const device_state_entry &entry) override; +private: + xavix_interrupt_vector_delegate m_vector_callback; + }; DECLARE_DEVICE_TYPE(XAVIX, xavix_device) diff --git a/src/mame/drivers/xavix.cpp b/src/mame/drivers/xavix.cpp index 610956ca2a0..45f88f4f382 100644 --- a/src/mame/drivers/xavix.cpp +++ b/src/mame/drivers/xavix.cpp @@ -46,7 +46,7 @@ #include "emu.h" #include "cpu/m6502/xavix.h" -//#include "sound/ay8910.h" +#include "machine/timer.h" #include "screen.h" #include "speaker.h" @@ -88,6 +88,8 @@ public: DECLARE_WRITE8_MEMBER(xavix_7ffe_w); DECLARE_WRITE8_MEMBER(xavix_7fff_w); + INTERRUPT_GEN_MEMBER(interrupt); + TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb); protected: // driver_device overrides @@ -107,6 +109,14 @@ private: uint8_t m_xavix_7986_data; uint8_t m_xavix_7987_data; + uint8_t m_xavix_7ff9_data; + uint8_t m_xavix_7ffa_data; + uint8_t m_xavix_7ffb_data; + uint8_t m_xavix_7ffe_data; + uint8_t m_xavix_7fff_data; + + uint8_t get_vectors(int which, int half); + }; void xavix_state::video_start() @@ -202,26 +212,31 @@ READ8_MEMBER(xavix_state::xavix_7980_r) WRITE8_MEMBER(xavix_state::xavix_7ff9_w) { logerror("%s: xavix_7ff9_w %02x (trigger for 7ffx region?)\n", machine().describe_context(), data); + m_xavix_7ff9_data = data; } WRITE8_MEMBER(xavix_state::xavix_7ffa_w) { logerror("%s: xavix_7ffa_w %02x (7ffx pair 1, byte 1?)\n", machine().describe_context(), data); + m_xavix_7ffa_data = data; } WRITE8_MEMBER(xavix_state::xavix_7ffb_w) { logerror("%s: xavix_7ffb_w %02x (7ffx pair 1, byte 2?)\n", machine().describe_context(), data); + m_xavix_7ffb_data = data; } WRITE8_MEMBER(xavix_state::xavix_7ffe_w) { logerror("%s: xavix_7ffe_w %02x (7ffx pair 2, byte 1?)\n", machine().describe_context(), data); + m_xavix_7ffe_data = data; } WRITE8_MEMBER(xavix_state::xavix_7fff_w) { logerror("%s: xavix_7fff_w %02x (7ffx pair 2, byte 2?)\n", machine().describe_context(), data); + m_xavix_7fff_data = data; } @@ -232,6 +247,22 @@ WRITE8_MEMBER(xavix_state::xavix_7900_w) +TIMER_DEVICE_CALLBACK_MEMBER(xavix_state::scanline_cb) +{ +// int scanline = param; +} + +INTERRUPT_GEN_MEMBER(xavix_state::interrupt) +{ +// if (m_xavix_7ff9_data != 0) +// m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE); + + if (m_xavix_7ff9_data != 0) + m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); +} + + + static ADDRESS_MAP_START( xavix_map, AS_PROGRAM, 8, xavix_state ) AM_RANGE(0x000000, 0x0001ff) AM_RAM @@ -266,16 +297,16 @@ static ADDRESS_MAP_START( xavix_map, AS_PROGRAM, 8, xavix_state ) AM_RANGE(0x007900, 0x007900) AM_WRITE(xavix_7900_w) // startup AM_RANGE(0x007902, 0x007902) AM_WRITENOP // startup - // possible trigger for below (written after the others) waits on status of bit 1 in a loop + // DMA trigger for below (written after the others) waits on status of bit 1 in a loop AM_RANGE(0x007980, 0x007980) AM_READWRITE(xavix_7980_r, xavix_7980_w) - // seem to be a triplet? + // DMA source AM_RANGE(0x007981, 0x007981) AM_WRITE(xavix_7981_w) AM_RANGE(0x007982, 0x007982) AM_WRITE(xavix_7982_w) AM_RANGE(0x007983, 0x007983) AM_WRITE(xavix_7983_w) - // seem to be a pair + // DMA dest AM_RANGE(0x007984, 0x007984) AM_WRITE(xavix_7984_w) AM_RANGE(0x007985, 0x007985) AM_WRITE(xavix_7985_w) - // seem to be a pair + // DMA length AM_RANGE(0x007986, 0x007986) AM_WRITE(xavix_7986_w) AM_RANGE(0x007987, 0x007987) AM_WRITE(xavix_7987_w) @@ -284,13 +315,12 @@ static ADDRESS_MAP_START( xavix_map, AS_PROGRAM, 8, xavix_state ) AM_RANGE(0x007a03, 0x007a03) AM_READNOP AM_WRITENOP // startup - // again possible trigger for below, written after them + // maybe irq enable, written after below AM_RANGE(0x007ff9, 0x007ff9) AM_WRITE(xavix_7ff9_w) - // also seems to be a pair + // an IRQ vector (nmi?) AM_RANGE(0x007ffa, 0x007ffa) AM_WRITE(xavix_7ffa_w) AM_RANGE(0x007ffb, 0x007ffb) AM_WRITE(xavix_7ffb_w) - - // also seems to be a pair + // an IRQ vector (irq?) AM_RANGE(0x007ffe, 0x007ffe) AM_WRITE(xavix_7ffe_w) AM_RANGE(0x007fff, 0x007fff) AM_WRITE(xavix_7fff_w) @@ -385,14 +415,46 @@ void xavix_state::machine_reset() m_xavix_7986_data = 0; m_xavix_7987_data = 0; + + m_xavix_7ff9_data = 0; + m_xavix_7ffa_data = 0; + m_xavix_7ffb_data = 0; + m_xavix_7ffe_data = 0; + m_xavix_7fff_data = 0; } +typedef device_delegate xavix_interrupt_vector_delegate; + +uint8_t xavix_state::get_vectors(int which, int half) +{ +// logerror("get_vectors %d %d\n", which, half); + + if (which == 0) // NMI + { + if (half == 0) + return m_xavix_7ffb_data; + else + return m_xavix_7ffa_data; + } + else + { + if (half == 0) + return m_xavix_7fff_data; + else + return m_xavix_7ffe_data; + } +} MACHINE_CONFIG_START(xavix_state::xavix) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",XAVIX,MAIN_CLOCK) MCFG_CPU_PROGRAM_MAP(xavix_map) + MCFG_CPU_VBLANK_INT_DRIVER("screen", xavix_state, interrupt) + MCFG_XAVIX_VECTOR_CALLBACK(xavix_state, get_vectors) + + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", xavix_state, scanline_cb, "screen", 0, 1) + /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) -- cgit v1.2.3