summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author joakim <Joakim Larsson Edstrom>2018-02-24 02:32:36 +0100
committer joakim <Joakim Larsson Edstrom>2018-02-24 02:32:36 +0100
commit35a7f3e628a860dd75b2b57a95c3190443fd25a2 (patch)
treefd0d06694d60b7e3ea10e65618dc4f92057fdd95
parent534dea91eee1a5b67d8c480d411a10944830f619 (diff)
WIP: Diablo printer CPU
-rw-r--r--scripts/src/cpu.lua17
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/cpu/diablo/diablo1300.cpp368
-rw-r--r--src/devices/cpu/diablo/diablo1300.h94
-rw-r--r--src/devices/cpu/diablo/diablo1300dasm.cpp82
-rw-r--r--src/devices/cpu/diablo/diablo1300dasm.h22
-rw-r--r--src/emu/xtal.cpp1
-rw-r--r--src/mame/drivers/diablo1300.cpp193
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/mame/mess.flt1
10 files changed, 783 insertions, 0 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index edb5df35a84..2da012dc594 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -1110,6 +1110,23 @@ if (CPUS["SSEM"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ssem/ssemdasm.h")
end
+------------------------------------------
+-- Diablo Systems printer CPU
+--@src/devices/cpu/diablo/diablo1300.h,CPUS["DIABLO"] = true
+--------------------------------------------------
+
+if (CPUS["DIABLO"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/cpu/diablo/diablo1300.cpp",
+ MAME_DIR .. "src/devices/cpu/diablo/diablo1300.h",
+ }
+end
+
+if (CPUS["DIABLO"]~=null or _OPTIONS["with-tools"]) then
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/diablo/diablo1300dasm.cpp")
+ table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ssem/diablo1300dasm.h")
+end
+
--------------------------------------------------
-- Fujitsu MB88xx
--@src/devices/cpu/mb88xx/mb88xx.h,CPUS["MB88XX"] = true
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index c38eb46c82b..07e76834fce 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -100,6 +100,7 @@ CPUS["TMS7000"] = true
CPUS["SM8500"] = true
CPUS["MINX"] = true
CPUS["SSEM"] = true
+CPUS["DIABLO"] = true
CPUS["AVR8"] = true
CPUS["TMS1000"] = true
CPUS["MCS40"] = true
@@ -3519,6 +3520,7 @@ files {
MAME_DIR .. "src/mame/drivers/d6800.cpp",
MAME_DIR .. "src/mame/drivers/d6809.cpp",
MAME_DIR .. "src/mame/drivers/daruma.cpp",
+ MAME_DIR .. "src/mame/drivers/diablo1300.cpp",
MAME_DIR .. "src/mame/drivers/didact.cpp",
MAME_DIR .. "src/mame/drivers/digel804.cpp",
MAME_DIR .. "src/mame/drivers/digijet.cpp",
diff --git a/src/devices/cpu/diablo/diablo1300.cpp b/src/devices/cpu/diablo/diablo1300.cpp
new file mode 100644
index 00000000000..6cfe0778622
--- /dev/null
+++ b/src/devices/cpu/diablo/diablo1300.cpp
@@ -0,0 +1,368 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+// thanks-to: Jeff Laughton
+/*
+ Diablo 1300 series Printer TTL CPU
+ The work is based on the RE done by Jeff Laughton http://laughtonelectronics.com/Arcana/Diablo%20CPU/DiabloCPU.html
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "diablo1300.h"
+#include "diablo1300dasm.h"
+
+//**************************************************************************
+// CONFIGURABLE LOGGING
+//**************************************************************************
+#define LOG_OP (1U << 1)
+
+#define VERBOSE (LOG_GENERAL | LOG_OP)
+//#define LOG_OUTPUT_FUNC printf
+
+#include "logmacro.h"
+
+#define LOGOP(...) LOGMASKED(LOG_OP, __VA_ARGS__)
+
+/*****************************************************************************/
+
+inline uint16_t diablo1300_cpu_device::opcode_read(uint16_t address)
+{
+ return m_direct->read_word(address);
+}
+
+inline uint16_t diablo1300_cpu_device::program_read16(uint16_t address)
+{
+ return m_program->read_word(address);
+}
+
+inline void diablo1300_cpu_device::program_write16(uint16_t address, uint16_t data)
+{
+ m_program->write_word(address, data);
+ return;
+}
+
+inline uint8_t diablo1300_cpu_device::data_read8(uint16_t address)
+{
+ return m_data->read_byte(address);
+}
+
+inline void diablo1300_cpu_device::data_write8(uint16_t address, uint8_t data)
+{
+ m_data->write_byte(address, data);
+ return;
+}
+
+inline uint8_t diablo1300_cpu_device::read_reg(uint16_t reg)
+{
+ return data_read8(reg);
+}
+
+inline void diablo1300_cpu_device::write_reg(uint16_t reg, uint8_t data)
+{
+ data_write8(reg, data);
+}
+
+/*****************************************************************************/
+
+DEFINE_DEVICE_TYPE(DIABLO1300, diablo1300_cpu_device, "diablo1300_cpu", "DIABLO 1300 CPU")
+
+//-------------------------------------------------
+// diablo1300_cpu_device - constructor
+//-------------------------------------------------
+
+diablo1300_cpu_device::diablo1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : cpu_device(mconfig, DIABLO1300, tag, owner, clock)
+ , m_program_config("program", ENDIANNESS_LITTLE, 16, 9, -1)
+ , m_data_config("data", ENDIANNESS_LITTLE, 8, 5)
+ , m_pc(0)
+ , m_a(0)
+ , m_b(0)
+ , m_carry(0)
+ , m_power_on(ASSERT_LINE)
+ , m_program(nullptr)
+ , m_data(nullptr)
+ , m_direct(nullptr)
+
+{
+ // Allocate & setup
+}
+
+
+void diablo1300_cpu_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
+ m_direct = m_program->direct<-1>();
+
+ // register our state for the debugger
+ state_add(STATE_GENPC, "GENPC", m_pc).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
+
+ state_add(DIABLO_PC, "PC", m_pc).mask(0x1ff);
+ state_add(DIABLO_A, "A", m_a).mask(0xff);
+ state_add(DIABLO_B, "B", m_b).mask(0xff);
+
+ /* setup regtable */
+ save_item(NAME(m_pc));
+ save_item(NAME(m_a));
+ save_item(NAME(m_b));
+ save_item(NAME(m_power_on));
+
+ // set our instruction counter
+ m_icountptr = &m_icount;
+}
+
+void diablo1300_cpu_device::device_stop()
+{
+}
+
+void diablo1300_cpu_device::device_reset()
+{
+ m_pc = 0;
+ m_a = 0;
+ m_b = 0;
+ m_carry = 0;
+
+ m_power_on = ASSERT_LINE; // should be CLEAR_LINE when card can detect power up
+}
+
+
+//-------------------------------------------------
+// memory_space_config - return the configuration
+// of the specified address space, or nullptr if
+// the space doesn't exist
+//-------------------------------------------------
+
+device_memory_interface::space_config_vector diablo1300_cpu_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config)
+ };
+}
+
+//-------------------------------------------------
+// disaassemble - call the disadiablobly
+// helper function
+//-------------------------------------------------
+
+util::disasm_interface *diablo1300_cpu_device::create_disassembler()
+{
+ return new diablo1300_disassembler;
+}
+
+
+//**************************************************************************
+// CORE EXECUTION LOOP
+//**************************************************************************
+
+//-------------------------------------------------
+// execute_min_cycles - return minimum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+uint32_t diablo1300_cpu_device::execute_min_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_max_cycles - return maximum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+uint32_t diablo1300_cpu_device::execute_max_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_run - execute a timeslice's worth of
+// opcodes
+//-------------------------------------------------
+void diablo1300_cpu_device::execute_run()
+{
+ uint32_t op;
+
+ m_pc &= 0x1f;
+
+ while (m_icount > 0)
+ {
+ debugger_instruction_hook(this, m_pc);
+
+ if( m_power_on == ASSERT_LINE )
+ {
+ op = opcode_read(m_pc);
+ m_pc++;
+ switch (op & 0x0007)
+ {
+ case 0:
+ /* OUTPUT Dport, Sreg: Output register SSSS via reg A to port DDD, reg B and carry are cleared
+ 111A SSSS 0DDD RIII
+ A = 0: register is ORed into reg A, = 1: register is copied into reg A
+ SSSS = Source register
+ DDD = Destination port address
+ R = RAM bank select
+ III = 000 (opcode)
+ */
+ LOGOP("OUTPUT dv%d, r%02X\n",
+ (op & 0x0070) >> 4,
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ m_a = read_reg(((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ m_b = 0;
+ m_carry = 0;
+ write_port((op & 0x0070) >> 4, m_a);
+ break;
+ case 1:
+ /* JNC Addr: Set PC to address H AAAA AAAA, reg B and carry are cleared
+ AAAA AAAA 0000 HIII
+ AAAA AAAA = 8 low bits in Destination Address
+ H = The 9th hi address bit
+ III = 001 (opcode)
+ */
+ LOGOP("JNC %03X\n", ((op & 0xff00) >> 8) + ((op & 0x0008) ? 0x100 : 0));
+ m_a = (op & 0xff00) >> 8;
+ m_b = 0;
+ m_carry = 0;
+ m_pc = ((op & 0x0008) + m_a);
+ break;
+ case 2:
+ /* RST Dport : Reset Port
+ 1111 0AAA BBBB RIII
+ AAA = Device address
+ BBBB = I8-I5 signals
+ R = RAM bank select
+ III = 010 (opcode)
+ */
+ LOGOP("RST dv%d\n", (op & 0x0700) >> 8);
+ m_b = read_ibus();
+ m_a = read_port((op & 0x0700) >> 8);
+ m_carry = (m_carry + m_a + m_b) > 0xff ? 1 : 0;
+ break;
+ case 3:
+ /* LDBBIT Sreg, #value: Load AAAA AAAA #value into reg A, register BBBB reg B and set carry if #value != 0
+ AAAA AAAA BBBB RIII
+ AAAA AAAA = bits to load immediate into A
+ BBBB = register to load into B
+ R = RAM bank select
+ III = 011 (opcode)
+ */
+ LOGOP("LDBBIT r%02X, %02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ m_a = (op & 0xff00) >> 8;
+ m_b = read_reg(((op & 0x00f0) >> 4));
+ m_carry = (m_a & m_b) != 0 ? 1 : 0;
+ break;
+ case 4:
+ switch(op & 0xc000)
+ {
+ case 0x4000:
+ /* XLAT Dreg: Load table data into A and reg, 0 into B
+ II10 0000 AAAA RIII
+ AAAA = Register
+ R = RAM bank select
+ II III = 01xx xxxx xxxx x100 (opcode)
+ */
+ LOGOP("XLAT r%02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0));
+ m_a = read_table(m_b + m_carry);
+ m_b = 0;
+ m_carry = 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+
+ case 0xc000:
+ /* MOVCPL Dreg, Sreg: register to register within RAM bank, acc B and carry is cleared
+ II11 SSSS DDDD RIII
+ SSSS = Source Register
+ DDDD = Destination register
+ R = RAM bank select
+ II III = 11xx xxxx xxxx x100 (opcode)
+ */
+ LOGOP("MOVCPL r%02X, r%02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ m_a = read_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x0f00) >> 8));
+ m_b = 0;
+ m_carry = 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+
+ case 0x8000:
+ /* INPUT Dreg, Sport: port to register, acc B and carry is cleared
+ II10 SSSS DDDD RIII
+ SSSS = Source Port
+ DDDD = Destination register
+ R = RAM bank select
+ II III = 01xx xxxx xxxx x100 (opcode)
+ */
+ LOGOP("INPUT r%02X, dv%X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8));
+ m_a = read_port((op & 0x0f00) >> 8);
+ m_b = 0;
+ m_carry = 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 5:
+ /* LOAD# Dreg,#val: Load value AAAA AAAA into register DDDD, acc B and carry is cleared
+ AAAA AAAA DDDD RIII
+ AAAA AAAA = bits to load into A
+ DDDD = register put A into
+ R = RAM bank select
+ III = 101 (opcode)
+ */
+ LOGOP("LOAD# r%02X, %02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ m_a = (op & 0xff00) >> 8;
+ m_b = 0;
+ m_carry = 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+ case 6:
+ /* ADCCPL S/Dreg, Sreg
+ 1111 AAAA BBBB RIII
+ AAAA = Load register AAAA into reg A
+ BBBB = Load register into reg B
+ R = RAM bank select
+ III = 110 (opcode)
+ */
+ LOGOP("ADCCPL r%02X, r%02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ m_a = read_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x0f00) >> 8));
+ m_b = read_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4));
+ m_carry = (m_a + m_b + m_carry) > 255 ? 1 : 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+ case 7:
+ /* ADC# S/Dreg, #val
+ AAAA AAAA BBBB RIII
+ AAAA AAAA = Load bits AAAA AAAA into A
+ BBBB = Load register BBBB into B
+ R = RAM bank select
+ III = 100 (opcode)
+ */
+ LOGOP("ADC# r%02X, %02X\n",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ m_a = (op & 0xff00) >> 8;
+ m_b = read_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4));
+ m_carry = (m_a + m_b + m_carry) > 255 ? 1 : 0;
+ write_reg(((op & 0x0008) != 0 ? 0x10 : 0) + ((op & 0x00f0) >> 4), m_a);
+ break;
+ default:
+ break;
+ }
+ }
+ --m_icount;
+ }
+}
diff --git a/src/devices/cpu/diablo/diablo1300.h b/src/devices/cpu/diablo/diablo1300.h
new file mode 100644
index 00000000000..fda5b8541c2
--- /dev/null
+++ b/src/devices/cpu/diablo/diablo1300.h
@@ -0,0 +1,94 @@
+// license:BSD-3-Clause copyright-holders:Joakim Larsson Edstrom
+/*
+ Diablo Printer TTL CPU
+*/
+
+#ifndef MAME_CPU_DIABLO_DIABLO1300_H
+#define MAME_CPU_DIABLO_DIABLO1300_H
+
+#pragma once
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> diablo1300_cpu_device
+
+// Used by core CPU interface
+class diablo1300_cpu_device : public cpu_device
+{
+public:
+ // construction/destruction
+ diablo1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_stop() override;
+
+ // device_execute_interface overrides
+ virtual uint32_t execute_min_cycles() const override;
+ virtual uint32_t execute_max_cycles() const override;
+ //virtual uint32_t execute_input_lines() const override;
+ virtual void execute_run() override;
+ //virtual void execute_set_input(int inputnum, int state) override;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
+ // device_disasm_interface overrides
+ virtual util::disasm_interface *create_disassembler() override;
+
+ // device_state_interface overrides
+ //virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+
+ // address spaces
+ const address_space_config m_program_config;
+ const address_space_config m_data_config;
+
+ // memory access
+ inline uint16_t opcode_read(uint16_t addr);
+ inline uint16_t program_read16(uint16_t addr);
+ inline void program_write16(uint16_t addr, uint16_t data);
+ inline uint8_t data_read8(uint16_t addr);
+ inline void data_write8(uint16_t addr, uint8_t data);
+
+ inline uint8_t read_reg(uint16_t reg);
+ inline uint16_t read_port(uint16_t port){ return 0;}
+ inline uint16_t read_table(uint16_t offset){ return 0;}
+ inline void write_reg(uint16_t reg, uint8_t data);
+ inline void write_port(uint16_t port, uint16_t data){}
+ inline uint16_t read_ibus(){ return 0; }
+
+ // CPU registers
+ uint16_t m_pc;
+ uint8_t m_a;
+ uint8_t m_b;
+ uint8_t m_carry;
+ uint8_t m_power_on;
+
+ // other internal states
+ int m_icount;
+
+ // address spaces
+ address_space *m_program;
+ address_space *m_data;
+ direct_read_data<-1> *m_direct;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(DIABLO1300, diablo1300_cpu_device)
+
+/***************************************************************************
+ REGISTER ENUMERATION
+***************************************************************************/
+
+enum
+{
+ DIABLO_PC = 1,
+ DIABLO_A,
+ DIABLO_B
+};
+
+#endif // MAME_CPU_DIABLO_DIABLO1300_H
diff --git a/src/devices/cpu/diablo/diablo1300dasm.cpp b/src/devices/cpu/diablo/diablo1300dasm.cpp
new file mode 100644
index 00000000000..3bc0a921dd2
--- /dev/null
+++ b/src/devices/cpu/diablo/diablo1300dasm.cpp
@@ -0,0 +1,82 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+// thanks-to: Jeff Laughton
+/*
+ Diablo 1300 series Printer TTL CPU disassembler
+ The work is based on the RE done by Jeff Laughton http://laughtonelectronics.com/Arcana/Diablo%20CPU/DiabloCPU.html
+*/
+
+#include "emu.h"
+#include "diablo1300dasm.h"
+
+u32 diablo1300_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+offs_t diablo1300_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ uint16_t op = opcodes.r16(pc);
+
+ switch (op & 0x0007)
+ {
+ case 0: // OUTPUT Dport, Sreg
+ util::stream_format(stream, "OUTPUT dv%d, r%02X",
+ (op & 0x0070) >> 4,
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ break;
+ case 1: // JNC Addr
+ util::stream_format(stream, "JNC %03X", ((op & 0xff00) >> 8) + ((op & 0x0008) ? 0x100 : 0));
+ break;
+ case 2: // RST #Dport
+ util::stream_format(stream, "RST dv%d", (op & 0x0700) >> 8);
+ break;
+ case 3: // LDBBIT Sreg, #val
+ util::stream_format(stream, "LDBBIT r%02X, %02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ break;
+ case 4: //
+ switch (op & 0xc000)
+ {
+ case 0x4000: // XLAT Dreg
+ util::stream_format(stream, "XLAT r%02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0));
+ break;
+ case 0xc000: // MOVCPL Dreg, Sreg
+ util::stream_format(stream, "MOVCPL r%02X, r%02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ break;
+ case 0x8000: // INPUT Dreg, Sport
+ util::stream_format(stream, "INPUT r%02X, dv%X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8));
+ break;
+ default:
+ util::stream_format(stream, "???");
+ break;
+ }
+ break;
+ case 5: // LOAD# Dreg,#val
+ util::stream_format(stream, "LOAD# r%02X, %02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ break;
+ case 6: // ADCCPL S/Dreg, Sreg
+ util::stream_format(stream, "ADCCPL r%02X, r%02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ ((op & 0x0f00) >> 8) + ((op & 0x0008) ? 0x10 : 0));
+ break;
+ case 7: // ADC# S/Dreg, val
+ util::stream_format(stream, "ADC# r%02X, %02X",
+ ((op & 0x00f0) >> 4) + ((op & 0x0008) ? 0x10 : 0),
+ (op & 0xff00) >> 8);
+ break;
+ default:
+ util::stream_format(stream, "???");
+ break;
+ }
+
+ return 1 | SUPPORTED;
+}
diff --git a/src/devices/cpu/diablo/diablo1300dasm.h b/src/devices/cpu/diablo/diablo1300dasm.h
new file mode 100644
index 00000000000..496ea9b1775
--- /dev/null
+++ b/src/devices/cpu/diablo/diablo1300dasm.h
@@ -0,0 +1,22 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/*
+ Diablo Printer TTL CPU disassembler
+*/
+
+#ifndef MAME_CPU_DIABLO_DIABLO1300DASM_H
+#define MAME_CPU_DIABLO_DIABLO1300DASM_H
+
+#pragma once
+
+class diablo1300_disassembler : public util::disasm_interface
+{
+public:
+ diablo1300_disassembler() = default;
+ virtual ~diablo1300_disassembler() = default;
+
+ virtual u32 opcode_alignment() const override;
+ virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
+};
+
+#endif
diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp
index b2b419aba5e..484ffbaed97 100644
--- a/src/emu/xtal.cpp
+++ b/src/emu/xtal.cpp
@@ -66,6 +66,7 @@ const double XTAL::known_xtals[] = {
1'000'000, /* 1_MHz_XTAL Used to drive OKI M6295 chips */
1'056'000, /* 1.056_MHz_XTAL Resonator - OKI M6295 on Trio The Punch h/w */
1'294'400, /* 1.2944_MHz_XTAL BBN BitGraph PSG */
+ 1'689'600, /* 1.6896_MHz_XTAL Diablo 1355WP Printer */
1'750'000, /* 1.75_MHz_XTAL RCA CDP1861 */
1'797'100, /* 1.7971_MHz_XTAL SWTPC 6800 (with MIKBUG) */
1'843'200, /* 1.8432_MHz_XTAL Bondwell 12/14 */
diff --git a/src/mame/drivers/diablo1300.cpp b/src/mame/drivers/diablo1300.cpp
new file mode 100644
index 00000000000..3b3b150c21c
--- /dev/null
+++ b/src/mame/drivers/diablo1300.cpp
@@ -0,0 +1,193 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/*
+
+ Diablo Printer Series 1300 HyType II driver
+
+ - Microprocessor based control logic for increased capacity and flexibility, plus provision for implementation of additional features.
+ - Advanced servo design for improved efficiency and performance.
+ - Rigid one piece cast aluminum frame to better maintain print quality, and reduce maintenance requirements.
+ - Rugged highly stable carriage assembly for enhanced print position accuracy and reduced maintenance.
+ - Plug-in interchangeable printed pircuit boards (PCB's), readily accessible for ease and simplicity of service, and implementation
+ of options and interfaces.
+ - Operator control of print hammer energy (Impression Control Switch) to shift the printer's internal hammer energy scale up
+ for multiple carbon forms or down for smaller lighter print font styles.
+ - 1/120 inch (.212 mm) horizontal spacing on command.
+ - 88/82 or 96 character metal wheel
+ - Optional interface access to directly address print hammer energy levels character by character.
+ - Optional interface access to command ribbon advance.
+ - Optional Paper Out Switch installation for either normal top or an optional bottom paper feed.
+ - Optional Cover Open Switch installation.
+ - Optional End Of Ribbon sensor installation for use with mu1tistrike carbon ribbon cartridges which are not the recirculating type.
+ - Carriage Return takes max 300 mS
+ - Tabulation can be set as right or left
+ - Column spacing 60 pt/inch by operator or 120 pt/inch by controller
+ - Print Line: 13.1 inch (332.74mm)
+ - Paper Feed: 4 inch/sec
+ - Dimensions: 591x365x400mm
+ - Weight: 12Kg
+
+Model performance
+-----------------
+ 1345A 1355HS 1355WP
+Print Speed char/sec 45 55 40
+Character Set 96 96 88/92/96
+
+Configurations
+--------------
+There are many options that comes with the Diablo 1300 series and while many are mechanical the electronics are built up with cards
+interconnected by a backplane. The backplane has well defined slots for each type of cards and there are also many external cables
+between the cards, sensors and motors of the printer. The backplane consists of up to 8 female connectors for 56 signals card edge
+connectors numbered A-H ordered in two rows, D,C,B,A on top with the fans to the left and H,G,F,E bellow. The signals are routed as
+needed and the slots are NOT generic, a specific card goes in at a specific slot but can be interchanged to accomodate improved
+performance or replaced for repair. Slots E and F are used for feature expansions such as serial, network cards etc.
+
+The slots are populated as follows:
+
+A: Logic #1 Command buffering and host signalling over a 50 pin ribbon cable. Sends commands to Logic #2 as needed
+B: Logic #2 TTL CPU that interpretes commands from Logic #1 and controls all motors in the system
+C: Servo
+D: Carriage Power Amp
+E: Optional 8080/Z80interface board, connects to Logic #1 board acting as host over the bus or the 50 pin ribbon cable
+F: Optional slot with all signals of slot F
+G: Transducer
+H: Print Wheel Power Amp
+
+In case the serial/IEEE488/network interface card is missing in the printer the host computer is supposed to drive which
+connects to the printer over the 50 pin ribbon cable instead of the printer hosted interface card.
+
+Logic #1 Card - printer command management
+------------------------------------------
+The board is marked 40505 and has an option field at the top and a J7 connector for the 50 pin ribbon cable. It produces the
+system clock of 5 MHz that is used by the TTL CPU at Logic #2 Card,
+
+ Identified IC:s
+ ---------------
+ 1 74LS221 Dual Monostable multivibrator
+ 7 74LS74 7907-7908 Dual D-type pos edg trg flip-flops w clr and preset
+ 3 74LS367 7849 Non inverted 3 state outputs, 2 and 4 line enabled inputs
+ 1 7451 7849 Dual AND+OR invert gates
+ 1 7486 7849 Quad XOR gates
+ 3 74LS170 7906 4 by 4 register file
+ 4 8837 7736
+ 2 7408 7906 Quad AND gales
+ 2 74LS42 7906 BCD to decimal decoder
+ 1 7426 7906 Quad NAND gates
+ 1 74LS174 7836 Hex D-type flip flops
+ 1 7432 7901 QUAD OR gates
+ 2 74LSI07 7906 Dual J-K M/S flip flops w clear
+ 1 7404 7901 Hex Inverters
+ 5 75452 7840-7901
+ 2 7400 7849 Quad NAND gates
+
+Logic #2 Card - printer command execution (TTL CPU)
+---------------------------------------------------
+The board is marked 40510 and has no connectors except the 56 signal bus edge connector
+
+ Identified IC:s
+ ---------------
+ 4 7400 7848-7902 Quad NAND gates
+ 3 74LS04 7850 Hex Inverters
+ 1 7408 7901 Quad AND gales
+ 1 7410 7840 Tripple 3-input NAND gates
+ 2 7453 7903 Expandable 4 wide AND+OR invert gates
+ 1 74LS74 7908 Dual D-type pos edg trg flip-flops w clr and preset
+ 2 74LS83 7901 4 bit binary full addres with fast carry
+ 4 74S289 4x16 bit RAM
+ 1 74107 Dual J-K M/S flip flops w clear
+ 1 74LS155 7731 1/2/3 to 4/8 lines decoder nwih totem pole ouputs
+ 2 74161 7904 synchronous binary 4 bit counter
+ 4 74LS259 7906 8 bit addressable latches
+ 4 74298 7849 Quad 2 input mux with storage
+ 1 74367 7840 Non inverted 3 state outputs, 2 and 4 line enabled inputs
+ 1 74LS174 Hex D-type flip flops
+
+RS232 Serial Interface Card
+----------------------------
+The serial interface card is z80 based and marked DIABLO-1300-V24
+
+ Identified ICs:
+ ---------------
+ 1 Z80-CPU 7904 Zilog CPU
+ 1 TMS2716 7906 2KB EPROM
+ 1 AM9551 7850 8251 USART
+ 2 Z80-PIO 7852 Zilog Paralell IO interface
+10 74367 7845 Non inverted 3 state outputs, 2 and 4 line enabled inputs
+ 2 UPB7400 7845 Quad NAND gates
+ 3 7432N 7832 QUAD OR gates
+ 1 1489 7841 Quad line receivers
+ 1 1488 7823 Quad line tranceivers
+ 1 74163 7827 Synchrounous 4 bit counters
+ 2 7493 7822 4 bit binary counters
+ 2 7404 7849 Hex inverters
+ 1 7410 7849 Tripple 3-input NAND gates
+ 2 2114 1024 x 4 bit SRAM
+ 1 9602 7423 Dual retriggable resetable one shots
+
+
+ Address decoding
+ ----------------
+ Z80 A0 30 -> 74367 -> Z80 PIO* Port A/B 6
+ Z80 A1 31 -> 74367 -> Z80 PIO* Control/Data 5
+ (Z80 A5 35 -> 74367) OR (Z80 IORQ 20) -> Z80 PIO1 CE* 4
+ (Z80 A4 34 -> 74367) OR (Z80 IORQ 20) -> Z80 PIO2 CE* 4
+*/
+
+#include "emu.h"
+#include "cpu/diablo/diablo1300.h"
+
+class diablo1300_state : public driver_device
+{
+public:
+ diablo1300_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ { }
+
+private:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ required_device<cpu_device> m_maincpu;
+public:
+ void diablo1300(machine_config &config);
+ void diablo1300_map(address_map &map);
+ void diablo1300_data_map(address_map &map);
+};
+
+ADDRESS_MAP_START( diablo1300_state::diablo1300_map) //, AS_PROGRAM, 16, diablo1300_state )
+ AM_RANGE(0x0000, 0x01ff) AM_ROM
+ADDRESS_MAP_END
+
+ADDRESS_MAP_START( diablo1300_state::diablo1300_data_map ) // , AS_DATA, 8, diablo1300_state )
+ AM_RANGE(0x00, 0x1f) AM_RAM
+ADDRESS_MAP_END
+
+static INPUT_PORTS_START( diablo1300 )
+INPUT_PORTS_END
+
+void diablo1300_state::machine_start()
+{
+}
+
+void diablo1300_state::machine_reset()
+{
+}
+
+MACHINE_CONFIG_START( diablo1300_state::diablo1300 )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", DIABLO1300, XTAL(1'689'600))
+ MCFG_CPU_PROGRAM_MAP(diablo1300_map)
+ MCFG_CPU_DATA_MAP(diablo1300_data_map)
+MACHINE_CONFIG_END
+
+ROM_START( diablo )
+ ROM_REGION( 0x10000, "maincpu", ROMREGION_16BIT )
+ ROM_DEFAULT_BIOS("diablo1300")
+
+ ROM_SYSTEM_BIOS(0, "diablo1300", "Diablo Printer Series 1300 14510-xx CPU microcode")
+ ROMX_LOAD ("diablo1300.odd", 0x0001, 0x200, CRC (5e295350) SHA1 (6ea9a22b23b8bab93ae57671541d65dba698c722), ROM_SKIP(1) | ROM_BIOS(1))
+ ROMX_LOAD ("diablo1300.even", 0x0000, 0x200, CRC (85562eb1) SHA1 (9335eeeabdd37255d6ffee153a027944a4519126), ROM_SKIP(1) | ROM_BIOS(1))
+ROM_END
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME
+COMP(1976, diablo, 0, 0, diablo1300, diablo1300, diablo1300_state, 0, "Diablo Systems Inc", "Diablo HyType II Series 1300 CPU", MACHINE_IS_SKELETON)
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 51e4bdf0b53..a4abe1328e7 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -11332,6 +11332,9 @@ kdynastg // (c) 1999 EZ Graphics
xfiles // (c) 1999 dgPIX Entertainment Inc
xfilesk // (c) 1999 dgPIX Entertainment Inc (censored for the Korean market)
+@source:diablo1300.cpp
+diablo //
+
@source:didact.cpp
md6802 //
mp68a //
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 959497979df..3e36a458ffa 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -166,6 +166,7 @@ dct11em.cpp
dectalk.cpp
decwritr.cpp
dgn_beta.cpp
+diablo1300.cpp
didact.cpp
digel804.cpp
digijet.cpp