    incdir  'include:'
    nolist
    include 'exec/execall.i'            ;preassembled exec includes
    include 'intuition/intuitionall.i'  ;preassembled intuition includes
    include 'devices/devicesall.i'      ;preassembled devices includes
    include 'libraries/librariesall.i'  ;preassembled libraries includes
    include 'offsets.i'             ;saves typing all those XREF's for
                                    ;amiga.lib  (preassembled offsets)
    list

    objfile 'Virus_Checker.o'
    addsym

Execbase    equ     0
Dosbase     equ     4
Intuibase   equ     8
Gfxbase     equ     12
Task        equ     16
Message     equ     20
Mementry    equ     24
Buff        equ     28
Buffer      equ     32
Oldpri      equ     36
DiskIO      equ     40
Port        equ     44
VFound      equ     48
DInstall    equ     52
DCheck      equ     56
Mywindow    equ     60
RPort       equ     64
Userport    equ     68
Signal      equ     72
I           equ     76
SFile       equ     80
SBuffer     equ     84
SSize       equ     88
SMem        equ     92
NHunk       equ     96
FHunk       equ     100
LHunk       equ     104
Unit        equ     108
Changecount equ     112

    section    Virus_Checker_Loader,CODE
Loader:
    move.l  4,a6
    moveq   #0,d7
    sub.l   a1,a1
    jsr     _LVOFindTask(a6)
    move.l  d0,a4
    tst.l   pr_CLI(a4)          ;are we called from CLI or WB
    bne.s   CLI
    lea     pr_MsgPort(a4),a0   ;WB then get message port
    jsr     _LVOWaitPort(a6)    ;wait for the startup message
    lea     pr_MsgPort(a4),a0
    jsr     _LVOGetMsg(a6)      ;get the startup message from WB
    move.l  d0,d7               ;save for reply later
CLI lea     dosname,a1
    jsr     _LVOOldOpenLibrary(a6)
    move.l  d0,a6
    lea     START,a0                    ;Get code Hunk
    subq.w  #4,a0                        ;Point to Segment
    move.l  a0,d3
    lsr.l   #2,d3                       ;into a BPTR
    lea     Title,a0
    move.l  a0,d1
    moveq   #19,d2                      ;Priority
    move.l  #4000,d4                    ;StackSize
    jsr     _LVOCreateProc(a6)
    move.l  a6,a1
    move.l  4,a6
    jsr     _LVOCloseLibrary(a6)
    lea     Loader(pc),a0
    clr.l   -4(a0)                      ;Zero segment
    tst.l   d7
    beq.s   1$
    move.l  d7,a1
    jsr     _LVOReplyMsg(a6)
1$  moveq   #0,d0
    rts                                 ;Unload this code

    section     Virus_Checker,CODE

START:
    moveq   #-1,d1              ;For Changecount
    moveq   #3,d0               ;4 LongWords to set
2$  move.l  d1,-(sp)
    dbra    d0,2$
    moveq   #27,d0
1$  clr.l   -(sp)               ;Clear the stack space
    dbra    d0,1$
    move.l  sp,a5               ;Get pointer to Data area
    bsr     Initiate            ;initiate ports/windows, etc
    bsr     CheckMemory         ;check memory for all viruses
    bsr     CheckMemIRQ         ;check memory for IRQ virus
    bsr     CheckFileIRQ        ;check first file for IRQ virus
    bsr     CheckFileTTV1       ;check for TTV1 virus
    bsr     CheckBlock          ;check disks in drives
MainLoop:
    move.l  Execbase(a5),a6
    lea     Fmtstring(pc),a0    ;format string for title
    move.l  VFound(a5),-(sp)    ;number of viruses found
    move.l  DInstall(a5),-(sp)  ;number of disks installed
    move.l  DCheck(a5),-(sp)    ;number of disks checked
    move.l  sp,a1
    lea     Format1(pc),a2      ;format routine
    move.l  Buff(a5),a3         ;buffer for string
    jsr     _LVORawDoFmt(a6)    ;format screen title
    lea     12(sp),sp           ;readjust stack
    move.l  Intuibase(a5),a6
    move.l  Mywindow(a5),a0
    moveq   #-1,d0
    move.l  d0,a1
    move.l  Buff(a5),a2
    jsr     _LVOSetWindowTitles(a6) ;set screen title only
LP  move.l  Execbase(a5),a6
    move.l  Userport(a5),a0
    jsr     _LVOGetMsg(a6)      ;get any messages recieved
    tst.l   d0
    bne.s   Act                 ;if a message then act on it
    bsr     CheckMemIRQ         ;otherwise see if memory infected by IRQ
    move.l  Dosbase(a5),a6
    moveq   #50,d1
    jsr     _LVODelay(a6)       ;delay for 1 second
    bra     LP
Act move.l  d0,a1               ;copy message pointer
    move.l  im_Class(a1),d3     ;get class of message
    jsr     _LVOReplyMsg(a6)    ;reply to message fast
    cmp.l   #CLOSEWINDOW,d3     ;close window message
    beq.s   EndIT               ;yes, then close down everything
    cmp.l   #DISKINSERTED,d3    ;did someone put a disk in
    bne     MainLoop            ;no, then keep looking
    bsr     CheckBlock          ;otherwise see which disk it was and check it
    bra     MainLoop            ;just keep on looking
EndIT:
2$  move.l  Userport(a5),a0
    jsr     _LVOGetMsg(a6)      ;anymore messages
    tst.l   d0
    beq.s   1$                  ;no more
    move.l  d0,a1
    jsr     _LVOReplyMsg(a6)    ;reply to message
    bra     2$
1$  move.l  Intuibase(a5),a6
    move.l  Mywindow(a5),a0
    jsr     _LVOCloseWindow(a6) ;close the window
    move.l  Execbase(a5),a6
    move.l  Port(a5),a1
    bsr     DeletePort          ;delete our port
    move.l  Mementry(a5),a0
    jsr     _LVOFreeEntry(a6)   ;free all the memory we allocated
    bsr     CloseLibraries      ;close down the libraries
    lea     128(sp),sp          ;Put SP back to the right place
    moveq   #0,d0               ;no error
    rts                         ;return to dos

Format1:
    move.b  d0,(a3)+            ;routine called by RawDoFmt
    rts

Initiate:
    move.l  4,a6
    move.l  a6,Execbase(a5)     ;save execbase
    sub.l   a1,a1
    jsr     _LVOFindTask(a6)
    move.l  d0,Task(a5)         ;save address of this task
    moveq   #33,d0
    lea     dosname(pc),a1
    jsr     _LVOOpenLibrary(a6) ;open dos.library
    move.l  d0,Dosbase(a5)      ;save
    moveq   #33,d0
    lea     Intuiname(pc),a1    ;open intuition.library
    jsr     _LVOOpenLibrary(a6)
    move.l  d0,Intuibase(a5)    ;and save it
    moveq   #33,d0
    lea     Gfxname(pc),a1
    jsr     _LVOOpenLibrary(a6) ;open graphics.library
    move.l  d0,Gfxbase(a5)      ;and save it
    lea     MemEnt(pc),a0
    jsr     _LVOAllocEntry(a6)  ;allocate all our memory at once
    btst    #31,d0
    beq.s   1$                  ;error if bit 31 set
    bsr     CloseLibraries      ;close libraries
    add.w   #4,sp               ;clean up rts from stack
    rts                         ;return to dos

1$  move.l  d0,Mementry(a5)     ;save memory pointer
    move.l  d0,a0
    add.w   #LN_SIZE,a0
    move.l  2(a0),Buffer(a5)    ;save pointer to buffer memory
    move.l  10(a0),Buff(a5)     ;save screen title buffer
    move.l  a0,-(sp)            ;save buffer pointer
    bsr     CreatePort          ;create a port for disk operations
    move.l  (sp)+,a0            ;restore pointer
    tst.l   d0                  ;zero if no port
    beq     Error
    move.l  d0,d3
    move.l  d0,Port(a5)         ;save port address
    add.w   #18,a0
    move.l  (a0),a0
    move.b  #NT_MESSAGE,LN_TYPE(a0)
    move.w  #IOSTD_SIZE,MN_LENGTH(a0)
    move.l  d3,MN_REPLYPORT(a0)
    move.l  a0,DiskIO(a5)       ;set up IO_REQUEST block and save pointer
    move.l  a0,a4               ;copy for later
    moveq   #3,d3               ;4 drives to check for
    moveq   #3*4,d4
