/*->c.serialdev */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.bbc"
#include "h.flex"
#include "h.swis"

#include "h.Drawlevel0"

#include "h.wos"
#include "h.strdef"

#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.pr"
#include "h.fsx"
#include "h.dir"

#include "h.xext"
#include "h.script"
#include "h.serial"
#include "h.trans"

#include "h.serialdev"


/***************************************************************************/

extern int serialdevcalllo(int fn,int r1,int r2,int r3);

static int   deviceactive;
static char  devicename[16];
       int   deviceport;
       int * deviceblock;
static int   deviceflags;


#define DEVNEEDSPOLL 0x10


static os_error * loadblock(char * name)
{
 os_error * err;
 char       string[128];
 fstat      fs;

 if(!getenv("SerialDev$Path")) fatalerror("{SDEV00}");

 sprintf(string,"SerialDev:Modules.%s.Driver",name);

 err=stat(string,&fs);
 if(err) report(err);
 else
 if(!fs.object || !fs.length) errorbox("{SDEV01}");
 else
 {
  if(deviceblock)
  {
   free(deviceblock);
   remzeroevent(SDEVZERO);
  }

  deviceblock=malloc(fs.length);
  if(!deviceblock) 
    fatalerror("{SDEV02}");

  err=fs_loadblock(string,deviceblock);
  if(!err)
  {
   deviceflags=deviceblock[0xC4/sizeof(int)];
   if(deviceflags & DEVNEEDSPOLL) addzeroevent(SDEVZERO);
  }
  else report(err);
 }
 return(err);
}


/* set device name and port            */
/* setserialdev(string & name,int port */

void setserialdev(int fp)
{
 strcpy(devicename,stringptr(stack[fp]));
 deviceport=stack[fp+1];
 if(deviceactive) loadblock(devicename);
}


void sdevzero(void)
{
 xexec("device_poll",NULL,&deviceport,NULL);
}


/* serialdevinit(int active) */

void serialdevinit(int fp)
{
 deviceactive=stack[fp];
}

/* int serialdevcall(int fn,int r1,int r2,int r3) */
/* return r0 */

int serialdevcall(int fp)
{
 if(deviceblock)
      return(serialdevcalllo(stack[fp],stack[fp+1],stack[fp+2],stack[fp+3]));
 else return(0);
}


int serialdevread(int fp)
{
 int index;
 index=stack[fp];
 if(deviceblock) return(deviceblock[index/sizeof(int)]);
 else            return(0);
}


int serialdevget(int port)
{
 if(deviceblock) return(serialdevcalllo(1,port,0,0));
 else            return(-1);
}


int serialdevput(int byte,int port)
{
 if(deviceblock) return(serialdevcalllo(0,port,byte,0));
 else            return(byte);
}



int sdevblockread(int port,char * data,int n)
{
 if(deviceblock) return(serialdevcalllo(3,port,(int)data,n));
 else            return(0);
}


int sdevblockwrite(int port,char * data,int n)
{
 if(deviceblock) return(serialdevcalllo(2,port,(int)data,n));
 else            return(0);
}


