/*
  Support
*/

#include "support.h"

#include "addr.h"
#include "console.h"
#include "head.h"
#include "input.h"
#include "interp.h"
#include "jump.h"
#include "message.h"
#include "page.h"
#include "pc.h"
#include "print.h"
#include "mem.h"
#include "shared.h"
#include "stack.h"
#include "stop.h"
#include "wio.h"

void restart(void)
{
  int i;
  new_line();
  for(i = 0; i < hd_save_blocks(); ++i)
    hd_load(i, 1, pg_fetch(i));
  hd_init();
  init_interpreter(1);
}

#define HEADER_SIZE 64

void verify(void)
{
  word sum    = 0;
  long_word finish = ad_code_addr(hd_verify());
  long_word addr   = HEADER_SIZE;
  while(addr != finish)
  {
    byte pg[BLOCK_SIZE];
    word off = pg_offset(addr);
    hd_load(pg_page(addr), 1, pg);
    while(addr != finish && off != BLOCK_SIZE)
    {
      sum += pg[off];
      ++off;
      ++addr;
    }
  }
  ret_value(sum == hd_check());
}

void ncrypt(word param1, word param2, word param3, word param4)
{
  int i;
  word coded[PLUS_ENCODED_SIZE];
  long_word src = param1 + (long_word) param3;
  long_word dst = param4;
  (void) get_code(&src, PLUS_CHARS_PER_WORD, coded);

  for(i = 0; i < PLUS_ENCODED_SIZE; i++)
  {
    wr_word_addr(dst, coded[i]);
    dst += 2;
  }
  USE(param2);
}

void block_copy(word src_offset, word dst_offset, signed_word num_words)
{
  if(src_offset != dst_offset && num_words != 0)
  {
    bool negative = num_words < 0;
    if(negative)
      num_words = -num_words;
    if(dst_offset == 0)
    {
      while(num_words--)
        wr_byte_addr(src_offset++, 0);
    }
#if 0
    /*
       The extra guards mean copy upwards if no overlap, but that
       is not needed ... they should be the same speed
    */
    else if(negative
         || src_offset > dst_offset
         || (word) ((signed_word) src_offset + num_words) < dst_offset)
#else
    else if(negative)
#endif
    {
      while(num_words--)
        wr_byte_addr(dst_offset++, rd_byte_addr(src_offset++));
    }
    else
    {
      dst_offset += num_words;
      src_offset += num_words;
      while(num_words--)
        wr_byte_addr(--dst_offset, rd_byte_addr(--src_offset));
    }
  }
}

void print_text(void)
{
  extern word param_stack[];

  int align = con.cursor.align;
  int cursor_x, cursor_y;
  int num_params  = param_stack[0];
  word address    = param_stack[1];
  word line_width = param_stack[2];
  word num_lines  = num_params < 3 ? 1 : param_stack[3];
  start_update();
  get_xy(&cursor_x, &cursor_y);
  /* save_attributes(2); */
  if(line_width > 0)
    while(num_lines--)
    {
      int count = line_width;
      goto_xy(cursor_x, cursor_y++);
      while(count--)
        print_char((word) rd_byte_addr(address++));
    }
  /* restore_attributes(2); */
  con.cursor.align = align;
  finish_update();
}

