void accel_set_func(glui32 index, glui32 addr) { int bucknum; accelentry_t *ptr; int functype; acceleration_func new_func = NULL; /* Check the Glulx type identifier byte. */ functype = Mem1(addr); if (functype != 0xC0 && functype != 0xC1) { fatal_error_i("Attempt to accelerate non-function.", addr); } if (!accelentries) { accelentries = (accelentry_t **)glulx_malloc(ACCEL_HASH_SIZE * sizeof(accelentry_t *)); if (!accelentries) fatal_error("Cannot malloc acceleration table."); for (bucknum=0; bucknum<ACCEL_HASH_SIZE; bucknum++) accelentries[bucknum] = NULL; } new_func = accel_find_func(index); /* Might be NULL, if the index is zero or not recognized. */ bucknum = (addr % ACCEL_HASH_SIZE); for (ptr = accelentries[bucknum]; ptr; ptr = ptr->next) { if (ptr->addr == addr) break; } if (!ptr) { if (!new_func) { return; /* no need for a new entry */ } ptr = (accelentry_t *)glulx_malloc(sizeof(accelentry_t)); if (!ptr) fatal_error("Cannot malloc acceleration entry."); ptr->addr = addr; ptr->index = 0; ptr->func = NULL; ptr->next = accelentries[bucknum]; accelentries[bucknum] = ptr; } ptr->index = index; ptr->func = new_func; }
glui32 do_gestalt(glui32 val, glui32 val2) { switch (val) { case gestulx_GlulxVersion: return 0x00030102; /* Glulx spec version 3.1.2 */ case gestulx_TerpVersion: return 0x00000502; /* Glulxe version 0.5.2 */ case gestulx_ResizeMem: #ifdef FIXED_MEMSIZE return 0; /* The setmemsize opcodes are compiled out. */ #else /* FIXED_MEMSIZE */ return 1; /* We can handle setmemsize. */ #endif /* FIXED_MEMSIZE */ case gestulx_Undo: return 1; /* We can handle saveundo and restoreundo. */ case gestulx_IOSystem: switch (val2) { case 0: return 1; /* The "null" system always works. */ case 1: return 1; /* The "filter" system always works. */ case 2: return 1; /* A Glk library is hooked up. */ default: return 0; } case gestulx_Unicode: return 1; /* We can handle Unicode. */ case gestulx_MemCopy: return 1; /* We can do mcopy/mzero. */ case gestulx_MAlloc: #ifdef FIXED_MEMSIZE return 0; /* The malloc opcodes are compiled out. */ #else /* FIXED_MEMSIZE */ return 1; /* We can handle malloc/mfree. */ #endif /* FIXED_MEMSIZE */ case gestulx_MAllocHeap: return heap_get_start(); case gestulx_Acceleration: return 1; /* We can do accelfunc/accelparam. */ case gestulx_AccelFunc: if (accel_find_func(val2)) return 1; /* We know this accelerated function. */ return 0; case gestulx_Float: #ifdef FLOAT_SUPPORT return 1; /* We can do floating-point operations. */ #else /* FLOAT_SUPPORT */ return 0; /* The floating-point opcodes are not compiled in. */ #endif /* FLOAT_SUPPORT */ #ifdef GLULX_EXTEND_GESTALT GLULX_EXTEND_GESTALT #endif /* GLULX_EXTEND_GESTALT */ default: return 0; } }