/* PopInfo v2.9 © Copyright 1989 Jonathan Potter

   Compiles with Manx C v3.6a - the makefile is included in the archive.

   This program is Public Domain - use it, don't abuse it.

   Jon. */

#include "PopInfo.h"

main(argc,argv)
int argc;
char *argv[];
{
	int message,code;
	int wmess;
	virusdesc[1]="  Not recognised as a virus.  ";
	virusdesc[2]="    SCA virus recognised!!    ";
	virusdesc[3]="BYTE BANDIT virus recognised!!";
	virusdesc[4]="BYTE WARRIOR virus recognised!";
	virusdesc[5]=" NORTHSTAR virus recognised!! ";
	virusdesc[6]="  REVENGE virus recognised!!  ";
	virusdesc[7]="  OBELISK virus recognised!!  ";
	virusdesc[8]=" PENTAGON virus recognised!!! ";
	virusdesc[9]=" SYSTEM Z virus recognised!!! ";
	virusdesc[10]="    UF VIRUS recognised!!!    ";
	virusdesc[11]="    HCS VIRUS recognised!!    ";
	virusdesc[12]="DISK-DOKTOR VIRUS recognised!!";
	virusdesc[13]="LAMER EX'TOR VIRUS recognised!";
	virusdesc[14]=" ULTRAFOX VIRUS recognised!!  ";
	virusdesc[15]=" GRAFFITI VIRUS recognised!!  ";
	virusdesc[16]="16 BIT CREW VIRUS recognised!!";
	virusdesc[17]=" PHANTASM VIRUS recognised!!  ";
	virusdesc[18]="OLD N. STAR VIRUS recognised!!";
	OpenAll();
	KillMemory();
	Window=(struct Window *) OpenWindow(&SWindow);
	if (Window==NULL) CloseUp(10);
	(void) SetTaskPri(FindTask((char *) 0), 20);
	scr=Window->WScreen;
	ScreenHeight=scr->Height;
	checkbbs=0;
	if (argc>=1 && (strncmp(argv[1],"-n",2))==0) checkbbs=1;
	numdevs=countdevices();
	oldtop=10; oldleft=0; oldw=639; oldh=50+(9*numdevs);
	maxnumdevs=(ScreenHeight-50)/9;
	onumdevs=numdevs;

	for(;;) {
		waitaround:
		if (((struct Window *) IntuitionBase->ActiveWindow)!=Window && flag==1
				&& popflag==0) goto inactivate;
		if (flag==1) OnGadget(&popstaygad,Window,NULL);
		wmess=Wait(WINDOWMESSAGE | TIMERMESSAGE);
		if (wmess&TIMERMESSAGE) {
			Msg=GetMsg(TimerPort);
			if (flag==1) goto partialrefresh;
			TimeReq.tr_time.tv_secs=0;
			TimeReq.tr_time.tv_micro=1000000;
			SendIO((char *) &TimeReq.tr_node);
			goto waitaround;
		}
		Msg=GetMsg(Window->UserPort);
		message=Msg->Class;
		code=Msg->Code;
		ReplyMsg(Msg);
		switch (message) {

			case CLOSEWINDOW:

				CloseUp(0);

			case GADGETUP:

				if (flag==1) {
					if (popflag==0) popflag=1;
					else popflag=0;
					goto waitaround;
				}
				flag=1;
				CloseWindow(Window);
				numdevs=countdevices();
				if (numdevs!=onumdevs) {
					if (oldh==(50+(9*onumdevs))) oldh=50+(9*numdevs);
					onumdevs=numdevs;
				}
				if (numdevs>maxnumdevs) numdevs=maxnumdevs;
				MWindow.TopEdge=oldtop;
				MWindow.LeftEdge=oldleft;
				MWindow.Width=oldw;
				MWindow.Height=oldh;
				MWindow.MaxHeight=50+(9*numdevs);
				if (oldh==(50+(9*onumdevs)))
					MWindow.Height=50+(9*numdevs);
				if (ScreenHeight-oldtop<50+(9*numdevs) && onumdevs!=numdevs)
					MWindow.TopEdge=(ScreenHeight-(50+(9*numdevs)));
				onumdevs=numdevs;
				Window=(struct Window *) OpenWindow(&MWindow);
				if (Window==NULL) CloseUp(10);
				SetWindowTitles(Window,-1,wintit);
				refreshwindow:
				sbbflag=0;
				cidcmp(0);
				OffGadget(&popstaygad,Window,NULL);
				SetAPen(iprint,0);
				RectFill(iprint,6,10,Window->Width-3,Window->Height-11);
				RectFill(iprint,17,Window->Height-10,Window->Width-17,Window->Height-2);
				SetAPen(iprint,3);
				mesg.FrontPen=3;
				sprintf(txt,"Unit Bytes     Used      Free      Ers WPS SBB Name");
				PrintIText(iprint,&mesg,-4,1);
				mesg.FrontPen=2;
				sprintf(txt,"____ _________ _________ _________ ___ ___ ___ ______________________________");
				PrintIText(iprint,&mesg,-4,2);
				mesg.FrontPen=1;
				y=12;
				Forbid();
				devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
				while (devlist) {
					if (devlist->dl_Type!=DLT_DEVICE) {
						devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
						continue;
					}
					conbstr((BPTR) devlist->dl_Name,devname);
					strcat(devname,":");
					if (devlist->dl_Task) {
						point1[0]=0;
						dnum=-1; nodisk=0; nondos=0; bbmess="N/A"; status="R/W";
						if (devname[0]==68 && devname[1]==70) dnum=devname[2]-48;
						if (dnum!=-1) {
							if (checkbbs==1) bbmess="N/C"; else bbmess="Yes";
							nodisk=diskpresent(dnum);
							if (nodisk==1) goto display;
							if (checkbbs!=1) {
								ReadBlock(dnum);
								point2=diskbuffer;
								point1=diskbuffer;
								if (point1[0]!=ID_DOS_DISK) {
									nondos=2;
									if (point1[0]==ID_UNREADABLE_DISK) nondos=1;
									if (point1[0]==ID_KICKSTART_DISK) nondos=3;
									goto display;
								}
								sum=0;
								for (a=0;a<256;a++) {
									lastsum=sum;
									sum=sum+point2[a];
									if (lastsum>sum) sum++;
								}
								if (sum!=0) {
									nsbb[dnum]=0;
									bbmess="NBB";
									goto display;
								}
								point2=&diskbuffer[4];
								for (x=0;x<39;x++) {
									if (diskbuffer[x+8]!=bootblock[x+8]) {
										nsbb[dnum]=1;
										sbbflag=1;
										bbmess="No";
										break;
									}
								}
								if ((CheckBlock(1))==FALSE) bbmess="VIR";
							}
						}
					display:
					if (nodisk==1) sprintf(txt,"%-4s No disk present in drive.", devname);
					else if (nondos==1)	sprintf(txt,"%-4s Unreadable disk.", devname);
					else if (nondos==2) sprintf(txt,"%-4s Not a DOS disk.", devname);
					else if (nondos==3)	sprintf(txt,"%-4s Kickstart disk.", devname);
					if (nodisk==0 && nondos==0) {
						if ((lock=Lock(devname,ACCESS_READ))==0) {
							nondos=1; goto display;
						}
						Info(lock,data);
						Examine(lock,finfo);
						if (data->id_DiskState==ID_VALIDATING)
							sprintf(txt,"%-4s Validating.", devname);
						else {
							volumename=finfo->fib_FileName;
							if ((strncmp(devname,"RAM:",4))==0 && volumename==NULL)
								volumename="RAM Disk";
							if (data->id_DiskState==ID_WRITE_PROTECTED) status="R O";
							sprintf(txt,"%-4s %-9ld %-9ld %-9ld %-3ld %-3s %-3s %-30s",
								devname,
								data->id_BytesPerBlock*data->id_NumBlocks,
								data->id_BytesPerBlock*data->id_NumBlocksUsed,
								(data->id_BytesPerBlock*data->id_NumBlocks)-
									(data->id_BytesPerBlock*data->id_NumBlocksUsed),
								data->id_NumSoftErrors,
								status,
								bbmess,
								volumename);
						}
					}
					PrintIText(iprint,&mesg,-4,y);
					if (nodisk==0 && nondos==0) {
						if (nsbb[dnum]>0) {
							sprintf(txt,"                                           %-3s",bbmess);
							if (nsbb[dnum]==1) mesg.FrontPen=2;
							else mesg.FrontPen=3;
							PrintIText(iprint,&mesg,-4,y);
							mesg.FrontPen=1;
							nsbb[dnum]=0;
						}
						UnLock(lock);
					}
					nondos=0; nodisk=0; dnum=0; y+=9;
				}
			devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
			}
			Permit();
			fast=FASTMEMORY;
			chip=CHIPMEMORY;
			total=TOTALMEMORY;
			DateStamp(&now);
			hours=HOURS;
			mins=MINS;
			secs=SECS;
			y+=5;
			mesg.FrontPen=2;
			sprintf(txt,"            FREE MEMORY      :             :             :");
			PrintIText(iprint,&mesg,-4,y);
			mesg.FrontPen=3;
			sprintf(txt,"                         FAST          CHIP         TOTAL");
   		PrintIText(iprint,&mesg,-4,y);
			mesg.FrontPen=1;
			sprintf(txt,"                              %-7ld       %-6ld        %-7ld",
				fast,chip,total);
			PrintIText(iprint,&mesg,-4,y);
			mesg.FrontPen=3;
			sprintf(txt,"                              TIME");
			PrintIText(iprint,&mesg,-4,y+9);
			mesg.FrontPen=2;
			sprintf(txt,"                                      :  :");
			PrintIText(iprint,&mesg,-4,y+9);
			mesg.FrontPen=1;
			sprintf(txt,"                                    %02d %02d %02d",
 			  hours,mins,secs);
			PrintIText(iprint,&mesg,-4,y+9);
			RefreshGadgets(Window->FirstGadget,Window,NULL);
			SizeWindow(Window,0,0);
			OnGadget(&popstaygad,Window,NULL);
			cidcmp(1);
			goto waitaround;

			case RAWKEY:
				if (code!=0x40) goto waitaround;
				oldtop=Window->TopEdge;
				oldleft=Window->LeftEdge;
				oldh=Window->Height;
				oldw=Window->Width;
				SWindow.TopEdge=oldtop;
				SWindow.LeftEdge=oldleft;
				CloseWindow(Window);
				Window=(struct Window *) OpenWindow(&LWindow);
				ViewBoot(0);
				Window=(struct Window *) OpenWindow(&MWindow);
				if (Window==NULL) CloseUp(10);
				goto refreshwindow;

			case INACTIVEWINDOW:

				inactivate:
				if (popflag==1) goto waitaround;
				if (flag==0) goto waitaround;
				flag=0;
				oldtop=Window->TopEdge;
				oldleft=Window->LeftEdge;
				oldh=Window->Height;
				oldw=Window->Width;
				CloseWindow(Window);
				SWindow.TopEdge=oldtop;
				SWindow.LeftEdge=oldleft;
				Window=(struct Window *) OpenWindow(&SWindow);
				if (Window==NULL) CloseUp(10);
				goto waitaround;

			case REFRESHWINDOW:

				if (oldh!=Window->Height || oldw!=Window->Width) {
					numdevs=countdevices();
					WindowLimits(Window,0,0,0,(50+(9*numdevs)));
					oldh=Window->Height;
					oldw=Window->Width;
					goto refreshwindow;
				}
				goto waitaround;

			case DISKINSERTED:

				if (flag==1)
					goto refreshwindow;
				goto waitaround;

			case DISKREMOVED:

				if (flag==1) goto refreshwindow;
				goto waitaround;

			case MOUSEBUTTONS:

				if (Msg->Code==MENUDOWN) goto refreshwindow;
				goto waitaround;

			default:
			goto waitaround;
		}

		partialrefresh:
			RemoveGadget(Window,&popstaygad);
			mesg.DrawMode=JAM2;
			mesg.FrontPen=1;
			fast=FASTMEMORY;
			chip=CHIPMEMORY;
			total=TOTALMEMORY;
			DateStamp(&now);
			hours=HOURS;
			mins=MINS;
			secs=SECS;
			sprintf(txt,"%-7ld",fast);
			PrintIText(iprint,&mesg,236,y);
			sprintf(txt,"%-6ld",chip);
			PrintIText(iprint,&mesg,348,y);
			sprintf(txt,"%-7ld",total);
			PrintIText(iprint,&mesg,460,y);
			sprintf(txt,"%02d",hours);
			PrintIText(iprint,&mesg,284,y+9);
			sprintf(txt,"%02d",mins);
			PrintIText(iprint,&mesg,308,y+9);
			sprintf(txt,"%02d",secs);
			PrintIText(iprint,&mesg,332,y+9);
			mesg.DrawMode=JAM1;
			AddGadget(Window,&popstaygad,-1);
			TimeReq.tr_time.tv_secs=0;
			TimeReq.tr_time.tv_micro=1000000;
			SendIO((char *) &TimeReq.tr_node);
			if (onumdevs!=countdevices()) {
				numdevs=countdevices();
				MWindow.MaxHeight=50+(9*numdevs);
				if (Window->Height==(50+(9*onumdevs)))
					MWindow.Height=50+(9*numdevs);
				if (ScreenHeight-oldtop<50+(9*numdevs) && onumdevs!=numdevs)
				MWindow.TopEdge=(ScreenHeight-(50+(9*numdevs)));
				if (Window->TopEdge+(50+(9*numdevs))>ScreenHeight) 
					MoveWindow(Window,0,(0-((Window->TopEdge)-(ScreenHeight-(50+(9*numdevs))))));
				SizeWindow(Window,0,((50+(9*numdevs))-(Window->Height))); 
				onumdevs=numdevs;
				goto refreshwindow;
			}
			onumdevs=countdevices();
			goto waitaround;
	}
}

