home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug184.arc / ROS34.LBR / ROSKMS.IZC / ROSKMS.INC
Text File  |  1979-12-31  |  10KB  |  329 lines

  1. { ROSKMS.INC - Remote Operating System Kernel - Miscellaneous routines }
  2.  
  3. procedure SetSect(Drive, User: integer);
  4. { Set to file section }
  5.   begin
  6.     BDOS(seldrive, Drive);
  7.     BDOS(getseluser, User)
  8.   end;
  9.  
  10. procedure FindSect(req: FileName; var Drive, User: integer; var found: boolean);
  11. { Find file section from requested name }
  12.   var
  13.     this: SectPtr;
  14.   begin
  15.     this := SectBase;
  16.     while (req <> this^.SectName) and (this <> nil) do
  17.       this := this^.next;
  18.     found := ((req = this^.SectName) and (cold or (user_rec.access >= this^.SectAccs)));
  19.     if found
  20.       then
  21.         begin
  22.           Drive := this^.SectDrive;
  23.           User := this^.SectUser
  24.         end
  25.   end;
  26.  
  27. function diskfree: integer;
  28. { Compute amount of disk space free on current drive }
  29.   type
  30.     param =
  31.       record
  32.         spt: integer;
  33.         bsh, blm, exm: byte;
  34.         dsm, drm, al, cks, off: integer
  35.       end;
  36.   var
  37.     allocptr, reserved, blocksize, disksize, i: integer;
  38.     dpbptr: ^param;
  39.   begin
  40.     allocptr := BDOSHL(getallocvec, 0);
  41.     dpbptr   := ptr(BDOSHL(getdiskparm, 0));
  42.     with dpbptr^ do
  43.       begin
  44.         reserved := 0;
  45.         for i := 0 to 15 do
  46.           reserved := reserved + (al shr i) and 1;
  47.         disksize := succ(dsm) - reserved;
  48.         for i := reserved to dsm do
  49.           disksize := disksize - (((mem[allocptr + i shr 3] shl (i mod 8)) and $80) shr 7);
  50.         blocksize := 1 shl (bsh - 3)
  51.       end;
  52.     diskfree := disksize * blocksize
  53.   end;
  54.  
  55. procedure hide_release(name: FileName; status: record_status);
  56. { Hide or release file }
  57.   var
  58.     i: integer;
  59.     temp_file: file;
  60.   begin
  61.     Assign(temp_file, name);
  62.     i := pos('.', name) + 2;
  63.     if status = public
  64.       then name[i] := chr($7F and ord(name[i]))  { Turn $SYS bit off }
  65.       else name[i] := chr($80 or ord(name[i]));  { Turn $SYS bit on }
  66.     {$I-} Rename(temp_file, name) {$I+};
  67.     if IOresult <> 0
  68.       then writeln(USR, name, ' not found.')
  69.   end;
  70.  
  71. function min(x, y: integer): integer;
  72. { Return minimum of two integers }
  73.   begin
  74.     if x < y
  75.       then min := x
  76.       else min := y
  77.   end;
  78.  
  79. function max(x, y: integer): integer;
  80. { Return greater of two integers }
  81.   begin
  82.     if x > y
  83.       then max := x
  84.       else max := y
  85.   end;
  86.  
  87. function trim(st: StrStd): StrStd;
  88. { Remove leading and trailing blanks }
  89.   var
  90.    i, j: integer;
  91.   begin
  92.     i := 1;
  93.     j := length(st);
  94.     while (st[i] = ' ') and (i <= j) do
  95.       i := succ(i);
  96.     while (st[j] = ' ') and (j >= i) do
  97.       j := pred(j);
  98.     trim := copy(st, i, succ(j - i))
  99.   end;
  100.  
  101. function pad(st: StrStd; i: integer): StrStd;
  102. { Pad string with spaces to length of i }
  103.   begin
  104.     while length(st) < i do
  105.       st := st + ' ';
  106.     pad := st
  107.   end;
  108.  
  109. function intstr(n, w: integer): Str10;
  110. { Return a string value (width 'w')for the input integer ('n') }
  111.   var
  112.     st: Str10;
  113.   begin
  114.     str(n:w, st);
  115.     intstr := st
  116.   end;
  117.  
  118. function strint(st: Str10): integer;
  119. { Convert string to integer }
  120.   var
  121.     x, code: integer;
  122.   begin
  123.     if st[1] = '+'
  124.       then delete(st, 1, 1);
  125.     if st = ''
  126.       then code := 1
  127.       else val(st, x, code);
  128.     if code = 0
  129.       then strint := x
  130.       else strint := 0                      { Error, return with 0 }
  131.   end;
  132.  
  133. function zeller(day, month, year: integer): integer;
  134. { Compute the day of the week using Zeller's Congruence }
  135.   var
  136.     century: integer;
  137.   begin
  138.     if month > 2
  139.       then month := month - 2
  140.       else
  141.         begin
  142.           month := month + 10;
  143.           year := pred(year)
  144.         end;
  145.     century := year div 100;
  146.     year := year mod 100;
  147.     zeller := (day - 1 + ((13 * month - 1) div 5) + (5 * year div 4) +
  148.               century div 4 - 2 * century + 1) mod 7
  149.   end;
  150.  
  151. function FormTAD(t: tad_array): StrTAD;
  152. { Build printable string of current time and date }
  153.   const
  154.     day: array [0..6] of string[6] =
  155.       ('Sun','Mon','Tues','Wednes','Thurs','Fri','Satur');
  156.     month: array [1..12] of string[3] =
  157.       ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  158.   var
  159.     i: integer;
  160.     line: StrTAD;
  161.   begin
  162.     if (t[1] in [0..59]) and (t[2] in [0..23])
  163.       then line := intstr(t[2], 2) + ':' + intstr(t[1], 2)
  164.       else line := '';
  165.     for i:= 1 to length(line) do
  166.       if line[i] = ' '
  167.         then line[i]:= '0';
  168.     if (t[3] in [1..31]) and (t[4] in [1..12]) and (t[5] in [0..99])
  169.       then FormTAD :=
  170.         line + '  ' +
  171.         day[zeller(t[3], t[4], 1900 + t[5])] + 'day  ' +
  172.         intstr(t[3], 2) + '-' + month[t[4]] + '-' + intstr(t[5], 2)
  173.       else FormTAD := 'No Date'
  174.   end;
  175.  
  176. procedure send_time(size: integer; var mm, ss: integer);
  177. { Compute the file transfer time }
  178.   var
  179.     tr_time: real;
  180.   begin
  181.     tr_time := size * 23.5 / rate;          { Factor is empirically derived  }
  182.     mm := trunc(tr_time);
  183.     ss := round(60.0 * frac(tr_time))
  184.   end;
  185.  
  186. procedure timer(var time_on, time_left: integer);
  187. { Compute the time on and the time remaining to the current user }
  188.   var
  189.     t: tad_array;
  190.   begin
  191.     GetTAD(t);
  192.     time_on := 60 * (t[2] - login_t[2]) + t[1] - login_t[1];
  193.     if time_on < 0
  194.       then time_on := time_on + 1440;
  195.     time_left := user_rec.limit + extra_time - time_on
  196.   end;
  197.  
  198. procedure log(activity: byte; text: FileName);
  199. { Update log file }
  200.   begin
  201.     seek(logr_file, FileSize(logr_file));
  202.     GetTAD(logr_rec.date);
  203.     logr_rec.action := activity;
  204.     logr_rec.user := user_loc;
  205.     logr_rec.text := text;
  206.     write(logr_file, logr_rec)
  207.   end;
  208.  
  209. procedure mesg_insert(TypMsg: byte);
  210. { Insert message into linked list }
  211.   var
  212.     this: MesgPtr;
  213.   begin
  214.     new(this);
  215.     if MesgBase = nil
  216.       then MesgBase := this
  217.       else MesgLast^.next := this;
  218.     MesgLast := this;
  219.     MesgLast^.MesgNo := summ_rec.num;
  220.     MesgLast^.SummLoc := pred(FilePos(summ_file));
  221.     MesgLast^.TypMsg := TypMsg;
  222.     MesgLast^.next := nil
  223.   end;
  224.  
  225. procedure InsertFile(fname: name_array; index, size: integer;
  226.                      var entries, total: integer; var first: FilePtr);
  227. { Insert a new file name into an alphabetic list }
  228.   var
  229.     space: integer;
  230.     f,                                      { File name entry being created }
  231.     this, last: FilePtr;                    { Followers for insertion }
  232.     fn: FileName;
  233.   begin
  234.     fn := '           ';                    { Initialize string }
  235.     move(fname, fn[1], 11);                 { Move name into place }
  236.     insert('.', fn, 9);
  237.     last := nil;
  238.     this := first;
  239.     while (this <> nil) and (this^.fname < fn) do
  240.       begin
  241.         last := this;
  242.         this := this^.next
  243.       end;
  244.     space := size shr 3;
  245.     if (size mod 8) <> 0
  246.       then space := succ(space);
  247.     if this^.fname <> fn
  248.       then
  249.         begin
  250.           entries := succ(entries);
  251.           total := total + space;
  252.           new(f);
  253.           f^.fname := fn;
  254.           f^.index := index;
  255.           f^.fsize := size;
  256.           f^.next  := this;
  257.           if last = nil
  258.             then first := f
  259.             else last^.next := f
  260.         end
  261.     else if (this^.fname = fn) and (this^.fsize < size)
  262.       then
  263.         begin
  264.           total := total + space;
  265.           space := this^.fsize shr 3;
  266.           if (this^.fsize mod 8) <> 0
  267.             then space := succ(space);
  268.           total := total - space;
  269.           this^.fsize := size
  270.         end
  271.   end;
  272.  
  273. { Notes on updcrc:
  274.  
  275.    Purists that want ROS to be written COMPLETELY in Pascal, should use the
  276.    Pascal version, but it is slower than the inline code version.  The inline
  277.    code version is, of course, Z-80 specific, but it is MUCH faster.
  278.  
  279.    The two procedures are functionally equivalent - simply comment out the
  280.    procedure you don't want to use.
  281. }
  282.  
  283. (*
  284. procedure updcrc(var crc: integer; acc: integer);
  285. { Update CRC with passed value }
  286.     var
  287.       carry: boolean;
  288.       i: integer;
  289.     begin
  290.       for i := 1 to 8 do
  291.         begin
  292.           carry := ((crc and $8000) <> 0);
  293.           crc := crc shl 1;
  294.           if (acc and $0080) <> 0
  295.             then crc := succ(crc);
  296.           acc := acc shl 1;
  297.           if carry
  298.             then crc := crc xor $1021       { Use $8005 for CRC-16 }
  299.         end
  300.     end;
  301. *)
  302.  
  303. procedure updcrc(var crc: integer; acc: integer);
  304. { Update CRC with passed value }
  305.   begin
  306.     inline($2A/crc/       {         LD      HL,(crc)    ; point to crc    }
  307.            $5E/           {         LD      E,(HL)      ; put crc into DE }
  308.            $23/           {         INC     HL          ;                 }
  309.            $56/           {         LD      D,(HL)      ;                 }
  310.            $EB/           {         EX      DE,HL       ; put it into HL  }
  311.            $ED/$4B/acc/   {         LD      BC,(acc)    ; get acc into C  }
  312.            $06/$08/       {         LD      B,8         ; shift 8 times   }
  313.            $CB/$01/       { UPDLP:  RLC     C           ; shift input     }
  314.            $ED/$6A/       {         ADC     HL,HL       ; shift crc       }
  315.            $30/$08/       {         JR      NC,SKIPIT   ; jump if no carry}
  316.            $7C/           {         LD      A,H         ; xor with $1021  }
  317.            $EE/$10/       {         XOR     10H         ; use $8005 for   }
  318.            $67/           {         LD      H,A         ;   CRC-16        }
  319.            $7D/           {         LD      A,L         ;                 }
  320.            $EE/$21/       {         XOR     21H         ;                 }
  321.            $6F/           {         LD      L,A         ;                 }
  322.            $10/$F0/       { SKIPIT: DJNZ    UPDLP       ; done?           }
  323.            $EB/           {         EX      DE,HL       ; result to DE    }
  324.            $72/           {         LD      (HL),E      ; then into       }
  325.            $2B/           {         DEC     HL          ;   into          }
  326.            $73)           {         LD      (HL),D      ;     memory      }
  327. end;
  328.  
  329.