 #include <exec/execbase.h>
 #include <exec/resident.h>
 #include <intuition/intuition.h>
 #include <ctype.h>

 #define NL 0

 extern struct ExecBase *SysBase;
 extern APTR BootBlocks[];

 /************
 *  C H E C K   M E M O R Y   O N   V I R U S E S 
 \******************/


CheckMem()
{
 	struct Resident *Res;

    if (SysBase->CoolCapture == (APTR) 0x7ec3e)
	{		/*kill SCA-Virus */
#asm
	movem.l	d0-d7/a0-a6,-(sp)
	move.l	4,a6
	clr.l	46(a6)
	lea		34(a6),a0
	clr.w	d0
	moveq	#$17,d1
chksum
	add.w	(a0)+,d0
	dbra	d1,chksum
	not.w	d0
	move.w	d0,(a0)
	movem.l	(sp)+,d0-d7/a0-a6
#endasm
		PrintMessage(14);
		ClrMem ((UBYTE *) 0x7ec00);
		return(0);
	}
	Res = (struct Resident *) *(SysBase->KickTagPtr);
	if (*(Res->rt_Init) == 0x207c0007)
	{
#asm	
	movem.l	d0-d7/a0-a6,-(sp)
	move.l	4,a6
	clr.l	550(a6)
	jsr		-612(a6)
	move.l	d0,554(a6)
	movem.l	(sp)+,d0-d7-a0-a6
#endasm
		SetFunction (SysBase,-456L,(LONG) 0xfc06dc);
		ClrMem ((UBYTE *) ((Res->rt_Init)-0x54));
		PrintMessage(16);
		return (0);
	}
	if (*(Res->rt_Init) == 0x41fa0046)
	{
#asm
	movem.l	d0-d7/a0-a6,-(sp)
	move.l	4,a6
	move.l	148(a6),a0
	move.l	$110(a0),148(a6)
	move.l	$10c(a0),a4
	lea		$e6(a0),a1
	lea		350(a6),a0
	jsr		-276(a6)
	move.l	d0,a0
	move.l	a4,-28(a0)
	clr.l	550(a6)
	jsr		-612(a6)
	move.l	d0,554(a6)
	movem.l	(sp)+,d0-d7/a0-a6
#endasm
		ClrMem ((UBYTE *) (Res->rt_Init)-0x388);
		PrintMessage (18);
		return (0);
	}
}
ClrMem (start)
UBYTE *start;
{
	int i;

	for (i=0; i<0x400; i++)
		*(start++) = 0;
}

unsigned long BBsum (BB)
unsigned long *BB;
{
   unsigned long prec, sum;
   int i;

   sum = prec = 0;

   for (i=0;i<256;i++)
   {
      sum += BB[i];
      if (sum < prec)
         ++sum;
      prec = sum;
   }
   return (0xffffffff - sum);
}


CheckBB()
{
	if (*(BootBlocks[3]+0x4)==0x43f90007)
	{
		PrintMessage(15);	/* SCA-Virus on disk */
		return;
	}
	if (*(BootBlocks[3]+0x26) == 0xfd9c2d40)
	{
		PrintMessage(17);	/* ByteWarrior on disk */
		return;
	}
	if (*(BootBlocks[3]+0x6c) == 0xfd9c2d40)
	{
		PrintMessage(19);	/* ByteBandit on disk */
		return;
	}
	if (*(BootBlocks[3]+0xff) == 0x0007f400)
	{
		PrintMessage(20);	/* ABC-Virus on disk */
		return;
	}
	if ((*(BootBlocks[3]+0x9) == 0x4eaefd9c) ||
		(*(BootBlocks[3]+0x12) == 0xfd9c2d40) ||
		(*(BootBlocks[3]+0xb) == 0x332e3020))
	{
		PrintMessage(13);	/* an old AntiVirus on disk */
		return;
	}
	if ((*(BootBlocks[3]+0xb) == 0x342e3020) ||
		(*(BootBlocks[3]+0xb) == 0x342e3120))
	{
		PrintMessage(9);	/* AntiVirus on disk */
		return;
	}
	if (BBComp (BootBlocks[0]+3, BootBlocks[3]+3, 19))
	{
		PrintMessage (10);
		return;
	}
	if (BBComp (BootBlocks[1]+3, BootBlocks[3]+3, 25))
	{
		PrintMessage (11); /* Sound BB */
		return;
	}
	if (BBsum(BootBlocks[3]))
	{
		PrintMessage (8);
		return;
	}
	PrintMessage(12);

}

int BBComp(source1, source2, num)
UBYTE *source1, *source2;
int num;
{
	int i;
	for (i=0;i < num; i++)
		if (*source1++ != *source2++)
			return (0);				/* 0 is ongelijk */
	return (1);
}

UBYTE Str80[80];

/*******************************
*  N E W   W I N D O W   F O R   A S C I I   D U M P 
\******************************************************/

struct NewWindow nw2 =
{
	60, 14, 
	520, 171,
	0, 1, 
	CLOSEWINDOW |
	REFRESHWINDOW,

	WINDOWDEPTH |
	WINDOWDRAG |
	WINDOWCLOSE |
	WINDOWACTIVE |
	SMART_REFRESH,

	NL,
	NL,
	(UBYTE *)"ASCII Dump",
	NL, NL,
	0, 0, 0, 0,
	WBENCHSCREEN
};

struct IntuiText AsciiLine =
{	
	1, 0,
	JAM1,	
	1, 1, NL,
	(UBYTE *) &Str80,
	NL
};


AsciiDump()
{
	struct Window *OpenWindow();
	struct Message *GetMsg();
	struct IntuiMessage *message2;

	int i,j;
	ULONG MessageClass;
	USHORT code;
	struct Window *w2;
	UBYTE *Text, *Text2;

	if (!(w2 = OpenWindow (&nw2)))
		return();

	Text = (UBYTE *) BootBlocks[3];
	for (i=0 ; i<16; i++)
	{
		Text2 = AsciiLine.IText;
		for (j=0 ; j<64 ; j++)
		{
			if ((*Text < 0x20) || (*Text > 0x7f))
			{
				*(Text2++) =(UBYTE) 0x2e;
				Text++;
			}
			else
				*Text2++ = *Text++;
		}
		PrintIText (w2->RPort, &AsciiLine, 3L, (LONG) i*10+11);
	}

	for (;;)
	{
		if ((message2 = (struct IntuiMessage *)GetMsg(w2->UserPort)) == 0L)
		{
			Wait (1L << w2->UserPort->mp_SigBit);
			continue;
		}
		MessageClass = message2->Class;
		code = message2->Code;
		ReplyMsg (message2);
		switch (MessageClass)
		{
			case CLOSEWINDOW:
						CloseWindow (w2);
						return (0);
		}
	}
}	


char *InfoText[] =  
{
"VirusKiller Instructions. (Against SCA, BYTEBANDIT AND BYTEWARRIOR (DASA)",
"",
"ReadBB: The VirusKiller reads the BB of the selected disk and copies it to",
"        'Buffer BB'. The VirusKiller checks what kind of BB it is.",
"",
"WriteBB:The VirusKiller writes the selected BB to disk.",
"   Normal BB: The normal BootBlock from Install.",
"   Sound  BB: A BB which makes the screen green and makes a sound",
"              if the Amiga starts reading your BootDisk.",
"   AntiVirus: This BB protects your Amiga against all known viruses.",
"              As long as you hear a sound and see a multicolored screen",
"              during a reset this program is still active.",
"              It gives a warning if the bootdisk is infected with a virus.",
"   Buffer BB: This BB contains the last BB that is checked with the",
"              ReadBB command. This option gives the posiblity to copy",
"              a BB from one disk to another.",
"",
"ASCII:  Gives a ASCII-dump of the BB in 'Buffer BB'."
};



/*******************************
*  N E W   W I N D O W   F O R   A S C I I   D U M P 
\******************************************************/

struct NewWindow nw3 =
{
	0, 0, 
	640, 200,
	0, 1, 
	CLOSEWINDOW |
	REFRESHWINDOW,

	WINDOWDEPTH |
	WINDOWDRAG |
	WINDOWCLOSE |
	WINDOWACTIVE |
	SMART_REFRESH,

	NL,
	NL,
	(UBYTE *)"Info",
	NL, NL,
	0, 0, 0, 0,
	WBENCHSCREEN
};


struct IntuiText InfoText_Str =
{	
	1, 0,
	JAM1,	
	1, 1, NL,
	(UBYTE *) &Str80,
	NL
};


InfoVK()
{
	struct Window *OpenWindow();
	struct Message *GetMsg();
	struct IntuiMessage *message3;

	ULONG MessageClass;
	USHORT code;
	struct Window *w3;
	int i;

	if (!(w3 = OpenWindow (&nw3)))
		return();

	for (i=0 ; i<18 ;i++)
	{
		strcpy ( InfoText_Str.IText, InfoText[i]);
		PrintIText (w3->RPort, &InfoText_Str, 3L,(LONG) i*10+11);
	}

	for (;;)
	{
		if ((message3 = (struct IntuiMessage *)GetMsg(w3->UserPort)) == 0L)
		{
			Wait (1L << w3->UserPort->mp_SigBit);
			continue;
		}
		MessageClass = message3->Class;
		code = message3->Code;
		ReplyMsg (message3);
		switch (MessageClass)
		{
			case CLOSEWINDOW:
						CloseWindow (w3);
						return (0);
		}
	}
}
CheckBBData()
{
	int i;
	ULONG *ptr, sum=0;

	ptr = BootBlocks[0];
	for (i=0; i<400; i++)
	{
		sum += *ptr++;
	}
#ifdef DEBUG
	printf ("De sum = %lx\n",sum);
	return (1);
#else DEBUG
	return ((sum == 0x8854617c) ? 1 : 0);
#endif DEBUG
}
