; 80166 C compiler v5.1 r0               SN077933-093 (C)1996 Tasking Software BV
; options: -x -s -Ms
$EXTEND
$NOMOD166
$STDNAMES(reg.def)
$CASE
$MODEL(SMALL)
	NAME	SERIO_C
; serio.c     1	/*
; serio.c     2	 *      Version : @(#)serio.c	1.4	10/26/94
; serio.c     3	 */
; serio.c     4	
; serio.c     5	/**************************************************************************
; serio.c     6	**                                                                        *
; serio.c     7	**  FILE        :  serio.c                                                *
; serio.c     8	**                                                                        *
; serio.c     9	**  DESCRIPTION :  Implementation of _ioread() and _iowrite()             *
; serio.c    10	**                 using the low level I/O functions getch(), putch(),    *
; serio.c    11	**                 kbhit() and init_serio() working with serial           *
; serio.c    12	**                 channel 0 or channel 1 of the SAB 80C166.              *
; serio.c    13	**		   Default is serial channel 0 used for I/O.		  *
; serio.c    14	**		   If serial channel 1 is wanted for I/O compile	  *
; serio.c    15	**		   "serio.c" with the -DSER_PORT_1 option.		  *
; serio.c    16	**                                                                        *
; serio.c    17	**  COPYRIGHT   :  1993 Tasking Software B.V., Amersfoort                 *
; serio.c    18	**                                                                        *
; serio.c    19	**************************************************************************/
; serio.c    20	#include <stdio.h>
; serio.c    21	
; serio.c    22	#include <reg167.h>
; serio.c    23	#include "serio.h"
; serio.c    24	
; serio.c    25	/* S0/1 port:
; serio.c    26	 * 8 bit, asynchronuous operation, one stopbit,
; serio.c    27	 * receive enable, no parity/frame/overrun check
; serio.c    28	 * baud rate generator enable
; serio.c    29	 */
; serio.c    30	#define	SXCON_MODE	0x8011
; serio.c    31	#define BAUDRATE	0x003f		/* 9600 Baud using 39.3216 MHz	*/
; serio.c    32	
; serio.c    33	void
; serio.c    34	init_serio( void )
; serio.c    35	{
	PUBLIC	_init_serio
SERIO_1_PR	SECTION	CODE WORD PUBLIC 'CPROGRAM'
_init_serio	PROC	FAR
; Stack: 0, CSE: 0 offset 0
; serio.c    36		_bfld( DP3, MSK_TDX_RDX, DP3_TDX_RDX );	/* direction bits	*/
	BFLDH	DP3,#0Ch,#04h
; serio.c    37		_putbit( 1, P3, P3_TXD );	/* enable TXD0/TXD1 output	*/
	BSET	P3.10
; serio.c    38		SXBG  = BAUDRATE;
	MOV	S0BG,#03Fh
; serio.c    39		SXTIC = 0;				/* clear errorflags	*/
	MOV	S0TIC,#00h
; serio.c    40		SXRIC = 0;
	MOV	S0RIC,#00h
; serio.c    41		SXEIC = 0;
	MOV	S0EIC,#00h
; serio.c    42		SXTIR = 1;
	BSET	S0TIR
; serio.c    43		SXCON = SXCON_MODE;
	MOV	S0CON,#08011h
; serio.c    44	}
	RETS
