/*
 *
 *	DISCLAIMER:
 *
 *	This program is provided as a service to the programmer
 *	community to demonstrate one or more features of the Amiga
 *	personal computer.  These code samples may be freely used
 *	for commercial or noncommercial purposes.
 * 
 * 	Commodore Electronics, Ltd ("Commodore") makes no
 *	warranties, either expressed or implied, with respect
 *	to the program described herein, its quality, performance,
 *	merchantability, or fitness for any particular purpose.
 *	This program is provided "as is" and the entire risk
 *	as to its quality and performance is with the user.
 *	Should the program prove defective following its
 *	purchase, the user (and not the creator of the program,
 *	Commodore, their distributors or their retailers)
 *	assumes the entire cost of all necessary damages.  In 
 *	no event will Commodore be liable for direct, indirect,
 *	incidental or consequential damages resulting from any
 *	defect in the program even if it has been advised of the 
 *	possibility of such damages.  Some laws do not allow
 *	the exclusion or limitation of implied warranties or
 *	liabilities for incidental or consequential damages,
 *	so the above limitation or exclusion may not apply.
 *
 */

/* SetSerial allows the CLI user to dynamically change any particular
 * serial port parameter.
 *
 * July 6, 1985  Version 1.0  Keith Stobie  Initial version 
 * July 7, 1985  Version 2.0  Keith Stobie  Converted to Lattice
 * July 8, 1985  Version 3.0  Keith Stobie  Both term words settable.
 * Sep 25, 1985  Version 3.1  Tom Pohorsky  Remove WBufLen
 * Nov  9, 1985  Version 3.2  Tom Pohorsky  Cleanup
 */
char *prog_name;            /* Name of program being run */
char *prog_version = "3.2"; /* Version of the program */

#include        <exec/types.h>
#include        <exec/nodes.h>
#include        <exec/lists.h>
#include        <exec/memory.h>
#include        <exec/ports.h>
#include        <exec/libraries.h>
#include        <exec/devices.h>
#include        <exec/tasks.h>
#include        <exec/io.h>
#include        <devices/serial.h>
#undef NULL
#include        <lattice/stdio.h>


extern struct MsgPort *CreatePort();

int set_serial( index, value )
   int   index;         /* which parameter to set */
   ULONG value;      /* The new value for paramter */
{
    struct IOExtSer IORser;      /* Serial port IO request block */
    int     error;

    if ((index < 0) || (index > 11)) {
       printf( "Index value %ld is not in range 0-10!\n", index );    
       return 20;
    }

    IORser.io_SerFlags |= SERF_SHARED;
    if ((error = OpenDevice (SERIALNAME, 0, &IORser, 0)) != 0) {
        printf( "Unable to open Serial Device, error=%ld\n", error );
        return 20;
    }

    IORser.IOSer.io_Command = SDCMD_QUERY;
    if ((error = DoIO( &IORser ) != 0)) {
        printf ( "Query status error %ld\n", error);
        return 20;
    }

    /* SET UP the read message port in the I/O request */
    if ((IORser.IOSer.io_Message.mn_ReplyPort = CreatePort( "SetSerial", 0 ))
         == NULL) {
        printf( "Unable to create port for IO message\n" );
        CloseDevice( &IORser );
        return 20;
      }

    switch( index ) {
      case 0:    print_request( &IORser );         break;
      case 1:    IORser.io_CtlChar       = value;  break;
      case 2:    IORser.io_RBufLen       = value;  break;
      case 3:    IORser.io_Baud          = value;  break;
      case 4:    IORser.io_BrkTime       = value;  break;
      case 5:    IORser.io_TermArray.TermArray0 = value; break;
      case 6:    IORser.io_TermArray.TermArray1 = value; break;
      case 7:    IORser.io_ReadLen       = value;  break;
      case 8:    IORser.io_WriteLen      = value;  break;
      case 9:    IORser.io_StopBits      = value;  break;
      case 10:   IORser.io_SerFlags      = value;  break;
      default:   printf( "Internal Logic error! case value %ld\n", index );
    } /* switch */

    IORser.IOSer.io_Command = SDCMD_SETPARAMS;

    error = DoIO( &IORser );

    DeletePort( IORser.IOSer.io_Message.mn_ReplyPort );

    CloseDevice( &IORser );

    if (error) {
       printf( "Error %ld doing IO to set params!\n", error );
       return 10;
    }
      
    if (IORser.IOSer.io_Error) {
       printf( "Error %ld from serial device doing set params!\n"
             , IORser.IOSer.io_Error );
       return 10;
    }

    return 0;
}  /* set_serial() */




print_request( IORser )
    struct IOExtSer *IORser;     /* Serial port IO request block */
{
#define PRINT( field )           printf( "      %s = %8lx %8ld\n" \
                                 , "field", (ULONG) IORser->field \
                                 , (ULONG) IORser->field )
#define IPRINT( index, field ) printf( " %2ld   %s = %8lx %8ld\n" \
                                    , index, "field", (ULONG) IORser->field \
                                                    , (ULONG) IORser->field )

      printf( "index field name       hexadec  decimal\n" ); 
      IPRINT( 1, io_CtlChar   );
      IPRINT( 2, io_RBufLen   );
      IPRINT( 3, io_Baud      );
      IPRINT( 4, io_BrkTime   ); 
      IPRINT( 5, io_TermArray.TermArray0   );
      IPRINT( 6, io_TermArray.TermArray1   );
      IPRINT( 7, io_ReadLen   );
      IPRINT( 8, io_WriteLen  );
      IPRINT( 9, io_StopBits  );
      IPRINT(10, io_SerFlags  );
      printf( "\n" );   /* Not associated with an index */
          PRINT( io_Status    );
}  /* print_request() */


print_usage() {
   printf("%s: version %s\n", prog_name, prog_version );
   printf("usage: %s <index> <value>\n", prog_name );
   printf("  <index> is a decimal number indicating which parameter.\n" );
   printf("          0 indicates print current values (and indexes) \n");
   printf("            without changing them.\n" );
   printf("  <value> number to set the indexed parameter to.\n");
   printf("          value should be in decimal unless it starts with X\n" );
   printf("          or x in which case the number should be hexadecimal\n");
   exit( 5 );
}





main( argc, argv ) 
   int argc;
   char *argv[];
{
   int   index;
   ULONG value;

   if (argc <=0 ) { prog_name = "SetSerial"; }
   else { prog_name = argv[0];}

   if (argc == 1) { print_usage(); }

   if (argc < 2 ) { printf( "Too few parameters\n" ); print_usage();}
   if (argc > 3 ) { printf( "Too many parameters\n" ); print_usage();}

   sscanf( *++argv, "%d", &index );

   if ((index != 0) && (argc < 3)) {
      printf( "Too few parameters\n" ); print_usage();
   }

   if (argc == 3) { 
      ++argv;
      if ((*argv[0] == 'x') || (*argv[0] == 'X')) {
         sscanf( *argv+1, "%x", &value ); /* Skip x or X */
      } else {
         sscanf( *argv, "%d", &value );
      }
   }

   exit( set_serial( index, value ) ); 
   
}  /* main() */
