summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author shattered <shattered@users.noreply.github.com>2025-10-22 12:19:20 +0300
committer GitHub <noreply@github.com>2025-10-22 11:19:20 +0200
commitedbffa754e94bdb35f747ee073fe2c1d886d2de4 (patch)
tree2e6fcc734428a47e12430adee165eff2fa3b366a
parentfa976f57527ffe5387aabf2d69c176c9b13014ff (diff)
t11: add interrupt processing and EIS instructions to K1801VM2 core. (#14325)
-rw-r--r--src/devices/cpu/t11/t11.cpp95
-rw-r--r--src/devices/cpu/t11/t11.h40
-rw-r--r--src/devices/cpu/t11/t11dasm.cpp20
-rw-r--r--src/devices/cpu/t11/t11ops.hxx245
-rw-r--r--src/devices/cpu/t11/t11table.hxx64
-rw-r--r--src/mame/ussr/dvk_kcgd.cpp1
6 files changed, 424 insertions, 41 deletions
diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp
index cc57c1b521b..73870745082 100644
--- a/src/devices/cpu/t11/t11.cpp
+++ b/src/devices/cpu/t11/t11.cpp
@@ -51,7 +51,7 @@ lsi11_device::lsi11_device(const machine_config &mconfig, const char *tag, devic
: t11_device(mconfig, LSI11, tag, owner, clock)
, z80_daisy_chain_interface(mconfig, *this)
{
- c_insn_set = IS_LEIS | IS_MXPS; // EISFIS is an option
+ c_insn_set = IS_LEIS | IS_EIS | IS_MXPS; // EISFIS is an option
}
/*
@@ -69,6 +69,12 @@ k1801vm1_device::k1801vm1_device(const machine_config &mconfig, const char *tag,
c_insn_set = IS_LEIS | IS_MXPS | IS_VM1;
}
+/*
+ * Not implemented:
+ *
+ * instruction timing (+ memory timing), bug compatibility (@PC addressing mode),
+ * HALT mode, traps: double bus error and bus error on vector fetch.
+ */
k1801vm2_device::k1801vm2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: t11_device(mconfig, K1801VM2, tag, owner, clock)
, z80_daisy_chain_interface(mconfig, *this)
@@ -391,7 +397,7 @@ void k1801vm1_device::t11_check_irqs()
// 8. external HALT (nIRQ1 pin, level triggered); PSW11, PSW10
else if (m_hlt_active)
{
- m_hlt_active = 0;
+ m_hlt_active = false;
mcir = MCIR_HALT;
vsel = VM1_HALT;
}
@@ -532,6 +538,88 @@ void t11_device::take_interrupt(uint8_t vector)
m_wait_state = 0;
}
+// priorities from technical manual, pp. 152, 154
+void k1801vm2_device::t11_check_irqs()
+{
+ int8_t mcir = MCIR_NONE;
+ uint16_t vsel = 0;
+
+ if (m_mcir != MCIR_NONE)
+ {
+ mcir = m_mcir;
+ vsel = m_vsel;
+ }
+ // 1. bus error; nm
+ else if (m_bus_error)
+ {
+ m_bus_error = false;
+ mcir = MCIR_IRQ;
+ vsel = T11_TIMEOUT;
+ }
+ // 2. illegal insn; nm
+ else if (m_mcir == MCIR_ILL)
+ {
+ take_interrupt(vsel);
+ }
+ // 3. trace trap; WCPU
+ else if (m_trace_trap)
+ {
+ if (GET_T)
+ {
+ mcir = MCIR_IRQ;
+ vsel = T11_BPT;
+ }
+ else
+ m_trace_trap = false;
+ }
+ else if (GET_T)
+ {
+ m_trace_trap = true;
+ }
+ // 4. power fail; PSW7, PSW8
+ else if (m_power_fail)
+ {
+ m_power_fail = false;
+ mcir = MCIR_IRQ;
+ vsel = T11_PWRFAIL;
+ }
+ // 5. external HALT (nHALT pin); PSW8
+ else if (m_hlt_active)
+ {
+ m_hlt_active = false;
+ mcir = MCIR_HALT;
+ vsel = VM2_HALT;
+ }
+ // 6. line clock (nEVNT pin, edge triggered); PSW7
+ else if (m_cp[2] && !GET_I)
+ {
+ m_cp[2] = false;
+ mcir = MCIR_IRQ;
+ vsel = VM1_EVNT;
+ }
+ // 7. nVIRQ pin; PSW7
+ else if (m_vec_active && !GET_I)
+ {
+ device_z80daisy_interface *intf = daisy_get_irq_device();
+ int vec = (intf != nullptr) ? intf->z80daisy_irq_ack() : m_in_iack_func(0);
+ if (vec == -1 || vec == 0)
+ {
+ m_vec_active = 0;
+ return;
+ }
+ mcir = MCIR_IRQ;
+ vsel = vec;
+ }
+
+ switch (mcir)
+ {
+ case MCIR_IRQ:
+ take_interrupt(vsel);
+ break;
+ }
+
+ m_mcir = MCIR_NONE;
+}
/*************************************
@@ -708,6 +796,9 @@ void k1801vm2_device::device_reset()
PC = RWORD(c_initial_mode);
PSW = RWORD(c_initial_mode+2);
+
+ m_mcir = MCIR_NONE;
+ m_vsel = 0;
}
diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h
index ab3b6b8e855..639e1849f19 100644
--- a/src/devices/cpu/t11/t11.h
+++ b/src/devices/cpu/t11/t11.h
@@ -683,6 +683,38 @@ protected:
void add_ixd_ded(uint16_t op);
void add_ixd_ix(uint16_t op);
void add_ixd_ixd(uint16_t op);
+ void ash_rg(uint16_t op);
+ void ash_rgd(uint16_t op);
+ void ash_in(uint16_t op);
+ void ash_ind(uint16_t op);
+ void ash_de(uint16_t op);
+ void ash_ded(uint16_t op);
+ void ash_ix(uint16_t op);
+ void ash_ixd(uint16_t op);
+ void ashc_rg(uint16_t op);
+ void ashc_rgd(uint16_t op);
+ void ashc_in(uint16_t op);
+ void ashc_ind(uint16_t op);
+ void ashc_de(uint16_t op);
+ void ashc_ded(uint16_t op);
+ void ashc_ix(uint16_t op);
+ void ashc_ixd(uint16_t op);
+ void mul_rg(uint16_t op);
+ void mul_rgd(uint16_t op);
+ void mul_in(uint16_t op);
+ void mul_ind(uint16_t op);
+ void mul_de(uint16_t op);
+ void mul_ded(uint16_t op);
+ void mul_ix(uint16_t op);
+ void mul_ixd(uint16_t op);
+ void div_rg(uint16_t op);
+ void div_rgd(uint16_t op);
+ void div_in(uint16_t op);
+ void div_ind(uint16_t op);
+ void div_de(uint16_t op);
+ void div_ded(uint16_t op);
+ void div_ix(uint16_t op);
+ void div_ixd(uint16_t op);
void xor_rg(uint16_t op);
void xor_rgd(uint16_t op);
void xor_in(uint16_t op);
@@ -1198,6 +1230,12 @@ protected:
void sub_ixd_ded(uint16_t op);
void sub_ixd_ix(uint16_t op);
void sub_ixd_ixd(uint16_t op);
+
+ // SIMH code
+ int _ash(int source, int dest, int *psw);
+ int _ashc(int source, int source1, int dest, int *psw);
+ int _mul(int source, int dest, int *psw);
+ int _div(int source, int source1, int dest, int *remainder, int *psw);
};
class lsi11_device : public t11_device, public z80_daisy_chain_interface
@@ -1240,6 +1278,8 @@ protected:
// device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+
+ virtual void t11_check_irqs() override;
};
diff --git a/src/devices/cpu/t11/t11dasm.cpp b/src/devices/cpu/t11/t11dasm.cpp
index 519916c1a2b..fdbe23ab8c3 100644
--- a/src/devices/cpu/t11/t11dasm.cpp
+++ b/src/devices/cpu/t11/t11dasm.cpp
@@ -269,6 +269,10 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data
util::stream_format(stream, "ASL %s", ea1);
break;
// 0064xx: MARK (not implemented on T-11)
+ case 0006400:
+ ea1 = MakeEA<false> (lo, pc, opcodes);
+ util::stream_format(stream, "MARK %s", ea1);
+ break;
// 0065xx: MFPI (not implemented on T-11)
// 0066xx: MTPI (not implemented on T-11)
case 0006700:
@@ -353,9 +357,25 @@ offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data
break;
// 070xxx: MUL (not implemented on T-11)
+ case 0070000: case 0070100: case 0070200: case 0070300: case 0070400: case 0070500: case 0070600: case 0070700:
+ ea1 = MakeEA<false> (lo, pc, opcodes);
+ util::stream_format(stream, "MUL %s,%s", ea1, regs[hi & 7]);
+ break;
// 071xxx: DIV (not implemented on T-11)
+ case 0071000: case 0071100: case 0071200: case 0071300: case 0071400: case 0071500: case 0071600: case 0071700:
+ ea1 = MakeEA<false> (lo, pc, opcodes);
+ util::stream_format(stream, "DIV %s,%s", ea1, regs[hi & 7]);
+ break;
// 072xxx: ASH (not implemented on T-11)
+ case 0072000: case 0072100: case 0072200: case 0072300: case 0072400: case 0072500: case 0072600: case 0072700:
+ ea1 = MakeEA<false> (lo, pc, opcodes);
+ util::stream_format(stream, "ASH %s,%s", ea1, regs[hi & 7]);
+ break;
// 073xxx: ASHC (not implemented on T-11)
+ case 0073000: case 0073100: case 0073200: case 0073300: case 0073400: case 0073500: case 0073600: case 0073700:
+ ea1 = MakeEA<false> (lo, pc, opcodes);
+ util::stream_format(stream, "ASHC %s,%s", ea1, regs[hi & 7]);
+ break;
case 0074000: case 0074100: case 0074200: case 0074300: case 0074400: case 0074500: case 0074600: case 0074700:
ea1 = MakeEA<false> (lo, pc, opcodes);
util::stream_format(stream, "XOR %s,%s", regs[hi & 7], ea1);
diff --git a/src/devices/cpu/t11/t11ops.hxx b/src/devices/cpu/t11/t11ops.hxx
index 90c0a4121f3..1aeaace16dd 100644
--- a/src/devices/cpu/t11/t11ops.hxx
+++ b/src/devices/cpu/t11/t11ops.hxx
@@ -33,6 +33,7 @@
/* extracts the source/destination register index from the opcode into 'sreg' or 'dreg' */
#define GET_SREG sreg = (op >> 6) & 7
#define GET_DREG dreg = op & 7
+#define EIS_SWAP op = ((op & 7) << 6) | ((op >> 6) & 7)
/* for a byte-sized source operand: extracts 'sreg', computes 'ea', and loads the value into 'source' */
#define GET_SB_RG GET_SREG; source = REGB(sreg)
@@ -144,6 +145,11 @@
#define SETW_NZV SETW_N; SETW_Z; SETW_V
#define SETW_NZVC SETW_N; SETW_Z; SETW_V; SETW_C
+/* SIMH */
+#define GET_ZERO(v) ((v) == 0)
+#define GET_SIGN_W(v) (((v) >> 15) & 1)
+#define GET_SIGN_B(v) (((v) >> 7) & 1)
+
/* operations */
/* ADC: dst += C */
#define ADC_R(d) int dreg, source, dest, result; source = GET_C; GET_DW_##d; CLR_NZVC; result = dest + source; SETW_NZVC; PUT_DW_DREG(result)
@@ -187,9 +193,9 @@
#define BR(c) if (c) { PC += 2 * (signed char)(op & 0xff); }
/* CLR: dst = 0 */
#define CLR_R(d) int dreg; PUT_DW_##d(0); CLR_NZVC; SET_Z
-#define CLR_M(d) int dreg, ea; PUT_DWT_##d(0); CLR_NZVC; SET_Z
+#define CLR_M(d) int dreg, ea; if (c_insn_set & (IS_T11|IS_VM1)) { PUT_DWT_##d(0); } else { PUT_DW_##d(0); } CLR_NZVC; SET_Z
#define CLRB_R(d) int dreg; PUT_DB_##d(0); CLR_NZVC; SET_Z
-#define CLRB_M(d) int dreg, ea; PUT_DBT_##d(0); CLR_NZVC; SET_Z
+#define CLRB_M(d) int dreg, ea; if (c_insn_set & (IS_T11|IS_VM1|IS_VM2)) { PUT_DBT_##d(0); } else { PUT_DB_##d(0); } CLR_NZVC; SET_Z
/* CMP: flags = src - dst */
#define CMP_R(s,d) int sreg, dreg, source, dest, result; GET_SW_##s; GET_DW_##d; CLR_NZVC; result = source - dest; SETW_NZVC;
#define CMP_M(s,d) int sreg, dreg, source, dest, result, ea; GET_SW_##s; GET_DW_##d; CLR_NZVC; result = source - dest; SETW_NZVC;
@@ -216,13 +222,13 @@
#define JSR(d) int sreg, dreg, ea; GET_SREG; GET_DREG; MAKE_EAW_##d(dreg); PUSH(REGW(sreg)); REGW(sreg) = PC; PC = ea
/* MFPS: dst = flags */
#define MFPS_R(d) int dreg, result; result = PSW; CLR_NZV; SETB_NZ; PUT_DW_##d((signed char)result)
-#define MFPS_M(d) int dreg, result, ea; result = PSW; CLR_NZV; SETB_NZ; PUT_DB_##d(result)
+#define MFPS_M(d) int dreg, result, ea; result = PSW; CLR_NZV; SETB_NZ; if (c_insn_set & (IS_VM1|IS_VM2)) { PUT_DBT_##d(result); } else { PUT_DB_##d(result); }
/* MOV: dst = src */
#define MOV_R(s,d) int sreg, dreg, source, result; GET_SW_##s; CLR_NZV; result = source; SETW_NZ; PUT_DW_##d(result)
-#define MOV_M(s,d) int sreg, dreg, source, result, ea; GET_SW_##s; CLR_NZV; result = source; SETW_NZ; if (c_insn_set & IS_VM1) { PUT_DW_##d(result); } else { PUT_DWT_##d(result); }
+#define MOV_M(s,d) int sreg, dreg, source, result, ea; GET_SW_##s; CLR_NZV; result = source; SETW_NZ; if (c_insn_set & IS_T11) { PUT_DWT_##d(result); } else { PUT_DW_##d(result); }
#define MOVB_R(s,d) int sreg, dreg, source, result; GET_SB_##s; CLR_NZV; result = source; SETB_NZ; PUT_DW_##d((signed char)result)
#define MOVB_X(s,d) int sreg, dreg, source, result, ea; GET_SB_##s; CLR_NZV; result = source; SETB_NZ; PUT_DW_##d((signed char)result)
-#define MOVB_M(s,d) int sreg, dreg, source, result, ea; GET_SB_##s; CLR_NZV; result = source; SETB_NZ; if (c_insn_set & IS_VM1) { PUT_DB_##d(result); } else { PUT_DBT_##d(result); }
+#define MOVB_M(s,d) int sreg, dreg, source, result, ea; GET_SB_##s; CLR_NZV; result = source; SETB_NZ; if (c_insn_set & (IS_T11|IS_VM2)) { PUT_DBT_##d(result); } else { PUT_DB_##d(result); }
/* MTPS: flags = src */
#define MTPS_R(d) int dreg, dest; GET_DB_##d; PSW = (PSW & ~0xef) | (dest & 0xef); m_check_irqs = true
#define MTPS_M(d) int dreg, dest, ea; GET_DB_##d; PSW = (PSW & ~0xef) | (dest & 0xef); m_check_irqs = true
@@ -258,7 +264,7 @@
#define SWAB_M(d) int dreg, dest, result, ea; GET_DW_##d; CLR_NZVC; result = ((dest >> 8) & 0xff) + (dest << 8); SETB_NZ; PUT_DW_EA(result)
/* SXT: dst = sign-extend dst */
#define SXT_R(d) int dreg, result; CLR_ZV; if (GET_N) result = -1; else { result = 0; SET_Z; } PUT_DW_##d(result)
-#define SXT_M(d) int dreg, result, ea; CLR_ZV; if (GET_N) result = -1; else { result = 0; SET_Z; } PUT_DWT_##d(result)
+#define SXT_M(d) int dreg, result, ea; CLR_ZV; if (GET_N) result = -1; else { result = 0; SET_Z; } if (c_insn_set & (IS_T11|IS_VM1)) { PUT_DWT_##d(result); } else { PUT_DW_##d(result); }
/* TST: dst = ~dst */
#define TST_R(d) int dreg, dest, result; GET_DW_##d; CLR_NZVC; result = dest; SETW_NZ;
#define TST_M(d) int dreg, dest, result, ea; GET_DW_##d; CLR_NZVC; result = dest; SETW_NZ;
@@ -271,6 +277,191 @@
/* test if insn is supported by the CPU */
#define CHECK_IS(d) do { if (!(c_insn_set & (d))) { illegal(op); return; } } while (false)
+/* Extended Instruction Set -- SIMH impl */
+
+int t11_device::_mul(int src, int src2, int *psw) {
+ int dst;
+ int N, Z, V, C;
+
+ if (GET_SIGN_W (src2))
+ src2 = src2 | ~077777;
+ if (GET_SIGN_W (src))
+ src = src | ~077777;
+ dst = src * src2;
+ N = (dst < 0);
+ Z = GET_ZERO (dst);
+ V = 0;
+ C = ((dst > 077777) || (dst < -0100000));
+ *psw = (*psw & ~15) | ((N&1) << 3) | ((Z&1) << 2) | ((V&1) << 1) | (C&1);
+
+ return dst;
+}
+
+#define MUL_M(s) \
+int sreg, dreg, source, dest, result, ea = 0, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _mul(dest, source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result >> 16); REGW(dreg|1) = result
+
+#define MUL_R(s) \
+int sreg, dreg, source, dest, result, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _mul(dest, source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result >> 16); REGW(dreg|1) = result
+
+int t11_device::_div(int source, int source1, int src2, int *remainder, int *psw) {
+ int src, dst = 0;
+ int N, Z, V, C;
+
+ src = (((uint32_t) source) << 16) | source1;
+ if (src2 == 0) {
+ N = 0; /* J11,11/70 compat */
+ Z = V = C = 1; /* N = 0, Z = 1 */
+ if (c_insn_set & IS_VM2) Z = 0;
+ } else if ((((uint32_t)src) == 020000000000) && (src2 == 0177777)) {
+ V = 1; /* J11,11/70 compat */
+ N = Z = C = 0; /* N = Z = 0 */
+ } else {
+ if (GET_SIGN_W (src2))
+ src2 = src2 | ~077777;
+ if (GET_SIGN_W (source))
+ src = src | ~017777777777;
+ dst = src / src2;
+ N = (dst < 0); /* N set on 32b result */
+ if ((dst > 077777) || (dst < -0100000)) {
+ V = 1; /* J11,11/70 compat */
+ Z = C = 0; /* Z = C = 0 */
+ if (c_insn_set & IS_VM2) N = 0;
+ } else {
+ Z = GET_ZERO (dst);
+ V = C = 0;
+ }
+ *remainder = (src - (src2 * dst)) & 0177777;
+ }
+ *psw = (*psw & ~15) | ((N&1) << 3) | ((Z&1) << 2) | ((V&1) << 1) | (C&1);
+ return dst;
+}
+
+#define DIV_M(s) \
+int sreg, dreg, source, dest, result, remainder = 0, ea = 0, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _div(dest, REGD(dreg|1), source, &remainder, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+if (!(PSW & VFLAG)) { REGW((dreg|1)) = remainder; PUT_DW_DREG(result); }
+
+#define DIV_R(s) \
+int sreg, dreg, source, dest, result, remainder = 0, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _div(dest, REGD(dreg|1), source, &remainder, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+if (!(PSW & VFLAG)) { REGW((dreg|1)) = remainder; PUT_DW_DREG(result); }
+
+int t11_device::_ash(int source, int dest, int *psw) {
+ int src, src2, dst, sign, i;
+ int N, Z, V, C;
+
+ N = BIT(*psw, 3);
+ Z = BIT(*psw, 2);
+ V = BIT(*psw, 1);
+ C = BIT(*psw, 0);
+
+ src2 = dest & 077;
+ sign = GET_SIGN_W (source);
+ src = sign? source | ~077777: source;
+ if (src2 == 0) { /* [0] */
+ dst = src;
+ V = C = 0;
+ }
+ else if (src2 <= 15) { /* [1,15] */
+ dst = src << src2;
+ i = (src >> (16 - src2)) & 0177777;
+ V = (i != ((dst & 0100000)? 0177777: 0));
+ C = (i & 1);
+ }
+ else if (src2 <= 31) { /* [16,31] */
+ dst = 0;
+ V = (src != 0);
+ C = (src << (src2 - 16)) & 1;
+ }
+ else if (src2 == 32) { /* [32] = -32 */
+ dst = -sign;
+ V = 0;
+ C = sign;
+ }
+ else { /* [33,63] = -31,-1 */
+ dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
+ V = 0;
+ C = ((src >> (63 - src2)) & 1);
+ }
+ N = GET_SIGN_W (dst);
+ Z = GET_ZERO (dst);
+ *psw = (*psw & ~15) | ((N&1) << 3) | ((Z&1) << 2) | ((V&1) << 1) | (C&1);
+ return dst & 0177777;
+}
+
+#define ASH_M(s) \
+int sreg, dreg, source, dest, result, _psw = PSW, ea = 0; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _ash(dest, source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result)
+
+#define ASH_R(s) \
+int sreg, dreg, source, dest, result, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _ash(dest, source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result)
+
+int t11_device::_ashc(int source, int source1, int dest, int *psw) {
+ int src, src2, dst, sign, i;
+ int N, Z, V, C;
+
+ N = BIT(*psw, 3);
+ Z = BIT(*psw, 2);
+ V = BIT(*psw, 1);
+ C = BIT(*psw, 0);
+
+ src2 = dest & 077;
+ sign = GET_SIGN_W (source);
+
+ src = (((uint32_t) source) << 16) | source1;
+ if (src2 == 0) { /* [0] */
+ dst = src;
+ V = C = 0;
+ }
+ else if (src2 <= 31) { /* [1,31] */
+ dst = ((uint32_t) src) << src2;
+ i = (src >> (32 - src2)) | (-sign << src2);
+ V = (i != ((dst & 020000000000)? -1: 0));
+ C = (i & 1);
+ }
+ else if (src2 == 32) { /* [32] = -32 */
+ dst = -sign;
+ V = 0;
+ C = sign;
+ }
+ else { /* [33,63] = -31,-1 */
+ dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
+ V = 0;
+ C = ((src >> (63 - src2)) & 1);
+ }
+ i = (dst >> 16) & 0177777;
+ N = GET_SIGN_W (i);
+ Z = GET_ZERO (dst | i);
+ *psw = (*psw & ~15) | ((N&1) << 3) | ((Z&1) << 2) | ((V&1) << 1) | (C&1);
+ return dst;
+}
+
+#define ASHC_M(s) \
+int sreg, dreg, source, dest, result, ea = 0, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _ashc(dest, REGD(dreg|1), source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result >> 16); REGW(dreg|1) = result
+
+#define ASHC_R(s) \
+int sreg, dreg, source, dest, result, _psw = PSW; \
+EIS_SWAP; GET_SW_##s; GET_DW_RG; \
+result = _ashc(dest, REGD(dreg|1), source, &_psw); PSW = (PSW & ~15) | (_psw & 15); \
+PUT_DW_DREG(result >> 16); REGW(dreg|1) = result
+
+
void t11_device::trap_to(uint16_t vector)
{
PUSH(PSW);
@@ -329,6 +520,12 @@ void t11_device::halt(uint16_t op)
m_mcir = MCIR_HALT;
m_vsel = VM1_HALT;
}
+ else if (c_insn_set & IS_VM2)
+ {
+ m_mcir = MCIR_HALT;
+ m_vsel = VM2_HALT;
+ m_check_irqs = true;
+ }
else
{
PUSH(PSW);
@@ -927,6 +1124,42 @@ void t11_device::xor_ded(uint16_t op) { CHECK_IS(IS_LEIS); m_icount -= 30;
void t11_device::xor_ix(uint16_t op) { CHECK_IS(IS_LEIS); m_icount -= 30; { XOR_M(IX); } }
void t11_device::xor_ixd(uint16_t op) { CHECK_IS(IS_LEIS); m_icount -= 36; { XOR_M(IXD); } }
+void t11_device::ash_rg(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 12; { ASH_R(RG); } } // XXX icount is fake
+void t11_device::ash_rgd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { ASH_M(RGD); } }
+void t11_device::ash_in(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { ASH_M(IN); } }
+void t11_device::ash_ind(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 27; { ASH_M(IND); } }
+void t11_device::ash_de(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 24; { ASH_M(DE); } }
+void t11_device::ash_ded(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { ASH_M(DED); } }
+void t11_device::ash_ix(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { ASH_M(IX); } }
+void t11_device::ash_ixd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 36; { ASH_M(IXD); } }
+
+void t11_device::ashc_rg(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 12; { ASHC_R(RG); } } // XXX icount is fake
+void t11_device::ashc_rgd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { ASHC_M(RGD); } }
+void t11_device::ashc_in(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { ASHC_M(IN); } }
+void t11_device::ashc_ind(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 27; { ASHC_M(IND); } }
+void t11_device::ashc_de(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 24; { ASHC_M(DE); } }
+void t11_device::ashc_ded(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { ASHC_M(DED); } }
+void t11_device::ashc_ix(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { ASHC_M(IX); } }
+void t11_device::ashc_ixd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 36; { ASHC_M(IXD); } }
+
+void t11_device::mul_rg(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 12; { MUL_R(RG); } } // XXX icount is fake
+void t11_device::mul_rgd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { MUL_M(RGD); } }
+void t11_device::mul_in(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { MUL_M(IN); } }
+void t11_device::mul_ind(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 27; { MUL_M(IND); } }
+void t11_device::mul_de(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 24; { MUL_M(DE); } }
+void t11_device::mul_ded(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { MUL_M(DED); } }
+void t11_device::mul_ix(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { MUL_M(IX); } }
+void t11_device::mul_ixd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 36; { MUL_M(IXD); } }
+
+void t11_device::div_rg(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 12; { DIV_R(RG); } } // XXX icount is fake
+void t11_device::div_rgd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { DIV_M(RGD); } }
+void t11_device::div_in(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 21; { DIV_M(IN); } }
+void t11_device::div_ind(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 27; { DIV_M(IND); } }
+void t11_device::div_de(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 24; { DIV_M(DE); } }
+void t11_device::div_ded(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { DIV_M(DED); } }
+void t11_device::div_ix(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 30; { DIV_M(IX); } }
+void t11_device::div_ixd(uint16_t op) { CHECK_IS(IS_EIS); m_icount -= 36; { DIV_M(IXD); } }
+
void t11_device::sob(uint16_t op)
{
int sreg, source;
diff --git a/src/devices/cpu/t11/t11table.hxx b/src/devices/cpu/t11/t11table.hxx
index 98ffaa6195f..e5ee1309ffe 100644
--- a/src/devices/cpu/t11/t11table.hxx
+++ b/src/devices/cpu/t11/t11table.hxx
@@ -592,45 +592,45 @@ const t11_device::opcode_func t11_device::s_opcode_table[65536 >> 3] =
OP(add_ixd_rg), OP(add_ixd_rgd), OP(add_ixd_in), OP(add_ixd_ind), OP(add_ixd_de), OP(add_ixd_ded), OP(add_ixd_ix), OP(add_ixd_ixd),
/* 0x7000 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
/* 0x7100 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
+ OP(mul_rg), OP(mul_rgd), OP(mul_in), OP(mul_ind), OP(mul_de), OP(mul_ded), OP(mul_ix), OP(mul_ixd),
/* 0x7200 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
/* 0x7300 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
+ OP(div_rg), OP(div_rgd), OP(div_in), OP(div_ind), OP(div_de), OP(div_ded), OP(div_ix), OP(div_ixd),
/* 0x7400 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
/* 0x7500 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
+ OP(ash_rg), OP(ash_rgd), OP(ash_in), OP(ash_ind), OP(ash_de), OP(ash_ded), OP(ash_ix), OP(ash_ixd),
/* 0x7600 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
/* 0x7700 */
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
+ OP(ashc_rg), OP(ashc_rgd), OP(ashc_in), OP(ashc_ind), OP(ashc_de), OP(ashc_ded), OP(ashc_ix), OP(ashc_ixd),
/* 0x7800 */
OP(xor_rg), OP(xor_rgd), OP(xor_in), OP(xor_ind), OP(xor_de), OP(xor_ded), OP(xor_ix), OP(xor_ixd),
OP(xor_rg), OP(xor_rgd), OP(xor_in), OP(xor_ind), OP(xor_de), OP(xor_ded), OP(xor_ix), OP(xor_ixd),
diff --git a/src/mame/ussr/dvk_kcgd.cpp b/src/mame/ussr/dvk_kcgd.cpp
index c6c1f8c81f4..857aaa1dc7f 100644
--- a/src/mame/ussr/dvk_kcgd.cpp
+++ b/src/mame/ussr/dvk_kcgd.cpp
@@ -14,7 +14,6 @@
Lower 32K of VRAM are not used to store pixel data.
To do:
- - K1801VM2 CPU core (interrupts and EVNT pin, full EIS set, other insns)
- verify hsync/vsync frequencies
- mouse
- mono/color CRT