📄 cpu.c
字号:
}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(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); Stepper(); 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; PRINTF(L_SYS_EMU,"WARN: V-flag not yet calculated"); 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; PRINTF(L_SYS_EMU,"WARN: V-flag not yet calculated"); 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; } AddCycles(cycles+clock_cycles[ins]); 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; } } // 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -