****************************************************************************
*
*                         B E R S E R K E R  IV.1
*                         -----------------------
*
*                 © Copyright 1988, 1989, 1990 by Ralf Thanner
*
* This code is entirely written in assembler for the Kuma Seka assembler
*
*    Executable program and source code are both in the PUBLIC-DOMAIN!
*
*  A small copy fee for Berserker is okay, but anything which looks like
*        commercial redistribution is forbidden (remember that!).
*
**************************************************************************
*				RALF THANNER
*			       ELLERSTASSE 83
*			     4000 DUESSELDORF 1
*				WEST GERMANY
*
**************************************************************************
*
*	REVISION HISTORY:
*	=================
*
*  R	V1.0	- Just a primitive SCA finder and killer.
*
*  R	V1.c	- Added Byte Bandit & Byte Warrior killer.
*		- Improved SCA & SCA mutants killer routine.
*		  -> OBELISK, AEK, LSD, PENTAGON, BAMIGA SECTOR ONE,
*		     WARHWAK, MICROMASTER & NORTHSTAR...
*
*  R	V2.b	- Now also finds the Exterminator (LAMER).
*
*  R	V2.d	- Now finds the first link virus (IRQ TEAM 41).
*
*	V2.e	- Added alert box. Idea by Olaf Barthel.
*		- Some cleanups and bug-fixes done.
*
*  R	V2.e+	- Doesn't refuse to work with Kick 1.3 any more.
*		- Added custom bootblock writer.
*		- Added kill cold-cool vectors;
*		  There are just too many SCA clones on the market
*		  and it is saver to clear these pointers.
*
*  R	V3.0	- Now also finds the BSG 9 link virus.
*		- Second (and final?) code cleanup for public
*		  release (YEAH!!!).
*		- Removed the custom bootblock writer, too many guys
*		  thought Berserker to be some kind of virus in
*		  disguise.
*
*  R	V3.0+	- Extended to find Gaddafi and Disk-Doctor viruses.
*
*	V3.1	- Extended to find the REVENGE BOOTLOADER virus.
*		  -> THIS IS A NEW ONE!!!
*		- Bug-fix in EXTERMINATOR routine done.
*		  -> should now find ALL lamer versions.... (does not!)
*		- Code cleanup (added some sub-routines).
*
*	V3.2	- Extended to find REVENGE (is an old one, but some
*		  nice guys told me, that berserker should also find
*		  the old ones....and because BERSERKER crashed when
*		  memory was infiltrated by REVENGE )
*
*	V3.2b   - Shortening, speeding up & cleaning the code.
*		  ( and berserker still works.... )
*
*  R	V3.39c+ - JOKE....
*
*	V3.5	- Added Xeno 'killer' routine by STEVE TIBBET.
*
*	V4.0	- Added a more userfriendly Cli-Interface and the
*		  possibility to start BERSERKER from workbench.
*
*  R	V4.0a	- WHAAA, what a pity: forgot to reply message..
*		  Bug now fixed... Thanks to Olaf for this hint.
*		- Shortened and improved code again.
*
*	V4.0b	- Throw the 'led switch off' out.
*		- Made the cold/cool capture killer optionable. 
*		  Hello Martin, yes -> only for you....
*		- Shortened and improved code again & again.....
*
*  R	V4.0c	- AARGH!! A new file virus -> Disaster Master V2
*
*  R	V4.0d   - CENTURION LINK VIRUS killer implemented
*		- Implemented a resident library checker.
*		- From now on the source contains only the
*		  'virus-killing-part'.
*
*  R	V4.1	- these fucking assholes... in the last two weeks
*		  i got three new file/link viruses, and this is
*		  even one of the best programmed viruses i ever
*		  saw: The Traveling JACK....
*		- OLSEN found out that 'BERSERKER' crashed on
*		  KICK 2.0.. checks now kick version.
*		- OKI DOKI.. from now on source contains everything..
*		  (some people didn't like it the other way) 
*
*  R = released version
* 
*  BERSERKER is now: 6920 bytes long. (not crunched!)
*
**************************************************************************

;
;
; 	exec.library
;

forbid=		-132
permit=		-138
freemem=	-210
findname=	-276
findtask=	-294
getmsg=		-372
replymsg=	-378
waitport=	-384
closelib=	-414
openlib=	-552

;
;	dos.library
;

open=		-30
close=		-36
read=		-42
write=		-48
output=		-60
delay=		-198

mode_old=	1005

;
;	intuition.library
;

dispalert=	-90

;
;
**********************************************************************
powerup:

	movem.l		d0-d7/a0-a6,-(a7)

	move.l		$04.w,a6
	suba.l		a1,a1
	jsr	findtask(a6)
	move.l		d0,a4
	tst.l		$ac(a4)
	bne.s	cli_call
	lea		$5c(a4),a0
	jsr	waitport(a6)
	lea		$5c(a4),a0
	jsr	getmsg(a6)
	move.l		d0,message

	movem.l 	(a7)+,d0-d7/a0-a6
	bra.L	workbench

* CLI-PARAMETER HANDLER

cli_call:
	movem.l 	(a7)+,d0-d7/a0-a6
	subq		#1,d0
	beq.s	no_cli_parameter
which_parameter:
	cmp.b		#$20,(a0)+
	bne.s	parameter_found
	dbra		d0,which_parameter
	bra.s	no_cli_parameter
parameter_found:
	move.b		-(a0),d0	
	cmp.b		#'?',d0
	beq.L	instructions
	cmp.b		#'c',d0
	bne.s	no_cli_parameter
	not.b		no_killy
no_cli_parameter:

	move.l		$04.w,a6
	jsr	FORBID(a6)		; forbid all tasks

	bsr.L	open_libs
	bsr.L	test_lib
	bsr.L	open_output

	tst.w		kickflag
	bne.s	wrong_kick
	bsr.s	kill_viruses

	move.w		virusflag,d0
	bne.s	exit4			; Lucky ones...
	move.l		#mes0,d2
	move.l		#mes0length,d3
 	bsr.L	writer
	bra.s	exit3

exit4:	bsr.L	alert			; Virus found

exit3:	move.l		$04.w,a6
	jsr     PERMIT(a6)		; Allow other tasks
exit5:	bsr.L	close_libs
	moveq		#00,d0
	rts

wrong_kick:
	move.l		#mes17,d2
	move.l		#mes17length,d3
 	bsr.L	writer
	bra.s	exit3

exit_workbench:
	bsr.L	close_libs
	move.l		$04.w,a6
	jsr	forbid(a6)
	move.l		message,a1
	jsr	replymsg(a6)
	moveq		#00,d0		; For clear entry into CLI
	rts				; Back to CLI...

************************* SUB ROUTINES *********************************
kill_viruses:
	bsr.L	jack			; The Traveling JACK
	bsr.L	centurion
	bsr.l	disaster_master
	bsr.L	Xeno			; XENO - Link
	bsr.L	revenge			; REVENGE (old one)	
	bsr.L	revenge_boot		; REVENGE - BOOTLOADER
	bsr.L	gadaffi			; Gadaffi
	bsr.L	disk_doctor		; Disk Doctor
	bsr.L	sca			; Checks for SCA & mutants
	bsr.L	dasa			; Checks for Byte Warrior
	bsr.L	irq			; Link
	bsr.L	bsg			; Link
	bsr.L	exterminator
	bsr.L	bytebandit
	bsr.L	killcold_cool

	bsr.L	lib_checker
	rts			

workbench:
	bsr.L	open_libs
	bsr.L	test_lib
	bsr.L	open_con
	bsr.s	work
	bsr.L	close_con
	bra.L	exit_workbench
work:
	bsr.L	write_con_txt
	bsr.L	read_con
	moveq		#0,d0
	move.b		input_buffer,d0
	cmp.b		#'?',d0
	beq.s	work03		; instructions
	cmp.b		#'q',d0
	beq.s	work04		
	cmp.b		#'Q',d0	; leave
	beq.s	work04
	cmp.b		#'c',d0
	beq.s	work05		; kill virus		
	cmp.b		#'C',d0
	beq.s	work05
	bra.s	work

work03:
	bsr.L	write_con_ins
mouse:
	move.l		#$0d,d1
	jsr	delay(a5)		
	btst		#10,$dff016
	bne.s	mouse
	clr.w		input_buffer
	bra.s	work

work04:	rts

work05:
	move.l		$04.w,a6
	jsr	forbid(a6)
	tst.w		kickflag
	bne.s	work005
	bsr.L	kill_viruses
	move.w		virusflag,d0
	bne.s	work06
	move.l		#mes7,d2
	move.l		#mes7length,d3
 	bsr.L	writer
work007:
	move.l		$04.w,a6
	jsr     permit(a6)
	move.l		dosbase,a5
work07:
	move.l		#$0a,d1
	jsr	delay(a5)		
	btst		#10,$dff016	; right MB
	bne.s	work07
	bra.L	work
work005:
	move.l		#con_error,d2
	move.l		#con_error_ende-con_error,d3
	bsr.L	writer
	bra.s	work007

work06:	bsr.L	alert
	clr.w		virusflag
	move.l		$04.w,a6
	jsr     permit(a6)		; Allow it all
	bra.L	work

test_lib:
	move.l		dosbase(pc),a0
	add.l		#$14,a0
	move.w		(a0),d1
	cmp.w		#35,d1
	bgt.s	no_lib
	rts
no_lib:	not.w		kickflag
	rts

open_libs:
	move.l		$04.w,a6
	lea.l		Dosname(pc),a1
	bsr.s		open_libs1
	move.l		d0,dosbase

	lea.l		expname(pc),a1	; expansion
	bsr.s		open_libs1
	move.l		d0,expbase

	lea.l		Intname(pc),a1
	bsr.s		open_libs1
	move.l 		d0,IntBase

	lea.l		layname(pc),a1
	bsr.s		open_libs1
	move.l		d0,laybase

	lea.l		gfxname(pc),a1
	bsr.s		open_libs1
	move.l 		d0,gfxBase
	rts
open_libs1:
	moveq		#$21,d0
	jsr	openlib(a6)
	rts

close_libs:
	move.l		dosbase,a1
	bsr	close_libs2
	move.l 		IntBase,a1
	bsr	close_libs2
	move.l		gfxbase,a1
	bsr	close_libs2
	move.l		laybase,a1
	bsr	close_libs2
	move.l 		expBase,a1
	bsr	close_libs2
	rts
close_libs2:
	move.l		$04.w,a6
	jsr     closelib(a6)
	rts

open_con:
	move.l		Dosbase,a5
	move.l		#con,d1
	move.l		#mode_old,d2
	jsr	open(a5)
	move.l		d0,handle
	rts

close_con:
	move.l		Dosbase,a5
	move.l		handle,d1
	jsr	close(a5)
	rts

open_output:
	move.l		Dosbase,a5
	jsr	output(a5)
	move.l		d0,handle
	rts

write_con_txt:
	move.l		#con_text,d2
	move.l		#cende-con_text,d3
	bsr.s	writer
	rts

read_con:
	move.l		Dosbase,a5
	move.l		handle,d1
	clr.w		input_buffer
	move.l		#input_buffer,d2
	move.l		#2,d3
	jsr	read(a5)
	rts

write_con_ins:
	move.l		#con_help,d2
	move.l		#con_help_ende-con_help,d3
	bsr.s	writer
	rts

writer:	move.l		Dosbase,a5
	move.l		handle,d1
	jsr	write(a5)
	rts

writer1:
	move.l		Dosbase,a5
	move.l		handle,d1
	jsr	write(a5)
	move.l		handle,d1
	move.l		#mes,d2
	move.l		#meslength,d3
	jsr	write(a5)
	rts

instructions:
	bsr.L	open_libs
	bsr.L	open_output
	move.l		#mes15,d2	; Prints out the instructions
	move.l	#mes15length,d3
	bsr.s		writer
	jmp	exit5

alert:
	lea		alert1(pc),a0
calert:
	move.l		Intbase,a6
 	moveq		#00,d0		; Recovery Alert
 	move.l 		#28,d1
 	jsr 	dispalert(a6)
	rts
killcold_cool:
	tst.b		no_killy
	bne.s	kcc3
	move.l		$04.w,a6
	moveq		#0,d3
	move.l		d3,46(a6)	; cool-capture normal
	move.l		d3,42(a6)	; cold-capture normal
	move.l		d3,50(a6)
	lea		34(a6),a0	; New execbase checksum
	moveq		#0,d0
	moveq		#$17,d1
kcc1:	add.w		(a0)+,d0
	dbf	d1,kcc1
	not.w		d0
	move.w		d0,(a0)
kcc3:	rts

tracker:move.l		$04.w,a6
	lea		350(a6),a0
	lea		Trddevice(pc),a1	; Searches
	jsr	findname(a6)			; for trackdisk.device
	move.l		d0,a0
	sub.l		#28,a0			; that's the most used
	rts					; pointer in trd.dev...

filler:	move.l		a0,a1			; fills
	add.l		#$400,a1		; the virus with zeros
fill1:	clr.l		(a0)+
	cmpa.l		a0,a1
	bge.s	fill1
	rts

clear_kicktag:
	move.l  	$04.w,a6
	moveq		#0,d0
	move.l		d0,554(a6)	; Kickchecksum
	move.l		d0,550(a6)	; Kicktagptr
	move.l		d0,546(a6)	; Kickmemptr
	rts
********************  L I B  C H E C K E R  *****************************

lib_checker:
	lea		layname(pc),a2
	move.l		laybase,a0
	bsr.s	lib_check
	lea		expname(pc),a2
	move.l		expbase,a0
	bsr.s	lib_check
	lea		gfxname(pc),a2
	move.l		gfxbase,a0
	bsr.s	lib_check
	lea		intname(pc),a2
	move.l		intbase,a0
	bsr.s	lib_check
	lea		dosname(pc),a2
	move.l		dosbase,a0
	bsr.s	lib_check
	lea		exename(pc),a2
	move.l		$04.w,a0	; execbase
	bsr.s	lib_check
	rts
lib_check:
	cmp.l		#0,a0
	beq.s	lib_check_ende
	moveq		#0,d0
	moveq		#0,d1
	moveq		#0,d2
	move.l		a0,a1
	move.w		$10(a1),d0	; laenge vor knoten
	move.w		$1c(a1),d2	; checksum	
	lsr.w		#1,d0		; for dbf
	bra.s	lib_check2
lib_check1:
	add.w		-(a0),d1
lib_check2:
	dbf	d0,lib_check1
	cmp.w		d1,d2
	beq.s	lib_check_ende
	bsr.s	lib_checker_alert
lib_check_ende:
	rts

lib_checker_alert:
	lea		alert4(pc),a0
lib_checker_alert1:
	move.b		(a2)+,(a0)+
	bne.s	lib_checker_alert1
	move.b		#$20,-(a0)
	lea		alert3(pc),a0
	bsr.L	calert
	rts

******************* V I R U S  K I L L I N G  P A R T ********************
jack:
	move.l		dosbase(pc),a0	
	move.l		46(a0),a1	; pointer to jack
	move.l		-$13e(a1),d0
	cmp.l		#$41fa001f,d0	; his first two 
	bne.s	no_jack
	move.l		-$13a(a1),d0
	cmp.l		#$303c0909,d0	; instructions
	bne.s	no_jack
	move.l		$656(a1),a2	; restore pointer
	move.l		a2,46(a0)	; aloha... HE HE
	lea		-$142(a1),a0
	bsr.L	filler
	move.w		#$1941,virusflag
	move.l		#mes18,d2
	move.l		#mes18length,d3
	bsr.L	writer1
no_jack:rts
***************************************************************************
*	The Traveling JACK
*
*	you can wipe him out with a reset..
*	he changes the dos.lib jump tab.. 
*	(meine hochachtung fuer die routinen, hat richtig spass gemacht)
*	he tries to infect a file..
*	when he is installed, he tries to write his 'VIRUS.xx' file to
*	the disk. each time a programm access the drive he write his
*	stupid text.
***************************************************************************
centurion:
	move.l		$04.w,a6
	move.l		550(a6),d0
	beq.s	cen_exit
	move.l		d0,a0
	move.l		30(a0),a1
	lea		cen(pc),a0
	moveq		#3,d0
cen1:	cmpm.l		(a0)+,(a1)+		; the first four longs
	dbne		d0,cen1			; of his code..
	tst.w		d0
	bpl.s	cen_exit
	move.l		-610(a6),a0	
	cmp.l		#$7f0fe,a0
	bne.s	cen_exit
	lea		$7fdf0,a0		; is his save back
	move.l		(a0),-610(a6)		; pointer..
	bsr.L	tracker
	lea		$7fdf4,a1		; restore
	move.l		(a1),(a0)		; trackdisk.device
	bsr.L	clear_kicktag			; throw resident out
	lea		$7f000,a0
	bsr.L	filler				; clears memory
	lea		$7f400,a0
	bsr.L	filler				; clears memory
	move.w		#$1941,virusflag
	move.l		#mes16,d2
	move.l		#mes16length,d3
	bsr.L	writer1
cen_exit:
	rts
	
cen:	dc.l	$4eaeff88,$60b241fa
	dc.l	$0d00202e,$02266712
**************************************************************************
*
*	CENTRUION - LINK VIRUS
*
*	makes himself resident, changes the DOIO & KICKSUM.
*
*	Virus is 3916 bytes long and tries to infect the programs in
*	the startup-sequence.
*	After XX resets he changes the mousepointer to a smiley with a
*	little scroller.
*
***************************************************************************
Disaster_Master:
	move.l		$04.w,a6
	move.l		550(a6),d0
	beq.s	disaster_exit
	move.l		d0,a0
	move.l		(a0),a0
	cmp.w		#$4afc,(a0)+	; isses denn RESIDENT???
	bne.s	disaster_exit
	move.l		(a0)+,a2
	move.l		(a0)+,a1		
	sub.l		a2,a1
	cmpa.l		#$1e,a1		; is immer seine struct laenge
	bne.s	disaster_exit
	move.l		(a0),d0
	cmp.l		#$01210873,d0	; sind seine flags
	bne.s	disaster_exit
	add.l		#12,a0	
	move.l		(a0),a0
	move.l		a0,a2		; backsave
	add.l		#8,a0
	move.l		(a0),d0
	cmp.l		#$011cd7c0,d0	; teil seines codes	
	bne.s	disaster_exit
	move.w		#$4e75,(a2)	; castrated	
	move.l		a2,a0
	add.l		#$14a,a0
	move.l		(a0),-454(a6)	; rauswerfen
	bsr.L	clear_kicktag
	move.w		#$1941,virusflag
	move.l		#mes14,d2
	move.l		#mes14length,d3
 	bsr.L	writer1
disaster_exit:
	rts

**************************************************************************
*
*	DISASTER-MASTER V2	FILE VIRUS
*
*	makes himself resident and changes the DOIO.
*
*	Virus is 1740 bytes long, his name is 'CLS' and is
*	found in the 'C' Dir.
*	When he has infected a disk, he is always the first command
*	in the startup-sequence -> 'CLS *'
*	If you execute him he will clear screen, but if you execute him
*	with 'CLS *' he will do nothing. Looks like a option!
*	Infects everything with 's/startup-sequence' even harddisks.
*
***************************************************************************

* here begins the part taken from VIRUSX4.0 by STEVE TIBBET

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;	Check for and Remove the Xeno Virus
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

xeno:
	move.l	DOSBase,a0		; Get addr of Open() Vector
	sub.w	#$1c,a0
	move.l	(a0),a0

	move.l	a0,d0			;: If Bit 0 of the Address is set,
	btst	#0,d0			;: then it's not really an address
	bne.s	NoVirus_xeno		
	
	cmp.l	#$B47C03EE,(a0)
	bne.s	NoVirus_xeno
	cmp.l	#$67000224,4(a0)
	bne.s	NoVirus_xeno

	;:: If we're here, we're fairly sure A0 is pointing to the
	;:: base of the Xeno virus (well, not it's base, but the address
	;:: of the first vector it stole, the Open() one.
	;:: So we'll nuke it.  8-)

	move.w	#$6000,$4(a0)
	move.w	#$603E,$240(a0)
	move.w	#$601E,$29C(a0)

* END OF PART

	move.w		#$1941,virusflag
	move.l		#mes13,d2
	move.l		#mes13length,d3
 	bsr.L		writer
NoVirus_xeno:
	rts

; i hate to do this, but until now i never got a xeno virus and was
; therefore not able to do my own killer.
; in addition to that: I HATE THE WAY S.TIBBET KILLS VIRUSES!!!!!!!
; it is not very intelligent to look for a checksum....

revenge:
	move.l		$04.w,a6
	cmp.l		#$7e060,46(a6)
	bne.s		revenge_ende
	move.l		$c0,d0
	cmp.l		#$0c794ef9,$c0
	bne.s		revenge_ende

	move.l		$7e068,-454(a6)	; restoring the old pointers
	move.l		$7e06e,148(a6) 	; by grabbing his saved systemcalls

	lea		$7e000,a0	; the virus
	bsr.L		filler

	lea		$c0,a0		; CLEAR
	moveq		#0,d0		; his routine
	moveq.l		#$10,d6		; located at $c0
rev1:
	move.l		d0,(a0)+
	dbf		d6,rev1

	bsr.L		killcold_cool	; out of memory!! HE HE..

	move.w		#$1941,virusflag
	move.l		#mes12,d2
	move.l		#mes12length,d3
 	bsr.L		writer1
revenge_ende:
	rts

*************************************************************************
* REVENGE is a stupid one, it copies a small CONTROLLER part down to
* $c0 and is ALWAYS located at $7e000. (No interest in Fast Mem!!) 
* I only added this one, because it was easy and BERSERKER III crashed
* when REVENGE was in memory. (uses cold cap., 148(a6) & -454(a6) DOIO)
*************************************************************************

revenge_boot:	; seems to be a brand new one...
	bsr.L		tracker
	move.l		a0,revenge1
	move.l		(a0),d4
	swap		d4
	cmp.b		#$fe,d4		; Is this pointer normal? (V1.2)
	beq.L		revenge_boot_ende
	cmp.b		#$ff,d4		; Is this pointer normal? (V1.3)
	beq.L		revenge_boot_ende

	move.l		$4.w,a6		; using his own check
	moveq		#0,d0		; routine... 
	move.w		$94(a6),d0
	and.l		#$f0,d0
	cmp.w		#$f0,d0
	beq.L		revenge_boot_ende	; not in memory

	move.l		(a0),a1
	add.l		#$228,a1
	move.l		(a1),revenge_track	; -28(trackdisk.device)
	add.l		#$4,a1
	move.l		(a1),revenge_rast	; 148(a6)
	add.l		#$4,a1
	move.l		(a1),revenge_alloc	; the part he spreads
	sub.l		#$3c4,a1
	move.l		a1,revenge_mem		; his own start

	move.l		revenge1,a0		; restoring pointers
	move.l		revenge_track,(a0)

	move.l		revenge_rast,$94(a6)		

	bsr.L		clear_kicktag

	move.l		revenge_mem,a0
	bsr.L		filler

	move.l		revenge_alloc,a0
	bsr.L		filler

	move.l		revenge_alloc,a1	; he allocatesw memory..
	move.l		#$400,d0		; ani i give it back...
	jsr		freemem(a6)

	move.w		#$1941,virusflag
	move.l		#mes11,d2
	move.l		#mes11length,d3
 	bsr.L		writer1
revenge_boot_ende:
	rts

*************************************************************************
*
* seems to be a new one -> contains ASCII Text 'REVENGE BOOTLOADER' 
*
*************************************************************************

disk_doctor:
	move.l		$04.w,a6	; Disk-Doc uses cold & cool capture
	move.l		46(a6),d0
					; No other virus uses both
	beq.L		dd0		; pointers... [ hope so !!! ]
	move.l		42(a6),d0
	beq.L		dd0

	move.l		42(a6),diskdoc	; I had to add this very
	move.l		diskdoc,a0	; complicated routine because
	add.l		#$c4,a0		; Disk-Doc uses or changes:
	move.l		a0,a1		; - cool capt.
	addq.l		#4,a1		; - cold capt.
	move.w		#$4e75,(a1)	; - DoIO
	jsr		(a0)		; - 148(a6) [what's that?]
	move.l		a2,diskdoc1	; - The task of clipboard.device
	addq.l		#6,a2
	move.l		a2,a3		; This routine gets the adress of
	addq.l		#4,a2		; its task routine and cuts it off
	move.w		#$4e75,(a2)
	jsr		(a3)
	move.l		a0,diskdoc2
	bsr.L		killcold_cool
	move.l		$04.w,a6
	move.l		#$fc06dc,-$1c6(A6); Only Kick 1.2 values, on 1.3
	move.l		#$fc12fc,148(a6)  ; Disk-Doc shouldn't work...

	move.l		diskdoc,a0
	move.l		a0,a1
	add.l		#$1a0,a1
	moveq		#0,d0
dd2:	move.l		d0,(a0)+
	cmpa.l		a0,a1
	bge.s		dd2
	move.l		diskdoc1,a2
	move.w		#$4e75,(a2)
	move.l		diskdoc2,a2
	move.w		#$4e75,(a2)

	move.w		#$1941,virusflag
	move.l		#mes6,d2
	move.l		#mes6length,d3
 	bsr.L		writer1
dd0:	rts

***********************************************************************
*
*	DISK-DOCTOR
*
*	- After each reset Disk Doctor allocates more memory
*	- This was in my opinion the best one, although it could be
*	  better: - it uses DoIO pointer from Kick 1.2 (crash on 1.3)
*		  - you can read text in the boot-block
*	- it uses the clipboard task for its dirty work
*	- it uses cold & cool capture to stay in memory
*
*	For such kind of virus Guardian or VirusX are the best killers!!
*	( Find them in the boot and fight them when they are harmless! )
*	Same with TIMEBOMB, Berserker can't fight this one........
************************************************************************

gadaffi:
	move.l		$04.w,a6	; Gadaffi uses cool capture
	cmp.l		#0,46(a6)	; for its dirty work...
	beq.s		gad0		; no cool capture set

	cmp.l		#$47414441,$7fb40; Gadaffi
	bne.s		gad0		; is ALWAYS to be found at $7fb00

	move.l		-$1c6(a6),d5	; $4b0 with 512 kb
	swap		d5
	cmp.w		#$fc,d5		; $fc06dc (1.2)  $fc0718 (1.3)
	beq.s		gad0

	move.l		46(a6),gadaf
	bsr.L		killcold_cool	; Clear its cool pointer
	move.l		$04.w,a6
	move.l		#$fc06dc,-$1c6(A6)

	bsr.L		clear_kicktag

	move.l		gadaf,a0
	sub.l		#$dc,a0
	bsr.L		filler
	move.w		#$1941,virusflag
	move.l		#mes4,d2
	move.l		#mes4length,d3
 	bsr.L		writer1
gad0:	rts

********************************************************************
*
*	GADAFFI is a mutant version of Byte Warrior
*
*	- It changes cool capture, kicktag. and DoIO
*	- It is much more stupid than Byte Warrior:
*	 -> you can read it in the boot...
*	 -> normally it crashes with Kick 1.3 because
*	    he uses the DoIO vector of 1.2 itself
*	- After 12 resets it tries to kill your drive, or
*	  was it playing a drive music ?? (I don't see any difference!)
*
********************************************************************
bsg:
	move.l		$04.w,a6
	move.l		546(a6),d0	; BSG 9 is a resident module
	adda.l		550(a6),d0	; It is still in memory after
	adda.l		554(a6),d0	; a reset
	beq.s		bsgende
	move.l		550(a6),a0	; Searching from A0
	move.l		a0,a1
	add.l		#$1000,a1	; Searching to A1
	move.l		#$00005454,d0	; Searching for 'TT'
	moveq		#0,d1
bsg0:
	move.w		(a0)+,d1
	cmp.w		d1,d0
	beq.s		bsg1
	cmpa.l		a0,a1
	bge.s		bsg0
	rts				; Nothing found !
					; It is not always a virus which
					; uses these pointers. It could
bsg1:					; also be your ramdrive....
	move.w		#$5631,d0
	move.w		(a0),d1
	cmp.w		d1,d0
	bne.s		bsg0
	moveq		#0,d0		; Kills it from beginning
	move.l		a0,a1		; to 'TTV1' <- its end marker
	move.l		550(a6),a0
bsg2:
	move.l		d0,(a0)+
	cmpa.l		a0,a1
	bne.s		bsg2

	bsr.L		clear_kicktag

	move.w		#$1941,virusflag
	move.l		#mes2,d2
	move.l		#mes2length,d3
 	bsr.L		writer
bsgende:
	rts

********************************************************************
*
*	BSG 9 is an intelligent version of a link virus
*
*	- It always modifies the FIRST file of the startup-
*	  sequence
*	- The file now always is about 2608 bytes long
*	- The old file in in the devs dir with
*	  spaces instead of a name now
*	- After the fourth or fifth reset it turns the
*	  screen black and prints out its stupid message.
*
*********************************************************************

irq:	; changes oldopen
	move.l		$04.w,a6
	move.l		-$196(a6),d4
	swap		d4
	cmp.b		#$fc,d4	; V1.2 00fc1430  V1.3 00fc146c
	beq.s		irq5
	move.w		#$1942,virusflag
	move.l		-$196(a6),a4
	add.w		#8,a4
	move.l		#$4e714e71,(a4)	; Castrate virus
	move.l		$04.w,a5
	sub.l		#$196,a5	; In this part the old
	move.l		(a5),a4		; oldopenlib call
	add.l		#18,a4		; is restored...
	move.l		(a4),(a5)
	move.l		#mes3,d2
	move.l		#mes3length,d3
	bsr.L		writer
irq5:	rts

**************************************************************
*
*	The IRQ Team Virus was the first link virus
*	on AMIGA...
*
*	It uses oldopenlibrary for its dirty work.
*	In order to work properly with all Kickstart
*	versions the IRQ-virus saves the replaced
*	sytemcall in memory.
*	To let my Berserker work with all kick versions
*	I just grab his saved sytemcall in order to
*	throw him out properly...
*
**************************************************************

exterminator:	; in trddevice, doio & kicktag... ($4678, $414, $898)
	bsr.L		tracker
	move.l		a0,exter
	move.l		(a0),d4
	swap		d4
	cmp.b		#$fe,d4		; Is the pointer normal (V1.2)
	beq.L		exe4
	cmp.b		#$ff,d4
	beq.L		exe4		; Is the pointer normal (V1.3)

	move.l		a6,a5
	sub.w		#$262,a5	; In A5 now Exterminator's address..
	move.l		a5,exter1
	move.l		(a5),d4
	swap		d4
	cmp.b		#$fc,d4		; Is it the normal system call?
	beq.s		exe4

	move.l		exter1,a5
	move.l		(a5),a0
	sub.l		#$14e,a0
	move.l		a0,a1
	add.l		#$400,a1
	moveq		#0,d1
	moveq		#0,d0
exe7:
	move.w		#$4c41,d0	; We are looking for 'LAMER'
	move.w		(a0)+,d1
	cmp.w		d1,d0
	beq.s		exe2
	cmpa.l		a0,a1
	bge.s		exe7
	rts
exe2:
	move.w		#$4d45,d0
	move.w		(a0),d1
	cmp.w		d1,d0
	bne.s		exe7
	add.l		#28,a0		; Here exteminator saves his
	move.l		(a0)+,a1	; changed system calls
	move.l		(a0)+,a2

	move.w		#$1941,virusflag

	bsr.L		clear_kicktag

	move.l		exter1,a0	; Correct both pointers
	move.l		a1,(a0)
	move.l		exter,a0
	move.l		a2,(a0)
	move.l		exter1,a5	; Crucify it
	move.l		(a5),a0
	sub.l		#$14e,a0
	bsr.L		filler
	move.l		#mes9,d2
	move.l		#mes9length,d3
	bsr.L		writer1
exe4:	rts

***********************************************************************

sca:
	move.l		$04.w,a6
	move.l		46(a6),d2	; Cold-capture
	bne.s		sca1
	rts
sca1:
	move.w		#$1941,virusflag
	move.l		46(a6),a0
	move.l		a0,a1
	sub.l		#$3e,a0		; We are now searching
	add.l		#$400,a1	; for jsr -456(a6) [DoIO]
	moveq		#0,d1		; if cold capture is set
	moveq		#0,d0		; and in the routine is
sca2:					; a DoIO it is 100% a
	move.w		#$4eae,d0	; virus ( mostly mutants)
	move.w		(a0)+,d1
	cmp.w		d1,d0
	beq.s		sca3
	cmpa.l		a0,a1
	bge.s		sca2
	rts				; Nothing found
sca3:
	move.w		#$fe38,d0
	move.w		(a0),d1
	cmp.w		d1,d0
	bne.s		sca2
	move.l		$7eff0,d2	; Here is the direct test
	cmp.l 		#$53434121,d2	; if it is SCA or AEK or LSD
	beq.s		sca4		; if it is none of them it is
					; another mutant SCA...
	cmp.l		#$4c534421,d2	; AEK
	beq.s		scamutants
	cmp.l		#$41454b21,d2	; LSD
	beq.s		scamutants
	bne.s		scamutants
sca4:
	move.l		#mes5,d2	; SCA
	move.l		#mes5length,d3
 	bsr.L		writer1
	bra.s		scakill
scamutants:
	move.l		#mes8,d2	; Mutant
	move.l		#mes8length,d3
 	bsr.L		writer1
scakill:
	move.l		46(a6),a0
	sub.l		#$3e,a0
	bsr.L		filler
	bsr.L		killcold_cool	; Repairs both vectors
	rts

************************************************************************

dasa:
	move.l		$04.w,a6
	move.l		-$1c6(a6),d5	; $4b0 with 512 kb
	swap		d5
	cmp.w		#$fc,d5		; $fc06dc (1.2)  $fc0718 (1.3)
	bne.s		dasa0
	move.l		$7f804,d5	; Dasa is ALWAYS at $7f800
	cmp.l		#$64116dec,d5	; no need to restore doio
	beq.s		dasa1		; pointer (not changed)
	rts
dasa0:
	move.l		#$00fc06dc,-$1c6(a6)	; Remove its pointer
dasa1:	move.l		-$1c6(a6),a3
	sub.l		#$16e,a3	; Its beginning

	bsr.L		clear_kicktag

	move.l		#$4ff,d1	; Delete virus
dasa2:	move.b		d0,(a3)+
	dbf		d1,dasa2
	move.w		#$1941,virusflag
	move.l		#mes1,d2
	move.l		#mes1length,d3
	bsr.L		writer1
	rts

****************************************************************
*
*	DASA is the Byte Warrior
*
*	DASA is always located at $7f800 and since
*	it uses a direct jump for DoIO of kick V1.2
*	( jmp $fc06dc ) for his own copy-routines it
*	crashes on kick v1.3.
*	Therefore I have added this two way search, because
*	when it's kick 1.3 DASA can't work but is still in
*	memory and I don't like a virus in memory...
*
*		ONLY A DEAD VIRUS IS A GOOD VIRUS!!!!
*
***************************************************************

bytebandit:		    ; Searches for byte bandit

	bsr.L		tracker
	move.l		a0,bb1
	cmp.l		#$00f00000,a0
	ble.s		bytebandit1	; OK! DoIO is changed
	rts

bytebandit1:
	move.l		148(a6),a0	; Now second test if it
	cmp.l		#$00f00000,a0	; is really byte bandit
	ble.s		bytebandit2	; LAMER also changes DoIO!
	rts

bytebandit2:	; it is byte bandit!!
	move.l		a0,a4
	add.l		#$10c,a0	; Here the pointers are
	move.l		(a0)+,a1	; saved...
	move.l		(a0),a2
	move.l		bb1,a0
	move.l		a1,(a0)		; Restoring both
	move.l		a2,148(a6)	; pointers...

	bsr.L		clear_kicktag

	sub.l		#$2ca,a4	; Its beginning
	move.l		a4,a0
	bsr.L		filler

	move.w		#$1941,virusflag
	move.l		#mes10,d2
	move.l		#mes10length,d3
	bsr.L		writer1
	rts

***************** M E S S A G E S  AND  D A T A S ********************
even
mes:	dc.b $0a,'Virus killed, check your disks....'
	dc.b $0a,$0a             
mesend:
meslength = mesend-mes
even
mes0:	dc.b $0a,$9b,'7;32;41m'
	dc.b $1b,'[1m'
	dc.b '   BERSERKER found ** NO VIRUS ** in memory !!!  '   
	dc.b $1b,'[0m'
	dc.b $9b,'0;31;40m'
	dc.b $0a,$0a
mes0end:
mes0length = mes0end-mes0
even
mes1:	dc.b $0a,'DANGER!! BYTE - WARRIOR (DASA) VIRUS found'
mes1end:
mes1length = mes1end-mes1
even
mes2:	dc.b $0a,'DANGER!!  BSG 9 LINK -  VIRUS killed!!!'                
	dc.b $0a,'Check first prog. in startup seq. or look into devs.'
	dc.b $0a,$0a
mes2end:
mes2length = mes2end-mes2
even
mes3:	dc.b $0a,'DANGER!!  IRQ LINK - VIRUS killed!!!'                
	dc.b $0a,'Check 2nd prog. in startup seq. or cli-command DIR.'
	dc.b $0a,$0a
mes3end:
mes3length = mes3end-mes3
even
mes4:	dc.b $0a,'DANGER!!  GADAFFI - VIRUS found!!!'                
mes4end:
mes4length = mes4end-mes4
even
mes5:	dc.b $0a,'DANGER!!  SCA - VIRUS found!!!'                
mes5end:
mes5length = mes5end-mes5
even
mes6:	dc.b $0a,'DANGER!!  Disk-Doctor VIRUS found!!!'                
mes6end:
mes6length = mes6end-mes6
even
mes7:	dc.b $0a,''
	dc.b $0a,$0a,$0a
	dc.b $0a,$9b,'7;32;41m'
	dc.b '        ** NO KNOWN VIRUS ** found        '
	dc.b $9b,'0;31;40m'
	dc.b $0a,$0a,$0a,$0a
	dc.b $1b,'[1m'
	dc.b '        PRESS RIGHT MOUSE BUTTON...'
	dc.b $1b,'[0m'
mes7end:
mes7length = mes7end-mes7
even
mes8:	dc.b $0a,'DANGER!!  MUTANT SCA - VIRUS found!!!'                
mes8end:
mes8length = mes8end-mes8
even
mes9:	dc.b $0a,'DANGER!!  EXTERMINATOR (Lamer!) found!!!'                
mes9end:
mes9length = mes9end-mes9
even
mes10:	dc.b $0a,'DANGER!!  BYTE - BANDIT VIRUS found!!!'
mes10end:
mes10length = mes10end-mes10
even
mes11:	dc.b $0a,'DANGER!! REVENGE - BOOTLOADER VIRUS found!'
mes11end:
mes11length = mes11end-mes11
even
mes12:	dc.b $0a,'DANGER!! REVENGE VIRUS found!'
mes12end:
mes12length = mes12end-mes12
even
mes13:	dc.b $0a,'DANGER!!  XENO LINK - VIRUS neutralized!!'                
	dc.b $0a,'Check files on disks and hard-disk with "KV".'
	dc.b $0a,$0a
mes13end:
mes13length = mes13end-mes13
even
mes14:	dc.b $0a,'DANGER!!  Disaster-Master V2 FILE VIRUS killed!!!'                
	dc.b $0a,'Check first prog. in startup seq. & cli-command CLS.'
	dc.b $0a,$0a
mes14end:
mes14length = mes14end-mes14
even
mes16:	dc.b $0a,'DANGER!!  CENTURION LINK - VIRUS neutralized!!'                
	dc.b $0a,'Check files in startup-sequence.'
	dc.b $0a,$0a
mes16end:
mes16length = mes16end-mes16
even
mes17:	dc.b $0a,'SORRY!!  You have the wrong KICKSTART.'                
	dc.b $0a,'BERSERKER cannot work with this version.'
	dc.b $0a,$0a
mes17end:
mes17length = mes17end-mes17
even
mes18:	dc.b $0a,'DANGER!!  Traveling Jack - VIRUS neutralized!!'                
	dc.b $0a,$0a
mes18end:
mes18length = mes18end-mes18
even
mes15:
dc.b $0c,$0a,$1b,'[1m','                        *****  BERSERKER IV.1  *****'
dc.b $1b,'[0m'
dc.b	$0a
dc.b $0a,'	   1. This Viruskiller finds and destroys the following:'
dc.b $0a,'	      Byte Bandit,  Byte Warrior (DASA), SCA,  AEK, LSD,'
dc.b $0a,'	      OBELISK, WARHAWK,  PENTAGON, BAMIGA S1, NORTHSTAR,'
dc.b $0a,'	      Exterminator (LAMER) all versions,  GADAFFI Virus,'
dc.b $0a,'	      Disk-Doctor Virus, IRQ-Team 41 Virus (Link Virus),'
dc.b $0a,'	      BSG9 VIRUS (Link Virus), REVENGE BOOTLOADER Virus,'
dc.b $0a,'	      REVENGE, XENO Link, Disaster Master File Virus,'
dc.b $0a,'	      CENTURION & Traveling JACK Link Virus.'
dc.b $0a,'	   2. All bootblock  viruses  will be deleted from memory'
dc.b $0a,'	      and all  changed  system pointers will be restored.'
dc.b $0a,'	   3. The  Link Viruses  are only  killed in memory. They'
dc.b $0a,'	      might have infected some prgs. on disk!! Take care!'
dc.b $0a,'	   4. Berserker  gives you the choice to kill the cold- &'
dc.b $0a,'	      cool capture....'
dc.b $0a,'	   5. BERSERKER checks now all ram resident libraries.....'
dc.b $0a
dc.b $1b,'[1m'	; dick
dc.b $0a,'	  USAGE: BERSERKER [C (kill COLD & COOL)] [? (instructions)]'
dc.b $1b,'[0m'
dc.b $0a
dc.b $1b,'[1m'
dc.b $0a,'                    This program is in the PUBLIC DOMAIN!!!'
dc.b $1b,'[3m'
dc.b $0a
dc.b $0a,'                               ©Copyright 1988, 1989, 1990 by Ralf Thanner.'
dc.b $1b,'[0m'
dc.b $0a
mes15end:
mes15length = mes15end-mes15
even
 con:
dc.b'CON:20/11/360/150/            BERSERKER IV.1            ',0
even
 con_text:
	dc.b ''
	dc.b $0a,$9b,'7;32;41m'
	dc.b ' BERSERKER IV  (C) 1990 by RALF THANNER   '   
	dc.b $9b,'0;31;40m'
	dc.b $0a,$0a,$0a
	dc.b '  PLEASE ENTER EITHER:',$0a
	dc.b '  --------------------'
	dc.b $0a,$0a
	dc.b '    "C" or "c" to check memory.'
	dc.b $0a,$0a
	dc.b '    "?" for short instructions.'
	dc.b $0a,$0a
	dc.b '    "Q" or "q" to leave BERSERKER.'
	dc.b $0a,$0a,$0a
	dc.b $1b,'[1m'
	dc.b '  ENTER YOUR CHOICE: '
	dc.b $1b,'[0m'
 cende:
even
 con_help:
 	dc.b ''
	dc.b 	 '  BERSERKER IV finds the following:'
	dc.b $0a,'  ---------------------------------'
	dc.b $0a,'  Byte Bandit,  Byte Warrior,  SCA,  AEK,'
	dc.b $0a,'  LSD,  OBELISK,  PENTAGON, BS1, WARHAWK,'
	dc.b $0a,'  NORTHSTAR,  Exterminator  Virus (LAMER),'
	dc.b $0a,'  GADAFFI,  Disk - Doctor,  IRQ-, Xeno-, '
	dc.b $0a,'  BSG-9 & Disaster Master V2 Link Viruses,'
	dc.b $0a,'  REVENGE, REVENGE BOOTLOADER Virus,'
	dc.b $0a,'  CENTURION & Traveling JACK Link Virus.'
	dc.b $0a
	dc.b $0a,'  All  bootblock  viruses  will be killed'
	dc.b $0a,'  in memory  and all system pointers will'
	dc.b $0a,'  be restored. The Link Viruses will ONLY'
	dc.b $0a,'  be deleted from memory. They might have'
	dc.b $0a,'  infected some programs on disk...'
	dc.b $0a,$0a
	dc.b $1b,'[1m'
	dc.b '  PRESS RIGHT MOUSE BUTTON'
	dc.b $1b,'[0m'
 con_help_ende:
even
 con_error:
	dc.b	''
	dc.b	$0a,$0a,$0a,$0a,$0a
	dc.b	'BERSERKER cannot work with this KICKSTART!'
	dc.b	$0a,$a0,$0a,$0a,$0a,$0a
	dc.b $1b,'[1m'
	dc.b '        PRESS RIGHT MOUSE BUTTON'
	dc.b $1b,'[0m'
 con_error_ende:
even
 revenge1:	dc.l 0
 revenge_alloc:	dc.l 0
 revenge_track:	dc.l 0
 revenge_rast:	dc.l 0
 revenge_mem:	dc.l 0
 diskdoc:	dc.l 0
 diskdoc1:	dc.l 0
 diskdoc2:	dc.l 0
 gadaf:		dc.l 0
 bb1:		dc.l 0
 exter:		dc.l 0
 exter1:	dc.l 0
 expbase: 	dc.l 0 
 gfxbase: 	dc.l 0 
 laybase: 	dc.l 0 
 dosbase: 	dc.l 0 
 IntBase:	dc.l 0
 handle:	dc.l 0
 message:	dc.l 0
 virusflag:	dc.w 0
 kickflag:	dc.w 0
 input_buffer:	blk.b 2,0
 no_killy:	dc.b $ff
EVEN
 TRDDEVICE:	dc.b	'trackdisk.device',0
EVEN
 INTNAME: 	DC.B	'intuition.library',0
EVEN
 EXPNAME: 	DC.B	'expansion.library',0
EVEN
 GFXNAME: 	DC.B	'graphics.library',0
EVEN 
 LAYNAME: 	DC.B	'layers.library',0
EVEN
 DOSNAME:	DC.B	'dos.library',0
EVEN
 EXENAME:	DC.B	'exec.library',0
even
alert1:	dc.w 	178
	dc.b 	16
	dc.b 	'Berserker found VIRUS in memory!'
even
alert3:	dc.w 	128
	dc.b 	16
	dc.b 	'CHECKSUM of   '
alert4: dc.b	'                   '
	dc.b	'is NOT correct....',0
even
