home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / bbs / rosuncr.arc / ROSUNCR.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-11  |  10KB  |  342 lines

  1. { ROSUNCR.PAS vers 1.0  17Dec87
  2.   by W. Brimhall  Z-Node 52  (602)996-8739
  3.  
  4.   This program adds Uncrunch support to a modified CP/M 80 ROS
  5.   vers 3.4 system. It must be compiled with the cHn option using
  6.   the same Start & End address as the main ROS program.
  7.  
  8.   The main ROS program passes parameters to ROSUNCR in these global
  9.   variables:
  10.  
  11.       name          type          desc
  12.       =========     ============  ==================================
  13.       in_library    boolean       true if library file open
  14.       libr_file     untyped file  file to uncrunch if in_library
  15.       XfrFile       untyped file  file to uncrunch if not in_library
  16.       SetDrv        integer       file area Drive
  17.       SetUsr        integer       file area User
  18.       HomDrv        integer       ROS.COM Drive
  19.       HomUsr        integer       ROS.COM User
  20.       remote_online boolean       true if online with remote system
  21.       local_online  boolean       true if online with local console
  22.       usr_rec       record        User data
  23.  
  24.   The file will be open and ready to access once the correct file area
  25.   is selected. If it is a LBR file it will be positioned to the record
  26.   containing the selected file member.
  27.  
  28.   The file is uncrunched and typed using UNCREL by Steven Greenberg. The
  29.   main ROS.COM program is then reexecuted.  This chained file scheme was
  30.   necessary because of the 24k buffer needed for UNCREL to operate.
  31.  
  32.   The main ROS program requires these modifications:
  33.    1) It must chain to ROSUNCR.CHN when a crunched file is specified
  34.       for the <T>ype command.
  35.    2) It must preserve the heap during the chain & execute.
  36.    3) It must go directly into file mode when it is executed by Turbo
  37.       Pascal instead of CP/M.
  38. }
  39.  
  40. program rosuncr;
  41. {$C-}
  42.  
  43. {****************************************}
  44. {* Global variables shared with ROS.COM *}
  45. {****************************************}
  46.  
  47.   {$I ROSDEF.INC}
  48.  
  49. {**************************************}
  50. {* Variables used by ROSUNCR.CHN only *}
  51. {**************************************}
  52.  
  53.   var
  54.     fbyte: byte;
  55.     x, BufferPtr, curin,
  56.     lastc, NoOfRecs, line_count, remaining: integer;
  57.     EndOFFile: Boolean;
  58.  
  59. {**************************}
  60. {* Machine dependent code *}
  61. {**************************}
  62.  
  63. { These file names should be changed to match your ROS hardware files. }
  64.  
  65.   {$I tdoswy60.MCH}                  { teminal and channel routines }
  66.   {$I courier.MDM}                   { Modem routines }
  67.   {$I tdos.CLK}                      { Clock routines }
  68.  
  69.  
  70. {******************************}
  71. {* Procedures from ROSKIO.INC *}
  72. {******************************}
  73.  
  74. function online: boolean;
  75. { Determine whether system is still online - local or remote }
  76.   begin
  77.     if remote_online
  78.       then if ch_carck
  79.              then online := TRUE
  80.              else
  81.                begin
  82.                  putstat('Carrier lost');
  83.                  mdhangup;
  84.                  remote_online := FALSE;
  85.                  online := FALSE
  86.                end
  87.       else online := local_online;
  88.   end;
  89.  
  90. Procedure PutChar(ch: char);
  91. { User written I/O driver to output character }
  92.   var
  93.     i: integer;
  94.   begin
  95.     if user_rec.shift_lock
  96.       then ch := UpCase(ch);
  97.     if printer_copy
  98.       then BDOS(5, ord(ch));
  99.     if online
  100.       then
  101.         begin
  102.           if (ch <> BEL) or local_online
  103.             then BDOS(6, ord(ch));
  104.           if remote_copy
  105.             then
  106.               begin
  107.                 ch_out($7F and ord(ch));
  108.                 if ch = CR
  109.                   then for i := 1 to user_rec.nulls do
  110.                     ch_out(ord(NUL));
  111.                 if ch = LF
  112.                   then for i := 1 to (user_rec.nulls shr 2) do
  113.                     ch_out(ord(NUL))
  114.               end
  115.         end
  116.   end;
  117.  
  118. function GetChar: char;
  119. { Get character: no wait, no echo }
  120.   var
  121.     ch: char;
  122.   begin
  123.     if keypressed
  124.       then
  125.         begin
  126.           read(KBD, ch);
  127.           if (not online) and (not (ch in [^C, LF, CR]))
  128.             then ch := NUL;
  129.           case ch of
  130.             ^W: begin
  131.                   op_chat := TRUE;
  132.                   ch := ' '
  133.                 end;
  134.             ^E: begin
  135.                   remote_copy := not remote_copy;
  136.                   if remote_copy
  137.                     then putstat('Remote copy on')
  138.                     else putstat('Remote copy off');
  139.                   ch := NUL
  140.                 end;
  141.             ^R: begin
  142.                   delay_down := not delay_down;
  143.                   if delay_down
  144.                     then putstat('Delayed shutdown on')
  145.                     else putstat('Delayed shutdown off');
  146.                   ch := NUL
  147.                 end;
  148.             ^T: begin
  149.                   remote_online := FALSE;
  150.                   mdhangup;
  151.                   ch := NUL
  152.                 end;
  153.             LF: begin
  154.                   if online
  155.                     then putstat('^W: CHAT, ^E: Remote copy on/off, ^R: Remote offline - delayed, ^T: Twit')
  156.                     else putstat('^C: Shutdown ROS, [C/R]: Local use');
  157.                   ch := NUL
  158.                 end
  159.           end
  160.         end
  161.     else if remote_online and remote_copy and ch_carck and ch_inprdy
  162.       then ch := chr($7F and ch_inp)
  163.       else ch := NUL;
  164.     GetChar := ch
  165.   end;
  166.  
  167. function brk: boolean;
  168. { Check for break or pause }
  169.   var
  170.     ch: char;
  171.   begin
  172.     ch := GetChar;
  173.     while ch = DC3 do                       { ^S }
  174.       repeat
  175.         ch := GetChar
  176.       until (not online) or (ch <> NUL);
  177.     brk := (not online) or (ch = ETX)       { ^C }
  178.   end;
  179.  
  180. procedure pause;
  181. { Pause for user response before continuing }
  182.   begin
  183.     Write(USR, 'Press any key to continue...');
  184.     if user_rec.noisy
  185.       then Write(USR, BEL);
  186.     repeat
  187.     until (not online) or (GetChar <> NUL);
  188.     Write(USR, CR, ' ':28, CR)
  189.   end;
  190.  
  191. {******************************}
  192. {* Procedures from ROSKMS.INC *}
  193. {******************************}
  194.  
  195. procedure SetSect(Drive, User: integer);
  196. { Set to file section }
  197.   begin
  198.     BDOS(seldrive, Drive);
  199.     BDOS(getseluser, User)
  200.   end;
  201.  
  202. {**********************************}
  203. {* New procedures for Uncrunching *}
  204. {**********************************}
  205.  
  206.   procedure uncrel;
  207.     begin
  208.       {$I UNCREL.INC}
  209.  
  210.       {UNCREL.INC must have following addresses patched in:
  211.  
  212.          byte          address
  213.          ----          -----------------
  214.          1+2            24k uncr buffer
  215.          7+8            getbyt routine
  216.          10+11          out routine
  217.  
  218.         The calling SP is stored at Uncrel+542h. To abort the uncrunch
  219.        procedure the in or out routine must restore the SP to this value
  220.        and execute a Z80 RET instruction.
  221.       }
  222.  
  223.   end;
  224.  
  225.   function getc: integer;
  226.   { Get an 8 bit value from the input buffer - read block if necessary }
  227.     begin
  228.       if BufferPtr > 128 then
  229.         begin
  230.           if in_library
  231.             then
  232.               {$I-} BlockRead(libr_file, Buffer, 1) {$I+}
  233.             else
  234.           {$I-} BlockRead(XfrFile, Buffer, 1) {$I+};
  235.           EndOfFile := (IOresult <> 0);
  236.           BufferPtr := 1
  237.         end;
  238.       getc := Buffer[BufferPtr];
  239.       BufferPtr := succ(BufferPtr)
  240.     end;
  241.  
  242.   procedure uncr_fname;
  243.   { Display uncrunched file name }
  244.     var
  245.       b: byte;
  246.     begin
  247.       write(USR,'      ===> ');
  248.       for i:= 1 to 2 do
  249.         b:=getc;                 { skip header bytes (76feh) }
  250.       while (b <> 0) do          { display uncrunched file name }
  251.         begin
  252.           write(USR,char(b));
  253.           b:=getc
  254.         end;
  255.       for b:=1 to 2 do
  256.         writeln(USR);
  257.       BufferPtr:=1;              { Reset pointer to start of file }
  258.       line_count:=3
  259.     end;
  260.  
  261.   procedure getbyte;
  262.     begin
  263.       if EndOFFile then { exit from Uncrel if premature eof }
  264.         begin
  265.           writeln(USR);
  266.           inline(
  267.             $ed/$7b/uncrel+$542/    { ld sp,(uncrel+542h) ;restore old sp }
  268.             $c9)              { ret }
  269.         end;
  270.       fbyte := getc;
  271.          end;
  272.  
  273.   procedure output;
  274.   { Output uncruched bytes to USR output driver. Filter clear screen
  275.     and form feed chars. Insert screen breaks & monitor for ^S and
  276.     ^C. }
  277.    begin
  278.      if (fbyte <> $1a) and (fbyte <> $0c) then
  279.        begin  { filter clear screen & form feed chars }
  280.           write(USR,char(fbyte));
  281.             if (user_rec.lines <> 99) and (char(fbyte) = LF) then
  282.               begin
  283.                 line_count := succ(line_count);
  284.                 if line_count mod user_rec.lines = 0
  285.                   then pause
  286.               end;
  287.        end;
  288.      if brk then { Exit Uncrel if ^C is entered }
  289.        begin
  290.          writeln(USR);
  291.          inline(
  292.            $ed/$7b/uncrel+$542/    { ld sp,(uncrel+542h) ;restore old sp }
  293.            $c9)              { ret }
  294.        end;
  295.    end;
  296.  
  297.   procedure getbyt;
  298.     begin
  299.       inline(
  300.         $cd/getbyte/  {call getbyte}
  301.         $3a/fbyte    {ld a,(fbyte)}
  302.       );
  303.     end;
  304.  
  305.   procedure out;
  306.     begin
  307.       inline(
  308.         $32/fbyte/    {ld (fbyte),a}
  309.         $cd/output   {call output}
  310.       );
  311.     end;
  312.  
  313. procedure patch;
  314. { Patch UNCREL I/O addresses and set 24k buffer to 3800h }
  315.   begin
  316.     mem[addr(uncrel)+1]:=$00;
  317.     mem[addr(uncrel)+2]:=$38;
  318.     {Set address of getbyt & out routines}
  319.     mem[addr(uncrel)+7]:=addr(getbyt) mod 256;
  320.     mem[addr(uncrel)+8]:=addr(getbyt) div 256;
  321.     mem[addr(uncrel)+10]:=addr(out) mod 256;
  322.     mem[addr(uncrel)+11]:=addr(out) div 256;
  323.   end;
  324.  
  325. {*****************}
  326. {* Main  program *}
  327. {*****************}
  328.  
  329.   begin
  330.     UsrOutPtr:=addr(putchar);      { Reassign USR: to ROS output driver }
  331.     BufferPtr := MaxInt;           { Force a file read }
  332.     patch;                         { Patch UNCREL addresses }
  333.     SetSect(SetDrv,SetUsr);        { Select DU: of file area }
  334.     uncr_fname;                    { Display uncrunched file name }
  335.     uncrel;                        { Uncrunch & type the file }
  336.     if not in_library then         { Close the file if not in LBR }
  337.       close (XfrFile);
  338.     SetSect(HomDrv,HomUsr);        { Select DU: of ROS.COM }
  339.     assign(chain_file,'ROS.COM');
  340.     execute(chain_file);           { Reexecute ROS.COM }
  341.   end.
  342.