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

⟦1d0064488⟧ TextFile

    Length: 17784 (0x4578)
    Types: TextFile
    Names: »COMON3.S«

Derivation

└─⟦1dc3ed39a⟧ Bits:30005066 8" CR80 Floppy CR80FD_0003 ( Id. O.K Vol. FLOPPY VOL: NSS )
    └─⟦02b6ff5ea⟧ 
        └─ ⟦this⟧ »TDXDR.851216.D!COMON3.S« 

TextFile

;=======================================================================
;
;       COROUTINE MONITOR,  PART 3 OF 4
;
;       PROGRAM
;
;=======================================================================

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:
        MOVC  0                 R2  ;   CLEAR EVENT MASK
        MOV   ANSWQ             R7  ;   TAKE ANSWER QUEUE
        INE          R7  SUCC.  X7  ;   IF NOT EMPTY
        ADDC  BMSYA             R2  ;   THEN WAIT FOR SYSTEM ANSWERS
        MOV   MESSC             R7  ;   COROUTINE WAITING FOR SYS MESS.
        INE          R7  0          ;   IF ANY
        ADDC  BMSYM             R2  ;   THEN INCLUDE WAITING FOR SYSMES.
        MOV   TINTRC            R7  ;   COROUTINE WAITING FOR TIMER/INTRP
        INE          R7  0          ;   IF ANY
        ADDC  BMDELAY+BMINTRPT  R2  ;   THEN INCLUDE WAITING FOR TIMER
                                    ;   AND FOR INTERRUPT
        MOVC  CDELAY            R0  ;   SET DELAY
        MOV   MSBREF            R1  ;   TAKE PTR TO MESSAGE BUFFER
        MON   WAITEVENT             ;   AWAIT NEXT MATCHING EVENT

        IEQ          R0  BNSYM      ;   IF SYS MESSAGE ARRIVED
        JMP              MESSGE     ;   THEN HANDLE MESSAGE
        IEQ          R0  BNSYA      ;   IF SYS ANSWER ARRIVED
        JMP              ANSWRC     ;   THEN HANDLE ANSWER
        JMP              TIMERC     ;   OTHERWISE HANDLE TIMER OR INTRPT

ANSWRC: MOV   ANSWQ             R7  ;   ANSWERQUEUE => R7
NEXTAQ: MOV   SUCC.  X7         R7  ;   NEXT COROUTINE => R7
        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
        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
        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 R5 TPSMP
MON OLTO, TPOS OR 2
TPSM
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 R5 TPSMP
MON OLTO, TPOS OR 3
TPSM
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 R5 TPSMP
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
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.
; THIS IS A WAITING POINT PROCEDURE.
;       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 R5 TPSMP
MON OLTO, TPOS OR 5
TPSM
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