OpenAll()
{
	IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
	if (IntuitionBase==NULL) CloseUp(20);
	GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
	if (GfxBase==NULL) CloseUp(25);
	DosBase=(struct DosLibrary *) OpenLibrary("dos.library",0);
	if (DosBase==NULL) CloseUp(30);
	diskport=CreatePort(0,0);
	if (diskport==NULL) CloseUp(35);
	diskreq=CreateStdIO(diskport);
	if (diskreq==NULL) CloseUp(40);
	lock=(struct FileLock *) AllocMem(sizeof(struct FileLock),0);
	if (lock==NULL) CloseUp(10);
	data=(struct InfoData *) AllocMem(sizeof(struct InfoData),0);
	if (data==NULL) CloseUp(10);
	finfo=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),0);
	if (finfo==NULL) CloseUp(10);
	TimerPort=CreatePort("Timer Port",0);
	if (TimerPort==NULL) CloseUp(45);
	error=OpenDevice("timer.device",UNIT_VBLANK,(char *) &TimeReq,0);
	if (error!=NULL) CloseUp(50);
	TimeReq.tr_node.io_Message.mn_ReplyPort=TimerPort;
	TimeReq.tr_node.io_Command=TR_ADDREQUEST;
	TimeReq.tr_node.io_Flags=0;
	TimeReq.tr_node.io_Error=0;
	TimeReq.tr_node.tv_secs=0;
	TimeReq.tr_node.tv_micro=1000000;
	SendIO((char *) &TimeReq.tr_node);
	rootnode=(struct RootNode *) DosBase->dl_Root;
	dosinfo-(struct DosInfo *) BADDR(rootnode->rn_Info);
}

