/*
 * $Header: DH0:src/omti/dist/src/RCS/OmtiFormat.c,v 1.1 92/11/25 02:06:12 Barnard Exp $
 *
 */

/*
 * This program is for low level formatting of the drives connected to
 * the harddisk controller
 *
 * Sorry, I just inserted this comment-lines, the rest is commented in
 * german.
 *
 * This program was written under AmigaOS 1.3. I don't know, whether it will
 * run under AmigaOS 2.04 and above.
 *
 * The TAB-Size use is 4.
 */

#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>

#include "stdio.h"

#include "include/omti.h"
#include "include/omtistruct.h"
#include "include/omtihard.h"
#include "include/parablock.h"

extern	struct	Gadget		UnitGad[],	StepGad[],	ErrGad[],
							SecGad[],	IntGad[],	OrgGad[],
							HeadGad,	CylGad,		PreGad,
							ParkGad;

extern	struct	Border		LargeRender,NumRender,ErrRender,FmtRender;

struct	NewWindow	NewWindowDef	=
{
	0,0,
	640,200,
	-1,-1,
	CLOSEWINDOW | GADGETUP,
	WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | NOCAREREFRESH | GIMMEZEROZERO,
	NULL, NULL,
	"Omti-Controller Formatierprogramm V 1.0 (C) Barnard",
	NULL,
	NULL,
	0, 0, 0, 0,
	WBENCHSCREEN
};

struct	IntuitionBase	*IntuitionBase;
struct	GfxBase			*GfxBase;

struct	RastPort		*WRP;
struct	ViewPort		*WVP;
struct	ColorMap		*ColMap;
struct	Window			*Window;

struct	OmtiController	*Controller;

UWORD MyColors[4][3]	=
{	0x0,0x0,0x0,
		0xf,0xf,0xf,
		0xf,0x0,0x0,
		0x1,0xc,0x0
};

UWORD SaveColors[4];



#define	ERRID		"ERRLIST"
#define	DEFLISTSIZE	200					/* Diesen Parameter fuer mehr Fehler vergroessern */

TEXT		ErrIDTx[8];

int			ErrList[DEFLISTSIZE][2];	/* 0: Head 1: Spur */

int					 OmtiUnit =	-1,
					 OmtiStep =	-1,
					 OmtiHead =	-1,
					OmtiHiCyl =	-1,
					 OmtiPre  =	-1,
					 OmtiSec  =	-1,
					 OmtiInt  =	-1;
				 OmtiParkCyl  =	-1;

int					 OmtiWrCu    =	 MAXCYL, /* Wird normalerweise nie benoetigt */
					 OmtiWrCyl   =	-1,
					 OmtiErrList =	-1;

#define	OMTIPFAD	"DEVS:Omti"

ULONG				 OmtiFlag =	0;

#define		OMTIUNITFLAG (1 << 0)
#define		OMTISTEPFLAG (1 << 1)
#define		OMTIHEADFLAG (1 << 2)
#define		OMTICYLFLAG  (1 << 3)
#define		OMTIPREFLAG  (1 << 4)
#define		OMTISECFLAG  (1 << 5)
#define		OMTIINTFLAG  (1 << 6)
#define		OMTIPARKFLAG (1 << 7)

#define		LUN(x)			((x & 1) << 5)
#define		TRACKHI(x)		((x & 0x400) >> 3)
#define		TRACKMI(x)		((x & 0x300) >> 2)
#define		TRACKLO(x)		 (x & 0xff)

 /* Alle Flags ausser INTFLAG */

 #define		ALLFLAGS	(	OMTIUNITFLAG | \
							OMTISTEPFLAG | \
							OMTIHEADFLAG | \
							OMTICYLFLAG |  \
							OMTIPREFLAG |  \
							OMTISECFLAG |  \
							OMTIPARKFLAG   \
						)

/* Texte */

