PPlugin PromptPlugin (int Type) { char filepath[MAX_PATH]; PPlugin result = (PPlugin)DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_SELECTPLUGIN),topHWnd,DLG_SelectPlugin,(LPARAM)Type); if (result == NULL) return NULL; if (result->num != 9998) return result; PromptTitle = "Specify iNES mapper number (cancel for none):\r\n(-1 to skip .NES, 9999 to skip .NES and .UNIF)"; if (Prompt(topHWnd)) custplug.num = atoi(PromptResult); else custplug.num = -1; if (custplug.num != 9999) { PromptTitle = "Specify UNIF board name (cancel for none):"; if (Prompt(topHWnd)) strcpy(custplug.name,PromptResult); else if (custplug.num == -1) custplug.num = 9999; } while (1) { if (!PromptFile(topHWnd,"USB CopyNES Plugins (*.bin)\0*.bin\0\0\0\0", filepath, custplug.file, Path_PLUG, "Select a plugin (must be in Plugins path)", "bin", FALSE)) return NULL; if (strnicmp(Path_PLUG, filepath, strlen(Path_PLUG))) MessageBox(topHWnd,"Selected file is not located in Plugins directory!","Select Plugin", MB_OK | MB_ICONERROR); else break; } return &custplug; }
BOOL UploadGAR (void) { FILE *GAR; char filename[MAX_PATH]; int i; if (!PromptFile(topHWnd,"Game Action Replay RAM file (gar.bin)\0gar.bin\0\0",filename,NULL,Path_PLUG,"Please select a valid Game Action Replay data file...","gar.bin",FALSE)) return FALSE; if ((GAR = fopen(filename,"rb")) == NULL) { MessageBox(topHWnd,"Unable to open GAR data file!",MSGBOX_TITLE,MB_OK | MB_ICONERROR); return FALSE; } OpenStatus(topHWnd); InitPort(); StatusText("Resetting CopyNES..."); ResetNES(RESET_COPYMODE); StatusText("Loading initialization plugin..."); if (!LoadPlugin("garset.bin")) { fclose(GAR); CloseStatus(); return FALSE; } StatusText("Running initialization plugin..."); RunCode(); Sleep(SLEEP_LONG); StatusText("Loading upload plugin..."); if (!LoadPlugin("garup.bin")) { fclose(GAR); CloseStatus(); return FALSE; } StatusText("Running upload plugin..."); RunCode(); StatusText("Uploading from data file..."); BYTE a[256]; for (i = 0; i < 8; i++) { fread(&a,256,1,GAR); if (!WriteBlock(a, 256)) { fclose(GAR); CloseStatus(); return FALSE; } StatusPercent((i*100)/8); } StatusPercent(100); StatusText("...done!"); fclose(GAR); StatusText("Upload complete!"); StatusOK(); ResetNES(RESET_COPYMODE); return TRUE; }
BOOL DownloadGAR (void) { FILE *GAR; char filename[MAX_PATH]; int i; if (!PromptFile(topHWnd,"Game Action Replay RAM file (gar_d.bin)\0gar_d.bin\0\0",filename,NULL,Path_PLUG,"Please specify where to save Game Action Replay RAM data...","gar_d.bin",TRUE)) return FALSE; if ((GAR = fopen(filename,"wb")) == NULL) { MessageBox(topHWnd,"Unable to open file for output!",MSGBOX_TITLE,MB_OK | MB_ICONERROR); return FALSE; } OpenStatus(topHWnd); InitPort(); StatusText("Resetting CopyNES..."); ResetNES(RESET_COPYMODE); StatusText("Loading initialization plugin..."); if (!LoadPlugin("garset.bin")) { fclose(GAR); CloseStatus(); return FALSE; } StatusText("Running initialization plugin..."); RunCode(); Sleep(SLEEP_LONG); StatusText("Loading download plugin..."); if (!LoadPlugin("gardn.bin")) { fclose(GAR); CloseStatus(); return FALSE; } StatusText("Running download plugin..."); RunCode(); StatusText("Saving to file..."); for (i = 0; i < 0x800; i++) { BYTE n; if (!ReadByte(n)) { fclose(GAR); CloseStatus(); return FALSE; } fwrite(&n,1,1,GAR); if (!(i & 0x7)) StatusPercent((i*100)/2048); } fclose(GAR); StatusText("Download complete!"); StatusOK(); ResetNES(RESET_COPYMODE); return TRUE; }
BOOL CMD_MAKEUNIF (void) { int i; char PRGback[MAX_PATH], CHRback[MAX_PATH], NESback[MAX_PATH]; int battery, mirror = 0, fourscrn = 0, mcon = 0; char filepath[MAX_PATH], filename[MAX_PATH]; Plugin *plugin = PromptPlugin(PLUG_STD); if (plugin == NULL) return FALSE; if (!PromptFile(topHWnd,"PRG data (*.PRG)\0*.prg\0\0",filepath,filename,NULL,"Select PRG segment","prg",FALSE)) return FALSE; mirror = (MessageBox(topHWnd,"Vertical mirroring?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); fourscrn = (MessageBox(topHWnd,"4-screen VRAM?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); mcon = (MessageBox(topHWnd,"Mapper-controlled mirroring?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); battery = (MessageBox(topHWnd,"Battery-backed RAM?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); strcpy(PRGback,Path_PRG); strcpy(CHRback,Path_CHR); strcpy(NESback,Path_NES); i = strlen(filepath); while (i > 0) if (filepath[--i] == '\\') { filepath[++i] = 0; break; } i = strlen(filename); while (i > 0 && filename[i] != '.') i--; if (i) filename[i] = 0; strcpy(Path_PRG,filepath); strcpy(Path_CHR,filepath); strcpy(Path_NES,filepath); WriteUNIF(filename, plugin->name.c_str(), battery, mirror, fourscrn, mcon); strcpy(Path_PRG,PRGback); strcpy(Path_CHR,CHRback); strcpy(Path_NES,NESback); return FALSE; }
BOOL CMD_MAKENES (void) { int i; char PRGback[MAX_PATH], CHRback[MAX_PATH], NESback[MAX_PATH]; int mapper, battery, mirror, fourscrn; char filepath[MAX_PATH], filename[MAX_PATH]; if (!PromptFile(topHWnd,"PRG data (*.PRG)\0*.prg\0\0",filepath,filename,NULL,"Select PRG segment","prg",FALSE)) return FALSE; PromptTitle = "Enter mapper number:"; if (!Prompt(topHWnd)) return FALSE; mapper = atoi(PromptResult); battery = (MessageBox(topHWnd,"Battery-backed RAM?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); mirror = (MessageBox(topHWnd,"Vertical mirroring?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); fourscrn = (MessageBox(topHWnd,"4-screen VRAM?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); strcpy(PRGback,Path_PRG); strcpy(CHRback,Path_CHR); strcpy(NESback,Path_NES); i = strlen(filepath); while (i > 0) if (filepath[--i] == '\\') { filepath[++i] = 0; break; } i = strlen(filename); while (i > 0 && filename[i] != '.') i--; if (i) filename[i] = 0; strcpy(Path_PRG,filepath); strcpy(Path_CHR,filepath); strcpy(Path_NES,filepath); WriteNES(filename, mapper, battery, mirror, fourscrn); strcpy(Path_PRG,PRGback); strcpy(Path_CHR,CHRback); strcpy(Path_NES,NESback); return FALSE; }
BOOL CMD_DISASM (void) { FILE *BIN, *ASM; char filename[MAX_PATH]; int pc; BOOL badops; if (!PromptFile(topHWnd,"6502 Binary Data (*.*)\0*.*\0\0",filename,NULL,NULL,"Select code segment","*",FALSE)) return FALSE; BIN = fopen(filename,"rb"); if (!BIN) { MessageBox(topHWnd,"Failed to open file!",MSGBOX_TITLE,MB_OK | MB_ICONERROR); return FALSE; } pc = 0; // using variable PC since we don't save this value PromptTitle = "File offset to begin disassembly from?\n(cancel for beginning of file)"; if (Prompt(topHWnd)) sscanf(PromptResult,"%i",&pc); fseek(BIN,pc,SEEK_SET); pc = 0x8000; PromptTitle = "Address of first instruction?\n(cancel for 0x8000)"; if (Prompt(topHWnd)) sscanf(PromptResult,"%i",&pc); if (!PromptFile(topHWnd,"Disassembly (*.ASM)\0*.asm\0\0",filename,NULL,NULL,"Enter filename for disassembly output","asm",TRUE)) return FALSE; ASM = fopen(filename,"wb"); if (!ASM) { fclose(BIN); MessageBox(topHWnd,"Failed to create output file!",MSGBOX_TITLE,MB_OK | MB_ICONERROR); return FALSE; } badops = (MessageBox(topHWnd,"Enable invalid opcodes?",MSGBOX_TITLE,MB_YESNO | MB_ICONQUESTION) == IDYES); while ((!feof(BIN)) && (pc < 0x10000)) { unsigned char OpData[3] = {0,0,0}; unsigned short Operand = 0; int AddrMode; char *Instruct; fread(OpData+0,1,1,BIN); AddrMode = TraceAddrMode[OpData[0]]; Instruct = TraceArr[OpData[0]]; if (!badops && Instruct[0] == '*') { AddrMode = ERR; Instruct = " ???"; } switch (AddrMode) { case IND: case ADR: case ABS: case ABX: case ABY: fread(OpData+1,1,1,BIN); fread(OpData+2,1,1,BIN); Operand = OpData[1] | (OpData[2] << 8); break; case IMM: case ZPG: case ZPX: case ZPY: case INX: case INY: fread(OpData+1,1,1,BIN); Operand = OpData[1]; break; case IMP: case ACC: case ERR: break; case REL: fread(OpData+1,1,1,BIN); Operand = pc + 2 + (signed char)OpData[1]; break; } switch (AddrMode) { case IMP: fprintf(ASM,"%04X %02X %s\n", pc,OpData[0], Instruct); break; case ERR: fprintf(ASM,"%04X %02X %s\n", pc,OpData[0], Instruct); break; case ACC: fprintf(ASM,"%04X %02X %s A\n", pc,OpData[0], Instruct); break; case IMM: fprintf(ASM,"%04X %02X %02X %s #$%02X\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case REL: fprintf(ASM,"%04X %02X %02X %s $%04X\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case ZPG: fprintf(ASM,"%04X %02X %02X %s $%02X\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case ZPX: fprintf(ASM,"%04X %02X %02X %s $%02X,X\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case ZPY: fprintf(ASM,"%04X %02X %02X %s $%02X,Y\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case INX: fprintf(ASM,"%04X %02X %02X %s ($%02X,X)\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case INY: fprintf(ASM,"%04X %02X %02X %s ($%02X),Y\n", pc,OpData[0],OpData[1], Instruct,Operand); break; case ADR: fprintf(ASM,"%04X %02X %02X %02X %s $%04X\n", pc,OpData[0],OpData[1],OpData[2], Instruct,Operand); break; case ABS: fprintf(ASM,"%04X %02X %02X %02X %s $%04X\n", pc,OpData[0],OpData[1],OpData[2], Instruct,Operand); break; case IND: fprintf(ASM,"%04X %02X %02X %02X %s ($%04X)\n", pc,OpData[0],OpData[1],OpData[2], Instruct,Operand); break; case ABX: fprintf(ASM,"%04X %02X %02X %02X %s $%04X,X\n", pc,OpData[0],OpData[1],OpData[2], Instruct,Operand); break; case ABY: fprintf(ASM,"%04X %02X %02X %02X %s $%04X,Y\n", pc,OpData[0],OpData[1],OpData[2], Instruct,Operand); break; } pc += TraceAddrBytes[AddrMode]; } fclose(BIN); fclose(ASM); return TRUE; }
BOOL CMD_SPLITUNIF (void) { FILE *UNIF; char filename[MAX_PATH], basename[MAX_PATH]; BYTE buf[1024]; DWORD len; int i; PromptFile(topHWnd,"UNIF Files (*.UNIF,*.UNF)\0*.unif,*.unf\0\0",filename,basename,NULL,"Select a ROM","unif",FALSE); if (!basename[0]) return FALSE; i = strlen(basename); while (basename[i] != '.') i--; basename[i] = 0; // drop the extension UNIF = fopen(filename,"rb"); fread(buf,1,4,UNIF); if (memcmp("UNIF",buf,4)) { fclose(UNIF); MessageBox(topHWnd,"This is not a UNIF ROM image!",MSGBOX_TITLE,MB_OK | MB_ICONERROR); return FALSE; } fseek(UNIF,28,SEEK_CUR); fread(buf,1,4,UNIF); fread(&len,4,1,UNIF); while (!feof(UNIF)) { char outname[MAX_PATH]; FILE *OUTPUT; if (!memcmp(buf,"MIRR",4)) { const char *mir[6] = {"Horizontal","Vertical","Single-screen L","Single-screen H","Four-screen","Mapper-controlled"}; char msg[48]; BYTE a; fread(&a,1,1,UNIF); sprintf(msg,"Mirroring type: %s",mir[a]); MessageBox(topHWnd,msg,MSGBOX_TITLE,MB_OK | MB_ICONINFORMATION); fseek(UNIF,len-1,SEEK_CUR); } else if (!memcmp(buf,"DINF",4)) { char msg[256]; char info[205]; fread(info,1,204,UNIF); info[204] = 0; sprintf(msg,"Dumped by %s on %i/%i/%i using %s", info, info[100] | info[101] << 8, info[102], info[103], info + 104); MessageBox(topHWnd,msg,MSGBOX_TITLE,MB_OK | MB_ICONINFORMATION); fseek(UNIF,len-204,SEEK_CUR); } else if (!memcmp(buf,"MAPR",4)) { char *msg = (char *)malloc(len + 16); char *board = (char *)malloc(len); fread(board,1,len,UNIF); sprintf(msg,"Board name: %s",board); free(board); MessageBox(topHWnd,msg,MSGBOX_TITLE,MB_OK | MB_ICONINFORMATION); free(msg); } else if (!memcmp(buf,"PRG",3)) { sprintf(outname,"%s%s.pr%c",Path_PRG,basename,buf[3]); OUTPUT = fopen(outname,"wb"); for (i = 0; i < (signed)len; i++) { BYTE a; fread(&a,1,1,UNIF); fwrite(&a,1,1,OUTPUT); } fclose(OUTPUT); } else if (!memcmp(buf,"CHR",3)) { sprintf(outname,"%s%s.pr%c",Path_CHR,basename,buf[3]); OUTPUT = fopen(outname,"wb"); for (i = 0; i < (signed)len; i++) { BYTE a; fread(&a,1,1,UNIF); fwrite(&a,1,1,OUTPUT); } fclose(OUTPUT); } else { // dunno, skip to end of block fseek(UNIF,len,SEEK_CUR); } fread(buf,1,4,UNIF); fread(&len,4,1,UNIF); } fclose(UNIF); MessageBox(topHWnd,"Done!",MSGBOX_TITLE,MB_OK); return TRUE; }