示例#1
0
文件: undo.c 项目: dfjdejulio/fizmo
void opcode_restore_undo(void)
{
  int result;
  size_t dynamic_memory_size;
  struct undo_frame *frame_to_restore;

  TRACE_LOG("Opcode: RESTORE_UNDO.\n");

  if (undo_index > 0)
  {
    undo_index--;

    frame_to_restore = undo_frames[undo_index];

    dynamic_memory_size = (size_t)(
        active_z_story->dynamic_memory_end - z_mem + 1 );

    ensure_z_stack_size(frame_to_restore->z_stack_size);

    pc = frame_to_restore->pc;
    //current_z_stack_size = frame_to_restore->z_stack_size;
    //behind_z_stack = z_stack + current_z_stack_size;
    z_stack_index = z_stack + frame_to_restore->z_stack_size;
    stack_words_from_active_routine
      = frame_to_restore->stack_words_from_active_routine;
    number_of_locals_active
      = frame_to_restore->number_of_locals_active;
    number_of_locals_from_function_call
      = frame_to_restore->number_of_locals_from_function_call;
    local_variable_storage_index
      = z_stack_index
      - stack_words_from_active_routine
      - number_of_locals_active;

    memcpy(
        z_stack, // non-null when size > 0
        frame_to_restore->stack,
        frame_to_restore->z_stack_size * sizeof(uint16_t));
        //current_z_stack_size * sizeof(uint16_t));

    memcpy(
        z_mem,
        frame_to_restore->dynamic_memory,
        dynamic_memory_size);

    delete_undo_frame(frame_to_restore);

    write_interpreter_info_into_header();

    result = 2;
  }
  else
  {
    result = 0;
  }

  read_z_result_variable();
  set_variable(z_res_var, (uint16_t)result, false);
}
示例#2
0
void opcode_load(void)
{
  TRACE_LOG("Opcode: LOAD.\n");

  read_z_result_variable();
  
  TRACE_LOG("Loading variable with code %d to variable with code %d.\n",
      op[0], z_res_var);

  set_variable(z_res_var, get_variable(op[0], true), false);
}
示例#3
0
void opcode_pull(void)
{
  uint16_t value = 0;
  uint16_t spare_slots;
  uint8_t *user_stack;

  TRACE_LOG("Opcode: PULL.\n");

  if (ver == 6)
    (void)read_z_result_variable();

  if ( (ver != 6) || (number_of_operands < 1) )
  {
    if (
        (stack_words_from_active_routine == 0)
        &&
        (bool_equal(skip_active_routines_stack_check_warning, false))
       )
    {
      i18n_translate_and_exit(
          libfizmo_module_name,
          i18n_libfizmo_NOT_ENOUGH_STACK_WORDS_FROM_LOCAL_ROUTINE_ON_STACK, -1);
    }
    else
    {
      TRACE_LOG("Pulling to variable %x.\n", op[0]);
      value = z_stack_pull_word();
      stack_words_from_active_routine--;
    }
  }
  else
  {
    user_stack = z_mem + (uint16_t)op[0];
    spare_slots = load_word(user_stack);
    spare_slots++;
    value = load_word(user_stack + spare_slots);
    store_word(user_stack, spare_slots);
  }

  if (ver == 6)
    set_variable(z_res_var, value, true);
  else
    set_variable(op[0], value, true);

}
示例#4
0
void opcode_loadw(void)
{
  uint16_t value;
  uint8_t *address = z_mem + (uint16_t)(op[0] + ((int16_t)op[1])*2);

  TRACE_LOG("Opcode: LOADW.\n");

  read_z_result_variable();

  if (address > active_z_story->static_memory_end)
  {
    TRACE_LOG("ERROR: Trying to loadw from %x which is above static memory.\n",
        address);
    set_variable(z_res_var, 0, false);
  }
  else
  {
    value = load_word(address);
    TRACE_LOG("Loading %x from %x var %x.\n", value, address, z_res_var);
    set_variable(z_res_var, value, false);
  }
}
示例#5
0
void opcode_push_user_stack(void)
{
  uint16_t spare_slots;
  uint8_t *user_stack;

  TRACE_LOG("Opcode: PUSH_USER_STACK.\n");

  (void)read_z_result_variable();
  user_stack = z_mem + (uint16_t)op[1];

  if ((spare_slots = load_word(user_stack)) > 0)
  {
    store_word(user_stack + spare_slots, (uint16_t)op[0]);
    spare_slots--;
    store_word(user_stack, spare_slots);
    evaluate_branch((uint8_t)1);
  }
  else
  {
    evaluate_branch((uint8_t)0);
  }
}
示例#6
0
void opcode_loadb(void)
{
  uint8_t *address = z_mem + (uint16_t)(op[0] + (int16_t)op[1]);

  TRACE_LOG("Opcode: LOADB.\n");

  read_z_result_variable();

  if (address > active_z_story->static_memory_end)
  {
    TRACE_LOG("Static memory end: %x.\n", active_z_story->static_memory_end);
    TRACE_LOG("Trying to loadb from %x which is above static memory.\n",
        address);
    set_variable(z_res_var, 0, false);
  }
  else
  {
    TRACE_LOG("Loading from %x to var %x.\n",
        *address,
        z_res_var);
    set_variable(z_res_var, *address, false);
  }
}
示例#7
0
文件: undo.c 项目: dfjdejulio/fizmo
void opcode_save_undo(void)
{
  size_t dynamic_memory_size;
  struct undo_frame *new_undo_frame;
  int result;
  size_t nof_stack_bytes_in_use;

  TRACE_LOG("Opcode: SAVE_UNDO.\n");

  if (max_undo_steps <= 0)
  {
    result = 0;
  }
  else
  {
    if ( (undo_frames == NULL) && (set_max_undo_steps(max_undo_steps) != 0) )
    {
      result = 0;
    }
    else
    {
      if ((new_undo_frame = create_new_undo_frame()) == NULL)
      {
        result = 0;
      }
      else
      {
        dynamic_memory_size = (size_t)(
            active_z_story->dynamic_memory_end - z_mem + 1 );

        if ( (new_undo_frame->dynamic_memory = malloc(dynamic_memory_size))
            == NULL)
        {
          delete_undo_frame(new_undo_frame);
          result = 0;
        }
        else
        {
          nof_stack_bytes_in_use = (z_stack_index - z_stack) * sizeof(uint16_t);

          if ((new_undo_frame->stack
                = (uint16_t*)malloc(nof_stack_bytes_in_use)) == NULL)
          {
            delete_undo_frame(new_undo_frame);
            result = 0;
          }
          else
          {
            if (undo_index == max_undo_steps)
            {
              delete_undo_frame(undo_frames[0]);

              memmove(
                  undo_frames,
                  undo_frames + 1,
                  sizeof(struct undo_frame*) * (max_undo_steps - 1));

              undo_index--;
            }

            memcpy(
                new_undo_frame->stack,
                z_stack, // non-null when size > 0
                nof_stack_bytes_in_use);

            memcpy(
                new_undo_frame->dynamic_memory,
                z_mem,
                dynamic_memory_size);

            // new_undo_frame->pc is not allocated, no free required.
            new_undo_frame->pc = pc;

            new_undo_frame->z_stack_size = z_stack_index - z_stack;
            new_undo_frame->stack_words_from_active_routine
              = stack_words_from_active_routine;
            new_undo_frame->number_of_locals_active
              = number_of_locals_active;
            new_undo_frame->number_of_locals_from_function_call
              = number_of_locals_from_function_call;

            undo_frames[undo_index++] = new_undo_frame;

            result = 1;
          }
        }
      }
    }
  }

  read_z_result_variable();
  set_variable(z_res_var, (uint16_t)result, false);
}
示例#8
0
void opcode_set_font(void)
{
  z_font new_z_font;

  // If the requested font is available, then it is chosen for the
  // current window, and the store value is the font ID of the previous
  // font (which is always positive). If the font is unavailable,
  // nothing will happen and the store value is 0.

  // Please note: I consider the "normal" -- code 1 -- and the courier,
  // fixed font -- code 4 -- to be always available. For simple interfaces,
  // these are probably the same. The availability of the character graphics
  // and picture font are read from interface definition.

  TRACE_LOG("Opcode: SET_FONT\n");
  read_z_result_variable();
  new_z_font = (int16_t)op[0];

  // REVISIT: Implement warning.
  if (
      ( (new_z_font < 0) || (new_z_font > 4) )
      ||
      (
       (new_z_font == Z_FONT_PICTURE)
       &&
       (active_interface->is_picture_font_availiable() != true)
      )
      ||
      (
       (new_z_font == Z_FONT_CHARACTER_GRAPHICS)
       &&
       (active_interface->is_character_graphics_font_availiable() != true)
      )
     )
  {
    set_variable(z_res_var, 0, false);
    return;
  }

  /*
  // REVISIT: Is it correct to not double-set fonts?
  if (new_z_font != current_font)
  {
    if (active_window_number == 0)
    {
#ifndef DISABLE_OUTPUT_HISTORY
      store_metadata_in_history(
          outputhistory[0],
          HISTORY_METADATA_TYPE_FONT,
          new_z_font);
#endif // DISABLE_OUTPUT_HISTORY
    }

    else if (active_window_number == 1)
    {
#ifndef DISABLE_BLOCKBUFFER
      if (ver >= 5)
      {
        set_blockbuf_font(upper_window_buffer, new_z_font);
      }
#endif // DISABLE_BLOCKBUFFER
    }

    active_interface->set_font(new_z_font);
    set_variable(z_res_var, (uint16_t)current_font, false);
    current_font = new_z_font;
    TRACE_LOG("New font is: %d\n", current_font);
  }
  else
  {
    set_variable(z_res_var, (uint16_t)current_font, false);
  }
  */

  current_font = new_z_font;
  set_variable(z_res_var, (uint16_t)current_font, false);
}