From a8475e4c1e642020366311c65bc0dbccc3c0529c Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Tue, 18 Nov 2008 17:15:40 +0000 Subject: [PATCH] Pointerized the COP400 CPU cores. --- .gitattributes | 3 + src/emu/cpu/cop400/410ops.c | 258 ++++++++----- src/emu/cpu/cop400/420ops.c | 126 ++++++- src/emu/cpu/cop400/440ops.c | 68 ++++ src/emu/cpu/cop400/cop400.h | 6 +- src/emu/cpu/cop400/cop410.c | 211 +++++------ src/emu/cpu/cop400/cop420.c | 526 +++++++------------------- src/emu/cpu/cop400/cop440.c | 690 ++++++++++++++++++++++++++++++++++ src/emu/cpu/cop400/cop440ds.c | 416 ++++++++++++++++++++ src/emu/cpu/cpu.mak | 24 +- src/emu/cpuintrf.c | 86 +++-- src/emu/cpuintrf.h | 21 +- src/mame/drivers/cidelsa.c | 4 +- src/mame/drivers/thayers.c | 7 +- src/mame/mame.mak | 9 + 15 files changed, 1793 insertions(+), 662 deletions(-) create mode 100644 src/emu/cpu/cop400/440ops.c create mode 100644 src/emu/cpu/cop400/cop440.c create mode 100644 src/emu/cpu/cop400/cop440ds.c diff --git a/.gitattributes b/.gitattributes index c5e8f9f3c98..6e968aa5b20 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,11 +51,14 @@ src/emu/cpu/cdp1802/cdp1802.c svneol=native#text/plain src/emu/cpu/cdp1802/cdp1802.h svneol=native#text/plain src/emu/cpu/cop400/410ops.c svneol=native#text/plain src/emu/cpu/cop400/420ops.c svneol=native#text/plain +src/emu/cpu/cop400/440ops.c svneol=native#text/plain src/emu/cpu/cop400/cop400.h svneol=native#text/plain src/emu/cpu/cop400/cop410.c svneol=native#text/plain src/emu/cpu/cop400/cop410ds.c svneol=native#text/plain src/emu/cpu/cop400/cop420.c svneol=native#text/plain src/emu/cpu/cop400/cop420ds.c svneol=native#text/plain +src/emu/cpu/cop400/cop440.c svneol=native#text/plain +src/emu/cpu/cop400/cop440ds.c svneol=native#text/plain src/emu/cpu/cp1610/1610dasm.c svneol=native#text/plain src/emu/cpu/cp1610/cp1610.c svneol=native#text/plain src/emu/cpu/cp1610/cp1610.h svneol=native#text/plain diff --git a/src/emu/cpu/cop400/410ops.c b/src/emu/cpu/cop400/410ops.c index 32a18b185a8..bbc42849eaa 100644 --- a/src/emu/cpu/cop400/410ops.c +++ b/src/emu/cpu/cop400/410ops.c @@ -9,7 +9,73 @@ ***************************************************************************/ -#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(UINT8 opcode) +#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; + + /* 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 */ + + /* 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(addr) program_decrypted_read_byte(addr) #define RAM_W(addr, value) (data_write_byte_8le(addr, value)) @@ -18,28 +84,26 @@ #define IN(addr) io_read_byte_8le(addr) #define OUT(addr, value) io_write_byte_8le(addr, value) -#define A R.A -#define B R.B -#define C R.C -#define G R.G -#define Q R.Q -#define EN R.EN -#define SA R.SA -#define SB R.SB -#define SIO R.SIO -#define SKL R.SKL -#define PC R.PC -#define prevPC R.PREVPC -#define skip R.skip -#define skipLBI R.skipLBI +#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) & R.G_mask) +#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) & R.D_mask) +#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)) @@ -50,11 +114,11 @@ /* Serial I/O */ -static TIMER_CALLBACK(cop410_serial_tick) +static TIMER_CALLBACK( cop400_serial_tick ) { - int cpunum = param; + cop400_state *cop400 = ptr; - cpu_push_context(machine->cpu[cpunum]); + cpu_push_context(cop400->device); if (BIT(EN, 0)) { @@ -76,10 +140,10 @@ static TIMER_CALLBACK(cop410_serial_tick) // serial input - R.si <<= 1; - R.si = (R.si & 0x0e) | IN_SI(); + cop400->si <<= 1; + cop400->si = (cop400->si & 0x0e) | IN_SI(); - if ((R.si & 0x0f) == 0x0c) // 1100 + if ((cop400->si & 0x0f) == 0x0c) // 1100 { SIO--; SIO &= 0x0f; @@ -129,7 +193,7 @@ static TIMER_CALLBACK(cop410_serial_tick) cpu_pop_context(); } -INLINE void WRITE_Q(UINT8 data) +INLINE void WRITE_Q(cop400_state *cop400, UINT8 data) { Q = data; @@ -139,11 +203,11 @@ INLINE void WRITE_Q(UINT8 data) } } -INLINE void WRITE_G(UINT8 data) +INLINE void WRITE_G(cop400_state *cop400, UINT8 data) { - if (R.intf->microbus == COP400_MICROBUS_ENABLED) + if (cop400->intf->microbus == COP400_MICROBUS_ENABLED) { - data = (data & 0x0e) | R.microbus_int; + data = (data & 0x0e) | cop400->microbus_int; } G = data; @@ -181,7 +245,7 @@ INSTRUCTION(asc) if (A > 0xF) { C = 1; - skip = 1; + cop400->skip = 1; A &= 0xF; } else @@ -203,7 +267,7 @@ INSTRUCTION(asc) */ -INSTRUCTION(add) +INSTRUCTION( add ) { A = (A + RAM_R(B)) & 0x0F; } @@ -224,7 +288,7 @@ INSTRUCTION(add) */ -INSTRUCTION(aisc) +INSTRUCTION( aisc ) { UINT4 y = opcode & 0x0f; @@ -232,7 +296,7 @@ INSTRUCTION(aisc) if (A > 0x0f) { - skip = 1; + cop400->skip = 1; A &= 0xF; } } @@ -250,7 +314,7 @@ INSTRUCTION(aisc) */ -INSTRUCTION(clra) +INSTRUCTION( clra ) { A = 0; } @@ -268,7 +332,7 @@ INSTRUCTION(clra) */ -INSTRUCTION(comp) +INSTRUCTION( comp ) { A = A ^ 0xF; } @@ -284,7 +348,7 @@ INSTRUCTION(comp) */ -INSTRUCTION(nop) +INSTRUCTION( nop ) { // do nothing } @@ -302,7 +366,7 @@ INSTRUCTION(nop) */ -INSTRUCTION(rc) +INSTRUCTION( rc ) { C = 0; } @@ -320,7 +384,7 @@ INSTRUCTION(rc) */ -INSTRUCTION(sc) +INSTRUCTION( sc ) { C = 1; } @@ -338,7 +402,7 @@ INSTRUCTION(sc) */ -INSTRUCTION(xor) +INSTRUCTION( xor ) { A = A ^ RAM_R(B); } @@ -358,7 +422,7 @@ INSTRUCTION(xor) */ -INSTRUCTION(jid) +INSTRUCTION( jid ) { UINT16 addr = (PC & 0x300) | (A << 4) | RAM_R(B); PC = (PC & 0x300) | ROM(addr); @@ -378,7 +442,7 @@ INSTRUCTION(jid) */ -INSTRUCTION(jmp) +INSTRUCTION( jmp ) { UINT16 a = ((opcode & 0x03) << 8) | ROM(PC); @@ -405,7 +469,7 @@ INSTRUCTION(jmp) */ -INSTRUCTION(jp) +INSTRUCTION( jp ) { UINT4 page = PC >> 6; @@ -443,7 +507,7 @@ INSTRUCTION(jp) */ -INSTRUCTION(jsr) +INSTRUCTION( jsr ) { UINT16 a = ((opcode & 0x03) << 8) | ROM(PC); @@ -464,7 +528,7 @@ INSTRUCTION(jsr) */ -INSTRUCTION(ret) +INSTRUCTION( ret ) { POP(); } @@ -484,10 +548,10 @@ INSTRUCTION(ret) */ -INSTRUCTION(retsk) +INSTRUCTION( retsk ) { POP(); - skip = 1; + cop400->skip = 1; } /* @@ -503,9 +567,9 @@ INSTRUCTION(retsk) */ -INSTRUCTION(halt) +INSTRUCTION( halt ) { - R.halt = 1; + cop400->halt = 1; } /* Memory Reference Instructions */ @@ -524,7 +588,7 @@ INSTRUCTION(halt) */ -INSTRUCTION(camq) +INSTRUCTION( camq ) { /* @@ -559,11 +623,11 @@ INSTRUCTION(camq) UINT8 data = (A << 4) | RAM_R(B); - WRITE_Q(data); + WRITE_Q(cop400, data); #ifdef CAMQ_BUG - WRITE_Q(0x3c); - WRITE_Q(data); + WRITE_Q(cop400, 0x3c); + WRITE_Q(cop400, data); #endif } @@ -582,7 +646,7 @@ INSTRUCTION(camq) */ -INSTRUCTION(ld) +INSTRUCTION( ld ) { UINT8 r = opcode & 0x30; @@ -604,11 +668,11 @@ INSTRUCTION(ld) */ -INSTRUCTION(lqid) +INSTRUCTION( lqid ) { PUSH(PC); PC = (PC & 0x300) | (A << 4) | RAM_R(B); - WRITE_Q(ROM(PC)); + WRITE_Q(cop400, ROM(PC)); POP(); } @@ -640,10 +704,10 @@ INSTRUCTION(lqid) */ -INSTRUCTION(rmb0) { RAM_W(B, RAM_R(B) & 0xE); } -INSTRUCTION(rmb1) { RAM_W(B, RAM_R(B) & 0xD); } -INSTRUCTION(rmb2) { RAM_W(B, RAM_R(B) & 0xB); } -INSTRUCTION(rmb3) { RAM_W(B, RAM_R(B) & 0x7); } +INSTRUCTION( rmb0 ) { RAM_W(B, RAM_R(B) & 0xE); } +INSTRUCTION( rmb1 ) { RAM_W(B, RAM_R(B) & 0xD); } +INSTRUCTION( rmb2 ) { RAM_W(B, RAM_R(B) & 0xB); } +INSTRUCTION( rmb3 ) { RAM_W(B, RAM_R(B) & 0x7); } /* @@ -673,10 +737,10 @@ INSTRUCTION(rmb3) { RAM_W(B, RAM_R(B) & 0x7); } */ -INSTRUCTION(smb0) { RAM_W(B, RAM_R(B) | 0x1); } -INSTRUCTION(smb1) { RAM_W(B, RAM_R(B) | 0x2); } -INSTRUCTION(smb2) { RAM_W(B, RAM_R(B) | 0x4); } -INSTRUCTION(smb3) { RAM_W(B, RAM_R(B) | 0x8); } +INSTRUCTION( smb0 ) { RAM_W(B, RAM_R(B) | 0x1); } +INSTRUCTION( smb1 ) { RAM_W(B, RAM_R(B) | 0x2); } +INSTRUCTION( smb2 ) { RAM_W(B, RAM_R(B) | 0x4); } +INSTRUCTION( smb3 ) { RAM_W(B, RAM_R(B) | 0x8); } /* @@ -693,7 +757,7 @@ INSTRUCTION(smb3) { RAM_W(B, RAM_R(B) | 0x8); } */ -INSTRUCTION(stii) +INSTRUCTION( stii ) { UINT4 y = opcode & 0x0f; UINT16 Bd; @@ -719,7 +783,7 @@ INSTRUCTION(stii) */ -INSTRUCTION(x) +INSTRUCTION( x ) { UINT4 r = opcode & 0x30; UINT8 t = RAM_R(B); @@ -744,7 +808,7 @@ INSTRUCTION(x) */ -INSTRUCTION(xad) +INSTRUCTION( xad ) { UINT8 rd = opcode & 0x3f; UINT8 t = A; @@ -772,7 +836,7 @@ INSTRUCTION(xad) */ -INSTRUCTION(xds) +INSTRUCTION( xds ) { UINT8 t, Bd; UINT4 r = opcode & 0x30; @@ -786,7 +850,7 @@ INSTRUCTION(xds) B = B ^ r; - if (Bd == 0x0f) skip = 1; + if (Bd == 0x0f) cop400->skip = 1; } /* @@ -807,7 +871,7 @@ INSTRUCTION(xds) */ -INSTRUCTION(xis) +INSTRUCTION( xis ) { UINT8 t, Bd; UINT4 r = opcode & 0x30; @@ -821,7 +885,7 @@ INSTRUCTION(xis) B = B ^ r; - if (Bd == 0x00) skip = 1; + if (Bd == 0x00) cop400->skip = 1; } /* Register Reference Instructions */ @@ -839,7 +903,7 @@ INSTRUCTION(xis) */ -INSTRUCTION(cab) +INSTRUCTION( cab ) { B = (B & 0x30) | A; } @@ -857,7 +921,7 @@ INSTRUCTION(cab) */ -INSTRUCTION(cba) +INSTRUCTION( cba ) { A = B & 0xF; } @@ -881,7 +945,7 @@ INSTRUCTION(cba) */ -INSTRUCTION(lbi) +INSTRUCTION( lbi ) { if (opcode & 0x80) { @@ -892,7 +956,7 @@ INSTRUCTION(lbi) B = (opcode & 0x30) | (((opcode & 0x0f) + 1) & 0x0f); } - skipLBI = 1; + cop400->skip_lbi = 1; } /* @@ -909,7 +973,7 @@ INSTRUCTION(lbi) */ -INSTRUCTION(lei) +INSTRUCTION( lei ) { UINT4 y = opcode & 0x0f; @@ -936,9 +1000,9 @@ INSTRUCTION(lei) */ -INSTRUCTION(skc) +INSTRUCTION( skc ) { - if (C == 1) skip = 1; + if (C == 1) cop400->skip = 1; } /* @@ -954,9 +1018,9 @@ INSTRUCTION(skc) */ -INSTRUCTION(ske) +INSTRUCTION( ske ) { - if (A == RAM_R(B)) skip = 1; + if (A == RAM_R(B)) cop400->skip = 1; } /* @@ -972,9 +1036,9 @@ INSTRUCTION(ske) */ -INSTRUCTION(skgz) +INSTRUCTION( skgz ) { - if (IN_G() == 0) skip = 1; + if (IN_G() == 0) cop400->skip = 1; } /* @@ -997,15 +1061,15 @@ INSTRUCTION(skgz) */ -INLINE void skgbz(int bit) +INLINE void skgbz(cop400_state *cop400, int bit) { - if (!BIT(IN_G(), bit)) skip = 1; + if (!BIT(IN_G(), bit)) cop400->skip = 1; } -INSTRUCTION(skgbz0) { skgbz(0); } -INSTRUCTION(skgbz1) { skgbz(1); } -INSTRUCTION(skgbz2) { skgbz(2); } -INSTRUCTION(skgbz3) { skgbz(3); } +INSTRUCTION( skgbz0 ) { skgbz(cop400, 0); } +INSTRUCTION( skgbz1 ) { skgbz(cop400, 1); } +INSTRUCTION( skgbz2 ) { skgbz(cop400, 2); } +INSTRUCTION( skgbz3 ) { skgbz(cop400, 3); } /* @@ -1027,15 +1091,15 @@ INSTRUCTION(skgbz3) { skgbz(3); } */ -INLINE void skmbz(int bit) +INLINE void skmbz(cop400_state *cop400, int bit) { - if (!BIT(RAM_R(B), bit)) skip = 1; + if (!BIT(RAM_R(B), bit)) cop400->skip = 1; } -INSTRUCTION(skmbz0) { skmbz(0); } -INSTRUCTION(skmbz1) { skmbz(1); } -INSTRUCTION(skmbz2) { skmbz(2); } -INSTRUCTION(skmbz3) { skmbz(3); } +INSTRUCTION( skmbz0 ) { skmbz(cop400, 0); } +INSTRUCTION( skmbz1 ) { skmbz(cop400, 1); } +INSTRUCTION( skmbz2 ) { skmbz(cop400, 2); } +INSTRUCTION( skmbz3 ) { skmbz(cop400, 3); } /* Input/Output Instructions */ @@ -1052,7 +1116,7 @@ INSTRUCTION(skmbz3) { skmbz(3); } */ -INSTRUCTION(ing) +INSTRUCTION( ing ) { A = IN_G(); } @@ -1071,7 +1135,7 @@ INSTRUCTION(ing) */ -INSTRUCTION(inl) +INSTRUCTION( inl ) { UINT8 L = IN_L(); @@ -1092,7 +1156,7 @@ INSTRUCTION(inl) */ -INSTRUCTION(obd) +INSTRUCTION( obd ) { OUT_D(B & 0x0f); } @@ -1110,9 +1174,9 @@ INSTRUCTION(obd) */ -INSTRUCTION(omg) +INSTRUCTION( omg ) { - WRITE_G(RAM_R(B)); + WRITE_G(cop400, RAM_R(B)); } /* @@ -1129,7 +1193,7 @@ INSTRUCTION(omg) */ -INSTRUCTION(xas) +INSTRUCTION( xas ) { UINT8 t = SIO; SIO = A; diff --git a/src/emu/cpu/cop400/420ops.c b/src/emu/cpu/cop400/420ops.c index d65f68484eb..75429b9b10e 100644 --- a/src/emu/cpu/cop400/420ops.c +++ b/src/emu/cpu/cop400/420ops.c @@ -9,15 +9,101 @@ ***************************************************************************/ -#define SC R.SC -#define IL R.IL +#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() (R.IN_mask ? IN(COP400_PORT_IN) : 0) +#define IN_IN() (cop400->in_mask ? IN(COP400_PORT_IN) : 0) + +/* Timer Counter */ + +static TIMER_CALLBACK( cop400_counter_tick ) +{ + cop400_state *cop400 = ptr; + + cpu_push_context(cop400->device); + + T++; + + if (T == 0) + { + cop400->skt_latch = 1; + + if (cop400->idle) + { + cop400->idle = 0; + cop400->halt = 0; + } + } + + cpu_pop_context(); +} + +/* IN Latches */ + +static TIMER_CALLBACK( cop400_inil_tick ) +{ + cop400_state *cop400 = ptr; + UINT8 in; + int i; + + cpu_push_context(cop400->device); + + 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); + } + } + + cpu_pop_context(); +} + +/* Microbus */ + +static TIMER_CALLBACK( cop400_microbus_tick ) +{ + cop400_state *cop400 = ptr; + UINT8 in; + + cpu_push_context(cop400->device); + + 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; + } + } + + cpu_pop_context(); +} /* Arithmetic Instructions */ @@ -34,7 +120,7 @@ */ -INSTRUCTION(adt) +INSTRUCTION( adt ) { A = (A + 10) & 0x0F; } @@ -55,14 +141,14 @@ INSTRUCTION(adt) */ -INSTRUCTION(casc) +INSTRUCTION( casc ) { A = (A ^ 0xF) + RAM_R(B) + C; if (A > 0xF) { C = 1; - skip = 1; + cop400->skip = 1; A &= 0xF; } else @@ -86,10 +172,10 @@ INSTRUCTION(casc) */ -INSTRUCTION(cop420_ret) +INSTRUCTION( cop420_ret ) { POP(); - skip = R.last_skip; + cop400->skip = cop400->last_skip; } /* Memory Reference Instructions */ @@ -108,7 +194,7 @@ INSTRUCTION(cop420_ret) */ -INSTRUCTION(cqma) +INSTRUCTION( cqma ) { RAM_W(B, Q >> 4); A = Q & 0xF; @@ -128,7 +214,7 @@ INSTRUCTION(cqma) */ -INSTRUCTION(ldd) +INSTRUCTION( ldd ) { UINT8 rd = opcode & 0x3f; @@ -150,7 +236,7 @@ INSTRUCTION(ldd) */ -INSTRUCTION(xabr) +INSTRUCTION( xabr ) { UINT8 Br = A & 0x03; UINT8 Bd = B & 0x0f; @@ -174,12 +260,12 @@ INSTRUCTION(xabr) */ -INSTRUCTION(skt) +INSTRUCTION( skt ) { - if (R.timerlatch) + if (cop400->skt_latch) { - R.timerlatch = 0; - skip = 1; + cop400->skt_latch = 0; + cop400->skip = 1; } } @@ -198,7 +284,7 @@ INSTRUCTION(skt) */ -INSTRUCTION(inin) +INSTRUCTION( inin ) { A = IN_IN(); } @@ -218,7 +304,7 @@ INSTRUCTION(inin) */ -INSTRUCTION(cop402m_inin) +INSTRUCTION( cop402m_inin ) { A = IN_IN() | 0x02; } @@ -236,7 +322,7 @@ INSTRUCTION(cop402m_inin) */ -INSTRUCTION(inil) +INSTRUCTION( inil ) { A = (IL & 0x09) | IN_CKO() << 2; @@ -257,9 +343,9 @@ INSTRUCTION(inil) */ -INSTRUCTION(ogi) +INSTRUCTION( ogi ) { UINT4 y = opcode & 0x0f; - WRITE_G(y); + WRITE_G(cop400, y); } diff --git a/src/emu/cpu/cop400/440ops.c b/src/emu/cpu/cop400/440ops.c new file mode 100644 index 00000000000..9642394daa7 --- /dev/null +++ b/src/emu/cpu/cop400/440ops.c @@ -0,0 +1,68 @@ +/*************************************************************************** + + 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.h b/src/emu/cpu/cop400/cop400.h index aade3162890..0726d84fc93 100644 --- a/src/emu/cpu/cop400/cop400.h +++ b/src/emu/cpu/cop400/cop400.h @@ -24,7 +24,7 @@ enum { - COP400_PC=1, + COP400_PC = 1, COP400_A, COP400_B, COP400_C, @@ -35,7 +35,8 @@ enum COP400_SB, COP400_SC, COP400_SIO, - COP400_SKL + COP400_SKL, + COP400_T }; typedef enum _cop400_cki_bond cop400_cki_bond; @@ -102,5 +103,6 @@ extern CPU_GET_INFO( cop445 ); CPU_DISASSEMBLE( cop410 ); CPU_DISASSEMBLE( cop420 ); +CPU_DISASSEMBLE( cop444 ); #endif /* __COP400__ */ diff --git a/src/emu/cpu/cop400/cop410.c b/src/emu/cpu/cop400/cop410.c index f9a4a208fad..b5c2cf37b3f 100644 --- a/src/emu/cpu/cop400/cop410.c +++ b/src/emu/cpu/cop400/cop410.c @@ -13,10 +13,11 @@ TODO: + - COP413/COP414/COP415/COP405 + - get rid of LBIOps/InstLen - run interrupt test suite - run production test suite - run microbus test suite - - remove LBIops */ @@ -25,53 +26,11 @@ #include "debugger.h" #include "cop400.h" -/* The opcode table now is a combination of cycle counts and function pointers */ -typedef struct { - unsigned cycles; - void (*function) (UINT8 opcode); -} s_opcode; - -#define UINT1 UINT8 -#define UINT4 UINT8 -#define UINT6 UINT8 -#define UINT9 UINT16 - -typedef struct -{ - const cop400_interface *intf; - - UINT9 PC; - UINT9 PREVPC; - UINT4 A; - UINT6 B; - UINT1 C; - UINT4 EN; - UINT4 G; - UINT8 Q; - UINT9 SA, SB; - UINT4 SIO; - UINT1 SKL; - UINT8 skip, skipLBI; - UINT8 G_mask; - UINT8 D_mask; - UINT8 si; - int microbus_int; - int halt; -} COP410_Regs; - -static COP410_Regs R; -static int cop410_ICount; - -static int InstLen[256]; -static int LBIops[256]; - -static emu_timer *cop410_serial_timer; - #include "410ops.c" /* Opcode Maps */ -static const s_opcode opcode_23_map[256]= +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 }, @@ -110,14 +69,14 @@ static const s_opcode opcode_23_map[256]= {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal } }; -static void cop410_op23(UINT8 opcode) +static void cop410_op23(cop400_state *cop400, UINT8 opcode) { UINT8 opcode23 = ROM(PC++); - (*(opcode_23_map[opcode23].function))(opcode23); + (*(COP410_OPCODE_23_MAP[opcode23].function))(cop400, opcode23); } -static const s_opcode opcode_33_map[256]= +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 }, @@ -156,14 +115,14 @@ static const s_opcode opcode_33_map[256]= {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal } }; -static void cop410_op33(UINT8 opcode) +static void cop410_op33(cop400_state *cop400, UINT8 opcode) { UINT8 opcode33 = ROM(PC++); - (*(opcode_33_map[opcode33].function))(opcode33); + (*(COP410_OPCODE_33_MAP[opcode33].function))(cop400, opcode33); } -static const s_opcode opcode_map[256]= +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 }, @@ -217,72 +176,72 @@ ADDRESS_MAP_END ****************************************************************************/ static CPU_INIT( cop410 ) { + cop400_state *cop400 = device->token; int i; - memset(&R, 0, sizeof(R)); - - R.intf = (cop400_interface *) device->static_config; - - assert(R.intf != NULL); + cop400->device = device; + cop400->intf = (cop400_interface *) device->static_config; /* set output pin masks */ - R.G_mask = 0x0f; - R.D_mask = 0x0f; + cop400->g_mask = 0x0f; + cop400->d_mask = 0x0f; /* set clock divider */ - cpu_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, R.intf->cki); + cpu_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki); /* allocate serial timer */ - cop410_serial_timer = timer_alloc(cop410_serial_tick, NULL); - timer_adjust_periodic(cop410_serial_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + cop400->serial_timer = timer_alloc(cop400_serial_tick, cop400); + timer_adjust_periodic(cop400->serial_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); /* initialize instruction length array */ - for (i=0; i<256; i++) InstLen[i]=1; + for (i=0; i<256; i++) cop400->InstLen[i]=1; - InstLen[0x60] = InstLen[0x61] = InstLen[0x68] = InstLen[0x69] = InstLen[0x33] = InstLen[0x23] = 2; + 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++) LBIops[i] = 0; - for (i=0x08; i<0x10; i++) LBIops[i] = 1; - for (i=0x18; i<0x20; i++) LBIops[i] = 1; - for (i=0x28; i<0x30; i++) LBIops[i] = 1; - for (i=0x38; i<0x40; i++) LBIops[i] = 1; + 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_item("cop410", device->tag, 0, PC); - state_save_register_item("cop410", device->tag, 0, R.PREVPC); - state_save_register_item("cop410", device->tag, 0, A); - state_save_register_item("cop410", device->tag, 0, B); - state_save_register_item("cop410", device->tag, 0, C); - state_save_register_item("cop410", device->tag, 0, EN); - state_save_register_item("cop410", device->tag, 0, G); - state_save_register_item("cop410", device->tag, 0, Q); - state_save_register_item("cop410", device->tag, 0, SA); - state_save_register_item("cop410", device->tag, 0, SB); - state_save_register_item("cop410", device->tag, 0, SIO); - state_save_register_item("cop410", device->tag, 0, SKL); - state_save_register_item("cop410", device->tag, 0, skip); - state_save_register_item("cop410", device->tag, 0, skipLBI); - state_save_register_item("cop410", device->tag, 0, R.G_mask); - state_save_register_item("cop410", device->tag, 0, R.D_mask); - state_save_register_item("cop410", device->tag, 0, R.si); - state_save_register_item("cop410", device->tag, 0, R.microbus_int); - state_save_register_item("cop410", device->tag, 0, R.halt); + state_save_register_item("cop410", device->tag, 0, cop400->pc); + state_save_register_item("cop410", device->tag, 0, cop400->prevpc); + state_save_register_item("cop410", device->tag, 0, cop400->a); + state_save_register_item("cop410", device->tag, 0, cop400->b); + state_save_register_item("cop410", device->tag, 0, cop400->c); + state_save_register_item("cop410", device->tag, 0, cop400->en); + state_save_register_item("cop410", device->tag, 0, cop400->g); + state_save_register_item("cop410", device->tag, 0, cop400->q); + state_save_register_item("cop410", device->tag, 0, cop400->sa); + state_save_register_item("cop410", device->tag, 0, cop400->sb); + state_save_register_item("cop410", device->tag, 0, cop400->sio); + state_save_register_item("cop410", device->tag, 0, cop400->skl); + state_save_register_item("cop410", device->tag, 0, cop400->skip); + state_save_register_item("cop410", device->tag, 0, cop400->skip_lbi); + state_save_register_item("cop410", device->tag, 0, cop400->g_mask); + state_save_register_item("cop410", device->tag, 0, cop400->d_mask); + state_save_register_item("cop410", device->tag, 0, cop400->si); + state_save_register_item("cop410", device->tag, 0, cop400->microbus_int); + state_save_register_item("cop410", device->tag, 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 */ - R.G_mask = 0x07; - R.D_mask = 0x03; + cop400->g_mask = 0x07; + cop400->d_mask = 0x03; } /**************************************************************************** @@ -290,15 +249,18 @@ static CPU_INIT( cop411 ) ****************************************************************************/ static CPU_RESET( cop410 ) { + cop400_state *cop400 = device->token; + PC = 0; A = 0; B = 0; C = 0; OUT_D(0); EN = 0; - WRITE_G(0); + WRITE_G(cop400, 0); + SKL = 1; - R.halt = 0; + cop400->halt = 0; } /**************************************************************************** @@ -306,9 +268,11 @@ static CPU_RESET( cop410 ) ****************************************************************************/ static CPU_EXECUTE( cop410 ) { + cop400_state *cop400 = device->token; + UINT8 opcode; - cop410_ICount = cycles; + cop400->icount = cycles; do { @@ -316,59 +280,65 @@ static CPU_EXECUTE( cop410 ) debugger_instruction_hook(device->machine, PC); - if (R.intf->cko == COP400_CKO_HALT_IO_PORT) + if (cop400->intf->cko == COP400_CKO_HALT_IO_PORT) { - R.halt = IN_CKO(); + cop400->halt = IN_CKO(); } - if (R.halt) continue; + if (cop400->halt) + { + cop400->icount -= 1; + continue; + } opcode = ROM(PC); - if (skipLBI == 1) + if (cop400->skip_lbi) { - if (LBIops[opcode] == 0) + if (cop400->LBIops[opcode]) { - skipLBI = 0; - } - else { - cop410_ICount -= opcode_map[opcode].cycles; + cop400->icount -= COP410_OPCODE_MAP[opcode].cycles; - PC += InstLen[opcode]; + PC += cop400->InstLen[opcode]; + } + else + { + cop400->skip_lbi = 0; } } - if (skipLBI == 0) + if (!cop400->skip_lbi) { - int inst_cycles = opcode_map[opcode].cycles; + int inst_cycles = COP410_OPCODE_MAP[opcode].cycles; PC++; - (*(opcode_map[opcode].function))(opcode); - cop410_ICount -= inst_cycles; + (*(COP410_OPCODE_MAP[opcode].function))(cop400, opcode); + cop400->icount -= inst_cycles; // skip next instruction? - if (skip == 1) + if (cop400->skip) { - void *function = opcode_map[ROM(PC)].function; + void *function = COP410_OPCODE_MAP[ROM(PC)].function; opcode = ROM(PC); if ((function == lqid) || (function == jid)) { - cop410_ICount -= 1; + cop400->icount -= 1; } else { - cop410_ICount -= opcode_map[opcode].cycles; + cop400->icount -= COP410_OPCODE_MAP[opcode].cycles; } - PC += InstLen[opcode]; - skip = 0; + PC += cop400->InstLen[opcode]; + + cop400->skip = 0; } } - } while (cop410_ICount > 0); + } while (cop400->icount > 0); - return cycles - cop410_ICount; + return cycles - cop400->icount; } /**************************************************************************** @@ -376,18 +346,13 @@ static CPU_EXECUTE( cop410 ) ****************************************************************************/ static CPU_GET_CONTEXT( cop410 ) { - if( dst ) - *(COP410_Regs*)dst = R; } - /**************************************************************************** * Set all registers to given values ****************************************************************************/ static CPU_SET_CONTEXT( cop410 ) { - if( src ) - R = *(COP410_Regs*)src; } /************************************************************************** @@ -413,6 +378,8 @@ static CPU_VALIDITY_CHECK( cop410 ) static CPU_SET_INFO( cop410 ) { + cop400_state *cop400 = device->token; + switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ @@ -438,10 +405,12 @@ static CPU_SET_INFO( cop410 ) 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(R); break; + 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 = CPU_IS_LE; break; @@ -456,7 +425,7 @@ CPU_GET_INFO( cop410 ) case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 9; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; /* Really 6 */ break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 9; break; @@ -488,7 +457,7 @@ CPU_GET_INFO( cop410 ) case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop410); break; case CPUINFO_PTR_BURN: info->burn = NULL; break; case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop410); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop410_ICount; break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break; case CPUINFO_PTR_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop410); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: diff --git a/src/emu/cpu/cop400/cop420.c b/src/emu/cpu/cop400/cop420.c index 7b580722843..733dd70cf07 100644 --- a/src/emu/cpu/cop400/cop420.c +++ b/src/emu/cpu/cop400/cop420.c @@ -13,78 +13,26 @@ 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 - - remove LBIops - - move cop440 stuff to cop440.c */ +#include "driver.h" #include "cpuintrf.h" #include "debugger.h" #include "cop400.h" -/* The opcode table now is a combination of cycle counts and function pointers */ -typedef struct { - unsigned cycles; - void (*function) (UINT8 opcode); -} s_opcode; - -#define UINT1 UINT8 -#define UINT4 UINT8 -#define UINT6 UINT8 -#define UINT10 UINT16 - -typedef struct -{ - const cop400_interface *intf; - - UINT10 PC; - UINT10 PREVPC; - UINT4 A; - UINT6 B; - UINT1 C; - UINT4 EN; - UINT4 G; - UINT8 Q; - UINT10 SA, SB, SC; - UINT4 SIO; - UINT1 SKL; - UINT8 skip, skipLBI; - UINT1 timerlatch; - UINT16 counter; - UINT8 G_mask; - UINT8 D_mask; - UINT8 IN_mask; - UINT4 IL; - UINT4 in[4]; - UINT8 si; - int last_skip; - int microbus_int; - int halt; -} COP420_Regs; - -static COP420_Regs R; -static int cop420_ICount; - -static int InstLen[256]; -static int LBIops[256]; -static int LBIops33[256]; - -static emu_timer *cop420_serial_timer; -static emu_timer *cop420_counter_timer; -static emu_timer *cop420_inil_timer; -static emu_timer *cop420_microbus_timer; - #include "420ops.c" /* Opcode Maps */ -static const s_opcode opcode_23_map[256]= +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 }, @@ -123,14 +71,14 @@ static const s_opcode opcode_23_map[256]= {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal } }; -static void cop420_op23(UINT8 opcode) +static void cop420_op23(cop400_state *cop400, UINT8 opcode) { UINT8 opcode23 = ROM(PC++); - (*(opcode_23_map[opcode23].function))(opcode23); + (*(COP420_OPCODE_23_MAP[opcode23].function))(cop400, opcode23); } -static const s_opcode opcode_33_map[256]= +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 }, @@ -169,14 +117,14 @@ static const s_opcode opcode_33_map[256]= {1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal } }; -static void cop420_op33(UINT8 opcode) +static void cop420_op33(cop400_state *cop400, UINT8 opcode) { UINT8 opcode33 = ROM(PC++); - (*(opcode_33_map[opcode33].function))(opcode33); + (*(COP420_OPCODE_33_MAP[opcode33].function))(cop400, opcode33); } -static const s_opcode opcode_map[256]= +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 }, @@ -225,201 +173,118 @@ static ADDRESS_MAP_START( cop420_internal_ram, ADDRESS_SPACE_DATA, 8 ) AM_RANGE(0x00, 0x3f) AM_RAM ADDRESS_MAP_END -/* Binary Counter */ - -static TIMER_CALLBACK(cop420_counter_tick) -{ - cpu_push_context(machine->cpu[param]); - - R.counter++; - - if (R.counter == 1024) - { - R.counter = 0; - R.timerlatch = 1; - } - - cpu_pop_context(); -} - -/* IN Latches */ - -static TIMER_CALLBACK(cop420_inil_tick) -{ - UINT8 in; - int i; - - cpu_push_context(machine->cpu[param]); - - in = IN_IN(); - for (i = 0; i < 4; i++) - { - R.in[i] = (R.in[i] << 1) | BIT(in, i); - - if ((R.in[i] & 0x07) == 0x04) // 100 - { - IL |= (1 << i); - } - } - - cpu_pop_context(); -} - -/* Microbus */ - -static TIMER_CALLBACK(cop420_microbus_tick) -{ - UINT8 in; - - cpu_push_context(machine->cpu[param]); - - in = IN_IN(); - - if (!BIT(in, 2)) - { - // chip select - - if (!BIT(in, 1)) - { - // read strobe - - OUT_L(Q); - - R.microbus_int = 1; - } - else if (!BIT(in, 3)) - { - // write strobe - - Q = IN_L(); - - R.microbus_int = 0; - } - } - - cpu_pop_context(); -} - /**************************************************************************** * Initialize emulation ****************************************************************************/ static CPU_INIT( cop420 ) { + cop400_state *cop400 = device->token; int i; - memset(&R, 0, sizeof(R)); - - R.intf = (cop400_interface *) device->static_config; - - assert(R.intf != NULL); + cop400->device = device; + cop400->intf = (cop400_interface *) device->static_config; /* set output pin masks */ - R.G_mask = 0x0f; // G0-G3 available - R.D_mask = 0x0f; // D0-D3 available - R.IN_mask = 0x0f; // IN0-IN3 available + cop400->g_mask = 0x0f; // G0-G3 available + cop400->d_mask = 0x0f; // D0-D3 available + cop400->in_mask = 0x0f; // IN0-IN3 available /* set clock divider */ - cpu_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, R.intf->cki); + cpu_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki); /* allocate serial timer */ - cop420_serial_timer = timer_alloc(cop410_serial_tick, NULL); - timer_adjust_periodic(cop420_serial_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + cop400->serial_timer = timer_alloc(cop400_serial_tick, cop400); + timer_adjust_periodic(cop400->serial_timer, attotime_zero, 0, ATTOTIME_IN_HZ(clock)); /* allocate counter timer */ - cop420_counter_timer = timer_alloc(cop420_counter_tick, NULL); - timer_adjust_periodic(cop420_counter_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + cop400->counter_timer = timer_alloc(cop400_counter_tick, cop400); + timer_adjust_periodic(cop400->counter_timer, attotime_zero, 0, ATTOTIME_IN_HZ(clock / 4)); /* allocate IN latch timer */ - cop420_inil_timer = timer_alloc(cop420_inil_tick, NULL); - timer_adjust_periodic(cop420_inil_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + cop400->inil_timer = timer_alloc(cop400_inil_tick, cop400); + timer_adjust_periodic(cop400->inil_timer, attotime_zero, 0, ATTOTIME_IN_HZ(clock)); /* allocate Microbus timer */ - if (R.intf->microbus == COP400_MICROBUS_ENABLED) + if (cop400->intf->microbus == COP400_MICROBUS_ENABLED) { - cop420_microbus_timer = timer_alloc(cop420_microbus_tick, NULL); - timer_adjust_periodic(cop420_microbus_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + cop400->microbus_timer = timer_alloc(cop400_microbus_tick, cop400); + timer_adjust_periodic(cop400->microbus_timer, attotime_zero, 0, ATTOTIME_IN_HZ(clock)); } /* initialize instruction length array */ - for (i=0; i<256; i++) InstLen[i]=1; + for (i=0; i<256; i++) cop400->InstLen[i]=1; - InstLen[0x60] = InstLen[0x61] = InstLen[0x62] = InstLen[0x63] = - InstLen[0x68] = InstLen[0x69] = InstLen[0x6a] = InstLen[0x6b] = - InstLen[0x33] = InstLen[0x23] = 2; + 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++) LBIops[i] = 0; - for (i=0x08; i<0x10; i++) LBIops[i] = 1; - for (i=0x18; i<0x20; i++) LBIops[i] = 1; - for (i=0x28; i<0x30; i++) LBIops[i] = 1; - for (i=0x38; i<0x40; i++) LBIops[i] = 1; + 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++) LBIops33[i] = 0; - for (i=0x80; i<0xc0; i++) LBIops33[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_item("cop420", device->tag, 0, PC); - state_save_register_item("cop420", device->tag, 0, R.PREVPC); - state_save_register_item("cop420", device->tag, 0, A); - state_save_register_item("cop420", device->tag, 0, B); - state_save_register_item("cop420", device->tag, 0, C); - state_save_register_item("cop420", device->tag, 0, EN); - state_save_register_item("cop420", device->tag, 0, G); - state_save_register_item("cop420", device->tag, 0, Q); - state_save_register_item("cop420", device->tag, 0, SA); - state_save_register_item("cop420", device->tag, 0, SB); - state_save_register_item("cop420", device->tag, 0, SC); - state_save_register_item("cop420", device->tag, 0, SIO); - state_save_register_item("cop420", device->tag, 0, SKL); - state_save_register_item("cop420", device->tag, 0, skip); - state_save_register_item("cop420", device->tag, 0, skipLBI); - state_save_register_item("cop420", device->tag, 0, R.timerlatch); - state_save_register_item("cop420", device->tag, 0, R.counter); - state_save_register_item("cop420", device->tag, 0, R.G_mask); - state_save_register_item("cop420", device->tag, 0, R.D_mask); - state_save_register_item("cop420", device->tag, 0, R.IN_mask); - state_save_register_item("cop420", device->tag, 0, R.si); - state_save_register_item("cop420", device->tag, 0, R.last_skip); - state_save_register_item_array("cop420", device->tag, 0, R.in); - state_save_register_item("cop420", device->tag, 0, R.microbus_int); - state_save_register_item("cop420", device->tag, 0, R.halt); + state_save_register_item("cop420", device->tag, 0, cop400->pc); + state_save_register_item("cop420", device->tag, 0, cop400->prevpc); + state_save_register_item("cop420", device->tag, 0, cop400->a); + state_save_register_item("cop420", device->tag, 0, cop400->b); + state_save_register_item("cop420", device->tag, 0, cop400->c); + state_save_register_item("cop420", device->tag, 0, cop400->en); + state_save_register_item("cop420", device->tag, 0, cop400->g); + state_save_register_item("cop420", device->tag, 0, cop400->q); + state_save_register_item("cop420", device->tag, 0, cop400->sa); + state_save_register_item("cop420", device->tag, 0, cop400->sb); + state_save_register_item("cop420", device->tag, 0, cop400->sc); + state_save_register_item("cop420", device->tag, 0, cop400->sio); + state_save_register_item("cop420", device->tag, 0, cop400->skl); + state_save_register_item("cop420", device->tag, 0, cop400->skip); + state_save_register_item("cop420", device->tag, 0, cop400->skip_lbi); + state_save_register_item("cop420", device->tag, 0, cop400->t); + state_save_register_item("cop420", device->tag, 0, cop400->skt_latch); + state_save_register_item("cop420", device->tag, 0, cop400->g_mask); + state_save_register_item("cop420", device->tag, 0, cop400->d_mask); + state_save_register_item("cop420", device->tag, 0, cop400->in_mask); + state_save_register_item("cop420", device->tag, 0, cop400->si); + state_save_register_item("cop420", device->tag, 0, cop400->last_skip); + state_save_register_item_array("cop420", device->tag, 0, cop400->in); + state_save_register_item("cop420", device->tag, 0, cop400->microbus_int); + state_save_register_item("cop420", device->tag, 0, cop400->halt); } static CPU_INIT( cop421 ) { + cop400_state *cop400 = device->token; + CPU_INIT_CALL(cop420); - /* microbus option is not available */ - - assert(R.intf->microbus != COP400_MICROBUS_ENABLED); - /* set output pin masks */ - - R.IN_mask = 0; // IN lines not available + cop400->in_mask = 0; // IN lines not available } static CPU_INIT( cop422 ) { + cop400_state *cop400 = device->token; + CPU_INIT_CALL(cop420); - /* microbus option is not available */ - - assert(R.intf->microbus != COP400_MICROBUS_ENABLED); - /* set output pin masks */ - - R.G_mask = 0x0e; // only G2, G3 available - R.D_mask = 0x0e; // only D2, D3 available - R.IN_mask = 0; // IN lines not available + cop400->g_mask = 0x0e; // only G2, G3 available + cop400->d_mask = 0x0e; // only D2, D3 available + cop400->in_mask = 0; // IN lines not available } /**************************************************************************** @@ -427,16 +292,19 @@ static CPU_INIT( cop422 ) ****************************************************************************/ static CPU_RESET( cop420 ) { + cop400_state *cop400 = device->token; + PC = 0; A = 0; B = 0; C = 0; OUT_D(0); EN = 0; - WRITE_G(0); + WRITE_G(cop400, 0); + SKL = 1; - R.counter = 0; - R.timerlatch = 1; + T = 0; + cop400->skt_latch = 1; } /**************************************************************************** @@ -444,9 +312,11 @@ static CPU_RESET( cop420 ) ****************************************************************************/ static CPU_EXECUTE( cop420 ) { + cop400_state *cop400 = device->token; + UINT8 opcode; - cop420_ICount = cycles; + cop400->icount = cycles; do { @@ -456,51 +326,49 @@ static CPU_EXECUTE( cop420 ) opcode = ROM(PC); - if (skipLBI == 1) + if (cop400->skip_lbi) { int is_lbi = 0; if (opcode == 0x33) { - is_lbi = LBIops33[ROM(PC+1)]; + is_lbi = cop400->LBIops33[ROM(PC+1)]; } else { - is_lbi = LBIops[opcode]; + is_lbi = cop400->LBIops[opcode]; } - if (is_lbi == 0) + if (is_lbi) { - skipLBI = 0; + cop400->icount -= COP420_OPCODE_MAP[opcode].cycles; + + PC += cop400->InstLen[opcode]; } else { - cop420_ICount -= opcode_map[opcode].cycles; - - PC += InstLen[opcode]; + cop400->skip_lbi = 0; } } - if (skipLBI == 0) + if (!cop400->skip_lbi) { - int inst_cycles = opcode_map[opcode].cycles; - + int inst_cycles = COP420_OPCODE_MAP[opcode].cycles; PC++; - - (*(opcode_map[opcode].function))(opcode); - cop420_ICount -= inst_cycles; + (*(COP420_OPCODE_MAP[opcode].function))(cop400, opcode); + cop400->icount -= inst_cycles; // check for interrupt if (BIT(EN, 1) && BIT(IL, 1)) { - void *function = opcode_map[ROM(PC)].function; + void *function = COP420_OPCODE_MAP[ROM(PC)].function; if ((function != jp) && (function != jmp) && (function != jsr)) { // store skip logic - R.last_skip = skip; - skip = 0; + cop400->last_skip = cop400->skip; + cop400->skip = 0; // push next PC PUSH(PC); @@ -517,28 +385,29 @@ static CPU_EXECUTE( cop420 ) // skip next instruction? - if (skip == 1) + if (cop400->skip) { - void *function = opcode_map[ROM(PC)].function; + void *function = COP420_OPCODE_MAP[ROM(PC)].function; opcode = ROM(PC); if ((function == lqid) || (function == jid)) { - cop420_ICount -= 1; + cop400->icount -= 1; } else { - cop420_ICount -= opcode_map[opcode].cycles; + cop400->icount -= COP420_OPCODE_MAP[opcode].cycles; } - PC += InstLen[opcode]; - skip = 0; + PC += cop400->InstLen[opcode]; + + cop400->skip = 0; } } - } while (cop420_ICount > 0); + } while (cop400->icount > 0); - return cycles - cop420_ICount; + return cycles - cop400->icount; } /**************************************************************************** @@ -546,18 +415,44 @@ static CPU_EXECUTE( cop420 ) ****************************************************************************/ static CPU_GET_CONTEXT( cop420 ) { - if( dst ) - *(COP420_Regs*)dst = R; } - /**************************************************************************** * Set all registers to given values ****************************************************************************/ static CPU_SET_CONTEXT( cop420 ) { - if( src ) - R = *(COP420_Regs*)src; +} + +/************************************************************************** + * 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; } /************************************************************************** @@ -566,6 +461,8 @@ static CPU_SET_CONTEXT( cop420 ) static CPU_SET_INFO( cop420 ) { + cop400_state *cop400 = device->token; + switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ @@ -592,10 +489,12 @@ static CPU_SET_INFO( cop420 ) 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(R); break; + 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 = CPU_IS_LE; break; @@ -610,7 +509,7 @@ CPU_GET_INFO( cop420 ) case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; /* Really 6 */ break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 9; break; @@ -643,10 +542,11 @@ CPU_GET_INFO( cop420 ) case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop420); break; case CPUINFO_PTR_BURN: info->burn = NULL; break; case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop420); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop420_ICount; break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break; + case CPUINFO_PTR_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop420); break; -/* case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: - info->internal_map8 = ADDRESS_MAP_NAME(cop420_internal_rom); break;*/ + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: + info->internal_map8 = ADDRESS_MAP_NAME(cop420_internal_rom); break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = ADDRESS_MAP_NAME(cop420_internal_ram); break; @@ -684,6 +584,7 @@ CPU_GET_INFO( cop421 ) { /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(cop421); break; + case CPUINFO_PTR_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; @@ -701,6 +602,7 @@ CPU_GET_INFO( cop422 ) { /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(cop422); break; + case CPUINFO_PTR_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; @@ -727,141 +629,3 @@ CPU_GET_INFO( cop402 ) default: CPU_GET_INFO_CALL(cop420); break; } } - -/* COP44x */ - -static CPU_INIT( cop426 ) -{ - CPU_INIT_CALL(cop420); - - R.G_mask = 0x0e; // only G2, G3 available - R.D_mask = 0x0e; // only D2, D3 available -} - -static CPU_INIT( cop445 ) -{ - CPU_INIT_CALL(cop420); - - R.G_mask = 0x07; - R.D_mask = 0x03; -} - -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 - -CPU_GET_INFO( cop444 ) -{ - switch (state) - { - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: - info->internal_map8 = ADDRESS_MAP_NAME(cop444_internal_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_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; - - default: CPU_GET_INFO_CALL(cop420); 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_PTR_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 pointers to data or functions --- */ - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: - info->internal_map8 = ADDRESS_MAP_NAME(cop424_internal_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_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 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(cop444); 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_PTR_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(cop444); 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 + ADDRESS_SPACE_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/cop400/cop440.c b/src/emu/cpu/cop400/cop440.c new file mode 100644 index 00000000000..2a96f37597d --- /dev/null +++ b/src/emu/cpu/cop400/cop440.c @@ -0,0 +1,690 @@ +/*************************************************************************** + + cop440.c + + National Semiconductor COP420 Emulator. + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +/* + + TODO: + + - COP441 + - 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; + + /* 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 */ + + cpu_set_info_int(device, CPUINFO_INT_CLOCK_DIVIDER, cop400->intf->cki); + + /* allocate serial timer */ + + cop400->serial_timer = timer_alloc(cop400_serial_tick, cop400); + timer_adjust_periodic(cop400->serial_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + + /* allocate counter timer */ + + cop400->counter_timer = timer_alloc(cop400_counter_tick, cop400); + timer_adjust_periodic(cop400->counter_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock / 4)); + + /* allocate IN latch timer */ + + cop400->inil_timer = timer_alloc(cop400_inil_tick, cop400); + timer_adjust_periodic(cop400->inil_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + + /* allocate Microbus timer */ + + if (cop400->intf->microbus == COP400_MICROBUS_ENABLED) + { + cop400->microbus_timer = timer_alloc(cop400_microbus_tick, cop400); + timer_adjust_periodic(cop400->microbus_timer, attotime_zero, index, ATTOTIME_IN_HZ(clock)); + } + + /* 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_item("cop420", device->tag, 0, cop400->pc); + state_save_register_item("cop420", device->tag, 0, cop400->prevpc); + state_save_register_item("cop420", device->tag, 0, cop400->a); + state_save_register_item("cop420", device->tag, 0, cop400->b); + state_save_register_item("cop420", device->tag, 0, cop400->c); + state_save_register_item("cop420", device->tag, 0, cop400->en); + state_save_register_item("cop420", device->tag, 0, cop400->g); + state_save_register_item("cop420", device->tag, 0, cop400->q); + state_save_register_item("cop420", device->tag, 0, cop400->sa); + state_save_register_item("cop420", device->tag, 0, cop400->sb); + state_save_register_item("cop420", device->tag, 0, cop400->sc); + state_save_register_item("cop420", device->tag, 0, cop400->sio); + state_save_register_item("cop420", device->tag, 0, cop400->skl); + state_save_register_item("cop420", device->tag, 0, cop400->skip); + state_save_register_item("cop420", device->tag, 0, cop400->skip_lbi); + state_save_register_item("cop420", device->tag, 0, cop400->t); + state_save_register_item("cop420", device->tag, 0, cop400->skt_latch); + state_save_register_item("cop420", device->tag, 0, cop400->g_mask); + state_save_register_item("cop420", device->tag, 0, cop400->d_mask); + state_save_register_item("cop420", device->tag, 0, cop400->in_mask); + state_save_register_item("cop420", device->tag, 0, cop400->si); + state_save_register_item("cop420", device->tag, 0, cop400->last_skip); + state_save_register_item_array("cop420", device->tag, 0, cop400->in); + state_save_register_item("cop420", device->tag, 0, cop400->microbus_int); + state_save_register_item("cop420", device->tag, 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->machine, 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; +} + +/**************************************************************************** + * Get all registers in given buffer + ****************************************************************************/ +static CPU_GET_CONTEXT( cop444 ) +{ +} + +/**************************************************************************** + * Set all registers to given values + ****************************************************************************/ +static CPU_SET_CONTEXT( cop444 ) +{ +} + +/************************************************************************** + * 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 = CPU_IS_LE; 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 + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 9; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_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_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cop444); break; + case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(cop444); break; + case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(cop444); break; + case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(cop444); break; + case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(cop444); break; + case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(cop444); break; + case CPUINFO_PTR_BURN: info->burn = NULL; break; + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(cop444); break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cop400->icount; break; + case CPUINFO_PTR_VALIDITY_CHECK: info->validity_check = CPU_VALIDITY_CHECK_NAME(cop444); break; + + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: + info->internal_map8 = ADDRESS_MAP_NAME(cop444_internal_rom); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_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_PTR_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 + ADDRESS_SPACE_DATA: info->i = 6; break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: + info->internal_map8 = ADDRESS_MAP_NAME(cop424_internal_rom); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_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_PTR_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_PTR_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 + ADDRESS_SPACE_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/cop400/cop440ds.c b/src/emu/cpu/cop400/cop440ds.c new file mode 100644 index 00000000000..724f3da6b01 --- /dev/null +++ b/src/emu/cpu/cop400/cop440ds.c @@ -0,0 +1,416 @@ +/*************************************************************************** + + cop420ds.c + + National Semiconductor COP420 Emulator. + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#include "cpuintrf.h" + +CPU_DISASSEMBLE( cop444 ) +{ + UINT8 opcode = oprom[0]; + UINT8 next_opcode = oprom[1]; + UINT16 address; + UINT32 flags = 0; + int bytes = 1; + + if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE)) + { + if ((pc & 0x3E0) >= 0x80 && (pc & 0x3E0) < 0x100) //JP pages 2,3 + { + address = (UINT16)((pc & 0x380) | (opcode & 0x7F)); + sprintf(buffer, "JP %x", address); + } + else + { + if ((opcode & 0xC0) == 0xC0) //JP other pages + { + address = (UINT16)((pc & 0x3C0) | (opcode & 0x3F)); + sprintf(buffer, "JP %x", address); + } + else //JSRP + { + address = (UINT16)(0x80 | (opcode & 0x3F)); + sprintf(buffer, "JSRP %x", address); + flags = DASMFLAG_STEP_OVER; + } + } + } + else if (opcode >= 0x08 && opcode <= 0x0F) + { + sprintf(buffer, "LBI 0,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x18 && opcode <= 0x1F) + { + sprintf(buffer, "LBI 1,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x28 && opcode <= 0x2F) + { + sprintf(buffer, "LBI 2,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x38 && opcode <= 0x3F) + { + sprintf(buffer, "LBI 3,%u", ((opcode & 0xF) + 1) & 0xF); + } + else if (opcode >= 0x51 && opcode <= 0x5F) + { + sprintf(buffer, "AISC %u", opcode & 0xF); + } + else if (opcode >= 0x60 && opcode <= 0x63) + { + address = ((opcode & 0x03) << 8) | next_opcode; + sprintf(buffer, "JMP %x", address); + bytes = 2; + } + else if (opcode >= 0x68 && opcode <= 0x6B) + { + address = ((opcode & 0x03) << 8) | next_opcode; + sprintf(buffer, "JSR %x", address); + flags = DASMFLAG_STEP_OVER; + bytes = 2; + } + else if (opcode >= 0x70 && opcode <= 0x7F) + { + sprintf(buffer, "STII %u", opcode & 0xF); + } + else + { + switch (opcode) + { + case 0: + sprintf(buffer, "CLRA"); + break; + + case 1: + sprintf(buffer, "SKMBZ 0"); + break; + + case 2: + sprintf(buffer, "XOR"); + break; + + case 3: + sprintf(buffer, "SKMBZ 2"); + break; + + case 4: + sprintf(buffer, "XIS 0"); + break; + + case 5: + sprintf(buffer, "LD 0"); + break; + + case 6: + sprintf(buffer, "X 0"); + break; + + case 7: + sprintf(buffer, "XDS 0"); + break; + + case 0x10: + sprintf(buffer, "CASC"); + break; + + case 0x11: + sprintf(buffer, "SKMBZ 1"); + break; + + case 0x12: + sprintf(buffer, "XABR"); + break; + + case 0x13: + sprintf(buffer, "SKMBZ 3"); + break; + + case 0x14: + sprintf(buffer, "XIS 1"); + break; + + case 0x15: + sprintf(buffer, "LD 1"); + break; + + case 0x16: + sprintf(buffer, "X 1"); + break; + + case 0x17: + sprintf(buffer, "XDS 1"); + break; + + case 0x20: + sprintf(buffer, "SKC"); + break; + + case 0x21: + sprintf(buffer, "SKE"); + break; + + case 0x22: + sprintf(buffer, "SC"); + break; + + case 0x23: + bytes = 2; + + if (next_opcode <= 0x3f) + { + address = (UINT16)(next_opcode & 0x3F); + sprintf(buffer, "LDD %x,%x", ((address & 0x30) >> 4),address & 0x0F); + } + else if (next_opcode >= 0x80 && next_opcode <= 0xbf) + { + address = (UINT16)(next_opcode & 0x3F); + sprintf(buffer, "XAD %x,%x", ((address & 0x30) >> 4),address & 0x0F); + } + else + { + sprintf(buffer, "Invalid"); + } + break; + + case 0x24: + sprintf(buffer, "XIS 2"); + break; + + case 0x25: + sprintf(buffer, "LD 2"); + break; + + case 0x26: + sprintf(buffer, "X 2"); + break; + + case 0x27: + sprintf(buffer, "XDS 2"); + break; + + case 0x30: + sprintf(buffer, "ASC"); + break; + + case 0x31: + sprintf(buffer, "ADD"); + break; + + case 0x32: + sprintf(buffer, "RC"); + break; + + case 0x33: + bytes = 2; + + if (next_opcode >= 0x50 && next_opcode <= 0x5F) + { + sprintf(buffer, "OGI %u", next_opcode & 0xF); + } + else if (next_opcode >= 0x60 && next_opcode <= 0x6F) + { + sprintf(buffer, "LEI %u", next_opcode & 0xF); + } + else if (next_opcode >= 0x80 && next_opcode <= 0x8F) + { + sprintf(buffer, "LBI 0,%u", next_opcode & 0xF); + } + else if (next_opcode >= 0x90 && next_opcode <= 0x9F) + { + sprintf(buffer, "LBI 1,%u", next_opcode & 0xF); + } + else if (next_opcode >= 0xA0 && next_opcode <= 0xAF) + { + sprintf(buffer, "LBI 2,%u", next_opcode & 0xF); + } + else if (next_opcode >= 0xB0 && next_opcode <= 0xBF) + { + sprintf(buffer, "LBI 3,%u", next_opcode & 0xF); + } + else + { + switch (next_opcode) + { + case 0x01: + sprintf(buffer, "SKGBZ 0"); + break; + + case 0x03: + sprintf(buffer, "SKGBZ 2"); + break; + + case 0x11: + sprintf(buffer, "SKGBZ 1"); + break; + + case 0x13: + sprintf(buffer, "SKGBZ 3"); + break; + + case 0x21: + sprintf(buffer, "SKGZ"); + break; + + case 0x28: + sprintf(buffer, "ININ"); + break; + + case 0x29: + sprintf(buffer, "INIL"); + break; + + case 0x2A: + sprintf(buffer, "ING"); + break; + + case 0x2C: + sprintf(buffer, "CQMA"); + break; + + case 0x2E: + sprintf(buffer, "INL"); + break; + + case 0x2F: + sprintf(buffer, "CTMA"); + break; + + case 0x38: + sprintf(buffer, "HALT"); + break; + + case 0x39: + sprintf(buffer, "IT"); + break; + + case 0x3A: + sprintf(buffer, "OMG"); + break; + + case 0x3C: + sprintf(buffer, "CAMQ"); + break; + + case 0x3E: + sprintf(buffer, "OBD"); + break; + + case 0x3F: + sprintf(buffer, "CAMT"); + break; + + + default: + sprintf(buffer, "Invalid"); + break; + } + } + break; + + case 0x34: + sprintf(buffer, "XIS 3"); + break; + + case 0x35: + sprintf(buffer, "LD 3"); + break; + + case 0x36: + sprintf(buffer, "X 3"); + break; + + case 0x37: + sprintf(buffer, "XDS 3"); + break; + + case 0x40: + sprintf(buffer, "COMP"); + break; + + case 0x41: + sprintf(buffer, "SKT"); + break; + + case 0x42: + sprintf(buffer, "RMB 2"); + break; + + case 0x43: + sprintf(buffer, "RMB 3"); + break; + + case 0x44: + sprintf(buffer, "NOP"); + break; + + case 0x45: + sprintf(buffer, "RMB 1"); + break; + + case 0x46: + sprintf(buffer, "SMB 2"); + break; + + case 0x47: + sprintf(buffer, "SMB 1"); + break; + + case 0x48: + sprintf(buffer, "RET"); + flags = DASMFLAG_STEP_OUT; + break; + + case 0x49: + sprintf(buffer, "RETSK"); + flags = DASMFLAG_STEP_OUT; + break; + + case 0x4A: + sprintf(buffer, "ADT"); + break; + + case 0x4B: + sprintf(buffer, "SMB 3"); + break; + + case 0x4C: + sprintf(buffer, "RMB 0"); + break; + + case 0x4D: + sprintf(buffer, "SMB 0"); + break; + + case 0x4E: + sprintf(buffer, "CBA"); + break; + + case 0x4F: + sprintf(buffer, "XAS"); + break; + + case 0x50: + sprintf(buffer, "CAB"); + break; + + case 0xBF: + sprintf(buffer, "LQID"); + break; + + case 0xFF: + sprintf(buffer, "JID"); + break; + + default: + sprintf(buffer, "Invalid"); + break; + } + } + + return bytes | flags | DASMFLAG_SUPPORTED; +} diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 8cf26d8b031..642c14d0fff 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -291,23 +291,38 @@ $(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 COP410 COP411,$(CPUS)),) +ifneq ($(filter COP401 COP410 COP411,$(CPUS)),) OBJDIRS += $(CPUOBJ)/cop400 CPUOBJS += $(CPUOBJ)/cop400/cop410.o DBGOBJS += $(CPUOBJ)/cop400/cop410ds.o endif -ifneq ($(filter COP420 COP421,$(CPUS)),) +ifneq ($(filter COP402 COP420 COP421 COP422,$(CPUS)),) OBJDIRS += $(CPUOBJ)/cop400 CPUOBJS += $(CPUOBJ)/cop400/cop420.o DBGOBJS += $(CPUOBJ)/cop400/cop420ds.o endif +ifneq ($(filter COP404 COP424 COP425 COP426 COP444 COP445,$(CPUS)),) +OBJDIRS += $(CPUOBJ)/cop400 +CPUOBJS += $(CPUOBJ)/cop400/cop440.o +DBGOBJS += $(CPUOBJ)/cop400/cop440ds.o +endif + $(CPUOBJ)/cop400/cop410.o: $(CPUSRC)/cop400/cop410.c \ $(CPUSRC)/cop400/cop400.h \ $(CPUSRC)/cop400/410ops.c @@ -317,6 +332,11 @@ $(CPUOBJ)/cop400/cop420.o: $(CPUSRC)/cop400/cop420.c \ $(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/emu/cpuintrf.c b/src/emu/cpuintrf.c index e98a4fc75f7..ed37820c350 100644 --- a/src/emu/cpuintrf.c +++ b/src/emu/cpuintrf.c @@ -229,10 +229,19 @@ CPU_GET_INFO( rsp ); CPU_GET_INFO( alpha8201 ); CPU_GET_INFO( alpha8301 ); CPU_GET_INFO( cdp1802 ); -CPU_GET_INFO( cop420 ); -CPU_GET_INFO( cop421 ); +CPU_GET_INFO( cop401 ); CPU_GET_INFO( cop410 ); CPU_GET_INFO( cop411 ); +CPU_GET_INFO( cop402 ); +CPU_GET_INFO( cop420 ); +CPU_GET_INFO( cop421 ); +CPU_GET_INFO( cop422 ); +CPU_GET_INFO( cop404 ); +CPU_GET_INFO( cop424 ); +CPU_GET_INFO( cop425 ); +CPU_GET_INFO( cop426 ); +CPU_GET_INFO( cop444 ); +CPU_GET_INFO( cop445 ); CPU_GET_INFO( tmp90840 ); CPU_GET_INFO( tmp90841 ); CPU_GET_INFO( tmp91640 ); @@ -801,11 +810,8 @@ static const struct #if (HAS_CDP1802) { CPU_CDP1802, CPU_GET_INFO_NAME(cdp1802) }, #endif -#if (HAS_COP420) - { CPU_COP420, CPU_GET_INFO_NAME(cop420) }, -#endif -#if (HAS_COP421) - { CPU_COP421, CPU_GET_INFO_NAME(cop421) }, +#if (HAS_COP401) + { CPU_COP401, CPU_GET_INFO_NAME(cop401) }, #endif #if (HAS_COP410) { CPU_COP410, CPU_GET_INFO_NAME(cop410) }, @@ -813,6 +819,36 @@ static const struct #if (HAS_COP411) { CPU_COP411, CPU_GET_INFO_NAME(cop411) }, #endif +#if (HAS_COP402) + { CPU_COP402, CPU_GET_INFO_NAME(cop402) }, +#endif +#if (HAS_COP420) + { CPU_COP420, CPU_GET_INFO_NAME(cop420) }, +#endif +#if (HAS_COP421) + { CPU_COP421, CPU_GET_INFO_NAME(cop421) }, +#endif +#if (HAS_COP422) + { CPU_COP422, CPU_GET_INFO_NAME(cop422) }, +#endif +#if (HAS_COP404) + { CPU_COP404, CPU_GET_INFO_NAME(cop404) }, +#endif +#if (HAS_COP424) + { CPU_COP424, CPU_GET_INFO_NAME(cop424) }, +#endif +#if (HAS_COP425) + { CPU_COP425, CPU_GET_INFO_NAME(cop425) }, +#endif +#if (HAS_COP426) + { CPU_COP426, CPU_GET_INFO_NAME(cop426) }, +#endif +#if (HAS_COP444) + { CPU_COP444, CPU_GET_INFO_NAME(cop444) }, +#endif +#if (HAS_COP445) + { CPU_COP445, CPU_GET_INFO_NAME(cop445) }, +#endif #if (HAS_TLCS90) { CPU_TMP90840, CPU_GET_INFO_NAME(tmp90840) }, { CPU_TMP90841, CPU_GET_INFO_NAME(tmp90841) }, @@ -921,7 +957,7 @@ INLINE char *get_temp_string_buffer(void) /*------------------------------------------------- - get_safe_classheader - makes sure that the + get_safe_classheader - makes sure that the passed in device is, in fact, a CPU, and return the class token -------------------------------------------------*/ @@ -944,7 +980,7 @@ INLINE cpu_class_header *get_safe_classheader(const device_config *device) INLINE void set_cpu_context(const device_config *oldcpu, const device_config *newcpu) { cpu_class_header *classheader; - + /* if nothing is changing, quick exit */ if (oldcpu == newcpu) return; @@ -955,7 +991,7 @@ INLINE void set_cpu_context(const device_config *oldcpu, const device_config *ne classheader = oldcpu->classtoken; (*classheader->get_context)(oldcpu->token); } - + /* swap in the new context if we have one */ if (newcpu != NULL) { @@ -1108,7 +1144,7 @@ int cpunum_get_active(void) int cpu_get_index_slow(const device_config *cpu) { int cpunum; - + for (cpunum = 0; cpunum < ARRAY_LENGTH(Machine->cpu); cpunum++) if (Machine->cpu[cpunum] == cpu) return cpunum; @@ -1131,7 +1167,7 @@ void cpu_init(const device_config *device, int index, int clock, cpu_irq_callbac memory_set_context(device->machine, index); device->machine->activecpu = device; - + classheader->index = index; classheader->space[ADDRESS_SPACE_PROGRAM] = active_address_space[ADDRESS_SPACE_PROGRAM]; classheader->space[ADDRESS_SPACE_DATA] = active_address_space[ADDRESS_SPACE_DATA]; @@ -1139,7 +1175,7 @@ void cpu_init(const device_config *device, int index, int clock, cpu_irq_callbac (*classheader->init)(device, index, clock, irqcallback); (*classheader->get_context)(device->token); - + device->machine->activecpu = NULL; } @@ -1151,7 +1187,7 @@ void cpu_init(const device_config *device, int index, int clock, cpu_irq_callbac void cpu_exit(const device_config *device) { cpu_class_header *classheader = get_safe_classheader(device); - + if (classheader->exit != NULL) { set_cpu_context(device->machine->activecpu, device); @@ -1162,7 +1198,7 @@ void cpu_exit(const device_config *device) /*------------------------------------------------- - cpu_get_info_* - return information about a + cpu_get_info_* - return information about a live CPU -------------------------------------------------*/ @@ -1216,7 +1252,7 @@ const char *cpu_get_info_string(const device_config *device, UINT32 state) /*------------------------------------------------- - cpu_set_info_* - set information about a + cpu_set_info_* - set information about a live CPU -------------------------------------------------*/ @@ -1256,7 +1292,7 @@ void cpu_set_info_fct(const device_config *device, UINT32 state, genf *data) /*------------------------------------------------- - cpu_execute - execute the requested cycles on + cpu_execute - execute the requested cycles on a given CPU -------------------------------------------------*/ @@ -1288,7 +1324,7 @@ void cpu_reset(const device_config *device) /*------------------------------------------------- - cpu_read_byte - read a byte from another CPU's + cpu_read_byte - read a byte from another CPU's memory space -------------------------------------------------*/ @@ -1304,7 +1340,7 @@ UINT8 cpu_read_byte(const device_config *device, offs_t address) /*------------------------------------------------- - cpu_write_byte - write a byte to another CPU's + cpu_write_byte - write a byte to another CPU's memory space -------------------------------------------------*/ @@ -1317,7 +1353,7 @@ void cpu_write_byte(const device_config *device, offs_t address, UINT8 data) /*------------------------------------------------- - cpu_get_physical_pc_byte - return the PC, + cpu_get_physical_pc_byte - return the PC, corrected to a byte offset and translated to physical space, on a given CPU -------------------------------------------------*/ @@ -1335,7 +1371,7 @@ offs_t cpu_get_physical_pc_byte(const device_config *device) /*------------------------------------------------- - cpu_dasm - disassemble a line at a given PC + cpu_dasm - disassemble a line at a given PC on a given CPU -------------------------------------------------*/ @@ -1343,7 +1379,7 @@ offs_t cpu_dasm(const device_config *device, char *buffer, offs_t pc, const UINT { cpu_class_header *classheader = get_safe_classheader(device); offs_t result = 0; - + cpu_push_context(device); /* check for disassembler override */ @@ -1396,7 +1432,7 @@ offs_t cpu_dasm(const device_config *device, char *buffer, offs_t pc, const UINT /*------------------------------------------------- - cpu_set_dasm_override - set a dasm override + cpu_set_dasm_override - set a dasm override handler -------------------------------------------------*/ @@ -1413,7 +1449,7 @@ void cpu_set_dasm_override(const device_config *device, cpu_disassemble_func das ***************************************************************************/ /*------------------------------------------------- - cputype_get_header_template - return a header + cputype_get_header_template - return a header template for a given CPU type -------------------------------------------------*/ @@ -1425,7 +1461,7 @@ const cpu_class_header *cputype_get_header_template(cpu_type cputype) /*------------------------------------------------- - cputype_get_info_* - return information about a + cputype_get_info_* - return information about a given CPU type -------------------------------------------------*/ diff --git a/src/emu/cpuintrf.h b/src/emu/cpuintrf.h index 1b1e87264f9..82182ac19e2 100644 --- a/src/emu/cpuintrf.h +++ b/src/emu/cpuintrf.h @@ -395,10 +395,19 @@ enum _cpu_type CPU_ALPHA8201, CPU_ALPHA8301, CPU_CDP1802, - CPU_COP420, - CPU_COP421, + CPU_COP401, CPU_COP410, CPU_COP411, + CPU_COP402, + CPU_COP420, + CPU_COP421, + CPU_COP422, + CPU_COP404, + CPU_COP424, + CPU_COP425, + CPU_COP426, + CPU_COP444, + CPU_COP445, CPU_TMP90840, CPU_TMP90841, CPU_TMP91640, @@ -744,7 +753,7 @@ const char *cputype_get_info_string(cpu_type cputype, UINT32 state); ***************************************************************************/ /*------------------------------------------------- - safe_cpu_get_pc - return the current PC or ~0 + safe_cpu_get_pc - return the current PC or ~0 if the CPU is invalid -------------------------------------------------*/ @@ -792,9 +801,9 @@ INLINE offs_t cpu_address_to_byte(const device_config *cpu, int space, offs_t ad /*------------------------------------------------- - cpu_address_to_byte_end - convert an address - in the specified address space to a byte - offset specifying the last byte covered by + cpu_address_to_byte_end - convert an address + in the specified address space to a byte + offset specifying the last byte covered by the address -------------------------------------------------*/ diff --git a/src/mame/drivers/cidelsa.c b/src/mame/drivers/cidelsa.c index 47f6166531f..387e66addf0 100644 --- a/src/mame/drivers/cidelsa.c +++ b/src/mame/drivers/cidelsa.c @@ -579,7 +579,7 @@ static MACHINE_START( draco ) static MACHINE_RESET( cidelsa ) { - cputag_set_input_line(machine, "main", INPUT_LINE_RESET, PULSE_LINE); + cputag_set_input_line(machine, "main", INPUT_LINE_RESET, PULSE_LINE); } /* Machine Drivers */ @@ -689,7 +689,7 @@ static MACHINE_DRIVER_START( draco ) MDRV_MACHINE_START(draco) MDRV_MACHINE_RESET(cidelsa) - MDRV_CPU_ADD("audio", COP420, DRACO_SND_CHR1) // COP402N + MDRV_CPU_ADD("audio", COP402, DRACO_SND_CHR1) // COP402N MDRV_CPU_PROGRAM_MAP(draco_sound_map, 0) MDRV_CPU_IO_MAP(draco_sound_io_map, 0) MDRV_CPU_CONFIG(draco_cop_intf) diff --git a/src/mame/drivers/thayers.c b/src/mame/drivers/thayers.c index 1de6aeb33a4..12a1c712d1b 100644 --- a/src/mame/drivers/thayers.c +++ b/src/mame/drivers/thayers.c @@ -571,10 +571,6 @@ static ADDRESS_MAP_START( thayers_io_map, ADDRESS_SPACE_IO, 8 ) AM_RANGE(0xf7, 0xf7) AM_WRITE(den2_w) ADDRESS_MAP_END -static ADDRESS_MAP_START( thayers_cop_map, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x000, 0x3ff) AM_ROM -ADDRESS_MAP_END - static ADDRESS_MAP_START( thayers_cop_io_map, ADDRESS_SPACE_IO, 8 ) AM_RANGE(COP400_PORT_L, COP400_PORT_L) AM_READWRITE(cop_l_r, cop_l_w) AM_RANGE(COP400_PORT_G, COP400_PORT_G) AM_READWRITE(cop_g_r, cop_g_w) @@ -751,7 +747,7 @@ static MACHINE_RESET( thayers ) static COP400_INTERFACE( thayers_cop_intf ) { - COP400_CKI_DIVISOR_16, // ??? + COP400_CKI_DIVISOR_4, // ??? COP400_CKO_OSCILLATOR_OUTPUT, // ??? COP400_MICROBUS_DISABLED }; @@ -765,7 +761,6 @@ static MACHINE_DRIVER_START( thayers ) MDRV_CPU_IO_MAP(thayers_io_map, 0) MDRV_CPU_ADD("mcu", COP421, XTAL_4MHz/2) // COP421L-PCA/N - MDRV_CPU_PROGRAM_MAP(thayers_cop_map, 0) MDRV_CPU_IO_MAP(thayers_cop_io_map, 0) MDRV_CPU_CONFIG(thayers_cop_intf) diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 6f4f51a3c55..ca5070c315b 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -204,10 +204,19 @@ 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 += TLCS90 CPUS += MB8841 CPUS += MB8842