Beispiel #1
0
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");
}
Beispiel #2
0
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); */
}
Beispiel #3
0
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);
}