
/*	C I/O functions	*/

#include <stdio.h>
#ifndef M6502
/* every time I thing some C weenie someplace might have opted to do
   something in a regular fashion, I get disappointed... */
#include <errno.h>
#endif
#include "cc65.h"
#include "cclex.h"

#ifndef M6502
int outcnt = 0;
#endif

/* not used?
char	ascii_tab[128] =
    {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
    };
*/

/*
  alpha( c )
  Test if given character is alpha.
*/
/* not used...
alpha(c)
int	c;
{
    return( ascii_tab[c] & 1 );
}
*/

/*
  numeric( c )
  Test if given character is numeric
*/
/* not used
numeric(c)
int	c;
{
    return( ascii_tab[c] & 2 );
}
*/

/*
  an( c )
  Test if given character is alphanumeric
*/
/* not used
an(c)
int	c;
{
    return( ascii_tab[c] );
}
*/

/*
  pl( str )
  Print a string followed by a carriage return.
*/
/* not used?
pl(str)
char * str;
{
    printf("%s\n", str);
}
*/

/* apparently, all callers of this have been redefined
   with defines....
ch()
{
#ifdef M6502
    return( *lptr );
#else
    return( *lptr & 0xFF );
#endif
}
*/

#ifdef M6502
#asm
	.globl	_nch
_nch:
	ldx	#0
	ldy	#0
	lda	(_lptr),y
	beq	nch1
	iny
	lda	(_lptr),y
nch1:
	rts
#endasm
#else
nch()
{
  if (*lptr == '\0')
    {
      return (0);
    }
  else
    {
#ifdef M6502
      return (lptr[1]);
#else
      return (lptr[1] & 0xFF);
#endif
    }
}

#endif

/*
  cgch()
  Get the current character in the input stream and advance line
  pointer (unless already at end of line).
*/
#ifdef M6502
#asm
	.globl	_cgch
_cgch:
	ldx	#0
	ldy	#0
	lda	(_lptr),y
	bne	cgch1
	rts
cgch1:
	inc	_lptr
	bne	cgch2
	inc	_lptr+1
cgch2:
	cmp	#0		; return cond codes
	rts
#endasm
#else
cgch()
{
  if (*lptr == '\0')
    {
      return (0);
    }
  else
    {
#ifdef M6502
      return (*lptr++);
#else
      return (*lptr++ & 0xFF);
#endif
    }
}

#endif

/*
  gch()
  Get the current character in the input stream and advance line
  pointer (no end of line check is performed).
*/
#ifdef M6502
#asm
	.globl	_gch
_gch:
	ldx	#0
	lda	(_lptr,x)
	inc	_lptr
	bne	gch1
	inc	_lptr+1
gch1:
	cmp	#0		; return cond codes
	rts
#endasm
#else
gch()
{
#ifdef M6502
  return (*lptr++);
#else
  return (*lptr++ & 0xFF);
#endif
}

#endif

#ifdef M6502
#asm
	.globl	_do_kill
_do_kill:
	lda	_line
	sta	_lptr
	lda	_line+1
	sta	_lptr+1
	ldx	#0
	txa
	sta	(_lptr,x)
	rts
#endasm
#else
do_kill()
{
  lptr = line;
  *lptr = '\0';
}

#endif

/*
  readline()
  Get a line from the current input.  Returns -1 on end of file.
*/
readline()
{
int k;
int len;
struct filent * pftab;

  while (1)
    {
      do_kill();
      if (inp == 0)
	{
	  eof = 1;
	  return (0);
	}
#ifdef old_cruft
      k = ciov(inp, 5, line, linesize, -1, -1);
      poke(CRITIC, critic);
      len = dpeek(0x348 + (inp << 4));
#else
      k = (int) fgets(line, linesize, inp);
      len = strlen(line);
#endif
      ++ln;
      if (k <= 0) /* eof? */
	{
	  line[len] = '\0';
	  cclose(inp);
/*	    fclose(inp);	*/

	  if (ifile > 0)
	    {
	      inp = (pftab = &filetab[--ifile])->f_iocb;
	      ln = pftab->f_ln;
	      fin = pftab->f_name;
	    }
	  else
	    {
	      inp = 0;
	    }
	}
      else
	{
	  line[len - 1] = '\0';
#ifndef M6502
	  if (source && (strlen(line) > 0))
	    {
/*		flushout();		this is broken... */
/*
		cout(';');
		sout(line);
		cout('\n');
*/
	      ot(";");
	      ol(line);
	    }
#endif
	}
      if (len)
	{
	  lptr = line;
	  return (1);
	}
    }
}

/*
  flushout()
  Flush output queue
*/
flushout()
{
  *outqi = '\0';
  peephole(outq);
  outqi = outq;
}

/*
  Output char c to assembler file.  Really just goes out to
  buffer, so the optimizer can work on it.
*/
#ifdef M6502
#asm
	.globl	_outchar
_outchar:
	jsr	popax
	ldy	#0
	sta	(_outqi),y
	inc	_outqi
	bne	*+4
	inc	_outqi+1
	rts
#endasm
#else
outchar(c)
char c;
{
#ifndef M6502
  ++outcnt;
#endif
  *outqi++ = c;
}

#endif

#ifdef old_cruft
/*
  rmvbyte( n )
  Remove n bytes from output stream.
*/
rmvbyte(n)
int n;
{
  outqi -= n;
}

#endif

/* out char to real output file */
cout(ch)
char ch;
{
  errno = 0;
  fputc(ch, output);
  if (errno != 0)
    {
      printmsg("IO error #x%x\n", errno);
#ifdef M6502
      closeall();
#endif
      exit(1);
    }
}

/* out string to real output file */
#ifdef M6502
#asm
	.globl	_sout
_sout:
	jsr	popax
	sta	ptr4
	stx	ptr4+1
sout1:
	ldy	#0
	lda	(ptr4),y
	beq	sout2
	ldx	#0
	jsr	pushax
	ldy	#1
	jsr	_cout
	inc	ptr4
	bne	sout1
	inc	ptr4+1
	jmp	sout1
sout2:
	rts
#endasm
#else
sout(s)
char * s;
{
  while (*s)
    cout(*s++);
}

#endif
