



		    NVT_device_.mexp                09/23/77  1035.2rew 09/22/77  1715.0      101178



"  ******************************************************
"  *                                                    *
"  *                                                    *
"  * Copyright (c) 1974 by Massachusetts Institute of   *
"  * Technology and Honeywell Information Systems, Inc. *
"  *                                                    *
"  *                                                    *
"  ******************************************************


          name      NVT_device_

" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
"
"      This data segment contains the character processing tables necessary for the Network
" Virtual Terminal interface on Multics.
"
" Originally created by D. M. Wells.
" last modified by D. M. Wells, April, 1976 while adding page length mode.
"
" The output entries may be declared as follows:
"
"      declare
"         1 output_entry aligned based,
"            2 horizontal_movement bit (5) unaligned,
"            2 vertical_movement bit (5) unaligned,
"            2 special_functions bit (3) unaligned,
"            2 entry_description bit (5) unaligned,         /* description of rest of word */
"            2 description_data bit (18) unaligned;
"
"
" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "

          &include  net_device_macros

" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
"
"      The following table describes the standard (default) Network Virtual Terminal
" Interface.
"

NVT_device_:        begin_table
          zero      output_normal-START,output_edited-START
          zero      0,output_format-START
          zero      0,0                               " padding info

          zero      input_normal-START,output_normal-START

          dec       130
          dec       0

          zero      0,0

          output    F_ascii_sequence,18/line_overflow_sequence-START
          output    F_exact_sequence,18/page_overflow_sequence-START

          vfd       a9/\,9/255,o9/0,o9/0
          vfd       o9/000,27/0

          oct       000000000000

line_overflow_sequence:
          vfd       9/3,o9/012,a18/\c

page_overflow_sequence:
          vfd       9/5,o9/015,o9/012,a27/EOP


input_normal:
          ignored_input_character      (000,001,002,003,004,005,006,007)
          input     000,010,0,H_bs,0                        " BS
          input     000,011,0,H_tab,0                       " HT
          input     000,012,0,H_cr+V_one,0                  " NL
          input     000,013,0,H_cr+V_tab+F_ignore,0         " VT
          input     000,014,0,H_cr+V_top+F_ignore,0         " NP
          input     000,015,CR_input_escapes-START,H_cr,0   " CR
          ignored_input_character                              (016,017)
          ignored_input_character      (020,021,022,023,024,025,026,027)
          ignored_input_character      (030,031,032,033,034,035,036,037)
          input     000,040,0,H_one,0                       " SP
          normal_input_character           (041,042,043,044,045,046,047)
          normal_input_character       (050,051,052,053,054,055,056,057)
          normal_input_character       (060,061,062,063,064,065,066,067)
          normal_input_character       (070,071,072,073,074,075,076,077)
          normal_input_character       (100,101,102,103,104,105,106,107)
          normal_input_character       (110,111,112,113,114,115,116,117)
          normal_input_character       (120,121,122,123,124,125,126,127)
          normal_input_character       (130,131,132,133,134,135,136,137)
          normal_input_character       (140,141,142,143,144,145,146,147)
          normal_input_character       (150,151,152,153,154,155,156,157)
          normal_input_character       (160,161,162,163,164,165,166,167)
          normal_input_character       (170,171,172,173,174,175,176)
          ignored_input_character                                  (177)
          ignored_input_character      (200,201,202,203,204,205,206,207)
          ignored_input_character      (210,211,212,213,214,215,216,217)
          ignored_input_character      (220,221,222,223,224,225,226,227)
          ignored_input_character      (230,231,232,233,234,235,236,237)
          ignored_input_character      (240,241,242,243,244,245,246,247)
          ignored_input_character      (250,251,252,253,254,255,256,257)
          ignored_input_character      (260,261,262,263,364,265,266,267)
          ignored_input_character      (270,271,272,273,274,275,276,277)
          ignored_input_character      (300,301,302,303,304,305,306,307)
          ignored_input_character      (310,311,312,313,314,315,316,317)
          ignored_input_character      (320,321,322,323,324,325,326,327)
          ignored_input_character      (330,331,332,333,334,335,336,337)
          ignored_input_character      (340,341,342,343,344,345,346,347)
          ignored_input_character      (350,351,352,353,354,355,356,357)
          ignored_input_character      (360,361,362,363,364,365,366,367)
          ignored_input_character      (370,371,372,373,374,375,376,377)

CR_input_escapes:
          dec       2
          escape_entry        000,015,H_cr
          escape_entry        012,012,H_cr+V_one

output_format:
          printing_character  040                           " SP
          printing_character  011                           " HT
          zero

          printing_character  010                           " BS
          zero
          output    H_cr+F_twochar,(o9/015,o9/000)                    " CR

          output    H_cr+V_one+F_twochar,(o9/015,o9/012)              "NL
          zero
          zero

          zero
          zero
          zero

          zero
          zero
          zero

          zero
          zero
          zero

          dec       0
          dec       0

output_normal:
          escape_in_octal    (000,001,002,003,004,005,006)
          output    S_audible+F_onechar,o9/007
          whitespace          (H_bs)
          whitespace          (H_tab)
          whitespace          (H_cr+V_one)
          output    H_cr+V_tab+F_exact_sequence,18/VT_chars-START
                                                            " 013o   11d  0Bh :: Vertical Tabulation
          output    H_cr+V_ff+F_exact_sequence,18/NP_chars-START                " NP
          whitespace          (H_cr)
          output    F_onechar,o9/000                        " RRS
          output    F_onechar,o9/000                        " BRS
          escape_in_octal    (020,021,022,023,024,025,026,027)
          escape_in_octal    (030,031,032,033,034,035,036,037)
          whitespace          (H_one)
          printing_character     (041,042,043,044,045,046,047)
          printing_character (050,051,052,053,054,055,056,057)
          printing_character (060,061,062,063,064,065,066,067)
          printing_character (070,071,072,073,074,075,076,077)
          printing_character (100,101,102,103,104,105,106,107)
          printing_character (110,111,112,113,114,115,116,117)
          printing_character (120,121,122,123,124,125,126,127)
          printing_character (130,131,132,133,134,135,136,137)
          printing_character (140,141,142,143,144,145,146,147)
          printing_character (150,151,152,153,154,155,156,157)
          printing_character (160,161,162,163,164,165,166,167)
          printing_character (170,171,172,173,174,175,176)
          output    F_onechar,o9/000                        " PAD
          escape_in_octal    (200,201,202,203,204,205,206,207)
          escape_in_octal    (210,211,212,213,214,215,216,217)
          escape_in_octal    (220,221,222,223,224,225,226,227)
          escape_in_octal    (230,231,232,233,234,235,236,237)
          escape_in_octal    (240,241,242,243,244,245,246,247)
          escape_in_octal    (250,251,252,253,254,255,256,257)
          escape_in_octal    (260,261,262,263,264,265,266,267)
          escape_in_octal    (270,271,272,273,274,275,276,277)
          escape_in_octal    (300,301,302,303,304,305,306,307)
          escape_in_octal    (310,311,312,313,314,315,316,317)
          escape_in_octal    (320,321,322,323,324,325,326,327)
          escape_in_octal    (330,331,332,333,334,335,336,337)
          escape_in_octal    (340,341,342,343,344,345,346,347)
          escape_in_octal    (350,351,352,353,354,355,356,357)
          escape_in_octal    (360,361,362,363,364,365,366,367)
          escape_in_octal    (370,371,372,373,374,375,376,377)

output_edited:
          ignore_output      (000,001,002,003,004,005,006)
          output    S_audible+F_onechar,o9/007
          whitespace          (H_bs)
          whitespace          (H_tab)
          whitespace          (H_cr+V_one)
          output    H_cr+V_tab+F_exact_sequence,18/VT_chars-START
          output    H_cr+V_ff+F_exact_sequence,18/NP_chars-START
          whitespace          (H_cr)
          output    F_onechar,o9/000                        " RRS
          output    F_onechar,o9/000                        " BRS
          ignore_output      (020,021,022,023,024,025,026,027)
          ignore_output      (030,031,032,033,034,035,036,037)
          whitespace          (H_one)
          printing_character     (041,042,043,044,045,046,047)
          printing_character (050,051,052,053,054,055,056,057)
          printing_character (060,061,062,063,064,065,066,067)
          printing_character (070,071,072,073,074,075,076,077)
          printing_character (100,101,102,103,104,105,106,107)
          printing_character (110,111,112,113,114,115,116,117)
          printing_character (120,121,122,123,124,125,126,127)
          printing_character (130,131,132,133,134,135,136,137)
          printing_character (140,141,142,143,144,145,146,147)
          printing_character (150,151,152,153,154,155,156,157)
          printing_character (160,161,162,163,164,165,166,167)
          printing_character (170,171,172,173,174,175,176)
          output    F_onechar,o9/000                        " PAD
          ignore_output      (200,201,202,203,204,205,206,207)
          ignore_output      (210,211,212,213,214,215,216,217)
          ignore_output      (220,221,222,223,224,225,226,227)
          ignore_output      (230,231,232,233,234,235,236,237)
          ignore_output      (240,241,242,243,244,245,246,247)
          ignore_output      (250,251,252,253,254,255,256,257)
          ignore_output      (260,261,262,263,264,265,266,267)
          ignore_output      (270,271,272,273,274,275,276,277)
          ignore_output      (300,301,302,303,304,305,306,307)
          ignore_output      (310,311,312,313,314,315,316,317)
          ignore_output      (320,321,322,323,324,325,326,327)
          ignore_output      (330,331,332,333,334,335,336,337)
          ignore_output      (340,341,342,343,344,345,346,347)
          ignore_output      (350,351,352,353,354,355,356,357)
          ignore_output      (360,361,362,363,364,365,366,367)
          ignore_output      (370,371,372,373,374,375,376,377)

VT_chars:
          vfd       9/3,o9/015,o9/000,o9/013

NP_chars:
          vfd       9/3,o9/015,o9/000,o9/014

          end_table

          end




		    NVT_tty33_device_.mexp          09/23/77  1035.2rew 09/22/77  1715.0      134118



"  ******************************************************
"  *                                                    *
"  *                                                    *
"  * Copyright (c) 1974 by Massachusetts Institute of   *
"  * Technology and Honeywell Information Systems, Inc. *
"  *                                                    *
"  *                                                    *
"  ******************************************************


          name      NVT_tty33_device_

" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
"
"      This data segment contains the character processing tables necessary for the Network
" Virtual Terminal interface on Multics.
"
" Originally created by D. M. Wells.
" Last modified by D. M. Wells, April, 1976, while adding page length mode.
" The output entries may be declared as follows:
"
"
"      declare
"         1 output_entry aligned based,
"            2 horizontal_movement bit (5) unaligned,
"            2 vertical_movement bit (5) unaligned,
"            2 special_functions bit (3) unaligned,
"            2 entry_description bit (5) unaligned,         /* description of rest of word */
"            2 description_data bit (18) unaligned;
"
"
" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "

          &include  net_device_macros

          define_fields                 " get the ALM declarations of the fields inserted

" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
"
"      The following table describes the terminal interface used if the "half-ASCII"
" (TTY33-like) mode is used.
"

NVT_tty33_device_:  begin_table
          zero      output_normal-START,output_edited-START
          zero      0,output_format-START
          zero      0,0                           " padding info

          zero      input_normal-START,output_normal-START

          dec       130
          dec       0

          zero      0,0

          output    F_ascii_sequence,18/line_overflow_sequence-START
          output    F_exact_sequence,18/page_overflow_sequence-START

          vfd       a9/\,9/255,o9/0,o9/0
          vfd       o9/000,27/0

          oct       000000000000

line_overflow_sequence:
          vfd       9/3,o9/012,a18/\c

page_overflow_sequence:
          vfd       9/5,o9/015,09/012,a27/EOP


input_normal:
          ignored_input_character      (000,001,002,003,004,005,006,007)
          input     000,010,0,H_bs,0
          input     000,011,0,H_tab,0                       " HT
          input     000,012,0,H_cr+V_one,0                  " NL
          input     000,013,0,H_cr+V_tab+F_ignore,0         " VT
          input     000,014,0,H_cr+V_top+F_ignore,0         " NP
          input     000,015,CR_input_escapes-START,H_cr,0   " CR
          ignored_input_character                              (016,017)
          ignored_input_character      (020,021,022,023,024,025,026,027)
          ignored_input_character      (030,031,032,033,034,035,036,037)
          input     000,040,0,H_one,0                       " SP
          normal_input_character           (041,042,043,044,045,046,047)
          normal_input_character       (050,051,052,053,054,055,056,057)
          normal_input_character       (060,061,062,063,064,065,066,067)
          normal_input_character       (070,071,072,073,074,075,076,077)
          normal_input_character       (100,141,142,143,144,145,146,147)
          normal_input_character       (150,151,152,153,154,155,156,157)
          normal_input_character       (160,161,162,163,164,165,166,167)
          normal_input_character       (170,171,172,133)
          input     000,134,backslash_input_escapes-START,H_one+S_visible,0
          normal_input_character                           (135,136,137)
          normal_input_character       (140,141,142,143,144,145,146,147)
          normal_input_character       (150,151,152,153,154,155,156,157)
          normal_input_character       (160,161,162,163,164,165,166,167)
          normal_input_character       (170,171,172,173,174,175,176)
          ignored_input_character                                  (177)
          ignored_input_character      (200,201,202,203,204,205,206,207)
          ignored_input_character      (210,211,212,213,214,215,216,217)
          ignored_input_character      (220,221,222,223,224,225,226,227)
          ignored_input_character      (230,231,232,233,234,235,236,237)
          ignored_input_character      (240,241,242,243,244,245,246,247)
          ignored_input_character      (250,251,252,253,254,255,256,257)
          ignored_input_character      (260,261,262,263,364,265,266,267)
          ignored_input_character      (270,271,272,273,274,275,276,277)
          ignored_input_character      (300,301,302,303,304,305,306,307)
          ignored_input_character      (310,311,312,313,314,315,316,317)
          ignored_input_character      (320,321,322,323,324,325,326,327)
          ignored_input_character      (330,331,332,333,334,335,336,337)
          ignored_input_character      (340,341,342,343,344,345,346,347)
          ignored_input_character      (350,351,352,353,354,355,356,357)
          ignored_input_character      (360,361,362,363,364,365,366,367)
          ignored_input_character      (370,371,372,373,374,375,376,377)

CR_input_escapes:
          dec       2
          escape_entry        000,015,H_cr
          escape_entry        012,012,H_cr+V_one

backslash_input_escapes:
          vfd       36/backslash_escape_count
          set       ESCAPE_COUNTER,0
          escape_entry        134,134
          escape_entry        101,101
          escape_entry        102,102
          escape_entry        103,103
          escape_entry        104,104
          escape_entry        105,105
          escape_entry        106,106
          escape_entry        107,107
          escape_entry        110,110
          escape_entry        111,111
          escape_entry        112,112
          escape_entry        113,113
          escape_entry        114,114
          escape_entry        115,115
          escape_entry        116,116
          escape_entry        117,117
          escape_entry        120,120
          escape_entry        121,121
          escape_entry        122,122
          escape_entry        123,123
          escape_entry        124,124
          escape_entry        125,125
          escape_entry        126,126
          escape_entry        127,127
          escape_entry        130,130
          escape_entry        131,131
          escape_entry        132,132
          escape_entry        055,010
          escape_entry        047,140
          escape_entry        050,173
          escape_entry        051,175
          escape_entry        041,174
          escape_entry        075,176
          set       backslash_escape_count,ESCAPE_COUNTER

output_format:
          printing_character  040                           " SP
          printing_character  011                           " HT
          zero

          printing_character  010                           " BS
          zero
          output    H_cr+F_twochar,(o9/015,o9/000)

          output    H_cr+V_one+F_twochar,(o9/015,o9/012)
          zero
          zero

          zero
          zero
          zero

          zero
          zero
          zero

          zero
          zero
          zero

          dec       0
          dec       0

output_normal:
          escape_in_octal    (000,001,002,003,004,005,006)
          output    S_audible+F_onechar,o9/007                        " BEL
          whitespace          (H_bs)
          whitespace          (H_tab)
          whitespace          (H_cr+V_one)
          output    H_cr+V_tab+F_exact_sequence,18/VT_tty33_chars-START
          output    H_cr+V_ff+F_exact_sequence,18/NP_tty33_chars-START
          whitespace          (H_cr)
          output    F_onechar,o9/000                        " RRS
          output    F_onechar,o9/000                        " BRS
          escape_in_octal    (020,021,022,023,024,025,026,027)
          escape_in_octal    (030,031,032,033,034,035,036,037)
          whitespace          (H_one)
          printing_character    (041,042,043,044,045,046,047)
          printing_character (050,051,052,053,054,055,056,057)
          printing_character (060,061,062,063,064,065,066,067)
          printing_character (070,071,072,073,074,075,076,077)
          printing_character (100)
          chars_in_data_field          134,141    " 101o   65d  41h :: A
          chars_in_data_field          134,142    " 102o   66d  42h :: B
          chars_in_data_field          134,143    " 103o   67d  43h :: C
          chars_in_data_field          134,144    " 104o   68d  44h :: D
          chars_in_data_field          134,145    " 105o   69d  45h :: E
          chars_in_data_field          134,146    " 106o   70d  46h :: F
          chars_in_data_field          134,147    " 107o   71d  47h :: G
          chars_in_data_field          134,150    " 110o   72d  48h :: H
          chars_in_data_field          134,151    " 111o   73d  49h :: I
          chars_in_data_field          134,152    " 112o   74d  4Ah :: J
          chars_in_data_field          134,153    " 113o   75d  4Bh :: K
          chars_in_data_field          134,154    " 114o   76d  4Ch :: L
          chars_in_data_field          134,155    " 115o   77d  4Dh :: M
          chars_in_data_field          134,156    " 116o   78d  4Eh :: N
          chars_in_data_field          134,157    " 117o   79d  4Fh :: O
          chars_in_data_field          134,160    " 120o   80d  40h :: P
          chars_in_data_field          134,161    " 121o   81d  51h :: Q
          chars_in_data_field          134,162    " 122o   82d  52h :: R
          chars_in_data_field          134,163    " 123o   83d  53h :: S
          chars_in_data_field          134,164    " 124o   84d  54h :: T
          chars_in_data_field          134,165    " 125o   85d  55h :: U
          chars_in_data_field          134,166    " 126o   86d  56h :: V
          chars_in_data_field          134,167    " 127o   87d  57h :: W
          chars_in_data_field          134,170    " 130o   88d  58h :: X
          chars_in_data_field          134,171    " 131o   89d  59h :: Y
          chars_in_data_field          134,172    " 132o   90d  5Ah :: Z
          printing_character             (133,134,135,136,137)
          chars_in_data_field          134,047    " 140o   96d  50h :: `
          printing_character     (101,102,103,104,105,106,107)
          printing_character (110,111,112,113,114,115,116,117)
          printing_character (120,121,122,123,124,125,126,127)
          printing_character (130,131,132)
          chars_in_data_field           134,050   " 173o  123d  7Bh :: [
          chars_in_data_field           134,041   " 174o  124d  7Ch :: \
          chars_in_data_field           134,051   " 175o  125d  7Dh :: ]
          chars_in_data_field           134,075   " 176o  126d  7Eh :: ^
          output    F_onechar,o9/000                        " PAD
          escape_in_octal    (200,201,202,203,204,205,206,207)
          escape_in_octal    (210,211,212,213,214,215,216,217)
          escape_in_octal    (220,221,222,223,224,225,226,227)
          escape_in_octal    (230,231,232,233,234,235,236,237)
          escape_in_octal    (240,241,242,243,244,245,246,247)
          escape_in_octal    (250,251,252,253,254,255,256,257)
          escape_in_octal    (260,261,262,263,264,265,266,267)
          escape_in_octal    (270,271,272,273,274,275,276,277)
          escape_in_octal    (300,301,302,303,304,305,306,307)
          escape_in_octal    (310,311,312,313,314,315,316,317)
          escape_in_octal    (320,321,322,323,324,325,326,327)
          escape_in_octal    (330,331,332,333,334,335,336,337)
          escape_in_octal    (340,341,342,343,344,345,346,347)
          escape_in_octal    (350,351,352,353,354,355,356,357)
          escape_in_octal    (360,361,362,363,364,365,366,367)
          escape_in_octal    (370,371,372,373,374,375,376,377)

output_edited:
          ignore_output      (000,001,002,003,004,005,006)
          output    S_audible+F_onechar,o9/007                        " BEL
          whitespace          (H_bs)
          whitespace          (H_tab)
          whitespace          (H_cr+V_one)
          output    H_cr+V_tab+F_exact_sequence,18/VT_tty33_chars-START
          output    H_cr+V_ff+F_exact_sequence,18/NP_tty33_chars-START
          whitespace          (H_cr)
          output    F_onechar,o9/000                        " RRS
          output    F_onechar,o9/000                        " BRS
          ignore_output      (020,021,022,023,024,025,026,027)
          ignore_output      (030,031,032,033,034,035,036,037)
          whitespace          (H_one)
          printing_character     (041,042,043,044,045,046,047)
          printing_character (050,051,052,053,054,055,056,057)
          printing_character (060,061,062,063,064,065,066,067)
          printing_character (070,071,072,073,074,075,076,077)
          printing_character (100,101,102,103,104,105,106,107)
          printing_character (110,111,112,113,114,115,116,117)
          printing_character (120,121,122,123,124,125,126,127)
          printing_character (130,131,132,133,134,135,136,137)
          printing_character (047,101,102,103,104,105,106,107)
          printing_character (110,111,112,113,114,115,116,117)
          printing_character (120,121,122,123,124,125,126,127)
          printing_character (130,131,132,050,041,051,075)
          output    F_onechar,o9/000                        " PAD
          ignore_output      (200,201,202,203,204,205,206,207)
          ignore_output      (210,211,212,213,214,215,216,217)
          ignore_output      (220,221,222,223,224,225,226,227)
          ignore_output      (230,231,232,233,234,235,236,237)
          ignore_output      (240,241,242,243,244,245,246,247)
          ignore_output      (250,251,252,253,254,255,256,257)
          ignore_output      (260,261,262,263,264,265,266,267)
          ignore_output      (270,271,272,273,274,275,276,277)
          ignore_output      (300,301,302,303,304,305,306,307)
          ignore_output      (310,311,312,313,314,315,316,317)
          ignore_output      (320,321,322,323,324,325,326,327)
          ignore_output      (330,331,332,333,334,335,336,337)
          ignore_output      (340,341,342,343,344,345,346,347)
          ignore_output      (350,351,352,353,354,355,356,357)
          ignore_output      (360,361,362,363,364,365,366,367)
          ignore_output      (370,371,372,373,374,375,376,377)

VT_tty33_chars:
          vfd       9/3,o9/015,o9/000,o9/013

NP_tty33_chars:
          vfd       9/3,o9/015,o9/000,o9/014

          end_table

          end




		    PNOTICE_network.alm             07/25/81  1205.9r w 07/25/81  1205.9        2853



	dec	1			"version 1 structure
	dec	1			"no. of pnotices
	dec	3			"no. of STIs
	dec	100			"lgth of all pnotices + no. of pnotices
          acc       "Copyright (c) 1972 by Massachusetts Institute of
Technology and Honeywell Information Systems, Inc."

	aci	"W1NETM090000"
	aci	"W2NETM090000"
	aci	"W3NETM090000"
	end




		    net_ascii_.alm                  09/23/77  1035.2rew 09/22/77  1715.0       11430



"          Compiled by Transfer Vector Compiler
"          Version of November 25, 1972
"          with parameters for "isc" transfer vectors.

          entry     net_ascii_module

net_ascii_module:
          cmpx6     0,du
          tmi       ..range_error
          cmpx6     15,du
          tmi       ..transfer_vector-0,6
..range_error:
          tra       <ios_>|[no_entry] 

..transfer_vector:
          tra       <net_ascii_dim_xtach_>|[net_ascii_attach] 
          tra       <net_ascii_dim_xtach_>|[net_ascii_detach] 
          tra       <net_ascii_dim_io_>|[net_ascii_read] 
          tra       <net_ascii_dim_io_>|[net_ascii_write] 
          tra       <net_ascii_dim_io_>|[net_ascii_abort] 
          tra       <net_ascii_dim_state_>|[net_ascii_order] 
          tra       <net_ascii_dim_io_>|[net_ascii_resetread] 
          tra       <net_ascii_dim_io_>|[net_ascii_resetwrite] 
          tra       ..range_error
          tra       <net_ascii_dim_state_>|[net_ascii_getsize] 
          tra       <net_ascii_dim_state_>|[net_ascii_setdelim] 
          tra       <net_ascii_dim_state_>|[net_ascii_getdelim] 
          tra       ..range_error
          tra       ..range_error
          tra       <net_ascii_dim_state_>|[net_ascii_changemode] 

          end




		    net_ascii_dim_io_.pl1           09/23/77  1035.2rew 09/22/77  1715.0      394911



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1972 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

