⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s2650.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************
 *
 *      Portable Signetics 2650 cpu emulation
 *
 *      Written by Juergen Buchmueller for use with MAME
 *
 *******************************************************/

#include "string.h"
#include "memory.h"
#include "types.h"
#include "S2650/s2650.h"
#include "S2650/s2650cpu.h"

/* define this to expand all EA calculations inline */
#define INLINE_EA

int     S2650_ICount    = 0;
static  S2650_Regs      S;

/* condition code changes for a byte */
static  byte    ccc[0x200] = {
	0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
	0x04,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
	0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
};

#define SET_CC(value) { S.psl = (S.psl & ~CC) | ccc[value]; }
#define SET_CC_OVF(value,before) { S.psl = (S.psl & ~(OVF+CC)) | ccc[value + ( ( (value^before) << 1) & 256 )]; }

/* read next opcode */
static  byte RDOP(void)
{
byte result = cpu_readop(S.page + S.iar);
	S.iar = (S.iar + 1) & PMSK;
	return result;
}

/* read next opcode argument */
static  byte RDOPARG(void)
{
byte result = cpu_readop_arg(S.page + S.iar);
	S.iar = (S.iar + 1) & PMSK;
	return result;
}

#define RDMEM(addr) cpu_readmem16(addr)

/* handy table to build relative offsets from HR */
static	int 	S2650_relative[0x100] = {
	  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
	-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,
	-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,
	-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,
	-16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1,
	  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
	-64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,
	-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,
	-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,
	-16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1,
};

/* build effective address with relative addressing */
#define _REL_EA(page) { 								\
byte	hr; 											\
	hr = RDOPARG(); /* get 'holding register' */        \
	/* build effective address within current 8K page */\
	S.ea = page + ((S.iar + S2650_relative[hr]) & PMSK);\
	if (hr & 0x80) /* indirect bit set ? */ 			\
	{													\
	int 	addr = S.ea;								\
		S2650_ICount -= 2;								\
		/* build indirect 32K address */				\
		S.ea = RDMEM(addr) << 8;						\
		if (!(++addr & PMSK))							\
		addr -= PLEN;									\
		S.ea = (S.ea + RDMEM(addr)) & AMSK; 			\
	}													\
}

/* build effective address with absolute addressing */
#define _ABS_EA() { 											\
byte	hr, dr; 												\
	hr = RDOPARG(); /* get 'holding register' */                \
	dr = RDOPARG(); /* get 'data bus register' */               \
	/* build effective address within current 8K page */		\
	S.ea = S.page + (((hr << 8) + dr) & PMSK);					\
	/* indirect addressing ? */ 								\
	if (hr & 0x80)												\
	{															\
	int addr = S.ea;											\
		S2650_ICount -= 2;										\
		/* build indirect 32K address */						\
		/* build indirect 32K address */						\
		S.ea = RDMEM(addr) << 8;								\
		if (!(++addr & PMSK))									\
			addr -= PLEN;										\
		S.ea = (S.ea + RDMEM(addr)) & AMSK; 					\
	}															\
	/* check for indexed addressing mode */ 					\
	switch (hr & 0x60)											\
	{															\
		case 0x00: /* not indexed */							\
			break;												\
		case 0x20: /* auto increment indexed */ 				\
			S.reg[S.r] += 1;									\
			S.ea = (S.ea & PAGE)+((S.ea+S.reg[S.r]) & PMSK);	\
			S.r = 0; /* absolute addressing reg is R0 */		\
			break;												\
		case 0x40: /* auto decrement indexed */ 				\
			S.reg[S.r] -= 1;									\
			S.ea = (S.ea & PAGE)+((S.ea+S.reg[S.r]) & PMSK);	\
			S.r = 0; /* absolute addressing reg is R0 */		\
			break;												\
		case 0x60: /* indexed */								\
			S.ea = (S.ea & PAGE)+((S.ea+S.reg[S.r]) & PMSK);	\
			S.r = 0; /* absolute addressing reg is R0 */		\
			break;												\
	}															\
}

