mirror of
https://github.com/holub/mame
synced 2025-05-21 21:29:15 +03:00
Pointerized the COP400 CPU cores.
This commit is contained in:
parent
09da237dcd
commit
a8475e4c1e
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
68
src/emu/cpu/cop400/440ops.c
Normal file
68
src/emu/cpu/cop400/440ops.c
Normal file
@ -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;
|
||||
}
|
@ -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__ */
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
690
src/emu/cpu/cop400/cop440.c
Normal file
690
src/emu/cpu/cop400/cop440.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
416
src/emu/cpu/cop400/cop440ds.c
Normal file
416
src/emu/cpu/cop400/cop440ds.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
|
@ -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
|
||||
-------------------------------------------------*/
|
||||
|
||||
|
@ -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
|
||||
-------------------------------------------------*/
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user