/*
	CD³²Ctrl Version 1.1, quick update
	
	changes:
	
	- SPEED now works not only on my drive
	- STOP stops the drive immediatly (some kind of NoiseSaver... ;-)
	
	i don't know what's the difference between EJECTRESET and CDREBOOT,
	but i found both functions and why not jump in...?
	
	all warning strings are disabled to save space. i use all this
	commands in a 10K RAD: drive - and i know how to use them.
	reenable them if you like.
*/

//int main (void);
//int _main (void) { return main(); }

#include <exec/exec.h>
#include <dos/dos.h>
#include <libraries/lowlevel.h>
#include <devices/cd.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/lowlevel.h>

#define TEMPLATE "REQ/S,NOREQ/S,CDREBOOT/S,NOCDREBOOT/S,EJECTRESET/S,NOEJECTRESET/S,DOUBLESPEED/S,SINGLESPEED/S,QUIET/S,STOP/S"

struct abc {
	ULONG	req,noreq,res,nores,eject,noeject,dspeed,sspeed;
	ULONG	quiet,stop;
//	ULONG	pads[8]; /* someone said RDArgs must be sized to a 16-longs boundary ??? */
} args = {0};

ULONG Cfg2Speed[] =
{
	TAGCD_READSPEED, 150,
	TAGCD_READXLSPEED, 150,
	TAGCD_PLAYSPEED, 150,
	TAG_END, 0
};

ULONG Cfg1Speed[] =
{
	TAGCD_READSPEED, 75,
	TAGCD_READXLSPEED, 75,
	TAGCD_PLAYSPEED, 75,
	TAG_END, 0
};

ULONG CfgEject[] =
{
	TAGCD_EJECTRESET, FALSE,
	TAG_END, 0
};

int main (void)
{
	struct RDArgs *rdargs;
//	struct abc args = {0};
	struct MsgPort *mp;
	struct IOStdReq *ior;
//	struct DosLibrary *DOSBase;
//	struct ExecBase *SysBase = (struct ExecBase*)*(ULONG*)4;
//	struct Library *LowLevelBase;

//	DOSBase = (struct DosLibrary*)OpenLibrary("dos.library",39);
//	LowLevelBase = OpenLibrary("lowlevel.library",39);
	
	if (rdargs=ReadArgs(TEMPLATE,(LONG*)&(args),NULL))
	{
	//	if(!args.quiet)
	//		PutStr("*** CD³²Ctrl Version 1.0.0 *** by Daniel Balster\n");

		if(mp=CreateMsgPort())
		{
			if(ior=(struct IOStdReq*)CreateIORequest(mp,sizeof(struct IOStdReq)))
			{
				if(!OpenDevice("cd.device",0,ior,0))
				{
					/* ok, the following is somehow ugly - but who carez */
				
					ior->io_Command	= CD_CONFIG;
					ior->io_Length	= 0;

					if (args.eject)
					{
						CfgEject[1]	= TRUE;
						ior->io_Data	= (APTR) &CfgEject;
						DoIO(ior);
					}

					if (args.noeject)
					{
						CfgEject[1]	= FALSE;
						ior->io_Data	= (APTR) &CfgEject;
						DoIO(ior);
					}

					if (args.dspeed)
					{
						ior->io_Data	= (APTR) &Cfg2Speed;
						DoIO(ior);
					}
					
					if (args.sspeed)
					{
						ior->io_Data	= (APTR) &Cfg1Speed;
						DoIO(ior);
					}

					if (args.stop)
					{
						ior->io_Command = CD_MOTOR;
						ior->io_Length	= 0;
						DoIO(ior);
					}
				
					CloseDevice((struct IORequest*)ior);
				}
	//			else PutStr("cannot access cd.device?\n");
				
				DeleteIORequest((struct IORequest*)ior);
			}
	//		else PutStr("cannot create ioreq?\n");

			DeleteMsgPort(mp);
		}
	//	else PutStr("cannot create msgport?\n");


		if (args.req) SystemControl(SCON_KillReq,FALSE,TAG_END);
		if (args.noreq) SystemControl(SCON_KillReq,TRUE,TAG_END);
		if (args.res) SystemControl(SCON_CDReboot,CDReboot_On,TAG_END);
		if (args.nores) SystemControl(SCON_CDReboot,CDReboot_Off,TAG_END);

		FreeArgs(rdargs);
	}
//	else PrintFault(IoErr(),0);


//	CloseLibrary(DOSBase);
//	CloseLibrary(LowLevelBase);
	return RETURN_OK;
}
