home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ucsdibmpc.zip / kermutil.text < prev    next >
Text File  |  1984-05-23  |  13KB  |  493 lines

  1. unit kermutil;
  2.  
  3. { Change log:
  4.  
  5.         13 May 84: Use KERNEL's syscom record for screen control -sp-
  6. }
  7.  
  8. interface
  9.  
  10.    uses {$U kermglob.code} kermglob;
  11.  
  12.  
  13.    function read_ch(unitno: integer; var ch: char): boolean;
  14.  
  15.    procedure read_str(unitno:integer; var s: string255);
  16.  
  17.    procedure echo(ch: char);
  18.  
  19.    procedure clear_buf(unitno:integer);
  20.  
  21.    function aand(x,y: integer): integer;
  22.  
  23.    function aor(x,y: integer): integer;
  24.  
  25.    function xor(x,y: integer): integer;
  26.  
  27.    procedure uppercase(var s: string255);
  28.  
  29.    procedure error(p: packettype; len: integer);
  30.  
  31.    procedure io_error(i: integer);
  32.  
  33.    procedure debugwrite(s: string255);
  34.  
  35.    procedure debugint(s: string255; i: integer);
  36.  
  37.    function min(x,y: integer): integer;
  38.  
  39.    function tochar(ch: char): char;
  40.  
  41.    function unchar(ch: char): char;
  42.  
  43.    function ctl(ch: char): char;
  44.  
  45.    function getch(var r: char_int_rec): boolean;
  46.  
  47.    function getsoh: boolean;
  48.  
  49.    function getfil(filename: string255): boolean;
  50.  
  51.    procedure send_brk;
  52.  
  53.    procedure setup_comm;
  54.  
  55.    procedure write_ch(unitno: integer; ch: char );
  56.  
  57.    procedure screen( scrcmd: scrcommands );
  58.  
  59.    procedure writescreen(s: string255);
  60.  
  61.    procedure refresh_screen(numtry, num: integer);
  62.  
  63.  
  64. implementation
  65.  
  66. uses {$U remunit.code} remunit,  {SP, 1/14/84}
  67.      {$U kernel.code} kernel;
  68.  
  69.  
  70. procedure uppercase(*var s: string255*);
  71.  
  72. var i: integer;
  73.  
  74.   begin
  75.     for i := 1 to length(s) do
  76.         if s[i] in ['a'..'z'] then
  77.             s[i] := chr(ord(s[i]) - ord('a') + ord('A'))
  78.   end; (* uppercase *)
  79.  
  80.  
  81.  screen -- perform screen operations 
  82. procedure screen{( scrcmd: scrcommands )};
  83. begin
  84.    { for portability, peek in at syscom vector to get control chars }
  85.    with syscom^ do begin
  86.       if crtctrl.prefixed[ord(scrcmd)] then
  87.          write( crtinfo.prefix );
  88.  
  89.       with crtctrl do
  90.          case scrcmd of
  91.             sc_up:       write( rlf );
  92.             sc_right:    write( ndfs );
  93.             sc_clreol:   write( eraseeol );
  94.             sc_clreos:   write( eraseeos );
  95.             sc_home:     write( home );
  96.             sc_escape:   write( escape );
  97.             sc_left:     write( backspace );
  98.             sc_clrall:   write( clearscreen );
  99.             scr_clrline: write( clearline )
  100.          end
  101.    end
  102. end; { screen }
  103.  
  104.  
  105. function read_ch(*unitno:integer; var ch: char): boolean*);
  106.  
  107. (* read a character from an input queue *)
  108. var
  109.    ready: boolean;
  110.  
  111.   begin
  112.     if unitno=keyport then
  113.        ready := cr_kbstat
  114.     else if unitno=inport then
  115.        ready := cr_remstat
  116.     else
  117.        ready := false;
  118.     if ready then            (* if a char there *)
  119.        if unitno=keyport then begin
  120.           ch := ' ';
  121.           unitread( keyport, ch, 1,, 12 )
  122.        end
  123.        else
  124.           ch := cr_getrem;
  125.     read_ch := ready
  126.   end; (* read_ch *)
  127.  
  128. procedure write_ch(*unitno: integer; ch: char*);
  129. begin
  130.    if unitno=oport then
  131.       cr_putrem( ch )
  132. end;
  133.  
  134.  
  135. procedure read_str(*unitno:integer; var s: string255*);
  136.  
  137. (* acts like readln(s) but takes input from input queue *)
  138.  
  139. var i: integer;
  140.  
  141.   begin
  142.     i := 0;
  143.     s := copy('',0,0);
  144.     repeat
  145.       repeat                              (* get a character *)
  146.       until read_ch(unitno,ch);
  147.       if (ord(ch) = backspace) then       (* if it's a backspace then *)
  148.         begin
  149.           if (i > 0) then                   (* if not at beginning of line *)
  150.             begin
  151.               write(ch);                      (* go back a space on screen *)
  152.               write(' ');                     (* erase char on screen *)
  153.               write(ch);                      (* go back a space again *)
  154.               i := i - 1;                     (* adjust string counter *)
  155.               s := copy(s,1,i)                (* adjust string *)
  156.             end (* if *)
  157.         end (* if *)
  158.       else if (ord(ch) <> eoln_sym) then  (* otherwise if not at eoln  then *)
  159.         begin
  160.           write(ch);                        (* echo char on screen *)
  161.           i := i + 1;                       (* inc string counter *)
  162.           s := concat(s,' ');
  163.           s[i] := ch;                       (* put char in string *)
  164.         end; (* if *)
  165.     until (ord(ch) = eoln_sym);           (* if not eoln, get another char *)
  166.     s := copy(s,1,i);                     (* correct string length *)
  167.     writeln                               (* write a line on the screen *)
  168.   end; (* read_str *)
  169.  
  170.  
  171. procedure clear_buf(*unitno:integer*);
  172.  modified by SP 
  173. begin
  174.    if unitno=keyport then
  175.       unitclear( unitno )
  176. end;
  177.  
  178.  
  179. procedure send_brk;
  180. begin
  181.    cr_break
  182. end;
  183.  
  184.  
  185. procedure setup_comm;
  186.  SP, 14 Jan 84 
  187. var
  188.    result: cr_baud_result;
  189. begin
  190.    cr_setcommunications(false,
  191.                         false,
  192.                         baud,
  193.                         8,
  194.                         1,
  195.                         cr_orig,
  196.                         'IBM PC',
  197.                         result );
  198. end;
  199.  
  200.  
  201. function aand(*x,y: integer): integer*);
  202.  
  203. (* arithmetic and--takes 2 integers and ands them, yeilding an integer *)
  204.  
  205. var xrec, yrec, temp: int_bool_rec;
  206.  
  207.   begin
  208.     xrec.i := x;                  (* put the two numbers in variant record *)
  209.     yrec.i := y;
  210.     temp.b := xrec.b and yrec.b;  (* use as booleans to 'and' them *)
  211.     aand := temp.i                (* return integer result *)
  212.   end; (* aand *)
  213.  
  214.  
  215. function aor(*x,y: integer): integer*);
  216.  
  217. (* arithmetic or *)
  218.  
  219. var xrec, yrec, temp: int_bool_rec;
  220.  
  221.   begin
  222.     xrec.i := x;                  (* put two numbers in variant record *)
  223.     yrec.i := y;
  224.     temp.b := xrec.b or yrec.b;   (* use as booleans to 'or' them *)
  225.     aor := temp.i                 (* return integer result *)
  226.   end; (* aor *)
  227.  
  228. function xor(*x,y: integer): integer*);
  229.  
  230. (* exclusive or *)
  231.  
  232. var xrec, yrec, temp: int_bool_rec;
  233.  
  234.   begin
  235.     xrec.i := x;                  (* put two numbers in variant record *)
  236.     yrec.i := y;
  237.                                   (* use as booleans to 'xor' them *)
  238.     temp.b := (xrec.b or yrec.b) and (not(xrec.b and yrec.b));
  239.     xor := temp.i                 (* return integer result *)
  240.   end; (* xor *)
  241.  
  242. procedure error(*p: packettype; len: integer*);
  243.  
  244. (* writes error message sent by remote host *)
  245.  
  246. var i: integer;
  247.  
  248.   begin
  249.     gotoxy(0,errorline);
  250.     for i := 0 to len-1 do
  251.         write(p[i]);
  252.     gotoxy(0,promptline);
  253.   end; (* error *)
  254.  
  255. procedure io_error(*i: integer*);
  256.  
  257.   begin
  258.     gotoxy( 0, errorline );
  259.     screen( sc_clreol );
  260.     case i of
  261.         0: writeln('No error');
  262.         1: writeln('Bad Block, Parity error (CRC)');
  263.         2: writeln('Bad Unit Number');
  264.         3: writeln('Bad Mode, Illegal operation');
  265.         4: writeln('Undefined hardware error');
  266.         5: writeln('Lost unit, Unit is no longer on-line');
  267.         6: writeln('Lost file, File is no longer in directory');
  268.         7: writeln('Bad Title, Illegal file name');
  269.         8: writeln('No room, insufficient space');
  270.         9: writeln('No unit, No such volume on line');
  271.         10: writeln('No file, No such file on volume');
  272.         11: writeln('Duplicate file');
  273.         12: writeln('Not closed, attempt to open an open file');
  274.         13: writeln('Not open, attempt to close a closed file');
  275.         14: writeln('Bad format, error in reading real or integer');
  276.         15: writeln('Ring buffer overflow')
  277.       end; (* case *)
  278.     gotoxy(0,promptline)
  279.   end; (* io_error *)
  280.  
  281. procedure debugwrite(*s: string255*);
  282.  
  283. (* writes a debugging message *)
  284. var i: integer;
  285.  
  286.   begin
  287.     if debug then
  288.       begin
  289.         gotoxy(0,debugline);
  290.         screen( sc_clreol );
  291.         write(s);
  292.         for i := 1 to 2000 do ;                (* write debugging message *)
  293.       end (* if debug *)
  294.   end; (* debugwrite *)
  295.  
  296. procedure debugint(*s: string255; i: integer*);
  297.  
  298. (* write a debugging message and an integer *)
  299.  
  300.   begin
  301.     if debug then
  302.       begin
  303.         debugwrite(s);
  304.         write(i)
  305.       end (* if debug *)
  306.   end; (* debugint *)
  307.  
  308. function min(*x,y: integer): integer*);
  309.  
  310. (* returns smaller of two integers *)
  311.  
  312.   begin
  313.     if x < y then
  314.         min := x
  315.     else
  316.         min := y
  317.   end; (* min *)
  318.  
  319. function tochar(*ch: char): char*);
  320.  
  321. (* tochar converts a control character to a printable one by adding space *)
  322.  
  323.   begin
  324.     tochar := chr(ord(ch) + ord(' '))
  325.   end; (* tochar *)
  326.  
  327. function unchar(*ch: char): char*);
  328.  
  329. (* unchar undoes tochar *)
  330.  
  331.   begin
  332.     unchar := chr(ord(ch) - ord(' '))
  333.   end; (* unchar *)
  334.  
  335. function ctl(*ch: char): char*);
  336.  
  337. (* ctl toggles control bit: ^A becomes A, A becomes ^A *)
  338.  
  339.   begin
  340.     ctl := chr(xor(ord(ch),64))
  341.   end; (* ctl *)
  342.  
  343. procedure echo(*ch: char*);
  344.  
  345. (* echos a character on the screen *)
  346. const
  347.    maxtry = 30000;
  348.  
  349. var count, cursorx, cursory:integer;
  350.  The DataMedia emulation is by John Socha. 
  351. begin
  352.    ch := chr(aand(ord(ch),127)); (* mask off parity bit *)
  353.  
  354.    if emulating and (ord(ch) in [30,25,28,31,29,11]) then
  355.       case ord(ch) of
  356.          { Datamedia 1520 emulation }
  357.          { rs }30: begin
  358.                       { allow timeout while waiting for coordinates
  359.                         so computer doesn't freeze }
  360.                       count := 0;
  361.                       repeat
  362.                          count := count + 1
  363.                       until read_ch( inport, ch ) or (count>maxtry);
  364.                       if count<=maxtry then begin
  365.                          cursorx:=ord(ch)-32;
  366.                          count := 0;
  367.                          repeat
  368.                             count := count + 1
  369.                          until read_ch( inport, ch ) or (count>maxtry);
  370.                          if count<=maxtry then begin
  371.                             cursory:=ord(ch)-32;
  372.                             gotoxy(cursorx,cursory)
  373.                          end
  374.                       end
  375.                    end;
  376.          { em }25: screen( sc_home );
  377.          { fs }28: screen( sc_right );
  378.          { us }31: screen( sc_up );
  379.          { gs }29: screen( sc_clreol );
  380.          { vt }11: screen( sc_clreos )
  381.       end
  382.     else
  383.        unitwrite(1,ch,1,,12)  { the 12 eliminates DLE & CR expansion }
  384.   end; (* echo *)
  385.  
  386.  
  387. function getch(*var r: char_int_rec): boolean*);
  388.  
  389. (* gets a character, strips parity, returns true if it got a char which *)
  390. (* isn't Kermit SOH, false if it gets SOH or nothing after maxtry *)
  391.  
  392. const maxtry = 10000;
  393.  
  394. var count: integer;
  395.  
  396.   begin
  397.     count := 0;
  398.     getch := false;
  399.     repeat
  400.         count := count + 1;
  401.     until (read_ch(inport,r.ch)) or (count>maxtry);  (* wait for a character *)
  402.     if (count > maxtry) then                    (* if wait too long then *)
  403.         exit(getch);                              (* get out of here *)
  404.     r.i := aand(r.i,127);                       (* strip parity from char *)
  405.     getch := (r.ch <> chr(soh));                (* return true if not SOH *)
  406.   end; (* getch *)
  407.  
  408.  
  409. function getsoh(*: boolean*);
  410.  
  411. (* reads characters until it finds an SOH; returns false if has to read more *)
  412. (* than maxtry chars *)
  413.  modified by SP 
  414.  
  415. const maxtry = 10000;
  416.  
  417. var ch: char;
  418.     count: integer;
  419.  
  420.   begin
  421.     count := 0;
  422.     getsoh := true;
  423.     repeat
  424.       repeat
  425.         count := count + 1
  426.       until (read_ch(inport,ch)) or (count > maxtry); (* wait for a character *)
  427.       if (count > maxtry) then
  428.         begin
  429.             getsoh := false;
  430.             exit(getsoh)
  431.           end; (* if *)
  432.         ch := chr(aand(ord(ch),127));            (* strip parity of char *)
  433.     until (ch = chr(SOH))                        (* if not SOH, get more *)
  434.   end; (* getsoh *)
  435.  
  436.  
  437. function getfil(*filename: string255): boolean*);
  438.  
  439. (* opens a file for writing *)
  440.  
  441.   begin
  442.     (*$I-*) (* turn i/o checking off *)
  443.     rewrite(f,filename);
  444.     (*$I-*) (* turn i/o checking on *)
  445.     getfil := (ioresult = 0)
  446.   end; (* getfil *)
  447.  
  448.  
  449. procedure writescreen(*s: string255*);
  450.  
  451. (* sets up the screen for receiving or sending files *)
  452.  
  453. begin
  454.    page(output);
  455.    gotoxy(0,titleline);
  456.    write('            Kermit UCSD p-system, Version ', version );
  457.    gotoxy(statuspos,statusline);
  458.    write(s);
  459.    gotoxy(0,packetline);
  460.    write('Number of Packets: ');
  461.    gotoxy(0,retryline);
  462.    write('Number of Tries: ');
  463.    gotoxy(0,fileline);
  464.    write('File Name: ');
  465. end; (* writescreen *)
  466.  
  467.  
  468. procedure refresh_screen(*numtry, num: integer*);
  469.  
  470. (* keeps track of packet count on screen *)
  471.  
  472. begin
  473.    gotoxy(retrypos,retryline);
  474.    write(numtry: 5);
  475.    gotoxy(packetpos,packetline);
  476.    write(num: 5)
  477. end; (* refresh_screen *)
  478.  
  479.  
  480. begin { body of unit kermutil }
  481.    { initialization code }
  482.    syscom^.crtinfo.flush := chr(255);  { effectively turning flush off }
  483.    syscom^.crtinfo.stop := chr(254);   { effectively turning stop off }
  484.  
  485.    ***;  { <-- would you believe that this is Pascal? }
  486.  
  487.    { termination code }
  488.    syscom^.crtinfo.flush := chr(6);  { turn flush back on }
  489.    syscom^.crtinfo.stop := chr(19)   { effectively turning stop off }
  490.  
  491. end. { kermutil }
  492.  
  493.