%CONSTSTRING(25) VSN = "GPC34 17TH NOV 80"; ! ************************************************GPC GPC GPC ! ! EMAS 2900 SUPERVISOR NOTE ! No: 5 ! Date: 21/05/80 ! Author: A.Gibbons ! ! ! %EXTERNAL ROUTINE GPC(%RECORDNAME P) ! ! 1. CONVENTIONS ! The record spec for the parameter is ! %RECORDFORMAT PARMF(%INTEGER DEST,SRCE,P1,P2,P3,P4,P5,P6) ! where ! DEST is considered as two half words DSNO and DACT. DSNO ! must be GPC's DSNO ! DACT is set according to the function required. ! ! SRCE is considered as two halfwords SSNO and SACT. ! SSNO is SNO of ORIGINATOR and SACT is DACT for ! the reply. ! ! DEVICE ENTRIES ! Each device on a GPC is allocated an area (a Device Entry) at ! GROPE time. The address of the Device Entry is given by GPC ! in P_P3 each time a response is generated for ALLOCATE, ! DE-ALLOCATE, EXECUTE and INTERRUPT. The format of the Device ! Entry is given elsewhere. ! ! ! ! ! 2. INPUTS TO GPC ! ! DACT = 2 INITIALISATION. This must be the first call ! P1 = ADDR of preprepared CONFIG TABLE ! P2 = address of PROCESS LIST picture ! DEST must contain SNO for GPC ! For each OPER, GPC pons an allocate message to ! itself with ! P2 = X'320005' ! SRCE = X'320002' ! OP<<8 ! For each FE, GPC pons an allocate message to itself ! with ! P2 = X'390005 ! SRCE = X'390002' ! For each TAPE stream, GPC pons a message ! DEST = X'310004' ! SRCE = X'300000' ! P1 = mnemonic ! ! ! DACT = 11 ALLOCATE DEVICE ! P1 = Device Mnemonic ! P2 = full DEST (i.e. DSNO+DACT) to be used for all ! interrupt responses (ATTENTION, TERMINATION, PCI &RI) ! RESPONSE ! P1 = 0 success ! 1 mnemonic invalid ! 2 alreadt allocated ! P2 = SNO for device to be used in EXECUTE ! P3 = address of device entry ! P6 = mnemonic ! additionally, for an OPER : ! D_X2 = buffer area address ! D_RESP0 = number of screens ! D_X1 = size of buffer area ! NOTE: P4 & P5 are not changed and may be used by the ! caller to hold data ! ! ! DACT = 5 DE ALLOCATE DEVICE ! P1 = device mnemonic ! RESPONSE ! P1 = 0 success ! 1 mnemonic 'LP' not allowed ! 2 mnemonic invalid ! 3 device not allocated ! P3 = address of device entry ! ! ! DACT = 12 EXECUTE CHAIN ! P1 = RCB address ! P2 = SNO for device returned by ALLOCATE in P2 ! P3 = RSD << 8 ! PAW FUNCTION << 4 ! SAWFLAGS ! (RSD is one bit ! 0 = no special action ! 1 = if chain terminates abnormally, do ! 'READ STREAMS CONTROLLER STATUS' ! controller command. The four status bytes are ! returned in P_P5) ! P4 = an ident field to be returned in P_P6 of ! interrupt responses. ! RESPONSE ! NOTE A response ! is sent only if the call fails. The response to ! a successful call is generated when an interrupt ! is received ! P1 = 1 SNO out of range ! 2 device not ready ! P2 = SNO i.e. P2 of request ! P3 = address of device entry (only if P1 > 1) ! P4 = 0 ! P5 = 0 ! P6 = ident i.e. P4 of request ! ! ! DACT = 6 CLOCK INTERRUPT ENTRY, no parameters, no responses ! ! ! DACT = 3 INTERRUPT ENTRY ! P1 = PT (PORT + TRUNK) ! RESPONSE ! A message is ponned to the dest that was ! supplied in P2 of the ALLOCATE ! P1 = stream response word RESP0 with byte0 ! overwritten with device SNO as returned ! by ALLOCATE ! P2 = stream response word RESP1 ! for all interrupts except attentions, ! RESP0 and RESP1 are also written to the ! appropriate fields in the device entry. ! If a chain has timed out, RESP1 is set ! to -1. ! ! P3 = address of device entry ! P4 = response analysis flags from the response ! to SENSE command (RESP0 >> 16) relevant ! only after an abnormal termination or timeout ! if the rightmost byte does not indicate ! successful termination, then the sense ! information is suspect. ! The sense information is pointed to by the field ! SENS AD in the device entry. It is laid out as ! SECONDARY STATUS, TERTIARY STATUS (as many bytes ! as appropriate) and PRIMARY STATUS. ! P5 = controller status, relevant only if RSD bit ! was set in EXECUTE ! P6 = ident i.e. P4 of most recent EXECUTE ! The following logic may be used to analyse the ! interrupt response: ! integer INTERRUPT ANALYSIS FLAGS ! INTERRUPT ANALYSIS FLAGS = P_P1 >> 20 & 15 ! if INTERRUPT ANALYSIS FLAGS = 1 ! then ATTENTION ! else if INTERRUPT ANALYSIS FLAGS & X'C' > 0 ! then TERMINATION ! else SOMETHING ELSE ie PCI, RI ! fi ! fi ! ! ! ! ! ! DACT = 8 SPECIAL ALLOCATE FOR USE BY ENTER, CALLED NOT PON'D ! P1 = PTSM ! RESPONSE ! P1 = 0 success ! 1 mnemonic invalid ! 2 stream disconnected ! P3 = address of device entry (unless P1 = 1) ! ! ! ! DACT = 1 GPC COMMAND ! P1-P6 contain up to 23 characters of string ! The forms recognised are: ! GPC QS mnemonic ! gives the current state of the device: ! NOT ALLOC, READY, REQ FIRED, SNS FIRED, QUEUED or ! DISCNCTED ! GPC CDS mnemonic OFF ! configures a device (stream) off (see Operations ! Note ) ! GPC CDS mnemonic ON ! GPC CDM mnem1 mnem2 ! Configures an ungroped device in or a groped device out ! E.G. GPC CDM ZX0 LP1 or GPC CDM CR0 ZX1 ! GPC ? ! gives the state of all the devices known to GPC ! ! ! ! ! ! 3. MESSAGES PRODUCED ON LOG (L) AND/OR OPER (O) ! ***** OPER MESSAGES REMOVED 18/7/80 (JM) ! ! from 'CONNECT STREAMS' ! (L ) GPC CONNECT STREAMS pts ! (L ) (DIS)CONNECT STRMs RESP0=response ! (L ) SAW FAILS=n PAW FAILS=n ! (L ) ABN TERM FOR GPTSM gptsm ! ! ! from 'GPC DUMP' ! (L ) GPC INIT RES=response ! from 'PAW NOT CLEARED' ! (L ) GPC PAW NOT CLEARED PT=pt, PAW=paw ! (L ) SAW NOT CLEARED ! from 'READ STRM DATA' ! (L ) GPC READ STRM DATA PTS=pts ! (L ) CRESP0=response ! FIRST ENTRY TO GPC ! (L ) GPC VERSION identifier ! WHEN TIMEOUT DETECTED ! (LO) GPC TIMEOUT dev pt ! from AN INVALID CALL ON GPC(ACT=7) DIS/RE-CONNECT STRM ! (L ) GPC DIS/CONNECT DEV P2=i FLAG=f ! from THE INTERRUPT HANDLER ! (LO) GPC ABTERM pts dev response ! (L ) GPC SPURIOUS INTERRUPT PTS=pts RESP0=response ! MONITOR MESSAGES ! (L ) GPC( IN): ptrec ! (L ) GPC( OUT): ptrec ! (L ) GPC( PONS): ptrec !! !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! EXTERNAL REFERENCES ! ! ! ! ! !---------------------------------------------------------------------------------------------------- %EXTERNALINTEGERFNSPEC REALISE(%INTEGER I) %EXTERNALROUTINESPEC SLAVESONOFF(%INTEGER ONOFF); ! 0=OFF, -1=ALL ON %EXTERNALROUTINESPEC GET PSTB(%INTEGERNAME PSTB0,PSTB1) %EXTERNALROUTINESPEC SEMALOOP(%INTEGERNAME SEMA) %EXTERNALROUTINESPEC CONTROLLER DUMP(%INTEGER CONTYPE,PT) %EXTERNALROUTINESPEC WAIT(%INTEGER MILLISECONDS) %EXTERNALROUTINESPEC DUMP TABLE(%INTEGER TABNO,ADR,LEN) %EXTERNALROUTINESPEC PKMONREC(%STRING(20)TXT,%RECORDNAME P) %EXTERNALSTRINGFNSPEC HTOS(%INTEGER I,PL) %EXTERNALROUTINESPEC PON(%RECORDNAME P) !%EXTERNALROUTINESPEC OPMESS2(%INTEGER OPER, %STRING(63) S) %SYSTEMROUTINESPEC MOVE(%INTEGER LENGTH,FROM,TO) %IF MULTIOCP = YES %START %EXTERNALROUTINESPEC RESERVE LOG %EXTERNALROUTINESPEC RELEASE LOG %FINISH ! %IF (MONLEVEL >> 1) & 1 = YES %START ! KMONNING REQUIRED %EXTRINSICLONGINTEGER KMON %CONSTINTEGER KMONNING = YES %FINISH %ELSE %START %CONSTINTEGER KMONNING = NO %FINISH !---------------------------------------------------------------------------------------------------- %CONSTINTEGER ABNORMAL TERMINATION = X'00400000' %CONSTINTEGER CONTROLLER DETECTED ERROR = X'00410000' %CONSTINTEGER DISCONNECTED = 5 %CONSTINTEGER DO CONTROLLER REQUEST = X'04000000' %CONSTINTEGER DO STREAM REQUEST = X'01000000' %CONSTINTEGER ENDLIST = 255 %CONSTINTEGER FE = 14 %CONSTINTEGER GET STRM DATA = 16 %CONSTINTEGER PROCESSING INTERRUPT=1 %CONSTINTEGER TIMING OUT=2 %CONSTINTEGER GPC DEST = X'00300000' %CONSTINTEGER GPC SNO = X'30' %CONSTINTEGER INIT CONTROLLER = X'32000010' ! 3=NO TERM INTS ! 2= INIT ! 10=BYTE COUNT FOR INIT WORDS %CONSTINTEGER LIMIT = 5 %CONSTINTEGER LOAD MICROPROGRAM = X'08000000' %CONSTINTEGER LOID = X'6E' %CONSTINTEGER LP = 6 %CONSTINTEGER MT = 5 %CONSTINTEGER NORMAL TERMINATION = X'00800000' %CONSTINTEGER NOT ALLOCATED = 0 %CONSTINTEGER OK = 0 %CONSTINTEGER OP = 8 %CONSTINTEGER PRIV ONLY = X'00004000' %CONSTINTEGER QUEUED = 4 %CONSTINTEGER RA0AD = X'81000000' %CONSTINTEGER RCB BOUND = 32 %CONSTINTEGER READ STREAM DATA = 7 %CONSTINTEGER READ CONTROL STREAM STATUS=5 %CONSTINTEGER READ STREAMS CONTROLLER STATUS = 3 %CONSTINTEGER READY = 1 %CONSTINTEGER REQUEST FIRED = 2 %CONSTINTEGER SENSE FIRED = 3 %CONSTINTEGER SLOTSI = 32 %CONSTINTEGER SPURIOUS LIMIT = 20 %CONSTINTEGER TICK INTERVAL = 2 %CONSTINTEGER TRUNKADDR = X'40000800' %CONSTINTEGER COMADDR=X'80C00000' %CONSTSTRING(4)%ARRAY COMMAND(1:LIMIT) = "QS ", "CDS ", "CDM ", "? ", "SET " %CONSTSTRING(9)%ARRAY STATES(0:5) = "NOT ALLOC", "READY", "REQ FIRED", "SNS FIRED", "QUEUED", "DISCNCTED" !---------------------------------------------------------------------------------------------------- %OWNINTEGER CAAS BASE %OWNINTEGER GPCT BASE %OWNINTEGER LAST SLOT %EXTERNALINTEGER LOPT %EXTERNALINTEGER HIPT; ! TO TRAP WAYWARD PON %OWNINTEGER MECHPT %OWNINTEGER NO OF GPCS %OWNINTEGER PT GPC BASE %OWNINTEGER PTS BASE %OWNINTEGER RECAT %OWNINTEGER STRMQ BASE %OWNBYTEINTEGERARRAYNAME MECHSLOTS %OWNBYTEINTEGERARRAYNAME PTS TO SLOT %OWNBYTEINTEGERARRAYNAME PT TO GPC %OWNBYTEINTEGERARRAYNAME STRM Q %OWNINTEGERARRAYNAME CAAS %OWNINTEGERARRAYNAME TABLE %OWNINTEGERARRAYNAME STRM SEMAPHORE %OWNINTEGERARRAY SPURIOUS INTS(0:15) %OWNSTRING(63) WK ! ! %EXTERNALINTEGER LP ILLCHAR=X'07'; ! ERCC VALUE (ALSO USED BY GROPE) ! ! LP repertoire addresses and lengths for each of 16 cartidge settings %OWNINTEGERARRAY REPERTOIRE A(0:15) %OWNINTEGERARRAY REPERTOIRE S(0:15) !---------------------------------------------------------------------------------------------------- %CONSTINTEGERARRAY LP96REP(0:23)=%C X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60',X'7B6B614E',X'C1C2C3E9', X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C',X'D4D5D6D7',X'D9C9C6D3', X'E5E6E7E8',X'7E4D505D',X'4C6D3F6E',X'5B7A7C4F',X'6C5E7F6F', X'4AE05F5A',X'A8A979F0',X'81828384',X'85868788',X'89919293', X'94959697',X'9899A2A3',X'A4A5A6A7',X'C06AA1D0' ! %CONSTINTEGERARRAY LP384REP(0:95)= %C X'F0F1F2F3',X'F4F5F6F7',X'F8F94B9C',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C', X'D4D5D6D7',X'D9C9C6D3',X'E5E6E7E8',X'7E4D505D', X'6C5E7F6F',X'4AE05F5A',X'4C6D3F6E',X'5B7A7C4F', X'81828384',X'85868788',X'89919293',X'F0F1F2F3', X'F4F5F6F7',X'F8F94B60',X'94959697',X'9899A2A3', X'A4A5A6A7',X'A8A979F0',X'9EADEFCA',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C', X'D4D5D6D7',X'D9C9C6D3',X'E5E6E7E8',X'7E4D505D', X'6C5E7F6F',X'4AB7A05A',X'F0F1F2F3',X'F4F5F6F7', X'F8F94B60',X'4CF08B6E',X'5B7A7C4F',X'C06AA1D0', X'9A6D749B',X'FCEAAFED',X'ACAB8F8E',X'8DB5B4B3', X'787776DC',X'DDDEDFB8',X'B9BABBB0',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D9C9C6D3', X'D1D2D85C',X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60', X'D4D5D6D7',X'E5E6E7E8',X'7E4D505D',X'6C5E7F6F', X'4AE05F5A',X'4CF08B6E',X'5B7A7C4F',X'A8A979F0', X'81828384',X'85868788',X'89919293',X'94959697', X'9899A2A3',X'A4A5A6A7',X'B1B2FAFB',X'C1C2C3E9', X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60',X'7B6B614E', X'C4E4E2E3',X'C7C57DC8',X'D9C9C6D3',X'D1D2D85C', X'D4D5D6D7',X'E5E6E7E8',X'7E4D505D',X'6C5EDBCB', X'4AB7A05A',X'4CF08B6E',X'5B7A7C4F',X'EBBC75BD', X'8CAEBFBE',X'B6AAFDFE',X'9DEE80DA',X'C06D6AD0' ! %CONSTBYTEINTEGERARRAY LCLETTS(1:26)= %C 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' !---------------------------------------------------------------------------------------------------- ! ! !---------------------------------------------------------------------------------------------------- ! GPC MICROPROGRAM FOLLOWS AS %OWNINTEGERARRAY GPCMPROG(0:511) ! PROGRAM C03 PATCH LEVEL 1 %ENDOFLIST %OWNINTEGERARRAY GPCMPROG(0:511)= %C X'F160F171',X'482049E0',X'4022802C',X'E80AF0C9', X'000AD009',X'80054265',X'9320BE0A',X'100A8005', X'C213CAB3',X'8025CA33',X'8223CA53',X'8275CAD3', X'8005CA93',X'80C2CA73',X'8005CB34',X'8005CAF3', X'82FACAD4',X'80788005',X'C273C2D3',X'80298005', X'C2B38213',X'8210182E',X'93088007',X'4820E00C', X'740C500B',X'930FB725',X'F9C0F16C',X'DEEB21CC', X'EB4BE008',X'29E82C8C',X'61CC2CAC',X'61EC4C6B', X'7968B795',X'F9C00CCC',X'610CFC00',X'61ECFC00', X'70CC0825',X'818F8070',X'48400825',X'C2D4CA93', X'804AA2D4',X'BC091005',X'CAD48059',X'C2738005', X'9062805F',X'B21AA27A',X'A29A82D9',X'B809A674', X'10054989',X'C2D48068',X'B2F4A2D4',X'C2F4B2F4', X'EA131013',X'C6732013',X'98019205',X'98020835', X'C2738005',X'A2F44282',X'498C9205',X'8005A83D', X'A9D4F3AC',X'DCAC200C',X'4BC0700E',X'090C4042', X'B3ACE80E',X'240C5006',X'C00680B0',X'782CB795', X'F9C0A335',X'AED45017',X'500C0C17',X'C073A9F4', X'F48C501F',X'640E080C',X'500EC873',X'AAF40D15', X'500C4FE0',X'68972CF5',X'12E1EA57',X'E017C274', X'80A6B795',X'F9C0A673',X'1059C033',X'80ACF800', X'90BAC008',X'BA0ACAF4',X'80054065',X'80DC4BE0', X'BC0A100A',X'4BC0C883',X'81229341',X'8180E41F', X'1122A150',X'C813A011',X'A2D39320',X'BA0AF800', X'98019308',X'BC0A100A',X'A83D9316',X'782CB795', X'F9C0A735',X'5017500C',X'0C17C073',X'AE93501F', X'930F0D15',X'68972D15',X'12E1C033',X'80DCF800', X'90BAC008',X'BA0AAB74',X'A2739341',X'82E1E006', X'5826EFF4',X'50085826',X'32A82768',X'C014AEF4', X'9012ABF2',X'5826F177',X'F168FC00',X'91972C37', X'C1A83C37',X'61770835',X'E40C6908',X'DFEC2173', X'58260CF5',X'501F9341',X'82E1E018',X'5826F177', X'AEB49197',X'58262C37',X'C1DAFC00',X'501F9341', X'82E1E419',X'6077A2B4',X'F573F9C0',X'C21481B4', X'C1F4C9D4',X'82E10835',X'0C06C01F',X'B3B7B01D', X'A15DA17D',X'A1B04298',X'A3144D81',X'10050905', X'8180DEF3',X'200CEB6C',X'E00CF168',X'DDE321C8', X'486829E8',X'2D4C632C',X'0C2C7B8C',X'0C2C70CC', X'0C0DC00E',X'4D00117D',X'0C4C70AC',X'4920F56E', X'117D0C4C',X'70AC0C25',X'70C88180',X'0C2C708C', X'48408170',X'0C2C70AC',X'0C257AC8',X'814B4840', X'0C2C790C',X'920B817D',X'640F0815',X'F575117D', X'09150C1F',X'C006920B',X'817D5C26',X'5004EBA4', X'E004920B',X'817D5C26',X'9002ABE2',X'920B817D', X'5C26500D',X'EBADE01F',X'93478180',X'E00D920B', X'81315406',X'500C49C0',X'C00C49E0',X'81314B20', X'920B817D',X'4B00C0E3',X'817A6E2F',X'08104716', X'117D5E2F',X'50108178',X'4840A500',X'11854840', X'9205A120',X'A1E0A2E4',X'0C07C101',X'DDE321C0', X'4BE0C053',X'A011A3E9',X'A6D31005',X'48409205', X'A2E4B160',X'A1E00C0B',X'C0C0818A',X'EB532418', X'C01F541F',X'501DEBDD',X'42229801',X'C0FD9802', X'E00CA8EC',X'DDF36A8C',X'EF5D200C',X'034C0CB5', X'732C28B5',X'EB5D2418',X'C01F541F',X'501DC8FD', X'980126D3',X'119C0855',X'C9F48287',X'C9D482B9', X'919782E1',X'0835F16C',X'DCFD21CC',X'C1FD81D7', X'C23482E1',X'292CB67A',X'F9A0F17B',X'0C2C612C', X'FC006ACC',X'498842A2',X'A21A4D8F',X'11D1498D', X'09B5A354',X'A233BC0A',X'100A82E1',X'0835282C', X'CA3481E3',X'2CAC628C',X'2C2C62CC',X'2C6C630C', X'FC00634C',X'C0DD81EA',X'A01FA03F',X'B3F70D75', X'11FE0835',X'EB5D075A',X'C00CC7FD',X'706CC2B4', X'82E12419',X'C00C582C',X'0C555017',X'500CA774', X'501F9341',X'82E1E41F',X'60F74284',X'4983A754', X'10112895',X'2D1512E1',X'EA15E00C',X'DCF5686C', X'E0159801',X'2887C007',X'98020887',X'9801B795', X'F9C08217',X'DE5221D5',X'AB55A375',X'A315A335', X'906282F6',X'82E3C053',X'A0110C13',X'C1D0A190', X'BA099801',X'B715F9C0',X'AA33CA5A',X'A2F3CB54', X'8252CB14',X'8238C334',X'823FC2D3',X'8232A633', X'10050855',X'AB34C29A',X'82F082F6',X'82F00835', X'AB149242',X'82D92A35',X'ADB011B4',X'0835A735', X'12F6EA3B',X'E01BF56C',X'689BC09D',X'AA9ADB7A', X'F55DC16C',X'DC6C216C',X'C61A686C',X'CAF49801', X'9802C87D',X'921CAB54',X'924282D9',X'C09D825F', X'C23AC19D',X'82ABA1D4',X'A69310C2',X'C0BD82D7', X'C23AC19D',X'8266A693',X'10C2EB53',X'E00CCA3A', X'082C0C2C',X'C1D3D9F3',X'1C2C200C',X'034C2D35', X'708C2CB5',X'11B982E1',X'C87D921C',X'AA53C19D', X'827DA1F4',X'A69310C2',X'DDF3200C',X'EB4C0753', X'C00C2DD5',X'708C0CB5',X'12E10833',X'919782E1', X'0895C0DD',X'8293A01F',X'A03FB3F7',X'498B0955', X'A7541011',X'EB5D075A',X'C00CC7FD',X'706CC2B4', X'82E12419',X'C00C582C',X'0C555017',X'500CA774', X'501F9341',X'82E1E41F',X'60B7498B',X'A7541011', X'2D1512E1',X'EB53E00C',X'CA3A082C',X'0C2CC1D3', X'D9F31C2C',X'200C034C',X'2D35786C',X'82E128B5', X'919782E1',X'C87D921C',X'C09D82CE',X'C19D82C4', X'A1D4A693',X'10C2DDF3',X'200CEB4C',X'0753C00C', X'0CB5706C',X'82E10C33',X'12B809D5',X'C0BD82D7', X'C19D82D5',X'A69310C2',X'AE3A1266',X'A51012DB', X'A130A2F4',X'EA3BE411',X'F9000C1A',X'C1B082E8', X'498D9205',X'CA138213',X'A2F4A130',X'A1F00C13', X'C1D0C053',X'A011AA73',X'BA09A6D3',X'1011B170', X'0C1AC0F0',X'DCFA21B0',X'82EA9205',X'A170A5F0', X'12DAAAF3',X'CAF48022',X'F17DF17F',X'B3D74284', X'A3344D8A',X'1005B715',X'F9C00C55',X'12F64BC0', X'740E5008',X'C8089802',X'4BE08801',X'F08C640E', X'080C540E',X'500C4BE0',X'98014043',X'B7AC131D', X'F3ACDCAC',X'200C090C',X'E80E200C',X'98019316', X'084C540C',X'50061C4E',X'68669308',X'98016C2C', X'0810640C',X'08114067',X'E00C540C',X'5006B806', X'640C0806',X'930FB809',X'AAD3F170',X'C8114880', X'F1719803',X'229F283F',X'A81FD83F',X'09159802', X'EA37E017',X'C43D62B7',X'4137413A',X'EFB4787F', X'EBA40835',X'07BFC008',X'EFBF60A8',X'E4087088', X'9801E008',X'0835A808',X'DFC82008',X'EE92787F', X'EA822008',X'5C28500C',X'5008EE3F',X'900BC374', X'8368DEEC',X'787DDB6C',X'E008EB74',X'0368B708', X'78689801',X'08353828',X'F0CCAA94',X'C82CA294', X'EA3F2637',X'C0082828',X'C9A89801',X'EA28022C', X'AFEB786C',X'98010835',X'C06B8385',X'C02B9801', X'A3EB540B',X'900B837D',X'0835CA94',X'8395C02B', X'9801EA3F',X'C83DEA28',X'E01FB34C',X'382CF1EB', X'D83F0875',X'328B9802',X'08354063',X'2855C02B', X'98010875',X'E81FC83D',X'E008B2AC',X'382CF07F', X'EA37241F',X'C00CABEB',X'F17EDD28',X'21DEEA8B', X'201E282C',X'F168DD2C',X'21C8D928',X'2017B108', X'E8080017',X'B2A8E808',X'000CFC00',X'716C583E', X'C03D285E',X'040C9016',X'C0369801',X'FC007ACC', X'541E9008',X'C0289801',X'C81783CA',X'085EC83D', X'289E200C',X'B12BE80B',X'0017EA88',X'E008A048', X'D82CC03D',X'D83F32C8',X'08359802',X'00000000', X'00000000',X'00000000',X'00000000',X'00000000', X'00000000',X'00000000',X'00000000',X'00000000', X'00000000',X'00000000',X'00000000',X'00000000', X'00000000',X'00000000',X'00000000',X'0000F2B2', X'B80AA213',X'498D9800',X'0C030001',X'ED81ADFB' %LIST ! ! !---------------------------------------------------------------------------------------------------- !* COMMUNICATIONS RECORD FORMAT - EXTANT FROM CHOPSUPE 20J ONWARDS * %RECORDFORMAT COMF(%INTEGER OCPTYPE,IPLDEV,SBLKS,SEPGS,NDISCS, %C DDTADDR,GPCTABSIZE,GPCA,SFCTABSIZE,SFCA,SFCK,DIRSITE, %C DCODEDA,SUPLVN,TOJDAY,DATE0,DATE1,DATE2, %C TIME0,TIME1,TIME2,EPAGESIZE,USERS,CATTAD,DQADDR, %C %BYTEINTEGER NSACS,RESV1,SACPORT1,SACPORT0, %C NOCPS,RESV2,OCPPORT1,OCPPORT0, %C %INTEGER ITINT,CONTYPEA,GPCCONFA,FPCCONFA,SFCCONFA, %C BLKADDR,RATION,SMACS,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,SP1, %C SP2,SP3,SP4,SP5,SP6,SP7,SP8, %C LSTL,LSTB,PSTL,PSTB,HKEYS,HOOT,SIM,CLKX,CLKY,CLKZ, %C HBIT,SLAVEOFF,INHSSR,SDR1,SDR2,SDR3, %C SDR4,SESR,HOFFBIT,S2,S3,S4,END) %RECORDFORMAT ALEF(%INTEGER %C S, %C A) !---------------------------------------------------------------------------------------------------- %RECORDFORMAT CA0F(%INTEGER %C MARK, %C PAW, %C PIW0, %C PIW1, %C CSAW0, %C CSAW1, %C CRESP0, %C CRESP1); ! LENGTH OF THIS RECORD FORMAT IS X'20' !---------------------------------------------------------------------------------------------------- %RECORDFORMAT CASEF(%INTEGER %C SAW0, %C SAW1, %C RESP0, %C RESP1) !---------------------------------------------------------------------------------------------------- %RECORDFORMAT CAF(%INTEGER %C MARK, %C PAW, %C PIW0, %C PIW1, %C CSAW0, %C CSAW1, %C CRESP0, %C CRESP1, %C %RECORDARRAY S ENTRY(0:14)(CASEF)); ! LENGTH X'110' !---------------------------------------------------------------------------------------------------- %RECORDFORMAT DEVICE ENTRY F(%INTEGER %C X1, %C GPTSM, %C PROP A, %C SECS SINCE, %C CA A, %C G RCB A, %C LB A, %C AL A, %C X2, %C RESP0, RESP1, %C SENSE1, SENSE2, SENSE3, SENSE4, %C X3, X4, %C IDENT, %C X5, %C MNEMONIC, %C DEVICE ENTRY S, %C PAW, %C U SAW 0, %C U RCB A, %C SENSE DATA A, %C LOG MASK, %C TR TABLE A, %C UA S, %C UA A, %C TIMEOUT, %C PROPS0, PROPS1) !---------------------------------------------------------------------------------------------------- ! FLAGS : ONLY ONE BIT USED 'GET STRM DATA' ! BUSY : MULTI-OCPS ONLY. MUST HOLD STRM SEMA TO SET ! : 0 = OK ! : 1 = PROCESSING INTERRUPT ! : 2 = TIMING OUT ! STATE : VALID STATES ARE ! 0 NOT ALLOCATED ! 1 READY ! 2 REQUEST FIRED ! 3 SENSE FIRED ! 4 QUEUED ! 5 DISCONNECTED %RECORDFORMAT GPCT F( %C %BYTEINTEGER %C FLAGS, %C DEVTYPE, %C BUSY, %C LINK, %C %INTEGER %C X4, %C RESPONSE DEST, %C DEVICE ENTRY A, %C C STATUS, %C PTSM, %C MNEMONIC, %C %BYTEINTEGER %C MECHINDEX, %C PROPS03, %C SERVRT, %C STATE) !---------------------------------------------------------------------------------------------------- %RECORDFORMAT INIF(%INTEGER %C PSTS, %C PSTA, %C CAA, %C SOE) !---------------------------------------------------------------------------------------------------- %RECORDFORMAT PARMF(%INTEGER %C DEST, %C SRCE, %C P1,P2,P3,P4,P5,P6) !---------------------------------------------------------------------------------------------------- ! LIMFLAGS ! BITS 0-13 BOUND OF LOCAL SEGMENT TABLE ! 16-23 FLAGS ! 16 INITWORD IS VALID ! 17 TRUSTED COMMAND CHAIN ! 28-31 ACR ! LB S,A LOGIC BLOCK DESCRIPTOR ! AL S,A ADDRESS LIST DESCRIPTOR ! INITWORD ! BITS 0- 7 MECH ! 8-15 COMMAND MASK ! 16-23 STATUS MASK ! 24-31 MODE %RECORDFORMAT RCB F(%INTEGER %C LIM FLAGS, %C LOCAL SEG TABLE A, %C LB S, %C LB A, %C AL S, %C AL A, %C INIT WORD, %C X1) %OWNBYTEINTEGERARRAYFORMAT BIFT(0:383) %OWNINTEGERARRAYFORMAT IFT(0:1023) ! ! DECLARATIONS FOR CDS DEV ON ! %OWNINTEGER XSTRM = -1, XPT = -1 %OWNINTEGER XINIT, XA, XSLOT, XMNEMONIC, XDEVTYPE, %C XGPC, XCAA, XGPTSM, XPTS, XSTATE, XSRCE %OWNINTEGER XCART, XSTYLE, XLEN, XS %OWNINTEGERARRAY X(0:117) %OWNRECORDNAME XRCB(RCBF) %OWNRECORDNAME XCA(CAF) %OWNRECORDNAME XSENT(CASEF) %OWNRECORDARRAYFORMAT ALEFF(0:3)(ALEF) %OWNRECORDARRAYNAME XALE(ALEF) %OWNINTEGERARRAY XLBE(0:7) = %C X'00F10900', X'04F10800', X'04F00E00', X'00F00402', X'80F02504', X'80F00106', X'82F00500', X'80F00106' ! ! DECLARATIONS FOR CDM ! %CONSTBYTEINTEGER ZX=11 %CONSTINTEGER CDMDEVLIMIT=5 %CONSTINTEGERARRAY CDMDEV(0:CDMDEVLIMIT)=%C M'FE',M'LP',M'CR',M'CP',M'PR',M'PT' %CONSTBYTEINTEGERARRAY CDMDEVTYPE(0:CDMDEVLIMIT)=14,6,4,3,2,1 %CONSTINTEGERARRAY CDMDEVTIMEOUT(0:CDMDEVLIMIT)=%C X'01FF0003',60,300,600,60,60; ! TOP OF FEP WORD IS LOGMASK !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! NOTES ON GPC PROGRAM ! ! ! ! ! ! 1. SOME CALLING SEQUENCES. ! PAW NOT CLEARED/GPC DUMP/GPC INIT ! CONNECT STREAMS/PON GPC INT ! HENCE ROUTINES ARE DECLARED IN REVERSE ORDER ! ! ! 2. SLOTS. ! A SLOT CAN BE IN ONE OF 6 STATES ! DISCONNECTED ! NOT ALLOCATED ! READY ! REQUEST FIRED ! SENSE FIRED ! QUEUED ! ! ! 3. MAG TAPES. ! THEORETICALLY, A MT STREAM CAN HAVE UP TO 8 DRIVES (OR ! MECHANISMS). FOR EACH MT STREAM THEREFORE, 8 BYTES ARE ! ALLOCATED IN THE ARRAY MECHSLOTS. EACH BYTE CONTAINS A ! SLOT NUMBER. THE MECHINDEX FIELD IN A SLOT POINTS TO ! THE FIRST OF THESE 8 BYTES. CONSEQUENTLY, GIVEN PTSM, ! CAN USE PTS_TO_SLOT TO GET SOME SLOT ON STREAM, PICK ! UP MECHINDEX, THEN ADD ON M AND ACCESS MECHSLOTS TO GET ! THE REQUIRED SLOT NUMBER. !---------------------------------------------------------------------------------------------------- ! JUST PRINTS A STRING + NEWLINE %ROUTINE MSG(%STRING(120)TXT) PRINTSTRING(TXT." ") %END; ! OF MSG ! ! %ROUTINE REPLY(%INTEGER SRCE, %STRING(63)TXT) %RECORD P(PARMF) P = 0 P_DEST = SRCE %IF LENGTH(TXT) > 23 %THEN LENGTH(TXT) = 23 STRING(ADDR(P_P1)) = TXT PON(P) %END; ! OF REPLY ! ! ! %ROUTINE SLOTS MSG("GPC'S TABLES:-") DUMPTABLE(0, ADDR(TABLE(0)), TABLE(0)<<2+4) %END; ! OF SLOTS ! ! ! ! ! PONS A PSEUDO INTERRUPT ENTRY TO GPC %ROUTINE PON GPC INT(%INTEGER PT) %RECORD P(PARMF) %UNLESS LOPT<=PT<=HIPT %THEN INTEGER(-1)=1; ! TRAP WAYWARD PON P_SRCE=0 P_DEST = GPC DEST ! 3; ! INTERRUPT ENTRY P_P1 = PT PON(P) %END; ! OF PON GPC INT ! ! ! ! ! ! GETS A COMMUNICATION AREA %ROUTINE GET CA(%INTEGER CAA) *LXN_CAA *INCT_(%XNB+0) *JCC_8, SEMALOOP(INTEGER(CAA)) GOT: %END; ! OF GET CA ! ! ! ! ! ! SENDS A CHANNEL FLAG %ROUTINE SEND CH FLAG(%INTEGER PT) %INTEGER BREG BREG = TRUNKADDR ! (PT << 16) *LB_BREG *LSS_1 *ST_(0+%B) %END; ! OF SEND CH FLAG ! ! ! ! ! !---------------------------------------------------------------------------------------------------- ! THIS FUNCTION INITIALISES THE GPC BY ! CLEARING IT ! LOADING THE MICROPROGRAM ! INITIALISING THE CONTROLLER AND COMMUNICATION AREA ! PARAMETERS ! CAA COMMUNICATION AREA ADDR ! PT FOR THIS GPC ! CHOPSUPE =1 IF CALLED FROM GROPE ELSE 0 ! IF 1 THEN ! SLAVES NOT SWITCHED OFF/ON ! CONTROLLER RESPONSES SAVED IN MAINSTORE, ! ADDR X'2000' INSTEAD OF DUMP TABLE BEING ! CALLED ! COMMS AREA COPIED ! RESPONSES ! 0 = SUCCESS ! 1 << 24 ! CRESP0 MICROPROGRAM LOAD FAILS ! 2 << 24 ! CRESP0 INITIALISE FAILED, RESPONSE FROM OLD CA ! 3 << 24 ! CRESP0 DITTO, RESPONSE FROM NEW COMMS AREA ! ! %EXTERNALINTEGERFN GPC INIT( %C %INTEGER CAA, %C %INTEGER PT, %C %INTEGER CHOPSUPE) %INTEGER BREG %INTEGER COUNT %INTEGER J %INTEGER PSTA %INTEGER PSTS %RECORDNAME CA0(CA0F) %RECORDNAME CA(CAF) %RECORD INI(INI F) ! CLEAR GPC BREG = TRUNKADDR !(PT << 16) *LSS_2 *LB_BREG *ST_(0+%B) WAIT(50); ! MILLISECONDS CA0 == RECORD(RA0AD); ! INITIAL COMMS AREA ! SLAVES OFF IF NOT CALLED FROM GROPE %IF CHOPSUPE = 0 %THEN SLAVES ON OFF(0) ! LOAD GPC MICROPROGRAM THE ORIGINAL BOOTSTRAP DID ! CA0_CSAW0 = X1000, ALTHOUGH GPC TECHNICAL DESCR ! 1112732 SHEET 13 SAYS ONLY CSAW1 RELEVANT CA0 = 0 CA0_PAW = LOAD MICROPROGRAM CA0_CSAW1 = REALISE(ADDR(GPCMPROG(0))); CA0_MARK = -1 SEND CH FLAG(PT) COUNT = 0 COUNT=COUNT+1 %UNTIL (CA0_CRESP0 # 0 %AND CA0_MARK = -1) %C %OR COUNT > 300000 ! IF NORMAL_REQUEST_TERMINATION BIT NOT SET THEN LOAD FAILED %IF CA0_CRESP0 & NORMAL TERMINATION = 0 %THEN %C %RESULT = (1<<24) ! CA0_CRESP0 WAIT(50); ! MILLISECONDS ! INITIALISE GPC GIVING PST REAL ADDR AND LIMIT CA0 = 0 CA0_PAW = DO CONTROLLER REQUEST CA0_CSAW0 = INIT CONTROLLER CA0_CSAW1 = REALISE(ADDR(INI)) GET PSTB(PSTS, PSTA); ! INI_PSTS = PSTS INI_PSTA = PSTA INI_CAA = CAA INI_SOE = 0 ! INITIALISE THE NEW COMMS AREA CA == RECORD(CAA) CA = 0 CA_MARK = -1 ! IF CALLED FROM GROPE : %IF CHOPSUPE # 0 %START %IF RECAT = 0 %THEN RECAT = RA0AD + X'2000' %CYCLE J = 0, 4, 28 INTEGER(RECAT+J) = INTEGER(RA0AD+J) %REPEAT %CYCLE J = 0, 4, 12 INTEGER(RECAT+X'20'+J) = INTEGER(ADDR(INI)+J) %REPEAT RECAT = RECAT + X'40' %FINISH ! FREE COMMS AREA CA0_MARK = -1 SEND CH FLAG(PT) COUNT = 0 COUNT=COUNT+1 %UNTIL (CA_CRESP0 # 0 %AND CA_MARK = -1) %C %OR COUNT > 900000 ! IF NOT CALLED FROM GROPE %IF CHOPSUPE = 0 %THEN SLAVES ON OFF(-1); ! SLAVES BACK ON ! LOOK FOR NORM TERM BIT %IF CA_CRESP0 & NORMAL TERMINATION = 0 %START %IF CHOPSUPE = 0 %START %IF MULTIOCP = YES %START; RESERVE LOG; %FINISH MSG("CA0") DUMP TABLE(2, RA0AD, 32) MSG("CA") DUMP TABLE(3, CAA, 272) MSG("INI") DUMP TABLE(4, ADDR(INI), 16) %IF MULTIOCP = YES %START; RELEASE LOG; %FINISH %FINISH %IF CA_CRESP0 = 0 %THEN %RESULT = (2<<24)!CA0_CRESP0 %RESULT = (3<<24)!CA_CRESP0 %FINISH CA_CRESP0 = 0 CA_MARK = -1 %RESULT = 0 %END; ! OF GPC INIT ! ! ! ! ! !---------------------------------------------------------------------------------------------------- ! DISCONNECTS THEN, IF CONNECT=1, CONNECTS ONE OR ALL ! STREAMS ON A GPC. ABNORMAL TERMINATIONS ARE GIVEN FOR ALL ! RELEVANT STREAMS WHICH ARE FOUND TO BE BUSY. ! PARAMETERS ! PT GPC ! CAA COMMUNICATIONS AREA ADDRESS ! STREAM IF < 0 ALL STREAMS ELSE SPECIFIED STREAM ! CONNECT =1 RECONNECTS ELSE ONLY DISCONNECTS ! TIMEOUT =1 FOR SPECIAL ABTERM OF SPECIFIED STREAM ! RESPONSES ! VARIOUS MESSAGES TO SYSTEM LOG %ROUTINE CONNECT STREAMS(%INTEGER %C PT, %C CAA, %C STREAM, %C CONNECT, %C TIMEOUT) %INTEGER COUNT %INTEGER FAILS %INTEGER HI %INTEGER J %INTEGER LO %INTEGER PAW FAILS %INTEGER STRM %OWNINTEGER DUMMY WORD %OWNRECORD ALE(ALEF); ! ********************** BUT WHAT ABOUT MULTI PROCESSORS ??????? %OWNRECORD RCB(RCBF) %RECORDNAME CA(CAF) %RECORDNAME GPCT(GPCTF) %RECORDNAME SENT(CASEF) %STRING(15)TXT %OWNINTEGER DISCONNECT LBE = X'00F10900' %OWNINTEGER CONNECT LBE = X'00F10800' ! MESSAGE WK = "GPC CONNECT STREAMS ".HTOS(PT,2) %UNLESS STREAM < 0 %THEN WK = WK.HTOS(STREAM,1) %UNLESS CONNECT = 1 %THEN WK = WK." DIS" MSG(WK) ! CONSTRUCT RCB ALE_S = 4 ALE_A = ADDR(DUMMY WORD) RCB_LIM FLAGS = PRIV ONLY RCB_LBS = 4 RCB_LBA = ADDR(DISCONNECT LBE) RCB_ALS = 8 RCB_ALA = ADDR(ALE) CA == RECORD(CAA) FAILS = 0 PAW FAILS = 0 SLAVES ON OFF(0); ! SLAVES OFF %IF STREAM < 0 %THEN %C LO = 0 %AND HI = 14 %ELSE %C LO = STREAM %AND HI = STREAM ! FIRST DISCONNECT STREAMS TXT = "DISCONNECT" *JLK_ ! THEN RECONNECT IF REQUIRED %IF CONNECT = 1 %START WAIT(10) RCB_LBA = ADDR(CONNECT LBE) TXT = "CONNECT" *JLK_ %FINISH ! SLAVES BACK ON AND PRINT COUNTS SLAVES ON OFF(-1); ! ON MSG("SAW FAILS=".HTOS(FAILS,1). %C ", PAW FAILS=".HTOS(PAW FAILS,1)) ! NOW GIVE SPECIAL ABNORMAL TERMINATION FOR EACH ! RELEVANT STREAM THAT WAS BUSY %IF TIMEOUT=1 %OR STREAM<0 %START GET CA(CAA) %CYCLE J = 0, 1, LASTSLOT GPCT == RECORD(GPCTBASE + J*SLOTSI) STRM = (GPCT_PTSM >> 4) & 15 %IF (GPCT_PTSM >> 8) & 255 = PT %C %AND %C (GPCT_STATE = REQUEST FIRED %C %OR %C GPCT_STATE = SENSE FIRED) %C %AND %C (STRM = STREAM %OR STREAM < 0) %C %START ! FOUND A RELEVANT STREAM THAT IS BUSY MSG("ABN TERM FOR GPTSM ".HTOS(GPCT_PTSM,5)) ! PLACE BIT IN PIW CA_PIW0 = CA_PIW0 ! (X'80000000' >> STRM) ! SET RESPONSE, RESP1=-1 IS AN EMAS SPECIAL SENT == CA_S ENTRY(STRM) SENT_RESP0 = ABNORMAL TERMINATION SENT_RESP1 = -1 %FINISH %REPEAT %FINISH CA_MARK = -1 PON GPC INT (PT) WAIT(100); ! MILLISECONDS %RETURN ! ! ! ! ! ! PSEUDO ROUTINE FOR EACH STREAM: %CYCLE J = LO, 1, HI SENT == CA_S ENTRY(J) GET CA(CAA) CA_PAW = DO STREAM REQUEST ! J SENT = 0 SENT_SAW0 = X'30000020'; ! SAW FLAGS + RCB BOUND SENT_SAW1 = ADDR(RCB) CA_MARK = -1 SEND CH FLAG(PT) COUNT = 0 COUNT=COUNT+1 %UNTIL SENT_RESP0 # 0 %C %OR COUNT > 100000 %IF SENT_RESP0 & NORMAL TERMINATION = 0 %START MSG(TXT." STRM".HTOS(J,1). %C " RESP0=".HTOS(SENT_RESP0,8)) FAILS = FAILS + 1 %FINISH SENT_RESP0 = 0 CA_PIW0 = CA_PIW0 & (\ ( X'80000000' >> J)); ! IF IN DOUBT CLEAR BIT! %IF CA_PAW # 0 %THEN PAWFAILS = PAW FAILS + 1 %REPEAT *J_%TOS ! END OF PSEUDO ROUTINE 'FOR EACH STREAM' ! ! ! ! ! %END; ! OF CONNECT STREAMS ! ! ! ! ! !---------------------------------------------------------------------------------------------------- ! THIS ROUTINE IS INVOKED BY 'PAW NOT CLEARED'. IT ! CALLS 'CONTROLLER DUMP' TO PRODUCE THE DUMP, THEN ! RE-INITS THE GPC. IF CALLED MORE THAN 10 TIMES, ! IT SIMPLY RETURNS. %ROUTINE GPC DUMP(%INTEGER PT) %INTEGER CAA %INTEGER GPCNO %INTEGER RES %OWNINTEGER TIMES = 0 %IF TIMES > 10 %THEN %RETURN TIMES = TIMES + 1 CONTROLLER DUMP(3, PT) GPCNO = PT TO GPC(PT - LOPT) CAA = CAAS(GPCNO) RES = GPC INIT(CAA, PT, 0) MSG("GPC INIT RES=".HTOS(RES,8)) CONNECT STREAMS(PT, CAA, -1, 1,0) %END; ! OF GPC DUMP ! ! ! ! ! !---------------------------------------------------------------------------------------------------- ! CALLED WHEN PAW OR SAW FOUND NON ZERO WHEN ! A CHANNEL FLAG IS ABOUT TO BE ISSUED. IF ! STREAM < 0, SAW IS NOT RELEVANT. %ROUTINE PAW NOT CLEARED(%INTEGER %C PT, %C STREAM, %C PAW) %INTEGER CAA %INTEGER GPCNO %INTEGER SAW %RECORDNAME CA(CAF) %RECORDNAME SENT(CASEF) ! SET UP POINTERS GPCNO = PT TO GPC(PT - LOPT) CAA = CAAS(GPCNO) CA == RECORD(CAA) ! SLAVES OFF SLAVES ON OFF(0) %IF CA_PAW # 0 %THEN WAIT(100) %IF CA_PAW=0 %THEN SLAVES ON OFF(-1) %AND %RETURN; ! OK NOW SEND CH FLAG(PT); ! RE-FIRE I/O WAIT(100) ! SLAVES BACK ON SLAVES ON OFF(-1) MSG("GPC PAW NOT CLEARED PT=".HTOS(PT,2).",PAW=".HTOS(PAW,8)) SAW = 0 %UNLESS STREAM < 0 %START SENT == CA_S ENTRY(STREAM) SAW = SENT_SAW0 %FINISH %IF SAW # 0 %START MSG("SAW NOT CLEARED") %FINISH %UNLESS CA_PAW = 0 %AND SAW = 0 %THEN GPC DUMP(PT) MSG("END OF PAW NOT CLEARED") %END; ! OF PAW NOT CLEARED ! ! ! ! ! !---------------------------------------------------------------------------------------------------- ! IF CONTROLLER = 0, ISSUES 'READ STREAM DATA' ! 1, 'READ STREAMS CONTROLLER STATUS' ! 2, 'READ CONTROL STREAM STATUS' %INTEGERFN READ STRM DATA(%INTEGER %C PT, %C STREAM, %C CONTROLLER) ! %CONSTSTRING(24)%ARRAY HEADER(0:2)="STREAM DATA", %C "STREAM CONTROLLER STATUS", %C "CONTROL STREAM STATUS" %INTEGER CAA %INTEGER COMMAND %INTEGER COUNT %INTEGER GPCNO %INTEGER LEN %INTEGER SAWFLAGS %OWNINTEGERARRAY STREAM DATA(0:63) %RECORDNAME CA(CAF) %IF CONTROLLER = 0 %START LEN = 64 COMMAND = READ STREAM DATA %FINISH %ELSE %START %IF CONTROLLER=1 %START LEN = 4 COMMAND = READ STREAMS CONTROLLER STATUS %FINISH %ELSE %START LEN=64 COMMAND=READ CONTROL STREAM STATUS %FINISH %FINISH GPCNO = PT TO GPC(PT - LOPT) CAA = CAAS(GPCNO) CA == RECORD(CAA) %IF CA_PAW # 0 %START PAW NOT CLEARED(PT, -1,CA_PAW) %RESULT = 0 %FINISH ! SLAVES OFF SLAVES ON OFF(0) GET CA(CAA) CA_CRESP0 = 0 SAWFLAGS = 3; ! CLEAR ABN & INHIBIT TERM INT CA_PAW = DO CONTROLLER REQUEST CA_CSAW0 = SAWFLAGS << 28 ! COMMAND << 24 ! STREAM << 16 ! LEN CA_CSAW1 = ADDR(STREAM DATA(0)) CA_MARK = -1 SEND CH FLAG(PT) ! LOOP AWAITING RESPONSE COUNT = 0 COUNT=COUNT+1 %UNTIL CA_CRESP0 # 0 %C %OR COUNT > 100000 ! SLAVES BACK ON SLAVES ON OFF(-1) %IF MULTIOCP = YES %START; RESERVE LOG; %FINISH PRINTSTRING("GPC ".HEADER(CONTROLLER). %C " PTS=".HTOS(PT<<4!STREAM,3)) DUMP TABLE(-1,ADDR(STREAM DATA(0)),LEN) MSG("CRESP0=".HTOS(CA_CRESP0, 8)) %IF MULTIOCP = YES %START; RELEASE LOG; %FINISH ! RESULT USEFUL ONLY IF CONTROLLER # 0 %RESULT = STREAM DATA(0) %END; ! OF READ STRM DATA ! ! ! ! ! !---------------------------------------------------------------------------------------------------- %INTEGERFN FIND BYTE(%INTEGER BYTE,ADDR,LEN) %INTEGER I %CYCLE I = 0, 1, LEN-1 %IF BYTE = BYTE INTEGER(ADDR+I) %THEN %RESULT = I %REPEAT %RESULT = -1 %END; ! OF FIND BYTE ! ! ! %STRINGFN MNEMO(%INTEGER MNEMONIC) %INTEGER I, J I = MNEMONIC J = 0 %IF BYTE INTEGER(ADDR(I)+1) = 0 %THEN J = 1 BYTE INTEGER(ADDR(I)+J) = 3-J %RESULT = STRING(ADDR(I)+J) %END; ! OF MNEMO ! ! ! ! ! %INTEGERFN TRANS MNEMO(%STRINGNAME S) %INTEGER M, A, I, J M = 0 A = ADDR(S) TRIM: %IF S -> (" ").S %THEN ->TRIM %IF S -> ("X").S %START %CYCLE I = 1, 1, BYTEINTEGER(A) J = BYTE INTEGER(A+I) %UNLESS '0' <= J <= '9' %OR %C 'A' <= J <= 'F' %C %THEN %RESULT = 0 M = M << 4 + (9*J>>6) + (J&15) %REPEAT %FINISH %ELSE %START %IF BYTE INTEGER(A) = 3 %START %CYCLE I = 1, 1, 3 BYTE INTEGER(ADDR(M)+I) = BYTE INTEGER(A+I) %REPEAT %FINISH %FINISH %RESULT = M %END; ! OF TRANS MNEMO ! ! ! ! ! %INTEGERFN STATE CHECK(%INTEGER SRCE, MNEM, STATE) %INTEGER J, A %RECORDNAME G(GPCT F) %IF MNEM >> 16 = M'M' %START ! TAPE CLUSTER, INSIST THAT ALL DECKS ! IN CLUSTER ARE 'NOT ALLOC' %UNLESS MNEM & 255 = M'0' %START REPLY(SRCE, "GPC: MUST BE MN0") %RESULT = 1 %FINISH ! A = GPCT BASE %CYCLE J = 0, 1, LASTSLOT G == RECORD(A) %IF G_MNEMONIC & X'FFFF30' = MNEM %START %UNLESS G_STATE = NOT ALLOCATED %START REPLY(SRCE, "GPC: ".MNEMO(G_MNEMONIC). %C " STATE ?") %RESULT = 1 %FINISH %FINISH A = A + SLOTSI %REPEAT %RESULT = 0 %FINISH ! %RESULT = 0 %IF STATE = NOT ALLOCATED ! %RESULT = 0 %IF STATE = READY %AND MNEM & X'FFFF30' = M'OP0'; ! SPECIAL DISPENSATION FOR OPERS ! REPLY(SRCE, "GPC: ".MNEMO(MNEM)." STATE ?") %RESULT = 1 %END; ! OF STATE CHECK ! ! ! ! %STRINGFN MNS(%RECORDNAME D) %RECORDSPEC D(DEVICE ENTRY F) %INTEGER I I=D_MNEMONIC BYTEINTEGER(ADDR(I))=3 %RESULT=STRING(ADDR(I)) %END; ! MNS !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! MAIN GPC ROUTINE ! ! ! ! ! %EXTERNALROUTINE GPC(%RECORDNAME INP) %RECORDSPEC INP(PARMF) %INTEGER DSNO,DACT,FLAG,CAA,SLOT,PAWFN,SAWFLAGS,URCB A,USAW0 %INTEGER LAST,MECH,STRM,GPCNO,BREG,PIW0 %INTEGER J,PT,RESP0,RESP1,OSNO,PREVIOUS PT %INTEGER SRCE,CALLED %INTEGER I %INTEGER INTERRUPT ANALYSIS FLAGS %INTEGER FLAGS %INTEGER GPTSM %INTEGER MNEMONIC %INTEGER MNEMONIC1,MNEMONIC2 %INTEGER P3 %INTEGER SEMA %INTEGER SLOT A %INTEGER STATE %INTEGER GMON %INTEGER ACT %STRING(15) MNEMOS %RECORD P(PARMF) %RECORD Q(PARMF) ! %OWNINTEGER SETUP=0 ! %BYTEINTEGERNAME QHD %BYTEINTEGERARRAYNAME REP, TRTAB ! %SWITCH G COMMAND(1:LIMIT) %SWITCH GS(1:12) %SWITCH CDS(0:7) ! %RECORDNAME COM(COMF) %RECORDNAME D(DEVICE ENTRY F) %RECORDNAME CA(CAF) %RECORDNAME SENT(CASEF) %RECORDNAME GPCT,GE(GPCTF) ! P=INP %IF KMONNING = YES %START GMON<-(KMON>>GPC SNO)&1 PKMONREC("GPC( IN):",P) %IF GMON = YES %FINISH %IF SETUP=0 %START ! ! ! IF NOT YET INITIALISED, IGNORE EVERYTHING ! EXCEPT THE INITIALISATION CALL %RETURN %UNLESS P_DEST&X'FFFF'=2 SETUP=1 J=P_P1; ! ADDRESS OF TABLE CONTAINING TABLES TABLE==ARRAY(J,IFT) TABLE(42) = P_P2 %UNLESS P_P2 = 0; ! ADDR OF PROCESS LIST PICTURE STRM SEMAPHORE == ARRAY(J+TABLE(40)<<2, IFT) GPCTBASE=J+TABLE(1)<<2 LASTSLOT=TABLE(2) NO OF GPCS=TABLE(3) STRMQBASE=J+TABLE(4)<<2 PTSBASE=J+TABLE(5)<<2 PTGPCBASE=J+TABLE(6)<<2 MECHPT=J+TABLE(7)<<2 CAASBASE=ADDR(TABLE(8)) LOPT=TABLE(16) %IF NO OF GPCS>1 %THEN HIPT=TABLE(15+NO OF GPCS) %C %ELSE HIPT=LOPT; ! TO TRAP WAYWARD PON PTS TO SLOT==ARRAY(PTSBASE,BIFT) PT TO GPC==ARRAY(PTGPCBASE,BIFT) STRMQ==ARRAY(STRMQBASE,BIFT) CAAS==ARRAY(CAASBASE,IFT) MECHSLOTS==ARRAY(MECHPT,BIFT) GPCT==RECORD(GPCTBASE) ! %CYCLE J = 0, 1, 15 REPERTOIRE A(J) = ADDR(LP96REP(0)) REPERTOIRE S(J) = 96 %REPEAT REPERTOIRE A(3) = ADDR(LP384REP(0)) REPERTOIRE S(2) = 48 REPERTOIRE S(3) = 384 REPERTOIRE S(4) = 64 ! ! ! RE-INITIALISE SLOTS %CYCLE J = 0, 1, LASTSLOT GPCT==RECORD(GPCTBASE + J*SLOTSI) GPCT_FLAGS=0 GPCT_LINK=ENDLIST %IF GPCT_DEVTYPE=ZX %THEN GPCT_STATE=DISCONNECTED %C %ELSE GPCT_STATE=NOT ALLOCATED GPCT_BUSY = 0 GPCT_X4 = 0 GPCT_RESPONSE DEST = 0 GPCT_C STATUS = 0 GPCT_SERVRT = 0 D == RECORD(GPCT_DEVICE ENTRY A) D_RESP0 = 0 D_RESP1 = 0 %REPEAT ! ! ! ! RE-INITIALISE STREAM Q HEADS J=0 %WHILE J> 4; ! LOGICAL OPER NO P = 0 P_P1 = GE_MNEMONIC P_P2 = X'320005' ! (I << 8); ! WHERE WE WANT OPER INTERRUPTS P_DEST = X'30000B'; ! ALLOCATE P_SRCE = X'320002' ! (I << 8); ! ALLOCATE RESPONSE TO OPER PON(P) %FINISH; ! DEVTYPE = OPER ! %IF GE_DEVTYPE = FE %START P = 0 P_P1 = GE_MNEMONIC P_P2 = X'390005'; ! WHERE WE WANT FE INTERRUPTS P_DEST = X'30000B'; ! ALLOCATE P_SRCE = X'390002'; ! ALLOCATE RESPONSE TO FE ADAPTOR PON(P) %FINISH; ! DEVTYPE = FE ! %IF GE_DEVTYPE=MT %START ! NEW TAPE INIT ! ONE CALL PER CLUSTER ! P_P1 = LOW MNEMONIC FOR STREAM PT=(GE_PTSM>>4) & X'FFF'; ! holds PTS really %IF PREVIOUS PT#PT %START P=0 P_DEST=X'00310004' P_SRCE = X'00300000' P_P1=GE_MNEMONIC; ! RH char must be and should be zero PON(P) PREVIOUS PT=PT %FINISH %FINISH; ! DEVTYPE MT %REPEAT ! ! ! MSG("...".VSN) SLOTS ! ! ! P_DEST=X'A0001'; ! INTERVAL TIMER P_SRCE=1<<31 P_P1=GPC DEST + 6 P_P2=TICK INTERVAL PON(P) -> OUT %FINISH !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! MAIN BODY ! ! ! ! ! !---------------------------------------------------------------------------------------------------- DSNO=P_DEST>>16 DACT=P_DEST&X'FFFF' SRCE=P_SRCE CALLED=SRCE>>31; ! SET #0 IF CALLED, ZERO IF PONNED SRCE=(SRCE<<1)>>1; ! REMOVE TOP BIT FLAG=1 %IF 0 < DACT < 13 %THEN -> GS(DACT) -> ACKNOWLEDGE !---------------------------------------------------------------------------------------------------- ! ! ! COMMAND, FORMS RECOGNISED ARE: ! QS DEV ! CDS DEV ON/OFF ! CDM mnem1 mnem2 ! ? ! SET ! GS(1): %IF BYTE INTEGER(ADDR(P_P1)) > 23 %THEN %RETURN; ! RUBBISH STRING WK = STRING(ADDR(P_P1)) . " * * *" TRIM: %IF WK -> (" ").WK %THEN -> TRIM %CYCLE J = 1, 1, LIMIT %IF WK -> (COMMAND(J)).WK %THEN -> FOUND %REPEAT ERR: REPLY(SRCE, "GPC ??".STRING(ADDR(P_P1))) %RETURN FOUND: %IF J < 4 %START WK -> MNEMOS.(" ").WK MNEMONIC = TRANS MNEMO(MNEMOS) *JLK_ %IF SLOT < 0 %THEN -> ERR *JLK_ %FINISH -> G COMMAND(J) ! ! ! QS DEV G COMMAND(1): *JLK_ %RETURN STATUS: REPLY(SRCE, "GPC: ". %C MNEMO(GPCT_MNEMONIC)." ". %C HTOS(GPCT_PTSM&X'FFFF',4)." ". %C STATES(GPCT_STATE & 15)) *J_%TOS ! ! ! CDS DEV ON/OFF ! G COMMAND(2): %IF WK -> ("OFF ").WK %START %IF STATE CHECK(SRCE, MNEMONIC, STATE) = OK %START CONNECT STREAMS(PT, CAA, STRM, 0,0) GPCT_STATE = (STATE << 4) ! DISCONNECTED %FINISH -> G COMMAND(1) %FINISH %IF WK -> ("ON ").WK %START %IF STATE = DISCONNECTED %START -> CDS ON %FINISH -> G COMMAND(1) %FINISH -> ERR ! G COMMAND(3): ! CDM MNEMONIC1=MNEMONIC WK->MNEMOS.(" ").WK MNEMONIC=TRANS MNEMO(MNEMOS) MNEMONIC2=MNEMONIC J=SLOT; ! SAVE 1ST SLOT *JLK_ %UNLESS SLOT<0 %THEN ->ERR; ! ALREADY EXISTS GPCT==RECORD(GPCT BASE+J*SLOTSI); ! REMAP TARGET SLOT COM==RECORD(COMADDR) %IF MNEMONIC1>>8=M'ZX' %START; ! INTRODUCE DEVICE I=MNEMONIC2>>8 %CYCLE J=0,1,CDMDEVLIMIT %IF I=CDMDEV(J) %THEN ->IDEV %REPEAT ->ERR; ! INVALID FOR CDM IDEV: GPCT_MNEMONIC=MNEMONIC2 GPCT_DEVTYPE=CDMDEVTYPE(J) D_MNEMONIC=MNEMONIC2 %IF CDMDEVTYPE(J)=LP %START D_UA S=D_UA S-256; ! TRTAB SPACE D_TR TABLE A=D_UA A+D_UA S %FINISH D_TIMEOUT=CDMDEVTIMEOUT(J)&X'FFFF' D_LOGMASK=CDMDEVTIMEOUT(J)>>16 %IF CDMDEVTYPE(J)=FE %THEN %C COM_FEPS=COM_FEPS!1<<(16+MNEMONIC2&15); ! FEP MAP %FINISH %ELSE %START; ! TAKE OUT DEVICE %UNLESS MNEMONIC2>>8=M'ZX' %THEN ->ERR %UNLESS STATE=DISCONNECTED %THEN ->ERR I=MNEMONIC1>>8 %CYCLE J=0,1,CDMDEVLIMIT %IF I=CDMDEV(J) %THEN ->TOUT %REPEAT ->ERR TOUT: %IF CDMDEVTYPE(J)=FE %THEN %C COM_FEPS=COM_FEPS&(\(1<<(16+MNEMONIC1&15))) %IF CDMDEVTYPE(J)=LP %START D_UA S=D_UA S+256; !RECOVER TRTAB SPACE D_TR TABLE A=0 %FINISH GPCT_MNEMONIC=MNEMONIC2 GPCT_DEVTYPE=ZX %FINISH ->G COMMAND(1) ! SET G COMMAND(5): XPT = -1 XSTRM = -1 ! ! G COMMAND(4): ! ? %CYCLE SLOT=0,1,LASTSLOT GPCT == RECORD(GPCT BASE + SLOT * SLOTSI) *JLK_ %REPEAT ! ! REPLY(SRCE, "GPC: ". %C ! "XPTS=".HTOS(XPT<<4!XSTRM,3). %C ! " XSTATE=".HTOS(XSTATE,1)) ! %RETURN !---------------------------------------------------------------------------------------------------- ! ! ! ALLOCATE ** NEW VERSION 9/79 ** ! ! P1 = MNEMONIC ! P2 = DEST FOR INTERRUPT RESPONSES ! ! GS(11): ! WK = "GPC ALLOCATE ".MNEMO(P_P1). %C ! " ".HTOS(P_P2,8) MNEMONIC = P_P1 *JLK_ %UNLESS SLOT < 0 %START *JLK_ FLAG = 2 %IF STATE = NOT ALLOCATED %START FLAG = 0 GPCT_STATE = READY GPCT_RESPONSE DEST = P_P2 ! NOW CONSTRUCT THE REPLY P_P2 = LOID + SLOT P_P3 = ADDR(D) P_P6 = GPCT_MNEMONIC ! EXTRA INFORMATION FOR OPERS %IF GPCT_DEV TYPE = OP %START ! GET LOGICAL NO OF THIS OPER STREAM OSNO = GPCT_MECHINDEX >> 4 ! BUFF AREA ADDR D_X2 = CAA + TABLE(OSNO + 32) >> 16 ! NO OF SCREENS D_RESP0 = GPCT_MECHINDEX & 15 ! SIZE OF BUFFER AREA D_X1 = TABLE(OSNO + 32) & X'FFFF' %FINISH %FINISH %FINISH ! %IF FLAG = 0 %C ! %THEN MSG(WK."/".MNS(D)."/".HTOS(P_P2,2)) %C ! %ELSE MSG(WK." FLAG=".HTOS(FLAG,1)) -> ACKNOWLEDGE !---------------------------------------------------------------------------------------------------- GS(8): ! SPECIAL FORCED ALLOCATE CALL (NOT PON) ! FOR USE BY ENTER ! P_P1 = PTSM ! ON RETURN ! P_P1 = 0 SUCCESS ! 1 MNEMONIC NOT KNOWN ! 2 DISCONNECTED ! P_P3 = ADDRESS OF DEVICE ENTRY MNEMONIC = P_P1 *JLK_ %UNLESS SLOT < 0 %START *JLK_ FLAG = 2 %UNLESS STATE = DISCONNECTED %START FLAG = 0 P_P3 = ADDR(D) %FINISH %FINISH P_P1 = FLAG INP = P %RETURN !---------------------------------------------------------------------------------------------------- ! ! ! ! DE-ALLOCATE ! ! GS(5): %UNLESS P_P1=M'LP' %START MNEMONIC = P_P1 *JLK_ FLAG = 2 %UNLESS SLOT < 0 %START *JLK_ P_P3=ADDR(D) FLAG=3 %UNLESS STATE = NOT ALLOCATED %OR STATE=QUEUED %START GPCT_FLAGS = 0 GPCT_STATE = NOT ALLOCATED FLAG = 0 %FINISH %FINISH %FINISH ! MSG("GPC DEALLOCATE ".MNEMO(P_P1). %C ! " FLAG=".HTOS(FLAG,1)) -> ACKNOWLEDGE ! !---------------------------------------------------------------------------------------------------- ! ! ! CLOCK INTERRUPT ! ! NO PARAMETERS ! ! GS(6): ! EACH TIME A CLOCK INTERRUPT OCCURS ! 1 FOR EACH GPC WITH PIW#0, PON GPC INT ! 2 FOR EACH BUSY SLOT, INCREMENT 'SECS SINCE' ! IF THIS BECOMES > TIMEOUT, ISSUE COPIOUS ! WARNINGS/DUMPS AND RECONNECT STREAM PREVIOUS PT = 0 %CYCLE SLOT = 0, 1, LASTSLOT GE == RECORD(GPCT BASE + SLOT * SLOTSI) GPCNO=GE_PTSM>>16 PT = (GE_PTSM >> 8) & 255 D == RECORD(GE_DEVICE ENTRY A) CAA = D_CAA CA == RECORD(CAA) %UNLESS PT = PREVIOUS PT %OR CA_PIW0 = 0 %C %THEN PON GPC INT(PT) %AND PREVIOUS PT = PT %IF GE_STATE = REQUEST FIRED %C %OR %C GE_STATE = SENSE FIRED %C %THEN %C D_SECS SINCE = D_SECS SINCE + TICK INTERVAL %IF D_SECS SINCE > D_TIMEOUT %START STRM=GE_PTSM>>4&15 %IF MULTI OCP=YES %START *JLK_ %UNLESS GE_BUSY=0 %THEN INTEGER(SEMA)=-1 %AND %CONTINUE GE_BUSY=TIMING OUT INTEGER(SEMA)=-1 %FINISH WK = "GPC TIMEOUT ".MNS(D)." ".HTOS(D_GPTSM, 5) MSG(WK) !OPMESS2(0, WK) J = READ STRM DATA(PT, STRM, 0) *JLK_ CA_PAW = 3 << 24 ! STRM; ! STOP STREAM *JLK_ WAIT(50) CONNECT STREAMS(PT, CAA, STRM, 1,1) D_SECS SINCE = 0 MSG("END OF TIMEOUT") %IF MULTI OCP=YES %START *JLK_ GE_BUSY=0 INTEGER(SEMA)=-1 %FINISH %FINISH %REPEAT -> OUT !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! ! ! ! ! ! EXECUTE ** NEW VERSION 9/79 ** ! ! P1 = RCB ! P2 = SNO FOR DEVICE ! P3 = RSD(1) + PAW FN(4) + SAWFLAGS(4) ! P4 = IDENT ! ! GS(12): SLOT = P_P2 - LOID ! CHECK THAT SLOT IN RANGE %IF 0 <= SLOT <= LASTSLOT %THEN %START *JLK_ P3 = P_P3 D_IDENT = P_P4 P_P3 = ADDR(D) P_P4 = 0 P_P5 = 0 P_P6 = D_IDENT FLAG = 2 ! CHECK DEVICE STATE FLAGS = GPCT_FLAGS %IF STATE = READY %START PAW FN = P3 & X'F0' U RCB A = P_P1 SAWFLAGS = P3 & 15 USAW0 = (SAWFLAGS << 28) ! RCB BOUND PAW FN = (PAW FN << 20) ! STRM ! IF THIS STREAM IS IDLE, CAN ISSUE REQUEST FORTHWITH %IF QHD = ENDLIST %START %IF CA_PAW # 0 %C %OR %C SENT_SAW0 # 0 %C %THEN PAW NOT CLEARED(PT, STRM,CA_PAW) *JLK_ CA_PAW = PAW FN GPCT_LINK = ENDLIST QHD = SLOT SENT_SAW0 = USAW0 SENT_SAW1 = U RCB A *JLK_ STATE = REQUEST FIRED %FINISH %ELSE %START ! IF DEVICE IS NOT BUSY BUT STREAM IS, WE HAVE ! MULTI MECH STREAM. SO QUEUE THIS REQUEST !++; %IF MULTI OCP = YES %START *JLK_ !++; %FINISH %IF GPCT_DEVTYPE#MT %START; ! GASP!! MSG("GPC ABOUT TO Q NON-MT DEV REQ!!") DUMPTABLE(79,X'80C00000',4096) %FINISH STATE = QUEUED LAST = QHD %UNTIL LAST = ENDLIST %CYCLE GE == RECORD(GPCT BASE + LAST*SLOTSI) LAST = GE_LINK %REPEAT GPCT_LINK = ENDLIST GE_LINK = SLOT !++; %IF MULTI OCP = YES %START INTEGER(SEMA) = -1; ! RELEASE SEMAPHORE !++; %FINISH %FINISH ! SET GPCT_FLAGS GPCT_STATE = STATE %IF P3 & X'100' = 0 %THEN %C GPCT_FLAGS = FLAGS & (\GET STRM DATA) %C %ELSE %C GPCT_FLAGS = FLAGS ! GET STRM DATA ! FINALLY, SET FIELDS IN DEVICE ENTRY D_USAW0 = USAW0 D_U RCB A = U RCB A D_PAW = PAW FN D_RESP1 = 0; ! TO CANCEL POSSIBLE TIMEOUT INDICATION D_SECS SINCE = 0 CALLED = 1 ! FORCES RETURN RATHER THAN PON FLAG = 0 %FINISH %FINISH -> ACKNOWLEDGE !---------------------------------------------------------------------------------------------------- ! ! ! ! ! INTERRUPT ! P1 = PT ! ! GS(3): PT=P_P1 GPCNO=PT TO GPC(PT - LOPT) CAA=CAAS(GPCNO) CA==RECORD(CAA) ! PICK UP AND CLEAR PIW *JLK_ PIW0 = CA_PIW0 CA_PIW0 = 0 CA_MARK = -1 MORE INTS: ! DEAL WITH EACH BIT IN PIW0 *LSS_PIW0 ! JUMP OUT IF 'NO BITS SET' *JAT_4, *SHZ_STRM %IF MULTI OCP=YES %START SLOT=PTS TO SLOT((PT-LOPT)<<4!STRM) %UNLESS SLOT=ENDLIST %START GPCT==RECORD(GPCT BASE+SLOT*SLOTSI) *JLK_ %UNLESS GPCT_BUSY=0 %THEN INTEGER(SEMA)=-1 %AND %C ->SPURIOUS INTERRUPT GPCT_BUSY=PROCESSING INTERRUPT INTEGER(SEMA)=-1 %FINISH %FINISH PIW0 = PIW0 !! X'80000000' >> STRM SENT == CA_S ENTRY(STRM) *JLK_ RESP0=SENT_RESP0 INTERRUPT ANALYSIS FLAGS = (RESP0 >> 20) & 15 RESP1=SENT_RESP1 SENT_RESP0=0 SENT_RESP1=0 CA_MARK=-1 ! IGNORE TOTALLY SPURIOUS INTERRUPTS %IF RESP0 = 0 %THEN SLOT = ENDLIST %AND -> SPURIOUS INTERRUPT ! ! XSTRM AND XPT ARE INITIALISED TO -1, THEY ! ASSUME OTHER VALUES DURING CDS ON %IF STRM = XSTRM %AND PT = XPT %START %IF MULTI OCP=YES %START %UNLESS SLOT=ENDLIST %START *JLK_ GPCT_BUSY=0 INTEGER(SEMA)=-1 %FINISH %FINISH -> MORE INTS %IF INTERRUPT ANALYSIS FLAGS = 1; ! THROW AWAY ATTENTION INTERRUPTS ! REPLY(XSRCE,HTOS(XSTATE,1)." ". %C ! HTOS(RESP0,8)." ". %C ! HTOS(RESP1,8)) -> CDS(XSTATE) %FINISH %IF INTERRUPT ANALYSIS FLAGS = 1 %START ! MECH APPEARS IN RESPONSE ONLY FOR ATTENTION INTERRUPTS ! HENCE THE TWO DIFFERENT WAYS OF COMPUTING SLOT MECH = (RESP0 >> 24) & 15 SLOT = PTS TO SLOT(((PT - LOPT) << 4 ) ! STRM) %UNLESS SLOT = ENDLIST %START GPCT == RECORD(GPCT BASE + SLOT*SLOTSI) %IF GPCT_DEV TYPE = MT %START SLOT = MECHSLOTS(GPCT_MECHINDEX + MECH) %FINISH %FINISH %FINISH %ELSE SLOT = STRMQ(GPCNO << 4 ! STRM) ! IF NO SLOT, ASSUME SPURIOUS FLAG = 2 %IF SLOT = ENDLIST %THEN -> SPURIOUS INTERRUPT *JLK_ FLAG = 3 %IF STATE = NOT ALLOCATED %THEN -> SPURIOUS INTERRUPT %IF INTERRUPT ANALYSIS FLAGS = 1 %START ! ATTENTION ACT = 3 Q_P1 = RESP0 *JLK_ %IF MULTI OCP=YES %START *JLK_ GPCT_BUSY=0 INTEGER(SEMA)=-1 %FINISH -> MORE INTS %FINISH ! NOT AN ATTENTION INTERRUPT %IF STATE = SENSE FIRED %START %IF D_LOGMASK & BYTEINTEGER(ADDR(D_SENSE1)) # 0 %START %IF MULTIOCP = YES %START; RESERVE LOG; %FINISH DUMPTABLE(70 + GPCT_DEVTYPE, ADDR(D), D_DEVICE ENTRY S) %IF MULTIOCP = YES %START; RELEASE LOG; %FINISH %FINISH GS3: ACT = 5 Q_P1 = D_RESP0 Q_P2 = D_RESP1 Q_P4 = RESP0 >> 16 Q_P5 = GPCT_C STATUS *JLK_ -> TRY NEXT %FINISH ! ! %IF STATE = REQUEST FIRED %START D_RESP0 = RESP0 D_RESP1 = RESP1 %IF RESP0&ABNORMAL TERMINATION#0 %C %AND GPCT_RESPONSE DEST>>16<65 %START ! LEAVE SLOT AS FIRST IN LIST AND ISSUE SENSE J=D_LOGMASK>>8 %IF RESP0&X'00FF0000'=CONTROLLER DETECTED ERROR %C %OR J#0 %START WK = "GPC ABTERM ". %C HTOS(PT << 4 ! STRM, 3)." ". %C MNS(D)." ".HTOS(RESP0, 8) MSG(WK) !OPMESS2(0, WK) J=READ STRM DATA(PT,STRM,2); !READ CONTROL STREAM STATUS J=READ STRM DATA(PT,STRM,0); !READ STREAM DATA ! J=READ STRM DATA(PT,STRM,1); !READ STREAM'S CONTROLLER STATUS %IF GPCT_DEV TYPE = FE %C %AND RESP0&X'FF0000'=CONTROLLER DETECTED ERROR %C %THEN CONNECT STREAMS(PT, CAA, STRM, 1,0); ! RE CONNECT FE AFTER ABTERM AND CDE %FINISH ! %IF GPCT_FLAGS&GETSTRMDATA#0 %START GPCT_CSTATUS= READ STRM DATA(PT,STRM,1); ! READ STREAM'S CONTROLLER STATUS -> GS3 %FINISH ! %IF CA_PAW#0 %THEN PAW NOT CLEARED(PT,STRM,CA_PAW) *JLK_ CA_PAW=DO STREAM REQUEST ! STRM SENT_SAW0=X'10000020'; ! INTS + RCB BOUND SENT_SAW1=D_GRCB A ! DO NOT SEND AN INIT WORD (IN THE CASE OF MT WE ARE ADDRESSING THE MECHANISM ALREADY SELECTED) *JLK_ GPCT_STATE = SENSE FIRED %IF MULTI OCP=YES %START *JLK_ GPCT_BUSY=0 INTEGER(SEMA)=-1 %FINISH -> MORE INTS %FINISH ! ! ACT = 2 Q_P1 = RESP0 Q_P2 = RESP1 *JLK_ %IF RESP0&NORMAL TERMINATION#0 %OR %C (RESP0&ABNORMAL TERMINATION#0 %AND %C GPCT_RESPONSE DEST>>16>64) %THEN ->TRY NEXT %IF MULTI OCP=YES %START *JLK_ GPCT_BUSY=0 INTEGER(SEMA)=-1 %FINISH -> MORE INTS %FINISH FLAG = 4 ! HM WE APPEAR TO HAVE A NON ATTENTION INTERRUPT WHEN ! STATE IS READY/QUEUED SPURIOUS INTERRUPT: J = SPURIOUS INTS(STRM) SPURIOUS INTS(STRM) = J + 1 %IF J < SPURIOUS LIMIT %START MSG("GPC SPURIOUS INT ON". %C HTOS(PT << 4 ! STRM, 3). %C "/".HTOS(RESP0, 8)) %FINISH %IF J = SPURIOUS LIMIT %START CONNECT STREAMS(PT, CAA, STRM, 0,0) %UNLESS SLOT = ENDLIST %THEN GPCT_STATE = DISCONNECTED %FINISH %IF MULTI OCP=YES %START *JLK_ GPCT_BUSY=0 INTEGER(SEMA)=-1 %FINISH -> MORE INTS TRY NEXT: ! A PREVIOUS REQUEST HAS BEEN COMPLETED (SOMEHOW) SO NOW ! MARK THAT SLOT 'READY' AGAIN AND SEE IF THERE ARE ANY ! OTHER REQUESTS QUEUED FOR THAT STREAM !++; %IF MULTI OCP = YES %START *JLK_ !++; %FINISH GPCT_STATE = READY QHD = GPCT_LINK GPCT_LINK = ENDLIST %IF QHD#ENDLIST %START SLOT = QHD *JLK_ ! TAKE NEXT REQUEST AND INITIATE %IF CA_PAW#0 %THEN PAW NOT CLEARED(PT,STRM,CA_PAW) *JLK_ CA_PAW=D_PAW SENT_SAW0=D_USAW0; ! SAW FLAGS + RCB BOUND SENT_SAW1=D_URCB A ! FREE COMMS AREA SEMAPHORE AND SEND CHANNEL FLAG *JLK_ GPCT_STATE = REQUEST FIRED %FINISH !++; %IF MULTI OCP = YES %START GPCT_BUSY=0 INTEGER(SEMA) = -1; ! RELEASE SEMAPHORE !++; %FINISH -> MORE INTS !---------------------------------------------------------------------------------------------------- ! ! ! ! ! GS(7): GS(10): GS(4): GS(2): GS(9): ACKNOWLEDGE: P_DEST=SRCE P_SRCE=GPC DEST ! DACT P_P1=FLAG %IF CALLED=0 %AND SRCE>>16#0 %START PON(P) %IF KMONNING = YES %START PKMONREC("GPC( PONS):",P) %IF GMON = YES %FINISH %RETURN %FINISH OUT: INP=P %IF KMONNING = YES %START PKMONREC("GPC( OUT):",P) %IF GMON = YES %FINISH %RETURN ! ! !---------------------------------------------------------------------------------------------------- ! ! ! ! CDS DEV ON ! 'FIND' AND 'DO MAPPINGS' HAVE BEEN DONE CDS ON: %IF XINIT = 0 %START ! ON FIRST CALL, SET UP RCB ETC XINIT = 1 XA = ADDR(X(0)) ! XRCB == RECORD(XA) XRCB_LIMFLAGS = X'4000'; ! TRUSTED CHAIN XRCB_LOCAL SEG TABLE A = 0 XRCB_LB S = 32 XRCB_AL S = 32 XRCB_AL A = XA + 32 ! XALE == ARRAY(XRCB_AL A, ALEFF) XALE(0)_S = 8 XALE(0)_A = XA + 64; ! PROPSDATA XALE(1)_S = 12 XALE(1)_A = XA + 72; ! SENSE DATA XALE(2)_S = 384 XALE(2)_A = XA + 84; ! LP REPERTOIRE XALE(3)_S = 4 XALE(3)_A = XA + 468; ! LP INITWORD ! %FINISH ! %UNLESS XPT < 0 %START REPLY(SRCE, "GPC: CDS ALREADY IN PROGRESS") %RETURN %FINISH ! ! REMEMBER WHAT WE'RE LOOKING FOR! XSRCE = SRCE PIW0 = 0; ! SO THAT WE CAN ->MORE INTS WITH IMPUNITY XSLOT = SLOT XMNEMONIC = MNEMONIC XDEVTYPE = GPCT_DEVTYPE XPTS = GPCT_PTSM >> 4 & X'FFF' ! XGPC = 0 GLOOP: XPT = TABLE(16 + XGPC) XCAA = TABLE(8 + XGPC) XCA == RECORD(XCAA) XSTRM = 0 SLOOP: XSTATE = -1; ! NOTHING FIRED SLOT = PTS TO SLOT((XPT-LOPT)<<4!XSTRM) %IF SLOT = 255 %THEN -> CONNECT GPCT == RECORD(GPCT BASE + SLOT*SLOTSI) %UNLESS GPCT_STATE & 15 = DISCONNECTED %THEN -> SKIP ! ! CONNECT: ! NOW FOUND A STRM THAT EITHER HAS NO SLOT ! ASSOCIATED WITH IT OR HAS A SLOT WHICH ! HAS BEEN DISCONNECTED XSENT == XCA_S ENTRY(XSTRM) X(16) = 0 XSTATE = 1; ! CONNECT -> XFIRE ! ! ! RESPONSE FROM CONNECT CDS(1): %IF X(16)>>24 > 0 %START ! FIRST BYTE OF PROPS DATA GIVES DEVTYPE, ! ZERO IF NO DEVICE %IF X(16)>>24 = XDEVTYPE %START ! DEV OF RIGHT TYPE ! IF MT, NEXT BYTE GIVES CLUSTER ID ! IF FE, NEXT BYTE GIVES FE NO. %UNLESS (XDEVTYPE=MT %AND %C XMNEMONIC&X'F00'#X(16)>>12&X'F00') %OR %C (XDEVTYPE=FE %AND XMNEMONIC&15#X(16)<<8>>24) %C %THEN ->XFOUND %FINISH ! IF FOUND A DEVICE OF WRONG TYPE, DISCONNECT IT XSTATE = 0; ! DISCONNECT -> XFIRE %FINISH ! ! ! RESPONSE FROM DISCONNECT CDS(0): SKIP: %UNLESS XSTRM=14 %THEN XSTRM=XSTRM+1 %AND -> SLOOP %UNLESS XGPC=NO OF GPCS-1 %THEN XGPC=XGPC+1 %AND -> GLOOP REPLY(XSRCE,"GPC: ".MNEMO(XMNEMONIC)." NOT FOUND") XPT = -1 XSTRM = -1 %IF XSTATE < 0 %THEN %RETURN %ELSE -> MORE INTS ! ! XFOUND: REPLY(XSRCE,"GPC: ".MNEMO(XMNEMONIC)." NOW ON PTS ". %C HTOS(XPT<<4!XSTRM, 3)) PTS TO SLOT(XPTS-(LOPT<<4)) = 255 PTS TO SLOT((XPT-LOPT)<<4!XSTRM) = XSLOT XGPTSM = (XGPC<<16)!(XPT<<8)!(XSTRM<<4) ! %CYCLE SLOT = 0, 1, LASTSLOT GPCT == RECORD(GPCT BASE + SLOT * SLOTSI) %IF (GPCT_PTSM >> 4)&X'FFF' = XPTS %START ! MOVE EVERYTHING ON THIS PTS D == RECORD(GPCT_DEVICE ENTRY A) D_GPTSM = XGPTSM ! (D_GPTSM & 15) GPCT_PTSM = D_GPTSM D_CAA = XCAA GPCT_STATE = GPCT_STATE >> 4 %FINISH %REPEAT ! %UNLESS XDEVTYPE=LP %THEN -> XOUT ! ! ! ! ! FIRST BUILD A TRANSLATE TABLE IN ! THE DEVICE ENTRY TO FILTER OUT INVALID CHARACTERS XCART=(X(17)>>16)&15 XA=REPERTOIRE A(XCART) REP==ARRAY(XA,BIFT) XS=REPERTOIRE S(XCART) TRTAB==ARRAY(D_TRTABLE A,BIFT) %CYCLE I=0,1,255; TRTAB(I)=I; %REPEAT %UNLESS XCART = 0 %START %CYCLE I = 0, 1, 255 %IF FIND BYTE(I,XA,XS) < 0 %START ! NOT IN REP %IF FIND BYTE(I,ADDR(LCLETTS(1)),26) < 0 %START TRTAB(I) = LP ILLCHAR %FINISH %ELSE %START TRTAB(I) = I ! X'40'; ! MAKE UC LETTER %FINISH %FINISH %REPEAT TRTAB(37) = X'15' TRTAB(21) = X'15' TRTAB(12) = X'0C'; ! NEWLINE TRTAB(13) = X'0D' TRTAB(64) = X'40'; ! SPACE %FINISH ! X(16) HAS BYTES 0-3 OF LP PROPERTIES ! X(17) HAS BYTES 4-5 ! BOTTOM 4 BITS OF BYTE 5 HAS CARTRIDGE NUMBER SET ON FRONT OF LP. ! IF CARTRIDGE NUMBER IS SET ZERO, WE DON'T LOAD ANY REP IF ! THERE'S ONE ALREADY LOADED, ELSE WE LOAD THE 64-CHAR REP ! (BEING THE FIRST 64 CHARS OF THE 96-CHAR REP ABOVE). ! IF THE CARTRIDGE NUMBER IS : ! 2 WE LOAD THE 48-CHAR REP FOR THE PO DPS CRAIGLOCKHART 2970 ! 3 WE LOAD THE 384-CHAR REP FOR THE BUSH ESTATE 2980 ! 4 WE LOAD THE 64-CHAR REP FOR THE PO DPS BARBICAN 2970 ! 5 WE LOAD THE 96-CHAR REP FOR THE ERCC-KB 2970 XSTYLE=X(16)&255 XLEN=(XSTYLE>>4)*10 + XSTYLE&15 XLEN=66 %IF XLEN=0 XLBE(6)= %C (XLBE(6)&(\255))!(XLEN - 1) ! REPLY(XSRCE,"GPC: LP CART=".HTOS(XCART,1). %C ! " L=X'".HTOS(XLEN,2)."'") ! ! ! %CYCLE I = 0, XS, 384 - XS MOVE(XS, XA, ADDR(X(21))+I) %REPEAT ! ! X(117) = X'00000010'; ! BACK ? FOR ILLEGAL, AUTOTHROW NOT SET XSTATE = 5; ! INITIALISE OUTWARDS -> XFIRE CDS(5): ! RESP FROM INIT %IF XCART = 0 %AND X(17)&X'100000' = 0 %C %THEN -> CDS(4) XSTATE = 4; ! LOADREP OUTWARDS -> XFIRE CDS(4): ! RESP FROM LOAD REP X(117) = X'0000FC10' XSTATE = 7; ! ANOTHER INIT -> XFIRE CDS(7): ! RESP FROM SECOND INIT %IF XSTYLE = X'99' %THEN -> XOUT XSTATE = 6; ! WRITE CONTROL -> XFIRE CDS(6): ! RESP FROM WRITE CONTROL ! ! ! XOUT: ! REPLY(XSRCE,"END OF CDS") XPT = -1 XSTRM = -1 -> MORE INTS ! ! ! XFIRE: ! NEEDS XCAA, XSENT, XPT, XSTRM SETTING UP OUTSIDE ! USES XSTATE TO SELECT REQUIRED COMMAND %IF XCA_PAW # 0 %OR XSENT_SAW0 # 0 %START PAW NOT CLEARED(XPT, XSTRM,XCA_PAW) %FINISH XRCB_LBA = ADDR(XLBE(XSTATE)) GET CA(XCAA) XCA_PAW = DO STREAM REQUEST ! XSTRM XSENT_SAW0 = X'10000020' XSENT_SAW1 = ADDR(XRCB) SEND CH FLAG(XPT) XCA_MARK = -1 -> MORE INTS ! ! ! !---------------------------------------------------------------------------------------------------- ! ! ! PSEUDO ROUTINE ! SENDS A RESPONSE AFTER AN INTERRUPT HAS ! BEEN ANALYSED ! ! RESPOND: Q_DEST = GPCT_RESPONSE DEST %IF GPCT_DEVTYPE=OP %THEN Q_DEST=Q_DEST ! %C ((GPCT_MECHINDEX>>4)<<8) Q_SRCE=GPC DEST ! 3 BYTEINTEGER(ADDR(Q_P1))=LOID + SLOT Q_P3=ADDR(D) Q_P6=D_IDENT PKMONREC("GPC( PONS):",Q) %IF GMON = YES PON(Q) *J_%TOS ! END OF RESPOND !------------------------------------------------------------------------ ! ! ! PSEUDO ROUTINE ! GIVEN MNEMONIC, SEARCHES FOR CORRESPONDING SLOT ! OR, IF NOT FOUND, SETS SLOT TO -1 ! ! FIND: SLOT A = GPCT BASE %CYCLE SLOT = 0, 1, LAST SLOT GPCT == RECORD(SLOTA) %IF %C MNEMONIC = LOID + SLOT %C %OR %C MNEMONIC = GPCT_MNEMONIC %C %OR %C MNEMONIC = GPCT_PTSM & X'FFFF' %C %OR %C (MNEMONIC = M'LP' %C %AND %C GPCT_MNEMONIC >> 8 = M'LP' %C %AND %C GPCT_PROPS03 & X'80' = 0) %C %THEN %START *J_%TOS %FINISH SLOT A = SLOT A + SLOTSI %REPEAT %IF MNEMONIC = M'LP' %START MNEMONIC = M'LP0' -> FIND %FINISH SLOT = -1 *J_%TOS ! END OF FIND !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! PSEUDO ROUTINE ! GIVEN SLOT, SETS VARIOUS POINTERS ! DO MAPPINGS: GPCT == RECORD(GPCT BASE + SLOT*SLOTSI) D == RECORD(GPCT_DEVICE ENTRY A) GPTSM = GPCT_PTSM GPC NO = GPTSM >> 16 PT = (GPTSM >> 8) & 255 STRM = (GPTSM >> 4) & 15 MECH = GPTSM & 15 STATE = GPCT_STATE & 15 CAA = CAAS(GPC NO) QHD == STRMQ(GPC NO << 4 + STRM) CA == RECORD(CAA) SENT == CA_S ENTRY(STRM) *J_%TOS ! END OF DO MAPPINGS !---------------------------------------------------------------------------------------------------- ! ! ! PSEUDO ROUTINE ! GET CA: *LXN_CAA *INCT_(%XNB+0) *JCC_8, SEMALOOP(INTEGER(CAA)) GOT: *J_%TOS ! END OF GET CA !---------------------------------------------------------------------------------------------------- ! ! ! PSEUDO ROUTINE GET STRM SEMA: SEMA = ADDR(STRM SEMAPHORE(GPCNO << 4 ! STRM)) *LXN_SEMA *INCT_(%XNB + 0) *JCC_8, SEMALOOP(INTEGER(SEMA)) GOT SS: *J_%TOS ! END OF GET STRM SEMA !---------------------------------------------------------------------------------------------------- ! ! ! PSEUDO ROUTINE ! SEND CH FLAG: CA_MARK = -1 BREG = TRUNKADDR ! (PT << 16) *LB_BREG *LSS_1 *ST_(0 + %B) *J_%TOS ! END OF SEND CH FLAG !---------------------------------------------------------------------------------------------------- !ZZZ %END; ! OF GPC %ENDOFFILE