.SBTTL DEFINITIONS OF BASIC KERNEL DATA TYPES ;"################################### ; # BASIC DATA TYPES # ;###################################" ; ; ;**********************************; ; IN THE CODE THAT FOLLOWS WE SHALL; ; ALWAYS FEEL FREE TO ASSUME THAT ; ; ALL RECORD FIELDS ARE ALLOCATED ; ; CONSECUTIVELY IN THE ORDER OF ; ; THEIR DECLARATION. ; ;**********************************; ; ; NIL = 0 ; CONST NIL = 0; GATES = 25. ; GATES = 25; "MONITOR GATES" PROCS = 10. ; PROCESSES = 10; "PROCESSES" ; ; PROCESS = 0 ; TYPE PROCESS = $ = PROCESS ; RECORD LINK0 = $ ; "QUEUE LINK" $ = $ + .QUEUETYPE ; HEAD0 = $ ; HEAD: $ = $ + .HEADTYPE ; HEADTYPE; REG0 = $ ; REG: $ = $ + .REGTYPE ; REGTYPE; MAP0 = $ ; MAP: $ = $ + .MAPTYPE ; MAPTYPE; .PROCESS= $ - PROCESS ; END; ; ; HEADTYPE= 0 ; TYPE HEADTYPE = $ = HEADTYPE ; RECORD INDEX1 = $ ; INDEX: $ = $ + .INTEGER ; INTEGER; HEAPT1 = $ ; HEAPTOP: $ = $ + .INTEGER ; INTEGER; LINE1 = $ ; LINE: $ = $ + .INTEGER ; INTEGER; RESUL1 = $ ; RESULT: $ = $ + .INTEGER ; INTEGER; RUNTI1 = $ ; RUNTIME: $ = $ + .TIME ; TIME; SLICE1 = $ ; SLICE: $ = $ + .INTEGER ; INTEGER; NESTI1 = $ ; NESTING: $ = $ + .INTEGER ; INTEGER; PRIOR1 = $ ; PRIORITY: $ = $ + .INTEGER ; INTEGER; OVERT1 = $ ; OVERTIME: $ = $ + .BOOLEAN ; BOOLEAN; JOB1 = $ ; JOB: $ = $ + .BOOLEAN ; BOOLEAN; CONTI1 = $ ; CONTINUE: $ = $ + .BOOLEAN ; BOOLEAN; OPCOD1 = $ ; OPCODE: $ = $ + .INTEGER ; INTEGER; PARAM1 = $ ; PARAM: $ = $ + <4. * .INTEGER> ; ARRAY (.1..4.) OF ; INTEGER; OPLIN1 = $ ; OPLINE: $ = $ + .INTEGER ; INTEGER; CHKDTL HEADTYPE ; END; ; ; REGTYPE = 0 ; TYPE REGTYPE = $ = REGTYPE ; RECORD W2 = $ ; W: $ = $ + .INTEGER ; INTEGER; X2 = $ ; X: $ = $ + .INTEGER ; INTEGER; Y2 = $ ; Y: $ = $ + .INTEGER ; INTEGER; Q2 = $ ; Q: $ = $ + .INTEGER ; INTEGER; B2 = $ ; B: $ = $ + .INTEGER ; INTEGER; G2 = $ ; G: $ = $ + .INTEGER ; INTEGER; S2 = $ ; S: $ = $ + .INTEGER ; INTEGER; P2 = $ ; P: $ = $ + .INTEGER ; INTEGER; PSTAT2 = $ ; PSTATUS: $ = $ + .INTEGER ; INTEGER; FW2 = $ ; FW: $ = $ + .REAL ; REAL; FX2 = $ ; FX: $ = $ + .REAL ; REAL; FSTAT2 = $ ; FSTATUS: $ = $ + .INTEGER ; INTEGER; CHKDTL REGTYPE ; END; ; ; MAPTYPE = 0 ; TYPE MAPTYPE = $ = MAPTYPE ; $ = $ + <8. * .INTEGER> ; ARRAY (.0..7.) OF INTEGER; CHKDTL MAPTYPE ; ; ; PROCREF = 0 ; TYPE PROCESSREF = $ = PROCREF ; $ = $ + .ADDRESS ; @ PROCESS; .PROCREF= $ - PROCREF ; ; ; PROCQUE = 0 ; TYPE PROCESSQUEUE = $ = PROCQUE ; $ = $ + .QUEUETYPE ; SEQUENCE OF PROCESSREF; .PROCQUE= $ - PROCQUE ; ;"################################### ; # NEWCORE # ;###################################" ; ; ; THIS CLASS MUST BE PLACED FIRST ; VAR NEWCORE: ; IN THE KERNEL SO AS TO OVERLAP ; CLASS ; THE CORE OCCUPIED BY THE TRANSI- ; ; ENT INITIALIZER BEGINNING AT LOC-; ; ATION "$KNL0". ; ; $G = GATES * .GATE ; CONST SPACE = GATES*GATELENG + $P = PROCS * .PROCESS ; PROCESSES*PROCESSLENG $S = $G + $P ; $M = . - $KNL0 ; $D = $S - $M ; .IF LT $D ; $S = $M ; $D = 0 ; .ENDC ; .BLKB $D ; SPAC16 = $S ; SLIM16: ; SPACELIMIT = .ASCIZ /SPACE LIMIT/ ; 'SPACE LIMIT(:0:)'; .EVEN ; BASE16 = $KNL0 ; BASEADDR = ...; .EVEN ; TOP16: .WORD BASE16 ; VAR TOP: INTEGER; FREE16: .WORD SPAC16 ; FREE: INTEGER; ; ; LENG16: .BLKB .INTEGER ; FUNCTION NEW(LENGTH: INTEGER): NEW16R: .BLKB .INTEGER ; INTEGER; ; NEW16: MOV LENG16,R0 ; BEGIN CMP R0,FREE16 ; IF LENGTH > FREE THEN BLE 1$ ; MOV #SLIM16,RESU19 ; KERNELERROR(SPACELIMIT); JSR PC,KERN19 ; 1$: MOV TOP16,NEW16R ; NEW := TOP; ADD R0,TOP16 ; TOP :+ LENGTH; SUB R0,FREE16 ; FREE :- LENGTH; RTS PC ; END; ; ; INIT16: ; BEGIN ; DONE AT LABEL "TOP16". ; TOP := BASEADDR; ; DONE AT LABEL "FREE16". ; FREE := SPACE; RTS PC ; END; ; ; ;"################################### ; # QUEUETYPE # ;###################################" ; ; QUTP4T: .BLKB .ADDRESS ; TYPE QUEUETYPE = ; CLASS ; QUEUETYP= 0 ; VAR $ = QUEUETYPE ; SUCC4 = $ ; SUCC: $ = $ + .ADDRESS ; @ QUEUETYPE; PRED4 = $ ; PRED: $ = $ + .ADDRESS ; @ QUEUETYPE; CHKDTL QUEUETYPE ; ; ; GET4R: .BLKB .ADDRESS ; FUNCTION GET: @ QUEUETYPE; ; ;FIRST IS R5 ; VAR FIRST, SECOND: @ QUEUETYPE; ;SECOND IS R4 ; ; GET4: MOV QUTP4T,R0 ; BEGIN MOV (R0),R5 ; FIRST := SUCC; MOV (R5),R4 ; SECOND := FIRST.SUCC; MOV R4,(R0) ; SUCC := SECOND; MOV PRED4(R5),PRED4(R4) ; SECOND.PRED := FIRST.PRED; MOV R5,GET4R ; GET := FIRST; QTRACE GET ; RTS PC ; END; ; ; ; PROCEDURE PUT(NEWELEM: NEWEL4: .BLKB .ADDRESS ; @ QUEUETYPE); ;LAST IS R5 ; VAR LAST: @ QUEUETYPE; ; PUT4: MOV QUTP4T,R0 ; BEGIN MOV NEWEL4,R1 ; MOV PRED4(R0),R5 ; LAST := PRED; MOV R1,PRED4(R0) ; PRED := NEWELEM; MOV R5,PRED4(R1) ; NEWELEM.PRED := LAST; MOV (R5),(R1) ; NEWELEM.SUCC := LAST.SUCC; MOV R1,(R5) ; LAST.SUCC := NEWELEM; QTRACE PUT ; RTS PC ; END; ; ; .MACRO ANY4 Q,FL ; MACRO FUNCTION ANY: BOOLEAN; ; ; "WE ASSUME THAT THIS FUNCTION AND ; EMPTY, BELOW, WILL NOT BE USED ; IN ASSIGNMENT STATEMENTS" ; ; BEGIN CMP Q,(Q) ; ANY := SUCC <> THIS QUEUETYPE; BEQ FL ; .ENDM ANY4 ; END; ; ; .MACRO EMPTY4 Q,FL ; MACRO FUNCTION EMPTY: BOOLEAN; ; CMP Q,(Q) ; EMPTY := SUCC = THIS QUEUETYPE; BNE FL ; .ENDM EMPTY4 ; END; ; ; INIT4: MOV QUTP4T,R0 ; BEGIN MOV R0,R1 ; MOV R1,(R0)+ ; SUCC := THIS QUEUETYPE; MOV R1,(R0) ; PRED := THIS QUEUETYPE; RTS PC ; END; ; ; ;"################################### ; # SIGNAL # ;###################################" ; ; SIG26T: .BLKB .ADDRESS ; TYPE SIGNAL = ; CLASS ; SIGNAL = 0 ; VAR AWAITING: PROCESSQUEUE; $ = SIGNAL ; $ = $ + .PROCQUE ; .SIGNAL = $ - SIGNAL ; ; ; PROCEDURE AWAIT; ; AWAI26: ; BEGIN JSR PC,PREE11 ; AWAITING.PUT(RUNNING.PREEMPTED); MOV PRE11R,NEWEL4 ; MOV SIG26T,QUTP4T ; JSR PC,PUT4 ; RTS PC ; END; ; ; ; PROCEDURE SEND; ; SEND26: ; BEGIN MOV SIG26T,R0 ; IF AWAITING.ANY THEN ANY4 R0,1$ ; BEGIN 2$: ; REPEAT MOV R0,QUTP4T ; READY.ENTER(AWAITING.GET); JSR PC,GET4 ; MOV GET4R,P12 ; JSR PC,ENTE12 ; MOV SIG26T,R0 ; UNTIL AWAITING.EMPTY; EMPTY4 R0,2$ ; JSR PC,RESC12 ; READY.RESCHEDULE; ; END; 1$: RTS PC ; END; ; ; INIT26: ; BEGIN MOV SIG26T,QUTP4T ; AWAITING.INITIALIZE; JSR PC,INIT4 ; RTS PC ; END "OF SIGNAL"; ; ; .SBTTL KERNEL TIMING PROCESSES ;"################################### ; # TIME # ;###################################" ; ; TIME5T: .BLKB .ADDRESS ; TYPE TIME = ; CLASS ; TIME = 0 ; VAR ENTRY $ = TIME ; SEC5 = $ ; SEC: $ = $ + .INTEGER ; INTEGER; FRACT5 = $ ; FRACTION: $ = $ + .INTEGER ; INTEGER; "FRACTION ; UNIT = 0.1 MILLISECOND" CHKDTL TIME ; ; ; INCR5: .BLKB .INTEGER ; PROCEDURE ADD(INCR: INTEGER); ; ADD5: MOV TIME5T,R0 ; BEGIN ADD INCR5,FRACT5(R0) ; FRACTION :+ INCR; CMP FRACT5(R0),#10000. ; IF FRACTION >= 10000 THEN BLT 1$ ; BEGIN INC SEC5(R0) ; SEC :+ 1; SUB #10000.,FRACT5(R0) ; FRACTION :- 10000; 1$: ; END; RTS PC ; END; ; ; INIT5: MOV TIME5T,R0 ; BEGIN CLR SEC5(R0) ; SEC := 0; CLR FRACT5(R0) ; FRACTION := 0; RTS PC ; END; ; ; ;"################################### ; # TIMER # ;###################################" ; ; ; VAR TIMER: ; CLASS ; SMALL6 = 10. ; CONST SMALLINCR = 10; LARGE6 = 167. ; LARGEINCR = 167; ; PERIO6: .WORD 0 ; VAR PERIOD: INTEGER; ; ; ; MACRO FUNCTION ELAPSED: INTEGER; ; .MACRO ELAPS6 ; BEGIN MOV PERIO6,R0 ; ELAPSED := PERIOD + SMALLINCR; ADD #SMALL6,R0 ; CLR PERIO6 ; PERIOD := 0; .ENDM ELAPS6 ; END; ; ; INTER6: .BLKB .INTEGER ; PROCEDURE TICK(INTERVAL: INTEGER); ; TICK6: ; BEGIN ADD #LARGE6,PERIO6 ; PERIOD :+ LARGEINCR; RTS PC ; END; ; ; ; MACRO PROCEDURE RESET; ; .MACRO RESET6 ; BEGIN CLR PERIO6 ; PERIOD := 0; .ENDM RESET6 ; END; ; ; INIT6: ; BEGIN ; DONE AT LABEL "PERIO6". ; PERIOD := 0; RTS PC ; END; ; ;"################################### ; # CLOCK # ;###################################" ; ; ; VAR CLOCK: ; CLASS ; WAITT7 = 1 ; CONST WAITTIME = 1; ; NOW7: .BLKB .TIME ; VAR NOW: TIME; NEXTT7: .BLKB .SIGNAL ; NEXTTIME: SIGNAL; ; ; ; PROCEDURE INCREMENT(INTERVAL: INTER7: .BLKB .INTEGER ; INTEGER); ;P IS GET4R, P12 ; VAR P: PROCESSREF; LASTT7: .BLKB .INTEGER ; LASTTIME: INTEGER; ; INCRE7: ; BEGIN MOV NOW7+SEC5,LASTT7 ; LASTTIME := NOW.SEC; MOV #NOW7,TIME5T ; NOW.ADD(INTERVAL); MOV INTER7,INCR5 ; JSR PC,ADD5 ; MOV LASTT7,R0 ; IF NOW.SEC >= ADD #WAITT7,R0 ; LASTTIME + WAITTIME THEN CMP NOW7+SEC5,R0 ; BLT 1$ ; MOV #NEXTT7,SIG26T ; NEXTTIME.SEND; JSR PC,SEND26 ; 1$: RTS PC ; END; ; ; WAIT7: ; PROCEDURE ENTRY WAIT; ; ; BEGIN MOV #NEXTT7,SIG26T ; NEXTTIME.AWAIT; JSR PC,AWAI26 ; RTS PC ; END; ; ; REALT7: ; FUNCTION ENTRY REALTIME: INTEGER; ; $$ = NOW7 + SEC5 ; BEGIN MOV $$, ; REALTIME := NOW.SEC; RTS PC ; END; ; ; INIT7: ; BEGIN MOV #NOW7,TIME5T ; NOW.INITIALIZE; JSR PC,INIT5 ; MOV #NEXTT7,SIG26T ; NEXTTIME.INITIALIZE; JSR PC,INIT26 ; RTS PC ; END; ; ; ; ;"################################### ; # CLOCK INTERRUPT # ;###################################" ; ; ; PROCEDURE ENTRY CLOCKINTERRUPT; ; INTER8 = LARGE6 ; CONST INTERVAL = 167; ; "UNIT = 0.1 MILLISECOND" ; CLOCK8: ; BEGIN MOV #INTER8,INTER6 ; TIMER.TICK(INTERVAL); JSR PC,TICK6 ; MOV #INTER8,INTER7 ; CLOCK.INCREMENT(INTERVAL); JSR PC,INCRE7 ; JSR PC,RESC12 ; READY.RESCHEDULE; RTS PC ; END; ; ; .SBTTL CORE ALLOCATION ;"################################### ; # CORE # ;###################################" ; ; ; VAR CORE: ; CLASS ; COREL9: ; CONST CORELIMIT = .ASCIZ /CORE LIMIT/ ; 'CORE LIMIT(:0:)'; .EVEN ; COREC9: .WORD 1536. ; CORECAPACITY = 1536 "BLOCKS"; ; " = 48 KILOWORDS" ; $ = USER99 - ZERO ; VAR TOP "BLOCK": INTEGER; TOP9: .WORD $ / .BLKSB ; FREE9: .BLKB .INTEGER ; FREE "BLOCKS": INTEGER; ; ; LENGT9: .BLKB .INTEGER ; PROCEDURE ALLOC(LENGTH: INTEGER; FIRST9: .BLKB .ADDRESS ; VAR FIRST: INTEGER); ;BLOCKS IS R4 ; VAR BLOCKS: INTEGER; ; ALLOC9: ; BEGIN MOV LENGT9,R5 ; BLOCKS := (LENGTH + 63) DIV 64; CLR R4 ; ADD #<.BLKSB-1>,R5 ; ADC R4 ; DIV #.BLKSB,R4 ; CMP R4,FREE9 ; IF BLOCKS > FREE THEN BLE 1$ ; MOV #COREL9,RESU19 ; KERNELERROR(CORELIMIT); JSR PC,KERN19 ; 1$: MOV TOP9,@FIRST9 ; FIRST := TOP; ADD R4,TOP9 ; TOP :+ BLOCKS; SUB R4,FREE9 ; FREE :- BLOCKS; RTS PC ; END; ; ; INIT9: ; BEGIN ; DONE AT LABEL "TOP9". ; TOP := HEADADDR DIV 64; MOV COREC9,R0 ; FREE := CORECAPACITY - TOP; SUB TOP9,R0 ; MOV R0,FREE9 ; RTS PC ; END; ; ; .SBTTL VIRTUAL MEMORY ;"################################### ; # VIRTUAL # ;###################################" ; ; ; VAR VIRTUAL: ; CLASS ; VIRT10: ; CONST VIRTUALLIMIT = .ASCIZ /VIRTUAL LIMIT/ ; 'VIRTUAL LIMIT(:0:)'; .EVEN ; ; HARD10 = UISAR ; VAR HARDWAREMAP: MAPTYPE; COMM10: .BLKB .INTEGER ; COMMON: INTEGER; HEAP10: .BLKB .INTEGER ; ENTRY HEAPTOP: INTEGER; ; ; ; PROCEDURE DEFCOMMON(LENGTH: CLEN10: .BLKB .INTEGER ; INTEGER); CBAS10: .BLKB .INTEGER ; VAR BASE: INTEGER; ;PAGE IS R3 ; PAGE: INTEGER; ; DEFC10: ; BEGIN MOV CLEN10,LENGT9 ; CORE.ALLOC(LENGTH, BASE); MOV #CBAS10,FIRST9 ; JSR PC,ALLOC9 ; MOV CLEN10,R1 ; COMMON := (LENGTH + 8191) DIV CLR R0 ; 8192; ADD #<.SEGSB-1>,R1 ; ADC R0 ; DIV #.SEGSB,R0 ; MOV R0,COMM10 ; CMP R0,#8. ; IF COMMON > 8 THEN BLE 1$ ; KERNELERROR(VIRTUALLIMIT); MOV #VIRT10,RESU19 ; JSR PC,KERN19 ; 1$: MOV CBAS10,R1 ; FOR PAGE := 0 TO COMMON - 1 DO MOV #HARD10,R3 ; BEGIN 2$: MOV R1,(R3)+ ; HARDWAREMAP(.PAGE.) := BASE; ADD #.SGSBK,R1 ; BASE :+ 128; SOB R0,2$ ; END; MOV COMM10,R1 ; HEAPTOP := COMMON * 8192; MUL #.SEGSB,R1 ; MOV R1,HEAP10 ; RTS PC ; END; ; ; ; PROCEDURE DEFPRIVATE(LENGTH: PLEN10: .BLKB .INTEGER ; INTEGER); PBAS10: .BLKB .INTEGER ; VAR BASE: INTEGER; ;PAGE IS R3 : PAGE: INTEGER; ;TOTAL IS R0 ; TOTAL: INTEGER; ; DEFP10: ; BEGIN MOV PLEN10,LENGT9 ; CORE.ALLOC(LENGTH, BASE); MOV #PBAS10,FIRST9 ; JSR PC,ALLOC9 ; MOV PLEN10,R1 ; TOTAL := (LENGTH + 8191) DIV 8192 ADD #<.SEGSB-1>,R1 ; + COMMON; CLR R0 ; DIV #.SEGSB,R0 ; MOV COMM10,R3 ; ADD R3,R0 ; CMP R0,#8. ; IF TOTAL > 8 THEN BLE 1$ ; KERNELERROR(VIRTUALLIMIT); MOV #VIRT10,RESU19 ; JSR PC,KERN19 ; 1$: MOV PBAS10,R1 ; FOR PAGE := COMMON TO TOTAL - 1 SUB R3,R0 ; DO ASL R3 ; ADD #HARD10,R3 ; BEGIN 2$: MOV R1,(R3)+ ; HARDWAREMAP(.PAGE.) := BASE; ADD #.SGSBK,R1 ; BASE :+ 128; SOB R0,2$ ; END; RTS PC ; END; ; ; P10: .BLKB .PROCREF ; PROCEDURE GETMAP(P: PROCESSREF); ;PAGE IS R0, R2 ; VAR PAGE: INTEGER; ; GETM10: ; BEGIN MOV COMM10,R0 ; FOR PAGE := COMMON TO 7 DO MOV #8.,R1 ; SUB R0,R1 ; ASL R0 ; MOV R0,R2 ; ADD #HARD10,R0 ; ADD P10,R2 ; WITH P@ DO ADD #MAP0,R2 ; 1$: MOV (R2)+,(R0)+ ; HARDWAREMAP(.PAGE.) := ; MAP(.PAGE.); SOB R1,1$ ; END; RTS PC ; ; ; ; PROCEDURE PUTMAP; ;PAGE IS R0, R2 ; VAR PAGE: INTEGER; ; PUTM10: ; BEGIN MOV COMM10,R0 ; FOR PAGE := COMMON TO 7 DO MOV #8.,R1 ; SUB R0,R1 ; ASL R0 ; MOV R0,R2 ; ADD #HARD10,R0 ; ADD USER99,R2 ; WITH RUNNING.USER @ DO ADD #MAP0,R2 ; 1$: MOV (R0)+,(R2)+ ; MAP(.PAGE.) := ; HARDWAREMAP(.PAGE.); SOB R1,1$ ; END; RTS PC ; ; ; ; PROCEDURE REALADDRESS( VTLA10: .BLKB .ADDRESS ; VIRTUALADDRESS: ADDRESS; PREF10: .BLKB .ADDRESS ; VAR PREFIX: 0..3; REST10: .BLKB .ADDRESS ; VAR REST: ADDRESS); ; ; TYPE LONGADDRESS = 0..262143; ; ;AD IS R1 ; VAR AD: ADDRESS; ;I IS R0 ; I: 0..7; ;RAD IS R2 AND R3 ; RAD: LONGADDRESS; ; REAL10: ; BEGIN MOV VTLA10,R1 ; AD := VIRTUALADDRESS; MOV R1,R0 ; I := AD DIV 8192; SWAB R0 ; ASH #-4,R0 ; BIC #^C000016,R0 ; "I=PAGENUMBER(VIRTUALADDRESS)" BIC #^C017777,R1 ; AD := AD MOD 8192; ; "AD=BYTE NUMBER IN PAGE" CLR R2 ; RAD := AD + HARDWAREMAP(.I.)*64; MOV HARD10(R0),R3 ; ASHC #6,R2 ; ADD R1,R3 ; ADC R2 ; "RAD=REAL ADDRESS OF BYTE" MOV R2,@PREF10 ; PREFIX := RAD DIV 65536; MOV R3,@REST10 ; REST := RAD MOD 65536; RTS PC ; END; ; ; INIT10: ; BEGIN MOV #UISDR,R0 ; "SET ALL SEGMENTS TO 4K WORDS MOV #8.,R1 ; WITH READ/WRITE/EXECUTE ACCESS 1$: MOV #USDR,(R0)+ ; AND LET THE DATA SPACE SEGMEN- SOB R1,1$ ; TATION REMAIN DISABLED" RTS PC ; END; ; ; .SBTTL THE CURRENTLY RUNNING PROGRAM ;"################################### ; # RUNNING # ;###################################" ; ; ; VAR RUNNING: ; CLASS ; PLIM11: ; CONST PARAMLIMIT = .ASCIZ /PARAMETER LIMIT/ ; 'PARAMETER LIMIT(:0:)'; .EVEN ; MAX11 = 20. ; MAX = 20; FLOA11 = FSTAT0 ; FLOATSTATUS = ...; PGST11 = USRPSW ; PROGSTATUS = ...; STAR11 = STARTADDR - USER99 ; STARTADDR = ...; ; ; VAR ENTRY USER11 = USER99 ; USER: PROCESSREF; ; ENTRY HEAD11 = HEAD99 ; HEAD: HEADTYPE; CONS11 = CONS99 ; CONSTADDR: INTEGER; ; PARA11: .REPT MAX11 ; PARAM: ARRAY (.1..MAX.) OF .BLKB .INTEGER ; INTEGER; .ENDR ; NEXT11: .WORD 1 ; NEXTINDEX: INTEGER; ; ENTRY PRID11: .REPT PROCS ; PROCESSID: ARRAY (.1..PROCESSES.) .BLKB .PROCREF ; OF PROCESSREF; .ENDR ; ; "HARDWARE" ; REG: REGTYPE; ; ; P11: .BLKB .PROCREF ; PROCEDURE SERVE(P: PROCESSREF); ; SERV11: ; BEGIN RESET6 ; TIMER.RESET; MOV P11,R0 ; USER := P; MOV R0,USER11 ; MOV #HEAD11,R1 ; HEAD := USER@.HEAD; ADD #HEAD0,R0 ; $ = .HEADTYP / .INTEGER ; .REPT $ ; MOV (R0)+,(R1)+ ; .ENDR ; MOV SP,R1 ; REG := USER@.REG; MOV R0,SP ; BIS #,PSW ;<01> SET PREVIOUS USER MODE MOV (SP)+,KSR0 ;<01> MOV (SP)+,KSR1 ;<01> MOV (SP)+,KSR2 ;<01> MOV (SP)+,KSR3 ;<01> MOV (SP)+,KSR4 ;<01> MOV (SP)+,KSR5 ;<01> MOV SP,R0 ; MOV R1,SP ; MOV (R0)+,-(SP) ; MTPI SP ; MOV (R0)+,KSOPC ; .IF DF,F$PU ;<01> ONLY IF FPU PRESENT MOV (R0)+,KSOPSW ; LDD (R0)+,W ; LDD (R0)+,X ; LDFPS (R0) ; .IFF ;<01> MOV (R0),KSOPSW ;<01> .ENDC ;<01> MOV USER11,P10 ; VIRTUAL.GETMAP(USER); JSR PC,GETM10 ; ; WITH HEAD DO TST HEAD11+NESTI1 ; IF NESTING = 0 THEN BNE 1$ ; CLR HEAD11+OVERT1 ; OVERTIME := FALSE; 1$: RTS PC ; END; ; ; .SBTTL PSW FETCH ROUTINE ;<01> ;<01> THIS SERVICE RETURNS THE PSW CONTENTS IN R0 (USED ONLY BY SOFTWARE ;<01> FLOATING POINT). ;<01> .IF NDF,F$PU ;<01> ONLY IF NO FPU EMTPRO: MOV KSOPSW,R0 ;<01> FETCH PSW RTI ;<01> AND RETURN .ENDC ;<01> PRE11R: .BLKB .PROCREF ; FUNCTION PREEMPTED: PROCESSREF; ; PREE11: ; BEGIN JSR PC,UPDA11 ; UPDATE; MOV USER11,R0 ; USER@.HEAD := HEAD; ADD #HEAD0,R0 ; MOV #HEAD11,R1 ; $ = .HEADTYP / .INTEGER ; .REPT $ ; MOV (R1)+,(R0)+ ; .ENDR ; MOV SP,R1 ; USER@.REG := REG; MOV R0,SP ; MOV KSR0,(SP)+ ;<01> MOV KSR1,(SP)+ ;<01> MOV KSR2,(SP)+ ;<01> MOV KSR3,(SP)+ ;<01> MOV KSR4,(SP)+ ;<01> MOV KSR5,(SP)+ ;<01> MOV SP,R0 ; MOV R1,SP ; MFPI SP ; MOV (SP)+,(R0)+ ; MOV KSOPC,(R0)+ ; .IF DF,F$PU ;<01> ONLY IF FPU PRESENT MOV KSOPSW,(R0)+ ; STD W,(R0)+ ; STD X,(R0)+ ; STFPS (R0) ; .IFF ;<01> MOV KSOPSW,(R0) ;<01> .ENDC ;<01> MOV USER11,PRE11R ; PREEMPTED := USER; CLR USER11 ; USER := NIL; RTS PC ; END; ; ; ; PROCEDURE UPDATE; ; MAXS11 = 167. ; CONST MAXSLICE = 167; ; NEWS11: .BLKB .INTEGER ; VAR NEWSLICE: INTEGER; ; UPDA11: ; BEGIN ; WITH HEAD DO ; BEGIN ELAPS6 ; SLICE :+ TIMER.ELAPSED; MOV R0,R1 ; ADD HEAD11+SLICE1,R1 ; MOV R1,HEAD11+SLICE1 ; CMP R1,#MAXS11 ; IF SLICE >= MAXSLICE THEN BLT 1$ ; BEGIN CLR R0 ; NEWSLICE := DIV #MAXS11,R0 ; SLICE MOD MAXSLICE; MOV R1,NEWS11 ; MOV HEAD11+SLICE1,R0 ; RUNTIME.ADD(SLICE - SUB R1,R0 ; NEWSLICE); MOV R0,INCR5 ; $$ = HEAD11 + RUNTI1 ; MOV #$$,TIME5T ; JSR PC,ADD5 ; MOV NEWS11,HEAD11+SLICE1; SLICE := NEWSLICE; INC HEAD11+OVERT1 ; OVERTIME := TRUE; TST HEAD11+NESTI1 ; IF NESTING = 0 THEN BNE 1$ ; MOV #2.,HEAD11+PRIOR1 ; PRIORITY := 2; ; END; ; END; 1$: RTS PC ; END; ; ; .MACRO ENTE11 ; MACRO PROCEDURE ENTER; ; ; BEGIN ; WITH HEAD DO ; BEGIN INC HEAD11+NESTI1 ; NESTING :+ 1; CLR HEAD11+PRIOR1 ; PRIORITY := 0; ; END; .ENDM ENTE11 ; END; ; ; ; MACRO PROCEDURE LEAVE; ; .MACRO LEAV11 ?L ; BEGIN ; WITH HEAD DO ; BEGIN DEC HEAD11+NESTI1 ; NESTING :- 1; BNE L ; IF NESTING = 0 THEN ; BEGIN MOV #2.,HEAD11+PRIOR1 ; PRIORITY := 2; JSR PC,RESC12 ; READY.RESCHEDULE; ; END; L: ; END; .ENDM LEAV11 ; END; ; ; ; MACRO PROCEDURE STARTIO; ; .MACRO STIO11 ?L ; BEGIN ; WITH HEAD DO TST HEAD11+NESTI1 ; IF NESTING = 0 THEN BNE L ; MOV #1.,HEAD11+PRIOR1 ; PRIORITY := 1; L: ; .ENDM STIO11 ; END; ; ; ; PROCEDURE POPPARAM(PARAMLENGTH: PLEN11: .BLKB .INTEGER ; INTEGER); ;I IS R0, R1 ; VAR I: INTEGER; ; POPP11: MOV PLEN11,R0 ; BEGIN BEQ 1$ ; ASR R0 ; CMP R0,#MAX11 ; IF PARAMLENGTH > MAX THEN BLE 2$ ; MOV #PLIM11,RESU19 ; KERNELERROR(PARAMLIMIT); JSR PC,KERN19 ; 2$: MOV #PARA11,R1 ; FOR I := 1 TO PARAMLENGTH DO MFPI SP ; MOV (SP)+,R2 ; 3$: MFPD (R2)+ ; POP(PARAM(.I.), REG.S); MOV (SP)+,(R1)+ ; SOB R0,3$ ; MOV R2,-(SP) ; MTPI SP ; 1$: RTS PC ; END; ; ; PARL11: .BLKB .INTEGER ; PROCEDURE INITCHILD(PARAMLENGTH, VARL11: .BLKB .INTEGER ; VARLENGTH, STAC11: .BLKB .INTEGER ; STACKLENGTH, QVAL11: .BLKB .INTEGER ; QVALUE: ; INTEGER); LENG11: .BLKB .INTEGER ; VAR LENGTH: INTEGER; ;I IS R1 ; I: INTEGER; ; INCH11: ; BEGIN MOV #.PROCESS,LENG16 ; USER := NEW(PROCESS); JSR PC,NEW16 ; MOV NEW16R,USER11 ; MOV NEXT11,R0 ; PROCESSID(.NEXTINDEX.) := USER; ADD R0,R0 ; $$ = PRID11 - 2 ; MOV USER11,$$(R0) ; MOV PARL11,R0 ; LENGTH := PARAMLENGTH + CLR R1 ; ADD VARL11,R0 ; VARLENGTH + ADC R1 ; ADD STAC11,R0 ; STACKLENGTH + ADC R1 ; ADD #2,R0 ; 2; ADC R1 ; BEQ 3$ ; IF LENGTH > 65535 THEN MOV #VIRT10,RESU19 ; KERNELERROR(VIRTUALLIMIT); JSR PC,KERN19 ; 3$: MOV R0,LENG11 ; MOV R0,PLEN10 ; VIRTUAL.DEFPRIVATE(LENGTH); JSR PC,DEFP10 ; ; WITH HEAD DO MOV #,R0 ; BEGIN MOV NEXT11,(R0)+ ; INDEX := NEXTINDEX; INC NEXT11 ; NEXTINDEX :+ 1; MOV HEAP10,(R0)+ ; HEAPTOP := VIRTUAL.HEAPTOP; $$ = HEAD11+RUNTI1 ; RUNTIME.INITIALIZE; MOV #$$,TIME5T ; JSR PC,INIT5 ; MOV #,R0 ; SLICE := 0; CLR (R0)+ ; CLR (R0)+ ; NESTING := 0; MOV #2.,(R0)+ ; PRIORITY := 2; CLR (R0)+ ; OVERTIME := FALSE; CLR (R0)+ ; JOB := FALSE "0"; MOV #10.,(R0) ; CONTINUE := TRUE "10"; ; END; ; WITH REG DO PUSH ;<01> SAVE REGISTERS BIS #,PSW ;<01> BEGIN MOV LENG11,R0 ; S := HEAD.HEAPTOP + LENGTH; ADD HEAD11+HEAPT1,R0 ; MOV PARL11,R1 ; FOR I := PARAMLENGTH DOWNTO 1 BEQ 1$ ; DO MOV R1,R2 ; ADD #PARA11,R1 ; ASR R2 ; 2$: MOV -(R1),-(SP) ; PUSH(PARAM(.I.), S); MTPI -(R0) ; SOB R2,2$ ; 1$: SUB #2,R0 ; S :- 2; MOV R0,KSR5 ;<01> G := S; SUB VARL11,R0 ; S :- (VARLENGTH + 2); SUB #2,R0 ; MOV R0,KSR4 ;<01> B := S; MOV QVAL11,KSR3 ;<01> Q := QVALUE; MOV R0,-(SP) ; MTPI S ; MOV R0,KSR0 ;<01> PASS REGS BACK MOV R1,KSR1 ;<01> MOV R2,KSR2 ;<01> POP ;<01> RESTORE REGISTERS .IF DF,F$PU ;<01> FPU VERSION ONLY LDFPS #FLOA11 ; FSTATUS := FLOATSTATUS; .ENDC ;<01> F$PU MOV #PGST11,KSOPSW ; PSTATUS := PROGSTATUS; MOV #STAR11,KSOPC ; P := STARTADDR; ; END; JSR PC,PUTM10 ; VIRTUAL.PUTMAP; JSR PC,RESC12 ; READY.RESCHEDULE; RTS PC ; END; ; ; ; PROCEDURE INITPARENT( INTL11: .BLKB .INTEGER ; INTERPRETERLENGTH: INTEGER); ; ;PROGADDR IS R0 ; VAR PROGADDR, PRGL11: .BLKB .INTEGER ; PROGLENGTH, CODL11: .BLKB .INTEGER ; CODELENGTH, STKL11: .BLKB .INTEGER ; STACKLENGTH, VRLE11: .BLKB .INTEGER ; VARLENGTH, LNTH11: .BLKB .INTEGER ; LENGTH: INTEGER; ; INPA11: ; BEGIN CLR HEAD11+LINE1 ; HEAD.LINE := 0; MOV #USER99,R0 ; PROGADDR := HEADADDR + ADD INTL11,R0 ; INTERPRETERLENGTH; MOV #PRGL11,R1 ; GETDATA(PROGADDR, MOV (R0)+,(R1)+ ; PROGLENGTH, MOV (R0)+,(R1)+ ; CODELENGTH, MOV (R0)+,(R1)+ ; STACKLENGTH, MOV (R0)+,(R1)+ ; VARLENGTH); MOV #.PROCESS,LENG16 ; USER := NEW(PROCESS); JSR PC,NEW16 ; MOV NEW16R,USER11 ; MOV NEXT11,R0 ; PROCESSID(.NEXTINDEX.) := USER; ADD R0,R0 ; $$ = PRID11 - 2 ; MOV USER11,$$(R0) ; MOV #,R0 ; WITH HEAD DO ; BEGIN MOV NEXT11,(R0)+ ; INDEX := NEXTINDEX; INC NEXT11 ; NEXTINDEX :+ 1; MOV INTL11,R1 ; HEAPTOP := INTERPRETERLENGTH + CLR R2 ; ADD PRGL11,R1 ; PROGLENGTH; ADC R2 ; MOV R1,(R0) ; ADD STKL11,R1 ; LENGTH := HEAPTOP + STACKLENGTH ADC R2 ; ADD VRLE11,R1 ; + VARLENGTH ADC R2 ; ADD #2,R1 ; + 2; ADC R2 ; BEQ 1$ ; IF LENGTH > 65535 THEN MOV #VIRT10,RESU19 ; KERNELERROR(VIRTUALLIMIT); JSR PC,KERN19 ; 1$: MOV R1,LNTH11 ; MOV R1,CLEN10 ; VIRTUAL.DEFCOMMON(LENGTH); JSR PC,DEFC10 ; $$ = HEAD11+RUNTI1 ; RUNTIME.INITIALIZE; MOV #$$,TIME5T ; JSR PC,INIT5 ; MOV #,R0 ; SLICE := 0; CLR (R0)+ ; CLR (R0)+ ; NESTING := 0; MOV #2.,(R0)+ ; PRIORITY := 2; CLR (R0)+ ; OVERTIME := FALSE; CLR (R0)+ ; JOB := FALSE "0"; MOV #10.,(R0) ; CONTINUE := TRUE "10"; ; END; ; WITH REG DO BIS #,PSW ;<01> BEGIN PUSH R0 ;<01> SAVE R0 MOV LNTH11,R0 ; S := LENGTH - 2; SUB #2.,R0 ; MOV R0,KSR5 ;<01> G := S; SUB VRLE11,R0 ; S :- (VARLENGTH + 2); SUB #2.,R0 ; MOV R0,-(SP) ; MTPI S ; MOV R0,KSR4 ;<01> B := S; MOV INTL11,R0 ; Q := INTERPRETERLENGTH + 8; ADD #8.,R0 ; MOV R0,KSR3 ;<01> .IF DF,F$PU ;<01> ONLY IF FPU IS PRESENT LDFPS #FLOA11 ; FSTATUS := FLOATSTATUS; .ENDC ;<01> MOV #PGST11,KSOPSW ; PSTATUS := PROGSTATUS; MOV #STAR11,KSOPC ; P := STARTADDR; ADD CODL11,R0 ; CONSTADDR := Q + CODELENGTH; MOV R0,CONS11 ; MOV R0,KSR0 ;<01> PASS R0 POP R0 ;<01> RESTORE R0 RTS PC ; END; ; ; ; PROCEDURE ENTRY SYSTEMERROR; ; TERM11: ; CONST TERMINATED = .ASCIZ /TERMINATED/ ; 'TERMINATED(:0:)'; OVER11: ; OVERFLOWERROR = .ASCIZ /OVERFLOW ERROR/ ; 'OVERFLOW ERROR(:0:)'; POIN11: ; POINTERERROR = .ASCIZ /POINTER ERROR/ ; 'POINTER ERROR(:0:)'; RANG11: ; RANGEERROR = .ASCIZ /RANGE ERROR/ ; 'RANGE ERROR(:0:)'; VARI11: ; VARIANTERROR = .ASCIZ /VARIANT ERROR/ ; 'VARIANT ERROR(:0:)'; HEAP11: ; HEAPLIMIT = .ASCIZ /HEAP LIMIT/ ; 'HEAP LIMIT(:0:)'; STAK11: ; STACKLIMIT = .ASCIZ /STACK LIMIT/ ; 'STACK LIMIT(:0:)'; .EVEN ; ;TEXT IS RESU19 ; VAR TEXT: LINE; ; SYST11: ; BEGIN MOV HEAD11+RESUL1,R0 ; CASE HEAD.RESULT OF ASL R0 ; MOV 1$(R0),RESU19 ; BR 2$ ; 1$: .WORD TERM11 ; 0: TEXT := TERMINATED; .WORD OVER11 ; 1: TEXT := OVERFLOWERROR; .WORD POIN11 ; 2: TEXT := POINTERERROR; .WORD RANG11 ; 3: TEXT := RANGEERROR; .WORD VARI11 ; 4: TEXT := VARIANTERROR; .WORD HEAP11 ; 5: TEXT := HEAPLIMIT; .WORD STAK11 ; 6: TEXT := STACKLIMIT; ; END; 2$: JSR PC,KERN19 ; KERNELERROR(TEXT); ; RTS PC ; END; ; ; ; PROCEDURE ENTRY REALINTERRUPT; ; RIAD11 = REALOV - USER99 ; CONST REALINTERRUPTADDR = ...; ; REAL11: ; BEGIN MOV #RIAD11,KSOPC ; REG.P := REALINTERRUPTADDR; RTS PC ; END; ; ; INIT11: ; BEGIN ; DONE AT LABEL "NEXT11". ; NEXTINDEX := 1; RTS PC ; END "OF RUNNING"; ; ; .SBTTL PROCESS INITIATION/TERMINATION ;"################################### ; # INIT/END/STOP PROCESS # ;###################################" ; ; ; PROCEDURE ENTRY INITPROCESS( ; PARAMLENGTH, ; VARLENGTH, ; STACKLENGTH, ; QVALUE: INTEGER); ; INIT13: MOV #,R0 ; BEGIN MOV (R0),PLEN11 ; MOV (R0)+,PARL11 ; MOV (R0)+,VARL11 ; MOV (R0)+,STAC11 ; MOV (R0),QVAL11 ; JSR PC,POPP11 ; RUNNING.POPPARAM(PARAMLENGTH); JSR PC,PREE11 ; READY.ENTER(RUNNING.PREEMPTED); MOV PRE11R,P12 ; JSR PC,ENTE12 ; JSR PC,INCH11 ; RUNNING.INITCHILD(PARAMLENGTH, ; VARLENGTH, ; STACKLENGTH, ; QVALUE); RTS PC ; END; ; ; ; PROCEDURE ENTRY ENDPROCESS; ; ;PROC IS PRE11R ; VAR PROC: PROCESSREF; ; ENDP14: ; BEGIN JSR PC,PREE11 ; PROC := RUNNING.PREEMPTED; RTS PC ; END; ; ; ; PROCEDURE ENTRY STOPJOB( ; P, ; WHY: INTEGER); ; ;PROC IS R1 ; VAR PROC: PROCESSREF; ;HEAD IS R1 ; HEAD: @HEADTYPE; ; STOP15: ; BEGIN MOV #,R0 ; PROC := RUNNING.PROCESSID(.P.); MOV (R0)+,R1 ; ADD R1,R1 ; MOV (R1),R1 ; CMP R1,USER11 ; IF PROC = RUNNING.USER BNE 1$ ; MOV #HEAD11,R1 ; THEN HEAD := @RUNNING.HEAD BR 2$ ; 1$: ADD #HEAD0,R1 ; ELSE HEAD := @PROC@.HEAD; 2$: ; WITH HEAD@ DO ; BEGIN MOV (R0),RESUL1(R1) ; RESULT := WHY; CLR CONTI1(R1) ; CONTINUE := FALSE "0"; ; END; RTS PC ; END; ; ; .SBTTL THE READY PROCESS QUEUES ;"################################### ; # READY # ;###################################" ; ; ; VAR READY ; CLASS ; TOP12: .BLKB .PROCQUE ; VAR TOP, MIDD12: .BLKB .PROCQUE ; MIDDLE, BOTT12: .BLKB .PROCQUE ; BOTTOM: PROCESSQUEUE; IDLI12: .WORD 0 ; IDLING: BOOLEAN; ; ; P12: .BLKB .PROCREF ; PROCEDURE ENTER(P: PROCESSREF); ; ENTE12: MOV P12,R0 ; BEGIN MOV R0,NEWEL4 ; MOV HEAD0+PRIOR1(R0),R1 ; CASE P@.HEAD.PRIORITY OF BNE 1$ ; MOV #TOP12,QUTP4T ; 0: TOP.PUT(P); JSR PC,PUT4 ; RTS PC ; 2$: MOV #BOTT12,QUTP4T ; 2: BOTTOM.PUT(P); JSR PC,PUT4 ; RTS PC ; 1$: SOB R1,2$ ; MOV #MIDD12,QUTP4T ; 1: MIDDLE.PUT(P); JSR PC,PUT4 ; RTS PC ; END; ; END; ; ; ; PROCEDURE SELECT; ; ;Q IS R0 ; VAR Q: @PROCESSQUEUE; ; SELE12: ; BEGIN TST IDLI12 ; IF NOT IDLING THEN BNE 1$ ; BEGIN 2$: ; REPEAT MOV #TOP12,R0 ; Q := @TOP; EMPTY4 R0,3$ ; IF Q@.EMPTY THEN ; BEGIN MOV #MIDD12,R0 ; Q := @MIDDLE; EMPTY4 R0,3$ ; IF Q@.EMPTY THEN ; BEGIN MOV #BOTT12,R0 ; Q := @BOTTOM; EMPTY4 R0,3$ ; IF Q@.EMPTY THEN ; BEGIN INC IDLI12 ; IDLING := TRUE; SPL 0 ; IDLE; WAIT ; SPL 7 ; CLR IDLI12 ; IDLING := FALSE; ; Q := NIL; ; END; ; END; ; END; TST USER11 ; UNTIL (RUNNING.USER <> NIL) OR BEQ 2$ ; (Q <> NIL); RTS PC ; IF (RUNNING.USER = NIL) THEN 3$: MOV R0,QUTP4T ; RUNNING.SERVE(Q@.GET); JSR PC,GET4 ; MOV GET4R,P11 ; JSR PC,SERV11 ; 1$: RTS PC ; END; ; END; ; ; ; PROCEDURE RESCHEDULE; ; RESC12: ; BEGIN ; WITH RUNNING, HEAD DO TST USER11 ; IF USER <> NIL THEN BEQ 1$ ; BEGIN JSR PC,UPDA11 ; UPDATE; TST HEAD11+PRIOR1 ; IF PRIORITY > 0 THEN BEQ 1$ ; IF MOV #TOP12,R0 ; TOP.ANY OR EMPTY4 R0,2$ ; TST HEAD11+OVERT1 ; OVERTIME OR BNE 2$ ; CMP #2.,HEAD11+PRIOR1 ; (PRIORITY = 2 AND BNE 1$ ; MOV #MIDD12,R0 ; MIDDLE.ANY) THEN ANY4 R0,1$ ; 2$: JSR PC,PREE11 ; ENTER(PREEMPTED); MOV PRE11R,P12 ; JSR PC,ENTE12 ; 1$: RTS PC ; END; ; END; ; ; ; PROCEDURE ENDIO; ; ENDI12: ; BEGIN JSR PC,RESC12 ; RESCHEDULE; ; WITH RUNNING DO TST USER11 ; IF USER <> NIL THEN BEQ 1$ ; MOV USER11,P10 ; VIRTUAL.GETMAP(USER); JSR PC,GETM10 ; 1$: RTS PC ; END; ; ; INIT12: ; BEGIN MOV #TOP12,QUTP4T ; TOP.INITIALIZE; JSR PC,INIT4 ; MOV #MIDD12,QUTP4T ; MIDDLE.INITIALIZE; JSR PC,INIT4 ; MOV #BOTT12,QUTP4T ; BOTTOM.INITIALIZE; JSR PC,INIT4 ; ; DONE AT LABEL "IDLI12". ; IDLING := FALSE; RTS PC ; END "OF READY"; ; ; .SBTTL MONITOR GATES ;"################################### ; # GATE # ;###################################" ; ; GATE = 0 ; TYPE GATE = $ = GATE ; CLASS ; OPEN15 = $ ; VAR OPEN: $ = $ + .BOOLEAN ; BOOLEAN; WAIT15 = $ ; WAITING: $ = $ + .PROCQUE ; PROCESSQUEUE; CHKDTL GATE ; ; ; ; PROCEDURE ENTRY ENTER; ; ENTE17: ; BEGIN ENTE11 ; RUNNING.ENTER; MOV ,R0 ; IF OPEN THEN DEC (R0) ; BEQ 1$ ; OPEN := FALSE ELSE CLR (R0)+ ; MOV R0,QUTP4T ; WAITING.PUT(RUNNING.PREEMPTED); JSR PC,PREE11 ; MOV PRE11R,NEWEL4 ; JSR PC,PUT4 ; 1$: RTS PC ; END; ; ; ; PROCEDURE ENTRY LEAVE; ; ;P IS GET4R, P12 ; VAR P: PROCESSREF; ; LEAV17: MOV ,R0 ; BEGIN INC (R0)+ ; ANY4 R0,1$ ; IF NOT WAITING.ANY THEN ; OPEN := TRUE ELSE MOV R0,QUTP4T ; BEGIN CLR -(R0) ; JSR PC,GET4 ; P := WAITING.GET; MOV GET4R,P12 ; READY.ENTER(P); JSR PC,ENTE12 ; ; END; 1$: LEAV11 ; RUNNING.LEAVE; RTS PC ; END; ; ; ; PROCEDURE ENTRY DELAY(VAR Q: ; PROCESSREF); ;P IS GET4R, P12 ; VAR P: PROCESSREF; ; DELA17: ; BEGIN JSR PC,PREE11 ; Q := RUNNING.PREEMPTED; MOV PRE11R,-(SP) ; $$ = HEAD11 + PARAM1 ; $$ = $$ + .INTEGER ; MTPD @$$ ; MOV ,R0 ; IF WAITING.ANY THEN INC (R0)+ ; BEGIN ANY4 R0,1$ ; MOV R0,QUTP4T ; P := WAITING.GET; CLR -(R0) ; JSR PC,GET4 ; MOV GET4R,P12 ; READY.ENTER(P); JSR PC,ENTE12 ; END ELSE 1$: ; OPEN := TRUE; RTS PC ; END; ; ; ; PROCEDURE ENTRY CONTINUE(VAR Q: ; PROCESSREF); ;P IS R1, P12 ; VAR P: PROCESSREF; ; CONT17: ; BEGIN $$ = HEAD11 + PARAM1 ; P := Q; MOV <$$ + .INTEGER>,R0 ; MFPD (R0) ; MOV (SP)+,R1 ; IF P = NIL THEN BEQ LEAV17 ; LEAVE ELSE CLR -(SP) ; BEGIN MTPD (R0) ; Q := NIL; MOV R1,P12 ; READY.ENTER(P); JSR PC,ENTE12 ; LEAV11 ; RUNNING.LEAVE; ; END; RTS PC ; END; ; ; GAT17T: .BLKB .INTEGER ; BEGIN INIT17: ENTE11 ; RUNNING.ENTER; MOV GAT17T,R0 ; CLR (R0)+ ; OPEN := FALSE; MOV R0,QUTP4T ; WAITING.INITIALIZE; JSR PC,INIT4 ; RTS PC ; END "OF GATE"; ; ; ; PROCEDURE ENTRY INITGATE(VAR G: @ ; GATE); INIT18: ; BEGIN MOV #.GATE,LENG16 ; G := NEW(GATE); JSR PC,NEW16 ; MOV NEW16R,-(SP) ; MTPD @ ; MOV NEW16R,GAT17T ; G@.INITIALIZE; JSR PC,INIT17 ; RTS PC ; END; ; ;