home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / sdepdec.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  26.4 KB  |  835 lines

  1. ::::::::::
  2. INTRO.TXT
  3. ::::::::::
  4.  
  5. Here are 2 implementations of a system dependent interface to terminals.
  6. The implementations run on DEC VAX/VMS Ada and Data General AOS/VS ADE.
  7. These packages were developed for a Virtual Terminal developed for NOSC
  8. through WIS tools contract.
  9.  
  10. The following functionality is supported:
  11. * open the physical terminal with no echo and in binary mode, XON/XOFF 
  12.   supported,
  13. * close the physical terminal and reset it back to what it was before,
  14. * put strings to the physical terminal with no translation,
  15. * get strings form the physical terminal, again, no translation,
  16. * get terminal capabilities file (TCF) name,
  17.   this may be of limited use for other applications,
  18. * get the terminal's name,
  19.   this may be of limited use for other applications,
  20. * check the validity of a particular character,
  21.   call this one to see what characters can be used and which cannot be
  22.   used.
  23.  
  24. Notes:
  25. * The calls to read DO NOT block the entire process, only the calling
  26.   task.
  27. * The DG implementation will return only a single character at a time when
  28.   'get' is called.
  29. * The VAX version may return many characters when 'get' is called.
  30. * The VAX version was developed using the Beta site compiler,  It may change
  31.   with the formal release (they claim that starlet, condition_handling, and
  32.   tasking_services may change with the formal release ).
  33.  
  34. There are five files here.
  35.  
  36. decada_sysdep_vt_spec.ada
  37. decada_sysdep_vt_body.ada
  38. decada_termsup.mar              This is the macro code to support
  39.                                 setting and resetting the terminal
  40.                                 characteristics.
  41.  
  42. dgade_sysdep_vt_spec.ada
  43. dgade_sysdep_vt_body.ada
  44.  
  45.  
  46. There is a sysdep_process package in the same vein being developed here
  47. at Texas Instruments.  It will be distributed it as soon as it is ready.
  48. It allows for process creation/deletion/communication through IPC channels.
  49.  
  50. -Stewart French
  51. french%ti-eg@csnet-relay.arpa
  52. Texas Instruments
  53.  
  54.  
  55.  
  56.  
  57. ::::::::::
  58. decada_sysdep_vt_spec.ada
  59. ::::::::::
  60. -- ---------------------------------------------------------------------------
  61. -- ABSTRACT:  This system dependency package is the only package that
  62. --            needs modifications when rehosting the Virtual Terminal tool
  63. --            to another environment.
  64. --            The supported functions are:
  65. --                * open the physical terminal,
  66. --                * close the physical terminal,
  67. --                * put strings to the physical terminal,
  68. --                * get strings form the physical terminal,
  69. --                * get terminal capabilities file (TCF) name,
  70. --                * get the terminal's name 
  71. --                  (to be subsequently looked up in TCF
  72. --                * check the validity of a particular character.
  73. --
  74. -- ----------------------------------------------------------------------------
  75.  
  76. PACKAGE sysdep IS
  77.  
  78.     PROCEDURE open;
  79.     --
  80.     -- Open the console for binary I/O, no echo.
  81.     --
  82.  
  83.     PROCEDURE close;
  84.     --
  85.     -- Close the console.  Parameters should be reset to original condition.
  86.     --
  87.  
  88.     PROCEDURE put ( data : IN string );
  89.  
  90.     --
  91.     -- Put a string to the terminal.  There should be no translation of
  92.     -- the characters. There can be exceptions to this rule (like CTRL-S and
  93.     -- CTRL-Q)  and these exceptions must be identified in valid_character
  94.     -- below.
  95.     --
  96.  
  97.     PROCEDURE get ( data : OUT string;
  98.                     last : OUT natural );
  99.  
  100.     --
  101.     -- Get a string from the terminal keyboard.  This ocurrs with no echo
  102.     -- and no translations.
  103.     --
  104.  
  105.     PROCEDURE tcf_name ( name : OUT string;
  106.                          last : OUT natural );
  107.     --
  108.     -- Returns the name of the terminal capabilities file as a string.
  109.     -- You better pass in a string of sufficient length to handle the name
  110.     -- that is returned or you will get a constraint error.  80 is a good
  111.     -- random number.
  112.     --
  113.  
  114.     PROCEDURE  terminal_name ( name : OUT string;
  115.                                last : OUT natural );
  116.     --
  117.     -- Returns the name of the terminal.  This name of a string like "tv970".
  118.     -- If the name cannot be determined then last is returned as 0 (zero).
  119.     -- Again,  you better make the name parameter big enough to hold the
  120.     -- value returned.
  121.     --
  122.     -- A DG implementation note:  This procedure looks for a file called
  123.     -- TERM on your searchlist.
  124.     --
  125.  
  126.     FUNCTION valid_character ( item : IN character ) RETURN boolean;
  127.  
  128.     --
  129.     -- Returns a boolean value identifying whether the character passed in
  130.     -- is safe to use in the environment.  Suspicious characters include
  131.     -- CTRL-S  CTRL-Q  CTRL-C  CTRL-Y.
  132.  
  133. END sysdep;
  134. ::::::::::
  135. decada_sysdep_vt_body.ada
  136. ::::::::::
  137. WITH
  138.     text_io,
  139.     system,
  140.     tasking_services,
  141.     starlet,
  142.     condition_handling;
  143.  
  144. USE
  145.     text_io,
  146.     system,
  147.     tasking_services,
  148.     starlet,
  149.     condition_handling;
  150.  
  151. PACKAGE BODY sysdep IS
  152.  
  153.     TYPE status_enum IS (io_ok, io_not_ok );
  154.  
  155.     FUNCTION setterminfo (chan : short_integer) RETURN integer;
  156.     PRAGMA interface( MACRO, setterminfo );
  157.     PRAGMA import_function( internal    =>     setterminfo,
  158.                             parameter_types => (short_integer),
  159.                             result_type =>     integer,
  160.                             external =>        "SETTERMINFO" );
  161.     
  162.     FUNCTION resetterminfo (chan : short_integer) RETURN integer;
  163.     PRAGMA interface( MACRO, resetterminfo );
  164.     PRAGMA import_function( internal    =>     resetterminfo,
  165.                             parameter_types => (short_integer),
  166.                             result_type =>     integer,
  167.                             external =>        "RESETTERMINFO" );
  168.  
  169.     PROCEDURE cancel (
  170.     status    : OUT integer;
  171.     chan    : IN  short_integer);
  172.  
  173.     PRAGMA interface (EXTERNAL, cancel);
  174.  
  175.     PRAGMA import_valued_procedure
  176.                          (cancel, "SYS$CANCEL",
  177.                           (integer, short_integer),
  178.                           (value,   value));
  179.  
  180.  
  181.     PROCEDURE alloc (
  182.     status    : OUT integer;
  183.     devnam    : IN  string;
  184.     phylen    : OUT integer;
  185.     phybuf    : OUT string;
  186.     acmode    : IN  integer := 0 );
  187.  
  188.     PRAGMA interface (EXTERNAL, alloc);
  189.  
  190.     PRAGMA import_valued_procedure (alloc, "SYS$ALLOC",
  191.     (integer, string,        integer,   string,        integer),
  192.     (value,   descriptor(s), reference, descriptor(s), value));
  193.  
  194.  
  195.     PROCEDURE assign (
  196.     status    : OUT integer;
  197.     devnam    : IN  string;
  198.     chan    : OUT short_integer;
  199.     acmode    : IN  integer := 0;
  200.     mbxnam    : IN  string := string'NULL_PARAMETER);
  201.  
  202.     PRAGMA interface (external, assign);
  203.  
  204.     PRAGMA import_valued_procedure (assign, "SYS$ASSIGN",
  205.     (integer, string,        short_integer,   integer, string),
  206.     (value,   descriptor(s), reference,       value,   descriptor(s)));
  207.  
  208.  
  209.     PROCEDURE dassgn (
  210.     status    : OUT condition_handling.cond_value_type;
  211.     chan    : IN  starlet.channel_type);
  212.  
  213.     PRAGMA interface (external, dassgn);
  214.  
  215.     PRAGMA import_valued_procedure (dassgn, "sys$dassgn",
  216.     (condition_handling.cond_value_type, starlet.channel_type),
  217.     (value, value));
  218.  
  219.     PROCEDURE trnlog (
  220.     status    : OUT integer;
  221.     lognam    : IN  string;
  222.     rsllen    : OUT short_integer;
  223.     rslbuf    : OUT string;
  224.     table    : IN  integer := 0;
  225.     acmode    : OUT integer;
  226.     dsbmsk    : IN  integer := 0 );
  227.  
  228.     PRAGMA interface (external, trnlog);
  229.  
  230.     PRAGMA import_valued_procedure (trnlog, "SYS$TRNLOG",
  231.     (integer, string, short_integer, string, integer, integer, integer),
  232.     (value, descriptor(s), reference, descriptor(s), value, reference,
  233.            value));
  234.  
  235.     TASK TYPE terminal_reader_type IS
  236.     ENTRY go;        
  237.     END terminal_reader_type;
  238.     
  239.     TYPE terminal_reader_pointer IS ACCESS terminal_reader_type;
  240.  
  241.     TASK TYPE terminal_buffer_type IS
  242.     ENTRY go;
  243.     ENTRY put( data : IN character; io_status : IN status_enum );
  244.     ENTRY get( data : OUT string; data_last : OUT natural );
  245.     END terminal_buffer_type;
  246.  
  247.     TYPE terminal_buffer_pointer IS ACCESS terminal_buffer_type;
  248.  
  249.     terminal_reader : terminal_reader_pointer;
  250.     terminal_buffer : terminal_buffer_pointer;
  251.     terminal_in_channel : short_integer;
  252.     terminal_out_channel : short_integer;
  253.  
  254.     PROCEDURE open IS
  255.     status : integer;
  256.     BEGIN
  257.         assign
  258.         ( status,
  259.           "SYS$INPUT:",
  260.               terminal_in_channel );
  261.  
  262.         IF status /= 1
  263.         THEN
  264.             text_io.put_line
  265.                ( "In open (assign sys$input)  status : " & 
  266.                  integer'image( status ) );
  267.         END IF;
  268.  
  269.         assign
  270.             ( status,
  271.               "SYS$OUTPUT:",
  272.           terminal_out_channel );
  273.  
  274.         IF status /= 1
  275.         THEN
  276.             text_io.put_line
  277.                ( "In open (assign sys$output)  status : " & 
  278.                  integer'image( status ) );
  279.         END IF;
  280.  
  281.         status := setterminfo( terminal_in_channel );
  282.  
  283.         IF status /= 1
  284.         THEN
  285.             text_io.put_line
  286.              ( "In open (setterminfo)  status : " & 
  287.                    integer'image( status ) );
  288.         END IF;
  289.  
  290.         terminal_reader := NEW terminal_reader_type;
  291.         terminal_buffer := NEW terminal_buffer_type;
  292.         terminal_buffer.go;  -- start up the buffer handler.
  293.         terminal_reader.go;  -- start up the terminal reader.
  294.      END open;
  295.  
  296.     PROCEDURE close IS
  297.     status : integer;
  298.     BEGIN
  299.         cancel( status, terminal_in_channel );
  300.  
  301.         IF status /= 1
  302.         THEN
  303.             text_io.put_line
  304.                ( "In close (cancel)  status : " & 
  305.                  integer'image( status ) );
  306.         END IF;
  307.  
  308.         status := resetterminfo( terminal_in_channel );
  309.  
  310.         IF status /= 1
  311.         THEN
  312.             text_io.put_line
  313.                ( "In close (resetterminfo)  status : " & 
  314.                  integer'image( status ) );
  315.         END IF;
  316.  
  317.         dassgn( condition_handling.cond_value_type( status ),
  318.                 starlet.channel_type(  terminal_in_channel ) );
  319.         dassgn( condition_handling.cond_value_type( status ),
  320.                 starlet.channel_type(  terminal_out_channel ) );
  321.  
  322.     END close;
  323.  
  324.  
  325.     PROCEDURE put ( data : IN string ) IS
  326.     status : integer;
  327.     temp_buffer : string( 1..data'LENGTH );
  328.     ios_block : starlet.iosb_type;
  329.     BEGIN
  330.  
  331.          tasking_services.task_qiow
  332.              ( status => condition_handling.cond_value_type( status ),
  333.                chan => starlet.channel_type( terminal_in_channel ),
  334.                func => starlet.io_writevblk,
  335.                iosb => ios_block,
  336.                p1 => system.to_unsigned_longword( data(data'FIRST)'ADDRESS ),
  337.                p2 => system.unsigned_longword( data'LENGTH )
  338.              );
  339.  
  340.         IF status /= 1
  341.         THEN
  342.             text_io.put_line
  343.                ( "In put  status : " & 
  344.                  integer'image( status ) );
  345.         END IF;
  346.     END put;
  347.  
  348.     PROCEDURE low_level_get 
  349.              ( data : OUT character; io_status : OUT status_enum  ) IS
  350.     status : integer;
  351.     length : CONSTANT positive := 1;
  352.     temp_buffer : string( 1..1 );
  353.     ios_block : starlet.iosb_type;
  354.     BEGIN
  355.  
  356.          tasking_services.task_qiow
  357.              ( status => condition_handling.cond_value_type( status ),
  358.                chan => starlet.channel_type( terminal_in_channel ),
  359.                func => ( starlet.io_readvblk OR 
  360.                          starlet.io_m_nofiltr),
  361.                iosb => ios_block,
  362.                p1 => system.to_unsigned_longword( temp_buffer(1)'ADDRESS ),
  363.                p2 => system.unsigned_longword( length )
  364.              );
  365.  
  366.          IF (status /= 1) OR
  367.             (ios_block.status /= 1)
  368.          THEN
  369.              io_status := io_not_ok;
  370.          ELSE
  371.              io_status := io_ok;
  372.              data := temp_buffer(1);
  373.          END IF;
  374.     END low_level_get;
  375.  
  376.     TASK BODY terminal_reader_type IS
  377.     buffer : character;
  378.     status : status_enum;
  379.     BEGIN
  380.         ACCEPT go;
  381.         LOOP
  382.             low_level_get( buffer, status );
  383.             terminal_buffer.put( buffer, status );
  384.             IF status /= io_ok
  385.             THEN
  386.                 EXIT;
  387.             END IF;
  388.         END LOOP;
  389.     END terminal_reader_type;
  390.  
  391.     TASK BODY terminal_buffer_type IS
  392.     type_ahead_buffer : string( 1..255 );
  393.     type_ahead_buffer_length : natural := 0;
  394.     keep_going : boolean := true;
  395.     BEGIN
  396.         ACCEPT go;
  397.         WHILE keep_going
  398.         LOOP
  399.             SELECT
  400.  
  401.             WHEN type_ahead_buffer_length > 0 =>
  402.             ACCEPT get( data : OUT string; data_last : OUT natural ) DO
  403.                 data( data'FIRST..data'FIRST+type_ahead_buffer_length-1 ) :=
  404.                   type_ahead_buffer(1..type_ahead_buffer_length);
  405.                 data_last := data'FIRST+type_ahead_buffer_length-1;
  406.                 type_ahead_buffer_length := 0;
  407.             END get;
  408.  
  409.             OR
  410.  
  411.             ACCEPT put( data : IN character;
  412.                         io_status : IN status_enum ) DO
  413.                 IF io_status = io_ok
  414.                 THEN
  415.                     type_ahead_buffer_length := type_ahead_buffer_length + 1;
  416.                     type_ahead_buffer( type_ahead_buffer_length ) := data;
  417.                 ELSE
  418.                     keep_going := false;
  419.                 END IF;
  420.             END put;
  421.  
  422.             OR TERMINATE;
  423.  
  424.             END SELECT;
  425.         END LOOP;
  426.     END terminal_buffer_type;
  427.  
  428.     PROCEDURE get ( data : OUT string;
  429.                     last : OUT natural ) IS
  430.     BEGIN
  431.         terminal_buffer.get( data, last );
  432.     END get;
  433.  
  434.     PROCEDURE tcf_name ( name : OUT string;
  435.                          last : OUT natural ) IS
  436.     status : integer;
  437.     temp_buffer : string( 1..80 ) := string'( 1..80 => ' ' );
  438.     short_temp_length : short_integer;
  439.     integer_temp_length : integer;
  440.     ac_mode : integer;
  441.     BEGIN
  442.         trnlog( status, "TCF", short_temp_length, temp_buffer, 0, ac_mode );
  443.         integer_temp_length := integer( short_temp_length );
  444.         IF status /= 1
  445.         THEN
  446.             last := 0;
  447.         ELSE
  448.             name( name'FIRST..name'FIRST+integer_temp_length-1 ) := 
  449.                    temp_buffer( 1..integer_temp_length );
  450.             last := name'FIRST+integer_temp_length-1;
  451.         END IF;
  452.     END tcf_name;
  453.  
  454.  
  455.  
  456.     PROCEDURE  terminal_name ( name : OUT string;
  457.                                last : OUT natural ) IS
  458.     status : integer;
  459.     temp_buffer : string( 1..80 ) := string'( 1..80 => ' ' );
  460.     short_temp_length : short_integer;
  461.     integer_temp_length : integer;
  462.     ac_mode : integer;
  463.     BEGIN
  464.         trnlog( status, "TERM", short_temp_length, temp_buffer, 0, ac_mode );
  465.         integer_temp_length := integer( short_temp_length );
  466.         IF status /= 1
  467.         THEN
  468.             last := 0;
  469.         ELSE
  470.             name( name'FIRST..name'FIRST+integer_temp_length-1 ) := 
  471.                    temp_buffer( 1..integer_temp_length );
  472.             last := name'FIRST+integer_temp_length-1;
  473.         END IF;
  474.     END terminal_name;
  475.  
  476.     FUNCTION valid_character ( item : IN character ) RETURN boolean IS
  477.     BEGIN
  478.         CASE item IS
  479.             WHEN ascii.dc3 => RETURN false; -- xon
  480.             WHEN ascii.dc1 => RETURN false; -- xoff
  481.             WHEN OTHERS => RETURN true;
  482.         END CASE;
  483.     END valid_character;
  484.  
  485. END sysdep;
  486. ::::::::::
  487. decada_termsup.mar
  488. ::::::::::
  489.          $TTDEF
  490.          $TT2DEF
  491.  ; Data section
  492.  ;
  493.          .PSECT DATA,NOEXE,WRT
  494.  ; data used by Read routine
  495.  ;
  496.  MASK:   .LONG  ^X002000         ; Carriage return is terminator
  497.          .LONG  0
  498.          .QUAD  0
  499.  TERMDESC:
  500.          .LONG  16               ; Length to terminator descriptor
  501.          .LONG  MASK             ; Address of mask
  502.  DESCADD:.LONG  TERMDESC         ; Address of descriptor for terminator
  503.  ;
  504.  ; data used by terminal characteristic routines
  505.  ;
  506.  IOSTAT: .QUAD  0                      ; IO status block
  507.  ;
  508.  ; The terminal charasteristics are saved in the following 3 longwords
  509.  ; we will save these for resetting terminal when we are finished
  510.  ;
  511.  SAVETERM:
  512.          .BLKL  3
  513.  TERMIN: .BLKL  3                      ; terminal information for setmode
  514.  ;
  515.      .PSECT SETTERMINFO,EXE,NOWRT
  516.      .ENTRY SETTERMINFO,^M<>
  517.  ;
  518.  ;  From Ada..
  519.  ;
  520.  ;   FUNCTION setterminfo (chan : short_integer) RETURN integer;
  521.  ;   PRAGMA interface( MACRO, setterminfo );
  522.  ;   PRAGMA import_function( internal    =>     setterminfo,
  523.  ;                           parameter_types => (short_integer),
  524.  ;                           result_type =>     integer,
  525.  ;                           external =>        "SETTERMINFO" );
  526.  ; 
  527.  ; This function sets the appropriate characteristics for the terminal
  528.  ; associated with the channel.  If this channel is not connected to a terminal
  529.  ; an error status will be returned.
  530.  ;
  531.          $QIOW_S FUNC=#IO$_SENSEMODE,-; get current characteristics
  532.                  CHAN=@B^4(AP),-      ; channel is input to this routine
  533.                  IOSB=IOSTAT,-        ; return status in IO status block
  534.                  P1=SAVETERM,-        ; terminal characteristics
  535.                  P2=#12               ; size of terminal characteristics block
  536.          BLBS    R0,GOON2             ; check return status
  537.      JMP    ERR
  538.  GOON2:  MOVZWL  IOSTAT,R0            ; Move return status to R0
  539.      BLBS    R0,GOON1
  540.      JMP    ERR
  541.  ;
  542.  GOON1:  MOVQ    SAVETERM,TERMIN      ; copy terminal information into buffer
  543.          MOVL    SAVETERM+8,TERMIN+8  ; for set mode
  544.  ;
  545.  ; If other functions are desired, then find the symbol for them in
  546.  ; the VAX/VMS I/O User's Guide (Volume 1) in the section on terminal
  547.  ; driver.
  548.  ;
  549.          BISL2   #TT$M_NOECHO,TERMIN+4  ; set no echo
  550.          BISL2   #TT$M_HOSTSYNC,TERMIN+4 ; set XON/XOFF
  551.      BISL2    #TT$M_TTSYNC,TERMIN+4    ; 
  552.      BISL2    #TT$M_MECHFORM,TERMIN+4    ; 
  553.      BISL2    #TT2$M_PASTHRU,TERMIN+8
  554.  ;
  555.      BICL2    #TT$M_WRAP,TERMIN+4    ; no wrap at end of line
  556.          BICL2   #TT2$M_LOCALECHO,TERMIN+8 ; set no local echo
  557.          $QIOW_S FUNC=#IO$_SETMODE,-  ; perform set mode
  558.                  CHAN=@B^4(AP),-      ; channel is input to this routine
  559.                  IOSB=IOSTAT,-        ; return status in IO status block
  560.                  P1=TERMIN,-          ; terminal characteristics
  561.                  P2=#12               ; size of terminal characteristics block
  562.          BLBC    R0,ERR               ; check return status
  563.          MOVZWL  IOSTAT,R0            ; Move return status to R0
  564.          BLBC    R0,ERR               ; check return status
  565.  ERR:    RET
  566.  ; 
  567.      .PSECT RESETTERMINFO,EXE,NOWRT
  568.      .ENTRY RESETTERMINFO,^M<>
  569.  ;
  570.  ;  From Ada..
  571.  ;
  572.  ;   FUNCTION resetterminfo (chan : short_integer) RETURN integer;
  573.  ;   PRAGMA interface( MACRO, resetterminfo );
  574.  ;   PRAGMA import_function( internal    =>     resetterminfo,
  575.  ;                           parameter_types => (short_integer),
  576.  ;                           result_type =>     integer,
  577.  ;                           external =>        "RESETTERMINFO" );
  578.  ; 
  579.  ; This function resets the terminal to its original charasteritics.
  580.  ; If SetTermInfo was not called first then this routine will return a
  581.  ; error status. If the channel is not connected to a terminal
  582.  ; an error status will be returned.
  583.  ;
  584.          $QIOW_S FUNC=#IO$_SETMODE,-  ; perform set mode
  585.                  CHAN=@B^4(AP),-      ; channel is input to this routine
  586.                  IOSB=IOSTAT,-        ; return status in IO status block
  587.                  P1=SAVETERM,-        ; terminal characteristics
  588.                  P2=#12               ; size of terminal characteristics block
  589.          BLBC    R0,ERROR             ; check return status
  590.          MOVZWL  IOSTAT,R0            ; Move return status to R0
  591.          BLBC    R0,ERROR             ; check return status
  592.  ERROR:    RET
  593.  
  594.      .END
  595. ::::::::::
  596. dgade_sysdep_vt_spec.ada
  597. ::::::::::
  598. PACKAGE sysdep IS
  599.  
  600.     PROCEDURE open;
  601.     --
  602.     -- Open the console for binary I/O, no echo.
  603.     --
  604.  
  605.     PROCEDURE close;
  606.     --
  607.     -- Close the console.  Parameters should be reset to original condition.
  608.     --
  609.  
  610.     PROCEDURE put ( data : IN string );
  611.  
  612.     --
  613.     -- Put a string to the terminal.  There should be no translation of
  614.     -- the characters. There can be exceptions to this rule (like CTRL-S and
  615.     -- CTRL-Q)  and these exceptions must be identified in valid_character
  616.     -- below.
  617.     --
  618.  
  619.     PROCEDURE get ( data : OUT string;
  620.                     last : OUT natural );
  621.  
  622.     --
  623.     -- Get a string from the terminal keyboard.  This ocurrs with no echo
  624.     -- and no translations.
  625.     --
  626.  
  627.     PROCEDURE tcf_name ( name : OUT string;
  628.                          last : OUT natural );
  629.     --
  630.     -- Returns the name of the terminal capabilities file as a string.
  631.     -- You better pass in a string of sufficient length to handle the name
  632.     -- that is returned or you will get a constraint error.  80 is a good
  633.     -- random number.
  634.     --
  635.  
  636.     PROCEDURE  terminal_name ( name : OUT string;
  637.                                last : OUT natural );
  638.     --
  639.     -- Returns the name of the terminal.  This name of a string like "tv970".
  640.     -- If the name cannot be determined then last is returned as 0 (zero).
  641.     -- Again,  you better make the name parameter big enough to hold the
  642.     -- value returned.
  643.     --
  644.     -- A DG implementation note:  This procedure looks for a file called
  645.     -- TERM on your searchlist.
  646.     --
  647.  
  648.     FUNCTION valid_character ( item : IN character ) RETURN boolean;
  649.  
  650.     --
  651.     -- Returns a boolean value identifying whether the character passed in
  652.     -- is safe to use in the environment.  Suspicious characters include
  653.     -- CTRL-S  CTRL-Q  CTRL-C  CTRL-Y.
  654.  
  655. END sysdep;
  656. ::::::::::
  657. dgade_sysdep_vt_body.ada
  658. ::::::::::
  659. WITH tty_io,
  660.      text_io,
  661.      sys_calls,
  662.      file_definitions,
  663.      file_io,
  664.      bit_ops,
  665.      current_exception;
  666.  
  667. PACKAGE BODY sysdep IS
  668.  
  669.     buffer_byte_ptr : integer;
  670.     buffer : integer;
  671.  
  672.     invalid_chars_array : ARRAY( 1..2 ) OF character;
  673.  
  674.     terminal : file_definitions.channel_number;
  675.     tty : tty_io.file_type;
  676.  
  677.     previously_opened : boolean := false;
  678.  
  679.     temp_buffer_last : natural;
  680.  
  681.     PRAGMA page;
  682.     TASK tty_server IS
  683.         ENTRY go;
  684.         ENTRY start_get;
  685.         ENTRY get( data : OUT string;
  686.                    last : OUT natural );
  687.     END tty_server;
  688.  
  689.     TASK BODY tty_server IS
  690.         bytes_read : integer;
  691.         error_code : integer;
  692.     BEGIN
  693.         ACCEPT go;
  694.         LOOP
  695.             SELECT
  696.  
  697.                 ACCEPT start_get;
  698.                     file_io.read( terminal,
  699.                                   error_code,
  700.                                   bytes_read,
  701.                                   buffer_byte_ptr,
  702.                                   file_definitions.binary_io,
  703.                                   1 );
  704.                     buffer := bit_ops.logical_right_shift( buffer, 24 );
  705.  
  706.                 ACCEPT get( data : OUT string;
  707.                             last : OUT natural ) DO
  708.                     last := 1;
  709.                     data( 1 ) := character'val( buffer );
  710.                 END get;
  711.             OR
  712.  
  713.                 TERMINATE;
  714.  
  715.             END SELECT;
  716.         END LOOP;
  717.  
  718.     END tty_server;
  719.  
  720.  
  721.     PROCEDURE open IS
  722.     console_characteristics : file_io.device_characteristics;
  723.     error_code : integer;
  724.     ac0, ac1, ac2 : integer;
  725.     name : sys_calls.call_name;
  726.     error_id : sys_calls.error_code;
  727.     BEGIN
  728.  
  729.       IF NOT previously_opened
  730.       THEN
  731.  
  732.        tty_io.open( tty, tty_io.inout_file, "@console" );
  733.  
  734.        -- turn off the keyboard interrupt capabilities
  735.  
  736.        ac0 := 0;
  737.        ac1 := 0;
  738.        ac2 := 0;
  739.        name := sys_calls.kioff;
  740.        sys_calls.long_sys( name, ac0, ac1, ac2, error_id );
  741.  
  742.        file_io.open( "@console", terminal, error_code,
  743.                   file_definitions.open_for_input_output +
  744.                   file_definitions.binary_io +
  745.                   file_definitions.variable_length  );
  746.  
  747.        file_io.get_characteristics( terminal,
  748.                   console_characteristics, error_code );
  749.        console_characteristics.echo := file_io.no_echo;
  750.        console_characteristics.characteristics(
  751.                   file_io.non_ansi_standard_device ) := false;
  752.        file_io.set_characteristics( terminal,
  753.                   console_characteristics, error_code );
  754.  
  755.        buffer_byte_ptr := integer'val( buffer'address );
  756.        buffer_byte_ptr := bit_ops.left_shift_by_1( buffer_byte_ptr );
  757.  
  758.        tty_server.go;
  759.  
  760.        previously_opened := true;
  761.      END IF;
  762.  
  763.     END open;
  764.  
  765.     PROCEDURE close IS
  766.     error_code : integer;
  767.     BEGIN
  768.        -- lets not do anything and let AOS clean up after me.
  769. --     file_io.close( terminal, error_code );
  770.        NULL;
  771.     END close;
  772.  
  773.  
  774.     PROCEDURE put ( data : IN string ) IS
  775.     BEGIN
  776.        tty_io.put( tty, data );
  777.     END put;
  778.  
  779.     PROCEDURE get ( data : OUT string;
  780.                     last : OUT natural ) IS
  781.     BEGIN
  782.         tty_server.start_get;
  783.         tty_server.get( data, last );
  784.     END get;
  785.  
  786.  
  787.     PROCEDURE tcf_name ( name : OUT string;
  788.                          last : OUT natural ) IS
  789.     BEGIN
  790.        last := name'first+2;
  791.        name( name'first..(name'first)+2 ) := "TCF";
  792.     END tcf_name;
  793.  
  794.  
  795.     PROCEDURE  terminal_name ( name : OUT string;
  796.                                last : OUT natural ) IS
  797.        terminal_name_file : text_io.file_type;
  798.        line_buffer : string( 1..80 );
  799.        last_char_on_line : natural;
  800.     BEGIN
  801.        text_io.open( terminal_name_file, text_io.in_file, "TERM" );
  802.        text_io.reset(terminal_name_file);
  803.        text_io.get_line( terminal_name_file, line_buffer, last_char_on_line );
  804.        name( name'first..(name'first)+last_char_on_line-1 ) :=
  805.                                 line_buffer( 1..last_char_on_line );
  806.        last := name'first + last_char_on_line - 1;
  807.        text_io.close( terminal_name_file );
  808.     EXCEPTION
  809.        WHEN others => last := 0;
  810.     END terminal_name;
  811.  
  812.  
  813.     FUNCTION valid_character ( item : IN character ) RETURN boolean IS
  814.        valid_flag : boolean;
  815.     BEGIN
  816.        valid_flag := true;
  817.        FOR i IN 1..8
  818.        LOOP
  819.           IF invalid_chars_array( i )=item
  820.           THEN valid_flag := false;
  821.           END IF;
  822.        END LOOP;
  823.        RETURN valid_flag;
  824.     END valid_character;
  825.  
  826. BEGIN
  827.  
  828.     -- please refer to AOS/VS Programmer's Manual, Volume 1, System Concepts
  829.     -- page 5-20 for a description of these character codes.
  830.  
  831.     invalid_chars_array( 1 ) := ascii.dc3;  -- CTRL-S
  832.     invalid_chars_array( 2 ) := ascii.dc1;  -- CTRL-Q
  833.  
  834. END sysdep;
  835.