DataMuseum.dk

Presents historical artifacts from the history of:

CR80 Hard and Floppy Disks

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CR80 Hard and Floppy Disks

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦db255c3bf⟧ TextFile

    Length: 15232 (0x3b80)
    Types: TextFile
    Names: »CORU1«

Derivation

└─⟦d9c1548a9⟧ Bits:30005185 8" CR80 Floppy CR80FD_0182 ( UTILITIES FOR X25 HOH )
    └─⟦851bd64f0⟧ 
        └─ ⟦this⟧ »ICL.CORU1« 

TextFile

;=======================================================================
;
;             COROUTINE MONITOR, PART 1.
;
;=======================================================================

MESSAGE       <:CALL: COMON1, 790813:>

;=======================================================================
;
; COROUTINE SYSTEM.
;
; THIS SYSTEM IS A MULTIPROGRAMMING SYSTEM FOR RUNNING A NUMBER OF
; PARALLEL ACTIVITIES WITHIN A SINGLE PROCESS.
;
; THE BASIC ENTITIES ARE:
;             COROUTINES  (PSEUDO PROCESSES)
;             SEMAPHORES  (SYNCHRONIZING AND COMMUNICATION PRIMITIVES)
;             OPERATIONS  (BUFFERS / MESSAGES)
;
; THE BASIC FUNCTIONS ARE:
;             SIGNAL  (SEMAPHORE)
;             WAIT  (SEMAPHORE)
;             SIGNALCH  (CHAINED SEMAPHORES)
;             WAITCH  (CHAINED SEMAPHORE)
;             WAITANSWER  (MESSAGEREF)
;             WAITMESSAGE
;             WAIT-TIMER-OR-INTERRUPT
;
;=======================================================================


USE BASE

;-----------------------------------------------------------------------
;
; BASIC DESCRIPTORS:
;


; CHAIN ELEMENTS AND QUEUE HEADS

AX=0
SUCC:=        AX, AX=AX+1           ;   SUCCESSOR (FORWARD CHAIN)
PRED:=        AX, AX=AX+1           ;   PREDECESSOR (BACKWARD CHAIN)
CHAINSIZE:=   AX                    ;   SIZE OF CHAIN HEAD

; SEMAPHORE

AX=0
SEMFST:=      AX, AX=AX+1           ;   FIRST WAITING COROUTINE
SEMLST:=      AX, AX=AX+1           ;   LAST WAITING COROUTINE
SEMVAL:=      AX, AX=AX+1           ;   SEMAPHORE VALUE
SEMSIZE:=     AX                    ;   SIZE OF SEMAPHORE

; COROUTINE DESCRIPTION

AX=CHAINSIZE                        ;   ROOM FOR CHAIN FIELDS
SV0:=         AX, AX=AX+1           ;   REGISTER SAVE AREA
SV1:=         AX, AX=AX+1           ;
SV2:=         AX, AX=AX+1           ;
SV3:=         AX, AX=AX+1           ;
SV4:=         AX, AX=AX+1           ;
SV5:=         AX, AX=AX+1           ;
SV6:=         AX, AX=AX+1           ;
CORUSIZE:=    AX                    ;   SIZE OF COROUTINE DESCRIPTOR

CCHAIN=0                            ;   CHAIN FOR INITIALIZATION

IF TPON THEN
TPOS=   8<TPLS OR 1<SMXS

TPSIGN: INXFIL,  TPSEM
TPWAIT: INXFIL,  TPSEM
TPSGCH: INXFIL,  TPSMOP
TPWTCH: INXFIL,  TPSEM
TPEXIT: INXFIL,  TPCORU
TPWTTI: INXFIL,  TPCORU
TPWTMS: INXFIL,  TPCORU
TPWANS: INXFIL,  TPCORU

DVAL:         0
TPSM:   RELFIL OR BINDAT OR 0<RCLGTS OR 1
        DVAL
        <:SEM :>
TPCOR:  RELFIL OR BINDAT OR (CORUSIZE-1)<RCLGTS OR 1
        DCORU:       0
        <:CORU:>
