%CONSTINTEGER NO = 0 %CONSTINTEGER YES = 1 %CONSTINTEGER MULTIOCP = NO !---------------------------------------------------------------------------------------------------- ! ! %CONSTSTRING(15) VSN = "GPC28 29 APR 80" ! ! ! %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 (PICKED UP DURING INITIALISATION) ! 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. ! ADDITIONALLY, IF GPC IS BEING CALLED, OR IF A REPLY IS ! NOT REQUIRED, THE TOP BIT SHOULD BE SET IN SRCE. ! ! 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 ! DEST MUST CONTAIN SNO FOR GPC ! GPC PONS (WITH A DACT OF 4) ! TAPE ! OPER ! MK1 FE ADAPTOR ! ! ! 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 ALREADY 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 'PONNER' 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 IF EXECUTE IS PON'D, AS IT SHOULD BE, 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 IE P2 OF REQUEST ! P3 = ADDRESS OF DEVICE ENTRY (ONLY IF P1 > 1) ! P4 = 0 ! P5 = 0 ! P6 = IDENT IE P4 OF REQUEST ! ! ! DACT = 6 CLOCK INTERRUPT ENTRY, NO PARAMETERS, NO RESPONSES ! ! ! DACT = 3 INTERRUPT ENTRY ! P1 = PT (PORT + TRUNK) ! RESPONSE ! A MESSAGE IS PON'D 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 IE 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 ! FORMS RECOGNISED : ! QS DEV ! CDS DEV OFF ! CDS DEV ON ! RESPONSES GO TO OPER ! ! ! ! ! ! 3. MESSAGES PRODUCED ON LOG (L) AND/OR OPER (O) ! ! 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, STREAM=s ! (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 ! TONY GIBBONS !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! 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 PTREC(%RECORDNAME P) %EXTERNALSTRINGFNSPEC HTOS(%INTEGER I,PL) %EXTERNALROUTINESPEC PON(%RECORDNAME P) %EXTERNALROUTINESPEC OPMESS2(%INTEGER OPER, %STRING(63) S) %SYSTEMROUTINESPEC MOVE(%INTEGER LENGTH,FROM,TO) %EXTRINSICLONGINTEGER KMON !---------------------------------------------------------------------------------------------------- %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 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 = 4 %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 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 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' %CONSTSTRING(4)%ARRAY COMMAND(1:LIMIT) = "QS ", "CDS ", "? ", "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 %OWNINTEGER LOPT %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 ! ! 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) ! PATCH LEVEL 3 %ENDOFLIST %OWNINTEGERARRAY GPCMPROG(0:511)= %C X'F1604820',X'49E04022',X'802BE80A',X'F0C9000A', X'D0098004',X'42659313',X'BE0A1009',X'8004C213', X'CAB38024',X'CA33821C',X'CA53826D',X'CAD38004', X'CA9380BF',X'CA738004',X'CB348004',X'CAF382F2', X'CAD48079',X'8004C273',X'C2D38028',X'8004C2B3', X'820C8209',X'182E92FB',X'80064820',X'E00C740C', X'500B9302',X'B725F9C0',X'F16CDEEB',X'21CCEB4B', X'E00829E8',X'2C8C61CC',X'2CAC61EC',X'4C6B7968', X'B795F9C0',X'0CCC610C',X'FC0061EC',X'FC0070CC', X'08258188',X'80714840',X'0825C2D4',X'CA938049', X'A2D4BC09',X'1004CAD4',X'805ACA73',X'90688004', X'8064CA73',X'80619068',X'A2D4B809',X'A6741004', X'9068F800',X'A2D4B21A',X'A27AA29A',X'82D183D1', X'B2F4EA13',X'1013C673',X'20139801',X'91FE9802', X'0835C273',X'8004A2F4',X'4282498C',X'91FE8004', X'A83DA9D4',X'F3ACDCAC',X'200C4BC0',X'700E090C', X'4042B3AC',X'E80E240C',X'5006C006',X'80AD782C', X'B795F9C0',X'A335AED4',X'5017500C',X'0C17C073', X'A9F4F48C',X'501F640E',X'080C500E',X'C873AAF4', X'0D15500C',X'4FE06897',X'2CF512D9',X'EA57E017', X'C27480A7',X'B795F9C0',X'A6731057',X'C83390B7', X'CAF48004',X'406580D5',X'4BE0BC0A',X'10094BC0', X'C883811B',X'93348179',X'E41F111B',X'A150C813', X'A011A2D3',X'9313BA0A',X'F8009801',X'92FBBC0A', X'1009A83D',X'9309782C',X'B795F9C0',X'A7355017', X'500C0C17',X'C073AE93',X'501F9302',X'0D156897', X'2D1512D9',X'C83390B7',X'AB74A273',X'933482D9', X'E0065826',X'EFF45008',X'582632A8',X'2768C014', X'AEF49012',X'ABF25826',X'F177F168',X'FC009197', X'2C37C1A8',X'3C376177',X'0835E40C',X'6908DFEC', X'21735826',X'0CF5501F',X'933482D9',X'E0185826', X'F177AEB4',X'91975826',X'2C37C1DA',X'FC00501F', X'933482D9',X'E4196077',X'A2B4F573',X'F9C0C214', X'81ADC1F4',X'C9D482D9',X'08354291',X'0C06C01F', X'B3B7A314',X'B01DA15D',X'A17DA1B0',X'4D811004', X'09058179',X'DEF3200C',X'EB6CE00C',X'F168DDE3', X'21C84868',X'29E82D4C',X'632C0C2C',X'7B8C0C2C', X'70CC0C0D',X'C00E4D00',X'11760C4C',X'70AC4920', X'F56E1176',X'0C4C70AC',X'0C2570C8',X'81790C2C', X'708C4840',X'81690C2C',X'70AC0C25',X'7AC88144', X'48400C2C',X'790C9204',X'8176640F',X'0815F575', X'11760915',X'0C1FC006',X'92048176',X'5C265004', X'EBA4E004',X'92048176',X'5C269002',X'ABE29204', X'81765C26',X'500DEBAD',X'E01F933A',X'8179E00D', X'9204812A',X'5406500C',X'49C0C00C',X'49E0812A', X'4B209204',X'81764B00',X'C0E38173',X'6E2F0810', X'47161176',X'5E2F5010',X'81714840',X'A500117E', X'484091FE',X'A120A1E0',X'A2E40C07',X'C101DDE3', X'21C04BE0',X'C053A011',X'A3E9A6D3',X'10044840', X'91FEA2E4',X'B160A1E0',X'0C0BC0C0',X'8183EB53', X'2418C01F',X'541F501D',X'EBDD4222',X'9801C0FD', X'9802E00C',X'A8ECDDF3',X'6A8CEF5D',X'200C034C', X'0CB5732C',X'28B5EB5D',X'2418C01F',X'541F501D', X'C8FD9801',X'26D31195',X'0855C9F4',X'827FC9D4', X'82B19190',X'82D90835',X'F16CDCFD',X'21CCC1FD', X'81CFC234',X'82D9292C',X'B67AF9A0',X'F17B0C2C', X'612CFC00',X'6ACC4988',X'42A2A21A',X'4D8F11CA', X'498D09B5',X'A354A233',X'BC0A1009',X'083542A2', X'82D90835',X'282CCA34',X'81DE2CAC',X'628C2C2C', X'62CC2C6C',X'630CFC00',X'634CC0DD',X'81E5A01F', X'A03FB3F7',X'0D7511F9',X'0835EB5D',X'075AC00C', X'C7FD706C',X'C2B482D9',X'2419C00C',X'582C0C55', X'5017500C',X'A774501F',X'933482D9',X'E41F60B7', X'4983A754',X'10102D15',X'12D9EA15',X'E00CDCF5', X'686CE015',X'98012887',X'C0079802',X'08879801', X'B795F9C0',X'8210DE52',X'21D5AB55',X'A375A315', X'A3359068',X'82EE82DB',X'C053A011',X'0C13C1D0', X'A190BA09',X'9801B715',X'F9C0AA33',X'CA5AA2F3', X'CB54824A',X'CB148230',X'C3348237',X'C2D3822B', X'A6331004',X'0855AB34',X'C29A82E8',X'82EE0835', X'AB14923A',X'82D12A35',X'ADB011AD',X'0835A735', X'12EEEA3B',X'E01BF56C',X'689BC09D',X'AA9ADB7A', X'F55DC16C',X'DC6C216C',X'C61A686C',X'CAF49801', X'9802C87D',X'9215AB54',X'923A82D1',X'C09D8257', X'C23AC19D',X'82A3A1D4',X'A69310BF',X'C0BD82CF', X'C23AC19D',X'825EA693',X'10BFEB53',X'E00CCA3A', X'082C0C2C',X'C1D3D9F3',X'1C2C200C',X'034C2D35', X'708C2CB5',X'11B282D9',X'C87D9215',X'AA53C19D', X'8275A1F4',X'A69310BF',X'DDF3200C',X'EB4C0753', X'C00C2DD5',X'708C0CB5',X'12D90833',X'919082D9', X'0895C0DD',X'828BA01F',X'A03FB3F7',X'498B0955', X'A7541010',X'EB5D075A',X'C00CC7FD',X'706CC2B4', X'82D92419',X'C00C582C',X'0C555017',X'500CA774', X'501F9334',X'82D9E41F',X'60B7498B',X'A7541010', X'2D1512D9',X'EB53E00C',X'CA3A082C',X'0C2CC1D3', X'D9F31C2C',X'200C034C',X'2D35786C',X'82D928B5', X'919082D9',X'C87D9215',X'C09D82C6',X'C19D82BC', X'A1D4A693',X'10BFDDF3',X'200CEB4C',X'0753C00C', X'0CB5706C',X'82D90C33',X'12B009D5',X'C0BD82CF', X'C19D82CD',X'A69310BF',X'AE3A125E',X'A51012D3', X'A130A2F4',X'EA3BE411',X'F9000C1A',X'C1B082E0', X'498D91FE',X'CA13820C',X'A2F4A130',X'A1F00C13', X'C1D0C053',X'A011AA73',X'BA09A6D3',X'1010B170', X'0C1AC0F0',X'DCFA21B0',X'82E291FE',X'A170A5F0', X'12D2AAF3',X'CAF48021',X'F17DF17F',X'A334B3D7', X'4D8A1004',X'4BC0740E',X'5008C808',X'98024BE0', X'8801F08C',X'640E080C',X'540E500C',X'4BE09801', X'4043B7AC',X'1310F3AC',X'DCAC200C',X'090CE80E', X'200C9801',X'9309084C',X'540C5006',X'1C4E6866', X'92FB9801',X'6C2C0810',X'640C0811',X'4067E00C', X'540C5006',X'B806640C',X'08069302',X'B809AAD3', X'F170C811',X'4880F171',X'9803229F',X'283FA81F', X'D83F0915',X'9802EA37',X'E017C43D',X'62B74137', X'413AEFB4',X'787FEBA4',X'083507BF',X'C008EFBF', X'60A8E408',X'70889801',X'E0080835',X'A808DFC8', X'2008EE92',X'787FEA82',X'20085C28',X'500C5008', X'EE3F900B',X'C374835B',X'DEEC787D',X'DB6CE008', X'EB740368',X'B7087868',X'98010835',X'3828F0CC', X'AA94C82C',X'A294EA3F',X'2637C008',X'2828C9A8', X'9801EA28',X'022CAFEB',X'786C9801',X'0835C06B', X'8378C02B',X'9801A3EB',X'540B900B',X'83700835', X'CA948388',X'C02B9801',X'EA3FC83D',X'EA28E01F', X'B34C382C',X'F1EBD83F',X'0875328B',X'98020835', X'40632855',X'C02B9801',X'0875E81F',X'C83DE008', X'B2AC382C',X'F07FEA37',X'241FC00C',X'ABEBF17E', X'DD2821DE',X'EA8B201E',X'282CF168',X'DD2C21C8', X'D9282017',X'B108E808',X'0017B2A8',X'E808000C', X'FC00716C',X'583EC03D',X'285E040C',X'9016C036', X'9801FC00',X'7ACC541E',X'9008C028',X'9801C817', X'83BD085E',X'C83D289E',X'200CB12B',X'E80B0017', X'EA88E008',X'A048D82C',X'C03DD83F',X'32C80835', X'98020000',X'00000000',X'00000000',X'00000000', X'4989C2D4',X'8069B2F4',X'A2D4806A',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'0C010003',X'A8BF8200' %LIST ! ! !---------------------------------------------------------------------------------------------------- %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' ! 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 X1, %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:255) %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' !---------------------------------------------------------------------------------------------------- ! ! ! ! ! ! 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) 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 %UNTIL (CA0_CRESP0 # 0 %AND CA0_MARK = -1) %C %OR %C COUNT > 300000 %C %THEN COUNT = COUNT + 1 ! 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 %UNTIL (CA_CRESP0 # 0 %AND CA_MARK = -1) %C %OR %C COUNT > 900000 %C %THEN COUNT = COUNT + 1 ! 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 MSG("CA0") DUMP TABLE(2, RA0AD, 32) MSG("CA") DUMP TABLE(3, CAA, 272) MSG("INI") DUMP TABLE(4, ADDR(INI), 16) %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 ! RESPONSES ! VARIOUS MESSAGES TO SYSTEM LOG %ROUTINE CONNECT STREAMS(%INTEGER %C PT, %C CAA, %C STREAM, %C CONNECT) %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 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 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 %UNTIL SENT_RESP0 # 0 %C %OR %C COUNT > 100000 %C %THEN COUNT = COUNT + 1 %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) %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) %INTEGER CAA %INTEGER GPCNO %INTEGER SAW %RECORDNAME CA(CAF) %RECORDNAME SENT(CASEF) MSG("GPC PAW NOT CLEARED PT=".HTOS(PT,2)) ! 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 SEND CH FLAG (PT) %AND WAIT(100) ! SLAVES BACK ON SLAVES ON OFF(-1) 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' ELSE ISSUES ! 'READ STREAMS CONTROLLER STATUS'. DUMPS RESPONSE TO SYS LOG %INTEGERFN READ STRM DATA(%INTEGER %C PT, %C STREAM, %C CONTROLLER) ! %INTEGER CAA %INTEGER COMMAND %INTEGER COUNT %INTEGER GPCNO %INTEGER LEN %INTEGER SAWFLAGS %OWNINTEGERARRAY STREAM DATA(0:63) %RECORDNAME CA(CAF) ! MESSAGE MSG("GPC READ STRM DATA PTS=".HTOS(PT << 4 ! STREAM, 3)) ! SET UP %IF CONTROLLER = 0 %START LEN = 64 COMMAND = READ STREAM DATA %FINISH %ELSE %START LEN = 4 COMMAND = READ STREAMS CONTROLLER STATUS %FINISH GPCNO = PT TO GPC(PT - LOPT) CAA = CAAS(GPCNO) CA == RECORD(CAA) %IF CA_PAW # 0 %START PAW NOT CLEARED(PT, -1) MSG("END OF READ STREAM DATA") %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 %UNTIL CA_CRESP0 # 0 %C %OR %C COUNT > 100000 %C %THEN COUNT = COUNT + 1 ! SLAVES BACK ON SLAVES ON OFF(-1) DUMP TABLE(79, ADDR(STREAM DATA(0)), LEN) MSG("CRESP0=".HTOS(CA_CRESP0, 8)) MSG("END OF READ SREAM DATA") ! 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 ! ! ! ! ! %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 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 D(DEVICE ENTRY F) %RECORDNAME CA(CAF) %RECORDNAME SENT(CASEF) %RECORDNAME GPCT,GE(GPCTF) ! P=INP GMON<-(KMON>>GPC SNO)&1 %IF GMON#0 %THEN PRINTSTRING("GPC( IN):") %AND PTREC(P) %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) 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) 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 GPCT_STATE = NOT ALLOCATED GPCT_X1 = 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 ! ? ! 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 < 3 %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 = NOT ALLOCATED %OR STATE = READY %START CONNECT STREAMS(PT, CAA, STRM, 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 ! ! SET G COMMAND(4): XPT = -1 XSTRM = -1 ! ! G COMMAND(3): ! ? %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 %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) 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 WK = "GPC TIMEOUT ".MNS(D)." ".HTOS(D_GPTSM, 5) MSG(WK) OPMESS2(0, WK) STRM = (GE_PTSM >> 4) & 15 J = READ STRM DATA(PT, STRM, 0) *JLK_ CA_PAW = 3 << 24 ! STRM; ! STOP STREAM *JLK_ WAIT(50) CONNECT STREAMS(PT, CAA, STRM, 1) D_SECS SINCE = 0 MSG("END OF TIMEOUT") %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) *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 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 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 -> 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_ -> MORE INTS %FINISH ! NOT AN ATTENTION INTERRUPT %IF STATE = SENSE FIRED %START %IF D_LOGMASK & BYTEINTEGER(ADDR(D_SENSE1)) # 0 %START DUMPTABLE(70 + GPCT_DEVTYPE, ADDR(D), D_DEVICE ENTRY S) %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 %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,0) %IF GPCT_DEV TYPE = FE %C %THEN CONNECT STREAMS(PT, CAA, STRM, 1); ! RE CONNECT FE AFTER ABTERM %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) *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 -> MORE INTS %FINISH ! ! ACT = 2 Q_P1 = RESP0 Q_P2 = RESP1 *JLK_ %IF RESP0 & NORMAL TERMINATION > 0 %THEN -> TRY NEXT -> 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) %UNLESS SLOT = ENDLIST %THEN GPCT_STATE = DISCONNECTED %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) *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 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 GMON#0 %THEN PRINTSTRING("GPC( PONS):") %AND PTREC(P) %RETURN %FINISH OUT: INP=P %IF GMON#0 %THEN PRINTSTRING("GPC( OUT):") %AND PTREC(P) %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 %UNLESS %C XDEVTYPE = MT %AND %C XMNEMONIC & X'F00' # X(16)>>12 & X'F00' %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) = X'07'; ! DELETE, IGNORED BY PRINTER %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) %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 %IF GMON#0 %THEN PRINTSTRING("GPC( PONS):") %AND PTREC(Q) 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