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

📄 cpu.c

📁 A Zilog Z80 simulator, debugger and profiler tailored for ZX Spectrum development (but generic enoug
💻 C
📖 第 1 页 / 共 3 页
字号:
        if(OPARG_F_NC(Opcode)) return &FlagNC;        if(OPARG_F_C(Opcode)) return &FlagC;        if(OPARG_F_PO(Opcode)) return &FlagPO;        if(OPARG_F_PE(Opcode)) return &FlagPE;        if(OPARG_F_P(Opcode)) return &FlagP;        if(OPARG_F_M(Opcode)) return &FlagM;	return NULL;}// As per OperandF(), but works with those opcode that only accept one// of four flags instead of eight in bits 3 and 4logic* OperandSF(byte Opcode) {        if(OPARG_SF_NZ(Opcode)) return &FlagNZ;        if(OPARG_SF_Z(Opcode)) return &FlagZ;        if(OPARG_SF_NC(Opcode)) return &FlagNC;        if(OPARG_SF_C(Opcode)) return &FlagC;	return NULL;}// Store a string in Name containing the human-readable name of the flag// which is a Flag* variable at address *Flag.void NameFlag(logic* Flag, char* Name) {	if(Flag==&FlagNZ) strcpy(Name, "nz"); else        if(Flag==&FlagZ) strcpy(Name, "z"); else        if(Flag==&FlagNC) strcpy(Name, "nc"); else        if(Flag==&FlagC) strcpy(Name, "c"); else        if(Flag==&FlagPO) strcpy(Name, "po"); else        if(Flag==&FlagPE) strcpy(Name, "pe"); else        if(Flag==&FlagP) strcpy(Name, "p"); else        if(Flag==&FlagM) strcpy(Name, "m"); else strcpy(Name, "?f");}// Store a string in Name containing the human-readable name of the (byte)// register at address *Register.void NameRegister(byte* Register, char* Name) {	if(Register==&AF.Bytes.H) strcpy(Name, "a"); else        if(Register==&AF.Bytes.L) strcpy(Name, "f"); else        if(Register==&BC.Bytes.H) strcpy(Name, "b"); else        if(Register==&BC.Bytes.L) strcpy(Name, "c"); else        if(Register==&DE.Bytes.H) strcpy(Name, "d"); else        if(Register==&DE.Bytes.L) strcpy(Name, "e"); else        if(Register==&HL.Bytes.H) strcpy(Name, "h"); else        if(Register==&HL.Bytes.L) strcpy(Name, "l"); else	if(Register==&MemoryData) {		if(PointerReg==&HL) strcpy(Name, "(hl)"); else		if(PointerReg==&IX) strcpy(Name, "(ix)"); else		if(PointerReg==&IY) strcpy(Name, "(iy)");		else strcpy(Name, "?i");	} else strcpy(Name, "?r");}// Store a string in Name containing the human-readable name of the// register pair at address *Register.void NameRegisterPair(word* Register, char* Name) {	if(Register==&AF.Word) strcpy(Name, "af"); else        if(Register==&BC.Word) strcpy(Name, "bc"); else        if(Register==&DE.Word) strcpy(Name, "de"); else        if(Register==&HL.Word) strcpy(Name, "hl"); else        if(Register==&SP.Word) strcpy(Name, "sp"); else        if(Register==&IX.Word) strcpy(Name, "ix"); else        if(Register==&IY.Word) strcpy(Name, "iy"); else strcpy(Name, "?p");}// Return the contents of cell number Address in main memory.inline byte ReadMemory(word Address) {	MemoryAddress=Address;	if(Protections[Address]&PROTECT_READ) Exception=TRAP_MEMORY;	MemoryData=Memory[Address];	return MemoryData;}// Write the contents of Value to cell number Address in main memory,// if this is allowed.void WriteMemory(word Address, byte Value) {        MemoryAddress=Address;	MemoryData=Value;	MemoryWrite=TRUE;	if(Protections[Address]&PROTECT_WRITE) {                Exception=TRAP_MEMORY;	} else {                Memory[Address]=Value;	}}inline byte ReadIO(byte Port) {	return 0;}void WriteIO(byte Port, byte Value) {	fprintf(stdout, "WARNING: Writing %02x into port %02x\n", Value, Port);}// Initialize the Z80 simulation.void Init() {	int i;	AF.Word=BC.Word=DE.Word=HL.Word=IX.Word=IY.Word=SP.Word=PC.Word=AF1.Word=BC1.Word=DE1.Word=HL1.Word=0x0000;	FlagNZ=!(FlagZ=0);	FlagNC=!(FlagC=0);	FlagPO=!(FlagPE=0);	FlagP=!(FlagM=0);	Flag3=0;	Flag5=0;	FlagN=0;	FlagH=0;	TStates=0;	InstructionsExecuted=0;	for(i=0; i<0x1000; i++) {		Memory[i]=0x00; // rand();	}	//ProtectRange(0x0000, 0x3fff, PROTECT_WRITE);	ProtectRange(0x0000, 0xffff, 0);	fprintf(stdout, "Z80 initialized\n");}void LoadROM(FILE* Handle) {	fread(Memory, 1, 0x10000, Handle);}void MetaCall(byte Number) {	switch(Number) {	case METACALL_ENTER:		// to be implemented		break;	case METACALL_EXIT:		// to be implemented		break;	case METACALL_PUTCHARACTER:		fprintf(stderr, "%c", HL.Bytes.L);		fflush(stderr);		break;	case METACALL_PUTWORD:		fprintf(stderr, "%04x", HL.Word);		fflush(stderr);		break;	case METACALL_WRITEPROTECT:		ProtectRange(HL.Word, DE.Word, PROTECT_WRITE);		break;	case METACALL_READPROTECT:		ProtectRange(HL.Word, DE.Word, PROTECT_READ);		break;	case METACALL_RWPROTECT:		ProtectRange(HL.Word, DE.Word, PROTECT_WRITE|PROTECT_READ);		break;	case METACALL_UNPROTECT:		ProtectRange(HL.Word, DE.Word, 0);		break;	default:		fprintf(stdout, "WARNING: Unimplemented metacall %02x\n", Number);		Exception=TRAP_METACALL;	}	UsefulInstruction=TRUE;}void SnapshotState(FILE* Handle) {	char Mnemonic[MAX_NAME];	word InstructionAddress;	InstructionAddress=PC.Word;	fprintf(Handle, "Frame %ld Begin\n", InstructionsExecuted);	fprintf(Handle, "\tPC <0x%04x> SP <0x%04x>\n", PC.Word, SP.Word);	fprintf(Handle, "\tA <0x%02x>\n", AF.Bytes.H);	fprintf(Handle, "\tfS <%d> fZ <%d> f5 <%d> fH <%d> f3 <%d> fP <%d> fN <%d> fC <%d>\n", ((AF.Bytes.L>>7)&1), ((AF.Bytes.L>>6)&1), ((AF.Bytes.L>>5)&1), ((AF.Bytes.L>>4)&1), ((AF.Bytes.L>>3)&1), ((AF.Bytes.L>>2)&1), ((AF.Bytes.L>>1)&1), ((AF.Bytes.L>>7)&0)); 	fprintf(Handle, "\tHL <0x%04x>\n", HL.Word);	fprintf(Handle, "\tIX <0x%04x> IY <0x%04x>\n", IX.Word, IY.Word),	fprintf(Handle, "\tBC <0x%04x> DE <0x%04x>\n", BC.Word, DE.Word);	fprintf(Handle, "\tMAR <0x%04x> MDR <0x%02x>\n", MemoryAddress, MemoryData);        if(MemoryWrite) fprintf(Handle, "\tStore <TRUE>\n"); else fprintf(Handle, "\tStore <FALSE>\n");	fprintf(Handle, "\tStack <0x%02x%02x>\n", Memory[(word)(SP.Word+1)], Memory[(word)(SP.Word+0)]);        Disassemble(&InstructionAddress, Mnemonic);	fprintf(Handle, "\tMnemonic <%s>\n", Mnemonic);	fprintf(Handle, "End\n");}void PrintRegisters(FILE *Handle) {        fprintf(Handle, "SP:%04x AF:%04x BC:%04x DE:%04x HL:%04x IX:%04x IY:%04x", SP.Word, AF.Word, BC.Word, DE.Word, HL.Word, IX.Word, IY.Word);}inline word FetchAddress(word* Address) {	return Memory[(*Address)++] | (Memory[(*Address)++]<<8);}// Disassemble the Z80 instruction starting at Address.void Disassemble(word* Address, char* Mnemonic) {	char NameR[MAX_NAME], NameS[MAX_NAME], NameP[MAX_NAME], NameI[MAX_NAME], NameF[MAX_NAME], Symbol[MAX_NAME];	byte Opcode;	Opcode=Memory[(*Address)++];        if(OP_IXPREFIX(Opcode)) {                Opcode=ReadMemory((*Address)++);                PointerReg=&IX;                Indexing=TRUE;        } else if(OP_IYPREFIX(Opcode)) {                Opcode=ReadMemory((*Address)++);                PointerReg=&IY;                Indexing=TRUE;        } else {                PointerReg=&HL;                Indexing=FALSE;        }        if(OP_HLT(Opcode)) {		sprintf(Mnemonic, "halt");        } else if(OP_LD_R_S(Opcode)) {                NameRegister(OperandR(Opcode), NameR);		NameRegister(OperandS(Opcode), NameS);                if(Indexing) {			if(OPARG_R_PHL(Opcode)) sprintf(Mnemonic, "ld #%02x %s, %s", Memory[(*Address)++], NameR, NameS);			else if(OPARG_S_PHL(Opcode)) sprintf(Mnemonic, "ld %s, #%02x %s", NameR, Memory[(*Address)++], NameS);		} else sprintf(Mnemonic, "ld %s, %s", NameR, NameS);        } else if(OP_LD_R_B(Opcode)) {                NameRegister(OperandR(Opcode), NameR);		if(Indexing) sprintf(Mnemonic, "ld #%02x %s, #%02x", Memory[(*Address)++], NameR, Memory[(*Address)++]);		else sprintf(Mnemonic, "ld %s, #%02x", NameR, Memory[(*Address)++]);	} else if(OP_LD_P_W(Opcode)) {		NameRegisterPair(OperandP(Opcode), NameP);		sprintf(Mnemonic, "ld %s, #%02x%02x", NameP, Memory[(*Address)++], Memory[(*Address)++]);	} else if(OP_LD_SP_HL(Opcode)) {		NameRegisterPair(&PointerReg->Word, NameI);		sprintf(Mnemonic, "ld sp, %s", NameI);	} else if(OP_LD_A_PBC(Opcode)) {		sprintf(Mnemonic, "ld a, (bc)");        } else if(OP_LD_A_PDE(Opcode)) {                sprintf(Mnemonic, "ld a, (de)");        } else if(OP_LD_A_PW(Opcode)) {                sprintf(Mnemonic, "ld a, (%02x%02x)", Memory[(*Address)++], Memory[(*Address)++]);        } else if(OP_LD_PW_A(Opcode)) {                sprintf(Mnemonic, "ld (%02x%02x), a", Memory[(*Address)++], Memory[(*Address)++]);	} else if(OP_LD_HL_PW(Opcode)) {		sprintf(Mnemonic, "ld hl, (%02x%02x)", Memory[(*Address)++], Memory[(*Address)++]);	} else if(OP_LD_PBC_A(Opcode)) {		sprintf(Mnemonic, "ld (bc), a");	} else if(OP_LD_PDE_A(Opcode)) {		sprintf(Mnemonic, "ld (de), a");        } else if(OP_ADD_S(Opcode)) {		NameRegister(OperandS(Opcode), NameS);                if(OPMOD_CARRYIN(Opcode)) sprintf(Mnemonic, "adc a, %s", NameS);		else sprintf(Mnemonic, "add a, %s", NameS);        } else if(OP_ADD_B(Opcode)) {                if(OPMOD_CARRYIN(Opcode)) sprintf(Mnemonic, "adc a, #%02x", Memory[(*Address)++]);		else sprintf(Mnemonic, "add a, #%02x", Memory[(*Address)++]);        } else if(OP_SUB_S(Opcode)) {                NameRegister(OperandS(Opcode), NameS);		if(OPMOD_CARRYIN(Opcode)) sprintf(Mnemonic, "sbc a, %s", NameS);		else sprintf(Mnemonic, "sub a, %s", NameS);        } else if(OP_SUB_B(Opcode)) {                if(OPMOD_CARRYIN(Opcode)) sprintf(Mnemonic, "sbc a, #%02x", Memory[(*Address)++]);		else sprintf(Mnemonic, "sub a, #%02x", Memory[(*Address)++]);        } else if(OP_ADD_HL_P(Opcode)) {		NameRegisterPair(&PointerReg->Word, NameI);                NameRegisterPair(OperandP(Opcode), NameP);		sprintf(Mnemonic, "add %s, %s", NameI, NameP);        } else if(OP_INC_R(Opcode)) {                NameRegister(OperandR(Opcode), NameR);		sprintf(Mnemonic, "inc %s", NameR);        } else if(OP_DEC_R(Opcode)) {                NameRegister(OperandR(Opcode), NameR);		sprintf(Mnemonic, "dec %s", NameR);        } else if(OP_INC_P(Opcode)) {		NameRegisterPair(OperandP(Opcode), NameP);                sprintf(Mnemonic, "inc %s", NameP);        } else if(OP_DEC_P(Opcode)) {                NameRegisterPair(OperandP(Opcode), NameP);                sprintf(Mnemonic, "dec %s", NameP);        } else if(OP_AND_S(Opcode)) {                NameRegister(OperandS(Opcode), NameS);		sprintf(Mnemonic, "and a, %s", NameS);        } else if(OP_AND_B(Opcode)) {                sprintf(Mnemonic, "and a, #%02x", Memory[(*Address)++]);        } else if(OP_XOR_S(Opcode)) {                NameRegister(OperandS(Opcode), NameS);		sprintf(Mnemonic, "xor a, %s", NameS);        } else if(OP_XOR_B(Opcode)) {                sprintf(Mnemonic, "xor a, #%02x", Memory[(*Address)++]);        } else if(OP_OR_S(Opcode)) {                NameRegister(OperandS(Opcode), NameS);		sprintf(Mnemonic, "or a, %s", NameS);        } else if(OP_OR_B(Opcode)) {                sprintf(Mnemonic, "or a, #%02x", Memory[(*Address)++]);        } else if(OP_CP_S(Opcode)) {                NameRegister(OperandS(Opcode), NameS);		sprintf(Mnemonic, "cp a, %s", NameS);        } else if(OP_CP_B(Opcode)) {                sprintf(Mnemonic, "cp a, #%02x", Memory[(*Address)++]);        } else if(OP_JP_W(Opcode)) {		LookupSymbol(FetchAddress(Address), Symbol);                sprintf(Mnemonic, "jp %s", Symbol);        } else if(OP_JP_F_W(Opcode)) {		NameFlag(OperandF(Opcode), NameF);                LookupSymbol(FetchAddress(Address), Symbol);                sprintf(Mnemonic, "jp %s, %s", NameF, Symbol);        } else if(OP_JP_PHL(Opcode)) {                sprintf(Mnemonic, "jp (HL)");        } else if(OP_JR_B(Opcode)) {                sprintf(Mnemonic, "jr %02x", Memory[(*Address)++]);        } else if(OP_JR_SF_B(Opcode)) {		NameFlag(OperandF(Opcode), NameF);                sprintf(Mnemonic, "jr %s, %02x", NameF, Memory[(*Address)++]);	} else if(OP_DJNZ_B(Opcode)) {		sprintf(Mnemonic, "djnz %02x", Memory[(*Address)++]);	} else if(OP_CPL(Opcode)) {		sprintf(Mnemonic, "cpl");        } else if(OP_DI(Opcode)) {                sprintf(Mnemonic, "di");        } else if(OP_EI(Opcode)) {                sprintf(Mnemonic, "ei");        } else if(OP_CALL_W(Opcode)) {                LookupSymbol(FetchAddress(Address), Symbol);                sprintf(Mnemonic, "call %s", Symbol);        } else if(OP_CALL_F_W(Opcode)) {                NameFlag(OperandF(Opcode), NameF);                LookupSymbol(FetchAddress(Address), Symbol);                sprintf(Mnemonic, "call %s, %s", NameF, Symbol);        } else if(OP_RET(Opcode)) {                sprintf(Mnemonic, "ret");        } else if(OP_RET_F(Opcode)) {                NameFlag(OperandF(Opcode), NameF);                sprintf(Mnemonic, "ret %s", NameF);        } else if(OP_EXDEHL(Opcode)) {                sprintf(Mnemonic, "ex de, HL");        } else if(OP_EXPSPHL(Opcode)) {                sprintf(Mnemonic, "ex (sp), HL");        } else if(OP_EXAFAF1(Opcode)) {                sprintf(Mnemonic, "ex af, af'");        } else if(OP_EXX(Opcode)) {                sprintf(Mnemonic, "exx");        } else if(OP_PUSH_P(Opcode)) {		if(OperandP(Opcode)==&SP.Word) strcpy(NameP, "AF"); else NameRegisterPair(OperandP(Opcode), NameP);                sprintf(Mnemonic, "push %s", NameP);        } else if(OP_POP_P(Opcode)) {                if(OperandP(Opcode)==&SP.Word) strcpy(NameP, "AF"); else NameRegisterPair(OperandP(Opcode), NameP);                sprintf(Mnemonic, "pop %s", NameP);	} else if(OP_RLA(Opcode)) {		sprintf(Mnemonic, "rla");        } else if(OP_RLCA(Opcode)) {                sprintf(Mnemonic, "rlca");        } else if(OP_RRCA(Opcode)) {                sprintf(Mnemonic, "rrca");        } else if(OP_RRA(Opcode)) {                sprintf(Mnemonic, "rra");        } else if(OP_IN_B(Opcode)) {                sprintf(Mnemonic, "in a, %02x", Memory[(*Address)++]);        } else if(OP_OUT_B(Opcode)) {                sprintf(Mnemonic, "out %02x, a", Memory[(*Address)++]);        } else if(OP_RST00(Opcode)) {                sprintf(Mnemonic, "rst 0x00");        } else if(OP_RST08(Opcode)) {                sprintf(Mnemonic, "rst 0x08 (META)");        } else if(OP_RST10(Opcode)) {                sprintf(Mnemonic, "rst 0x10");        } else if(OP_RST18(Opcode)) {                sprintf(Mnemonic, "rst 0x18");        } else if(OP_RST20(Opcode)) {                sprintf(Mnemonic, "rst 0x20");        } else if(OP_RST28(Opcode)) {                sprintf(Mnemonic, "rst 0x28");        } else if(OP_RST30(Opcode)) {                sprintf(Mnemonic, "rst 0x30");        } else if(OP_RST38(Opcode)) {                sprintf(Mnemonic, "rst 0x38");        } else if(OP_NOP(Opcode)) {                sprintf(Mnemonic, "nop");	} else if(OP_CB(Opcode)) {		Opcode=Memory[(*Address)++];		if(OP_CB_RLC(Opcode)) {	                NameRegister(OperandS(Opcode), NameS);			sprintf(Mnemonic, "rlc %s", NameS);		} else if(OP_CB_RL(Opcode)) {                        NameRegister(OperandS(Opcode), NameS);                        sprintf(Mnemonic, "rl %s", NameS);                } else if(OP_CB_RRC(Opcode)) {                        NameRegister(OperandS(Opcode), NameS);                        sprintf(Mnemonic, "rrc %s", NameS);                } else if(OP_CB_SLA(Opcode)) {                        NameRegister(OperandS(Opcode), NameS);                        sprintf(Mnemonic, "sla %s", NameS);		} else if(OP_CB_BIT_N_S(Opcode)) {			NameRegister(OperandS(Opcode), NameS);			sprintf(Mnemonic, "bit %d, %s", OPPARM_N(Opcode), NameS);		} else {			sprintf(Mnemonic, "???");		}	} else if(OP_ED(Opcode)) {		Opcode=Memory[(*Address)++];		if(OP_ED_LD_P_PW(Opcode)) {			NameRegisterPair(OperandP(Opcode), NameP);			LookupSymbol(FetchAddress(Address), Symbol);			sprintf(Mnemonic, "ld %s, (%s)", NameP, Symbol);		} else if(OP_ED_LD_PW_SP(Opcode)) {			LookupSymbol(FetchAddress(Address), Symbol);

⌨️ 快捷键说明

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