summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/mips_rambo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/mips_rambo.cpp')
-rw-r--r--src/mame/machine/mips_rambo.cpp76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/mame/machine/mips_rambo.cpp b/src/mame/machine/mips_rambo.cpp
index 86409db8642..2d6bd16e17c 100644
--- a/src/mame/machine/mips_rambo.cpp
+++ b/src/mame/machine/mips_rambo.cpp
@@ -10,8 +10,6 @@
*
* TODO
* - interrupts
- * - dma
- * - timer
* - buzzer
*/
@@ -33,6 +31,7 @@ mips_rambo_device::mips_rambo_device(const machine_config &mconfig, const char *
, m_parity_out_cb(*this)
, m_timer_out_cb(*this)
, m_buzzer_out_cb(*this)
+ , m_channel{{ 0,0,0,0,0,0, false, *this, *this }, { 0,0,0,0,0,0, false, *this, *this }}
, m_irq_out_state(0)
, m_buzzer_out_state(0)
{
@@ -68,6 +67,13 @@ void mips_rambo_device::device_start()
m_timer_out_cb.resolve_safe();
m_buzzer_out_cb.resolve_safe();
+ for (dma_t &ch : m_channel)
+ {
+ ch.read_cb.resolve_safe(0);
+ ch.write_cb.resolve_safe();
+ }
+
+ m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mips_rambo_device::timer), this));
m_buzzer_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mips_rambo_device::buzzer_toggle), this));
}
@@ -81,7 +87,11 @@ void mips_rambo_device::device_reset()
READ32_MEMBER(mips_rambo_device::tcount_r)
{
- return attotime_to_clocks(machine().time() - m_tcount);
+ u32 const data = attotime_to_clocks(machine().time() - m_tcount);
+
+ LOGMASKED(LOG_REG, "tcount_r 0x%08x (%s)\n", data, machine().describe_context());
+
+ return data;
}
WRITE32_MEMBER(mips_rambo_device::tcount_w)
@@ -94,6 +104,10 @@ WRITE32_MEMBER(mips_rambo_device::tcount_w)
WRITE32_MEMBER(mips_rambo_device::tbreak_w)
{
LOGMASKED(LOG_REG, "tbreak_w 0x%08x (%s)\n", data, machine().describe_context());
+
+ COMBINE_DATA(&m_tbreak);
+
+ m_timer->adjust(clocks_to_attotime(m_tbreak) - (machine().time() - m_tcount));
}
WRITE32_MEMBER(mips_rambo_device::control_w)
@@ -130,6 +144,10 @@ template <unsigned Channel> WRITE32_MEMBER(mips_rambo_device::mode_w)
{
LOGMASKED(LOG_REG, "mode_w<%d> 0x%08x (%s)\n", Channel, data, machine().describe_context());
+ if (data & MODE_CHANNEL_EN)
+ m_channel[Channel].current_address = m_channel[Channel].load_address;
+
+ mem_mask &= MODE_WRITE_MASK;
COMBINE_DATA(&m_channel[Channel].mode);
}
@@ -138,6 +156,14 @@ template <unsigned Channel> WRITE16_MEMBER(mips_rambo_device::block_count_w)
LOGMASKED(LOG_REG, "block_count_w<%d> 0x%04x (%s)\n", Channel, data, machine().describe_context());
COMBINE_DATA(&m_channel[Channel].block_count);
+ COMBINE_DATA(&m_channel[Channel].reload_count);
+}
+
+TIMER_CALLBACK_MEMBER(mips_rambo_device::timer)
+{
+ // FIXME: clear timer out line here, or on tcount/tbreak write?
+ m_timer_out_cb(ASSERT_LINE);
+ m_timer_out_cb(CLEAR_LINE);
}
TIMER_CALLBACK_MEMBER(mips_rambo_device::buzzer_toggle)
@@ -150,9 +176,19 @@ u32 mips_rambo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
{
// check if dma channel is configured
u32 const blocks_required = (screen.visible_area().height() * screen.visible_area().width()) >> 9;
- if (!(m_channel[1].mode & MODE_CHANNEL_EN) || !(m_channel[1].mode & MODE_AUTO_RELOAD) || (m_channel[1].block_count != blocks_required))
+ if (!(m_channel[1].mode & MODE_CHANNEL_EN) || (m_channel[1].reload_count != blocks_required))
return 1;
+ // screen is blanked unless auto reload is enabled
+ if (!(m_channel[1].mode & MODE_AUTO_RELOAD))
+ {
+ m_channel[1].block_count = 0;
+
+ return 0;
+ }
+ else
+ m_channel[1].block_count = m_channel[1].reload_count;
+
u32 address = m_channel[1].load_address;
for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++)
for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8)
@@ -173,3 +209,35 @@ u32 mips_rambo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
return 0;
}
+
+template WRITE_LINE_MEMBER(mips_rambo_device::drq_w<0>);
+template WRITE_LINE_MEMBER(mips_rambo_device::drq_w<1>);
+
+template <unsigned Channel> WRITE_LINE_MEMBER(mips_rambo_device::drq_w)
+{
+ m_channel[Channel].drq_asserted = bool(state == ASSERT_LINE);
+
+ while (m_channel[Channel].drq_asserted)
+ {
+ // check channel enabled
+ if (!(m_channel[Channel].mode & MODE_CHANNEL_EN))
+ break;
+
+ // TODO: check data remaining
+
+ // FIXME: 16 bit dma
+ if (m_channel[Channel].mode & MODE_TO_MEMORY)
+ {
+ u8 const data = m_channel[Channel].read_cb();
+
+ m_ram->write(BYTE4_XOR_BE(m_channel[Channel].current_address), data);
+ }
+ else
+ {
+ u8 const data = m_ram->read(BYTE4_XOR_BE(m_channel[Channel].current_address));
+ m_channel[Channel].write_cb(data);
+ }
+
+ m_channel[Channel].current_address++;
+ }
+}