📄 cpu.c
字号:
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 + -