DataMuseum.dkPresents historical artifacts from the history of: CR80 Hard and Floppy Disks |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CR80 Hard and Floppy Disks Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 17784 (0x4578) Types: TextFile Names: »COMON3.S«
└─⟦1dc3ed39a⟧ Bits:30005066 8" CR80 Floppy CR80FD_0003 ( Id. O.K Vol. FLOPPY VOL: NSS ) └─⟦02b6ff5ea⟧ └─ ⟦this⟧ »TDXDR.851216.D!COMON3.S«
;======================================================================= ; ; 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