#include <libraries/zbbs.h>
#include "protos.h"
#include "globals.c"

enum { ARG_CONFIG, ARG_DEPTH, ARG_KEEPIO, ARG_ANSWER, ARG_IMMEDIATE, ARGS };
#define ARGTEMPLATE "C=CONFIG/K,D=DEPTH/N,K=KEEPIO/S,A=ANSWER/S,I=IMMEDIATE/S"

VOID Init(VOID);
VOID error(STRPTR);
VOID __saveds Handler(VOID);
struct Process *SegmentSplit(STRPTR, BYTE, LONG, APTR);

LONG __saveds main()
{
	SysBase		= *(struct ExecBase **)4;
	ThisProcess	= (struct Process *)SysBase->ThisTask;

	if(!ThisProcess->pr_CLI)
	{
		WaitPort(&ThisProcess->pr_MsgPort);
		WBenchMsg = GetMsg(&ThisProcess->pr_MsgPort);
	}
	else	WBenchMsg = NULL;

	if(!(DOSBase = OpenLibrary("dos.library", 0)))					error("dos.library");
	if(!(ZBBSBase = OpenLibrary("zbbs.library", 0)))				error("zbbs.library");
	if(!(IntuitionBase = OpenLibrary("intuition.library", 0)))	error("intuition.library");

	if(SysBase->LibNode.lib_Version < 36)
	{
		STATIC struct IntuiText BodyText = {0, 1, JAM1, 5, 3, NULL, "Kickstart 2.04 or higher required.", NULL};
		STATIC struct IntuiText OkayText = {0, 1, JAM1, 6, 3, NULL, "Okay", NULL};
		struct Window *Window;

		if(ThisProcess->pr_CLI)	ThisProcess->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
		if(Window = BuildSysRequest(NULL, &BodyText, NULL, &OkayText, GADGETUP, 301, 46))
		{
			struct IntuiMessage *Message;

			ScreenToFront(Window->WScreen);
			DisplayBeep(Window->WScreen);

			WaitPort(Window->UserPort);
			if(Message = GetMsg(Window->UserPort))	ReplyMsg(Message);

			FreeSysRequest(Window);
		}
		error(NULL);
	}

	depth = 3;
	keepio = FALSE;
	answer = FALSE;
	strcpy(configfile, "BBS:Config");

	if(ThisProcess->pr_CLI)
	{
		UBYTE **ArgArray;

		if(ArgArray = AllocVec(sizeof(UBYTE *) * ARGS, MEMF_ANY | MEMF_CLEAR))
		{
			struct RDArgs *ArgsPtr;

			if(ArgsPtr = AllocVec(sizeof(struct RDArgs), MEMF_ANY | MEMF_CLEAR))
			{
				if(ReadArgs(ARGTEMPLATE, (LONG *)ArgArray, ArgsPtr))
				{
					if(ArgArray[ARG_CONFIG])	strcpy(configfile, ArgArray[ARG_CONFIG]);
					if(ArgArray[ARG_ANSWER])	answer = TRUE;
					if(ArgArray[ARG_KEEPIO])	keepio = TRUE;
					if(ArgArray[ARG_DEPTH])	depth = *((LONG *)ArgArray[ARG_DEPTH]);
					if(depth < 1)	depth = 1;
					if(depth > 6)	depth = 6;
				}
				else
				{
					PrintFault(IoErr(), "Z-BBS");

					FreeArgs(ArgsPtr);
					FreeVec(ArgsPtr);
					FreeVec(ArgArray);
					error(NULL);
				}
				FreeArgs(ArgsPtr);
				FreeVec(ArgsPtr);
			}
			FreeVec(ArgArray);
		}

		if(keepio && ((struct CommandLineInterface *)BADDR(ThisProcess->pr_CLI))->cli_DefaultStack < 4096)
		{
			MyEasyRequest("Sorry, the Shell stack must be at least 16384 bytes large", "Okay");
			error(NULL);
		}

		if(keepio)	Handler();
		else
		{
			if(!SegmentSplit("Z-BBS", 0, 16384, Handler))
				error("new process");
		}
	}
	else
	{
		LONG StackSize;

		StackSize = (LONG)SysBase->ThisTask->tc_SPUpper - (LONG)SysBase->ThisTask->tc_SPLower;

		if(StackSize < 16384)
		{
			MyEasyRequest("The current stack size of %ld bytes is too low,\nplease edit the icon file to use at least\n16384 bytes and restart the proram.", "Okay", StackSize);
			error(NULL);
		}
		CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);

		Handler();
	}

	return(RETURN_OK);
}

