Implemented halt instruction in the NEC CPU core [Wilbert Pol, Alex Jackson]

This commit is contained in:
Alex W. Jackson 2011-07-10 07:03:32 +00:00
parent 17a94a70ce
commit e1edbacccc
6 changed files with 69 additions and 8 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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;