Loop:
    lea     Trackname(pc),a0    ;trackdisk.device
    move.l  d3,d0               ;unit number
    move.l  a4,a1               ;pointer to IO block
    moveq   #0,d1               ;flags for open
    jsr     _LVOOpenDevice(a6)  ;try and open unit
    tst.l   d0
    bgt.s   1$                  ;no unit available
    move.w  #TD_CHANGENUM,IO_COMMAND(a1) ;otherwise find change count
    jsr     _LVODoIO(a6)        ;find change count
    lea     Changecount(a5),a0
    move.l  IO_ACTUAL(a1),0(a0,d4.l) ;put count into save area
    jsr     _LVOCloseDevice(a6) ;close this device
1$  subq    #4,d4
    dbra    d3,Loop             ;loop till all drives checked
    lea     Mynewwindow(pc),a0
    move.l  a6,-(sp)
    move.l  Intuibase(a5),a6
    jsr     _LVOOpenWindow(a6)  ;open window for our program
    move.l  (sp)+,a6
    tst.l   d0
    beq     Error
    move.l  d0,Mywindow(a5)     ;save address of window
    move.l  d0,a0
    move.l  wd_RPort(a0),RPort(a5) ;find RastPort
    move.l  wd_UserPort(a0),a0  ;and the userport
    move.l  a0,Userport(a5)
    moveq   #0,d0
    move.b  MP_SIGBIT(a0),d0    ;get signal number
    moveq   #1,d1
    lsl.l   d0,d1               ;convert into a signal mask
    move.l  d1,Signal(a5)       ;and save

    ifd     John                ;Enter code for My copy Only

    move.l  a6,-(sp)
    move.l  Intuibase(a5),a6
    move.l  Mywindow(a5),a0
    jsr     _LVOWindowToBack(a6)    ;Put the window to the Back
    move.l  (sp)+,a6

    endc

    moveq   #3,d3
    lea     Changecount(a5),a0
LP1 cmp.l   #-1,(a0)            ;if count is -1 then no unit available
    bne.s   1$
    add.w   #4,a0
    bra.s   2$
1$  move.l  #10000,(a0)+        ;otherwise set to an impossible count
2$  dbra    d3,LP1
    move.l  RPort(a5),a1        ;get rastport
    moveq   #1,d0
    move.l  Gfxbase(a5),a6
    jsr     _LVOSetAPen(a6)     ;set pen
    moveq   #0,d0
    jsr     _LVOSetBPen(a6)     ;set pen
    moveq   #RP_JAM2,d0
    jsr     _LVOSetDrMd(a6)     ;set draw mode
    move.l  Execbase(a5),a6
Ret rts                         ;return to main program

CheckMemIRQ:
    move.l  -$196(a6),a2        ;get OldOpenLibrary vector
    move.l  a2,a1
    add.w   #12,a1
    cmp.l   #$2f3a0010,(a2)     ;is the IRQ virus in there
    bne.s   Ret                 ;no
    move.l  (a1),(a2)           ;Yes, then fix it up
    bsr     FixRomTag           ;fix up RomTag
    lea     IRQV(pc),a0
    bra     DisplayV            ;display virus in mem message

CloseLibraries:
    move.l  Intuibase(a5),a1
    jsr     _LVOCloseLibrary(a6)    ;close Intuition.library
    move.l  Gfxbase(a5),a1
    jsr     _LVOCloseLibrary(a6)    ;close graphics.library
    move.l  Dosbase(a5),a1
    jsr     _LVOCloseLibrary(a6)    ;close dos.library
    rts

Error:
    bsr     CloseLibraries          ;close all libraries
    add.w   #4,sp                   ;adjust stack
    rts                             ;return to dos


CreatePort:
      move.l   a2,-(sp)
      move.l   Mementry(a5),a2
      add.w    #LN_SIZE+26,a2
      move.l   (a2),a2          ;get memory allocated for port
      moveq    #-1,d0
      jsr      _LVOAllocSignal(a6) ;get a signal number
      moveq    #-1,d1
      cmp.l    d0,d1            ;-1 indicates bad signal
      bne.s    cp_sigok
      move.l   (a7)+,a2
      moveq    #0,d0            ;otherwise indicate no port
      rts
cp_sigok:
      move.b   d0,MP_SIGBIT(a2) ;save signal bit
      move.b   #PA_SIGNAL,MP_FLAGS(a2)
      move.b   #NT_MSGPORT,LN_TYPE(a2)
      clr.b    LN_PRI(a2)
      move.l   Task(a5),d0
      move.l   d0,MP_SIGTASK(a2)
      lea.l    MP_MSGLIST(a2),a0  ;Point to list header
      NEWLIST  a0               ;Init new list macro
      move.l   a2,d0            ;port into d0
      move.l   (a7)+,a2         ;cc's NOT affected
      rts

DeletePort:
      moveq    #-1,d0
      move.b   d0,LN_TYPE(a1)
      move.l   d0,MP_MSGLIST+LH_HEAD(a1)
      moveq    #0,d0
      move.b   MP_SIGBIT(a1),d0
      jsr      _LVOFreeSignal(a6)
      rts

CheckMemory:
    lea     $142(a6),a0         ;get pointer to MemList structure
    move.l  (a0),a0             ;get first available memory
    move.l  $18(a0),a1          ;get upper part of memory
    cmp.l   #$444f5300,(a1)     ;is the Byte bandit virus here
    bne.s   NextMem             ;no
    cmp.l   #'Viru',$10(a1)     ;another check for it
    bne.s   NextMem
    jsr     _LVODisable(a6)     ;turn off interupts
    move.l  $3da(a1),$94(a6)    ;restore vertical blank routine
    move.l  #$6000010a,$1b8(a1) ;patch virus for now
    lea     $3e2(a1),a0         ;start of virus RomTag
    moveq   #12,d1
    moveq   #0,d0
1$  move.l  d0,(a0)+            ;clear the RomTag out
    dbra    d1,1$
    moveq   #18,d1
2$  move.l  d0,(a1)+            ;wipe out start of virus
    dbra    d1,2$
    bsr     FixRomTag           ;Fix RomTag pointer
    jsr     _LVOEnable(a6)      ;turn on interupts
    lea     BYTV(pc),a0
    bsr     DisplayV            ;display byte bandit message
NextMem:
    lea     $7ec00,a0
    cmp.l   #$41fafff2,12(a0)   ;is an SCA type virus in memory
    bne.s   Nextmem2
    clr.l   12(a0)              ;clear it so we dont find it again
    bsr     FixCoolCapture      ;fix CoolCapture vector (easy)
    lea     SCAV(pc),a0
    bsr     DisplayV            ;display SCA message
Nextmem2:
    lea     $7f800,a0
    cmp.l   #$7f954,$14c(a0)    ;is the byte warrior virus here
    bne.s   Nextmem3
    move.l  #$fc06dc,-$1c6(a6)  ;manually patch DoIO vector (not V1.3 compat)
    move.w  #$ff,d1
    moveq   #0,d0
1$  move.l  d0,(a0)+            ;wipe out virus
    dbra    d1,1$
    bsr     FixRomTag           ;fix RomTag pointer
    lea     WARV(pc),a0
    bsr     DisplayV            ;display message
Nextmem3:
    move.l  $2e(a6),d7
    cmp.l   #$7e060,d7          ;is the revenge virus in memory
    bne.s   Nextmem4
    bsr     FixCoolCapture      ;fix coolcapture vectors
    jsr     _LVODisable(a6)     ;turn off interupts
    lea     $7e000,a0
    clr.l   (a0)                ;get rid of DOS0
    add.w   #$1e0,a0
    move.l  #$4ef90007,(a0)+    ;patch DoIO routine in virus
    move.w  #$e066,(a0)
    lea     $7e2da,a0
    move.l  #$4ef90007,(a0)+    ;patch vertical interupt wedge
    move.w  #$e06c,(a0)
    jsr     _LVOEnable(a6)      ;enable interupts
    lea     REVV(pc),a0
    bsr     DisplayV            ;display message
Nextmem4:
    cmp.l   #$7e86c,d7          ;is the Obelisk virus in memory
    bne.s   Nextmem5
    bsr     FixCoolCapture      ;fix the Vectors
    jsr     _LVOForbid(a6)      ;turn off multitasking
    move.b  #10,$7fb4c          ;patch virus
    jsr     _LVOPermit(a6)      ;multitasking on
    lea     OBLV(pc),a0
    bsr     DisplayV            ;display message
