/* -> c.ckamis
 */

#include "ckcdeb.h"

#ifdef ANSI
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "ckatio.h"
#include "ckafio.h"
#include <assert.h>
#include "ckamis.h"
#include "ckuusr.h"
#endif

#ifdef ARTHUR
#include <arthur.h>
#include "plib.h"
#include "tty.h"
#endif

#ifdef PANOS
#include "time.h"
#endif

extern char *CWDCMD;
extern int RawFrig;

static reg_set rs;
static error *ret_val;

void
gettimeofday(time_now, time_zone)
timeval *time_now;
int *time_zone;
{
      XBinaryTime(time_now);
      *time_zone = 0;
}

unsigned int timerdiff(ts, tf)
timeval ts, tf;
{
/*
 * Returns difference(in centi-seconds) between 2 time
 * stamp records.  NB uses simplified double-precision
 * algorithm: ts is start time; tf is finishing time,
 * assumed greater than ts.
 */
#ifdef ANSI
#define MAX_U_INT UINT_MAX
#else
#define MAX_U_INT (unsigned int) 0xFFFFFFFF
#endif
  unsigned int diff;

#ifdef ANSI  
  if( (tf.high = ts.high) != 0 )
#else
  if(tf.high = ts.high)
#endif
    diff =(tf.low - ts.low);  /* in centi-seconds */
  else if((tf.high > ts.high + 1) || (tf.low > ts.low))
    diff = MAX_U_INT; /* vast difference */
  else
    diff =(tf.low +(MAX_U_INT - ts.low) + 1);
  return diff;
}

static timeval epoch;

void
rtimer()
{ int timezone;
  gettimeofday(&epoch, &timezone);
}

unsigned int
gtimer()
{ timeval now; int timezone;
  gettimeofday(&now, &timezone);
  return (timerdiff(now, epoch) / 100);
}

void
sleep(secs) int secs; {
  msleep(secs * 1000);
}

void
eraseleft() {
  XSWriteByte(RawFrig, 127);
}

void
beep() {
  XSWriteByte(RawFrig, 7);
}

/***************************************/
/*    C H D I R  --  Change directory  */
/***************************************/
int
chdir(dirnam) char *dirnam; {
char cmdstr [512];
char *prefix, *suffix;
  char *cp;
  prefix = CWDCMD; suffix = dirnam;
  for (cp = cmdstr; *prefix != '\0'; *cp++ = *prefix++) ;
#ifdef ANSI
  while ( (*cp++ = *suffix++) != '\0' ) ;
#else
  while (*cp++ = *suffix++) ;
#endif
  system(cmdstr);
  return(0);
}

void
setbaud(speed) int speed; {
int fx;

  switch (speed) {
  case 75: fx = 1; break;
  case 150: fx = 2; break;
  case 300: fx = 3; break;
  case 1200: fx = 4; break;
  case 2400: fx = 5; break;
  case 4800: fx = 6; break;
  case 9600: fx = 7; break;
  case 19200: fx = 8; break;
  default:
    fx = 7; break;
  }

  rs.r[0] = 7;
  rs.r[1] = fx;
  ret_val = osbyte( &rs );

  rs.r[0] = 8;
  rs.r[1] = fx;
  ret_val = osbyte( &rs );

}

int
baudint(newx) int newx; {
  switch (newx&7) {
  case 0: return(75);
  case 1: return(150);
  case 2: return(300);
  case 3: return(1200);
  case 4: return(2400);
  case 5: return(4800);
  case 6: return(9600);
  case 7: return(19200);
  default:  return(-1);
  }

}


int
dfbaudr () {
int fx7code, fx8code;


    /* Read baud rate from CMOS ram, can't read directly using fx7 */

    rs.r[0] = 161;
    rs.r[1] = 15;
    rs.r[2] = 0x0;
    ret_val = osbyte( &rs );

    fx7code = fx8code = (rs.r[2] >> 2) & 0x7;

    if (fx7code != fx8code) {
       printf("Warning - split baud rates not supported - %d:%d\n\
  Please set speed <nnn> immediately\n",
       baudint(fx7code), baudint(fx8code));
    } else {
      setbaud(baudint(fx7code));
    }
  
  return(baudint(fx7code));

}

