home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / lxlt121s.zip / lxLite_src / common / MiscUtil.pas < prev    next >
Pascal/Delphi Source File  |  1997-03-09  |  29KB  |  991 lines

  1. {$A-,B-,D+,E-,F-,G+,I-,L+,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
  2. {&AlignCode-,AlignData-,AlignRec-,G3+,Speed-,Frame-}
  3. Unit miscUtil;
  4.  
  5. Interface uses use32;
  6.  
  7. const
  8. {$ifDef OS2}
  9.  tickerFreq             = 100;  {ticker frequence in 100000/Freq (1000)}
  10. {$else}
  11.  tickerFreq             = 5494; { = 100000/18.2 }
  12. {$endIf}
  13.  
  14. type
  15.  tByteArray      = array[0..65500] of Byte;
  16.  pByteArray      = ^tByteArray;
  17.  tWordArray      = array[0..32700] of Word;
  18.  pWordArray      = ^tWordArray;
  19.  tSmallWordArray = array[0..32700] of SmallWord;
  20.  pSmallWordArray = ^tSmallWordArray;
  21.  pWord16Array    = ^tWord16Array;
  22.  tWord16Array    = array[0..32700] of Word16;
  23.  tLongArray      = array[0..16380] of Longint;
  24.  pLongArray      = ^tLongArray;
  25.  tPointerArray   = array[0..16380] of Pointer;
  26.  pPointerArray   = ^tPointerArray;
  27.  tCharArray      = array[0..65500] of Char;
  28.  pCharArray      = ^tCharArray;
  29.  pByte           = ^Byte;
  30.  pWord           = ^Word;
  31.  pSmallWord      = ^SmallWord;
  32.  pWord16         = ^Word16;
  33.  pSmallInt       = ^SmallInt;
  34.  pInteger16      = ^Integer16;
  35.  pInteger        = ^Integer;
  36.  pLong           = ^Longint;
  37.  pInteger32      = ^Integer32;
  38.  pString         = ^String;
  39.  { Compare function for QuickSort. Return TRUE if Buff[N1] is 'greater    }
  40.  { or _EQUAL_' than Buff[N2]. If it will return simply 'less' or 'greater'}
  41.  { the function will cause a protection failure in the best case. If you  }
  42.  { use the QuickSort with CmpFunc, you don`t need to specify element size }
  43.  tCmpFunc        = Function(var Buff; N1,N2 : Word) : boolean;
  44.  { Procedure which exchanges element N1 with N2 in Buff for QuickSort     }
  45.  { Note that N1 and N2 in both cases are zero-based                       }
  46.  tXchgProc       = Procedure(var Buff; N1,N2 : Word);
  47.  
  48.  { tObject base object, stolen :-) from TurboVision }
  49.  pObject = ^tObject;
  50.  tObject = object
  51.   Constructor Create;
  52.   Procedure   Zero;
  53.   Procedure   Free; virtual;
  54.   Destructor  Destroy; virtual;
  55. {$ifDef OS2}
  56.  {Multi-thread support: detach an object.function(Parm : Pointer) : longint}
  57.   function    Detach(ObjFunc, Parm : Pointer; StackSize : Word; Ready : boolean) : Longint;
  58. {$endIf}
  59.  end;
  60.  
  61. { Dynamic string [de]allocation routines }
  62.  Function  NewStr(const S : String) : pString;
  63.  Procedure DisposeStr(P : PString);
  64. { Return interval in minutes between two events }
  65.  Function  TimeInterval(sYear,sMonth,sDay,sHour,sMin,
  66.                         fYear,fMonth,fDay,fHour,fMin : Word) : Longint;
  67.  
  68. { Quick sort routine. Element size must be one of 1,2,4 if cmpFunc is }
  69. { not provided (is nil) - the array will be sorted in usual way (i.e. }
  70. { from minimal to maximal value. If you use cmpFunc it`s also in your }
  71. { responsability to supply a valid xchgProc pointer.                  }
  72. { NOTE THAT BYTES, WORDS AND DWORDS WILL BE TREATED AS UNSIGNED VALUE }
  73. {$ifDef use32}
  74.  Procedure QuickSort(var Buff; First,Last : Word; ElementSize : Byte;
  75.                      cmpFunc : tCmpFunc; xchgProc : tXchgProc);
  76. {$endIf}
  77.  
  78. { Bit-manipulation routines }
  79. {&saves ebx,edx,esi,edi}
  80.  Function  bitTest(var bitArray; BitNo : Word) : boolean;
  81.  Procedure bitSet(var bitArray; BitNo : Word);
  82.  Procedure bitReset(var bitArray; BitNo : Word);
  83.  
  84. {Bit scan forward/reverse functions; return 255 if no set bits in A}
  85. {&saves all}
  86.  Function  BitSF(A : Longint) : Byte;
  87.  Function  BitSR(A : Longint) : Byte;
  88.  
  89. { Min/max functions }
  90. {&saves all}
  91.  Function  minL(A,B : Longint) : Longint;
  92. {$ifDef VirtualPascal}
  93.  Inline; begin if A <= B then minL := A else minL := B; end;
  94. {$endIf}
  95.  Function  maxL(A,B : Longint) : Longint;
  96. {$ifDef VirtualPascal}
  97.  Inline; begin if A >= B then maxL := A else maxL := B; end;
  98. {$endIf}
  99.  Function  minI(A,B : Integer) : Integer;
  100. {$ifDef VirtualPascal}
  101.  Inline; begin if A <= B then minI := A else minI := B; end;
  102. {$endIf}
  103.  Function  maxI(A,B : Integer) : Integer;
  104. {$ifDef VirtualPascal}
  105.  Inline; begin if A >= B then maxI := A else maxI := B; end;
  106. {$endIf}
  107.  
  108. { The same as System.Move but address always increments (i.e. CLD)   }
  109. { Use it ONLY when there is no possibility of overlapping A & B      }
  110. { or you intentionaly want to overlap them (i.e. in un/packers)      }
  111. { NOTE: IT DOES NOT OPTIMIZE MOVES BY DWORDS/WORDS: DONT CHANGE THIS }
  112. {&saves eax,ebx,edx,esi,edi}
  113.  Procedure linearMove(var A,B; Size : Word);
  114.  
  115. { Exchange bytes, words, double words and vars of any size }
  116. {&saves ebx,esi,edi}
  117.  Procedure XchgB(var A,B);
  118.  Procedure XchgW(var A,B);
  119.  Procedure XchgL(var A,B);
  120.  Procedure Xchg(var A,B; Size : Word);
  121.  
  122. { Compare two strings; return 0 if equal; positive if A>B and negative if A<B }
  123. {&saves ebx,edx,esi,edi}
  124.  Function  MemCmp(var A,B; Size : Word) : Shortint;
  125.  
  126. { Search buffer Buff of length BuffLen for a Target of given length TargetLen }
  127. {&saves ebx,esi,edi}
  128.  Function  Search(var Buff; BuffLen : Word; var Target; TargetLen : Word) : Word;
  129.  
  130. { Return number of "Value" bytes beginning from Buff to Buff+BuffLen }
  131. {&saves ebx,esi,edi}
  132.  Function MemScanFwd(var Buff; BuffLen : Word; Value : byte) : Word;
  133. { Return number of "Value" bytes beginning from Buff+BuffLen down to Buff }
  134. {&saves ebx,esi,edi}
  135.  Function MemScanBwd(var Buff; BuffLen : Word; Value : byte) : Word;
  136.  
  137. {$ifDef use32}
  138. {&saves ebx,esi,edi}
  139.  Function bTicker : Byte;
  140.  Function wTicker : Word;
  141.  Function lTicker : Longint;
  142. {$else use32}
  143.  Function bTicker : Byte;
  144.  InLine( $8E/$06/seg0040/   { mov   es,seg0040   }
  145.          $26/$A0/$6C/$00);  { mov   ax,es:[6Ch] }
  146.  Function wTicker : Word;
  147.  InLine( $8E/$06/seg0040/   { mov   es,seg0040   }
  148.          $26/$A1/$6C/$00);  { mov   ax,es:[6Ch] }
  149.  Function lTicker : Longint;
  150.  InLine( $8E/$06/seg0040/   { mov   es,seg0040   }
  151.          $26/$A1/$6C/$00/   { mov   ax,es:[6Ch] }
  152.          $26/$8B/$16/$6E/$00);{mov  dx,es:[6Eh] }
  153. {$endIf use32}
  154.  
  155. { Trick: call a embedded (ONLY level 2!) procedure }
  156. {&saves ebx,esi,edi}
  157.  Function level2call(Proc,Info : Pointer) : boolean;
  158.  
  159. Implementation {$ifDef os2} uses os2base; {$endIf}
  160.  
  161. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ High-level functions ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  162. constructor tObject.Create;
  163. begin
  164.  Zero;
  165. end;
  166.  
  167. procedure tObject.Zero;
  168. type Image = record
  169.       Link : Word;
  170.       Data : record end;
  171.      end;
  172. begin
  173.  FillChar(Image(Self).Data, SizeOf(Self) - SizeOf(TObject), 0);
  174. end;
  175.  
  176. {$ifDef OS2}
  177. type
  178.      pThreadParmBlock = ^tThreadParmBlock;
  179.      tThreadParmBlock = record
  180.       Func,Self,Parm : Pointer;
  181.      end;
  182.  
  183. function stubThread(ParmBlock : Pointer) : Longint; assembler;
  184. {&FRAME-} {&USES none} {&SAVES ebx,esi,edi}
  185. asm             mov    eax,ParmBlock
  186.                 push   [eax].tThreadParmBlock.Parm
  187.                 push   [eax].tThreadParmBlock.Self
  188.                 push   [eax].tThreadParmBlock.Func
  189.                 push   eax
  190.                 push   type tThreadParmBlock
  191.                 call   _MemFree
  192.                 pop    eax
  193.                 call   eax
  194. end;
  195.  
  196. function tObject.Detach;
  197. var
  198.  tpb : pThreadParmBlock;
  199.  tid : Longint;
  200. begin
  201.  New(tpb);
  202.  tpb^.Func := ObjFunc;
  203.  tpb^.Self := @Self;
  204.  tpb^.Parm := Parm;
  205.  tid := 0;
  206.  BeginThread(nil, StackSize, stubThread, tpb,
  207.   create_Suspended * byte(not Ready) + stack_Sparse, tid);
  208.  Detach := tid;
  209. end;
  210. {$endIf}
  211.  
  212. procedure tObject.Free;
  213. begin
  214. end;
  215.  
  216. destructor tObject.Destroy;
  217. begin
  218.  Free;
  219. end;
  220.  
  221. Function NewStr;
  222. var P : PString;
  223. begin
  224.  if S = ''
  225.   then P := nil
  226.   else begin
  227.         GetMem(P, succ(length(S)));
  228.         if P <> nil then P^ := S;
  229.        end;
  230.  NewStr := P;
  231. end;
  232.  
  233. Procedure DisposeStr;
  234. begin
  235.  if P <> NIL then FreeMem(p, succ(integer(length(p^))));
  236. end;
  237.  
  238. Function TimeInterval(sYear,sMonth,sDay,sHour,sMin,
  239.                       fYear,fMonth,fDay,fHour,fMin : Word) : Longint;
  240. const
  241.     daysInMonth      : array[1..12] of Byte =
  242.     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  243. var cY,cM,cD,cH,cMin : Word;
  244.     tI               : Longint;
  245.  
  246. procedure IncMonth;
  247. begin
  248.  Inc(cM);
  249.  if cM > 12 then begin cM := 1; Inc(cY); end;
  250. end;
  251.  
  252. procedure IncDay;
  253. begin
  254.  Inc(cD);
  255.  if cD > daysInMonth[cM] + byte((cM = 2) and (cY and 3 = 0))
  256.   then begin cD := 1; IncMonth; end;
  257. end;
  258.  
  259. procedure IncHour;
  260. begin
  261.  Inc(cH);
  262.  if cH > 23 then begin cH := 0; IncDay; end;
  263. end;
  264.  
  265. procedure IncMin;
  266. begin
  267.  Inc(cMin);
  268.  if cMin > 59 then begin cMin := 0; IncHour; end;
  269. end;
  270.  
  271. begin
  272.  cY := sYear; cM := sMonth; cD := sDay;
  273.  cH := sHour; cMin := sMin; tI := 0;
  274.  While (cY <> fYear) or (cM <> fMonth) or (cD <> fDay) or
  275.        (cH <> fHour) or (cMin <> fMin) do
  276.   begin
  277.    if (cY <> fYear) and (cM = 1) and (cD = 1) and (cH = 0) and (cMin = 0)
  278.     then begin
  279.           Inc(tI, longint(365 + byte(cY and 3 = 0)) * 1440);
  280.           Inc(cY);
  281.          end
  282.     else
  283.    if ((cY <> fYear) or (cM <> fMonth)) and (cD = 1) and (cH = 0) and (cMin = 0)
  284.     then begin
  285.           Inc(tI, longint(daysInMonth[cM] + byte((cM = 2) and (cY and 3 = 0))) * 1440);
  286.           IncMonth;
  287.          end
  288.     else
  289.    if ((cY <> fYear) or (cM <> fMonth) or (cD <> fDay)) and (cH = 0) and (cMin = 0)
  290.     then begin
  291.           Inc(tI, 1440); IncDay;
  292.          end
  293.     else
  294.    if ((cY <> fYear) or (cM <> fMonth) or (cD <> fDay) or (cH <> fHour)) and (cMin = 0)
  295.     then begin
  296.           Inc(tI, 60); IncHour;
  297.          end
  298.     else begin
  299.           Inc(tI); IncMin;
  300.          end;
  301.   end;
  302.  TimeInterval := tI;
  303. end;
  304.  
  305. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ Compiler-specific functions ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  306. {$ifDef use32}
  307.  
  308. Function lTicker : Longint;
  309. var L : Longint;
  310. begin
  311.  DosQuerySysInfo(qsv_Ms_Count, qsv_Ms_Count, L, SizeOf(L));
  312.  lTicker := L;
  313. end;
  314.  
  315. Function wTicker : Word;
  316. begin
  317.  wTicker := lTicker and $FFFF;
  318. end;
  319.  
  320. Function bTicker : Byte;
  321. begin
  322.  bTicker := lTicker and $FF;
  323. end;
  324.  
  325. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ Low-level functions ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  326. {&frame+,uses ebx,edi,esi}
  327. Procedure QuickSort; assembler;
  328. asm             mov     eax,First
  329.                 cmp     eax,Last
  330.                 jge     @@done
  331.                 push    eax
  332.                 push    Last
  333.                 push    offset @@done
  334.                 cmp     cmpFunc,0
  335.                 jne     @@qsAny
  336.                 mov     al,ElementSize
  337.                 cmp     al,1
  338.                 je      @@qsByte
  339.                 cmp     al,2
  340.                 je      @@qsWord
  341.                 cmp     al,4
  342.                 je      @@qsDWord               {For maximal speed}
  343.                 jmp     @@done3d
  344.  
  345. {*** Sort Buff as bytes ***}
  346. @@qsByte:       mov     esi,Buff
  347.                 mov     edi,esi
  348.                 mov     eax,[esp+8]             {First}
  349.                 mov     ecx,eax
  350.                 add     esi,eax
  351.                 mov     eax,[esp+4]             {Last}
  352.                 add     ecx,eax
  353.                 shr     ecx,1
  354.                 mov     bl,[edi+ecx]            {BL = Buff[(first+last)/2]}
  355.                 add     edi,eax
  356. @@repeat1b:     dec     esi
  357. @@loop1b:       inc     esi
  358.                 cmp     bl,[esi]
  359.                 ja      @@loop1b
  360.  
  361.                 inc     edi
  362. @@loop2b:       dec     edi
  363.                 cmp     bl,[edi]
  364.                 jb      @@loop2b
  365.  
  366.                 cmp     esi,edi
  367.                 ja      @@done2b
  368.                 je      @@done1b
  369.                 mov     al,[esi]
  370.                 xchg    al,[edi]
  371.                 mov     [esi],al
  372.                 inc     esi
  373.                 dec     edi
  374.                 jmp     @@repeat1b
  375. @@done1b:       inc     esi
  376.                 dec     edi
  377. @@done2b:       mov     eax,[esp+8]
  378.                 sub     edi,Buff
  379.                 jc      @@skip1b
  380.                 cmp     eax,edi
  381.                 jae     @@skip1b
  382.                 push    esi
  383.                 push    eax
  384.                 push    edi
  385.                 call    @@qsByte
  386.                 pop     esi
  387. @@skip1b:       sub     esi,Buff
  388.                 jc      @@skip2b
  389.                 mov     eax,[esp+4]
  390.                 cmp     esi,eax
  391.                 jae     @@skip2b
  392.                 push    esi
  393.                 push    eax
  394.                 call    @@qsByte
  395. @@skip2b:       ret     8
  396.  
  397. {*** Sort Buff as words ***}
  398. @@qsWord:       mov     esi,Buff
  399.                 mov     edi,esi
  400.                 mov     eax,[esp+8]             {First}
  401.                 mov     ecx,eax
  402.                 shl     eax,1
  403.                 add     esi,eax
  404.                 mov     eax,[esp+4]             {Last}
  405.                 add     ecx,eax
  406.                 shr     ecx,1
  407.                 mov     bx,[edi+ecx*2]          {BX = Buff[(first+last)/2]}
  408.                 shl     eax,1
  409.                 add     edi,eax
  410. @@repeat1w:     sub     esi,2
  411. @@loop1w:       add     esi,2
  412.                 cmp     bx,[esi]
  413.                 ja      @@loop1w
  414.  
  415.                 add     edi,2
  416. @@loop2w:       sub     edi,2
  417.                 cmp     bx,[edi]
  418.                 jb      @@loop2w
  419.  
  420.                 cmp     esi,edi
  421.                 ja      @@done2w
  422.                 je      @@done1w
  423.                 mov     ax,[esi]
  424.                 xchg    ax,[edi]
  425.                 mov     [esi],ax
  426.                 add     esi,2
  427.                 sub     edi,2
  428.                 jmp     @@repeat1w
  429. @@done1w:       add     esi,2
  430.                 sub     edi,2
  431. @@done2w:       mov     eax,[esp+8]
  432.                 sub     edi,Buff
  433.                 jc      @@skip1w
  434.                 shr     edi,1
  435.                 cmp     eax,edi
  436.                 jae     @@skip1w
  437.                 push    esi
  438.                 push    eax
  439.                 push    edi
  440.                 call    @@qsWord
  441.                 pop     esi
  442. @@skip1w:       sub     esi,Buff
  443.                 jc      @@skip2w
  444.                 shr     esi,1
  445.                 mov     eax,[esp+4]
  446.                 cmp     esi,eax
  447.                 jae     @@skip2w
  448.                 push    esi
  449.                 push    eax
  450.                 call    @@qsWord
  451. @@skip2w:       ret     8
  452.  
  453. {*** Sort Buff as dwords ***}
  454. @@qsDWord:      mov     esi,Buff
  455.                 mov     edi,esi
  456.                 mov     eax,[esp+8]             {First}
  457.                 mov     ecx,eax
  458.                 shl     eax,2
  459.                 add     esi,eax
  460.                 mov     eax,[esp+4]             {Last}
  461.                 add     ecx,eax
  462.                 shr     ecx,1
  463.                 mov     ebx,[edi+ecx*4]         {EBX = Buff[(first+last)/2]}
  464.                 shl     eax,2
  465.                 add     edi,eax
  466. @@repeat1d:     sub     esi,4
  467. @@loop1d:       add     esi,4
  468.                 cmp     ebx,[esi]
  469.                 ja      @@loop1d
  470.  
  471.                 add     edi,4
  472. @@loop2d:       sub     edi,4
  473.                 cmp     ebx,[edi]
  474.                 jb      @@loop2d
  475.  
  476.                 cmp     esi,edi
  477.                 ja      @@done2d
  478.                 je      @@done1d
  479.                 mov     eax,[esi]
  480.                 xchg    eax,[edi]
  481.                 mov     [esi],eax
  482.                 add     esi,4
  483.                 sub     edi,4
  484.                 jmp     @@repeat1d
  485. @@done1d:       add     esi,4
  486.                 sub     edi,4
  487. @@done2d:       mov     eax,[esp+8]
  488.                 sub     edi,Buff
  489.                 jc      @@skip1d
  490.                 shr     edi,2
  491.                 cmp     eax,edi
  492.                 jae     @@skip1d
  493.                 push    esi
  494.                 push    eax
  495.                 push    edi
  496.                 call    @@qsDWord
  497.                 pop     esi
  498. @@skip1d:       sub     esi,Buff
  499.                 jc      @@skip2d
  500.                 shr     esi,2
  501.                 mov     eax,[esp+4]
  502.                 cmp     esi,eax
  503.                 jae     @@skip2d
  504.                 push    esi
  505.                 push    eax
  506.                 call    @@qsDWord
  507. @@skip2d:       ret     8
  508.  
  509. {*** Sort Buff as any values ***}
  510. @@qsAny:        cmp     xchgProc,0
  511.                 je      @@done3d
  512.                 mov     esi,[esp+8]             {First}
  513.                 mov     ebx,esi
  514.                 mov     edi,[esp+4]             {Last}
  515.                 add     ebx,edi
  516.                 shr     ebx,1                   {EBX = (first+last)/2}
  517. @@repeat1a:     dec     esi
  518. @@loop1a:       inc     esi
  519.                 push    Buff
  520.                 push    esi
  521.                 push    ebx
  522.                 call    cmpFunc                 {Assume $SAVES ebx,esi,edi}
  523.                 test    al,al
  524.                 je      @@loop1a
  525.  
  526.                 inc     edi
  527. @@loop2a:       dec     edi
  528.                 push    Buff
  529.                 push    ebx
  530.                 push    edi
  531.                 call    cmpFunc                 {Assume $SAVES esi,edi}
  532.                 test    al,al
  533.                 je      @@loop2a
  534.  
  535.                 cmp     esi,edi
  536.                 ja      @@done2a
  537.                 je      @@done1a
  538.                 push    Buff
  539.                 push    esi
  540.                 push    edi
  541.                 call    xchgProc
  542.                 cmp     ebx,esi
  543.                 jne     @@xchg1a
  544.                 mov     ebx,edi
  545.                 jmp     @@xchg2a
  546. @@xchg1a:       cmp     ebx,edi
  547.                 jne     @@xchg2a
  548.                 mov     ebx,esi
  549. @@xchg2a:       inc     esi
  550.                 dec     edi
  551.                 jmp     @@repeat1a
  552. @@done1a:       inc     esi
  553.                 dec     edi
  554. @@done2a:       mov     eax,[esp+8]
  555.                 test    edi,edi
  556.                 js      @@skip1a
  557.                 cmp     eax,edi
  558.                 jae     @@skip1a
  559.                 push    esi
  560.                 push    eax
  561.                 push    edi
  562.                 call    @@qsAny
  563.                 pop     esi
  564. @@skip1a:       test    esi,esi
  565.                 js      @@skip2a
  566.                 mov     eax,[esp+4]
  567.                 cmp     esi,eax
  568.                 jae     @@skip2a
  569.                 push    esi
  570.                 push    eax
  571.                 call    @@qsAny
  572. @@skip2a:       ret     8
  573.  
  574. @@done3d:       add     esp,4+4+4
  575. @@done:
  576. end;
  577. {&frame-,uses none}
  578.  
  579. Function bitTest; assembler;
  580. asm             mov     eax,bitArray
  581.                 mov     ecx,bitNo
  582.                 bt      [eax],ecx
  583.                 setc    al
  584. end;
  585.  
  586. Procedure bitSet; assembler;
  587. asm             mov     eax,bitArray
  588.                 mov     ecx,bitNo
  589.                 bts     [eax],ecx
  590. end;
  591.  
  592. Procedure bitReset; assembler;
  593. asm             mov     eax,bitArray
  594.                 mov     ecx,bitNo
  595.                 btr     [eax],ecx
  596. end;
  597.  
  598. Procedure XchgB(var a,b); assembler;
  599. asm             mov     ecx,A
  600.                 mov     edx,B
  601.                 mov     al,[ecx]
  602.                 xchg    al,[edx]
  603.                 mov     [ecx],al
  604. end;
  605.  
  606. Procedure XchgW(var a,b); assembler;
  607. asm             mov     ecx,A
  608.                 mov     edx,B
  609.                 mov     ax,[ecx]
  610.                 xchg    ax,[edx]
  611.                 mov     [ecx],ax
  612. end;
  613.  
  614. Procedure XchgL; assembler;
  615. asm             mov     ecx,A
  616.                 mov     edx,B
  617.                 mov     eax,[ecx]
  618.                 xchg    eax,[edx]
  619.                 mov     [ecx],eax
  620. end;
  621.  
  622. {&uses ebx}
  623. Procedure Xchg(var A,B; Size : Word); assembler;
  624. asm             mov     ebx,A
  625.                 mov     edx,B
  626.                 mov     ecx,Size
  627. @@next:         mov     al,[ebx]
  628.                 xchg    al,[edx]
  629.                 mov     [ebx],al
  630.                 inc     ebx
  631.                 inc     edx
  632.                 loop    @@next
  633. end;
  634.  
  635. {&uses esi,edi}
  636. Procedure linearMove; assembler;
  637. asm             cld
  638.                 mov     esi,A
  639.                 mov     edi,B
  640.                 mov     ecx,Size
  641.                 rep     movsb
  642. end;
  643.  
  644. {&uses none}
  645. Function BitSF; assembler;
  646. asm             mov     eax,A
  647.                 bsf     eax,eax
  648.                 jnz     @@ok
  649.                 dec     al
  650. @@ok:
  651. end;
  652.  
  653. Function BitSR; assembler;
  654. asm             mov     eax,A
  655.                 bsr     eax,eax
  656.                 jnz     @@ok
  657.                 dec     al
  658. @@ok:
  659. end;
  660.  
  661. {&uses esi,edi}
  662. Function MemCmp; assembler;
  663. asm             cld
  664.                 mov    esi,A
  665.                 mov    edi,B
  666.                 mov    ecx,Size
  667.                 repe   cmpsb
  668.                 lahf
  669.                 mov    al,ah
  670.                 and    al,0C0h         {Dirty trick :)}
  671.                 xor    al,040h
  672. end;
  673.  
  674. {&uses esi,edi}
  675. Function Search; assembler;
  676. asm             cld
  677.                 mov     edi,Buff
  678.                 mov     ecx,BuffLen
  679.                 sub     ecx,TargetLen
  680.                 jbe     @@notFound
  681.                 inc     ecx
  682.                 mov     esi,Target
  683.                 mov     al,[esi]
  684. @@Scan:         repne   scasb
  685.                 jne     @@notFound
  686.                 push    ecx
  687.                 push    esi
  688.                 push    edi
  689.                 dec     edi
  690.                 mov     ecx,TargetLen[4+4+4]
  691.                 repe    cmpsb
  692.                 pop     edi
  693.                 pop     esi
  694.                 pop     ecx
  695.                 jne     @@Scan
  696.                 dec     edi
  697.                 sub     edi,Buff
  698.                 mov     eax,edi
  699.                 jmp     @@locEx
  700. @@notFound:     mov     eax,-1
  701. @@locEx:
  702. end;
  703.  
  704. {&uses none}
  705. function level2call(Proc,Info : Pointer) : boolean; assembler;
  706. asm             push    ebp
  707.                 mov     ebp,[ebp]
  708.                 push    Info[4]
  709.                 call    Proc[8]
  710.                 pop     ebp
  711. end;
  712.  
  713. {&uses edi}
  714. Function MemScanFwd; assembler;
  715. asm             cld
  716.                 mov     edi,Buff
  717.                 mov     ecx,BuffLen
  718.                 mov     al,Value
  719.                 repe    scasb
  720.                 setne   al
  721.                 movzx   eax,al
  722.                 sub     edi,eax
  723.                 sub     edi,Buff
  724.                 mov     eax,edi
  725. end;
  726.  
  727. {&uses edi}
  728. Function MemScanBwd; assembler;
  729. asm             std
  730.                 mov     edi,Buff
  731.                 mov     ecx,BuffLen
  732.                 jecxz   @@zeroLen
  733.                 lea     edi,[edi+ecx-1]
  734.                 mov     al,Value
  735.                 repe    scasb
  736.                 setnz   al
  737.                 movzx   eax,al
  738.                 add     edi,eax
  739.                 inc     edi
  740. @@zeroLen:      sub     edi,Buff
  741.                 mov     eax,BuffLen
  742.                 sub     eax,edi
  743.                 cld
  744. end;
  745. {&uses none}
  746. {$else ███████████ Implementation specific for Borland Pascal 7.0 ███████████}
  747.  
  748. Procedure bitSet; assembler;
  749. asm             les     di,bitArray
  750.                 mov     bx,bitNo
  751.                 cmp     test8086,2
  752.                 jb      @@8086
  753.                 db      $26,$0F,$AB,$1D {bts es:[di],bx}
  754.                 jmp     @@locEx
  755.  
  756. @@8086:         mov     cl,bl
  757.                 shr     bx,1
  758.                 shr     bx,1
  759.                 shr     bx,1
  760.                 and     cl,7
  761.                 mov     al,00000001b
  762.                 rol     al,cl
  763.                 or      es:[bx+di],al
  764. @@locEx:
  765. end;
  766.  
  767. Procedure bitReset; assembler;
  768. asm             les     di,bitArray
  769.                 mov     bx,bitNo
  770.                 cmp     test8086,2
  771.                 jb      @@8086
  772.                 db      $26,$0F,$B3,$1D {btr es:[di],bx}
  773.                 jmp     @@locEx
  774.  
  775. @@8086:         mov     cl,bl
  776.                 shr     bx,1
  777.                 shr     bx,1
  778.                 shr     bx,1
  779.                 and     cl,7
  780.                 mov     al,11111110b
  781.                 rol     al,cl
  782.                 and     es:[bx+di],al
  783. @@locEx:
  784. end;
  785.  
  786. Function bitTest; assembler;
  787. asm             les     di,bitArray
  788.                 mov     bx,bitNo
  789.                 cmp     test8086,2
  790.                 jb      @@8086
  791.                 db      $26,$0F,$A3,$1D {bt es:[di],bx}
  792.                 db      $0F,$92,$C0     {setc al}
  793.                 jmp     @@locEx
  794.  
  795. @@8086:         mov     cl,bl
  796.                 shr     bx,1
  797.                 shr     bx,1
  798.                 shr     bx,1
  799.                 and     cl,7
  800.                 mov     al,00000001b
  801.                 rol     al,cl
  802.                 test    es:[bx+di],al
  803.                 mov     al,0
  804.                 jz      @@locEx
  805.                 inc     al
  806. @@locEx:
  807. end;
  808.  
  809. Function bitSF; assembler;
  810. asm      db $66;mov     ax,A.word
  811.          db $66,$0F,$BC,$C0 {bsf eax,eax}
  812.                 jnz     @@ok
  813.                 dec     al
  814. @@ok:
  815. end;
  816.  
  817. Function bitSR; assembler;
  818. asm      db $66;mov     ax,A.word
  819.          db $66,$0F,$BD,$C0 {bsr eax,eax}
  820.                 jnz     @@ok
  821.                 dec     al
  822. @@ok:
  823. end;
  824.  
  825. Function MemCmp; assembler;
  826. asm             cld
  827.                 push    ds
  828.                 lds     si,A
  829.                 les     di,B
  830.                 mov     cx,Size
  831.                 repe    cmpsb
  832.                 pop     ds
  833.                 lahf
  834.                 mov     al,ah
  835.                 and     al,0C0h {Dirty trick :)}
  836.                 xor     al,040h
  837. end;
  838.  
  839. Function Search; assembler;
  840. asm             cld
  841.                 push    ds
  842.                 les     di,Buff
  843.                 mov     cx,BuffLen
  844.                 sub     cx,TargetLen
  845.                 jbe     @@NotFound
  846.                 inc     cx
  847.                 lds     si,Target
  848.                 mov     al,[si]
  849. @@Scan:         repne   scasb
  850.                 jne     @@NotFound
  851.                 push    cx
  852.                 push    si
  853.                 push    di
  854.                 dec     di
  855.                 mov     cx,TargetLen
  856.                 repe    cmpsb
  857.                 pop     di
  858.                 pop     si
  859.                 pop     cx
  860.                 jne     @@Scan
  861.                 dec     di
  862.                 sub     di,Buff.word
  863.                 mov     ax,di
  864.                 jmp     @@locEx
  865. @@NotFound:     mov     ax,-1
  866. @@locEx:        pop     ds
  867. end;
  868.  
  869. Procedure XchgB(var a,b); assembler;
  870. asm             push    ds
  871.                 les     di,a
  872.                 lds     si,b
  873.                 mov     al,es:[di]
  874.                 xchg    al,ds:[si]
  875.                 cld
  876.                 stosb
  877.                 pop     ds
  878. end;
  879.  
  880. Procedure XchgW(var a,b); assembler;
  881. asm             push    ds
  882.                 les     di,a
  883.                 lds     si,b
  884.                 mov     ax,es:[di]
  885.                 xchg    ax,ds:[si]
  886.                 cld
  887.                 stosw
  888.                 pop     ds
  889. end;
  890.  
  891. Procedure XchgL(var a,b); assembler;
  892. asm             push    ds
  893.                 les     di,a
  894.                 lds     si,b
  895.                 mov     ax,es:[di]
  896.                 xchg    ax,ds:[si]
  897.                 cld
  898.                 stosw
  899.                 mov     ax,es:[di]
  900.                 xchg    ax,ds:[si+2]
  901.                 stosw
  902.                 pop     ds
  903. end;
  904.  
  905. Procedure Xchg(var A,B; Size : Word); assembler;
  906. asm             push    ds
  907.                 lds     si,A
  908.                 les     di,B
  909.                 mov     cx,Size
  910. @@1:            mov     al,ds:[si]
  911.                 xchg    es:[di],al
  912.                 mov     ds:[si],al
  913.                 inc     si
  914.                 inc     di
  915.                 loop    @@1
  916.                 pop     ds
  917. end;
  918.  
  919. Procedure linearMove; assembler;
  920. asm             cld
  921.                 push    ds
  922.                 lds     si,A
  923.                 les     di,B
  924.                 mov     cx,Size
  925.                 rep     movsb
  926.                 pop     ds
  927. end;
  928.  
  929. Function  minL(A,B : Longint) : Longint;
  930. begin
  931.  if A <= B then minL := A else minL := B;
  932. end;
  933.  
  934. Function  maxL(A,B : Longint) : Longint;
  935. begin
  936.  if A >= B then maxL := A else maxL := B;
  937. end;
  938.  
  939. Function  minI;
  940. begin
  941.  if A <= B then minI := A else minI := B;
  942. end;
  943.  
  944. Function  maxI;
  945. begin
  946.  if A >= B then maxI := A else maxI := B;
  947. end;
  948.  
  949. function level2call(Proc,Info : Pointer) : boolean; assembler;
  950. asm             push    bp
  951.                 push    Info[2].word
  952.                 push    Info[0].word
  953.                 mov     bx,[bp]
  954.                 push    ss:[bx].word
  955.                 call    Proc
  956.                 pop     bp
  957. end;
  958.  
  959. Function MemScanFwd; assembler;
  960. asm             cld
  961.                 les     di,Buff
  962.                 mov     cx,BuffLen
  963.                 mov     al,Value
  964.                 repe    scasb
  965.                 je      @@1
  966.                 dec     di
  967. @@1:            sub     di,word ptr Buff
  968.                 mov     ax,di
  969. end;
  970.  
  971. Function MemScanBwd; assembler;
  972. asm             std
  973.                 les     di,Buff
  974.                 mov     cx,BuffLen
  975.                 add     di,cx
  976.                 dec     di
  977.                 mov     al,Value
  978.                 repe    scasb
  979.                 je      @@1
  980.                 inc     di
  981. @@1:            inc     di
  982.                 sub     di,word ptr Buff
  983.                 mov     ax,BuffLen
  984.                 sub     ax,di
  985.                 cld
  986. end;
  987. {$endIf ███████████████████ end of compiler - specific  section █████████████}
  988.  
  989. end.
  990.  
  991.