summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/video/cdp1861.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/video/cdp1861.c')
-rw-r--r--trunk/src/emu/video/cdp1861.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/trunk/src/emu/video/cdp1861.c b/trunk/src/emu/video/cdp1861.c
new file mode 100644
index 00000000000..c071562bd98
--- /dev/null
+++ b/trunk/src/emu/video/cdp1861.c
@@ -0,0 +1,265 @@
+/**********************************************************************
+
+ RCA CDP1861 Video Display Controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "cdp1861.h"
+#include "machine/devhelpr.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define CDP1861_CYCLES_DMA_START 2*8
+#define CDP1861_CYCLES_DMA_ACTIVE 8*8
+#define CDP1861_CYCLES_DMA_WAIT 6*8
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+// device type definition
+const device_type CDP1861 = &device_creator<cdp1861_device>;
+
+//-------------------------------------------------
+// cdp1861_device - constructor
+//-------------------------------------------------
+
+cdp1861_device::cdp1861_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, CDP1861, "CDP1861", tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void cdp1861_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const cdp1861_interface *intf = reinterpret_cast<const cdp1861_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<cdp1861_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
+ memset(&m_out_dmao_cb, 0, sizeof(m_out_dmao_cb));
+ memset(&m_out_efx_cb, 0, sizeof(m_out_efx_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cdp1861_device::device_start()
+{
+ // resolve callbacks
+ m_out_int_func.resolve(m_out_int_cb, *this);
+ m_out_dmao_func.resolve(m_out_dmao_cb, *this);
+ m_out_efx_func.resolve(m_out_efx_cb, *this);
+
+ // allocate timers
+ m_int_timer = timer_alloc(TIMER_INT);
+ m_efx_timer = timer_alloc(TIMER_EFX);
+ m_dma_timer = timer_alloc(TIMER_DMA);
+
+ // find devices
+ m_cpu = machine().device<cpu_device>(m_cpu_tag);
+ m_screen = machine().device<screen_device>(m_screen_tag);
+ m_screen->register_screen_bitmap(m_bitmap);
+
+ // register for state saving
+ save_item(NAME(m_disp));
+ save_item(NAME(m_dispon));
+ save_item(NAME(m_dispoff));
+ save_item(NAME(m_dmaout));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void cdp1861_device::device_reset()
+{
+ m_int_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_INT_START, 0));
+ m_efx_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_EFX_TOP_START, 0));
+ m_dma_timer->adjust(m_cpu->cycles_to_attotime(CDP1861_CYCLES_DMA_START));
+
+ m_disp = 0;
+ m_dmaout = 0;
+
+ m_out_int_func(CLEAR_LINE);
+ m_out_dmao_func(CLEAR_LINE);
+ m_out_efx_func(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// device_timer - handle timer events
+//-------------------------------------------------
+
+void cdp1861_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ int scanline = m_screen->vpos();
+
+ switch (id)
+ {
+ case TIMER_INT:
+ if (scanline == CDP1861_SCANLINE_INT_START)
+ {
+ if (m_disp)
+ {
+ m_out_int_func(ASSERT_LINE);
+ }
+
+ m_int_timer->adjust(m_screen->time_until_pos( CDP1861_SCANLINE_INT_END, 0));
+ }
+ else
+ {
+ if (m_disp)
+ {
+ m_out_int_func(CLEAR_LINE);
+ }
+
+ m_int_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_INT_START, 0));
+ }
+ break;
+
+ case TIMER_EFX:
+ switch (scanline)
+ {
+ case CDP1861_SCANLINE_EFX_TOP_START:
+ m_out_efx_func(ASSERT_LINE);
+ m_efx_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_EFX_TOP_END, 0));
+ break;
+
+ case CDP1861_SCANLINE_EFX_TOP_END:
+ m_out_efx_func(CLEAR_LINE);
+ m_efx_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_EFX_BOTTOM_START, 0));
+ break;
+
+ case CDP1861_SCANLINE_EFX_BOTTOM_START:
+ m_out_efx_func(ASSERT_LINE);
+ m_efx_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_EFX_BOTTOM_END, 0));
+ break;
+
+ case CDP1861_SCANLINE_EFX_BOTTOM_END:
+ m_out_efx_func(CLEAR_LINE);
+ m_efx_timer->adjust(m_screen->time_until_pos(CDP1861_SCANLINE_EFX_TOP_START, 0));
+ break;
+ }
+ break;
+
+ case TIMER_DMA:
+ if (m_dmaout)
+ {
+ if (m_disp)
+ {
+ if (scanline >= CDP1861_SCANLINE_DISPLAY_START && scanline < CDP1861_SCANLINE_DISPLAY_END)
+ {
+ m_out_dmao_func(CLEAR_LINE);
+ }
+ }
+
+ m_dma_timer->adjust(m_cpu->cycles_to_attotime(CDP1861_CYCLES_DMA_WAIT));
+
+ m_dmaout = 0;
+ }
+ else
+ {
+ if (m_disp)
+ {
+ if (scanline >= CDP1861_SCANLINE_DISPLAY_START && scanline < CDP1861_SCANLINE_DISPLAY_END)
+ {
+ m_out_dmao_func(ASSERT_LINE);
+ }
+ }
+
+ m_dma_timer->adjust(m_cpu->cycles_to_attotime(CDP1861_CYCLES_DMA_ACTIVE));
+
+ m_dmaout = 1;
+ }
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// dma_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( cdp1861_device::dma_w )
+{
+ int sx = m_screen->hpos() + 4;
+ int y = m_screen->vpos();
+ int x;
+
+ for (x = 0; x < 8; x++)
+ {
+ int color = BIT(data, 7);
+ m_bitmap.pix16(y, sx + x) = color;
+ data <<= 1;
+ }
+}
+
+
+//-------------------------------------------------
+// disp_on_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( cdp1861_device::disp_on_w )
+{
+ if (!m_dispon && state) m_disp = 1;
+
+ m_dispon = state;
+}
+
+
+//-------------------------------------------------
+// disp_off_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( cdp1861_device::disp_off_w )
+{
+ if (!m_dispon && !m_dispoff && state) m_disp = 0;
+
+ m_dispoff = state;
+
+ m_out_int_func(CLEAR_LINE);
+ m_out_dmao_func(CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// screen_update -
+//-------------------------------------------------
+
+UINT32 cdp1861_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_disp)
+ {
+ copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
+ }
+ else
+ {
+ bitmap.fill(get_black_pen(machine()), cliprect);
+ }
+ return 0;
+}