struct	IntuiText	ConIText	={ 3,0,JAM1, 0, 0,NULL,"Controller at xxxxxxxx",NULL};
struct	IntuiText	UnitIText	={ 3,0,JAM1, 0, 0,NULL,"Unit      ",NULL};
struct	IntuiText	StepIText	={ 3,0,JAM1, 0, 0,NULL,"Steprate  ",NULL};
struct	IntuiText	HeadIText	={ 3,0,JAM1, 0, 0,NULL,"Heads     ",NULL};
struct	IntuiText	CylIText	={ 3,0,JAM1, 0, 0,NULL,"Nof Cyl.  ",NULL};
struct	IntuiText	WrCylIText	={ 3,0,JAM1, 0, 0,NULL,"Nof WrCyl.",NULL};
struct	IntuiText	PreIText	={ 3,0,JAM1, 0, 0,NULL,"WrPrecomp ",NULL};
struct	IntuiText	ParkIText	={ 3,0,JAM1, 0, 0,NULL,"Park-Cyl. ",NULL};
struct	IntuiText	SecIText	={ 3,0,JAM1, 0, 0,NULL,"Sectors   ",NULL};
struct	IntuiText	IntIText	={ 3,0,JAM1, 0, 0,NULL,"Interleave",NULL};

struct	IntuiText	ErrText		={ 1,0,JAM2, 0, 0,NULL,"Head  Track",NULL};
struct	IntuiText	OmtiWrTx	={ 1,0,JAM2, 0, 0,NULL,"    ",NULL };

struct	IntuiText	InitText	={ 1,0,JAM1, 0, 0,NULL,"Init Drive",NULL };
struct	IntuiText	FormatText	={ 2,0,JAM1, 0, 0,NULL,"Format Drive",NULL };
struct	IntuiText	AssignText	={ 1,0,JAM1, 0, 0,NULL,"Assign Bad Tracks",NULL };
struct	IntuiText	VerifyText	={ 1,0,JAM1, 0, 0,NULL,"Verify Drive",NULL };
struct	IntuiText	BlockText	={ 1,0,JAM1, 0, 0,NULL,"Write PARA-Block",NULL };
struct	IntuiText	EndeText	={ 1,0,JAM1, 0, 0,NULL,"Format complete",NULL };
struct	IntuiText	AssText		={ 3,0,JAM2, 0, 0,NULL,"Assign: xx/yyyy -> xx/yyyy",NULL};
struct	IntuiText	VerText		={ 3,0,JAM2, 0, 0,NULL,"Verify: xx/yyyy",NULL};