VOID __saveds Handler()
{
	Init();

	FOREVER
	{
		User.level		= 0;
		wait_buffer[0]	= 0;
		In(80, 4);

		out_buffer[0] = '\n';
		if(Status.window)
		{
			WriteCON->io_Command	=	CMD_WRITE;
			WriteCON->io_Data		=	out_buffer;
			WriteCON->io_Length	=	1;
			DoIO(WriteCON);
		}

		if(instr(wait_buffer, "RING"))
		{
			Location("RING");
			ATCmd(Config.answer);
		}
		if(instr(wait_buffer, "CONNECT"))
		{
			connected	= TRUE;
			ser_out		= TRUE;

			baud = Config.baud;
			if(strstr(wait_buffer, "19200"))	baud = 19200;
			if(strstr(wait_buffer, "16800"))	baud = 16800;
			if(strstr(wait_buffer, "14400"))	baud = 14400;
			if(strstr(wait_buffer, "9600"))	baud = 9600;
			if(strstr(wait_buffer, "4800"))	baud = 4800;
			if(strstr(wait_buffer, "2400"))	baud = 2400;
			if(strstr(wait_buffer, "1200"))	baud = 1200;
			if(strstr(wait_buffer, "FAX"))
			{
				Location(wait_buffer);

				KillSer();
				ShowPrg(Config.fax_command);
				KillSer();

				QueueSerial();
				HangUp();
			}

			if(baud <= 2400)						Status.b_2400++;
			if(baud <= 9600 && baud > 2400)	Status.b_9600++;
			if(baud >  9600)						Status.b_19200++;
		}
		if(strstr(wait_buffer, "NO CARRIER"))
		{
			connected	= FALSE;
			baud			= Config.baud;
			SetSerial();
		}
		if(strstr(wait_buffer, "ERROR"))	HangUp();

		if(connected || login)
		{
			Location((connected ? wait_buffer : "Lokaler Logon"));

			realbaud = baud;
			if(Config.lock_baud)	baud = Config.baud;
			SetSerial();

			OnLine();

			if(do_sort)
			{
				ATCmd(Config.busy);
				ShowPrg("ZSort C=%ls F=%lsPUFFER N=%ls POINT PRI=%ld S=%ld", configfile, Config.temp, User.alias, Config.priority, (LONG)Scr);
				HangUp();
				do_sort = FALSE;
			}

			Location("----------------");
		}
	}
}

STATIC VOID __saveds __asm ProcessCleanup(register __d1 BPTR SegList)
{
	Forbid();
	UnLoadSeg(SegList);

	CloseLibrary(DOSBase);
}

struct Process *SegmentSplit(STRPTR Name, BYTE Pri, LONG StackSize, APTR Function)
{
	struct Process			*Child;
	struct CommandLineInterface	*CLI;

	CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase->ThisTask)->pr_CLI);
	if(Child = (struct Process *)CreateNewProcTags(
		NP_CommandName,	"Z-BBS "VERSION,
		NP_Name,				Name,
		NP_Priority,		Pri,
		NP_StackSize,		StackSize,
		NP_Entry,			Function,
		NP_Cli,				TRUE,
		NP_ExitCode,		ProcessCleanup,
		NP_ExitData,		CLI->cli_Module,
		TAG_DONE))
	{
		CLI -> cli_Module = NULL;
		return(Child);
	}
	else	return(NULL);
}