net_ascii_dim_io_:
          procedure ();

/*             "net_ascii_dim_io_" -- Network typewriter interface for the user process.  */
/*        This code is based on the user ring typewriter DIM.                   */

/*        Last modified by D. M. Wells Feb, 1972 to fix various bugs in format control.             */
/*        Last modified by D. M. Wells, March, 1976, while changing handling of machine conditions. */
/*        Last modified by D. M. Wells, and D. P. Reed, Oct. 1976, to add       */
/*             suppress GoAhead and to use ncp_ interfaces.                     */

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          (bv_nelem fixed binary (24),                      /* num of elements requested to be transmitted    */
          bv_nelemt fixed binary (24),                      /* num of elements actually transmitted           */
          bv_offset fixed binary (24),                      /* offset of first char within workspace          */
          bv_continue_switch bit (1) aligned,
          bv_condition_name character (*),
          bv_mc_ptr pointer,
          bv_crawlout_ptr pointer,
          bv_SDB_ptr pointer,                               /* pointer to the SDB for this attachment         */
          bv_wksp_ptr pointer)                              /* pointer to input workspace                     */
               parameter;

    declare
          1 bv_status aligned parameter like status_template;

     declare
          1 bv_old_status aligned parameter like status_template;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          have_machine_conditions bit (1) initial ("0"b)
               automatic;

     declare
          (state fixed binary (6),
          connection_state fixed binary (6) initial (6),
          (first_input, last_input, next_input) fixed binary (24),
          (buffer_allocation_size, next_output, num_output) fixed binary (24),
          (n8, next_out, xnt) fixed binary (24),
          timeout_time fixed binary (71),
          have_shipped_GA bit (1),
          err_code bit (36) aligned,
          delimiter_array (0 : 511) bit (1) unaligned,
          buffer2 (0 : 999) character (1) unaligned,
          (temp_ptr, wksp_ptr) pointer)
               automatic;

     declare
          1 event_message aligned automatic,
             2 channel_name fixed binary (71),
             2 message fixed binary (71),
             2 sender bit (36) aligned,
             2 origin unaligned,
                3 devsignal fixed binary (17) unaligned,
                3 ring fixed binary (17) unaligned,
             2 channel_index fixed binary (17);

     declare
	1 dummy_status aligned automatic like status_template;

          /* * * * * DEFINED REFERENCES  * * * * * * * * * */

     declare
          1 SDB aligned like SDB_template defined (bv_SDB_ptr -> SDB_template);

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
          based_area area
                         based;

     declare
          1 based_workspace aligned based,
             2 byte (0 : 1) bit (9) unaligned;

     declare
          1 byte_buffer aligned based,
             2 header like byte_buffer_header,
             2 workspace aligned,
                3 byte (0 : buffer_allocation_size refer (byte_buffer.header.buffer_bound)) bit (9) unaligned;

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
          enable_mask bit (36) aligned initial (""b)
               internal static options (constant);

     declare
          OPEN_STATE initial (6)
               fixed binary (6) internal static options (constant);

     declare
         (IAC_DM (2) initial ("011111111"b, "011110010"b),            /* TELNET Data Mark (255, 242)          */
          IAC_GA (2) initial ("011111111"b, "011111001"b))            /* TELNET Go Ahead (255, 249)           */
               bit (9) internal static options (constant);

          /* * * * * EXTERNAL STATIC DECLARATIONS  * * * * */

     declare
          (error_table_$area_too_small,
          error_table_$invalid_read,
          error_table_$invalid_write,
          error_table_$ips_has_occurred,
          error_table_$net_invalid_state)                   /* means we got a bad state from hardcore NCP     */
               bit (36) aligned external static;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          net_canonicalize_ constant entry (ptr, ptr, fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          clock_ constant entry () returns (fixed bin (71)),
          get_system_free_area_ constant entry () returns (ptr),
          hcs_$set_ips_mask constant entry (bit (36) aligned, bit (36) aligned),
          ipc_$block constant entry (ptr, ptr, bit (36) aligned),
          ncp_$discard_buffered_data constant entry (fixed bin (12), fixed bin (6), bit (36) aligned),
          ncp_$send_interrupt constant entry (fixed bin (12), fixed bin (6), bit (36) aligned),
          net_$ncp_read constant entry (fixed bin (12), ptr, fixed bin (24), fixed bin (24), fixed bin (6), bit (36) aligned),
          net_$ncp_write constant entry (fixed bin (12), ptr, fixed bin (24), fixed bin (24), fixed bin (6), bit (36) aligned),
          net_ascii_dim_state_$net_ascii_order constant entry (ptr, char (*), ptr, 1 aligned like status_template),
          net_convert_bytesize_$direct_8_to_9 constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), bit (36) aligned),
          net_convert_bytesize_$direct_9_to_8 constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          net_convert_bytesize_$telnet_8_to_9 constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          net_convert_bytesize_$telnet_9_to_8 constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          net_convert_input_ constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          net_convert_output_ constant entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned),
          net_telnet_interpreter_ constant entry (ptr, ptr, bit (36) aligned),
          signal_ constant entry (char (*), ptr, ptr, ptr),
          timer_manager_$alarm_wakeup constant entry (fixed bin (71), bit (2), fixed bin (71)),
          timer_manager_$reset_alarm_wakeup constant entry (fixed bin (71));

     declare
          (addr, binary, bit, dimension, hbound, lbound, min, null, string, unspec)
               builtin;

          /* * * * * STACK REFERENCES  * * * * * * * * * * */

     declare
         net_ascii_ipc_error_
               condition;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include mc;
          % include net_ascii_dim_sdb_dcls;
          % include net_status_template;
          % include static_handlers;
          % include telnet_options;
          % include telnet_special_chars;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_write_raw:                                        /* internal entry to write without processing     */
          entry (bv_SDB_ptr, bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, bv_status);

          string (bv_status) = ""b;

          next_output = bv_offset;
          num_output = bv_nelem;

          do while ((num_output > 0) | (SDB.output_buffer.num_bytes > 0));
               call write_to_ncp (bv_wksp_ptr, next_output, num_output, xnt, "0"b, err_code);
	     if err_code ^= ""b
	     then goto return_from_write;
               next_output = next_output + xnt;
               num_output = num_output - xnt;

               if (SDB.output_buffer.num_bytes > 0)
               then do;
                    call block_for_write ();

                    call net_ascii_dim_state_$net_ascii_order (addr (SDB), "start", null (), bv_status);
                    end;
               end;

          bv_nelemt = bv_nelem;

          string (bv_status) = ""b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_write:                                            /* entry to write on typewriter                   */
          entry (bv_SDB_ptr, bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, bv_status);

          string (bv_status) = ""b;                         /* initialize status code to zero                 */

          bv_nelemt = 0;

          if SDB.w_ncp_idx = -1 then do;
               err_code = error_table_$invalid_write;
               goto return_from_write;
               end;

          wksp_ptr = bv_wksp_ptr;

          if SDB.current_terminal_state.aborting_output
          then do;
               bv_nelemt = bv_nelem;
               err_code = ""b;
               goto return_from_write;
               end;

          if SDB.current_modes.rawo
          then do;
               next_output = bv_offset;
               num_output = bv_nelem;

               do while ((num_output > 0) | (SDB.output_buffer.num_bytes > 0));
                    call write_to_ncp (wksp_ptr, next_output, num_output, xnt, (SDB.do_telnet), err_code);
		if err_code ^= ""b
		then goto return_from_write;
                    next_output = next_output + xnt;
                    num_output = num_output - xnt;

                    if (SDB.output_buffer.num_bytes > 0)
                    then call block_for_write ();
                    end;
               end;
          else do;
               first_input = bv_offset;
               next_input = first_input;
               last_input = first_input + bv_nelem - 1;
               next_out = lbound (buffer2, 1);

               do while (next_input <= last_input);
		if SDB.device_state.in_page_wait
                    then do;
                         string (delimiter_array) = ""b;
                         delimiter_array (12) = "1"b;

		     do while (SDB.device_state.in_page_wait);
                              if detected_a_break_condition (xnt, err_code)
                              then do;
                                   if err_code ^= ""b
                                   then goto return_from_write;

                                   SDB.rawbuffer_ptr -> byte_buffer.byte (SDB.rawbuffer_ptr -> byte_buffer.byte_offset + xnt - 1) = OUR_NOP;
                                   SDB.device_state.actual_line = 0;
                                   SDB.device_state.desired_line = 0;
                                   SDB.device_state.in_page_wait = "0"b;
                                   end;

                              if err_code ^= ""b
                              then goto return_from_write;

                              if SDB.device_state.in_page_wait
                              then call block_for_read ();
                              end;
                         call net_ascii_dim_state_$net_ascii_order (bv_SDB_ptr, "start", null (), bv_status);
                         end;

                    call net_convert_output_ (addr (SDB.device_state), wksp_ptr, next_input, last_input,
                              addr (buffer2), next_out, hbound (buffer2, 1), err_code);
                    if err_code ^= ""b
                    then goto return_from_write;

                    next_output = lbound (buffer2, 1);
                    num_output = next_out;

                    do while ((num_output > 0) | (SDB.output_buffer.num_bytes > 0));
                         call write_to_ncp (addr (buffer2), next_output, num_output, xnt, (SDB.do_telnet), err_code);
		     if err_code ^= ""b
		     then goto return_from_write;
                         next_output = next_output + xnt;
                         num_output = num_output - xnt;

                         if SDB.output_buffer.num_bytes > 0
                         then call block_for_write ();
                         end;

                    next_out = lbound (buffer2, 1);
                    bv_nelemt = next_input - first_input;
                    end;
               end;

          bv_nelemt = bv_nelem;

          string (bv_status.trans_state) = "11101"b;        /* return I/O completion indicators               */

          return;

return_from_write:
          bv_status.error_code = err_code;
          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_read_no_block:                                    /* entry to read from typewriter, but never block */
          entry (bv_SDB_ptr, bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, bv_status);

          string (bv_status) = ""b;
          err_code = ""b;

          SDB.current_terminal_state.aborting_output = "0"b;

          bv_nelemt = 0;

          if SDB.r_ncp_idx = -1
          then do;
               err_code = error_table_$invalid_read;
               goto return_from_read;
               end;

          have_shipped_GA = (^ SDB.protocol_495);

          call read_from_network (bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, err_code);
	if err_code ^= ""b
	then goto return_from_read;
          if bv_nelemt = 0
          then do;
               if SDB.string_ptr = null ()
               then do;
                    if (^ have_shipped_GA) & (SDB.do_telnet) & (^SDB.option_in_effect (TRANSMIT).option(OPTION_suppress_ga)) /* may change as time goes on */
                    then call net_ascii_write_raw (bv_SDB_ptr, addr (IAC_GA), 0, 2, (0), bv_status);
                    have_shipped_GA = "1"b;
                    end;
               end;

          string (bv_status.trans_state) = "11111"b;
          if SDB.string_ptr = null ()
          then bv_status.successful_physical_completion = "0"b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_read:                                             /* entry to read from typewriter                  */
          entry (bv_SDB_ptr, bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, bv_status);

          string (bv_status) = ""b;                         /* initialize status code to zero                 */
          err_code = ""b;
          SDB.current_terminal_state.aborting_output = "0"b;

          bv_nelemt = 0;                                    /* initialize elements transferred to zero        */

          if SDB.r_ncp_idx = -1 then do;
               err_code = error_table_$invalid_read;
               goto return_from_read;
               end;

          have_shipped_GA = ^ SDB.protocol_495;

          do while (bv_nelemt = 0);
               call read_from_network (bv_wksp_ptr, bv_offset, bv_nelem, bv_nelemt, err_code);
	     if err_code ^= ""b
	     then goto return_from_read;
               if bv_nelemt = 0
               then do;
                    if (^ have_shipped_GA) & (SDB.do_telnet) & (^ SDB.option_in_effect (TRANSMIT).option(OPTION_suppress_ga))
                    then do;
                         call net_ascii_write_raw (bv_SDB_ptr, addr (IAC_GA), 0, 2, (0), bv_status);
                         have_shipped_GA = "1"b;
                         end;
                    else do;
                         call block_for_read ();
                         end;
                    end;
               end;

return_from_read:
          SDB.current_terminal_state.aborting_output = "0"b;
          string (bv_status.trans_state) = "11111"b;
          bv_status.error_code = err_code;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_resetread:                                        /* entry to reset read-ahead data                 */
          entry (bv_SDB_ptr, bv_status);

          string (bv_status) = ""b;

          if SDB.r_ncp_idx = -1 then do;
               err_code = error_table_$invalid_read;
               goto abort_err;
               end;

                                                  /*      In order to do a resetread, while also remembering  */
                                                  /* to process any telnet control that comes through, we     */
                                                  /* will simply read until we don't get anything.  In order  */
                                                  /* to get all such characters, however, we will set all     */
                                                  /* characters as break characters.                          */

          string (delimiter_array) = ""b;
          string (delimiter_array) = ^ string (delimiter_array);

          do while (detected_a_break_condition (next_input, err_code));
               temp_ptr = SDB.rawbuffer_ptr;

               temp_ptr -> byte_buffer.byte_offset = temp_ptr -> byte_buffer.byte_offset + next_input;
               temp_ptr -> byte_buffer.num_bytes = temp_ptr -> byte_buffer.num_bytes - next_input;
               end;
	if err_code ^= ""b
	then goto return_from_read;

          if SDB.string_ptr ^= null ()
          then do;
               free SDB.string_ptr -> byte_buffer in (SDB.area_ptr -> based_area);
               SDB.string_ptr = null ();
               end;

          string (bv_status) = ""b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_resetwrite:                                       /* entry to reset write-behind buffers            */
          entry (bv_SDB_ptr, bv_status);

          string (bv_status) = ""b;

          SDB.current_terminal_state.aborting_output = "0"b;

          if SDB.w_ncp_idx = -1 then do;
               err_code = error_table_$invalid_write;
               goto abort_err;
               end;

          if SDB.protocol_495
          then do;
               call net_ascii_write_raw (bv_SDB_ptr, addr (IAC_DM), 0, 2, (0), bv_status);
               call ncp_$send_interrupt (SDB.w_ncp_idx, (0), err_code);
               end;
          else do;
               call ncp_$discard_buffered_data (SDB.w_ncp_idx, state, err_code);
               if (err_code ^= ""b) | (state ^= OPEN_STATE) then goto abort_err;
               end;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_abort:                                            /* entry to reset read, write and quit conditions */
          entry (bv_SDB_ptr, bv_old_status, bv_status);


          call net_ascii_resetwrite (bv_SDB_ptr, bv_status);

          call net_ascii_resetread (bv_SDB_ptr, bv_status);

          string (bv_status) = ""b;

          return;

abort_err:
          if err_code ^= ""b
          then bv_status.error_code = err_code;
          else bv_status.error_code = error_table_$net_invalid_state;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_signal_handler:
          entry (bv_mc_ptr, bv_condition_name, bv_SDB_ptr, bv_crawlout_ptr, bv_continue_switch);

          have_machine_conditions = "1"b;

          if bv_mc_ptr ^= null ()
          then bv_mc_ptr -> mc.fcode = bit (binary (quit_sct_index, 17));

          if ^ SDB.protocol_495
          then do;
               if SDB.allow_quits
               then call signal_ ("quit", bv_mc_ptr, null (), bv_crawlout_ptr);
               return;
               end;

          timeout_time = clock_ () + 1000000 * SDB.timeout_value;

          call timer_manager_$alarm_wakeup (timeout_time, "00"b, SDB.read_event_channel);

          string (delimiter_array) = ""b;
          delimiter_array (binary (OUR_DM, 9)) = "1"b;

          do while (^ detected_a_break_condition (next_input, err_code));
	     if err_code ^= ""b
	     then return;
               if clock_ () > timeout_time
               then return;

               call block_for_read ();
               end;

          call net_ascii_dim_state_$net_ascii_order (addr (SDB), "start", null (), dummy_status);

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

