summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/tms6100.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/tms6100.c')
-rw-r--r--trunk/src/emu/machine/tms6100.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/tms6100.c b/trunk/src/emu/machine/tms6100.c
new file mode 100644
index 00000000000..8bbb2e08202
--- /dev/null
+++ b/trunk/src/emu/machine/tms6100.c
@@ -0,0 +1,282 @@
+/**********************************************************************************************
+
+ TMS6100 simulator
+
+ Written for MAME by Couriersud
+
+ Todo:
+ - implement CS
+ - implement 4 bit mode (mask programmed)
+ - implement chip addressing (0-15 mask programmed)
+
+ TMS6100:
+
+ +-----------------+
+ VDD | 1 28 | NC
+ NC | 2 27 | NC
+ DATA/ADD1 | 3 26 | NC
+ DATA/ADD2 | 4 25 | NC
+ DATA/ADD4 | 5 24 | NC
+ DATA/ADD8 | 6 23 | NC
+ CLK | 7 22 | NC
+ NC | 8 21 | NC
+ NC | 9 20 | NC
+ M0 | 10 19 | NC
+ M1 | 11 18 | NC
+ NC | 12 17 | NC
+ /CS | 13 16 | NC
+ VSS | 14 15 | NC
+ +-----------------+
+
+ M58819 (from radarscope schematics):
+
+ +-----------------+
+ AD0 | 1 40 | AD1
+ GND | 2 39 | AD2
+ -5V | 3 38 | AD3
+ A0 | 4 37 | AD4
+ NC | 5 36 | AD5
+ NC | 6 35 | AD6
+ A1 | 7 34 | AD7
+ A2 | 8 33 | AD8
+ A3 | 9 32 | AD9
+ CLK | 10 31 | AD10
+ NC | 11 30 | AD11
+ -5V | 12 29 | AD12
+ C0 | 13 28 | NC
+ C1 | 14 27 | NC
+ NC | 15 26 | I7
+ NC | 16 25 | NC
+ +5V | 17 24 | I6
+ I0 | 18 23 | I5
+ I1 | 19 22 | I4
+ I2 | 20 21 | I3
+ +-----------------+
+
+ The M58819 is used as an interface to external speech eproms.
+ NC pins may have a function, although they are not connected in
+ radarscope.
+
+***********************************************************************************************/
+
+#include "emu.h"
+#include "tms6100.h"
+
+#define VERBOSE (0)
+
+#if VERBOSE
+#define LOG(x) logerror x
+#else
+#define LOG(x)
+#endif
+
+#define TMS6100_READ_PENDING 0x01
+#define TMS6100_NEXT_READ_IS_DUMMY 0x02
+
+typedef struct _tms6100_state tms6100_state;
+struct _tms6100_state
+{
+ /* Rom interface */
+ UINT32 address;
+ UINT32 address_latch;
+ UINT8 loadptr;
+ UINT8 m0;
+ UINT8 m1;
+ UINT8 addr_bits;
+ UINT8 clock;
+ UINT8 data;
+ UINT8 state;
+
+ const UINT8 *rom;
+
+ device_t *device;
+
+#if 0
+ const tms5110_interface *intf;
+#endif
+};
+
+/**********************************************************************************************
+
+ get_safe_token -- get tms6100_state
+
+***********************************************************************************************/
+
+INLINE tms6100_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == TMS6100 ||
+ device->type() == M58819);
+ return (tms6100_state *)downcast<legacy_device_base *>(device)->token();
+}
+
+/**********************************************************************************************
+
+ register_save_states -- register state vars for saving
+
+***********************************************************************************************/
+
+static void register_for_save_states(tms6100_state *tms)
+{
+ tms->device->save_item(NAME(tms->addr_bits));
+ tms->device->save_item(NAME(tms->address));
+ tms->device->save_item(NAME(tms->address_latch));
+ tms->device->save_item(NAME(tms->data));
+ tms->device->save_item(NAME(tms->loadptr));
+ tms->device->save_item(NAME(tms->m0));
+ tms->device->save_item(NAME(tms->m1));
+ tms->device->save_item(NAME(tms->state));
+}
+
+/******************************************************************************
+
+ DEVICE_START( tms6100 ) -- allocate buffers and reset the 6100
+
+******************************************************************************/
+
+static DEVICE_START( tms6100 )
+{
+ //static const tms5110_interface dummy = { 0 };
+ tms6100_state *tms = get_safe_token(device);
+
+ assert_always(tms != NULL, "Error creating TMS6100 chip");
+
+ //tms->intf = device->static_config ? (const tms5110_interface *)device->static_config : &dummy;
+ tms->rom = *device->region();
+
+ tms->device = device;
+
+ register_for_save_states(tms);
+}
+
+static DEVICE_START( m58819 )
+{
+ //tms6100_state *tms = get_safe_token(device);
+ DEVICE_START_CALL( tms6100 );
+ //tms5110_set_variant(tms, TMS5110_IS_5100);
+}
+
+static DEVICE_RESET( tms6100 )
+{
+ tms6100_state *tms = get_safe_token(device);
+
+ /* initialize the chip */
+ tms->addr_bits = 0;
+ tms->address = 0;
+ tms->address_latch = 0;
+ tms->loadptr = 0;
+ tms->m0 = 0;
+ tms->m1 = 0;
+ tms->state = 0;
+ tms->clock = 0;
+ tms->data = 0;
+}
+
+WRITE_LINE_DEVICE_HANDLER( tms6100_m0_w )
+{
+ tms6100_state *tms = get_safe_token(device);
+ if (state != tms->m0)
+ tms->m0 = state;
+}
+
+WRITE_LINE_DEVICE_HANDLER( tms6100_m1_w )
+{
+ tms6100_state *tms = get_safe_token(device);
+ if (state != tms->m1)
+ tms->m1 = state;
+}
+
+WRITE_LINE_DEVICE_HANDLER( tms6100_romclock_w )
+{
+ tms6100_state *tms = get_safe_token(device);
+
+ /* process on falling edge */
+ if (tms->clock && !state)
+ {
+ switch ((tms->m1<<1) | tms->m0)
+ {
+ case 0x00:
+ /* NOP in datasheet, not really ... */
+ if (tms->state & TMS6100_READ_PENDING)
+ {
+ if (tms->state & TMS6100_NEXT_READ_IS_DUMMY)
+ {
+ tms->address = (tms->address_latch << 3);
+ tms->address_latch = 0;
+ tms->loadptr = 0;
+ tms->state &= ~TMS6100_NEXT_READ_IS_DUMMY;
+ LOG(("loaded address %08x\n", tms->address));
+ }
+ else
+ {
+ /* read bit at address */
+ tms->data = (tms->rom[tms->address >> 3] >> ((tms->address & 0x07) ^ 0x07)) & 1;
+ tms->address++;
+ }
+ tms->state &= ~TMS6100_READ_PENDING;
+ }
+ break;
+ case 0x01:
+ /* READ */
+ tms->state |= TMS6100_READ_PENDING;
+ break;
+ case 0x02:
+ /* LOAD ADDRESS */
+ tms->state |= TMS6100_NEXT_READ_IS_DUMMY;
+ tms->address_latch |= (tms->addr_bits << tms->loadptr);
+ LOG(("loaded address latch %08x\n", tms->address_latch));
+ tms->loadptr += 4;
+ break;
+ case 0x03:
+ /* READ AND BRANCH */
+ if (tms->state & TMS6100_NEXT_READ_IS_DUMMY)
+ {
+ tms->state &= ~TMS6100_NEXT_READ_IS_DUMMY; // clear - no dummy read according to datasheet
+ LOG(("loaded address latch %08x\n", tms->address_latch));
+ tms->address = tms->rom[tms->address_latch] | (tms->rom[tms->address_latch+1]<<8);
+ tms->address &= 0x3fff; // 14 bits
+ LOG(("loaded indirect address %04x\n", tms->address));
+ tms->address = (tms->address << 3);
+ tms->address_latch = 0;
+ tms->loadptr = 0;
+ }
+ break;
+ }
+ }
+ tms->clock = state;
+}
+
+WRITE8_DEVICE_HANDLER( tms6100_addr_w )
+{
+ tms6100_state *tms = get_safe_token(device);
+ if (data != tms->addr_bits)
+ tms->addr_bits = data;
+}
+
+READ_LINE_DEVICE_HANDLER( tms6100_data_r )
+{
+ tms6100_state *tms = get_safe_token(device);
+
+ return tms->data;
+}
+
+/*-------------------------------------------------
+ TMS 6100 device definition
+-------------------------------------------------*/
+
+static const char DEVTEMPLATE_SOURCE[] = __FILE__;
+
+#define DEVTEMPLATE_ID(p,s) p##tms6100##s
+#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET
+#define DEVTEMPLATE_NAME "TMS6100"
+#define DEVTEMPLATE_FAMILY "TI Speech"
+#include "devtempl.h"
+
+#define DEVTEMPLATE_DERIVED_ID(p,s) p##m58819##s
+#define DEVTEMPLATE_DERIVED_FEATURES DT_HAS_START
+#define DEVTEMPLATE_DERIVED_NAME "M58819"
+#include "devtempl.h"
+
+
+DEFINE_LEGACY_DEVICE(TMS6100, tms6100);
+DEFINE_LEGACY_DEVICE(M58819, m58819);