Nextmem5:
    cmp.l   #$7ec0e,d7          ;check for NorthStar virus
    bne.s   Nextmem6
    bsr     FixCoolCapture      ;fix vectors (very easy one)
    lea     NRTHV(pc),a0
    bsr     DisplayV            ;display message
Nextmem6:
    cmp.l   #$7fb4c,d7          ;check for pentagon circle virus
    bne.s   Nextmem7
    bsr     FixCoolCapture      ;fix vectors
    lea     PENTV(pc),a0
    bsr     DisplayV            ;display message
Nextmem7:
    move.l  $2a(a6),a0
    cmp.w   #$424d,$14(a0)      ;check for CrackRight virus
    bne.s   Nextmem8
    bsr     FixCoolCapture      ;fix vectors
    jsr     _LVODisable(a6)     ;interupts off
    move.l  #$fc12fc,$94(a6)    ;put back Vert Blank Int (not V1.3 compat)
    move.l  #$fc06dc,-$1c6(a6)  ;put back DoIO Vector    (not V1.3 compat)
    jsr     _LVOEnable(a6)      ;interupts on
    lea     Clipname(pc),a1
    jsr     _LVOFindTask(a6)    ;find clipboard.device task
    tst.l   d0
    beq.s   1$                  ;not here
    move.l  d0,a1
    jsr     _LVORemTask(a6)     ;otherwise remove it
1$  lea     CRACKV(pc),a0
    bsr     DisplayV            ;display message
Nextmem8:
    move.l  $226(a6),a1
    cmp.l   #$2d7c0007,$92(a1)  ;is the systemz virus in memory
    bne.s   Nextmem9
    bsr     FixRomTag           ;fix romtag pointer
    move.l  $7f800,-$1c6(a6)    ;restore DoIO vector
    lea     HCSV(pc),a0
    bsr     DisplayV            ;display message
Nextmem9:
    move.l  $226(a6),a4
    cmp.l   #$343c0352,-$376(a4);is Lamer virus in memory
    bne.s   Nextmem10
    move.l  4(a4),d0            ;get RomTag continuation pointer
    bclr    #31,d0              ;clear continuation bit
    move.l  d0,$226(a6)         ;restore pointer
    jsr     _LVODisable(a6)     ;interupts off
    move.l  -$10(a4),-$262(a6)  ;restore SumKick vector
    move.l  -8(a4),a1
    move.l  #$400,d0
    jsr     _LVOFreeMem(a6)     ;free allocated memory
    lea     $15e(a6),a0
    lea     Trackname(pc),a1
    jsr     _LVOFindName(a6)    ;find trackdisk.device
    move.l  d0,a0
    move.l  -$c(a4),-$1c(a0)    ;restore IO routine
    bsr     FixCoolCapture      ;fix vectors
    jsr     _LVOEnable(a6)      ;interupts on
    clr.l   $22a(a6)            ;clear old checksum
    jsr     _LVOSumKickData(a6)
    move.l  d0,$22a(a6)         ;redo checksum on RomTags
    lea     LAMERV(pc),a0
    bsr     DisplayV            ;display message
Nextmem10:
    move.l  $226(a6),a4
    cmp.l   #$b118b5c8,-$376(a4);is Lamer #2 virus in memory
    bne.s   Nextmem11
    move.l  4(a4),d0            ;get RomTag continuation ptr
    bclr    #31,d0              ;clear continuation bit
    move.l  d0,$226(a6)         ;and save new address
    jsr     _LVODisable(a6)     ;turn interupts off
    move.l  -$e(a4),-$262(a6)   ;restore SumKickData vector
    move.l  -6(a4),a1           ;get memory pointer
    move.l  #$400,d0            ;ammount to free
    jsr     _LVOFreeMem(a6)     ;free memory
    lea     $15e(a6),a0
    lea     Trackname(pc),a1
    jsr     _LVOFindName(a6)    ;find trackdisk.device
    move.l  d0,a0
    move.l  -$a(a4),-$1c(a0)    ;restore IO routine
    bsr     FixCoolCapture      ;fix vectors
    jsr     _LVOEnable(a6)      ;interupts on
    clr.l   $22a(a6)            ;clear old checksum
    jsr     _LVOSumKickData(a6)
    move.l  d0,$22a(a6)         ;redo checksum on RomTags
    lea     LAMERV(pc),a0
    bsr     DisplayV            ;display message
Nextmem11:
    move.l  CoolCapture(a6),a0
    cmp.l   #'GADA',-$9c(a0)    ;is it the GADAFFI Virus
    bne.s   Nextmem12
    bsr     FixCoolCapture      ;fix CoolCapture Vectors
    clr.l   KickTagPtr(a6)      ;Clear RomTags
    jsr     _LVOSumKickData(a6)
    move.l  d0,$22a(a6)         ;redo checksum
    move.l  #$fc06dc,_LVODoIO+2(a6) ;restore V1.2 DoIO routine
    lea     GADAFFIV(pc),a0
    bsr     DisplayV
Nextmem12
    move.l  CoolCapture(a6),d0
    cmp.l   #$7ec58,d0          ;is Graffiti Virus in Memory
    bne.s   Nextmem13
    bsr     FixCoolCapture      ;Fiz Vectors
    lea     GRAFFITIV(pc),a0
    bsr     DisplayV
Nextmem13
    move.l  CoolCapture(a6),d0
    cmp.l   #$7ec74,d0          ;is Phantasmumble Virus Here
    bne.s   Nextmem14
    bsr     FixCoolCapture
    lea     PHANTAV(pc),a0
    bsr     DisplayV
Nextmem14
    move.l  CoolCapture(a6),d0
    cmp.l   #$7ed36,d0          ;is UltraFox in Memory
    bne.s   Nextmem15
    bsr     FixCoolCapture
    move.l  -$1c6(a6),a0
    moveq   #7,d0
    cmp.w   (a0),d0
    bne.s   1$
    lea     $7eb38,a1
    move.l  (a1),(a0)           ;Restore DoIO vector
1$  lea     ULTRAFOXV(pc),a0
    bsr     DisplayV
Nextmem15
    move.l  $226(a6),d1
    bmi     resetbit
    beq     Nextmem16
    move.l  d1,a0
Nexttag
    move.l  (a0)+,d1            ;get tag pointer
    bmi     resetbit
    beq     Nextmem16
    move.l  d1,a1
    move.l  RT_NAME(a1),d0
    beq     Nexttag
    move.l  a0,-(sp)
    move.l  d0,a0
    move.l  (a0),d0
    move.l  (sp)+,a0
    cmp.l   #'TTV1',d0
    bne     Nexttag
    move.l  RT_INIT(a1),a0
    cmp.w   #$4e75,(a0)         ;see if we done it already
    beq.s   Nextmem16
    move.w  #$4e75,(a0)         ;change to RTS
    lea     TTVV(pc),a0
    bsr     DisplayV
    move.l  a6,-(sp)            ;save execbase
    bsr.s   CheckOtherDisks     ;check disks in df0: for TTV1 virus
    move.l  (sp)+,a6            ;get execbase
    bra.s   Nextmem16

resetbit
    bclr    #$1f,d1
    move.l  d1,a0
    bra     Nexttag

Nextmem16
Checkrts
    rts                         ;no more checks YET!

CheckOtherDisks
    clr.l   SSize(a5)
    clr.l   SFile(a5)
    clr.l   SBuffer(a5)
    lea     TTV1.MSG(pc),a0
    lea     Checkdisk.MSG(pc),a1
    move.l  a1,d0
    lea     Yes(pc),a2
    lea     No(pc),a3
    moveq   #0,d2
    bsr     DisplayReq          ;ask user if they want disks checked
    tst.l   d0
    beq     Checkrts            ;no return to caller
    lea     DF0.MSG(pc),a0
    bsr     GetFirstStartupFile ;get name into Buffer
    tst.l   d4
    bmi     ErrorCheck          ;error on read file
    bne     1$                  ;device given
    move.l  Buffer(a5),a0       ;get file name buffer
    move.b  #'/',1(a0)          ;insert
    move.l  I(a5),d1            ;get index
2$  move.b  0(a0,d1.l),4(a0,d1.l); copy name up 4 places in buffer
    dbra    d1,2$
    move.l  #'df0:',(a0)        ;put drive into buffer