write_to_ncp:
          procedure (bv_buff_ptr, bv_first_offset, bv_num_elements, bv_num_elements_proc, bv_external_data, bv_err_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          ((bv_first_offset, bv_num_elements, bv_num_elements_proc) fixed binary (24),
          bv_external_data bit (1) aligned,
	bv_err_code bit (36) aligned,
          bv_buff_ptr pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          ((first_loc, indx, next_free_loc, num_free_locs, num_transmitted) fixed binary (24),
          previous_mask bit (36) aligned,
          buffer_ptr pointer,
          transfer_proc variable entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned))
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          first_loc = bv_first_offset;
          buffer_ptr = bv_buff_ptr;

          if bv_external_data
          then transfer_proc = net_convert_bytesize_$telnet_9_to_8;
          else transfer_proc = net_convert_bytesize_$direct_9_to_8;

          call hcs_$set_ips_mask (enable_mask, previous_mask);

          if SDB.output_buffer.num_bytes = 0
          then SDB.output_buffer.byte_offset = 0;

          next_free_loc = SDB.output_buffer.byte_offset + SDB.output_buffer.num_bytes;
          indx = first_loc;

          call transfer_proc (null (), buffer_ptr, indx, bv_num_elements + first_loc - 1,
                    addr (SDB.output_buffer.byte8), next_free_loc, SDB.output_buffer.buffer_bound, bv_err_code);

          bv_num_elements_proc = indx - first_loc;
          SDB.output_buffer.num_bytes = next_free_loc - SDB.output_buffer.byte_offset;

          call net_$ncp_write (SDB.w_ncp_idx, addr (SDB.output_buffer.byte8 (SDB.output_buffer.byte_offset)),
                    SDB.output_buffer.num_bytes, num_transmitted, state, bv_err_code);
          if state ^= 6
          then connection_state = 1;                        /* connection has been closed                     */
          SDB.output_buffer.byte_offset = SDB.output_buffer.byte_offset + num_transmitted;
          SDB.output_buffer.num_bytes = SDB.output_buffer.num_bytes - num_transmitted;

          call hcs_$set_ips_mask (previous_mask, ((36)"0"b));

	if bv_err_code ^= ""b
	then return;

          return;

end write_to_ncp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

block_for_write:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          1 ipc_event_list aligned automatic,
             2 num_chans fixed binary (17),
             2 event_channel fixed binary (71);

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          call timer_manager_$alarm_wakeup ((6 * SDB.timeout_value), "11"b, SDB.write_event_channel);

          ipc_event_list.num_chans = 1;
          ipc_event_list.event_channel = SDB.write_event_channel;

          call ipc_$block (addr (ipc_event_list), addr (event_message), err_code);
          if err_code ^= ""b
	then signal net_ascii_ipc_error_;

          call timer_manager_$reset_alarm_wakeup (SDB.write_event_channel);

          return;

end block_for_write;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

block_for_read:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          1 ipc_event_list aligned automatic,
             2 num_chans fixed binary (17),
             2 event_channel fixed binary (71);

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          ipc_event_list.num_chans = 1;
          ipc_event_list.event_channel = SDB.read_event_channel;

          call ipc_$block (addr (ipc_event_list), addr (event_message), err_code);
          if err_code ^= ""b
	then signal net_ascii_ipc_error_;

          return;

end block_for_read;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

read_from_network:
          procedure (bv_buffer_ptr, bv_first_offset, bv_num_elements, bv_num_elements_trans, bv_err_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          ((bv_first_offset, bv_num_elements, bv_num_elements_trans) fixed binary (24),
	bv_err_code bit (36) aligned,
          bv_buffer_ptr pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          ((first_offset, num_elements, num_to_read) fixed binary (24),
          (ext_buffer_ptr, ext_wksp_ptr, read_ptr, wksp_ptr) pointer)
               automatic;

     declare
          1 internal_buffer aligned automatic,
             2 header like byte_buffer_header,
             2 workspace aligned,
                3 byte (0 : 255) bit (9) unaligned;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

	bv_err_code = ""b;

          wksp_ptr = bv_buffer_ptr;

          if SDB.string_ptr ^= null ()
          then do;
               ext_buffer_ptr = SDB.string_ptr;
               ext_wksp_ptr = addr (ext_buffer_ptr -> byte_buffer.byte);

               num_elements = min (bv_num_elements, ext_buffer_ptr -> byte_buffer.num_bytes);

               call copy_byte_array (addr (ext_wksp_ptr -> based_workspace.byte (ext_buffer_ptr -> byte_buffer.byte_offset)), addr (wksp_ptr -> based_workspace.byte (bv_first_offset)), num_elements);

               ext_buffer_ptr -> byte_buffer.num_bytes = ext_buffer_ptr -> byte_buffer.num_bytes - num_elements;
               ext_buffer_ptr -> byte_buffer.byte_offset = ext_buffer_ptr -> byte_buffer.byte_offset + num_elements;

               if ext_buffer_ptr -> byte_buffer.num_bytes <= 0
               then do;
                    SDB.string_ptr = null ();

                    free ext_buffer_ptr -> byte_buffer in (SDB.area_ptr -> based_area);
                    end;

               bv_num_elements_trans = num_elements;
               return;
               end;

          internal_buffer.header.info.area_ptr = null ();
          internal_buffer.header.info.lock_word = ""b;
          internal_buffer.header.buffer_bound = hbound (internal_buffer.workspace.byte, 1);
          internal_buffer.header.byte_offset = 0;
          internal_buffer.header.num_bytes = 0;
          read_ptr = addr (internal_buffer);

          err_code = error_table_$area_too_small;
          do while (err_code = error_table_$area_too_small);
               call read_from_telnet_interpreter (read_ptr, err_code);
               if err_code = error_table_$area_too_small
               then call make_bigger_buffer (read_ptr);
               end;

          if err_code ^= ""b
          then do;
               bv_err_code = err_code;
               return;
               end;

          if read_ptr -> byte_buffer.num_bytes = 0
          then do;
               bv_num_elements_trans = 0;
               bv_err_code = ""b;
               return;
               end;

          wksp_ptr = bv_buffer_ptr;
          first_offset = bv_first_offset;
          num_to_read = bv_num_elements;

          call copy_to_user_buffer (wksp_ptr, first_offset, num_to_read, num_elements, err_code);
          if err_code = ""b
          then do;
               do n8 = first_offset by 1 to first_offset + num_elements - 1
                         while (^ SDB.read_delim_chars.delim (binary (wksp_ptr -> based_workspace.byte (n8), 9)));
                    end;
               if n8 = first_offset + num_elements - 1
               then do;
                    bv_num_elements_trans = num_elements;

                    call delete_buffer (read_ptr);

                    return;
                    end;
               if n8 > first_offset + num_elements - 1      /* if there is no read delimiter,                 */
               then if connection_state ^= 6                /* then if the connection has been closed         */
                    then do;
                         bv_num_elements_trans = num_elements;
                         call delete_buffer (read_ptr);
                         return;
                         end;
               end;

          ext_buffer_ptr = null ();

          err_code = error_table_$area_too_small;
          do while (err_code = error_table_$area_too_small);
               call make_bigger_buffer (ext_buffer_ptr);

               call copy_to_user_buffer (addr (ext_buffer_ptr -> byte_buffer.byte), ext_buffer_ptr -> byte_buffer.byte_offset, ext_buffer_ptr -> byte_buffer.buffer_bound - ext_buffer_ptr -> byte_buffer.num_bytes, num_elements, err_code);
               end;

          if err_code ^= ""b
	then do;
	     bv_err_code = err_code;
	     return;
	     end;

          ext_buffer_ptr -> byte_buffer.num_bytes = ext_buffer_ptr -> byte_buffer.num_bytes + num_elements;

          do n8 = ext_buffer_ptr -> byte_buffer.byte_offset by 1 to ext_buffer_ptr -> byte_buffer.byte_offset + ext_buffer_ptr -> byte_buffer.num_bytes - 1
                    while (^ SDB.read_delim_chars.delim (binary (ext_buffer_ptr -> byte_buffer.byte (n8), 9)));
               end;

          if n8 > ext_buffer_ptr -> byte_buffer.byte_offset + ext_buffer_ptr -> byte_buffer.num_bytes - 1
          then return;

          num_elements = n8 - ext_buffer_ptr -> byte_buffer.byte_offset + 1;

          SDB.string_ptr = ext_buffer_ptr;

          num_elements = min (num_elements, bv_num_elements);

          wksp_ptr = bv_buffer_ptr;
          call copy_byte_array (addr (ext_buffer_ptr -> byte_buffer.byte (ext_buffer_ptr -> byte_buffer.byte_offset)), addr (wksp_ptr -> based_workspace.byte (bv_first_offset)), num_elements);

          ext_buffer_ptr -> byte_buffer.num_bytes = ext_buffer_ptr -> byte_buffer.num_bytes - num_elements;
          ext_buffer_ptr -> byte_buffer.byte_offset = ext_buffer_ptr -> byte_buffer.byte_offset + num_elements;

          bv_num_elements_trans = num_elements;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

copy_to_user_buffer:
          procedure (bv_to_ptr, bv_to_offset, bv_num_to_read, bv_num_read, bv_error_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         ((bv_num_read, bv_num_to_read, bv_to_offset) fixed binary (24),
          bv_error_code bit (36) aligned,
          bv_to_ptr pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS * * * * */

     declare
         ((from_count, from_offset) fixed binary (24),
          dont_call_canonicalizer bit (1),
          from_ptr pointer)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          dont_call_canonicalizer = "0"b;

          if SDB.rawi
          then dont_call_canonicalizer = "1"b;

          if (^ SDB.can) & (^ SDB.erkl) & (^ SDB.esc) & (^ SDB.half)
          then dont_call_canonicalizer = "1"b;

          from_ptr = addr (read_ptr -> byte_buffer.byte);
          from_offset = read_ptr -> byte_buffer.byte_offset;
          from_count = read_ptr -> byte_buffer.num_bytes;

          if dont_call_canonicalizer
          then do;
               if from_count > bv_num_to_read
               then do;
                    bv_num_read = 0;
                    bv_error_code = error_table_$area_too_small;

                    return;
                    end;

               call copy_byte_array (addr (from_ptr -> based_workspace.byte (from_offset)), addr (bv_to_ptr -> based_workspace.byte (bv_to_offset)), from_count);

               bv_num_read = from_count;

               bv_error_code = ""b;
               return;
               end;

          call net_canonicalize_ (addr (SDB.canon_info), addr (from_ptr -> based_workspace.byte (from_offset)), from_count,
                    addr (bv_to_ptr -> based_workspace.byte (bv_to_offset)), bv_num_to_read, bv_num_read, bv_error_code);

          return;

end copy_to_user_buffer;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end read_from_network;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

read_from_telnet_interpreter:
          procedure (bv_read_ptr, bv_error_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_error_code bit (36) aligned,
          bv_read_ptr pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          (auto_byte_offset, raw_buff_count, read_byte_offset) fixed binary (24)
               automatic;

     declare
          1 temp_device_state automatic aligned like device_state_template;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          string (delimiter_array) = string (bv_SDB_ptr -> SDB_template.break_chars.break);

          do while (bv_read_ptr -> byte_buffer.num_bytes = 0);
               if (^ detected_a_break_condition (raw_buff_count, bv_error_code))
               then return;

               read_byte_offset = bv_read_ptr -> byte_buffer.byte_offset + bv_read_ptr -> byte_buffer.num_bytes;
               auto_byte_offset = SDB.rawbuffer_ptr -> byte_buffer.byte_offset;

               unspec (temp_device_state) = unspec (bv_SDB_ptr -> SDB_template.device_state);

               call net_convert_input_ (addr (temp_device_state), addr (SDB.rawbuffer_ptr -> byte_buffer.byte),
                         auto_byte_offset, SDB.rawbuffer_ptr -> byte_buffer.byte_offset + raw_buff_count - 1,
                         addr (bv_read_ptr -> byte_buffer.byte), read_byte_offset, bv_read_ptr -> byte_buffer.buffer_bound, bv_error_code);
	     if bv_error_code ^= ""b
	     then return;

               if auto_byte_offset ^= SDB.rawbuffer_ptr -> byte_buffer.byte_offset + raw_buff_count
               then do;
                    bv_error_code = error_table_$area_too_small;
                    return;
                    end;

               unspec (bv_SDB_ptr -> SDB_template.device_state.terminal_state) = unspec (temp_device_state.terminal_state);

               SDB.rawbuffer_ptr -> byte_buffer.byte_offset = SDB.rawbuffer_ptr -> byte_buffer.byte_offset + raw_buff_count;
               SDB.rawbuffer_ptr -> byte_buffer.num_bytes = SDB.rawbuffer_ptr -> byte_buffer.num_bytes - raw_buff_count;

               bv_read_ptr -> byte_buffer.num_bytes = read_byte_offset - bv_read_ptr -> byte_buffer.byte_offset;
               end;

          bv_error_code = ""b;

          return;

end read_from_telnet_interpreter;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

detected_a_break_condition:
          procedure (bv_raw_count, bv_error_code) returns (bit (1) aligned);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_raw_count fixed binary (24),
          bv_error_code bit (36) aligned)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         ((n8, n8t, raw_hbound, raw_lbound) fixed binary (24),
          found_a_break_char bit (1),
          raw_buff_ptr pointer)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          bv_error_code = ""b;

          bv_raw_count = 0;

          found_a_break_char = "0"b;
          do while (^ found_a_break_char);
               raw_buff_ptr = SDB.rawbuffer_ptr;
               raw_lbound = raw_buff_ptr -> byte_buffer.byte_offset;
               raw_hbound = raw_lbound + raw_buff_ptr -> byte_buffer.num_bytes - 1;

               do n8 = raw_lbound by 1 to raw_hbound
                         while ((raw_buff_ptr -> byte_buffer.byte (n8) ^= OUR_IAC)
                              & (^ delimiter_array (binary (raw_buff_ptr -> byte_buffer.byte (n8), 9))));
                    end;
               if (n8 <= raw_hbound) & (raw_buff_ptr -> byte_buffer.byte (n8) ^= OUR_IAC)
               then found_a_break_char = "1"b;
               else do;
                    if raw_buff_ptr -> byte_buffer.num_bytes = 0
                    then raw_buff_ptr -> byte_buffer.byte_offset = 0;

                    call read_from_ncp (n8t, bv_error_code);
		if bv_error_code ^= ""b
                    then do;
                         if SDB.rawbuffer_ptr -> byte_buffer.num_bytes ^= 0
                         then do;
                              bv_raw_count = n8 + 1 - SDB.rawbuffer_ptr -> byte_buffer.byte_offset;
                              return ("1"b);
                              end;
                         return ("0"b);
                         end;

                    if n8t = 0
                    then return ("0"b);

                    if SDB.do_telnet
                    then do;
                         call net_telnet_interpreter_ (bv_SDB_ptr, SDB.rawbuffer_ptr, bv_error_code);
                         if bv_error_code = error_table_$ips_has_occurred
                         then do;
                              bv_error_code = ""b;

                              if have_machine_conditions
                              then call signal_ ("quit", bv_mc_ptr, null (), bv_crawlout_ptr);
                              else call signal_ ("quit", null (), null (), null ());
                              end;
                         end;
                    end;
               end;

          bv_raw_count = n8 + 1 - SDB.rawbuffer_ptr -> byte_buffer.byte_offset;

          bv_error_code = ""b;

          return ("1"b);

end detected_a_break_condition;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

read_from_ncp:
          procedure (bv_num_elements_trans, bv_err_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_num_elements_trans fixed binary (24),
	bv_err_code bit (36) aligned)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          ((first_offset, indx, num_elements) fixed binary (24),
          input_buffer (0 : 1099) bit (8),
          previous_mask bit (36) aligned,
          raw_buffer_ptr pointer,
          transfer_proc variable entry (ptr, ptr, fixed bin (24), fixed bin (24), ptr, fixed bin (24), fixed bin (24), bit (36) aligned))
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          call hcs_$set_ips_mask (enable_mask, previous_mask);

          if SDB.rawbuffer_ptr -> byte_buffer.num_bytes = 0
          then do;
               call delete_buffer (SDB.rawbuffer_ptr);

               SDB.rawbuffer_ptr = addr (SDB.initial_raw_buffer);
               SDB.rawbuffer_ptr -> byte_buffer.byte_offset = 0;
               SDB.rawbuffer_ptr -> byte_buffer.num_bytes = 0;
               end;

          num_elements = 0;
          do while (num_elements < dimension (input_buffer, 1));
               raw_buffer_ptr = SDB.rawbuffer_ptr;
               num_elements = raw_buffer_ptr -> byte_buffer.buffer_bound - (raw_buffer_ptr -> byte_buffer.byte_offset + raw_buffer_ptr -> byte_buffer.num_bytes);

               if num_elements < dimension (input_buffer, 1)
               then call make_bigger_buffer (SDB.rawbuffer_ptr);
               end;

          call net_$ncp_read (SDB.r_ncp_idx, addr (input_buffer), dimension (input_buffer, 1),
                    bv_num_elements_trans, state, bv_err_code);
          if state ^= 6 & state ^= 11
          then connection_state = 1;                        /* connection has been closed                     */

          raw_buffer_ptr = SDB.rawbuffer_ptr;
          first_offset = raw_buffer_ptr -> byte_buffer.byte_offset + raw_buffer_ptr -> byte_buffer.num_bytes;
          indx = 0;
          if SDB.do_telnet
          then transfer_proc = net_convert_bytesize_$telnet_8_to_9;
          else transfer_proc = net_convert_bytesize_$direct_8_to_9;

          call transfer_proc (null (), addr (input_buffer), indx, bv_num_elements_trans - 1,
                    addr (raw_buffer_ptr -> byte_buffer.byte), first_offset, raw_buffer_ptr -> byte_buffer.buffer_bound, ((36)"0"b));

          raw_buffer_ptr -> byte_buffer.num_bytes = raw_buffer_ptr -> byte_buffer.num_bytes + bv_num_elements_trans;

          call hcs_$set_ips_mask (previous_mask, ((36)"0"b));

          if bv_err_code ^= ""b
          then if bv_err_code ^= error_table_$area_too_small
               then return;

          bv_err_code = ""b;

          return;

end read_from_ncp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

copy_byte_array:
          procedure (bv_from_ptr, bv_to_ptr, bv_byte_count);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_byte_count fixed binary (24),
          (bv_from_ptr, bv_to_ptr) pointer)
               parameter;

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
          overlay_string bit (9 * bv_byte_count)
               based;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          bv_to_ptr -> overlay_string = bv_from_ptr -> overlay_string;

          return;

end copy_byte_array;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

make_bigger_buffer:
          procedure (bv_buffer_ptr);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          bv_buffer_ptr pointer
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          temp_ptr pointer
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if bv_buffer_ptr = null ()
          then buffer_allocation_size = 256;
          else buffer_allocation_size = 2 * bv_buffer_ptr -> byte_buffer.buffer_bound;

          if SDB.area_ptr = null ()
          then SDB.area_ptr = get_system_free_area_ ();

          allocate byte_buffer in (SDB.area_ptr -> based_area) set (temp_ptr);
          temp_ptr -> byte_buffer.header.info.area_ptr = SDB.area_ptr;
          temp_ptr -> byte_buffer.header.lock_word = ""b;
          temp_ptr -> byte_buffer.byte_offset = 0;
          temp_ptr -> byte_buffer.num_bytes = 0;

          if bv_buffer_ptr ^= null ()
          then do;
               temp_ptr -> byte_buffer.num_bytes = bv_buffer_ptr -> byte_buffer.num_bytes;

               call copy_byte_array (addr (bv_buffer_ptr -> byte_buffer.byte (bv_buffer_ptr -> byte_buffer.byte_offset)), addr (temp_ptr -> byte_buffer.byte (0)), temp_ptr -> byte_buffer.num_bytes);

               if bv_buffer_ptr -> byte_buffer.header.info.area_ptr ^= null ()
               then free bv_buffer_ptr -> byte_buffer in (bv_buffer_ptr -> byte_buffer.header.area_ptr -> based_area);
               end;

          bv_buffer_ptr = temp_ptr;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

delete_buffer:
          entry (bv_buffer_ptr);

          temp_ptr = bv_buffer_ptr;

          bv_buffer_ptr = null ();

          if temp_ptr = null ()
          then return;

          if temp_ptr -> byte_buffer.header.area_ptr = null ()
          then return;

          free temp_ptr -> byte_buffer in (temp_ptr -> byte_buffer.header.area_ptr -> based_area);

          return;

end make_bigger_buffer;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_ascii_dim_io_;




		    net_ascii_dim_state_.pl1        02/04/80  1131.4rew 02/04/80  1119.3      390060



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1972 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

net_ascii_dim_state_:
          procedure ();

/*             "net_ascii_dim_state_" -- this procedure contains the entry      */
/*        points associated with maintaining the attachment (through the I/O    */
/*        switch) for a stream using this IOSIM.                                */

/*        Originally created by D. M. Wells 1973, December 17.                  */
/*        Modified by D. P. Reed, Oct. 1976, to add Suppress GoAhead.           */
/*        Modified by D. M. Wells, Mar. 1977, to handle term types from AS.     */
/*        Modified by D. M. Wells, July 1977, to use TTT mechanism.             */
/*        Modified by G. Palter, March 1979, to ignore bad modes when setting   */
/*             terminal type or default modes                                   */
/*	Modified by G. Palter, September 1979, to fix bug in terminal_info    */
/*	     control order						*/

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          (bv_size fixed binary (24),                       /* element size of this attachment                */
          bv_num_breaks fixed binary (24),
          bv_num_delims fixed binary (24),
          bv_interpretation_modes bit (*),
          (bv_break_list, bv_delim_list) (*) bit (9),
          (bv_mode, bv_old_mode, bv_request) character (*),
          bv_request_ptr pointer,                           /* pointer to additional args for order call      */
          bv_table_ptr pointer,                             /* pointer to a device driver table               */
          bv_SDB_ptr pointer)                               /* pointer to the SDB for this attachment         */
               parameter;

    declare
          1 bv_status aligned parameter like status_template;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (set_code fixed binary (9),
          state fixed binary (12),
          indx fixed binary (24),
          err_code bit (36) aligned,
          foreign_socket_for_hc bit (41),
          (temp_delims, temp_breaks) (0 : 511) bit (1) unaligned,
          table_ptr pointer)
               automatic;

     declare
          1 temp_status aligned automatic like status_template;

     declare
          1 interpretation_modes automatic,
             2 use_hc_modes bit (1),
             2 set_initial_modes bit (1),
             2 ignore_bad_modes bit (1);

     declare
          1 ttd aligned automatic like terminal_type_data;

          /* * * * * DEFINED REFERENCES  * * * * * * * * * */

     declare
          1 SDB aligned like SDB_template defined (bv_SDB_ptr -> SDB_template);

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
         (sis_version_1 fixed binary (17) initial (1),
          terminal_info_version_1 fixed binary (17) initial (1),
          ttd_version_1 fixed binary (17) initial (1))
               internal static options (constant);

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
         (based_fb35 fixed binary (35),
          based_bit41 bit (41))
               based;

     declare
          1 read_status_struc aligned based,
             2 ev_chan fixed binary (71),
             2 input_available bit (1) unaligned,
             2 read_status_padding bit (35) unaligned;

     declare
          1 socket_info_struc (0 : 1) aligned based,
             2 socket_state fixed binary (12),
             2 local_socket fixed binary (32),
             2 foreign_host fixed binary (16),
             2 foreign_socket fixed binary (32);

     declare
          1 tab_position_comm aligned based,
             2 version_number fixed binary (17),
             2 tab_string_len fixed binary (24),
             2 tab_string_ptr pointer;

     declare
          1 editing_chars_v1 aligned based,
             2 version_number fixed binary (17),
             2 escape_char bit (9) aligned,
             2 erase_char bit (9) aligned,
             2 kill_char bit (9) aligned;

     declare
          1 editing_chars_v2 aligned based,
             2 version_number fixed binary (17),
             2 erase bit (9) unaligned,
             2 kill bit (9) unaligned;

     declare
          1 info_struc aligned based,
             2 id character (4) unaligned,
             2 flags aligned,
                3 baud_rate fixed binary (17) unaligned,
                3 line_type fixed binary (17) unaligned,
                3 pad bit (36) unaligned,
             2 tw_type fixed binary (17);

     declare
          1 send_initial_string_info aligned based,
             2 version fixed binary (17),
             2 initial_string character (512) varying unaligned;

          /* * * * * EXTERNAL STATIC DECLARATIONS  * * * * */

     declare
         (NVT_device_$NVT_device_,
          NVT_tty33_device_$NVT_tty33_device_)
               external static;

     declare
         (error_table_$action_not_performed,
          error_table_$bad_mode,                           /* we didn't understand the mode the guy wanted   */
          error_table_$no_initial_string,
          error_table_$undefined_order_request,             /* code indicating ignorance of order call        */
          error_table_$unimplemented_version)
               bit (36) aligned external static;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          convert_binary_integer_$decimal_string constant entry (fixed bin (35)) returns (char (12) varying),
          cv_dec_check_ constant entry (char (*), bit (36) aligned) returns (fixed bin (35)),
          get_process_id_ constant entry () returns (bit (36) aligned),
          hcs_$wakeup constant entry (bit (36) aligned, fixed bin (71), fixed bin (71), bit (36) aligned),
          host_id_$abbrev constant entry (fixed bin (32), char (*), bit (36) aligned),
          ncp_$get_foreign_socket constant entry (fixed bin (12), fixed bin (16), fixed bin (32), fixed bin (12), bit (36) aligned),
          ncp_$get_local_socket constant entry (fixed bin (12), fixed bin (16), fixed bin (32), fixed bin (12), bit (36) aligned),
          net_$ncp_order constant entry (fixed bin (12), fixed bin (12), ptr, fixed bin (12), bit (36) aligned),
          net_$ncp_state constant entry (fixed bin (12), bit (41), fixed bin (12), bit (36) aligned),
          net_ascii_dim_io_$net_ascii_read_no_block constant entry (ptr, ptr, fixed bin (24), fixed bin (24),
                    fixed bin (24), 1 aligned like status_template),
          net_ascii_dim_io_$net_ascii_write constant entry (ptr, ptr, fixed bin (24), fixed bin (24),
                    fixed bin (24), 1 aligned like status_template),
          net_mode_parser_ constant entry (char (*), entry (char (*) varying, bit (*), ptr, bit (36) aligned), bit (36) aligned),
          ttt_info_$initial_string constant entry (char (*), char (512) varying, bit (36) aligned),
          ttt_info_$modes constant entry (char (*), char (256), bit (36) aligned),
          ttt_info_$terminal_data constant entry (char (*), fixed bin (17), fixed bin (17), ptr, bit (36) aligned);

     declare
          (addr, addrel, binary, bit, hbound, index, lbound, length, null, string, substr)
               builtin;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include line_types;
          % include net_ascii_dim_sdb_dcls;
          % include net_device_table_dcls;
          % include net_status_template;
          % include set_term_type_info;
          % include terminal_info;
          % include terminal_type_data;
          % include tty_types;
          % include ttyp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_order:                                            /* entry to issue typewriter order calls          */
          entry (bv_SDB_ptr, bv_request, bv_request_ptr, bv_status);

          string (bv_status) = ""b;                         /* initialize status word to zero                 */

          if bv_request = "start"
          then do;
               call hcs_$wakeup (get_process_id_ (), SDB.read_event_channel, 0, err_code);
               call hcs_$wakeup (get_process_id_ (), SDB.write_event_channel, 0, err_code);
               return;
               end;

          if bv_request = "terminal_info"
          then do;
               if bv_request_ptr -> terminal_info.version ^= terminal_info_version_1
               then do;
                    bv_status.error_code = error_table_$unimplemented_version;
                    return;
                    end;

               if SDB.chan = ""
               then do;
                    call net_$ncp_state (SDB.w_ncp_idx, foreign_socket_for_hc, state, err_code);
                    call host_id_$abbrev (binary (substr (foreign_socket_for_hc, 1, 32), 32), SDB.chan, err_code);
                    if err_code ^= ""b
                    then SDB.chan = convert_binary_integer_$decimal_string (binary (substr (foreign_socket_for_hc, 1, 32), 32));
                    end;

               bv_request_ptr -> terminal_info.id = substr (SDB.chan, 1, 4);
               bv_request_ptr -> terminal_info.term_type = SDB.terminal_type_name;
               bv_request_ptr -> terminal_info.line_type = LINE_TELNET;
               bv_request_ptr -> terminal_info.baud_rate = 0;
               unspec (bv_request_ptr -> terminal_info.reserved) = ""b;

               return;
               end;

          if bv_request = "info"
          then do;
               if SDB.chan = ""
               then do;                                     /* haven't got the foreign site name yet          */
                    call net_$ncp_state (SDB.w_ncp_idx, foreign_socket_for_hc, state, err_code);
                    call host_id_$abbrev (binary (substr (foreign_socket_for_hc, 1, 32), 32), SDB.chan, err_code);
                    if err_code ^= ""b
                    then SDB.chan = convert_binary_integer_$decimal_string (binary (substr (foreign_socket_for_hc, 1, 32)));
                    end;
               bv_request_ptr -> info_struc.id = substr (SDB.chan, 1, 4);
               bv_request_ptr -> info_struc.baud_rate = 0;  /* if we don't know, we are to return 0 here      */
               bv_request_ptr -> info_struc.line_type = LINE_TELNET;
               bv_request_ptr -> info_struc.pad = ""b;
               bv_request_ptr -> info_struc.tw_type = SDB.old_term_type;
               return;
               end;

          if bv_request = "quit_enable"
          then do;
               SDB.allow_quits = "1"b;

               return;
               end;

          if bv_request = "quit_disable"
          then do;
               SDB.allow_quits = "0"b;

               return;
               end;

          if bv_request = "abort_output"
          then do;
               SDB.current_terminal_state.aborting_output = "1"b;

               return;
               end;

          if bv_request = "set_editing_chars"
          then do;
               if bv_request_ptr -> editing_chars_v1.version_number = 1
               then do;
                    SDB.canon_info.escape = bv_request_ptr -> editing_chars_v1.escape_char;
                    SDB.canon_info.erase = bv_request_ptr -> editing_chars_v1.erase_char;
                    SDB.canon_info.kill = bv_request_ptr -> editing_chars_v1.kill_char;
                    return;
                    end;

               if bv_request_ptr -> editing_chars_v2.version_number = 2
               then do;
                    if bv_request_ptr -> editing_chars_v2.erase ^= "040"b3
                    then SDB.canon_info.erase = bv_request_ptr -> editing_chars_v2.erase;

                    if bv_request_ptr -> editing_chars_v2.kill ^= "040"b3
                    then SDB.canon_info.kill = bv_request_ptr -> editing_chars_v2.kill;

                    return;
                    end;

               bv_status.error_code = error_table_$unimplemented_version;
               return;
               end;

          if bv_request = "get_editing_chars"
          then do;
               if bv_request_ptr -> editing_chars_v1.version_number = 1
               then do;
                    bv_request_ptr -> editing_chars_v1.escape_char = SDB.canon_info.escape;
                    bv_request_ptr -> editing_chars_v1.erase_char = SDB.canon_info.erase;
                    bv_request_ptr -> editing_chars_v1.kill_char = SDB.canon_info.kill;
                    return;
                    end;

               if bv_request_ptr -> editing_chars_v2.version_number = 2
               then do;
                    bv_request_ptr -> editing_chars_v2.erase = SDB.canon_info.erase;
                    bv_request_ptr -> editing_chars_v2.kill = SDB.canon_info.kill;
                    return;
                    end;

               bv_status.error_code = error_table_$unimplemented_version;
               return;
               end;

          if bv_request = "set_device_table"
          then do;
               call net_ascii_set_table (bv_SDB_ptr, bv_request_ptr, bv_status);
               return;
               end;

          if bv_request = "get_socket_states"
          then do;
               call fillin_socket_info (SDB.r_ncp_idx, bv_request_ptr -> socket_info_struc (0));
               call fillin_socket_info (SDB.w_ncp_idx, bv_request_ptr -> socket_info_struc (1));
               return;
               end;

          if bv_request = "get_foreign_socket"
          then do;
               call net_$ncp_state (SDB.w_ncp_idx, bv_request_ptr -> based_bit41, state, bv_status.error_code);

               return;
               end;

          if (bv_request = "set_term_type")
          then do;
               if bv_request_ptr -> set_term_type_info.version ^= stti_version_1
               then do;
                    bv_status.error_code = error_table_$unimplemented_version;
                    return;
                    end;

               ttd.version = ttd_version_1;
               if bv_request_ptr -> set_term_type_info.ignore_line_type
               then call ttt_info_$terminal_data (bv_request_ptr -> set_term_type_info.name, 0, 0, addr (ttd), bv_status.error_code);
               else call ttt_info_$terminal_data (bv_request_ptr -> set_term_type_info.name, LINE_TELNET, 0, addr (ttd), bv_status.error_code);
               if bv_status.error_code ^= ""b
               then return;

                                                            /* At this point, we have checked all we are      */
                                                            /* supposed to.  Therefore, we set the term type  */
                                                            /* and then go on to check the other flags.       */

               SDB.terminal_type_name = bv_request_ptr -> set_term_type_info.name;
               SDB.old_term_type = ttd.old_type;

	     if SDB.old_term_type = TYPE_TTY33
	     then SDB.half = "1"b;
	     else SDB.half = "0"b;

	     call change_modes ("", (""), "0"b, temp_status);	/* distribute this knowledge	*/

               if unspec (ttd.erase) ^= "040"b3
               then SDB.canon_info.erase = unspec (ttd.erase);

               if unspec (ttd.kill) ^= "040"b3
               then SDB.canon_info.kill = unspec (ttd.kill);

               if bv_request_ptr -> set_term_type_info.set_modes
               then do;
                    call set_default_modes ("", bv_status);
                    if bv_status.error_code ^= ""b
                    then return;
                    end;

               if bv_request_ptr -> set_term_type_info.send_initial_string
               then do;
                    call send_default_initial_string (bv_status);
                    if (bv_status.error_code ^= ""b) & (bv_status.error_code ^= error_table_$no_initial_string)
                    then return;
                    end;

               bv_status.error_code = ""b;

               return;
               end;

          if (bv_request = "set_terminal_type") | (bv_request = "set_type")
          then do;
               SDB.old_term_type = bv_request_ptr -> based_fb35;
               if SDB.old_term_type = TYPE_TTY33
               then SDB.current_modes.mode_switches.half = "1"b;
               else SDB.current_modes.mode_switches.half = "0"b;
               SDB.terminal_type_name = tty_dev_type (SDB.old_term_type);

               call change_modes ("", (""), "0"b, temp_status);       /* get this mode switch distributed     */

               return;
               end;

          if bv_request = "read_status"
          then do;
               call net_ascii_dim_io_$net_ascii_read_no_block (bv_SDB_ptr, null (), 0, 0, (0), bv_status);

               bv_request_ptr -> read_status_struc.read_status_padding = ""b;

               if bv_status.successful_physical_completion
               then do;
                    bv_request_ptr -> read_status_struc.ev_chan = 0;
                    bv_request_ptr -> read_status_struc.input_available = "1"b;
                    end;
               else do;
                    bv_request_ptr -> read_status_struc.ev_chan = SDB.read_event_channel;
                    bv_request_ptr -> read_status_struc.input_available = "0"b;
                    end;

               string (bv_status) = ""b;
               return;
               end;

          if bv_request = "set_default_modes"
          then do;
               call set_default_modes ("init,", bv_status);

               return;
               end;

          if bv_request = "send_initial_string"
          then do;
               if bv_request_ptr = null ()
               then do;
                    call send_default_initial_string (bv_status);

                    return;
                    end;

               if bv_request_ptr -> send_initial_string_info.version = sis_version_1
               then do;
                    call send_initial_string (bv_request_ptr -> send_initial_string_info.initial_string, bv_status);

                    return;
                    end;

               bv_status.error_code = error_table_$unimplemented_version;
               return;
               end;

          bv_status.error_code = error_table_$undefined_order_request;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_set_table:                                        /* entry to start to use new device table         */
          entry (bv_SDB_ptr, bv_table_ptr, bv_status);

          string (bv_status) = ""b;

          table_ptr = bv_table_ptr;

          SDB.device_state.version_number = 1;

          SDB.device_state.device_table_ptr = table_ptr;
          if SDB.mode_switches.edited
          then SDB.device_state.output_table_ptr = addrel (table_ptr, table_ptr -> device_table_header.edited_table_rel);
          else SDB.device_state.output_table_ptr = addrel (table_ptr, table_ptr -> device_table_header.normal_table_rel);
          SDB.device_state.input_table_ptr = addrel (table_ptr, table_ptr -> device_table_header.input_table_rel);

          SDB.device_state.line_length = table_ptr -> device_table_header.default_line_length;
          SDB.device_state.page_length = table_ptr -> device_table_header.default_page_length;

          SDB.device_state.out_of_position = "1"b;
          SDB.device_state.in_page_wait = "0"b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_getsize:                                          /* entry to return current element size           */
          entry (bv_SDB_ptr, bv_size, bv_status);

          string (bv_status) = ""b;
          bv_size = 9;                                      /* element size for consoles is always 9          */

          return;                                           /* so return the constant 9 to the caller         */

          /* * * * * * * * * * * * * * * * * * * * * * * * */

initialize_device_modes:                                    /* internal interface to set initial modes        */
          entry (bv_SDB_ptr, bv_mode, bv_interpretation_modes, bv_status);

          string (bv_status) = ""b;

          string (interpretation_modes) = bv_interpretation_modes;

          if interpretation_modes.set_initial_modes         /* "010"b                                         */
          then call setup_initial_modes (bv_mode, bv_status);

          if interpretation_modes.use_hc_modes              /* "100"b                                         */
          then call get_usermodes_from_NCP ();

          if interpretation_modes.ignore_bad_modes          /* "001"b                                         */
          then call change_modes (bv_mode, (""), "1"b, bv_status);

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_changemode:
          entry (bv_SDB_ptr, bv_mode, bv_old_mode, bv_status);

          string (bv_status) = ""b;                         /* initialize status code to zero                 */

          call change_modes (bv_mode, bv_old_mode, "0"b, bv_status);

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_getdelim:
          entry (bv_SDB_ptr, bv_num_breaks, bv_break_list, bv_num_delims, bv_delim_list, bv_status);

          string (bv_status) = ""b;

          bv_num_breaks = 0;

          do indx = lbound (SDB.break_chars.break, 1) by 1 to hbound (SDB.break_chars.break, 1);
               if SDB.break_chars.break (indx)
               then do;
                    bv_num_breaks = bv_num_breaks + 1;
                    bv_break_list (lbound (bv_break_list, 1) + bv_num_breaks - 1) = bit (binary (indx, 9));
                    end;
               end;

          bv_num_delims = 0;

          do indx = lbound (SDB.read_delim_chars.delim, 1) by 1 to hbound (SDB.read_delim_chars.delim, 1);
               if SDB.read_delim_chars.delim (indx)
               then do;
                    bv_num_delims = bv_num_delims + 1;
                    bv_delim_list (lbound (bv_delim_list, 1) + bv_num_delims - 1) = bit (binary (indx, 9));
                    end;
               end;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_setdelim:
          entry (bv_SDB_ptr, bv_num_breaks, bv_break_list, bv_num_delims, bv_delim_list, bv_status);

          string (bv_status) = ""b;

          string (temp_delims) = ""b;
          string (temp_breaks) = ""b;
          string (bv_SDB_ptr -> SDB_template.break_chars) = ""b;

          do indx = lbound (bv_break_list, 1) by 1 to lbound (bv_break_list, 1) + bv_num_breaks - 1;
               set_code = binary (bv_break_list (indx), 9);
               if (set_code >= lbound (temp_breaks, 1)) & (set_code <= hbound (temp_breaks, 1))
               then temp_breaks (set_code) = "1"b;
               end;

          do indx = lbound (bv_delim_list, 1) by 1 to lbound (bv_delim_list, 1) + bv_num_delims - 1;
               set_code = binary (bv_delim_list (indx), 9);
               if (set_code >= lbound (temp_delims, 1)) & (set_code <= hbound (temp_delims, 1))
               then temp_delims (set_code) = "1"b;
               end;

          string (bv_SDB_ptr -> SDB_template.read_delim_chars) = string (temp_delims);
          string (bv_SDB_ptr -> SDB_template.break_chars) = string (temp_breaks);

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

reflect_modes_to_hardcore:
          entry (bv_SDB_ptr);

	call set_usermodes_in_NCP ();
	return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

change_modes:
          procedure (bv_new_modes, bv_old_modes, bv_ignore_bad_modes, bv_mode_status);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_ignore_bad_modes bit (1),
          bv_new_modes character (*),
          bv_old_modes character (*))
               parameter;

     declare
          1 bv_mode_status aligned parameter like status_template;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         ((indx, jdex, ll_temp, pl_temp, to_temp) fixed binary (24),
          forcing_modes bit (1),
          setting_initial_modes bit (1),
          tn_temp bit (1),
          attach_modes bit (5),
          (newm, oldm) bit (11),
          temps character (128))
               automatic;

          /* * * * * CONSTANT DECLARATIONS * * * * * * * * */

     declare
          modestr (10) character (12) initial (
                    "can", "erkl", "esc", "half", "tabsin", "edited", "hndlquit", "tabs", "rawi", "rawo")
               internal static options (constant);

     declare
          (modes_by_default_on initial ("11100000000"b),    /* can, erkl, esc                                 */
          modes_by_default_off initial ("00000000110"b))     /* rawi, rawo                                    */
               bit (11) internal static options (constant);

     declare
          initial_modes (5) character (12) initial (
                  "read", "write", "icp", "listen", "connect")
               internal static options (constant);

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          setting_initial_modes = "0"b;
          forcing_modes = bv_ignore_bad_modes;

                                                            /* the status code has been zeroed already        */

          newm, oldm = string (bv_SDB_ptr -> SDB_template.current_modes.mode_switches);     /* get current modes          */
          ll_temp = SDB.line_length;
          to_temp = SDB.timeout_value;
          pl_temp = SDB.page_length;
          tn_temp = SDB.do_telnet;

                                                            /* figure out the mode string for current modes   */
          indx = 1;
          temps = "";                                       /* blank out the entire temporary string          */
          do jdex = 1 to hbound (modestr, 1);
               if jdex ^= 4                                 /* don't report hndlquit to user                  */
               then do;
                    if ^ substr (oldm, jdex, 1) then do;    /* if "^" needed                                  */
                         substr (temps, indx, 1) = "^";     /* insert "^"                                     */
                         indx = indx + 1;
                         end;
                    substr (temps, indx, 8) = modestr (jdex);         /* insert mode name                     */
                    indx = index (modestr (jdex), " ") + indx - 1;
                    substr (temps, indx, 1) = ",";          /* insert ","                                     */
                    indx = indx + 1;
                    end;
               end;

          if ll_temp = 0
          then do;
               substr (temps, indx, 4) = "^ll,";
               indx = indx + 4;
               end;
          else do;
               substr (temps, indx) = "ll" || convert_binary_integer_$decimal_string ((ll_temp)) || ",";
               indx = index (temps, " ");
               end;

          if pl_temp = 0
          then do;
               substr (temps, indx, 3) = "^pl";
               indx = indx + 3;
               end;
          else do;
               substr (temps, indx) = "pl" || convert_binary_integer_$decimal_string ((pl_temp));
               indx = index (temps, " ");
               end;

          bv_old_modes = temps;

          goto common_new_mode_setting;

                    /* * * * * * * * * * * * * * * * * * * */

setup_initial_modes:
          entry (bv_new_modes, bv_mode_status);

          setting_initial_modes = "1"b;
          forcing_modes = "1"b;

          ll_temp = 130;
          to_temp = 15;
          pl_temp = 0;
          tn_temp = SDB.do_telnet;

          attach_modes = ""b;
          newm = ""b;
          newm = (newm & ^ modes_by_default_off) | (modes_by_default_on);

          goto common_new_mode_setting;

                    /* * * * * * * * * * * * * * * * * * * */

common_new_mode_setting:
                                                            /* now weve got the old modes, figure out the new */
          call net_mode_parser_ (bv_new_modes, interpret_key, bv_mode_status.error_code);
          if bv_mode_status.error_code ^= ""b
          then goto error;

          if setting_initial_modes
          then string (bv_SDB_ptr -> SDB_template.attach_modes) = attach_modes;             /* set the attachment info    */

          SDB.modes_inconsistent = "1"b;

          string (bv_SDB_ptr -> SDB_template.current_modes.mode_switches) = newm;           /* set new modes              */
          string (bv_SDB_ptr -> SDB_template.canon_info.flags) = newm;            /* copy canon flags into canon_info     */
          SDB.current_modes.mode_switches.red = "0"b;

          SDB.device_state.hor_tabs_out = SDB.mode_switches.tabs;
          SDB.device_state.hor_tabs_in = SDB.mode_switches.tabsin;

          if (SDB.device_state.device_table_ptr = addr (NVT_device_$NVT_device_) ) | (SDB.device_state.device_table_ptr = addr (NVT_tty33_device_$NVT_tty33_device_))
          then do;
               if SDB.half
               then call net_ascii_set_table (bv_SDB_ptr, addr (NVT_tty33_device_$NVT_tty33_device_), bv_status);
               else call net_ascii_set_table (bv_SDB_ptr, addr (NVT_device_$NVT_device_), bv_status);
               end;

          if SDB.rawi
          then SDB.device_state.input_table_ptr = null ();

          SDB.line_length = ll_temp;
          SDB.timeout_value = to_temp;
          SDB.page_length = pl_temp;
          SDB.do_telnet = tn_temp;

          if ^ setting_initial_modes
          then if SDB.w_local_pin ^= -1
               then call set_usermodes_in_NCP ();

          SDB.modes_inconsistent = "0"b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

error:
          bv_mode_status.error_code = error_table_$bad_mode;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


interpret_key:
          procedure (bv_key, bv_info_bits, bv_data_ptr, bv_error_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_error_code bit (36) aligned,
          bv_info_bits bit (*),
          bv_key character (*) varying,
          bv_data_ptr pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (mode_desired_on bit (1),
          integer_value_exists bit (1))
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          bv_error_code = ""b;

          mode_desired_on = "1"b;                           /* default is to make the mode go on              */
          integer_value_exists = "0"b;                      /* default is that no integer was decoded         */

          if length (bv_info_bits) >= 1
          then mode_desired_on = substr (bv_info_bits, 1, 1);

          if length (bv_info_bits) >= 2
          then integer_value_exists = substr (bv_info_bits, 2, 1);

          if SDB.dim_name = "ntw_" & bv_key = "default"        /* if user wants default modes                    */
          then do;
               newm = (newm & ^ modes_by_default_off) | modes_by_default_on;

               return;
               end;

          if SDB.dim_name = "ntw_" & bv_key = "init"
          then do;
               newm = ""b;
               newm = (newm & ^ modes_by_default_off) | (modes_by_default_on);

               pl_temp = 0;
               ll_temp = 130;
               return;
               end;

          if substr (bv_key, 1, 2) = "ll" then do;                  /* line-length mode                     */
               if ^ mode_desired_on
               then ll_temp = 0;
               else do;
                    ll_temp = cv_dec_check_ (substr (bv_key, 3), err_code);
                    if err_code ^= ""b then goto found_error_in_key;
                    if (ll_temp < 10) | (ll_temp > 254) then goto found_error_in_key;
                    end;

               return;
               end;

          if substr (bv_key, 1, 2) = "pl" then do;
               if ^ mode_desired_on
               then pl_temp = 0;
               else do;
                    pl_temp = cv_dec_check_ (substr (bv_key, 3), err_code);
                    if err_code ^= ""b
                    then goto found_error_in_key;
                    if (pl_temp < 10) | (pl_temp > 253)
                    then goto found_error_in_key;
                    end;

               return;
               end;

          if SDB.dim_name ^= "ntw_" & bv_key = "telnet"
          then do;
               tn_temp = mode_desired_on;

               return;
               end;

          if bv_key = "timeout" & integer_value_exists
          then do;                                          /* setting of timeout delay period                */
               to_temp = bv_data_ptr -> based_fb35;         /* pick up the decoded integer                    */
               if to_temp < 0 then goto found_error_in_key;

               return;
               end;

          do jdex = 1 to hbound (modestr, 1)
                    while (bv_key ^= modestr (jdex));     /* search for bv_key             */
               end;
          if jdex <= hbound (modestr, 1)     /* if found                             */
          then do;
               substr (newm, jdex, 1) = mode_desired_on;

               return;
               end;

          do jdex = 1 by 1 to hbound (initial_modes, 1)
                  while (bv_key ^= initial_modes (jdex));
               end;
          if jdex <= hbound (initial_modes, 1)
          then do;
               substr (attach_modes, jdex, 1) = mode_desired_on;

               return;
               end;

          if bv_key = "force"
          then do;
               forcing_modes = mode_desired_on;
               return;
               end;

found_error_in_key:
          if ^ forcing_modes
          then bv_error_code = error_table_$bad_mode;

          return;

end interpret_key;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end change_modes;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

fillin_socket_info:
          procedure (P_sock_indx, P_info_struc);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          P_sock_indx fixed bin (12)
               parameter;

     declare
          1 P_info_struc aligned parameter like socket_info_struc;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          err_code bit (36) aligned
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          call ncp_$get_foreign_socket (P_sock_indx, P_info_struc.foreign_host, P_info_struc.foreign_socket, (0), err_code);
          if err_code ^= ""b
          then P_info_struc.foreign_host, P_info_struc.foreign_socket = -1;

          call ncp_$get_local_socket (P_sock_indx, (0), P_info_struc.local_socket, P_info_struc.socket_state, err_code);
          if err_code ^= ""b
          then do;
               P_info_struc.local_socket = -1;
               P_info_struc.socket_state = 0;
               end;

          return;

end;      /* end fillin_socket_info                        */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

set_usermodes_in_NCP:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          ncp_umodes bit (36) aligned
               automatic;

     declare
          1 modes_comm automatic like user_AS_modes_comm_template,
          1 options_comm automatic like user_AS_options_comm_template;

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
         (GET_UMODES          initial (27),                 /* order number to get user modes from NCP        */
          SET_UMODES          initial (28))                 /* order number of set user modes in NCP          */
               fixed binary (12) internal static;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include net_user_as_comm_dcls;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          string (modes_comm) = ""b;

          modes_comm.mode_switches.can = SDB.current_modes.mode_switches.can;
          modes_comm.mode_switches.erkl = SDB.current_modes.mode_switches.erkl;
          modes_comm.mode_switches.esc = SDB.current_modes.mode_switches.esc;
          modes_comm.mode_switches.half = SDB.current_modes.mode_switches.half;
          modes_comm.mode_switches.edited = SDB.current_modes.mode_switches.edited;
          modes_comm.mode_switches.hndlquit = "0"b;
          modes_comm.mode_switches.tabs = SDB.current_modes.mode_switches.tabs;

          modes_comm.line_length = bit (binary (SDB.line_length, 10));

          modes_comm.version_number = bit (binary (user_as_comm_version_2, 4));
          if SDB.old_term_type = 0
          then modes_comm.terminal_type = bit (binary (TYPE_ASCII, 4));
          else modes_comm.terminal_type = bit (binary (SDB.old_term_type, 4));

          modes_comm.protocol_info.protocol_15372 = SDB.current_modes.protocol_495;

          ncp_umodes = string (modes_comm);

          call net_$ncp_order (SDB.w_ncp_idx, (SET_UMODES), addr (ncp_umodes), (0), (""b));

          string (options_comm.receive_option.in_effect) = string (SDB.option_in_effect (RECEIVE));
          string (options_comm.receive_option.in_negotiation) = string (SDB.option_in_negotiation (RECEIVE));

          string (options_comm.transmit_option.in_effect) = string (SDB.option_in_effect (TRANSMIT));
          string (options_comm.transmit_option.in_negotiation) = string (SDB.option_in_negotiation (TRANSMIT));

          ncp_umodes = string (options_comm);

          call net_$ncp_order (SDB.r_ncp_idx, (SET_UMODES), addr (ncp_umodes), (0), (""b));

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

get_usermodes_from_NCP:
          entry ();

          call net_$ncp_order (SDB.w_ncp_idx, (GET_UMODES), addr (ncp_umodes), (0), err_code);
          if err_code ^= ""b
          then return;

          string (modes_comm) = ncp_umodes;


          SDB.current_modes.mode_switches.can = modes_comm.mode_switches.can;
          SDB.current_modes.mode_switches.erkl = modes_comm.mode_switches.erkl;
          SDB.current_modes.mode_switches.esc = modes_comm.mode_switches.esc;
          SDB.current_modes.mode_switches.half = modes_comm.mode_switches.half;
          SDB.current_modes.mode_switches.edited = modes_comm.mode_switches.edited;
          SDB.current_modes.mode_switches.red = "0"b;
          SDB.current_modes.mode_switches.tabs = modes_comm.mode_switches.tabs;

          SDB.line_length = binary (modes_comm.line_length, 10);

          SDB.old_term_type = binary (modes_comm.terminal_type, 17);
          if SDB.old_term_type = 0
          then SDB.old_term_type = TYPE_ASCII;
          else if SDB.old_term_type = TYPE_TTY33
               then SDB.current_modes.mode_switches.half = "1"b;

          SDB.current_modes.protocol_495 = modes_comm.protocol_info.protocol_15372;

          call net_$ncp_order (SDB.r_ncp_idx, (GET_UMODES), addr (ncp_umodes), (0), err_code);
          if err_code ^= ""b
          then return;

          string (options_comm) = ncp_umodes;

          string (SDB.option_in_effect (RECEIVE)) = string (options_comm.receive_option.in_effect);
          string (SDB.option_in_negotiation (RECEIVE)) = string (options_comm.receive_option.in_negotiation);

          string (SDB.option_in_effect (TRANSMIT)) = string (options_comm.transmit_option.in_effect);
          string (SDB.option_in_negotiation (TRANSMIT)) = string (options_comm.transmit_option.in_negotiation);

          return;

end set_usermodes_in_NCP;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

set_default_modes:
          procedure (bv_prefix, bv_status);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_prefix char (*),
          1 bv_status aligned like status_template)
	     parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (new_modes character (256),
          initial_string character (512) varying)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          call ttt_info_$modes (SDB.terminal_type_name, new_modes, bv_status.error_code);
          if bv_status.error_code ^= ""b
          then return;

	call change_modes (bv_prefix || new_modes, (""), "1"b, bv_status);

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

send_default_initial_string:
          entry (bv_status);

          call ttt_info_$initial_string (SDB.terminal_type_name, initial_string, bv_status.error_code);
          if bv_status.error_code ^= ""b
          then return;

          if length (initial_string) = 0
          then do;
               bv_status.error_code = error_table_$no_initial_string;
               return;
               end;

          call send_initial_string (initial_string, bv_status);

          return;

end;      /* end set_default_modes                         */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

send_initial_string:
          procedure (bv_string, bv_status);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          bv_string character (512) varying
               parameter;

     declare
          1 bv_status aligned parameter like status_template;

          /* * * * * AUTOMATIC STPRAGE DECLARATIONS  * * * */

     declare
         (initial_string_length fixed binary (24),
          old_modes character (256),
          initial_string character (512))
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          initial_string_length = length (bv_string);
          initial_string = bv_string;

          call net_ascii_changemode (addr (SDB), "rawo", old_modes, bv_status);
          if bv_status.error_code ^= ""b
          then return;

          call net_ascii_dim_io_$net_ascii_write (addr (SDB), addr (initial_string), 0, initial_string_length, (0), bv_status);
          if bv_status.error_code ^= ""b
          then do;
               call net_ascii_changemode (addr (SDB), old_modes, (""), temp_status);
               return;
               end;

          call net_ascii_changemode (addr (SDB), old_modes, (""), bv_status);

          return;

end;      /* end send_initial_string                       */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_ascii_dim_state_;




		    net_ascii_dim_xtach_.pl1        04/03/81  1123.3rew 04/03/81  1115.9      230517



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1972 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

net_ascii_dim_xtach_:
          procedure ();

/*             "net_ascii_dim_xtach_" -- this procedure contains the entry      */
/*        points associated with maintaining the attachment (through the I/O    */
/*        switch) for a stream using this IOSIM.                                */

/*        Originally created by D. M. Wells 1973, December 17.                  */
/*        Modified by D. M. Wells, to use device name interpreting subr         */
/*        Modified by D. M. Wells, Mar. 1977, to get term type info from AS.    */
/*        Modified by D. M. Wells, July 1977, to use TTT mechanism.             */
/*        Modified by Benson I. Margulies March 80 for reconnection		*/

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         ((bv_attach_device, bv_att_stream, bv_dim_name, bv_disposal, bv_mode) character (*),
          bv_SDB_ptr pointer)                               /* pointer to the SDB for this attachment         */
               parameter;

    declare
          1 bv_status aligned parameter like status_template;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (connection_type fixed binary (2),
          pin_number fixed binary (8),
          tries fixed binary (17),
          net_user_id fixed binary (24),
          should_allocate_pins bit (1),
          desired_sockets bit (2),
          err_code bit (36) aligned,
          foreign_socket bit (64),
	attach_device character (32),
          SDB_ptr pointer)
               automatic;

     declare
          1 temp_status aligned automatic like status_template;

     declare
          1 ipc_event_list aligned automatic,
             2 num_chans fixed binary (17),
             2 event_channel fixed binary (71);

     declare
          1 event_message aligned automatic like event_message_template;

          /* * * * * INTERNAL STATIC DECLARATIONS  * * * * */

     declare
          SDB_ptr_stat pointer initial (null ())
               internal static;

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
         (ICP_CONNECTION initial (1),
          LISTEN_CONNECTION initial (2),
          CONNECT_CONNECTION initial (3))
               fixed binary (2) internal static options (constant);

     declare
          (default_erase initial ("043"b3),
          default_escape initial ("134"b3),
          default_kill initial ("100"b3))
               bit (9) internal static options (constant);

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

          /* * * * * EXTERNAL STATIC DECLARATIONS  * * * * */

     declare
          NVT_device_$NVT_device_
               external static;

     declare
          (error_table_$bad_mode,                           /* we didn't understand the mode the guy wanted   */
          error_table_$invalid_device,
          error_table_$ionmat,                              /* code indicating stream already attached        */
          error_table_$net_invalid_state)
               bit (36) aligned external static;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          cv_dec_check_ constant entry (char (*), bit (36) aligned) returns (fixed bin (35)),
	get_system_free_area_ entry () returns (ptr),
          hcs_$assign_channel constant entry (fixed bin (71), bit (36) aligned),
          interpret_socket_name_ constant entry (char (*), bit (64), fixed bin (8), bit (36) aligned),
          ipc_$block constant entry (ptr, ptr, bit (36) aligned),
          ipc_$create_ev_chn constant entry (fixed bin (71), bit (36) aligned),
          ipc_$delete_ev_chn constant entry (fixed bin (71), bit (36) aligned),
          ncp_$accept_passoff constant entry (fixed bin (24), fixed bin (8), fixed bin (71), fixed bin (12), bit (36) aligned),
          ncp_$detach_socket constant entry (fixed bin (12), bit (36) aligned),
          net_$set_userid constant entry (bit (24) aligned, bit (36) aligned),
          net_ascii_dim_io_$net_ascii_signal_handler constant entry (ptr),
          net_ascii_dim_io_$net_ascii_write_raw constant entry (ptr, ptr, fixed bin (24), fixed bin (24), fixed bin (24), 1 aligned like status_template),
          net_ascii_dim_state_$initialize_device_modes constant entry (ptr, char (*), bit (*), 1 aligned like status_template),
          net_ascii_dim_state_$net_ascii_changemode constant entry (ptr, char (*), char (*), 1 aligned like status_template),
          net_ascii_dim_state_$net_ascii_set_table constant entry (ptr, ptr, 1 aligned like status_template),
          net_connect_$abort_connection constant entry (fixed bin (8), bit (36) aligned),
          net_connect_$conclude_connection constant entry (fixed bin (8), fixed bin (71), fixed bin (71), bit (64),
                    fixed bin (12), fixed bin (12), bit (36) aligned),
          net_connect_$initiate_connection constant entry (fixed bin (8), fixed bin (2), bit (64), bit (2),
                    fixed bin (17), fixed bin (71), bit (36) aligned),
          net_pin_manager_$allocate_pins constant entry (fixed bin (8), fixed bin (8), bit (36) aligned),
          net_pin_manager_$free_pins constant entry (fixed bin (8), fixed bin (8), bit (36) aligned),
          net_signal_handler_$remove_signal_handler constant entry (fixed bin (12), bit (36) aligned),
          net_signal_handler_$setup_signal_handler constant entry (fixed bin (12), entry (ptr), ptr, bit (36) aligned),
          net_telnet_interpreter_$rationalize_options constant entry (ptr, bit (36) aligned),
	user_info_$terminal_data entry (char(*), char(*), char(*), fixed bin, char(*));

/* BASED STORAGE */

     declare system_area area (1024) /* size irrelevant */ based (get_system_free_area_ ());
     declare
          (addr, binary, bit, hbound, length, mod, null, size, string, substr)
               builtin;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include net_ascii_dim_sdb_dcls;
          % include net_event_template;
          % include net_status_template;
          % include tty_types;
          % include ttyp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

net_ttydim_attach:                                          /* entry to create a new attachment instance      */
          entry (bv_att_stream, bv_dim_name, bv_attach_device, bv_mode, bv_status, bv_SDB_ptr);

          string (bv_status) = ""b;

          call initialize_sdb ("1"b);

          SDB_ptr -> SDB_template.chan = "";                         /* we will look up host name only if needed       */

          call assign_ipc_channel (SDB_ptr -> SDB_template.read_event_channel, "1"b);
          call assign_ipc_channel (SDB_ptr -> SDB_template.write_event_channel, "1"b);

	attach_device = bv_attach_device;
	if attach_device = "-login_channel" then 
	     call user_info_$terminal_data ((4) " ", (32)" ", attach_device, (0), (32)" ");
	     
          net_user_id = cv_dec_check_ (substr (attach_device, 4, 3), err_code);
          if err_code ^= ""b then goto report_attach_error;

/*        call net_$set_userid (bit (binary (net_user_id, 24)), err_code);   */
/*        if err_code ^= ""b then goto report_attach_error;   */

                                                            /* Activate the read and write sockets            */

          SDB_ptr -> SDB_template.attach_modes.read, SDB_ptr -> SDB_template.attach_modes.write = "1"b;

          SDB_ptr -> SDB_template.r_local_pin = 0;
          call ncp_$accept_passoff (net_user_id, SDB_ptr -> SDB_template.r_local_pin, SDB_ptr -> SDB_template.read_event_channel,
                    SDB_ptr -> SDB_template.r_ncp_idx, err_code);
          if err_code ^= ""b
          then goto deactivate_any_sockets;

          SDB_ptr -> SDB_template.w_local_pin = 1;
          call ncp_$accept_passoff (net_user_id, SDB_ptr -> SDB_template.w_local_pin, SDB_ptr -> SDB_template.write_event_channel,
                    SDB_ptr -> SDB_template.w_ncp_idx, err_code);
          if err_code ^= ""b
          then goto deactivate_any_sockets;

          call net_signal_handler_$setup_signal_handler (SDB_ptr -> SDB_template.r_ncp_idx,
                    net_ascii_dim_io_$net_ascii_signal_handler, SDB_ptr, bv_status.error_code);
          if bv_status.error_code ^= ""b
          then goto deactivate_any_sockets;

          SDB_ptr -> SDB_template.do_telnet = "1"b;

          call net_ascii_dim_state_$initialize_device_modes (SDB_ptr, "tabsin", "111"b, bv_status);

          call net_ascii_dim_state_$net_ascii_changemode (SDB_ptr, bv_mode, (""), bv_status);

          if SDB_ptr -> SDB_template.protocol_495
          then call net_telnet_interpreter_$rationalize_options (SDB_ptr, bv_status.error_code);

          string (bv_status) = ""b;

          bv_SDB_ptr = SDB_ptr;                             /* finally set ios_'s SDB pointer                 */

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

report_that_already_attached:
          err_code = error_table_$ionmat;

report_attach_error:
          bv_status.error_code = err_code;                  /* here on error, return status code to caller    */
          bv_status.stream_name_detached = "1"b;            /* indicate stream not attached                   */

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_attach:                                           /* entry to attach non-user_i/o typewriter        */
          entry (bv_att_stream, bv_dim_name, bv_attach_device, bv_mode, bv_status, bv_SDB_ptr);

          string (bv_status) = ""b;                         /* set status word to zero                        */

          call initialize_sdb ("0"b);

          call net_ascii_dim_state_$initialize_device_modes (SDB_ptr, bv_mode, "010"b, bv_status);

          if (^ SDB_ptr -> SDB_template.attach_modes.read) & (^ SDB_ptr -> SDB_template.attach_modes.write)
          then SDB_ptr -> SDB_template.attach_modes.read, SDB_ptr -> SDB_template.attach_modes.write = "1"b;
                                                            /* if not specified, use full duplex connection   */

                                                  /*      Now we are going to parse the device name that was  */
                                                  /* given to us.  The general form of the device name is:    */
                                                  /*           foreign_host,foreign_socket/local_pin          */
                                                  /* The local_pin portion of the name is optional.           */

          call interpret_socket_name_ (bv_attach_device, foreign_socket, pin_number, err_code);
          if err_code ^= ""b
          then goto bad_device;                             /* bad socket name, go refuse attachment          */

          if pin_number = -1
          then should_allocate_pins = "1"b;                 /* we need to allocate some pins for our use      */
          else do;                                          /* a slash was specified, so parse the local pin  */
               should_allocate_pins = "0"b;                 /* user has already gotten the pins allocated     */

               if SDB_ptr -> SDB_template.attach_modes.read
               then do;
                    SDB_ptr -> SDB_template.r_local_pin = pin_number;
                    SDB_ptr -> SDB_template.w_local_pin = pin_number + 1;
                    end;
               else do;
                    SDB_ptr -> SDB_template.r_local_pin = pin_number - 1;
                    SDB_ptr -> SDB_template.w_local_pin = pin_number;
                    end;

               if mod (SDB_ptr -> SDB_template.r_local_pin, 2) ^= 0
               then goto bad_device;                        /* wrong gender pin specified for given modes     */
               end;

          call assign_ipc_channel (SDB_ptr -> SDB_template.read_event_channel, "0"b);
          call assign_ipc_channel (SDB_ptr -> SDB_template.write_event_channel, "0"b);

          SDB_ptr -> SDB_template.connect_done = "1"b;

          desired_sockets = SDB_ptr -> SDB_template.attach_modes.read || SDB_ptr -> SDB_template.attach_modes.write;

          if SDB_ptr -> SDB_template.attach_modes.icp
          then connection_type = ICP_CONNECTION;
          else if SDB_ptr -> SDB_template.attach_modes.connect
               then connection_type = CONNECT_CONNECTION;
               else if SDB_ptr -> SDB_template.attach_modes.listen
                    then connection_type = LISTEN_CONNECTION;
                    else do;                                /* user didnt tell us how to make the connection  */
                         err_code = error_table_$bad_mode;
                         goto report_attach_error;
                         end;

          SDB_ptr -> SDB_template.r_ncp_idx = -1;
          SDB_ptr -> SDB_template.w_ncp_idx = -1;

          err_code = error_table_$net_invalid_state;        /* set err_code up to cause loop to go once       */
          do tries = 1 by 1 to 5 while (err_code = error_table_$net_invalid_state);
                                                            /* try up to five times                           */
               if should_allocate_pins
               then do;
                    call net_pin_manager_$allocate_pins (4, SDB_ptr -> SDB_template.r_local_pin, err_code);
                    if err_code ^= ""b
                    then goto detach_net;
                    SDB_ptr -> SDB_template.w_local_pin = SDB_ptr -> SDB_template.r_local_pin + 1;
                    end;

               call net_connect_$initiate_connection (SDB_ptr -> SDB_template.r_local_pin, connection_type, foreign_socket,
                         desired_sockets, SDB_ptr -> SDB_template.timeout_value, SDB_ptr -> SDB_template.read_event_channel, err_code);
               if err_code ^= ""b
               then do;
                    if should_allocate_pins
                    then do;
                         call net_pin_manager_$free_pins (4, SDB_ptr -> SDB_template.r_local_pin, ((36)"0"b));
                         SDB_ptr -> SDB_template.r_local_pin = -1;
                         end;

                    end;
               end;

          if err_code ^= ""b
          then goto detach_net;
          ipc_event_list.num_chans = 1;
          ipc_event_list.event_channel = SDB_ptr -> SDB_template.read_event_channel;

          call ipc_$block (addr (ipc_event_list), addr (event_message), err_code);
          if err_code ^= ""b
          then goto detach_net;

          err_code = substr (event_message.message, 37, 36);
          if err_code ^= ""b
          then goto detach_net;

          call net_connect_$conclude_connection (SDB_ptr -> SDB_template.r_local_pin, SDB_ptr -> SDB_template.read_event_channel,
                    SDB_ptr -> SDB_template.write_event_channel, foreign_socket,
                    SDB_ptr -> SDB_template.r_ncp_idx, SDB_ptr -> SDB_template.w_ncp_idx, err_code);
          if err_code ^= ""b
          then goto detach_net;

          SDB_ptr -> SDB_template.do_telnet = "0"b;

          call net_ascii_dim_state_$initialize_device_modes (SDB_ptr, "can,^tabsin,^esc,^erkl,^ll,^pl,^edited,^half", "001"b, bv_status);
          call net_ascii_dim_state_$net_ascii_changemode (SDB_ptr, bv_mode, (""), bv_status);

          if ^ should_allocate_pins
          then SDB_ptr -> SDB_template.r_local_pin = -1;             /* forget about this pin number if not allocated  */

          bv_SDB_ptr = SDB_ptr;                             /* finally set ios_'s SDB pointer                 */

          return;                                           /* and return to caller */

          /* * * * * * * * * * * * * * * * * * * * * * * * */

bad_device:
          err_code = error_table_$invalid_device;

          goto report_attach_error;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

detach_net:
          bv_status.error_code = err_code;

          goto deactivate_any_sockets;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

net_ascii_detach:                                           /* entry to detach a given instance of attachment */
          entry (bv_SDB_ptr, bv_attach_device, bv_disposal, bv_status);

          SDB_ptr = bv_SDB_ptr;                             /* get pointer to entry for this typewriter       */
          string (bv_status) = ""b;                         /* initialize status code to zero                 */

          err_code = ""b;

deactivate_any_sockets:
          call net_signal_handler_$remove_signal_handler (SDB_ptr -> SDB_template.r_ncp_idx, ((36)"0"b));

          if SDB_ptr -> SDB_template.connect_done then do;
               if SDB_ptr -> SDB_template.r_ncp_idx ^= -1 then do;
                    call ncp_$detach_socket (SDB_ptr -> SDB_template.r_ncp_idx, ((36)"0"b));
                    end;

               if SDB_ptr -> SDB_template.w_ncp_idx ^= -1 then do;
                    call ncp_$detach_socket (SDB_ptr -> SDB_template.w_ncp_idx, ((36)"0"b));
                    end;

               if SDB_ptr -> SDB_template.r_local_pin ^= -1
               then call net_pin_manager_$free_pins (4, SDB_ptr -> SDB_template.r_local_pin, ((36)"0"b));
               end;

          call ipc_$delete_ev_chn (SDB_ptr -> SDB_template.read_event_channel, ((36)"0"b));
          call ipc_$delete_ev_chn (SDB_ptr -> SDB_template.write_event_channel, ((36)"0"b));

          bv_status.error_code = err_code;
          bv_status.stream_name_detached = "1"b;            /* set code to detach this ioname                 */
          SDB_ptr -> SDB_template.vacant = "1"b;                     /* indicate tw list entry no longer in use        */

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

initialize_sdb:
          procedure (bv_check_for_old_attachment);

          /* * * * * PARAMETER DECLARATIONS * * * * * * * */

     declare
          bv_check_for_old_attachment bit (1) aligned
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (last_ptr, vacant_ptr) pointer
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          string (bv_status) = ""b;                         /* set status word to zero                        */

          if bv_SDB_ptr ^= null () then goto report_that_already_attached;                 /* this is a multiple attachment, no good         */
          vacant_ptr = null ();                             /* use to locate first vacant entry (if any)      */
          do SDB_ptr = SDB_ptr_stat repeat (SDB_ptr -> SDB_template.nextp) while (SDB_ptr ^= null ());
                                                            /* search entire tw list */
               last_ptr = SDB_ptr;                          /* keep track of last entry in_last_ptr           */
               if SDB_ptr -> SDB_template.vacant then do;                      /* is this entry an unused (vacant) entry? */
                    if vacant_ptr = null ()
                    then vacant_ptr = SDB_ptr;              /* record first vacant entry found in list        */
                    end;
               else if SDB_ptr -> SDB_template.device_name = bv_attach_device
                    then if bv_check_for_old_attachment
                         then goto report_that_already_attached;
                                                            /* prohibit multiple attachment */
               end;
          if vacant_ptr = null ()
          then do;                                          /* if no vacant entry found in tw list            */
	     allocate SDB_template in (system_area) set (vacant_ptr);

               vacant_ptr -> SDB_template.vacant = "1"b;                     /* initialize new tw list entry */
               vacant_ptr -> SDB_template.nextp = null ();                             /* indicate new entry is last entry in list */
               if SDB_ptr_stat = null ()
               then SDB_ptr_stat = vacant_ptr;                      /* save ptr to first block on chain */
               else last_ptr -> SDB_template.nextp = vacant_ptr;                              /* thread new entry into SDB list */
               end;
          SDB_ptr = vacant_ptr;

          SDB_ptr -> SDB_template.vacant = "0"b;
          SDB_ptr -> SDB_template.connect_done = "0"b;

          SDB_ptr -> SDB_template.r_local_pin = -1;
          SDB_ptr -> SDB_template.w_local_pin = -1;

          SDB_ptr -> SDB_template.device_name = bv_attach_device;                             /* store "ioname2" */
          SDB_ptr -> SDB_template.device_name_size = length (SDB_ptr -> SDB_template.device_name);
          SDB_ptr -> SDB_template.dim_name = bv_dim_name;                      /* initialize name of DIM */
          SDB_ptr -> SDB_template.device_name_list = addr (SDB_ptr -> SDB_template.next_device);  /* get pointer to list of device names */
          SDB_ptr -> SDB_template.next_device = null ();                       /* this is last entry in list */

          SDB_ptr -> SDB_template.initial_raw_buffer.buffer_bound = hbound (SDB_ptr -> SDB_template.initial_raw_buffer.byte, 1);
          SDB_ptr -> SDB_template.initial_raw_buffer.area_ptr = null ();
          SDB_ptr -> SDB_template.initial_raw_buffer.lock_word = ""b;
          SDB_ptr -> SDB_template.initial_raw_buffer.num_bytes = 0;
          SDB_ptr -> SDB_template.initial_raw_buffer.byte_offset = 0;

          SDB_ptr -> SDB_template.allow_quits = "0"b;

          call net_ascii_dim_state_$net_ascii_set_table (SDB_ptr, addr (NVT_device_$NVT_device_), bv_status);

          SDB_ptr -> SDB_template.desired_column = 0;
          SDB_ptr -> SDB_template.actual_column = 0;
          SDB_ptr -> SDB_template.desired_line = 0;
          SDB_ptr -> SDB_template.actual_line = 0;
          SDB_ptr -> SDB_template.current_terminal_state.aborting_output = "0"b;
          SDB_ptr -> SDB_template.timeout_value = 15;                /* default timeout period is 15 seconds           */
          SDB_ptr -> SDB_template.old_term_type = TYPE_ASCII;
          SDB_ptr -> SDB_template.terminal_type_name = tty_dev_type (SDB_ptr -> SDB_template.old_term_type);

          SDB_ptr -> SDB_template.canon_info.version_number = 2;

          SDB_ptr -> SDB_template.canon_info.escape = default_escape;          /* the default escape char is \ (134)   */
          SDB_ptr -> SDB_template.canon_info.erase = default_erase;            /* the default erase char is # (043)    */
          SDB_ptr -> SDB_template.canon_info.kill = default_kill;              /* the default kill char is @ (100)     */

          SDB_ptr -> SDB_template.canon_info.tabs_info.tab_string_ptr = null ();         /* use default tab settings   */

          string (SDB_ptr -> SDB_template.break_chars) = ""b;
          SDB_ptr -> SDB_template.break_chars.break (10) = "1"b;     /* the NL is the only initial break character     */

          string (SDB_ptr -> SDB_template.read_delim_chars) = ""b;
          SDB_ptr -> SDB_template.read_delim_chars.delim (10) = "1"b;

          SDB_ptr -> SDB_template.string_ptr = null ();
          SDB_ptr -> SDB_template.area_ptr = null ();
          SDB_ptr -> SDB_template.output_ptr = null ();
          SDB_ptr -> SDB_template.rawbuffer_ptr = addr (SDB_ptr -> SDB_template.initial_raw_buffer);

          SDB_ptr -> SDB_template.output_buffer.area_ptr = null ();
          SDB_ptr -> SDB_template.output_buffer.lock_word = ""b;
          SDB_ptr -> SDB_template.output_buffer.buffer_bound = hbound (SDB_ptr -> SDB_template.output_buffer.byte8, 1);
          SDB_ptr -> SDB_template.output_buffer.byte_offset = 0;
          SDB_ptr -> SDB_template.output_buffer.num_bytes = 0;

          SDB_ptr -> SDB_template.output_ptr = addr (SDB_ptr -> SDB_template.output_buffer);

          SDB_ptr -> SDB_template.protocol_495 = "0"b;

	string(SDB_ptr -> SDB_template.option_in_effect) = ""b;
	string(SDB_ptr -> SDB_template.option_in_negotiation) = ""b;

          return;

end initialize_sdb;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

assign_ipc_channel:
          procedure (bv_ipc_channel, bv_try_for_fast_channel);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_ipc_channel fixed binary (71),
          bv_try_for_fast_channel bit (1) aligned)
               parameter;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if bv_try_for_fast_channel
          then call hcs_$assign_channel (bv_ipc_channel, err_code);
          else err_code = "1"b;

          if err_code ^= ""b
          then do;
               call ipc_$create_ev_chn (bv_ipc_channel, err_code);
               if err_code ^= ""b
               then goto report_attach_error;
               end;

          return;

end assign_ipc_channel;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_ascii_dim_xtach_;




		    net_canonicalize_.pl1           06/26/79  1713.7rew 06/13/79  1350.0      142758



/* ******************************************************
   *					      *
   *					      *
   * Copyright (c) 1974 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *					      *
   *					      *
   ****************************************************** */

net_canonicalize_:
     procedure (bv_info_ptr, bv_input_ptr, bv_num_input, bv_output_ptr, bv_num_output, bv_num_output_trans, bv_error_code);

/* This procedure performs canonicalization, erase-kill, and escape processing
   for the Multics ARPA Network TTY DIM.
   */
/* Initial coding:	??? by D. Wells */
/* Last modified:	26 March 1979 by G. Palter to eliminate OOB faults */


dcl (bv_num_input, bv_num_output, bv_num_output_trans) fixed binary (24) parameter;
dcl  bv_error_code bit (36) aligned parameter;
dcl (bv_info_ptr, bv_input_ptr, bv_output_ptr) pointer parameter;

dcl (i, j, position_start, position_end, last_position_start,
     extra_space_count, tabs_len, temp_number, ini) fixed binary (24);
dcl (erase, escape, kill) character (1);
dcl (allow_tabs, longsw, do_can, do_erkl, do_esc, do_tty33) bit (1) aligned;
dcl  tabs_ptr pointer;

dcl  instring character (bv_num_input) based (inp);
dcl  chars (0: 1) character (1) based;
dcl  bit9 bit (9) unaligned based;
dcl  lastin_high_column fixed binary (24);
dcl  lastin_cur_column fixed binary (24);
dcl  column fixed binary (24);
dcl  high_column fixed binary (24);
dcl (outp, inp) pointer;
dcl (ch, ch1) character (1);

dcl (minus initial ("-"),
     apostrophe initial ("'"),
     grave initial ("`"),
     lparen initial ("("),
     rparen initial (")"),
     lbrace initial ("{"),
     rbrace initial ("}"),
     exc_pt initial ("!"),
     vert_bar initial ("|"),
     equals initial ("="),
     tilde initial ("~"))
     character (1) static options (constant);

dcl  tabsize fixed binary (24) static options (constant) initial (10);

dcl  space character (10) static options (constant) initial ("          ");

dcl  tab_string bit (tabs_len) based;
dcl  outstring character (lastin_high_column) based;

dcl (ascii_value_$HT,
     ascii_value_$BS,
     ascii_value_$NL,
     ascii_value_$RT)
     character (1) aligned external;

dcl (error_table_$area_too_small,
     error_table_$bad_mode,
     error_table_$unimplemented_version)
     bit (36) aligned external;

dcl  cv_oct_check_ entry (character (*), fixed binary (24)) returns (fixed binary (24));

dcl (addr, binary, bit, index, max, mod, substr, unspec) builtin;

/*  */

%include net_conversion_dcls;

/*  */

	if (bv_info_ptr -> canon_info_template.version_number < 1) | (bv_info_ptr -> canon_info_template.version_number > 2)
	then do;
	     bv_error_code = error_table_$unimplemented_version;
	     return;
	end;

	if bv_num_output = 0 then do;
	     bv_error_code = error_table_$area_too_small;
	     return;
	end;

	bv_error_code = ""b;

	unspec (escape) = bv_info_ptr -> canon_info_template.special_chars.escape;
	unspec (erase) = bv_info_ptr -> canon_info_template.special_chars.erase;
	unspec (kill) = bv_info_ptr -> canon_info_template.special_chars.kill;

	do_can = bv_info_ptr -> canon_info_template.flags.do_can;
	do_esc = bv_info_ptr -> canon_info_template.flags.do_esc;
	do_erkl = bv_info_ptr -> canon_info_template.flags.do_erkl;
	allow_tabs = bv_info_ptr -> canon_info_template.flags.allow_tabs;
	do_tty33 = bv_info_ptr -> canon_info_template.flags.do_tty33;

	if bv_info_ptr -> canon_info_template.version_number < 2 then
	     tabs_ptr = null ();

	else do;
	     tabs_ptr = bv_info_ptr -> canon_info_template.tab_string_ptr;
	     tabs_len = bv_info_ptr -> canon_info_template.tab_string_length;
	     if allow_tabs & (tabs_ptr ^= null ()) then do;
		bv_error_code = error_table_$bad_mode;
		return;
	     end;
	end;

	longsw = do_esc | do_tty33 | do_erkl;
	column, lastin_high_column, lastin_cur_column, bv_num_output_trans = 0;
	outp = bv_output_ptr;
	inp = bv_input_ptr;


	do ini = 1 to bv_num_input;
	     ch = substr (instring, ini, 1);

	     if ch < space then
		call control_character ();
	     else call normal_character ();

end_char_loop:
	     if lastin_cur_column = lastin_high_column then
	     high_column = column;
	end;


	bv_num_output_trans = bv_num_output_trans + lastin_high_column;

	return;


crump:	substr (outp -> outstring, 1, bv_num_output) = "NON-CANONICALIZED GARBAGE";
	bv_error_code = error_table_$area_too_small;
	return;

/*  */

normal_character:
	procedure ();

	     column = column + 1;
	     if lastin_cur_column = lastin_high_column
	     then do;				/* are we at the end of this line? */
		if lastin_cur_column + 1 > bv_num_output then
		     goto crump;
		lastin_cur_column, lastin_high_column = lastin_cur_column + 1;
						/* one more character */
		substr (outp -> outstring, lastin_cur_column, 1) = ch;
	     end;

	     else do;
		if ch = space then do;
dospace:		     lastin_cur_column = lastin_cur_column + 1;
		     goto scan_loop;
		end;

insert_after_char:
		ch1 = substr (outp -> outstring, lastin_cur_column+1, 1);
						/* look at next char */
		if ch = ch1 then
		     goto dospace;

		if ch1 = space then do;		/* replace space */
		     substr (outp -> outstring, lastin_cur_column+1, 1) = ch;
		     lastin_cur_column = lastin_cur_column + 1;
		     goto end_char_loop;
		end;

		if ch < ch1 then do;
		     do i = lastin_high_column to lastin_cur_column + 1 by -1;
			substr (outp -> outstring, i+2, 1) = substr (outp -> outstring, i, 1);
		     end;
		     if lastin_high_column + 2 > bv_num_output
		     then goto crump;
		     substr (outp -> outstring, lastin_cur_column+1, 2) = ch || ascii_value_$BS;
		     lastin_high_column = lastin_high_column + 2;
		     lastin_cur_column = lastin_cur_column + 3;
scan_loop:
		     if lastin_cur_column ^= lastin_high_column
		     then if substr (outp -> outstring, lastin_cur_column+1, 1) = ascii_value_$BS
			then do;
			     lastin_cur_column = lastin_cur_column + 2;
			     goto scan_loop;
			end;
		end;
		else if ch1 < ch
		then do;
		     lastin_cur_column = lastin_cur_column + 1;
		     if lastin_cur_column = lastin_high_column
		     then do;
			if lastin_high_column + 2 > bv_num_output
			then goto crump;
			substr (outp -> outstring, lastin_cur_column+1, 2) = ascii_value_$BS || ch;
			lastin_cur_column, lastin_high_column = lastin_cur_column + 2;
			goto end_char_loop;
		     end;
		     if do_can
		     then if substr (outp -> outstring, lastin_cur_column+1, 1) = ascii_value_$BS
			then do;
			     lastin_cur_column = lastin_cur_column + 1;
			     goto insert_after_char;
			end;

		     do i = lastin_high_column to lastin_cur_column by -1;
			substr (outp -> outstring, i+2, 1) = substr (outp -> outstring, i, 1);
		     end;
		     substr (outp -> outstring, lastin_cur_column, 2) = ch || ascii_value_$BS;
		     lastin_high_column = lastin_high_column + 2;
		     lastin_cur_column = lastin_cur_column + 2;
		end;
	     end;

	     return;

	end normal_character;

/*  */

control_character:
	procedure ();

	     if ch = ascii_value_$NL
	     then do;				/* terminate the current line */
trailing:
		if lastin_high_column ^= 0
		then if substr (outp -> outstring, lastin_high_column, 1) = space
		     then do;
			lastin_high_column = lastin_high_column - 1;
			goto trailing;
		     end;
		lastin_high_column = lastin_high_column + 1;
		substr (outp -> outstring, lastin_high_column, 1) = ascii_value_$NL; /* add new line to end */

/* ADDITION */

		if longsw
		then do;
		     position_start, position_end = 1;
		     do while (position_end < lastin_high_column + 1);
			last_position_start = max (position_start, 1);
			position_start = position_end;
			if do_can
			then do position_end = position_end + 1 by 2 while (position_end <= lastin_high_column);
			     if substr (outp -> outstring, position_end, 1) ^= ascii_value_$BS
			     then goto out;
			end;
out:
			if position_end = position_start
			then position_end = position_end + 1;
			if substr (outp -> outstring, position_start, 1) = escape
			then do;
			     if ^ do_esc
			     then goto check_erkl;
			     j = 0;
			     do i = position_start+1 to position_start+3 while (substr (outp -> outstring, i, 1)<"8"&substr (outp -> outstring, i, 1) >= "0");
				j = j * 8 + cv_oct_check_ (substr (outp -> outstring, i, 1), 0);
			     end;
			     i = i - 1;

			     if i = position_start
			     then do;
				ch1 = substr (outp -> outstring, i + 1, 1);
				if ch1 = erase then goto shift;
				if ch1 = kill then goto shift;
				if ch1 = escape
				then do;
shift:
				     substr (outp -> outstring, position_start) = substr (outp -> outstring, position_end);
				     lastin_high_column = lastin_high_column - 1;
				end;
				else if do_tty33
				then do;
				     if (ch1 >= "A" & ch1 <= "Z")
				     then;
				     else if ch1 = minus
				     then ch1 = ascii_value_$BS;
				     else if ch1 = apostrophe
				     then ch1 = grave;
				     else if ch1 = lparen
				     then ch1 = lbrace;
				     else if ch1 = rparen
				     then ch1 = rbrace;
				     else if ch1 = exc_pt
				     then ch1 = vert_bar;
				     else if ch1 = equals
				     then ch1 = tilde;
				     else goto real_escape;
				     substr (outp -> outstring, position_end, 1) = ch1;
				     goto shift;
real_escape:
				end;
			     end;
			     else do;
						/*			     addr (outp -> chars (position_start-1)) -> bit9 = bit (binary (j, 9)); SB except for Compiler error 332 */
				unspec (outp -> chars (position_start-1)) = bit (binary (j, 9));
				substr (outp -> outstring, position_start + 1) = substr (outp -> outstring, i+1);
				lastin_high_column = lastin_high_column - i + position_start;
				position_end, position_start = position_start + 1;
			     end;
			end;

			else
check_erkl:
			if do_erkl
			then if index (substr (outp -> outstring, position_start, position_end - position_start), erase) ^= 0
			     then do;
				if position_end - position_start = 1
				then do;
				     if substr (outp -> outstring, last_position_start, 1) = space
				     then do last_position_start = last_position_start to 1 by -1
					     while (substr (outp -> outstring, last_position_start - 1, 1) = space
					     | substr (outp -> outstring, last_position_start - 1, 1) = ascii_value_$HT);
				     end;
				     substr (outp -> outstring, last_position_start) = substr (outp -> outstring, position_end);
				     lastin_high_column = lastin_high_column - position_end + last_position_start;
				     position_start = last_position_start - 1;
				     position_end = last_position_start;
				end;
				else do;
				     substr (outp -> outstring, position_start) = substr (outp -> outstring, position_end);
				     lastin_high_column = lastin_high_column - position_end + position_start;
				     position_end = position_start;
				     position_start = position_start - 1;
				end;
			     end;

			     else if index (substr (outp -> outstring, position_start, position_end - position_start), kill) ^= 0
			     then do;
				substr (outp -> outstring, 1) = substr (outp -> outstring, position_end);
				lastin_high_column = lastin_high_column - position_end + 1;
				position_start = 0;
				position_end = 1;
			     end;
		     end;
		     if lastin_high_column > 1 then
			if substr (outp -> outstring, lastin_high_column - 1, 1) = escape
			then do;
			     lastin_cur_column, lastin_high_column = lastin_high_column - 2;
			     column = 0;
			     goto end_char_loop;
			end;
		end;

/* END ADDITION */
		bv_num_output_trans = bv_num_output_trans + lastin_high_column; /* add line to file */
		outp = addr (outp -> chars (lastin_high_column)); /* make outp point to end of output */
		lastin_high_column, column, lastin_cur_column = 0; /* we are at beginning */
		return;
	     end;

	     if ch = ascii_value_$RT
	     then do;
		lastin_cur_column, column = 0;	/* back to beginning of line */
		return;
	     end;

	     if ch = ascii_value_$BS
	     then if do_can
		then do;				/* back up a character position */
		     column = max (column-1, 0);
		     if lastin_cur_column = lastin_high_column then
			if lastin_cur_column > 0 then
			     if substr (outp -> outstring, lastin_cur_column, 1) = space
			     then do;		/* forget space on end of line */
				lastin_cur_column, lastin_high_column = lastin_cur_column - 1;
				goto end_char_loop;
			     end;
		     if lastin_cur_column > 0 then
			if substr (outp -> outstring, lastin_cur_column, 1) = ascii_value_$HT
			then do;
			     extra_space_count = 0;
			     do j = lastin_cur_column - 1 to 1 by -1;
				ch = substr (outp -> outstring, j, 1);
				if ch = ascii_value_$NL then goto found_tenmod;
				if ch = ascii_value_$HT then goto found_tenmod;
				if ch = ascii_value_$RT then goto found_tenmod;
				if ch = ascii_value_$BS then extra_space_count = extra_space_count - 1;
				else extra_space_count = mod (extra_space_count+ 1, 10);
			     end;
found_tenmod:
			     extra_space_count = 9 - extra_space_count;
			     lastin_high_column = lastin_high_column + extra_space_count;
			     if lastin_high_column ^= lastin_cur_column then
				substr (outp -> outstring, lastin_cur_column) = substr (space, 1, extra_space_count + 1)
				|| substr (outp -> outstring, lastin_cur_column + 1, lastin_high_column - lastin_cur_column - extra_space_count);
			     lastin_cur_column = lastin_cur_column + extra_space_count - 1;
			     goto end_char_loop;
			end;

		     lastin_cur_column = lastin_cur_column - 1; /* look back */
back_up:
		     if lastin_cur_column <= 0 then
			lastin_cur_column = 0;
		     else if substr (outp -> outstring, lastin_cur_column, 1) = ascii_value_$BS
		     then do;			/* must back to beginning of char position */
			lastin_cur_column = lastin_cur_column - 2;
			goto back_up;
		     end;
		     return;
		end;

		else goto end_char_loop;

	     if ch = ascii_value_$HT
	     then do;				/* reluctantly let them through, rmaining ever vigilant	*/
		i = column;
		if tabs_ptr = null ()
		then column = column + tabsize - mod (column, tabsize); /* next tab stop */
		else do;
		     if column < length (tabs_ptr -> tab_string)
		     then do;
			temp_number = index (substr (tabs_ptr -> tab_string, (column + 1) + 1), "1"b);
			if temp_number = 0
			then column = length (tabs_ptr -> tab_string) + 1;
			else column = (column + 1) + temp_number - 1;
		     end;
		end;
		if lastin_cur_column = lastin_high_column
		then do;
		     if allow_tabs
		     then do;
			substr (outp -> outstring, lastin_high_column+1, 1) = ascii_value_$HT; /* add enough to column count */
			if lastin_high_column + 1 > bv_num_output
			then goto crump;
			lastin_high_column, lastin_cur_column = lastin_high_column + 1;
		     end;
		     else do;
			do i = i by 1 to column - 1;
			     substr (outp -> outstring, lastin_high_column+1, 1) = space;
			     if lastin_high_column + 1 > bv_num_output
			     then goto crump;
			     lastin_high_column, lastin_cur_column = lastin_high_column + 1;
			end;
		     end;
		     goto end_char_loop;
		end;
		else if column > high_column
		then do;
		     i = column - high_column;
		     if lastin_high_column + i > bv_num_output
		     then goto crump;
		     substr (outp -> outstring, lastin_high_column + 1, i) = space;
		     lastin_high_column, lastin_cur_column = lastin_high_column + i;
		end;
		else if do_can
		then do;
		     do lastin_cur_column = lastin_cur_column + 1 to lastin_high_column while (i <= column);
			if substr (outp -> outstring, lastin_cur_column, 1) = ascii_value_$RT
			then i = 0;
			else if substr (outp -> outstring, lastin_cur_column, 1) = ascii_value_$BS
			then i = i - 1;
			else i = i + 1;
		     end;
		     lastin_cur_column = lastin_cur_column - 1;
		end;
		goto end_char_loop;
	     end;

	     call normal_character ();

	     return;

	end control_character;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

     end net_canonicalize_;




		    net_convert_bytesize_.pl1       09/23/77  1035.2rew 09/22/77  1724.6      218367



net_convert_bytesize_:
          procedure ();

/*             "net_convert_bytesize_" -- a collection of procedures used in    */
/*        converting from Network characters (8 bits) to Multics characters (9  */
/*        bits).  The most common subsets of conversions are here so that, if   */
/*        necessary, this module can be converted to assembly language for      */
/*        efficiency.                                                           */
/*             The interfaces to all entries in this module are identical:      */
/*        The info_ptr is ignored (but is here because it makes the calling     */
/*        sequence of this entries similar to others having to do with code     */
/*        conversion (and someday, it just might be useful).                    */
/*        The input_ptr and output_ptr parameters point to an I/O workspace     */
/*        (i.e., word aligned).  The next_XXX argument indicates the next       */
/*        available (from the beginning) byte to be read from/stored into.      */
/*        The last_XXX argument indicates the last available byte.  Notice      */
/*        that the next_XXX argument is thus both an input and an output arg.   */

/*        Originally written by D. M. Wells 30 April, 1974.                     */


          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_next_in fixed binary (24),                     /* next byte in workspace to process              */
          bv_last_in fixed binary (24),                     /* last byte in workspace to process              */
          bv_next_out fixed binary (24),                    /* next available byte in output workspace        */
          bv_last_out fixed binary (24),                    /* last available byte in output workspace        */

          bv_error_code bit (36) aligned,                   /* always returned as zero                        */
          bv_info_ptr pointer,                              /* unused, makes arg list similar to other procs  */
          bv_input_ptr pointer,                             /* points to input I/O workspace                  */
          bv_output_ptr pointer)                            /* points to output I/O workspace                 */
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (byte_num_in fixed binary (3) initial (-1),        /* byte offset (within element) of next input     */
          byte_num_out fixed binary (3) initial (-1),       /* byte offset (within element) of next output    */
          next_in fixed binary (24) initial (bv_next_in),   /* automatic copy of bv_next_in                   */
          next_out fixed binary (24) initial (bv_next_out), /* automatic copy of bv_next_out                  */
          last_in fixed binary (24) initial (bv_last_in),   /* automatic copy of bv_last_in                   */
          last_out fixed binary (24) initial (bv_last_out), /* automatic copy of bv_last_out                  */
          string_offset fixed binary (18),
          current_byte bit (9),
          temp_byte bit (9),                                /* used to remember last byte during lookahead    */
          in_string_ptr pointer,                            /* points to current input element                */
          out_string_ptr pointer,                           /* points to current output element               */
          input_ptr pointer initial (bv_input_ptr),         /* automatic copy of bv_input_ptr                 */
          output_ptr pointer initial (bv_output_ptr))       /* automatic copy of bv_output_ptr                */
               automatic;

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
         (based_bit72_algn bit (72) aligned,
          based_bit36_array (0 : 1) bit (36) aligned,
          based_bit72_array (0 : 1) bit (72) aligned)
               based;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          (addr, substr)
               builtin;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include telnet_special_chars;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      Because PL/1 doesn't have a feature which implements the      */
                                        /* converse of the initial attribute, we cause all returns to go here */
                                        /* so that we can update the arguments to this procedure from the     */
                                        /* automatic copies that we created with an initial attribute (or     */
                                        /* that are constants like the error code).                           */

return_to_caller:
          bv_next_out = next_out;
          bv_next_in = next_in;

          bv_error_code = ""b;

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      This entry point does a particular translation of Multics     */
                                        /* ASCII to Network ASCII.  In particular, it only implements the     */
                                        /* CR-LF -> NL, CR-NUL -> CR, and NUL -> /0 conversions.  In general,  */
                                        /* programs will have to do separate translations for conversions     */
                                        /* not performed here.  These other translations can generally be     */
                                        /* performed by a PL/1 translate statement.                           */

ascii_8_to_9:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_8_bits ();

               if current_byte >= "000100000"b              /* (SPACE) -- All controls are less than space    */
               then call store_9_bits ();                   /* non-control, just store it                     */
               else if current_byte = "000001101"b
                    then do;                                /* this is a CR, look at next char for info       */
                         if next_in + 1 > last_in
                         then goto return_to_caller;        /* see if we can look at one more character       */

                         next_in = next_in + 1;             /* update to next character                       */
                         call fetch_8_bits ();              /* fetch the next input byte                      */
                         if current_byte = "000001010"b
                         then call store_9_bits ();         /* store this NL character                        */
                         else if current_byte = "000000000"b
                              then do;
                                   current_byte = "000001101"b;       /* this was CR-NUL, store a CR          */
                                   call store_9_bits ();
                                   end;
                              else do;                      /* PROTOCOL VIOLATION -- but attempt to recover   */
                                   current_byte = "000001101"b;       /* pick up a CR again                   */
                                   call store_9_bits ();              /* and store it                         */

                                   next_in = next_in - 1;             /* back down on the input byte num      */
                                   byte_num_in = -1;                  /* and cause recomputation of byte num  */
                                   end;
                         end;
                    else if current_byte ^= "000000000"b              /* pass through all but NULs            */
                         then call store_9_bits ();
               end;

          goto return_to_caller;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      This entry converts from 8 bits to 9 bits, but is for the use */
                                        /* of programs using the TELNET protocol.  All IACs in the input      */
                                        /* are converted to an internal form of IAC.  The use of this is that */
                                        /* such programs can retranslate all such tIAC-tIAC to a data IAC     */
                                        /* and can use the tIAC as an end of processed input pointer.         */

telnet_8_to_9:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_8_bits ();

               if current_byte = NET_IAC
               then current_byte = OUR_IAC;

               call store_9_bits ();
               end;

          goto return_to_caller;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      This entry converts from 8 bits to 9 bits (and nothing else). */

direct_8_to_9:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_8_bits ();

               call store_9_bits ();
               end;

          goto return_to_caller;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

fetch_8_bits:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto fetch_eight (byte_num_in);

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (-1):
          string_offset = divide (next_in, 9, 24, 0);       /* which 72-bit element are we referencing        */
          byte_num_in = next_in - 9 * string_offset;        /* now which 8-bit byte in that element           */
          in_string_ptr = addr (input_ptr -> based_bit72_array (string_offset));          /* addr of element  */

          goto fetch_eight (byte_num_in);


                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (0):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 1, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 1, but use an "aos" instruction        */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (1):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 9, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 2, but use an "aos" instruction        */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (2):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 17, 8);
          byte_num_in = byte_num_in + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (3):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 25, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 4, but use an "aos" instruction        */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (4):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 33, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 5                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (5):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 41, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 6                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (6):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 49, 8);
          byte_num_in = byte_num_in + 1;                    /* will be 7                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (7):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 57, 8);
          byte_num_in = byte_num_in + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_eight (8):
          current_byte = "0"b || substr (in_string_ptr -> based_bit72_algn, 65, 8);
          byte_num_in = 0;
          in_string_ptr = addr (in_string_ptr -> based_bit72_array (1));        /* move to next element       */

          return;

