Exemplo n.º 1
0
void iffputchunk(strid_t stream, const char *type, glui32 ulength)
{
  glui32 c;
  unsigned char length[4];

  c = glk_stream_get_position(stream);
  if(c & 1)
    glk_put_char_stream(stream, 0);  /* Spew padding */

  MSBencode4(length, ulength);

  w_glk_put_buffer_stream(stream, type, 4);
  w_glk_put_buffer_stream(stream, (char *) length, 4);
}
Exemplo n.º 2
0
glui32 emptystruct(strid_t stream, const unsigned *info, const glui32 *src)
{
  unsigned char buffer[4];
  unsigned e;
  glui32 len = 0;;

  for(e = 0; info[e]; e++) {
    if(info[e] > 4) {
      unsigned i;
      for(i = 0; i < info[e]; i++) {
	glk_put_char_stream(stream, *src++);
	len++;
      }
    } else {
      switch(info[e]) {
      case 1: MSBencode1(buffer, *src); break;
      case 2: MSBencode2(buffer, *src); break;
      case 3: MSBencode3(buffer, *src); break;
      case 4: MSBencode4(buffer, *src); break;
      }

      w_glk_put_buffer_stream(stream, (char *) buffer, info[e]);
      
      src++;
      len++;
    }
  }
  return len;
}
Exemplo n.º 3
0
void op_save5(void)
{
  unsigned i;
  char filename[256];
  unsigned length;
  strid_t file = NULL;
  offset end;
  switch(numoperands) {
  case 0:
    op_save4();
    return;
  case 1: 
    n_show_error(E_INSTR, "call save with bad number of operands", numoperands);
    mop_store_result(0);
    return;
  case 2:
    file = n_file_prompt(fileusage_Data | fileusage_BinaryMode,
			 filemode_Write);
    break;
  default:
    length = LOBYTE(operand[2]);
    if(length > 13)
      n_show_port(E_INSTR, "save with filename > 13 characters", length);
    for(i = 0; i < length; i++)
      filename[i] = glk_char_to_upper(LOBYTE(operand[2] + 1 + i));
    filename[length] = 0;
    file = n_file_name(fileusage_Data | fileusage_BinaryMode,
		       filemode_Write, filename);
    break;
  }
  if(!file) {
    mop_store_result(0);
    return;
  }
  end = ((offset) operand[0]) + operand[1];
  if(end > 65535 || end > total_size) {
    n_show_error(E_MEMORY, "attempt to save data out of range", end);
    mop_store_result(0);
    return;
  }

  w_glk_put_buffer_stream(file, (char *) z_memory + operand[0], operand[1]);
  glk_stream_close(file, NULL);

  mop_store_result(1);
}
Exemplo n.º 4
0
BOOL quetzal_stack_save(strid_t stream)
{
  unsigned frame_num = 0;

  if(zversion == 6)
    frame_num++;

  if(!verify_stack()) {
    n_show_error(E_SAVE, "stack did not pass verification before saving", 0);
    return FALSE;
  }

  /* We have to look one ahead to see how much stack space a frame uses; when
     we get to the last frame, there will be no next frame, so this won't work
     if there wasn't a frame there earlier with the correct info.  Add and
     remove a frame to make things happy */
  add_stack_frame(0, 0, NULL, 0, 0);
  remove_stack_frame();

  for(; frame_num <= frame_count; frame_num++) {
    unsigned n;
    int num_locals;
    unsigned stack_size;

    glui32 qframe[5];

    const unsigned char argarray[8] = {
      b00000000, b00000001, b00000011, b00000111,
      b00001111, b00011111, b00111111, b01111111
    };

    qframe[qreturnPC] = stack_frames[frame_num].return_PC;

    qframe[qvar]      = stack_frames[frame_num].result_variable;

    num_locals        = stack_frames[frame_num].num_locals;

    if(num_locals > 15) {
      n_show_error(E_SAVE, "num_locals too big", num_locals);
      return FALSE;
    }

    qframe[qflags] = num_locals;

    if(stack_frames[frame_num].result_variable == -1) {
      qframe[qflags] |= b00010000;
      qframe[qvar] = 0;
    }

    if(stack_frames[frame_num].arguments > 7) {
      n_show_error(E_SAVE, "too many function arguments", stack_frames[frame_num].arguments);
      return FALSE;
    }
    
    qframe[qargs] = argarray[stack_frames[frame_num].arguments];

    stack_size = (stack_frames[frame_num+1].stack_stack_start -
		  stack_frames[frame_num].stack_stack_start -
		  num_locals);

    qframe[qeval] = stack_size;
	             
    if(frame_num == 0) {
      qframe[qreturnPC] = 0;
      qframe[qflags] = 0;
      qframe[qvar] = 0;
      qframe[qargs] = 0;
    }

    emptystruct(stream, qstackframe, qframe);
    
    for(n = 0; n < num_locals + stack_size; n++) {
      unsigned char v[ZWORD_SIZE];
      zword z = stack_stack[stack_frames[frame_num].stack_stack_start + n];
      MSBencodeZ(v, z);
      w_glk_put_buffer_stream(stream, (char *) v, ZWORD_SIZE);
    }
  }
  return TRUE;
}