 Rem File: Dndsub1 for Dndbbs Version v5.0a Release r2.0 Tweak t5.0a
 Rem $Include: 'dndbbs.inc'

Function ValidFormat$(V$)
 On Local Error Goto ErrTrapXX
 ValidFormat$=Format$(Now,V$)
ErrResumeXX:
 Exit Function
ErrTrapXX:
 ValidFormat$="<error>"
 Resume ErrResumeXX
End Function

Sub Modem.Status
 On Local Error Goto ErrTrap1
 If Bypass.Screen Then
    Exit Sub
 Endif
 Out3=Strng
 If Blank.Screen Then
    Blank.Screen=False
    Call Opening.Screen
 Endif
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)
 Call ScreenANSI(2,23,10)
 Strng=Out3
 VarZ=Local.Mode
 Local.Mode=True
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 Local.Mode=VarZ
 Out3=Strng
 Out3=Left$(Out3,14)
 Out3=Out3+Space$(14-Len(Out3))
 Call Scrn(Out3)
 Call Display.Time
 Strng=Out3
ErrResume1:
 Exit Sub
ErrTrap1:
 Resume ErrResume1
End Sub

Sub Display.Time
 On Local Error Goto ErrTrap2
 If Blank.Screen Then
    Exit Sub
 Endif
 If Debug.Mode Then
    Call Display25row
 Endif
 Gosub Get.ConfigX
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)
 Call ScreenANSI(2,23,50)
 Strng=D1$
 VarZ=Local.Mode
 Local.Mode=True
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 D1$=Strng
 Strng=ValidFormat$(D1$)
 Call Scrn(Strng)
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)
 Call ScreenANSI(2,23,61)
 Strng=T1$
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 Local.Mode=VarZ
 T1$=Strng
 Strng=ValidFormat$(T1$)
 Tmp1=Len(Strng)
 Call Scrn(Strng)
 Locate 23,61+Tmp1,1
 Exit Sub
Get.ConfigX:
 VarX=0
 D1$="ddd dd mmm"
 T1$="hh:mm:ssa/p"
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[DNDBBS]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Exit Do
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Exit Do
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Lcase$(Ltrim$(Rtrim$(Left$(Var$,Var-1))))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             If Var2$="date.display" Then
                If Len(Var3$) Then
                   If Left$(Var3$,1)=Chr$(34) And Right$(Var3$,1)=Chr$(34) Then
                      Var3$=Left$(Var3$,Len(Var3$)-1) : Var3$=Mid$(Var3$,2)
                   Endif
                   Var3$=Ltrim$(Rtrim$(Var3$))
                   If Len(Var3$) Then
                      D1$=Var3$
                   Endif
                Endif
             Endif
             If Var2$="time.display" Then
                If Len(Var3$) Then
                   If Left$(Var3$,1)=Chr$(34) And Right$(Var3$,1)=Chr$(34) Then
                      Var3$=Left$(Var3$,Len(Var3$)-1) : Var3$=Mid$(Var3$,2)
                   Endif
                   Var3$=Ltrim$(Rtrim$(Var3$))
                   If Len(Var3$) Then
                      T1$=Var3$
                   Endif
                Endif
             Endif
          Endif
       Loop
    Endif
 Loop
 Return
ErrResume2:
 Exit Sub
ErrTrap2:
 Resume ErrResume2
End Sub

Sub Opening.Screen
 On Local Error Goto ErrTrap3
 ' extends array 06/30/2022
 Dim Menu.Array(1 To 26) As Integer
 Gosub Get.Config2
 Call Playwav(1)
 If Bypass.Screen=False Then
    If Config2(106) Then
       Def Seg=False
       Poke &H0417,0
       Def Seg
    Endif
 Endif
 Selection=1
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)
 Call ScreenANSI(3,0,0)
 If Max.Row=43 Then
    Width 80,Max.Row
    Locate Max.Row,1,1
    Call Shell.Program("ANSI.EXE","43")
    Locate ,,0
 Endif
 If Max.Row=50 Then
    Width 80,Max.Row
    Locate Max.Row,1,1
    Call Shell.Program("ANSI.EXE","50")
    Locate ,,0
 Endif
 Call ScreenANSI(2,24,1)
 Call ScreenANSI(4,33,0)
 Call ScreenANSI(4,44,30)
 Call ScreenANSI(2,2,3)
 If Border.Off=0 Then
    If Border.Char=0 Then
       Strng=Chr$(201)
       Call Scrn(Strng)
       Strng=String$(74,205)
       Call Scrn(Strng)
       Strng=Chr$(187)
       Call Scrn(Strng)
    Else
       Strng="+"
       Call Scrn(Strng)
       Strng=String$(74,"-")
       Call Scrn(Strng)
       Strng="+"
       Call Scrn(Strng)
    Endif
 Endif
 Redim Temp.ArrayS(1 To 18) As String
 Filename$=DND.Path+"copyrite.dat"
 If Dir$(Filename$)<>Nul Then
    Close TempFile1
    Open FileName For Input Shared As #TempFile1
    VarX=0
    Do Until Eof(TempFile1)
       Line Input #TempFile1,Var$
       Var$=Ltrim$(Var$)
       If Len(Var$) Then
          If Left$(Var$,1)<>";" Then
             If Instr(Var$,"=") Then
                Var2$=Left$(Var$,Instr(Var$,"=")-1)
                Var3$=Mid$(Var$,Instr(Var$,"=")+1)
             Endif
             Var2$=Ltrim$(Rtrim$(Var2$))
             Var3$=Ltrim$(Rtrim$(Var3$))
             If Left$(Var3$,1)=Chr$(34) And Right$(Var3$,1)=Chr$(34) Then
                Var3$=Left$(Var3$,Len(Var3$)-1) : Var3$=Mid$(Var3$,2)
             Endif
             If Lcase$(Var2$)="title" Then
                Title$=Var3$
                Temp.ArrayS(1)=Var3$
             Endif
             If Lcase$(Var2$)="author1" Then
                Author1$=Var3$
                Temp.ArrayS(4)=Var3$
             Endif
             If Lcase$(Var2$)="author2" Then
                Author2$=Var3$
                Temp.ArrayS(5)=Var3$
             Endif
             If Lcase$(Var2$)="author3" Then
                Author3$=Var3$
                Temp.ArrayS(6)=Var3$
             Endif
             If Left$(Lcase$(Var2$),5)="array" Then
                VarX=Int(Val(Mid$(Var2$,6))+.5)
                If VarX>=7 And VarX<=18 Then
                   If Left$(Lcase$(Var3$),4)="alt-" Then
                      VarQ$=Lcase$(Rtrim$(Mid$(Var3$,5,1)))
                      If Len(VarQ$)=1 Then
                         If VarQ$>="a" And VarQ$<="z" Then
                            VarQ=Asc(VarQ$)-96
                            If Menu.Array(VarQ) Then
                               Var3$=Var3$+"  <n/a>"
                            Endif
                         Endif
                      Endif
                   Endif
                   Temp.ArrayS(VarX)=Var3$
                Endif
             Endif
          Endif
       Endif
    Loop
 Endif
 If Title$=Nul Then
    Title$=ProgramName$+" v"+Version$+" r"+Release$+" t"+Tweak$+" "+YearRelease$
    Temp.ArrayS(1)=Title$
 Endif
 Temp1=1
 For Temp5=3 To 24
    Call ScreenANSI(4,33,0)
    Call ScreenANSI(4,44,30)
    Call ScreenANSI(2,Temp5,3)
    If Border.Off=0 Then
       If Border.Char=0 Then
          Strng=Chr$(186)
       Else
          Strng="|"
       Endif
       Call Scrn(Strng)
    Endif
    Select Case Temp5
    Case 5
       Strng=Title$
    Case 6, 7
       Strng=Nul
    Case 8
       Strng=Author1$
    Case 9
       Strng=Author2$
    Case 10
       Strng=Author3$
    Case 11 To 16
       If Bypass.Splash=4 Then
          Strng=Rtrim$(Temp.ArrayS(Temp5+2))
       Else
          Strng=Rtrim$(Temp.ArrayS(Temp5-4))
       Endif
       If Len(Strng) Then
          Mid$(Strng,1,1)=Ucase$(Mid$(Strng,1,1))
       Endif
    End Select
    Select Case Temp5
    Case 5 To 10
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
    Case 11 To 16
       Call ScreenANSI(4,33,0)
       Call ScreenANSI(4,44,30)
    End Select
    Select Case Temp5
    Case 5
       Call ScreenANSI(2,4,10)
       Call Scrn(Strng)
    Case 6
       Call ScreenANSI(2,6,10)
       Strng="Version v"+Version$+" r"+Release$+" t"+Tweak$+" ("+YearRelease$+")"
       Call Scrn(Strng)
       Call Copyright(-2)
       Call Amount2(Run.Number,Var$)
       Strng="Run: "+RunMode$+Var$
       Temp=74-Len(Strng)
       Call ScreenANSI(2,6,Temp)
       Call Scrn(Strng)
    Case 8 To 16
       VarQ1=True
       If Bypass.Splash=4 Then
          Eat$=Nul
       Else
          If (Bypass.Splash And 1)=1 Then
             If Temp5>=11 Then
                VarQ1=False
             Endif
          Endif
          If (Bypass.Splash And 2)=2 Then
             If Temp5<11 Then
                VarQ1=False
             Endif
          Endif
          If (Bypass.Splash And 1)=1 Then
             If (Bypass.Splash And 2)=0 Then
                If Temp5=11 Then
                   VarQ1=True
                   Strng=Rtrim$(GuestRecord.SysopEmail)
                   If Strng=Nul Then
                      Strng="dndbbs@gmail.com"
                   Endif
                Endif
              Endif
          Endif
       Endif
       If VarQ1 Then
          Call ScreenANSI(2,Temp5,28)
          If Right$(Rtrim$(Strng),5)="<n/a>" Then
             Var$=Left$(Strng,Len(Strng)-6)
             Call Scrn(Var$)
             Call ScreenANSI(4,37,0)
             Call ScreenANSI(4,44,31)
             Call ScreenANSI(2,Temp5,28+Len(Var$))
             Strng="<n/a>"
          Endif
          Call Scrn(Strng)
       Endif
    End Select
    If Temp1<6 Then
       If Temp5=Menu2(Temp1,1) Then
          Call ScreenANSI(4,33,0)
          Call ScreenANSI(4,44,30)
	  Var1=Menu2(Temp1,1)
	  Var2=Menu2(Temp1,2)
          Call ScreenANSI(2,Var1,Var2)
	  Strng="F"+Mid$(Str$(Temp1),2)+" "
	  Call Scrn(Strng)
          Call ScreenANSI(4,37,0)
          Call ScreenANSI(4,44,31)
          Strng=Left$(Menu1(Temp1),1)
	  Call Scrn(Strng)
          Call ScreenANSI(4,33,0)
          Call ScreenANSI(4,44,30)
          Strng=Mid$(Menu1(Temp1),2)
	  Strng=Rtrim$(Strng)
          VarZ=Local.Mode
          Local.Mode=True
          Call Convert.String ' convert macros
          Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
          Local.Mode=VarZ
	  Call Scrn(Strng)
          Call ScreenANSI(4,33,0)
          Call ScreenANSI(4,44,30)
	  Var1=Menu2(Temp1+5,1)
	  Var2=Menu2(Temp1+5,2)
          Call ScreenANSI(2,Var1,Var2)
          Strng="F"+Mid$(Str$(Temp1+5),2)+" "
	  Call Scrn(Strng)
          Call ScreenANSI(4,37,0)
          Call ScreenANSI(4,44,31)
          Strng=Left$(Menu1(Temp1+5),1)
	  Call Scrn(Strng)
          Call ScreenANSI(4,33,0)
          Call ScreenANSI(4,44,30)
          Strng=Mid$(Menu1(Temp1+5),2)
	  Strng=Rtrim$(Strng)
          VarZ=Local.Mode
          Local.Mode=True
          Call Convert.String ' convert macros
          Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
          Local.Mode=VarZ
	  Call Scrn(Strng)
	  Temp1=Temp1+1
       Endif
    Endif
    Select Case Temp5
    Case 18
       Call ScreenANSI(4,36,0)
       Call ScreenANSI(4,44,27)
       Call ScreenANSI(2,18,10)
       Strng="Ansi"
       Call Scrn(Strng)
       Call ScreenANSI(2,18,24)
       Strng="Avatar"
       Call Scrn(Strng)
       Call ScreenANSI(2,18,36)
       Strng="Share"
       Call Scrn(Strng)
       Call ScreenANSI(2,18,50)
       Strng="Fossil"
       Call Scrn(Strng)
       Call ScreenANSI(2,18,61)
       Strng="Port"
       Call Scrn(Strng)
       Call ScreenANSI(2,18,71)
       Strng="Disk"
       Call Scrn(Strng)
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,19,10)
       If Local.ANSI.Color Then
	  Strng="Yes"
       Else
	  Strng="No"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,19,24)
       If Local.Avatar.Color Then
	  Strng="Yes"
       Else
	  Strng="No"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,19,36)
       If Share.Installed Then
	  Strng="Yes"
       Else
	  Strng="No"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,19,50)
       If Local.Mode Then
          Strng="<n/a>"
       Else
          If Fossil.Active Then
             Strng="Yes"
             If Fossil.Version=1 Then
                Strng=Strng+": X00"
             Endif
          Else
             Strng="No"
          Endif
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,19,60)
       If Port<0 Then
          Strng=" -"
       Else
          Strng=Str$(Port)
          Strng=Strng+" ("+Hex$(Base.Address)+")"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,19,71)
       If Disk.Log Then
          Strng="Yes"
       Else
          Strng="No "
       Endif
       Call Scrn(Strng)
    Case 20
       Call ScreenANSI(4,36,0)
       Call ScreenANSI(4,44,27)
       Call ScreenANSI(2,20,10)
       Strng="Boot Type"
       Call Scrn(Strng)
       Call ScreenANSI(2,20,24)
       Strng="Mouse"
       Call Scrn(Strng)
       Call ScreenANSI(2,20,36)
       If Init.Space = 1 Then
          Strng="Free Space"
       Else
          If Init.Space = 2 Then
             Strng="Total Space"
          Else
             If Init.Space = 3 Then
                Strng="Used Space"
             Else
                Strng="Disk Space"
             Endif
          Endif
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,20,50)
       Strng="System"
       Call Scrn(Strng)
       Call ScreenANSI(2,20,61)
       Strng="Node"
       Call Scrn(Strng)
       Call ScreenANSI(2,20,71)
       Strng="Print"
       Call Scrn(Strng)
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,21,10)
       If Local.Mode Then
	  Strng="Local"
       Else
          Strng="BBS"
          Strng=Strng+" ("+Ltrim$(Str$(Modem.Baud))+")"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,21,24)
       If Mouse.Present Then
	  Strng="Yes"
       Else
	  Strng="No"
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,21,36)
       ' added 09/05/2021
       V = Init.Space
       Call FreeSpace (V, T#)
       Call Make.Format(T#)
       Call Scrn(Strng)

       Call ScreenANSI(2,21,50)
       Call System.Type
       Strng=Left$(Strng,10)
       Call Scrn(Strng)
       Call ScreenANSI(2,21,60)
       If Rtrim$(NodeX)=Nul Then
          Strng=" -"
       Else
          Strng=" "+NodeX
       Endif
       Call Scrn(Strng)
       Call ScreenANSI(2,21,71)
       If Print.Log Then
          Strng="Yes"
       Else
          Strng="No "
       Endif
       Call Scrn(Strng)
    Case 22
       Call ScreenANSI(4,36,0)
       Call ScreenANSI(4,44,27)
       Call ScreenANSI(2,22,10)
       Strng="Status"
       Call Scrn(Strng)
       Call ScreenANSI(2,22,24)
       Strng="Free Memory"
       Call Scrn(Strng)
       Call ScreenANSI(2,22,36)
       Strng="Version"
       Call Scrn(Strng)
       Call ScreenANSI(2,22,50)
       Strng="Date"
       Call Scrn(Strng)
       Call ScreenANSI(2,22,61)
       Strng="Time"
       Call Scrn(Strng)
       Call ScreenANSI(2,22,71)
       Strng="Debug"
       Call Scrn(Strng)
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,23,24)
       Call Get.Free.Memory
       Call Scrn(Strng)
       Call ScreenANSI(2,23,36)
       Strng="v"+Version$+" r"+Release$
       Call Scrn(Strng)
       Call ScreenANSI(2,23,71)
       If Debug.Mode Then
          Strng="(on)"
       Else
          Strng="(off)"
       Endif
       Call Scrn(Strng)
    End Select
    Call ScreenANSI(4,33,0)
    Call ScreenANSI(4,44,30)
    Call ScreenANSI(2,Temp5,78)
    If Border.Off=0 Then
       If Border.Char=0 Then
          Strng=Chr$(186)
       Else
          Strng="|"
       Endif
       Call Put.Screen(Strng)
    Endif
 Next
 Erase Temp.ArrayS
 Call ScreenANSI(2,24,3)
 If Border.Off=0 Then
    If Border.Char=0 Then
       Strng=Chr$(200)
       Call Scrn(Strng)
       Strng=String$(74,205)
       Call Scrn(Strng)
       Strng=Chr$(188)
       Call Put.Screen(Strng)
    Else
       Strng="+"
       Call Scrn(Strng)
       Strng=String$(74,"-")
       Call Scrn(Strng)
       Strng="+"
       Call Put.Screen(Strng)
    Endif
 Endif
 Next.Field=Init.Field
 Call Show.Field
 If Mouse.Present Then
    Call Mouse.Function(1,0)
 Endif
 Exit Sub
Get.Config2:
 VarX=0
 Init.Space=1
 Init.Field=1
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[DNDBBS]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Exit Do
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Exit Do
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Lcase$(Ltrim$(Rtrim$(Left$(Var$,Var-1))))
             Var3$=Lcase$(Ltrim$(Rtrim$(Mid$(Var$,Var+1))))
             If Var2$="init.field" Then
                If (Var3$>="a" And Var3$<="z") Or Var3$="*" Then
                   VarX$=Nul
                   For VarZ=1 To 10
                      VarZ$=Menu1(VarZ)
                      VarZ$=Rtrim$(VarZ$)
                      If VarZ$="" Then
                         VarX$=VarX$+"*"
                      Else
                         VarX$=VarX$+Left$(VarZ$,1)
                      Endif
                   Next
                   VarX$=Lcase$(VarX$)
                   If Instr(VarX$,Var3$) Then
                      Init.Field=Instr(VarX$,Var3$)
                   Endif
                Endif
                If Int(Val(Var3$)+.5)>=1 And Int(Val(Var3$)+.5)<=10 Then
                   Init.Field=Int(Val(Var3$)+.5)
                Endif
             Endif
             If Var2$="border" Then
                Select Case Var3$
                Case "0", "false", "off"
                   Border.Off=True
                End Select
             Endif
             If Var2$="borderchar" Then
                Select Case Var3$
                Case "0", "false", "off"
                   Border.Char=True
                End Select
             Endif
             If Var2$="diskspace" Then
                Select Case Var3$
                Case "-1", "true", "on", "total"
                   Init.Space=2
                Case "-2", "used"
                   Init.Space=3
                End Select
                If Var3$=Chr$(34)+"total"+Chr$(34) Then
                   Init.Space=2
                Endif
                If Var3$=Chr$(34)+"used"+Chr$(34) Then
                   Init.Space=3
                Endif
             Endif
             If Left$(Var2$,4)="alt-" Then
                VarQ$=Mid$(Var2$,5)
                If Len(VarQ$)=1 Then
                   If VarQ$>="a" And VarQ$<="z" Then
                      VarQ=Asc(VarQ$)-96
                      Select Case Var3$
                      Case "0", "false", "off"
                         Menu.Array(VarQ)=-1
                      End Select
                   Endif
                Endif
             Endif
          Endif
       Loop
    Endif
 Loop
 VarX$=Ucase$(Environ$("BLIND"))
 If VarX$="ON" Or VarX$="-1" Or VarX$="TRUE" Then
    Border.Off=True
 Endif
 VarX$=Ucase$(Environ$("BLINDCHAR"))
 If VarX$="ON" Or VarX$="-1" Or VarX$="TRUE" Then
    Border.Char=-1
 Endif
 Return
ErrResume3:
 Exit Sub
ErrTrap3:
 Resume ErrResume3
End Sub

Sub Display25row
 On Local Error Goto Row.Error
 Gosub Get.ConfigX3
 Strng=Nul
 If Option0 Then
    Strng="Debug"
 Endif
 If Option1 Then
    Strng=Strng+" : port"
    If Port<0 Then
       Strng=Strng+" -"
    Else
       Strng=Strng+Str$(Port)
    Endif
 Endif
 If Option2 Then
    Strng=Strng+" : modem baud"+Str$(Modem.Baud)
 Endif
 If Option3 Then
    Strng=Strng+" : base address 0x"+Hex$(Base.Address)
 Endif
 If Option4 Then
    If Local.Mode Then
       Strng=Strng+" : Local Mode"
    Else
       If Fossil.Active = 0 Then
          Strng=Strng+" : BBS Mode"
       Else
          If Fossil.Version = 1 Then
             Strng=Strng+" : X00 Mode"
          Endif
          If Fossil.Version = 2 Then
             Strng=Strng+" : Fossil Mode"
          Endif
       Endif
    Endif
 Endif
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)

 ' ztore statusline value
 If OptionZ=-1 Then
    Var9=25
 Else
    If OptionZ=1 Then
       Var9=1
    Else
       Var9=Max.Row
    Endif
 Endif

 Call ScreenANSI(2,Var9,3)
 Var$=Space$(77)
 Call Put.Screen(Var$)

 If Debug.Mode=-1 Then
    If Len(DebugColor$) Then
       Strng=DebugColor$+Strng
    Endif
 Endif
 If Debug.Mode=-2 Then
    If Len(DebugColor2$) Then
       Strng=DebugColor2$+Strng
    Else
       DebugColor2$="{B2{FE"
       Strng=DebugColor2$+Strng
    Endif
 Endif
 VarZ=Local.Mode
 Local.Mode=True
 Call Convert.String ' convert macros
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 Local.Mode=VarZ
 Call ScreenANSI(2,Var9,3)
 If Left$(Strng, 3) = " : " Then
    Strng=Mid$(Strng, 4)
 Endif
 Strng=Left$(Strng,76)
 Strng=Strng+Space$(76-Len(Strng))
 Call Put.Screen(Strng)
 Exit Sub
