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

📄 cpu.c

📁 A Zilog Z80 simulator, debugger and profiler tailored for ZX Spectrum development (but generic enoug
💻 C
📖 第 1 页 / 共 3 页
字号:
			sprintf(Mnemonic, "ld (%s), sp", Symbol);		} else if(OP_ED_IM0(Opcode)) {			sprintf(Mnemonic, "im 0");                } else if(OP_ED_IM1(Opcode)) {                        sprintf(Mnemonic, "im 1");                } else if(OP_ED_IM2(Opcode)) {                        sprintf(Mnemonic, "im 2");		} else if(OP_ED_IN_R_C(Opcode)) {			NameRegister(OperandR(Opcode), NameR);			sprintf(Mnemonic, "in %s, (c)", NameR);		} else {			sprintf(Mnemonic, "???");		}	} else {		sprintf(Mnemonic, "???");	}}// Process an interrupt requestvoid ProcessIRQ() {	Push(PC.Word);	PC.Word=0x0038;	InterruptRequest=FALSE;}// Execute the Z80 instruction pointed to by PC.trap Step() {	reg OldAF, OldSP, OldPC, OldBC, OldDE, OldHL, OldIX, OldIY;	logic OldIFF1, OldIFF2;        word Word;	byte Byte;	Exception=TRAP_NONE;	IR=ReadMemory(PC.Word++);	OldAF=AF;	OldSP=SP;	OldPC=PC;	OldBC=BC;	OldDE=DE;	OldHL=HL;	OldIX=IX;	OldIY=IY;	OldIFF1=IFF1;	OldIFF2=IFF2;	UsefulInstruction=FALSE;	IndirectMemoryWrite=MemoryWrite=FALSE;	if(EnableInterrupts) IFF1=TRUE;	if(OP_IXPREFIX(IR)) {	        IR=ReadMemory(PC.Word++);		PointerReg=&IX;		Indexing=TRUE;		TStates+=4;	} else if(OP_IYPREFIX(IR)) {	        IR=ReadMemory(PC.Word++);		PointerReg=&IY;		Indexing=TRUE;		TStates+=4;	} else {		PointerReg=&HL;		Indexing=FALSE;	}	Index=0x00;	PHLOverhead=3;	if(OP_HLT(IR)) {		PC.Word--;		TStates+=4;		UsefulInstruction=TRUE;	} else if(OP_LD_R_S(IR)) {		if(Indexing) Index=ReadMemory(PC.Word++);		*OperandR(IR)=*OperandS(IR);		TStates+=4;	} else if(OP_LD_R_B(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);		*OperandR(IR)=ReadMemory(PC.Word++);		TStates+=7;        } else if(OP_LD_P_W(IR)) {                *OperandP(IR)=ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8);		TStates+=10;        } else if(OP_LD_SP_HL(IR)) {		SP.Word=PointerReg->Word;		TStates+=10;	} else if(OP_LD_A_PBC(IR)) {		AF.Bytes.H=ReadMemory(BC.Word);		TStates+=7;        } else if(OP_LD_A_PDE(IR)) {                AF.Bytes.H=ReadMemory(DE.Word);                TStates+=7;        } else if(OP_LD_A_PW(IR)) {                AF.Bytes.H=ReadMemory(ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8));                TStates+=13;        } else if(OP_LD_PW_A(IR)) {                WriteMemory(ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8), AF.Bytes.H);                TStates+=13;	} else if(OP_LD_HL_PW(IR)) {		word Address=ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8);		PointerReg->Word=ReadMemory(Address)|(ReadMemory(Address+1)<<8);		TStates+=16;	} else if(OP_LD_PBC_A(IR)) {		WriteMemory(BC.Word, AF.Bytes.H);		TStates+=7;	} else if(OP_LD_PDE_A(IR)) {		WriteMemory(DE.Word, AF.Bytes.H);		TStates+=7;	} else if(OP_ADD_S(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);		if(OPMOD_CARRYIN(IR)) AddByte(&AF.Bytes.H, *OperandS(IR)+(FlagC?1:0)); else AddByte(&AF.Bytes.H, *OperandS(IR));	} else if(OP_ADD_B(IR)) {                if(OPMOD_CARRYIN(IR)) AddByte(&AF.Bytes.H, ReadMemory(PC.Word++)+(FlagC?1:0)); else AddByte(&AF.Bytes.H, ReadMemory(PC.Word++));                TStates+=3;	} else if(OP_SUB_S(IR)) {                if(Indexing) Index=ReadMemory(PC.Word++);	        if(OPMOD_CARRYIN(IR)) SubByte(&AF.Bytes.H, *OperandS(IR)+(FlagC?1:0)); else SubByte(&AF.Bytes.H, *OperandS(IR));		FlagN=1;        } else if(OP_SUB_B(IR)) {                if(OPMOD_CARRYIN(IR)) /* ... */ ;                SubByte(&AF.Bytes.H, ReadMemory(PC.Word++));		FlagN=1;                TStates+=3;	} else if(OP_ADD_HL_P(IR)) {		AddWord(&PointerReg->Word, *OperandP(IR));	} else if(OP_INC_R(IR)) {	        byte* Operand; logic Negative;		if(Indexing) Index=ReadMemory(PC.Word++);                Operand=OperandR(IR);		Negative=SignBit(*Operand);		SetFlags(++(*Operand));		if(Negative^(SignBit(*Operand))) FlagPO=!(FlagPE=TRUE); else FlagPO=!(FlagPE=FALSE);// Overflow                FlagN=0;		TStates+=4;	} else if(OP_DEC_R(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);		SetFlags(--(*OperandR(IR)));		FlagN=1;		TStates+=4;	} else if(OP_INC_P(IR)) {		(*OperandP(IR))++;		TStates+=6;	} else if(OP_DEC_P(IR)) {	        (*OperandP(IR))--;		TStates+=6;	} else if(OP_AND_S(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);		And(&AF.Bytes.H, *OperandS(IR));	} else if(OP_AND_B(IR)) {		And(&AF.Bytes.H, ReadMemory(PC.Word++));	} else if(OP_XOR_S(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);	        XOr(&AF.Bytes.H, *OperandS(IR));        } else if(OP_XOR_B(IR)) {                XOr(&AF.Bytes.H, ReadMemory(PC.Word++));	} else if(OP_OR_S(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);	        Or(&AF.Bytes.H, *OperandS(IR));        } else if(OP_OR_B(IR)) {                Or(&AF.Bytes.H, ReadMemory(PC.Word++));	} else if(OP_CP_S(IR)) {	        if(Indexing) Index=ReadMemory(PC.Word++);	        Compare(&AF.Bytes.H, *OperandS(IR));        } else if(OP_CP_B(IR)) {                Compare(&AF.Bytes.H, ReadMemory(PC.Word++));		TStates+=3;	} else if(OP_JP_W(IR)) {		JumpAbsolute(GetWordOperand());	} else if(OP_JP_F_W(IR)) {		Word=GetWordOperand();		if(*OperandF(IR)) JumpAbsolute(Word); else TStates+=10;		UsefulInstruction=TRUE;	} else if(OP_JP_PHL(IR)) {		PC.Word=HL.Word;		TStates+=4;	} else if(OP_JR_B(IR)) {		JumpRelative(ReadMemory(PC.Word++));	} else if(OP_JR_SF_B(IR)) {		Byte=ReadMemory(PC.Word++);		if(*OperandF(IR)) JumpRelative(Byte); else TStates+=7;		UsefulInstruction=TRUE;	} else if(OP_DJNZ_B(IR)) {		Byte=ReadMemory(PC.Word++);		BC.Bytes.H--;		if(BC.Bytes.H!=0) {			JumpRelative(Byte);					TStates+=1;		} else TStates+=8;	} else if(OP_CPL(IR)) {		AF.Bytes.H=~AF.Bytes.H;		FlagN=FlagH=1;		TStates+=4;	} else if(OP_DI(IR)) {		IFF1=FALSE;		TStates+=4;	} else if(OP_EI(IR)) {		EnableInterrupts=TRUE;		TStates+=4;	} else if(OP_CALL_W(IR)) {		Call(GetWordOperand());	} else if(OP_CALL_F_W(IR)) {		Word=GetWordOperand();		if(*OperandF(IR)) Call(Word); else TStates+=10;		UsefulInstruction=TRUE;	} else if(OP_RET(IR)) {		Pop(&(PC.Word));	} else if(OP_RET_F(IR)) {		if(*OperandF(IR)) {			Pop(&PC.Word);			TStates+=1;		} else TStates+=5;		UsefulInstruction=TRUE;        } else if(OP_EXDEHL(IR)) {                Swap(&DE.Word, &HL.Word);                TStates+=4;        } else if(OP_EXPSPHL(IR)) {                byte TempH, TempL;                TempL=ReadMemory((word)(SP.Word+0));                TempH=ReadMemory((word)(SP.Word+1));                WriteMemory((word)(SP.Word+0), PointerReg->Bytes.L);                WriteMemory((word)(SP.Word+1), PointerReg->Bytes.H);                PointerReg->Bytes.H=TempH;                PointerReg->Bytes.L=TempL;                if(Indexing) TStates+=23; else TStates+=4;        } else if(OP_EXAFAF1(IR)) {                Swap(&AF.Word, &AF1.Word);                TStates+=4;        } else if(OP_EXX(IR)) {                Swap(&BC.Word, &BC1.Word);                Swap(&DE.Word, &DE1.Word);                Swap(&HL.Word, &HL1.Word);                TStates+=4;        } else if(OP_PUSH_P(IR)) {                Push((OperandP(IR)==&SP.Word)?(AF.Word):(*OperandP(IR)));        } else if(OP_POP_P(IR)) {		if(OperandP(IR)==&SP.Word) Pop(&AF.Word); else Pop(OperandP(IR));	} else if(OP_RLA(IR)) {		logic Carry;		Carry=SignBit(AF.Bytes.H);		AF.Bytes.H=((AF.Bytes.H)<<1)+(FlagC?1:0);		FlagNC=!(FlagC=Carry);		FlagN=FlagH=0;		TStates+=4;        } else if(OP_RLCA(IR)) {                if(SignBit(AF.Bytes.H)) FlagNC=!(FlagC=TRUE); else FlagC=!(FlagNC=FALSE);                AF.Bytes.H=(AF.Bytes.H)<<1+(FlagC?1:0);		FlagN=FlagH=0;	} else if(OP_RRCA(IR)) {                if(AF.Bytes.H&1) FlagNC=!(FlagC=TRUE); else FlagC=!(FlagNC=FALSE);                AF.Bytes.H=(AF.Bytes.H)>>1+(FlagC?(1<<7):(0<<7));                FlagN=FlagH=0;		TStates+=4;        } else if(OP_RRA(IR)) {                logic Carry;                Carry=AF.Bytes.H&1;                AF.Bytes.H=((AF.Bytes.H)>>1)+(FlagC?(1<<7):(0<<7));                FlagNC=!(FlagC=Carry);                FlagN=FlagH=0;		TStates+=4;        } else if(OP_IN_B(IR)) {                AF.Bytes.H=ReadIO(ReadMemory(PC.Word++));                TStates+=11;	} else if(OP_OUT_B(IR)) {		WriteIO(ReadMemory(PC.Word++), AF.Bytes.H);		TStates+=11;	} else if(OP_RST00(IR)) {		Push(PC.Word);		PC.Word=0x0000;	} else if(OP_RST08(IR)) {		MetaCall(AF.Bytes.H);	        // Push(PC.Word);	        // PC.Word=0x0008;	} else if(OP_RST10(IR)) {	        Push(PC.Word);	        PC.Word=0x0010;	} else if(OP_RST18(IR)) {	        Push(PC.Word);	        PC.Word=0x0018;	} else if(OP_RST20(IR)) {	        Push(PC.Word);	        PC.Word=0x0020;	} else if(OP_RST28(IR)) {	        Push(PC.Word);	        PC.Word=0x0028;	} else if(OP_RST30(IR)) {	        Push(PC.Word);	        PC.Word=0x0030;	} else if(OP_RST38(IR)) {	        Push(PC.Word);	        PC.Word=0x0038;        } else if(OP_NOP(IR)) {                TStates+=4;		UsefulInstruction=TRUE;        } else if(OP_CB(IR)) {                IR=ReadMemory(PC.Word++);		PHLOverhead=7;                if(OP_CB_RLC(IR)) {			if(SignBit(*OperandS(IR))) FlagNC=!(FlagC=TRUE); else FlagNC=!(FlagC=FALSE);			*OperandS(IR)=(*OperandS(IR))<<1+(FlagC?1:0);			SetFlags(*OperandS(IR));			TStates+=8;		} else if(OP_CB_RL(IR)) {                        logic Carry;			if(SignBit(*OperandS(IR))) Carry=TRUE; else Carry=FALSE;                        *OperandS(IR)=(*OperandS(IR))<<1+(FlagC?1:0);			FlagNC=!(FlagC=Carry);                        SetFlags(*OperandS(IR));			TStates+=8;                } else if(OP_CB_RRC(IR)) {                        if((*OperandS(IR))&0x01) FlagNC=!(FlagC=TRUE); else FlagNC=!(FlagC=FALSE);                        *OperandS(IR)=(*OperandS(IR))>>1+(FlagC?0x80:0);                        SetFlags(*OperandS(IR));			TStates+=8;		} else if(OP_CB_SLA(IR)) {			if(SignBit(*OperandS(IR))) FlagNC=!(FlagC=TRUE); else FlagNC=!(FlagC=FALSE);			*OperandS(IR)=(*OperandS(IR))<<1;                        SetFlags(*OperandS(IR));			FlagN=0;			FlagH=0;			TStates+=8;                } else if(OP_CB_BIT_N_S(IR)) {			FlagZ=!(FlagNZ=(*OperandS(IR))&(1<<OPPARM_N(IR)));			FlagN=0;			FlagH=1;			TStates+=8;                } else {	                fprintf(stdout, "ERROR: Unimplemented CB opcode %02x at %04x\n", IR, PC.Word-1);			Exception=TRAP_ILLEGAL;	                UsefulInstruction=TRUE;                }	} else if(OP_ED(IR)) {		IR=ReadMemory(PC.Word++);		if(OP_ED_LD_P_PW(IR)) {                        int Addr;                        Addr=ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8);			*OperandP(IR)=ReadMemory(Addr++)|(ReadMemory(Addr)<<8);			TStates+=20;		} else if(OP_ED_LD_PW_SP(IR)) {	                int Addr;			Addr=ReadMemory(PC.Word++)|(ReadMemory(PC.Word++)<<8);			WriteMemory(Addr, SP.Bytes.L); Addr++;			WriteMemory(Addr, SP.Bytes.L);			TStates+=20;		} else if(OP_ED_IM0(IR)) {			#warning TODO: Switch to interrupt mode 0                } else if(OP_ED_IM1(IR)) {                        #warning TODO: Switch to interrupt mode 1                } else if(OP_ED_IM2(IR)) {                        #warning TODO: Switch to interrupt mode 2		} else if(OP_ED_IN_R_C(IR)) {			BC.Bytes.L=ReadIO(*OperandR(IR));			TStates+=12;		} else {			fprintf(stdout, "ERROR: Unimplemented ED opcode %02x at %04x\n", IR, PC.Word-1);			Exception=TRAP_ILLEGAL;	                UsefulInstruction=TRUE;		}	} else {		fprintf(stdout, "ERROR: Unimplemented simple opcode %02x at %04x\n", IR, PC.Word-1);		Exception=TRAP_ILLEGAL;		UsefulInstruction=TRUE;	}	StoreFlags();	if(IndirectMemoryWrite) {		MemoryAddress=PointerReg->Word+(word)(sbyte)Index;		WriteMemory(MemoryAddress, MemoryData);	} else if(!MemoryWrite && !UsefulInstruction && AF.Word==OldAF.Word && BC.Word==OldBC.Word && DE.Word==OldDE.Word && HL.Word==OldHL.Word && IX.Word==OldIX.Word && IY.Word==OldIY.Word && SP.Word==OldSP.Word && IFF1==OldIFF1 && IFF2==OldIFF2) {		//fprintf(stderr, "WARNING: instruction %02x at %04x had no effect\n", IR, PC.Word-1);		Exception=TRAP_NOEFFECT;	}	InstructionsExecuted++;	if(InterruptRequest && IFF1) ProcessIRQ();	return Exception;}word GetRegister(regSpec Reg) {	switch(Reg) {	case REG_PC: return PC.Word;	case REG_SP: return SP.Word;	case REG_AF: return AF.Word;	case REG_BC: return BC.Word;        case REG_DE: return DE.Word;        case REG_HL: return HL.Word;        case REG_IX: return IX.Word;        case REG_IY: return IY.Word;	}}inline byte GetMemoryByte(word Address) {	return Memory[Address];}inline word GetMemoryWord(word Address) {	return Memory[Address] | (Memory[Address+1]<<8);}inline unsigned long GetFrame() {	return InstructionsExecuted;}void RaiseIRQ() {	InterruptRequest=TRUE;}

⌨️ 快捷键说明

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