summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/ti99_peb/evpc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/ti99_peb/evpc.cpp')
-rw-r--r--src/devices/bus/ti99_peb/evpc.cpp369
1 files changed, 369 insertions, 0 deletions
diff --git a/src/devices/bus/ti99_peb/evpc.cpp b/src/devices/bus/ti99_peb/evpc.cpp
new file mode 100644
index 00000000000..57b16fb9466
--- /dev/null
+++ b/src/devices/bus/ti99_peb/evpc.cpp
@@ -0,0 +1,369 @@
+// license:LGPL-2.1+
+// copyright-holders:Michael Zapf
+/****************************************************************************
+ SNUG Enhanced Video Processor Card (evpc)
+ based on v9938 (may also be equipped with v9958)
+ Can be used with TI-99/4A as an add-on card; internal VDP must be removed
+
+ The SGCPU ("TI-99/4P") only runs with EVPC.
+ Michael Zapf
+
+ October 2010: Rewritten as device
+ February 2012: Rewritten as class
+
+ FIXME: Locks up on startup when HFDC is present. This can be avoided
+ by using another controller (like bwg) or doing a soft reset.
+
+*****************************************************************************/
+
+#include "evpc.h"
+
+#define EVPC_CRU_BASE 0x1400
+#define VERBOSE 1
+#define LOG logerror
+
+#define NOVRAM_SIZE 256
+
+snug_enhanced_video_device::snug_enhanced_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+: ti_expansion_card_device(mconfig, TI99_EVPC, "SNUG Enhanced Video Processor Card", tag, owner, clock, "ti99_evpc", __FILE__),
+ device_nvram_interface(mconfig, *this)
+{
+}
+
+//-------------------------------------------------
+// nvram_default - called to initialize NVRAM to
+// its default state
+//-------------------------------------------------
+
+void snug_enhanced_video_device::nvram_default()
+{
+ memset(m_novram, 0, NOVRAM_SIZE);
+}
+
+//-------------------------------------------------
+// nvram_read - called to read NVRAM from the
+// .nv file
+//-------------------------------------------------
+
+void snug_enhanced_video_device::nvram_read(emu_file &file)
+{
+ file.read(m_novram, NOVRAM_SIZE);
+}
+
+//-------------------------------------------------
+// nvram_write - called to write NVRAM to the
+// .nv file
+//-------------------------------------------------
+
+void snug_enhanced_video_device::nvram_write(emu_file &file)
+{
+ file.write(m_novram, NOVRAM_SIZE);
+}
+
+
+/*
+ Read a byte in evpc DSR space
+ 0x4000 - 0x5eff DSR (paged)
+ 0x5f00 - 0x5fef NOVRAM
+ 0x5ff0 - 0x5fff Palette
+*/
+READ8Z_MEMBER(snug_enhanced_video_device::readz)
+{
+ if (m_selected)
+ {
+ if ((offset & m_select_mask)==m_select_value)
+ {
+ if ((offset & 0x1ff0)==0x1ff0) // Palette control
+ {
+ switch (offset & 0x000f)
+ {
+ case 0:
+ /* Palette Read Address Register */
+ *value = m_palette.write_index;
+ break;
+
+ case 2:
+ /* Palette Read Color Value */
+ if (m_palette.read)
+ {
+ switch (m_palette.state)
+ {
+ case 0:
+ *value = m_palette.color[m_palette.read_index].red;
+ break;
+ case 1:
+ *value = m_palette.color[m_palette.read_index].green;
+ break;
+ case 2:
+ *value = m_palette.color[m_palette.read_index].blue;
+ break;
+ }
+ m_palette.state++;
+ if (m_palette.state == 3)
+ {
+ m_palette.state = 0;
+ m_palette.read_index++;
+ }
+ }
+ break;
+
+ case 4:
+ /* Palette Read Pixel Mask */
+ *value = m_palette.mask;
+ break;
+ case 6:
+ /* Palette Read Address Register for Color Value */
+ if (m_palette.read)
+ *value = 0;
+ else
+ *value = 3;
+ break;
+ }
+ }
+ else
+ {
+ if ((offset & 0x1f00)==0x1f00)
+ {
+ if (m_RAMEN) // NOVRAM hides DSR
+ {
+ *value = m_novram[offset & 0x00ff];
+ }
+ else // DSR
+ {
+ *value = m_dsrrom[(offset&0x1fff) | (m_dsr_page<<13)];
+ }
+ }
+ else
+ {
+ *value = m_dsrrom[(offset&0x1fff) | (m_dsr_page<<13)];
+ }
+ }
+ }
+ }
+}
+
+/*
+ Write a byte in evpc DSR space
+ 0x4000 - 0x5eff DSR (paged)
+ 0x5f00 - 0x5fef NOVRAM
+ 0x5ff0 - 0x5fff Palette
+*/
+WRITE8_MEMBER(snug_enhanced_video_device::write)
+{
+ if (m_selected)
+ {
+ if ((offset & m_select_mask)==m_select_value)
+ {
+ if ((offset & 0x1ff0)==0x1ff0)
+ {
+ /* PALETTE */
+ if (VERBOSE>5) LOG("palette write %04x <- %02x\n", offset&0xffff, data);
+ switch (offset & 0x000f)
+ {
+ case 0x08:
+ /* Palette Write Address Register */
+ if (VERBOSE>5) LOG("EVPC palette address write (for write access)\n");
+ m_palette.write_index = data;
+ m_palette.state = 0;
+ m_palette.read = 0;
+ break;
+
+ case 0x0a:
+ /* Palette Write Color Value */
+ if (VERBOSE>5) LOG("EVPC palette color write\n");
+ if (!m_palette.read)
+ {
+ switch (m_palette.state)
+ {
+ case 0:
+ m_palette.color[m_palette.write_index].red = data;
+ break;
+ case 1:
+ m_palette.color[m_palette.write_index].green = data;
+ break;
+ case 2:
+ m_palette.color[m_palette.write_index].blue = data;
+ break;
+ }
+ m_palette.state++;
+ if (m_palette.state == 3)
+ {
+ m_palette.state = 0;
+ m_palette.write_index++;
+ }
+ //evpc_palette.dirty = 1;
+ }
+ break;
+
+ case 0x0c:
+ /* Palette Write Pixel Mask */
+ if (VERBOSE>5) LOG("EVPC palette mask write\n");
+ m_palette.mask = data;
+ break;
+
+ case 0x0e:
+ /* Palette Write Address Register for Color Value */
+ if (VERBOSE>5) LOG("EVPC palette address write (for read access)\n");
+ m_palette.read_index = data;
+ m_palette.state = 0;
+ m_palette.read = 1;
+ break;
+ }
+ }
+ else
+ {
+ if ((offset & 0x1f00)==0x1f00)
+ {
+ if (m_RAMEN)
+ {
+ // NOVRAM
+ m_novram[offset & 0x00ff] = data;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ The CRU read handler. Read EVPC DIP switches
+ 0: Video timing (PAL/NTSC)
+ 1: -
+ 2: charset
+ 3: RAM shift
+ 4: -
+ 5: -
+ 6: -
+ 7: DIP or NOVRAM
+ Logic is inverted
+*/
+READ8Z_MEMBER(snug_enhanced_video_device::crureadz)
+{
+ if ((offset & 0xff00)==EVPC_CRU_BASE)
+ {
+ if ((offset & 0x00f0)==0) // offset 0 delivers bits 0-7 (address 00-0f)
+ {
+ *value = ~(ioport("EVPC-SW1")->read() | (ioport("EVPC-SW3")->read()<<2)
+ | (ioport("EVPC-SW4")->read()<<3) | (ioport("EVPC-SW8")->read()<<7));
+ }
+ }
+}
+
+/*
+ The CRU write handler.
+ Bit 0: Turn on DSR ROM
+ Bit 1: DSR page select (bit 0)
+ Bit 2: -
+ Bit 3: RAM enable
+ Bit 4: DSR page select (bit 2)
+ Bit 5: DSR page select (bit 1)
+ Bit 6: -
+ Bit 7: -
+*/
+WRITE8_MEMBER(snug_enhanced_video_device::cruwrite)
+{
+ if ((offset & 0xff00)==EVPC_CRU_BASE)
+ {
+ int bit = (offset >> 1) & 0x0f;
+ switch (bit)
+ {
+ case 0:
+ m_selected = (data!=0);
+ if (VERBOSE>4) LOG("evpc: Map DSR = %d\n", m_selected);
+ break;
+
+ case 1:
+ if (data!=0)
+ m_dsr_page |= 1;
+ else
+ m_dsr_page &= ~1;
+ break;
+
+ case 3:
+ m_RAMEN = (data!=0);
+ break;
+
+ case 4:
+ if (data!=0)
+ m_dsr_page |= 4;
+ else
+ m_dsr_page &= ~4;
+ break;
+
+ case 5:
+ if (data!=0)
+ m_dsr_page |= 2;
+ else
+ m_dsr_page &= ~2;
+ break;
+
+ case 2:
+ case 6:
+ case 7:
+ break;
+ }
+ }
+}
+
+void snug_enhanced_video_device::device_start()
+{
+ m_dsrrom = memregion(DSRROM)->base();
+ m_novram = global_alloc_array(UINT8, NOVRAM_SIZE);
+}
+
+void snug_enhanced_video_device::device_reset()
+{
+ if (VERBOSE>5) LOG("evpc: reset\n");
+ m_select_mask = 0x7e000;
+ m_select_value = 0x74000;
+ m_dsr_page = 0;
+ m_RAMEN = false;
+ m_selected = false;
+}
+
+void snug_enhanced_video_device::device_stop()
+{
+ global_free_array(m_novram);
+}
+
+ROM_START( ti99_evpc )
+ ROM_REGION(0x10000, DSRROM, 0)
+ ROM_LOAD("evpcdsr.bin", 0, 0x10000, CRC(a062b75d) SHA1(6e8060f86e3bb9c36f244d88825e3fe237bfe9a9)) /* evpc DSR ROM */
+ROM_END
+
+/*
+ Input ports for the EPVC
+*/
+INPUT_PORTS_START( ti99_evpc )
+ PORT_START( "EVPC-SW1" )
+ PORT_DIPNAME( 0x01, 0x00, "EVPC video mode" ) PORT_CONDITION( "EVPC-SW8", 0x01, EQUALS, 0x00 )
+ PORT_DIPSETTING( 0x00, "PAL" )
+ PORT_DIPSETTING( 0x01, "NTSC" )
+
+ PORT_START( "EVPC-SW3" )
+ PORT_DIPNAME( 0x01, 0x00, "EVPC charset" ) PORT_CONDITION( "EVPC-SW8", 0x01, EQUALS, 0x00 )
+ PORT_DIPSETTING( 0x00, DEF_STR( International ))
+ PORT_DIPSETTING( 0x01, DEF_STR( German ))
+
+ PORT_START( "EVPC-SW4" )
+ PORT_DIPNAME( 0x01, 0x00, "EVPC VDP RAM" ) PORT_CONDITION( "EVPC-SW8", 0x01, EQUALS, 0x00 )
+ PORT_DIPSETTING( 0x00, "shifted" )
+ PORT_DIPSETTING( 0x01, "not shifted" )
+
+ PORT_START( "EVPC-SW8" )
+ PORT_DIPNAME( 0x01, 0x00, "EVPC Configuration" )
+ PORT_DIPSETTING( 0x00, "DIP" )
+ PORT_DIPSETTING( 0x01, "NOVRAM" )
+INPUT_PORTS_END
+
+const rom_entry *snug_enhanced_video_device::device_rom_region() const
+{
+ return ROM_NAME( ti99_evpc );
+}
+
+ioport_constructor snug_enhanced_video_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(ti99_evpc);
+}
+
+const device_type TI99_EVPC = &device_creator<snug_enhanced_video_device>;