Get.ConfigX3:
 VarX=0
 DebugColor$=Nul
 DebugColor2$=Nul
 Option0=-1
 Option1=-1
 Option2=-1
 Option3=-1
 Option4=-1
 OptionZ=-1
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[DNDBBS]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Exit Do
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Exit Do
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Lcase$(Ltrim$(Rtrim$(Left$(Var$,Var-1))))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             If Left$(Var3$,1)=Chr$(34) And Right$(Var3$,1)=Chr$(34) Then
                Var3$=Left$(Var3$,Len(Var3$)-1) : Var3$=Mid$(Var3$,2)
             Endif
             Select Case Var2$
             Case "debug.debug"
                Select Case Var3$
                Case "0", "false", "off"
                   Option0=False
                End Select
             Case "debug.line"
                Var3$=Ltrim$(Rtrim$(Var3$))
                If Var3$="maxrow" Then
                   OptionZ=0
                Endif
                If Var3$="minrow" Then
                   OptionZ=1
                Endif
             Case "debug.port"
                Select Case Var3$
                Case "0", "false", "off"
                   Option1=False
                End Select
             Case "debug.baud" 
                Select Case Var3$
                Case "0", "false", "off"
                   Option2=False
                End Select
             Case "debug.base"
                Select Case Var3$
                Case "0", "false", "off"
                   Option3=False
                End Select
             Case "debug.mode"
                Select Case Var3$
                Case "0", "false", "off"
                   Option4=False
                End Select
             Case "debug.color"
                If Len(Var3$) Then
                   DebugColor$=Var3$
                Endif
             Case "debug.color2" 
                If Len(Var3$) Then
                   DebugColor2$=Var3$
                Endif
             End Select
          Endif
       Loop
    Endif
 Loop
 Return
RowResume1:
 Exit Sub
Row.Error:
 Resume RowResume1
End Sub

