/** DoRevision Header ** Header built automatically - do not edit! **********
 *
 *	(C) Copyright 1991 by Olaf Barthel
 *
 *	Name .....:	SetBatt.c
 *	Created ..:	Wednesday 24-Jul-91 14:21
 *	Revision .:	1
 *
 *	Date		Author		Comment
 *	=========	========	====================
 *	24-Jul-91	Olsen		Created this file!
 *
 ***************************************************************************/

	/* Argument template and extra help. */

#define ARG_TEMPLATE	"T=Timeout/K,U=UseLUNS/K,H=HostID/K/N,S=Sync/K"

#define ARG_HELP	"\nUsage: SetBatt [Timeout L|S] [UseLUNS Y|N] [HostID n] [Sync Y|N]\n\n\
               Timeout Set (L)ong or (S)hort SCSI selection timeout.\n\
               UseLUNS Access logical units above 0 at any given\n\
                       SCSI address, responds to (Y)es or (N)o.\n\
               HostID  Set the SCSI controller's host ID, correct IDs are 0..7.\n\
               Sync    Initiate synchronous transfer, responds to\n\
                       (Y)es or (N)o.\n\n"

	/* Argument vector offsets. */

enum	{	ARG_TIMEOUT,ARG_USELUNS,ARG_HOSTID,ARG_SYNC };

	/* Handy international toupper() macro. */

#define ToUpper(c)	((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : (c))

	/* Shared library identifiers. */

struct ExecBase		*SysBase;
struct DosLibrary	*DOSBase;

struct Library		*BattMemBase;

	/* Prototypes for this module. */

LONG __saveds		Main(VOID);
VOID			ShowConfig(VOID);

	/* Main():
	 *
	 *	Main entry point to this module.
	 */

LONG __saveds
Main()
{
	LONG Result = RETURN_FAIL;

		/* Set up SysBase. */

	SysBase = *(struct ExecBase **)4;

		/* Open dos.library. */

	if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
	{
			/* Open battmem.resource. */

		if(BattMemBase = (struct Library *)OpenResource(BATTMEMNAME))
		{
			struct RDArgs	*ArgsPtr;
			UBYTE		**Args;

				/* Allocate space for the RDArgs auxilary structure. */

			if(ArgsPtr = AllocVec(sizeof(struct RDArgs),MEMF_PUBLIC|MEMF_CLEAR))
			{
					/* Provide extended help information. */

				ArgsPtr -> RDA_ExtHelp = ARG_HELP;

					/* Allocate space for the arguments. */

				if(Args = (UBYTE **)AllocVec(sizeof(UBYTE *) * 4,MEMF_PUBLIC|MEMF_CLEAR))
				{
						/* Read the args if any. */

					if(ReadArgs(ARG_TEMPLATE,(APTR)Args,ArgsPtr))
					{
						UBYTE Data;

						Result = RETURN_OK;

							/* Obtain exclusive access
							 * to battmem.resource.
							 */

						ObtainBattSemaphore();

							/* Set the SCSI scan timeout. */

						if(Args[ARG_TIMEOUT])
						{
							switch(ToUpper(Args[ARG_TIMEOUT][0]))
							{
								case 'L':	Data = 1;
										WriteBattMem(&Data,BATTMEM_SCSI_TIMEOUT_ADDR,BATTMEM_SCSI_TIMEOUT_LEN);
										break;

								case 'S':	Data = 0;
										WriteBattMem(&Data,BATTMEM_SCSI_TIMEOUT_ADDR,BATTMEM_SCSI_TIMEOUT_LEN);
										break;

								default:	Printf("SetBatt: Argument not recognized \"%s\".\n",Args[ARG_TIMEOUT]);
										Result = RETURN_FAIL;
										break;
							}
						}

							/* Toggle LUNs. */

						if(Result != RETURN_FAIL)
						{
							if(Args[ARG_USELUNS])
							{
								switch(ToUpper(Args[ARG_USELUNS][0]))
								{
									case 'Y':	Data = 1;
											WriteBattMem(&Data,BATTMEM_SCSI_LUNS_ADDR,BATTMEM_SCSI_LUNS_LEN);
											break;

									case 'N':	Data = 0;
											WriteBattMem(&Data,BATTMEM_SCSI_LUNS_ADDR,BATTMEM_SCSI_LUNS_LEN);
											break;

									default:	Printf("SetBatt: Argument not recognized \"%s\".\n",Args[ARG_USELUNS]);
											Result = RETURN_FAIL;
											break;
								}
							}
						}

							/* Select SCSI host ID. */

						if(Result != RETURN_FAIL)
						{
							if(Args[ARG_HOSTID])
							{
								LONG ID = *((LONG *)Args[ARG_HOSTID]);

								if(ID < 0 || ID > 7)
								{
									Printf("SetBatt: SCSI Host ID must be between 0 and 7.\n");
									Result = RETURN_FAIL;
								}
								else
								{
									Data = ID ^ 7;
									WriteBattMem(&Data,BATTMEM_SCSI_HOST_ID_ADDR,BATTMEM_SCSI_HOST_ID_LEN);
								}
							}
						}

							/* Toggle synchronous transfer. */

						if(Result != RETURN_FAIL)
						{
							if(Args[ARG_SYNC])
							{
								switch(ToUpper(Args[ARG_SYNC][0]))
								{
									case 'Y':	Data = 1;
											WriteBattMem(&Data,BATTMEM_SCSI_SYNC_XFER_ADDR,BATTMEM_SCSI_LUNS_LEN);
											break;

									case 'N':	Data = 1;
											WriteBattMem(&Data,BATTMEM_SCSI_SYNC_XFER_ADDR,BATTMEM_SCSI_LUNS_LEN);
											break;

									default:	Printf("SetBatt: Argument not recognized \"%s\".\n",Args[ARG_SYNC]);
											Result = RETURN_FAIL;
											break;
								}
							}
						}

							/* Show the current configuration. */

						if(Result != RETURN_FAIL)
							ShowConfig();

							/* Release access semaphore. */

						ReleaseBattSemaphore();

							/* Start the cleanup. */

						FreeArgs(ArgsPtr);
					}
					else
						PrintFault(IoErr(),"SetBatt");

					FreeVec(Args);
				}
				else
					Printf("SetBatt: Unable to allocate argument line!\n");

				FreeVec(ArgsPtr);
			}
		}
		else
			Printf("SetBatt: Failed to open \"%s\"!\n",BATTMEMNAME);

		CloseLibrary(DOSBase);
	}

	return(Result);
}

	/* ShowConfig():
	 *
	 *	Display the current battmem settings.
	 */

