Beispiel #1
0
static void* nes_thread_proc(void *param)
{
    NES *nes = (NES*)param;
    int totalpclk, nmi, irq;

    while (!nes->thread_exit)
    {
        //++ for run/pause ++//
        if (!nes->isrunning)
        {
            nes->ispaused = 1;
            nes->ppu.vdev->dequeue(nes->ppu.vctxt, NULL, NULL);
            nes->ppu.vdev->enqueue(nes->ppu.vctxt);
            continue;
        }
        //-- for run/pause --//

        //++ for replay playing ++//
        if (!replay_progress(&(nes->replay)) && nes->request_reset == 0)
        {
            nes->ppu.vdev->dequeue(nes->ppu.vctxt, NULL, NULL);
            nes->ppu.vdev->enqueue(nes->ppu.vctxt);
            continue;
        }
        //-- for replay playing --//

        //++ for nes reset ++//
        if (nes->request_reset == 1)
        {
            nes->request_reset = 0;
            nes_do_reset(nes);
        }
        //-- for nes reset --//

        //++ run cpu & apu & ppu
        do {
            cpu_run_pclk(&(nes->cpu)); // run cpu
            ppu_run_pclk(&(nes->ppu)); // run ppu
            apu_run_pclk(&(nes->apu)); // run apu

            //+ for cpu nmi & irq
            nmi =   nes->ppu.pinvbl;
            irq = !(nes->apu.regs[0x0015] & 0xC0);
            cpu_nmi(&(nes->cpu), nmi);
            cpu_irq(&(nes->cpu), irq);
            //- for cpu nmi & irq
        } while (nes->ppu.pclk_frame != NES_HTOTAL * 241 + 2);
        // at frame clk (241, 2) the frame buffer will be enqueued
        //-- run cpu & apu & ppu

        // run joypad for turbo key function
        joypad_run(&(nes->pad));
    }
    return NULL;
}
Beispiel #2
0
void gb_run()
{
	
#ifdef PROFILE
	prof_enter(PF_GB_RUN);
#endif

	//if (rom_get_loaded()){
		if (g_regs.LCDC&0x80){ // LCDC 起動時
			g_regs.LY=(g_regs.LY+1)%154;

			g_regs.STAT&=0xF8;
			if (g_regs.LYC==g_regs.LY){
				g_regs.STAT|=4;
				if (g_regs.STAT&0x40)
					cpu_irq(INT_LCDC);
			}
			if (g_regs.LY==0){
				renderer_refresh();
				if (now_frame>=skip){
					//pgFillvram(0);

					render_screen(vframe);
					now_frame=0;
				}
				else
					now_frame++;
				lcd_clear_win_count();
//				skip=skip_buf;
			}
			if (g_regs.LY>=144){ // VBlank 期間中
				g_regs.STAT|=1;
				if (g_regs.LY==144){
					cpu_exec(72);
					cpu_irq(INT_VBLANK);
					if (g_regs.STAT&0x10)
						cpu_irq(INT_LCDC);
					cpu_exec(456-80);
				}
				else if (g_regs.LY==153){
					cpu_exec(80);
					g_regs.LY=0;
					cpu_exec(456-80); // 前のラインのかなり早目から0になるようだ。
					g_regs.LY=153;
				}
				else
					cpu_exec(456);
			}
			else{ // VBlank 期間外
				g_regs.STAT|=2;
				if (g_regs.STAT&0x20)
					cpu_irq(INT_LCDC);
				cpu_exec(80); // state=2
				g_regs.STAT|=3;
				cpu_exec(169); // state=3

				if (dma_executing){ // HBlank DMA
					if (b_dma_first){
						dma_dest_bank=vram_bank;
						if (dma_src<0x4000)
							dma_src_bank=get_rom();
						else if (dma_src<0x8000)
							dma_src_bank=mbc_get_rom();
						else if (dma_src>=0xA000&&dma_src<0xC000)
							dma_src_bank=mbc_get_sram()-0xA000;
						else if (dma_src>=0xC000&&dma_src<0xD000)
							dma_src_bank=ram-0xC000;
						else if (dma_src>=0xD000&&dma_src<0xE000)
							dma_src_bank=ram_bank-0xD000;
						else dma_src_bank=NULL;
						b_dma_first=false;
					}
					memcpy(dma_dest_bank+(dma_dest&0x1ff0),dma_src_bank+dma_src,16);
//					fprintf(cpu_file,"%03d : dma exec %04X -> %04X rest %d\n",g_regs.LY,cpu_dma_src,cpu_dma_dest,cpu_dma_rest);

					dma_src+=16;
					dma_src&=0xfff0;
					dma_dest+=16;

					dma_dest&=0xfff0;
					dma_rest--;
					if (!dma_rest)
						dma_executing=false;

//					cpu_total_clock+=207*(cpu_speed?2:1);
//					cpu_sys_clock+=207*(cpu_speed?2:1);
//					cpu_div_clock+=207*(cpu_speed?2:1);
//					g_regs.STAT|=3;

					if (now_frame>=skip && !sgb_mask)
						lcd_render(vframe,g_regs.LY);

					g_regs.STAT&=0xfc;
					cpu_exec(207); // state=3
				}
				else{
/*					if (lcd_get_sprite_count()){
						if (lcd_get_sprite_count()>=10){
							cpu_exec(129);
							if ((g_regs.STAT&0x08))
								cpu_irq(INT_LCDC);
							g_regs.STAT&=0xfc;
							if (now_frame>=skip)
								lcd_render(vframe,g_regs.LY);
							cpu_exec(78); // state=0
						}
						else{
							cpu_exec(129*lcd_get_sprite_count()/10);
							if ((g_regs.STAT&0x08))
								cpu_irq(INT_LCDC);
							g_regs.STAT&=0xfc;
							if (now_frame>=skip)
								lcd_render(vframe,g_regs.LY);
							cpu_exec(207-(129*lcd_get_sprite_count()/10)); // state=0
						}
					}
					else{
*/						g_regs.STAT&=0xfc;
						if (now_frame>=skip && !sgb_mask)
							lcd_render(vframe,g_regs.LY);
						if ((g_regs.STAT&0x08))
							cpu_irq(INT_LCDC);
						cpu_exec(207); // state=0
//					}
				}
			}
		}
		else{ // LCDC 停止時
			g_regs.LY=0;
//			g_regs.LY=(g_regs.LY+1)%154;
			re_render++;
			if (re_render>=154){
				gb_fill_vframe(0xff);
				
				renderer_refresh();
				if (now_frame>=skip){
					//pgFillvram(0);
					
					render_screen(vframe);
					now_frame=0;
				}
				else
					now_frame++;
				lcd_clear_win_count();
				re_render=0;
			}
			g_regs.STAT&=0xF8;
			cpu_exec(456);
		}
	//}
	
#ifdef PROFILE
	prof_out();
#endif
}
Beispiel #3
0
int gb_run()
{
	int cmd = 0;
	if (rom_get_loaded()){
		if (g_regs.LCDC&0x80){ // LCDC 起動時
			g_regs.LY=(g_regs.LY+1)%154;

			g_regs.STAT&=0xF8;
			if (g_regs.LYC==g_regs.LY){
				g_regs.STAT|=4;
				if (g_regs.STAT&0x40)
					cpu_irq(INT_LCDC);
			}
			if (g_regs.LY==0){
//				renderer_refresh();
				cmd |= 1;
/*				if (gbSkip){
					render_screen(vframe);
//					now_frame=0;
				}
				else
					now_frame++;*/
				lcd_clear_win_count();
//				skip=skip_buf;
			}
			if (g_regs.LY>=144){ // VBlank 期間中
				g_regs.STAT|=1;
				if (g_regs.LY==144){
					cpu_exec(72);
					cpu_irq(INT_VBLANK);
					if (g_regs.STAT&0x10)
						cpu_irq(INT_LCDC);
					cpu_exec(456-80);
				}
				else if (g_regs.LY==153){
					cpu_exec(80);
					g_regs.LY=0;
					cpu_exec(456-80); // 前のラインのかなり早目から0になるようだ。
					g_regs.LY=153;
				}
				else
					cpu_exec(456);
			}
			else{ // VBlank 期間外
				g_regs.STAT|=2;
				if (g_regs.STAT&0x20)
					cpu_irq(INT_LCDC);
				cpu_exec(80); // state=2
				g_regs.STAT|=3;
				cpu_exec(169); // state=3

				if (dma_executing){ // HBlank DMA
					if (b_dma_first){
						dma_dest_bank=vram_bank;
						if (dma_src<0x4000)
							dma_src_bank=get_rom();
						else if (dma_src<0x8000)
							dma_src_bank=mbc_get_rom();
						else if (dma_src>=0xA000&&dma_src<0xC000)
							dma_src_bank=mbc_get_sram()-0xA000;
						else if (dma_src>=0xC000&&dma_src<0xD000)
							dma_src_bank=ram-0xC000;
						else if (dma_src>=0xD000&&dma_src<0xE000)
							dma_src_bank=ram_bank-0xD000;
						else dma_src_bank=NULL;
						b_dma_first=false;
					}
					memcpy(dma_dest_bank+(dma_dest&0x1ff0),dma_src_bank+dma_src,16);
//					fprintf(cpu_file,"%03d : dma exec %04X -> %04X rest %d\n",g_regs.LY,cpu_dma_src,cpu_dma_dest,cpu_dma_rest);

					dma_src+=16;
					dma_src&=0xfff0;
					dma_dest+=16;
					dma_dest&=0xfff0;
					dma_rest--;
					if (!dma_rest)
						dma_executing=false;

//					cpu_total_clock+=207*(cpu_speed?2:1);
//					cpu_sys_clock+=207*(cpu_speed?2:1);
//					cpu_div_clock+=207*(cpu_speed?2:1);
//					g_regs.STAT|=3;

					if (!gbSkip && !sgb_mask)
						lcd_render(vframe,g_regs.LY);

					g_regs.STAT&=0xfc;
					cpu_exec(207); // state=3
				}
				else{
/*					if (lcd_get_sprite_count()){
						if (lcd_get_sprite_count()>=10){
							cpu_exec(129);
							if ((g_regs.STAT&0x08))
								cpu_irq(INT_LCDC);
							g_regs.STAT&=0xfc;
							if (now_frame>=skip)
								lcd_render(vframe,g_regs.LY);
							cpu_exec(78); // state=0
						}
						else{
							cpu_exec(129*lcd_get_sprite_count()/10);
							if ((g_regs.STAT&0x08))
								cpu_irq(INT_LCDC);
							g_regs.STAT&=0xfc;
							if (now_frame>=skip)
								lcd_render(vframe,g_regs.LY);
							cpu_exec(207-(129*lcd_get_sprite_count()/10)); // state=0
						}
					}
					else{
*/						g_regs.STAT&=0xfc;
						if (!gbSkip && !sgb_mask)
							lcd_render(vframe,g_regs.LY);
						if ((g_regs.STAT&0x08))
							cpu_irq(INT_LCDC);
						cpu_exec(207); // state=0
//					}
				}
			}
		}
		else{ // LCDC 停止時
			g_regs.LY=0;
//			g_regs.LY=(g_regs.LY+1)%154;
			re_render++;
			if (re_render>=154)		{
//				memset(vframe,0xff,(160+16)*144*2);
				if (!gbSkip)
					memset(vframe, 0xff, VFRAME_SIZE);
//				renderer_refresh();
				cmd |= 1;
/*				if (!gbSkip)		{
//					render_screen(vframe);
					now_frame=0;
				}
				else
					now_frame++;*/
				lcd_clear_win_count();
				re_render=0;
			}
			g_regs.STAT&=0xF8;
			cpu_exec(456);
		}

//		if (!menuConfig.sound.perfectSynchro)
//			sound_update_gb(line);
	}
	return cmd;

}
Beispiel #4
0
int sc_main(int, char **) {
	MBWrapper cpu("MBWrapper");
	Memory inst_ram("inst_ram", INST_RAM_SIZE);
	// Memory data_ram("data_ram", SRAM_SIZE);
	Bus bus("bus");
	TIMER timer("timer", sc_core::sc_time(20, sc_core::SC_NS));
	Vga vga("vga");
	Intc intc("intc");
	Gpio gpio("gpio");


	sc_core::sc_signal<bool> timer_irq("timer_irq");
	sc_core::sc_signal<bool> vga_irq("vga_irq");
	sc_core::sc_signal<bool> cpu_irq("cpu_irq");

	// Load the program in RAM
	soclib::common::Loader::register_loader("elf",
	                                        soclib::common::elf_load);
	try {
		soclib::common::Loader loader("../software/cross/a.out");
		loader.load(inst_ram.storage, 0, SOFT_SIZE);
		for (int i = 0; i < SOFT_SIZE / 4; i++) {
			inst_ram.storage[i] =
			    uint32_be_to_machine(inst_ram.storage[i]);
		}
	} catch (soclib::exception::RunTimeError e) {
		std::cerr << "unable to load ELF file in memory:" << std::endl;
		std::cerr << e.what() << std::endl;
		abort();
	}

	// initiators
	cpu.socket.bind(bus.target);
	vga.initiator(bus.target);

	// targets
	// bus.initiator(data_ram.target);
	bus.initiator(inst_ram.target);
	bus.initiator(vga.target);
	bus.initiator(timer.target);
	bus.initiator(gpio.target);
	bus.initiator(intc.target);

	// interrupts
	vga.irq(vga_irq);
	timer.irq(timer_irq);
	intc.in0(vga_irq);
	intc.in1(timer_irq);
	intc.out(cpu_irq);
	cpu.irq(cpu_irq);

	//      port             start addr         size
	bus.map(inst_ram.target, INST_RAM_BASEADDR, INST_RAM_SIZE);
	// bus.map(data_ram.target, SRAM_BASEADDR,     SRAM_SIZE);
	bus.map(vga.target, VGA_BASEADDR, VGA_SIZE);
	bus.map(gpio.target, GPIO_BASEADDR, GPIO_SIZE);
	bus.map(timer.target, TIMER_BASEADDR, TIMER_SIZE);
	bus.map(intc.target, INTC_BASEADDR, INTC_SIZE);


	// start the simulation
	sc_core::sc_start();

	return 0;
}