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

📄 zz80.c

📁 DGen源码最后版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/* z80stb.c * Zilog Z80 processor emulator in C. Modified to be API compliant with Neil * Bradley's MZ80 (for ported projects) * Ported to 'C' by Jeff Mitchell; original copyright follows: * * Abstract: *   Internal declarations for Zilog Z80 emulator. * * Revisions: *   18-Apr-97 EAM Created *   ??-???-97 EAM Released in MageX 0.5 *   26-Jul-97 EAM Fixed Time Pilot slowdown bug and *      Gyruss hiscore bugs (opcode 0xC3) * * Original copyright (C) 1997 Edward Massey */// Dave#define FALSE 0#define TRUE 1#define HOST_TO_LE16 /**/#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "mz80.h"#include "z80stb.h"/* *************************************************************************** * Edward's Internals (so to speak) * *************************************************************************** */#define _ASSERT assertULONG m_cRef; // reference countunion { /* WARN: Endianness! */  WORD m_regAF;  struct {#ifdef BIG_ENDIAN    BYTE m_regA;    BYTE m_regF;#else    BYTE m_regF;    BYTE m_regA;#endif  } regAFs;} regAF;#define m_regAF regAF.m_regAF#define m_regF regAF.regAFs.m_regF#define m_regA regAF.regAFs.m_regAunion { /* WARN: Endianness! */  WORD m_regBC;  struct {#ifdef BIG_ENDIAN    BYTE m_regB;    BYTE m_regC;#else    BYTE m_regC;    BYTE m_regB;#endif  } regBCs;} regBC;#define m_regBC regBC.m_regBC#define m_regB regBC.regBCs.m_regB#define m_regC regBC.regBCs.m_regCunion { /* WARN: Endianness! */  WORD m_regDE;  struct {#ifdef BIG_ENDIAN    BYTE m_regD;    BYTE m_regE;#else    BYTE m_regE;    BYTE m_regD;#endif  } regDEs;} regDE;#define m_regDE regDE.m_regDE#define m_regD regDE.regDEs.m_regD#define m_regE regDE.regDEs.m_regEunion { /* WARN: Endianness! */  WORD m_regHL;  struct {#ifdef BIG_ENDIAN    BYTE m_regH;    BYTE m_regL;#else    BYTE m_regL;    BYTE m_regH;#endif  } regHLs;} regHL;#define m_regHL regHL.m_regHL#define m_regH regHL.regHLs.m_regH#define m_regL regHL.regHLs.m_regLunion { /* WARN: Endianness! */  WORD m_regIX;  struct {#ifdef BIG_ENDIAN    BYTE m_regIXh;    BYTE m_regIXl;#else    BYTE m_regIXl;    BYTE m_regIXh;#endif  } regIXs;} regIX;#define m_regIX regIX.m_regIX#define m_regIXl regIX.regIXs.m_regIXl#define m_regIXh regIX.regIXs.m_regIXhunion {  WORD m_regIY;  struct {#ifdef BIG_ENDIAN    BYTE m_regIYh;    BYTE m_regIYl;#else    BYTE m_regIYl;    BYTE m_regIYh;#endif  } regIYs;} regIY;#define m_regIY regIY.m_regIY#define m_regIYl regIY.regIYs.m_regIYl#define m_regIYh regIY.regIYs.m_regIYhconst BYTE *m_rgbOpcode; // takes place of the PC registerLPBYTE m_rgbStack; // takes place of the SP registerLPBYTE m_rgbMemory; // direct access to memory buffer (RAM)const BYTE *m_rgbOpcodeBase; // "base" pointer for m_rgbOpcodeLPBYTE m_rgbStackBase;static int cCycles = 0;BYTE m_regR; // consider:  should be int for performance?BYTE m_regI; // consider:  combine into// TODO:  combine into a single int...int m_iff1, m_iff2;BOOL m_fHalt;int m_nIM;BOOL m_fPendingInterrupt = FALSE;WORD m_regAF2;static WORD m_regBC2;static WORD m_regDE2;static WORD m_regHL2;WORD z80intAddr = 0x38;WORD z80nmiAddr = 0x66;/* *************************************************************************** * Pre-calculated math tables and junk (sucked from Marat and Edward) * *************************************************************************** */void InitTables (void);BYTE ZSTable[256];BYTE ZSPTable[256];BYTE rgfAdd[256][256];BYTE rgfSub[256][256];BYTE rgfAddc[256][256][2];BYTE rgfSubc[256][256][2];BYTE rgfInc[256];BYTE rgfDec[256];BYTE rgfBit[256][8];static UINT32 dwElapsedTicks = 0;/* #include "z80daa.h" */#include "z80stbd.h"/* *************************************************************************** * Retrocade guts stuff * *************************************************************************** */static struct MemoryReadByte *z80MemoryRead = NULL;static struct MemoryWriteByte *z80MemoryWrite = NULL;static struct z80PortRead *z80IoRead = NULL;static struct z80PortWrite *z80IoWrite = NULL;WORD z80pc = 0;/* *************************************************************************** * Retrocade interface follows * *************************************************************************** *//* reset registers, interrupts, memory read/write memory handlers, * port read and writing handlers, etc. */void mz80reset(void) {  InitTables();  m_fPendingInterrupt = FALSE;  m_rgbOpcodeBase = m_rgbMemory;  /* m_rgbMemory = */  m_rgbStackBase = m_rgbMemory;  m_regAF = 0;  m_regBC = 0;  m_regDE = 0;  m_regHL = 0;  m_regAF2 = 0;  m_regBC2 = 0;  m_regDE2 = 0;  m_regHL2 = 0;  m_regR = rand();  m_regI = 0;  m_fHalt = FALSE;  m_nIM = 0;  m_regIX = 0xffff;		// Yes, this intentional, and the way a Z80 comes  m_regIY = 0xffff;		// up in power-on state!  m_iff1 = 0;  m_iff2 = 0;	z80intAddr = 0x38;	z80nmiAddr = 0x66;  SetPC(0x0000);  SetSP(0x0000);#if 0  fprintf ( stderr, "Reset\n" );#endif}/* UINT32 mz80int(UINT32 a) { * return ( Irq ( (BYTE) ( a & 0xFF ) ) ); * } *//* UINT32 mz80nmi(void) { * return ( Nmi() ); * } *//* *************************************************************************** * Edward Memory Handlers (guesses) * *************************************************************************** */#define ImmedByte() *m_rgbOpcode++/* static */ UINT16 ImmedWord ( void ) {  WORD w = HOST_TO_LE16(*(WORD*)m_rgbOpcode);  m_rgbOpcode += 2;  return w; // attn: little endian specific}#define GetPC() ( (WORD)(m_rgbOpcode - m_rgbOpcodeBase) )void SetPC ( WORD wAddr ) {  m_rgbOpcode = &m_rgbOpcodeBase[wAddr];}void AdjustPC ( signed char cb ) {  m_rgbOpcode += cb;}void Push(WORD wArg) {  MemWriteByte(--m_rgbStack - m_rgbStackBase, HIBYTE(wArg));  MemWriteByte(--m_rgbStack - m_rgbStackBase, LOBYTE(wArg));}WORD Pop() {	unsigned short wAddr = 0;	wAddr = MemReadByte(m_rgbStack++ - m_rgbStackBase);	wAddr |= (MemReadByte(m_rgbStack++ - m_rgbStackBase) << 8);	return(wAddr);}WORD GetSP() {  return (WORD)(m_rgbStack - m_rgbStackBase);}void SetSP(WORD wAddr) {  m_rgbStack = &m_rgbStackBase[wAddr];}/* static */ UINT8 mz80GetMemory ( UINT16 addr ) {  struct MemoryReadByte *mr = z80MemoryRead;  z80pc = GetPC(); /* for some of the platforms */  while ( mr -> lowAddr != 0xffffffff ) {	 if (addr >= mr->lowAddr && addr <= mr->highAddr) {		z80pc = GetPC();		return ( mr -> memoryCall ( addr, mr ) );	 }	 ++mr;  }  return ( m_rgbMemory [ addr ] );}/* static */ void mz80PutMemory ( unsigned short int addr, unsigned char byte ) {  struct MemoryWriteByte *mr = z80MemoryWrite;  while ( mr->lowAddr != 0xffffffff ) {	 if (addr >= mr->lowAddr && addr <= mr->highAddr) {		z80pc = GetPC();		mr->memoryCall(addr, byte, mr);		return;	 }	 mr++;  }  m_rgbMemory [ addr ] = byte;}BYTE In(BYTE bPort) {  BYTE bVal;  // BYTE bVal = m_rgpfnPortRead[bPort](bPort);  struct z80PortRead *mr = z80IoRead;  z80pc = GetPC(); /* for some of the platforms */  while ( mr->lowIoAddr != 0xffff ) {    if ( bPort >= mr->lowIoAddr && bPort <= mr->highIoAddr) {      bVal = mr->IOCall ( bPort, mr );      break;    }    mr++;  }  m_regF = (m_regF & C_FLAG) | ZSPTable[bVal];  return bVal;}BYTE InRaw (BYTE bPort) {  BYTE bVal;  struct z80PortRead *mr = z80IoRead;  z80pc = GetPC(); /* for some of the platforms */  while ( mr->lowIoAddr != 0xffff ) {    if ( bPort >= mr->lowIoAddr && bPort <= mr->highIoAddr) {      bVal = mr->IOCall ( bPort, mr );      break;    }    mr++;  }  // m_regF = (m_regF & C_FLAG) | ZSPTable[bVal];  return bVal;}void Out(BYTE bPort, BYTE bVal) {  // m_rgpfnPortWrite[bPort](bPort, bVal);  struct z80PortWrite *mr = z80IoWrite;  z80pc = GetPC(); /* for some of the platforms */  while ( mr->lowIoAddr != 0xffff ) {    if (bPort >= mr->lowIoAddr && bPort <= mr->highIoAddr) {      mr->IOCall ( bPort, bVal, mr );      return;    }    mr++;  }}/* static */ void MemWriteWord ( UINT16 wAddr, UINT16 wVal ) {  MemWriteByte ( wAddr++, LOBYTE ( wVal ) );  MemWriteByte ( wAddr,   HIBYTE ( wVal ) );}/* static */ /* inline */ void MemWriteByte ( UINT16 wAddr, UINT8 bVal ) {  mz80PutMemory ( wAddr, bVal );}/* static */ /* inline */ UINT8 MemReadByte ( UINT16 wAddr ) {  return ( mz80GetMemory ( wAddr ) );}/* static */ /* inline */ UINT16 MemReadWord ( UINT16 wAddr ) {  UINT8 op1;  UINT8 op2;	op1 = MemReadByte(wAddr ++);	op2 = MemReadByte(wAddr);  return ( MAKEWORD ( op1, op2 ) );}/* *************************************************************************** * Retrocade guts stuff (again) (these guys are defined after macros) * *************************************************************************** */unsigned long int mz80GetContextSize(void) {  return ( sizeof ( CONTEXTMZ80 ) );}/* set memory base, etc. */void mz80GetContext ( void *receiver ) {  CONTEXTMZ80 *c = receiver;  c -> z80MemRead = z80MemoryRead;  c -> z80MemWrite = z80MemoryWrite;  c -> z80Base = (UINT8 *) m_rgbOpcodeBase;  c -> z80IoRead = z80IoRead;  c -> z80IoWrite = z80IoWrite;  c -> z80af = m_regAF;  c -> z80bc = m_regBC;  c -> z80de = m_regDE;  c -> z80hl = m_regHL;  c -> z80afprime = m_regAF2;  c -> z80bcprime = m_regBC2;  c -> z80deprime = m_regDE2;  c -> z80hlprime = m_regHL2;  c -> z80ix = m_regIX;  c -> z80iy = m_regIY;  c -> z80sp = GetSP();  c -> z80pc = GetPC();  c -> z80i = m_regI;  c -> z80r = m_regR;	c -> z80intAddr = z80intAddr;	c -> z80nmiAddr = z80nmiAddr;	c -> z80inInterrupt = m_iff1;	c -> z80interruptMode = m_nIM;	c -> z80interruptState = m_iff2;	c -> z80halted = m_fHalt;	#if 0  fprintf ( stderr, "GetContext\n" );#endif}void mz80SetContext( void *sender ) {  CONTEXTMZ80 *c = sender;  z80MemoryRead = c -> z80MemRead;  z80MemoryWrite = c -> z80MemWrite;  m_rgbMemory = c -> z80Base;  z80IoRead = c -> z80IoRead;  z80IoWrite = c -> z80IoWrite;  m_regAF = c -> z80af;  m_regBC = c -> z80bc;  m_regDE = c -> z80de;  m_regHL = c -> z80hl;  m_regAF2 = c -> z80afprime;  m_regBC2 = c -> z80bcprime;  m_regDE2 = c -> z80deprime;  m_regHL2 = c -> z80hlprime;  m_regIX = c -> z80ix;  m_regIY = c -> z80iy;  m_regI = c -> z80i;  m_regR = c -> z80r;  z80intAddr = c -> z80intAddr;  z80nmiAddr = c -> z80nmiAddr;  m_rgbOpcodeBase = m_rgbMemory;	m_iff1 = c->z80inInterrupt;	m_iff2 = c->z80interruptState;	m_nIM = c->z80interruptMode;	m_fHalt = c->z80halted;  SetPC ( c -> z80pc );  SetSP ( c -> z80sp );#if 0  fprintf ( stderr, "SetContext\n" );#endif}/* *************************************************************************** * Z80 Please-inline-my-ass opcodes * *************************************************************************** *//* inline */ int Ret0(int f){	if (f)	{		SetPC(Pop());		return 6;	}	else	{		return 0;	}}/* inline */ int Ret1(int f){	if (f)	{		return 0;	}	else	{		SetPC(Pop());		return 6;	}}/* inline */ WORD Adc_2 (WORD wArg1, WORD wArg2){#ifdef ARITH_TABLES	int q  = wArg1 + wArg2 + (m_regF & C_FLAG);	m_regF = (((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1)|((q&0x8000)>>8)|((q&65535)?0:Z_FLAG)|(((wArg2^wArg1^0x8000)&(wArg2^q)&0x8000)>>13);	return q;#else	int q  = wArg1 + wArg2 + (m_regF & C_FLAG);	m_regF = (((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1)|((q&0x8000)>>8)|((q&65535)?0:Z_FLAG)|(((wArg2^wArg1^0x8000)&(wArg2^q)&0x8000)>>13);	return q;#endif}/* inline */ WORD Sbc_2 (WORD wArg1, WORD wArg2){#ifdef ARITH_TABLES	int q   = wArg1 - wArg2 - (m_regF & C_FLAG);	m_regF  = (((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1)|((q&0x8000)>>8)|		((q&65535)?0:Z_FLAG)|(((wArg1^wArg2)&(wArg1^q)&0x8000)>>13)|N_FLAG;	return q;#else	int q   = wArg1 - wArg2 - (m_regF & C_FLAG);	m_regF  = (((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1)|((q&0x8000)>>8)|		((q&65535)?0:Z_FLAG)|(((wArg1^wArg2)&(wArg1^q)&0x8000)>>13)|N_FLAG;	return q;#endif}/* inline */ WORD Add_2 (WORD wArg1, WORD wArg2){#ifdef ARITH_TABLES	int q  = wArg1 + wArg2;	m_regF = (m_regF&(S_FLAG|Z_FLAG|V_FLAG))|(((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1);	return q;#else	int q  = wArg1 + wArg2;	m_regF = (m_regF&(S_FLAG|Z_FLAG|V_FLAG))|(((wArg1^q^wArg2)&0x1000)>>8)|((q>>16)&1);	return q;#endif}/* inline */ void Add_1 (BYTE bArg){#ifdef ARITH_TABLES	int q = m_regA + bArg;	m_regF = rgfAdd[m_regA][bArg];	m_regA = q;#else	int q = m_regA + bArg;	m_regF=ZSTable[q&255]|((q&256)>>8)| ((m_regA^q^bArg)&H_FLAG)| (((bArg^m_regA^0x80)&(bArg^q)&0x80)>>5);	m_regA=q;#endif}/* inline */ void Adc_1 (BYTE bArg){#ifdef ARITH_TABLES	int q  = m_regA + bArg + (m_regF & C_FLAG);	m_regF = rgfAddc[m_regA][bArg][m_regF & C_FLAG];	m_regA = q;#else	int q  = m_regA + bArg + (m_regF & C_FLAG);	m_regF = ZSTable[q & 255]|((q & 256)>>8)|((m_regA^q^bArg)&H_FLAG)|(((bArg^m_regA^0x80)&(bArg^q)&0x80)>>5);	m_regA = q;#endif}/* inline */ void Sub_1 (BYTE bArg){#ifdef ARITH_TABLES	int q  = m_regA - bArg;	m_regF = rgfSub[m_regA][bArg];	m_regA = q;#else	int q  = m_regA - bArg;	m_regF = ZSTable[q&255]|((q&256)>>8)|N_FLAG|((m_regA^q^bArg)&H_FLAG)|(((bArg^m_regA)&(m_regA^q)&0x80)>>5);	m_regA = q;#endif}/* inline */ void Sbc_1 (BYTE bArg){#ifdef ARITH_TABLES	int q = m_regA - bArg - (m_regF & C_FLAG);	m_regF = rgfSubc[m_regA][bArg][m_regF & C_FLAG];	m_regA = q;#else	int q = m_regA - bArg - (m_regF & C_FLAG);	m_regF=ZSTable[q&255]|((q&256)>>8)|N_FLAG|((m_regA^q^bArg)&H_FLAG)|(((bArg^m_regA)&(bArg^q)&0x80)>>5);	m_regA=q;#endif}/* inline */ void And (BYTE bArg){	m_regF = ZSPTable[m_regA &= bArg] | H_FLAG;}/* inline */ void Or(BYTE bArg){	m_regF = ZSPTable[m_regA |= bArg];}/* inline */ void Xor(BYTE bArg){	m_regF = ZSPTable[m_regA ^= bArg];}/* inline */ void Cp(BYTE bArg){#ifdef ARITH_TABLES	int q = m_regA - bArg;	m_regF = rgfSub[m_regA][bArg];#else	int q = m_regA - bArg;	m_regF = ZSTable[q&255]|((q&256)>>8)|N_FLAG|((m_regA^q^bArg)&H_FLAG)|(((bArg^m_regA)&(bArg^q)&0x80)>>5);#endif}/* inline */ static BYTE Inc(BYTE bArg){#ifdef ARITH_TABLES	bArg++;	m_regF = (m_regF & C_FLAG) | rgfInc[bArg];	return bArg;#else	bArg++;	m_regF = (m_regF&C_FLAG)|ZSTable[bArg]|((bArg==0x80)?V_FLAG:0)|((bArg&0x0F)?0:H_FLAG);	return bArg;#endif}/* inline */ static BYTE Dec(BYTE bArg){#ifdef ARITH_TABLES	m_regF = (m_regF & C_FLAG) | rgfDec[bArg--];	return bArg;#else	m_regF=(m_regF&C_FLAG)|N_FLAG|		((bArg==0x80)?V_FLAG:0)|((bArg&0x0F)?0:H_FLAG);	m_regF|=ZSTable[--bArg];	return bArg;#endif}// shouldn't even be members.../* inline */ BYTE Set(BYTE bArg, int nBit){	return (bArg | (1 << nBit));}/* inline */ BYTE Res(BYTE bArg, int nBit){	return (bArg & ~(1 << nBit));}/* inline */ void Bit(BYTE bArg, int nBit){#ifdef ARITH_TABLES	m_regF = (m_regF & C_FLAG) | rgfBit[bArg][nBit];#else	m_regF = (m_regF & C_FLAG) | H_FLAG | ((bArg&(1<< nBit))? ((nBit==7)?S_FLAG:0):Z_FLAG);#endif}/* inline */ BYTE Rlc(BYTE bArg){	int q  = bArg >> 7;	bArg   = (bArg << 1) | q;	m_regF = ZSPTable[bArg] | q;	return bArg;}/* inline */ BYTE Rrc(BYTE bArg){	int q = bArg & 1;	bArg = (bArg >> 1) | (q << 7);	m_regF = ZSPTable[bArg]|q;	return bArg;}/* inline */ BYTE Rl(BYTE bArg){	int q=bArg>>7;	bArg=(bArg<<1)|(m_regF&1);	m_regF=ZSPTable[bArg]|q;	return bArg;}/* inline */ BYTE Rr(BYTE bArg){	int q = bArg&1;	bArg=(bArg>>1)|(m_regF<<7);	m_regF=ZSPTable[bArg]|q;	return bArg;}/* inline */ BYTE Sll(BYTE bArg){	int q = bArg>>7;	bArg=(bArg<<1)|1;	m_regF=ZSPTable[bArg]|q;	return bArg;}

⌨️ 快捷键说明

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