#include <portab.h>
#include <screen.h>
#include <string.h>
#include <tos.h>
#include <ext.h>

#include <stdlib.h>
#include <stdio.h>

#define AUX   (1)
/* AUX (channel 1) undefined (EUNDEV) in FastXSer/XSDD, will be changed later */

#define MODEM1 (6)
/* MODEM1 (channel 6) undefined (EUNDEV) in FastXSer/XSDD, will be changed later */

#define MODEM2 (7)
#define SERIAL2 (8)
#define SERIAL2 (9)

/*
   the assignment of the channels is subject to changes
   at the moment they meet the assignment of MSTE and Falcon030,
   and TT (SERIAL1 left out on TT, channel8 !equals! channel9 )
*/


extern UWORD get_cookie( ULONG, ULONG * );

typedef LONG cdecl (*cookie_fun)(UWORD opcode,...);

static cookie_fun XSDD = NULL;

char init[] = "at&t1\r";
char bye[] = "+++  at&t0\r";
char buffers[8192];
char buffer[8192];


/*
  Rckgabewert:
  0
*/

WORD XSDriverInfo( BYTE *info, LONG *product, WORD *version )
{
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	XSDD( -2, info, product, version );

	if ( old_ssp ) Super( (void *) old_ssp );

	return 0;
}


/*
  Rckgabewert:
  Version
*/

WORD XSVersion( void )
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( -1 );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  >=0 - Anzahl der verfgbaren Zeichen
  EUNDEV - Ungltiges Device
*/

LONG XSInStat(WORD device)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = XSDD( 0, device );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
Rckgabewert:
  >=0 - Anzahl der Zeichen, die gelesen wurden wurden
  EUNDEV - Ungltiges Device
  Weitere (negative) TOS-Fehlernummern bei I/O-fehlern
*/

LONG XSRead(WORD device, LONG count, BYTE *buffer)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = XSDD( 1, device, count, buffer );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  >=0 - Anzahl der Zeichen, die ausgegeben werden knnen
  EUNDEV - Ungltiges Device
*/

LONG XSOutStat(WORD device)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = XSDD( 2, device );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  >=0 - Anzahl der Zeichen, die geschrieben wurden
  EUNDEV - Ungltiges Device
  Weitere (negative) TOS-Fehlernummern bei I/O-Fehlern
*/

LONG XSWrite(WORD device, LONG count, BYTE *buffer)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = XSDD( 3, device, count, buffer );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabe:
  0 bei Erfolg
  EUNDEV - Ungltiges Device
*/

WORD XSDevName(WORD device, BYTE *name)
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 4, device, name );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}
  

#define TIOCM_LE  0x01  			/* line enable */
#define TIOCM_DTR 0x02  			/* data terminal ready */
#define TIOCM_RTS 0x04  			/* ready to send */
#define TIOCM_CTS 0x08  			/* clear to send */
#define TIOCM_CAR 0x10  			/* carrier detect */
#define TIOCM_RNG 0x20  			/* ring */
#define TIOCM_DSR 0x40  			/* data set ready */

/*
  Rckgabewert:
  >=0 (LONG!) - Verfgbare Kontrolleitungen
  EUNDEV - Ungltiges Device
*/

LONG XSCtlMap(WORD device)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 5, device );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  >=0 (LONG!) - Status der Kontrolleitungen
  EUNDEV - Ungltiges Device
*/

LONG XSGetCtl(WORD device)
{
	LONG ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 5, device );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  0 bei Erfolg
  EUNDEV - Ungltiges Device
*/

WORD XSSetCtl(WORD device, UWORD ctl)
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 6, device, ctl );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  0 bei Erfolg
  EUNDEV - Ungltiges Device
*/

WORD XSOnCtl(WORD device, UWORD on_mask)
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 7, device, on_mask );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabewert:
  0 bei Erfolg
  EUNDEV - Ungltiges Device
*/

WORD XSOffCtl(WORD device, UWORD off_mask)
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 8, device, off_mask );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}


/*
  Rckgabe: 
  0 bei Erfolg
  EUNDEV - Ungltiges Device
*/

WORD XSBreak(WORD device, WORD on)
{
	WORD ret;
	LONG old_ssp=0;
	
	if ( !Super( (void *) 1L) ) old_ssp = Super( 0L );

	ret = (WORD) XSDD( 8, device, on );

	if ( old_ssp ) Super( (void *) old_ssp );

	return ret;
}

/* fehlen noch:    (laut XSDD-spec)
LONG XSIBaud(WORD device, LONG baudrate)
LONG XSOBaud(WORD device, LONG baudrate)
WORD XSReserve(WORD device)
WORD XSRelease(WORD device)
LONG XSCapMap(WORD device)
LONG XSSetFlags(WORD device, UWORD flags)
LONG XSGetFlags(WORD device)
WORD XSFlush(WORD device, WORD mode)

und die hab ich mir selbst ausgedacht:
LONG XSIBuffer(WORD device, LONG *buffer, LONG *size)
LONG XSOBuffer(WORD device, LONG *buffer, LONG *size)

die setzen den BufferPointer und BufferSize im IOREC, jeweils fr
Eingabe und Ausgabe, und liefern die alten Werte zurck.

Weitere Vorschlge???

brigens: Im Moment werden (entgegen der XSDD-Spec) nur die Register
 A2-A7/D3-D7 nicht verndert, das entspricht der PureC-Konvention.

*/


int main()
{
	int cnt;
	char *cp;
	
	ULONG cookievalue[1];

	char xsddinfo[128], devinfo[32];
	char *p;
	LONG product;
	WORD version1, version2;
	int i;
	
	p=buffers;
	for( i=0; i<0x200; i++)
	{
		strcpy(p,"abcdefghijklmnop");
		p+=0x10;
	}
	cnt = get_cookie( 'xSDD', cookievalue );
	
	if ( cnt )
	{
		XSDD = (cookie_fun) *cookievalue;
	}
	else
	{
		printf( "\n XSDD nicht installiert.\n" );
		exit( 1 );
	}

	XSDriverInfo( xsddinfo, &product, &version1 );
	version2 = XSVersion();
	XSDevName( 7, devinfo );
	
	printf( "\n xsddinfo: %s", xsddinfo );
	printf( "\n product:  %.4s", &product );
	printf( "\n Version1: %#06x", version1 );
	printf( "\n Version2: %#06x", version2 );
	printf( "\n devname:  %s", devinfo );

	cp = init;
	do
	{
		Bconout( 7, *cp++ );
		delay(200);
	}
	while( *cp );

	delay(5000);

	while( !kbhit() )
	{
		while( XSOutStat( 7 )<0x7ffL );
		
		while( XSOutStat( 7 )>=0x7ffL )
		{
			XSWrite( 7, 0x10L, buffers );
		}

		while( XSInStat( 7 )<0x10L );

		while( XSInStat( 7 )>=0x10L )
		{
			buffer[0x10] = 0;
			XSRead( 7, 0x10L, buffer );
	
			printf( "\n%s", buffer );
		}
	}

	getch();

	cp = bye;
	do
	{
		delay( 500 );
		Bconout( 7, *cp++ );
	}
	while( *cp );

	while( Bconstat( 7 ) ) Bconin(7);

	return 0;
}