void nes_reset(NES *nes) { joypad_reset(&(nes->pad)); mmc_reset (&(nes->mmc)); ppu_reset (&(nes->ppu)); apu_reset (&(nes->apu)); cpu_reset (&(nes->cpu)); }
void reset(bool hard_reset) { if(hard_reset) { memset(cpu_->mem_page[0], 0, NES_RAMSIZE); if(rominfo_->vram) { mem_trash_(rominfo_->vram, 0x2000 * rominfo_->vram_banks); } } apu_reset(); ppu_reset(hard_reset == true ? 1 : 0); mmc_reset(); nes6502_reset(); scanline_ = 241; }
void nes_reset(int hard) { int i; if(nes->rom == 0) return; //set default read/write handlers for(i=0;i<16;i++) { mem_setread(i,0); mem_setwrite(i,0); } //set rom read handlers (mappers might use these) for(i=8;i<16;i++) mem_setread(i,nes_read_rom); //ram mem_setreadptr(0,nes->ram); mem_setwriteptr(0,nes->ram); mem_setreadptr(1,nes->ram); mem_setwriteptr(1,nes->ram); //ppu mem_setread(2,ppu_read); mem_setwrite(2,ppu_write); mem_setread(3,ppu_read); mem_setwrite(3,ppu_write); //apu mem_setread(4,nes_read_4000); mem_setwrite(4,nes_write_4000); //mapper will set its read/write handlers nes->mapper->reset(hard); nes->frame_irqmode = 0; apu_reset(hard); ppu_reset(); dead6502_reset(); if(hard) { memset(nes->ram,0,0x800); for(i=0;i<32;i++) pal_write(i,startup_pal[i]); } log_message("nes reset ok\n"); }
void gb_reset() { set_gb_type(); g_regs.SC=0; g_regs.DIV=0; g_regs.TIMA=0; g_regs.TMA=0; g_regs.TAC=0; g_regs.LCDC=0x91; g_regs.STAT=0; g_regs.SCY=0; g_regs.SCX=0; g_regs.LY=153; g_regs.LYC=0; g_regs.BGP=0xFC; g_regs.OBP1=0xFF; g_regs.OBP2=0xFF; g_regs.WY=0; g_regs.WX=0; g_regs.IF=0; g_regs.IE=0; cpu_irq_check(); // memset(&c_regs,0,sizeof(c_regs)); cpu_reset(); lcd_reset(); apu_reset(); mbc_reset(); sgb_reset(); gbe_reset(); gb_fill_vframe(0); // now_frame=0; gbSkip=0; //skip_buf=0; re_render=0; // char *gb_names[]={"Invalid","Gameboy","SuperGameboy","Gameboy Color","Gameboy Advance"}; // if (m_rom->get_loaded()) // renderer_output_log("Current GB Type : %s \n",gb_names[m_rom->get_info()->gb_type]); }
// 内部函数实现 static void nes_do_reset(NES *nes) { // mmc need reset first mmc_reset(&(nes->mmc)); // reset cpu & ppu & apu cpu_reset(&(nes->cpu)); ppu_reset(&(nes->ppu)); apu_reset(&(nes->apu)); // reset joypad joypad_reset(&(nes->pad)); // reset replay replay_reset(&(nes->replay)); // restart ndb ndb_set_debug(&(nes->ndb), NDB_DEBUG_MODE_RESTART); }
void gb_init(void) { lcd_init(); rom_init(); apu_init();// ROMより後に作られたし mbc_init(); cpu_init(); sgb_init(); cheat_init(); apu_reset(); mbc_reset(); //target=NULL; renderer_init(); gb_reset(); hook_ext=false; use_gba=false; }
void gb_init(void) { lcd_init(); rom_init(); apu_init();// ROMより後に作られたし mbc_init(); cpu_init(); sgb_init(); #ifdef CHEAT_SUPPORT cheat_init(); #endif apu_reset(); mbc_reset(); //target=NULL; gbe_init(); gb_reset(); hook_ext=false; use_gba=false; }
int LoadAPU_embedded(FILE *fptr) { int i=0, j=0, count=0, val=0; unsigned char spc_pcl; unsigned char spc_pch; unsigned char spc_a; unsigned char spc_x; unsigned char spc_y; unsigned char spc_sw; unsigned char spc_sp; // unsigned char spcdata[65536]; // unsigned char spcram[64]; unsigned char dsp_kon=0; unsigned char dsp_flg=0; unsigned char dsp_esa=0; unsigned char dsp_edl=0; unsigned char workbuf[64]; int echosize, echoregion, bootptr, readcount; fseek(fptr, 0x25, SEEK_SET); fread(&spc_pcl, 1, 1, fptr); fread(&spc_pch, 1, 1, fptr); fread(&spc_a, 1, 1, fptr); fread(&spc_x, 1, 1, fptr); fread(&spc_y, 1, 1, fptr); fread(&spc_sw, 1, 1, fptr); fread(&spc_sp, 1, 1, fptr); if (g_debug) { printf("PC: %02x%02x\n", spc_pch, spc_pcl); printf("A: %02X\n", spc_a); printf("X: %02X\n", spc_x); printf("Y: %02X\n", spc_y); printf("SW: %02X\n", spc_sw); printf("SP: %02X\n", spc_sp); } apu_reset(); apu_initTransfer(0x0002); if (g_verbose) printf("Restoring dsp registers...\n"); if (g_exit_now || !g_playing) { apu_reset(); return 0; } /* first, we send a small program called the dsploader which we will * use to restore the DSP registers (with our modified KON and FLG to * keep it silent) */ if (apu_writeBytes(dsploader, 16)) { fprintf(stderr, "Timeout sending dsploader\n"); return -1; } apu_endTransfer(0x0002); if (g_exit_now || !g_playing) { apu_reset(); return 0; } /* restore the 128 dsp registers one by one with the help of the dsp loader. */ fseek(fptr, OFFSET_DSPDATA, SEEK_SET); for (i=0; i<128; i+=64) { fread(workbuf, 64, 1, fptr); for (j=0; j<64; j++) { /* mute all voices and stop all notes */ if (i+j == DSP_FLG) { dsp_flg = workbuf[j]; // save it for later workbuf[j] = DSP_FLG_MUTE|DSP_FLG_ECEN; } if (i+j == DSP_KON) { dsp_kon = workbuf[j]; // save it for later workbuf[j] = 0x00; } // take note of some values while we upload... if (i+j == DSP_ESA) { dsp_esa = workbuf[j]; } if (i+j == DSP_EDL) { dsp_edl = workbuf[j]; } apu_write(1, workbuf[j]); apu_write(0, i+j); if (!apu_waitInport(0, i+j, 500)) { if (apu_read(0)==0xaa) { // fprintf(stderr, "ingored\n"); } else { fprintf(stderr, "timeout 3\n"); return -1; } } if (g_exit_now || !g_playing) { apu_reset(); return 0; } #ifdef PROGRESS_SPINNER if (g_progress) { pspin_update(); } #endif } } // if (g_verbose) // printf("\n"); /* after receiving 128 registers, the dsp loaded will jump * inside the rom at address $ffc9. Once 0xAA appears in * port0, the apu is ready for a new transfer. */ if (!apu_waitInport(0, 0xaa, 500)) { fprintf(stderr, "timeout 4\n"); return -1; } // fseek(fptr, OFFSET_SPCRAM, SEEK_SET); // fread(spcram, 64, 1, fptr); /* save a bunch of registers to be restored * later by the "bootcode" */ bootcode[BOOT_DSP_FLG] = dsp_flg; bootcode[BOOT_DSP_KON] = dsp_kon; bootcode[BOOT_A] = spc_a; bootcode[BOOT_Y] = spc_y; bootcode[BOOT_X] = spc_x; bootcode[BOOT_SP] = spc_sp - 3; // save new stack pointer /* save address $0000 and $0001 to be restored by "bootcode" */ fseek(fptr, OFFSET_SPCDATA, SEEK_SET); fread(workbuf, 2, 1, fptr); bootcode[0x01] = workbuf[0]; bootcode[0x04] = workbuf[1]; /* save most spc registers (0xf0 to 0xff) into bootcode to be restored * later */ fseek(fptr, OFFSET_SPCDATA+0xf0, SEEK_SET); fread(workbuf, 0x10, 1, fptr); for (i=0xf0; i<=0xff; i++) { switch (i) { case SPC_PORT0: bootcode[BOOT_SPC_PORT0] = workbuf[i-0xf0]; break; case SPC_PORT1: bootcode[BOOT_SPC_PORT1] = workbuf[i-0xf0]; break; case SPC_PORT2: bootcode[BOOT_SPC_PORT2] = workbuf[i-0xf0]; break; case SPC_PORT3: bootcode[BOOT_SPC_PORT3] = workbuf[i-0xf0]; break; case SPC_TIMER0: bootcode[BOOT_SPC_TIMER0] = workbuf[i-0xf0]; break; case SPC_TIMER1: bootcode[BOOT_SPC_TIMER1] = workbuf[i-0xf0]; break; case SPC_TIMER2: bootcode[BOOT_SPC_TIMER2] = workbuf[i-0xf0]; break; case SPC_CONTROL: bootcode[BOOT_SPC_CONTROL] = workbuf[i-0xf0]; break; case SPC_REGADD: bootcode[BOOT_SPC_REGADD] = workbuf[i-0xf0]; break; } } /* to produce an echo effect, the dsp uses a memory region. * ESA: Esa * 100h becomes the lead-off address of the echo * region. Calculate this address... */ echoregion = dsp_esa * 256; /* echo delay. The bigger the delay is, more memory is needed. * calculate how much memory used... */ echosize = dsp_edl * 2048; if (echosize==0) { echosize = 4; } if (g_debug) { printf("debug: echoregion: $%04x, size %d\n", echoregion, echosize); } apu_initTransfer(0x0002); if (g_verbose) printf("Restoring spc700 memory...\n"); if (g_debug) { printf("debug: Sending spc memory from 0x02 to 0xef\n"); } /* send the first part of the memory (0x02 to 0xef) * After 0xef comes spc700 registers (0xf0 to 0xff). Those * are taken care of by the bootcode. 0x00 and 0x01 are * retored by the bootcode too. */ fseek(fptr, OFFSET_SPCDATA, SEEK_SET); for (j=0; j<256; j+=64) { fread(workbuf, 64, 1, fptr); for (i=0; i<0x40; i++) { if (j+i>=0xf0) { break; } if (j==0 && i<2) { continue; } // skip $0000 and $0001 apu_write(1, workbuf[i]); apu_write(0, j+i-2); if (!apu_waitInport(0, j+i-2, 500)) { fprintf(stderr, "timeout 5\n"); return -1; } #ifdef PROGRESS_SPINNER if (g_progress) pspin_update(); #endif if (g_exit_now || !g_playing) { apu_reset(); return 0; } } if (j+i>=0xf0) { break; } } // if (g_verbose) // printf("\n"); if (apu_newTransfer(0x100)) { apu_reset(); return -1; } if (g_debug) { printf("debug: Sending spc memory from 0x100 to 0xffc0\n"); } /* upload the external memory region data (0x100 (page 1) to 0xffbf (rom), * and look for an area with the same consecutive value repeated 77 times */ fseek(fptr, OFFSET_SPCDATA+0x100, SEEK_SET); bootptr = -1; for (i=0x100; i <= 65471; i+= 16) { fread(workbuf, 16, 1, fptr); for (j=0; j<16; j++) { /* push program counter and status ward on stack */ if ((i+j) == (0x100 +spc_sp - 0)) { workbuf[j] = spc_pch; } if ((i+j) == (0x100 +spc_sp - 1)) { workbuf[j] = spc_pcl; } if ((i+j) == (0x100 +spc_sp - 2)) { workbuf[j] = spc_sw; } if ((i > echoregion + echosize) || (i < echoregion) ) { if (val==workbuf[j]) { count++; if (count>=77) { bootptr = i+j-77; // printf("nbptr: %d\n", i+j-77); } } else { val = workbuf[j]; count = 0; } } else { count = 0; } } if (apu_writeBytes(workbuf, 16)) { fprintf(stderr, "Transfer error\n"); return -1; } if (i % 256 == 0) { readcount += 256; #ifdef PROGRESS_SPINNER if (g_progress) { pspin_update(); } #endif } if (g_exit_now || !g_playing) { apu_reset(); return 0; } } // bootptr = 0x2e47; if (g_debug) { printf("debug: area for bootcode: $%04x (%02X)\n", bootptr, val); } /* we did not find an area of 77 consecutive identical byte values. */ if (bootptr == -1) { /* We will have to use the echo region. The region will need to be * at least 77 bytes... */ if (echosize < 77) { fprintf(stderr, "This spc file does not have sufficient ram to be loaded"); return -1; } else { /* we will use the echo region */ bootptr = echoregion; } } if (g_debug) { printf("debug: Sending spc memory from 0xffc0 to 0xffff\n"); } /* upload the external memory area overlapping with the rom... I guess * if we write to those address from the SPC it really writes to this * memory area, but if you read you'll probably get the ROM code. Maybe * it's really Read/Write from the DSP point of view... TODO: Check this * * Maybe also setting SPC_CONTROL msb bit enables this region? It's not * documented my manual... * */ if (bootcode[BOOT_SPC_CONTROL] & 0x80) { fseek(fptr, OFFSET_SPCRAM, SEEK_SET); fread(workbuf, 64, 1, fptr); } else { fseek(fptr, OFFSET_SPCDATA + 65472, SEEK_SET); fread(workbuf, 64, 1, fptr); } if (apu_writeBytes(workbuf, 64)) { return -1; } // if (g_verbose) // printf("\n"); if (apu_newTransfer(bootptr)) { apu_reset(); return -1; } /* Copy our bootcode into the area we found */ if (apu_writeBytes(bootcode, 77)) { fprintf(stderr, "Bootcode transfer error\n"); return -1; } apu_endTransfer(bootptr); //i = 0; if (!apu_waitInport(0, 0x53, 500)) { fprintf(stderr, "timeout 7\n"); return -1; } if (g_debug) { printf("Setting final port values $%02X $%02X $%02X $%02X\n", bootcode[BOOT_SPC_PORT0], bootcode[BOOT_SPC_PORT1], bootcode[BOOT_SPC_PORT2], bootcode[BOOT_SPC_PORT3]); } /* Restore the ports to the value they * had in the .spc (this is not done by the bootcode because * Port0-3 have 2 different values (The value set internally is * seen externaly and the value seen internally is set externally) */ apu_write(0, bootcode[BOOT_SPC_PORT0]); apu_write(1, bootcode[BOOT_SPC_PORT1]); apu_write(2, bootcode[BOOT_SPC_PORT2]); apu_write(3, bootcode[BOOT_SPC_PORT3]); if (g_exit_now || !g_playing) { apu_reset(); return 0; } return 0; }
int main(int argc, char **argv) { int res, i; int use_ppdev=0; int use_ppio=0; int io_specified=0; int reset_and_exit=0, status_line=1, loop=0, play_and_exit=0; char *filename; FILE *fptr=NULL; id666_tag tag; struct timeval tv_before, tv_now; signal(SIGINT, signal_handler); while((res =getopt(argc, argv, "rslvhxed" #ifdef PPDEV_SUPPORTED "p" #endif #ifdef PPIO_SUPPORTED "i" #endif ))>=0) { switch(res) { case 'd': g_debug = 1; break; case 'e': g_use_embedded = 1; break; case 'v': g_verbose = 1; break; case 's': status_line = 0; break; case 'l': loop = 1; break; case 'r': reset_and_exit = 1; break; case 'h': printhelp(); return 0; case 'x': play_and_exit = 1; break; #ifdef PPDEV_SUPPORTED case 'p': use_ppdev = 1; io_specified = 1; break; #endif #ifdef PPIO_SUPPORTED case 'i': use_ppio = 1; io_specified = 1; break; #endif case '?': fprintf(stderr, "Unknown argument. try -h\n"); return -1; } } if (argc-optind<=0 && !reset_and_exit) { fprintf(stderr, "No file specified. Try -h\n"); return -2; } #ifdef PPDEV_SUPPORTED if (!io_specified) { use_ppdev = 1; io_specified = 1; } #endif #ifdef PPIO_SUPPORTED if (!io_specified) { use_ppio = 1; io_specified = 1; } #endif if (!io_specified) { fprintf(stderr, "No io layer for apu compiled\n"); return -3; } #ifdef PPDEV_SUPPORTED if (use_ppdev) { apu_ops = apu_ppdev_getOps(); } else #endif #ifdef PPIO_SUPPORTED if (use_ppio) { apu_ops = apu_ppio_getOps(); } #endif apu_setOps(apu_ops); /* initialize the interface with the module. * (Open device, get io permissions, etc...) */ if (apu_ops->init("")<0) { return 1; } if (reset_and_exit) { if (g_verbose) { printf("Resetting APU\n"); } apu_reset(); return 0; } for (i = optind; i<argc; i++) { if (g_exit_now) { break; } filename = argv[i]; fptr = fopen(filename, "rb"); if (fptr==NULL) { perror("fopen"); return 1; } read_id666(fptr, &tag); g_playing = 1; time_t start, end; start = time (NULL); printf("Now loading '%s'", filename); if (g_use_embedded) { printf(" using 'embedded' algo\n"); if (LoadAPU_embedded(fptr)<0) { break; } } else { printf(" \n"); if (LoadAPU(fptr)<0) { break; } } end = time (NULL); printf("Took %ld seconds to load APU.\n", (end - start) ); if (!g_playing) { continue; } // next if (g_exit_now) { break; } BOLD(); printf("Title: "); NORMAL(); printf("%s\n", tag.title); BOLD(); printf("Game Title: "); NORMAL(); printf("%s\n", tag.game_title); BOLD(); printf("Dumper: "); NORMAL(); printf("%s\n", tag.name_of_dumper); BOLD(); printf("Comments: "); NORMAL(); printf("%s\n", tag.comments); BOLD(); printf("Seconds: "); NORMAL(); printf("%s\n", tag.seconds_til_fadeout); fclose(fptr); if (play_and_exit) { return 0; } gettimeofday(&tv_before, NULL); { int elaps_sec; int num_sec = atoi(tag.seconds_til_fadeout); int last_elaps_sec=-1; if (num_sec<1 || num_sec>999) { num_sec = 150; } if (strlen(tag.title)==0) { strncpy(tag.title, filename, 32); } if (g_exit_now) { break; } while (g_playing) { gettimeofday(&tv_now, NULL); elaps_sec = tv_now.tv_sec - tv_before.tv_sec; if (elaps_sec > num_sec) { break; } if (status_line) { if (last_elaps_sec != elaps_sec) { if (!loop) { BOLD(); printf("Time: "); NORMAL(); printTime(elaps_sec); printf(" ["); printTime(num_sec - elaps_sec); printf("] of "); printTime(num_sec); printf(" \r"); } else { BOLD(); printf("Time: "); NORMAL(); printTime(elaps_sec); printf(" \r"); } } last_elaps_sec = elaps_sec; fflush(stdout); } usleep(7500); // update every 75 ms } if (g_playing) printf("\nFinished playing.\n"); apu_reset(); if (g_exit_now) { break; } } } apu_reset(); return 0; }