}/* z_insert_obj */ /* * z_put_prop, set the value of an object property. * * Process.zargs[0] = object * Process.zargs[1] = number of property to set * Process.zargs[2] = value to set property to * */ internal static void z_put_prop() { zword prop_addr; zbyte value; zbyte mask; if (Process.zargs[0] == 0) { Err.runtime_error(ErrorCodes.ERR_PUT_PROP_0); return; } /* Property id is in bottom five or six bits */ mask = (zbyte)((main.h_version <= ZMachine.V3) ? 0x1f : 0x3f); /* Load address of first property */ prop_addr = first_property(Process.zargs[0]); /* Scan down the property list */ for (; ;) { FastMem.LOW_BYTE(prop_addr, out value); if ((value & mask) <= Process.zargs[1]) { break; } prop_addr = next_property(prop_addr); } /* Exit if the property does not exist */ if ((value & mask) != Process.zargs[1]) { Err.runtime_error(ErrorCodes.ERR_NO_PROP); } /* Store the new property value (byte or word sized) */ prop_addr++; if ((main.h_version <= ZMachine.V3 && !((value & 0xe0) > 0)) || (main.h_version >= ZMachine.V4 && !((value & 0xc0) > 0))) { zbyte v = (zbyte)Process.zargs[2]; FastMem.SET_BYTE(prop_addr, v); } else { zword v = Process.zargs[2]; FastMem.SET_WORD(prop_addr, v); } }/* z_put_prop */
}/* z_remove_obj */ /* * z_set_attr, set an object attribute. * * Process.zargs[0] = object * Process.zargs[1] = number of attribute to set * */ internal static void z_set_attr() { zword obj_addr; zbyte value; if (main.story_id == Story.SHERLOCK) { if (Process.zargs[1] == 48) { return; } } if (Process.zargs[1] > ((main.h_version <= ZMachine.V3) ? 31 : 47)) { Err.runtime_error(ErrorCodes.ERR_ILL_ATTR); } /* If we are monitoring attribute assignment display a short note */ if (main.option_attribute_assignment == true) { Stream.stream_mssg_on(); Text.print_string("@set_attr "); Text.print_object(Process.zargs[0]); Text.print_string(" "); Text.print_num(Process.zargs[1]); Stream.stream_mssg_off(); } if (Process.zargs[0] == 0) { Err.runtime_error(ErrorCodes.ERR_SET_ATTR_0); return; } /* Get attribute address */ obj_addr = (zword)(object_address(Process.zargs[0]) + Process.zargs[1] / 8); /* Load attribute byte */ FastMem.LOW_BYTE(obj_addr, out value); /* Set attribute bit */ value |= (zbyte)(0x80 >> (Process.zargs[1] & 7)); /* Store attribute byte */ FastMem.SET_BYTE(obj_addr, value); }/* z_set_attr */
}/* z_get_sibling */ /* * z_insert_obj, make an object the first child of another object. * * Process.zargs[0] = object to be moved * Process.zargs[1] = destination object * */ internal static void z_insert_obj() { zword obj1 = Process.zargs[0]; zword obj2 = Process.zargs[1]; zword obj1_addr; zword obj2_addr; /* If we are monitoring object movements display a short note */ if (main.option_object_movement == true) { Stream.stream_mssg_on(); Text.print_string("@move_obj "); Text.print_object(obj1); Text.print_string(" "); Text.print_object(obj2); Stream.stream_mssg_off(); } if (obj1 == 0) { Err.runtime_error(ErrorCodes.ERR_MOVE_OBJECT_0); return; } if (obj2 == 0) { Err.runtime_error(ErrorCodes.ERR_MOVE_OBJECT_TO_0); return; } /* Get addresses of both objects */ obj1_addr = object_address(obj1); obj2_addr = object_address(obj2); /* Remove object 1 from current parent */ unlink_object(obj1); /* Make object 1 first child of object 2 */ if (main.h_version <= ZMachine.V3) { zbyte child; obj1_addr += O1_PARENT; FastMem.SET_BYTE(obj1_addr, (zbyte)obj2); obj2_addr += O1_CHILD; FastMem.LOW_BYTE(obj2_addr, out child); FastMem.SET_BYTE(obj2_addr, (zbyte)obj1); obj1_addr += (zword)(O1_SIBLING - O1_PARENT); FastMem.SET_BYTE(obj1_addr, child); } else { zword child; obj1_addr += O4_PARENT; FastMem.SET_WORD(obj1_addr, obj2); obj2_addr += O4_CHILD; FastMem.LOW_WORD(obj2_addr, out child); FastMem.SET_WORD(obj2_addr, obj1); obj1_addr += (zword)(O4_SIBLING - O4_PARENT); FastMem.SET_WORD(obj1_addr, child); } }/* z_insert_obj */
}/* next_property */ /* * unlink_object * * Unlink an object from its parent and siblings. * */ static void unlink_object(zword object_var) { zword obj_addr; zword parent_addr; zword sibling_addr; if (object_var == 0) { Err.runtime_error(ErrorCodes.ERR_REMOVE_OBJECT_0); return; } obj_addr = object_address(object_var); if (main.h_version <= ZMachine.V3) { zbyte parent; zbyte younger_sibling; zbyte older_sibling; zbyte zero = 0; /* Get parent of object, and return if no parent */ obj_addr += O1_PARENT; FastMem.LOW_BYTE(obj_addr, out parent); if (parent == 0) { return; } /* Get (older) sibling of object and set both parent and sibling * pointers to 0 */ FastMem.SET_BYTE(obj_addr, zero); obj_addr += (zword)(O1_SIBLING - O1_PARENT); FastMem.LOW_BYTE(obj_addr, out older_sibling); FastMem.SET_BYTE(obj_addr, zero); /* Get first child of parent (the youngest sibling of the object) */ parent_addr = (zword)(object_address(parent) + O1_CHILD); FastMem.LOW_BYTE(parent_addr, out younger_sibling); /* Remove object from the list of siblings */ if (younger_sibling == object_var) { FastMem.SET_BYTE(parent_addr, older_sibling); } else { do { sibling_addr = (zword)(object_address(younger_sibling) + O1_SIBLING); FastMem.LOW_BYTE(sibling_addr, out younger_sibling); } while (younger_sibling != object_var); FastMem.SET_BYTE(sibling_addr, older_sibling); } } else { zword parent; zword younger_sibling; zword older_sibling; zword zero = 0; /* Get parent of object, and return if no parent */ obj_addr += O4_PARENT; FastMem.LOW_WORD(obj_addr, out parent); if (parent == 0) { return; } /* Get (older) sibling of object and set both parent and sibling * pointers to 0 */ FastMem.SET_WORD(obj_addr, zero); obj_addr += (zword)(O4_SIBLING - O4_PARENT); FastMem.LOW_WORD(obj_addr, out older_sibling); FastMem.SET_WORD(obj_addr, zero); /* Get first child of parent (the youngest sibling of the object) */ parent_addr = (zword)(object_address(parent) + O4_CHILD); FastMem.LOW_WORD(parent_addr, out younger_sibling); /* Remove object from the list of siblings */ if (younger_sibling == object_var) { FastMem.SET_WORD(parent_addr, older_sibling); } else { do { sibling_addr = (zword)(object_address(younger_sibling) + O4_SIBLING); FastMem.LOW_WORD(sibling_addr, out younger_sibling); } while (younger_sibling != object_var); FastMem.SET_WORD(sibling_addr, older_sibling); } } }/* unlink_object */