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)
This commit is contained in:
David Haywood 2018-02-07 00:37:26 +00:00 committed by R. Belmont
parent 37fa0f6d29
commit 2c592e7f14
5 changed files with 134 additions and 10 deletions

View File

@ -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

View File

@ -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;

View File

@ -39,6 +39,9 @@ void xavix_device::device_start()
else
mintf = std::make_unique<mi_xavix_normal>(this);
// bind delegates
m_vector_callback.bind_relative_to(*owner());
init();
state_add(STATE_GENPC, "GENPC", XPC).callexport().noshow();

View File

@ -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<uint8_t (int which, int half)> xavix_interrupt_vector_delegate;
static void set_vector_callback(device_t &device, xavix_interrupt_vector_delegate &&cb) { downcast<xavix_device &>(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)

View File

@ -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<uint8_t (int which, int half)> 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)