TPOP:   RELFIL OR BINDAT OR 6<RCLGTS OR 1
        DOP:         0
        <:OP  :>

TPSEM:  1,  TPSM
TPSMOP: 2,  TPSM,  TPOP
TPCORU: 1,  TPCOR

FI

READYQ:       RDYFST                ;   ADDRESS OF READY QUEUE
ANSWQ:        ANSFST                ;   ADDRESS OF ANSWER QUEUE
MESSC:        0                     ;   COROUTINE WAITING FOR MESSAGE
TINTRC:       0                     ;   COROUTINE WAITING FOR TIMER
                                    ;   OR INTERRUPT
CURRC:        INITCH                ;   ADDRESS OF ACTIVE COROUTINE
                                    ;   (REF TO INIT CHAIN AT STARTUP)
MSBREF:       MSBUF                 ;   REF TO RECEIVED MESSAGE

RDYFST:       LOC                   ;   EMPTY READY QUEUE
RDYLST:       LOC-1                 ;
ANSFST:       LOC                   ;   EMPTY ANSWER QUEUE
ANSLST:       LOC-1                 ;
MSBUF:        0, REPEAT 4           ;   BUFFER FOR RECEIVING MESSAGES

USE PROG

;-----------------------------------------------------------------------
;
; MAIN WAITING POINT IN COROUTINE SYSTEM
;
; THE SYSTEM SCHEDULES ALL INTERNAL EVENTS BEFORE EXTERNAL EVENTS
; I.E. COROUTINES ARE ACTIVATED FROM THE READY QUEUE UNTIL THE READY
; QUEUE IS EMPTY.
; FINALLY THE SYSTEM AWAITS SOME EXTERNAL EVENT TO TRIGGER A NEW SERIES
; OF INTERNAL EVENTS.
;
;_______________________________________________________________________

WEVENT: MON   INITWAIT              ;   BASE OF EVENT QUEUE
        MOVC  CDELAY            R0  ;   DELAY
        MON   SETDELAY              ;   SETDELAY(DELAY)
        MOV   MSBREF            R1  ;   MESSAGE AREA
        JMP              MAINWT     ;   GOTO MAIN WAITING POINT
WTNEXT: MON   RESUMEEVENT           ;   RESUMEEVENT AND
MAINWT: MON   WAITNEXT              ;   WAIT NEXT EVENT TO ARRIVE
        JMP & TIMERC                ;     TIMEOUT,
        JMP & ANSWRC                ;     ANSWER,
        JMP & MESSGE                ;     MESSAGE ARRIVED
        JMP & INTRPC                ;     INTERRUPT)

ANSWRC: MOV   ANSWQ             R7  ;   ANSWERQUEUE => R7
NEXTAQ: MOV   SUCC.  X7         R7  ;   NEXT COROUTINE => R7
        IEQ          R7  ANSWQ      ;   IF NO MORE IN QUEUE
        JMP              WTNEXT     ;   THEN GOTO WAIT NEXT EVENT
        SEQ          R2  SV2.   X7  ;   IF NOT WAITING FOR ACTUAL ANSWER
        JMP              NEXTAQ     ;   THEN GOTO NEXT IN ANSWER QUEUE
        MOVL  SV0.   X7         R0  ;   REESTABLISH R0, R1
        MOV   READYQ            R5  ;   READY QUEUE
        MOV          R7         R4  ;   ACTUAL COROUTINE
        JMP          S6  LINK       ;   LINK(CURRENT, READY QUEUE)
        JMP              SCHED      ;   GOTO SCHEDULE

MESSGE: MOV   MESSC             R7  ;   WAITING COROUTINE => R7
        JOZ          R7  WTNEXT     ;   IF NO WAITING COROUTINE
                                    ;   THEN GOTO WAIT NEXT EVENT
        MOV          R1  SV1.   X7  ;   SET BUFFER ADDRESS
        MOV          R2  SV2.   X7  ;   SET MESSAGE REFERENCE
        MOVC  0                 R0  ;
        MOV          R0  MESSC      ;   CLEAR REF TO WAITING COROUTINE
        JMP              PREPC      ;   PREPARE COROUTINE FOR RUN