Sub Get.Command
 On Local Error Goto Boot.Error
 ' init startup variables
 Local.Mode=False
 Low.Mem.Use=False
 Node=False
 NodeX=Nul
 Call Read.Rows(Max.Row)
 MaxRow.Override=False
 Port.Override=False
 Time.Override=False

 User.PageLength=25
 User.LineLength=80

 Call VideoInt(15,0)
 Video.Page=OutregsX.BX

 Command.Line$=Ucase$(Command$)
 Command.Line$=Ltrim$(Rtrim$(Command.Line$))

 ' parse command line
 Select Case Command.Line$
 Case "/?", "-?", "?"
    Goto Boot.Usage
 End Select
 If Ucase$(Command.Line$) = "/HELP" Then
    Goto Boot.Usage
 Endif

 ' get command line from file
 If Instr(Command.Line$,"/")=0 Then
    If Left$(Command.Line$,1)="@" Then
       If Instr(Command.Line$,"\") Then Goto Boot.Error
       If Instr(Command.Line$,":") Then Goto Boot.Error
       DND.Path=Environ$("DNDBBS")
       If DND.Path<>Nul Then
          If Right$(DND.Path,1)<>"\" Then
             DND.Path=DND.Path+"\"
          Endif
       Endif
       Filename$=Mid$(Command.Line$,2)
       Filename$=Ltrim$(Rtrim$(Filename$))
       If Left$(Filename$,1)=Chr$(34) Then
          Filename$=Mid$(Filename$,2)
          If Right$(Filename$,1)=Chr$(34) Then
             Filename$=Left$(Filename$,Len(Filename$)-1)
          Else
             Goto Boot.Error
          Endif
       Endif
       Filename$=DND.Path+Filename$
       If Dir$(Filename$)<>"" Then
          Close #TempFile1
          Open Filename$ For Input Shared As #TempFile1
          If Eof(TempFile1)=0 Then
             Line Input #TempFile1,Command.Line$
             Command.Line$=Ucase$(Command.Line$)
          Else
             Goto Boot.Error
          Endif
       Else
          Goto Boot.Error
       Endif
    Endif
 Endif
 Close #TempFile1, #TempFile2

 ' remove spaces from command line
 Var1=Instr(Command.Line$," ")
 While Var1
    Command.Line$=Left$(Command.Line$,Var1-1)+Mid$(Command.Line$,Var1+1)
    Var1=Instr(Command.Line$," ")
 Wend

 ' login name override
 Var1=Instr(Command.Line$,"/N:"+Chr$(34))
 If Var1 Then
    Var2=Instr(Var1+4,Command.Line$,Chr$(34))
    If Var2 Then
       Temp$=Mid$(Command.Line$,Var1+4,Var2-Var1-4)
       Command.Line$=Left$(Command.Line$,Var1-1)+Mid$(Command.Line$,Var2+1)
       If Temp$=Nul Then
          Goto Boot.Error
       Endif
       Bypass.CodeName=Temp$
       Bypass.Login=True
    Endif
 Endif

 ' time cold boot
 Var1=Instr(Command.Line$,"/S:"+Chr$(34))
 If Var1 Then
    Var2=Instr(Var1+4,Command.Line$,Chr$(34))
    If Var2 Then
       Temp$=Mid$(Command.Line$,Var1+4,Var2-Var1-4)
       Command.Line$=Left$(Command.Line$,Var1-1)+Mid$(Command.Line$,Var2+1)
       If Temp$=Nul Then
          Goto Boot.Error
       Endif
       MidnightX$=Temp$
    Endif
 Endif

 ' modem base address
 Var1=Instr(Command.Line$,"/A:"+Chr$(34))
 If Var1 Then
    Var2=Instr(Var1+4,Command.Line$,Chr$(34))
    If Var2 Then
       Temp$=Mid$(Command.Line$,Var1+4,Var2-Var1-4)
       Command.Line$=Left$(Command.Line$,Var1-1)+Mid$(Command.Line$,Var2+1)
       If Temp$=Nul Then
          Goto Boot.Error
       Endif
       VarX=ValidHex(Temp$)
       If VarX=0 Then
          Goto Boot.Error
       Endif
       Temp$="&H"+Temp$
       If Int(Val(Temp$)+.5)>=1 And Int(Val(Temp$)+.5)<=MaxInt Then
          Base.Address=Int(Val(Temp$)+.5)
       Else
          Goto Boot.Error
       Endif
    Endif
 Endif

 ' override os
 Out2="/SUNOS"
 Gosub Get.Switch
 If Var1 Then
    DOS.Major=50
    DOS.Minor=0
 Endif

 ' override os
 Out2="/LINUX"
 Gosub Get.Switch
 If Var1 Then
    DOS.Major=40
    DOS.Minor=0
 Endif

 ' override os
 Out2="/OSX"
 Gosub Get.Switch
 If Var1 Then
    DOS.Major=30
    DOS.Minor=0
 Endif

 ' override os
 Out2="/OS2"
 Gosub Get.Switch
 If Var1 Then
    OS2.Detected=True
    DOS.Major=10
    DOS.Minor=0
 Endif

 ' override os
 Out2="/OS"
 Gosub Get.Switch
 If Var1 Then
    Windows.Detected=-1
    Win.Major=5
    Win.Minor=0
 Endif

 ' detect remaining switches
 Out2="/BY" ' bypass
 Gosub Get.Switch
 Bypass.Screen=Var1
 Out2="/DO" ' door
 Gosub Get.Switch
 BBS.Mode=Var1
 Out2="/TN" ' telnet
 Gosub Get.Switch
 If Var1 Then
    BBS.Mode=-2
 Endif
 Out2="/LC"
 Gosub Get.Switch
 Local.Mode=Var1
 If Modem.Baud=0 Then
    Modem.Baud=9600!
 Endif
 If Base.Address=0 Then
    Base.Address=&H3F8
 Endif
 ' debug switches
 Out2="/D:1"
 Gosub Get.Switch
 If Var1 Then
    Bypass.Splash=Bypass.Splash Or 1
 Endif
 Out2="/D:2"
 Gosub Get.Switch
 If Var1 Then
    Bypass.Splash=Bypass.Splash Or 2
 Endif
 Out2="/D:3"
 Gosub Get.Switch
 If Var1 Then
    Debug.Pack=True
 Endif
 Out2="/D:4"
 Gosub Get.Switch
 If Var1 Then
    Low.Mem.Use=True
 Endif
 Out2="/D:5"
 Gosub Get.Switch
 If Var1 Then
    Disable.Share=True
 Endif
 Out2="/D:6"
 Gosub Get.Switch
 If Var1 Then
    Debug.Mode=True
 Endif

 ' fossil version override switches
 Out2="/F:0" ' off
 Gosub Get.Switch
 If Var1 Then
    Fossil.Mode=-1
 Endif
 Out2="/F:1" ' v1
 Gosub Get.Switch
 If Var1 Then
    Fossil.Mode=1
 Endif
 Out2="/F:2" ' v2
 Gosub Get.Switch
 If Var1 Then
    Fossil.Mode=2
 Endif

 ' max rows override
 Var1=Instr(Command.Line$,"/M:")
 If Var1 Then
    Temp$=Left$(Command.Line$,Var1-1)
    Command.Line$=Mid$(Command.Line$,Var1+3)
    Gosub Get.Numeric
    Command.Line$=Temp$+Command.Line$
    Temp=Int(Val(TempA$)+.5)
    Select Case Temp
    Case 25, 43, 50
       MaxRow.Override=Temp
    Case Else
       Goto Boot.Error
    End Select
 Endif
 If MaxRow.Override=False Then
    Call Read.Rows(Max.Row)
 Else
    Max.Row=MaxRow.Override
 Endif

 ' modem base address
 Var1=Instr(Command.Line$,"/A:")
 Var2=Instr(Command.Line$,"/A")
 If Var1 Or Var2 Then
    If Var1 Then
       Temp$=Left$(Command.Line$,Var1-1)
       Command.Line$=Mid$(Command.Line$,Var1+3)
    Else
       Temp$=Left$(Command.Line$,Var2-1)
       Command.Line$=Mid$(Command.Line$,Var2+2)
    Endif
    Gosub Get.Numeric3
    Command.Line$=Temp$+Command.Line$
    Temp=Int(Val("&H"+TempA$)+.5)
    If Temp>=1 And Temp<=MaxInt Then
       Base.Address=Temp
    Else
       Goto Boot.Error
    Endif
    ' fixed 08/10/2021
    UserConfigRecord.UserConfig2=Base.Address
    Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+114)
 Endif

 ' port number override
 Var1=Instr(Command.Line$,"/P:")
 Var2=Instr(Command.Line$,"/P")
 If Var1 Or Var2 Then
    If Var1 Then
       Temp$=Left$(Command.Line$,Var1-1)
       Command.Line$=Mid$(Command.Line$,Var1+3)
    Else
       Temp$=Left$(Command.Line$,Var2-1)
       Command.Line$=Mid$(Command.Line$,Var2+2)
    Endif
    Gosub Get.Numeric
    Command.Line$=Temp$+Command.Line$
    Temp=Int(Val(TempA$)+.5)
    If Temp>=1 And Temp<=MaxPorts Then
       Port.Override=Temp
       ' fixed 08/10/2021
       UserConfigRecord.UserConfig2=Port.Override
       Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+46)
    Endif
    If Port.Override=False Then
       Goto Boot.Error
    Endif
 Endif

 ' port baud override
 Var1=Instr(Command.Line$,"/B:")
 Var2=Instr(Command.Line$,"/B")
 If Var1 Or Var2 Then
    If Var1 Then
       Temp$=Left$(Command.Line$,Var1-1)
       Command.Line$=Mid$(Command.Line$,Var1+3)
    Else
       Temp$=Left$(Command.Line$,Var2-1)
       Command.Line$=Mid$(Command.Line$,Var2+2)
    Endif
    Gosub Get.Numeric2
    Command.Line$=Temp$+Command.Line$
    TempQ!=Csng(Int(Val(TempA$))+.5)
    If TempQ!=0! Then
       Goto Boot.Error
    Endif
    Call Set.Baud(TempQ!)
    ' fixed 08/10/2021
    UserConfigRecord.UserConfig2=Cint(Modem.Baud/100!)
    Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+64)
 Endif

 ' cold reboot switch
 VarQ=0
 Out2="/R:1"
 Gosub Get.Switch
 If Var1 Then
    VarQ=1
 Endif

 ' warm reboot switch
 Out2="/R:2"
 Gosub Get.Switch
 If Var1 Then
    VarQ=2
 Endif

 ' midnight reboot cold switch
 Out2="/R:3"
 Gosub Get.Switch
 If Var1 Then
    Midnight.Reboot=True
 Endif

 ' midnight reboot warm switch
 Out2="/R:4"
 Gosub Get.Switch
 If Var1 Then
    Midnight.Reboot=-2
 Endif

 ' ram drive letter
 Var1=Instr(Command.Line$,"/R:")
 If Var1 Then
    TempA$=Mid$(Command.Line$,Var1+3,1)
    Command.Line$=Left$(Command.Line$,Var1-1)+Mid$(Command.Line$,Var1+4)
    Temp=Asc(TempA$)
    If Temp>=65 And Temp<=90 Then
       Drive.Override=Temp
    Endif
    If Drive.Override=False Then
       Goto Boot.Error
    Endif
 Endif

 ' time override
 Var1=Instr(Command.Line$,"/T:")
 If Var1 Then
    Temp$=Left$(Command.Line$,Var1-1)
    Command.Line$=Mid$(Command.Line$,Var1+3)
    Gosub Get.Numeric
    Command.Line$=Temp$+Command.Line$
    Temp=Int(Val(TempA$)+.5)
    If Temp>=1 And Temp<=MaxInt Then
       Time.Override=Temp
    Endif
    If Time.Override=False Then
       Goto Boot.Error
    Endif
 Endif

 ' optional node switch
 If Left$(Command.Line$,1)="/" Then
    Select Case Len(Command.Line$)
    Case 1 ' no node
       Node=0
       NodeX=""
       Command.Line$=Nul
    Case 2 ' single char
       Command.Line$=Mid$(Command.Line$,2)
       Select Case Ucase$(Command.Line$)
       Case "0" To "9" ' 1-10
          Node=Val(Command.Line$)+1
          NodeX=Command.Line$
          Command.Line$=Nul
       Case "A" To "Z" ' 11-36
          Node=Asc(Ucase$(Command.Line$))-54
          NodeX=Ucase$(Command.Line$)
          Command.Line$=Nul
       End Select
    Case 3 ' double char
       Command.Line$=Mid$(Command.Line$,2)
       VarX=Int(Val(Command.Line$)+.5)
       If VarX>=10 And VarX<=99 Then
          Node=VarX+27 ' 37-126
          NodeX=Mid$(Str$(VarX),2) ' 10-99
          Command.Line$=Nul
       Endif
    End Select
 Endif

 ' recheck remaining command line
 If Command.Line$<>Nul Then
    Goto Boot.Error
 Endif

 If VarQ=1 Then
    ' cold boot
    Out2="Now exiting the Dndbbs Adventure System.."
    Out3="Reason: Command line cold boot. "+Fclock$
    Strng1="Terminated program."
    Strng2="Reason: Command line cold boot."
    Strng3=Nul
    Call Write.Logfile(True)
    Close #TempFile1
    Call Terminate.Program(2)
    End 0
 Endif
 If VarQ=2 Then
    ' warm boot
    Out2="Now exiting the Dndbbs Adventure System.."
    Out3="Reason: Command line warm boot. "+Fclock$
    Strng1="Terminated program."
    Strng2="Reason: Command line warm boot."
    Strng3=Nul
    Call Write.Logfile(True)
    Close #TempFile1
    Call Terminate.Program(1)
    End 0
 Endif

 ' check local mode override
 If Local.Mode Then
    MessWorkRecord1.PortNumber=0
    VarX2=Node+1
    Call Write.Message.Record(MessWorkFile1,VarX2)
 Endif

 ' store variables and exit
 NodeX=Rtrim$(NodeX)
 Width 80,Max.Row
 Locate Max.Row,1,1
 Exit Sub

' scan for a switch in command line
Get.Switch:
 Var1=False
 VarX=Instr(Command.Line$,Out2)
 If VarX Then
    Var1=True
    Command.Line$=Left$(Command.Line$,VarX-1)+Mid$(Command.Line$,VarX+Len(Out2))
 Endif
 Return

' scan for a value in command line
Get.Numeric:
 TempA$=Nul
 Do
    TempY$=Left$(Command.Line$,1)
    If TempY$>="0" And TempY$<="9" Then
       TempA$=TempA$+TempY$
       Command.Line$=Mid$(Command.Line$,2)
    Else
       Exit Do
    Endif
 Loop
 Return

' scan for a value in command line
'  including a . character..
Get.Numeric2:
 TempA$=Nul
 Do
    TempY$=Left$(Command.Line$,1)
    Select Case TempY$
    Case "0" To "9"
       TempA$=TempA$+TempY$
       Command.Line$=Mid$(Command.Line$,2)
    Case "."
       TempA$=TempA$+TempY$
       Command.Line$=Mid$(Command.Line$,2)
    Case Else
       Exit Do
    End Select
 Loop
 Return

' scan for a hex value in command line
Get.Numeric3:
 TempA$=Nul
 Do
    TempY$=Left$(Command.Line$,1)
    Select Case TempY$
    Case "0" To "9", "A" To "F"
       TempA$=TempA$+TempY$
       Command.Line$=Mid$(Command.Line$,2)
    Case Else
       Exit Do
    End Select
 Loop
 Return

' display boot usage for command line
Boot.Usage:
 Call Read.Rows(Max.Row)
 Locate Max.Row-1,1,1

 Var$="bootkey1.txt"
 Gosub Display.File

 If Instr(Command$,"/HELP") Then
    Var$="bootkey2.txt"
    Gosub Display.File
    Var$="bootkey3.txt"
    Gosub Display.File
 Endif
 Call Exit.To.DOS
 Color 7,0
 End 0

' trap and display any error processing command line
Boot.Error:
 Call Read.Rows(Max.Row)
 Locate Max.Row-1,1,1

 Var$="booterr.txt"
 Gosub Display.File

 Strng1="Terminated program."
 Strng2="Reason: Command line boot error."
 Strng3=Nul
 Call Write.Logfile(True)

 Call Exit.To.DOS
 Color 7,0
 End 0