/* build effective address with absolute addressing (branch) */
#define _BRA_EA() { 											\
byte	hr, dr; 												\
	hr = RDOPARG(); /* get 'holding register' */                \
	dr = RDOPARG(); /* get 'data bus register' */               \
	/* build address in 32K address space */					\
	S.ea = ((hr << 8) + dr) & AMSK; 							\
	/* indirect addressing ? */ 								\
	if (hr & 0x80)												\
	{															\
	int 	addr = S.ea;										\
		S2650_ICount -= 2;										\
		/* build indirect 32K address */						\
		S.ea = RDMEM(addr) << 8;								\
		if (!(++addr & PMSK))									\
			addr -= PLEN;										\
		S.ea = (S.ea + RDMEM(addr)) & AMSK; 					\
	}															\
}

/* swap registers 1-3 with 4-6 */
/* this is done when the RS bit in PSL changes */
#define SWAP_REGS { 		\
byte swap;					\
	swap = S.reg[1];		\
	S.reg[1] = S.reg[4];	\
	S.reg[4] = swap;		\
	swap = S.reg[2];		\
	S.reg[2] = S.reg[5];	\
	S.reg[5] = swap;		\
	swap = S.reg[3];		\
	S.reg[3] = S.reg[6];	\
	S.reg[6] = swap;		\
}

/* BRanch Relative if cond is true */
#define S_BRR(cond) {					\
	if (cond) { 						\
		REL_EA(S.page); 				\
		S.page = S.ea & PAGE;			\
		S.iar  = S.ea & PMSK;			\
		change_pc(S.ea);				\
	} else	S.iar = (S.iar + 1) & PMSK; \
}

/* Zero Branch Relative  */
#define S_ZBRR() {			\
	REL_EA(0x0000); 		\
	S.page = S.ea & PAGE;	\
	S.iar  = S.ea & PMSK;	\
	change_pc(S.ea);		\
}

/* BRanch Absolute if cond is true */
#define S_BRA(cond) {					\
	if (cond) { 						\
		BRA_EA();						\
		S.page = S.ea & PAGE;			\
		S.iar  = S.ea & PMSK;			\
		change_pc(S.ea);				\
	} else S.iar = (S.iar + 2) & PMSK;	\
}

/* Branch indeXed Absolute (R3) */
#define S_BXA() {						\
	BRA_EA();							\
	S.ea   = (S.ea + S.reg[3]) & AMSK;	\
	S.page = S.ea & PAGE;				\
	S.iar  = S.ea & PMSK;				\
	change_pc(S.ea);					\
}

/* Branch to Subroutine Relative if cond is true */
#define S_BSR(cond) {									\
	if (cond) { 										\
		REL_EA(S.page); 								\
		S.psu  = (S.psu & ~SP) | ((S.psu + 1) & SP);	\
		S.ras[S.psu & SP] = S.iar;						\
		S.page = S.ea & PAGE;							\
		S.iar  = S.ea & PMSK;							\
		change_pc(S.ea);								\
	} else	S.iar = (S.iar + 1) & PMSK; 				\
}

/* Zero Branch to Subroutine Relative */
#define S_ZBSR() {									\
	REL_EA(0x0000); 								\
	S.psu  = (S.psu & ~SP) | ((S.psu + 1) & SP);	\
	S.ras[S.psu & SP] = S.iar;						\
	S.page = S.ea & PAGE;							\
	S.iar  = S.ea & PMSK;							\
	change_pc(S.ea);								\
}

/* Branch to Subroutine Absolute */
#define S_BSA(cond) {								\
	if (cond) { 									\
		BRA_EA();									\
		S.psu = (S.psu & ~SP) | ((S.psu + 1) & SP); \
		S.ras[S.psu & SP] = S.iar;					\
		S.page = S.ea & PAGE;						\
		S.iar  = S.ea & PMSK;						\
		change_pc(S.ea);							\
	} else S.iar = (S.iar + 2) & PMSK;				\
}