CloseUp(err)
{
	if (Window) CloseWindow(Window);
	AbortIO((char *) &TimeReq.tr_node);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
	if (GfxBase) CloseLibrary(GfxBase);
	if (DosBase) CloseLibrary(DosBase);
	CloseDevice(&TimeReq);
	DeletePort(TimerPort);
	DeletePort(diskport);
	DeleteStdIO(diskreq);
	OpenWorkBench();
	if (err!=0) DisplayBeep(NULL);
	exit(err);
}

conbstr(in,out)
BSTR in;
char *out;
{
	register UBYTE *ch;
	register int len,i;
	ch=(UBYTE *) BADDR(in);
	len=(int) *(ch++);
	len=(len>20)?20:len;
	for (i=0;i<len;i++) out[i]=*(ch++);
	out[i]='\0';
}

countdevices()
{
	int devices;
	devices=0;
	Forbid();
	rootnode=(struct RootNode *) DosBase->dl_Root;
	dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
	devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
	while (devlist) {
		if (devlist->dl_Type!=NULL) {
			devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
			continue;
		}
		if (DLT_DEVICE!=NULL || devlist->dl_Task) ++devices;
		devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
	}
	Permit();
	return(devices);
}

diskpresent(drive)
int drive;
{
	int nd;
	nd=0;
	error=OpenDevice("trackdisk.device",drive,diskreq,0);
	diskreq->io_Command=TD_CHANGESTATE;
	DoIO(diskreq);
	if (diskreq->io_Actual!=0) nd=1;
	CloseDevice(diskreq);
	return(nd);
}