VOID
ShowConfig()
{
	UBYTE Data;

		/* Amnesia on the Amiga side? */

	if(!ReadBattMem(&Data,BATTMEM_AMIGA_AMNESIA_ADDR,BATTMEM_AMIGA_AMNESIA_LEN))
	{
		if(!(Data & 1))
			Printf("\33[33mWarning\33[31m - a memory loss has occured on the Amiga side!\n\n");
	}

		/* Long or short timeouts? */

	if(!ReadBattMem(&Data,BATTMEM_SCSI_TIMEOUT_ADDR,BATTMEM_SCSI_TIMEOUT_LEN))
	{
		if(Data & 1)
			Printf("The SCSI selection timeout is \33[33mLONG\33[31m (2 seconds).\n");
		else
			Printf("The SCSI selection timeout is \33[33mSHORT\33[31m (128 miliseconds).\n");
	}

		/* Scan LUNs? */

	if(!ReadBattMem(&Data,BATTMEM_SCSI_LUNS_ADDR,BATTMEM_SCSI_LUNS_LEN))
	{
		if(Data & 1)
			Printf("Logical SCSI units above 0 \33[33mARE\33[31m accessed.\n");
		else
			Printf("Logical SCSI units above 0 \33[33mARE NOT\33[31m accessed.\n");
	}

	Printf("\n");

		/* Amnesia on the shared Amiga/Amix side? */

	if(!ReadBattMem(&Data,BATTMEM_SHARED_AMNESIA_ADDR,BATTMEM_SHARED_AMNESIA_LEN))
	{
		if(!(Data & 1))
			Printf("\33[33mWarning\33[31m - a memory loss has occured on the shared Amiga/Unix side!\n\n");
	}

		/* Show SCSI host ID. */

	if(!ReadBattMem(&Data,BATTMEM_SCSI_HOST_ID_ADDR,BATTMEM_SCSI_HOST_ID_LEN))
		Printf("The SCSI controller's host ID is \33[33m%ld\33[31m.\n",(Data & 7) ^ 7);

		/* Synchronous transfer enabled? */

	if(!ReadBattMem(&Data,BATTMEM_SCSI_SYNC_XFER_ADDR,BATTMEM_SCSI_SYNC_XFER_LEN))
	{
		if(!(Data & 1))
			Printf("Synchronous transfer is \33[33mINITIATED\33[31m.\n");
		else
			Printf("Synchronous transfer is \33[33mNOT INITIATED\33[31m.\n");
	}
}
