mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
xavix2: Add dma, completion issues (nw)
This commit is contained in:
parent
6b3a689ce1
commit
ad06ccc77c
@ -110,12 +110,15 @@ void xavix2_device::device_start()
|
||||
save_item(NAME(m_if1));
|
||||
save_item(NAME(m_hr));
|
||||
save_item(NAME(m_int_line));
|
||||
save_item(NAME(m_wait));
|
||||
save_item(NAME(m_ei_count));
|
||||
|
||||
set_icountptr(m_icount);
|
||||
|
||||
m_pc = 0;
|
||||
m_f = 0;
|
||||
m_int_line = false;
|
||||
m_wait = false;
|
||||
|
||||
memset(m_r, 0, sizeof(m_r));
|
||||
memset(m_hr, 0, sizeof(m_hr));
|
||||
@ -144,9 +147,11 @@ uint32_t xavix2_device::execute_input_lines() const noexcept
|
||||
|
||||
u32 xavix2_device::check_interrupt(u32 cpc)
|
||||
{
|
||||
if(m_int_line && !(m_f & F_I)) {
|
||||
if(m_int_line && (!(m_f & F_I) || m_wait)) {
|
||||
standard_irq_callback(0);
|
||||
m_ilr1 = cpc;
|
||||
m_ilr1 = m_wait ? cpc + 1 : cpc;
|
||||
m_wait = false;
|
||||
m_ei_count = 0;
|
||||
m_if1 = m_f;
|
||||
m_f |= F_I;
|
||||
return 0x40000010;
|
||||
@ -187,8 +192,14 @@ void xavix2_device::state_string_export(const device_state_entry &entry, std::st
|
||||
|
||||
void xavix2_device::execute_run()
|
||||
{
|
||||
m_pc = check_interrupt(m_pc);
|
||||
if(!m_ei_count)
|
||||
m_pc = check_interrupt(m_pc);
|
||||
while(m_icount > 0) {
|
||||
if(m_ei_count) {
|
||||
m_ei_count--;
|
||||
if(!m_ei_count)
|
||||
m_pc = check_interrupt(m_pc);
|
||||
}
|
||||
if(machine().debug_flags & DEBUG_FLAG_ENABLED)
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
@ -373,10 +384,12 @@ void xavix2_device::execute_run()
|
||||
case 0xe3: /* rti2 */ break;
|
||||
// e4-fb
|
||||
case 0xf8: m_f |= F_I; break;
|
||||
case 0xf9: m_f &= ~F_I; npc = check_interrupt(npc); break;
|
||||
case 0xf9: m_f &= ~F_I; m_ei_count = 2; break;
|
||||
|
||||
case 0xfc: break;
|
||||
// fd-ff
|
||||
// fd
|
||||
case 0xfe: m_wait = true; npc = check_interrupt(npc-1); if(m_wait) m_icount = 0; break;
|
||||
// ff
|
||||
}
|
||||
|
||||
m_pc = npc;
|
||||
|
@ -21,6 +21,7 @@ protected:
|
||||
F_N = 2,
|
||||
F_C = 4,
|
||||
F_V = 8,
|
||||
F_MASK = 15,
|
||||
F_I = 16
|
||||
};
|
||||
|
||||
@ -41,14 +42,14 @@ protected:
|
||||
address_space *m_program;
|
||||
memory_access_cache<2, 0, ENDIANNESS_LITTLE> *m_program_cache;
|
||||
|
||||
int m_icount;
|
||||
int m_icount, m_ei_count;
|
||||
u32 m_pc;
|
||||
u32 m_r[8], m_hr[64];
|
||||
u32 m_ilr1;
|
||||
u8 m_f;
|
||||
u8 m_if1;
|
||||
|
||||
bool m_int_line;
|
||||
bool m_int_line, m_wait;
|
||||
|
||||
static inline int r1(u32 opcode) { return (opcode >> 22) & 7; }
|
||||
static inline int r2(u32 opcode) { return (opcode >> 19) & 7; }
|
||||
@ -81,7 +82,7 @@ protected:
|
||||
f |= F_C;
|
||||
if(((v1 ^ r) & (v2 ^ r)) & 0x80000000)
|
||||
f |= F_V;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -96,7 +97,7 @@ protected:
|
||||
f |= F_C;
|
||||
if(((v1 ^ v2) & (v2 ^ r)) & 0x80000000)
|
||||
f |= F_V;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -106,67 +107,67 @@ protected:
|
||||
f |= F_Z;
|
||||
if(r & 0x80000000)
|
||||
f |= F_N;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline u32 do_lsl(u32 v1, u32 shift) {
|
||||
if(!shift) {
|
||||
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
|
||||
m_f = (m_f & ~F_MASK) | (v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z);
|
||||
return v1;
|
||||
} else if(shift < 32) {
|
||||
u32 r = v1 << shift;
|
||||
u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
|
||||
if(v1 & (1 << (32-shift)))
|
||||
f |= F_C;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
} else if(shift == 32) {
|
||||
m_f = v1 & 1 ? F_C|F_Z : F_Z;
|
||||
m_f = (m_f & ~F_MASK) | (v1 & 1 ? F_C|F_Z : F_Z);
|
||||
return 0;
|
||||
} else {
|
||||
m_f = F_Z;
|
||||
m_f = (m_f & ~F_MASK) | F_Z;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline u32 do_lsr(u32 v1, u32 shift) {
|
||||
if(!shift) {
|
||||
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
|
||||
m_f = (m_f & ~F_MASK) | (v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z);
|
||||
return v1;
|
||||
} else if(shift < 32) {
|
||||
u32 r = v1 >> shift;
|
||||
u32 f = v1 ? 0 : F_Z;
|
||||
if(v1 & (1 << (shift - 1)))
|
||||
f |= F_C;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
} else if(shift == 32) {
|
||||
m_f = v1 & 0x80000000 ? F_C|F_Z : F_Z;
|
||||
m_f = (m_f & ~F_MASK) | (v1 & 0x80000000 ? F_C|F_Z : F_Z);
|
||||
return 0;
|
||||
} else {
|
||||
m_f = F_Z;
|
||||
m_f = (m_f & ~F_MASK) | F_Z;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline u32 do_asr(u32 v1, u32 shift) {
|
||||
if(!shift) {
|
||||
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
|
||||
m_f = (m_f & ~F_MASK) | (v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z);
|
||||
return v1;
|
||||
} else if(shift < 32) {
|
||||
u32 r = static_cast<s32>(v1) >> shift;
|
||||
u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
|
||||
if(v1 & (1 << (shift - 1)))
|
||||
f |= F_C;
|
||||
m_f = f;
|
||||
m_f = (m_f & ~F_MASK) | f;
|
||||
return r;
|
||||
} else {
|
||||
if(v1 & 0x80000000) {
|
||||
m_f = F_C;
|
||||
m_f = (m_f & ~F_MASK) | F_C;
|
||||
return 0xffffffff;
|
||||
} else {
|
||||
m_f = F_Z;
|
||||
m_f = (m_f & ~F_MASK) | F_Z;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -31,24 +31,139 @@ public:
|
||||
void xavix2(machine_config &config);
|
||||
|
||||
private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
enum {
|
||||
IRQ_TIMER = 7,
|
||||
IRQ_DMA = 12
|
||||
};
|
||||
|
||||
required_device<xavix2_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
u32 m_dma_src;
|
||||
u16 m_dma_dst;
|
||||
u16 m_dma_count;
|
||||
emu_timer *m_dma_timer;
|
||||
|
||||
u32 m_int_active;
|
||||
|
||||
void irq_raise(u32 level);
|
||||
void irq_clear(u32 level);
|
||||
bool irq_state(u32 level) const;
|
||||
u8 irq_level_r();
|
||||
|
||||
void dma_src_w(offs_t, u32 data, u32 mem_mask);
|
||||
void dma_dst_w(offs_t, u16 data, u16 mem_mask);
|
||||
void dma_count_w(offs_t, u16 data, u16 mem_mask);
|
||||
void dma_control_w(u8 data);
|
||||
void dma_status_w(u8 data);
|
||||
u8 dma_status_r();
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dma_end);
|
||||
INTERRUPT_GEN_MEMBER(vblank_irq);
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void mem(address_map &map);
|
||||
};
|
||||
|
||||
void xavix2_state::irq_raise(u32 level)
|
||||
{
|
||||
if(!m_int_active)
|
||||
m_maincpu->set_input_line(0, ASSERT_LINE);
|
||||
m_int_active |= 1 << level;
|
||||
}
|
||||
|
||||
void xavix2_state::irq_clear(u32 level)
|
||||
{
|
||||
m_int_active &= ~(1 << level);
|
||||
if(!m_int_active)
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
}
|
||||
|
||||
u8 xavix2_state::irq_level_r()
|
||||
{
|
||||
for(u32 i=31; i>=0; i--)
|
||||
if(m_int_active & (1 << i))
|
||||
return i;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
bool xavix2_state::irq_state(u32 level) const
|
||||
{
|
||||
return m_int_active & (1 << level);
|
||||
}
|
||||
|
||||
void xavix2_state::dma_src_w(offs_t, u32 data, u32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_dma_src);
|
||||
}
|
||||
|
||||
void xavix2_state::dma_dst_w(offs_t, u16 data, u16 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_dma_dst);
|
||||
}
|
||||
|
||||
void xavix2_state::dma_count_w(offs_t, u16 data, u16 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_dma_count);
|
||||
}
|
||||
|
||||
void xavix2_state::dma_control_w(u8 data)
|
||||
{
|
||||
if(data == 3 || data == 7) {
|
||||
logerror("DMA %s:%08x -> %04x (%04x)\n",
|
||||
data == 3 ? "ram" : "rom",
|
||||
m_dma_src, m_dma_dst, m_dma_count);
|
||||
u32 sadr = m_dma_src | (data == 3 ? 0xc0000000 : 0x40000000);
|
||||
u32 dadr = m_dma_dst | 0xc0000000;
|
||||
auto &prg = m_maincpu->space(AS_PROGRAM);
|
||||
for(u32 i=0; i != m_dma_count; i++)
|
||||
prg.write_byte(dadr + i, prg.read_byte(sadr + i));
|
||||
m_dma_timer->adjust(attotime::from_ticks(m_dma_count, m_maincpu->clock()));
|
||||
}
|
||||
}
|
||||
|
||||
void xavix2_state::dma_status_w(u8 data)
|
||||
{
|
||||
if(data == 2)
|
||||
irq_clear(IRQ_DMA);
|
||||
}
|
||||
|
||||
u8 xavix2_state::dma_status_r()
|
||||
{
|
||||
return irq_state(IRQ_DMA) ? 7 : 0;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(xavix2_state::dma_end)
|
||||
{
|
||||
irq_raise(IRQ_DMA);
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(xavix2_state::vblank_irq)
|
||||
{
|
||||
irq_raise(IRQ_TIMER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void xavix2_state::mem(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x00001fff).ram().share("part1");
|
||||
|
||||
map(0x00002000, 0x00002003).w(FUNC(xavix2_state::dma_src_w));
|
||||
map(0x00002004, 0x00002005).w(FUNC(xavix2_state::dma_dst_w));
|
||||
map(0x00002008, 0x00002009).w(FUNC(xavix2_state::dma_count_w));
|
||||
map(0x0000200c, 0x0000200c).w(FUNC(xavix2_state::dma_control_w));
|
||||
map(0x00002010, 0x00002010).rw(FUNC(xavix2_state::dma_status_r), FUNC(xavix2_state::dma_status_w));
|
||||
|
||||
map(0x00002630, 0x00002631).lr16(NAME([]() { return 0x210; }));
|
||||
map(0x00002632, 0x00002633).lr16(NAME([]() { return 0x210; }));
|
||||
map(0x00003c00, 0x00003c00).lr8(NAME([]() { return 7; })); // Current active interrupt number
|
||||
map(0x00003c00, 0x00003c00).r(FUNC(xavix2_state::irq_level_r));
|
||||
|
||||
map(0x00004000, 0x0000ffff).ram().share("part2");
|
||||
map(0x00010000, 0x00ffffff).rom().region("maincpu", 0x010000);
|
||||
|
||||
@ -67,13 +182,15 @@ uint32_t xavix2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
|
||||
|
||||
void xavix2_state::machine_start()
|
||||
{
|
||||
m_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(xavix2_state::dma_end), this));
|
||||
}
|
||||
|
||||
void xavix2_state::machine_reset()
|
||||
{
|
||||
auto &prg = m_maincpu->space(AS_PROGRAM);
|
||||
for(u32 adr=0; adr != 0x2000; adr++)
|
||||
prg.write_byte(adr, prg.read_byte(0x40000000 + adr));
|
||||
m_dma_src = 0;
|
||||
m_dma_dst = 0;
|
||||
m_dma_count = 0;
|
||||
m_int_active = 0;
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( xavix2 )
|
||||
@ -84,7 +201,7 @@ void xavix2_state::xavix2(machine_config &config)
|
||||
// unknown CPU 'SSD 2002-2004 NEC 800208-51'
|
||||
XAVIX2(config, m_maincpu, 98'000'000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &xavix2_state::mem);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(xavix2_state::irq0_line_hold));
|
||||
m_maincpu->set_vblank_int("screen", FUNC(xavix2_state::vblank_irq));
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(60);
|
||||
|
Loading…
Reference in New Issue
Block a user