ReadBlock(drive)
int drive;
{
	int l;
	for (l=0;l<1024;l++) diskbuffer[l]=0;
	error=OpenDevice("trackdisk.device",drive,diskreq,0);
	diskreq->io_Command=CMD_READ;
	diskreq->io_Data=diskbuffer;
	diskreq->io_Length=1024;
	diskreq->io_Offset=0;
	DoIO(diskreq);
	diskreq->io_Length=0;
	diskreq->io_Command=TD_MOTOR;
	DoIO(diskreq);
	CloseDevice(diskreq);
}

cidcmp(state)
int state;
{
	if (state==0) {
		ModifyIDCMP(Window,NULL);
		return();
	}
	ModifyIDCMP(Window,CLOSEWINDOW|INACTIVEWINDOW|GADGETUP|DISKINSERTED|
		RAWKEY|DISKREMOVED|REFRESHWINDOW|MOUSEBUTTONS);
	return();
}

ViewBoot(c)
int c;
{
	struct Gadget *gad;
	int q, gadgetid, block;
	CheckDriveGadgets();
	nsbb[c]=0;
	y=0;
	ReadBlock(c);
	DisplayBoot(0); block=0; blktext.IText="BLK1"; CheckBlock();
	RefreshGadgets(&blkgadget,Window,NULL);
	for (;;) {
		Wait(1<<Window->UserPort->mp_SigBit);
		while (Msg=GetMsg(Window->UserPort)) {
			ReplyMsg(Msg);
			gad=(struct Gadget *) Msg->IAddress;
			gadgetid=gad->GadgetID;
			switch (gadgetid) {
				case EXIT:
					CloseWindow(Window);
					return(FALSE);
					break;
				case BLK:
					if (block==0) block=1; else block=0;
					if (block==1) blktext.IText="BLK0"; else blktext.IText="BLK1";
					RefreshGadgets(&blkgadget,Window,NULL);
					DisplayBoot(block);
					break;
				case DF0:
					ReadBlock(0); c=0;
					DisplayBoot(0); block=0; blktext.IText="BLK1";
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				case DF1:
					ReadBlock(1); c=1;
					DisplayBoot(0); block=0; blktext.IText="BLK1"; 
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				case DF2:
					ReadBlock(2); c=2;
					DisplayBoot(0); block=0; blktext.IText="BLK1"; 
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				case DF3:
					ReadBlock(3); c=3;
					DisplayBoot(0); block=0; blktext.IText="BLK1"; 
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				case WIPE:
					WipeBoot(c);
					ReadBlock(c);
					DisplayBoot(0); block=0; blktext.IText="BLK1"; 
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				case SAVE:
					SaveBoot();
					break;
				case LOAD:
					LoadBoot(c);
					ReadBlock(c);
					DisplayBoot(0); block=0; blktext.IText="BLK1";
					RefreshGadgets(&blkgadget,Window,NULL);
					CheckBlock();
					break;
				default:
					break;
			}
		}
	}
}

