!* ! IDLES at IPL ! ***** ** *** ! ! If certain errors occurr before an OPER has been found ! CHOPSUPE can not tell the Operator. Insteads it halts with an ! Idle instruction. These signify as follows:- ! ! {(S) indicates S series only, (P) indicates P series only.} ! ! A) Idles during Booting (from Disc or Tape) ! ! F001 (P) CRESP0 zero on entry ! F002 (P) Abnormal termination ! F003 (P) SAC interrupt flags, which give trunk, zero on entry ! F004 (P) First 4 decks on IPL stream inoperable ! F005 (P) GPC microprogram load failed ! F006 (P) Connect IPL stream fails ! F007 (P) Controller detected error when reading tape ! F008 (P) More than 10 attempts to read block ! F009 (P) Backspace failed when retrying read block ! F010 (P) Rewind fails ! F011 (P) Sense fails ! F012 (P) MARK < -1 ! F013 (P) Non attention response rcvd when attn expected ! 1111 System errror on entry to CHOPSUPE ! ! ! B) Errors detected during GROPEing for devices ! ! ! ! B00B (P) OCP not 2960,2970,2980,2972 or 2976 ! B00B (S) OCP not 2950,2956 or 2966 ! 00DD (P) No operable GPC found in configuration ! 00DD (S) No operable DCU found in configuration ! 0DDD No Controllers found at all ! FF00 (P) Too many GPCs (>8) ! FF00 (S) Too many DCUs (>8) ! FF01 Too many SLOTS (>256) or supplied table too small ! FF02 Too many entries in 'RESPONSE' array ! FF03 Too many MAGTAPE streams (>32) (in 'FORM TABLES') ! FF04 Too many OPER streams (>7) (in 'FORM TABLES') ! FF05 Supplied table too small (in 'CHECKLIM') ! ! C) Errors detected after GROPE completed ! ! AAAA Normal CHOPSUPE idle (Awaiting Command from OPER) ! 3333 Imp %STOP executed (Software error) ! E00E Dump to tape completed successfully ! 12121 Dump to tape failed(Deck not known or faulty) ! CCCC Attempt to return from Procedure invoked by Activate ! ! ! D) Unexpected interrupts in CHOPSUPE ! ! 00F0 Sytem error interupt occurred (Probable OCP fault) ! 00F1 External interupt occurred (none ever expected) ! 00F2 Multi-processor interupt occurred (none ever expected) ! 00F4 Virtual Store interupt occurred (none ever expected) ! 00F6 Program error interupt occurred (S-ware or h-ware fault) ! 00F7 System Call interupt occurred (no System Calls ever made!) ! 00F8 Out interupt occurred (no Outs in code!) ! 00F9 Extracode interupt occurred (none ever expected) ! 00FA Event pending interupt occurred (none ever expected) ! 00FB Instruction Counter interupt occurred (Always masked) ! ! CONSTSTRING (3) VSN="22B" CONSTSTRING (8) VDATE="11/6/84" RECORDFORMAT PARMF(INTEGER DEST,SRCE,P1,P2,P3,P4,P5,P6) STRING (8)FNSPEC STRHEX(INTEGER N) STRING (15) FNSPEC STRINT(INTEGER N) STRINGFNSPEC HTOS(INTEGER VALUE,PLACES) ROUTINESPEC MONITOR(STRING (63) S) INTEGERFNSPEC HANDKEYS ROUTINESPEC DUMPTABLE(INTEGER T, A, L) INTEGERFNSPEC REALISE(INTEGER AD) ROUTINESPEC PKMONREC(STRING (20)TEXT,RECORD (PARMF)NAME P) ROUTINESPEC PTREC(RECORD (PARMF)NAME P) ROUTINESPEC PRHEX(INTEGER N) EXTERNALROUTINESPEC OPER(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC GDC(RECORD (PARMF)NAME P) ROUTINESPEC PRINTER(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC TAPE(RECORD (PARMF)NAME P) ROUTINESPEC OPMESS2(INTEGER OPER,STRING (63)MESS) ROUTINESPEC OPERRELAY(RECORD (PARMF)NAME P) ROUTINESPEC OPMESS(STRING (63) S) ROUTINESPEC WAIT(INTEGER MILLESECS) ROUTINESPEC COMREP(RECORD (PARMF)NAME P) ROUTINESPEC SLAVESONOFF(INTEGER MASK) ROUTINESPEC ONOFF(INTEGER OFFSET,MASK) ROUTINESPEC PARSE COM(INTEGER SRCE,STRINGNAME S) ROUTINESPEC TIMEEVAL(INTEGER FLAG) IF SSERIES=YES START ROUTINESPEC LIGHTS(INTEGER PATTERN) FINISH INTEGERFNSPEC STOI(STRINGNAME S) !----------------------------------------------------------------------- ! PON & POFF etc. declarations RECORDFORMAT PARMXF(INTEGER DEST, SRCE, P1, P2, P3, P4, P5, C P6, LINK) INTEGERFNSPEC PP INIT(RECORD (PARMXF)ARRAYNAME SPACE,INTEGER SIZE) ROUTINESPEC MORE PP SPACE ROUTINESPEC RETURN PPCELL(INTEGER CELL) ROUTINESPEC PON(RECORD (PARMF)NAME P) ROUTINESPEC POFF(RECORD (PARMF)NAME P) ROUTINESPEC INHIBIT(INTEGER SERVICE) ROUTINESPEC UNINHIBIT(INTEGER SERVICE) ! 64 services & 80 sets of parms CONSTINTEGER MAXSERV=64 CONSTINTEGER PARMCELLS=80 IF SSERIES=YES START ! !* image store addresses for S1,S2 & S3 processors !* ordered:- LSTL,LSTB,PSTL,PSTB,HKEYS,HOOTER,SIR, !* CLOCK X,Y,Z,HBIT,SLAVES,INH REPS,INH PHOTO,IT INT,IRATE,TSLICE ! CONSTINTEGER ISAS ESIZE=17 OWNINTEGERARRAY ISAS(0:ISAS ESIZE*4-1)=C X'6000',X'6001',X'6002',X'6003',X'6006',0,0, X'600C',X'600D',X'600E',0,X'00086011',0,X'00016011',2,150,X'40000', X'6000',X'6001',X'6002',X'6003',X'6006',0,6007, X'600C',X'600D',X'600E',0,X'00086011',0,0,2,300,X'30000', X'6000',X'6001',X'6002',X'6003',X'6006',0,0, X'600C',X'600D',X'600E',0,X'01C86011',X'00106011',X'00026011', 2,900,X'20000', X'6000',X'6001',X'6002',X'6003',X'6006',0,0, X'600C',X'600D',X'600E',0,X'01C86011',X'00106011',X'00026011', 2,1000,X'20000' !*** see PSD 2.5.1 & processor specs - amend when OCP types stable CONSTBYTEINTEGERARRAY ISASP(1:3,0:6)=C 0,255, 255, 255,ISAS ESIZE,2*ISAS ESIZE, 255,255, 3*ISAS ESIZE, 255,255, 255, 255,255, 255, 255,255, 255, 255,255, 3*ISAS ESIZE CONSTHALFINTEGERARRAY OCP NAME(1:4)=X'2950',X'2956',X'2966',X'2988' CONSTINTEGER VAR88=6 OWNINTEGER ISAS PTR CONSTINTEGER LSTL OFFSET=0 CONSTINTEGER LSTB OFFSET=1 CONSTINTEGER HK OFFSET=4 CONSTINTEGER SLAVES OFFSET=11 CONSTINTEGER INH REPS OFFSET=12 CONSTINTEGER INH PHOTO OFFSET=13 CONSTINTEGER ITIMER OFFSET=14 CONSTINTEGER IRATE OFFSET=15 CONSTINTEGER TSLICE OFFSET=16 CONSTINTEGER ISAS COML=12 ! FINISH ELSE START ! ! this array has the vital image store addrsess for P2,P3&P4s ! ordered as LST LIMIT,LST BASE, PST LIMIT, PST BASE,HKEYS,HOOTER, SIR, ! CLOCK X,Y,Z REGS,HOOTER BIT,SLAVES,INH REPORTS,INH PHOTO,IT INTERVAL,SMACINF RECORD, ! IRATE,TSLICE ! (SMACINF RECORD:- CONFIG REG,SMACPOS,BLOCK0 BIT,BLKSHIFT, ! BLKSPERSEG,BLKSIZE,SMACMAX,INTERLEAVE,SMAC DIAG REGS(3),SMAC ES REG,HAMMING OFF BIT ! CONSTINTEGER ISAS ESIZE=30; !ENTRY SIZE IN WORDS OWNINTEGERARRAY ISAS(0:4*ISAS ESIZE-1)=C X'6000',X'6001',X'6002',X'6003',X'6006',X'6008', X'600A',X'600C',X'600D',X'600E',1,X'00086011', X'00806011',X'00016011',2, X'4C006A20',16,X'100',1,2,X'20000',1, 0,X'4C006004',X'4C006100',X'4C006A00',X'4C006A10', X'20000000',290,X'30000', X'6000',X'6001',X'6002',X'6003',X'6006',X'6008', X'600A',X'600C',X'600D',X'600E',1,X'00086011', X'00906011',X'00016011',8, X'4C006A20',16,X'100',1,2,X'20000',15, 0,X'4C006004',X'4C006100',X'4C006A00',X'4C006A10', X'20000000',624,X'20000', X'402C',X'402A',X'402B',X'4029',X'4205',X'4013', X'4014',X'44004000',X'44004100',X'44004200',X'1000', X'08084013',X'01004013',X'01004012',8, X'4C004A20',20,X'01000000',-1,1,X'40000', 15,X'10000000',X'4C004004',X'4C004100',X'4C004A00', X'4C004A10',X'40000000',2128,X'10000', X'402C',X'402A',X'402B',X'4029',X'4205',X'4013', X'4014',X'44004000',X'44004100',X'44004200',X'1000', X'08084013',X'01004013',X'01004012',8, X'4C006A20',20,X'100',1,2,X'20000',15, 0,X'4C006004',X'4C006100',X'4C006A00',X'4C006A10', X'20000000',1400,X'10000'; ! ! THIS ARRAY HAS POINTERS TO ISAS FOR P1-P4 AND P1/1-P4/1 ! 255 MEANS THIS MACHINE NOT CATERED FOR ! CONSTBYTEINTEGERARRAY ISASP(1:4,0:1)=C 255,0,ISAS ESIZE,2*ISAS ESIZE, 255,255,255,3*ISAS ESIZE; OWNINTEGER ISAS PTR CONSTINTEGER SMACINF OFFSET=15 CONSTINTEGER ITIMER OFFSET=14 CONSTINTEGER HK OFFSET=4 CONSTINTEGER SLAVES OFFSET=11 CONSTINTEGER LSTL OFFSET=0 CONSTINTEGER LSTB OFFSET=1 CONSTINTEGER ISAS COML=12 CONSTINTEGER INH REPS OFFSET=12 CONSTINTEGER INH PHOTO OFFSET=13 CONSTINTEGER IRATE OFFSET=28 CONSTINTEGER TSLICE OFFSET=29 CONSTINTEGER IRATE2972=1050; ! different for 2972 RECORDFORMAT SMACF(INTEGER CONFREG,SMACPOS,BLOCK0,BLKSHIFT, C BLKSPERSEG,BLKSIZE,SMACMAX,INTERLEAVE,SDR1,SDR2,SDR3, C SESR,HOFFBIT) FINISH !* !* Communications record format - extant from CHOPSUPE 22B onwards * !* RECORDFORMAT COMF(INTEGER OCPTYPE,SLIPL,SBLKS,SEPGS,NDISCS,DLVNADDR, C (INTEGER GPCTABSIZE,GPCA OR INTEGER DCUTABSIZE,DCUA), C INTEGER SFCTABSIZE,SFCA,SFCK,DIRSITE, C DCODEDA,SUPLVN,TOJDAY,DATE0,DATE1,DATE2, C TIME0,TIME1,TIME2,EPAGESIZE,USERS,CATTAD,SERVAAD, C BYTEINTEGER NSACS,RESV1, C (BYTEINTEGER SACPORT1,SACPORT0 OR BYTEINTEGER C OCP1 SCU PORT,OCP0 SCU PORT), BYTEINTEGER C NOCPS,SYSTYPE,OCPPORT1,OCPPORT0,INTEGER ITINT, C (INTEGER CONTYPEA,GPCCONFA,FPCCONFA,SFCCONFA OR C INTEGER DCU2HWNA,DCUCONFA,MIBA,SP0), C INTEGER BLKADDR,RATION, C (INTEGER SMACS OR INTEGER SCUS), C INTEGER TRANS,LONGINTEGER KMON, C INTEGER DITADDR,SMACPOS,SUPVSN,PSTVA,SECSFRMN,SECSTOCD, C SYNC1DEST,SYNC2DEST,ASYNCDEST,MAXPROCS,INSPERSEC,ELAPHEAD, C COMMSRECA,STOREAAD,PROCAAD,SFCCTAD,DRUMTAD,TSLICE,FEPS, C MAXCBT,PERFORMAD,BYTEINTEGER DAPNO,DAPBLKS,DAPUSER,DAPSTATE, C INTEGER DAP1,DAPBMASK,SP1,SP2,SP3, C LSTL,LSTB,PSTL,PSTB,HKEYS,HOOT,SIM,CLKX,CLKY,CLKZ, C HBIT,SLAVEOFF,INHSSR,SDR1,SDR2,SDR3, C SDR4,SESR,HOFFBIT,BLOCKZBIT,BLKSHIFT,BLKSIZE,END) ! ! This format describes "The Communication Record" which is kept ! locked in store at Public address X'80C00000'. It is readable at ! all ACR levels but writeable at ACR 1 only. Its purpose is to describe ! the hardware on which the EMAS System is running. Each entry is now ! described in more detail:- ! ! OCPTYPE The 2900 Processor on this configuration as follows ! 1 = 2950 (S1) ! 2 = 2960 (P2) or 2956 (S2) ! 3 = 2970 (P3) or 2966 (S3) ! 4 = 2980 (P4) ! 5 = 2972 or non-interleaved 2976 (P4/1) ! 6 = Interleaved 2976 (P4/1) ! ! SLIPL bit 0 is set to 1 to force an AUTO IPL from RESTART. ! bits 1-15 are the SLOAD lvn & site >>4. ! (equivalent to the handkey settings for AUTO IPL). ! bits 16-31 are thehe port/trunk/stream(or DCU/stream) of the ! device used at IPL time. ! SBLKS The no of 128k blocks of main store present ! SEPGS The no of extended pages for paging(ie not including ! any pages occupied by resident code & data). ! NDISCS Then number of EDS drives avaliable ! DLVNADDR The address of an array which maps disc lvns to ! their ddt slots. ! GPCTABSIZE The size in bytes of the GPC (or DCU) table ! GPCA The address of the GPC (or DCU) table ! SFCTABSIZE The size of the SFC(ie DRUM) table ! SFCA The address of the SFC table ! SFCK The number of (useable) 1K page frames of Drum store ! available for paging.(0 = No drum configuration) ! DIRSITE The Director site address(eg X200) no longer reqd? ! DCODEDA The Disc Address of the Director (expressed as ! SUPLVN<<24!DIRSITE) ! SUPLVN The logical volume no of the disc from which the ! Sytem was "SLOADED". Various System components (eg ! DIRECT, VOLUMS will page from here ! ! TOJDAY Todays (Julien) day number. ! DATE0} These three integers define the current date(updated at ! DATE1} at 2400) as a character string such that ! DATE2} the length byte is in the bottom of DATE0 ! ! TIME0} These three integers define the clock time as a string ! TIME1} in the same format as for DATE. The time is updated ! TIME2} about every 2 seconds ! ! EPAGESIZE The number of 1K pages combined together to make up ! the logical "Extended Page" used in Emas.Currently=4 ! USERS The number of user processes (foreground+background) ! currently in existence.Includes DIRECT,VOLUMS&SPOOLR ! CATTAD Address of maxcat followed by category table. ! SERVAAD The address of the service array SERVA. ! NSACS The number of sacs found at grope time ! SACPORT1} Holds the Port no of the Store Access Controller(s) ! SACPORT0} found at grope time. SACPORT0 was used to IPL system. ! NOCPS The number of OCPS found at grope time. ! SYSTYPE System infrastructure: ! 0 = SMAC based ! 1 = SCU based (SCU1) ! 2 = SCU based (SCU2) ! OCPPORT1} Hold the Port no of the OCPs found at grope time. ! OCPPORT0} OCPPORT0 was used to IPL the system. ! ITINT The Interval Timer interval in microsecs. Varies ! between different members of the range ! CONTYPEA The address of a 31 byte area containing the codes ! of the controllers in port-trunk order. Codes are:- ! 0 = Not relevant to EMAS ! 1 = SFC1 ! 2 = FPC2 ! 3 = GPC1 ! ! GPCCONFA} These three variables each point to a word array ! FPCCONFA} containing controller data. The first word in each ! SFCCONFA} case says how many controllers on the system. The ! remainder have Port&Trunk in top byte and Public ! segment no of comms segment in bottom byte. For GPCS ! the Public Seg no is apparently omitted! ! BLKADDR The address of first element of a word array bounds ! (1:SBLKS) containing the real address of each 128K ! block of main store. Real addresses are in the form ! RSN/SMAC NO/Address in SMAC ! RATION Information maintained by DIRECT concerning access ! rationing. Bytes from left indicate scarcity, ! pre-empt point, zero and interactive users ! respectively ! SMACS Bits 0-15 are a map of SMACS in use by the system. ! 2**16 bit set if SMAC0 in use etc. ! Bits 16-31 are a map of SMACS found at grope time. ! 2**0 bit set if SMAC0 found etc. ! TRANS The address of a 768 byte area containing 3 translate ! tables. The first is ISO to EBCDIC, the second the ! exact converse & the third is ISO to ISO with ! lower to upper case conversion. ! KMON A 64 bit bitmask controlling monitoring of Kernel ! services. Bit 2**n means monitor service n. Bits can ! be set by Operator command KMON. ! DITADDR Disc index table address. The address of first ! element of an array(0:NDISCS-1) containing the address ! of the disc device entries. ! SMACPOS The no of places that the Smac no must be left ! shifted to be in the right position to access ! a Smac image store location. Incredibly this varies ! between the 2980 and others!! ! SUPVSN The Supervisor id no as a three char string eg 22A ! PSTVA The virtual address of the Public Segment table which ! is itself a Public segment. All other information ! about PST can be found by looking at its own PST entry ! SECSFRMN The no of Seconds since midnight. Updated as for TIME ! SECSTOCD The number of seconds to System closedown if positive ! If zero or negative no close down time has yet been ! notified. Updated as for TIME ! SYNC1DEST} These are the service nos N2,N3 & N4 for process ! SYNC2DEST} parameter passing described in Supervisor Note 1 ! ASYNCDEST} ! MAXPROCS The maximum number of paged processes that the ! Supervisor is configured to run. Also the size ! of the Process array. ! INSPERSECS The number of instructions the OCP executes in 1 ! second divided by 1000(Approx average for EMAS) ! ELAPHEAD The head of a linked list of param cells holding ! service with an elapsed interval interrupt request ! outstanding ! COMMSRECA The address of an area containing details of the ! Communication streams.(private to COMMS Control) ! STOREAAD The address of first element of the store record array ! bounds (0:SEPGS-1) ! PROCAAD The address of first element of the process record ! array bounds(0:MAXPROCS) ! SFCCTAB} The addresses of two private tables provided by grope ! DRUMTAD} for use by the routine DRUM. They give details of ! the SFCS and DRUMS found on the system ! TSLICE Time slice in microsecs. Supervisor has to allow for ! differences in interval timer speeds accross the range ! FEPS Bits 0-15 are a map of FEPs found at grope time. ! 2**16 bit set if FE0 found etc. ! Bits 16-31 are a map of currently available FEPs. ! 2**0 bit set if FE0 available etc. ! MAXCBT Maximum cbt entry ! PERFORMAD Address of record holding timing information and counts ! for performance analysis. ! DAPNO SMAC number for the DAP ! DAPBLKS The number of 128K blocks in DAP ! DAPUSER The PROCESS currently holding the DAP ! DAPSTATE The state of the DAP ! DAP1 DAP control fields ! DAPBMASK Bit map of currently allocated DAP blocks ! SP1->SP3 Spare locations ! LSTL} ! LSTB} ! PSTL} ! PSTB} These are the image store addresses for the following ! HKEYS} control registers:- ! HOOT} Local Segment Table Limit & Base ! SIM } Public Segment Table Limit & Base ! CLKX} Handkeys,Hooter System Interrupt Mask Register ! CLKY} and the clock X,Y & Z Registers ! CLKZ} ! HBIT A bit pattern that when ORed into Control Register ! "HOOT" operates the Hooter.(0=Hooterless machine) ! SLAVEOFF A bit pattern (top 16 bits) and Image store address ! in bottom 16 bits. ORing the top 16 bits(after ! shifting) into the image store will stop all slaving of ! operands but not instructions ! INHSSR A bit pattern and image location as for SLAVEOFF. ! ORing the bits into the location will switch off ! reporting of successful system retry ! SDR1} ! SDR2} The image store addresses of SMAC internal registers ! SDR3} needed by the Engineers after Smac errors have ! SDR4} occurred ! SESR} ! HOFFBIT A bit pattern that when ORed into a Smac Engineers ! status register will stop reporting of error ! from that Smac ! ! BLOCKZBIT A bit pattern indicating the position of ! the block zero bit in the SMAC config register. ! ! BLKSHIFT Indicates which way to shift the BLOCKZBIT mask ! to correspond with subsequent store blocks. ! ! BLKSIZE Store block size. ! CONSTRECORD (COMF)NAME COM=X'80000000'!48<<18 RECORDFORMAT PARMAF(INTEGER DEST, SRCE, INTEGERARRAY P(1:6)) CONSTINTEGER PCELLSIZE=36; ! PARM cell size EXTERNALINTEGER FEP MAP EXTERNALLONGINTEGER PARMDES EXTERNALINTEGER PARMASL,PARMAD RECORDFORMAT SERVF(INTEGER P, L) OWNRECORD (SERVF)ARRAY SERVA(0:MAXSERV) OWNRECORD (PARMXF)ARRAYNAME PARM OWNINTEGER KERNELQ, SERVICE OWNINTEGER OCPTYPE OWNINTEGER OCPVAR CONSTINTEGER EPAGESPERBLOCK=32,EPBYTES=EPAGESIZE*1024 CONSTINTEGER DITSIZE=4,MAIN LP SIZE=X'4000' IF SSERIES=NO START CONSTINTEGER DDTSIZE=128,DCONSIZE=672 FINISH CONSTLONGINTEGER SUPACR=1,DIRACR=2,ALLACR=15,PRIVACR=5 CONSTLONGINTEGER WSUPRDIR=SUPACR<<56!DIRACR<<52 CONSTLONGINTEGER WSUPRSUP=SUPACR<<56!SUPACR<<52 CONSTLONGINTEGER WDIRRDIR=DIRACR<<56!DIRACR<<52 CONSTLONGINTEGER WDIRRPRIV=DIRACR<<56!PRIVACR<<52 CONSTLONGINTEGER WDIRRALL=DIRACR<<56!ALLACR<<52 CONSTLONGINTEGER WSUPRPRIV=SUPACR<<56!PRIVACR<<52 CONSTLONGINTEGER NONSLAVED=X'2000000000000000' OWNINTEGER IST VA CONSTINTEGER REAL0ADDR=X'80000000'!64<<18 CONSTINTEGER UNDUMPSEG=X'80000000'!10<<18 CONSTINTEGER GROPESEG=UNDUMPSEG EXTERNALLONGINTEGER KMON=0 OWNINTEGER POFFMON=0 OWNINTEGER STORE BLOCKS, STORE EPAGES EXTERNALINTEGER NDISCS,HI STRM CONSTINTEGER BA SIZE=128; ! ALLOW 16 MEG OWNINTEGERARRAY BLOCK ADDR(0:BA SIZE-1) IF SSERIES=YES START OWNINTEGERARRAY DCUCONF(0:7) CONSTINTEGER CONF LENGTH=32 CONSTINTEGER DCU2HWNL=64 OWNBYTEINTEGERARRAY DCU2HWN(0:DCU2HWNL-1) OWNINTEGER FOOTPRINT FINISH ELSE START OWNINTEGERARRAY GPCCONF(0:7) OWNINTEGERARRAY FPCCONF(0:7) OWNINTEGERARRAY SFCCONF(0:7) CONSTINTEGER CONF LENGTH=96 CONSTINTEGER CONTYPEL=32 OWNBYTEINTEGERARRAY CONTYPE(0:CONTYPEL-1) FINISH CONSTINTEGER DLVN SIZE=100 IF SSERIES=YES START RECORDFORMAT ENTFORM(INTEGER C SER, PTSM, PROPADDR, SECS SINCE, CAA, GRCB AD, C BYTE INTEGER LAST ATTN, DACTAD, HALF INTEGER HALFSPARE, C INTEGER LAST TCB ADDR, C STATE, PAW, RESP1, SENSE1, SENSE2, SENSE3, SENSE4, C REPSNO, BASE, ID, DLVN, MNEMONIC, C STRING (6) LABEL, BYTE INTEGER HWCODE, C INTEGER ENTSIZE, URCB AD, SENSDAT AD, LOGMASK, TRTAB AD, C UA SIZE, UA AD, TIMEOUT,PROPS0,PROPS1) FINISH ELSE START RECORDFORMAT DDTFORM(INTEGER SER, PTS, PROPADDR, STICK, CCA, RQA, C LBA, ALA, STATE, IW1, CONCOUNT, SENSE1, SENSE2, SENSE3, C SENSE4, REPSNO, BASE, ID, DLVN, MNEMONIC, C STRING (6) LAB, BYTEINTEGER MECH, C INTEGER PROPS,STATS1,STATS2, C BYTEINTEGER QSTATE,PRIO,SP1,SP2, C INTEGER LQLINK,UQLINK,CURCYL,SEMA,TRLINK,CHFISA) RECORDFORMAT ENTFORM(INTEGER C SER, PTSM, PROPADDR, SECS SINCE, CAA, GRCB AD, LBA, ALA, C STATE, RESP0, RESP1, SENSE1, SENSE2, SENSE3, SENSE4, C REPSNO, BASE, ID, DLVN, MNEMONIC, C ENTSIZE, PAW, USAW0, URCB AD, SENSDAT AD, LOGMASK, TRTAB AD, C UA SIZE, UA AD, TIMEOUT,PROPS0,PROPS1) FINISH CONSTINTEGER PROP LENGTH=5*40 OWNINTEGERARRAY PROPERTIES(0:PROP LENGTH//4-1)=C 19,404,3,4096,23028,40,256,344,4,20, C { EDS100 } 19,808,3,4096,46056,40,256,344,4,20, C { EDS200 } 5,808,4,4096,16160,40,256,344,4,6, C { EDS80 } 10,816,9,4096,36720,40,256,344,4,4, C { FDS160 } 40,830,9,4096,149400,40,256,344,4,4 { FDS640 } !* !* FDS devices have 4.5 pages per track formatted thus:- !* !* Even numbered tracks - 4K 4K 4K 4K 2K !* Odd numbered - 2K 4K 4K 4K 4K !* !* So that _PPERTRK (currently 9) is the number of pages in an even/odd !* track pair !* CONSTBYTEINTEGERARRAY HEXDS(0:15)='0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F' CONSTBYTEINTEGERARRAY SERV TAB(1:64)= C 0,0,0,4,5,6,0(3),10,0(6), C 0(15),32, C 33,34,35,36,37,38,0(8),47,48, C 49,50,51,0,0,54,0(3),58,59,0,0,62,0,0 ! ! MASTER RESIDENT TRANSLATE TABLES FOR EMAS2900 ! CONSTINTEGER TRTAB SIZE=256 CONSTBYTEINTEGERARRAY ITOETAB(0 : 255) = C X'00',X'01',X'02',X'03', X'37',X'2D',X'2E',X'2F', X'16',X'05',X'25',X'0B', X'0C',X'0D',X'0E',X'0F', X'10',X'11',X'12',X'13', X'3C',X'3D',X'32',X'26', X'18',X'19',X'3F',X'27', X'1C',X'1D',X'1E',X'1F', X'40',X'4F',X'7F',X'7B', X'5B',X'6C',X'50',X'7D', X'4D',X'5D',X'5C',X'4E', X'6B',X'60',X'4B',X'61', X'F0',X'F1',X'F2',X'F3', X'F4',X'F5',X'F6',X'F7', X'F8',X'F9',X'7A',X'5E', X'4C',X'7E',X'6E',X'6F', X'7C',X'C1',X'C2',X'C3', X'C4',X'C5',X'C6',X'C7', X'C8',X'C9',X'D1',X'D2', X'D3',X'D4',X'D5',X'D6', X'D7',X'D8',X'D9',X'E2', X'E3',X'E4',X'E5',X'E6', X'E7',X'E8',X'E9',X'4A', X'E0',X'5A',X'5F',X'6D', X'79',X'81',X'82',X'83', X'84',X'85',X'86',X'87', X'88',X'89',X'91',X'92', X'93',X'94',X'95',X'96', X'97',X'98',X'99',X'A2', X'A3',X'A4',X'A5',X'A6', X'A7',X'A8',X'A9',X'C0', X'6A',X'D0',X'A1',X'07', X'20',X'21',X'22',X'23', X'24',X'15',X'06',X'17', X'28',X'29',X'2A',X'2B', X'2C',X'09',X'0A',X'1B', X'30',X'31',X'1A',X'33', X'34',X'35',X'36',X'08', X'38',X'39',X'3A',X'3B', X'04',X'14',X'3E',X'E1', X'41',X'42',X'43',X'44', X'45',X'46',X'47',X'48', X'49',X'51',X'52',X'53', X'54',X'55',X'56',X'57', X'58',X'59',X'62',X'63', X'64',X'65',X'66',X'67', X'68',X'69',X'70',X'71', X'72',X'73',X'74',X'75', X'76',X'77',X'78',X'80', X'8A',X'8B',X'8C',X'8D', X'8E',X'8F',X'90',X'9A', X'9B',X'9C',X'9D',X'9E', X'9F',X'A0',X'AA',X'AB', X'AC',X'AD',X'AE',X'AF', X'B0',X'B1',X'B2',X'B3', X'B4',X'B5',X'B6',X'B7', X'B8',X'B9',X'BA',X'BB', X'BC',X'BD',X'BE',X'BF', X'CA',X'CB',X'CC',X'CD', X'CE',X'CF',X'DA',X'DB', X'DC',X'DD',X'DE',X'DF', X'EA',X'EB',X'EC',X'ED', X'EE',X'EF',X'FA',X'FB', X'FC',X'FD',X'FE',X'FF' CONSTBYTEINTEGERARRAY ETOITAB(0 : 255) = 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26, 32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33, 38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94, 45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63, 186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34, 195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201, 202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208, 209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237, 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243, 92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255; CONSTBYTEINTEGERARRAY UPPER CASE ISO(0 : 255) = C 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, C 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, C 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, C 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, C 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, C 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, C 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, C 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127, C 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,C 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,C 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,C 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,C 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,C 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,C 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,C 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 !----------------------------------------------------------------------- RECORDFORMAT CATTABF(BYTEINTEGER PRIORITY,EPLIM,RTLIM,MOREP,MORET, C LESSP,SP0,SUSP,RQTS1,RQTS2,STROBEI,SP2) CONSTINTEGER MAXCAT=20 OWNBYTEINTEGERARRAY CATDATA(0:12*MAXCAT+11)= C 1, 0, 0, 0, 0, 0,'F', 0, 1,1, 0,0, 1,90, 8, 15,16, 0,'F',10, 1,1, 0,1, 1,90, 8, 18,18, 0,'B',14, 1,1, 0,2, 1,20, 4, 6, 4, 0,'F', 3, 1,1, 0,3, 4,20,48, 8, 4, 0,'F', 3, 1,2, 0,4, 5,20,64, 9, 5, 0,'B',13, 2,2, 0,5, 2,32, 4, 10, 7, 3,'F', 6, 1,1, 0,6, 3,32,48, 11, 8, 4,'F', 6, 1,2, 0,7, 4,32,64, 12, 8, 4,'F', 6, 2,2, 8,8, 5,32,80, 14, 9, 5,'B',13, 2,2, 10,9, 2,64, 4, 15,11, 6,'F',10, 1,1, 0,10, 3,64,48, 16,12, 7,'F',10, 1,2, 0,11, 4,64,48, 17,12, 8,'F',10, 2,2, 4,12, 2,64, 8, 18,14, 5,'B',13, 1,2, 0,13, 5,64,64, 18,14, 9,'B',13, 2,2, 8,14, 3,128,4, 19,16,10,'F',15, 1,1, 0,15, 3,128,48, 19,17,11,'F',15, 1,2, 0,16, 4,128,24, 19,17,12,'F',15, 2,2, 3,17, 5,128,32, 20,18,14,'B',13, 2,2, 4,18, 3,128,8, 19,19,16,'F',15, 1,1, 1,19, 5,128,32, 20,20,18,'B',13, 1,2, 4,20; ROUTINE CHOP29 IF SSERIES=YES START INTEGER DCU TAB SIZE,SCU MAP INTEGER CONFIG TABLE,CONFIG LENGTH INTEGER OCP0 SCU PORT,OCP1 SCU PORT,MIBA CONSTINTEGER CONFIG SEG=49 FINISH ELSE START INTEGER GPC TAB SIZE,SMAC MAP INTEGER SFC TAB SIZE,SFCK,IPL SAC PORT,OTHER SAC PORT,NSACS,SFCA FINISH INTEGER COM SEG SIZE,NOCPS,IPL OCP PORT,REMOTE OCP PORT,CLOCK PORT,NJ INTEGER I,J,K,IPLDEV,LAST REAL BYTE,TOP BLOCK,NEXT COM SEG,AUTO SLOAD,SYSPARM INTEGER SYSTEM STORE BLOCKS LONGINTEGER L,ACT1,ACT2 !----------------------------------------------------------------------- ! IST entry format etc. RECORDFORMAT ISTF(INTEGER LNB, PSR, PC, SSR, SF, IT, IC, SP) RECORD (ISTF)NAME IST RECORD (ISTF) SAVE IST CONSTLONGINTEGERARRAYNAME PST=PST VA !----------------------------------------------------------------------- SWITCH SERVROUT(1:64); ! services>64 are user processes IF SSERIES=NO START SWITCH CONROUT(0:3); ! controller type FINISH RECORD (PARMF) P RECORD (PARMAF) PA ! interrupt routine specs ROUTINESPEC ITIMER !----------------------------------------------------------------------- ! service routine specs IF SSERIES=YES START EXTERNALROUTINESPEC DCU GROPE(RECORD (PARMF)NAME P) FINISH ELSE START EXTERNALROUTINESPEC GPC GROPE(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC DISC GROPE(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC DRUM GROPE(RECORD (PARMF)NAME P) FINISH EXTERNALROUTINESPEC DISC(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC DLABEL(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC FORMAT(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC RANDREAD(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC MOVE(RECORD (PARMF)NAME P) EXTERNALROUTINESPEC PDISC(RECORD (PARMF)NAME P) ROUTINESPEC GET EPAGE(RECORD (PARMF)NAME P) ROUTINESPEC RETURN EPAGE(RECORD (PARMF)NAME P) ROUTINESPEC CONFIG ROUTINESPEC GET REAL CORE(INTEGERNAME BYTE) ROUTINESPEC LOAD SUP(RECORD (PARMF)NAME P) ROUTINESPEC ACTIVATE SUP ROUTINESPEC NULL SERVICE(RECORD (PARMF)NAME P) INTEGERFNSPEC FIND GAP(INTEGER N) !----------------------------------------------------------------------- ! process inormation array decs etc. RECORD (PARMXF)ARRAY PARMSPACE(0:PARMCELLS) INTEGERARRAY GROPE SPACE(0:1023) IF SSERIES=YES START RECORD (ENTFORM)NAME DDT FINISH ELSE START RECORD (DDTFORM)NAME DDT RECORD (SMACF)NAME SMACINF INTEGERARRAY ONLINE(0:15) FINISH INTEGERARRAY DDT SPACE,SPEC PAGE(0:1023) !----------------------------------------------------------------------- ! initialise IST (after decs LNB & SF valid) *LSS_(3); ! current(ie IPL) OCP in SSR *USH_-26 *AND_3; *ST_IPL OCP PORT IST VA=X'80000000'!IPL OCP PORT<<18 IF SSERIES=YES THEN LIGHTS(X'2900FACE') IST==RECORD(IST VA); ! IST base *STLN_I IST_LNB=I IST_PSR=X'00140001'; ! ACR=1, PRIV=1, PM=0, ACS=1 IST_SSR=X'0180382E'; ! IM=382E (synch. ints. unmasked) !DIG & ISR added 14/09/78 *STSF_I IST_SF=I IST_IT=0 IST_IC=0 IST_SP=0 FOR I=IST VA+X'20',X'20',IST VA+X'1A0' CYCLE RECORD(I)<-IST REPEAT IST_SF=IST_SF+X'1000'; ! syserr SF beyond current frames ! insert PCs *LXN_IST VA *JLK_<IST1I> *LSS_TOS *ST_(XNB +2) *JLK_<IST2I> *LSS_TOS *ST_(XNB +10) *JLK_<IST3I> *LSS_TOS *ST_(XNB +18) *JLK_<IST4I> *LSS_TOS *ST_(XNB +26) *JLK_<IST5I> *LSS_TOS *ST_(XNB +34) *JLK_<IST6I> *LSS_TOS *ST_(XNB +42) *JLK_<IST7I> *LSS_TOS *ST_(XNB +50) *JLK_<IST8I> *LSS_TOS *ST_(XNB +58) *JLK_<IST9I> *LSS_TOS *ST_(XNB +66) *JLK_<IST10I> *LSS_TOS *ST_(XNB +74) *JLK_<IST11I> *LSS_TOS *ST_(XNB +82) *JLK_<IST12I> *LSS_TOS *ST_(XNB +90) *JLK_<IST13I> *LSS_TOS *ST_(XNB +98) *JLK_<IST14I> *LSS_TOS *ST_(XNB +106) !----------------------------------------------------------------------- ! initialise PON & POFF etc. *LSS_(16) *ST_J OCPTYPE=J>>4&15 OCPVAR=J&15 ISAS PTR=ISASP(OCPTYPE,OCPVAR) IF ISAS PTR=255 THEN START *IDLE_X'B00B' FINISH IF SSERIES=YES START OCP0 SCU PORT=J>>24 I=OCP0 SCU PORT<<22 *LB_X'601D'; *LSS_I; *ST_(0+B ); ! report errors to this OCP *LB_X'602B'; *LSS_0; *ST_(0+B ); ! unset selective masks *LB_X'6011'; *LSS_(0+B ); *OR_1; *ST_(0+B ); ! mini photos only I=OCPVAR IF I=VAR88 THEN I=4 FOOTPRINT=OCPNAME(I)<<16 LIGHTS(FOOTPRINT!X'FACE') FINISH ONOFF(INH REPS OFFSET,0); !turn off retry reporting IF SSERIES=NO AND OCPTYPE=4 START ; ! turn off hamming reporting in SMAC0 SMACINF==RECORD(ADDR(ISAS(ISAS PTR+SMACINF OFFSET))) J=SMACINF_SESR K=SMACINF_HOFFBIT *LB_J; *LSS_(0+B ); *OR_K; *ST_(0+B ) FINISH SYSPARM=0 SAVE IST=IST; ! take any masked syserrs IST_SSR=X'0180FFFE' *JLK_<HOFF> *LSS_TOS *ST_I IST_PC=I *LSS_X'0180FFFE' *ST_(3) ->NOMSE; ! none outstanding HOFF: *JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_SYSPARM NOMSE: IST=SAVE IST PARMAD=PP INIT(PARMSPACE,PARMCELLS) FOR I=0,1,1023 CYCLE SPEC PAGE(I)=0; GROPE SPACE(I)=0 REPEAT KERNELQ=0 REMOTE OCP PORT=0 NOCPS=1; ! default is nothing dualled IF SSERIES=YES START OCP1 SCU PORT=0 MIBA=0 FINISH ELSE START OTHER SAC PORT=0 NSACS=1 FINISH P=0 PA=0; ACT1=0; ACT2=0 !----------------------------------------------------------------------- ! initialise control OPER INHIBIT(47); ! hold OPER messages OPMESS("CHOPSUPE ".VSN." ".VDATE) UNLESS SYSPARM=0 THEN OPMESS("SYSERR parm=".STRHEX(SYSPARM)) IF SSERIES=YES START IPLDEV=INTEGER(8) OPMESS("S".HTOS(OCPTYPE,1)."/".HTOS(OCPVAR,1). C " IPLed from ".HTOS(IPLDEV,3)) FINISH ELSE START IPLDEV=INTEGER(8) OPMESS("P".HTOS(OCPTYPE,1)."/".HTOS(OCPVAR,1). C " IPLed from ".HTOS(IPLDEV,3)) IPL SAC PORT=IPLDEV>>8 FINISH AUTO SLOAD=INTEGER(12); ! zero or AUTO SLOAD parms ! ! turn off slaving for grope as PST and IST being changed ! SLAVESONOFF(0) IF SSERIES=NO AND OCPTYPE=2 START ! inhibit stops & photos on 2960 *LSS_X'11001'; *ST_(X'6011') FINISH !----------------------------------------------------------------------- ! CONFIG; ! grope store,controllers, etc. J=MAIN LP SIZE; ! set up main LP buffer IF SSERIES=NO AND OCPTYPE=3 START ; ! 2970 GET REAL CORE(J) I=LAST REAL BYTE FINISH ELSE START ; ! use overlay area J=J-128 I=X'4000' FINISH PST(63)=WSUPRSUP!X'080000001'+I+LENGTHENI(J)<<32 BYTEINTEGER(X'80FC0000')=12 ! perform the GPC/DCU grope GROPE SPACE(0)=0 IF SSERIES=YES THEN J=DCU CONF(0) ELSE J=GPC CONF(0) IF J=0 START ; ! no GPCs/DCUs - we are snookered! *IDLE_X'0DDD' FINISH FOR I=1,1,J CYCLE P_DEST=1 P_P2=ADDR(GROPE SPACE(0)) P_P3=GROPESEG P_P4=1023; ! grope space limit IF SSERIES=YES START P_P1=DCU CONF(I) P_P5=CONFIG TABLE DCU GROPE(P) FINISH ELSE START P_P1=GPC CONF(I)>>24 GPC GROPE(P) FINISH REPEAT ; ! for all attached GPCs/DCUs P_DEST=3 P_P2=ADDR(GROPE SPACE(0)) P_P4=1023; ! grope space limit ! form the tables IF SSERIES=YES START DCU GROPE(P) DCU TAB SIZE=4*GROPE SPACE(0)+4 NJ=DCU CONF(0) K=NJ FINISH ELSE START GPC GROPE(P) GPC TAB SIZE=4*GROPE SPACE(0)+4 NJ=GPC CONF(0) K=NJ FINISH FOR I=1,1,K CYCLE J=GROPE SPACE(I+23); ! required comm area size GET REAL CORE(J) PST(NEXT COM SEG)=X'080000001'!WDIRRPRIV!NONSLAVED+ C LENGTHENI(J)<<32+LAST REAL BYTE P_DEST=2 P_P2=ADDR(GROPE SPACE(0)) P_P3=GROPESEG P_P4=X'80000000'+NEXT COM SEG<<18 IF SSERIES=YES START P_P1=DCU CONF(I) P_P5=CONFIG TABLE P_P6=ADDR(DDT SPACE(0)) DCU GROPE(P) DCU CONF(I)=DCU CONF(I)!NEXT COM SEG<<16 IF P_P1#0 THEN OPMESS("DCU ".HTOS(DCU CONF(I)>>8&15,2). C " flag=".HTOS(P_P1,8)) AND NJ=NJ-1 FINISH ELSE START J=GPC CONF(I)>>24 P_P1=J GPC GROPE(P) IF P_P1#0 THEN OPMESS("GPC ".HTOS(J,2)." RI res=". C HTOS(P_P1,8)) AND NJ=NJ-1 FINISH NEXT COM SEG=NEXT COM SEG+1 REPEAT IF NJ=0 START ; ! no operable GPCs/DCUs *IDLE_X'0DD' FINISH IF SSERIES=NO START NJ=FPCCONF(0) IF NJ=0 THEN ->SKDISC FOR I=1,1,NJ CYCLE P_DEST=0 P_P1=FPCCONF(I)>>24 P_P2=ADDR(DDT SPACE(0)) J=NDISCS DISC GROPE(P) J=(NDISCS-J)*DCONSIZE+(32+16*(HI STRM+1)) J=(J+255)&X'FFFFFF00'; ! commcn area size J=512 IF J<512 GET REAL CORE(J) PST(NEXT COM SEG)=X'080000001'!WDIRRDIR!NONSLAVED+ C LENGTHENI(J)<<32+LAST REAL BYTE FPCCONF(I)=FPCCONF(I)!HI STRM<<16+NEXT COM SEG NEXT COM SEG=NEXT COM SEG+1 REPEAT SKDISC: ! perform the drum grope K=GROPE SPACE(0)+4 SFC TAB SIZE=0; SFCK=0 GROPE SPACE(K)=0 NJ=SFC CONF(0) ->SKSFC IF NJ=0; ! no drum configuration FOR I=1,1,NJ CYCLE P_DEST=1; P_P1=SFC CONF(I)>>24; ! SFC port&trunk P_P2=ADDR(GROPE SPACE(K)) P_P3=GROPESEG DRUM GROPE(P) J=P_P6 CONTINUE IF J=0; ! no drums on SFC GET REAL CORE(J) PST(NEXT COM SEG)=X'080000001'!WDIRRDIR!NONSLAVED+ C LENGTHENI(J)<<32+LAST REAL BYTE SFC CONF(I)=SFC CONF(I)+NEXT COM SEG NEXT COM SEG=NEXT COM SEG+1 REPEAT SFCK=P_P5; ! drum size in kilobytes FOR I=1,1,SFC CONF(0) CYCLE CONTINUE IF SFC CONF(I)&X'FFFF' = 0 P_DEST=2; P_P1=SFC CONF(I)>>24 P_P2=ADDR(GROPE SPACE(K)) P_P3=GROPESEG P_P4=(SFC CONF(I)&X'FFFF')<<18!X'80000000' DRUM GROPE(P) REPEAT SFC TAB SIZE=4*GROPE SPACE(K)+4 SFCA=ADDR(GROPE SPACE(K)) SKSFC: FINISH ! calculate comm area size & fill it J=((ADDR(COM_END)-ADDR(COM_OCPTYPE))+ C PROP LENGTH+ C (NDISCS*DITSIZE+31))&(-32) +C (BA SIZE*4+ C 12*(MAXCAT+1)+4+ C DLVN SIZE+ C (TRTAB SIZE*3+31))&(-32) IF SSERIES=YES START J=J+ C (DCU TAB SIZE+31)&(-32)+ C CONF LENGTH+DCU2HWNL FINISH ELSE START J=J+ C (NDISCS*DDTSIZE+31)&(-32)+ C (GPC TAB SIZE+31)&(-32)+ C (SFC TAB SIZE+31)&(-32)+ C CONF LENGTH+CONTYPEL FINISH COM SEG SIZE=J GET REAL CORE(J) PST(48)=WDIRRALL!X'080000001'+LAST REAL BYTE+LENGTHENI(J)<<32 PST(48)=PST(48)!NONSLAVED IF NOCPS>1 COM=0 IF SSERIES=NO AND OCPTYPE=4 AND OCPVAR=1 START ; ! 2972 or 2976 *LSS_(X'4469'); ! inspect interleaved state *ST_I IF I>>28=0 START OCPTYPE=5; ! 2972 or non-interleaved 2976 ISAS(ISAS PTR+IRATE OFFSET)=IRATE2972 FINISH ELSE OCPTYPE=6; ! interleaved 2976 FINISH IF SSERIES=YES AND OCPVAR=VAR88 THEN OCPTYPE=4 COM_OCPTYPE=OCPTYPE COM_SLIPL=IPLDEV COM_SBLKS=STORE BLOCKS COM_SEPGS=STORE EPAGES COM_NDISCS=NDISCS COM_NOCPS=NOCPS *LSS_(16); *USH_-16; *AND_255; *ST_J COM_SYSTYPE=J COM_OCPPORT0=IPL OCP PORT COM_OCPPORT1=REMOTE OCP PORT COM_DIRSITE=X'200' COM_EPAGESIZE=EPAGESIZE COM_FEPS=FEP MAP<<16; ! set by GPC/DCU grope STRING(ADDR(COM_SUPVSN))=VSN; ! for compatability check COM_PSTVA=PST VA COM_INSPERSEC=ISAS(ISAS PTR+IRATE OFFSET) COM_TSLICE=ISAS(ISAS PTR+TSLICE OFFSET) COM_ITINT=ISAS(ISAS PTR+ITIMER OFFSET); ! interval timer interval FOR I=0,1,ISAS COML CYCLE ; ! copy in image store addrs INTEGER(ADDR(COM_LSTL)+4*I)=ISAS(ISAS PTR+LSTL OFFSET+I) REPEAT IF SSERIES=YES START COM_DCU TAB SIZE=DCU TAB SIZE COM_SCUS=SCU MAP COM_OCP0 SCU PORT=OCP0 SCU PORT COM_OCP1 SCU PORT=OCP1 SCU PORT COM_MIBA=MIBA FINISH ELSE START COM_GPC TAB SIZE=GPC TAB SIZE COM_NSACS=NSACS COM_SACPORT0=IPL SAC PORT COM_SACPORT1=OTHER SAC PORT COM_SMACS=SMAC MAP SMACINF==RECORD(ADDR(ISAS(ISAS PTR+SMACINF OFFSET))) COM_SMACPOS=SMACINF_SMACPOS COM_SDR1=SMACINF_SDR1 COM_SDR2=SMACINF_SDR2 COM_SDR3=SMACINF_SDR3 COM_SDR4=SMACINF_CONFREG COM_SESR=SMACINF_SESR COM_HOFFBIT=SMACINF_HOFFBIT COM_BLOCKZBIT=SMACINF_BLOCK0 COM_BLKSHIFT=SMACINF_BLKSHIFT COM_BLKSIZE=SMACINF_BLKSIZE FINISH ! ! P4 clocks set clock port no in image store address and also unmask ! external interupts for that port. note SSR mask still prevents ! any RTC interrupts till main sup activated ! IF SSERIES=NO AND OCPTYPE>3 START K=CLOCK PORT<<20 COM_CLKX=COM_CLKX!K COM_CLKY=COM_CLKY!K COM_CLKZ=COM_CLKZ!K I=X'80000000'>>CLOCK PORT *LSS_(X'4012') *OR_I *ST_(X'4012') FINISH K=ADDR(COM_END) FOR I=0,1,PROP LENGTH//4-1 CYCLE INTEGER(K)=PROPERTIES(I) K=K+4 REPEAT IF SSERIES=NO START I=0 J=K WHILE I<(DDTSIZE//4)*NDISCS CYCLE INTEGER(K)=DDTSPACE(I) K=K+4 I=I+1 REPEAT FINISH COM_DITADDR=K I=0 WHILE I<NDISCS CYCLE IF SSERIES=YES THEN INTEGER(K)=DDT SPACE(I) ELSE INTEGER(K)=J+I*DDTSIZE K=K+4; I=I+1 REPEAT K=(K+31)&(-32) I=0 WHILE I<NDISCS CYCLE DDT==RECORD(INTEGER(COM_DITADDR+4*I)) DDT_PROPADDR=DDT_PROPADDR+ADDR(COM_END) I=I+1 REPEAT ! copy in the GPC/DCU table IF SSERIES=YES THEN COM_DCUA=K ELSE COM_GPCA=K FOR I=0,1,GROPE SPACE(0) CYCLE INTEGER(K)=GROPE SPACE(I) K=K+4 REPEAT K=(K+31)&(-32) IF SSERIES=YES START COM_DCUCONFA=K FOR I=0,1,7 CYCLE INTEGER(K)=DCU CONF(I) K=K+4 REPEAT COM_DCU2HWNA=K FOR I=0,1,DCU2HWNL-1 CYCLE BYTEINTEGER(K)=DCU2HWN(I) K=K+1 REPEAT FINISH ELSE START COM_SFC TAB SIZE=SFC TAB SIZE COM_SFCA=K; COM_SFCK=SFCK IF SFCK>0 THEN START FOR I=0,1,INTEGER(SFCA) CYCLE INTEGER(K)=INTEGER(SFCA) K=K+4; SFCA=SFCA+4 REPEAT K=(K+31)&(-32) FINISH COM_GPCCONFA=K FOR I=0,1,7 CYCLE INTEGER(K)=GPCCONF(I) K=K+4 REPEAT COM_FPCCONFA=K FOR I=0,1,7 CYCLE INTEGER(K)=FPCCONF(I) K=K+4 REPEAT COM_SFCCONFA=K FOR I=0,1,7 CYCLE INTEGER(K)=SFCCONF(I) K=K+4 REPEAT COM_CONTYPEA=K FOR I=0,1,CONTYPEL-1 CYCLE BYTEINTEGER(K)=CONTYPE(I) K=K+1 REPEAT FINISH COM_BLKADDR=K FOR I=0,1,BA SIZE-1 CYCLE ; ! leave room for 16 meg. INTEGER(K)=BLOCK ADDR(I) K=K+4 REPEAT COM_TRANS=K J=ADDR(ITOETAB(0)) FOR NJ=0,1,2 CYCLE FOR I=0,1,TRTAB SIZE//4-1 CYCLE INTEGER(K)=INTEGER(J) J=J+4 K=K+4 REPEAT J=ADDR(ETOITAB(0)) IF NJ=1 THEN J=ADDR(UPPER CASE ISO(0)) REPEAT ! ! amend category table now core size is known and copy it in to com seg ! INTEGER(K)=MAXCAT COM_CATTAD=K K=K+4 J=CAT DATA(12*MAXCAT+1); ! core size for thrashing IF STORE BLOCKS>16 THEN J=J+STORE BLOCKS-16 J=200 IF J>200; ! for enormous machines CATDATA(12*MAXCAT+1)=J CATDATA(12*(MAXCAT-1)+1)=J FOR J=0,1,12*MAXCAT+11 CYCLE BYTEINTEGER(K)=CAT DATA(J) K=K+1 REPEAT ! COM_DLVNADDR=K FOR I=0,1,DLVN SIZE-1 CYCLE BYTEINTEGER(K)=254 K=K+1 REPEAT ! ! set up public 19 as a readonly zero epage using top 1k of restart ! stack 4 times over. ! J=PST(6)&X'3FF80'!X'C00' FOR I=0,1,EPAGESIZE-1 CYCLE INTEGER(X'81000000'-16+J+4*I)=X'80000001'!J REPEAT PST(19)=X'40F00F8080000001'!(J-16) *LDTB_X'18000400' *LDA_X'81000000' *INCA_J *MVL_L =DR ,0,0; ! clear it INTEGER(UNDUMPSEG)=-1; ! initialise P_P2=0; ! no process picture space P_DEST=X'300002' IF SSERIES=YES THEN P_P1=COM_DCUA ELSE P_P1=COM_GPCA GDC(P) IF SSERIES=NO START UNLESS NDISCS=0 START P_DEST=1 P_P2=COM_FPCCONFA P_P3=COM_DITADDR P_P4=NDISCS DISC GROPE(P) P_DEST=0 DISC(P) FINISH IF INTEGER(COM_SFCCONFA)>1 START ; ! tidy drum table P_DEST=3 P_P2=COM_SFCA DRUM GROPE(P) FINISH FINISH P_DEST=X'360000' PRINTER(P) !----------------------------------------------------------------------- ! initialise RTC and timing scalars I=COM_CLKZ *LSS_0; *LB_I; *ST_(0+B ); ! clear clock Z reg COM_DATE0=8; COM_TIME0=8 COM_DATE1=M'00/0' COM_DATE2=M'0/00' COM_TIME1=M'00.0' COM_TIME2=M'0.00' TIMEEVAL(1); ! evaluate time&date *LSS_X'140001' ; ! allow prog errors *ST_(1) IF AUTO SLOAD=0 THEN AUTO SLOAD=HANDKEYS>>16&X'7FFF'; ! lvn/site of Supervisor IF SSERIES=YES THEN LIGHTS(FOOTPRINT!X'C0DA') SERVE: *LSS_X'382E' ; ! allow synch. interrupts *ST_(3) !----------------------------------------------------------------------- ! supervisor service loop CYCLE IF KERNELQ=0 THEN EXIT ; ! go to do useful work SERVICE=SERVA(KERNELQ)_L NEXT: IF SERVA(SERVICE)_P>0 START ; ! if service is unihibited ! pass all params on list P_DEST=SERVICE<<16 POFF(P) IF POFFMON#0 THEN C PKMONREC("Service ".STRINT(SERVICE)." called",P) IF SERVICE>64 OR SERV TAB(SERVICE)=0 C THEN NULL SERVICE(P) AND ->NEXT ->SERVROUT(SERVICE) FINISH ! remove this service from Q IF SERVICE=KERNELQ THEN KERNELQ=0 C ELSE SERVA(KERNELQ)_L=SERVA(SERVICE)_L SERVA(SERVICE)_L=0 REPEAT !----------------------------------------------------------------------- *LSS_X'826'; ! allow synch. & peripheral interrupts *ST_(3) *LSS_X'382E'; ! mask IC,IT,PERI,M-P&EXTRN *ST_(3) UNINHIBIT(47); ! let OPER messages go *LSS_X'826'; ! peri int back in *ST_(3) I=1000000//COM_ITINT; ! wait a second *LSS_I *ST_(5) *LSS_X'806' *ST_(3); ! allow IT interupts *IDLE_X'AAAA' ->SERVE !----------------------------------------------------------------------- ! service routine calls SERVROUT(4): NULL SERVICE(P); ->NEXT SERVROUT(5): GET EPAGE(P); ->NEXT SERVROUT(6): RETURN EPAGE(P); ->NEXT SERVROUT(10): ->NEXT SERVROUT(32): DISC(P) ->NEXT SERVROUT(33): PDISC(P); ->NEXT SERVROUT(34): RANDREAD(P); ->NEXT SERVROUT(35): DLABEL(P); ->NEXT SERVROUT(36): SERVROUT(37): MOVE(P); ->NEXT SERVROUT(38): FORMAT(P); ->NEXT SERVROUT(47): OPER RELAY(P); ->NEXT SERVROUT(48): GDC(P) ->NEXT SERVROUT(49): TAPE(P); ->NEXT SERVROUT(50): SERVROUT(51): OPER(P); ->NEXT SERVROUT(54): PRINTER(P); ->NEXT SERVROUT(58): ACTIVATE SUP; ->NEXT SERVROUT(59): LOAD SUP(P); ->NEXT SERVROUT(62): COMREP(P); ->NEXT !----------------------------------------------------------------------- ! interrupt entry points ! system error IST1I:*JLK_TOS ; ! entry point is link PC i.e. next instr *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP>; ! set up SSN+1 seg for tape dump *IDLE_X'F0' ->SERVE !----------------------------------------------------------------------- ! external IST2I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F1' !----------------------------------------------------------------------- ! multiprocessor IST3I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F2' ->SERVE !----------------------------------------------------------------------- ! peripheral IST4I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I IF SSERIES=YES START P_DEST=X'300003' P_P1=I GDC(P) FINISH ELSE START *LB_X'44000000'; *ADB_I; *LSS_(0+B ); ! IS #44P00000 int flags *ST_J P_SRCE=0 FOR K=0,1,15 CYCLE IF J&(X'80000000'>>K)#0 THEN START P_P1=I>>16+K; ! port trunk ->CONROUT(CONTYPE(P_P1)) CONROUT(2): ! discs P_DEST=X'200003'; DISC(P) ->CONTINUE CONROUT(3): ! GPCs P_DEST=X'300003'; GDC(P) ->CONTINUE CONROUT(1): ! SFC CONROUT(0): ! not valid OPMESS("INT on port trunk ".HTOS(P_P1,2)."??") FINISH CONTINUE: REPEAT FINISH ->SERVE !----------------------------------------------------------------------- ! virtual store IST5I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F4' ->SERVE !----------------------------------------------------------------------- ! interval timer IST6I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; ! parameter undefined ITIMER ->SERVE !----------------------------------------------------------------------- ! program error IST7I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F6' ->SERVE !----------------------------------------------------------------------- ! system call IST8I:*JLK_TOS *STD_L I=0 *JLK_<UNDUMP> *IDLE_X'F7' ->SERVE !----------------------------------------------------------------------- ! OUT IST9I:*JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F8' ->SERVE !----------------------------------------------------------------------- ! extracode IST10I: *JLK_TOS *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'F9' ->SERVE !----------------------------------------------------------------------- ! event pending IST11I: *JLK_TOS *LSS_TOS ; *LSS_TOS ; ! parameter undefined I=0 *JLK_<UNDUMP> *IDLE_X'FA' ->SERVE !----------------------------------------------------------------------- ! instruction counter IST12I: *JLK_TOS *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'FB' ->SERVE !----------------------------------------------------------------------- ! primitive IST13I: *JLK_TOS *LSS_TOS ; *ST_I *JLK_<UNDUMP> *IDLE_X'FC' ->SERVE !----------------------------------------------------------------------- ! UNIT IST14I: *JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I IF SSERIES=YES START K=UT VA+(I&X'FFFF')*64; ! unit table entry J=DCU2HWN(INTEGER(K+8)>>24)<<24!(INTEGER(K+8)>>8&255) ! h/w no./00/00/strm K=I>>16&15; ! int. sub-class IF K=1 THEN J=J!X'400' ELSE C IF K=4 THEN J=J!X'00204000' C ELSE IF K#0 THEN ->SERVE P_DEST=X'300003' P_P1=J P_P2=I GDC(P) FINISH ELSE START *JLK_<UNDUMP> *IDLE_X'FD' FINISH ->SERVE !----------------------------------------------------------------------- !%ROUTINE UNDUMP !%INTEGER J,K UNDUMP: IF SSERIES=YES START !LIGHTS(FOOTPRINT!X'D1ED!) J=FOOTPRINT!X'D1ED'; ! avoid disturbing stack frame *LB_X'6016'; *LSS_J; *ST_(0+B ) FINISH INTEGER(UNDUMPSEG)=I INTEGER(UNDUMPSEG+4)=X'80B80000' J=ISAS(ISAS PTR+LSTL OFFSET) *LB_J *LSS_(0+B ) *ST_K INTEGER(UNDUMPSEG+8)=K J=ISAS(ISAS PTR+LSTB OFFSET) *LB_J *LSS_(0+B ) *ST_K INTEGER(UNDUMPSEG+12)=K *J_TOS !%END !* !******************************************************************** !----------------------------------------------------------------------- ROUTINE GET EPAGE(RECORD (PARMF)NAME P) !*********************************************************************** !* Gets an extended (4k) page. Frigged version for CHOPSUPE * !*********************************************************************** CONSTINTEGER GESNO=X'50000' P_P2=999; ! frigged index no P_P4=ADDR(SPEC PAGE(0)); ! virtual address INHIBIT(GESNO>>16); ! CHOPSUPE has only 1 page P_DEST=P_SRCE P_SRCE=GESNO IF P_DEST#0 THEN PON(P) END ROUTINE RETURN EPAGE(RECORD (PARMF)NAME P) !*********************************************************************** !* Returns a 4k page. Frigged for CHOPSUPE which only has 1 page * !*********************************************************************** CONSTINTEGER GESNO=X'50000' IF P_P2#999 THEN OPMESS("Bum page returned") UNINHIBIT(GESNO>>16) END ROUTINE GET REAL CORE(INTEGERNAME BYTES) !*********************************************************************** !* Allocates real core from top of store updating epage count * !* rounding to next 256 byte boundary if not a multiple of 256 * !* and resetting 'BYTES' to bound for segment table * !*********************************************************************** INTEGER I TOP BLOCK=TOP BLOCK-1 C WHILE LAST REAL BYTE<BLOCK ADDR(TOP BLOCK); !align on relevant block BYTES=(BYTES+255)&X'FFFFFF00' REGET: I=LAST REAL BYTE LAST REAL BYTE=I-BYTES IF LAST REAL BYTE>=BLOCK ADDR(TOP BLOCK) OR C BLOCK ADDR(TOP BLOCK)-X'20000'=BLOCK ADDR(TOP BLOCK-1) START STORE EPAGES=STORE EPAGES-(I//(EPAGESIZE*1024)- C LAST REAL BYTE//(EPAGESIZE*1024)) BYTES=BYTES-128 RETURN FINISH STORE EPAGES=STORE EPAGES-(I//(EPAGESIZE*1024)- C BLOCK ADDR(TOP BLOCK)//(EPAGESIZE*1024)); !discard useless chunk TOP BLOCK=TOP BLOCK-1 LAST REAL BYTE=BLOCK ADDR(TOP BLOCK)+X'20000' ->REGET END INTEGERFN FIND GAP(INTEGER GAP) !*********************************************************************** !* Used by routine 'LOAD SUP' to see if there is a contiguous * !* area at the top of store for the supervisor GLA or code * !* (Only called if OCP is not a P3) * !*********************************************************************** INTEGER STORE BLOCK STORE BLOCK=TOP BLOCK LOOK: IF LAST REAL BYTE-BLOCK ADDR(STORE BLOCK)>=GAP C THEN RESULT =0; !gap found IF BLOCK ADDR(STORE BLOCK-1)>>18&X'3F'=0 C THEN RESULT =1; !next block is SMAC/SCU 0 block 0/1 IF BLOCK ADDR(STORE BLOCK)-X'20000'#BLOCK ADDR(STORE BLOCK-1) C THEN RESULT =1; !next block discontiguous !or in next SMAC/SCU STORE BLOCK=STORE BLOCK-1 ->LOOK END CONSTINTEGER CODESEG=8,GLASEG=9 CONSTINTEGER CODEAD=X'80000000'!CODESEG<<18,GLAAD=X'80000000'!GLASEG<<18 ROUTINE LOAD SUP(RECORD (PARMF)NAME P) !*********************************************************************** !* Reads down a supervisor from the disc to top of store * !* P_P1=lvn !* P_P2=start page on disc * !*********************************************************************** CONSTINTEGER PDISCSNO=X'210000', LSNO=X'3B0000' SWITCH INACT(0:3) STRING (23) LOADMSG INTEGER SIZE INTEGER ACT INTEGER I OWNINTEGER DEV, PAGE, COUNT, CODESIZE, GLASIZE, DONT ENTER OWNINTEGER J,BASE PAGE,PT REALAD OWNLONGINTEGER PAGIT ACT=P_DEST&255 ->INACT(ACT) INACT(0): ! request DEV=P_P1 IF DEV<0 THEN OPMESS("Give disc lvn") AND RETURN PAGIT=0 COM_SUPLVN=DEV COM_DCODEDA=COM_DIRSITE&X'FFFF'!DEV<<24 BASE PAGE=P_P2 PAGE=P_P2 DONT ENTER=P_P3 P_P2=DEV<<24!PAGE P_P3=ADDR(SPEC PAGE(0)) P_SRCE=LSNO!1 PONIT:P_DEST=PDISCSNO+1 PON(P) RETURN INACT(1): ! header page read IF P_P2#0 THEN ->TRANS FAIL CODESIZE=(SPEC PAGE(6)-SPEC PAGE(1)+4095)&X'7FFFF000' GLA SIZE=(SPEC PAGE(0)-SPEC PAGE(6)+4095)&X'7FFFF000' UNLESS 0<CODESIZE<256*1024 C THEN OPMESS("Bad header") AND RETURN ! ! Deal with GLA first then code. If not continuous space or we ! have a P3 with funny address translation h-w have a paged segment ! otherwise unpaged ! IF (SSERIES=NO AND OCPTYPE=3) OR FIND GAP(GLA SIZE)#0 START PAGIT=4 SIZE=GLASIZE//1024*4; !page table size FINISH ELSE SIZE=GLA SIZE GET REAL CORE(SIZE) PT REALAD=LAST REAL BYTE PST(GLASEG)=WSUPRDIR!X'080000001'!PAGIT<<60+LAST REAL BYTE+ C LENGTHENI(GLASIZE-128)<<32 IF NOCPS>1 THEN PST(GLASEG)=PST(GLASEG)!NONSLAVED COUNT=0 PAGE=PAGE+(CODESIZE+(1024*EPAGESIZE-1))//(1024*EPAGESIZE) C +(GLASIZE+(1024*EPAGESIZE-1))//(1024*EPAGESIZE)-1 ! round to 1K boundary if paged IF PAGIT#0 THEN C LAST REAL BYTE=LAST REAL BYTE&X'FFFFFC00' AND C J=(X'81000000'+PT REALAD)!(GLASIZE+(1024*EPAGESIZE-1)) C //(1024*EPAGESIZE)*EPAGESIZE*4 ! GLA to be contiguous GPAG: IF PAGIT#0 START ; ! fill in page table I=EPAGESIZE*1024 GET REAL CORE(I) J=J-EPAGESIZE*4 FOR I=0,4,EPAGESIZE*4-4 CYCLE INTEGER(J+I)=X'80000001'!LAST REAL BYTE+I*256 REPEAT FINISH P_SRCE=LSNO!3 P_P1=COUNT P_P2=DEV<<24!(PAGE-COUNT) P_P3=GLAAD+(GLASIZE-EPAGESIZE*1024)-1024*EPAGESIZE*COUNT P_P6=J ->PONIT INACT(3): ! GLA page read IF P_P2#0 THEN ->TRANS FAIL COUNT=COUNT+1 IF COUNT*(EPAGESIZE*1024)<GLASIZE THEN ->GPAG ! ! Have read all the GLA pages. Now start on the code ! IF (SSERIES=NO AND OCPTYPE=3) OR FIND GAP(CODESIZE)#0 START PAGIT=4 SIZE=CODESIZE//1024*4; !page table size FINISH ELSE SIZE=CODESIZE AND PAGIT=0 ! P3 or insufficient contiguous core ! ! Set up code segment table entry (public 8) ! GET REAL CORE(SIZE) PT REALAD=LAST REAL BYTE PST(CODESEG)=WSUPRDIR!X'080000001'!PAGIT<<60 C +LAST REAL BYTE+LENGTHENI(CODESIZE-128)<<32 PAGE=BASE PAGE COUNT=0 IF PAGIT#0 THEN LAST REAL BYTE=LAST REAL BYTE&X'FFFFFC00' CPAG: IF PAGIT#0 START ; ! code is paged I=EPAGESIZE*1024 GET REAL CORE(I); !for code page J=(X'81000000'+PT REALAD)+COUNT*EPAGESIZE*4 FOR I=0,4,EPAGESIZE*4-4 CYCLE INTEGER(J+I)=X'80000001'!LAST REAL BYTE+I*256 REPEAT FINISH P_SRCE=LSNO!2 P_P2=DEV<<24!(PAGE+COUNT) P_P3=CODEAD+EPAGESIZE*1024*COUNT ->PONIT INACT(2): ! code page read IF P_P2#0 THEN ->TRANS FAIL COUNT=COUNT+1 IF COUNT*(EPAGESIZE*1024)<CODESIZE THEN ->CPAG PST(CODESEG)=PST(CODESEG)!!LENGTHENI(X'11')<<56;! flip ex/wr permit bits ! ! Having changed permission bits must clear address trans slave ! easiest done by reloading PSTB ! I=COM_PSTB; *LB_I *LSS_(0+B ); *ST_(0+B ) COM_SLIPL=COM_SLIPL!DEV<<24!BASEPAGE>>4<<16; ! remember SLOAD lvn/site LOADMSG="Supervisor loaded" UNLESS SSERIES=YES OR SYSTEM STORE BLOCKS=STORE BLOCKS THEN C LOADMSG=LOADMSG."-SMAC0" OPMESS(LOADMSG) IF DONT ENTER=0 THEN P_DEST=X'3A0000' AND PON(P) !activate sup RETURN TRANSFAIL: OPMESS("Load failed") END ROUTINE ACTIVATE SUP !*********************************************************************** !* Create the store array in segment 23 then activate the * !* supervisor in code segment 8. * !*********************************************************************** CONSTINTEGER MAX EPAGES=EPAGES PER BLOCK*8*16; ! 16 megabytes CONSTINTEGER STOREFSIZE=12; ! store array recsize CONSTINTEGER MAX PT SIZE=(MAX EPAGES*STOREFSIZE+1023)//1024*4; ! max store array page table size CONSTINTEGER SASEG=23; ! PST 23 RECORDFORMAT STOREF(BYTEINTEGER FLAGS,USERS, C HALFINTEGER LINK,BLINK,FLINK,INTEGER REALAD) RECORD (STOREF)ARRAYFORMAT STOREAF(0:MAX EPAGES) CONSTRECORD (STOREF)ARRAYNAME STORE=X'80000000'!SASEG<<18+MAX PT SIZE RECORDFORMAT REGF(INTEGER LNB,PSR,PC,SSR,SF,IT,IC,LTB,XNB,B,C DR0,DR1,LONGLONGREAL ACC) CONSTINTEGER SSN=4 CONSTRECORD (REGF)NAME REGS=X'80000000'!(SSN+1)<<18 INTEGER I,J,K,REAL AD,EPDISP,FSTASL,BSTASL,SSNB,TOTAL EPAGES *STSF_I I=(I<<1)>>19+1; ! current SSN+1 REAL AD=PST(I)&X'FFFFF80'; ! and its real address REAL AD=REAL AD+128; ! in case this rt craps!! PST(SSN+1)=WSUPRSUP!X'00080000001'+REAL AD REAL AD=REAL AD+256; ! room for 2 SSN+1s for duals SSNB=(X'3FC00'+REAL AD)&(-EPBYTES)-REAL AD; ! TOS on epage boundary PST(SSN)=WSUPRPRIV!X'080000001'!LENGTHENI(SSNB-128)<<32+REAL AD IF NOCPS>1 THEN PST(SSN)=PST(SSN)!NONSLAVED ! ! Set up the registers in (SSN+1) ! REGS=0 REGS_LNB=X'80000000'+SSN<<18+4; !align stack frame REGS_SF=REGS_LNB+28; ! five words +2 1word params REGS_PSR=X'0014FF01'; ! PRIV=1,ACS=1,ACR=1 REGS_SSR=X'0180FFFF'; ! all masked, VA mode EPDISP=INTEGER(CODEAD+28) REGS_DR0=X'B0000001' REGS_DR1=GLAAD+EPDISP REGS_PC=INTEGER(REGS_DR1+4) UNLESS REGS_PC&X'FFFC0000'=CODEAD THEN C OPMESS("SUP has a bad EP") AND RETURN ! Set up the 4word activate parameter in two long integers ACT1=X'01FC000000008080'; ! 127<<(18+32)+LST REAL ADDR ACT2=X'80000000'!SSN<<18 TOTAL EPAGES=STORE BLOCKS*EPAGES PER BLOCK I=((TOTAL EPAGES- C ((TOTAL EPAGES*STOREFSIZE+MAX PT SIZE+EPBYTES-1)//EPBYTES))* C STOREFSIZE+MAX PT SIZE+1023)&(-1024); ! pt + store array GET REAL CORE(I) LAST REAL BYTE=LAST REAL BYTE&(-EPBYTES); ! to page boundary PST(SASEG)=WSUPRPRIV!X'4000000080000001'+LAST REAL BYTE+ C LENGTHENI(I)<<32 PST(SASEG)=PST(SASEG)!NONSLAVED IF NOCPS>1 J=X'81000000'+LAST REAL BYTE FOR I=0,4,(I+128+1023)//1024*4-4 CYCLE ; ! fill in page table INTEGER(J+I)=X'80000001'!LAST REAL BYTE+I*256 REPEAT COM_SEPGS=TOTAL EPAGES FOR I=0,1,TOTAL EPAGES-1 CYCLE ; ! set real addresses into store array STORE(I)=0 STORE(I)_USERS=255; ! system store J=I//EPAGES PER BLOCK STORE(I)_REALAD=BLOCK ADDR(J)! C (EPAGESIZE*(I-J*EPAGES PER BLOCK))<<10 REPEAT FSTASL=(SSNB+REAL AD)//EPBYTES; ! first free epage J=FSTASL BSTASL=TOTAL EPAGES-1 K=BLOCK ADDR(SYSTEM STORE BLOCKS-1)+X'20000'; ! end of supervisor store FOR I=FSTASL+1,1,BSTASL CYCLE ; ! forward links IF LAST REAL BYTE<=STORE(I)_REALAD<K THEN CONTINUE ; ! supvsr store IF SSERIES=NO AND OCPTYPE>=4 START ; ! preserve SMAC1 photo area if P4 IF STORE(I)_REALAD=X'400000' OR C (STORE(I)_REALAD=X'401000' AND NOCPS>1) C THEN CONTINUE FINISH STORE(J)_FLINK=I J=I REPEAT UNLESS J=I THEN BSTASL=J; ! supvsr at end of store STORE(BSTASL)_FLINK=0 STORE(FSTASL)_BLINK=0 I=FSTASL; ! set up blinks K=1; ! free epages UNTIL I=BSTASL CYCLE J=I STORE(I)_USERS=0; ! not system store I=STORE(I)_FLINK STORE(I)_BLINK=J K=K+1 REPEAT STORE(I)_USERS=0 STORE(0)_LINK=K; ! free epages STORE(0)_FLINK=FSTASL; ! for supervisor STORE(0)_BLINK=BSTASL COM_STOREAAD=ADDR(STORE(0)) END ROUTINE CONFIG IF SSERIES=YES START RECORDFORMAT TCBF(INTEGER CMD,STE,LEN,DATAD,NTCB,RESP, C INTEGERARRAY PR,PO(0:3)) RECORDFORMAT UTEF(INTEGER PD,PP,BYTEINTEGER FMN,SP,STRM,FLAGS, C INTEGER TCBA,A1,A2,A3,A4,IDEST,I1,I2,I3,S1,S2,L1,L2) RECORD (TCBF)NAME TCB RECORD (UTEF)NAME UT LONGINTEGER TCB DESC,UT DESC INTEGER I,J,K,R INTEGER DCU2S,INIT WAITS CONSTINTEGER MAX INIT WAITS=2 LONGINTEGER BLOCKS LONGINTEGER L STRING (23)MSG CONFIG LENGTH=INTEGER(16)&X'FFFF'; !table length INTEGER(16)=(CONFIG LENGTH+127)&(-128)-X'80'; !PST bound L=LONGINTEGER(16); !real address & bound PST(CONFIG SEG)=X'01F0000080000001'!L CONFIG TABLE=X'80000000'+CONFIG SEG<<18 DCU2S=0 SCU MAP=0 I=8 I=I+8 WHILE INTEGER(CONFIG TABLE+I)>>24#X'E2'; ! find store entry SCU MAP=SCU MAP!1<<(I//8-1); !one SCU protem I=I+CONFIG TABLE+4 BLOCKS=LENGTHENI(INTEGER(I))<<32; ! 1st 4 meg of store map BLOCKS=BLOCKS!LENGTHENI(INTEGER(I+8)) IF INTEGER(I+4)>>24=X'E2'; ! 2nd 4 meg STORE BLOCKS=0 FOR I=0,1,63 CYCLE ; ! 8 meg/SCU EXIT IF BLOCKS>>(63-I)&1=0 BLOCK ADDR(I)=X'20000'*I STORE BLOCKS=STORE BLOCKS+1 REPEAT I=I+1 IF BLOCKS=-1 OPMESS("SCU 0 has ".STRINT((I)*128)."K bytes") FOR I=0,1,STORE BLOCKS-1 CYCLE PST(64+I>>1)=WDIRRDIR!NONSLAVED!X'3FF8080000001'+I<<17&X'0FFC0000' REPEAT STORE EPAGES=STORE BLOCKS*EPAGES PER BLOCK SYSTEM STORE BLOCKS=STORE BLOCKS; ! supervisor to top of store LAST REAL BYTE=BLOCK ADDR(SYSTEM STORE BLOCKS-1)+128*1024 TOP BLOCK=SYSTEM STORE BLOCKS-1 NEXT COM SEG=CONFIG SEG+1 I=CONFIG LENGTH GET REAL CORE(I); ! save config table ! (always at top of store?) I=8; ! set up OCP/DCU configs WHILE I<CONFIG LENGTH CYCLE J=INTEGER(CONFIG TABLE+I) IF J>>24=X'C3' START J=DCU CONF(0)+1 DCU CONF(0)=J K=CONFIG TABLE+INTEGER(CONFIG TABLE+I+4)&X'FFFF'; !addr(stream tables) K=INTEGER(K+4)>>8&X'FF'; !no. of streams K=K<<24!(I//8-1); !& SCU port K=K!(INTEGER(CONFIG TABLE+I+4)>>16&X'FF')<<8; !& DCU unit no. DCU CONF(J)=K OPMESS("DCU ".HTOS(K>>8&255,2)." on port ".STRINT(K&255)) FINISH ELSE IF J>>24=X'C2' START ; ! DCU2 DCU2S=DCU2S+1 J=DCU CONF(0)+1 DCU CONF(0)=J K=(I//8-1) ! h/w no. inserted later DCU CONF(J)=K J=X'20000010'!K<<22 *LB_J; *LSS_X'00180000'; *ST_(0+B ); ! initialise DCU I=I+24; ! takes 4 entries FINISH ELSE IF J>>24=X'D7' START UNLESS I//8-1=OCP0 SCU PORT START ; ! not IPL OCP NOCPS=2; ! 2 only for now (dual 2988 has 4) OCP1 SCU PORT=I//8-1 REMOTE OCP PORT=IPL OCP PORT!!1 PST(REMOTE OCP PORT)=PST(IPL OCP PORT)-X'200' FINISH FINISH I=I+8 REPEAT !* clear store from store block 2 to base of config table J=2 WHILE J<STORE BLOCKS-1 CYCLE I=X'80000000'+(64<<18)+BLOCK ADDR(J) ! K=0 ! %WHILE K<128*1024 %CYCLE ! LONGLONGREAL(I+K)=0 ! K=K+16 ! %REPEAT *LDTB_X'38002000'; *LDA_I; *LB_0; *LSQ_0 AGN: *ST_(DR +B ); *CPIB_X'1FFF' *JCC_4,<AGN> J=J+1 REPEAT I=X'80000000'+(64<<18)+BLOCKADDR(J) R=REALISE(CONFIG TABLE)!X'81000000' K=0 WHILE I+K<R CYCLE LONGLONGREAL(I+K)=0 K=K+16 IF K>=X'20000' START OPMESS("CFGT outwith store!!!") EXIT FINISH REPEAT IF DCU2S>0 START I=16*4*256*DCU2S; ! UT size GET REAL CORE(I) PST(UT SEG)=X'080000001'!WDIRRDIR!NONSLAVED+ C LENGTHENI(I)<<32+LAST REAL BYTE I=X'28000000'!(16*256*DCU2S); ! bound *LB_X'6005'; *LSS_UT VA; *ST_(0+B ); ! UTBA *LB_X'6004'; *LSS_I; *ST_(0+B ); ! UTBL NEXT COM SEG=UT SEG+1 ! set up interrupt buffer I=4096*NOCPS; ! at 3 words/int & 2 ints/stream ! enough room for 170 streams GET REAL CORE(I) I=I+128 I=I>>(NOCPS-1) MIBA=LAST REAL BYTE!I>>8 J=MIBA IF NOCPS>1 THEN J=J+IPL OCP PORT<<12 *LB_X'601A'; *LSS_J; *ST_(0+B ) ! !* Wait for DCU2s to initialise ! TCB==RECORD(GROPESEG) TCB=0 TCB_CMD=X'2C41400E'; ! read stream properties TCB_STE=REALISE(GROPESEG)!1 TCB_LEN=8 TCB_DATAD=GROPESEG+64 UT==RECORD(UT VA) UT=0 UT_PD=X'E7000000' UT_STRM=1 UT_FLAGS=X'81' UT_IDEST=X'000E4000' TCB DESC=GROPESEG&X'0FFFFFFFF'!LENGTHENI(X'2800000E')<<32 UT DESC=UT VA&X'0FFFFFFFF'!LENGTHENI(X'B0000001')<<32 SAVE IST=IST *JLK_<DCUTO>; *LSS_TOS ; *ST_I IST_PC=I IST_SSR=X'0180FFFE' *STLN_I IST_LNB=I *STSF_I IST_SF=I ONOFF(INH PHOTO OFFSET,0); ! no photos whilst initiating ONOFF(INH REPS OFFSET,-1); ! retry reporting to catch all fails FOR I=1,1,DCU CONF(0) CYCLE J=DCU CONF(I) IF J>>8=0 START ; ! DCU2 UT_FMN=J TCB_RESP=0 INIT WAITS=0 RETRY: *PRCL_4 *LSS_2 *SLSD_TCB DESC *ST_TOS *LD_UT DESC *RALN_8 *CALL_(DR ) *ST_K ->INIT FAILS UNLESS K=0 K=0 K=K+1 UNTIL TCB_RESP#0 OR K>100000 ->INIT FAILS IF TCB_RESP=0 K=BYTEINTEGER(TCB_DATAD+5); ! h/w no. DCU2HWN(J)=K DCU CONF(I)=K<<8!J MSG="DCU ".HTOS(K,2)." is fmn " IF J<10 THEN MSG=MSG." " MSG=MSG.STRINT(J) UNLESS INIT WAITS=0 THEN MSG=MSG."*" OPMESS(MSG) CONTINUE DCUTO: ! syserr if DCU not initialised *JLK_TOS ; *LSS_TOS *LSS_TOS ; *ST_R INIT WAITS=INIT WAITS+1 ->INIT FAILS IF INIT WAITS>MAX INIT WAITS WAIT(10000//MAX INIT WAITS); ! 10 seconds total wait time ->RETRY INIT FAILS: ! intialise fails - abandon DCU2 *LSQ_J; ! fmn/K/seip/DCU2S *LSS_X'DCFA' DCU CONF(I)=-1; ! abandon DCU OPMESS("DCU2 fmn ".STRINT(J)." init fails".TOSTRING(17)) FINISH REPEAT IST=SAVE IST ONOFF(INH REPS OFFSET,0); ! retry reporting off ONOFF(INH PHOTO OFFSET,-1); ! photos back on RESCAN: J=DCU CONF(0) FOR I=1,1,J CYCLE IF DCU CONF(I)=-1 START DCU CONF(0)=DCU CONF(0)-1 FOR K=I,1,J CYCLE DCU CONF(K)=DCU CONF(K+1) REPEAT ->RESCAN FINISH REPEAT FINISH IF NOCPS>1 THEN OPMESS("Dual OCP found") FINISH ELSE START ROUTINESPEC SAC GROPE(INTEGER PORT) INTEGER B,J, K, REALA, BLOCK, CONFBITS, WORK, BLKSIZE, BLKSPERSEG INTEGER SMAC, SF, LNB, INT PARAM, I, OLDSSN, PORTS, SMACMAX RECORD (SMACINF)NAME SMACINF STRING (7) S,T LONGINTEGER L CONSTINTEGER NO=0 CONSTINTEGER MINSTORE=6; ! (768k) minimum store for SMAC0 supvsr etc. CONSTINTEGER DAC=X'02000000'; ! SMAC is a DAC SAVE IST=IST SMACINF==RECORD(ADDR(ISAS(ISAS PTR+SMACINF OFFSET))) SMACMAX=SMACINF_SMACMAX FOR J=0,1,15 CYCLE ONLINE(J)=-1 REPEAT B=0 INT PARAM=0 FOR J=0,1,15 CYCLE ; !set block mask B=B!SMACINF_BLOCK0<<(J*SMACINF_BLKSHIFT) REPEAT PORTS=0 SMAC MAP=0 FOR SMAC=0,1,SMACMAX CYCLE *STLN_LNB *STSF_SF IST_LNB=LNB IST_PSR=X'14FF01' *JLK_<TOUTAD> *LSS_TOS *ST_I IST_PC=I IST_SSR=X'01800FFE' IST_SF=SF J=SMACINF_CONFREG!(SMAC<<SMACINF_SMACPOS) *LB_J *L_(0+B ); ! this instruction causes timeout if SMAC not present *ST_J PORTS=PORTS!(J>>2&15) SMAC MAP=SMAC MAP!1<<SMAC; !for com seg ONLINE(SMAC)=J ! ! P4 processor can not turn off hamming reporting in OCP. Must be done in each SMAC ! separately. Therefore turn it off here. It will be turned on again ! by the periodic kick of 'TURN OFF ER' in supervisor ! IF SMAC#0 AND OCPTYPE=4 START ; ! already done for SMAC0 J=SMACINF_SESR!(SMAC<<SMACINF_SMACPOS) K=SMACINF_HOFFBIT *LB_J *LSS_(0+B ) *OR_K *ST_(0+B ) FINISH ! ! Highest SMAC no. on thE P3 & P4 is 7 - however if the 'INTERLEAVE' bit is set ! then store accesses are interleaved between the odd & even highways. ! The SMAC responds to addresses for one highway in SMAC n ! & for the other in SMAC n+8. corresponding blocks must be present ! in both SMAC n & SMAC n+8. ! Highest SMAC no. on a P2 is 1. ! Thus :- ! IF OCPTYPE>=4 AND SMAC>7 START ->REPT IF ONLINE(SMAC&7)=NO; ! no corresponding SMAC J=(ONLINE(SMAC)&B)!!(ONLINE(SMAC&7)&B) IF J#0 START ; ! non-corresponding blocks OPMESS("SMACS ".STRINT(SMAC&7)."/".STRINT(SMAC). C " BLK clash".TOSTRING(17)) ONLINE(SMAC)=ONLINE(SMAC)&(¬J); ! reduce to common blocks only ONLINE(SMAC&7)=ONLINE(SMAC&7)&(¬J) FINISH IF SMAC=8 THEN ONLINE(SMAC)=ONLINE(SMAC)!SMACINF_BLOCK0 ! block 0 SMAC 8 always present FINISH ->REPT TOUTAD: *JLK_TOS ; ! gets PC of next instruction ! timed out *LSS_TOS ; ! discard old SSN *ST_OLDSSN *LSS_TOS *ST_INT PARAM IF 0<=SMAC<=15 THEN ONLINE(SMAC)=NO REPT: IF SMAC=0 THEN ONLINE(SMAC)=ONLINE(SMAC)!SMACINF_BLOCK0; !block0 SMAC 0 REPEAT IST=SAVE IST ! ! On P3 SMACs (blksize=128K) must allow for 16K ram variant with ! 256K blksize. This is distinguished by bit7(X01000000) set in ! the configuration register. NB both sorts of SMAC can be present ! on one machine ! FOR J=0,1,SMACMAX CYCLE CONFBITS=ONLINE(J) BLKSIZE=SMACINF_BLKSIZE BLKSPERSEG=SMACINF_BLKSPERSEG IF BLKSIZE=X'20000' AND CONFBITS&X'01000000'#0 THEN C BLKSIZE=X'40000' AND BLKSPERSEG=1 I=0 B=0 FOR K=0,1,15 CYCLE BLOCK=SMACINF_BLOCK0<<(K*SMACINF_BLKSHIFT) IF CONFBITS&BLOCK#0 THEN START REALA=J<<22!I<<17 FOR WORK=0,1,BLKSIZE//X'20000'-1 CYCLE BLOCK ADDR(STORE BLOCKS+WORK)=REALA+WORK*X'20000' REPEAT ! ! Set up virtual=real mapping in segs 64 onwards ! but have a care! If bottom block of a 128K pair is missing ! the segment table entry will lie and pretend both are present. ! This ruse is to facilitate real->virtual conversion viz:- ! ! (REAL ADDRESS)+X'81000000' = VIRTUAL ADDRESS ! WORK=1+K-(K//BLKSPERSEG)*BLKSPERSEG L=BLKSIZE*WORK-X'80'; ! PST bound field L=L<<32 PST(64+REALA>>18)=WDIRRDIR!X'080000001'+L+REALA& C X'FFC0000' WORK=BLKSIZE//X'20000' I=I+WORK B=B+WORK STORE BLOCKS=STORE BLOCKS+WORK STORE EPAGES=STORE EPAGES+EPAGES PER BLOCK*WORK FINISH ELSE I=I+BLKSIZE//X'20000' REPEAT IF CONFBITS&DAC=0 THEN S="SMAC " ELSE S=" DAC " IF B#0 THEN START OPMESS(S.STRINT(J)." has ".STRINT(B*128)."K bytes") ! ! Ensure that same ports closed in all SMACs ! I = PORTS<<2 K = SMACINF_CONFREG!(J<<SMACINF_SMACPOS) *LB_K *LSS_(0+B ) *OR_I *ST_(0+B ) FINISH ONLINE(J)=B; ! SMAC storesize REPEAT S=""; T="PORT " FOR J=0,1,3 CYCLE IF 8>>J&PORTS#0 THEN START IF S#"" THEN S=S."," AND T="PORTS " S=S.STRINT(J) FINISH REPEAT IF S#"" THEN OPMESS(T.S." closed") ! ! Multiprocessor standard is SAC on ports0&1,CPUs on 2&3 ! with all unused ports closed off ! ! ! Work out CPU ports ! J=(PORTS!!(-1))&3 IF J=3 THEN START OPMESS("Dual OCP found") NOCPS=2 REMOTE OCP PORT=IPL OCP PORT!!1 FINISH PST(IPL OCP PORT!!1)=PST(IPL OCP PORT)-X'200' ! separate ISTS for duals ! (single could become dual) ! ! Work out SAC ports ! J=(PORTS!!(-1))&X'C' IF J=X'C' START ; ! dual SAC confign OPMESS("Dual SACS found") ! ! Open paths for ints from SACs to ipl OCPs where necessary ! this is hardware dependent coding ! ! IF OCP TYPE=4 START *LSS_(X'4012') *OR_X'C030'; ! peri&se ints from both SACs *ST_(X'4012') FINISH ELSE START *LSS_(X'600A') *AND_X'FFFFFF33';! ! open peri se int paths *ST_(X'600A') FINISH NSACS=2 OTHER SAC PORT=IPL SAC PORT!!1 FINISH ELSE START ; ! single SAC confign IF OCPTYPE=4 START I=X'8020'>>IPL SAC PORT *LSS_(X'4012') *OR_I; ! open perei & se ints from SAC *ST_(X'4012') FINISH ! ! P2&P3 single SAC mcs: paths opened by hardware on IPL ! FINISH ! ! P4 series processors need clock port no in an internal register ! before the RRTC intruction(needed for groping) will work ! IF OCPTYPE=4 AND OCP VAR=0 THEN CLOCK PORT=IPL SAC PORT C ELSE CLOCK PORT=IPL OCP PORT IF OCPTYPE=4 START ; !P4 series - set up port for RTC *LSS_(X'4013') *SLSS_CLOCK PORT *USH_20 *OR_TOS *ST_(X'4013') FINISH ! ! Before groping the SAC(s), ensure the C toggle is clear in SMAC 0 if ! it is a P2 or P3 SMAC. It can be left set by a failed remote IPL on a ! dual. If not cleared here, it will cause a spurious syserr on first ! attempt to grope SAC. This is because the activate is sent OK, but ! words 8 and 9 in SMAC 0 still contain the values for remote IPL. The ! easiest way to clear the toggle is to access a SAC (e.g. try to master ! clear a trunk) and ignore any resulting syserr. Subsequent gropes ! will then be clean. ! IF SSERIES=NO AND OCPTYPE <= 3 THEN START SAVE IST = IST *STLN _LNB *STSF _SF IST_LNB = LNB IST_PSR = X'14FF01' *JLK _<SEAD> *LSS _TOS *ST _I IST_PC = I IST_SSR = X'01800FFE' IST_SF = SF I = X'40000800'!(IPL SAC PORT<<20) *LB _I *LSS _2; ! for master clear *ST _(0+B ) -> CTOGGLE OK SEAD: *JLK _TOS ; ! return link *LSD _TOS ; ! clear stack CTOGGLE OK: IST = SAVE IST FINISH ! ! now can grope the SAC(s) ! IF NSACS=2 START ; ! grope SACS - lowest first SAC GROPE(0) SAC GROPE(1) FINISH ELSE SAC GROPE(IPL SAC PORT) I=REAL0ADDR; !clear photo area protem J=X'100' LONGINTEGER(I+J)=0 AND J=J+8 WHILE J<X'1000' INTEGER(REAL0ADDR+X'104')=X'000F0000';! mp stop char for duals ! ! clear store with STQ to avoid IPL troubles on 2970 up to x370000 ! is cleared by the boot. Rest is full of parities ! FOR J=X'81037000',16,X'81040000'-16 CYCLE LONGLONGREAL(J)=0 REPEAT J=2 WHILE J<STORE BLOCKS CYCLE I=X'80000000'+(64<<18)+BLOCK ADDR(J) K=0 ! %WHILE K<128*1024 %CYCLE ! LONGLONGREAL(I+K)=0 ! K=K+16 ! %REPEAT *LDTB_X'38002000'; *LDA_I; *LB_0; *LSQ_0 AGN: *ST_(DR +B ); *CPIB_X'1FFF' *JCC_4,<AGN> J=J+1 REPEAT IF ONLINE(0)>=MINSTORE START ; ! resident supvsr into SMAC0 SMAC MAP=SMAC MAP!(SMAC MAP&X'101')<<16;! mark SMAC0 (& 8) in permanent use SYSTEM STORE BLOCKS=ONLINE(0) FINISH ELSE START SMAC MAP=SMAC MAP!SMAC MAP<<16; ! all SMACS in permanent use SYSTEM STORE BLOCKS=STORE BLOCKS FINISH LAST REAL BYTE=BLOCK ADDR(SYSTEM STORE BLOCKS-1)+128*1024 TOP BLOCK=SYSTEM STORE BLOCKS-1 NEXT COM SEG=49 ROUTINE SAC GROPE(INTEGER PORT) !*********************************************************************** !* Tries all trunks in the port. Put them into direct control mode * !* and reads out the controller properties. Controller gropes can * !* then find the devices on the controller * !*********************************************************************** INTEGERFNSPEC WAITRFB INTEGER LNB,PC,SF CONSTINTEGER GPC1=1, FPC2=5, SFC1=6 CONSTSTRING (4)ARRAY CTYPE(1:16)="GPC1","CPC1","CPC2", "FPC1","FPC2","SFC1","EM1","EM2","EM3", "EC1","EC2","EC3","CPC3","GPCS","CPC4","D16?" INTEGER TRUNK, TRUNKMAX, PT, I, J, ISA, MASK IST==RECORD(IST VA) SAVE IST=IST TRUNKMAX=15 *STLN_LNB *STSF_SF *JLK_<NOTRUNK> *LSS_TOS *ST_PC IST_LNB=LNB IST_PSR=X'14FF01' IST_PC=PC IST_SSR=X'01800FFF' IST_SF=SF IST_IT=X'7FFFFF' IST_IC=X'7FFFFF' MASK=0 TRUNK=0 NEXT: WHILE TRUNK<=TRUNKMAX CYCLE PT=PORT<<20!TRUNK<<16 ISA=X'40000800'!PT *LB_ISA; *LSS_2; *ST_(0+B ); ! master clear TRUNK=TRUNK+1 REPEAT FOR I=TRUNKMAX,-1,0 CYCLE IF MASK&1<<I=0 THEN TRUNKMAX=I AND ->PART2 REPEAT IF NSACS=1 THEN START ; ! no port on only SAC *IDLE_X'0DDD' FINISH RETURN ; ! hope other SAC is more useful PART2: OPMESS(STRINT(TRUNKMAX+1)." TRUNKS on SAC ".STRINT(PORT)) ! inhibits photo's so uninhibit ! xcept 2960 where photo stops mc! ONOFF(INH PHOTO OFFSET,-1) UNLESS OCPTYPE=2 IST=SAVE IST WAIT(100) FOR TRUNK=0,1,TRUNKMAX CYCLE IF MASK&1<<TRUNK=0 START ; ! trunk was ok ! ! Step 1 perform 2 suspends at least 50 musecs apart ! PT=PORT<<20!TRUNK<<16 ISA=X'40000800'!PT *LB_ISA *LSS_3 *ST_(0+B ) WAIT(1) *LB_ISA *LSS_(0+B ); ! read to clear lock on P4 *LSS_3 *ST_(0+B ) *LSS_(0+B ); ! to clear lock on P4 ! !Step 2 set direct control mode bit(21) in the diagnostic ! control register for this port&trunk ! *ADB_X'500'; ! from 40PT0800 to 40PT0D00 *LSS_X'400'; ! bit 21 *ST_(0+B ) ! ! Step 3 send a request contoller properties & waitfor 'RFB' ! *ADB_X'100'; ! from 40PT0D00 to 40PT0E00 *STB_ISA *LSS_X'C0000E80' *ST_(0+B ) I=WAITRFB ! ! Step 4 send AFA and unset all the from bs ! *LB_ISA *LSS_X'100'; *ST_(0+B ) *LSS_X'1E12'; *ST_(0+B ); ! master clear combined with FBs ! ! Step 5 unset dcm and master clear ! *SBB_X'100'; ! from 40PT0E00 to 40PT0D00 *LSS_0 *ST_(0+B ) I=I>>24 IF I>16 THEN I=16 IF I#0 THEN OPMESS("TRUNK ".STRINT(TRUNK). C " reports ".CTYPE(I)) IF I=GPC1 THEN START J=GPCCONF(0)+1 GPCCONF(0)=J GPCCONF(J)=PT<<8 CONTYPE(16*PORT+TRUNK)=3 FINISH IF I=FPC2 THEN START J=FPCCONF(0)+1 FPCCONF(0)=J FPCCONF(J)=PT<<8 CONTYPE(16*PORT+TRUNK)=2 FINISH IF I=SFC1 THEN START J=SFCCONF(0)+1 SFCCONF(0)=J SFCCONF(J)=PT<<8 CONTYPE(16*PORT+TRUNK)=1 FINISH FINISH ELSE START ; ! trunk did not masterclear OPMESS("Bad SACTRUNK ".HTOS(16*PORT+TRUNK,2)) FINISH REPEAT WAIT(100); ! to let DFCs setlle after mclear RETURN NOTRUNK: ! syserr int if illegal trunk *JLK_TOS *LSS_TOS ; *LSS_TOS ; *ST_I J=I>>29; ! failing port IF 0<=J<=1 START ; ! SAC syserr J=X'44000200'!J<<20 *LB_J; *LSS_(0+B ); *ST_J; ! read & clear syserr OPMESS("SAC syserr ".STRHEX(I)) FINISH *LSS_X'01800FFE'; *ST_(3) MASK=MASK!1<<TRUNK TRUNK=TRUNK+1 ->NEXT INTEGERFN WAITRFB CONSTINTEGER RFB=X'400' INTEGER I,Q Q=500 AGN: *LB_ISA; *LSS_(0+B ); *ST_I IF I&RFB#0 THEN RESULT =I Q=Q-1 ->AGN IF Q>0 RESULT =0 END END FINISH END !----------------------------------------------------------------------- ROUTINE ITIMER OWNINTEGER COUNT RECORD (PARMF) P INTEGER I,J,K STRING (23)MSG COUNT=COUNT+1 IF ACT1#0 THEN START IF SSERIES=YES START ! turn on retry reporting so that DCUs are recovered on comms fail etc. I=ISAS(ISAS PTR+INH REPS OFFSET) J=I&X'FFFF'; I=¬(I>>16) *LB_J; *LSS_(0+B ); *AND_I; *ST_(0+B ) IF NOCPS>1 START J=J!X'400C0000'!OCP1 SCU PORT<<22 *LB_J; *LSS_(0+B ); *AND_I; *ST_(0+B ) FINISH FINISH *ACT_ACT1 FINISH IF COUNT&3=0 THEN START P_DEST=X'360000'; PON(P) IF AUTO SLOAD#0 START ; ! AUTO SLOAD supervisor I=AUTO SLOAD>>8 J=(AUTO SLOAD&X'FF')<<4 IF X'40'<=J<=X'1C0' AND J#X'100' AND J&X'3F'=0 C AND BYTEINTEGER(COM_DLVNADDR+I)<254 START IF J>255 THEN K=3 ELSE K=2 MSG="from ".STRINT(I)." X".HTOS(J,K) P=0 P_DEST=X'3B0000' P_P1=I P_P2=J PON(P) FINISH ELSE MSG="HKEYs ??" OPMESS("AUTO SLOAD ".MSG) AUTO SLOAD=0 FINISH FINISH END !----------------------------------------------------------------------- ROUTINE NULL SERVICE(RECORD (PARMF)NAME P) PKMONREC("Unsupported service",P) END END SYSTEMROUTINE MOVE(INTEGER LENGTH, FROM, TO) *LB_LENGTH; *JAT_14,<L99> *LDTB_X'18000000'; *LDB_B ; *LDA_FROM *CYD_0; *LDA_TO; *MV_L =DR L99: END ; ! of MOVE SYSTEMROUTINE ITOE(INTEGER AD, L) *LB_L; *JAT_14,<L99> *LDTB_X'18000000'; *LDB_B ; *LDA_AD *LSS_ITOETAB+4; *LUH_X'18000100' *TTR_L =DR L99: END ; ! ITOE SYSTEMROUTINE ETOI(INTEGER AD, L) *LB_L; *JAT_14,<L99> *LDTB_X'18000000'; *LDB_B ; *LDA_AD *LSS_ETOITAB+4; *LUH_X'18000100' *TTR_L =DR L99: END ; ! ETOI ROUTINE HOOT(INTEGER NUM) INTEGER J, HOOTISA, HOOTBIT HOOTBIT=COM_HBIT HOOTISA=COM_HOOT IF HOOTISA#0 START ; ! lest no hooter FOR J=1,1,NUM CYCLE *LB_HOOTISA; *LSS_(0+B ) *OR_HOOTBIT; *ST_(0+B ) WAIT(40) *LB_HOOTISA; *LSS_(0+B ) *SLSS_-1; *NEQ_HOOTBIT *AND_TOS ; *ST_(0+B ) WAIT(40) REPEAT FINISH WAIT(300) END EXTERNALROUTINE PTREC(RECORD (PARMAF)NAME P) INTEGER I, J, SPTR, VAL STRING (120) S SPTR=1 FOR I=ADDR(P),4,ADDR(P)+28 CYCLE VAL=INTEGER(I) FOR J=28,-4,0 CYCLE CHARNO(S,SPTR)=HEXDS((VAL>>J)&15) SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=' ' SPTR=SPTR+1 REPEAT FOR I=ADDR(P)+8,1,ADDR(P)+31 CYCLE J=BYTEINTEGER(I) IF J<32 OR J>95 THEN J='_' CHARNO(S,SPTR)=J SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=NL LENGTH(S)=SPTR PRINTSTRING(S) END EXTERNALROUTINE PKMONREC(STRING (20)TEXT,RECORD (PARMAF)NAME P) PRINTSTRING(TEXT) SPACE PTREC(P) END EXTERNALINTEGERFN REALISE(INTEGER AD) CONSTINTEGER RA=X'0FFFFFFC' RESULT =(AD&X'3FFFF')+INTEGER(PST VA+(AD>>15)&X'FFF8'+4)& C RA END EXTERNALROUTINE DUMPTABLE(INTEGER TABLE, ADD, LENGTH) OWNINTEGER NEXT INTEGER I, K, END, SPTR, VAL STRING (132) S NEXT=NEXT+1; ADD=ADD&(-4) ! Some sort of validation is required here PRINTSTRING(" **** SUPERVISOR DUMP TABLE: ".STRINT( C TABLE)." ADDR ") PRINTSTRING(STRHEX(ADD)." LENGTH: ".STRINT(LENGTH)) PRINTSTRING(" DUMP NO: ".STRINT(NEXT)."****") ! Time of day and date added here NEWLINE END=ADD+LENGTH; I=1 S=" " UNTIL ADD>=END CYCLE *LDTB_X'18000020'; *LDA_ADD *VAL_(LNB +1); *JCC_3,<INVL> IF I=0 THEN START FOR K=ADD,4,ADD+28 CYCLE ->ON IF INTEGER(K)#INTEGER(K-32) REPEAT S="O"; ->UP FINISH ON: CHARNO(S,2)='('; SPTR=3 FOR I=28,-4,0 CYCLE CHARNO(S,SPTR)=HEXDS((ADD>>I)&15) SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=')' CHARNO(S,SPTR+1)=' ' SPTR=SPTR+2 FOR K=ADD,4,ADD+28 CYCLE VAL=INTEGER(K) FOR I=28,-4,0 CYCLE CHARNO(S,SPTR)=HEXDS((VAL>>I)&15) SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=' ' SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=' ' SPTR=SPTR+1 FOR K=ADD,1,ADD+31 CYCLE I=BYTEINTEGER(K)&X'7F' UNLESS 32<=I<=95 THEN I=' ' CHARNO(S,SPTR)=I SPTR=SPTR+1 REPEAT CHARNO(S,SPTR)=' ' SPTR=SPTR+1 CHARNO(S,SPTR)=NL BYTEINTEGER(ADDR(S))=SPTR PRINTSTRING(S) S=" " UP: ADD=ADD+32 I=0 REPEAT RETURN INVL: PRINTSTRING("Address validation fails ") END ; !ROUTINE DUMP ! own variables for joint use by 'IOCP' and 'PRINTER' CONSTINTEGER MASK=X'80FC3FFF' OWNINTEGER INPTR=X'80FC0000', OUTPTR=X'80FC0000', PAVAIL=0 OWNINTEGER BUSY, INTPEND, TESTPEND=0, INIT=0 SYSTEMROUTINE IOCP(INTEGER EP, N) !*********************************************************************** !* This routine receives all the output from main via IMP stmts * !* such as printstring, and sends it to the main print file. * !* A cyclic buffer is maintained in page 2 and one other buffer * !* is used in segment public 63. If output arrives faster * !* than the printer can cope it is discarded. * !*********************************************************************** RECORD (PARMF) Q INTEGER I, J, ADR, L, OLDINPTR, SYM, NLSEEN STRING (63) S ->END UNLESS X'280A8'&1<<EP¬=0; !check for valid entry OLDINPTR=INPTR; NLSEEN=0 IF EP=17 THEN START ; ! repeated symbols L=N>>8&63; J=L WHILE J>0 CYCLE CHARNO(S,J)=N&127; J=J-1 REPEAT ADR=ADDR(S)+1 FINISH ELSE START IF EP>=7 THEN START ; ! print string L=BYTE INTEGER(N); ADR=N+1 FINISH ELSE START ; ! print symbol & print ch L=1; ADR=ADDR(N)+3 FINISH FINISH I=1 WHILE I<=L CYCLE ->END IF BUSY=1; ! buffers busy discard output J=(INPTR+1)&MASK IF J#OUTPTR THEN START ; ! room for current char SYM=BYTE INTEGER(ADR) BYTE INTEGER(J)=SYM IF SYM=NL THEN NLSEEN=1 ADR=ADR+1; INPTR=J; I=I+1 FINISH ELSE BUSY=1 AND RETURN REPEAT RETURN IF PAVAIL=0 IF OLDINPTR=OUTPTR AND NLSEEN#0 THEN C Q_DEST=X'360000' AND PON(Q) END: END ; ! of routine IOCP EXTERNALROUTINE PRINTER(RECORD (PARMF)NAME P) !*********************************************************************** !* Version for a real printer. * !*********************************************************************** ROUTINESPEC ETOE(INTEGER AD, L) INTEGER I, J OWNBYTEINTEGERARRAY BUFFER(0:133) IF SSERIES=YES START RECORDFORMAT TCBF(INTEGER COMMAND,STE,LEN,DATAD,NTCB,RESP, C INTEGERARRAY PREAMBLE,POSTAMBLE(0:3)) OWNRECORD (TCBF)NAME TCB OWNINTEGER INITLP=X'FC10' CONSTINTEGER TCBM=X'2F004000' FINISH ELSE START RECORDFORMAT RQBF(INTEGER LFLAG, LSTBA, LBL, LBA, ALL, ALA, INIT) OWNRECORD (RQBF) RQB OWNINTEGER LBE=X'80700300',ALE1,ALE2 FINISH RECORD (ENTFORM)NAME D OWNINTEGER MNEM=M'LP0',TRANSTABAD=0 RECORD (PARMF) Q SWITCH DACT(0:8) IF INIT=0 THEN START Q=0 Q_DEST=X'30000B' Q_SRCE=X'360007' Q_P1=M'LP' Q_P2=X'360002'; ! ints to act 2 IF SSERIES=NO START RQB_LBL=4 RQB_LBA=ADDR(LBE) RQB_ALL=8 RQB_ALA=ADDR(ALE1) RQB_INIT=X'FC10' ALE2=ADDR(BUFFER(1)) FINISH PON(Q) INIT=1 FINISH ->DACT(P_DEST&15) NEXTLINE: BUFFER(0)=0 DACT(0): ! alarm clock tick or equivalent IF INTPEND#0 OR TESTPEND#0 OR PAVAIL=0 THEN ->END IF INPTR=OUTPTR THEN ->UNBUSY I=BUFFER(0) CYCLE J=BYTE INTEGER(OUTPTR) BYTE INTEGER(OUTPTR)=0 OUTPTR=(OUTPTR+1)&MASK IF J=10 OR J=12 OR I=132 START IF I=132 THEN J=10 J=133 IF J=10; !for "NEW" trantabs I=I+1; BUFFER(I)=J BUFFER(0)=I IF SSERIES=YES THEN TCB_LEN=I ELSE ALE1=X'58000000'+I ITOE(ADDR(BUFFER(1)),I) ETOE(ADDR(BUFFER(1)),I); ! deal with unprintables ->PRINT FINISH IF J#13 THEN I=I+1 AND BUFFER(I)=J IF INPTR=OUTPTR THEN BUFFER(0)=I AND ->UNBUSY ! incomplete line REPEAT PRINT: ! print line in array buffer(again) INTPEND=1 PRINTI: IF SSERIES=YES START P_P1=ADDR(TCB) FINISH ELSE START P_P1=ADDR(RQB) P_P3=X'11'; ! do stream req. clear abnormal FINISH P_DEST=X'30000C' P_SRCE=X'360008' P_P2=INIT PON(P) ->END DACT(8): ! request rejected OPMESS("Main LP request reject") INTPEND=0 ->END DACT(1): ! not now used ->END DACT(2): ! printer interupt normal termn J=(P_P1)>>20&15 IF J&1#0 THEN ->ATTN IF J&4#0 THEN ->ABTERM IF INTPEND=0 THEN START OPMESS("Main LP INT???") RETURN FINISH IF SSERIES=YES AND INTPEND=2 START TCB_COMMAND=TCBM!X'83'; ! write (was initialise) TCB_DATAD=ADDR(BUFFER(1)) FINISH INTPEND=0 ->NEXT LINE ABTERM: ! abnormal termination INTPEND=0 IF SSERIES=YES START IF TCB_POSTAMBLE(0)>>24=X'20' START ; ! illegal char only TCB_LEN=1 BUFFER(1)=X'15'; ! EBCDIC newline ->PRINT; ! blank line FINISH FINISH ELSE START D==RECORD(P_P3); ! onto device entry IF D_SENSE1>>24=X'20' START ALE1=X'58000001' BUFFER(1)=X'15' ->PRINT FINISH FINISH PKMONREC("Printer abtermn:",P) OPMESS("Attend main LP") TESTPEND=1; ->END ATTN: ! attention IF TESTPEND#0 AND P_P1&X'8000'#0 C THEN TESTPEND=0 AND ->PRINT ->END DACT(6): ! reset printer Q=0; Q_DEST=X'300005' Q_P1=MNEM; Q_SRCE=X'360000'; ! reply is ignored PON(Q); ! deallocate from whoever has it Q_DEST=X'30000B' Q_P2=X'360002'; ! ints to act 2 Q_P1=M'LP' Q_SRCE=X'360007' PON(Q) PAVAIL=0 INTPEND=0; ->NEXT LINE DACT(7): ! reply from allocate IF P_P1#0 THEN OPMESS("Main LP alloc fails ".STRINT(P_P1)) C ELSE START INTPEND=0 PAVAIL=1 TESTPEND=0 INIT=P_P2 MNEM=P_P6 D==RECORD(P_P3) TRANSTABAD=D_TRTABAD IF SSERIES=YES START TCB==RECORD(D_UA AD) TCB_COMMAND=TCBM!X'81'; ! initialise TCB_STE=REALISE(ADDR(INITLP)&X'FFFC0000')!1 TCB_LEN=4 TCB_DATAD=ADDR(INITLP) INTPEND=2 ->PRINTI FINISH FINISH ->NEXTLINE UNBUSY: ! restart if buffer oflow occurred IF BUSY=1 START BUSY=0; PRINTSTRING(" *** Output lost *** ") FINISH ->END ROUTINE ETOE(INTEGER AD, L) INTEGER J RETURN IF TRANSTABAD=0 J=TRANSTABAD *LB_L *JAT_14,<L99> *LDTB_X'18000000' *LDB_B *LDA_AD *LSS_J *LUH_X'18000100' *TTR_L =DR L99: END END: END ; ! of routine PRINTER EXTERNALROUTINE GET PSTB(INTEGERNAME PSTB0, PSTB1) ! Machine-independent version ! Public segment PST SEG is mapped to the PST itself RECORDFORMAT EF(INTEGER LIM, RA) CONSTRECORD (EF)NAME E=PST VA+PST SEG*8 ! E_LIM gives the size of the PST (bytes) ! for double words, >>3, and this is the top public seg which is ! potentially available. To get the va limit therefore we <<18. ! we add the top bit and also the bottom 7 bits >>3 and <<18, which ! is the '3C'. PSTB0=((E_LIM&X'0003FF80')<<15)!X'803C0000' PSTB1=E_RA&X'0FFFFFC0' END ; ! GET PSTB SYSTEMROUTINE STOP INTEGER I,W0,W1,W2,W3 I=COM_LSTL *LB_I; *LSS_(0+B ); *ST_W2 I=COM_LSTB *LB_I; *LSS_(0+B ); *ST_W3 *STSF_I W1=I>>18<<18 W0=-1; ! dummy syserr param *LXN_UNDUMPSEG; *LSQ_W0; *ST_(XNB +0) ! ! Now if supervisor stop seg 10 is set up as if we have had a dummy ! system error. A tape dump will then look ok to the dump analyser ! IF SSERIES=YES THEN LIGHTS(FOOTPRINT!X'DEAD') HOOT(15) *IDLE_X'3333' END ; ! STOP IF SSERIES=YES START EXTERNALINTEGERFN PINT RECORDFORMAT ISTF(INTEGER LNB,PSR,PC,SSR,SF,IT,IC) RECORD (ISTF)NAME IST4,IST14 RECORD (ISTF) SAVE IST4,SAVE IST14 INTEGER LNB,PC,SF INTEGER I,J I=0 IST4==RECORD(IST VA+(4-1)*32) IST14==RECORD(IST VA+(14-1)*32) SAVE IST4=IST4 SAVE IST14=IST14 *STLN_LNB *STSF_SF *JLK_<INT> *LSS_TOS *ST_PC IST4_LNB=LNB IST4_PSR=X'14FF01' IST4_PC=PC IST4_SSR=X'3FFE' IST4_SF=SF IST4_IT=X'7FFFFF' IST4_IC=X'7FFFFF' IST14=IST4 *LSS_X'1FF6'; *ST_(3); ! allow unit & peripheral ints. WAIT(10) ->FINI INT: *JLK_TOS *LSS_TOS *LSS_TOS *ST_I; !interrupt param FINI: *LSS_X'3FFE' *ST_(3) IST4=SAVE IST4 IST14=SAVE IST14 RESULT =I END FINISH !* ROUTINE RESTART ! ROUTINESPEC DOWAIT(INTEGER MASK) IF SSERIES=YES START OWNINTEGERARRAY TCBA(0:14) OWNINTEGERARRAYFORMAT TCBF(0:13) OWNINTEGERARRAYNAME TCB TCB==ARRAY(ADDR(TCBA(1))&X'FFFFFFF8',TCBF); ! double-word align CONSTINTEGER TCBM=X'2C404000' OWNINTEGER INIT=X'FC03'; ! 1600 BPI/PE OWNINTEGERARRAY ACTIVATE(0:1)=X'10001400',0 INTEGER PSM,AWORDA,PCWORDA FINISH ELSE START RECORD (PARMF) P RECORDFORMAT RQBF(INTEGER LFLAG,LSTBA,LBL,LBA,ALL,ALA,INIT) RECORDFORMAT STRMF(INTEGER SAW0,SAW1,RESP0,RESP1) RECORDFORMAT CAF(INTEGER MARK,PAW,PIW0,PIW1,CSAW0,CSAW1,CRESP0,C CRESP1,RECORD (STRMF)ARRAY STRMS(0:15)) RECORD (CAF)NAME CA RECORD (RQBF)NAME RQB RECORD (ENTFORM)NAME D INTEGERNAME LBE,ALE1,ALE2 INTEGER PTSM,STRM,RESP0,RESP1 FINISH RECORDFORMAT SEG10F(INTEGER SYSERRP,STACK,LSTL,LSTB,PSTL,PSTB, C HKEYS,INPTR,OUTPTR,BUFFLASTBYTE,OLDSE,OLDST,OLDLSTL,OLDLSTB,SBLKS,C PASL,KQ,RQ1,RQ2,LONGINTEGER SA,PARM,PARML,INTEGERARRAY BLOCKAD(0:127)) CONSTRECORD (SEG10F)NAME SEG10=UNDUMPSEG OWNINTEGERARRAYFORMAT BF(0:127) INTEGERARRAYNAME BLOCKAD LONGINTEGER A INTEGER I,J SLAVESONOFF(0) ! ! Seg 10 (which must be in SMAC0/SCU0-block0) is used at failure to pass ! info to the dump program. First 4 words are set up by system ! error routine (where appropiate) ! FOR I=0,4,8 CYCLE J=INTEGER(ADDR(COM_PSTL)+I) *LB_J; *LSS_(0+B ); *ST_J INTEGER(REAL0ADDR+I)=J INTEGER(X'80280010'+I)=J REPEAT SEG10_INPTR=INPTR; ! for the printer buffer SEG10_OUTPTR=OUTPTR SEG10_BUFFLASTBYTE=MASK SEG10_SBLKS=COM_SBLKS BLOCKAD==ARRAY(COM_BLKADDR,BF) FOR I=0,1,SEG10_SBLKS-1 CYCLE SEG10_BLOCKAD(I)=BLOCKAD(I) REPEAT SEG10_PASL=PARMASL SEG10_KQ=KERNELQ SEG10_RQ1=0 SEG10_RQ2=0 *LSD_SERVA; *ST_A; SEG10_SA=A *LSD_PARM; *ST_A; SEG10_PARM=A SEG10_PARML=0 IF SSERIES=YES START PSM=HANDKEYS&X'FFFFF' AWORDA=X'60000000'!PSM>>16<<22; !activate word address *LSS_(16); *USH_-24; *ST_PCWORDA; ! OCP SCU port PCWORDA=PCWORDA<<22!X'60000010'; ! processor coupler address *LB_PCWORDA; *MPSR_X'12'; *L_(0+B ); ! free CC (perhaps!) ACTIVATE(1)=REALISE(ADDR(TCB(0))&X'FFFC0000')!X'80000001' J=0 I=PINT AND J=J+1 UNTIL I=0 OR J=100 A=LONGINTEGER(ADDR(ACTIVATE(0))) *LSD_A; !set emergency CCA (@ X'1400') *LB_AWORDA *ADB_X'20' *ST_(0+B ) ACTIVATE(0)=ADDR(TCB(0)) ACTIVATE(1)=3<<24!PSM>>8&X'FF'; !connect stream A=LONGINTEGER(ADDR(ACTIVATE(0))) I=100; ! for timeout *LSD_A *LB_AWORDA *ST_(0+B ) CON: *MPSR_X'12' *L_(0+B ) *MPSR_X'11' *JAT_4,<CONOK> I=I-1 IF I<=0 THEN ->CONOK; ! forget it (stream probably connected anyway) *LB_AWORDA *J_<CON> CONOK: J=0 I=PINT AND J=J+1 UNTIL I#0 OR J=100 ACTIVATE(1)=ACTIVATE(1)&X'00FFFFFF'!1<<24; !start stream TCB(0)=TCBM!X'81'; !initialise TCB(1)=REALISE(ADDR(INIT)&X'FFFC0000')!1; !GLA STE TCB(2)=4; !data length TCB(3)=ADDR(INIT); !data address INIT=INIT!(PSM&15)<<24; !mechanism DOWAIT(X'C00000') TCB(0)=TCBM!X'238'; !rewind to BT (& skip data) TCB(1)=1; !fixed TCB(2)=0 TCB(3)=0 DOWAIT(X'C00000'); !wait for term J=0 I=PINT AND J=J+1 UNTIL I#0 OR J=100; !wait for BT sense WAIT(2000) FINISH ELSE START PTSM=HANDKEYS&X'FFFF' P=0 P_DEST=8; P_P1=PTSM P_SRCE=X'80360000' GDC(P) IF P_P1#0 THEN START PKMONREC("Claim dumpmt:",P) NEWLINE HOOT(4) *IDLE_X'12121' FINISH D==RECORD(P_P3) CA==RECORD(D_CAA) RQB==RECORD(D_GRCB AD) CA_MARK=-1 LBE==INTEGER(RQB_LBA) ALE1==INTEGER(RQB_ALA) ALE2==INTEGER(RQB_ALA+4) RQB_LFLAG=1<<18!X'C000'; ! LST 1 seg,note mech no,ACR=0 ! and trusted chain RQB_LSTBA=X'8080' RQB_LBL=4; RQB_ALL=8 RQB_INIT=(PTSM&15)<<24!X'FC03'; ! status mask&1600BPI STRM=PTSM>>4&15 ALE1=X'58001000' ALE2=X'81000000' LBE=X'00F10800'; ! connect stream if nec DOWAIT(X'C00000') LBE=X'80F03800'; ! rewind DOWAIT(X'C00000'); ! wait for term(=rewnd starts) DOWAIT(X'80100000'); ! wait for attmnt(=at BT) FOR I=1,1,500*COM_INSPERSEC CYCLE ; ! wait about 1 sec REPEAT ; ! (RTC may be down in duals - avoid 'wait') FINISH IF SSERIES=YES START ; ! read over label TCB(0)=TCBM!X'202' TCB(2)=4096 FINISH ELSE LBE=X'80F04200' DOWAIT(X'C00000') IF SSERIES=YES THEN TCB(0)=TCBM!X'A3' ELSE LBE=X'80F02300' DOWAIT(X'C00000'); ! write TM IF SSERIES=YES THEN TCB(0)=TCBM!X'83' ELSE LBE=X'80C00300' FOR I=0,1,SEG10_SBLKS-1 CYCLE ; ! dump store in 4K blocks IF SSERIES=YES THEN TCB(1)=BLOCKAD(I)!1 FOR J=0,4096,31*4096 CYCLE IF SSERIES=YES THEN TCB(3)=J ELSE C ALE2=X'81000000'+SEG10_BLOCKAD(I)+J DOWAIT(X'C00000') REPEAT REPEAT IF SSERIES=YES THEN TCB(0)=TCBM!X'A3' ELSE LBE=X'80F02300' DOWAIT(X'C00000'); ! write 2 TMs DOWAIT(X'C00000') IF SSERIES=YES THEN TCB(0)=TCBM!X'258' ELSE LBE=X'80F03800' DOWAIT(X'C00000'); ! unload HOOT(40) *IDLE_X'E00E' STOP ROUTINE DOWAIT(INTEGER MASK) !*********************************************************************** !* Fires an I-O operation and waits for the reply. Any attentions * !* are thrown away. Response words are left in globals * !*********************************************************************** IF SSERIES=YES START INTEGER TCBR INTEGER I LONGLONGREAL TCBP UNLESS MASK<0 START *LB_PCWORDA; !clear unwanted ints. *MPSR_X'12' *L_(0+B ) TCB(5)=0; !clear response word A=LONGINTEGER(ADDR(ACTIVATE(0))) *LSD_A *LB_AWORDA *ST_(0+B ) CA: *MPSR_X'12' *L_(0+B ) *MPSR_X'11' *JAF_4,<CA> CR: TCBR=TCB(5) *LSS_TCBR; !wait for response *JAT_4,<CR> ->FIREOK IF TCBR>>30=0 OR TCBR&X'FFFF'=0 OR MASK=0 TCBP=LONGLONGREAL(ADDR(TCB(10))) *LB_TCBR *LSQ_TCBP *JCC_0,<FIREOK> *IDLE_X'EEEE' FIREOK: RETURN FINISH *LB_PCWORDA; !wait for interrupt *MPSR_X'12' CI: *L_(0+B ) *JAT_4,<CI> RETURN FINISH ELSE START INTEGER CHISA RECORD (STRMF)NAME STRMS IF MASK<0 THEN MASK=MASK&X'7FFFFFFF' AND ->AGN WAIT: *LXN_CA+4; *INCT_(XNB +0) *JCC_7,<WAIT> CA_PAW=1<<24!STRM; ! do stream request CA_PIW0=0 STRMS==CA_STRMS(STRM) STRMS_SAW0=1<<28!32; ! clear abnormal termination STRMS_SAW1=ADDR(RQB) STRMS_RESP0=0 STRMS_RESP1=0 CA_MARK=-1 CHISA=X'40000800'!(PTSM>>8<<16) *LB_CHISA; *LSS_1; *ST_(0+B ); ! send channel flag ! AGN: UNTIL STRMS_RESP0#0 AND CA_MARK=-1 CYCLE ; REPEAT ! GET: *LXN_CA+4; *INCT_(XNB +0); *JCC_7,<GET> RESP0=STRMS_RESP0 RESP1=STRMS_RESP1 STRMS_RESP0=0 STRMS_RESP1=0 CA_PIW0=0 CA_MARK=-1 ->AGN UNLESS RESP0&MASK#0; ! normal or abnorml set FINISH END END ; ! RESTART EXTERNALROUTINE ENTER(INTEGER A, B) RECORDFORMAT REGF(INTEGER LNB, PSR, PC, SSR, SF, IT, IC, LTB) RECORD (REGF)NAME R INTEGER SSNP1ADDR, PB0, PB1, THIS LNB, THIS SF, REACT PC, CURSTKAD CONSTINTEGER RESSTKAD = X'80180000' CONSTINTEGER REACTAD=X'81000080' *STLN_THIS LNB ! ! Copy words from alternate stack segment to RA word 32(dec) ie. X80 bytes ! work out alt stack seg from current stack front ! *STSF_THIS SF CURSTKAD = THIS SF&X'FFFC0000' SSNP1ADDR = CURSTKAD!X'00040000' ! ! Copy sufficient of current stack to the restart stack (public 6) to ! allow 'RESTART' to be called on it. ! MOVE(THIS SF&X'3FFFF',CURSTKAD,RESSTKAD) ! ! Now set up re-activation words for re-entry below ! *JLK_<ELAB> *LSS_TOS *ST_REACT PC R == RECORD(REACTAD) R_LNB = RESSTKAD!(THIS LNB&X'3FFFF') R_PSR = X'0014FF01' R_PC = REACT PC R_SSR = X'0180FFFE'; ! VA mode all masked except system error R_SF = RESSTKAD!(THIS SF&X'3FFFF') GET PSTB(PB0,PB1) INTEGER(REACTAD+X'48') = PB0 INTEGER(REACTAD+X'4C') = PB1 CHOP29 *IDLE_X'CCCC' ELAB: *JLK_TOS ! re-entry here for post mortem RESTART *IDLE_X'CCCC' END ; ! ENTER EXTERNALROUTINE PRHEX(INTEGER N) PRINTSTRING(STRHEX(N)) END ROUTINE MONITOR(STRING (63) S) PRINT STRING(S." ") MONITOR STOP END !----------------------------------------------------------------------- !----------------------------------------------------------------------- EXTERNALROUTINE DPON(RECORD (PARMF)NAME P,INTEGER DELAY) PON(P) END !---------------------------------------------------------------------- ROUTINE PUTONQ(INTEGER SERVICE) RECORD (SERVF)NAME SERV, SERVQ SERV==SERVA(SERVICE) IF KERNELQ=0 THEN SERV_L=SERVICE ELSE START SERVQ==SERVA(KERNELQ) SERV_L=SERVQ_L SERVQ_L=SERVICE FINISH KERNELQ=SERVICE END !----------------------------------------------------------------------- INTEGERFN PPINIT(RECORD (PARMXF)ARRAYNAME PARMSPACE,INTEGER LASTCELL) INTEGER I, J, CELLS, PARMAD RECORD (PARMXF)NAME HDCELL PARMAD=ADDR(PARMSPACE(0)) PARM==PARMSPACE CELLS=LASTCELL HDCELL==PARM(0); ! set up hdecell for dump prg HDCELL_DEST=LASTCELL HDCELL_SRCE=LASTCELL HDCELL_P1=LASTCELL+1 FOR I=1,1,CELLS-1 CYCLE PARM(I)_LINK=I+1 REPEAT PARM(CELLS)_LINK=1 PARMASL=CELLS J=PARMAD I=PCELLSIZE*(LASTCELL+1)!X'18000000' PARMDES=LONGINTEGER(ADDR(I)); ! descrptr to PP area RESULT =PARMAD END !----------------------------------------------------------------------- EXTERNALROUTINE MORE PPSPACE !*********************************************************************** !* Called when PARM ASL is empty * !* Chopsupe version just gives up * !*********************************************************************** MONITOR("PARM ASL empty") END !----------------------------------------------------------------------- EXTERNALROUTINE PON(RECORD (PARMF)NAME P) RECORD (SERVF)NAME SERV RECORD (PARMXF)NAME ACELL, SCELL, NCELL INTEGER SERVICE, NEWCELL, SERVP SERVICE=P_DEST>>16 UNLESS SERVICE<=MAXSERV C THEN PKMONREC("Invalid PON:",P) AND RETURN IF PARMASL=0 THEN MORE PPSPACE ACELL==PARM(PARMASL); ! ACELL =ASL headcell NEWCELL=ACELL_LINK NCELL==PARM(NEWCELL); ! NCELL mapped onto NEWCELL IF NEWCELL=PARMASL THEN PARMASL=0 C ELSE ACELL_LINK=NCELL_LINK NCELL<-P; ! copy parameters in SERV==SERVA(SERVICE) SERVP=SERV_P&X'7FFFFFFF' IF SERVP=0 THEN NCELL_LINK=NEWCELL ELSE START SCELL==PARM(SERVP) NCELL_LINK=SCELL_LINK SCELL_LINK=NEWCELL FINISH SERV_P=SERV_P&X'80000000'!NEWCELL IF SERV_P>0 AND SERV_L=0 THEN PUTONQ(SERVICE) END !----------------------------------------------------------------------- EXTERNALROUTINE FASTPON(INTEGER CELL) RECORD (PARMF)NAME P P==RECORD(ADDR(PARM(CELL))) PON(P) RETURN PPCELL(CELL) END !----------------------------------------------------------------------- EXTERNALINTEGERFN NEWPPCELL !*********************************************************************** !* Provide a PP cell for use elsewhere than in PON-POFF area * !*********************************************************************** INTEGER NEWCELL RECORD (PARMXF)NAME ACELL IF PARMASL=0 THEN MORE PPSPACE ACELL==PARM(PARMASL) NEWCELL=ACELL_LINK IF NEWCELL=PARMASL THEN PARMASL=0 C ELSE ACELL_LINK=PARM(NEWCELL)_LINK RESULT =NEWCELL END !----------------------------------------------------------------------- ROUTINE POFF(RECORD (PARMF)NAME P) !*********************************************************************** !* Remove a set of paramaters from their queue and copy them * !* into the parameter record. The service no is in P_DEST and an * !* empty or inhibited queue is notified by returning a zero P_DEST * !*********************************************************************** RECORD (SERVF)NAME SERV RECORD (PARMXF)NAME ACELL, CCELL, SCELL INTEGER SERVICE, CELL, SERVP SERVICE=P_DEST>>16 UNLESS 0<SERVICE<=MAXSERV C THEN PKMONREC("Invalid POFF:",P) AND P_DEST=0 AND RETURN SERV==SERVA(SERVICE) SERVP=SERV_P IF SERVP<=0 THEN P_DEST=0 AND RETURN SCELL==PARM(SERVP) CELL=SCELL_LINK CCELL==PARM(CELL) P<-CCELL; ! copy parameters out IF CELL=SERV_P THEN SERV_P=0 ELSE SCELL_LINK=CCELL_LINK IF PARMASL=0 THEN CCELL_LINK=CELL ELSE START ACELL==PARM(PARMASL) CCELL_LINK=ACELL_LINK ACELL_LINK=CELL FINISH PARMASL=CELL END !----------------------------------------------------------------------- EXTERNALROUTINE RETURN PPCELL(INTEGER CELL) !*********************************************************************** !* Returns a cell suplied for other purposes via NEWPPCELL * !*********************************************************************** RECORD (PARMXF)NAME ACELL, CCELL CCELL==PARM(CELL) IF PARMASL=0 THEN CCELL_LINK=CELL ELSE START ACELL==PARM(PARMASL) CCELL_LINK=ACELL_LINK ACELL_LINK=CELL FINISH PARMASL=CELL END !----------------------------------------------------------------------- EXTERNALROUTINE INHIBIT(INTEGER SERVICE) !*********************************************************************** !* Inhibit a service by setting top bit in SERV_P * !*********************************************************************** RECORD (SERVF)NAME SERV UNLESS 0<SERVICE<=MAXSERV C THEN PRINT STRING("INVALID INHIBIT: ".STRINT(SERVICE)." ") AND RETURN SERV==SERVA(SERVICE) SERV_P=SERV_P!X'80000000' END !----------------------------------------------------------------------- EXTERNALROUTINE UNINHIBIT(INTEGER SERVICE) !*********************************************************************** !* Uninhibit a service by unsetting top bit in P_SERV and adding * !* any service calls to appropiate queue * !*********************************************************************** RECORD (SERVF)NAME SERV UNLESS 0<SERVICE<=MAXSERV C THEN PRINT STRING("Invalid UNINHIBIT: ".STRINT(SERVICE)." ") AND RETURN SERV==SERVA(SERVICE) SERV_P=SERV_P&X'7FFFFFFF' IF SERV_L=0 AND SERV_P#0 THEN PUTONQ(SERVICE) END !---------------------------------------------------------------------- EXTERNALSTRING (8) FN STRHEX(INTEGER VALUE) STRING (8) S *LD_S; *LSS_8; *ST_(DR ) *INCA_1; *STD_TOS ; *STD_TOS *LSS_0; *LUH_VALUE *MPSR_X'24'; ! set CC=1 *SUPK_L =8 *LD_TOS ; *ANDS_L =8,0,15; ! throw away zone codes *LSS_HEXDS+4; *LUH_X'18000010' *LD_TOS ; *TTR_L =8 RESULT = S END SYSTEMROUTINE WRITE(INTEGER VALUE,PLACES) STRING (16)S INTEGER D0,D1,D2,D3,L PLACES=PLACES&15 *LSS_VALUE; *CDEC_0 *LD_S; *INCA_1; *STD_TOS *CPB_B ; ! set CC=0 *SUPK_L =15,0,32; ! unpack & space fill *STD_D2; *JCC_8,<WASZERO> *LD_TOS ; *STD_D0; ! for sign insertion *LD_TOS *MVL_L =15,63,0; ! force ISO zone codes IF VALUE<0 THEN BYTEINTEGER(D1)='-' L=D3-D1 OUT: IF PLACES>=L THEN L=PLACES+1 D3=D3-L-1 BYTEINTEGER(D3)=L PRINTSTRING(STRING(D3)) RETURN WASZERO: BYTEINTEGER(D3-1)='0' L=2; ->OUT END EXTERNALSTRING (8) FN HTOS(INTEGER VALUE, PLACES) STRING (8) S INTEGER I I=64-4*PLACES *LD_S; *LSS_PLACES; *ST_(DR ) *INCA_1; *STD_TOS ; *STD_TOS *LSS_VALUE; *LUH_0; *USH_I *MPSR_X'24'; ! set CC=1 *SUPK_L =8 *LD_TOS ; *ANDS_L =8,0,15; ! throw away zone codes *LSS_HEXDS+4; *LUH_X'18000010' *LD_TOS ; *TTR_L =8 RESULT = S END !----------------------------------------------------------------------- EXTERNALSTRING (15) FN STRINT(INTEGER N) STRING (16) S INTEGER D0,D1,D2,D3 *LSS_N; *CDEC_0 *LD_S; *INCA_1; ! past length byte *CPB_B ; ! set CC=0 *SUPK_L =15,0,32; ! unpack 15 digits space fill *STD_D2; ! final DR for length calcs *JCC_8,<WASZERO>; ! N=0 case *LSD_TOS ; *ST_D0; ! sign descriptor stked by SUPK *LD_S; *INCA_1 *MVL_L =15,15,48; ! force in ISO zone codes IF N<0 THEN BYTEINTEGER(D1)='-' AND D1=D1-1 BYTEINTEGER(D1)=D3-D1-1 RESULT =STRING(D1) WASZERO: RESULT ="0" END EXTERNALROUTINE OPMESS2(INTEGER OPER,STRING (63) MESS) !*********************************************************************** !* PON a message to the OPER. In preparation for interrupt driven * !* operator routines which can not be called * !*********************************************************************** STRING (23) T RECORD (PARMF) P INTEGER I T<-MESS P_DEST=X'2F0007'!OPER<<8 P_SRCE=0 FOR I=0,1,23 CYCLE BYTE INTEGER(ADDR(P_P1)+I)=BYTE INTEGER(ADDR(T)+I) REPEAT PON(P) END EXTERNALROUTINE OPMESS(STRING (63)MESS) OPMESS2(0,MESS) END ROUTINE OPER RELAY(RECORD (PARMF)NAME P) !*********************************************************************** !* To hold up OPER message prior to initialisation * !*********************************************************************** P_DEST=P_DEST&X'FFFF'!X'00320000' PON(P) END EXTERNALROUTINE WAIT(INTEGER MILLESECS) LONGINTEGER T *CPSR_B ; *MPSR_X'C0'; ! mask out overflow *RRTC_0; *SHS_1; ! ACC=microsecs *SLSS_MILLESECS; *IMY_2 *IAD_1; *IMYD_512; ! ACC=delay in microsecs *IAD_TOS ; *ST_T *JAF_15,<L1>; ! jump unless overflow *JAT_6,<L1>; ! logical ok +ve to -ve oflow ! Addition has caused clock to overflow -ve to +ve. Use signed comparision L2:*RRTC_0; *SHS_1 *ICP_T; *JCC_4,<L2> *J_<L3> L1:*RRTC_0; *SHS_1 *UCP_T; *JCC_4,<L1> L3:*MPSR_B ; ! reset program mask END INTEGERFN STOI(STRINGNAME S) STRING (50) P INTEGER SIGN,AD,I,J,HEX LONGINTEGER TOTAL HEX=0; TOTAL=0; SIGN=1 AD=ADDR(P) ->NULLS IF S="" L1: I=CHARNO(S,1); ! first char IF I=' ' THEN S->(" ").S AND ->L1; ! chop leading spaces IF I='-' THEN S->("-").S AND SIGN=-1 AND ->L1 IF I='X' THEN S->("X").S AND HEX=1 AND ->L1 P=S UNLESS S->P.(" ").S THEN S="" I=1 WHILE I<=BYTEINTEGER(AD) CYCLE J=BYTE INTEGER(I+AD) ->FAULT UNLESS '0'<=J<='9' OR (HEX#0 AND 'A'<=J<='F') IF HEX=0 THEN TOTAL=10*TOTAL ELSE TOTAL=TOTAL<<4+9*J>>6 TOTAL=TOTAL+J&15; I=I+1 REPEAT IF HEX#0 AND I>9 THEN ->FAULT J<-TOTAL IF I>1 THEN RESULT =SIGN*J FAULT: S=P." ".S NULLS: RESULT =X'80808080' END ROUTINE KTIME(INTEGERNAME H,M,S,INTEGER DAYSECS) *LSS_DAYSECS; *IMDV_60; *IMDV_60 *ST_(H); *LSD_TOS *STUH_(S) *ST_(M) END ROUTINE KDATE(INTEGERNAME D,M,Y,INTEGER K) !*********************************************************************** !* K is days since 1st Jan 1900. Returns D:M:YY * !*********************************************************************** INTEGER W ! k=k+693902; ! days since CAESARS bday ! W=4*K-1 ! Y=W//146097 ! K=W-146097*Y ! D=K//4 ! K=(4*D+3)//1461 ! D=4*D+3-1461*K ! D=(D+4)//4 ! M=(5*D-3)//153 ! D=5*D-3-153*M ! D=(D+5)//5 ! Y=K *LSS_K; *IAD_693902 *IMY_4; *ISB_1; *IMDV_146097 *LSS_TOS ; *IDV_4; *IMY_4; *IAD_3 *IMDV_1461; *ST_(Y) *LSS_TOS ; *IAD_4; *IDV_4 *IMY_5; *ISB_3; *IMDV_153 *ST_(M); *LSS_TOS *IAD_5; *IDV_5; *ST_(D) IF M<10 THEN M=M+3 ELSE M=M-9 AND Y=Y+1 END INTEGERFN KDAY(INTEGER D,M,Y) IF M>2 THEN M=M-3 ELSE M=M+9 AND Y=Y-1 RESULT =1461*Y//4+(153*M+2)//5+D+58 END ROUTINE SETAD(INTEGER VALUE,AD) !*********************************************************************** !* Sets two byte at AD &AD+1 to value in character form * !*********************************************************************** *LSS_VALUE; *IMDV_100; ! in case >100 *LSS_TOS ; *IMDV_10 *USH_8; *IAD_TOS ; *IAD_X'3030'; ! to ASCII chars *LDTB_X'58000002'; *LDA_AD; *ST_(DR ) END ROUTINE TIMEEVAL(INTEGER FLAG) !*********************************************************************** !* Evaluate date&time from RTC and display to operator for corrn * !* must allow for any old rubbish in RTC on IPL ! * !*********************************************************************** INTEGER D,M,Y,HR,MIN,SEC,JDAY,DAYSECS,AD,ISA,RTC1,RTC2 CONSTLONGINTEGER MILL=1000000,SECSIN24HRS=86400 *RRTC_0; *ST_RTC1 IF RTC1&1#RTC2>>31 START ; ! guard bit indicates oflow ISA=COM_CLKX *LSS_RTC1; *UAD_1; ! overflow has happened here *ST_RTC1 *LB_ISA; *ST_(0+B ) FINISH RTC2=RTC2<<1 *LSD_RTC1 *JAT_5,<OK>; ! check for -ve *LSD_0 OK: *IDV_MILL; *IMDV_SECSIN24HRS *STUH_B ; *ST_JDAY *LSS_TOS ; *ST_DAYSECS COM_TOJDAY=JDAY KDATE(D,M,Y,JDAY) KTIME(HR,MIN,SEC,DAYSECS) AD=ADDR(COM_DATE1) SETAD(D,AD) SETAD(M,AD+3) SETAD(Y,AD+6) SETAD(HR,AD+12) SETAD(MIN,AD+15) SETAD(SEC,AD+18) IF FLAG#0 THEN C OPMESS("DT=".STRING(AD-1)." ".STRING(AD+11)) END EXTERNALROUTINE PARSE COM(INTEGER SRCE,STRINGNAME S) !*********************************************************************** !* Transcribe a command to a PON message and PON it * !*********************************************************************** INTEGERFNSPEC TAPEPLACE(INTEGERNAME A, B, C STRINGNAME S, INTEGER F) INTEGERFNSPEC DISCPLACE(INTEGERNAME A, B, C STRINGNAME S, INTEGER F) INTEGERFNSPEC GET MNEM(STRINGNAME S) OWNINTEGER SRCESERV CONSTINTEGER LIMIT=24, COMREP=X'3E0000' CONSTBYTEINTEGERARRAY PARAMS(1:LIMIT)=2,1,0,0,0,0,0,3,2,0,0,1,2,0,1(3), 2,2,2,1,2,2,0 IF SSERIES=YES START CONSTSTRING (7)ARRAY COMMAND(1:LIMIT)="PON ","SRCE ","PLOT ", "PLOD ","LABEL ","ILABEL ","FORMAT ","RREAD ", "SLOAD ","DUMP ","PRIME ","POFFMON","KMON ", "UNPLOT ","INH ","UNINH ","DIRVSN ","DT ", "XDUMP ","REP ","ISR ","ISW ","SHOW ","DCU " FINISH ELSE START CONSTSTRING (7)ARRAY COMMAND(1:LIMIT)="PON ","SRCE ","PLOT ", "PLOD ","LABEL ","ILABEL ","FORMAT ","RREAD ", "SLOAD ","DUMP ","PRIME ","POFFMON","KMON ", "UNPLOT ","INH ","UNINH ","DIRVSN ","DT ", "XDUMP ","REP ","ISR ","ISW ","SHOW ","GPC " FINISH SWITCH SWT(1:LIMIT) RECORD (PARMF) PP INTEGERARRAY DATA(1:6) INTEGER I, J, K, WORK, OP, D, M, Y, HR, MIN CONSTINTEGER SECSIN24HRS=86400 LONGINTEGER L STRING (40) P, Q ! RETURN IF LENGTH(S) = 0; ! ignore null lines ! PP=0 OP=SRCE>>8&7 P=S IF LENGTH(P)>23 START ; ! split long lines FOR I=23,-1,1 CYCLE EXIT IF CHARNO(P,I)=' ' REPEAT I=I-1 I=23 IF I=0 J=LENGTH(P) LENGTH(P)=I OPMESS2(OP,P) LENGTH(P)=J-I FOR K=1,1,J-I CYCLE CHARNO(P,K)=CHARNO(P,K+I) REPEAT FINISH OPMESS2(OP,P); ! log input line ! FOR I=1,1,LIMIT CYCLE ->FOUND IF S->Q.(COMMAND(I)).P AND Q="" REPEAT ERR: OPMESS2(OP,"????".S) RETURN ! FOUND: ! command recognised J=PARAMS(I); ! (minimum) no of parameters K=1 WHILE K<=J CYCLE DATA(K)=STOI(P) ->ERR IF DATA(K)=X'80808080' K=K+1 REPEAT ->SWT(I) SWT(1): ! PON (variable params) PP_DEST=DATA(1)<<16!DATA(2) FOR K=0,1,5 CYCLE I=STOI(P) IF I=X'80808080' AND CHARNO(P,1)='"' C AND P->("""").Q.("""").P START STRING(ADDR(PP_P1)+4*K)=Q K=K+LENGTH(Q)//4 FINISH ELSE INTEGER(ADDR(PP_P1)+4*K)=I REPEAT PP_SRCE=SRCESERV POUT: PKMONREC("OPER command",PP) PON(PP) RETURN SWT(2): ! SRCE = srce serv no for PON SRCESERV=DATA(1) RETURN SWT(3): ! PLOT T F D PGE NPAGES PP_DEST=X'240000'; ! bulk mover PP_SRCE=COMREP!SRCE&X'FF00' ->ERR UNLESS TAPEPLACE(PP_P2,PP_P3,P,1)=0 ->ERR UNLESS DISCPLACE(PP_P4,PP_P5,P,1)=0 I=STOI(P) ->ERR UNLESS I>0 PP_P1=X'04020000'+I PP_P6=M'PLOT' ->POUT SWT(4): ! PLOD FD FP TD TP NP PP_DEST=X'240000' PP_SRCE=COMREP!SRCE&X'FF00' ->ERR UNLESS DISCPLACE(PP_P2,PP_P3,P,1)=0 ->ERR UNLESS DISCPLACE(PP_P4,PP_P5,P,1)=0 I=STOI(P) ->ERR UNLESS I>0 PP_P1=X'02020000'+I PP_P6=M'PLOD' ->POUT SWT(5): ! LABEL SWT(6): ! ILABEL=IPL label PP_DEST=X'230000' PP_SRCE=0 PP_P1=GET MNEM(P) ->ERR IF PP_P1=0 ->ERR UNLESS LENGTH(P)=6 STRING(ADDR(PP_P2))=P PP_P4=I-5 PP_P5=M'DISC' PP_P6=M'LABL' ->POUT SWT(7): ! FORMAT MNEM LC UC LT UT PP=0; PP_DEST=X'260000' PP_P1=GET MNEM(P) ->ERR IF PP_P1=0 K=STOI(P) IF K<0 THEN PP_P2=K ELSE PP_P2=K<<16!STOI(P) K=STOI(P) IF K<0 THEN PP_P3=K ELSE PP_P3=K<<16!STOI(P) ->POUT SWT(8): ! RREAD removed 30th june 1980 (JM) ->ERR SWT(9): ! SLOAD DEV PAGE(Chopsupe only) IF COM_DATE2&X'FFFF'<M'78' THEN C OPMESS2(OP,"Date&time not given") AND RETURN PP=0; PP_DEST=X'3B0000' PP_P1=DATA(1) PP_P2=DATA(2) ->POUT SWT(10): ! DUMP T D NPAGES PP_DEST=X'240000'; PP_SRCE=COMREP ->ERR UNLESS TAPEPLACE(PP_P4,PP_P5,P,0)=0 ->ERR UNLESS DISCPLACE(PP_P2,PP_P3,P,0)=0 I=STOI(P) ->ERR UNLESS I>0 PP_P1=X'02040000'+I PP_P6=M'DUMP' ->POUT SWT(11): ! PRIME T D NPAGES PP_DEST=X'240000'; PP_SRCE=COMREP ->ERR UNLESS TAPEPLACE(PP_P2,PP_P3,P,0)=0 ->ERR UNLESS DISCPLACE(PP_P4,PP_P5,P,0)=0 I=STOI(P) ->ERR UNLESS I>0 PP_P1=X'04020000'+I PP_P6=M'PRME' ->POUT SWT(12): ! POFFMON POFFMON=DATA(1); RETURN SWT(13): ! KMON I=DATA(1) J=DATA(2) ->ERR UNLESS 0<=J<=1 L=LENGTHENI(1)<<I KMON=KMON&(L!!X'FFFFFFFFFFFFFFFF') IF J=1 THEN KMON=KMON!L COM_KMON=KMON RETURN SWT(14): ! UNPLOT PP_DEST=X'240000'; ! bulk mover PP_SRCE=COMREP!SRCE&X'FF00' ->ERR UNLESS DISCPLACE(PP_P2,PP_P3,P,1)=0 ->ERR UNLESS TAPEPLACE(PP_P4,PP_P5,P,1)=0 I=STOI(P) ->ERR UNLESS I>0 PP_P1=X'02040000'+I PP_P6=M'PLOT' ->POUT SWT(15): ! INH INHIBIT(DATA(1)); RETURN SWT(16): ! UNINH UNINHIBIT(DATA(1)); RETURN SWT(17): ! DIRVSN COM_DIRSITE=X'200'+(DATA(1)&3)*64 RETURN SWT(18): ! DT DATE TIME WORK=DATA(1); ! date *LSS_WORK; *IMDV_100; *IMDV_100 *ST_D; ! days *LSS_TOS ; *ST_M; ! months *LSS_TOS ; *ST_Y; ! year ->ERR UNLESS 1<=D<=31 AND 1<=M<=12 AND Y>=77 J=KDAY(D,M,Y); ! days since 01/01/1900 ! WORK=DATA(2); ! time *LSS_WORK; *IMDV_100 *ST_HR; ! hours *LSS_TOS ; *ST_MIN; ! mins ->ERR UNLESS 0<=HR<=23 AND 0<=MIN<60 *LSS_J; *IMYD_SECSIN24HRS; *ST_L L=(L+60*(60*HR+MIN))*1000000; ! microsecs since Jan 1900 I=COM_CLKX *LB_I; *LSS_L; *ST_(0+B ); ! set clock X register I=COM_CLKY; L=L>>1 *LB_I; *LSS_L+4; *ST_(0+B ) TIMEEVAL(0) RETURN SWT(19): ! XDUMP DUMPTABLE(32,DATA(1),DATA(2)) RETURN SWT(20): ! REP AT WITH I=DATA(1) *LDTB_X'18000004'; *LDA_I; *VAL_(LNB +1) *JCC_7,<ERR> J=INTEGER(I); INTEGER(I)=DATA(2) OPMESS2(OP,STRHEX(DATA(2))." reps ".STRHEX(J)) RETURN SWT(21): ! image store read I=DATA(1); *LB_I *LSS_(0+B ); *ST_J OPMESS2(SRCE>>8&255,"IS ".STRHEX(I)."=".STRHEX(J)) RETURN SWT(22): ! image store write I=DATA(1); J=DATA(2) *LB_I; *LSS_J; *ST_(0+B ) RETURN SWT(23): ! SHOW VIRTADDR LENGTH I=DATA(1); J=DATA(2) IF J<=0 OR J>64 THEN J=64 *LDTB_X'18000000' *LDB_J; *LDA_I *VAL_(LNB +1) *JCC_3,<ERR> CYCLE OPMESS(HTOS(I,4)." ".HTOS(INTEGER(I),8)." ". C HTOS(INTEGER(I+4),8)) I=I+8; J=J-8 EXIT IF J<=0 REPEAT RETURN SWT(24): ! DCU/GPC <TEXT> ->ERR IF LENGTH(P)>23 PP_DEST=X'300001' PP_SRCE=SRCE STRING(ADDR(PP_P1))=P ->POUT INTEGERFN GET MNEM(STRINGNAME S) !*********************************************************************** !* Extract a device mnemonic from S returning the string remnant * !*********************************************************************** INTEGER I, J STRING (15) P J=0 P="" IF S->P.(" ").S AND LENGTH(P)=4 THEN STRING(ADDR(I)+3)=P RESULT =J END INTEGERFN DISCPLACE(INTEGERNAME A, B, STRINGNAME S, C INTEGER FLAG) !*********************************************************************** !* Extract a disc no or label from S and set A&B in bulkmover format* !* flag=0 if no page no expected(when page 0 assumed) * !*********************************************************************** INTEGER I, J, K STRING (63) P I=STOI(S); B=0; K=0 IF I>=0 THEN A=I+M'ED00' AND ->PAGE AGN: RESULT =1 UNLESS S->P.(" ").S ->AGN IF P="" RESULT =1 UNLESS LENGTH(P)=6 FOR I=0,1,5 CYCLE BYTEINTEGER(ADDR(J)+I)=CHARNO(P,I+1) REPEAT A=J; B=K; ! 6 char vol label PAGE: IF FLAG#0 START I=STOI(S) IF I<0 THEN RESULT =1 B=B&X'FFFF0000'+I FINISH RESULT =0 END INTEGERFN TAPEPLACE(INTEGERNAME A, B, STRINGNAME S, C INTEGER FLAG) !*********************************************************************** !* Extract a tape no or label from S and set A&B in bulkmover format* !* flag=0 if no chap no expected (when 1 is assumed) * !*********************************************************************** INTEGER I, J, K STRING (63) P I=STOI(S); B=1; K=1 IF I>=0 THEN A=X'0031006E'+I AND ->CHAP AGN: RESULT =1 UNLESS S->P.(" ").S ->AGN IF P="" RESULT =1 UNLESS LENGTH(P)=6 STRING(ADDR(J))=P A=J; B=K CHAP: IF FLAG#0 THEN START I=STOI(S) IF I<0 THEN RESULT =1 B=B&X'FFFFFF00'+I&255 FINISH RESULT =0 END END ROUTINE COMREP(RECORD (PARMF)NAME P) !*********************************************************************** !* This routine collects the replies from routines kicked by the * !* operator using opcomm and parse * !*********************************************************************** SWITCH SW(0:3) ->SW(P_DEST&15) SW(0): ! bulk mover replies IF P_P1=0 THEN OPMESS("Load OK") C ELSE OPMESS("Load failed ".STRHEX(P_P1)) RETURN SW(1): ! reply from deallocate tape IF P_P2#0 THEN OPMESS("Dealloc fails - ".STRING(ADDR(P_P3))) END INTEGERFN HANDKEYS INTEGER I I=ISAS(ISAS PTR+HK OFFSET) *LB_I; *LSS_(0+B ); *EXIT_-64 END EXTERNALROUTINE SLAVESONOFF(INTEGER MASK) !*********************************************************************** !* Turn off all slaves if MASK=0 * !* Turn on all slaves if MASK=-1 * !* or turn off and on slectively if MASK == a bitmask * !*********************************************************************** ONOFF(SLAVES OFFSET,MASK) END ROUTINE ONOFF(INTEGER OFFSET,MASK) INTEGER I,J,K I=ISAS(ISAS PTR+OFFSET) J=I>>16; I=I&X'FFFF' K=J!!(-1); J=J&(MASK!!(-1)) *LB_I; *LSS_(0+B ) *AND_K; *OR_J; *ST_(0+B ) END EXTERNALROUTINE CONTROLLERDUMP(INTEGER CONTYPE,PT) PRINTSTRING("CHOPSUPE can not dump PT=".HTOS(PT,2)." ") END EXTERNALROUTINE SEMALOOP(INTEGERNAME SEMA,INTEGER PARM) !*********************************************************************** !* Loop till a SEMA comes free. Maxcount is large enough so that * !* it is only invoked when another OCP has gone down holding a sema * !*********************************************************************** CONSTINTEGER MAXCOUNT=64000 INTEGER I FOR I=1,1,MAXCOUNT CYCLE *INCT_(SEMA) *JCC_7,<ON> RETURN ON: REPEAT PRINTSTRING(" SEMA forced free at ".STRHEX(ADDR(SEMA))) SEMA=0 END IF SSERIES=YES START EXTERNALROUTINE RETRY REPORTING(INTEGER PARM) !* !* Turn retry reporting on or off !* ONOFF(INH REPS OFFSET,PARM) END EXTERNALINTEGER DCU RFLAG=0; ! GDC reconnects DCU1 streams if non-zero EXTERNALROUTINE DCU1 RECOVERY(INTEGER PARM) PRINTSTRING("CHOPSUPE cannot recover DCU1s ") END ROUTINE LIGHTS(INTEGER PATTERN) !********************************************************************* !* Display 'PATTERN' on the SCP monitor * !********************************************************************* *LB_X'6016' *LSS_PATTERN *ST_(0+B ) END FINISH ENDOFFILE