/****************************************************************************
NEC V30MZ(V20/V30/V33) emulator
Small changes made by toshi (Cycle count macros changed , "THROUGH" macro added)
Small changes made by dox@space.pl (Corrected bug in NEG instruction , different AUX flag handling in some opcodes)
(Re)Written June-September 2000 by Bryan McPhail (mish@tendril.co.uk) based
on code by Oliver Bergmann (Raul_Bloodworth@hotmail.com) who based code
on the i286 emulator by Fabrice Frances which had initial work based on
David Hedley's pcemu(!).
This new core features 99% accurate cycle counts for each processor,
there are still some complex situations where cycle counts are wrong,
typically where a few instructions have differing counts for odd/even
source and odd/even destination memory operands.
Flag settings are also correct for the NEC processors rather than the
I86 versions.
Nb: This emulation should be faster than previous NEC cores, but
because the old cycle count values were far too high in many cases
the processor has to do more 'work' than before, so the overall effect
may be a slower core.
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned int
#define INT8 signed char
#define INT16 signed short
#define INT32 signed int
#include "necintrf.h"
#include "nec.h"
typedef union
{ /* eight general registers */
UINT16 w[8]; /* viewed as 16 bits registers */
UINT8 b[16]; /* or as 8 bit registers */
} necbasicregs;
typedef struct
{
necbasicregs regs;
UINT16 sregs[4];
UINT16 ip;
INT32 SignVal;
UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
UINT32 int_vector;
UINT32 pending_irq;
UINT32 nmi_state;
UINT32 irq_state;
int (*irq_callback)(int irqline);
} nec_Regs;
/***************************************************************************/
/* cpu state */
/***************************************************************************/
int nec_ICount;
int nec_Cycles;
static nec_Regs I;
static UINT32 cpu_type;
static UINT32 prefix_base; /* base address of the latest prefix segment */
char seg_prefix; /* prefix segment indicator */
/* 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 */
#include "necinstr.h"
#include "necea.h"
#include "necmodrm.h"
static int no_interrupt;
static UINT8 parity_table[256];
/***************************************************************************/
void nec_reset (void *param)
{
unsigned int i,j,c;
BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
memset( &I, 0, sizeof(I) );
no_interrupt=0;
I.sregs[CS] = 0xffff;
for (i = 0;i < 256; i++)
{
for (j = i, c = 0; j > 0; j >>= 1)
if (j & 1) c++;
parity_table[i] = !(c & 1);
}
I.ZeroVal = I.ParityVal = 1;
SetMD(1); /* set the mode-flag = native mode */
for (i = 0; i < 256; i++)
{
Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
}
for (i = 0xc0; i < 0x100; i++)
{
Mod_RM.RM.w[i] = (WREGS)( i & 7 );
Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
}
}
void nec_exit (void)
{
}
void nec_int(void)
{
WORD vector;
DWORD dest_seg, dest_off;
if(I.IF)
{
vector = cpu_interrupt();
if (vector != 0xFFFF)
{
i_pushf();
I.TF = I.IF = 0;
dest_off = ReadWord(vector);
dest_seg = ReadWord(vector+2);
PUSH(I.sregs[CS]);
PUSH(I.ip);
I.ip = (WORD)dest_off;
I.sregs[CS] = (WORD)dest_seg;
}
}
}
static void nec_interrupt(unsigned int_num,BOOLEAN md_flag)
{
UINT32 dest_seg, dest_off;
if (int_num == -1)
return;
i_pushf();
I.TF = I.IF = 0;
dest_off = ReadWord((int_num)*4);
dest_seg = ReadWord((int_num)*4+2);
PUSH(I.sregs[CS]);
PUSH(I.ip);
I.ip = (WORD)dest_off;
I.sregs[CS] = (WORD)dest_seg;
}
/****************************************************************************/
/* OPCODES */
/****************************************************************************/
#define OP(num,func_name) static void func_name(void)
OP( 0x00, i_add_br8 ) { DEF_br8; ADDB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x01, i_add_wr16 ) { DEF_wr16; ADDW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x02, i_add_r8b ) { DEF_r8b; ADDB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x03, i_add_r16w ) { DEF_r16w; ADDW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x04, i_add_ald8 ) { DEF_ald8; ADDB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x05, i_add_axd16) { DEF_axd16; ADDW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x06, i_push_es ) { PUSH(I.sregs[ES]); CLK(2); }
OP( 0x07, i_pop_es ) { POP(I.sregs[ES]); CLK(3); }
OP( 0x08, i_or_br8 ) { DEF_br8; ORB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x09, i_or_wr16 ) { DEF_wr16; ORW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x0a, i_or_r8b ) { DEF_r8b; ORB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x0b, i_or_r16w ) { DEF_r16w; ORW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x0e, i_push_cs ) { PUSH(I.sregs[CS]); CLK(2); }
OP( 0x0f, i_pre_nec ) { UINT32 ModRM, tmp, tmp2; /* pop cs at V30MZ? */
switch (FETCH) {
case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = I.regs.b[CL] & 0x7; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = I.regs.b[CL] & 0xf; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = I.regs.b[CL] & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = I.regs.b[CL] & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH) & 0x7; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH) & 0xf; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.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;
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
in_wsr_source.7z.zip (22个子文件)
ws_memory.c 2KB
winamp_sym_In2.h 4KB
nec
necinstr.h 16KB
necmodrm.h 2KB
nec.h 13KB
necintrf.h 2KB
nec.c 47KB
necea.h 4KB
wsr_winamp.h 35B
ws_io.c 3KB
wsr_player.h 454B
ws_audio.h 350B
winamp_sym_Out.h 2KB
ws_memory.h 227B
wsr_player.c 4KB
types.h 725B
winamp_sym_API.h 10KB
makefile 706B
wsr_winamp.c 10KB
ws_initialIo.h 3KB
ws_audio.c 8KB
ws_io.h 150B
共 22 条
- 1
资源评论
钱亚锋
- 粉丝: 90
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功