DisplayBoot(which)
int which;
{
	int a,s;
	if (which==0) a=0; else a=512; s=a;
	SetAPen(iprint,0);
	RectFill(iprint,5,2,579,140);
	RectFill(iprint,5,130,637,198);
	SetAPen(iprint,1);
	for (y=-9;y<=111;y=y+8) {
		sprintf(txt,"%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
			diskbuffer[a],diskbuffer[a+1],diskbuffer[a+2],
			diskbuffer[a+3],diskbuffer[a+4],diskbuffer[a+5],
			diskbuffer[a+6],diskbuffer[a+7],diskbuffer[a+8],
			diskbuffer[a+9],diskbuffer[a+10],diskbuffer[a+11],
			diskbuffer[a+12],diskbuffer[a+13],diskbuffer[a+14],
			diskbuffer[a+15]);
		PrintIText(iprint,&mesg,0,y);
		sprintf(txt,"%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
			diskbuffer[a+16],diskbuffer[a+17],diskbuffer[a+18],
			diskbuffer[a+19],diskbuffer[a+20],diskbuffer[a+21],
			diskbuffer[a+22],diskbuffer[a+23],diskbuffer[a+24],
			diskbuffer[a+25],diskbuffer[a+26],diskbuffer[a+27],
			diskbuffer[a+28],diskbuffer[a+29],diskbuffer[a+30],
			diskbuffer[a+31]);
		PrintIText(iprint,&mesg,288,y);
		a+=32;
	}
	Move(iprint,10,140);
	Text(iprint,&diskbuffer[s],78);
	Move(iprint,10,149);
	Text(iprint,&diskbuffer[s+78],78);
	Move(iprint,10,158);
	Text(iprint,&diskbuffer[s+156],78);
	Move(iprint,10,167);
	Text(iprint,&diskbuffer[s+234],78);
	Move(iprint,10,176);
	Text(iprint,&diskbuffer[s+312],78);
	Move(iprint,10,185);
	Text(iprint,&diskbuffer[s+390],78);
	Move(iprint,141,194);
	Text(iprint,&diskbuffer[s+468],44);
}