/* Branch to Subroutine indeXed Absolute (R3) */
#define S_BSXA() {								\
	BRA_EA();									\
	S.ea  = (S.ea + S.reg[3]) & AMSK;			\
	S.psu = (S.psu & ~SP) | ((S.psu + 1) & SP); \
	S.ras[S.psu & SP] = S.iar;					\
	S.page = S.ea & PAGE;						\
	S.iar  = S.ea & PMSK;						\
	change_pc(S.ea);							\
}

/* RETurn from subroutine */
#define S_RET(cond) {								\
	if (cond) { 									\
		S.ea = S.ras[S.psu & SP];					\
		S.psu = (S.psu & ~SP) | ((S.psu - 1) & SP); \
		S.page = S.ea & PAGE;						\
		S.iar  = S.ea & PMSK;						\
		change_pc(S.ea);							\
	}												\
}

/* RETurn from subroutine and Enable interrupts */
#define S_RETE(cond) {								\
	if (cond) { 									\
		S.ea = S.ras[S.psu & SP];					\
		S.psu = (S.psu & ~SP) | ((S.psu - 1) & SP); \
		S.page = S.ea & PAGE;						\
		S.iar  = S.ea & PMSK;						\
		change_pc(S.ea);							\
		S.psu &= ~II;								\
	}												\
}

/* LOaD destination with source */
#define S_LOD(dest,source) {  \
	dest = source;		  \
	SET_CC(dest);		  \
}

/* SToRe source to memory addr (CC unchanged) */
#define S_STR(address,source) cpu_writemem16(address, source)

/* logical and destination with source */
#define S_AND(dest,source) {	\
	dest &= source; 			\
	SET_CC(dest);				\
}

/* logical inclusive or destination with source */
#define S_IOR(dest,source) {	\
	dest |= source; 			\
	SET_CC(dest);				\
}

/* logical exclusive or destination with source */
#define S_EOR(dest,source) {	\
	dest ^= source; 			\
	SET_CC(dest);				\
}

/* add source to destination */
#define S_ADD(dest,source) {							\
byte before = dest; 									\
	/* add source; carry only if WC is set */			\
	dest = dest + source + ((S.psl >> 3) & S.psl & C);	\
	S.psl &= ~(C + OVF + IDC);							\
	if (dest < before)									\
		S.psl |= C; 									\
	if ((dest & 15) < (before & 15))					\
		S.psl |= IDC;									\
	SET_CC_OVF(dest,before);							\
}

/* subtract source from destination */
#define S_SUB(dest,source) {									\
byte before = dest; 											\
	/* add source; carry only if WC is set */					\
	dest = dest - source - ((S.psl >> 3) & (S.psl ^ C) & C);	\
	S.psl &= ~(C + OVF + IDC);									\
	if (dest <= before) 										\
		S.psl |= C; 											\
	if ((dest & 15) > (before & 15))							\
		S.psl |= IDC;											\
	SET_CC_OVF(dest,before);									\
}

#define S_COM(reg,val) {			\
int 	d;							\
	S.psl &= ~CC;					\
	if (S.psl & COM)				\
		d = (byte)reg - (byte)val;	\
	else							\
		d = (char)reg - (char)val;	\
	if (d < 0)						\
		S.psl |= 0x80;				\
	else							\
	if (d > 0)						\
		S.psl |= 0x40;				\
}

#define S_DAR(dest) {	\
	if (!(S.psl & IDC)) \
		dest += 0x0a;	\
	if (!(S.psl & C))	\
		dest += 0xa0;	\
}

/* rotate register left */
#define S_RRL(dest) {											\
byte before = dest; 											\
	if (S.psl & WC) 											\
	{															\
	byte c = S.psl & C; 										\
		S.psl &= ~(C + IDC);									\
		dest = (before << 1) | c;								\
		S.psl |= (before >> 7) + (dest & IDC);					\
	} else	dest = (before << 1) | (before >> 7);				\
		SET_CC_OVF(dest,before);								\
}

/* rotate register right */
#define S_RRR(dest) {											\
byte	before = dest;											\
	if (S.psl & WC) 											\
	{															\
	byte c = S.psl & C; 										\
		S.psl &= ~(C + IDC);									\
		dest = (before >> 1) | (c << 7);						\
		S.psl |= (before & C) + (dest & IDC);					\
	} else	dest = (before >> 1) | (before << 7);				\
	SET_CC_OVF(dest,before);									\
}

