
;	****************************–*****************
;	****************************–*****************
;	***					  ***
;	***	     Boot Protector 1.1 	  ***
;	***		    by			  ***
;	***		Andre Leis 		  ***
;	***					  ***
;	***	  (with the Seka-Assembler)	  ***
;	***					  ***
;	*********************************************
;	****************************–*****************


ExecBase:	equ	4	;Exec-Basis Adresse

; Exec Library Base Offsets

OpenLibrary:	equ	-552	;LibName,Version/a1,d0
CloseLibrary:	equ	-414	;Library/a1

;** Speicheranforderungen ***
Chip:		equ	2	; Speicher soll Chip-Ram sein
Clear:		equ	$10000	; Speicher Null gefuellen

AllocMem:	equ	-198	;ByteSize,Requirements/d0,d1
FreeMem:	equ	-210	;MemoryBlock,ByteSize/a1,d0

BootBlockSize:	equ	1024	; Platz fuer BootBlock
VirusFileSize:	equ	14*32	; Platz fuer 14 neue Viren lassen

Wait:		equ	-318	;SignalSet/d0

Getmsg:		equ	-372	;Port/d1
ReplyMsg:	equ	-378	;Message/a1

FindTask:equ	-294		;Task-Struktur suchen
AddPort: equ	-354		;Port erstellen
RemPort: equ	-360		;Port entfernen
OpenDev: equ	-444		;Device oeffnen
CloseDev:equ	-450		;Device schliessen
DoIo:	 equ	-456		;I/O starten und warten
SendIO:	 equ	-462		;I/O Starten und weitermachen

;	*** Intuition Library Base Offsets ***

OpenWindow:	equ	-204	;OWargs (OpenWindowarguments)/a0
CloseWindow:	equ	-72	;Window/a0

;	*** Graphics Library Base Offsets ***

Move:		equ	-240	;X-Pos,Y-Pos,RastPort/d0,d1,a1
Text:		equ	-60	;Testlenth,Text,RastPort/d0,a0,a1

SetAPen:	equ	-342	;PenColor,RastPort/d0,a1

PolyDraw:	equ	-336	;Count,DrawList,RastPort/d0,a0,a1

;	**** DOS Library Base Offsets ****

Delay:		equ	-198		;Timeout/d1
Delete:		equ	-72		;Name /d1
Open:		equ	-30		;Name,AccessMode/d1,d2
Close:		equ	-36		;File/d1
Read:		equ	-42		;File,Buffer,Len/d1,d2,d3
Write:		equ	-48		;File,Buffer,len/d1,d2,d3
Exit:		equ	-144		;ReturnCode

Examine:	equ	-102		;Lock,FileInfoBl/d1,d2
IoErr:		equ	-132		;
Lock:		equ	-84		;Name,Type/d1,d2
ExNext:		equ	-108		;Lock,FileInfoBlock/d1,d2

Mode_Old:	equ	1005		; Modus lesen
Mode_New:	equ	1006		; Modus schreiben

;	***   Window-Port   ***

wd_RPort:	equ	$32
wd_UserPort:	equ	$56

;	***    Message-Port    ***

mp_SigBit:	equ	$0f		;Signal-Bit-Nummer

im_Class:	equ	$14	;Bits wie IDCMP-Flags
im_Code:	equ	$18	;Werte hier
im_IAddress:	equ	$1c	;Adresse von Objekten
im_MouseX:	equ	$20	; Mouse X-Koordinate 

;	****	Window Parameter 	****

Windowdrag:  	equ	$0002		; Window Gadgets
Windowclose: 	equ	$0004
Windowdepth: 	equ	$0008

Smart_Refresh:	equ	$0000		;
Activate:	equ	$1000		;Aktiv nach Open

;		**** Library macros ****

Call:		macro
	jsr	?1(a6)
	endm

CallExec:	macro
	move.l	ExecBase,a6
	jsr	?1(a6)
	endm

CallDos:	macro
	move.l	DosBase(pc),a6
	jsr	?1(a6)
	endm

CallInt:	macro
	move.l	IntuitionBase(pc),a6
	jsr	?1(a6)
	endm

CallGraf:	macro
	move.l	GfxBase(pc),a6
	jsr	?1(a6)
	endm

Grafic:		macro
	move.l	windowptr(pc),a1
	move.l	wd_RPort(a1),a1
	move.l	GfxBase(pc),a6
	jsr	?1(a6)
	endm

Start:
; Intuition Library öffnen

	lea	IntName(pc),a1
	moveq	#0,d0
	CallExec OpenLibrary
	move.l	d0,IntuitionBase
	beq	Error

; Graphics Library öffnen

	lea	GrafName(pc),a1
	moveq	#0,d0
	Call	OpenLibrary
	move.l	d0,GfxBase		;Basis-Zeiger sichern
	beq	CloseINT

; DOS Library öffnen

	lea	DosName(pc),a1
	moveq	#0,d0
	Call	OpenLibrary
	move.l	d0,DosBase
	beq	CloseGraf

; Window öffnen
	lea	WindowDEF(pc),a0	;zeige auf Window-Struktur
	CallINT OpenWindow		;öffne Window
	move.l	d0,WindowPtr		;Window-Zeiger sichern
	beq	CloseDOS

	move.l	d0,a1			;Via Window-Zeiger
	move.l	wd_RPort(a1),a1		;   Rast-Port-Adresse holen
	move.l	a1,RastPort		;      und Sichern

; Port holen und TrackDisk öffnen

	sub.l	a1,a1		;eigener Task (Null in A1)
	CallExec Findtask	;Task suchen
	move.l	d0,readreply+$10;SigTask: eigener Task

	lea	ReadReply(pc),a1
	Call	AddPort		;Add Reply-Port

	lea	DiskIO(pc),a1	;I/O-Struktur
	moveq	#1,d0		;Laufwerk df1:
	moveq	#0,d1		;keine Flags
	moveq	#-4,d3
	lea	TrdDevice(pc),a0;Device-Name
	Call	OpenDev		;Open trackdisk.device
	tst.l	d0		;ok?
	bne.s	OnlyOneDrive	;nein: Dann Nur ein Laufwerk

	lea	DiskIO(pc),a1	; Device wieder schliessen
	Call	CloseDev

	not.w	SecondDrive	; Kennung für Zweit-Laufwerk
	moveq	#0,d3

OnlyOneDrive:
	move.w	#418,d0
	moveq	#85,d1
	move.l	RastPort(pc),a1
	CallGraf Move

	lea	Gadgetadd(pc),a0
	add.l	d3,a0
	moveq	#12,d0
	move.l	RastPort(pc),a1
	Call	Text

	lea	DiskIO(pc),a1	;I/O-Struktur
	moveq	#0,d0		;Laufwerk df0:
	moveq	#0,d1		;keine Flags
	lea	TrdDevice(pc),a0;Device-Name
	CallExec OpenDev	;Open trackdisk.device
	tst.l	d0		;ok?
	bne	RemovePort	;nein: Fehler aufgetreten!

;	****  hole Speicher für Buffer  ****

	move.l	#BootBlockSize+4,d0	; Buffer sichern
	moveq	#Chip,d1
	CallExec AllocMem

	move.l	d0,PointDiskBuff	; Adresse des Speicher merken
	beq	CloseDiskDevice		; Kein Speicher frei

;	***  PolyDraw-installieren (Rahmen zeichnen)  ***

	move.l	RastPort(pc),a1
	move.l	a1,a4

	moveq	#6,d0
	moveq	#91,d1
	CallGraf Move

	move.l	a4,a1
	moveq	#1,d0
	Call	SetAPen

	move.l	a4,a1
	lea	PolyTab(pc),a0
	moveq	#PolySize/4,d0

	Call	PolyDraw

	move.l	a4,a1
	moveq	#2,d0
	Call	SetAPen

	move.l	a4,a1
	lea	PolyTab2(pc),a0
	moveq	#PolySize2/4,d0

	Call	PolyDraw

	move.l	a4,a1
	moveq	#8,d0
	moveq	#15,d1
	Call	Move

	move.l	a4,a1
	moveq	#1,d0
	Call	SetAPen

	move.l	a4,a1
	lea	PolyTab3(pc),a0
	moveq	#PolySize3/4,d0
	Call	PolyDraw

	move.l	a4,a1
	moveq	#2,d0
	Call	SetAPen

	move.l	a4,a1
	lea	PolyTab4(pc),a0
	moveq	#PolySize4/4,d0
	Call	PolyDraw

	move.l	a4,a1
	moveq	#1,d0
	Call	SetAPen

