home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / LASER / FPC35_5.ZIP / FPCSRC.ZIP / MULTASK.SEQ < prev    next >
Encoding:
Text File  |  1989-09-21  |  5.9 KB  |  156 lines

  1. \ MULTASK.SEQ   Multi tasking code for Forth.
  2.  
  3. PREFIX
  4.  
  5. ONLY FORTH ALSO DEFINITIONS
  6.  
  7. DECIMAL
  8.  
  9. comment:
  10.  
  11.   The MultiTasker is loaded as an application on top of the
  12. regular Forth System.  There is support for it in the nucleus
  13. in the form of USER variables and PAUSEs inserted inside of
  14. KEY EMIT and BLOCK.  The Forth multitasking scheme is
  15. co-operative instead of interruptive.  All IO operations cause
  16. a PAUSE to occur, and the multitasking loop looks around at
  17. all of the current task for something to do.
  18.  
  19.   Modified by Tom Zimmer to work with F-PC, which needs to save the ES
  20. register along with IP. - 2/29/88 -
  21.  
  22. NOTICE !!       This multi tasking DOES NOT SUPPORT MULTIPLE USERS !!!
  23.  
  24.   There are a significant number of things what will have to be changed
  25. in this Forth system to support multi user, like the editor would have
  26. to be re-written, ect.  So I am not supporting multi user, only
  27. background processing.
  28.  
  29.   Background processing MAY NOT do any compiling, compile, like VARIABLE,
  30. or CREATE, ect. at *** RUNTIME ***.                     06/06/88 13:58
  31.  
  32.   YDP and XDP are NOT user variables.
  33.  
  34. comment;
  35.  
  36. CODE (PAUSE)    ( -- )
  37.                 PUSH ES         \ Push ES, IP, and RP
  38.                 PUSH IP
  39.                 PUSH RP
  40.                 MOV BX, UP      \ make BX point to user area
  41.                 MOV 0 [BX], SP  \ save SP in user area offset 0
  42.                 ADD BX, # 4     \ adjust BX to point to LINK
  43.                 ADD BX, 0 [BX]  \ Add value in LINK to BX, pointing it to
  44.                                 \ next tasks user area offset 0
  45.                 ADD BX, # 2     \ bump BX 2 to point to ENTRY
  46.                 JMP BX          \ jump to next tasks entry point
  47.                 END-CODE
  48.  
  49. CODE RESTART    ( -- )
  50.                 POP BX          \ pop address of where we came from
  51.                 MOV AX, # -4
  52.                 ADD BX, AX      \ adjust to beginning of user area
  53.                 MOV UP BX       \ set UP to point to begin of user area
  54.                 POP AX          \ pop off old PC
  55.                 POPF            \ restore status register
  56.                 MOV SP, 0 [BX]  \ restore SP (stack pointer)
  57.                 POP RP          \ restore RP, IP, and ES
  58.                 POP IP
  59.                 POP ES
  60.                 NEXT            END-CODE
  61.  
  62. $0E9 CONSTANT INT#
  63.  
  64. : LOCAL         ( base addr -- addr' )   UP @ -   +   ;
  65. : @LINK         ( -- addr ) LINK DUP @ +   2+   ;
  66. : !LINK         ( addr -- ) LINK 2+ -   LINK !   ;
  67. : SLEEP         ( addr -- ) $0E990 SWAP ENTRY LOCAL !   ;
  68. : WAKE          ( addr -- ) $0E9CD SWAP ENTRY LOCAL !   ;
  69. : STOP          ( -- )      UP @ SLEEP   PAUSE   ;
  70. : SINGLE        ( -- )
  71.                 $0E9  ['] PAUSE C!              \ set JMP in PAUSE
  72.                 >NEXT ['] PAUSE >BODY -         \ get offset to NEXT
  73.                       ['] PAUSE 1+ ! ;          \ store in PAUSE + 1
  74.  
  75. CODE MULTI      ( -- )
  76.                 MOV ' PAUSE # $0E9
  77.                 MOV BX, # ' (PAUSE) ' PAUSE 3 + -       \ relative I hope!
  78.                 MOV ' PAUSE 1+ BX
  79.                 MOV BX, # ' RESTART
  80.                 MOV AX, DS
  81.                 PUSH AX
  82.                 SUB AX, AX      MOV DS, AX
  83.                 MOV AX, CS      MOV INT# 4 * 2+ AX
  84.                                 MOV INT# 4 *    BX
  85.                 POP AX
  86.                 MOV DS, AX      NEXT
  87.                 END-CODE
  88.  
  89. UP @ WAKE   ENTRY !LINK
  90.  
  91. : TASK:         ( size -- )
  92.                 CREATE   TOS HERE #USER @ CMOVE   ( Copy the USER Area )
  93.                 @LINK  UP @ -ROT  HERE UP !  !LINK ( I point where he did)
  94.                 DUP HERE +   DUP RP0 !   100 - SP0 !  SWAP UP !
  95.                 HERE ENTRY LOCAL !LINK    ( He points to me)
  96.                 HERE #USER @ +  HERE DP LOCAL !
  97.                 HERE SLEEP   ALLOT   ;
  98.  
  99. : SET-TASK      ( ES ip task -- )       \ NOTE: both ES and IP are passed
  100.                                         \ to SET-TASK.
  101.                 >R SWAP R>
  102.                 DUP SP0 LOCAL @                 \ Top of Stack
  103.                 2- ROT OVER !                   \ Initial ES
  104.                 2- ROT OVER !                   \ Initial IP
  105.                 2- OVER RP0 LOCAL @ OVER !      \ Initial RP
  106.                 SWAP TOS LOCAL !  ;
  107.  
  108. : ACTIVATE      ( task -- )
  109.                 DUP
  110.                 2R> ROT SET-TASK   WAKE  ;
  111.  
  112. : BACKGROUND:   ( -- )
  113.                 400 TASK:
  114.                 XHERE @LINK 2-          \ get address of new task, note that
  115.                                         \ XHERE returns SEGMENT and OFFSET,
  116.                                         \ which is used by SET-TASK
  117.                 SET-TASK  !CSP  ]  ;
  118.  
  119. comment:
  120.  
  121.   Here is a sample of how to create a background task that will do a
  122. listing of the current file, with the hypothetical word FUNCTION1.  The
  123. task MYTASK is created with the default function FUNCTION1 assigned to it.
  124. Next we define a word MYTASK-THIS, what changes the function assigned to
  125. MYTASK to perform FUNCTION2.  This allows us to change the function a
  126. task performs without having to define a new task. In each case, the
  127. task is stopped after its assigned FUNCTION is performed.
  128.  
  129.  
  130.         background: mytask  function1 stop ;
  131.  
  132.         : mytask-this   mytask activate   function2 stop  ;
  133.  
  134.  
  135.   This next example defines a variable, and a routine which increments
  136. the variable in the background.  Notice that the program is an infinite
  137. loop, and will only stop when put to sleep, or when multi tasking is
  138. turned off with SINGLE.  This example will actually work, you might try
  139. typing it into a file and loading it.
  140.  
  141.  
  142. variable counts
  143. background: counter     begin   pause incr> counts
  144.                         again   ;
  145.  
  146. MULTI COUNTER WAKE              \ start up the COUNTER task
  147.  
  148. \ COUNTER SLEEP                 \ put the COUNTER task to sleep
  149. \ SINGLE                        \ disable multi tasking
  150.  
  151. comment;
  152.  
  153. ONLY FORTH ALSO DEFINITIONS
  154.  
  155.  
  156.