ZXTape!
0Created with Ramsoft MakeTZX  stdio.h          s /*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*          HEADER           */
/*                           */
/* Copyright (C) 1984 Hisoft */
/* Last changed  15 Aug 1985 */
/*****************************/

#list-

#define  NULL    0 /* for use with pointers  */
#define  FALSE   0 /* for Boolean operations */
#define  TRUE    1
#define  EOF    -1 /* end of file value      */
#define  ERROR  -1
#define  FAST	static
#define  _SAFETY 50 /* for  sbrk() */
#define  void  int /* for functions which return no value */

#define LD_A_from  0x3A
#define LD_A_into  0x32
#define LD_A_with  0x3E
#define LD_HL_from 0x2A
#define LD_HL_into 0x22
#define LD_HL_with 0x21
#define LD_DE_from 0x5BED
#define LD_DE_into 0x53ED
#define LD_DE_with 0x11
#define LD_BC_from 0x4BED
#define LD_BC_into 0x43ED
#define LD_IX_from 0x2ADD
#define RLA        0x17
#define LD_L_A     0x6F
#define LD_H_with  0x26
#define RL_L       0x15CB
#define LD_B_with  0x06
Z #define JR_Z       0x28
#define JR_NC      0x30
#define JP_HL      0xE9
#define INC_B      0x04
#define PUSH_HL    0xE5
#define PUSH_IX    0xE5DD
#define POP_IX     0xE1DD
#define PUSH_IY    0xE5FD
#define POP_IY     0xE1FD
#define CALL       0xCD
#define DI         0xF3
#define EI         0xFB
#define ADD_HL_DE  0x19


/*  File system Structure */

typedef int  FILE;


/*  Storage Allocation Structure and Variables */

struct  _header
{
  struct _header * _ptr;
  unsigned  _size;
N };

typedef struct _header  HEADER, * HEADER_PTR;

HEADER  _base, *_allocp;



/*  Z80 register cache for inline code  */

unsigned  reg_hl, reg_de, reg_bc;
char      reg_a;


/*  Forward declarations for non-int library functions  */

extern char *strcat(), *strncat(), *strcpy(), *strncpy(), *strchr(), *strrchr(),
            *strpbrk(), *calloc(), *malloc(), *sbrk(),    *fgets(),  *gets();
extern unsigned strlen();


/*  Two variadic arithmetic functions (see manual for details)  */
 
int max(param_byte_count)  auto
{
  static int argc, *argv, max;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  max  = -32767;

  while (argc--)
    {
      if (*argv > max) max = *argv;
      --argv;
    }

  return max;
}


int min(param_byte_count)  auto
{
  static int argc, *argv, min;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  min  = 32767;

  while (argc--)
    {
      if (*argv < min) min = *argv;
      --argv;
    Ȁ}

  return min;
}

#list+

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*        End Header         */
/*****************************/
rgv > max) max = *argv;
      --argv;
    }

  return max;
}