;	****  New-Virus-File laden ****

	lea	LookForNewVirus(pc),a0	; entsprechenden Text
	moveq	#LFNVLen,d0		; ausgeben
	bsr.L	TextOutPut

	move.l	#NewVirusFile,d1	; die New-Virus-File
	move.l	#Mode_Old,d2		; wird zum Lesen 

	CallDos	Open			; geöffnet

	move.l	d0,FileHandle
	bne.s	OpenVirusListOK		;Kein New-Virus_file aus Disk

	bra.s	DiskIN

OpenVirusListOK:
	move.l	d0,d1			; und wird an
	move.l	#NewVirusList,d2	; die Virus Liste angehängt
	move.l	#VirusFileSize+6,d3
	Call	Read

	move.l	FileHandle(pc),d1	; File
	Call	Close			; schliessen

DisplayAndWait:
	bsr.L	DisplayVirusList	; New-Virus-List anzeigen

	moveq	#100,d1			; und 2 Sekunden warten
	CallDos Delay

;	***  BootBlock einladen und ind Window ausgeben ***

DiskIN:	
	lea	ReadBootText(pc),a0	; während des einladen 
	moveq	#RBTLen,d0		; entspr. Text auszeigen
	bsr.L	TextOutPut

	lea	DiskIO(pc),a1

	move.l	#ReadReply,14(a1)	;setze Reply-Port
	move.l	#512*2,36(a1)	 	;Länge: 2 Sektoren
	move.l	PointDiskBuff(pc),40(a1);Buffer
	clr.l	44(a1)			; Offset: Null

	move.w	#2,28(a1)		;Command: READ
	CallExec DoIO			;Track lesen

	move.b  DiskIO+31(pc),d6
	beq.s	BootBlkOK

;	Fehler !!! beim Einlesen des BootBlocks

	bsr.L	ErrorMessage
	bra.s	DiskIN

BootBlkOK:
	bsr.L	CopyBootToProtect	; BootBlock sichern
	bsr.L	ClearStatusLine

	move.l	Protector+ProtectBootOffset(pc),d6
				; Diskkennung nach d6
	clr.b	d6		; entspricht and #$fffffff00,d6

	cmp.l	#"DOS"*$100,d6
	beq.s	DosDisk

	lea	NotDosDisk(pc),a0	; Kein Dos-Disk Meldung 
	moveq	#NotDosDiskLen,d0	; Meldung ausgeben
	bsr.L	TextOutPut

	bra.L	NoVirusOnDisk

DosDisk:

;	*** testen ob identisch mit BootBlock im Speicher ***

	lea	BootBlockData+12(pc),a0	; zeig auf Teil Des BootBlocks
	lea	Protector+ProtectBootOffset(pc),a1

	moveq	#36-1,d3		; 9 Langwort (36Bytes)

TestStandart:
	move.b	(a0,d3.w),d5		; Original-BootBlock Daten mit
	cmp.b	12(a1,d3.w),d5		;  BootBLock vergleichen
	bne.s	NotStandartDisk		; Kein Original-BootBlock

	dbra	d3,TestStandart

	lea	StandartBB(pc),a0	; es ist ein Standart-
	moveq	#StandartBBLen,d0	; BootBlock
	bsr.L	TEXTOutPut

	bra.L	NoVirusOnDisk

NotStandartDisk:
	lea	VirusIDTab(pc),a0

VirusTestLoop:
	tst.l	(a0)		; Virus Liste zu Ende
	beq.s	UnknownBB	; unbekanter BootBlock

	move.l	a0,a3
	move.l	a0,a4			; Virus Name ist 16 Bytes
	moveq	#16,d0
	add.l	d0,a4			; hinter Virus ID

	moveq	#0,d0
	moveq	#0,d1

VirusLoop:
	move.b	(a3,d1.w),d3		; Null-Byte beim Virus ID
	beq.s	VirusFound		; bedeutet: Virus gefunden

	cmp.b	#".",d3			; Der Joker (unknown Byte)
	beq.s	EqualByte		; tue so als ob gleich

	cmp.b	(a1,d0.w),d3
	beq.s	EqualByte

	moveq	#-1,d1			; Es wird 1 zuaddiert und
					; gibt 0
	moveq	#32,d4
EqualByte:
	addq.w	#1,d1

	addq.w	#1,d0
	cmp.w	#BootBlockSize,d0	; Ende des BootBlock
	bne.s	VirusLoop		; noch nit erreicht
	add.l	d4,a0

	bra.s	VirusTestLoop

;	*** SCHEi... Die Disk ist infiziert ***

VirusFound:
	lea	DiskInfect(pc),a0
	move.l	a0,a1

	moveq	#13,d0
	add.l	d0,a1

VirNameCopy:
	move.b	(a4)+,d1	; Kopiere Virus Name hinter "warning"

	tst.b	d1		; Ende des Virus Name
	beq.s	EndVirName

	move.b	d1,(a1)+

	addq	#1,d0
	bra.s	VirNameCopy	

EndVirName:
	moveq	#6-1,d1		; " Virus" Länge
	lea	ToBeAdded(pc),a2

ToAddLoop:
	move.b	(a2)+,d2
	move.b	d2,(a1)+

	addq.w	#1,d0
	dbra	d1,ToAddLoop

	bsr.L	TextOutPut

	moveq	#-1,d0

ColorFlash:
	move.w	d0,$dff180		; Damit es auch auffällt
	dbra	d0,ColorFlash		; zählt nur 1 word

	bra.s	NoVirusOnDisk

UnKnownBB:
	lea	UnKnownBoot(pc),a0	; Die Disk Kenn ich nit
	moveq	#UnKnownBootLen,d0
	bsr.L	TEXTOutPut

	move.w	#$800,d0
	moveq	#-1,d1
ColorFlash2:
	move.w	d1,$dff180
	clr.w	$dff180
	dbra	d0,ColorFlash2
NoVirusOnDisk:
	bsr.L	VirusT			; Display BootBlock

Off_Motor:
	lea	DiskIO(pc),a1
	move.w	#9,28(a1)	;Command: TD_Motor
	clr.l	36(a1)		;  Motor Aus

	CallExec DoIO

;	    ***   Auf Ereignisse warten   ***

WaitEvent:
	bsr	MasterMessage

	cmpi.w	#$200,d4		;Window Closed?
	beq.L	Quit_End		;wenn so dann tschuess

	cmpi.w	#$40,d4			;Gadget up
	beq.s	Do_Gadget		; Gadget losgelassen

	tst.w	EditVirus		; beim Eingeben passiert beim
	bne.s	WaitEvent		; Disk einlegen nicht's

	cmp.w	#$8000,d4		; Diskette eingelegt
	beq.L	DiskIN

	bra.s	WaitEvent