TIMERC:
INTRPC: MOV   TINTRC            R7  ;   WAITING COROUTINE => R7
        JOZ          R7  WTNEXT     ;   IF NO COROUTINE IS WAITING
                                    ;   THEN GOTO WAIT NEXT EVENT
        MOVC  0                 R0  ;
        MOV          R0  TINTRC     ;   CLEAR REF TO WAITING COROUTINE
        JMP              PREPC      ;   GOTO PREPARE COROUTINE FOR RUN

PREPC:  MOV          R7         R4  ;   COROUTINE
        MOVL  SV0.   X7         R0  ;   REESTABLISH R0, R1
        MOV   READYQ            R5  ;   READY QUEUE
        JMP          S6  LINKON     ;   LINKON(COROUTINE, READYQUEUE)

SCHED:  MOV   READYQ            R0  ;   READY QUEUE
        MOV   SUCC.  X0         R7  ;   FIRST ELEMENT IN READY QUEUE
        IEQ          R0         R7  ;   IF EMPTY (POINTS TO ITSELF)
        JMP              WEVENT     ;   THEN GOTO WAIT EVENT
        MOV          R7  CURRC      ;   SET CURRENT COROUTINE
        ADDC  -7                R7  ;     MODIFY POINTER FOR UNSTACK
        MODC  SV6+1                 ;   UNSTACK
        UNS   6                     ;   R0 - R6
NOLIST
IF TPON THEN
MOV R7 DCORU
MON OLTO, TPOS OR 1
TPEXIT
MOV CURRC R7
FI
LIST
        JMP              0.     X6  ;   JUMP TO SAVED LINK


;-----------------------------------------------------------------------
;
; PROCEDURE LINK(ELEMENT, QUEUE)
;
; THIS PROCEDURE MOVES A QUEUE ELEMENT FROM ONE QUEUE TO ANOTHER
; THE ELEMENT IS REMOVED FROM WHEREVER IT IS LINKED BEFORE CALL
; THE QUEUES ARE DOUBLE LINKED
; THE ELEMENT IS LINKED INTO THE QUEUE AS THE VERY LAST ELEMENT
;       CALL:                   EXIT:
; R4    ELEMENT ADDRESS         UNCHANGED
; R5    QUEUE ADDRESS           UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED
;
;
; PROCEDURE LINKON (ELEMENT, QUEUE)
;
; THIS PROCEDURE LINKS AN ELEMENT INTO A QUEUE.
; THE ELEMENT IS EXPECTED NOT TO RESIDE IN ANY QUEUE WHEN THIS PROCEDURE
; IS CALLED (THE VALUES OF THE CHAIN FIELDS ARE CONSIDERED TO BE IRRE-
; LEVANT.
;       CALL:                   EXIT:
; R4    ELEMENT ADDRESS         UNCHANGED
; R5    QUEUE ADDRESS           UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED
;
;
; PROCEDURE LINKOFF (ELEMENT)
;
; THIS PROCEDURE REMOVES A QUEUE ELEMENT FROM WHEREVER IT IS LINKED UP
; WHEN THIS PROCEDURE IS CALLED.
;       CALL:                   EXIT:
; R4    ELEMENT ADDRESS         UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

LINKOFF:MOV          R5  SV5.   X7  ;   SAVE R5
        MOVC  0                 R5  ;   CLEAR QUEUE

LINK:   MOVL         R0  SV0.   X7  ;   SAVE R0, R1
                                    ;   REMOVE ELEMENT FROM QUEUE
        MOV   PRED.  X4         R0  ;   PRED.ELEMENT => PREDECESSOR
        MOV   SUCC.  X4         R1  ;   SUCC.ELEMENT => SUCCESSOR
        MOV          R1  SUCC.  X0  ;   SUCCESSOR => SUCC.PREDECESSOR
        MOV          R0  PRED.  X1  ;   PREDECESSOR => PRED.SUCCESSOR
        JON          R5  LINTO      ;   IF LINKOFF THEN
        MOV   SV5.   X7         R5  ;     REESTABLISH R5
        JMP              LNKXIT     ;     GOTO EXIT

LINKON: MOVL         R0  SV0.   X7  ;   SAVE R0, R1
        MOV          R4  SUCC.  X4  ;   SET EMPTY CHAIN
        MOV          R4  PRED.  X4  ;
LINTO:                              ;   LINK ELEMENT INTO QUEUE
        MOV   PRED.  X5         R0  ;   PRED.QUEUE => OLDLAST
        MOV          R4  SUCC.  X0  ;   ELEMENT => SUCC.OLDLAST
        MOV          R4  PRED.  X5  ;   ELEMENT => PRED.QUEUE
        MOV          R0  PRED.  X4  ;   OLDLAST => PRED.ELEMENT
        MOV          R5  SUCC.  X4  ;   QUEUE => SUCC.ELEMENT
LNKXIT: MOVL  SV0.   X7         R0  ;   REESTABLISH R0, R1
        JMP              0.     X6  ;   RETURN TO LINK


;-----------------------------------------------------------------------
;
; PROCEDURE SIGNAL (SEMAPHORE)
;
; THIS PROCEDURE INCREASES THE VALUE OF A SIMPLE SEMAPHORE BY ONE
; IN CASE THE VALUE WAS NEGATIVE BEFORE CALLING THE PROCEDURE (BECAUSE
; A COROUTINE WAS ALREADY WAITING FOR A SIGNAL) THE FIRST WAITING
; COROUTINE IS LINKED INTO THE READY QUEUE (TO BE ACTIVATED)
; IN ANY CASE THE CALLING COROUTINE WILL BE REACTIVATED AFTER CALLING
; THIS PROCEDURE (NO WAITING POINT)
;       CALL:                   EXIT:
; R5    SEMAPHORE ADDRESS       UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

SIGNAL: MOV          R4  SV4.   X7  ;   SAVE R4,
        MOV          R5  SV5.   X7  ;   R5
        MOV          R6  SV6.   X7  ;   AND R6
        INC              SEMVAL.X5  ;   INCREASE SEMAPHORE VALUE BY 1
        MOV   SEMVAL.X5         R6  ;
NOLIST
IF TPON THEN
MOV R6 DVAL
MON OLTO, TPOS OR 2
TPSIGN
MOV CURRC R7
FI
LIST
        IGE          R6  1          ;   IF SEMVALUE > 0
        JMP              SIGXIT     ;   THEN GOTO EXIT
        MOV   SEMFST.X5         R4  ;   SEMFST.SEMAPHORE => COROUTINE
        MOV   READYQ            R5  ;   READY QUEUE
        JMP          S6  LINK       ;   LINK (COROUTINE, READY QUEUE)
SIGXIT: MOV   SV4.   X7         R4  ;   REESTABLISH R4,
        MOV   SV5.   X7         R5  ;   R5,
        MOV   SV6.   X7         R6  ;   AND R6
        JMP              0.     X6  ;   RETURN TO LINK


;-----------------------------------------------------------------------
;
; PROCEDURE WAIT (SEMAPHORE)
;
; THIS PROCEDURE DECREASES THE VALUE OF A SIMPLE SEMAPHORE BY ONE
; IN CASE THE VALUE WAS NOT POSITIVE BEFORE CALLING THIS PROCEDURE
; (BECAUSE NO SIGNALS WERE READY) THE CALLING COROUTINE IS LINKED TO
; THE SEMAPHORE, WAITING FOR A SIGNAL TO ARRIVE.
; THIS IS A WAITING POINT PROCEDURE.
;       CALL:                   EXIT:
; R5    SEMAPHORE ADDRESS       UNCHANMGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

WAITS:  MODC  SV6+1                 ;   STACK
        STC   6                     ;   R0 _ R6
        MOV   CURRC             R7  ;   REESTABLISH R7
        DEC              SEMVAL.X5  ;   DECREMENT (SEMVAL.SEMAPHORE)
        MOV   SEMVAL.X5         R6  ;   SEMVAL.SEMAPHORE => SEMVALUE
NOLIST
IF TPON THEN
MOV R6 DVAL
MON OLTO, TPOS OR 3
TPWAIT
MOV CURRC R7
FI
LIST
        MOV          R7         R4  ;   CURRENT COROUTINE
        ILT          R6  0          ;   IF SEMVALUE < 0
        JMP          S6  LINK       ;   THEN LINK (CURRENT, SEMAPHORE)
        JMP              SCHED      ;   GOT SCHEDULE


;-----------------------------------------------------------------------
;
; PROCEDURE SIGNALCH (SEMAPHORE, OPERATION)
;
; THIS PROCEDURE DELIVERS AN OPERATION AT A CHAINED SEMAPHORE.
; IN CASE A COROUTINE IS ALREADY WAITING AT THE SEMAPHORE, THE OPERA-
; TION IS HANDED TO THIS COROUTINE, WHICH IS THEN PUT INTO THE READY
; QUEUE (FOR LATER ACTIVATION).
; IN CASE NO COROUTINE WAITS AT THE SEMAPHORE, THE OPERATION IS LINKED
; TO IT, WAITING TO BE FETCHED BY WAITCH.
;       CALL:                   EXIT:
; R4    OPERATION ADDRESS       UNCHANGED
; R5    SEMAPHORE ADDRESS       UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

SIGNCH: MOV          R4  SV4.   X7  ;   SAVE R4,
        MOV          R5  SV5.   X7  ;   R5,
        MOV          R6  SV6.   X7  ;   AND R6
        INC              SEMVAL.X5  ;   INCREASE SEMAPHORE VALUE
        MOV   SEMVAL.X5         R6  ;
NOLIST
IF TPON THEN
MOV R6 DVAL
MOV R4 DOP
MON OLTO, TPOS OR 4
TPSGCH
MOV CURRC R7
FI
LIST
        SGE          R6  1          ;   IF SEMVALUE > 0
        JMP              SCHLSE     ;   THEN
        JMP          S6  LINKON     ;     LINKON(OPERATION,SEMAPHORE)
        JMP              SCHXIT     ;   ELSE
SCHLSE: MOV   SEMFST.X5         R4  ;     FIRST WAITING COROUTINE
        MOV   READYQ            R5  ;     READY QUEUE
        JMP          S6  LINK       ;     LINK(WAITINGCORU, READYQYEYE)
        MOV   SV4.   X7         R6  ;     OPERATION
        MOV          R6  SV4.   X4  ;     OPERATION => SV4.WAITINGCORU
        MOV   SV4.   X7         R4  ;     OPERATION
        JMP          S6  LINKOFF    ;     LINKOFF(OPERATION)
SCHXIT: MOV   SV4.   X7         R4  ;   REESTABLISH R4,
        MOV   SV5.   X7         R5  ;   R5,
        MOV   SV6.   X7         R6  ;   AND R6
        JMP              0.     X6  ;   RETURN TO LINK


;-----------------------------------------------------------------------
;
; PROCEDURE WAITCH (SEMAPHORE, OPERATION)
;
; THIS PROCEDURE FETCHES AN OPERATION FROM A SEMAPHORE.
; IN CASE AN OPERATION IS READY WHEN THE PROCEDURE IS CALLED, THE OPE-
; RATION IS SIMPLY HANDED TO THE CALLING COROUTINE.
; IN CASE NO OPERATION IS READY AT CALL TIME, THE CALLING COROUTINE IS
; DELAYED UNTIL AN OPERATION ARRIVES FOR IT.
;       CALL:                   EXIT:
; R4    IRRELEVANT              OPERATION ADDRESS
; R5    SEMAPHORE               UNCHANGED
; R6    LINK                    UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

WAITCH: MODC  SV6+1                 ;   STACK
        STC   6                     ;   R0 - R6
        MOV   CURRC             R7  ;   REESTABLISH R7
        DEC              SEMVAL.X5  ;   DECREMENT (SEMVAL.SEMAPHORR)
        MOV   SEMVAL.X5         R6  ;   SEMVALUE
NOLIST
IF TPON THEN
MOV R6 DVAL
MON OLTO, TPOS OR 5
TPWTCH
MOV CURRC R7
FI
LIST
        SLT          R6  0          ;   IF SEMVALUE < 0
        JMP              WCHLSE     ;   THEN
        MOV          R7         R4  ;     CURRENT COROUTINE
        JMP          S6  LINK       ;     LINK(CURRENTCORU, SEMAPHORE)
        JMP              SCHED      ;   ELSE
WCHLSE: MOV   SEMFST.X5         R4  ;     FIRST WAITING OPERATION
        JMP          S6  LINKOFF    ;     LINKOFF(OPERATION)
        MOV          R4  SV4.   X7  ;     OPERATION => SV4.CURRENTCORU
        JMP              SCHED      ;   GOTO SCHEDULE


;-----------------------------------------------------------------------
;
; PROCEDURE WAITANSWER (MESSAGEREF)
;
; THIS PROCEDURE INDICATES THAT THE CALLING COROUTINE IS TO BE DELAYED
; UNTIL AN ANSWER ARIVES TO THE MESSAGE POINTED OUT BY MESSAGEREF.
; THIS IS A WAITING POINT PROCEDURE.
;       CALL:                   EXIT:
; R2    MESSAGEREF              UNCHANGED
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

WANSW:  MODC  SV6+1                 ;   STACK
        STC   6                     ;   R0 _ R6
        MOV   CURRC             R7  ;   REESTABLISH R7
NOLIST
IF TPON THEN
MOV R7 DCORU
MON OLTO, TPOS OR 6
TPWANS
MOV CURRC R7
FI
LIST
        MOV          R7         R4  ;   CURRENT COROUTINE
        MOV   ANSWQ             R5  ;   ANSWER QUEUE
        JMP          S6  LINK       ;   LINK (CURRENT, ANSWER QUEUE)
        JMP              SCHED      ;   GOTO SCHEDULE


;-----------------------------------------------------------------------
;
; PROCEDURE WAITMESSAGE (EVENT, MESSAGE), (ALREADY AWAITED, NORMAL)
;
; THIS PROCEDURE INDICATES THAT THE CALLING COROUTINE IS TO BE DELAYED
; UNTIL A MESSAGE ARRIVES TO THE PROCESS.
; NOTE, THAT ONLY ONE COROUTINE MAY WAIT FOR MESSAGES AT A TIME.
; (USUALLY A DEDICATED MESSAGE SCHEDULER COROUTINE IS THE ONLY COROU_
; TINE AWAITING MESSAGES).
; THIS IS A WAITING POINT PROCEDURE.
;       CALL:                   EXIT:
; R1    IRRELEVANT              MESSAGE ADDRESS
; R2    IRRELEVANT              EVENT
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

WTMESS: MODC  SV6+1                 ;   STACK
        STC   6                     ;   R0 - R6
        MOV   CURRC             R7  ;   REESTABLISH R7
NOLIST
IF TPON THEN
MOV R7 DCORU
MON OLTO, TPOS OR 7
TPWTMS
MOV CURRC R7
FI
LIST
        MOV   MESSC             R2  ;   IF ANOTHER COROUTINE IS WAITING
        JON          R2  0.     X6  ;   THEN RETURN TO LINK
        INC              SV6.   X7  ;   ELSE INCREMENT LINK
        MOV          R7  MESSC      ;   CURRC => WAITING FOR MESSAGE
        MOV          R7         R4  ;   CURRENT COROUTINE
        JMP          S6  LINKOFF    ;   LINKOFF(CURRENT COROUTINE)
        JMP              SCHED      ;   GOTO SCHEDULE


;-----------------------------------------------------------------------
;
; PROCEDURE WAITTIMER_OR_INTERRUPT (), (ALREADY AWAITED, NORMAL)
;
; THIS PROCEDURE INDICATES THAT THE CALLING COROUTINE IS TO BE DELAYED
; UNTIL THE PROCESS IS INTERRUPTED OR TIMED OUT.
; NOTE, THAT ONLY ONE COROUTINE MAY WAIT FOR THESE EVENTS AT A TIME.
; THIS IS A WAITING POINT PROCEDURE.
;       CALL:                   EXIT:
; R7    CURRENT COROUTINE       UNCHANGED
; --    IRRELEVANT              UNCHANGED

WTINTR: MODC  SV6+1                 ;   STACK
        STC   6                     ;   R0 _ R6
        MOV   CURRC             R7  ;   REESTABLISH R7
NOLIST
IF TPON THEN
MOV R7 DCORU
MON OLTO, TPOS OR 8
TPWTTI
MOV CURRC R7
FI
LIST
        MOV   TINTRC            R0  ;   IF ANOTHER COROUTINE IS WAITING
        JON          R0  0.     X6  ;   THEN RETURN TO LINK
        INC              SV6.   X7  ;   ELSE INCREMENT LINK
        MOV          R7  TINTRC     ;   CURRC => WAITING COROUTINE
        MOV          R7         R4  ;   CURRENT COROUTINE
        JMP          S6  LINKOFF    ;   LINKOFF(CURRENT COROUTINE)
        JMP              SCHED      ;   GOTO SCHEDULE


;-----------------------------------------------------------------------
;
; COROUTINE INITIALIZATION
;
; THIS PIECE OF CODE INITIALIZES ALL COROUTINE DESCRIPTORS AND PUTS
; ALL COROUTINES INTO THE READY QUEUE.
; THIS IS DONE BY SCANNING THE LIST OF COROUTINE BLOCKS (TYPICALLY
; THERE WILL BE A BLOCK PER COROUTINE TYPE - CONTAINING A NUMBER OF
; OF INCARNATIONS OF THE ACTUAL COROUTINE TYPE).

; INITIALIZATION RECORD

AX=0
ICHAIN:=      AX, AX=AX+1           ;   CHAIN TO NEXT INIT BLOCK
IPRPC:=       AX, AX=AX+1           ;   ENTRY POINT OF COROUTINE
ISIZE:=       AX, AX=AX+1           ;   SIZE OF COROUTINE RECORD
ICOUNT:=      AX, AX=AX+1           ;   NUMBER OF COROUTINES IN BLOCK

COINIT: MOV   CURRC             R1  ;   START OF INITIALIZATION CHAIN
NXTBLC: JOZ          R1  SCHED      ;   IF NO MORE BLOCKS THEN SCHEDULE
        ADDC  -4                R1  ;   START OF INIT RECORD
        MOV          R1         R7  ;   CURRENT COROUTINE
        MOV   ICOUNT.X7         R0  ;   COROUTINE COUNTER
        MOV   IPRPC. X7         R2  ;   ENTRY POINT
        MOV   ISIZE. X7         R3  ;   COROUTINE RECORD SIZE
        MOV   ICHAIN.X7         R1  ;   ADDRESS OF NEXT BLOCK IN CHAIN
        MOV   READYQ            R5  ;   READY CUEUE

NEXTC:  MOV          R7         R4  ;   CURRENT COROUTINE
        MOV          R7  SUCC.  X7  ;   INIT CHAIN FIELDS
        MOV          R7  PRED.  X7  ;
        JMP          S6  LINK       ;   LINK (CURRENT, READY QUEUE)
        MOV          R2  SV6.   X7  ;   SET ENTRY POINT (SAVED LINK)
        ADD          R3         R7  ;   NEXT COROUTINE RECORD
        SOB          R0  NEXTC      ;   REPEAT UNTIL COUNT = 0
        JMP              NXTBLC     ;   GOTO NEXT BLOCK


«eof»