static void sync_w(int offset, int data) { int oldword = READ_WORD(&sync_data[offset]); int newword = COMBINE_WORD(oldword, data); WRITE_WORD(&sync_data[offset], newword); if ((oldword & 0xff00) != (newword & 0xff00)) cpu_yield(); }
static WRITE_HANDLER( sync_w ) { int oldword = READ_WORD(&sync_data[offset]); int newword = COMBINE_WORD(oldword, data); WRITE_WORD(&sync_data[offset], newword); if ((oldword & 0xff00) != (newword & 0xff00)) cpu_yield(); }
static WRITE_HANDLER( xain_sharedram_w ) { /* locations 003d and 003e are used as a semaphores between CPU A and B, */ /* so let's resync every time they are changed to avoid deadlocks */ if ((offset == 0x003d || offset == 0x003e) && xain_sharedram[offset] != data) cpu_yield(); xain_sharedram[offset] = data; }
static WRITE16_HANDLER( sync_w ) { int oldword = sync_data[offset]; int newword = oldword; COMBINE_DATA(&newword); sync_data[offset] = newword; if ((oldword & 0xff00) != (newword & 0xff00)) cpu_yield(space->cpu); }
static READ8_HANDLER( mcu_tnzs_r ) { unsigned char data; if (offset == 0) { data = cpunum_get_reg(2, I8X41_DATA); cpu_yield(); } else { data = cpunum_get_reg(2, I8X41_STAT); cpu_yield(); } // logerror("PC %04x: read %02x from mcu $c00%01x\n", activecpu_get_previouspc(), data, offset); return data; }
struct arcp_region *arcp_load(arcp_t *rcp) { /* YURI * We saw a sample of your manhood on the way. A place called Mink. * * PASHA (A shadow on his face) * They'd been selling horses to the whites. * * YURI * No. It seems you burned the wrong village. * * PASHA * They always say that. And what does it matter? A village betrays * us, a village is burnt. The point's made. * * ---Dr. Zhivago, 1964 * (i.e. don't sweat whose reference is whose) */ struct arcp_region *ptr; struct arcp_region *ret; ptr = ak_load(rcp, mo_acquire); do { while (unlikely(__ARCP_PTR2COUNT(ptr) == __ARCP_COUNTMASK)) { /* Spinlock if too many threads are accessing this * at once. */ cpu_yield(); ptr = ak_load(rcp, mo_consume); } } while (unlikely(!ak_cas(rcp, &ptr, __ARCP_PTRINC(ptr), mo_acq_rel, mo_consume))); ptr = __ARCP_PTRINC(ptr); /* We have one reference */ ret = __ARCP_PTRDECOUNT(ptr); if (ret != NULL) { __arcp_urefs(ret, 0, 1); } /* We have two references, try and remove the one stored on the * pointer. */ while (unlikely(!ak_cas(rcp, &ptr, __ARCP_PTRDEC(ptr), mo_acq_rel, mo_acquire))) { /* Is the pointer still valid? */ if ((__ARCP_PTRDECOUNT(ptr) != ret) /* The second test will prevent a/b/a errors */ || (__ARCP_PTR2COUNT(ptr) == 0)) { /* Somebody else has transferred / will transfer the * count. */ if (ret != NULL) { __arcp_urefs(ret, 0, -1); } break; } } return ret; }
static READ8_HANDLER( mcu_tnzs_r ) { UINT8 data; data = upi41_master_r(cputag_get_cpu(space->machine, "mcu"), offset & 1); cpu_yield(space->cpu); // logerror("PC %04x: read %02x from mcu $c00%01x\n", cpu_get_previouspc(space->cpu), data, offset); return data; }
static WRITE8_HANDLER( route16_sharedram_w ) { sharedram[offset] = data; // 4313-4319 are used in Route 16 as triggers to wake the other CPU if (offset >= 0x0313 && offset <= 0x0319 && data == 0xff) { // Let the other CPU run cpu_yield(space->cpu); } }
static WRITE16_HANDLER( sync_w ) { eprom_state *state = space->machine->driver_data<eprom_state>(); int oldword = state->sync_data[offset]; int newword = oldword; COMBINE_DATA(&newword); state->sync_data[offset] = newword; if ((oldword & 0xff00) != (newword & 0xff00)) cpu_yield(space->cpu); }
static READ8_HANDLER( mcu_tnzs_r ) { tnzs_state *state = (tnzs_state *)space->machine->driver_data; UINT8 data; data = upi41_master_r(state->mcu, offset & 1); cpu_yield(space->cpu); // logerror("PC %04x: read %02x from mcu $c00%01x\n", cpu_get_previouspc(space->cpu), data, offset); return data; }
struct arcp_region *arcp_weakref_load(struct arcp_weakref *weakref) { struct arcp_region *ptr; struct arcp_region *desired; struct arcp_region *ret; if (weakref == NULL) { return NULL; } /* load the target */ ptr = ak_load(&weakref->target, mo_consume); do { retry: switch (__ARCP_PTR2COUNT(ptr)) { case __ARCP_WEAKMAX: /* spinlock if too many threads are accessing this at * once. */ cpu_yield(); ptr = ak_load(&weakref->target, mo_consume); goto retry; case __ARCP_HOHDEL: /* attempted deletion; treat it as 0 */ desired = __ARCP_PTRSETCOUNT(ptr, 1); break; default: desired = __ARCP_PTRINC(ptr); } } while (unlikely(!ak_cas(&weakref->target, &ptr, desired, mo_acq_rel, mo_consume))); ptr = desired; /* We have one reference */ ret = __ARCP_PTRDECOUNT(ptr); if (ret != NULL) { __arcp_urefs(ret, 0, 1); } /* We have two references, try and remove the one stored on the * pointer. */ while (unlikely(!ak_cas(&weakref->target, &ptr, __ARCP_PTRDEC(ptr), mo_acq_rel, mo_consume))) { /* Is the pointer still valid? */ if ((__ARCP_PTRDECOUNT(ptr) != ret) || (__ARCP_PTR2COUNT(ptr) == 0) || (__ARCP_PTR2COUNT(ptr) == __ARCP_HOHDEL)) { /* Somebody else has transferred / will transfer the * count. */ if (ret != NULL) { __arcp_urefs(ret, 0, -1); } break; } } return ret; }
static UINT16 ReadWriteC148( int cpu, offs_t offset, UINT16 data, int bWrite ) { offs_t addr = ((offset*2)+0x1c0000)&0x1fe000; UINT16 *pC148Reg = NULL; UINT16 *pC148RegAlt = NULL; UINT16 result = 0; int altCPU = 0; switch( cpu ) { case CPU_MASTER: pC148Reg = namcos2_68k_master_C148; altCPU = CPU_SLAVE; pC148RegAlt = namcos2_68k_slave_C148; break; case CPU_SLAVE: pC148Reg = namcos2_68k_slave_C148; altCPU = CPU_MASTER; pC148RegAlt = namcos2_68k_master_C148; break; case CPU_GPU: pC148Reg = namcos2_68k_gpu_C148; altCPU = CPU_MASTER; pC148RegAlt = namcos2_68k_master_C148; break; } if( bWrite ) { pC148Reg[(addr>>13)&0x1f] = data&0x0007; } switch(addr) { case 0x1c0000: break; /* NAMCOS2_C148_0 level */ case 0x1c2000: break; /* NAMCOS2_C148_1 level */ case 0x1c4000: break; /* NAMCOS2_C148_2 level */ case 0x1c6000: break; /* NAMCOS2_C148_CPUIRQ level */ case 0x1c8000: break; /* NAMCOS2_C148_EXIRQ level */ case 0x1ca000: break; /* NAMCOS2_C148_POSIRQ level */ case 0x1cc000: break; /* NAMCOS2_C148_SERIRQ level */ case 0x1ce000: break; /* NAMCOS2_C148_VBLANKIRQ level */ case 0x1d0000: if( bWrite ) { cpunum_set_input_line(altCPU, pC148RegAlt[NAMCOS2_C148_CPUIRQ], ASSERT_LINE); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_0], CLEAR_LINE); break; case 0x1d2000: cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_1], CLEAR_LINE); break; case 0x1d4000: if( bWrite ) { cpunum_set_input_line(altCPU, pC148RegAlt[NAMCOS2_C148_CPUIRQ], ASSERT_LINE); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_2], CLEAR_LINE); break; case 0x1d6000: if( bWrite ) { // mame_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_CPUIRQ], CLEAR_LINE); break; case 0x1d8000: /* ack EXIRQ */ if( bWrite ) { // mame_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_EXIRQ], CLEAR_LINE); break; case 0x1da000: /* ack POSIRQ */ if( bWrite ) { // mame_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_POSIRQ], CLEAR_LINE); break; case 0x1dc000: /* ack SCIRQ */ if( bWrite ) { // mame_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_SERIRQ], CLEAR_LINE); break; case 0x1de000: /* ack VBLANK */ cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_VBLANKIRQ], CLEAR_LINE); break; case 0x1e0000: /* EEPROM Status Register */ result = ~0; /* Only BIT0 used: 1=EEPROM READY 0=EEPROM BUSY */ break; case 0x1e2000: /* Sound CPU Reset control */ if( cpu == CPU_MASTER ) /* ? */ { if( data&0x01 ) { /* Resume execution */ cpunum_set_input_line(CPU_SOUND, INPUT_LINE_RESET, CLEAR_LINE); cpu_yield(); } else { /* Suspend execution */ cpunum_set_input_line(CPU_SOUND, INPUT_LINE_RESET, ASSERT_LINE); } if( IsSystem21() ) { //printf( "dspkick=0x%x\n", data ); if( data&4 ) { namcos21_kickstart(1); } } } break; case 0x1e4000: /* Alt 68000 & IO CPU Reset */ if( cpu == CPU_MASTER ) /* ? */ { if( data&0x01 ) { /* Resume execution */ ResetAllSubCPUs( CLEAR_LINE ); /* Give the new CPU an immediate slice of the action */ cpu_yield(); } else { /* Suspend execution */ ResetAllSubCPUs( ASSERT_LINE ); } } break; case 0x1e6000: /* Watchdog reset kicker */ /* watchdog_reset_w(0,0); */ break; default: break; } return result; }
/* Release reset on sound CPU */ void slapfight_port_01_w(int offset, int data) { cpu_halt(1,1); cpu_reset(1); cpu_yield(); }
static UINT16 ReadWriteC148( int cpu, offs_t offset, UINT16 data, int bWrite ) { offs_t addr = ((offset*2)+0x1c0000)&0x1fe000; UINT16 *pC148Reg = (cpu==CPU_MASTER)?namcos2_68k_master_C148:namcos2_68k_slave_C148; UINT16 *pC148RegAlt = (cpu==CPU_SLAVE)?namcos2_68k_master_C148:namcos2_68k_slave_C148; UINT16 result = pC148Reg[(addr>>13)&0x1f]; int altCPU = (cpu==CPU_MASTER)?CPU_SLAVE:CPU_MASTER; if( bWrite ) { pC148Reg[(addr>>13)&0x1f] = data&0x0007; } switch(addr) { case 0x1c0000: break; /* NAMCOS2_C148_0 level */ case 0x1c2000: break; /* NAMCOS2_C148_1 level */ case 0x1c4000: break; /* NAMCOS2_C148_2 level */ case 0x1c6000: break; /* NAMCOS2_C148_CPUIRQ level */ case 0x1c8000: break; /* NAMCOS2_C148_EXIRQ level */ case 0x1ca000: break; /* NAMCOS2_C148_POSIRQ level */ case 0x1cc000: break; /* NAMCOS2_C148_SERIRQ level */ case 0x1ce000: break; /* NAMCOS2_C148_VBLANKIRQ level */ case 0x1d0000: if( bWrite ) { /* DSP "render display list now" trigger */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_0], CLEAR_LINE); break; case 0x1d2000: if( bWrite ) { /* printf( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_1], CLEAR_LINE); break; case 0x1d4000: if( bWrite ) { cpunum_set_input_line(altCPU, pC148RegAlt[NAMCOS2_C148_CPUIRQ], ASSERT_LINE); } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_2], CLEAR_LINE); break; case 0x1d6000: if( bWrite ) { /* printf( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_CPUIRQ], CLEAR_LINE); break; case 0x1d8000: /* ack EXIRQ */ if( bWrite ) { /* printf( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_EXIRQ], CLEAR_LINE); break; case 0x1da000: /* ack POSIRQ */ if( bWrite ) { /* printf( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_POSIRQ], CLEAR_LINE); break; case 0x1dc000: /* ack SCIRQ */ if( bWrite ) { /* printf( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data ); */ } cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_SERIRQ], CLEAR_LINE); break; case 0x1de000: /* ack VBLANK */ cpunum_set_input_line(cpu, pC148Reg[NAMCOS2_C148_VBLANKIRQ], CLEAR_LINE); break; case 0x1e0000: /* EEPROM Status Register */ result = ~0; /* Only BIT0 used: 1=EEPROM READY 0=EEPROM BUSY */ break; case 0x1e2000: /* Sound CPU Reset control */ if( cpu == CPU_MASTER ) /* ? */ { if( data&0x01 ) { /* Resume execution */ cpunum_set_input_line(CPU_SOUND, INPUT_LINE_RESET, CLEAR_LINE); cpu_yield(); } else { /* Suspend execution */ cpunum_set_input_line(CPU_SOUND, INPUT_LINE_RESET, ASSERT_LINE); } } break; case 0x1e4000: /* Alt 68000 & IO CPU Reset */ if( cpu == CPU_MASTER ) /* ? */ { if( data&0x01 ) { /* Resume execution */ cpunum_set_input_line(altCPU, INPUT_LINE_RESET, CLEAR_LINE); cpunum_set_input_line(CPU_MCU, INPUT_LINE_RESET, CLEAR_LINE); /* Give the new CPU an immediate slice of the action */ cpu_yield(); } else { /* Suspend execution */ cpunum_set_input_line(altCPU, INPUT_LINE_RESET, ASSERT_LINE); cpunum_set_input_line(CPU_MCU, INPUT_LINE_RESET, ASSERT_LINE); } } break; case 0x1e6000: /* Watchdog reset kicker */ /* watchdog_reset_w(0,0); */ break; default: break; } return result; }