mirror of
https://github.com/holub/mame
synced 2025-05-18 19:49:35 +03:00
Implemented a preliminary V25/V35 CPU core [Alex Jackson]
This commit is contained in:
parent
855636d33c
commit
e8cfb9e513
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -319,13 +319,19 @@ src/emu/cpu/mn10200/mn10200.c svneol=native#text/plain
|
||||
src/emu/cpu/mn10200/mn10200.h svneol=native#text/plain
|
||||
src/emu/cpu/mn10200/mn102dis.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/nec.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/nec.h -text svneol=native#text/plain
|
||||
src/emu/cpu/nec/nec.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necdasm.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/necea.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/nechost.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necinstr.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/necinstr.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necmodrm.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necpriv.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/v25.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/v25instr.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/v25instr.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/v25priv.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/v25sfr.c svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1.c svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1.h svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1dasm.c svneol=native#text/plain
|
||||
|
@ -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 \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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,
|
||||
|
672
src/emu/cpu/nec/necinstr.c
Normal file
672
src/emu/cpu/nec/necinstr.c
Normal file
@ -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));
|
||||
}
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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; \
|
||||
|
622
src/emu/cpu/nec/v25.c
Normal file
622
src/emu/cpu/nec/v25.c
Normal file
@ -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);
|
34
src/emu/cpu/nec/v25instr.c
Normal file
34
src/emu/cpu/nec/v25instr.c
Normal file
@ -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); }
|
510
src/emu/cpu/nec/v25instr.h
Normal file
510
src/emu/cpu/nec/v25instr.h
Normal file
@ -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 */
|
||||
};
|
455
src/emu/cpu/nec/v25priv.h
Normal file
455
src/emu/cpu/nec/v25priv.h
Normal file
@ -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++; \
|
||||
} \
|
||||
}
|
137
src/emu/cpu/nec/v25sfr.c
Normal file
137
src/emu/cpu/nec/v25sfr.c
Normal file
@ -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);
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) )
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 );
|
||||
|
@ -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.. */
|
||||
|
Loading…
Reference in New Issue
Block a user