mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
bert: fix it (nw)
This commit is contained in:
parent
c05e716513
commit
379bba82b6
@ -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;
|
||||
constexpr u16 type = 0x00ca;
|
||||
u16 data = m_memory->read_word(offset << 1);
|
||||
u16 res;
|
||||
|
||||
u16 result = (m_shifter << (16 - shift)) | (data >> shift);
|
||||
m_shifter = data & mask_r;
|
||||
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;
|
||||
}
|
||||
|
||||
if (BIT(m_control, 8))
|
||||
result = ~result;
|
||||
m_step = (m_step + 1) & 3;
|
||||
|
||||
LOG("r 0x%06x 0x%04x 0x%04x 0x%04x (%s)\n", offset << 1, data, result, m_shifter, machine().describe_context());
|
||||
|
||||
return result;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user