BOOL OpenAll()
{
	if(NULL == (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
	{
		printf("OmtiFormat: No Intuition\n");
		return(TRUE);
	}
	if(NULL == (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
	{
		printf("OmtiFormat: No Gfx\n");
		return(TRUE);
	}
	if(NULL == (Window = (struct Window *)OpenWindow(&NewWindowDef)))
	{
		printf("OmtiFormat: No Window\n");
		return(TRUE);
	}
	return(FALSE);
}


void CloseAll()
{
	if(Window)			CloseWindow(Window);
	if(IntuitionBase)	CloseLibrary(IntuitionBase);
	if(GfxBase)			CloseLibrary(GfxBase);
}

void DisableOmtiController()
{
	Controller->omask	= 0;		/* Interrupts sperren */
	while(Controller->ostatus & F_oBSY){} /* Warten, bis Controller idle */
}

struct	IntuiText	ConText	=
{
	AUTOFRONTPEN,AUTOBACKPEN,AUTODRAWMODE,AUTOLEFTEDGE,AUTOTOPEDGE,AUTOITEXTFONT,"Leider",AUTONEXTTEXT
};

struct	IntuiText	BodyText[2]	=
{
	{	AUTOFRONTPEN,AUTOBACKPEN,AUTODRAWMODE,15,12,AUTOITEXTFONT,NULL,NULL		},
	{	AUTOFRONTPEN,AUTOBACKPEN,AUTODRAWMODE,15,22,AUTOITEXTFONT,NULL,&BodyText[0]},
};

void MyRequest(str1,str2)
STRPTR	str1,
		str2;
{
register BOOL dummy;
	BodyText[0].IText = str1;
	BodyText[1].IText = str2;
	dummy = AutoRequest(Window,&BodyText[1],NULL,&ConText,NULL,NULL,320,70);
}

void RefreshScreen()
{
	RefreshGadgets(&UnitGad[1],Window,NULL);
	sprintf(OmtiWrTx.IText,"%d",OmtiWrCyl);
	PrintIText(WRP,&OmtiWrTx,131,98);
}

/* Warten, dass Controller SELECTED meldet */

void WaitForSelect()
{	while((Controller->ostatus &  F_oBSY)  != F_oBSY){}}

/* Warten, dass Controller Command-Byte haben will */

void WaitForCommand()
{	while((Controller->ostatus & ( F_oREQ | F_oIO | F_oCD)) != (F_oREQ | F_oCD)){}}

/* Warten, bis Controller Daten-Byte schicken will */

void WaitForSend()
{	while((Controller->ostatus & ( F_oREQ | F_oIO | F_oCD)) != (F_oREQ  | F_oIO)){}}

/* Warten, bis Controller Datenbyte haben will */

void WaitForRec()
{	while((Controller->ostatus & ( F_oREQ | F_oIO | F_oCD)) != F_oREQ){}}

void SendCommand(command,track,sector,head,step,nofsec)
UBYTE	command;	/* Kommando, das gesendet werden soll */

int		track,		/* Track, der angefahren werden soll */
		sector,		/* Sektor, der angefahren werden soll */
		head,		/* Kopf fuer Lese-/Schreib-Kommandos */
		step,		/* Steprate */
		nofsec;		/* Anzahl der zu uebertragenden Sektoren */
{
UBYTE			OmtiCommand[6];
register	int	i;
	OmtiCommand[0]	 = command;
	OmtiCommand[1]	 = (UBYTE)LUN(OmtiUnit);
	OmtiCommand[1]	|= (UBYTE)TRACKHI(track);
	OmtiCommand[1]	|= (UBYTE)head;
	OmtiCommand[2]	 = (UBYTE)sector;
	OmtiCommand[2]	|= (UBYTE)TRACKMI(track);
	OmtiCommand[3]	 = (UBYTE)TRACKLO(track);
	OmtiCommand[4]	 = (UBYTE)nofsec;
	OmtiCommand[5]	 = (UBYTE)step;

	Controller->oselect = 0;	/* Controller selecten */
	WaitForSelect();
	for(i=0;i<6;i++)
	{
		WaitForCommand();
		Controller->odata = OmtiCommand[i];
	}
}

void TestSense()
{
register UBYTE	Sense;
register COUNT	i;
TEXT			SenseTxt[20];
UBYTE			ReqSense[4];
	while((Controller->ostatus & ( F_oREQ | F_oIO | F_oCD)) != (F_oREQ | F_oIO | F_oCD))
	{}
	Sense = Controller->odata;
	if(!(Sense & F_sCS))
		return;

	SendCommand(omti_c_reqsens,0,0,0,0,0);
	for(i=0;i<4;i++)
	{
		WaitForSend();
		ReqSense[i] = Controller->odata;
	}
	TestSense();
	sprintf(SenseTxt,"Sense: %2d %2d %2d %2d",ReqSense[0],ReqSense[1],ReqSense[2],ReqSense[3]);
	MyRequest("Controller-Fehler:",SenseTxt);
}

void Recalibrate()
{
	SendCommand(omti_c_recali,0,0,0,0,1);
	TestSense();
}

void InitDrive()
{
	SendCommand(omti_c_idc,0,0,0,0,0);

	WaitForRec();
	Controller->odata = (UBYTE)(OmtiHiCyl >>8);
	WaitForRec();
	Controller->odata = (UBYTE)(OmtiHiCyl & 0xff);

	WaitForRec();
	Controller->odata = (UBYTE)OmtiHead;

	WaitForRec();
	Controller->odata = (UBYTE)(OmtiWrCu >> 8);
	WaitForRec();
	Controller->odata = (UBYTE)(OmtiWrCu & 0xff);

	WaitForRec();
	Controller->odata = (UBYTE)(OmtiPre >> 8);
	WaitForRec();
	Controller->odata = (UBYTE)(OmtiPre & 0xff);

	WaitForRec();
	Controller->odata = 0;

	TestSense();
}

void ReadParaBlock(PB)
UBYTE PB[];
{
register COUNT i;
	Recalibrate();
	SendCommand(omti_c_read,0,0,0,OmtiStep,1);
	for(i=0;i<PARABLOCKSIZE;i++)
	{
		WaitForSend();
		PB[i] = Controller->odata;
	}
	TestSense();
}

void WriteParaBlock(PB)
UBYTE PB[];
{
register COUNT i;
	Recalibrate();
	SendCommand(omti_c_write,0,0,0,OmtiStep,1);
	for(i=0;i<PARABLOCKSIZE;i++)
	{
		WaitForRec();
		Controller->odata = PB[i];
	}
	TestSense();
}

void FormatDrive()
{
	Recalibrate();
	SendCommand(omti_c_format,0,0,0,OmtiStep,OmtiInt+1);
	TestSense();
}

void AssignATrack(errhead,errtrack,newhead,newtrack)
UWORD	errtrack,newtrack;
UBYTE	errhead,newhead;
{
UBYTE				alttrack[4];
register	COUNT	i;
	SendCommand(omti_c_assalt,errtrack,0,errhead,OmtiStep,OmtiInt+1);

	alttrack[0]	=  newhead;
	alttrack[0]	|= TRACKHI(newtrack);
	alttrack[1]	=  TRACKMI(newtrack);
	alttrack[2]	=  TRACKLO(newtrack);
	alttrack[3]	=  0;

	for(i=0;i<4;i++)
	{
		WaitForRec();
		Controller->odata = alttrack[i];
	}
	TestSense();
}

void VerifyATrack(track,head)
UWORD track;
UBYTE head;
{
	SendCommand(omti_c_rdver,track,0,head,OmtiStep,(OmtiSec ? 26 : 17));
	TestSense();
}

void SetUpPARABlock(PB)
UBYTE PB[];
{
register COUNT i;
struct ParaBlock *ParaBlock;

	for(i=0;i<PARABLOCKSIZE;i++)
		PB[i] = 0;

	ParaBlock = (struct ParaBlock *)PB;
	strncpy(&(ParaBlock->pb_paraid),PARAID,4);
	ParaBlock->pb_hicyl      = (UWORD)OmtiHiCyl;
	ParaBlock->pb_heads      = (UBYTE)OmtiHead;
	ParaBlock->pb_wrcur      = (UWORD)OmtiWrCu;
	ParaBlock->pb_wrpre      = (UWORD)OmtiPre;
	ParaBlock->pb_step       = (UBYTE)OmtiStep;
	ParaBlock->pb_wrcyl      = (UWORD)OmtiWrCyl;
	ParaBlock->pb_parkcyl    = (UWORD)OmtiParkCyl;
	ParaBlock->pb_interleave = (UBYTE)OmtiInt;
	ParaBlock->pb_sectors    = (UBYTE)(OmtiSec ? 26 : 17);

	ParaBlock->pb_bootlun = OmtiUnit ? 0xffff : 0;

}

void SetUpParameter(PB)
UBYTE PB[];
{
struct ParaBlock *ParaBlock;
	ParaBlock   = (struct ParaBlock *)PB;

	if(OmtiStep != -1) StepGad[OmtiStep].GadgetText->FrontPen = 2;
	if(OmtiSec  != -1) SecGad[OmtiSec].GadgetText->FrontPen   = 2;
	if(OmtiInt  != -1) IntGad[OmtiInt].GadgetText->FrontPen   = 2;

	OmtiFlag =	OMTIUNITFLAG |
				OMTISTEPFLAG |
				OMTIHEADFLAG |
				OMTICYLFLAG  |
				OMTIPREFLAG  |
				OMTIPARKFLAG |
				OMTIINTFLAG  |
				OMTISECFLAG;

	OmtiStep    = ParaBlock->pb_step % 6;

	OmtiHead    = (ParaBlock->pb_heads + 16) % 16;

	OmtiPre     = ParaBlock->pb_wrpre;
	OmtiParkCyl = ParaBlock->pb_parkcyl;

	if(ParaBlock->pb_sectors == 17)
		OmtiSec = 0;
	else if(ParaBlock->pb_sectors == 26)
		OmtiSec = 1;
	else
	{
		OmtiSec = -1;
		OmtiFlag &= ~OMTISECFLAG;
	}

	if(ParaBlock->pb_interleave < 3)
		OmtiInt = ParaBlock->pb_interleave;
	else
	{
		OmtiInt = -1;
		OmtiFlag &= ~OMTIINTFLAG;
	}

	OmtiHiCyl   = ParaBlock->pb_hicyl;
	OmtiWrCu    = ParaBlock->pb_wrcur;
	OmtiWrCyl   = ParaBlock->pb_wrcyl;

	StepGad[OmtiStep].GadgetText->FrontPen = 3;

	if(OmtiSec != -1) SecGad[OmtiSec].GadgetText->FrontPen = 3;
	if(OmtiInt != -1) IntGad[OmtiInt].GadgetText->FrontPen = 3;

	sprintf(HeadGad.SpecialInfo->Buffer,"%d",OmtiHead);
	sprintf(CylGad.SpecialInfo->Buffer, "%d",OmtiHiCyl);
	sprintf(PreGad.SpecialInfo->Buffer, "%d",OmtiPre);
	sprintf(ParkGad.SpecialInfo->Buffer,"%d",OmtiParkCyl);
}

void	DisplayErrList(start,nof)
int	start,		/* Von hier an anzeigen */
	nof;		/* maximale Fehlerzahl */
{
register	COUNT	i;
	for(i=0;i<20;i++,start++)
	{
		if(start<nof)
			sprintf(ErrText.IText," %2d    %3d",ErrList[start][0],ErrList[start][1]);
		else
			strcpy(ErrText.IText,"          ");
		PrintIText(WRP,&ErrText,412,14+i*8);
	}
}

main()
{
struct	IntuiMessage	*Message;
ULONG					 Signal,UserBit;
ULONG					 GadgetID;
BOOL					 EndeFlag = FALSE;
TEXT					 FileName[30];
UBYTE					 ParaBlock[PARABLOCKSIZE];
FILE					*fp;
register	COUNT		 i,j;
int						 NofErr,StartErr;
UWORD					 AltTrack;
UBYTE					 AltHead;

/* Die Drive-Parameter */

	if(OpenAll())
		CloseAll();

/* Hauptschirm aufbauen */

	WRP	= Window->RPort;
	WVP		= &((*(Window->WScreen)).ViewPort);
	ColMap	= WVP->ColorMap;
	for(i=0;i<4;i++)
	{
		SaveColors[i]=GetRGB4(ColMap,i);
		SetRGB4(WVP,i,MyColors[i][0],MyColors[i][1],MyColors[i][2]);
	}

	sprintf(ConIText.IText,"Controller at %lx",(Controller = omtibase));

/* 1. Controller-Adresse */

	DrawBorder(WRP,&LargeRender,10,3);
	PrintIText(WRP,&ConIText,13,8);

/* 2. Unit-Requester */

	DrawBorder(WRP,&LargeRender,10,21);
	PrintIText(WRP,&UnitIText,13,26);
	AddGList(Window,&UnitGad[1],-1,-1,NULL);

/* 3. Steprate */

	DrawBorder(WRP,&LargeRender,10,39);
	PrintIText(WRP,&StepIText,13,44);
	AddGList(Window,&StepGad[5],-1,-1,NULL);

/* 4. Heads */

	DrawBorder(WRP,&LargeRender,10,57);
	PrintIText(WRP,&HeadIText,13,62);
	AddGadget(Window,&HeadGad,-1);

/* 5. NumCyl */

	DrawBorder(WRP,&LargeRender,10,75);
	PrintIText(WRP,&CylIText,13,80);
	AddGadget(Window,&CylGad,-1);

/* 5aa WrCyl */

	DrawBorder(WRP,&LargeRender,10,93);
	DrawBorder(WRP,&NumRender,130,98);
	PrintIText(WRP,&WrCylIText,13,98);

/* 5a. WrPre */

	DrawBorder(WRP,&LargeRender,10,111);
	PrintIText(WRP,&PreIText,13,116);
	AddGadget(Window,&PreGad,-1);

/* 5b. ParkCyl */

	DrawBorder(WRP,&LargeRender,10,129);
	PrintIText(WRP,&ParkIText,13,134);
	AddGadget(Window,&ParkGad,-1);

/* 6. NumSec */

	DrawBorder(WRP,&LargeRender,10,147);
	PrintIText(WRP,&SecIText,13,153);
	AddGList(Window,&SecGad[1],-1,-1,NULL);

/* 7. InterLeave */

	DrawBorder(WRP,&LargeRender,10,165);
	PrintIText(WRP,&IntIText,13,170);
	AddGList(Window,&IntGad[2],-1,-1,NULL);

/* 8. Click-Gadgets fuer Operationen */

	AddGList(Window,&OrgGad[6],-1,-1,NULL);

/* 9. ErrTrack-Block */

	DrawBorder(WRP,&ErrRender,408,3);
	PrintIText(WRP,&ErrText,410,5);
	AddGList(Window,&ErrGad[1],-1,-1,NULL);

/* 10. Format-Block */

	DrawBorder(WRP,&FmtRender,177,109);

	RefreshScreen();

/* Intui-Schleife */

	UserBit	 = (1L << Window->UserPort->mp_SigBit);

	while(!EndeFlag)
	{
		Signal = Wait(UserBit);
 		if(Signal & UserBit)
			while(Message = (struct IntuiMessage *)(GetMsg(Window->UserPort)))
			{
				if(Message->Class == CLOSEWINDOW)
					EndeFlag = TRUE;
				if(Message->Class == GADGETUP)
				{
					GadgetID = ((struct Gadget *)Message->IAddress)->GadgetID;
					switch(GadgetID)
					{
						case 100:
						case 101:
						{
							GadgetID -= 100;
							if(OmtiUnit != -1) UnitGad[OmtiUnit].GadgetText->FrontPen = 2;
							UnitGad[GadgetID].GadgetText->FrontPen = 3;
							OmtiUnit = GadgetID;
							OmtiFlag |= OMTIUNITFLAG;
							break;
						}
						case 200:
						case 201:
						case 202:
						case 203:
						case 204:
						case 205:
						{
							GadgetID -= 200;
							if(OmtiStep != -1) StepGad[OmtiStep].GadgetText->FrontPen = 2;
							StepGad[GadgetID].GadgetText->FrontPen = 3;
							OmtiStep = GadgetID;
							OmtiFlag |= OMTISTEPFLAG;
							break;
						}
						case 300:
						{
							OmtiHead = ((struct Gadget *)Message->IAddress)->SpecialInfo->LongInt;
							if((OmtiHead < 1) || (OmtiHead > 16))
							{
								OmtiHead = -1;
								DisplayBeep(Window->WScreen);
								OmtiFlag &= ~OMTIHEADFLAG;
								ActivateGadget(&HeadGad,Window,NULL);
							}
							else
							{
								OmtiHead %= 16; /* Heads 16 -> 0 */
								OmtiFlag |= OMTIHEADFLAG;
								ActivateGadget(&CylGad,Window,NULL);
							}
						break;
						}
						case 400:
						{
							OmtiHiCyl = ((struct Gadget *)Message->IAddress)->SpecialInfo->LongInt;
							if((OmtiHiCyl < 1) || (OmtiHiCyl > MAXCYL))
							{
								OmtiHiCyl = -1;
								DisplayBeep(Window->WScreen);
								OmtiFlag &= ~OMTICYLFLAG;
								ActivateGadget(&CylGad,Window,NULL);
							}
							else
							{
								OmtiFlag |= OMTICYLFLAG;
								ActivateGadget(&PreGad,Window,NULL);
								OmtiWrCyl = OmtiHiCyl;			/* Bei Eingabe: Hoechster Cyl ist hoechster Schreibbarer Cyl */
							}
							break;
						}
						case 410:
						{
							OmtiPre = ((struct Gadget *)Message->IAddress)->SpecialInfo->LongInt;
							if((OmtiPre < 1) || (OmtiPre > MAXCYL))
							{
								OmtiPre = -1;
								DisplayBeep(Window->WScreen);
								OmtiFlag &= ~OMTICYLFLAG;
								ActivateGadget(&PreGad,Window,NULL);
							}
							else
							{
								OmtiFlag |= OMTIPREFLAG;
								ActivateGadget(&ParkGad,Window,NULL);
							}
							break;
						}
						case 420:
						{
							OmtiParkCyl = ((struct Gadget *)Message->IAddress)->SpecialInfo->LongInt;
							if((OmtiParkCyl < 0) || (OmtiParkCyl > MAXCYL))
							{
								OmtiParkCyl = -1;
								DisplayBeep(Window->WScreen);
								OmtiFlag &= ~OMTIPARKFLAG;
								ActivateGadget(&ParkGad,Window,NULL);
							}
							else
							{
								OmtiFlag |= OMTIPARKFLAG;
							}
							break;
						}
						case 500:
						case 501:
						{
							GadgetID -= 500;
							if(OmtiSec != -1) SecGad[OmtiSec].GadgetText->FrontPen = 2;
							SecGad[GadgetID].GadgetText->FrontPen = 3;
							OmtiSec = GadgetID;
							OmtiFlag |= OMTISECFLAG;
							break;
						}
						case 600:
						case 601:
						case 602:
						{
							GadgetID -= 600;
							if(OmtiInt != -1) IntGad[OmtiInt].GadgetText->FrontPen = 2;
							IntGad[GadgetID].GadgetText->FrontPen = 3;
							OmtiInt = GadgetID;
							OmtiFlag |= OMTIINTFLAG;
							break;
						}
						case 701:
						{
							if(!((OmtiFlag & (OMTIUNITFLAG | OMTIHEADFLAG | OMTICYLFLAG)) == (OMTIUNITFLAG | OMTIHEADFLAG | OMTICYLFLAG))) /* Unit wird benoetigt */
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								sprintf(FileName,"%s/ErrorList.%d",OMTIPFAD,OmtiUnit);
								if(NULL == (fp = (FILE *)fopen(FileName,"r")))
									MyRequest("Dateifehler:",FileName);
								else
								{
									fread(ErrIDTx,strlen(ERRID),1,fp);
									if(strncmp(ERRID,ErrIDTx,strlen(ERRID)))
									{
										fclose(fp);
										MyRequest("Keine Error-Liste:",FileName);
										OmtiErrList = -1;
									}
									else
									{
										fscanf(fp,"%d",&NofErr);
										for(i=0;i<NofErr;i++)
											fscanf(fp,"%d,%d",&ErrList[i][0],&ErrList[i][1]);
										fclose(fp);
										OmtiErrList = OmtiUnit;
										if(NofErr)	OmtiWrCyl = OmtiHiCyl - (NofErr + OmtiHead) / OmtiHead;
										DisplayErrList((StartErr=0),NofErr);
									}
								}
							}
							break;
						}
						case 702:
						{
							if(!((OmtiFlag & OMTIUNITFLAG) == OMTIUNITFLAG) || !(OmtiErrList == OmtiUnit)) /* Unit wird benoetigt */
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								sprintf(FileName,"%s/ErrorList.%d",OMTIPFAD,OmtiUnit);
								if(NULL == (fp = (FILE *)fopen(FileName,"w")))
									MyRequest("Dateifehler:",FileName);
								else
								{
									fprintf(fp,"%s\n",ERRID);
									fprintf(fp,"%d\n",NofErr);
									for(i=0;i<NofErr;i++)
										fprintf(fp,"%d,%d\n",ErrList[i][0],ErrList[i][1]);
									fclose(fp);
								}
							}
							break;
						}
						case 703:
						{
							if(!((OmtiFlag & (OMTIUNITFLAG | OMTISTEPFLAG)) == (OMTIUNITFLAG | OMTISTEPFLAG)))
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								DisableOmtiController();
								Disable();
								ReadParaBlock(ParaBlock);
								Enable();
								if(strncmp(PARAID,ParaBlock,4))
									MyRequest("Kein PARA-Block",NULL);
								else
									SetUpParameter(ParaBlock);
							}
							break;
						}
						case 704:
						{
							if(!((OmtiFlag & (ALLFLAGS | OMTIINTFLAG)) == (ALLFLAGS | OMTIINTFLAG)))
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								SetUpPARABlock(ParaBlock);
								DisableOmtiController();
								Disable();
								WriteParaBlock(ParaBlock);
								Enable();
							}
							break;
						}
						case 705:
						{
/* Get Parameter from File */
							if(!((OmtiFlag & OMTIUNITFLAG) == OMTIUNITFLAG)) /* Unit wird benoetigt */
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								sprintf(FileName,"%s/ParaBlock.%d",OMTIPFAD,OmtiUnit);
								if(NULL == (fp = (FILE *)fopen(FileName,"r")))
									MyRequest("Dateifehler:",FileName);
								else
								{
									fread(ParaBlock,PARABLOCKSIZE,1,fp);
									fclose(fp);
									if(strncmp(PARAID,ParaBlock,4))
										MyRequest("Keine PARA-Datei:",FileName);
									else
										SetUpParameter(ParaBlock);
								}
							}
							break;
						}
						case 706:
						{
/* Save Parameter to File */
							if(!((OmtiFlag & ALLFLAGS) == ALLFLAGS))
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								SetUpPARABlock(ParaBlock);
								sprintf(FileName,"%s/ParaBlock.%d",OMTIPFAD,OmtiUnit);
								if(NULL == (fp = (FILE *)fopen(FileName,"w")))
									MyRequest("Dateifehler:",FileName);
								else
								{
									fwrite(ParaBlock,PARABLOCKSIZE,1,fp);
									fclose(fp);
								}
							}
							break;
						}
						case 707:
						{
							if(!((OmtiFlag & (ALLFLAGS | OMTIINTFLAG)) == (ALLFLAGS | OMTIINTFLAG)))
							{
								DisplayBeep(Window->WScreen);
							}
							else
							{
								SetAPen(WRP,0);
								RectFill(WRP,178,110,404,185);
								DisableOmtiController();
								PrintIText(WRP,&InitText,179,111);
								InitDrive();
								PrintIText(WRP,&FormatText,179,119);
								FormatDrive();
								PrintIText(WRP,&AssignText,179,127);
								AltTrack = OmtiHiCyl-1;
								AltHead  = 0;
								for(i=0;i<NofErr;i++)
								{
									sprintf(AssText.IText,"Assign: %2d/%4d -> %2d/%4d",ErrList[i][0],ErrList[i][1],AltHead,AltTrack);
									PrintIText(WRP,&AssText,179,135);
									AltHead	= ++AltHead % OmtiHead;
									if(AltHead == 0)	AltTrack--;
									AssignATrack(ErrList[i][0],ErrList[i][1],AltHead,AltTrack);
								}
								PrintIText(WRP,&VerifyText,179,143);
								for(i=0;i<OmtiWrCyl;i++)
									for(j=0;j<OmtiHead;j++)
									{
										sprintf(VerText.IText,"Verify: %2d/%4d",j,i);
										PrintIText(WRP,&VerText,179,151);
										VerifyATrack(i,j);
									}
								PrintIText(WRP,&BlockText,179,159);
								SetUpPARABlock(ParaBlock);
								WriteParaBlock(ParaBlock);
								PrintIText(WRP,&EndeText,179,168);
							}
							break;
						}
						case 800:
						{
							StartErr = (StartErr >= 20) ? (StartErr-20) : 0;
							DisplayErrList(StartErr,NofErr);
							break;
						}
						case 801:
						{
							if(StartErr+20 < NofErr)
								StartErr += 20;
							DisplayErrList(StartErr,NofErr);
							break;
						}

						default:
							break;
					}
					RefreshScreen();
				}
				ReplyMsg(Message);
			}
	}
	RemoveGList(Window,&UnitGad[1],-1);
	for(i=0;i<4;i++)
		SetRGB4(WVP,i,(SaveColors[i] >> 8) & 0xf,(SaveColors[i] >> 4) & 0xf,SaveColors[i] & 0xf);
	CloseAll();
}
