Ejemplo n.º 1
0
Archivo: nec.cpp Proyecto: RalfVB/mame
void nec_common_device::state_string_export(const device_state_entry &entry, std::string &str) const
{
	UINT16 flags = CompressFlags();

	switch (entry.index())
	{
		case STATE_GENFLAGS:
			str = string_format("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
				flags & 0x8000 ? 'N':'E',
				flags & 0x4000 ? '?':'.',
				flags & 0x2000 ? '?':'.',
				flags & 0x1000 ? '?':'.',
				flags & 0x0800 ? 'O':'.',
				flags & 0x0400 ? 'D':'.',
				flags & 0x0200 ? 'I':'.',
				flags & 0x0100 ? 'T':'.',
				flags & 0x0080 ? 'S':'.',
				flags & 0x0040 ? 'Z':'.',
				flags & 0x0020 ? '?':'.',
				flags & 0x0010 ? 'A':'.',
				flags & 0x0008 ? '?':'.',
				flags & 0x0004 ? 'P':'.',
				flags & 0x0002 ? '.':'?',
				flags & 0x0001 ? 'C':'.');
			break;
	}
}
Ejemplo n.º 2
0
static void i80286_load_flags(i8086_state *cpustate, UINT16 flags, int cpl)
{
	cpustate->flags = CompressFlags();
	if(PM && cpl) {
		UINT16 mask = 0x3000;
		if(cpl>IOPL) mask |= 0x200;
		flags &= ~mask;
		flags |= (cpustate->flags & mask);
	}
	else if(!PM) (flags &= ~0xf000);
	ExpandFlags(flags);
	cpustate->flags = flags;

	if (cpustate->TF) PREFIX(_trap)(cpustate);
	/* if the IF is set, and an interrupt is pending, signal an interrupt */
	if (cpustate->IF && cpustate->irq_state)
		i80286_interrupt_descriptor(cpustate, (*cpustate->irq_callback)(cpustate->device, 0), 2, -1);
}
Ejemplo n.º 3
0
void nec_common_device::state_export(const device_state_entry &entry)
{
	switch (entry.index())
	{
		case STATE_GENPC:
		case NEC_PC:
			m_debugger_temp = (Sreg(PS)<<4) + m_ip;
			break;

		case STATE_GENSP:
			m_debugger_temp = (Sreg(SS)<<4) + Wreg(SP);
			break;

		case NEC_FLAGS:
			m_debugger_temp = CompressFlags();
			break;
	}
}
Ejemplo n.º 4
0
static void PREFIX286(_0fpre)(i8086_state *cpustate)
{
	unsigned next = FETCHOP;
	UINT16 ModRM, desc[3];
	UINT16 tmp, msw, sel;
	UINT8 r;
	UINT32 addr;

	switch (next) {
	case 0:
		if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
		ModRM=FETCHOP;
		switch (ModRM&0x38) {
		case 0: /* sldt */
			PutRMWord(ModRM, cpustate->ldtr.sel);
			break;
		case 8: /* str */
			PutRMWord(ModRM, cpustate->tr.sel);
			break;
		case 0x10: /* lldt */
			if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0);
			sel=GetRMWord(ModRM);
			if (TBL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
			if (IDXTBL(sel)) {
				if (IDX(sel)>=cpustate->gdtr.limit) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
				addr = cpustate->gdtr.base + IDX(sel);
				desc[0] = ReadWord(addr);
				desc[1] = ReadWord(addr+2);
				desc[2] = ReadWord(addr+4);
				r = RIGHTS(desc);
				if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
				if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
			} else {
				desc[0] = 0;
				desc[1] = 0;
				desc[2] = 0;
			}
			cpustate->ldtr.sel=sel;
			cpustate->ldtr.limit=LIMIT(desc);
			cpustate->ldtr.base=BASE(desc);
			cpustate->ldtr.rights=RIGHTS(desc);
			break;
		case 0x18: /* ltr */
			if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0);
			sel=GetRMWord(ModRM);
			if ((addr = i80286_selector_address(cpustate,sel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
			desc[0] = ReadWord(addr);
			desc[1] = ReadWord(addr+2);
			desc[2] = ReadWord(addr+4);
			r = RIGHTS(desc);
			if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel));
			if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
			desc[2] |= 0x200; // mark busy
			WriteWord(addr+4, desc[2]);
			cpustate->tr.sel=sel;
			cpustate->tr.limit=LIMIT(desc);
			cpustate->tr.base=BASE(desc);
			cpustate->tr.rights=RIGHTS(desc);
			break;
		case 0x20: /* verr */
			tmp=GetRMWord(ModRM);
			if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
			else {
				desc[2] = ReadWord(addr+4);
				r = RIGHTS(desc);
				cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_READ, RIGHTS(desc), 0);
				cpustate->ZeroVal = cpustate->ZeroVal || (CODE(r) && CONF(r) ? 0 : (DPL(r)<PMAX(RPL(tmp),CPL)));
			}
			break;
		case 0x28: /* verw */
			tmp=GetRMWord(ModRM);
			if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
			else {
				desc[2] = ReadWord(addr+4);
				r = RIGHTS(desc);
				cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_WRITE, RIGHTS(desc), 0);
				cpustate->ZeroVal = cpustate->ZeroVal || (DPL(r)<PMAX(RPL(tmp),CPL));
			}
			break;
		default:
			throw TRAP(ILLEGAL_INSTRUCTION,-1);
			break;
		}
		break;
	case 1:
		/* lgdt, lldt in protected mode privilege level 0 required else common protection
           failure 0xd */
		ModRM = FETCHOP;
		switch (ModRM&0x38) {
		case 0: /* sgdt */
			PutRMWord(ModRM,cpustate->gdtr.limit);
			PutRMWordOffset(2,cpustate->gdtr.base&0xffff);
			PutRMWordOffset(4,0xff00|cpustate->gdtr.base>>16);
			break;
		case 8: /* sidt */
			PutRMWord(ModRM,cpustate->idtr.limit);
			PutRMWordOffset(2,cpustate->idtr.base&0xffff);
			PutRMWordOffset(4,0xff00|cpustate->idtr.base>>16);
			break;
		case 0x10: /* lgdt */
			if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
			cpustate->gdtr.limit=GetRMWord(ModRM);
			cpustate->gdtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16);
			break;
		case 0x18: /* lidt */
			if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
			cpustate->idtr.limit=GetRMWord(ModRM);
			cpustate->idtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16);
			break;
		case 0x20: /* smsw */
			PutRMWord(ModRM, cpustate->msw);
			break;
		case 0x30: /* lmsw */
			if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
			msw = GetRMWord(ModRM);
			if (!PM&&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0
			cpustate->msw=(cpustate->msw&1)|msw;
			break;
		default:
			throw TRAP(ILLEGAL_INSTRUCTION,-1);
			break;
		}
		break;
	case 2: /* LAR */
		if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
		ModRM = FETCHOP;
		tmp=GetRMWord(ModRM);
		if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
		else {
			desc[2] = ReadWord(addr+4);
			r = RIGHTS(desc);
			if (DPL(r)>=PMAX(RPL(tmp),CPL)) {
				cpustate->ZeroVal = 0;
				// rights are expected to be in upper byte
				RegWord(ModRM) = r << 8;
			}
			else
				cpustate->ZeroVal = 1;
		}
		break;
	case 3: /* LSL */
		if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1);
		ModRM = FETCHOP;
		tmp=GetRMWord(ModRM);
		if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1;
		else {
			desc[2] = ReadWord(addr+4);
			r = RIGHTS(desc);
			if (!SEGDESC(r) && (GATE(r) >= CALLGATE)) cpustate->ZeroVal = 1; // not valid for gates
			else if (DPL(r)>=PMAX(RPL(tmp),CPL)) {
				cpustate->ZeroVal = 0;
				RegWord(ModRM) = ReadWord(addr);
			}
			else
				cpustate->ZeroVal = 1;
		}
		break;
	case 5: /* loadall */
		if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
		cpustate->msw =        (cpustate->msw&1)|ReadWord(0x806);
		cpustate->tr.sel =     ReadWord(0x816);
		tmp =	               ReadWord(0x818);
		ExpandFlags(tmp);
		cpustate->flags = tmp;
		cpustate->flags = CompressFlags();
		cpustate->pc =         ReadWord(0x81a);
		cpustate->ldtr.sel =   ReadWord(0x81c);
		cpustate->sregs[DS] =  ReadWord(0x81e);
		cpustate->sregs[SS] =  ReadWord(0x820);
		cpustate->sregs[CS] =  ReadWord(0x822);
		cpustate->sregs[ES] =  ReadWord(0x824);
		cpustate->regs.w[DI] = ReadWord(0x826);
		cpustate->regs.w[SI] = ReadWord(0x828);
		cpustate->regs.w[BP] = ReadWord(0x82a);
		cpustate->regs.w[SP] = ReadWord(0x82c);
		cpustate->regs.w[BX] = ReadWord(0x82e);
		cpustate->regs.w[DX] = ReadWord(0x830);
		cpustate->regs.w[CX] = ReadWord(0x832);
		cpustate->regs.w[AX] = ReadWord(0x834);
// loadall uses base-rights-limit order
#define LOADDESC(addr, sreg) {  desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \
				cpustate->base[sreg] = BASE(desc); cpustate->rights[sreg] = RIGHTS(desc); \
				cpustate->limit[sreg] = LIMIT(desc); }
		LOADDESC(0x836, ES);
		LOADDESC(0x83C, CS);
		LOADDESC(0x842, SS);
		LOADDESC(0x848, DS);
#undef LOADDESC
// void cast supresses warning
#define LOADDESC(addr, reg, r) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \
				cpustate->reg.base = BASE(desc); (void)(r); cpustate->reg.limit = LIMIT(desc); }
		LOADDESC(0x84e, gdtr, 1);
		LOADDESC(0x854, ldtr, cpustate->ldtr.rights = RIGHTS(desc));
		LOADDESC(0x85a, idtr, 1);
		LOADDESC(0x860, tr,  cpustate->tr.rights = RIGHTS(desc));
#undef LOADDESC
		cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
		CHANGE_PC(cpustate->pc);
		break;

	case 6: /* clts */
		if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
		cpustate->msw&=~8;
		break;
	default:
		throw TRAP(ILLEGAL_INSTRUCTION,-1);
		break;
	}
}
Ejemplo n.º 5
0
static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
{
	UINT16 ndesc[3], desc[3], ntss[22], otss[22];
	UINT8 r, lr;
	UINT32 naddr, oaddr, ldtaddr;
	int i;
	logerror("This program uses TSSs, how rare. Please report this to the developers.\n");
	if (TBL(ntask)) throw TRAP(INVALID_TSS,IDXTBL(ntask));
	if ((naddr = i80286_selector_address(cpustate,ntask)) == -1) throw TRAP(INVALID_TSS,IDXTBL(ntask));
	oaddr = i80286_selector_address(cpustate,cpustate->tr.sel);
	ndesc[0] = ReadWord(naddr);
	ndesc[1] = ReadWord(naddr+2);
	ndesc[2] = ReadWord(naddr+4);
	desc[2] = ReadWord(oaddr+4);
	r = RIGHTS(ndesc);
	if (SEGDESC(r) || ((GATE(r) & ~2) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(ntask));
	if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(ntask));
	if (LIMIT(ndesc) < 43) throw TRAP(INVALID_TSS,IDXTBL(ntask));
	for (i = 0; i < 44; i+=2) ntss[i/2] = ReadWord(BASE(ndesc)+i);

	cpustate->flags = CompressFlags();
	if (type == CALL) WriteWord(BASE(ndesc)+TSS_BACK*2, cpustate->tr.sel);
	if (type == IRET) cpustate->flags &= ~0x4000;

	otss[TSS_IP] = cpustate->pc-cpustate->base[CS];
	otss[TSS_FLAG] = cpustate->flags;
	otss[TSS_AX] = cpustate->regs.w[AX];
	otss[TSS_CX] = cpustate->regs.w[CX];
	otss[TSS_DX] = cpustate->regs.w[DX];
	otss[TSS_BX] = cpustate->regs.w[BX];
	otss[TSS_SP] = cpustate->regs.w[SP];
	otss[TSS_BP] = cpustate->regs.w[BP];
	otss[TSS_SI] = cpustate->regs.w[SI];
	otss[TSS_DI] = cpustate->regs.w[DI];
	otss[TSS_ES] = cpustate->sregs[ES];
	otss[TSS_CS] = cpustate->sregs[CS];
	otss[TSS_SS] = cpustate->sregs[SS];
	otss[TSS_DS] = cpustate->sregs[DS];
	otss[TSS_LDT] = cpustate->ldtr.sel;

	for (i = 14; i < 44; i+=2) WriteWord(cpustate->tr.base+i, otss[i/2]);

	// jmp does both
	if (type != CALL) {
		desc[2] &= ~0x200; // mark idle
		WriteWord(oaddr+4, desc[2]);
	}
	if (type != IRET) {
		ndesc[2] |= 0x200;
		WriteWord(naddr+4, ndesc[2]);
	}
	cpustate->tr.sel=ntask;
	cpustate->tr.limit=LIMIT(ndesc);
	cpustate->tr.base=BASE(ndesc);
	cpustate->tr.rights=RIGHTS(ndesc);

	cpustate->flags      = ntss[TSS_FLAG];
	cpustate->regs.w[AX] = ntss[TSS_AX];
	cpustate->regs.w[CX] = ntss[TSS_CX];
	cpustate->regs.w[DX] = ntss[TSS_DX];
	cpustate->regs.w[BX] = ntss[TSS_BX];
	cpustate->regs.w[SP] = ntss[TSS_SP];
	cpustate->regs.w[BP] = ntss[TSS_BP];
	cpustate->regs.w[SI] = ntss[TSS_SI];
	cpustate->regs.w[DI] = ntss[TSS_DI];

	if (TBL(ntss[TSS_LDT])) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
	if (IDXTBL(ntss[TSS_LDT])) {
		if ((ldtaddr = i80286_selector_address(cpustate,ntss[TSS_LDT])) == -1)
			throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
		desc[0] = ReadWord(ldtaddr);
		desc[1] = ReadWord(ldtaddr+2);
		desc[2] = ReadWord(ldtaddr+4);
		lr = RIGHTS(desc);
		if (SEGDESC(lr) || (GATE(lr) != LDTDESC)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
		if (!PRES(lr)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
		cpustate->ldtr.sel=ntss[TSS_LDT];
		cpustate->ldtr.limit=LIMIT(desc);
		cpustate->ldtr.base=BASE(desc);
		cpustate->ldtr.rights=RIGHTS(desc);
	} else {
		cpustate->ldtr.sel=0;
		cpustate->ldtr.limit=0;
		cpustate->ldtr.base=0;
		cpustate->ldtr.rights=0;
	}

	if (type == CALL) cpustate->flags |= 0x4000;
	cpustate->msw |= 8;
	i80286_data_descriptor_full(cpustate, SS, ntss[TSS_SS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_SS])), 0, 0);

	cpustate->sregs[CS] = IDXTBL(cpustate->sregs[CS]) | RPL(ntss[TSS_CS]);  // fixme
	try {
		i80286_code_descriptor(cpustate, ntss[TSS_CS], ntss[TSS_IP], 0);
	} catch(UINT32 e) {
		int error_code = e & 0xffff;
		if(error_code == GENERAL_PROTECTION_FAULT) e = TRAP(INVALID_TSS,(e >> 16)); // #NP fault is correct
		throw e;
	}

	i80286_data_descriptor_full(cpustate, ES, ntss[TSS_ES], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_ES])), 0, 0);
	i80286_data_descriptor_full(cpustate, DS, ntss[TSS_DS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_DS])), 0, 0);
}
Ejemplo n.º 6
0
Archivo: nec.c Proyecto: opicron/mame
static CPU_GET_INFO( nec )
{
	nec_state_t *nec_state = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
	int flags;

	switch (state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(nec_state_t);                  break;
		case CPUINFO_INT_INPUT_LINES:                   info->i = 1;                            break;
		case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0xff;                         break;
		case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;                    break;
		case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
		case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
		case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                            break;
		case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 8;                            break;
		case CPUINFO_INT_MIN_CYCLES:                    info->i = 1;                            break;
		case CPUINFO_INT_MAX_CYCLES:                    info->i = 80;                           break;

		case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 16;                   break;
		case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:    info->i = 20;                   break;
		case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:    info->i = 0;                    break;
		case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                    break;
		case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                    break;
		case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                    break;
		case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 16;                   break;
		case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 16;                   break;
		case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                    break;

		case CPUINFO_INT_INPUT_STATE + 0:                   info->i = (nec_state->pending_irq & INT_IRQ) ? ASSERT_LINE : CLEAR_LINE; break;
		case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:      info->i = nec_state->nmi_state;             break;
		case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL: info->i = nec_state->poll_state;                break;

		case CPUINFO_INT_PREVIOUSPC:                    /* not supported */                     break;

		case CPUINFO_INT_PC:
		case CPUINFO_INT_REGISTER + NEC_PC:             info->i = ((Sreg(PS)<<4) + nec_state->ip);  break;
		case CPUINFO_INT_REGISTER + NEC_IP:             info->i = nec_state->ip;                            break;
		case CPUINFO_INT_SP:                            info->i = (Sreg(SS)<<4) + Wreg(SP); break;
		case CPUINFO_INT_REGISTER + NEC_SP:             info->i = Wreg(SP);                 break;
		case CPUINFO_INT_REGISTER + NEC_FLAGS:          info->i = CompressFlags();              break;
		case CPUINFO_INT_REGISTER + NEC_AW:             info->i = Wreg(AW);                 break;
		case CPUINFO_INT_REGISTER + NEC_CW:             info->i = Wreg(CW);                 break;
		case CPUINFO_INT_REGISTER + NEC_DW:             info->i = Wreg(DW);                 break;
		case CPUINFO_INT_REGISTER + NEC_BW:             info->i = Wreg(BW);                 break;
		case CPUINFO_INT_REGISTER + NEC_BP:             info->i = Wreg(BP);                 break;
		case CPUINFO_INT_REGISTER + NEC_IX:             info->i = Wreg(IX);                 break;
		case CPUINFO_INT_REGISTER + NEC_IY:             info->i = Wreg(IY);                 break;
		case CPUINFO_INT_REGISTER + NEC_ES:             info->i = Sreg(DS1);                    break;
		case CPUINFO_INT_REGISTER + NEC_CS:             info->i = Sreg(PS);                 break;
		case CPUINFO_INT_REGISTER + NEC_SS:             info->i = Sreg(SS);                 break;
		case CPUINFO_INT_REGISTER + NEC_DS:             info->i = Sreg(DS0);                    break;
		case CPUINFO_INT_REGISTER + NEC_PENDING:        info->i = nec_state->pending_irq;               break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(nec);         break;
		case CPUINFO_FCT_INIT:                          /* set per-CPU */                       break;
		case CPUINFO_FCT_RESET:                         info->reset = CPU_RESET_NAME(nec);              break;
		case CPUINFO_FCT_EXIT:                          info->exit = CPU_EXIT_NAME(nec);                    break;
		case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(necv);         break;
		case CPUINFO_FCT_BURN:                          info->burn = NULL;                      break;
		case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(nec);          break;
		case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &nec_state->icount;              break;

		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case CPUINFO_STR_NAME:                          strcpy(info->s, "NEC");                 break;
		case CPUINFO_STR_FAMILY:                    strcpy(info->s, "NEC V-Series");        break;
		case CPUINFO_STR_VERSION:                   strcpy(info->s, "2.0");                 break;
		case CPUINFO_STR_SOURCE_FILE:                       strcpy(info->s, __FILE__);              break;
		case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Bryan McPhail (V25/V35 support added by Alex W. Jackson)"); break;

		case CPUINFO_STR_FLAGS:
			flags = CompressFlags();
			sprintf(info->s, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
				flags & 0x8000 ? 'N':'E',
				flags & 0x4000 ? '?':'.',
				flags & 0x2000 ? '?':'.',
				flags & 0x1000 ? '?':'.',
				flags & 0x0800 ? 'O':'.',
				flags & 0x0400 ? 'D':'.',
				flags & 0x0200 ? 'I':'.',
				flags & 0x0100 ? 'T':'.',
				flags & 0x0080 ? 'S':'.',
				flags & 0x0040 ? 'Z':'.',
				flags & 0x0020 ? '?':'.',
				flags & 0x0010 ? 'A':'.',
				flags & 0x0008 ? '?':'.',
				flags & 0x0004 ? 'P':'.',
				flags & 0x0002 ? '.':'?',
				flags & 0x0001 ? 'C':'.');
			break;

		case CPUINFO_STR_REGISTER + NEC_PC:             sprintf(info->s, "PC:%05X", (Sreg(PS)<<4) + nec_state->ip); break;
		case CPUINFO_STR_REGISTER + NEC_IP:             sprintf(info->s, "IP:%04X", nec_state->ip); break;
		case CPUINFO_STR_REGISTER + NEC_SP:             sprintf(info->s, "SP:%04X", Wreg(SP)); break;
		case CPUINFO_STR_REGISTER + NEC_FLAGS:          sprintf(info->s, "F:%04X", CompressFlags()); break;
		case CPUINFO_STR_REGISTER + NEC_AW:             sprintf(info->s, "AW:%04X", Wreg(AW)); break;
		case CPUINFO_STR_REGISTER + NEC_CW:             sprintf(info->s, "CW:%04X", Wreg(CW)); break;
		case CPUINFO_STR_REGISTER + NEC_DW:             sprintf(info->s, "DW:%04X", Wreg(DW)); break;
		case CPUINFO_STR_REGISTER + NEC_BW:             sprintf(info->s, "BW:%04X", Wreg(BW)); break;
		case CPUINFO_STR_REGISTER + NEC_BP:             sprintf(info->s, "BP:%04X", Wreg(BP)); break;
		case CPUINFO_STR_REGISTER + NEC_IX:             sprintf(info->s, "IX:%04X", Wreg(IX)); break;
		case CPUINFO_STR_REGISTER + NEC_IY:             sprintf(info->s, "IY:%04X", Wreg(IY)); break;
		case CPUINFO_STR_REGISTER + NEC_ES:             sprintf(info->s, "DS1:%04X", Sreg(DS1)); break;
		case CPUINFO_STR_REGISTER + NEC_CS:             sprintf(info->s, "PS:%04X", Sreg(PS)); break;
		case CPUINFO_STR_REGISTER + NEC_SS:             sprintf(info->s, "SS:%04X", Sreg(SS)); break;
		case CPUINFO_STR_REGISTER + NEC_DS:             sprintf(info->s, "DS0:%04X", Sreg(DS0)); break;
	}
}