summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Devin Acker <d@revenant1.net>2026-03-28 16:29:00 -0400
committer GitHub <noreply@github.com>2026-03-28 16:29:00 -0400
commit607a052f9a12beca3ca252b5e6aa2af81c1c32cc (patch)
treed5b987f3b8c2267f72b6c3e8469bf1e738865398
parenta3d864ad9efdd6dd03977e3e73671f28ec0887f2 (diff)
bus/centronics: Add NEC PC-6022 plotter [Devin Acker] (#15162)
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/centronics/ctronics.cpp2
-rw-r--r--src/devices/bus/centronics/pc6022.cpp146
-rw-r--r--src/devices/bus/centronics/pc6022.h61
-rw-r--r--src/devices/cpu/upd7810/upd7810.cpp11
-rw-r--r--src/devices/cpu/upd7810/upd7810.h3
-rw-r--r--src/devices/cpu/upd7810/upd7810_dasm.cpp238
-rw-r--r--src/devices/cpu/upd7810/upd7810_opcodes.cpp12
8 files changed, 357 insertions, 118 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 769a9a8eb21..11bf42d3ed7 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -1608,6 +1608,8 @@ if BUSES["CENTRONICS"] then
MAME_DIR .. "src/devices/bus/centronics/nec_p72.h",
MAME_DIR .. "src/devices/bus/centronics/nlq401.cpp",
MAME_DIR .. "src/devices/bus/centronics/nlq401.h",
+ MAME_DIR .. "src/devices/bus/centronics/pc6022.cpp",
+ MAME_DIR .. "src/devices/bus/centronics/pc6022.h",
MAME_DIR .. "src/devices/bus/centronics/printer.cpp",
MAME_DIR .. "src/devices/bus/centronics/printer.h",
MAME_DIR .. "src/devices/bus/centronics/samdac.cpp",
diff --git a/src/devices/bus/centronics/ctronics.cpp b/src/devices/bus/centronics/ctronics.cpp
index 224048a1df6..c5a747346fe 100644
--- a/src/devices/bus/centronics/ctronics.cpp
+++ b/src/devices/bus/centronics/ctronics.cpp
@@ -132,6 +132,7 @@ device_centronics_peripheral_interface::~device_centronics_peripheral_interface(
#include "mz1p16.h"
#include "nec_p72.h"
#include "nlq401.h"
+#include "pc6022.h"
#include "printer.h"
#include "samdac.h"
#include "smartboard.h"
@@ -157,6 +158,7 @@ void centronics_devices(device_slot_interface &device)
device.option_add("smartboard", CENTRONICS_SMARTBOARD);
device.option_add("nlq401", NLQ401);
device.option_add("mz1p16", MZ1P16);
+ device.option_add("pc6022", PC6022);
device.option_add_internal("hasp_savquest", HASP_SAVQUEST);
// TODO: will become option_add_internal when misc/neomania.cpp will have a working chipset
diff --git a/src/devices/bus/centronics/pc6022.cpp b/src/devices/bus/centronics/pc6022.cpp
new file mode 100644
index 00000000000..063971bca92
--- /dev/null
+++ b/src/devices/bus/centronics/pc6022.cpp
@@ -0,0 +1,146 @@
+// license:BSD-3-Clause
+// copyright-holders:Devin Acker
+/**********************************************************************
+
+Skeleton for NEC PC-6022 Color Plotter Printer
+
+User manual:
+https://archive.org/details/nec-pc-6022-color-plotter-printer-users-manual
+
+**********************************************************************/
+
+#include "emu.h"
+#include "pc6022.h"
+
+//#define VERBOSE 1
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(PC6022, pc6022_device, "pc6022", "NEC PC-6022 Color Plotter Printer")
+
+
+ROM_START( pc6022 )
+ ROM_REGION(0x1000, "cpu", 0)
+ ROM_LOAD("upd7801g-138.bin", 0x0000, 0x1000, CRC(0a294989) SHA1(fab85e88566ffa10923dec3a1a6b0d8346bc69ec))
+ROM_END
+
+const tiny_rom_entry *pc6022_device::device_rom_region() const
+{
+ return ROM_NAME( pc6022 );
+}
+
+
+INPUT_PORTS_START( pc6022 )
+ PORT_START("PB") // TODO: verify button order / switch polarity
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Pen Right");
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Pen Left");
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Pen Down / Paper Feed");
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Pen Up");
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_TOGGLE PORT_NAME("Step");
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPSETTING( 0x10, "2" )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_TOGGLE PORT_NAME("Character Set");
+ PORT_DIPSETTING( 0x00, "Hiragana" )
+ PORT_DIPSETTING( 0x20, "Katakana" )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Color Change")
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Pen Change")
+
+ PORT_START("PC")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) // TODO (stop/online LED?)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Stop")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) // TODO
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("busy", FUNC(input_merger_device::in_w<1>))
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(FUNC(pc6022_device::ack_w));
+ PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_OUTPUT ) // TODO (set/cleared during timer irq)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // TODO
+INPUT_PORTS_END
+
+ioport_constructor pc6022_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( pc6022 );
+}
+
+
+pc6022_device::pc6022_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, PC6022, tag, owner, clock),
+ device_centronics_peripheral_interface(mconfig, *this),
+ m_cpu(*this, "cpu"),
+ m_busy(*this, "busy")
+{
+}
+
+void pc6022_device::io_map(address_map &map)
+{
+ map.global_mask(0x00ff);
+ // TODO: does the address actually matter?
+ map(0x00, 0x00).r(FUNC(pc6022_device::data_r));
+}
+
+void pc6022_device::device_add_mconfig(machine_config &config)
+{
+ UPD7801(config, m_cpu, 4'000'000); // actual clock unknown
+ m_cpu->set_addrmap(AS_IO, &pc6022_device::io_map);
+ m_cpu->pa_out_cb().set(FUNC(pc6022_device::pa_w));
+ m_cpu->pb_in_cb().set_ioport("PB");
+ m_cpu->pc_in_cb().set_ioport("PC");
+ m_cpu->pc_out_cb().set_ioport("PC");
+
+ // firmware only manually polls INT1, but BUSY needs to go high faster than that
+ INPUT_MERGER_ANY_HIGH(config, m_busy);
+ m_busy->output_handler().set(FUNC(pc6022_device::output_busy));
+}
+
+void pc6022_device::device_start()
+{
+ m_data = 0;
+ m_last_pa = 0;
+ m_ack = 0;
+ m_strobe = 0;
+
+ save_item(NAME(m_data));
+ save_item(NAME(m_last_pa));
+ save_item(NAME(m_ack));
+ save_item(NAME(m_strobe));
+}
+
+void pc6022_device::device_reset()
+{
+ output_select(1);
+ output_busy(0);
+}
+
+void pc6022_device::input_strobe(int state)
+{
+ if (!state && m_strobe)
+ {
+ m_busy->in_set<0>();
+ m_cpu->set_input_line(UPD7810_INTF1, ASSERT_LINE);
+ }
+
+ m_strobe = state;
+}
+
+void pc6022_device::ack_w(int state)
+{
+ if (!state && m_ack)
+ {
+ m_busy->in_clear<0>();
+ m_cpu->set_input_line(UPD7810_INTF1, CLEAR_LINE);
+ }
+
+ m_ack = state;
+}
+
+void pc6022_device::pa_w(u8 data)
+{
+ // TODO: motor control?
+ // data is treated as two 4-bit values, only set/cleared during timer irq
+
+ if (data != m_last_pa)
+ LOG("pa_w: %02x\n", data);
+ m_last_pa = data;
+}
+
+u8 pc6022_device::data_r()
+{
+ return m_data;
+}
diff --git a/src/devices/bus/centronics/pc6022.h b/src/devices/bus/centronics/pc6022.h
new file mode 100644
index 00000000000..69e9582ffb1
--- /dev/null
+++ b/src/devices/bus/centronics/pc6022.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:Devin Acker
+
+#ifndef MAME_BUS_CENTRONICS_PC6022_H
+#define MAME_BUS_CENTRONICS_PC6022_H
+
+#pragma once
+
+#include "ctronics.h"
+#include "cpu/upd7810/upd7810.h"
+#include "machine/input_merger.h"
+
+class pc6022_device : public device_t,
+ public device_centronics_peripheral_interface
+{
+public:
+ static constexpr feature_type unemulated_features() { return feature::PRINTER; }
+
+ // construction/destruction
+ pc6022_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ void ack_w(int state);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual void input_strobe(int state) override;
+ virtual void input_data0(int state) override { if (state) m_data |= 0x01; else m_data &= ~0x01; }
+ virtual void input_data1(int state) override { if (state) m_data |= 0x02; else m_data &= ~0x02; }
+ virtual void input_data2(int state) override { if (state) m_data |= 0x04; else m_data &= ~0x04; }
+ virtual void input_data3(int state) override { if (state) m_data |= 0x08; else m_data &= ~0x08; }
+ virtual void input_data4(int state) override { if (state) m_data |= 0x10; else m_data &= ~0x10; }
+ virtual void input_data5(int state) override { if (state) m_data |= 0x20; else m_data &= ~0x20; }
+ virtual void input_data6(int state) override { if (state) m_data |= 0x40; else m_data &= ~0x40; }
+ virtual void input_data7(int state) override { if (state) m_data |= 0x80; else m_data &= ~0x80; }
+
+private:
+ required_device<upd7801_device> m_cpu;
+ required_device<input_merger_any_high_device> m_busy;
+
+ void io_map(address_map &map) ATTR_COLD;
+
+ void pa_w(u8 data);
+
+ u8 data_r();
+
+ u8 m_data;
+ u8 m_last_pa;
+ u8 m_ack;
+ u8 m_strobe;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(PC6022, pc6022_device)
+
+#endif // MAME_BUS_CENTRONICS_PC6022_H
diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp
index c6dcc437bd2..4c6b9da34fb 100644
--- a/src/devices/cpu/upd7810/upd7810.cpp
+++ b/src/devices/cpu/upd7810/upd7810.cpp
@@ -436,6 +436,7 @@ upd7810_device::upd7810_device(const machine_config &mconfig, device_type type,
, m_pf_out_cb(*this)
, m_pt_in_cb(*this, 0) // TODO: uPD7807 only
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, internal_map)
+ , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0)
, m_ram_view(*this, "ram_view")
, m_pa_pullups(0xff)
, m_pb_pullups(0xff)
@@ -568,6 +569,14 @@ device_memory_interface::space_config_vector upd7810_device::memory_space_config
};
}
+device_memory_interface::space_config_vector upd7801_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_IO, &m_io_config)
+ };
+}
+
std::unique_ptr<util::disasm_interface> upd7810_device::create_disassembler()
{
return std::make_unique<upd7810_disassembler>();
@@ -1670,6 +1679,8 @@ void upd7810_device::base_device_start()
{
space(AS_PROGRAM).specific(m_program);
space(AS_PROGRAM).cache(m_opcodes);
+ if (has_space(AS_IO))
+ space(AS_IO).specific(m_io);
configure_ops();
diff --git a/src/devices/cpu/upd7810/upd7810.h b/src/devices/cpu/upd7810/upd7810.h
index 503f9fcf270..f5f78d9afd2 100644
--- a/src/devices/cpu/upd7810/upd7810.h
+++ b/src/devices/cpu/upd7810/upd7810.h
@@ -239,6 +239,7 @@ protected:
static const struct opcode_s s_opXX_78c06[256];
address_space_config m_program_config;
+ address_space_config m_io_config; // 7800/01/02 only
memory_view m_ram_view;
PAIR m_ppc; /* previous program counter */
@@ -344,6 +345,7 @@ protected:
const struct opcode_s *m_op74;
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_opcodes;
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
+ memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_io;
int m_icount;
uint8_t RP(offs_t port);
@@ -1418,6 +1420,7 @@ protected:
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 2 - 1) / 2; }
virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 2); }
virtual void execute_set_input(int inputnum, int state) override;
+ virtual space_config_vector memory_space_config() const override;
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
virtual void handle_timers(int cycles) override;
virtual void upd7810_take_irq() override;
diff --git a/src/devices/cpu/upd7810/upd7810_dasm.cpp b/src/devices/cpu/upd7810/upd7810_dasm.cpp
index 6f07126a029..c08cc4a111a 100644
--- a/src/devices/cpu/upd7810/upd7810_dasm.cpp
+++ b/src/devices/cpu/upd7810/upd7810_dasm.cpp
@@ -3921,67 +3921,67 @@ const upd7810_base_disassembler::dasm_s upd7801_disassembler::d48_7801[256] = {
const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4C_7801[256] = {
// 0x00 - 0x3F
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
// 0x40 - 0x7F
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
// 0x80 - 0xBF
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
-
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
- { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
+ { IN, "%A" }, { IN, "%A" }, { IN, "%A" }, { IN, "%A" },
// 0xC0 - 0xFF
{ MOV, "A,PA" }, { MOV, "A,PB" }, { MOV, "A,PC" }, { MOV, "A,MK" },
@@ -4007,67 +4007,67 @@ const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4C_7801[256] = {
const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4D_7801[256] = {
// 0x00 - 0x3F
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
// 0x40 - 0x7F
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
// 0x80 - 0xBF
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
-
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
- { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
+ { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" }, { OUT, "%A" },
// 0xC0 - 0xFF
{ MOV, "PA,A" }, { MOV, "PB,A" }, { MOV, "PC,A" }, { MOV, "MK,A" },
@@ -5232,10 +5232,13 @@ const char *const upd7810_base_disassembler::regname[32] =
offs_t upd7810_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
offs_t idx = pc;
- const uint8_t op = opcodes.r8(idx++);
+ uint8_t op = opcodes.r8(idx++);
const dasm_s *desc = &m_dasmXX[op];
if (desc->is_prefix())
- desc = &desc->prefix_get(opcodes.r8(idx++));
+ {
+ op = opcodes.r8(idx++);
+ desc = &desc->prefix_get(op);
+ }
util::stream_format(stream, "%-8.8s", desc->name());
@@ -5255,6 +5258,9 @@ offs_t upd7810_base_disassembler::disassemble(std::ostream &stream, offs_t pc, c
op2 = params.r8(idx++);
util::stream_format(stream, "VV:%02X", op2);
break;
+ case 'A': /* I/O address (7801) */
+ util::stream_format(stream, "$%02X", op);
+ break;
case 'b': /* immediate byte */
util::stream_format(stream, "$%02X", params.r8(idx++));
break;
diff --git a/src/devices/cpu/upd7810/upd7810_opcodes.cpp b/src/devices/cpu/upd7810/upd7810_opcodes.cpp
index 89117d84b95..49c3b6b38bf 100644
--- a/src/devices/cpu/upd7810/upd7810_opcodes.cpp
+++ b/src/devices/cpu/upd7810/upd7810_opcodes.cpp
@@ -9404,12 +9404,20 @@ void upd7810_device::CALT_7801()
void upd7810_device::IN()
{
- logerror("unimplemented instruction: IN\n");
+ PAIR ea;
+ ea.b.h = B;
+ ea.b.l = OP2;
+
+ A = m_io.read_byte(ea.w.l);
}
void upd7810_device::OUT()
{
- logerror("unimplemented instruction: OUT\n");
+ PAIR ea;
+ ea.b.h = B;
+ ea.b.l = OP2;
+
+ m_io.write_byte(ea.w.l, A);
}
void upd7810_device::MOV_A_S()