1$  exg     a4,a6
    move.l  Execbase(a5),a6
    move.l  #$a0a,d0
    moveq   #MEMF_PUBLIC,d1
    jsr     _LVOAllocMem(a6)
    exg     a4,a6
    tst.l   d0
    beq     ErrorCheck
    move.l  d0,SBuffer(a5)          ;save tempory
    move.l  Buffer(a5),d1
    move.l  #MODE_OLDFILE,d2
    jsr     _LVOOpen(a6)            ;open file
    tst     d0
    beq     ErrorCheck
    move.l  d0,SFile(a5)
    move.l  d0,d1
    move.l  SBuffer(a5),d2
    move.l  #$a0a,d3
    jsr     _LVORead(a6)            ;read file
    bmi     ErrorCheck                ;error on read
    cmp.l   #$a0a,d0                ;did we get enough
    bne     Closediskcheck          ;no, can't be the TTV virus
    move.l  SBuffer(a5),a0
    cmp.l   #'TTV1',$A04(a0)        ;get for virus
    bne     Closediskcheck          ;no virus here, ByeBye
    move.l  SFile(a5),d1
    jsr     _LVOClose(a6)           ;close file
    clr.l   SFile(a5)
    lea     TTVName1(pc),a0
    move.l  a0,d1
    move.l  #MODE_OLDFILE,d2
    jsr     _LVOOpen(a6)            ;open file
    tst.l   d0
    beq     ErrorCheck
    move.l  d0,SSize(a5)
    move.l  Buffer(a5),d1
    move.l  #MODE_NEWFILE,d2
    jsr     _LVOOpen(a6)            ;open as new file
    tst.l   d0
    beq     ErrorCheck
    move.l  d0,SFile(a5)            ;save handle
TLoop1
    move.l  SSize(a5),d1
    move.l  SBuffer(a5),d2
    move.l  #$a00,d3
    jsr     _LVORead(a6)
    tst.l   d0
    bmi     ErrorCheck
    beq     Endcheck
    move.l  d0,-(sp)
    move.l  d0,d3
    move.l  SFile(a5),d1
    move.l  SBuffer(a5),d2
    jsr     _LVOWrite(a6)
    move.l  (sp)+,d1
    tst.l   d0
    bmi     ErrorCheck
    cmp.l   d0,d1
    bne     ErrorCheck
    bra     TLoop1

Endcheck
    addq.l  #1,VFound(a5)
    move.l  SSize(a5),d1
    jsr     _LVOClose(a6)
    clr.l   SSize(a5)
    lea     TTVName1(pc),a0
    move.l  a0,d1
    jsr     _LVODeleteFile(a6)      ;delete file in devs
    lea     TTVV(pc),a0
    bsr     SetMsg
    move.l  a0,d0
    lea     IRQ2(pc),a0
    lea     IRQ4(pc),a1
    move.l  a1,d1
    bsr     Disp2
    bra.s   Closediskcheck

ErrorCheck
    lea     Error.MSG(pc),a0
    lea     Present.MSG(pc),a1
    move.l  a1,d0
    lea     Okay(pc),a2
    lea     Okay(pc),a3
    moveq   #0,d2
    bsr     DisplayReq          ;inform user of error

Closediskcheck
    move.l  SSize(a5),d1
    beq.s   3$
    jsr     _LVOClose(a6)
    clr.l   SSize(a5)
3$  move.l  SFile(a5),d1
    beq.s   2$
    jsr     _LVOClose(a6)
    clr.l   SFile(a5)
2$  move.l  SBuffer(a5),d0
    beq.s   1$
    move.l  d0,a1
    move.l  #$a0a,d0
    exg     a4,a6
    move.l  Execbase(a5),a6
    jsr     _LVOFreeMem(a6)
    clr.l   SBuffer(a5)
    exg     a4,a6
1$  bra     CheckOtherDisks     ;go and check next disk


SetMsg:
    move.l  a2,-(sp)
    lea     InfectedMsg(pc),a1  ;Get first part of message
    move.l  a1,a2               ;copy message
    add.w   #18,a2
    moveq   #19,d0
1$  move.b  (a0)+,(a2)+         ;copy message
    dbra    d0,1$
    move.l  a1,a0
    move.l  (sp)+,a2
    rts

DisplayV:
    addq.l  #1,VFound(a5)       ;add one to viruses found
    bsr     SetMsg
    move.l  a0,d0               ;save message
    lea     Memmess(pc),a0      ;get memory message
    lea     Disablemess(pc),a2  ;and disabled message
    move.l  a2,d1
Disp2:
    lea     Okay(pc),a2         ;gadget to display
    move.l  a2,a3
    moveq   #1,d2               ;3 lines to display

DisplayReq:             ;a0 = 1  d0 = 2 d1 = 3  a2 = yes a3 = no
    lea     Req(pc),a1          ;get pointer to structure
    move.l  a0,Point(a1)        ;save first line of message
    move.l  d0,Point1(a1)       ;     second line of message
    move.l  d1,Point2(a1)       ;     third line of message
    lea     Req1(pc),a4         ;get the requster
    move.l  a4,Point+4(a1)      ;save in structure
    tst.l   d2
    beq.s   1$
    lea     Req2(pc),a4
    move.l  a4,Point1+4(a1)
    bra.s   Disp3
1$  clr.l   Point1+4(a1)
Disp3:
    move.l  Mywindow(a5),a0     ;get window pointer
    moveq   #0,d0
    move.l  d0,d1
    move.l  #370,d2
    moveq   #75,d3
    move.l  a6,-(sp)
    move.l  Intuibase(a5),a6
    jsr     _LVOAutoRequest(a6) ;display requester and get input
    move.l  (sp)+,a6
    rts                         ;and return

CheckBlock:
    move.l  Execbase(a5),a6
    bsr     WhoChanged          ;find which disk was changed
    cmp.w   #-1,d3              ;no more disks changed
    bne.s   7$
    rts                         ;return to caller
7$  move.b  d3,Unit(a5)         ;save unit number
    lea     Trackname(pc),a0
    move.l  DiskIO(a5),a1
    move.l  a1,d7
    moveq   #0,d1
    move.l  d3,d0
    jsr     _LVOOpenDevice(a6)  ;open correct unit
    bgt     CheckBlock          ;error then check next one
    addq.l  #1,DCheck(a5)       ;add one to disks checked
    move.l  d7,a1               ;get IO block
    move.w  #CMD_READ,IO_COMMAND(a1)
    move.l  Buffer(a5),IO_DATA(a1)
    move.l  #1536,IO_LENGTH(a1)
    clr.l   IO_OFFSET(a1)
    jsr     _LVODoIO(a6)        ;read boot block into buffer
    move.l  d7,a1
    move.w  #TD_MOTOR,IO_COMMAND(a1)
    clr.l   IO_LENGTH(a1)
    jsr     _LVODoIO(a6)        ;turn off motor
    move.l  d7,a1
    move.b  IO_ERROR(a1),d3     ;get error code
    jsr     _LVOCloseDevice(a6) ;close unit
    cmp.b   #19,d3
    bgt     CheckBlock          ;if greater than 19 then disk error
    move.w  #$ff,d1
    moveq   #0,d2
    move.l  Buffer(a5),a0
    move.l  a0,d7
1$  add.l   (a0)+,d2
    bcc.s   2$
    addq.l  #1,d2
2$  dbra    d1,1$
    not.l   d2                  ;do checksum on bootblock
    bne     CheckBlock          ;not a bootable disk
    move.l  d7,a1
    cmp.l   #$41fafff2,12(a1)   ;is an SCA type virus here
    beq     DispSCA
    cmp.l   #'Band',32(a1)      ;byte bandit virus
    beq     DispBYT
    cmp.w   #'ID',14(a1)        ;revenge virus
    beq     DispREV
    cmp.l   #'DASA',$c0(a1)     ;byte warrior virus
    beq     DispWAR
    cmp.l   #$ffa02040,$40(a1)  ;pentagon circle virus
    beq     DispPENT
    cmp.l   #$fe3a4cdf,$170(a1) ;systemz virus
    beq     DispHCS
    cmp.b   #78,$12(a1)
    bne.s   4$
    cmp.b   #68,$13c(a1)
    bne.s   4$
    cmp.w   #$5374,$18(a1)      ;northstar virus
    beq     DispNRTH
4$  cmp.b   #71,$38(a1)
    bne.s   5$
    cmp.b   #83,$bc(a1)
    bne.s   5$
    cmp.b   #100,$1fb(a1)
    bne.s   5$
    cmp.b   #80,$2d(a1)         ;obelisk virus
    beq     DispOBL