Display.File:
 ANSIPrefixChar="{"
 Disable.Play=-2
 Local.Mode=True
 Port=True

 DND.Path=Environ$("DNDBBS")
 If DND.Path<>Nul Then
    If Right$(DND.Path,1)<>"\" Then
       DND.Path=DND.Path+"\"
    Endif
 Endif
 Filename=DND.Path+Var$
 If Dir$(FileName)<>Nul Then
    Call Out.File(FileName)
 Endif
 Return
End Sub

' set the default modem baud rate
'  fixed default.baud 08/10/2021
Sub Set.Baud(TempQ!)
 On Local Error Goto Baud.Error
 Gosub Get.Config3
 If TempQ!>=0! And TempQ!<=230400! Then
    Select Case TempQ!
    Case 50!, 75!, 110!, 134.5!, 150!, 450!
       Modem.Baud=300!
    Case 7200!
       Modem.Baud=4800!
    Case 12000!, 14400!, 16800!
       Modem.Baud=9600!
    Case 21600!, 24000!, 26400!, 28800!, 31200!, 33600!
       Modem.Baud=19200!
    Case 64000!, 78600!
       Modem.Baud=57600!
    Case 230400!
       Modem.Baud=115200!
    Case 300!, 600!, 1200!, 2400!, 4800!, 9600!, 19200!, 38400!, 57600!, 115200!
       Modem.Baud=TempQ!
    Case Else
       Modem.Baud=Default.Baud!
    End Select
 Endif
 Exit Sub
Get.Config3:
 Default.Baud!=9600!
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[MODEM]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,Var-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             Select Case Lcase$(Var2$)
             Case "ignore.baud"
                Default.Baud!=9600! ' hardwired/could be changed
                Return
             Case "default.baud"
                VarQ!=Csng(Int(Val(Var3$))+.5)
                Select Case VarQ!
                Case 300!, 600!, 1200!, 2400!, 4800!, 9600!, 19200!, 38400!, 57600!, 115200!
                   Default.Baud!=VarQ!
                Case Else ' default baud default!
                   Default.Baud!=9600!
                End Select
             End Select
          Endif
       Loop
    Endif
 Loop
 Return
Baud.Exit:
 Modem.Baud=9600!
 Exit Sub
Baud.Error:
 Resume Baud.Exit
 End Sub

Sub Read.Door
 On Local Error Goto Door.Error
 If Rtrim$(Door.Name)=Nul Then
    VarX=-1
 Endif
 BBS.Name=Nul
 Door.Name=Nul
 Door.Node=Config3(83)
 Door.Time=180! ' default time
 If BBS.Mode=False Then
    Exit Sub
 Endif
 If BBS.Mode=-2 Then ' telnet mode
    Gosub Get.Config9
    Exit Sub
 Endif
 VarX$=Rtrim$(Door.Node)
 ' RBBS v17.4 node: 1-9,0,A-Z (can be nul)
 If Len(VarX$)<=1 Then ' single-letter
    Var$="DORINFO"+VarX$+".DEF"
    Filename=Config3(84)+Var$
    Var2$=Filename
    If Dir$(FileName)=Var$ Then
       Goto Read.Door.File
    Endif
 Endif
 ' RBBS v17.5 node: 1-9,0,A-Z,10-99 (can be nul)
 Var$="DINF"+VarX$+".DEF" ' dual-letter
 Filename=Config3(84)+Var$
 Var3$=Filename
 If Dir$(FileName)=Var$ Then
    Goto Read.Door.File
 Endif
 Goto Door.Error
' fixed 08/30/2020
Read.Door.File:
 Close #TempFile1
 Open FileName For Input Shared As #TempFile1
 For Var=1 To 13
    If Var=13 Then ' old rbbs file
       If Eof(TempFile1) Then
          Exit For
       Endif
    Endif
    Line Input #TempFile1,Strng
    Strng=Rtrim$(Strng)
    Select Case Var
    Case 1
       ' store BBS name.
       If Strng=Nul Then
          BBS.Name="<n/a>"
       Else
          BBS.Name=Strng
       Endif
    Case 4
       ' store modem comm port number.
       Port=Int(Val(Mid$(Strng,4))+.5)
       ' comm port 0 is sysop.
       If Port=0 Then
          Local.Mode=True
       Endif
       ' modem port starts at 0.
       Port=Port-1
    Case 5
       ' store modem speed.
       Strng=Ltrim$(Strng)
       ' fixed variable collision here:
       VarZ=Instr(Strng," ")
       If VarZ Then
          Temp$=Left$(Strng,VarZ-1)
       Else
          Temp$=Strng
       Endif
       Modem.Baud=Csng(Int(Val(Temp$))+.5)
       Modem.Return=Mid$(Str$(Modem.Baud),2)
    ' Note: First name 'Sysop' does not imply local mode.
    Case 7
       ' store first part of user name.
       Door.Name=Strng
    Case 8
       ' store second part of user name.
       If Len(Strng) Then
          Door.Name=Door.Name+" "+Strng
       Endif
    Case 10
       If Int(Val(Strng)+.5)=2 Then
          Remote.ANSI.Color=True
       Endif
    Case 12
       ' store remaining bbs door time.
       Door.Time=Val(Strng)*60!
    Case 13
       ' fossil
       If Val(Strng) Then
          Fossil.Active=True
          Fossil.Version=2
       Endif
    End Select
 Next
 ' check fossil override
 Select Case Fossil.Mode
 Case -1 ' off
    Fossil.Active=False
    Fossil.Version=0
 Case 1 ' v1 x00
    Fossil.Active=True
    Fossil.Version=1
 Case 2 ' v2 fossil
    Fossil.Active=True
    Fossil.Version=2
 End Select
 If VarX Then
    Strng1="RBBS door information file loaded."
    Strng2=Nul:Strng3=Nul
    Call Write.Logfile(False)
 Endif
 Exit Sub
Door.Error:
 Out2=Nul
 If Len(Var2$) Then
    Out2=Out2+Var2$
    If Len(Var3$) Then
       Out2=Out2+" -- "
    Endif
 Endif
 If Len(Var3$) Then
    Out2=Out2+Var3$
 Endif
 If Len(Var2$)=0 And Len(Var3$)=0 Then
    If Rtrim$(Door.Node)=Nul Then
       Out2=Out2+"Node -"
    Else
       Out2=Out2+"Node "+Door.Node
    Endif
 Endif
 Out3="RBBS door information file not found, or invalid."
 Strng1=Out3
 Strng2=Nul:Strng3=Nul
 Call Write.Logfile(False)
 Strng2=" reading door file:"
 Call Terminal.Error
 End 0
Get.Config9:
 ' default door settings
 BBS.Name="DNDBBS"
 Door.Name="JOE UZERNAME"
 Door.Time=3600!
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[TELNET]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,Var-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             Select Case Lcase$(Var2$)
             Case "base.address" ' /A
                Temp=Int(Val("&H"+Var3$)+.5)
                If Temp>=1 And Temp<=MaxInt Then
                   Base.Address=Temp
                Endif
             Case "baud.rate" ' /B
                TempQ!=Csng(Int(Val(Var3$))+.5)
                If TempQ!>0! Then
                   Call Set.Baud(TempQ!)
                Endif
             Case "port.number" ' /C
                Temp=Int(Val(Var3$)+.5)
                If Temp>=0 And Temp<=64 Then
                   Port=Temp-1
                   Port.Override=Temp
                Endif
             Case "bbs.name"
                BBS.Name=Var3$
             Case "door.name"
                Door.Name=Ucase$(Var3$)
             Case "door.time"
                Door.Time=Int(Val(Var3$)+.5)*60!
             Case "ansi.color"
                If Var3$="-1" Then
                   Remote.ANSI.Color=True
                Endif
                If Var3$="-2" Then
                   Remote.Avatar.Color=True
                Endif
                If Var3$="-3" Then
                   Remote.ANSI.Color=True
                   Remote.Avatar.Color=True
                Endif
             Case "fossil.mode"
                If Var3$="-1" Then
                   Fossil.Active=True
                   Fossil.Version=2
                Endif
                If Var3$="-2" Then ' x00
                   Fossil.Active=True
                   Fossil.Version=1
                Endif
             End Select
          Endif
       Loop
    Endif
 Loop
 Return
End Sub