VOID error(STRPTR meldung)
{
	if(meldung)
	{
		if(IntuitionBase)	MyEasyRequest("ERROR : Couldn't open %ls.", "Abort", meldung);
		else Printf("ERROR: Couldn't open %ls.", meldung);
	}

	if(Font)	CloseFont(Font);

	if(ReadSER && ReadSER->IOSer.io_Device)
	{
		KillSer();
		CloseDevice(ReadSER);
	}
	if(serial_in)	FreeVec(serial_in);

	if(ReadCON && ReadCON->io_Device)
	{
		AbortIO(ReadCON);
		WaitIO(ReadCON);
		CloseDevice(ReadCON);
	}

	if(DoTime && DoTime->tr_node.io_Device)
	{
		AbortIO(DoTime);
		WaitIO(DoTime);
		CloseDevice(DoTime);
	}

	if(DoAudio)
	{
		CloseDevice(DoAudio);
		DeleteIORequest(DoAudio);
	}

	if(WriteCON)			DeleteIORequest(WriteCON);
	if(ReadCON)				DeleteIORequest(ReadCON);
	if(WriteSER)			DeleteIORequest(WriteSER);
	if(ReadSER)				DeleteIORequest(ReadSER);
	if(DoTime)				DeleteIORequest(DoTime);

	if(WritePortCON)		DeleteMsgPort(WritePortCON);
	if(ReadPortCON)		DeleteMsgPort(ReadPortCON);
	if(WritePortSER)		DeleteMsgPort(WritePortSER);
	if(ReadPortSER)		DeleteMsgPort(ReadPortSER);
	if(TimerPort)			DeleteMsgPort(TimerPort);
	if(AudioPort)			DeleteMsgPort(AudioPort);
	if(RexxPort)			DeletePort(RexxPort);

	if(Win1)					ClearMenuStrip(Win1);
	if(menu)					FreeMenus(menu);
	if(Win1)					CloseWindow(Win1);
	if(Win2)					CloseWindow(Win2);
	if(Scr)					CloseScreen(Scr);
	if(VisualInfo)			FreeVisualInfo(VisualInfo);
	if(AslFileRequest)	FreeAslRequest(AslFileRequest);

	RemList(&ProtocolList);
	RemList(&FileList);
	RemList(&MenuList);

	if(RexxBase)			CloseLibrary(RexxBase);
   if(GadToolsBase)  	CloseLibrary(GadToolsBase);
	if(AslBase)				CloseLibrary(AslBase);
	if(DiskfontBase)		CloseLibrary(DiskfontBase);
	if(GfxBase)				CloseLibrary(GfxBase);
	if(IntuitionBase)		CloseLibrary(IntuitionBase);
	if(ZBBSBase)			CloseLibrary(ZBBSBase);

	if(keepio)
	{
		SetTaskPri(FindTask(NULL), 0);
		if(DOSBase)	CloseLibrary(DOSBase);
	}

	if(WBenchMsg)
	{
		if(DOSBase)	CloseLibrary(DOSBase);
		Forbid();
		ReplyMsg(WBenchMsg);
	}

	Exit(NULL);
}

