summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/cop400/cop400.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/cop400/cop400.c')
-rw-r--r--trunk/src/emu/cpu/cop400/cop400.c1709
1 files changed, 1709 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/cop400/cop400.c b/trunk/src/emu/cpu/cop400/cop400.c
new file mode 100644
index 00000000000..f629e7913bd
--- /dev/null
+++ b/trunk/src/emu/cpu/cop400/cop400.c
@@ -0,0 +1,1709 @@
+/***************************************************************************
+
+ cop400.c
+
+ National Semiconductor COP400 Emulator.
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+****************************************************************************
+
+ Type ROM RAM G D IN
+
+ COP410 512x8 32x4 none
+ COP411 512x8 32x4 0-2 0-1 none
+ COP401 none 32x4 none
+ COP413?
+ COP414?
+ COP415?
+ COP405?
+
+ COP420 1024x8 64x4
+ COP421 1024x8 64x4 none
+ COP422 1024x8 64x4 2-3 2-3 none
+ COP402 none 64x4
+
+ COP444 2048x8 128x4
+ COP445 2048x8 128x4 none
+ COP424 1024x8 64x4
+ COP425 1024x8 64x4 none
+ COP426 1024x8 64x4 2-3 2-3
+ COP404 none none
+
+ COP440 2048x8 160x4
+ COP441 2048x8 160x4
+ COP442 2048x8 160x4
+
+****************************************************************************
+
+ Prefix Temperature Range
+
+ COP4xx 0C ... 70C
+ COP3xx -40C ... +85C
+ COP2xx -55C ... +125C
+
+***************************************************************************/
+
+/*
+
+ TODO:
+
+ - remove LBIOps
+ - remove InstLen
+ - run interrupt test suite
+ - run production test suite
+ - run microbus test suite
+ - when is the microbus int cleared?
+ - opcode support for 2048x8 and 128x4/160x4 memory sizes
+ - CKO sync input
+ - save internal RAM when CKO is RAM power supply pin
+ - COP413/COP414/COP415/COP405
+ - COP404 opcode map switching, dual timer, microbus enable
+ - COP440/COP441/COP442 (new registers: 2-bit N, 4-bit H, 8-bit R; some new opcodes, 2Kx8 ROM, 160x4 RAM)
+
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "cop400.h"
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* feature masks */
+#define COP410_FEATURE 0x01
+#define COP420_FEATURE 0x02
+#define COP444_FEATURE 0x04
+#define COP440_FEATURE 0x08
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+typedef struct _cop400_opcode_map cop400_opcode_map;
+
+typedef struct _cop400_state cop400_state;
+struct _cop400_state
+{
+ const cop400_interface *intf;
+
+ address_space *program;
+ direct_read_data *direct;
+ address_space *data;
+ address_space *io;
+
+ UINT8 featuremask;
+
+ /* registers */
+ UINT16 pc; /* 9/10/11-bit ROM address program counter */
+ UINT16 prevpc; /* previous value of program counter */
+ UINT8 a; /* 4-bit accumulator */
+ UINT8 b; /* 5/6/7-bit RAM address register */
+ int c; /* 1-bit carry register */
+ UINT8 n; /* 2-bit stack pointer (COP440 only) */
+ UINT8 en; /* 4-bit enable register */
+ UINT8 g; /* 4-bit general purpose I/O port */
+ UINT8 q; /* 8-bit latch for L port */
+ UINT16 sa, sb, sc; /* subroutine save registers (not present in COP440) */
+ UINT8 sio; /* 4-bit shift register and counter */
+ int skl; /* 1-bit latch for SK output */
+ UINT8 h; /* 4-bit general purpose I/O port (COP440 only) */
+ UINT8 r; /* 8-bit general purpose I/O port (COP440 only) */
+ UINT8 flags; // used for I/O only
+
+ /* counter */
+ UINT8 t; /* 8-bit timer */
+ int skt_latch; /* timer overflow latch */
+
+ /* input/output ports */
+ UINT8 g_mask; /* G port mask */
+ UINT8 d_mask; /* D port mask */
+ UINT8 in_mask; /* IN port mask */
+ UINT8 il; /* IN latch */
+ UINT8 in[4]; /* IN port shift register */
+ UINT8 si; /* serial input */
+
+ /* skipping logic */
+ int skip; /* skip next instruction */
+ int skip_lbi; /* skip until next non-LBI instruction */
+ int last_skip; /* last value of skip */
+ int halt; /* halt mode */
+ int idle; /* idle mode */
+
+ /* microbus */
+ int microbus_int; /* microbus interrupt */
+
+ /* execution logic */
+ int InstLen[256]; /* instruction length in bytes */
+ int LBIops[256];
+ int LBIops33[256];
+ int icount; /* instruction counter */
+
+ const cop400_opcode_map *opcode_map;
+
+ /* timers */
+ emu_timer *serial_timer;
+ emu_timer *counter_timer;
+ emu_timer *inil_timer;
+ emu_timer *microbus_timer;
+};
+
+typedef void (*cop400_opcode_func) (cop400_state *cpustate, UINT8 opcode);
+
+struct _cop400_opcode_map {
+ unsigned cycles;
+ cop400_opcode_func function;
+};
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+#define ROM(a) cpustate->direct->read_decrypted_byte(a)
+#define RAM_R(a) cpustate->data->read_byte(a)
+#define RAM_W(a, v) cpustate->data->write_byte(a, v)
+#define IN(a) cpustate->io->read_byte(a)
+#define OUT(a, v) cpustate->io->write_byte(a, v)
+
+#define IN_G() (IN(COP400_PORT_G) & cpustate->g_mask)
+#define IN_L() IN(COP400_PORT_L)
+#define IN_SI() BIT(IN(COP400_PORT_SIO), 0)
+#define IN_CKO() BIT(IN(COP400_PORT_CKO), 0)
+#define IN_IN() (cpustate->in_mask ? IN(COP400_PORT_IN) : 0)
+
+#define OUT_G(v) OUT(COP400_PORT_G, (v) & cpustate->g_mask)
+#define OUT_L(v) OUT(COP400_PORT_L, (v))
+#define OUT_D(v) OUT(COP400_PORT_D, (v) & cpustate->d_mask)
+#define OUT_SK(v) OUT(COP400_PORT_SK, (v))
+#define OUT_SO(v) OUT(COP400_PORT_SIO, (v))
+
+#define PC cpustate->pc
+#define A cpustate->a
+#define B cpustate->b
+#define C cpustate->c
+#define G cpustate->g
+#define Q cpustate->q
+#define H cpustate->h
+#define R cpustate->r
+#define EN cpustate->en
+#define SA cpustate->sa
+#define SB cpustate->sb
+#define SC cpustate->sc
+#define SIO cpustate->sio
+#define SKL cpustate->skl
+#define T cpustate->t
+#define IL cpustate->il
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+INLINE cop400_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == COP401 ||
+ device->type() == COP410 ||
+ device->type() == COP411 ||
+ device->type() == COP402 ||
+ device->type() == COP420 ||
+ device->type() == COP421 ||
+ device->type() == COP422 ||
+ device->type() == COP404 ||
+ device->type() == COP424 ||
+ device->type() == COP425 ||
+ device->type() == COP426 ||
+ device->type() == COP444 ||
+ device->type() == COP445);
+ return (cop400_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+INLINE void PUSH(cop400_state *cpustate, UINT16 data)
+{
+ if (cpustate->featuremask != COP410_FEATURE)
+ {
+ SC = SB;
+ }
+
+ SB = SA;
+ SA = data;
+}
+
+INLINE void POP(cop400_state *cpustate)
+{
+ PC = SA;
+ SA = SB;
+
+ if (cpustate->featuremask != COP410_FEATURE)
+ {
+ SB = SC;
+ }
+}
+
+INLINE void WRITE_Q(cop400_state *cpustate, UINT8 data)
+{
+ Q = data;
+
+ if (BIT(EN, 2))
+ {
+ OUT_L(Q);
+ }
+}
+
+INLINE void WRITE_G(cop400_state *cpustate, UINT8 data)
+{
+ if (cpustate->intf->microbus == COP400_MICROBUS_ENABLED)
+ {
+ data = (data & 0x0e) | cpustate->microbus_int;
+ }
+
+ G = data;
+
+ OUT_G(G);
+}
+
+/***************************************************************************
+ OPCODE HANDLERS
+***************************************************************************/
+
+#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(cop400_state *cpustate, UINT8 opcode)
+
+INSTRUCTION(illegal)
+{
+ logerror("COP400: PC = %04x, Illegal opcode = %02x\n", PC-1, ROM(PC-1));
+}
+
+#include "cop400op.c"
+
+/***************************************************************************
+ OPCODE TABLES
+***************************************************************************/
+
+static const cop400_opcode_map COP410_OPCODE_23_MAP[] =
+{
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, xad },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal }
+};
+
+static void cop410_op23(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode23 = ROM(PC++);
+
+ (*(COP410_OPCODE_23_MAP[opcode23].function))(cpustate, opcode23);
+}
+
+static const cop400_opcode_map COP410_OPCODE_33_MAP[] =
+{
+ {1, illegal },{1, skgbz0 },{1, illegal },{1, skgbz2 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgbz1 },{1, illegal },{1, skgbz3 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgz },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, ing },{1, illegal },{1, illegal },{1, illegal },{1, inl },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, halt },{1, illegal },{1, omg },{1, illegal },{1, camq },{1, illegal },{1, obd },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal }
+};
+
+static void cop410_op33(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode33 = ROM(PC++);
+
+ (*(COP410_OPCODE_33_MAP[opcode33].function))(cpustate, opcode33);
+}
+
+static const cop400_opcode_map COP410_OPCODE_MAP[] =
+{
+ {1, clra },{1, skmbz0 },{1, xor_ },{1, skmbz2 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {0, illegal },{1, skmbz1 },{0, illegal },{1, skmbz3 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, skc },{1, ske },{1, sc },{1, cop410_op23 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, asc },{1, add },{1, rc },{1, cop410_op33 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+
+ {1, comp },{0, illegal },{1, rmb2 },{1, rmb3 },{1, nop },{1, rmb1 },{1, smb2 },{1, smb1 },
+ {1, ret },{1, retsk },{0, illegal },{1, smb3 },{1, rmb0 },{1, smb0 },{1, cba },{1, xas },
+ {1, cab },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {2, jmp },{2, jmp },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
+ {2, jsr },{2, jsr },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, lqid },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, jid }
+};
+
+static const cop400_opcode_map COP420_OPCODE_23_MAP[] =
+{
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal }
+};
+
+static void cop420_op23(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode23 = ROM(PC++);
+
+ (*(COP420_OPCODE_23_MAP[opcode23].function))(cpustate, opcode23);
+}
+
+static const cop400_opcode_map COP420_OPCODE_33_MAP[] =
+{
+ {1, illegal },{1, skgbz0 },{1, illegal },{1, skgbz2 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgbz1 },{1, illegal },{1, skgbz3 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgz },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, inin },{1, inil },{1, ing },{1, illegal },{1, cqma },{1, illegal },{1, inl },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, omg },{1, illegal },{1, camq },{1, illegal },{1, obd },{1, illegal },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },
+ {1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal }
+};
+
+static void cop420_op33(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode33 = ROM(PC++);
+
+ (*(COP420_OPCODE_33_MAP[opcode33].function))(cpustate, opcode33);
+}
+
+static const cop400_opcode_map COP420_OPCODE_MAP[] =
+{
+ {1, clra },{1, skmbz0 },{1, xor_ },{1, skmbz2 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, casc },{1, skmbz1 },{1, xabr },{1, skmbz3 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, skc },{1, ske },{1, sc },{1, cop420_op23 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, asc },{1, add },{1, rc },{1, cop420_op33 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+
+ {1, comp },{1, skt },{1, rmb2 },{1, rmb3 },{1, nop },{1, rmb1 },{1, smb2 },{1, smb1 },
+ {1, cop420_ret },{1, retsk },{1, adt },{1, smb3 },{1, rmb0 },{1, smb0 },{1, cba },{1, xas },
+ {1, cab },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {2, jmp },{2, jmp },{2, jmp },{2, jmp },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
+ {2, jsr },{2, jsr },{2, jsr },{2, jsr },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, lqid },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, jid }
+};
+
+static const cop400_opcode_map COP444_OPCODE_23_MAP[256] =
+{
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+ {1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },{1, ldd },
+
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+ {1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
+};
+
+static void cop444_op23(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode23 = ROM(PC++);
+
+ (*(COP444_OPCODE_23_MAP[opcode23].function))(cpustate, opcode23);
+}
+
+static const cop400_opcode_map COP444_OPCODE_33_MAP[256] =
+{
+ {1, illegal },{1, skgbz0 },{1, illegal },{1, skgbz2 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgbz1 },{1, illegal },{1, skgbz3 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, skgz },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, inin },{1, inil },{1, ing },{1, illegal },{1, cqma },{1, illegal },{1, inl },{1, ctma },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, it },{1, illegal },{1, omg },{1, illegal },{1, camq },{1, illegal },{1, obd },{1, camt },
+
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },
+ {1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+ {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
+
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+};
+
+static void cop444_op33(cop400_state *cpustate, UINT8 opcode)
+{
+ UINT8 opcode33 = ROM(PC++);
+
+ (*(COP444_OPCODE_33_MAP[opcode33].function))(cpustate, opcode33);
+}
+
+static const cop400_opcode_map COP444_OPCODE_MAP[256] =
+{
+ {1, clra },{1, skmbz0 },{1, xor_ },{1, skmbz2 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, casc },{1, skmbz1 },{1, cop444_xabr},{1, skmbz3 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, skc },{1, ske },{1, sc },{1, cop444_op23 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+ {1, asc },{1, add },{1, rc },{1, cop444_op33 },{1, xis },{1, ld },{1, x },{1, xds },
+ {1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },{1, lbi },
+
+ {1, comp },{1, skt },{1, rmb2 },{1, rmb3 },{1, nop },{1, rmb1 },{1, smb2 },{1, smb1 },
+ {1, cop420_ret },{1, retsk },{1, adt },{1, smb3 },{1, rmb0 },{1, smb0 },{1, cba },{1, xas },
+ {1, cab },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
+ {2, jmp },{2, jmp },{2, jmp },{2, jmp },{2, jmp },{2, jmp },{2, jmp },{2, jmp },
+ {2, jsr },{2, jsr },{2, jsr },{2, jsr },{2, jsr },{2, jsr },{2, jsr },{2, jsr },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+ {1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, lqid },
+
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
+ {1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{2, jid }
+};
+
+/***************************************************************************
+ TIMER CALLBACKS
+***************************************************************************/
+
+static TIMER_CALLBACK( serial_tick )
+{
+ cop400_state *cpustate = (cop400_state *)ptr;
+
+ if (BIT(EN, 0))
+ {
+ /*
+
+ SIO is an asynchronous binary counter decrementing its value by one upon each low-going pulse ("1" to "0") occurring on the SI input.
+ Each pulse must remain at each logic level at least two instruction cycles. SK outputs the value of the C upon the execution of an XAS
+ and remains latched until the execution of another XAS instruction. The SO output is equal to the value of EN3.
+
+ */
+
+ // serial output
+
+ OUT_SO(BIT(EN, 3));
+
+ // serial clock
+
+ OUT_SK(SKL);
+
+ // serial input
+
+ cpustate->si <<= 1;
+ cpustate->si = (cpustate->si & 0x0e) | IN_SI();
+
+ if ((cpustate->si & 0x0f) == 0x0c) // 1100
+ {
+ SIO--;
+ SIO &= 0x0f;
+ }
+ }
+ else
+ {
+ /*
+
+ SIO is a serial shift register, shifting continuously left each instruction cycle time. The data present at SI goes into the least
+ significant bit of SIO: SO can be enabled to output the most significant bit of SIO each cycle time. SK output becomes a logic-
+ controlled clock, providing a SYNC signal each instruction time. It will start outputting a SYNC pulse upon the execution of an XAS
+ instruction with C = "1," stopping upon the execution of a subsequent XAS with C = "0".
+
+ If EN0 is changed from "1" to "0" ("0" to "1") the SK output will change from "1" to SYNC (SYNC to "1") without the execution of
+ an XAS instruction.
+
+ */
+
+ // serial output
+
+ if (BIT(EN, 3))
+ {
+ OUT_SO(BIT(SIO, 3));
+ }
+ else
+ {
+ OUT_SO(0);
+ }
+
+ // serial clock
+
+ if (SKL)
+ {
+ OUT_SK(1); // SYNC
+ }
+ else
+ {
+ OUT_SK(0);
+ }
+
+ // serial input
+
+ SIO = ((SIO << 1) | IN_SI()) & 0x0f;
+ }
+}
+
+static TIMER_CALLBACK( counter_tick )
+{
+ cop400_state *cpustate = (cop400_state *)ptr;
+
+ T++;
+
+ if (T == 0)
+ {
+ cpustate->skt_latch = 1;
+
+ if (cpustate->idle)
+ {
+ cpustate->idle = 0;
+ cpustate->halt = 0;
+ }
+ }
+}
+
+static TIMER_CALLBACK( inil_tick )
+{
+ cop400_state *cpustate = (cop400_state *)ptr;
+ UINT8 in;
+ int i;
+
+ in = IN_IN();
+
+ for (i = 0; i < 4; i++)
+ {
+ cpustate->in[i] = (cpustate->in[i] << 1) | BIT(in, i);
+
+ if ((cpustate->in[i] & 0x07) == 0x04) // 100
+ {
+ IL |= (1 << i);
+ }
+ }
+}
+
+static TIMER_CALLBACK( microbus_tick )
+{
+ cop400_state *cpustate = (cop400_state *)ptr;
+ UINT8 in;
+
+ in = IN_IN();
+
+ if (!BIT(in, 2))
+ {
+ // chip select
+
+ if (!BIT(in, 1))
+ {
+ // read strobe
+
+ OUT_L(Q);
+
+ cpustate->microbus_int = 1;
+ }
+ else if (!BIT(in, 3))
+ {
+ // write strobe
+
+ Q = IN_L();
+
+ cpustate->microbus_int = 0;
+ }
+ }
+}
+
+/***************************************************************************
+ INITIALIZATION
+***************************************************************************/
+
+static void define_state_table(device_t *device)
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ device_state_interface *state;
+ device->interface(state);
+ state->state_add(STATE_GENPC, "GENPC", cpustate->pc).mask(0xfff).noshow();
+ state->state_add(STATE_GENPCBASE, "GENPCBASE", cpustate->prevpc).mask(0xfff).noshow();
+ state->state_add(STATE_GENSP, "GENSP", cpustate->n).mask(0x3).noshow();
+ state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->flags).mask(0x3).callimport().callexport().noshow().formatstr("%2s");
+
+ state->state_add(COP400_PC, "PC", cpustate->pc).mask(0xfff);
+
+ if (cpustate->featuremask & (COP410_FEATURE | COP420_FEATURE | COP444_FEATURE))
+ {
+ state->state_add(COP400_SA, "SA", cpustate->sa).mask(0xfff);
+ state->state_add(COP400_SB, "SB", cpustate->sb).mask(0xfff);
+ if (cpustate->featuremask & (COP420_FEATURE | COP444_FEATURE))
+ state->state_add(COP400_SC, "SC", cpustate->sc).mask(0xfff);
+ }
+ if (cpustate->featuremask & COP440_FEATURE)
+ state->state_add(COP400_N, "N", cpustate->n).mask(0x3);
+
+ state->state_add(COP400_A, "A", cpustate->a).mask(0xf);
+ state->state_add(COP400_B, "B", cpustate->b);
+ state->state_add(COP400_C, "C", cpustate->c).mask(0x1);
+
+ state->state_add(COP400_EN, "EN", cpustate->en).mask(0xf);
+ state->state_add(COP400_G, "G", cpustate->g).mask(0xf);
+ if (cpustate->featuremask & COP440_FEATURE)
+ state->state_add(COP400_H, "H", cpustate->h).mask(0xf);
+ state->state_add(COP400_Q, "Q", cpustate->q);
+ if (cpustate->featuremask & COP440_FEATURE)
+ state->state_add(COP400_R, "R", cpustate->r);
+
+ state->state_add(COP400_SIO, "SIO", cpustate->sio).mask(0xf);
+ state->state_add(COP400_SKL, "SKL", cpustate->skl).mask(0x1);
+
+ if (cpustate->featuremask & (COP420_FEATURE | COP444_FEATURE | COP440_FEATURE))
+ state->state_add(COP400_T, "T", cpustate->t);
+}
+
+static void cop400_init(legacy_cpu_device *device, UINT8 g_mask, UINT8 d_mask, UINT8 in_mask, int has_counter, int has_inil)
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ cpustate->intf = (cop400_interface *) device->static_config();
+
+ /* find address spaces */
+
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->data = device->space(AS_DATA);
+ cpustate->io = device->space(AS_IO);
+
+ /* set output pin masks */
+
+ cpustate->g_mask = g_mask;
+ cpustate->d_mask = d_mask;
+ cpustate->in_mask = in_mask;
+
+ /* allocate serial timer */
+
+ cpustate->serial_timer = device->machine().scheduler().timer_alloc(FUNC(serial_tick), cpustate);
+ cpustate->serial_timer->adjust(attotime::zero, 0, attotime::from_hz(device->clock() / 16));
+
+ /* allocate counter timer */
+
+ if (has_counter)
+ {
+ cpustate->counter_timer = device->machine().scheduler().timer_alloc(FUNC(counter_tick), cpustate);
+ cpustate->counter_timer->adjust(attotime::zero, 0, attotime::from_hz(device->clock() / 16 / 4));
+ }
+
+ /* allocate IN latch timer */
+
+ if (has_inil)
+ {
+ cpustate->inil_timer = device->machine().scheduler().timer_alloc(FUNC(inil_tick), cpustate);
+ cpustate->inil_timer->adjust(attotime::zero, 0, attotime::from_hz(device->clock() / 16));
+ }
+
+ /* allocate Microbus timer */
+
+ if (cpustate->intf->microbus == COP400_MICROBUS_ENABLED)
+ {
+ cpustate->microbus_timer = device->machine().scheduler().timer_alloc(FUNC(microbus_tick), cpustate);
+ cpustate->microbus_timer->adjust(attotime::zero, 0, attotime::from_hz(device->clock() / 16));
+ }
+
+ /* register for state saving */
+
+ device->save_item(NAME(cpustate->pc));
+ device->save_item(NAME(cpustate->prevpc));
+ device->save_item(NAME(cpustate->n));
+ device->save_item(NAME(cpustate->sa));
+ device->save_item(NAME(cpustate->sb));
+ device->save_item(NAME(cpustate->sc));
+ device->save_item(NAME(cpustate->a));
+ device->save_item(NAME(cpustate->b));
+ device->save_item(NAME(cpustate->c));
+ device->save_item(NAME(cpustate->g));
+ device->save_item(NAME(cpustate->h));
+ device->save_item(NAME(cpustate->q));
+ device->save_item(NAME(cpustate->r));
+ device->save_item(NAME(cpustate->en));
+ device->save_item(NAME(cpustate->sio));
+ device->save_item(NAME(cpustate->skl));
+ device->save_item(NAME(cpustate->t));
+ device->save_item(NAME(cpustate->skip));
+ device->save_item(NAME(cpustate->skip_lbi));
+ device->save_item(NAME(cpustate->skt_latch));
+ device->save_item(NAME(cpustate->si));
+ device->save_item(NAME(cpustate->last_skip));
+ device->save_item(NAME(cpustate->in));
+ device->save_item(NAME(cpustate->microbus_int));
+ device->save_item(NAME(cpustate->halt));
+ device->save_item(NAME(cpustate->idle));
+}
+
+static void cop410_init_opcodes(device_t *device)
+{
+ cop400_state *cpustate = get_safe_token(device);
+ int i;
+
+ /* set up the state table */
+
+ cpustate->featuremask = COP410_FEATURE;
+ define_state_table(device);
+
+ /* initialize instruction length array */
+
+ for (i=0; i<256; i++) cpustate->InstLen[i]=1;
+
+ cpustate->InstLen[0x60] = cpustate->InstLen[0x61] = cpustate->InstLen[0x68] =
+ cpustate->InstLen[0x69] = cpustate->InstLen[0x33] = cpustate->InstLen[0x23] = 2;
+
+ /* initialize LBI opcode array */
+
+ for (i=0x00; i<0x100; i++) cpustate->LBIops[i] = 0;
+ for (i=0x08; i<0x10; i++) cpustate->LBIops[i] = 1;
+ for (i=0x18; i<0x20; i++) cpustate->LBIops[i] = 1;
+ for (i=0x28; i<0x30; i++) cpustate->LBIops[i] = 1;
+ for (i=0x38; i<0x40; i++) cpustate->LBIops[i] = 1;
+
+ /* select opcode map */
+
+ cpustate->opcode_map = COP410_OPCODE_MAP;
+}
+
+static void cop420_init_opcodes(device_t *device)
+{
+ cop400_state *cpustate = get_safe_token(device);
+ int i;
+
+ /* set up the state table */
+
+ cpustate->featuremask = COP420_FEATURE;
+ define_state_table(device);
+
+ /* initialize instruction length array */
+
+ for (i=0; i<256; i++) cpustate->InstLen[i]=1;
+
+ cpustate->InstLen[0x60] = cpustate->InstLen[0x61] = cpustate->InstLen[0x62] = cpustate->InstLen[0x63] =
+ cpustate->InstLen[0x68] = cpustate->InstLen[0x69] = cpustate->InstLen[0x6a] = cpustate->InstLen[0x6b] =
+ cpustate->InstLen[0x33] = cpustate->InstLen[0x23] = 2;
+
+ /* initialize LBI opcode array */
+
+ for (i=0x00; i<0x100; i++) cpustate->LBIops[i] = 0;
+ for (i=0x08; i<0x10; i++) cpustate->LBIops[i] = 1;
+ for (i=0x18; i<0x20; i++) cpustate->LBIops[i] = 1;
+ for (i=0x28; i<0x30; i++) cpustate->LBIops[i] = 1;
+ for (i=0x38; i<0x40; i++) cpustate->LBIops[i] = 1;
+
+ for (i=0; i<256; i++) cpustate->LBIops33[i] = 0;
+ for (i=0x80; i<0xc0; i++) cpustate->LBIops33[i] = 1;
+
+ /* select opcode map */
+
+ cpustate->opcode_map = COP420_OPCODE_MAP;
+}
+
+static void cop444_init_opcodes(device_t *device)
+{
+ cop400_state *cpustate = get_safe_token(device);
+ int i;
+
+ /* set up the state table */
+
+ cpustate->featuremask = COP444_FEATURE;
+ define_state_table(device);
+
+ /* initialize instruction length array */
+
+ for (i=0; i<256; i++) cpustate->InstLen[i]=1;
+
+ cpustate->InstLen[0x60] = cpustate->InstLen[0x61] = cpustate->InstLen[0x62] = cpustate->InstLen[0x63] =
+ cpustate->InstLen[0x68] = cpustate->InstLen[0x69] = cpustate->InstLen[0x6a] = cpustate->InstLen[0x6b] =
+ cpustate->InstLen[0x33] = cpustate->InstLen[0x23] = 2;
+
+ /* initialize LBI opcode array */
+
+ for (i=0x00; i<0x100; i++) cpustate->LBIops[i] = 0;
+ for (i=0x08; i<0x10; i++) cpustate->LBIops[i] = 1;
+ for (i=0x18; i<0x20; i++) cpustate->LBIops[i] = 1;
+ for (i=0x28; i<0x30; i++) cpustate->LBIops[i] = 1;
+ for (i=0x38; i<0x40; i++) cpustate->LBIops[i] = 1;
+
+ for (i=0; i<256; i++) cpustate->LBIops33[i] = 0;
+ for (i=0x80; i<0xc0; i++) cpustate->LBIops33[i] = 1;
+
+ /* select opcode map */
+
+ cpustate->opcode_map = COP444_OPCODE_MAP;
+}
+
+static CPU_INIT( cop410 )
+{
+ cop410_init_opcodes(device);
+ cop400_init(device, 0xf, 0xf, 0, 0, 0);
+}
+
+static CPU_INIT( cop411 )
+{
+ cop410_init_opcodes(device);
+ cop400_init(device, 0x7, 0x3, 0, 0, 0);
+}
+
+static CPU_INIT( cop420 )
+{
+ cop420_init_opcodes(device);
+ cop400_init(device, 0xf, 0xf, 0xf, 1, 1);
+}
+
+static CPU_INIT( cop421 )
+{
+ cop420_init_opcodes(device);
+ cop400_init(device, 0xf, 0xf, 0, 1, 0);
+}
+
+static CPU_INIT( cop422 )
+{
+ cop420_init_opcodes(device);
+ cop400_init(device, 0xe, 0xe, 0, 1, 0);
+}
+
+static CPU_INIT( cop444 )
+{
+ cop444_init_opcodes(device);
+ cop400_init(device, 0xf, 0xf, 0xf, 1, 1);
+}
+
+static CPU_INIT( cop425 )
+{
+ cop444_init_opcodes(device);
+ cop400_init(device, 0xf, 0xf, 0, 1, 0);
+}
+
+static CPU_INIT( cop426 )
+{
+ cop444_init_opcodes(device);
+ cop400_init(device, 0xe, 0xe, 0xf, 1, 1);
+}
+
+static CPU_INIT( cop445 )
+{
+ cop444_init_opcodes(device);
+ cop400_init(device, 0x7, 0x3, 0, 1, 0);
+}
+
+/***************************************************************************
+ RESET
+***************************************************************************/
+
+static CPU_RESET( cop400 )
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ PC = 0;
+ A = 0;
+ B = 0;
+ C = 0;
+ OUT_D(0);
+ EN = 0;
+ WRITE_G(cpustate, 0);
+ SKL = 1;
+
+ T = 0;
+ cpustate->skt_latch = 1;
+
+ cpustate->halt = 0;
+ cpustate->idle = 0;
+}
+
+/***************************************************************************
+ EXECUTION
+***************************************************************************/
+
+static CPU_EXECUTE( cop400 )
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ UINT8 opcode;
+
+ do
+ {
+ cpustate->prevpc = PC;
+
+ debugger_instruction_hook(device, PC);
+
+ if (cpustate->intf->cko == COP400_CKO_HALT_IO_PORT)
+ {
+ cpustate->halt = IN_CKO();
+ }
+
+ if (cpustate->halt)
+ {
+ cpustate->icount -= 1;
+ continue;
+ }
+
+ opcode = ROM(PC);
+
+ if (cpustate->skip_lbi)
+ {
+ int is_lbi = 0;
+
+ if (opcode == 0x33)
+ {
+ is_lbi = cpustate->LBIops33[ROM(PC+1)];
+ }
+ else
+ {
+ is_lbi = cpustate->LBIops[opcode];
+ }
+
+ if (is_lbi)
+ {
+ cpustate->icount -= cpustate->opcode_map[opcode].cycles;
+
+ PC += cpustate->InstLen[opcode];
+ }
+ else
+ {
+ cpustate->skip_lbi = 0;
+ }
+ }
+
+ if (!cpustate->skip_lbi)
+ {
+ int inst_cycles = cpustate->opcode_map[opcode].cycles;
+
+ PC++;
+
+ (*(cpustate->opcode_map[opcode].function))(cpustate, opcode);
+ cpustate->icount -= inst_cycles;
+
+ // check for interrupt
+
+ if (BIT(EN, 1) && BIT(IL, 1))
+ {
+ cop400_opcode_func function = cpustate->opcode_map[ROM(PC)].function;
+
+ if ((function != jp) && (function != jmp) && (function != jsr))
+ {
+ // store skip logic
+ cpustate->last_skip = cpustate->skip;
+ cpustate->skip = 0;
+
+ // push next PC
+ PUSH(cpustate, PC);
+
+ // jump to interrupt service routine
+ PC = 0x0ff;
+
+ // disable interrupt
+ EN &= ~0x02;
+ }
+
+ IL &= ~2;
+ }
+
+ // skip next instruction?
+
+ if (cpustate->skip)
+ {
+ cop400_opcode_func function = cpustate->opcode_map[ROM(PC)].function;
+
+ opcode = ROM(PC);
+
+ if ((function == lqid) || (function == jid))
+ {
+ cpustate->icount -= 1;
+ }
+ else
+ {
+ cpustate->icount -= cpustate->opcode_map[opcode].cycles;
+ }
+
+ PC += cpustate->InstLen[opcode];
+
+ cpustate->skip = 0;
+ }
+ }
+ } while (cpustate->icount > 0);
+}
+
+/***************************************************************************
+ ADDRESS MAPS
+***************************************************************************/
+
+static ADDRESS_MAP_START( program_512b, AS_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x1ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( program_1kb, AS_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( program_2kb, AS_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x7ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_32b, AS_DATA, 8 )
+ AM_RANGE(0x00, 0x1f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_64b, AS_DATA, 8 )
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_128b, AS_DATA, 8 )
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+#ifdef UNUSED_CODE
+static ADDRESS_MAP_START( data_160b, AS_DATA, 8 )
+ AM_RANGE(0x00, 0x9f) AM_RAM
+ADDRESS_MAP_END
+#endif
+
+/***************************************************************************
+ VALIDITY CHECKS
+***************************************************************************/
+
+#if 0
+static CPU_VALIDITY_CHECK( cop410 )
+{
+ int error = FALSE;
+ const cop400_interface *intf = (const cop400_interface *) config;
+
+ if ((intf == NULL) || (intf->cki <= 0))
+ {
+ mame_printf_error("%s: %s has an invalid CPU configuration\n", driver->source_file, driver->name);
+ error = TRUE;
+ }
+
+ return error;
+}
+
+static CPU_VALIDITY_CHECK( cop420 )
+{
+ int error = FALSE;
+ const cop400_interface *intf = (const cop400_interface *) config;
+
+ if ((intf == NULL) || (intf->cki <= 0))
+ {
+ mame_printf_error("%s: %s has an invalid CPU configuration\n", driver->source_file, driver->name);
+ error = TRUE;
+ }
+
+ return error;
+}
+
+static CPU_VALIDITY_CHECK( cop421 )
+{
+ int error = FALSE;
+ const cop400_interface *intf = (const cop400_interface *) config;
+
+ if ((intf == NULL) || (intf->cki <= 0) || (intf->microbus == COP400_MICROBUS_ENABLED))
+ {
+ mame_printf_error("%s: %s has an invalid CPU configuration\n", driver->source_file, driver->name);
+ error = TRUE;
+ }
+
+ return error;
+}
+
+static CPU_VALIDITY_CHECK( cop444 )
+{
+ int error = FALSE;
+ const cop400_interface *intf = (const cop400_interface *) config;
+
+ if ((intf == NULL) || (intf->cki <= 0))
+ {
+ mame_printf_error("%s: %s has an invalid CPU configuration\n", driver->source_file, driver->name);
+ error = TRUE;
+ }
+
+ return error;
+}
+#endif
+
+/***************************************************************************
+ GENERAL CONTEXT ACCESS
+***************************************************************************/
+
+static CPU_IMPORT_STATE( cop400 )
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ cpustate->c = (cpustate->flags >> 1) & 1;
+ cpustate->skl = (cpustate->flags >> 0) & 1;
+ break;
+ }
+}
+
+static CPU_EXPORT_STATE( cop400 )
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ cpustate->flags = (cpustate->c ? 0x02 : 0x00) |
+ (cpustate->skl ? 0x01 : 0x00);
+ break;
+ }
+}
+
+static CPU_EXPORT_STRING( cop400 )
+{
+ cop400_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ string.printf("%c%c",
+ cpustate->c ? 'C' : '.',
+ cpustate->skl ? 'S' : '.');
+ break;
+ }
+}
+
+static CPU_SET_INFO( cop400 )
+{
+ /* nothing to set */
+}
+
+static CPU_GET_INFO( cop400 )
+{
+ cop400_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+ cop400_interface *intf = (device->static_config() != NULL) ? (cop400_interface *)device->static_config() : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(cop400_state); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = (intf != NULL) ? intf->cki : 16; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 2; break;
+
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: /* set per-core */ break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 8; /* really 4 */ break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: /* set per-core */ break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 9; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
+
+ /* --- the following bits of info are returned as pointers to functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cop400); break;
+ case CPUINFO_FCT_INIT: /* set per-core */ break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(cop400); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop400); break;
+ case CPUINFO_FCT_DISASSEMBLE: /* set per-core */ break;
+// case CPUINFO_FCT_VALIDITY_CHECK: /* set per-core */ break;
+ case CPUINFO_FCT_IMPORT_STATE: info->import_state = CPU_IMPORT_STATE_NAME(cop400); break;
+ case CPUINFO_FCT_EXPORT_STATE: info->export_state = CPU_EXPORT_STATE_NAME(cop400); break;
+ case CPUINFO_FCT_EXPORT_STRING: info->export_string = CPU_EXPORT_STRING_NAME(cop400); break;
+
+ /* --- the following bits of info are returned as pointers --- */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: /* set per-core */ break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: /* set per-core */ break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP400"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
+ }
+}
+
+/***************************************************************************
+ CPU-SPECIFIC CONTEXT ACCESS
+***************************************************************************/
+
+CPU_GET_INFO( cop410 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 9; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 5; break;
+
+ /* --- the following bits of info are returned as pointers to functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop410); break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop410); break;
+// case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop410); break;
+
+ /* --- the following bits of info are returned as pointers --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_512b); break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_32b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP410"); break;
+
+ default: CPU_GET_INFO_CALL(cop400); break;
+ }
+}
+
+CPU_GET_INFO( cop411 )
+{
+ // COP411 is a 20-pin package version of the COP410, missing D2/D3/G3/CKO
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop411); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP411"); break;
+
+ default: CPU_GET_INFO_CALL(cop410); break;
+ }
+}
+
+CPU_GET_INFO( cop401 )
+{
+ // COP401 is a ROMless version of the COP410
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP401"); break;
+
+ default: CPU_GET_INFO_CALL(cop410); break;
+ }
+}
+
+CPU_GET_INFO( cop420 )
+{
+ cop400_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 10; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 6; break;
+
+ /* --- the following bits of info are returned as pointers to functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop420); break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop420); break;
+// case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop420); break;
+
+ /* --- the following bits of info are returned as pointers --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_1kb); break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_64b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP420"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s,
+ "%c%c%c",
+ cpustate->c ? 'C' : '.',
+ cpustate->skl ? 'S' : '.',
+ cpustate->skt_latch ? 'T' : '.'); break;
+
+ default: CPU_GET_INFO_CALL(cop400); break;
+ }
+}
+
+CPU_GET_INFO( cop421 )
+{
+ // COP421 is a 24-pin package version of the COP420, lacking the IN ports
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop421); break;
+// case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop421); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP421"); break;
+
+ default: CPU_GET_INFO_CALL(cop420); break;
+ }
+}
+
+CPU_GET_INFO( cop422 )
+{
+ // COP422 is a 20-pin package version of the COP420, lacking G0/G1, D0/D1, and the IN ports
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop422); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP422"); break;
+
+ default: CPU_GET_INFO_CALL(cop421); break;
+ }
+}
+
+CPU_GET_INFO( cop402 )
+{
+ // COP402 is a ROMless version of the COP420
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP402"); break;
+
+ default: CPU_GET_INFO_CALL(cop420); break;
+ }
+}
+
+CPU_GET_INFO( cop444 )
+{
+ cop400_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 11; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 7; break;
+
+ /* --- the following bits of info are returned as pointers to functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop444); break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop444); break;
+// case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop444); break;
+
+ /* --- the following bits of info are returned as pointers --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_2kb); break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_128b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP444"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s,
+ "%c%c%c",
+ cpustate->c ? 'C' : '.',
+ cpustate->skl ? 'S' : '.',
+ cpustate->skt_latch ? 'T' : '.'); break;
+
+ default: CPU_GET_INFO_CALL(cop400); break;
+ }
+}
+
+CPU_GET_INFO( cop445 )
+{
+ // COP445 is a 24-pin package version of the COP444, lacking the IN ports
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop445); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP445"); break;
+
+ default: CPU_GET_INFO_CALL(cop444); break;
+ }
+}
+
+CPU_GET_INFO( cop424 )
+{
+ // COP424 is functionally equivalent to COP444, with only 1K ROM and 64x4 bytes RAM
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 10; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 6; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_1kb); break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_64b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP424"); break;
+
+ default: CPU_GET_INFO_CALL(cop444); break;
+ }
+}
+
+CPU_GET_INFO( cop425 )
+{
+ // COP425 is a 24-pin package version of the COP424, lacking the IN ports
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop425); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP425"); break;
+
+ default: CPU_GET_INFO_CALL(cop424); break;
+ }
+}
+
+CPU_GET_INFO( cop426 )
+{
+ // COP426 is a 20-pin package version of the COP424, with only L0-L7, G2-G3, D2-D3 ports
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop426); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP426"); break;
+
+ default: CPU_GET_INFO_CALL(cop424); break;
+ }
+}
+
+CPU_GET_INFO( cop404 )
+{
+ // COP404 is a ROMless version of the COP444, which can emulate a COP410C/COP411C, COP424C/COP425C, or a COP444C/COP445C
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "COP404"); break;
+
+ default: CPU_GET_INFO_CALL(cop444); break;
+ }
+}
+
+/* COP410 family */
+DEFINE_LEGACY_CPU_DEVICE(COP401, cop401);
+DEFINE_LEGACY_CPU_DEVICE(COP410, cop410);
+DEFINE_LEGACY_CPU_DEVICE(COP411, cop411);
+
+/* COP420 family */
+DEFINE_LEGACY_CPU_DEVICE(COP402, cop402);
+DEFINE_LEGACY_CPU_DEVICE(COP420, cop420);
+DEFINE_LEGACY_CPU_DEVICE(COP421, cop421);
+DEFINE_LEGACY_CPU_DEVICE(COP422, cop422);
+
+/* COP444 family */
+DEFINE_LEGACY_CPU_DEVICE(COP404, cop404);
+DEFINE_LEGACY_CPU_DEVICE(COP424, cop424);
+DEFINE_LEGACY_CPU_DEVICE(COP425, cop425);
+DEFINE_LEGACY_CPU_DEVICE(COP426, cop426);
+DEFINE_LEGACY_CPU_DEVICE(COP444, cop444);
+DEFINE_LEGACY_CPU_DEVICE(COP445, cop445);