📄 cpu.c
字号:
/* 0x60 */ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 5, 6, 6,/* 0x70 */ 5, 2, 3, 5, 5, 4, 5, 5, 5, 5, 5, 2, 5, 4, 5, 5,/* 0x80 */ 9, 6, 0, 10, 4, 4, 4, 6, 3, 3, 3, 2, 2, 7, 2, 2,/* 0x90 */ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* 0xa0 */ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 3, 6, 2, 4,/* 0xb0 */ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4,/* 0xc0 */ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,/* 0xd0 */ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 7, 5, 6,/* 0xe0 */ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,/* 0xf0 */ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4, };char * c6805::PADDR(unsigned char s, unsigned short ea){ snprintf(addrBuff,sizeof(addrBuff),((ea&0x8000) && s>0)?"%2$x:%1$04x":"%04x",ea,s); return addrBuff;}int c6805::Run(int max_count){// returns:// 0 - breakpoint// 1 - stack overflow// 2 - instruction counter exeeded// 3 - unsupported instruction bool disAsmHeader=false; disAsmLogClass=L_SYS_DISASM; if(LOG(L_SYS_DISASM)) doDisAsm=true; else { doDisAsm=false; if(LOG(L_SYS_DISASM80)) disAsmLogClass=L_SYS_DISASM80; } int count=0; while (1) { if(exptPending && !cc.i) { exptPending=false; for(int i=0; i<EXPT_MAX; ++i) if(expt[i]) { exptPending=true; // to force check for another interrupt in next Run pass expt[i]=false; pushpc(); push(x); push(a); pushc(); cc.i=1; pc=exptBase+4*i; break; } } Stepper(); if(sp<spLow) { PRINTF(L_SYS_EMU,"stack overflow (count=%d)",count); return 1; } if(spHi>spLow && sp>spHi) { PRINTF(L_SYS_EMU,"stack underflow (count=%d)",count); return 1; } if(pc>0x0400 && mapMap[pc+PAGEOFF(pc,cr)]==0) { PRINTF(L_SYS_EMU,"NX protection at %04x (count=%d)",pc,count); return 1; } count++; if(!LOG(L_SYS_DISASM) && LOG(L_SYS_DISASM80)) { bool flag=(pc>=0x80 && pc<0x200); if(doDisAsm && !flag) PRINTF(disAsmLogClass,"[...]"); doDisAsm=flag; } if(doDisAsm && !disAsmHeader) { PRINTF(disAsmLogClass,"cr:-pc- aa xx yy dr -sp- VHINZC -mem@pc- -mem@sp- -cycles-"); disAsmHeader=true; } CCLOGLBPUT("%02x:%04x %02x %02x %02x %02x %04x %c%c%c%c%c%c %02x%02x%02x%02x %02x%02x%02x%02x %08x ", cr,pc,a,x,y,dr,sp, cc.v?'V':'.',cc.h?'H':'.',cc.i?'I':'.',cc.n?'N':'.',cc.z?'Z':'.',cc.c?'C':'.', Get(pc),Get(pc+1),Get(pc+2),Get(pc+3),Get(sp+1),Get(sp+2),Get(sp+3),Get(sp+4), clockcycles); unsigned char *ex=&x; unsigned short idx=*ex; indirect=false; bool paged=false, vbra=false; unsigned char ins=Get(pc++); char xs='X', xi='X'; int cycles=0; // check pre-bytes switch(ins) { case 0x31: // use SP indexed or indirect paged mode (ST19) cycles+=2; ins=Get(pc++); switch(ins) { case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: vbra=true; break; case 0x75: case 0x8D: case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDE: case 0xDF: paged=true; indirect=true; break; case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEE: case 0xEF: idx=sp; xi='S'; break; } break; case 0x32: // use indirect SP indexed or indirect paged Y indexed mode (ST19) cycles+=2; ins=Get(pc++); switch(ins) { case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: vbra=true; indirect=true; break; case 0xC3: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDE: case 0xDF: paged=true; indirect=true; ex=&y; idx=*ex; xs='Y'; xi='Y'; break; case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEE: case 0xEF: indirect=true; idx=sp; xi='S'; break; } break; case 0x91: // use Y register with indirect addr mode (ST7) cycles++; indirect=true; // fall through case 0x90: // use Y register (ST7) cycles++; ex=&y; idx=*ex; xs='Y'; xi='Y'; ins=Get(pc++); break; case 0x92: // use indirect addr mode (ST7) cycles+=2; indirect=true; ins=Get(pc++); break; } cycles+=clock_cycles[ins]; int readCycles=clock_cycles[ins]>=2 ? 2:0; AddCycles(readCycles); if(doDisAsm) { char str[8]; if(!vbra) snprintf(str,sizeof(str),ops[ins],xs,xs^1); else snprintf(str,sizeof(str),"%s",vops[ins-0x22]); LOGLBPUT("%-5s ",str); } // address decoding unsigned short ea=0; unsigned char flags=opFlags[ins]; unsigned char pr=(flags&4) ? dr:cr; switch(((flags&8) ? flags:ins)>>4) { case 0x2: // no or special address mode case 0x8: case 0x9: break; case 0xA: // immediate CCLOGLBPUT("#%02x ",Get(pc)); ea=pc++; break; case 0x3: // short case 0xB: ea=Get(pc++); if(!indirect) { // short direct } else { // short indirect CCLOGLBPUT("[%02x] -> ",ea); ea=Get(ea); } CCLOGLBPUT("%02x ",ea); break; case 0xC: // long if(!indirect) { // long direct ea=HILO(pc); pc+=2; } else { // long indirect if(paged) { ea=HILO(pc); pc+=2; CCLOGLBPUT("[%s] -> ",PADDR(pr,ea)); unsigned char s=Get(pr,ea); ea=HILOS(pr,ea+1); pr=s; } else { ea=Get(pc++); CCLOGLBPUT("[%02x] -> ",ea); ea=HILO(ea); } } CCLOGLBPUT("%s ",PADDR(pr,ea)); break; case 0xD: // long indexed if(!indirect) { // long direct indexed ea=HILO(pc); pc+=2; CCLOGLBPUT("(%s",PADDR(cr,ea)); } else { // long indirect indexed if(paged) { ea=HILO(pc); pc+=2; CCLOGLBPUT("([%s]",PADDR(pr,ea)); unsigned char s=Get(pr,ea++); ea=HILOS(pr,ea); pr=s; } else { ea=Get(pc++); CCLOGLBPUT("([%02x]",ea); ea=HILO(ea); } CCLOGLBPUT(",%c) -> (%s",xi,PADDR(pr,ea)); } ea+=idx; CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea)); break; case 0x6: // short indexed case 0xE: ea=Get(pc++); if(!indirect) { // short direct indexed CCLOGLBPUT("(%02x",ea); } else { // short indirect indexed CCLOGLBPUT("([%02x]",ea); ea=Get(ea); CCLOGLBPUT(",%c) -> (%02x",xi,ea); } ea+=idx; CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea)); break; case 0x7: // indexed case 0xF: ea=idx; CCLOGLBPUT("(%c) -> %s ",xi,PADDR(pr,ea)); break; case 0x4: // inherent A CCLOGLBPUT("A "); break; case 0x5: // inherent X/Y CCLOGLBPUT("%c ",xs); 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); if(hasReadHandler) ReadHandler(pr,ea,op); 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; } } AddCycles(cycles-readCycles); // 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++; cc.v=(op==0x80); tst(op); break; case 0x3A: // DEC case 0x4A: case 0x5A: case 0x6A: case 0x7A: op--; cc.v=(op==0x7f); 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; cc.c=(op!=0); cc.v=(op==0x80); 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -