summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/psion_asic4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/psion_asic4.cpp')
-rw-r--r--src/devices/machine/psion_asic4.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/devices/machine/psion_asic4.cpp b/src/devices/machine/psion_asic4.cpp
new file mode 100644
index 00000000000..0ed603eaa74
--- /dev/null
+++ b/src/devices/machine/psion_asic4.cpp
@@ -0,0 +1,170 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/******************************************************************************
+
+ Psion ASIC4
+
+ ASIC4 is a serial protocol slave IC for addressing memory and general
+ memory-mapped peripherals. It is used in SSDs to convert SIBO serial protocol
+ signals into addresses within the memory range of the memory pack. ASIC4 was
+ designed to be a cut-down version of ASIC5 which was the original SIBO serial
+ protocol slave chip.
+
+ A27 A26 A25 A24 D7 D6 D5 D4 D3 D2 D1 D0
+ M Peripheral Id Memory Type No. devices Memory Size
+ 1 0 0 0 No peripheral 0 0 0 RAM 0 0 1 device 0 0 0 No memory
+ 0 0 1 Turbo RS232 (16550) 0 0 1 Type 1 Flash 0 1 2 devices 0 0 1 32K
+ 0 1 0 3Fax 0 1 0 Type 2 Flash 1 0 3 devices 0 1 0 64K
+ 1 1 1 Extended info in ROM 1 1 0 ROM 1 1 4 devices 0 1 1 128K
+ 1 0 0 256K
+ 1 0 1 512K
+ 1 1 0 1M
+
+******************************************************************************/
+
+#include "emu.h"
+#include "psion_asic4.h"
+
+#define VERBOSE 0
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+
+DEFINE_DEVICE_TYPE(PSION_ASIC4, psion_asic4_device, "psion_asic4", "Psion ASIC4")
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+psion_asic4_device::psion_asic4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, PSION_ASIC4, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , m_space_config("program", ENDIANNESS_LITTLE, 8, 28)
+{
+}
+
+
+device_memory_interface::space_config_vector psion_asic4_device::memory_space_config() const
+{
+ return space_config_vector{ std::make_pair(0, &m_space_config) };
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void psion_asic4_device::device_start()
+{
+ m_space = &space(0);
+
+ save_item(NAME(m_addr_latch));
+ save_item(NAME(m_addr_writes));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void psion_asic4_device::device_reset()
+{
+ m_addr_latch = 0x00;
+ m_addr_writes = 0;
+}
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+void psion_asic4_device::data_w(uint16_t data)
+{
+ switch (data & 0x300)
+ {
+ case NULL_FRAME:
+ device_reset();
+ break;
+
+ case CONTROL_FRAME:
+ m_sibo_control = data & 0xff;
+
+ // reset address register to LSB
+ m_addr_writes = 0;
+ break;
+
+ case DATA_FRAME:
+ data &= 0xff;
+ switch (m_sibo_control & 0x0f)
+ {
+ case 0x00: // Data register
+ LOG("%s data_w: Data register %02x\n", machine().describe_context(), data);
+ m_space->write_byte(m_addr_latch, data);
+ break;
+
+ case 0x01: // Device Size register
+ LOG("%s data_w: Device Size register %02x\n", machine().describe_context(), data);
+ break;
+
+ case 0x02: // Address Increment register
+ LOG("%s data_w: Address Increment register %02x\n", machine().describe_context(), data);
+ m_addr_latch = (m_addr_latch & 0xffffff0) | ((m_addr_latch + 1) & 0x0f);
+ break;
+
+ case 0x03: // Address register
+ LOG("%s data_w: Address register %02x\n", machine().describe_context(), data);
+ if (m_addr_writes == 0)
+ m_addr_latch = 0x00;
+ m_addr_latch |= data << (m_addr_writes << 3);
+ m_addr_writes = (m_addr_writes + 1) & 3;
+ break;
+
+ case 0x07: // Control register
+ LOG("%s data_w: Control register %02x\n", machine().describe_context(), data);
+ break;
+
+ default:
+ LOG("%s data_w: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data);
+ break;
+ }
+ break;
+ }
+}
+
+uint8_t psion_asic4_device::data_r()
+{
+ uint8_t data = 0x00;
+
+ switch (m_sibo_control & 0xc0)
+ {
+ case 0x40: // SerialSelect
+ switch (m_sibo_control & 0x0f)
+ {
+ case 0x06: // Asic4Id
+ data = m_info_byte & 0xff; // A4InfoByte
+ break;
+ }
+ break;
+
+ case 0xc0: // SerialRead
+ switch (m_sibo_control & 0x0f)
+ {
+ case 0x00: // Data register
+ data = m_space->read_byte(m_addr_latch);
+ LOG("%s data_r: Data register %02x\n", machine().describe_context(), data);
+ m_addr_latch++;
+ break;
+
+ case 0x01: // Input register
+ data = (m_info_byte >> 4) & 0xf0;
+ LOG("%s data_r: Input register %02x\n", machine().describe_context(), data);
+ break;
+
+ default:
+ LOG("%s data_r: unknown control %02x data %02x\n", machine().describe_context(), m_sibo_control, data);
+ break;
+ }
+ break;
+ }
+
+ return data;
+}