Sub Open.Modem
 On Local Error Goto ErrTrap4
 Static Ansi.Blank As Integer
 Gosub Get.Config5
 Ansi.Blank=False
 Connect=False
 Logged.In=False
 Lost.Carrier=False
 Locate Max.Row-1,1,1
 If BBS.Mode Then
    Color 15,0
    Lost.Carrier=False
    Timeon=Timeit!
    Time.Left=Door.Time
    Two.Minutes.Left=False
    Security.Guard=True
    If Local.Mode Then
       Print "Local DOOR Mode: Door node ";
       If Rtrim$(Door.Node)=Nul Then
          Print "-."
       Else
          Print Rtrim$(Door.Node)+"."
       Endif
       Exit Sub
    Endif
    Out2=Nul
    Out3=Nul
    Call Init.Fossil.Port
    Call Check.Modem(Var)
    If Var Then
       OutZ="no modem"
       Goto Quit.Door
    Endif
    If (OutregsX.AX And &H80)=0 Then
       OutZ="carrier lost"
       Goto Quit.Door
    Endif
    For VarQ=1 To MaxModemBauds
       Strng=Rtrim$(Modem.String(VarQ))
       If Len(Strng) Then
          If Modem.Baud=Modem.Connect(VarQ) Then
             If Modem.Allow(VarQ)=False Then
                Strng="Sorry,"+Str$(Modem.Baud)+" baud access not allowed!"
                Call IO.O
                OutZ="baud rate"
                Goto Quit.Door
             Endif
          Endif
       Endif
    Next
    Strng="DOOR Mode: Door node "
    If Rtrim$(Door.Node)=Nul Then
       Strng=Strng+"-"
    Else
       Strng=Strng+Rtrim$(Door.Node)
    Endif
    If Port=-1 Then
       Strng=Strng+": Port -"
    Else
       Strng=Strng+": Port"+Str$(Port)+", "
       Strng=Strng+": Connect"+Str$(Modem.Baud)
    Endif
    Call IO.O
    Exit Sub
 Endif
 If Bypass.Screen Or Bypass.Login Then
    Timeon=Timeit!
    Time.Left=3600!
    Two.Minutes.Left=False
    Local.Mode=True
    Exit Sub
 Endif
 Call Init.Comm.Driver
 Recycle=True
 Wait.State!=Timeit!
 Do While Recycle
    Ansi.Blank=False
    Blank.Menu=True
    Blank.Screen=False
    Menu.Timer=SFalse
    ScreenTimer=SFalse
    Connect=False
    Time.Out!=SFalse
    Ring.Count=0
    Pack.Time!=Timeit!
    Pack.Time2!=Timeit!
    VarQ=False
    Call Opening.Screen
    Call Recycle.Modem
    Wait.State!=Timeit!
    Out2=Nul
    Do Until Connect
       ' start modem loop
       If Local.Mode=False Then
          If Time.Elapsed(Wait.State!,1!) Then
             Wait.State!=Timeit!

             ' get line status
             Call Check.Modem(Var)

             ' carrier bit
             If (OutregsX.AX And &H80)=&H80 Then
                Connect=True
             Endif

             ' check ring bit
             If (OutregsX.AX And &H40)=&H40 Then
                If Ring.Count>Max.Ring.Count Then
                   VarQ=False
                   Out2=Nul
                   Time.Out!=SFalse
                   Ring.Count=0
                   Strng="No Carrier"
                   If Rtrim$(ANSIPrefixChar)<>"" Then
                      Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                   Endif
                   Call Modem.Status
                   Call Playwav(1)
                   Call Recycle.Modem
                Endif
             Endif
          Endif
          Call Read.Modem
          If Instr(Out2,"RING") Then
             Ring.Count=Ring.Count+1
             Strng="Ring"+Str$(Ring.Count)
             If Rtrim$(ANSIPrefixChar)<>"" Then
                Strng=ANSIPrefixChar+"FA"+Strng ' green
             Endif
             Call Modem.Status
             Call Playwav(2)
             Time.Out!=Timeit!
             Out2=Nul
             If Instr(Config3(39),"S0=0") Then
                Strng=Config3(40)+Chr$(13) ' send ATA
                Call Send.Modem(Strng)
                Strng="Auto Answer"
                If Rtrim$(ANSIPrefixChar)<>"" Then
                   Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                Endif
                Call Modem.Status
             Endif
          Endif
          If Instr(Out2,"NO CARRIER") Then
             VarQ=False
             Out2=Nul
             Time.Out!=SFalse
             Ring.Count=0
             Strng="No Carrier"
             If Rtrim$(ANSIPrefixChar)<>"" Then
                Strng=ANSIPrefixChar+"FB"+Strng ' cyan
             Endif
             Call Modem.Status
             Call playwav(1)
             Call Recycle.Modem
          Endif
	  If Time.Out! Then
	     If Time.Elapsed(Time.Out!,Csng(Config2(60))) Then
                VarQ=False
                Out2=Nul
                Time.Out!=SFalse
                Ring.Count=0
                Strng="No Carrier"
                If Rtrim$(ANSIPrefixChar)<>"" Then
                   Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                Endif
                Call Modem.Status
                Call playwav(1)
                Call Recycle.Modem
	     Endif
	  Endif
       Endif
       If Time.Elapsed(Pack.Time2!,Pack.Timer!) Then
          If Len(MidnightX$) Then
             t1$=Format$(Now,"hh:mm")
             If t1$ = MidnightX$ Then
                Gosub Set.Usage.File
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Specified cold boot. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Specified cold boot."
                Strng3=Nul
                Call Write.Logfile(False)
                ' cold boot
                Call Terminate.Program(2)
                End 0
             Endif
          Endif
          Pack.Time2!=Timeit!
          Close #TempFile1
          FileName=Usage.FileName
          Open FileName For Random Shared As #TempFile1 Len=26
          Field #TempFile1,10 As D$,8 As T$,8 As X$
          Get #TempFile1,3
          ' should reboot every midnight
          If D$<>DateS$ Then
             ' check midnight cold reboot
             If Midnight.Reboot=True Then
                Gosub Set.Usage.File
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Midnight cold boot. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Midnight cold boot."
                Strng3=Nul
                Call Write.Logfile(False)
                ' cold boot
                Call Terminate.Program(2)
                End 0
             Endif
             ' check midnight warm reboot
             If Midnight.Reboot=-2 Then
                Gosub Set.Usage.File
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Midnight warm boot. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Midnight warm boot."
                Strng3=Nul
                Call Write.Logfile(False)
                ' warm boot
                Call Terminate.Program(1)
                End 0
             Endif
          Endif
       Endif
       If Rtrim$(NodeX)=Nul Then
          If Time.Elapsed(Pack.Time!,Pack.Timer!) Then
             Pack.Time!=Timeit!
             If Debug.Pack=False Then
                Close #TempFile1
                FileName=Usage.FileName
                Open FileName For Random Shared As #TempFile1 Len=26
                Field #TempFile1,10 As D$,8 As T$,8 As X$
                Get #TempFile1,3
                ' should pack every midnight
                If D$<>DateS$ Then
                   Gosub DndPack
                Endif
             Endif
             ' pack at specified date/time intervals
             If Debug.Pack2 Then
                Filename=Dnd.Path+"dndpack.dat"
                Close #TempFile1
                If Dir$(Filename)<>"" Then
                   Open Filename For Input As #TempFile1
                   Do While Eof(TempFile1)=0
                      Line Input #TempFile1, Var$
                      Var$=Ltrim$(Rtrim$(Var$))
                      If Left$(Var$,1)=";" Then
                         Eat$=Nul
                      Else
                         If Len(Var$)=5 Then ' hh:mm
                            ' minutes past midnight
                            t1$ = Format$(Now, "hh:mm")
                            If Var$ = t1$ Then
                               Gosub DndPack
                               Exit Do
                            Endif
                         Else
                            If Len(Var$)=16 Then ' mm-dd-yyyy hh:mm
                               VarQ1$=Left$(Var$,10) ' date
                               VarQ2$=Mid$(Var$,12) ' time
                               If ValidDate(VarQ1$) Then
                                  d1$=Format$(Now,"mm-dd-yyyy")
                                  t1$=Format$(Now,"hh:mm")
                                  If d1$=VarQ1$ And t1$=VarQ2$ Then
                                     Gosub DndPack
                                     Exit Do
                                  Endif
                               Endif
                            Else
                               ' mm-dd-yyyy to mm-dd-yyyy hh:mm
                               If Len(Var$)=30 Then
                                  Var$=Lcase$(Var$)
                                  If Mid$(Var$,11,4)=" to " Then
                                     StartDate$=Left$(Var$,10)
                                     EndDate$=Mid$(Var$,15,10)
                                     VarQ2$=Mid$(Var$,26,5)
                                     d1$=Format$(Now,"mm-dd-yyyy")
                                     If ValidDate(StartDate$) Then
                                        If ValidDate(EndDate$) Then
                                           If ValidDate(d1$) Then
                                              S1#=DateValue(StartDate$)
                                              S2#=DateValue(EndDate$)
                                              S3#=DateValue(d1$) ' today
                                              ' compare date range.
                                              If S3#>=S1# And S3#<=S2# Then
                                                 t1$=Format$(Now,"hh:mm")
                                                 If t1$=VarQ2$ Then
                                                    Gosub DndPack
                                                    Exit Do
                                                 Endif
                                              Endif
                                           Endif
                                        Endif
                                     Endif
                                  Endif
                               Endif
                            Endif
                         Endif
                      Endif
                   Loop
                Endif
             Endif
          Endif
       Endif
       If Time.Elapsed(Time.Temp!,1!) Then
          Call Display.Time
          VarX2=Node+1
          Call Read.Message.Record(MessWorkFile1,VarX2)
          If MessWorkRecord1.ActiveNode=False Then
             If MessWorkRecord1.SuspendNode=False Then
                Call Zero.Node(0)
                Call Clear.Screen
                Out2="Now aborting the Dndbbs adventure system."
                Out3="Reason: Inactive node. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Inactive node."
                Strng3=Nul
                Call Write.Logfile(False)
                Call Terminate.Program(0)
                End 0
             Endif
          Endif
          Call Read.Message.Record(MessWorkFile1,VarX2)
          If MessWorkRecord1.SuspendNode=True Then ' suspend mode on
             MessWorkRecord1.ActiveNode=False
             Call Write.Message.Record(MessWorkFile1,VarX2)
             Call Close.Files
             Call Close.Temp
             Close #MessWorkFile3
             Close #MessWorkFile4
             Close #MessWorkFile5
             Close #MessWorkFile6
             Strng="Suspend"
             If Rtrim$(ANSIPrefixChar)<>"" Then
                Strng=ANSIPrefixChar+"FB"+Strng ' cyan
             Endif
	     Call Modem.Status
          Endif
          If MessWorkRecord1.SuspendNode=1 Then ' suspend mode off
             MessWorkRecord1.ActiveNode=True
             MessWorkRecord1.SuspendNode=False
             Call Write.Message.Record(MessWorkFile1,VarX2)
             Call Open.Files
             Call Open.Session.Files
	     If Local.Mode Then
                Strng="Waiting"
	     Else
		Strng="Call Waiting"
	     Endif
	     Call Modem.Status
          Endif
          Time.Temp!=Timeit!
	  If Blank.Menu=False Then
             Menu.Timer=Menu.Timer+1!
             VarX=False
             If Menu.Timer>=Display.Menu.Timer! Then
                VarX=True
             Else
                If Config2(47)>False Then
                   If Menu.Timer>=Config2(47) Then
                      VarX=True
                   Endif
                Endif
             Endif
             If VarX Then
                Menu.Timer=SFalse
                Blank.Menu=True
                Call ScreenANSI(4,33,0)
                Call ScreenANSI(4,44,30)
                Call Display.Field
                Selection=1
             Endif
          Endif
          If Blank.Screen=False Then
             ScreenTimer=ScreenTimer+1!
             If ScreenTimer>Config2(47) Then
                ScreenTimer=SFalse
                If Config2(47)>False Then
		   Call Clear.Screen
                   Ansi.Blank=False
		   Blank.Menu=True
		   Blank.Screen=True
                   Keyboard.Timer!=Timeit!
		   Keyboard.Count=10
		   Keyboard.Flag=False
		   Shift.State=False
		   Selection=1
		Endif
	     Endif
          Endif
       Endif
       If Blank.Screen Then
          If Time.Elapsed(Keyboard.Timer!,1!) Then
             Keyboard.Timer!=Timeit!
	     If Keyboard.Count=False Then
		If Keyboard.Flag<22 Then
		   Keyboard.Flag=Keyboard.Flag+1
		   If Int(Keyboard.Flag/2)=Keyboard.Flag/2 Then
		      Key.State=False
		   Else
		      Key.State=112
		   Endif
                   Gosub ShiftKey
                   If Ansi.Blank<>True Then
                      Ansi.Blank=4
                      Var$=Mid$(Str$(Ansi.Blank),2)
                      Call Shell.Program("ANSI.EXE",Var$)
                      Locate ,,0
                      Ansi.Blank=True
                   Endif
                Else
                   If Keyboard.Flag=22 Then
                      Keyboard.Flag=23
                      Call Clear.Screen
                      Locate ,,0
                   Endif
		Endif
	     Endif
             If Keyboard.Count>False Then
		Select Case Shift.State
		Case 0
                   Key.State=False
		Case 1
		   Key.State=32
		Case 2
		   Key.State=64
		Case 3
		   Key.State=96
		Case 4
		   Key.State=16
		Case 5
		   Key.State=48
		Case 6
		   Key.State=80
		Case 7
		   Key.State=112
		End Select
                Gosub ShiftKey
		Shift.State=Shift.State+1
		If Shift.State=8 Then
		   Shift.State=False
		   Keyboard.Count=Keyboard.Count-1
		   If Keyboard.Count=False Then
		      Keyboard.Flag=False
		   Endif
                Endif
                Var$=Mid$(Str$(Ansi.Blank),2)
                Call Shell.Program("ANSI.EXE",Var$)
                Locate ,,0
                Ansi.Blank=Ansi.Blank+1
                If Ansi.Blank>4 Then
                   Ansi.Blank=1
                Endif
	     Endif
	  Endif
       Endif
       TempX=False
       Call Read.Keyboard(TempX$)
       If TempX$=Nul Then
          DEF SEG = &H40
          ShiftFlag = PEEK(&H17)
          DEF SEG
          RightShift = ShiftFlag AND 1
          LeftShift = ShiftFlag AND 2
          CtrlShift = ShiftFlag AND 4
          AltShift = ShiftFlag AND 8
          If RightShift Or LeftShift Or CtrlShift Or AltShift Then
             TempX$ = Chr$(0) + Chr$(0)
          Endif
       Endif
       If Mouse.Present Then
          Call MouseDriver
          If Mouse.Button2 Then
             TempX$=Chr$(27)
          Endif
          If Mouse.Button Then
             Call MouseSelect(1)
          Else
             If Mouse.Row Or Mouse.Column Then
                Call MouseSelect(2)
             Endif
          Endif
       Endif
       If Len(TempX$)=1 Then
          TempX$=Ucase$(TempX$)
       Endif
       If Len(TempX$) Then
	  If Len(TempX$)=2 Then
	     TempX=Asc(Right$(TempX$,1))
	  Endif
          If Blank.Screen Then
             Cls
             Call Passwrd3(Var,True)
             If Var=False Then
                Cls
                If Ansi.Blank>0 Then
                   Call Shell.Program("ANSI.EXE","-1")
                Endif
                Locate ,,0
                Goto End.Loop
             Endif
	     If Local.Mode Then
                Strng="Waiting"
	     Else
		Strng="Call Waiting"
	     Endif
	     Call Modem.Status
             TempX$=Nul
             TempX=False
	  Endif
          Menu.Timer=SFalse
          ScreenTimer=SFalse
	  If Blank.Menu Then
             TempX$=Nul
             TempX=False
	     Next.Field=1
	     Call Show.Field
          Endif
          Call Menu.Select
          If TempX$=Chr$(13) Then
             If Local.Mode=False Then ' bring modem offhook
                Select Case Selection
                Case 2, 3, 4, 5, 8, 9, 13, 14, 15, 16, 32
                   Strng=Config3(41)+Chr$(13)
                   Call Send.Modem(Strng)
		   Strng="Off Hook"
                   If Rtrim$(ANSIPrefixChar)<>"" Then
                      Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                   Endif
		   Call Modem.Status
                End Select
	     Endif
             Select Case Selection
             Case 1
                If Local.Mode=False Then
                   Ring.Count=0
                   Time.Out!=Timeit!
                   Out2=Nul
                   Strng=Config3(40)+Chr$(13)
                   Call Send.Modem(Strng)
                   Strng="Auto Answer"
                   If Rtrim$(ANSIPrefixChar)<>"" Then
                      Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                   Endif
                   Call Modem.Status
                Endif
             Case 2
		Call Clear.Screen
                Locate Max.Row-1,1,1
                Print "Type Exit to return.."
                Print
		Close
                Var$=Curdir$
		Shell
                Chdrive Var$
                Chdir Var$
                Call Read.Config(False)
		Exit Do
             Case 3
		Call Clear.Screen
                Print "Enter DOS command: ";
                Line Input Var$
		Close #TempFile1
		Open DOS.Exit For Output Shared As #TempFile1
		Print #TempFile1,Var$
		Print #TempFile1,"PAUSE"
		Print #TempFile1,"EXIT"
		Close #TempFile1
		Close
                Var$=Curdir$
		Shell DOS.Exit
                Chdrive Var$
                Chdir Var$
                Call Read.Config(False)
		Exit Do
             Case 4
                If Mouse.Present Then
                   Call Mouse.Function(2,0)
                Endif
                TempC=False
                TempD=False
		Call Chain.Program("EDIT.EXE",True,False)
                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit Do
             Case 5
		Graphics.Off=False
		Local.Mode=True
		Lost.Carrier=False
		Recycle=False
                Timeon=Timeit!
		Time.Left=3600!
		Two.Minutes.Left=False
                If Mouse.Present Then
                   Call Mouse.Function(2,0)
                Endif
                Call Playwav(3)
		Exit Do
             Case 6
                If Local.Mode=False Then
                   Connect=False
                   Ring.Count=0
                   Time.Out!=SFalse
                   VarQ=False
                   Call playwav(1)
                   Call Recycle.Modem
                Endif
             Case 7
                If Local.Mode=False Then
                   Ring.Count=0
                   Time.Out!=Timeit!
                   Out2=Nul
                   Strng=Config3(66)+Chr$(13)
                   Call Send.Modem(Strng)
                   Strng="Originate Call"
                   If Rtrim$(ANSIPrefixChar)<>"" Then
                      Strng=ANSIPrefixChar+"FB"+Strng ' cyan
                   Endif
                   Call Modem.Status
                Endif
             Case 8
                Call Playwav(8)
		Call Chain.Program("DNDCNFG.EXE",True,False)
                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit Do
             Case 9
                Call Playwav(8)
		Call Chain.Program("DNDEDIT.EXE",True,False)
                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit DO
             Case 10
		Lost.Carrier=False
                Security.Guard=True
                Call Zero.Node(0)
                Call Clear.Screen
                Mouse.Present=False
                Call Playwav(3)
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Terminate program selected "
                If Rtrim$(NodeX)=Nul Then
                   Out3 = Out3 + "(Node -). "
                Else
                   Out3 = Out3 + "(Node "+NodeX+"). "
                Endif
                Out3=Out3+Fclock$
                Strng1="Terminated program."
                Strng2=Nul : Strng3=Nul
                Call Write.Logfile(False)
                Call Terminate.Program(0)
                End 0
             Case 31 ' F11
		Lost.Carrier=False
                Security.Guard=True
                Call Zero.Node(0)
                Call Clear.Screen
                Mouse.Present=False
                Call Playwav(3)
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Warm boot selected. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Warm boot."
                Strng3=Nul
                Call Write.Logfile(False)
                Close #TempFile1
                ' warm boot
                Call Terminate.Program(1)
                End 0
             Case 32 ' F12
		Lost.Carrier=False
                Security.Guard=True
                Call Zero.Node(0)
                Call Clear.Screen
                Mouse.Present=False
                Call Playwav(3)
                Out2="Now exiting the Dndbbs Adventure System.."
                Out3="Reason: Cold boot selected. "+Fclock$
                Strng1="Terminated program."
                Strng2="Reason: Cold boot."
                Strng3=Nul
                Call Write.Logfile(False)
                Close #TempFile1
                ' cold boot
                Call Terminate.Program(2)
                End 0
             Case 33 ' Alt-F11
                Call Playwav(8)
                TempX$="-1"
                Call Chain.Program("DNDSIC.EXE",True,True)
                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit DO
             Case 34 ' Alt-F12
                Call Playwav(8)
                TempX$="-1"
                Call Chain.Program("CMD155.EXE",True,True)
                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit DO
             Case 11 ' Alt-X
                ' allow any node to pack
                Gosub Dndpack2

                ' reset current node
                Call Restore.Active

                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=True
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit Do
             Case 22 ' Alt-0
                ' call dos screen saver
                Call Clear.Screen
                Call Sleep.Second2(3!) ' wait so Alt- does not stick
                Locate ,,0

                ' reset all screen saver variables
                Ansi.Blank=True
                Blank.Menu=False
                Blank.Screen=True
                Keyboard.Timer!=Timeit!
                Keyboard.Count=0
                Keyboard.Flag=23
                Shift.State=False
                Selection=1
             Case 12 ' Alt-Y
                ' call windows screen saver
                If Selection=12 Then
                   Filename=DND.Path+"scrnsave.exe"
                   Call Shell.Program("SCRNSAVE.EXE","")
                Endif

                ' call dos screen saver
                Call Clear.Screen
                Call Sleep.Second2(3!) ' wait so Alt- does not stick
                Locate ,,0

                ' reset all screen saver variables
                Ansi.Blank=True
                Blank.Menu=False
                Blank.Screen=True
                Keyboard.Timer!=Timeit!
                Keyboard.Count=0
                Keyboard.Flag=23
                Shift.State=False
                Selection=1
             ' Alt-1 to 9
             Case 13 To 21
                Call Zero.Node(0)
                Var2$="/N:"+NodeX
                Call Clear.Screen
                Select Case Selection
                Case 13
                   Var$ = "CMD008.EXE" ' Bank
                Case 14
                   Var$ = "CMD023.EXE" ' Casino
                Case 15
                   Var$ = "CMD086.EXE" ' Mail
                Case 16
                   Var$ = "CMD126.EXE" ' Team
                Case 17
                   Var$ = "CMD190.EXE" ' |Password
                Case 18
                   Var$ = "CMD201.EXE" ' HexCalc
                Case 19
                   Var$ = "CMD203.EXE" ' |Toggle
                Case 20
                   Var$ = "CMD208.EXE" ' |Reboot
                Case 21
                   Var$ = "CMD037.EXE" ' Read.Dayfile
                End Select
                Call Shell.Program(Var$,Var2$)
                Call Zero.Node(-1)

                ' reset opening screen properties
                TempX$=Nul
                TempX=False
                Blank.Screen=False
                Connect=False
                Ring.Count=0
                Time.Out!=SFalse
                VarQ=False
                Exit Do
	     End Select
	  Endif
       Endif
       VarX2=Node+1
       Call Read.Message.Record(MessWorkFile1,VarX2)
       If MessWorkRecord1.SuspendNode Then
          Connect=False
       Endif
       Call Release.Time(1)
