summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
author holub <andrei.holub@gmail.com>2024-12-27 21:56:18 -0500
committer GitHub <noreply@github.com>2024-12-27 21:56:18 -0500
commit07cc2cf76ab85656a11aee05c308176e4e1c9105 (patch)
treea79068c6042d8446826c34fd199e414fd2251dfa /src/devices/cpu
parent39aac1bc7035c10a41bcf0547139279651249519 (diff)
cpu/mpk1839/kl1839vm1.cpp: Improved VAX-11 code decoder in user space (#13107)
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/mpk1839/kl1839vm1.cpp672
-rw-r--r--src/devices/cpu/mpk1839/kl1839vm1.h61
-rw-r--r--src/devices/cpu/mpk1839/kl1839vm1dasm.cpp34
-rw-r--r--src/devices/cpu/vax/vaxdasm.cpp46
-rw-r--r--src/devices/cpu/vax/vaxdasm.h14
5 files changed, 626 insertions, 201 deletions
diff --git a/src/devices/cpu/mpk1839/kl1839vm1.cpp b/src/devices/cpu/mpk1839/kl1839vm1.cpp
index 00c30e8a5f2..5be6b534f6d 100644
--- a/src/devices/cpu/mpk1839/kl1839vm1.cpp
+++ b/src/devices/cpu/mpk1839/kl1839vm1.cpp
@@ -5,22 +5,26 @@
#include "kl1839vm1.h"
#include "kl1839vm1dasm.h"
+#include "cpu/vax/vaxdasm.h"
+#include <regex>
-#define VERBOSE ( LOG_GENERAL )
+#define LOG_VAX (1U << 1)
+
+//#define VERBOSE ( LOG_GENERAL | LOG_VAX )
#include "logmacro.h"
#define UNIMPLEMENTED(msg) LOG("Unimplemented: %s\n", msg)
+#define LOGVAX(...) LOGMASKED(LOG_VAX, __VA_ARGS__)
-#define MCA m_mca.w.l // Micro Command Address
-#define VMA m_vma.d // Virtual Memory Address
-#define RV m_rv.d
-#define SCH m_sch.b.l // Program Counter
-#define RSP m_rsp.b.l
+#define AMC m_amc.d // Microcode PC
+#define RV m_rv.d // Return Address
+#define SCH m_sch.b.l // Counter
+#define RSP m_rsp.b.l // Flags
#define K(x) m_consts[x & 0x0f]
#define PCM K(5)
-#define RC K(6)
+#define RC K(6) // Constant
/* registers of various sizes */
#define R(x) m_reg[x].d
@@ -65,8 +69,13 @@ device_memory_interface::space_config_vector kl1839vm1_device::memory_space_conf
void kl1839vm1_device::flag(u32 op)
{
- const u8 copwt = BIT(op, 15, 1);
+ const bool tou = BIT(op, 16);
+ if (tou)
+ {
+ // TODO Stop BO till the end of DP (Memory Manager?)
+ }
+ const bool copwt = BIT(op, 15);
if (copwt)
{
RNK = PC;
@@ -94,7 +103,7 @@ u32 kl1839vm1_device::shr(u32 val, bool va, u8 fo, bool a_c, bool l_r)
{
case 0b00: left_bit = 31; break;
case 0b01: left_bit = 15; break;
- case 0b10: left_bit = 31; break; // ??? dd
+ case 0b10: left_bit = 31; break;
case 0b11: left_bit = 7; break;
}
const u8 rd = l_r ? left_bit : 0;
@@ -105,14 +114,13 @@ u32 kl1839vm1_device::shr(u32 val, bool va, u8 fo, bool a_c, bool l_r)
res &= ~(1 << wr);
if (!a_c)
{
- res |= (va ? (RSP & CF) : carry_out) << wr;
+ res |= (va ? (PSW & CF) : carry_out) << wr;
}
else if (l_r && !va)
{
res |= carry_out << wr;
}
- RSP &= ~(VF | CF);
RSP |= carry_out;
if (a_c && l_r && (fo == 0b10) && (carry_out != BIT(res, rd)))
{
@@ -121,23 +129,34 @@ u32 kl1839vm1_device::shr(u32 val, bool va, u8 fo, bool a_c, bool l_r)
return res;
}
-void kl1839vm1_device::kop(u8 kop, u8 fd, u32 x, u32 y, u32 &z, u8 ps, bool va = false, u8 fo = 0)
+void kl1839vm1_device::kop(u8 kop, u8 fd, u32 x, u32 y, u8 rz, u8 ps, bool va = false, u8 fo = 0)
{
- u32 res = 0;
- RSP &= ~(NF | ZF | VF);
- if ((kop & 0b1001) == 0b1001) // shr
+ u64 res = 0;
+ switch(fd)
{
- RSP &= ~CF;
+ case 0b11:
+ x = s8(x);
+ y = s8(y);
+ break;
+ case 0b01:
+ x = s16(x);
+ y = s16(y);
+ break;
+ case 0b00:
+ default: // 0b10
+ break;
}
+
+ RSP &= ~(VF | CF);
switch(kop)
{
case 0b0000: res = y; break;
// 0b0001:
- case 0b0010: res = x + y; break;
+ case 0b0010: res = u64(x) + y; break;
case 0b0011: res = x; break;
- case 0b0100: res = x - y; break;
+ case 0b0100: res = u64(x) - y; break;
// 0b0101
- case 0b0110: res = y - x; break;
+ case 0b0110: res = u64(y) - x; break;
case 0b0111: res = ~x; break;
case 0b1000: res = x ^ y; break;
case 0b1001: res = shr(x, va, fo, 1, 1); break; // AL
@@ -150,40 +169,54 @@ void kl1839vm1_device::kop(u8 kop, u8 fd, u32 x, u32 y, u32 &z, u8 ps, bool va =
default: break; // 0b0001, 0b0101 - reserved
}
- switch(fd)
- {
- case 0b00:
- z = res;
- RSP |= BIT(res, 31) ? NF : 0;
- break;
- case 0b01:
- z = (z & 0xffff0000) | (res & 0x0000ffff);
- RSP |= BIT(res, 15) ? NF : 0;
- break;
- case 0b11:
- z = (z & 0xffffff00) | (res & 0x000000ff);
- RSP |= BIT(res, 7) ? NF : 0;
- break;
- default: RKA = res; break; // 0b10
- }
+ // flags
+ RSP &= ~(NF | ZF);
+ RSP |= BIT(res, 31) ? NF : 0;
RSP |= (res == 0) ? ZF : 0;
+ if (kop && ((kop & 0b1001) == 0b0000)) // +/-
+ {
+ const bool sig_y = BIT(y, 31);
+ const bool sig_x = BIT(x, 31);
+ RSP |= (kop == 0b0010) // +
+ ? (((sig_y == sig_x) && (BIT(res, 31) != sig_y)) ? VF : 0)
+ : (((sig_y != sig_x) && (BIT(res, 31) != ((kop == 0b0110) ? sig_y : sig_x))) ? VF : 0);
+ RSP |= (((kop & 0b1001) != 0b1001) && BIT(res, 32)) ? CF : 0;
+ }
switch (ps)
{
case 0b00: PSW = (PSW & ~0x0f) | (RSP & 0x0f); break;
- case 0b01: PSW = (PSW & ~0x0e) | (RSP & 0x0e); break;
- case 0b10: PSW = (PSW & ~0x0f) | (RSP & 0x0c); break;
+ case 0b01: PSW = (PSW & ~0x0f) | (RSP & 0x0c); break;
+ case 0b10: PSW = (PSW & ~0x0e) | (RSP & 0x0e); break;
default: break;
}
+
+ switch(fd)
+ {
+ case 0b11:
+ res &= 0x000000ff;
+ R(rz) &= 0xffffff00;
+ break;
+ case 0b01:
+ res &= 0x0000ffff;
+ R(rz) &= 0xffff0000;
+ break;
+ case 0b00:
+ default: // 0b10
+ R(rz) = 0;
+ break;
+ }
+ R(rz) |= res;
+ if (rz == 0x1f) mreg_w();
}
-void kl1839vm1_device::mreg_r()
+bool kl1839vm1_device::mreg_r()
{
- const u8 kob_tmp = BIT(m_vma_tmp.d, 24, 3);
- if (kob_tmp == 0b001)
+ const u8 kob = BIT(m_vma_tmp.d, 24, 3);
+ if ((kob & 0b101) == 0b001)
{
- const u8 no_tmp = BIT(m_vma_tmp.d, 30, 2);
- switch (no_tmp)
+ const u8 no = BIT(m_vma_tmp.d, 30, 2);
+ switch (no)
{
case 0b00:
BO = m_ram.read_dword(m_vma_tmp.d);
@@ -198,16 +231,20 @@ void kl1839vm1_device::mreg_r()
UNIMPLEMENTED("Read w/ catch BRA");
break;
}
+
+ return true;
}
+
+ return false;
}
void kl1839vm1_device::mreg_w()
{
- const u8 kob_tmp = BIT(m_vma_tmp.d, 24, 3);
- if (kob_tmp == 0b010)
+ const u8 kob = BIT(m_vma_tmp.d, 24, 3);
+ if ((kob & 0b110) == 0b010)
{
- const u8 no_tmp = BIT(m_vma_tmp.d, 30, 2);
- switch (no_tmp)
+ const u8 no = BIT(m_vma_tmp.d, 30, 2);
+ switch (no)
{
case 0b00:
m_ram.write_dword(m_vma_tmp.d, BO);
@@ -229,8 +266,8 @@ void kl1839vm1_device::ma(u32 op)
{
const u8 fd = BIT(op, 28, 2);
const u8 kop1 = BIT(op, 24, 4);
- const u8 am = BIT(op, 20, 4);
- const u8 x = BIT(op, 15, 5);
+ u8 am = BIT(op, 20, 4);
+ u8 x = BIT(op, 15, 5);
const u8 ps = BIT(op, 13, 2);
const bool va = BIT(op, 12);
const u8 no = BIT(op, 10, 2);
@@ -241,28 +278,55 @@ void kl1839vm1_device::ma(u32 op)
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- if (am==5 || am==8 || am>=0xd)
- UNIMPLEMENTED("Read regs with data mirror");
+ if (am>=0xd)
+ UNIMPLEMENTED("Read const with data mirror K>0x0d");
+ else if (am == 8)
+ UNIMPLEMENTED("Read const with data mirror K=8"); // CRM priveleges check
- if (po | py | px)
- UNIMPLEMENTED("MA: P*");
+ if (po)
+ UNIMPLEMENTED("MA: PO");
u32 kob_data = kop1 ? R(x) : K(am);
- kop(kop1, fd, R(x), K(am), R(x), ps, va, fo);
- if (pd || x == 0x1f) mreg_w();
+
+ if (!m_pcm_queue.empty())
+ {
+ if (py)
+ am = vax_pcm_pull();
+ else if (am == 5) // PCM
+ K(5) = vax_pcm_pull(1);
+ else if (pd && (am == 0x1f))
+ BO = vax_pcm_pull(1);
+ if (px)
+ x = vax_pcm_pull();
+ else if (pd && (x == 0x1f))
+ BO = vax_pcm_pull(1);
+ }
+ else if (pd)
+ {
+ mreg_r();
+ }
+
+ kop(kop1, fd, R(x), K(am), x, ps, va, fo);
if (va)
{
kob_data = R(x);
}
- kob_process(no, fo, kob, kob_data);
+ if (fd == 0b10)
+ {
+ RKA = m_sysram.read_dword(R(x));
+ }
+ else
+ {
+ kob_process(no, fo, kob, kob_data, R(x));
+ }
}
void kl1839vm1_device::mb(u32 op)
{
const u8 fd = BIT(op, 28, 2);
const u8 kop2 = BIT(op, 25, 3);
- const u8 y = BIT(op, 20, 5);
- const u8 x = BIT(op, 15, 5);
+ u8 y = BIT(op, 20, 5);
+ u8 x = BIT(op, 15, 5);
const u8 ps = BIT(op, 13, 2);
const bool va = BIT(op, 12);
const u8 no = BIT(op, 10, 2);
@@ -273,41 +337,70 @@ void kl1839vm1_device::mb(u32 op)
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- if (po | py | px)
- UNIMPLEMENTED("MB: P*");
+ if (po)
+ UNIMPLEMENTED("MB: PO");
u32 kob_data = kop2 ? R(x) : R(y);
- if (pd || y == 0x1f) mreg_r();
- kop(kop2 << 1, fd, R(x), R(y), R(x), ps, va, fo);
- if (pd || x == 0x1f) mreg_w();
+
+ if (!m_pcm_queue.empty())
+ {
+ if (py)
+ y = vax_pcm_pull();
+ else if (pd && !mreg_r() && (y == 0x1f))
+ BO = vax_pcm_pull(1);
+ if (px)
+ x = vax_pcm_pull();
+ else if (pd && (x == 0x1f))
+ BO = vax_pcm_pull(1);
+ }
+ else if (pd)
+ {
+ mreg_r();
+ }
+
+ kop(kop2 << 1, fd, R(x), R(y), x, ps, va, fo);
if (va)
{
kob_data = R(x);
}
- kob_process(no, fo, kob, kob_data);
+ kob_process(no, fo, kob, kob_data, R(x));
}
void kl1839vm1_device::mc(u32 op)
{
const u8 fd = BIT(op, 28, 2);
const u8 kop2 = BIT(op, 25, 3);
- const u8 y = BIT(op, 20, 5);
- const u8 x = BIT(op, 15, 5);
+ u8 y = BIT(op, 20, 5);
+ u8 x = BIT(op, 15, 5);
const u8 ps = BIT(op, 13, 2);
-
- const u8 z = BIT(op, 7, 5);
+ u8 z = BIT(op, 7, 5);
const bool pd = BIT(op, 4);
const bool pz = BIT(op, 3);
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- if (pz | py | px)
- UNIMPLEMENTED("MC: P*");
+ if (!m_pcm_queue.empty())
+ {
+ if (py)
+ y = vax_pcm_pull();
+ else if (pd && !mreg_r() && (y == 0x1f))
+ BO = vax_pcm_pull(1);
+ if (px)
+ x = vax_pcm_pull();
+ else if (pd && !mreg_r() && (x == 0x1f))
+ BO = vax_pcm_pull(1);
+ if (pz)
+ z = vax_pcm_pull();
+ else if (pd && (z == 0x1f))
+ BO = vax_pcm_pull(1);
+ }
+ else if (pd)
+ {
+ mreg_r();
+ }
- if (pd || x == 0x1f) mreg_r();
- kop(kop2 << 1, fd, R(x), kop2 ? R(y) : R(x), R(z), ps);
- if (pd || z == 0x1f) mreg_w();
+ kop(kop2 << 1, fd, R(x), kop2 ? R(y) : R(x), z, ps);
}
void kl1839vm1_device::mk(u32 op)
@@ -315,7 +408,7 @@ void kl1839vm1_device::mk(u32 op)
const bool ret = BIT(op, 17);
if (!ret)
{
- RV = MCA;
+ RV = AMC;
}
if ((op & 0xfe000000) == 0xe0000000)
@@ -323,19 +416,19 @@ void kl1839vm1_device::mk(u32 op)
if (BIT(~op, 16)) // madr == 0
{
const u16 addr = BIT(op, 2, 14);
- MCA = addr;
+ AMC = addr;
}
else
{
u16 addr_hi = BIT(op, 8, 8) << 6;
- MCA = addr_hi | (R(0x18) & 0x3f);
+ AMC = addr_hi | (R(0x18) & 0x3f);
}
}
else if ((op & 0xfe000000) == 0xe2000000)
{
u16 addr_hi = BIT(op, 8, 8) << 6;
//u8 rpp = BIT(op, 2, 4); // TODO rpp irq code
- MCA = addr_hi;
+ AMC = addr_hi;
}
}
@@ -347,7 +440,7 @@ void kl1839vm1_device::yp(u32 op)
const bool v = BIT(op, 25);
const bool c = BIT(op, 24);
const bool fp = BIT(op, 23);
- //const bool fpd = BIT(op, 22);
+ const bool fpd = BIT(op, 22);
//const bool prb = BIT(op, 21);
//const bool rst = BIT(op, 20);
//const bool rd = BIT(op, 19);
@@ -358,10 +451,16 @@ void kl1839vm1_device::yp(u32 op)
bool jump = false;
if (fp)
{
+ // Jump based on SRF flags
jump = uv == m_fp;
}
+ else if (fpd)
+ {
+ jump = true;
+ }
else
{
+ // zhs=1 - don't wait for the state completed
const u8 mask = (n << 3) | (z << 2) | (v << 1) | (c << 0);
const u8 reg = zhs ? RSP : PSW;
jump = uv ? ((reg & mask) != 0) : ((reg & mask) == 0);
@@ -371,49 +470,56 @@ void kl1839vm1_device::yp(u32 op)
{
if (!ret)
{
- RV = MCA;
+ RV = AMC;
}
- MCA = addr;
+ AMC = addr;
}
}
void kl1839vm1_device::zsch(u32 op)
{
- const bool madr = BIT(op, 16);
- if (madr)
+ if (m_jzdra_waiting)
{
- const u8 cnst_hi = BIT(op, 8, 2) << 6;
- SCH = cnst_hi | (R(0x18) & 0x3f);
+ SCH = R(0x19);
+ m_jzdra_waiting = false;
}
else
{
- const u8 cnst = BIT(op, 2, 8);
- SCH = cnst;
+ const bool madr = BIT(op, 16);
+ if (madr)
+ {
+ const u8 cnst_hi = BIT(op, 8, 2) << 6;
+ SCH = cnst_hi | (R(0x18) & 0x3f);
+ }
+ else
+ {
+ const u8 cnst = BIT(op, 2, 8);
+ SCH = cnst;
+ }
}
}
void kl1839vm1_device::psch(u32 op)
{
- const bool madr = BIT(op, 16);
- if (madr)
- {
- const u16 addr_hi = BIT(op, 8, 8) << 6;
- MCA = addr_hi | (R(0x18) & 0x3f);
- }
- else
+ if (SCH--)
{
- if (SCH--)
+ const bool madr = BIT(op, 16);
+ if (madr)
+ {
+ const u16 addr_hi = BIT(op, 8, 8) << 6;
+ AMC = addr_hi | (R(0x18) & 0x3f);
+ }
+ else
{
const u16 addr = BIT(op, 2, 14);
- MCA = addr;
+ AMC = addr;
}
-
}
}
void kl1839vm1_device::rts(u32 op)
{
- MCA = RV;
+ AMC = RV;
}
void kl1839vm1_device::acc(u32 op)
@@ -463,11 +569,10 @@ void kl1839vm1_device::srf(u32 op)
}
if (BIT(op, 4)) // OCT
{
- --MCA;
}
if (BIT(op, 2)) // JDZRA
{
- UNIMPLEMENTED("SRF: JDZRA");
+ m_jzdra_waiting = true;
}
if (BIT(op, 1)) // INC
{
@@ -479,23 +584,31 @@ void kl1839vm1_device::invalid(u32 op)
{
}
-void kl1839vm1_device::kob_process(u8 no, u8 fo, u8 kob, u32 data)
+void kl1839vm1_device::kob_process(u8 no, u8 fo, u8 kob, u32 kob_data, u32 data)
{
switch (kob) {
+ case 0b000: // NOP
+ break;
case 0b001: // Data Read
case 0b010: // Data Write
case 0b011: // Read-Modify-Write
- m_vma_tmp.d = (no << 30) | (fo << 28) | (kob << 24) | data;
+ m_vma_tmp.d = (no << 30) | (fo << 28) | (kob << 24) | kob_data;
break;
case 0b100: // Write Accum R(17)
+ R(0x17) = data;
+ break;
case 0b101: // Read Command
+ m_vma_tmp.d = 0;
+ PC = data;
+ break;
case 0b110: // Offset Write
UNIMPLEMENTED("KOB");
break;
- case 0b000: // NOP
case 0b111: // Reserve
- default: break;
+ default:
+ m_vma_tmp.d = 0;
+ break;
}
}
@@ -539,43 +652,289 @@ void kl1839vm1_device::decode_op(u32 op)
else if ((op & 0xfc000000) == 0xfc000000)
srf(op);
else
- invalid(op);
+ UNIMPLEMENTED(op);
}
}
+void kl1839vm1_device::vax_decode_pc()
+{
+ if (!m_pcm_queue.empty())
+ {
+ LOGVAX("Unused decoded data\n");
+ }
+ m_vma_tmp.d = 0;
+
+ const u8 op = m_ram.read_byte(PC);
+ m_op_size = 1;
+ AMC = op << 4;
+
+ m_pcm_queue.clear();
+ const vax_disassembler::mode* args = vax_disassembler::get_operands(op);
+ u8 arg_n = 0;
+ do
+ {
+ m_mem_reg[arg_n] = ~0; // Default to unknown
+
+ const vax_disassembler::mode mode = args[arg_n];
+ switch (mode)
+ {
+ case vax_disassembler::mode::none:
+ break;
+
+ // byte
+ case vax_disassembler::mode::bb:
+ m_pcm_queue.push_back(s8(m_ram.read_byte(PC + m_op_size)));
+ m_mem_reg[arg_n] = 0x8f;
+ m_op_size += 1;
+ break;
+
+ case vax_disassembler::mode::cntb:
+ case vax_disassembler::mode::mb:
+ case vax_disassembler::mode::urb:
+ case vax_disassembler::mode::srb:
+ case vax_disassembler::mode::wb:
+ {
+ u8 p = m_ram.read_byte(PC + m_op_size);
+ if (p == 0x8f) // M
+ {
+ m_pcm_queue.push_back(m_ram.read_byte(PC + m_op_size + 1));
+ m_mem_reg[arg_n] = p;
+ m_op_size += 2;
+ }
+ else if ((p & 0xf0) == 0x80) // M = R(n)+
+ {
+ m_pcm_queue.push_back(p & 0x0f);
+ m_mem_reg[arg_n] = p;
+ m_op_size += 1;
+ }
+ else if ((p & 0xf0) == 0x50) // R
+ {
+ m_pcm_queue.push_back(p & 0x0f);
+ m_mem_reg[arg_n] = p;
+ m_op_size += 1;
+ }
+ else // ?
+ {
+ LOGVAX("OP=%02x unknown prefix %02x in operand mode::%02d\n", op, p, u8(mode));
+ m_op_size = 0;
+ }
+ break;
+ }
+
+ // word
+ case vax_disassembler::mode::bw:
+ m_pcm_queue.push_back(s16(m_ram.read_word(PC + m_op_size)));
+ m_mem_reg[arg_n] = 0x8f;
+ m_op_size += 2;
+ break;
+
+ // dword
+ case vax_disassembler::mode::rl:
+ case vax_disassembler::mode::url:
+ case vax_disassembler::mode::ml:
+ case vax_disassembler::mode::prl:
+ case vax_disassembler::mode::srl:
+ case vax_disassembler::mode::wl:
+ {
+ u8 p = m_ram.read_byte(PC + m_op_size);
+ if (p == 0x8f) // M
+ {
+ m_pcm_queue.push_back(m_ram.read_dword(PC + m_op_size + 1));
+ m_mem_reg[arg_n] = p;
+ m_op_size += 5;
+ }
+ else if ((p & 0xf0) == 0x80) // M = R(n)+
+ {
+ m_pcm_queue.push_back(p & 0x0f);
+ m_mem_reg[arg_n] = p;
+ m_op_size += 1;
+ }
+ else if ((p & 0xf0) == 0x50) // R
+ {
+ m_pcm_queue.push_back(p & 0x0f);
+ m_mem_reg[arg_n] = p;
+ m_op_size += 1;
+ }
+ else // ?
+ {
+ LOGVAX("OP=%02x unknown prefix %02x in operand mode::%02d\n", op, p, u8(mode));
+ m_op_size = 0;
+ }
+ break;
+ }
+
+ default:
+ LOGVAX("(%x): unknown operand mode %02d in OP=%02x (n=%d)\n", PC, u8(mode), op, arg_n + 1);
+ m_pcm_queue.clear();
+ m_op_size = 0;
+ break;
+ }
+
+ ++arg_n;
+ } while ((arg_n < 6) && (args[arg_n] != vax_disassembler::mode::none));
+
+ if (m_op_size > 0) // above completed without failure
+ {
+ u8 args_type = 0;
+ if (!m_pcm_queue.empty())
+ {
+ for (u8 i = 0; i < arg_n; ++i)
+ {
+ args_type <<= 1;
+ if ((m_mem_reg[i] & 0xf0) == 0x80)
+ args_type |= 1;
+ else if ((m_mem_reg[i] & 0xf0) == 0x50)
+ args_type |= 0;
+ else
+ LOGVAX("Unknown argument type: %02x\n", m_mem_reg[i]);
+ }
+ }
+
+ switch (op)
+ {
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ assert(m_op_size == 1); // no operands
+ break;
+
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ case 0x30: case 0x31:
+ assert(arg_n == 1);
+ break;
+
+ case 0x94: case 0x95: case 0x96: case 0x97:
+ case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ assert(arg_n == 1);
+ AMC += 0x0c * args_type;
+ break;
+
+ case 0xda:
+ case 0xe8: case 0xe9:
+ assert(arg_n == 2);
+ break;
+
+ case 0xdb:
+ assert(arg_n == 2);
+ AMC += BIT(args_type, 0) ? 0x0 : 0x2;
+ break;
+
+ case 0x80: case 0x82: case 0x84: case 0x86: case 0x88: case 0x8a: case 0x8c:
+ case 0x90: case 0x92:
+ case 0xa0: case 0xa2: case 0xa4: case 0xa6: case 0xa8: case 0xaa: case 0xac:
+ case 0xb0: case 0xb2:
+ case 0xc0: case 0xc2: case 0xc4: case 0xc6: case 0xc8: case 0xca: case 0xcc:
+ case 0xd0: case 0xd2:
+ assert(arg_n == 2);
+ switch (args_type)
+ {
+ case 0b00: AMC += 0x0; break; // RR
+ case 0b01: AMC += 0x4; break; // RM
+ case 0b10: AMC += 0xe; break; // MR
+ case 0b11: AMC += 0xc; break; // MM
+ }
+ break;
+
+ case 0x91: case 0x93:
+ case 0xb1: case 0xb3:
+ case 0xd1: case 0xd3:
+ assert(arg_n == 2);
+ switch (args_type)
+ {
+ case 0b00: AMC += 0x0; break; // RR
+ case 0b01: AMC += 0x4; break; // RM
+ case 0b10:
+ case 0b11: AMC += 0xc; break; // MM, MR
+ }
+ break;
+
+ case 0x78:
+ assert(arg_n == 3);
+ AMC += BIT(args_type, 0) ? 0x0 : 0x2;
+ break;
+
+ case 0x81: case 0x83: case 0x85: case 0x87: case 0x89: case 0x8b: case 0x8d:
+ case 0xa1: case 0xa3: case 0xa5: case 0xa7: case 0xa9: case 0xab: case 0xad:
+ case 0xc1: case 0xc3: case 0xc5: case 0xc7: case 0xc9: case 0xcb: case 0xcd:
+ assert(arg_n == 3);
+ switch (args_type)
+ {
+ case 0b000: AMC += 0x0; break; // RRR
+ case 0b011: AMC += 0x4; break; // RMM
+ case 0b010: AMC += 0x6; break; // RMR
+ case 0b001: AMC += 0x8; break; // RRM
+ case 0b110: AMC += 0xe; break; // MMR
+ case 0b111: AMC += 0xc; break; // MMM
+ }
+ break;
+
+ default:
+ LOGVAX("(%x): OP=%02x with %d operands is not implemented or supported\n", PC, op, arg_n);
+ }
+ }
+
+ if (!m_op_size)
+ LOGVAX("(%x): undecoded OP=%02x .. EXIT\n", PC, op);
+ else
+ PC += m_op_size; // move to a next op
+ ;//LOGVAX("(%x): Decoded: OP=%02x args:%d \n", PC, op, m_pcm_queue.size());
+}
+
+u32 kl1839vm1_device::vax_pcm_pull(bool is_bo)
+{
+ if (m_pcm_queue.empty())
+ {
+ LOGVAX("Pooling empty decoder queue\n");
+ }
+ else
+ {
+ PCM = m_pcm_queue.front();
+ m_pcm_queue.pop_front();
+
+ bool is_mem = (m_mem_reg[0] & 0xf0) == 0x80;
+ if (is_bo && !is_mem)
+ {
+ PCM = R(PCM);
+ }
+ else if (is_mem && ((m_mem_reg[0] & 0x0f) != 0x0f))
+ {
+ u8 r = PCM;
+ PCM = R(PCM);
+ R(r) = PCM + 1;
+ }
+ std::copy(std::begin(m_mem_reg) + 1, std::end(m_mem_reg), std::begin(m_mem_reg));
+ }
+
+ return PCM;
+}
+
+
void kl1839vm1_device::device_start()
{
+ m_vax_dasm = std::make_unique<vax_disassembler>();
+
space(AS_OPCODES).cache(m_microcode);
space(AS_DATA).specific(m_sysram);
space(AS_PROGRAM).specific(m_ram);
space(AS_IO).specific(m_io);
- save_item(NAME(m_mca));
- save_item(NAME(m_vma));
save_item(NAME(m_vma_tmp));
save_item(NAME(m_rv));
save_item(NAME(m_sch));
save_item(NAME(m_rsp));
+ save_item(NAME(m_amc));
save_item(NAME(m_ppc));
save_item(NAME(m_fp));
save_pointer(NAME(m_reg), 0x20);
save_pointer(NAME(m_consts), 0x10);
// Register debugger state
- state_add(KL1839_MCA, "MCA", MCA).formatstr("%04X");
- state_add(KL1839_VMA, "VMA", VMA).formatstr("%08X");
- state_add_divider(-1);
- state_add(KL1839_IF, "cond", m_fp).formatstr("%08s");
- state_add(KL1839_RSP, "RSP", RSP).formatstr("%08s");
- state_add(KL1839_PCM, "PCM", PCM).formatstr("%08X");
- state_add(KL1839_RC, "RC", RC).formatstr("%08X");
- state_add(KL1839_RV, "RV", RV).formatstr("%08X");
- state_add(KL1839_SCH, "SCH", SCH).formatstr("%02X");
- state_add_divider(-1);
- state_add(VAX_AP, "AP", AP).formatstr("%08X");
- state_add(VAX_FP, "FP", FP).formatstr("%08X");
- state_add(VAX_SP, "SP", SP).formatstr("%08X");
- state_add(VAX_PC, "PC", PC).formatstr("%08X");
+ state_add(KL1839_AMC, "AMC", AMC).formatstr("%08X");
+ state_add(KL1839_PSW, "PSW", PSW).formatstr("%08s");
+ state_add(KL1839_IF, "cond", m_fp).formatstr("%08s");
+ state_add(KL1839_RC, "RC", RC).formatstr("%08X");
+ state_add(KL1839_RV, "RV", RV).formatstr("%08X");
+ state_add(KL1839_SCH, "SCH", SCH).formatstr("%02X");
state_add_divider(-1);
state_add(VAX_R0, "R0", R(0)).formatstr("%08X");
state_add(VAX_R1, "R1", R(1)).formatstr("%08X");
@@ -587,8 +946,15 @@ void kl1839vm1_device::device_start()
state_add(VAX_R7, "R7", R(7)).formatstr("%08X");
state_add(VAX_R8, "R8", R(8)).formatstr("%08X");
state_add(VAX_R9, "R9", R(9)).formatstr("%08X");
- state_add(VAX_RA, "RA", R(0x0a)).formatstr("%08X");
- state_add(VAX_RB, "RB", R(0x0b)).formatstr("%08X");
+ state_add(VAX_R10, "R10", R(10)).formatstr("%08X");
+ state_add(VAX_R11, "R11", R(11)).formatstr("%08X");
+ state_add_divider(-1);
+ state_add(VAX_AP, "AP", AP).formatstr("%08X");
+ state_add(VAX_FP, "FP", FP).formatstr("%08X");
+ state_add(VAX_SP, "SP", SP).formatstr("%08X");
+ state_add(VAX_PC, "PC", PC).formatstr("%08X");
+ state_add_divider(-1);
+ state_add(VAX_INST, "INST", PC).formatstr("%20s");
state_add_divider(-1);
state_add(VAX_AK0, "AK0", R(0x14)).formatstr("%08X");
state_add(VAX_AK1, "AK1", R(0x15)).formatstr("%08X");
@@ -605,9 +971,9 @@ void kl1839vm1_device::device_start()
state_add(VAX_PSL, "PSL", PSL).formatstr("%08X");
state_add(VAX_BO, "BO", BO).formatstr("%08X");
- state_add(STATE_GENPC, "GENPC", MCA).noshow(); // ???
- state_add(STATE_GENPCBASE, "CURPC", m_ppc.d).noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", PSW).formatstr("%8s").noshow();
+ state_add(STATE_GENPC, "GENPC", AMC).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_ppc.d).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", RSP).formatstr("%8s").noshow();
set_icountptr(m_icount);
}
@@ -618,18 +984,6 @@ void kl1839vm1_device::state_string_export(const device_state_entry &entry, std:
{
case STATE_GENFLAGS:
str = string_format("%c%c%c%c%c%c%c%c",
- PSW & 0x80 ? '?' : '.',
- PSW & 0x40 ? '?' : '.',
- PSW & 0x20 ? '?' : '.',
- PSW & 0x10 ? '?' : '.',
- PSW & NF ? 'N' : '.',
- PSW & ZF ? 'Z' : '.',
- PSW & VF ? 'V' : '.',
- PSW & CF ? 'C' : '.'
- );
- break;
- case KL1839_RSP:
- str = string_format("%c%c%c%c%c%c%c%c",
RSP & 0x80 ? '?' : '.',
RSP & 0x40 ? '?' : '.',
RSP & 0x20 ? '?' : '.',
@@ -640,9 +994,37 @@ void kl1839vm1_device::state_string_export(const device_state_entry &entry, std:
RSP & CF ? 'C' : '.'
);
break;
+ case KL1839_PSW:
+ str = string_format("%c%c%c%c%c%c%c%c",
+ PSW & 0x80 ? '?' : '.',
+ PSW & 0x40 ? '?' : '.',
+ PSW & 0x20 ? '?' : '.',
+ PSW & 0x10 ? '?' : '.',
+ PSW & NF ? 'N' : '.',
+ PSW & ZF ? 'Z' : '.',
+ PSW & VF ? 'V' : '.',
+ PSW & CF ? 'C' : '.'
+ );
+ break;
case KL1839_IF:
str = string_format("FP%d", m_fp);
break;
+ case VAX_INST:
+ if (m_op_size)
+ {
+ address_space &space_prg = space(AS_PROGRAM);
+ std::ostringstream buffer;
+ disasm_data_buffer databuf(space_prg);
+ m_vax_dasm->disassemble(buffer, PC - m_op_size, databuf, databuf);
+
+ const std::regex reg("\\s+");
+ str = regex_replace(buffer.str(), reg, " ");
+ }
+ else
+ {
+ str = "--------";
+ }
+ break;
}
}
@@ -651,13 +1033,15 @@ void kl1839vm1_device::device_reset()
for (auto &reg : m_reg)
reg.d = 0;
- m_ppc.d = MCA = 0x2000;
- VMA = 0;
+ m_ppc.d = AMC = 0x2000;
m_fp = false;
+ m_jzdra_waiting = false;
RSP = 0;
m_vma_tmp.d = 0;
RV = 0;
SCH = 0;
+ m_pcm_queue.clear();
+ m_op_size = 0;
}
void kl1839vm1_device::execute_set_input(int irqline, int state)
@@ -668,14 +1052,19 @@ void kl1839vm1_device::execute_run()
{
do
{
- m_ppc.d = MCA;
+ m_ppc.d = AMC;
debugger_instruction_hook(m_ppc.d);
- u32 op = m_microcode.read_dword(MCA);
+ u32 op = m_microcode.read_dword(AMC);
m_icount -= 2;
- ++MCA &= 0x3fff;
+ ++AMC &= 0x3fff;
decode_op(op);
+
+ if (op & 1) // S-bit
+ {
+ vax_decode_pc();
+ }
} while (m_icount > 0);
}
@@ -683,4 +1072,3 @@ std::unique_ptr<util::disasm_interface> kl1839vm1_device::create_disassembler()
{
return std::make_unique<kl1839vm1_disassembler>();
}
-
diff --git a/src/devices/cpu/mpk1839/kl1839vm1.h b/src/devices/cpu/mpk1839/kl1839vm1.h
index d04320cf838..4ee4d9eaeae 100644
--- a/src/devices/cpu/mpk1839/kl1839vm1.h
+++ b/src/devices/cpu/mpk1839/kl1839vm1.h
@@ -6,14 +6,15 @@
#pragma once
+#include <deque>
enum
{
- KL1839_MCA = STATE_GENPC, KL1839_VMA, KL1839_IF, KL1839_RSP, KL1839_PCM, KL1839_RC, KL1839_RV, KL1839_SCH,
- VAX_R0, VAX_R1, VAX_R2, VAX_R3, VAX_R4, VAX_R5, VAX_R6, VAX_R7, VAX_R8, VAX_R9, VAX_RA, VAX_RB,
+ KL1839_AMC = STATE_GENPC, KL1839_IF, KL1839_PSW, KL1839_RC, KL1839_RV, KL1839_SCH,
+ VAX_R0, VAX_R1, VAX_R2, VAX_R3, VAX_R4, VAX_R5, VAX_R6, VAX_R7, VAX_R8, VAX_R9, VAX_R10, VAX_R11,
VAX_AP, VAX_FP, VAX_SP, VAX_PC,
VAX_AK0, VAX_AK1, VAX_AK2, VAX_AK3, VAX_AK4, VAX_AK5, VAX_AK6, VAX_AK7, VAX_AK8,
- VAX_RNK, VAX_RKA, VAX_PSL, VAX_BO
+ VAX_RNK, VAX_RKA, VAX_PSL, VAX_BO, VAX_INST
};
@@ -43,6 +44,22 @@ protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
+ class disasm_data_buffer : public util::disasm_interface::data_buffer
+ {
+ public:
+ disasm_data_buffer(address_space &space) : m_space(space)
+ {
+ }
+
+ virtual u8 r8(offs_t pc) const override { return m_space.read_byte(pc); }
+ virtual u16 r16(offs_t pc) const override { return m_space.read_word(pc); }
+ virtual u32 r32(offs_t pc) const override { return m_space.read_dword(pc); }
+ virtual u64 r64(offs_t pc) const override { return m_space.read_qword(pc); }
+
+ private:
+ address_space &m_space;
+ };
+
void flag(u32 op);
void rest(u32 op);
void ma(u32 op);
@@ -60,12 +77,15 @@ private:
void invalid(u32 op);
u32 shr(u32 val, bool va, u8 fo, bool a_c, bool l_r);
- void kob_process(u8 no, u8 fd, u8 kob, u32 data);
- void kop(u8 kop, u8 fd, u32 x, u32 y, u32 &z, u8 ps, bool va, u8 fo);
+ void kob_process(u8 no, u8 fd, u8 kob, u32 kob_data, u32 data);
+ void kop(u8 kop, u8 fd, u32 x, u32 y, u8 rz, u8 ps, bool va, u8 fo);
void mreg_w();
- void mreg_r();
+ bool mreg_r();
void decode_op(u32 op);
+ void vax_decode_pc();
+ u32 vax_pcm_pull(bool is_bo = 0);
+
address_space_config m_microcode_config;
address_space_config m_sysram_config;
address_space_config m_ram_config;
@@ -75,17 +95,24 @@ private:
memory_access<24, 0, 0, ENDIANNESS_BIG>::specific m_sysram;
memory_access<24, 0, 0, ENDIANNESS_LITTLE>::specific m_ram;
memory_access<6, 2, -2, ENDIANNESS_LITTLE>::specific m_io;
- PAIR m_mca;
- PAIR m_vma;
- PAIR m_vma_tmp; // does we have int reg for this?
- PAIR m_rv;
- PAIR m_sch;
- PAIR m_rsp;
- PAIR m_ppc; // previous program counter
- bool m_fp;
- u32 m_consts[0x10] = { 0x4, 0x2, 0x8, 0x1, 0x0, 0, 0, 0x66, 0, 0xc00000, 0xffffffff, 0x1f0000, 0x4000000, 0, 0, 0 };
- PAIR m_reg[0x20];
- int m_icount;
+
+ std::unique_ptr<util::disasm_interface> m_vax_dasm;
+
+ PAIR m_vma_tmp; // do we have int reg for this?
+ PAIR m_rv;
+ PAIR m_sch;
+ PAIR m_rsp;
+ PAIR m_amc; // Microdode PC
+ PAIR m_ppc; // previous program counter
+ bool m_fp;
+ bool m_jzdra_waiting;
+ u32 m_consts[0x10] = { 0x4, 0x2, 0x8, 0x1, 0x0, 0, 0, 0x66, 0, 0xc00000, 0xffffffff, 0x1f0000, 0x4000000, 0, 0, 0 };
+ PAIR m_reg[0x20];
+ int m_icount;
+ u32 m_op_size;
+
+ std::deque<u32> m_pcm_queue;
+ u8 m_mem_reg[6];
};
DECLARE_DEVICE_TYPE(KL1839VM1, kl1839vm1_device)
diff --git a/src/devices/cpu/mpk1839/kl1839vm1dasm.cpp b/src/devices/cpu/mpk1839/kl1839vm1dasm.cpp
index 1b9ad4e7dc1..ea80d7a0613 100644
--- a/src/devices/cpu/mpk1839/kl1839vm1dasm.cpp
+++ b/src/devices/cpu/mpk1839/kl1839vm1dasm.cpp
@@ -12,6 +12,7 @@ static const std::string r_name(u8 id)
std::ostringstream ss;
switch (id)
{
+ case 0x0f: ss << "PC"; break;
case 0x14: ss << "AK0"; break;
case 0x15: ss << "AK1"; break;
case 0x16: ss << "AK2"; break;
@@ -98,7 +99,7 @@ static const void ma(std::ostream &stream, u32 op)
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- m_base(stream, op, 'A', kop1, r_name(x), k_name(am), r_name(x));
+ m_base(stream, op, 'A', kop1, px ? "RX" : r_name(x), py ? "RY" : k_name(am), px ? "RX" : r_name(x));
if (kob)
{
@@ -128,7 +129,7 @@ static const void ma(std::ostream &stream, u32 op)
case 0b001: stream << "4D "; break;
case 0b010: stream << "ZD "; break;
case 0b011: stream << "4Z "; break;
- case 0b100: stream << "?R(17)==ACC "; break;
+ case 0b100: stream << "WDAK "; break;
case 0b101: stream << "4K "; break;
case 0b110: break; // reserved
case 0b111: stream << "BRD "; break;
@@ -136,8 +137,8 @@ static const void ma(std::ostream &stream, u32 op)
}
}
- if (px | po | py)
- stream << "?:" << (px ? "PX " : "") << (po ? "PO " : "") << (py ? "PY " : "");
+ if (po)
+ stream << "?:" << (po ? "RO" : "");
}
static const void mb(std::ostream &stream, u32 op)
@@ -150,11 +151,11 @@ static const void mb(std::ostream &stream, u32 op)
const u8 no = BIT(op, 10, 2);
const u8 fo = BIT(op, 8, 2);
const u8 kob = BIT(op, 5, 3);
- const bool pz = BIT(op, 3);
+ const bool po = BIT(op, 3);
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- m_base(stream, op, 'B', kop2 << 1, r_name(x), r_name(y), r_name(x));
+ m_base(stream, op, 'B', kop2 << 1, px ? "RX" : r_name(x), py ? "RY" : r_name(y), px ? "RX" : r_name(x));
if (kob)
{
@@ -192,7 +193,7 @@ static const void mb(std::ostream &stream, u32 op)
case 0b001: stream << "4D "; break;
case 0b010: stream << "ZD "; break;
case 0b011: stream << "4Z "; break;
- case 0b100: stream << "?R(17)==ACC "; break;
+ case 0b100: stream << "WDAK "; break;
case 0b101: stream << "4K "; break;
case 0b110: break; // reserved
case 0b111: stream << "BRD "; break;
@@ -200,8 +201,8 @@ static const void mb(std::ostream &stream, u32 op)
}
}
- if (px | pz | py)
- stream << "?:" << (px ? "PX " : "") << (pz ? "PZ " : "") << (py ? "PY " : "");
+ if (po)
+ stream << "?:" << (po ? "RO" : "");
}
static const void mc(std::ostream &stream, u32 op)
@@ -214,10 +215,7 @@ static const void mc(std::ostream &stream, u32 op)
const bool py = BIT(op, 2);
const bool px = BIT(op, 1);
- m_base(stream, op, 'C', kop2 << 1, r_name(x), kop2 ? r_name(y) : r_name(x), r_name(z));
-
- if (px | pz | py)
- stream << "?:" << (px ? "PX " : "") << (pz ? "PZ " : "") << (py ? "PY " : "");
+ m_base(stream, op, 'C', kop2 << 1, px ? "RX" : r_name(x), kop2 ? (py ? "RY" : r_name(y)) : (px ? "RX" : r_name(x)), pz ? "RZ" : r_name(z));
}
static const u32 mk(std::ostream &stream, u32 op)
@@ -228,11 +226,12 @@ static const u32 mk(std::ostream &stream, u32 op)
if (BIT(~op, 16)) // madr == 0
{
const u16 addr = BIT(op, 2, 14);
- util::stream_format(stream, "BP%s : ;A=%04X", ret ? " " : "B" ,addr);
+ util::stream_format(stream, "BP%s : ;A=(%04X)", ret ? " " : "B" , addr);
}
else
{
- stream << "??MK-2";
+ u16 addr_hi = BIT(op, 8, 8) << 6;
+ util::stream_format(stream, "BPV%s : ;A=(%04X+%s)", ret ? " " : "D" , addr_hi, r_name(0x18));
}
}
else if ((op & 0xfe000000) == 0xe2000000)
@@ -437,5 +436,10 @@ offs_t kl1839vm1_disassembler::disassemble(std::ostream &stream, offs_t pc, cons
stream << "<invalid>";
}
+ if (op & 1)
+ {
+ stream << "S";
+ }
+
return 1 | SUPPORTED | step;
}
diff --git a/src/devices/cpu/vax/vaxdasm.cpp b/src/devices/cpu/vax/vaxdasm.cpp
index 423f5746ebc..229d3972fda 100644
--- a/src/devices/cpu/vax/vaxdasm.cpp
+++ b/src/devices/cpu/vax/vaxdasm.cpp
@@ -23,37 +23,11 @@ u32 vax_disassembler::opcode_alignment() const
return 1;
}
-enum class vax_disassembler::mode : u8
-{
- none,
- rb, srb, urb, cntb, rw, srw, urw, mskw, rl, srl, url, posl, prl, rq, srq, urq, ro, uro,
- mb, mw, ml, mq, mo,
- wb, ww, wl, wq, wo,
- ab, aw, al, aq, ao,
- bb, bw,
- vb
-};
-
namespace {
using namespace std::literals;
using mode = vax_disassembler::mode;
-static constexpr bool is_read_mode(mode m)
-{
- switch (m)
- {
- case mode::rb: case mode::srb: case mode::urb: case mode::cntb:
- case mode::rw: case mode::srw: case mode::urw: case mode::mskw:
- case mode::rl: case mode::srl: case mode::url: case mode::posl: case mode::prl:
- case mode::rq: case mode::urq:
- case mode::ro: case mode::uro:
- return true;
- default:
- return false;
- }
-}
-
static constexpr bool is_address_mode(mode m)
{
return m == mode::ab || m == mode::aw || m == mode::al || m == mode::aq || m == mode::ao;
@@ -1119,3 +1093,23 @@ offs_t vax_disassembler::disassemble(std::ostream &stream, offs_t pc, const vax_
else
return disassemble_inst(stream, s_nonprefix_ops[op], pc, ppc, opcodes);
}
+
+bool vax_disassembler::is_read_mode(vax_disassembler::mode m)
+{
+ switch (m)
+ {
+ case mode::rb: case mode::srb: case mode::urb: case mode::cntb:
+ case mode::rw: case mode::srw: case mode::urw: case mode::mskw:
+ case mode::rl: case mode::srl: case mode::url: case mode::posl: case mode::prl:
+ case mode::rq: case mode::urq:
+ case mode::ro: case mode::uro:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const vax_disassembler::mode* vax_disassembler::get_operands(u8 op)
+{
+ return s_nonprefix_ops[op].operand;
+}
diff --git a/src/devices/cpu/vax/vaxdasm.h b/src/devices/cpu/vax/vaxdasm.h
index e5549d4d59f..e12657daab9 100644
--- a/src/devices/cpu/vax/vaxdasm.h
+++ b/src/devices/cpu/vax/vaxdasm.h
@@ -9,7 +9,16 @@
class vax_disassembler : public util::disasm_interface
{
public:
- enum class mode : u8;
+ enum class mode : u8
+ {
+ none,
+ rb, srb, urb, cntb, rw, srw, urw, mskw, rl, srl, url, posl, prl, rq, srq, urq, ro, uro,
+ mb, mw, ml, mq, mo,
+ wb, ww, wl, wq, wo,
+ ab, aw, al, aq, ao,
+ bb, bw,
+ vb
+ };
struct opdef
{
@@ -21,6 +30,9 @@ public:
// construction/destruction
vax_disassembler();
+ static bool is_read_mode(mode m);
+ static const mode* get_operands(u8 op);
+
protected:
// disassembler overrides
virtual u32 opcode_alignment() const override;