void
DirtyFlush(buffer) int buffer; {

    rs.r[0] = 21;
    rs.r[1] = buffer;
    ret_val = osbyte( &rs );

}

void
fx(a,x,y) int a,x,y; {

    rs.r[0] = a; 
    rs.r[1] = x;
    rs.r[2] = y;
    ret_val = osbyte( &rs );

}

static char escape_char;

void
initrs() {

  /* This should be in ttvt in ckptio - should also be undone afterwards */
  fx(204,0,0);
  fx(2,2,0);
  fx(3,0,0);
  fx(181,1,0);
  fx(202,48,0);
  fx(118,0,0);

  rs.r[0] = 220;
  rs.r[1] = 0;
  rs.r[2] = 255;
  ret_val = osbyte( &rs );
  escape_char = rs.r[1];
} 

void
termrs() {
  
  rs.r[0] = 220;
  rs.r[1] = escape_char;
  rs.r[2] = 0;
  ret_val = osbyte( &rs );

}

int
testbf(buff, val) int buff; int *val; {
#define keybf      0
#define rs423inbf  1
#define rs423outbf 2

int ch;

    switch( buff )
    {
        case keybf:
#ifndef ARTHUR
            rs.r[0] = 145;
            rs.r[1] = buff;
            ch = rs.r[2] = 0xff00;

            ret_val = osbyte( &rs );

            if ( ch != rs.r[2] )
            { /* not empty */
                 *val = rs.r[2] & 0xff;
                 return 1;
            }
            return 0;
#endif
            ch = kbremove(buff);
            if( ch == 0 )
                return 0;

            *val = ch & 0xff;
            return 1;
            break;
        case rs423inbf:
        case rs423outbf:
            if( (ch = rsremove(buff)) == 0 )
                return 0;

            *val = ch & 0xff;
            return 1;
            break;
        default:
            fatal("Bad buff number\n");
    }

    return 0;

}

int
putinbf(buff, val) int buff, val; {

  rs.r[0] = 153;
  rs.r[1] = buff;
  rs.r[2] = val;
  ret_val = osbyte( &rs );

  return(1);


}

int nrsbuf() { /* returns number of chars in RS423 input buffer */
    return rscount( 0, 1 );
}

void
get_posn(x,y) int *x,*y; { /* returns Beeb text cursor coords */
  
  rs.r[0] = 134;
  rs.r[1] = 0;
  rs.r[2] = 0;

  ret_val = osbyte( &rs );
  *x = rs.r[1];
  *y = rs.r[2];

}

error *mosbyte3r(int r0, int r1, int r2)
{       rs.r[0] = r0;
        rs.r[1] = r1;
        rs.r[2] = r2;
        return (osbyte(&rs));
}

void mosbyte3(int r0, int r1, int r2) { mosbyte3r(r0, r1, r2); }


#define MAXNAMLEN 255
static char dirname[MAXNAMLEN];
static char cmdbuf[MAXNAMLEN+4];


int
getcwd()
{
osgbpb_block ctl_blk;
error *ret;
char buf[16];
int len;


        ctl_blk.action = 6;
        ctl_blk.file_handle = NULL; 
        ctl_blk.data_addr = buf;

        if( (ret = osgbpb( &ctl_blk )) != NULL )
        {
                printf("%s (%d)\n",ret->errmess,ret->errnum);
                return( NULL );
        }

        /* Format is:
           <null byte><length byte><dir name><privilege byte>
         */
        len = buf[1];
        buf[len+2] = '\0';

        if( (len == 1) && (buf[2] == '$') )
        {
            dirname[0] = '$';
            dirname[1] = '\0';
            return 1;
        }
        else
        {
            system("dir ^");
            if( getcwd() == 1 )
            {
                buf[1] = '.'; 
                strcat( dirname, buf+1 );
                return 1;
            }
            else 
                return NULL;
        }
                 
        /* Should never get here! */
        return 0;

}


char *
pwd()
{

    if( getcwd() != 1 )
        return NULL;

    strcpy(cmdbuf,"dir ");
    strcat(cmdbuf, dirname );
    system(cmdbuf);

    return dirname;

}