end fetch_8_bits;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

store_9_bits:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if next_out > last_out
          then goto return_to_caller;

          next_out = next_out + 1;

          goto store_nine (byte_num_out);

                    /* * * * * * * * * * * * * * * * * * * */

store_nine (-1):
          string_offset = divide ((next_out - 1), 4, 18, 0);          /* which 36-bit element is referenced   */
          byte_num_out = (next_out - 1) - 4 * string_offset;          /* which byte in that 36-bit element    */
          out_string_ptr = addr (output_ptr -> based_bit36_array (string_offset));        /* addr of element  */

          goto store_nine (byte_num_out);

                    /* * * * * * * * * * * * * * * * * * * */

store_nine (0):
          substr (out_string_ptr -> based_bit72_algn, 1, 9) = current_byte;
          byte_num_out = byte_num_out + 1;                    /* will be 1, but use "aos" instruction           */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_nine (1):
          substr (out_string_ptr -> based_bit72_algn, 10, 9) = current_byte;
          byte_num_out = byte_num_out + 1;                    /* will be 2, but use "aos" instruction           */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_nine (2):
          substr (out_string_ptr -> based_bit72_algn, 19, 9) = current_byte;
          byte_num_out = byte_num_out + 1;                    /* will be 3                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_nine (3):
          substr (out_string_ptr -> based_bit72_algn, 28, 9) = current_byte;
          byte_num_out = 0;
          out_string_ptr = addr (out_string_ptr -> based_bit36_array (1));      /* move to next element       */

          return;

