summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-11-25 22:51:21 -0500
committer AJR <ajrhacker@users.noreply.github.com>2019-11-25 22:55:20 -0500
commite69ff59e42f8ebe217bc6a2b6fdedce755cc32aa (patch)
treee1592fa0e93ec5c8854f28a782d698e2afa9e610 /src
parentafa6622592e937f2951d1f4ee65a73e1e9849f53 (diff)
New machines marked as NOT_WORKING
---------------------------------- Speedcom VD56SP [ClawGrip] Add disassembler and basic execution core for Rockwell R65C19 [AJR]
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/m6502/dr65c19.lst20
-rw-r--r--src/devices/cpu/m6502/m6502d.cpp15
-rw-r--r--src/devices/cpu/m6502/m6502d.h3
-rwxr-xr-xsrc/devices/cpu/m6502/m6502make.py4
-rw-r--r--src/devices/cpu/m6502/or65c19.lst355
-rw-r--r--src/devices/cpu/m6502/r65c19.cpp106
-rw-r--r--src/devices/cpu/m6502/r65c19.h90
-rw-r--r--src/devices/cpu/m6502/r65c19d.cpp10
-rw-r--r--src/devices/cpu/m6502/r65c19d.h21
-rw-r--r--src/mame/drivers/vd56sp.cpp57
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/mame/mess.flt1
-rw-r--r--src/tools/unidasm.cpp2
13 files changed, 685 insertions, 2 deletions
diff --git a/src/devices/cpu/m6502/dr65c19.lst b/src/devices/cpu/m6502/dr65c19.lst
new file mode 100644
index 00000000000..f202944f2a7
--- /dev/null
+++ b/src/devices/cpu/m6502/dr65c19.lst
@@ -0,0 +1,20 @@
+# license:BSD-3-Clause
+# copyright-holders:AJR
+# r65c19 - many new instructions, others shuffled around or subtly altered in behavior
+brk_r_imp ora_zpi mpy_imp tip_imp nop_zpg ora_zpg asl_c_zpg rmb_bzp php_imp ora_imm asl_acc jsb_vec jpi_ind ora_aba asl_c_aba bbr_zpb
+bpl_rel ora_idx mpa_imp lab_acc nop_zpx ora_zpx asl_c_zpx rmb_bzp clc_imp ora_aby neg_acc jsb_vec nop_c_abx ora_abx asl_c_abx bbr_zpb
+jsr_r_adr and_zpi psh_imp phw_imp bit_zpg and_zpg rol_c_zpg rmb_bzp plp_imp and_imm rol_acc jsb_vec bit_aba and_aba rol_c_aba bbr_zpb
+bmi_rel and_idx pul_imp plw_imp nop_zpx and_zpx rol_c_zpx rmb_bzp sec_imp and_aby asr_acc jsb_vec nop_c_abx and_abx rol_c_abx bbr_zpb
+rti_imp eor_zpi rnd_imp nop_c_imp nop_zpg eor_zpg lsr_c_zpg rmb_bzp pha_imp eor_imm lsr_acc jsb_vec jmp_adr eor_aba lsr_c_aba bbr_zpb
+bvc_rel eor_idx clw_imp nop_c_imp nop_zpx eor_zpx lsr_c_zpx rmb_bzp cli_imp eor_aby phy_imp jsb_vec nop_c_abx eor_abx lsr_c_abx bbr_zpb
+rts_r_imp adc_c_zpi taw_imp nop_c_imp add_zpg adc_c_zpg ror_c_zpg rmb_bzp pla_imp adc_c_imm ror_acc jsb_vec jmp_r_ind adc_c_aba ror_c_aba bbr_zpb
+bvs_rel adc_c_idx twa_imp nop_c_imp add_zpx adc_c_zpx ror_c_zpx rmb_bzp sei_imp adc_c_aby ply_imp jsb_vec jmp_iax adc_c_abx ror_c_abx bbr_zpb
+bra_rel sta_zpi nop_imm nop_c_imp sty_zpg sta_zpg stx_zpg smb_bzp dey_imp add_imm txa_imp nxt_imp sty_aba sta_aba stx_aba bbs_zpb
+bcc_rel sta_idx nop_imm nop_c_imp sty_zpx sta_zpx stx_zpy smb_bzp tya_imp sta_aby txs_imp lii_imp nop_c_abx sta_abx nop_c_abx bbs_zpb
+ldy_imm lda_zpi ldx_imm nop_c_imp ldy_zpg lda_zpg ldx_zpg smb_bzp tay_imp lda_imm tax_imp lan_imp ldy_aba lda_aba ldx_aba bbs_zpb
+bcs_rel lda_idx sti_imz nop_c_imp ldy_zpx lda_zpx ldx_zpy smb_bzp clv_imp lda_aby tsx_imp ini_imp ldy_abx lda_abx ldx_aby bbs_zpb
+cpy_imm cmp_zpi rba_ima nop_c_imp cpy_zpg cmp_zpg dec_c_zpg smb_bzp iny_imp cmp_imm dex_imp phi_imp cpy_aba cmp_aba dec_c_aba bbs_zpb
+bne_rel cmp_idx sba_ima nop_c_imp exc_zpx cmp_zpx dec_c_zpx smb_bzp cld_imp cmp_aby phx_imp pli_imp nop_c_abx cmp_abx dec_c_abx bbs_zpb
+cpx_imm sbc_c_zpi bar_amr nop_c_imp cpx_zpg sbc_c_zpg inc_c_zpg smb_bzp inx_imp sbc_c_imm nop_imp lai_imp cpx_aba sbc_c_aba inc_c_aba bbs_zpb
+beq_rel sbc_c_idx bas_amr nop_c_imp nop_zpx sbc_c_zpx inc_c_zpx smb_bzp sed_imp sbc_c_aby plx_imp pia_imp nop_c_abx sbc_c_abx inc_c_abx bbs_zpb
+reset_r
diff --git a/src/devices/cpu/m6502/m6502d.cpp b/src/devices/cpu/m6502/m6502d.cpp
index 589aafdf3b7..59d1dfc05f5 100644
--- a/src/devices/cpu/m6502/m6502d.cpp
+++ b/src/devices/cpu/m6502/m6502d.cpp
@@ -62,6 +62,11 @@ offs_t m6502_base_disassembler::disassemble(std::ostream &stream, offs_t pc, con
flags |= 3;
break;
+ case DASM_amr:
+ util::stream_format(stream, " $%02x%02x, #$%02x, $%04x", params.r8(pc+2), params.r8(pc+1), params.r8(pc+3), uint16_t(pc + 5 + int8_t(params.r8(pc+4))));
+ flags |= 5;
+ break;
+
case DASM_bzp:
util::stream_format(stream, "%d $%02x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1));
flags |= 2;
@@ -87,6 +92,11 @@ offs_t m6502_base_disassembler::disassemble(std::ostream &stream, offs_t pc, con
flags |= 2;
break;
+ case DASM_ima:
+ util::stream_format(stream, " #$%02x, $%02x%02x", params.r8(pc+1), params.r8(pc+3), params.r8(pc+2));
+ flags |= 4;
+ break;
+
case DASM_imm:
util::stream_format(stream, " #$%02x", params.r8(pc+1));
flags |= 2;
@@ -126,6 +136,11 @@ offs_t m6502_base_disassembler::disassemble(std::ostream &stream, offs_t pc, con
flags |= 3;
break;
+ case DASM_vec:
+ util::stream_format(stream, "%d", (opcodes.r8(pc) >> 4) & 7);
+ flags |= 1;
+ break;
+
case DASM_zpb:
util::stream_format(stream, "%d $%02x, $%04x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1), (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+2))));
flags |= 3;
diff --git a/src/devices/cpu/m6502/m6502d.h b/src/devices/cpu/m6502/m6502d.h
index 5a02dddca04..de15b41d253 100644
--- a/src/devices/cpu/m6502/m6502d.h
+++ b/src/devices/cpu/m6502/m6502d.h
@@ -36,11 +36,13 @@ protected:
DASM_aby, /* absolute + Y */
DASM_acc, /* accumulator */
DASM_adr, /* absolute address (jmp,jsr) */
+ DASM_amr, /* absolute address, mask byte and relative address (r65c19) */
DASM_bzp, /* zero page with bit selection */
DASM_iax, /* indirect + X (65c02 jmp) */
DASM_idx, /* zero page pre indexed */
DASM_idy, /* zero page post indexed */
DASM_idz, /* zero page post indexed (65ce02) */
+ DASM_ima, /* immediate byte and absolute address (r65c19) */
DASM_imm, /* immediate */
DASM_imp, /* implicit */
DASM_ind, /* indirect (jmp) */
@@ -49,6 +51,7 @@ protected:
DASM_iw3, /* augment (65ce02) */
DASM_rel, /* relative */
DASM_rw2, /* relative word (65cs02, 65ce02) */
+ DASM_vec, /* vector (r65c19 jbs) */
DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */
DASM_zpg, /* zero page */
DASM_zpi, /* zero page indirect (65c02) */
diff --git a/src/devices/cpu/m6502/m6502make.py b/src/devices/cpu/m6502/m6502make.py
index ea51fe43350..31f10d4f8d1 100755
--- a/src/devices/cpu/m6502/m6502make.py
+++ b/src/devices/cpu/m6502/m6502make.py
@@ -227,9 +227,9 @@ def save_dasm(f, device, states):
opc = tokens[0]
mode = tokens[-1]
extra = "0"
- if opc in ["jsr", "bsr", "callf"]:
+ if opc in ["jsr", "bsr", "callf", "jpi", "jsb"]:
extra = "STEP_OVER"
- elif opc in ["rts", "rti", "rtn", "retf"]:
+ elif opc in ["rts", "rti", "rtn", "retf", "tpi"]:
extra = "STEP_OUT"
emit(f, '\t{ "%s", DASM_%s, %s },' % (opc, mode, extra))
emit(f, DISASM_EPILOG % d)
diff --git a/src/devices/cpu/m6502/or65c19.lst b/src/devices/cpu/m6502/or65c19.lst
new file mode 100644
index 00000000000..392ccfa9ac6
--- /dev/null
+++ b/src/devices/cpu/m6502/or65c19.lst
@@ -0,0 +1,355 @@
+# license:BSD-3-Clause
+# copyright-holders:Olivier Galibert, AJR
+add_imm
+ TMP = read_pc();
+ do_add(TMP);
+ if(P & F_D) {
+ read_pc_noinc();
+ set_nz(A);
+ }
+ prefetch();
+
+add_zpg
+ TMP = read_pc();
+ TMP = read(TMP);
+ do_add(TMP);
+ if(P & F_D) {
+ read_pc_noinc();
+ set_nz(A);
+ }
+ prefetch();
+
+add_zpx
+ TMP = read_pc();
+ read(TMP);
+ TMP = read(uint8_t(TMP+X));
+ do_add(TMP);
+ if(P & F_D) {
+ read_pc_noinc();
+ set_nz(A);
+ }
+ prefetch();
+
+asr_acc
+ read_pc_noinc();
+ A = do_asr(A);
+ prefetch();
+
+bar_amr
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ TMP2 = read(TMP);
+ TMP = read_pc_noinc();
+ read_pc();
+ TMP2 &= ~TMP;
+ TMP = read_pc();
+ if(TMP2 != 0) {
+ read_pc_noinc();
+ if(page_changing(PC, int8_t(TMP))) {
+ read_arg(set_l(PC, PC+int8_t(TMP)));
+ }
+ PC += int8_t(TMP);
+ }
+ prefetch();
+
+bas_amr
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ TMP2 = read(TMP);
+ TMP = read_pc_noinc();
+ read_pc();
+ TMP2 &= TMP;
+ TMP = read_pc();
+ if(TMP2 != 0) {
+ read_pc_noinc();
+ if(page_changing(PC, int8_t(TMP))) {
+ read_arg(set_l(PC, PC+int8_t(TMP)));
+ }
+ PC += int8_t(TMP);
+ }
+ prefetch();
+
+brk_r_imp
+ if(irq_taken || nmi_state) {
+ read_pc_noinc();
+ } else {
+ read_pc();
+ }
+ write(SP, PC >> 8);
+ dec_SP();
+ write(SP, PC);
+ dec_SP();
+ write(SP, irq_taken || nmi_state ? P & ~F_B : P);
+ dec_SP();
+ if(irq_taken && nmi_state) {
+ PC = read_arg(0xfffc);
+ PC = set_h(PC, read_arg(0xfffd));
+ nmi_state = false;
+ standard_irq_callback(NMI_LINE);
+ } else {
+ TMP = get_irq_vector();
+ PC = read_arg(TMP);
+ PC = set_h(PC, read_arg(TMP+1));
+ if(irq_taken)
+ standard_irq_callback(((~TMP & 0x000e) >> 1) - 1);
+ }
+ irq_taken = false;
+ P = (P | F_I) & ~F_D; // Do *not* move after the prefetch
+ prefetch();
+ inst_state = -1;
+
+clw_imp
+ read_pc_noinc();
+ P &= ~F_V;
+ m_w = 0;
+ prefetch();
+
+exc_zpx
+ TMP = read_pc();
+ read(TMP);
+ TMP = uint8_t(TMP+X);
+ TMP2 = read(TMP);
+ write(TMP, A);
+ A = TMP2;
+ prefetch();
+
+ini_imp
+ read_pc_noinc();
+ read(m_i);
+ m_i++;
+ prefetch();
+
+jpi_ind
+ m_i = PC;
+ TMP = read_arg(m_i);
+ TMP = set_h(TMP, read_arg(m_i+1));
+ m_i += 2;
+ PC = read(TMP);
+ PC = set_h(PC, read(TMP+1));
+ prefetch();
+
+jsb_vec
+ read_pc_noinc();
+ write(SP, PC>>8);
+ dec_SP();
+ write(SP, PC);
+ dec_SP();
+ TMP = 0xffe0 | ((inst_state >> 3) & 0x0e);
+ PC = read_arg(TMP);
+ PC = set_h(PC, read_arg(TMP+1));
+ prefetch();
+
+jmp_r_ind
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ PC = read(TMP);
+ PC = set_h(PC, read(TMP+1));
+ prefetch();
+
+jsr_r_adr
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ write(SP, PC>>8);
+ dec_SP();
+ write(SP, PC);
+ dec_SP();
+ PC = TMP;
+ prefetch();
+
+lab_acc
+ read_pc_noinc();
+ read_pc_noinc();
+ if(int8_t(A) < 0)
+ A = -A;
+ set_nz(A);
+ prefetch();
+
+lai_imp
+ read_pc_noinc();
+ A = read(m_i);
+ prefetch();
+
+lan_imp
+ read_pc_noinc();
+ A = read(m_i);
+ m_i++;
+ prefetch();
+
+lii_imp
+ read_pc_noinc();
+ TMP = read(m_i);
+ TMP = set_h(TMP, read(m_i+1));
+ read(TMP);
+ m_i = TMP;
+ prefetch();
+
+mpa_imp
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ TMP = int8_t(A) * int8_t(Y);
+ m_w = do_accumulate(TMP, m_w);
+ prefetch();
+
+mpy_imp
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ read_pc_noinc();
+ TMP = int8_t(A) * int8_t(Y);
+ A = do_accumulate(TMP, 0)>>8;
+ prefetch();
+
+neg_acc
+ read_pc_noinc();
+ A = -A;
+ set_nz(A);
+ prefetch();
+
+nxt_imp
+ read_pc_noinc();
+ PC = read(m_i);
+ PC = set_h(PC, read(m_i+1));
+ m_i += 2;
+ prefetch();
+
+phi_imp
+ read_pc_noinc();
+ write(SP, m_i>>8);
+ dec_SP();
+ write(SP, m_i);
+ dec_SP();
+ prefetch();
+
+phw_imp
+ read_pc_noinc();
+ write(SP, m_w>>8);
+ dec_SP();
+ write(SP, m_w);
+ dec_SP();
+ prefetch();
+
+pia_imp
+ read_pc_noinc();
+ read(SP);
+ inc_SP();
+ m_i = read(SP);
+ inc_SP();
+ m_i = set_h(m_i, read(SP));
+ A = read(m_i);
+ m_i++;
+ prefetch();
+
+pli_imp
+ read_pc_noinc();
+ read(SP);
+ inc_SP();
+ m_i = read(SP);
+ inc_SP();
+ m_i = set_h(m_i, read(SP));
+ read(m_i);
+ prefetch();
+
+plw_imp
+ read_pc_noinc();
+ read(SP);
+ inc_SP();
+ m_w = read(SP);
+ inc_SP();
+ m_w = set_h(m_w, read(SP));
+ prefetch();
+
+psh_imp
+ read_pc_noinc();
+ write(SP, A);
+ dec_SP();
+ write(SP, X);
+ dec_SP();
+ write(SP, Y);
+ dec_SP();
+ prefetch();
+
+pul_imp
+ read_pc_noinc();
+ read(SP);
+ inc_SP();
+ Y = read(SP);
+ inc_SP();
+ X = read(SP);
+ inc_SP();
+ A = read(SP);
+ prefetch();
+
+rba_ima
+ A = read_pc(); // "Note that Accumulator contents are altered by RBA and SBA" (C29/C39 Technical Reference Manual, p. C-29)
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ TMP2 = read(TMP);
+ read(TMP);
+ TMP2 &= ~A;
+ write(TMP, TMP2);
+ prefetch();
+
+rnd_imp
+ read_pc_noinc();
+ TMP = set_l(m_w, Y);
+ A = do_accumulate(TMP, (m_w<<1) & 0x100)>>8;
+ prefetch();
+
+rts_r_imp
+ read_pc_noinc();
+ read_pc_noinc();
+ inc_SP();
+ PC = read(SP);
+ inc_SP();
+ PC = set_h(PC, read(SP));
+ prefetch();
+
+sba_ima
+ A = read_pc();
+ TMP = read_pc();
+ TMP = set_h(TMP, read_pc());
+ TMP2 = read(TMP);
+ read(TMP);
+ TMP2 |= A;
+ write(TMP, TMP2);
+ prefetch();
+
+sti_imz
+ TMP = read_pc();
+ TMP2 = read_pc();
+ write(TMP2, TMP);
+ prefetch();
+
+taw_imp
+ read_pc_noinc();
+ m_w = A<<8;
+ set_nz(m_w>>8);
+ prefetch();
+
+tip_imp
+ read_pc_noinc();
+ PC = m_i;
+ prefetch();
+
+twa_imp
+ read_pc_noinc();
+ A = m_w>>8;
+ set_nz(A);
+ prefetch();
+
+# exceptions
+reset_r
+ read_pc();
+ read_pc_noinc();
+ read(SP); dec_SP();
+ read(SP); dec_SP();
+ read(SP); dec_SP();
+ P = (P | F_I) & ~F_D;
+ PC = read_arg(0xfffe);
+ PC = set_h(PC, read_arg(0xffff));
+ prefetch();
+ inst_state = -1;
diff --git a/src/devices/cpu/m6502/r65c19.cpp b/src/devices/cpu/m6502/r65c19.cpp
new file mode 100644
index 00000000000..9cda9d33a0e
--- /dev/null
+++ b/src/devices/cpu/m6502/r65c19.cpp
@@ -0,0 +1,106 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Rockwell R65C19 Microcomputer (MCU)
+
+ TODO: fully describe this MCU and its successors (C29, C39) and
+ emulate their internal peripherals (only core emulation now)
+
+**********************************************************************/
+
+#include "emu.h"
+#include "r65c19.h"
+#include "r65c19d.h"
+
+DEFINE_DEVICE_TYPE(R65C19, r65c19_device, "r65c19", "Rockwell R65C19 MCU")
+
+r65c19_device::r65c19_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map)
+ : r65c02_device(mconfig, type, tag, owner, clock)
+ , m_w(0)
+ , m_i(0)
+{
+ program_config.m_internal_map = std::move(internal_map);
+}
+
+r65c19_device::r65c19_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : r65c19_device(mconfig, R65C19, tag, owner, clock, address_map_constructor())
+{
+}
+
+std::unique_ptr<util::disasm_interface> r65c19_device::create_disassembler()
+{
+ return std::make_unique<r65c19_disassembler>();
+}
+
+void r65c19_device::do_add(u8 v)
+{
+ P &= ~F_C;
+ do_adc(v);
+}
+
+u16 r65c19_device::do_accumulate(u16 v, u16 w)
+{
+ // Compute the sum
+ s32 result = s16(v) + s16(w);
+
+ // Determine flags and saturate result upon overflow
+ P &= ~(F_N | F_V);
+ if (result > 32767)
+ {
+ P |= F_V;
+ result = 32767;
+ }
+ else if (result < 0)
+ {
+ P |= F_N;
+ if (result < -32768)
+ {
+ P |= F_V;
+ result = -32768;
+ }
+ }
+
+ // MPA and MPY always destroy the old value of Y, as does RND when it overflows
+ Y = result & 0xff;
+
+ // 16-bit result to W, or high byte to A
+ return result & 0xffff;
+}
+
+u16 r65c19_device::get_irq_vector()
+{
+ // TODO: this is a stub
+ return 0xfffc;
+}
+
+void r65c19_device::device_start()
+{
+ mintf = std::make_unique<mi_default>();
+
+ c19_init();
+}
+
+void r65c19_device::c19_init()
+{
+ init();
+
+ state_add(R65C19_W, "W", m_w);
+ state_add<u8>(R65C19_WL, "WL",
+ [this]() { return m_w & 0xff; },
+ [this](u8 data) { m_w = set_l(m_w, data); }).noshow();
+ state_add<u8>(R65C19_WH, "WH",
+ [this]() { return m_w >> 8; },
+ [this](u8 data) { m_w = set_h(m_w, data); }).noshow();
+ state_add(R65C19_I, "I", m_i);
+
+ save_item(NAME(m_w));
+ save_item(NAME(m_i));
+}
+
+void r65c19_device::device_reset()
+{
+ r65c02_device::device_reset();
+}
+
+#include "cpu/m6502/r65c19.hxx"
diff --git a/src/devices/cpu/m6502/r65c19.h b/src/devices/cpu/m6502/r65c19.h
new file mode 100644
index 00000000000..a300d4a332a
--- /dev/null
+++ b/src/devices/cpu/m6502/r65c19.h
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+
+#ifndef MAME_CPU_M6502_R65C19_H
+#define MAME_CPU_M6502_R65C19_H
+
+#pragma once
+
+#include "r65c02.h"
+
+class r65c19_device : public r65c02_device
+{
+public:
+ enum {
+ R65C19_W = M6502_IR + 1,
+ R65C19_WL,
+ R65C19_WH,
+ R65C19_I
+ };
+
+ r65c19_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ r65c19_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ virtual void do_exec_full() override;
+ virtual void do_exec_partial() override;
+
+ virtual u16 get_irq_vector();
+
+ void c19_init();
+
+private:
+ void do_add(u8 v);
+ u16 do_accumulate(u16 v, u16 w);
+
+#define O(o) void o ## _full(); void o ## _partial()
+
+ O(add_imm);
+ O(add_zpg);
+ O(add_zpx);
+ O(asr_acc);
+ O(bar_amr);
+ O(bas_amr);
+ O(brk_r_imp);
+ O(clw_imp);
+ O(exc_zpx);
+ O(ini_imp);
+ O(jpi_ind);
+ O(jsb_vec);
+ O(jmp_r_ind);
+ O(jsr_r_adr);
+ O(lab_acc);
+ O(lai_imp);
+ O(lan_imp);
+ O(lii_imp);
+ O(mpa_imp);
+ O(mpy_imp);
+ O(neg_acc);
+ O(nxt_imp);
+ O(phi_imp);
+ O(phw_imp);
+ O(pia_imp);
+ O(pli_imp);
+ O(plw_imp);
+ O(psh_imp);
+ O(pul_imp);
+ O(rba_ima);
+ O(rnd_imp);
+ O(rts_r_imp);
+ O(sba_ima);
+ O(sti_imz);
+ O(taw_imp);
+ O(tip_imp);
+ O(twa_imp);
+ O(reset_r);
+
+#undef O
+
+ u16 m_w;
+ u16 m_i;
+};
+
+DECLARE_DEVICE_TYPE(R65C19, r65c19_device)
+
+#endif // MAME_CPU_M6502_R65C19_H
diff --git a/src/devices/cpu/m6502/r65c19d.cpp b/src/devices/cpu/m6502/r65c19d.cpp
new file mode 100644
index 00000000000..6f244a79151
--- /dev/null
+++ b/src/devices/cpu/m6502/r65c19d.cpp
@@ -0,0 +1,10 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#include "emu.h"
+#include "r65c19d.h"
+#include "cpu/m6502/r65c19d.hxx"
+
+r65c19_disassembler::r65c19_disassembler() : m6502_base_disassembler(disasm_entries)
+{
+}
diff --git a/src/devices/cpu/m6502/r65c19d.h b/src/devices/cpu/m6502/r65c19d.h
new file mode 100644
index 00000000000..1b6466a0e6f
--- /dev/null
+++ b/src/devices/cpu/m6502/r65c19d.h
@@ -0,0 +1,21 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#ifndef MAME_CPU_M6502_R65C19D_H
+#define MAME_CPU_M6502_R65C19D_H
+
+#pragma once
+
+#include "m6502d.h"
+
+class r65c19_disassembler : public m6502_base_disassembler
+{
+public:
+ r65c19_disassembler();
+ virtual ~r65c19_disassembler() = default;
+
+private:
+ static const disasm_entry disasm_entries[0x100];
+};
+
+#endif
diff --git a/src/mame/drivers/vd56sp.cpp b/src/mame/drivers/vd56sp.cpp
new file mode 100644
index 00000000000..ac1569f62a5
--- /dev/null
+++ b/src/mame/drivers/vd56sp.cpp
@@ -0,0 +1,57 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/****************************************************************************
+
+ Skeleton driver for Speedcom 56K V.90 external modem using Conexant
+ (formerly Rockwell) chipset.
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/m6502/r65c19.h"
+
+class vd56sp_state : public driver_device
+{
+public:
+ vd56sp_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ {
+ }
+
+ void vd56sp(machine_config &mconfig);
+
+private:
+ void mem_map(address_map &map);
+
+ required_device<r65c19_device> m_maincpu;
+};
+
+
+void vd56sp_state::mem_map(address_map &map)
+{
+ map(0x0040, 0x03ff).ram();
+ map(0x0800, 0x1fff).rom().region("firmware", 0x20800);
+ map(0x8000, 0xffff).rom().region("firmware", 0x28000);
+}
+
+
+static INPUT_PORTS_START(vd56sp)
+INPUT_PORTS_END
+
+void vd56sp_state::vd56sp(machine_config &config)
+{
+ R65C19(config, m_maincpu, 8'000'000); // FIXME: actually L2800-38 (XTAL not readable)
+ m_maincpu->set_addrmap(AS_PROGRAM, &vd56sp_state::mem_map);
+
+ // Modem IC: Conexant R6764-61
+}
+
+
+ROM_START(vd56sp)
+ ROM_REGION(0x40000, "firmware", 0)
+ ROM_LOAD("vd56sp_v2.2_8904005.u10", 0x00000, 0x40000, CRC(23ddae13) SHA1(7a194f681389c2923ea6848b3a25f26c532a3200))
+ROM_END
+
+
+SYST(199?, vd56sp, 0, 0, vd56sp, vd56sp, vd56sp_state, empty_init, "Pro-Nets Technology", "Speedcom VD56SP", MACHINE_IS_SKELETON)
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index d460f00ab5e..e063c6ad2fc 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -39373,6 +39373,9 @@ vcs80 //
break86 //
papillon //
+@source:vd56sp.cpp
+vd56sp //
+
@source:vdm7932x.cpp
vdm79322 //
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 556cfab1ddb..cde2cffb87e 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -910,6 +910,7 @@ vax11.cpp
vboy.cpp
vc4000.cpp
vcs80.cpp
+vd56sp.cpp
vdm7932x.cpp
vector06.cpp
vector4.cpp
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index 5261424feb4..c7b125dc54f 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -82,6 +82,7 @@ using util::BIT;
#include "cpu/m6502/m65ce02d.h"
#include "cpu/m6502/m740d.h"
#include "cpu/m6502/r65c02d.h"
+#include "cpu/m6502/r65c19d.h"
#include "cpu/m6502/xavixd.h"
#include "cpu/m6502/xavix2000d.h"
#include "cpu/m6800/6800dasm.h"
@@ -453,6 +454,7 @@ static const dasm_table_entry dasm_table[] =
{ "pps4", le, 0, []() -> util::disasm_interface * { return new pps4_disassembler; } },
{ "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } },
{ "r65c02", le, 0, []() -> util::disasm_interface * { return new r65c02_disassembler; } },
+ { "r65c19", le, 0, []() -> util::disasm_interface * { return new r65c19_disassembler; } },
{ "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } },
{ "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } },
{ "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } },