Rewrote the COP400 execute function.

This commit is contained in:
Curt Coder 2008-03-29 12:17:59 +00:00
parent 1a931524f6
commit d23a72d1cd
4 changed files with 493 additions and 298 deletions

View File

@ -9,7 +9,7 @@
***************************************************************************/
#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(UINT8 opcode)
#define INSTRUCTION(mnemonic) INLINE UINT16 (mnemonic)(UINT8 opcode)
#define ROM(addr) cpu_readop(addr)
#define RAM_W(addr, value) (data_write_byte_8(addr, value))
@ -31,10 +31,7 @@
#define PC R.PC
#define prevPC R.PREVPC
#define skip R.skip
#define skipLBI R.skipLBI
#define READ_M RAM_R(B)
#define WRITE_M(VAL) RAM_W(B,VAL)
#define skip_lbi R.skip_lbi
#define IN_G() IN(COP400_PORT_G)
#define IN_L() IN(COP400_PORT_L)
@ -55,7 +52,7 @@
static TIMER_CALLBACK(cop410_serial_tick)
{
int cpunum = param;
cpuintrf_push_context(cpunum);
if (BIT(EN, 0))
@ -141,6 +138,8 @@ INLINE void WRITE_G(UINT8 data)
INSTRUCTION(illegal)
{
logerror("COP400: PC = %04x, Illegal opcode = %02x\n", PC-1, ROM(PC-1));
return PC + 1;
}
/* Arithmetic Instructions */
@ -148,7 +147,7 @@ INSTRUCTION(illegal)
/*
Mnemonic: ASC
Hex Code: 30
Binary: 0 0 1 1 0 0 0 0
@ -175,32 +174,34 @@ INSTRUCTION(asc)
{
C = 0;
}
return PC + 1;
}
/*
Mnemonic: ADD
Hex Code: 31
Binary: 0 0 1 1 0 0 0 1
Data Flow: A + RAM(B) -> A
Skip Conditions: None
Description: Add RAM to A
*/
INSTRUCTION(add)
{
A = (A + RAM_R(B)) & 0x0F;
A = (A + RAM_R(B)) & 0x0F;
return PC + 1;
}
/*
Mnemonic: AISC
Operand: y
Hex Code: 5-
Binary: 0 1 0 1 y3 y2 y1 y0
@ -221,22 +222,24 @@ INSTRUCTION(aisc)
if (A > 0x0f)
{
popmessage("SKIP!");
skip = 1;
logerror("skip %x\n", skip);
A &= 0xF;
}
return PC + 1;
}
/*
Mnemonic: CLRA
Hex Code: 00
Binary: 0 0 0 0 0 0 0 0
Data Flow: 0 -> A
Skip Conditions: None
Description: Clear A
*/
@ -244,19 +247,19 @@ INSTRUCTION(aisc)
INSTRUCTION(clra)
{
A = 0;
return PC + 1;
}
/*
Mnemonic: COMP
Hex Code: 40
Binary: 0 1 0 0 0 0 0 0
Data Flow: ~A -> A
Skip Conditions: None
Description: Ones Complement of A to A
*/
@ -264,19 +267,17 @@ INSTRUCTION(clra)
INSTRUCTION(comp)
{
A = A ^ 0xF;
return PC + 1;
}
/*
Mnemonic: NOP
Hex Code: 44
Binary: 0 1 0 0 0 1 0 0
Data Flow: None
Skip Conditions: None
Description: No Operation
*/
@ -284,19 +285,19 @@ INSTRUCTION(comp)
INSTRUCTION(nop)
{
// do nothing
return PC + 1;
}
/*
Mnemonic: RC
Hex Code: 32
Binary: 0 0 1 1 0 0 1 0
Data Flow: "0" -> C
Skip Conditions: None
Description: Reset C
*/
@ -304,19 +305,19 @@ INSTRUCTION(nop)
INSTRUCTION(rc)
{
C = 0;
return PC + 1;
}
/*
Mnemonic: SC
Hex Code: 22
Binary: 0 0 1 0 0 0 1 0
Data Flow: "1" -> C
Skip Conditions: None
Description: Set C
*/
@ -324,26 +325,28 @@ INSTRUCTION(rc)
INSTRUCTION(sc)
{
C = 1;
return PC + 1;
}
/*
Mnemonic: XOR
Hex Code: 02
Binary: 0 0 0 0 0 0 1 0
Data Flow: A ^ RAM(B) -> A
Skip Conditions: None
Description:
Description:
*/
INSTRUCTION(xor)
{
A = RAM_R(B) ^ A;
return PC + 1;
}
/* Transfer-of-Control Instructions */
@ -351,49 +354,48 @@ INSTRUCTION(xor)
/*
Mnemonic: JID
Hex Code: FF
Binary: 1 1 1 1 1 1 1 1
Data Flow: ROM(PC9:8,A,M) -> PC7:0
Skip Conditions: None
Description: Jump Indirect
*/
INSTRUCTION(jid)
{
UINT16 addr = (PC & 0x300) | (A << 4) | READ_M;
PC = (PC & 0x300) | ROM(addr);
UINT16 addr = (PC & 0x300) | (A << 4) | RAM_R(B);
return (PC & 0x300) | ROM(addr);
}
/*
Mnemonic: JMP
Operand: a
Hex Code: 6- --
Binary: 0 1 1 0 0 0 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
Data Flow: a -> PC
Skip Conditions: None
Description: Jump
*/
INSTRUCTION(jmp)
{
PC = ((opcode & 0x03) << 8) | ROM(PC);
UINT8 a = ((opcode & 0x03) << 8) | ROM(++PC);
return a;
}
/*
Mnemonic: JP
Operand: a
Hex Code: --
Binary: 1 a6 a5 a4 a3 a2 a1 a0
@ -406,38 +408,51 @@ INSTRUCTION(jmp)
a -> PC5:0
Skip Conditions: None
Description: Jump within Page
--------------------------------------------
Mnemonic: JSRP
Operand: a
Hex Code: --
Binary: 1 0 a5 a4 a3 a2 a1 a0
Data Flow: PC + 1 -> SA -> SB -> SC
0010 -> PC9:6
a -> PC5:0
Description: Jump to Subroutine Page
*/
INSTRUCTION(jp)
{
UINT8 op = ROM(prevPC);
UINT8 page = (PC >> 6) & 0x0f;
if (((PC & 0x3E0) >= 0x80) && ((PC & 0x3E0) < 0x100)) //JP pages 2,3
if (page == 2 || page == 3)
{
PC = (UINT16)((PC & 0x380) | (op & 0x7F));
UINT8 a = opcode & 0x7f;
return (PC & 0x30) | a;
}
else if ((opcode & 0xc0) == 0xc0)
{
UINT8 a = opcode & 0x3f;
return (PC & 0x3c0) | a;
}
else
{
if ((op & 0xC0) == 0xC0) //JP other pages
{
PC = (UINT16)((PC & 0x3C0) | (op & 0x3F));
}
else //JSRP
{
PUSH((UINT16)(PC));
PC = (UINT16)(0x80 | (op & 0x3F));
}
// JSRP
UINT8 a = opcode & 0x3f;
PUSH(PC + 1);
return 0x80 | a;
}
}
/*
Mnemonic: JSR
Operand: a
Hex Code: 6- --
Binary: 0 1 1 0 1 0 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
@ -445,27 +460,22 @@ INSTRUCTION(jp)
Data Flow: PC + 1 -> SA -> SB -> SC
a -> PC
Skip Conditions: None
Description: Jump to Subroutine
*/
INLINE void JSR(UINT8 a8)
{
PUSH(PC + 1);
PC = (a8 << 8) | ROM(PC);
}
INSTRUCTION(jsr0) { JSR(0); }
INSTRUCTION(jsr1) { JSR(1); }
INSTRUCTION(jsr2) { JSR(2); }
INSTRUCTION(jsr3) { JSR(3); }
INSTRUCTION(jsr)
{
UINT16 a = ((opcode & 0x03) << 8) | ROM(++PC);
PUSH(PC + 1);
return a;
}
/*
Mnemonic: RET
Hex Code: 48
Binary: 0 1 0 0 1 0 0 0
@ -478,12 +488,14 @@ INSTRUCTION(jsr3) { JSR(3); }
INSTRUCTION(ret)
{
POP();
return PC;
}
/*
Mnemonic: RETSK
Hex Code: 49
Binary: 0 1 0 0 1 0 0 1
@ -499,6 +511,8 @@ INSTRUCTION(retsk)
{
POP();
skip = 1;
return PC;
}
/* Memory Reference Instructions */
@ -506,7 +520,7 @@ INSTRUCTION(retsk)
/*
Mnemonic: CAMQ
Hex Code: 33 3C
Binary: 0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0
@ -519,13 +533,15 @@ INSTRUCTION(retsk)
INSTRUCTION(camq)
{
WRITE_Q((A << 4) | READ_M);
WRITE_Q((A << 4) | RAM_R(B));
return PC + 1;
}
/*
Mnemonic: LD
Operand: r
Hex Code: -5
Binary: 0 0 r1 r0 0 1 0 1
@ -543,15 +559,15 @@ INLINE void LD(UINT8 r)
B = B ^ (r << 4);
}
INSTRUCTION(ld0) { LD(0); }
INSTRUCTION(ld1) { LD(1); }
INSTRUCTION(ld2) { LD(2); }
INSTRUCTION(ld3) { LD(3); }
INSTRUCTION(ld0) { LD(0); return PC + 1; }
INSTRUCTION(ld1) { LD(1); return PC + 1; }
INSTRUCTION(ld2) { LD(2); return PC + 1; }
INSTRUCTION(ld3) { LD(3); return PC + 1; }
/*
Mnemonic: LQID
Hex Code: BF
Binary: 1 0 1 1 1 1 1 1
@ -565,15 +581,17 @@ INSTRUCTION(ld3) { LD(3); }
INSTRUCTION(lqid)
{
PUSH(PC + 1);
PC = (UINT16)((PC & 0x300) | (A << 4) | READ_M);
PC = (PC & 0x300) | (A << 4) | RAM_R(B);
WRITE_Q(ROM(PC));
POP();
return PC;
}
/*
Mnemonic: RMB
Operand: 0
1
2
@ -598,15 +616,15 @@ 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); return PC + 1; }
INSTRUCTION(rmb1) { RAM_W(B, RAM_R(B) & 0xD); return PC + 1; }
INSTRUCTION(rmb2) { RAM_W(B, RAM_R(B) & 0xB); return PC + 1; }
INSTRUCTION(rmb3) { RAM_W(B, RAM_R(B) & 0x7); return PC + 1; }
/*
Mnemonic: SMB
Operand: 0
1
2
@ -631,15 +649,15 @@ 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); return PC + 1; }
INSTRUCTION(smb1) { RAM_W(B, RAM_R(B) | 0x2); return PC + 1; }
INSTRUCTION(smb2) { RAM_W(B, RAM_R(B) | 0x4); return PC + 1; }
INSTRUCTION(smb3) { RAM_W(B, RAM_R(B) | 0x8); return PC + 1; }
/*
Mnemonic: STII
Operand: y
Hex Code: 7-
Binary: 0 1 1 1 y3 y2 y1 y0
@ -660,12 +678,14 @@ INSTRUCTION(stii)
Bd = (B & 0x0f) + 1;
if (Bd > 15) Bd = 0;
B = (B & 0x30) + Bd;
return PC + 1;
}
/*
Mnemonic: X
Operand: r
Hex Code: -6
Binary: 0 0 r1 r0 0 1 1 0
@ -686,12 +706,14 @@ INSTRUCTION(x)
A = t;
B = B ^ (r << 4);
return PC + 1;
}
/*
Mnemonic: XAD
Operand: r,d
Hex Code: 23 --
Binary: 0 0 1 0 0 0 1 1 1 0 r1 r0 d3 d2 d1 d0
@ -704,16 +726,18 @@ INSTRUCTION(x)
INSTRUCTION(xad)
{
UINT8 addr = ROM(PC++) & 0x3f;
UINT8 addr = ROM(++PC) & 0x3f;
UINT8 t = A;
A = RAM_R(addr);
RAM_W(addr, t);
return PC + 1;
}
/*
Mnemonic: XDS
Operand: r
Hex Code: -7
Binary: 0 0 r1 r0 0 1 1 1
@ -742,12 +766,14 @@ INSTRUCTION(xds)
B = (UINT8)(Br | (Bd & 0x0F));
if (Bd == 0xFF) skip = 1;
return PC + 1;
}
/*
Mnemonic: XIS
Operand: r
Hex Code: -4
Binary: 0 0 r1 r0 0 1 0 0
@ -776,6 +802,8 @@ INSTRUCTION(xis)
B = (UINT8)(Br | (Bd & 0x0F));
if (Bd == 0x10) skip = 1;
return PC + 1;
}
/* Register Reference Instructions */
@ -783,7 +811,7 @@ INSTRUCTION(xis)
/*
Mnemonic: CAB
Hex Code: 50
Binary: 0 1 0 1 0 0 0 0 0
@ -796,12 +824,14 @@ INSTRUCTION(xis)
INSTRUCTION(cab)
{
B = (B & 0x30) | A;
return PC + 1;
}
/*
Mnemonic: CBA
Hex Code: 4E
Binary: 0 1 0 0 1 1 1 0
@ -814,12 +844,14 @@ INSTRUCTION(cab)
INSTRUCTION(cba)
{
A = B & 0xF;
return PC + 1;
}
/*
Mnemonic: LBI
Operand: r,d
Hex Code: --
33 --
@ -838,81 +870,81 @@ INSTRUCTION(cba)
INLINE void LBI(UINT8 r, UINT8 d)
{
B = (r << 4) | d;
skipLBI = 1;
skip_lbi = 1;
}
INSTRUCTION(lbi0_0) { LBI(0,0); }
INSTRUCTION(lbi0_1) { LBI(0,1); }
INSTRUCTION(lbi0_2) { LBI(0,2); }
INSTRUCTION(lbi0_3) { LBI(0,3); }
INSTRUCTION(lbi0_4) { LBI(0,4); }
INSTRUCTION(lbi0_5) { LBI(0,5); }
INSTRUCTION(lbi0_6) { LBI(0,6); }
INSTRUCTION(lbi0_7) { LBI(0,7); }
INSTRUCTION(lbi0_8) { LBI(0,8); }
INSTRUCTION(lbi0_9) { LBI(0,9); }
INSTRUCTION(lbi0_10) { LBI(0,10); }
INSTRUCTION(lbi0_11) { LBI(0,11); }
INSTRUCTION(lbi0_12) { LBI(0,12); }
INSTRUCTION(lbi0_13) { LBI(0,13); }
INSTRUCTION(lbi0_14) { LBI(0,14); }
INSTRUCTION(lbi0_15) { LBI(0,15); }
INSTRUCTION(lbi0_0) { LBI(0,0); return PC + 1; }
INSTRUCTION(lbi0_1) { LBI(0,1); return PC + 1; }
INSTRUCTION(lbi0_2) { LBI(0,2); return PC + 1; }
INSTRUCTION(lbi0_3) { LBI(0,3); return PC + 1; }
INSTRUCTION(lbi0_4) { LBI(0,4); return PC + 1; }
INSTRUCTION(lbi0_5) { LBI(0,5); return PC + 1; }
INSTRUCTION(lbi0_6) { LBI(0,6); return PC + 1; }
INSTRUCTION(lbi0_7) { LBI(0,7); return PC + 1; }
INSTRUCTION(lbi0_8) { LBI(0,8); return PC + 1; }
INSTRUCTION(lbi0_9) { LBI(0,9); return PC + 1; }
INSTRUCTION(lbi0_10) { LBI(0,10); return PC + 1; }
INSTRUCTION(lbi0_11) { LBI(0,11); return PC + 1; }
INSTRUCTION(lbi0_12) { LBI(0,12); return PC + 1; }
INSTRUCTION(lbi0_13) { LBI(0,13); return PC + 1; }
INSTRUCTION(lbi0_14) { LBI(0,14); return PC + 1; }
INSTRUCTION(lbi0_15) { LBI(0,15); return PC + 1; }
INSTRUCTION(lbi1_0) { LBI(1,0); }
INSTRUCTION(lbi1_1) { LBI(1,1); }
INSTRUCTION(lbi1_2) { LBI(1,2); }
INSTRUCTION(lbi1_3) { LBI(1,3); }
INSTRUCTION(lbi1_4) { LBI(1,4); }
INSTRUCTION(lbi1_5) { LBI(1,5); }
INSTRUCTION(lbi1_6) { LBI(1,6); }
INSTRUCTION(lbi1_7) { LBI(1,7); }
INSTRUCTION(lbi1_8) { LBI(1,8); }
INSTRUCTION(lbi1_9) { LBI(1,9); }
INSTRUCTION(lbi1_10) { LBI(1,10); }
INSTRUCTION(lbi1_11) { LBI(1,11); }
INSTRUCTION(lbi1_12) { LBI(1,12); }
INSTRUCTION(lbi1_13) { LBI(1,13); }
INSTRUCTION(lbi1_14) { LBI(1,14); }
INSTRUCTION(lbi1_15) { LBI(1,15); }
INSTRUCTION(lbi1_0) { LBI(1,0); return PC + 1; }
INSTRUCTION(lbi1_1) { LBI(1,1); return PC + 1; }
INSTRUCTION(lbi1_2) { LBI(1,2); return PC + 1; }
INSTRUCTION(lbi1_3) { LBI(1,3); return PC + 1; }
INSTRUCTION(lbi1_4) { LBI(1,4); return PC + 1; }
INSTRUCTION(lbi1_5) { LBI(1,5); return PC + 1; }
INSTRUCTION(lbi1_6) { LBI(1,6); return PC + 1; }
INSTRUCTION(lbi1_7) { LBI(1,7); return PC + 1; }
INSTRUCTION(lbi1_8) { LBI(1,8); return PC + 1; }
INSTRUCTION(lbi1_9) { LBI(1,9); return PC + 1; }
INSTRUCTION(lbi1_10) { LBI(1,10); return PC + 1; }
INSTRUCTION(lbi1_11) { LBI(1,11); return PC + 1; }
INSTRUCTION(lbi1_12) { LBI(1,12); return PC + 1; }
INSTRUCTION(lbi1_13) { LBI(1,13); return PC + 1; }
INSTRUCTION(lbi1_14) { LBI(1,14); return PC + 1; }
INSTRUCTION(lbi1_15) { LBI(1,15); return PC + 1; }
INSTRUCTION(lbi2_0) { LBI(2,0); }
INSTRUCTION(lbi2_1) { LBI(2,1); }
INSTRUCTION(lbi2_2) { LBI(2,2); }
INSTRUCTION(lbi2_3) { LBI(2,3); }
INSTRUCTION(lbi2_4) { LBI(2,4); }
INSTRUCTION(lbi2_5) { LBI(2,5); }
INSTRUCTION(lbi2_6) { LBI(2,6); }
INSTRUCTION(lbi2_7) { LBI(2,7); }
INSTRUCTION(lbi2_8) { LBI(2,8); }
INSTRUCTION(lbi2_9) { LBI(2,9); }
INSTRUCTION(lbi2_10) { LBI(2,10); }
INSTRUCTION(lbi2_11) { LBI(2,11); }
INSTRUCTION(lbi2_12) { LBI(2,12); }
INSTRUCTION(lbi2_13) { LBI(2,13); }
INSTRUCTION(lbi2_14) { LBI(2,14); }
INSTRUCTION(lbi2_15) { LBI(2,15); }
INSTRUCTION(lbi2_0) { LBI(2,0); return PC + 1; }
INSTRUCTION(lbi2_1) { LBI(2,1); return PC + 1; }
INSTRUCTION(lbi2_2) { LBI(2,2); return PC + 1; }
INSTRUCTION(lbi2_3) { LBI(2,3); return PC + 1; }
INSTRUCTION(lbi2_4) { LBI(2,4); return PC + 1; }
INSTRUCTION(lbi2_5) { LBI(2,5); return PC + 1; }
INSTRUCTION(lbi2_6) { LBI(2,6); return PC + 1; }
INSTRUCTION(lbi2_7) { LBI(2,7); return PC + 1; }
INSTRUCTION(lbi2_8) { LBI(2,8); return PC + 1; }
INSTRUCTION(lbi2_9) { LBI(2,9); return PC + 1; }
INSTRUCTION(lbi2_10) { LBI(2,10); return PC + 1; }
INSTRUCTION(lbi2_11) { LBI(2,11); return PC + 1; }
INSTRUCTION(lbi2_12) { LBI(2,12); return PC + 1; }
INSTRUCTION(lbi2_13) { LBI(2,13); return PC + 1; }
INSTRUCTION(lbi2_14) { LBI(2,14); return PC + 1; }
INSTRUCTION(lbi2_15) { LBI(2,15); return PC + 1; }
INSTRUCTION(lbi3_0) { LBI(3,0); }
INSTRUCTION(lbi3_1) { LBI(3,1); }
INSTRUCTION(lbi3_2) { LBI(3,2); }
INSTRUCTION(lbi3_3) { LBI(3,3); }
INSTRUCTION(lbi3_4) { LBI(3,4); }
INSTRUCTION(lbi3_5) { LBI(3,5); }
INSTRUCTION(lbi3_6) { LBI(3,6); }
INSTRUCTION(lbi3_7) { LBI(3,7); }
INSTRUCTION(lbi3_8) { LBI(3,8); }
INSTRUCTION(lbi3_9) { LBI(3,9); }
INSTRUCTION(lbi3_10) { LBI(3,10); }
INSTRUCTION(lbi3_11) { LBI(3,11); }
INSTRUCTION(lbi3_12) { LBI(3,12); }
INSTRUCTION(lbi3_13) { LBI(3,13); }
INSTRUCTION(lbi3_14) { LBI(3,14); }
INSTRUCTION(lbi3_15) { LBI(3,15); }
INSTRUCTION(lbi3_0) { LBI(3,0); return PC + 1; }
INSTRUCTION(lbi3_1) { LBI(3,1); return PC + 1; }
INSTRUCTION(lbi3_2) { LBI(3,2); return PC + 1; }
INSTRUCTION(lbi3_3) { LBI(3,3); return PC + 1; }
INSTRUCTION(lbi3_4) { LBI(3,4); return PC + 1; }
INSTRUCTION(lbi3_5) { LBI(3,5); return PC + 1; }
INSTRUCTION(lbi3_6) { LBI(3,6); return PC + 1; }
INSTRUCTION(lbi3_7) { LBI(3,7); return PC + 1; }
INSTRUCTION(lbi3_8) { LBI(3,8); return PC + 1; }
INSTRUCTION(lbi3_9) { LBI(3,9); return PC + 1; }
INSTRUCTION(lbi3_10) { LBI(3,10); return PC + 1; }
INSTRUCTION(lbi3_11) { LBI(3,11); return PC + 1; }
INSTRUCTION(lbi3_12) { LBI(3,12); return PC + 1; }
INSTRUCTION(lbi3_13) { LBI(3,13); return PC + 1; }
INSTRUCTION(lbi3_14) { LBI(3,14); return PC + 1; }
INSTRUCTION(lbi3_15) { LBI(3,15); return PC + 1; }
/*
Mnemonic: LEI
Operand: y
Hex Code: 33 6-
Binary: 0 0 1 1 0 0 1 1 0 1 1 0 y3 y2 y1 y0
@ -933,6 +965,8 @@ INSTRUCTION(lei)
{
OUT_L(0);
}
return PC + 1;
}
/* Test Instructions */
@ -940,7 +974,7 @@ INSTRUCTION(lei)
/*
Mnemonic: SKC
Hex Code: 20
Binary: 0 0 1 0 0 0 0 0
@ -952,13 +986,15 @@ INSTRUCTION(lei)
INSTRUCTION(skc)
{
if (C == 1) skip = 1;
if (C == 1) skip = 1;
return PC + 1;
}
/*
Mnemonic: SKE
Hex Code: 21
Binary: 0 0 1 0 0 0 0 1
@ -971,12 +1007,14 @@ INSTRUCTION(skc)
INSTRUCTION(ske)
{
if (A == RAM_R(B)) skip = 1;
return PC + 1;
}
/*
Mnemonic: SKGZ
Hex Code: 33 21
Binary: 00 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1
@ -989,18 +1027,20 @@ INSTRUCTION(ske)
INSTRUCTION(skgz)
{
if (IN_G() == 0) skip = 1;
return PC + 1;
}
/*
Mnemonic: SKGBZ
Hex Code: 33 01
33 11
33 03
33 13
Binary:
Binary:
Skip Conditions: G0 = 0
G1 = 0
@ -1011,21 +1051,21 @@ INSTRUCTION(skgz)
*/
INSTRUCTION(skgbz0) { if (!BIT(IN_G(), 0)) skip = 1; }
INSTRUCTION(skgbz1) { if (!BIT(IN_G(), 1)) skip = 1; }
INSTRUCTION(skgbz2) { if (!BIT(IN_G(), 2)) skip = 1; }
INSTRUCTION(skgbz3) { if (!BIT(IN_G(), 3)) skip = 1; }
INSTRUCTION(skgbz0) { if (!BIT(IN_G(), 0)) skip = 1; return PC + 1; }
INSTRUCTION(skgbz1) { if (!BIT(IN_G(), 1)) skip = 1; return PC + 1; }
INSTRUCTION(skgbz2) { if (!BIT(IN_G(), 2)) skip = 1; return PC + 1; }
INSTRUCTION(skgbz3) { if (!BIT(IN_G(), 3)) skip = 1; return PC + 1; }
/*
Mnemonic: SKMBZ
Hex Code: 01
11
03
13
Binary:
Binary:
Skip Conditions: RAM(B)0 = 0
RAM(B)0 = 1
@ -1036,19 +1076,19 @@ INSTRUCTION(skgbz3) { if (!BIT(IN_G(), 3)) skip = 1; }
*/
INSTRUCTION(skmbz0) { if (!BIT(RAM_R(B), 0)) skip = 1; }
INSTRUCTION(skmbz1) { if (!BIT(RAM_R(B), 1)) skip = 1; }
INSTRUCTION(skmbz2) { if (!BIT(RAM_R(B), 2)) skip = 1; }
INSTRUCTION(skmbz3) { if (!BIT(RAM_R(B), 3)) skip = 1; }
INSTRUCTION(skmbz0) { if (!BIT(RAM_R(B), 0)) skip = 1; return PC + 1; }
INSTRUCTION(skmbz1) { if (!BIT(RAM_R(B), 1)) skip = 1; return PC + 1; }
INSTRUCTION(skmbz2) { if (!BIT(RAM_R(B), 2)) skip = 1; return PC + 1; }
INSTRUCTION(skmbz3) { if (!BIT(RAM_R(B), 3)) skip = 1; return PC + 1; }
/* Input/Output Instructions */
/*
Mnemonic: ING
Hex Code: 33 2A
Binary:
Binary:
Data Flow: G -> A
@ -1059,14 +1099,16 @@ INSTRUCTION(skmbz3) { if (!BIT(RAM_R(B), 3)) skip = 1; }
INSTRUCTION(ing)
{
A = IN_G();
return PC + 1;
}
/*
Mnemonic: INL
Hex Code: 33 2E
Binary:
Binary:
Data Flow: L7:4 -> RAM(B)
L3:0 -> A
@ -1080,14 +1122,16 @@ INSTRUCTION(inl)
UINT8 L = IN_L();
RAM_W(B, L >> 4);
A = L & 0xF;
return PC + 1;
}
/*
Mnemonic: OBD
Hex Code: 33 3E
Binary:
Binary:
Data Flow: Bd -> D
@ -1098,14 +1142,16 @@ INSTRUCTION(inl)
INSTRUCTION(obd)
{
OUT_D(B & 0x0f);
return PC + 1;
}
/*
Mnemonic: OMG
Hex Code: 33 3A
Binary:
Binary:
Data Flow: RAM(B) -> G
@ -1116,12 +1162,14 @@ INSTRUCTION(obd)
INSTRUCTION(omg)
{
WRITE_G(RAM_R(B));
return PC + 1;
}
/*
Mnemonic: XAS
Hex Code: 4F
Binary: 0 1 0 0 1 1 1 1
@ -1139,4 +1187,6 @@ INSTRUCTION(xas)
A = t;
SKL = C;
return PC + 1;
}

View File

@ -24,7 +24,7 @@
/*
Mnemonic: ADT
Hex Code: 4A
Binary: 0 1 0 0 1 0 1 0
@ -39,12 +39,14 @@
INSTRUCTION(adt)
{
A = (A + 10) & 0x0F;
return PC + 1;
}
/*
Mnemonic: CASC
Hex Code: 10
Binary: 0 0 0 1 0 0 0 0
@ -71,6 +73,8 @@ INSTRUCTION(casc)
{
C = 0;
}
return PC + 1;
}
/* Transfer-of-Control Instructions */
@ -78,7 +82,7 @@ INSTRUCTION(casc)
/*
Mnemonic: RET
Hex Code: 48
Binary: 0 1 0 0 1 0 0 0
@ -92,6 +96,8 @@ INSTRUCTION(cop420_ret)
{
POP();
skip = R.last_skip;
return PC;
}
/* Memory Reference Instructions */
@ -99,7 +105,7 @@ INSTRUCTION(cop420_ret)
/*
Mnemonic: CQMA
Hex Code: 33 2C
Binary: 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0
@ -114,14 +120,16 @@ INSTRUCTION(cop420_ret)
INSTRUCTION(cqma)
{
WRITE_M(Q >> 4);
RAM_W(B, Q >> 4);
A = Q & 0xF;
return PC + 1;
}
/*
Mnemonic: LDD
Operand: r, d
Hex Code: 23 --
Binary: 0 0 1 0 0 0 1 1 0 0 r1 r0 d3 d2 d1 d0
@ -135,8 +143,10 @@ INSTRUCTION(cqma)
INSTRUCTION(ldd)
{
UINT8 rd = opcode & 0x3f;
A = RAM_R(rd);
return PC + 1;
}
/* Register Reference Instructions */
@ -144,7 +154,7 @@ INSTRUCTION(ldd)
/*
Mnemonic: XABR
Hex Code: 12
Binary: 0 0 0 1 0 0 1 0
@ -161,6 +171,8 @@ INSTRUCTION(xabr)
A = (B & 0x30) >> 4;
B = (Br << 4) + Bd;
return PC + 1;
}
/* Test Instructions */
@ -168,7 +180,7 @@ INSTRUCTION(xabr)
/*
Mnemonic: SKT
Hex Code: 41
Binary: 0 1 0 0 0 0 0 1
@ -185,6 +197,8 @@ INSTRUCTION(skt)
R.timerlatch = 0;
skip = 1;
}
return PC + 1;
}
/* Input/Output Instructions */
@ -192,9 +206,9 @@ INSTRUCTION(skt)
/*
Mnemonic: ININ
Hex Code: 33 28
Binary:
Binary:
Data Flow: IN -> A
@ -202,16 +216,21 @@ INSTRUCTION(skt)
*/
INSTRUCTION(inin) { A = IN_IN(); }
INSTRUCTION(inin)
{
A = IN_IN();
return PC + 1;
}
/*
Processor: COP402M
Mnemonic: ININ
Hex Code: 33 28
Binary:
Binary:
Data Flow: IN -> A, A1 = "1"
@ -222,15 +241,17 @@ INSTRUCTION(inin) { A = IN_IN(); }
INSTRUCTION(cop402m_inin)
{
A = IN_IN() | 0x02;
return PC + 1;
}
/*
Mnemonic: INIL
Hex Code: 33 29
Binary:
Binary:
Data Flow: IL3,"1","0",IL0 -> A
@ -241,8 +262,10 @@ INSTRUCTION(cop402m_inin)
INSTRUCTION(inil)
{
// NOT PROPERLY IMPLEMENTED
A = (IN_IN() & 0x09) | 0x04;
return PC + 1;
}
/*
@ -250,9 +273,9 @@ INSTRUCTION(inil)
Processor: COP421
Mnemonic: INIL
Hex Code: 33 29
Binary:
Binary:
Data Flow: "0",CKO,"0","0" -> A
@ -263,12 +286,14 @@ INSTRUCTION(inil)
INSTRUCTION(cop421_inil)
{
// NOT IMPLEMENTED
return PC + 1;
}
/*
Mnemonic: OGI
Operand: y
Hex Code: 33 5-
Binary: 0 0 1 1 0 0 1 1 0 1 0 1 y3 y2 y1 y0
@ -284,4 +309,6 @@ INSTRUCTION(ogi)
UINT4 y = opcode & 0x0f;
WRITE_G(y);
return PC + 1;
}

View File

@ -25,7 +25,7 @@
/* The opcode table now is a combination of cycle counts and function pointers */
typedef struct {
unsigned cycles;
void (*function) (UINT8 opcode);
UINT16 (*function) (UINT8 opcode);
} s_opcode;
#define UINT1 UINT8
@ -46,10 +46,11 @@ typedef struct
UINT9 SA, SB;
UINT4 SIO;
UINT1 SKL;
UINT8 skip, skipLBI;
UINT8 G_mask;
UINT8 D_mask;
int last_si;
int skip;
int skip_lbi;
} COP410_Regs;
static COP410_Regs R;
@ -100,13 +101,6 @@ 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)
{
UINT8 opcode23 = ROM(PC++);
(*(opcode_23_map[opcode23].function))(opcode23);
}
static const s_opcode opcode_33_map[256]=
{
{1, illegal },{1, skgbz0 },{1, illegal },{1, skgbz2 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
@ -143,31 +137,25 @@ 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)
{
UINT8 opcode33 = ROM(PC++);
(*(opcode_33_map[opcode33].function))(opcode33);
}
static const s_opcode opcode_map[256]=
{
{1, clra },{1, skmbz0 },{1, xor },{1, skmbz2 },{1, xis },{1, ld0 },{1, x },{1, xds },
{1, lbi0_9 },{1, lbi0_10 },{1, lbi0_11 },{1, lbi0_12 },{1, lbi0_13 },{1, lbi0_14 },{1, lbi0_15 },{1, lbi0_0 },
{0, illegal },{1, skmbz1 },{0, illegal },{1, skmbz3 },{1, xis },{1, ld1 },{1, x },{1, xds },
{1, lbi1_9 },{1, lbi1_10 },{1, lbi1_11 },{1, lbi1_12 },{1, lbi1_13 },{1, lbi1_14 },{1, lbi1_15 },{1, lbi1_0 },
{1, skc },{1, ske },{1, sc },{2, cop410_op23 },{1, xis },{1, ld2 },{1, x },{1, xds },
{1, skc },{1, ske },{1, sc },{2, illegal },{1, xis },{1, ld2 },{1, x },{1, xds },
{1, lbi2_9 },{1, lbi2_10 },{1, lbi2_11 },{1, lbi2_12 },{1, lbi2_13 },{1, lbi2_14 },{1, lbi2_15 },{1, lbi2_0 },
{1, asc },{1, add },{1, rc },{2, cop410_op33 },{1, xis },{1, ld3 },{1, x },{1, xds },
{1, asc },{1, add },{1, rc },{2, illegal },{1, xis },{1, ld3 },{1, x },{1, xds },
{1, lbi3_9 },{1, lbi3_10 },{1, lbi3_11 },{1, lbi3_12 },{1, lbi3_13 },{1, lbi3_14 },{1, lbi3_15 },{1, lbi3_0 },
{1, comp },{0, illegal },{1, rmb2 },{1, rmb2 },{1, nop },{1, rmb1 },{1, smb2 },{1, smb1 },
{1, ret },{1, retsk },{0, illegal },{1, smb3 },{1, rmb0 },{1, smb0 },{1, cba },{1, xas },
{1, cab },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },{1, aisc },
{2, jmp },{2, jmp },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
{2, jsr0 },{2, jsr1 },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
{2, jsr },{2, jsr },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },{1, stii },
{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
@ -233,7 +221,7 @@ static void cop410_init(int index, int clock, const void *config, int (*irqcallb
state_save_register_item("cop410", index, SIO);
state_save_register_item("cop410", index, SKL);
state_save_register_item("cop410", index, skip);
state_save_register_item("cop410", index, skipLBI);
state_save_register_item("cop410", index, skip_lbi);
state_save_register_item("cop410", index, R.G_mask);
state_save_register_item("cop410", index, R.D_mask);
state_save_register_item("cop410", index, R.last_si);
@ -268,6 +256,8 @@ static void cop410_reset(void)
static int cop410_execute(int cycles)
{
UINT8 opcode;
UINT16 (*function)(UINT8);
int is_lbi = 0;
cop410_ICount = cycles;
@ -275,50 +265,67 @@ static int cop410_execute(int cycles)
{
prevPC = PC;
CALL_DEBUGGER(PC);
// fetch and decode
opcode = ROM(PC);
if (skipLBI == 1)
switch (opcode)
{
if (LBIops[opcode] == 0)
{
skipLBI = 0;
}
else {
cop410_ICount -= opcode_map[opcode].cycles;
case 0x23:
opcode = ROM(++PC);
function = opcode_23_map[opcode].function;
break;
PC += InstLen[opcode];
case 0x33:
opcode = ROM(++PC);
function = opcode_33_map[opcode].function;
break;
default:
function = opcode_map[opcode].function;
is_lbi = LBIops[opcode];
break;
}
// skip LBI?
if (skip_lbi)
{
if (is_lbi)
{
skip = 1;
}
else
{
skip_lbi = 0;
}
}
if (skipLBI == 0)
if (skip)
{
int inst_cycles = opcode_map[opcode].cycles;
PC++;
(*(opcode_map[opcode].function))(opcode);
cop410_ICount -= inst_cycles;
// skip
// skip next instruction?
if (skip == 1)
if ((function == lqid) || (function == jid))
{
void *function = opcode_map[ROM(PC)].function;
opcode = ROM(PC);
if ((function == lqid) || (function == jid))
{
cop410_ICount -= 1;
}
else
{
cop410_ICount -= opcode_map[opcode].cycles;
}
PC += InstLen[opcode];
skip = 0;
cop410_ICount -= 1;
}
else
{
cop410_ICount -= opcode_map[opcode].cycles;
}
PC++;
skip = 0;
}
else
{
// execute
CALL_DEBUGGER(PC);
PC = function(opcode);
cop410_ICount -= opcode_map[opcode].cycles;
}
} while (cop410_ICount > 0);

View File

@ -26,7 +26,7 @@
/* The opcode table now is a combination of cycle counts and function pointers */
typedef struct {
unsigned cycles;
void (*function) (UINT8 opcode);
UINT16 (*function) (UINT8 opcode);
} s_opcode;
#define UINT1 UINT8
@ -47,14 +47,14 @@ typedef struct
UINT10 SA, SB, SC;
UINT4 SIO;
UINT1 SKL;
UINT8 skip, skipLBI;
UINT1 timerlatch;
UINT16 counter;
UINT8 G_mask;
UINT8 D_mask;
UINT4 IL;
int last_si;
int last_skip;
int skip, last_skip;
int skip_lbi;
} COP420_Regs;
static COP420_Regs R;
@ -81,6 +81,7 @@ static const s_opcode 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, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
@ -89,6 +90,7 @@ static const s_opcode opcode_23_map[256]=
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, 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 },
@ -97,6 +99,7 @@ static const s_opcode opcode_23_map[256]=
{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },{1, xad },
{1, xad },{1, xad },{1, xad },{1, xad },{1, 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 },
@ -107,13 +110,6 @@ 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)
{
UINT8 opcode23 = ROM(PC++);
(*(opcode_23_map[opcode23].function))(opcode23);
}
static const s_opcode opcode_33_map[256]=
{
{1, inil },{1, skgbz0 },{1, illegal },{1, skgbz2 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
@ -124,6 +120,7 @@ static const s_opcode opcode_33_map[256]=
{1, inin },{1, illegal },{1, ing },{1, illegal },{1, cqma },{1, illegal },{1, inl },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, omg },{1, illegal },{1, camq },{1, illegal },{1, obd },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },{1, ogi },
@ -132,6 +129,7 @@ static const s_opcode opcode_33_map[256]=
{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },{1, lei },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, lbi0_1 },{1, lbi0_2 },{1, lbi0_3 },{1, lbi0_4 },{1, lbi0_5 },{1, lbi0_6 },{1, lbi0_7 },
{1, lbi0_8 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, lbi1_1 },{1, lbi1_2 },{1, lbi1_3 },{1, lbi1_4 },{1, lbi1_5 },{1, lbi1_6 },{1, lbi1_7 },
@ -140,6 +138,7 @@ static const s_opcode opcode_33_map[256]=
{1, lbi2_8 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, lbi3_1 },{1, lbi3_2 },{1, lbi3_3 },{1, lbi3_4 },{1, lbi3_5 },{1, lbi3_6 },{1, lbi3_7 },
{1, lbi3_8 },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
@ -150,31 +149,26 @@ 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)
{
UINT8 opcode33 = ROM(PC++);
(*(opcode_33_map[opcode33].function))(opcode33);
}
static const s_opcode opcode_map[256]=
{
{1, clra },{1, skmbz0 },{1, xor },{1, skmbz2 },{1, xis },{1, ld0 },{1, x },{1, xds },
{1, lbi0_9 },{1, lbi0_10 },{1, lbi0_11 },{1, lbi0_12 },{1, lbi0_13 },{1, lbi0_14 },{1, lbi0_15 },{1, lbi0_0 },
{1, casc },{1, skmbz1 },{1, xabr },{1, skmbz3 },{1, xis },{1, ld1 },{1, x },{1, xds },
{1, lbi1_9 },{1, lbi1_10 },{1, lbi1_11 },{1, lbi1_12 },{1, lbi1_13 },{1, lbi1_14 },{1, lbi1_15 },{1, lbi1_0 },
{1, skc },{1, ske },{1, sc },{2, cop420_op23 },{1, xis },{1, ld2 },{1, x },{1, xds },
{1, skc },{1, ske },{1, sc },{2, illegal },{1, xis },{1, ld2 },{1, x },{1, xds },
{1, lbi2_9 },{1, lbi2_10 },{1, lbi2_11 },{1, lbi2_12 },{1, lbi2_13 },{1, lbi2_14 },{1, lbi2_15 },{1, lbi2_0 },
{1, asc },{1, add },{1, rc },{2, cop420_op33 },{1, xis },{1, ld3 },{1, x },{1, xds },
{1, asc },{1, add },{1, rc },{2, illegal },{1, xis },{1, ld3 },{1, x },{1, xds },
{1, lbi3_9 },{1, lbi3_10 },{1, lbi3_11 },{1, lbi3_12 },{1, lbi3_13 },{1, lbi3_14 },{1, lbi3_15 },{1, lbi3_0 },
{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, jsr0 },{2, jsr1 },{2, jsr2 },{2, jsr3 },{0, illegal },{0, illegal },{0, illegal },{0, illegal },
{2, jmp },{2, jmp },{2, jmp },{2, jmp },{1, illegal },{1, illegal },{1, illegal },{1, illegal },
{2, jsr },{2, jsr },{2, jsr },{2, jsr },{1, illegal },{1, illegal },{1, illegal },{1, 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 },
@ -183,6 +177,7 @@ static const s_opcode opcode_map[256]=
{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },{1, jp },
{1, jp },{1, jp },{1, jp },{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 },
@ -273,7 +268,7 @@ static void cop420_init(int index, int clock, const void *config, int (*irqcallb
state_save_register_item("cop420", index, SIO);
state_save_register_item("cop420", index, SKL);
state_save_register_item("cop420", index, skip);
state_save_register_item("cop420", index, skipLBI);
state_save_register_item("cop420", index, skip_lbi);
state_save_register_item("cop420", index, R.timerlatch);
state_save_register_item("cop420", index, R.counter);
state_save_register_item("cop420", index, R.G_mask);
@ -312,9 +307,124 @@ static void cop420_reset(void)
WRITE_G(0);
}
static int cop420_execute(int cycles)
{
UINT8 opcode;
UINT16 (*function)(UINT8);
int is_lbi = 0;
cop420_ICount = cycles;
do
{
prevPC = PC;
// fetch and decode
opcode = ROM(PC);
switch (opcode)
{
case 0x23:
opcode = ROM(++PC);
function = opcode_23_map[opcode].function;
break;
case 0x33:
opcode = ROM(++PC);
function = opcode_33_map[opcode].function;
is_lbi = LBIops33[opcode];
break;
default:
function = opcode_map[opcode].function;
is_lbi = LBIops[opcode];
break;
}
// check interrupt
if (!skip_lbi && BIT(EN, 1))
{
UINT8 in = IN_IN();
if (BIT(IL, 1) && !BIT(in, 1))
{
if ((function != jp) && (function != jmp) && (function != jsr))
{
// disable interrupt
EN &= ~0x02;
// store skip logic
R.last_skip = skip;
skip = 0;
// push next PC
PUSH(PC + 1);
// jump to interrupt service routine
PC = 0x0ff;
continue;
}
}
IL = in;
}
// skip LBI?
if (skip_lbi)
{
if (is_lbi)
{
skip = 1;
}
else
{
skip_lbi = 0;
}
}
if (skip)
{
// skip
if ((function == lqid) || (function == jid))
{
cop420_ICount -= 1;
}
else
{
cop420_ICount -= opcode_map[opcode].cycles;
}
PC++;
skip = 0;
}
else
{
// execute
CALL_DEBUGGER(PC);
PC = function(opcode);
cop420_ICount -= opcode_map[opcode].cycles;
}
} while (cop420_ICount > 0);
return cycles - cop420_ICount;
}
/****************************************************************************
* Execute cycles CPU cycles. Return number of cycles really executed
****************************************************************************/
/*
static int cop420_execute(int cycles)
{
UINT8 opcode;
@ -329,7 +439,7 @@ static int cop420_execute(int cycles)
opcode = ROM(PC);
if (skipLBI == 1)
if (skip_lbi == 1)
{
int is_lbi = 0;
@ -344,7 +454,7 @@ static int cop420_execute(int cycles)
if (is_lbi == 0)
{
skipLBI = 0;
skip_lbi = 0;
}
else
{
@ -354,15 +464,15 @@ static int cop420_execute(int cycles)
}
}
if (skipLBI == 0)
if (skip_lbi == 0)
{
int inst_cycles = opcode_map[opcode].cycles;
PC++;
(*(opcode_map[opcode].function))(opcode);
cop420_ICount -= inst_cycles;
PC++;
// check for interrupt
if (BIT(EN, 1))
@ -373,7 +483,7 @@ static int cop420_execute(int cycles)
{
void *function = opcode_map[ROM(PC)].function;
if ((function != jp) && (function != jmp) && (function != jsr0) && (function != jsr1) && (function != jsr2) && (function != jsr3))
if ((function != jp) && (function != jmp) && (function != jsr))
{
// store skip logic
R.last_skip = skip;
@ -409,8 +519,9 @@ static int cop420_execute(int cycles)
{
cop420_ICount -= opcode_map[opcode].cycles;
}
PC += InstLen[opcode];
skip = 0;
}
}
@ -418,7 +529,7 @@ static int cop420_execute(int cycles)
return cycles - cop420_ICount;
}
*/
/****************************************************************************
* Get all registers in given buffer
****************************************************************************/
@ -588,7 +699,7 @@ void cop422_get_info(UINT32 state, cpuinfo *info)
}
void cop402_get_info(UINT32 state, cpuinfo *info)
{
{
// COP402 is a ROMless version of the COP420
switch (state)
@ -606,7 +717,7 @@ void cop402_get_info(UINT32 state, cpuinfo *info)
}
void cop444_get_info(UINT32 state, cpuinfo *info)
{
{
// COP444 is functionally equivalent to COP420, but with twice the RAM/ROM
switch (state)
@ -626,7 +737,7 @@ void cop444_get_info(UINT32 state, cpuinfo *info)
}
void cop445_get_info(UINT32 state, cpuinfo *info)
{
{
// COP445 is a 24-pin package version of the COP444, lacking the IN ports
switch (state)
@ -643,7 +754,7 @@ void cop445_get_info(UINT32 state, cpuinfo *info)
}
void cop404_get_info(UINT32 state, cpuinfo *info)
{
{
// COP404 is a ROMless version of the COP444
switch (state)