End.Loop:
    Loop
    If Local.Mode=False Then
       If Connect Then
          Modem.Return="CONNECT"+Str$(Modem.Baud)
          VarQ=False
          Time.Temp!=Timeit!
          Do
             If Time.Elapsed(Time.Temp!,6!) Then
                Exit Do
             Endif
             Call Read.Modem
             Out2=Ucase$(Out2)
             For Temp1=1 To MaxModemBauds
                Strng=Rtrim$(Modem.String(Temp1))
                If Len(Strng) Then
                   If Instr(Out2,Strng) Then
                      Modem.Return=Strng
                      VarQ=Temp1
                      Exit Do
                   Endif
                Endif
             Next
             If Instr(Out2,"CONNECT"+Chr$(13)+Chr$(10)) Then
                Out2="CONNECT 300"
             Endif
             If Instr(Out2,"CONNECT FAST") Then
                Out2="CONNECT 19200"
             Endif
          Loop
          If VarQ Then
             If Modem.Allow(VarQ)=False Then
                Strng2=Rtrim$(Modem.String(VarQ))
                Var=Instr(Strng2," ")
                If Var Then
                   Strng2=Mid$(Strng2,Var+1)
                Endif
                Strng="Sorry, "+Strng2+" baud access not allowed!"+Chr$(13)
                Call Send.Modem(Strng)
                Connect=False
             Endif
          Endif
       Endif
       If Connect Then
          Call Playwav(3)
	  Recycle=False
          Strng="Connect"+Str$(Modem.Baud)
	  Call Modem.Status
          Call Init.Fossil.Port
          Var=Instr(Modem.Return," ")
          If Var Then
             Modem.Return=Mid$(Modem.Return,Var+1)
          Endif
          Strng1="Modem to modem= "+Modem.Return
          Strng2="Computer to modem="+Str$(Modem.Baud)
          Strng3="Ring count:"+Str$(Ring.Count)
          Call Write.Logfile(False)
       Endif
    Endif
 Loop
 Call Clear.Screen
 Exit Sub
ShiftKey:
 If Bypass.Screen=False Then
    If Config2(106) Then
       Def Seg=False
       Poke &H0417,Key.State
       Def Seg
    Endif
 Endif
 Return
Quit.Door:
 ' display exit message
 Call Pre.Clock(Var$)
 Strng="Dndbbs online at "+Var$
 Print Strng
 Color 15,0
 Strng1="DOOR Mode: Door node "
 If Rtrim$(Door.Node)=Nul Then
    Strng1=Strng1+"-"
 Else
    Strng1=Strng1+Rtrim$(Door.Node)
 Endif
 If Port=-1 Then
    Strng1=Strng1+": Port -: "
 Else
    Strng1=Strng1+": Port"+Str$(Port)+": "
 Endif
 Strng1=Strng1+OutZ
 Color 14,0
 Print Strng1
 ' store log entry
 Strng2=Nul:Strng3=Nul
 Call Write.Logfile(False)
 ' exit program
 Call Zero.Node(0)
 Call Exit.To.DOS
 Color 7,0
 End 0
DndPack:
 If Only.No.Pack Then
    VarQ=0
    For VarX=False To MaxNodes
       Call Read.Message.Record(MessWorkFile1,VarX+1)
       Strng=Rtrim$(MessWorkRecord1.UserName)
       Call Valid.Name(Strng)
       If TempA Then
          If Only.No.Pack=-1 Then
             Return
          Endif
          VarQ=VarQ+1
       Endif
    Next
    If Only.No.Pack>0 Then
       If VarQ>=Only.No.Pack Then
          Return
       Endif
    Endif
 Endif
Dndpack2:
 VarX2=Node+1
 Call Read.Message.Record(MessWorkFile1,VarX2)
 If MessWorkRecord1.SuspendNode=False Then
    ' reset modem to off hook
    If Local.Mode=False Then
       Strng=Config3(41)+Chr$(13)
       Call Send.Modem(Strng)
       Strng="Off Hook"
       If Rtrim$(ANSIPrefixChar)<>"" Then
          Strng=ANSIPrefixChar+"FB"+Strng ' cyan
       Endif
       Call Modem.Status
    Endif
    ' reset active node
    MessWorkRecord1.ActiveNode=False
    Call Write.Message.Record(MessWorkFile1,VarX2)
    Call Clear.Screen
    V$="DNDPACK.EXE"
    X$="/N:"+NodeX
    Call Shell.Program(V$,X$)
    Call Sleep.Second2(3!)
    Gosub Set.Usage.File
    ' reset active node
    Call Read.Message.Record(MessWorkFile1,VarX2)
    MessWorkRecord1.ActiveNode=True
    MessWorkRecord1.SuspendNode=False
    Call Write.Message.Record(MessWorkFile1,VarX2)
    ' reset opening screen properties
    TempX$=Nul
    TempX=False
    If Blank.Screen=False Then
       Call Opening.Screen
       Connect=False
       Ring.Count=0
       Time.Out!=SFalse
       VarQ=False
       If Local.Mode Then
          Strng="Waiting"
       Else
          Strng="Call Waiting"
       Endif
       Call Modem.Status
       Return
    Endif
    Call Clear.Screen
    Locate ,,0
    If Keyboard.Count>False Then
       If Keyboard.Flag<22 Then
          Call Shell.Program("ANSI.EXE","-1")
          If Ansi.Blank>0 Then
             Var$=Mid$(Str$(Ansi.Blank),2)
             Call Shell.Program("ANSI.EXE",Var$)
          Endif
          Locate ,,0
       Endif
    Endif
 Endif
 Return
Set.Usage.File:
 ' check usage file
 Close #TempFile1
 FileName=Usage.FileName
 Open FileName For Random Shared As #TempFile1 Len=26
 Field #TempFile1,10 As D$,8 As T$,8 As X$
 Get #TempFile1,3
 Lset D$=DateS$
 Time1$=Format$(Now,"hh:mm:ss")
 Lset T$=Time1$
 Put #TempFile1,3
 Close #TempFile1
 Return
Get.Config5:
 Debug.Pack2=0
 Max.Ring.Count=10
 Display.Menu.Timer!=30!
 Only.No.Pack=0
 Pack.Timer!=60!
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[MODEM]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,Var-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             Select Case Lcase$(Var2$)
             Case "only.no.pack"
                Select Case Ucase$(Var3$)
                Case "-1","ON","TRUE"
                   Only.No.Pack=-1
                Case Else
                   If Int(Val(Var3$)+.5)>=1 And Int(Val(Var3$)+.5)<=127 Then
                      Only.No.Pack=Int(Val(Var3$)+.5)
                   Endif
                End Select
             Case "also.allow.data.pack"
                Select Case Ucase$(Var3$)
                Case "-1","ON","TRUE"
                   Debug.Pack2=-1
                End Select
             Case "max.ring.count"
                Select Case Int(Val(Var3$)+.5)
                Case 10 To 1024
                   Max.Ring.Count=Int(Val(Var3$)+.5)
                End Select
             Case "display.menu.timer"
                Select Case Int(Val(Var3$)+.5)
                Case 1 To 1024
                   Display.Menu.Timer!=Int(Val(Var3$)+.5)
                End Select
             Case "pack.timer"
                Select Case Int(Val(Var3$)+.5)
                Case 1 To 60
                   Pack.Timer!=Int(Val(Var3$)+.5)
                End Select
             End Select
          Endif
       Loop
    Endif
 Loop
 Return
ErrResume4:
 Exit Sub
ErrTrap4:
 Resume ErrResume4
End Sub

Sub Write.Logfile(Var)
 On Local Error Goto ErrTrap4a
 If Var=False Then
    If Config2(45)=0 Then
       Exit Sub
    Endif
 Endif
 Close #TempFile1
 FileName$=DND.Path+"modem"+NodeX+".log"
 Open FileName$ For Append As #TempFile1
 If Rtrim$(NodeX)=Nul Then
    Strng="-"
 Else
    Strng=NodeX
 Endif
 Strng="Node "+Strng+", "
 If Port<0 Then
    Strng=Strng+"Port -"
 Else
    Strng=Strng+"Port"+Str$(Port)
 Endif
 Print #TempFile1,Fclock$+", "+Strng
 Print #TempFile1,Strng1
 If Len(Strng2) Then
    Print #TempFile1,Strng2
 Endif
 If Len(Strng3) Then
    Print #TempFile1,Strng3
 Endif
 Print #TempFile1,""
 Exit Sub
ErrResume4a:
 Print "Error"+Str$(Err)+" writing "+Filename$
 Exit Sub
ErrTrap4a:
 Resume ErrResume4a
End Sub