5$  cmp.w   #$424d,$54(a1)      ;crackright virus
    beq     DispCRACK
    cmp.l   #$343c0352,$42(a1)
    beq     DispLAMER           ;lamer exterminator virus
    cmp.l   #$1012b118,$46(a1)
    beq     DispLAMER           ;Second Lamer Exterminator virus
    cmp.l   #$237c0003,$16(a1)  ;is it a BootGirl BootBlock
    beq     CheckBlock          ;yes Ignore it
    cmp.l   #$237c0007,$2a(a1)  ;check for TimeBomb virus
    beq     DispTIMV
    cmp.l   #'GADA',$40(a1)     ;check for Gadaffi virus
    beq     DispGADV
    cmp.l   #$100bf,$150(a1)    ;Check for Graffiti
    beq     DispGRAFV
    cmp.l   #$4240323c,$40(a1)  ;Check for Phantasmumble
    beq     DispPHANTV
    cmp.l   #$83353ef0,$1d0(a1) ;check for Ultra Fox
    beq     DispULTRAV


    ;   Start Here for Non-Standard Boot Block

    add.w   #$c,a1
    lea     Bootblock+$c(pc),a2
    moveq   #9,d3
6$  cmp.l   (a1)+,(a2)+         ;non-standard bootblock
    bne     DispNSTD
    dbra    d3,6$
    bra     CheckBlock          ;standard then keep looking
DispSCA:
    lea     SCAV(pc),a0
Dispall:
    cmp.b   #'-',3(a0)          ;see if NON-Standard message
    beq.s   3$
    bsr     SetMsg
3$  move.l  a0,d0
    lea     Textmess(pc),a0     ;first message
    move.b  Unit(a5),d7
    add.b   #'0',d7
    move.b  d7,24(a0)           ;put in unit number
    addq.l  #1,VFound(a5)       ;add one to viruses found
    moveq   #0,d2
    lea     Req(pc),a1
    move.l  a0,Point(a1)
    move.l  d0,Point1(a1)
    move.l  d1,Point2(a1)
    lea     Req1(pc),a4
    move.l  a4,Point+4(a1)
    tst.l   d2
    beq.s   1$
    lea     Req2(pc),a4
    move.l  a4,Point1+4(a1)
    bra.s   2$
1$  clr.l   Point1+4(a1)
2$  bsr     GetInput            ;see what user wants to do with it
    bra     CheckBlock          ;keep looking
DispPENT:
    lea     PENTV(pc),a0
    bra     Dispall
DispGADV
    lea     GADAFFIV(pc),a0
    bra     Dispall
DispHCS:
    lea     HCSV(pc),a0
    bra     Dispall
DispWAR:
    lea     WARV(pc),a0
    bra     Dispall
DispBYT:
    lea     BYTV(pc),a0
    bra     Dispall
DispOBL:
    lea     OBLV(pc),a0
    bra     Dispall
DispNRTH:
    lea     NRTHV(pc),a0
    bra     Dispall
DispREV:
    lea     REVV(pc),a0
    bra     Dispall
DispCRACK:
    lea     CRACKV(pc),a0
    bra     Dispall
DispLAMER:
    lea     LAMERV(pc),a0
    bra     Dispall
DispTIMV
    lea     TIMEBOMBV(pc),a0
    bra     Dispall
DispGRAFV
    lea     GRAFFITIV(pc),a0
    bra     Dispall
DispPHANTV
    lea     PHANTAV(pc),a0
    bra     Dispall
DispULTRAV
    lea     ULTRAFOXV(pc),a0
    bra     Dispall

DispNSTD:
    lea     NSTD(pc),a0
    sub.l   #1,VFound(a5)       ;needed to correct count
    bra     Dispall

WhoChanged:
    moveq   #3,d3                ;three drives to check
    movem.l d6-d7/a4,-(sp)
    lea     Changecount(a5),a4  ;get address of change count
    move.l  DiskIO(a5),d7       ;disk IO block
1$  move.l  d3,d6
    lsl.l   #2,d6               ;drive times 4 for index into table
    cmp.l   #-1,0(a4,d6.l)      ;is there any drive there
    beq.s   2$                  ;no
    lea     Trackname(pc),a0    ;trackdisk.device
    move.l  d3,d0               ;unit number
    move.l  d7,a1               ;IO block
    moveq   #0,d1               ;flags
    jsr     _LVOOpenDevice(a6)  ;open the drive
    tst.l   d0
    bgt.s   2$                  ;error on drive
    move.l  d7,a1               ;IO block
    move.w  #TD_CHANGESTATE,IO_COMMAND(a1) ;change state of drive
    jsr     _LVODoIO(a6)
    move.l  d7,a1
    tst.l   IO_ACTUAL(a1)       ;did this one have a disk changed
    bne.s   3$                  ;no
    move.w  #TD_CHANGENUM,IO_COMMAND(a1);get change number now
    jsr     _LVODoIO(a6)
    move.l  d7,a1
    move.l  IO_ACTUAL(a1),d0    ;get the change number
    cmp.l   0(a4,d6.l),d0       ;is it the same as the last time
    beq.s   3$                  ;yes
    move.l  d0,0(a4,d6.l)       ;no, then save it as current number
    jsr     _LVOCloseDevice(a6) ;close the device
    movem.l (sp)+,d6-d7/a4
    rts                         ;and return the drive number in d3
3$  jsr     _LVOCloseDevice(a6)
2$  dbra    d3,1$               ;otherwise keep looking
    movem.l (sp)+,d6-d7/a4
    rts

GetInput:
    movem.l a1/a6,-(sp)
    lea     Mnewwindow(pc),a0   ;load window discription for the requester
    move.l  Intuibase(a5),a6
    jsr     _LVOOpenWindow(a6)  ;open the window up
    movem.l (sp)+,a1/a6
    tst.l   d0
    beq     5$                  ;no window
    move.l  d0,I(a5)            ;save tempory
    move.l  d0,a0
    move.l  wd_UserPort(a0),a0  ;get userport
    move.l  a0,FHunk(a5)        ;tempory save
    moveq   #0,d0
    move.b  MP_SIGBIT(a0),d0
    moveq   #1,d1
    lsl.l   d0,d1
    move.l  d1,LHunk(a5)
    lea     Myrequester(pc),a0  ;get requester discription
    move.l  a1,rq_ReqText(a0)   ;save in window structure
    clr.l   (a0)
6$  move.l  a6,-(sp)
    move.l  I(a5),a1
    move.l  Intuibase(a5),a6
    jsr     _LVORequest(a6)     ;do the requester
    move.l  (sp)+,a6
1$  move.l  FHunk(a5),a0
    jsr     _LVOGetMsg(a6)      ;get a message
    tst.l   d0
    bne.s   2$
    move.l  LHunk(a5),d0
    jsr     _LVOWait(a6)        ;otherwise wait till one comes
    bra     1$
2$  move.l  d0,a1
    cmp.l   #GADGETUP,im_Class(a1);is it a gadget up message
    beq.s   7$
    jsr     _LVOReplyMsg(a6)    ;no then reply message and keep looking
    bra     6$
7$  move.l  im_IAddress(a1),a0  ;get gadget address
    move.w  gg_GadgetID(a0),d3  ;get gadget ID
    jsr     _LVOReplyMsg(a6)    ;reply to the message
    move.l  a6,-(sp)
    move.l  Intuibase(a5),a6
    move.l  I(a5),a0
    jsr     _LVOCloseWindow(a6) ;close the window on the requester
    move.l  (sp)+,a6
    cmp.w   #0,d3               ;is it install disk
    bne.s   3$
    bsr     DoInstall           ;yes then install disk
    rts
3$  cmp.w   #1,d3               ;is it display
    bne.s   4$
5$  bsr     DisplayIt           ;yes, then display the contents
4$  rts

DisplayIt:
    move.l  a6,-(sp)
    lea     Filename(pc),a0     ;CON: filename
    move.l  a0,d1
    move.l  Dosbase(a5),a6
    move.l  #MODE_NEWFILE,d2
    jsr     _LVOOpen(a6)        ;open a console device
    move.l  (sp)+,a6
    tst.l   d0
    beq     5$
    move.l  d0,-(sp)
    move.l  #1023,d2
    move.l  Buffer(a5),a2       ;get bootblock buffer
    move.l  a2,d6
4$  moveq   #0,d0
    move.b  (a2),d0             ;get a byte
    cmp.b   #' ',d0
    blt.s   1$
    cmp.b   #'~',d0
    ble.s   2$
