summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Sandro Ronco <sandro.ronco@gmx.com>2019-06-29 23:44:25 +0200
committer Sandro Ronco <sandro.ronco@gmx.com>2019-06-29 23:44:25 +0200
commit1bc2b0472856ce10a189c791bbbce66d0d6f9764 (patch)
tree02c415bd7dcc0059b9a2861967f44850d31276a2
parent804fc3d1884ec450a47f878e1639ef511cfcd4cc (diff)
tascr30: add display, inputs and SmartBoard. [Sandro Ronco]
Machines promoted to working ---------------------------- Tasc ChessSystem R30 [Sandro Ronco]
-rw-r--r--scripts/target/mame/mess.lua9
-rw-r--r--src/devices/video/t6963c.cpp197
-rw-r--r--src/devices/video/t6963c.h24
-rw-r--r--src/mame/drivers/tasc.cpp98
-rw-r--r--src/mame/layout/tascr30.lay480
-rw-r--r--src/mame/machine/smartboard.cpp282
-rw-r--r--src/mame/machine/smartboard.h60
7 files changed, 1118 insertions, 32 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 3f5c92c4f31..4b67abf9b56 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -1222,6 +1222,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"ta",
"tandberg",
"tangerin",
+ "tasc",
"tatung",
"teamconc",
"tektroni",
@@ -3366,6 +3367,13 @@ files {
MAME_DIR .. "src/mame/drivers/oric.cpp",
}
+createMESSProjects(_target, _subtarget, "tasc")
+files {
+ MAME_DIR .. "src/mame/drivers/tasc.cpp",
+ MAME_DIR .. "src/mame/machine/smartboard.cpp",
+ MAME_DIR .. "src/mame/machine/smartboard.h",
+}
+
createMESSProjects(_target, _subtarget, "tatung")
files {
MAME_DIR .. "src/mame/drivers/einstein.cpp",
@@ -4054,7 +4062,6 @@ files {
MAME_DIR .. "src/mame/drivers/systel1.cpp",
MAME_DIR .. "src/mame/drivers/talkingbb.cpp",
MAME_DIR .. "src/mame/drivers/talkingfb.cpp",
- MAME_DIR .. "src/mame/drivers/tasc.cpp",
MAME_DIR .. "src/mame/drivers/tavernie.cpp",
MAME_DIR .. "src/mame/drivers/tecnbras.cpp",
MAME_DIR .. "src/mame/drivers/telex1192.cpp",
diff --git a/src/devices/video/t6963c.cpp b/src/devices/video/t6963c.cpp
index 0a07a1a7553..7e62d70c0e8 100644
--- a/src/devices/video/t6963c.cpp
+++ b/src/devices/video/t6963c.cpp
@@ -10,6 +10,9 @@
#include "emu.h"
#include "t6963c.h"
+//#define VERBOSE 1
+#include "logmacro.h"
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -38,6 +41,16 @@ t6963c_device::t6963c_device(const machine_config &mconfig, const char *tag, dev
, m_data(0)
, m_adp(0)
, m_auto_mode(auto_mode::NONE)
+ , m_graphic_home(0)
+ , m_text_home(0)
+ , m_graphic_area(0)
+ , m_text_area(0)
+ , m_cgram_offset(0)
+ , m_mode(0)
+ , m_display_mode(0)
+ , m_font_size(6)
+ , m_number_cols(40)
+ , m_number_lines(8)
{
}
@@ -66,6 +79,16 @@ void t6963c_device::device_start()
save_item(NAME(m_data));
save_item(NAME(m_adp));
save_item(NAME(m_auto_mode));
+ save_item(NAME(m_graphic_home));
+ save_item(NAME(m_text_home));
+ save_item(NAME(m_graphic_area));
+ save_item(NAME(m_text_area));
+ save_item(NAME(m_cgram_offset));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_display_mode));
+ save_item(NAME(m_font_size));
+ save_item(NAME(m_number_cols));
+ save_item(NAME(m_number_lines));
}
@@ -76,6 +99,15 @@ void t6963c_device::device_start()
void t6963c_device::device_reset()
{
m_auto_mode = auto_mode::NONE;
+ m_data = 0;
+ m_adp = 0;
+ m_graphic_home = 0;
+ m_text_home = 0;
+ m_graphic_area = 0;
+ m_text_area = 0;
+ m_cgram_offset = 0;
+ m_mode = 0;
+ m_display_mode = 0;
}
@@ -105,11 +137,11 @@ void t6963c_device::write(offs_t offset, u8 data)
// Data register
if (m_auto_mode == auto_mode::WRITE)
{
- logerror("%s: Auto write %02X to %04X\n", machine().describe_context(), data, m_adp);
+ LOG("%s: Auto write %02X to %04X\n", machine().describe_context(), data, m_adp);
m_display_ram->write_byte(m_adp++, data);
}
else
- m_data = (u16(data) << 8) | (data >> 8);
+ m_data = (u16(data) << 8) | (m_data >> 8);
}
}
@@ -129,14 +161,16 @@ void t6963c_device::do_command(u8 cmd)
break;
case 0x02:
- logerror("%s: Setting offset register for CG RAM at %04X to %04XH\n",
+ LOG("%s: Setting offset register for CG RAM at %04X to %04XH\n",
machine().describe_context(),
(m_data & 0x1f) << 11,
(m_data & 0x1f) << 11 | 0x7ff);
+
+ m_cgram_offset = (m_data & 0x1f) << 11;
break;
case 0x04:
- logerror("%s: Setting address pointer = %04X\n", machine().describe_context(), m_data);
+ LOG("%s: Setting address pointer = %04X\n", machine().describe_context(), m_data);
m_adp = m_data;
break;
@@ -147,37 +181,51 @@ void t6963c_device::do_command(u8 cmd)
}
else if ((cmd & 0xfd) == 0x40)
{
- logerror("%s: Setting %s home address = %04X\n", machine().describe_context(),
+ LOG("%s: Setting %s home address = %04X\n", machine().describe_context(),
BIT(cmd, 1) ? "graphic" : "text",
m_data);
+
+ if (BIT(cmd, 1))
+ m_graphic_home = m_data;
+ else
+ m_text_home = m_data;
}
else if ((cmd & 0xfd) == 0x41)
{
- logerror("%s: Setting %s area = %d columns\n", machine().describe_context(),
+ LOG("%s: Setting %s area = %d columns\n", machine().describe_context(),
BIT(cmd, 1) ? "graphic" : "text",
m_data);
+
+
+ if (BIT(cmd, 1))
+ m_graphic_area = m_data;
+ else
+ m_text_area = m_data;
}
else if ((cmd & 0xf0) == 0x80)
{
- logerror("%s: %s mode, %s\n", machine().describe_context(),
+ LOG("%s: %s mode, %s\n", machine().describe_context(),
(cmd & 0x07) == 0x00 ? "OR"
: (cmd & 0x07) == 0x01 ? "EXOR"
: (cmd & 0x07) == 0x03 ? "AND"
: (cmd & 0x07) == 0x04 ? "Text attribute"
: "Unknown",
BIT(cmd, 3) ? "external CG RAM" : "internal CG ROM");
+
+ m_mode = cmd & 0x0f;
}
else if ((cmd & 0xf0) == 0x90)
{
if (cmd == 0x90)
- logerror("%s: Display off\n", machine().describe_context());
+ LOG("%s: Display off\n", machine().describe_context());
else
- logerror("%s: Text %s, graphic %s, cursor %s, blink %s\n",
+ LOG("%s: Text %s, graphic %s, cursor %s, blink %s\n",
machine().describe_context(),
BIT(cmd, 3) ? "on" : "off",
BIT(cmd, 2) ? "on" : "off",
BIT(cmd, 1) ? "on" : "off",
BIT(cmd, 0) ? "on" : "off");
+ m_display_mode = cmd & 0x0f;
}
else if ((cmd & 0xf8) == 0xa0)
{
@@ -185,20 +233,19 @@ void t6963c_device::do_command(u8 cmd)
}
else if ((cmd & 0xfe) == 0xb0)
{
- logerror("%s: Set data auto %s\n", machine().describe_context(), BIT(cmd, 0) ? "read" : "write");
+ LOG("%s: Set data auto %s\n", machine().describe_context(), BIT(cmd, 0) ? "read" : "write");
m_auto_mode = BIT(cmd, 0) ? auto_mode::READ : auto_mode::WRITE;
}
else if (cmd == 0xb2)
{
- logerror("%s: Auto reset\n", machine().describe_context());
+ LOG("%s: Auto reset\n", machine().describe_context());
m_auto_mode = auto_mode::NONE;
}
else if ((cmd & 0xf0) == 0xc0)
{
if (BIT(cmd, 0))
{
- logerror("%s: Read data from %04X and %s ADP\n", machine().describe_context(),
- BIT(cmd, 0) ? "read" : "write",
+ LOG("%s: Read data from %04X and %s ADP\n", machine().describe_context(),
m_adp,
(cmd & 0x0e) == 0x00 ? "increment"
: (cmd & 0x0e) == 0x02 ? "decrement"
@@ -207,7 +254,7 @@ void t6963c_device::do_command(u8 cmd)
}
else
{
- logerror("%s: Write %02X to %04X and %s ADP\n", machine().describe_context(),
+ LOG("%s: Write %02X to %04X and %s ADP\n", machine().describe_context(),
m_data >> 8,
m_adp,
(cmd & 0x0e) == 0x00 ? "increment"
@@ -216,11 +263,12 @@ void t6963c_device::do_command(u8 cmd)
: "invalid");
m_display_ram->write_byte(m_adp, m_data >> 8);
- if ((cmd & 0x0e) == 0x00)
- ++m_adp;
- else if ((cmd & 0x0e) == 0x02)
- --m_adp;
}
+
+ if ((cmd & 0x0e) == 0x00)
+ ++m_adp;
+ else if ((cmd & 0x0e) == 0x02)
+ --m_adp;
}
else if (cmd == 0xe0)
{
@@ -232,9 +280,17 @@ void t6963c_device::do_command(u8 cmd)
}
else if ((cmd & 0xf0) == 0xf0)
{
- logerror("%s: %s bit %d\n", machine().describe_context(),
+ LOG("%s: %s bit %d\n", machine().describe_context(),
BIT(cmd, 3) ? "Set" : "Reset",
cmd & 0x07);
+
+ u8 data = m_display_ram->read_byte(m_adp);
+ if (BIT(cmd, 3))
+ data |= 1 << (cmd & 0x07);
+ else
+ data &= ~(1 << (cmd & 0x07));
+
+ m_display_ram->write_byte(m_adp, data);
}
else
{
@@ -242,6 +298,88 @@ void t6963c_device::do_command(u8 cmd)
}
}
+void t6963c_device::set_fs(u8 data)
+{
+ m_font_size = 8 - (data & 3);
+}
+
+void t6963c_device::set_md(u8 data)
+{
+ // MD0, MD1
+ m_number_lines = 8 - (data & 3) * 2;
+
+ if (BIT(data, 4)) // MDS
+ m_number_lines += 8;
+
+ switch((data >> 2) & 3) // MD2, MD3
+ {
+ case 0: m_number_cols = 32; break;
+ case 1: m_number_cols = 40; break;
+ case 2: m_number_cols = 64; break;
+ case 3: m_number_cols = 80; break;
+ }
+}
+
+
+uint32_t t6963c_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(0, cliprect);
+
+ // Text layer
+ if (BIT(m_display_mode, 3))
+ for(int y=0; y<m_number_lines; y++)
+ for(int x=0; x<m_text_area; x++)
+ {
+ u8 c = m_display_ram->read_byte(m_text_home + y * m_number_cols + x);
+
+ for(int cy=0; cy<8; cy++)
+ {
+ u8 data;
+ if (!BIT(m_mode, 3))
+ {
+ if (c < 0x80)
+ data = m_cgrom[c * 8 + cy];
+ else
+ data = m_display_ram->read_byte(m_cgram_offset + (c & 0x7f) * 8 + cy);
+ }
+ else
+ data = m_display_ram->read_byte(m_cgram_offset + c * 8 + cy);
+
+ for(int cx=0; cx<m_font_size; cx++)
+ bitmap.pix16(y * 8 + cy, x * m_font_size + cx) = BIT(data, m_font_size - 1 - cx);
+ }
+ }
+
+ // Graphic layer
+ if (BIT(m_display_mode, 2))
+ for(int y=0; y<m_number_lines*8; y++)
+ for(int x=0; x<m_graphic_area; x++)
+ {
+ u8 data = m_display_ram->read_byte(m_graphic_home + y * m_number_cols + x);
+ for(int i=0; i<m_font_size; i++)
+ {
+ int pix = BIT(data, m_font_size - 1 - i);
+ switch(m_mode & 7)
+ {
+ case 0: // OR
+ bitmap.pix16(y, x * m_font_size + i) |= pix;
+ break;
+ case 1: // EXOR
+ bitmap.pix16(y, x * m_font_size + i) ^= pix;
+ break;
+ case 3: // AND
+ bitmap.pix16(y, x * m_font_size + i) &= pix;
+ break;
+ case 4: // Text attribute
+ logerror("%s: Unimplemented Text attribute\n", machine().describe_context());
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
//**************************************************************************
// T6963C-BASED LCD UNITS
@@ -254,6 +392,7 @@ void t6963c_device::do_command(u8 cmd)
lm24014h_device::lm24014h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, LM24014H, tag, owner, clock)
, m_lcdc(*this, "lcdc")
+ , m_fs(1)
{
}
@@ -264,6 +403,10 @@ lm24014h_device::lm24014h_device(const machine_config &mconfig, const char *tag,
void lm24014h_device::device_start()
{
+ save_item(NAME(m_fs));
+
+ m_lcdc->set_md(4); // 8 lines x 40 columns
+ m_lcdc->set_fs(m_fs << 1); // font size 6x8 or 8x8
}
@@ -277,6 +420,12 @@ void lm24014h_device::ram_map(address_map &map)
map(0x0000, 0x1fff).ram(); // TC5564AFL-15
}
+void lm24014h_device::lcd_palette(palette_device &palette) const
+{
+ palette.set_pen_color(0, rgb_t(138, 146, 148));
+ palette.set_pen_color(1, rgb_t(92, 83, 88));
+}
+
//-------------------------------------------------
// device_add_mconfig - add device-specific
@@ -287,6 +436,16 @@ void lm24014h_device::device_add_mconfig(machine_config &config)
{
T6963C(config, m_lcdc, 0); // XTAL is unknown
m_lcdc->set_addrmap(0, &lm24014h_device::ram_map);
+
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
+ screen.set_refresh_hz(50);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
+ screen.set_size(240, 64);
+ screen.set_visarea(0, 240-1, 0, 64-1);
+ screen.set_screen_update("lcdc", FUNC(t6963c_device::screen_update));
+ screen.set_palette("palette");
+
+ PALETTE(config, "palette", FUNC(lm24014h_device::lcd_palette), 2);
}
diff --git a/src/devices/video/t6963c.h b/src/devices/video/t6963c.h
index 6eabc1bc4c0..3cc0018f81b 100644
--- a/src/devices/video/t6963c.h
+++ b/src/devices/video/t6963c.h
@@ -12,6 +12,10 @@
#pragma once
+#include "emupal.h"
+#include "screen.h"
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -35,6 +39,12 @@ public:
u8 read(offs_t offset);
void write(offs_t offset, u8 data);
+ // Display configurations
+ void set_md(u8 data); // MD0, MD1, MD2, MD3, MDS
+ void set_fs(u8 data); // FS0, FS1
+
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
static constexpr feature_type unemulated_features() { return feature::GRAPHICS; }
protected:
@@ -58,6 +68,16 @@ private:
u16 m_data;
u16 m_adp;
auto_mode m_auto_mode;
+ u16 m_graphic_home;
+ u16 m_text_home;
+ u16 m_graphic_area;
+ u16 m_text_area;
+ u16 m_cgram_offset;
+ u8 m_mode;
+ u8 m_display_mode;
+ u8 m_font_size;
+ u8 m_number_cols;
+ u8 m_number_lines;
};
// ======================> lm24014h_device
@@ -71,6 +91,7 @@ public:
// CPU read/write access
u8 read(offs_t offset) { return m_lcdc->read(offset); }
void write(offs_t offset, u8 data) { m_lcdc->write(offset, data); }
+ void set_fs(u8 data) { m_fs = data & 1; }
protected:
// device-specific overrides
@@ -78,12 +99,15 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
+ void lcd_palette(palette_device &palette) const;
+
private:
// internal configuration
void ram_map(address_map &map);
// internal LCD controller
required_device<t6963c_device> m_lcdc;
+ int m_fs;
};
// device type declarations
diff --git a/src/mame/drivers/tasc.cpp b/src/mame/drivers/tasc.cpp
index 671c521eedc..06988487ecb 100644
--- a/src/mame/drivers/tasc.cpp
+++ b/src/mame/drivers/tasc.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:hap
+// copyright-holders:hap, Sandro Ronco
/******************************************************************************
Tasc ChessSystem
@@ -27,14 +27,22 @@ references:
- https://www.schach-computer.info/wiki/index.php?title=Tasc_SmartBoard
- https://www.miclangschach.de/index.php?n=Main.TascR30
-TODO:
-- everything
+notes:
+- holding LEFT+RIGHT on boot load the QC TestMode
+- holding UP+DOWN on boot load the TestMode
******************************************************************************/
#include "emu.h"
#include "cpu/arm/arm.h"
+#include "machine/nvram.h"
+#include "machine/smartboard.h"
#include "machine/timer.h"
+#include "video/t6963c.h"
+#include "sound/spkrdev.h"
+#include "speaker.h"
+
+#include "tascr30.lh"
namespace {
@@ -45,9 +53,14 @@ public:
tasc_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
+ m_lcd(*this, "lcd"),
+ m_smartboard(*this, "smartboard"),
m_rom(*this, "maincpu"),
+ m_speaker(*this, "speaker"),
m_mainram(*this, "mainram"),
- m_disable_bootrom(*this, "disable_bootrom")
+ m_disable_bootrom(*this, "disable_bootrom"),
+ m_inputs(*this, "IN.%u", 0U),
+ m_out_leds(*this, "pled%u", 0U)
{ }
void tasc(machine_config &config);
@@ -59,13 +72,19 @@ protected:
private:
// devices/pointers
required_device<arm_cpu_device> m_maincpu;
+ required_device<lm24014h_device> m_lcd;
+ required_device<tasc_sb30_device> m_smartboard;
required_region_ptr<u32> m_rom;
+ required_device<speaker_sound_device> m_speaker;
required_shared_ptr<u32> m_mainram;
required_device<timer_device> m_disable_bootrom;
+ required_ioport_array<4> m_inputs;
+ output_finder<2> m_out_leds;
void main_map(address_map &map);
bool m_bootrom_enabled;
+ uint32_t m_mux;
TIMER_DEVICE_CALLBACK_MEMBER(disable_bootrom) { m_bootrom_enabled = false; }
// I/O handlers
@@ -76,12 +95,15 @@ private:
void tasc_state::machine_start()
{
+ m_out_leds.resolve();
save_item(NAME(m_bootrom_enabled));
+ save_item(NAME(m_mux));
}
void tasc_state::machine_reset()
{
m_bootrom_enabled = true;
+ m_mux = 0;
}
@@ -96,23 +118,41 @@ READ32_MEMBER(tasc_state::bootrom_r)
READ32_MEMBER(tasc_state::p1000_r)
{
- logerror("p1000_r\n");
-
// disconnect bootrom from the bus after next opcode
if (m_bootrom_enabled && !m_disable_bootrom->enabled() && !machine().side_effects_disabled())
m_disable_bootrom->adjust(m_maincpu->cycles_to_attotime(5));
- return 0;
+ uint32_t data = m_smartboard->read();
+
+ for(int i=0; i<4; i++)
+ {
+ if (BIT(m_mux, i))
+ data |= (m_inputs[i]->read() << 24);
+ }
+
+ return data;
}
WRITE32_MEMBER(tasc_state::p1000_w)
{
- // similar to risc2500 where msb is select, lsb is data
- logerror("p1000_w: %02X %02X\n", data >> 24, data & 0xff);
+ if (ACCESSING_BITS_24_31)
+ {
+ if (BIT(data, 27))
+ m_lcd->write(BIT(data, 26), data & 0xff);
+
+ m_smartboard->write((data >> 24) & 0xff);
+ }
+ else
+ {
+ m_out_leds[0] = BIT(data, 0);
+ m_out_leds[1] = BIT(data, 1);
+ m_speaker->level_w((data >> 2) & 3);
+ }
+
+ COMBINE_DATA(&m_mux);
}
-
/******************************************************************************
Address Maps
******************************************************************************/
@@ -123,7 +163,7 @@ void tasc_state::main_map(address_map &map)
map(0x00000000, 0x0000000b).r(FUNC(tasc_state::bootrom_r));
map(0x01000000, 0x01000003).rw(FUNC(tasc_state::p1000_r), FUNC(tasc_state::p1000_w));
map(0x02000000, 0x0203ffff).rom().region("maincpu", 0);
- //map(0x03000000, 0x03003fff).ram();
+ map(0x03000000, 0x0307ffff).ram().share("nvram").umask32(0x000000ff);
}
@@ -133,6 +173,25 @@ void tasc_state::main_map(address_map &map)
******************************************************************************/
static INPUT_PORTS_START( tasc )
+ PORT_START("IN.0")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("PLAY")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("LEFT")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
+
+ PORT_START("IN.1")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("BACK")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("RIGHT")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
+
+ PORT_START("IN.2")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("MENU")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("UP")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Left Clock")
+
+ PORT_START("IN.3")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("ENTER")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("DOWN")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Right Clock")
INPUT_PORTS_END
@@ -150,6 +209,21 @@ void tasc_state::tasc(machine_config &config)
m_maincpu->set_periodic_int(FUNC(tasc_state::irq1_line_hold), attotime::from_hz(250));
TIMER(config, "disable_bootrom").configure_generic(FUNC(tasc_state::disable_bootrom));
+
+ NVRAM(config, "nvram", nvram_device::DEFAULT_NONE);
+
+ LM24014H(config, m_lcd, 0);
+ m_lcd->set_fs(1); // font size 6x8
+
+ TASC_SB30(config, m_smartboard, 0);
+
+ config.set_default_layout(layout_tascr30);
+
+ /* sound hardware */
+ SPEAKER(config, "mono").front_center();
+ static const int16_t speaker_levels[3] = { 0, 32767, -32768 };
+ SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.75);
+ m_speaker->set_levels(3, speaker_levels);
}
@@ -189,4 +263,4 @@ ROM_END
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
-CONS( 1993, tascr30, 0, 0, tasc, tasc, tasc_state, empty_init, "Tasc", "ChessSystem R30", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+CONS( 1993, tascr30, 0, 0, tasc, tasc, tasc_state, empty_init, "Tasc", "ChessSystem R30", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
diff --git a/src/mame/layout/tascr30.lay b/src/mame/layout/tascr30.lay
new file mode 100644
index 00000000000..180f01fb6f8
--- /dev/null
+++ b/src/mame/layout/tascr30.lay
@@ -0,0 +1,480 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+ <element name="ledr" defstate="0">
+ <disk state="0"> <color red="0.15" green="0.15" blue="0.15" /> </disk>
+ <disk state="1"> <color red="0.75" green="0.00" blue="0.00" /> </disk>
+ </element>
+ <element name="ledg" defstate="0">
+ <disk state="0"> <color red="0.15" green="0.15" blue="0.15" /> </disk>
+ <disk state="1"> <color red="0.00" green="0.75" blue="0.00" /> </disk>
+ </element>
+
+ <element name="hlb">
+ <rect state="0"> <color red="0.1" green="0.1" blue="0.1" /> </rect>
+ <rect state="1"> <color red="0.4" green="0.4" blue="0.4" /> </rect>
+ </element>
+
+ <element name="hlbr">
+ <disk state="0"> <color red="0.56" green="0.33" blue="0.12" /> </disk>
+ <disk state="1"> <color red="0.76" green="0.53" blue="0.32" /> </disk>
+ </element>
+
+ <element name="piece" defstate="0">
+ <image file="chess/wn.png" state="1"/>
+ <image file="chess/wn.png" state="2"/>
+ <image file="chess/bk.png" state="3"/>
+ <image file="chess/wk.png" state="4"/>
+ <image file="chess/bq.png" state="5"/>
+ <image file="chess/wq.png" state="6"/>
+ <image file="chess/br.png" state="7"/>
+ <image file="chess/br.png" state="8"/>
+ <image file="chess/wr.png" state="9"/>
+ <image file="chess/wr.png" state="10"/>
+ <image file="chess/bb.png" state="11"/>
+ <image file="chess/bb.png" state="12"/>
+ <image file="chess/wb.png" state="13"/>
+ <image file="chess/wb.png" state="14"/>
+ <image file="chess/bn.png" state="15"/>
+ <image file="chess/bn.png" state="16"/>
+ <image file="chess/wp.png" state="17"/>
+ <image file="chess/wp.png" state="18"/>
+ <image file="chess/wp.png" state="19"/>
+ <image file="chess/wp.png" state="20"/>
+ <image file="chess/wp.png" state="21"/>
+ <image file="chess/wp.png" state="22"/>
+ <image file="chess/wp.png" state="23"/>
+ <image file="chess/wp.png" state="24"/>
+ <image file="chess/bp.png" state="25"/>
+ <image file="chess/bp.png" state="26"/>
+ <image file="chess/bp.png" state="27"/>
+ <image file="chess/bp.png" state="28"/>
+ <image file="chess/bp.png" state="29"/>
+ <image file="chess/bp.png" state="30"/>
+ <image file="chess/bp.png" state="31"/>
+ <image file="chess/bp.png" state="32"/>
+
+ <!-- selected pieces -->
+ <image file="chess/wn.png" state="33"><color alpha="0.5" /></image>
+ <image file="chess/wn.png" state="34"><color alpha="0.5" /></image>
+ <image file="chess/bk.png" state="35"><color alpha="0.5" /></image>
+ <image file="chess/wk.png" state="36"><color alpha="0.5" /></image>
+ <image file="chess/bq.png" state="37"><color alpha="0.5" /></image>
+ <image file="chess/wq.png" state="38"><color alpha="0.5" /></image>
+ <image file="chess/br.png" state="39"><color alpha="0.5" /></image>
+ <image file="chess/br.png" state="40"><color alpha="0.5" /></image>
+ <image file="chess/wr.png" state="41"><color alpha="0.5" /></image>
+ <image file="chess/wr.png" state="42"><color alpha="0.5" /></image>
+ <image file="chess/bb.png" state="43"><color alpha="0.5" /></image>
+ <image file="chess/bb.png" state="44"><color alpha="0.5" /></image>
+ <image file="chess/wb.png" state="45"><color alpha="0.5" /></image>
+ <image file="chess/wb.png" state="46"><color alpha="0.5" /></image>
+ <image file="chess/bn.png" state="47"><color alpha="0.5" /></image>
+ <image file="chess/bn.png" state="48"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="49"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="50"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="51"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="52"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="53"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="54"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="55"><color alpha="0.5" /></image>
+ <image file="chess/wp.png" state="56"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="57"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="58"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="59"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="60"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="61"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="62"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="63"><color alpha="0.5" /></image>
+ <image file="chess/bp.png" state="64"><color alpha="0.5" /></image>
+ </element>
+
+ <element name="text_1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="1"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_2"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="2"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_3"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="3"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_4"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="4"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_5"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="5"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_6"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="6"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_7"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="7"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_8"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="8"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_a"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="A"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_b"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="B"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_c"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="C"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_d"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="D"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_e"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="E"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_f"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="F"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_g"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="G"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_h"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="H"> <color red="1" green="1" blue="1" /></text> </element>
+ <element name="text_play"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="PLAY"> <color red="0" green="0" blue="0" /></text> </element>
+ <element name="text_back"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="BACK"> <color red="0" green="0" blue="0" /></text> </element>
+ <element name="text_menu"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="MENU"> <color red="0" green="0" blue="0" /></text> </element>
+ <element name="text_enter"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="ENTER"> <color red="0" green="0" blue="0" /></text> </element>
+ <element name="text_gt"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="&gt;"> <color red="0" green="0" blue="0" /></text> </element>
+ <element name="text_lt"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect> <text string="&lt;"> <color red="0" green="0" blue="0" /></text> </element>
+
+ <element name="background"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect></element>
+ <element name="background_cp"> <rect><color red="0.89" green="0.85" blue="0.66" /></rect></element>
+
+ <group name="control_panel">
+ <screen index="0"><bounds x="30" y="40" width="240" height="64" /></screen>
+ <bezel element="background_cp"><bounds x="0" y="00" width="300" height="39" /></bezel>
+ <bezel element="background_cp"><bounds x="0" y="105" width="300" height="80" /></bezel>
+ <bezel element="background_cp"><bounds x="0" y="20" width="29" height="90" /></bezel>
+ <bezel element="background_cp"><bounds x="271" y="20" width="29" height="90" /></bezel>
+
+ <bezel element="hlbr" inputtag="IN.2" inputmask="0x80"><bounds x="50" y="11" width="15" height="15" /></bezel>
+ <bezel element="hlbr" inputtag="IN.3" inputmask="0x80"><bounds x="235" y="11" width="15" height="15" /></bezel>
+
+ <bezel name="pled0" element="ledg"><bounds x="20" y="15" width="8" height="8" /></bezel>
+ <bezel name="pled1" element="ledg"><bounds x="272" y="15" width="8" height="8" /></bezel>
+
+ <bezel element="text_play" ><bounds x="30" y="125" width="20" height="6" /></bezel>
+ <bezel element="text_back" ><bounds x="60" y="125" width="20" height="6" /></bezel>
+ <bezel element="text_menu" ><bounds x="90" y="125" width="20" height="6" /></bezel>
+
+ <bezel element="text_lt" ><bounds x="145" y="135" width="6" height="15" /></bezel>
+ <bezel element="text_gt" ><bounds x="233" y="135" width="6" height="15" /></bezel>
+ <bezel element="text_lt" ><bounds x="182.5" y="114" width="20" height="6" /><orientation rotate="90" /></bezel>
+ <bezel element="text_gt" ><bounds x="182.5" y="165" width="20" height="6" /><orientation rotate="90" /></bezel>
+ <bezel element="text_enter" ><bounds x="250" y="125" width="20" height="6" /></bezel>
+
+ <bezel element="hlb" inputtag="IN.0" inputmask="0x20"><bounds x="30" y="135" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.1" inputmask="0x20"><bounds x="60" y="135" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.2" inputmask="0x20"><bounds x="90" y="135" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.0" inputmask="0x40"><bounds x="152.5" y="135" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.3" inputmask="0x40"><bounds x="182.5" y="148" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.2" inputmask="0x40"><bounds x="182.5" y="123" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.1" inputmask="0x40"><bounds x="212.5" y="135" width="20" height="15" /></bezel>
+ <bezel element="hlb" inputtag="IN.3" inputmask="0x20"><bounds x="250" y="135" width="20" height="15" /></bezel>
+ </group>
+
+
+<!-- sb board -->
+
+ <element name="cblack"><rect><color red="0.56" green="0.33" blue="0.12" /></rect></element>
+ <element name="cwhite"><rect><color red="0.84" green="0.75" blue="0.50" /></rect></element>
+ <element name="board_border"><rect><color red="0.00" green="0.00" blue="0.00" /></rect></element>
+
+ <element name="hlbb" defstate="0">
+ <text string=" "><bounds x="0" y="0" width="1" height="1" /></text>
+ <disk state="1">
+ <bounds x="0.12" y="0.12" width="0.76" height="0.76" />
+ <color red="0" green="0" blue="0" />
+ </disk>
+ </element>
+
+ <group name="sb_board">
+ <bounds x="0" y="0" width="82" height="82" />
+ <bezel element="board_border"><bounds x="0.7" y="0.7" width="0.3" height="80.6" /></bezel>
+ <bezel element="board_border"><bounds x="81" y="0.7" width="0.3" height="80.6" /></bezel>
+ <bezel element="board_border"><bounds x="0.7" y="0.7" width="80.6" height="0.3" /></bezel>
+ <bezel element="board_border"><bounds x="0.7" y="81" width="80.6" height="0.3" /></bezel>
+
+ <!-- squares (avoid seams) -->
+ <bezel element="cwhite"><bounds x="1" y="1" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="11" y="1" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="21" y="1" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="31" y="1" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="41" y="1" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="51" y="1" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="61" y="1" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="71" y="1" width="10" height="11" /></bezel>
+
+ <bezel element="cblack"><bounds x="1" y="11" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="11" y="11" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="21" y="11" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="31" y="11" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="41" y="11" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="51" y="11" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="61" y="11" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="71" y="11" width="10" height="11" /></bezel>
+
+ <bezel element="cwhite"><bounds x="1" y="21" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="11" y="21" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="21" y="21" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="31" y="21" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="41" y="21" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="51" y="21" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="61" y="21" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="71" y="21" width="10" height="11" /></bezel>
+
+ <bezel element="cblack"><bounds x="1" y="31" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="11" y="31" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="21" y="31" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="31" y="31" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="41" y="31" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="51" y="31" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="61" y="31" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="71" y="31" width="10" height="11" /></bezel>
+
+ <bezel element="cwhite"><bounds x="1" y="41" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="11" y="41" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="21" y="41" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="31" y="41" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="41" y="41" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="51" y="41" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="61" y="41" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="71" y="41" width="10" height="11" /></bezel>
+
+ <bezel element="cblack"><bounds x="1" y="51" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="11" y="51" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="21" y="51" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="31" y="51" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="41" y="51" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="51" y="51" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="61" y="51" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="71" y="51" width="10" height="11" /></bezel>
+
+ <bezel element="cwhite"><bounds x="1" y="61" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="11" y="61" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="21" y="61" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="31" y="61" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="41" y="61" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="51" y="61" width="11" height="11" /></bezel>
+ <bezel element="cwhite"><bounds x="61" y="61" width="11" height="11" /></bezel>
+ <bezel element="cblack"><bounds x="71" y="61" width="10" height="11" /></bezel>
+
+ <bezel element="cblack"><bounds x="1" y="71" width="11" height="10" /></bezel>
+ <bezel element="cwhite"><bounds x="11" y="71" width="11" height="10" /></bezel>
+ <bezel element="cblack"><bounds x="21" y="71" width="11" height="10" /></bezel>
+ <bezel element="cwhite"><bounds x="31" y="71" width="11" height="10" /></bezel>
+ <bezel element="cblack"><bounds x="41" y="71" width="11" height="10" /></bezel>
+ <bezel element="cwhite"><bounds x="51" y="71" width="11" height="10" /></bezel>
+ <bezel element="cblack"><bounds x="61" y="71" width="11" height="10" /></bezel>
+ <bezel element="cwhite"><bounds x="71" y="71" width="10" height="10" /></bezel>
+
+ <!-- sensors, pieces -->
+ <repeat count="8">
+ <param name="y" start="1" increment="10" />
+ <param name="i" start="8" increment="-1" />
+
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x01"><bounds x="1" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x02"><bounds x="11" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x04"><bounds x="21" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x08"><bounds x="31" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x10"><bounds x="41" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x20"><bounds x="51" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x40"><bounds x="61" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+ <bezel element="hlbb" inputtag="smartboard:board:RANK.~i~" inputmask="0x80"><bounds x="71" y="~y~" width="10" height="10" /><color alpha="0.1" /></bezel>
+
+ <bezel name="piece_a~i~" element="piece"><bounds x="1" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_b~i~" element="piece"><bounds x="11" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_c~i~" element="piece"><bounds x="21" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_d~i~" element="piece"><bounds x="31" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_e~i~" element="piece"><bounds x="41" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_f~i~" element="piece"><bounds x="51" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_g~i~" element="piece"><bounds x="61" y="~y~" width="10" height="10" /></bezel>
+ <bezel name="piece_h~i~" element="piece"><bounds x="71" y="~y~" width="10" height="10" /></bezel>
+ </repeat>
+
+ <!-- LEDs -->
+ <repeat count="9">
+ <param name="x" start="80.3" increment="-10" />
+ <param name="i" start="0" increment="1" />
+
+ <bezel name="led_0~i~" element="ledr"><bounds x="~x~" y="0.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_1~i~" element="ledr"><bounds x="~x~" y="10.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_2~i~" element="ledr"><bounds x="~x~" y="20.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_3~i~" element="ledr"><bounds x="~x~" y="30.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_4~i~" element="ledr"><bounds x="~x~" y="40.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_5~i~" element="ledr"><bounds x="~x~" y="50.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_6~i~" element="ledr"><bounds x="~x~" y="60.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_7~i~" element="ledr"><bounds x="~x~" y="70.3" width="1.4" height="1.4" /></bezel>
+ <bezel name="led_8~i~" element="ledr"><bounds x="~x~" y="80.3" width="1.4" height="1.4" /></bezel>
+ </repeat>
+ </group>
+
+
+<!-- sb ui -->
+
+ <element name="piece_ui" defstate="0">
+ <image file="chess/wp.png" state="1"/>
+ <image file="chess/wn.png" state="2"/>
+ <image file="chess/wb.png" state="3"/>
+ <image file="chess/wr.png" state="4"/>
+ <image file="chess/wq.png" state="5"/>
+ <image file="chess/wk.png" state="6"/>
+
+ <image file="chess/bp.png" state="7"/>
+ <image file="chess/bn.png" state="8"/>
+ <image file="chess/bb.png" state="9"/>
+ <image file="chess/br.png" state="10"/>
+ <image file="chess/bq.png" state="11"/>
+ <image file="chess/bk.png" state="12"/>
+
+ <!-- selected pieces -->
+ <image file="chess/wp.png" state="13"><color alpha="0.5" /></image>
+ <image file="chess/wn.png" state="14"><color alpha="0.5" /></image>
+ <image file="chess/wb.png" state="15"><color alpha="0.5" /></image>
+ <image file="chess/wr.png" state="16"><color alpha="0.5" /></image>
+ <image file="chess/wq.png" state="17"><color alpha="0.5" /></image>
+ <image file="chess/wk.png" state="18"><color alpha="0.5" /></image>
+
+ <image file="chess/bp.png" state="19"><color alpha="0.5" /></image>
+ <image file="chess/bn.png" state="20"><color alpha="0.5" /></image>
+ <image file="chess/bb.png" state="21"><color alpha="0.5" /></image>
+ <image file="chess/br.png" state="22"><color alpha="0.5" /></image>
+ <image file="chess/bq.png" state="23"><color alpha="0.5" /></image>
+ <image file="chess/bk.png" state="24"><color alpha="0.5" /></image>
+ </element>
+ <element name="hlub" defstate="0">
+ <rect state="1"><color red="0" green="0" blue="0" /></rect>
+ </element>
+ <element name="text_uit1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="S.BOARD"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uit2"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="INTERFACE"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uib1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect> <text string="BOARD:"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uib2">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string="RESET"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uib3">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string="CLEAR"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uis1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect><text string="SPAWN:"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uih1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect><text string="HAND:"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uih2">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string="REMOVE"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uiu1"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect><text string="UNDO:"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uiu2a">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string=" &lt;&lt;"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uiu2b">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string=" &lt; "><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uiu2c">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string=" &gt;"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uiu2d">
+ <rect><color red="0.84" green="0.75" blue="0.50" /></rect>
+ <text string=" &gt;&gt;"><color red="0.01" green="0.01" blue="0.01" /></text>
+ </element>
+ <element name="text_uiu3a" defstate="0">
+ <rect><color red="0.56" green="0.33" blue="0.12" /></rect>
+ <simplecounter maxstate="999" digits="1" align="2">
+ <color red="0.81" green="0.8" blue="0.79" />
+ </simplecounter>
+ </element>
+ <element name="text_uiu3b"> <rect><color red="0.56" green="0.33" blue="0.12" /></rect><text string="/"><color red="0.81" green="0.8" blue="0.79" /></text></element>
+ <element name="text_uiu3c" defstate="0">
+ <rect><color red="0.56" green="0.33" blue="0.12" /></rect>
+ <simplecounter maxstate="999" digits="1" align="1">
+ <color red="0.81" green="0.8" blue="0.79" />
+ </simplecounter>
+ </element>
+
+ <group name="sb_ui">
+ <bounds x="0" y="0" width="10" height="80" />
+ <bezel element="cwhite"><bounds x="0" y="0" width="10" height="1" /></bezel>
+ <bezel element="cwhite"><bounds x="0" y="7" width="10" height="1" /></bezel>
+ <bezel element="cwhite"><bounds x="0" y="79" width="10" height="1" /></bezel>
+ <bezel element="text_uit1"><bounds x="0" y="2" width="10" height="2" /></bezel>
+ <bezel element="text_uit2"><bounds x="0" y="4" width="10" height="2" /></bezel>
+
+ <!-- board -->
+ <bezel element="text_uib1"><bounds x="0" y="9" width="10" height="2" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="11.5" width="8" height="2.5" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="15" width="8" height="2.5" /></bezel>
+
+ <bezel element="text_uib2"><bounds x="1.5" y="11.75" width="7" height="2" /></bezel>
+ <bezel element="text_uib3"><bounds x="1.5" y="15.25" width="7" height="2" /></bezel>
+
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x200"><bounds x="1" y="11.5" width="8" height="2.5" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x100"><bounds x="1" y="15" width="8" height="2.5" /><color alpha="0.25" /></bezel>
+
+ <!-- spawn -->
+ <bezel element="text_uis1"><bounds x="0" y="20.5" width="10" height="2" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="23" width="8" height="12" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="36" width="8" height="12" /></bezel>
+
+ <bezel name="piece_ui1" element="piece_ui"><bounds x="1" y="23" width="4" height="4" /></bezel>
+ <bezel name="piece_ui2" element="piece_ui"><bounds x="1" y="27" width="4" height="4" /></bezel>
+ <bezel name="piece_ui3" element="piece_ui"><bounds x="1" y="31" width="4" height="4" /></bezel>
+ <bezel name="piece_ui4" element="piece_ui"><bounds x="5" y="23" width="4" height="4" /></bezel>
+ <bezel name="piece_ui5" element="piece_ui"><bounds x="5" y="27" width="4" height="4" /></bezel>
+ <bezel name="piece_ui6" element="piece_ui"><bounds x="5" y="31" width="4" height="4" /></bezel>
+ <bezel name="piece_ui7" element="piece_ui"><bounds x="1" y="36" width="4" height="4" /></bezel>
+ <bezel name="piece_ui8" element="piece_ui"><bounds x="1" y="40" width="4" height="4" /></bezel>
+ <bezel name="piece_ui9" element="piece_ui"><bounds x="1" y="44" width="4" height="4" /></bezel>
+ <bezel name="piece_ui10" element="piece_ui"><bounds x="5" y="36" width="4" height="4" /></bezel>
+ <bezel name="piece_ui11" element="piece_ui"><bounds x="5" y="40" width="4" height="4" /></bezel>
+ <bezel name="piece_ui12" element="piece_ui"><bounds x="5" y="44" width="4" height="4" /></bezel>
+
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0001"><bounds x="1" y="23" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0002"><bounds x="1" y="27" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0004"><bounds x="1" y="31" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0008"><bounds x="5" y="23" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0010"><bounds x="5" y="27" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0020"><bounds x="5" y="31" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0040"><bounds x="1" y="36" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0080"><bounds x="1" y="40" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0100"><bounds x="1" y="44" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0200"><bounds x="5" y="36" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0400"><bounds x="5" y="40" width="4" height="4" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:SPAWN" inputmask="0x0800"><bounds x="5" y="44" width="4" height="4" /><color alpha="0.25" /></bezel>
+
+ <!-- hand -->
+ <bezel element="text_uih1"><bounds x="0" y="51" width="10" height="2" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="53.5" width="8" height="6" /></bezel>
+ <bezel name="piece_ui0" element="piece"><bounds x="2" y="53.5" width="6" height="6" /></bezel>
+
+ <bezel element="cwhite"><bounds x="1" y="60.5" width="8" height="2.5" /></bezel>
+ <bezel element="text_uih2"><bounds x="1.5" y="60.75" width="7" height="2" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x08"><bounds x="1" y="60.5" width="8" height="2.5" /><color alpha="0.25" /></bezel>
+
+ <!-- undo -->
+ <bezel element="text_uiu1"><bounds x="0" y="66" width="10" height="2" /></bezel>
+ <bezel element="cwhite"><bounds x="1" y="68.5" width="1.7" height="6" /></bezel>
+ <bezel element="cwhite"><bounds x="3.1" y="68.5" width="1.7" height="6" /></bezel>
+ <bezel element="cwhite"><bounds x="5.2" y="68.5" width="1.7" height="6" /></bezel>
+ <bezel element="cwhite"><bounds x="7.3" y="68.5" width="1.7" height="6" /></bezel>
+ <bezel element="text_uiu2a"><bounds x="1" y="69.5" width="1.7" height="4" /></bezel>
+ <bezel element="text_uiu2b"><bounds x="3.1" y="69.5" width="1.7" height="4" /></bezel>
+ <bezel element="text_uiu2c"><bounds x="5.2" y="69.5" width="1.7" height="4" /></bezel>
+ <bezel element="text_uiu2d"><bounds x="7.3" y="69.5" width="1.7" height="4" /></bezel>
+
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x10"><bounds x="1" y="68.5" width="1.7" height="6" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x20"><bounds x="3.1" y="68.5" width="1.7" height="6" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x40"><bounds x="5.2" y="68.5" width="1.7" height="6" /><color alpha="0.25" /></bezel>
+ <bezel element="hlub" inputtag="smartboard:board:UI" inputmask="0x80"><bounds x="7.3" y="68.5" width="1.7" height="6" /><color alpha="0.25" /></bezel>
+
+ <bezel name="count_ui0" element="text_uiu3a"><bounds x="0" y="75" width="4" height="2" /></bezel>
+ <bezel name="count_ui1" element="text_uiu3c"><bounds x="6" y="75" width="4" height="2" /></bezel>
+ <bezel element="text_uiu3b"><bounds x="4" y="75" width="2" height="2" /></bezel>
+ </group>
+
+ <view name="Chessboard + Control Panel">
+ <bezel element="background"><bounds x="0" y="0" width="108" height="95" /></bezel>
+
+ <!-- chessboard coords -->
+
+ <bezel element="text_8" ><bounds x="14.5" y="12" width="2" height="2" /></bezel>
+ <bezel element="text_7" ><bounds x="14.5" y="22" width="2" height="2" /></bezel>
+ <bezel element="text_6" ><bounds x="14.5" y="32" width="2" height="2" /></bezel>
+ <bezel element="text_5" ><bounds x="14.5" y="42" width="2" height="2" /></bezel>
+ <bezel element="text_4" ><bounds x="14.5" y="52" width="2" height="2" /></bezel>
+ <bezel element="text_3" ><bounds x="14.5" y="62" width="2" height="2" /></bezel>
+ <bezel element="text_2" ><bounds x="14.5" y="72" width="2" height="2" /></bezel>
+ <bezel element="text_1" ><bounds x="14.5" y="82" width="2" height="2" /></bezel>
+ <bezel element="text_a" ><bounds x="22" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_b" ><bounds x="32" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_c" ><bounds x="42" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_d" ><bounds x="52" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_e" ><bounds x="62" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_f" ><bounds x="72" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_g" ><bounds x="82" y="90" width="2" height="2" /></bezel>
+ <bezel element="text_h" ><bounds x="92" y="90" width="2" height="2" /></bezel>
+
+ <group ref="sb_board"><bounds x="17" y="7" width="82" height="82" /></group>
+ <group ref="sb_ui"><bounds x="2" y="8" width="10" height="80" /></group>
+ <group ref="control_panel"><bounds x="0" y="95" width="108" height="67" /></group>
+ </view>
+
+ <view name="Control Panel">
+ <group ref="control_panel"><bounds x="0" y="0" width="300" height="185" /></group>
+ </view>
+</mamelayout>
diff --git a/src/mame/machine/smartboard.cpp b/src/mame/machine/smartboard.cpp
new file mode 100644
index 00000000000..7dd37e2ac54
--- /dev/null
+++ b/src/mame/machine/smartboard.cpp
@@ -0,0 +1,282 @@
+// license:BSD-3-Clause
+// copyright-holders:Sandro Ronco
+/******************************************************************************
+
+ Tasc SmartBoard
+
+ The SmartBoard can detect which piece is present on a specific square, more
+ info on the technology used in the piece recognition system can be found in
+ the US patent 5,129,654
+
+******************************************************************************/
+
+#include "emu.h"
+#include "smartboard.h"
+
+enum
+{
+ SB30_WHITE_KNIGHT1 = 0,
+ SB30_WHITE_KNIGHT2 = 1,
+ SB30_BLACK_KING = 2,
+ SB30_WHITE_KING = 3,
+ SB30_BLACK_QUEEN = 4,
+ SB30_WHITE_QUEEN = 5,
+ SB30_BLACK_ROOK1 = 6,
+ SB30_BLACK_ROOK2 = 7,
+ SB30_WHITE_ROOK1 = 8,
+ SB30_WHITE_ROOK2 = 9,
+ SB30_BLACK_BISHOP1 = 10,
+ SB30_BLACK_BISHOP2 = 11,
+ SB30_WHITE_BISHOP1 = 12,
+ SB30_WHITE_BISHOP2 = 13,
+ SB30_BLACK_KNIGHT1 = 14,
+ SB30_BLACK_KNIGHT2 = 15,
+ SB30_WHITE_PAWN1 = 16,
+ SB30_WHITE_PAWN2 = 17,
+ SB30_WHITE_PAWN3 = 18,
+ SB30_WHITE_PAWN4 = 19,
+ SB30_WHITE_PAWN5 = 20,
+ SB30_WHITE_PAWN6 = 21,
+ SB30_WHITE_PAWN7 = 22,
+ SB30_WHITE_PAWN8 = 23,
+ SB30_BLACK_PAWN1 = 24,
+ SB30_BLACK_PAWN2 = 25,
+ SB30_BLACK_PAWN3 = 26,
+ SB30_BLACK_PAWN4 = 27,
+ SB30_BLACK_PAWN5 = 28,
+ SB30_BLACK_PAWN6 = 29,
+ SB30_BLACK_PAWN7 = 30,
+ SB30_BLACK_PAWN8 = 31,
+};
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(TASC_SB30, tasc_sb30_device, "tasc_sb30", "Tasc SmartBoard SB30")
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// tasc_sb30_device - constructor
+//-------------------------------------------------
+
+tasc_sb30_device::tasc_sb30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, TASC_SB30, tag, owner, clock)
+ , m_board(*this, "board")
+ , m_out_leds(*this, "led_%u%u", 0U, 0U)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void tasc_sb30_device::device_start()
+{
+ m_out_leds.resolve();
+ m_leds_off_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tasc_sb30_device::leds_off_cb), this));
+
+ save_item(NAME(m_data));
+ save_item(NAME(m_position));
+ save_item(NAME(m_shift));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void tasc_sb30_device::device_reset()
+{
+ m_data = 0;
+ m_position = 0;
+ m_shift = 0;
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device-specific
+// machine configuration
+//-------------------------------------------------
+
+void tasc_sb30_device::device_add_mconfig(machine_config &config)
+{
+ SENSORBOARD(config, m_board);
+ m_board->set_type(sensorboard_device::INDUCTIVE);
+ m_board->set_max_id(32);
+ m_board->set_mod_enable(false);
+ m_board->init_cb().set(FUNC(tasc_sb30_device::init_cb));
+ m_board->spawn_cb().set(FUNC(tasc_sb30_device::spawn_cb));
+}
+
+
+TIMER_CALLBACK_MEMBER(tasc_sb30_device::leds_off_cb)
+{
+ for (int y=0; y<9; y++)
+ for (int x=0; x<9; x++)
+ m_out_leds[y][x] = 0;
+}
+
+void tasc_sb30_device::init_cb(int state)
+{
+ m_board->clear_board();
+ m_board->write_piece(0, 0, 1 + SB30_WHITE_ROOK1);
+ m_board->write_piece(7, 0, 1 + SB30_WHITE_ROOK2);
+ m_board->write_piece(1, 0, 1 + SB30_WHITE_KNIGHT1);
+ m_board->write_piece(6, 0, 1 + SB30_WHITE_KNIGHT2);
+ m_board->write_piece(2, 0, 1 + SB30_WHITE_BISHOP1);
+ m_board->write_piece(5, 0, 1 + SB30_WHITE_BISHOP2);
+ m_board->write_piece(3, 0, 1 + SB30_WHITE_QUEEN);
+ m_board->write_piece(4, 0, 1 + SB30_WHITE_KING);
+ m_board->write_piece(0, 7, 1 + SB30_BLACK_ROOK1);
+ m_board->write_piece(7, 7, 1 + SB30_BLACK_ROOK2);
+ m_board->write_piece(1, 7, 1 + SB30_BLACK_KNIGHT1);
+ m_board->write_piece(6, 7, 1 + SB30_BLACK_KNIGHT2);
+ m_board->write_piece(2, 7, 1 + SB30_BLACK_BISHOP1);
+ m_board->write_piece(5, 7, 1 + SB30_BLACK_BISHOP2);
+ m_board->write_piece(3, 7, 1 + SB30_BLACK_QUEEN);
+ m_board->write_piece(4, 7, 1 + SB30_BLACK_KING);
+
+ for (int x = 0; x < 8; x++)
+ {
+ m_board->write_piece(x, 1, 1 + SB30_WHITE_PAWN1 + x);
+ m_board->write_piece(x, 6, 1 + SB30_BLACK_PAWN1 + x);
+ }
+}
+
+bool tasc_sb30_device::piece_available(uint8_t id)
+{
+ for (int y=0; y<8; y++)
+ for (int x=0; x<8; x++)
+ {
+ if (m_board->read_piece(x, y) == id)
+ return false;
+ }
+
+ return true;
+}
+
+uint8_t tasc_sb30_device::spawn_cb(offs_t offset)
+{
+ int piece_id = -1;
+ if (offset == 1)
+ {
+ for (int p = 0; p < 8; p++)
+ if (piece_available(1 + SB30_WHITE_PAWN1 + p))
+ {
+ piece_id = SB30_WHITE_PAWN1 + p;
+ break;
+ }
+ }
+ else if (offset == 7)
+ {
+ for (int p = 0; p < 8; p++)
+ if (piece_available(1 + SB30_BLACK_PAWN1 + p))
+ {
+ piece_id = SB30_BLACK_PAWN1 + p;
+ break;
+ }
+ }
+ else if (offset == 2)
+ {
+ if (piece_available(1 + SB30_WHITE_KNIGHT1)) piece_id = SB30_WHITE_KNIGHT1;
+ else if (piece_available(1 + SB30_WHITE_KNIGHT2)) piece_id = SB30_WHITE_KNIGHT2;
+ }
+ else if (offset == 3)
+ {
+ if (piece_available(1 + SB30_WHITE_BISHOP1)) piece_id = SB30_WHITE_BISHOP1;
+ else if (piece_available(1 + SB30_WHITE_BISHOP2)) piece_id = SB30_WHITE_BISHOP2;
+ }
+ else if (offset == 4)
+ {
+ if (piece_available(1 + SB30_WHITE_ROOK1)) piece_id = SB30_WHITE_ROOK1;
+ else if (piece_available(1 + SB30_WHITE_ROOK2)) piece_id = SB30_WHITE_ROOK2;
+ }
+ else if (offset == 5)
+ piece_id = SB30_WHITE_QUEEN;
+
+ else if (offset == 6 && piece_available(1 + SB30_WHITE_KING))
+ piece_id = SB30_WHITE_KING;
+
+ else if (offset == 8)
+ {
+ if (piece_available(1 + SB30_BLACK_KNIGHT1)) piece_id = SB30_BLACK_KNIGHT1;
+ else if (piece_available(1 + SB30_BLACK_KNIGHT2)) piece_id = SB30_BLACK_KNIGHT2;
+ }
+ else if (offset == 9)
+ {
+ if (piece_available(1 + SB30_BLACK_BISHOP1)) piece_id = SB30_BLACK_BISHOP1;
+ else if (piece_available(1 + SB30_BLACK_BISHOP2)) piece_id = SB30_BLACK_BISHOP2;
+ }
+
+ else if (offset == 10)
+ {
+ if (piece_available(1 + SB30_BLACK_ROOK1)) piece_id = SB30_BLACK_ROOK1;
+ else if (piece_available(1 + SB30_BLACK_ROOK2)) piece_id = SB30_BLACK_ROOK2;
+ }
+ else if (offset == 11)
+ piece_id = SB30_BLACK_QUEEN;
+
+ else if (offset == 12 && piece_available(1 + SB30_BLACK_KING))
+ piece_id = SB30_BLACK_KING;
+
+ if (piece_id >= 0)
+ return piece_id + 1;
+ else
+ return 0; // not available
+}
+
+uint8_t tasc_sb30_device::read()
+{
+ int x = (m_position & 0x3f) / 8;
+ int y = (m_position & 0x3f) % 8;
+ int piece_id = m_board->read_sensor(7 - x, 7 - y);
+
+ // each piece is identified by a single bit in a 32-bit sequence, if multiple bits are active the MSB is used
+ uint32_t sb30_id = 0;
+ if (piece_id > 0)
+ sb30_id = 1UL << (piece_id - 1);
+
+ return BIT(sb30_id, m_shift & 0x1f);
+}
+
+
+void tasc_sb30_device::write(uint8_t data)
+{
+ if (BIT(data, 3) && !BIT(m_data, 3))
+ m_position = 0;
+
+ if (BIT(data, 7) && BIT(data, 6) && !BIT(m_data, 6))
+ {
+ out_led(m_position);
+ m_leds_off_timer->adjust(attotime::from_hz(5));
+ }
+
+ if (!BIT(data, 7) && BIT(m_data, 7))
+ {
+ m_position++;
+ if (m_position & 0x40)
+ {
+ m_shift++;
+ if (m_position & 1)
+ m_shift = 0;
+ }
+ }
+
+ m_data = data;
+}
+
+
+void tasc_sb30_device::out_led(int pos)
+{
+ pos &= 0x3f;
+ int x = pos / 8;
+ int y = pos % 8;
+ m_out_leds[y + 0][x + 0] = 1;
+ m_out_leds[y + 0][x + 1] = 1;
+ m_out_leds[y + 1][x + 0] = 1;
+ m_out_leds[y + 1][x + 1] = 1;
+}
diff --git a/src/mame/machine/smartboard.h b/src/mame/machine/smartboard.h
new file mode 100644
index 00000000000..e42981b7d4d
--- /dev/null
+++ b/src/mame/machine/smartboard.h
@@ -0,0 +1,60 @@
+// license:BSD-3-Clause
+// copyright-holders:Sandro Ronco
+/**********************************************************************
+
+ Tasc SmartBoard
+
+*********************************************************************/
+
+#ifndef MAME_MACHINE_SMARTBOARD_H
+#define MAME_MACHINE_SMARTBOARD_H
+
+#pragma once
+
+#include "machine/sensorboard.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> tasc_sb30_device
+
+class tasc_sb30_device : public device_t
+{
+public:
+ // construction/destruction
+ tasc_sb30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ uint8_t read();
+ void write(uint8_t data);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ TIMER_CALLBACK_MEMBER(leds_off_cb);
+ void out_led(int pos);
+ bool piece_available(uint8_t id);
+ void init_cb(int state);
+ uint8_t spawn_cb(offs_t offset);
+
+ required_device<sensorboard_device> m_board;
+ output_finder<9,9> m_out_leds;
+ emu_timer * m_leds_off_timer;
+ uint8_t m_data;
+ uint8_t m_position;
+ uint8_t m_shift;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(TASC_SB30, tasc_sb30_device)
+
+
+#endif // MAME_MACHINE_SMARTBOARD_H
/span>I_TCY, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, /* 0x60 */ I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, /* 0x80 */ F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, /* 0xC0 */ F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, }; static const UINT32 tms1100_default_decode[256] = { /* 0x00 */ I_MNEA, I_ALEM, I_YNEA, I_XMA, I_DYN, I_IYC, I_AMAAC, I_DMAN, I_TKA, F_COMX, F_TDO, F_COMC, F_RSTR, F_SETR, I_KNEZ, F_RETN, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, /* 0x20 */ I_TAY, I_TMA, I_TMY, I_TYA, I_TAMDYN, I_TAMIYC, I_TAMZA, I_TAM, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT, I_TBIT, I_TBIT, I_TBIT, I_TBIT, I_SAMAN, I_CPAIZ, I_IMAC, I_MNEZ, /* 0x40 */ I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, /* 0x60 */ I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_CLA, /* 0x80 */ F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, /* 0xC0 */ F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, }; static ADDRESS_MAP_START(tms0980_internal_rom, AS_PROGRAM, 16, tms1xxx_cpu_device) AM_RANGE( 0x0000, 0x0FFF ) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(tms0980_internal_ram, AS_DATA, 8, tms1xxx_cpu_device) AM_RANGE( 0x0000, 0x0FFF ) AM_RAM ADDRESS_MAP_END static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device) AM_RANGE( 0x000, 0x3ff ) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device) AM_RANGE( 0x000, 0x7ff ) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_6bit, AS_DATA, 8, tms1xxx_cpu_device) AM_RANGE( 0x00, 0x3f ) AM_RAM ADDRESS_MAP_END static ADDRESS_MAP_START(data_7bit, AS_DATA, 8, tms1xxx_cpu_device) AM_RANGE( 0x00, 0x7f ) AM_RAM ADDRESS_MAP_END void tms1xxx_cpu_device::device_start() { m_program = &space( AS_PROGRAM ); m_data = &space( AS_DATA ); m_read_k.resolve_safe(0xff); m_write_o.resolve_safe(); m_write_r.resolve_safe(); save_item( NAME(m_prev_pc) ); save_item( NAME(m_prev_pa) ); save_item( NAME(m_pc) ); save_item( NAME(m_pa) ); save_item( NAME(m_sr) ); save_item( NAME(m_pb) ); save_item( NAME(m_a) ); save_item( NAME(m_x) ); save_item( NAME(m_y) ); save_item( NAME(m_dam) ); save_item( NAME(m_ca) ); save_item( NAME(m_cb) ); save_item( NAME(m_cs) ); save_item( NAME(m_r) ); save_item( NAME(m_o) ); save_item( NAME(m_cki_bus) ); save_item( NAME(m_p) ); save_item( NAME(m_n) ); save_item( NAME(m_adder_result) ); save_item( NAME(m_carry_in) ); save_item( NAME(m_status) ); save_item( NAME(m_status_latch) ); save_item( NAME(m_special_status) ); save_item( NAME(m_call_latch) ); save_item( NAME(m_add_latch) ); save_item( NAME(m_branch_latch) ); save_item( NAME(m_subcycle) ); save_item( NAME(m_ram_address) ); save_item( NAME(m_ram_data) ); save_item( NAME(m_rom_address) ); save_item( NAME(m_opcode) ); save_item( NAME(m_decode) ); // Register state for debugger state_add( TMS0980_PC, "PC", m_pc ).callimport().callexport().formatstr("%02X"); state_add( TMS0980_SR, "SR", m_sr ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_PA, "PA", m_pa ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_PB, "PB", m_pb ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_A, "A", m_a ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_X, "X", m_x ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_Y, "Y", m_y ).callimport().callexport().formatstr("%01X"); state_add( TMS0980_STATUS, "STATUS", m_status ).callimport().callexport().formatstr("%01X"); state_add(STATE_GENPC, "curpc", m_pc).callimport().callexport().formatstr("%8s").noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).callimport().callexport().formatstr("%8s").noshow(); m_icountptr = &m_icount; } void tms1xxx_cpu_device::device_reset() { m_pa = 0x0F; m_pb = 0x0F; m_pc = 0; m_dam = 0; m_ca = 0; m_cb = 0; m_cs = 0; m_subcycle = 0; m_status = 1; m_status_latch = 0; m_call_latch = 0; m_add_latch = 0; m_branch_latch = 0; m_r = 0; m_o = 0; m_ram_address = 0; m_decode = F_ILL; m_opcode = 0; } /* The program counter is implemented using PRNG logic and gets incremented as follows: 00, 01, 03, 07, 0F, 1F, 3F, 3E, 3D, 3B, 37, 2F, 1E, 3C, 39, 33 27, 0E, 1D, 3A, 35, 2B, 16, 2C, 18, 30, 21, 02, 05, 0B, 17, 2E, 1C, 38, 31, 23, 06, 0D, 1B, 36, 2D, 1A, 34, 29, 12, 24, 08, 11, 22, 04, 09, 13, 26, 0C, 19, 32, 25, 0A, 15, 2A, 14, 28, 10, 20 There is also a strange address (AD) to location (LOC) mapping performed by the tms1000 family. From tms1000 family pdf: AD LOC 000 000000 003 000011 001 000001 004 000100 003 000011 00C 001100 007 000111 01C 011100 00F 001111 03C 111100 01F 011111 03F 111111 03F 111111 03E 111110 03E 111110 039 111001 03D 111101 036 110110 03B 111011 02E 101110 037 110111 01E 011110 02F 101111 03D 111101 01E 011110 038 111000 03C 111100 031 110001 039 111001 026 100110 033 110011 00E 001110 027 100111 01D 011101 00E 001110 03B 111011 01D 011101 037 110111 03A 111010 029 101001 035 110101 016 010110 02B 101011 02D 101101 016 010110 018 011000 02C 101100 032 110010 018 011000 020 100000 030 110000 001 000001 021 100001 005 000101 002 000010 00B 001011 005 000101 014 010100 00B 001011 02C 101100 017 010111 01F 011111 02E 101110 03A 111010 01C 011100 030 110000 038 111000 021 100001 031 110001 006 000110 023 100011 00D 001101 006 000110 01B 011011 00D 001101 034 110100 01B 011011 02F 101111 036 110110 019 011001 02D 101101 035 110101 01A 011010 028 101000 034 110100 011 010001 029 101001 025 100101 012 010010 008 001000 024 100100 012 010010 008 001000 023 100011 011 010001 007 000111 022 100010 00A 001010 004 000100 013 010011 009 001001 024 100100 013 010011 00F 001111 026 100110 01A 011010 00C 001100 033 110011 019 011001 027 100111 032 110010 009 001001 025 100101 015 010101 00A 001010 02B 101011 015 010101 017 010111 02A 101010 02A 101010 014 010100 010 010000 028 101000 022 100010 010 010000 000 000000 020 100000 002 000010 The following formula seems to be used to decode a program counter into a rom address: location{5:2} = pc{3:0} location{1:0} = ( pc{5:4} == 00 && pc{0} == 0 ) => 11 ( pc{5:4} == 00 && pc{0} == 1 ) => 00 ( pc{5:4} == 01 && pc{0} == 0 ) => 00 ( pc{5:4} == 01 && pc{0} == 1 ) => 11 ( pc{5:4} == 10 && pc{0} == 0 ) => 10 ( pc{5:4} == 10 && pc{0} == 1 ) => 01 ( pc{5:4} == 11 && pc{0} == 0 ) => 01 ( pc{5:4} == 11 && pc{0} == 1 ) => 10 */ static const UINT8 tms1000_next_pc[64] = { 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3B, 0x3D, 0x3E, }; /* emulator for the program counter increment on the tms0980/tmc0980 mcu; see patent 4064554 figure 19 (on page 13) for an explanation of feedback: nand324 = NAND of PC0 through pc4, i.e. output is true if ((pc&0x1f) != 0x1f) nand323 = NAND of pc5, pc6 and nand324 i.e. output is true, if ((pc&0x1f)==0x1f) || pc5 is 0 || pc 6 is 0 or321 = OR of pc5 and pc6, i.e. output is true if ((pc&0x60) != 0) nand322 = NAND of pc0 through pc5 plus /pc6, i.e. output is true if (pc != 0x3f) nand325 = nand pf nand323, or321 and nand322 This one is complex: / or321 means if pc&0x60 is zero, output MUST be true \ nand323 means if (pc&0x60=0x60) && (pc&0x1f != 0x1f), output MUST be true nand322 means if pc = 0x3f, output MUST be true hence, nand325 is if pc = 0x7f, false. if pc = 0x3f, true. if pc&0x60 is zero OR pc&0x60 is 0x60, true. otherwise, false. tms0980_nect_pc below implements an indentical function to this in a somewhat more elegant way. */ void tms1xxx_cpu_device::next_pc() { if ( m_byte_size > 8 ) { UINT8 xorval = ( m_pc & 0x3F ) == 0x3F ? 1 : 0; UINT8 new_bit = ( ( m_pc ^ ( m_pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval; m_pc = ( m_pc << 1 ) | new_bit; } else { m_pc = tms1000_next_pc[ m_pc & 0x3f ]; } } static const UINT8 tms1000_pc_decode[64] = { 0x03, 0x04, 0x0B, 0x0C, 0x13, 0x14, 0x1B, 0x1C, 0x23, 0x24, 0x2B, 0x2C, 0x33, 0x34, 0x3B, 0x3C, 0x00, 0x07, 0x08, 0x0F, 0x10, 0x17, 0x18, 0x1F, 0x20, 0x27, 0x28, 0x2F, 0x30, 0x37, 0x38, 0x3F, 0x02, 0x05, 0x0A, 0x0D, 0x12, 0x15, 0x1A, 0x1D, 0x22, 0x25, 0x2A, 0x2D, 0x32, 0x35, 0x3A, 0x3D, 0x01, 0x06, 0x09, 0x0E, 0x11, 0x16, 0x19, 0x1E, 0x21, 0x26, 0x29, 0x2E, 0x31, 0x36, 0x39, 0x3E }; void tms1xxx_cpu_device::set_cki_bus() { switch( m_opcode & 0x1F8 ) { case 0x008: m_cki_bus = m_read_k( 0, 0xff ); break; case 0x020: case 0x028: m_cki_bus = 0; break; case 0x030: case 0x038: m_cki_bus = tms0980_nbit_value[ m_opcode & 0x03 ]; break; case 0x000: case 0x040: case 0x048: case 0x050: case 0x058: case 0x060: case 0x068: case 0x070: case 0x078: case 0x080: case 0x088: case 0x090: case 0x098: case 0x0c0: case 0x0c8: case 0x0d0: case 0x0d8: case 0x0e0: case 0x0e8: case 0x0f0: case 0x0f8: m_cki_bus = tms0980_c4_value[ m_opcode & 0x0F ]; break; default: m_cki_bus = 0x0F; break; } } void tms1xxx_cpu_device::execute_run() { do { // debugger_instruction_hook( this, ( ( m_pa << m_pc_size ) | m_pc ) << 1 ); m_icount--; switch( m_subcycle ) { case 0: /* fetch: rom address 0 */ /* execute: read ram, alu input, execute br/call, k input valid */ set_cki_bus(); m_ram_data = m_data->read_byte( m_ram_address ); m_status = 1; m_p = 0; m_n = 0; m_carry_in = 0; break; case 1: /* fetch: rom address 1 */ m_rom_address = ( m_ca << ( m_pc_size + 4 ) ) | ( m_pa << m_pc_size ) | m_pc; /* execute: k input valid */ if ( m_decode & MICRO_MASK ) { /* Check N inputs */ if ( m_decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) { m_n = 0; if ( m_decode & M_15TN ) { m_n |= 0x0F; } if ( m_decode & M_ATN ) { m_n |= m_a; } if ( m_decode & M_CKN ) { m_n |= m_cki_bus; } if ( m_decode & M_MTN ) { m_n |= m_ram_data; } if ( m_decode & M_NATN ) { m_n |= ( ( ~m_a ) & 0x0F ); } } /* Check P inputs */ if ( m_decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) { m_p = 0; if ( m_decode & M_CKP ) { m_p |= m_cki_bus; } if ( m_decode & M_DMTP ) { m_p |= m_dam; } if ( m_decode & M_MTP ) { m_p |= m_ram_data; } if ( m_decode & M_NDMTP ) { m_p |= ( ( ~m_dam ) & 0x0F ); } if ( m_decode & M_YTP ) { m_p |= m_y; } } /* Carry In input */ if ( m_decode & M_CIN ) { m_carry_in = 1; } } break; case 2: /* fetch: nothing */ /* execute: write ram */ /* perform adder logic */ m_adder_result = m_p + m_n + m_carry_in; if ( m_decode & MICRO_MASK ) { if ( m_decode & M_NE ) { if ( m_n == m_p ) { m_status = 0; } } if ( m_decode & M_C8 ) { m_status = m_adder_result >> 4; } if ( m_decode & M_STO ) { //printf("write ram %02x data %01x\n", m_ram_address, m_a ); m_data->write_byte( m_ram_address, m_a ); } if ( m_decode & M_CKM ) { //printf("write ram %02x data %01x\n", m_ram_address, m_cki_bus ); m_data->write_byte( m_ram_address, m_cki_bus ); } } else { if ( m_decode & F_SBIT ) { //printf("write ram %02x data %01x\n", m_ram_address, m_ram_data | tms0980_bit_value[ m_opcode & 0x03 ] ); m_data->write_byte( m_ram_address, m_ram_data | tms0980_bit_value[ m_opcode & 0x03 ] ); } if ( m_decode & F_RBIT ) { //printf("write ram %02x data %01x\n", m_ram_address, m_ram_data & tms0980_nbit_value[ m_opcode & 0x03 ] ); m_data->write_byte( m_ram_address, m_ram_data & tms0980_nbit_value[ m_opcode & 0x03 ] ); } if ( m_decode & F_SETR ) { m_r = m_r | ( 1 << m_y ); m_write_r( 0, m_r & m_r_mask, 0xffff ); } if ( m_decode & F_RSTR ) { m_r = m_r & ( ~( 1 << m_y ) ); m_write_r( 0, m_r & m_r_mask, 0xffff ); } if ( m_decode & F_TDO ) { /* Calculate O-outputs based on status latch, A, and the output PLA configuration */ m_o = c_output_pla[ ( m_status_latch << 4 ) | m_a ]; if ( ( c_output_pla[ ( m_status_latch << 4 ) | m_a ] & 0xFF00 ) == 0xFF00 ) { logerror("unknown output pla mapping for status latch = %d and a = %X\n", m_status_latch, m_a); } //if ( ( c_output_pla[ ( m_status_latch << 4 ) | m_a ] & 0xFF00 ) == 0xFF00 ) //printf("****** o output m_status_latch = %X, m_a = %X\n", m_status_latch, m_a); //else //printf("o output m_status_latch = %X, m_a = %X\n", m_status_latch, m_a); m_write_o( 0, m_o & m_o_mask, 0xffff ); } if ( m_decode & F_CLO ) { m_o = 0; m_write_o( 0, m_o & m_o_mask, 0xffff ); } if ( m_decode & F_LDX ) { switch( m_x_bits ) { case 2: m_x = tms0980_c2_value[ m_opcode & 0x03 ]; break; case 3: m_x = tms0980_c3_value[ m_opcode & 0x07 ]; break; case 4: m_x = tms0980_c4_value[ m_opcode & 0x0f ]; break; } } if ( m_decode & F_COMX ) { switch ( m_x_bits ) { case 2: m_x = m_x ^ 0x03; break; case 3: m_x = m_x ^ 0x07; break; case 4: m_x = m_x ^ 0x0f; break; } } if ( m_decode & F_COMC ) { m_cb = m_cb ^ 0x01; } if ( m_decode & F_LDP ) { m_pb = tms0980_c4_value[ m_opcode & 0x0F ]; } if ( m_decode & F_REAC ) { m_special_status = 0; } if ( m_decode & F_SEAC ) { m_special_status = 1; } if ( m_decode == F_SAL ) { m_add_latch = 1; } if ( m_decode == F_SBL ) { m_branch_latch = 1; } } break; case 3: /* fetch: fetch, update pc, ram address */ /* execute: register store */ break; case 4: /* execute: register store */ if ( m_decode & MICRO_MASK ) { if ( m_decode & M_AUTA ) { m_a = m_adder_result & 0x0F; } if ( m_decode & M_AUTY ) { m_y = m_adder_result & 0x0F; } if ( m_decode & M_STSL ) { m_status_latch = m_status; } } /* fetch: fetch, update pc, ram address */ if ( m_byte_size > 8 ) { debugger_instruction_hook( this, m_rom_address << 1 ); m_opcode = m_program->read_word( m_rom_address << 1 ) & 0x1FF; } else { debugger_instruction_hook( this, m_rom_address ); m_opcode = m_program->read_byte( m_rom_address ); } next_pc(); if (LOG) logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", m_opcode, m_rom_address, m_pc ); /* ram address */ m_ram_address = ( m_x << 4 ) | m_y; break; case 5: /* fetch: instruction decode */ m_decode = m_decode_table[ m_opcode ]; /* execute: execute br/call */ if ( m_status ) { if ( m_decode == F_BR ) { m_ca = m_cb; if ( m_call_latch == 0 ) { m_pa = m_pb; } m_pc = m_opcode & ( ( 1 << m_pc_size ) - 1 ); } if ( m_decode == F_CALL ) { UINT8 t = m_pa; if ( m_call_latch == 0 ) { m_sr = m_pc; m_call_latch = 1; m_pa = m_pb; m_cs = m_ca; } m_ca = m_cb; m_pb = t; m_pc = m_opcode & ( ( 1 << m_pc_size ) - 1 ); } } if ( m_decode == F_RETN ) { if ( m_call_latch == 1 ) { m_pc = m_sr; m_call_latch = 0; m_ca = m_cs; } m_add_latch = 0; m_pa = m_pb; } else { m_branch_latch = 0; } break; } m_subcycle = ( m_subcycle + 1 ) % 6; } while( m_icount > 0 ); } void tms0980_cpu_device::state_string_export(const device_state_entry &entry, astring &string) { switch( entry.index() ) { case STATE_GENPC: string.printf( "%03X", ( ( m_pa << 7 ) | m_pc ) << 1 ); break; } } void tms1000_cpu_device::state_string_export(const device_state_entry &entry, astring &string) { switch( entry.index() ) { case STATE_GENPC: string.printf( "%03X", ( m_pa << 6 ) | tms1000_pc_decode[ m_pc ] ); break; } } void tms1100_cpu_device::state_string_export(const device_state_entry &entry, astring &string) { switch( entry.index() ) { case STATE_GENPC: string.printf( "%03X", ( m_ca << 10 ) | ( m_pa << 6 ) | m_pc ); break; } } tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1xxx_cpu_device( mconfig, TMS0980, "TMS0980", tag, owner, clock, tms0980_decode, 0x00ff, 0x07ff, 7, 9, 4 , 12, ADDRESS_MAP_NAME( tms0980_internal_rom ), 7, ADDRESS_MAP_NAME( tms0980_internal_ram ), "tms0980", __FILE__) { } offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { extern CPU_DISASSEMBLE( tms0980 ); return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options); } tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1xxx_cpu_device( mconfig, TMS1000, "TMS1000", tag, owner, clock, tms1000_default_decode, 0x00ff, 0x07ff, 6, 8, 2 , 11, ADDRESS_MAP_NAME( program_11bit_8 ), 7, ADDRESS_MAP_NAME( data_7bit ), "tms1000", __FILE__) { } tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char*name, const char *tag, device_t *owner, UINT32 clock, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source) : tms1xxx_cpu_device( mconfig, type, name, tag, owner, clock, tms1000_default_decode, o_mask, r_mask, 6, 8, 2 , 10, ADDRESS_MAP_NAME( program_10bit_8 ), 6, ADDRESS_MAP_NAME( data_6bit ), shortname, source ) { } offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { extern CPU_DISASSEMBLE( tms1000 ); return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options); } tms1070_cpu_device::tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1000_cpu_device( mconfig, TMS1070, "TMS1070", tag, owner, clock, 0x00ff, 0x07ff, "tms1070", __FILE__) { } tms1200_cpu_device::tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1000_cpu_device( mconfig, TMS1200, "TMS1200", tag, owner, clock, 0x00ff, 0x1fff, "tms1200", __FILE__) { } tms1270_cpu_device::tms1270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1000_cpu_device( mconfig, TMS1270, "TMS1270", tag, owner, clock, 0x03ff, 0x1fff, "tms1270", __FILE__) { } tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1xxx_cpu_device( mconfig, TMS1100, "TMS1100", tag, owner, clock, tms1100_default_decode, 0x00ff, 0x07ff, 6, 8, 3 , 11, ADDRESS_MAP_NAME( program_11bit_8 ), 7, ADDRESS_MAP_NAME( data_7bit ), "tms1100", __FILE__ ) { } tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char*name, const char *tag, device_t *owner, UINT32 clock, UINT16 o_mask, UINT16 r_mask, const char *shortname, const char *source) : tms1xxx_cpu_device( mconfig, type, name, tag, owner, clock, tms1100_default_decode, o_mask, r_mask, 6, 8, 3 , 11, ADDRESS_MAP_NAME( program_11bit_8 ), 7, ADDRESS_MAP_NAME( data_7bit ), shortname, source ) { } offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { extern CPU_DISASSEMBLE( tms1100 ); return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options); } tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms1100_cpu_device( mconfig, TMS1300, "TMS1300", tag, owner, clock, 0x00ff, 0xffff, "tms1300", __FILE__ ) { }