summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author jbu <pullmoll@t-online.de>2014-12-09 13:06:54 +0100
committer jbu <pullmoll@t-online.de>2014-12-09 13:06:54 +0100
commit1eaba9c1684bbe0e5a7bd688c929b9425f1e8749 (patch)
tree0ce3d4e6bdabe460a8e58354ff97958d3b0670ca
parentafdc0a8e767974af6b514f9f8913cf0045e2864f (diff)
Skeleton Rockwell 10788 chip emulation and use in gts1 - WIP (nw)
-rw-r--r--src/emu/machine/machine.mak9
-rw-r--r--src/emu/machine/r10788.c195
-rw-r--r--src/emu/machine/r10788.h72
-rw-r--r--src/mame/drivers/gts1.c44
-rw-r--r--src/mame/mame.mak1
5 files changed, 317 insertions, 4 deletions
diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak
index ddd1de3e803..50f21afac6c 100644
--- a/src/emu/machine/machine.mak
+++ b/src/emu/machine/machine.mak
@@ -1304,6 +1304,15 @@ endif
#-------------------------------------------------
#
+#@src/emu/machine/r10788.h,MACHINES += R10788
+#-------------------------------------------------
+
+ifneq ($(filter R10788,$(MACHINES)),)
+MACHINEOBJS+= $(MACHINEOBJ)/r10788.o
+endif
+
+#-------------------------------------------------
+#
#@src/emu/machine/rf5c296.h,MACHINES += RF5C296
#-------------------------------------------------
diff --git a/src/emu/machine/r10788.c b/src/emu/machine/r10788.c
new file mode 100644
index 00000000000..7c3984c2823
--- /dev/null
+++ b/src/emu/machine/r10788.c
@@ -0,0 +1,195 @@
+/**********************************************************************
+
+ Rockwell 10788 General Purpose Keyboard and Display circuit
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+
+ REGISTER DESCRIPTION
+
+
+ [ Opcodes IOL, I2 ]
+ NAME W/IO CS I/O CMD I/O Names
+ --------------------------------------------------------------
+ KTR 1 1 x x x 1 1 0 0 Transfer Keyboard Return
+ KTS 1 1 x x x 1 0 1 0 Transfer Keyboard Strobe
+ KLA 1 1 x x x 1 1 1 0 Load Display Register A
+ KLB 1 1 x x x 1 1 0 1 Load Display Register A
+ KDN 1 1 x x x 0 0 1 1 Turn On Display
+ KAF 1 1 x x x 1 0 1 1 Turn Off A
+ KBF 1 1 x x x 0 1 1 1 Turn Off B
+ KER 1 1 x x x 0 1 1 0 Reset Keyboard Error
+
+ Notes:
+ 1.) W/IO is generated by the first word of the PPS IOL instruction.
+ 2.) Polarities of I/O7, I/O6 and I/O5 must be the same as the
+ polarities of the chip select straps SC7, SC6 and SC5.
+ 3.) KLA resets DA1-DA4 and DB1 and DB2 to VSS level. KLB resets
+ DB3 and DB4 to VSS level.
+ 4.) KAF and KBF is used to blank the display without changing the
+ contents of display data registers.
+ 5.) KAF resets output lines DA1, DA2, DA3, DA4, DB1 and DB2 to
+ VSS level. KBF resets output lines DB3 and DB4 to VSS level.
+ 6.) KAF stops the circulation of the display register A, and KBF
+ stops the circulation of the display register B.
+ 7.) KER takes a maximum of 10-bit times to complete (= 80 clocks)
+ Therefore, there must be at least 10 bit times between KER
+ and the next KTS instruction.
+**********************************************************************/
+
+#include "emu.h"
+#include "machine/r10788.h"
+
+
+/*************************************
+ *
+ * Device interface
+ *
+ *************************************/
+
+const device_type R10788 = &device_creator<r10788_device>;
+
+r10788_device::r10788_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, R10788, "Rockwell 10788", tag, owner, clock, "r10788", __FILE__),
+ m_reg(),
+ m_ktr(0), m_kts(0), m_kla(0), m_klb(0), m_enable(3), m_ker(0),
+ m_scan_counter(0),
+ m_display(*this)
+{
+}
+
+/**
+ * @brief r10788_device::device_start device-specific startup
+ */
+void r10788_device::device_start()
+{
+ m_display.resolve();
+
+ save_item(NAME(m_reg));
+ save_item(NAME(m_ktr));
+ save_item(NAME(m_kts));
+ save_item(NAME(m_kla));
+ save_item(NAME(m_klb));
+ save_item(NAME(m_enable));
+ save_item(NAME(m_ker));
+ save_item(NAME(m_scan_counter));
+
+ m_timer = timer_alloc(TIMER_DISPLAY);
+ /* Default clock is from CPU1 */
+ if (clock() == 0)
+ {
+ set_unscaled_clock(machine().firstcpu->clock());
+ }
+ m_timer->adjust(clocks_to_attotime(36));
+}
+
+/**
+ * @brief r10788_device::device_reset device-specific reset
+ */
+void r10788_device::device_reset()
+{
+ for (int i = 0; i < 16; i++)
+ m_reg[0][i] = m_reg[1][i] = 0;
+ m_ktr = 0;
+ m_kts = 0;
+ m_kla = 0;
+ m_klb = 0;
+ m_enable = 3;
+ m_ker = 0;
+ m_scan_counter = 0;
+}
+
+
+/**
+ * @brief r10788_device::device_timer timer event callback
+ * @param timer emu_timer which fired
+ * @param id timer identifier
+ * @param param parameter
+ * @param ptr pointer parameter
+ */
+void r10788_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_scan_counter = (m_scan_counter + 1) % 16;
+ switch (id)
+ {
+ case TIMER_DISPLAY:
+ m_display(m_scan_counter, m_reg[0][m_scan_counter] << 4 | m_reg[1][m_scan_counter], 0xff);
+ break;
+ }
+}
+
+/*************************************
+ *
+ * Constants
+ *
+ *************************************/
+
+/*************************************
+ *
+ * Command access handlers
+ *
+ *************************************/
+
+WRITE8_MEMBER( r10788_device::io_w )
+{
+ assert(offset < 16);
+ switch (offset)
+ {
+ case KTR: // Transfer Keyboard Return
+ m_ktr = data;
+ break;
+ case KTS: // Transfer Keyboard Strobe
+ m_kts = data;
+ break;
+ case KLA: // Load Display Register A
+ m_kla = data;
+ break;
+ case KLB: // Load Display Register B
+ m_klb = data;
+ break;
+ case KDN: // Turn On Display
+ m_enable = 1 | 2;
+ break;
+ case KAF: // Turn Off A
+ m_enable &= ~1;
+ break;
+ case KBF: // Turn Off B
+ m_enable &= ~1;
+ break;
+ case KER: // Reset Keyboard Error
+ m_ker = 10;
+ break;
+ }
+}
+
+
+READ8_MEMBER( r10788_device::io_r )
+{
+ assert(offset < 16);
+ UINT8 data = 0xf;
+ switch (offset)
+ {
+ case KTR: // Transfer Keyboard Return
+ data = m_ktr;
+ break;
+ case KTS: // Transfer Keyboard Strobe
+ data = m_kts;
+ break;
+ case KLA: // Load Display Register A
+ data = m_kla;
+ break;
+ case KLB: // Load Display Register B
+ data = m_klb;
+ break;
+ case KDN: // Turn On Display
+ break;
+ case KAF: // Turn Off A
+ break;
+ case KBF: // Turn Off B
+ break;
+ case KER: // Reset Keyboard Error
+ break;
+ }
+ return data;
+}
diff --git a/src/emu/machine/r10788.h b/src/emu/machine/r10788.h
new file mode 100644
index 00000000000..d758876f16c
--- /dev/null
+++ b/src/emu/machine/r10788.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+
+ Rockwell 10788 General Purpose Keyboard and Display circuit
+
+ Juergen Buchmueller <pullmoll@t-online.de>
+
+ The device decodes reads/write to a 16 byte I/O range defined
+ by three wired inputs SC5, SC6 and SC7. The range is one of
+ 80-8f, 90-9f, ..., f0-ff depending on the wiring.
+
+**********************************************************************/
+
+#ifndef __R10788_H__
+#define __R10788_H__
+
+#include "device.h"
+
+/*************************************
+ *
+ * Device configuration macros
+ *
+ *************************************/
+
+/* Set the writer used to update a display digit */
+#define MCFG_R10788_UPDATE(_devcb) \
+ r10788_device::set_update(*device, DEVCB_##_devcb);
+
+class r10788_device : public device_t
+{
+public:
+ r10788_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ ~r10788_device() {}
+
+ enum {
+ KTR = 0xc, //!< Transfer Keyboard Return
+ KTS = 0xa, //!< Transfer Keyboard Strobe
+ KLA = 0xe, //!< Load Display Register A
+ KLB = 0xd, //!< Load Display Register B
+ KDN = 0x3, //!< Turn On Display
+ KAF = 0xb, //!< Turn Off A
+ KBF = 0x7, //!< Turn Off B
+ KER = 0x6 //!< Reset Keyboard Error
+ };
+
+ DECLARE_READ8_MEMBER ( io_r );
+ DECLARE_WRITE8_MEMBER( io_w );
+
+ template<class _Object> static devcb_base &set_update(device_t &device, _Object object) { return downcast<r10788_device &>(device).m_display.set_callback(object); }
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+private:
+ static const device_timer_id TIMER_DISPLAY = 0;
+
+ UINT8 m_reg[2][16]; //!< display registers
+ UINT8 m_ktr; //!< transfer keyboard return value
+ UINT8 m_kts; //!< transfer keyboard strobe value
+ UINT8 m_kla; //!< display register A value
+ UINT8 m_klb; //!< display register B value
+ UINT8 m_enable; //!< display enable flags for A (1) and B (2)
+ UINT8 m_ker; //!< keyboard error value
+ int m_scan_counter; //!< current display scan
+ devcb_write8 m_display; //!< display updater
+ emu_timer* m_timer; //!< timer running at clock / 18 / 36
+};
+
+extern const device_type R10788;
+
+#endif /* __R10788_H__ */
diff --git a/src/mame/drivers/gts1.c b/src/mame/drivers/gts1.c
index 4c1613b9ede..da96e9b3023 100644
--- a/src/mame/drivers/gts1.c
+++ b/src/mame/drivers/gts1.c
@@ -67,6 +67,7 @@ ToDo:
#include "machine/genpin.h"
+#include "machine/r10788.h"
#include "cpu/pps4/pps4.h"
#include "gts1.lh"
@@ -87,12 +88,19 @@ public:
{ }
DECLARE_DRIVER_INIT(gts1);
+
+ DECLARE_WRITE8_MEMBER(gts1_display_w);
+ DECLARE_READ8_MEMBER (gts1_io_r);
+ DECLARE_WRITE8_MEMBER(gts1_io_w);
DECLARE_READ8_MEMBER (gts1_pa_r);
DECLARE_WRITE8_MEMBER(gts1_pa_w);
DECLARE_WRITE8_MEMBER(gts1_pb_w);
private:
virtual void machine_reset();
required_device<cpu_device> m_maincpu;
+ // required_device<r10788_device> m_gpkd; // FIXME: doesn't compile
+ UINT8 m_io[256];
+ UINT8 m_counter;
UINT8 m_6351_addr;
};
@@ -101,12 +109,14 @@ static ADDRESS_MAP_START( gts1_map, AS_PROGRAM, 8, gts1_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( gts1_data, AS_DATA, 8, gts1_state )
- AM_RANGE(0x0000, 0x0fff) AM_RAM // not correct
+ AM_RANGE(0x0000, 0x00ff) AM_RAM // not correct
ADDRESS_MAP_END
static ADDRESS_MAP_START( gts1_io, AS_IO, 8, gts1_state )
- AM_RANGE(0x0000, 0x00ff) AM_RAM // connects to all the other chips
- AM_RANGE(0x0100, 0x0100) AM_READ (gts1_pa_r) AM_WRITE(gts1_pa_w)
+ AM_RANGE(0x00d0, 0x00df) AM_DEVREADWRITE ( "r10788", r10788_device, io_r, io_w )
+ AM_RANGE(0x0000, 0x00ff) AM_READ ( gts1_io_r ) AM_WRITE( gts1_io_w ) // connects to all the other chips
+
+ AM_RANGE(0x0100, 0x0100) AM_READ ( gts1_pa_r ) AM_WRITE( gts1_pa_w )
AM_RANGE(0x0101, 0x0101) AM_WRITE(gts1_pb_w)
ADDRESS_MAP_END
@@ -199,6 +209,29 @@ DRIVER_INIT_MEMBER(gts1_state,gts1)
{
}
+/**
+ * @brief write a 8seg display value
+ * @param offset digit number 0 .. 19
+ * @param data 4-bit value to display
+ */
+WRITE8_MEMBER(gts1_state::gts1_display_w)
+{
+ output_set_digit_value(offset, data);
+}
+
+READ8_MEMBER (gts1_state::gts1_io_r)
+{
+ UINT8 data = m_io[offset] & 0x0f;
+ LOG(("%s: io[%02x] -> %x\n", __FUNCTION__, offset, data));
+ return data;
+}
+
+WRITE8_MEMBER(gts1_state::gts1_io_w)
+{
+ LOG(("%s: io[%02x] <- %x\n", __FUNCTION__, offset, data));
+ m_io[offset] = data;
+}
+
READ8_MEMBER (gts1_state::gts1_pa_r)
{
// return ROM nibble
@@ -232,8 +265,11 @@ static MACHINE_CONFIG_START( gts1, gts1_state )
//MCFG_NVRAM_ADD_0FILL("nvram")
+ /* General Purpose Display and Keyboard */
+ MCFG_R10788_UPDATE( WRITE8(gts1_state,gts1_display_w) )
+
/* Video */
- MCFG_DEFAULT_LAYOUT(layout_gts1)
+ MCFG_DEFAULT_LAYOUT( layout_gts1 )
/* Sound */
MCFG_FRAGMENT_ADD( genpin_audio )
diff --git a/src/mame/mame.mak b/src/mame/mame.mak
index 300a071e9c8..ddb9180e57a 100644
--- a/src/mame/mame.mak
+++ b/src/mame/mame.mak
@@ -499,6 +499,7 @@ MACHINES += PCKEYBRD
MACHINES += PIC8259
MACHINES += PIT8253
MACHINES += PLA
+MACHINES += R10788
#MACHINES += PROFILE
#MACHINES += R64H156
MACHINES += RF5C296