WipeBoot(c)
int c;
{
	error=YesNo(" Really install this disk?");
	if (error==FALSE) return();
	error=OpenDevice("trackdisk.device",c,diskreq,0);
	tryagain:
	diskreq->io_Command=TD_PROTSTATUS;
	DoIO(diskreq);
	if (diskreq->io_Actual!=0) {
		error=YesNo(" Disk is write protected!!");
		if (error==TRUE) goto tryagain;
		CloseDevice(diskreq);
		return();
	}
	for (x=0;x<1024;x++)
		diskbuffer[x]=0;
	CopyMem(bootblock,diskbuffer,50);
	diskreq->io_Length=1024;
	diskreq->io_Data=&diskbuffer[0];
	diskreq->io_Command=CMD_WRITE;
	diskreq->io_Offset=0;
	DoIO(diskreq);
	diskreq->io_Command=CMD_UPDATE;
	DoIO(diskreq);
	diskreq->io_Command=TD_MOTOR;
	diskreq->io_Length=0;
	DoIO(diskreq);
	nsbb[dnum]=0;
	return();
}

SaveBoot()
{
	opensavefile:
	filename=gf("Enter filename for Save",170,70);
	if (filename==NULL) return();
	bbsavefile=fopen(filename,"w");
	if (bbsavefile==NULL) {
		error=YesNo("Can't open specified file!!");
		if (error==FALSE) return();
		goto opensavefile;
	}
	for (x=0;x<1024;x++)
	putc(diskbuffer[x],bbsavefile);
	fclose(bbsavefile);
	return();
}

LoadBoot(unit)
int unit;
{
	char c;
	int x;

	openloadfile:
	filename=gf("Enter filename for Load",170,70);
	if (filename==NULL) return();
	bbsavefile=fopen(filename,"r");
	if (bbsavefile==NULL) {
		error=YesNo("Can't open specified file!!");
		if (error==FALSE) return();
		goto openloadfile;
	}
	for (x=0;x<1024;x++)
		diskbuffer[x]=getc(bbsavefile);
	fclose(bbsavefile);
	error=OpenDevice("trackdisk.device",unit,diskreq,0);
	tryagain:
	diskreq->io_Command=TD_PROTSTATUS;
	DoIO(diskreq);
	if (diskreq->io_Actual!=0) {
		error=YesNo(" Disk is write protected!!");
		if (error==TRUE) goto tryagain;
		CloseDevice(diskreq);
		return();
	}
	error=YesNo("  Really write bootblock?");
	if (error==FALSE) {
		CloseDevice(diskreq);
		return();
	}
	diskreq->io_Length=1024;
	diskreq->io_Data=&diskbuffer[0];
	diskreq->io_Command=CMD_WRITE;
	diskreq->io_Offset=0L;
	DoIO(diskreq);
	diskreq->io_Command=CMD_UPDATE;
	DoIO(diskreq);
	diskreq->io_Length=0;
	diskreq->io_Command=TD_MOTOR;
	DoIO(diskreq);
	CloseDevice(diskreq);
	return();
}

