📄 cpu.c
字号:
break; case 0x0: // bit case 0x1: ea=Get(pc++); if(!indirect) { } else { CCLOGLBPUT("[%02x] -> ",ea); ea=Get(ea); indirect=false; // don't use indirect mode in case this is a bit branch } CCLOGLBPUT("%02x ",ea); break; } // read operant unsigned char op=0; if(flags & 1) { switch(((flags&8) ? flags:ins)>>4) { case 0x2: // no or special address mode case 0x8: case 0x9: break; case 0x3: // short case 0xB: case 0xC: // long case 0xD: // long indexed case 0x6: // short indexed case 0xE: case 0x7: // indexed case 0xF: case 0x0: // bit case 0x1: op=Get(pr,ea); CCLOGLBPUT("{%02x} ",op); break; case 0xA: // immediate op=Get(pr,ea); break; case 0x4: // inherent A op=a; break; case 0x5: // inherent X/Y op=*ex; break; } } // command decoding stats[ins]++; switch(ins) { case 0xA6: // LDA case 0xB6: case 0xC6: case 0xD6: case 0xE6: case 0xF6: a=op; tst(op); break; case 0xAE: // LDX case 0xBE: case 0xCE: case 0xDE: case 0xEE: case 0xFE: *ex=op; tst(op); break; case 0xB7: // STA case 0xC7: case 0xD7: case 0xE7: case 0xF7: op=a; tst(op); break; case 0xBF: // STX case 0xCF: case 0xDF: case 0xEF: case 0xFF: op=*ex; tst(op); break; case 0x97: // TAX *ex=a; break; case 0x9F: // TXA a=*ex; break; case 0x93: // TYX (ST7) if(ex==&x) *ex=y; else *ex=x; break; case 0x3D: // TST case 0x4D: case 0x5D: case 0x6D: case 0x7D: tst(op); break; case 0x3F: // CLR case 0x4F: case 0x5F: case 0x6F: case 0x7F: op=0; tst(0); break; case 0x3C: // INC case 0x4C: case 0x5C: case 0x6C: case 0x7C: op++; tst(op); break; case 0x3A: // DEC case 0x4A: case 0x5A: case 0x6A: case 0x7A: op--; tst(op); break; case 0x33: // COM case 0x43: case 0x53: case 0x63: case 0x73: op=~op; cc.c=1; tst(op); break; case 0x30: // NEG case 0x40: case 0x50: case 0x60: case 0x70: op=~op+1; if(!op) cc.c=0; tst(op); break; case 0x42: // MUL case 0x52: { unsigned short res=*ex * a; *ex=(res>>8); a=res&0xff; cc.c=0; cc.h=0; break; } case 0xA9: // ADC case 0xB9: case 0xC9: case 0xD9: case 0xE9: case 0xF9: a=add(op,cc.c); break; case 0xAB: // ADD case 0xBB: case 0xCB: case 0xDB: case 0xEB: case 0xFB: a=add(op,0); break; case 0xA2: // SBC case 0xB2: case 0xC2: case 0xD2: case 0xE2: case 0xF2: a=sub(a,op,cc.c); break; case 0xA0: // SUB case 0xB0: case 0xC0: case 0xD0: case 0xE0: case 0xF0: a=sub(a,op,0); break; case 0xA1: // CMP case 0xB1: case 0xC1: case 0xD1: case 0xE1: case 0xF1: sub(a,op,0); break; case 0xA3: // CPX case 0xB3: case 0xC3: case 0xD3: case 0xE3: case 0xF3: sub(*ex,op,0); break; case 0xA4: // AND case 0xB4: case 0xC4: case 0xD4: case 0xE4: case 0xF4: a &= op; tst(a); break; case 0xAA: // ORA case 0xBA: case 0xCA: case 0xDA: case 0xEA: case 0xFA: a |= op; tst(a); break; case 0xA8: // EOR case 0xB8: case 0xC8: case 0xD8: case 0xE8: case 0xF8: a ^= op; tst(a); break; case 0xA5: // BIT case 0xB5: case 0xC5: case 0xD5: case 0xE5: case 0xF5: tst(a & op); break; case 0x38: // ASL case 0x48: case 0x58: case 0x68: case 0x78: op=rollL(op,0); break; case 0x39: // ROL case 0x49: case 0x59: case 0x69: case 0x79: op=rollL(op,cc.c); break; case 0x37: // ASR case 0x47: case 0x57: case 0x67: case 0x77: op=rollR(op,bitset(op,7)); break; case 0x34: // LSR case 0x44: case 0x54: case 0x64: case 0x74: op=rollR(op,0); break; case 0x36: // ROR case 0x46: case 0x56: case 0x66: case 0x76: op=rollR(op,cc.c); break; case 0x3E: // SWAP (ST7) case 0x4E: case 0x5E: case 0x6E: case 0x7E: op=(op<<4)|(op>>4); tst(op); break; case 0x00 ... 0x0F: // BRSET BRCLR { int bit=(ins&0x0F)>>1; CCLOGLBPUT(",#%x,",bit); cc.c=bitset(op,bit); branch((ins&0x01) ? !cc.c:cc.c); break; } case 0x10 ... 0x1F: // BSET BCLR { int bit=(ins&0x0F)>>1; CCLOGLBPUT(",#%x",bit); if(ins&0x01) op &= ~(1<<bit); else op |= (1<<bit); break; } case 0x20: // BRA branch(true); break; case 0x21: // BRN branch(false); break; case 0x22: // BHI if(vbra) branch(!cc.z && ((cc.n && cc.v) || (!cc.n && !cc.v))); else branch(!cc.c && !cc.z); break; case 0x23: // BLS if(vbra) branch(cc.z || (cc.n && !cc.v) || (!cc.n && cc.v)); else branch( cc.c || cc.z); break; case 0x24: // BCC BHS if(vbra) branch((cc.n && cc.v) || (!cc.n && !cc.v)); else branch(!cc.c); break; case 0x25: // BCS BLO if(vbra) branch((cc.n && !cc.v) || (!cc.n && cc.v)); else branch( cc.c); break; case 0x26: // BNE if(vbra) branch(!cc.v); else branch(!cc.z); break; case 0x27: // BEQ if(vbra) branch(cc.v); else branch( cc.z); break; case 0x28: // BHCC branch(!cc.h); break; case 0x29: // BHCS branch( cc.h); break; case 0x2A: // BPL branch(!cc.n); break; case 0x2B: // BMI branch( cc.n); break; case 0x2C: // BMC branch(!cc.i); break; case 0x2D: // BMS branch( cc.i); break; case 0xBC: // JMP case 0xCC: case 0xDC: case 0xEC: case 0xFC: pc=ea; break; case 0xAD: // BSR pc++; pushpc(); pc--; branch(true); break; case 0xBD: // JSR case 0xCD: case 0xDD: case 0xED: case 0xFD: pushpc(); pc=ea; break; case 0x81: // RTS poppc(); break; case 0x83: // SWI pushpc(); push(x); push(a); pushc(); cc.i=1; pc=HILO(0x1ffc); break; case 0x80: // RTI popc(); a=pop(); x=pop(); poppc(); break; case 0x9C: // RSP sp=spHi; break; case 0x96: // TSX *ex=sp; break; case 0x94: // TXS (ST7) sp=*ex; break; case 0x9E: // TSA a=sp; break; case 0x95: // TAS (ST7) sp=a; break; case 0x84: // POPA (ST7) a=pop(); break; case 0x85: // POPX (ST7) *ex=pop(); break; case 0x86: // POPC (ST7) popc(); break; case 0x88: // PUSHA (ST7) push(a); break; case 0x89: // PUSHX (ST7) push(*ex); break; case 0x8A: // PUSHC (ST7) pushc(); break; case 0x98: // CLC cc.c=0; break; case 0x99: // SEC cc.c=1; break; case 0x9A: // CLI cc.i=0; break; case 0x9B: // SEI cc.i=1; break; case 0x9D: // NOP break; case 0x71: // LDD (ST19) case 0x72: case 0x75: dr=op; break; case 0x7B: // TAD (ST19) dr=a; break; case 0x8B: // TDA (ST19) a=dr; break; case 0x8C: // TCA (ST19) a=cr; break; case 0xAC: // PUSHD (ST19) push(dr); break; case 0xAF: // POPD (ST19) dr=pop(); break; case 0x87: // PRTS (ST19) cr=pop(); poppc(); break; case 0x8D: // PJSR (ST19) if(paged) { ea=HILO(pc); pc+=2; CCLOGLBPUT("[%s] -> ",PADDR(cr,ea)); } else { ea=pc; pc+=3; } pr=Get(ea++); ea=HILO(ea); CCLOGLBPUT("%s ",PADDR(pr,ea)); pushpc(); push(cr); cr=pr; pc=ea; break; case 0x90: // pre-bytes case 0x91: case 0x92: case 0x31: case 0x32: PRINTF(L_SYS_EMU,"pre-byte %02x in command decoding (count=%d)",ins,count); return 3; default: PRINTF(L_SYS_EMU,"unsupported instruction 0x%02x (count=%d)",ins,count); return 3; } // write operant if(flags & 2) { switch(((flags&8) ? flags:ins)>>4) { case 0x2: // no or special address mode case 0x8: case 0x9: break; case 0xA: // immediate case 0x3: // short case 0xB: case 0xC: // long case 0xD: // long indexed case 0x6: // short indexed case 0xE: case 0x7: // indexed case 0xF: case 0x0: // bit case 0x1: Set(ea,op); break; case 0x4: // inherent A a=op; break; case 0x5: // inherent X/Y *ex=op; break; } } PUTLB(disAsmLogClass,loglb); for(int i=numBp-1 ; i>=0 ; i--) { if(bp[i]==pc) { PRINTF(L_SYS_EMU,"6805: breakpoint at %04x (count=%d)",pc,count); return 0; } } if(count>=max_count) { PRINTF(L_SYS_EMU,"max. instruction counter exceeded (count=%d)",count); return 2; } }}void c6805::branch(bool branch){ if(doDisAsm) { unsigned char off=Get(pc); if(indirect) { LOGLBPUT("[%02x] -> ",off); off=Get(off); } unsigned short npc=pc+off+1; if(off&0x80) npc-=0x100; // gcc fixup. take care of sign LOGLBPUT("%s ",PADDR(cr,npc)); if(branch) LOGLBPUT("(taken) "); } pc++; if(branch) { unsigned char offset=Get(pc-1); if(indirect) offset=Get(offset); pc+=offset; if(offset&0x80) pc-=0x100; // gcc fixup. take care of sign }}void c6805::push(unsigned char c){ Set(sp--,c);}unsigned char c6805::pop(void){ return Get(++sp);}void c6805::pushpc(void){ push(pc & 0xff); push(pc >> 8);}void c6805::poppc(void){ pc=(pop()<<8) | pop();}void c6805::pushc(void){ unsigned char c=0xC0+(cc.v?32:0)+(cc.h?16:0)+(cc.i?8:0)+(cc.n?4:0)+(cc.z?2:0)+(cc.c?1:0); push(c);}void c6805::popc(void){ unsigned char c=pop(); cc.v=(c&32) ? 1:0; cc.h=(c&16) ? 1:0; cc.i=(c& 8) ? 1:0; cc.n=(c& 4) ? 1:0; cc.z=(c& 2) ? 1:0; cc.c=(c& 1) ? 1:0;}void c6805::tst(unsigned char c){ cc.z=!c; cc.n=bitset(c,7);}unsigned char c6805::add(unsigned char op, unsigned char c){ unsigned short res_half=(a&0x0f) + (op&0x0f) + c; unsigned short res=(unsigned short)a + (unsigned short)op + (unsigned short)c; cc.h=res_half > 0x0f; cc.c=res > 0xff; res&=0xff; tst(res); return res;}unsigned char c6805::sub(unsigned char op1, unsigned char op2, unsigned char c){ short res=(short)op1 - (short)op2 - (short)c; cc.c=res < 0; res&=0xff; tst(res); return res;}unsigned char c6805::rollR(unsigned char op, unsigned char c){ cc.c=bitset(op,0); op >>= 1; op |= c << 7; tst(op); return op;}unsigned char c6805::rollL(unsigned char op, unsigned char c){ cc.c=bitset(op,7); op <<= 1; op |= c; tst(op); return op;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -