home *** CD-ROM | disk | FTP | other *** search
- \ MULTASK.SEQ Multi tasking code for Forth.
-
- PREFIX
-
- ONLY FORTH ALSO DEFINITIONS
-
- DECIMAL
-
- comment:
-
- The MultiTasker is loaded as an application on top of the
- regular Forth System. There is support for it in the nucleus
- in the form of USER variables and PAUSEs inserted inside of
- KEY EMIT and BLOCK. The Forth multitasking scheme is
- co-operative instead of interruptive. All IO operations cause
- a PAUSE to occur, and the multitasking loop looks around at
- all of the current task for something to do.
-
- Modified by Tom Zimmer to work with F-PC, which needs to save the ES
- register along with IP. - 2/29/88 -
-
- NOTICE !! This multi tasking DOES NOT SUPPORT MULTIPLE USERS !!!
-
- There are a significant number of things what will have to be changed
- in this Forth system to support multi user, like the editor would have
- to be re-written, ect. So I am not supporting multi user, only
- background processing.
-
- Background processing MAY NOT do any compiling, compile, like VARIABLE,
- or CREATE, ect. at *** RUNTIME ***. 06/06/88 13:58
-
- YDP and XDP are NOT user variables.
-
- comment;
-
- CODE (PAUSE) ( -- )
- PUSH ES \ Push ES, IP, and RP
- PUSH IP
- PUSH RP
- MOV BX, UP \ make BX point to user area
- MOV 0 [BX], SP \ save SP in user area offset 0
- ADD BX, # 4 \ adjust BX to point to LINK
- ADD BX, 0 [BX] \ Add value in LINK to BX, pointing it to
- \ next tasks user area offset 0
- ADD BX, # 2 \ bump BX 2 to point to ENTRY
- JMP BX \ jump to next tasks entry point
- END-CODE
-
- CODE RESTART ( -- )
- POP BX \ pop address of where we came from
- MOV AX, # -4
- ADD BX, AX \ adjust to beginning of user area
- MOV UP BX \ set UP to point to begin of user area
- POP AX \ pop off old PC
- POPF \ restore status register
- MOV SP, 0 [BX] \ restore SP (stack pointer)
- POP RP \ restore RP, IP, and ES
- POP IP
- POP ES
- NEXT END-CODE
-
- $0E9 CONSTANT INT#
-
- : LOCAL ( base addr -- addr' ) UP @ - + ;
- : @LINK ( -- addr ) LINK DUP @ + 2+ ;
- : !LINK ( addr -- ) LINK 2+ - LINK ! ;
- : SLEEP ( addr -- ) $0E990 SWAP ENTRY LOCAL ! ;
- : WAKE ( addr -- ) $0E9CD SWAP ENTRY LOCAL ! ;
- : STOP ( -- ) UP @ SLEEP PAUSE ;
- : SINGLE ( -- )
- $0E9 ['] PAUSE C! \ set JMP in PAUSE
- >NEXT ['] PAUSE >BODY - \ get offset to NEXT
- ['] PAUSE 1+ ! ; \ store in PAUSE + 1
-
- CODE MULTI ( -- )
- MOV ' PAUSE # $0E9
- MOV BX, # ' (PAUSE) ' PAUSE 3 + - \ relative I hope!
- MOV ' PAUSE 1+ BX
- MOV BX, # ' RESTART
- MOV AX, DS
- PUSH AX
- SUB AX, AX MOV DS, AX
- MOV AX, CS MOV INT# 4 * 2+ AX
- MOV INT# 4 * BX
- POP AX
- MOV DS, AX NEXT
- END-CODE
-
- UP @ WAKE ENTRY !LINK
-
- : TASK: ( size -- )
- CREATE TOS HERE #USER @ CMOVE ( Copy the USER Area )
- @LINK UP @ -ROT HERE UP ! !LINK ( I point where he did)
- DUP HERE + DUP RP0 ! 100 - SP0 ! SWAP UP !
- HERE ENTRY LOCAL !LINK ( He points to me)
- HERE #USER @ + HERE DP LOCAL !
- HERE SLEEP ALLOT ;
-
- : SET-TASK ( ES ip task -- ) \ NOTE: both ES and IP are passed
- \ to SET-TASK.
- >R SWAP R>
- DUP SP0 LOCAL @ \ Top of Stack
- 2- ROT OVER ! \ Initial ES
- 2- ROT OVER ! \ Initial IP
- 2- OVER RP0 LOCAL @ OVER ! \ Initial RP
- SWAP TOS LOCAL ! ;
-
- : ACTIVATE ( task -- )
- DUP
- 2R> ROT SET-TASK WAKE ;
-
- : BACKGROUND: ( -- )
- 400 TASK:
- XHERE @LINK 2- \ get address of new task, note that
- \ XHERE returns SEGMENT and OFFSET,
- \ which is used by SET-TASK
- SET-TASK !CSP ] ;
-
- comment:
-
- Here is a sample of how to create a background task that will do a
- listing of the current file, with the hypothetical word FUNCTION1. The
- task MYTASK is created with the default function FUNCTION1 assigned to it.
- Next we define a word MYTASK-THIS, what changes the function assigned to
- MYTASK to perform FUNCTION2. This allows us to change the function a
- task performs without having to define a new task. In each case, the
- task is stopped after its assigned FUNCTION is performed.
-
-
- background: mytask function1 stop ;
-
- : mytask-this mytask activate function2 stop ;
-
-
- This next example defines a variable, and a routine which increments
- the variable in the background. Notice that the program is an infinite
- loop, and will only stop when put to sleep, or when multi tasking is
- turned off with SINGLE. This example will actually work, you might try
- typing it into a file and loading it.
-
-
- variable counts
- background: counter begin pause incr> counts
- again ;
-
- MULTI COUNTER WAKE \ start up the COUNTER task
-
- \ COUNTER SLEEP \ put the COUNTER task to sleep
- \ SINGLE \ disable multi tasking
-
- comment;
-
- ONLY FORTH ALSO DEFINITIONS
-
-
-