summaryrefslogtreecommitdiff
path: root/obsolete/systems/knuth/unsupported/tex/tex.vms-changes
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /obsolete/systems/knuth/unsupported/tex/tex.vms-changes
Initial commit
Diffstat (limited to 'obsolete/systems/knuth/unsupported/tex/tex.vms-changes')
-rw-r--r--obsolete/systems/knuth/unsupported/tex/tex.vms-changes1092
1 files changed, 1092 insertions, 0 deletions
diff --git a/obsolete/systems/knuth/unsupported/tex/tex.vms-changes b/obsolete/systems/knuth/unsupported/tex/tex.vms-changes
new file mode 100644
index 0000000000..35e203cc2e
--- /dev/null
+++ b/obsolete/systems/knuth/unsupported/tex/tex.vms-changes
@@ -0,0 +1,1092 @@
+This change file is for the Vax/VMS vesion of TeX.
+Copyright (C) 1983 by David Fuchs. All rights are reserved.
+14May85 JLC .Increased string_vacancies and pool_size as in 1.1.
+ ? VLJ .Modified to handle tabs and form-feeds in input.
+
+@x
+\pageno=3
+@y
+\pageno=3
+\let\maybe=\iffalse
+\def\title{\TeX82 changes for Vax/VMS}
+@z
+
+@x
+@d banner=='This is TeX, Version 2.9' {printed when \TeX\ starts}
+@y
+@d banner=='This is TeX, Vax/VMS Version 2.9'
+@z
+
+@x
+procedure initialize; {this procedure gets things started properly}
+@y
+@<Vax/VMS procedures@>@/
+procedure initialize; {this procedure gets things started properly}
+@z
+
+@x
+@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
+@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
+@y
+@d debug==@{
+@d gubed==@}
+@z
+
+@x
+@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering
+ usage statistics}
+@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering
+ usage statistics}
+@y
+@d stat==
+@d tats==
+@z
+
+@x
+@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version}
+@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version}
+@y
+@d init==@{
+@d tini==@}
+@z
+
+@x compiler directives== starlet and vax reserved words
+@<Compiler directives@>=
+@{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead}
+@!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging}
+@y
+On Vax/VMS, there are no compiler directives that can be introduced in this
+way, but we take this opportunity to include a few sysetem dependent goodies.
+
+@d VAX_text==@= text @>
+@d VAX_new==@= new @>
+@d VAX_none==@= none @>
+@d VAX_word==@= word @>
+@d VAX_error==@= error @>
+@d VAX_length==@= length @>
+@d VAX_syi_sid==@= syi$_sid @>
+@d VAX_continue==@= continue @>
+@d VAX_external==@= external @>
+@d VAX_readonly==@= readonly @>
+@d VAX_volatile==@= volatile @>
+@d VAX_aligned==@= aligned @>
+@d VAX_static==@= static @>
+@d VAX_unsigned==@= unsigned @>
+@d VAX_carriage_control==@= carriage_control @>
+@d VAX_io_setmode==@= io$_setmode @>
+@d VAX_iom_ctrlcast==@= io$m_ctrlcast @>
+@d VAX_immed==@= %immed @>
+@d VAX_stdescr==@= %stdescr @>
+@d VAX_ref==@= %ref @>
+@d VAX_qiow==@= $qiow @>
+@d VAX_assign==@= $assign @>
+@d VAX_numtim==@= $numtim @>
+@d VAX_getsyi==@= $getsyi @>
+@d VAX_lib_get_foreign==@= lib$get_foreign @>
+@d VAX_disposition==@= disposition @>
+@d VAX_delete==@= delete @>
+@d VAX_save==@= save @>
+@d VAX_varying==@= varying @>
+@d VAX_substr==@= substr @>
+@d VAX_trnlog==@= $trnlog @>
+@d VAX_ss_normal==@= ss$_normal @>
+@d VAX_user_action==@=user_action@>
+@d VAX_create==@=$create@>
+@d VAX_connect==@=$connect@>
+@d VAX_open==@=$open@>
+@d VAX_FAB_type==@= FAB$type @>
+@d VAX_RAB_type==@= RAB$type @>
+@d VAX_NAM_type==@= NAM$type @>
+@d VAX_PAS_FAB==@= PAS$FAB @>
+@d VAX_PAS_RAB==@= PAS$RAB @>
+@d VAX_undefined==@= undefined@>
+@d VAX_FAB_L_NAM== @=FAB$L_NAM@>
+@d VAX_NAM_B_RSL== @=NAM$B_RSL@>
+@d VAX_NAM_L_RSA== @=NAM$L_RSA@>
+
+@<Compiler directives@>=
+@\@=[inherit('sys$library:starlet')]@>@\
+ {allows us to use system symbols and routines}
+@z
+
+@x
+@d othercases == others: {default for cases not listed explicitly}
+@y
+@d othercases == otherwise {default for cases not listed explicitly}
+@z
+
+@x [1] compile-time constants
+@!mem_max=30000; {greatest index in \TeX's internal |mem| array;
+ must be strictly less than |max_halfword|;
+ must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|}
+@!mem_min=0; {smallest index in \TeX's internal |mem| array;
+ must be |min_halfword| or more;
+ must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|}
+@!buf_size=500; {maximum number of characters simultaneously present in
+ current lines of open files and in control sequences between
+ \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
+@!error_line=72; {width of context lines on terminal error messages}
+@!half_error_line=42; {width of first lines of contexts in terminal
+ error messages; should be between 30 and |error_line-15|}
+@!max_print_line=79; {width of longest text lines output; should be at least 60}
+@!stack_size=200; {maximum number of simultaneous input sources}
+@!max_in_open=6; {maximum number of input files and error insertions that
+ can be going on simultaneously}
+@!font_max=75; {maximum internal font number; must not exceed |max_quarterword|
+ and must be at most |font_base+256|}
+@!font_mem_size=20000; {number of words of |font_info| for all fonts}
+@!param_size=60; {maximum number of simultaneous macro parameters}
+@!nest_size=40; {maximum number of semantic levels simultaneously active}
+@!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|}
+@!string_vacancies=8000; {the minimum number of characters that should be
+ available for the user's control sequences and font names,
+ after \TeX's own error messages are stored}
+@!pool_size=32000; {maximum number of characters in strings, including all
+ error messages and help texts, and the names of all fonts and
+ control sequences; must exceed |string_vacancies| by the total
+ length of \TeX's own strings, which is currently about 23000}
+@!save_size=600; {space for saving values outside of current group; must be
+ at most |max_halfword|}
+@!trie_size=8000; {space for hyphenation patterns; should be larger for
+ \.{INITEX} than it is in production versions of \TeX}
+@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8}
+@!file_name_size=40; {file names shouldn't be longer than this}
+@!pool_name='TeXformats:TEX.POOL ';
+ {string of length |file_name_size|; tells where the string pool appears}
+@y
+@!mem_max=65500; {greatest index in \TeX's internal |mem| array;
+ must be strictly less than |max_halfword|;
+ must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|}
+@!mem_min=0; {smallest index in \TeX's internal |mem| array;
+ must be |min_halfword| or more;
+ must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|}
+@!buf_size=500; {maximum number of characters simultaneously present in
+ current lines of open files and in control sequences between
+ \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
+@!error_line=79; {width of context lines on terminal error messages}
+@!half_error_line=50; {width of first lines of contexts in terminal
+ error messages; should be between 30 and |error_line-15|}
+@!max_print_line=79; {width of longest text lines output; should be at least 60}
+@!stack_size=200; {maximum number of simultaneous input sources}
+@!max_in_open=6; {maximum number of input files and error insertions that
+ can be going on simultaneously}
+@!font_max=100; {maximum internal font number; must not exceed |max_quarterword|
+ and must be at most |font_base+256|}
+@!font_mem_size=35000; {number of words of |font_info| for all fonts}
+@!param_size=60; {maximum number of simultaneous macro parameters}
+@!nest_size=40; {maximum number of semantic levels simultaneously active}
+@!max_strings=5400; {maximum number of strings; must not exceed |max_halfword|}
+@!string_vacancies=26000; {the minimum number of characters that should be
+ available for the user's control sequences and font names,
+ after \TeX's own error messages are stored}
+@!pool_size=65500; {maximum number of characters in strings, including all
+ error messages and help texts, and the names of all fonts and
+ control sequences; must exceed |string_vacancies| by the total
+ length of \TeX's own strings, which is currently about 22500}
+@!save_size=600; {space for saving values outside of current group; must be
+ at most |max_halfword|}
+@!trie_size=8000; {space for hyphenation patterns; should be larger for
+ \.{INITEX} than it is in production versions of \TeX}
+@!dvi_buf_size=1024; {size of the output buffer; must be a multiple of 8}
+@!VAX_block_length=512; {must be half |dvi_buf_size| on Vax/VMS}
+@!file_name_size=69; {file names shouldn't be longer than this}
+@!pool_name=
+ 'TeX$formats:TEX.POO ';
+ {string of length |file_name_size|; tells where the string pool appears}
+@.TeX{\$}formats@>
+@z
+
+@x [1] Tangle-time constants
+@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX};
+ must not be less than |mem_min|}
+@d mem_top==30000 {largest index in the |mem| array dumped by \.{INITEX};
+ must be substantially larger than |mem_bot|
+ and not greater than |mem_max|}
+@d font_base=0 {smallest internal font number; must not be less
+ than |min_quarterword|}
+@d hash_size=2100 {maximum number of control sequences; it should be at most
+ about |(mem_max-mem_min)/10|, but 2100 is already quite generous}
+@d hash_prime=1777 {a prime number equal to about 85\% of |hash_size|}
+@d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions}
+@y
+@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX};
+ must not be less than |mem_min|}
+@d mem_top==65500 {largest index in the |mem| array dumped by \.{INITEX};
+ must be substantially larger than |mem_bot|
+ and not greater than |mem_max|}
+@d font_base=0 {smallest internal font number; must not be less
+ than |min_quarterword|}
+@d hash_size=2500 {maximum number of control sequences; it should be at most
+ about |(mem_max-mem_min)/10|, but 2100 is already quite generous}
+@d hash_prime=2113 {a prime number equal to about 85\% of |hash_size|}
+@d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions}
+@z
+
+@x [2] System-dependent character set changes:
+@^character set dependencies@>
+@^system dependencies@>
+
+@<Set init...@>=
+for i:=1 to @'37 do xchr[i]:=' ';
+@y
+@^character set dependencies@>
+@^system dependencies@>
+
+The code shown here is intended to be used on VAX/VMS systems,
+and at other installations where only the printable ASCII set, plus
+|carriage_return|, |tab|, and |form_feed| will show up in text files.
+All |line_feed| and |null| characters are skipped.
+
+@d form_feed=@'14 {ASCII code used at end of a page}
+@d tab=@'11
+
+@<Set initial values...@>=
+for i:=1 to @'37 do xchr[i]:=chr(i);
+xchr[form_feed]:=chr(form_feed);
+xchr[tab]:=chr(tab);
+@z
+
+@x [3] alpha files are text and byte files are blocks
+@!alpha_file=packed file of text_char; {files that contain textual data}
+@!byte_file=packed file of eight_bits; {files that contain binary data}
+@y
+@!alpha_file=VAX_text; {files that contain textual data}
+@!byte_block=packed array [0..VAX_block_length-1] of eight_bits;
+@!byte_file=packed file of byte_block; {files that contain binary data}
+@z
+
+
+@x
+@d reset_OK(#)==erstat(#)=0
+@d rewrite_OK(#)==erstat(#)=0
+
+@p function a_open_in(var f:alpha_file):boolean;
+@y
+@p function user_reset
+ (var FAB:VAX_FAB_type;
+ var RAB:VAX_RAB_type;
+ var F:unsafe_file):integer;
+var status:integer; NAM:NAM_ptr; p:charptr; i:integer;
+begin
+last_length:=0;
+status:=VAX_open(FAB);
+if odd(status) then status:=VAX_connect(RAB);
+if odd(status) then begin
+ NAM:=FAB.VAX_FAB_L_NAM::NAM_ptr;
+ if NAM<>nil then last_length:=NAM^.VAX_NAM_B_RSL;
+ for i:=1 to last_length do begin
+ p:=(NAM^.VAX_NAM_L_RSA::integer+i-1)::charptr;
+ last_name[i]:=p^;
+ end;
+ end;
+user_reset:=status;
+end;
+@#
+function user_rewrite
+ (var FAB:VAX_FAB_type;
+ var RAB:VAX_RAB_type;
+ var F:unsafe_file):integer;
+var status:integer; NAM:NAM_ptr; p:charptr; i:integer;
+begin
+status:=VAX_create(FAB);
+if odd(status) then status:=VAX_connect(RAB);
+if odd(status) then begin
+ NAM:=FAB.VAX_FAB_L_NAM::NAM_ptr;
+ if NAM<>nil then last_length:=NAM^.VAX_NAM_B_RSL;
+ for i:=1 to last_length do begin
+ p:=(NAM^.VAX_NAM_L_RSA::integer+i-1)::charptr;
+ last_name[i]:=p^;
+ end;
+ end;
+user_rewrite:=status;
+end;
+@#
+function a_open_in(var f:alpha_file):boolean;
+@z
+
+@x [3] file opening
+begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset,
+ VAX_error:=VAX_continue);
+if status(f)>0 then a_open_in:=false
+else begin
+ reset(f,VAX_error:=VAX_continue);
+ a_open_in:=status(f)<=0;
+ end;
+@z
+
+@x
+begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_new,16383,VAX_disposition:=VAX_delete,
+ VAX_user_action:=user_rewrite,VAX_error:=VAX_continue);
+if status(f)>0 then a_open_out:=false
+else begin
+ linelimit(f,maxint);
+ rewrite(f,VAX_error:=VAX_continue);
+ a_open_out:=status(f)<=0;
+ end;
+@z
+
+@x
+begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset,
+ VAX_error:=VAX_continue);
+if status(f)>0 then b_open_in:=false
+else begin
+ reset(f,VAX_error:=VAX_continue);
+ b_open_in:=status(f)<=0;
+ end;
+@z
+
+@x
+begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_new,VAX_disposition:=VAX_delete,
+ VAX_user_action:=user_rewrite,VAX_error:=VAX_continue);
+if status(f)>0 then b_open_out:=false
+else begin
+ rewrite(f,VAX_error:=VAX_continue);
+ b_open_out:=status(f)<=0;
+ end;
+@z
+
+@x
+begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset,
+ VAX_error:=VAX_continue);
+if status(f)>0 then w_open_in:=false
+else begin
+ reset(f,VAX_error:=VAX_continue);
+ w_open_in:=status(f)<=0;
+ end;
+fmt_count:=0; {hack}
+@z
+
+@x
+begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f);
+@y
+begin
+open(f,name_of_file,VAX_new,VAX_disposition:=VAX_delete,
+ VAX_user_action:=user_rewrite,VAX_error:=VAX_continue);
+if status(f)>0 then w_open_out:=false
+else begin
+ rewrite(f,VAX_error:=VAX_continue);
+ w_open_out:=status(f)<=0;
+ end;
+fmt_count:=0; {hack}
+@z
+
+@x [3] file closing
+begin close(f);
+@y
+begin close(f,VAX_disposition:=VAX_save,VAX_error:=VAX_continue);
+@z
+
+@x
+begin close(f);
+@y
+begin close(f,VAX_disposition:=VAX_save,VAX_error:=VAX_continue);
+@z
+
+@x
+begin close(f);
+@y
+begin close(f,VAX_disposition:=VAX_save,VAX_error:=VAX_continue);
+@z
+
+@x [3] read into auxiliary buffer first
+representing the beginning and ending of a line of text.
+
+@<Glob...@>=
+@y
+representing the beginning and ending of a line of text.
+
+On Vax/VMS, we will read the lines first into an auxiliary buffer, in
+order to save the running time of procedure-call overhead. We have
+to be very carefull to handle lines longer than the arbitrarily chosen
+length of the |aux_buf|.
+
+@<Glob...@>=
+@!aux_buf:VAX_varying [133] of char; {where the characters go first}
+@z
+
+@x [3] ditto
+@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean;
+ {inputs the next line or returns |false|}
+var last_nonblank:0..buf_size; {|last| with trailing blanks removed}
+begin if bypass_eoln then if not eof(f) then get(f);
+ {input the first character of the line into |f^|}
+last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
+if eof(f) then input_ln:=false
+else begin last_nonblank:=first;
+ while not eoln(f) do
+ begin if last>=max_buf_stack then
+ begin max_buf_stack:=last+1;
+ if max_buf_stack=buf_size then
+ overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+ end;
+ buffer[last]:=xord[f^]; get(f); incr(last);
+ if buffer[last-1]<>" " then last_nonblank:=last;
+ end;
+ last:=last_nonblank; input_ln:=true;
+ end;
+end;
+@y
+@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean;
+ {inputs the next line or returns |false|}
+label found;
+var @!len:integer; {length of line input}
+@!k:0..buf_size; {index into |buffer|}
+begin
+last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
+if status(f)<>0 then input_ln:=false
+else begin
+ while not eoln(f) do
+ begin read(f,aux_buf,VAX_error:=VAX_continue);
+ len:=VAX_length(aux_buf);
+ if last+len>=max_buf_stack then
+ begin
+ if last+len<buf_size then max_buf_stack:=last+len
+ else overflow("buffer size",buf_size);
+ end;
+ for k:=last to last+len-1 do buffer[k]:=xord[aux_buf[k-last+1]];
+ last:=last+len;
+ end;
+ found: if last>first then if buffer[last-1]=" " then begin
+ decr(last); goto found; end;
+ input_ln:=true;
+ read_ln(f,VAX_error:=VAX_continue);
+ end;
+end;
+@z
+
+@x [3] terminal file opening
+@ Here is how to open the terminal files
+in \ph. The `\.{/I}' switch suppresses the first |get|.
+@^system dependencies@>
+
+@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input}
+@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output}
+@y
+@ Here is how to open the terminal files
+under Vax/VMS.
+@^system dependencies@>
+
+@d t_open_in==begin open(term_in,'SYS$INPUT');
+ reset(term_in);
+ in_FAB:=VAX_PAS_FAB(term_in);
+ in_RAB:=VAX_PAS_RAB(term_in);
+ end {open the terminal for text input}
+@d t_open_out==begin
+ open(term_out,'SYS$OUTPUT',VAX_carriage_control:=VAX_none);
+ linelimit(term_out,maxint);
+ rewrite(term_out);
+ out_FAB:=VAX_PAS_FAB(term_out);
+ out_RAB:=VAX_PAS_RAB(term_out);
+ end {open the terminal for text output}
+@z
+
+@x [3] terminal hacks: clear and update
+these operations can be specified in \ph:
+@^system dependencies@>
+
+@d update_terminal == break(term_out) {empty the terminal output buffer}
+@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer}
+@d wake_up_terminal == do_nothing {cancel the user's cancellation of output}
+@y
+these operations can be specified in Vax/VMS Pascal:
+@^system dependencies@>
+
+@d update_terminal == write_ln(term_out) {empty the terminal output buffer}
+@d clear_terminal == in_RAB^.@=RAB$V_PTA@>:=true
+ {clear the terminal input buffer}
+@.PTA@>
+@d wake_up_terminal == begin
+ out_RAB^.@=RAB$V_CCO@>:=true;
+ write_ln(term_out);
+ out_RAB^.@=RAB$V_CCO@>:=false;
+ end {cancel the user's cancellation of output}
+@.CCO@>
+@d crlf == chr(13),chr(10)
+@z
+
+@x [3] terminal initialization
+@ The following program does the required initialization
+without retrieving a possible command line.
+It should be clear how to modify this routine to deal with command lines,
+if the system permits them.
+@^system dependencies@>
+
+@p function init_terminal:boolean; {gets the terminal input started}
+label exit;
+begin t_open_in;
+loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal;
+@.**@>
+ if not input_ln(term_in,true) then {this shouldn't happen}
+ begin write_ln(term_out);
+ write(term_out,'! End of file on the terminal... why?');
+@.End of file on the terminal@>
+ init_terminal:=false; return;
+ end;
+ loc:=first;
+ while (loc<last)and(buffer[loc]=" ") do incr(loc);
+ if loc<last then
+ begin init_terminal:=true;
+ return; {return unless the line was all blank}
+ end;
+ write_ln(term_out,'Please type the name of your input file.');
+ end;
+exit:end;
+@y
+@ The following program does the required initialization
+by retrieving a possible command line, and if none exists,
+prompting the user for the first line of input.
+@^system dependencies@>
+
+@p
+[VAX_external] function VAX_lib_get_foreign(
+ VAX_stdescr cmdlin:[VAX_volatile] packed array [$l1..$u1:integer] of char
+ := VAX_immed 0;
+ VAX_stdescr prompt:[VAX_volatile] packed array [$l2..$u2:integer] of char
+ := VAX_immed 0;
+ var len : [VAX_volatile] sixteen_bits := VAX_immed 0;
+ var flag : [VAX_volatile] integer := VAX_immed 0)
+ :integer; extern;
+
+function init_terminal:boolean; {gets the terminal input started}
+label exit;
+var command_line: packed array[1..300] of char;
+@!len: sixteen_bits;
+@!i: integer;
+begin t_open_in;
+i:=0;
+VAX_lib_get_foreign(command_line,,len,i);
+i:=1; while (i<=len) and (command_line[i]=' ') do incr(i);
+if i<=len then begin
+ loc:=first;
+ last:=first;
+ while i<=len do begin
+ buffer[last]:=xord[command_line[i]];
+ if (buffer[last]>="A") and (buffer[last]<="Z")
+ then buffer[last]:=buffer[last]+"a"-"A";
+ incr(last); incr(i);
+ end;
+ init_terminal:=true; return;
+ end;
+loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal;
+@.**@>
+ if not input_ln(term_in,true) then {this shouldn't happen}
+ begin write(term_out,crlf);
+ write_ln(term_out,'! End of file on the terminal... why?',crlf);
+@.End of file on the terminal@>
+ init_terminal:=false; return;
+ end;
+ loc:=first;
+ while (loc<last)and(buffer[loc]=" ") do incr(loc);
+ if loc<last then
+ begin init_terminal:=true;
+ return; {return unless the line was all blank}
+ end;
+ write_ln(term_out,'Please type the name of your input file.',crlf);
+ end;
+exit:end;
+@z
+
+@x [4] bad_pool needs real crlf
+@ @d bad_pool(#)==begin wake_up_terminal; write_ln(term_out,#);
+@y
+@ @d bad_pool(#)==begin wake_up_terminal; write_ln(term_out,#,crlf);
+@z
+
+@x [5] real crlf for terminal
+@d wterm(#)==write(term_out,#)
+@d wterm_ln(#)==write_ln(term_out,#)
+@d wterm_cr==write_ln(term_out)
+@y
+@d wterm(#)==write(term_out,#)
+@d wterm_ln(#)==write_ln(term_out,#,crlf)
+@d wterm_cr==write_ln(term_out,crlf)
+@z
+
+@x [5] Turn off clearing typeahead after terminal input
+term_offset:=0; {the user's line ended with \<\rm return>}
+@y
+in_RAB^.@=RAB$V_PTA@>:=false; {turn off purging of typeahead}
+@.PTA@>
+term_offset:=0; {the user's line ended with \<\rm return>}
+@z
+
+@x [6] interrupts
+@d check_interrupt==begin if interrupt<>0 then pause_for_instructions;
+ end
+
+@<Global...@>=
+@!interrupt:integer; {should \TeX\ pause for instructions?}
+@y
+@d check_interrupt==begin if interrupt<>0 then pause_for_instructions;
+ end
+@d enable_control_C==
+VAX_qiow(,tt_chan,VAX_io_setmode+VAX_iom_ctrlcast,,,,
+ VAX_immed ctrlc_rout,,VAX_immed 3,,,);
+
+@<Global...@>=
+@!interrupt:[VAX_volatile]integer; {should \TeX\ pause for instruction?}
+@z
+
+@x
+interrupt:=0; OK_to_interrupt:=true;
+@y
+interrupt:=0; OK_to_interrupt:=true;
+if VAX_assign('TT',tt_chan,,)=1 then enable_control_C;
+@z
+
+@x [7] double precision reals
+@d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio}
+@d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio}
+@d float(#) == # {convert from |glue_ratio| to type |real|}
+@d unfloat(#) == # {convert from |real| to type |glue_ratio|}
+@d float_constant(#) == #.0 {convert |integer| constant to |real|}
+
+@<Types...@>=
+@!glue_ratio=real; {one-word representation of a glue expansion factor}
+@y
+On Vax/VMS, we use some hackery to cause floating point numbers stored in
+|mem| to be |single|, but other |real| variables and expressions are
+done as |double| length reals.
+
+@d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio}
+@d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio}
+@d real == double {use double precision reals for computation}
+@d float(#) == dble(#) {convert from |glue_ratio| to type |real|}
+{FIX ME}
+@d unfloat(#) == sngl(1.0@&D0 * #) {convert from |real| to type |glue_ratio|}
+@d float_constant(#) == #.0@&D0 {convert |integer| constant to |real|}
+
+@<Types...@>=
+@!glue_ratio=r@&e@&a@&l; {one-word representation of a glue expansion factor}
+@z
+
+@x
+@d qi(#)==#+min_quarterword
+ {to put an |eight_bits| item into a quarterword}
+@d qo(#)==#-min_quarterword
+ {to take an |eight_bits| item out of a quarterword}
+@d hi(#)==#+min_halfword
+ {to put a sixteen-bit item into a halfword}
+@d ho(#)==#-min_halfword
+ {to take a sixteen-bit item from a halfword}
+@y
+@d qi(#)==#
+@d qo(#)==#
+@d hi(#)==#
+@d ho(#)==#
+@z
+
+@x [8] block up word files
+@!word_file = file of memory_word;
+@y
+@!word_block = packed array [0..VAX_block_length-1] of memory_word;
+@!word_file = packed file of word_block;
+@z
+
+@x [12] check glue ratio for REALness
+arbitrary random value. The following code assumes that a properly
+formed nonzero |real| number has absolute value $2^{20}$ or more when
+it is regarded as an integer; this precaution was adequate to prevent
+floating point underflow on the author's computer.
+@y
+arbitrary random value. The following code uses the Vax/VMS predeclared
+routine |undefined|.
+@z
+
+@x
+ if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?")
+@y
+ if VAX_undefined(mem[p+glue_offset].gr) then print("?.?")
+@z
+
+@x [17] Special form_feed initialization:
+cat_code("\"):=escape; cat_code("%"):=comment;
+@y
+cat_code("\"):=escape; cat_code("%"):=comment;
+cat_code(form_feed):=car_ret;
+@z
+
+@x [17] date/time
+Since standard \PASCAL\ cannot provide such information, something special
+is needed. The program here simply specifies July 4, 1776, at noon; but
+users probably want a better approximation to the truth.
+
+@p procedure fix_date_and_time;
+begin time:=12*60; {minutes since midnight}
+day:=4; {fourth day of the month}
+month:=7; {seventh month of the year}
+year:=1776; {Anno Domini}
+@y
+@p procedure fix_date_and_time;
+var t:array[1..7] of signed_halfword; {raw year, month, day and time}
+begin VAX_numtim(t);
+year:=t[1]; month:=t[2]; day:=t[3];
+time:=t[4]*60+t[5]; {minutes since midnight}
+@z
+
+@x [28] file names and default areas
+following structure: If the name contains `\.>' or `\.:', the file area
+@y
+following structure: If the name contains `\.]' or `\.:', the file area
+@z
+
+@x [28] system logical names
+@d TEX_area=="TeXinputs:"
+@.TeXinputs@>
+@d TEX_font_area=="TeXfonts:"
+@.TeXfonts@>
+@y
+@d TEX_area=="TeX$inputs:"
+@.TeXinputs@>
+@.TeX{\$}inputs@>
+@d TEX_font_area=="TeX$fonts:"
+@.TeXfonts@>
+@.TeX{\$}fonts@>
+@z
+
+@x [28] directories delimited with square brackets
+else begin if (c=">")or(c=":") then
+@y
+else begin if (c="]")or(c=":") then
+@z
+
+@x [29] Logical name translation:
+@ The third.
+@^system dependencies@>
+
+@p procedure end_name;
+begin if str_ptr+3>max_strings then
+ overflow("number of strings",max_strings-init_str_ptr);
+@:TeX capacity exceeded number of strings}{\quad number of strings@>
+if area_delimiter=0 then cur_area:=""
+else begin cur_area:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=area_delimiter+1;
+ end;
+if ext_delimiter=0 then
+ begin cur_ext:=""; cur_name:=make_string;
+ end
+else begin cur_name:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=ext_delimiter; cur_ext:=make_string;
+ end;
+end;
+@y
+@ The third. We have to check to see if a logical name has been
+referred to, and if so, translate it.
+@^system dependencies@>
+
+@p procedure end_name;
+label restart,exit;
+var s,@!u:VAX_varying[file_name_size] of char;
+@!t:packed array[1..file_name_size] of char;
+@!TRNLOG_return: integer; {what did the TRNLOG return?}
+@!i:pool_pointer;
+@!len:signed_halfword;
+@!c:char;
+begin
+restart:
+if (str_pool[area_delimiter]=":") and (pool_ptr=area_delimiter+1) then
+ begin
+ cur_area:=make_string;
+ len:=length(cur_area)-1; {don't include the colon}
+ for i:=1 to len do begin
+ c:=xchr[str_pool[str_start[cur_area]+i-1]];
+ if ('a'<=c) and (c<='z') then c:=chr(ord(c)+ord('A')-ord('a'));
+ t[i]:=c;
+ end;
+ s:=VAX_substr(t,1,len);
+ TRNLOG_return:=VAX_trnlog(s,len,t,,,);
+ if TRNLOG_return<>VAX_ss_normal then begin
+ cur_ext:=""; cur_name:=""; {silly case}
+ return;
+ end;
+ flush_string; {needn't remember logical name in |cur_area|}
+ begin_name;
+ for i:=1 to len do
+ if not more_name(xord[t[i]]) then goto restart;
+ goto restart; {heavy!}
+ end;
+if str_ptr+3>max_strings then
+ overflow("number of strings",max_strings-init_str_ptr);
+@:TeX capacity exceeded number of strings}{\quad number of strings@>
+if area_delimiter=0 then cur_area:=""
+else begin cur_area:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=area_delimiter+1;
+ end;
+if ext_delimiter=0 then
+ begin cur_ext:=""; cur_name:=make_string;
+ end
+else begin cur_name:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=ext_delimiter; cur_ext:=make_string;
+ end;
+exit:
+end;
+@z
+
+@x [28] system logical names
+@d format_default_length=20 {length of the |TEX_format_default| string}
+@d format_area_length=11 {length of its area part}
+@y
+@d format_default_length=21 {length of the |TEX_format_default| string}
+@d format_area_length=12 {length of its area part}
+@z
+
+@x [28] system logical names
+TEX_format_default:='TeXformats:plain.fmt';
+@y
+TEX_format_default:='TeX$formats:plain.fmt';
+@.TeX{\$}formats@>
+@z
+
+@x [28] get file name from system
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings) then
+ make_name_string:="?"
+else begin for k:=1 to name_length do append_char(xord[name_of_file[k]]);
+ make_name_string:=make_string;
+ end;
+@y
+begin if (pool_ptr+last_length>pool_size)or(str_ptr=max_strings) then
+ make_name_string:="?"
+else begin for k:=1 to last_length do append_char(xord[last_name[k]]);
+ make_name_string:=make_string;
+ end;
+@z
+
+@x
+@p procedure pack_job_name(@!s:str_number); {|s = ".log"|, |".dvi"|, or
+@y
+@p procedure pack_job_name(@!s:str_number); {|s = ".lis"|, |".dvi"|, or
+@z
+
+@x
+pack_job_name(".log");
+@y
+pack_job_name(".lis");
+@z
+
+@x
+prompt_file_name("transcript file name",".log");
+@y
+prompt_file_name("transcript file name",".lis");
+@z
+
+@x [29] tfm blocking
+if not b_open_in(tfm_file) then abort;
+@y
+if not b_open_in(tfm_file) then abort;
+tfm_count:=0;
+@z
+
+@x [29] tfm blocked
+@d fget==get(tfm_file)
+@d fbyte==tfm_file^
+@y
+@d fget==begin incr(tfm_count);
+ if tfm_count=VAX_block_length then begin
+ get(tfm_file,VAX_error:=VAX_continue); tfm_count:=0; end
+ end
+@d fbyte==tfm_file^[tfm_count]
+@z
+
+@x [29] tfm blocked
+if eof(tfm_file) then abort;
+@y
+if status(tfm_file)<>0 then abort;
+if eof(tfm_file) then abort;
+@z
+
+@x [31] dvi blocked
+@ Some systems may find it more efficient to make |dvi_buf| a |packed|
+array, since output of four bytes at once may be facilitated.
+@^system dependencies@>
+
+@<Glob...@>=
+@!dvi_buf:array[dvi_index] of eight_bits; {buffer for \.{DVI} output}
+@y
+@ Some systems may find it more efficient to make |dvi_buf| a |packed|
+array, since output of four bytes at once may be facilitated. On Vax/VMS,
+we get even more complicated than that, for efficiency.
+
+@d dvi_buf==d_buffer.b {buffer for \.{DVI} output}
+
+@<Glob...@>=
+@!d_buffer: [VAX_volatile,VAX_aligned(9)] packed record
+ case boolean of
+ false: (b:packed array[dvi_index] of eight_bits);
+ true: (l:byte_block; r:byte_block; j:eight_bits);
+ end;
+@z
+
+@x [31] dvi blocked
+@ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
+|write_dvi(a,b)|. For best results, this procedure should be optimized to
+run as fast as possible on each particular system, since it is part of
+\TeX's inner loop. It is safe to assume that |a| and |b+1| will both be
+multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
+many machines to use efficient methods to pack four bytes per word and to
+output an array of words with one system call.
+@^system dependencies@>
+@^inner loop@>
+@^defecation@>
+
+@p procedure write_dvi(@!a,@!b:dvi_index);
+var k:dvi_index;
+begin for k:=a to b do write(dvi_file,dvi_buf[k]);
+end;
+@y
+@ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
+|write| on the other variant of the |dvi_buf| record. Thus, we have to be
+sure that things line up properly.
+@^system dependencies@>
+@^inner loop@>
+@^defecation@>
+
+@<Check the ``co...@>=
+if dvi_buf_size<>2*VAX_block_length then bad:=223;
+@z
+
+% [31] dvi blocked
+@x
+ begin write_dvi(0,half_buf-1); dvi_limit:=half_buf;
+@y
+ begin write(dvi_file,d_buffer.l); dvi_limit:=half_buf;
+@z
+
+@x
+else begin write_dvi(half_buf,dvi_buf_size-1); dvi_limit:=dvi_buf_size;
+@y
+else begin write(dvi_file,d_buffer.r); dvi_limit:=dvi_buf_size;
+@z
+
+@x [31] dvi blocked
+if dvi_limit=half_buf then write_dvi(half_buf,dvi_buf_size-1);
+if dvi_ptr>0 then write_dvi(0,dvi_ptr-1)
+@y
+if dvi_limit=half_buf then write(dvi_file,d_buffer.r);
+for k:=dvi_ptr to dvi_buf_size do dvi_buf[k]:=223;
+if dvi_ptr>0 then write(dvi_file,d_buffer.l);
+if dvi_ptr>half_buf then write(dvi_file,d_buffer.r);
+@z
+
+@x [50] block fmt files
+@d dump_wd(#)==begin fmt_file^:=#; put(fmt_file);@+end
+@d dump_int(#)==begin fmt_file^.int:=#; put(fmt_file);@+end
+@d dump_hh(#)==begin fmt_file^.hh:=#; put(fmt_file);@+end
+@d dump_qqqq(#)==begin fmt_file^.qqqq:=#; put(fmt_file);@+end
+@y
+@d fmt_put==begin incr(fmt_count);
+ if fmt_count=VAX_block_length then begin
+ put(fmt_file,VAX_error:=VAX_continue); fmt_count:=0; end
+ end
+@d fmt_word==fmt_file^[fmt_count]
+
+@d dump_wd(#)==begin fmt_word:=#; fmt_put;@+end
+@d dump_int(#)==begin fmt_word.int:=#; fmt_put;@+end
+@d dump_hh(#)==begin fmt_word.hh:=#; fmt_put;@+end
+@d dump_qqqq(#)==begin fmt_word.qqqq:=#; fmt_put;@+end
+@z
+
+@x
+@d undump_wd(#)==begin get(fmt_file); #:=fmt_file^;@+end
+@d undump_int(#)==begin get(fmt_file); #:=fmt_file^.int;@+end
+@d undump_hh(#)==begin get(fmt_file); #:=fmt_file^.hh;@+end
+@d undump_qqqq(#)==begin get(fmt_file); #:=fmt_file^.qqqq;@+end
+@y
+@d fmt_get==begin incr(fmt_count);
+ if fmt_count=VAX_block_length then begin
+ get(fmt_file,VAX_error:=VAX_continue); fmt_count:=0; end
+ end
+@d undump_wd(#)==begin fmt_get; #:=fmt_word;@+end
+@d undump_int(#)==begin fmt_get; #:=fmt_word.int;@+end
+@d undump_hh(#)==begin fmt_get; #:=fmt_word.hh;@+end
+@d undump_qqqq(#)==begin fmt_get; #:=fmt_word.qqqq;@+end
+@z
+
+@x
+x:=fmt_file^.int;
+@y
+x:=fmt_word.int;
+@z
+
+@x [50] fmt file blocked
+w_close(fmt_file)
+@y
+while fmt_count>0 do dump_int(0); {flush out the buffer}
+w_close(fmt_file)
+@z
+
+@x
+@!ready_already:integer; {a sacrifice of purity for economy}
+@y
+@!ready_already:[VAX_static]integer := 0; {a sacrifice of purity for economy}
+@z
+
+@x [54] left overs
+This section should be replaced, if necessary, by changes to the program
+that are necessary to make \TeX\ work at a particular installation.
+It is usually best to design your change file so that all changes to
+previous sections preserve the section numbering; then everybody's version
+will be consistent with the published program. More extensive changes,
+which introduce new sections, can be inserted here; then only the index
+itself will get a new section number.
+@y
+Here are the remaining changes to the program
+that are necessary to make \.{TeX} work on Vax/VMS.
+
+@ Here are the things we need for |byte_file| and |word_file| files:
+
+@<Glob...@>=
+@!tfm_count: 0..VAX_block_length;
+@!fmt_count: 0..VAX_block_length;
+
+@ Here's the interrupt stuff.
+
+@<Types...@>=
+@!signed_halfword=[VAX_word] -32768..32767;
+@!sixteen_bits=[VAX_word] 0..65535;
+
+@ @<Glob...@>=
+@!itm: array [1..4] of VAX_unsigned;
+@!res:[VAX_volatile] integer;
+@!tt_chan: [VAX_volatile] signed_halfword;
+
+@ @<Vax/VMS procedures@>=
+[asynchronous] procedure @!ctrlc_rout;
+begin
+interrupt:=1;
+enable_control_C;
+end;
+
+@ Here is the stuff for magic file operations.
+@<Types...@>=
+unsafe_file = [unsafe] file of char;
+FAB_ptr = ^VAX_FAB_type;
+RAB_ptr = ^VAX_RAB_type;
+NAM_ptr = ^VAX_NAM_type;
+charptr = ^char;
+
+@ @<Vax/VMS procedures@>=
+function VAX_PAS_FAB(var foobar:unsafe_file):FAB_ptr; extern;
+function VAX_PAS_RAB(var foobar:unsafe_file):RAB_ptr; extern;
+
+@ @<Glob...@>=
+in_FAB,out_FAB: FAB_ptr;
+in_RAB,out_RAB: RAB_ptr;
+last_length: integer;
+last_name:packed array [1..file_name_size] of char;
+@z