home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / MODEM / MUFUS32R.ZIP / MUFUSION.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1991-10-31  |  31.4 KB  |  1,079 lines

  1. {$B-}    {Boolean complete evaluation off}
  2. {$S-}    {Stack checking off}
  3. {$I-}    {I/O checking off}
  4. {$R-}    {Range checking off}
  5. {$M 4096,8192,8192}
  6.  
  7. program mufusion;
  8.  
  9. {  This terminal package by was written by Peter Summers, using code
  10.    released to the public domain program by Jim Nutt.  It now emulates a
  11.    Microfusion MF30 terminal.  The program (including source) may be
  12.    distributed freely, but copyright is retained by the Cardiology
  13.    Department at Royal Melbourne Hospital.    }
  14.  
  15. Uses
  16.   Dos,
  17.   Crt,
  18.   MufAsync;
  19.  
  20. const
  21.   default     = -1;
  22.   defportnum  = 1;
  23.   defbaudrate = 9600;
  24.   deffcolor   = 2;          {default foreround color}
  25.   defbcolor   = 0;          {default background color}
  26.   defpcolor   = 3;          {default protected text color}
  27.   space       = $20;
  28.   bufsize     = 744;        {number of lines of backpage buffer (=30+current).  This can be reduced
  29.                              to increase the amount of memory available when shelled to DOS.}
  30.  
  31. var
  32.   fcolor      : integer;
  33.   bcolor      : integer;
  34.   pcolor      : integer;
  35.   screenbuf   : array[1..80,0..bufsize-1] of byte;      {backpage buffer}
  36.   screenptr   : integer;                                {pointer to current screen within backpage buffer}
  37.   end_now     : boolean;
  38.   protmode    : boolean;                                {true = protected text on}
  39.   fkey        : array[1..20] of string[80];             {function key definitions}
  40.   new_line    : boolean;                                {true if a line feed is pending}
  41.   gen_cr      : boolean;                                {true if a carriage return may be generated}
  42.   portnum     : integer;                                {communications port number}
  43.   baudrate    : word;
  44.   capture     : text;
  45.   capture_on  : boolean;
  46.   printer     : text;
  47.   printer_on  : boolean;
  48.   printbuf    : string[128];                            {Buffer for output to the printer.  Don't make this string >128 long,
  49.                                                          or the close command at the end of the program will have to time out
  50.                                                          if the printer is unavailable.  I don't understand this.}
  51.   emulation   : boolean;                                {True if emulation is on, false in debugging mode}
  52.   start_mode  : integer;                                {Text mode when mufusion was called}
  53.   stat_line   : integer;                                {Position of the status line}
  54.   thiskb_stat : byte;                                   {Status of shift/control/alt keys}
  55.   lastkb_stat : byte;                                   {Previous status of shift/control/alt keys}
  56.   fk_defined  : boolean;                                {True if the function keys have been defined}
  57.   auto_echo   : boolean;                                {True if characters echoed locally}
  58.   lastposx    : integer;                                {Used for restoring cursor position (with on of the ecs F functions)}
  59.   lastposy    : integer;
  60.   saveint05   : pointer;                                {The original print screen vector}
  61.   reg         : registers;                              {Used for called to interrupt routines}
  62.   sendbreak   : boolean;                                {True if a break signal should be sent}
  63.   printscrn   : boolean;                                {True if a print screen is pending}
  64.  
  65.  
  66.  
  67. function kb_stat: byte;
  68.  
  69. { Returns the shift/control/alt function key status of the keyboard}
  70.  
  71. begin
  72.   reg.AH := $02;
  73.   intr($16, Reg);
  74.   kb_stat := reg.AL;
  75. end;
  76.  
  77.  
  78.  
  79. procedure stat_write(tstr : string);
  80.  
  81. { Write a string to the status line}
  82.  
  83. var
  84.   oldtextattr : byte;
  85.   x,y         : integer;
  86.  
  87. begin
  88.   x := wherex;
  89.   y := wherey;
  90.   oldtextattr:=textattr;
  91.   textattr:=$70;
  92.   window(1,stat_line,80,stat_line);
  93.   clreol;
  94.   gotoxy(3,1);
  95.   write(tstr);
  96.   window(1,1,80,stat_line-1);
  97.   textattr:=oldtextattr;
  98.   gotoxy(x,y);
  99. end;
  100.  
  101.  
  102.  
  103. function stat_read(pstr : string) : string;
  104.  
  105. { Prompt for an input string on the status line}
  106.  
  107. var
  108.   oldtextattr : byte;
  109.   tstr        : string[80];
  110.   x,y         : integer;
  111.  
  112. begin
  113.  
  114.   x := wherex;
  115.   y := wherey;
  116.   oldtextattr:=textattr;
  117.   textattr:=$70;
  118.   window(1,stat_line,80,stat_line);
  119.   clreol;
  120.   gotoxy(3,1);
  121.   write(pstr);
  122.   gotoxy(length(pstr) + 3,1);
  123.   readln(tstr);
  124.   stat_read := tstr;
  125.   window(1,1,80,stat_line-1);
  126.   textattr:=oldtextattr;
  127.   gotoxy(x,y);
  128. end;
  129.  
  130.  
  131.  
  132. procedure display_statline;
  133.  
  134. { Display the current status line, dependant on keyboard shift/alt key
  135.   status and definition of function keys }
  136.  
  137. var
  138.   oldtextattr : byte;
  139.   startkey    : integer;
  140.   i,j,x,y     : integer;
  141.  
  142. begin
  143.   if (thiskb_stat and $08)<>0 then
  144.     stat_write('(C)apture   (D)ial   (E)mulation   (H)angup   d(O)s   (P)rinter   e(X)it')
  145.   else
  146.     begin
  147.       if fk_defined then
  148.         begin
  149.           x := wherex;
  150.           y := wherey;
  151.           oldtextattr:=textattr;
  152.           window(1,stat_line,80,stat_line);
  153.           gotoxy(1,1);
  154.           clreol;
  155.           textattr:=$70;
  156.           if (thiskb_stat and $03)=0 then
  157.             startkey:=1
  158.           else
  159.             startkey:=11;
  160.           for i:= 0 to 9 do
  161.             begin
  162.               gotoxy(7*i+2*(i div 4)+1,1);
  163.               for j:= 1 to 6 do
  164.                 if (j <= length(fkey[startkey+i]))
  165.                   and (ord(fkey[startkey+i,j]) in [32..126])
  166.                     then write(fkey[startkey+i,j]) else write(' ');
  167.             end;
  168.           gotoxy(75,1);
  169.           textattr:=$01;
  170.           write('µ3.2r');
  171.           window(1,1,80,stat_line-1);
  172.           textattr:=oldtextattr;
  173.           gotoxy(x,y);
  174.         end
  175.       else
  176.         stat_write('µfusion v3.2r by Peter Summers                         (C) Cardiology at RMH');
  177.     end;
  178. end;
  179.  
  180.  
  181.  
  182. procedure flushprintbuf;
  183.  
  184. { Flush the printer buffer }
  185.  
  186. begin
  187.   stat_write('Writing to the printer...');
  188.   write(printer,printbuf);
  189.   if IOresult<>0 then
  190.     begin
  191.       stat_write('Can''t write to the printer, turning printing off...');
  192.       printer_on:=false;
  193.       sound(50);
  194.       delay(1000);
  195.       nosound;
  196.     end;
  197.   printbuf:='';
  198.   display_statline;
  199. end;
  200.  
  201.  
  202.  
  203. function cgetc(TimeLimit : integer) : integer;
  204.  
  205. { Get a character from the COM port, and send it to the printer and capture
  206.   file as required, or return -1 if no character was found }
  207.  
  208. const
  209.   TIMED_OUT = -1;
  210. var
  211.   rcvd : char;
  212.  
  213. begin
  214.   if TimeLimit>0 then
  215.     begin
  216.       TimeLimit := 1000*TimeLimit;
  217.       repeat
  218.         delay(1);
  219.         TimeLimit:=TimeLimit-1;
  220.       until Async_Buffer_Check or (TimeLimit=0);
  221.     end;
  222.  
  223.   if (Async_Receive(rcvd)) then
  224.     begin
  225.       cgetc := ord(rcvd) and $7F;
  226.       if capture_on then
  227.         begin
  228.           write(capture,rcvd);
  229.           if IOresult<>0 then
  230.             begin
  231.               stat_write('Can''t write to capture file...');
  232.               sound(50);
  233.               delay(1000);
  234.               nosound;
  235.               close(capture);
  236.               capture_on:=false;
  237.               display_statline;
  238.             end;
  239.         end;
  240.       if printer_on then
  241.         begin
  242.           printbuf:=printbuf+rcvd;
  243.           if length(printbuf)=128 then flushprintbuf;
  244.         end;
  245.     end
  246.   else
  247.     cgetc := TIMED_OUT;
  248. end;
  249.  
  250.  
  251.  
  252. procedure hangup;
  253.  
  254. { Hang up the modem }
  255.  
  256. begin
  257.   stat_write('Hanging up the modem...');
  258.   Async_Close(true);
  259.   delay(1100);
  260.   if not(Async_Open(portnum,baudrate,'N',8,1)) then halt(1);
  261.   if Async_Carrier_Detect then
  262.     begin
  263.       Async_Send_String_With_Delays('+++',10,10);
  264.       delay(1100);
  265.       Async_Send_String_With_Delays(^M+'ATH'+^M,10,10);
  266.     end;
  267.   if Async_Carrier_Detect then
  268.     stat_write('The modem won''t hang up...')
  269.   else
  270.     stat_write('The modem has hung up...');
  271.   delay(1000);
  272.  end;
  273.  
  274.  
  275.  
  276. procedure dial;
  277.  
  278. { Dial with a Hayes compatible modem }
  279.  
  280. var
  281.   number : string[40];
  282.  
  283. begin
  284.   number := stat_read('Number to dial? ');
  285.   if number<>'' then
  286.     begin
  287.       if Async_Carrier_Detect then hangup;
  288.       Async_Send_String_With_Delays(^M + 'ATD' + number + ^M,10,10);
  289.     end;
  290. end;
  291.  
  292.  
  293.  
  294. procedure master_clear;
  295.  
  296. { Clear the current screen }
  297.  
  298. var
  299.   i,j : integer;
  300.  
  301. begin
  302.   textattr:=(bcolor shl 4) or 8 or pcolor;
  303.   clrscr;
  304.   protmode:=true;
  305.   screenptr:=(screenptr+24) mod bufsize;
  306.   for i:=1 to 80 do
  307.     for j:=1 to 24 do
  308.       screenbuf[i,(j+screenptr) mod bufsize]:=space;
  309. end;
  310.  
  311.  
  312.  
  313. procedure display_screen;
  314.  
  315. { Display the section of the backpage buffer pointed to by screenptr }
  316.  
  317. var
  318.   i,j,k       : integer;
  319.   oldtextattr : byte;
  320.  
  321. begin
  322.   oldtextattr:=textattr;
  323.   clrscr;
  324.   for j:=1 to 24 do
  325.     if screenbuf[1,(j+screenptr) mod bufsize]=0 then write(^M^J) else
  326.       for i:=1 to 80 do
  327.         if not ((i=80) and (j=24)) then
  328.           begin
  329.             k:=screenbuf[i,(j+screenptr) mod bufsize];
  330.             if (k and $80)=0 then
  331.               textattr:=(bcolor shl 4) or 8 or fcolor
  332.             else
  333.               textattr:=(bcolor shl 4) or 8 or pcolor;
  334.             write(chr(k and $7F));
  335.           end;
  336.   textattr:=oldtextattr;
  337. end;
  338.  
  339.  
  340.  
  341. procedure control_break(flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp:word);
  342.  
  343. { Interrupt routine to catch the control-break key }
  344.  
  345. interrupt;
  346.  
  347. begin
  348.   sendbreak:=true;
  349. end;
  350.  
  351.  
  352.  
  353. procedure print_screen(flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp:word);
  354.  
  355. { Interrupt routine to catch the print-screen key }
  356.  
  357. interrupt;
  358.  
  359. begin
  360.   printscrn:=true;
  361. end;
  362.  
  363.  
  364.  
  365. procedure screen_dump;
  366.  
  367. { Print the section of the backpage buffer pointed to by screenptr (normally
  368.   the current screen) to the nominated print device }
  369.  
  370. var
  371.   i,j,k : integer;
  372.  
  373. begin
  374.   stat_write('Writing to the printer...');
  375.   for j:=1 to 24 do
  376.     if screenbuf[1,(j+screenptr) mod bufsize]<>0 then
  377.       for i:=1 to 81 do
  378.         begin
  379.           if (i<81) then
  380.             write(printer,chr(screenbuf[i,(j+screenptr) mod bufsize] and $7F))
  381.           else
  382.             write(printer,^M+^J);
  383.           if IOresult<>0 then
  384.             begin
  385.               stat_write('Can''t write to the printer, turning printing off...');
  386.               sound(50);
  387.               delay(1000);
  388.               nosound;
  389.               display_statline;
  390.               exit;
  391.             end;
  392.         end;
  393.   display_statline;
  394. end;
  395.  
  396.  
  397.  
  398. procedure backpage;
  399.  
  400. { Do backpaging }
  401.  
  402. var
  403.   x,y          : integer;
  404.   oldtextattr  : byte;
  405.   oldscreenptr : integer;
  406.   keystroke    : integer;
  407.  
  408. begin
  409.   x:=wherex;
  410.   y:=wherey;
  411.   oldtextattr:=textattr;
  412.   oldscreenptr:=screenptr;
  413.   screenptr:=(screenptr+bufsize-24) mod bufsize;
  414.   repeat
  415.     stat_write('PgUp goes backwards, PgDn goes forward, press the Space Bar to quit...');
  416.     display_screen;
  417.     keystroke:=ord(readkey);
  418.     if keystroke=0 then
  419.       begin
  420.         if ord(readkey) in [73,110] then
  421.           begin
  422.             if ((screenptr+bufsize-oldscreenptr) mod bufsize) > 24 then
  423.               screenptr:=(screenptr+bufsize-24) mod bufsize;
  424.           end
  425.         else
  426.           screenptr:=(screenptr+24) mod bufsize;
  427.       end;
  428.     if printscrn then
  429.       begin
  430.         screen_dump;
  431.         printscrn:=false;
  432.       end;
  433.   until (keystroke<>0) or (screenptr=oldscreenptr);
  434.   screenptr:=oldscreenptr;
  435.   display_screen;
  436.   display_statline;
  437.   gotoxy(x,y);
  438.   textattr:=oldtextattr;
  439. end;
  440.  
  441.  
  442.  
  443. procedure toggle_emulation;
  444.  
  445. { Toggle emulution/debugging }
  446.  
  447. begin
  448.   if start_mode<>mono then
  449.     begin
  450.       if emulation then
  451.         begin
  452.           textmode(Font8x8+CO80);
  453.           setintvec($05,saveint05);
  454.         end
  455.       else
  456.         begin
  457.           textmode(CO80);
  458.           setintvec($05,@print_screen);
  459.         end;
  460.       stat_line:=hi(windmax)+1;
  461.     end;
  462.   emulation := not emulation;
  463.   master_clear;
  464. end;
  465.  
  466.  
  467.  
  468. procedure toggle_capture;
  469.  
  470. { Toggle the capture file status }
  471.  
  472. var
  473.   attributes   : word;
  474.   keystroke    : char;
  475.   capture_file : string[80];
  476.  
  477. begin
  478.   if capture_on then
  479.     begin
  480.       stat_write('Closing capture file...');
  481.       close(capture);
  482.       delay(1000);
  483.       capture_on:=false;
  484.       display_statline;
  485.     end
  486.   else
  487.     begin
  488.       capture_file:=stat_read('Capture file name ... ');
  489.       if capture_file<>'' then
  490.         begin
  491.           assign(capture,capture_file);
  492.           getfattr(capture,attributes);
  493.           if attributes=0 then
  494.             rewrite(capture)
  495.           else
  496.             repeat
  497.               sound(50);
  498.               delay(1000);
  499.               nosound;
  500.               stat_write('File exists, (A)ppend, (O)verlay, or (Q)uit ? ..');
  501.               keystroke:=readkey;
  502.               case keystroke of
  503.                 'A','a' : append(capture);
  504.                 'O','o' : rewrite(capture);
  505.                 'Q','q' : exit;
  506.               end;
  507.             until keystroke in ['Q','q','O','o','A','a'];
  508.           if IOresult=0 then
  509.             capture_on:=true
  510.           else
  511.             begin
  512.               stat_write('Can''t open '+capture_file+'...');
  513.               sound(50);
  514.               delay(1000);
  515.               nosound;
  516.             end;
  517.         end;
  518.     end;
  519. end;
  520.  
  521.  
  522.  
  523. procedure shell_to_dos;
  524.  
  525. { Shell to DOS }
  526.  
  527. var
  528.   x,y         : integer;
  529.   oldscrnmode : word;
  530.   oldtextattr : byte;
  531.  
  532. begin
  533.   x:=wherex;
  534.   y:=wherey;
  535.   oldtextattr:=textattr;
  536.   oldscrnmode:=lastmode;
  537.   textmode(start_mode);
  538.   textattr:=$07;
  539.   write('Shelling to DOS, type EXIT to return...');
  540.   setintvec($05,saveint05);
  541.   swapvectors;
  542.   exec(getenv('COMSPEC'),'');
  543.   swapvectors;
  544.   textmode(oldscrnmode);
  545.   textattr:=oldtextattr;
  546.   display_statline;
  547.   if emulation then
  548.     begin
  549.       setintvec($05,@print_screen);
  550.       display_screen;
  551.       gotoxy(x,y);
  552.     end;
  553. end;
  554.  
  555.  
  556.  
  557. procedure findunprot;
  558.  
  559. { Find the next unprotected section of the screen }
  560.  
  561. var
  562.   i,j  : integer;
  563.  
  564. begin
  565.   i := wherex;
  566.   j := wherey;
  567.   repeat
  568.     i:=i+1;
  569.     if i=81 then
  570.       begin
  571.         i:=1;
  572.         j:=j+1;
  573.       end;
  574.   until ((i=80) and (j=24)) or
  575.     ((screenbuf[i,(j+screenptr) mod bufsize] and $80)=0);
  576.   gotoxy(i,j);
  577. end;
  578.  
  579.  
  580.  
  581. procedure setup;
  582.  
  583. { Initialise the program }
  584.  
  585. var
  586.   code : integer;
  587.   i,j  : integer;
  588.  
  589. begin
  590.   checkbreak:=false;
  591.   start_mode:=lastmode;
  592.   stat_line:=hi(windmax)+1;
  593.   code:=0;
  594.   if paramcount>0 then
  595.     val(paramstr(1),portnum,code)
  596.   else
  597.     portnum:=defportnum;
  598.   portnum:=((portnum-1) and 3)+1;
  599.   if paramcount>1 then
  600.     val(paramstr(2),baudrate,code)
  601.   else
  602.     baudrate:=defbaudrate;
  603.   if start_mode=mono then
  604.     begin
  605.       fcolor:=7;
  606.       bcolor:=0;
  607.       pcolor:=7;
  608.     end
  609.   else
  610.     begin
  611.       textmode(co80);
  612.       if paramcount>2 then
  613.         val(paramstr(3),fcolor,code)
  614.       else
  615.         fcolor:=deffcolor;
  616.       fcolor:=fcolor and 7;
  617.       if paramcount>3 then
  618.         val(paramstr(4),bcolor,code)
  619.       else
  620.         bcolor:=defbcolor;
  621.       bcolor:=bcolor and 7;
  622.       if paramcount>4 then
  623.         val(paramstr(5),pcolor,code)
  624.       else
  625.         pcolor:=defpcolor;
  626.       pcolor:=pcolor and 7;
  627.     end;
  628.   if paramcount>5 then
  629.     assign(printer,paramstr(6))
  630.   else
  631.     assign(printer,'LPT1');
  632.   rewrite(printer);
  633.   end_now := false;
  634.   for i := 1 to 20 do fkey[i]:='';
  635.   new_line:=false;
  636.   gen_cr:=false;
  637.   capture_on:=false;
  638.   printer_on:=false;
  639.   printbuf:='';
  640.   emulation:=true;
  641.   lastkb_stat:=$FF;
  642.   fk_defined:=false;
  643.   auto_echo:=false;
  644.   sendbreak:=false;
  645.   printscrn:=false;
  646.  
  647.   Async_Init(default,default,default,default,default);
  648.   Async_Setup_Port(portnum,default,default,default);
  649.  
  650.   if not(Async_Open(portnum,baudrate,'N',8,1)) then
  651.     begin
  652.       write('Can''t find port number ',portnum,'.');
  653.       halt(1);
  654.     end;
  655.  
  656.   Async_Clear_Errors;
  657.  
  658.   screenptr:=0;
  659.   for j:=0 to bufsize-1 do
  660.     screenbuf[1,j]:=0;
  661.  
  662.   master_clear;
  663.  
  664.   getintvec($05,saveint05);
  665.   setintvec($05,@print_screen);
  666.   setintvec($1B,@control_break);
  667.  
  668. end;
  669.  
  670.  
  671.  
  672. procedure facilities;
  673.  
  674. { Implement the esc-F facilities }
  675.  
  676. var
  677.   i,k : integer;
  678.  
  679. begin
  680.   case cgetc(5) of
  681.     65 : printer_on:=true;
  682.     66 : begin
  683.            printer_on:=false;
  684.            flushprintbuf;
  685.          end;
  686.     67 : begin
  687.            printer_on:=true;
  688.            repeat until ((cgetc(5)=27)and(cgetc(5)=70)and(cgetc(5)=66))
  689.              or (keypressed and (readkey=chr(3)));
  690.            printer_on:=false;
  691.            flushprintbuf;
  692.          end;
  693.     69 : auto_echo:=true;
  694.     70 : auto_echo:=false;
  695.     77 : begin
  696.            gotoxy(lastposx,lastposy);
  697.            lastposx:=wherex;
  698.            lastposy:=wherey;
  699.          end;
  700.     87 : begin
  701.            for i:=1 to 20 do fkey[i]:='';
  702.            i:=1;
  703.            repeat
  704.              k:=cgetc(5);
  705.              case k of
  706.                2 : if i>1 then i:=i-1;
  707.                3 : i:=i+1;
  708.                4 : ;
  709.                6 : i:=i+1;
  710.              else
  711.                if i<=20 then fkey[i]:=fkey[i]+chr(k);
  712.              end;
  713.            until k=4;
  714.            fk_defined:=true;
  715.            display_statline;
  716.          end;
  717.   end;
  718. end;
  719.  
  720.  
  721.  
  722. procedure escape;
  723.  
  724. { Implement the escape sequences }
  725.  
  726. var
  727.   rcvd : integer;
  728.   ch   : char;
  729.   x,y  : integer;
  730.   i,j  : integer;
  731.  
  732. begin
  733.   rcvd := cgetc(5);
  734.   if rcvd > 0
  735.     then
  736.       begin
  737.         case rcvd of
  738.           32    : write(^H+' '+^H);           {back space destructive}
  739.           33    : begin
  740.                     sound(50);
  741.                     repeat until keypressed;
  742.                     nosound;
  743.                   end;
  744.           38    : begin
  745.                     protmode:=FALSE;          {protected mode OFF}
  746.                     textattr:=textattr and $F8 or fcolor
  747.                   end;
  748.           39    : begin
  749.                     protmode:=TRUE;           {protected mode ON}
  750.                     textattr:=textattr and $F8 or pcolor
  751.                   end;
  752.           40    : textattr:=textattr or 8;    {high intensity}
  753.           41    : textattr:=textattr and $F7; {low intensity}
  754.           42    : gotoxy(1,wherey+1);         {new line}
  755.           43    : master_clear;               {master clear}
  756.           44,89,111
  757.                 : begin                       {clear to end of page}
  758.                     i := wherex;
  759.                     j := wherey;
  760.                     x := wherex;
  761.                     y := wherey;
  762.                     repeat
  763.                       if ((screenbuf[x,(y+screenptr) mod bufsize] and $80)=0)
  764.                         or (protmode and (rcvd<>111)) then
  765.                           begin
  766.                             screenbuf[x,(y+screenptr) mod bufsize]:=space;
  767.                             gotoxy(x,y);
  768.                             write(' ');
  769.                           end;
  770.                       x:=x+1;
  771.                       if x=81 then
  772.                         begin
  773.                           x:=1;
  774.                           y:=y+1;
  775.                         end;
  776.                     until (x=80) and (y=24);
  777.                     gotoxy(i,j);
  778.                   end;
  779.           45,84 : begin                       {clear to end of line}
  780.                     i := wherex;
  781.                     j := wherey;
  782.                     x := wherex;
  783.                     y := wherey;
  784.                     repeat
  785.                       if ((screenbuf[x,(y+screenptr) mod bufsize] and $80)=0)
  786.                         or protmode then
  787.                         begin
  788.                           screenbuf[x,(y+screenptr) mod bufsize]:=space;
  789.                           gotoxy(x,y);
  790.                           write(' ');
  791.                         end;
  792.                       x:=x+1;
  793.                     until (x=81) or ((x=80) and (y=24));
  794.                     gotoxy(i,j);
  795.                   end;
  796.           49    : if protmode then            {non-reverse text}
  797.                     textattr:=(textattr and $88) or pcolor or (bcolor shl 4)
  798.                   else
  799.                     textattr:=(textattr and $88) or fcolor or (bcolor shl 4);
  800.           50    : if protmode then            {reverse text}
  801.                     textattr:=(textattr and $88) or bcolor or (pcolor shl 4)
  802.                   else
  803.                     textattr:=(textattr and $88) or bcolor or (fcolor shl 4);
  804.           53    : begin                       {bell}
  805.                     sound(220);
  806.                     delay(200);
  807.                     nosound;
  808.                   end;
  809.           60    : if (wherex>1) and
  810.                     ((screenbuf[wherex-1,(wherey+screenptr) mod bufsize] and $80)=0)
  811.                       then gotoxy(wherex-1,wherey);  {cursor left}
  812.           61    : begin                       {goto y,x}
  813.                     y:=cgetc(5)-31;
  814.                     x:=cgetc(5)-31;
  815.                     if x>80 then x:=wherex;
  816.                     if y>24 then y:=wherey;
  817.                     lastposx:=wherex;
  818.                     lastposy:=wherey;
  819.                     gotoxy(x,y);
  820.                   end;
  821.           62    :  if wherex<80 then
  822.                      begin
  823.                        if ((screenbuf[wherex+1,(wherey+screenptr) mod bufsize]
  824.                          and $80)<>0) then
  825.                            findunprot
  826.                          else
  827.                            gotoxy(wherex+1,wherey);    {cursor right}
  828.                      end;
  829.           64    : Async_Send(^M);             {clear prism junk}
  830.           69    : begin
  831.                     insline;                  {insert line}
  832.                     for j:=24 downto wherey+1 do
  833.                       for i:= 1 to 80 do
  834.                         screenbuf[i,(j+screenptr) mod bufsize]:=
  835.                           screenbuf[i,(j-1+screenptr) mod bufsize];
  836.                     for i:= 1 to 80 do
  837.                       screenbuf[i,(wherey+screenptr) mod bufsize]:=space;
  838.                   end;
  839.           70    : facilities;                 {extended facilities}
  840.           76    : begin
  841.                     write(^J);                  {cursor down}
  842.                     if (wherey=24) then
  843.                       begin
  844.                         screenptr:=(screenptr+1) mod bufsize;
  845.                         for i:=1 to 80 do
  846.                           screenbuf[i,(24+screenptr) mod bufsize]:=space;
  847.                       end;
  848.                   end;
  849.           77    : if wherey>1 then gotoxy(wherex,wherey-1);    {cursor up}
  850.           78    : begin                       {blinking}
  851.                     textattr:=textattr or $80;
  852.                   end;
  853.           79    : begin;                      {non-blinking}
  854.                     textattr:=textattr and $7F;
  855.                   end;
  856.           80    : screen_dump;
  857.           82    : begin
  858.                     delline;                  {delete line}
  859.                     for j:=wherey to 23 do
  860.                       for i:= 1 to 80 do
  861.                         screenbuf[i,(j+screenptr) mod bufsize]:=
  862.                           screenbuf[i,(j-1+screenptr) mod bufsize];
  863.                     for i:= 1 to 80 do
  864.                       screenbuf[i,(24+screenptr) mod bufsize]:=space;
  865.                   end;
  866.           90    : begin
  867.                     gotoxy(1,1);              {cursor home}
  868.                     if ((screenbuf[wherex,(wherey+screenptr) mod bufsize]
  869.                       and $80)<>0) and not protmode then
  870.                       findunprot;
  871.                   end;
  872.           101   : begin                       {write a character n times}
  873.                     j:=cgetc(5);
  874.                     ch:=chr(cgetc(5));
  875.                     for i:=1 to j do
  876.                       Async_Stuff(ch);
  877.                   end;
  878.           112   : begin                       {clear field}
  879.                     x := wherex;
  880.                     y := wherey;
  881.                     while not (((screenbuf[wherex,(wherey+screenptr) mod bufsize]
  882.                       and $80)<>0) or (wherex=1) or
  883.                         ((wherex=80)and(wherey=24))) do
  884.                         begin
  885.                           screenbuf[wherex,(wherey+screenptr) mod bufsize]
  886.                             :=space;
  887.                           write(' ');
  888.                         end;
  889.                     gotoxy(x,y);
  890.                   end;
  891.         end;
  892.       end;
  893. end;
  894.  
  895.  
  896.  
  897. var
  898.   keystroke : char;
  899.   rcvd      : integer;
  900.   k         : integer;
  901.  
  902. begin {mufusion}
  903.   setup;
  904.   repeat
  905.     if keypressed then
  906.       begin
  907.         keystroke:=readkey;
  908.         if (keystroke = chr(0)) and keypressed then
  909.           begin
  910.             keystroke:=readkey;
  911.             case ord(keystroke) of
  912.               18 : toggle_emulation;                                 {Alt-E}
  913.               24 : shell_to_dos;                                     {Alt-O}
  914.               25 : begin                                             {Alt-P}
  915.                      if printer_on then flushprintbuf;
  916.                      printer_on := not printer_on;
  917.                    end;
  918.               32 : dial;                                             {Alt-D}
  919.               35 : hangup;
  920.               45 : end_now := true;
  921.               46 : toggle_capture;
  922.               59..68 : Async_Send_String_With_Delays(fkey[ord(keystroke)-58],10,10);   {F1-10}
  923.               73,110 : if emulation then backpage;                   {PgUp,alt-F7}
  924.               83 : Async_Send(chr(127));                             {Del}
  925.               84..93 : Async_Send_String_With_Delays(fkey[ord(keystroke)-73],10,10);   {shift F1-10}
  926.               104 : Async_Send(chr(27));                             {alt-F1}
  927.               105 : Async_Send(chr(28));                             {alt-F2}
  928.               106 : Async_Send(chr(30));                             {alt-F3}
  929.               107 : Async_Send(chr(29));                             {alt-F4}
  930.               108,109 : Async_Send(chr(0));                          {alt-F5,alt-F6}
  931.               112 : master_clear;                                    {alt-F9}
  932.             end;
  933.           end
  934.         else
  935.           begin
  936.             gen_cr:=true;
  937.             Async_Send(keystroke);
  938.             if auto_echo then Async_Stuff(keystroke);
  939.           end;
  940.       end;
  941.  
  942.     if not end_now
  943.       then
  944.         begin
  945.  
  946.           if sendbreak then
  947.             begin
  948.               Async_Send_Break;
  949.               sendbreak:=false;
  950.             end;
  951.  
  952.           if printscrn then
  953.             begin
  954.               screen_dump;
  955.               printscrn:=false;
  956.             end;
  957.  
  958.           rcvd := cgetc(0);
  959.  
  960.           if rcvd > 0 then
  961.             begin
  962.               if emulation then
  963.                 begin
  964.                   if new_line then
  965.                     begin
  966.                       if (rcvd in [10,32..126]) then
  967.                         begin
  968.                           write(^J);
  969.                           screenptr:=(screenptr+1) mod bufsize;
  970.                           for k:=1 to 80 do
  971.                             screenbuf[k,(24+screenptr) mod bufsize]:=space;
  972.                         end;
  973.                       if not (rcvd in [7,10,13]) then new_line:=false;
  974.                     end;
  975.  
  976.                   case rcvd of
  977.  
  978.                   32..126 : begin
  979.                               if protmode then
  980.                                 begin
  981.                                   screenbuf[wherex,(wherey+screenptr) mod
  982.                                     bufsize]:=ord(rcvd)+$80;
  983.                                 end
  984.                               else
  985.                                 begin
  986.                                   if ((screenbuf[wherex,(wherey+screenptr)
  987.                                     mod bufsize]and $80)<>0) then findunprot;
  988.                                   screenbuf[wherex,(wherey+screenptr) mod
  989.                                     bufsize]:=ord(rcvd);
  990.                                 end;
  991.                               if (wherex=80) and (wherey=24) then
  992.                                 begin
  993.                                   screenptr:=(screenptr+1) mod bufsize;
  994.                                   for k:=1 to 80 do
  995.                                     screenbuf[k,(24+screenptr)
  996.                                       mod bufsize]:=space;
  997.                                 end;
  998.                               write(chr(rcvd));
  999.                               if gen_cr and (not protmode) and
  1000.                                 ((screenbuf[wherex,(wherey+screenptr)
  1001.                                 mod bufsize] and $80)<>0) then
  1002.                                   Async_Send(chr(13));
  1003.                             end;
  1004.                    7      : begin                {bell}
  1005.                               sound(220);
  1006.                               delay(200);
  1007.                               nosound;
  1008.                             end;
  1009.                    8      : write(^H+' '+^H);    {back space destructive}
  1010.                   10      : if wherey<24 then    {line feed}
  1011.                               write(^J)
  1012.                             else
  1013.                               new_line:=true;
  1014.                   11      : begin                {vertical address lead-in}
  1015.                               k:=cgetc(5);
  1016.                               lastposx:=wherex;
  1017.                               lastposy:=wherey;
  1018.                               if k>0 then gotoxy(wherex,(k mod 32)+1);
  1019.                             end;
  1020.                   12,26   : master_clear;        {master clear}
  1021.                   13      : gotoxy(1,wherey);    {carriage return}
  1022.                   16      : begin                {horiz. address lead-in}
  1023.                               k:=cgetc(5);
  1024.                               lastposx:=wherex;
  1025.                               lastposy:=wherey;
  1026.                               gotoxy(k mod 16 + 10*(k div 16) +1,wherey);
  1027.                             end;
  1028.                   18      : printer_on:=true;    {printer on}
  1029.                   20      : begin                {printer off}
  1030.                               printer_on:=false;
  1031.                               flushprintbuf;
  1032.                             end;
  1033.                   27      : escape;              {escape}
  1034.  
  1035.                   end;
  1036.                   if (not protmode) and (rcvd<>13) and ((screenbuf[wherex,
  1037.                     (wherey+screenptr) mod bufsize] and $80)<>0)
  1038.                       then findunprot;
  1039.                   gen_cr:=false;
  1040.                 end
  1041.               else                                             {no emulation}
  1042.                 begin
  1043.                   while rcvd=13 do
  1044.                     begin                                      {drop the}
  1045.                       write(^M^J);                             {line feed}
  1046.                       rcvd:=cgetc(1);                          {after a}
  1047.                       if rcvd=10 then rcvd:=cgetc(1);          {carriage}
  1048.                     end;                                       {return}
  1049.                   case rcvd of
  1050.                     32..126 : write(chr(rcvd));                {printable}
  1051.                     11,16 : write('<',rcvd,'><',cgetc(5),'>'); {address leadin}
  1052.                     12 : write('<12>'+^M^J);                   {clear screen}
  1053.                     8  : if keystroke<>^H then write('<8>')
  1054.                            else write(^H+' '+^H);              {backspace}
  1055.                   else
  1056.                     if rcvd>0 then write('<',rcvd,'>');        {unprintable}
  1057.                   end;
  1058.                 end;
  1059.               end;
  1060.         end;
  1061.  
  1062.     thiskb_stat:=(kb_stat and $0F);
  1063.     if thiskb_stat<>lastkb_stat then display_statline;
  1064.     lastkb_stat:=thiskb_stat;
  1065.  
  1066.   until end_now;
  1067.  
  1068.   flushprintbuf;
  1069.   close(printer);
  1070.   if capture_on then close(capture);
  1071.   setintvec($05,saveint05);
  1072.   Async_Close(false);
  1073.   textbackground(0);
  1074.   textcolor(7);
  1075.   window(1,1,80,25);
  1076.   textmode(start_mode);
  1077.   clrscr;
  1078. end.
  1079.