diff --git a/src/emu/cpu/i86/i286.c b/src/emu/cpu/i86/i286.c index 18e96ffcc27..199b8be6484 100644 --- a/src/emu/cpu/i86/i286.c +++ b/src/emu/cpu/i86/i286.c @@ -60,16 +60,18 @@ struct _i80286_state const device_config *device; const address_space *program; const address_space *io; - INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */ - UINT8 ParityVal; + INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */ + UINT8 ParityVal; UINT8 TF, IF; /* 0 or 1 valued flags */ UINT8 int_vector; INT8 nmi_state; INT8 irq_state; - INT8 test_state; /* PJB 03/05 */ + INT8 test_state; UINT8 rep_in_progress; INT32 extra_cycles; /* extra cycles for interrupts */ + int halted; /* Is the CPU halted ? */ + memory_interface mem; int icount; unsigned prefix_base; @@ -173,6 +175,7 @@ static CPU_RESET( i80286 ) CHANGE_PC(cpustate->pc); + cpustate->halted = 0; } /****************************************************************************/ @@ -181,6 +184,11 @@ static CPU_RESET( i80286 ) static void set_irq_line(i80286_state *cpustate, int irqline, int state) { + if (state != CLEAR_LINE && cpustate->halted) + { + cpustate->halted = 0; + } + if (irqline == INPUT_LINE_NMI) { if (cpustate->nmi_state == state) @@ -205,6 +213,9 @@ static CPU_EXECUTE( i80286 ) { i80286_state *cpustate = get_safe_token(device); + if (cpustate->halted) + return cycles; + /* copy over the cycle counts if they're not correct */ if (timing.id != 80286) timing = i80286_cycles; diff --git a/src/emu/cpu/i86/i86.c b/src/emu/cpu/i86/i86.c index 7fe23ebf1d8..55d36f6882b 100644 --- a/src/emu/cpu/i86/i86.c +++ b/src/emu/cpu/i86/i86.c @@ -48,10 +48,12 @@ struct _i8086_state UINT8 int_vector; INT8 nmi_state; INT8 irq_state; - INT8 test_state; /* PJB 03/05 */ + INT8 test_state; UINT8 rep_in_progress; INT32 extra_cycles; /* extra cycles for interrupts */ + int halted; /* Is the CPU halted ? */ + UINT16 ip; UINT32 sp; @@ -183,6 +185,7 @@ static void i8086_state_register(const device_config *device) state_save_register_device_item(device, 0, cpustate->nmi_state); state_save_register_device_item(device, 0, cpustate->irq_state); state_save_register_device_item(device, 0, cpustate->extra_cycles); + state_save_register_device_item(device, 0, cpustate->halted); state_save_register_device_item(device, 0, cpustate->test_state); /* PJB 03/05 */ state_save_register_device_item(device, 0, cpustate->rep_in_progress); /* PJB 03/05 */ } @@ -238,16 +241,16 @@ static CPU_RESET( i8086 ) { i8086_state *cpustate = get_safe_token(device); cpu_irq_callback save_irqcallback; - memory_interface save_mem; - cpu_state_table save_state; + memory_interface save_mem; + cpu_state_table save_state; save_irqcallback = cpustate->irq_callback; save_mem = cpustate->mem; - save_state = cpustate->state; + save_state = cpustate->state; memset(cpustate, 0, sizeof(*cpustate)); cpustate->irq_callback = save_irqcallback; cpustate->mem = save_mem; - cpustate->state = save_state; + cpustate->state = save_state; cpustate->device = device; cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM); cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO); @@ -256,6 +259,8 @@ static CPU_RESET( i8086 ) cpustate->base[CS] = SegBase(CS); cpustate->pc = 0xffff0 & AMASK; ExpandFlags(cpustate->flags); + + cpustate->halted = 0; } static CPU_EXIT( i8086 ) @@ -267,6 +272,11 @@ static CPU_EXIT( i8086 ) static void set_irq_line(i8086_state *cpustate, int irqline, int state) { + if (state != CLEAR_LINE && cpustate->halted) + { + cpustate->halted = 0; + } + if (irqline == INPUT_LINE_NMI) { if (cpustate->nmi_state == state) @@ -275,7 +285,9 @@ static void set_irq_line(i8086_state *cpustate, int irqline, int state) /* on a rising edge, signal the NMI */ if (state != CLEAR_LINE) + { PREFIX(_interrupt)(cpustate, I8086_NMI_INT_VECTOR); + } } else { @@ -290,13 +302,17 @@ static void set_irq_line(i8086_state *cpustate, int irqline, int state) /* PJB 03/05 */ static void set_test_line(i8086_state *cpustate, int state) { - cpustate->test_state = !state; + cpustate->test_state = !state; } static CPU_EXECUTE( i8086 ) { i8086_state *cpustate = get_safe_token(device); + + if (cpustate->halted) + return cycles; + /* copy over the cycle counts if they're not correct */ if (timing.id != 8086) timing = i8086_cycles; diff --git a/src/emu/cpu/i86/instr86.c b/src/emu/cpu/i86/instr86.c index bb4debe2def..7962c4b6326 100644 --- a/src/emu/cpu/i86/instr86.c +++ b/src/emu/cpu/i86/instr86.c @@ -2729,13 +2729,13 @@ static void PREFIX(_repne)(i8086_state *cpustate) /* Opcode 0xf2 */ static void PREFIX(_repe)(i8086_state *cpustate) /* Opcode 0xf3 */ { - PREFIX(rep)(cpustate, 1); + PREFIX(rep)(cpustate, 1); } #ifndef I80186 static void PREFIX86(_hlt)(i8086_state *cpustate) /* Opcode 0xf4 */ { - cpustate->pc--; + cpustate->halted=1; ICOUNT = 0; }