예제 #1
0
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
	struct GB* gb = (struct GB*) cpu->master;
	struct GBMemory* memory = &gb->memory;
	switch (address >> 12) {
	case GB_REGION_CART_BANK0:
	case GB_REGION_CART_BANK0 + 1:
	case GB_REGION_CART_BANK0 + 2:
	case GB_REGION_CART_BANK0 + 3:
	case GB_REGION_CART_BANK1:
	case GB_REGION_CART_BANK1 + 1:
	case GB_REGION_CART_BANK1 + 2:
	case GB_REGION_CART_BANK1 + 3:
		memory->mbc(gb, address, value);
		cpu->memory.setActiveRegion(cpu, cpu->pc);
		return;
	case GB_REGION_VRAM:
	case GB_REGION_VRAM + 1:
		gb->video.renderer->writeVRAM(gb->video.renderer, (address & (GB_SIZE_VRAM_BANK0 - 1)) | (GB_SIZE_VRAM_BANK0 * gb->video.vramCurrentBank));
		gb->video.vramBank[address & (GB_SIZE_VRAM_BANK0 - 1)] = value;
		return;
	case GB_REGION_EXTERNAL_RAM:
	case GB_REGION_EXTERNAL_RAM + 1:
		if (memory->rtcAccess) {
			memory->rtcRegs[memory->activeRtcReg] = value;
		} else if (memory->sramAccess) {
			memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
		} else if (memory->mbcType == GB_MBC7) {
			GBMBC7Write(memory, address, value);
		}
		gb->sramDirty |= GB_SRAM_DIRT_NEW;
		return;
	case GB_REGION_WORKING_RAM_BANK0:
	case GB_REGION_WORKING_RAM_BANK0 + 2:
		memory->wram[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		return;
	case GB_REGION_WORKING_RAM_BANK1:
		memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		return;
	default:
		if (address < GB_BASE_OAM) {
			memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		} else if (address < GB_BASE_UNUSABLE) {
			if (gb->video.mode < 2) {
				gb->video.oam.raw[address & 0xFF] = value;
			}
		} else if (address < GB_BASE_IO) {
			mLOG(GB_MEM, GAME_ERROR, "Attempt to write to unusable memory: %04X:%02X", address, value);
		} else if (address < GB_BASE_HRAM) {
			GBIOWrite(gb, address & (GB_SIZE_IO - 1), value);
		} else if (address < GB_BASE_IE) {
			memory->hram[address & GB_SIZE_HRAM] = value;
		} else {
			GBIOWrite(gb, REG_IE, value);
		}
	}
}
예제 #2
0
void GBIOReset(struct GB* gb) {
	memset(gb->memory.io, 0, sizeof(gb->memory.io));

	GBIOWrite(gb, REG_TIMA, 0);
	GBIOWrite(gb, REG_TMA, 0);
	GBIOWrite(gb, REG_TAC, 0);
	GBIOWrite(gb, REG_IF, 1);
	GBIOWrite(gb, REG_NR52, 0xF1);
	GBIOWrite(gb, REG_NR10, 0x80);
	GBIOWrite(gb, REG_NR11, 0xBF);
	GBIOWrite(gb, REG_NR12, 0xF3);
	GBIOWrite(gb, REG_NR13, 0xF3);
	GBIOWrite(gb, REG_NR14, 0xBF);
	GBIOWrite(gb, REG_NR21, 0x3F);
	GBIOWrite(gb, REG_NR22, 0x00);
	GBIOWrite(gb, REG_NR24, 0xBF);
	GBIOWrite(gb, REG_NR30, 0x7F);
	GBIOWrite(gb, REG_NR31, 0xFF);
	GBIOWrite(gb, REG_NR32, 0x9F);
	GBIOWrite(gb, REG_NR34, 0xBF);
	GBIOWrite(gb, REG_NR41, 0xFF);
	GBIOWrite(gb, REG_NR42, 0x00);
	GBIOWrite(gb, REG_NR43, 0x00);
	GBIOWrite(gb, REG_NR44, 0xBF);
	GBIOWrite(gb, REG_NR50, 0x77);
	GBIOWrite(gb, REG_NR51, 0xF3);
	GBIOWrite(gb, REG_LCDC, 0x91);
	GBIOWrite(gb, REG_SCY, 0x00);
	GBIOWrite(gb, REG_SCX, 0x00);
	GBIOWrite(gb, REG_LYC, 0x00);
	GBIOWrite(gb, REG_BGP, 0xFC);
	GBIOWrite(gb, REG_OBP0, 0xFF);
	GBIOWrite(gb, REG_OBP1, 0xFF);
	GBIOWrite(gb, REG_WY, 0x00);
	GBIOWrite(gb, REG_WX, 0x00);
	GBIOWrite(gb, REG_VBK, 0);
	GBIOWrite(gb, REG_BCPS, 0);
	GBIOWrite(gb, REG_OCPS, 0);
	GBIOWrite(gb, REG_SVBK, 1);
	GBIOWrite(gb, REG_HDMA1, 0xFF);
	GBIOWrite(gb, REG_HDMA2, 0xFF);
	GBIOWrite(gb, REG_HDMA3, 0xFF);
	GBIOWrite(gb, REG_HDMA4, 0xFF);
	gb->memory.io[REG_HDMA5] = 0xFF;
	GBIOWrite(gb, REG_IE, 0x00);
}
예제 #3
0
파일: memory.c 프로젝트: OpenEmu/mGBA-Core
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
	struct GB* gb = (struct GB*) cpu->master;
	struct GBMemory* memory = &gb->memory;
	if (gb->memory.dmaRemaining) {
		const enum GBBus* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB;
		enum GBBus dmaBus = block[memory->dmaSource >> 13];
		enum GBBus accessBus = block[address >> 13];
		if (dmaBus != GB_BUS_CPU && dmaBus == accessBus) {
			return;
		}
		if (address >= GB_BASE_OAM && address < GB_BASE_UNUSABLE) {
			return;
		}
	}
	switch (address >> 12) {
	case GB_REGION_CART_BANK0:
	case GB_REGION_CART_BANK0 + 1:
	case GB_REGION_CART_BANK0 + 2:
	case GB_REGION_CART_BANK0 + 3:
	case GB_REGION_CART_BANK1:
	case GB_REGION_CART_BANK1 + 1:
	case GB_REGION_CART_BANK1 + 2:
	case GB_REGION_CART_BANK1 + 3:
		memory->mbcWrite(gb, address, value);
		cpu->memory.setActiveRegion(cpu, cpu->pc);
		return;
	case GB_REGION_VRAM:
	case GB_REGION_VRAM + 1:
		gb->video.renderer->writeVRAM(gb->video.renderer, (address & (GB_SIZE_VRAM_BANK0 - 1)) | (GB_SIZE_VRAM_BANK0 * gb->video.vramCurrentBank));
		gb->video.vramBank[address & (GB_SIZE_VRAM_BANK0 - 1)] = value;
		return;
	case GB_REGION_EXTERNAL_RAM:
	case GB_REGION_EXTERNAL_RAM + 1:
		if (memory->rtcAccess) {
			memory->rtcRegs[memory->activeRtcReg] = value;
		} else if (memory->sramAccess && memory->sram && memory->mbcType != GB_MBC2) {
			memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
		} else if (memory->mbcType == GB_MBC7) {
			GBMBC7Write(memory, address, value);
		}
		gb->sramDirty |= GB_SRAM_DIRT_NEW;
		return;
	case GB_REGION_WORKING_RAM_BANK0:
	case GB_REGION_WORKING_RAM_BANK0 + 2:
		memory->wram[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		return;
	case GB_REGION_WORKING_RAM_BANK1:
		memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		return;
	default:
		if (address < GB_BASE_OAM) {
			memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)] = value;
		} else if (address < GB_BASE_UNUSABLE) {
			if (gb->video.mode < 2) {
				gb->video.oam.raw[address & 0xFF] = value;
				gb->video.renderer->writeOAM(gb->video.renderer, address & 0xFF);
			}
		} else if (address < GB_BASE_IO) {
			mLOG(GB_MEM, GAME_ERROR, "Attempt to write to unusable memory: %04X:%02X", address, value);
		} else if (address < GB_BASE_HRAM) {
			GBIOWrite(gb, address & (GB_SIZE_IO - 1), value);
		} else if (address < GB_BASE_IE) {
			memory->hram[address & GB_SIZE_HRAM] = value;
		} else {
			GBIOWrite(gb, REG_IE, value);
		}
	}
}