--------------------------------------------------------------- ------CODE PIECE 1 (PART OF bisqbot.cc FOR NOW)---------------- --------------------------------------------------------------- static void Check_RAMdiffs(unsigned S) { static unsigned prev_S; static std::map RAMstates; std::string cur_ramstate((char*)RAM, (char*)RAM+0x800); /* Ignore stack differences */ for(unsigned a=0x180; a<=0x1FF; ++a) cur_ramstate[a] = 0; /* Ignore sprite table */ for(unsigned a=0x200; a<=0x2FF; ++a) cur_ramstate[a] = 0; /* Ignore music player differences */ for(unsigned a=0x500; a<=0x57D; ++a) cur_ramstate[a] = 0; for(unsigned a=0xE0; a<=0xF5; ++a) cur_ramstate[a] = 0; std::string& prev_ramstate = RAMstates[S]; if(cur_ramstate != prev_ramstate) { if(S > prev_S) /* returning from function */ { unsigned wid = 0; wid += printf("RAM diffs (to previous time when S=%02X): ", S); for(unsigned a=0; a<0x800 && a < prev_ramstate.size() && a < cur_ramstate.size(); ++a) { if(cur_ramstate[a] != prev_ramstate[a]) { if(wid > 76) { printf("\n "); wid = 2; } wid += printf("%03X:%02X ", a, (unsigned char)cur_ramstate[a]); } } printf("\n"); } prev_ramstate = cur_ramstate; } prev_S = S; } static const struct {const char*pat;unsigned bytes;bool rel;} addrmodes[12] = { {"%.3s" ,0,0}, {"%.3s #%s" ,1,0}, {"%.3s %s" ,1,1}, {"%.3s %s" ,1,0}, {"%.3s %s,x" ,1,0}, {"%.3s %s,y" ,1,0}, {"%.3s (%s,x)" ,1,0}, {"%.3s (%s),y" ,1,0}, {"%.3s %s" ,2,0}, {"%.3s %s,x" ,2,0}, {"%.3s %s,y" ,2,0}, {"%.3s (%s)" ,2,0}, }; static const char asminfo[] = // addressing modes "AGZZZDDZABAZZIIZ" "CHZZZEEZAKZZZJJZ" "IGZZDDDZABAZIIIZ" "CHZZZEEZAKZZZJJZ" "AGZZZDDZABAZIIIZ" "CHZZZEEZAKZZZJJZ" "AGZZZDDZABAZLIIZ" "CHZZZEEZAKZZZJJZ" "ZGZZDDDZAZAZIIIZ" "CHZZEEFZAKAZZJZZ" "BGBZDDDZABAZIIIZ" "CHZZEEFZAKAZJJKZ" "BGZZDDDZABAZIIIZ" "CHZZZEEZAKZZZJJZ" "BGZZDDDZABAZIIIZ" "CHZZZEEZAKZZZJJZ" // opcodes "brkora" "??????" "???ora" "asl???" "phpora" "asl???" "???ora" "asl???" "bplora" "??????" "???ora" "asl???" "clcora" "??????" "???ora" "asl???" "jsrand" "??????" "bitand" "rol???" "plpand" "rol???" "bitand" "rol???" "bmiand" "??????" "???and" "rol???" "secand" "??????" "???and" "rol???" "rtieor" "??????" "???eor" "lsr???" "phaeor" "lsr???" "jmpeor" "lsr???" "bvceor" "??????" "???eor" "lsr???" "clieor" "??????" "???eor" "lsr???" "rtsadc" "??????" "???adc" "ror???" "plaadc" "ror???" "jmpadc" "ror???" "bvsadc" "??????" "???adc" "ror???" "seiadc" "??????" "???adc" "ror???" "???sta" "??????" "stysta" "stx???" "dey???" "txa???" "stysta" "stx???" "bccsta" "??????" "stysta" "stx???" "tyasta" "txs???" "???sta" "??????" "ldylda" "ldx???" "ldylda" "ldx???" "taylda" "tax???" "ldylda" "ldx???" "bcslda" "??????" "ldylda" "ldx???" "clvlda" "tsx???" "ldylda" "ldx???" "cpycmp" "??????" "cpycmp" "dec???" "inycmp" "dex???" "cpycmp" "dec???" "bnecmp" "??????" "???cmp" "dec???" "cldcmp" "??????" "???cmp" "dec???" "cpxsbc" "??????" "cpxsbc" "inc???" "inxsbc" "nop???" "cpxsbc" "inc???" "beqsbc" "??????" "???sbc" "inc???" "sedsbc" "??????" "???sbc" "inc???"; static void DisAsm(unsigned PC,unsigned A,unsigned X,unsigned Y,unsigned S,unsigned P) { /* NES diassembler -- (C) 2006 Joel Yliluoma (http://iki.fi/bisqwit/) */ //Check_RAMdiffs(S); const unsigned char opcode = ARead[PC](PC); const unsigned addrmode = asminfo[opcode]-'A'; const unsigned bytes = 1+addrmodes[addrmode].bytes; bool indexed = addrmode==9||addrmode==10; printf("%04X: ", PC); for(unsigned b=0; b= 3) { switch(opparam) { case 0x400: o = oo+"Type"; break; case 0x420: o = oo+"Flags"; break; case 0x440: o = oo+"PosScreen"; break; case 0x460: o = oo+"PosX"; break; case 0x480: o = oo+"PosXFraction"; break; case 0x4A0: o = oo+"PosY"; break; case 0x4C0: o = oo+"PosYFraction"; break; case 0x600: o = oo+"SpeedX"; break; case 0x620: o = oo+"SpeedXFraction"; break; case 0x640: o = oo+"SpeedY"; break; case 0x660: o = oo+"SpeedYFraction"; break; case 0x6C0: o = oo+"LifeMeter"; break; case 0x200: o = "SpriteTable"; break; case 0x1D: o = "NMI_GfxUpdateDone"; break; case 0x1C: o = "FrameCounter"; break; case 0x14: o = "CurrentBeginScreen"; break; case 0x15: o = "CurrentEndScreen"; break; case 0x38: o = "CurrentOrderNum"; break; case 0x4A: o = "RandomSeed"; break; case 0x4B: o = "BlinkStatus"; break; case 0xC000: o = "SwitchBank"; break; case 0xC07F: o = "WaitNextFrame"; break; case 0xCC6C: o = "ClearSpriteTable"; break; case 0xCFA8: o = "RenderMeter"; break; case 0xCF5D: o = "RenderMeters"; break; case 0xCEF9: o = "RenderSomething"; break; case 0xCC77: o = "RenderEverything"; break; case 0xD0D7: o = "ReadJoypads"; break; case 0xEEEF: o = "MoveObject"; break; } if(addrmode == 4 || addrmode == 9) opparam += X; if(addrmode == 5 || addrmode == 10) opparam += Y; } sprintf(OpBuf, addrmodes[addrmode].pat, &asminfo[256+opcode*3], o.c_str()); o = OpBuf; for(unsigned tmp = 0xFF; tmp > S; --tmp) o = " " + o; char OpInfo[512] = ""; if(addrmode >= 3 && addrmode != 6 && addrmode != 7 && addrmode != 11) { sprintf(OpInfo, " [$%04X]", opparam); } printf("%-30s %10s A=%02X X=%02X Y=%02X S=%02X P=%02X\n", o.c_str(), OpInfo, A,X,Y, S, P); } --------------------------------------------------------------- -------------CODE PIECE 2 (PART OF bisqbot.cc)----------------- --------------------------------------------------------------- extern "C" { void FCEUI_GetIVectors(unsigned short *reset, unsigned short *irq, unsigned short *nmi); unsigned SavedHScroll,SavedVScroll; extern unsigned char (__attribute__((regparm(1))) *ARead[0x10000])(unsigned); } void BisqBotMonitorCPU (unsigned short PC, unsigned char A, unsigned char X, unsigned char Y, unsigned char S, unsigned char P) { static unsigned short irq=0, nmi=0, res=0; if(!irq) { FCEUI_GetIVectors(&res,&irq,&nmi); } #if 1 { static int InSoundCode=0; static unsigned UnLoopPtr=0; static bool Looping=false; if(PC == irq) { printf("IRQ\n"); InSoundCode=0; Looping=false; } if(PC == nmi) { printf("NMI\n"); InSoundCode=0; Looping=false; } if(PC == res) { printf("RESET\n"); InSoundCode=0; Looping=false; } if(PC == 0xD0AD) { InSoundCode=0; /*printf("exit sound code\n");*/ } if(PC == 0xD0BD) { InSoundCode=0; /*printf("exit sound code\n");*/ } if(PC == UnLoopPtr) { /*printf("Loop break\n");*/ Looping=false; } if(PC == 0xC000) InSoundCode++; //switchbank if(PC == 0xD0D7) InSoundCode++; //readjoypads if(PC == 0xCFA8) InSoundCode++; //RenderMeter if(PC == 0xCF5D) InSoundCode++; //RenderMeters if(PC == 0xCEF9) InSoundCode++; //RenderSomething if(PC == 0xCC77) InSoundCode++; //RenderEverything if(!InSoundCode && !Looping) { DisAsm(PC,A,X,Y,S,P); if((ARead[PC](PC) & 0x1F) == 0x10 && (ARead[PC+1](PC+1) >= 0xE0)) { unsigned jump_target = PC + (signed char)(ARead[PC+1](PC+1)) + 2; bool valid_short_jump = true; while(jump_target < PC) { unsigned char opcode = ARead[jump_target](jump_target); const unsigned addrmode = asminfo[opcode]-'A'; const unsigned bytes = 1+addrmodes[addrmode].bytes; /* Don't hide this short loop, if it contains a branch or a call */ if(opcode == 0x20 || ((opcode&0x1F)==0x10) || opcode==0x4C || opcode==0x6C) { valid_short_jump=false; break; } jump_target += bytes; } if(valid_short_jump) { Looping=true; UnLoopPtr = PC+2; printf("\n"); } } } if(PC == 0xC021) { printf("\n"); InSoundCode--; } //switchbank if(PC == 0xD0F4) { printf("\n"); InSoundCode--; } //readjoypads if(PC == 0xCFE2) { printf("\n"); InSoundCode--; } //RenderMeter if(PC == 0xCFA7) { printf("\n"); InSoundCode--; } //RenderMeters if(PC == 0xCEF6) { printf("\n"); InSoundCode--; } //RenderSomething if(PC == 0xCD04) { printf("\n"); InSoundCode--; } //RenderEverything if(PC == 0xD0AA) { InSoundCode++; printf("\n"); } if(PC == 0xD0BA) { InSoundCode++; printf("\n"); } fflush(stdout); } #endif } --------------------------------------------------------------- --------------CODE PIECE 3 (PATCH IN x6502.c)------------------ --------------------------------------------------------------- _PI=_P; + BisqBotMonitorCPU(_PC, X.A, X.X, X.Y, X.S, X.P); b1=RdMem(_PC); //printf("$%04x, $%02x\n",_PC,b1); ADDCYC(CycTable[b1]); //PPUHack(); temp=_tcount; _tcount=0;