summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2010-12-23 02:46:39 +0000
committer Angelo Salese <angelosa@users.noreply.github.com>2010-12-23 02:46:39 +0000
commite8cfb9e5133e9185b5c7c44ecf80d2d85b6a29ff (patch)
tree4c2a540435b2f8c2d82975e41393ae878bbbec5e /src
parent855636d33ce6bb57583679c572d0eb7fb28ecd77 (diff)
Implemented a preliminary V25/V35 CPU core [Alex Jackson]
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/cpu.mak17
-rw-r--r--src/emu/cpu/nec/nec.c908
-rw-r--r--src/emu/cpu/nec/nec.h58
-rw-r--r--src/emu/cpu/nec/necea.h46
-rw-r--r--src/emu/cpu/nec/necinstr.c672
-rw-r--r--src/emu/cpu/nec/necinstr.h3
-rw-r--r--src/emu/cpu/nec/necmodrm.h24
-rw-r--r--src/emu/cpu/nec/necpriv.h172
-rw-r--r--src/emu/cpu/nec/v25.c622
-rw-r--r--src/emu/cpu/nec/v25instr.c34
-rw-r--r--src/emu/cpu/nec/v25instr.h510
-rw-r--r--src/emu/cpu/nec/v25priv.h455
-rw-r--r--src/emu/cpu/nec/v25sfr.c137
-rw-r--r--src/mame/drivers/cb2001.c2
-rw-r--r--src/mame/drivers/m107.c2
-rw-r--r--src/mame/drivers/m72.c2
-rw-r--r--src/mame/drivers/m90.c46
-rw-r--r--src/mame/drivers/m92.c34
-rw-r--r--src/mame/drivers/segas32.c13
-rw-r--r--src/mame/includes/segas32.h1
-rw-r--r--src/mame/machine/segas32.c27
21 files changed, 2715 insertions, 1070 deletions
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak
index ef0d4e67133..a17c77b990a 100644
--- a/src/emu/cpu/cpu.mak
+++ b/src/emu/cpu/cpu.mak
@@ -1147,6 +1147,8 @@ $(CPUOBJ)/powerpc/ppcdrc.o: $(CPUSRC)/powerpc/ppcdrc.c \
ifneq ($(filter NEC,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/nec
CPUOBJS += $(CPUOBJ)/nec/nec.o
+CPUOBJS += $(CPUOBJ)/nec/v25.o
+CPUOBJS += $(CPUOBJ)/nec/v25sfr.o
DASMOBJS += $(CPUOBJ)/nec/necdasm.o
endif
@@ -1159,11 +1161,24 @@ endif
$(CPUOBJ)/nec/nec.o: $(CPUSRC)/nec/nec.c \
$(CPUSRC)/nec/nec.h \
$(CPUSRC)/nec/necea.h \
- $(CPUSRC)/nec/nechost.h \
+ $(CPUSRC)/nec/necinstr.c \
$(CPUSRC)/nec/necinstr.h \
$(CPUSRC)/nec/necmodrm.h \
$(CPUSRC)/nec/necpriv.h
+$(CPUOBJ)/nec/v25.o: $(CPUSRC)/nec/v25.c \
+ $(CPUSRC)/nec/nec.h \
+ $(CPUSRC)/nec/necea.h \
+ $(CPUSRC)/nec/necinstr.c \
+ $(CPUSRC)/nec/v25instr.c \
+ $(CPUSRC)/nec/v25instr.h \
+ $(CPUSRC)/nec/necmodrm.h \
+ $(CPUSRC)/nec/v25priv.h
+
+$(CPUOBJ)/nec/v25sfr.o: $(CPUSRC)/nec/v25sfr.c \
+ $(CPUSRC)/nec/nec.h \
+ $(CPUSRC)/nec/v25priv.h
+
$(CPUOBJ)/v30mz/v30mz.o: $(CPUSRC)/v30mz/v30mz.c \
$(CPUSRC)/v30mz/v30mz.h \
$(CPUSRC)/v30mz/necmodrm.h \
diff --git a/src/emu/cpu/nec/nec.c b/src/emu/cpu/nec/nec.c
index 15590d9ed03..3b69dc72de8 100644
--- a/src/emu/cpu/nec/nec.c
+++ b/src/emu/cpu/nec/nec.c
@@ -111,73 +111,19 @@ typedef UINT8 BYTE;
typedef UINT16 WORD;
typedef UINT32 DWORD;
-#include "necpriv.h"
#include "nec.h"
+#include "necpriv.h"
-#define PC(n) (((n)->sregs[PS]<<4)+(n)->ip)
-
-/* default configuration */
-static const nec_config default_config =
-{
- NULL
-};
+#define PC(n) ((Sreg(PS)<<4)+(n)->ip)
extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, const nec_config *config);
-/* NEC registers */
-typedef union
-{ /* eight general registers */
- UINT16 w[8]; /* viewed as 16 bits registers */
- UINT8 b[16]; /* or as 8 bit registers */
-} necbasicregs;
-
-typedef struct _nec_state_t nec_state_t;
-struct _nec_state_t
-{
- necbasicregs regs;
- offs_t fetch_xor;
- UINT16 sregs[4];
-
- UINT16 ip;
-
- INT32 SignVal;
- UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
- UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
- UINT32 int_vector;
- UINT32 pending_irq;
- UINT32 nmi_state;
- UINT32 irq_state;
- UINT32 poll_state;
- UINT8 no_interrupt;
-
- device_irq_callback irq_callback;
- legacy_cpu_device *device;
- address_space *program;
- direct_read_data *direct;
- address_space *io;
- int icount;
-
- const nec_config *config;
-
- UINT8 prefetch_size;
- UINT8 prefetch_cycles;
- INT8 prefetch_count;
- UINT8 prefetch_reset;
- UINT32 chip_type;
-
- UINT32 prefix_base; /* base address of the latest prefix segment */
- UINT8 seg_prefix; /* prefix segment indicator */
-
-};
-
INLINE nec_state_t *get_safe_token(running_device *device)
{
assert(device != NULL);
assert(device->type() == V20 ||
- device->type() == V25 ||
device->type() == V30 ||
- device->type() == V33 ||
- device->type() == V35);
+ device->type() == V33);
return (nec_state_t *)downcast<legacy_cpu_device *>(device)->token();
}
@@ -199,7 +145,7 @@ static void do_prefetch(nec_state_t *nec_state, int previous_ICount)
/* The implementation is not accurate, but comes close.
* It does not respect that the V30 will fetch two bytes
* at once directly, but instead uses only 2 cycles instead
- * of 4. There are however only very few sources publicy
+ * of 4. There are however only very few sources publicly
* available and they are vague.
*/
while (nec_state->prefetch_count<0)
@@ -229,7 +175,7 @@ static void do_prefetch(nec_state_t *nec_state, int previous_ICount)
INLINE UINT8 fetch(nec_state_t *nec_state)
{
prefetch(nec_state);
- return nec_state->direct->read_raw_byte(FETCH_XOR((nec_state->sregs[PS]<<4)+nec_state->ip++));
+ return nec_state->direct->read_raw_byte(FETCH_XOR((Sreg(PS)<<4)+nec_state->ip++));
}
INLINE UINT16 fetchword(nec_state_t *nec_state)
@@ -245,21 +191,10 @@ INLINE UINT16 fetchword(nec_state_t *nec_state)
static UINT8 parity_table[256];
-#include "emu.h"
-
static UINT8 fetchop(nec_state_t *nec_state)
{
- UINT8 ret;
-
prefetch(nec_state);
- ret = nec_state->direct->read_decrypted_byte(FETCH_XOR( ( nec_state->sregs[PS]<<4)+nec_state->ip++));
-
- if (nec_state->MF == 1)
- if (nec_state->config->v25v35_decryptiontable)
- {
- ret = nec_state->config->v25v35_decryptiontable[ret];
- }
- return ret;
+ return nec_state->direct->read_decrypted_byte(FETCH_XOR( ( Sreg(PS)<<4)+nec_state->ip++));
}
@@ -279,7 +214,7 @@ static CPU_RESET( nec )
nec_state->TF = 0;
nec_state->IF = 0;
nec_state->DF = 0;
- nec_state->MF = 0;
+ nec_state->MF = 1;
nec_state->SignVal = 0;
nec_state->int_vector = 0;
nec_state->pending_irq = 0;
@@ -293,7 +228,7 @@ static CPU_RESET( nec )
nec_state->ParityVal = 0;
- nec_state->sregs[PS] = 0xffff;
+ Sreg(PS) = 0xffff;
CHANGE_PC;
@@ -305,10 +240,6 @@ static CPU_RESET( nec )
}
nec_state->ZeroVal = nec_state->ParityVal = 1;
- SetMD(1); /* set the mode-flag = native mode */
-
- /* for v25+ / v35+ there is an internal decryption table */
- //nec_state->config->v25v35_decryptiontable = gussun_test_decryption_table;
for (i = 0; i < 256; i++)
{
@@ -330,13 +261,12 @@ static CPU_EXIT( nec )
}
-static void nec_interrupt(nec_state_t *nec_state, unsigned int_num,BOOLEAN md_flag)
+static void nec_interrupt(nec_state_t *nec_state, unsigned int_num, ATTR_UNUSED unsigned mode)
{
UINT32 dest_seg, dest_off;
i_pushf(nec_state);
nec_state->TF = nec_state->IF = 0;
- if (md_flag) SetMD(0); /* clear Mode-flag = start 8080 emulation mode */
if (int_num == -1)
{
@@ -349,10 +279,10 @@ static void nec_interrupt(nec_state_t *nec_state, unsigned int_num,BOOLEAN md_fl
dest_off = read_mem_word(int_num*4);
dest_seg = read_mem_word(int_num*4+2);
- PUSH(nec_state->sregs[PS]);
+ PUSH(Sreg(PS));
PUSH(nec_state->ip);
nec_state->ip = (WORD)dest_off;
- nec_state->sregs[PS] = (WORD)dest_seg;
+ Sreg(PS) = (WORD)dest_seg;
CHANGE_PC;
}
@@ -381,671 +311,7 @@ static void external_int(nec_state_t *nec_state)
/* OPCODES */
/****************************************************************************/
-#define OP(num,func_name) static void func_name(nec_state_t *nec_state)
-
-OP( 0x00, i_add_br8 ) { DEF_br8; ADDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x01, i_add_wr16 ) { DEF_wr16; ADDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x02, i_add_r8b ) { DEF_r8b; ADDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x03, i_add_r16w ) { DEF_r16w; ADDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x04, i_add_ald8 ) { DEF_ald8; ADDB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x05, i_add_axd16) { DEF_axd16; ADDW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x06, i_push_es ) { PUSH(nec_state->sregs[DS1]); CLKS(12,8,3); }
-OP( 0x07, i_pop_es ) { POP(nec_state->sregs[DS1]); CLKS(12,8,5); }
-
-OP( 0x08, i_or_br8 ) { DEF_br8; ORB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x09, i_or_wr16 ) { DEF_wr16; ORW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x0a, i_or_r8b ) { DEF_r8b; ORB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x0b, i_or_r16w ) { DEF_r16w; ORW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x0e, i_push_cs ) { PUSH(nec_state->sregs[PS]); CLKS(12,8,3); }
-OP( 0x0f, i_pre_nec ) { UINT32 ModRM, tmp, tmp2;
- switch (FETCH()) {
- case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = nec_state->regs.b[CL] & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
- case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = nec_state->regs.b[CL] & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
- case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = nec_state->regs.b[CL] & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
- case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = nec_state->regs.b[CL] & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
- case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = nec_state->regs.b[CL] & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
- case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = nec_state->regs.b[CL] & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
- case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = nec_state->regs.b[CL] & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
- case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = nec_state->regs.b[CL] & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
-
- case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
- case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
- case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
- case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
- case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
- case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
- case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
- case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
-
- case 0x20 : ADD4S; CLKS(7,7,2); break;
- case 0x22 : SUB4S; CLKS(7,7,2); break;
- case 0x26 : CMP4S; CLKS(7,7,2); break;
- case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= nec_state->regs.b[AL] & 0xf; nec_state->regs.b[AL] = (nec_state->regs.b[AL] & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
- case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (nec_state->regs.b[AL] & 0xf)<<4; nec_state->regs.b[AL] = (nec_state->regs.b[AL] & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
- case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC(nec_state)); break;
- case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC(nec_state)); break;
- case 0x92 : CLK(2); break; /* V25/35 FINT */
- case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC(nec_state)); break;
- case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC(nec_state)); break;
- case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC(nec_state)); break;
- default: logerror("%06x: Unknown V20 instruction\n",PC(nec_state)); break;
- }
-}
-
-OP( 0x10, i_adc_br8 ) { DEF_br8; src+=CF; ADDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x11, i_adc_wr16 ) { DEF_wr16; src+=CF; ADDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x12, i_adc_r8b ) { DEF_r8b; src+=CF; ADDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x13, i_adc_r16w ) { DEF_r16w; src+=CF; ADDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x14, i_adc_ald8 ) { DEF_ald8; src+=CF; ADDB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF; ADDW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x16, i_push_ss ) { PUSH(nec_state->sregs[SS]); CLKS(12,8,3); }
-OP( 0x17, i_pop_ss ) { POP(nec_state->sregs[SS]); CLKS(12,8,5); nec_state->no_interrupt=1; }
-
-OP( 0x18, i_sbb_br8 ) { DEF_br8; src+=CF; SUBB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x19, i_sbb_wr16 ) { DEF_wr16; src+=CF; SUBW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x1a, i_sbb_r8b ) { DEF_r8b; src+=CF; SUBB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x1b, i_sbb_r16w ) { DEF_r16w; src+=CF; SUBW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x1c, i_sbb_ald8 ) { DEF_ald8; src+=CF; SUBB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF; SUBW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x1e, i_push_ds ) { PUSH(nec_state->sregs[DS0]); CLKS(12,8,3); }
-OP( 0x1f, i_pop_ds ) { POP(nec_state->sregs[DS0]); CLKS(12,8,5); }
-
-OP( 0x20, i_and_br8 ) { DEF_br8; ANDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x21, i_and_wr16 ) { DEF_wr16; ANDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x22, i_and_r8b ) { DEF_r8b; ANDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x23, i_and_r16w ) { DEF_r16w; ANDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x24, i_and_ald8 ) { DEF_ald8; ANDB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x25, i_and_axd16) { DEF_axd16; ANDW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x26, i_es ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS1]<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
-OP( 0x27, i_daa ) { ADJ4(6,0x60); CLKS(3,3,2); }
-
-OP( 0x28, i_sub_br8 ) { DEF_br8; SUBB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x29, i_sub_wr16 ) { DEF_wr16; SUBW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x2a, i_sub_r8b ) { DEF_r8b; SUBB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x2b, i_sub_r16w ) { DEF_r16w; SUBW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x2c, i_sub_ald8 ) { DEF_ald8; SUBB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x2e, i_cs ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[PS]<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
-OP( 0x2f, i_das ) { ADJ4(-6,-0x60); CLKS(3,3,2); }
-
-OP( 0x30, i_xor_br8 ) { DEF_br8; XORB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
-OP( 0x31, i_xor_wr16 ) { DEF_wr16; XORW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
-OP( 0x32, i_xor_r8b ) { DEF_r8b; XORB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
-OP( 0x33, i_xor_r16w ) { DEF_r16w; XORW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x34, i_xor_ald8 ) { DEF_ald8; XORB; nec_state->regs.b[AL]=dst; CLKS(4,4,2); }
-OP( 0x35, i_xor_axd16) { DEF_axd16; XORW; nec_state->regs.w[AW]=dst; CLKS(4,4,2); }
-OP( 0x36, i_ss ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[SS]<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
-OP( 0x37, i_aaa ) { ADJB(6, (nec_state->regs.b[AL] > 0xf9) ? 2 : 1); CLKS(7,7,4); }
-
-OP( 0x38, i_cmp_br8 ) { DEF_br8; SUBB; CLKM(2,2,2,11,11,6); }
-OP( 0x39, i_cmp_wr16 ) { DEF_wr16; SUBW; CLKR(15,15,8,15,11,6,2,EA);}
-OP( 0x3a, i_cmp_r8b ) { DEF_r8b; SUBB; CLKM(2,2,2,11,11,6); }
-OP( 0x3b, i_cmp_r16w ) { DEF_r16w; SUBW; CLKR(15,15,8,15,11,6,2,EA); }
-OP( 0x3c, i_cmp_ald8 ) { DEF_ald8; SUBB; CLKS(4,4,2); }
-OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW; CLKS(4,4,2); }
-OP( 0x3e, i_ds ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS0]<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
-OP( 0x3f, i_aas ) { ADJB(-6, (nec_state->regs.b[AL] < 6) ? -2 : -1); CLKS(7,7,4); }
-
-OP( 0x40, i_inc_ax ) { IncWordReg(AW); CLK(2); }
-OP( 0x41, i_inc_cx ) { IncWordReg(CW); CLK(2); }
-OP( 0x42, i_inc_dx ) { IncWordReg(DW); CLK(2); }
-OP( 0x43, i_inc_bx ) { IncWordReg(BW); CLK(2); }
-OP( 0x44, i_inc_sp ) { IncWordReg(SP); CLK(2); }
-OP( 0x45, i_inc_bp ) { IncWordReg(BP); CLK(2); }
-OP( 0x46, i_inc_si ) { IncWordReg(IX); CLK(2); }
-OP( 0x47, i_inc_di ) { IncWordReg(IY); CLK(2); }
-
-OP( 0x48, i_dec_ax ) { DecWordReg(AW); CLK(2); }
-OP( 0x49, i_dec_cx ) { DecWordReg(CW); CLK(2); }
-OP( 0x4a, i_dec_dx ) { DecWordReg(DW); CLK(2); }
-OP( 0x4b, i_dec_bx ) { DecWordReg(BW); CLK(2); }
-OP( 0x4c, i_dec_sp ) { DecWordReg(SP); CLK(2); }
-OP( 0x4d, i_dec_bp ) { DecWordReg(BP); CLK(2); }
-OP( 0x4e, i_dec_si ) { DecWordReg(IX); CLK(2); }
-OP( 0x4f, i_dec_di ) { DecWordReg(IY); CLK(2); }
-
-OP( 0x50, i_push_ax ) { PUSH(nec_state->regs.w[AW]); CLKS(12,8,3); }
-OP( 0x51, i_push_cx ) { PUSH(nec_state->regs.w[CW]); CLKS(12,8,3); }
-OP( 0x52, i_push_dx ) { PUSH(nec_state->regs.w[DW]); CLKS(12,8,3); }
-OP( 0x53, i_push_bx ) { PUSH(nec_state->regs.w[BW]); CLKS(12,8,3); }
-OP( 0x54, i_push_sp ) { PUSH(nec_state->regs.w[SP]); CLKS(12,8,3); }
-OP( 0x55, i_push_bp ) { PUSH(nec_state->regs.w[BP]); CLKS(12,8,3); }
-OP( 0x56, i_push_si ) { PUSH(nec_state->regs.w[IX]); CLKS(12,8,3); }
-OP( 0x57, i_push_di ) { PUSH(nec_state->regs.w[IY]); CLKS(12,8,3); }
-
-OP( 0x58, i_pop_ax ) { POP(nec_state->regs.w[AW]); CLKS(12,8,5); }
-OP( 0x59, i_pop_cx ) { POP(nec_state->regs.w[CW]); CLKS(12,8,5); }
-OP( 0x5a, i_pop_dx ) { POP(nec_state->regs.w[DW]); CLKS(12,8,5); }
-OP( 0x5b, i_pop_bx ) { POP(nec_state->regs.w[BW]); CLKS(12,8,5); }
-OP( 0x5c, i_pop_sp ) { POP(nec_state->regs.w[SP]); CLKS(12,8,5); }
-OP( 0x5d, i_pop_bp ) { POP(nec_state->regs.w[BP]); CLKS(12,8,5); }
-OP( 0x5e, i_pop_si ) { POP(nec_state->regs.w[IX]); CLKS(12,8,5); }
-OP( 0x5f, i_pop_di ) { POP(nec_state->regs.w[IY]); CLKS(12,8,5); }
-
-OP( 0x60, i_pusha ) {
- unsigned tmp=nec_state->regs.w[SP];
- PUSH(nec_state->regs.w[AW]);
- PUSH(nec_state->regs.w[CW]);
- PUSH(nec_state->regs.w[DW]);
- PUSH(nec_state->regs.w[BW]);
- PUSH(tmp);
- PUSH(nec_state->regs.w[BP]);
- PUSH(nec_state->regs.w[IX]);
- PUSH(nec_state->regs.w[IY]);
- CLKS(67,35,20);
-}
-OP( 0x61, i_popa ) {
- unsigned tmp;
- POP(nec_state->regs.w[IY]);
- POP(nec_state->regs.w[IX]);
- POP(nec_state->regs.w[BP]);
- POP(tmp);
- POP(nec_state->regs.w[BW]);
- POP(nec_state->regs.w[DW]);
- POP(nec_state->regs.w[CW]);
- POP(nec_state->regs.w[AW]);
- CLKS(75,43,22);
-}
-OP( 0x62, i_chkind ) {
- UINT32 low,high,tmp;
- GetModRM;
- low = GetRMWord(ModRM);
- high= GetnextRMWord;
- tmp= RegWord(ModRM);
- if (tmp<low || tmp>high) {
- nec_interrupt(nec_state, 5,0);
- }
- nec_state->icount-=20;
- logerror("%06x: bound %04x high %04x low %04x tmp\n",PC(nec_state),high,low,tmp);
-}
-OP( 0x63, i_brkn ) { nec_interrupt(nec_state, FETCH(),1); CLKS(50,50,24); } // timing not verified, used by riskchal / gussun
-OP( 0x64, i_repnc ) { UINT32 next = fetchop(nec_state); UINT16 c = nec_state->regs.w[CW];
- switch(next) { /* Segments */
- case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS1]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[PS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[SS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS0]<<4; next = fetchop(nec_state); CLK(2); break;
- }
-
- switch(next) {
- case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && !CF); nec_state->regs.w[CW]=c; break;
- default: logerror("%06x: REPNC invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
- }
- nec_state->seg_prefix=FALSE;
-}
-
-OP( 0x65, i_repc ) { UINT32 next = fetchop(nec_state); UINT16 c = nec_state->regs.w[CW];
- switch(next) { /* Segments */
- case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS1]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[PS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[SS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS0]<<4; next = fetchop(nec_state); CLK(2); break;
- }
-
- switch(next) {
- case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && CF); nec_state->regs.w[CW]=c; break;
- default: logerror("%06x: REPC invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
- }
- nec_state->seg_prefix=FALSE;
-}
-
-OP( 0x68, i_push_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(tmp); CLKW(12,12,5,12,8,5,nec_state->regs.w[SP]); }
-OP( 0x69, i_imul_d16 ) { UINT32 tmp; DEF_r16w; tmp = FETCHWORD(); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); nec_state->CarryVal = nec_state->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; nec_state->icount-=(ModRM >=0xc0 )?38:47;}
-OP( 0x6a, i_push_d8 ) { UINT32 tmp = (WORD)((INT16)((INT8)FETCH())); PUSH(tmp); CLKW(11,11,5,11,7,3,nec_state->regs.w[SP]); }
-OP( 0x6b, i_imul_d8 ) { UINT32 src2; DEF_r16w; src2= (WORD)((INT16)((INT8)FETCH())); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); nec_state->CarryVal = nec_state->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; nec_state->icount-=(ModRM >=0xc0 )?31:39; }
-OP( 0x6c, i_insb ) { PutMemB(DS1,nec_state->regs.w[IY],read_port_byte(nec_state->regs.w[DW])); nec_state->regs.w[IY]+= -2 * nec_state->DF + 1; CLK(8); }
-OP( 0x6d, i_insw ) { PutMemW(DS1,nec_state->regs.w[IY],read_port_word(nec_state->regs.w[DW])); nec_state->regs.w[IY]+= -4 * nec_state->DF + 2; CLKS(18,10,8); }
-OP( 0x6e, i_outsb ) { write_port_byte(nec_state->regs.w[DW],GetMemB(DS0,nec_state->regs.w[IX])); nec_state->regs.w[IX]+= -2 * nec_state->DF + 1; CLK(8); }
-OP( 0x6f, i_outsw ) { write_port_word(nec_state->regs.w[DW],GetMemW(DS0,nec_state->regs.w[IX])); nec_state->regs.w[IX]+= -4 * nec_state->DF + 2; CLKS(18,10,8); }
-
-OP( 0x70, i_jo ) { JMP( OF); CLKS(4,4,3); }
-OP( 0x71, i_jno ) { JMP(!OF); CLKS(4,4,3); }
-OP( 0x72, i_jc ) { JMP( CF); CLKS(4,4,3); }
-OP( 0x73, i_jnc ) { JMP(!CF); CLKS(4,4,3); }
-OP( 0x74, i_jz ) { JMP( ZF); CLKS(4,4,3); }
-OP( 0x75, i_jnz ) { JMP(!ZF); CLKS(4,4,3); }
-OP( 0x76, i_jce ) { JMP(CF || ZF); CLKS(4,4,3); }
-OP( 0x77, i_jnce ) { JMP(!(CF || ZF)); CLKS(4,4,3); }
-OP( 0x78, i_js ) { JMP( SF); CLKS(4,4,3); }
-OP( 0x79, i_jns ) { JMP(!SF); CLKS(4,4,3); }
-OP( 0x7a, i_jp ) { JMP( PF); CLKS(4,4,3); }
-OP( 0x7b, i_jnp ) { JMP(!PF); CLKS(4,4,3); }
-OP( 0x7c, i_jl ) { JMP((SF!=OF)&&(!ZF)); CLKS(4,4,3); }
-OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); CLKS(4,4,3); }
-OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); CLKS(4,4,3); }
-OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); CLKS(4,4,3); }
-
-OP( 0x80, i_80pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH();
- if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
- switch (ModRM & 0x38) {
- case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
- case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
- case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
- case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
- case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
- case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
- case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
- case 0x38: SUBB; break; /* CMP */
- }
-}
-
-OP( 0x81, i_81pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8);
- if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,EA) else CLKW(26,26,11,26,18,7,EA)
- switch (ModRM & 0x38) {
- case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
- case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
- case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
- case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
- case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
- case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
- case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
- case 0x38: SUBW; break; /* CMP */
- }
-}
-
-OP( 0x82, i_82pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((INT8)FETCH());
- if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
- switch (ModRM & 0x38) {
- case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
- case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
- case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
- case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
- case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
- case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
- case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
- case 0x38: SUBB; break; /* CMP */
- }
-}
-
-OP( 0x83, i_83pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((INT16)((INT8)FETCH()));
- if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,EA) else CLKW(26,26,11,26,18,7,EA)
- switch (ModRM & 0x38) {
- case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
- case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
- case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
- case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
- case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
- case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
- case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
- case 0x38: SUBW; break; /* CMP */
- }
-}
-
-OP( 0x84, i_test_br8 ) { DEF_br8; ANDB; CLKM(2,2,2,10,10,6); }
-OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW; CLKR(14,14,8,14,10,6,2,EA); }
-OP( 0x86, i_xchg_br8 ) { DEF_br8; RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(3,3,3,16,18,8); }
-OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKR(24,24,12,24,16,8,3,EA); }
-
-OP( 0x88, i_mov_br8 ) { UINT8 src; GetModRM; src = RegByte(ModRM); PutRMByte(ModRM,src); CLKM(2,2,2,9,9,3); }
-OP( 0x89, i_mov_wr16 ) { UINT16 src; GetModRM; src = RegWord(ModRM); PutRMWord(ModRM,src); CLKR(13,13,5,13,9,3,2,EA); }
-OP( 0x8a, i_mov_r8b ) { UINT8 src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src; CLKM(2,2,2,11,11,5); }
-OP( 0x8b, i_mov_r16w ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src; CLKR(15,15,7,15,11,5,2,EA); }
-OP( 0x8c, i_mov_wsreg ) { GetModRM; PutRMWord(ModRM,nec_state->sregs[(ModRM & 0x38) >> 3]); CLKR(14,14,5,14,10,3,2,EA); }
-OP( 0x8d, i_lea ) { UINT16 ModRM = FETCH(); (void)(*GetEA[ModRM])(nec_state); RegWord(ModRM)=EO; CLKS(4,4,2); }
-OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,EA);
- switch (ModRM & 0x38) {
- case 0x00: nec_state->sregs[DS1] = src; break; /* mov es,ew */
- case 0x08: nec_state->sregs[PS] = src; break; /* mov cs,ew */
- case 0x10: nec_state->sregs[SS] = src; break; /* mov ss,ew */
- case 0x18: nec_state->sregs[DS0] = src; break; /* mov ds,ew */
- default: logerror("%06x: Mov Sreg - Invalid register\n",PC(nec_state));
- }
- nec_state->no_interrupt=1;
-}
-OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); nec_state->icount-=21; }
-OP( 0x90, i_nop ) { CLK(3); }
-OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); }
-OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); }
-OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); }
-OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); }
-OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); }
-OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); }
-OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); }
-
-OP( 0x98, i_cbw ) { nec_state->regs.b[AH] = (nec_state->regs.b[AL] & 0x80) ? 0xff : 0; CLK(2); }
-OP( 0x99, i_cwd ) { nec_state->regs.w[DW] = (nec_state->regs.b[AH] & 0x80) ? 0xffff : 0; CLK(4); }
-OP( 0x9a, i_call_far ) { UINT32 tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(nec_state->sregs[PS]); PUSH(nec_state->ip); nec_state->ip = (WORD)tmp; nec_state->sregs[PS] = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,nec_state->regs.w[SP]); }
-OP( 0x9b, i_wait ) { if (!nec_state->poll_state) nec_state->ip--; CLK(5); }
-OP( 0x9c, i_pushf ) { UINT16 tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); }
-OP( 0x9d, i_popf ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (nec_state->TF) nec_trap(nec_state); }
-OP( 0x9e, i_sahf ) { UINT32 tmp = (CompressFlags() & 0xff00) | (nec_state->regs.b[AH] & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); }
-OP( 0x9f, i_lahf ) { nec_state->regs.b[AH] = CompressFlags() & 0xff; CLKS(3,3,2); }
-
-OP( 0xa0, i_mov_aldisp ) { UINT32 addr; addr = FETCHWORD(); nec_state->regs.b[AL] = GetMemB(DS0, addr); CLKS(10,10,5); }
-OP( 0xa1, i_mov_axdisp ) { UINT32 addr; addr = FETCHWORD(); nec_state->regs.w[AW] = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); }
-OP( 0xa2, i_mov_dispal ) { UINT32 addr; addr = FETCHWORD(); PutMemB(DS0, addr, nec_state->regs.b[AL]); CLKS(9,9,3); }
-OP( 0xa3, i_mov_dispax ) { UINT32 addr; addr = FETCHWORD(); PutMemW(DS0, addr, nec_state->regs.w[AW]); CLKW(13,13,5,13,9,3,addr); }
-OP( 0xa4, i_movsb ) { UINT32 tmp = GetMemB(DS0,nec_state->regs.w[IX]); PutMemB(DS1,nec_state->regs.w[IY], tmp); nec_state->regs.w[IY] += -2 * nec_state->DF + 1; nec_state->regs.w[IX] += -2 * nec_state->DF + 1; CLKS(8,8,6); }
-OP( 0xa5, i_movsw ) { UINT32 tmp = GetMemW(DS0,nec_state->regs.w[IX]); PutMemW(DS1,nec_state->regs.w[IY], tmp); nec_state->regs.w[IY] += -4 * nec_state->DF + 2; nec_state->regs.w[IX] += -4 * nec_state->DF + 2; CLKS(16,16,10); }
-OP( 0xa6, i_cmpsb ) { UINT32 src = GetMemB(DS1, nec_state->regs.w[IY]); UINT32 dst = GetMemB(DS0, nec_state->regs.w[IX]); SUBB; nec_state->regs.w[IY] += -2 * nec_state->DF + 1; nec_state->regs.w[IX] += -2 * nec_state->DF + 1; CLKS(14,14,14); }
-OP( 0xa7, i_cmpsw ) { UINT32 src = GetMemW(DS1, nec_state->regs.w[IY]); UINT32 dst = GetMemW(DS0, nec_state->regs.w[IX]); SUBW; nec_state->regs.w[IY] += -4 * nec_state->DF + 2; nec_state->regs.w[IX] += -4 * nec_state->DF + 2; CLKS(14,14,14); }
-
-OP( 0xa8, i_test_ald8 ) { DEF_ald8; ANDB; CLKS(4,4,2); }
-OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLKS(4,4,2); }
-OP( 0xaa, i_stosb ) { PutMemB(DS1,nec_state->regs.w[IY],nec_state->regs.b[AL]); nec_state->regs.w[IY] += -2 * nec_state->DF + 1; CLKS(4,4,3); }
-OP( 0xab, i_stosw ) { PutMemW(DS1,nec_state->regs.w[IY],nec_state->regs.w[AW]); nec_state->regs.w[IY] += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,nec_state->regs.w[IY]); }
-OP( 0xac, i_lodsb ) { nec_state->regs.b[AL] = GetMemB(DS0,nec_state->regs.w[IX]); nec_state->regs.w[IX] += -2 * nec_state->DF + 1; CLKS(4,4,3); }
-OP( 0xad, i_lodsw ) { nec_state->regs.w[AW] = GetMemW(DS0,nec_state->regs.w[IX]); nec_state->regs.w[IX] += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,nec_state->regs.w[IX]); }
-OP( 0xae, i_scasb ) { UINT32 src = GetMemB(DS1, nec_state->regs.w[IY]); UINT32 dst = nec_state->regs.b[AL]; SUBB; nec_state->regs.w[IY] += -2 * nec_state->DF + 1; CLKS(4,4,3); }
-OP( 0xaf, i_scasw ) { UINT32 src = GetMemW(DS1, nec_state->regs.w[IY]); UINT32 dst = nec_state->regs.w[AW]; SUBW; nec_state->regs.w[IY] += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,nec_state->regs.w[IY]); }
-
-OP( 0xb0, i_mov_ald8 ) { nec_state->regs.b[AL] = FETCH(); CLKS(4,4,2); }
-OP( 0xb1, i_mov_cld8 ) { nec_state->regs.b[CL] = FETCH(); CLKS(4,4,2); }
-OP( 0xb2, i_mov_dld8 ) { nec_state->regs.b[DL] = FETCH(); CLKS(4,4,2); }
-OP( 0xb3, i_mov_bld8 ) { nec_state->regs.b[BL] = FETCH(); CLKS(4,4,2); }
-OP( 0xb4, i_mov_ahd8 ) { nec_state->regs.b[AH] = FETCH(); CLKS(4,4,2); }
-OP( 0xb5, i_mov_chd8 ) { nec_state->regs.b[CH] = FETCH(); CLKS(4,4,2); }
-OP( 0xb6, i_mov_dhd8 ) { nec_state->regs.b[DH] = FETCH(); CLKS(4,4,2); }
-OP( 0xb7, i_mov_bhd8 ) { nec_state->regs.b[BH] = FETCH(); CLKS(4,4,2); }
-
-OP( 0xb8, i_mov_axd16 ) { nec_state->regs.b[AL] = FETCH(); nec_state->regs.b[AH] = FETCH(); CLKS(4,4,2); }
-OP( 0xb9, i_mov_cxd16 ) { nec_state->regs.b[CL] = FETCH(); nec_state->regs.b[CH] = FETCH(); CLKS(4,4,2); }
-OP( 0xba, i_mov_dxd16 ) { nec_state->regs.b[DL] = FETCH(); nec_state->regs.b[DH] = FETCH(); CLKS(4,4,2); }
-OP( 0xbb, i_mov_bxd16 ) { nec_state->regs.b[BL] = FETCH(); nec_state->regs.b[BH] = FETCH(); CLKS(4,4,2); }
-OP( 0xbc, i_mov_spd16 ) { nec_state->regs.b[SPL] = FETCH(); nec_state->regs.b[SPH] = FETCH(); CLKS(4,4,2); }
-OP( 0xbd, i_mov_bpd16 ) { nec_state->regs.b[BPL] = FETCH(); nec_state->regs.b[BPH] = FETCH(); CLKS(4,4,2); }
-OP( 0xbe, i_mov_sid16 ) { nec_state->regs.b[IXL] = FETCH(); nec_state->regs.b[IXH] = FETCH(); CLKS(4,4,2); }
-OP( 0xbf, i_mov_did16 ) { nec_state->regs.b[IYL] = FETCH(); nec_state->regs.b[IYH] = FETCH(); CLKS(4,4,2); }
-
-OP( 0xc0, i_rotshft_bd8 ) {
- UINT32 src, dst; UINT8 c;
- GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src;
- c=FETCH();
- CLKM(7,7,2,19,19,6);
- if (c) switch (ModRM & 0x38) {
- case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x08: do { ROR_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x20: SHL_BYTE(c); break;
- case 0x28: SHR_BYTE(c); break;
- case 0x30: logerror("%06x: Undefined opcode 0xc0 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_BYTE(c); break;
- }
-}
-
-OP( 0xc1, i_rotshft_wd8 ) {
- UINT32 src, dst; UINT8 c;
- GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src;
- c=FETCH();
- CLKM(7,7,2,27,19,6);
- if (c) switch (ModRM & 0x38) {
- case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x08: do { ROR_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x20: SHL_WORD(c); break;
- case 0x28: SHR_WORD(c); break;
- case 0x30: logerror("%06x: Undefined opcode 0xc1 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_WORD(c); break;
- }
-}
-
-OP( 0xc2, i_ret_d16 ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(nec_state->ip); nec_state->regs.w[SP]+=count; CHANGE_PC; CLKS(24,24,10); }
-OP( 0xc3, i_ret ) { POP(nec_state->ip); CHANGE_PC; CLKS(19,19,10); }
-OP( 0xc4, i_les_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; nec_state->sregs[DS1] = GetnextRMWord; CLKW(26,26,14,26,18,10,EA); }
-OP( 0xc5, i_lds_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; nec_state->sregs[DS0] = GetnextRMWord; CLKW(26,26,14,26,18,10,EA); }
-OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); nec_state->icount-=(ModRM >=0xc0 )?4:11; }
-OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); nec_state->icount-=(ModRM >=0xc0 )?4:15; }
-
-OP( 0xc8, i_enter ) {
- UINT32 nb = FETCH();
- UINT32 i,level;
-
- nec_state->icount-=23;
- nb += FETCH() << 8;
- level = FETCH();
- PUSH(nec_state->regs.w[BP]);
- nec_state->regs.w[BP]=nec_state->regs.w[SP];
- nec_state->regs.w[SP] -= nb;
- for (i=1;i<level;i++) {
- PUSH(GetMemW(SS,nec_state->regs.w[BP]-i*2));
- nec_state->icount-=16;
- }
- if (level) PUSH(nec_state->regs.w[BP]);
-}
-OP( 0xc9, i_leave ) {
- nec_state->regs.w[SP]=nec_state->regs.w[BP];
- POP(nec_state->regs.w[BP]);
- nec_state->icount-=8;
-}
-OP( 0xca, i_retf_d16 ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(nec_state->ip); POP(nec_state->sregs[PS]); nec_state->regs.w[SP]+=count; CHANGE_PC; CLKS(32,32,16); }
-OP( 0xcb, i_retf ) { POP(nec_state->ip); POP(nec_state->sregs[PS]); CHANGE_PC; CLKS(29,29,16); }
-OP( 0xcc, i_int3 ) { nec_interrupt(nec_state, 3,0); CLKS(50,50,24); }
-OP( 0xcd, i_int ) { nec_interrupt(nec_state, FETCH(),0); CLKS(50,50,24); }
-OP( 0xce, i_into ) { if (OF) { nec_interrupt(nec_state, 4,0); CLKS(52,52,26); } else CLK(3); }
-OP( 0xcf, i_iret ) { POP(nec_state->ip); POP(nec_state->sregs[PS]); i_popf(nec_state); SetMD(1); CHANGE_PC; CLKS(39,39,19); }
-
-OP( 0xd0, i_rotshft_b ) {
- UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
- CLKM(6,6,2,16,16,7);
- switch (ModRM & 0x38) {
- case 0x00: ROL_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x08: ROR_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x20: SHL_BYTE(1); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x28: SHR_BYTE(1); nec_state->OverVal = (src^dst)&0x80; break;
- case 0x30: logerror("%06x: Undefined opcode 0xd0 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_BYTE(1); nec_state->OverVal = 0; break;
- }
-}
-
-OP( 0xd1, i_rotshft_w ) {
- UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
- CLKM(6,6,2,24,16,7);
- switch (ModRM & 0x38) {
- case 0x00: ROL_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x08: ROR_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x18: RORC_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x20: SHL_WORD(1); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x28: SHR_WORD(1); nec_state->OverVal = (src^dst)&0x8000; break;
- case 0x30: logerror("%06x: Undefined opcode 0xd1 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_WORD(1); nec_state->OverVal = 0; break;
- }
-}
-
-OP( 0xd2, i_rotshft_bcl ) {
- UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
- c=nec_state->regs.b[CL];
- CLKM(7,7,2,19,19,6);
- if (c) switch (ModRM & 0x38) {
- case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x08: do { ROR_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
- case 0x20: SHL_BYTE(c); break;
- case 0x28: SHR_BYTE(c); break;
- case 0x30: logerror("%06x: Undefined opcode 0xd2 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_BYTE(c); break;
- }
-}
-
-OP( 0xd3, i_rotshft_wcl ) {
- UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
- c=nec_state->regs.b[CL];
- CLKM(7,7,2,27,19,6);
- if (c) switch (ModRM & 0x38) {
- case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x08: do { ROR_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
- case 0x20: SHL_WORD(c); break;
- case 0x28: SHR_WORD(c); break;
- case 0x30: logerror("%06x: Undefined opcode 0xd3 0x30 (SHLA)\n",PC(nec_state)); break;
- case 0x38: SHRA_WORD(c); break;
- }
-}
-
-OP( 0xd4, i_aam ) { UINT32 mult=FETCH(); mult=0; nec_state->regs.b[AH] = nec_state->regs.b[AL] / 10; nec_state->regs.b[AL] %= 10; SetSZPF_Word(nec_state->regs.w[AW]); CLKS(15,15,12); }
-OP( 0xd5, i_aad ) { UINT32 mult=FETCH(); mult=0; nec_state->regs.b[AL] = nec_state->regs.b[AH] * 10 + nec_state->regs.b[AL]; nec_state->regs.b[AH] = 0; SetSZPF_Byte(nec_state->regs.b[AL]); CLKS(7,7,8); }
-OP( 0xd6, i_setalc ) { nec_state->regs.b[AL] = (CF)?0xff:0x00; nec_state->icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC(nec_state)); }
-OP( 0xd7, i_trans ) { UINT32 dest = (nec_state->regs.w[BW]+nec_state->regs.b[AL])&0xffff; nec_state->regs.b[AL] = GetMemB(DS0, dest); CLKS(9,9,5); }
-OP( 0xd8, i_fpo ) { GetModRM; nec_state->icount-=2; logerror("%06x: Unimplemented floating point control %04x\n",PC(nec_state),ModRM); }
-
-OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH(); nec_state->regs.w[CW]--; if (!ZF && nec_state->regs.w[CW]) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
-OP( 0xe1, i_loope ) { INT8 disp = (INT8)FETCH(); nec_state->regs.w[CW]--; if ( ZF && nec_state->regs.w[CW]) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
-OP( 0xe2, i_loop ) { INT8 disp = (INT8)FETCH(); nec_state->regs.w[CW]--; if (nec_state->regs.w[CW]) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
-OP( 0xe3, i_jcxz ) { INT8 disp = (INT8)FETCH(); if (nec_state->regs.w[CW] == 0) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
-OP( 0xe4, i_inal ) { UINT8 port = FETCH(); nec_state->regs.b[AL] = read_port_byte(port); CLKS(9,9,5); }
-OP( 0xe5, i_inax ) { UINT8 port = FETCH(); nec_state->regs.w[AW] = read_port_word(port); CLKW(13,13,7,13,9,5,port); }
-OP( 0xe6, i_outal ) { UINT8 port = FETCH(); write_port_byte(port, nec_state->regs.b[AL]); CLKS(8,8,3); }
-OP( 0xe7, i_outax ) { UINT8 port = FETCH(); write_port_word(port, nec_state->regs.w[AW]); CLKW(12,12,5,12,8,3,port); }
-
-OP( 0xe8, i_call_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(nec_state->ip); nec_state->ip = (WORD)(nec_state->ip+(INT16)tmp); CHANGE_PC; nec_state->icount-=24; }
-OP( 0xe9, i_jmp_d16 ) { UINT32 tmp; tmp = FETCHWORD(); nec_state->ip = (WORD)(nec_state->ip+(INT16)tmp); CHANGE_PC; nec_state->icount-=15; }
-OP( 0xea, i_jmp_far ) { UINT32 tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); nec_state->sregs[PS] = (WORD)tmp1; nec_state->ip = (WORD)tmp; CHANGE_PC; nec_state->icount-=27; }
-OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((INT8)FETCH()); nec_state->icount-=12; nec_state->ip = (WORD)(nec_state->ip+tmp); }
-OP( 0xec, i_inaldx ) { nec_state->regs.b[AL] = read_port_byte(nec_state->regs.w[DW]); CLKS(8,8,5);}
-OP( 0xed, i_inaxdx ) { nec_state->regs.w[AW] = read_port_word(nec_state->regs.w[DW]); CLKW(12,12,7,12,8,5,nec_state->regs.w[DW]); }
-OP( 0xee, i_outdxal ) { write_port_byte(nec_state->regs.w[DW], nec_state->regs.b[AL]); CLKS(8,8,3); }
-OP( 0xef, i_outdxax ) { write_port_word(nec_state->regs.w[DW], nec_state->regs.w[AW]); CLKW(12,12,5,12,8,3,nec_state->regs.w[DW]); }
-
-OP( 0xf0, i_lock ) { logerror("%06x: Warning - BUSLOCK\n",PC(nec_state)); nec_state->no_interrupt=1; CLK(2); }
-OP( 0xf2, i_repne ) { UINT32 next = fetchop(nec_state); UINT16 c = nec_state->regs.w[CW];
- switch(next) { /* Segments */
- case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS1]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[PS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[SS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS0]<<4; next = fetchop(nec_state); CLK(2); break;
- }
-
- switch(next) {
- case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && ZF==0); nec_state->regs.w[CW]=c; break;
- case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && ZF==0); nec_state->regs.w[CW]=c; break;
- case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && ZF==0); nec_state->regs.w[CW]=c; break;
- case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && ZF==0); nec_state->regs.w[CW]=c; break;
- default: logerror("%06x: REPNE invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
- }
- nec_state->seg_prefix=FALSE;
-}
-OP( 0xf3, i_repe ) { UINT32 next = fetchop(nec_state); UINT16 c = nec_state->regs.w[CW];
- switch(next) { /* Segments */
- case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS1]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[PS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[SS]<<4; next = fetchop(nec_state); CLK(2); break;
- case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=nec_state->sregs[DS0]<<4; next = fetchop(nec_state); CLK(2); break;
- }
-
- switch(next) {
- case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && ZF==1); nec_state->regs.w[CW]=c; break;
- case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && ZF==1); nec_state->regs.w[CW]=c; break;
- case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0); nec_state->regs.w[CW]=c; break;
- case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && ZF==1); nec_state->regs.w[CW]=c; break;
- case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && ZF==1); nec_state->regs.w[CW]=c; break;
- default: logerror("%06x: REPE invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
- }
- nec_state->seg_prefix=FALSE;
-}
-OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC(nec_state)); 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);
- switch (ModRM & 0x38) {
- case 0x00: tmp &= FETCH(); nec_state->CarryVal = nec_state->OverVal = 0; SetSZPF_Byte(tmp); nec_state->icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
- case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC(nec_state)); break;
- case 0x10: PutbackRMByte(ModRM,~tmp); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
- case 0x18: nec_state->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
- case 0x20: uresult = nec_state->regs.b[AL]*tmp; nec_state->regs.w[AW]=(WORD)uresult; nec_state->CarryVal=nec_state->OverVal=(nec_state->regs.b[AH]!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
- case 0x28: result = (INT16)((INT8)nec_state->regs.b[AL])*(INT16)((INT8)tmp); nec_state->regs.w[AW]=(WORD)result; nec_state->CarryVal=nec_state->OverVal=(nec_state->regs.b[AH]!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
- case 0x30: if (tmp) { DIVUB; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
- case 0x38: if (tmp) { DIVB; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
- }
-}
-
-OP( 0xf7, i_f7pre ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2;
- GetModRM; tmp = GetRMWord(ModRM);
- switch (ModRM & 0x38) {
- case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; nec_state->CarryVal = nec_state->OverVal = 0; SetSZPF_Word(tmp); nec_state->icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
- case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC(nec_state)); break;
- case 0x10: PutbackRMWord(ModRM,~tmp); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
- case 0x18: nec_state->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
- case 0x20: uresult = nec_state->regs.w[AW]*tmp; nec_state->regs.w[AW]=uresult&0xffff; nec_state->regs.w[DW]=((UINT32)uresult)>>16; nec_state->CarryVal=nec_state->OverVal=(nec_state->regs.w[DW]!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
- case 0x28: result = (INT32)((INT16)nec_state->regs.w[AW])*(INT32)((INT16)tmp); nec_state->regs.w[AW]=result&0xffff; nec_state->regs.w[DW]=result>>16; nec_state->CarryVal=nec_state->OverVal=(nec_state->regs.w[DW]!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
- case 0x30: if (tmp) { DIVUW; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
- case 0x38: if (tmp) { DIVW; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
- }
-}
-
-OP( 0xf8, i_clc ) { nec_state->CarryVal = 0; CLK(2); }
-OP( 0xf9, i_stc ) { nec_state->CarryVal = 1; CLK(2); }
-OP( 0xfa, i_di ) { SetIF(0); CLK(2); }
-OP( 0xfb, i_ei ) { SetIF(1); CLK(2); }
-OP( 0xfc, i_cld ) { SetDF(0); CLK(2); }
-OP( 0xfd, i_std ) { SetDF(1); CLK(2); }
-OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM);
- switch(ModRM & 0x38) {
- case 0x00: tmp1 = tmp+1; nec_state->OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* INC */
- case 0x08: tmp1 = tmp-1; nec_state->OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* DEC */
- default: logerror("%06x: FE Pre with unimplemented mod\n",PC(nec_state));
- }
-}
-OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM);
- switch(ModRM & 0x38) {
- case 0x00: tmp1 = tmp+1; nec_state->OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* INC */
- case 0x08: tmp1 = tmp-1; nec_state->OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* DEC */
- case 0x10: PUSH(nec_state->ip); nec_state->ip = (WORD)tmp; CHANGE_PC; nec_state->icount-=(ModRM >=0xc0 )?16:20; break; /* CALL */
- case 0x18: tmp1 = nec_state->sregs[PS]; nec_state->sregs[PS] = GetnextRMWord; PUSH(tmp1); PUSH(nec_state->ip); nec_state->ip = tmp; CHANGE_PC; nec_state->icount-=(ModRM >=0xc0 )?16:26; break; /* CALL FAR */
- case 0x20: nec_state->ip = tmp; CHANGE_PC; nec_state->icount-=13; break; /* JMP */
- case 0x28: nec_state->ip = tmp; nec_state->sregs[PS] = GetnextRMWord; CHANGE_PC; nec_state->icount-=15; break; /* JMP FAR */
- case 0x30: PUSH(tmp); nec_state->icount-=4; break;
- default: logerror("%06x: FF Pre with unimplemented mod\n",PC(nec_state));
- }
-}
-
-static void i_invalid(nec_state_t *nec_state)
-{
- nec_state->icount-=10;
- logerror("%06x: Invalid Opcode\n",PC(nec_state));
-}
+#include "necinstr.c"
/*****************************************************************************/
@@ -1083,19 +349,13 @@ static void set_poll_line(nec_state_t *nec_state, int state)
static CPU_DISASSEMBLE( nec )
{
- nec_state_t *nec_state = get_safe_token(device);
-
- return necv_dasm_one(buffer, pc, oprom, nec_state->config);
+ return necv_dasm_one(buffer, pc, oprom, NULL);
}
static void nec_init(legacy_cpu_device *device, device_irq_callback irqcallback, int type)
{
- const nec_config *config = device->baseconfig().static_config() ? (const nec_config *)device->baseconfig().static_config() : &default_config;
nec_state_t *nec_state = get_safe_token(device);
- nec_state->config = config;
-
-
state_save_register_device_item_array(device, 0, nec_state->regs.w);
state_save_register_device_item_array(device, 0, nec_state->sregs);
@@ -1144,7 +404,7 @@ static CPU_EXECUTE( necv )
if (nec_state->no_interrupt)
nec_state->no_interrupt--;
- debugger_instruction_hook(device, (nec_state->sregs[PS]<<4) + nec_state->ip);
+ debugger_instruction_hook(device, (Sreg(PS)<<4) + nec_state->ip);
prev_ICount = nec_state->icount;
nec_instruction[fetchop(nec_state)](nec_state);
do_prefetch(nec_state, prev_ICount);
@@ -1209,41 +469,41 @@ static CPU_SET_INFO( nec )
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + NEC_PC:
- if( info->i - (nec_state->sregs[PS]<<4) < 0x10000 )
+ if( info->i - (Sreg(PS)<<4) < 0x10000 )
{
- nec_state->ip = info->i - (nec_state->sregs[PS]<<4);
+ nec_state->ip = info->i - (Sreg(PS)<<4);
}
else
{
- nec_state->sregs[PS] = info->i >> 4;
+ Sreg(PS) = info->i >> 4;
nec_state->ip = info->i & 0x0000f;
}
break;
case CPUINFO_INT_REGISTER + NEC_IP: nec_state->ip = info->i; break;
case CPUINFO_INT_SP:
- if( info->i - (nec_state->sregs[SS]<<4) < 0x10000 )
+ if( info->i - (Sreg(SS)<<4) < 0x10000 )
{
- nec_state->regs.w[SP] = info->i - (nec_state->sregs[SS]<<4);
+ Wreg(SP) = info->i - (Sreg(SS)<<4);
}
else
{
- nec_state->sregs[SS] = info->i >> 4;
- nec_state->regs.w[SP] = info->i & 0x0000f;
+ Sreg(SS) = info->i >> 4;
+ Wreg(SP) = info->i & 0x0000f;
}
break;
- case CPUINFO_INT_REGISTER + NEC_SP: nec_state->regs.w[SP] = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_SP: Wreg(SP) = info->i; break;
case CPUINFO_INT_REGISTER + NEC_FLAGS: ExpandFlags(info->i); break;
- case CPUINFO_INT_REGISTER + NEC_AW: nec_state->regs.w[AW] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_CW: nec_state->regs.w[CW] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_DW: nec_state->regs.w[DW] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_BW: nec_state->regs.w[BW] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_BP: nec_state->regs.w[BP] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_IX: nec_state->regs.w[IX] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_IY: nec_state->regs.w[IY] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_ES: nec_state->sregs[DS1] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_CS: nec_state->sregs[PS] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_SS: nec_state->sregs[SS] = info->i; break;
- case CPUINFO_INT_REGISTER + NEC_DS: nec_state->sregs[DS0] = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_AW: Wreg(AW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_CW: Wreg(CW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_DW: Wreg(DW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_BW: Wreg(BW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_BP: Wreg(BP) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_IX: Wreg(IX) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_IY: Wreg(IY) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_ES: Sreg(DS1) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_CS: Sreg(PS) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_SS: Sreg(SS) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_DS: Sreg(DS0) = info->i; break;
case CPUINFO_INT_REGISTER + NEC_VECTOR: nec_state->int_vector = info->i; break;
}
}
@@ -1290,22 +550,22 @@ static CPU_GET_INFO( nec )
case CPUINFO_INT_PREVIOUSPC: /* not supported */ break;
case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + NEC_PC: info->i = ((nec_state->sregs[PS]<<4) + nec_state->ip); break;
+ 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 = (nec_state->sregs[SS]<<4) + nec_state->regs.w[SP]; break;
- case CPUINFO_INT_REGISTER + NEC_SP: info->i = nec_state->regs.w[SP]; 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 = nec_state->regs.w[AW]; break;
- case CPUINFO_INT_REGISTER + NEC_CW: info->i = nec_state->regs.w[CW]; break;
- case CPUINFO_INT_REGISTER + NEC_DW: info->i = nec_state->regs.w[DW]; break;
- case CPUINFO_INT_REGISTER + NEC_BW: info->i = nec_state->regs.w[BW]; break;
- case CPUINFO_INT_REGISTER + NEC_BP: info->i = nec_state->regs.w[BP]; break;
- case CPUINFO_INT_REGISTER + NEC_IX: info->i = nec_state->regs.w[IX]; break;
- case CPUINFO_INT_REGISTER + NEC_IY: info->i = nec_state->regs.w[IY]; break;
- case CPUINFO_INT_REGISTER + NEC_ES: info->i = nec_state->sregs[DS1]; break;
- case CPUINFO_INT_REGISTER + NEC_CS: info->i = nec_state->sregs[PS]; break;
- case CPUINFO_INT_REGISTER + NEC_SS: info->i = nec_state->sregs[SS]; break;
- case CPUINFO_INT_REGISTER + NEC_DS: info->i = nec_state->sregs[DS0]; 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_VECTOR: info->i = nec_state->int_vector; break;
case CPUINFO_INT_REGISTER + NEC_PENDING: info->i = nec_state->pending_irq; break;
@@ -1329,7 +589,7 @@ static CPU_GET_INFO( nec )
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 ? 'M':'.',
+ flags & 0x8000 ? 'N':'E',
flags & 0x4000 ? '?':'.',
flags & 0x2000 ? '?':'.',
flags & 0x1000 ? '?':'.',
@@ -1343,25 +603,25 @@ static CPU_GET_INFO( nec )
flags & 0x0010 ? 'A':'.',
flags & 0x0008 ? '?':'.',
flags & 0x0004 ? 'P':'.',
- flags & 0x0002 ? 'N':'.',
+ flags & 0x0002 ? '.':'?',
flags & 0x0001 ? 'C':'.');
break;
- case CPUINFO_STR_REGISTER + NEC_PC: sprintf(info->s, "PC:%04X", (nec_state->sregs[PS]<<4) + nec_state->ip); break;
+ case CPUINFO_STR_REGISTER + NEC_PC: sprintf(info->s, "PC:%04X", (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", nec_state->regs.w[SP]); 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", nec_state->regs.w[AW]); break;
- case CPUINFO_STR_REGISTER + NEC_CW: sprintf(info->s, "CW:%04X", nec_state->regs.w[CW]); break;
- case CPUINFO_STR_REGISTER + NEC_DW: sprintf(info->s, "DW:%04X", nec_state->regs.w[DW]); break;
- case CPUINFO_STR_REGISTER + NEC_BW: sprintf(info->s, "BW:%04X", nec_state->regs.w[BW]); break;
- case CPUINFO_STR_REGISTER + NEC_BP: sprintf(info->s, "BP:%04X", nec_state->regs.w[BP]); break;
- case CPUINFO_STR_REGISTER + NEC_IX: sprintf(info->s, "IX:%04X", nec_state->regs.w[IX]); break;
- case CPUINFO_STR_REGISTER + NEC_IY: sprintf(info->s, "IY:%04X", nec_state->regs.w[IY]); break;
- case CPUINFO_STR_REGISTER + NEC_ES: sprintf(info->s, "DS1:%04X", nec_state->sregs[DS1]); break;
- case CPUINFO_STR_REGISTER + NEC_CS: sprintf(info->s, "PS:%04X", nec_state->sregs[PS]); break;
- case CPUINFO_STR_REGISTER + NEC_SS: sprintf(info->s, "SS:%04X", nec_state->sregs[SS]); break;
- case CPUINFO_STR_REGISTER + NEC_DS: sprintf(info->s, "DS0:%04X", nec_state->sregs[DS0]); 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;
case CPUINFO_STR_REGISTER + NEC_VECTOR: sprintf(info->s, "V:%02X", nec_state->int_vector); break;
}
}
@@ -1394,29 +654,6 @@ CPU_GET_INFO( v20 )
* CPU-specific set_info
**************************************************************************/
-CPU_GET_INFO( v25 )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
- case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(v20); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case DEVINFO_STR_NAME: strcpy(info->s, "V25"); break;
-
- default: CPU_GET_INFO_CALL(nec); break;
- }
-}
-
-
-/**************************************************************************
- * CPU-specific set_info
- **************************************************************************/
-
CPU_GET_INFO( v30 )
{
switch (state)
@@ -1450,27 +687,6 @@ CPU_GET_INFO( v33 )
}
}
-
-/**************************************************************************
- * CPU-specific set_info
- **************************************************************************/
-
-CPU_GET_INFO( v35 )
-{
- switch (state)
- {
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(v30); break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case DEVINFO_STR_NAME: strcpy(info->s, "V35"); break;
-
- default: CPU_GET_INFO_CALL(nec); break;
- }
-}
-
DEFINE_LEGACY_CPU_DEVICE(V20, v20);
-DEFINE_LEGACY_CPU_DEVICE(V25, v25);
DEFINE_LEGACY_CPU_DEVICE(V30, v30);
DEFINE_LEGACY_CPU_DEVICE(V33, v33);
-DEFINE_LEGACY_CPU_DEVICE(V35, v35);
diff --git a/src/emu/cpu/nec/nec.h b/src/emu/cpu/nec/nec.h
index 93070d1b5d4..3c47aa8c051 100644
--- a/src/emu/cpu/nec/nec.h
+++ b/src/emu/cpu/nec/nec.h
@@ -1,29 +1,29 @@
-/* ASG 971222 -- rewrote this interface */
-#ifndef __NEC_H_
-#define __NEC_H_
-
-
-typedef struct _nec_config nec_config;
-struct _nec_config
-{
- const UINT8* v25v35_decryptiontable; // internal decryption table
-};
-
-#define NEC_INPUT_LINE_POLL 20
-
-enum
-{
- NEC_PC=0,
- NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
- NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
- NEC_VECTOR, NEC_PENDING
-};
-
-/* Public functions */
-DECLARE_LEGACY_CPU_DEVICE(V20, v20);
-DECLARE_LEGACY_CPU_DEVICE(V25, v25);
-DECLARE_LEGACY_CPU_DEVICE(V30, v30);
-DECLARE_LEGACY_CPU_DEVICE(V33, v33);
-DECLARE_LEGACY_CPU_DEVICE(V35, v35);
-
-#endif
+/* ASG 971222 -- rewrote this interface */
+#ifndef __NEC_H_
+#define __NEC_H_
+
+
+typedef struct _nec_config nec_config;
+struct _nec_config
+{
+ const UINT8* v25v35_decryptiontable; // internal decryption table
+};
+
+#define NEC_INPUT_LINE_POLL 20
+
+enum
+{
+ NEC_PC=0,
+ NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
+ NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
+ NEC_VECTOR, NEC_PENDING
+};
+
+/* Public functions */
+DECLARE_LEGACY_CPU_DEVICE(V20, v20);
+DECLARE_LEGACY_CPU_DEVICE(V25, v25);
+DECLARE_LEGACY_CPU_DEVICE(V30, v30);
+DECLARE_LEGACY_CPU_DEVICE(V33, v33);
+DECLARE_LEGACY_CPU_DEVICE(V35, v35);
+
+#endif
diff --git a/src/emu/cpu/nec/necea.h b/src/emu/cpu/nec/necea.h
index 17f72a1177e..cafbb27a620 100644
--- a/src/emu/cpu/nec/necea.h
+++ b/src/emu/cpu/nec/necea.h
@@ -3,32 +3,32 @@ static UINT32 EA;
static UINT16 EO;
static UINT16 E16;
-static unsigned EA_000(nec_state_t *nec_state) { EO=nec_state->regs.w[BW]+nec_state->regs.w[IX]; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_001(nec_state_t *nec_state) { EO=nec_state->regs.w[BW]+nec_state->regs.w[IY]; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_002(nec_state_t *nec_state) { EO=nec_state->regs.w[BP]+nec_state->regs.w[IX]; EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_003(nec_state_t *nec_state) { EO=nec_state->regs.w[BP]+nec_state->regs.w[IY]; EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_004(nec_state_t *nec_state) { EO=nec_state->regs.w[IX]; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_005(nec_state_t *nec_state) { EO=nec_state->regs.w[IY]; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_000(nec_state_t *nec_state) { EO=Wreg(BW)+Wreg(IX); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_001(nec_state_t *nec_state) { EO=Wreg(BW)+Wreg(IY); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_002(nec_state_t *nec_state) { EO=Wreg(BP)+Wreg(IX); EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_003(nec_state_t *nec_state) { EO=Wreg(BP)+Wreg(IY); EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_004(nec_state_t *nec_state) { EO=Wreg(IX); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_005(nec_state_t *nec_state) { EO=Wreg(IY); EA=DefaultBase(DS0)+EO; return EA; }
static unsigned EA_006(nec_state_t *nec_state) { EO=FETCH(); EO+=FETCH()<<8; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_007(nec_state_t *nec_state) { EO=nec_state->regs.w[BW]; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_007(nec_state_t *nec_state) { EO=Wreg(BW); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_100(nec_state_t *nec_state) { EO=(nec_state->regs.w[BW]+nec_state->regs.w[IX]+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_101(nec_state_t *nec_state) { EO=(nec_state->regs.w[BW]+nec_state->regs.w[IY]+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_102(nec_state_t *nec_state) { EO=(nec_state->regs.w[BP]+nec_state->regs.w[IX]+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_103(nec_state_t *nec_state) { EO=(nec_state->regs.w[BP]+nec_state->regs.w[IY]+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_104(nec_state_t *nec_state) { EO=(nec_state->regs.w[IX]+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_105(nec_state_t *nec_state) { EO=(nec_state->regs.w[IY]+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_106(nec_state_t *nec_state) { EO=(nec_state->regs.w[BP]+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_107(nec_state_t *nec_state) { EO=(nec_state->regs.w[BW]+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_100(nec_state_t *nec_state) { EO=(Wreg(BW)+Wreg(IX)+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_101(nec_state_t *nec_state) { EO=(Wreg(BW)+Wreg(IY)+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_102(nec_state_t *nec_state) { EO=(Wreg(BP)+Wreg(IX)+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_103(nec_state_t *nec_state) { EO=(Wreg(BP)+Wreg(IY)+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_104(nec_state_t *nec_state) { EO=(Wreg(IX)+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_105(nec_state_t *nec_state) { EO=(Wreg(IY)+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_106(nec_state_t *nec_state) { EO=(Wreg(BP)+(INT8)FETCH()); EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_107(nec_state_t *nec_state) { EO=(Wreg(BW)+(INT8)FETCH()); EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_200(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BW]+nec_state->regs.w[IX]+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_201(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BW]+nec_state->regs.w[IY]+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_202(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BP]+nec_state->regs.w[IX]+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_203(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BP]+nec_state->regs.w[IY]+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_204(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[IX]+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_205(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[IY]+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
-static unsigned EA_206(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BP]+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
-static unsigned EA_207(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=nec_state->regs.w[BW]+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_200(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BW)+Wreg(IX)+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_201(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BW)+Wreg(IY)+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_202(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BP)+Wreg(IX)+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_203(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BP)+Wreg(IY)+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_204(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(IX)+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_205(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(IY)+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
+static unsigned EA_206(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BP)+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
+static unsigned EA_207(nec_state_t *nec_state) { E16=FETCH(); E16+=FETCH()<<8; EO=Wreg(BW)+(INT16)E16; EA=DefaultBase(DS0)+EO; return EA; }
static unsigned (*const GetEA[192])(nec_state_t *)={
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
diff --git a/src/emu/cpu/nec/necinstr.c b/src/emu/cpu/nec/necinstr.c
new file mode 100644
index 00000000000..4a85241227b
--- /dev/null
+++ b/src/emu/cpu/nec/necinstr.c
@@ -0,0 +1,672 @@
+#define OP(num,func_name) static void func_name(nec_state_t *nec_state)
+
+OP( 0x00, i_add_br8 ) { DEF_br8; ADDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x01, i_add_wr16 ) { DEF_wr16; ADDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x02, i_add_r8b ) { DEF_r8b; ADDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x03, i_add_r16w ) { DEF_r16w; ADDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x04, i_add_ald8 ) { DEF_ald8; ADDB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x05, i_add_axd16) { DEF_axd16; ADDW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x06, i_push_es ) { PUSH(Sreg(DS1)); CLKS(12,8,3); }
+OP( 0x07, i_pop_es ) { POP(Sreg(DS1)); CLKS(12,8,5); }
+
+OP( 0x08, i_or_br8 ) { DEF_br8; ORB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x09, i_or_wr16 ) { DEF_wr16; ORW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x0a, i_or_r8b ) { DEF_r8b; ORB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x0b, i_or_r16w ) { DEF_r16w; ORW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x0e, i_push_cs ) { PUSH(Sreg(PS)); CLKS(12,8,3); }
+OP( 0x0f, i_pre_nec ) { UINT32 ModRM, tmp, tmp2;
+ switch (FETCH()) {
+ case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
+ case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
+ case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
+ case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
+ case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
+ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
+
+ case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
+ case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
+ case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
+ case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
+ case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
+ case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
+
+ case 0x20 : ADD4S; CLKS(7,7,2); break;
+ case 0x22 : SUB4S; CLKS(7,7,2); break;
+ case 0x26 : CMP4S; CLKS(7,7,2); break;
+ case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
+ case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
+ case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC(nec_state)); break;
+ case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC(nec_state)); break;
+ case 0x92 : CLK(2); break; /* V25/35 FINT */
+ case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC(nec_state)); break;
+ case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC(nec_state)); break;
+ case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC(nec_state)); break;
+ default: logerror("%06x: Unknown V20 instruction\n",PC(nec_state)); break;
+ }
+}
+
+OP( 0x10, i_adc_br8 ) { DEF_br8; src+=CF; ADDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x11, i_adc_wr16 ) { DEF_wr16; src+=CF; ADDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x12, i_adc_r8b ) { DEF_r8b; src+=CF; ADDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x13, i_adc_r16w ) { DEF_r16w; src+=CF; ADDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x14, i_adc_ald8 ) { DEF_ald8; src+=CF; ADDB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF; ADDW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x16, i_push_ss ) { PUSH(Sreg(SS)); CLKS(12,8,3); }
+OP( 0x17, i_pop_ss ) { POP(Sreg(SS)); CLKS(12,8,5); nec_state->no_interrupt=1; }
+
+OP( 0x18, i_sbb_br8 ) { DEF_br8; src+=CF; SUBB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x19, i_sbb_wr16 ) { DEF_wr16; src+=CF; SUBW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x1a, i_sbb_r8b ) { DEF_r8b; src+=CF; SUBB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x1b, i_sbb_r16w ) { DEF_r16w; src+=CF; SUBW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x1c, i_sbb_ald8 ) { DEF_ald8; src+=CF; SUBB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF; SUBW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x1e, i_push_ds ) { PUSH(Sreg(DS0)); CLKS(12,8,3); }
+OP( 0x1f, i_pop_ds ) { POP(Sreg(DS0)); CLKS(12,8,5); }
+
+OP( 0x20, i_and_br8 ) { DEF_br8; ANDB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x21, i_and_wr16 ) { DEF_wr16; ANDW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x22, i_and_r8b ) { DEF_r8b; ANDB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x23, i_and_r16w ) { DEF_r16w; ANDW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x24, i_and_ald8 ) { DEF_ald8; ANDB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x25, i_and_axd16) { DEF_axd16; ANDW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x26, i_es ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS1)<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
+OP( 0x27, i_daa ) { ADJ4(6,0x60); CLKS(3,3,2); }
+
+OP( 0x28, i_sub_br8 ) { DEF_br8; SUBB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x29, i_sub_wr16 ) { DEF_wr16; SUBW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x2a, i_sub_r8b ) { DEF_r8b; SUBB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x2b, i_sub_r16w ) { DEF_r16w; SUBW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x2c, i_sub_ald8 ) { DEF_ald8; SUBB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x2e, i_cs ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(PS)<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
+OP( 0x2f, i_das ) { ADJ4(-6,-0x60); CLKS(3,3,2); }
+
+OP( 0x30, i_xor_br8 ) { DEF_br8; XORB; PutbackRMByte(ModRM,dst); CLKM(2,2,2,16,16,7); }
+OP( 0x31, i_xor_wr16 ) { DEF_wr16; XORW; PutbackRMWord(ModRM,dst); CLKR(24,24,11,24,16,7,2,EA);}
+OP( 0x32, i_xor_r8b ) { DEF_r8b; XORB; RegByte(ModRM)=dst; CLKM(2,2,2,11,11,6); }
+OP( 0x33, i_xor_r16w ) { DEF_r16w; XORW; RegWord(ModRM)=dst; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x34, i_xor_ald8 ) { DEF_ald8; XORB; Breg(AL)=dst; CLKS(4,4,2); }
+OP( 0x35, i_xor_axd16) { DEF_axd16; XORW; Wreg(AW)=dst; CLKS(4,4,2); }
+OP( 0x36, i_ss ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(SS)<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
+OP( 0x37, i_aaa ) { ADJB(6, (Breg(AL) > 0xf9) ? 2 : 1); CLKS(7,7,4); }
+
+OP( 0x38, i_cmp_br8 ) { DEF_br8; SUBB; CLKM(2,2,2,11,11,6); }
+OP( 0x39, i_cmp_wr16 ) { DEF_wr16; SUBW; CLKR(15,15,8,15,11,6,2,EA);}
+OP( 0x3a, i_cmp_r8b ) { DEF_r8b; SUBB; CLKM(2,2,2,11,11,6); }
+OP( 0x3b, i_cmp_r16w ) { DEF_r16w; SUBW; CLKR(15,15,8,15,11,6,2,EA); }
+OP( 0x3c, i_cmp_ald8 ) { DEF_ald8; SUBB; CLKS(4,4,2); }
+OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW; CLKS(4,4,2); }
+OP( 0x3e, i_ds ) { nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS0)<<4; CLK(2); nec_instruction[fetchop(nec_state)](nec_state); nec_state->seg_prefix=FALSE; }
+OP( 0x3f, i_aas ) { ADJB(-6, (Breg(AL) < 6) ? -2 : -1); CLKS(7,7,4); }
+
+OP( 0x40, i_inc_ax ) { IncWordReg(AW); CLK(2); }
+OP( 0x41, i_inc_cx ) { IncWordReg(CW); CLK(2); }
+OP( 0x42, i_inc_dx ) { IncWordReg(DW); CLK(2); }
+OP( 0x43, i_inc_bx ) { IncWordReg(BW); CLK(2); }
+OP( 0x44, i_inc_sp ) { IncWordReg(SP); CLK(2); }
+OP( 0x45, i_inc_bp ) { IncWordReg(BP); CLK(2); }
+OP( 0x46, i_inc_si ) { IncWordReg(IX); CLK(2); }
+OP( 0x47, i_inc_di ) { IncWordReg(IY); CLK(2); }
+
+OP( 0x48, i_dec_ax ) { DecWordReg(AW); CLK(2); }
+OP( 0x49, i_dec_cx ) { DecWordReg(CW); CLK(2); }
+OP( 0x4a, i_dec_dx ) { DecWordReg(DW); CLK(2); }
+OP( 0x4b, i_dec_bx ) { DecWordReg(BW); CLK(2); }
+OP( 0x4c, i_dec_sp ) { DecWordReg(SP); CLK(2); }
+OP( 0x4d, i_dec_bp ) { DecWordReg(BP); CLK(2); }
+OP( 0x4e, i_dec_si ) { DecWordReg(IX); CLK(2); }
+OP( 0x4f, i_dec_di ) { DecWordReg(IY); CLK(2); }
+
+OP( 0x50, i_push_ax ) { PUSH(Wreg(AW)); CLKS(12,8,3); }
+OP( 0x51, i_push_cx ) { PUSH(Wreg(CW)); CLKS(12,8,3); }
+OP( 0x52, i_push_dx ) { PUSH(Wreg(DW)); CLKS(12,8,3); }
+OP( 0x53, i_push_bx ) { PUSH(Wreg(BW)); CLKS(12,8,3); }
+OP( 0x54, i_push_sp ) { PUSH(Wreg(SP)); CLKS(12,8,3); }
+OP( 0x55, i_push_bp ) { PUSH(Wreg(BP)); CLKS(12,8,3); }
+OP( 0x56, i_push_si ) { PUSH(Wreg(IX)); CLKS(12,8,3); }
+OP( 0x57, i_push_di ) { PUSH(Wreg(IY)); CLKS(12,8,3); }
+
+OP( 0x58, i_pop_ax ) { POP(Wreg(AW)); CLKS(12,8,5); }
+OP( 0x59, i_pop_cx ) { POP(Wreg(CW)); CLKS(12,8,5); }
+OP( 0x5a, i_pop_dx ) { POP(Wreg(DW)); CLKS(12,8,5); }
+OP( 0x5b, i_pop_bx ) { POP(Wreg(BW)); CLKS(12,8,5); }
+OP( 0x5c, i_pop_sp ) { POP(Wreg(SP)); CLKS(12,8,5); }
+OP( 0x5d, i_pop_bp ) { POP(Wreg(BP)); CLKS(12,8,5); }
+OP( 0x5e, i_pop_si ) { POP(Wreg(IX)); CLKS(12,8,5); }
+OP( 0x5f, i_pop_di ) { POP(Wreg(IY)); CLKS(12,8,5); }
+
+OP( 0x60, i_pusha ) {
+ unsigned tmp=Wreg(SP);
+ PUSH(Wreg(AW));
+ PUSH(Wreg(CW));
+ PUSH(Wreg(DW));
+ PUSH(Wreg(BW));
+ PUSH(tmp);
+ PUSH(Wreg(BP));
+ PUSH(Wreg(IX));
+ PUSH(Wreg(IY));
+ CLKS(67,35,20);
+}
+OP( 0x61, i_popa ) {
+ unsigned tmp;
+ POP(Wreg(IY));
+ POP(Wreg(IX));
+ POP(Wreg(BP));
+ POP(tmp);
+ POP(Wreg(BW));
+ POP(Wreg(DW));
+ POP(Wreg(CW));
+ POP(Wreg(AW));
+ CLKS(75,43,22);
+}
+OP( 0x62, i_chkind ) {
+ UINT32 low,high,tmp;
+ GetModRM;
+ low = GetRMWord(ModRM);
+ high= GetnextRMWord;
+ tmp= RegWord(ModRM);
+ if (tmp<low || tmp>high) {
+ nec_interrupt(nec_state, 5,0);
+ }
+ nec_state->icount-=20;
+ logerror("%06x: bound %04x high %04x low %04x tmp\n",PC(nec_state),high,low,tmp);
+}
+OP( 0x64, i_repnc ) { UINT32 next = fetchop(nec_state); UINT16 c = Wreg(CW);
+ switch(next) { /* Segments */
+ case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS1)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(PS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(SS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS0)<<4; next = fetchop(nec_state); CLK(2); break;
+ }
+
+ switch(next) {
+ case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && !CF); Wreg(CW)=c; break;
+ default: logerror("%06x: REPNC invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
+ }
+ nec_state->seg_prefix=FALSE;
+}
+
+OP( 0x65, i_repc ) { UINT32 next = fetchop(nec_state); UINT16 c = Wreg(CW);
+ switch(next) { /* Segments */
+ case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS1)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(PS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(SS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS0)<<4; next = fetchop(nec_state); CLK(2); break;
+ }
+
+ switch(next) {
+ case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && CF); Wreg(CW)=c; break;
+ default: logerror("%06x: REPC invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
+ }
+ nec_state->seg_prefix=FALSE;
+}
+
+OP( 0x68, i_push_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(tmp); CLKW(12,12,5,12,8,5,Wreg(SP)); }
+OP( 0x69, i_imul_d16 ) { UINT32 tmp; DEF_r16w; tmp = FETCHWORD(); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); nec_state->CarryVal = nec_state->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; nec_state->icount-=(ModRM >=0xc0 )?38:47;}
+OP( 0x6a, i_push_d8 ) { UINT32 tmp = (WORD)((INT16)((INT8)FETCH())); PUSH(tmp); CLKW(11,11,5,11,7,3,Wreg(SP)); }
+OP( 0x6b, i_imul_d8 ) { UINT32 src2; DEF_r16w; src2= (WORD)((INT16)((INT8)FETCH())); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); nec_state->CarryVal = nec_state->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; nec_state->icount-=(ModRM >=0xc0 )?31:39; }
+OP( 0x6c, i_insb ) { PutMemB(DS1,Wreg(IY),read_port_byte(Wreg(DW))); Wreg(IY)+= -2 * nec_state->DF + 1; CLK(8); }
+OP( 0x6d, i_insw ) { PutMemW(DS1,Wreg(IY),read_port_word(Wreg(DW))); Wreg(IY)+= -4 * nec_state->DF + 2; CLKS(18,10,8); }
+OP( 0x6e, i_outsb ) { write_port_byte(Wreg(DW),GetMemB(DS0,Wreg(IX))); Wreg(IX)+= -2 * nec_state->DF + 1; CLK(8); }
+OP( 0x6f, i_outsw ) { write_port_word(Wreg(DW),GetMemW(DS0,Wreg(IX))); Wreg(IX)+= -4 * nec_state->DF + 2; CLKS(18,10,8); }
+
+OP( 0x70, i_jo ) { JMP( OF); CLKS(4,4,3); }
+OP( 0x71, i_jno ) { JMP(!OF); CLKS(4,4,3); }
+OP( 0x72, i_jc ) { JMP( CF); CLKS(4,4,3); }
+OP( 0x73, i_jnc ) { JMP(!CF); CLKS(4,4,3); }
+OP( 0x74, i_jz ) { JMP( ZF); CLKS(4,4,3); }
+OP( 0x75, i_jnz ) { JMP(!ZF); CLKS(4,4,3); }
+OP( 0x76, i_jce ) { JMP(CF || ZF); CLKS(4,4,3); }
+OP( 0x77, i_jnce ) { JMP(!(CF || ZF)); CLKS(4,4,3); }
+OP( 0x78, i_js ) { JMP( SF); CLKS(4,4,3); }
+OP( 0x79, i_jns ) { JMP(!SF); CLKS(4,4,3); }
+OP( 0x7a, i_jp ) { JMP( PF); CLKS(4,4,3); }
+OP( 0x7b, i_jnp ) { JMP(!PF); CLKS(4,4,3); }
+OP( 0x7c, i_jl ) { JMP((SF!=OF)&&(!ZF)); CLKS(4,4,3); }
+OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); CLKS(4,4,3); }
+OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); CLKS(4,4,3); }
+OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); CLKS(4,4,3); }
+
+OP( 0x80, i_80pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH();
+ if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
+ switch (ModRM & 0x38) {
+ case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
+ case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
+ case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
+ case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
+ case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
+ case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
+ case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
+ case 0x38: SUBB; break; /* CMP */
+ }
+}
+
+OP( 0x81, i_81pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8);
+ if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,EA) else CLKW(26,26,11,26,18,7,EA)
+ switch (ModRM & 0x38) {
+ case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
+ case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
+ case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
+ case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
+ case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
+ case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
+ case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
+ case 0x38: SUBW; break; /* CMP */
+ }
+}
+
+OP( 0x82, i_82pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((INT8)FETCH());
+ if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7)
+ switch (ModRM & 0x38) {
+ case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
+ case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
+ case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
+ case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
+ case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
+ case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
+ case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
+ case 0x38: SUBB; break; /* CMP */
+ }
+}
+
+OP( 0x83, i_83pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((INT16)((INT8)FETCH()));
+ if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,EA) else CLKW(26,26,11,26,18,7,EA)
+ switch (ModRM & 0x38) {
+ case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
+ case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
+ case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
+ case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
+ case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
+ case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
+ case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
+ case 0x38: SUBW; break; /* CMP */
+ }
+}
+
+OP( 0x84, i_test_br8 ) { DEF_br8; ANDB; CLKM(2,2,2,10,10,6); }
+OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW; CLKR(14,14,8,14,10,6,2,EA); }
+OP( 0x86, i_xchg_br8 ) { DEF_br8; RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(3,3,3,16,18,8); }
+OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKR(24,24,12,24,16,8,3,EA); }
+
+OP( 0x88, i_mov_br8 ) { UINT8 src; GetModRM; src = RegByte(ModRM); PutRMByte(ModRM,src); CLKM(2,2,2,9,9,3); }
+OP( 0x89, i_mov_wr16 ) { UINT16 src; GetModRM; src = RegWord(ModRM); PutRMWord(ModRM,src); CLKR(13,13,5,13,9,3,2,EA); }
+OP( 0x8a, i_mov_r8b ) { UINT8 src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src; CLKM(2,2,2,11,11,5); }
+OP( 0x8b, i_mov_r16w ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src; CLKR(15,15,7,15,11,5,2,EA); }
+OP( 0x8c, i_mov_wsreg ) { GetModRM;
+ switch (ModRM & 0x38) {
+ case 0x00: PutRMWord(ModRM,Sreg(DS1)); CLKR(14,14,5,14,10,3,2,EA); break;
+ case 0x08: PutRMWord(ModRM,Sreg(PS)); CLKR(14,14,5,14,10,3,2,EA); break;
+ case 0x10: PutRMWord(ModRM,Sreg(SS)); CLKR(14,14,5,14,10,3,2,EA); break;
+ case 0x18: PutRMWord(ModRM,Sreg(DS0)); CLKR(14,14,5,14,10,3,2,EA); break;
+ default: logerror("%06x: MOV Sreg - Invalid register\n",PC(nec_state));
+ }
+}
+OP( 0x8d, i_lea ) { UINT16 ModRM = FETCH(); (void)(*GetEA[ModRM])(nec_state); RegWord(ModRM)=EO; CLKS(4,4,2); }
+OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,EA);
+ switch (ModRM & 0x38) {
+ case 0x00: Sreg(DS1) = src; break; /* mov es,ew */
+ case 0x08: Sreg(PS) = src; break; /* mov cs,ew */
+ case 0x10: Sreg(SS) = src; break; /* mov ss,ew */
+ case 0x18: Sreg(DS0) = src; break; /* mov ds,ew */
+ default: logerror("%06x: MOV Sreg - Invalid register\n",PC(nec_state));
+ }
+ nec_state->no_interrupt=1;
+}
+OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); nec_state->icount-=21; }
+OP( 0x90, i_nop ) { CLK(3); }
+OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); }
+OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); }
+OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); }
+OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); }
+OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); }
+OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); }
+OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); }
+
+OP( 0x98, i_cbw ) { Breg(AH) = (Breg(AL) & 0x80) ? 0xff : 0; CLK(2); }
+OP( 0x99, i_cwd ) { Wreg(DW) = (Breg(AH) & 0x80) ? 0xffff : 0; CLK(4); }
+OP( 0x9a, i_call_far ) { UINT32 tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(Sreg(PS)); PUSH(nec_state->ip); nec_state->ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); }
+OP( 0x9b, i_wait ) { if (!nec_state->poll_state) nec_state->ip--; CLK(5); }
+OP( 0x9c, i_pushf ) { UINT16 tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); }
+OP( 0x9d, i_popf ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (nec_state->TF) nec_trap(nec_state); }
+OP( 0x9e, i_sahf ) { UINT32 tmp = (CompressFlags() & 0xff00) | (Breg(AH) & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); }
+OP( 0x9f, i_lahf ) { Breg(AH) = CompressFlags() & 0xff; CLKS(3,3,2); }
+
+OP( 0xa0, i_mov_aldisp ) { UINT32 addr; addr = FETCHWORD(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); }
+OP( 0xa1, i_mov_axdisp ) { UINT32 addr; addr = FETCHWORD(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); }
+OP( 0xa2, i_mov_dispal ) { UINT32 addr; addr = FETCHWORD(); PutMemB(DS0, addr, Breg(AL)); CLKS(9,9,3); }
+OP( 0xa3, i_mov_dispax ) { UINT32 addr; addr = FETCHWORD(); PutMemW(DS0, addr, Wreg(AW)); CLKW(13,13,5,13,9,3,addr); }
+OP( 0xa4, i_movsb ) { UINT32 tmp = GetMemB(DS0,Wreg(IX)); PutMemB(DS1,Wreg(IY), tmp); Wreg(IY) += -2 * nec_state->DF + 1; Wreg(IX) += -2 * nec_state->DF + 1; CLKS(8,8,6); }
+OP( 0xa5, i_movsw ) { UINT32 tmp = GetMemW(DS0,Wreg(IX)); PutMemW(DS1,Wreg(IY), tmp); Wreg(IY) += -4 * nec_state->DF + 2; Wreg(IX) += -4 * nec_state->DF + 2; CLKS(16,16,10); }
+OP( 0xa6, i_cmpsb ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = GetMemB(DS0, Wreg(IX)); SUBB; Wreg(IY) += -2 * nec_state->DF + 1; Wreg(IX) += -2 * nec_state->DF + 1; CLKS(14,14,14); }
+OP( 0xa7, i_cmpsw ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = GetMemW(DS0, Wreg(IX)); SUBW; Wreg(IY) += -4 * nec_state->DF + 2; Wreg(IX) += -4 * nec_state->DF + 2; CLKS(14,14,14); }
+
+OP( 0xa8, i_test_ald8 ) { DEF_ald8; ANDB; CLKS(4,4,2); }
+OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLKS(4,4,2); }
+OP( 0xaa, i_stosb ) { PutMemB(DS1,Wreg(IY),Breg(AL)); Wreg(IY) += -2 * nec_state->DF + 1; CLKS(4,4,3); }
+OP( 0xab, i_stosw ) { PutMemW(DS1,Wreg(IY),Wreg(AW)); Wreg(IY) += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
+OP( 0xac, i_lodsb ) { Breg(AL) = GetMemB(DS0,Wreg(IX)); Wreg(IX) += -2 * nec_state->DF + 1; CLKS(4,4,3); }
+OP( 0xad, i_lodsw ) { Wreg(AW) = GetMemW(DS0,Wreg(IX)); Wreg(IX) += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,Wreg(IX)); }
+OP( 0xae, i_scasb ) { UINT32 src = GetMemB(DS1, Wreg(IY)); UINT32 dst = Breg(AL); SUBB; Wreg(IY) += -2 * nec_state->DF + 1; CLKS(4,4,3); }
+OP( 0xaf, i_scasw ) { UINT32 src = GetMemW(DS1, Wreg(IY)); UINT32 dst = Wreg(AW); SUBW; Wreg(IY) += -4 * nec_state->DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); }
+
+OP( 0xb0, i_mov_ald8 ) { Breg(AL) = FETCH(); CLKS(4,4,2); }
+OP( 0xb1, i_mov_cld8 ) { Breg(CL) = FETCH(); CLKS(4,4,2); }
+OP( 0xb2, i_mov_dld8 ) { Breg(DL) = FETCH(); CLKS(4,4,2); }
+OP( 0xb3, i_mov_bld8 ) { Breg(BL) = FETCH(); CLKS(4,4,2); }
+OP( 0xb4, i_mov_ahd8 ) { Breg(AH) = FETCH(); CLKS(4,4,2); }
+OP( 0xb5, i_mov_chd8 ) { Breg(CH) = FETCH(); CLKS(4,4,2); }
+OP( 0xb6, i_mov_dhd8 ) { Breg(DH) = FETCH(); CLKS(4,4,2); }
+OP( 0xb7, i_mov_bhd8 ) { Breg(BH) = FETCH(); CLKS(4,4,2); }
+
+OP( 0xb8, i_mov_axd16 ) { Breg(AL) = FETCH(); Breg(AH) = FETCH(); CLKS(4,4,2); }
+OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = FETCH(); Breg(CH) = FETCH(); CLKS(4,4,2); }
+OP( 0xba, i_mov_dxd16 ) { Breg(DL) = FETCH(); Breg(DH) = FETCH(); CLKS(4,4,2); }
+OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = FETCH(); Breg(BH) = FETCH(); CLKS(4,4,2); }
+OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = FETCHWORD(); CLKS(4,4,2); }
+OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = FETCHWORD(); CLKS(4,4,2); }
+OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = FETCHWORD(); CLKS(4,4,2); }
+OP( 0xbf, i_mov_did16 ) { Wreg(IY) = FETCHWORD(); CLKS(4,4,2); }
+
+OP( 0xc0, i_rotshft_bd8 ) {
+ UINT32 src, dst; UINT8 c;
+ GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src;
+ c=FETCH();
+ CLKM(7,7,2,19,19,6);
+ if (c) switch (ModRM & 0x38) {
+ case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x08: do { ROR_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x20: SHL_BYTE(c); break;
+ case 0x28: SHR_BYTE(c); break;
+ case 0x30: logerror("%06x: Undefined opcode 0xc0 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_BYTE(c); break;
+ }
+}
+
+OP( 0xc1, i_rotshft_wd8 ) {
+ UINT32 src, dst; UINT8 c;
+ GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src;
+ c=FETCH();
+ CLKM(7,7,2,27,19,6);
+ if (c) switch (ModRM & 0x38) {
+ case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x08: do { ROR_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x20: SHL_WORD(c); break;
+ case 0x28: SHR_WORD(c); break;
+ case 0x30: logerror("%06x: Undefined opcode 0xc1 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_WORD(c); break;
+ }
+}
+
+OP( 0xc2, i_ret_d16 ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(nec_state->ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); }
+OP( 0xc3, i_ret ) { POP(nec_state->ip); CHANGE_PC; CLKS(19,19,10); }
+OP( 0xc4, i_les_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS1) = GetnextRMWord; CLKW(26,26,14,26,18,10,EA); }
+OP( 0xc5, i_lds_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS0) = GetnextRMWord; CLKW(26,26,14,26,18,10,EA); }
+OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); nec_state->icount-=(ModRM >=0xc0 )?4:11; }
+OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); nec_state->icount-=(ModRM >=0xc0 )?4:15; }
+
+OP( 0xc8, i_enter ) {
+ UINT32 nb = FETCH();
+ UINT32 i,level;
+
+ nec_state->icount-=23;
+ nb += FETCH() << 8;
+ level = FETCH();
+ PUSH(Wreg(BP));
+ Wreg(BP)=Wreg(SP);
+ Wreg(SP) -= nb;
+ for (i=1;i<level;i++) {
+ PUSH(GetMemW(SS,Wreg(BP)-i*2));
+ nec_state->icount-=16;
+ }
+ if (level) PUSH(Wreg(BP));
+}
+OP( 0xc9, i_leave ) {
+ Wreg(SP)=Wreg(BP);
+ POP(Wreg(BP));
+ nec_state->icount-=8;
+}
+OP( 0xca, i_retf_d16 ) { UINT32 count = FETCH(); count += FETCH() << 8; POP(nec_state->ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); }
+OP( 0xcb, i_retf ) { POP(nec_state->ip); POP(Sreg(PS)); CHANGE_PC; CLKS(29,29,16); }
+OP( 0xcc, i_int3 ) { nec_interrupt(nec_state, 3,0); CLKS(50,50,24); }
+OP( 0xcd, i_int ) { nec_interrupt(nec_state, FETCH(),0); CLKS(50,50,24); }
+OP( 0xce, i_into ) { if (OF) { nec_interrupt(nec_state, 4,0); CLKS(52,52,26); } else CLK(3); }
+OP( 0xcf, i_iret ) { POP(nec_state->ip); POP(Sreg(PS)); i_popf(nec_state); CHANGE_PC; CLKS(39,39,19); }
+
+OP( 0xd0, i_rotshft_b ) {
+ UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
+ CLKM(6,6,2,16,16,7);
+ switch (ModRM & 0x38) {
+ case 0x00: ROL_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x08: ROR_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x20: SHL_BYTE(1); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x28: SHR_BYTE(1); nec_state->OverVal = (src^dst)&0x80; break;
+ case 0x30: logerror("%06x: Undefined opcode 0xd0 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_BYTE(1); nec_state->OverVal = 0; break;
+ }
+}
+
+OP( 0xd1, i_rotshft_w ) {
+ UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
+ CLKM(6,6,2,24,16,7);
+ switch (ModRM & 0x38) {
+ case 0x00: ROL_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x08: ROR_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x18: RORC_WORD; PutbackRMWord(ModRM,(WORD)dst); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x20: SHL_WORD(1); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x28: SHR_WORD(1); nec_state->OverVal = (src^dst)&0x8000; break;
+ case 0x30: logerror("%06x: Undefined opcode 0xd1 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_WORD(1); nec_state->OverVal = 0; break;
+ }
+}
+
+OP( 0xd2, i_rotshft_bcl ) {
+ UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
+ c=Breg(CL);
+ CLKM(7,7,2,19,19,6);
+ if (c) switch (ModRM & 0x38) {
+ case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x08: do { ROR_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
+ case 0x20: SHL_BYTE(c); break;
+ case 0x28: SHR_BYTE(c); break;
+ case 0x30: logerror("%06x: Undefined opcode 0xd2 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_BYTE(c); break;
+ }
+}
+
+OP( 0xd3, i_rotshft_wcl ) {
+ UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
+ c=Breg(CL);
+ CLKM(7,7,2,27,19,6);
+ if (c) switch (ModRM & 0x38) {
+ case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x08: do { ROR_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
+ case 0x20: SHL_WORD(c); break;
+ case 0x28: SHR_WORD(c); break;
+ case 0x30: logerror("%06x: Undefined opcode 0xd3 0x30 (SHLA)\n",PC(nec_state)); break;
+ case 0x38: SHRA_WORD(c); break;
+ }
+}
+
+OP( 0xd4, i_aam ) { UINT32 mult=FETCH(); mult=0; Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); }
+OP( 0xd5, i_aad ) { UINT32 mult=FETCH(); mult=0; Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); }
+OP( 0xd6, i_setalc ) { Breg(AL) = (CF)?0xff:0x00; nec_state->icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC(nec_state)); }
+OP( 0xd7, i_trans ) { UINT32 dest = (Wreg(BW)+Breg(AL))&0xffff; Breg(AL) = GetMemB(DS0, dest); CLKS(9,9,5); }
+OP( 0xd8, i_fpo ) { GetModRM; nec_state->icount-=2; logerror("%06x: Unimplemented floating point control %04x\n",PC(nec_state),ModRM); }
+
+OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (!ZF && Wreg(CW)) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
+OP( 0xe1, i_loope ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if ( ZF && Wreg(CW)) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); }
+OP( 0xe2, i_loop ) { INT8 disp = (INT8)FETCH(); Wreg(CW)--; if (Wreg(CW)) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
+OP( 0xe3, i_jcxz ) { INT8 disp = (INT8)FETCH(); if (Wreg(CW) == 0) { nec_state->ip = (WORD)(nec_state->ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); }
+OP( 0xe4, i_inal ) { UINT8 port = FETCH(); Breg(AL) = read_port_byte(port); CLKS(9,9,5); }
+OP( 0xe5, i_inax ) { UINT8 port = FETCH(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); }
+OP( 0xe6, i_outal ) { UINT8 port = FETCH(); write_port_byte(port, Breg(AL)); CLKS(8,8,3); }
+OP( 0xe7, i_outax ) { UINT8 port = FETCH(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port); }
+
+OP( 0xe8, i_call_d16 ) { UINT32 tmp; tmp = FETCHWORD(); PUSH(nec_state->ip); nec_state->ip = (WORD)(nec_state->ip+(INT16)tmp); CHANGE_PC; nec_state->icount-=24; }
+OP( 0xe9, i_jmp_d16 ) { UINT32 tmp; tmp = FETCHWORD(); nec_state->ip = (WORD)(nec_state->ip+(INT16)tmp); CHANGE_PC; nec_state->icount-=15; }
+OP( 0xea, i_jmp_far ) { UINT32 tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); Sreg(PS) = (WORD)tmp1; nec_state->ip = (WORD)tmp; CHANGE_PC; nec_state->icount-=27; }
+OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((INT8)FETCH()); nec_state->icount-=12; nec_state->ip = (WORD)(nec_state->ip+tmp); }
+OP( 0xec, i_inaldx ) { Breg(AL) = read_port_byte(Wreg(DW)); CLKS(8,8,5);}
+OP( 0xed, i_inaxdx ) { Wreg(AW) = read_port_word(Wreg(DW)); CLKW(12,12,7,12,8,5,Wreg(DW)); }
+OP( 0xee, i_outdxal ) { write_port_byte(Wreg(DW), Breg(AL)); CLKS(8,8,3); }
+OP( 0xef, i_outdxax ) { write_port_word(Wreg(DW), Wreg(AW)); CLKW(12,12,5,12,8,3,Wreg(DW)); }
+
+OP( 0xf0, i_lock ) { logerror("%06x: Warning - BUSLOCK\n",PC(nec_state)); nec_state->no_interrupt=1; CLK(2); }
+OP( 0xf2, i_repne ) { UINT32 next = fetchop(nec_state); UINT16 c = Wreg(CW);
+ switch(next) { /* Segments */
+ case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS1)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(PS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(SS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS0)<<4; next = fetchop(nec_state); CLK(2); break;
+ }
+
+ switch(next) {
+ case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && ZF==0); Wreg(CW)=c; break;
+ case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && ZF==0); Wreg(CW)=c; break;
+ case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && ZF==0); Wreg(CW)=c; break;
+ case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && ZF==0); Wreg(CW)=c; break;
+ default: logerror("%06x: REPNE invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
+ }
+ nec_state->seg_prefix=FALSE;
+}
+OP( 0xf3, i_repe ) { UINT32 next = fetchop(nec_state); UINT16 c = Wreg(CW);
+ switch(next) { /* Segments */
+ case 0x26: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS1)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x2e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(PS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x36: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(SS)<<4; next = fetchop(nec_state); CLK(2); break;
+ case 0x3e: nec_state->seg_prefix=TRUE; nec_state->prefix_base=Sreg(DS0)<<4; next = fetchop(nec_state); CLK(2); break;
+ }
+
+ switch(next) {
+ case 0x6c: CLK(2); if (c) do { i_insb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6d: CLK(2); if (c) do { i_insw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6e: CLK(2); if (c) do { i_outsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0x6f: CLK(2); if (c) do { i_outsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa4: CLK(2); if (c) do { i_movsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa5: CLK(2); if (c) do { i_movsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xa6: CLK(2); if (c) do { i_cmpsb(nec_state); c--; } while (c>0 && ZF==1); Wreg(CW)=c; break;
+ case 0xa7: CLK(2); if (c) do { i_cmpsw(nec_state); c--; } while (c>0 && ZF==1); Wreg(CW)=c; break;
+ case 0xaa: CLK(2); if (c) do { i_stosb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xab: CLK(2); if (c) do { i_stosw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xac: CLK(2); if (c) do { i_lodsb(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xad: CLK(2); if (c) do { i_lodsw(nec_state); c--; } while (c>0); Wreg(CW)=c; break;
+ case 0xae: CLK(2); if (c) do { i_scasb(nec_state); c--; } while (c>0 && ZF==1); Wreg(CW)=c; break;
+ case 0xaf: CLK(2); if (c) do { i_scasw(nec_state); c--; } while (c>0 && ZF==1); Wreg(CW)=c; break;
+ default: logerror("%06x: REPE invalid\n",PC(nec_state)); nec_instruction[next](nec_state);
+ }
+ nec_state->seg_prefix=FALSE;
+}
+OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC(nec_state)); 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);
+ switch (ModRM & 0x38) {
+ case 0x00: tmp &= FETCH(); nec_state->CarryVal = nec_state->OverVal = 0; SetSZPF_Byte(tmp); nec_state->icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
+ case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC(nec_state)); break;
+ case 0x10: PutbackRMByte(ModRM,~tmp); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
+ case 0x18: nec_state->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
+ case 0x20: uresult = Breg(AL)*tmp; Wreg(AW)=(WORD)uresult; nec_state->CarryVal=nec_state->OverVal=(Breg(AH)!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
+ case 0x28: result = (INT16)((INT8)Breg(AL))*(INT16)((INT8)tmp); Wreg(AW)=(WORD)result; nec_state->CarryVal=nec_state->OverVal=(Breg(AH)!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
+ case 0x30: if (tmp) { DIVUB; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
+ case 0x38: if (tmp) { DIVB; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
+ }
+}
+
+OP( 0xf7, i_f7pre ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2;
+ GetModRM; tmp = GetRMWord(ModRM);
+ switch (ModRM & 0x38) {
+ case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; nec_state->CarryVal = nec_state->OverVal = 0; SetSZPF_Word(tmp); nec_state->icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */
+ case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC(nec_state)); break;
+ case 0x10: PutbackRMWord(ModRM,~tmp); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */
+ case 0x18: nec_state->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); nec_state->icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */
+ case 0x20: uresult = Wreg(AW)*tmp; Wreg(AW)=uresult&0xffff; Wreg(DW)=((UINT32)uresult)>>16; nec_state->CarryVal=nec_state->OverVal=(Wreg(DW)!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MULU */
+ case 0x28: result = (INT32)((INT16)Wreg(AW))*(INT32)((INT16)tmp); Wreg(AW)=result&0xffff; Wreg(DW)=result>>16; nec_state->CarryVal=nec_state->OverVal=(Wreg(DW)!=0); nec_state->icount-=(ModRM >=0xc0 )?30:36; break; /* MUL */
+ case 0x30: if (tmp) { DIVUW; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
+ case 0x38: if (tmp) { DIVW; } else nec_interrupt(nec_state, 0,0); nec_state->icount-=(ModRM >=0xc0 )?43:53; break;
+ }
+}
+
+OP( 0xf8, i_clc ) { nec_state->CarryVal = 0; CLK(2); }
+OP( 0xf9, i_stc ) { nec_state->CarryVal = 1; CLK(2); }
+OP( 0xfa, i_di ) { SetIF(0); CLK(2); }
+OP( 0xfb, i_ei ) { SetIF(1); CLK(2); }
+OP( 0xfc, i_cld ) { SetDF(0); CLK(2); }
+OP( 0xfd, i_std ) { SetDF(1); CLK(2); }
+OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM);
+ switch(ModRM & 0x38) {
+ case 0x00: tmp1 = tmp+1; nec_state->OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* INC */
+ case 0x08: tmp1 = tmp-1; nec_state->OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(2,2,2,16,16,7); break; /* DEC */
+ default: logerror("%06x: FE Pre with unimplemented mod\n",PC(nec_state));
+ }
+}
+OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM);
+ switch(ModRM & 0x38) {
+ case 0x00: tmp1 = tmp+1; nec_state->OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* INC */
+ case 0x08: tmp1 = tmp-1; nec_state->OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(2,2,2,24,16,7); break; /* DEC */
+ case 0x10: PUSH(nec_state->ip); nec_state->ip = (WORD)tmp; CHANGE_PC; nec_state->icount-=(ModRM >=0xc0 )?16:20; break; /* CALL */
+ case 0x18: tmp1 = Sreg(PS); Sreg(PS) = GetnextRMWord; PUSH(tmp1); PUSH(nec_state->ip); nec_state->ip = tmp; CHANGE_PC; nec_state->icount-=(ModRM >=0xc0 )?16:26; break; /* CALL FAR */
+ case 0x20: nec_state->ip = tmp; CHANGE_PC; nec_state->icount-=13; break; /* JMP */
+ case 0x28: nec_state->ip = tmp; Sreg(PS) = GetnextRMWord; CHANGE_PC; nec_state->icount-=15; break; /* JMP FAR */
+ case 0x30: PUSH(tmp); nec_state->icount-=4; break;
+ default: logerror("%06x: FF Pre with unimplemented mod\n",PC(nec_state));
+ }
+}
+
+static void i_invalid(nec_state_t *nec_state)
+{
+ nec_state->icount-=10;
+ logerror("%06x: Invalid Opcode\n",PC(nec_state));
+}
diff --git a/src/emu/cpu/nec/necinstr.h b/src/emu/cpu/nec/necinstr.h
index 07e118583b5..30bc3ffcbb2 100644
--- a/src/emu/cpu/nec/necinstr.h
+++ b/src/emu/cpu/nec/necinstr.h
@@ -97,7 +97,6 @@ static void i_pop_di(nec_state_t *nec_state);
static void i_pusha(nec_state_t *nec_state);
static void i_popa(nec_state_t *nec_state);
static void i_chkind(nec_state_t *nec_state);
-static void i_brkn(nec_state_t *nec_state);
static void i_repnc(nec_state_t *nec_state);
static void i_repc(nec_state_t *nec_state);
static void i_push_d16(nec_state_t *nec_state);
@@ -348,7 +347,7 @@ static void (*const nec_instruction[256])(nec_state_t *nec_state) =
i_pusha, /* 0x60 */
i_popa, /* 0x61 */
i_chkind, /* 0x62 */
- i_brkn, /* 0x63 - V25S/V35S only */
+ i_invalid, /* 0x63 */
i_repnc, /* 0x64 */
i_repc, /* 0x65 */
i_invalid, /* 0x66 */
diff --git a/src/emu/cpu/nec/necmodrm.h b/src/emu/cpu/nec/necmodrm.h
index e21519fcddc..cf8956b8106 100644
--- a/src/emu/cpu/nec/necmodrm.h
+++ b/src/emu/cpu/nec/necmodrm.h
@@ -9,15 +9,15 @@ static struct {
} RM;
} Mod_RM;
-#define RegWord(ModRM) nec_state->regs.w[Mod_RM.reg.w[ModRM]]
-#define RegByte(ModRM) nec_state->regs.b[Mod_RM.reg.b[ModRM]]
+#define RegWord(ModRM) Wreg(Mod_RM.reg.w[ModRM])
+#define RegByte(ModRM) Breg(Mod_RM.reg.b[ModRM])
#define GetRMWord(ModRM) \
- ((ModRM) >= 0xc0 ? nec_state->regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(nec_state), read_mem_word( EA ) ))
+ ((ModRM) >= 0xc0 ? Wreg(Mod_RM.RM.w[ModRM]) : ( (*GetEA[ModRM])(nec_state), read_mem_word( EA ) ))
#define PutbackRMWord(ModRM,val) \
{ \
- if (ModRM >= 0xc0) nec_state->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ if (ModRM >= 0xc0) Wreg(Mod_RM.RM.w[ModRM])=val; \
else write_mem_word(EA,val); \
}
@@ -26,7 +26,7 @@ static struct {
#define PutRMWord(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
- nec_state->regs.w[Mod_RM.RM.w[ModRM]]=val; \
+ Wreg(Mod_RM.RM.w[ModRM])=val; \
else { \
(*GetEA[ModRM])(nec_state); \
write_mem_word( EA ,val); \
@@ -37,7 +37,7 @@ static struct {
{ \
WORD val; \
if (ModRM >= 0xc0) \
- nec_state->regs.w[Mod_RM.RM.w[ModRM]] = FETCHWORD(); \
+ Wreg(Mod_RM.RM.w[ModRM]) = FETCHWORD(); \
else { \
(*GetEA[ModRM])(nec_state); \
val = FETCHWORD(); \
@@ -46,12 +46,12 @@ static struct {
}
#define GetRMByte(ModRM) \
- ((ModRM) >= 0xc0 ? nec_state->regs.b[Mod_RM.RM.b[ModRM]] : read_mem_byte( (*GetEA[ModRM])(nec_state) ))
+ ((ModRM) >= 0xc0 ? Breg(Mod_RM.RM.b[ModRM]) : read_mem_byte( (*GetEA[ModRM])(nec_state) ))
#define PutRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
- nec_state->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ Breg(Mod_RM.RM.b[ModRM])=val; \
else \
write_mem_byte( (*GetEA[ModRM])(nec_state) ,val); \
}
@@ -59,7 +59,7 @@ static struct {
#define PutImmRMByte(ModRM) \
{ \
if (ModRM >= 0xc0) \
- nec_state->regs.b[Mod_RM.RM.b[ModRM]]=FETCH(); \
+ Breg(Mod_RM.RM.b[ModRM])=FETCH(); \
else { \
(*GetEA[ModRM])(nec_state); \
write_mem_byte( EA , FETCH() ); \
@@ -69,7 +69,7 @@ static struct {
#define PutbackRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
- nec_state->regs.b[Mod_RM.RM.b[ModRM]]=val; \
+ Breg(Mod_RM.RM.b[ModRM])=val; \
else \
write_mem_byte(EA,val); \
}
@@ -96,9 +96,9 @@ static struct {
#define DEF_ald8 \
UINT32 src = FETCH(); \
- UINT32 dst = nec_state->regs.b[AL]
+ UINT32 dst = Breg(AL)
#define DEF_axd16 \
UINT32 src = FETCH(); \
- UINT32 dst = nec_state->regs.w[AW]; \
+ UINT32 dst = Wreg(AW); \
src += (FETCH() << 8)
diff --git a/src/emu/cpu/nec/necpriv.h b/src/emu/cpu/nec/necpriv.h
index 5c8ca972fd4..aa7e52a0220 100644
--- a/src/emu/cpu/nec/necpriv.h
+++ b/src/emu/cpu/nec/necpriv.h
@@ -1,7 +1,3 @@
-
-typedef enum { DS1, PS, SS, DS0 } SREGS;
-typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
-
#define NEC_NMI_INT_VECTOR 2
/* Cpu types, steps of 8 to help the cycle count calculation */
@@ -14,6 +10,51 @@ typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
#define TRUE 1
#endif
+/* NEC registers */
+typedef union
+{ /* eight general registers */
+ UINT16 w[8]; /* viewed as 16 bits registers */
+ UINT8 b[16]; /* or as 8 bit registers */
+} necbasicregs;
+
+typedef struct _nec_state_t nec_state_t;
+struct _nec_state_t
+{
+ necbasicregs regs;
+ offs_t fetch_xor;
+ UINT16 sregs[4];
+
+ UINT16 ip;
+
+ INT32 SignVal;
+ UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
+ UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */
+ UINT32 int_vector;
+ UINT32 pending_irq;
+ UINT32 nmi_state;
+ UINT32 irq_state;
+ UINT32 poll_state;
+ UINT8 no_interrupt;
+
+ device_irq_callback irq_callback;
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ address_space *io;
+ int icount;
+
+ UINT8 prefetch_size;
+ UINT8 prefetch_cycles;
+ INT8 prefetch_count;
+ UINT8 prefetch_reset;
+ UINT32 chip_type;
+
+ UINT32 prefix_base; /* base address of the latest prefix segment */
+ UINT8 seg_prefix; /* prefix segment indicator */
+};
+
+typedef enum { DS1, PS, SS, DS0 } SREGS;
+typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
typedef enum {
AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1),
AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0),
@@ -23,16 +64,12 @@ typedef enum {
DH = NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4),
BL = NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7),
BH = NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6),
- SPL = NATIVE_ENDIAN_VALUE_LE_BE(0x8, 0x9),
- SPH = NATIVE_ENDIAN_VALUE_LE_BE(0x9, 0x8),
- BPL = NATIVE_ENDIAN_VALUE_LE_BE(0xa, 0xb),
- BPH = NATIVE_ENDIAN_VALUE_LE_BE(0xb, 0xa),
- IXL = NATIVE_ENDIAN_VALUE_LE_BE(0xc, 0xd),
- IXH = NATIVE_ENDIAN_VALUE_LE_BE(0xd, 0xc),
- IYL = NATIVE_ENDIAN_VALUE_LE_BE(0xe, 0xf),
- IYH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe)
} BREGS;
+#define Sreg(x) nec_state->sregs[x]
+#define Wreg(x) nec_state->regs.w[x]
+#define Breg(x) nec_state->regs.b[x]
+
/* parameter x = result, y = source 1, z = source 2 */
#define SetTF(x) (nec_state->TF = (x))
@@ -76,7 +113,6 @@ typedef enum {
#define PF parity_table[(BYTE)nec_state->ParityVal]
#define AF (nec_state->AuxVal!=0)
#define OF (nec_state->OverVal!=0)
-#define MD (nec_state->MF!=0)
/************************************************************************/
@@ -94,9 +130,9 @@ typedef enum {
#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0)
-#define SegBase(Seg) (nec_state->sregs[Seg] << 4)
+#define SegBase(Seg) (Sreg(Seg) << 4)
-#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : nec_state->sregs[Seg] << 4)
+#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : Sreg(Seg) << 4)
#define GetMemB(Seg,Off) (read_mem_byte(DefaultBase(Seg) + (Off)))
#define GetMemW(Seg,Off) (read_mem_word(DefaultBase(Seg) + (Off)))
@@ -112,8 +148,8 @@ typedef enum {
#define EMPTY_PREFETCH() nec_state->prefetch_reset = 1
-#define PUSH(val) { nec_state->regs.w[SP]-=2; write_mem_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP])),val); }
-#define POP(var) { var = read_mem_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP]))); nec_state->regs.w[SP]+=2; }
+#define PUSH(val) { Wreg(SP)-=2; write_mem_word((((Sreg(SS)<<4)+Wreg(SP))),val); }
+#define POP(var) { var = read_mem_word((((Sreg(SS)<<4)+Wreg(SP)))); Wreg(SP)+=2; }
#define GetModRM UINT32 ModRM=FETCH()
@@ -136,39 +172,39 @@ typedef enum {
#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_state->icount-=vall; else nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
/************************************************************************/
-#define CompressFlags() (WORD)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
+#define CompressFlags() (WORD)(CF | 0x02 | (PF << 2) | (AF << 4) | (ZF << 6) \
| (SF << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \
- | (nec_state->DF << 10) | (OF << 11)| (MD << 15))
+ | (nec_state->DF << 10) | (OF << 11) | (nec_state->MF << 15))
#define ExpandFlags(f) \
{ \
- nec_state->CarryVal = (f) & 1; \
- nec_state->ParityVal = !((f) & 4); \
- nec_state->AuxVal = (f) & 16; \
- nec_state->ZeroVal = !((f) & 64); \
- nec_state->SignVal = (f) & 128 ? -1 : 0; \
- nec_state->TF = ((f) & 256) == 256; \
- nec_state->IF = ((f) & 512) == 512; \
- nec_state->DF = ((f) & 1024) == 1024; \
- nec_state->OverVal = (f) & 2048; \
+ nec_state->CarryVal = (f) & 0x0001; \
+ nec_state->ParityVal = !((f) & 0x0004); \
+ nec_state->AuxVal = (f) & 0x0010; \
+ nec_state->ZeroVal = !((f) & 0x0040); \
+ nec_state->SignVal = (f) & 0x0080 ? -1 : 0; \
+ nec_state->TF = ((f) & 0x0100) == 0x0100; \
+ nec_state->IF = ((f) & 0x0200) == 0x0200; \
+ nec_state->DF = ((f) & 0x0400) == 0x0400; \
+ nec_state->OverVal = (f) & 0x0800; \
nec_state->MF = ((f) & 0x8000) == 0x8000; \
}
#define IncWordReg(Reg) \
- unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
+ unsigned tmp = (unsigned)Wreg(Reg); \
unsigned tmp1 = tmp+1; \
nec_state->OverVal = (tmp == 0x7fff); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
- nec_state->regs.w[Reg]=tmp1
+ Wreg(Reg)=tmp1
#define DecWordReg(Reg) \
- unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
+ unsigned tmp = (unsigned)Wreg(Reg); \
unsigned tmp1 = tmp-1; \
nec_state->OverVal = (tmp == 0x8000); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
- nec_state->regs.w[Reg]=tmp1
+ Wreg(Reg)=tmp1
#define JMP(flag) \
int tmp; \
@@ -184,26 +220,26 @@ typedef enum {
}
#define ADJ4(param1,param2) \
- if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
+ if (AF || ((Breg(AL) & 0xf) > 9)) \
{ \
UINT16 tmp; \
- tmp = nec_state->regs.b[AL] + param1; \
- nec_state->regs.b[AL] = tmp; \
+ tmp = Breg(AL) + param1; \
+ Breg(AL) = tmp; \
nec_state->AuxVal = 1; \
nec_state->CarryVal |= tmp & 0x100; \
} \
- if (CF || (nec_state->regs.b[AL]>0x9f)) \
+ if (CF || (Breg(AL)>0x9f)) \
{ \
- nec_state->regs.b[AL] += param2; \
+ Breg(AL) += param2; \
nec_state->CarryVal = 1; \
} \
- SetSZPF_Byte(nec_state->regs.b[AL])
+ SetSZPF_Byte(Breg(AL))
#define ADJB(param1,param2) \
- if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
+ if (AF || ((Breg(AL) & 0xf) > 9)) \
{ \
- nec_state->regs.b[AL] += param1; \
- nec_state->regs.b[AH] += param2; \
+ Breg(AL) += param1; \
+ Breg(AH) += param2; \
nec_state->AuxVal = 1; \
nec_state->CarryVal = 1; \
} \
@@ -212,12 +248,12 @@ typedef enum {
nec_state->AuxVal = 0; \
nec_state->CarryVal = 0; \
} \
- nec_state->regs.b[AL] &= 0x0F
+ Breg(AL) &= 0x0F
#define BITOP_BYTE \
ModRM = FETCH(); \
if (ModRM >= 0xc0) { \
- tmp=nec_state->regs.b[Mod_RM.RM.b[ModRM]]; \
+ tmp=Breg(Mod_RM.RM.b[ModRM]); \
} \
else { \
(*GetEA[ModRM])(nec_state); \
@@ -227,7 +263,7 @@ typedef enum {
#define BITOP_WORD \
ModRM = FETCH(); \
if (ModRM >= 0xc0) { \
- tmp=nec_state->regs.w[Mod_RM.RM.w[ModRM]]; \
+ tmp=Wreg(Mod_RM.RM.w[ModRM]); \
} \
else { \
(*GetEA[ModRM])(nec_state); \
@@ -242,9 +278,9 @@ typedef enum {
#define XchgAWReg(Reg) \
WORD tmp; \
- tmp = nec_state->regs.w[Reg]; \
- nec_state->regs.w[Reg] = nec_state->regs.w[AW]; \
- nec_state->regs.w[AW] = tmp
+ tmp = Wreg(Reg); \
+ Wreg(Reg) = Wreg(AW); \
+ Wreg(AW) = tmp
#define ROL_BYTE nec_state->CarryVal = dst & 0x80; dst = (dst << 1)+CF
#define ROL_WORD nec_state->CarryVal = dst & 0x8000; dst = (dst << 1)+CF
@@ -262,50 +298,50 @@ typedef enum {
#define SHRA_WORD(c) nec_state->icount-=c; dst = ((INT16)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT16)((WORD)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
#define DIVUB \
- uresult = nec_state->regs.w[AW]; \
+ uresult = Wreg(AW); \
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xff) { \
nec_interrupt(nec_state, 0,0); break; \
} else { \
- nec_state->regs.b[AL] = uresult; \
- nec_state->regs.b[AH] = uresult2; \
+ Breg(AL) = uresult; \
+ Breg(AH) = uresult2; \
}
#define DIVB \
- result = (INT16)nec_state->regs.w[AW]; \
+ result = (INT16)Wreg(AW); \
result2 = result % (INT16)((INT8)tmp); \
if ((result /= (INT16)((INT8)tmp)) > 0xff) { \
nec_interrupt(nec_state, 0,0); break; \
} else { \
- nec_state->regs.b[AL] = result; \
- nec_state->regs.b[AH] = result2; \
+ Breg(AL) = result; \
+ Breg(AH) = result2; \
}
#define DIVUW \
- uresult = (((UINT32)nec_state->regs.w[DW]) << 16) | nec_state->regs.w[AW];\
+ uresult = (((UINT32)Wreg(DW)) << 16) | Wreg(AW);\
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xffff) { \
nec_interrupt(nec_state, 0,0); break; \
} else { \
- nec_state->regs.w[AW]=uresult; \
- nec_state->regs.w[DW]=uresult2; \
+ Wreg(AW)=uresult; \
+ Wreg(DW)=uresult2; \
}
#define DIVW \
- result = ((UINT32)nec_state->regs.w[DW] << 16) + nec_state->regs.w[AW]; \
+ result = ((UINT32)Wreg(DW) << 16) + Wreg(AW); \
result2 = result % (INT32)((INT16)tmp); \
if ((result /= (INT32)((INT16)tmp)) > 0xffff) { \
nec_interrupt(nec_state, 0,0); break; \
} else { \
- nec_state->regs.w[AW]=result; \
- nec_state->regs.w[DW]=result2; \
+ Wreg(AW)=result; \
+ Wreg(DW)=result2; \
}
#define ADD4S { \
int i,v1,v2,result; \
- int count = (nec_state->regs.b[CL]+1)/2; \
- unsigned di = nec_state->regs.w[IY]; \
- unsigned si = nec_state->regs.w[IX]; \
+ int count = (Breg(CL)+1)/2; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
static const UINT8 table[3]={18,19,19}; \
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for add4s\n",PC(nec_state)); \
nec_state->ZeroVal = nec_state->CarryVal = 0; \
@@ -327,10 +363,10 @@ typedef enum {
}
#define SUB4S { \
- int count = (nec_state->regs.b[CL]+1)/2; \
+ int count = (Breg(CL)+1)/2; \
int i,v1,v2,result; \
- unsigned di = nec_state->regs.w[IY]; \
- unsigned si = nec_state->regs.w[IX]; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
static const UINT8 table[3]={18,19,19}; \
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for sub4s\n",PC(nec_state)); \
nec_state->ZeroVal = nec_state->CarryVal = 0; \
@@ -357,10 +393,10 @@ typedef enum {
}
#define CMP4S { \
- int count = (nec_state->regs.b[CL]+1)/2; \
+ int count = (Breg(CL)+1)/2; \
int i,v1,v2,result; \
- unsigned di = nec_state->regs.w[IY]; \
- unsigned si = nec_state->regs.w[IX]; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
static const UINT8 table[3]={14,19,19}; \
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for cmp4s\n",PC(nec_state)); \
nec_state->ZeroVal = nec_state->CarryVal = 0; \
diff --git a/src/emu/cpu/nec/v25.c b/src/emu/cpu/nec/v25.c
new file mode 100644
index 00000000000..f619de1426b
--- /dev/null
+++ b/src/emu/cpu/nec/v25.c
@@ -0,0 +1,622 @@
+/****************************************************************************
+
+ NEC V25/V35 emulator
+
+ ---------------------------------------------
+
+ TODO:
+
+ Using V20/V30 cycle counts for now. Cycle counts change
+ depending on whether the internal RAM access is enabled.
+ Also, the clock divider can be changed to 1/2, 1/4 or 1/8.
+
+ IBRK flag (trap I/O instructions) included but not implemented.
+
+ Most special function registers not implemented yet.
+
+ It would be nice if the internal ram area was viewable in the debugger.
+
+****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+
+typedef UINT8 BOOLEAN;
+typedef UINT8 BYTE;
+typedef UINT16 WORD;
+typedef UINT32 DWORD;
+
+#include "nec.h"
+#include "v25priv.h"
+
+/* default configuration */
+static const nec_config default_config =
+{
+ NULL
+};
+
+extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, const nec_config *config);
+
+INLINE v25_state_t *get_safe_token(running_device *device)
+{
+ assert(device != NULL);
+ assert(device->type() == V25 || device->type() == V35);
+ return (v25_state_t *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+/* The interrupt number of a pending external interrupt pending NMI is 2. */
+/* For INTR interrupts, the level is caught on the bus during an INTA cycle */
+
+#define INT_IRQ 0x01
+#define NMI_IRQ 0x02
+
+INLINE void prefetch(v25_state_t *nec_state)
+{
+ nec_state->prefetch_count--;
+}
+
+static void do_prefetch(v25_state_t *nec_state, int previous_ICount)
+{
+ int diff = previous_ICount - (int) nec_state->icount;
+
+ /* The implementation is not accurate, but comes close.
+ * It does not respect that the V30 will fetch two bytes
+ * at once directly, but instead uses only 2 cycles instead
+ * of 4. There are however only very few sources publicly
+ * available and they are vague.
+ */
+ while (nec_state->prefetch_count<0)
+ {
+ nec_state->prefetch_count++;
+ if (diff>nec_state->prefetch_cycles)
+ diff -= nec_state->prefetch_cycles;
+ else
+ nec_state->icount -= nec_state->prefetch_cycles;
+ }
+
+ if (nec_state->prefetch_reset)
+ {
+ nec_state->prefetch_count = 0;
+ nec_state->prefetch_reset = 0;
+ return;
+ }
+
+ while (diff>=nec_state->prefetch_cycles && nec_state->prefetch_count < nec_state->prefetch_size)
+ {
+ diff -= nec_state->prefetch_cycles;
+ nec_state->prefetch_count++;
+ }
+
+}
+
+INLINE UINT8 fetch(v25_state_t *nec_state)
+{
+ prefetch(nec_state);
+ return nec_state->direct->read_raw_byte(FETCH_XOR((Sreg(PS)<<4)+nec_state->ip++));
+}
+
+INLINE UINT16 fetchword(v25_state_t *nec_state)
+{
+ UINT16 r = FETCH();
+ r |= (FETCH()<<8);
+ return r;
+}
+
+#define nec_state_t v25_state_t
+
+#include "v25instr.h"
+#include "necea.h"
+#include "necmodrm.h"
+
+static UINT8 parity_table[256];
+
+static UINT8 fetchop(v25_state_t *nec_state)
+{
+ UINT8 ret;
+
+ prefetch(nec_state);
+ ret = nec_state->direct->read_decrypted_byte(FETCH_XOR( ( Sreg(PS)<<4)+nec_state->ip++));
+
+ if (nec_state->MF == 0)
+ if (nec_state->config->v25v35_decryptiontable)
+ {
+ ret = nec_state->config->v25v35_decryptiontable[ret];
+ }
+ return ret;
+}
+
+
+
+/***************************************************************************/
+
+static CPU_RESET( v25 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+ unsigned int i,j,c;
+
+ static const WREGS wreg_name[8]={ AW, CW, DW, BW, SP, BP, IX, IY };
+ static const BREGS breg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
+
+ memset( &nec_state->ram.w, 0, sizeof(nec_state->ram.w));
+
+ nec_state->ip = 0;
+ nec_state->IBRK = 1;
+ nec_state->F0 = 0;
+ nec_state->F1 = 0;
+ nec_state->TF = 0;
+ nec_state->IF = 0;
+ nec_state->DF = 0;
+ nec_state->RB = 7;
+ nec_state->SignVal = 0;
+ nec_state->int_vector = 0;
+ nec_state->pending_irq = 0;
+ nec_state->nmi_state = 0;
+ nec_state->irq_state = 0;
+ nec_state->poll_state = 0;
+ nec_state->mode_state = nec_state->MF = (nec_state->config->v25v35_decryptiontable) ? 0 : 1;
+ nec_state->AuxVal = 0;
+ nec_state->OverVal = 0;
+ nec_state->ZeroVal = 0;
+ nec_state->CarryVal = 0;
+ nec_state->ParityVal = 0;
+
+ nec_state->PRC = 0x4E;
+ nec_state->IDB = 0xFF;
+
+ Sreg(PS) = 0xffff;
+
+ CHANGE_PC;
+
+ for (i = 0;i < 256; i++)
+ {
+ for (j = i, c = 0; j > 0; j >>= 1)
+ if (j & 1) c++;
+ parity_table[i] = !(c & 1);
+ }
+
+ nec_state->ZeroVal = nec_state->ParityVal = 1;
+
+ for (i = 0; i < 256; i++)
+ {
+ Mod_RM.reg.b[i] = breg_name[(i & 0x38) >> 3];
+ Mod_RM.reg.w[i] = wreg_name[(i & 0x38) >> 3];
+ }
+
+ for (i = 0xc0; i < 0x100; i++)
+ {
+ Mod_RM.RM.w[i] = wreg_name[i & 7];
+ Mod_RM.RM.b[i] = breg_name[i & 7];
+ }
+
+ nec_state->poll_state = 1;
+}
+
+static CPU_EXIT( v25 )
+{
+
+}
+
+static void nec_interrupt(v25_state_t *nec_state, unsigned int_num, unsigned mode)
+{
+ UINT32 dest_seg, dest_off;
+
+ i_pushf(nec_state);
+ nec_state->TF = nec_state->IF = 0;
+
+ switch(mode)
+ {
+ case 0:
+ nec_state->MF = nec_state->mode_state;
+ break;
+ case 1: /* BRKN: force native mode */
+ nec_state->MF = 1;
+ break;
+ case 2: /* BRKS: force secure mode */
+ if (nec_state->config->v25v35_decryptiontable)
+ nec_state->MF = 0;
+ else
+ logerror("%06x: BRKS executed with no decryption table\n",PC(nec_state));
+ }
+
+ if (int_num == -1)
+ {
+ int_num = (*nec_state->irq_callback)(nec_state->device, 0);
+
+ nec_state->irq_state = CLEAR_LINE;
+ nec_state->pending_irq &= ~INT_IRQ;
+ }
+
+ dest_off = read_mem_word(int_num*4);
+ dest_seg = read_mem_word(int_num*4+2);
+
+ PUSH(Sreg(PS));
+ PUSH(nec_state->ip);
+ nec_state->ip = (WORD)dest_off;
+ Sreg(PS) = (WORD)dest_seg;
+ CHANGE_PC;
+}
+
+static void nec_trap(v25_state_t *nec_state)
+{
+ nec_instruction[fetchop(nec_state)](nec_state);
+ nec_interrupt(nec_state, 1,0);
+}
+
+static void external_int(v25_state_t *nec_state)
+{
+ if( nec_state->pending_irq & NMI_IRQ )
+ {
+ nec_interrupt(nec_state, NEC_NMI_INT_VECTOR,0);
+ nec_state->pending_irq &= ~NMI_IRQ;
+ }
+ else if( nec_state->pending_irq )
+ {
+ /* the actual vector is retrieved after pushing flags */
+ /* and clearing the IF */
+ nec_interrupt(nec_state, (UINT32)-1,0);
+ }
+}
+
+/****************************************************************************/
+/* OPCODES */
+/****************************************************************************/
+
+#include "necinstr.c"
+#include "v25instr.c"
+
+/*****************************************************************************/
+
+static void set_irq_line(v25_state_t *nec_state, int irqline, int state)
+{
+ if (irqline == 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;
+ }
+ }
+ else
+ {
+ nec_state->irq_state = state;
+ if (state == CLEAR_LINE)
+ {
+ // if (!nec_state->IF) NS010718 fix interrupt request loss
+ nec_state->pending_irq &= ~INT_IRQ;
+ }
+ else
+ {
+ // if (nec_state->IF) NS010718 fix interrupt request loss
+ nec_state->pending_irq |= INT_IRQ;
+ }
+ }
+}
+
+static void set_poll_line(v25_state_t *nec_state, int state)
+{
+ nec_state->poll_state = state;
+}
+
+static CPU_DISASSEMBLE( v25 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+
+ return necv_dasm_one(buffer, pc, oprom, nec_state->config);
+}
+
+static void v25_init(legacy_cpu_device *device, device_irq_callback irqcallback, int type)
+{
+ const nec_config *config = device->baseconfig().static_config() ? (const nec_config *)device->baseconfig().static_config() : &default_config;
+ v25_state_t *nec_state = get_safe_token(device);
+
+ nec_state->config = config;
+
+
+ state_save_register_device_item_array(device, 0, nec_state->ram.w);
+
+ state_save_register_device_item(device, 0, nec_state->ip);
+ state_save_register_device_item(device, 0, nec_state->IBRK);
+ state_save_register_device_item(device, 0, nec_state->F0);
+ state_save_register_device_item(device, 0, nec_state->F1);
+ state_save_register_device_item(device, 0, nec_state->TF);
+ state_save_register_device_item(device, 0, nec_state->IF);
+ state_save_register_device_item(device, 0, nec_state->DF);
+ state_save_register_device_item(device, 0, nec_state->MF);
+ state_save_register_device_item(device, 0, nec_state->RB);
+ state_save_register_device_item(device, 0, nec_state->PRC);
+ state_save_register_device_item(device, 0, nec_state->IDB);
+ state_save_register_device_item(device, 0, nec_state->SignVal);
+ state_save_register_device_item(device, 0, nec_state->int_vector);
+ state_save_register_device_item(device, 0, nec_state->pending_irq);
+ state_save_register_device_item(device, 0, nec_state->nmi_state);
+ state_save_register_device_item(device, 0, nec_state->irq_state);
+ state_save_register_device_item(device, 0, nec_state->poll_state);
+ state_save_register_device_item(device, 0, nec_state->mode_state);
+ state_save_register_device_item(device, 0, nec_state->AuxVal);
+ state_save_register_device_item(device, 0, nec_state->OverVal);
+ state_save_register_device_item(device, 0, nec_state->ZeroVal);
+ state_save_register_device_item(device, 0, nec_state->CarryVal);
+ state_save_register_device_item(device, 0, nec_state->ParityVal);
+
+ nec_state->irq_callback = irqcallback;
+ nec_state->device = device;
+ nec_state->program = device->space(AS_PROGRAM);
+ nec_state->direct = &nec_state->program->direct();
+ nec_state->io = device->space(AS_IO);
+}
+
+
+
+static CPU_EXECUTE( v25 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+ int prev_ICount;
+
+ while(nec_state->icount>0) {
+ /* Dispatch IRQ */
+ if (nec_state->pending_irq && nec_state->no_interrupt==0)
+ {
+ if (nec_state->pending_irq & NMI_IRQ)
+ external_int(nec_state);
+ else if (nec_state->IF)
+ external_int(nec_state);
+ }
+
+ /* No interrupt allowed between last instruction and this one */
+ if (nec_state->no_interrupt)
+ nec_state->no_interrupt--;
+
+ debugger_instruction_hook(device, (Sreg(PS)<<4) + nec_state->ip);
+ prev_ICount = nec_state->icount;
+ nec_instruction[fetchop(nec_state)](nec_state);
+ do_prefetch(nec_state, prev_ICount);
+ }
+}
+
+/* Wrappers for the different CPU types */
+static CPU_INIT( v25 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+
+ v25_init(device, irqcallback, 0);
+ nec_state->fetch_xor = 0;
+ nec_state->chip_type=V20_TYPE;
+ nec_state->prefetch_size = 4; /* 3 words */
+ nec_state->prefetch_cycles = 4; /* four cycles per byte */
+}
+
+static CPU_INIT( v35 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+
+ v25_init(device, irqcallback, 1);
+ nec_state->fetch_xor = BYTE_XOR_LE(0);
+ nec_state->chip_type=V30_TYPE;
+ nec_state->prefetch_size = 6; /* 3 words */
+ nec_state->prefetch_cycles = 2; /* two cycles per byte / four per word */
+
+}
+
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( v25 )
+{
+ v25_state_t *nec_state = get_safe_token(device);
+
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(nec_state, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(nec_state, INPUT_LINE_NMI, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL: set_poll_line(nec_state, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + NEC_PC:
+ if( info->i - (Sreg(PS)<<4) < 0x10000 )
+ {
+ nec_state->ip = info->i - (Sreg(PS)<<4);
+ }
+ else
+ {
+ Sreg(PS) = info->i >> 4;
+ nec_state->ip = info->i & 0x0000f;
+ }
+ break;
+ case CPUINFO_INT_REGISTER + NEC_IP: nec_state->ip = info->i; break;
+ case CPUINFO_INT_SP:
+ if( info->i - (Sreg(SS)<<4) < 0x10000 )
+ {
+ Wreg(SP) = info->i - (Sreg(SS)<<4);
+ }
+ else
+ {
+ Sreg(SS) = info->i >> 4;
+ Wreg(SP) = info->i & 0x0000f;
+ }
+ break;
+ case CPUINFO_INT_REGISTER + NEC_SP: Wreg(SP) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_FLAGS: ExpandFlags(info->i); break;
+ case CPUINFO_INT_REGISTER + NEC_AW: Wreg(AW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_CW: Wreg(CW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_DW: Wreg(DW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_BW: Wreg(BW) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_BP: Wreg(BP) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_IX: Wreg(IX) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_IY: Wreg(IY) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_ES: Sreg(DS1) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_CS: Sreg(PS) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_SS: Sreg(SS) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_DS: Sreg(DS0) = info->i; break;
+ case CPUINFO_INT_REGISTER + NEC_VECTOR: nec_state->int_vector = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+static CPU_GET_INFO( v25v35 )
+{
+ v25_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(v25_state_t); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
+ case DEVINFO_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 DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 20; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_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_VECTOR: info->i = nec_state->int_vector; 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(v25); break;
+ case CPUINFO_FCT_INIT: /* set per-CPU */ break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(v25); break;
+ case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(v25); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(v25); break;
+ case CPUINFO_FCT_BURN: info->burn = NULL; break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(v25); break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &nec_state->icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "NEC"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "NEC V-Series"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Alex W. Jackson, based on NEC V emulator by Bryan McPhail"); break;
+
+ case CPUINFO_STR_FLAGS:
+ flags = CompressFlags();
+ sprintf(info->s, "%c %d %c%c%c%c%c%c%c%c%c%c%c%c",
+ flags & 0x8000 ? 'N':'S',
+ (flags & 0x7000) >> 12,
+ flags & 0x0800 ? 'O':'.',
+ flags & 0x0400 ? 'D':'.',
+ flags & 0x0200 ? 'I':'.',
+ flags & 0x0100 ? 'T':'.',
+ flags & 0x0080 ? 'S':'.',
+ flags & 0x0040 ? 'Z':'.',
+ flags & 0x0020 ? '1':'.',
+ flags & 0x0010 ? 'A':'.',
+ flags & 0x0008 ? '0':'.',
+ flags & 0x0004 ? 'P':'.',
+ flags & 0x0002 ? '.':'I',
+ flags & 0x0001 ? 'C':'.');
+ break;
+
+ case CPUINFO_STR_REGISTER + NEC_PC: sprintf(info->s, "PC:%04X", (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;
+ case CPUINFO_STR_REGISTER + NEC_VECTOR: sprintf(info->s, "V:%02X", nec_state->int_vector); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific set_info
+ **************************************************************************/
+
+CPU_GET_INFO( v25 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(v25); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "V25"); break;
+
+ default: CPU_GET_INFO_CALL(v25v35); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific set_info
+ **************************************************************************/
+
+CPU_GET_INFO( v35 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(v35); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "V35"); break;
+
+ default: CPU_GET_INFO_CALL(v25v35); break;
+ }
+}
+
+DEFINE_LEGACY_CPU_DEVICE(V25, v25);
+DEFINE_LEGACY_CPU_DEVICE(V35, v35);
diff --git a/src/emu/cpu/nec/v25instr.c b/src/emu/cpu/nec/v25instr.c
new file mode 100644
index 00000000000..ee16098bb9b
--- /dev/null
+++ b/src/emu/cpu/nec/v25instr.c
@@ -0,0 +1,34 @@
+OP( 0x0f, i_pre_v25 ) { UINT32 ModRM, tmp, tmp2;
+ switch (FETCH()) {
+ case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
+ case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = Breg(CL) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
+ case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
+ case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
+ case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
+ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
+
+ case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; nec_state->ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; nec_state->CarryVal=nec_state->OverVal=0; break; /* Test */
+ case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
+ case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
+ case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
+ case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
+ case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
+ case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
+
+ case 0x20 : ADD4S; CLKS(7,7,2); break;
+ case 0x22 : SUB4S; CLKS(7,7,2); break;
+ case 0x26 : CMP4S; CLKS(7,7,2); break;
+ case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break;
+ case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
+ case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC(nec_state)); break;
+ case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC(nec_state)); break;
+ case 0x92 : CLK(2); break; /* V25/35 FINT */
+ default: logerror("%06x: Unknown V25 instruction\n",PC(nec_state)); break;
+ }
+}
+
+OP( 0x63, i_brkn ) { nec_interrupt(nec_state, FETCH(),1); CLKS(50,50,24); }
+OP( 0xF1, i_brks ) { nec_interrupt(nec_state, FETCH(),2); CLKS(50,50,24); }
diff --git a/src/emu/cpu/nec/v25instr.h b/src/emu/cpu/nec/v25instr.h
new file mode 100644
index 00000000000..77a8503bc2f
--- /dev/null
+++ b/src/emu/cpu/nec/v25instr.h
@@ -0,0 +1,510 @@
+static void i_add_br8(nec_state_t *nec_state);
+static void i_add_wr16(nec_state_t *nec_state);
+static void i_add_r8b(nec_state_t *nec_state);
+static void i_add_r16w(nec_state_t *nec_state);
+static void i_add_ald8(nec_state_t *nec_state);
+static void i_add_axd16(nec_state_t *nec_state);
+static void i_push_es(nec_state_t *nec_state);
+static void i_pop_es(nec_state_t *nec_state);
+static void i_or_br8(nec_state_t *nec_state);
+static void i_or_r8b(nec_state_t *nec_state);
+static void i_or_wr16(nec_state_t *nec_state);
+static void i_or_r16w(nec_state_t *nec_state);
+static void i_or_ald8(nec_state_t *nec_state);
+static void i_or_axd16(nec_state_t *nec_state);
+static void i_push_cs(nec_state_t *nec_state);
+ATTR_UNUSED static void i_pre_nec(nec_state_t *nec_state);
+static void i_pre_v25(nec_state_t *nec_state);
+static void i_adc_br8(nec_state_t *nec_state);
+static void i_adc_wr16(nec_state_t *nec_state);
+static void i_adc_r8b(nec_state_t *nec_state);
+static void i_adc_r16w(nec_state_t *nec_state);
+static void i_adc_ald8(nec_state_t *nec_state);
+static void i_adc_axd16(nec_state_t *nec_state);
+static void i_push_ss(nec_state_t *nec_state);
+static void i_pop_ss(nec_state_t *nec_state);
+static void i_sbb_br8(nec_state_t *nec_state);
+static void i_sbb_wr16(nec_state_t *nec_state);
+static void i_sbb_r8b(nec_state_t *nec_state);
+static void i_sbb_r16w(nec_state_t *nec_state);
+static void i_sbb_ald8(nec_state_t *nec_state);
+static void i_sbb_axd16(nec_state_t *nec_state);
+static void i_push_ds(nec_state_t *nec_state);
+static void i_pop_ds(nec_state_t *nec_state);
+static void i_and_br8(nec_state_t *nec_state);
+static void i_and_r8b(nec_state_t *nec_state);
+static void i_and_wr16(nec_state_t *nec_state);
+static void i_and_r16w(nec_state_t *nec_state);
+static void i_and_ald8(nec_state_t *nec_state);
+static void i_and_axd16(nec_state_t *nec_state);
+static void i_es(nec_state_t *nec_state);
+static void i_daa(nec_state_t *nec_state);
+static void i_sub_br8(nec_state_t *nec_state);
+static void i_sub_wr16(nec_state_t *nec_state);
+static void i_sub_r8b(nec_state_t *nec_state);
+static void i_sub_r16w(nec_state_t *nec_state);
+static void i_sub_ald8(nec_state_t *nec_state);
+static void i_sub_axd16(nec_state_t *nec_state);
+static void i_cs(nec_state_t *nec_state);
+static void i_das(nec_state_t *nec_state);
+static void i_xor_br8(nec_state_t *nec_state);
+static void i_xor_r8b(nec_state_t *nec_state);
+static void i_xor_wr16(nec_state_t *nec_state);
+static void i_xor_r16w(nec_state_t *nec_state);
+static void i_xor_ald8(nec_state_t *nec_state);
+static void i_xor_axd16(nec_state_t *nec_state);
+static void i_ss(nec_state_t *nec_state);
+static void i_aaa(nec_state_t *nec_state);
+static void i_cmp_br8(nec_state_t *nec_state);
+static void i_cmp_wr16(nec_state_t *nec_state);
+static void i_cmp_r8b(nec_state_t *nec_state);
+static void i_cmp_r16w(nec_state_t *nec_state);
+static void i_cmp_ald8(nec_state_t *nec_state);
+static void i_cmp_axd16(nec_state_t *nec_state);
+static void i_ds(nec_state_t *nec_state);
+static void i_aas(nec_state_t *nec_state);
+static void i_inc_ax(nec_state_t *nec_state);
+static void i_inc_cx(nec_state_t *nec_state);
+static void i_inc_dx(nec_state_t *nec_state);
+static void i_inc_bx(nec_state_t *nec_state);
+static void i_inc_sp(nec_state_t *nec_state);
+static void i_inc_bp(nec_state_t *nec_state);
+static void i_inc_si(nec_state_t *nec_state);
+static void i_inc_di(nec_state_t *nec_state);
+static void i_dec_ax(nec_state_t *nec_state);
+static void i_dec_cx(nec_state_t *nec_state);
+static void i_dec_dx(nec_state_t *nec_state);
+static void i_dec_bx(nec_state_t *nec_state);
+static void i_dec_sp(nec_state_t *nec_state);
+static void i_dec_bp(nec_state_t *nec_state);
+static void i_dec_si(nec_state_t *nec_state);
+static void i_dec_di(nec_state_t *nec_state);
+static void i_push_ax(nec_state_t *nec_state);
+static void i_push_cx(nec_state_t *nec_state);
+static void i_push_dx(nec_state_t *nec_state);
+static void i_push_bx(nec_state_t *nec_state);
+static void i_push_sp(nec_state_t *nec_state);
+static void i_push_bp(nec_state_t *nec_state);
+static void i_push_si(nec_state_t *nec_state);
+static void i_push_di(nec_state_t *nec_state);
+static void i_pop_ax(nec_state_t *nec_state);
+static void i_pop_cx(nec_state_t *nec_state);
+static void i_pop_dx(nec_state_t *nec_state);
+static void i_pop_bx(nec_state_t *nec_state);
+static void i_pop_sp(nec_state_t *nec_state);
+static void i_pop_bp(nec_state_t *nec_state);
+static void i_pop_si(nec_state_t *nec_state);
+static void i_pop_di(nec_state_t *nec_state);
+static void i_pusha(nec_state_t *nec_state);
+static void i_popa(nec_state_t *nec_state);
+static void i_chkind(nec_state_t *nec_state);
+static void i_brkn(nec_state_t *nec_state);
+static void i_repnc(nec_state_t *nec_state);
+static void i_repc(nec_state_t *nec_state);
+static void i_push_d16(nec_state_t *nec_state);
+static void i_imul_d16(nec_state_t *nec_state);
+static void i_push_d8(nec_state_t *nec_state);
+static void i_imul_d8(nec_state_t *nec_state);
+static void i_insb(nec_state_t *nec_state);
+static void i_insw(nec_state_t *nec_state);
+static void i_outsb(nec_state_t *nec_state);
+static void i_outsw(nec_state_t *nec_state);
+static void i_jo(nec_state_t *nec_state);
+static void i_jno(nec_state_t *nec_state);
+static void i_jc(nec_state_t *nec_state);
+static void i_jnc(nec_state_t *nec_state);
+static void i_jz(nec_state_t *nec_state);
+static void i_jnz(nec_state_t *nec_state);
+static void i_jce(nec_state_t *nec_state);
+static void i_jnce(nec_state_t *nec_state);
+static void i_js(nec_state_t *nec_state);
+static void i_jns(nec_state_t *nec_state);
+static void i_jp(nec_state_t *nec_state);
+static void i_jnp(nec_state_t *nec_state);
+static void i_jl(nec_state_t *nec_state);
+static void i_jnl(nec_state_t *nec_state);
+static void i_jle(nec_state_t *nec_state);
+static void i_jnle(nec_state_t *nec_state);
+static void i_80pre(nec_state_t *nec_state);
+static void i_82pre(nec_state_t *nec_state);
+static void i_81pre(nec_state_t *nec_state);
+static void i_83pre(nec_state_t *nec_state);
+static void i_test_br8(nec_state_t *nec_state);
+static void i_test_wr16(nec_state_t *nec_state);
+static void i_xchg_br8(nec_state_t *nec_state);
+static void i_xchg_wr16(nec_state_t *nec_state);
+static void i_mov_br8(nec_state_t *nec_state);
+static void i_mov_r8b(nec_state_t *nec_state);
+static void i_mov_wr16(nec_state_t *nec_state);
+static void i_mov_r16w(nec_state_t *nec_state);
+static void i_mov_wsreg(nec_state_t *nec_state);
+static void i_lea(nec_state_t *nec_state);
+static void i_mov_sregw(nec_state_t *nec_state);
+static void i_invalid(nec_state_t *nec_state);
+static void i_popw(nec_state_t *nec_state);
+static void i_nop(nec_state_t *nec_state);
+static void i_xchg_axcx(nec_state_t *nec_state);
+static void i_xchg_axdx(nec_state_t *nec_state);
+static void i_xchg_axbx(nec_state_t *nec_state);
+static void i_xchg_axsp(nec_state_t *nec_state);
+static void i_xchg_axbp(nec_state_t *nec_state);
+static void i_xchg_axsi(nec_state_t *nec_state);
+static void i_xchg_axdi(nec_state_t *nec_state);
+static void i_cbw(nec_state_t *nec_state);
+static void i_cwd(nec_state_t *nec_state);
+static void i_call_far(nec_state_t *nec_state);
+static void i_pushf(nec_state_t *nec_state);
+static void i_popf(nec_state_t *nec_state);
+static void i_sahf(nec_state_t *nec_state);
+static void i_lahf(nec_state_t *nec_state);
+static void i_mov_aldisp(nec_state_t *nec_state);
+static void i_mov_axdisp(nec_state_t *nec_state);
+static void i_mov_dispal(nec_state_t *nec_state);
+static void i_mov_dispax(nec_state_t *nec_state);
+static void i_movsb(nec_state_t *nec_state);
+static void i_movsw(nec_state_t *nec_state);
+static void i_cmpsb(nec_state_t *nec_state);
+static void i_cmpsw(nec_state_t *nec_state);
+static void i_test_ald8(nec_state_t *nec_state);
+static void i_test_axd16(nec_state_t *nec_state);
+static void i_stosb(nec_state_t *nec_state);
+static void i_stosw(nec_state_t *nec_state);
+static void i_lodsb(nec_state_t *nec_state);
+static void i_lodsw(nec_state_t *nec_state);
+static void i_scasb(nec_state_t *nec_state);
+static void i_scasw(nec_state_t *nec_state);
+static void i_mov_ald8(nec_state_t *nec_state);
+static void i_mov_cld8(nec_state_t *nec_state);
+static void i_mov_dld8(nec_state_t *nec_state);
+static void i_mov_bld8(nec_state_t *nec_state);
+static void i_mov_ahd8(nec_state_t *nec_state);
+static void i_mov_chd8(nec_state_t *nec_state);
+static void i_mov_dhd8(nec_state_t *nec_state);
+static void i_mov_bhd8(nec_state_t *nec_state);
+static void i_mov_axd16(nec_state_t *nec_state);
+static void i_mov_cxd16(nec_state_t *nec_state);
+static void i_mov_dxd16(nec_state_t *nec_state);
+static void i_mov_bxd16(nec_state_t *nec_state);
+static void i_mov_spd16(nec_state_t *nec_state);
+static void i_mov_bpd16(nec_state_t *nec_state);
+static void i_mov_sid16(nec_state_t *nec_state);
+static void i_mov_did16(nec_state_t *nec_state);
+static void i_rotshft_bd8(nec_state_t *nec_state);
+static void i_rotshft_wd8(nec_state_t *nec_state);
+static void i_ret_d16(nec_state_t *nec_state);
+static void i_ret(nec_state_t *nec_state);
+static void i_les_dw(nec_state_t *nec_state);
+static void i_lds_dw(nec_state_t *nec_state);
+static void i_mov_bd8(nec_state_t *nec_state);
+static void i_mov_wd16(nec_state_t *nec_state);
+static void i_enter(nec_state_t *nec_state);
+static void i_leave(nec_state_t *nec_state);
+static void i_retf_d16(nec_state_t *nec_state);
+static void i_retf(nec_state_t *nec_state);
+static void i_int3(nec_state_t *nec_state);
+static void i_int(nec_state_t *nec_state);
+static void i_into(nec_state_t *nec_state);
+static void i_iret(nec_state_t *nec_state);
+static void i_rotshft_b(nec_state_t *nec_state);
+static void i_rotshft_w(nec_state_t *nec_state);
+static void i_rotshft_bcl(nec_state_t *nec_state);
+static void i_rotshft_wcl(nec_state_t *nec_state);
+static void i_aam(nec_state_t *nec_state);
+static void i_aad(nec_state_t *nec_state);
+static void i_setalc(nec_state_t *nec_state);
+static void i_trans(nec_state_t *nec_state);
+static void i_fpo(nec_state_t *nec_state);
+static void i_loopne(nec_state_t *nec_state);
+static void i_loope(nec_state_t *nec_state);
+static void i_loop(nec_state_t *nec_state);
+static void i_jcxz(nec_state_t *nec_state);
+static void i_inal(nec_state_t *nec_state);
+static void i_inax(nec_state_t *nec_state);
+static void i_outal(nec_state_t *nec_state);
+static void i_outax(nec_state_t *nec_state);
+static void i_call_d16(nec_state_t *nec_state);
+static void i_jmp_d16(nec_state_t *nec_state);
+static void i_jmp_far(nec_state_t *nec_state);
+static void i_jmp_d8(nec_state_t *nec_state);
+static void i_inaldx(nec_state_t *nec_state);
+static void i_inaxdx(nec_state_t *nec_state);
+static void i_outdxal(nec_state_t *nec_state);
+static void i_outdxax(nec_state_t *nec_state);
+static void i_lock(nec_state_t *nec_state);
+static void i_brks(nec_state_t *nec_state);
+static void i_repne(nec_state_t *nec_state);
+static void i_repe(nec_state_t *nec_state);
+static void i_hlt(nec_state_t *nec_state);
+static void i_cmc(nec_state_t *nec_state);
+static void i_f6pre(nec_state_t *nec_state);
+static void i_f7pre(nec_state_t *nec_state);
+static void i_clc(nec_state_t *nec_state);
+static void i_stc(nec_state_t *nec_state);
+static void i_di(nec_state_t *nec_state);
+static void i_ei(nec_state_t *nec_state);
+static void i_cld(nec_state_t *nec_state);
+static void i_std(nec_state_t *nec_state);
+static void i_fepre(nec_state_t *nec_state);
+static void i_ffpre(nec_state_t *nec_state);
+
+static void i_wait(nec_state_t *nec_state);
+
+static void (*const nec_instruction[256])(nec_state_t *nec_state) =
+{
+ i_add_br8, /* 0x00 */
+ i_add_wr16, /* 0x01 */
+ i_add_r8b, /* 0x02 */
+ i_add_r16w, /* 0x03 */
+ i_add_ald8, /* 0x04 */
+ i_add_axd16, /* 0x05 */
+ i_push_es, /* 0x06 */
+ i_pop_es, /* 0x07 */
+ i_or_br8, /* 0x08 */
+ i_or_wr16, /* 0x09 */
+ i_or_r8b, /* 0x0a */
+ i_or_r16w, /* 0x0b */
+ i_or_ald8, /* 0x0c */
+ i_or_axd16, /* 0x0d */
+ i_push_cs, /* 0x0e */
+ i_pre_v25, /* 0x0f */
+ i_adc_br8, /* 0x10 */
+ i_adc_wr16, /* 0x11 */
+ i_adc_r8b, /* 0x12 */
+ i_adc_r16w, /* 0x13 */
+ i_adc_ald8, /* 0x14 */
+ i_adc_axd16, /* 0x15 */
+ i_push_ss, /* 0x16 */
+ i_pop_ss, /* 0x17 */
+ i_sbb_br8, /* 0x18 */
+ i_sbb_wr16, /* 0x19 */
+ i_sbb_r8b, /* 0x1a */
+ i_sbb_r16w, /* 0x1b */
+ i_sbb_ald8, /* 0x1c */
+ i_sbb_axd16, /* 0x1d */
+ i_push_ds, /* 0x1e */
+ i_pop_ds, /* 0x1f */
+ i_and_br8, /* 0x20 */
+ i_and_wr16, /* 0x21 */
+ i_and_r8b, /* 0x22 */
+ i_and_r16w, /* 0x23 */
+ i_and_ald8, /* 0x24 */
+ i_and_axd16, /* 0x25 */
+ i_es, /* 0x26 */
+ i_daa, /* 0x27 */
+ i_sub_br8, /* 0x28 */
+ i_sub_wr16, /* 0x29 */
+ i_sub_r8b, /* 0x2a */
+ i_sub_r16w, /* 0x2b */
+ i_sub_ald8, /* 0x2c */
+ i_sub_axd16, /* 0x2d */
+ i_cs, /* 0x2e */
+ i_das, /* 0x2f */
+ i_xor_br8, /* 0x30 */
+ i_xor_wr16, /* 0x31 */
+ i_xor_r8b, /* 0x32 */
+ i_xor_r16w, /* 0x33 */
+ i_xor_ald8, /* 0x34 */
+ i_xor_axd16, /* 0x35 */
+ i_ss, /* 0x36 */
+ i_aaa, /* 0x37 */
+ i_cmp_br8, /* 0x38 */
+ i_cmp_wr16, /* 0x39 */
+ i_cmp_r8b, /* 0x3a */
+ i_cmp_r16w, /* 0x3b */
+ i_cmp_ald8, /* 0x3c */
+ i_cmp_axd16, /* 0x3d */
+ i_ds, /* 0x3e */
+ i_aas, /* 0x3f */
+ i_inc_ax, /* 0x40 */
+ i_inc_cx, /* 0x41 */
+ i_inc_dx, /* 0x42 */
+ i_inc_bx, /* 0x43 */
+ i_inc_sp, /* 0x44 */
+ i_inc_bp, /* 0x45 */
+ i_inc_si, /* 0x46 */
+ i_inc_di, /* 0x47 */
+ i_dec_ax, /* 0x48 */
+ i_dec_cx, /* 0x49 */
+ i_dec_dx, /* 0x4a */
+ i_dec_bx, /* 0x4b */
+ i_dec_sp, /* 0x4c */
+ i_dec_bp, /* 0x4d */
+ i_dec_si, /* 0x4e */
+ i_dec_di, /* 0x4f */
+ i_push_ax, /* 0x50 */
+ i_push_cx, /* 0x51 */
+ i_push_dx, /* 0x52 */
+ i_push_bx, /* 0x53 */
+ i_push_sp, /* 0x54 */
+ i_push_bp, /* 0x55 */
+ i_push_si, /* 0x56 */
+ i_push_di, /* 0x57 */
+ i_pop_ax, /* 0x58 */
+ i_pop_cx, /* 0x59 */
+ i_pop_dx, /* 0x5a */
+ i_pop_bx, /* 0x5b */
+ i_pop_sp, /* 0x5c */
+ i_pop_bp, /* 0x5d */
+ i_pop_si, /* 0x5e */
+ i_pop_di, /* 0x5f */
+ i_pusha, /* 0x60 */
+ i_popa, /* 0x61 */
+ i_chkind, /* 0x62 */
+ i_brkn, /* 0x63 - V25S/V35S only */
+ i_repnc, /* 0x64 */
+ i_repc, /* 0x65 */
+ i_invalid, /* 0x66 */
+ i_invalid, /* 0x67 */
+ i_push_d16, /* 0x68 */
+ i_imul_d16, /* 0x69 */
+ i_push_d8, /* 0x6a */
+ i_imul_d8, /* 0x6b */
+ i_insb, /* 0x6c */
+ i_insw, /* 0x6d */
+ i_outsb, /* 0x6e */
+ i_outsw, /* 0x6f */
+ i_jo, /* 0x70 */
+ i_jno, /* 0x71 */
+ i_jc, /* 0x72 */
+ i_jnc, /* 0x73 */
+ i_jz, /* 0x74 */
+ i_jnz, /* 0x75 */
+ i_jce, /* 0x76 */
+ i_jnce, /* 0x77 */
+ i_js, /* 0x78 */
+ i_jns, /* 0x79 */
+ i_jp, /* 0x7a */
+ i_jnp, /* 0x7b */
+ i_jl, /* 0x7c */
+ i_jnl, /* 0x7d */
+ i_jle, /* 0x7e */
+ i_jnle, /* 0x7f */
+ i_80pre, /* 0x80 */
+ i_81pre, /* 0x81 */
+ i_82pre, /* 0x82 */
+ i_83pre, /* 0x83 */
+ i_test_br8, /* 0x84 */
+ i_test_wr16, /* 0x85 */
+ i_xchg_br8, /* 0x86 */
+ i_xchg_wr16, /* 0x87 */
+ i_mov_br8, /* 0x88 */
+ i_mov_wr16, /* 0x89 */
+ i_mov_r8b, /* 0x8a */
+ i_mov_r16w, /* 0x8b */
+ i_mov_wsreg, /* 0x8c */
+ i_lea, /* 0x8d */
+ i_mov_sregw, /* 0x8e */
+ i_popw, /* 0x8f */
+ i_nop, /* 0x90 */
+ i_xchg_axcx, /* 0x91 */
+ i_xchg_axdx, /* 0x92 */
+ i_xchg_axbx, /* 0x93 */
+ i_xchg_axsp, /* 0x94 */
+ i_xchg_axbp, /* 0x95 */
+ i_xchg_axsi, /* 0x96 */
+ i_xchg_axdi, /* 0x97 */
+ i_cbw, /* 0x98 */
+ i_cwd, /* 0x99 */
+ i_call_far, /* 0x9a */
+ i_wait, /* 0x9b */
+ i_pushf, /* 0x9c */
+ i_popf, /* 0x9d */
+ i_sahf, /* 0x9e */
+ i_lahf, /* 0x9f */
+ i_mov_aldisp, /* 0xa0 */
+ i_mov_axdisp, /* 0xa1 */
+ i_mov_dispal, /* 0xa2 */
+ i_mov_dispax, /* 0xa3 */
+ i_movsb, /* 0xa4 */
+ i_movsw, /* 0xa5 */
+ i_cmpsb, /* 0xa6 */
+ i_cmpsw, /* 0xa7 */
+ i_test_ald8, /* 0xa8 */
+ i_test_axd16, /* 0xa9 */
+ i_stosb, /* 0xaa */
+ i_stosw, /* 0xab */
+ i_lodsb, /* 0xac */
+ i_lodsw, /* 0xad */
+ i_scasb, /* 0xae */
+ i_scasw, /* 0xaf */
+ i_mov_ald8, /* 0xb0 */
+ i_mov_cld8, /* 0xb1 */
+ i_mov_dld8, /* 0xb2 */
+ i_mov_bld8, /* 0xb3 */
+ i_mov_ahd8, /* 0xb4 */
+ i_mov_chd8, /* 0xb5 */
+ i_mov_dhd8, /* 0xb6 */
+ i_mov_bhd8, /* 0xb7 */
+ i_mov_axd16, /* 0xb8 */
+ i_mov_cxd16, /* 0xb9 */
+ i_mov_dxd16, /* 0xba */
+ i_mov_bxd16, /* 0xbb */
+ i_mov_spd16, /* 0xbc */
+ i_mov_bpd16, /* 0xbd */
+ i_mov_sid16, /* 0xbe */
+ i_mov_did16, /* 0xbf */
+ i_rotshft_bd8, /* 0xc0 */
+ i_rotshft_wd8, /* 0xc1 */
+ i_ret_d16, /* 0xc2 */
+ i_ret, /* 0xc3 */
+ i_les_dw, /* 0xc4 */
+ i_lds_dw, /* 0xc5 */
+ i_mov_bd8, /* 0xc6 */
+ i_mov_wd16, /* 0xc7 */
+ i_enter, /* 0xc8 */
+ i_leave, /* 0xc9 */
+ i_retf_d16, /* 0xca */
+ i_retf, /* 0xcb */
+ i_int3, /* 0xcc */
+ i_int, /* 0xcd */
+ i_into, /* 0xce */
+ i_iret, /* 0xcf */
+ i_rotshft_b, /* 0xd0 */
+ i_rotshft_w, /* 0xd1 */
+ i_rotshft_bcl, /* 0xd2 */
+ i_rotshft_wcl, /* 0xd3 */
+ i_aam, /* 0xd4 */
+ i_aad, /* 0xd5 */
+ i_setalc, /* 0xd6 */
+ i_trans, /* 0xd7 */
+ i_fpo, /* 0xd8 */
+ i_fpo, /* 0xd9 */
+ i_fpo, /* 0xda */
+ i_fpo, /* 0xdb */
+ i_fpo, /* 0xdc */
+ i_fpo, /* 0xdd */
+ i_fpo, /* 0xde */
+ i_fpo, /* 0xdf */
+ i_loopne, /* 0xe0 */
+ i_loope, /* 0xe1 */
+ i_loop, /* 0xe2 */
+ i_jcxz, /* 0xe3 */
+ i_inal, /* 0xe4 */
+ i_inax, /* 0xe5 */
+ i_outal, /* 0xe6 */
+ i_outax, /* 0xe7 */
+ i_call_d16, /* 0xe8 */
+ i_jmp_d16, /* 0xe9 */
+ i_jmp_far, /* 0xea */
+ i_jmp_d8, /* 0xeb */
+ i_inaldx, /* 0xec */
+ i_inaxdx, /* 0xed */
+ i_outdxal, /* 0xee */
+ i_outdxax, /* 0xef */
+ i_lock, /* 0xf0 */
+ i_brks, /* 0xf1 */
+ i_repne, /* 0xf2 */
+ i_repe, /* 0xf3 */
+ i_hlt, /* 0xf4 */
+ i_cmc, /* 0xf5 */
+ i_f6pre, /* 0xf6 */
+ i_f7pre, /* 0xf7 */
+ i_clc, /* 0xf8 */
+ i_stc, /* 0xf9 */
+ i_di, /* 0xfa */
+ i_ei, /* 0xfb */
+ i_cld, /* 0xfc */
+ i_std, /* 0xfd */
+ i_fepre, /* 0xfe */
+ i_ffpre /* 0xff */
+};
diff --git a/src/emu/cpu/nec/v25priv.h b/src/emu/cpu/nec/v25priv.h
new file mode 100644
index 00000000000..fbf292ade41
--- /dev/null
+++ b/src/emu/cpu/nec/v25priv.h
@@ -0,0 +1,455 @@
+#define NEC_NMI_INT_VECTOR 2
+
+/* Cpu types, steps of 8 to help the cycle count calculation */
+#define V33_TYPE 0
+#define V30_TYPE 8
+#define V20_TYPE 16
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* internal RAM and register banks */
+typedef union
+{
+ UINT16 w[128];
+ UINT8 b[256];
+} internalram;
+
+typedef struct _v25_state_t v25_state_t;
+struct _v25_state_t
+{
+ internalram ram;
+ offs_t fetch_xor;
+
+ UINT16 ip;
+
+ INT32 SignVal;
+ UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
+ UINT8 IBRK, F0, F1, TF, IF, DF, MF; /* 0 or 1 valued flags */
+ UINT8 RB; /* current register bank */
+ UINT32 int_vector;
+ UINT32 pending_irq;
+ UINT32 nmi_state;
+ UINT32 irq_state;
+ UINT32 poll_state;
+ UINT32 mode_state;
+ UINT8 no_interrupt;
+
+ /* special function registers */
+ UINT8 PRC, IDB;
+
+ device_irq_callback irq_callback;
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ address_space *io;
+ int icount;
+
+ const nec_config *config;
+
+ UINT8 prefetch_size;
+ UINT8 prefetch_cycles;
+ INT8 prefetch_count;
+ UINT8 prefetch_reset;
+ UINT32 chip_type;
+
+ UINT32 prefix_base; /* base address of the latest prefix segment */
+ UINT8 seg_prefix; /* prefix segment indicator */
+};
+
+typedef enum {
+ DS1 = 0x0E/2,
+ PS = 0x0C/2,
+ SS = 0x0A/2,
+ DS0 = 0x08/2,
+} SREGS;
+
+typedef enum {
+ AW = 0x1E/2,
+ CW = 0x1C/2,
+ DW = 0x1A/2,
+ BW = 0x18/2,
+ SP = 0x16/2,
+ BP = 0x14/2,
+ IX = 0x12/2,
+ IY = 0x10/2,
+} WREGS;
+
+typedef enum {
+ AL = NATIVE_ENDIAN_VALUE_LE_BE(0x1E, 0x1F),
+ AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1F, 0x1E),
+ CL = NATIVE_ENDIAN_VALUE_LE_BE(0x1C, 0x1D),
+ CH = NATIVE_ENDIAN_VALUE_LE_BE(0x1D, 0x1C),
+ DL = NATIVE_ENDIAN_VALUE_LE_BE(0x1A, 0x1B),
+ DH = NATIVE_ENDIAN_VALUE_LE_BE(0x1B, 0x1A),
+ BL = NATIVE_ENDIAN_VALUE_LE_BE(0x18, 0x19),
+ BH = NATIVE_ENDIAN_VALUE_LE_BE(0x19, 0x18),
+} BREGS;
+
+#define Sreg(x) nec_state->ram.w[(nec_state->RB << 4) + (x)]
+#define Wreg(x) nec_state->ram.w[(nec_state->RB << 4) + (x)]
+#define Breg(x) nec_state->ram.b[(nec_state->RB << 5) + (x)]
+
+#define PC(n) ((Sreg(PS)<<4)+(n)->ip)
+
+/* parameter x = result, y = source 1, z = source 2 */
+
+#define SetTF(x) (nec_state->TF = (x))
+#define SetIF(x) (nec_state->IF = (x))
+#define SetDF(x) (nec_state->DF = (x))
+#define SetMD(x) (nec_state->MF = (x)) /* OB [19.07.99] Mode Flag V30 */
+
+#define SetCFB(x) (nec_state->CarryVal = (x) & 0x100)
+#define SetCFW(x) (nec_state->CarryVal = (x) & 0x10000)
+#define SetAF(x,y,z) (nec_state->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
+#define SetSF(x) (nec_state->SignVal = (x))
+#define SetZF(x) (nec_state->ZeroVal = (x))
+#define SetPF(x) (nec_state->ParityVal = (x))
+
+#define SetSZPF_Byte(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT8)(x))
+#define SetSZPF_Word(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT16)(x))
+
+#define SetOFW_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
+#define SetOFB_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
+#define SetOFW_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
+#define SetOFB_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
+
+#define ADDB { UINT32 res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define ADDW { UINT32 res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+#define SUBB { UINT32 res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
+#define SUBW { UINT32 res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
+
+#define ORB dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
+#define ORW dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
+
+#define ANDB dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
+#define ANDW dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
+
+#define XORB dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
+#define XORW dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
+
+#define CF (nec_state->CarryVal!=0)
+#define SF (nec_state->SignVal<0)
+#define ZF (nec_state->ZeroVal==0)
+#define PF parity_table[(BYTE)nec_state->ParityVal]
+#define AF (nec_state->AuxVal!=0)
+#define OF (nec_state->OverVal!=0)
+
+/************************************************************************/
+
+int v25_read_byte(v25_state_t *nec_state, unsigned a);
+int v25_read_word(v25_state_t *nec_state, unsigned a);
+void v25_write_byte(v25_state_t *nec_state, unsigned a, unsigned d);
+void v25_write_word(v25_state_t *nec_state, unsigned a, unsigned d);
+
+#define read_mem_byte(a) v25_read_byte(nec_state,(a))
+#define read_mem_word(a) v25_read_word(nec_state,(a))
+#define write_mem_byte(a,d) v25_write_byte(nec_state,(a),(d))
+#define write_mem_word(a,d) v25_write_word(nec_state,(a),(d))
+
+#define read_port_byte(a) nec_state->io->read_byte(a)
+#define read_port_word(a) nec_state->io->read_word_unaligned(a)
+#define write_port_byte(a,d) nec_state->io->write_byte((a),(d))
+#define write_port_word(a,d) nec_state->io->write_word_unaligned((a),(d))
+
+/************************************************************************/
+
+#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0)
+
+#define SegBase(Seg) (Sreg(Seg) << 4)
+
+#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : Sreg(Seg) << 4)
+
+#define GetMemB(Seg,Off) (read_mem_byte(DefaultBase(Seg) + (Off)))
+#define GetMemW(Seg,Off) (read_mem_word(DefaultBase(Seg) + (Off)))
+
+#define PutMemB(Seg,Off,x) { write_mem_byte(DefaultBase(Seg) + (Off), (x)); }
+#define PutMemW(Seg,Off,x) { write_mem_word(DefaultBase(Seg) + (Off), (x)); }
+
+/* prefetch timing */
+
+#define FETCH() fetch(nec_state)
+#define FETCH_XOR(a) ((a) ^ nec_state->fetch_xor)
+#define FETCHWORD() fetchword(nec_state)
+#define EMPTY_PREFETCH() nec_state->prefetch_reset = 1
+
+
+#define PUSH(val) { Wreg(SP)-=2; write_mem_word((((Sreg(SS)<<4)+Wreg(SP))),val); }
+#define POP(var) { var = read_mem_word((((Sreg(SS)<<4)+Wreg(SP)))); Wreg(SP)+=2; }
+
+#define GetModRM UINT32 ModRM=FETCH()
+
+/* Cycle count macros:
+ CLK - cycle count is the same on all processors
+ CLKS - cycle count differs between processors, list all counts
+ CLKW - cycle count for word read/write differs for odd/even source/destination address
+ CLKM - cycle count for reg/mem instructions
+ CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
+
+
+ Prefetch & buswait time is not emulated.
+ Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
+*/
+
+#define CLK(all) nec_state->icount-=all
+#define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; nec_state->icount-=(ccount>>nec_state->chip_type)&0x7f; }
+#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
+#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_state->icount-=( ModRM >=0xc0 )?((ccount>>nec_state->chip_type)&0x7f):((mcount>>nec_state->chip_type)&0x7f); }
+#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_state->icount-=vall; else nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
+
+/************************************************************************/
+#define CompressFlags() (WORD)(CF | (nec_state->IBRK << 1) | (PF << 2) | (nec_state->F0 << 3) | (AF << 4) \
+ | (nec_state->F1 << 5) | (ZF << 6) | (SF << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \
+ | (nec_state->DF << 10) | (OF << 11) | (nec_state->RB << 12) | (nec_state->MF << 15))
+
+#define ExpandFlags(f) \
+{ \
+ nec_state->CarryVal = (f) & 0x0001; \
+ nec_state->IBRK = ((f) & 0x0002) == 0x0002; \
+ nec_state->ParityVal = !((f) & 0x0004); \
+ nec_state->F0 = ((f) & 0x0008) == 0x0008; \
+ nec_state->AuxVal = (f) & 0x0010; \
+ nec_state->F1 = ((f) & 0x0020) == 0x0020; \
+ nec_state->ZeroVal = !((f) & 0x0040); \
+ nec_state->SignVal = (f) & 0x0080 ? -1 : 0; \
+ nec_state->TF = ((f) & 0x0100) == 0x0100; \
+ nec_state->IF = ((f) & 0x0200) == 0x0200; \
+ nec_state->DF = ((f) & 0x0400) == 0x0400; \
+ nec_state->OverVal = (f) & 0x0800; \
+ /* RB only changes on interrupts, so skip it */ \
+ nec_state->MF = ((f) & 0x8000) == 0x8000; \
+}
+
+#define IncWordReg(Reg) \
+ unsigned tmp = (unsigned)Wreg(Reg); \
+ unsigned tmp1 = tmp+1; \
+ nec_state->OverVal = (tmp == 0x7fff); \
+ SetAF(tmp1,tmp,1); \
+ SetSZPF_Word(tmp1); \
+ Wreg(Reg)=tmp1
+
+#define DecWordReg(Reg) \
+ unsigned tmp = (unsigned)Wreg(Reg); \
+ unsigned tmp1 = tmp-1; \
+ nec_state->OverVal = (tmp == 0x8000); \
+ SetAF(tmp1,tmp,1); \
+ SetSZPF_Word(tmp1); \
+ Wreg(Reg)=tmp1
+
+#define JMP(flag) \
+ int tmp; \
+ EMPTY_PREFETCH(); \
+ tmp = (int)((INT8)FETCH()); \
+ if (flag) \
+ { \
+ static const UINT8 table[3]={3,10,10}; \
+ nec_state->ip = (WORD)(nec_state->ip+tmp); \
+ nec_state->icount-=table[nec_state->chip_type/8]; \
+ CHANGE_PC; \
+ return; \
+ }
+
+#define ADJ4(param1,param2) \
+ if (AF || ((Breg(AL) & 0xf) > 9)) \
+ { \
+ UINT16 tmp; \
+ tmp = Breg(AL) + param1; \
+ Breg(AL) = tmp; \
+ nec_state->AuxVal = 1; \
+ nec_state->CarryVal |= tmp & 0x100; \
+ } \
+ if (CF || (Breg(AL)>0x9f)) \
+ { \
+ Breg(AL) += param2; \
+ nec_state->CarryVal = 1; \
+ } \
+ SetSZPF_Byte(Breg(AL))
+
+#define ADJB(param1,param2) \
+ if (AF || ((Breg(AL) & 0xf) > 9)) \
+ { \
+ Breg(AL) += param1; \
+ Breg(AH) += param2; \
+ nec_state->AuxVal = 1; \
+ nec_state->CarryVal = 1; \
+ } \
+ else \
+ { \
+ nec_state->AuxVal = 0; \
+ nec_state->CarryVal = 0; \
+ } \
+ Breg(AL) &= 0x0F
+
+#define BITOP_BYTE \
+ ModRM = FETCH(); \
+ if (ModRM >= 0xc0) { \
+ tmp=Breg(Mod_RM.RM.b[ModRM]); \
+ } \
+ else { \
+ (*GetEA[ModRM])(nec_state); \
+ tmp=read_mem_byte(EA); \
+ }
+
+#define BITOP_WORD \
+ ModRM = FETCH(); \
+ if (ModRM >= 0xc0) { \
+ tmp=Wreg(Mod_RM.RM.w[ModRM]); \
+ } \
+ else { \
+ (*GetEA[ModRM])(nec_state); \
+ tmp=read_mem_word(EA); \
+ }
+
+#define BIT_NOT \
+ if (tmp & (1<<tmp2)) \
+ tmp &= ~(1<<tmp2); \
+ else \
+ tmp |= (1<<tmp2)
+
+#define XchgAWReg(Reg) \
+ WORD tmp; \
+ tmp = Wreg(Reg); \
+ Wreg(Reg) = Wreg(AW); \
+ Wreg(AW) = tmp
+
+#define ROL_BYTE nec_state->CarryVal = dst & 0x80; dst = (dst << 1)+CF
+#define ROL_WORD nec_state->CarryVal = dst & 0x8000; dst = (dst << 1)+CF
+#define ROR_BYTE nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
+#define ROR_WORD nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
+#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
+#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst)
+#define RORC_BYTE dst = (CF<<8)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
+#define RORC_WORD dst = (CF<<16)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
+#define SHL_BYTE(c) nec_state->icount-=c; dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
+#define SHL_WORD(c) nec_state->icount-=c; dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
+#define SHR_BYTE(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
+#define SHR_WORD(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
+#define SHRA_BYTE(c) nec_state->icount-=c; dst = ((INT8)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT8)((BYTE)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
+#define SHRA_WORD(c) nec_state->icount-=c; dst = ((INT16)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT16)((WORD)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
+
+#define DIVUB \
+ uresult = Wreg(AW); \
+ uresult2 = uresult % tmp; \
+ if ((uresult /= tmp) > 0xff) { \
+ nec_interrupt(nec_state, 0,0); break; \
+ } else { \
+ Breg(AL) = uresult; \
+ Breg(AH) = uresult2; \
+ }
+
+#define DIVB \
+ result = (INT16)Wreg(AW); \
+ result2 = result % (INT16)((INT8)tmp); \
+ if ((result /= (INT16)((INT8)tmp)) > 0xff) { \
+ nec_interrupt(nec_state, 0,0); break; \
+ } else { \
+ Breg(AL) = result; \
+ Breg(AH) = result2; \
+ }
+
+#define DIVUW \
+ uresult = (((UINT32)Wreg(DW)) << 16) | Wreg(AW);\
+ uresult2 = uresult % tmp; \
+ if ((uresult /= tmp) > 0xffff) { \
+ nec_interrupt(nec_state, 0,0); break; \
+ } else { \
+ Wreg(AW)=uresult; \
+ Wreg(DW)=uresult2; \
+ }
+
+#define DIVW \
+ result = ((UINT32)Wreg(DW) << 16) + Wreg(AW); \
+ result2 = result % (INT32)((INT16)tmp); \
+ if ((result /= (INT32)((INT16)tmp)) > 0xffff) { \
+ nec_interrupt(nec_state, 0,0); break; \
+ } else { \
+ Wreg(AW)=result; \
+ Wreg(DW)=result2; \
+ }
+
+#define ADD4S { \
+ int i,v1,v2,result; \
+ int count = (Breg(CL)+1)/2; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
+ static const UINT8 table[3]={18,19,19}; \
+ if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for add4s\n",PC(nec_state)); \
+ nec_state->ZeroVal = nec_state->CarryVal = 0; \
+ for (i=0;i<count;i++) { \
+ nec_state->icount-=table[nec_state->chip_type/8]; \
+ tmp = GetMemB(DS0, si); \
+ tmp2 = GetMemB(DS1, di); \
+ v1 = (tmp>>4)*10 + (tmp&0xf); \
+ v2 = (tmp2>>4)*10 + (tmp2&0xf); \
+ result = v1+v2+nec_state->CarryVal; \
+ nec_state->CarryVal = result > 99 ? 1 : 0; \
+ result = result % 100; \
+ v1 = ((result/10)<<4) | (result % 10); \
+ PutMemB(DS1, di,v1); \
+ if (v1) nec_state->ZeroVal = 1; \
+ si++; \
+ di++; \
+ } \
+}
+
+#define SUB4S { \
+ int count = (Breg(CL)+1)/2; \
+ int i,v1,v2,result; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
+ static const UINT8 table[3]={18,19,19}; \
+ if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for sub4s\n",PC(nec_state)); \
+ nec_state->ZeroVal = nec_state->CarryVal = 0; \
+ for (i=0;i<count;i++) { \
+ nec_state->icount-=table[nec_state->chip_type/8]; \
+ tmp = GetMemB(DS1, di); \
+ tmp2 = GetMemB(DS0, si); \
+ v1 = (tmp>>4)*10 + (tmp&0xf); \
+ v2 = (tmp2>>4)*10 + (tmp2&0xf); \
+ if (v1 < (v2+nec_state->CarryVal)) { \
+ v1+=100; \
+ result = v1-(v2+nec_state->CarryVal); \
+ nec_state->CarryVal = 1; \
+ } else { \
+ result = v1-(v2+nec_state->CarryVal); \
+ nec_state->CarryVal = 0; \
+ } \
+ v1 = ((result/10)<<4) | (result % 10); \
+ PutMemB(DS1, di,v1); \
+ if (v1) nec_state->ZeroVal = 1; \
+ si++; \
+ di++; \
+ } \
+}
+
+#define CMP4S { \
+ int count = (Breg(CL)+1)/2; \
+ int i,v1,v2,result; \
+ unsigned di = Wreg(IY); \
+ unsigned si = Wreg(IX); \
+ static const UINT8 table[3]={14,19,19}; \
+ if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for cmp4s\n",PC(nec_state)); \
+ nec_state->ZeroVal = nec_state->CarryVal = 0; \
+ for (i=0;i<count;i++) { \
+ nec_state->icount-=table[nec_state->chip_type/8]; \
+ tmp = GetMemB(DS1, di); \
+ tmp2 = GetMemB(DS0, si); \
+ v1 = (tmp>>4)*10 + (tmp&0xf); \
+ v2 = (tmp2>>4)*10 + (tmp2&0xf); \
+ if (v1 < (v2+nec_state->CarryVal)) { \
+ v1+=100; \
+ result = v1-(v2+nec_state->CarryVal); \
+ nec_state->CarryVal = 1; \
+ } else { \
+ result = v1-(v2+nec_state->CarryVal); \
+ nec_state->CarryVal = 0; \
+ } \
+ v1 = ((result/10)<<4) | (result % 10); \
+ if (v1) nec_state->ZeroVal = 1; \
+ si++; \
+ di++; \
+ } \
+}
diff --git a/src/emu/cpu/nec/v25sfr.c b/src/emu/cpu/nec/v25sfr.c
new file mode 100644
index 00000000000..8ec4ccfbc70
--- /dev/null
+++ b/src/emu/cpu/nec/v25sfr.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+
+ NEC V25/V35 special function registers and internal ram access
+
+****************************************************************************/
+
+#include "emu.h"
+#include "nec.h"
+#include "v25priv.h"
+
+#define RAMEN (nec_state->PRC & 0x40)
+
+int read_sfr(v25_state_t *nec_state, unsigned o)
+{
+ switch(o)
+ {
+ case 0xEA: /* FLAG */
+ return ((nec_state->F0 << 3) | (nec_state->F1 << 5));
+ case 0xEB: /* PRC */
+ return nec_state->PRC;
+ break;
+ case 0xFF: /* IDB */
+ return nec_state->IDB;
+ break;
+ default:
+ logerror("%06x: Read from special function register %02x\n",PC(nec_state),o);
+ return 0;
+ }
+}
+
+void write_sfr(v25_state_t *nec_state, unsigned o, unsigned d)
+{
+ switch(o)
+ {
+ case 0xEA: /* FLAG */
+ nec_state->F0 = ((d & 0x08) == 0x08); \
+ nec_state->F1 = ((d & 0x20) == 0x20); \
+ break;
+ case 0xEB: /* PRC */
+ nec_state->PRC = d & 0x4F;
+ break;
+ case 0xFF: /* IDB */
+ nec_state->IDB = d;
+ break;
+ default:
+ logerror("%06x: Wrote %02x to special function register %02x\n",PC(nec_state),d,o);
+ }
+}
+
+int v25_read_byte(v25_state_t *nec_state, unsigned a)
+{
+ unsigned page = a >> 8;
+ unsigned offs = a & 0xff;
+
+ if(RAMEN && page == (nec_state->IDB << 4 | 0xE))
+ return nec_state->ram.b[BYTE_XOR_LE(offs)];
+
+ if(a == 0xFFFFF || page == (nec_state->IDB << 4 | 0xF))
+ return read_sfr(nec_state, offs);
+
+ return nec_state->program->read_byte(a);
+}
+
+int v25_read_word(v25_state_t *nec_state, unsigned a)
+{
+ if( a & 1 )
+ return (v25_read_byte(nec_state, a) | (v25_read_byte(nec_state, a + 1) << 8));
+
+ unsigned page = a >> 8;
+ unsigned offs = a & 0xff;
+
+ if(RAMEN && page == (nec_state->IDB << 4 | 0xE))
+ return nec_state->ram.w[offs/2];
+
+ if(page == (nec_state->IDB << 4 | 0xF))
+ return (read_sfr(nec_state, offs) | (read_sfr(nec_state, offs+1) << 8));
+
+ if(a == 0xFFFFE) /* not sure about this */
+ return (nec_state->program->read_byte(a) | (read_sfr(nec_state, 0xFF) << 8));
+
+ return nec_state->program->read_word(a);
+}
+
+void v25_write_byte(v25_state_t *nec_state, unsigned a, unsigned d)
+{
+ unsigned page = a >> 8;
+ unsigned offs = a & 0xff;
+
+ if(RAMEN && page == (nec_state->IDB << 4 | 0xE))
+ {
+ nec_state->ram.b[BYTE_XOR_LE(offs)] = d;
+ return;
+ }
+
+ if(a == 0xFFFFF || page == (nec_state->IDB << 4 | 0xF))
+ {
+ write_sfr(nec_state, offs, d);
+ return;
+ }
+
+ nec_state->program->write_byte(a, d);
+}
+
+void v25_write_word(v25_state_t *nec_state, unsigned a, unsigned d)
+{
+ if( a & 1 )
+ {
+ v25_write_byte(nec_state, a, d & 0xff);
+ v25_write_byte(nec_state, a + 1, d >> 8);
+ return;
+ }
+
+ unsigned page = a >> 8;
+ unsigned offs = a & 0xff;
+
+ if(RAMEN && page == (nec_state->IDB << 4 | 0xE))
+ {
+ nec_state->ram.w[offs/2] = d;
+ return;
+ }
+
+ if(page == (nec_state->IDB << 4 | 0xF))
+ {
+ write_sfr(nec_state, offs, d & 0xff);
+ write_sfr(nec_state, offs + 1, d >> 8);
+ return;
+ }
+
+ if(a == 0xFFFFE) /* not sure about this */
+ {
+ nec_state->program->write_byte(a, d & 0xff);
+ write_sfr(nec_state, 0xFF, d >> 8);
+ return;
+ }
+
+ nec_state->program->write_word(a, d);
+}
diff --git a/src/mame/drivers/cb2001.c b/src/mame/drivers/cb2001.c
index 967f168d340..37ba7dce5da 100644
--- a/src/mame/drivers/cb2001.c
+++ b/src/mame/drivers/cb2001.c
@@ -792,7 +792,7 @@ static const ay8910_interface cb2001_ay8910_config =
static const nec_config cb2001_config = { cb2001_decryption_table, };
static MACHINE_CONFIG_START( cb2001, driver_device )
- MDRV_CPU_ADD("maincpu", V30, 20000000) // CPU91A-011-0016JK004; encrypted cpu like nec v25/35 used in some irem game
+ MDRV_CPU_ADD("maincpu", V35, 20000000) // CPU91A-011-0016JK004; encrypted cpu like nec v25/35 used in some irem game
MDRV_CPU_CONFIG(cb2001_config)
MDRV_CPU_PROGRAM_MAP(cb2001_map)
MDRV_CPU_IO_MAP(cb2001_io)
diff --git a/src/mame/drivers/m107.c b/src/mame/drivers/m107.c
index fbba3c37610..0697aee19af 100644
--- a/src/mame/drivers/m107.c
+++ b/src/mame/drivers/m107.c
@@ -824,7 +824,7 @@ static MACHINE_CONFIG_START( firebarr, driver_device )
MDRV_CPU_PROGRAM_MAP(main_map)
MDRV_CPU_IO_MAP(main_portmap)
- MDRV_CPU_ADD("soundcpu", V30, 14318000/2)
+ MDRV_CPU_ADD("soundcpu", V35, 14318000/2)
MDRV_CPU_PROGRAM_MAP(sound_map)
MDRV_CPU_CONFIG(firebarr_config)
diff --git a/src/mame/drivers/m72.c b/src/mame/drivers/m72.c
index c5e68c8b9bd..9a9725d067d 100644
--- a/src/mame/drivers/m72.c
+++ b/src/mame/drivers/m72.c
@@ -2318,7 +2318,7 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( cosmccop, driver_device )
/* basic machine hardware */
- MDRV_CPU_ADD("maincpu", V30,MASTER_CLOCK/2/2)
+ MDRV_CPU_ADD("maincpu", V35,MASTER_CLOCK/2/2)
MDRV_CPU_PROGRAM_MAP(kengo_map)
MDRV_CPU_IO_MAP(kengo_portmap)
diff --git a/src/mame/drivers/m90.c b/src/mame/drivers/m90.c
index 88e57b205ee..4e9ddf7ba18 100644
--- a/src/mame/drivers/m90.c
+++ b/src/mame/drivers/m90.c
@@ -689,7 +689,7 @@ static INTERRUPT_GEN( bomblord_interrupt )
/* Basic hardware -- no decryption table is setup for CPU */
static MACHINE_CONFIG_START( m90, driver_device )
/* basic machine hardware */
- MDRV_CPU_ADD("maincpu", V30,XTAL_32MHz/2/2) /* verified clock on cpu is 16Mhz but probably divided internally by 2 */
+ MDRV_CPU_ADD("maincpu", V35,XTAL_32MHz/2/2) /* verified clock on cpu is 16Mhz but probably divided internally by 2 */
MDRV_CPU_PROGRAM_MAP(m90_main_cpu_map)
MDRV_CPU_IO_MAP(m90_main_cpu_io_map)
MDRV_CPU_VBLANK_INT("screen", m90_interrupt)
@@ -763,47 +763,11 @@ MACHINE_CONFIG_END
static const nec_config bomberman_config ={ bomberman_decryption_table, };
-static MACHINE_CONFIG_START( bombrman, driver_device )
-
- /* basic machine hardware */
- MDRV_CPU_ADD("maincpu", V30,XTAL_32MHz/2/2) /* verified clock on cpu is 16Mhz but probably divided internally by 2 */
+static MACHINE_CONFIG_DERIVED( bombrman, m90 )
+ MDRV_CPU_MODIFY("maincpu")
MDRV_CPU_CONFIG(bomberman_config)
- MDRV_CPU_PROGRAM_MAP(m90_main_cpu_map)
- MDRV_CPU_IO_MAP(m90_main_cpu_io_map)
- MDRV_CPU_VBLANK_INT("screen", m90_interrupt)
-
- MDRV_CPU_ADD("soundcpu", Z80, XTAL_3_579545MHz) /* verified on pcb */
- MDRV_CPU_PROGRAM_MAP(m90_sound_cpu_map)
- MDRV_CPU_IO_MAP(m90_sound_cpu_io_map)
- MDRV_CPU_VBLANK_INT_HACK(nmi_line_pulse,128) /* clocked by V1? (Vigilante) */
- /* IRQs are generated by main Z80 and YM2151 */
- MDRV_SOUND_START(m72)
- MDRV_SOUND_RESET(m72)
-
- /* video hardware */
- MDRV_SCREEN_ADD("screen", RASTER)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
- MDRV_SCREEN_SIZE(64*8, 64*8)
+ MDRV_SCREEN_MODIFY("screen")
MDRV_SCREEN_VISIBLE_AREA(10*8, 50*8-1, 17*8, 47*8-1)
-
- MDRV_GFXDECODE(m90)
- MDRV_PALETTE_LENGTH(512)
-
- MDRV_VIDEO_START(m90)
- MDRV_VIDEO_UPDATE(m90)
-
- /* sound hardware */
- MDRV_SPEAKER_STANDARD_MONO("mono")
-
- MDRV_SOUND_ADD("ymsnd", YM2151, XTAL_3_579545MHz) /* verified on pcb */
- MDRV_SOUND_CONFIG(ym2151_config)
- MDRV_SOUND_ROUTE(0, "mono", 0.15)
- MDRV_SOUND_ROUTE(1, "mono", 0.15)
-
- MDRV_SOUND_ADD("dac", DAC, 0)
- MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.10)
MACHINE_CONFIG_END
static const nec_config dynablaster_config ={ dynablaster_decryption_table, };
@@ -811,7 +775,7 @@ static const nec_config dynablaster_config ={ dynablaster_decryption_table, };
static MACHINE_CONFIG_START( bbmanw, driver_device )
/* basic machine hardware */
- MDRV_CPU_ADD("maincpu", V30,XTAL_32MHz/2/2) /* verified clock on cpu is 16Mhz but probably divided internally by 2 */
+ MDRV_CPU_ADD("maincpu", V35,XTAL_32MHz/2/2) /* verified clock on cpu is 16Mhz but probably divided internally by 2 */
MDRV_CPU_CONFIG(dynablaster_config)
MDRV_CPU_PROGRAM_MAP(m90_main_cpu_map)
MDRV_CPU_IO_MAP(m90_main_cpu_io_map)
diff --git a/src/mame/drivers/m92.c b/src/mame/drivers/m92.c
index e448106b108..3c28807135b 100644
--- a/src/mame/drivers/m92.c
+++ b/src/mame/drivers/m92.c
@@ -181,7 +181,7 @@ Notes:
62256: 32K x8 SRAM
Custom chips:
- NANAO 08J27261A1 (PLCC84, encrypted V30 sound CPU, clocked at 14.31818MHz on pins 78 & 79)
+ NANAO 08J27261A1 (PLCC84, encrypted V35 sound CPU, clocked at 14.31818MHz on pins 78 & 79)
NANAO GA23 (QFP180)
@@ -924,7 +924,7 @@ static MACHINE_CONFIG_START( m92, driver_device )
MDRV_CPU_PROGRAM_MAP(m92_map)
MDRV_CPU_IO_MAP(m92_portmap)
- MDRV_CPU_ADD("soundcpu" ,V30, 14318180/2) /* 14.31818 MHz */
+ MDRV_CPU_ADD("soundcpu" ,V35, 14318180/2) /* 14.31818 MHz */
MDRV_CPU_PROGRAM_MAP(sound_map)
MDRV_MACHINE_START(m92)
@@ -1293,7 +1293,7 @@ ROM_START( gunforce )
ROM_LOAD16_BYTE( "gf_h1-c.5l", 0x040001, 0x20000, CRC(c84188b7) SHA1(ff710be742f610d90538db296acdd435260bef12) )
ROM_LOAD16_BYTE( "gf_l1-c.5j", 0x040000, 0x20000, CRC(b189f72a) SHA1(f17d87349a57e1a4b20c4947e41edd7c39eaca13) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "gf_sh0.rom", 0x000001, 0x010000, CRC(3f8f16e0) SHA1(a9f568c1b585c2cf13b21716954dac0a89936fc6) )
ROM_LOAD16_BYTE( "gf_sl0.rom", 0x000000, 0x010000, CRC(db0b13a3) SHA1(6723026010610b706725a5284a7b8d70fe479dae) )
@@ -1320,7 +1320,7 @@ ROM_START( gunforcej )
ROM_LOAD16_BYTE( "gfb_h1-e.5l", 0x040001, 0x20000, CRC(d9744f5d) SHA1(056d6e6e9874c33dcebe2e0ec946117d5eaa5d76) )
ROM_LOAD16_BYTE( "gfb_l1-e.5j", 0x040000, 0x20000, CRC(a0f7b61b) SHA1(5fc7fc3f57e82a9ae4e1f3c3e8e3e3b0bd3ff8f5) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "gf_sh0.rom",0x000001, 0x010000, CRC(3f8f16e0) SHA1(a9f568c1b585c2cf13b21716954dac0a89936fc6) )
ROM_LOAD16_BYTE( "gf_sl0.rom",0x000000, 0x010000, CRC(db0b13a3) SHA1(6723026010610b706725a5284a7b8d70fe479dae) )
@@ -1347,7 +1347,7 @@ ROM_START( gunforceu )
ROM_LOAD16_BYTE( "gf_h1-d.5l", 0x040001, 0x20000, CRC(08a3736c) SHA1(0ae904cf486a371f8b635c1f9dc5201e38a73f5a) )
ROM_LOAD16_BYTE( "gf_l1-d.5j", 0x040000, 0x20000, CRC(435f524f) SHA1(65c282ec50123747880850bc32c7ace0471ed9f2) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "gf_sh0.rom",0x000001, 0x010000, CRC(3f8f16e0) SHA1(a9f568c1b585c2cf13b21716954dac0a89936fc6) )
ROM_LOAD16_BYTE( "gf_sl0.rom",0x000000, 0x010000, CRC(db0b13a3) SHA1(6723026010610b706725a5284a7b8d70fe479dae) )
@@ -1455,7 +1455,7 @@ ROM_START( hook )
ROM_LOAD16_BYTE( "h-h1.rom", 0x080001, 0x020000, CRC(264ba1f0) SHA1(49ecf9b3e5375629607fb747abe264406065580b) )
ROM_LOAD16_BYTE( "h-l1.rom", 0x080000, 0x020000, CRC(f9913731) SHA1(be7871d6843e76f66fae6b501c5ee83ccc366463) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "h-sh0.rom", 0x000001, 0x010000, CRC(86a4e56e) SHA1(61163010e713be64368a4126f17d33cbdcf0c5ed) )
ROM_LOAD16_BYTE( "h-sl0.rom", 0x000000, 0x010000, CRC(10fd9676) SHA1(1b51181a8f0711997e107e9a8b8f44341d08ea81) )
@@ -1482,7 +1482,7 @@ ROM_START( hooku )
ROM_LOAD16_BYTE( "h-h1.rom", 0x080001, 0x020000, CRC(264ba1f0) SHA1(49ecf9b3e5375629607fb747abe264406065580b) )
ROM_LOAD16_BYTE( "h-l1.rom", 0x080000, 0x020000, CRC(f9913731) SHA1(be7871d6843e76f66fae6b501c5ee83ccc366463) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "h-sh0.rom", 0x000001, 0x010000, CRC(86a4e56e) SHA1(61163010e713be64368a4126f17d33cbdcf0c5ed) )
ROM_LOAD16_BYTE( "h-sl0.rom", 0x000000, 0x010000, CRC(10fd9676) SHA1(1b51181a8f0711997e107e9a8b8f44341d08ea81) )
@@ -1509,7 +1509,7 @@ ROM_START( hookj )
ROM_LOAD16_BYTE( "h-h1.rom", 0x080001, 0x020000, CRC(264ba1f0) SHA1(49ecf9b3e5375629607fb747abe264406065580b) )
ROM_LOAD16_BYTE( "h-l1.rom", 0x080000, 0x020000, CRC(f9913731) SHA1(be7871d6843e76f66fae6b501c5ee83ccc366463) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "h-sh0-a.3l", 0x000001, 0x010000, CRC(bd3d1f61) SHA1(0c884a0b5519f9c0823128872baf7b0c4078e5c4) )
ROM_LOAD16_BYTE( "h-sl0-a.3n", 0x000000, 0x010000, CRC(76371def) SHA1(b7a86fd4eecdd8a538c32e08cd920c27bd50924b) )
@@ -1561,7 +1561,7 @@ ROM_START( rtypeleo )
ROM_LOAD16_BYTE( "rtl-h1-d.bin", 0x080001, 0x020000, CRC(352ff444) SHA1(e302bc8dbf80abe5c1aaf02e92473fc72a796e72) )
ROM_LOAD16_BYTE( "rtl-l1-d.bin", 0x080000, 0x020000, CRC(fd34ea46) SHA1(aca12d46ebff94505d03884e45805e84bbece6a7) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "rtl-sh0a.bin", 0x000001, 0x010000, CRC(e518b4e3) SHA1(44ec1d6b27bc3e49ad967f43960398ba1a19c5e3) )
ROM_LOAD16_BYTE( "rtl-sl0a.bin", 0x000000, 0x010000, CRC(896f0d36) SHA1(9246b1a5a8717dd823340d4cb79012a3df6fa4b7) )
@@ -1588,7 +1588,7 @@ ROM_START( rtypeleoj )
ROM_LOAD16_BYTE( "rtl-h1-d.bin", 0x080001, 0x020000, CRC(352ff444) SHA1(e302bc8dbf80abe5c1aaf02e92473fc72a796e72) )
ROM_LOAD16_BYTE( "rtl-l1-d.bin", 0x080000, 0x020000, CRC(fd34ea46) SHA1(aca12d46ebff94505d03884e45805e84bbece6a7) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "rtl-sh0a.bin", 0x000001, 0x010000, CRC(e518b4e3) SHA1(44ec1d6b27bc3e49ad967f43960398ba1a19c5e3) )
ROM_LOAD16_BYTE( "rtl-sl0a.bin", 0x000000, 0x010000, CRC(896f0d36) SHA1(9246b1a5a8717dd823340d4cb79012a3df6fa4b7) )
@@ -1615,7 +1615,7 @@ ROM_START( mysticri )
ROM_LOAD16_BYTE( "mr-h1-b.bin", 0x080001, 0x010000, CRC(e17649b9) SHA1(fb09a0ccd22475d81ba667c88d1b5eb7cc64728f) )
ROM_LOAD16_BYTE( "mr-l1-b.bin", 0x080000, 0x010000, CRC(a87c62b4) SHA1(d3cae0f420faeb4556767b6ad817fc39d31b7273) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "mr-sh0.bin", 0x000001, 0x010000, CRC(50d335e4) SHA1(a1a92e95fbd6b99d904a82cea4a1ff6fd2ac8dde) )
ROM_LOAD16_BYTE( "mr-sl0.bin", 0x000000, 0x010000, CRC(0fa32721) SHA1(1561ddd2597592060b8a78f1dff6cbb25fb7cd2e) )
@@ -1642,7 +1642,7 @@ ROM_START( gunhohki )
ROM_LOAD16_BYTE( "mr-h1.bin", 0x080001, 0x010000, CRC(c9532b60) SHA1(b83322ba7bb3eea4c64dd65b3c0a5cade61841d8) )
ROM_LOAD16_BYTE( "mr-l1.bin", 0x080000, 0x010000, CRC(6349b520) SHA1(406620d9c63ce3d6801105c8122e1d0bbe6152ad) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "mr-sh0.bin", 0x000001, 0x010000, CRC(50d335e4) SHA1(a1a92e95fbd6b99d904a82cea4a1ff6fd2ac8dde) )
ROM_LOAD16_BYTE( "mr-sl0.bin", 0x000000, 0x010000, CRC(0fa32721) SHA1(1561ddd2597592060b8a78f1dff6cbb25fb7cd2e) )
@@ -1669,7 +1669,7 @@ ROM_START( mysticrib )
ROM_LOAD16_BYTE( "h1", 0x080001, 0x010000, CRC(4dcb085b) SHA1(7c053f5ef2978e574d3d2d9f5c12035473d13c3b) )
ROM_LOAD16_BYTE( "l1", 0x080000, 0x010000, CRC(88df4f70) SHA1(f55769a107fe3f5446d8268f66e895b02727c61e) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
// older revision code? rev 3.31, doesn't work?
ROM_LOAD16_BYTE( "sh0", 0x000001, 0x010000, CRC(fc7221ee) SHA1(4e714f31ce0d1bb2f6c649a26af748f96912848e) )
ROM_LOAD16_BYTE( "sl0", 0x000000, 0x010000, CRC(65c809e6) SHA1(45a860b250219a15aa8a2177251f4d3f2e559b9e) )
@@ -1698,7 +1698,7 @@ ROM_START( uccops )
ROM_LOAD16_BYTE( "uc_h1.rom", 0x080001, 0x020000, CRC(8d29bcd6) SHA1(470b77d1b8f88824bac294bd12a205a23dad2287) )
ROM_LOAD16_BYTE( "uc_l1.rom", 0x080000, 0x020000, CRC(a8a402d8) SHA1(0b40fb69f0a3e24e6b60117d2d2fd4cc170bc621) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "uc_sh0.rom", 0x000001, 0x010000, CRC(df90b198) SHA1(6b334457f06f6b9cfb355ba3d399bebb37b5733e) )
ROM_LOAD16_BYTE( "uc_sl0.rom", 0x000000, 0x010000, CRC(96c11aac) SHA1(16c47b4f97f0532fff30bb163f26d8cf6b923a2e) )
@@ -1725,7 +1725,7 @@ ROM_START( uccopsu )
ROM_LOAD16_BYTE( "uc_h1-g.rom", 0x080001, 0x020000, CRC(6b8ca2de) SHA1(1096b93bbaa4c97d4900e8c083cde99195cad5ba) )
ROM_LOAD16_BYTE( "uc_l1-g.rom", 0x080000, 0x020000, CRC(2bdec7dd) SHA1(58817099e74fd5bc299b7bc14d83ee75ed200b53) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "uc_sh0.rom", 0x000001, 0x010000, CRC(df90b198) SHA1(6b334457f06f6b9cfb355ba3d399bebb37b5733e) )
ROM_LOAD16_BYTE( "uc_sl0.rom", 0x000000, 0x010000, CRC(96c11aac) SHA1(16c47b4f97f0532fff30bb163f26d8cf6b923a2e) )
@@ -1766,7 +1766,7 @@ ROM_START( uccopsar ) /* Alpha Renewal Version */
ROM_LOAD16_BYTE( "uc_h1.ic27", 0x080001, 0x020000, CRC(79d79742) SHA1(f9c03c4d42b5b3d0f0185462868b04f1bb679f90) )
ROM_LOAD16_BYTE( "uc_l1.ic38", 0x080000, 0x020000, CRC(37211581) SHA1(b8fdff96b2c7d5cf2975dcf81c00581ccb595c15) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "uc_sh0.ic30", 0x000001, 0x010000, CRC(f0ca1b03) SHA1(07154a2c747091f8be23587c109d91ed1672da6e) )
ROM_LOAD16_BYTE( "uc_sl0.ic31", 0x000000, 0x010000, CRC(d1661723) SHA1(bdc00196aa2074e7b21e5949f73e9f2b93d76fd9) )
@@ -1793,7 +1793,7 @@ ROM_START( uccopsj )
ROM_LOAD16_BYTE( "uc_h1_a.ic27", 0x080001, 0x020000, CRC(83f78dea) SHA1(6d197c3ea76beac31c3ea6e54a3ffea9d6c0c653) )
ROM_LOAD16_BYTE( "uc_l1_a.ic38", 0x080000, 0x020000, CRC(19628280) SHA1(e6c06cb7c37e46a7db3b4f318e836aa5a2390eda) )
- ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V30 = NANAO custom D80001 (?) */
+ ROM_REGION( 0x100000, "soundcpu", 0 ) /* 1MB for the audio CPU - encrypted V35 = NANAO custom D80001 (?) */
ROM_LOAD16_BYTE( "uc_sh0.ic30", 0x000001, 0x010000, CRC(f0ca1b03) SHA1(07154a2c747091f8be23587c109d91ed1672da6e) )
ROM_LOAD16_BYTE( "uc_sl0.ic31", 0x000000, 0x010000, CRC(d1661723) SHA1(bdc00196aa2074e7b21e5949f73e9f2b93d76fd9) )
diff --git a/src/mame/drivers/segas32.c b/src/mame/drivers/segas32.c
index 80798577ad3..987ade72a8c 100644
--- a/src/mame/drivers/segas32.c
+++ b/src/mame/drivers/segas32.c
@@ -2232,11 +2232,14 @@ static MACHINE_CONFIG_START( system32, driver_device )
MACHINE_CONFIG_END
+static const nec_config ga2_v25_config ={ ga2_v25_opcode_table, };
+
static MACHINE_CONFIG_DERIVED( system32_v25, system32 )
/* add a V25 for protection */
MDRV_CPU_ADD("mcu", V25, 10000000)
MDRV_CPU_PROGRAM_MAP(ga2_v25_map)
+ MDRV_CPU_CONFIG(ga2_v25_config)
MACHINE_CONFIG_END
@@ -2475,7 +2478,7 @@ ROM_END
**************************************************************************************************************************
**************************************************************************************************************************
Arabian Fight
- protected via a custom V20 with encrypted code
+ protected via a custom V25 with encrypted code
*/
ROM_START( arabfgt )
@@ -2542,7 +2545,7 @@ ROM_END
/**************************************************************************************************************************
Arabian Fight (Japan)
- protected via a custom V20 with encrypted code
+ protected via a custom V25 with encrypted code
*/
ROM_START( arabfgtj )
ROM_REGION( 0x200000, "maincpu", 0 ) /* v60 code + data */
@@ -2818,7 +2821,7 @@ ROM_END
**************************************************************************************************************************
**************************************************************************************************************************
Golden Axe: The Return of Death Adder
- protected via a custom V20 with encrypted code
+ protected via a custom V25 with encrypted code
*/
ROM_START( ga2 )
ROM_REGION( 0x200000, "maincpu", 0 ) /* v60 code + data */
@@ -2853,7 +2856,7 @@ ROM_END
/**************************************************************************************************************************
Golden Axe: The Return of Death Adder (U.S.)
- protected via a custom V20 with encrypted code
+ protected via a custom V25 with encrypted code
Sega Game ID codes:
Game: 833-8932-02 GOLDEN AXE II AC USA
Rom board: 833-8933-01
@@ -2893,7 +2896,7 @@ ROM_END
/**************************************************************************************************************************
Golden Axe: The Return of Death Adder (Japan)
- protected via a custom V20 with encrypted code
+ protected via a custom V25 with encrypted code
*/
ROM_START( ga2j )
ROM_REGION( 0x200000, "maincpu", 0 ) /* v60 code + data */
diff --git a/src/mame/includes/segas32.h b/src/mame/includes/segas32.h
index a06d3117fd8..767dd3accfc 100644
--- a/src/mame/includes/segas32.h
+++ b/src/mame/includes/segas32.h
@@ -29,6 +29,7 @@ WRITE16_HANDLER( jleague_protection_w );
READ16_HANDLER( dbzvrvs_protection_r );
WRITE16_HANDLER( dbzvrvs_protection_w );
+extern const UINT8 ga2_v25_opcode_table[];
void decrypt_ga2_protrom(running_machine *machine);
READ16_HANDLER( ga2_dpram_r );
WRITE16_HANDLER( ga2_dpram_w );
diff --git a/src/mame/machine/segas32.c b/src/mame/machine/segas32.c
index 2302b609823..dae81b3377e 100644
--- a/src/mame/machine/segas32.c
+++ b/src/mame/machine/segas32.c
@@ -12,7 +12,7 @@
#define xxxx 0x00
-static const UINT8 ga2_v25_opcode_table[256] = {
+const UINT8 ga2_v25_opcode_table[256] = {
xxxx,xxxx,0xEA,xxxx,xxxx,0x8B,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,
xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,0xFA,
xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,0x49,xxxx,xxxx,xxxx,
@@ -33,41 +33,22 @@ static const UINT8 ga2_v25_opcode_table[256] = {
#undef xxxx
-static void nec_v25_cpu_decrypt(running_machine *machine)
+void decrypt_ga2_protrom(running_machine *machine)
{
int i;
- address_space *space = cputag_get_address_space(machine, "mcu", ADDRESS_SPACE_PROGRAM);
UINT8 *rom = memory_region(machine, "mcu");
- UINT8* decrypted = auto_alloc_array(machine, UINT8, 0x10000);
UINT8* temp = auto_alloc_array(machine, UINT8, 0x100000);
- // set CPU3 opcode base
- space->set_decrypted_region(0x00000, 0x0ffff, decrypted);
- space->set_decrypted_region(0xf0000, 0xfffff, decrypted);
-
// make copy of ROM so original can be overwritten
memcpy(temp, rom, 0x10000);
+ // unscramble the address lines
for(i = 0; i < 0x10000; i++)
- {
- int j = BITSWAP16(i, 14, 11, 15, 12, 13, 4, 3, 7, 5, 10, 2, 8, 9, 6, 1, 0);
-
- // normal ROM data with address swap undone
- rom[i] = temp[j];
-
- // decryped opcodes with address swap undone
- decrypted[i] = ga2_v25_opcode_table[ temp[j] ];
- }
+ rom[i] = temp[BITSWAP16(i, 14, 11, 15, 12, 13, 4, 3, 7, 5, 10, 2, 8, 9, 6, 1, 0)];
auto_free(machine, temp);
}
-void decrypt_ga2_protrom(running_machine *machine)
-{
- nec_v25_cpu_decrypt(machine);
-}
-
-
WRITE16_HANDLER( ga2_dpram_w )
{
/* does it ever actually write.. */