DO_Gadget:
	move.w	$26(a4),d0		;gg_GedgetID (welcher war's)

	tst.w	EditVirus		; Beim Eingeben zählt nur
	beq.s	NormalKlick		; das Eingabe-Gadget

	cmp.w	#3,d0
	beq.L	PressReturnGadget
	bra.s	WaitEvent

NormalKlick:
	cmp.w	#1,d0
	beq.s	PressSTART

	cmp.w	#2,d0
	beq.L	PressKill

	cmp.w	#4,d0
	beq.L	PressSaveBoot

	cmp.w	#5,d0
	beq.L	PressLoadBoot

	cmp.w	#6,d0
	beq.L	PressEditVirusList

	cmp.w	#7,d0
	beq.L	PressSaveVirusList

	cmp.w	#8,d0
	beq.L	PressInfo

	cmp.w	#9,d0
	beq.L	PressInvent
	bra.s	WaitEvent

;	*** hier wird der Protector auf Disk geschrieben ***

PressStart:
	; Die Startup-Sequence wird in Diskbuff gelesen

	move.l	#StartupSequence,d1	; die Startup-Sequence
	move.l	#Mode_Old,d2		; wird zum Lesen 

	CallDos	Open			; geöffnet

	move.l	d0,FileHandle
	bne.s	OpenStartupOK

	lea	NoStartup(pc),a0	; keine Startup-Sequence
	moveq	#NoStartupLen,d0	; auf dieser Disk
	bsr.L	TEXTOutPut

JmpWaitEvent1:
	bra.L	WaitEvent

OpenStartupOK:
	move.l	d0,d1			; und wird in
	move.l	PointDiskBuff(pc),d2	; PointDiskBuffer geschrieben
	move.l	#BootBlockSize,d3	;  1024 Bytes (max.Laenge)
	Call	Read

	move.l	d0,d4
	cmp.w	#BootBlockSize,d0
	beq.L	FileAccessError		; Startup-Sequence zu lang

	not.l	d0			; auf -1 testen
	beq.L	FileAccessError		; wenn ja DOS Fehler

	move.l	FileHandle(pc),d1	; Startup-Sequence
	Call	Close			; schliessen

;	 Nun wird geteste ob das 1. File "FinalProtection" heißt

	lea	ProtectName+4(pc),a0	; Da DF0: nicht in der 
	move.l	PointDiskBuff(pc),a1	; Startup-Sequence +4
	moveq	#ProtectNLen-3-4,d0

CmpStartup:
	move.b	(a0)+,d5
	cmp.b	(a1)+,d5
	bne.s	SaveProtector		; Protector nicht auf Disk
	dbra	d0,CmpStartup

	lea	AlreadyOnDisk(pc),a0	; Der Protector ist schon
	moveq	#AlreadyOnDiskLen,d0	; in der Startup-Sequence
	bsr.L	TEXTOutPut

	bra.s	JmpWaitEvent1

;	*** Protector saven ***

SaveProtector:
	bsr.L	TestDiskProtection	; Diskette schreibgeschützt?
	bne.L	BootWriteOK	; Ja also DiskIN (über BootWritOK)

	move.b	#0,DosNEnd

	move.l	#ProtectName,d1	; Protector auf Disk
	move.l	#Mode_New,d2	; schreiben

	CallDos	Open

	move.l	d0,FileHandle
	beq.L	OpenFileError

	move.l	d0,d1
	move.l	#Protector,d2
	move.l	#ProtectLen,d3

	Call	Write

	not.l	d0			; -1 = DOS Fehler
	bne.s	ProtectorSaveOK

	bsr.L	DiskFull		; Diskette voll !!!

	move.l	#ProtectName,d1		; Protector wieder loeschen
	Call	Delete			; (wir wollen doch keinen
	bra.s	JmpWaitEvent2		;  Schrott)

ProtectorSaveOK:
	move.l	FileHandle(pc),d1	; Protector-File
	Call	Close			; zu

	move.b	#10,DosNEnd

;	*** Nun geänderte Startup-Sequence schreiben ***

					; Startup-Sequence
	move.l	#StartupSequence,d1	; zum Schreiben wieder
	move.l	#Mode_New,d2		; öffnen
	Call	Open

	move.l	d0,FileHandle
	beq.s	OpenFileError

	move.l	d0,d1
	move.l	#ProtectName+4,d2	; selbe Name wie beim Saven
	move.l	#ProtectNLen-4,d3	; auf Disk (+4 wegen df0:)
	Call	Write

	move.l	FileHandle(pc),d1
	move.l	PointDiskBuff(pc),d2
	move.l	d4,d3			; Länge vermerkt
	Call	Write

	not.l	d0
	beq.s	FileAccessError

CloseFile:
	move.l	FileHandle(pc),d1		; File 
	CallDos	Close				; schließen
JmpWaitEvent2:
	bra.L	WaitEvent

OpenFileError:
	bsr.L	ErrorMessage
	bra.s	JmpWaitEvent2

FileAccessError:
	bsr.L	ErrorMessage
	bra.s	CloseFile

DiskFull:
	lea	DiskFullT(pc),a0
	moveq	#DiskFullTLen,d0
	bsr.L	TEXTOutPut

	move.l	FileHandle(pc),d1	; Geöffneten File Schliessen
	CallDos Close
	rts	

;	*** Diskette mit neuem BootBlock beschreiben ***

PressKill:
	bsr.L	ClrDiskBuff

	lea	BootBlockData(pc),a0
	moveq	#EndBootPRG-BootBlockData /4-1,d0

InstallBootBlock:
	move.l	PointDiskBuff(pc),a2

BootCopyLoop:
	move.l	(a0)+,(a2)+		; BootBlock ins Chip-Ram
	dbra	d0,BootCopyLoop	

	bsr.L	TestDiskProtection	; Schreibschutz??
	bne.s	BootWriteOK		; geschützt

	lea	DiskIO(pc),a1
	move.l	a1,a4

	move.l	#ReadReply,14(a1)	;setze Reply-Port
	move.l	#512*2,36(a1)		;Länge: 2 Sektoren
	move.l	PointDiskBuff(pc),40(a1); Buffer

	move.w	#3,28(a1)		; BootBlock in TrackBuffer
	Call	DoIO			; schreiben

	move.l	a4,a1
	move.w	#4,28(a1)		; Von TrackBuffer
	Call	DoIO			; auf Diskette schreiben

	move.b	31(a4),d6		; Fehler sichern

	move.l	a4,a1
	move.w	#5,28(a1)		; TrackBuffer
	Call	DoIO			; als ungueltig erklaeren

	tst.b	d6			; Fehler Testen
	beq.s	BootWriteOK		; kein Fehler

	bsr.L	ErrorMessage		; Fehlermeldung

BootWriteOK:
	bra.L	DiskIN

;  **** BootSave oder BootLoad gedrückt als auf Eingabe warten ****

PressSaveBoot:
	move.w	#1,EditVirus
	bra.s	EnterBootBlockSame

PressLoadBoot:
	move.w	#2,EditVirus

EnterBootBlockSame:
	bsr.L	ClearSecondLine

	moveq	#12,d0
	moveq	#38,d1
	move.l	a4,a1
	Call	Move

	lea	EnterBootName(pc),a0
	moveq	#EnterBootNameLen,d0
	move.l	a4,a1
	Call	Text

	bsr.L	KlickOut

JmpWaitEvent3:
	bra.L	WaitEvent

;	*** beim Eingeben löst Return eine Funktion aus ***

PressReturnGadGet:
	move.w	EditVirus(pc),d0
	beq.s	JmpWaitEvent3

	cmp.w	#1,d0
	beq.s	PressReturn1

	cmp.w	#2,d0
	beq.s	PressReturn2

	cmp.w	#3,d0
	beq.L	PressReturn3

	cmp.w	#4,d0
	beq.L	PressReturn4

	clr.w	EditVirus
	bra.s	JmpWaitEvent3

;	*** BootBlock auf "BootSaveDisk:" abspeichern ***

PressReturn1:
	bsr.L	TestBootFileLen	; die Länge der Eingabe testen

	tst.b	d0		; bei 0
	beq.s	JmpWaitEvent3	; keine Eingabe

;	bsr.L	TestDiskProtection	; Schreibschutz?
;	bne.L	JmpWaitEvent3		; Ja (nur df0:)
;		(da Boot-Save-Disk auch in df1:  nicht zulässig)

	move.l	#BootSaveName,d1	; File zum Schreiben
	move.l	#Mode_New,d2		; öffnen

	CallDos	Open

	move.l	d0,FileHandle
	beq.L	OpenFileError

	move.l	d0,d1
	move.l	#Protector+ProtectBootOffset,d2
	move.l	#BootBlockSize,d3

	Call	Write

	not.w	d0
	beq.s	BootSaveError

	lea	BootGoodSave(pc),a0	; es ging alles Glatt
	moveq	#BootGoodSaveLen,d0
	bsr.L	TEXTOutPut

	bra.L	CloseFile

BootSaveError:
	bsr.L	DiskFull		; Es Gab Ärger:Disk ist voll

	move.l	#BootSaveName,d1	; BootBlock von Diskette
	Call	Delete			; löschen
JMPWaitEvent4:
	bra	WaitEvent

;	*** BootBlock von "BootSaveDisk:" laden ***

PressReturn2:
	bsr.L	ClrDiskBuff

	bsr.L	TestBootFileLen

	tst.b	d0
	beq.s	JMPWaitEvent4

	move.l	#BootSaveName,d1
	move.l	#Mode_Old,d2

	CallDos	Open

	move.l	d0,FileHandle
	bne.s	BootBlockLoaded

	lea	BootBlockNotFound(pc),a0
	moveq	#BootBlockNFLen,d0
	bsr.L	TEXTOutPut
	bra.s	JMPWaitEvent4

BootBlockLoaded:
	move.l	d0,d1
	move.l	PointDiskBuff(pc),d2	; BootBlock einladen
	move.l	#BootBlockSize+2,d3	; +2 um Länge zu testen

	Call	Read

	cmp.l	#-1,d0			; Dos Fehler
	beq.L	FileAccessError

	cmp.l	#1024,d0		; die Länge Testen
	bne.s	NotStandartBBLen	; Länge nicht in Ordung

	move.l	FileHandle(pc),d1
	Call	Close
	bra.s	BootBlockLenOK

NotStandartBBLen:
	cmp.l	#1025-12,d0		; größer als 1012 Bytes
	bcc.L	FileAccessError		; wenn ja dann ...

	move.l	FileHandle(pc),d1	; File schliessen
	Call	Close			;

	bsr.L	CopyBootToProtect	; Das geladene File anzeigen
	bsr.L	VirusT			;

	lea	ModifyToBoot(pc),a0	; Nun muss man entscheiben
	moveq	#ModifyToBLen,d0
	bsr.L	TEXTOutPut

WaitForLeftRight:
	btst	#6,$bfe001		; Ob das Prg. als BootBlock
	beq.s	PressChangeBoot		; abgespeichert werden soll
	btst	#10,$dff016	
	beq.L	DiskIN		; oder nicht

	bra.s	WaitForLeftRight

PressChangeBoot:
;	Hier wird das Programm ab dem 12.Byte kopiert,
;	davor kommen DOS-Kennung, Checksumme und Root-Block

	move.l	PointDiskBuff(pc),a0

	move.l	#"DOS"*$100,(a0)	; Kennung: DOS
	clr.l	4(a0)			; Checksumme Null
	move.l	#$0370,8(a0)		; RootBlock: 880

	lea	Protector+ProtectBootOffset(pc),a1

	move.w	#1012-1,d0
CopyPrgBackwards:
	move.b	(a1,d0.w),12(a0,d0.w)
	dbra	d0,CopyPrgBackwards

	move.w	#BootBlockSize/4 -1,d0
	moveq	#0,d1
	moveq	#1,d2

CalcCheckSumm:
	add.l	(a0,d1.w),d2
	bcc.s	OverFlow

	addq	#1,d2
OverFlow:
	addq.l	#4,d1
	dbra	d0,CalcCheckSumm
	
	sub.l	d2,4(a0)

BootBlockLenOK:
	bsr.L	CopyBootToProtect	; BootBlock sichern
	bsr.L	VirusT			; und in Window darstellen

; fordert auf die Disk zun "installen" einzulegen

	lea	InsertDisk2(pc),a0
	moveq	#InsertDisk2Len,d0

	move.l	a0,a1
	add.l	d0,a1

	lea	KeyBuffer(pc),a2
CopyName:
	move.b	(a2)+,d1
	beq.s	EndOfName
	move.b	d1,(a1)+

	addq	#1,d0
	bra.s	CopyName

EndOfName:
	lea	InsertDisk21,a2
	moveq	#InsertDisk21Len-1,d1

CopyBBInDf0:
	move.b	(a2)+,(a1)+
	addq.w	#1,d0
	dbra	d1,CopyBBinDF0

	bsr.L	TEXTOutPut
	bsr.L	TestDiskIns

;	*** Installier BootBlock auf Disk ***
;		(benutzt Kill-Routinen)

	lea	Protector+ProtectBootOffset(pc),a0
	move.w	#BootBlockSize/4-1,d0
	bra.L	InstallBootBlock

TestBootFileLen:
	bsr.L	ClearSecondLine
	clr.w	EditVirus

	move.b	KeyBuffer(pc),d0
	bne.s	NotEmptyBuff
	rts

NotEmptyBuff:
	bsr.L	ClearStatusLine

	lea	InsertDisk(pc),a0 ; fordert auf die BootSaveDisk
	moveq	#InsertDiskLen,d0 ; einzulegen
	bsr.L	TEXTOutPut

	bsr.L	TestDiskIns

	moveq	#-1,d0		; Kennung für Eingabe OK

EndLenCheck:
	rts

PressEditVirusList:
	bsr.L	DisplayVirusList	; zeigt Liste Der Viren an

	cmp.w	#14,VirusCounter	; testet ob VirusListe Voll
	bne.s	VListNotFull

	lea	VirusOverflow(pc),a0	; VirusList is voll
	moveq	#VirusOverLen,d0
	bsr.L	TEXToutPut

	bsr.L	TestDiskIns
	bra.L	DiskIN

VListNotFull:
	bsr.L	ClearSecondLine

	moveq	#12,d0
	moveq	#38,d1
	move.l	a4,a1
	Call	Move

	lea	EnterVirusN(pc),a0	; fordert den Virus Name
	moveq	#EnterVirusNLen,d0
	move.l	a4,a1
	Call	Text

	bsr.L	KlickOut

	move.w	#3,EditVirus ; Nächste Eingabe als Name Kennzeichnen
JmpWaitEvent5:
	bra.L	WaitEvent

PressReturn3:		; hier geht's dann nach Return weiter

	moveq	#16,d3		; OffSet Für den Namen
	bsr.s	CmpCopyInput	; Eingabe testen und eintragen

	tst.w	d0		; Keine Eingabe also
	beq.s	QuitEdit	; Schluss

	bsr.L	ClearSecondLine

	moveq	#12,d0
	moveq	#38,d1
	move.l	a4,a1
	Call	Move

	lea	EnterVirusID(pc),a0	; fordert Virus ID
	move.l	#EnterVirusIDLen,d0
	move.l	a4,a1
	Call	Text

	bsr.L	KlickOut

	move.w	#4,EditVirus	; Nächste Eingabe als ID deklarieren
	bra.L	DiskIn

PressReturn4:
	moveq	#0,d3		; kein OffSet für VirursID
	bsr.s	CmpCopyInput	; Eingabe testen und eintragen

	tst.w	d0		; Keine Eingabe
	beq.s	QuitEdit

	addq.w	#1,VirusCounter
	bsr.s	ResetEditing

	lea	NewVirusAdded(pc),a0; entsprechend Meldung
	moveq	#NewVirusAddedLen,d0
	bsr.L	TEXTOutPut

	bra.L	DisplayAndWait

QuitEdit:
	bsr.s	ResetEditing
	bra.L	DiskIN

ResetEditing:
	bsr.L	ClearSecondLine ; EingabeZeile Löschen
	clr.w	EditVirus	; keine weitern Eingaben erwartet
	rts

CmpCopyInput:	; Testet länge und kopiert in VirusListe
	lea	StrInfo(pc),a0

	move.w	16(a0),d0		; Lange der Eingabe
	bne.s	InputOK			; es steht was im KeyBuffer

	rts				; Keine Eingabe also mit 0
					; in d0 zurueck
InputOK:
	lea	KeyBuffer(pc),a1
	lea	NewVirusList(pc),a2

	move.w	VirusCounter(pc),d1 	; mal 32 (für jeden Virus sind
	lsl.w	#5,d1		    	;         32 Byte reserviert)
	ext.l	d1			; auf Long erweitern

	add.l	d1,a2			; und hinzuaddieren
	add.l	d3,a2			; Offset für Name dazu
					; ist beim Virus Name 16 

	clr.w	32(a2)	; Nächste VirusAdresse mit 0 EndKenung

CopyKeyBToList:
	move.b	(a1)+,(a2)+	; kopieren vom KeyBuffer in VirusList
	dbra	d0,CopyKeyBToList

	rts

;	*** Speichern der Neuen VirusListe auf Diskette ***

PressSaveVirusList:
	tst.w	VirusCounter		; testen ob überhaupt neue
	bne.s	VirusListNotEmpty	; Viren eingegeben

	lea	VirusListEmpty(pc),a0
	moveq	#VirusListEmptyLen,d0
	bsr.L	TEXToutPut
	bra.L	WaitEvent

VirusListNotEmpty:
	bsr.L	DisplayVirusList	; VirusListe Zeigen

	lea	InsertDisk3(pc),a0	; fordert eine Disk
	moveq	#InsertDisk3Len,d0
	bsr.L	TEXToutPut

	bsr.L	TestDiskIns

	lea	SaveVirusList(pc),a0
	moveq	#SaveVirusListLen,d0
	bsr.L	TEXTOutPut

	move.l	#NewVirusFile,d1	; New-Virus-List auf Disk
	move.l	#Mode_New,d2		; schreiben

	CallDos	Open

	move.l	d0,FileHandle
	beq.L	OpenFileError

	move.l	d0,d1
	move.l	#NewVirusList,d2
	move.l	#VirusFileSize+6,d3	; Länge +6 weil der Virus-
				; counter und Endkennung mit sollen

	Call	Write

	not.l	d0		; -1 Dos Fehler
	bne.s	NewVirusSaveOK

	bsr.L	DiskFull

	move.l	#NewVirusFile,d1
	Call	Delete
JmpDiskIN1:
	bra.L	DiskIN

NewVirusSaveOK:
	move.l	FileHandle(pc),d1
	Call	Close
	bra.s	JmpDiskIN1

;	*** Für Info wird die VirusDisplay-Routine benutzt ***

PressInfo:
	bsr.L	CLRDiskBuff		; loeschen des Diskbuffer
	lea	InfoT0-1(pc),a3		; und Text dort eintragen

OutInWindow:
	move.l	PointDiskBuff(pc),a4

	moveq	#0,d2
	moveq	#0,d3

CharCopyLoop:
	addq	#1,d2
	move.b	(a3,d2.w),d1
	beq.s	EndOfText		; auf Textende (0) testen

	cmp.b	#10,d1			; auf LineFeed testen
	beq.s	EndOfLine

	move.b	d1,(a4,d3.w)		; Zeichen Ok
	addq	#1,d3

	bra.s	CharCopyLoop

EndOfLine:
	add.w	#64,d3		; das ergibt 
	and.b	#-64,d3		; ein LineFeed

	bra.s	CharCopyLoop

EndOfText:
	bsr.L	VirusT		; Text ausgeben

	bsr.L	TestDiskINS
	bra.s	JmpDiskIN1

PressInvent:
	tst.w	SecondDrive	; ZweitLaufwerk
	beq.s	OnlyOneDr	; nein!

	moveq	#"0",d1		; DF 0

	cmp.w	#466,d6		; MousPosition in d6 wird zum teilen
	bcs.s	Drivedf0	; des Gadget benutzt

	addq	#1,d1		; DF 0 +1 = DF1 

Drivedf0:
	move.b	d1,Path+2	; in PfadNamen
	move.b	d1,ListInvent+ListInventLen-2; und Meldung eintragen

OnlyOneDr:
	lea	ListInvent(pc),a0	; listing Directory
	moveq	#ListInventLen,d0	; ausgeben
	bsr.L	TEXTOutPut

	bsr.L	ClrDiskBuff		; Window loeschen
	bsr.L	VirusT

	clr.w	XOutPut
	clr.w	YOutPut

	move.l	#Path,d1	; zugriff auf den Pfad
	moveq	#-2,d2
	CallDos	Lock

	move.l	d0,SaveLock	; Lock Merken
	beq.s	InventError	; ging Schief!!

	move.l	d0,d1		; Lock nach D1

	move.l	#FIB,d2		; FileInfoBlock
	Call	Examine		; durchsuchen

	tst.l	d0		; nicht eingelesen
	beq.s	InventError

InventLoop:
	move.l	SaveLock(pc),d1	; Lock holen
	move.l	#FIB,d2		; FileInfoBlock
	CallDos	ExNext		; Nächsten Eintrag holen

	tst.l	d0		; Fehler oder Kein weiterer Eintrag
	beq.s	InventError

	bsr.s	OutFileName	; FileName ausgeben
	bra.s	InventLoop

InventError:
	Call	IoErr		; Fehler testen
	cmp.l	#232,d0		; No more Entries??
	beq.s	InventOK	; dann ist es OK

	bsr.L	ErrorMessage
	bra.L	DiskIN

InventOK:
	lea	NoMoreEntries(pc),a0	; kein weiteren Einträge
	moveq	#NoMoreEntriesLen,d0
	bsr.L	TextOutPut

	bsr.L	TestDiskIns
	bra.L	DiskIn

;	*** FileName ausgeben ***

OutFileName:
	lea	FIB+8(pc),a0	; FileInfoBlock
	moveq	#-1,d0

CharCounter:		; zählen der Zeichen bis zum 0 Byte
	addq	#1,d0
	tst.b	(a0)+
	bne.s	CharCounter

	cmp.w	#16,d0		; nicht Länger als 15 Bytes
	bcs.s	NotToLong

	moveq	#15,d0		; der Rest wieder weggeschnitten

NotToLong:
	move.l	d0,d6		; sichern der Länge

	move.w	YOutPut(pc),d0	; Eintrag am unteren
	cmp.w	#16,d0		; Ende des Window ?
	bne.s	NotLastLine	; NEE

	clr.w	YOutPut		; Wieder Oben

	addq	#1,XOutPut	; und eine Zeile weiter rechts
	move.w	XOutPut(pc),d0
	cmp.w	#3,d0		; 3. Zeile
	bne.s	NotLastLine	; Nein !

;	*** Seite voll ***

	clr.w	XOutPut		; Wieder Oben Links

	lea	PressForMore(pc),a0
	moveq	#PressFMLen,d0	; und Ausgeben das Seite voll
	bsr.L	TextOutPut

	bsr.L	TestDiskIns	; wir warten auf was

	bsr.L	ClearStatusLine	; alles wieder
	bsr.L	CLRDiskBuff	; schön
	bsr.L	VirusT		; löschen

NotLastLine:
	addq.w	#1,YOutPut	; eine Zeile tiefer

	move.w	YOutPut(pc),d1
	mulu	#8,d1		; Positionen berechnen
	add.w	#93,d1

	move.w	XOutPut(pc),d0
	mulu	#168,d0
	add.w	#10,d0

	move.l	Rastport(pc),a4
	move.l	a4,a1
	CallGraf Move

	lea	FIB(pc),a3

	tst.w	4(a3)		; testen ob file oder dir
	bne.s	ItsAFile

	moveq	#3,d0		; Bei DIR. aktuelle Farbe ändern
	move.l	a4,a1
	Call	SetAPen

ItsAFile:
	move.w	d6,d0	; in D6 hab ich die Länge zwischengelagert

	lea	FIB+8(pc),a0; FileName
	move.l	a4,a1
	Call	Text

	moveq	#1,d0	; Farbe wieder normal
	move.l	a4,a1
	Call	SetAPen

	rts	

;	      ***  Ab hier Endet das PRG  ***

;	*** Speicher ,Librarys, TDDevice freigeben ***

Quit_End:

FreeMemory:
	move.l	#BootBlockSize+4,d0
	move.l	PointDiskBuff(pc),a1
	CallExec FreeMem	; Speicher freigeben

CloseDiskDevice:
	lea	DiskIO(pc),a1
	Call	CloseDev	; Trackdisk-Device schliessen

RemovePort:
	lea	ReadReply(pc),a1
	Call	RemPort		; Port entfernen

CloseXWindow:
	move.l	WindowPTR(pc),a0
	CallINT CloseWindow	; Window wieder schliessen

CloseDOS:
	move.l	DOSBase(pc),a1
	CallExec CloseLibrary	

CloseGraf:
	move.l	GfxBase(pc),a1
	Call	CloseLibrary

CloseInt:
	move.l	IntuitionBase(pc),a1
	Call	CloseLibrary

Error:
	rts			;Good Bye

;	*** Diskettenschreibschutz testen ***

TestDiskProtection:
	bsr.s	TestState	; Status testen
	beq.s	NotProtected	; nicht geschützt

	lea	DiskProt(pc),a0	; Diskette schreibgeschützt
	moveq	#DiskProtLen,d0	;
	bsr.s	TextOutPut	; ausgeben
	bsr.L	TestDiskIns	; auf Message oder so warten

; nochmal testen (vieleicht ist jetzt der Schreibschutz unten)

TestState:
	lea	DiskIO(pc),a1
	move.w	#15,28(a1)	; ProtStatus
	CallExec DoIO

	move.l	DiskIO+32(pc),d0
NotProtected:
	rts

;		*** Error-Message ***

ErrorMessage:
	lea	DiskProblems(pc),a0
	moveq	#DiskProbLen,d0
	bsr.s	TextOutPut

	bsr.L	TestDiskIns

ClearSecondLine:
	moveq	#38,d1
	bra.s	ClearLineJmp

ClearStatusLine:
	moveq	#25,d1			;Y-Position

ClearLineJmp:
	moveq	#12,d0			;X-Position

	move.l	RastPort(pc),a1
	move.l	a1,a4
	CallGraf Move			;Funktion Move to X,Y

	move.l	a4,a1
	lea	ClearCode(pc),a0		;Adresse Text
	moveq	#ClearCodeLen,d0		;seine Länge
	Call	Text			;und ausgeben

	rts

;	*** Text mittig zentriert ausgeben ***

TextOutPut:
	movem.l	d0/a0,-(sp)

	bsr.s	ClearStatusLine

	movem.l	(sp)+,d0/a0

	move.w	d0,d1
	move.w	d0,d2

	lsl.w	#2,d0

	sub.w	#262,d0
	neg.w	d0

	move.l	a4,a1
	moveq	#25,d1
	Call	Move

	move.l	a4,a1
	move.l	d2,d0
	Call	Text

	rts

KlickOut:
	move.w	#222,d0		; "Klick Here" ausgeben
	moveq	#38,d1
	move.l	RastPort(pc),a1
	CallGraf Move

	lea	DisplayKlick(pc),a0
	move.l	#DisplayKlickLen,d0
	move.l	RastPort(pc),a1
	Call	Text

	rts

;	***	Wartet und holt Message	   ***

MessageLoop:
	move.l	WindowPtr(pc),a0
	move.l	wd_UserPort(a0),a0
	move.b	MP_SigBit(a0),d1

	moveq	#0,d0
	bset	d1,d0

	Call	Wait

MasterMessage:
	move.l	WindowPTR(pc),a0	;zeige auf Window-Struktur
	move.l	wd_UserPort(a0),a0	;nun auf Message-Port
	CallExec GetMSG

	tst.l	d0
	beq.s	MessageLoop

	move.l	d0,a1
	move.l	im_CLass(a1),d4
	move.w	im_Code(a1),d5
	move.w	im_MouseX(a1),d6
	move.l	im_IAddress(a1),a4

	Call	ReplyMSG

	rts

;	*** Warten auf DiskInsert oder linken Mauskn. ***

TestDiskIns:
	btst	#6,$bfe001	; vorher Knopf nicht druecken
	beq.s	TestDiskIns

ButtonReleased:
	btst	#6,$bfe001	; test linken MausKnopf
	beq.s	LeaveWaitLoop

	move.l	WindowPTR(pc),a0	;zeige auf Window-Struktur
	move.l	wd_UserPort(a0),a0	;nun auf Message-Port
	CallExec GetMSG			; Message Holen

	tst.l	d0			; keine Message und kein
	beq.s	ButtonReleased		; MausKnopf

	move.l	d0,a1			; Message zurueck-
	move.l	IM_CLass(a1),d4		; schicken
	Call	ReplyMSG

	cmp.w	#$8000,d4		; muss "DiskInsert" sein
	bne.s	ButtonReleased
	
LeaveWaitLoop:
	rts

;	***	DiskBuffer Löschen	***

CLRDiskBuff:
	move.w	#BootBlockSize/4-1,d0
	move.l	PointDiskBuff(pc),a0

CLRDiskBuffLoop:
	move.l	#"    ",(a0)+		; füllen mit Spaces
	dbra	d0,CLRDiskBuffLoop
	rts

;	***   BootBlock in Protector   ***

CopyBootToProtect:
	move.l	PointDiskBuff(pc),a0
	lea	Protector+ProtectBootOffset(pc),a1
	move.w	#BootBlockSize/4-1,d0	; 256 Lanworte kopieren

CopyBTP:
	move.l	(a0)+,(a1)+
	dbra	d0,CopyBTP

	rts

;	***     Virus-Test-Display     ***

VirusT:
	move.l	PointDiskBuff(pc),a2	; A2 dient als Quelle
	move.l	a2,a3			; A3 als Ziel
	move.l	RastPort(pc),a1		; Rastport holen
	move.l	a1,a4			; und Sichern
	move.l	GfxBase(pc),a6		; Graphics-Base

	moveq	#015,d3			; Anzahl der Zeilen -1
	moveq	#101,d5			; Y-StartPosition

ModifyLoop:				; direkter Rastport Zugriff
	move.w	#10,36(a4)		; X-StartPosition
	move.w	d5,38(a4)		; Y-Position setzen

	moveq	#63,d2			; Zeichen pro Zeile

ModifyLoop2:
	move.b	(a2,d2.w),d1
	cmp.b	#32,d1
	bcs.s	Point

GreaterByte:
	btst	#7,d1
	beq.s	CharOK

Point:
	moveq	#".",d1

CharOK:
	move.b	d1,(a3,d2.w)
	dbra	d2,ModifyLoop2

	moveq	#64,d0			; 64 Zeichen pro Zeile

	addq	#8,d5			; eine Zeile weiter runter
	add.l	d0,a2

	move.l	a4,a1
	move.l	a3,a0
	Call	Text			; ausgeben

	dbra	d3,ModifyLoop

	rts

;	*** zeigt Liste aller eingetragenen Viren ***

DisplayVirusList:
	bsr.L	ClrDiskBuff

	moveq	#VirusTLen-1,d0
	lea	VirusText(pc),a0
	move.l	PointDiskBuff(pc),a1
	add.l	#64,a1

CopyVLLoop:
	move.b	(a0)+,24(a1,d0.w)
	move.b	#"-",88(a1,d0.w)
	dbra	d0,CopyVLLoop

	lea	VirusIDTab+16(pc),a0
	add.l	#128,a1

	lea	ToBeAdded(pc),a2

	moveq	#0,d2

StartVirusNC:
	moveq	#0,d0

VirusNameCopy:
	move.b	(a0,d0.w),d1
	beq.s	Add_Virus
	move.b	d1,(a1,d0.w)

	addq	#1,d0
	bne.s	VirusNameCopy

Add_Virus:
	move.l	a1,a3
	add.l	d0,a3

	moveq	#6-1,d1
ToAddCopy:
	move.b	(a2,d1.w),(a3,d1.w)
	dbra	d1,ToAddCopy

NextVir:
	moveq	#32,d0
	add.l	d0,a0
	add.l	d0,a1	

	addq	#1,d2
	cmp.w	#10,d2
	bne.s	NotNewViruses

	moveq	#64-1,d1	; zieht Strich unter "feste" Viren
DrawLine:
	move.b	#"-",(a1)+
	dbra	d1,DrawLine	

NotNewViruses:
	tst.w	(a0)			; Ende der VirusListe
	bne.s	StartVirusNC

	bsr.L	VirusT

	rts

;		*** Datenbereich ***

IntuitionBase:	dc.l	0
GfxBase:	dc.l	0
DOSBase:	dc.l	0
WindowPtr:	dc.l	0
RastPort:	dc.l	0
PointDiskBuff:	dc.l	0
FileHandle:	dc.l	0
SaveLock:	dc.l	0

TrdDevice:	dc.b	"trackdisk.device",0
	align	2
IntName:	dc.b	"intuition.library",0
	align	2
GrafName:	dc.b	"graphics.library",0
	align	2
DosName:	dc.b	"dos.library",0
	align	2

ReadBootText:	dc.b	"Reading BootBlock of df0:"
RBTLen:	equ	*-ReadBootText
	align	2

LookForNewVirus:dc.b	"Looking for New-Virus-List"
LFNVLen:	equ	*-LookForNewVirus
	align	2

InsertDisk:	dc.b	"Insert Boot-Save-Disk in any drive"
InsertDiskLen:	equ	*-InsertDisk
	align	2

InsertDisk21:	dc.b	") in df0:"
InsertDisk21Len:equ	*-InsertDisk21
	align	2

InsertDisk2:	dc.b	"Insert disk to install (with "
InsertDisk2Len:	equ	*-InsertDisk2
		blk.b	16+InsertDisk21Len
	align	2

InsertDisk3:
	dc.b	"Insert disk with the Final Boot Protector in df0:"
InsertDisk3Len:	equ	*-InsertDisk3
	align	2

DiskFullT:	dc.b	"disk full error"
DiskFullTLen:	equ	*-DiskFullT
	align	2

DiskProblems:	dc.b	"DISKERROR: check your drive & disk"
DiskProbLen:	equ	*-DiskProblems
	align	2
DiskProt:	dc.b	"disk in df0: is write-protected"
DiskProtLen:	equ	*-DiskProt
	align	2

BootBlockNotFound:dc.b	"BootBlock not found"
BootBlockNFLen:	equ	*-BootBlockNotFound
	align	2

ModifyToBoot:
	dc.b	"modify this file to a BootBlock (left OK/right NO)"
ModifyToBLen:	equ	*-ModifytoBoot

AlreadyOnDisk:	dc.b	"Protector already on disk"
AlreadyOnDiskLen:	equ	*-AlreadyOnDisk
	align	2

NoStartup:	dc.b	"No Startup-Sequence on this disk"
NoStartupLen:	equ	*-NoStartup
	align	2

BootGoodSave:	dc.b	"BootBlock saved to Boot-Save-Disk"
BootGoodSaveLen:equ	*-BootGoodSave
	align	2

NotDosDisk:	dc.b	"Not a DOS-disk"
NotDosDiskLen:	equ	*-NotDosDisk
	align	2

StandartBB:	dc.b	"normal BootBlock"
StandartBBLen:	equ	*-StandartBB
	align	2

UnKnownBoot:	dc.b	"unknown BootBlock"
UnKnownBootLen:	equ	*-UnKnownBoot
	align	2

VirusText:	dc.b	" tsiLsuriV "	; Rückwärts !
VirusTLen:	equ	*-VirusText
	align	2

DiskInfect:	dc.b	"Warning! -> "
		blk.b	20,32		; Hier wird der VirusName
					; hinkopiert
ToBeAdded:	dc.b	" Virus"	; wird an VirusName angehängt
	align 2

DisplayKlick:	dc.b	"KLICK HERE"
DisplayKlickLen:equ	*-DisplayKlick
	align	2

EnterBootName:	dc.b	"BootBlock Name ->"
EnterBootNameLen:equ	*-EnterBootName
	align	2

EnterVirusN:	dc.b	"Name of the Virus ->"
EnterVirusNLen:	equ	*-EnterVirusN
	align	2

EnterVirusID:	dc.b	"ID of the Virus   ->"
EnterVirusIDLen:	equ	*-EnterVirusID
	align	2

NewVirusAdded:	dc.b	"New Virus added to New-Virus-List"
NewVirusAddedLen:	equ	*-NewVirusAdded

VirusListEmpty:	dc.b	"New-Virus-List is empty"
VirusListEmptyLen:	equ	*-VirusListEmpty
	align	2

VirusOverflow:	dc.b	"New-Virus-List is full"
VirusOverLen:	equ	*-VirusOverflow
	align	2

SaveVirusList:	dc.b	"Save New-Virus-List to disk"
SaveVirusListLen:	equ	*-SaveVirusList
	align	2

ListInvent:	dc.b	"listing directory of df0:"
ListInventLen:	equ	*-ListInvent
	align	2

Path:		dc.b	"df0:",0,0
		dc.b	"    "
GadgetAdd:	dc.b	"df0:    df1:"

PressForMore:	dc.b	"press left mouse button for more"
PressFMLen:	equ	*-PressForMore
	align	2

NoMoreEntries:	dc.b	"No more entries in this directory"
NoMoreEntriesLen:	equ	*-NoMoreEntries

InfoT0:
dc.b 10
dc.b "                The Final BootProtector V1.0",10
dc.b "               ------------------------------",10,10
dc.b "     The Final BootProtector is a very powerfull Tool.",10
dc.b 10
dc.b "                    Please use it with care!",10
dc.b "You could protect your disks against ANY BootBlock-VIRUS",10
dc.b "                       (yet and future)",10,10
dc.b "Any change in bootblock will be detected "
dc.b "(infected or installed)"
dc.b "In that case you could write the old bootblock"
dc.b " back to disk.",10
dc.b 10,"author: A.L."
dc.b 0

ClearCode:	blk.b	62," "
ClearCodeLen:	equ	*-ClearCode
	align	2

SecondDrive:	dc.w	0
EditVirus:	dc.w	0
YOutPut:	dc.l	0
XOutPut:	dc.l	0
	align	4

DiskIO:		blk.l	20,0	; Disk IO
ReadReply:	blk.l	8,0	; Task-repley
FIB:		blk.b	$108,0	; File-Info-Block

BootSaveName:	dc.b	"Boot-Save-Disk:" ; Save BootBlock to this
KeyBuffer:	blk.b	32,0		  ; Name Of BootBlock

	align	2
;	            ***  Window-Daten ***
			 
W_Title1:dc.b	"     --------   The Boot Protector  V1.1  -------- "
	dc.b	"     ",0
	align	2

WindowDEF:
	dc.w	50,20			;links oben
	dc.w	533,230			;Breite Höhe
	dc.b	-1,-1			;Pens des Screen
	dc.l	$8240			;GadgetsFlags
;		CloseWindow!Gadgetup!GadgetDown!DiskInsert 
dc.l	WindowDrag!WindowDepth!WindowClose!Smart_Refresh!Activate
					;Window Flag
	dc.l	Gadget0			;keine User Gadgets
	dc.l	0			;keine User-Checkmarktitle
	dc.l	W_Title1		;Title des window
	dc.l	0			;kein eigener SCREEN
	dc.l	0			;Keine Super Bitmap
	dc.w	0,0			;min. Größe
	dc.w	0,0			;max. Größe
	dc.w	$0001  ;WBENCHSCREEN		;Use Workbech Screen

Gadget0:
	dc.l	Gadget1		;^Nächstes Gadget
	dc.w	8		;Links
	dc.w	44		;	Oben
	dc.w	121		;Breite
	dc.w	21		;Höhe
	dc.w	1 ;GadgHBox	;Flags
	dc.w	1		;Activation
	dc.w	1 ;StrGadget	;Gadget - Type
	dc.l	SpecialBorder	;^Image oder ^Border
	dc.l	0		;Alternative von "
	dc.l	GadText0	;^ Text-Struktur
	dc.l	0		; ?
	dc.l	0		;^Str oder ^PropInfo
	dc.w	1		; User-ID
	dc.l	0		; User-Daten

Gadget1:
	dc.l	GadGet2
	dc.w	8
	dc.w	68
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText1
	dc.l	0
	dc.l	0
	dc.w	2
	dc.l	0

Gadget2:
	dc.l	GadGet3
	dc.w	10
	dc.w	32
	dc.w	515
	dc.w	10
	dc.w	0
	dc.w	$201
	dc.w	$004
	dc.l	StrGadBorder
	dc.l	0
	dc.l	GadText2
	dc.l	0
	dc.l	StrInfo
	dc.w	3
	dc.l	0

Gadget3:
	dc.l	GadGet4
	dc.w	139
	dc.w	44
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText3
	dc.l	0
	dc.l	0
	dc.w	4
	dc.l	0

Gadget4:
	dc.l	GadGet5
	dc.w	139
	dc.w	68
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText4
	dc.l	0
	dc.l	0
	dc.w	5
	dc.l	0

Gadget5:
	dc.l	GadGet6
	dc.w	271
	dc.w	44
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText5
	dc.l	0
	dc.l	0
	dc.w	6
	dc.l	0

Gadget6:
	dc.l	Gadget7
	dc.w	271
	dc.w	68
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText6
	dc.l	0
	dc.l	0
	dc.w	7
	dc.l	0

Gadget7:
	dc.l	Gadget8
	dc.w	403
	dc.w	44
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText7
	dc.l	0
	dc.l	0
	dc.w	8
	dc.l	0

Gadget8:
	dc.l	0
	dc.w	403
	dc.w	68
	dc.w	121
	dc.w	21
	dc.w	1
	dc.w	1
	dc.w	1
	dc.l	SpecialBorder
	dc.l	0
	dc.l	GadText8
	dc.l	0
	dc.l	0
	dc.w	9
	dc.l	0

SpecialBorder:			; weiß
	dc.w	0		; Start Links
	dc.w	0		;	Oben
	dc.b	1		;Vordergrund-Pen
	dc.b	0		;BackPen
	dc.b	0		;DrawMode		
	dc.b	7		;Anzahl Paare
	dc.l	SXYData		;Arry mit Paaren
	dc.l	SpBord2		;Nächstes

SpBord2:			; schwarz
	dc.w	0
	dc.w	0
	dc.b	2
	dc.b	0
	dc.b	0		
	dc.b	6
	dc.l	SXYData2
	dc.l	0

SXYData:
	dc.w	0,0
	dc.w	121,0
	dc.w	120,1
	dc.w	1,1
	dc.w	1,20
	dc.w	0,19
	dc.w	0,0

SXYData2:
	dc.w	121,0
	dc.w	121,20
	dc.w	0,20

	dc.w	1,19
	dc.w	120,19
	dc.w	120,1

StrGadBorder:			; weiß
	dc.w	0		; Start Links
	dc.w	0		;	Oben
	dc.b	1		;Vordergrund-Pen
	dc.b	0		;BackPen
	dc.b	0		;DrawMode		
	dc.b	7		;Anzahl Paare
	dc.l	StrData		;Arry mit Paaren
	dc.l	StrBord2		;Nächstes

StrBord2:			; schwarz
	dc.w	0
	dc.w	0
	dc.b	2
	dc.b	0
	dc.b	0		
	dc.b	6
	dc.l	StrData2
	dc.l	0

StrData:
	dc.w	-2,-3
	dc.w	515,-3
	dc.w	514,-2
	dc.w	-1,-2
	dc.w	-1,8
	dc.w	-2,9
	dc.w	-2,-3

StrData2:
	dc.w	515,-3
	dc.w	515,9
	dc.w	-2,9

	dc.w	-1,8
	dc.w	514,8
	dc.w	514,-2

StrInfo:
	dc.l	KeyBuffer	;^ KeyBuffer
	dc.l	0		;^ Undo-Buffer
	dc.w	0		; KeyPos
	dc.w	15 +1		; BufferSize +1
	dc.w	0		; Cursor-Zeichen
	dc.w	0		; 
	dc.w	0		; Zeichen in Buffer
	dc.w	100		; Zeichen Sichtbar
	dc.w	0		; Cleft
	dc.w	0		; CTop
	dc.l	0		;^ Layer of Gadget
	dc.l	0		; Long Int ???
	dc.l	0		; eigene KeyMap

GadText0: dc.b	3,0		; Color
	dc.b	0,0
	dc.w	14,7		; X,Y Position
	dc.l	0		;Sys-Font
	dc.l	StrG0		; ^Text
	dc.l	0

StrG0:	dc.b	"Protect Disk",0
	align	2

GadText1: dc.b	3,0
	dc.b	0,0
	dc.w	14,7
	dc.l	0
	dc.l	StrG1
	dc.l	0

StrG1:	dc.b	"Install Disk",0
	align	2

GadText2: dc.b	1,0
	dc.b	0,0
	dc.w	2,0
	dc.l	0
	dc.l	0 ;StrG2
	dc.l	0

StrG2:	dc.b	"Klick Gadget",0
	align	2

GadText3: dc.b	3,0
	dc.b	0,0
	dc.w	5,7
	dc.l	0
	dc.l	StrG3
	dc.l	0

StrG3:	dc.b	"Save BootBlock",0
	align	2

GadText4: dc.b	3,0
	dc.b	0,0
	dc.w	5,7
	dc.l	0
	dc.l	StrG4
	dc.l	0

StrG4:	dc.b	"Load BootBlock",0
	align	2

GadText5: dc.b	3,0
	dc.b	0,0
	dc.w	25,7
	dc.l	0
	dc.l	StrG5
	dc.l	0

StrG5:	dc.b	"Add Virus",0
	align	2

GadText6: dc.b	3,0
	dc.b	0,0
	dc.w	5,7
	dc.l	0
	dc.l	StrG6
	dc.l	0

StrG6:	dc.b	"Save VirusList",0
	align	2

GadText7: dc.b	3,0
	dc.b	0,0
	dc.w	44,7
	dc.l	0
	dc.l	StrG7
	dc.l	0

StrG7:	dc.b	"Info",0
	align	2

GadText8: dc.b	3,0
	dc.b	0,0
	dc.w	14,3
	dc.l	0
	dc.l	StrG8
	dc.l	0

StrG8:	dc.b	"directory of",0
	align	2

;	***   PolyDraw-Tabelle   ***

PolyTab:
	dc.w	6,225
	dc.w	7,224
	dc.w	7,91
	dc.w	525,91
	dc.w	524,92
	dc.w	6,92
	dc.w	525,92

PolySize:	equ	*-PolyTab

PolyTab2:
	dc.w	525,225
	dc.w	6,225
	dc.w	7,224
	dc.w	524,224
	dc.w	524,91
PolySize2:	equ	*-PolyTab2

PolyTab3:
	dc.w	525,15
	dc.w	524,16
	dc.w	9,16

	dc.w	9,27
	dc.w	8,28
	dc.w	8,15
	dc.w	525,16

PolySize3:	equ	*-PolyTab3

PolyTab4:
	dc.w	525,27
	dc.w	10,27
	dc.w	9,28
	dc.w	524,28
	dc.w	524,17

PolySize4:	equ	*-PolyTab4

NewVirusFile:	dc.b	"df0:New-Virus-List",0
	align	2

StartupSequence:dc.b	"df0:s/Startup-Sequence",0
	align	2

ProtectName:	dc.b	"df0:FinalProtection"	; der Name auf Disk
DosNEnd:		dc.b	0,10
ProtectNLen:	equ	*-ProtectName		; in Startup-Sequence
	align	4

;	**** Hier muss der Protector hingeladen werden ****

ProtectBootOffset:	equ	968

ProtectLen:	equ	2048
Protector:
	blk.b	ProtectLen,0
EndProtector:

	align	4

;	**** 	Boot-Block   ****

; Achtung bei jeder Veränderung auch die Checksumme ändern

BootBlockData:
	dc.b	"DOS",0		; Disk ID
	dc.l	$dfeee40f	; Checksumm
	dc.l	$370		; Root-Block (880)

;	****  Hier fängt das Boot-PRG an  ****

	lea	DosLib(pc),a1	; Dos.library
	jsr	-96(a6)		; FindResisdent

	tst.l	d0
	beq.s	FindResisdentError

	move.l	d0,a0
	move.l	$0016(a0),a0
	moveq	#0,d0

BootEnd:
	rts

FindResisdentError:
	moveq	#-1,d0
	bra.s	BootEnd

DosLib:
	dc.b	"dos.library",0
EndOriginalBoot:
dc.b	"                        "
dc.b	"Installed with the FinalBootProtector V1.0"
EndBootPRG:
	align	4

;	**** 	Virus-Tabelle 	****

VirusIDTab:	; Dies sind die mir bekannten Viren

	dc.b	"SCA!",0
	dc.b	     "           "
	dc.b	"SCA",0
	dc.b	    "            "

	dc.b	"Virus by",0
	dc.b		 "       "
	dc.b	"Byte Bandit",0
	dc.b		    "    "

	dc.b	"DASA0.2",0
	dc.b	        "        "
	dc.b	"Byte Warrior",0
	dc.b	             "   "

	dc.b	"North Star",0
	dc.b		   "     "
	dc.b	"NORTH STAR",0
	dc.b		   "     "
	dc.b	"OBELISK CREW",0
	dc.b		     "   "
	dc.b	"Obelisk Crew",0
	dc.b		     "   "

	dc.b	"WARHAWK SAYS",0
	dc.b		     "   "
	dc.b	"WARHAWK",0
	dc.b		"        "

	dc.b	"V I R U S !!!",0
	dc.b		      "  "
	dc.b	"Micro-Master",0
	dc.b		     "   "

	dc.b	"Marl of LSD is ",0
	dc.b	"LSD",0
	dc.b	    "            "

	dc.b	"h..p.Nup...dos.",0
	dc.b	"a coverd ",0
	dc.b	          "      "

	dc.b	"by Disk-Doktors",0
	dc.b	"Disk-Doktors",0
	dc.b		     "   "

NewVirusList:	; Hier kommen die neuen Viruen hin
	dc.l	0
	blk.b	VirusFileSize,0	; (32*14) Platz für 14 neue Viren

VirusCounter:	dc.w	0	; der steht hier hinten damit er
				; mitgesavet wird

xx:	dc.l	0
