home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / msj / msjv4_6 / unix / unixbsc.arc / IODEMO.BAS < prev    next >
Encoding:
BASIC Source File  |  1989-06-19  |  13.5 KB  |  455 lines

  1. ' == [ GENERAL NOTES   ] ================================================
  2. '                                                                       =
  3. '    This Basic program demonstrates how to interface to the     =
  4. '    AsyncTermio device driver.  The interface used finds it's    =
  5. '    origin on AT&T's UNIX systems.                     =
  6. '                                    =
  7. '    The generalized UNIX serial link interface was originally moved    =
  8. '    to MS-DOS for C programmers that desire to port serial comm    =
  9. '    software between MS-DOS and UNIX.                =
  10. '                                    =
  11. '    Most Basic programmers will tell you that Basic's COM port    =
  12. '    management is sufficient for most applications.  We agree.    =
  13. '    However, should you desire to use the generalized UNIX serial    =
  14. '    port interface, Async TermIO will suffice.            =
  15. '                                    =
  16. '    With the OPEN COM statement, Basic provides:            =
  17. '                                    =
  18. '        + Speed, Parity, Stopbits, Character Length Control.    =
  19. '        + Asynchronous buffering of input and output.        =
  20. '        + Call back functions that are invoked on COM activity.    =
  21. '        + Exception handling.                    =
  22. '        + Timing.                        =
  23. '                                    =
  24. '    With the OPEN COM statement, Basic DOES NOT provide:        =
  25. '                                    =
  26. '        + Xon/Xoff Flow Control.                =
  27. '        + The interface is not generalized across environments.    =
  28. '            and is not portable to other operating systems.    =
  29. '        + Not as diverse as the generalized UNIX interface.    =
  30. '                                    =
  31. '    The trade-offs of writing serial communications software are     =
  32. '    discussed at length in the Async TermIO documentation.        =
  33. '                                    =
  34. '    Please review the publication (See Async TermIO    User's Manual)    =
  35. '        "Portable Serial Communications Between MS-DOS & UNIX"    =
  36. '                                    =
  37. ' =======================================================================
  38. '                                    =
  39. '    Copyright (c) 1988    Boulder Software Group            =
  40. '                P.O. BOX 14200                =
  41. '                Boulder, CO   80308-4200        =
  42. '                                    =
  43. '                (303) 440-7868 (Voice)            =
  44. '                (303) 447-0711 (FAX)            =
  45. '                                                                       =
  46. ' =======================================================================
  47. '
  48.  
  49. '
  50. ' == [ INCLUDE FILES   ] ================================================
  51. '                                                                       =
  52. '    The include file TERMIO.H contains several constants that are    =
  53. '    use to set flags, compare values, function declarations, etc.    =
  54. '                                                                       =
  55. ' =======================================================================
  56. '
  57.     
  58.     ' $INCLUDE: 'TERMIO.H'
  59.  
  60.  
  61. '
  62. ' == [ GLOBAL VARS     ] ================================================
  63. '                                                                       =
  64. '                                                                       =
  65. ' =======================================================================
  66. '
  67.  
  68.     DIM         TtyParams        AS    Termio
  69.     DIM        FileNumberTty        AS    INTEGER
  70.     DIM        FileHandle        AS    INTEGER
  71.     DIM        FileMode        AS    INTEGER
  72.  
  73.  
  74. '
  75. ' == [ MAIN            ] ================================================
  76. '                                                                       =
  77. '    Main driver program used to demonstrate how to use the        =
  78. '    AsyncTermIO device driver.  Each meaningful code fragment    =
  79. '    is commented.                            =
  80. '                                                                       =
  81. ' =======================================================================
  82. '
  83.     '
  84.     '    Set up primitive error trapping (exception handling)
  85.     '    in case something goes "wrong."
  86.     '
  87.  
  88.     ON ERROR GO TO ErrorHandler
  89.  
  90.     '
  91.     '    Obtain a free file number for the I/O stream we wish
  92.     '    to open for the terminal device "TTY01" which is a
  93.     '    device driver you should have installed in your
  94.     '    CONFIG.SYS file.
  95.     '
  96.  
  97.     FileNumberTty    = FREEFILE
  98.  
  99.     '
  100.     '    There are several ways to open a file in Basic, the
  101.     '    method shown below is recommended when you intend
  102.     '    to use the AsyncTermIO driver.
  103.     '
  104.  
  105.     OPEN "TTY01" FOR BINARY ACCESS READ WRITE AS #FileNumberTty
  106.  
  107.     '
  108.     '    Set set up the flags in the struct termio
  109.     '
  110.         '    Request that the BREAK character be ignored.
  111.     '    Ignore parity errors .
  112.         '    Start the XON/XOFF mechanism.
  113.     '
  114.     '    
  115.  
  116.     TtyParams.Ciflag        = BRKINT OR IGNPAR OR IXON OR IXOFF
  117.  
  118.         '
  119.     '    Request no delays after NL, CR, TAB or VT.  Expand tabs
  120.         '    to spaces and delay on sending a FF character.
  121.     '
  122.  
  123.     TtyParams.Coflag        = NL0 OR CR0 OR TAB3 OR BS1 OR VT0 OR FF1
  124.  
  125.     '
  126.     '    Request that the baud (symbols/sec) rate at 9600, eight
  127.     '    bits of data, one stop bit (default), enable the
  128.     '    the receiver, and hang-up on the last close of the file.
  129.     '    No parity was requested (PARENB flag not present).
  130.     '
  131.  
  132.     TtyParams.Ccflag        = B9600 OR CS8 OR CREAD OR HUPCL
  133.  
  134.     '
  135.     '    Request no Clflag options.
  136.     '
  137.  
  138.     TtyParams.Clflag        = 0
  139.  
  140.     '
  141.     '    Line discipline is always zero for this device driver
  142.     '
  143.  
  144.     TtyParams.Cline            = CHR$(0)
  145.  
  146.  
  147.     '
  148.     '    Since ICANON is not set the MIN/TIME parameters are
  149.     '    used.  So set both their values to zero.  If the ICANON
  150.     '    flag is set, some of these entries have different meanings.
  151.     '    See the Async TermIO documentation on "MIN/TIME Interaction"
  152.     '    (Somewhere around page 12 for Doc version 4.02, see also
  153.     '    Pages 2 and 3).
  154.     '
  155.  
  156.     MID$( TtyParams.ccc, VINTR,    1 )    = "A"
  157.     MID$( TtyParams.ccc, VQUIT,    1 )    = "B"
  158.     MID$( TtyParams.ccc, VERASE,    1 )     = CHR$( 00 )
  159.     MID$( TtyParams.ccc, VKILL,    1 )     = CHR$( 00 )
  160.     MID$( TtyParams.ccc, VEOF,    1 )    = CHR$( 00 )
  161.     MID$( TtyParams.ccc, VEOL,    1 )    = CHR$( 00 )
  162.     MID$( TtyParams.ccc, RESERVED,    1 )    = CHR$( 00 )
  163.     MID$( TtyParams.ccc, SWTCH,    1 )    = CHR$( 00 )
  164.  
  165.     '
  166.     '    Obtain the file's handle and attribute (mode)
  167.     '
  168.  
  169.     FileMode    = FILEATTR( FileNumberTty, 1 )
  170.     FileHandle    = FILEATTR( FileNumberTty, 2 )
  171.  
  172.     '
  173.     '    Attempt to set the new parameters for the device
  174.     '
  175.     '    Uncomment the next line of code if you desire to
  176.     '    see what is in the record TtyParams thus far
  177.     '
  178.     '
  179.     '    CALL    PrintTermioRecord( TtyParams )
  180.     '
  181.     '
  182.     '    Normally the function TtyDeviceIoctl() would be named
  183.     '    Ioctl() (as it is in C), however, Basic reserves IOCTL
  184.     '    as a keyword and thus we can't use it as an identifier.
  185.     '
  186.     '    The name TtyDeviceIoctl() was arbitrarily chosen, the
  187.     '    source code is provided in the file IOCTL.BAS, so feel free 
  188.     '    to change it to what ever you want.  The make file MAKEDEMO
  189.     '    will convert IOCTL.BAS to a library that can be linked to
  190.     '    your application under the Microsoft Basic 6.0 compiler; 
  191.     '    (IOCTL.LIB).
  192.     '
  193.     '    Note that TtyDeviceIoctl() will be described as the 
  194.     '    function ioctl() in all accompanying Async TermIO documentation.
  195.     '    
  196.  
  197.     IF TtyDeviceIoctl( FileHandle, TCSETS, TtyParams ) <> PASS THEN
  198.  
  199.         PRINT    "TtyDeviceIoctl() can't set new parameters"
  200.         RESET
  201.         SYSTEM
  202.     END IF
  203.  
  204.     '
  205.     '    Call a function to echo characters from the device
  206.     '    attached to the serial link tty01 (COM1).
  207.     '
  208.  
  209.     CALL    Tty2Con2Tty( FileNumberTty )
  210.  
  211.     '
  212.     '    Close the device that we opened
  213.     '
  214.  
  215.     CLOSE    #FileNumberTty
  216.  
  217.     '
  218.     '    Clear the screen and exit the program.
  219.     ' 
  220.  
  221.     CLS
  222.     PRINT    "Exit from Basic Demo Program for AsyncTermIO"
  223.  
  224.     END
  225.  
  226.  
  227. '
  228. ' == [ ERRORHANDLER    ] ================================================
  229. '                                                                       =
  230. '    This is a very lazy error handler, it does not try to recover    =
  231. '    from any errors that may trap to it.  All it does is print    =
  232. '    out the exception handling information and kill this process.    =
  233. '                                                                       =
  234. ' =======================================================================
  235. '
  236.  
  237. ErrorHandler:
  238.  
  239.     CLS
  240.     PRINT    "There has been a runtime error deemed critical"
  241.     PRINT    "enough to terminate the program."
  242.     PRINT    ""
  243.     PRINT    "Errortype: ", ERDEV
  244.     PRINT    "On device: ", ERDEV$
  245.     PRINT    "Basic ERR: ", ERR
  246.  
  247.     SELECT CASE( ERR AND &h00FF )
  248.         CASE    0
  249.             PRINT    "MS-DOS   : Attempt to write on a write-protected diskette"
  250.         CASE    1
  251.             PRINT    "MS-DOS   : Unknown Unit"
  252.         CASE    2
  253.             PRINT    "MS-DOS   : Drive (or Device) Not Ready"
  254.         CASE    3
  255.             PRINT    "MS-DOS   : Unknown Command"
  256.         CASE    4
  257.             PRINT    "MS-DOS   : Data Error (CRC)"
  258.         CASE    5
  259.             PRINT    "MS-DOS   : Bad Request Structure Length"
  260.         CASE    6
  261.             PRINT    "MS-DOS   : Seek Error"
  262.         CASE    7
  263.             PRINT    "MS-DOS   : Unknown Media Type"
  264.         CASE    8
  265.             PRINT    "MS-DOS   : Sector Not Found"
  266.         CASE    9
  267.             PRINT    "MS-DOS   : Printer Out Of Paper"
  268.         CASE    10
  269.             PRINT    "MS-DOS   : Write Fault On Device"
  270.         CASE    11
  271.             PRINT    "MS-DOS   : Read Fault On Device"
  272.         CASE    12
  273.             PRINT    "MS-DOS   : General MS-DOS Device Failure"    
  274.  
  275.         CASE    ELSE
  276.             PRINT    "MS-DOS   : Unrecognized MS-DOS Error"    
  277.     END SELECT
  278.  
  279.     '
  280.     '    To bomb out with Basic Runtime error messages uncomment
  281.     '    the next line of code.
  282.     '
  283.     '
  284.     '    ON ERROR GOTO 0
  285.     '
  286.     '
  287.  
  288.     RESET
  289.     SYSTEM
  290.  
  291. '
  292. ' == [ DOSOMETHINGELSE ] ================================================
  293. '                                                                       =
  294. '    The user can place code that can be executed between arriving    =
  295. '    characters.  If a character arrives, it will be buffered and    =
  296. '    readable later.                            =
  297. '                                                                       =
  298. ' =======================================================================
  299. '
  300. '
  301. '
  302. SUB    DoSomeThingElse
  303.  
  304.     '
  305.     '    Your code here to process other things while waiting for
  306.     '    characters to arrive.
  307.     '    
  308.     '    
  309.     '    
  310.  
  311. END    SUB
  312.  
  313.  
  314. '
  315. ' == [ TTY2CON2TTY     ] ================================================
  316. '                                                                       =
  317. '    Simple SUB that loops looking for characters from the device.    =
  318. '    If it finds one it echos it to the console.  Otherwise it    =
  319. '    will process something else (DoSomeThingElse()).        =
  320. '                                    =
  321. '    If a key is pressed on the console, it is echoed to the device    =
  322. '    driver.  I/O is somewhat clumsy, in that characters entered    =
  323. '    at the console must each be followed by the <Enter> key to be    =
  324. '    read by the INPUT statement.  You can tailor I/O specifically    =
  325. '    for your application as is desired.                =
  326. '                                    =
  327. '    The SUBs GET and PUT can be used to send and receive blocks of    =
  328. '    character data to and from the device driver.  There are     =
  329. '    several examples, coded in C, that can be ported to Basic,    =
  330. '    that demonstrate these techniques.  See the directories        =
  331. '    \C\MSC\DEMO1, \C\MSC\DEMO2, and \C\MSC\DEMO3.            =
  332. '                                                                       =
  333. ' =======================================================================
  334. '
  335. '
  336. '
  337. SUB    Tty2Con2Tty( FileNumber AS INTEGER )
  338.  
  339.     DIM        InChar            AS    STRING * 1
  340.     DIM        OutChar            AS    STRING * 1
  341.     DIM        TestChar        AS    STRING * 1
  342.     
  343.     '
  344.     '    Loop looking for keys from the console.  If a key has
  345.     '    been pressed send it to the terminal device.
  346.     '
  347.     '    When the user enters "Z" on the serial link, this SUB
  348.     '    will return.
  349.     '
  350.  
  351.  
  352.     WHILE( InChar <> "Z" )
  353.     
  354.         '
  355.         '    Get a character from the device.  If EOF is
  356.         '    encountered, do something else in the meantime
  357.         '
  358.  
  359.         GET    #FileNumber, , InChar
  360.  
  361.         IF EOF( FileNumber ) THEN
  362.  
  363.             CALL    DoSomeThingElse    
  364.  
  365.         ELSE
  366.             '
  367.             '    Uncomment the next line if you desire to
  368.             '    echo characters from the device back to the 
  369.             '    device
  370.             '
  371.             '    PUT    #FileNumber,, InChar
  372.             '
  373.  
  374.             WRITE    InChar
  375.  
  376.         END    IF
  377.  
  378.         '
  379.         '    See if there is anything hanging around in the
  380.         '    stdin stream (CON).  If so, pick it up send it
  381.         '    to the device
  382.         '
  383.  
  384.         IF( KbHit = PASS ) THEN
  385.  
  386.             INPUT    ;"",    OutChar
  387.             PUT    #FileNumber,, OutChar
  388.  
  389.         END    IF    
  390.  
  391.     WEND
  392.  
  393. END    SUB
  394.  
  395.  
  396. '
  397. ' == [ KBHIT             ] ==============================================
  398. '                                    =
  399. '    Can't find any function in Basic to see if a keyboard        =
  400. '    character was hit, so gin up a quick one similar to         =
  401. '    MS C's kbhit() function.  Most likely, a similar Basic function    =
  402. '    exists, but I can't find it.                      =
  403. '                                    =
  404. ' =======================================================================
  405. '
  406. FUNCTION    KbHit
  407.  
  408.     DIM        InRegs            AS    RegType
  409.     DIM        OutRegs            AS    RegType
  410.  
  411.     InRegs.AX        = &H0B00
  412.  
  413.     CALL INTERRUPT( &H0021, InRegs, OutRegs )
  414.  
  415.     IF ( ( OutRegs.AX AND &H00FF ) <> 0 ) THEN
  416.         KbHit    = PASS
  417.     ELSE
  418.         KbHit    = FAIL
  419.     END    IF
  420.  
  421. END    FUNCTION
  422.  
  423.  
  424. '
  425. ' == [ PRINTTERMIORECORD ] ==============================================
  426. '                                                                       =
  427. '    Debugging function that prints out the contents of the object    =
  428. '    TtyParams.  Uses the same format as the "stty -g < \dev\tty01"    =
  429. '    command line at the MS-DOS prompt.                =
  430. '                                                                       =
  431. ' =======================================================================
  432. '
  433. '
  434. '
  435. SUB    PrintTermioRecord( TtyParams AS Termio )
  436.  
  437.     PRINT    "Ciflag               : ", OCT$( TtyParams.Ciflag )
  438.     PRINT    "Coflag               : ", OCT$( TtyParams.Coflag )
  439.     PRINT    "Ccflag               : ", OCT$( TtyParams.Ccflag )
  440.     PRINT    "Clflag               : ", OCT$( TtyParams.Clflag )
  441.  
  442.     PRINT    "Cline               : ", OCT$( ASC( TtyParams.Cline ) )
  443.  
  444.     PRINT    "Ccc( VINTR )      : ", OCT$( ASC( MID$( TtyParams.ccc, VINTR,        1 ) ) )
  445.     PRINT    "Ccc( VQUIT )      : ", OCT$( ASC( MID$( TtyParams.ccc, VQUIT,        1 ) ) )
  446.     PRINT    "Ccc( VERASE )     : ", OCT$( ASC( MID$( TtyParams.ccc, VERASE,     1 ) ) )
  447.     PRINT    "Ccc( VKILL )      : ", OCT$( ASC( MID$( TtyParams.ccc, VKILL,        1 ) ) )
  448.     PRINT    "Ccc( VEOF )       : ", OCT$( ASC( MID$( TtyParams.ccc, VEOF,        1 ) ) )
  449.     PRINT    "Ccc( VEOL )       : ", OCT$( ASC( MID$( TtyParams.ccc, VEOL,        1 ) ) )
  450.     PRINT    "Ccc( RESERVED )   : ", OCT$( ASC( MID$( TtyParams.ccc, RESERVED,    1 ) ) )
  451.     PRINT    "Ccc( SWTCH )      : ", OCT$( ASC( MID$( TtyParams.ccc, SWTCH,        1 ) ) )
  452.     
  453. END    SUB
  454.  
  455.