diff --git a/src/emu/cpu/nec/nec.c b/src/emu/cpu/nec/nec.c index b95326b78d5..240ef2fc1b9 100644 --- a/src/emu/cpu/nec/nec.c +++ b/src/emu/cpu/nec/nec.c @@ -215,6 +215,7 @@ static CPU_RESET( nec ) nec_state->nmi_state = 0; nec_state->irq_state = 0; nec_state->poll_state = 1; + nec_state->halted = 0; Sreg(PS) = 0xffff; Sreg(SS) = 0; @@ -289,13 +290,19 @@ static void set_irq_line(nec_state_t *nec_state, int irqline, int state) if (state == CLEAR_LINE) nec_state->pending_irq &= ~INT_IRQ; else + { nec_state->pending_irq |= INT_IRQ; + nec_state->halted = 0; + } break; case INPUT_LINE_NMI: if (nec_state->nmi_state == state) return; nec_state->nmi_state = state; if (state != CLEAR_LINE) + { nec_state->pending_irq |= NMI_IRQ; + nec_state->halted = 0; + } break; case NEC_INPUT_LINE_POLL: nec_state->poll_state = state; @@ -308,7 +315,7 @@ static CPU_DISASSEMBLE( nec ) return necv_dasm_one(buffer, pc, oprom, NULL); } -static void nec_init(legacy_cpu_device *device, device_irq_callback irqcallback, int type) +static void nec_init(legacy_cpu_device *device, device_irq_callback irqcallback) { nec_state_t *nec_state = get_safe_token(device); @@ -356,6 +363,7 @@ static void nec_init(legacy_cpu_device *device, device_irq_callback irqcallback, device->save_item(NAME(nec_state->nmi_state)); device->save_item(NAME(nec_state->irq_state)); device->save_item(NAME(nec_state->poll_state)); + device->save_item(NAME(nec_state->halted)); nec_state->irq_callback = irqcallback; nec_state->device = device; @@ -371,6 +379,13 @@ static CPU_EXECUTE( necv ) nec_state_t *nec_state = get_safe_token(device); int prev_ICount; + if (nec_state->halted) + { + nec_state->icount = 0; + debugger_instruction_hook(device, (Sreg(PS)<<4) + nec_state->ip); + return; + } + while(nec_state->icount>0) { /* Dispatch IRQ */ if (nec_state->pending_irq && nec_state->no_interrupt==0) @@ -397,7 +412,7 @@ static CPU_INIT( v20 ) { nec_state_t *nec_state = get_safe_token(device); - nec_init(device, irqcallback, 0); + nec_init(device, irqcallback); nec_state->fetch_xor = 0; nec_state->chip_type=V20_TYPE; nec_state->prefetch_size = 4; /* 3 words */ @@ -408,7 +423,7 @@ static CPU_INIT( v30 ) { nec_state_t *nec_state = get_safe_token(device); - nec_init(device, irqcallback, 1); + nec_init(device, irqcallback); nec_state->fetch_xor = BYTE_XOR_LE(0); nec_state->chip_type=V30_TYPE; nec_state->prefetch_size = 6; /* 3 words */ @@ -420,7 +435,7 @@ static CPU_INIT( v33 ) { nec_state_t *nec_state = get_safe_token(device); - nec_init(device, irqcallback, 2); + nec_init(device, irqcallback); nec_state->chip_type=V33_TYPE; nec_state->prefetch_size = 6; /* FIXME: Need information about prefetch size and cycles for V33. diff --git a/src/emu/cpu/nec/necinstr.c b/src/emu/cpu/nec/necinstr.c index 1fb8ee1d195..63fb0270c56 100644 --- a/src/emu/cpu/nec/necinstr.c +++ b/src/emu/cpu/nec/necinstr.c @@ -608,7 +608,7 @@ OP( 0xf3, i_repe ) { UINT32 next = fetchop(nec_state); UINT16 c = Wreg(CW); } nec_state->seg_prefix=FALSE; } -OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC(nec_state)); nec_state->icount=0; } +OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC(nec_state)); nec_state->halted=1; nec_state->icount=0; } OP( 0xf5, i_cmc ) { nec_state->CarryVal = !CF; CLK(2); } OP( 0xf6, i_f6pre ) { UINT32 tmp; UINT32 uresult,uresult2; INT32 result,result2; GetModRM; tmp = GetRMByte(ModRM); diff --git a/src/emu/cpu/nec/necpriv.h b/src/emu/cpu/nec/necpriv.h index 7931b728aad..ae27a451f9c 100644 --- a/src/emu/cpu/nec/necpriv.h +++ b/src/emu/cpu/nec/necpriv.h @@ -53,6 +53,7 @@ struct _nec_state_t UINT32 irq_state; UINT32 poll_state; UINT8 no_interrupt; + UINT8 halted; device_irq_callback irq_callback; legacy_cpu_device *device; diff --git a/src/emu/cpu/nec/v25.c b/src/emu/cpu/nec/v25.c index d3f8c3c374b..140ed9da766 100644 --- a/src/emu/cpu/nec/v25.c +++ b/src/emu/cpu/nec/v25.c @@ -181,6 +181,7 @@ static CPU_RESET( v25 ) nec_state->intp_state[0] = 0; nec_state->intp_state[1] = 0; nec_state->intp_state[2] = 0; + nec_state->halted = 0; nec_state->TM0 = nec_state->MD0 = nec_state->TM1 = nec_state->MD1 = 0; nec_state->TMC0 = nec_state->TMC1 = 0; @@ -366,13 +367,19 @@ static void set_irq_line(v25_state_t *nec_state, int irqline, int state) if (state == CLEAR_LINE) nec_state->pending_irq &= ~INT_IRQ; else + { nec_state->pending_irq |= INT_IRQ; + nec_state->halted = 0; + } break; case INPUT_LINE_NMI: if (nec_state->nmi_state == state) return; nec_state->nmi_state = state; if (state != CLEAR_LINE) + { nec_state->pending_irq |= NMI_IRQ; + nec_state->halted = 0; + } break; case NEC_INPUT_LINE_INTP0: case NEC_INPUT_LINE_INTP1: @@ -396,7 +403,7 @@ static CPU_DISASSEMBLE( v25 ) return necv_dasm_one(buffer, pc, oprom, nec_state->config); } -static void v25_init(legacy_cpu_device *device, device_irq_callback irqcallback, int type) +static void v25_init(legacy_cpu_device *device, device_irq_callback irqcallback) { const nec_config *config = device->static_config() ? (const nec_config *)device->static_config() : &default_config; v25_state_t *nec_state = get_safe_token(device); @@ -465,6 +472,7 @@ static void v25_init(legacy_cpu_device *device, device_irq_callback irqcallback, device->save_item(NAME(nec_state->irq_state)); device->save_item(NAME(nec_state->poll_state)); device->save_item(NAME(nec_state->mode_state)); + device->save_item(NAME(nec_state->halted)); device->save_item(NAME(nec_state->TM0)); device->save_item(NAME(nec_state->MD0)); device->save_item(NAME(nec_state->TM1)); @@ -490,6 +498,41 @@ static CPU_EXECUTE( v25 ) v25_state_t *nec_state = get_safe_token(device); int prev_ICount; + int pending = nec_state->pending_irq & nec_state->unmasked_irq; + + if (nec_state->halted && pending) + { + for(int i = 0; i < 8; i++) + { + if (nec_state->ISPR & (1 << i)) break; + + if (nec_state->priority_inttu == i && (pending & (INTTU0|INTTU1|INTTU2))) + nec_state->halted = 0; + + if (nec_state->priority_intd == i && (pending & (INTD0|INTD1))) + nec_state->halted = 0; + + if (nec_state->priority_intp == i && (pending & (INTP0|INTP1|INTP2))) + nec_state->halted = 0; + + if (nec_state->priority_ints0 == i && (pending & (INTSER0|INTSR0|INTST0))) + nec_state->halted = 0; + + if (nec_state->priority_ints1 == i && (pending & (INTSER1|INTSR1|INTST1))) + nec_state->halted = 0; + + if (i == 7 && (pending & INTTB)) + nec_state->halted = 0; + } + } + + if (nec_state->halted) + { + nec_state->icount = 0; + debugger_instruction_hook(device, (Sreg(PS)<<4) + nec_state->ip); + return; + } + while(nec_state->icount>0) { /* Dispatch IRQ */ if (nec_state->no_interrupt==0 && (nec_state->pending_irq & nec_state->unmasked_irq)) @@ -516,7 +559,7 @@ static CPU_INIT( v25 ) { v25_state_t *nec_state = get_safe_token(device); - v25_init(device, irqcallback, 0); + v25_init(device, irqcallback); nec_state->fetch_xor = 0; nec_state->chip_type=V20_TYPE; nec_state->prefetch_size = 4; /* 3 words */ @@ -527,7 +570,7 @@ static CPU_INIT( v35 ) { v25_state_t *nec_state = get_safe_token(device); - v25_init(device, irqcallback, 1); + v25_init(device, irqcallback); nec_state->fetch_xor = BYTE_XOR_LE(0); nec_state->chip_type=V30_TYPE; nec_state->prefetch_size = 6; /* 3 words */ diff --git a/src/emu/cpu/nec/v25instr.c b/src/emu/cpu/nec/v25instr.c index a18c4a24daa..72cc1c9f7e3 100644 --- a/src/emu/cpu/nec/v25instr.c +++ b/src/emu/cpu/nec/v25instr.c @@ -73,6 +73,7 @@ OP( 0x0f, i_pre_v25 ) { UINT32 ModRM, tmp, tmp2; case 0x92 : FINT; CLK(2); nec_state->no_interrupt = 1; break; case 0x94 : GetRB; TSKSW; CLK(20); break; case 0x95 : GetRB; MOVSPB; CLK(11); break; + case 0x9e : logerror("%06x: STOP\n",PC(nec_state)); nec_state->icount=0; break; default: logerror("%06x: Unknown V25 instruction\n",PC(nec_state)); break; } } diff --git a/src/emu/cpu/nec/v25priv.h b/src/emu/cpu/nec/v25priv.h index dd209388970..87ced6cdb2e 100644 --- a/src/emu/cpu/nec/v25priv.h +++ b/src/emu/cpu/nec/v25priv.h @@ -92,6 +92,7 @@ struct _v25_state_t UINT32 mode_state; UINT32 intp_state[3]; UINT8 no_interrupt; + UINT8 halted; /* timer related */ UINT16 TM0, MD0, TM1, MD1;