VOID Init()
{
	UWORD Pens[] = { 0, 6, 7, 7, 4, 6, 4, 0, 2, ~0 };
	struct ColorSpec colspec[17];
	char file[256];
	LONG i;

	STATIC struct NewMenu newmenu[] =
	{
		{ NM_TITLE, "Mailbox",			0, 0, 0, NULL },
			{ NM_ITEM, "Palette",		0, 0, 0, (APTR)MEN_PALETTE},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "QUIT",			"Q", 0, 0, (APTR)MEN_QUIT},

		{ NM_TITLE, "Misc",				0, 0, 0, NULL },
			{ NM_ITEM, "Login",			"L", 0, 0, (APTR)MEN_LOGIN},
			{ NM_ITEM, "Sysop",			"S", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_SYSOP},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "Chat",			"C", 0, 0, (APTR)MEN_CHAT},
			{ NM_ITEM, "+10 min",		"+", 0, 0, (APTR)MEN_PLUS},
			{ NM_ITEM, "-10 min",		"-", 0, 0, (APTR)MEN_MINUS},

		{ NM_TITLE, "Modem",				0, 0, 0, NULL },
			{ NM_ITEM, "Hang Up",		"H", 0, 0, (APTR)MEN_HANGUP},
			{ NM_ITEM, "send ATA",		"A", 0, 0, (APTR)MEN_ATA},
			{ NM_ITEM, "Busy Out",		"B", 0, 0, (APTR)MEN_BUSY},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "Terminal",		"T", 0, 0, (APTR)MEN_TERMINAL},

		{ NM_TITLE, "Data Flow",		0, 0, 0, NULL },
			{ NM_ITEM, "Window",			"W", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_WINDOW},
			{ NM_ITEM, "Keyboard",		"K", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_KEYBOARD},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "Input",			"I", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_INPUT},
			{ NM_ITEM, "Output",			"O", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_OUTPUT},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "Capture",		"D", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_CAPTURE},
			{ NM_ITEM, "Printer",		"P", MENUTOGGLE | CHECKIT, 0, (APTR)MEN_PRINTER},

		{ NM_TITLE, "Transfer",			0, 0, 0, NULL },
			{ NM_ITEM, "Send File",		"Y", 0, 0, (APTR)MEN_SEND},
			{ NM_ITEM, "Receive File",	"X", 0, 0, (APTR)MEN_RECEIVE},
			{ NM_ITEM, "Protocol",		"F", 0, 0, (APTR)MEN_PROTOCOL},
			{ NM_ITEM, NM_BARLABEL,		0, 0, 0, NULL },
			{ NM_ITEM, "Send ASCII",	"Z", 0, 0, (APTR)MEN_ASCII},

		{ NM_TITLE, "User",				0, 0, 0, NULL },
			{ NM_ITEM, NULL,				"1", 0, 0, (APTR)MEN_USER1},
			{ NM_ITEM, NULL,				"2", 0, 0, (APTR)MEN_USER2},
			{ NM_ITEM, NULL,				"3", 0, 0, (APTR)MEN_USER3},
			{ NM_ITEM, NULL,				"4", 0, 0, (APTR)MEN_USER4},
			{ NM_ITEM, NULL,				"5", 0, 0, (APTR)MEN_USER5},
			{ NM_ITEM, NULL,				"6", 0, 0, (APTR)MEN_USER6},
			{ NM_ITEM, NULL,				"7", 0, 0, (APTR)MEN_USER7},
			{ NM_ITEM, NULL,				"8", 0, 0, (APTR)MEN_USER8},
			{ NM_ITEM, NULL,				"9", 0, 0, (APTR)MEN_USER9},
			{ NM_ITEM, NULL,				"0", 0, 0, (APTR)MEN_USER10},

		{ NM_END, 0, 0, 0, 0, (APTR)0 }
	};

	ThisProcess = (struct Process *)SysBase -> ThisTask;

	if(!GetConfig(configfile, &Config, &Status))	error(NULL);
	SetTaskPri(FindTask(NULL), Config.priority);

	NewList(&ProtocolList);
	SPrintf(file, "%lsProtocolData", Config.system);
	if(!GetProtocolList(file, &ProtocolList))	error("ProtocolData");

	if(!(GfxBase = OpenLibrary("graphics.library", 0)))		error("graphics.library");
	if(!(RexxBase = OpenLibrary("rexxsyslib.library", 0)))	error("rexxsyslib.library");
	if(!(DiskfontBase = OpenLibrary("diskfont.library", 0)))	error("diskfont.library");
	if(!(AslBase = OpenLibrary("asl.library", 0)))				error("asl.library");
	if(!(GadToolsBase = OpenLibrary("gadtools.library", 0)))	error("gadtools.library");

	if(!(AslFileRequest = AllocAslRequest(ASL_FileRequest, 0)))
		error("asl-filerequest");

	FontAttr.ta_Name	= Config.fontname;
	FontAttr.ta_YSize	= Config.fontsize;

	if(!(Font = (struct TextFont *)OpenDiskFont(&FontAttr)))
		error(Config.fontname);

	number = 0;
	RexxPort = NULL;
	i = FALSE;
	do
	{
		SPrintf(rexx_name, "rexx_zbbs%ld", ++number);

		Forbid();
		i = (LONG)FindPort(rexx_name);
		if(!i)	RexxPort = CreatePort(rexx_name, NULL);
		Permit();
	}	while(!i);
	if(!RexxPort)	error("rexx-port");

	i = 0;
	while(i < (1 << depth) && i < 16)
	{
		colspec[i].ColorIndex	= i;
		colspec[i].Red				= (Status.colors[i] >> 8) & 0xF;
		colspec[i].Green			= (Status.colors[i] >> 4) & 0xF;
		colspec[i].Blue			= Status.colors[i] & 0xF;
		i++;
	}
	colspec[i].ColorIndex	= -1;

	if(depth < 3)	Pens[0] = ~0;

	if(!(Scr = OpenScreenTags(NULL,
		SA_Title,		"Z-BBS "VERSION,
		SA_Overscan,	OSCAN_TEXT,
		SA_DisplayID,	DEFAULT_MONITOR_ID | HIRES | (Config.interlaced ? LACE : NULL),
		SA_ShowTitle,	!Config.backdrop,
		SA_Depth,		depth,
		SA_AutoScroll,	TRUE,
		SA_Colors,		colspec,
		SA_Pens,			&Pens,
		SA_DetailPen,	(depth > 1 ? 6 : 1),
		SA_BlockPen,	0,
		SA_Font,			&FontAttr,
		TAG_END)))	error("screen");

	if(!(Win1 = OpenWindowTags(NULL,
		WA_Top,				1,
		WA_Left,				0,
		WA_Width,			Scr->Width,
		WA_Height,			Scr->Height - (Config.backdrop ? 63 : 74),
		WA_MinWidth,		45,
		WA_MaxWidth,		Scr->Width,
		WA_MinHeight,		20,
		WA_MaxHeight,		Scr->Height,
		WA_SmartRefresh,	TRUE,
		WA_AutoAdjust,		TRUE,
		WA_Activate,		TRUE,
		WA_Backdrop,		Config.backdrop,
		WA_Borderless,		Config.backdrop,
		WA_DragBar,			!Config.backdrop,
		WA_DepthGadget,	!Config.backdrop,
		WA_SizeGadget,		!Config.backdrop,
		WA_Title,			(Config.backdrop ? NULL: "Data-Window"),
		WA_CustomScreen,	Scr,
		WA_IDCMP,			IDCMP_MENUPICK,
		TAG_DONE)))	error("data-window");

	if(!(Win2 = OpenWindowTags(NULL,
		WA_Top,				Scr->Height - (Config.backdrop ? 62 : 75),
		WA_Left,				0,
		WA_Width,			Scr->Width,
		WA_Height,			(Config.backdrop ? 62 : 75),
		WA_MinWidth,		45,
		WA_MaxWidth,		Scr->Width,
		WA_MinHeight,		20,
		WA_MaxHeight,		100,
		WA_SmartRefresh,	TRUE,
		WA_AutoAdjust,		TRUE,
		WA_Activate,		FALSE,
		WA_Backdrop,		Config.backdrop,
		WA_Borderless,		Config.backdrop,
		WA_DragBar,			!Config.backdrop,
		WA_DepthGadget,	!Config.backdrop,
		WA_SizeGadget,		!Config.backdrop,
		WA_GimmeZeroZero,	!Config.backdrop,
		WA_Title,			(Config.backdrop ? NULL : "Info-Window"),
		WA_CustomScreen,	Scr,
		WA_IDCMP,			IDCMP_ACTIVEWINDOW,
		TAG_DONE)))	error("info-window");

	if(!(VisualInfo = (APTR)GetVisualInfo(Scr, TAG_DONE)))
		error("visual info");

	NewList(&MenuList);
	SPrintf(file, "%lsMenuData", Config.system);
	GetLineList(file, &MenuList);

	if(GetHead(&MenuList))
	{
		struct Line *line;

		i = 0;
		line = GetHead(&MenuList);
		while(line && i < 10)
		{
			if(line->text[0])
				newmenu[33 + i++].nm_Label		= line->text;
			else
			{
				newmenu[33 + i].nm_Label		= NM_BARLABEL;
				newmenu[33 + i].nm_CommKey		= NULL;
				newmenu[33 + i++].nm_UserData	= NULL;
			}

			line = GetSucc(line);
			line = GetSucc(line);
		}
		if(i < 10)
		{
			newmenu[33 + i].nm_Type 		= NM_END;
			newmenu[33 + i].nm_Label		= NULL;
			newmenu[33 + i].nm_CommKey		= NULL;
			newmenu[33 + i].nm_Flags		= NULL;
			newmenu[33 + i].nm_UserData	= (APTR)NULL;
		}
	}

	if(!(menu = CreateMenus(newmenu, GTMN_FrontPen, 7, TAG_DONE)))
		error("menus");

	if(!LayoutMenus(menu, VisualInfo, GTMN_TextAttr, &FontAttr, TAG_DONE))
		error("menu layout");

	if(!(serial_in = AllocVec(Config.ser_read_size + 8, MEMF_ANY | MEMF_CLEAR)))
		error("serial buffer");

	WritePortCON	= CreateMsgPort();
	ReadPortCON		= CreateMsgPort();
	WritePortSER	= CreateMsgPort();
	ReadPortSER		= CreateMsgPort();
	TimerPort		= CreateMsgPort();
	AudioPort		= CreateMsgPort();

	if(!WritePortCON || !ReadPortCON ||
		!WritePortSER || !ReadPortSER ||
		!TimerPort    || !AudioPort)
		error("ports");

	WriteCON	= CreateIORequest(WritePortCON, sizeof(struct IOStdReq));
	ReadCON	= CreateIORequest(ReadPortCON, sizeof(struct IOStdReq));
	WriteSER	= CreateIORequest(WritePortSER, sizeof(struct IOExtSer));
	ReadSER	= CreateIORequest(ReadPortSER, sizeof(struct IOExtSer));
	DoTime	= CreateIORequest(TimerPort, sizeof(struct timerequest));
	DoAudio	= CreateIORequest(AudioPort, sizeof(struct IOAudio));

	if(!WriteCON || !ReadCON ||
		!WriteSER || !ReadSER ||
		!DoTime   || !DoAudio)
		error("io's");

	ReadCON->io_Data		= (APTR)Win1;
	ReadCON->io_Length	= sizeof(*Win1);
	if(OpenDevice("console.device", 0, ReadCON, NULL))
		error("console.device");
	WriteCON->io_Device	= ReadCON->io_Device;
	WriteCON->io_Unit		= ReadCON->io_Unit;
	QueueConsole();

	ReadSER->io_SerFlags	|= SERF_SHARED;
	ReadSER->io_Baud		= Config.baud;
	if(Config.rts_cts)	ReadSER->io_SerFlags |= SERF_7WIRE;
	if(OpenDevice(Config.device, Config.unit, ReadSER, NULL))
		error(Config.device);
	WriteSER->IOSer.io_Device	= ReadSER->IOSer.io_Device;
	WriteSER->IOSer.io_Unit		= ReadSER->IOSer.io_Unit;

	ReadSER->IOSer.io_Command	=	CMD_READ;
	ReadSER->IOSer.io_Data		=	(APTR)serial_in;
	ReadSER->IOSer.io_Length	=	1;
	SendIO(ReadSER);

	if(OpenDevice(TIMERNAME, UNIT_VBLANK, DoTime, NULL))
		error("timer.device");
	DoTime->tr_node.io_Command	= TR_ADDREQUEST;
	DoTime->tr_node.io_Flags	=
	DoTime->tr_node.io_Error	= 0;
	QueueTimer();

	if(OpenDevice(AUDIONAME, 0, DoAudio, NULL))
		error("audio.device");
	DoAudio->ioa_Data											= &AnyChannel[0];
	DoAudio->ioa_Length										= 4;
	DoAudio->ioa_Request.io_Command						= ADCMD_ALLOCATE;
	DoAudio->ioa_Request.io_Message.mn_Node.ln_Pri	= 10;
	if(DoIO(DoAudio))	error("audio alloc");
	DoAudio->ioa_Request.io_Command	= CMD_WRITE;
	DoAudio->ioa_Request.io_Flags		= ADIOF_PERVOL;
	DoAudio->ioa_Period					= 223;
	DoAudio->ioa_Volume					= 64;
	DoAudio->ioa_Cycles					= 150;
	DoAudio->ioa_Data						= &SineWave[0];
	DoAudio->ioa_Length					= 8;

	CurrentTime(&time_now, &micros);
	time_last = time_now;

	SetMenuStrip(Win1, menu);
	GetDate();
	Location("*** MAILBOX GESTARTET ***");

	NewList(&FileList);

	do_sort = FALSE;
	baud = Config.baud;
	SetSerial();

	date_time.dat_StrDay		= dayname;
	date_time.dat_StrDate	= date;
	date_time.dat_StrTime	= time;
	date_time.dat_Format		= FORMAT_CDN;
	date_time.dat_Flags		= DTB_SUBST;

	RangeSeed = time_now;

	ser_out = FALSE;
	MyPrintf("\33[0;37m");

	HangUp();
	ShowSystem();

	if(answer)
	{
		Location("RING");
		ATCmd(Config.answer);
	}
	ClearDevs();
}