1$  move.b  #'.',(a2)+          ;if not printable then change to a period
    bra.s   3$
2$  move.b  d0,(a2)+
3$  dbra    d2,4$
    move.l  a6,-(sp)
    move.l  Dosbase(a5),a6
    move.l  #1024,d3
    move.l  4(sp),d1
    move.l  d6,d2
    jsr     _LVOWrite(a6)       ;write it to the screen
    move.l  (sp)+,a6
5$  lea     Req(pc),a1
    lea     Remove(pc),a2
    lea     Ignore(pc),a3
    bsr     Disp3               ;redo the requester for input
    move.l  (sp)+,d1
    movem.l d0/a6,-(sp)
    move.l  Dosbase(a5),a6
    jsr     _LVOClose(a6)       ;close the file
    movem.l (sp)+,d0/a6
    tst.l   d0                  ;if user pressed install
    beq.s   6$
    bsr.s   DoInstall           ;then redo bootblock
6$  rts                         ;otherwise leave it alone

DoInstall:
    lea     Rwritemess(pc),a0
    lea     Bootmess(pc),a1
    move.l  a1,d0
    lea     Okay(pc),a2
    lea     No(pc),a3
    moveq   #0,d2
    bsr     DisplayReq          ;ask if user really wants to install
    tst.l   d0
    beq     7$
    move.l  Buffer(a5),a0       ;yes then clear bootblock buffer
    move.l  a0,d6
    move.l  #256,d3
    moveq   #0,d0
1$  move.l  d0,(a0)+
    dbra    d3,1$
    move.l  d6,a0
    lea     Bootblock(pc),a1    ;load our good copy of bootblock
    moveq   #12,d3
2$  move.l  (a1)+,(a0)+         ;and put it in the buffer
    dbra    d3,2$
    lea     Trackname(pc),a0
    move.l  DiskIO(a5),a1
    move.l  a1,d5
    move.b  Unit(a5),d0
    moveq   #0,d1
    jsr     _LVOOpenDevice(a6)
    tst.l   d0
    bgt     8$
4$  move.l  d5,a1
    move.w  #TD_PROTSTATUS,IO_COMMAND(a1)
    jsr     _LVODoIO(a6)        ;get the protection status of disk
    move.l  d5,a1
    tst.l   IO_ACTUAL(a1)
    beq.s   3$
    lea     Diskerr(pc),a0
    lea     Wrtpro(pc),a1
    move.l  a1,d0
    lea     Retry(pc),a2
    lea     Cancel(pc),a3
    moveq   #0,d2
    bsr     DisplayReq          ;if write protected then inorm user
    move.l  d5,a1
    tst.l   d0
    bne.s   4$
    jsr     _LVOCloseDevice(a6)
    rts
3$  move.l  #1024,IO_LENGTH(a1)
    move.l  d6,IO_DATA(a1)
    move.w  #CMD_WRITE,IO_COMMAND(a1)
    clr.l   IO_OFFSET(a1)
    jsr     _LVODoIO(a6)
    move.l  d5,a1
    move.w  #CMD_UPDATE,IO_COMMAND(a1)
    jsr     _LVODoIO(a6)        ;otherwise do the install routine
    move.l  d5,a1
    move.b  IO_ERROR(a1),d3
    move.w  #TD_MOTOR,IO_COMMAND(a1)
    clr.l   IO_LENGTH(a1)
    jsr     _LVODoIO(a6)        ;check error from write
    move.l  d5,a1
    jsr     _LVOCloseDevice(a6)
    cmp.b   #19,d3
    ble.s   5$
8$  lea     ErrorND(pc),a1      ;if error, display error message
    bra.s   6$
5$  lea     Healed(pc),a1       ;otherwise display healed message
6$  move.l  Mywindow(a5),a0
    moveq   #-1,d0
    move.l  d0,a3
    move.l  a6,-(sp)
    move.l  Intuibase(a5),a6
    jsr     _LVOSetWindowTitles(a6);set the window tho the message
    move.l  a6,-(sp)
    move.l  Dosbase(a5),a6
    moveq   #100,d1
    jsr     _LVODelay(a6)       ;wait 2 seconds
    move.l  (sp)+,a6
    move.l  Mywindow(a5),a0
    lea     Title(pc),a1
    moveq   #-1,d0
    move.l  d0,a3
    jsr     _LVOSetWindowTitles(a6);set title back to original
    move.l  (sp)+,a6
    addq.l  #1,DInstall(a5)     ;add one to number of disks installed
7$  rts

FixRomTag:
    moveq   #0,d0               ;clear out the RomTag pointers
    move.l  d0,$222(a6)
    move.l  d0,$226(a6)
    move.l  d0,$22a(a6)
    rts

FixCoolCapture:                 ;fix the exec vectors
    clr.l   $2e(a6)
    clr.l   $2a(a6)
    clr.l   $32(a6)
    lea     $22(a6),a0
    moveq   #0,d0
    moveq   #17,d1
1$  add.w   (a0)+,d0            ;redo exec checksum
    dbf     d1,1$
    not.w   d0
    move.w  d0,(a0)
    rts

;   enter with a0 pointing to startup file name
;   returns D4 = Device given
;   Buffer(a5) = name of file

GetFirstStartupFile
    clr.l   SFile(a5)
    move.l  a0,d1
    move.l  #MODE_OLDFILE,d2
    move.l  Dosbase(a5),a6
    jsr     _LVOOpen(a6)        ;open file for read
    tst.l   d0
    beq     Nofile              ;cant find file
    move.l  d0,SFile(a5)        ;save file handle
    move.l  Buffer(a5),a3       ;use this buffer tempory
    moveq   #0,d4               ;comment flag
1$  move.l  SFile(a5),d1        ;get file handle
    move.l  a3,d2               ;buffer address
    moveq   #1,d3               ;number of chars to read
    jsr     _LVORead(a6)        ;read a char
    tst.l   d0
    bmi     Nofile              ;error on read
    beq     NoStUp              ;no more chars
    move.b  (a3),d0             ;get char from buffer
    beq     NoStUp              ;end of file
    cmp.b   #10,d0              ;line feed
    bne     2$
    moveq   #0,d4               ;yes,then clear comment flag
    bra     1$
2$  tst.l   d4                  ;is comment flag set
    bne     1$                  ;yes, then keep looking til a LF
    cmp.b   #34,d0              ;is it a quote
    beq     1$                  ;yes, keep looking
    cmp.b   #';',d0             ;semi colon
    bne.s   3$
    moveq   #1,d4               ;yes, then set comment flag
    bra     1$
3$  cmp.b   #' ',d0             ;is it a space
    beq     1$                  ;yes, keep looking
    moveq   #0,d4               ;No errors, no device
    move.l  #1,I(a5)            ;set index into buffer at one
4$  move.l  SFile(a5),d1        ;get file handle
    move.l  a3,d2               ;pointer to buffer
    add.l   I(a5),d2            ;add index to find current buffer position
    moveq   #1,d3               ;number of chars to read
    jsr     _LVORead(a6)        ;read 1 char into buffer
    tst.l   d0                  ;eof
    bmi     Nofile              ;error on read
    beq     EndI
    move.l  I(a5),d1            ;get index
    move.b  0(a3,d1.l),d0       ;save char into buffer
    cmp.b   #':',d0             ;is it a colon
    bne.s   5$
    moveq   #1,d4               ;yes then set device specified flag
5$  cmp.b   #10,d0
    beq.s   EndI
    cmp.b   #';',d0
    beq.s   EndI
    cmp.b   #' ',d0             ;otherwise scan till a LF, semicolon, space
    beq.s   EndI
    addq.l  #1,I(a5)            ;add one to index
    bra     4$
EndI:
    clr.b   0(a3,d1.l)          ;clear the last byte of the filename
    move.l  SFile(a5),d1
    clr.l   SFile(a5)
    jsr     _LVOClose(a6)       ;close the startup-sequence file
    tst.l   d4                  ;see if device has been specified
    bne.s   1$                  ;no
    move.l  I(a5),d1            ;yes, get index
2$  move.b  0(a3,d1.l),2(a3,d1.l); copy name up two places in buffer
    dbra    d1,2$
    addq.l  #2,I(a5)            ;add 2 to index
    move.w  #'C:',(a3)          ;add the 'C:' prefix to filename
1$  rts
Nofile
    tst.l   SFile(a5)           ;file open
    beq.s   1$
    move.l  SFile(a5),d1
    jsr     _LVOClose(a6)
    clr.l   SFile(a5)