end store_9_bits;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      This entry point translates from 9 bits to 8 bits and in the  */
                                        /* process converts Multics ASCII to Network ASCII.  This includes    */
                                        /* NL -> CR-LF, CR -> CR-NUL, PAD -> /0.                               */

ascii_9_to_8:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_9_bits ();

               if current_byte >= "000100000"b
               then do;                                     /* if above SP                                    */
                    if current_byte ^= "001111111"b         
                    then call store_8_bits ();              /* then store, if not a PAD                       */
                    end;
               else do;                                     /* else this is a control character               */
                    if current_byte = "000001010"b
                    then do;                                /* this is a NL character, handle specially       */
                         if next_out + 1 > last_out
                         then goto return_to_caller;        /* we dont have enough room left, give up         */

                         current_byte = "000001101"b;       /* NL gets replaced by CR-LF                      */
                         call store_8_bits ();
                         current_byte = "000001010"b;
                         call store_8_bits ();
                         end;
                    else if current_byte = "000001101"b
                         then do;                           /* this is a CR character, handler specially      */
                              if next_out + 1 > last_out
                              then goto return_to_caller;   /* we dont have enough room left, give up         */

                              call store_8_bits ();         /* store the CR and then follow it by a NUL       */
                              current_byte = "000000000"b;
                              call store_8_bits ();
                              end;
                         else call store_8_bits ();         /* otherwise, just store the random character     */
                    end;

               end;

          goto return_to_caller;

          /* * * * * * * * * ** * * * * * * * * * * * * * */

                                        /*      This entry point translates from 9 bits to 8 bits and in the  */
                                        /* process doubles any IACs that it may find.  Thus this entry may be */
                                        /* used by a TELNET processor to write out data (as opposed to        */
                                        /* TELNET commands).                                                  */