int min(param_byte_count)  auto
{
  static int argc, *argv, min;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  min  = 32767;

  while (argc--)
    {
      if (*argv < min) min = *argv;
      --argv;
      stdio.lib       b /*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*          HEADER           */
/*                           */
/* Copyright (C) 1984 Hisoft */
/* Last changed  15 Aug 1985 */
/*****************************/

#list-

#define  NULL    0 /* for use with pointers  */
#define  FALSE   0 /* for Boolean operations */
#define  TRUE    1
#define  EOF    -1 /* end of file value      */
#define  ERROR  -1
#define  FAST	static
#define  _SAFETY 50 /* for S sbrk() */
#define  void  int /* for functions which return no value */

#define LD_A_from  0x3A
#define LD_A_into  0x32
#define LD_A_with  0x3E
#define LD_HL_from 0x2A
#define LD_HL_into 0x22
#define LD_HL_with 0x21
#define LD_DE_from 0x5BED
#define LD_DE_into 0x53ED
#define LD_DE_with 0x11
#define LD_BC_from 0x4BED
#define LD_BC_into 0x43ED
#define LD_IX_from 0x2ADD
#define RLA        0x17
#define LD_L_A     0x6F
#define LD_H_with  0x26
#define RL_L       0x15CB
#define LD_B_with  0x06
T
 #define JR_Z       0x28
#define JR_NC      0x30
#define JP_HL      0xE9
#define INC_B      0x04
#define PUSH_HL    0xE5
#define PUSH_IX    0xE5DD
#define POP_IX     0xE1DD
#define PUSH_IY    0xE5FD
#define POP_IY     0xE1FD
#define CALL       0xCD
#define DI         0xF3
#define EI         0xFB
#define ADD_HL_DE  0x19


/*  File system Structure */

typedef int  FILE;


/*  Storage Allocation Structure and Variables */

struct  _header
{
  struct _header * _ptr;
  unsigned  _size;
 };

typedef struct _header  HEADER, * HEADER_PTR;

HEADER  _base, *_allocp;



/*  Z80 register cache for inline code  */

unsigned  reg_hl, reg_de, reg_bc;
char      reg_a;


/*  Forward declarations for non-int library functions  */

extern char *strcat(), *strncat(), *strcpy(), *strncpy(), *strchr(), *strrchr(),
            *strpbrk(), *calloc(), *malloc(), *sbrk(),    *fgets(),  *gets();
extern unsigned strlen();


/*  Two variadic arithmetic functions (see manual for details)  */
} 
int max(param_byte_count)  auto
{
  static int argc, *argv, max;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  max  = -32767;

  while (argc--)
    {
      if (*argv > max) max = *argv;
      --argv;
    }

  return max;
}


int min(param_byte_count)  auto
{
  static int argc, *argv, min;

  argc = param_byte_count/2 - 1;
  argv = &param_byte_count  + argc;
  min  = 32767;

  while (argc--)
    {
      if (*argv < min) min = *argv;
      --argv;
     }

  return min;
}

#list+

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*        End Header         */
/*****************************/

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */
/*       version 1.3         */
/* Copyright (C) 1985 Hisoft */
/* Last changed  31 Oct 1985 */
/*****************************/

#list-

/* Some arithmetic functions */

/*
  min and max are in "stdio. h"
  because they are variadic
*/

int abs(n)
{
  return  n<0  ?  -n  :  n  ;
}


int sign(n)
{
  return  n  ?
    ( n<0 ? -1 : 1 ) : 0 ;
}



/*  An illustration of how to grub around in the store */


typedef  char * __char_ptr;


int peek(address)
{
  return  * cast(__char_ptr) address;
}


void poke(address, value)
{
  * cast(__char_ptr) address = value;
}


/*  Input and Output  */


int out(data, port)
{
  reg_bc = port;  reg_hl = data;
  inline(
    0x4BED, E &reg_bc, /* ld bc,(reg_bc) */
    0x2A,   &reg_hl, /* ld hl,(reg_hl) */
    0x69ED);         /* out (c),l      */
}


int inp(port)
{
  inline(
    0xE1DD,     /* pop  ix    */
    0xE1,       /* pop  hl    */
    0xC1,       /* pop  bc    */
    0xE5,       /* push hl    */
    0x68ED,     /* in   l,(c) */
    0x26,   0,  /* ld   h,0   */
    0xC9);      /* ret        */
}



/*  Format conversion routine  -  ASCII to binary integer  */

int atoi(s)
  char *s;
{
  static int c, val2 ue, sign;

  while (isspace(*s)) ++s;
  value = 0;
  sign  = 1;
  if      (*s == '-') { ++s; sign = -1; }
  else if (*s == '+')   ++s;
  while (isdigit(c = *s++)) value = 10 * value + c - '0';
  return  sign * value;
}




/*  Sorting function - a Shell sort  */

void qsort(list, num_items, size, cmp_func)
  char *list;
  int   num_items, size;
  int (*cmp_func)();
{
  static unsigned gap, byte_gap, i;
  static char *p;

  for (gap = num_items >> 1;  gap > 0;  gap >>= 1)
    {
    
   byte_gap = gap * size;
      for (i = gap;  i < num_items;  ++i)
        for (p = list + i * size - byte_gap;  p >= list;  p -= byte_gap)
          {
            if ((*cmp_func)(p, p + byte_gap) <= 0) break;
            swap(p, p + byte_gap, size);
          }
    }
}




/*  String Handling Functions  */


char *strcat(base, add)
  char *base, *add;
{
  static char *dest;

  dest = base;
  while (*dest) ++dest;
  while (*dest++ = *add++);
  return  base;
}


char *strncat(s1, S s2, n)
  char *s1, *s2;
{
  static char *s;

  s = s1;
  while (*s) ++s;
  while (n--  &&  *s2) *s++ = *s2++;
  *s = NULL;
  return s1;
}


int strcmp(s, t)
  char *s, *t;
{
  while (*s == *t)
    {
      if (! *s)  return 0;
      ++s; ++t;
    }
  return *s - *t;
}


int strncmp(s1, s2, n)
  char *s1, *s2;
{
  if (!n) return 0;
  while (*s1 == *s2)
    {
      if ( ! *s1) return 0;
      if ( ! --n) break;
      ++s1;  ++s2;
    }
  return *s1 - *s2;
}



char *strc= py(dest, source)
  char *dest, *source;
{
  static char *result;

  result = dest;
  while (*result++ = *source++) ;
  return dest;
}


char *strncpy(s1, s2, n)
  char *s1, *s2;
{
  static char *s, c;

  s = s1;
  c = *s2;
  while (n)
    {
      *s++ = ( c  ?  ( c = *s2++ )  :  0 ) ;
      --n;
    }
  return s1;
}



unsigned strlen(s)
  char *s;
{
  static char *p;

  p = s;
  do ; while (*p++);
  return p-s-1;
}



char *strpbrk(s1, s2)
  char *s1, *s2;
{
  whi le (*s1)
    {
      if (strchr(s2, *s1)) return s1;
      ++s1;
    }
  return NULL;
}


int strspn(s1, s2)
  char *s1, *s2;
{
  char *s;

  s = s1;
  while (*s)
    {
      if ( ! strchr(s2, *s)) break;
      ++s;
    }
  return s - s1;
}


int strcspn(s1, s2)
  char *s1, *s2;
{
  char *s;

  s = s1;
  while (*s)
    {
      if (strchr(s2, *s)) break;
      ++s;
    }
  return s - s1;
}



char *strchr(s, c)
  char *s, c;
{
  do
    {
      if (*s == c) return J s;
      if ( ! *s)   return NULL;
      ++s;
    }
  while (TRUE);
}


char *strrchr(s, c)
  char *s, c;
{
  static char *t;

  t = s;
  s = NULL;
  do    if (*t == c) s = t;
  while (*t++);
  return s;
}

 


/*  Character Test and Manipulate Functions  */

/*  NB - the common ones are built-in for efficiency  */

int ispunct(c)
  char c;
{
  return  isprint(c) & ! isalnum(c);
}


int isalnum(c)
  char c;
{
  return  isalpha(c) | isdigit(c) ;
}


int isxdigit(c)
 ^  char c;
{
  c = toupper(c);
  return  isdigit(c) | (c >= 'A'  &  c <= 'F');
}


int isascii(c)
  char c;
{
  return  c < 0x80 ;
}


int iscntrl(c)
  char c;
{
  return  c < ' ' | c == '\177' ;
}


int isprint(c)
  char c;
{
  return  c >= ' '  &  c < '\177' ;
}


int isgraph(c)
  char c;
{
  return  c > ' '  &  c < '\177' ;
}


int toascii(c)
  char c;
{
  return  c & 0x7F;
}



/******      FILE SYSTEM      ******/


char *fgets(s, n, fp)
  char *s;
  int    n;
  FILE *fp;
{
  static int c;
  static char *cs;

  cs = s;
  while (--n > 0  &&  (c = getc(fp)) != EOF)
    if ((*cs++ = c) == '\n') break;
  *cs = '\0';
  return ((c == EOF  &&  cs == s) ? NULL : s);
}



char *gets(s)
  char *s;
{
  static int   c;
  static char *cs;

  cs = s;
  while ((c = getchar())
    !=EOF  &&  c!='\n')
      *cs++ = c;
  *cs = 0;
  return
   ((c==-1 && cs==s) ?
    NULL : s );
}



void fputs(s, fp)
  char *s;
  FILE *fp;
{
  static int c;
 
  while (c = *s++) putc(c, fp);
}



void puts(s)
  char *s;
{
 static int c;

 while(c = *s++)putchar(c);
 putchar('\n');
}


/*  Storage Allocation and Freeing (Heap Management)  */


char *calloc(n, size)
  unsigned   n, size;
{
  FAST char *ptr;
  FAST char length;

  ptr = malloc(length = n * size);
  if ( ! ptr) return NULL;
  *ptr = 0;			/* now zero fill the store */
  move(ptr+1, ptr, length-1);
  return ptr;
}


char *malloc(num_bytes)
{
  static HEADER  *p, *q;] 
  static unsigned  nbytes;
  char *sbrk();

  if ( ! num_bytes) return NULL;
  nbytes = (num_bytes + (sizeof(HEADER) - 1)) / sizeof(HEADER) + 1;
  if ((q = _allocp) == NULL)  /* no free list */
    {
      _base._ptr  = _allocp = q = &_base;
      _base._size = 0;
    }
  p = q->_ptr;
  while (TRUE)
    {
      if (p->_size >= nbytes)  /* big enough */
        {
          if (p->_size == nbytes)  q->_ptr = p->_ptr;  /* just right size */
          else
            {                        Z   /* split block and allocate tail */
              p->_size -= nbytes;
              p        += p->_size;
              p->_size  = nbytes;
            }
          _allocp = q;
          return cast(__char_ptr) (p+1);
        }
      if (p == _allocp)  /* wrapped around free list */
        {
          if ((p = cast(HEADER_PTR) sbrk(nbytes * sizeof(HEADER))) == ERROR)
            return NULL;
          p->_size = nbytes;
          free(p+1);
          p = _allocp;
        }
      q = p;
       p = p->_ptr;
    }  /* end while TRUE */
}