1$  moveq   #-1,d4
    rts

CheckFileTTV1
    clr.l   SBuffer(a5)         ;clear what we need
    clr.l   SFile(a5)
    clr.l   SSize(a5)
    lea     SName(pc),a0        ;s:startup-sequence
    bsr     GetFirstStartupFile ;get name of first file
    tst.l   d4
    bmi     CloseTTV
    exg     a4,a6
    move.l  Execbase(a5),a6
    move.l  #$a0a,d0
    moveq   #MEMF_PUBLIC,d1
    jsr     _LVOAllocMem(a6)
    exg     a4,a6
    tst.l   d0
    beq     ErrorTTV
    move.l  d0,SBuffer(a5)          ;save tempory
    move.l  Buffer(a5),d1
    move.l  #MODE_OLDFILE,d2
    jsr     _LVOOpen(a6)            ;open file
    tst     d0
    beq     ErrorTTV
    move.l  d0,SFile(a5)
    move.l  d0,d1
    move.l  SBuffer(a5),d2
    move.l  #$a0a,d3
    jsr     _LVORead(a6)            ;read file
    bmi     ErrorTTV                ;error on read
    cmp.l   #$a0a,d0                ;did we get enough
    bne     CloseTTV                ;no, can't be the TTV virus
    move.l  SBuffer(a5),a0
    cmp.l   #'TTV1',$A04(a0)        ;get for virus
    bne     CloseTTV                ;no virus here, ByeBye
    move.l  SFile(a5),d1
    jsr     _LVOClose(a6)           ;close file
    clr.l   SFile(a5)
    move.l  Buffer(a5),d1
    move.l  #MODE_NEWFILE,d2
    jsr     _LVOOpen(a6)            ;open as new file
    tst.l   d0
    beq     ErrorTTV
    move.l  d0,SFile(a5)            ;save handle
    lea     TTVName(pc),a0
    move.l  a0,d1
    move.l  #MODE_OLDFILE,d2
    jsr     _LVOOpen(a6)            ;open as new file
    tst.l   d0
    beq     ErrorTTV
    move.l  d0,SSize(a5)
TLoop
    move.l  SSize(a5),d1
    move.l  SBuffer(a5),d2
    move.l  #$a00,d3
    jsr     _LVORead(a6)
    tst.l   d0
    bmi     ErrorTTV
    beq     EndTTV
    move.l  d0,-(sp)
    move.l  d0,d3
    move.l  SFile(a5),d1
    move.l  SBuffer(a5),d2
    jsr     _LVOWrite(a6)
    move.l  (sp)+,d1
    tst.l   d0
    bmi     ErrorTTV
    cmp.l   d0,d1
    bne     ErrorTTV
    bra     TLoop

EndTTV
    addq.l  #1,VFound(a5)
    bsr     CloseTTV
    lea     TTVName(pc),a0
    move.l  a0,d1
    jsr     _LVODeleteFile(a6)      ;delete file in devs
    lea     TTVV(pc),a0
    bsr     SetMsg
    move.l  a0,d0
    lea     IRQ2(pc),a0
    lea     IRQ4(pc),a1
    move.l  a1,d1
    bra     Disp2


ErrorTTV
    bsr     CloseTTV
    lea     IRQ1(pc),a0
    lea     IRQ2(pc),a1
    move.l  a1,d0
    lea     IRQ3(pc),a1
    move.l  a1,d1
    bra     Disp2


CloseTTV
    move.l  SSize(a5),d1
    beq.s   3$
    jsr     _LVOClose(a6)
    clr.l   SSize(a5)
3$  move.l  SFile(a5),d1
    beq.s   2$
    jsr     _LVOClose(a6)
    clr.l   SFile(a5)
2$  move.l  SBuffer(a5),d0
    beq.s   1$
    move.l  d0,a1
    move.l  #$a0a,d0
    exg     a4,a6
    move.l  Execbase(a5),a6
    jsr     _LVOFreeMem(a6)
    clr.l   SBuffer(a5)
    exg     a4,a6
1$  rts

CheckFileIRQ:
    lea     SName(pc),a0        ;s:startup-sequence
    bsr     GetFirstStartupFile
    tst.l   d4
    bmi     NoIRQ               ;error on read
    exg     a4,a6

    ;allocate memory for read of file

    move.l  Execbase(a5),a6
    move.l  #500,d0
    moveq   #MEMF_PUBLIC,d1
    jsr     _LVOAllocMem(a6)
    exg     a4,a6
    tst.l   d0
    beq     ErrorIRQ
    move.l  d0,SBuffer(a5)
    move.l  Buffer(a5),d1
    move.l  #MODE_OLDFILE,d2
    jsr     _LVOOpen(a6)
    tst.l   d0
    beq     ErrorIRQ
    move.l  d0,SFile(a5)
    move.l  SBuffer(a5),d2
    move.l  d0,d1
    move.l  #487,d3
    jsr     _LVORead(a6)
    move.l  SBuffer(a5),a0
    cmp.l   #$3f3,(a0)
    bne     NoIRQ
    cmp.l   #$109,5*4(a0)
    bne     NoIRQ
    move.l  SFile(a5),d1
    moveq   #0,d2
    moveq   #OFFSET_END,d3          ;find end of file
    jsr     _LVOSeek(a6)
    move.l  SFile(a5),d1
    moveq   #0,d2
    moveq   #OFFSET_BEGINNING,d3    ;rewind to get length of file
    jsr     _LVOSeek(a6)
    tst.l   d0
    ble     NoIRQ
    move.l  d0,SSize(a5)
    exg     a4,a6
    moveq   #MEMF_PUBLIC,d1
    jsr     _LVOAllocMem(a6)
    exg     a4,a6
    tst.l   d0
    beq     ErrorIRQ
    move.l  d0,SMem(a5)
    move.l  d0,d2
    move.l  SFile(a5),d1
    move.l  SSize(a5),d3
    jsr     _LVORead(a6)
    cmp.l   SSize(a5),d0
    bne     ErrorIRQ
    move.l  SMem(a5),a0
    move.l  $8(a0),NHunk(a5)
    move.l  $c(a0),FHunk(a5)
    move.l  $10(a0),LHunk(a5)
    clr.l   I(a5)
3$  move.l  I(a5),d0
    asl.l   #2,d0
    addq.l  #1,I(a5)
    cmp.l   #$3e9,0(a0,d0.l)
    bne     3$
    move.l  I(a5),d0
    asl.l   #2,d0
    move.l  4(a0,d0.l),d1
    and.l   #$ffff,d1
    cmp.l   #$fffe,d1
    bne     NoIRQ
    move.l  8(a0,d0.l),d1
    and.w   #0,d1
    cmp.l   #$61000000,d1
    bne     NoIRQ
    move.l  SFile(a5),d1
    jsr     _LVOClose(a6)
    clr.l   SFile(a5)
    move.l  Buffer(a5),d1
    move.l  #MODE_NEWFILE,d2
    jsr     _LVOOpen(a6)
    tst.l   d0
    beq     ErrorIRQ
    move.l  d0,SFile(a5)
    move.l  SMem(a5),a0
    subq.l  #1,8(a0)
    subq.l  #1,$10(a0)
    move.l  d0,d1
    move.l  a0,d2
    moveq   #20,d3
    jsr     _LVOWrite(a6)
    cmp.l   #20,d0
    bne     ErrorIRQ
    move.l  SMem(a5),d2
    add.l   #24,d2
    move.l  SFile(a5),d1
    move.l  NHunk(a5),d3
    asl.l   #2,d3
    move.l  d3,d7
    jsr     _LVOWrite(a6)
    cmp.l   d0,d7
    bne     ErrorIRQ
    add.l   #$111,I(a5)
    move.l  SSize(a5),d0
    asr.l   #2,d0
    move.l  I(a5),d1
    sub.l   d1,d0
    asl.l   #2,d0
    move.l  d0,d7
    asl.l   #2,d1
    move.l  SMem(a5),a0
    add.l   d1,a0
    move.l  a0,d2
    move.l  SFile(a5),d1
    move.l  d0,d3
    jsr     _LVOWrite(a6)
    cmp.l   d7,d0
    bne     ErrorIRQ
    lea     IRQ2(pc),a0
    lea     IRQV(pc),a1
    move.l  a1,d0
    lea     IRQ4(pc),a1
    bra.s   ErI

NoIRQ:
NoStUp:
    move.l  Dosbase(a5),a6
    move.l  SFile(a5),d1
    beq.s   1$
    clr.l   SFile(a5)
    jsr     _LVOClose(a6)