CheckDriveGadgets()
{
	int c;
	OnGadget(&df0gadget,Window,NULL);
	OnGadget(&df1gadget,Window,NULL);
	OnGadget(&df2gadget,Window,NULL);
	OnGadget(&df3gadget,Window,NULL);
	for (c=0;c<4;c++) {
		error=OpenDevice("trackdisk.device",c,diskreq,0);
		if (error!=0) {
			switch (c) {
				case 0:
					OffGadget(&df0gadget,Window,NULL);
					break;
				case 1:
					OffGadget(&df1gadget,Window,NULL);
					break;
				case 2:
					OffGadget(&df2gadget,Window,NULL);
					break;
				case 3:
					OffGadget(&df3gadget,Window,NULL);
					break;
				default:
					break;
			}
		}
		else CloseDevice(diskreq);
	}
}

CheckBlock(state)
int state;
{
	nsbb[dnum]=0;
	if (diskbuffer[8]=='C' &&
			diskbuffer[9]=='H' &&
			diskbuffer[10]=='W' &&
			diskbuffer[11]=='!') nsbb[dnum]=2;
	if (diskbuffer[43]=='9' &&
			diskbuffer[44]=='.' &&
			diskbuffer[45]=='8' &&
			diskbuffer[46]=='7') nsbb[dnum]=3;
	if (diskbuffer[192]=='D' &&
			diskbuffer[193]=='A' &&
			diskbuffer[194]=='S' &&
			diskbuffer[195]=='A')	nsbb[dnum]=4;
	if (diskbuffer[42]=='N' &&
			diskbuffer[43]=='o' &&
			diskbuffer[44]=='r' &&
			diskbuffer[45]=='t') nsbb[dnum]=5;
	if (diskbuffer[14]=='I' &&
			diskbuffer[15]=='D' &&
			diskbuffer[16]=='9') nsbb[dnum]=6;
	if (diskbuffer[56]=='G' &&
			diskbuffer[188]=='S' &&
			diskbuffer[507]=='d' &&
			diskbuffer[45]=='P') nsbb[dnum]=7;
	if (diskbuffer[64]==0xff &&
			diskbuffer[65]==0xa0 &&
			diskbuffer[66]==0x20 &&
			diskbuffer[67]==0x40)	nsbb[dnum]=8;
	if (diskbuffer[368]==0xfe &&
			diskbuffer[369]==0x3a &&
			diskbuffer[370]==0x4c &&
			diskbuffer[371]==0xdf) nsbb[dnum]=9;
	if (diskbuffer[288]==0x33 &&
			diskbuffer[289]==0xfc &&
			diskbuffer[290]==0xf6 &&
			diskbuffer[291]==0xd5) nsbb[dnum]=10;
	if (diskbuffer[336]==0x66 &&
			diskbuffer[337]==0x62 &&
			diskbuffer[338]==0x48 &&
			diskbuffer[339]==0xe7) nsbb[dnum]=11;
	if (diskbuffer[112]==0x41 &&
			diskbuffer[113]==0xfa &&
			diskbuffer[114]==0x03 &&
			diskbuffer[115]==0x5e) nsbb[dnum]=12;
	if (diskbuffer[64]==0x03 &&
			diskbuffer[65]==0x61 &&
			diskbuffer[66]==0x34 &&
			diskbuffer[67]==0x3c) nsbb[dnum]=13;
	if (diskbuffer[464]==0x83 &&
			diskbuffer[465]==0x35 &&
			diskbuffer[466]==0x3e &&
			diskbuffer[467]==0xf0) nsbb[dnum]=14;
	if (point1[84]==0x000100bf) nsbb[dnum]=15;
	if (point1[84]==0x3fff2c78) nsbb[dnum]=16;
	if (point1[16]==0x4240323c) nsbb[dnum]=17;
	if (point1[16]==0x0007ec1a) nsbb[dnum]=18;
	if (nsbb[dnum]==0) return(TRUE);
	if (state==1) return(FALSE);
	CWindow=(struct Window *) OpenWindow(&WWindow);
	Move(cprint,25,17);
	Text(cprint,virusdesc[nsbb[c]],30);
	Wait(1<<CWindow->UserPort->mp_SigBit);
	nsbb[dnum]=0;
	CloseWindow(CWindow);
	return(TRUE);
}