Sub Menu.Select
 On Local Error Goto ErrTrap5
 Dim Menu.Array(1 To 10) As Integer
 Dim Menu.Array2(1 To 26) As Integer
 Gosub Get.Config1
 Next.Field=False
 Select Case TempX$
 Case Chr$(0) ' ctrl-break
    Exit Sub
 Case Chr$(9) ' tab
    TempX=77
 Case Chr$(27) ' escape
    TempX=10
 Case Chr$(13) ' enter
    If Left$(Menu1(Selection),1)="*" Then
       If Selection<>10 Then
          VarZ=-1
          TempX$=Nul
       Endif
    Endif
 Case Else
    ' fixed 07-19-2020
    If Len(TempX$)=1 Then
       VarX$=Nul
       For VarX=1 To 10
          VarZ$=Menu1(VarX)
          VarZ$=Rtrim$(VarZ$)
          If VarZ$="" Then
             VarX$=VarX$+"*"
          Else
             VarX$=VarX$+Left$(VarZ$,1)
          Endif
       Next
       VarX$=Ucase$(VarX$)
       TempX=Instr(VarX$,TempX$)
    Endif
 End Select
 Select Case TempX
 Case 1 To 10 ' menu key
    If Left$(Menu1(TempX),1)<>"*" Or TempX=10 Then
       Next.Field=TempX
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 Case 59 To 68 ' F1 - F10
    If Left$(Menu1(TempX-58),1)<>"*" Or TempX=68 Then
       Next.Field=TempX-58
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 Case 84 To 93 ' Shift-F1 To Shift-F10
    If Left$(Menu1(TempX-83),1)<>"*" Or TempX=93 Then
       Next.Field=TempX-83
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 Case 94 To 103 ' Ctrl-F1 To Ctrl-F10
    If Left$(Menu1(TempX-93),1)<>"*" Or TempX=103 Then
       Next.Field=TempX-93
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 Case 104 To 113 ' Alt-F1 To Alt-F10
    If Left$(Menu1(TempX-103),1)<>"*" Or TempX=113 Then
       Next.Field=TempX-103
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 Case 72, 141, 152 ' up/ctrl-up/alt-up
    If Selection>1 Then
       Next.Field=Selection-1
    Endif
 Case 80, 145, 160 ' down/ctrl-dn/alt-dn
    If Selection<10 Then
       Next.Field=Selection+1
    Endif
 Case 15, 75, 155, 115 ' shift-tab/left/alt-left/ctrl-left
    If Selection>5 Then
       Next.Field=Selection-5
    Endif
 Case 77, 157, 116 ' right/alt-right/ctrl-right
    If Selection<6 Then
       Next.Field=Selection+5
    Endif
 Case 71, 119 ' home/ctrl-home
    If Selection<>1 Then
       Next.Field=1
    Endif
 Case 79, 117, 147 ' end/ctrl-end/ctrl-delete
    If Selection<>10 Then
       Next.Field=10
    Endif
 Case 73, 132, 152 ' pageup/ctrl-pageup/alt-up
    If Selection<6 And Selection<>1 Then
       Next.Field=1
    Endif
    If Selection>5 And Selection<>6 Then
       Next.Field=6
    Endif
 Case 81, 118, 160 ' pagedown/ctrl-pagedn/alt-down
    If Selection<6 And Selection<>5 Then
       Next.Field=5
    Endif
    If Selection>5 And Selection<>10 Then
       Next.Field=10
    Endif

 ' Shell to Cmd008, Cmd023, Cmd086, Cmd126,
 '   Cmd190, Cmd201, Cmd203, Cmd208, Cmd037.
 '  Alt-0 to clear screen
 Case 120 To 129 ' Alt-1 To Alt-9, Alt-0
    If Menu.Array(TempX-119)=0 Then
       Selection=TempX-107
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif

 ' scancodes for Alt-A to Alt-Z:
 '  30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50
 '  49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44 

 ' Alt-R = refresh opening screen
 Case 19
    If Menu.Array2(18)=0 Then
       Call Restore.Active
       Goto Show.Toggle
    Endif

 ' Alt-G = enable/disable fossil
 Case 34
    If Menu.Array2(7)=0 Then
       If Fossil.Active Then
          Fossil.Active=0
       Else
          Fossil.Active=-1
          Fossil.Version=2
       Endif
    Endif

 ' Alt-E = toggle fossil
 Case 18
    If Menu.Array2(5)=0 Then
       If Fossil.Active Then
          If Fossil.Version=1 Then
             Fossil.Version=2
          Else
             If Fossil.Version=2 Then
                Fossil.Version=1
             Endif
          Endif
       Endif
    Endif

 ' Alt-A = base address
 Case 30
    If Menu.Array2(1)=0 Then
       'VarQ=Max.Row
       VarQ=25
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Call ScreenANSI(2,VarQ,3)
       Locate VarQ,3
       Line Input; "Base address(hex):"; Var$
       Var$=Ucase$(Var$)
       VarX=ValidHex(Var$)
       If VarX Then
          Temp$="&H"+Var$
          If Int(Val(Temp$)+.5)>=1 And Int(Val(Temp$)+.5)<=MaxInt Then
             Base.Address=Int(Val(Temp$)+.5)
             UserConfigRecord.UserConfig2=Base.Address
             Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+114)
          Endif
       Endif
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Goto Show.Toggle
    Endif

 ' Alt-B = baud rate
 Case 48
    If Menu.Array2(2)=0 Then
       'VarQ=Max.Row
       VarQ=25
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Call ScreenANSI(2,VarQ,3)
       Locate VarQ,3
       Line Input; "Baud rate:"; Var$
       Temp!=Csng(Int(Val(Var$))+.5)
       If Temp!>0! Then
          Call Set.Baud(Temp!)
          UserConfigRecord.UserConfig2=Cint(Modem.Baud/100!)
          Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+64)
       Endif
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Goto Show.Toggle
    Endif

 ' Alt-C = comm port
 Case 46 
    If Menu.Array2(3)=0 Then
       'VarQ=Max.Row
       VarQ=25
       Call ScreenANSI(4,37,0)
       Call ScreenANSI(4,44,31)
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Call ScreenANSI(2,VarQ,3)
       Locate VarQ,3
       Line Input; "Comm port(0-64):"; Var$
       Temp=Int(Val(Var$)+.5)
       If Temp>=0 And Temp<=64 Then
          Port=Temp-1
          Port.Override=Temp
          UserConfigRecord.UserConfig2=Port.Override
          Call Write.Message.Record(MessWorkFile9,MaxConfigArray1+46)
       Endif
       Call ScreenANSI(2,VarQ,3)
       Var$=Space$(77)
       Call Put.Screen(Var$)
       Goto Show.Toggle
    Endif

 ' Alt-D  disk log
 Case 32
    If Menu.Array2(4)=0 Then
       Call Flag.Toggles(7)
       Goto Show.Toggle
    Endif
    VarZ=-1
 ' Alt-P  printer log
 Case 25
    If Menu.Array2(16)=0 Then
       Call Flag.Toggles(8)
       Goto Show.Toggle
    Endif
    VarZ=-1
 ' Alt-W  toggle display
 Case 17
    If Menu.Array2(23)=0 Then
       Select Case Bypass.Splash
       Case 0
          Bypass.Splash=1
       Case 1
          Bypass.Splash=2
       Case 2
          Bypass.Splash=3
       Case 3
          Bypass.Splash=4
       Case 4
          Bypass.Splash=0
       End Select
       Goto Show.Toggle
    Endif
    VarZ=-1
 ' Alt-X  shell to dndpack
 Case 45
    If Menu.Array2(24)=0 Then
       ' node pack
       Selection=11
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 ' Alt-Y  windows screen saver function call
 Case 21
    If Menu.Array2(25)=0 Then
       Selection=12
       TempX$=Chr$(13)
    Else
       VarZ=-1
    Endif
 ' Alt-Z toggle debug
 Case 44
    If Menu.Array2(26)=0 Then
       If Debug.Mode=-1 Then
          Debug.Mode=-2
       Else
          If Debug.Mode=-2 Then
             Debug.Mode=0
          Else
             Debug.Mode=-1
          Endif
       Endif
       Goto Show.Toggle
    Endif
    VarZ=-1
 ' Alt-F toggle local.mode
 Case 33
    If Menu.Array2(6)=0 Then
       Local.Mode=Not Local.Mode
       Goto Show.Toggle
    Endif

   ' F11=133, shift-F11=135, ctrl-F11=137, alt-F11=139
   ' F12=134, shift-F12=136, ctrl-F12=138, alt-F12=140
 Case 133, 135, 137 ' F11
    Selection=31
    TempX$=Chr$(13)
    Exit Sub
 Case 134, 136, 138 ' F12
    Selection=32
    TempX$=Chr$(13)
    Exit Sub
 Case 139 ' Alt-F11
    Selection=33
    TempX$=Chr$(13)
    Exit Sub
 Case 140 ' Alt-F12
    Selection=34
    TempX$=Chr$(13)
    Exit Sub
 Case 241 To 250 ' mouse
    Next.Field=TempX-240
 End Select
 If Next.Field Then
    Call Show.Field
 Endif
 If VarZ Then
    Call playwav(1)
 Endif
 Exit Sub
Show.Toggle:
 Blank.Screen=True
 If Local.Mode Then
    Strng="Waiting"
 Else
    Strng="Call Waiting"
 Endif
 If Mouse.Present Then
    Call Mouse.Function(2,0)
 Endif
 Call Modem.Status
 If Mouse.Present Then
    Call Mouse.Function(1,0)
 Endif
 Exit Sub
Get.Config1:
 VarX=0
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[DNDBBS]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Exit Do
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Exit Do
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Lcase$(Ltrim$(Rtrim$(Left$(Var$,Var-1))))
             Var3$=Lcase$(Ltrim$(Rtrim$(Mid$(Var$,Var+1))))
             If Left$(Var2$,4)="alt-" Then
                VarQ$=Mid$(Var2$,5)
                If Len(VarQ$)=1 Then
                   Select Case Var3$
                   Case "0", "false", "off"
                      Select Case VarQ$
                      Case "1" To "9" ' Alt-1 to Alt-9
                         VarQ=Int(Val(VarQ$)+.5)
                         Menu.Array(VarQ)=-1
                      Case "0" ' Alt-0
                         Menu.Array(10)=-1
                      Case "a" To "z" ' Alt-A to Alt-Z
                         VarQ=Asc(VarQ$)-96
                         Menu.Array2(VarQ)=-1
                      End Select
                   End Select
                Endif
             Endif
          Endif
       Loop
    Endif
 Loop
 Return
ErrResume5:
 Exit Sub
ErrTrap5:
 Resume ErrResume5
End Sub

' display blank field
Sub Show.Field
 On Local Error Goto ErrTrap6
 Call Display.Field
 Blank.Menu=False
 Selection=Next.Field
 Call Mouse.Function(2,0)
 Var1=Menu2(Selection,1)
 Var2=Menu2(Selection,2)+3
 If Selection=10 Then
    Var2=Var2+1
 Endif
 Call ScreenANSI(2,Var1,Var2)
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,45,95)
 Strng=Left$(Menu1(Selection),1)
 Call Scrn(Strng)
 Call ScreenANSI(4,33,0)
 Call ScreenANSI(4,45,94)
 Strng=Mid$(Menu1(Selection),2)
 Strng=Rtrim$(Strng)
 VarZ=Local.Mode
 Local.Mode=True
 Call Convert.String ' convert macros
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 Local.Mode=VarZ
 Call Scrn(Strng)
 Call Mouse.Function(1,0)
ErrResume6:
 Exit Sub
ErrTrap6:
 Resume ErrResume6
End Sub

' display hilighted field
Sub Display.Field
 On Local Error Goto ErrTrap7
 Var1=Menu2(Selection,1)
 Var2=Menu2(Selection,2)+3
 If Selection=10 Then
    Var2=Var2+1
 Endif
 Call Mouse.Function(2,0)
 Call ScreenANSI(2,Var1,Var2)
 Call ScreenANSI(4,37,0)
 Call ScreenANSI(4,44,31)
 Strng=Left$(Menu1(Selection),1)
 Call Scrn(Strng)
 Call ScreenANSI(4,33,0)
 Call ScreenANSI(4,44,30)
 Strng=Mid$(Menu1(Selection),2)
 Strng=Rtrim$(Strng)
 VarZ=Local.Mode
 Local.Mode=True
 Call Convert.String ' convert macros
 Call Convert.ANSI(False,VarQ,VarR) ' convert prefixes
 Local.Mode=VarZ
 Call Scrn(Strng)
 Call Mouse.Function(1,0)
ErrResume7:
 Exit Sub
ErrTrap7:
 Resume ErrResume7
End Sub

