*********************************************************************
*M*      P2SCPU   PROCESSES :SCPU COMMAND OPTIONS & CREATES STABLES LMN
********************************************************************
*P*      NAME*        P2SCPU
*P*      PURPOSE: THE :SCPU CONTROL COMMAND ESTABLISHES THE
*P*               EXISTENCE OF A MULTIPROCESSING SYSTEM AND DEFINES THE
*P*               NUMBER AND CHARACTERISTICS OF THE SLAVE CENTRAL
*P*               PROCESSING UNITS.
*P*
*P*      METHOD   IF THE :SCPU COMMAND IS PRESENT IN THE PASS2 INPUT
*P*               COMMAND STREAM, THEN THE OPTIONS ARE PROCESSED
*P*               AND THE STABLES LOAD MODULE TABLES ARE INITIALLIZED
*P*               AND DEFED USING THE MODGEN SUBROUTINE. WHEN ALL THRU
*P*               THE 'STABLES' LOAD MODULE IS WRITTEN OUT VIA WRITELM.
*P*               IF THE SCPU OPTION IS NOT PRESENT THE STABLES
*P*               LOAD MODULE IS STILL PRODUCED, BUT WILL ONLY
*P*               CONTAIN 2 VALUE DEFS -- 'NSCPU' AND 'MAXP'
*******************************************************************
*
         SYSTEM   BPM
         SYSTEM   SIG9
*     SYMBOLIC REGISTERS
R0       EQU      0
R1       EQU      1
R2       EQU      2
R3       EQU      3
R4       EQU      4
R5       EQU      5
R6       EQU      6
R7       EQU      7
SR1      EQU      8
SR2      EQU      9
SR3      EQU      10
SR4      EQU      11
D1       EQU      12
D2       EQU      13
D3       EQU      14
D4       EQU      15
         REF      P2ABRT
         REF      SYNTAX
         REF      P2ERR
         REF      WRITELM
         REF      COREALLOC
         REF      MODGEN
         REF      READSTRG
         REF      FETCHBUF
         REF      SCPUFLG
         DEF      SCPU
         REF      BIGLOC
         REF      LOGIT
FOP      CNAME
         PROC
         GEN,1,7,8    AF(1),AF(2),AF(3)
         PEND
DYN      CNAME
         PROC
LF       EQU      %-DYNAM
         GEN,1,15,16  AF(1),AF(2),AF(3)
         PEND
