Example #1
0
void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) {
	const struct GBMemory* memory = &gb->memory;
	memcpy(state->wram, memory->wram, GB_SIZE_WORKING_RAM);
	memcpy(state->hram, memory->hram, GB_SIZE_HRAM);
	STORE_16LE(memory->currentBank, 0, &state->memory.currentBank);
	state->memory.wramCurrentBank = memory->wramCurrentBank;
	state->memory.sramCurrentBank = memory->sramCurrentBank;

	STORE_16LE(memory->dmaSource, 0, &state->memory.dmaSource);
	STORE_16LE(memory->dmaDest, 0, &state->memory.dmaDest);

	STORE_16LE(memory->hdmaSource, 0, &state->memory.hdmaSource);
	STORE_16LE(memory->hdmaDest, 0, &state->memory.hdmaDest);

	STORE_16LE(memory->hdmaRemaining, 0, &state->memory.hdmaRemaining);
	state->memory.dmaRemaining = memory->dmaRemaining;
	memcpy(state->memory.rtcRegs, memory->rtcRegs, sizeof(state->memory.rtcRegs));

	STORE_32LE(memory->dmaEvent.when - mTimingCurrentTime(&gb->timing), 0, &state->memory.dmaNext);
	STORE_32LE(memory->hdmaEvent.when - mTimingCurrentTime(&gb->timing), 0, &state->memory.hdmaNext);

	GBSerializedMemoryFlags flags = 0;
	flags = GBSerializedMemoryFlagsSetSramAccess(flags, memory->sramAccess);
	flags = GBSerializedMemoryFlagsSetRtcAccess(flags, memory->rtcAccess);
	flags = GBSerializedMemoryFlagsSetRtcLatched(flags, memory->rtcLatched);
	flags = GBSerializedMemoryFlagsSetIme(flags, memory->ime);
	flags = GBSerializedMemoryFlagsSetIsHdma(flags, memory->isHdma);
	flags = GBSerializedMemoryFlagsSetActiveRtcReg(flags, memory->activeRtcReg);
	STORE_16LE(flags, 0, &state->memory.flags);

	switch (memory->mbcType) {
	case GB_MBC1:
		state->memory.mbc1.mode = memory->mbcState.mbc1.mode;
		state->memory.mbc1.multicartStride = memory->mbcState.mbc1.multicartStride;
		break;
	case GB_MBC3_RTC:
		STORE_64LE(gb->memory.rtcLastLatch, 0, &state->memory.rtc.lastLatch);
		break;
	case GB_MBC7:
		state->memory.mbc7.state = memory->mbcState.mbc7.state;
		state->memory.mbc7.eeprom = memory->mbcState.mbc7.eeprom;
		state->memory.mbc7.address = memory->mbcState.mbc7.address;
		state->memory.mbc7.access = memory->mbcState.mbc7.access;
		state->memory.mbc7.latch = memory->mbcState.mbc7.latch;
		state->memory.mbc7.srBits = memory->mbcState.mbc7.srBits;
		STORE_16LE(memory->mbcState.mbc7.sr, 0, &state->memory.mbc7.sr);
		STORE_32LE(memory->mbcState.mbc7.writable, 0, &state->memory.mbc7.writable);
		break;
	default:
		break;
	}
}
Example #2
0
// TODO: Reorganize SGB into its own file
void GBSGBSerialize(struct GB* gb, struct GBSerializedState* state) {
	state->sgb.command = gb->video.sgbCommandHeader;
	state->sgb.bits = gb->sgbBit;

	GBSerializedSGBFlags flags = 0;
	flags = GBSerializedSGBFlagsSetP1Bits(flags, gb->currentSgbBits);
	flags = GBSerializedSGBFlagsSetRenderMode(flags, gb->video.renderer->sgbRenderMode);
	flags = GBSerializedSGBFlagsSetBufferIndex(flags, gb->video.sgbBufferIndex);
	flags = GBSerializedSGBFlagsSetReqControllers(flags, gb->sgbControllers);
	flags = GBSerializedSGBFlagsSetCurrentController(flags, gb->sgbCurrentController);
	STORE_32LE(flags, 0, &state->sgb.flags);

	memcpy(state->sgb.packet, gb->video.sgbPacketBuffer, sizeof(state->sgb.packet));
	memcpy(state->sgb.inProgressPacket, gb->sgbPacket, sizeof(state->sgb.inProgressPacket));

	if (gb->video.renderer->sgbCharRam) {
		memcpy(state->sgb.charRam, gb->video.renderer->sgbCharRam, sizeof(state->sgb.charRam));
	}
	if (gb->video.renderer->sgbMapRam) {
		memcpy(state->sgb.mapRam, gb->video.renderer->sgbMapRam, sizeof(state->sgb.mapRam));
	}
	if (gb->video.renderer->sgbPalRam) {
		memcpy(state->sgb.palRam, gb->video.renderer->sgbPalRam, sizeof(state->sgb.palRam));
	}
	if (gb->video.renderer->sgbAttributeFiles) {
		memcpy(state->sgb.atfRam, gb->video.renderer->sgbAttributeFiles, sizeof(state->sgb.atfRam));
	}
	if (gb->video.renderer->sgbAttributes) {
		memcpy(state->sgb.attributes, gb->video.renderer->sgbAttributes, sizeof(state->sgb.attributes));
	}
	gb->video.renderer->enableSGBBorder(gb->video.renderer, gb->video.sgbBorders);
}
Example #3
0
ssize_t VFileRead32LE(struct VFile* vf, void* word) {
	uint32_t leword;
	ssize_t r = vf->read(vf, &leword, 4);
	if (r == 4) {
		STORE_32LE(leword, 0, word);
	}
	return r;
}
Example #4
0
void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
	STORE_32LE(GB_SAVESTATE_MAGIC + GB_SAVESTATE_VERSION, 0, &state->versionMagic);
	STORE_32LE(gb->romCrc32, 0, &state->romCrc32);
	STORE_32LE(gb->timing.masterCycles, 0, &state->masterCycles);

	if (gb->memory.rom) {
		memcpy(state->title, ((struct GBCartridge*) &gb->memory.rom[0x100])->titleLong, sizeof(state->title));
	} else {
		memset(state->title, 0, sizeof(state->title));
	}

	state->model = gb->model;

	state->cpu.a = gb->cpu->a;
	state->cpu.f = gb->cpu->f.packed;
	state->cpu.b = gb->cpu->b;
	state->cpu.c = gb->cpu->c;
	state->cpu.d = gb->cpu->d;
	state->cpu.e = gb->cpu->e;
	state->cpu.h = gb->cpu->h;
	state->cpu.l = gb->cpu->l;
	STORE_16LE(gb->cpu->sp, 0, &state->cpu.sp);
	STORE_16LE(gb->cpu->pc, 0, &state->cpu.pc);

	STORE_32LE(gb->cpu->cycles, 0, &state->cpu.cycles);
	STORE_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);

	STORE_16LE(gb->cpu->index, 0, &state->cpu.index);
	state->cpu.bus = gb->cpu->bus;
	state->cpu.executionState = gb->cpu->executionState;

	GBSerializedCpuFlags flags = 0;
	flags = GBSerializedCpuFlagsSetCondition(flags, gb->cpu->condition);
	flags = GBSerializedCpuFlagsSetIrqPending(flags, gb->cpu->irqPending);
	flags = GBSerializedCpuFlagsSetDoubleSpeed(flags, gb->doubleSpeed);
	flags = GBSerializedCpuFlagsSetEiPending(flags, mTimingIsScheduled(&gb->timing, &gb->eiPending));
	STORE_32LE(flags, 0, &state->cpu.flags);
	STORE_32LE(gb->eiPending.when - mTimingCurrentTime(&gb->timing), 0, &state->cpu.eiPending);

	GBMemorySerialize(gb, state);
	GBIOSerialize(gb, state);
	GBVideoSerialize(&gb->video, state);
	GBTimerSerialize(&gb->timer, state);
	GBAudioSerialize(&gb->audio, state);

	if (gb->model & GB_MODEL_SGB) {
		GBSGBSerialize(gb, state);
	}
}
Example #5
0
ssize_t VFileWrite32LE(struct VFile* vf, int32_t word) {
	uint32_t leword;
	STORE_32LE(word, 0, &leword);
	return vf->write(vf, &leword, 4);
}
Example #6
0
void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
	STORE_32LE(GB_SAVESTATE_MAGIC + GB_SAVESTATE_VERSION, 0, &state->versionMagic);
	STORE_32LE(gb->romCrc32, 0, &state->romCrc32);

	if (gb->memory.rom) {
		memcpy(state->title, ((struct GBCartridge*) gb->memory.rom)->titleLong, sizeof(state->title));
	} else {
		memset(state->title, 0, sizeof(state->title));
	}

	state->model = gb->model;

	state->cpu.a = gb->cpu->a;
	state->cpu.f = gb->cpu->f.packed;
	state->cpu.b = gb->cpu->b;
	state->cpu.c = gb->cpu->c;
	state->cpu.d = gb->cpu->d;
	state->cpu.e = gb->cpu->e;
	state->cpu.h = gb->cpu->h;
	state->cpu.l = gb->cpu->l;
	STORE_16LE(gb->cpu->sp, 0, &state->cpu.sp);
	STORE_16LE(gb->cpu->pc, 0, &state->cpu.pc);

	STORE_32LE(gb->cpu->cycles, 0, &state->cpu.cycles);
	STORE_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent);

	STORE_16LE(gb->cpu->index, 0, &state->cpu.index);
	state->cpu.bus = gb->cpu->bus;
	state->cpu.executionState = gb->cpu->executionState;
	STORE_16LE(gb->cpu->irqVector, 0, &state->cpu.irqVector);

	STORE_32LE(gb->eiPending, 0, &state->cpu.eiPending);

	GBSerializedCpuFlags flags = 0;
	flags = GBSerializedCpuFlagsSetCondition(flags, gb->cpu->condition);
	flags = GBSerializedCpuFlagsSetIrqPending(flags, gb->cpu->irqPending);
	flags = GBSerializedCpuFlagsSetDoubleSpeed(flags, gb->doubleSpeed);
	STORE_32LE(flags, 0, &state->cpu.flags);

	GBMemorySerialize(&gb->memory, state);
	GBIOSerialize(gb, state);
	GBVideoSerialize(&gb->video, state);
	GBTimerSerialize(&gb->timer, state);
	GBAudioSerialize(&gb->audio, state);

#ifndef _MSC_VER
	struct timeval tv;
	if (!gettimeofday(&tv, 0)) {
		uint64_t usec = tv.tv_usec;
		usec += tv.tv_sec * 1000000LL;
		STORE_64LE(usec, 0, &state->creationUsec);
	}
#else
	struct timespec ts;
	if (timespec_get(&ts, TIME_UTC)) {
		uint64_t usec = ts.tv_nsec / 1000;
		usec += ts.tv_sec * 1000000LL;
		STORE_64LE(usec, 0, &state->creationUsec);
	}
#endif
	else {
		state->creationUsec = 0;
	}
}