Sub Recycle.Modem
 On Local Error Goto ErrTrap8
 Call Restore.Active
 ' test modem offline/turned off
 If Local.Mode=False Then
    Call Check.Modem(Var)
    If Var Then
       Blank.Screen=True
       Local.Mode=True
       Strng="Waiting"
       Call Modem.Status
       Exit Sub
    Endif
 Endif
 ' check local, display & exit
 If Local.Mode Then
    Strng="Waiting"
    Call Modem.Status
    Exit Sub
 Endif
 ' reset cycle counter
 Var1=False
 ' start modem recycle loop
 TempX$=""
 Do
    ' check escape pressed
    TempX$=Inkey$
    If TempX$=Chr$(27) Then
       Call Playwav(3)
       Strng="Recycle Halt"
       If Rtrim$(ANSIPrefixChar)<>"" Then
          Strng=ANSIPrefixChar+"FC"+Strng ' red
       Endif
       Exit Do
    Endif
    ' display recycle
    Strng="Recycle"
    Call Modem.Status
    ' lower/raise dtr
    TempX$=""
    Call Recycle.DTR
    ' activate port
    Call Init.Fossil.Port
    ' check locked baud
    If Config2(65)=False Then
       Call Set.Driver ' set baud n,8,1
    Endif
    ' check escape during recycle.dtr
    If TempX$=Chr$(27) Then
       Call Playwav(3)
       Strng="Recycle Halt"
       If Rtrim$(ANSIPrefixChar)<>"" Then
          Strng=ANSIPrefixChar+"FC"+Strng ' red
       Endif
       Exit Do
    Endif
    ' recycle modem
    Out2=Nul
    Strng=Config3(42)+Chr$(13) ' ATZ
    Call Send.Modem(Strng)
    Display.Timer!=Timeit!
    Time.Temp!=Timeit!
    Do
       ' check escape pressed
       TempX$=Inkey$
       If TempX$=Chr$(27) Then
          Call Playwav(3)
          Strng="Recycle Halt"
          If Rtrim$(ANSIPrefixChar)<>"" Then
             Strng=ANSIPrefixChar+"FC"+Strng ' red
          Endif
          Goto RecycleEnd
       Endif
       Call Read.Modem
       If Instr(Out2,"OK") Then
          Exit Do
       Endif
       If Time.Elapsed(Time.Temp!,Csng(Config2(84))) Then
	  Exit Do
       Endif
       If Time.Elapsed(Display.Timer!,1!) Then
          Display.Timer!=Timeit!
          Call Display.Time
       Endif
    Loop
    If Instr(Out2,"OK") Then
       Strng="Reset OK"
       VarX=True
    Else
       If Instr(Out2,"ERROR") Then
          Strng="Reset Error"
          VarX=False
       Else
          Strng="Reset Fail"
          VarX=False
       Endif
    Endif
    If Rtrim$(ANSIPrefixChar)<>"" Then
       Strng=ANSIPrefixChar+"FA"+Strng ' green
    Endif
    Call Modem.Status
    Call Sleep.Second2(1!)
    Out2=Nul
    Strng=Config3(39)+Chr$(13) ' init string
    Call Send.Modem(Strng)
    Display.Timer!=Timeit!
    Time.Temp!=Timeit!
    Do
       ' check escape pressed
       TempX$=Inkey$
       If TempX$=Chr$(27) Then
          Call Playwav(3)
          Strng="Recycle Halt"
          If Rtrim$(ANSIPrefixChar)<>"" Then
             Strng=ANSIPrefixChar+"FC"+Strng ' red
          Endif
          Goto RecycleEnd
       Endif
       Call Read.Modem
       If Instr(Out2,"OK") Then
          Exit Do
       Endif
       If Time.Elapsed(Time.Temp!,Csng(Config2(84))) Then
	  Exit Do
       Endif
       If Time.Elapsed(Display.Timer!,1!) Then
          Display.Timer!=Timeit!
          Call Display.Time
       Endif
    Loop
    If Instr(Out2,"OK") Then
       Strng="Init OK"
       VarY=True
    Else
       If Instr(Out2,"ERROR") Then
          Strng="Init Error"
          VarY=False
       Else
          Strng="Init Fail"
          VarY=False
       Endif
    Endif
    If Rtrim$(ANSIPrefixChar)<>"" Then
       Strng=ANSIPrefixChar+"FA"+Strng ' green
    Endif
    Call Modem.Status
    Call Sleep.Second2(1!)
    Out2=Nul
    ' test both strings sent & received OK
    If VarX And VarY Then
       Strng="Call Waiting"
       Exit Do
    Endif
    ' check counters
    If Config2(49)>False Then
       Var1=Var1+1
       If Var1>Config2(49) Then
          Call Playwav(3)
	  Strng="Recycle Fail"
          If Rtrim$(ANSIPrefixChar)<>"" Then
             Strng=ANSIPrefixChar+"FC"+Strng ' red
          Endif
	  Exit Do
       Endif
    Endif
 Loop
RecycleEnd:
 Call Modem.Status
ErrResume8:
 Exit Sub
ErrTrap8:
 Resume ErrResume8
End Sub

Sub Shell.Program(Var$,Var2$)
 On Local Error Goto ErrTrap9
 If Var2$="43" Or Var2$="50" Then
    Close #TempFile1
    Open DND.Path+"NODE"+NodeX+".DEF" For Output As #TempFile1
    Print #TempFile1,Config3(11) ' c:\dnddat\
    Print #TempFile1,Config3(51) ' dndusage
    Print #TempFile1,Config3(15) ' .dat
    Print #TempFile1,Var2$ ' screen size
    Close #TempFile1
 Endif

 VarX=0
 Select Case Var$
 Case "ANSI.EXE", "COPYSCRN.EXE", "SCRNSAVE.EXE", "TOPTEN.EXE"
    VarX=-1
 End Select
 ' get dndpath with filename
 Filename=DND.Path+Var$
 ' get ramdrive with filename
 If Left$(Var$,3)="CMD" Then
    Var1=Val(Mid$(Var$,4,3)) ' command number
    Call Get.Config2x(Option1$,Var1)
    Filename=Option1$+Var$
 Endif
 If Dir$(Filename)<>Nul Then
    Call Close.Nodes
    Call Close.Files
    Call Close.Temp
    Var3$=Curdir$
    If Var2$="43" Or Var2$="50" Then
       Filename=Filename+" /"+NodeX
    Else
       If Var2$<>Nul Then
          Filename=Filename+" "+Var2$
       Else
          If Var$="SCRNSAVE.EXE" Then
             If Windows.Detected Then
                Filename="START "+Var$
             Endif
          Else
             Filename=Var$
          Endif
       Endif
    Endif

    If VarX=0 Then
       Color 15,0
       Cls
       Locate Max.Row-1,1,1
       Print
       Print "Shelling: "+Filename
       Print "  (error here then use Shroom)"
    Endif

    Shell Filename

    If VarX=0 Then
       Call Sleep.Second2(3!)
    Endif

    Chdrive Var3$
    Chdir Var3$
    Call Open.Shell.Files
    Call Open.Temp.Files
    Call Open.Node.Files
    Call Open.Session.Files
    Exit Sub
 Endif
ErrResume9:
 If VarX Then
    Exit Sub
 Endif
 Var2=Err
 If Var2=0 Then
    Var2=53 ' file not found
 Endif
 Call Error.Message(Var2,VarX$)
 Cls
 Color 15,0
 Print "Dndbbs menu error:"
 Color 14,0
 Print
 Print "Error:"+VarX$+" shelling to "+Filename+". Reinstall Dndbbs."
 Call More.Prompt
 Exit Sub
ErrTrap9:
 Resume ErrResume9
End Sub

Sub Init.Drivers
 On Local Error Goto ErrTrap10
 Call Read.Rows(Max.Row)
 ' check ansi
 Call Plex.Function(26)
 If (OutregsX.AX And &HFF)=&HFF Then
    Local.ANSI.Color=True
 Else
    Local.ANSI.Color=False
 Endif
 ' check config switch
 If Disable.ANSI=True Then
    Local.ANSI.Color=False
 Endif
 If Disable.ANSI=-2 Then
    Local.ANSI.Color=True
 Endif
 ' check avatar
 Local.Avatar.Color=False
 Call Plex.Function(27)
 If (OutregsX.AX And &HFF)=&HFF Then
    If (OutregsX.DX And &HFF)=&H16 Then
       Local.Avatar.Color=True
    Endif
 Endif
 ' check config switch
 If Disable.Avatar=True Then
    Local.Avatar.Color=False
 Endif
 If Disable.Avatar=-2 Then
    Local.Avatar.Color=True
 Endif
 ' check mouse
 Locate Max.Row-1,1,1
 Mouse.Present=False
 Call Mouse.Function(0,0)
 ' mouse block cursor is 8x8 pixels..
 If OutregsX.AX=&HFFFF Then
    Mouse.Present=True
    M.Row=Max.Row*8-8 ' row is 0 based.
    Call Mouse.Function2(7,0,0,632) ' 80 columns
    Select Case Max.Row
    Case 25
       Call Mouse.Function2(8,0,0,M.Row) ' 25 rows
    Case 43
       Call Mouse.Function2(8,0,0,M.Row) ' 43 rows
    Case 50
       Call Mouse.Function2(8,0,0,M.Row) ' 50 rows
    Case Else
       Call Mouse.Function2(8,0,0,192) ' 25 rows
    End Select
 Endif
 ' check os
 Call StdinInt(48,0)
 ' store dos version
 DOS.Major=OutregsX.AX And &HFF
 DOS.Minor=(OutregsX.AX And &HFF00)/256
 ' check os/2
 If DOS.Major=10 Or DOS.Major=20 Then
    OS2.Detected=True
 Else
    OS2.Detected=False
 Endif
 ' check windows
 Windows.Detected = False
 Call Plex.Function(22)
 If OutregsX.BX>0 Then
    Windows.Detected = True
    ' store windows version
    Win.Minor=OutregsX.BX And &HFF
    Win.Major=(OutregsX.BX And &HFF00)/256
 Endif
 ' check share
 Call Plex.Function(16)
 If (OutregsX.AX And &HFF)=&HFF Then
    Share.Installed=True
 Else
    Share.Installed=False
 Endif
 ' check config switch
 If Disable.Share=True Then
    Share.Installed=False
 Endif
 If Disable.Share=-2 Then
    Share.Installed=True
 Endif
 ' init screen
 Call ScreenANSI(1,37,15)
 Call ScreenANSI(4,37,15)
 Call ScreenANSI(2,Max.Row-1,1)
ErrResume10:
 Exit Sub
ErrTrap10:
 Resume ErrResume10
End Sub

Sub System.Type
 On Local Error Goto ErrTrap11
 Strng=Nul
 If Windows.Detected Then
    If Win.Major=4 Then
       If Win.Minor>10 Then
          Strng="Win ME"
       Else
          If Win.Minor=10 Then
             Strng="Win 98"
          Else
             If Win.Minor=3 Then
                Strng="Win 95B"
             Else
                Strng="Win 95"
             Endif
          Endif
       Endif
    Else
       If Win.Major>4 Then
          Strng="WinX" ' OS past 98
       Else
          If Win.Major=0 And Win.Minor=0 Then
             Win.Major=3 : Win.Minor=1
          Endif
          Strng="Win"+Str$(Win.Major)+"."+Ltrim$(Str$(Win.Minor))
       Endif
    Endif
    Exit Sub
 Endif
 Select Case DOS.Major
 Case 10
    Strng="OS/2 v1.0"
 Case 20
    Strng="OS/2 v2.0"
    Select Case DOS.Minor
    Case 30
       Strng="OS/2 v3.0"
    Case 40
       Strng="OS/2 v4.0"
    End Select
 Case 30
    Strng="Mac OSX"
 Case 40
    Strng="Linux"
 Case 50
    Strng="SunOS"
 Case Else
    Strng="DOS"+Str$(DOS.Major)+"."+Ltrim$(Str$(DOS.Minor))
 End Select
 If Strng=Nul Then
    Strng="DOS 7.10"
 Endif
ErrResume11:
 Exit Sub
ErrTrap11:
 Strng="DOS 7.10"
 Resume ErrResume11
End Sub

Sub Get.Free.Memory
 On Local Error Goto ErrTrap12
 Strng=Nul
 If OS2.Detected Then ' has no freespace
    Strng="256.00 KB"
 Else
    Temp#=Fre(-1)+Fre(a$) ' free far+temp
    Call Make.Format(Temp#)
 Endif
 If Strng=Nul Then
    Strng="256.00 KB"
 Endif
ErrResume12:
 Exit Sub
ErrTrap12:
 Strng="256.00 KB"
 Resume ErrResume12
End Sub

Sub Make.Format(Var#)
 On Local Error Goto ErrTrap13
 Var2#=Var#
 If Var2#=0 Then
    Strng="0.00 B"
    Exit Sub
 Endif
 If Var2#<0# Then
    Sign=-1
    Var2#=Abs(Var2#)
 Endif
 TempA=False
 Do
    If Var2#<1024# Then
       Exit Do
    Endif
    Var2#=Var2#/1024#
    TempA=TempA+1
    If TempA=8 Then
       Exit Do
    Endif
 Loop
 Strng=Nul
 If TempA>=1 And TempA<=8 Then
    Strng=Mid$("KMGTPEZY",TempA,1)
 Endif
 Strng=Format$(Var2#,"#,##0.00;;")+" "+Strng+"B"
 If Sign Then
    Strng="-"+Strng
 Endif
ErrResume13:
 Exit Sub
ErrTrap13:
 Strng="0.00 B"
 Resume ErrResume13
End Sub

Sub Read.Rows(Var)
 On Local Error Goto Error.Trap62x
 Temp1=50
 Locate 50,1,0
 Var=50
 Exit Sub
Next.Trap1:
 Temp1=43
 Locate 43,1,0
 Var=43
 Exit Sub
Next.Trap2:
 Var=25
Error.Resume62x:
 Exit Sub
Error.Trap62x:
 If Temp1=50 Then
    Resume Next.Trap1
 Endif
 If Temp1=43 Then
    Resume Next.Trap2
 Endif
 Resume Error.Resume62x
End Sub

Sub Amount(Var#,Var$)
 If Instr(Str$(Var#),"D") Then
    Var$=Str$(Var#)
 Else
    Var$=" "+Form$(Var#)
 Endif
End Sub

Sub Amount2(Var#,Var$)
 VarX$=Ltrim$(Str$(Var#)) ' 1.111D308
 V=Instr(VarX$,"D")
 If V Then
    If Mid$(VarX$,2,1)="." Then
       VarX$=Left$(VarX$,1)+Mid$(VarX$,V)
    Endif
    Var$=" "+VarX$
 Else
    Var$=" "+Form$(Var#)
 Endif
End Sub
