home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / basic / library / qb_pds / communic / asylib / asydemo.bas < prev    next >
Encoding:
BASIC Source File  |  1989-03-04  |  47.9 KB  |  1,817 lines

  1. ' AsyDEMO - (C) InfoSoft, 1987-1988
  2. ' ALL RIGHTS RESERVED
  3. '
  4. ' This serves as a demo of some comport and async programming from
  5. ' QuickBasic 4.0.
  6. '
  7. ' This was written with a TAB setting of 5
  8. '
  9. ' BILL!  Look NO GOTOs !!!!!!!
  10. '
  11. '
  12.     TYPE struct                         ' dialing directory structure
  13.        BBS AS STRING * 30              '  BBS name
  14.        Phone AS STRING * 14            '  phone number
  15.        BPS AS LONG                     '  "baud" (115000 > integer)
  16.        Par AS INTEGER                  '  parity, WordLen, Stop bits
  17.        WLen AS INTEGER
  18.        SBit AS INTEGER
  19.        Comment AS STRING * 20          ' a comment
  20.        ProtoPtr AS INTEGER             ' default protocol array pointer
  21.        PWord AS STRING * 20            ' Password
  22.        LDate AS STRING * 10            ' last date on
  23.        LTime AS STRING * 5             ' last time on
  24.        Upls AS INTEGER                 ' successful UpL count
  25.        Dnls AS INTEGER                 ' successful DnL count
  26.     END TYPE
  27.  
  28.     TYPE stra                           ' parameter type file
  29.        Cport AS INTEGER
  30.        BPS AS LONG
  31.        Par AS INTEGER                  '  parity, WordLen, Stop bits
  32.        WLen AS INTEGER
  33.        SBit AS INTEGER
  34.        ' prefix as string
  35.        Echo AS INTEGER                 ' echo status
  36.        fg AS INTEGER                   ' Colors: These could be expanded
  37.        bg AS INTEGER                   '  for various windows etc
  38.        fgh AS INTEGER
  39.        Hangup AS INTEGER               ' type of hangup to perform
  40.     END TYPE
  41.  
  42.     TYPE strb
  43.        s AS STRING * 80
  44.     END TYPE
  45.  
  46.     DIM DIR AS struct                   ' define user type for DIR
  47.     DIM Parm AS stra                    ' define user type for PARMS
  48.  
  49. ' -----------------------------------------------------------------------
  50. ' This is a bare bones example of how to manage ComPort I/O.  There is
  51. ' very little flash and dazzle here - no exploding windows, no sound effects,
  52. ' no screen save/restore effects.  These would be immensely easy to add to
  53. ' the code, but were they to be used here, it would tie the demo to the
  54. ' general pupose library that I use.  Without screen save/restores and
  55. ' windows, we end up clearing the screen a LOT more often. As is, you can
  56. ' use whatever library that you currently use.  This demo is for educational
  57. ' purposes of utilizing the AsyLIB routines.
  58. '
  59. ' -----------------------------------------------------------------------
  60. '
  61. '  AsyLIB, GLIB and DLIB are (C) Copyright 1986-1988 InfoSoft
  62. '
  63. ' -----------------------------------------------------------------------
  64.  
  65. ' AsyLIB.BI holds all the declaration statements for AsyLIB
  66. REM $INCLUDE: 'ASYLIB.BI'
  67.  
  68.  
  69. ' These subs are INLINE to the demo code module - they are more
  70. ' to do with the demo than AsyLIB
  71.  
  72. DECLARE SUB Help ()
  73. DECLARE SUB PSetup (parmfil$, Parm AS stra)
  74. DECLARE SUB UpdStatLine (fg%, bg%)
  75.  
  76.  
  77. COMMON SHARED /TComm/ BPS%, Com$, ComFileNum%
  78. COMMON stat AS strb
  79.  
  80.     CLEAR
  81.     DEFINT A-Z                ' Fallacy #432: QB does NOT default to integer
  82.     OPTION BASE 1
  83.  
  84.     REM $INCLUDE: 'tcomm.inc'           ' Telecommunication definitions
  85.  
  86.  
  87.     ' These should be in a external cfg file too and read into an
  88.     ' an array in a "real" program implementation
  89.     DIM proto$(10)                       ' protocols supported
  90.  
  91.     proto$(1) = "Xmodem"
  92.     proto$(2) = "Xmodem 1k"
  93.     proto$(3) = "ASCII "
  94.     proto$(4) = "Ymodem-G"
  95.     proto$(5) = "Ymodem-B"
  96.     proto$(6) = "Relaxed Xmodem"
  97.     proto$(7) = "Jmodem (Shell)"        ' these 2 require DSZ.COM and
  98.     proto$(8) = "Zmodem (Shell)"        ' JMODEM.COM available on many BBS
  99.     proto$(9) = ""
  100.     proto$(10) = ""
  101.  
  102.     REDIM macro$(10)                     ' Alt 1- 0 = macro keys
  103.  
  104.     FOR x = 1 TO 10
  105.        macro$(x) = ""
  106.     NEXT x
  107.  
  108.  
  109.     '******* Global variables and setup *********
  110.     ret$ = SPACE$(12)                   ' set up for ASM call
  111.  
  112.  
  113.     ' some external file names:
  114.     phonedir$ = "ASYDEMO.DIR"           ' Phone book
  115.     parmfil$ = "ASYDEMO.INI"            ' initial parameters
  116.  
  117.     CALL SetBline(24)                   ' Tell TAnsiPrint we are using
  118.                     '   lines 24-25 (for CLS)
  119.  
  120.     CALL SetBeep(500, 50)               ' Tell TAnsiPrint what kinda
  121.                                 '   BEEP we want
  122.                ' TAnsiPrint and the related functions make managing
  123.                ' the local screen handling a BREEZE.  Everthing that
  124.                ' we want to go to the local screen just as it is echoed
  125.                ' to the remote terminal, is done so with TAnsiPrint.  This
  126.                ' includes automatically leaving any size of status line
  127.                ' alone
  128.  
  129.     CALL SetCRIN(1)                     ' Set CR in to CR not CR/LF
  130.  
  131.     slin$ = SPACE$(80)                  ' status line mask
  132.     stat.s = slin$                      ' status line
  133.  
  134.     DirEnt = 0                          ' currently no directory selection
  135.     LogFile = 0                         ' log file not active
  136.  
  137.     AnsRow = 1                          ' Row/col tracked and maintained by
  138.     AnsCol = 1                          '  TAnsiPrint
  139.  
  140.     ProtPtr = 2                         ' Protocol in effect until dir
  141.                                 '  entry loaded proto$(2) = Xmodem1K
  142.  
  143.     ScriptF = 0                         ' no script file active
  144.     Prefix$ = "ATDT"                    ' Dialing prefix$
  145.  
  146.     RemoteCLS$ = CHR$(27) + "[2J"       ' ANSI code to Clear remote screen
  147.     Minute = 60
  148.     waitfor = 0                         ' no IF WAITFOR pending
  149.  
  150.  
  151.     ' The logfile mode should be read from a CFG file too or at least
  152.     '   be able to be altered by some setup process.
  153.     LogMode = 0                         ' set log file output to APPEND mode
  154.  
  155.  
  156.     ' Atime sets the length of the alarm.  The alarm sounds after a file Xfer
  157.     ' session, or in response to the ALARM x script file command.  Terminal
  158.     ' mode ATIME could be read from a CFG file, or set via ATIME from a script
  159.     ' file.
  160.     ATime = 3                           ' default
  161.  
  162.  
  163.     ' -- This gets the default COM parameters
  164.  
  165.     errc = FirstF(parmfil$, ret$)       ' find file
  166.     IF errc = 18 THEN                   ' no parm file, need to setup
  167.        slin$ = "No Parameters - run setup"
  168.        stat.s = slin$
  169.        CALL UpdStatLine(7, 0)
  170.        CALL PSetup(parmfil$, Parm)
  171.     ELSE
  172.        f = FREEFILE                    ' get parms
  173.        OPEN parmfil$ FOR RANDOM AS #f LEN = LEN(Parm)
  174.        GET #f, 1, Parm
  175.        CLOSE #f
  176.     END IF
  177.  
  178.  
  179.     ' assign global variables from the parameter file.
  180.     ' This allows EZ modification for those who do not like or
  181.     '   do not understand TYPE structures
  182.  
  183.     ComPort = Parm.Cport
  184.     BPS = Parm.BPS
  185.     Parity = Parm.Par
  186.     WordLen = Parm.WLen
  187.     StopBit = Parm.SBit
  188.     fg = Parm.fg
  189.     bg = Parm.bg
  190.     fgh = Parm.fgh
  191.     EchoStat = Parm.Echo
  192.     '
  193.     ' By the by, this terminal program works fine as a dumb terminal - IE
  194.     ' connected to PCPlus or QMODEM directly with no modem!
  195.     '
  196.  
  197.     ComFileNum = FREEFILE                    ' get BAS File no.
  198.  
  199.  
  200.     COLOR fg, bg
  201.     CLS
  202.  
  203.     CALL Help                                ' start up screen / help
  204.  
  205.     CALL TAnsiCLS
  206.     LOCATE AnsRow, AnsCol
  207.  
  208.     GOSUB MakeSline                          ' make / display status line
  209.  
  210.  
  211.     errc = FirstF(phonedir$, ret$)
  212.     IF errc = 18 THEN                   ' no phone file, make 0 byte file
  213.         f = FREEFILE                   ' to avoid RTE later
  214.         OPEN phonedir$ FOR RANDOM AS #f LEN = LEN(DIR)
  215.         CLOSE #f
  216.     END IF
  217.  
  218.     ' set up the com port.
  219.     '
  220.     ' You CAN leave this closed until needed or until the user wants to
  221.     ' enter terminal mode.  In fact, Alt-T is meant for this but, if we use
  222.     ' this approach we need to add another IF into the terminal mode block
  223.     ' of code to NOT poll the comm port if Terminal Mode is 0 and therefore
  224.     ' the comport is closed.
  225.  
  226.     CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  227.  
  228.     ' these file names are those automatically loaded as the script and / or
  229.     ' macro file if they exist on disk
  230.     AutoScr$ = "AsyAuto.SCR"
  231.     AutoMac$ = "AsyAuto.MAC"
  232.  
  233.     errc = FirstF(AutoMac$, ret$)
  234.     IF errc = 0 THEN                    ' file was found
  235.        macfil$ = AutoMac$              ' assign to global macro file name
  236.        GOSUB LoadMacs
  237.     END IF
  238.  
  239.  
  240.     ' load script file
  241.     errc = FirstF(AutoScr$, ret$)
  242.     IF errc = 0 THEN                    ' file was found
  243.        ScrFil$ = AutoScr$              '   assign to global script file name
  244.  
  245.        errc = ScrCompiler(ScrFil$, Scr$)
  246.  
  247.        IF errc = 0 THEN
  248.           ScriptF = 1                ' indicate Script File active
  249.        ELSE
  250.           PRINT " Script File error - press any key"
  251.           x$ = INPUT$(1)
  252.        END IF
  253.  
  254.        CALL TAnsiCLS
  255.        LOCATE 1, 1
  256.     END IF
  257.  
  258.  
  259.  
  260. '         ********* here is the start of the terminal program ********
  261. ' \\\\/\\\\\/\\\\\/\\\\\\/\\\\\\/\\\\\\/\\\\\\/\\\\\\/\\\\\/\\\\\/\\\\\/\\\\\
  262.  
  263.     DO                     ' endless loop covering Terminal and Script LOOPS
  264.  
  265.        DO                                   ' loop thru terminal control
  266.  
  267.           ' note that we are using 0 as the num of secs to wait for a char.
  268.           m = 0
  269.           CALL RecChar(m, ch$, Status%)    ' get Com, KB char or TimeOut
  270.  
  271.           SELECT CASE Status
  272.              CASE 1                       ' KB char hit
  273.                 k$ = INKEY$              ' get key
  274.                 MOpt = KBOption(k$)      ' test for [Alt+key] combo
  275.                 IF MOpt THEN             ' YES !
  276.                     GOSUB AltFuncs       '  go exec desired function
  277.                 ELSE
  278.                     CALL SendChar(k$)    ' plain char - send to other end
  279.                     IF EchoStat THEN     ' if local echo is ON,
  280.                         CALL TAnsiPrint(k$, AnsRow, AnsCol)    ' do it
  281.                     END IF
  282.                 END IF
  283.  
  284.  
  285.              CASE 2                       ' com port char seen
  286.                 CALL TAnsiPrint(ch$, AnsRow, AnsCol)    ' print it
  287.                 IF LogFile THEN          ' if Log file open,
  288.                     PRINT #lf, ch$;      ' store it
  289.                 END IF
  290.  
  291.              CASE -1                      ' time ran out
  292.  
  293.           END SELECT
  294.  
  295.           IF KeyReady THEN                 ' be ready to send
  296.              k$ = INKEY$                  '   ^K, ^S ^X especially
  297.              CALL SendChar(k$)
  298.           END IF
  299.  
  300.           GOSUB StatLineChk                ' see if stat line needs updating
  301.  
  302.        LOOP UNTIL ScriptF         ' end terminal if AltFuncs toggles
  303.                             ' script file flag
  304.  
  305.     ' /////////////////////////////////////////////////////////////////
  306.     ' Thats it!  The terminal portion is very sleek and compact: get KB
  307.     ' or comport I/O and handle it.  The rest, dialing and so forth is
  308.     ' all handled via the menu items!
  309.     ' /////////////////////////////////////////////////////////////////
  310.     ' If a script file is activated by the Alt key selection process,
  311.     ' the AltFuncs CASE statement sets the ScriptF variable and the
  312.     ' loop falls thru to here.
  313.     '
  314.     ' When the script file is done or terminated, control returns
  315.     ' to the terminal loop
  316.     ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  317.  
  318.  
  319.     ' at this point, the Alt-O function from the kb has read in the desired
  320.     ' script file and compiled it into a memory image.  We are now ready
  321.     ' the bgin reading it Command Series by Command Series.
  322.     '
  323.        GOSUB MakeSline            ' display name of script file executing
  324.  
  325.        ScrPtr = 0                 ' initialize compiled script pointer
  326.        DO
  327.           ScrOpt = ScrReader(Scr$, ScrPtr%, arg$, arg%)
  328.  
  329.           IF ScrOpt = 36 THEN              ' trap for IF
  330.  
  331.              SELECT CASE arg              ' act on condition
  332.                 CASE 1                   ' Test CD
  333.                     ScrCD = CarrierDetect(ComPort)          ' get state
  334.                     IF ScrCD THEN
  335.                        DO
  336.                           ScrOpt = ScrReader(Scr$, ScrPtr%, arg$, arg%)
  337.                           GOSUB ExecScript
  338.                        LOOP UNTIL ScrOpt = 37 OR ScrOpt = -1 OR ScrOpt = 42
  339.                        ' do until ENDIF, end of Scr, or ELSE
  340.                     ELSE
  341.                        DO
  342.                           ScrOpt = ScrReader(Scr$, ScrPtr%, arg$, arg%)
  343.                        LOOP UNTIL ScrOpt = 37 OR ScrOpt = -1 OR ScrOpt = 42
  344.                        ' do until ENDIF, EOS or ELSE
  345.  
  346.                     END IF
  347.  
  348.                 CASE 2                   ' test for 'IF waitfor'
  349.                     IF waitfor THEN
  350.                        DO
  351.                           ScrOpt = ScrReader(Scr$, ScrPtr%, arg$, arg%)
  352.                           GOSUB ExecScript
  353.                        LOOP UNTIL ScrOpt = 37 OR ScrOpt = -1 OR ScrOpt = 42
  354.                             ' do until ENDIF, EOS or ELSE
  355.                     ELSE
  356.                        DO
  357.                           ScrOpt = ScrReader(Scr$, ScrPtr%, arg$, arg%)
  358.                        LOOP UNTIL ScrOpt = 37 OR ScrOpt = -1 OR ScrOpt = 42
  359.                             ' do until ENDIF
  360.                     END IF
  361.  
  362.                 CASE ELSE      ' should not get here - compiler catches
  363.                             ' most errors
  364.                     LOCATE 1, 1
  365.                     PRINT "unknown IF condition"
  366.                     LOCATE AnsRow, AnsCol
  367.                     ScriptF = 0
  368.                     ScrOpt = -1
  369.  
  370.              END SELECT
  371.           ELSEIF ScrOpt = -1 THEN
  372.              ' this just keeps the ExecScript routine from trying to
  373.              ' exec a -1
  374.           ELSE
  375.  
  376.             GOSUB ExecScript         ' do the desired function
  377.  
  378.           END IF
  379.  
  380.           GOSUB StatLineChk           ' see if status line needs updating
  381.  
  382.           DO                          ' quickly scan CON and COM for
  383.                                 ' char I/O
  384.              i = 0
  385.              CALL RecChar(i, ch$, stats)
  386.              SELECT CASE stats
  387.                 CASE 1
  388.                     k$ = INKEY$
  389.                     CALL SendChar(k$)    ' plain char - send to other end
  390.                     IF EchoStat THEN
  391.                         CALL TAnsiPrint(k$, AnsRow, AnsCol)
  392.                     END IF
  393.  
  394.                 CASE 2
  395.                     CALL TAnsiPrint(ch$, AnsRow, AnsCol)
  396.                     IF LogFile THEN
  397.                        PRINT #lf, ch$;
  398.                     END IF
  399.  
  400.                 CASE ELSE
  401.              END SELECT
  402.  
  403.           LOOP UNTIL stats = -1       ' do chars until no more
  404.  
  405.  
  406.        LOOP UNTIL ScrOpt = -1          ' do until ScrReader says we are done
  407.  
  408.        SOUND 1200, .5                  ' BEEP = end of script
  409.  
  410.        ScriptF = 0                     ' reset script file active flag
  411.        Scr$ = ""                       ' clear old scipt
  412.        GOSUB MakeSline                 ' clear name from status line
  413.  
  414.     LOOP                 ' end of LOOP housing TERMINAL and Script mode
  415.  
  416. SYSTEM                   ' cannot get here really
  417.  
  418. '------------------
  419.  
  420. '     \\\\\\\\\/\\\\\\\\\\\/\\\\\\\\\\\\/\\\\\\\\\\\\\\/\\\\\\\\\\/
  421. '     This routine houses and handles the Alt-Key function request
  422. '
  423. AltFuncs:
  424.     SELECT CASE MOpt
  425.        CASE 1                          ' Alt-A = answer
  426.           PRINT #ComFileNum, "ATA"
  427.           ' The actual string to send to answer should be read
  428.           ' from some PARM file.
  429.  
  430.        CASE 2                          ' Alt-B = Burp
  431.           CALL PurgeCommBuffer
  432.  
  433.  
  434.        CASE 3                          ' Alt-C - Clear Screen
  435.           CALL TAnsiCLS               '  If your screen color gets changed
  436.                                 '  via ANSI, you should change it
  437.                                 '  via ANSI like with AnsiCOLOR
  438.  
  439.        CASE 4                          ' Alt-D = Dial
  440.           CALL TAnsiCLS               ' SvScrn would be great !!
  441.           DCol = 1: DRow = 5
  442.           pd = 1                      ' entry pointer
  443.           GOSUB OpenDirFile           ' open ASYDEMO.DIR
  444.  
  445.           LOCATE 4, 1                 ' print header
  446.           COLOR fgh, bg
  447.           PRINT "#   BBS Name                     Phone         Last On       Ups  Dns"
  448.           LOCATE 20, 18
  449.           PRINT "D = Dial, R = Revise, A = Add, N = Next Set, [Esc]"
  450.           COLOR fg, bg
  451.                                 
  452.           IF QFones THEN              ' if there are phone entries,
  453.              DirLo = 1
  454.              IF QFones > 12 THEN
  455.                 DirHi = 12
  456.              ELSE                    ' Hi and Lo items to print
  457.                 DirHi = QFones
  458.              END IF
  459.  
  460.              DO
  461.                 
  462.                 GOSUB PrintDir      ' print items Lo to Hi
  463.  
  464.                 DO
  465.                     x$ = UCASE$(INPUT$(1))   ' get a key (yes it's legal)
  466.                 LOOP UNTIL INSTR("DRAN" + CHR$(27), x$)
  467.  
  468.                 SELECT CASE x$
  469.                     CASE "D"                ' dial a number
  470.                        LOCATE 21, 20
  471.                        INPUT "Number to dial: "; DirEnt
  472.                        GOSUB DialDirEnt
  473.  
  474.                     CASE "R"                ' revise entry
  475.                        LOCATE 21, 20
  476.                        INPUT "Number to Revise: "; DirItem
  477.                        GOSUB ReviseDir
  478.                        x$ = Esc$   ' to get out of LOOP
  479.  
  480.                     CASE "A"                ' add number
  481.                        GOSUB AddDir
  482.  
  483.                     CASE "N"
  484.                        IF DirHi + 1 < QFones THEN
  485.                           DirLo = DirHi + 1
  486.                           IF DirHi + 13 <= QFones THEN
  487.                              DirHi = DirHi + 13
  488.                           ELSE
  489.                              DirHi = QFones
  490.                           END IF
  491.                        ELSE
  492.                           SOUND 185, 4      ' error - no more numbers
  493.                        END IF
  494.  
  495.                     CASE CHR$(27)             ' [ESC] - do nothing
  496.                        CALL TAnsiCLS
  497.  
  498.                     CASE ELSE
  499.                 END SELECT
  500.  
  501.              LOOP UNTIL DirEnt OR x$ = Esc$
  502.              CALL TAnsiCLS
  503.           ELSE                        ' new fone file with no entries
  504.              LOCATE 10, 5
  505.              GOSUB AddDir
  506.           END IF
  507.  
  508.  
  509.        CASE 5                          ' Alt-E = Toggle Echo (1 or 0)
  510.           EchoStat = (1 - EchoStat)
  511.           Parm.Echo = EchoStat
  512.           GOSUB MakeSline
  513.  
  514.        CASE 6                          ' Alt-F = Get disk file list
  515.           ' ALL thus would be better done with windows and DIR from
  516.           ' GLIB 1.6
  517.           '
  518.           CALL TAnsiCLS
  519.           INPUT "Enter filespec: (Enter = none)", mask$
  520.           IF LEN(mask$) THEN          ' mask entered ???
  521.              ret$ = SPACE$(12)
  522.              errc = FirstF(mask$, ret$)
  523.              IF errc = 0 THEN
  524.                 FILES mask$
  525.                 LOCATE 23, 25
  526.                 COLOR fgh, bg
  527.                 PRINT "press any key to continue"
  528.                 x$ = INPUT$(1)      ' BC6 users can use SLEEP
  529.                 CALL TAnsiCLS
  530.              END IF
  531.           END IF
  532.  
  533.           GOSUB MakeSline
  534.  
  535.  
  536.        CASE 7                          ' Alt-G = nothing
  537.  
  538.  
  539.        ' this section is weak due to the way QB4.00b and BC 6 handle
  540.        ' the comport and is HIGHLY modem dependant
  541.        CASE 8                          ' Hangup
  542.           SELECT CASE Parm.Hangup
  543.              CASE 0
  544.                 PRINT #ComFileNum, "ATH"
  545.  
  546.              CASE 1
  547.                 ' AT s2 MUST equal 43 for this to work
  548.                 PRINT #ComFileNum, "+++"
  549.                 PRINT #ComFileNum, "ATH"
  550.  
  551.              ' suggest you use this one, but even then, it does not
  552.              ' always hangup - see text.
  553.              CASE 2
  554.                 CLOSE #ComFileNum
  555.                 CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  556.  
  557.              CASE ELSE
  558.  
  559.           END SELECT
  560.  
  561.           ' when hanging up, AsyDEMO updates the last time and date
  562.           ' you called much like QMODEM does
  563.           IF DirEnt THEN              ' Connected via Alt-D ?
  564.              pd = DirEnt
  565.              GOSUB GetpDir
  566.  
  567.              DIR.LDate = DATE$       ' store fate and time
  568.              DIR.LTime = TIME$
  569.  
  570.              GOSUB UpdPhoneDir       ' to disk
  571.  
  572.           END IF
  573.  
  574.           DirEnt = 0
  575.           GOSUB MakeSline             ' show we are OFFLINE
  576.  
  577.  
  578.        CASE 9                          ' Alt I = info and help
  579.           CALL Help
  580.           CALL TAnsiCLS
  581.           LOCATE AnsRow, AnsCol
  582.  
  583.  
  584.        CASE 10                         ' Alt-J = undefined
  585.        CASE 11                         ' Alt-K = undefined
  586.  
  587.        CASE 12                         ' Alt-L = Log file toggle
  588.           IF LogFile THEN
  589.              CLOSE #lf
  590.              LogFile = 0
  591.           ELSE
  592.              IF AnsRow > 13 THEN
  593.                 r = 1
  594.              ELSE
  595.                 r = 21
  596.              END IF
  597.  
  598.              LOCATE r, 1
  599.              PRINT SPACE$(79);
  600.              LOCATE r, 1
  601.              SOUND 1200, 1
  602.              INPUT "Log File name (Enter = none): ", LogFil$
  603.  
  604.              IF LEN(LogFil$) THEN
  605.                 GOSUB OpenLogFile
  606.              END IF
  607.               
  608.              LOCATE r, 1
  609.              PRINT SPACE$(79)
  610.              LOCATE AnsRow, AnsCol
  611.           END IF
  612.           GOSUB MakeSline             ' update status line
  613.  
  614.  
  615.        CASE 13                         ' Alt-M = Load Macro File
  616.           ' this will load a macro file from disk, and exchange embed-
  617.           ' ded '{'s for CRs.  You will have to make macro files with
  618.           ' a text editor as I would not subject an end user to the rigours
  619.           ' of editing or changing them without the use of a good, solid
  620.           ' input editor such as FED, found in GLIB.
  621.  
  622.           ' display list of available MACRO files
  623.           CALL TAnsiCLS
  624.           FILES "*.mac"
  625.  
  626.           LOCATE 23, 1
  627.           INPUT "Macro File to load (Enter = NONE):", macfil$
  628.  
  629.           ' check for just enter
  630.           IF macfil$ > "" THEN
  631.  
  632.              IF INSTR(1, macfil$, ".") = 0 THEN
  633.                 macfil$ = LTRIM$(RTRIM$(macfil$)) + ".MAC"
  634.              END IF
  635.  
  636.              GOSUB LoadMacs
  637.  
  638.           END IF
  639.           CALL TAnsiCLS
  640.           LOCATE 1, 1
  641.  
  642.  
  643.        CASE 14                         ' Alt-N = undefined
  644.  
  645.  
  646.        CASE 15                         ' Alt-O = Execute script file
  647.           CALL TAnsiCLS
  648.           LOCATE 1, 1
  649.           ret$ = SPACE$(12)
  650.           errc = FirstF("*.scr", ret$)
  651.           IF errc = 0 THEN            ' any script files available ??
  652.              FILES "*.scr"           ' yup - show em
  653.              PRINT
  654.              PRINT
  655.              INPUT "Script File to execute (Enter = None): ", SFil$
  656.  
  657.              IF LEN(SFil$) THEN
  658.                 Scr$ = ""           ' initialize compiled pointer
  659.  
  660.                 ' tack on a .SCR if needed
  661.                 IF INSTR(SFil$, ".") = 0 THEN
  662.                    ScrFil$ = LTRIM$(RTRIM$(SFil$)) + ".SCR"
  663.                 END IF
  664.  
  665.                 ' this compiles a text script file into a 'compiled'
  666.                 ' string representation of that script. We access the
  667.                 ' disk only ONCE - to get it.
  668.                 errc = ScrCompiler(ScrFil$, Scr$)
  669.  
  670.                 IF errc = 0 THEN
  671.                     ScriptF = 1     ' indicate Script File active
  672.                 ELSE
  673.                     PRINT " Script File error - press any key"
  674.                     x$ = INPUT$(1)
  675.                 END IF
  676.              END IF
  677.           ELSE                        ' no script files
  678.              PRINT "No script files to execute"
  679.              PRINT "press any key"
  680.              x$ = INPUT$(1)
  681.           END IF
  682.           CALL TAnsiCLS
  683.           LOCATE 1, 1
  684.  
  685.  
  686.        CASE 16                         ' alt p - set line parms
  687.           CALL TAnsiCLS
  688.           PRINT TAB(25); "A -  300 N 8 1      D -  300 E 7 1 "
  689.           PRINT TAB(25); "B - 1200 N 8 1      E - 1200 E 7 1 "
  690.           PRINT TAB(25); "C - 2400 N 8 1      F - 2400 E 7 1 "
  691.           ' in a full fledged program I would allow up to 19200
  692.           ' bps rates and use initcom to change the rates, but
  693.           ' this is a demo
  694.  
  695.           DO
  696.              x$ = UCASE$(INPUT$(1))
  697.           LOOP UNTIL INSTR("ABCDEF", x$)
  698.  
  699.           CALL TAnsiCLS
  700.           LOCATE 1, 1
  701.  
  702.           StopBit = 1
  703.  
  704.           SELECT CASE x$
  705.              CASE "A", "B", "C"
  706.                 Parity = 0
  707.                 WordLen = 8
  708.  
  709.              CASE ELSE
  710.                 Parity = 2
  711.                 WordLen = 7
  712.           END SELECT
  713.  
  714.           SELECT CASE x$
  715.              CASE "A", "D"
  716.                 BPS = 300
  717.  
  718.              CASE "B", "E"
  719.                 BPS = 1200
  720.  
  721.              CASE "C", "F"
  722.                 BPS = 2400
  723.           END SELECT
  724.  
  725.           ' this can be ComPortInit to reset them
  726.           ' but QB 4.00b tends to dislike that
  727.           CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  728.           GOSUB MakeSline             ' update status line
  729.  
  730.  
  731.        CASE 17                         ' Alt - Q Send Password
  732.           IF DirEnt THEN              ' online via a Alt-D function?
  733.              pw$ = LTRIM$(RTRIM$(DIR.PWord))
  734.              IF LEN(pw$) THEN        ' make sure there is one
  735.                 CALL SendString(pw$ + CHR$(13), 0)
  736.              END IF
  737.           END IF
  738.  
  739.  
  740.        ' there are better ways of doing a redisl, but this is a demo
  741.        CASE 18                           ' Alt-Redial
  742.           DO UNTIL CarrierDetect(1) OR KeyReady
  743.             PRINT #ComFileNum, "A/"
  744.             Status = 0
  745.  
  746.             DO UNTIL Status = -1       ' grab the chars
  747.                 m = 5
  748.                 CALL RecChar(m, ch$, Status)
  749.                 CALL TAnsiPrint(ch$, Row, Col)
  750.             LOOP
  751.  
  752.             d = 0
  753.             DO UNTIL d >= 30 OR KeyReady   ' wait for KB input or 30 times
  754.                 CALL MPacing(500)          ' wait a half a sec
  755.                 d = d + 1
  756.                 LOCATE 12, 15
  757.                 PRINT 30 - d               ' times redialed
  758.                 IF CarrierDetect(1) THEN
  759.                   EXIT DO                 ' do until DCD hi
  760.                 END IF
  761.             LOOP
  762.             PRINT #ComFileNum, CHR$(13)
  763.           LOOP
  764.  
  765.  
  766.        CASE 19                         ' ALT-S - SHELL
  767.           ' while we suggest a 10 k comm port buffer, if you are
  768.           ' going to actually support an OS shell, you may want
  769.           ' to increase the buffer, or make positive the other side
  770.           ' supports XON/XOFF to prevent buffer overflow
  771.           PRINT #ComFileNum, XOFF$;
  772.           SLEEP 3
  773.           SHELL
  774.           PRINT #ComFileNum, XON$; XON$
  775.  
  776.  
  777.        CASE 20                         ' Alt-T -- Terminal mode
  778.           CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  779.           DirEnt = 0                  ' no dir entry active
  780.  
  781.        CASE 21                         ' Alt-U
  782.        CASE 22                         ' Alt-V
  783.        CASE 23                         ' Alt-W
  784.  
  785.        CASE 24                         ' Alt-X   EXIT
  786.           LOCATE 1, 1
  787.           COLOR fgh, bg
  788.           INPUT "Quit to DOS? ", x$
  789.           IF UCASE$(x$) = "Y" THEN
  790.              IF CarrierDetect(ComPort) THEN
  791.                 INPUT "Drop Carrier? ", y$
  792.                 IF UCASE$(y$) = "Y" THEN
  793.                     ' DTRHi and DTRLo have little effect in QB 4.00a+
  794.                     CLOSE #ComFileNum
  795.                 END IF
  796.              END IF
  797.              SYSTEM
  798.           END IF
  799.           LOCATE AnsRow, AnsCol
  800.  
  801.  
  802.        CASE 25                         ' Alt-Y: save current settings
  803.           Parm.Cport = ComPort        '    as defaults
  804.           Parm.BPS = BPS
  805.           Parm.Par = Parity
  806.           Parm.WLen = WordLen
  807.           Parm.SBit = StopBit
  808.           Parm.fg = fg
  809.           Parm.bg = bg
  810.           Parm.fgh = fgh
  811.           Parm.Echo = EchoStat
  812.  
  813.           f = FREEFILE                    ' get next BAS FileNo
  814.           OPEN parmfil$ FOR RANDOM AS #f LEN = LEN(Parm)
  815.           PUT #f, 1, Parm
  816.           CLOSE #f
  817.  
  818.  
  819.  
  820.        CASE 26                         ' Alt-Z - run setup
  821.           CALL PSetup(parmfil$, Parm)
  822.           fg = Parm.fg
  823.           bg = Parm.bg
  824.           fgh = Parm.fgh
  825.           COLOR fg, bg
  826.           GOSUB MakeSline
  827.  
  828.  
  829.        CASE 29                         ' Pg Up - upload
  830.           GOSUB protocol              ' get desired protocol to use
  831.           IF ProtPtr THEN
  832.              GOSUB UpLoad
  833.  
  834.              IF DirEnt THEN          ' Connected via Alt-D ?
  835.                 pd = DirEnt         ' entry pointer
  836.                 GOSUB GetpDir
  837.                 IF XferOk% THEN     ' set by protocol sub program
  838.                     DIR.Upls = DIR.Upls + 1
  839.                                 ' increment upload counter
  840.                     GOSUB UpdPhoneDir
  841.  
  842.                 END IF
  843.              END IF
  844.           END IF
  845.  
  846.  
  847.        CASE 37                         ' Pg Dn - DownLoad
  848.           GOSUB protocol
  849.           IF ProtPtr > 0 THEN
  850.              GOSUB DownLoad
  851.  
  852.              IF DirEnt THEN               ' Connected via Alt-D ?
  853.                 pd = DirEnt
  854.                 GOSUB GetpDir
  855.                 IF XferOk% THEN          '  Set by protocol sub program
  856.                     DIR.Dnls = DIR.Dnls + 1
  857.                                 ' increment d/l counter
  858.                     GOSUB UpdPhoneDir
  859.  
  860.                 END IF
  861.              END IF
  862.           END IF
  863.  
  864.           ' MACRO keys....
  865.        CASE 121                        ' Alt - 1 (Top Row)
  866.           IF LEN(LTRIM$(RTRIM$(macro$(1)))) THEN
  867.              CALL SendString(macro$(1), 0)
  868.           END IF
  869.  
  870.  
  871.        CASE 122 TO 130
  872.           IF LEN(LTRIM$(RTRIM$(macro$(MOpt - 120)))) THEN
  873.              CALL SendString(macro$(MOpt - 120), 0)
  874.           END IF
  875.  
  876.  
  877.        CASE ELSE
  878.         ' rest of cursor keys.
  879.  
  880.     END SELECT
  881. RETURN                        ' return to terminal or script loop
  882.  
  883. '-----------
  884. '    This is the execution control point for all the script file functions.
  885. ' Keep this in mind if you alter the demo.  More importantly, the
  886. ' following block of code would need to be copied (cut and pasted) or
  887. ' something similar implemented in your own terminal package to interpet
  888. ' the script file.
  889. '
  890. ' We COULD write a CALLable sub that executes all this stuff, but it would
  891. ' do nothing but duplicate an enormous amount of code.  The fact of the
  892. ' matter is that managing a session from the keyboard or from a script file
  893. ' is simply a matter of the source of the commands: text from a script file
  894. ' or via keystrokes.
  895. '
  896. '    This becomes obvious when you look at the code.  Lots of the script
  897. ' functions to execute simply sets the MOpt variable and executes the
  898. ' code as if it WERE entered from the KB; others GOSUB (Never GOTO) to a
  899. ' section of code called from the Script control block AND the
  900. ' keyboard / menu control block.
  901. '
  902. '   We could also skip the Script compile and read steps and interpet the
  903. ' lines read from the script file, but using this algorithm, a number of
  904. ' benefits befall us as described in ASYScript.DOC that comes with the source
  905. ' code license, not the least of which is that the entire Script Compile step
  906. ' can be omitted at run time as well as the script compile CODE, by storing
  907. ' the compiled script to its own file via Scr2File.
  908. '
  909. ExecScript:
  910.     SELECT CASE ScrOpt
  911.        CASE 1                     ' alarm
  912.           IF arg THEN
  913.              FOR x = 1 TO arg
  914.                 SOUND 1200, .5
  915.                 SOUND 800, 3
  916.              NEXT x
  917.           ELSE
  918.              GOSUB SoundAlarm
  919.           END IF
  920.  
  921.        CASE 2                     ' set baud
  922.           BPS = VAL(arg$)
  923.  
  924.        CASE 3
  925.           ScrCD = CarrierDetect(ComPort)
  926.  
  927.        CASE 4                     ' cls
  928.           CALL TAnsiCLS
  929.  
  930.        CASE 5                     ' set color
  931.           attr = arg
  932.           b = attr \ 16
  933.           f = attr MOD 16
  934.           COLOR f, b
  935.  
  936.        CASE 6                     ' CLOG
  937.           CLOSE #lf
  938.           LogFile = 0
  939.    
  940.        CASE 7                     ' CRIN
  941.           IF arg THEN
  942.              CALL SetCRIN(1)    ' set for CR / LF
  943.           ELSE
  944.              CALL SetCRIN(0)    ' set for CR only
  945.           END IF
  946.  
  947.        CASE 8                     ' CROUT
  948.              
  949.        CASE 9
  950.           WordLen = arg
  951.  
  952.        CASE 10                    ' dial
  953.           IF arg THEN
  954.              GOSUB OpenDirFile  ' get number fones in dir
  955.              CLOSE #p
  956.              IF arg <= QFones AND arg > 0 THEN   ' if in range
  957.                 DirEnt = arg     ' set entry to argument
  958.                 GOSUB DialDirEnt ' dial it
  959.              END IF
  960.           END IF
  961.  
  962.        CASE 11                    ' delay
  963.           IF arg = 0 THEN
  964.              arg = 5            ' some default I pulled out of the air
  965.           END IF
  966.  
  967.           'for BC 6:
  968.           SLEEP arg
  969.  
  970.           'IF arg = 0 THEN
  971.           '    arg = 5
  972.           'END IF
  973.           't! = TIMER
  974.           'DO UNTIL t! + CSNG(arg) > TIMER
  975.           'LOOP
  976.  
  977.        CASE 12                     ' echo
  978.           MOpt = 5
  979.           GOSUB AltFuncs          ' use existing inline code
  980.  
  981.        CASE 13                     ' ends
  982.           ScrOpt = -1             '  set DONE flag
  983.  
  984.        CASE 14                     ' EXEC
  985.           IF LEN(arg$) THEN       '  valid argument????
  986.              ScrPtr = 0
  987.              Scr$ = ""
  988.              ret$ = SPACE$(12)
  989.              errc = FirstF(arg$, ret$)    ' does file desired exist?
  990.              IF errc = 0 THEN
  991.                 errc = ScrCompiler(arg$, Scr$)
  992.                 IF errc THEN             ' syntax error in script
  993.                     ScriptF = 0
  994.                     ScrOpt = -1
  995.                     CALL TAnsiCLS
  996.                     PRINT "Error loading Script: "; arg$
  997.                     PRINT " press any key"
  998.                     x$ = INPUT$(1)
  999.                 ELSE
  1000.                     ScriptF = 1
  1001.                     ScrFil$ = arg$
  1002.                     GOSUB MakeSline      ' show new script name
  1003.                 END IF
  1004.              ELSE
  1005.                 SOUND 105, 5
  1006.              END IF
  1007.           ELSE
  1008.              SOUND 105, 5
  1009.           END IF
  1010.  
  1011.  
  1012.        CASE 15                    ' try to hang up
  1013.           MOpt = 8
  1014.           GOSUB AltFuncs
  1015.  
  1016.        CASE 16                    ' LMOD
  1017.           LogMode = arg          ' set log file mode parameter
  1018.  
  1019.        CASE 17                    ' set log file name
  1020.           IF LEN(arg$) THEN
  1021.              LogFil$ = arg$
  1022.           END IF
  1023.  
  1024.        CASE 18                    ' Locate Cursor
  1025.           Row = arg
  1026.           Col = VAL(arg$)
  1027.           IF Col + Row >= 2 THEN ' check for legal coords
  1028.              LOCATE Row, Col
  1029.              AnsRow = Row       ' Update ANSI cursor locations
  1030.              AnsCol = Col
  1031.           END IF
  1032.  
  1033.  
  1034.        CASE 19                    ' load macro file
  1035.           IF LEN(arg$) THEN
  1036.              IF INSTR(arg$, ".") THEN
  1037.                 macfil$ = arg$
  1038.              ELSE
  1039.                 macfil$ = RTRIM$(arg$) + ".mac"
  1040.              END IF
  1041.              GOSUB LoadMacs
  1042.           END IF
  1043.             
  1044.        CASE 20                    ' Open log
  1045.           GOSUB OpenLogFile
  1046.  
  1047.        CASE 21                    ' set parity
  1048.           Parity = arg
  1049.  
  1050.        CASE 22                    ' set comport
  1051.           ComPort = arg
  1052.  
  1053.        CASE 23                    ' print msg
  1054.           CALL TAnsiPrint(arg$, AnsRow, AnsCol)
  1055.  
  1056.        CASE 24                    ' Prefix
  1057.           Prefix$ = arg$
  1058.  
  1059.        CASE 25                    ' set protocol
  1060.           ProtPtr = arg
  1061.  
  1062.        CASE 26                    ' Quit
  1063.           CLOSE #lf              ' close log file if open
  1064.           'CLOSE                 ' Un Rem if you want to maybe drop carrier
  1065.           SYSTEM
  1066.  
  1067.        CASE 27                    ' RECV
  1068.           IF ProtPtr = 0 THEN
  1069.              ProtPtr = 1        ' default to Xmodem (YUK)
  1070.           END IF
  1071.  
  1072.           IF LEN(arg$) THEN
  1073.              XferFil$ = arg$
  1074.              GOSUB DownLoad
  1075.              IF DirEnt THEN     ' connected to legit entry ?
  1076.                 DIR.Dnls = DIR.Dnls + 1
  1077.  
  1078.                 GOSUB UpdPhoneDir
  1079.              END IF
  1080.  
  1081.           END IF
  1082.  
  1083.        CASE 28                    ' Remote Shell
  1084.           IF ComPort = 1 THEN
  1085.              CALL SendString(RemoteCLS$ + "Exit to return", 0)
  1086.              CALL TAnsiPrint(RemoteCLS$ + "Exit to return", AnsRow, AnsCol)
  1087.              SHELL "CTTY COM1:"
  1088.           ELSEIF ComPort = 2 THEN
  1089.              CALL SendString(RemoteCLS$ + "Exit to return", 0)
  1090.              CALL TAnsiPrint(RemoteCLS$ + "Exit to return", AnsRow, AnsCol)
  1091.              SHELL "CTTY COM2:"
  1092.           ELSE                   ' dunno what port is active!
  1093.              CALL SendString("Cannot Shell", 0)
  1094.           END IF
  1095.  
  1096.  
  1097.        CASE 29                    ' send a file
  1098.           IF ProtPtr = 0 THEN
  1099.              ProtPtr = 1        ' default to Xmodem (YUK)
  1100.           END IF
  1101.  
  1102.           IF LEN(arg$) THEN
  1103.              XferFil$ = arg$
  1104.              GOSUB UpLoad
  1105.  
  1106.              IF DirEnt THEN     ' connected to legit entry ?
  1107.                 DIR.Upls = DIR.Upls + 1
  1108.  
  1109.                 GOSUB UpdPhoneDir
  1110.              END IF
  1111.  
  1112.           END IF
  1113.  
  1114.  
  1115.        CASE 30                    ' SET Comport
  1116.           ' hopefully all the vars are set from previous
  1117.           ' scr commands OR the default settings are ok
  1118.           CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  1119.  
  1120.        CASE 31                    ' SLOG
  1121.           LogFile = 0
  1122.  
  1123.        CASE 32                    ' STOP bits
  1124.           StopBit = arg
  1125.  
  1126.        CASE 33                    ' TRANS
  1127.           IF LEN(arg$) THEN
  1128.  
  1129.              CALL SendString(arg$, 0)
  1130.  
  1131.           END IF
  1132.  
  1133.        CASE 34                    ' resume log
  1134.           LogFile = 0
  1135.  
  1136.        CASE 35                    ' WaitFor x$ x
  1137.           IF CarrierDetect(ComPort) THEN
  1138.              MOpt = 2
  1139.              GOSUB AltFuncs          ' purge comm port buffer
  1140.           END IF
  1141.  
  1142.           ' The `waitfor' variable will be set to 1
  1143.           ' if the string is recieved.  Therefore if you write an
  1144.           ' IF construct, you can evaluate the result of this with
  1145.           ' an IF WAITFOR type statement
  1146.           waitfor = 0
  1147.  
  1148.           IF (LEN(arg$)) THEN
  1149.              w$ = ""
  1150.              IF arg = 0 THEN arg = 35
  1151.  
  1152.                 DO
  1153.                     CALL RecChar(arg, p$, Status)
  1154.                     SELECT CASE Status
  1155.                        CASE -1         ' time out
  1156.                           waitfor = 0
  1157.  
  1158.                        CASE 1          ' kb
  1159.                           kb$ = INKEY$
  1160.                           IF kb$ = CHR$(27) THEN
  1161.                              EXIT DO
  1162.                           END IF
  1163.                           CALL SendChar(kb$)
  1164.  
  1165.                        CASE 2           ' com
  1166.                           w$ = RIGHT$(w$, 30) + p$    ' chars recieved so far
  1167.                           IF INSTR(UCASE$(w$), UCASE$(arg$)) THEN
  1168.                              waitfor = 1
  1169.                           END IF
  1170.                           CALL TAnsiPrint(p$, AnsRow, AnsCol)
  1171.  
  1172.                     END SELECT
  1173.                 LOOP UNTIL Status = -1 OR waitfor
  1174.              END IF
  1175.  
  1176.        CASE 36, 37                ' place holders
  1177.  
  1178.        CASE 38                    ' set alarm time
  1179.           ATime = arg
  1180.  
  1181.        CASE 39                    ' send password
  1182.           MOpt = 17
  1183.           GOSUB AltFuncs
  1184.  
  1185.        CASE 40
  1186.           MOpt = 120 + arg       ' set macro to send
  1187.           GOSUB AltFuncs         ' exec Alt KB function
  1188.  
  1189.        CASE 41
  1190.           MOpt = 2
  1191.           GOSUB AltFuncs         ' exec Alt KB function
  1192.  
  1193.        CASE 43
  1194.           ' should only exec if terminal mode = 0 and OFFLINE ??
  1195.           ' adjust to your tastes
  1196.           MOpt = 20              ' enter terminal mode
  1197.           GOSUB AltFuncs         ' exec Alt KB function
  1198.  
  1199.  
  1200.        CASE ELSE
  1201.           PRINT "Unknown script command: "; ScrOpt; arg$; arg
  1202.  
  1203.     END SELECT
  1204. RETURN
  1205. '----------
  1206.  
  1207. StatLineChk:
  1208.     IF CarrierDetect(ComPort) THEN   ' if CD true and
  1209.        IF online = 0 THEN           '  stat line thinks we're OFFLINE
  1210.           GOSUB MakeSline          ' post BBS on Status line
  1211.           SOUND 1200, .5
  1212.        END IF
  1213.     ELSE                             ' If CD False
  1214.        IF online THEN               ' Stat line thinks we're ONLINE
  1215.           DirEnt = 0               ' set to no dir entry active
  1216.           GOSUB MakeSline          ' Clear BBS on Status line
  1217.           SOUND 1200, .5
  1218.        END IF
  1219.     END IF
  1220. RETURN
  1221.  
  1222. '----------
  1223. SoundAlarm:
  1224.     FOR x = 1 TO ATime
  1225.        SOUND 1200, .5
  1226.        SOUND 800, 3
  1227.     NEXT x
  1228.     SOUND 40, .2                        ' make sure speakder is shut off
  1229. RETURN
  1230.  
  1231. '--------------
  1232.  
  1233. ' I reckon INPUT$(1) would have worked as well.
  1234. GetKey:
  1235.     Keyb$ = INKEY$
  1236.     DO UNTIL Keyb$ <> ""
  1237.        Keyb$ = INKEY$
  1238.     LOOP
  1239. RETURN
  1240.  
  1241. '------------------
  1242.  
  1243. ' get protocol to use
  1244. protocol:
  1245.     CALL TAnsiCLS
  1246.     LOCATE 1, 1
  1247.     x = 1
  1248.     ProtOk = 0
  1249.     DO
  1250.        PRINT x; proto$(x)
  1251.        x = x + 1
  1252.     LOOP UNTIL LEN(proto$(x)) < 1
  1253.  
  1254.     IF DirEnt THEN                      ' connected via dial dir?
  1255.        PRINT "Protocol (Enter = "; proto$(DIR.ProtoPtr); ": ";
  1256.     ELSE
  1257.        PRINT "Protocol: ";
  1258.     END IF
  1259.  
  1260.     DO
  1261.        GOSUB GetKey
  1262.  
  1263.        SELECT CASE ASC(Keyb$)
  1264.           CASE 13                ' enter
  1265.              ProtPtr = DIR.ProtoPtr
  1266.  
  1267.           CASE 27
  1268.              ProtPtr = -1
  1269.  
  1270.           CASE ELSE
  1271.              temp = VAL(Keyb$)
  1272.              IF temp >= 1 AND temp < x THEN    ' w/in range
  1273.                 ProtPtr = temp
  1274.              END IF
  1275.  
  1276.        END SELECT
  1277.  
  1278.     LOOP UNTIL ProtPtr
  1279.  
  1280.     PRINT
  1281.     SOUND 1200, .3
  1282.  
  1283.     IF ProtPtr > 0 THEN
  1284.        LINE INPUT "File to transfer: "; XferFil$
  1285.        IF XferFil$ = "" THEN
  1286.           ProtPtr = 0
  1287.           RETURN
  1288.        END IF
  1289.     END IF
  1290.     CALL TAnsiCLS
  1291.     LOCATE 1, 1
  1292.     SOUND 1200, .3
  1293. RETURN
  1294.  
  1295. '--------------
  1296.  
  1297.                 '**** Xfer File from there to here ****
  1298. UpLoad:
  1299.     PRINT "Attemting File Send. Press <ESC> to abort."
  1300.     SELECT CASE ProtPtr
  1301.         CASE 1
  1302.            CALL SendXmodem(XferFil$, XferOk%, 1)       ' Xmodem CRC/Checksum
  1303.  
  1304.         CASE 2
  1305.            CALL SendXmodem1k(XferFil$, XferOk%)
  1306.  
  1307.         CASE 3
  1308.            CALL SendASCII(XferFil$, XferOk%)
  1309.  
  1310.         CASE 4
  1311.            CALL SendYmodemG(XferFil$, XferOk%)
  1312.  
  1313.         CASE 5
  1314.            CALL SendYmodemB(XferFil$, XferOk%)
  1315.  
  1316.         CASE 6
  1317.            CALL SendXmodem(XferFil$, XferOk%, 2)     ' relaxed Xmodem
  1318.  
  1319.         CASE 7
  1320.           ' The BAT file controller 'ASY_SJ.BAT' must
  1321.           ' exist and be accurately written for this one
  1322.           id$ = "j"
  1323.           CALL SendShell(XferFil$, id$, ComPort%, XferOk%)
  1324.  
  1325.  
  1326.         CASE 8
  1327.           ' The BAT file controller 'ASY_SZ.BAT' must
  1328.           ' exist and be accurately written for this one
  1329.           id$ = "z"
  1330.           CALL SendShell(XferFil$, id$, ComPort%, XferOk%)
  1331.  
  1332.  
  1333.         CASE ELSE
  1334.  
  1335.     END SELECT
  1336.  
  1337.     CALL TAnsiCLS
  1338.     LOCATE 1, 1
  1339.     IF XferOk% THEN
  1340.         PRINT
  1341.         PRINT "SUCCESS!!!!!"
  1342.     ELSE
  1343.         PRINT "Failed."
  1344.     END IF
  1345.     GOSUB SoundAlarm
  1346.  
  1347. RETURN
  1348.  
  1349. '-----------------
  1350.                 '****  Xfer file from here to there ***
  1351. DownLoad:
  1352.     PRINT "Attemting File Receive. Press <ESC> to abort."
  1353.  
  1354.     SELECT CASE ProtPtr
  1355.        CASE 1
  1356.           CALL RecXmodem(XferFil$, XferOk%, 1)
  1357.  
  1358.        CASE 2
  1359.           CALL RecXmodem1k(XferFil$, XferOk%)
  1360.  
  1361.        CASE 3
  1362.           CALL RecASCII(XferFil$, 1)
  1363.           x = 1
  1364.  
  1365.        CASE 4
  1366.           CALL RecYmodemG(XferFil$, XferOk%)
  1367.  
  1368.        CASE 5
  1369.           CALL RecYmodemB(XferOk%)
  1370.           PRINT x; "files!!"
  1371.  
  1372.        CASE 6
  1373.           CALL RecXmodem(XferFil$, XferOk%, 2)     ' relaxed Xmodem
  1374.  
  1375.        CASE 7
  1376.           ' The BAT file controller 'ASY_RJ.BAT' must
  1377.           ' exist and be accurately written for this one
  1378.           id$ = "j"
  1379.           CALL RecShell(XferFil$, id$, ComPort%, XferOk%)
  1380.           GOSUB MakeSline
  1381.  
  1382.  
  1383.        CASE 8
  1384.           ' The BAT file controller 'ASY_RZ.BAT' must
  1385.           ' exist and be accurately written for this one
  1386.           id$ = "z"
  1387.           CALL RecShell(XferFil$, id$, ComPort%, XferOk%)
  1388.           GOSUB MakeSline
  1389.  
  1390.        CASE ELSE
  1391.     END SELECT
  1392.  
  1393.     CALL TAnsiCLS
  1394.     LOCATE 1, 1
  1395.     IF XferOk = 1 THEN
  1396.        PRINT "SUCCESS!!!!!"
  1397.     ELSE
  1398.        PRINT "Failed."
  1399.     END IF
  1400.     GOSUB SoundAlarm
  1401. RETURN
  1402.  
  1403. '--------------
  1404.  
  1405. ' This routine simply makes a string suitable for the UpdStatline Call
  1406. MakeSline:
  1407.     IF EchoStat THEN
  1408.        slin$ = "  Echo: ON   "
  1409.     ELSE
  1410.        slin$ = "  Echo: OFF  "
  1411.     END IF
  1412.  
  1413.     slin$ = slin$ + LTRIM$(RTRIM$(STR$(BPS))) + " bps"
  1414.  
  1415.     carrier = CarrierDetect(ComPort)
  1416.     IF carrier THEN
  1417.        slin$ = slin$ + "   ONLINE to"
  1418.        online = 1
  1419.     ELSE
  1420.        slin$ = slin$ + "   OFFLINE  "
  1421.        online = 0
  1422.     END IF
  1423.  
  1424.     IF carrier AND DirEnt THEN
  1425.        slin$ = slin$ + " " + DIR.BBS
  1426.     ELSE
  1427.        slin$ = slin$ + SPACE$(31)                ' clear BBS name
  1428.     END IF
  1429.  
  1430.     IF ScriptF THEN
  1431.        slin$ = slin$ + "Scr: " + LEFT$(ScrFil$, INSTR(ScrFil$, ".") - 1)
  1432.     ELSE
  1433.        IF LogFile THEN
  1434.           slin$ = slin$ + "LOG: " + LogFil$
  1435.        ELSE
  1436.           slin$ = slin$ + SPACE$(13)
  1437.        END IF
  1438.     END IF
  1439.  
  1440.     stat.s = slin$
  1441.  
  1442.     CALL UpdStatLine(Parm.fg, Parm.bg)
  1443.     LOCATE AnsRow, AnsCol
  1444. RETURN
  1445.  
  1446. '-------------------
  1447. '  Here are a bunch of dialing directory primitives
  1448. '  Be careful combining them - they are called by the Alt Key handler AND
  1449. ' the script file handler
  1450. '--------------------
  1451.  
  1452. ' Open the DIR file and get the number of entries in QFones
  1453. OpenDirFile:
  1454.     p = FREEFILE
  1455.     OPEN phonedir$ FOR RANDOM AS #p LEN = LEN(DIR)
  1456.     QFones = LOF(p) / LEN(DIR)
  1457. RETURN
  1458.  
  1459. '-------------
  1460.  
  1461. ' Macro type subroutine to get Dir ent #pd into DIR TYPE from DIR file
  1462. GetpDir:
  1463.     GOSUB OpenDirFile
  1464.     GET #p, pd, DIR
  1465.     CLOSE #p
  1466. RETURN
  1467.  
  1468. '---------
  1469. ' This one just dials the phone. it is a GOSUB so as to be called from
  1470. ' the Alt key handler AND the Script File handler
  1471. '---------
  1472. DialDirEnt:
  1473.     IF DirEnt > 0 AND DirEnt <= QFones THEN   ' an entry was selected
  1474.        pd = DirEnt
  1475.        GOSUB GetpDir
  1476.  
  1477.        CALL CommPortSetUp(ComPort%, Parity%, WordLen%, StopBit%, Errcode%, 10240)
  1478.        CALL TAnsiCLS
  1479.  
  1480.        PRINT #ComFileNum, Prefix$ + LTRIM$(RTRIM$(DIR.Phone))
  1481.  
  1482.        ProtPtr = DIR.ProtoPtr          ' set global variable
  1483.  
  1484.     END IF
  1485. RETURN
  1486.  
  1487. '-----------
  1488. ' revise DIR entry
  1489. ReviseDir:
  1490.     IF DirItem > 0 AND DirItem <= QFones THEN   ' legit item to revise
  1491.        pd = DirItem
  1492.        GOSUB GetpDir
  1493.  
  1494.        CALL TAnsiCLS
  1495.        CALL AddToDir(DIR, proto$())
  1496.  
  1497.        GOSUB OpenDirFile
  1498.        pd = DirItem
  1499.        GOSUB UpdDir
  1500.     ELSE
  1501.        SOUND 150, .5
  1502.     END IF
  1503. RETURN
  1504.  
  1505. '---------
  1506. AddDir:
  1507.     CALL TAnsiCLS
  1508.     GOSUB OpenDirFile
  1509.  
  1510.     CALL AddToDir(DIR, proto$())
  1511.  
  1512.     DIR.Upls = 0
  1513.     DIR.Dnls = 0
  1514.     DIR.LDate = SPACE$(10)                   ' last date on
  1515.     DIR.LTime = SPACE$(5)                    ' last time on
  1516.  
  1517.     CALL TAnsiCLS
  1518.     pd = QFones + 1
  1519.     GOSUB UpdDir
  1520. RETURN
  1521.  
  1522. '----------
  1523.  
  1524. ' Write current values of DIR to position pd in DIR file
  1525. UpdPhoneDir:
  1526.     p = FREEFILE
  1527.     OPEN phonedir$ FOR RANDOM AS #p LEN = LEN(DIR)
  1528.  
  1529. UpdDir:                                 ' this is a no-no
  1530.     PUT #p, pd, DIR
  1531.     CLOSE #p
  1532. RETURN
  1533.  
  1534. '------
  1535.  
  1536. PrintDir:
  1537.     ' This routine gets entries from the dialing Dir in the range
  1538.     ' DirLo to DirHi and prints them to the screen.   This SHOULD
  1539.     ' be a Screen Save type thing, pop up a window and fill it with
  1540.     ' the data, but then, to use this as is, you'd need to use the
  1541.     ' SAME library as I do.  Other inmprovements would be to load the
  1542.     ' DIR into a string array and use a QuickPrint to display it.
  1543.     '  But this is after all, a demo.
  1544.  
  1545.     FOR xx = DirLo TO DirHi
  1546.        pd = xx
  1547.        GOSUB GetpDir
  1548.  
  1549.        psetting$ = LTRIM$(RTRIM$(STR$(DIR.BPS)))
  1550.        SELECT CASE DIR.Par
  1551.           CASE 0: psetting$ = psetting$ + "N"
  1552.           CASE 1: psetting$ = psetting$ + "O"
  1553.           CASE 2: psetting$ = psetting$ + "E"
  1554.           CASE ELSE
  1555.        END SELECT
  1556.        psetting$ = psetting$ + LTRIM$(RTRIM$(STR$(DIR.WLen)))
  1557.        psetting$ = psetting$ + LTRIM$(RTRIM$(STR$(DIR.SBit)))
  1558.  
  1559.        LOCATE DRow, DCol
  1560.        PRINT USING "## "; xx;
  1561.        PRINT DIR.BBS; TAB(35); DIR.Phone; TAB(50); DIR.LDate; TAB(62); DIR.Upls; TAB(67); DIR.Dnls
  1562.        DRow = DRow + 1
  1563.     NEXT xx
  1564.  
  1565.     CLOSE #p
  1566. RETURN
  1567.  
  1568. '///\///\///\///\///\///\///\///\///\///\///\///\///\///\///\///\///\///\
  1569. ' As a GOSUB, we can use this code to open a log file from the
  1570. '  key board (Alt-L) _OR_ from a script file
  1571. '
  1572. OpenLogFile:
  1573.     IF LogFil$ <> CHR$(13) THEN
  1574.        lf = FREEFILE
  1575.        IF LogMode THEN
  1576.           OPEN LogFil$ FOR OUTPUT AS #lf
  1577.        ELSE
  1578.           OPEN LogFil$ FOR APPEND AS #lf
  1579.        END IF
  1580.        LogFile = 1
  1581.     END IF
  1582. RETURN
  1583.  
  1584. '----------
  1585. ' This opens the file specified in macfil$, reads it in and assigns
  1586. ' them to the macro keys Alt-1 to Alt-0
  1587. LoadMacs:
  1588.     mac = FREEFILE
  1589.  
  1590.     ret$ = SPACE$(12)
  1591.     errc = FirstF(macfil$, ret$)
  1592.     IF errc THEN
  1593.        SOUND 105, 5
  1594.        CALL TAnsiPrint("Cannot find " + macfil$ + " Press any key", AnsRow, AnsCol)
  1595.        SLEEP 3
  1596.        RETURN
  1597.     END IF
  1598.  
  1599.     OPEN macfil$ FOR INPUT AS #mac            ' open file
  1600.     j = 1
  1601.  
  1602.     DO UNTIL EOF(mac) OR j = 10            ' only 10 per set, but
  1603.                                    ' each can be 32k!
  1604.        LINE INPUT #mac, lin$              ' get a line
  1605.  
  1606.        CALL CRXlate(lin$)                 ' Xlate '{' for CR's
  1607.  
  1608.        macro$(j) = lin$                   ' assign it
  1609.     LOOP
  1610.  
  1611.     CLOSE #mac
  1612. RETURN
  1613.  
  1614. SUB AddToDir (DIR AS struct, proto$())
  1615.     DEFINT A-Z
  1616.     ' This too, begs for a QuickPrint and a SaveScreen
  1617.  
  1618.     LOCATE 7, 10
  1619.     INPUT "BBS Name: ", DIR.BBS
  1620.  
  1621.     LOCATE 8, 10
  1622.     INPUT "BBS Phone: ", DIR.Phone
  1623.  
  1624.     LOCATE 9, 10
  1625.     INPUT "BBS baud rate: ", DIR.BPS
  1626.  
  1627.     LOCATE 10, 10
  1628.     INPUT "BBS Parity (0=N, 1=O, 2=E): ", DIR.Par
  1629.  
  1630.     LOCATE 11, 10
  1631.     INPUT "BBS Word Length: ", DIR.WLen
  1632.  
  1633.     LOCATE 12, 10
  1634.     INPUT "BBS Stop Bits: ", DIR.SBit
  1635.  
  1636.     q = 2
  1637.     DO UNTIL LEN(proto$(q - 1)) < 1
  1638.        LOCATE q, 50
  1639.        PRINT q - 1; "  "; proto$(q - 1)
  1640.        q = q + 1
  1641.     LOOP
  1642.  
  1643.     LOCATE 13, 10
  1644.     INPUT "Protocol Number: ", DIR.ProtoPtr
  1645.  
  1646.     q = 2
  1647.     DO UNTIL LEN(proto$(q - 1)) < 1
  1648.        LOCATE q, 50
  1649.        PRINT SPACE$(LEN(proto$(q - 1)) + 5)
  1650.        q = q + 1
  1651.     LOOP
  1652.  
  1653.  
  1654.     LOCATE 14, 10
  1655.     INPUT "Comment: ", DIR.Comment
  1656.  
  1657.     LOCATE 15, 10
  1658.     INPUT "Password: ", DIR.PWord
  1659.  
  1660.  
  1661. END SUB
  1662.  
  1663. SUB Help
  1664.     CALL TAnsiCLS
  1665.     ' good lord, an OSC screen would be TERRIFIC here!!!
  1666.  
  1667.     LOCATE 2
  1668.     PRINT TAB(25); "AsyDEMO for AsyLIB 1.1 (C) InfoSoft"
  1669.     LOCATE 3
  1670.     PRINT TAB(30); "DEMO Command Key Summary"
  1671.  
  1672.  
  1673.     LOCATE 5, 3
  1674.     PRINT "[Alt-A] - Answer the Phone!!!              [Alt-N] - "
  1675.     LOCATE 6, 3
  1676.     PRINT "[Alt-B] - Purge comm buffer                [Alt-O] - Execute Script File"
  1677.     LOCATE 7, 3
  1678.     PRINT "[Alt-C] - Clear terminal screen            [Alt-P] - Set Line parameters"
  1679.     LOCATE 8, 3
  1680.     PRINT "[Alt-D] - Add/Chg Dial Directory entries   [Alt-Q] - Quit TO DOS"
  1681.     LOCATE 9, 3
  1682.     PRINT "[Alt-E] - Toggle Echo mode                 [Alt-R] - Redial"
  1683.     LOCATE 10, 3
  1684.     PRINT "[Alt-F] - Disk File List                   [Alt-S] - SHELL"
  1685.     LOCATE 11, 3
  1686.     PRINT "[Alt-G] -                                  [Alt-T] - Terminal Mode"
  1687.     ' this is gonna look like the old PC talk thing
  1688.     LOCATE 12, 3
  1689.     PRINT "[Alt-H] - Hangup                           [Alt-U] -"
  1690.     LOCATE 13, 3
  1691.     PRINT "[Alt-I] - Info and help                    [Alt-V] -"
  1692.     LOCATE 14, 3
  1693.     PRINT "[Alt-J] -                                  [Alt-W] -"
  1694.     LOCATE 15, 3
  1695.     PRINT "[Alt-K] -                                  [Alt-X] - Exit to DOS"
  1696.     LOCATE 16, 3
  1697.     PRINT "[Alt-L] - Toggle LogFile                   [Alt-Y] - Save settings to disk"
  1698.     LOCATE 17, 3
  1699.     PRINT "[Alt-M] - Load Macro File                  [Alt-Z] - Set up"
  1700.  
  1701.     LOCATE 18, 3
  1702.     PRINT "[Alt-1] to [Alt-0] (TOPROW!) - Execute macro"
  1703.     LOCATE 19, 3
  1704.     PRINT "[PgDn]  - DownLoad                         [PgUp]  - UpLoad"
  1705.  
  1706.     LOCATE 21, 25
  1707.     PRINT "[ Press any key to continue]"
  1708.  
  1709.     x$ = INPUT$(1)
  1710.  
  1711. END SUB
  1712.  
  1713. SUB PSetup (parmfil$, Parm AS stra)
  1714.     DEFINT A-Z
  1715.     '
  1716.     ' This is very I/O intensive and does very little validity checking.
  1717.     ' The only way I would do this is to use a decent library using
  1718.     ' either its text input editor or okay$ input routine.
  1719.     '
  1720.  
  1721.  
  1722.     ret$ = SPACE$(12)
  1723.     errc = FirstF(parmfil$, ret$)
  1724.  
  1725.     IF errc <> 18 THEN
  1726.        f = FREEFILE                    ' get next BAS FileNo
  1727.        OPEN parmfil$ FOR RANDOM AS #f LEN = LEN(Parm)
  1728.        GET #f, 1, Parm
  1729.        CLOSE #f
  1730.     END IF
  1731.  
  1732.     CLS
  1733.     CALL UpdStatLine(7, 0)
  1734.  
  1735.  
  1736.     LOCATE 8, 20
  1737.     INPUT "      Default COMM Port:"; Parm.Cport
  1738.  
  1739.     LOCATE 9, 20
  1740.     INPUT "      Default Baud rate:"; Parm.BPS
  1741.  
  1742.     done = 0
  1743.     DO UNTIL done
  1744.        done = 1
  1745.        LOCATE 10, 20
  1746.        INPUT "       Parity (N, 0, E):"; x$
  1747.        SELECT CASE UCASE$(x$)
  1748.           CASE "N": Parm.Par = 0
  1749.           CASE "O": Parm.Par = 1
  1750.           CASE "E": Parm.Par = 2
  1751.           CASE ELSE
  1752.              SOUND 185, 3
  1753.              done = 0
  1754.  
  1755.        END SELECT
  1756.     LOOP
  1757.  
  1758.  
  1759.     LOCATE 11, 20
  1760.     INPUT "      Data Bits (7 or 8):"; Parm.WLen
  1761.     ' this should keep asking for the word length until what you
  1762.     ' enter is 7 or 8.  GLIB users could use GetChar or PGetChar:
  1763.     ' okay$="78": a$=" "
  1764.     ' CALL GetChar(okay$, a$)
  1765.     '  -- or --
  1766.     ' CALL PGetChar("Data bits or Word length:", 11, 7, okay$, a$)
  1767.     '
  1768.  
  1769.     LOCATE 12, 20
  1770.     INPUT "     Stop Bits (0 or 1):"; Parm.SBit
  1771.  
  1772.     LOCATE 13, 20
  1773.     INPUT "      Echo: 0=Off, 1=On:"; Parm.Echo
  1774.  
  1775.     LOCATE 14, 20
  1776.     INPUT " Foreground color(0-31):"; Parm.fg
  1777.  
  1778.     LOCATE 15, 20
  1779.     INPUT "  Background color(0-7):"; Parm.bg
  1780.  
  1781.     LOCATE 16, 20
  1782.     INPUT "HiIntensity color(0-31):"; Parm.fgh
  1783.  
  1784.     LOCATE 17, 20
  1785.     PRINT "Hangup mode:"
  1786.     PRINT TAB(22); " 0 = use ATH"
  1787.     PRINT TAB(22); " 1 = use +++ATH"
  1788.     PRINT TAB(22); " 2 = Drop DTR"
  1789.     LOCATE 21, 20
  1790.     INPUT "      Mode to use (0-2):"; Parm.Hangup
  1791.  
  1792.     f = FREEFILE                    ' get next BAS FileNo
  1793.     OPEN parmfil$ FOR RANDOM AS #f LEN = LEN(Parm)
  1794.     PUT #f, 1, Parm
  1795.     CLOSE #f
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.     CLS
  1804. END SUB
  1805.  
  1806. SUB UpdStatLine (fg%, bg%)
  1807.     SHARED stat AS strb
  1808.     LOCATE 25, 1
  1809.     COLOR bg, fg
  1810.     PRINT stat.s;                      ' adjust this to print 2,3 or
  1811.                                 ' more elements of an array
  1812.                                 ' for 2 or 3 line status lines
  1813.                                 ' use a QUICK PRINT too!
  1814.     COLOR fg, bg
  1815. END SUB
  1816.  
  1817.