summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2008-02-20 05:11:31 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2008-02-20 05:11:31 +0000
commit5f4c195fe6be0b53df932102dc84a0d6e53706b4 (patch)
tree3f3e39a1a98c9eeb5ec742308bac9fc219dabce4
parent4ba34771dcbb7c882728fab12c14ca66d417cedd (diff)
[SH4] Added missing SH4 instructions and bugfixed the FPU
[NAOMI] Improved I/O board emulation and added working controls (Credit Samuele Zannoli, I just tweeked it to cooperate with my changes).
-rw-r--r--src/emu/cpu/sh4/sh4.c261
-rw-r--r--src/emu/cpu/sh4/sh4.h9
-rw-r--r--src/emu/cpu/sh4/sh4dasm.c33
-rw-r--r--src/mame/drivers/naomi.c37
-rw-r--r--src/mame/includes/dc.h1
-rw-r--r--src/mame/machine/dc.c258
6 files changed, 403 insertions, 196 deletions
diff --git a/src/emu/cpu/sh4/sh4.c b/src/emu/cpu/sh4/sh4.c
index 916046fb08b..cb641af5bb7 100644
--- a/src/emu/cpu/sh4/sh4.c
+++ b/src/emu/cpu/sh4/sh4.c
@@ -29,8 +29,6 @@
/* speed up delay loops, bail out of tight loops */
#define BUSY_LOOP_HACKS 0
-/* work only as described in the datasheet */
-#define DATASHEET_STRICT 0
#define VERBOSE 0
@@ -160,6 +158,84 @@ static void TODO(void)
{
}
+#if 0
+int sign_of(int n)
+{
+ return(sh4.fr[n]>>31);
+}
+
+void zero(int n,int sign)
+{
+if (sign == 0)
+ sh4.fr[n] = 0x00000000;
+else
+ sh4.fr[n] = 0x80000000;
+if ((sh4.fpscr & PR) == 1)
+ sh4.fr[n+1] = 0x00000000;
+}
+
+int data_type_of(int n)
+{
+UINT32 abs;
+
+ abs = sh4.fr[n] & 0x7fffffff;
+ if ((sh4.fpscr & PR) == 0) { /* Single-precision */
+ if (abs < 0x00800000) {
+ if (((sh4.fpscr & DN) == 1) || (abs == 0x00000000)) {
+ if (sign_of(n) == 0) {
+ zero(n, 0);
+ return(SH4_FPU_PZERO);
+ } else {
+ zero(n, 1);
+ return(SH4_FPU_NZERO);
+ }
+ } else
+ return(SH4_FPU_DENORM);
+ } else
+ if (abs < 0x7f800000)
+ return(SH4_FPU_NORM);
+ else
+ if (abs == 0x7f800000) {
+ if (sign_of(n) == 0)
+ return(SH4_FPU_PINF);
+ else
+ return(SH4_FPU_NINF);
+ } else
+ if (abs < 0x7fc00000)
+ return(SH4_FPU_qNaN);
+ else
+ return(SH4_FPU_sNaN);
+ } else { /* Double-precision */
+ if (abs < 0x00100000) {
+ if (((sh4.fpscr & DN) == 1) || ((abs == 0x00000000) && (sh4.fr[n+1] == 0x00000000))) {
+ if(sign_of(n) == 0) {
+ zero(n, 0);
+ return(SH4_FPU_PZERO);
+ } else {
+ zero(n, 1);
+ return(SH4_FPU_NZERO);
+ }
+ } else
+ return(SH4_FPU_DENORM);
+ } else
+ if (abs < 0x7ff00000)
+ return(SH4_FPU_NORM);
+ else
+ if ((abs == 0x7ff00000) && (sh4.fr[n+1] == 0x00000000)) {
+ if (sign_of(n) == 0)
+ return(SH4_FPU_PINF);
+ else
+ return(SH4_FPU_NINF);
+ } else
+ if (abs < 0x7ff80000)
+ return(SH4_FPU_qNaN);
+ else
+ return(SH4_FPU_sNaN);
+ }
+ return(SH4_FPU_NORM);
+}
+#endif
+
INLINE UINT8 RB(offs_t A)
{
if (A >= 0xfe000000)
@@ -2837,12 +2913,20 @@ INLINE void FMOVMRIFR(UINT32 m,UINT32 n)
#endif
} else { /* PR = 0 */
if (sh4.fpu_sz) { /* SZ = 1 */
- n = n & 14;
- sh4.ea = sh4.r[m];
- sh4.fr[n] = RL( sh4.ea );
- sh4.r[m] += 4;
- sh4.fr[n+1] = RL( sh4.r[m] );
- sh4.r[m] += 4;
+ if (n & 1) {
+ n = n & 14;
+ sh4.ea = sh4.r[m];
+ sh4.xf[n] = RL( sh4.ea );
+ sh4.r[m] += 4;
+ sh4.xf[n+1] = RL( sh4.ea+4 );
+ sh4.r[m] += 4;
+ } else {
+ sh4.ea = sh4.r[m];
+ sh4.fr[n] = RL( sh4.ea );
+ sh4.r[m] += 4;
+ sh4.fr[n+1] = RL( sh4.ea+4 );
+ sh4.r[m] += 4;
+ }
} else { /* SZ = 0 */
sh4.ea = sh4.r[m];
sh4.fr[n] = RL( sh4.ea );
@@ -2897,11 +2981,18 @@ INLINE void FMOVFRMDR(UINT32 m,UINT32 n)
#endif
} else { /* PR = 0 */
if (sh4.fpu_sz) { /* SZ = 1 */
- m= m & 14;
- sh4.r[n] -= 8;
- sh4.ea = sh4.r[n];
- WL( sh4.ea,sh4.fr[m] );
- WL( sh4.ea+4,sh4.fr[m+1] );
+ if (m & 1) {
+ m= m & 14;
+ sh4.r[n] -= 8;
+ sh4.ea = sh4.r[n];
+ WL( sh4.ea,sh4.xf[m] );
+ WL( sh4.ea+4,sh4.xf[m+1] );
+ } else {
+ sh4.r[n] -= 8;
+ sh4.ea = sh4.r[n];
+ WL( sh4.ea,sh4.fr[m] );
+ WL( sh4.ea+4,sh4.fr[m+1] );
+ }
} else { /* SZ = 0 */
sh4.r[n] -= 4;
sh4.ea = sh4.r[n];
@@ -2973,29 +3064,6 @@ INLINE void FMOVS0FR(UINT32 m,UINT32 n)
/* FMOV @Rm,DRn PR=1 1111nnn0mmmm1000 */
INLINE void FMOVMRFR(UINT32 m,UINT32 n)
{
-#if DATASHEET_STRICT
- if (sh4.fpu_pr) { /* PR = 1 */
- n= n & 14;
- sh4.ea = sh4.r[m];
-#ifdef LSB_FIRST
- sh4.xf[n+1] = RL( sh4.ea );
- sh4.xf[n] = RL( sh4.ea+4 );
-#else
- sh4.xf[n] = RL( sh4.ea );
- sh4.xf[n+1] = RL( sh4.ea+4 );
-#endif
- } else { /* PR = 0 */
- if (sh4.fpu_sz) { /* SZ = 1 */
- n= n & 14;
- sh4.ea = sh4.r[m];
- sh4.fr[n] = RL( sh4.ea );
- sh4.fr[n+1] = RL( sh4.ea+4 );
- } else { /* SZ = 0 */
- sh4.ea = sh4.r[m];
- sh4.fr[n] = RL( sh4.ea );
- }
- }
-#else
if (sh4.fpu_pr) { /* PR = 1 */
if (n & 1) {
n= n & 14;
@@ -3036,7 +3104,6 @@ INLINE void FMOVMRFR(UINT32 m,UINT32 n)
sh4.fr[n] = RL( sh4.ea );
}
}
-#endif
}
/* FMOV FRm,FRn PR=0 SZ=0 FRm -> FRn 1111nnnnmmmm1100 */
@@ -3046,33 +3113,10 @@ INLINE void FMOVMRFR(UINT32 m,UINT32 n)
/* FMOV XDm,XDn PR=1 XDm -> XDn 1111nnn1mmm11100 */
INLINE void FMOVFR(UINT32 m,UINT32 n)
{
-#if DATASHEET_STRICT
- if (sh4.fpu_pr) { /* PR = 1 */
- if (m & 1)
- if (n & 1) {
- sh4.xf[n & 14] = sh4.xf[m & 14];
- sh4.xf[n | 1] = sh4.xf[m | 1];
- } else {
- sh4.fr[n] = sh4.xf[m & 14];
- sh4.fr[n | 1] = sh4.xf[m | 1];
- }
- else {
- sh4.xf[n & 14] = sh4.fr[m];
- sh4.xf[n | 1] = sh4.fr[m|1]; // (a&14)+1 -> a|1
- }
- } else { /* PR = 0 */
- if (sh4.fpu_sz) { /* SZ = 1 */
- sh4.fr[n] = sh4.fr[m];
- sh4.fr[n+1] = sh4.fr[m+1];
- } else { /* SZ = 0 */
- sh4.fr[n] = sh4.fr[m];
- }
- }
-#else
- if (sh4.fpu_sz == 0) /* SZ = 0 */
+ if ((sh4.fpu_sz == 0) && (sh4.fpu_pr == 0)) /* SZ = 0 */
sh4.fr[n] = sh4.fr[m];
else { /* SZ = 1 or PR = 1 */
- if (m & 1)
+ if (m & 1) {
if (n & 1) {
sh4.xf[n & 14] = sh4.xf[m & 14];
sh4.xf[n | 1] = sh4.xf[m | 1];
@@ -3080,17 +3124,16 @@ INLINE void FMOVFR(UINT32 m,UINT32 n)
sh4.fr[n] = sh4.xf[m & 14];
sh4.fr[n | 1] = sh4.xf[m | 1];
}
- else {
+ } else {
if (n & 1) {
sh4.xf[n & 14] = sh4.fr[m];
sh4.xf[n | 1] = sh4.fr[m | 1]; // (a&14)+1 -> a|1
} else {
- sh4.fr[n] = sh4.fr[m & 14];
+ sh4.fr[n] = sh4.fr[m];
sh4.fr[n | 1] = sh4.fr[m | 1];
}
}
}
-#endif
}
/* FLDI1 FRn 1111nnnn10011101 */
@@ -3137,10 +3180,10 @@ INLINE void FTRC(UINT32 n)
{
if (sh4.fpu_pr) { /* PR = 1 */
n = n & 14;
- sh4.fpul = (INT32)FP_RFD(n);
+ *((INT32 *)&sh4.fpul) = (INT32)FP_RFD(n);
} else { /* PR = 0 */
/* read sh4.fr[n] as float -> truncate -> fpul(32) */
- sh4.fpul = (INT32)FP_RFS(n);
+ *((INT32 *)&sh4.fpul) = (INT32)FP_RFS(n);
}
}
@@ -3150,9 +3193,9 @@ INLINE void FLOAT(UINT32 n)
{
if (sh4.fpu_pr) { /* PR = 1 */
n = n & 14;
- FP_RFD(n) = (double)(INT32)sh4.fpul;
+ FP_RFD(n) = (double)*((INT32 *)&sh4.fpul);
} else { /* PR = 0 */
- FP_RFS(n) = (float)(INT32)sh4.fpul;
+ FP_RFS(n) = (float)*((INT32 *)&sh4.fpul);
}
}
@@ -3161,19 +3204,12 @@ INLINE void FLOAT(UINT32 n)
INLINE void FNEG(UINT32 n)
{
if (sh4.fpu_pr) { /* PR = 1 */
-#ifdef LSB_FIRST
- n = n | 1; // n & 14 + 1
- sh4.fr[n] = sh4.fr[n] ^ 0x80000000;
-#else
- n = n & 14;
- sh4.fr[n] = sh4.fr[n] ^ 0x80000000;
-#endif
+ FP_RFD(n) = -FP_RFD(n);
} else { /* PR = 0 */
- sh4.fr[n] = sh4.fr[n] ^ 0x80000000;
+ FP_RFS(n) = -FP_RFS(n);
}
}
-
/* FABS FRn PR=0 1111nnnn01011101 */
/* FABS DRn PR=1 1111nnn001011101 */
INLINE void FABS(UINT32 n)
@@ -3250,7 +3286,7 @@ INLINE void FCNVSD(UINT32 n)
{
if (sh4.fpu_pr) { /* PR = 1 */
n = n & 14;
- FP_RFD(n) = *((float *)&sh4.fpul);
+ FP_RFD(n) = (double)*((float *)&sh4.fpul);
}
}
@@ -3331,10 +3367,28 @@ INLINE void FSQRT(UINT32 n)
} else { /* PR = 0 */
if (FP_RFS(n) < 0)
return;
- FP_RFS(n) = sqrt(FP_RFS(n));
+ FP_RFS(n) = sqrtf(FP_RFS(n));
}
}
+/* FSRRA FRn PR=0 1111nnnn01111101 */
+INLINE void FSRRA(UINT32 n)
+{
+ if (FP_RFS(n) < 0)
+ return;
+ FP_RFS(n) = 1.0 / sqrtf(FP_RFS(n));
+}
+
+/* FSSCA FPUL,FRn PR=0 1111nnn011111101 */
+INLINE void FSSCA(UINT32 n)
+{
+float angle;
+
+ angle = (((float)(sh4.fpul & 0xFFFF)) / 65536.0) * 2.0 * M_PI;
+ FP_RFS(n) = sinf(angle);
+ FP_RFS(n+1) = cosf(angle);
+}
+
/* FIPR FVm,FVn PR=0 1111nnmm11101101 */
INLINE void FIPR(UINT32 n)
{
@@ -3359,7 +3413,7 @@ float sum[4];
for (i = 0;i < 4;i++) {
sum[i] = 0;
for (j=0;j < 4;j++)
- sum[i] += FP_XFS((j << 2) + i)*FP_RFS(n + i);
+ sum[i] += FP_XFS((j << 2) + i)*FP_RFS(n + j);
FP_RFS(n + i) = sum[i];
}
}
@@ -3431,6 +3485,9 @@ INLINE void op1111(UINT16 opcode)
case 0x60:
FSQRT(Rn);
break;
+ case 0x70:
+ FSRRA(Rn);
+ break;
case 0x80:
FLDI0(Rn);
break;
@@ -3447,18 +3504,44 @@ INLINE void op1111(UINT16 opcode)
FIPR(Rn);
break;
case 0xF0:
- if (opcode == 0xF3FD)
- FSCHG();
- else if (opcode == 0xFBFD)
- FRCHG();
- else if ((opcode & 0x300) == 0x100)
- FTRV(Rn);
+ if (opcode & 0x100) {
+ if (opcode & 0x200) {
+ switch (opcode & 0xC00)
+ {
+ case 0x000:
+ FSCHG();
+ break;
+ case 0x800:
+ FRCHG();
+ break;
+#ifdef ENABLE_DEBUGGER
+ default:
+ mame_debug_break();
+ break;
+#endif
+ }
+ } else {
+ FTRV(Rn);
+ }
+ } else {
+ FSSCA(Rn);
+ }
+ break;
+#ifdef ENABLE_DEBUGGER
+ default:
+ mame_debug_break();
break;
+#endif
}
break;
case 14:
FMAC(Rm,Rn);
break;
+#ifdef ENABLE_DEBUGGER
+ default:
+ mame_debug_break();
+ break;
+#endif
}
}
@@ -5132,7 +5215,7 @@ void sh4_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + SH4_FPSCR: sprintf(info->s, "FPSCR :%08X", sh4.fpscr); break;
case CPUINFO_STR_REGISTER + SH4_FPUL: sprintf(info->s, "FPUL :%08X", sh4.fpul); break;
#ifdef LSB_FIRST
- case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.4e", FP_RS2( 0),(double)FP_RFS2( 0)); break;
+ case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.2e", FP_RS2( 0),(double)FP_RFS2( 0)); break;
case CPUINFO_STR_REGISTER + SH4_FR1: sprintf(info->s, "FR1 :%08X %01.2e", FP_RS2( 1),(double)FP_RFS2( 1)); break;
case CPUINFO_STR_REGISTER + SH4_FR2: sprintf(info->s, "FR2 :%08X %01.2e", FP_RS2( 2),(double)FP_RFS2( 2)); break;
case CPUINFO_STR_REGISTER + SH4_FR3: sprintf(info->s, "FR3 :%08X %01.2e", FP_RS2( 3),(double)FP_RFS2( 3)); break;
@@ -5165,7 +5248,7 @@ void sh4_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + SH4_XF14: sprintf(info->s, "XF14 :%08X %01.2e", FP_XS2(14),(double)FP_XFS2(14)); break;
case CPUINFO_STR_REGISTER + SH4_XF15: sprintf(info->s, "XF15 :%08X %01.2e", FP_XS2(15),(double)FP_XFS2(15)); break;
#else
- case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.4e", FP_RS( 0),(double)FP_RFS( 0)); break;
+ case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.2e", FP_RS( 0),(double)FP_RFS( 0)); break;
case CPUINFO_STR_REGISTER + SH4_FR1: sprintf(info->s, "FR1 :%08X %01.2e", FP_RS( 1),(double)FP_RFS( 1)); break;
case CPUINFO_STR_REGISTER + SH4_FR2: sprintf(info->s, "FR2 :%08X %01.2e", FP_RS( 2),(double)FP_RFS( 2)); break;
case CPUINFO_STR_REGISTER + SH4_FR3: sprintf(info->s, "FR3 :%08X %01.2e", FP_RS( 3),(double)FP_RFS( 3)); break;
diff --git a/src/emu/cpu/sh4/sh4.h b/src/emu/cpu/sh4/sh4.h
index 3d8c9248a96..9e89f8a8bb3 100644
--- a/src/emu/cpu/sh4/sh4.h
+++ b/src/emu/cpu/sh4/sh4.h
@@ -42,6 +42,15 @@ enum {
SH4_INTC_SCIFTXI, SH4_INTC_ITI, SH4_INTC_RCMI, SH4_INTC_ROVI
};
+#define SH4_FPU_PZERO 0
+#define SH4_FPU_NZERO 1
+#define SH4_FPU_DENORM 2
+#define SH4_FPU_NORM 3
+#define SH4_FPU_PINF 4
+#define SH4_FPU_NINF 5
+#define SH4_FPU_qNaN 6
+#define SH4_FPU_sNaN 7
+
enum
{
CPUINFO_INT_SH4_IRLn_INPUT = CPUINFO_INT_CPU_SPECIFIC,
diff --git a/src/emu/cpu/sh4/sh4dasm.c b/src/emu/cpu/sh4/sh4dasm.c
index 1b8ece6dee7..6aa2fd1f3de 100644
--- a/src/emu/cpu/sh4/sh4dasm.c
+++ b/src/emu/cpu/sh4/sh4dasm.c
@@ -9,7 +9,7 @@
static const char *const regname[16] = {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
- "R8", "R9", "R10","R11","R12","R13","R14","SP"
+ "R8", "R9", "R10","R11","R12","R13","R14","R15"
};
static UINT32 op0000(char *buffer, UINT32 pc, UINT16 opcode)
@@ -721,6 +721,9 @@ static UINT32 op1111(char *buffer, UINT32 pc, UINT16 opcode)
case 0x60:
sprintf(buffer, "FSQRT F%s\n", regname[Rn]);
break;
+ case 0x70:
+ sprintf(buffer, "FSRRA F%s\n", regname[Rn]);
+ break;
case 0x80:
sprintf(buffer, "FLDI0 F%s\n", regname[Rn]);
break;
@@ -737,14 +740,26 @@ static UINT32 op1111(char *buffer, UINT32 pc, UINT16 opcode)
sprintf(buffer, "FIPR FV%d, FV%d\n", Rn << 2, Rn & 12);
break;
case 0xF0:
- if (opcode == 0xF3FD)
- sprintf(buffer, "FSCHG\n");
- else if (opcode == 0xFBFD)
- sprintf(buffer, "FRCHG\n");
- else if ((opcode & 0x300) == 0x100)
- sprintf(buffer, "FTRV XMTRX, FV%d\n", Rn & 12);
- else
- sprintf(buffer, "Funknown $%04X", opcode);
+ if (opcode & 0x100) {
+ if (opcode & 0x200) {
+ switch (opcode & 0xC00)
+ {
+ case 0x000:
+ sprintf(buffer, "FSCHG\n");
+ break;
+ case 0x800:
+ sprintf(buffer, "FRCHG\n");
+ break;
+ default:
+ sprintf(buffer, "Funknown $%04X", opcode);
+ break;
+ }
+ } else {
+ sprintf(buffer, "FTRV XMTRX, FV%d\n", Rn & 12);
+ }
+ } else {
+ sprintf(buffer, "FSSCA FPUL, F%d\n", Rn & 14);
+ }
break;
default:
sprintf(buffer, "Funknown $%04X", opcode);
diff --git a/src/mame/drivers/naomi.c b/src/mame/drivers/naomi.c
index 9bba7ed22ee..124bee141c3 100644
--- a/src/mame/drivers/naomi.c
+++ b/src/mame/drivers/naomi.c
@@ -512,7 +512,7 @@ Virtua Striker 2 2000 840-0010C 21929C 15 315-6213 317-025
#include "dc.h"
#include "deprecat.h"
-#define CPU_CLOCK 200000000
+#define CPU_CLOCK (200000000)
/* MD2 MD1 MD0 MD6 MD4 MD3 MD5 MD7 MD8 */
static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, 0, CPU_CLOCK };
@@ -523,6 +523,15 @@ UINT32 dma_offset;
static INTERRUPT_GEN( naomi_vblank )
{
+ FILE *f;
+
+ if (input_code_pressed_once(KEYCODE_H))
+ {
+ f = fopen("aica.bin", "wb");
+ fwrite(dc_sound_ram, 8*1024*1024, 1, f);
+ fclose(f);
+ }
+
dc_vblank();
}
@@ -727,9 +736,32 @@ static ADDRESS_MAP_START( dc_audio_map, ADDRESS_SPACE_PROGRAM, 32 )
ADDRESS_MAP_END
static INPUT_PORTS_START( naomi )
- PORT_START
+ PORT_START_TAG("IN0")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Service")
PORT_SERVICE_NO_TOGGLE( 0x01, IP_ACTIVE_LOW )
+ PORT_START_TAG("IN1")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START1 )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 )
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 )
+ PORT_START_TAG("IN2")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON3 )
+ PORT_START_TAG("IN3")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START2 )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_START_TAG("IN4")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2)
+ PORT_START_TAG("COINS")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
INPUT_PORTS_END
static const struct AICAinterface aica_interface =
@@ -756,6 +788,7 @@ static MACHINE_DRIVER_START( naomi )
MDRV_CPU_ADD_TAG("sound", ARM7, ((XTAL_33_8688MHz*2)/3)/8) // AICA bus clock is 2/3rds * 33.8688. ARM7 gets 1 bus cycle out of each 8.
MDRV_CPU_PROGRAM_MAP(dc_audio_map, 0)
+ MDRV_MACHINE_START( dc )
MDRV_MACHINE_RESET( naomi )
MDRV_SCREEN_REFRESH_RATE(60)
diff --git a/src/mame/includes/dc.h b/src/mame/includes/dc.h
index 8d8ef98bf47..5f2437a3f1b 100644
--- a/src/mame/includes/dc.h
+++ b/src/mame/includes/dc.h
@@ -29,6 +29,7 @@ WRITE64_HANDLER( dc_aica_reg_w );
READ32_HANDLER( dc_arm_aica_r );
WRITE32_HANDLER( dc_arm_aica_w );
+MACHINE_START( dc );
MACHINE_RESET( dc );
int compute_interrupt_level(void);
diff --git a/src/mame/machine/dc.c b/src/mame/machine/dc.c
index fdcbef086af..7e1367ce573 100644
--- a/src/mame/machine/dc.c
+++ b/src/mame/machine/dc.c
@@ -15,7 +15,7 @@
#if DEBUG_REGISTERS
-#define DEBUG_SYSCTRL (1)
+#define DEBUG_SYSCTRL (0)
#define DEBUG_MAPLE (0)
#if DEBUG_SYSCTRL
@@ -125,6 +125,7 @@ static UINT32 g1bus_regs[0x100/4];
extern UINT32 dma_offset;
static UINT8 maple0x86data1[0x80];
static UINT8 maple0x86data2[0x400];
+static UINT32 coin_counts[8];
static const UINT32 maple0x82answer[]=
{
@@ -252,9 +253,6 @@ WRITE64_HANDLER( dc_sysctrl_w )
ddtdata.direction=0;
ddtdata.channel=2;
ddtdata.mode=25; //011001
- /*if (pp == 1)
- if (sysctrl_regs[SB_C2DLEN] == 0x240)
- pp=pp+1;*/
cpunum_set_info_ptr(0,CPUINFO_PTR_SH4_EXTERNAL_DDT_DMA,&ddtdata);
#if DEBUG_SYSCTRL
mame_printf_verbose("SYSCTRL: Ch2 dma %x from %08x to %08x (lmmode0=%d lmmode1=%d)\n", sysctrl_regs[SB_C2DLEN], ddtdata.source-ddtdata.length, sysctrl_regs[SB_C2DSTAT],sysctrl_regs[SB_LMMODE0],sysctrl_regs[SB_LMMODE1]);
@@ -308,6 +306,7 @@ WRITE64_HANDLER( dc_maple_w )
struct sh4_ddt_dma ddtdata;
UINT32 buff[512];
UINT32 endflag,port,pattern,length,command,dap,sap,destination;
+ UINT32 subcommand;
static int jvs_command = 0,jvs_address = 0;
int chk;
int a;
@@ -401,7 +400,8 @@ WRITE64_HANDLER( dc_maple_w )
ddtdata.mode=-1;
cpunum_set_info_ptr(0,CPUINFO_PTR_SH4_EXTERNAL_DDT_DMA,&ddtdata);
- if ((buff[0] & 0xff) == 3) // read data
+ subcommand = buff[0] & 0xff;
+ if (subcommand == 3) // read data
{
for (a=0;a < 0x80;a+=4)
{
@@ -409,18 +409,18 @@ WRITE64_HANDLER( dc_maple_w )
}
ddtdata.length=0x84/4;
}
- else if ((buff[0] & 0xff) == 0xb) // store data
+ else if (subcommand == 0xb) // store data
{
off=(buff[0] >> 8) & 0xff;
len=(buff[0] >> 16) & 0xff;
for (a=0;a < len;a++)
maple0x86data1[off+a]=(buff[1+a/4] >> (a & 3) * 8) & 255;
}
- else if (((buff[0] & 0xff) == 0x31) || ((buff[0] & 0xff) == 0x1))
+ else if ((subcommand == 0x31) || (subcommand == 0x1))
{
ddtdata.length=1;
}
- else if ((buff[0] & 0xff) == 0x17) // send command into jvs serial bus !!!
+ else if (subcommand == 0x17) // send command into jvs serial bus !!!
{
// Examples:
// 17,*c295407 (77),*c295404,*c295405,*c295406,0,ff,2,f0,d9, 0 // ff broadcast
@@ -436,114 +436,160 @@ WRITE64_HANDLER( dc_maple_w )
buff[1] = 0xe4e3e2e1;
ddtdata.length = 2;
}
- else if ((buff[0] & 0xff) == 0x15) // get response from previous jvs command
+ else if (subcommand == 0x15) // get response from previous jvs command
{
- int tocopy;
+ int tocopy, pos;
// 15,0,0,0
- maple0x86data1[0] = 0xa0;
+ maple0x86data2[0] = 0xa0;
for (a=1;a < 32;a++)
maple0x86data2[a] = maple0x86data2[a-1] + 1;
- buff[1] = 0xA3A2A1A0;
- for (a=0;a < 9;a++)
- {
- buff[2+a]=buff[1+a]+0x04040404;
- }
- buff[1] = buff[1] | 0x0c000000;
maple0x86data2[3] = maple0x86data2[3] | 0x0c;
- buff[2] = buff[2] & 0xFFCFFFFF;
maple0x86data2[6] = maple0x86data2[6] & 0xcf;
- a = readinputport(0); // put keys here
- buff[2]= buff[2] | (a << 20);
+ a = readinputportbytag("IN0"); // put keys here
maple0x86data2[6] = maple0x86data2[6] | (a << 4);
- if (jvs_command)
- *(((unsigned char *)buff)+0x15+2)=jvs_address;
- else
- *(((unsigned char *)buff)+0x15+2)=0;
- *(((unsigned char *)buff)+0x15+3)=0;
- *(((unsigned char *)buff)+0x15+8)=1;
- *(((unsigned char *)buff)+0x15+1)=0x8e;
- if (jvs_command)
- maple0x86data2[0x11+2] = jvs_address;
- else
- maple0x86data2[0x11+2] = 0;
- maple0x86data2[0x11+3] = 0;
- maple0x86data2[0x11+8] = 1;
- maple0x86data2[0x11+1] = 0x8e;
- maple0x86data2[0x11+9] = 1;
- // 4 + 1 + 0x10 + ?,8e,addr,0,?,?,addr?,len,status,report1,jvsbytes...
- ddtdata.length=11;
- tocopy=27;
- *(((unsigned char *)buff)+0x15+9)=1;
- switch (jvs_command)
+ pos = 0x11;
+ tocopy = 17;
+ for (;;)
{
- case 0xf0: // reset
- case 0xf1: // set address
- break;
- case 0x10:
- strcpy((char *)(maple0x86data2+0x11+10), "MAME test JVS I/O board"); // name
- maple0x86data2[0x11+7]=24+2;
- tocopy += 24;
- break;
- case 0x11:
- maple0x86data2[0x11+10]=0x13; // version bcd
- maple0x86data2[0x11+7]=1+2;
- tocopy += 1;
- break;
- case 0x12:
- maple0x86data2[0x11+10]=0x30; // version bcd
- maple0x86data2[0x11+7]=1+2;
- tocopy += 1;
- break;
- case 0x13:
- maple0x86data2[0x11+10]=0x10; // version bcd
- maple0x86data2[0x11+7]=1+2;
- tocopy += 1;
- break;
- case 0x14:
- // four bytes for every available function
- // first function
- maple0x86data2[0x11+10]=1;
- maple0x86data2[0x11+11]=2; // number of players
- maple0x86data2[0x11+12]=7;
- maple0x86data2[0x11+13]=0;
- // second function
- maple0x86data2[0x11+14]=2;
- maple0x86data2[0x11+15]=2; // number of coin slots
- maple0x86data2[0x11+16]=0;
- maple0x86data2[0x11+17]=0;
- // third function
- maple0x86data2[0x11+18]=3;
- maple0x86data2[0x11+19]=2; // channels
- maple0x86data2[0x11+20]=8; // bits
- maple0x86data2[0x11+21]=0;
- // no more functions
- maple0x86data2[0x11+22]=0;
- maple0x86data2[0x11+7]=13+2;
- tocopy += 13;
- break;
- case 0x21:
- maple0x86data2[0x11+10]=0; // bits 7-6 status bits 5-0 higer bits of coin count
- maple0x86data2[0x11+11]=0; // lower bits of coin count
- maple0x86data2[0x11+12]=0; // like previuos two but for second coin slot
- maple0x86data2[0x11+13]=0;
- maple0x86data2[0x11+7]=4+2;
- tocopy += 4;
+ if (jvs_command)
+ maple0x86data2[pos+2] = jvs_address;
+ else
+ maple0x86data2[pos+2] = 0;
+ maple0x86data2[pos+3] = 0;
+ maple0x86data2[pos+8] = 1;
+ maple0x86data2[pos+1] = 0x8e;
+ maple0x86data2[pos+9] = 1;
+ // 4 + 1 + 0x10 + ?,8e,addr,0,?,?,addr?,len,status,report1,jvsbytes...
+ ddtdata.length=11;
+ tocopy += 10;
+ switch (jvs_command)
+ {
+ case 0xf0: // reset
+ case 0xf1: // set address
+ break;
+ case 0x10:
+ strcpy((char *)(maple0x86data2+0x11+10), "MAME test JVS I/O board"); // name
+ maple0x86data2[pos+7]=24+2;
+ tocopy += 24;
+ break;
+ case 0x11:
+ maple0x86data2[pos+10]=0x13; // version bcd
+ maple0x86data2[pos+7]=1+2;
+ tocopy += 1;
+ break;
+ case 0x12:
+ maple0x86data2[pos+10]=0x30; // version bcd
+ maple0x86data2[pos+7]=1+2;
+ tocopy += 1;
+ break;
+ case 0x13:
+ maple0x86data2[pos+10]=0x10; // version bcd
+ maple0x86data2[pos+7]=1+2;
+ tocopy += 1;
+ break;
+ case 0x14:
+ // four bytes for every available function
+ // first function
+ maple0x86data2[pos+10]=1;
+ maple0x86data2[pos+11]=2; // number of players
+ maple0x86data2[pos+12]=9; // switches per player (27 = mahjong)
+ maple0x86data2[pos+13]=0;
+ // second function
+ maple0x86data2[pos+14]=2;
+ maple0x86data2[pos+15]=2; // number of coin slots
+ maple0x86data2[pos+16]=0;
+ maple0x86data2[pos+17]=0;
+ // third function
+ maple0x86data2[pos+18]=3;
+ maple0x86data2[pos+19]=2; // analog channels
+ maple0x86data2[pos+20]=8; // bits per channel
+ maple0x86data2[pos+21]=0;
+ // no more functions
+ maple0x86data2[pos+22]=0;
+ maple0x86data2[pos+7]=13+2;
+ tocopy += 13;
+ break;
+ case 0x21:
+ maple0x86data2[pos+10]=0; // bits 7-6 status bits 5-0 higer bits of coin count
+ maple0x86data2[pos+11]=0; // lower bits of coin count
+ maple0x86data2[pos+12]=0; // like previuos two but for second coin slot
+ maple0x86data2[pos+13]=0;
+ maple0x86data2[pos+7]=4+2;
+ tocopy += 4;
+ break;
+ case -1: // special case to read controls
+ case -2:
+ // report1,jvsbytes repeated for each function
+ // first function
+ maple0x86data2[pos+ 9]=1; // report
+ maple0x86data2[pos+10]=0; // bits TEST TILT1 TILT2 TILT3 ? ? ? ?
+ maple0x86data2[pos+11]=readinputportbytag("IN1"); // bits 1Pstart 1Pservice 1Pup 1Pdown 1Pleft 1Pright 1Ppush1 1Ppush2
+ maple0x86data2[pos+12]=readinputportbytag("IN2"); // bits 1Ppush3 1Ppush4 1Ppush5 1Ppush6 1Ppush7 1Ppush8 ...
+ maple0x86data2[pos+13]=readinputportbytag("IN3"); // bits 2Pstart 2Pservice 2Pup 2Pdown 2Pleft 2Pright 2Ppush1 2Ppush2
+ maple0x86data2[pos+14]=readinputportbytag("IN4"); // bits 2Ppush3 2Ppush4 2Ppush5 2Ppush6 2Ppush7 2Ppush8 ...
+ // second function
+ maple0x86data2[pos+15]=1; // report
+ maple0x86data2[pos+16]=(coin_counts[0] >> 8) & 0xff; // 1CONDITION, 1SLOT COIN(bit13-8)
+ maple0x86data2[pos+17]=coin_counts[0] & 0xff; // 1SLOT COIN(bit7-0)
+ maple0x86data2[pos+18]=(coin_counts[1] >> 8) & 0xff; // 2CONDITION, 2SLOT COIN(bit13-8)
+ maple0x86data2[pos+19]=coin_counts[1] & 0xff; // 2SLOT COIN(bit7-0)
+ // third function
+ maple0x86data2[pos+20]=1; // report
+ maple0x86data2[pos+21]=0xff; // channel 1 bits 7-0
+ maple0x86data2[pos+22]=0; // channel 1
+ maple0x86data2[pos+23]=0; // channel 2 bits 7-0
+ maple0x86data2[pos+24]=0xff; // channel 2
+ if (jvs_command == -1)
+ {
+ // ?
+ maple0x86data2[pos+25]=0;
+ maple0x86data2[pos+26]=0;
+ maple0x86data2[pos+7]=17+2;
+ tocopy += 17;
+ }
+ else
+ {
+ maple0x86data2[pos+7]=15+2;
+ tocopy += 15;
+ }
+ break;
+ }
+ if (jvs_command == -1)
+ {
+ maple0x86data2[pos+4]=maple0x86data2[pos+7]+5;
+ pos = pos+maple0x86data2[pos+4]+3;
+ jvs_command = 0;
+ continue;
+ }
+ else
+ {
+ maple0x86data2[pos+4]=maple0x86data2[pos+7]-1;
break;
+ }
}
for (a=0;a < tocopy;a=a+4)
buff[1+a/4] = maple0x86data2[a] | (maple0x86data2[a+1] << 8) | (maple0x86data2[a+2] << 16) | (maple0x86data2[a+3] << 24);
jvs_command=0;
ddtdata.length = (tocopy+7)/4;
}
- else if ((buff[0] & 0xff) == 0x21)
+ else if (subcommand == 0x21)
{
// 21,*c295407 (77),*c295404,*c295405,*c295406,0,1,0
- ddtdata.length=1;
+ jvs_address = (buff[1] >> 16) & 0xff; // slave address
+ jvs_command = -2;
+ ddtdata.length=2;
}
- else //0x27
+ else if (subcommand == 0x27) //0x27
{
- ddtdata.length=1;
+ // 27,*c295407 (77),*c295404,*c295405,*c295406,0,01,1,0,0,0
+ jvs_address = (buff[1] >> 16) & 0xff; // slave address
+ jvs_command = -1;
+ ddtdata.length=2;
+ }
+ else // 0x13
+ {
+ ddtdata.length=2;
}
break;
default:
@@ -574,6 +620,20 @@ WRITE64_HANDLER( dc_maple_w )
}
}
+static void coin_slots_callback(void *param, UINT32 oldval, UINT32 newval)
+{
+UINT32 a,b,c;
+
+ c = (newval ^ oldval) & newval;
+ b = 1;
+ for (a=0;a < 2;a++)
+ {
+ if (c & b)
+ coin_counts[a]++;
+ b = b << 1;
+ }
+}
+
READ64_HANDLER( dc_gdrom_r )
{
UINT32 off;
@@ -751,6 +811,11 @@ WRITE64_HANDLER( dc_rtc_w )
dc_rtcregister[RTC1] = (dc_rtcregister[RTC1] + 1) & 0xFFFF;
}*/
+MACHINE_START( dc )
+{
+ input_port_set_changed_callback(port_tag_to_index("COINS"), 0x03, coin_slots_callback, NULL);
+}
+
MACHINE_RESET( dc )
{
int a;
@@ -761,6 +826,7 @@ MACHINE_RESET( dc )
memset(sysctrl_regs, 0, sizeof(sysctrl_regs));
memset(maple_regs, 0, sizeof(maple_regs));
memset(dc_rtcregister, 0, sizeof(dc_rtcregister));
+ memset(coin_counts, 0, sizeof(coin_counts));
sysctrl_regs[SB_SBREV] = 0x0b;
for (a=0;a < 0x80;a++)