/* store processor status upper to register 0 */
#define S_SPSU() {	\
	R0 = S.psu & ~PSU34; \
	SET_CC(R0); 	\
}

/* store processor status lower to register 0 */
#define S_SPSL() {	\
	R0 = S.psl; 	\
	SET_CC(R0); 	\
}

/* clear processor status upper, selective */
#define S_CPSU() {			\
byte cpsu = RDOPARG();		\
	S.psu = S.psu & ~cpsu;	\
}

/* clear processor status lower, selective */
#define S_CPSL() {							\
byte cpsl = RDOPARG();						\
		/* select 1st register set now ? */ \
		if ((cpsl & RS) && (S.psl & RS))	\
				SWAP_REGS;					\
		S.psl = S.psl & ~cpsl;				\
}

/* preset processor status upper, selective */
#define S_PPSU() {					\
byte ppsu = RDOPARG() & ~PSU34; 	\
	S.psu = S.psu | ppsu;			\
}

/* preset processor status lower, selective */
#define S_PPSL() {							\
byte ppsl = RDOPARG();						\
	/* select 2nd register set now ? */ 	\
	if ((ppsl & RS) && !(S.psl & RS))		\
		SWAP_REGS;							\
	S.psl = S.psl | ppsl;					\
}

/* test processor status upper */
#define S_TPSU() {				\
byte tpsu = RDOPARG();			\
	S.psl &= ~CC;				\
	if ((S.psu & tpsu) != tpsu) \
		S.psl |= 0x80;			\
}

/* test processor status lower */
#define S_TPSL() {						\
byte tpsl = RDOPARG();					\
	if ((S.psl & tpsl) != tpsl) 		\
		S.psl = (S.psl & ~CC) | 0x80;	\
	else								\
		S.psl &= ~CC;					\
}

/* test under mask immediate */
#define S_TMI(value) {			\
byte	tmi = RDOPARG();		\
	S.psl &= ~CC;				\
	if ((value & tmi) != tmi)	\
		S.psl |= 0x80;			\
}

#ifdef  INLINE_EA
#define REL_EA(page)    _REL_EA(page)
#define ABS_EA()        _ABS_EA()
#define BRA_EA()        _BRA_EA()
#else
static  void    REL_EA(unsigned short page)
        _REL_EA(page)
static  void    ABS_EA(void)
        _ABS_EA()
static  void    BRA_EA(void)
        _BRA_EA()
#endif

void	S2650_SetRegs(S2650_Regs * rgs)
{
	S = *rgs;
}

void	S2650_GetRegs(S2650_Regs * rgs)
{
	*rgs = S;
}

int     S2650_GetPC(void)
{
	return S.page + S.iar;
}

void	S2650_set_flag(int state)
{
	if (state)
		S.psu |= FO;
	else
		S.psu &= ~FO;
}

int 	S2650_get_flag(void)
{
	return (S.psu & FO) ? 1 : 0;
}

void    S2650_set_sense(int state)
{
	if (state)
		S.psu |= SI;
	else
		S.psu &= ~SI;
}

int 	S2650_get_sense(void)
{
	return (S.psu & SI) ? 1 : 0;
}

void    S2650_Reset(void)
{
	memset(&S, 0, sizeof(S));
	S.irq = S2650_INT_NONE;
	S.psl = COM | WC;
	S.psu = SI;
}

void    S2650_Cause_Interrupt(int type)
{

	S.irq = type;			/* set interrupt request (vector) */
}

void    S2650_Clear_Pending_Interrupts(void)
{
        S.irq = S2650_INT_NONE; /* clear interrupt request */
}

static  int S2650_Cycles[0x100] = {
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 3,3,3,3, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 3,3,3,3, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 3,3,3,3, 3,3,3,3, 3,3,3,3,
        2,2,2,2, 2,2,2,2, 3,3,3,3, 4,4,4,4,
        2,2,2,2, 3,3,3,3, 3,3,3,3, 3,3,3,3

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -