/**************************************************************************/
/*		       lowsrc.c:					  */
/*------------------------------------------------------------------------*/
/*         SH-series simulator debugger interface routine		  */
/*   - Only standard I/O files (stdin, stdout, stderr) are supported      */
/**************************************************************************/
#include <string.h>

/* file number */

#define STDIN  0                       /* Standard input (console)        */
#define STDOUT 1                       /* Standard output (console)       */
#define STDERR 2                       /* Standard error output (console) */

#define FLMIN  0                       /* Minimum file number             */
#define FLMAX  3                       /* Maximum number of files         */

/* file flag */

#define O_RDONLY 0x0001                /* Read only                       */
#define O_WRONLY 0x0002                /* Write only                      */
#define O_RDWR   0x0004                /* Both read and write             */

/* special character code */

#define CR 0x0d                        /* Carriage return                 */
#define LF 0x0a                        /* Line feed                       */

/* size of area managed by sbrk */

#define HEAPSIZE 1024

/**************************************************************************/
/* Declaration of reference function                                      */
/* Reference of assembly program in which the simulator debugger input or */
/* output characters to the console					  */
/**************************************************************************/
extern void charput(char);              /* One character input            */
extern char charget(void);              /* One character oputput          */

/**************************************************************************/
/* Definition of static variable:					  */
/* Definition of static variables used in low-level interface routines    */
/**************************************************************************/

char flmod[FLMAX];                   /* Open file mode specification area */

static  union  {
		long  dummy ;       /* Dummy for 4-byte boundary          */
		char heap[HEAPSIZE]; /* Declaration of the area managed   */
                                     /*                           by sbrk */
 }heap_area ;

static  char  *brk=(char *)&heap_area;/* End address of area assigned     */
                                     /*                           by sbrk */
/**************************************************************************/
/*       open:file open							  */
/*          Return value:File number (Pass)				  */
/*                       -1          (Failure)				  */
/**************************************************************************/
int open(char *name,                    /* File name			  */
     int mode)				/* File mode			  */
{
    /* Check mode depending on file name and return file numbers          */

     if(strcmp(name,"stdin")==0){       /* Standard input file	 	  */
            if((mode&O_RDONLY)==0)
                     return -1;
	    flmod[STDIN]=mode;
	    return STDIN;
     }

     else if (strcmp(name,"stdout")==0){ /* Standard output file          */
            if((mode&O_WRONLY)==0)
                     return -1;
	    flmod[STDOUT]=mode;
	    return STDOUT;
     }

     else if (strcmp(name,"stderr")==0){ /* Standard error file           */
            if((mode&O_WRONLY)==0)
                     return -1;
	    flmod[STDERR]=mode;
	    return STDERR;
     }

     else
            return -1;                   /* Error			  */
}

/**************************************************************************/
/*   close:File close							  */
/*	   Return value:0 (pass)					  */
/*	                -1 (Failure)					  */
/**************************************************************************/
int close(int fileno)                      /* File number		  */
{
      if(fileno<FLMIN || FLMAX<fileno)     /* File number range check     */
           return -1;

      flmod[fileno]=0;			   /* File mode reset		  */
      return 0;
}

/**************************************************************************/
/* read:Data read     		 					  */
/*	Return value:Number of read characters (Pass)			  */
/*	             -1                        (Failure)		  */
/**************************************************************************/
int read(int  fileno,                      /* File number		  */
        char *buf,                         /* Destination buffer address  */
        unsigned int  count)               /* Number of read characters   */
{
      unsigned int i;

   /*Check mode according to file name and stores each character in buffer*/

      if(flmod[fileno]&O_RDONLY||flmod[fileno]&O_RDWR){
	    for(i=count; i>0; --i){
		  *buf=charget();
		  if(*buf==CR)           /*Line feed character replacement*/
			*buf=LF;
		  buf++;
	    }
	    return count;
       }
       else
            return -1;
}

/**************************************************************************/
/* write:Data write   		 					  */
/*	Return value:Number of write characters (Pass)			  */
/*	             -1                         (Failure)		  */
/**************************************************************************/
int write(int  fileno,                     /* File number		  */
        char *buf,                         /* Destination buffer address  */
        unsigned int  count)               /* Number of write characters  */
{
       unsigned int i;
       char c;

       /* Check mode according to file name and output each character     */

       if(flmod[fileno]&O_WRONLY || flmod[fileno]&O_RDWR){
       	    for(i=count; i>0; --i){
		  c=*buf++;
		  charput(c);
	    }
            return count;
       }
       else
            return -1;
}

/**************************************************************************/
/* lseek:Definition of file read/write position				  */
/*	Return value:Offset from the top of file read/whrte position(Pass)*/
/*	             -1              (Failure)				  */
/*	(lseek is not supported in the console input/output)		  */
/**************************************************************************/
long lseek(int  fileno,                    /* File number		  */
	   long offset,			   /* Read/write position	  */
	   int  base)			   /* Origin of offset		  */
{
     return -1;
}
/**************************************************************************/
/*     sbrk:Data write							  */
/*	    Return value:Start address of the assigned area (Pass)	  */
/*	                 -1				    (Failure)	  */
/**************************************************************************/
char  *sbrk(unsigned long size)		   /* Assigned area size	  */
{
      char  *p;

      if(brk+size>heap_area.heap+HEAPSIZE) /* Empty area size		  */
	   return (char *)-1 ;

      p=brk ;				   /* Area assignment		  */
      brk += size ;			   /* End address update	  */
      return p ;
}
