📄 zz80.c
字号:
/* inline */ BYTE Srl(BYTE bArg){ int q = bArg&1; bArg>>=1; m_regF=ZSPTable[bArg]|q; return bArg;}/* inline */ BYTE Sla(BYTE bArg){ int q = bArg>>7; bArg<<=1; m_regF=ZSPTable[bArg]|q; return bArg;}/* inline */ BYTE Sra(BYTE bArg){ int q = bArg&1; bArg = (bArg>>1)|(bArg&0x80); m_regF = ZSPTable[bArg]|q; return bArg;}/* *************************************************************************** * Edwards Z80 Utilities * *************************************************************************** */UINT16 swap_variable;#define swap(b1,b2) swap_variable = b1; b1 = b2; b2 = swap_variable;/* inline void swap ( WORD &b1, WORD &b2 ) { * WORD b = b1; * b1 = b2; * b2 = b; * } *//* inline */ void Rlca() { m_regA = (m_regA << 1) | ((m_regA & 0x80) >> 7); m_regF = (m_regF & 0xEC) | (m_regA & C_FLAG);}/* inline */ void Rrca() { m_regF=(m_regF&0xEC)|(m_regA&0x01); m_regA=(m_regA>>1)|(m_regA<<7);}/* inline */ void Rla() { int i = m_regF&C_FLAG; m_regF = (m_regF&0xEC)|((m_regA&0x80)>>7); m_regA = (m_regA<<1)|i;}/* inline */ void Rra() { int i = m_regF&C_FLAG; m_regF=(m_regF&0xEC)|(m_regA&0x01); m_regA=(m_regA>>1)|(i<<7);}/* *************************************************************************** * Edwards Z80 Good-bits follow * *************************************************************************** */void InitTables (void) { int i; DWORD dw; // // // for (i=0; i<256; ++i) { BYTE zs = 0; int p=0; BYTE bArg; int j; // zs |= i ? 0 : Z_FLAG; if (i==0) zs|=Z_FLAG; // zs |= i & S_FLAG; if (i&0x80) zs|=S_FLAG; if (i&1) ++p; if (i&2) ++p; if (i&4) ++p; if (i&8) ++p; if (i&16) ++p; if (i&32) ++p; if (i&64) ++p; if (i&128) ++p; // PTable[i] = (p&1) ? 0:V_FLAG; ZSTable[i] = zs; ZSPTable[i]= zs | ((p&1) ? 0:V_FLAG); rgfInc[i] = ZSTable[i] | ((i == 0x80) ? V_FLAG : 0) | ((i & 0x0F) ? 0 : H_FLAG); // rgfDec[i] = N_FLAG | ((i == 0x80) ? V_FLAG : 0) | ((i & 0x0F) ? 0 : H_FLAG) | ZSTable[(BYTE)i - 1]; bArg = i; rgfDec[i] = N_FLAG|((bArg==0x80)?V_FLAG:0)|((bArg&0x0F)?0:H_FLAG); rgfDec[i]|=ZSTable[--bArg]; for ( j = 0; j < 8; j++) rgfBit[i][j] = H_FLAG | ((i & (1 << j))? ((j == 7) ? S_FLAG : 0) : Z_FLAG); } // // Calculate flag tables // for ( dw = 0; dw <= 256 * 256; dw++) { BYTE bLo = LOBYTE(LOWORD(dw)); BYTE bHi = HIBYTE(LOWORD(dw)); const BYTE regA = bLo; const BYTE bArg = bHi; int nAcc; BYTE regF; int c; // // ADD // nAcc = regA + bArg; regF = 0; regF |= ZSTable[nAcc&255]; regF |= ((nAcc&256)>>8); regF |= ((regA^nAcc^bArg)&H_FLAG); regF |= (((bArg^regA^0x80)&(bArg^nAcc)&0x80)>>5); rgfAdd[regA][bArg] = regF; // // SUB // nAcc = regA - bArg; regF = ZSTable[nAcc&255]|((nAcc&256)>>8)|N_FLAG|((regA^nAcc^bArg)&H_FLAG)|(((bArg^regA)&(regA^nAcc)&0x80)>>5); rgfSub[regA][bArg] = regF; // // // for ( c = 0; c <= 1; c++) { // // ADC // nAcc = regA + bArg + c; regF = 0; regF |= ZSTable[nAcc&255]; regF |= ((nAcc&256)>>8); regF |= ((regA^nAcc^bArg)&H_FLAG); regF |= (((bArg^regA^0x80)&(bArg^nAcc)&0x80)>>5); rgfAddc[regA][bArg][c] = regF; // // SBC // nAcc = regA - bArg - c; regF = ZSTable[nAcc&255]|((nAcc&256)>>8)|N_FLAG|((regA^nAcc^bArg)&H_FLAG)|(((bArg^regA)&(bArg^nAcc)&0x80)>>5); rgfSubc[regA][bArg][c] = regF; } }}/* *************************************************************************** * Opcodes * *************************************************************************** *//*--------------------------------------------------------------------------- Exec Executes the specified number of t-states. Returns the actual number of t-states executed. If a halt instruction is encountered, the execution loop exits. If the processor is currently in a halted state this function immediately returns 0.---------------------------------------------------------------------------*/unsigned long int mz80exec ( unsigned long int cCyclesArg ) { UINT32 origElapsedTicks=dwElapsedTicks; // // // // if (m_fHalt)// return 0; // // Save t-state count for return value calculation // cCycles = cCyclesArg; // // // #ifndef TRACE_Z80 while (cCycles > 0) #endif {#ifdef _DEBUG static int cins; if ((cins % 1000) == 0 && GetAsyncKeyState('X') < 0) _ASSERT(FALSE); _ASSERT(cins != _instrap); if (cins >= _rgcins[0] && cins <= _rgcins[0] + _rgcins[1] * _rgcins[2] && ((cins - _rgcins[0]) % _rgcins[2]) == 0) { if (cins == _rgcins[0]) { TRACE("instr PC AF BC DE HL IX IY SP cycl dasm \n"); TRACE("-------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ------------\n"); } TCHAR szBuf[128]; Z80_Dasm(&m_rgbMemory[GetPC()], szBuf, GetPC()); TRACE("%08X %04X %04X %04X %04X %04X %04X %04X %04X %04X %s\n", cins, GetPC(), m_regAF, m_regBC, m_regDE, m_regHL, m_regIX, m_regIY, GetSP(), cCycles, szBuf); } cins++;#endif const BYTE bOpcode = ImmedByte();#ifdef _DEBUG m_rgcOpcode[0][bOpcode]++;#endif m_regR++;#if 0 /* debug crap for RC */ { char szBuf [ 128 ]; Z80_Dasm(&m_rgbMemory[GetPC()], szBuf, GetPC()); fprintf ( stderr, "%04X %04X %04X %04X %04X %04X %04X %04X %04X %s\n", GetPC(), m_regAF, m_regBC, m_regDE, m_regHL, m_regIX, m_regIY, GetSP(), cCycles, szBuf ); } // fprintf ( stderr, "%d\n", bOpcode );#endif z80pc = GetPC(); /* for some of the platforms */ dwElapsedTicks = origElapsedTicks + (cCyclesArg - cCycles); switch (bOpcode) { case 0x00: // nop cCycles -= 4; break; case 0x01: // ld_bc_word cCycles -= 10; m_regBC = ImmedWord(); break; case 0x02: // ld_xbc_a cCycles -= 7; MemWriteByte(m_regBC, m_regA); break; case 0x03: // inc_bc cCycles -= 6; m_regBC++; break; case 0x04: // inc_b cCycles -= 4; m_regB = Inc(m_regB); break; case 0x05: // dec_b cCycles -= 4; m_regB = Dec(m_regB); break; case 0x06: // ld_b_byte cCycles -= 7; m_regB = ImmedByte(); break; case 0x07: // rlca cCycles -= 4; Rlca(); break; case 0x08: // ex_af_af cCycles -= 4; swap(m_regAF, m_regAF2); break; case 0x09: // add_hl_bc cCycles -= 11; m_regHL = Add_2(m_regHL, m_regBC); break; case 0x0A: // ld_a_xbc cCycles -= 7; m_regA = MemReadByte(m_regBC); break; case 0x0B: // dec_bc cCycles -= 6; m_regBC--; break; case 0x0C: // inc_c cCycles -= 4; m_regC = Inc(m_regC); break; case 0x0D: // dec_c cCycles -= 4; m_regC = Dec(m_regC); break; case 0x0E: // ld_c_byte cCycles -= 7; m_regC = ImmedByte(); break; case 0x0F: // rrca cCycles -= 4; Rrca(); break; case 0x10: // djnz cCycles -= 8; cCycles -= Jr0(--m_regB); break; case 0x11: // ld_de_word cCycles -= 10; m_regDE = ImmedWord(); break; case 0x12: // ld_xde_a cCycles -= 7; MemWriteByte(m_regDE, m_regA); break; case 0x13: // inc_de cCycles -= 6; m_regDE++; break; case 0x14: // inc_d cCycles -= 4; m_regD = Inc(m_regD); break; case 0x15: // dec_d cCycles -= 4; m_regD = Dec(m_regD); break; case 0x16: // ld_d_byte cCycles -= 7; m_regD = ImmedByte(); break; case 0x17: // rla cCycles -= 4; Rla(); break; case 0x18: // jr {#if 0 cCycles -= Jr0(TRUE);#else // speedup technique adopted from Nicola's code in MAME to speedup // Galaga (the sound CPU spins with "loop: jr loop" waiting for // an interrupt). This technique is generic enough that is shouldn't // adversely effect other applications. signed char offset = (signed char)ImmedByte(); cCycles -= 7; cCycles -= 5; AdjustPC(offset); if (offset == -2) {// TRACE(__FILE__ ":jr (infinite loop) at %04X\n", GetPC()); goto z80ExecBottom; /* return (cCyclesArg - cCycles); */ }#endif break; } case 0x19: // add_hl_de cCycles -= 11; m_regHL = Add_2(m_regHL, m_regDE); break; case 0x1A: // ld_a_xde cCycles -= 7; m_regA = MemReadByte(m_regDE); break; case 0x1B: // dec_de cCycles -= 6; m_regDE--; break; case 0x1C: // inc_e cCycles -= 4; m_regE = Inc(m_regE); break; case 0x1D: // dec_e cCycles -= 4; m_regE = Dec(m_regE); break; case 0x1E: // ld_e_byte cCycles -= 7; m_regE = ImmedByte(); break; case 0x1F: // rra cCycles -= 4; Rra(); break; case 0x20: // jr_nz cCycles -= 7; cCycles -= Jr1(m_regF & Z_FLAG); break; case 0x21: // ld_hl_word cCycles -= 10; m_regHL = ImmedWord(); break; case 0x22: // ld_xword_hl cCycles -= 16; MemWriteWord(ImmedWord(), m_regHL); break; case 0x23: // inc_hl cCycles -= 6; m_regHL++; break; case 0x24: // inc_h cCycles -= 4; m_regH = Inc(m_regH); break; case 0x25: // dec_h cCycles -= 4; m_regH = Dec(m_regH); break; case 0x26: // ld_h_byte cCycles -= 7; m_regH = ImmedByte(); break; case 0x27: // daa { int i = m_regA; cCycles -= 4; if (m_regF&C_FLAG) i|=256; if (m_regF&H_FLAG) i|=512; if (m_regF&N_FLAG) i|=1024; m_regAF = DAATable[i]; break; } case 0x28: // jr_z cCycles -= 7; cCycles -= Jr0(m_regF & Z_FLAG); break; case 0x29: // add_hl_hl cCycles -= 11; m_regHL = Add_2(m_regHL, m_regHL); break; case 0x2A: // ld_hl_xword cCycles -= 16; m_regHL = MemReadWord(ImmedWord()); break; case 0x2B: // dec_hl cCycles -= 6; m_regHL--; break; case 0x2C: // inc_l cCycles -= 4; m_regL = Inc(m_regL); break; case 0x2D: // dec_l cCycles -= 4; m_regL = Dec(m_regL); break; case 0x2E: // ld_l_byte cCycles -= 7; m_regL = ImmedByte(); break; case 0x2F: // cpl cCycles -= 4; m_regA ^= 0xFF; m_regF |= (H_FLAG | N_FLAG); break; case 0x30: // jr_nc cCycles -= 7; cCycles -= Jr1(m_regF & C_FLAG); break; case 0x31: // ld_sp_word cCycles -= 10; SetSP(ImmedWord()); break; case 0x32: // ld_xbyte_a cCycles -= 13; MemWriteByte(ImmedWord(), m_regA); break; case 0x33: // inc_sp cCycles -= 6; SetSP(GetSP() + 1); break; case 0x34: // inc_xhl cCycles -= 11; MemWriteByte(m_regHL, Inc(MemReadByte(m_regHL))); break; case 0x35: // dec_xhl cCycles -= 11; MemWriteByte(m_regHL, Dec(MemReadByte(m_regHL))); break; case 0x36: // ld_xhl_byte cCycles -= 10; MemWriteByte(m_regHL, ImmedByte()); break; case 0x37: // scf cCycles -= 4; m_regF = (m_regF & 0xEC) | C_FLAG; break; case 0x38: // jr_c cCycles -= 7; cCycles -= Jr0(m_regF & C_FLAG); break; case 0x39: // add_hl_sp cCycles -= 11; m_regHL = Add_2(m_regHL, GetSP()); break; case 0x3A: // ld_a_xbyte cCycles -= 13; m_regA = MemReadByte(ImmedWord()); break; case 0x3B: // dec_sp cCycles -= 6; SetSP(GetSP() - 1); break; case 0x3C: // inc_a cCycles -= 4; m_regA = Inc(m_regA); break; case 0x3D: // dec_a cCycles -= 4; m_regA = Dec(m_regA); break; case 0x3E: // ld_a_byte cCycles -= 7; m_regA = ImmedByte(); break; case 0x3F: // ccf cCycles -= 4; m_regF =((m_regF & 0xED)|((m_regF & 1)<<4))^1; break; case 0x40: // ld_b_b cCycles -= 4; m_regB = m_regB; break; case 0x41: // ld_b_c cCycles -= 4; m_regB = m_regC; break; case 0x42: // ld_b_d cCycles -= 4; m_regB = m_regD; break; case 0x43: // ld_b_e cCycles -= 4; m_regB = m_regE; break; case 0x44: // ld_b_h cCycles -= 4; m_regB = m_regH; break; case 0x45: // ld_b_l cCycles -= 4; m_regB = m_regL; break; case 0x46: // ld_b_xhl cCycles -= 7; m_regB = MemReadByte(m_regHL); break; case 0x47: // ld_b_a cCycles -= 4; m_regB = m_regA; break; case 0x48: // ld_c_b cCycles -= 4; m_regC = m_regB; break; case 0x49: // ld_c_c cCycles -= 4; m_regC = m_regC; break; case 0x4A: // ld_c_d cCycles -= 4; m_regC = m_regD; break; case 0x4B: // ld_c_e cCycles -= 4; m_regC = m_regE; break; case 0x4C: // ld_c_h cCycles -= 4; m_regC = m_regH; break; case 0x4D: // ld_c_l cCycles -= 4; m_regC = m_regL; break; case 0x4E: // ld_c_xhl cCycles -= 7; m_regC = MemReadByte(m_regHL); break; case 0x4F: // ld_c_a cCycles -= 4; m_regC = m_regA; break; case 0x50: // ld_d_b cCycles -= 4; m_regD = m_regB; break; case 0x51: // ld_d_c cCycles -= 4; m_regD = m_regC; break; case 0x52: // ld_d_d cCycles -= 4; m_regD = m_regD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -