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 ioreg_write(byte r, byte b) { if (!hw.cgb) { switch (r) { case RI_VBK: case RI_BCPS: case RI_OCPS: case RI_BCPD: case RI_OCPD: case RI_SVBK: case RI_KEY1: case RI_HDMA1: case RI_HDMA2: case RI_HDMA3: case RI_HDMA4: case RI_HDMA5: return; } } switch(r) { case RI_TIMA: case RI_TMA: case RI_TAC: case RI_SCY: case RI_SCX: case RI_WY: case RI_WX: REG(r) = b; break; case RI_BGP: if (R_BGP == b) break; pal_write_dmg(0, 0, b); pal_write_dmg(8, 1, b); R_BGP = b; break; case RI_OBP0: if (R_OBP0 == b) break; pal_write_dmg(64, 2, b); R_OBP0 = b; break; case RI_OBP1: if (R_OBP1 == b) break; pal_write_dmg(72, 3, b); R_OBP1 = b; break; case RI_IF: case RI_IE: REG(r) = b & 0x1F; break; case RI_P1: REG(r) = b; pad_refresh(); break; case RI_SC: /* FIXME - this is a hack for stupid roms that probe serial */ if ((b & 0x81) == 0x81) { R_SB = 0xff; hw_interrupt(IF_SERIAL, IF_SERIAL); hw_interrupt(0, IF_SERIAL); } R_SC = b; /* & 0x7f; */ break; case RI_DIV: REG(r) = 0; break; case RI_LCDC: lcdc_change(b); break; case RI_STAT: stat_write(b); break; case RI_LYC: REG(r) = b; stat_trigger(); break; case RI_VBK: REG(r) = b | 0xFE; mem_updatemap(); break; case RI_BCPS: R_BCPS = b & 0xBF; R_BCPD = lcd.pal[b & 0x3F]; break; case RI_OCPS: R_OCPS = b & 0xBF; R_OCPD = lcd.pal[64 + (b & 0x3F)]; break; case RI_BCPD: R_BCPD = b; pal_write(R_BCPS & 0x3F, b); if (R_BCPS & 0x80) R_BCPS = (R_BCPS+1) & 0xBF; break; case RI_OCPD: R_OCPD = b; pal_write(64 + (R_OCPS & 0x3F), b); if (R_OCPS & 0x80) R_OCPS = (R_OCPS+1) & 0xBF; break; case RI_SVBK: REG(r) = b & 0x07; mem_updatemap(); break; case RI_DMA: hw_dma(b); break; case RI_KEY1: REG(r) = (REG(r) & 0x80) | (b & 0x01); break; case RI_HDMA1: REG(r) = b; break; case RI_HDMA2: REG(r) = b & 0xF0; break; case RI_HDMA3: REG(r) = b & 0x1F; break; case RI_HDMA4: REG(r) = b & 0xF0; break; case RI_HDMA5: hw_hdma_cmd(b); break; } switch (r) { case RI_BGP: case RI_OBP0: case RI_OBP1: /* printf("palette reg %02X write %02X at LY=%02X\n", r, b, R_LY); */ case RI_HDMA1: case RI_HDMA2: case RI_HDMA3: case RI_HDMA4: case RI_HDMA5: /* printf("HDMA %d: %02X\n", r - RI_HDMA1 + 1, b); */ break; } /* printf("reg %02X => %02X (%02X)\n", r, REG(r), b); */ }
int nes_loadstate(int fp) { stateheader_t header; blocknes_t *bnes; blockcpu_t *cpu; blockppu_t *ppu; blockapu_t *apu; blockvram_t *vram; blocksvram_t *svram; blocksram_t *sram; blockwram_t *wram; blockmapper_t *mapper; blockdisk_t *disk; int i; void *block; int blocktype; //load state header if(blocks_loadheader(fp,&header) != 0) return(1); //enumerate thru all the state blocks while((block = blocks_load(fp,&blocktype)) != 0) { switch(blocktype) { case B_NES: bnes = (blocknes_t*)block; memcpy(nes->ram,bnes->ram,0x800); memcpy(nes->nametables[0],bnes->nametables + 0x000,0x400); memcpy(nes->nametables[1],bnes->nametables + 0x400,0x400); memcpy(nes->nametables[2],bnes->nametables + 0x800,0x400); memcpy(nes->nametables[3],bnes->nametables + 0xC00,0x400); memcpy(nes->pal,bnes->palette,32); nes->strobe = bnes->strobe; for(i=0;i<32;i++) pal_write(i,nes->pal[i]); break; case B_CPU: cpu = (blockcpu_t*)block; nes->cpu.a = cpu->a; nes->cpu.x = cpu->x; nes->cpu.y = cpu->y; nes->cpu.s = cpu->s; nes->cpu.f = cpu->f; nes->cpu.pc = cpu->pc; nes->cpu.totalcycles = cpu->cycles; nes->cpu.needirq = cpu->irq; break; case B_PPU: ppu = (blockppu_t*)block; nes->scanline = ppu->scanline; nes->ppu.ctrl0 = ppu->control1; nes->ppu.ctrl1 = ppu->control2; nes->ppu.status = ppu->status; nes->ppu.temp = ppu->temp; nes->ppu.scroll = ppu->scroll; nes->ppu.scrollx = ppu->finex; nes->ppu.toggle = ppu->toggle; nes->ppu.buf = ppu->buffer; nes->ppu.latch = ppu->latch; nes->ppu.spraddr = ppu->spraddr; memcpy(nes->sprmem,ppu->spriteram,0x100); ppucycles = ppu->cycles; ppuframes = ppu->frames; break; case B_APU: apu = (blockapu_t*)block; for(i=0;i<0x16;i++) apu_write(0x4000 + i,apu->regs[i]); break; case B_VRAM: vram = (blockvram_t*)block; if(nes->rom->vram) { memcpy(nes->rom->vram,vram->data,nes->rom->vramsize); for(i=0;i<0x2000;i++) ppumem_write(i,ppumem_read(i)); } break; case B_SVRAM: svram = (blocksvram_t*)block; if(nes->rom->svram) memcpy(nes->rom->svram,svram->data,nes->rom->svramsize); break; case B_SRAM: sram = (blocksram_t*)block; if(nes->rom->sram) memcpy(nes->rom->sram,sram->data,nes->rom->sramsize); break; case B_WRAM: wram = (blockwram_t*)block; if(nes->rom->wram) memcpy(nes->rom->wram,wram->data,nes->rom->wramsize); break; case B_MAPR: mapper = (blockmapper_t*)block; if(nes->mapper->state) nes->mapper->state(STATE_LOAD,mapper->data); break; case B_DISK: disk = (blockdisk_t*)block; for(i=0;i<(nes->rom->disksides * 65500);i++) nes->rom->diskdata[i] = nes->rom->orig_diskdata[i] ^ disk->data[i]; break; } blocks_free(block); log_message("loading block '%s'\n",blockids[blocktype]); } log_message("loaded state, %ld bytes\n",file_tell(fp)); return(0); }