void free(block)
  char *block;
{
  static HEADER *p, *q;

  p = cast(HEADER_PTR) block - 1;
  for (q = _allocp; !(p > q  &&  p < q->_ptr); q = q->_ptr)
    if (q >= q->_ptr  &&  (p > q  ||  p < q->_ptr))  break;

  if (p + p->_size  ==  q->_ptr)
    {
      p->_size += q->_ptr->_size;
      p->_ptr   = q->_ptr->_ptr;
    }
  else  p->_ptr = q->_ptr;

  if (q + q->_size  ==  p)
    {
      q->_size += p->_size;
      q->_ptr   = p-> _ptr;
    }
  else  q->_ptr = p;

  _allocp = q;
}


#define HEAPSIZE 1000

char *sbrk(n)
  unsigned n;
{
  static char *p,
    heap[HEAPSIZE],
    *heap_ptr=heap;

  if (heap_ptr+n > heap+HEAPSIZE) return ERROR;
  p=heap_ptr;
  heap_ptr += n;
  return p;
}



/*  Pseudo-Random Number Generator  */
/*
    Adapted from "Learning to Program in C" by Thomas Plum.
*/


char  _rnum[4];


void srand(n)
{
  long_init(_rnum, 0,n);
}


int rand()
{
  static char k[4];

  l| ong_init(k,  0x41c6,0x4e6d);
  long_multiply(_rnum, _rnum, k);
  long_init(k,       0,0x3039);
  long_add(_rnum, _rnum, k);
  return  ((_rnum[3] << 8)  +  _rnum[2]) & 0x7FFF;
}