KillMemory()
{
	int temp;
	struct ExecBase *ExecBase;
	unsigned int *LongMemPointer, *ptr, x;
	unsigned short *loc, *wordpointer;
	unsigned long TD, *open, *entry, *oldopen;
	char linebuffer[80];
	char *a;
	long *src, *dest, *vbase, *array;
	int f,num;
	UWORD *wordptr;
	ExecBase=OpenLibrary("exec.library",0);
	LongMemPointer=FindName(&ExecBase->DeviceList,"trackdisk.device");
	array=4; array=array[0]; num=array; num=num-0x196;
	open=num; entry=open[0]; oldopen=entry+0x12;
	if (entry[0]=0x2f3a0010) {
		open[0]=oldopen[0];
		ExecBase->KickTagPtr=0;
	}
	temp=LongMemPointer;
	temp=temp-0x1c;
	LongMemPointer=temp;
	VirusBase=(*LongMemPointer)-0x1b8;
	LongMemPointer=VirusBase;
	if (*LongMemPointer==ID_DOS_DISK) {

		#asm
		xdef _VirusBase
		xref _geta4
		xref _LVODisable
		xref _LVOEnable
		jsr _geta4
		move.l 4,a6
		jsr _LVODisable(a6)
		move.l _VirusBase,a0
		move.w #$4e71,d0
		move.w d0,$aa(a0)
		move.w d0,$ac(a0)
		move.w d0,$ae(a0)
		move.w d0,$b0(a0)
		move.w #$6000,$1c2(a0)
		move.w #$6000,$2d2(a0)
		move.w #$4e75,$388(a0)
		move.w #0,(a0)
		jsr _LVOEnable(a6)
		#endasm

	};
	TD=FindName(&ExecBase->DeviceList,"trackdisk.device");
	x=TD; x=x-0x1c;
	LongMemPointer=x; LongMemPointer=LongMemPointer[0];
	x=LongMemPointer; x=x-0x17c;
	LongMemPointer=x;
	if (*LongMemPointer=ID_DOS_DISK) {
		*LongMemPointer=0;
		vbase=LongMemPointer;
		Disable();
		src=&vbase[234];
		a=ExecBase; a=a-0x264;
		dest=a; *dest=*src;
		Enable();
		ExecBase->KickTagPtr=0;
	}
	if (ExecBase->CoolCapture==0x7e060) {
		ExecBase->CoolCapture=0;

		#asm
		xref _LVODisable
		xref _LVOEnable
		move.l 4,a6
		jsr _LVODisable(a6)
		lea $7e000,a0
		move.l #0,(a0)
		move.w #$4ef9,$1e0(a0)
		move.w #$7,$1e2(a0)
		move.w #$e066,$1e4(a0)
		move.w #$4ef9,$2da(a0)
		move.w #$7,$2dc(a0)
		move.w #$e06c,$2de(a0)
		jsr _LVOEnable(a6)
		#endasm

	};
	if (ExecBase->CoolCapture==0x7ec64) {
		ExecBase->CoolCapture=0;
		x=ExecBase; x=x-0x1c6;
		ptr=x;
		LongMemPointer=0x7ef9c;
		*ptr=*LongMemPointer;
	}
	wordpointer=ExecBase->CoolCapture;
	if (*wordpointer==0x2c79) {
		if (wordpointer[3]==0x203c) {
			Disable();
			f=ExecBase; f=f-0x1c6;
			LongMemPointer=x;
			wordpointer=*LongMemPointer;
			f=wordpointer; f=f+0x15c;
			wordpointer=f; *wordpointer=0x4e75;
			f=wordpointer;
			f=f+0x1e2;
			wordpointer=f; *wordpointer=0x4e75;
			f=ExecBase; f=f-0x1c6;
			ptr=x;
			f=*ptr; f=f+2;
			LongMemPointer=f;
			*ptr=*LongMemPointer;
			Enable();
		}
	}
	if (ExecBase->CoolCapture=0x7ed36) {
		ExecBase->CoolCapture=0;
		x=ExecBase;
		x=x-0x1c6;
		ptr=x;
		wordptr=ptr;
		if (wordptr[0]==0x0007) {
			LongMemPointer=0x7eb38;
			*ptr=*LongMemPointer;
		}
	}
	if (ExecBase->CoolCapture==0x7e86c) {
		ExecBase->CoolCapture=0;
		ptr=0x7e88a;
		Forbid();
		ptr[0]=10;
		Permit();
	}
	ExecBase->ColdCapture=0;
	ExecBase->CoolCapture=0;
	ExecBase->WarmCapture=0;
	CloseLibrary(ExecBase);
	return();
}
