REM File: Dndsic2 for Dndbbs Version v5.0a Release r2.0 Tweak t6.0a

' get standard include declarations
REM $INCLUDE: 'DNDSIC.INC'

SUB Get.Graphics
 SELECT CASE ScreenMode
 CASE 1
    Plane.Bits = 2
    Planes = 1
 CASE 2, 11
    Plane.Bits = 1
    Planes = 1
 CASE 7, 8, 9, 12
    Plane.Bits = 1
    Planes = 4
 CASE 10
    Plane.Bits = 1
    Planes = 2
 CASE 13
    Plane.Bits = 8
    Planes = 1
 CASE ELSE
    ERROR 49
 END SELECT
 Xcoor1 = False
 Ycoor1 = False
 Xcoor2 = False
 Ycoor2 = False
 Out2 = MID$(Out2, 4)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Xcoor1 = CINT(Temp3#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp3#)
    Ycoor1 = CINT(Temp3#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       Xcoor2 = CINT(Temp3#)
       IF Strng = "," THEN
	  CALL Get.Token
	  CALL Parse1(Temp3#)
	  Ycoor2 = CINT(Temp3#)
	  Array.Size = 4 + INT(((Xcoor2 - Xcoor1 + 1) * (Plane.Bits) + 7) / 8) * Planes * ((Ycoor2 - Ycoor1) + 1)
	  Elements = INT((Array.Size + 1) / 2)
	  REDIM Graphics.Screen(1 TO Elements) AS INTEGER
	  GET (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), Graphics.Screen
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 49
END SUB

SUB Put.Graphics
 Xcoor1 = False
 Ycoor1 = False
 Out2 = MID$(Out2, 4)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Xcoor1 = CINT(Temp3#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp3#)
    Ycoor1 = CINT(Temp3#)
    IF Strng = "," THEN
       Temp1$ = MID$(Out2, Token.Index)
       Temp1$ = STRIM$(Temp1$)
       Temp1$ = UCASE$(Temp1$)
       IF LEFT$(Temp1$, 4) = "PSET" THEN
	  PUT (Xcoor1, Ycoor1), Graphics.Screen, PSET
          EXIT SUB
       ELSE
	  IF LEFT$(Temp1$, 6) = "PRESET" THEN
	     PUT (Xcoor1, Ycoor1), Graphics.Screen, PRESET
             EXIT SUB
	  ELSE
	     IF LEFT$(Temp1$, 3) = "AND" THEN
		PUT (Xcoor1, Ycoor1), Graphics.Screen, AND
                EXIT SUB
	     ELSE
		IF LEFT$(Temp1$, 2) = "OR" THEN
		   PUT (Xcoor1, Ycoor1), Graphics.Screen, OR
                   EXIT SUB
		ELSE
		   IF LEFT$(Temp1$, 3) = "XOR" THEN
		      PUT (Xcoor1, Ycoor1), Graphics.Screen, XOR
                      EXIT SUB
		   END IF
		END IF
	     END IF
	  END IF
       END IF
    ELSE
       PUT (Xcoor1, Ycoor1), Graphics.Screen
       EXIT SUB
    END IF
 END IF
 ERROR 49
END SUB

SUB Window.Screen(Var)
 IF Var = 1 THEN
    Window.Type = True
    Out2 = MID$(Out2, 14)
    Out2 = STRIM$(Out2)
 ELSE
    Window.Type = False
    Out2 = MID$(Out2, 7)
    Out2 = STRIM$(Out2)
 END IF
 Xcoor1 = False
 Xcoor2 = False
 Ycoor1 = False
 Ycoor2 = False
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Xcoor1 = CINT(Temp3#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp3#)
    Ycoor1 = CINT(Temp3#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       Xcoor2 = CINT(Temp3#)
       IF Strng = "," THEN
	  CALL Get.Token
	  CALL Parse1(Temp3#)
	  Ycoor2 = CINT(Temp3#)
	  IF Window.Type THEN
	     WINDOW SCREEN (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2)
	  ELSE
	     WINDOW (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2)
	  END IF
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 78
END SUB

SUB View.Screen(Var)
 Allow.Extra = True
 IF Var = 1 THEN
    View.Type = True
    Out2 = MID$(Out2, 12)
    Out2 = STRIM$(Out2)
 ELSE
    View.Type = False
    Out2 = MID$(Out2, 5)
    Out2 = STRIM$(Out2)
 END IF
 Xcoor1 = False
 Xcoor2 = False
 Ycoor1 = False
 Ycoor2 = False
 Color.Code = False
 Color.Set = False
 Border.Color = False
 Border.Set = False
 Last.Token = False
 Out3 = Nul
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Xcoor1 = CINT(Temp3#)
 IF Strng = "," THEN
    Last.Token = False
    Out3 = Nul
    CALL Get.Token
    CALL Parse1(Temp3#)
    Ycoor1 = CINT(Temp3#)
    IF Strng = "," THEN
       Last.Token = False
       Out3 = Nul
       CALL Get.Token
       CALL Parse1(Temp3#)
       Xcoor2 = CINT(Temp3#)
       IF Strng = "," THEN
	  Last.Token = False
	  Out3 = Nul
	  CALL Get.Token
	  CALL Parse1(Temp3#)
	  Ycoor2 = CINT(Temp3#)
	  IF Strng = "," THEN
	     Last.Token = False
	     Out3 = Nul
	     CALL Get.Token
	     CALL Parse1(Temp3#)
	     Color.Code = CINT(Temp3#)
	     IF Last.Token THEN
		Color.Set = True
	     END IF
	     IF Strng = "," THEN
		Last.Token = False
		Out3 = Nul
		CALL Get.Token
		CALL Parse1(Temp3#)
		Border.Color = CINT(Temp3#)
		IF Last.Token THEN
		   Border.Set = True
		END IF
	     END IF
	  END IF
	  IF View.Type THEN
	     IF Color.Set AND Border.Set THEN
		VIEW SCREEN (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), Color.Code, Border.Color
	     ELSE
		IF Color.Set THEN
		   VIEW SCREEN (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), Color.Code, Border.Color
		ELSE
		   IF Border.Set THEN
		      VIEW SCREEN (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), , Border.Color
		   ELSE
		      VIEW SCREEN (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2)
		   END IF
		END IF
	     END IF
	  ELSE
	     IF Color.Set AND Border.Set THEN
		VIEW (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), Color.Code, Border.Color
	     ELSE
		IF Color.Set THEN
		   VIEW (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), Color.Code
		ELSE
		   IF Border.Set THEN
		      VIEW (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2), , Border.Color
		   ELSE
		      VIEW (Xcoor1, Ycoor1)-(Xcoor2, Ycoor2)
		   END IF
		END IF
	     END IF
	  END IF
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 77
END SUB

SUB Paint.Area
 Allow.Extra = True
 Xcoor1 = False
 Xcoor1.Set = False
 Ycoor1 = False
 Ycoor1.Set = False
 Paint.Type = False
 Paint.Style$ = Nul
 Border.Color = False
 Border.Set = False
 BackGround.Style$ = Nul
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Last.Token = False
 Out3 = Nul
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Xcoor1 = CINT(Temp3#)
 IF Last.Token THEN
    Xcoor1.Set = True
 END IF
 IF Strng = "," THEN
    Last.Token = False
    Out3 = Nul
    CALL Get.Token
    CALL Parse1(Temp3#)
    Ycoor1 = CINT(Temp3#)
    IF Last.Token THEN
       Ycoor1.Set = True
    END IF
    IF Strng = "," THEN
       Last.Token = False
       Out3 = Nul
       CALL Get.Token
       CALL Parse1(Temp3#)
       IF Last.Token = False THEN
	  Paint.Type = True
	  Paint.Style$ = Out3
       ELSE
	  Paint.Type = CINT(Temp3#)
       END IF
       IF Strng = "," THEN
	  Last.Token = False
	  Out3 = Nul
	  CALL Get.Token
	  CALL Parse1(Temp3#)
	  Border.Color = CINT(Temp3#)
	  IF Last.Token THEN
	     Border.Set = True
	  END IF
	  IF Strng = "," THEN
	     Last.Token = False
	     Out3 = Nul
	     CALL Get.Token
	     CALL Parse1(Temp3#)
	     BackGround.Style$ = Out3
	  END IF
       END IF
    END IF
    IF Xcoor1.Set AND Ycoor1.Set THEN
       IF Paint.Type = True THEN
	  IF Border.Set THEN
	     IF LEN(BackGround.Style$) THEN
		PAINT (Xcoor1, Ycoor1), Paint.Style$, Border.Color, BackGround.Style$
	     ELSE
		PAINT (Xcoor1, Ycoor1), Paint.Style$, Border.Color
	     END IF
	  ELSE
	     IF LEN(BackGround.Style$) THEN
		PAINT (Xcoor1, Ycoor1), Paint.Style$, , BackGround.Style$
	     ELSE
		PAINT (Xcoor1, Ycoor1), Paint.Style$
	     END IF
	  END IF
       ELSE
	  IF Paint.Type > False THEN
	     IF Border.Set THEN
		IF LEN(BackGround.Style$) THEN
		   ERROR 48
                   EXIT SUB
		ELSE
		   PAINT (Xcoor1, Ycoor1), Paint.Type, Border.Color
		END IF
	     ELSE
		IF LEN(BackGround.Style$) THEN
		   ERROR 48
                   EXIT SUB
		ELSE
		   PAINT (Xcoor1, Ycoor1), Paint.Type
		END IF
	     END IF
	  ELSE
	     IF Border.Set THEN
		IF LEN(BackGround.Style$) THEN
		   ERROR 48
                   EXIT SUB
		ELSE
		   PAINT (Xcoor1, Ycoor1), , Border.Color
		END IF
	     ELSE
		IF LEN(BackGround.Style$) THEN
		   ERROR 48
                   EXIT SUB
		ELSE
		   PAINT (Xcoor1, Ycoor1)
		END IF
	     END IF
	  END IF
       END IF
       EXIT SUB
    END IF
 END IF
 ERROR 48
END SUB

SUB Print.Expression
 If Left$(Ucase$(Out2), 11) = "PRINT USING" Then
    Out2 = "UPRINT " + MID$(Out2, 12)
    Call Uprint.Expression
    Exit Sub
 Endif
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Temp# = False
 Token.Index = 1

 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    LineFeed = True
    Out2 = Out2 + Quote$ + Quote$ + ";"
 ELSE
    LineFeed = False
    Out2 = Out2 + ";" + Quote$ + Quote$
 END IF

 PrinterLF = 1
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 DO
    Last.Token = False
    CALL Get.Token
    CALL Parse1(Temp3#)
    SELECT CASE Strng
    CASE ","
       SELECT CASE Last.Token
       CASE -1
          Strng3 = STR$(Temp3#)
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Carriage.Input = False
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE 0
          Strng3 = Out3
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Carriage.Input = False
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE ELSE
          Strng3 = Nul
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Carriage.Input = False
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       END SELECT
    CASE ";"
       SELECT CASE Last.Token
       CASE -1
          Strng3 = STR$(Temp3#) + " "
          Carriage.Input = True
          Call IO.O
       CASE 0
          Strng3 = Out3
          Carriage.Input = True
          Call IO.O
       CASE ELSE
          Strng3 = Nul
          Carriage.Input = True
          Call IO.O
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
 IF LineFeed = False THEN
    IF Break = 0 THEN
       CALL Line.Return
       If Csrlin<Max.Row-1 Then
          Call Scrn(Chr$(10))
       Endif
    END IF
 END IF
 PrinterLF = False
 Printing = False
END SUB

SUB Print.Expression.File
 Allow.Extra = True
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Out2 = MID$(Out2, Token.Index)
    Out2 = STRIM$(Out2)
    Last.Token = False
    Out3 = Nul
    Out4 = Nul
    Temp# = False
    Token.Index = 1

    IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
       LineFeed = True
       Out2 = Out2 + Quote$ + Quote$ + ";"
    ELSE
       LineFeed = False
       Out2 = Out2 + ";" + Quote$ + Quote$
    END IF

    DO
       Last.Token = False
       CALL Get.Token
       CALL Parse1(Temp3#)
       SELECT CASE Strng
       CASE ","
          SELECT CASE Last.Token
          CASE -1
             If Program.Running=0 Then
                IF AccountLimit (LEN(STR$(Temp3))) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, STR$(Temp3#),
          CASE 0
             If Program.Running=0 Then
                IF AccountLimit (LEN(Out3)) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, Out3,
          CASE ELSE
             If Program.Running=0 Then
                IF AccountLimit (LEN(Out3)) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, "",
          END SELECT
       CASE ";"
          SELECT CASE Last.Token
          CASE -1
             If Program.Running=0 Then
                IF AccountLimit (LEN(STR$(Temp3))+1) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, STR$(Temp3#);" ";
          CASE 0
             If Program.Running=0 Then
                IF AccountLimit (LEN(Out3)) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, Out3;
          CASE ELSE
             If Program.Running=0 Then
                IF AccountLimit (LEN(Out3)) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, "";
          END SELECT
       CASE ELSE
          IF LEN(Strng) THEN
             Strng = "<extra token>"
             ERROR 92
          END IF
          EXIT DO
       END SELECT
       IF Token.Index > LEN(Out2) THEN
          EXIT DO
       END IF
    LOOP
    IF LineFeed = False THEN
       If Program.Running=0 Then
          IF AccountLimit (2#) THEN
             ERROR 140
             EXIT SUB
          END IF
       Endif
       PRINT #File.Num%, CHR$(13); CHR$(10);
    END IF
    EXIT SUB
 END IF
 ERROR 32
END SUB

SUB Dprint.Expression
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Temp# = False
 Token.Index = 1
 Out2 = XTRIM$(Out2, True)
 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    LineFeed = True
 ELSE
    LineFeed = False
    Out2 = Out2 + ";"
 END IF

 PrinterLF = 1
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 DO
    Last.Token = False
    CALL Get.Token
    CALL Parse1(Temp3#)
    SELECT CASE Strng
    CASE ","
       SELECT CASE Last.Token
       CASE -1
          Strng = "<string error>"
          Error 92
       CASE 0
          Strng3 = FORMAT$(NOW, Out3)
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE ELSE
          Strng3 = Nul
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       END SELECT
    CASE ";"
       SELECT CASE Last.Token
       CASE -1
          Strng = "<string error>"
          Error 92
       CASE 0
          Strng3 = FORMAT$(NOW, Out3)+" "
          Carriage.Input = True
          Call IO.O
       CASE ELSE
          Strng3 = Nul
          Carriage.Input = True
          Call IO.O
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
 IF LineFeed = False THEN
    IF Break = 0 THEN
       CALL Line.Return
       If Csrlin<Max.Row-1 Then
          Call Scrn(Chr$(10))
       Endif
    END IF
 END IF
 PrinterLF = False
 Printing = False
END SUB

SUB Lprint.Expression
 If PrinterSelected = False Then
    ERROR 147
    EXIT SUB
 Endif
 If Left$(Ucase$(Out2), 12) = "LPRINT USING" Then
    Call Lprint.Using
    Exit Sub
 Endif
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Temp# = False
 Token.Index = 1

 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    LineFeed = True
    Out2 = Out2 + Quote$ + Quote$ + ";"
 ELSE
    LineFeed = False
    Out2 = Out2 + ";" + Quote$ + Quote$
 END IF

 PrinterLF = True
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 DO
    Last.Token = False
    CALL Get.Token
    CALL Parse1(Temp3#)
    SELECT CASE Strng
    CASE ","
       SELECT CASE Last.Token
       CASE -1
	  LPRINT STR$(Temp3#),
       CASE 0
	  LPRINT Out3,
       CASE ELSE
          LPRINT "",
       END SELECT
    CASE ";"
       SELECT CASE Last.Token
       CASE -1
          LPRINT STR$(Temp3#);" ";
       CASE 0
	  LPRINT Out3;
       CASE ELSE
          LPRINT "";
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
 IF LineFeed = False THEN
    LPRINT
 END IF
 PrinterLF = False
 Printing = False
 LineFeed = False
END SUB

' special lprint function requires:
'    Lprint Using (<x>,"x"), (<x>,"x"), ...
SUB Lprint.Using
AllowExtra = True
Printing = True
Last.Token = False
Out3 = Nul
Out4 = Nul
Temp# = False
Token.Index = 1
Out2 = MID$(Out2, 13)
Out2 = STRIM$(Out2)
Out2 = XTRIM$(Out2, True)

IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
   LineFeed = True
ELSE
   LineFeed = False
END IF

PrinterLF = True
DO
   Last.Token = False
   CALL Get.Token
   IF Strng <> "(" THEN
      Strng = "<missing left token>"
      ERROR 92
      EXIT SUB
   END IF
   CALL Get.Token
   CALL Parse1(Temp3#)
   IF ErrorValue THEN
      ErrorValue = 0
      EXIT SUB
   END IF
   Number# = Temp3#
   CALL Get.Token
   CALL Parse1(Temp3#)
   IF ErrorValue THEN
      ErrorValue = 0
      EXIT SUB
   END IF
   Strng = MID$(Out2, Token.Index, 1)
   Token.Index = Token.Index + 1
   SELECT CASE Strng
      CASE ","
         SELECT CASE Last.Token
            CASE -1
               Strng = "<string error>"
               ERROR 92
            CASE 0
               LPRINT USING Out3; Number#;
               LPRINT , " ";
            CASE ELSE
               LPRINT "",
         END SELECT
      CASE ";"
         SELECT CASE Last.Token
            CASE -1
               Strng = "<string error>"
               ERROR 92
            CASE 0
               LPRINT USING Out3; Number#;
            CASE ELSE
               LPRINT "";
         END SELECT
      CASE ELSE
         IF LEN(Strng) THEN
            Strng = "<extra token>"
            ERROR 92
         END IF
         SELECT CASE Last.Token
            CASE -1
               Strng = "<string error>"
               ERROR 92
            CASE 0
               LPRINT USING Out3; Number#;
            CASE ELSE
               LPRINT "";
         END SELECT
         EXIT DO
   END SELECT
   IF Token.Index > LEN(Out2) THEN
      EXIT DO
   END IF
LOOP
IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
   Out2 = LEFT$(Out2, LEN(Out2) - 1)
END IF
IF RIGHT$(Out2, 1) <> ")" THEN
   Strng = "<missing right token>"
   ERROR 92
   EXIT SUB
END IF
IF LineFeed = False THEN
   LPRINT
END IF
PrinterLF = False
Printing = False
END SUB

SUB Sprint.Expression
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Temp# = False
 Token.Index = 1

 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    LineFeed = True
    Out2 = Out2 + Quote$ + Quote$ + ";"
 ELSE
    LineFeed = False
    Out2 = Out2 + ";" + Quote$ + Quote$
 END IF

 PrinterLF = 1
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 DO
    Last.Token = False
    CALL Get.Token
    CALL Parse1(Temp3#)
    SELECT CASE Strng
    CASE ","
       SELECT CASE Last.Token
       CASE -1 ' number
          Strng3 = Chr$(Temp3#)
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE 0 ' string
          Strng3 = Out3
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE ELSE
          Strng3 = Nul
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       END SELECT
    CASE ";"
       SELECT CASE Last.Token
       CASE -1 ' number
          Strng3 = CHR$(Temp3#)+" "
          Carriage.Input = True
          Call IO.O
       CASE 0 ' string
          Strng3 = Out3
          Carriage.Input = True
          Call IO.O
       CASE ELSE
          Strng3 = Nul
          Carriage.Input = True
          Call IO.O
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
 IF LineFeed = False THEN
    IF Break = 0 THEN
       CALL Line.Return
       If Csrlin<Max.Row-1 Then
          Call Scrn(Chr$(10))
       Endif
    END IF
 END IF
 PrinterLF = False
 Printing = False
END SUB

SUB Uprint.Expression
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Temp# = False
 Token.Index = 1

 Out2 = XTRIM$(Out2, True)
 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    Out2 = Left$(Out2, Len(Out2) - 1)
    LineFeed = True
 ELSE
    LineFeed = False
 END IF
 Out2 = Out2 + ","

 PrinterLF = 1
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 DO While Lost.Carrier=False
    Last.Token = False
    CALL Get.Token
    CALL Get.Token
    CALL Parse1(Temp3#)
    Number# = Temp3#
    CALL Get.Token
    CALL Parse1(Temp3#)
    Strng = MID$(Out2, Token.Index, 1)
    Token.Index = Token.Index + 1
    SELECT CASE Strng
    CASE ","
       SELECT CASE Last.Token
       CASE -1
          Strng = "<string error>"
          Error 92
       CASE 0
          Strng3 = FORMAT$(Number#, Out3)
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       CASE ELSE
          Strng3 = Nul
          Tmp1 = TabStop - Len(Strng3)
          If Tmp1>=1 Then
             If Pos(0)+Len(Strng3)+Tmp1<ScreenWidth Then
                Strng3 = Strng3 + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Else
                TmpX$ = Strng3
                Strng3 = Nul
                Call IO.O
                Strng3 = TmpX$ + Space$(Tmp1)
                Carriage.Input = True
                Call IO.O
             Endif
          Else
             Carriage.Input = True
             Call IO.O
          Endif
       END SELECT
    CASE ";"
       SELECT CASE Last.Token
       CASE -1
          Strng = "<string error>"
          Error 92
       CASE 0
          Strng3 = FORMAT$(Number#, Out3)+" "
          Carriage.Input = True
          Call IO.O
       CASE ELSE
          Strng3 = Nul
          Carriage.Input = True
          Call IO.O
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
 IF LineFeed = False THEN
    IF Break = 0 THEN
       CALL Line.Return
       If Csrlin<Max.Row-1 Then
          Call Scrn(Chr$(10))
       Endif
    END IF
 END IF
 PrinterLF = False
 Printing = False
END SUB

SUB Line.Input.Expression(Var)
 IF Var = 1 THEN
    Add.Cursor = False
    Temp1$ = MID$(Out2, 12)
 ELSE
    Add.Cursor = True
    Temp1$ = MID$(Out2, 11)
 END IF
 Temp1$ = STRIM$(Temp1$)
 Token.Index = 1
 Out2 = Temp1$
 Last.Token = True
 Quotes = False
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    IF Quotes THEN
       Strng3 = Out3
       Carriage.Input = True
       Call IO.O
       Temp1$ = MID$(Out2, Token.Index)
    END IF
 END IF
 Temp1$ = STRIM$(Temp1$)
 Temp1$ = UCASE$(Temp1$)
 SELECT CASE LEN(Temp1$)
 CASE 1
    IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
       Variable = ASC(Temp1$) - 64
       Strng3 = NUL
       Carriage.Return = True
       Call IO.I
       Temp2$ = Out9
       Variables(Variable) = VAL(Temp2$)
    END IF
 CASE 2
    Temp1$ = LEFT$(Temp1$, 1)
    IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
       Variable = ASC(Temp1$) - 64
       Strng3 = NUL
       Carriage.Return = True
       Call IO.I
       Temp2$ = Out9
       Strngs(Variable) = Temp2$
    END IF
 CASE 3
    IF RIGHT$(Temp1$, 2) = "()" THEN
       Temp1$ = LEFT$(Temp1$, 1)
       IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
	  Variable = ASC(Temp1$) - 64
          Strng3 = NUL
          Carriage.Return = True
          Call IO.I
          Temp2$ = Out9
          FOR Temp3 = 1 TO LEN(Temp2$)
             Arrays(Variable, Temp3) = ASC(MID$(Temp2$, Temp3, 1))
             IF Temp3 >= MaxArrays THEN
		EXIT FOR
	     END IF
	  NEXT
       END IF
    END IF
 CASE ELSE
    Out2 = MID$(Temp1$, 2)
    Temp1$ = LEFT$(Temp1$, 1)
    IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
       Variable = ASC(Temp1$) - 64
       CALL Equate(Temp3#)
       Element = CINT(Temp3#)
       IF Element > False AND Element <= MaxArrays THEN
          Strng3 = NUL
          Carriage.Return = True
          Call IO.I
          Temp2$ = Out9
	  Arrays(Variable, Element) = VAL(Temp2$)
       END IF
    END IF
 END SELECT
 IF Add.Cursor THEN
    Strng3 = Nul
    Call IO.O
 END IF
END SUB

SUB Line.Input.Exp.File
 Out2 = MID$(Out2, 13)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Temp1$ = MID$(Out2, Token.Index)
    Temp1$ = STRIM$(Temp1$)
    Temp1$ = UCASE$(Temp1$)
    SELECT CASE LEN(Temp1$)
    CASE 1
       IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
          Variable = ASC(Temp1$) - 64
          LINE INPUT #File.Num%, Temp2$
          IF RIGHT$(Temp2$, 1) = CHR$(10) THEN
             Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
          END IF
          IF RIGHT$(Temp2$, 1) = CHR$(13) THEN
             Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
          END IF
          Variables(Variable) = VAL(Temp2$)
       END IF
    CASE 2
       IF MID$(Temp1$, 2, 1) = "$" THEN
          Temp1$ = LEFT$(Temp1$, 1)
          IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
             Variable = ASC(Temp1$) - 64
             LINE INPUT #File.Num%, Temp2$
             IF RIGHT$(Temp2$, 1) = CHR$(10) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             IF RIGHT$(Temp2$, 1) = CHR$(13) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             Strngs(Variable) = Temp2$
          END IF
       END IF
    CASE 3
       IF RIGHT$(Temp1$, 2) = "()" THEN
          Temp1$ = LEFT$(Temp1$, 1)
          IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
             Variable = ASC(Temp1$) - 64
             LINE INPUT #File.Num%, Temp2$
             IF RIGHT$(Temp2$, 1) = CHR$(10) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             IF RIGHT$(Temp2$, 1) = CHR$(13) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             FOR Temp = 1 TO LEN(Temp2$)
                Arrays(Variable, Temp) = ASC(MID$(Temp2$, Temp, 1))
                IF Temp >= MaxArrays THEN
                   EXIT FOR
                END IF
             NEXT
          END IF
       END IF
    CASE ELSE
       Out2 = MID$(Temp1$, 2)
       Temp1$ = LEFT$(Temp1$, 1)
       IF Temp1$ >= "A" AND Temp1$ <= "Z" THEN
          Variable = ASC(Temp1$) - 64
          CALL Equate(Temp3#)
          Element = CINT(Temp3#)
          IF Element > False AND Element <= MaxArrays THEN
             LINE INPUT #File.Num%, Temp2$
             IF RIGHT$(Temp2$, 1) = CHR$(10) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             IF RIGHT$(Temp2$, 1) = CHR$(13) THEN
                Temp2$ = LEFT$(Temp2$, LEN(Temp2$) - 1)
             END IF
             Arrays(Variable, Element) = VAL(Temp2$)
          ELSE
             ERROR 9
          END IF
       END IF
    END SELECT
    EXIT SUB
 END IF
 ERROR 36
END SUB

SUB Input.Expression(Var)
 If StdinEnabled Then
    Var$ = Environ$("STDINCHAR")
    If Var$<>"" Then
       VarX$=Chr$(Val(Var$))
       Strng3 = VarX$
       Out3 = VarX$
       Buffer = Nul
       Last.Token = False
    Else
       X$ = Inkey$
       Strng3 = NUL
       Out3 = Nul
       Buffer = Nul
       Last.Token = False
    Endif
    Exit Sub
 Endif
 Allow.Extra = 1
 IF Var = 1 THEN
    Add.Cursor = False
    Temp1$ = MID$(Out2, 7)
 ELSE
    Add.Cursor = True
    Temp1$ = MID$(Out2, 6)
 END IF
 Temp1$ = STRIM$(Temp1$)
 Token.Index = 1
 Out2 = Temp1$
 Last.Token = True
 Quotes = False
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    IF Quotes THEN
       IF Strng = ";" THEN
          Strng3 = Out3
          Carriage.Input = True
          Call IO.O
       ELSE
	  IF Strng = "," THEN
             Strng3 = Out3 + "?"
             Carriage.Input = True
             Call IO.O
	  END IF
       END IF
       Out2 = MID$(Temp1$, Token.Index)
    ELSE
       Out2 = Temp1$
       Strng3 = "?"
       Carriage.Input = True
       Call IO.O
    END IF
 ELSE
    Out2 = Temp1$
    Strng3 = "?"
    Carriage.Input = True
    Call IO.O
 END IF
 Strng3 = NUL
 Carriage.Return = True
 Call IO.I
 IF Break THEN
    EXIT SUB
 END IF
 User.Input$ = Out9
 Stored.Input$ = User.Input$
 Stored.Token.Index = 1
 Stored.Out2$ = STRIM$(UCASE$(Out2))
 DO While Lost.Carrier=False
    Token.Index = Stored.Token.Index
    Out2 = Stored.Out2$
    Last.Token = False
    CALL Get.Token
    Stored.Token.Index = Token.Index
    Stored.Out2$ = Out2
    Temp1$ = STRIM$(Strng)
    IF LEFT$(Temp1$, 1) >= "A" AND LEFT$(Temp1$, 1) <= "Z" THEN
       Variable = ASC(LEFT$(Temp1$, 1)) - 64
       Out2 = Stored.Input$
       Last.Token = False
       Token.Index = 1
       Temp3# = Dfalse
       DO While Lost.Carrier=False
	  CALL Get.Token
          Last.Token.Type = Token
	  IF Token = 1 THEN
	     IF Strng = "," THEN
                Last.Token.Type = Prev.Token.Type
		Out3 = LEFT$(Out2, Token.Index - 2)
		EXIT DO
	     END IF
	  END IF
	  IF Token.Index > LEN(Out2) THEN
	     Out3 = Out2
	     EXIT DO
	  END IF
          Prev.Token.Type = Last.Token.Type
       LOOP
       Temp3# = VAL(Out3)
       IF Stored.Input$ = Nul THEN
          ERROR 136
       END IF
       Stored.Input$ = MID$(Out2, Token.Index)
       Token.Index = Stored.Token.Index
       Out2 = Stored.Out2$
       SELECT CASE LEN(Temp1$)
       CASE 1
	  IF MID$(Out2, Token.Index, 1) = "(" THEN
	     IF MID$(Out2, Token.Index + 1, 1) = ")" THEN
		CALL Get.Token
		CALL Get.Token
		Stored.Token.Index = Token.Index
		Stored.Out2$ = Out2
		FOR Element = 1 TO LEN(Out3)
		   Arrays(Variable, Element) = ASC(MID$(Out3, Element, 1))
                   IF Element >= MaxArrays THEN
		      EXIT FOR
		   END IF
		NEXT
	     ELSE
		CALL Get.Token
		CALL Parse1(Temp4#)
		Stored.Token.Index = Token.Index
		Stored.Out2$ = Out2
		Element = CINT(Temp4#)
                IF Element > False AND Element <= MaxArrays THEN
                   IF Last.Token.Type = 2 THEN
                      Arrays(Variable, Element) = Temp3#
                   ELSE
                      ERROR 135
                   END IF
                ELSE
                   ERROR 9
		END IF
	     END IF
	  ELSE
             IF Last.Token.Type = 2 THEN
                Variables(Variable) = Temp3#
             ELSE
                ERROR 135
             END IF
	  END IF
       CASE 2
	  IF MID$(Temp1$, 2, 1) = "$" THEN
	     Strngs(Variable) = Out3
          ELSE
             ERROR 134
	  END IF
       CASE ELSE
          ERROR 134
       END SELECT
    ELSE
       IF Temp1$ <> "," THEN
          ERROR 134
       END IF
    END IF
    IF Stored.Token.Index > LEN(Stored.Out2$) THEN
       EXIT DO
    END IF
 LOOP
 IF Stored.Input$ <> Nul THEN
    ERROR 137
 END IF
 IF Add.Cursor THEN
    Strng3 = Nul
    Call IO.O
 END IF
END SUB

SUB Input.Expression.File
 Allow.Extra = 1
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Out2 = MID$(Out2, Token.Index)
    Out2 = STRIM$(Out2)
    DO While Lost.Carrier=False
       Last.Token = False
       Token.Index = 1
       CALL Get.Token
       IF Strng = "," THEN
          CALL Get.Token
       END IF
       Temp1$ = STRIM$(Strng)
       Temp1$ = UCASE$(Temp1$)
       IF LEFT$(Temp1$, 1) >= "A" AND LEFT$(Temp1$, 1) <= "Z" THEN
          Variable = ASC(LEFT$(Temp1$, 1)) - 64
          SELECT CASE LEN(Temp1$)
          CASE 1
             IF MID$(Out2, Token.Index, 1) = "(" THEN
                IF MID$(Out2, Token.Index + 1, 1) = ")" THEN
                   INPUT #File.Num%, Out3
                   FOR Element = 1 TO LEN(Out3)
                      Arrays(Variable, Element) = ASC(MID$(Out3, Element, 1))
                      IF Element >= MaxArrays THEN
                         EXIT FOR
                      END IF
                   NEXT
                ELSE
                   CALL Get.Token
                   CALL Parse1(Temp4#)
                   Element = CINT(Temp4#)
                   INPUT #File.Num%, Temp3#
                   IF Element > False AND Element <= MaxArrays THEN
                      Arrays(Variable, Element) = Temp3#
                   ELSE
                      ERROR 9
                   END IF
                END IF
             ELSE
                INPUT #File.Num, Temp3#
                Variables(Variable) = Temp3#
             END IF
          CASE 2
             IF MID$(Temp1$, 2, 1) = "$" THEN
                INPUT #File.Num%, Out3
                IF LEFT$(Out3, 1) = Quote$ THEN
                   Out3 = MID$(Out3, 2)
                END IF
                IF RIGHT$(Out3, 1) = Quote$ THEN
                   Out3 = LEFT$(Out3, LEN(Out3) - 1)
                END IF
                Strngs(Variable) = Out3
             ELSE
                ERROR 134
             END IF
          CASE ELSE
             ERROR 134
          END SELECT
       ELSE
          IF Temp1$ <> "," THEN
             ERROR 134
          END IF
       END IF
       IF Token.Index > LEN(Out2) THEN
          EXIT DO
       END IF
       Out2 = MID$(Out2, Token.Index)
    LOOP
    EXIT SUB
 END IF
 ERROR 34
END SUB

SUB Write.Expression
 Allow.Extra = True
 Printing = True
 Last.Token = False
 Out3 = Nul
 Out4 = Nul
 Token.Index = 1

 IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
    LineFeed = True
    Out2 = LEFT$(Out2, LEN(Out2) - 1)
 ELSE
    LineFeed = False
 END IF
 Out2 = Out2 + ","

 PrinterLF = -2
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 DO
    Last.Token = False
    CALL Get.Token
    CALL Parse1(Temp3#)
    SELECT CASE Strng
    CASE ",", ";"
       SELECT CASE Last.Token
       CASE -1
          Var$ = STRIM$(STR$(Temp3#))
          FOR Var = 1 TO LEN(Var$)
             Strng3 = MID$(Var$, Var, 1)
             Carriage.Input = True
             Call IO.O
          NEXT
       CASE 0
          Var$ = Quote$ + Out3 + Quote$
          FOR Var = 1 TO LEN(Var$)
             Strng3 = MID$(Var$, Var, 1)
             Carriage.Input = True
             Call IO.O
          NEXT
       END SELECT
    CASE ELSE
       IF LEN(Strng) THEN
          Strng = "<extra token>"
          ERROR 92
       END IF
       EXIT DO
    END SELECT
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
    Strng3 = ","
    Carriage.Input = True
    Call IO.O
 LOOP
 IF LineFeed THEN
    Strng3 = ","
    Carriage.Input = True
    Call IO.O
 END IF
 IF LineFeed = False THEN
    IF Break = 0 THEN
       CALL Line.Return
       If Csrlin<Max.Row-1 Then
          Call Scrn(Chr$(10))
       Endif
    END IF
 END IF
 PrinterLF = False
 Printing = False
END SUB

SUB Write.Expression.File
 Allow.Extra = True
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Out2 = MID$(Out2, Token.Index)
    Out2 = STRIM$(Out2)
    Last.Token = False
    Out3 = Nul
    Out4 = Nul
    Token.Index = 1

    IF RIGHT$(Out2, 1) = ";" OR RIGHT$(Out2, 1) = "," THEN
       LineFeed = True
       Out2 = LEFT$(Out2, LEN(Out2) - 1)
    ELSE
       LineFeed = False
    END IF
    Out2 = Out2 + ","

    DO While Lost.Carrier=False
       Last.Token = False
       CALL Get.Token
       CALL Parse1(Temp3#)
       SELECT CASE Strng
       CASE ",", ";"
          SELECT CASE Last.Token
          CASE -1
             If Program.Running=0 Then
                IF AccountLimit (LEN(STRIM$(STR$(Temp3)))) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, STRIM$(STR$(Temp3#));
          CASE 0
             If Program.Running=0 Then
                IF AccountLimit (LEN(Quote$ + Out3 + Quote$)) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PRINT #File.Num%, Quote$ + Out3 + Quote$;
          END SELECT
       CASE ELSE
          IF LEN(Strng) THEN
             Strng = "<extra token>"
             ERROR 92
          END IF
          EXIT DO
       END SELECT
       IF Token.Index > LEN(Out2) THEN
          EXIT DO
       END IF
       PRINT #File.Num%, ",";
    LOOP
    IF LineFeed THEN
       PRINT #File.Num%, ",";
    END IF
    IF LineFeed = False THEN
       PRINT #File.Num%, CHR$(13); CHR$(10);
    END IF
    EXIT SUB
 END IF
 ERROR 31
END SUB

SUB Change.Color
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp4#)
 Foreground = CINT(Temp4#)
 Call Get.ANSI.Color(VarX,VarY,VarQ)
 IF VarX=0 THEN
    ERROR 2
    EXIT SUB
 END IF
 IF Strng = "," THEN
    ' store foreground
    VarZ1=VarX
    VarZ2=VarY
    CALL Get.Token
    CALL Parse1(Temp4#)
    BackGround = CINT(Temp4#)
    Call Get.ANSI.Color2(VarX,VarY)
    IF VarX=0 THEN
       ERROR 2
       EXIT SUB
    END IF
    ' background
    Call Modem.ANSI(5,VarX,VarY)
    Call ScreenANSI(5,VarX,VarY)
    ' foreground
    IF VarQ THEN ' hi-intensity
       Call Modem.ANSI(4,VarZ1,VarZ2)
       Call ScreenANSI(4,VarZ1,VarZ2)
    ELSE
       Call Modem.ANSI(1,VarZ1,VarZ2)
       Call ScreenANSI(1,VarZ1,VarZ2)
    END IF
    EXIT SUB
 END IF
 IF VarQ THEN
    Call Modem.ANSI(4,VarX,VarY)
    Call ScreenANSI(4,VarX,VarY)
 ELSE
    Call Modem.ANSI(1,VarX,VarY)
    Call ScreenANSI(1,VarX,VarY)
 END IF
END SUB

Sub Get.ANSI.Color(VarX,VarY,VarQ)
 VarX=0
 VarY=0
 VarQ=0
 Select Case ForeGround
 Case 0
    VarX=30
    VarY=0
 Case 1
    VarX=34
    VarY=1
 Case 2
    VarX=32
    VarY=2
 Case 3
    VarX=36
    VarY=3
 Case 4
    VarX=31
    VarY=4
 Case 5
    VarX=35
    VarY=5
 Case 6
    VarX=33
    VarY=6
 Case 7
    VarX=37
    VarY=7
 Case 8
    VarX=30
    VarY=8
    VarQ=-1
 Case 9
    VarX=34
    VarY=9
    VarQ=-1
 Case 10
    VarX=32
    VarY=10
    VarQ=-1
 Case 11
    VarX=36
    VarY=11
    VarQ=-1
 Case 12
    VarX=31
    VarY=12
    VarQ=-1
 Case 13
    VarX=35
    VarY=13
    VarQ=-1
 Case 14
    VarX=33
    VarY=14
    VarQ=-1
 Case 15
    VarX=37
    VarY=15
    VarQ=-1
 End Select
End Sub

Sub Get.ANSI.Color2(VarX,VarY)
 VarX=0
 Select Case BackGround
 Case 0
    VarX=40
    VarY=0
 Case 1
    VarX=44
    VarY=16
 Case 2
    VarX=42
    VarY=32
 Case 3
    VarX=46
    VarY=48
 Case 4
    VarX=41
    VarY=64
 Case 5
    VarX=45
    VarY=80
 Case 6
    VarX=43
    VarY=96
 Case 7
    VarX=47
    VarY=112
 End Select
End Sub

SUB Change.Screen
 Allow.Extra = True
 ScreenColor = False
 Color.Set = False
 Active.Page = False
 Active.Set = False
 Visual.Page = False
 Visual.Set = False
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp4#)
 VarX = Cint(Temp4#)
 Select Case VarX
    Case 0, 1, 2, 7 To 13
       ScreenMode = CInt(Temp4#)
    Case Else
       Error 5
       Exit Sub
 End Select
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    ScreenColor = CINT(Temp4#)
    IF Last.Token THEN
       Color.Set = True
    END IF
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp4#)
       Active.Page = CINT(Temp4#)
       IF Last.Token THEN
	  Active.Set = True
       END IF
       IF Strng = "," THEN
	  CALL Get.Token
	  CALL Parse1(Temp4#)
	  Visual.Page = CINT(Temp4#)
	  IF Last.Token THEN
	     Visual.Set = True
	  END IF
       END IF
    END IF
 END IF
 IF Color.Set AND Active.Set AND Visual.Set THEN
    SCREEN ScreenMode, ScreenColor, Active.Page, Visual.Page
 ELSE
    IF Color.Set AND Active.Set THEN
       SCREEN ScreenMode, ScreenColor, Active.Page
    ELSE
       IF Color.Set AND Visual.Set THEN
          SCREEN ScreenMode, ScreenColor, , Visual.Page
       ELSE
	  IF Active.Set AND Visual.Set THEN
             SCREEN ScreenMode, , Active.Page, Visual.Page
	  ELSE
	     IF Color.Set THEN
                SCREEN ScreenMode, ScreenColor
	     ELSE
		IF Active.Set THEN
                   SCREEN ScreenMode, , Active.Page
		ELSE
		   IF Visual.Set THEN
                      SCREEN ScreenMode, , , Visual.Page
		   ELSE
                      SCREEN ScreenMode
		   END IF
		END IF
	     END IF
	  END IF
       END IF
    END IF
 END IF
 IF ScreenMode = False THEN
    New.Screen = False
 ELSE
    New.Screen = True
 END IF
END SUB

SUB Change.Width
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 IF LEFT$(Out2, 1) = "#" THEN
    Out2 = MID$(Out2, 2)
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp4#)
    FileNumber = CINT(Temp4#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp4#)
       FileWidth = CINT(Temp4#)
       WIDTH #FileNumber, FileWidth
       EXIT SUB
    END IF
 ELSE
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp4#)
    IF Last.Token THEN
       ScreenWidth = CINT(Temp4#)
       IF Strng = "," THEN
          CALL Get.Token
          CALL Parse1(Temp4#)
          ScreenHeight = CINT(Temp4#)
          SELECT CASE ScreenWidth
          CASE 40, 80
             SELECT CASE ScreenHeight
             CASE 25, 30, 43, 50, 60
                WIDTH ScreenWidth, ScreenHeight
                LastWidth1 = ScreenWidth
                LastWidth2 = ScreenHeight
                IF ScreenWidth = 80 AND ScreenHeight = 25 THEN
                   New.Width = False
                ELSE
                   New.Width = True
                END IF
                EXIT SUB
             END SELECT
          END SELECT
       END IF
    ELSE
       Device$ = Out3
       IF Strng = "," THEN
          CALL Get.Token
          CALL Parse1(Temp4#)
          DeviceWidth = CINT(Temp4#)
          IF UCASE$(Device$) = "LPRINT" THEN
             WIDTH LPRINT DeviceWidth
          ELSE
             WIDTH Device$, DeviceWidth
          END IF
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 146
END SUB

' Freq ranges from 37 to 32,767, Duration from 0 to 65,535.
SUB Sound.Speaker
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp4#)
 If Temp4#>=37 And Temp4#<=32767 Then
    Tone% = CINT(Temp4#)
 Else
    Tone%=Freq
 Endif
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    If Temp4#>=0 And Temp4#<=65535 Then
       Duration2% = CINT(Temp4#)
    Else
       Duration2%=Duration
    Endif
    If Tone%=0% And Duration%=0% Then
       Sound Freq,Duration
    Else
       Sound Tone%, Duration2%
    Endif
    If Local.Mode = False Then
       Sleep 1
       Var$ = CHR$(7)
       Call Put.Modem(Var$)
    Endif
    Exit Sub
 END IF
 Error 175
END SUB

SUB Locate.Cursor
 Allow.Extra = True
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Xcoor = CSRLIN
 Ycoor = POS(0)
 IF LEN(Out2) THEN
    Token.Index = 1
    IF MID$(Out2, Token.Index, 1) = "," THEN
       CALL Get.Token
    ELSE
       CALL Get.Token
       CALL Parse1(Temp4#)
       Xcoor = CINT(Temp4#)
    END IF
    IF Strng = "," THEN
       IF MID$(Out2, Token.Index, 1) = "," THEN
	  CALL Get.Token
       ELSE
	  CALL Get.Token
	  CALL Parse1(Temp4#)
	  Ycoor = CINT(Temp4#)
       END IF
       IF Strng = "," THEN
	  IF MID$(Out2, Token.Index, 1) = "," THEN
	     CALL Get.Token
	  ELSE
	     CALL Get.Token
	     CALL Parse1(Temp4#)
	     Visible = CINT(Temp4#)
	  END IF
	  IF Strng = "," THEN
	     CALL Get.Token
	     CALL Parse1(Temp4#)
	     StartScan = CINT(Temp4#)
	     EndScan = StartScan
	     IF Strng = "," THEN
		CALL Get.Token
		CALL Parse1(Temp4#)
		EndScan = CINT(Temp4#)
	     END IF
	     LOCATE Xcoor, Ycoor, Visible, StartScan, EndScan
             Call Modem.ANSI(2,Xcoor,Ycoor)
             'Call ScreenANSI(2,Xcoor,Ycoor)
	     EXIT SUB
	  END IF
       END IF
    END IF
 END IF
 LOCATE Xcoor, Ycoor, Visible
 Call Modem.ANSI(2,Xcoor,Ycoor)
 'Call ScreenANSI(2,Xcoor,Ycoor)
END SUB

SUB CLS.Screen
 Out2 = MID$(Out2, 4)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) THEN
    SELECT CASE Out2
    CASE "0"
       Color 7,0
       CLS 0
    CASE "1"
       Color 7,0
       CLS 1
    CASE "2"
       Color 7,0
       CLS 2
    CASE ELSE
       ERROR 2
    END SELECT
 ELSE
    Cls
    Call ScreenANSI(3,0,0)
 END IF
 Call Modem.ANSI(3,0,0)
 Call Modem.ANSI(4,33,14)
 Call ScreenANSI(4,33,14)
' If Debug Then
'    Call Sic.Status.Line2
' Else
'    Call Sic.Status.Line
' Endif
' Call Reset.Cursor
 Locate ,,1
END SUB

SUB BSave.Image
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Filename$ = Nul
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    Filename$ = Out3 + ".sc2"
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       Offset = CINT(Temp3#)
       IF Strng = "," THEN
	  CALL Get.Token
	  CALL Parse1(Temp3#)
	  Length = CINT(Temp3#)
	  BSAVE Filename$, Offset, Length
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 60
END SUB

SUB BLoad.Image
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Filename$ = Nul
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    Filename$ = Out3 + ".sc2"
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       Offset = CINT(Temp3#)
       BLOAD Filename$, Offset
    ELSE
       BLOAD Filename$
    END IF
    EXIT SUB
 END IF
 ERROR 60
END SUB

SUB Draw.Pixel
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 X% = CINT(Temp3#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp3#)
    Y% = CINT(Temp3#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       C% = CINT(Temp3#)
       PSET (X%, Y%), C%
       EXIT SUB
    ELSE
       PSET (X%, Y%)
       EXIT SUB
    END IF
 END IF
 ERROR 15
END SUB

SUB Draw.PixelX
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 X% = CINT(Temp3#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp3#)
    Y% = CINT(Temp3#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp3#)
       C% = CINT(Temp3#)
       PRESET (X%, Y%), C%
       EXIT SUB
    ELSE
       PRESET (X%, Y%)
       EXIT SUB
    END IF
 END IF
 ERROR 15
END SUB

SUB Draw.Expression
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    DRAW Out3
    EXIT SUB
 END IF
 ERROR 46
END SUB

SUB Play.Expression
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    PLAY Out3
    EXIT SUB
 END IF
 ERROR 47
END SUB

SUB Restore.Data
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)

 ' search first data statement
 IF LEN(Out2) = False THEN
    FOR LineNumber% = 1 TO Last.Line
       Out2 = Program$(LineNumber%)
       Out2 = STRIM$(Out2)
       Out2 = UCASE$(Out2)
       IF LEFT$(Out2, 5) = "DATA " THEN
          DataLine = LineNumber%
          DataNumber = False
          EXIT FOR
       END IF
    NEXT
    EXIT SUB
 END IF

 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = True THEN
    Line.Number% = CINT(Temp3#)

    IF Line.Number% = -1 THEN ' move back
       IF DataLine > 0 THEN
          FOR V = DataLine - 1 to 1 STEP -1
             Out2 = Program$(V)
             Out2 = STRIM$(Out2)
             Out2 = UCASE$(Out2)
             IF LEFT$(Out2, 5) = "DATA " THEN
                DataLine = V
                DataNumber = False
                EXIT SUB
             END IF
          NEXT
       END IF
       EXIT SUB
    END IF

    IF Line.Number% >= 1 AND Line.Number% <= Last.Line THEN
       Out2 = Program(Line.Number%)
       Out2 = STRIM$(Out2)
       Out2 = UCASE$(Out2)
       IF LEFT$(Out2, 5) = "DATA " THEN
	  DataLine = Line.Number%
	  DataNumber = False
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 65
END SUB

SUB Read.Data
 Allow.Extra = 1
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 DO
    Last.Token = False
    CALL Get.Token
    Temp1$ = STRIM$(Strng)
    Temp1$ = UCASE$(Temp1$)
    IF LEFT$(Temp1$, 1) >= "A" AND LEFT$(Temp1$, 1) <= "Z" THEN
       Variable = ASC(LEFT$(Temp1$, 1)) - 64
       SELECT CASE LEN(Temp1$)
       CASE 1
	  IF MID$(Out2, Token.Index, 1) = "(" THEN
	     IF MID$(Out2, Token.Index + 1, 1) = ")" THEN
		CALL Get.Token
		CALL Get.Token
		CALL Read.Data.Element(More.Data)
		IF More.Data THEN
		   ERROR 66
		END IF
		IF Last.Token = False THEN
		   FOR Element = 1 TO LEN(Out3)
		      Arrays(Variable, Element) = ASC(MID$(Out3, Element, 1))
                      IF Element >= MaxArrays THEN
			 EXIT FOR
		      END IF
		   NEXT
                ELSE
                   ERROR 135
		END IF
	     ELSE
		CALL Get.Token
		CALL Parse1(Temp4#)
		Element = CINT(Temp4#)
		CALL Read.Data.Element(More.Data)
		IF More.Data THEN
		   ERROR 66
		END IF
		IF Last.Token THEN
                   IF Element > False AND Element <= MaxArrays THEN
		      Arrays(Variable, Element) = DataValue
                   ELSE
                      ERROR 9
		   END IF
                ELSE
                   IF Out3 = Nul THEN
                      IF Element > False AND Element <= MaxArrays THEN
                         Arrays(Variable, Element) = 0#
                      ELSE
                         ERROR 9
                      END IF
                   ELSE
                      ERROR 135
                   END IF
		END IF
	     END IF
	  ELSE
	     CALL Read.Data.Element(More.Data)
	     IF More.Data THEN
		ERROR 66
	     END IF
	     IF Last.Token THEN
		Variables(Variable) = DataValue
             ELSE
                IF Out3 = Nul THEN
                   Variables(Variable) = 0#
                ELSE
                   ERROR 135
                END IF
	     END IF
	  END IF
       CASE 2
	  IF MID$(Temp1$, 2, 1) = "$" THEN
	     CALL Read.Data.Element(More.Data)
	     IF More.Data THEN
		ERROR 66
	     END IF
	     IF Last.Token = False THEN
		Strngs(Variable) = Out3
             ELSE
                Strngs(Variable) = LTRIM$(STR$(DataValue))
	     END IF
          ELSE
             ERROR 134
	  END IF
       CASE ELSE
          ERROR 134
       END SELECT
    ELSE
       IF Temp1$ <> "," THEN
          ERROR 134
       END IF
    END IF
    IF Token.Index > LEN(Out2) THEN
       EXIT DO
    END IF
 LOOP
END SUB

SUB Read.Record
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Field.Read = False
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Temp1$ = MID$(Out2, Token.Index)
    Temp1$ = STRIM$(Temp1$)
    Temp1$ = UCASE$(Temp1$)
    Temp2$ = LEFT$(Temp1$, 1)
    Temp1$ = MID$(Temp1$, 2)
    IF Temp1$ = "$" THEN
       IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
          Variable = ASC(Temp2$) - 64
          Out2 = Field.Array(File.Num%)
          Out2 = STRIM$(Out2)
          Out2 = UCASE$(Out2)
          Token.Index = 1
          Start% = 1
          DO
             CALL Get.Token
             CALL Parse1(Temp3#)
             Length% = CINT(Temp3#)
             FieldVariable = False
             IF Strng = "AS" THEN
                Out2 = MID$(Out2, Token.Index + 1)
                Out2 = STRIM$(Out2)
                IF LEFT$(Out2, 1) >= "A" AND LEFT$(Out2, 1) <= "Z" THEN
                   IF MID$(Out2, 2, 1) = "$" THEN
                      FieldVariable = ASC(LEFT$(Out2, 1)) - 64
                      Out2 = MID$(Out2, 4)
                   END IF
                END IF
                Token.Index = 1
             END IF
             IF Strng = "," THEN
                Out2 = MID$(Out2, Token.Index + 1)
                Token.Index = 1
             END IF
             IF FieldVariable = Variable THEN
                Field.Read = True
                Temp$ = MID$(File.Fields(File.Num%), Start%, Length%)
                Strngs(Variable) = Temp$
             END IF
             IF FieldVariable THEN
                Start% = Start% + Length%
             END IF
             IF Token.Index > LEN(Out2) THEN
                EXIT DO
             END IF
          LOOP
       END IF
    END IF
 END IF
 IF Field.Read = False THEN
    ERROR 45
 END IF
END SUB

SUB Get.Record
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    Record.Number& = CSNG(Temp4#)
    IF Strng = "," THEN
       Temp1$ = MID$(Out2, Token.Index)
       Temp1$ = STRIM$(Temp1$)
       Temp1$ = UCASE$(Temp1$)
       Temp2$ = LEFT$(Temp1$, 1)
       Temp1$ = MID$(Temp1$, 2)
       IF LEFT$(Temp1$, 1) = "$" THEN
          IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
             Variable = ASC(Temp2$) - 64
             IF Record.Number& = SFalse THEN
                GET #File.Num%, , Strngs(Variable)
             ELSE
                GET #File.Num%, Record.Number&, Strngs(Variable)
                For Z = 1 To RecordCount
                   If File.Records(Z) > 0& Then
                      If File.Records(Z) = Record.Number& Then
                         Break = -3
                         Exit Sub
                      End If
                   End If
                Next
             END IF
             EXIT SUB
          END IF
       END IF
    ELSE
       GET #File.Num%, Record.Number&
       EXIT SUB
    END IF
 ELSE
    GET #File.Num%
    EXIT SUB
 END IF
 ERROR 44
END SUB

SUB Put.Record
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    Record.Number& = CSNG(Temp4#)
    IF Record.Number& > LOF(File.Num%) + 1 THEN
       ERROR 111
       EXIT SUB
    END IF
    IF Record.Number& > 0& THEN
       For Z = 1 To RecordCount
          If File.Records(Z) > 0& Then
             If File.Records(Z) = Record.Number& Then
                Break = -3
                Exit Sub
             End If
          End If
       Next
    Endif
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp4#)
       IF Last.Token = False THEN
          IF Record.Number& = SFalse THEN
             If Program.Running=0 Then
                IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PUT #File.Num%, , Out3
          ELSE
             IF Record.Number& > LOF(File.Num%) THEN
                If Program.Running=0 Then
                   IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
                      ERROR 140
                      EXIT SUB
                   END IF
                Endif
             END IF
             PUT #File.Num%, Record.Number&, Out3
          END IF
       ELSE
          IF Record.Number& = SFalse THEN
             If Program.Running=0 Then
                IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
                   ERROR 140
                   EXIT SUB
                END IF
             Endif
             PUT #File.Num%, , Temp4#
          ELSE
             IF Record.Number& > LOF(File.Num%) THEN
                If Program.Running=0 Then
                   IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
                      ERROR 140
                      EXIT SUB
                   END IF
                Endif
             END IF
             PUT #File.Num%, Record.Number&, Temp4#
          END IF
       END IF
       EXIT SUB
    ELSE
       IF Record.Number& > LOF(File.Num%) THEN
          If Program.Running=0 Then
             IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
                ERROR 140
                EXIT SUB
             END IF
          Endif
       END IF
       PUT #File.Num%, Record.Number&
       EXIT SUB
    END IF
 ELSE
    If Program.Running=0 Then
       IF AccountLimit(CDBL(Field.Sizes(File.Num%))) THEN
          ERROR 140
          EXIT SUB
       END IF
    Endif
    PUT #File.Num%
    EXIT SUB
 END IF
 ERROR 43
END SUB

SUB Field.Set(Var)
 IF Var = 1 THEN
    Field.Type = 1
 ELSE
    Field.Type = 2
 END IF
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 FieldSet = False
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Temp1$ = MID$(Out2, Token.Index)
    Temp1$ = STRIM$(Temp1$)
    Temp1$ = UCASE$(Temp1$)
    Temp2$ = LEFT$(Temp1$, 1)
    Temp1$ = MID$(Temp1$, 2)
    IF LEFT$(Temp1$, 1) = "$" THEN
       Temp1$ = MID$(Temp1$, 2)
       Temp1$ = STRIM$(Temp1$)
       IF LEFT$(Temp1$, 1) = "," THEN
          IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
             Variable = ASC(Temp2$) - 64
             CALL Get.Token
             CALL Parse1(Temp4#)
             CALL Get.Token
             CALL Parse1(Temp4#)
             IF Last.Token = False THEN
                Field.Value$ = Out3
                Out2 = Field.Array(File.Num%)
                Out2 = STRIM$(Out2)
                Out2 = UCASE$(Out2)
                Token.Index = 1
                Start% = 1
                DO
                   CALL Get.Token
                   CALL Parse1(Temp3#)
                   Length% = CINT(Temp3#)
                   FieldVariable = False
                   IF Strng = "AS" THEN
                      Out2 = MID$(Out2, Token.Index + 1)
                      Out2 = STRIM$(Out2)
                      IF LEFT$(Out2, 1) >= "A" AND LEFT$(Out2, 1) <= "Z" THEN
                         IF MID$(Out2, 2, 1) = "$" THEN
                            FieldVariable = ASC(LEFT$(Out2, 1)) - 64
                            Out2 = MID$(Out2, 4)
                         END IF
                      END IF
                      Token.Index = 1
                   END IF
                   IF Strng = "," THEN
                      Out2 = MID$(Out2, Token.Index + 1)
                      Token.Index = 1
                   END IF
                   IF FieldVariable = Variable THEN
                      FieldSet = True
                      Temp$ = STRING$(Length%, CHR$(0))
                      IF Field.Type = 1 THEN
                         LSET Temp$ = Field.Value$
                      ELSE
                         RSET Temp$ = Field.Value$
                      END IF
                      MID$(File.Fields(File.Num%), Start%, Length%) = Temp$
                   END IF
                   IF FieldVariable THEN
                      Start% = Start% + Length%
                   END IF
                   IF Token.Index > LEN(Out2) THEN
                      EXIT DO
                   END IF
                LOOP
             END IF
          END IF
       END IF
    END IF
 END IF
 IF FieldSet = False THEN
    IF Field.Type = 1 THEN
       ERROR 41
    ELSE
       ERROR 42
    END IF
 END IF
END SUB

SUB Open.Field
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    Temp1$ = MID$(Out2, Token.Index)
    Temp1$ = STRIM$(Temp1$)
    Field.Array(File.Num%) = Temp1$
    EXIT SUB
 END IF
 ERROR 23
END SUB

SUB Open.File
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 File.Num% = CINT(Temp3#)
 IF File.Num% <= False OR File.Num% > MaxFiles THEN
    ERROR 126
    EXIT SUB
 END IF
 If File.Trap(File.Num%) Then
    Break = -2
    Exit Sub
 Endif
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    IF Last.Token = False THEN
       Program.File$ = Out3
       IF Strng = "," THEN
          CALL Get.Token
          CALL Parse1(Temp4#)
          IF Last.Token = False THEN
             Program.Type$ = Out3
             IF Strng = "," THEN
                CALL Get.Token
                CALL Parse1(Temp4#)
                Program.Length = CINT(Temp4#)
             ELSE
                Program.Length = 128
             END IF
             IF Left$(Ucase$(Program.File$),3)="LPT" THEN
                IF Right$(Program.File$,1)=":" THEN
                   IF PrinterSelected = False THEN
                      Error 147
                      Exit Sub
                   END IF
                END IF
             END IF
             Program.Data$ = Program.File$
             Call Valid.File(Program.Data$, Program.File$, Var)
             If Var = 0 Then
                Error 142
                Exit Sub
             Endif
             SELECT CASE UCASE$(Program.Type$)
             CASE "I"
                OPEN Program.Data$ FOR INPUT SHARED AS #File.Num% LEN = Program.Length
                Field.Sizes(File.Num%) = Program.Length
             CASE "O"
                OPEN Program.Data$ FOR OUTPUT SHARED AS #File.Num% LEN = Program.Length
                Field.Sizes(File.Num%) = Program.Length
             CASE "A"
                OPEN Program.Data$ FOR APPEND SHARED AS #File.Num% LEN = Program.Length
                Field.Sizes(File.Num%) = Program.Length
             CASE "R"
                OPEN Program.Data$ FOR RANDOM SHARED AS #File.Num% LEN = Program.Length
                File.Fields(File.Num%) = STRING$(Program.Length, CHR$(0))
                FIELD #File.Num%, Program.Length AS File.Fields(File.Num%)
                Field.Sizes(File.Num%) = Program.Length
             CASE "B"
                OPEN Program.Data$ FOR BINARY SHARED AS #File.Num% LEN = Program.Length
                File.Fields(File.Num%) = STRING$(Program.Length, CHR$(0))
                Field.Sizes(File.Num%) = Program.Length
             CASE ELSE
                ERROR 21
             END SELECT
             EXIT SUB
          END IF
       END IF
    END IF
 END IF
 ERROR 21
END SUB

' force file to open.
Sub Valid.File(Program.Data$, Program.File$, Var)
 Var = -1 ' assume valid
 Select Case Program.Running
    Case LibraryProgram
       Eat$ = Nul ' no restrictions
    Case GroupProgram
       IF Instr(Program.File$, ":") Then ' drive restricted
          Var = 0
       EXIT SUB
    END IF
 Case CatalogProgram
    ' drive/path/extension restricted
    Call Strip.Program(Program.File$,Var2)
    If Var2 Then
       Var = 0
       EXIT SUB
    END IF
    IF LEN(Program.Data$) > 8 THEN
       Var = 0
       EXIT SUB
    END IF
    ' create catalog data file
    Program.Data$ = Current.Directory + Account + ".SIC\" + Program.File$ + ".DAT"
 End Select
End Sub

SUB Close.File(Var)
 IF Var=2 THEN
    Out2 = STRIM$(Out2)
    If Ucase$(Out2)="CLOSE" Then
       CLOSE
       If FileTrap0 Then
          Break = -2
          Exit Sub
       End If
    Else
       Error 22
    Endif
    EXIT SUB
 END IF
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) THEN
    Token.Index = 1
    CALL Get.Token
    'If Left$(Strng,1)="#" Then
    '   Strng=Mid$(Strng,2)
    'Endif
    CALL Parse1(Temp3#)
Start.Close:
    File.Num% = CINT(Temp3#)
    IF File.Num% <= False OR File.Num% > MaxFiles THEN
       ERROR 126
       EXIT SUB
    END IF
    CLOSE #File.Num%
    If File.Trap(File.Num%) Then
       Break = -2
       Exit Sub
    Endif
    If Strng = "TO" Then
       Call Get.Token
       Call Get.Token
       If Left$(Strng, 1) = "#" Then
          Strng = Mid$(Strng, 2)
       End If
       File.Num2% = Int(Val(Strng)+.5)
       For Var% = File.Num% To File.Num2%
          If Var% <= 0 Or Var% > MaxFiles Then
             Error 126
             Exit Sub
          End If
          Close #Var%
          If File.Trap(Var%) Then
             File.Num%=Var%
             Break = -2
             Exit Sub
          End If
       Next
       Call Parse1(Temp3#)
       Goto Start.Close
    Else
       If Strng = "," Or Strng = ";" Then
          CALL Get.Token
          CALL Get.Token
          If Left$(Strng,1)="#" Then
             Strng=Mid$(Strng,2)
          Endif
          CALL Parse1(Temp3#)
          Goto Start.Close
       Endif
    Endif
    EXIT SUB
 END IF
 ERROR 22
END SUB

SUB Chain.Program
 Var$ = Program.Name
 Var2$ = FileName
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    Program.File$ = Out3
    Start.Line = False
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp4#)
       Start.Line = CINT(Temp4#) - 1
    END IF
    IF Program.File$ = Nul THEN
       ERROR 112
       EXIT SUB
    END IF
    Program.File$ = STRIM$(Program.File$)
    Program.File$ = LCASE$(Program.File$)
    Program.Data$ = Program.File$
    Call Chain.Valid(Program.Data$, Program.File$, Var)
    If Var = 0 Then
       Error 142
       Exit Sub
    Endif
    Filename = Program.Data$
    IF DIR$(Filename) = Nul THEN
       Error 53
    END IF
    Recurse2=Recurse2+1
    If Recurse2>=MaxChainRecurse Then
       Error 172
    Endif
    CHDRIVE Program.Directory
    CHDIR Program.Directory
    Close #TempFile1, #TempFile2
    IF Program.Running=False THEN ' catalog
       If Dir$(Prepare.Filename)<>"" Then
          KILL Prepare.Filename
       Endif
    END IF
    CALL New.Program
    CALL Read.Program(Var,Var#)
    If Var Then
       Program.Name = LCASE$(Program.File$)
       Running.Program = LCASE$(Program.File$)
       IF Program.Running=False THEN
          CALL Prepare.Program(True)
       ELSE
          CALL Prepare.Program(False)
       END IF
       Nested.Gosub = False
       Max.Gosubs = 10
       Visible = 1
       REDIM GosubReturn(1 TO 10) AS INTEGER
       Program.Line = Start.Line
       Program.Name = Var$
       Running.Program = Var$
       FileName = Var2$
       CALL Count.Lines(Last.Line)
    Else
       CALL Read.Program(Var,Var#)
       Program.Name = Var$
       Running.Program = Var$
       FileName = Var2$
    Endif
    EXIT SUB
 END IF
 ERROR 112
END SUB

' force program to chain to.
Sub Chain.Valid(Program.Data$, Program.File$, Var)
    Var = -1 ' assume valid
    Select Case Program.Running
    Case LibraryProgram ' can access any file.
       IF Instr(Program.File$, "\") OR Instr(Program.File$, ":") Then
          Eat$ = Nul
       Else
          If Lcase$(Right$(Program.File$, 4)) = ".sic" Then 
             Program.File$ = Left$(Program.File$, Len(Program.File$) - 4)
          Endif
          Program.Data$ = Current.Directory + Account + ".SIC\" + Program.File$ + ".SIC"
       Endif
    Case GroupProgram ' can access only pathname.
       IF Instr(Program.File$, ":") Then
          Var = 0
          EXIT SUB
       END IF
       IF Instr(Program.File$, "\") Then
          Eat$ = Nul
       Else
          If Lcase$(Right$(Program.File$, 4)) = ".sic" Then 
             Program.File$ = Left$(Program.File$, Len(Program.File$) - 4)
          Endif
          Program.Data$ = Current.Directory + Account + ".SIC\" + Program.File$ + ".SIC"
       Endif
    Case CatalogProgram ' can access only filename.
       If Lcase$(Right$(Program.File$, 4)) = ".sic" Then 
          Program.File$ = Left$(Program.File$, Len(Program.File$) - 4)
       Endif
       IF Instr(Program.File$, ".") OR Instr(Program.File$, "\") OR Instr(Program.File$, ":") Then
          Var = 0
          EXIT SUB
       END IF
       If Lcase$(Right$(Program.Data$, 4)) = ".sic" Then 
          Program.Data$ = Left$(Program.Data$, Len(Program.Data$) - 4)
       Endif
       IF LEN(Program.Data$) > 8 THEN
          Var = 0
          EXIT SUB
       END IF
       Program.Data$ = Current.Directory + Account + ".SIC\" + Program.File$ + ".SIC"
    End Select
End Sub

SUB Shell.Program
 Token.Index = Len(Out2) + 1
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 DOS.Command$ = Out2
 CALL Execute.Command(DOS.Command$)
END SUB

' fixed 09/10/2020
SUB Name.Expression(Var)
 IF Var = 1 THEN
    Out2 = MID$(Out2, 7)
 ELSE
    Out2 = MID$(Out2, 5)
 END IF
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    Var4$ = Out3
    IF Strng = "," THEN
       Last.Token = False
       CALL Get.Token
       CALL Parse1(Temp4#)
       IF Last.Token = False THEN
          Out4 = Var4$
          IF Out3 = Nul THEN
             Error 142
             EXIT SUB
          END IF
          IF Out4 = Nul THEN
             Error 142
             EXIT SUB
          END IF
          Program.Data$ = Out4
          Program.Data2$ = Out3
          Select Case Program.Running
          Case LibraryProgram 
             Eat$ = Nul
          Case GroupProgram 
             IF Instr(Out3, ":") Or Instr(Out4, ":") Then
                Error 142
                EXIT SUB
             END IF
          Case CatalogProgram
             Call Strip.Program(Out3,Var2)
             Call Strip.Program(Out4,Var3)
             If Var2 Or Var3 Then
                Error 142
                EXIT SUB
             END IF
             IF LEN(Out3) > 8 OR LEN(Out4) > 8 THEN
                ERROR 52
                EXIT SUB
             END IF
             Program.Data$ = Current.Directory + Account + ".SIC\" + Out4 + ".DAT"
             Program.Data2$ = Current.Directory + Account + ".SIC\" + Out3 + ".DAT"
          End Select
          NAME Program.Data$ AS Program.Data2$
          EXIT SUB
       END IF
    END IF
 END IF
 ERROR 113
END SUB

SUB Kill.File(Var)
 DIM ASCIIZ2 AS STRING * 260
 IF Var = 1 THEN
    Out2 = MID$(Out2, 5)
 ELSE
    Out2 = MID$(Out2, 7)
 END IF
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Last.Token = False THEN
    IF Out3 = Nul THEN
       Error 142
       EXIT SUB
    END IF
    Program.Data$ = Out3
    Select Case Program.Running
    Case LibraryProgram 
       Eat$ = Nul
    Case GroupProgram 
       IF Instr(Out3, ":") Then
          Error 142
          EXIT SUB
       END IF
    Case CatalogProgram
       Call Strip.Program(Out3,Var2)
       If Var2 Then
          Error 142
          EXIT SUB
       END IF
       IF LEN(Program.Data$) > 8 THEN
          ERROR 52
          EXIT SUB
       END IF
       Program.Data$ = Current.Directory + Account + ".SIC\" + Out3 + ".DAT"
    End Select
    If Dir$(Program.Data$)<>Nul Then
       ' set file attributes
       ASCIIZ2=Program.Data$+CHR$(0)
       InregsX.AX = &H4301
       InregsX.DS = VARSEG(ASCIIZ2)
       InregsX.DX = VARPTR(ASCIIZ2)
       InregsX.CX = &H0
       CALL InterruptX(&H21, InregsX, OutregsX)
       KILL Program.Data$
    Else
       Error 142
    Endif
    EXIT SUB
 END IF
 ERROR 114
END SUB

SUB CD.Directory(Var)
 IF Var = 1 THEN
    Out2 = MID$(Out2, 3)
 ELSE
    Out2 = MID$(Out2, 6)
 END IF
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Program.Running = False THEN
    ERROR 142
 END IF
 IF Last.Token = False THEN
    IF Out3 = Nul THEN
       Error 142
       EXIT SUB
    END IF
    Program.Data$ = Out3
    Select Case Program.Running
    Case LibraryProgram
       Eat$ = Nul
    Case GroupProgram
       IF Instr(Out3, ":") Then
          Error 142
          EXIT SUB
       END IF
    End Select
    CHDIR Program.Data$
    EXIT SUB
 END IF
 ERROR 115
END SUB

SUB MD.Directory(Var)
 IF Var = 1 THEN
    Out2 = MID$(Out2, 3)
 ELSE
    Out2 = MID$(Out2, 6)
 END IF
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Program.Running = False THEN
    ERROR 142
 END IF
 IF Last.Token = False THEN
    IF Out3 = Nul THEN
       Error 142
       EXIT SUB
    END IF
    Program.Data$ = Out3
    Select Case Program.Running
    Case LibraryProgram 
       Eat$ = Nul
    Case GroupProgram 
       IF Instr(Out3, ":") Then
          Error 142
          EXIT SUB
       END IF
    End Select
    MKDIR Program.Data$
    EXIT SUB
 END IF
 ERROR 116
END SUB

SUB RD.Directory(Var)
 IF Var = 1 THEN
    Out2 = MID$(Out2, 3)
 ELSE
    Out2 = MID$(Out2, 6)
 END IF
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 IF Program.Running = False THEN
    ERROR 142
 END IF
 IF Last.Token = False THEN
    IF Out3 = Nul THEN
       Error 142
       EXIT SUB
    END IF
    Program.Data$ = Out3
    Select Case Program.Running
    Case LibraryProgram 
       Eat$ = Nul
    Case GroupProgram 
       IF Instr(Out3, ":") Then
          Error 142
          EXIT SUB
       END IF
    End Select
    RMDIR Program.Data$
    EXIT SUB
 END IF
 ERROR 117
END SUB

SUB Set.Date
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 IF LEFT$(Out2, 1) = "=" THEN
    Out2 = MID$(Out2, 2)
    Out2 = STRIM$(Out2)
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp3#)
    IF Last.Token = False THEN
       DATE$ = Out3
       EXIT SUB
    END IF
 END IF
 ERROR 118
END SUB

SUB Set.Time
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 IF LEFT$(Out2, 1) = "=" THEN
    Out2 = MID$(Out2, 2)
    Out2 = STRIM$(Out2)
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp3#)
    IF Last.Token = False THEN
       TIME$ = Out3
       EXIT SUB
    END IF
 END IF
 ERROR 119
END SUB

SUB Change.Drive
 Out2 = MID$(Out2, 8)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 Var# = Temp3#
 IF Program.Running <> LibraryProgram THEN
    ERROR 142
 END IF
 Temp# = 0#
 IF Last.Token THEN
    Var = CINT(Var#)
    IF Var >= 1 AND Var <= 26 THEN
       Var$ = Chr$(Var + 64) + ":\"
       ChDrive Var$
       Exit Sub
    END IF
 ELSE
    Var$ = UCase$(Out3)
    If Var$ >= "A" And Var$ <= "Z" Then
       Var$ = Var$ + ":\"
       ChDrive Var$
       Exit Sub
    End If
 END IF
 Last.Token = True
 ERROR 120
END SUB

SUB Swap.Data
 Temp1$ = MID$(Out2, 5)
 Temp1$ = STRIM$(Temp1$)
 Temp2$ = UCASE$(LEFT$(Temp1$, 1))
 IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
    Variable1 = ASC(Temp2$) - 64
    Temp1$ = MID$(Temp1$, 2)
    Temp1$ = STRIM$(Temp1$)
    IF LEFT$(Temp1$, 1) = "," THEN
       Temp1$ = MID$(Temp1$, 2)
       Temp1$ = STRIM$(Temp1$)
       Temp2$ = UCASE$(LEFT$(Temp1$, 1))
       IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
	  Variable2 = ASC(Temp2$) - 64
	  Temp1$ = MID$(Temp1$, 2)
	  Temp1$ = STRIM$(Temp1$)
	  IF Temp1$ = Nul THEN
	     SWAP Variables(Variable1), Variables(Variable2)
             EXIT SUB
	  ELSE
             Var1$ = Left$(Temp1$, 1)
             IF Var1$ = "(" Or Var1$ = "[" Or Var1$ = "{" THEN
		Out2 = MID$(Temp1$, 2)
		Out2 = STRIM$(Out2)
		Last.Token = False
		Token.Index = 1
		CALL Get.Token
		CALL Parse1(Temp3#)
		Element = CINT(Temp3#)
                Select Case Var1$
                Case "("
                   If Strng<>")" Then
                      Strng = "<bad closing token>"
                      Error 92
                   Endif
                Case "["
                   If Strng<>"]" Then
                      Strng = "<bad closing token>"
                      Error 92
                   Endif
                Case "{"
                   If Strng<>"}" Then
                      Strng = "<bad closing token>"
                      Error 92
                   Endif
                End Select
                IF Element > False AND Element <= MaxArrays THEN
                   SWAP Variables(Variable1), Arrays(Variable2, Element)
                   EXIT SUB
                END IF
	     END IF
	  END IF
       END IF
    ELSE
       Var1$ = LEFT$(Temp1$, 1)
       IF Var1$ = "(" Or Var1$ = "[" Or Var1$ = "{" THEN
	  Out2 = MID$(Temp1$, 2)
	  Out2 = STRIM$(Out2)
	  Last.Token = False
	  Token.Index = 1
	  CALL Get.Token
	  CALL Parse1(Temp3#)
          Select Case Var1$
          Case "("
             If Strng<>")" Then
                Strng = "<bad closing token>"
                Error 92
             Endif
          Case "["
             If Strng<>"]" Then
                Strng = "<bad closing token>"
                Error 92
             Endif
          Case "{"
             If Strng<>"}" Then
                Strng = "<bad closing token>"
                Error 92
             Endif
          End Select
	  Element1 = CINT(Temp3#)
	  Temp1$ = MID$(Out2, Token.Index)
	  Temp1$ = STRIM$(Temp1$)
	  IF LEFT$(Temp1$, 1) = "," THEN
	     Out2 = MID$(Temp1$, 2)
	     Out2 = UCASE$(Out2)
	     Temp1$ = MID$(Temp1$, 2)
	     Temp1$ = STRIM$(Temp1$)
	     Temp2$ = UCASE$(LEFT$(Temp1$, 1))
	     IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
		Variable2 = ASC(Temp2$) - 64
		Temp1$ = MID$(Temp1$, 2)
		Temp1$ = STRIM$(Temp1$)
		IF Temp1$ = Nul THEN
                   IF Element1 > False AND Element1 <= MaxArrays THEN
                      SWAP Arrays(Variable1, Element1), Variables(Variable2)
                      EXIT SUB
                   END IF
		ELSE
                   Var1$ = LEFT$(Temp1$, 1)
                   IF Var1$ = "(" Or Var1$ = "[" Or Var1$ = "{" THEN
		      Out2 = MID$(Temp1$, 2)
		      Out2 = STRIM$(Out2)
		      Last.Token = False
		      Token.Index = 1
		      CALL Get.Token
		      CALL Parse1(Temp3#)
                      Select Case Var1$
                      Case "("
                         If Strng<>")" Then
                            Strng = "<bad closing token>"
                            Error 92
                         Endif
                      Case "["
                        If Strng<>"]" Then
                            Strng = "<bad closing token>"
                            Error 92
                         Endif
                      Case "{"
                         If Strng<>"}" Then
                            Strng = "<bad closing token>"
                            Error 92
                         Endif
                      End Select
		      Element2 = CINT(Temp3#)
                      IF Element1 > False AND Element1 <= MaxArrays THEN
                         IF Element2 > False AND Element2 <= MaxArrays THEN
                            SWAP Arrays(Variable1, Element1), Arrays(Variable2, Element2)
                            EXIT SUB
                         END IF
                      END IF
		   END IF
		END IF
	     END IF
	  END IF
       ELSE
	  IF LEFT$(Temp1$, 1) = "$" THEN
	     Temp1$ = MID$(Temp1$, 2)
	     Temp1$ = STRIM$(Temp1$)
	     IF LEFT$(Temp1$, 1) = "," THEN
		Temp1$ = MID$(Temp1$, 2)
		Temp1$ = STRIM$(Temp1$)
		Temp2$ = UCASE$(LEFT$(Temp1$, 1))
		IF Temp2$ >= "A" AND Temp2$ <= "Z" THEN
		   Variable2 = ASC(Temp2$) - 64
		   Temp1$ = MID$(Temp1$, 2)
		   Temp1$ = STRIM$(Temp1$)
		   IF Temp1$ = "$" THEN
		      SWAP Strngs(Variable1), Strngs(Variable2)
                      EXIT SUB
		   END IF
		END IF
	     END IF
	  END IF
       END IF
    END IF
 END IF
 ERROR 110
END SUB

SUB Sleep.Second
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) = False THEN
    Temp3# = 1#
 ELSE
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp3#)
 END IF
 Pause.Time! = CSNG(Temp3#)
 Start.Timer1! = Timeit!
 Start.Timer2! = Timeit!
 If Pause.Time! < 1! Then
    Error 5
 Endif
 If Pause.Time! > 86400! Then
    Error 5
 Endif
 DO
    Elapsed.Time! = Timeit! - Start.Timer1!
    IF Elapsed.Time! < SFalse THEN
       Elapsed.Time! = Elapsed.Time! + 86400!
    END IF
    IF Elapsed.Time! >= Pause.Time! THEN
       EXIT DO
    END IF
    IF Time.Elapsed(Start.Timer2!,1!) THEN
       Start.Timer2!=Timeit!
       CALL Check.Carrier
       CALL Check.Program
       Call Check.Break
       CALL Keyboard
       CALL Get.Modem
       If Break Then
          Exit Do
       Endif
       If Len(Buffer) Then
          Buffer = Nul
          EXIT DO
       Endif
    END IF
 LOOP
END SUB

SUB Pause.Second
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) = False THEN
    Temp3# = 1#
 ELSE
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp3#)
 END IF
 Pause.Time! = CSNG(Temp3#)
 Start.Timer1! = Timeit!
 Start.Timer2! = Timeit!
 If Pause.Time! < 1! Then
    Error 5
 Endif
 If Pause.Time! > 86400! Then
    Error 5
 Endif
 DO
    Elapsed.Time! = Timeit! - Start.Timer1!
    IF Elapsed.Time! < SFalse THEN
       Elapsed.Time! = Elapsed.Time! + 86400!
    END IF
    IF Elapsed.Time! >= Pause.Time! THEN
       EXIT DO
    END IF
    IF Time.Elapsed(Start.Timer2!,1!) THEN
       Start.Timer2!=Timeit!
       CALL Check.Carrier
       CALL Check.Program
       Call Check.Break
       CALL Keyboard
       CALL Get.Modem
       If Break Then
          EXIT DO
       Endif
    END IF
 LOOP
END SUB

SUB Output.Port
 Out2 = MID$(Out2, 4)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp4#)
 Port.Address = CINT(Temp4#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    Port.Byte = CINT(Temp4#)
    OUT Port.Address, Port.Byte
    EXIT SUB
 END IF
 ERROR 121
END SUB

SUB Wait.Port
 Allow.Extra = True
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) THEN
    Token.Index = 1
    CALL Get.Token
    CALL Parse1(Temp4#)
    Port.Address = CINT(Temp4#)
    IF Strng = "," THEN
       CALL Get.Token
       CALL Parse1(Temp4#)
       And.Value = CINT(Temp4#)
       Xor.Value = False
       IF Strng = "," THEN
	  CALL Get.Token
	  CALL Parse1(Temp4#)
	  Xor.Value = CINT(Temp4#)
       END IF
       WAIT Port.Address, And.Value, Xor.Value
       EXIT SUB
    END IF
 END IF
 ERROR 122
END SUB

SUB Int86.Function
 Out2 = MID$(Out2, 6)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token3
 CALL Get.Token
 CALL Parse1(Temp4#)
 CALL Get.Token4
 Int86.Value = CINT(Temp4#)
 If Int86.Value<0 Or Int86.Value>255 Then
    Error 158
    Exit Sub
 Endif
 InregsX.AX = INT(VAL("&H" + HEX$(AX))+.5)
 InregsX.BX = INT(VAL("&H" + HEX$(BX))+.5)
 InregsX.CX = INT(VAL("&H" + HEX$(CX))+.5)
 InregsX.DX = INT(VAL("&H" + HEX$(DX))+.5)
 InregsX.BP = INT(VAL("&H" + HEX$(BP))+.5)
 InregsX.SI = INT(VAL("&H" + HEX$(SI))+.5)
 InregsX.DI = INT(VAL("&H" + HEX$(DI))+.5)
 InregsX.Flags = INT(VAL("&H" + HEX$(FL))+.5)
 InregsX.DS = INT(VAL("&H" + HEX$(DS))+.5)
 InregsX.ES = INT(VAL("&H" + HEX$(ES))+.5)
 Call SpecInt86X(Int86.Value)
 IF OutregsX.AX < False THEN
    AX = CDBL(OutregsX.AX + 65536)
 ELSE
    AX = CDBL(OutregsX.AX)
 END IF
 IF OutregsX.BX < False THEN
    BX = CDBL(OutregsX.BX + 65536)
 ELSE
    BX = CDBL(OutregsX.BX)
 END IF
 IF OutregsX.CX < False THEN
    CX = CDBL(OutregsX.CX + 65536)
 ELSE
    CX = CDBL(OutregsX.CX)
 END IF
 IF OutregsX.DX < False THEN
    DX = CDBL(OutregsX.DX + 65536)
 ELSE
    DX = CDBL(OutregsX.DX)
 END IF
 IF OutregsX.BP < False THEN
    BP = CDBL(OutregsX.BP + 65536)
 ELSE
    BP = CDBL(OutregsX.BP)
 END IF
 IF OutregsX.SI < False THEN
    SI = CDBL(OutregsX.SI + 65536)
 ELSE
    SI = CDBL(OutregsX.SI)
 END IF
 IF OutregsX.DI < False THEN
    DI = CDBL(OutregsX.DI + 65536)
 ELSE
    DI = CDBL(OutregsX.DI)
 END IF
 IF OutregsX.Flags < False THEN
    FL = CDBL(OutregsX.Flags + 65536)
 ELSE
    FL = CDBL(OutregsX.Flags)
 END IF
 IF OutregsX.DS < False THEN
    DS = CDBL(OutregsX.DS + 65536)
 ELSE
    DS = CDBL(OutregsX.DS)
 END IF
 IF OutregsX.ES < False THEN
    ES = CDBL(OutregsX.ES + 65536)
 ELSE
    ES = CDBL(OutregsX.ES)
 END IF
END SUB

SUB Defseg.Function
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) = False THEN
    DEF SEG
    EXIT SUB
 END IF
 Token.Index = 1
 CALL Get.Token3
 CALL Get.Token
 CALL Parse1(Temp4#)
 CALL Get.Token4
 IF Temp4#>=DFalse AND Temp4#<=65535# THEN
    DEF SEG = CINT(Temp4#)
    EXIT SUB
 END IF
 ERROR 125
END SUB

SUB Absolute.Function
 Out2 = MID$(Out2, 9)
 Out2 = STRIM$(Out2)
 IF LEN(Out2) THEN
    Token.Index = 1
    CALL Get.Token3
    CALL Get.Token
    CALL Parse1(Temp4#)
    CALL Get.Token4
    CALL Absolute(CINT(Temp4#))
    EXIT SUB
 END IF
 ERROR 123
END SUB

SUB Poke.Value
 Out2 = MID$(Out2, 5)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp4#)
 Poke.Address = CINT(Temp4#)
 IF Strng = "," THEN
    CALL Get.Token
    CALL Parse1(Temp4#)
    Poke.Byte = CINT(Temp4#)
    POKE Poke.Address, Poke.Byte
    EXIT SUB
 END IF
 ERROR 124
END SUB

SUB Seed.Random
 Out2 = MID$(Out2, 10)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token
 CALL Parse1(Temp3#)
 RANDOMIZE CLNG(Temp3#)
 X = RND
END SUB

 ' def fn(x)=value
SUB Define.Function
 Out2 = MID$(Out2, 7)
 Out2 = STRIM$(Out2)
 Token.Index = 1
 CALL Get.Token3
 CALL Get.Token
 CALL Parse1(Temp4#)
 CALL Get.Token4
 Func% = CINT(Temp4#)
 IF Func% >= 1 AND Func% <= MaxFNs THEN
    Out2 = MID$(Out2, Token.Index)
    Out2 = LTRIM$(Out2)
    IF LEFT$(Out2, 1) = "=" THEN
       Out2 = MID$(Out2, 2)
       Definitions(Func%) = Out2
       EXIT SUB
    END IF
 END IF
 ERROR 152
END SUB

' gets .cfg information
Sub Read.Config
 On Local Error Goto Config.Error
 Local.Mode=True
 Lost.Carrier=False
 Call Read.Rows(Max.Row)
 Locate Max.Row-1,1,1
 ' check ansi
 Call Plex.Function(26)
 If (OutregsX.AX And &HFF)=&HFF Then
    Local.ANSI.Color=True
 Else
    Local.ANSI.Color=False
 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
 ' get share.installed
 Call Detect.Share
 ' get current path
 DND.Path = Environ$("DNDBBS")
 If DND.Path <> Nul Then
    If Right$(DND.Path, 1) <> "\" Then
       DND.Path = DND.Path + "\"
    Endif
 Endif
 ' read config variables
 Close #TempFile2
 FileName=DND.Path+"DND"+Rtrim$(NodeX)+".CFG"
 Open FileName For Input Shared As #TempFile2
 For Temp1=1 To 41
    Line Input #TempFile2,Temp$
 Next
 For Temp1=1 To 90
    Input #TempFile2,Temp2
    Select Case Temp1
    Case 86
       User.Echo=Temp2
    Case 87
       User.Linefeeds=Temp2
    Case 88
       User.Linelength=Temp2
    Case 89
       User.Pagelength=Temp2
    Case 90
       User.Wordwrap=Temp2
    End Select
 Next
 Exit Sub
 ' assign default user variables
Config.Resume:
 User.Echo=True
 User.Linefeeds=True
 User.Linelength=80
 User.Pagelength=25
 User.Wordwrap=True
 Exit Sub
Config.Error:
 Resume Config.Resume
End Sub

' increases open file handles
SUB Increase.PSP
 Call StdinInt(62,0)
 PSP.Segment = OutregsX.BX
 DEF SEG = PSP.Segment
 Command.Line = &H80
 Command.Tail = Command.Line + 20
 FOR Var = 1 TO 104 ' 100 file handles
    POKE Command.Tail + Var - 1, &HFF
 NEXT
 FOR Var = 1 TO 4 ' DOS handles
    File.Handle = PEEK(&H18 + Var - 1)
    POKE Command.Tail + Var - 1, File.Handle
 NEXT
 POKE &H32, 104
 POKE &H34, Command.Tail
 DEF SEG
 CLOSE
END SUB

' decreases open file handles
SUB Decrease.PSP
 CLOSE
 Call StdinInt(62,0)
 PSP.Segment = OutregsX.BX
 DEF SEG = PSP.Segment
 POKE &H32, 20
 POKE &H34, &H18
 DEF SEG
 CLOSE
END SUB

' prompts for more
SUB More.Prompt (Input.String$, Input.Mask$, Output.String$, Default.String$)
 Call Modem.ANSI(4,37,15)
 Call ScreenANSI(4,37,15)
 If StdinEnabled Then
    Output.String$ = Default.String$
    Exit Sub
 Endif
 Input.Char$ = Nul
 DO While Lost.Carrier=False
    Line.Length = 1
    Carriage.Return = True
    Strng3 = Input.String$ + "?"
    Call IO.I
    Strng3 = Nul
    Input.Char$ = LCASE$(Out9)
    IF Input.Char$ = Nul THEN
       IF Default.String$ <> Nul THEN
          Input.Char$ = Default.String$
          Strng3 = Input.Char$
       END IF
    END IF
    Call IO.O
    IF Input.Char$ <> Nul THEN
       IF INSTR(Input.Mask$, Input.Char$) THEN
          Output.String$ = Input.Char$
          EXIT DO
       END IF
    END IF
 LOOP
 Call Modem.ANSI(4,33,14)
 Call ScreenANSI(4,33,14)
END SUB

' prompts for a keypress
SUB Key.Prompt
 If StdinEnabled Then
    Exit Sub
 Endif
 Call Modem.ANSI(4,37,15)
 Call ScreenANSI(4,37,15)
 Line.Length = 1
 No.Echo = True
 Carriage.Return = True
 Strng3 = "Press any key to continue:"
 Call IO.I
 No.Echo = False
 Call IO.O
 Call Modem.ANSI(4,33,14)
 Call ScreenANSI(4,33,14)
END SUB

' prompts for a keypress
SUB Key.Prompt2
 If StdinEnabled Then
    Exit Sub
 Endif
 Call Modem.ANSI(4,37,15)
 Call ScreenANSI(4,37,15)
 Line.Length = 1
 No.Echo = True
 Carriage.Return = True
 Strng3 = "Press a key:"
 Call IO.I
 No.Echo = False
 Call IO.O
 Call Modem.ANSI(4,33,14)
 Call ScreenANSI(4,33,14)
END SUB