/*  Some Functions for 32 bit integer arithmetic  */

void long_multiply(c, a, b)
  char *a, *b, *c;
{
  static char x[4], product[4];
  static int i, j;

  long_set(product, 0,0);
  for (i = 0; i < 4; ++i)
    for (j = i; j >= 0; --j)
      {
        long_set(x, a[i-j] * b[j], i);
        long_add(product,s  product, x);
      }
  long_copy(c, product);
}



void long_add(c, a, b)
  char *a, *b, *c;
{
  static unsigned u, i;

  u = 0;
  for (i = 0; i < 4; ++i)
    {
      u   +=  *a++  +  *b++;
      *c++ =  u & 0xff;
      u  >>=  8;
    }
}



void long_init(a, n1, n0)
  char *a;
  unsigned n1,n0;
{
  a[0] = n0 & 0xff;
  a[1] = n0 >> 8;
  a[2] = n1 & 0xff;
  a[3] = n1 >> 8;
}



void long_set(a, n, d)
  char *a;
  unsigned n, d;
{
  static int i;

  for (i=0; i<4; ++i2 ) a[i] = 0;
  a[d] = n & 0xff;
  if (d < 3) a[d+1] = n >> 8;
}



void long_copy(c, a)
  char *a, *c;
{
  move(c, a, 4);
}



/***  System Interface  ***/


exit(n)
{
 inline(0xcd,25236);
 _exit(n);
}




_exit(n)
{
  inline(0xe1,0xe1,0xe1,
   0x2b,0xc3,0x55,0);
}



/* Spectrum Graphics and
   Sound Functions      */


plot(on,x,y)
{
 _setover(on);
 inline(0xdd,0x46,4,
        0xdd,0x4e,6,
        0xcd,0x22e5);
}


line(on,dx,dy)
{
 static sx,sy,de,bc;

 
 _setover(on);
 sx=sy=1;
 if (dx<0)
  {
   dx= -dx;
   sx= 0xFF;
  }
 if (dy<0)
  {
   dy= -dy;
   sy= 0xFF;
  }
 de=	(sy<<8)+sx;
 bc=(dy<<8)+dx;
 inline(0xed,0x5b,&de,
        0xed,0x4b,&bc,
        0xcd,0x24ba);
}


beep(duration,pitch)
 unsigned duration,pitch;
{
 static ft;

 if ( ! pitch)
  for(ft=0;ft<duration;++ft)
   for(pitch=4630;++pitch;);
 else {
 ft=duration*pitch/10;
 pitch=pitch/10;
 _beep(ft,cast(unsigned)43750/pitch-30);
 }
}


paper(i)
{
 return _colour7 (17,i);
}


ink(i)
{
 return _colour(16,i);
}


cls()
{
  inline(0xCD,0xD6B);
}


_setover(on)
{
 printf("\025%c",on?0:1);
}


_beep(DE,HL)
{
 static de,hl;

 de=DE;
 hl=HL;
 inline(0xdd,0xe5,
        0xed,0x5b,&de,
        0x2a,&hl,
        0xcd,0x3b5,
        0xdd,0xe1);
}


_colour(h,i)
{
 if (i<0 | i>7) return -1;
 putc(h,2);
 putc(i,2);
 return i;
}


#list+

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */C
/*           End             */
/*****************************/

  inline(0xCD,0xD6B);
}


_setover(on)
{
 printf("\025%c",on?0:1);
}


_beep(DE,HL)
{
 static de,hl;

 de=DE;
 hl=HL;
 inline(0xdd,0xe5,
        0xed,0x5b,&de,
        0x2a,&hl,
        0xcd,0x3b5,
        0xdd,0xe1);
}


_colour(h,i)
{
 if (i<0 | i>7) return -1;
 putc(h,2);
 putc(i,2);
 return i;
}


#list+

/*****************************/
/*         Hisoft C          */
/* Standard Function Library */