summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2009-01-12 13:18:32 +0000
committer Curt Coder <curtcoder@mail.com>2009-01-12 13:18:32 +0000
commitde81d24aabab83a32d3ee724845b5e53d0108b69 (patch)
tree78d42c35470aa47666e50d5b76c73abfee48a05e /src
parentac0abd17066f0b9c95a64430be86c451c6ae6f32 (diff)
COP400 cpu core refactoring:
- added state table for the debugger - grouped all cpu types under a single makefile entry - removed duplicate code
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/cop400/420ops.c339
-rw-r--r--src/emu/cpu/cop400/440ops.c68
-rw-r--r--src/emu/cpu/cop400/cop400.c1651
-rw-r--r--src/emu/cpu/cop400/cop400.h114
-rw-r--r--src/emu/cpu/cop400/cop400op.c (renamed from src/emu/cpu/cop400/410ops.c)670
-rw-r--r--src/emu/cpu/cop400/cop410.c514
-rw-r--r--src/emu/cpu/cop400/cop420.c621
-rw-r--r--src/emu/cpu/cop400/cop440.c681
-rw-r--r--src/emu/cpu/cpu.mak50
-rw-r--r--src/mame/mame.mak14
10 files changed, 2124 insertions, 2598 deletions
diff --git a/src/emu/cpu/cop400/420ops.c b/src/emu/cpu/cop400/420ops.c
deleted file mode 100644
index 3809ab84707..00000000000
--- a/src/emu/cpu/cop400/420ops.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/***************************************************************************
-
- 420ops.c
-
- National Semiconductor COP420 Emulator.
-
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
-
-***************************************************************************/
-
-#define T cop400->t
-#define SC cop400->sc
-#define IL cop400->il
-
-#define PUSH(addr) { SC = SB; SB = SA; SA = addr; }
-#define POP() { PC = SA; SA = SB; SB = SC; }
-
-#include "410ops.c"
-
-#define IN_IN() (cop400->in_mask ? IN(COP400_PORT_IN) : 0)
-
-/* Timer Counter */
-
-static TIMER_CALLBACK( cop400_counter_tick )
-{
- cop400_state *cop400 = ptr;
-
- T++;
-
- if (T == 0)
- {
- cop400->skt_latch = 1;
-
- if (cop400->idle)
- {
- cop400->idle = 0;
- cop400->halt = 0;
- }
- }
-}
-
-/* IN Latches */
-
-static TIMER_CALLBACK( cop400_inil_tick )
-{
- cop400_state *cop400 = ptr;
- UINT8 in;
- int i;
-
- in = IN_IN();
-
- for (i = 0; i < 4; i++)
- {
- cop400->in[i] = (cop400->in[i] << 1) | BIT(in, i);
-
- if ((cop400->in[i] & 0x07) == 0x04) // 100
- {
- IL |= (1 << i);
- }
- }
-}
-
-/* Microbus */
-
-static TIMER_CALLBACK( cop400_microbus_tick )
-{
- cop400_state *cop400 = ptr;
- UINT8 in;
-
- in = IN_IN();
-
- if (!BIT(in, 2))
- {
- // chip select
-
- if (!BIT(in, 1))
- {
- // read strobe
-
- OUT_L(Q);
-
- cop400->microbus_int = 1;
- }
- else if (!BIT(in, 3))
- {
- // write strobe
-
- Q = IN_L();
-
- cop400->microbus_int = 0;
- }
- }
-}
-
-/* Arithmetic Instructions */
-
-/*
-
- Mnemonic: ADT
-
- Hex Code: 4A
- Binary: 0 1 0 0 1 0 1 0
-
- Data Flow: A + 10 -> A
-
- Description: Add Ten to A
-
-*/
-
-INSTRUCTION( adt )
-{
- A = (A + 10) & 0x0F;
-}
-
-/*
-
- Mnemonic: CASC
-
- Hex Code: 10
- Binary: 0 0 0 1 0 0 0 0
-
- Data Flow: ~A + RAM(B) + C -> A
- Carry -> C
-
- Skip Conditions: Carry
-
- Description: Complement and Add with Carry, Skip on Carry
-
-*/
-
-INSTRUCTION( casc )
-{
- A = (A ^ 0xF) + RAM_R(B) + C;
-
- if (A > 0xF)
- {
- C = 1;
- cop400->skip = 1;
- A &= 0xF;
- }
- else
- {
- C = 0;
- }
-}
-
-/* Transfer-of-Control Instructions */
-
-/*
-
- Mnemonic: RET
-
- Hex Code: 48
- Binary: 0 1 0 0 1 0 0 0
-
- Data Flow: SC -> SB -> SA -> PC
-
- Description: Return from Subroutine, restore Skip logic
-
-*/
-
-INSTRUCTION( cop420_ret )
-{
- POP();
- cop400->skip = cop400->last_skip;
-}
-
-/* Memory Reference Instructions */
-
-/*
-
- Mnemonic: CQMA
-
- Hex Code: 33 2C
- Binary: 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0
-
- Data Flow: Q7:4 -> RAM(B)
- Q3:0 -> A
-
- Description: Copy Q to RAM, A
-
-*/
-
-INSTRUCTION( cqma )
-{
- RAM_W(B, Q >> 4);
- A = Q & 0xF;
-}
-
-/*
-
- Mnemonic: LDD
-
- Operand: r, d
- Hex Code: 23 --
- Binary: 0 0 1 0 0 0 1 1 0 0 r1 r0 d3 d2 d1 d0
-
- Data Flow: RAM(r,d) -> A
-
- Description: Load A with RAM pointed to directly by r,d
-
-*/
-
-INSTRUCTION( ldd )
-{
- UINT8 rd = opcode & 0x3f;
-
- A = RAM_R(rd);
-}
-
-/* Register Reference Instructions */
-
-/*
-
- Mnemonic: XABR
-
- Hex Code: 12
- Binary: 0 0 0 1 0 0 1 0
-
- Data Flow: A <-> Br(0,0 -> A3,A2)
-
- Description: Exchange A with Br
-
-*/
-
-INSTRUCTION( xabr )
-{
- UINT8 Br = A & 0x03;
- UINT8 Bd = B & 0x0f;
-
- A = B >> 4;
- B = (Br << 4) + Bd;
-}
-
-/* Test Instructions */
-
-/*
-
- Mnemonic: SKT
-
- Hex Code: 41
- Binary: 0 1 0 0 0 0 0 1
-
- Skip Conditions: A time-base counter carry has occurred since last test
-
- Description: Skip on Timer
-
-*/
-
-INSTRUCTION( skt )
-{
- if (cop400->skt_latch)
- {
- cop400->skt_latch = 0;
- cop400->skip = 1;
- }
-}
-
-/* Input/Output Instructions */
-
-/*
-
- Mnemonic: ININ
-
- Hex Code: 33 28
- Binary:
-
- Data Flow: IN -> A
-
- Description: Input IN Inputs to A
-
-*/
-
-INSTRUCTION( inin )
-{
- A = IN_IN();
-}
-
-/*
-
- Processor: COP402M
-
- Mnemonic: ININ
-
- Hex Code: 33 28
- Binary:
-
- Data Flow: IN -> A, A1 = "1"
-
- Description: Input IN Inputs to A
-
-*/
-
-INSTRUCTION( cop402m_inin )
-{
- A = IN_IN() | 0x02;
-}
-
-/*
-
- Mnemonic: INIL
-
- Hex Code: 33 29
- Binary:
-
- Data Flow: IL3,CKO,"0",IL0 -> A
-
- Description: Input IL Latches to A
-
-*/
-
-INSTRUCTION( inil )
-{
- A = (IL & 0x09) | IN_CKO() << 2;
-
- IL = 0;
-}
-
-/*
-
- Mnemonic: OGI
-
- Operand: y
- Hex Code: 33 5-
- Binary: 0 0 1 1 0 0 1 1 0 1 0 1 y3 y2 y1 y0
-
- Data Flow: y -> G
-
- Description: Output to G Ports Immediate
-
-*/
-
-INSTRUCTION( ogi )
-{
- UINT4 y = opcode & 0x0f;
-
- WRITE_G(cop400, y);
-}
diff --git a/src/emu/cpu/cop400/440ops.c b/src/emu/cpu/cop400/440ops.c
deleted file mode 100644
index 7934de01090..00000000000
--- a/src/emu/cpu/cop400/440ops.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
-
- 440ops.c
-
- National Semiconductor COP440 Emulator.
-
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
-
-***************************************************************************/
-
-#include "420ops.c"
-
-/*
-
- Mnemonic: CAMT
-
- Hex Code: 33 3F
- Binary:
-
- Data Flow: A -> T7:4
- RAM(B) -> T3:0
-
- Description: Copy A, RAM to T
-
-*/
-
-INSTRUCTION( camt )
-{
- T = (A << 4) | RAM_R(B);
-}
-
-/*
-
- Mnemonic: CTMA
-
- Hex Code: 33 2F
- Binary:
-
- Data Flow: T7:4 -> RAM(B)
- T3:0 -> A
-
- Description: Copy T to RAM, A
-
-*/
-
-INSTRUCTION( ctma )
-{
- RAM_W(B, T >> 4);
- A = T & 0x0f;
-}
-
-/*
-
- Mnemonic: IT
-
- Hex Code: 33 39
- Binary: 0 0 1 1 0 0 1 1 0 0 1 1 1 0 0 1
-
- Description: IDLE till Timer Overflows then Continues
-
-*/
-
-INSTRUCTION( it )
-{
- cop400->halt = 1;
- cop400->idle = 1;
-}
diff --git a/src/emu/cpu/cop400/cop400.c b/src/emu/cpu/cop400/cop400.c
new file mode 100644
index 00000000000..deaa3c1c8cd
--- /dev/null
+++ b/src/emu/cpu/cop400/cop400.c
@@ -0,0 +1,1651 @@
+/***************************************************************************
+
+ 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 "driver.h"
+#include "cpuintrf.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;
+
+ const address_space *program;
+ const address_space *data;
+ const address_space *io;
+
+ /* 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) */
+
+ /* 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 */
+ cpu_state_table state_table; /* state table */
+
+ const cop400_opcode_map *opcode_map;
+
+ /* timers */
+ emu_timer *serial_timer;
+ emu_timer *counter_timer;
+ emu_timer *inil_timer;
+ emu_timer *microbus_timer;
+};
+
+struct _cop400_opcode_map {
+ unsigned cycles;
+ void (*function) (cop400_state *cpustate, UINT8 opcode);
+};
+
+/***************************************************************************
+ CPU STATE DESCRIPTION
+***************************************************************************/
+
+#define COP400_STATE_ENTRY(_name, _format, _member, _datamask, _featuremask, _flags) \
+ CPU_STATE_ENTRY(COP400_##_name, #_name, _format, cop400_state, _member, _datamask, _featuremask, _flags)
+
+#define COP410_STATE_ENTRY(_name, _format, _member, _datamask, _flags) \
+ COP400_STATE_ENTRY(_name, _format, _member, _datamask, COP410_FEATURE | COP420_FEATURE | COP444_FEATURE | COP440_FEATURE, _flags)
+
+#define COP420_STATE_ENTRY(_name, _format, _member, _datamask, _flags) \
+ COP400_STATE_ENTRY(_name, _format, _member, _datamask, COP420_FEATURE | COP444_FEATURE | COP440_FEATURE, _flags)
+
+#define COP444_STATE_ENTRY(_name, _format, _member, _datamask, _flags) \
+ COP400_STATE_ENTRY(_name, _format, _member, _datamask, COP444_FEATURE | COP440_FEATURE, _flags)
+
+#define COP440_STATE_ENTRY(_name, _format, _member, _datamask, _flags) \
+ COP400_STATE_ENTRY(_name, _format, _member, _datamask, COP440_FEATURE, _flags)
+
+static const cpu_state_entry state_array[] =
+{
+ COP410_STATE_ENTRY(GENPC, "%03X", pc, 0xfff, CPUSTATE_NOSHOW)
+ COP410_STATE_ENTRY(GENPCBASE, "%03X", prevpc, 0xfff, CPUSTATE_NOSHOW)
+ COP440_STATE_ENTRY(GENSP, "%01X", n, 0x3, CPUSTATE_NOSHOW)
+
+ COP410_STATE_ENTRY(PC, "%03X", pc, 0xfff, 0)
+
+ COP400_STATE_ENTRY(SA, "%03X", sa, 0xfff, COP410_FEATURE | COP420_FEATURE | COP444_FEATURE, 0)
+ COP400_STATE_ENTRY(SB, "%03X", sb, 0xfff, COP410_FEATURE | COP420_FEATURE | COP444_FEATURE, 0)
+ COP400_STATE_ENTRY(SC, "%03X", sc, 0xfff, COP420_FEATURE | COP444_FEATURE, 0)
+ COP440_STATE_ENTRY(N, "%01X", n, 0x3, 0)
+
+ COP410_STATE_ENTRY(A, "%01X", a, 0xf, 0)
+ COP410_STATE_ENTRY(B, "%02X", b, 0xff, 0)
+ COP410_STATE_ENTRY(C, "%1u", c, 0x1, 0)
+
+ COP410_STATE_ENTRY(EN, "%01X", en, 0xf, 0)
+ COP410_STATE_ENTRY(G, "%01X", g, 0xf, 0)
+ COP440_STATE_ENTRY(H, "%01X", h, 0xf, 0)
+ COP410_STATE_ENTRY(Q, "%02X", q, 0xff, 0)
+ COP440_STATE_ENTRY(R, "%02X", r, 0xff, 0)
+
+ COP410_STATE_ENTRY(SIO, "%01X", sio, 0xf, 0)
+ COP410_STATE_ENTRY(SKL, "%1u", skl, 0x1, 0)
+
+ COP420_STATE_ENTRY(T, "%02X", t, 0xff, 0)
+};
+
+static const cpu_state_table state_table_template =
+{
+ NULL, /* pointer to the base of state (offsets are relative to this) */
+ 0, /* subtype this table refers to */
+ ARRAY_LENGTH(state_array), /* number of entries */
+ state_array /* array of entries */
+};
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+#define ROM(a) memory_decrypted_read_byte(cpustate->program, a)
+#define RAM_R(a) memory_read_byte_8le(cpustate->data, a)
+#define RAM_W(a, v) memory_write_byte_8le(cpustate->data, a, v)
+#define IN(a) memory_read_byte_8le(cpustate->io, a)
+#define OUT(a, v) memory_write_byte_8le(cpustate->io, 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 void PUSH(cop400_state *cpustate, UINT16 data)
+{
+ if (cpustate->state_table.subtypemask != COP410_FEATURE)
+ {
+ SC = SB;
+ }
+
+ SB = SA;
+ SA = data;
+}
+
+INLINE void POP(cop400_state *cpustate)
+{
+ PC = SA;
+ SA = SB;
+
+ if (cpustate->state_table.subtypemask != 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 = 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 = 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 = 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 = 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 cop400_init(const device_config *device, UINT8 g_mask, UINT8 d_mask, UINT8 in_mask, int has_counter, int has_inil)
+{
+ cop400_state *cpustate = device->token;
+
+ cpustate->intf = (cop400_interface *) device->static_config;
+
+ /* find address spaces */
+
+ cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
+ cpustate->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
+ cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
+
+ /* set output pin masks */
+
+ cpustate->g_mask = g_mask;
+ cpustate->d_mask = d_mask;
+ cpustate->in_mask = in_mask;
+
+ /* set clock divider */
+
+ device_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cpustate->intf->cki);
+
+ /* allocate serial timer */
+
+ cpustate->serial_timer = timer_alloc(device->machine, serial_tick, cpustate);
+ timer_adjust_periodic(cpustate->serial_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
+
+ /* allocate counter timer */
+
+ if (has_counter)
+ {
+ cpustate->counter_timer = timer_alloc(device->machine, counter_tick, cpustate);
+ timer_adjust_periodic(cpustate->counter_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16 / 4));
+ }
+
+ /* allocate IN latch timer */
+
+ if (has_inil)
+ {
+ cpustate->inil_timer = timer_alloc(device->machine, inil_tick, cpustate);
+ timer_adjust_periodic(cpustate->inil_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
+ }
+
+ /* allocate Microbus timer */
+
+ if (cpustate->intf->microbus == COP400_MICROBUS_ENABLED)
+ {
+ cpustate->microbus_timer = timer_alloc(device->machine, microbus_tick, cpustate);
+ timer_adjust_periodic(cpustate->microbus_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
+ }
+
+ /* register for state saving */
+
+ state_save_register_device_item(device, 0, cpustate->pc);
+ state_save_register_device_item(device, 0, cpustate->prevpc);
+ state_save_register_device_item(device, 0, cpustate->n);
+ state_save_register_device_item(device, 0, cpustate->sa);
+ state_save_register_device_item(device, 0, cpustate->sb);
+ state_save_register_device_item(device, 0, cpustate->sc);
+ state_save_register_device_item(device, 0, cpustate->a);
+ state_save_register_device_item(device, 0, cpustate->b);
+ state_save_register_device_item(device, 0, cpustate->c);
+ state_save_register_device_item(device, 0, cpustate->g);
+ state_save_register_device_item(device, 0, cpustate->h);
+ state_save_register_device_item(device, 0, cpustate->q);
+ state_save_register_device_item(device, 0, cpustate->r);
+ state_save_register_device_item(device, 0, cpustate->en);
+ state_save_register_device_item(device, 0, cpustate->sio);
+ state_save_register_device_item(device, 0, cpustate->skl);
+ state_save_register_device_item(device, 0, cpustate->t);
+ state_save_register_device_item(device, 0, cpustate->skip);
+ state_save_register_device_item(device, 0, cpustate->skip_lbi);
+ state_save_register_device_item(device, 0, cpustate->skt_latch);
+ state_save_register_device_item(device, 0, cpustate->si);
+ state_save_register_device_item(device, 0, cpustate->last_skip);
+ state_save_register_device_item_array(device, 0, cpustate->in);
+ state_save_register_device_item(device, 0, cpustate->microbus_int);
+ state_save_register_device_item(device, 0, cpustate->halt);
+ state_save_register_device_item(device, 0, cpustate->idle);
+}
+
+static void cop410_init_opcodes(const device_config *device)
+{
+ cop400_state *cpustate = device->token;
+ int i;
+
+ /* set up the state table */
+
+ cpustate->state_table = state_table_template;
+ cpustate->state_table.baseptr = cpustate;
+ cpustate->state_table.subtypemask = COP410_FEATURE;
+
+ /* 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=0; i<256; 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(const device_config *device)
+{
+ cop400_state *cpustate = device->token;
+ int i;
+
+ /* set up the state table */
+
+ cpustate->state_table = state_table_template;
+ cpustate->state_table.baseptr = cpustate;
+ cpustate->state_table.subtypemask = COP420_FEATURE;
+
+ /* 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=0; i<256; 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(const device_config *device)
+{
+ cop400_state *cpustate = device->token;
+ int i;
+
+ /* set up the state table */
+
+ cpustate->state_table = state_table_template;
+ cpustate->state_table.baseptr = cpustate;
+ cpustate->state_table.subtypemask = COP444_FEATURE;
+
+ /* 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=0; i<256; 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 = device->token;
+
+ 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 = device->token;
+
+ UINT8 opcode;
+
+ cpustate->icount = cycles;
+
+ 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))
+ {
+ void *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)
+ {
+ void *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);
+
+ return cycles - cpustate->icount;
+}
+
+/***************************************************************************
+ ADDRESS MAPS
+***************************************************************************/
+
+static ADDRESS_MAP_START( program_512b, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x1ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( program_1kb, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( program_2kb, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x000, 0x7ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_32b, ADDRESS_SPACE_DATA, 8 )
+ AM_RANGE(0x00, 0x1f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_64b, ADDRESS_SPACE_DATA, 8 )
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_128b, ADDRESS_SPACE_DATA, 8 )
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( data_160b, ADDRESS_SPACE_DATA, 8 )
+ AM_RANGE(0x00, 0x9f) AM_RAM
+ADDRESS_MAP_END
+
+/***************************************************************************
+ VALIDITY CHECKS
+***************************************************************************/
+
+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;
+}
+
+/***************************************************************************
+ GENERAL CONTEXT ACCESS
+***************************************************************************/
+
+static CPU_SET_INFO( cop400 )
+{
+ /* nothing to set */
+}
+
+static CPU_GET_INFO( cop400 )
+{
+ cop400_state *cpustate = (device != NULL) ? device->token : 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 CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 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 CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: /* set per-core */ break;
+ case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 8; /* really 4 */ break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_DATA: /* set per-core */ break;
+ case CPUINFO_INT_ADDRBUS_SHIFT_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH_IO: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_IO: info->i = 9; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT_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;
+
+ /* --- the following bits of info are returned as pointers --- */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+ case CPUINFO_PTR_STATE_TABLE: info->state_table = &cpustate->state_table; break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: /* set per-core */ break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: /* set per-core */ break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "COP400"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
+ }
+}
+
+/***************************************************************************
+ CPU-SPECIFIC CONTEXT ACCESS
+***************************************************************************/
+
+CPU_GET_INFO( cop410 )
+{
+ cop400_state *cpustate = (device != NULL) ? device->token : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 9; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_512b); break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_32b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "COP410"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s,
+ "%c%c",
+ cpustate->c ? 'C' : '.',
+ cpustate->skl ? 'S' : '.'); 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 CPUINFO_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_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;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_1kb); break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_64b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_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 CPUINFO_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 CPUINFO_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_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;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 11; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_2kb); break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_128b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_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 CPUINFO_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 CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 6; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(program_1kb); break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME(data_64b); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_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 CPUINFO_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 CPUINFO_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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = NULL; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "COP404"); break;
+
+ default: CPU_GET_INFO_CALL(cop444); break;
+ }
+}
diff --git a/src/emu/cpu/cop400/cop400.h b/src/emu/cpu/cop400/cop400.h
index fe6ee670147..8d4ba60bbae 100644
--- a/src/emu/cpu/cop400/cop400.h
+++ b/src/emu/cpu/cop400/cop400.h
@@ -14,6 +14,35 @@
#ifndef __COP400__
#define __COP400__
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* register access indexes */
+enum
+{
+ COP400_PC,
+ COP400_SA,
+ COP400_SB,
+ COP400_SC,
+ COP400_N,
+ COP400_A,
+ COP400_B,
+ COP400_C,
+ COP400_G,
+ COP400_H,
+ COP400_Q,
+ COP400_R,
+ COP400_EN,
+ COP400_SIO,
+ COP400_SKL,
+ COP400_T,
+ COP400_GENPC = REG_GENPC,
+ COP400_GENPCBASE = REG_GENPCBASE,
+ COP400_GENSP = REG_GENSP
+};
+
+/* special I/O space ports */
enum
{
COP400_PORT_L = 0x100,
@@ -27,25 +56,23 @@ enum
COP400_PORT_CKO
};
+/* input lines */
enum
{
- COP400_PC = 1,
- COP400_A,
- COP400_B,
- COP400_C,
- COP400_G,
- COP400_H,
- COP400_R,
- COP400_EN,
- COP400_Q,
- COP400_SA,
- COP400_SB,
- COP400_SC,
- COP400_SIO,
- COP400_SKL,
- COP400_T
+ /* COP420 */
+ COP400_IN0 = 0,
+ COP400_IN1,
+ COP400_IN2,
+ COP400_IN3,
+
+ /* COP404 */
+ COP400_MB,
+ COP400_DUAL,
+ COP400_SEL10,
+ COP400_SEL20
};
+/* CKI bonding options */
typedef enum _cop400_cki_bond cop400_cki_bond;
enum _cop400_cki_bond {
COP400_CKI_DIVISOR_4 = 4,
@@ -54,6 +81,7 @@ enum _cop400_cki_bond {
COP400_CKI_DIVISOR_32 = 32
};
+/* CKO bonding options */
typedef enum _cop400_cko_bond cop400_cko_bond;
enum _cop400_cko_bond {
COP400_CKO_OSCILLATOR_OUTPUT = 0,
@@ -63,6 +91,7 @@ enum _cop400_cko_bond {
COP400_CKO_GENERAL_PURPOSE_INPUT
};
+/* microbus bonding options */
typedef enum _cop400_microbus cop400_microbus;
enum _cop400_microbus {
COP400_MICROBUS_DISABLED = 0,
@@ -79,37 +108,42 @@ struct _cop400_interface
};
#define COP400_INTERFACE(name) const cop400_interface (name) =
-/*
+/***************************************************************************
+ MACROS
+***************************************************************************/
- Prefix Temperature Range
+#define CPU_COP401 CPU_GET_INFO_NAME( cop401 )
+#define CPU_COP410 CPU_GET_INFO_NAME( cop410 )
+#define CPU_COP411 CPU_GET_INFO_NAME( cop411 )
- COP4xx 0C to 70C
- COP3xx -40C to +85C
- COP2xx -55C to +125C
+#define CPU_COP402 CPU_GET_INFO_NAME( cop402 )
+#define CPU_COP420 CPU_GET_INFO_NAME( cop420 )
+#define CPU_COP421 CPU_GET_INFO_NAME( cop421 )
+#define CPU_COP422 CPU_GET_INFO_NAME( cop422 )
-*/
+#define CPU_COP404 CPU_GET_INFO_NAME( cop404 )
+#define CPU_COP424 CPU_GET_INFO_NAME( cop424 )
+#define CPU_COP425 CPU_GET_INFO_NAME( cop425 )
+#define CPU_COP426 CPU_GET_INFO_NAME( cop426 )
+#define CPU_COP444 CPU_GET_INFO_NAME( cop444 )
+#define CPU_COP445 CPU_GET_INFO_NAME( cop445 )
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
-/* COP 41x */
+/* COP410 family */
extern CPU_GET_INFO( cop401 );
extern CPU_GET_INFO( cop410 );
extern CPU_GET_INFO( cop411 );
-#define CPU_COP401 CPU_GET_INFO_NAME( cop401 )
-#define CPU_COP410 CPU_GET_INFO_NAME( cop410 )
-#define CPU_COP411 CPU_GET_INFO_NAME( cop411 )
-
-/* COP 42x */
+/* COP420 family */
extern CPU_GET_INFO( cop402 );
extern CPU_GET_INFO( cop420 );
extern CPU_GET_INFO( cop421 );
extern CPU_GET_INFO( cop422 );
-#define CPU_COP402 CPU_GET_INFO_NAME( cop402 )
-#define CPU_COP420 CPU_GET_INFO_NAME( cop420 )
-#define CPU_COP421 CPU_GET_INFO_NAME( cop421 )
-#define CPU_COP422 CPU_GET_INFO_NAME( cop422 )
-
-/* COP 44x */
+/* COP444 family */
extern CPU_GET_INFO( cop404 );
extern CPU_GET_INFO( cop424 );
extern CPU_GET_INFO( cop425 );
@@ -117,15 +151,9 @@ extern CPU_GET_INFO( cop426 );
extern CPU_GET_INFO( cop444 );
extern CPU_GET_INFO( cop445 );
-#define CPU_COP404 CPU_GET_INFO_NAME( cop404 )
-#define CPU_COP424 CPU_GET_INFO_NAME( cop424 )
-#define CPU_COP425 CPU_GET_INFO_NAME( cop425 )
-#define CPU_COP426 CPU_GET_INFO_NAME( cop426 )
-#define CPU_COP444 CPU_GET_INFO_NAME( cop444 )
-#define CPU_COP445 CPU_GET_INFO_NAME( cop445 )
-
-CPU_DISASSEMBLE( cop410 );
-CPU_DISASSEMBLE( cop420 );
-CPU_DISASSEMBLE( cop444 );
+/* disassemblers */
+extern CPU_DISASSEMBLE( cop410 );
+extern CPU_DISASSEMBLE( cop420 );
+extern CPU_DISASSEMBLE( cop444 );
#endif /* __COP400__ */
diff --git a/src/emu/cpu/cop400/410ops.c b/src/emu/cpu/cop400/cop400op.c
index dd667ccdad2..8d5bd424733 100644
--- a/src/emu/cpu/cop400/410ops.c
+++ b/src/emu/cpu/cop400/cop400op.c
@@ -1,227 +1,17 @@
/***************************************************************************
- 410ops.c
+ cop400op.c
- National Semiconductor COP410 Emulator.
+ National Semiconductor COP400 Emulator.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
-#define UINT1 UINT8
-#define UINT4 UINT8
-#define UINT6 UINT8
-#define UINT10 UINT16
-
-typedef struct _cop400_state cop400_state;
-struct _cop400_state
-{
- const cop400_interface *intf;
-
- const address_space *program;
- const address_space *data;
- const address_space *io;
-
- /* registers */
- UINT10 pc; /* 11-bit ROM address program counter */
- UINT10 prevpc; /* previous value of program counter */
- UINT4 a; /* 4-bit accumulator */
- UINT8 b; /* 5/6/7-bit RAM address register */
- UINT1 c; /* 1-bit carry register */
- UINT4 en; /* 4-bit enable register */
- UINT4 g; /* 4-bit general purpose I/O port */
- UINT8 q; /* 8-bit latch for L port */
- UINT10 sa, sb, sc; /* subroutine save registers */
- UINT4 sio; /* 4-bit shift register and counter */
- UINT1 skl; /* 1-bit latch for SK output */
- UINT8 si; /* serial input */
- UINT4 h; /* 4-bit general purpose I/O port (COP440 only) */
- UINT8 r; /* 8-bit general purpose I/O port (COP440 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 */
- UINT4 il; /* IN latch */
- UINT4 in[4]; /* IN port shift register */
-
- /* 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 device_config *device;
-
- /* timers */
- emu_timer *serial_timer;
- emu_timer *counter_timer;
- emu_timer *inil_timer;
- emu_timer *microbus_timer;
-};
-
-/* The opcode table now is a combination of cycle counts and function pointers */
-typedef struct {
- unsigned cycles;
- void (*function) (cop400_state *cop400, UINT8 opcode);
-} s_opcode;
-
-#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(cop400_state *cop400, UINT8 opcode)
-
-#define ROM(a) memory_decrypted_read_byte(cop400->program, a)
-#define RAM_R(a) memory_read_byte_8le(cop400->data, a)
-#define RAM_W(a, v) memory_write_byte_8le(cop400->data, a, v)
-#define IN(a) memory_read_byte_8le(cop400->io, a)
-#define OUT(a, v) memory_write_byte_8le(cop400->io, a, v)
-
-#define A cop400->a
-#define B cop400->b
-#define C cop400->c
-#define G cop400->g
-#define Q cop400->q
-#define EN cop400->en
-#define SA cop400->sa
-#define SB cop400->sb
-#define SIO cop400->sio
-#define SKL cop400->skl
-#define PC cop400->pc
-#define prevPC cop400->prevpc
-
-#define IN_G() IN(COP400_PORT_G)
-#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 OUT_G(A) OUT(COP400_PORT_G, (A) & cop400->g_mask)
-#define OUT_L(A) OUT(COP400_PORT_L, (A))
-#define OUT_D(A) OUT(COP400_PORT_D, (A) & cop400->d_mask)
-#define OUT_SK(A) OUT(COP400_PORT_SK, (A))
-#define OUT_SO(A) OUT(COP400_PORT_SIO, (A))
-
-#ifndef PUSH
-#define PUSH(addr) { SB = SA; SA = addr; }
-#define POP() { PC = SA; SA = SB; }
-#endif
-
-/* Serial I/O */
-
-static TIMER_CALLBACK( cop400_serial_tick )
-{
- cop400_state *cop400 = 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
-
- cop400->si <<= 1;
- cop400->si = (cop400->si & 0x0e) | IN_SI();
-
- if ((cop400->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;
- }
-}
-
-INLINE void WRITE_Q(cop400_state *cop400, UINT8 data)
-{
- Q = data;
-
- if (BIT(EN, 2))
- {
- OUT_L(Q);
- }
-}
-
-INLINE void WRITE_G(cop400_state *cop400, UINT8 data)
-{
- if (cop400->intf->microbus == COP400_MICROBUS_ENABLED)
- {
- data = (data & 0x0e) | cop400->microbus_int;
- }
-
- G = data;
-
- OUT_G(G);
-}
-
-INSTRUCTION(illegal)
-{
- logerror("COP400: PC = %04x, Illegal opcode = %02x\n", PC-1, ROM(PC-1));
-}
-
-/* Arithmetic Instructions */
+/***************************************************************************
+ ARITHMETIC INSTRUCTIONS
+***************************************************************************/
/*
@@ -239,14 +29,14 @@ INSTRUCTION(illegal)
*/
-INSTRUCTION(asc)
+INSTRUCTION( asc )
{
A = A + C + RAM_R(B);
if (A > 0xF)
{
C = 1;
- cop400->skip = 1;
+ cpustate->skip = 1;
A &= 0xF;
}
else
@@ -291,13 +81,13 @@ INSTRUCTION( add )
INSTRUCTION( aisc )
{
- UINT4 y = opcode & 0x0f;
+ UINT8 y = opcode & 0x0f;
A = A + y;
if (A > 0x0f)
{
- cop400->skip = 1;
+ cpustate->skip = 1;
A &= 0xF;
}
}
@@ -408,7 +198,59 @@ INSTRUCTION( xor )
A = A ^ RAM_R(B);
}
-/* Transfer-of-Control Instructions */
+/*
+
+ Mnemonic: ADT
+
+ Hex Code: 4A
+ Binary: 0 1 0 0 1 0 1 0
+
+ Data Flow: A + 10 -> A
+
+ Description: Add Ten to A
+
+*/
+
+INSTRUCTION( adt )
+{
+ A = (A + 10) & 0x0F;
+}
+
+/*
+
+ Mnemonic: CASC
+
+ Hex Code: 10
+ Binary: 0 0 0 1 0 0 0 0
+
+ Data Flow: ~A + RAM(B) + C -> A
+ Carry -> C
+
+ Skip Conditions: Carry
+
+ Description: Complement and Add with Carry, Skip on Carry
+
+*/
+
+INSTRUCTION( casc )
+{
+ A = (A ^ 0xF) + RAM_R(B) + C;
+
+ if (A > 0xF)
+ {
+ C = 1;
+ cpustate->skip = 1;
+ A &= 0xF;
+ }
+ else
+ {
+ C = 0;
+ }
+}
+
+/***************************************************************************
+ TRANSFER-OF-CONTROL INSTRUCTIONS
+***************************************************************************/
/*
@@ -417,7 +259,7 @@ INSTRUCTION( xor )
Hex Code: FF
Binary: 1 1 1 1 1 1 1 1
- Data Flow: ROM(PC9:8,A,M) -> PC7:0
+ Data Flow: ROM(PC10:8,A,M) -> PC7:0
Description: Jump Indirect
@@ -425,8 +267,8 @@ INSTRUCTION( xor )
INSTRUCTION( jid )
{
- UINT16 addr = (PC & 0x300) | (A << 4) | RAM_R(B);
- PC = (PC & 0x300) | ROM(addr);
+ UINT16 addr = (PC & 0x700) | (A << 4) | RAM_R(B);
+ PC = (PC & 0x700) | ROM(addr);
}
/*
@@ -435,7 +277,7 @@ INSTRUCTION( jid )
Operand: a
Hex Code: 6- --
- Binary: 0 1 1 0 0 0 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
+ Binary: 0 1 1 0 0 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
Data Flow: a -> PC
@@ -445,7 +287,7 @@ INSTRUCTION( jid )
INSTRUCTION( jmp )
{
- UINT16 a = ((opcode & 0x03) << 8) | ROM(PC);
+ UINT16 a = ((opcode & 0x07) << 8) | ROM(PC);
PC = a;
}
@@ -472,23 +314,23 @@ INSTRUCTION( jmp )
INSTRUCTION( jp )
{
- UINT4 page = PC >> 6;
+ UINT8 page = PC >> 6;
if (page == 2 || page == 3)
{
UINT8 a = opcode & 0x7f;
- PC = (PC & 0x380) | a;
+ PC = (PC & 0x780) | a;
}
else if ((opcode & 0xc0) == 0xc0)
{
UINT8 a = opcode & 0x3f;
- PC = (PC & 0x3c0) | a;
+ PC = (PC & 0x7c0) | a;
}
else
{
// JSRP
UINT8 a = opcode & 0x3f;
- PUSH(PC);
+ PUSH(cpustate, PC);
PC = 0x80 | a;
}
}
@@ -499,7 +341,7 @@ INSTRUCTION( jp )
Operand: a
Hex Code: 6- --
- Binary: 0 1 1 0 1 0 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
+ Binary: 0 1 1 0 1 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
Data Flow: PC + 1 -> SA -> SB -> SC
a -> PC
@@ -510,9 +352,9 @@ INSTRUCTION( jp )
INSTRUCTION( jsr )
{
- UINT16 a = ((opcode & 0x03) << 8) | ROM(PC);
+ UINT16 a = ((opcode & 0x07) << 8) | ROM(PC);
- PUSH(PC + 1);
+ PUSH(cpustate, PC + 1);
PC = a;
}
@@ -531,7 +373,28 @@ INSTRUCTION( jsr )
INSTRUCTION( ret )
{
- POP();
+ POP(cpustate);
+}
+
+/*
+
+ Processor: COP420
+
+ Mnemonic: RET
+
+ Hex Code: 48
+ Binary: 0 1 0 0 1 0 0 0
+
+ Data Flow: SC -> SB -> SA -> PC
+
+ Description: Return from Subroutine, restore Skip logic
+
+*/
+
+INSTRUCTION( cop420_ret )
+{
+ POP(cpustate);
+ cpustate->skip = cpustate->last_skip;
}
/*
@@ -551,8 +414,8 @@ INSTRUCTION( ret )
INSTRUCTION( retsk )
{
- POP();
- cop400->skip = 1;
+ POP(cpustate);
+ cpustate->skip = 1;
}
/*
@@ -570,10 +433,29 @@ INSTRUCTION( retsk )
INSTRUCTION( halt )
{
- cop400->halt = 1;
+ cpustate->halt = 1;
}
-/* Memory Reference Instructions */
+/*
+
+ Mnemonic: IT
+
+ Hex Code: 33 39
+ Binary: 0 0 1 1 0 0 1 1 0 0 1 1 1 0 0 1
+
+ Description: IDLE till Timer Overflows then Continues
+
+*/
+
+INSTRUCTION( it )
+{
+ cpustate->halt = 1;
+ cpustate->idle = 1;
+}
+
+/***************************************************************************
+ MEMORY REFERENCE INSTRUCTIONS
+***************************************************************************/
/*
@@ -624,11 +506,11 @@ INSTRUCTION( camq )
UINT8 data = (A << 4) | RAM_R(B);
- WRITE_Q(cop400, data);
+ WRITE_Q(cpustate, data);
#ifdef CAMQ_BUG
- WRITE_Q(cop400, 0x3c);
- WRITE_Q(cop400, data);
+ WRITE_Q(cpustate, 0x3c);
+ WRITE_Q(cpustate, data);
#endif
}
@@ -662,7 +544,7 @@ INSTRUCTION( ld )
Hex Code: BF
Binary: 1 0 1 1 1 1 1 1
- Data Flow: ROM(PC9:8,A,M) -> Q
+ Data Flow: ROM(PC10:8,A,M) -> Q
SB -> SC
Description: Load Q Indirect
@@ -671,10 +553,10 @@ INSTRUCTION( ld )
INSTRUCTION( lqid )
{
- PUSH(PC);
- PC = (PC & 0x300) | (A << 4) | RAM_R(B);
- WRITE_Q(cop400, ROM(PC));
- POP();
+ PUSH(cpustate, PC);
+ PC = (PC & 0x700) | (A << 4) | RAM_R(B);
+ WRITE_Q(cpustate, ROM(PC));
+ POP(cpustate);
}
/*
@@ -760,13 +642,13 @@ INSTRUCTION( smb3 ) { RAM_W(B, RAM_R(B) | 0x8); }
INSTRUCTION( stii )
{
- UINT4 y = opcode & 0x0f;
+ UINT8 y = opcode & 0x0f;
UINT16 Bd;
RAM_W(B, y);
Bd = ((B & 0x0f) + 1) & 0x0f;
- B = (B & 0x30) + Bd;
+ B = (B & 0x70) + Bd;
}
/*
@@ -786,7 +668,7 @@ INSTRUCTION( stii )
INSTRUCTION( x )
{
- UINT4 r = opcode & 0x30;
+ UINT8 r = opcode & 0x30;
UINT8 t = RAM_R(B);
RAM_W(B, A);
@@ -801,7 +683,7 @@ INSTRUCTION( x )
Operand: r,d
Hex Code: 23 --
- Binary: 0 0 1 0 0 0 1 1 1 0 r1 r0 d3 d2 d1 d0
+ Binary: 0 0 1 0 0 0 1 1 1 r2 r1 r0 d3 d2 d1 d0
Data Flow: RAM(r,d) <-> A
@@ -811,7 +693,7 @@ INSTRUCTION( x )
INSTRUCTION( xad )
{
- UINT8 rd = opcode & 0x3f;
+ UINT8 rd = opcode & 0x7f;
UINT8 t = A;
A = RAM_R(rd);
@@ -840,7 +722,7 @@ INSTRUCTION( xad )
INSTRUCTION( xds )
{
UINT8 t, Bd;
- UINT4 r = opcode & 0x30;
+ UINT8 r = opcode & 0x30;
t = RAM_R(B);
RAM_W(B, A);
@@ -851,7 +733,7 @@ INSTRUCTION( xds )
B = B ^ r;
- if (Bd == 0x0f) cop400->skip = 1;
+ if (Bd == 0x0f) cpustate->skip = 1;
}
/*
@@ -875,7 +757,7 @@ INSTRUCTION( xds )
INSTRUCTION( xis )
{
UINT8 t, Bd;
- UINT4 r = opcode & 0x30;
+ UINT8 r = opcode & 0x30;
t = RAM_R(B);
RAM_W(B, A);
@@ -886,10 +768,91 @@ INSTRUCTION( xis )
B = B ^ r;
- if (Bd == 0x00) cop400->skip = 1;
+ if (Bd == 0x00) cpustate->skip = 1;
}
-/* Register Reference Instructions */
+/*
+
+ Mnemonic: CQMA
+
+ Hex Code: 33 2C
+ Binary: 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0
+
+ Data Flow: Q7:4 -> RAM(B)
+ Q3:0 -> A
+
+ Description: Copy Q to RAM, A
+
+*/
+
+INSTRUCTION( cqma )
+{
+ RAM_W(B, Q >> 4);
+ A = Q & 0xF;
+}
+
+/*
+
+ Mnemonic: LDD
+
+ Operand: r, d
+ Hex Code: 23 --
+ Binary: 0 0 1 0 0 0 1 1 0 r2 r1 r0 d3 d2 d1 d0
+
+ Data Flow: RAM(r,d) -> A
+
+ Description: Load A with RAM pointed to directly by r,d
+
+*/
+
+INSTRUCTION( ldd )
+{
+ UINT8 rd = opcode & 0x7f;
+
+ A = RAM_R(rd);
+}
+
+/*
+
+ Mnemonic: CAMT
+
+ Hex Code: 33 3F
+ Binary:
+
+ Data Flow: A -> T7:4
+ RAM(B) -> T3:0
+
+ Description: Copy A, RAM to T
+
+*/
+
+INSTRUCTION( camt )
+{
+ T = (A << 4) | RAM_R(B);
+}
+/*
+
+ Mnemonic: CTMA
+
+ Hex Code: 33 2F
+ Binary:
+
+ Data Flow: T7:4 -> RAM(B)
+ T3:0 -> A
+
+ Description: Copy T to RAM, A
+
+*/
+
+INSTRUCTION( ctma )
+{
+ RAM_W(B, T >> 4);
+ A = T & 0x0f;
+}
+
+/***************************************************************************
+ REGISTER REFERENCE INSTRUCTIONS
+***************************************************************************/
/*
@@ -906,7 +869,7 @@ INSTRUCTION( xis )
INSTRUCTION( cab )
{
- B = (B & 0x30) | A;
+ B = (B & 0x70) | A;
}
/*
@@ -936,7 +899,7 @@ INSTRUCTION( cba )
33 --
Binary: 0 0 r1 r0 d3 d2 d1 d0 (d-1)
- 0 0 1 1 0 0 1 1 1 0 r1 r0 d3 d2 d1 d0
+ 0 0 1 1 0 0 1 1 1 r2 r1 r0 d3 d2 d1 d0
Data Flow: r,d -> B
@@ -954,10 +917,10 @@ INSTRUCTION( lbi )
}
else
{
- B = (opcode & 0x30) | (((opcode & 0x0f) + 1) & 0x0f);
+ B = (opcode & 0x70) | (((opcode & 0x0f) + 1) & 0x0f);
}
- cop400->skip_lbi = 1;
+ cpustate->skip_lbi = 1;
}
/*
@@ -976,7 +939,7 @@ INSTRUCTION( lbi )
INSTRUCTION( lei )
{
- UINT4 y = opcode & 0x0f;
+ UINT8 y = opcode & 0x0f;
EN = y;
@@ -986,7 +949,55 @@ INSTRUCTION( lei )
}
}
-/* Test Instructions */
+/*
+
+ Mnemonic: XABR
+
+ Hex Code: 12
+ Binary: 0 0 0 1 0 0 1 0
+
+ Data Flow: A <-> Br(0,0 -> A3,A2)
+
+ Description: Exchange A with Br
+
+*/
+
+INSTRUCTION( xabr )
+{
+ UINT8 Br = A & 0x03;
+ UINT8 Bd = B & 0x0f;
+
+ A = B >> 4;
+ B = (Br << 4) + Bd;
+}
+
+/*
+
+ Processor: COP444
+
+ Mnemonic: XABR
+
+ Hex Code: 12
+ Binary: 0 0 0 1 0 0 1 0
+
+ Data Flow: A <-> Br(0 -> A3)
+
+ Description: Exchange A with Br
+
+*/
+
+INSTRUCTION( cop444_xabr )
+{
+ UINT8 Br = A & 0x07;
+ UINT8 Bd = B & 0x0f;
+
+ A = B >> 4;
+ B = (Br << 4) + Bd;
+}
+
+/***************************************************************************
+ TEST INSTRUCTIONS
+***************************************************************************/
/*
@@ -1003,7 +1014,7 @@ INSTRUCTION( lei )
INSTRUCTION( skc )
{
- if (C == 1) cop400->skip = 1;
+ if (C == 1) cpustate->skip = 1;
}
/*
@@ -1021,7 +1032,7 @@ INSTRUCTION( skc )
INSTRUCTION( ske )
{
- if (A == RAM_R(B)) cop400->skip = 1;
+ if (A == RAM_R(B)) cpustate->skip = 1;
}
/*
@@ -1039,7 +1050,7 @@ INSTRUCTION( ske )
INSTRUCTION( skgz )
{
- if (IN_G() == 0) cop400->skip = 1;
+ if (IN_G() == 0) cpustate->skip = 1;
}
/*
@@ -1062,15 +1073,15 @@ INSTRUCTION( skgz )
*/
-INLINE void skgbz(cop400_state *cop400, int bit)
+INLINE void skgbz(cop400_state *cpustate, int bit)
{
- if (!BIT(IN_G(), bit)) cop400->skip = 1;
+ if (!BIT(IN_G(), bit)) cpustate->skip = 1;
}
-INSTRUCTION( skgbz0 ) { skgbz(cop400, 0); }
-INSTRUCTION( skgbz1 ) { skgbz(cop400, 1); }
-INSTRUCTION( skgbz2 ) { skgbz(cop400, 2); }
-INSTRUCTION( skgbz3 ) { skgbz(cop400, 3); }
+INSTRUCTION( skgbz0 ) { skgbz(cpustate, 0); }
+INSTRUCTION( skgbz1 ) { skgbz(cpustate, 1); }
+INSTRUCTION( skgbz2 ) { skgbz(cpustate, 2); }
+INSTRUCTION( skgbz3 ) { skgbz(cpustate, 3); }
/*
@@ -1092,17 +1103,41 @@ INSTRUCTION( skgbz3 ) { skgbz(cop400, 3); }
*/
-INLINE void skmbz(cop400_state *cop400, int bit)
+INLINE void skmbz(cop400_state *cpustate, int bit)
{
- if (!BIT(RAM_R(B), bit)) cop400->skip = 1;
+ if (!BIT(RAM_R(B), bit)) cpustate->skip = 1;
}
-INSTRUCTION( skmbz0 ) { skmbz(cop400, 0); }
-INSTRUCTION( skmbz1 ) { skmbz(cop400, 1); }
-INSTRUCTION( skmbz2 ) { skmbz(cop400, 2); }
-INSTRUCTION( skmbz3 ) { skmbz(cop400, 3); }
+INSTRUCTION( skmbz0 ) { skmbz(cpustate, 0); }
+INSTRUCTION( skmbz1 ) { skmbz(cpustate, 1); }
+INSTRUCTION( skmbz2 ) { skmbz(cpustate, 2); }
+INSTRUCTION( skmbz3 ) { skmbz(cpustate, 3); }
-/* Input/Output Instructions */
+/*
+
+ Mnemonic: SKT
+
+ Hex Code: 41
+ Binary: 0 1 0 0 0 0 0 1
+
+ Skip Conditions: A time-base counter carry has occurred since last test
+
+ Description: Skip on Timer
+
+*/
+
+INSTRUCTION( skt )
+{
+ if (cpustate->skt_latch)
+ {
+ cpustate->skt_latch = 0;
+ cpustate->skip = 1;
+ }
+}
+
+/***************************************************************************
+ INPUT/OUTPUT INSTRUCTIONS
+***************************************************************************/
/*
@@ -1177,7 +1212,7 @@ INSTRUCTION( obd )
INSTRUCTION( omg )
{
- WRITE_G(cop400, RAM_R(B));
+ WRITE_G(cpustate, RAM_R(B));
}
/*
@@ -1202,3 +1237,82 @@ INSTRUCTION( xas )
SKL = C;
}
+
+/*
+
+ Mnemonic: ININ
+
+ Hex Code: 33 28
+ Binary:
+
+ Data Flow: IN -> A
+
+ Description: Input IN Inputs to A
+
+*/
+
+INSTRUCTION( inin )
+{
+ A = IN_IN();
+}
+
+/*
+
+ Processor: COP402M
+
+ Mnemonic: ININ
+
+ Hex Code: 33 28
+ Binary:
+
+ Data Flow: IN -> A, A1 = "1"
+
+ Description: Input IN Inputs to A
+
+*/
+
+INSTRUCTION( cop402m_inin )
+{
+ A = IN_IN() | 0x02;
+}
+
+/*
+
+ Mnemonic: INIL
+
+ Hex Code: 33 29
+ Binary:
+
+ Data Flow: IL3,CKO,"0",IL0 -> A
+
+ Description: Input IL Latches to A
+
+*/
+
+INSTRUCTION( inil )
+{
+ A = (IL & 0x09) | IN_CKO() << 2;
+
+ IL = 0;
+}
+
+/*
+
+ Mnemonic: OGI
+
+ Operand: y
+ Hex Code: 33 5-
+ Binary: 0 0 1 1 0 0 1 1 0 1 0 1 y3 y2 y1 y0
+
+ Data Flow: y -> G
+
+ Description: Output to G Ports Immediate
+
+*/
+
+INSTRUCTION( ogi )
+{
+ UINT8 y = opcode & 0x0f;
+
+ WRITE_G(cpustate, y);
+}
diff --git a/src/emu/cpu/cop400/cop410.c b/src/emu/cpu/cop400/cop410.c
deleted file mode 100644
index f2389121d03..00000000000
--- a/src/emu/cpu/cop400/cop410.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/***************************************************************************
-
- cop410.c
-
- National Semiconductor COP410 Emulator.
-
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
-
-***************************************************************************/
-
-/*
-
- TODO:
-
- - COP413/COP414/COP415/COP405
- - get rid of LBIOps/InstLen
- - run interrupt test suite
- - run production test suite
- - run microbus test suite
-
-*/
-
-#include "driver.h"
-#include "cpuintrf.h"
-#include "debugger.h"
-#include "cop400.h"
-
-#include "410ops.c"
-
-/* Opcode Maps */
-
-static const s_opcode 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 *cop400, UINT8 opcode)
-{
- UINT8 opcode23 = ROM(PC++);
-
- (*(COP410_OPCODE_23_MAP[opcode23].function))(cop400, opcode23);
-}
-
-static const s_opcode 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 *cop400, UINT8 opcode)
-{
- UINT8 opcode33 = ROM(PC++);
-
- (*(COP410_OPCODE_33_MAP[opcode33].function))(cop400, opcode33);
-}
-
-static const s_opcode 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 }
-};
-
-/* Memory Maps */
-
-static ADDRESS_MAP_START( cop410_internal_rom, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x000, 0x1ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cop410_internal_ram, ADDRESS_SPACE_DATA, 8 )
- AM_RANGE(0x00, 0x3f) AM_RAM
-ADDRESS_MAP_END
-
-/****************************************************************************
- * Initialize emulation
- ****************************************************************************/
-static CPU_INIT( cop410 )
-{
- cop400_state *cop400 = device->token;
- int i;
-
- cop400->device = device;
- cop400->intf = (cop400_interface *) device->static_config;
-
- /* get address spaces */
-
- cop400->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
- cop400->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
- cop400->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
-
- /* set output pin masks */
-
- cop400->g_mask = 0x0f;
- cop400->d_mask = 0x0f;
-
- /* set clock divider */
-
- device_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki);
-
- /* allocate serial timer */
-
- cop400->serial_timer = timer_alloc(device->machine, cop400_serial_tick, cop400);
- timer_adjust_periodic(cop400->serial_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
-
- /* initialize instruction length array */
-
- for (i=0; i<256; i++) cop400->InstLen[i]=1;
-
- cop400->InstLen[0x60] = cop400->InstLen[0x61] = cop400->InstLen[0x68] = cop400->InstLen[0x69] = cop400->InstLen[0x33] = cop400->InstLen[0x23] = 2;
-
- /* initialize LBI opcode array */
-
- for (i=0; i<256; i++) cop400->LBIops[i] = 0;
- for (i=0x08; i<0x10; i++) cop400->LBIops[i] = 1;
- for (i=0x18; i<0x20; i++) cop400->LBIops[i] = 1;
- for (i=0x28; i<0x30; i++) cop400->LBIops[i] = 1;
- for (i=0x38; i<0x40; i++) cop400->LBIops[i] = 1;
-
- /* register for state saving */
-
- state_save_register_device_item(device, 0, cop400->pc);
- state_save_register_device_item(device, 0, cop400->prevpc);
- state_save_register_device_item(device, 0, cop400->a);
- state_save_register_device_item(device, 0, cop400->b);
- state_save_register_device_item(device, 0, cop400->c);
- state_save_register_device_item(device, 0, cop400->en);
- state_save_register_device_item(device, 0, cop400->g);
- state_save_register_device_item(device, 0, cop400->q);
- state_save_register_device_item(device, 0, cop400->sa);
- state_save_register_device_item(device, 0, cop400->sb);
- state_save_register_device_item(device, 0, cop400->sio);
- state_save_register_device_item(device, 0, cop400->skl);
- state_save_register_device_item(device, 0, cop400->skip);
- state_save_register_device_item(device, 0, cop400->skip_lbi);
- state_save_register_device_item(device, 0, cop400->g_mask);
- state_save_register_device_item(device, 0, cop400->d_mask);
- state_save_register_device_item(device, 0, cop400->si);
- state_save_register_device_item(device, 0, cop400->microbus_int);
- state_save_register_device_item(device, 0, cop400->halt);
-}
-
-static CPU_INIT( cop411 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop410);
-
- /* the COP411 is like the COP410, just with less output ports */
- cop400->g_mask = 0x07;
- cop400->d_mask = 0x03;
-}
-
-/****************************************************************************
- * Reset registers to their initial values
- ****************************************************************************/
-static CPU_RESET( cop410 )
-{
- cop400_state *cop400 = device->token;
-
- PC = 0;
- A = 0;
- B = 0;
- C = 0;
- OUT_D(0);
- EN = 0;
- WRITE_G(cop400, 0);
- SKL = 1;
-
- cop400->halt = 0;
-}
-
-/****************************************************************************
- * Execute cycles CPU cycles. Return number of cycles really executed
- ****************************************************************************/
-static CPU_EXECUTE( cop410 )
-{
- cop400_state *cop400 = device->token;
-
- UINT8 opcode;
-
- cop400->icount = cycles;
-
- do
- {
- prevPC = PC;
-
- debugger_instruction_hook(device, PC);
-
- if (cop400->intf->cko == COP400_CKO_HALT_IO_PORT)
- {
- cop400->halt = IN_CKO();
- }
-
- if (cop400->halt)
- {
- cop400->icount -= 1;
- continue;
- }
-
- opcode = ROM(PC);
-
- if (cop400->skip_lbi)
- {
- if (cop400->LBIops[opcode])
- {
- cop400->icount -= COP410_OPCODE_MAP[opcode].cycles;
-
- PC += cop400->InstLen[opcode];
- }
- else
- {
- cop400->skip_lbi = 0;
- }
- }
-
- if (!cop400->skip_lbi)
- {
- int inst_cycles = COP410_OPCODE_MAP[opcode].cycles;
- PC++;
- (*(COP410_OPCODE_MAP[opcode].function))(cop400, opcode);
- cop400->icount -= inst_cycles;
-
- // skip next instruction?
-
- if (cop400->skip)
- {
- void *function = COP410_OPCODE_MAP[ROM(PC)].function;
-
- opcode = ROM(PC);
-
- if ((function == lqid) || (function == jid))
- {
- cop400->icount -= 1;
- }
- else
- {
- cop400->icount -= COP410_OPCODE_MAP[opcode].cycles;
- }
-
- PC += cop400->InstLen[opcode];
-
- cop400->skip = 0;
- }
- }
- } while (cop400->icount > 0);
-
- return cycles - cop400->icount;
-}
-
-/**************************************************************************
- * Validity check
- **************************************************************************/
-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;
-}
-
-/**************************************************************************
- * Generic set_info
- **************************************************************************/
-
-static CPU_SET_INFO( cop410 )
-{
- cop400_state *cop400 = device->token;
-
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: PC = info->i; break;
-
- case CPUINFO_INT_REGISTER + COP400_A: A = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_B: B = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_C: C = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_EN: EN = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_G: G = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_Q: Q = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SA: SA = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SB: SB = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: SIO = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: SKL = info->i; break;
- }
-}
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-CPU_GET_INFO( cop410 )
-{
- cop400_state *cop400 = (device != NULL) ? device->token : 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 CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
- case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
- case CPUINFO_INT_CLOCK_DIVIDER: info->i = 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 CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 9; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 6; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_IO: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_IO: info->i = 9; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_IO: info->i = 0; break;
-
- case CPUINFO_INT_INPUT_STATE + 0: info->i = 0; break;
-
- case CPUINFO_INT_PREVIOUSPC: info->i = prevPC; break;
-
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: info->i = PC; break;
- case CPUINFO_INT_REGISTER + COP400_A: info->i = A; break;
- case CPUINFO_INT_REGISTER + COP400_B: info->i = B; break;
- case CPUINFO_INT_REGISTER + COP400_C: info->i = C; break;
- case CPUINFO_INT_REGISTER + COP400_EN: info->i = EN; break;
- case CPUINFO_INT_REGISTER + COP400_G: info->i = G; break;
- case CPUINFO_INT_REGISTER + COP400_Q: info->i = Q; break;
- case CPUINFO_INT_REGISTER + COP400_SA: info->i = SA; break;
- case CPUINFO_INT_REGISTER + COP400_SB: info->i = SB; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: info->i = SIO; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: info->i = SKL; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cop410); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop410); break;
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(cop410); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop410); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop410); break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break;
- case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop410); break;
-
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = ADDRESS_MAP_NAME(cop410_internal_rom); break;
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:
- info->internal_map8 = ADDRESS_MAP_NAME(cop410_internal_ram); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP410"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
- case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
-
- case CPUINFO_STR_FLAGS:
- sprintf(info->s, " ");
- break;
-
- case CPUINFO_STR_REGISTER + COP400_PC: sprintf(info->s, "PC:%04X", PC); break;
- case CPUINFO_STR_REGISTER + COP400_A: sprintf(info->s, "A:%01X", A ); break;
- case CPUINFO_STR_REGISTER + COP400_B: sprintf(info->s, "B:%02X", B ); break;
- case CPUINFO_STR_REGISTER + COP400_C: sprintf(info->s, "C:%01X", C); break;
- case CPUINFO_STR_REGISTER + COP400_EN: sprintf(info->s, "EN:%01X", EN); break;
- case CPUINFO_STR_REGISTER + COP400_G: sprintf(info->s, "G:%01X", G); break;
- case CPUINFO_STR_REGISTER + COP400_Q: sprintf(info->s, "Q:%02X", Q); break;
- case CPUINFO_STR_REGISTER + COP400_SA: sprintf(info->s, "SA:%04X", SA); break;
- case CPUINFO_STR_REGISTER + COP400_SB: sprintf(info->s, "SB:%04X", SB); break;
- case CPUINFO_STR_REGISTER + COP400_SIO: sprintf(info->s, "SIO:%01X", SIO); break;
- case CPUINFO_STR_REGISTER + COP400_SKL: sprintf(info->s, "SKL:%01X", SKL); 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 CPUINFO_STR_NAME: strcpy(info->s, "COP411"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- default: CPU_GET_INFO_CALL(cop410); break;
- }
-}
-
-CPU_GET_INFO( cop401 )
-{
- // COP401 is a ROMless version of the COP410
-
- switch (state)
- {
- case CPUINFO_STR_NAME: strcpy(info->s, "COP401"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = NULL; break;
-
- default: CPU_GET_INFO_CALL(cop410); break;
- }
-}
diff --git a/src/emu/cpu/cop400/cop420.c b/src/emu/cpu/cop400/cop420.c
deleted file mode 100644
index ca9a41e8ab5..00000000000
--- a/src/emu/cpu/cop400/cop420.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/***************************************************************************
-
- cop420.c
-
- National Semiconductor COP420 Emulator.
-
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
-
-***************************************************************************/
-
-/*
-
- TODO:
-
- - get rid of LBIOps/InstLen
- - when is the microbus int cleared?
- - CKO sync input
- - save internal RAM when CKO is RAM power supply pin
- - run interrupt test suite
- - run production test suite
- - run microbus test suite
-
-*/
-
-#include "driver.h"
-#include "cpuintrf.h"
-#include "debugger.h"
-#include "cop400.h"
-
-#include "420ops.c"
-
-/* Opcode Maps */
-
-static const s_opcode 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 *cop400, UINT8 opcode)
-{
- UINT8 opcode23 = ROM(PC++);
-
- (*(COP420_OPCODE_23_MAP[opcode23].function))(cop400, opcode23);
-}
-
-static const s_opcode 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 *cop400, UINT8 opcode)
-{
- UINT8 opcode33 = ROM(PC++);
-
- (*(COP420_OPCODE_33_MAP[opcode33].function))(cop400, opcode33);
-}
-
-static const s_opcode 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 }
-};
-
-/* Memory Maps */
-
-static ADDRESS_MAP_START( cop420_internal_rom, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x000, 0x3ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cop420_internal_ram, ADDRESS_SPACE_DATA, 8 )
- AM_RANGE(0x00, 0x3f) AM_RAM
-ADDRESS_MAP_END
-
-/****************************************************************************
- * Initialize emulation
- ****************************************************************************/
-static CPU_INIT( cop420 )
-{
- cop400_state *cop400 = device->token;
- int i;
-
- cop400->device = device;
- cop400->intf = (cop400_interface *) device->static_config;
-
- /* get address spaces */
-
- cop400->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
- cop400->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
- cop400->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
-
- /* set output pin masks */
-
- cop400->g_mask = 0x0f; // G0-G3 available
- cop400->d_mask = 0x0f; // D0-D3 available
- cop400->in_mask = 0x0f; // IN0-IN3 available
-
- /* set clock divider */
-
- device_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki);
-
- /* allocate serial timer */
-
- cop400->serial_timer = timer_alloc(device->machine, cop400_serial_tick, cop400);
- timer_adjust_periodic(cop400->serial_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
-
- /* allocate counter timer */
-
- cop400->counter_timer = timer_alloc(device->machine, cop400_counter_tick, cop400);
- timer_adjust_periodic(cop400->counter_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16 / 4));
-
- /* allocate IN latch timer */
-
- cop400->inil_timer = timer_alloc(device->machine, cop400_inil_tick, cop400);
- timer_adjust_periodic(cop400->inil_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
-
- /* allocate Microbus timer */
-
- if (cop400->intf->microbus == COP400_MICROBUS_ENABLED)
- {
- cop400->microbus_timer = timer_alloc(device->machine, cop400_microbus_tick, cop400);
- timer_adjust_periodic(cop400->microbus_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
- }
-
- /* initialize instruction length array */
-
- for (i=0; i<256; i++) cop400->InstLen[i]=1;
-
- cop400->InstLen[0x60] = cop400->InstLen[0x61] = cop400->InstLen[0x62] = cop400->InstLen[0x63] =
- cop400->InstLen[0x68] = cop400->InstLen[0x69] = cop400->InstLen[0x6a] = cop400->InstLen[0x6b] =
- cop400->InstLen[0x33] = cop400->InstLen[0x23] = 2;
-
- /* initialize LBI opcode array */
-
- for (i=0; i<256; i++) cop400->LBIops[i] = 0;
- for (i=0x08; i<0x10; i++) cop400->LBIops[i] = 1;
- for (i=0x18; i<0x20; i++) cop400->LBIops[i] = 1;
- for (i=0x28; i<0x30; i++) cop400->LBIops[i] = 1;
- for (i=0x38; i<0x40; i++) cop400->LBIops[i] = 1;
-
- for (i=0; i<256; i++) cop400->LBIops33[i] = 0;
- for (i=0x80; i<0xc0; i++) cop400->LBIops33[i] = 1;
-
- /* register for state saving */
-
- state_save_register_device_item(device, 0, cop400->pc);
- state_save_register_device_item(device, 0, cop400->prevpc);
- state_save_register_device_item(device, 0, cop400->a);
- state_save_register_device_item(device, 0, cop400->b);
- state_save_register_device_item(device, 0, cop400->c);
- state_save_register_device_item(device, 0, cop400->en);
- state_save_register_device_item(device, 0, cop400->g);
- state_save_register_device_item(device, 0, cop400->q);
- state_save_register_device_item(device, 0, cop400->sa);
- state_save_register_device_item(device, 0, cop400->sb);
- state_save_register_device_item(device, 0, cop400->sc);
- state_save_register_device_item(device, 0, cop400->sio);
- state_save_register_device_item(device, 0, cop400->skl);
- state_save_register_device_item(device, 0, cop400->skip);
- state_save_register_device_item(device, 0, cop400->skip_lbi);
- state_save_register_device_item(device, 0, cop400->t);
- state_save_register_device_item(device, 0, cop400->skt_latch);
- state_save_register_device_item(device, 0, cop400->g_mask);
- state_save_register_device_item(device, 0, cop400->d_mask);
- state_save_register_device_item(device, 0, cop400->in_mask);
- state_save_register_device_item(device, 0, cop400->si);
- state_save_register_device_item(device, 0, cop400->last_skip);
- state_save_register_device_item_array(device, 0, cop400->in);
- state_save_register_device_item(device, 0, cop400->microbus_int);
- state_save_register_device_item(device, 0, cop400->halt);
-}
-
-static CPU_INIT( cop421 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop420);
-
- /* set output pin masks */
- cop400->in_mask = 0; // IN lines not available
-}
-
-static CPU_INIT( cop422 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop420);
-
- /* set output pin masks */
- cop400->g_mask = 0x0e; // only G2, G3 available
- cop400->d_mask = 0x0e; // only D2, D3 available
- cop400->in_mask = 0; // IN lines not available
-}
-
-/****************************************************************************
- * Reset registers to their initial values
- ****************************************************************************/
-static CPU_RESET( cop420 )
-{
- cop400_state *cop400 = device->token;
-
- PC = 0;
- A = 0;
- B = 0;
- C = 0;
- OUT_D(0);
- EN = 0;
- WRITE_G(cop400, 0);
- SKL = 1;
-
- T = 0;
- cop400->skt_latch = 1;
-}
-
-/****************************************************************************
- * Execute cycles CPU cycles. Return number of cycles really executed
- ****************************************************************************/
-static CPU_EXECUTE( cop420 )
-{
- cop400_state *cop400 = device->token;
-
- UINT8 opcode;
-
- cop400->icount = cycles;
-
- do
- {
- prevPC = PC;
-
- debugger_instruction_hook(device, PC);
-
- opcode = ROM(PC);
-
- if (cop400->skip_lbi)
- {
- int is_lbi = 0;
-
- if (opcode == 0x33)
- {
- is_lbi = cop400->LBIops33[ROM(PC+1)];
- }
- else
- {
- is_lbi = cop400->LBIops[opcode];
- }
-
- if (is_lbi)
- {
- cop400->icount -= COP420_OPCODE_MAP[opcode].cycles;
-
- PC += cop400->InstLen[opcode];
- }
- else
- {
- cop400->skip_lbi = 0;
- }
- }
-
- if (!cop400->skip_lbi)
- {
- int inst_cycles = COP420_OPCODE_MAP[opcode].cycles;
- PC++;
- (*(COP420_OPCODE_MAP[opcode].function))(cop400, opcode);
- cop400->icount -= inst_cycles;
-
- // check for interrupt
-
- if (BIT(EN, 1) && BIT(IL, 1))
- {
- void *function = COP420_OPCODE_MAP[ROM(PC)].function;
-
- if ((function != jp) && (function != jmp) && (function != jsr))
- {
- // store skip logic
- cop400->last_skip = cop400->skip;
- cop400->skip = 0;
-
- // push next PC
- PUSH(PC);
-
- // jump to interrupt service routine
- PC = 0x0ff;
-
- // disable interrupt
- EN &= ~0x02;
- }
-
- IL &= ~2;
- }
-
- // skip next instruction?
-
- if (cop400->skip)
- {
- void *function = COP420_OPCODE_MAP[ROM(PC)].function;
-
- opcode = ROM(PC);
-
- if ((function == lqid) || (function == jid))
- {
- cop400->icount -= 1;
- }
- else
- {
- cop400->icount -= COP420_OPCODE_MAP[opcode].cycles;
- }
-
- PC += cop400->InstLen[opcode];
-
- cop400->skip = 0;
- }
- }
- } while (cop400->icount > 0);
-
- return cycles - cop400->icount;
-}
-
-/**************************************************************************
- * Validity check
- **************************************************************************/
-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;
-}
-
-/**************************************************************************
- * Generic set_info
- **************************************************************************/
-
-static CPU_SET_INFO( cop420 )
-{
- cop400_state *cop400 = device->token;
-
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: PC = info->i; break;
-
- case CPUINFO_INT_REGISTER + COP400_A: A = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_B: B = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_C: C = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_EN: EN = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_G: G = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_Q: Q = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SA: SA = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SB: SB = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SC: SC = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: SIO = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: SKL = info->i; break;
- }
-}
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-CPU_GET_INFO( cop420 )
-{
- cop400_state *cop400 = (device != NULL) ? device->token : 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 CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
- case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
- case CPUINFO_INT_CLOCK_DIVIDER: info->i = 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 CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 6; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_IO: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_IO: info->i = 9; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_IO: info->i = 0; break;
-
- case CPUINFO_INT_INPUT_STATE + 0: info->i = 0; break;
-
- case CPUINFO_INT_PREVIOUSPC: info->i = prevPC; break;
-
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: info->i = PC; break;
- case CPUINFO_INT_REGISTER + COP400_A: info->i = A; break;
- case CPUINFO_INT_REGISTER + COP400_B: info->i = B; break;
- case CPUINFO_INT_REGISTER + COP400_C: info->i = C; break;
- case CPUINFO_INT_REGISTER + COP400_EN: info->i = EN; break;
- case CPUINFO_INT_REGISTER + COP400_G: info->i = G; break;
- case CPUINFO_INT_REGISTER + COP400_Q: info->i = Q; break;
- case CPUINFO_INT_REGISTER + COP400_SA: info->i = SA; break;
- case CPUINFO_INT_REGISTER + COP400_SB: info->i = SB; break;
- case CPUINFO_INT_REGISTER + COP400_SC: info->i = SC; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: info->i = SIO; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: info->i = SKL; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cop420); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop420); break;
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(cop420); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop420); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop420); break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break;
- case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop420); break;
-
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = ADDRESS_MAP_NAME(cop420_internal_rom); break;
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:
- info->internal_map8 = ADDRESS_MAP_NAME(cop420_internal_ram); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP420"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
- case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
-
- case CPUINFO_STR_FLAGS:
- sprintf(info->s, " ");
- break;
-
- case CPUINFO_STR_REGISTER + COP400_PC: sprintf(info->s, "PC:%04X", PC); break;
- case CPUINFO_STR_REGISTER + COP400_A: sprintf(info->s, "A:%01X", A ); break;
- case CPUINFO_STR_REGISTER + COP400_B: sprintf(info->s, "B:%02X", B ); break;
- case CPUINFO_STR_REGISTER + COP400_C: sprintf(info->s, "C:%01X", C); break;
- case CPUINFO_STR_REGISTER + COP400_EN: sprintf(info->s, "EN:%01X", EN); break;
- case CPUINFO_STR_REGISTER + COP400_G: sprintf(info->s, "G:%01X", G); break;
- case CPUINFO_STR_REGISTER + COP400_Q: sprintf(info->s, "Q:%02X", Q); break;
- case CPUINFO_STR_REGISTER + COP400_SA: sprintf(info->s, "SA:%04X", SA); break;
- case CPUINFO_STR_REGISTER + COP400_SB: sprintf(info->s, "SB:%04X", SB); break;
- case CPUINFO_STR_REGISTER + COP400_SC: sprintf(info->s, "SC:%04X", SC); break;
- case CPUINFO_STR_REGISTER + COP400_SIO: sprintf(info->s, "SIO:%01X", SIO); break;
- case CPUINFO_STR_REGISTER + COP400_SKL: sprintf(info->s, "SKL:%01X", SKL); 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 CPUINFO_STR_NAME: strcpy(info->s, "COP421"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); 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;
- 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 CPUINFO_STR_NAME: strcpy(info->s, "COP422"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- default: CPU_GET_INFO_CALL(cop420); 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 CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = NULL; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP402"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- default: CPU_GET_INFO_CALL(cop420); break;
- }
-}
diff --git a/src/emu/cpu/cop400/cop440.c b/src/emu/cpu/cop400/cop440.c
deleted file mode 100644
index 296bbe84d99..00000000000
--- a/src/emu/cpu/cop400/cop440.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/***************************************************************************
-
- cop440.c
-
- National Semiconductor COP420 Emulator.
-
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
-
-***************************************************************************/
-
-/*
-
- TODO:
-
- - rename this file to cop444.c
- - COP440/COP441/COP442 (new registers: 4-bit H, 8-bit R; some new opcodes, 2Kx8 ROM, 160x4 RAM)
- - COP404 emulation configuration inputs
- - RAM bus width
- - get rid of LBIOps/InstLen
- - when is the microbus int cleared?
- - CKO sync input
- - save internal RAM when CKO is RAM power supply pin
- - run interrupt test suite
- - run production test suite
- - run microbus test suite
-
-*/
-
-#include "driver.h"
-#include "cpuintrf.h"
-#include "debugger.h"
-#include "cop400.h"
-
-#include "440ops.c"
-
-/* Opcode Maps */
-
-static const s_opcode COP440_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, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, 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 cop440_op23(cop400_state *cop400, UINT8 opcode)
-{
- UINT8 opcode23 = ROM(PC++);
-
- (*(COP440_OPCODE_23_MAP[opcode23].function))(cop400, opcode23);
-}
-
-static const s_opcode COP440_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, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
- {1, illegal },{1, illegal },{1, illegal },{1, illegal },{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 cop440_op33(cop400_state *cop400, UINT8 opcode)
-{
- UINT8 opcode33 = ROM(PC++);
-
- (*(COP440_OPCODE_33_MAP[opcode33].function))(cop400, opcode33);
-}
-
-static const s_opcode COP440_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, 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, cop440_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, cop440_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 }
-};
-
-/* Memory Maps */
-
-static ADDRESS_MAP_START( cop424_internal_rom, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x000, 0x3ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cop424_internal_ram, ADDRESS_SPACE_DATA, 8 )
- AM_RANGE(0x00, 0x3f) AM_RAM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cop444_internal_rom, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x000, 0x7ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cop444_internal_ram, ADDRESS_SPACE_DATA, 8 )
- AM_RANGE(0x00, 0x7f) AM_RAM
-ADDRESS_MAP_END
-
-/****************************************************************************
- * Initialize emulation
- ****************************************************************************/
-static CPU_INIT( cop444 )
-{
- cop400_state *cop400 = device->token;
- int i;
-
- cop400->device = device;
- cop400->intf = (cop400_interface *) device->static_config;
-
- /* get address spaces */
-
- cop400->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
- cop400->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
- cop400->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
-
- /* set output pin masks */
-
- cop400->g_mask = 0x0f; // G0-G3 available
- cop400->d_mask = 0x0f; // D0-D3 available
- cop400->in_mask = 0x0f; // IN0-IN3 available
-
- /* set clock divider */
-
- device_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki);
-
- /* allocate serial timer */
-
- cop400->serial_timer = timer_alloc(device->machine, cop400_serial_tick, cop400);
- timer_adjust_periodic(cop400->serial_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
-
- /* allocate counter timer */
-
- cop400->counter_timer = timer_alloc(device->machine, cop400_counter_tick, cop400);
- timer_adjust_periodic(cop400->counter_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16 / 4));
-
- /* allocate IN latch timer */
-
- cop400->inil_timer = timer_alloc(device->machine, cop400_inil_tick, cop400);
- timer_adjust_periodic(cop400->inil_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
-
- /* allocate Microbus timer */
-
- if (cop400->intf->microbus == COP400_MICROBUS_ENABLED)
- {
- cop400->microbus_timer = timer_alloc(device->machine, cop400_microbus_tick, cop400);
- timer_adjust_periodic(cop400->microbus_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock / 16));
- }
-
- /* initialize instruction length array */
-
- for (i=0; i<256; i++) cop400->InstLen[i]=1;
-
- cop400->InstLen[0x60] = cop400->InstLen[0x61] = cop400->InstLen[0x62] = cop400->InstLen[0x63] =
- cop400->InstLen[0x68] = cop400->InstLen[0x69] = cop400->InstLen[0x6a] = cop400->InstLen[0x6b] =
- cop400->InstLen[0x33] = cop400->InstLen[0x23] = 2;
-
- /* initialize LBI opcode array */
-
- for (i=0; i<256; i++) cop400->LBIops[i] = 0;
- for (i=0x08; i<0x10; i++) cop400->LBIops[i] = 1;
- for (i=0x18; i<0x20; i++) cop400->LBIops[i] = 1;
- for (i=0x28; i<0x30; i++) cop400->LBIops[i] = 1;
- for (i=0x38; i<0x40; i++) cop400->LBIops[i] = 1;
-
- for (i=0; i<256; i++) cop400->LBIops33[i] = 0;
- for (i=0x80; i<0xc0; i++) cop400->LBIops33[i] = 1;
-
- /* register for state saving */
-
- state_save_register_device_item(device, 0, cop400->pc);
- state_save_register_device_item(device, 0, cop400->prevpc);
- state_save_register_device_item(device, 0, cop400->a);
- state_save_register_device_item(device, 0, cop400->b);
- state_save_register_device_item(device, 0, cop400->c);
- state_save_register_device_item(device, 0, cop400->en);
- state_save_register_device_item(device, 0, cop400->g);
- state_save_register_device_item(device, 0, cop400->q);
- state_save_register_device_item(device, 0, cop400->sa);
- state_save_register_device_item(device, 0, cop400->sb);
- state_save_register_device_item(device, 0, cop400->sc);
- state_save_register_device_item(device, 0, cop400->sio);
- state_save_register_device_item(device, 0, cop400->skl);
- state_save_register_device_item(device, 0, cop400->skip);
- state_save_register_device_item(device, 0, cop400->skip_lbi);
- state_save_register_device_item(device, 0, cop400->t);
- state_save_register_device_item(device, 0, cop400->skt_latch);
- state_save_register_device_item(device, 0, cop400->g_mask);
- state_save_register_device_item(device, 0, cop400->d_mask);
- state_save_register_device_item(device, 0, cop400->in_mask);
- state_save_register_device_item(device, 0, cop400->si);
- state_save_register_device_item(device, 0, cop400->last_skip);
- state_save_register_device_item_array(device, 0, cop400->in);
- state_save_register_device_item(device, 0, cop400->microbus_int);
- state_save_register_device_item(device, 0, cop400->halt);
-}
-
-static CPU_INIT( cop425 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop444);
-
- cop400->in_mask = 0;
-}
-
-static CPU_INIT( cop426 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop444);
-
- cop400->g_mask = 0x0e; // only G2, G3 available
- cop400->d_mask = 0x0e; // only D2, D3 available
-}
-
-static CPU_INIT( cop445 )
-{
- cop400_state *cop400 = device->token;
-
- CPU_INIT_CALL(cop444);
-
- cop400->g_mask = 0x07;
- cop400->d_mask = 0x03;
- cop400->in_mask = 0;
-}
-
-/****************************************************************************
- * Reset registers to their initial values
- ****************************************************************************/
-static CPU_RESET( cop444 )
-{
- cop400_state *cop400 = device->token;
-
- PC = 0;
- A = 0;
- B = 0;
- C = 0;
- OUT_D(0);
- EN = 0;
- WRITE_G(cop400, 0);
- SKL = 1;
-
- T = 0;
- cop400->skt_latch = 1;
-
- cop400->halt = 0;
- cop400->idle = 0;
-}
-
-/****************************************************************************
- * Execute cycles CPU cycles. Return number of cycles really executed
- ****************************************************************************/
-static CPU_EXECUTE( cop444 )
-{
- cop400_state *cop400 = device->token;
-
- UINT8 opcode;
-
- cop400->icount = cycles;
-
- do
- {
- prevPC = PC;
-
- debugger_instruction_hook(device, PC);
-
- if (cop400->intf->cko == COP400_CKO_HALT_IO_PORT)
- {
- cop400->halt = IN_CKO();
- }
-
- if (cop400->halt)
- {
- cop400->icount -= 1;
- continue;
- }
-
- opcode = ROM(PC);
-
- if (cop400->skip_lbi)
- {
- int is_lbi = 0;
-
- if (opcode == 0x33)
- {
- is_lbi = cop400->LBIops33[ROM(PC+1)];
- }
- else
- {
- is_lbi = cop400->LBIops[opcode];
- }
-
- if (is_lbi)
- {
- cop400->icount -= COP440_OPCODE_MAP[opcode].cycles;
-
- PC += cop400->InstLen[opcode];
- }
- else
- {
- cop400->skip_lbi = 0;
- }
- }
-
- if (!cop400->skip_lbi)
- {
- int inst_cycles = COP440_OPCODE_MAP[opcode].cycles;
-
- PC++;
-
- (*(COP440_OPCODE_MAP[opcode].function))(cop400, opcode);
- cop400->icount -= inst_cycles;
-
- // check for interrupt
-
- if (BIT(EN, 1) && BIT(IL, 1))
- {
- void *function = COP440_OPCODE_MAP[ROM(PC)].function;
-
- if ((function != jp) && (function != jmp) && (function != jsr))
- {
- // store skip logic
- cop400->last_skip = cop400->skip;
- cop400->skip = 0;
-
- // push next PC
- PUSH(PC);
-
- // jump to interrupt service routine
- PC = 0x0ff;
-
- // disable interrupt
- EN &= ~0x02;
- }
-
- IL &= ~2;
- }
-
- // skip next instruction?
-
- if (cop400->skip)
- {
- void *function = COP440_OPCODE_MAP[ROM(PC)].function;
-
- opcode = ROM(PC);
-
- if ((function == lqid) || (function == jid))
- {
- cop400->icount -= 1;
- }
- else
- {
- cop400->icount -= COP440_OPCODE_MAP[opcode].cycles;
- }
- PC += cop400->InstLen[opcode];
-
- cop400->skip = 0;
- }
- }
- } while (cop400->icount > 0);
-
- return cycles - cop400->icount;
-}
-
-/**************************************************************************
- * Validity check
- **************************************************************************/
-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;
-}
-
-/**************************************************************************
- * Generic set_info
- **************************************************************************/
-
-static CPU_SET_INFO( cop444 )
-{
- cop400_state *cop400 = device->token;
-
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: PC = info->i; break;
-
- case CPUINFO_INT_REGISTER + COP400_A: A = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_B: B = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_C: C = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_EN: EN = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_G: G = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_Q: Q = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SA: SA = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SB: SB = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SC: SC = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: SIO = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: SKL = info->i; break;
- case CPUINFO_INT_REGISTER + COP400_T: T = info->i; break;
- }
-}
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-CPU_GET_INFO( cop444 )
-{
- cop400_state *cop400 = (device != NULL) ? device->token : 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 CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
- case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
- case CPUINFO_INT_CLOCK_DIVIDER: info->i = 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 CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 7; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH_IO: info->i = 8; break;
- case CPUINFO_INT_ADDRBUS_WIDTH_IO: info->i = 9; break;
- case CPUINFO_INT_ADDRBUS_SHIFT_IO: info->i = 0; break;
-
- case CPUINFO_INT_INPUT_STATE + 0: info->i = 0; break;
-
- case CPUINFO_INT_PREVIOUSPC: info->i = prevPC; break;
-
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + COP400_PC: info->i = PC; break;
- case CPUINFO_INT_REGISTER + COP400_A: info->i = A; break;
- case CPUINFO_INT_REGISTER + COP400_B: info->i = B; break;
- case CPUINFO_INT_REGISTER + COP400_C: info->i = C; break;
- case CPUINFO_INT_REGISTER + COP400_EN: info->i = EN; break;
- case CPUINFO_INT_REGISTER + COP400_G: info->i = G; break;
- case CPUINFO_INT_REGISTER + COP400_Q: info->i = Q; break;
- case CPUINFO_INT_REGISTER + COP400_SA: info->i = SA; break;
- case CPUINFO_INT_REGISTER + COP400_SB: info->i = SB; break;
- case CPUINFO_INT_REGISTER + COP400_SC: info->i = SC; break;
- case CPUINFO_INT_REGISTER + COP400_SIO: info->i = SIO; break;
- case CPUINFO_INT_REGISTER + COP400_SKL: info->i = SKL; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cop444); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(cop444); break;
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(cop444); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop444); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop444); break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break;
- case CPUINFO_FCT_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop444); break;
-
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = ADDRESS_MAP_NAME(cop444_internal_rom); break;
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:
- info->internal_map8 = ADDRESS_MAP_NAME(cop444_internal_ram); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP444"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
- case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright MAME Team"); break;
-
- case CPUINFO_STR_FLAGS:
- sprintf(info->s, " ");
- break;
-
- case CPUINFO_STR_REGISTER + COP400_PC: sprintf(info->s, "PC:%04X", PC); break;
- case CPUINFO_STR_REGISTER + COP400_A: sprintf(info->s, "A:%01X", A ); break;
- case CPUINFO_STR_REGISTER + COP400_B: sprintf(info->s, "B:%02X", B ); break;
- case CPUINFO_STR_REGISTER + COP400_C: sprintf(info->s, "C:%01X", C); break;
- case CPUINFO_STR_REGISTER + COP400_EN: sprintf(info->s, "EN:%01X", EN); break;
- case CPUINFO_STR_REGISTER + COP400_G: sprintf(info->s, "G:%01X", G); break;
- case CPUINFO_STR_REGISTER + COP400_Q: sprintf(info->s, "Q:%02X", Q); break;
- case CPUINFO_STR_REGISTER + COP400_SA: sprintf(info->s, "SA:%04X", SA); break;
- case CPUINFO_STR_REGISTER + COP400_SB: sprintf(info->s, "SB:%04X", SB); break;
- case CPUINFO_STR_REGISTER + COP400_SC: sprintf(info->s, "SC:%04X", SC); break;
- case CPUINFO_STR_REGISTER + COP400_SIO: sprintf(info->s, "SIO:%01X", SIO); break;
- case CPUINFO_STR_REGISTER + COP400_SKL: sprintf(info->s, "SKL:%01X", SKL); 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 CPUINFO_STR_NAME: strcpy(info->s, "COP445"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); 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 CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 6; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = ADDRESS_MAP_NAME(cop424_internal_rom); break;
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:
- info->internal_map8 = ADDRESS_MAP_NAME(cop424_internal_ram); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP424"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); 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 CPUINFO_STR_NAME: strcpy(info->s, "COP425"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); 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 CPUINFO_STR_NAME: strcpy(info->s, "COP426"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- default: CPU_GET_INFO_CALL(cop424); break;
- }
-}
-
-CPU_GET_INFO( cop404 )
-{
- // COP404 is a ROMless version of the COP444, which can emulate a COP410 or a COP424
-
- switch (state)
- {
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
- info->internal_map8 = NULL; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "COP404"); break;
- case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "National Semiconductor COPS"); break;
-
- default: CPU_GET_INFO_CALL(cop444); break;
- }
-}
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak
index da1825a40d0..8c54a6e456e 100644
--- a/src/emu/cpu/cpu.mak
+++ b/src/emu/cpu/cpu.mak
@@ -300,55 +300,23 @@ $(CPUOBJ)/cdp1802/cdp1802.o: $(CPUSRC)/cdp1802/cdp1802.c \
#-------------------------------------------------
-# National Semiconductor COP4xx
-#-------------------------------------------------
-
-CPUDEFS += -DHAS_COP401=$(if $(filter COP401,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP410=$(if $(filter COP410,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP411=$(if $(filter COP411,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP402=$(if $(filter COP402,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP420=$(if $(filter COP420,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP421=$(if $(filter COP421,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP422=$(if $(filter COP421,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP404=$(if $(filter COP404,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP424=$(if $(filter COP424,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP425=$(if $(filter COP425,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP426=$(if $(filter COP426,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP444=$(if $(filter COP444,$(CPUS)),1,0)
-CPUDEFS += -DHAS_COP445=$(if $(filter COP445,$(CPUS)),1,0)
-
-ifneq ($(filter COP401 COP410 COP411,$(CPUS)),)
-OBJDIRS += $(CPUOBJ)/cop400
-CPUOBJS += $(CPUOBJ)/cop400/cop410.o
-DBGOBJS += $(CPUOBJ)/cop400/cop410ds.o
-endif
+# National Semiconductor COP400 family
+#-------------------------------------------------
-ifneq ($(filter COP402 COP420 COP421 COP422,$(CPUS)),)
-OBJDIRS += $(CPUOBJ)/cop400
-CPUOBJS += $(CPUOBJ)/cop400/cop420.o
-DBGOBJS += $(CPUOBJ)/cop400/cop420ds.o
-endif
+CPUDEFS += -DHAS_COP400=$(if $(filter COP400,$(CPUS)),1,0)
-ifneq ($(filter COP404 COP424 COP425 COP426 COP444 COP445,$(CPUS)),)
+ifneq ($(filter COP400,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/cop400
-CPUOBJS += $(CPUOBJ)/cop400/cop440.o
+CPUOBJS += $(CPUOBJ)/cop400/cop400.o
+DBGOBJS += $(CPUOBJ)/cop400/cop410ds.o
+DBGOBJS += $(CPUOBJ)/cop400/cop420ds.o
DBGOBJS += $(CPUOBJ)/cop400/cop440ds.o
endif
-$(CPUOBJ)/cop400/cop410.o: $(CPUSRC)/cop400/cop410.c \
+$(CPUOBJ)/cop400/cop400.o: $(CPUSRC)/cop400/cop400.c \
$(CPUSRC)/cop400/cop400.h \
- $(CPUSRC)/cop400/410ops.c
+ $(CPUSRC)/cop400/cop400op.c
-$(CPUOBJ)/cop400/cop420.o: $(CPUSRC)/cop400/cop420.c \
- $(CPUSRC)/cop400/cop400.h \
- $(CPUSRC)/cop400/410ops.c \
- $(CPUSRC)/cop400/420ops.c
-
-$(CPUOBJ)/cop400/cop440.o: $(CPUSRC)/cop400/cop440.c \
- $(CPUSRC)/cop400/cop400.h \
- $(CPUSRC)/cop400/410ops.c \
- $(CPUSRC)/cop400/420ops.c \
- $(CPUSRC)/cop400/440ops.c
#-------------------------------------------------
diff --git a/src/mame/mame.mak b/src/mame/mame.mak
index f5f65acf5c5..66af229bf32 100644
--- a/src/mame/mame.mak
+++ b/src/mame/mame.mak
@@ -178,19 +178,7 @@ CPUS += RSP
CPUS += ALPHA8201
CPUS += ALPHA8301
CPUS += CDP1802
-CPUS += COP401
-CPUS += COP410
-CPUS += COP411
-CPUS += COP402
-CPUS += COP420
-CPUS += COP421
-CPUS += COP422
-CPUS += COP404
-CPUS += COP424
-CPUS += COP425
-CPUS += COP426
-CPUS += COP444
-CPUS += COP445
+CPUS += COP400
CPUS += TLCS90
CPUS += MB8841
CPUS += MB8842