telnet_9_to_8:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_9_bits ();

               if current_byte = NET_IAC
               then call store_8_bits ();

               call store_8_bits ();
               end;

          goto return_to_caller;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

                                        /*      This entry converts from 9 bits to 8 bits (and nothing else). */

direct_9_to_8:
          entry (bv_info_ptr, bv_input_ptr, bv_next_in, bv_last_in,
                    bv_output_ptr, bv_next_out, bv_last_out, bv_error_code);

          do next_in = next_in by 1 to last_in;
               call fetch_9_bits ();

               call store_8_bits ();
               end;

          goto return_to_caller;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

store_8_bits:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if next_out > last_out
          then goto return_to_caller;

          next_out = next_out + 1;

          goto store_eight (byte_num_out);

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (-1):
          string_offset = divide ((next_out - 1), 9, 18, 0);          /* which 72-bit element is referenced   */
          byte_num_out = (next_out - 1) - 9 * string_offset;          /* which byte in that 72-bit element    */
          out_string_ptr = addr (output_ptr -> based_bit72_array (string_offset));        /* addr of element  */

          goto store_eight (byte_num_out);

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (0):
          substr (out_string_ptr -> based_bit72_algn, 1, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* will be 1, but use an "aos" instruction        */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (1):
          substr (out_string_ptr -> based_bit72_algn, 9, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* wil be 1, but use an "aos" instruction         */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (2):
          substr (out_string_ptr -> based_bit72_algn, 17, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (3):
          substr (out_string_ptr -> based_bit72_algn, 25, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* will be 4, but use an "aos" instruction        */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (4):
          substr (out_string_ptr -> based_bit72_algn, 33, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* will be 5                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (5):
          substr (out_string_ptr -> based_bit72_algn, 41, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* will be 6                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (6):
          substr (out_string_ptr -> based_bit72_algn, 49, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;                  /* will be 7                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (7):
          substr (out_string_ptr -> based_bit72_algn, 57, 8) = substr (current_byte, 2, 8);
          byte_num_out = byte_num_out + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

store_eight (8):
          substr (out_string_ptr -> based_bit72_algn, 65, 8) = substr (current_byte, 2, 8);

          byte_num_out = 0;
          out_string_ptr = addr (out_string_ptr -> based_bit72_array (1));      /* move to next element       */

          return;

end store_8_bits;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

fetch_9_bits:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto fetch_nine (byte_num_in);

                    /* * * * * * * * * * * * * * * * * * * */

fetch_nine (-1):
          string_offset = divide (next_in, 4, 18, 0);       /* which 36-bit element are we referencing        */
          byte_num_in = next_in - 4 * string_offset;        /* which byte in that 36-bit element              */
          in_string_ptr = addr (input_ptr -> based_bit36_array (string_offset));          /* addr of element  */

          goto fetch_nine (byte_num_in);

                    /* * * * * * * * * * * * * * * * * * * */

fetch_nine (0):
          current_byte = substr (in_string_ptr -> based_bit72_algn, 1, 9);
          byte_num_in = byte_num_in + 1;                    /* will be 1, but use "aos" instruction           */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_nine (1):
          current_byte = substr (in_string_ptr -> based_bit72_algn, 10, 9);
          byte_num_in = byte_num_in + 1;                    /* will be 2, but use "aos" instruction           */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_nine (2):
          current_byte = substr (in_string_ptr -> based_bit72_algn, 19, 9);
          byte_num_in = byte_num_in + 1;                    /* will be 3                                      */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

fetch_nine (3):
          current_byte = substr (in_string_ptr -> based_bit72_algn, 28, 9);
          byte_num_in = 0;
          in_string_ptr = addr (in_string_ptr -> based_bit36_array (1));        /* move to next element       */

          return;

end fetch_9_bits;


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_convert_bytesize_;




		    net_convert_input_.pl1          09/23/77  1035.2rew 09/22/77  1723.9      136233



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1974 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

net_convert_input_:
          procedure (bv_info_ptr, bv_input_ptr, bv_next_input, bv_last_input,
                    bv_output_ptr, bv_next_output, bv_last_output, bv_error_code);

/*             "net_convert_input_" -- this procedure is used to convert from   */
/*        device specific character codes to Multics internal ASCII (generally) */
/*        over the network.  This procedure actually shuffles chars from the    */
/*        input buffer (containing device specific codes) to the output buffer  */
/*        (to contain Multics ASCII after processing) and is memory-free.  All  */
/*        information about device state is contained in a structure pointed to */
/*        by the first argument.  This procedure is able to backup by not       */
/*        updating its argument list until a character has been entirely        */
/*        processed.

/*        Originally created by D. M. Wells on 1973, December 17 from a         */
/*             previously existing privately maintained IOSIM.                  */
/*        Last modifed by D. M. Wells in Summer, 1974.                          */


          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         ((bv_last_input, bv_last_output, bv_next_input, bv_next_output) fixed binary (24),
          bv_error_code bit (36) aligned,
          (bv_info_ptr, bv_input_ptr, bv_output_ptr) pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         ((next_out, temp_next_in) fixed binary (24),
          tabincr fixed binary (24),
          current_character bit (9),
          (header_ptr, table_ptr) pointer)
               automatic;

     declare
          1 device_state aligned automatic like device_state_template;

     declare
          1 input_descriptor aligned automatic like input_descriptor_template;

          /* * * * * DEFINED DECLARATIONS  * * * * * * * * */

     declare
          1 device_state_original aligned like device_state_template defined (bv_info_ptr -> device_state_template);

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
          1 input_descriptor_array (0 : 255) aligned based like input_descriptor_template;


     declare
          1 based_workspace aligned based,
             2 byte (0 : 1) bit (9) unaligned;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          (addrel, binary, bit, max, mod, null, string, unspec)
               builtin;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include net_conversion_dcls;
          % include net_device_table_dcls;
          % include telnet_special_chars;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

          bv_error_code = ""b;

          unspec (device_state) = unspec (bv_info_ptr -> device_state_template);

          header_ptr = device_state.device_table_ptr;
          table_ptr = device_state.input_table_ptr;

          next_out = bv_next_output;

          do bv_next_input = bv_next_input by 1 to bv_last_input;
               current_character = bv_input_ptr -> based_workspace.byte (bv_next_input);

               if binary (current_character, 9) > 255
               then call process_protocol ();               /* this is a (translated) protocol character      */
               else call process_normal_character ();       /* this character is in normal data space         */

               unspec (bv_info_ptr -> device_state_template.terminal_state) = unspec (device_state.terminal_state);
               bv_next_output = next_out;
               end;

return_to_caller_for_more_input:

return_to_caller_for_more_space:
          bv_error_code = ""b;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

process_normal_character:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if table_ptr = null ()
          then do;                                          /* if raw input mode, just pass these through     */
               call put_byte ();
               return;
               end;

          string (input_descriptor) = string (table_ptr -> input_descriptor_array (binary (current_character, 9)));
          current_character = input_descriptor.translated_character;

          if input_descriptor.escape_list_rel ^= ""b
          then do;
               temp_next_in = bv_next_input + 1;
               if found_escape_list (addrel (header_ptr, bit (binary (input_descriptor.escape_list_rel, 18))))
               then do;
                    bv_next_input = temp_next_in;
                    end;
               end;

          if ^ input_descriptor.ignore_this_character
          then call put_byte ();

          call type_processing ();
          call column_processing ();
          call line_processing ();

          device_state.desired_column = device_state.actual_column;   /* update to actual position            */
          device_state.desired_line = device_state.actual_line;

          return;

end process_normal_character;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

process_protocol:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if current_character = OUR_NOP
          then return;                                      /* we just plain ignore nop's                     */

          if current_character = OUR_DM
          then return;                                      /* we also currently ignore data marks            */

          call put_byte ();                                 /* otherwise, let the character through           */

          return;

end process_protocol;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

put_byte:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if next_out > bv_last_output
          then goto return_to_caller_for_more_space;

          bv_output_ptr -> based_workspace.byte (next_out) = current_character;
          next_out = next_out + 1;

          return;

end put_byte;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

type_processing:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto character_type (binary (input_descriptor.special_functions, 3));

                    /* * * * * * * * * * * * * * * * * * * */

character_type (0):                               /* nothing special about this particular character   */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

character_type (1):                               /* this is a normal visible character   */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

character_type (2):                               /* this is a redshift character                   */
character_type (3):                               /* this is a blackshift character                 */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

character_type (4):                               /* this is an audible character         */
          return;

end type_processing;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

column_processing:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          1 line_overflow_sequence aligned automatic,
             2 byte (0 : 2) bit (9) unaligned;

     declare
          1 spaces_workspace aligned automatic,
             2 chars (10) character (1) unaligned;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto width (binary (input_descriptor.horizontal_movement, 5));

                    /* * * * * * * * * * * * * * * * * * * */

width (0):                                        /* No action, this character has no width                   */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (1):                                        /* This character takes one normal space                    */
          device_state.actual_column = device_state.actual_column + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (2):                                        /* This character is a backspace character.                 */
          device_state.actual_column = max (0, device_state.actual_column - 2);

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (3):                                        /* This character is a carriage return character.           */
          device_state.actual_column = 0;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (4):                                        /* This character moves to the end of the line              */
          device_state.actual_column = device_state.line_length;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (5):                                        /* This is a horizontal tabulation character.               */
          tabincr = 9 - mod (device_state.actual_column, 10);

          device_state.actual_column = device_state.actual_column + tabincr + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (6):                                        /* This character takes two normal spaces                   */
          device_state.actual_column = device_state.actual_column + 2;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (7):                                        /* This character takes three normal spaces                 */
          device_state.actual_column = device_state.actual_column + 3;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (8):

          return;

end column_processing;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

line_processing:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto height (binary (input_descriptor.vertical_movement, 5));

                    /* * * * * * * * * * * * * * * * * * * */

height (0):                                       /* No action, this character has no height                  */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (1):                                       /* This character moves the curpos position one line down   */
          device_state.actual_line = device_state.actual_line + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (2):                                       /* This character moves the curpos up one line              */
          device_state.actual_line = max (0, device_state.actual_line - 1);

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (3):                                       /* This character moves the curpos to the top of the page   */
          device_state.actual_line = 0;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (4):                                       /* The character moves the curpos to the end of the page    */
          device_state.actual_line = device_state.page_length;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (5):                                       /* This character moves the curpos to the next tab stop.    */
          tabincr = 9 - mod (device_state.actual_line, 10);

          device_state.actual_line = device_state.actual_line + tabincr;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (6):                                       /* This character moves the curpos two lines down           */
          device_state.actual_line = device_state.actual_line + 2;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (7):                                       /* This character moves the curpos three lines down         */
          device_state.actual_line = device_state.actual_line + 3;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (8):
          return;

end line_processing;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

found_escape_list:
          procedure (bv_escape_list_ptr) returns (bit (1));

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
          bv_escape_list_ptr pointer
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (indx fixed binary (17),
          input_position fixed binary (24),
          test_character bit (9))
               automatic;

          /* * * * * DEFINED REFERENCES  * * * * * * * * * */

/*   declare  */
/*        1 escapes aligned like input_escape_list defined (bv_escape_list_ptr -> input_escape_list);  */

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          input_position = temp_next_in;                    /* save the position of this character            */
          if input_position > bv_last_input
          then goto return_to_caller_for_more_input;

          test_character = bv_input_ptr -> based_workspace.byte (input_position);

          do indx = 1 by 1 to bv_escape_list_ptr -> input_escape_list.count;
               if test_character = bv_escape_list_ptr -> input_escape_list.escape_entry (indx).match_character
               then do;
                    if bv_escape_list_ptr -> input_escape_list.escape_entry (indx).escape_list_rel ^= ""b
                    then do;
                         temp_next_in = temp_next_in + 1;
                         if found_escape_list (addrel (header_ptr, bit (binary (bv_escape_list_ptr -> input_escape_list.escape_entry (indx).escape_list_rel, 18))))
                         then return ("1"b);                /* descriptor was changed by lower invocation     */
                         end;

                    unspec (input_descriptor) = unspec (bv_escape_list_ptr -> input_escape_list.escape_entry (indx));
                    current_character = input_descriptor.translated_character;
                    temp_next_in = input_position;
                    return ("1"b);
                    end;
               end;

          return ("0"b);

end found_escape_list;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_convert_input_;




		    net_convert_output_.pl1         09/23/77  1035.2rew 09/22/77  1725.6      242478



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1972 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1974 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

/*             "net_convert_output_" -- this procedure is used to convert from  */
/*        Multics internal ASCII (generally) to a device specific character set */
/*        to be sent over the network.  This procedure actually shuffles chars  */
/*        from the input buffer to the output buffer and is memory-free.  Thus  */
/*        all information used by this procedure is gathered from the info      */
/*        structure pointed to by the first argument.  This procedure has the   */
/*        usual conventions within the Network IOSIMs of being able to backup   */
/*        by not actually informing the calling procedure of changes until they */
/*        are complete (and updated into the parameter list).                   */

/*        originally created by D. M. Wells in October, 1973.                   */
/*        Last modified by D. M. Wells in Summer, 1974.                         */

net_convert_output_:
          procedure (bv_info_ptr, bv_input_ptr, bv_next_input, bv_last_input,
                    bv_output_ptr, bv_next_output, bv_last_output, bv_error_code);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_next_input fixed binary (24),                  /* byte offset of the first char to be looked at  */
          bv_last_input fixed binary (24),                  /* byte offset of the last char to be looked at   */
          bv_next_output fixed binary (24),                 /* byte offset of the first available output char */
          bv_last_output fixed binary (24),                 /* byte offset of the last available output char  */
          bv_error_code bit (36) aligned,                   /* standard Multics error code                    */
          bv_info_ptr pointer,                              /* points to the device state information         */
          bv_input_ptr pointer,                             /* points to the input workspace                  */
          bv_output_ptr pointer)                            /* points to the output workspace                 */
               parameter;

     declare
          1 bv_descriptor aligned parameter like output_descriptor_template;
                                                            /* descriptor to be processed in recursive call   */

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          (next_output fixed binary (24),
          use_internal_format bit (1),
          current_char bit (9),
          output_char bit (9),                              /* special byte for use with put_byte             */
          err_code bit (36) aligned,
          sequence_ptr pointer,                             /* special pointer for use with put_sequence      */
          (format_ptr, header_ptr, table_ptr) pointer)
               automatic;

     declare
          1 device_state aligned automatic like device_state_template;

     declare
          1 output_descriptor aligned automatic like output_descriptor_template;

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
          TOO_BIG fixed binary (30) initial (1073741823)    /* 2**30-1 => number bigger than fixed bin (24)   */
               internal static;

          /* * * * * DEFINED REFERENCES  * * * * * * * * * */

     declare
          1 device_state_original aligned like device_state_template defined (bv_info_ptr -> device_state_template);

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
          1 based_workspace aligned based,
             2 byte (0 : 1) bit (9) unaligned;

     declare
          1 output_descriptor_array (0 : 255) aligned based like output_descriptor_template;

          /* * * * * EXTERNAL STATIC DECLARATIONS  * * * * */

     declare
         (error_table_$badcall,
          error_table_$not_done)
               bit (36) aligned external static;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          (addr, addrel, binary, max, mod, null, string, substr, unspec)
               builtin;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include net_conversion_dcls;
          % include net_device_table_dcls;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

          bv_error_code = ""b;

          unspec (device_state) = unspec (bv_info_ptr -> device_state_template);

          header_ptr = device_state.device_table_ptr;
          table_ptr = device_state.output_table_ptr;

          use_internal_format = (header_ptr -> device_table_header.output_noopt_format_rel ^= ""b);
          if use_internal_format
          then format_ptr = addrel (header_ptr, header_ptr -> device_table_header.output_noopt_format_rel);
          else format_ptr = addrel (header_ptr, header_ptr -> device_table_header.output_format_rel);

          if device_state.in_page_wait
          then do;
               bv_error_code = error_table_$badcall;
               return;
               end;

          next_output = bv_next_output;

          do bv_next_input = bv_next_input by 1 to bv_last_input while (^ device_state.in_page_wait);
               current_char = bv_input_ptr -> based_workspace.byte (bv_next_input);    /* get one char     */
               string (output_descriptor) = string (table_ptr -> output_descriptor_array (binary (current_char, 9)));

               call process_descriptor ();

               unspec (bv_info_ptr -> device_state_template.terminal_state) = unspec (device_state.terminal_state);
               bv_next_output = next_output;
               end;

update_output_and_return_to_caller:
          call update_carriage_position ();
          unspec (bv_info_ptr -> device_state_template.terminal_state) = unspec (device_state.terminal_state);
          bv_next_output = next_output;

return_to_caller:
          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

                                                  /*      This entry point is to be called only from within   */
                                                  /* net_convert_output_.  Its purpose is to process the      */
                                                  /* complicated descriptors (which might be present for such */
                                                  /* things as line overflow sequences).                      */

process_from_descriptor:
          entry (bv_info_ptr, bv_descriptor, bv_output_ptr, bv_next_output, bv_last_output, bv_error_code);

          bv_error_code = error_table_$not_done;

          unspec (device_state) = unspec (bv_info_ptr -> device_state_template);

          header_ptr = device_state.device_table_ptr;
          table_ptr = device_state.output_table_ptr;

          use_internal_format = (header_ptr -> device_table_header.output_noopt_format_rel ^= ""b);
          if use_internal_format
          then format_ptr = addrel (header_ptr, header_ptr -> device_table_header.output_noopt_format_rel);
          else format_ptr = addrel (header_ptr, header_ptr -> device_table_header.output_format_rel);

          next_output = bv_next_output;

          unspec (output_descriptor) = unspec (bv_descriptor);

          call process_descriptor ();

          unspec (bv_info_ptr -> device_state_template.terminal_state) = unspec (device_state.terminal_state);
          bv_next_output = next_output;

          bv_error_code = ""b;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

process_descriptor:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if output_descriptor.ignore_this_character
          then return;

          if table_ptr = null ()
          then do;
               output_char = current_char;

               call put_byte ();
               return;
               end;

          call type_processing ();                          /* figure out what type of character this is      */

          return;

end process_descriptor;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

put_byte:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if next_output >= bv_last_output
          then goto return_to_caller;

          bv_output_ptr -> based_workspace.byte (next_output) = output_char;
          next_output = next_output + 1;

          return;

end put_byte;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

put_sequence:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          indx fixed binary (24)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          do indx = 1 by 1 to sequence_ptr -> sequence_template.count;
               output_char = sequence_ptr -> sequence_template.byte (indx);
               call put_byte ();
               end;

          return;

end put_sequence;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

type_processing:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          goto character_type (binary (output_descriptor.special_functions, 3));

                    /* * * * * * * * * * * * * * * * * * * */

character_type (0):                               /* there is only characters to be processed                 */
          call character_processing ();                     /* actuall insert the character(s) in the buffer  */

          return;

                    /* * * * * * * * * * * * * * * * * * * */

character_type (1):                               /* this is a normal visible character                       */
character_type (2):                               /* this is a redshift character                             */
character_type (3):                               /* this is a blackshift character                           */
character_type (4):                               /* this is an audible character                             */
          if device_state.out_of_position
          then call update_carriage_position ();                    /* get the carriage where its supposed to be      */

          call movement_processing ();                      /* figure out where this is going to put us      */

          call character_processing ();                     /* actually insert the character in buffer        */

          device_state.terminal_state.actual_column = device_state.terminal_state.desired_column;
          device_state.terminal_state.actual_line = device_state.terminal_state.desired_line;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

character_type (5):                               /* this is a whitespace character                           */
          call movement_processing ();                      /* figure out where this is going to put us       */

          device_state.terminal_state.out_of_position = "1"b;

          return;

end type_processing;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

character_processing:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          1 octal_sequence aligned automatic,
             2 byte (0 : 3) bit (9) unaligned;

          /* * * * * * * * * * * * * * * ** * * * * * * * */

          goto function_type (binary (output_descriptor.function_description, 9));

                    /* * * * * * * * * * * * * * * * * * * */

function_type (0):                                /* No action is to be taken upon this character.            */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (1):                                /* There is one character in description data to be sent.   */
          output_char = substr (output_descriptor.description_data, 1, 9);
          call put_byte ();

          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (2):                                /* There are two characters in description data to be sent.  */
          output_char = substr (output_descriptor.description_data, 1, 9);
          call put_byte ();

          output_char = substr (output_descriptor.description_data, 10, 9);
          call put_byte ();

          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (3):                                /* There is an escape sequence to be typed.                 */
          sequence_ptr = addrel (header_ptr, output_descriptor.description_data);
          call put_sequence ();

          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (4):                                /* This character is to be put in octal escape form.        */
          octal_sequence.byte (0) = header_ptr -> device_table_header.escape_char;
          octal_sequence.byte (1) = "000110"b || substr (output_descriptor.description_data, 1, 3);
          octal_sequence.byte (2) = "000110"b || substr (output_descriptor.description_data, 4, 3);
          octal_sequence.byte (3) = "000110"b || substr (output_descriptor.description_data, 7, 3);

          if ^ process_character_sequence (addr (octal_sequence), 0, 3)
          then goto update_output_and_return_to_caller;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (5):                                /* The data field has two chars to be reprocessed.          */
          if ^ process_character_sequence (addr (output_descriptor), 2, 3)
          then goto update_output_and_return_to_caller;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

function_type (6):
          sequence_ptr = addrel (header_ptr, output_descriptor.description_data);

          if ^ process_character_sequence (sequence_ptr, 1, (sequence_ptr -> sequence_template.count))
          then goto update_output_and_return_to_caller;

          return;

end character_processing;

/* * * * * * * * * * * * ** * * * * * * * * * * * * * * * */

movement_processing:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          (col_overrun, new_column, new_line) fixed binary (24)
               automatic;

     declare
          1 line_overflow_sequence aligned automatic,
             2 byte (0 : 2) bit (9) unaligned;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

recheck_character:
          if device_state.in_page_wait
          then goto update_output_and_return_to_caller;

          call check_character_width ();                    /* sets the variable new_column                   */
          call check_character_height ();                   /* sets the variable new_line                     */

          if new_line >= device_state.page_length
          then if device_state.page_length > 0
               then do;
                    if ^ process_from_this_descriptor (header_ptr -> device_table_header.page_overflow_descriptor)
                    then goto return_to_caller;
                    call update_carriage_position ();

                    device_state.in_page_wait = "1"b;

                    goto recheck_character;
                    end;

          if new_column > device_state.line_length
          then do;
               if device_state.line_length > 0
               then do;                                     /* if this would overflow the printing line       */
/*                  col_overrun = max (device_state.desired_column - device_state.line_length - 1, 0);  */

                    if ^ process_from_this_descriptor (header_ptr -> device_table_header.line_overflow_descriptor)
                    then goto update_output_and_return_to_caller;
                    call update_carriage_position ();

                    goto recheck_character;
                    end;
               end;

          device_state.desired_column = new_column;
          device_state.desired_line = new_line;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

check_character_width:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          1 spaces_workspace aligned automatic,
             2 chars (10) character (1) unaligned;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          new_column = device_state.desired_column;

          goto width (binary (output_descriptor.horizontal_movement, 5));

                    /* * * * * * * * * * * * * * * * * * * */

width (0):                                        /* No action, this character has no width                   */
          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (1):                                        /* This character takes one normal space                    */
          new_column = new_column + 1;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (2):                                        /* This character is a backspace character.                 */
          new_column = max (0, new_column - 1);

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (3):                                        /* This character is a carriage return character.           */
          new_column = 0;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (4):                                        /* This character moves to the end of the line              */
          new_column = device_state.line_length;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (5):                                        /* This is a horizontal tabulation character.               */
          new_column = new_column + 10 - mod (new_column, 10);

          return;

width (6):                                        /* This character takes two horiz positions                 */
          new_column = new_column + 2;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (7):                                        /* This character takes three horiz positions               */
          new_column = new_column + 3;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

width (8):
          return;

end check_character_width;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

check_character_height:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          new_line = device_state.desired_line;

          goto height (binary (output_descriptor.vertical_movement, 5));

                    /* * * * * * * * * * * * * * * * * * * */

height (0):                                       /* No action, this character takes no vertical movement     */
          return;

height (1):                                       /* This character takes one vertical column                 */
          new_line = new_line + 1;

          return;

height (2):                                       /* This character moves up one vertical position            */
          new_line = max (0, new_line -1);

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (3):                                       /* This character moves to the top of the page              */
          new_line = 0;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (4):                                       /* This character moves to the end of the page              */
          new_line = device_state.page_length;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (5):                                       /* This character moves to the next tab stop                */
          new_line = new_line + 10 - mod (new_line, 10);

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (6):                                       /* This character moves down two lines                      */
          new_line = new_line + 2;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (7):                                       /* This character moves down three lines                    */
          new_line = new_line + 3;

          return;

                    /* * * * * * * * * * * * * * * * * * * */

height (8):
          return;

end check_character_height;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end movement_processing;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

update_carriage_position:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          next_HT fixed binary (30)
               automatic;

     declare
          1 saved_output_descriptor aligned automatic like output_descriptor_template;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if use_internal_format
          then do;
               unspec (saved_output_descriptor) = unspec (output_descriptor);

               do while (device_state.desired_line ^= device_state.actual_line);
                    if device_state.desired_line > device_state.actual_line
                    then do;
                         unspec (output_descriptor) = unspec (format_ptr -> output_format_template.NL_descriptor);
                         call character_processing ();
                         device_state.actual_line = device_state.actual_line + 1;
                         device_state.actual_column = 0;
                         end;
                    else if device_state.desired_line < device_state.actual_line
                         then device_state.actual_line = device_state.desired_line;       /* messed-up table  */
                    end;

               do while (device_state.desired_column ^= device_state.actual_column);
                    if device_state.desired_column > device_state.actual_column
                    then do;
                         if ^ device_state.hor_tabs_out
                         then next_HT = TOO_BIG;
                         else next_HT = device_state.actual_column + 10 - mod (device_state.actual_column, 10);

                         if next_HT <= device_state.desired_column
                         then do;
                              unspec (output_descriptor) = unspec (format_ptr -> output_format_template.HT_descriptor);
                              call character_processing ();
                              device_state.actual_column = next_HT;
                              end;
                         else do;
                              unspec (output_descriptor) = unspec (format_ptr -> output_format_template.SP_descriptor);
                              call character_processing ();
                              device_state.actual_column = device_state.actual_column + 1;
                              end;
                         end;
                    else do;
                         if device_state.desired_column = 0
                         then do;
                              unspec (output_descriptor) = unspec (format_ptr -> output_format_template.CR_descriptor);
                              call character_processing ();
                              device_state.actual_column = 0;
                              end;
                         else do;
                              unspec (output_descriptor) = unspec (format_ptr -> output_format_template.BS_descriptor);
                              call character_processing ();
                              device_state.actual_column = device_state.actual_column - 1;
                              end;
                         end;
                    end;

               unspec (output_descriptor) = unspec (saved_output_descriptor);
               end;

          device_state.terminal_state.out_of_position = "0"b;

          return;

end update_carriage_position;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


process_character_sequence:
          procedure (bv_sequence_ptr, bv_first_in_sequence, bv_last_in_sequence) returns (bit (1));

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         ((bv_first_in_sequence, bv_last_in_sequence) fixed binary (24),
          bv_sequence_ptr pointer)
               parameter;

     declare
          1 bv_output_descriptor aligned parameter like output_descriptor_template;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         ((sub_last_input, sub_next_input) fixed binary (24),
          sub_sequence_ptr pointer)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          sub_next_input = bv_first_in_sequence;
          sub_last_input = bv_last_in_sequence;
          sub_sequence_ptr = bv_sequence_ptr;

          call net_convert_output_ (addr (device_state), sub_sequence_ptr, sub_next_input, sub_last_input,
                    bv_output_ptr, next_output, bv_last_output, err_code);

          if sub_next_input <= sub_last_input
          then return ("0"b);

          return ("1"b);

          /* * * * * * * * * * * * * * * * * * * * * * * * */

process_from_this_descriptor:
          entry (bv_output_descriptor) returns (bit (1));

          call process_from_descriptor (addr (device_state), bv_output_descriptor,
                    bv_output_ptr, next_output, bv_last_output, err_code);
          if err_code ^= ""b
          then return ("0"b);

          return ("1"b);


end process_character_sequence;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end net_convert_output_;




		    net_telnet_interpreter_.pl1     09/23/77  1035.2rew 09/22/77  1723.9      223830



/* ******************************************************
   *                                                    *
   *                                                    *
   * Copyright (c) 1972 by Massachusetts Institute of   *
   * Technology and Honeywell Information Systems, Inc. *
   *                                                    *
   *                                                    *
   ****************************************************** */

net_telnet_interpreter_:
          procedure (bv_SDB_ptr, bv_raw_buffer_ptr, bv_error_code);

/*             "net_telnet_interpreter_" -- this procedure interprets the       */
/*        Network TELNET characters received from the Network.  It also         */
/*        performs any necessary action required by these characters.           */

/*        Originally created by D. M. Wells 1973, December 17.                  */
/*        Modified by D. M. Wells, March, 1976, to change method of             */
/*                  signalling quits.                                           */
/*        Modified by D. P. Reed, and D. M. Wells, Oct. 1976, to add Suppress   */
/*             GoAhead, and the rationalize options entry.                      */
/*        Modified by D. M. Wells, Feb. 1977, per auditing suggestions.         */

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (bv_error_code bit (36) aligned,
          (bv_raw_buffer_ptr, bv_SDB_ptr) pointer)
               parameter;

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
         (option_num fixed binary (8),
          (buffer_hbound, raw_indx) fixed binary (24),
          byte_element bit (9),
          transmit_buffer (0 : 100) bit (9),
          buffer_ptr pointer)
               automatic;

    declare
          1 status aligned automatic like status_template;

          /* * * * * INTERNAL STATIC DECLARATIONS  * * * * */

     declare
          NL initial ("000001010"b)                         /* New Line character                             */
               bit (9) internal static;

          /* * * * * BASED & TEMPLATE DECLARATIONS * * * * */

     declare
          based_area area
                         based;

     declare
          1 based_workspace aligned based,
             2 byte (0 : 1) bit (9) unaligned;

     declare
          1 byte_buffer aligned based,
             2 header like byte_buffer_header,
             2 workspace aligned,
                3 byte (0 : buffer_allocation_size refer (byte_buffer.header.buffer_bound)) bit (9) unaligned;

          /* * * * * DEFINED REFERENCES  * * * * * * * * * */

     declare
          1 SDB aligned like SDB_template defined (bv_SDB_ptr -> SDB_template);

     declare
          1 option_supported (0 : 1) defined (supported_options),
             2 option (0 : 35) bit (1);

          /* * * * * TEXT SECTION REFERENCES * * * * * * * */

     declare
          supported_options (0 : 1) bit (36) internal static options (constant) initial (
                    "000100000000000000000000000000000000"b,
                    "000100010000000000000000000000000000"b);

          /* * * * * EXTERNAL STATIC DECLARATIONS  * * * * */

     declare
          error_table_$ips_has_occurred
               bit (36) external static;

          /* * * * * ENTRY & PROCEDURE DECLARATIONS  * * * */

     declare
          net_ascii_dim_io_$net_ascii_resetwrite constant entry (ptr, 1 aligned like status_template),
          net_ascii_dim_io_$net_ascii_write constant entry (ptr, ptr, fixed bin (24), fixed bin (24),
                    fixed bin (24), 1 aligned like status_template),
          net_ascii_dim_io_$net_ascii_write_raw constant entry (ptr, ptr, fixed bin (24), fixed bin (24),
                    fixed bin (24), 1 aligned like status_template),
	net_ascii_dim_state_$reflect_modes_to_hardcore constant entry (ptr);

     declare
         (addr, binary, bit, hbound, lbound, null)
               builtin;

          /* * * * * STACK REFERENCES  * * * * * * * * * * */

     declare
          unimplemented_telnet_control_
               condition;

          /* * * * * INCLUDE FILES * * * * * * * * * * * * */

          % include net_ascii_dim_sdb_dcls;
          % include net_status_template;
          % include telnet_options;
          % include telnet_special_chars;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

          bv_error_code = ""b;

restart_buffer_scan:
          buffer_ptr = bv_raw_buffer_ptr;
          buffer_hbound = buffer_ptr -> byte_buffer.byte_offset + buffer_ptr -> byte_buffer.num_bytes - 1;

          do raw_indx = buffer_ptr -> byte_buffer.byte_offset by 1 to buffer_hbound;
               byte_element = buffer_ptr -> byte_buffer.byte (raw_indx);
               if byte_element = OUR_IAC                    /* if this character is our translated IAC        */
               then call process_protocol ();               /* then find out what foreign system wants        */
               end;

return_from_raw_scan:
          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

rationalize_options:
          entry (bv_SDB_ptr, bv_error_code);

          bv_error_code = ""b;

          do option_num = lbound (option_supported.option, 2) by 1 to hbound (option_supported.option, 2);
               if option_supported (RECEIVE).option (option_num)
               then call invoke_option (option_num, RECEIVE);
               else call revoke_option (option_num, RECEIVE);

               if option_supported (TRANSMIT).option (option_num)
               then call invoke_option (option_num, TRANSMIT);
               else call revoke_option (option_num, TRANSMIT);
               end;

	call rcte_subnegotiation;	/* if RCTE in effect, start us out */

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

                                                  /*      this procedure is a subroutine which implements the */
                                                  /* basic level of the TELNET IAC processing.                */

process_protocol:
          procedure ();

          /* * * * * AUTOMATIC STORAGE DECLARATIONS  * * * */

     declare
          iac_indx fixed binary (24)
               automatic;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if ^ SDB.protocol_495
          then do;                                          /* are now just switching into new protocol mode  */
               SDB.protocol_495 = "1"b;

               transmit_buffer (0) = NET_IAC;
               transmit_buffer (1) = NET_NOP;
               call net_ascii_dim_io_$net_ascii_write_raw (bv_SDB_ptr, addr (transmit_buffer), 0, 2, (0), status);
	     call net_ascii_dim_state_$reflect_modes_to_hardcore (bv_SDB_ptr);
               end;

          iac_indx = raw_indx;

          if iac_indx + 1 > buffer_hbound
          then goto return_from_raw_scan;                   /* we dont have another character to interpret    */

          raw_indx = raw_indx + 1;

          byte_element = buffer_ptr -> byte_buffer.byte (raw_indx);   /* pick up the next character           */

          if byte_element = OUR_IAC                         /* if this is doubled IAC (means really data)     */
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = NET_IAC;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_NOP
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_GA
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_EC
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_EC;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_EL
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_EL;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_AO
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;

               call net_ascii_dim_io_$net_ascii_resetwrite (bv_SDB_ptr, status);

               SDB.aborting_output = "1"b;

	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_IP
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;

               if SDB.current_modes.handle_quit
               then do;
                    if SDB.string_ptr ^= null ()
                    then do;
                         free SDB.string_ptr -> byte_buffer in (SDB.string_ptr -> byte_buffer.area_ptr -> based_area);
                         SDB.string_ptr = null ();
                         end;

                    call net_ascii_dim_io_$net_ascii_resetwrite (bv_SDB_ptr, status);

                    buffer_ptr -> byte_buffer.num_bytes = buffer_ptr -> byte_buffer.num_bytes + buffer_ptr -> byte_buffer.byte_offset - raw_indx - 1;
                    buffer_ptr -> byte_buffer.byte_offset = raw_indx + 1;

                    call net_ascii_dim_io_$net_ascii_write (bv_SDB_ptr, addr (NL), 0, 1, (0), status);
                    end;

	     call rcte_subnegotiation;

               if SDB.allow_quits
               then do;
                    bv_error_code = error_table_$ips_has_occurred;
                    goto return_from_raw_scan;
                    end;

               goto restart_buffer_scan;
               end;

          if byte_element = NET_AYT
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;

               transmit_buffer (0) = "001011001"b;          /* we will currently answer "YES"                 */
               transmit_buffer (1) = "001000101"b;
               transmit_buffer (2) = "001010011"b;

               call net_ascii_dim_io_$net_ascii_write_raw (bv_SDB_ptr, addr (transmit_buffer), 0, 3, (0), status);

	     call rcte_subnegotiation;

               return;
               end;

          if byte_element = NET_DM
          then do;
               buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_DM;
               buffer_ptr -> byte_buffer.byte (raw_indx) = OUR_NOP;
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_DONT
          then do;
               call option_revoked (get_option_num (), TRANSMIT);
               call mask_out_option ();
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_DO
          then do;
               call option_invoked (get_option_num (), TRANSMIT);
               call mask_out_option ();
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_WONT
          then do;
               call option_revoked (get_option_num (), RECEIVE);
               call mask_out_option ();
	     call rcte_subnegotiation;
               return;
               end;

          if byte_element = NET_WILL
          then do;
               call option_invoked (get_option_num (), RECEIVE);
               call mask_out_option ();
	     call rcte_subnegotiation;
               return;
               end;

	if byte_element = NET_SB
	then do;
               call process_subnegotiation ();
	     call rcte_subnegotiation;
               return;
	     end;

          buffer_ptr -> byte_buffer.byte (iac_indx) = OUR_NOP;        /* get rid of the IAC that is there     */
	call rcte_subnegotiation;    /* just for form's sake */

          signal unimplemented_telnet_control_;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

get_option_num:
          procedure () returns (fixed bin (8));

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if iac_indx + 2 > buffer_hbound
          then goto return_from_raw_scan;

          return (binary (buffer_ptr -> byte_buffer.byte (iac_indx + 2)));

end;      /* end get_option_num                            */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

mask_out_option:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          buffer_ptr -> byte_buffer.byte (iac_indx + 0) = OUR_NOP;
          buffer_ptr -> byte_buffer.byte (iac_indx + 1) = OUR_NOP;
          buffer_ptr -> byte_buffer.byte (iac_indx + 2) = OUR_NOP;

          return;

end;      /* end mask_out_option                           */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

process_subnegotiation:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

dcl option_number fixed bin(8),
    sb_indx fixed bin,
    buffer_size fixed bin (24);


	do sb_indx = iac_indx+3 repeat(sb_indx+1) while (sb_indx<buffer_hbound);
		if buffer_ptr -> byte_buffer.byte(sb_indx) = NET_IAC
		then if buffer_ptr -> byte_buffer.byte(sb_indx+1) = NET_SE
		     then go to found;
		     else if buffer_ptr -> byte_buffer.byte(sb_indx+1) = NET_IAC
			then sb_indx = sb_indx+1;
			else signal unimplemented_telnet_control_;
	end;

	goto return_from_raw_scan;	/* haven't got everthing yet */

found:
	option_number = binary (buffer_ptr -> byte_buffer.byte (iac_indx+2), 8);
	if option_number > hbound (option_supported.option, 2) then signal unimplemented_telnet_control_;

	if option_number ^= OPTION_status
          then signal unimplemented_telnet_control_;

                                                  /* Notice that although we have code here for STATUS        */
                                                  /* negotiation, the STATUS option is not enabled as we      */
                                                  /* have never found a user side implementation and thus     */
                                                  /* could not test this server implementation.               */

	goto status_handler (binary (buffer_ptr -> byte_buffer.byte (iac_indx+3), 8));

status_handler(0):	/* IS */
	/* should parse and save status information here */
	goto nullify_subneg_bytes;

status_handler(1):
	transmit_buffer (0) = NET_IAC;
	transmit_buffer (1) = NET_SB;
	transmit_buffer (2) = bit (binary (OPTION_status, 9));
	transmit_buffer (3) = ""b;
	buffer_size = 4;

	do option_number = 0 to 17;
               if SDB.option_in_effect (RECEIVE).option (option_number)
	     then call status_do (option_number);
               if SDB.option_in_effect (TRANSMIT).option (option_number)
	     then call status_will (option_number);
	end;

	transmit_buffer(buffer_size) = NET_IAC;
	buffer_size = buffer_size+1;
	transmit_buffer(buffer_size) = NET_SE;
	buffer_size = buffer_size+1;
	call net_ascii_dim_io_$net_ascii_write_raw (bv_SDB_ptr, addr(transmit_buffer), 0, buffer_size, (0), status);

nullify_subneg_bytes:
	raw_indx = sb_indx + 2;
	do sb_indx = iac_indx to raw_indx;
		buffer_ptr -> byte_buffer.byte(sb_indx) = OUR_NOP;
	end;

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

status_will:
          procedure(option_number);
dcl option_number fixed bin(8);

	transmit_buffer(buffer_size) = NET_WILL;
	goto write_option;

status_do: entry(option_number);

	transmit_buffer(buffer_size) = NET_DO;
write_option:
	buffer_size = buffer_size + 1;
	if option_number = binary(NET_IAC)
	then do;
		transmit_buffer(buffer_size),
		transmit_buffer(buffer_size+1) = NET_IAC;
		buffer_size = buffer_size + 2;
	     end;
	else do;
		transmit_buffer(buffer_size) = bit(binary(option_number,9,0),9);
		buffer_size = buffer_size + 1;
	     end;

end;      /* end status_will                               */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end;      /* end process_subnegotiation                    */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end;      /* end process_protocol                          */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

revoke_option:
          procedure (p_option_num, p_direction);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (p_direction fixed binary (1),
          p_option_num fixed binary (8))
               parameter;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          if p_option_num > hbound (option_supported.option, 2)
          then return;                                      /* not known, can't be currently in effect        */

          if ^ SDB.option_in_effect (p_direction).option (p_option_num)
          then return;

          if SDB.option_in_negotiation (p_direction).option (p_option_num)
          then return;

          if p_direction = RECEIVE
          then call send_negotiation_string (NET_DONT, p_option_num);
          else call send_negotiation_string (NET_WONT, p_option_num);

          SDB.option_in_negotiation (p_direction).option (p_option_num) = "1"b;

          call disperse_option_states ();

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

option_revoked:
          entry (p_option_num, p_direction);

          if p_option_num > hbound (option_supported.option, 2)
          then return;                                      /* not known, can't possibly be in effect         */

          if ^ SDB.option_in_effect (p_direction).option (p_option_num)
          then do;
               if ^ SDB.option_in_negotiation (p_direction).option (p_option_num)
               then return;                                 /* this is improper revocation -- ignore it       */

                                                  /* Otherwise, we have proposed this option, and other host  */
                                                  /* has decided to refuse the option                         */

               SDB.option_in_negotiation (p_direction).option (p_option_num) = "0"b;
               call disperse_option_states ();

               return;
               end;

                                                  /* At this point, the option is currently is effect, but    */
                                                  /* somebody has decided to flush the option.                */

          if SDB.option_in_negotiation (p_direction).option (p_option_num)
          then do;                                          /* we flushed the option, and this is reply       */
               SDB.option_in_effect (p_direction).option (p_option_num) = "0"b;
               SDB.option_in_negotiation (p_direction).option (p_option_num) = "0"b;
               call disperse_option_states ();

               return;
               end;

                                                  /* Other host has decided to flush the option, and we must  */
                                                  /* acknowledge the revocation and update our tables.        */

          if p_direction = RECEIVE
          then call send_negotiation_string (NET_DONT, p_option_num);
          else call send_negotiation_string (NET_WONT, p_option_num);

          SDB.option_in_effect (p_direction).option (p_option_num) = "0"b;
          call disperse_option_states ();

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

invoke_option:
          entry (p_option_num, p_direction);

          if p_option_num > hbound (option_supported.option, 2)
          then return;                                                /* don't support options outside range   */

          if SDB.option_in_effect (p_direction).option (p_option_num)
          then return;                                      /* the option in already in effect                */

          if SDB.option_in_negotiation (p_direction).option (p_option_num)
          then return;                                      /* we have already asked for the option */

          if p_direction = RECEIVE
          then call send_negotiation_string (NET_DO, p_option_num);
          else call send_negotiation_string (NET_WILL, p_option_num);

          SDB.option_in_negotiation (p_direction).option (p_option_num) = "1"b;

          call disperse_option_states ();

          return;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

option_invoked:
          entry (p_option_num, p_direction);

          if p_option_num > hbound (option_supported.option, 2)
          then do;                                          /* we refuse large numbered options               */
               if p_direction = RECEIVE
               then call send_negotiation_string (NET_DONT, p_option_num);
               else call send_negotiation_string (NET_WONT, p_option_num);

               return;
               end;

          if SDB.option_in_effect (p_direction).option (p_option_num)
          then return;                                      /* ignore attempts to invoke active option        */

          if SDB.option_in_negotiation (p_direction).option (p_option_num)
          then do;                                          /* we asked for option, foreign host has agreed   */
               SDB.option_in_negotiation (p_direction).option (p_option_num) = "0"b;
	     go to accepted_option;
               end;

                                                  /* Otherwise, the foreign host is offering an option to     */
                                                  /* us.  We must see whether or not we support this option   */
          if ^ option_supported (p_direction).option (p_option_num)
          then do;
               if p_direction = RECEIVE
               then call send_negotiation_string (NET_DONT, p_option_num);
               else call send_negotiation_string (NET_WONT, p_option_num);

               return;
               end;

          if p_direction = RECEIVE
          then call send_negotiation_string (NET_DO, p_option_num);
          else call send_negotiation_string (NET_WILL, p_option_num);

accepted_option:		/* here if we have just finished successful negotion */
          SDB.option_in_effect (p_direction).option (p_option_num) = "1"b;
          call disperse_option_states ();

          return;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

disperse_option_states:
          procedure ();

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          call net_ascii_dim_state_$reflect_modes_to_hardcore (bv_SDB_ptr);

          return;

end;      /* end disperse_option_states                    */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

end;      /* end revoke_option                             */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

send_negotiation_string:
          procedure (p_command, p_option_num);

          /* * * * * PARAMETER DECLARATIONS  * * * * * * * */

     declare
         (p_option_num fixed binary (8),
          p_command bit (9))
               parameter;

          /* * * * * * * * * * * * * * * * * * * * * * * * */

          transmit_buffer (0) = NET_IAC;
          transmit_buffer (1) = p_command;
          transmit_buffer (2) = bit (binary (p_option_num, 9));

          call net_ascii_dim_io_$net_ascii_write_raw (bv_SDB_ptr, addr (transmit_buffer), 0, 3, (0), status);

          return;

end;      /* end send_negotiation_string                   */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

          /* end net_telnet_interpreter_                   */
rcte_subnegotiation:
	procedure;

	if ^SDB.option_in_effect(TRANSMIT).option(OPTION_rcte) then return;

	transmit_buffer(0) = NET_IAC;
	transmit_buffer(1) = NET_SB;
	transmit_buffer(2) = bit(binary(OPTION_rcte,9));
	transmit_buffer(3) = bit(binary(25,9));
	transmit_buffer(4) , transmit_buffer(5) = "0"b;
	transmit_buffer(6) = "0"b;
	transmit_buffer(7) = "000001000"b;	/* transmit on control such as CR etc. */
	transmit_buffer(8) = NET_IAC;
	transmit_buffer(9) = NET_SE;

	call net_ascii_dim_io_$net_ascii_write_raw(bv_SDB_ptr, addr(transmit_buffer), 0, 10, (0), status);

end;
end;




		    ntw_.alm                        09/23/77  1035.2rew 09/22/77  1724.6       11331



"          Compiled by Transfer Vector Compiler
"          Version of November 25, 1972
"          with parameters for "isc" transfer vectors.

          entry     ntw_module

ntw_module:
          cmpx6     0,du
          tmi       ..range_error
          cmpx6     15,du
          tmi       ..transfer_vector-0,6
..range_error:
          tra       <ios_>|[no_entry] 

..transfer_vector:
          tra       <net_ascii_dim_xtach_>|[net_ttydim_attach] 
          tra       <net_ascii_dim_xtach_>|[net_ascii_detach] 
          tra       <net_ascii_dim_io_>|[net_ascii_read] 
          tra       <net_ascii_dim_io_>|[net_ascii_write] 
          tra       <net_ascii_dim_io_>|[net_ascii_abort] 
          tra       <net_ascii_dim_state_>|[net_ascii_order] 
          tra       <net_ascii_dim_io_>|[net_ascii_resetread] 
          tra       <net_ascii_dim_io_>|[net_ascii_resetwrite] 
          tra       ..range_error
          tra       <net_ascii_dim_state_>|[net_ascii_getsize] 
          tra       <net_ascii_dim_state_>|[net_ascii_setdelim] 
          tra       <net_ascii_dim_state_>|[net_ascii_getdelim] 
          tra       ..range_error
          tra       ..range_error
          tra       <net_ascii_dim_state_>|[net_ascii_changemode] 

          end




		    bull_copyright_notice.txt       08/30/05  1008.4r   08/30/05  1007.3    00020025

                                          -----------------------------------------------------------


Historical Background

This edition of the Multics software materials and documentation is provided and donated
to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. 
as a contribution to computer science knowledge.  
This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology,
Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull
and Bull HN Information Systems Inc. to the development of this operating system. 
Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970),
renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership
of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for 
managing computer hardware properly and for executing programs. Many subsequent operating systems
incorporated Multics principles.
Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., 
as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. .

                                          -----------------------------------------------------------

Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without
fee is hereby granted,provided that the below copyright notice and historical background appear in all copies
and that both the copyright notice and historical background and this permission notice appear in supporting
documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining
to distribution of the programs without specific prior written permission.
    Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc.
    Copyright 2006 by Bull HN Information Systems Inc.
    Copyright 2006 by Bull SAS
    All Rights Reserved