_init_serio	ENDP
; serio.c    45	
; serio.c    46	/*
; serio.c    47	 * Read character from serial channel
; serio.c    48	 */
; serio.c    49	int
; serio.c    50	getch( void )
; serio.c    51	{
	PUBLIC	_getch
; c = R12 (automatic)
_getch	PROC	FAR
; Stack: 0, CSE: 0 offset 0
; serio.c    52		int c = EOF;
	MOV	R12,#0FFFFh
; serio.c    53	
; serio.c    54		if ( SXEIR )
	JNB	S0EIR,_3
; serio.c    55		{
; serio.c    56			SXPE = 0;
	BCLR	S0PE
; serio.c    57			SXFE = 0;
	BCLR	S0FE
; serio.c    58			SXEIR = 0;
	BCLR	S0EIR
; serio.c    59			SXRIR = 0;
	BCLR	S0RIR
; serio.c    60		}
	JMPR	cc_UC,_5
_3:
; serio.c    61		else if ( SXRIR )
	JNB	S0RIR,_5
; serio.c    62		{
; serio.c    63			c = SXRBUF & 0x7F;
	MOV	R12,S0RBUF
	AND	R12,#07Fh
; serio.c    64			SXRIR = 0;
	BCLR	S0RIR
; serio.c    65		}
; serio.c    66		return ( c );
_5:
	MOV	R4,R12
; serio.c    67	}
	RETS
_getch	ENDP
; serio.c    68	
; serio.c    69	/*
; serio.c    70	 * Return 1 if character available, otherwise 0
; serio.c    71	 */
; serio.c    72	int
; serio.c    73	kbhit( void )
; serio.c    74	{
	PUBLIC	_kbhit
_kbhit	PROC	FAR
; Stack: 0, CSE: 0 offset 0
; serio.c    75		if ( SXRIR )
	JNB	S0RIR,_6
; serio.c    76			return ( 1 );
	MOV	R4,#01h
	RETS
_6:
; serio.c    77		return ( 0 );
	MOV	R4,#00h
; serio.c    78	}
_7:
	RETS
_kbhit	ENDP
; serio.c    79	
; serio.c    80	/*
; serio.c    81	 * Write character to serial channel
; serio.c    82	 */
; serio.c    83	int
; serio.c    84	putch( int c )
; serio.c    85	{
	PUBLIC	_putch
_putch	PROC	FAR
; c = R12 (parameter)
; Stack: 0, CSE: 0 offset 0
; serio.c    86		while ( ! SXTIR ) 
_8:
	JNB	S0TIR,_8
; serio.c    87			;
; serio.c    88		SXTIR  = 0;
	BCLR	S0TIR
; serio.c    89		SXTBUF = c;
	MOV	S0TBUF,R12
; serio.c    90		return ( c );
	MOV	R4,R12
; serio.c    91	}
	RETS
