% Change file for TOPS-20 by Tomas Rokicki. Send bug reports to % ROKICKI@SU-SCORE. @x [1] Tell WEAVE to print only the changes: \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\ttw{{\mc TOPS-20}} \def\title{DVIIMP changes for \ttw} @z @x [2] @d banner=='This is DVIIMP, Version 0.94' {printed when the program starts} @y @d banner=='This is DVIIMP, TOPS-20 Version 0.94' {printed when the program starts} @z @x [3] @ The binary input comes from |dvi_file|, and the symbolic output is written on \PASCAL's standard |output| file. The term |print| is used instead of |write| when this program writes on |output|, so that all such output could easily be redirected if desired. @d print(#)==write(#) @d print_ln(#)==write_ln(#) @d print_nl==write_ln @y @ The binary input comes from |dvi_file|, and the symbolic output is written on TOPS-20's standard |tty| file. The term |print| is used instead of |write| when this program writes on |tty|, so that all such output could easily be redirected if desired. @d print(#)==write(tty,#) @d print_ln(#)==write_ln(tty,#) @d print_nl==write_ln(tty) @z @x [4] @p program DVI_IMP(@!dvi_file,@!im_file,@!output); @y @p program DVI_IMP ; @z @x [30] @p function read_int:integer; var i:integer; @!neg_flag:boolean; begin neg_flag:=false; i:=0; get(tty); while tty^=' ' do get(tty); if (tty^='-') then neg_flag:=true; while (tty^='-') or (tty^='+') do get(tty); while (tty^>='0') and (tty^<='9') do begin i:=i*10+xord[tty^]-"0"; get(tty); end; if neg_flag then i:=-i; read_int:=i; end; @y @p function read_int:integer; var i:integer; @!neg_flag:boolean; begin neg_flag:=false; i:=0; if rescan[rsp]='-' then neg_flag := true ; if (rescan[rsp]='-') or (rescan[rsp]='+') then incr(rsp) ; while (rescan[rsp]>='0') and (rescan[rsp]<='9') do begin i:=i*10+xord[rescan[rsp]]-"0"; incr(rsp); end; if neg_flag then i:=-i; read_int:=i; end; @z @x [31] @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file); cur_loc:=0; end; @# procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin reset(gf_file,cur_name); cur_gf_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_tfm_name); end; @y @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file,dvi_name,'/O/B:8'); cur_loc:=0; end; @# procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin reset(gf_file,cur_name,'/O/B:8'); cur_gf_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_tfm_name,'/O/B:8'); end; @z @x [32] @p procedure open_im_file; {prepares to write packed bytes in |im_file|} begin rewrite(im_file); im_byte_no:=0; end; @y @p procedure open_im_file; {prepares to write packed bytes in |im_file|} begin rewrite(im_file,im_name,'/O/B:8'); im_byte_no:=0; end; @z @x [32] it, we will also declare |cur_gf_loc|. @y it, we will also declare |cur_gf_loc|, |dvi_name|, and |im_name|. @z @x [32] @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @!cur_tfm_name:packed array[1..name_length] of char; {external name, with no lower case letters} @y @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @!cur_tfm_name:packed array[1..name_length] of char; {external name, with no lower case letters} @!dvi_name,@!im_name:packed array[1..name_length] of char; {external name, with no lower case letters} @z <><>@x [49] @!font_m_val:array [0..max_fonts] of integer; {overall font magnification} <><>@y @!font_m_val:array [0..max_fonts] of integer; {overall font magnification} @!font_d_val:array [0..max_fonts] of integer; {directory size of font} <><>@z @x [66] and |term_out| for terminal output. @^system dependencies@> @= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y and |term_out| for terminal output. @^system dependencies@> @d term_in==tty {the terminal, considered as an input file} @d term_out==tty {the terminal, considered as an output file} @= @!buffer:array[0..terminal_line_length] of ASCII_code; @z @x [66] begin update_terminal; reset(term_in); @y begin update_terminal; @z @x [67] begin rewrite(term_out); {prepare the terminal for output} write_ln(term_out,banner); @y begin @ ; @z @x [67] repeat if buffer[buf_ptr]="*" then @y begin f_flag := true ; repeat if buffer[buf_ptr]="*" then @z @x [67] until start_vals=k @y until start_vals=k ; start_page := start_count[0] ; end @z @x [68] begin max_pages:=get_integer; @y begin n_flag := true ; max_pages := get_integer ; num_pages := max_pages ; @z <><>@x [72] m:=round((0.3*mag*q)/d); <><>@y m:=round((0.3*mag*q)/d);font_d_val[nf]:=round((1.5*mag*q)/d); <><>@z @x [73] @!k:0..name_size; {indices into |names|} @y @!i:integer; {general index} @!k:0..name_size; {indices into |names|} @z @x [74] print(' not found'); @y print('gf not found'); @z @x [75] cur_name[r+1]:='.'; cur_name[r+2]:='G'; cur_name[r+3]:='F'; @y incr(r) ; cur_name[r] := '.' ; i := font_m_val[cur_font] ; incr(r) ; if i > 1000 then begin cur_name[r] := xchr["0"+i div 1000] ; incr(r) ; i := i mod 1000 ; end ; cur_name[r] := xchr["0"+i div 100] ; incr(r) ; i := i mod 100 ; cur_name[r] := xchr["0"+i div 10] ; incr(r) ; cur_name[r] := xchr["0"+i mod 10] ; cur_name[r+1]:='G'; cur_name[r+2]:='F'; @z @x [98] @p begin initialize; {get all variables initialized} @y @p begin initialize; {get all variables initialized} @ ; @z @x final_end:end. @y if spoolit then @; final_end:end. @z @x [99] This section should be replaced, if necessary, by changes to the program that are necessary to make \.{DVIIMP} 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 printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @^system dependencies@> @y These are the changes that are necessary to make \.{DVIIMP} work on TOPS-20. This just means getting the file name from the command line currently, but additional code to parse options needs to be added. @^system dependencies@> @ On TOPS-20, we can get the command line using the so-called rescan buffer. Thus, the command line actually becomes the first part of input seen in the file \.{TTY}. We need to skip over to the file name, then parse the file name and any options that may be specified. @d RSCAN=@'500 {ReSCAN buffer JSYS} @= jsys(RSCAN,1,i;0;ac1); {put the command line into the |TTY| input buffer} if (i<>2) or (ac1<=0) then abort('Couldn''t get a command line, somehow.'); {RSCAN failed, somehow} if eoln(term_in) then read_ln(term_in); {for some TOPS-20's} read(term_in,rescan:rescan_len); {read in rescan buffer} if rescan_len>max_rescan then abort('command line too long!') ; read_ln(term_in) ; if rescan_len=ac1-2 then dialog else begin i:=1; while rescan[i]>' ' do incr(i) ; { skip invocation name } while(i<=rescan_len) and (rescan[i]=' ') do incr(i) ; {skip spaces} if (i>rescan_len) then dialog else @ ; end ; @ Now we define the routine in dialog which gets the file name from the terminal. @= print('DVI file name: ') ; input_ln ; @ @ We had something on the command line. Now we try to figure out what it was. For now we assume that the whole command line option is the name of the file, so we copy it into |dvi_name|. We then try to figure out where the extension begins, so we can tack on the extension \.{IMP} and use that as the file name. @= begin spoolit:=true; j := 0 ; last_ext := 0 ; rescan[rescan_len+1] := '!' ; while (i <= rescan_len) and (j < terminal_line_length) and (rescan[i] <> '/') do begin buffer[j] := xord[rescan[i]] ; incr(i) ; incr(j) ; end ; rsp := i ; while (rescan[rsp]='/') do @ ; if j >= terminal_line_length then abort('File name too long!') ; buffer[j] := " " ; @; end @ Now we parse the desired option. This can be any of C, F, or N, for copies, starting page, and maximum pages, respectively. @= begin incr(rsp) ; {skip "/"} i := rsp ; while (rescan[i] <> '/') and (rescan[i] <> '!') do incr(i) ; {now |i| points after option spec} opt:=rescan[rsp]; incr(rsp); if (opt>='A') and (opt<='Z') then opt:=chr(ord(opt)-ord('A')+ord('a')); if (opt='c') then read_c else if (opt='f') then read_f else if (opt='n') then read_n else if (opt='h') then read_h else if (opt='v') then read_v else if (opt='i') then spoolit:=false else print_ln('Did not understand ',opt,' option. Ignoring.') ; rsp := i ; end @ Now we parse the name of the file, finding the extension (if any), suffixing one if there wasn't, and creating the |im_name|. @= i := 1 ; last_ext := 0 ; while (buffer[i-1] <> " ") and (i <= terminal_line_length) and (i <= name_length) do begin if (buffer[i-1] <= "z") and (buffer[i-1] >= "a") then buffer[i-1] := buffer[i-1] - 32 ; dvi_name[i] := xchr[buffer[i-1]] ; im_name[i] := xchr[buffer[i-1]] ; if (buffer[i-1] = ".") and (last_ext = 0) then last_ext := i else if buffer[i-1] = ">" then last_ext := 0 ; incr(i) ; end ; if (i > name_length) then abort('File name too long!') ; if last_ext = 0 then begin last_ext := i ; dvi_name[i] := '.' ; incr(i) ; dvi_name[i] := 'D' ; incr(i) ; dvi_name[i] := 'V' ; incr(i) ; dvi_name[i] := 'I' ; incr(i) ; end ; for j := i to name_length do dvi_name[j] := chr(0) ; i := last_ext ; im_name[i] := '.' ; incr(i) ; im_name[i] := 'I' ; incr(i) ; im_name[i] := 'M' ; incr(i) ; im_name[i] := 'P' ; incr(i) ; for j := i to name_length do im_name[j] := chr(0) @ Magic. @d STI=@'114 {Simulate Terminal Input JSYS} @d PRIIN=@'100 {PRImary INput JFN JSYS} @= begin jsys(STI;PRIIN,ord('I')); jsys(STI;PRIIN,ord('M')); jsys(STI;PRIIN,ord('P')); jsys(STI;PRIIN,ord('S')); jsys(STI;PRIIN,ord('P')); jsys(STI;PRIIN,ord('O')); jsys(STI;PRIIN,ord('O')); jsys(STI;PRIIN,ord('L')); jsys(STI;PRIIN,ord(':')); jsys(STI;PRIIN,ord(' ')); for i:=1 to name_length do if im_name[i]>chr(0) then jsys(STI;PRIIN,ord(im_name[i])); jsys(STI;PRIIN,13); end @ Now we declare all of those variables we used. @= @!max_rescan = 300 ; {maximum command line length} @ @= i, j : integer ; {temporary indices} @!rsp : integer ; {rescan line pointer} @!option : 1..3 ; {what option was selected} @!last_ext : integer ; {where we saw an extension} @!ac1, @!rescan_len : integer ; {system call variables} @!rescan : packed array [1..max_rescan] of char ; {rescan buffer} @!spoolit: boolean; @!opt: char; @z