//返回值:0,执行OK; // 其他,错误代码 u8 nes_main(GContext *ctx) { u16 offset=0; u8 res; NesHeader *neshreader = (NesHeader *) rom_file; //由于NES文件头类型以0x1A结束,(0x1a是Ctrl+Z,这是模拟文件结束的符号) //所以使用strcncmp比较前3个字节。 if(strncmp(neshreader->filetype, "NES", 3) != 0) { APP_LOG(APP_LOG_LEVEL_INFO, "\r\n文件未加载或文件类型错误, NES模拟器退出。"); return 1; }else { APP_LOG(APP_LOG_LEVEL_INFO, "\r\n文件加载完成。"); APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 16kB ROM 的数目: %d", neshreader->romnum); APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 8kB VROM 的数目: %d", neshreader->vromnum); if((neshreader->romfeature & 0x01) == 0){ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 水平镜像"); }else{ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 垂直镜像"); } if((neshreader->romfeature & 0x02) == 0){ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 无记忆SRAM"); }else{ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 有记忆SRAM"); } if((neshreader->romfeature & 0x04) == 0) { APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 无512字节的trainer($7000-$71FF)"); }else { offset=512; APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 有512字节的trainer(ROM格式暂不支持)"); } if((neshreader->romfeature & 0x08) == 0){ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 2屏幕VRAM布局"); }else{ APP_LOG(APP_LOG_LEVEL_INFO, "\r\n 4屏幕VRAM布局(暂不支持)"); } APP_LOG(APP_LOG_LEVEL_INFO, "\r\n iNES Mapper Numbers: %d", (neshreader->rommappernum & 0xF0)|( neshreader->romfeature >> 4)); } res=nes_mem_creat();//申请内存 if(res==0)//申请成功了.则运行游戏 { //初始化nes 模拟器 init6502mem(0, //exp_rom 0, //sram 由卡类型决定, 暂不支持 ((u8*)&rom_file[offset+0x10]), //prg_rombank, 存储器大小 由卡类型决定 neshreader->romnum );//初始化6502存储器镜像 reset6502();//复位 PPU_Init(((u8*)&rom_file[offset+0x10] + (neshreader->romnum * 0x4000)), (neshreader->romfeature & 0x01));//PPU_初始化 NES_JoyPadInit(); NesFrameCycle(ctx);//模拟器循环执行 } nes_mem_delete();//释放内存 return res; }
int main(int argc, char **argv) { int cycles_to_run; char *machine_code; // This will hold our "ASCII Object File" char debug_command[180]="init"; char *cmdptr; unsigned int dbg_addr; printf("6502 simulator front end for CS 2208a.\n\n"); // Did the user specify an object file on the command line? // If not... help them. if(argc < 3) { printf("Usage: %s [ASCII Object File name] [# cycles to simulate] {-d}\n",argv[0]); printf(" e.g.: %s test.obj 3000 -d\n\n",argv[0]); exit(-1); } // Read the object file into a string. machine_code = read_obj_file(argv[1]); // Fire up the system RAM initMem(); // Load the object file from the string into our simulated RAM, // starting at memory location 'code_location'. loadMem(machine_code,code_location); // We did something horribly underhanded in read_obj_file()... // we allocated memory with 'malloc' and then passed back a pointer. // But note that the onus is on us, the C programmer, to _remember_ // that we did that and free up the memory when it's no longer needed. // Not a big deal here, but imagine a bigger program where you're keeping // track of hundreds of mallocs and frees. Now you know why C programs // leak memory like the titanic. free(machine_code); // Initialize the 6502 init6502(); reset6502(); PC = code_location; // Make sure the program counter points to our code! // All set to run the simulator now! // Everything below is just fanciness to give you a rudimentry 6502 debugger // to help with your assignment. Without the fancyness, all we're really doing // is one call: // // exec6502(num_cycles); // Run in debug mode, if requested if( (argc > 3) && (!strcmp(argv[3],"-d"))) { printf("Running in DEBUG MODE.\n\nType '?' for help.\n"); // Debug loop while(strcmp(debug_command,"quit")) { //dumpMem(0x0021); // Check the value we stored to the zero page //dumpMem(0x01FF); // Peek at the top of the stack. Remember, the stack // is hard-coded to addresses $0100–$01FF. //dump6502reg(); // print registers to the screen printf("debug> "); if( (gets(debug_command))[0] != '\0'){ cmdptr = strtok(debug_command," "); switch(cmdptr[0]) { case 'p': if(cmdptr = strtok(NULL," ")) { sscanf(cmdptr, "%x", &dbg_addr); dumpMem((WORD)dbg_addr); } break; case 'r': dump6502reg(); break; case 's': exec6502(1); // Execute 1 command break; case '?': printf("\n\np [0xAddress] - print value at memory location\n"); printf("r - print register values\n"); printf("s - step through program\n"); printf("quit - exit\n\n"); break; default: (cmdptr[0] % 2) ? printf("Herp.\n") : printf("Derp.\n"); } } } } else { // Otherwise, run in regular mode. exec6502(atoi(argv[2])); } }