diff options
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 |
commit | de81d24aabab83a32d3ee724845b5e53d0108b69 (patch) | |
tree | 78d42c35470aa47666e50d5b76c73abfee48a05e /src | |
parent | ac0abd17066f0b9c95a64430be86c451c6ae6f32 (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.c | 339 | ||||
-rw-r--r-- | src/emu/cpu/cop400/440ops.c | 68 | ||||
-rw-r--r-- | src/emu/cpu/cop400/cop400.c | 1651 | ||||
-rw-r--r-- | src/emu/cpu/cop400/cop400.h | 114 | ||||
-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.c | 514 | ||||
-rw-r--r-- | src/emu/cpu/cop400/cop420.c | 621 | ||||
-rw-r--r-- | src/emu/cpu/cop400/cop440.c | 681 | ||||
-rw-r--r-- | src/emu/cpu/cpu.mak | 50 | ||||
-rw-r--r-- | src/mame/mame.mak | 14 |
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 |