summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2009-09-03 23:53:43 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2009-09-03 23:53:43 +0000
commitb54790792adee8081f40f53892771197ca3a6eb2 (patch)
tree278d7375e85ce155f57c63725f00a161ef3b48ee /src/emu
parent85d9b4decbfcba69a47aa444c6633db73457ac5b (diff)
Fixed numerous opcodes in the AVR8 core [Harmony]
Fixed a register naming issue in the MIPS core [Harmony] Numerous SuperFX updates: [Harmony] - Hooked up RAM and ROM buffering - Inlined several more functions - Removed debug spew - Added the ability to define an external IRQ line callback, and hooked it up to the 65C816 - Fixed flag calculation for HIB opcode - Hooked SuperFX chip up to the SNES machine driver
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/cpu/avr8/avr8.c259
-rw-r--r--src/emu/cpu/avr8/avr8.h31
-rw-r--r--src/emu/cpu/avr8/avr8dasm.c2
-rw-r--r--src/emu/cpu/mips/mips3com.c64
-rw-r--r--src/emu/cpu/mips/mips3dsm.c8
-rw-r--r--src/emu/cpu/superfx/superfx.c178
-rw-r--r--src/emu/cpu/superfx/superfx.h9
7 files changed, 400 insertions, 151 deletions
diff --git a/src/emu/cpu/avr8/avr8.c b/src/emu/cpu/avr8/avr8.c
index 96047271b1e..780a7bfc990 100644
--- a/src/emu/cpu/avr8/avr8.c
+++ b/src/emu/cpu/avr8/avr8.c
@@ -128,6 +128,7 @@ INLINE void PUSH(avr8_state *cpustate, UINT8 val)
UINT16 sp = SPREG;
WRITE_IO_8(cpustate, sp, val);
sp--;
+ //printf( "PUSH %02x, new SP = %04x\n", val, sp );
WRITE_IO_8(cpustate, AVR8_IO_SPH, (sp >> 8) & 0x00ff);
WRITE_IO_8(cpustate, AVR8_IO_SPL, sp & 0x00ff);
}
@@ -138,9 +139,23 @@ INLINE UINT8 POP(avr8_state *cpustate)
sp++;
WRITE_IO_8(cpustate, AVR8_IO_SPH, (sp >> 8) & 0x00ff);
WRITE_IO_8(cpustate, AVR8_IO_SPL, sp & 0x00ff);
+ //printf( "POP %02x, new SP = %04x\n", READ_IO_8(cpustate, sp), sp );
return READ_IO_8(cpustate, sp);
}
+static void avr8_set_irq_line(avr8_state *cpustate, UINT16 vector, int state)
+{
+ //printf( "OMFG SETTING IRQ LINE\n" );
+ // Horrible hack, not accurate
+ if(state)
+ {
+ SREG_W(AVR8_SREG_I, 0);
+ PUSH(cpustate, (cpustate->pc >> 8) & 0x00ff);
+ PUSH(cpustate, cpustate->pc & 0x00ff);
+ cpustate->pc = vector;
+ }
+}
+
/*****************************************************************************/
static CPU_INIT( avr8 )
@@ -176,6 +191,8 @@ static CPU_EXECUTE( avr8 )
UINT8 rr = 0;
UINT8 res = 0;
UINT16 pd = 0;
+ INT16 sd = 0;
+ INT32 opcycles = 1;
//UINT16 pr = 0;
avr8_state *cpustate = get_safe_token(device);
@@ -195,20 +212,22 @@ static CPU_EXECUTE( avr8 )
switch(op & 0x0f00)
{
case 0x0000: // NOP
- //output += sprintf( output, "NOP" );
- unimplemented_opcode(cpustate, op);
break;
case 0x0100: // MOVW Rd+1:Rd,Rr+1:Rd
- //output += sprintf( output, "MOVW R%d:R%d, R%d:R%d", RD4(op)+1, RD4(op), RR4(op)+1, RR4(op) );
- unimplemented_opcode(cpustate, op);
+ WRITE_IO_8(cpustate, (RD4(op) << 1)+1, READ_IO_8(cpustate, (RR4(op) << 1)+1));
+ WRITE_IO_8(cpustate, RD4(op) << 1, READ_IO_8(cpustate, RR4(op) << 1));
break;
case 0x0200: // MULS Rd,Rr
//output += sprintf( output, "MULS R%d, R%d", 16+RD4(op), 16+RR4(op) );
unimplemented_opcode(cpustate, op);
break;
case 0x0300: // MULSU Rd,Rr
- //output += sprintf( output, "MULSU R%d, R%d", 16+RD4(op), 16+RR4(op) );
- unimplemented_opcode(cpustate, op);
+ sd = (INT8)READ_IO_8(cpustate, 16+RD4(op)) * (UINT8)READ_IO_8(cpustate, 16+RR4(op));
+ WRITE_IO_8(cpustate, 1, (sd >> 8) & 0x00ff);
+ WRITE_IO_8(cpustate, 0, sd & 0x00ff);
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
break;
case 0x0400:
case 0x0500:
@@ -228,8 +247,16 @@ static CPU_EXECUTE( avr8 )
case 0x0900:
case 0x0a00:
case 0x0b00: // SBC Rd,Rr
- //output += sprintf( output, "SBC R%d, R%d", RD5(op), RR5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ rr = READ_IO_8(cpustate, RR5(op));
+ res = rd - (rr + SREG_R(AVR8_SREG_C));
+ WRITE_IO_8(cpustate, RD5(op), res);
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
case 0x0c00:
case 0x0d00:
@@ -267,8 +294,16 @@ static CPU_EXECUTE( avr8 )
SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
case 0x0800: // SUB Rd,Rr
- //output += sprintf( output, "SUB R%d, R%d", RD5(op), RR5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ rr = READ_IO_8(cpustate, RR5(op));
+ res = rd - rr;
+ WRITE_IO_8(cpustate, RD5(op), res);
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
case 0x0c00: // ADC Rd,Rr
rd = READ_IO_8(cpustate, RD5(op));
@@ -361,16 +396,16 @@ static CPU_EXECUTE( avr8 )
unimplemented_opcode(cpustate, op);
break;
case 0x0008: // LDD Rd,Y+q
- //output += sprintf( output, "LD(D) R%d, Y+%02x", RD5(op), QCONST6(op) );
- unimplemented_opcode(cpustate, op);
+ WRITE_IO_8(cpustate, RD5(op), YREG + QCONST6(op));
+ opcycles = 2;
break;
case 0x0200: // STD Z+q,Rr
//output += sprintf( output, "ST(D) Z+%02x, R%d", QCONST6(op), RD5(op) );
unimplemented_opcode(cpustate, op);
break;
- case 0x0208: // STD Z+q,Rr
- //output += sprintf( output, "ST(D) Y+%02x, R%d", QCONST6(op), RD5(op) );
- unimplemented_opcode(cpustate, op);
+ case 0x0208: // STD Y+q,Rr
+ WRITE_IO_8(cpustate, YREG + QCONST6(op), READ_IO_8(cpustate, RD5(op)));
+ opcycles = 2;
break;
}
break;
@@ -386,6 +421,7 @@ static CPU_EXECUTE( avr8 )
cpustate->pc++;
op |= READ_PRG_16(cpustate, cpustate->pc);
WRITE_IO_8(cpustate, RD5(op >> 16), READ_IO_8(cpustate, op & 0x0000ffff));
+ opcycles = 2;
break;
case 0x0001: // LD Rd,Z+
unimplemented_opcode(cpustate, op);
@@ -396,6 +432,7 @@ static CPU_EXECUTE( avr8 )
break;
case 0x0004: // LPM Rd,Z
WRITE_IO_8(cpustate, RD5(op), READ_PRG_8(cpustate, ZREG));
+ opcycles = 3;
break;
case 0x0005: // LPM Rd,Z+
pd = ZREG;
@@ -403,6 +440,7 @@ static CPU_EXECUTE( avr8 )
pd++;
WRITE_IO_8(cpustate, 31, (pd >> 8) & 0x00ff);
WRITE_IO_8(cpustate, 30, pd & 0x00ff);
+ opcycles = 3;
break;
case 0x0006: // ELPM Rd,Z
//output += sprintf( output, "ELPM R%d, Z", RD5(op) );
@@ -425,16 +463,20 @@ static CPU_EXECUTE( avr8 )
unimplemented_opcode(cpustate, op);
break;
case 0x000d: // LD Rd,X+
- //output += sprintf( output, "LD R%d, X+", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ pd = XREG;
+ WRITE_IO_8(cpustate, RD5(op), READ_IO_8(cpustate, pd));
+ pd++;
+ WRITE_IO_8(cpustate, 27, (pd >> 8) & 0x00ff);
+ WRITE_IO_8(cpustate, 26, pd & 0x00ff);
+ opcycles = 2;
break;
case 0x000e: // LD Rd,-X
//output += sprintf( output, "LD R%d,-X", RD5(op) );
unimplemented_opcode(cpustate, op);
break;
case 0x000f: // POP Rd
- //output += sprintf( output, "POP R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ WRITE_IO_8(cpustate, RD5(op), POP(cpustate));
+ opcycles = 2;
break;
default:
unimplemented_opcode(cpustate, op);
@@ -451,6 +493,7 @@ static CPU_EXECUTE( avr8 )
cpustate->pc++;
op |= READ_PRG_16(cpustate, cpustate->pc);
WRITE_IO_8(cpustate, op & 0x0000ffff, READ_IO_8(cpustate, RD5(op >> 16)));
+ opcycles = 2;
break;
case 0x0001: // ST Z+,Rd
//output += sprintf( output, "ST Z+, R%d", RD5(op) );
@@ -471,6 +514,7 @@ static CPU_EXECUTE( avr8 )
case 0x000c: // ST X,Rd
rd = READ_IO_8(cpustate, RD5(op));
WRITE_IO_8(cpustate, XREG, rd);
+ opcycles = 2;
break;
case 0x000d: // ST X+,Rd
pd = XREG;
@@ -478,14 +522,15 @@ static CPU_EXECUTE( avr8 )
pd++;
WRITE_IO_8(cpustate, 27, (pd >> 8) & 0x00ff);
WRITE_IO_8(cpustate, 26, pd & 0x00ff);
+ opcycles = 2;
break;
case 0x000e: // ST -X,Rd
//output += sprintf( output, "ST -X , R%d", RD5(op) );
unimplemented_opcode(cpustate, op);
break;
case 0x000f: // PUSH Rd
- //output += sprintf( output, "PUSH R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ PUSH(cpustate, READ_IO_8(cpustate, RD5(op)));
+ opcycles = 2;
break;
default:
unimplemented_opcode(cpustate, op);
@@ -497,12 +542,23 @@ static CPU_EXECUTE( avr8 )
switch(op & 0x000f)
{
case 0x0000: // COM Rd
- //output += sprintf( output, "COM R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ rd = ~rd;
+ SREG_W(AVR8_SREG_C, 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V));
break;
case 0x0001: // NEG Rd
- //output += sprintf( output, "NEG R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = 0 - rd;
+ SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
break;
case 0x0002: // SWAP Rd
//output += sprintf( output, "SWAP R%d", RD5(op) );
@@ -522,8 +578,13 @@ static CPU_EXECUTE( avr8 )
unimplemented_opcode(cpustate, op);
break;
case 0x0006: // LSR Rd
- //output += sprintf( output, "LSR R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = rd >> 1;
+ SREG_W(AVR8_SREG_C, rd & 0x01);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, 0);
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
break;
case 0x0007: // ROR Rd
//output += sprintf( output, "ROR R%d", RD5(op) );
@@ -559,21 +620,26 @@ static CPU_EXECUTE( avr8 )
{
case 0x0000: // IJMP
cpustate->pc = ZREG - 1;
+ opcycles = 2;
break;
case 0x0010: // EIJMP
//output += sprintf( output, "EIJMP" );
unimplemented_opcode(cpustate, op);
break;
default:
- unimplemented_opcode(cpustate, op);
//output += sprintf( output, "Undefined (%04x)", op );
unimplemented_opcode(cpustate, op);
break;
}
break;
case 0x000a: // DEC Rd
- //output += sprintf( output, "DEC R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = rd - 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ WRITE_IO_8(cpustate, RD5(op), res);
break;
case 0x000c:
case 0x000d: // JMP k
@@ -603,12 +669,24 @@ static CPU_EXECUTE( avr8 )
switch(op & 0x000f)
{
case 0x0000: // COM Rd
- //output += sprintf( output, "COM R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ rd = ~rd;
+ SREG_W(AVR8_SREG_C, 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V));
break;
case 0x0001: // NEG Rd
- //output += sprintf( output, "NEG R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = 0 - rd;
+ WRITE_IO_8(cpustate, RD5(op), res);
+ SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
break;
case 0x0002: // SWAP Rd
//output += sprintf( output, "SWAP R%d", RD5(op) );
@@ -628,8 +706,13 @@ static CPU_EXECUTE( avr8 )
unimplemented_opcode(cpustate, op);
break;
case 0x0006: // LSR Rd
- //output += sprintf( output, "LSR R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = rd >> 1;
+ SREG_W(AVR8_SREG_C, rd & 0x01);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, 0);
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
break;
case 0x0007: // ROR Rd
//output += sprintf( output, "ROR R%d", RD5(op) );
@@ -642,10 +725,14 @@ static CPU_EXECUTE( avr8 )
cpustate->pc = POP(cpustate);
cpustate->pc |= POP(cpustate) << 8;
cpustate->pc--;
+ opcycles = 4;
break;
case 0x0010: // RETI
- //output += sprintf( output, "RETI" );
- unimplemented_opcode(cpustate, op);
+ cpustate->pc = POP(cpustate);
+ cpustate->pc |= POP(cpustate) << 8;
+ cpustate->pc--;
+ SREG_W(AVR8_SREG_I, 1);
+ opcycles = 4;
break;
case 0x0080: // SLEEP
//output += sprintf( output, "SLEEP" );
@@ -661,6 +748,7 @@ static CPU_EXECUTE( avr8 )
break;
case 0x00c0: // LPM
WRITE_IO_8(cpustate, 0, READ_PRG_8(cpustate, ZREG));
+ opcycles = 3;
break;
case 0x00d0: // ELPM
//output += sprintf( output, "ELPM" );
@@ -698,8 +786,13 @@ static CPU_EXECUTE( avr8 )
}
break;
case 0x000a: // DEC Rd
- //output += sprintf( output, "DEC R%d", RD5(op) );
- unimplemented_opcode(cpustate, op);
+ rd = READ_IO_8(cpustate, RD5(op));
+ res = rd - 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ WRITE_IO_8(cpustate, RD5(op), res);
break;
case 0x000c:
case 0x000d: // JMP k
@@ -727,47 +820,56 @@ static CPU_EXECUTE( avr8 )
break;
case 0x0700: // SBIW Rd+1:Rd,K
//output += sprintf( output, "SBIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op) );
+ unimplemented_opcode(cpustate, op);
break;
case 0x0800: // CBI A,b
//output += sprintf( output, "CBI 0x%02x, %d", ACONST5(op), RR3(op) );
+ WRITE_IO_8(cpustate, ACONST5(op), READ_IO_8(cpustate, ACONST5(op)) &~ (1 << RR3(op)));
+ opcycles = 2;
break;
case 0x0900: // SBIC A,b
//output += sprintf( output, "SBIC 0x%02x, %d", ACONST5(op), RR3(op) );
+ unimplemented_opcode(cpustate, op);
break;
case 0x0a00: // SBI A,b
//output += sprintf( output, "SBI 0x%02x, %d", ACONST5(op), RR3(op) );
+ WRITE_IO_8(cpustate, ACONST5(op), READ_IO_8(cpustate, ACONST5(op)) | (1 << RR3(op)));
+ opcycles = 2;
break;
case 0x0b00: // SBIS A,b
//output += sprintf( output, "SBIS 0x%02x, %d", ACONST5(op), RR3(op) );
+ unimplemented_opcode(cpustate, op);
break;
case 0x0c00:
case 0x0d00:
case 0x0e00:
case 0x0f00: // MUL Rd,Rr
//output += sprintf( output, "MUL R%d, R%d", RD5(op), RR5(op) );
+ unimplemented_opcode(cpustate, op);
break;
}
break;
case 0xb000:
- unimplemented_opcode(cpustate, op);
if(op & 0x0800) // OUT A,Rr
{
- //output += sprintf( output, "OUT 0x%02x, R%d", ACONST6(op), RD5(op) );
+ WRITE_IO_8(cpustate, 0x20 + ACONST6(op), READ_IO_8(cpustate, RD5(op)));
}
else // IN Rd,A
{
- //output += sprintf( output, "IN R%d, 0x%02x", RD5(op), ACONST6(op) );
+ WRITE_IO_8(cpustate, RD5(op), READ_IO_8(cpustate, 0x20 + ACONST6(op)));
}
break;
case 0xc000: // RJMP k
offs = (INT32)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
cpustate->pc += offs;
+ opcycles = 2;
break;
case 0xd000: // RCALL k
offs = (INT32)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
PUSH(cpustate, ((cpustate->pc + 1) >> 8) & 0x00ff);
PUSH(cpustate, (cpustate->pc + 1) & 0x00ff);
cpustate->pc += offs;
+ opcycles = 3;
break;
case 0xe000: // LDI Rd,K
rd = KCONST8(op);
@@ -785,6 +887,7 @@ static CPU_EXECUTE( avr8 )
offs |= 0xffffff80;
}
cpustate->pc += offs;
+ opcycles = 2;
}
break;
case 0x0400: // BRSH through BRID
@@ -796,28 +899,54 @@ static CPU_EXECUTE( avr8 )
offs |= 0xffffff80;
}
cpustate->pc += offs;
+ opcycles = 2;
}
break;
case 0x0800:
- unimplemented_opcode(cpustate, op);
if(op & 0x0200) // BST Rd, b
{
- //output += sprintf( output, "BST R%d, %d", RD5(op), RR3(op) );
+ SREG_W(AVR8_SREG_T, (BIT(READ_IO_8(cpustate, RD5(op)),RR3(op))) ? 1 : 0);
}
else // BLD Rd, b
{
- //output += sprintf( output, "BLD R%d, %d", RD5(op), RR3(op) );
+ if(SREG_R(AVR8_SREG_T))
+ {
+ WRITE_IO_8(cpustate, RD5(op), READ_IO_8(cpustate, RD5(op)) | (1 << RR3(op)));
+ }
+ else
+ {
+ WRITE_IO_8(cpustate, RD5(op), READ_IO_8(cpustate, RD5(op)) &~ (1 << RR3(op)));
+ }
}
break;
case 0x0c00:
- unimplemented_opcode(cpustate, op);
if(op & 0x0200) // SBRS Rd, b
{
- //output += sprintf( output, "SBRS R%d, %d", RD5(op), RR3(op) );
+ if(BIT(READ_IO_8(cpustate, RD5(op)),RR3(op)))
+ {
+ op = (UINT32)READ_PRG_16(cpustate, cpustate->pc++);
+ opcycles = 2;
+ if((op & 0xfe0c) == 0x940c ||
+ (op & 0xfe0f) == 0xfe0f)
+ {
+ cpustate->pc++;
+ opcycles = 3;
+ }
+ }
}
else // SBRC Rd, b
{
- //output += sprintf( output, "SBRC R%d, %d", RD5(op), RR3(op) );
+ if(!BIT(READ_IO_8(cpustate, RD5(op)),RR3(op)))
+ {
+ op = (UINT32)READ_PRG_16(cpustate, cpustate->pc++);
+ opcycles = 2;
+ if((op & 0xfe0c) == 0x940c ||
+ (op & 0xfc0f) == 0x9000)
+ {
+ cpustate->pc++;
+ opcycles = 3;
+ }
+ }
}
break;
}
@@ -826,7 +955,7 @@ static CPU_EXECUTE( avr8 )
cpustate->pc++;
- --cpustate->icount;
+ cpustate->icount -= opcycles;
}
return cycles - cpustate->icount;
@@ -840,6 +969,35 @@ static CPU_SET_INFO( avr8 )
switch (state)
{
+
+ /* interrupt lines/exceptions */
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_RESET: avr8_set_irq_line(cpustate, AVR8_INT_RESET, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_INT0: avr8_set_irq_line(cpustate, AVR8_INT_INT0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_INT1: avr8_set_irq_line(cpustate, AVR8_INT_INT1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_PCINT0: avr8_set_irq_line(cpustate, AVR8_INT_PCINT0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_PCINT1: avr8_set_irq_line(cpustate, AVR8_INT_PCINT1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_PCINT2: avr8_set_irq_line(cpustate, AVR8_INT_PCINT2, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_WDT: avr8_set_irq_line(cpustate, AVR8_INT_WDT, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T2COMPA: avr8_set_irq_line(cpustate, AVR8_INT_T2COMPA, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T2COMPB: avr8_set_irq_line(cpustate, AVR8_INT_T2COMPB, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T2OVF: avr8_set_irq_line(cpustate, AVR8_INT_T2OVF, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T1CAPT: avr8_set_irq_line(cpustate, AVR8_INT_T1CAPT, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T1COMPA: avr8_set_irq_line(cpustate, AVR8_INT_T1COMPA, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T1COMPB: avr8_set_irq_line(cpustate, AVR8_INT_T1COMPB, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T1OVF: avr8_set_irq_line(cpustate, AVR8_INT_T1OVF, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T0COMPA: avr8_set_irq_line(cpustate, AVR8_INT_T0COMPA, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T0COMPB: avr8_set_irq_line(cpustate, AVR8_INT_T0COMPB, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_T0OVF: avr8_set_irq_line(cpustate, AVR8_INT_T0OVF, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_SPI_STC: avr8_set_irq_line(cpustate, AVR8_INT_SPI_STC, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_USART_RX: avr8_set_irq_line(cpustate, AVR8_INT_USART_RX, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_USART_UDRE: avr8_set_irq_line(cpustate, AVR8_INT_USART_UDRE, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_USART_TX: avr8_set_irq_line(cpustate, AVR8_INT_USART_TX, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_ADC: avr8_set_irq_line(cpustate, AVR8_INT_ADC, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_EE_RDY: avr8_set_irq_line(cpustate, AVR8_INT_EE_RDY, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_ANALOG_COMP: avr8_set_irq_line(cpustate, AVR8_INT_ANALOG_COMP, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_TWI: avr8_set_irq_line(cpustate, AVR8_INT_TWI, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + AVR8_INT_SPM_RDY: avr8_set_irq_line(cpustate, AVR8_INT_SPM_RDY, info->i); break;
+
/* --- the following bits of info are set as 64-bit signed integers --- */
case CPUINFO_INT_PC: /* intentional fallthrough */
case CPUINFO_INT_REGISTER + AVR8_PC: cpustate->pc = info->i; break;
@@ -966,5 +1124,6 @@ CPU_GET_INFO( avr8 )
case CPUINFO_STR_REGISTER + AVR8_X: sprintf(info->s, "X: %04x", XREG ); break;
case CPUINFO_STR_REGISTER + AVR8_Y: sprintf(info->s, "Y: %04x", YREG ); break;
case CPUINFO_STR_REGISTER + AVR8_Z: sprintf(info->s, "Z: %04x", ZREG ); break;
+ case CPUINFO_STR_REGISTER + AVR8_SP: sprintf(info->s, "SP: %04x", SPREG ); break;
}
}
diff --git a/src/emu/cpu/avr8/avr8.h b/src/emu/cpu/avr8/avr8.h
index b7883ac4b5a..48bf10aa9a4 100644
--- a/src/emu/cpu/avr8/avr8.h
+++ b/src/emu/cpu/avr8/avr8.h
@@ -50,6 +50,37 @@ enum
AVR8_X,
AVR8_Y,
AVR8_Z,
+ AVR8_SP,
+};
+
+enum
+{
+ AVR8_INT_RESET = 0,
+ AVR8_INT_INT0,
+ AVR8_INT_INT1,
+ AVR8_INT_PCINT0,
+ AVR8_INT_PCINT1,
+ AVR8_INT_PCINT2,
+ AVR8_INT_WDT,
+ AVR8_INT_T2COMPA,
+ AVR8_INT_T2COMPB,
+ AVR8_INT_T2OVF,
+ AVR8_INT_T1CAPT,
+ AVR8_INT_T1COMPA,
+ AVR8_INT_T1COMPB,
+ AVR8_INT_T1OVF,
+ AVR8_INT_T0COMPA,
+ AVR8_INT_T0COMPB,
+ AVR8_INT_T0OVF,
+ AVR8_INT_SPI_STC,
+ AVR8_INT_USART_RX,
+ AVR8_INT_USART_UDRE,
+ AVR8_INT_USART_TX,
+ AVR8_INT_ADC,
+ AVR8_INT_EE_RDY,
+ AVR8_INT_ANALOG_COMP,
+ AVR8_INT_TWI,
+ AVR8_INT_SPM_RDY,
};
CPU_GET_INFO( avr8 );
diff --git a/src/emu/cpu/avr8/avr8dasm.c b/src/emu/cpu/avr8/avr8dasm.c
index 0f025b134b6..a70483f383a 100644
--- a/src/emu/cpu/avr8/avr8dasm.c
+++ b/src/emu/cpu/avr8/avr8dasm.c
@@ -38,7 +38,7 @@ CPU_DISASSEMBLE( avr8 )
output += sprintf( output, "NOP" );
break;
case 0x0100:
- output += sprintf( output, "MOVW R%d:R%d, R%d:R%d", RD4(op)+1, RD4(op), RR4(op)+1, RR4(op) );
+ output += sprintf( output, "MOVW R%d:R%d, R%d:R%d", (RD4(op) << 1)+1, RD4(op) << 1, (RR4(op) << 1)+1, RR4(op) << 1 );
break;
case 0x0200:
output += sprintf( output, "MULS R%d, R%d", 16+RD4(op), 16+RR4(op) );
diff --git a/src/emu/cpu/mips/mips3com.c b/src/emu/cpu/mips/mips3com.c
index 0d7d15db711..197dc9e8576 100644
--- a/src/emu/cpu/mips/mips3com.c
+++ b/src/emu/cpu/mips/mips3com.c
@@ -558,38 +558,38 @@ void mips3com_get_info(mips3_state *mips, UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + MIPS3_WIRED: sprintf(info->s, "Wired:%08X", (UINT32)mips->cpr[0][COP0_Wired]); break;
case CPUINFO_STR_REGISTER + MIPS3_BADVADDR: sprintf(info->s, "BadVAddr:%08X", (UINT32)mips->cpr[0][COP0_BadVAddr]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R0: sprintf(info->s, "R0: %08X%08X", (UINT32)(mips->r[0] >> 32), (UINT32)mips->r[0]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R1: sprintf(info->s, "R1: %08X%08X", (UINT32)(mips->r[1] >> 32), (UINT32)mips->r[1]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R2: sprintf(info->s, "R2: %08X%08X", (UINT32)(mips->r[2] >> 32), (UINT32)mips->r[2]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R3: sprintf(info->s, "R3: %08X%08X", (UINT32)(mips->r[3] >> 32), (UINT32)mips->r[3]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R4: sprintf(info->s, "R4: %08X%08X", (UINT32)(mips->r[4] >> 32), (UINT32)mips->r[4]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R5: sprintf(info->s, "R5: %08X%08X", (UINT32)(mips->r[5] >> 32), (UINT32)mips->r[5]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R6: sprintf(info->s, "R6: %08X%08X", (UINT32)(mips->r[6] >> 32), (UINT32)mips->r[6]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R7: sprintf(info->s, "R7: %08X%08X", (UINT32)(mips->r[7] >> 32), (UINT32)mips->r[7]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R8: sprintf(info->s, "R8: %08X%08X", (UINT32)(mips->r[8] >> 32), (UINT32)mips->r[8]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R9: sprintf(info->s, "R9: %08X%08X", (UINT32)(mips->r[9] >> 32), (UINT32)mips->r[9]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R10: sprintf(info->s, "R10:%08X%08X", (UINT32)(mips->r[10] >> 32), (UINT32)mips->r[10]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R11: sprintf(info->s, "R11:%08X%08X", (UINT32)(mips->r[11] >> 32), (UINT32)mips->r[11]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R12: sprintf(info->s, "R12:%08X%08X", (UINT32)(mips->r[12] >> 32), (UINT32)mips->r[12]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R13: sprintf(info->s, "R13:%08X%08X", (UINT32)(mips->r[13] >> 32), (UINT32)mips->r[13]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R14: sprintf(info->s, "R14:%08X%08X", (UINT32)(mips->r[14] >> 32), (UINT32)mips->r[14]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R15: sprintf(info->s, "R15:%08X%08X", (UINT32)(mips->r[15] >> 32), (UINT32)mips->r[15]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R16: sprintf(info->s, "R16:%08X%08X", (UINT32)(mips->r[16] >> 32), (UINT32)mips->r[16]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R17: sprintf(info->s, "R17:%08X%08X", (UINT32)(mips->r[17] >> 32), (UINT32)mips->r[17]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R18: sprintf(info->s, "R18:%08X%08X", (UINT32)(mips->r[18] >> 32), (UINT32)mips->r[18]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R19: sprintf(info->s, "R19:%08X%08X", (UINT32)(mips->r[19] >> 32), (UINT32)mips->r[19]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R20: sprintf(info->s, "R20:%08X%08X", (UINT32)(mips->r[20] >> 32), (UINT32)mips->r[20]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R21: sprintf(info->s, "R21:%08X%08X", (UINT32)(mips->r[21] >> 32), (UINT32)mips->r[21]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R22: sprintf(info->s, "R22:%08X%08X", (UINT32)(mips->r[22] >> 32), (UINT32)mips->r[22]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R23: sprintf(info->s, "R23:%08X%08X", (UINT32)(mips->r[23] >> 32), (UINT32)mips->r[23]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R24: sprintf(info->s, "R24:%08X%08X", (UINT32)(mips->r[24] >> 32), (UINT32)mips->r[24]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R25: sprintf(info->s, "R25:%08X%08X", (UINT32)(mips->r[25] >> 32), (UINT32)mips->r[25]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R26: sprintf(info->s, "R26:%08X%08X", (UINT32)(mips->r[26] >> 32), (UINT32)mips->r[26]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R27: sprintf(info->s, "R27:%08X%08X", (UINT32)(mips->r[27] >> 32), (UINT32)mips->r[27]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R28: sprintf(info->s, "R28:%08X%08X", (UINT32)(mips->r[28] >> 32), (UINT32)mips->r[28]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R29: sprintf(info->s, "R29:%08X%08X", (UINT32)(mips->r[29] >> 32), (UINT32)mips->r[29]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R30: sprintf(info->s, "R30:%08X%08X", (UINT32)(mips->r[30] >> 32), (UINT32)mips->r[30]); break;
- case CPUINFO_STR_REGISTER + MIPS3_R31: sprintf(info->s, "R31:%08X%08X", (UINT32)(mips->r[31] >> 32), (UINT32)mips->r[31]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R0: sprintf(info->s, "$zero: %08X%08X", (UINT32)(mips->r[0] >> 32), (UINT32)mips->r[0]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R1: sprintf(info->s, " $at: %08X%08X", (UINT32)(mips->r[1] >> 32), (UINT32)mips->r[1]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R2: sprintf(info->s, " $v0: %08X%08X", (UINT32)(mips->r[2] >> 32), (UINT32)mips->r[2]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R3: sprintf(info->s, " $v1: %08X%08X", (UINT32)(mips->r[3] >> 32), (UINT32)mips->r[3]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R4: sprintf(info->s, " $a0: %08X%08X", (UINT32)(mips->r[4] >> 32), (UINT32)mips->r[4]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R5: sprintf(info->s, " $a1: %08X%08X", (UINT32)(mips->r[5] >> 32), (UINT32)mips->r[5]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R6: sprintf(info->s, " $a2: %08X%08X", (UINT32)(mips->r[6] >> 32), (UINT32)mips->r[6]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R7: sprintf(info->s, " $a3: %08X%08X", (UINT32)(mips->r[7] >> 32), (UINT32)mips->r[7]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R8: sprintf(info->s, " $t0: %08X%08X", (UINT32)(mips->r[8] >> 32), (UINT32)mips->r[8]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R9: sprintf(info->s, " $t1: %08X%08X", (UINT32)(mips->r[9] >> 32), (UINT32)mips->r[9]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R10: sprintf(info->s, " $t2:%08X%08X", (UINT32)(mips->r[10] >> 32), (UINT32)mips->r[10]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R11: sprintf(info->s, " $t3:%08X%08X", (UINT32)(mips->r[11] >> 32), (UINT32)mips->r[11]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R12: sprintf(info->s, " $t4:%08X%08X", (UINT32)(mips->r[12] >> 32), (UINT32)mips->r[12]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R13: sprintf(info->s, " $t5:%08X%08X", (UINT32)(mips->r[13] >> 32), (UINT32)mips->r[13]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R14: sprintf(info->s, " $t6:%08X%08X", (UINT32)(mips->r[14] >> 32), (UINT32)mips->r[14]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R15: sprintf(info->s, " $t7:%08X%08X", (UINT32)(mips->r[15] >> 32), (UINT32)mips->r[15]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R16: sprintf(info->s, " $s0:%08X%08X", (UINT32)(mips->r[16] >> 32), (UINT32)mips->r[16]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R17: sprintf(info->s, " $s1:%08X%08X", (UINT32)(mips->r[17] >> 32), (UINT32)mips->r[17]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R18: sprintf(info->s, " $s2:%08X%08X", (UINT32)(mips->r[18] >> 32), (UINT32)mips->r[18]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R19: sprintf(info->s, " $s3:%08X%08X", (UINT32)(mips->r[19] >> 32), (UINT32)mips->r[19]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R20: sprintf(info->s, " $s4:%08X%08X", (UINT32)(mips->r[20] >> 32), (UINT32)mips->r[20]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R21: sprintf(info->s, " $s5:%08X%08X", (UINT32)(mips->r[21] >> 32), (UINT32)mips->r[21]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R22: sprintf(info->s, " $s6:%08X%08X", (UINT32)(mips->r[22] >> 32), (UINT32)mips->r[22]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R23: sprintf(info->s, " $s7:%08X%08X", (UINT32)(mips->r[23] >> 32), (UINT32)mips->r[23]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R24: sprintf(info->s, " $t8:%08X%08X", (UINT32)(mips->r[24] >> 32), (UINT32)mips->r[24]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R25: sprintf(info->s, " $t9:%08X%08X", (UINT32)(mips->r[25] >> 32), (UINT32)mips->r[25]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R26: sprintf(info->s, " $k0:%08X%08X", (UINT32)(mips->r[26] >> 32), (UINT32)mips->r[26]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R27: sprintf(info->s, " $k1:%08X%08X", (UINT32)(mips->r[27] >> 32), (UINT32)mips->r[27]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R28: sprintf(info->s, " $gp:%08X%08X", (UINT32)(mips->r[28] >> 32), (UINT32)mips->r[28]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R29: sprintf(info->s, " $sp:%08X%08X", (UINT32)(mips->r[29] >> 32), (UINT32)mips->r[29]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R30: sprintf(info->s, " $fp:%08X%08X", (UINT32)(mips->r[30] >> 32), (UINT32)mips->r[30]); break;
+ case CPUINFO_STR_REGISTER + MIPS3_R31: sprintf(info->s, " $ra:%08X%08X", (UINT32)(mips->r[31] >> 32), (UINT32)mips->r[31]); break;
case CPUINFO_STR_REGISTER + MIPS3_HI: sprintf(info->s, "HI: %08X%08X", (UINT32)(mips->r[REG_HI] >> 32), (UINT32)mips->r[REG_HI]); break;
case CPUINFO_STR_REGISTER + MIPS3_LO: sprintf(info->s, "LO: %08X%08X", (UINT32)(mips->r[REG_LO] >> 32), (UINT32)mips->r[REG_LO]); break;
diff --git a/src/emu/cpu/mips/mips3dsm.c b/src/emu/cpu/mips/mips3dsm.c
index e72ad959d0d..6d477867ec7 100644
--- a/src/emu/cpu/mips/mips3dsm.c
+++ b/src/emu/cpu/mips/mips3dsm.c
@@ -11,10 +11,10 @@
static const char *const reg[32] =
{
- "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
+ "$0", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
+ "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
+ "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
+ "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra"
};
diff --git a/src/emu/cpu/superfx/superfx.c b/src/emu/cpu/superfx/superfx.c
index 446a15ef268..08f3ba0a617 100644
--- a/src/emu/cpu/superfx/superfx.c
+++ b/src/emu/cpu/superfx/superfx.c
@@ -18,7 +18,12 @@ typedef struct
typedef struct _superfx_state superfx_state;
struct _superfx_state
{
+ superfx_config config;
+
+ devcb_resolved_write_line out_irq_func;
+
UINT8 pipeline;
+ UINT16 ramaddr; // RAM Address
UINT16 r[16]; // GPRs
UINT16 sfr; // Status Flag Register
@@ -41,7 +46,6 @@ struct _superfx_state
UINT32 ramcl; // Clock ticks until RAMDR is valid;
UINT16 ramar; // RAM Buffer Address Register
UINT8 ramdr; // RAM Buffer Data Register
- UINT16 ramaddr; // RAM Address
UINT16 *sreg; // Source Register (From)
UINT8 sreg_idx;// Source Register (To), index
@@ -81,17 +85,24 @@ static void superfx_cache_mmio_write(superfx_state *cpustate, UINT32 addr, UINT8
static void superfx_memory_reset(superfx_state *cpustate);
INLINE UINT8 superfx_bus_read(superfx_state *cpustate, UINT32 addr);
INLINE void superfx_bus_write(superfx_state *cpustate, UINT32 addr, UINT8 data);
-static void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line);
-static void superfx_plot(superfx_state *cpustate, UINT8 x, UINT8 y);
+INLINE void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line);
+INLINE void superfx_plot(superfx_state *cpustate, UINT8 x, UINT8 y);
static UINT8 superfx_rpix(superfx_state *cpustate, UINT8 r1, UINT8 r2);
-static UINT8 superfx_color(superfx_state *cpustate, UINT8 source);
+INLINE UINT8 superfx_color(superfx_state *cpustate, UINT8 source);
+
+INLINE void superfx_rambuffer_sync(superfx_state *cpustate);
INLINE UINT8 superfx_rambuffer_read(superfx_state *cpustate, UINT16 addr);
INLINE void superfx_rambuffer_write(superfx_state *cpustate, UINT16 addr, UINT8 val);
+
+INLINE void superfx_rombuffer_sync(superfx_state *cpustate);
+INLINE void superfx_rombuffer_update(superfx_state *cpustate);
+INLINE UINT8 superfx_rombuffer_read(superfx_state *cpustate);
+
INLINE void superfx_gpr_write(superfx_state *cpustate, UINT8 r, UINT16 data);
INLINE UINT8 superfx_op_read(superfx_state *cpustate, UINT16 addr);
INLINE UINT8 superfx_peekpipe(superfx_state *cpustate);
INLINE UINT8 superfx_pipe(superfx_state *cpustate);
-static void superfx_add_clocks_internal(superfx_state *cpustate, INT32 clocks);
+INLINE void superfx_add_clocks_internal(superfx_state *cpustate, UINT32 clocks);
static void superfx_timing_reset(superfx_state *cpustate);
/*****************************************************************************/
@@ -137,14 +148,12 @@ static void superfx_cache_flush(superfx_state *cpustate)
static UINT8 superfx_cache_mmio_read(superfx_state *cpustate, UINT32 addr)
{
addr = (addr + cpustate->cbr) & 0x1ff;
- printf( "superfx_cache_mmio_read: %04x = %02x\n", addr, cpustate->cache.buffer[addr] );
return cpustate->cache.buffer[addr];
}
static void superfx_cache_mmio_write(superfx_state *cpustate, UINT32 addr, UINT8 data)
{
addr = (addr + cpustate->cbr) & 0x1ff;
- printf( "superfx_cache_mmio_write: %04x = %02x\n", addr, data );
cpustate->cache.buffer[addr] = data;
if((addr & 15) == 15)
{
@@ -180,7 +189,7 @@ INLINE void superfx_bus_write(superfx_state *cpustate, UINT32 addr, UINT8 data)
memory_write_byte(cpustate->program, addr, data);
}
-static void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line)
+INLINE void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line)
{
UINT8 x = cpustate->pixelcache[line].offset << 3;
UINT8 y = cpustate->pixelcache[line].offset >> 5;
@@ -225,7 +234,6 @@ static void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line)
{
superfx_add_clocks_internal(cpustate, cpustate->memory_access_speed);
data &= cpustate->pixelcache[line].bitpend;
- //printf( "superfx_pixelcache_flush: calling superfx_bus_read\n" );
data |= superfx_bus_read(cpustate, addr + byte) & ~cpustate->pixelcache[line].bitpend;
}
superfx_add_clocks_internal(cpustate, cpustate->memory_access_speed);
@@ -235,13 +243,11 @@ static void superfx_pixelcache_flush(superfx_state *cpustate, INT32 line)
cpustate->pixelcache[line].bitpend = 0x00;
}
-static void superfx_plot(superfx_state *cpustate, UINT8 x, UINT8 y)
+INLINE void superfx_plot(superfx_state *cpustate, UINT8 x, UINT8 y)
{
UINT8 color = cpustate->colr;
UINT16 offset = (y << 5) + (x >> 3);
- //printf( "%08x: plot: %d, %d = %02x\n", cpustate->r[15], x, y, color );
-
if((cpustate->por & SUPERFX_POR_DITHER) != 0 && (cpustate->scmr & SUPERFX_SCMR_MD) != 3)
{
if((x ^ y) & 1)
@@ -282,42 +288,20 @@ static void superfx_plot(superfx_state *cpustate, UINT8 x, UINT8 y)
if(offset != cpustate->pixelcache[0].offset)
{
superfx_pixelcache_flush(cpustate, 1);
- cpustate->pixelcache[1].bitpend = cpustate->pixelcache[0].bitpend;
- cpustate->pixelcache[1].offset = cpustate->pixelcache[0].offset;
- cpustate->pixelcache[1].data[0] = cpustate->pixelcache[0].data[0];
- cpustate->pixelcache[1].data[1] = cpustate->pixelcache[0].data[1];
- cpustate->pixelcache[1].data[2] = cpustate->pixelcache[0].data[2];
- cpustate->pixelcache[1].data[3] = cpustate->pixelcache[0].data[3];
- cpustate->pixelcache[1].data[4] = cpustate->pixelcache[0].data[4];
- cpustate->pixelcache[1].data[5] = cpustate->pixelcache[0].data[5];
- cpustate->pixelcache[1].data[6] = cpustate->pixelcache[0].data[6];
- cpustate->pixelcache[1].data[7] = cpustate->pixelcache[0].data[7];
cpustate->pixelcache[1] = cpustate->pixelcache[0];
cpustate->pixelcache[0].bitpend = 0x00;
cpustate->pixelcache[0].offset = offset;
}
x = (x & 7) ^ 7;
- cpustate->pixelcache[0].data[x] = 0x0f;//color;
+ cpustate->pixelcache[0].data[x] = color;
cpustate->pixelcache[0].bitpend |= 1 << x;
if(cpustate->pixelcache[0].bitpend == 0xff)
{
superfx_pixelcache_flush(cpustate, 1);
- cpustate->pixelcache[1].bitpend = cpustate->pixelcache[0].bitpend;
- cpustate->pixelcache[1].offset = cpustate->pixelcache[0].offset;
- cpustate->pixelcache[1].data[0] = cpustate->pixelcache[0].data[0];
- cpustate->pixelcache[1].data[1] = cpustate->pixelcache[0].data[1];
- cpustate->pixelcache[1].data[2] = cpustate->pixelcache[0].data[2];
- cpustate->pixelcache[1].data[3] = cpustate->pixelcache[0].data[3];
- cpustate->pixelcache[1].data[4] = cpustate->pixelcache[0].data[4];
- cpustate->pixelcache[1].data[5] = cpustate->pixelcache[0].data[5];
- cpustate->pixelcache[1].data[6] = cpustate->pixelcache[0].data[6];
- cpustate->pixelcache[1].data[7] = cpustate->pixelcache[0].data[7];
+ cpustate->pixelcache[1] = cpustate->pixelcache[0];
cpustate->pixelcache[0].bitpend = 0x00;
}
-
- //superfx_pixelcache_flush(cpustate, 1);
- //superfx_pixelcache_flush(cpustate, 0);
}
static UINT8 superfx_rpix(superfx_state *cpustate, UINT8 x, UINT8 y)
@@ -359,14 +343,11 @@ static UINT8 superfx_rpix(superfx_state *cpustate, UINT8 x, UINT8 y)
data |= ((superfx_bus_read(cpustate, addr + byte) >> x) & 1) << n;
}
- //printf( "%08x: superfx_rpix; %d, %d = %02x\n", (cpustate->pbr << 16) | cpustate->r[15], x, y, data );
-
return data;
}
-static UINT8 superfx_color(superfx_state *cpustate, UINT8 source)
+INLINE UINT8 superfx_color(superfx_state *cpustate, UINT8 source)
{
- //printf("superfx_color\n" );
if(cpustate->por & SUPERFX_POR_HIGHNIBBLE)
{
return (cpustate->colr & 0xf0) | (source >> 4);
@@ -378,20 +359,56 @@ static UINT8 superfx_color(superfx_state *cpustate, UINT8 source)
return source;
}
+INLINE void superfx_rambuffer_sync(superfx_state *cpustate)
+{
+ if(cpustate->ramcl)
+ {
+ superfx_add_clocks_internal(cpustate, cpustate->ramcl);
+ }
+}
+
INLINE UINT8 superfx_rambuffer_read(superfx_state *cpustate, UINT16 addr)
{
+ superfx_rambuffer_sync(cpustate);
return superfx_bus_read(cpustate, 0x700000 + (cpustate->rambr << 16) + addr);
}
INLINE void superfx_rambuffer_write(superfx_state *cpustate, UINT16 addr, UINT8 data)
{
- superfx_bus_write(cpustate, 0x700000 + (cpustate->rambr << 16) + addr, data);
+ superfx_rambuffer_sync(cpustate);
+ cpustate->ramcl = cpustate->memory_access_speed;
+ cpustate->ramar = addr;
+ cpustate->ramdr = data;
+}
+
+static void superfx_rombuffer_sync(superfx_state *cpustate)
+{
+ if(cpustate->romcl)
+ {
+ superfx_add_clocks_internal(cpustate, cpustate->romcl);
+ }
+}
+
+static void superfx_rombuffer_update(superfx_state *cpustate)
+{
+ cpustate->sfr |= SUPERFX_SFR_R;
+ cpustate->romcl = cpustate->memory_access_speed;
+}
+
+static UINT8 superfx_rombuffer_read(superfx_state *cpustate)
+{
+ superfx_rombuffer_sync(cpustate);
+ return cpustate->romdr;
}
INLINE void superfx_gpr_write(superfx_state *cpustate, UINT8 r, UINT16 data)
{
cpustate->r[r] = data;
- if(r == 15)
+ if(r == 14)
+ {
+ superfx_rombuffer_update(cpustate);
+ }
+ else if(r == 15)
{
cpustate->r15_modified = 1;
}
@@ -421,7 +438,20 @@ INLINE UINT8 superfx_op_read(superfx_state *cpustate, UINT16 addr)
return cpustate->cache.buffer[offset];
}
- return superfx_bus_read(cpustate, (cpustate->pbr << 16) + addr);
+ if(cpustate->pbr <= 0x5f)
+ {
+ //$[00-5f]:[0000-ffff] ROM
+ superfx_rombuffer_sync(cpustate);
+ superfx_add_clocks_internal(cpustate, cpustate->memory_access_speed);
+ return superfx_bus_read(cpustate, (cpustate->pbr << 16) + addr);
+ }
+ else
+ {
+ //$[60-7f]:[0000-ffff] RAM
+ superfx_rambuffer_sync(cpustate);
+ superfx_add_clocks_internal(cpustate, cpustate->memory_access_speed);
+ return superfx_bus_read(cpustate, (cpustate->pbr << 16) + addr);
+ }
}
INLINE UINT8 superfx_peekpipe(superfx_state *cpustate)
@@ -468,6 +498,7 @@ UINT8 superfx_mmio_read(const device_config *cpu, UINT32 addr)
UINT8 r = cpustate->sfr >> 8;
cpustate->sfr &= ~SUPERFX_SFR_IRQ;
cpustate->irq = 0;
+ devcb_call_write_line(&cpustate->out_irq_func, cpustate->irq);
return r;
}
@@ -490,8 +521,6 @@ UINT8 superfx_mmio_read(const device_config *cpu, UINT32 addr)
return cpustate->cbr >> 8;
}
- printf( "Unsuppoted mmio read: %08x\n", addr );
-
return 0;
}
@@ -506,8 +535,6 @@ void superfx_mmio_write(const device_config *cpu, UINT32 addr, UINT8 data)
return superfx_cache_mmio_write(cpustate, addr - 0x3100, data);
}
- //printf( "superfx_mmio_write: %08x = %02x\n", addr, data );
-
if(addr >= 0x3000 && addr <= 0x301f)
{
UINT32 n = (addr >> 1) & 0xf;
@@ -523,7 +550,6 @@ void superfx_mmio_write(const device_config *cpu, UINT32 addr, UINT8 data)
if(addr == 0x301f)
{
cpustate->sfr |= SUPERFX_SFR_G;
- //printf( "new PC: %04x\n", cpustate->r[15] );
}
return;
}
@@ -572,14 +598,29 @@ void superfx_mmio_write(const device_config *cpu, UINT32 addr, UINT8 data)
case 0x303a:
cpustate->scmr = data;
break;
-
- default:
- printf( "Unsuppoted mmio write: %08x = %02x\n", addr, data );
}
}
-static void superfx_add_clocks_internal(superfx_state *cpustate, INT32 clocks)
+INLINE void superfx_add_clocks_internal(superfx_state *cpustate, UINT32 clocks)
{
+ if(cpustate->romcl)
+ {
+ cpustate->romcl -= MIN(clocks, cpustate->romcl);
+ if(cpustate->romcl == 0)
+ {
+ cpustate->sfr &= ~SUPERFX_SFR_R;
+ cpustate->romdr = superfx_bus_read(cpustate, (cpustate->rombr << 16) + cpustate->r[14]);
+ }
+ }
+
+ if(cpustate->ramcl)
+ {
+ cpustate->ramcl -= MIN(clocks, cpustate->ramcl);
+ if(cpustate->ramcl == 0)
+ {
+ superfx_bus_write(cpustate, 0x700000 + (cpustate->rambr << 16) + cpustate->ramar, cpustate->ramdr);
+ }
+ }
}
static void superfx_timing_reset(superfx_state *cpustate)
@@ -637,6 +678,13 @@ static CPU_INIT( superfx )
cpustate->device = device;
cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
+
+ if (device->static_config != NULL)
+ {
+ cpustate->config = *(superfx_config *)device->static_config;
+ }
+
+ devcb_resolve_write_line(&cpustate->out_irq_func, &cpustate->config.out_irq_func, device);
}
static CPU_EXIT( superfx )
@@ -707,18 +755,17 @@ static CPU_EXECUTE( superfx )
op = superfx_peekpipe(cpustate);
- //printf( "Executing op at %06x: %02x\n", (cpustate->pbr << 16) | cpustate->r[15], op );
switch(op)
{
case 0x00: // STOP
- if(!(cpustate->cfgr & SUPERFX_CFGR_IRQ))
+ if((cpustate->cfgr & SUPERFX_CFGR_IRQ) == 0)
{
cpustate->sfr |= SUPERFX_SFR_IRQ;
cpustate->irq = 1;
+ devcb_call_write_line(&cpustate->out_irq_func, cpustate->irq ? ASSERT_LINE : CLEAR_LINE );
}
cpustate->sfr &= ~SUPERFX_SFR_G;
cpustate->pipeline = 0x01;
- cpustate->por = 0x00;
superfx_regs_reset(cpustate);
break;
case 0x01: // NOP
@@ -848,7 +895,7 @@ static CPU_EXECUTE( superfx )
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: // TO
- if(!(cpustate->sfr & SUPERFX_SFR_B))
+ if((cpustate->sfr & SUPERFX_SFR_B) == 0)
{
cpustate->dreg = &cpustate->r[op & 0xf];
cpustate->dreg_idx = op & 0xf;
@@ -959,7 +1006,6 @@ static CPU_EXECUTE( superfx )
}
else
{ // CMODE
- //printf( "CMODE: %04x\n", *(cpustate->sreg) );
cpustate->por = *(cpustate->sreg);
superfx_regs_reset(cpustate);
}
@@ -1148,7 +1194,7 @@ static CPU_EXECUTE( superfx )
}
else
{ // LJMP
- cpustate->pbr = cpustate->r[op & 0xf] & 0x7f;
+ cpustate->pbr = cpustate->r[op & 0xf];
superfx_gpr_write(cpustate, 15, *(cpustate->sreg));
cpustate->cbr = cpustate->r[15] & 0xfff0;
superfx_cache_flush(cpustate);
@@ -1157,7 +1203,7 @@ static CPU_EXECUTE( superfx )
break;
case 0x9e: // LOB
- superfx_gpr_write(cpustate, cpustate->dreg_idx, (UINT16)(*(cpustate->sreg)) & 0xff);
+ superfx_gpr_write(cpustate, cpustate->dreg_idx, (UINT16)(*(cpustate->sreg)) & 0x00ff);
cpustate->sfr &= ~(SUPERFX_SFR_S | SUPERFX_SFR_Z);
cpustate->sfr |= (*(cpustate->dreg) & 0x80) ? SUPERFX_SFR_S : 0;
cpustate->sfr |= (*(cpustate->dreg) == 0) ? SUPERFX_SFR_Z : 0;
@@ -1210,7 +1256,7 @@ static CPU_EXECUTE( superfx )
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: // FROM
- if(!(cpustate->sfr & SUPERFX_SFR_B))
+ if((cpustate->sfr & SUPERFX_SFR_B) == 0)
{
cpustate->sreg = &(cpustate->r[op & 0xf]);
cpustate->sreg_idx = op & 0xf;
@@ -1226,8 +1272,10 @@ static CPU_EXECUTE( superfx )
break;
case 0xc0: // HIB
- superfx_gpr_write(cpustate, cpustate->dreg_idx, (UINT16)*(cpustate->sreg) >> 8);
- superfx_dreg_sfr_sz_update(cpustate);
+ superfx_gpr_write(cpustate, cpustate->dreg_idx, (*(cpustate->sreg)) >> 8);
+ cpustate->sfr &= ~(SUPERFX_SFR_S | SUPERFX_SFR_Z);
+ cpustate->sfr |= (*(cpustate->dreg) & 0x80) ? SUPERFX_SFR_S : 0;
+ cpustate->sfr |= (*(cpustate->dreg) == 0) ? SUPERFX_SFR_Z : 0;
superfx_regs_reset(cpustate);
break;
@@ -1266,14 +1314,16 @@ static CPU_EXECUTE( superfx )
{
case SUPERFX_SFR_ALT0: // GETC
case SUPERFX_SFR_ALT1: // GETC
- cpustate->colr = superfx_color(cpustate, superfx_bus_read(cpustate, (cpustate->rombr << 16) + cpustate->r[14]));
+ cpustate->colr = superfx_color(cpustate, superfx_rombuffer_read(cpustate));
superfx_regs_reset(cpustate);
break;
case SUPERFX_SFR_ALT2: // RAMB
+ superfx_rambuffer_sync(cpustate);
cpustate->rambr = *(cpustate->sreg);
superfx_regs_reset(cpustate);
break;
case SUPERFX_SFR_ALT3: // ROMB
+ superfx_rombuffer_sync(cpustate);
cpustate->rombr = *(cpustate->sreg);
superfx_regs_reset(cpustate);
break;
@@ -1291,7 +1341,7 @@ static CPU_EXECUTE( superfx )
case 0xef: // GETB / GETBH / GETBL / GETBS
{
- UINT8 byte = superfx_bus_read(cpustate, (cpustate->rombr << 16) + cpustate->r[14]);
+ UINT8 byte = superfx_rombuffer_read(cpustate);
switch(cpustate->sfr & SUPERFX_SFR_ALT)
{
case SUPERFX_SFR_ALT0: // GETB
diff --git a/src/emu/cpu/superfx/superfx.h b/src/emu/cpu/superfx/superfx.h
index b7b19a58d78..4b308ec10d8 100644
--- a/src/emu/cpu/superfx/superfx.h
+++ b/src/emu/cpu/superfx/superfx.h
@@ -1,6 +1,8 @@
#ifndef __SUPERFX_H__
#define __SUPERFX_H__
+#include "devcb.h"
+
enum
{
SUPERFX_PC = 1,
@@ -82,6 +84,13 @@ enum
#define SUPERFX_CFGR_IRQ 0x80 // IRQ
#define SUPERFX_CFGR_MS0 0x20 // MS0
+typedef struct _superfx_config superfx_config;
+struct _superfx_config
+{
+ devcb_write_line out_irq_func; /* IRQ changed callback */
+};
+#define SUPERFX_CONFIG(name) const superfx_config (name) =
+
CPU_GET_INFO( superfx );
#define CPU_SUPERFX CPU_GET_INFO_NAME( superfx )