Exemplo n.º 1
0
static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp)
{
    WinDumpPhyMemDesc64 *desc = &h->PhysicalMemoryBlock;
    WinDumpPhyMemRun64 *run = desc->Run;
    Error *local_err = NULL;
    int i;

    for (i = 0; i < desc->NumberOfRuns; i++) {
        s->written_size += write_run(run + i, s->fd, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
    }
}
Exemplo n.º 2
0
bool Quetzal::save(Common::WriteStream *svf, Processor *proc, const Common::String &desc) {
	Processor &p = *proc;
	uint ifzslen = 0, cmemlen = 0, stkslen = 0, descLen = 0;
	uint pc;
	zword i, j, n;
	zword nvars, nargs, nstk;
	zbyte var;
	long cmempos, stkspos;
	int c;

	// Set a temporary memory stream for writing out the data. This is needed, since we need to
	// do some seeking within it at the end to fill out totals before properly writing it all out
	Common::MemoryWriteStreamDynamic saveData(DisposeAfterUse::YES);
	_out = &saveData;

	// Write `IFZS' header.
	write_chnk(ID_FORM, 0);
	write_long(ID_IFZS);

	// Write `IFhd' chunk
	pc = p.getPC();
	write_chnk(ID_IFhd, 13);
	write_word(p.h_release);
	for (i = H_SERIAL; i<H_SERIAL + 6; ++i)
		write_byte(p[i]);

	write_word(p.h_checksum);
	write_long(pc << 8);		// Includes pad

	// Write 'ANNO' chunk
	descLen = desc.size() + 1;
	write_chnk(ID_ANNO, descLen);
	saveData.write(desc.c_str(), desc.size());
	write_byte(0);
	if ((desc.size() % 2) == 0) {
		write_byte(0);
		++descLen;
	}

	// Write `CMem' chunk.
	cmempos = saveData.pos();
	write_chnk(ID_CMem, 0);
	_storyFile->seek(0);

	// j holds current run length.
	for (i = 0, j = 0, cmemlen = 0; i < p.h_dynamic_size; ++i) {
		c = _storyFile->readByte();
		c ^= p[i];

		if (c == 0) {
			// It's a run of equal bytes
			++j;
		} else {
			// Write out any run there may be.
			if (j > 0) {
				for (; j > 0x100; j -= 0x100) {
					write_run(0xFF);
					cmemlen += 2;
				}
				write_run(j - 1);
				cmemlen += 2;
				j = 0;
			}

			// Any runs are now written. Write this (nonzero) byte
			write_byte((zbyte)c);
			++cmemlen;
		}
	}

	// Reached end of dynamic memory. We ignore any unwritten run there may be at this point.
	if (cmemlen & 1)
		// Chunk length must be even.
		write_byte(0);

	// Write `Stks' chunk. You are not expected to understand this. ;)
	stkspos = saveData.pos();
	write_chnk(ID_Stks, 0);

	// We construct a list of frame indices, most recent first, in `frames'.
	// These indices are the offsets into the `stack' array of the word before
	// the first word pushed in each frame.
	frames[0] = p._sp - p._stack;	// The frame we'd get by doing a call now.
	for (i = p._fp - p._stack + 4, n = 0; i < STACK_SIZE + 4; i = p._stack[i - 3] + 5)
		frames[++n] = i;

	// All versions other than V6 can use evaluation stack outside a function
	// context. We write a faked stack frame (most fields zero) to cater for this.
	if (p.h_version != V6) {
		for (i = 0; i < 6; ++i)
			write_byte(0);
		nstk = STACK_SIZE - frames[n];
		write_word(nstk);
		for (j = STACK_SIZE - 1; j >= frames[n]; --j)
			write_word(p._stack[j]);
		stkslen = 8 + 2 * nstk;
	}

	// Write out the rest of the stack frames.
	for (i = n; i > 0; --i) {
		zword *pf = p._stack + frames[i] - 4;	// Points to call frame
		nvars = (pf[0] & 0x0F00) >> 8;
		nargs = pf[0] & 0x00FF;
		nstk = frames[i] - frames[i - 1] - nvars - 4;
		pc = ((uint)pf[3] << 9) | pf[2];

		// Check type of call
		switch (pf[0] & 0xF000)	{
		case 0x0000:
			// Function
			var = p[pc];
			pc = ((pc + 1) << 8) | nvars;
			break;

		case 0x1000:
			// Procedure
			var = 0;
			pc = (pc << 8) | 0x10 | nvars;	// Set procedure flag
			break;

		default:
			p.runtimeError(ERR_SAVE_IN_INTER);
			return 0;
		}
		if (nargs != 0)
			nargs = (1 << nargs) - 1;	// Make args into bitmap

		// Write the main part of the frame...
		write_long(pc);
		write_byte(var);
		write_byte(nargs);
		write_word(nstk);

		// Write the variables and eval stack
		for (j = 0, --pf; j<nvars + nstk; ++j, --pf)
			write_word(*pf);

		// Calculate length written thus far
		stkslen += 8 + 2 * (nvars + nstk);
	}

	// Fill in variable chunk lengths
	ifzslen = 4 * 8 + 4 + 14 + cmemlen + stkslen + descLen;
	if (cmemlen & 1)
		++ifzslen;

	saveData.seek(4);
	saveData.writeUint32BE(ifzslen);
	saveData.seek(cmempos + 4);
	saveData.writeUint32BE(cmemlen);
	saveData.seek(stkspos + 4);
	saveData.writeUint32BE(stkslen);

	// Write the save data out
	svf->write(saveData.getData(), saveData.size());

	// After all that, still nothing went wrong!
	return true;
}
Exemplo n.º 3
0
void generate_run (run_tab_t *run_table) {
    int i;
    for (i=0; i<run_table->used_size; i++) {
	write_run (run_table->table[i]);
    }
}