diff options
Diffstat (limited to 'engines/sci/engine/kemu_old.c')
-rw-r--r-- | engines/sci/engine/kemu_old.c | 330 |
1 files changed, 0 insertions, 330 deletions
diff --git a/engines/sci/engine/kemu_old.c b/engines/sci/engine/kemu_old.c deleted file mode 100644 index 4ec6c0a106..0000000000 --- a/engines/sci/engine/kemu_old.c +++ /dev/null @@ -1,330 +0,0 @@ -/*************************************************************************** - kemu_old.c Copyright (C) 2002 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <jameson@linuxgames.com> - -***************************************************************************/ -/* Emulation code for old kernel functions */ - -#include <engine.h> -#include "kernel_compat.h" -#include "kernel_types.h" -#include "heap.h" - -#define EMU_HEAP_START_ADDR 1000 - -#define EMU_TYPE_VERBATIM 0 /* Arithmetic values */ -#define EMU_TYPE_REGISTERS 1 /* Must re-interpret afterwards. Also used for objects. */ -#define EMU_TYPE_BLOCK 2 /* Bulk data; string or similar. May physically point to stack */ - -static int funct_nr; - -typedef struct { - heap_ptr start; /* Beginning of the block */ - reg_t pos; /* Needed for resolving conflicts */ - int length; /* Number of bytes occupied on the heap */ - object_t *obj; /* For object types: Pointer to the physical object */ - - /* Emulation data part */ - int emudat_type; /* EMU_TYPE_... */ - heap_ptr emudat_location; /* Only for 1 and 2 */ - union { - reg_t *regs; /* registers, for type 1 */ - byte *block; /* Bulk data location, for type 2 */ - } emu_data; - int emudat_size; /* Amount of bytes or number of entries */ -} emu_param_t; - -static inline emu_param_t -identify_value(state_t *s, reg_t reg, heap_ptr firstfree) -{ - emu_param_t retval; - int type = determine_reg_type(s, reg); - - retval.start = firstfree; - retval.pos = reg; - - retval.obj = NULL; - retval.length = 0; - retval.emudat_type = EMU_TYPE_VERBATIM; /* To allow error aborts */ - - if (type & KSIG_NULL) - type &= KSIG_ARITHMETIC; - - switch (type) { - - case KSIG_ARITHMETIC: /* trivial */ - retval.emudat_size = 0; - break; - - case KSIG_OBJECT: - retval.emudat_type = EMU_TYPE_REGISTERS; - retval.obj = obj_get(s, reg); - if (!retval.obj) { BREAKPOINT(); } - retval.length = -SCRIPT_OBJECT_MAGIC_OFFSET - + retval.obj->variables_nr * 4 /* values and selectors */ - + 2; /* Extra magic selector word (is this really needed?) */ - retval.emu_data.regs = retval.obj->variables; - retval.emudat_size = retval.obj->variables_nr; - retval.emudat_location = retval.start - SCRIPT_OBJECT_MAGIC_OFFSET; - break; - - case KSIG_REF: { - retval.emudat_type = EMU_TYPE_BLOCK; - - retval.emu_data.block = - s->seg_manager.dereference(&s->seg_manager, - reg, &retval.emudat_size); - - if (!retval.emu_data.block) { - SCIkdebug(SCIkERROR, "Cannot handle references into segment type %02x" - " (from "PREG") during emulation\n", - type, PRINT_REG(reg)); - retval.emudat_type = EMU_TYPE_VERBATIM; - retval.length = 0; - } - - retval.length = retval.emudat_size; - retval.emudat_location = retval.start; - - break; - } - - default: - SCIkdebug(SCIkERROR, "Cannot handle argument type %02x (from "PREG - ") during emulation\n", - type, PRINT_REG(reg)); - } - - return retval; -} - -static inline void -writeout_value(state_t *s, emu_param_t *p) -{ - if (p->obj) /* First copy object; don't need to read back this part later */ - memcpy(s->heap + p->start, p->obj->base_obj + SCRIPT_OBJECT_MAGIC_OFFSET, - p->length); - - switch (p->emudat_type) { - - case EMU_TYPE_VERBATIM: - SCIkdebug(SCIkEMU, "\tVerbatim/Arithmetic\n"); - return; - - case EMU_TYPE_REGISTERS: { - int i, max = p->emudat_size; - - SCIkdebug(SCIkEMU, "\tObject, %d selectors\n", max); - - for (i = 0; i < max; i++) { - byte *dest = s->heap + p->emudat_location + (i << 1); - - dest[0] = p->emu_data.regs[i].offset & 0xff; - dest[1] = (p->emu_data.regs[i].offset >> 8) & 0xff; - /* Assume they're all numeric values */ - } - return; - } - - case EMU_TYPE_BLOCK: - SCIkdebug(SCIkEMU, "\tBulk\n"); - memcpy(s->heap + p->emudat_location, p->emu_data.block, p->emudat_size); - return; - - default: - BREAKPOINT(); - } -} - -static inline void -recover_value(state_t *s, emu_param_t *p) -{ /* Writes back the value */ - switch (p->emudat_type) { - - case EMU_TYPE_VERBATIM: - return; - - case EMU_TYPE_REGISTERS: { - int i, max = p->emudat_size; - for (i = 0; i < max; i++) { - int val = GET_HEAP(p->emudat_location + (i << 1)); - if (p->emu_data.regs[i].offset != val) { - SCIkdebug(SCIkEMU, " Recovering property #%d from %04x: 0:%04x\n", - i, p->emudat_location + (i << 1), val); - p->emu_data.regs[i] = make_reg(0, val); - } else { - SCIkdebug(SCIkEMU, " Property #%d from %04x is unchanged (%04x vs "PREG")\n", - i, p->emudat_location + (i << 1), val, PRINT_REG(p->emu_data.regs[i])); - } - /* Don't overwrite unless something changed, to preserve pointers */ - } - return; - } - - case EMU_TYPE_BLOCK: - memcpy(p->emu_data.block, s->heap + p->emudat_location, p->emudat_size); - SCIkdebug(SCIkEMU, " Recovering %d raw bytes from %04x\n", - p->emudat_size, p->emudat_location); - return; - - default: - BREAKPOINT(); - } -} - -static void -_restrict_against(state_t *s, emu_param_t *self, emu_param_t *other) -{ - if (self->pos.segment != other->pos.segment) - return; - - if (self->pos.offset <= other->pos.offset - && self->pos.offset + self->emudat_size > other->pos.offset) { - mem_obj_t *mobj = GET_SEGMENT_ANY(s->seg_manager, self->pos.segment); - - self->emudat_size = other->pos.offset - self->pos.offset; - - if (mobj && mobj->type == MEM_OBJ_STACK) - self->emudat_size *= sizeof(reg_t); /* Accomodate for size differences */ - } -} - -static void -resolve_conflicts(state_t *s, emu_param_t *params, int count) -{ - int i, j; - for (i = 0; i < count; i++) - for (j = 0; j < count; j++) - if (i != j) - _restrict_against(s, params + i, params + j); -} - -reg_t -kFsciEmu(state_t *s, int _funct_nr, int argc, reg_t *argv) -{ - emu_param_t *shadow_args; - funct_nr = _funct_nr; - - if (!s->kfunct_emu_table[funct_nr]) { - SCIkwarn(SCIkERROR, "Attempt to emulate unknown kernel function %x\n", - funct_nr); - return NULL_REG; - } else { - heap_ptr argp = EMU_HEAP_START_ADDR; /* arguments go here */ - heap_ptr datap = argp + argc * 2; /* copied stuff goes here */ - int i; - - shadow_args = sci_malloc(sizeof(emu_param_t) * (argc + 1 - /* Prevents stupid warning */)); - memset(shadow_args, 0, sizeof(emu_param_t) * (argc + 1)); - - SCIkdebug(SCIkEMU, "Emulating kernel call %s[%x] w/ %d arguments at HP:%04x\n", - s->kernel_names[funct_nr], funct_nr, argc, argp); - - for (i = 0; i < argc; i++) { - int emu_value = argv[i].offset; /* Value we'll pass to the function */ - - SCIkdebug(SCIkEMU, " %3d : ["PREG"] ->\n", i, PRINT_REG(argv[i])); - - shadow_args[i] = identify_value(s, argv[i], datap); - - switch (shadow_args[i].emudat_type) { - - case EMU_TYPE_VERBATIM: - break; - - case EMU_TYPE_REGISTERS: - case EMU_TYPE_BLOCK: - emu_value = shadow_args[i].emudat_location; - break; - - default: - BREAKPOINT(); - - } - - SCIkdebug(SCIkEMU, "\t%04x [%d at %04x]\n", - emu_value, shadow_args[i].length, shadow_args[i].start); - - PUT_HEAP(argp, emu_value); - argp += 2; - - if (0xffff - shadow_args[i].length < datap) { - SCIkdebug(SCIkERROR, "Out of heap space while emulating!\n"); - return NULL_REG; - } - datap += shadow_args[i].length; /* Step over last block we wrote */ - } - - for (i = 0; i < argc; i++) - writeout_value(s, shadow_args + i); - - resolve_conflicts(s, shadow_args, argc); - - s->kfunct_emu_table[funct_nr](s, funct_nr, argc, EMU_HEAP_START_ADDR); - - for (i = 0; i < argc; i++) - recover_value(s, shadow_args + i); - free(shadow_args); - return make_reg(0, s->acc); - } -} - - -int -read_selector16(state_t *s, heap_ptr object, selector_t selector_id, const char *file, int line) -{ - int slc_count = GET_HEAP(object + SCRIPT_SELECTORCTR_OFFSET); - int i; - heap_ptr slc_names = object + slc_count * 2; - - for (i = 0; i < slc_count; i++) { - if (GET_HEAP(slc_names + (i<<1)) == selector_id) - return GET_HEAP(object + (i<<1)); - } - - SCIkdebug(SCIkWARNING, "[EMU] Could not read selector %d from HP:%04x (%s, L%d)\n", - selector_id, object, file, line); - return 0; -} - -void -write_selector16(state_t *s, heap_ptr object, selector_t selector_id, - int value, const char *fname, int line) -{ - int slc_count = GET_HEAP(object + SCRIPT_SELECTORCTR_OFFSET); - int i; - heap_ptr slc_names = object + slc_count * 2; - - for (i = 0; i < slc_count; i++) { - if (GET_HEAP(slc_names + (i<<1)) == selector_id) { - PUT_HEAP(object + (i<<1), value); - return; - } - } - - SCIkdebug(SCIkWARNING, "[EMU] Could not write selector %d from HP:%04x (%s, L%d)\n", - selector_id, object, fname, line); -} - |