        .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    $$,<HEAD99+PARAM1>  ;   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    #<PSPMDU>,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    #<HEAD11+INDEX1>,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    #<HEAD11+SLICE1>,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   <R0,R1,R2>	   ;<01> SAVE REGISTERS
        BIS    #<PSPMDU>,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    <R2,R1,R0>	   ;<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    #<HEAD11+INDEX1>,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    #<HEAD11+SLICE1>,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    #<PSPMDU>,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    #<HEAD11+PARAM1>,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    #<HEAD11+PARAM1>,R0 ;   PROC := RUNNING.PROCESSID(.P.);
        MOV    (R0)+,R1            ;
        ADD    R1,R1               ;
        MOV    <PRID11-2>(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    <HEAD11+PARAM1>,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    <HEAD11+PARAM1>,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    <HEAD11+PARAM1>,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   @<HEAD11+PARAM1>    ;
        MOV    NEW16R,GAT17T       ;   G@.INITIALIZE;
        JSR    PC,INIT17           ;
        RTS    PC                  ; END;
                                   ;
                                   ;
                                                                                                                                                                                                                                                                   