KWDTBL0  EQU      %
         DATA     KWDTBL-KWDTBL0
         FOP      0,0,3          0  FIND LEFT (
         FOP      1,0,9          1  FIND KEYWORD
         FOP      1,0,10         2  PROCESS KEYWORD
         FOP      1,0,8          3  LOOK FOR ) OR ),( OR END OF COMMAND
         FOP      0,1,1          4  GO TO KWDTBL0+1
         FOP      1,3,14         5  NEXT STRING MUST BE HEX IF SO
*                                   CONVERT IT. IF NOT GO TO KWDTBL+3
         FOP      0,4,18         6  STORE IT INTO *DYNAM+4,R5
         FOP      0,3,6          7  LOOK FOR ',' IF NOT, GO TO KWDTBL0+3
         FOP      0,5,1          8  GO TO KWDTBL0+5
         FOP      1,3,13         9  NEXT STRING MUST BE DECIMAL
         FOP      0,6,18         10 STORE IT INTO *DYNAM+6,R5
         FOP      0,3,6          11 LOOK FOR ','. IF NOT GO TO KWDTBL0+3
         FOP      0,9,1          12 TO TO KDWTBL0+9
         FOP      1,3,13         13 NEXT STRING MUST BE DECIMAL
         FOP      0,8,18         14 STORE IT INTO *DYNAM+8,R5
         FOP      0,3,6          15 LOOK FOR ','. IF NOT GO TO KWDTBL0+3
         FOP      0,13,1         16 GO TO KWDTBL0+13
         FOP      1,3,13         17 NEXT STRING MUST BE DECIMAL
         FOP      0,10,18        18 STORE IT INTO *DYNAM+10,R5
         FOP      0,3,6          19 LOOK FOR ','. IF NOT GO TO KWDTBL0+3
         FOP      0,17,1         20 GO TO KWDTBL0+17
         DATA,2   0              ROUND OFF H.W. THIS IS A NOP
         PAGE
KWDTBL   EQU      %
         TEXT     'NSCPU'           NSPCU KEYWORD OPTION
         GEN,8,7,17  1,0,NSCPU
         TEXT     'NOAUTO'          NOAUTO KEYWORD OPTION
         GEN,8,8,16  0,1,(NOAUTO*4)+3   SET FLAG IF NOAUTO OPTION PRESENT
         TEXT     'MPIPI'           MPIPI KEYWORD OPTION
         GEN,8,8,16  0,1,(MPIPI*4)+3  SET FLAG IF MPIPI OPTION PRESENT
         TEXT     'INTS'            INTS KEYWORD OPTION
         GEN,8,24 8,5               GO TO KWDTBL0+5
*                                    AND STORE THEM STARTING AT INTSLOC
         TEXT     'AUTO'            AUTO KEYWORD OPTION
         GEN,8,24 8,9               GO TO KWDTBL0+9
         TEXT     'MINQ'            MINQ KEYWORD OPTION
         GEN,8,24 8,13              GO TO KWDTBL0+13
         TEXT     'MAXQ'            MAXQ KEYWORD OPTION
         GEN,8,24 8,17              GO TO KWDTBL0+17
DFLTS    DATA     #DFLT
KWDPTR   GEN,15,17    DFLTS-KWDTBL,KWDTBL0   SIZE OF KEYWORD TBL,ADDRESS
*                                            OF KEYWORD TBL.
         DATA     #DYNAM
DYNAM    EQU      %
NSCPU    DYN      1,0,3             DESTINATION OF # OF SLAVE CPU
*                                   LIMIT OF VALUE IS BETWEEN 1 & 3
NOAUTO   DYN      0,0,0             WILL BE 1 IF NOAUTO OPTION IS USED
MPIPI    DYN      0,0,0             WILL BE 1 IF MPIPI OPTION IS USED
INTSTOP  DATA     INTSEND+1         PTR TO END INTS TABLE + 1
INTSPTR  DATA     INTSLOC           PTR TO START OF INTS TBL
AUTOTOP  DATA     AUTOEND+1         PTR TO END AUTO TABLE + 1
AUTOPTR  DATA     AUTOLOC           PTR TO START OF AUTO TBL
MINQTOP  DATA     MINQEND+1         PTR TO END MINQ TABLE + 1
MINQPTR  DATA     MINQLOC           PTR TO START OF MINQ TBL
MAXQTOP  DATA     MAXQEND+1         PTR TO END MAXQ TABLE + 1
MAXQPTR  DATA     MAXQLOC           PTR TO START OF MAXQ TBL
#DYNAM   EQU      %-DYNAM
#DFLT    EQU      #DYNAM
INTSLOC  DATA     0,0               UP TO 3 VAL. EXPECTED FOR INTS OPTION
INTSEND  DATA     0
AUTOLOC  DATA     0,0               UP TO 3 VAL. EXPECTED FOR AUTO OPTION
AUTOEND  DATA     0
MINQLOC  DATA     0,0               UP TO 3 VAL. EXPECTED FOR MINQ OPTION
MINQEND  DATA     0
MAXQLOC  DATA     0,0               UP TO 3 VAL. EXPECTED FOR MAXQ OPTION
MAXQEND  DATA     0
STABLENM TEXTC    'STABLES'
SCPUNM   TEXT     'SCPU'
NOROOM   TEXTC    '*** NO CORE FOR SCPU MODULE PROCESSING.',;
                  ' STABLES LMN NOT INCLUDED'
         PZE      ERREXIT           ERR. ADDRESS FOR WRITELM & MODGEN
         PAGE
SCPU     EQU      %
         LW,R1    FETCHBUF,R3
         CW,R1     SCPUNM
         BE       ITEXISTS
*    IF NO SCPU COMMAND, THEN THE ONLY ENTRIES IN STABLES LMN ARE*
*        NSCPU SET = 0, MAXP SET = 1, MPIPI SET = 0 AND 1 TABLE
*        ENTRY CELL FOR S:ADR SET = 0.
*
*
NOSCPUCD LI,R1    0
         STW,R1   SCPUFLG,R3        SET SCPU PRESENCE FLAG TO 0
         LI,D1    36                SET FOR SIZE OF REF/DEF STACK
         LI,D2    20                SET FOR SIZE OF DATA RECORD. THESE
         BAL,SR4  COREALLOC         ARE NECESSARY INPUT TO COREALLOC
         BAL,SR3  MODGEN            NOW GO DEF THE 2 VALUES FOR STABLES
         LI,D1    0                 SET NSCPU TO A VALUE DEF OF 0
         TEXTC    'NSCPU0'          TRAILING 0 FLAGS THIS AS A VALUE DEF
         TEXTC    'MPIPI0'          SET MPIPI TO 0
         LI,D1    1                 SET MAXP TO A VALUE OF 1
         TEXTC    'MAXP0'
         TEXTC    'S:ADR1'
         AI,SR1   1
         B        %+1               GET OUT OF THE MODGEN EXECUTION
WRTLMN   LI,D3    STABLENM          D3 PTS TO THE LMN NAME OF 'STABLES'
         BAL,SR4  WRITELM           GO WRITE THE LOAD MODULE
         CI,SR1   -1                SR1 = -1 IF UNABLE TO WRITE IT
         BE       ERREXIT           IF SR1 = -1 IT'S AN ERROR
         MTW,0    SCPUFLG,R3        CHECK IF EXECUTION WENT THRU
         BEZ      READSTRG          ITEXISTS CODE. RETURN TO P2CCI IF NO
         LI,R1    -#DYNAM           REMOVE TEMP STACK LOCATIONS
         MSP,R1   *R0
         B        READSTRG          RETURN TO P2CCI
ERREXIT  MTW,1    P2ERR,R3          INCREMENT ERROR COUNT
         M:PRINT  (MESS,NOROOM)
         B        READSTRG
ITEXISTS EQU      %                 THE SCPU COMMAND EXISTS
         MTW,1    SCPUFLG,R3
         LI,R1    #DYNAM
         LI,R2    DYNAM
         LW,R4    KWDPTR
         BAL,SR4  SYNTAX
         LW,R1    NSCPU,R5          GET # OF SLAVE CPU'S
         BEZ      REPORTER          ERROR IF NO NSCPU VALUE
         CI,R1    3                 NSCPU MAY = 1 TO 3
         BE       CHKINST           SKIP ADDITIONAL CHECKS
         BL       CHKAUIN           GO CHK # OF AUTO'S & INTS SPECIFIED
         LI,R1    3
         STW,R1   NSCPU,R5          SET NSCPU TO MAX
         LI,D3    ERR2              ERROR.  TELL USER
         BAL,SR4  LOGIT
         B        CHKINST
CHKAUIN  LI,D1    0                 HERE WE CHK THAT AUTO AND INTS VAL.S
         LI,R2    3                  DO NOT EXCEED THE VAL OF NSCPU
         SW,R2    R1                R2 = # OF EMPTY TABLE SLOTS
         LI,R4    2
LOOP1    LW,SR1   AUTOLOC,R4        SEE IF INDEED EMPTY
         BEZ      %+3               O.K. IF 0
         STW,R4   AUTOFLER          SET ERROR FLAG
         STW,D1   AUTOLOC,R4        ZERO OUT TABLE CELL
         LW,SR1   INTSLOC,R4
         BEZ      %+3               O.K. IF 0
         STW,R4   INTSFLER          SET ERROR FLAG
         STW,D1   INTSLOC,R4
         AI,R4    -1
         BDR,R2   LOOP1
         MTW,0    AUTOFLER          CHK ERR FLG
         BEZ      %+3
         LI,D3    ERR3              ERROR.  TELL USER
         BAL,SR4  LOGIT
         MTW,0    INTSFLER
         BEZ      CHKINST
         LI,D3    ERR4
         BAL,SR4  LOGIT             ERROR.  TELL USER
*        HERE WE CHK TO INSURE THAT THERE ARE AS MANY INTS VAL.S
CHKINST  LW,R2    NSCPU,R5          AS THERE ARE SLAVE CPU'S.
         LI,R4    0
         LW,SR1   INTSLOC,R4
         BEZ      ABRTP2            SET A DELAYED ABORT ERROR
         AI,R4    1
         BDR,R2   %-3
AUTONDNO LW,SR1    NOAUTO,R5        CHK IF AUTO & NOAUTO BOTH SPECIFIED
         BEZ      CHKAUTO           IF ZERO,  NOAUTO WAS NOT SPECIFIED
         LW,SR1   AUTOLOC           SEE IF AT LEAST 1 AUTO SPECIFIED
         BEZ      CHKMINMX          BRANCH IF NOT BOTH SPECIFIED
         LI,D1    0
         STW,D1   NOAUTO,R5         ZAP NOAUTO AND KEEP AUTO
         LI,D3    ERR5              ERROR.  TELL USER
         BAL,SR4  LOGIT
*        HERE WE CHK FOR ANY AUTO VAL.'S IN THE 1 TO 3 RANGE
*        AND IF FOUND A BIT IS SET IN CORRESPONDING BYTE OF SBINIT.
CHKAUTO  LW,R2    NSCPU,R5          GET # OF NSCPU'S
         LI,D1    1
         LI,R4    0
LOOP2    LW,R6    AUTOLOC,R4        GET USER-SUPPLIES VALUE
         CI,R6    3                 CHECK FOR WITHIN RANGE
         BLE      %+4               BRANCH IF O.K.
         LI,D3    ERR11             ERROR.  TELL USER
         BAL,SR4  LOGIT
         B        CONTIN            AND SKIP SETTING BIT
         CI,R6    0
         BLE      CONTIN
         STB,D1   SBINIT,R6         STORE BIT IN CORRECT BYTE
CONTIN   AI,R4    1
         BDR,R2   LOOP2
*        HERE CHK THAT 9 < MINQ. THAT MAXQ < 32767.
*        AND THAT MINQ IS LESS THAN OR EQUAL TO MAXQ.
CHKMINMX LI,R6    0
         LW,R2    NSCPU,R5
         BAL,SR4  CHKCODE
         AI,R6    1
         BDR,R2   %-2
         B        WRTSTABL          GO WRITE OUT THE STABLES LMN
CHKCODE  LI,D1    10                10 = LOWER LIMIT OF VALUE
         LW,D2    MAXQLOC,R6        D2 GETS UPPER VALUE
         BEZ      GETMXDF           BR. IF MAXQLOC = 0
COMPARE  CLR,D1   MINQLOC,R6        SEE IF MINQ VAL FALLS BETWEEN
         BCS,2    USE10             10 AND MAXQ VAL. BR IF < 10
         BCR,4    CHKMAXQ           BRANCH IF COPESETIC
         LW,D2    MINQLOC,R6        NO. MAXQ IS < MINQ
         STW,D2   MAXQLOC,R6        SO MAKE MAXQ EQUAL TO MINQ
         LI,D3    ERR7
         B        LOGIT             ERROR.  TELL USER
GETMXDF  CI,R6    0                 IS THIS FOR FIRST VAL.
         BEZ      STORDEF           YES. THEN GO STORE DEFAULT
         LW,D2    MAXQLOC           NO. USE FIRST VAL FOR SUBSEQUENT
         STW,D2   MAXQLOC,R6        ONES.
         B        COMPARE
STORDEF  LI,D2    2000              2000 IS DEFAULT FOR MAXQ
         STW,D2   MAXQLOC,R6
         LI,D3    ERR8              ERROR.  TELL USER
STORDEFA PSW,SR4  *R0
         BAL,SR4  LOGIT
         PLW,SR4  *R0
         B        COMPARE
USE10    CI,R6    0
         BEZ      STOR10            BR. IF FIRST TIME AROUND
         LW,SR1   MINQLOC           OTHERWISE USE FIRST MINQ VAL.
         STW,SR1  MINQLOC,R6        FOR ALL SUBSEQUENT ONES
         B        COMPARE
STOR10   LI,SR1   10                DEFAULT MINQ TO 10
         STW,SR1  MINQLOC,R6
         LI,D3    ERR9              ERROR   TELL USER
         B        STORDEFA
CHKMAXQ  CI,D2    32767             SEE IF MAXQ IS > 32767
         BL       *SR4
         LI,D2    32767             SET MAXQ TO MAXIMUM ALLOWED
         STW,D2   MAXQLOC,R6
         LI,D3    ERR10             ERROR  TELL USER
         B        LOGIT
ABRTP2   MTW,1    P2ABRT,R3
         LI,D3    ERR6              ERROR.  TELL USER
         B        %+2
REPORTER LI,D3    ERR1
         LI,SR4   NOSCPUCD
         B        LOGIT
         PAGE
***  WRTSTABL GETS CORE TO BUILD LOAD MODULE. THEN GENERATES
***           DEFS WITH APPROPRIATE INITIAL VALUES. FINALLY
***           IT CALLS WRITLM TO WRITE IT OUT AND TO RELEASE
***           CORE WHEN FINISHED.
WRTSTABL LI,D1    -1                SET SIZE OF REFDEF STK TO UNKNOWN
         LI,D2    -1                SET SIZE OF DATA REC. TO UNKNOWN
         BAL,SR4  COREALLOC         GO GET SUFFICIENT CORE
         CI,SR1   -1                CHK FOR ENOUGH ROOM
         BE       ERREXIT           ERROR IF SR1 = -1
         BAL,SR3  MODGEN            SR1 CONTAINS START OF DATA INFO
         TEXTC    'S:PCUN1'         DEF START AS S:PCUN
         LW,R2    NSCPU,R5
         AI,R2    1                 TABLE LENGHT IS NSCPU+1
         AW,SR1   R2
         TEXTC    'SB:MPSW1'        SINCE NSCPU MAX VAL =3, TABLE
         AI,SR1   1                 IS AT LEAST 1 WORD LONG
         TEXTC    'SB:PFLG1'
         AI,SR1   1                 BYTE OR HW TBL IS AT LEAST 1 LONG
         TEXTC    'SX:SPP1'
         LW,D1    BIGLOC,R3         BIGLOC (BYTE 0) IS EITHER 1 OR 0
         LB,D1    D1                DEPENDING
*                                   ON WHETHER 'BIG' WAS SPECIFIED ON
*                                   :MON COMMAND
         SLS,D1   1                 D1 = 0 OR 2
         AW,D1    R2                ADD NSCPU+1
         SLS,D1   -2                D1 = 0 OR 1
         AW,SR1   D1                BYTE OR HW TABLE
         AI,SR1   1
         TEXTC    'SB:STATE1'
         AI,SR1   1
         LW,D1    SBINIT            GET BIT 7 BYTE SETTINGS
         STW,D1   *SR1
         TEXTC    'SB:INIT1'
         AI,SR1   1
         TEXTC    'S:CLAIM1'
         AW,SR1   R2
         TEXTC    'SB:MINT1'
         LI,R4    0
         LW,R6    NSCPU,R5
         LW,D1    INTSLOC,R4        THIS LOOP STORES INTS VALS IN *8
         AI,R4    1
         STB,D1   *SR1,R4
         BDR,R6   %-3
         AI,SR1   1                 MAX & MIN SIZE OF ENTRY = 1
         B        %+1
         LW,R1    R2
         AI,R1    1                 ROUND TO HW
         SLS,R1   -1
         LW,SR2   SR1
         AW,SR2   R1
         LI,R4    0
         LW,R6    NSCPU,R5
         LW,D1    MINQLOC,R4        THIS LOOP STORES MINQ AND MAXQ
         LW,D2    MAXQLOC,R4        VALUES IN H.W. LOCATED AT *8 & *9
         AI,R4    1
         STH,D1   *8,R4
         STH,D2   *9,R4
         BDR,R6   %-5
         BAL,SR3  MODGEN
         TEXTC    'SH:MINQ1'
         LW,SR1   SR2
         TEXTC    'SH:MAXQ1'
         AW,SR1   R1
         TEXTC    'S:ADR1'
         AW,SR1   R2
         TEXTC    'SB:SFLG1'
         AI,SR1   1
         TEXTC    'SB:RCVR1'
         AI,SR1   1
         TEXTC    'SB:RCVA1'
         AI,SR1   1
         TEXTC    'SL:BSTRT1'
         LW,D1    NOAUTO,R5
         STW,D1   *SR1
         AI,SR1   1
         LW,D1    =700000
         STW,D1   *SR1
         TEXTC    'S:STOUT1'
         AI,SR1   1
         TEXTC    'S:MPKYN1'
         AI,SR1   1
         TEXTC    'S:MPDISP1'
         AI,SR1   1
         TEXTC    'SL:MPCALR1'
         LI,R4    1
         STW,R4   *SR1
         AI,SR1   1
         TEXTC    'FB:FLT1'
         AI,SR1   1
         TEXTC    'FB:EFLG1'
         AI,SR1   1
         TEXTC    'F:EADDR1'
         AW,SR1   NSCPU,R5
         AI,SR1   1
         TEXTC    'FH:SCRCH1'
         AW,SR1   R1
         TEXTC    'F:PFSR1'
         LW,D1    MPIPI,R5
         TEXTC    'MPIPI0'
         LW,D1    NSCPU,R5
         TEXTC    'NSCPU0'
         LW,D1    R2
         TEXTC    'MAXP0'
         B        WRTLMN
ERR1     TEXTC    '*** NO VALUE FOR NSCPU THERFORE A NON-MULTI',;
                  'PROCESSING SYSTEM WILL BE GENERATED'
ERR2     TEXTC    '*** NSCPU VALUE > 3. VALUE 3 HAS BEEN USED'
ERR3     TEXTC    '*** AUTO ENTRIES EXCEED NSCPU -- EXCESS IGNORED'
ERR4     TEXTC    '*** INTS ENTRIES EXCEED NSCPU -- EXCESS IGNORED'
ERR5     TEXTC    '*** AUTO AND NOAUTO BOTH SPECIFIED -- AUTO USED'
ERR6     TEXTC    '*** INTS ENTRIES NOT EQUAL TO NSCPU -- DELAYED ABORT'
ERR7     TEXTC    '*** MAXQ VALUE IS LESS THAN CORRESPONDING MINQ ',;
                  'VALUE THEREFORE THIS MAXQ SET TO THE MINQ MATE'
ERR8     TEXTC    '*** MAXQ VALUE IS ZERO-- DEFAULTED TO 2000'
ERR9     TEXTC    '*** MINQ VALUE IS ZERO-- DEFAULTED TO 10'
ERR10    TEXTC    '*** MAXQ VALUE IS > 32767-- DEFAULTED TO 32767'
ERR11    TEXTC    '*** AN AUTO VALUE IS GREATER THAN 3. IT WILL',;
                  ' BE IGNORED.'
SBINIT   DATA     0
AUTOFLER DATA     0                 SET IF AUTO'S EXCEED NSCPU#
INTSFLER DATA     0                 SET IF INTS'S EXCCED NSCPU#
PATCH    EQU      %
         LIST     0
         DO1      50
         DATA     0
         LIST     1
         END

