home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / multtsk / multi / multi.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1993-02-27  |  4.6 KB  |  220 lines

  1. {$G-}
  2.  
  3. {$IFDEF DPMI}
  4.  {$C FIXED PRELOAD PERMANENT}
  5. {$ENDIF}
  6.  
  7. {*
  8. * ┌───────────────────────────────────────────────────────────────┐
  9. * │ Multi.PAS  Version 1.00                                       │
  10. * │                                                               │
  11. * │ Dos Multi Threader unit for Turbo pascal                      │
  12. * │                                                               │
  13. * │ Copyright (c) 1993 by Bill McKee, all rights reserved.        │
  14. * └───────────────────────────────────────────────────────────────┘
  15. *
  16. *
  17. *
  18. *
  19. *  Registration and payment of a license fee is required for any use, whether
  20. *  in whole or part, of this source code.
  21. *
  22. *}
  23.  
  24. Unit Multi;
  25.  
  26.   Interface
  27.    Type
  28.        YieldProcType = procedure;
  29.  
  30.    Procedure MakeTask(ProcAddr : Pointer ; StackSize : Word);
  31.  
  32.    Procedure Wait(n : Longint);Far;
  33.  
  34.    Procedure DummyYield;
  35.  
  36.    Procedure Start;
  37.  
  38.  
  39.   Var
  40.      ActiveTasks : Integer;
  41.   Const
  42.      TicksNow        : ^longint = ptr($40,$6c);
  43.      Yield : YieldProcType = DummyYield;
  44.  
  45.   Implementation
  46.    Uses
  47.        Memory;
  48.  
  49.    Const
  50.         MaxTasks = 24;
  51.    var
  52.         CurrentTask     : Integer;
  53.         Task            : array[1..MaxTasks] of Pointer;
  54.         Dispatcher,main : Pointer;
  55.  
  56.    Procedure DummyYield;
  57.    begin
  58.    end;
  59.  
  60.    Procedure newprocess( Var task : Pointer; ProcAddr : Pointer; stacka : Pointer; stacksize : word);
  61.    var
  62.       Temp         : Pointer;
  63.       tw,nss,nsp   : Word;
  64.  
  65.    begin
  66.  
  67.       fillchar(stacka^,StackSize,$00);
  68.  
  69. {$ifdef StonyBrook}
  70.       task  := ptr(seg(stacka^),Stacksize-30);
  71. {$else}
  72.       task  := ptr(seg(stacka^),Stacksize-16);
  73. {$endif}
  74.       temp  := ptr(seg(stacka^),Stacksize-12);
  75.  
  76.       move(procaddr,temp^,4);
  77.       nss   := seg(stacka^);
  78.       nsp   := StackSize-14;
  79.       asm
  80.         mov   cx,ss
  81.         mov   dx,sp
  82.         mov   ax,nss
  83.         mov   bx,nsp
  84.         cli
  85.         mov   ss,ax
  86.         mov   sp,bx
  87.         sti
  88. {$ifdef StonyBrook}
  89.         push  ax
  90.         push  bx
  91.         push  cx
  92.         push  dx
  93.         push  es
  94.         push  si
  95.         push  di
  96. {$endif}
  97.         Pushf
  98.         cli
  99.         mov   ss,cx
  100.         mov   sp,dx
  101.         sti
  102.       end;
  103.    end;
  104.  
  105.    Procedure Wait(n : Longint);
  106.    Var
  107.       LastTicks : Longint;
  108.       NowTicks  : Longint;
  109.    begin
  110.       LastTicks := TicksNow^ ;
  111.       Repeat
  112.        Yield;
  113.        NowTicks := TicksNow^ ;
  114.        if LastTicks <> NowTicks then begin
  115.          if LastTicks<NowTicks then
  116.            Dec(n,NowTicks-LastTicks)
  117.          else
  118.            Dec(n,NowTicks);  {TickNow^ is reset to zero at midnight}
  119.          if n<=0 then exit;
  120.          LastTicks := NowTicks;
  121.        end;
  122.       Until False;
  123.    end;
  124.  
  125.    Procedure NewTask(ProcAddr : Pointer; Stacka : Pointer; StackSize : Word);
  126.    begin
  127.       inc(activeTasks);
  128.       newProcess(task[activeTasks],procaddr,stacka,Stacksize);
  129.    end;
  130.  
  131.    Procedure MakeTask(ProcAddr : Pointer; StackSize : Word);
  132.    Var p  : Pointer;
  133.    begin
  134.      p := memAllocSeg(StackSize);
  135.      if p = nil then Halt(8);
  136.      newTask(ProcAddr , p , StackSize);
  137.    end;
  138.  
  139. {$S-,R-}
  140.    Procedure Transfer( Var op,np : Pointer);Far;
  141.    begin
  142.      asm
  143. {$ifdef StonyBrook}
  144.        push  ax
  145.        push  bx
  146.        push  cx
  147.        push  dx
  148.        push  es
  149.        push  si
  150.        push  di
  151. {$endif}
  152.        Pushf
  153.        les   di,[bp+10]
  154.        mov   es:[di],sp
  155.        mov   es:[di+2],ss
  156.        les   di,[bp+6]
  157.      end;
  158.  
  159. {$ifdef DPMI}
  160.     inline(
  161.        $26/$0F/$B2/$25   {  lss   sp,es:[di] }
  162.        );
  163. {$else}
  164.      asm
  165.        cli
  166.        mov   sp,es:[di]
  167.        mov   ss,es:[di+2]
  168.      end;
  169. {$endif}
  170.  
  171.      asm
  172.        popf
  173. {$ifdef StonyBrook}
  174.        pop   di
  175.        pop   si
  176.        pop   es
  177.        pop   dx
  178.        pop   cx
  179.        pop   bx
  180.        pop   ax
  181. {$endif}
  182.      end;
  183.    end;
  184.  
  185.    Procedure RealYield; Far;
  186.    begin
  187.      Transfer(Task[currentTask],dispatcher);
  188.    end;
  189.  
  190.    Procedure dispatcherTask; Far;
  191.    begin
  192.       CurrentTask := 1;
  193.       Repeat
  194.         transfer(dispatcher,task[currentTask]);
  195.         inc(CurrentTask);
  196.         if CurrentTask  > ActiveTasks then CurrentTask := 1;
  197.       Until false;
  198.    end;
  199.  
  200.    Procedure Start;
  201.    Var p : Pointer;
  202.    begin
  203.      yield := RealYield;
  204.      p := memAllocSeg(2048);
  205.      if p = nil then halt(8);
  206.      newprocess(dispatcher,@dispatcherTask,p,2048);
  207.      transfer(main,dispatcher);
  208.    end;
  209.  
  210.    Function HeapFunc(Size : Word): Integer;  FAR;
  211.      begin
  212.        HeapFunc := 1;
  213.      end;
  214.  
  215.  
  216. begin
  217.      TicksNow    := ptr(Seg0040,$6C);
  218.      ActiveTasks := 0;
  219.      HeapError := @HeapFunc;   { Add a heap function so errors return nil  }
  220. end.