1$  move.l  Execbase(a5),a6
    move.l  SBuffer(a5),d0
    beq.s   2$
    move.l  d0,a1
    move.l  #500,d0
    jsr     _LVOFreeMem(a6)
2$  move.l  SMem(a5),d0
    beq.s   3$
    move.l  d0,a1
    move.l  SSize(a5),d0
    jsr     _LVOFreeMem(a6)
3$  rts

ErrorIRQ:
    lea     IRQ1(pc),a0
    lea     IRQ2(pc),a1
    move.l  a1,d0
    lea     IRQ3(pc),a1
ErI move.l  a1,d1
    bsr     Disp2
    bra     NoIRQ


MemEnt      ds.b    LN_SIZE
            dc.w    4
            dc.l    MEMF_CHIP|MEMF_CLEAR
            dc.l    1536
            dc.l    MEMF_PUBLIC|MEMF_CLEAR
            dc.l    100
            dc.l    MEMF_PUBLIC|MEMF_CLEAR
            dc.l    IOSTD_SIZE
            dc.l    MEMF_PUBLIC|MEMF_CLEAR
            dc.l    MP_SIZE
Mynewwindow
            dc.w    128,0,300,10
            dc.b    0,1
            dc.l    DISKINSERTED|CLOSEWINDOW|MOUSEBUTTONS
            dc.l    WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH
            dc.l    0,0,Title,0,0
            dc.w    0,0,0,0,WBENCHSCREEN
Mnewwindow
            dc.w    0,0,380,133
            dc.b    0,1
            dc.l    MOUSEBUTTONS|GADGETUP
            dc.l    WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH
            dc.l    0,0,TITLETEXT1,0,0
            dc.w    0,0,0,0,WBENCHSCREEN


Req         dc.b    0,1,RP_JAM2,0
            dc.w    20,8
            dc.l    TxtAt_Plain
NB          dc.l    0
            dc.l    0
Req1        dc.b    0,1,RP_JAM2,0
            dc.w    20,18
            dc.l    TxtAt_Plain
NB1         dc.l    0
            dc.l    0
Req2        dc.b    0,1,RP_JAM2,0
            dc.w    20,28
            dc.l    TxtAt_Plain
NB2         dc.l    0
            dc.l    0

Point       equ     NB-Req
Point1      equ     NB1-Req
Point2      equ     NB2-Req

TxtAt_Plain dc.l    def_font
            dc.w    8
            dc.b    FS_NORMAL,FPF_ROMFONT
Okay        dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    OkayMess
            dc.l    0
No          dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    NoMess
            dc.l    0
Yes         dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    Yes.MSG
            dc.l    0

Display     dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    DispMess
            dc.l    0
Ignore      dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    IgnoreMess
            dc.l    0
Remove      dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    RemoveMess
            dc.l    0
Retry       dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    RetryMess
            dc.l    0
Cancel      dc.b    0,1,RP_JAM2,0
            dc.w    7,3
            dc.l    TxtAt_Plain
            dc.l    CancelMess
            dc.l    0

Myrequester
         dc.l  0
         dc.w  4,12
         dc.w  380,120
         dc.w  0,0
         dc.l  Gad1
         dc.l  0          ›
         dc.l  0                 ;filled in later
         dc.w  0
         dc.b  1
         dc.b  0
         dc.l  0
         ds.b  32
         dc.l  0
         dc.l  0
         ds.b  36

Gad1     dc.l  Gad2
         dc.w  40,45,95,12
         dc.w  GADGHCOMP,RELVERIFY!ENDGADGET,BOOLGADGET!REQGADGET
         dc.l  MyBorder
         dc.l  0,Remove
         dc.l  0,0
         dc.w  0
         dc.l  0
Gad2     dc.l  Gad3
         dc.w  92,70,95,12
         dc.w  GADGHCOMP,RELVERIFY!ENDGADGET,BOOLGADGET!REQGADGET
         dc.l  MyBorder
         dc.l  0,Display
         dc.l  0,0
         dc.w  1
         dc.l  0
Gad3     dc.l  0
         dc.w  145,45,95,12
         dc.w  GADGHCOMP,RELVERIFY!ENDGADGET,BOOLGADGET!REQGADGET
         dc.l  MyBorder
         dc.l  0,Ignore
         dc.l  0,0
         dc.w  2
         dc.l  0
MyBorder dc.w  -1,-1
         dc.b  2,0,RP_JAM1,5
         dc.l  Pairs
         dc.l  0

Pairs    dc.w  0,0,95,0,95,12,0,12,0,0

Bootblock   dc.b  'DOS',0
            dc.l  $c0200f19
            dc.l  $00000370
            dc.l  $43fa0018
            dc.l  $4eaeffa0
            dc.l  $4a80670a
            dc.l  $20402068
            dc.l  $00167000
            dc.l  $4e7570ff
            dc.w  $60fa
dosname     dc.b  'dos.library',0
            dc.l  0
Intuiname   dc.b    'intuition.library',0
Gfxname     dc.b    'graphics.library',0
Trackname   dc.b    'trackdisk.device',0
Clipname    dc.b    'clipboard.device',0
SName       dc.b    's:startup-sequence',0
DF0.MSG     dc.b    'df0:s/startup-sequence',0
Filename    dc.b    'CON:0/75/640/130/Ascii Dump of Boot Block',0
Title       dc.b    'Virus Checker V4.25',0
TITLETEXT1  dc.b    'Virus Checker Requester',0
def_font    dc.b    'topaz.font',0
TTVName     dc.b    'devs:',$a0,$a0,$a0,'   ',$a0,'   ',$a0,0
TTVName1    dc.b    'df0:devs/',$a0,$a0,$a0,'   ',$a0,'   ',$a0,0
Memmess     dc.b    'Your    Memory    was',0
BYTV        dc.b    'Byte Bandit Virus',0
SCAV        dc.b    'SCA type Virus',0
REVV        dc.b    'Revenge Virus',0
WARV        dc.b    'Byte Warrior Virus',0
TTVV        dc.b    'TTV1 Virus',0
IRQV        dc.b    'IRQ Virus',0
PENTV       dc.b    'Pentagon Virus',0
HCSV        dc.b    'HCS  Virus',0
NRTHV       dc.b    'North Star Virus',0
OBLV        dc.b    'Obelisk Virus',0
CRACKV      dc.b    'CrackRight Virus',0
LAMERV      dc.b    'LAMER Exterminator',0
TIMEBOMBV   dc.b    'TimeBomb Virus',0
GADAFFIV    dc.b    'GADAFFI Virus',0
GRAFFITIV   dc.b    'Graffiti Virus',0
PHANTAV     dc.b    'Phantasmumble Virus',0
ULTRAFOXV   dc.b    'Ultra Fox Virus',0
InfectedMsg dc.b    'infected with the                        ',0
NSTD        dc.b    'NON-STANDARD BOOT CODE',0
IRQ1        dc.b    'An error occured while trying to fix',0
IRQ2        dc.b    'The first file in the startup-sequence',0
IRQ3        dc.b    'The FILE MAY??? be DAMAGED',0
IRQ4        dc.b    'But it has now been corrected',0
Fmtstring   dc.b    'Virus Checker: Disks Checked: %ld Disks Installed:'
            dc.b    ' %ld Viruses Found %ld',0
Textmess    dc.b    'DANGER:   The disk in DF0: is',0
TTV1.MSG    dc.b    'TTVI Virus Found in Memory',0
Checkdisk.MSG dc.b  'Check disk in DF0:',0
Disablemess   dc.b  'But it has now been disabled',0
Error.MSG   dc.b    'Error Reading File on Disk',0
Present.MSG dc.b    'Disk not CHECKED',0
OkayMess    dc.b    'Okay',0
NoMess      dc.b    'No',0
Yes.MSG     dc.b    'Yes',0
DispMess    dc.b    'Display',0
RemoveMess  dc.b    'Remove',0
IgnoreMess  dc.b    'Ignore',0
RetryMess   dc.b    'Retry',0
CancelMess  dc.b    'Cancel',0
Bootmess    dc.b    'Rewrite the boot sectors',0
Rwritemess   dc.b   'Are you sure you want to',0
Wrtpro      dc.b    'Write Protected',0
Diskerr     dc.b    'DISK  ERROR:   Disk is',0
ErrorND     dc.b    'ERROR,  Nothing Done',0
Healed      dc.b    'Disk Healed',0


        end