_putch	ENDP
; serio.c    92	
; serio.c    93	int
; serio.c    94	_ioread( FILE * fin )
; serio.c    95	{
	PUBLIC	__ioread
; c = R9 (automatic)
__ioread	PROC	FAR
; fin = offset 2 (parameter: R12 pushed)
; Stack: 4, CSE: 0 offset 0
	MOV	[-R0],R12
	MOV	[-R0],R9
; serio.c    96	        /* At this point, it is known that 'fin' is a file opened for   */
; serio.c    97	        /* reading, and is not in error yet.                            */
; serio.c    98	        /* This routine should read the input for the given filehandle  */
; serio.c    99	        /* (in the standard version only 'stdin') from the required     */
; serio.c   100	        /* hardware.                                                    */
; serio.c   101	        /* Whenever an error occurs, 'EOF' should be returned           */
; serio.c   102	        /* and fin->_flag should be set to the proper error value       */
; serio.c   103	        /* i.e.         _IOEOF on end of FILE                           */
; serio.c   104	        /*              _IOERR on any other error                       */
; serio.c   105	        /* Note that when a read is done on 'stdin', this routine       */
; serio.c   106	        /* should do the scanning, and whenever neccessary, do the      */
; serio.c   107	        /* echoing to stdout                                            */
; serio.c   108	
; serio.c   109		int c = EOF;
	MOV	R9,#0FFFFh
; serio.c   110	
; serio.c   111	        if ( fin == stdin )
	MOV	R4,[R0+#02H]
	CMP	R4,#__iob
	JMPR	cc_NE,_13
; serio.c   112	        {
; serio.c   113	        	/*
; serio.c   114	        	 * Assume terminal sending either CR or CRLF. Allow
; serio.c   115	        	 * only LF as valid delimiter, so translate CR into LF
; serio.c   116	        	 * and ignore received LF's
; serio.c   117	        	 */
; serio.c   118	                do	/* blocking read from serial channel 0 */
_9:
; serio.c   119			{
; serio.c   120				c = getch();		/* without echo */
	CALLS	SEG _getch,_getch
	MOV	R9,R4
; serio.c   121				if ( c == 0x0a )	/* LF */
	CMP	R9,#0Ah
	JMPR	cc_NE,_10
; serio.c   122					c = EOF;	/* ignore it */
	MOV	R9,#0FFFFh
	JMPR	cc_UC,_12
_10:
; serio.c   123				else if ( c == 0x0d )	/* CR */
	CMP	R9,#0Dh
	JMPR	cc_NE,_12
; serio.c   124					c = 0x0a;	/* turn into LF */
	MOV	R9,#0Ah
; serio.c   125			}
_12:
; serio.c   126			while ( c < 0 );
	CMP	R9,#00h
	JMPR	cc_SLT,_9
; serio.c   127	
; serio.c   128			/*
; serio.c   129			 * when reading 'stdin', echo to 'stdout'
; serio.c   130			 * performing LF ==> CR-LF translation
; serio.c   131			 */
; serio.c   132	                _iowrite( c, stdout );
	MOV	R12,R9
	MOV	R13,#(__iob+10)
	CALLS	SEG __iowrite,__iowrite
; serio.c   133	        }
_13:
; serio.c   134		return( c );	/* return read character on succes */
	MOV	R4,R9
; serio.c   135	}
	MOV	R9,[R0+]
	ADD	R0,#02h
	RETS
__ioread	ENDP
; serio.c   136	
; serio.c   137	
; serio.c   138	int
; serio.c   139	_iowrite( int c, FILE * fout )
; serio.c   140	{
	PUBLIC	__iowrite
__iowrite	PROC	FAR
; c = R9 (parameter: R12 copied)
; fout = R8 (parameter: R13 copied)
; Stack: 4, CSE: 0 offset 0
	MOV	[-R0],R9
	MOV	[-R0],R8
	MOV	R8,R13
	MOV	R9,R12
; serio.c   141	        /* At this point, it is known that 'fout' is a file opened for  */
; serio.c   142	        /* writing, and is not in error yet.                            */
; serio.c   143	        /* This routine should write the output for the given filehandle*/
; serio.c   144	        /* (in the standard version only 'stdout' or 'stderr')          */
; serio.c   145	        /* to the required hardware.                                    */
; serio.c   146	        /* Whenever an error occurs, 'EOF' should be returned           */
; serio.c   147	        /* and fout->_flag should be set to the proper error value      */
; serio.c   148	        /* i.e.         _IOEOF on end of FILE                           */
; serio.c   149	        /*              _IOERR on any other error                       */
; serio.c   150	
; serio.c   151		if ( fout == stdout  ||  fout == stderr )
	CMP	R8,#(__iob+10)
	JMPR	cc_EQ,_14
	CMP	R8,#(__iob+20)
	JMPR	cc_NE,_16
_14:
; serio.c   152		{
; serio.c   153			if ( c == '\n' )
	CMP	R9,#0Ah
	JMPR	cc_NE,_15
; serio.c   154				putch( '\r' );
	MOV	R12,#0Dh
	CALLS	SEG _putch,_putch
_15:
; serio.c   155			putch( c );
	MOV	R12,R9
	CALLS	SEG _putch,_putch
; serio.c   156		}
_16:
; serio.c   157	
; serio.c   158	        return( c );    /* return written character on success */
	MOV	R4,R9
; serio.c   159	}
	MOV	R8,[R0+]
	MOV	R9,[R0+]
	RETS
__iowrite	ENDP
SERIO_1_PR	ENDS

C166_US	SECTION	LDAT WORD GLBUSRSTACK 'CUSTACK'
	DS	8
C166_US	ENDS

	EXTERN	__iob:WORD
	REGDEF	R0-R15
	END
