summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2019-06-27 15:39:45 +0200
committer Olivier Galibert <galibert@pobox.com>2019-06-27 15:39:05 +0200
commit379bba82b68ed3599625a22b023adfff36268ba9 (patch)
treeed89e7509a1c203dc5f3cdcf876e543a84b046e9
parentc05e71651303cee9941af0e3f7e03b5943d4cbda (diff)
bert: fix it (nw)
-rw-r--r--src/mame/machine/bert.cpp72
-rw-r--r--src/mame/machine/bert.h6
2 files changed, 36 insertions, 42 deletions
diff --git a/src/mame/machine/bert.cpp b/src/mame/machine/bert.cpp
index f0b38049370..9aca9bfb267 100644
--- a/src/mame/machine/bert.cpp
+++ b/src/mame/machine/bert.cpp
@@ -5,21 +5,12 @@
* An emulation of the BERT ASIC found in the NCD 16 X terminal.
*
* Sources:
- * - none known
- *
- * TODO:
- * - shift amounts greater than 16
- * - other control bits
+ * - none known, but there's a full simulation in the firmware to test it
*/
#include "emu.h"
#include "bert.h"
-#define LOG_GENERAL (1U << 0)
-
-//#define VERBOSE (LOG_GENERAL)
-#include "logmacro.h"
-
DEFINE_DEVICE_TYPE(BERT, bert_device, "ncd_bert_asic", "NCD BERT ASIC")
bert_device::bert_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
@@ -32,7 +23,8 @@ bert_device::bert_device(const machine_config &mconfig, const char *tag, device_
void bert_device::device_start()
{
save_item(NAME(m_control));
- save_item(NAME(m_shifter));
+ save_item(NAME(m_history));
+ save_item(NAME(m_step));
m_memory = m_memory_space->cache<1, 0, ENDIANNESS_BIG>();
}
@@ -40,44 +32,46 @@ void bert_device::device_start()
void bert_device::device_reset()
{
m_control = 0;
- m_shifter = 0;
+ m_history = 0;
+ m_step = 0;
}
void bert_device::map(address_map &map)
{
map(0x000000, 0x7fffff).rw(FUNC(bert_device::read), FUNC(bert_device::write));
- map(0x000000, 0x000001).lw16("control", [this](u16 data) { LOG("control 0x%04x\n", data); m_control = data; });
}
u16 bert_device::read(offs_t offset)
{
- u16 const data = m_memory->read_word(offset << 1);
- unsigned const shift = m_control & 0x1f;
- u16 const mask_r = (1 << shift) - 1;
-
- u16 result = (m_shifter << (16 - shift)) | (data >> shift);
- m_shifter = data & mask_r;
-
- if (BIT(m_control, 8))
- result = ~result;
-
- LOG("r 0x%06x 0x%04x 0x%04x 0x%04x (%s)\n", offset << 1, data, result, m_shifter, machine().describe_context());
-
- return result;
+ constexpr u16 type = 0x00ca;
+ u16 data = m_memory->read_word(offset << 1);
+ u16 res;
+
+ if(type & (1 << (((m_control >> 8) & 0xc) | m_step))) {
+ // mask
+ res = m_control & 0x200 ? ~data : data;
+ } else {
+ // data
+ u32 tmp = m_control & 0x10 ? (data << 16) | m_history : (m_history << 16) | data;
+ res = tmp >> (m_control & 15);
+ if(m_control & 0x100)
+ res = ~res;
+ m_history = m_control & 0x1000 ? 0 : data;
+ }
+
+ m_step = (m_step + 1) & 3;
+
+ return res;
}
-void bert_device::write(offs_t offset, u16 data)
+void bert_device::write(offs_t offset, u16 data, u16 mem_mask)
{
- unsigned const shift = m_control & 0x1f;
- u16 const mask_r = (1 << shift) - 1;
-
- u16 result = (data << shift) | (m_shifter & mask_r);
- m_shifter = data >> (16 - shift);
-
- if (BIT(m_control, 8))
- result = ~result;
-
- LOG("w 0x%06x 0x%04x 0x%04x 0x%04x (%s)\n", offset << 1, data, result, m_shifter, machine().describe_context());
-
- m_memory->write_word(offset << 1, result);
+ m_step = 0;
+ m_memory->write_word(offset << 1, data, mem_mask);
+ if(!offset) {
+ COMBINE_DATA(&m_control);
+ m_step = 0;
+ if(m_control & 0x1000)
+ m_history = 0;
+ }
}
diff --git a/src/mame/machine/bert.h b/src/mame/machine/bert.h
index 0d7fd688799..58c67ec5e1e 100644
--- a/src/mame/machine/bert.h
+++ b/src/mame/machine/bert.h
@@ -14,7 +14,6 @@ public:
bert_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- static constexpr feature_type imperfect_features() { return feature::GRAPHICS; }
void map(address_map &map);
protected:
@@ -22,14 +21,15 @@ protected:
virtual void device_reset() override;
u16 read(offs_t offset);
- void write(offs_t offset, u16 data);
+ void write(offs_t offset, u16 data, u16 mem_mask);
private:
required_address_space m_memory_space;
memory_access_cache<1, 0, ENDIANNESS_BIG> *m_memory;
u16 m_control;
- u16 m_shifter;
+ u16 m_history;
+ u32 m_step;
};
DECLARE_DEVICE_TYPE(BERT, bert_device)