diff options
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 |
commit | 5f4c195fe6be0b53df932102dc84a0d6e53706b4 (patch) | |
tree | 3f3e39a1a98c9eeb5ec742308bac9fc219dabce4 | |
parent | 4ba34771dcbb7c882728fab12c14ca66d417cedd (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.c | 261 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4.h | 9 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4dasm.c | 33 | ||||
-rw-r--r-- | src/mame/drivers/naomi.c | 37 | ||||
-rw-r--r-- | src/mame/includes/dc.h | 1 | ||||
-rw-r--r-- | src/mame/machine/dc.c | 258 |
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++) |