Example #1
0
//返回值: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]));
	}
}