$€ðskQ ›c, .TITLE TTDRV .IDENT /32.00/ ; ; ; COPYRIGHT (c) 1981 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD ; MASSACHUSETTS. ALL RIGHTS RESERVED. ; ; COPYRIGHT (c) 1973 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE ; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS ; SOFTWARE OR ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR ; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND  ; OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERED. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ; ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. ; ; ; VERSION 32.00 ; ; D. N. CUTLER 24-OCT-73 ; ; PRE-VERSION 18 MODIFICATIONS BY: ; ; D. N. CUTLER ; T. J. MILLER ; R. LARY ; E. L. BAATZ ; C. SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 12-JUL-79 ; MSH041 -- CHANGE TS.CKR REFERENCE TO T.CKR ; ** RETRACTED - 4/6/81 ** ; ; ERIC BAATZ 21-JUL-79 ; EB228 -- REDISPATCH CPU AFTER SINGLE-USER MCR OPEN ; ; ERIC BAATZ 10-NOV-79 ; EB251 -- CLEAR U.ATT IF BAD IO.ATA ; ; ERIC BAATZ 6-JAN-80 ; EB252 -- DO NOT USE CURBF FOR DZTIM ; ; ERIC BAATZ 26-MAY-80 ; EB266 -- HIGHLIGHT HOW TO CONTROL THE LENGTH OF THE ; INTERVAL DURING WHICH LOSS OF CARRIER ON ; REMOTE DH11 LINES IS NOT CONSIDERED A REASON ; TO HANG UP ; ; ERIC BAATZ 26-MAY-80 ; EB267 -- OPTIONALLY DO NOT SET TERMINAL CHARACTERISTICS ; TO A KNOWN STATE WHEN ANSWERING A REMOTE LINE ; ; ERIC BAATZ 26-MAY-80 ; EB268 -- OPTIONALLY ALLOW LINE FEEDS TO BE TREATED "LIKE FORM ; FEEDS" ; ; ERIC BAATZ 26-MAY-80 ; EB269 -- OPTIONALLY ALLOW A HARDWARE IMPLEMENTATION OF ; XON/XOFF ; ; T. M. MARTIN 9-SEP-80 ; TMM008 -- PREVENT DOUBLE LOCK ON US.ECH IN ACCEPTANCE ROUTINE ; OF IO.WBT, WHICH CAN RESULT IN DOUBLE FORKS AFTER ; US.ECH IS CLEARED ; ; T.M. MARTIN 9-SEP-80 ; TMM009 -- DO NOT CHECK US.OUT WHEN BREAKING-THRU A BUSY UNIT ; ; T. M. MARTIN ; TMM010 -- CLEAR I.PRM+16 ( RMS LOCKING WORD ) BEFORE CALLING $IODON ; ; T. M. MARTIN 31-OCT-80 ; TMM011 -- IMPLEMENT MULTIPLE BUFFERED I/O SUPPORT ; ; T. M. MARTIN 15-NOV-80 ; TMM012 -- ALLOW VT100 ANSI ESCAPE SEQUENCES TO BE RECOGNIZED ; ; T. M. MARTIN 20-DEC-80 ; TMM013 -- DZ MODEM SUPPORT, DO NOT CHECK FOR CARRIER IMMEDIATELY ; AFTER SETTING DTR ; ; T. M. MARTIN 7-MAR-81 ; TMM032 -- ADD ALTERNATE CLI SUPPORT ; ; T. M. MARTIN 20-APR-81 ; TMM035 -- RESTRUCTURE U.CW3 FOR SETTABLE REMOTE BAUD RATE ; AND FREE UP A FEW BITS IN THE HDX-TTDRV UCB ; ; T. M. MARTIN 27-APR-81 ; TMM036 -- ADD ASR33 TERMINAL TYPE (UPCASE OUTPUT) ; ; ; TERMINAL DRIVER FOR DL11-A LINE INTERFACE AND DH11/DJ11/DZ11 ; LINE MULTIPLEXERS ; ;- ; MACROS TO CONSOLIDATE LOADABLE DRIVER CONDITIONAL ASSEMBLY ; ; IF NECESSARY, SAVE THE PS WORD FROM THE INTERRUPT (IT ; CONTAINS THE UNIT NUMBER OF THE INTERRUPTER), SAVE R4 AND R5, ; AND LOWER OUR PRIORITY. IF THE DRIVER IS LOADABLE AND MAPPED, ALL ; OF THAT IS DONE BY ANOTHER PART OF THE EXEC (THE INTERRUPT CONTROL ; BLOCK) SO IT DOES NOT HAVE TO BE DONE HERE ; TYPE = DL, DH, DJ, OR DZ ; PRI = PRIORITY TO CALL $INTSV WITH ; NCTRLR = NUMBER OF CONTROLLERS ; .MACRO TTSAV$ TYPE,PRI,NCTRLR .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT NCTRLR-1 MFPS TYPE'TMP .ENDC CALL $INTSV,PRI .ENDC JSR R3,TYPE'SAV .ENDM ; ; GENERATE COMMON CODE FOR THE SAVE ROUTINES OF THE VARIOUS ; DEVICES THIS DRIVER SUPPORTS. IF THIS DRIVER IS LOADABLE, ; SOME OF THE CODE IS DONE BY ANOTHER PART OF THE EXEC (THE ; INTERRUPT CONTROL BLOCK) SO IT DOES NOT HAVE TO BE DONE HERE. ; TYPE = DL, DH, DJ, DZ ; NCTRLR = NUMBER OF CONTROLLERS ; MUX = NONNULL IF TO GENERATE FOR A MULTIPLEXER ; .MACRO TTSET$ TYPE,NCTRLR,MUX MOV R3,-(SP) .IF GT NCTRLR-1 .IF NDF L$$DRV!M$$MGE!LD$TT MOV TYPE'TMP,R4 BIC #177760,R4 ASL R4 .ENDC  .IF NB MUX MOV TYPE'TBL(R4),R3 MOV TYPE'CSR(R4),R4 .IFF MOV CNTBL(R4),R5 .ENDC .IFF .IF NB MUX MOV TYPE'TBL,R3 MOV TYPE'CSR,R4 .IFF MOV CNTBL,R5 .ENDC .ENDC .ENDM ; ; DEFINE THE MACRO USED TO GENERATE THE SET SPEED TABLE FOR SF.SMC ; ; SYMBOL = A BAUD RATE SYMBOL FROM TTSYM$ (OF THE FORM S.X) ; DH = THE FOUR BIT PATTERN THAT MUST BE ASSERTED IN THE ; DH11 LINE PARAMETER CSR TO GET THE BAUD RATE REPRESENTED ; BY SYMBOL. A VALUE OF ZERO INDICATES THAT A SPEED IS ; NOT SUPPORTED BY THE DH11. ; DZ = THE FOUR BIT PATTERN THAT MUST BE ASSERTED IN THE ; DZ11 LINE PARAMETER CSR TO GET THE BAUD RATE REPRESENTED ; BY SYMBOL. A VALUE OF ZERO INDICATES THAT A SPEED IS ; NOT SUPPORTED BY THE DZ11. ; .MACRO SPDTAB SYMBOL,DH,DZ .BYTE DH*20+DZ .BYTE SYMBOL .ENDM ; ; MACRO LIBRARY CALLS ; .MCALL PCBDF$,TTSYM$,UCBDF$ ;TMM008 UCBDF$ ,,TTDEF ;TMM008 PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS ;**-1 TTSYM$ ;DEFINE "TF.", "F1.", "F2.", "T.", ; AND "TC." SYMBOLS .IF DF D$$M11 .GLOBL U.DMCS ;REFERENCE SO SYMBOL WILL BE IN ; TTDRV.STB FOR LOA.TSK .ENDC ; ; THE SUBFUNCTION BIT IO.UMD (VALUE OF 4) SHOULD NEVER BE USED ; TO INDICATE A TERMINAL SUBFUNCTION, BECAUSE IT FLAGS THE FUNCTION ; AS A USER MODE DIAGNOSTIC. FUNCTION CODE 10 (10*400 IF YOU PREFER) ; IS RESERVED FOR DIAGNOSTICS. ; M$$CRI=80. ;NUMBER OF BYTES OF INFORMATION IN A MCR BUFFER ; ; EQUATED SYMBOLS ; ; FOR CONVENIENCE DEFINE AN INTERNAL CONDITIONAL ASSEMBLY SYMBOL ; .IF DF T$$UTB .IF NDF C$$CKP!T$$BUF NOEXBF=0 ;DEFINED IF TASK'S BUFFER TO BE USED FOR ; CHARACTER BUFFERING AND SYSTEM CANNOT ; CHECKPOINT .ENDC .ENDC ;TMM011 .IF DF C$$CKP&T$$BUF ;TMM011 ;TMM011 DFCKP=0 ;DEFINED FOR BUFFERED INPUT ;TMM011 ;TMM011 .ENDC ;TMM011 ;TMM011 .IF DF T$$RNE!T$$RPR!T$$RST!T$$TRW SS.RAL=200 ;SET IN S.STS IF READ ALL MODE SS.WAL=100 ;SET IN S.STS IF WRITE ALL MODE SS.RNE=40 ;SET IN S.STS IF READ WITH NO ECHO SS.RST=20 ;SET IN S.STS IF READ WITH SPECIAL TERMINATORS .ENDC ; ; IN PRE-V3.2 VERSIONS OF THIS TERMINAL DRIVER, "ESC P IC FC" ; WAS AN ESCAPE SEQUENCE (SEE COMMENTS IN FRONT OF THE LABEL ; 200$ THAT PRECEDES THE LABEL TTCAN), BECAUSE THE VT61 COULD ; EMIT A SUBSTANTIAL NUMBER OF SUCH ESCAPE SEQUENCES. BECAUSE ; OF THE INCREASING NUMBER OF TERMINALS THAT THINK "ESC P" IS ; A COMPLETE ESCAPE SEQUENCE (VT52, VT100 (THE PF1 KEY), ETC.), ; THE TERMINAL DRIVER HAS BEEN MODIFIED TO RECOGNIZE "ESC P" ; AS AN ESCAPE SEQUENCE. THE DRIVER CAN BE MODIFIED TO ; RECOGNIZE "ESC P IC FC" RATHER THAN "ESC P" AS AN ESCAPE ; SEQUENCE BY REMOVING THE SEMICOLON THAT PRECEDES THE ; FOLLOWING DEFINITION. ; ;ESCPIC=0 ; EB266 ; ; EB266 ; THE LENGTH OF THE INTERVAL DURING WHICH LOSS OF CARRIER ON ; EB266 ; A REMOTE DH11 LINE DOES NOT CAUSE A HANG UP IS FROM A ; EB266 ; MINIMUM OF (N-1)*4 SECONDS TO N*4 SECONDS, WHERE N IS ; EB266 ; DEFINED BY THE VALUE OF DMGLTC, WHICH STANDS FOR "DM11 ; EB266 ; GLITCH VALUE". ; EB266 ; ; EB266 ; EB266 DMGLTC=2 ; EB266 ; EB268 ; ; EB268 ; SOME FILE FORMATS AND APPLICATION SYSTEMS USE LINE FEEDS ; EB268 ; RATHER THAN LINE FEEDS/CARRIAGE RETURN PAIRS AS RECORD ; EB268 ; TERMINATORS. UNDER THOSE CIRCUMSTANCES, THE TERMINAL ; EB268 ; DRIVER WILL DO AUTOMATIC LINE WRAPAROUND, BECAUSE IT DOES ; EB268 ; NOT SEE A CARRIAGE RETURN FOR LONG STRETCHES OF TIME. ; EB268 ; ; EB268 ; REMOVING THE SEMICOLON IN FRONT OF THE NEXT SYMBOL DEFINITION ; EB268 ; CAUSES LINE FEEDS TO BE TREATED LIKE FORM FEEDS (THEY ARE ; EB268 ; PASSED TO THE TERMINAL AND RESET THE CURRENT HORIZONTAL ; EB268 ; POSITION TO THE LEFT MARGIN) FOR DEVICES THAT CAN HANDLE ; EB268 ; HARDWARE FORM FEEDS. ; EB268 ; ; EB268 ; EB268 ;.IIF DF T$$HFF, PASSLF=0 ; EB268 ; EB269 ; ; EB269 ; REMOVING THE SEMICOLON IN FRONT OF THE NEXT SYMBOL DEFINITION ; EB269 ; CAUSES THE TERMINAL DRIVER TO HANDLE THE LOSS OF A MODEM ; EB269 ; SIGNAL FOR A TERMINAL THAT KNOWS HOW TO HANDLE HARDWARE ; EB269 ; FORM FEEDS AND IS CONNECTED BY A REMOTE DH11 LINE (A ; EB269 ; DM11-BB) AS IF AN XOFF HAD BEEN RECEIVED. THE ASSERTION ; EB269 ; OF THE SIGNAL IS HANDLED AS IF AN XON HAD BEEN RECEIVED. ; EB269 ; ; EB269 ; THE SECONDARY RECEIVE SIGNAL IS USED AS AN EXAMPLE ; EB269 ; ; EB269 ; EB269 ;.IIF DF T$$HLD!T$$SYN, XONSIG=0 ; EB269 .IIF DF XONSIG, XONBIT=10000 ;SECONDARY RECEIVE IN 1ST CSR ; EB269 .IIF DF XONSIG, XONBI2=20 ;SECONDARY RECEIVE IN 2ND CSR ; EB269 ; EB267 ; ; EB267 ; THE NORMAL BEHAVIOR OF THE TERMINAL DRIVER IS TO SET A REMOTE ; EB267 ; LINE TO A KNOWN SET OF TERMINAL CHARACTERISTICS BEFORE ; EB267 ; ANSWERING THE LINE. THIS IS TO AVOID CONFUSION (FOR EXAMPLE, ; EB267 ; HAVING THE LINE SET TO HOLD SCREEN MODE) AND MISCHIEF (A ; EB267 ; TERMINAL CAN BE DISABLED BY SETTING ITS BUFFER SIZE TO TWO ; EB267 ; AND THEN HANGING UP). ; EB267 ; ; EB267 ; REMOVING THE SEMICOLON IN FRONT OF THE NEXT SYMBOL DEFINITION ; EB267 ; CAUSES THE TERMINAL DRIVER NOT TO CHANGE THE CHARACTERISTICS ; EB267 ; OF A TERMINAL (TO USE THOSE FROM THE LAST MCR SET COMMANDS) ; EB267 ; BEFORE ANSWERING A REMOTE DH11 LINE. ; EB267 ; ; EB267  ; EB267 ;USECDH=0 ; EB267 ; EB267 ; ; EB267 ; REMOVING THE SEMICOLON IN FRONT OF THE NEXT SYMBOL DEFINITION ; EB267 ; CAUSES THE TERMINAL DRIVER NOT TO CHANGE THE CHARACTERISTICS ; EB267 ; OF A TERMINAL (TO USE THOSE FROM THE LAST MCR SET COMMANDS) ; EB267 ; BEFORE ANSWERING A REMOTE DZ11 LINE. ; EB267 ; ; EB267 ; EB267 ;USECDZ=0 ; EB267 ; ;TMM035 ; ;TMM035 ; HALF DUPLEX TERMINAL DRIVER SPECIFIC U.CW3 DEFINITIONS ;TMM035 ; ;TMM035 ; +-------------------------------------+ ;TMM035 ;U.CW3 |15|14|13|12|11 10 9 8|7 6 5 4|3 2 1 0| ;TMM035 ; +-------------------------------------+ ;TMM035 ; | | | | | | | ;TMM035 ; odd | | | | | | ;TMM035 ; parity | | | | | | ;TMM035 ;(DH's & DZ's) | | | | | | ;TMM035 ; | | | | | | ;TMM035 ; enable | |  | | | ;TMM035 ; parity | | | | | ;TMM035 ; (DH's & DZ's) | | | | | ;TMM035 ; | | | | | ;TMM035 ; U3.UPC | | | | ;TMM035 ; Upcase Output | | | | ;TMM035 ; | | | | ;TMM035 ; undefined | | | ;TMM035 ; | | | ;TMM035 ; Remote | | ;TMM035 ; Answer | |  ;TMM035 ; Speed | | ;TMM035 ; | | ;TMM035 ; Transmit | ;TMM035 ; Speed | ;TMM035 ; | ;TMM035 ; Receive ;TMM035 ; Speed ;TMM035 ; ;TMM035 ; ;TMM035 ;**-28 ; ; TERMINAL CONTROL BLOCK OFFSET DEFINITIONS ; STATS=0 ;TERMINAL STATUS WORD STRBF=2 ;CURRENT BUFFER ADDRESS (INPUT) RMBYT=4 ;REMAINING BYTES IN BUFFER (INPUT) FNBYT=5 ;FINAL (TERMINATING) BYTE OF A READ CURBF=6 ;STARTING BUFFER ADDRESS (INPUT) HORPS=10 ;HORIZONTAL POSITION OF CARRIAGE ;**-1 FLBYT=11 ;FILL BYTE DFUIC=12 ;DEFAULT UIC OF TERMINAL MEBUF=14 ;MULTI-ECHO BUFFER ADDRESS MBUFR=16 ;DYNAMIC MULTI-ECHO BUFFER INPRQ=20 ;IF NONZERO, UNSOLICITED INPUT REQUEST MBUF0=21 ;ZERO BYTE TERMINATING M-E BUFFER DHBUF=22 ;DH11 OUTPUT BUFFER IHORP=23 ;INITIAL HORIZONTAL POSITION (T$$RUB) DZTIM=IHORP ;TIME OUT COUNT FOR DZ11 REMOTE LINES ; EB252 NEXTB=IHORP+1 .IIF DF T$$ACR!T$$BTW!T$$CCA!T$$CCO!T$$ESC!T$$HLD, T1=0 .IF DF T1!T$$RPR!T$$SYN!T$$TRW!T$$UTB!T$$30P!DFCKP ;TMM011 ATERS=NEXTB ;ADDITIONAL TERMINAL STATUS ;**-1 NEXTB=NEXTB+2 .ENDC .IF DF T$$CCA&A$$TRP CCAST=NEXTB ;STARTING ADDRESS OF CONTROL C AST NEXTB=NEXTB+2 .ENDC .IF DF T$$ESC SYNTX=NEXTB ;ADDRESS OF CURRENT SYNTAX RULE FOR NEXTB=NEXTB+2 ; ESCAPE SEQUENCES .ENDC .IF DF D$$M11 DMTIM=NEXTB ;TIME OUT COUNT ON REMOTE LINES NEXTB=NEXTB+1 UDMVC=NEXTB ;VECTOR ADDR OF DM11 (USED BY LOA.TSK) NEXTB=NEXTB+1 DMCSR=NEXTB ;CSR OF DM11 FOR THIS UNIT ; U.DMCS=DMCSR ;DEFINED BY SGN. USED BY LOA.TSK NEXTB=NEXTB+2 .ENDC ; ; TERMINAL STATUS WORD BIT DEFINITIONS ; MODE=100000 ;MODE OF BUSY TERMINAL (0=INPUT 1=OUTPUT) LFCT=74000 ;UNPROCESSED LINE FEED COUNT FIELD LFBT=4000 ;UNPROCESSED LINE FEED ADD/SUB BIT CRTY=2000 ;CARRIAGE CONTROL AT END OF LINE (1=YES) CRJT=1000 ;CARRIAGE RETURN JUST TYPED (1=YES) EOLS=400 ;END OF LINE SEEN (1=YES) UIFP=200 ;UNSOLICITED INPUT FORK PENDING (1=YES) SOLI=100 ;SOLICITED INPUT (1=YES) CTLO=40 ;OUTPUT DISABLED (1=YES) RUBP=20 ;RUBOUT SEQUENCE IN PROGRESS (1=YES) FLCT=17 ;UNPROCESSED FILL COUNT FIELD FLBT=1 ;UNPROCESSED FILL COUNT BIT ; ; ADDITIONAL TERMINAL STATUS WORD BIT DEFINITIONS ; RPRM=100000 ;SET IF CURRENT WRITE IS THE PROMPT FROM IO.RPR BTWP=20000 ;SET IF A WRITE IS BREAKING THROUGH A READ CCPN=10000 ;SET IF A CONTROL C IS PENDING UNDER SPECIAL ; CIRCUMSTANCES (T$$SYN, T$$HLD) BAKS=4000 ;SET IF SENDING EXIT HOLD-SCREEN MODE ESCAPE ; SEQUENCE (T$$HLD) FKCR=2000 ;SET IF LAST CR WAS JUST TO DISPLAY A LONG ; LINE ON MULTIPLE CRT LINES (T$$ACR) ECHO=1000 ;SET IF ECHOING IN PROGRESS (T$$30P) XOFF=400 ;SET IF XOFF TO BE SENT AT END OF PRESENT READ ; (T$$RPR) UPND=200 ;SET IF DHBUF HOLDS BYTE SUPPRESSED BY XOFF ; (T$$HLD, T$$SYN) CHAR=100 ;SET IF MBUFR HOLDS AN INPUT CHARACTER THAT ; HAS BEEN RECEIVED BUT NOT ECHOED (T$$30P) WESC=40 ;SET IF ATTACHED TASK WANTS ESCAPE SEQUENCES ; (T$$ESC) ESCS=20 ;SET IF IN MIDDLE OF AN ESCAPE SEQUENCE (T$$ESC) CCON=10 ;SET IF CONTROL C AST CODE IS ACTIVE (T$$CCA) MCTR=4 ;SET IF DOING CONTROL R FROM TASK'S BUFFER ; (T$$CTR, T$$UTB) NCKP=2 ;SET IF SOLICITED INPUT REQUEST IS FROM ; A NONCHECKPOINTABLE TASK (T$$UTB) UOFF=1 ;SET IF OUTPUT TURNED OFF BY AN XOFF ; (T$$HLD, T$$SYN) ; ; MOST LOCAL DATA (SEE ALSO CNTBL) ; ; ESCAPE SEQUENCE SYNTAX TABLE ; .IF DF T$$ESC SYNTAB: .BYTE 73,73 ;;;A ;  .WORD 265$ ;;; .BYTE 77,77 ;;;A ? .WORD 265$ ;;; .BYTE 117,117 ;;;AN O .WORD 270$ ;;; .IF DF ESCPIC .BYTE 120,120 ;;;A P .WORD 265$ ;;; .ENDC .BYTE 131,131 ;;;A Y .WORD 280$ ;;; .BYTE 133,133 ;;;CONTROL SEQUENCE INTRODUCER ;TMM012 .WORD 300$ ;;; ;TMM012 265$: .BYTE 40,57 ;;;AN INTERMEDIATE CHARACTER .WORD 265$ ;;; .BYTE 60,176 ;;;ANYTHING ELSE .WORD 0 ;;; 270$: .BYTE 40,57 ;;;AN INTERMEDIATE CHARACTER .WORD 270$ ;;; .BYTE 100,176 ;;;SPECIAL O RANGE TERMINATOR .WORD 0 ;;; 280$: .BYTE 40,176 ;;;FIRST COORDINATE (BIAS 40) .WORD 290$ ;;; 290$: .BYTE 40,176 ;;;SECOND COORDINATE (BIAS 40) .WORD 0 ;;; 300$: .BYTE 40,77 ;;;PARAMETER OR INTERMEDIATE CHARACTER ;TMM012 .WORD 300$ ;;; ;TMM012 .BYTE 100,176 ;;;SPECIAL FINAL CHARACTER ;TMM012 .WORD 0 ;;; ;TMM012 .ENDC .IF DF T$$GTS ; ; FORM THE WORDS RETURNED BY IO.GTS THAT INDICATE WHICH SYSGEN ; OPTIONS ARE IN THIS DRIVER ; T2=0 .IF DF T$$ACR T2=T2!F1.ACR .ENDC .IF DF T$$BTW T2=T2!F1.BTW .ENDC .IF DF T$$BUF&C$$CKP T2=T2!F1.BUF .ENDC .IF DF T$$CCA&A$$TRP T2=T2!F1.UIA .ENDC .IF DF T$$CCO T2=T2!F1.CCO .ENDC .IF DF T$$ESC T2=T2!F1.ESQ .ENDC .IF DF T$$HLD T2=T2!F1.HLD .ENDC .IF DF T$$LWC T2=T2!F1.LWC .ENDC .IF DF T$$RNE T2=T2!F1.RNE .ENDC .IF DF T$$RPR T2=T2!F1.RPR .ENDC .IF DF T$$RST T2=T2!F1.RST .ENDC .IF DF T$$RUB T2=T2!F1.RUB .ENDC .IF DF T$$SYN T2=T2!F1.SYN .ENDC .IF DF T$$TRW T2=T2!F1.TRW .ENDC .IF DF T$$UTB T2=T2!F1.UTB .ENDC .IF DF T$$VBF T2=T2!F1.VBF .ENDC ; ; ALL WORDS OF "T2" MUST BE CONTIGUOUS ; TCHR1: .WORD T2 T2=0 ;RSX-11M DOES NOT SUPPORT F2.DCH (DUMP/RESTORE ; CHARACTERISTICS), RSX-11D STYLE IO.KIL ; (F2.DKL), ALTS ECHOING AS "$" (F2.ALT), ; OR SIMULATED FORM FEEDS (F2.SFF) .IF DF T$$SMC T2=T2!F2.SCH .ENDC .IF DF T$$GMC T2=T2!F2.GCH .ENDC .WORD T2 TCHR1E=. .ENDC ; DF T$$GTS .IF DF T$$GMC!T$$SMC ; ; DATA STRUCTURES FOR GET AND SET MULTIPLE CHARACTERISTICS ; ; FROM U2.VT5 TO U2.L3S CONTAINS MASKS FOR U.CW2 TO TEST FOR TERMINAL ; TYPE. THIS INFORMATION MUST PRECEDE ANY INFORMATION ; ASSOCIATED WITH THE MATERIAL FROM TC.SCP TO TC.XSP. ; FROM 0*400+360 TO 1*400+360 CONTAINS CONSTANTS USED FOR SETTING ; RECEIVER AND TRANSMITTER BAUD RATES (SPEEDS) ; FROM U2.CRT TO U2.PRV CONTAINS MASKS FOR U.CW2 TO TEST FOR TERMINAL ; CHARACTERISTICS ; FROM TC.SCP TO TC.XSP CONTAINS WHAT CHARACTERISTICS ARE RECOGNIZED ; BY SF.SMC AND SF.GMC (NOTE THAT TC.RSP AND TC.XSP ARE NOT ; RECOGNIZED BY SF.GMC) ; FROM T.VT05 TO T.L30S CONTAINS WHAT TERMINAL TYPES ARE RECOGNIZED ; BY SF.SMC AND SF.GMC ; .WORD 0 ; .WORD U2.L3S ;LA30 .WORD U2.VT5 ;VT05 .WORD 0 ; .IF DF T$$SMC .WORD 200*400+360 ;REMOTE ANSWER SPEED ;TMM035 .WORD 1*400+360 ;TRANSMITTER SPEED .WORD 0*400+360 ;RECEIVER SPEED .ENDC .WORD U2.PRV ;PRIVILEGED .IF DF T$$HFF .WORD U2.HFF ;HANDLES HARDWARE FORM FEED .ENDC .WORD U2.SLV ;SLAVE .WORD U2.HLD ;HOLD-SCREEN MODE .IF DF T$$RNE .WORD U2.NEC ;NO ECHO MODE .ENDC .WORD U2.LWC ;LOWER TO UPPER CASE CONVERSION .WORD U2.ESC ;CAN GENERATE ESCAPE SEQUENCES .WORD U2.CRT ;CRT (SCOPE) GMCTAB: ; .BYTE TC.SCP ;SCOPE (CRT) .BYTE TC.ESQ ;ESCAPE SEQUENCES .BYTE TC.SMR ;LOWER TO UPPER CASE CONVERSION .IF DF T$$RNE .BYTE TC.NEC ;NO ECHO MODE .ENDC .BYTE TC.HLD ;HOLD-SCREEN MODE .BYTE TC.SLV ;SLAVED .IF DF T$$HFF .BYTE TC.HFF .ENDC .BYTE TC.PRI ;PRIVILEGED .IF DF T$$SMC ENDCW2: .BYTE TC.RSP ;RECEIVER SPEED (END OF U.CW2 ; CHARACTERISTICS) .BYTE TC.XSP ;TRANSMITTER SPEED .BYTE TC.ASP ;REMOTE ANSWER SPEED ;TMM035 .ENDC .BYTE T.VT05 ;VT05 .BYTE T.L30S ;LA30 .BYTE 0 ; .ENDC ; DF T$$GMC!T$$SMC ; ; LEGAL MULTIPLEXER SPEEDS TABLE FOR SF.SMC ; ; EACH ENTRY IS TWO CONSECUTIVE BYTES CONSISTING OF: ; ; HIGH BYTE LOW BYTE ; ; ------------------------------------------------ ; ! BAUD RATE ! DH11 BITS ! DZ11 BITS ! ; ------------------------------------------------ ; ; WHERE BAUD RATE = A TTSYM$ SYMBOL INDICATING WHICH BAUD RATE THIS ; (8 BITS) ENTRY IS FOR ; ; DH11 BITS = IF ZERO, THE BAUD RATE IS NOT SUPPORTED FOR THE DH11 ; (4 BITS) IF NONZERO, THE BIT PATTERN THAT MUST BE ASSERTED ; IN THE DH11 LINE PARAMETER REGISTER TO GET THE ; BAUD RATE FOR RECEPTION OR TRANSMISSION ; ; DZ11 BITS = IF ZERO, THE BAUD RATE IS NOT SUPPORTED FOR THE DZ11 ; (4 BITS) IF NONZERO, THE BIT PATTERN THAT MUST BE ASSERTED ; IN THE DZ11 LINE PARAMETER REGISTER TO GET THE ; BAUD RATE FOR RECEPTION AND TRANSMISSION ; ; A BYTE OF ZEROS (DZ11 AND DH11 BITS ARE ZERO) TERMINATES THE TABLE. ; DH11 BITS = 1 IS A SPECIAL CASE. ; ; THE SUPPORTED SPEEDS ARE THOSE SUPPORTED BY THE MCR COMMAND SET /SPEED. ; .IF DF T$$SMC SPDTB: SPDTAB S.0,1,0 ;SPECIAL CASE FOR DH11 SPDTAB S.110,3,2 S150: SPDTAB S.150,5,4 SPDTAB S.200,6,0 SPDTAB S.300,7,5 SPDTAB S.600,10,6 SPDTAB S.1200,11,7 SPDTAB S.1800,12,10 SPDTAB S.2000,0,11 SPDTAB S.2400,13,12 SPDTAB S.3600,0,13 SPDTAB S.4800,14,14 SPDTAB S.7200,0,15 SPDTAB S.9600,15,16 SPDTAB S.EXTA,16,0 SPDTAB S.EXTB,17,0 .BYTE 0 .ENDC ; ; CONTROL OUTPUT MESSAGES ; .IF NDF M$$CLI!A$$CLI ;TMM032 ;TMM032 ;**-1 CTRLC: .ASCIZ <15><12>/MCR>/ ; .ENDC ;M$$CLI CTRLZ: .ASCIZ /^Z/<15><12> CTRLU: .ASCIZ /^U/<15><12> ;MUST BE AFTER A ZERO BYTE .IF DF T$$HLD LEVHSM: .ASCIZ <33>/\/ ;LEAVE HOLD-SCREEN MODE .ENDC .IF DF T$$RUB .ASCIZ <10><10><10><10><10><10><10><10> ;BACKSPACES CRTBS=.-1 ;MUST BE AT END OF BACKSPACES CRTRUB: .ASCIZ <10>/ /<10> ;BACKSPACE, SPACE, BACKSPACE .ENDC ; ; LA30S CARRIAGE RETURN FILL TABLE ; FILTB: .BYTE 4. ;0-8. .BYTE 8. ;9.-16. .BYTE 6. ;17.-24. .BYTE 3. ;25.-32. .BYTE 0. ;33.-40. .BYTE 2. ;41.-48. .BYTE 4. ;49.-56. .BYTE 6. ;57.-64. .BYTE 8. ;65.-72. .BYTE 10. ;73.-80. .EVEN .SBTTL TERMINAL INITIATOR .IF DF T$$RPR!T$$BTW TTCHK: MOV R1,R3 ;SAVE START OF PACKET FOR $IOFIN .IF NDF T$$RPR BR 30$ ;SKIP AROUND CODE .ENDC .ENDC ; DF T$$RPR!T$$BTW .IF DF T$$RPR ;+ ; **-TTCHK-TERMINAL DRIVER SPECIAL PARAMETER CHECKING ; ; ENTRY HERE FROM DRQIO WHEN A QIO FOR THE TERMINAL DRIVER HAS BEEN ; CHECKED. A READ-WITH-PROMPT QIO HAS A SECOND BUFFER ; SPECIFICATION THAT NEEDS TO BE CHECKED IN THE CONTEXT OF THE ; ISSUING TASK. IF NECESSARY, DO THE CHECKS. ALWAYS QUEUE THE REQUEST. ; ; INPUTS: ; ; R1 -> I/O REQUEST PACKET ; R4 -> SCB ; R5 -> UCB ; ; OUTPUTS: ; ; THE PROMPT (WRITE) BUFFER IS ADDRESS CHECKED TO MAKE SURE IT ; LIES WITHIN THE ISSUING TASK. IF IT DOES, THE BUFFER ADDRESS ; IS RELOCATED AND STORED IN THE I/O PACKET, THE PACKET IS ; INSERTED IN THE CONTROLLER QUEUE, AND THE DEVICE INITIATOR ; IS ENTERED TO START THE CONTROLLER. ;- CMPB #IO.RPR/400,I.FCN+1(R1) ;QIO NEED SPECIAL CHECKING? .IF DF T$$BTW BNE 30$ ;IF NE NO .IFF  BNE 20$ ;IF NE NO -- JUST QUEUE IT .ENDC MOV I.PRM+10(R3),R0 ;GET VIRTUAL ADDRESS OF BUFFER .IF DF A$$CHK!M$$MGE MOV I.PRM+12(R3),R1 ;GET LENGTH OF BUFFER BEQ 8$ ;MUST PROMPT WITH AT LEAST 1 CHAR .IF DF T$$VBF CMP #255.,R1 ;PROMPT BIGGER THAN LARGEST BUFFER? .IFF CMP #80.,R1 ;PROMPT BIGGER THAN LARGEST BUFFER? .IFTF BHIS 7$ ;IF HIS NO MOV #IE.BAD&377,R0 ;RETURN BAD PARAMETER STATUS BR 9$ ; .ENDC 7$: CALL $ACHKB ;ADDRESS CHECK BUFFER BCC 10$ ;IF CC OKAY 8$: MOV #IE.SPC&377,R0 ;RETURN ILLEGAL BUFFER STATUS 9$: CLR R1 ;SET IOSB+2 TO ZERO CALLR $IOFIN ;FINISH I/O OPERATION 10$: ;REF LABEL .ENDC CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R1,I.PRM+10(R3) ;SET RELOCATION BIAS OF BUFFER MOV R3,R1 ;COPY I/O PACKET ADDRESS ADD #I.PRM+14,R3 ;POINT INTO I/O PACKET MOV (R3)+,(R3) ;SAVE VERTICAL FORMAT CONTROL CMP -(R3),-(R3) ;POINT AT PROMPT BUFFER SIZE MOV (R3)+,(R3) ;MOVE BUFFER SIZE TO SAFETY MOV R2,-(R3) ;SET ADDRESS OF BUFFER .ENDC ; DF T$$RPR .IF DF T$$RPR!T$$BTW 20$: MOV R4,R0 ;SET ADDRESS OF I/O QUEUE LISTHEAD CALL $QINSP ;INSERT I/O PACKET IN REQUEST QUEUE 23$: JMP TTINI ;GO TO WORK .ENDC .IF DF T$$BTW 30$: CMPB #IO.WLB/400,I.FCN+1(R1) ;A WRITE? BNE 20$ ;IF NE NO -- JUST QUEUE IT BITB #TF.WBT,I.FCN(R1) ;A BREAKTHROUGH WRITE? BEQ 20$ ;IF EQ NO -- JUST QUEUE IT .IF DF M$$MUP MOV I.TCB(R1),R2 ;GET TCB OF REQUESTING TASK BIT #T3.PRV!T3.CLI,T.ST3(R2) ;IS TASK PRIV. OR A CLI? ;TMM011 BEQ 35$ ;IF EQ NO ;**-1 .ENDC .IF DF D$$M11&D$$H11!D$$ZMD MOV #IE.DNR&377,R0 ;ASSUME WRITING TO DISABLED LINE BITB #US.DSB,U.STS(R5) ;IS LINE DISABLED? BNE 9$ ;IF NE YES -- REJECT PACKET .ENDC BISB #TF.CCO,I.FCN(R1) ;IO.WBT IMPLIES CANCEL CONTROL O .IF DF T$$HLD!T$$SYN BIC #UOFF,U.CNT+2+ATERS(R5) ;IGNORE ANY XOFF'S .ENDC MTPS S.PRI(R4) ;DISALLOW INTERRUPTS MOVB U.STS(R5),R2 ;;;SAVE STATUS OF US.ECH ;TMM008 BISB #US.ECH,U.STS(R5) ;;;DISALLOW INPUT (BUSYING OF UNIT) ;TMM008 .IIF NE US.BSY-200, .ERROR US.BSY ;TMM008 ;TMM008 ;;; UNIT BUSY? ;TMM008 BMI 40$ ;IF MI YES (RATS!) ;**-1 32$: ;REF LABEL MOV (R4),(R1) ;QUEUE THIS AS FIRST IN QUEUE BNE 3400$ ;IF NE ANOTHER PACKET IN QUEUE MOV R1,2(R4) ;MAKE "LAST" POINT AT THIS PACKET 3400$: MOV R1,(R4) ; MTPS #0 ;;;REDUCE PRIORITY BR 23$ ;HANDLE IT NORMALLY .IF DF M$$MUP 35$: MOV #IE.PRI&377,R0 ;IO.WBT ILLEGAL FROM UNPRIVILEGED TASK BR 9$ ; IN A MULTIUSER PROTECTION SYSTEM .ENDC 40$: TSTB @U.CNT+2+MEBUF(R5) ;;;DOING A MULTIECHO (GENERALLY ;;; A CONTROL/R)? BNE 42$ ;;;IF NE YES ;;; CHARACTER IN TRANSMITTER BUFFER ;**-2 BIT #SOLI!MODE,U.CNT+2+STATS(R5) ;;;SOLICITED INPUT OR ;;; OUTPUT IN PROGRESS? BNE 41$ ;IF NE YES MOV U.CNT+2+STRBF(R5),R0 ;POINT AT UNSOLICITED INPUT BUFFER BR 46$ ;PRESS ON 41$: MOV S.PKT(R4),R0 ;GET START OF PACKET THAT IS BEING ; PROCESSED BIT #RPRM!BTWP,U.CNT+2+ATERS(R5) ;;;BREAKING THROUGH OR ;;; PROMPTING? BEQ 43$ ;;;IF EQ NO 42$: MOV #IE.RSU&377,R0 ;;;UNSHARABLE RESOURCE IN USE (CANNOT ;;; IO.WBT WHILE DOING AN IO.WBT, ;;; PROMPT, OR MULTIECHO) BITB #US.ECH,R2 ;;; WAS US.ECH ALREADY SET ? ;TMM008 BNE 44$ ;;; IF NE YES, DO NOT CLEAR IT. ;TMM008 CALL INPT0 ;;;CLEAR US.ECH 44$: ;;; REF LABEL ;TMM008 MTPS #0 ;;;REDUCE PRIORITY .IF DF A$$CHK!M$$MGE&T$$RPR BR 9$ ; .IFF 9$: CLR R1 ;WANT IOSB+2 TO BE ZERO CALLR $IOFIN ;FINISH OFF I/O PACKET .ENDC 43$: CMPB #IO.RLB/400,I.FCN+1(R0) ;;;DOING A READ? BEQ 46$ ;;;IF EQ YES -- BREAKTHROUGH .IIF NE UPND-200, .ERROR UPND TSTB U.CNT+2+ATERS(R5) ;;;HAVE A HELD UP CHARACTER? BPL 32$ ;;;IF PL NO BIC #UPND,U.CNT+2+ATERS(R5) ;;;CLEAR PENDING FLAG MOV #45$,-(SP) ;;;WANT TO RETURN TO 45$ MOVB U.CNT+2+DHBUF(R5),-(SP) ;;;RETRIEVE HELD UP CHARACTER CALLR FCHAR ;;;FORCE IT OUT 45$: MOV U.SCB(R5),R4 ;;;RESTORE THE MESSED UP REGISTER BR 32$ ;;;DO THIS IO.WBT AS NEXT FUNCTION 46$: MOV R5,R3 ;POINT AT TERMINAL STATUS ADD #U.CNT+2+STATS,R3 ; BIT #EOLS,(R3) ;;;HAS THE READ "FINISHED"? BNE 32$ ;;;IF NE YES -- JUST QUEUE BREAKTHROUGH BIT #SOLI,(R3) ;SOLICITED INPUT GOING ON? BNE 48$ ;IF NE YES MOV (R3),-(R0) ;SAVE TERMINAL STATUS FOR UNSOL READ BIC #LFCT!CRTY!CRJT!CTLO!FLCT,(R0) ;;;MAKE SAVED STATUS ;;; SHOW INACTIVE ON OUTPUT CLR I.PRM+16(R1) ;SIGNAL UNSOLICITED READ BREAKTHROUGH SUB #U.CNT+2+STATS-U.BUF,R3 ;POINT AT U.BUF BR 50$ ; 48$: MOVB S.STS(R4),(R0) ;SAVE STATUS OF DISPLACED READ MOV R0,I.PRM+16(R1) ;SAVE POINTER TO DISPLACED PACKET ADD #I.PRM+14,R0 ;POINT NEAR END OF DISPLACED PACKET MOV (R3),(R0) ;SAVE STATS BIC #LFCT!CRTY!CRJT!CTLO!FLCT,(R0) ;;;MAKE SAVED STATS ;;; SHOW INACTIVE ON OUTPUT ; NEXT INSTUCTION DEPENDS ON STATS=U.CNT+2 MOV -(R3),-(R0) ;SAVE U.CNT MOV -(R3),-(R0) ;SAVE U.BUF+2 MOV -(R3),-(R0) ;SAVE U.BUF 50$: MOV I.PRM(R1),(R3)+ ;RESET U.BUF FOR IO.WBT MOV I.PRM+2(R1),(R3)+ ;RESET U.BUF+2 MOV I.PRM+4(R1),(R3)+ ;RESET U.CNT MOV R1,S.PKT(R4) ;MAKE IO.WBT THE CURRENT I/O PACKET BIC #CTLO!LFCT!CRTY!EOLS!RUBP!SOLI,(R3) ;;;RESET BIS #MODE,(R3) ;;; STATUS WORD FOR IO.WBT BIS #BTWP,ATERS(R3) ;FLAG IO.WBT ACTION JMP FWRITE ;DO THE WRITE .ENDC .ENABL LSB .IF DF T$$SMC ; ; R0 = IS.SUC&377 (PRESERVE IF AN ERROR IS NOT DETECTED) ; R1 = POINTER TO WORD PRECEDING GMCTAB THAT CORRESPONDS TO BUFFER'S ; CHARACTERISTIC SYMBOL (SCRATCH) ; -(R2) = BUFFER'S CHARACTERISTIC SYMBOL (SCRATCH) ; R3 = (SCRATCH) ; R4 = ADDRESS OF I/O PACKET (PRESERVE) ; R5 = UCB ADDRESS (PRESERVE) ; NOTHING ON THE STACK ; 1820$: MOV U.CW2(R5),-(SP) ;GET CHARACTERISTICS WORD ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 .IF DF D$$H11!D$$Z11 ;TMM035 ;TMM035 BPL 1852$ ;IF PL TERMINAL IS NOT ON A MULTIPLEXER ASL (SP) ;IS MULTIPLEXER A DJ11? ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 1852$ ;IF MI YES -- BAUD RATE NOT PROGRAMMABLE MOVB (R1)+,R3 ;GET DZ11 BAUD RATE MASK ;TMM035 ;TMM035 .IF DF D$$H11 ;TMM035 ;TMM035 TSTB (SP) ;IS MULTIPLEXER A DH11? ;TMM035 ;TMM035 .IF DF D$$Z11 ;TMM035 ;TMM035 BMI 1822$ ;IF MI NO ;TMM035 ;TMM035 .IFF ;TMM035 ;TMM035 BMI 1852$ ;IF MI NO NAD THERE'S NO DZ11 SUPPORT ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 COMB R3 ;CONVERT TO DH11 MASK ;TMM035 ;TMM035 .IFF ;TMM035 ;TMM035 .IF DF D$$Z11 ;TMM035 ;TMM035 TSTB (SP) ;IS MULTIPLEXER A DH11? ;TMM035 BPL 1852$ ;IF PL YES AND THERE'S NO DH11 SUPPORT ;TMM035 TSTB (SP)+ ;CLEANUP STCAK ;TMM035 ;TMM035 .ENDC ;D$$Z11 ;TMM035 ;TMM035 .ENDC ;D$$H11 ;TMM035 ;TMM035 1822$: CALL $GTBYT ;GET BUFFER'S BAUD RATE SYMBOL ;**-7 MOV #SPDTB,R0 ;POINT AT LEGAL SPEED TABLE 1824$: MOVB (R0)+,R2 ;GET BAUD RATE BITS ;TMM035 BNE 1826$ ;IF NE HAVE NOT FOUND END OF TABLE ;**-1 1825$: JMP 18772$ ; 1826$: CMPB (R0)+,(SP) ;ARE THE BAUD RATE BITS FOR THE ; BUFFER'S BAUD RATE SYMBOL? BNE 1824$ ;IF NE NO BIC R3,R2 ;THROW AWAY BITS FOR OTHER MULTIPLEXER ;TMM035 BEQ 1825$ ;IF EQ THIS MULTIPLEXER DOES NOT ;**-1 ; SUPPORT THIS BAUD RATE TST (SP)+ ;POP STACK ;TMM035 TSTB (R1) ;WORKING ON TC.RSP OR TC.RSP? ;TMM035 BGT 1829$ ;IF GT TC.TSP ;TMM035 ;TMM035 .IF DF D$$M11!D$$ZMD ;TMM035  ;TMM035 BEQ 1828$ ;IF EQ TC.RSP ;TMM035 INC R5 ;TC.ASP AFFECTS U.CW3+1 ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 1828$: BICB #<17>,U.CW3(R5) ;CLEAR A SPOT FOR ASP OR RSP ;TMM035 1829$: ;TMM035 ;TMM035 .IF DF D$$H11 ;TMM035 ;TMM035 TSTB (SP)+ ;IS MULTIPLEXER A DZ11? ;TMM035 BPL 1830$ ;IF PL IT'S A DH11 ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$Z11 ;TMM035  ;TMM035 SWAB R2 ;POSITION BAUD RATE BITS FOR DZ11 ;TMM035 ;TMM035 .IF DF D$$ZMD ;TMM035 ;TMM035 TSTB (R1) ;TC.ASP? ;TMM035 BMI 1832$ ;IF MI YES ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 CLRB U.CW3(R5) ;CLEAR OUT BOTH TSP AND RSP FIELDS FOR DZ11 ;TMM035 CALL SSSZSP ;SET BAUD RATE BITS INTO U.CW3 ;TMM035 ;TMM035 .IF DF D$$H11!D$$ZMD ;TMM035 ;TMM035 BR 1838$ ;GO TELL DZ11 ABOUT CHANGE ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$H11 ;TMM035 ;TMM035 1830$: CMP #<1*20>,R2 ;IS THIS THE DH11 SPECIAL CASE? ;TMM035 BNE 1831$ ;IF NE NO ;TMM035 CLR R2 ;CLEAR OUT BAUD RATE BITS FOR A "ZERO" BAUDRATE ;TMM035 1831$: TSTB (R1) ;IS THIS TC.RSP OR TC.ASP? ;TMM035 BLE 1833$ ;IF LE YES ;TMM035 BIC #<360>,U.CW3(R5);CLEAR OUT SPOT FOR TSP ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$H11!D$$ZMD ;TMM035 ;TMM035 1832$: BISB R2,U.CW3(R5) ;SET UP NEW ASP OR RSP ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$H11 ;TMM035 ;TMM035 BR 1834$ ;GO SET UP LPR IN DH ;TMM035 1833$: CALL SSSCW3 ;SHIFT,SWAB AND SET BAUDRATE IN R2 INTO U.CW3 ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$ZMD!D$$M11 ;TMM035 ;TMM035 1834$: BIC #1,R5 ;ADJUST R5 TO POINT TO UCB ;TMM035 ;TMM035 .IFF ;TMM035 ;TMM035 1834$: ;REF LABEL ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 1838$: MOV U.SCB(R5),R2 ;GET SCB ADDRESS ;TMM035 MOV S.CSR(R2),R2 ;GET CSR ADDRESS ;TMM035 MTPS #7 ;LOCK OUT INTERRUPTS ;TMM035 CALL SETLIN ;;;SET THE NEW BAUD RATE INTO THE CONTROLLER ;TMM035 MTPS #0 ;RETURN TO NORMAL PRIORITY ;TMM035 MOV #IS.SUC&377,R0 ;RESTORE SUCCESS STATUS ;TMM035 BR 1872$ ;DECODE NEXT BUFFER BYTE ;TMM035 ;TMM035 .IFF ;D$$H11!D$$Z11 ;TMM035 ;TMM035 BR 1852$ ;RETURN ERROR IF NO DZ OR DH SUPPORT ;TMM035 ;TMM035 .ENDC ;D$$H11!D$$Z11 ;TMM035 ;TMM035 .ENDC ;T$$SMC ;TMM035 ;TMM035 ;**-58 .IF DF T$$GMC!T$$SMC 1840$: TST (SP)+ ;DESTROY SAVED R3 SUB #2,U.CNT(R5) ;FINISHED DECIPHERING BUFFER? BLT 1846$ ;IF LT YES MOV #GMCTAB,R2 ;POINT AT RECOGNITION TABLE MOV R2,R1 ;COPY THE POINTER CALL $GTBYT ;GET BYTE TO DECIPHER 1842$: TST -(R1) ;TABLE OF CHARACTERISTICS EXHAUSTED? BEQ 1850$ ;IF EQ YES CMPB (R2)+,(SP) ;RECOGNIZE CHARACTERISTIC? BNE 1842$ ;IF NE NO SEC ;SET C-BIT TO SHOW TC. MATCH 1844$: RTS R3 ;RETURN AND CLEAR STACK 1846$: JMP 5$ ;RETURN WITH IOSB+2 = 0 1850$: CMPB #TC.TTP,(SP) ;WORRYING ABOUT TERMINAL TYPE? BEQ 1844$ ;IF EQ YES (C-BIT IS CLEAR) 1852$: MOV #SE.NIH*400!,R0 ;DID NOT RECOGNIZE BYTE 1854$: MOV S.PKT(R4),R3 ;POINT AT I/O PACKET MOV U.BUF+2(R5),R1 ;PICK UP WHERE WE STOPPED IN BUFFER ; (ASSUME BUFFER < 4096.-32. BYTES) SUB I.PRM+2(R3),R1 ;STOPPING POINT - START OF BUFFER DEC R1 ;ADJUST TST (SP)+ ;CLEAN UP STACK .IF DF T$$GTS BR 1868$ ;RETURN AN ERROR TO THE TASK .IFF JMP IODON ;RETURN AN ERROR TO THE TASK .ENDC .ENDC ; DF T$$GMC!T$$SMC 1860$: ;REF LABEL .IF DF T$$GMC!T$$SMC&A$$CHK!T$$GTS MOV U.CNT(R5),R3 ;COPY LENGTH OF BUFFER .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC&A$$CHK BIT #1,U.BUF+2(R5) ;BUFFER ON A BYTE BOUNDARY? BEQ 1861$ ;IF EQ NO ; EB251 19088$: MOV #IE.SPC&377,R0 ;ILLEGAL BUFFER ;TMM036 ;**-9 .IF DF T$$GMC!T$$SMC BR 1846$ ; .IFF JMP 5$ ; .ENDC 1861$: ;REF LABEL ; EB251 BIT #1,R3 ;BUFFER CONTAINS WORDS? ;**-4 1862$: BNE 19088$ ;IF NE NO ; EB251 CMP #4096.-32.,R3 ;BUFFER TOO LARGE ;**-1 BLT 19088$ ;IF LT YES -- MIGHT BLOW ERROR OFFSET ;TMM036 ; ON A MAPPED SYSTEM ;**-1 .ENDC ; DF T$$GMC!T$$GTS!T$$SMC&A$$CHK .IF DF T$$GTS CMPB #IO.GTS,I.FCN(R1) ;GET TERMINAL SUPPORT QIO? BNE 1870$ ;IF NE NO CMP #TCHR1E-TCHR1,R3 ;WANTS MORE THAN WE DELIVER? BGE 1863$ ;IF GE NO MOV #TCHR1E-TCHR1,R3 ;CHANGE TO OUR MAXIMUM 1863$: MOV #TCHR1,R2 ;POINT AT SUPPORT INFO WORDS CLR R1 ;CLEAR COUNTER OF MOVED BYTES 1864$: MOVB (R2)+,-(SP) ;PUT THE 1ST BYTE OF THE 1ST CALL $PTBYT ; SUPPORT WORD INTO THE TASK'S BUFFER INC R1 ;COUNT A BYTE MOVED CMP R1,R3 ;TASK WANTS MORE? BLT 1864$ ;IF LT YES 1868$: JMP IODON ;RETURN STATUS 1870$: ;REF LABEL .ENDC .IF DF T$$SMC CMPB #SF.SMC,I.FCN(R1) ;SET MULTIPLE CHARACTERISTICS? BNE 1880$ ;IF NE NO .IF DF M$$MUP MOV I.TCB(R1),R3 ;POINT AT TCB OF REQUESTING TASK CMP T.UCB(R3),R5 ;IS TASK'S TI: THIS TERMINAL? BEQ 1872$ ;IF EQ YES -- ALMOST ANYTHING IS LEGAL BIT #T3.PRV,T.ST3(R3) ;IS THE TASK PRIVILEGED BNE 1872$ ;IF NE YES -- ALMOST ANYTHING IS LEGAL MOV #IE.PRI&377,R0 ;PRIVILEGE VIOLATION BR 1846$ ; .ENDC 1872$: JSR R3,1840$ ;DECIPHER MEANING OF THEIR ; CHARACTERISTICS BYTE BCC 1876$ ;IF CC WORRY ABOUT TERMINAL TYPE CMP #ENDCW2,R2 ;U.CW2 CHARACTERISTIC OR SPEED? BHIS 18722$ ;IF HIS U.CW2 CHARACTERISTIC JMP 1820$ ; 18722$: CALL $GTBYT ;GET DESIRED VALUE FOR CHARACTERISTIC CMP #U2.PRV,(R1) ;TASK TRYING TO CHANGE PRIVILEGE STATUS? BEQ 1852$ ;IF EQ YES -- DO NOT ALLOW THAT BITB #376,(SP) ;VALUE IS 1 OR 0? BEQ 1873$ ;IF EQ YES MOV #SE.BIN*400!,R0 ;IT SHOULD HAVE BEEN BR 1854$ ; 1873$: BIC (R1),U.CW2(R5) ;ASSUME THE VALUE IS ZERO 1874$: TSTB (SP)+ ;IS THE VALUE ZERO? BEQ 1872$ ;IF EQ YES 1875$: BIS (R1),U.CW2(R5) ;SET THE APPROPRIATE BIT BR 1872$ ;TRY TO DECIPHER THEIR NEXT BYTE 1876$: CALL $GTBYT ;GET DESIRED TERMINAL TYPE VALUE 1877$: TST -(R1) ;EXHAUSTED LIST OF RECOGNIZIBLE VALUES? BNE 1878$ ;IF NE NO CMPB #T.UNK0,(SP) ;SET TERMINAL TO UNKNOWN TYPE? BEQ 1879$ ;IF EQ YES CMP #T.AS33,(SP) ;SET TERMINAL TO ASR33 (UPCASE OUTPUT?) ;TMM036 BNE 18772$ ;IF NE NO ;TMM036 BIS #U3.UPC,U.CW3(R5) ;SET CHARACTERISTIC ;TMM036 BIC #U2.VT5!U2.L3S,U.CW2(R5) ;IGNORE OLD TERMINAL TYPE ;TMM036 TST (SP)+ ;CLEAN STACK ;TMM036 BR 1872$ ;TRY TO DECIPHER NEXT BYTE ;TMM036 18772$: MOV #SE.VAL*400!,R0 ;SHOW INAPPROPRIATE VALUE BR 1854$ ; 1878$: CMPB (R2)+,(SP) ;RECOGNIZE THE TERMINAL TYPE VALUE? BNE 1877$ ;IF NE NO 1879$: BIC #U2.VT5!U2.L3S,U.CW2(R5) ;IGNORE OLD TERMINAL TYPE BIC #U3.UPC,U.CW3(R5) ;RESET ASR33 TERMINAL TYPE ;TMM036 BR 1874$ ;SET THEIR TYPE [(SP) IS GENERALLY NONZERO] 1880$: ;REF LABEL .ENDC .IF DF T$$GMC CMPB #SF.GMC,I.FCN(R1) ;GET MULTIPLE CHARACTERISTICS? BNE 1888$ ;IF NE NO 1882$: JSR R3,1840$ ;FIND OUT WHAT CHARACTERISTIC THEY ; ARE INQUIRING ABOUT BCC 1884$ ;IF CC WANT TO KNOW THE TERMINAL TYPE CLR -(SP) ;ASSUME CHARACTERISTIC NOT ASSERTED .IF DF T$$SMC CMP #ENDCW2,R2 ;GETTING U.CW2 CHARACTERISTIC? BHIS 18822$ ;IF HIS YES ;TMM036  JMP 1852$ ;IF LO -- CANNOT GET SPEEDS ;TMM036 18822$: ;TMM036 ;**-1 .ENDC BIT (R1),U.CW2(R5) ;CHARACTERISTIC ASSERTED? BEQ 1883$ ;IF EQ NO INC (SP) ;REMEMBER ITS BEING ASSERTED 1883$: CALL $PTBYT ;PUT VALUE INTO TASK'S BUFFER BR 1882$ ;TRY AGAIN 1884$: MOVB #T.UNK0,-(SP) ;ASSUME UNKNOWN TERMINAL TYPE 1885$: TSTB (R2)+ ;TERMINAL TYPE TABLE EXHAUSTED? BEQ 1886$ ;IF EQ YES ;TMM036 BIT -(R1),U.CW2(R5) ;IS THIS TERMINAL THIS TYPE? ;**-1 BEQ 1885$ ;IF EQ NO MOVB -(R2),(SP) ;PICK UP THE TERMINAL TYPE BR 1883$ ;RETURN IT TO THE TASK 1886$: BIT #U3.UPC,U.CW3(R5) ;COULD THIS TERMINAL BE AN ASR33? ;TMM036 BEQ 1883$ ;IF EQ NO ;TMM036 MOVB #T.AS33,(SP) ;GET ASR33 TERMINAL TYPE ;TMM036 BR 1883$ ;RETURN TYPE TO TASK ;TMM036 1888$: ;REF LABEL .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC MOV #IE.IFC&377,R0 ;NO OTHER SUBFUNCTIONS ARE SUPPORTED BR 304$ ; 1889$: JMP 1860$ ; ;TMM036 ;**-1 .ENDC .IF DF T$$CCA&A$$TRP  ; ; SET UP FOR UNSOLICITED CHARACTER AST ; 1900$: MOV I.PRM(R1),CCAST(R3) ;SAVE AST ENTRY POINT ADDRESS BEQ 1907$ ;IF EQ BAD ADDRESS ; EB251 BIT #1,CCAST(R3) ;IS ADDRESS ODD? ;**-1 BNE 1907$ ;IF NE YES ; EB251 BIS #CCON,ATERS(R3) ;ARM UNSOLICITED CHAR AST CODE ;**-1 BR 1910$ ; 1907$: CLR U.ATT(R5) ;SHOW NOT ATTACHED ; EB251 1908$: MOV #IE.SPC&377,R0 ;THERE'S NO POINT IF NO 1910$: BR 304$ ; AST ADDRESS .ENDC .IF DF T$$RPR ; ; START ANALYSIS OF READ AFTER PROMPT QIO FOR SUBFUNCTIONS ; 1920$: MOV #RPRM,-(SP) ;COPY BIT PATTERN FOR ATERS BITB #TF.XOF,I.FCN(R1) ;XOFF TERMINATION SUBFUNCTION? BEQ 1922$ ;IF EQ NO BIS #XOFF,(SP) ;REMEMBER NEED FOR XOFF 1922$: BIS (SP)+,ATERS(R3) ;SET STATUS FOR LATER REFERENCE CMP I.PRM+14(R1),U.CNT(R5) ;PROMPT BUFFER LONGER THAN READ? BLE 1924$ ;IF LE NO MOV I.PRM+14(R1),U.CNT(R5) ;WANT TO ALLOCATE EXECUTIVE 1924$: BR 305$ ; BUFFER THAT IS BIG ENOUGH FOR EITHER .ENDC ;+ ; **-TTINI-TERMINAL INTITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER (UNIT) TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ; ; SEE THE I/O DRIVERS REFERENCE MANUAL FOR A DETAILED DESCRIPTION ; OF WHAT THIS DRIVER SUPPORTS. IN BRIEF: ; ; A$$CHK = ADDRESS CHECKING (GOES WITH T$$RPR, T$$GMC, T$$SMC, T$$GTS) ; A$$TRP = AST SUPPORT IN SYSTEM (GOES WITH T$$CCA) ; C$$CKP = CHECKPOINT SUPPORT IN SYSTEM (GOES WITH T$$BUF) ; D$$H11 = DH11 MULTIPLEXERS ; D$$J11 = DJ11 MULTIPLEXERS ; D$$L11 = DL11/A/B/C/D ; D$$M11 = DM11-BB MODEM CONTROLLER FOR DH11 ; D$$YNC = DYNAMIC CHECKPOINTING (GOES WITH C$$CKP AND T$$BUF) ; D$$YNM = DYNAMIC MEMORY MANAGEMENT IN SYSTEM (GOES WITH M$$MGE, ; C$$CKP, AND T$$BUF) ; D$$ZMD = BELL 103A MODEM CONTROL FOR DZ11 LINES ; D$$Z11 = DZ11 MULTIPLEXER ; I$$RAR = REMOVE AFTER RUNNING (GOES WITH I$$RDN AND M$$MGE) ; I$$RDN = I/O RUNDOWN (GOES WITH I$$RAR AND M$$MGE) ; LD$$H, LD$$J, LD$$L, LD$$Z = VARIOUS FLAVORS OF LOADABLE USER DRIVERS ; (NOT SUPPORTED) ; LD$TT = DEFINED IF TERMINAL DRIVER IS LOADABLE ; L$$DRV = DEFINED IF LOADABLE TERMINAL DRIVER SUPPORT IN SYSTEM ; L$$SI1 = LSI-11 SUPPORT. EFFECTS MTPS MACRO. ; (DH11, DJ11, DM11, AND DZ11 ARE NOT COMPATIBLE WITH Q-BUS) ; L$$50H = FIFTY HERTZ VT05 SUPPORT ; M$$MGE = MEMORY MANAGEMENT SUPPORT ; M$$MUP = AUTOMATIC "BYE" ON DM11 AND DZ11 HANGUPS AND PRIVILEGE CHECKS ; P$$LAS = MEMORY MANAGEMENT DIRECTIVES ; R$$LKL = RMS-11 LOCKING ; R$$11S = IGNORE UNSOLICITED INPUT ON RSX-11S SYSTEMS THAT HAVE ; NO BASIC MCR ; T$$ACR = AUTOMATIC CR/LF FOR LINES THAT ARE BIGGER THAN TERMINAL ; BUFFER SIZE (U.CW4) ; T$$BTW = BREAKTHROUGH WRITE ; T$$BUF = CHECKPOINTING DURING TERMINAL INPUT (GOES WITH C$$CKP) ; T$$CCA = UNSOLICITED CHARACTER AST'S (GOES WITH A$$TRP) ; T$$CCO = CLEAR CONTROL O INHIBIT BEFORE DOING WRITE ; T$$CTR = CONTROL R DISPLAYS THE INTERPRETED INCOMPLETE INPUT BUFFER ; T$$ESC = RECOGNITION OF ESCAPE SEQUENCES FOR SOLICITED READS ; T$$GMC = GET MULTIPLE TERMINAL CHARACTERISTICS ; T$$GTS = GET TERMINAL DRIVER SUPPORT MASKS ; T$$HFF = FORM FEEDS ARE PASSED THROUGH ON OUTPUT ; T$$HLD = HOLD-SCREEN MODE SUPPORT (ALMOST T$$SYN SUPPORT) AND ; CONTROL C KNOCKS TERMINAL OUT OF IT. INTERACTS WITH MCR. ; T$$LWC = LOWER CASE TO UPPER CASE MAPPING ON INPUT AND RECOGNITION ; OF 175 AND 176 AS ASCII CHARACTERS ; T$$MIN = DEFINED IN THE MINIMUM TERMINAL DRIVER AND THE MINIMUM ; MULTIUSER DRIVER (ALONG WITH T$$BTW, T$$RNE, T$$RST) ; T$$RNE = READ WITH NO ECHO ; T$$RPR = READ AFTER PROMPT ; T$$RST = READ WITH SPECIAL TERMINATORS ; T$$RUB = RUBOUTS ERASE PRINTING CHARACTERS AND TABS ON CRT'S ; T$$SMC = SET MULTIPLE TERMINAL CHARACTERISTICS ; T$$SYN = CTRL S AND Q SUPPORT. CTRL C CLEARS EFFECT OF CTRL S. ; T$$TRW = TRANSPARENT READS AND WRITES ; T$$UTB = WHEN POSSIBLE, RECEIVED CHARACTERS ARE PUT DIRECTLY INTO THE ; TASK'S BUFFER ; T$$VBF = VARIABLE LENGTH BUFFERS (FROM 1 BYTE TO 255.) ARE USED BY THE ; DRIVER ; T$$30P = ONE CHARACTER SOFTWARE BUFFERING OF RECEIVED CHARACTERS ; (NEEDED ONLY BY LA30P'S BECAUSE THEIR INTERFACES ARE NOT ; HARDWARE DOUBLE BUFFERED). ;- .IIF NE UIFP-200, .ERROR UIFP 1$: TSTB U.CNT+2+STATS(R5) ;UNSOLICITED INPUT FORK PENDING? BMI 2$ ;IF MI YES -- WAIT FOR FORK MOV U.SCB(R5),R4 ;POINT TO SCB CALLR TINP1 ;START UNSOLICITED READ ; NEXT INSTRUCTION DEPENDS ON US.BSY=200 TTINI: TSTB U.STS(R5) ;UNIT BUSY? 2$: BMI 900$ ;IF MI YES BISB #US.ECH,U.STS(R5) ;IGNORE INPUT CHARACTERS TSTB U.CNT+2+INPRQ(R5) ;UNSOLICITED INPUT REQUEST? BNE 1$ ;IF NE YES CALL $GTPKT ;GET AN I/O PACKET .IF DF T$$MIN BCS 28$ ;IF CS CONTROLLER BUSY OR NO REQUEST ;SO CLEAR ECHO-IN-PROGRESS AND EXIT .IFF BCS 9$ ;IF CS CONTROLLER BUSY OR NO REQUEST ; SO CLEAR ECHO-IN-PROGRESS AND EXIT .ENDC ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER (UNIT) TO BE INITIATED. ; ; TERMINAL I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRUTAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- CARRIAGE CONTROL BYTE. ; WD. 16 -- RELOCATION BIAS OF PROMPT. ; WD. 17 -- BUFFER ADDRESS OF PROMPT. ; WD. 20 -- NUMBER OF BYTES IN PROMPT. ; WD. 21 -- CARRIAGE CONTROL BYTE FOR PROMPT. ; MOV R5,R3 ;CALCULATE ADDRESS OF ADD #U.CNT+2+STATS,R3 ;STATUS WORD .IF DF D$$M11&D$$H11!D$$ZMD MOV #IE.DNR&377,R0 ;ASSUME TERMINAL DISABLED BITB #US.DSB,U.STS(R5) ;UNIT DISABLED? .IF DF T$$CCA&A$$TRP!T$$ESC BEQ 3$ ;IF EQ NO CMPB #IO.DET/400,I.FCN+1(R1) ;DETACH FUNCTION? BNE 5$ ;IF NE NO MOV #IS.SUC&377,R0 ;THE DETACH WILL SUCCEED BR 301$ ; .IFF BNE 5$ ;IF NE YES .ENDC .ENDC 3$: CMPB #IO.WLB/400,I.FCN+1(R1) ;WRITE LOGICAL BLOCK FUNCTION? .IF DF T$$MIN BEQ 30$ ;IF EQ YES .IFF BEQ 8$ ;IF EQ YES .ENDC BIC #CTLO,(R3) ;ENABLE OUTPUT MOV #IS.SUC&377,R0 ;ASSUME A HAPPY ENDING .IF DF T$$CCA&A$$TRP&T$$ESC CMPB #IO.ATT/400,I.FCN+1(R1) ;ATTACH FUNCTION? BNE 300$ ;IF NE NO BITB #TF.ESQ,I.FCN(R1) ;WANT ESCAPE SEQUENCE SUBFUNCTION? BEQ 3000$ ;IF EQ NO BIS #WESC,ATERS(R3) ;SHOW WANT ESCAPE SEQUENCES 3000$: BITB #TF.AST,I.FCN(R1) ;WANT UNSOLICITED CHAR AST'S? BNE 1900$ ;IF NE YES .IFF .IF DF T$$CCA&A$$TRP CMP #IO.ATT!TF.AST,I.FCN(R1) ;UNSOLICITED INPUT AST ATTACH? BEQ 1900$ ;IF EQ YES .ENDC .IF DF T$$ESC CMP #IO.ATT!TF.ESQ,I.FCN(R1) ;ATTACH WITH ESCAPE SEQUENCES? BNE 300$ ;IF NE NO BIS #WESC,ATERS(R3) ;REMEMBER THAT THEY ARE WANTED .ENDC .ENDC ; DF T$$CCA&A$$TRP&T$$ESC 300$: ;REF LABEL .IF DF T$$RPR CMPB #IO.RPR/400,I.FCN+1(R1) ;READ AFTER PROMPT? BEQ 1920$ ;IF EQ YES .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC CMPB #IO.GTS/400,I.FCN+1(R1) ;SET/GET CHARACTERISTICS? BEQ 1889$ ;IF EQ YES .ENDC .IF DF T$$CCA&A$$TRP!T$$ESC CMPB #IO.DET/400,I.FCN+1(R1) ;DETACH? BNE 302$ ;IF NE NO 301$: BIC #CCON!WESC,ATERS(R3) ;SHOW NO CONTROL C AST ACTION ; AND NO DESIRE FOR ESCAPE SEQUENCES BR 5$ ;LEAVE SUCCESSFUL 302$: ;REF LABEL .ENDC CMPB #IO.RLB/400,I.FCN+1(R1) ;READ LOGICAL BLOCK FUNCTION? 304$: BNE 5$ ;IF NE NO 305$: ;REF LABEL .IF DF T$$TRW BITB #TF.RAL,I.FCN(R1) ;READ ALL?  BEQ 306$ ;IF EQ NO BISB #SS.RAL,S.STS(R4) ;REMEMBER READING ALL 306$: ;REF LABEL .ENDC .IF DF T$$RST BITB #TF.RST,I.FCN(R1) ;READ WITH SPECIAL TERMINATORS? BEQ 4$ ;IF EQ NO BISB #SS.RST,S.STS(R4) ;SET SPECIAL TERMINATOR FLAG 4$: ;REF LABEL .ENDC .IF DF T$$RNE BIT #U2.NEC,U.CW2(R5) ;TERMINAL IN NO ECHO MODE? BNE 400$ ;IF NE YES BITB #TF.RNE,I.FCN(R1) ;THIS READ WITH NO ECHO? BEQ 401$ ;IF EQ NO 400$: BISB #SS.RNE,S.STS(R4) ;REMEMBER READING WITH NO ECHO 401$: ;REF LABEL .ENDC ;**-1 .IF DF DFCKP ;TMM011 ;**-1 ;TMM011 .IF DF T$$RPR ;TMM011 ;TMM011 TST ATERS(R3) ;READ AFTER PROMPT ;TMM011 BPL 402$ ;IF PL NO ;TMM011 MOV I.PRM+16(R1),-(SP) ;SAVE PROMPT VFC ;TMM011 402$: ;TMM011 .ENDC ;T$$RPR ;TMM011 ;TMM011 MOV R1,R3 ;COPY ADDRESS OF START OF I/O PACKET ;TMM011 CALL $TSTBF ;CAN I/O BUFFERING BE INITIATED? ;TMM011 BCC 403$ ;IF CC YES ;TMM011 BIS #NCKP,ATERS+U.CNT+2(R5) ;REMEMBER AS NONCHECKPOINTABLE ;TMM011 ;**-5 .ENDC ;DF DFCKP ;TMM011 ;TMM011 .IF DF T$$UTB ;TMM011 ;TMM011 MOV U.BUF+2(R5),R0 ;MAKE INPINI SET UCB TO POINT ;**-2 CALL INPINI ; AT TASK'S BUFFER BR 10$ ; .ENDC ; DF T$$UTB ; ; REQUEST IS A SOLICITED INPUT REQUEST-GET A BUFFER FOR INPUT ; 403$: ;REF LABEL .IF NDF T$$UTB!NOEXBF .IF DF T$$VBF MOV U.CNT(R5),R1 ;GET HOW MUCH HE WANTS ALLOCATED ADD #M$$CRB-M$$CRI,R1 ;EXEC BUFFER IS A BIT LONGER CALL GETBF2 ;ALLOCATE EXEC BUFFER .IFF CALL GETBF ;GET BUFFER FOR INPUT .ENDC BCC 10$ ;IF CC BUFFER ALLOCATED MOV #IE.NOD&377,R0 ;SET NO BUFFER AVAILABLE STATUS .IF DF T$$UTB!T$$RPR BIC #NCKP!RPRM!XOFF,ATERS(R3) ;CLEAR POSSIBLY SET BITS .ENDC .ENDC ; NDF T$$UTB!NOEXBF 5$: CALL $IOALT ;FINISH I/O OPERATION BTTINI: BR TTINI ;TRY AGAIN .IF NDF T$$MIN 8$: BR 30$ ;STRETCH THE BRANCH A BIT 9$: BR 28$ ; AND SAVE A WORD .ENDC 900$: RETURN ; 10$: BIS #SOLI,(R3) ;SET SOLICITED INPUT FLAG .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;READ AFTER PROMPT? .IF DF D$$YNM&M$$MGE BMI 29$ ;IF MI YES .IFF BMI 70$ ;IF MI YES .ENDC .ENDC BIT #CRJT,(R3) ;CARRIAGE RETURN JUST TYPED? .IF DF C$$CKP&T$$BUF ; ; TRY TO CHECKPOINT THE TASK WHILE IT IS WAITING FOR INPUT ; CALL 27$ ;OUTPUT LF OR CLEAR ECHO-IN-PROGRESS MOV U.SCB(R5),R4 ;RETRIEVE ADDRESS OF SCB BIT #NCKP,ATERS+U.CNT+2(R5) ;BUFFERABLE? ;TMM011 BNE 900$ ;IF NE NO ;TMM011 MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET ;TMM011 CALLR $INIBF ;INITIATE I/O BUFFERING ;TMM011 ; AND $NXTSK ;**-55 .ENDC ; DF C$$CKP&T$$BUF 27$: BNE 55$ ;IF NE OUTPUT LINE FEED AND RETURN 28$: ;REF LABEL .IF DF T$$MIN .IF DF T$$BTW CALLR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .IFF BR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .ENDC .IFF  CALLR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .ENDC ; DF T$$MIN .IF DF D$$YNM&M$$MGE&T$$RPR 29$: BR 70$ ; .ENDC ; ; REQUEST IS AN OUTPUT REQUEST-SET UP CARRIAGE CONTROL FLAGS ; 30$: BIC #LFCT!CRTY!EOLS!RUBP!SOLI!FLCT,(R3) ;CLEAR STATUS WORD BIS #MODE,(R3) ;SET OUTPUT MODE .IF DF T$$BTW BITB #TF.WBT,I.FCN(R1) ;IS THIS A BREAKTHROUGH WRITE? BNE FWRITE ;IF NE YES (LEAVE US.ECH SET TO ; DISALLOW CONTROL O DURING THE WRITE) .ENDC CALL INPT0 ;ALLOW INPUT INTERRUPTS FWRITE: ;REF LABEL .IF DF T$$CCO!T$$BTW BITB #TF.CCO,I.FCN(R1) ;TASK WANTS TO CLEAR CONTROL O FLAG? BNE 33$ ;IF NE YES .ENDC TST U.ATT(R5) ;TERMINAL ATTACHED? BNE 34$ ;IF NE YES 33$: BIC #CTLO,(R3) ;STOP SUPPRESSING OUTPUT 34$: ;REF LABEL .IF DF T$$TRW BITB #TF.WAL,I.FCN(R1) ;WRITE ALL? BEQ 36$ ;IF EQ NO .IFF BR 36$ ;PROCESS CARRIAGE CONTROL .ENDC .IF DF T$$RPR!T$$TRW 35$: BISB #SS.WAL,S.STS(R4) ;REMEMBER WRITING ALL BIC #CRJT,(R3) ;CLEAR CR JUST TYPED INDICATOR CLRB HORPS(R3) ;CLEAR HORIZANTAL POSITION INDICATOR BR 60$ ;SKIP CARRIAGE CONTROL BYTE PROCESSING .ENDC 36$: MOVB I.PRM+6(R1),R0 ;GET CARRIAGE CONTROL BYTE 37$: BEQ 60$ ;IF EQ NO CARRIAGE CONTROL CMPB #'$,R0 ;CARRIAGE RETURN AT END OF LINE? BEQ 40$ ;IF EQ NO BIS #CRTY,(R3) ;SET FOR CARRIAGE RETURN AT END 40$: CMPB #'+,R0 ;LINE FEED AT START OF LINE? BEQ 60$ ;IF EQ NO CMPB #'1,R0 ;FORM FEED AT BEGINNING OF LINE? BNE 50$ ;IF NE NO .IF DF T$$HFF  BIT #U2.HFF,U.CW2(R5) ;TERMINAL CAN HANDLE FORM FEED? BEQ 48$ ;IF EQ NO .IIF NE FLBT-1, .ERROR FLBT INC (R3) ;WANT ONE FILL CHARACTER MOVB #14,FLBYT(R3) ;IT IS TO BE A FORM FEED BR 60$ ; .ENDC 48$: ADD #LFBT*7,(R3) ;ADD IN SEVEN LINE FEEDS 50$: ADD #LFBT,(R3) ;ADD IN ONE LINE FEED CMPB #'0,R0 ;DOUBLE SPACE? BNE 60$ ;IF NE NO 55$: ADD #LFBT,(R3) ;ADD IN ONE LINE FEED 60$: MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS CALLR OUTPT1 ;;;START OUTPUT .IF DF T$$RPR ;  ; IF NECESSARY, COPY THE PROMPT TO AN EXECUTIVE BUFFER SO THE ; TASK CAN BE CHECKPOINTED FOR BOTH THE PROMPT WRITE AND THE ; FOLLOWING READ. ; 70$: BIC #CTLO,(R3) ;CLEAR CONTROL O FLAG MOV S.PKT(R4),R1 ;FIND START OF I/O PACKET ADD #I.PRM+4,R1 ;POINT AT READ BUFFER LENGTH CMP (R1),U.CNT(R5) ;READ LARGER THAN OUR BUFFER? BHIS 72$ ;IS HIS UCB PROPERLY SETUP FOR READ MOV (R1),U.CNT(R5) ;RESTORE COUNT OF CHARS TO BE READ MOVB (R1),RMBYT(R3) ;CORRECT COUNT OF BYTES LEFT IN READ BUF 72$: CMP (R1)+,(R1)+ ;POINT AT 1ST WORD OF ADDR DOUBLE WORD .IF DF C$$CKP&T$$BUF ;**-1 .IFF MOV I.PRM+16-I.PRM-10(R1),R0 ;PUT PROMPT WHERE IT'S EXPECTED ;**-7 .IFT BIT #NCKP,ATERS(R3) ;CHECKPOINTABLE? ;TMM011 BNE 78$ ;IF NE NO ;**-3 .IF DF M$$MGE MOV (R1)+,@#KISAR6 ;MAP TO PROMPT (WRITE) BUFFER .IFF TST (R1)+ ;POINT AT PROMPT BUFFER ADDRESS .ENDC MOV STRBF(R3),R2 ;POINT AT EXEC READ BUFFER MOV (R1),R0 ;POINT AT PROMPT BUFFER MOV R2,(R1)+ ;PUT EXEC BUFFER ADDRESS IN I/O PACKET MOV (R1),-(SP) ;SAVE LENGTH OF PROMPT 75$: MOVB (R0)+,(R2)+ ;COPY PROMPT TO EXEC BUFFER DEC (SP) ;DONE? BGT 75$ ;IF GT NO MOV R3,(SP) ;SAVE R3 MOV S.PKT(R4),R3 ;GET I/O PACKET ADDRESS ;TMM011 CALL $INIBF ;INITIATE BUFFERING ;TMM011 MOV (SP)+,R3 ;RESTORE R3 ;**-4 78$: MOV (SP)+,R0 ;RETRIEVE PROMPT VFC .ENDC ; DF C$$CKP&T$$BUF MOV S.PKT(R4),R1 ;POINT AT I/O PACKET BITB #TF.BIN,I.FCN(R1) ;WRITE ALL PROMPT? BNE 35$ ;IF NE YES MOV R0,R0 ;SET CONDITION BITS BR 37$ ;INTERPRET PROMPT VFC .ENDC ; DF T$$RPR .DSABL LSB .SBTTL OUTPUT-NEXT-BYTE ROUTINE .ENABL LSB .IF DF T$$RPR ; ; WRITE OUT THE PROMPT OF AN IO.RPR ; 57$: MOV S.PKT(R4),R4 ;;;FIND START OF I/O PACKET BIT #CTLO,(R3) ;;;CONTROL/O IN MIDDLE OF PROMPT? BNE 5704$ ;;;IF NE YES DEC I.PRM+14(R4) ;;;DONE PROMPTING? BMI 5702$ ;;;IF MI YES .IF DF M$$MGE MOV @#KISAR6,-(SP) ;;;SAVE EXECUTIVE MAPPING MOV I.PRM+10(R4),@#KISAR6 ;;;MAP TO PROMPT BUFFER MOVB @I.PRM+12(R4),-(SP) ;;;GET NEXT BYTE OF PROMPT .IFF MOVB @I.PRM+12(R4),-(SP) ;;;GET NEXT BYTE OF PROMPT .IFTF INC I.PRM+12(R4) ;;;POINT AT ITS SUCCESSOR .IFT MOV 2(SP),@#KISAR6 ;;;RESTORE EXECUTIVE MAPPING MOV (SP)+,(SP) ;;;LEAVE PROMPT BYTE ON STACK .ENDC ;;; DF M$$MGE MOV U.SCB(R5),R4 ;;;RESTORE R4 CALL INPT0 ;;;ALLOW CONTROL Q, S, AND O INPUT ;;; (REDUNDANT AFTER FIRST CLEARING) BR 5703$ ;;;TRANSMIT THE PROMPT CHARACTER 5702$: BIT #CRTY,(R3) ;;;CARRIAGE RETURN AFTER PROMPT? BEQ 5704$ ;;;IF EQ NO MOV U.SCB(R5),R4 ;;;RESTORE POINTER TO SCB MOV #15,-(SP) ;;;TRANSMIT A CARRIAGE RETURN BIC #CRTY,(R3) ;;;CLEAR WANT CARRIAGE RETURN FLAG .IF DF T$$BTW&T$$30P 5703$: JMP ECHOB ;;; .IFF 5703$: BR BECHOB ;;; .ENDC 5704$: BIC #RPRM,ATERS(R3) ;;;CLEAR PROMPTING FLAG MOVB #IO.RLB/400,I.FCN+1(R4) ;;;CONVERT IO.RPR TO IO.RLB MOV U.SCB(R5),R4 ;;;RESTORE POINTER TO SCB RETURN ;;; .IF DF T$$BTW 5705$: BR 57$ ;;; .ENDC .ENDC ;;; DF T$$RPR .IF DF T$$30P ; ; TRANSMITTER NOT BUSY ECHOING, SO PROCESS CHARACTER THAT WAS ; RECEIVED (AND BUFFERED IN SOFTWARE), BUT NOT ECHOED. ; 5708$: BIC #CHAR,ATERS(R3) ;;;CLEAR FLAG CLR -(SP) ;;;CLEAR UPPER BYTE OF STACK MOVB MBUFR(R3),(SP) ;;;RETRIEVE INPUT CHARACTER JMP RESUME ;;;PROCESS THE CHARACTER .ENDC .IF DF T$$BTW ; ; RESTORE THE SCB AND UCB ENVIRONMENT FOR AN UNSOLICITED READ ; DISPLACED BY AN IO.WBT ; 5710$: MOVB #1,S.STS(R4) ;LINE WAS ONLY BUSY CLR (R3)+ ;CLEAR U.BUF (BUFFER IS IN EXEC SPACE) MOV U.CNT+2+CURBF(R5),(R3)+ ;RESTORE U.BUF+2 ; NEXT INSTRUCTION DEPENDS ON STRBF=U.CNT+4 CMP (R3)+,(R3)+ ;POINT AT STRBF MOV (R3),-(SP) ;FORM POINTER TO SAVED STATS SUB #1*2,(SP) ; MOV @(SP)+,-(R3) ;RESTORE STATS BR 5800$ ;FINISH WITH A FLOURISH ; ; RESTORE THE SCB AND UCB ENVIRONMENT OF THE READ DISPLACED ; BY AN IO.WBT ; 58$: MOV U.SCB(R5),R4 ;RESTORE R4 BISB #US.BSY,U.STS(R5) ;REBUSY LINE BIC #BTWP,U.CNT+2+ATERS(R5) ;CLEAR BREAKTHROUGH FLAG MOV R5,R3 ;POINT AT U.BUF ADD #U.BUF,R3 ; MOV U.CNT+2+STATS(R5),R1 ;RETRIEVE READ'S I/O PACKET POINTER BEQ 5710$ ;IF EQ BROKE THROUGH UNSOLICITED READ MOVB (R1),S.STS(R4) ;RESTORE SCB STATUS MOV R1,S.PKT(R4) ;MAKE THE READ THE CURRENT OPERATION ADD #I.PRM+6,R1 ;POINT AT THE READ'S SAVED UCB INFO MOV (R1)+,(R3)+ ;RESTORE U.BUF MOV (R1)+,(R3)+ ;RESTORE U.BUF+2 MOV (R1)+,(R3)+ ;RESTORE U.CNT ; NEXT INSTRUCTION DEPENDS ON STATS=U.CNT+2 MOV (R1)+,(R3) ;RETRIEVE TERMINAL STATUS CMPB #IE.ABO,FNBYT(R3) ;CANCEL THE DISPLACED READ? BNE 5800$ ;IF NE NO JMP INPT2 ;TERMINATE READ 5800$: MTPS S.PRI(R4) ;RAISE PRIORITY FOR FAKE CONTROL R CLR -(SP) ;;;FAKE A CONTROL R JMP CTRLR ;;; .ENDC ; ; OUTPT - START OR CONTINUE AN OUTPUT STREAM ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; R3 -> TCB (UCB + #U.CNT+2) ; INTERRUPT PRIORITY = THAT OF OUTPUT DEVICE ; ; EXITS VIA RETURN AFTER OUTPUTTING ANOTHER CHARACTER OR THROUGH ; $FORK AT 20$ IF THERE ARE NO MORE CHARACTERS TO OUTPUT OR THROUGH ; $FORK AT INPT1 IF THE INPUT LINE IS COMPLETE (THE OUTPUT ; INTERRUPT IS FROM A CHARACTER ECHO). ; OUTPT: ;;;REF LABEL .IF DF T$$30P BIC #ECHO,ATERS(R3) ;;;CLEAR ECHOING BIT .ENDC .IF DF T$$HLD BIT #BAKS,ATERS(R3) ;;;CLEARING HOLD-SCREEN MODE? BEQ 2$ ;;;IF EQ NO XITHSM: MOVB @MEBUF(R3),-(SP) ;;;GET NEXT BYTE OF "ESC \" BNE 5300$ ;;;IF NE HAVE ANOTHER BYTE TO SEND BIC #BAKS,ATERS(R3) ;;;CLEAR FLAG TST (SP)+ ;;;THROW AWAY TERMINATING BYTE 2$: ;;;REF LABEL .ENDC .IF DF T$$SYN!T$$HLD BIT #CCPN,ATERS(R3) ;;;CONTROL C PENDING? BEQ 2002$ ;;;IF EQ NO BIC #CCPN,ATERS(R3) ;;;CLEAR FLAG TSTB S.STS(R4) ;;;IS CONTROL C GOING TO BE PROCESSED ;;; IMMEDIATELY? BEQ 2000$ ;;;IF EQ YES .IIF NE MODE-100000, .ERROR MODE TST (R3) ;;;BUSY ON INPUT? BPL 2000$ ;;;IF PL YES MOV #2002$,-(SP) ;;;SETUP SO NEXT RETURN IS TO 2002$, ;;; WHICH PROPAGATES THE RENEWED OUTPUT 2000$: MOV #3,-(SP) ;;;FAKE A RECEIVED CONTROL C JMP DOCTLC ;;;EVALUATE IT 2002$: ;;;REF LABEL .ENDC .IF DF T$$30P BIT #CHAR,ATERS(R3) ;;;HAVE AN INPUT CHAR TO PROCESS? BNE 5708$ ;;;IF NE YES .ENDC OUTPT1: BIT #FLCT,(R3) ;;;SHOULD A FILL BE ECHOED? BNE 60$ ;;;IF NE YES BIT #LFCT,(R3) ;;;ANY UNPROCESSED LINE FEEDS? BNE 40$ ;;;IF NE YES MOVB @MEBUF(R3),-(SP);;;MULTI-ECHO SEQUENCE IN PROGRESS? BNE 50$ ;;;IF NE YES 3$: TST (SP)+ ;;;NO - REMOVE ZERO CHAR FROM STACK .IF DF T$$BTW!T$$CTR  MOV #CTRLU-1,MEBUF(R3) ;;;POINT AT ZERO THAT WON'T DISAPPEAR .ENDC .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;;;WRITING A PROMPT? .IF DF T$$BTW BMI 5705$ ;;;IF MI YES .IFF BMI 57$ ;;;IF MI YES .ENDC .ENDC ;;; DF T$$RPR .IIF NE MODE-100000, .ERROR MODE TST (R3) ;;;INPUT OR OUTPUT IN PROGRESS? BPL INPPT ;;;IF PL INPUT ; ; OUTPUT REQUEST IN PROGRESS ; BIT #EOLS!CTLO,(R3) ;;;END OF LINE SEEN OR OUTPUT DISABLED? BNE 20$ ;;;IF NE YES DEC U.CNT(R5) ;;;DECREMENT BYTE COUNT BMI 10$ ;;;IF MI CHECK CARRIAGE CONTROL CALL $GTBYT ;;;GET NEXT BYTE FROM USER BUFFER BECHOB: BR ECHOB ;;;ECHO NEXT BYTE .IF DF T$$BTW 9$: BR 58$ ; .ENDC 10$: MOVB #15,-(SP) ;;;ASSUME TRAILING CARRIAGE RETURN REQUIRED BIS #EOLS,(R3) ;;;SET END OF LINE SEEN BIT #CRTY,(R3) ;;;OUTPUT TRAILING CARRIAGE RETURN? BNE ECHOB ;;;IF NE YES TST (SP)+ ;;;CLEAN STACK ; ; FINISHED AN OUTPUT REQUEST. WANT TO RETURN STATUS. ; 20$: CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS BR 55$ ;SEE IF ERROR OR SUCCESS ; ; ECHO LINE FEED ; 40$: SUB #LFBT,(R3) ;;;REDUCE LINE FEED COUNT MOVB #12,-(SP) ;;;SET TO ECHO LINE FEED BR ECHOB ;;;ECHO BYTE ; ; MULTI-ECHO SEQUENCE ; 50$: ;;;REF LABEL .IF DF T$$BTW!T$$CTR&T$$UTB&M$$MGE BIT #MCTR,ATERS(R3) ;;;CONTROL/R INPUT IN TASK'S BUFFER? BEQ 53$ ;;;IF EQ NO ; ; DOING CONTROL R FOR A TASK THAT HAS THE INPUT STRING IN ITS ; ADDRESS SPACE. TRY HARDER. ; CALL $GTBYT ;;;PUT NEXT BYTE ON STACK MOVB (SP)+,(SP) ;;;COLLAPSE STACK BNE ECHOB ;;;IF NE SOMETHING TO TRANSMIT DEC U.BUF+2(R5) ;;;POINT AT POSITION TO STORE NEXT ;;; INPUT CHARACTER BIC #MCTR,ATERS(R3) ;;;CLEAR FLAG BR 3$ ;;;DO NORMAL COMPLETION 53$: ;;;REF LABEL .ENDC 5300$: INC MEBUF(R3) ;;;INCREMENT BUFFER ADDRESS BR ECHOB ;;;ECHO BYTE ON STACK ; ; TERMINAL TIMEOUT-FINISH I/O OPERATION ; ENTERED ON FORK LEVEL WITH TERMINAL CONTROLLER ALREADY RESET ; TTOUT1: CMPB #IE.ABO,U.CNT+2+FNBYT(R5) ;TIMEOUT OR CANCEL? BEQ 54$ ;IF EQ CANCEL MOVB R0,U.CNT+2+FNBYT(R5) ;REMEMBER TIMEOUT STATUS 54$: ;REF LABEL .IF DF T$$BTW!T$$CTR MOV #CTRLU-1,U.CNT+2+MEBUF(R5) ;POINT AT A ZERO BYTE .IF DF T$$UTB&M$$MGE BIC #MCTR,U.CNT+2+ATERS(R5) ;CLEAR SPECIAL CONTROL R FLAG .ENDC .ENDC .IIF NE MODE-100000, .ERROR MODE TST U.CNT+2+STATS(R5) ;INPUT OR OUTPUT IN PROGRESS? .IF DF T$$MIN .IF DF T$$BTW BPL INPT22 ;IF PL INPUT .IFF BPL INPT2 ;IF PL INPUT .ENDC .IFF BPL INPT22 ;IF PL INPUT .ENDC 55$: MOV S.PKT(R4),R1 ;POINT AT COMPLETED OUTPUT I/O PACKET MOV I.PRM+4(R1),R1 ;GET BYTES IT WANTED TRANSFERED BIT #CTLO,U.CNT+2+STATS(R5) ;TERMINATION BY CONTROL O ; OR EOLS? BNE 56$ ;IF NE CONTROL O MOV U.CNT(R5),R2 ;SAVE BYTES LEFT TO TRANSFER BMI 56$ ;IF MI DID THE ENTIRE WRITE SUB R2,R1 ;CALCULATE BYTES NOT TRANSFERED MOV U.CNT+2+FNBYT-1(R5),R0 ;GET REASON FOR PARTIAL TRANSFER CLRB R0 ;CHANGE INTO IOSB SWAB R0 ; 56$: ;REF LABEL .IF DF T$$BTW BIT #BTWP,U.CNT+2+ATERS(R5) ;DID A BREAKTHROUGH WRITE? BEQ IODON ;IF EQ NO MOV S.PKT(R4),R2 ;POINT AT I/O PACKET FOR WRITE MOV I.PRM+16(R2),U.CNT+2+STATS(R5) ;SAVE DISPLACED READ'S ; I/O PACKET ADDRESS IN THE UCB .IF DF R$$LKL CLR I.PRM+16(R2) ;MAKE LOCKING WORD ZERO AGAIN .ENDC .IFTF IODON: CALL $IODON ;FINISH I/O OPERATION .IFT BIT #BTWP,U.CNT+2+ATERS(R5) ;DID A BREAKTHROUGH WRITE? BNE 9$ ;IF NE YES .ENDC .IF DF T$$MIN .IF DF T$$BTW JMP TTINI ;GO AGAIN .IFF BR BTTINI ;GO AGAIN .ENDC .IFF JMP TTINI ;GO AGAIN .ENDC ; ; INPUT REQUEST IN PROGRESS ; INPPT: BIT #EOLS,(R3) ;;;END OF LINE SEEN? .IF NDF T$$MIN BNE INPT11 ;;;IF NE YES .IFF BNE INPT1 ;;;IF NE YES .ENDC INPT0: BICB #US.ECH,U.STS(R5) ;;;ENABLE INPUT CHARACTER HANDLING RETURN ;;; ; ; ECHO FILL BYTE ; .IIF NE FLBT-1, .ERROR FLBT 60$: DEC (R3) ;;;DECREMENT FILL COUNT MOVB FLBYT(R3),-(SP) ;;;SET TO ECHO FILL BYTE ;;;FALL INTO CODE TO ECHO BYTE .DSABL LSB ; ; ECHO NEXT BYTE ; .ENABL LSB ECHOB: ;;;REF LABEL .IF DF T$$TRW BITB #SS.WAL,S.STS(R4) ;;;WRITE PASS ALL? BNE ECHB11 ;;; IF NE YES ;TMM036 ;**-1 .ENDC ; ; CHECK IF OUTPUT CHARACTER HAS SPECIAL SIGNIFICANCE ; CMPB (SP),#37 ;;;IS THIS A CONTROL CHARACTER? BHI 70$ ;;;IF HI NO CMPB #15,(SP) ;;;CARRIAGE RETURN? BEQ 10$ ;;;IF EQ YES CMPB #14,(SP) ;;;FORM FEED? BEQ 30$ ;;;IF EQ YES CMPB #13,(SP) ;;;VERTICAL TAB? BEQ 40$ ;;;IF EQ YES CMPB #12,(SP) ;;;LINE FEED? BEQ 50$ ;;;IF EQ YES CMPB #11,(SP) ;;;HORIZONTAL TAB? BNE 79$ ;;;IF NE NO ; ; HORIZONTAL TAB ; MOVB HORPS(R3),(SP) ;;;GET CURRENT HORIZONTAL POSITION BIS #177770,(SP) ;;;CALCULATE BLANK COUNT TO NEXT TAB STOP SUB (SP),(R3) ;;;MERGE BLANK COUNT MOVB #' ,FLBYT(R3) ;;;SET FILL TO A BLANK 5$: TST (SP)+ ;;;REMOVE BYTE FROM STACK .IF DF T$$MIN .IF DF T$$BTW JMP OUTPT1 ;;;START OUTPUT .IFF BR OUTPT1 ;;;START OUTPUT .ENDC .IFF JMP OUTPT1 ;;;START OUTPUT .ENDC ; ; CARRIAGE RETURN ; 10$: BIS #CRJT+FLBT,(R3) ;;;SET CR JUST TYPED AND FORCE 1 FILL BIT #U2.L3S,U.CW2(R5) ;;;LA30S? BEQ 20$ ;;;IF EQ NO CLR -(SP) ;;;PICKUP CURRENT HORIZONAL POSITION BISB HORPS(R3),(SP) ;;; .IF DF T$$ACR 14$: SUB U.CW4(R5),(SP) ;;;REDUCE THE LOGICAL HORIZONTAL BGT 14$ ;;; POSITION TO THE PHYSICAL POSITION ADD U.CW4(R5),(SP) ;;; (BETWEEN 0 AND 80). .IFTF ASR (SP) ;;;DIVIDE POSITION BY 8. ASR (SP) ;;; ASR (SP) ;;; ADD #FILTB,(SP) ;;;CALCULATE ADDRESS OF FILL TABLE ENTRY MOVB @(SP)+,-(SP) ;;;GET CORRECT FILL COUNT BIC #^C<17>,(SP) ;;;CLEAR EXTRANEOUS BITS ON WIDE CARRIAGE ADD (SP)+,(R3) ;;;SET PROPER FILL COUNT 20$: ;;;REF LABEL .IFT BIT #FKCR,ATERS(R3) ;;;FAKE CARRIAGE RETURN? BNE 60$ ;;;IF NE YES -- NOT A NEW LINE .ENDC 27$: CLRB HORPS(R3) ;;;CLEAR HORIZONTAL POSITION BR 60$ ;;;OUTPUT CARRIAGE RETURN ; ; FORM FEED ; 30$: ;;;REF LABEL .IF DF T$$HFF BIT #U2.HFF,U.CW2(R5) ;;;TERMINAL CAN HANDLE FORM FEED? BNE 27$ ;;;IF NE YES .ENDC ADD #LFBT*4,(R3) ;;;ADD IN FOUR LINE FEEDS ; ; VERTICAL TAB ; 40$: ADD #LFBT*4,(R3) ;;;ADD IN FOUR LINE FEEDS BR 5$ ;;;GO BACK TO THE TOP TO PRINT THEM .IF NDF T$$MIN INPT22: BR INPT2 ;;; INPT11: BR INPT1 ;;; .ENDC ;TMM036 .IF DF T$$TRW ;TMM036 ;TMM036 ECHB11: BR ECHOB1 ;;; ;TMM036 ;TMM036 .ENDC ;TMM036 ;TMM036 ; ; LINE FEED ; 50$: BIC #CRJT,(R3) ;;;CLEAR CARRIAGE RETURN JUST TYPED ; EB268 .IF DF PASSLF ; EB268 ; EB268 BIT #U2.HFF,U.CW2(R5) ;;;TREAT LF LIKE FF? ; EB268 BNE 27$ ;;;IF NE YES ; EB268 ; EB268 .ENDC ; EB268 BIT #U2.VT5,U.CW2(R5) ;;;VT05B? BEQ 80$ ;;;IF EQ NO .IF DF L$$50H ADD #FLBT*4,(R3) ;;;SET FILL COUNT TO 4 .IFF ADD #FLBT*3,(R3) ;;;SET FILL COUNT TO 3 .ENDC 60$: CLRB FLBYT(R3) ;;;SET NULL FILL BYTE BR 80$ ;;; .IF DF T$$MIN&T$$BTW INPT22: BR INPT2 ;;; .ENDC ; ; BYTE REQUIRES HORIZONTAL POSITION ; 70$: BIC #CRJT,(R3) ;;;CLEAR CARRIAGE RETURN JUST TYPED ;TMM036 CMPB (SP),#172 ;;;IS THIS A LOWER CASE ALPHABETIC? ;TMM036 BHI 71$ ;;;IF HI NO ALSO NOT A SPECIAL CHAR ;TMM036 CMPB (SP),#141 ;;;UPPER CASE OR CONTROL CHARACTER? ;TMM036 BLO 71$ ;;;IF LO YES ;TMM036 BIT #U3.UPC,U.CW3(R5) ;;; IS THIS AN ASR33? ;TMM036 BEQ 71$ ;;; IF EQ NO, ALLOW LOWERCASE OUTPUT ;TMM036 BIC #40,(SP) ;;;CONVERT LOWERCASE TO UPPER CASE ;TMM036 71$: ;;;REF LABEL ;TMM036 TSTB (SP) ;;;BYPASS HORIZONAL POSITION CHECK? ;**-1 BMI 80$ ;;;IF MI YES .IF NDF T$$ACR ; ; SEE IF OUTPUT (OR ECHO) IS OFF SCREEN. THIS IMPLIES THAT NO MORE ; THAN 255. CHARACTERS CAN BE OUTPUT (TABS ARE EXPANDED INTO BLANKS ; SO THEY COUNT AS MORE THAN ONE CHARACTER) WITH ONE NORMAL WRITE. ; CMPB HORPS(R3),U.CW4(R5) ;;;ANY ROOM LEFT? BHIS 5$ ;;;IF HIS NO .IFF ; ; SEE IF LINE MUST BE WRAPPED AROUND SCREEN ; BIT #FKCR,ATERS(R3) ;;;LAST PRINTING CHAR WRAPPED AROUND? BNE 75$ ;;;IF NE YES -- DON'T TEST FOR WRAP CLR -(SP) ;;;MAKE THE PRESENT HORIZONTAL MOVB HORPS(R3),(SP) ;;; POSITION A WORD 73$: SUB U.CW4(R5),(SP) ;;;HORIZONTAL POSITION - BUFFER SIZE BGT 73$ ;;;IF GT NOT LOGICALLY ON SAME LINE TST (SP)+ ;;;ADJUST STACK BEQ 90$ ;;;IF EQ AT RIGHT EDGE OF SCREEN 75$: BIC #FKCR,ATERS(R3) ;;;CLEAR DISPLAY TRANSITION FLAG .ENDC INCB HORPS(R3) ;;;INCREMENT HORIZONTAL POSITION 79$: ;;;REF LABEL .IF DF T$$RUB CMPB #10,(SP) ;;;TRYING TO OUTPUT A BACKSPACE? BNE 80$ ;;;IF NE NO TSTB HORPS(R3) ;;;SAFE TO BACKUP ON LINE? BLE 80$ ;;;IF LE NO DECB HORPS(R3) ;;;BACKUP HORIZONTAL POSITION .ENDC .IIF NE MODE-100000, .ERROR MODE 80$: TST (R3) ;;;INPUT MODE? BPL ECHOB1 ;;;IF PL YES BIT #CTLO,(R3) ;;;OUTPUT DISABLED? BNE 5$ ;;;IF NE YES ECHOB1: CALLR OCHAR ;;;GO AND OUTPUT THE CHARACTER .IF DF T$$ACR ; ; WRAP LINE AROUND SCREEN (BLOWS TABS EXPANDING AT RIGHT EDGE) ; 90$: BIS #FKCR,ATERS(R3) ;;;SIGNAL LINE WRAPPING AROUND SCREEN BIT #FLCT,(R3) ;;;FILLING (DOING A TAB)? BEQ 93$ ;;;IF EQ NO MOV (R3),-(SP) ;;;CHANGE REMAINING FILL COUNT TO BIC #^C,(SP) ;;; A WORD CLR -(SP) ;;;DO THE SAME FOR HORIZONTAL MOVB HORPS(R3),(SP) ;;; POSITION ADD (SP)+,(SP) ;;;FORM LOGICAL SCREEN POSITION AFTER ;;; WRAPAROUND (DISPLAY WILL BE OFF) MOVB (SP)+,HORPS(R3) ;;;SAVE IT. IF THIS TRUNCATES, ;;; CONSIDER IT A HINT TO THE USER. 93$: TSTB @MEBUF(R3) ;;;DOING MULTI-ECHO? BEQ 100$ ;;;IF EQ NO .IF DF T$$UTB&M$$MGE BIT #MCTR,ATERS(R3) ;;;DOING CONTROL/R? BEQ 95$ ;;;IF EQ NO INC U.BUF+2(R5) ;;;SHOW LAST CHAR NOT REMOVED BR 96$ ;;; 95$: ;;;REF LABEL .ENDC DEC MEBUF(R3) ;;;SHOW LAST CHAR NOT REMOVED 96$: BIS #LFBT,(R3) ;;;WANT A LINE FEED EVENTUALLY MOV #15,(SP) ;;;WANT A CARRIAGE RETURN NEXT JMP 10$ ;;; ;TMM036 100$: BIS #LFBT+FLBT,(R3) ;;;SET UP ONE FILL CHAR AND 1 LF ;**-1 MOVB #15,FLBYT(R3) ;;;THE FILL CHAR IS A CR CLRB 1(SP) ;;;MAKE SURE BYTE ON STACK IS ASCIZ JMP MECHO1 ;;;DEFER OVFLO CHAR TO MULTI-ECHO BUFFER .ENDC .DSABL LSB .SBTTL END-OF-INPUT-LINE PROCESSOR ; ; INPT1 - FORK IN ORDER TO FINISH AN INPUT REQUEST ; ; ON ENTRY: ; R5 -> UCB ; R4 -> SCB ; INTERRUPT PRIORITY = THAT OF DEVICE INPUT CAME FROM ; INPT1: ;;;REF LABEL .IF DF T$$RPR BIT #XOFF,ATERS(R3) ;;;SEND XOFF AT READ COMPLETE? BEQ 10$ ;;;IF EQ NO BIC #XOFF,ATERS(R3) ;;;CLEAR FLAG MOV #23,-(SP) ;;;PUT XOFF ON STACK BR ECHOB1 ;;;TRANSMIT IT 10$: ;;;REF LABEL .ENDC CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN .ENABL LSB ; ; END-OF-LINE FORK PROCESS ; INPT2: MOV R5,R3 ;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ; BIT #SOLI,(R3)+ ;SOLICITED INPUT? BNE 20$ ;IF NE YES ; ; UNSOLICITED INPUT FINISHED ; MOVB FNBYT-2(R3),@CURBF-2(R3) ;SET FINAL BYTE FOR MCR MOV (R3),R1 ;GET STARTING ADDRESS OF BUFFER MOV R5,-(R1) ;INSERT ADDRESS OF UCB IN BUFFER TST -(R1) ;POINT TO BEGINNING OF BUFFER CALL $QMCRL ;INSERT BUFFER IN MCR QUEUE 10$: BICB #US.BSY,U.STS(R5) ;CLEAR UNIT BUSY CLRB S.STS(R4) ;CLEAR CONTROLLER (UNIT) BUSY JTTINI: JMP TTINI ;GO AGAIN ; ; SOLICITED INPUT FINISHED ; 20$: MOV (R3)+,R1 ;GET STARTING ADDRESS OF BUFFER MOV U.CNT(R5),-(SP) ;CALCULATE NUMBER OF BYTES IN INPUT SUB (R3),(SP) ; BUFFER MOVB #IS.SUC&377,(R3) ;ASSUME NORMAL COMPLETION CLRB 1(SP) ;MAKE SURE COUNT IS POSITIVE MOV (R3)+,R0 ;GET FINAL BYTE (STATUS INDICATION) BPL 30$ ;IF PL NORMAL TERMINATION CLRB R0 ;PUT ERROR STATUS IN LOW BYTE OF SWAB R0 ; IOSB AND CLEAR UPPER BYTE .IF DF T$$ESC INCB -(R3) ;FOUND ESCAPE SEQUENCE? BNE 30$ ;IF NE NO MOV #IS.ESQ,R0 ;SHOW AN ESCAPE SEQUENCE IN BUFFER .ENDC 30$: ;REF LABEL ; ; SEE IF NECESSARY TO MOVE THE RECEIVED CHARACTERS FROM THE ; EXECUTIVE BUFFER TO THE TASK BUFFER ; MOV S.PKT(R4),R3 ;GET I/O PACKET ADDRESS ;TMM010 .IF DF T$$UTB .IF DF C$$CKP&T$$BUF BIT #NCKP,U.CNT+2+ATERS(R5) ;CHARS ALREADY IN TASK BUFFER? BEQ 35$ ;IF EQ NO BIC #NCKP,U.CNT+2+ATERS(R5) ;CLEAR NOT CHECKPOINTABLE FLAG .ENDC MOV (SP)+,R1 ;SET NUMBER OF BYTES PROCESSED ;TMM010 .IF DF T$$RPR&R$$LKL ;TMM010 ;TMM010 CLR I.PRM+16(R3) ;CLEAR LOCKING WORD ;TMM010 ;TMM010 .ENDC ;TMM010 CALL $IODON ;FINISH I/O OPERATION BR JTTINI ;ANYTHING ELSE TO DO? 35$: ;REF LABEL .IF DF M$$MGE MOV R1,U.BUF+2(R5) ;POINT AGAIN AT TASK'S BUFFER .ENDC .ENDC ; DF T$$UTB .IF NDF T$$UTB!NOEXBF .IF DF C$$CKP&T$$BUF MOV I.TCB(R3),R2 ;GET ADDRESS OF REQUESTER TCB ;**-1 BIT #NCKP,U.CNT+2+ATERS(R5) ;BUFFERED ? ;TMMO11 BEQ 80$ ;IF EQ YES ;TMMO11 ;**-2 .IFTF ; ; MOVE CHARACTERS TO TASK'S BUFFER FROM AN EXECUTIVE BUFFER ; MOV (SP),R3 ;SET LOOP COUNT .IF DF M$$MGE MOV U.BUF(R5),@#KISAR6 ;MAP INTO TASK'S SPACE .ENDC MOV U.BUF+2(R5),R2 ;POINT AT TASK'S BUFFER 50$: DEC R3 ;ANY MORE BYTES TO MOVE? BLT 60$ ;IF LT NO MOVB (R1)+,(R2)+ ;PUT BYTE IN TASK'S BUFFER BR 50$ ; ; ; RETURN STATUS TO TASK AND RESOURCES TO EXEC FROM SOLICITED READ ; 60$: ;TMM010 .IF DF R$$LKL ;TMM010 ;TMM010 MOV S.PKT(R4),R3 ;GET I/O PACKET ADDRESS ;TMM010 CLR I.PRM+16(R3) ;MAKE LOCKING WORD ZERO AGAIN ;TMM010 ;POSSIBLY AN RPR PROMPT ;TMM010 .ENDC ;R$$LKL ;TMM010 ;TMM010 MOV (SP)+,R1 ;SET NUMBER OF BYTES PROCESSED ;TMM010 CALL $IODON ;FINISH I/O OPERATION ;**-1 MOV U.CNT+2+STRBF(R5),R0 ;RETRIEVE BUFFER ADDRESS .IF DF T$$VBF MOV -(R0),R1 ;GET LENGTH OF BUFFER TST -(R0) ;POINT TO BEGINNING OF BUFFER .IFF CMP -(R0),-(R0) ;POINT TO BEGINNING OF BUFFER MOV #M$$CRB,R1 ;SET LENGTH OF BUFFER .ENDC CALL $DEACB ;DEALLOCATE CORE BLOCK BR JTTINI ; .IFT ; DF C$$CKP&T$$BUF ; ; HAUL THE TASK INTO MEMORY SO THE RECEIVED CHARACTERS CAN BE COPIED ; INTO THE TASK'S BUFFER. COPYING AND PACKET TERMINATION IS DONE BY ; $FINBF IN SYSXT. ; 80$: CMP -(R1),-(R1) ;POINT TO BEGINNING OF BUFFER ;TMM011 MOV R1,I.PRM+12(R3) ;SAVE BUFFER ADDRESS ;TMM011 MOV (SP)+,R1 ;GET SECOND WORD OF STATUS ;TMM011 CALL $QUEBF ;KICK OFF KERNAL AST TO COPY BUFFER ;TMM011 ;INTO THE TASK AFTER THE TASK'S CONTEXT ;TMM011 ;HAS BEEN LOADED. ;TMM011 BR 10$ ;CALL $NXTSK ;TMM011 .ENDC ; DF C$$CKP&T$$BUF ;**-24 .ENDC ; NDF T$$UTB!NOEXBT .DSABL LSB .SBTTL CHARACTER INPUT INTERRUPT PROCESSOR .ENABL LSB .IF DF T$$CCA&A$$TRP ; ; QUEUE AN AST BLOCK FOR AN UNSOLICITED CHARACTER ; 1$: CALL INPT0 ;CLEAR ECHO IN PROGRESS FLAG MOV #6*2,R1 ;LENGTH OF AST BLOCK CALL $ALOCB ;ALLOCATE AN AST BLOCK BCS 20$ ;IF CS DIDN'T GET ONE TST (R0)+ ;SKIP OVER LINK WORD MOV R1,(R0)+ ;SAVE SIZE OF AST BLOCK MOV R0,R1 ;SAVE BEGINNING ADDRESS OF CMP -(R1),-(R1) ; AST BLOCK MOV #10*2,(R0)+ ;SAVE BYTES TO ALLOCATE ON STACK MOV U.CNT+2+CCAST(R5),(R0)+ ;SAVE AST TRAP ADDRESS MOV #1,(R0)+ ;SAVE NUMBER OF AST PARAMETERS MOV (SP)+,(R0) ;UNSOLICITED CHAR IS AST PARAMETER MOV U.ATT(R5),R0 ;GET ADDRESS OF TASK'S TCB CALL $QASTT ;INSERT AST BLOCK IN AST QUEUE BR JTTINI ; AND CALL $SETCR .ENDC ; ; ICHAR - PROCESS AN INPUT CHARACTER ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; R3 -> TCB (UCB + #U.CNT+2) ; INTERRUPT PRIORITY = THAT OF INTERRUPTING DEVICE ; ; INPUT CHAR IS ON TOP OF STACK AND PARITY BIT IS CLEARED (UNLESS ; INPUTTING IN READ-PASS-ALL MODE). ; EXIT VIA POPPING CHAR FROM STACK AND RETURNING OR BY ; QUEUING A FORK PROCESS AT INPT1 IF THE INPUT REQUEST IS ; SATISFIED OR BY QUEUING A FORK PROCESS AT TINP1 IF THE INPUT ; IS UNSOLICITED. ; ICHAR: ;;;REF LABEL .IF DF T$$30P BIT #ECHO,ATERS(R3) ;;;ECHOING A CHARACTER? BEQ 3$ ;;;IF EQ NO ; ; THE TRANSMITTER IS BEING USED ; (WHICH IS TO SAY THE TERMINAL IS A LA30P CONNECTED BY A LC11) TO ; ECHO THE LAST CHARACTER. BUFFER THIS CHAR IN THE SOFTWARE. ; MOVB (SP),MBUFR(R3) ;;;SAVE CHAR IN MULTIECHO BUFFER BIS #CHAR,ATERS(R3) ;;;FLAG INPUT CHAR IN BUFFER BR 20$ ;;;WORRY ABOUT CHAR WHEN TRANSMITTER 3$: ;;; BECOMES FREE .ENDC BITB #US.ECH,U.STS(R5) ;;;INPUT CHARACTERS LOCKED OUT? BNE 20$ ;;;IF NE YES DOCTLC: BISB #US.ECH,U.STS(R5) ;;;LOCK OUT INPUT CHARACTERS RESUME: ;;;REF LABEL .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;;;DOING A PROMPT FOR AN IO.RPR? BMI 8$ ;;;IF MI YES .ENDC .IF DF T$$TRW!T$$RST .IIF NE SS.RAL-200, .ERROR SS.RAL BITB #SS.RAL!SS.RST,S.STS(R4) ;;;READ PASS ALL OR READ WITH ;;; SPECIAL TERMINATORS? .IF DF T$$TRW&T$$LWC BMI 156$ ;;;IF MI READ PASS ALL .IF DF T$$RST BNE 155$ ;;;IF NE YES .ENDC .IFF ;;; DF T$$TRW&T$$LWC BNE 155$ ;;;IF NE YES .ENDC ;;; DF T$$TRW&T$$LWC .ENDC ;;; DF T$$TRW!T$$RST 8$: CMPB #17,(SP) ;;;CONTROL/O? BNE 26$ ;;;IF NE NO MOV #CTLO,-(SP) ;;;GET OUTPUT DISABLE BIT BIC (R3),(SP) ;;;.NOT.TERMINAL STATUS.AND.DISABLE BIT BIC #CTLO,(R3) ;;;.NOT.DISABLE BIT.AND.TERMINAL STATUS BIS (SP)+,(R3) ;;;DISABLE BIT.OR.TERMINAL STATUS 10$: CALL INPT0 ;;;CLEAR ECHO IN PROGRESS ; ; CONTROLLER IS BUSY ON OUTPUT. IGNORE INPUT REQUEST ; 20$: TST (SP)+ ;;;REMOVE BYTE FROM STACK RETURN ;;;EXIT INTERRUPT 26$: ;;;REF LABEL .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;;;DOING A PROMPT FOR AN IO.RPR? BMI 10$ ;;;IF MI YES -- IGNORE CHAR IF NOT ;;; A CONTROL Q, S, OR O .ENDC TSTB S.STS(R4) ;;;CONTROLLER (UNIT) BUSY? BNE 30$ ;;;IF NE YES 27$: ;;;REF LABEL .IF DF T$$CCA&A$$TRP BIT #CCON,ATERS(R3) ;;;CONTROL C AST CODE ACTIVE? BNE 140$ ;;;IF NE YES -- CHAR CAUSES AST .ENDC ; NEXT INSTRUCTION DEPENDS ON U2.SLV=200 TSTB U.CW2(R5) ;;;SLAVE TERMINAL? BMI 10$ ;;;IF MI YES CMPB #3,(SP) ;;;CONTROL C? BEQ 140$ ;;;IF EQ YES TST U.ATT(R5) ;;;UNIT ATTACHED? BNE 10$ ;;;IF NE YES ; ; UNSOLICITED INPUT REQUEST ; 140$: ;;;REF LABEL .IF DF T$$CCA&A$$TRP TSTB INPRQ(R3) ;;;ALREADY WAITING TO FORK? BNE 10$ ;;;IF NE YES -- IGNORE THIS CHAR ;;; RATHER THAN THE PRECEDING ONE .ENDC TSTB (SP) ;;;IS THE CHARACTER A NULL? BEQ 10$ ;;;IF EQ YES -- IGNORE IT MOVB (SP),INPRQ(R3) ;;;SAVE BYTE (ALSO UNSOL INP PNDG FLG) TSTB S.STS(R4) ;;;UNIT BUSY ON INPUT OR OUTPUT BNE 10$ ;;;IF NE YES -- FORK LATER (TTINI) BIS #UIFP,(R3) ;;;SET UNSOLICITED INPUT FORK PENDING TST (SP)+ ;;;REMOVE BYTE FROM STACK CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN ; ; UNSOLICITED INPUT FORK PROCESS ; TINP1: MOV U.CNT+2+INPRQ(R5),-(SP) ;GET INPUT BYTE AND ZERO BYTE CLRB U.CNT+2+INPRQ(R5) ;CLEAR UNSOL INPUT PENDING FLAG BIC #UIFP,U.CNT+2+STATS(R5) ;CLEAR UNSOL INP FORK PEND FLG .IF DF T$$CCA&A$$TRP BIT #CCON,U.CNT+2+ATERS(R5) ;WORRY ABOUT CONTROL C AST'S?  BNE 1$ ;IF NE YES .ENDC .IF DF R$$11S TST $MCRPT ;BASIC MCR AROUND? BEQ 10$ ;IF EQ NO -- IGNORE CHAR .ENDC MOV U.CW4(R5),U.CNT(R5) ;SET NUMBER OF BYTES REQUESTED CALL GETBF ;GET BUFFER FOR INPUT AND SET R3 BCS 10$ ;IF CS DID NOT GET ONE ; ; BUFFER ALLOCATED. SET CONTROLLER AND UNIT BUSY. ; BISB #US.BSY,U.STS(R5) ;SET UNIT BUSY INCB S.STS(R4) ;SET CONTROLLER BUSY BIT #CRJT,(R3) ;CARRIAGE RETURN JUST TYPED? BEQ 150$ ;IF EQ NO ADD #LFBT,(R3) ;ADD IN ONE LINE FEED 150$: MTPS S.PRI(R4) ;RAISE PRIO TO ENTER OUTPUT ROUTINES CMPB #3,(SP) ;;;CONTROL C? BNE 35$ ;;;IF NE NO .IF DF M$$CLI MOV U.CLI(R5),(SP) ;;;GET TERMINAL'S CLI POINTER ADD #2,(SP) ;;;POINT TO CLI'S PROMPT STRING .IFF ;M$$CLI ;TMM032 .IF NDF A$$CLI ;TMM032 MOV #CTRLC,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER ;TMM032 .IFF ;TMM032 MOV U.MUP(R5),R1 ;PICK UP CLI INDEX ;TMM032 BIC #^C,R1 ;AND ONLY THE INDEX ;TMM032 MOV $CPTBL(R1),R1 ;GET ADDRESS OF CPB ;TMM032 ADD #C.PDPL,R1 ;POINT TO DEFAULT PROMPT STRING LENGTH ;TMM032 CLR (SP) ;MAKE SURE HIGH BYTE IS ZERO ;TMM032 MOVB (R1)+,(SP) ;GET LENGTH OF DEFAULT PROMPT ;TMM032 TSTB (R1)+ ;ANY CONTROL-C PROMPT? ;TMM032 BEQ 158$ ;IF EQ,NO ;TMM032 ADD R1,@SP ;FORM POINTER TO CONTROL-C PROMPT ;TMM032 BR 180$ ;TMM032 158$: MOV #CTRLU-1,@SP ;POINT TO A ZERO WHICH WILL NOT DISAPPEAR ;TMM032 BR 180$ ;TMM032 ;TMM032 .ENDC ;A$$CLI ;TMM032 ;TMM032 .ENDC ;M$$CLI 152$: BR 180$ ;;; .IF DF T$$TRW!T$$RST 155$: JMP 36$ ;;; .ENDC .IF DF T$$TRW&T$$LWC!T$$ESC 156$: JMP 37$ ;;; .ENDC .IF NDF T$$MIN 157$: BR 10$ ;;; .ENDC ;;; NDF T$$MIN ; ; CONTROLLER IS BUSY ON INPUT OR OUTPUT ; .IIF NE MODE-100000, .ERROR MODE 30$: TST (R3) ;;;BUSY ON INPUT? BMI 27$ ;;;IF MI NO CMPB #3,(SP) ;;;CONTROL C? BEQ 27$ ;;;IF EQ YES ; ; PROCESS NEXT INPUT BYTE ; .IF DF T$$ESC BIT #ESCS,ATERS(R3) ;;;IN MIDDLE OF AN ESCAPE SEQUENCE? BNE 156$ ;;;IF NE YES .ENDC 35$: ;;;REF LABEL .IF DF T$$RUB CMP STRBF(R3),CURBF(R3) ;;;THIS IS FIRST CHAR FOR BUFFER? BNE 350$ ;;;IF NE NO MOVB HORPS(R3),IHORP(R3) ;;;SAVE CURRENT HORIZONTAL POSITION 350$: ;;;REF LABEL .ENDC .IF DF T$$CTR CMPB #22,(SP) ;;;CONTROL R? BNE 352$ ;;;IF NE NO .IFF .IF DF T$$BTW BR 352$ ;;;DO NOT TREAT CHAR AS CONTROL/R .ENDC ; ; CONTROL R ; .IFTF  .IF DF T$$BTW CTRLR: ;;;REF LABEL .ENDC .IFT .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;IGNORE CONTROL R IF NO ECHO BNE 10$ ;;; .ENDC .ENDC ;;; DF T$$CTR .IF DF T$$BTW!T$$CTR BIC #RUBP,(R3) ;;;NEW LINE=NEW RUBOUT SEQUENCE BIS #LFBT+FLBT,(R3) ;;;WANT 1 FILL CHAR AND 1 LF MOVB #15,FLBYT(R3) ;;;FILL CHAR IS A CR .IF DF T$$UTB&M$$MGE CLR -(SP) ;;;ZERO TO SHOW END OF MULTIECHO CALL $PTBYT ;;;SHOVE AT END OF TASK'S INPUT MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF INPUT BIS #MCTR,ATERS(R3) ;;;FLAG THE NEED TO MAP MULTIECHO MOV #CTRLU,(SP) ;;;POINT AT A NONZERO BYTE .IFF CLRB @CURBF(R3) ;;;SHOW END OF CHARS MOV STRBF(R3),(SP) ;;;START FROM BEGINNING OF INPUT BUFFER .ENDC .IF DF T$$RUB CLRB IHORP(R3) ;;;OUTPUT STARTS AT LEFT MARGIN .ENDC BR 180$ ;;;DO MULTI-ECHO BUFFER 352$: ;;;REF LABEL .ENDC ;;; DF T$$BTW!T$$CTR CMPB #177,(SP) ;;;RUBOUT? BNE 185$ ;;;IF NE NO ; ; RUBOUT ; CMP CURBF(R3),STRBF(R3) ;;;ANY BYTES TO RUBOUT? .IF DF T$$MIN BEQ 10$ ;;;IF EQ NO .IFF BEQ 157$ ;;;IF EQ NO .ENDC DEC CURBF(R3) ;;;BACK UP ONE BYTE .IF DF T$$UTB&M$$MGE DEC U.BUF+2(R5) ;;;POINT AT LAST CHARCTER CALL $GTBYT ;;;PUT IT ON STACK DEC U.BUF+2(R5) ;;;POINT AT PLACE FOR NEXT INPUT CHAR MOV (SP)+,(SP) ;;;ADJUST STACK .IFF MOVB @CURBF(R3),(SP) ;;;GET BYTE TO BE RUBBED OUT .ENDC INCB RMBYT(R3) ;;;INCREMENT REMAINING SPACE IN BUFFER .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;ECHOING CHARACTERS? .IF DF T$$MIN 355$: BNE 10$ ;;;IF NE NO .IFF 355$: BNE 157$ ;;;IF NE NO .ENDC .ENDC ;;; DF T$$RNE .IF DF T$$RUB BIT #U2.CRT,U.CW2(R5) ;;;TERMINAL A CRT? BEQ 58$ ;;;IF EQ NO ; ; CRT RUBOUT ; ; CHECK TO SEE IF TRYING TO RUB OUT A TAB. IT IS THE ONLY ; CASE OF A SPECIAL CURSOR POSITIONING CHAR WE WORRY ABOUT. ; TOO BAD ABOUT THINGS LIKE BACKSPACE. ; CMPB #11,(SP) ;;;LAST CHAR A TAB? BEQ 50$ ;;;IF EQ YES .IF DF T$$ACR  BIS #FKCR,ATERS(R3) ;;;FLAG DO NOT WORRY ABOUT WRAPAROUND .ENDC MOV #CRTRUB,(SP) ;;;OVERPRINT CHAR WITH A BR 180$ ;;; BACKSPACE, SPACE, BACKSPACE 50$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF BUFFER .IFF MOV STRBF(R3),R4 ;;;POINT AT START OF INPUT LINE .IFTF MOVB IHORP(R3),(SP) ;;;INITIALIZE LINE POSITION BR 56$ ;;;1ST CHARACTER IS A TAB? 53$: ;;;REF LABEL .IFT CALL $GTBYT ;;;PUT NEXT BYTE ON STACK CMPB #11,(SP)+ ;;;IS OLD CHARACTER A TAB? .IFF CMPB #11,(R4)+ ;;;IS OLD CHARACTER A TAB? .IFTF BNE 55$ ;;;IF NE NO BISB #7,(SP) ;;;BUMP COUNT TO NEXT TAB STOP 55$: INCB (SP) ;;;COUNT THE CHARACTER 56$: ;;;REF LABEL .IFT CMP U.BUF+2(R5),CURBF(R3) ;;;FOUND LAST TAB? .IFF CMP R4,CURBF(R3) ;;;FOUND LAST TAB? .IFTF BLT 53$ ;;;IF LT NO BIS #177770,(SP) ;;;-SPACES LAST TAB PUT OUT ADD #CRTBS,(SP) ;;;POINT AT SAME NUMBER OF BACKSPACES .IFF MOV U.SCB(R5),R4 ;;;RESTORE R4 .IFTF BR 180$ ;;;BACKUP ON LINE .ENDC ;;; DF T$$UTB&M$$MGE 58$: ;;;REF LABEL .ENDC ;;; DF T$$RUB BIT #RUBP,(R3) ;;;RUBOUT ALREADY IN PROGRESS? BNE 120$ ;;;IF NE YES BIS #RUBP,(R3) ;;;SET RUBOUT IN PROGRESS 60$: SWAB (SP) ;;;SWAP BYTE TO HIGH BYTE MOVB #'\,(SP) ;;;INSERT BACKSLASH ; ; SET UP FOR MULTI-ECHO ; MECHO1: MOV (SP),MBUFR(R3) ;;;SET FOR MULTI-ECHO OF 1-2 BYTES MOV R3,(SP) ;;;CALCULATE ADDR OF MULTI-ECHO BUFFER ADD #MBUFR,(SP) ;;; 180$: MOV (SP)+,MEBUF(R3) ;;;INSERT ADDRESS OF MULTI-ECHO BUFFER JMP OUTPT1 ;;;START OUTPUT 185$: CMPB #25,(SP) ;;;LINE DELETE? BNE 75$ ;;;IF NE NO ; ; LINE DELETE (CONTROL U) ; MOV #CTRLU,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER BIC #RUBP,(R3) ;;;CLEAR RUBOUT IN PROGRESS FLAG MOV U.CNT(R5),RMBYT(R3) ;;;RESET REMAINING BYTES IN BUFFER ;;; ALSO CLEARS FINAL BYTE INDICATOR MOV STRBF(R3),CURBF(R3) ;;;RESET ADDRESS IN BUFFER .IF DF T$$UTB&M$$MGE MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF BUFFER .ENDC .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;IN NO ECHO MODE? BNE 355$ ;;;IF NE YES -- DON'T TYPE ^U .ENDC BR 180$ ;;;GO SET MULTI-ECHO BUFFER 75$: CMPB #33,(SP) ;;;ESCAPE OR ALTMODE BNE 85$ ;;;IF NE NO ; ; ALTMODE CODE 33 (ESCAPE) AND POSSIBLY 37, 175, AND 176 ; .IF DF T$$ESC BIT #WESC,ATERS(R3) ;;;TASK WANTS ESCAPE SEQUENCES? BEQ 81$ ;;;IF EQ NO BIT #U2.ESC,U.CW2(R5) ;;;TERMINAL OUTPUTS ESCAPE SEQUENCES? BEQ 81$ ;;;IF EQ NO BIS #ESCS,ATERS(R3) ;;;SHOW IN AN ESCAPE SEQUENCE CLR SYNTX(R3) ;;;SHOW HAVE ONLY THE ESC BR 37$ ;;;SAVE ESC IN BUFFER .ENDC 81$: CLRB (SP) ;;;SET TO ECHO ZERO BYTE MOVB #33,FNBYT(R3) ;;;SET FINAL BYTE BR 115$ ;;;SET END OF LINE SEEN 85$: ;;;REF LABEL .IF DF T$$ESC BIT #U2.ESC,U.CW2(R5) ;;;TERMINAL OUTPUTS ESCAPE SEQUENCES? BEQ 87$ ;;;IF EQ NO CMPB #37,(SP) ;;;NEW "ESCAPE"? BEQ 81$ ;;;IF EQ YES 87$: ;;;REF LABEL .ENDC .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;TERMINAL IN LOWER CASE? BNE 88$ ;;;IF NE YES -- 175&176 ARE CHARS .ENDC CMPB #175,(SP) ;;;ALTMODE? BLOS 81$ ;;;IF LOS YES 88$: CMPB #32,(SP) ;;;CONTROL Z? BNE 89$ ;;;IF NE NO ; ; CONTROL Z (END OF FILE) ; MOVB #IE.EOF&377,FNBYT(R3) ;;;SET CONTROL Z FLAG BIS #EOLS,(R3) ;;;SET END OF LINE SEEN .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;IN NO ECHO MODE? BNE 48$ ;;;IF NE YES -- DON'T TYPE ^Z .ENDC MOV #CTRLZ,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER BR 180$ ;;; 89$: CMPB #15,(SP) ;;;CARRIAGE RETURN? BNE 36$ ;;;IF NE NO ; ; CARRIAGE RETURN ; MOVB (SP),FNBYT(R3) ;;;SET FINAL BYTE 115$: BIS #EOLS,(R3) ;;;SET END OF LINE SEEN .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;SHOULD ECHO CR OR ESC? BNE 48$ ;;;IF NE NO .ENDC 120$: BIT #LFCT,(R3) ;;;ANY LINE FEEDS WAITING? BNE MECHO1 ;;;IF NE YES JMP ECHOB ;;;ECHO BYTE ON STACK ; ; STORE BYTE IN INPUT BUFFER ; 36$: ;;;REFERENCE BYTE .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;CASE CONVERSION ENABLED? BNE 37$ ;;;IF NE NO CMPB #173,(SP) ;;;UPPER END GRAPHICS? BLOS 37$ ;;;IF LOS YES CMPB #141,(SP) ;;;LOWER CASE LETTER? BHI 37$ ;;;IF HI NO BICB #40,(SP) ;;;CONVERT TO UPPER CASE .ENDC 37$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE MOV (SP),-(SP) ;;;COPY UNKNOWN CHARCTER CALL $PTBYT ;;;PUT IT INTO TASK'S BUFFER .IFF MOVB (SP),@CURBF(R3) ;;;STORE BYTE IN BUFFER .ENDC DECB RMBYT(R3) ;;;ANY REMAINING SPACE IN BUFFER BNE 39$ ;;;IF NE YES BIS #EOLS,(R3) ;;;TERMINATE ON BYTE COUNT BR 40$ ;;; 39$: INC CURBF(R3) ;;;INCREMENT BUFFER ADDRESS 40$: ;;;REF LABEL .IF DF T$$RST BITB #SS.RST,S.STS(R4) ;;;READ WITH SPECIAL TERMINATORS? BNE 46$ ;;;IF NE YES .ENDC 45$: ;;;REF LABEL .IF DF T$$ESC BIT #ESCS,ATERS(R3) ;;;DOING AN ESCAPE SEQUENCE? BNE 200$ ;;;IF NE YES .ENDC 450$: ;;;REF LABEL .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;SUPPOSED TO ECHO CHARACTER? BNE 48$ ;;;IF NE NO .ENDC .IF DF T$$30P BIS #ECHO,ATERS(R3) ;;;SHOW ECHOING CHAR .ENDC .IF DF T$$SYN BIC #UOFF!UPND,ATERS(R3) ;;;IGNORE PREVIOUS CONTROL/S .ENDC BIT #RUBP,(R3) ;;;RUBOUT IN PROGRESS? BEQ 120$ ;;;IF EQ NO 451$: BIC #RUBP,(R3) ;;;CLEAR RUBOUT IN PROGRESS .IF DF T$$ESC JMP 60$ ;;; .IFF BR 60$ ;;; .ENDC .IF DF T$$RST ; ; TERMINATE READ ON A SPECIAL TERMINATOR. A SPECIAL TERMINATOR IS ; FROM A LOWERCASE TERMINAL - ANY CHAR OUTSIDE OF [40,176] ; FROM OTHER TERMINALS - ANY CHARACTER OUTSIDE OF [40,174] ; 46$: CMPB (SP),#40 ;;;CHARACTER LOWER THAN RANGE? BLO 47$ ;;;IF LO YES -- IT IS A TERMINATOR CMPB (SP),#174 ;;;CHARACTER WITHIN RANGE? BLOS 450$ ;;;IF LOS YES -- TREAT IT NORMALLY .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;TERMINAL SET TO LOWER CASE? BEQ 47$ ;;;IF EQ NO -- ALT DECISION IS OKAY CMPB (SP),#177 ;;;CHAR IN EXPANDED ASCII RANGE? BLO 450$ ;;;IF LO YES .ENDC 47$: BIS #EOLS,(R3) ;;;SHOW TERMINATOR FOUND ; NEXT INSTRUCTION IMPLIES 7-BIT CHARACTERS (SEE AFTER INPT2) MOVB (SP),FNBYT(R3) ;;;STORE FINAL BYTE FOR I/O STATUS INCB RMBYT(R3) ;;;READJUST BYTE COUNT .ENDC ;;; DF T$$RST .IF DF T$$ESC!T$$RNE!T$$RST!T$$TRW 48$: TST (SP)+ ;;;REMOVE CHARACTER FROM STACK JMP INPPT ;;;DO NOT ECHO CHARACTER .ENDC .IF DF T$$ESC ;+ ; GATHER AN ESCAPE SEQUENCE ; ; IN GENERAL, AN ESCAPE SEQUENCE IS ; ESC IC FC ; WHERE ESC = 33 ; IC = ZERO OR MORE INTERMEDIATE CHARACTERS (40-57) ; FC = FINAL CHARACTER (60-176) ; THE FOLLOWING VIOLATIONS OF THAT RULE ARE ALSO ESCAPE SEQUENCES: ; ESC ; IC FC ; ESC ? IC FC ; ESC O IC SFC ; ESC [ PC!IC SFC ;TMM012 .IF DF ESCPIC ; ESC P IC FC .ENDC ; ESC Y CO CO ; WHERE ; = 73 ; ? = 77 ; O = 117 ; P = 120 ; Y = 131 ; SFC = SPECIAL FINAL CHARACTER (100-176) ; CO = BIASED 40 COORDINATE (40-176) ; PC = PARAMETER CHARACTER (60-77) ;TMM012 ; AN ESCAPE SEQUENCE TERMINATES A SOLICITED READ. A SYNTACTICALLY ; CORRECT ESCAPE SEQUENCE RETURNS A STATUS OF IS.ESQ IN THE IOSB ; AND THE ESCAPE SEQUENCE IN THE INPUT BUFFER. A SYNTACTICALLY ; INCORRECT ESCAPE SEQUENCE (RECEPTION OF A CHARACTER NOT IN THE ; LEGAL RANGE OF THE NEXT EXPECTED CHARACTER) RETURNS IE.IES ; (ILLEGAL ESCAPE SEQUENCE) IN THE IOSB AND THE INCORRECT ESCAPE ; SEQUENCE IN THE INPUT BUFFER. IF THE INPUT BUFFER IS FILLED BEFORE ; A FINAL CHARACTER IS RECEIVED, IE.PES (PARTIAL ESCAPE SEQUENCE) ; IS RETURNED. IF A RUBOUT (177) IS RECEIVED, THE PARTIAL ESCAPE ; SEQUENCE IS ERASED FROM THE INPUT BUFFER AND ESCAPE SEQUENCE ; RECOGNITION MODE IS EXITED. ;- 200$: MOV SYNTX(R3),R4 ;;;GET RULE TO HANDLE CHARACTER BNE 210$ ;;;IF NE HAVE A RULE MOV #SYNTAB,SYNTX(R3) ;;;GET RULE FOR 2ND CHARACTER 204$: BIT #EOLS,(R3) ;;;PARTIAL SEQUENCE FILLS BUFFER? BNE 245$ ;;;IF NE YES BIT #RUBP,(R3) ;;;RUBOUT IN PROGRESS? BEQ 225$ ;;;IF EQ NO MOV U.SCB(R5),R4 ;;;RESTORE R4 CLR (SP) ;;;FAKE OUT RUBOUT PROCESSING BR 451$ ;;; 210$: CMPB #37,(SP) ;;;CHAR IN RANGE 0 -> 37? BGE 240$ ;;;IF GE YES -- SYNTAX VIOLATION CMPB #177,(SP) ;;;CHAR A DEL? BEQ 250$ ;;;IF EQ YES -- FORGET ESCAPE SEQUENCE 215$: CMPB (SP),(R4)+ ;;;CHAR LESS THAN LOW VALUE OF RANGE? BLO 230$ ;;;IF LO YES -- TRY NEXT RANGE CMPB (SP),(R4)+ ;;;CHAR GREATER THAN RANGE'S HIGH VALUE? BHI 232$ ;;;IF HI YES -- NO MATCH MOV (R4),SYNTX(R3) ;;;SAVE NEXT SYNTAX RULE BNE 204$ ;;;IF NE SEQUENCE NOT COMPLETED COMB FNBYT(R3) ;;;SET A -1 TO GET IS.ESQ 220$: BIS #EOLS,(R3) ;;;SHOW BUFFER COMPLETE 222$: BIC #ESCS,ATERS(R3) ;;;SHOW OUT OF ESCAPE SEQUENCE 225$: MOV U.SCB(R5),R4 ;;;RESTORE R4 BR 48$ ;;;CLEAN UP STACK AND LEAVE WITHOUT ;;; ECHOING 230$: INC R4 ;;;BUMP PAST TOP OF RANGE 232$: TST (R4)+ ;;;TESTED ALL RANGES OF RULE? BNE 215$ ;;;IF NE NO -- CHECK THE NEXT 240$: MOVB #IE.IES&377,FNBYT(R3) ;;;SAVE ESCAPE ERROR STATUS BR 220$ ;;;GET OUT 245$: MOVB #IE.PES&377,FNBYT(R3) ;;;PARTIAL ESCAPE SEQUENCE STATUS BR 220$ ;;; ; ; IGNORE THE PARTIAL ESCAPE SEQUENCE AND GET OUT OF ESCAPE SEQUENCE ; MODE ; 250$: TSTB RMBYT(R3) ;;;DEL FILLED BUFFER? BNE 252$ ;;;IF NE NO INC CURBF(R3) ;;;MAKE UP FOR NOT BUMPING CURBF AT 39$ 252$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE DEC U.BUF+2(R5) ;;;POINT AT LAST CHAR IN BUFFER CALL $GTBYT ;;;PUT IT ONTO STACK DEC U.BUF+2(R5) ;;;POINT WHERE LAST CHAR CAME FROM DEC CURBF(R3) ;;;MAKE BOTH POINTERS AGREE .IFF DEC CURBF(R3) ;;;POINT AT LAST CHAR IN BUFFER MOVB @CURBF(R3),-(SP) ;;;PUT IT ONTO STACK .ENDC INCB RMBYT(R3) ;;;SHOW INCREASED ROOM IN BUFFER CMPB #33,(SP)+ ;;;FOUND FIRST CHAR OF ESCAPE SEQUENCE? BNE 252$ ;;;IF NE NO BIC #EOLS,(R3) ;;;SHOW ARE NOT AT END OF LINE BR 222$ ;;;LEAVE .ENDC ;;; DF T$$ESC .DSABL LSB .SBTTL MISCELLANY ;+ ; TTCAN - CANCEL I/O OPERATION ENTRY POINT (FORCE I/O COMPLETE) ; ; AT ENTRY: ; R0 -> ADDR OF ACTIVE I/O PACKET ; R1 -> ADDR OF TCB OF CURRENT TASK ; R3 -> CONTROLLER INDEX ; R4 -> ADDR OF SCB ; R5 -> ADDR OF UCB ; INTERRUPT PRIORITY=THAT OF DEVICE ;- .ENABL LSB .IIF NE MODE-100000, .ERROR MODE TTCAN: MOV U.CNT+2+STATS(R5),R2 ;;;UNIT BUSY ON INPUT? BMI 10$ ;;;IF MI NO BIT #SOLI,R2 ;;;SOLICITED INPUT? BEQ 40$ ;;;IF EQ NO 10$: CMP R1,I.TCB(R0) ;;;REQUEST FOR CURRENT TASK? BNE 40$ ;;;IF NE NO 15$: BIT #EOLS,R2 ;;;END OF LINE SEEN? .IF DF T$$SYN BEQ 18$ ;;;IF EQ NO .IIF NE UPND-200, .ERROR UPND TSTB U.CNT+2+ATERS(R5) ;;;IS CHARACTER THAT SET EOLS ;;;BEING HELD UP? BPL 40$ ;;;IF PL NO .IFF BNE 40$ ;;;IF NE END OF LINE SEEN .ENDC .IIF NE MODE-100000, .ERROR MODE 18$: TST R2 ;;;INPUT OR OUTPUT? BMI 20$ ;;;IF MI OUTPUT BISB #US.ECH,U.STS(R5) ;;;DISABLE INPUT CHARACTER HANDLING 20$: MOVB #IE.ABO&377,U.CNT+2+FNBYT(R5) ;;;SETUP FOR ABORT STATUS BIS #EOLS,U.CNT+2+STATS(R5) ;;;SET END OF LINE SEEN MOVB #1,S.CTM(R4) ;;;SET TIMEOUT COUNT TO 1 .IF DF T$$BTW!T$$ESC!T$$RPR!T$$SYN BIC #ESCS!RPRM!XOFF!UPND,U.CNT+2+ATERS(R5) ;;; ;;; CLEAR STATUS BITS THAT MAY BE SET .ENDC 40$: RETURN ;;; ;  ; ROUTINE EXECUTED WHENEVER A DM11 OR DZ11 LINE HANGS UP. ; CANCEL I/O AND SAY "BYE" IF NECESSARY ON A MULTIUSER SYSTEM. ; .IF DF D$$M11!D$$ZMD TTHUP: MOV R2,-(SP) ;;;SAVE R2 CALL 80$ ;;;CANCEL I/O IF UNIT IS BUSY MOV #CTRLU-1,U.CNT+2+MEBUF(R5) ;;;SUPPRESS MULTIECHO .IF DF T$$ACR!T$$BTW!T$$CCA!T$$ESC!T$$HLD!T$$SYN!T$$30P T3=CCPN!BAKS!FKCR!ECHO!UPND!CHAR!WESC!CCON!MCTR!UOFF BIC #T3,U.CNT+2+ATERS(R5) ;CLEAR ADDITIONAL TERMINAL STATUS .ENDC .IF DF M$$MUP .IF DF D$$M11 MTPS #0 ;;;DROP PRIORITY .ENDC BIT #U2.LOG,U.CW2(R5) ;TERMINAL LOGGED ON? BNE 70$ ;IF NE NO MOV R3,-(SP) ;SAVE REGISTERS NEEDED MOV R1,-(SP) ; MOV R0,-(SP) ; MOV #M$$CRB,R1 ;SET SIZE OF MCR COMMAND LINE CALL $ALOCB ;ALLOCATE MCR COMMAND LINE BCS 50$ ;IF CS ALLOCATION FAILURE MOV R0,R1 ;COPY POINTER TO BUFFER TST (R0)+ ;POINT TO UCB WORD MOV R5,(R0)+ ;PASS UCB POINTER MOV #"BY,(R0)+ ;STICK IN BYE COMMAND MOV (PC)+,(R0)+ ; .ASCII /E/<15> ; .IF DF M$$CLI MOV $MCRPT,R0 ;POINT TO MCR'S TCB CALL $QCLIL ;AND QUEUE "BYE" COMMAND .IFF ;M$$CLI CALL $QMCRL ;QUEUE THE COMMAND .ENDC ;M$$CLI .IF DF D$$ZMD CLC ;SHOW A SUCCESSFUL FORAY .ENDC .IF DF D$$M11 BR 60$ ; .ENDC 50$: ;REF LABEL .IF DF D$$M11&D$$ZMD BIT #U2.DZ1,U.CW2(R5) ;THIS LINE ON A DZ11? BNE 60$ ;IF NE YES .ENDC .IF DF D$$M11 BISB #US.CRW,U.STS(R5) ;TRY AGAIN IN 4 SECONDS MOVB #1,U.CNT+2+DMTIM(R5) ;SET TIMEOUT VALUE TO 4 .ENDC 60$: MOV (SP)+,R0 ;RESTORE REGISTERS MOV (SP)+,R1 ; MOV (SP)+,R3 ; .ENDC ; DF M$$MUP 70$: MOV (SP)+,R2 ;;;RESTORE R2 RETURN ;;; ; NEXT INSTRUCTION DEPENDS ON US.BSY=200 80$: TSTB U.STS(R5) ;;;UNIT BUSY? BPL 40$ ;;;IF PL NO - RETURN CLRB U.CNT+2+INPRQ(R5) ;;;CLEAR UNSOLICITED INPUT PENDING FLG MOV U.CNT+2+STATS(R5),R2 ;;;TERMINAL STATUS WORD INTO R2 BR 15$ ;;;BRANCH INTO CANCEL ROUTINE .ENDC .DSABL LSB ; ; GETBF - GET AN INPUT BUFFER AND SETUP TERMINAL CONTROL BLOCK ; ; WHEN ENTERED AT GETBF ; ; R5 -> UCB ; ; DESTROYS R0, R1, R2 ; SETS R3 = UCB+U.CNT+2 ; PRESERVES R4, R5, SP ; ; WHEN ENTERED AT GETBF2 ; ; R1 = NUMBER OF BYTES TO ALLOCATE ; R5 -> UCB ; ; DESTROYS R0, R2 ; SETS R3 = UCB+U.CNT+2 ; PRESERVES R4, R5, SP ; ; EITHER ENTRY POINT GETS A BUFFER FROM THE EXEC CORE POOL AND ; MAKES THE UCB POINT TO IT ; .ENABL LSB GETBF: MOV #M$$CRB,R1 ;SET LENGTH OF BUFFER REQUIRED .IF DF T$$VBF CMP #M$$CRI,U.CNT(R5) ;BUF=SCREEN SIZE TOO MUCH FOR MCR? BGE GETBF2 ;IF GE NO MOV #M$$CRI,U.CNT(R5) ;GIVE MCR ONLY WHAT IT CAN HANDLE .IFTF GETBF2: CALL $ALOCB ;ALLOCATE A CORE BLOCK BCS 20$ ;IF CS NO BLOCK AVAILABLE .IFTF ;TMM011 CLR (R0)+ ;CLEAR FIRST WORD OF BUFFER ;TMM011 MOV R1,(R0)+ ;SAVE LENGTH OF BUFFER ;**-3 ;**-6 .IF DF T$$UTB&M$$MGE CLR U.BUF(R5) ;MAKE "TASK BUFFER POINTERS" POINT AT MOV R0,U.BUF+2(R5) ; THE NEW EXECUTIVE BUFFER. BUFFER TO ; TASK TRANSFER DONE BY $FINBF WHICH ; GETS MAPPING FROM I/O PACKET. .ENDC INPINI: MOV R5,R3 ;COPY UCB ADDRESS ADD #U.CNT,R3 ;POINT TO NUMBER OF BYTES REQUESTED .IFT ; DF T$$VBF CMP #255.,(R3) ;BUFFER TOO BIG FOR RMBYT? BHIS 10$ ;IF HIS NO MOV #255.,(R3) ;CUT IT DOWN TO SIZE .IFF ; DF T$$VBF CMP #M$$CRI,(R3) ;MORE THAN ONE BUFFER? BHIS 10$ ;IF HIS NO MOV #M$$CRI,(R3) ;ALLOW ONLY ONE BUFFER'S WORTH .ENDC ; DF T$$VBF 10$: MOV (R3)+,-(SP) ;SET LENGTH OF INPUT REQUEST BIC #MODE!LFCT!CRTY!EOLS!RUBP!SOLI!CTLO!FLCT,(R3)+ ;CLEAR STATUS MOV R0,(R3)+ ;SET STARTING BUFFER ADDRESS MOV (SP)+,(R3)+ ;SET SPACE REMAINING IN BUFFER MOV R0,(R3) ;SET CURRENT BUFFER ADDRESS SUB #CURBF,R3 ;POINT TO START OF CONTROL BLOCK .IF DF T$$ESC BIC #ESCS,ATERS(R3) ;CLEAR STATUS .ENDC 20$: RETURN ; .DSABL LSB ;TMM011 .IF DF C$$CKP&T$$BUF ;TMM011 ;TMM011 ; ;TMM011 ; BUFFER DEALLOCATION ROUTINE CALLED FROM $FINBF WITH ;TMM011 ; ;TMM011 ; R0 -> BUFFER TO BE DEALLOCATED ;TMM011 ; ;TMM011 TTDEA: ;TMM011 MOV 2(R0),R1 ;GET SIZE OF BUFFER ALLOCATED ;TMM011 CALL $DEACB ;DEALLOCATE CORE BLOCK ;TMM011 RETURN ;TMM011 .IF NDF A$$BIO ;TMM011 ;**-1 ;TMM011 ;+ ;TMM011 ; **-$TSTBF-TEST IF I/O BUFFERING CAN BE INITIATED ;TMM011 ; ;TMM011 ; THIS ROUTINE DETERMINES IF A GIVEN I/O REQUEST IS ELIGIBLE FOR I/O ;TMM011 ; BUFFERING, AND IF SO (FOR SYSTEMS THAT SUPPORT SYSTEM-CONTROLLED ;MSH046 ;TMM011 ; PARTITIONS) IT STORES THE PCB ADDRESS OF THE REGION INTO WHICH ;MSH046 ;TMM011 ; THE TRANSFER IS TO OCCUR IN I.PRM+16 OF THE I/O PACKET. ;MSH046 ;TMM011 ; ;**-2 ;TMM011 ; INPUTS: ;TMM011 ; ;TMM011 ; R3=ADDRESS OF I/O PACKET FOR I/O REQUEST ;TMM011 ; ;TMM011 ; OUTPUTS: ;TMM011 ; ;TMM011 ; R3 IS PRESERVED. ;TMM011 ; ;TMM011 ; C=0 IF I/O BUFFERING CAN BE INITIATED. ;TMM011 ; ;TMM011 ; C=1 IF I/O BUFFERING CAN NOT BE INITIATED. ;TMM011 ;- ;TMM011 ;TMM011 $TSTBF::MOV I.TCB(R3),R0 ;GET ADDRESS OF REQUESTOR TCB ;TMM011 SEC ;ASSUME TASK CANNOT BE STOPPED? ;TMM011 BIT #T2.CHK!T2.CKD,T.ST2(R0) ;STOP IT? ;MSH090 ;TMM011 BNE 20$ ;IF NE NO ;**-1 ;TMM011 ;MSH046 ;TMM011 .IF DF M$$MGE&D$$YNM ;MSH046 ;TMM011 ;MSH046 ;TMM011 SAVNR ;SAVE R4 AND R5 ;TMM011 MOV T.PCB(R0),R1 ;GET ADDRESS OF REQUESTER HEADER ;TMM011 MOV P.HDR(R1),R1 ;  ;TMM011 MOV H.WND(R1),R1 ;POINT TO NUMBER OF WINDOW BLOCKS ;TMM011 MOV (R1)+,R2 ;GET COUNT OF WINDOWS ;TMM011 10$: SEC ;ASSUME NO MORE WINDOWS ;TMM011 DEC R2 ;ANY MORE WINDOWS TO EXAMINE? ;TMM011 BLT 20$ ;IF LT NO, DON'T CHECKPOINT ;TMM011 MOV (R1)+,R4 ;GET ADDRESS OF DESCRIPTOR PCB ;TMM011 BEQ 30$ ;IF EQ WINDOW NOT MAPPED ;TMM011 MOV (R1)+,-(SP) ;GET LOW VIRTUAL ADDRESS ;TMM011 MOV (R1)+,R5 ;GET HIGH VIRTUAL ADDRESS ;TMM011 SUB (SP),R5 ;CALCULATE NUMBER OF BYTES MINUS 1 ;TMM011 SUB #77,R5 ;REDUCE TO ACTUAL NUMBER OF BYTES - 64B ;TMM011 ASL R5 ;CONVERT TO 32W BLOCKS ;TMM011 ROL R5 ; ;TMM011 ROLB R5 ; ;TMM011 SWAB R5 ; ;TMM011 MOV P.REL(R4),(SP) ;GET RELOCATION BIAS OF PCB ;TMM011 ;TMM011 ;TMM011 .IF DF P$$LAS!A$$HDR ;MSH096 ;TMM011 ;**-1 ;TMM011 ADD W.BOFF-W.BATT(R1),(SP) ;ADD IN OFFSET IN PARTITION ;TMM011 ;TMM011 .ENDC ;TMM011 ;TMM011 ;TMM011 ADD (SP),R5 ;CALCULATE HIGHEST 32W BLOCK ;TMM011 ADD #W.BLGH-W.BATT,R1 ;POINT TO NEXT DESCRIPTOR ;TMM011 CMP I.PRM(R3),(SP)+ ;TRANSFER IN THIS PARTITION? ;TMM011 BLO 10$ ;IF LO NO ;TMM011 CMP R5,I.PRM(R3) ;TRANSFER IN THIS PARTITION? ;TMM011 BLO 10$ ;IF LO NO ;TMM011 MOV R4,I.PRM+16(R3) ;STORE PCB ADDRESS IN I/O PACKET ;TMM011 ;MSH046 ;TMM011 .IFF ;M$$MGE&D$$YNM ;MSH046 ;TMM011 ;MSH046 ;TMM011 CLC ;I/O BUFFERING CAN BE INITIATED ;MSH046 ;TMM011 ;MSH046 ;TMM011 .IFTF ;MSH046 ;TMM011 ;MSH046 ;TMM011 20$: RETURN ; ;TMM011 ;MSH046 ;TMM011 .IFT ;MSH046 ;TMM011 ;MSH046 ;TMM011 30$: ADD #W.BLGH-W.BLVR,R1 ;POINT TO NEXT WINDOW BLOCK ;TMM011 BR 10$ ; ;MSH046 ;TMM011 ;MSH046 ;TMM011 .IFTF ;MSH046 ;TMM011 ;**-1 ;TMM011 ;TMM011 ;+ ;TMM011 ; **-$INIBF-INITIATE I/O BUFFERING ;TMM011 ; ;TMM011 ; THIS ROUTINE INITIATES I/O BUFFERING BY DOING THE FOLLOWING: ;TMM011 ; ;TMM011 ; 1. DECREMENT THE TASK'S I/O COUNT. ;TMM011 ; 2. INCREMENT THE TASK'S BUFFERED I/O COUNT. ;MSH046 ;TMM011 ; 3. INITIATE CHECKPOINTING IF A REQUEST IS PENDING. ;MSH046 ;TMM011 ; ;**-6 ;TMM011 ; INPUTS: ;TMM011 ; ;TMM011 ; R3=ADDRESS OF I/O PACKET FOR I/O REQUEST. ;TMM011 ; ;TMM011 ; OUTPUTS: ;TMM011 ; ;TMM011 ; R3 IS PRESERVED. ;TMM011 ;-  ;TMM011 ;TMM011 $INIBF::MOV R5,-(SP) ;SAVE R5 ;MSH046 ;TMM011 MOV I.TCB(R3),R5 ;POINT TO ISSUING TASK'S TCB ;MSH046 ;TMM011 INCB T.TIO(R5) ;TALLY THE BUFFERED I/O ;MSH046 ;TMM011 DECB T.IOC(R5) ;ADJUST OUTSTANDING I/O REQUEST COUNT ;MSH046 ;TMM011 ;MSH046 ;TMM011 .IFT ;MSH046 ;TMM011 ;MSH046 ;TMM011 MOV I.PRM+16(R3),R1 ;GET PCB ;**-4 ;TMM011 SUB P.REL(R1),I.PRM(R3) ;CONVERT TO RELATIVE RELOCATION BIAS ;TMM011 ;MSH046 ;TMM011 .ENDC ;M$$MGE&D$$YNM ;MSH046 ;TMM011 ;**-1 ;TMM011 .IF DF D$$ISK&C$$CKP ;TMM011 ;TMM011 BIT #TS.CKR,T.STAT(R5) ;CHECKPOINT REQUEST PENDING? ;MSH041 ;TMM011 BEQ 20$ ;IF EQ NO ;**-1 ;TMM011 BIC #TS.CKR,T.STAT(R5) ;CLEAR CHECKPOINT REQUEST ;MSH041 ;TMM011 MOV R5,R1 ;COPY TCB ADDRESS ;MSH041 ;TMM011 MOV R3,-(SP) ;SAVE PACKET ADDRESS ;MSH041 ;TMM011 ;TMM011 .IF DF D$$YNM&D$$SHF ;TMM011 ;TMM011 MOV R5,-(SP) ;SAVE TCB ADDRESS ;TMM011  ;TMM011 .IFTF ;TMM011 ;TMM011 CALL $ICHKP ;INITIATE CHECKPOINT OF PCB ;**-3 ;TMM011 ;TMM011 .IFT ;TMM011 ;TMM011 MOV (SP)+,R5 ;RESTORE TCB ADDRESS ;TMM011 TSTB T.IOC(R5) ;I/O COUNT NOW ZERO? ;TMM011 BNE 15$ ;IF NE NO ;TMM011 MOV T.PCB(R5),R0 ;GET TASK'S PCB ADDRESS ;TMM011 BIT #PS.LIO,P.STAT(R0) ;CLEAR LONG I/O BIT ;TMM011 CALL $NXTSK ;REALLOCATE PARTITION ;TMM011 ;TMM011 .ENDC ;TMM011  ;TMM011 15$: MOV (SP)+,R3 ;RESTORE PACKET ADDRESS IN R3 ;MSH046 ;TMM011 ;**-1 ;TMM011 .ENDC ;TMM011 ;TMM011 20$: MOV (SP)+,R5 ;RESTORE R5 ;MSH046 ;TMM011 RETURN ; ;**-2 ;TMM011 ;TMM011 ;+ ;TMM011 ; **-$QUEBF-QUEUE BUFFERED I/O FOR COMPLETION ;TMM011 ; ;TMM011 ; THIS ROUTINE QUEUES A SPECIAL ENTRY TO A TASK'S AST QUEUE TO COMPLETE ;TMM011 ; A BUFFERED I/O REQUEST THE NEXT TIME THE TASK IS SCHEDULED. IT ALSO ;TMM011 ; DECREMENTS THE TASK'S BUFFERED I/O COUNT. ;MSH046 ;TMM011 ; ;**-1 ;TMM011 ; NOTE: THIS ROUTINE IS EQUIVALENT TO CALLING $IOFIN AND IT DOES NOT ;TMM011 ; UNBUSY THE DEVICE. ;TMM011 ; ;TMM011 ; INPUTS: ;TMM011 ; ;TMM011 ; R0=FIRST WORD OF I/O STATUS ;TMM011 ; R1=SECOND WORD OF I/O STATUS ;TMM011 ; R3=ADDRESS OF I/O PACKET ;TMM011 ; ;TMM011 ; OUTPUTS: ;TMM011 ; ;TMM011 ; NONE ;TMM011 ;- ;TMM011 ;TMM011 $QUEBF::MOV R0,I.PRM+6(R3) ;STORE OFFSPRING I/O RETURN STATUS ;TMM011 MOV R1,I.PRM+10(R3) ; ;TMM011 MOV I.TCB(R3),R0 ;PICK UP OFFSPRING TCB ADDRESS ;TMM011 BIC #TS.RDN,T.STAT(R0) ;CLEAR RUNDOWN IN PROG ;TMM011 MOV R0,R2 ;COPY TCB ADDRESS ;TMM011 ADD #T.ASTL,R2 ;POINT TO AST LISTHEAD ;TMM011 MOV (R2),(R3) ;LINK PACKET TO FRONT OF LIST ;TMM011 BNE 10$ ; ;TMM011 MOV R3,2(R2) ; ;TMM011 10$: MOV R3,(R2) ; ;TMM011 MOVB #AK.BUF,A.CBL(R3) ;SET BUFFERED I/O KERNEL AST TYPE ;MSH091 ;TMM011 DECB T.TIO(R0) ;DECREMENT BUFFERED I/O COUNT ;MSH046 ;TMM011 BIT #T2.WFR,T.ST2(R0) ;TASK STOPPED FOR BUFFERED I/O? ;MSH046 ;TMM011 BNE 12$ ;IF NE YES ;MSH046 ;TMM011 CALLR $SETCR ;SET CONDITIONAL SCHEDULE REQUEST ;MSH046 ;TMM011 ;MSH046 ;TMM011 12$: CALLR $EXRQU ;UNSTOP TASK AND RETURN ;MSH046 ;TMM011 ;**-3 ;TMM011 ;**-1 ;TMM011 ;TMM011 .ENDC ;A$$BIO ;TMM011 .ENDC ;C$$CKP&T$$BUF ;TMM011 .SBTTL CONTROLLER-DEPENDENT DATA BASE ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER (UNIT) NUMBER) ; .IF DF D$$L11 CNTBL: .BLKW D$$L11 ;ADDRESS OF UNIT CONTROL BLOCK .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$L11-1 DLTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .ENDC ; DF D$$L11 .IF DF D$$H11 DHTBL: ;REF LABEL N=0 .REPT D$$H11 .WORD UCBTB+N ;POINTER TO DH11 UCB TABLE N=N+34. .ENDR UCBTB: ;REF LABEL .REPT D$$H11 .REPT 16. .WORD 0 ;ADDR OF UCB FOR LINE (PLUGGED AT TTPWF) .ENDR .WORD 0 ;ZERO SENTINEL WORD .ENDR DHCSR: .BLKW D$$H11 ;DH11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$H11-1 DHTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .IF DF D$$M11 DMTBL: ;DM11-BB CSR ADDRESSES .REPT D$$M11 .WORD 0 .ENDR CLKSW: .WORD 0 ;DM11-BB CLOCK SWITCH WORD .IF NDF L$$DRV!LD$TT  .WORD 0,0,0,0,0 ;DM11-BB CLOCK QUEUE CONTROL BLOCK .WORD DMTMO ;DM11-BB TIMER SUBROUTINE ADDRESS .IF DF L$$DRV&M$$MGE .WORD 0 ;WORD FOR APR5 BIAS .ENDC .ENDC ; NDF L$$DRV!LD$TT .ENDC ; DF D$$M11 .ENDC ; DF D$$H11 .IF DF D$$Z11 DZTBL: ;REF LABEL N=0 .REPT D$$Z11 .WORD UCZTB+N ;POINTER TO DZ11 UCB TABLE (INDEXED BY ; CONTROLLER NUMBER) .IF DF L$$SI1 .IF DF D$$ZMD N=N+10. .IFF N=N+8. .ENDC .IFF .IF DF D$$ZMD N=N+18. .IFF N=N+16. .ENDC .ENDC .ENDR UCZTB: ;REF LABEL .REPT D$$Z11 .IF NDF L$$SI1 .WORD 0,0,0,0 ;UCB ADDRESS FOR EACH LINE (INDEXED BY .ENDC .WORD 0,0,0,0 ; LINE (UNIT) NUMBER) .IF DF D$$ZMD .WORD 0 .ENDC .ENDR DZCSR: .BLKW D$$Z11 ;DZ11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$Z11-1 DZTMP: .WORD 0 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .IF DF D$$ZMD DZCLKS: .WORD 0 ;DZ11 CLOCK SWITCH WORD .IF NDF L$$DRV!LD$TT .WORD 0,0,0,0,0 ;DZ11 CLOCK QUEUE ENTRY .WORD DZTMO ;DZ11 TIMEOUT ENTRY POINT .IF DF L$$DRV&M$$MGE .WORD 0 ;WORD FOR APR5 BIAS .ENDC .ENDC ; NDF L$$DRV!LD$TT .ENDC ; DF D$$ZMD .ENDC ; DF D$$Z11 .IF DF D$$J11 DJTBL: ;REF LABEL N=0 .REPT D$$J11 .WORD UCJTB+N ;POINTER TO DJ11 UCB TABLE N=N+32. .ENDR UCJTB: ;REF LABEL .REPT D$$J11 .REPT 16. .WORD 0 ;ADDRESS OF LINE'S UCB .ENDR .ENDR DJCSR: .BLKW D$$J11 ;DJ11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$J11-1 DJTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .ENDC ; DF D$$J11 ;+ ; DRIVER DISPATCH TABLE ; ; THE $XYTBL GLOBAL SYMBOLS ARE FOR EASING THE MENTAL BURDEN WHEN ; CREATING LOADABLE USER TERMINAL DRIVERS FOR TEST PURPOSES ;- .IF DF LD$$L $DLTBL:: .ENDC .IF DF LD$$H $DHTBL:: .ENDC .IF DF LD$$J $DJTBL:: .ENDC .IF DF LD$$Z $DZTBL:: .ENDC ;TMM011 .IF DF C$$CKP&T$$BUF  ;TMM011 ;TMM011 .WORD TTDEA ;TMM011 ;TMM011 .ENDC ;TMM011 ;TMM011 .IF NDF LD$$L & LD$$H & LD$$J & LD$$Z $TTTBL:: .ENDC .IF DF T$$BTW!T$$RPR .WORD TTCHK ;DEVICE INITIATOR ENTRY POINT .IFF .WORD TTINI ;DEVICE INITIATOR ENTRY POINT .ENDC .WORD TTCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD TTOUT ;DEVICE TIMEOUT ENTRY POINT .WORD TTPWF ;POWERFAIL ENTRY POINT .SBTTL CONTROLLER-DEPENDENT OUTPUT INTERRUPT CODE .ENABL LSB ;+ ; **-$DZOUT-DZ11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$Z11 $DZOUT:: ;REF LABEL TTSAV$ DZ,PR5,D$$Z11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER MOVB 1(R4),R5 ;;;GET BYTE CONTAINING LINE NUMBER BIC #177770,R5 ;;;ISOLATE LINE NUMBER ASL R5 ;;;MAKE IT INTO A WORD INDEX MOV R5,-(SP) ;;;SAVE IT ADD R3,R5 ;;;ADDR OF ADDR OF UCB FOR LINE MOV (R5),R5 ;;;ADDR OF UCB FOR LINE MOV (SP)+,R3 ;;;SET R3 TO LINE NUMBER BITB #US.OUT,U.STS(R5) ;;;EXPECT INTERRUPT? BNE 3$ ;;;IF NE YES BICB $BTMSK(R3),4(R4) ;;;SHOW NO DESIRE TO TRANSMIT MOV U.SCB(R5),R4 ;;;SET R4 TO START OF SCB BR 40$ ;;;DONE 3$: MOVB U.CNT+2+DHBUF(R5),6(R4) ;;;TRANSMIT BYTE .IF DF D$$J11 BR 5$ .ENDC .ENDC ;;; DF D$$Z11 ;+ ; **-$DJOUT-DJ11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$J11 $DJOUT:: ;;;REF LABEL TTSAV$ DJ,PR5,D$$J11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER MOV R3,R5 ;;;COPY ADDRESS OF UCB TABLE ADD #7,R4 ;;;POINT TO UNIT NUMBER MOVB (R4),R3 ;;;GET INTERRUPTING UNIT BIC #177760,R3 ;;;CLEAR EXCESS BITS ASL R3 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD R3,R5 ;;;CALCULATE ADDRESS OF UCB ADDRESS MOV (R5),R5 ;;;GET ADDRESS OF UCB BEQ 40$ ;;;IF EQ NO UCB -- IGNORE INTERRUPT MOVB U.CNT+2+DHBUF(R5),-(R4) ;;;OUTPUT NEXT BYTE BIC $BTMSK(R3),-(R4) ;;;CLEAR BUFFER ACTIVE .ENDC ;;; DF D$$J11 .IF DF D$$J11!D$$Z11 5$: MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS ADD #U.CNT+2+STATS,R3 ;;; .IF DF D$$H11!D$$L11 BR 35$ ;;; .ENDC .ENDC ;;; DF D$$J11!D$$Z11 ;+ ; **-$DHOUT-DH11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$H11 $DHOUT:: ;;;REF LABEL TTSAV$ DH,PR5,D$$H11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER BIC #101077,(R4) ;;;CLEAR CURRENT UNIT AND TRANSMIT INT 10$: MOV (R3)+,R5 ;;;UNIT EXIST? BEQ 40$ ;;;IF EQ NO -- DONE BITB #US.OUT,U.STS(R5) ;;;OUTPUT INTERRUPT EXPECTED? BEQ 20$ ;;;IF EQ NO TST 10(R4) ;;;ZERO BYTE COUNT? BEQ 30$ ;;;IF EQ YES 20$: INC (R4) ;;;INCREMENT UNIT NUMBER BR 10$ ;;;TRY AGAIN 30$: MOV R4,-(SP) ;;;SAVE R4 AND R3 MOV R3,-(SP) ;;; MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ;;; CALL 50$ ;;;FINISH OUTPUT PROCESSING MTPS #PR5 ;;;OUTPT MAY RETURN THRU $FORK MOV (SP)+,R3 ;;;RESTORE R3 AND R4 MOV (SP)+,R4 ;;; BR 20$ ;;;GO AGAIN .ENDC ;+ ; **-$DLOUT-DL11 TERMINAL OUTPUT INTERRUPTS ;- .IF DF D$$L11 $DLOUT:: ;;;REF LABEL TTSAV$ DL,PR4,D$$L11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3= R5+U.CNT+2 ;;; SET R4=ADDRESS OF SCB ;;; SET R5=ADDRESS OF UCB .ENDC .IF DF D$$J11!D$$L11!D$$Z11 35$: BITB #US.OUT,U.STS(R5) ;;;OUTPUT INTERRUPT EXPECTED? BNE 50$ ;;;IF NE YES .ENDC 40$: RETURN ;;;IGNORE SPURIOUS INTERRUPTS 50$: BICB #US.OUT,U.STS(R5) ;;;CLEAR OUTPUT INTERRUPT EXPECTED CLRB S.CTM(R4) ;;;DISABLE UNIT TIMEOUT CALLR OUTPT ;;;OUTPUT NEXT BYTE, IF THERE IS ONE .DSABL LSB .SBTTL TERMINAL TIMEOUT ROUTINE ;+ ; TTOUT - TERMINAL DRIVER TIMEOUT ENTRY POINT ; ; ENTERED AT FORK LEVEL WITH ; R5 -> UCB ; R4 -> SCB ; R3 -> CONTROLLER NUMBER ; R2 -> CSR ; R0 -> IE.DNR ; INTERRUPT PRIORITY = THAT OF DEVICE ; ; EXITS BY GOING TO COMMON CODE AFTER REENABLING INTERRUPTS ON ; DEVICE ;- TTOUT: ;;;REF LABEL .IF DF D$$H11!D$$J11!D$$Z11 MOV U.CW2(R5),R1 ;;;MULTIPLEXED TERMINAL? .IF DF D$$L11 ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 25$ ;;;IF PL NO .ENDC .IF DF D$$H11 .IF DF D$$J11!D$$Z11 ASL R1 ;;;DJ11 TERMINAL? .IF DF D$$J11 ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 23$ ;;;IF MI YES .ENDC .IF DF D$$Z11 TSTB R1 ;;;DZ11 TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DZ1=100 BMI 22$ ;;;IF MI YES .ENDC .ENDC ;;; DF D$$J11!D$$Z11 BIC #1077,(R2) ;;;CLEAR CURRENT UNIT BIS #20100,(R2) ;;;MAKE SURE INTERRUPTS ARE ENABLED BISB U.UNIT(R5),(R2) ;;;SELECT DESIRED UNIT CLR 10(R2) ;;;ZERO BYTE COUNT .IF DF D$$J11!D$$Z11 BR 25$ ;;; .ENDC .IFF ;;; DF D$$H11 .IF DF D$$J11&D$$Z11 ASL R1 ;;;DJ11 TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 23$ ;;;IF NE YES .ENDC .ENDC ;;; DF D$$H11 .IF DF D$$Z11 22$: BIS #40140,(R2) ;;;MAKE SURE INTERRUPTS ENABLED .IF DF D$$J11 BR 25$ ;;; .ENDC .ENDC ;;; DF D$$Z11 .IF DF D$$J11 23$: BIS #40501,(R2) ;;;MAKE SURE INTERRUPTS ARE ENABLED .ENDC .ENDC ;;; DF D$$H11!D$$J11!D$$Z11 25$: BICB #US.OUT,U.STS(R5) ;;;CLEAR OUTPUT INTERRUPT EXPECTED MTPS #0 ;;;ALLOW DEVICE INTERRUPTS CALLR TTOUT1 ; .SBTTL CONTROLLER-DEPENDENT OUTPUT CHAR ROUTINE ; ; OCHAR - OUTPUT A CHARACTER TO A TERMINAL ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; (SP) = CHAR TO OUTPUT ; INTERRUPT PRIORITY = THAT OF OUTPUT DEVICE ; ; EXITS VIA RETURN ; .ENABL LSB OCHAR: ;;;REF LABEL .IF DF T$$SYN BIT #UOFF,U.CNT+2+ATERS(R5) ;;;OUTPUT TURNED OFF? BNE 100$ ;;;IF NE YES .IFTF FCHAR: MOV S.CSR(R4),R3 ;;;GET ADDRESS OF CSR MOVB S.ITM(R4),S.CTM(R4) ;;;ENABLE TIMEOUT .IF DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 TST U.CW2(R5) ;;;MULTIPLEXED TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 90$ ;;;IF PL NO .ENDC MOVB (SP)+,U.CNT+2+DHBUF(R5) ;;;PUT BYTE IN OUTPUT BUFFER MOVB U.UNIT(R5),R4 ;;;GET PHYSICAL UNIT NUMBER .IF DF D$$H11 .IF DF D$$J11!D$$Z11 BIT #U2.DJ1!U2.DZ1,U.CW2(R5) ;;;DJ11 OR DZ11? BNE 83$ ;;;IF NE YES .IFTF BIC #1077,(R3) ;;;CLEAR CURRENT UNIT BIS R4,(R3) ;;;SELECT DESIRED UNIT BIC #60,(R3)+ ;;; ADD #4,R3 ;;;POINT TO CURRENT ADDRESS REGISTER MOV R5,(R3) ;;;CALCULATE ADDRESS OF BYTE BUFFER ADD #U.CNT+2+DHBUF,(R3)+ ;;; MOV #-1,(R3)+ ;;;SET BYTE COUNT TO MINUS ONE .IFT BR 87$ ;;; .ENDC .IFTF ;;; DF D$$H11 .IF DF D$$J11!D$$Z11 83$: ADD #4,R3 ;;;POINT TO BUFFER ACTIVE REGISTER .ENDC 87$: ASL R4 ;;;CONVERT UNIT NUMBER TO WORD INDEX BIS $BTMSK(R4),(R3) ;;;START OUTPUT .IF DF D$$L11 BR 95$ ;;;SET OUTPUT INT EXPECTED AND EXIT .ENDC .ENDC ;;; DF D$$H11 .ENDC ;;; DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 90$: MOVB (SP)+,6(R3) ;;;OUTPUT BYTE BIS #100,4(R3) ;;;ENABLE OUTPUT INTERRUPT .ENDC 95$: BISB #US.OUT,U.STS(R5) ;;;SET OUTPUT INTERRUPT EXPECTED RETURN ;;; .IFT ;;; DF T$$SYN 100$: MOVB (SP)+,U.CNT+2+DHBUF(R5) ;;;SAVE BYTE TO OUTPUT BIS #UPND,U.CNT+2+ATERS(R5) ;;;SET OUTPUT BYTE PENDING RETURN ;;; .ENDC ;;; DF T$$SYN .DSABL LSB .SBTTL CONTROLLER-DEPENDENT INPUT INTERRUPT CODE .ENABL LSB ;+ ; **-$DZINP-DZ11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- .IF DF D$$Z11 $DZINP:: ;;;REF LABEL TTSAV$ DZ,PR5,D$$Z11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$H11!D$$J11 BR 1$ ;;; .ENDC .ENDC ;;; DF D$$Z11 ;+ ; **-$DJINP-DJ11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- .IF DF D$$J11 $DJINP:: ;;;REF LABEL TTSAV$ DJ,PR5,D$$J11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$H11 BR 1$ ;;; .ENDC .ENDC ;;; DF D$$J11 .IF DF D$$H11 ;+ ; **-$DHINP-DH11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- $DHINP:: ;;;REF LABEL TTSAV$ DH,PR5,D$$H11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .ENDC .IF DF D$$H11!D$$J11!D$$Z11 1$: MOV 2(R4),-(SP) ;;;GET NEXT BYTE FROM SILO BPL 5$ ;;;IF PL SILO IS EMPTY MOVB 1(SP),R5 ;;;GET PHYSICAL UNIT NUMBER BIC #177760,R5 ;;;CLEAR EXCESS BITS  ASL R5 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD R3,R5 ;;;ADD BASE ADDRESS OF UCB TABLE MOV (R5),R5 ;;;GET ADDRESS OF UCB BEQ 5$ ;;;IF EQ SPURIOUS INTERRUPT .IF DF D$$M11&D$$H11!D$$ZMD BITB #US.DSB,U.STS(R5) ;;;UNIT DISABLED? BNE 5$ ;;;IF NE YES .ENDC MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ;;; .IF DF D$$L11 BR 2$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$H11!D$$J11!D$$Z11  ;+ ; **-$DLINP-DL11 TERMINAL INPUT INTERRUPT ;- .IF DF D$$L11 $DLINP:: ;;;REF LABEL TTSAV$ DL,PR4,D$$L11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=R5+U.CNT+2 ;;; SET R4=ADDRESS OF SCB ;;; SET R5=ADDRESS OF UCB MOV S.CSR(R4),-(SP) ;;;GET ADDRESS OF CSR ADD #2,(SP) ;;;POINT TO DATA BUFFER REGISTER MOV @(SP)+,-(SP) ;;;GET INPUT BYTE AND ERROR BITS .ENDC 2$: ;;;REF LABEL .IF NDF T$$MIN BIT #60000,(SP) ;;;HAD A HARD ERROR? BNE 5$  ;;;IF NE YES .ENDC .IF DF T$$TRW .IIF NE SS.RAL-200, .ERROR SS.RAL TSTB S.STS(R4) ;;;READ PASS ALL? BMI 3$ ;;;IF MI YES .ENDC BIC #177600,(SP) ;;;CLEAR PARITY BIT AND HIGH BYTE .IF DF T$$HLD!T$$SYN CMPB #23,(SP) ;;;TURN OUTPUT OFF? BEQ 4$ ;;;IF EQ YES CMPB #21,(SP) ;;;TURN OUTPUT ON? BEQ 6$ ;;;IF EQ YES .ENDC .IF DF T$$HLD!T$$SYN CMPB #3,(SP) ;;;CHARACTER A CONTROL C? BEQ 8$ ;;;IF EQ YES .ENDC 3$: CALLR ICHAR .IF DF T$$HLD!T$$SYN ; ; TURN OUTPUT OFF (RECEIVED A XOFF) ; 4$: BIS #UOFF,ATERS(R3) ;;;TURN OUTPUT OFF .IFTF .IF DF T$$MIN .IF DF D$$H11!D$$J11!D$$Z11 5$: TST (SP)+ ;;;NOW IGNORE CHARACTER RETURN ;;;RETURN FROM INTERRUPT .ENDC .IFF ;;; DF T$$MIN 5$: TST (SP)+ ;;;NOW IGNORE CHARACTER RETURN ;;;RETURN FROM INTERRUPT .ENDC .IFT ;;; DF T$$HLD!T$$SYN ; ; TURN OUTPUT ON (RECEIVED A XON) ; 6$: BIC #UOFF,ATERS(R3) ;;;CLEAR HOLD OUTPUT FLAG .IIF NE UPND-200, .ERROR UPND TSTB ATERS(R3) ;;;OUTPUT BYTE PENDING? BPL 5$ ;;;IF PL NO 7$: MOVB DHBUF(R3),(SP) ;;;GET HELD UP BYTE 7000$: BIC #UPND,ATERS(R3) ;;;CLEAR OUTPUT BYTE PENDING FLAG CALLR OCHAR ;;;OUTPUT BYTE .ENDC ;;; DF T$$HLD!T$$SYN .IF DF T$$HLD!T$$SYN ; ; RECEIVED A CONTROL C. IF IN HOLD-SCREEN MODE, GET OUT OF IT. ; IF OUTPUT TURNED OFF, TURN IT ON. IN ANY CASE, GET TO MCR. ; 8$: BIC #UOFF,ATERS(R3) ;;;TURN OUTPUT ON .ENDC .IF DF T$$HLD BIT #U2.HLD,U.CW2(R5) ;;;IN HOLD-SCREEN MODE? .IF DF T$$SYN BEQ 9$ ;;;IF EQ NO .IFF BEQ 3$ ;;;IF EQ NO .ENDC BIS #BAKS!CCPN,ATERS(R3) ;;;FLAG SPECIAL MULTI-ECHO AND ;;; HAVE CONTROL/C BIC #U2.HLD,U.CW2(R5) ;;;SHOW NOT IN HOLD-SCREEN MODE ; ; WANT TO GET OUT OF HOLD-SCREEN MODE (SEND "ESC \" TO TERMINAL AND ; HOPE IT EVENTUALLY PAYS ATTENTION), SEND CHAR HELD UP BY CONTROL/S, ; AND PROMPT WITH "MCR>." ASSUME WE CANNOT IMMEDIATELY KICK TERMINAL ; OUT OF HOLD-SCREEN MODE (THE TERMINAL'S SILO AND THE INTERFACE'S ; DOUBLE BUFFERING PROBABLY HAVE STACKED UP CHARACTERS). SO SEND HELD ; UP CHAR FIRST, BECAUSE IT IS CONVENIENT. BECAUSE CONTROL/C IS ; CONSIDERED BY THE USER TO BE DESTRUCTIVE, HE OR SHE SHOULD NOT BE ; CONCERNED WITH OUR ABUSE OF THE OUTPUT STREAM FLAGS. ; MOV #LEVHSM,MEBUF(R3) ;;;MULTI-ECHO ESCAPE SEQUENCE BIC #LFCT!FLCT,(R3) ;;;CLEAN UP FIELD FOR "MCR>" .IIF NE UPND-200, .ERROR UPND TSTB ATERS(R3) ;;;SOMETHING IN DHBUF? BMI 7$ ;;;IF MI YES TST (SP)+ ;;;CLEAN UP STACK CALLR XITHSM ;;;START SENDING ESCAPE SEQUENCE .ENDC ;;; DF T$$HLD .IF DF T$$SYN .IIF NE UPND-200, .ERROR UPND 9$: TSTB ATERS(R3) ;;;OUTPUT PENDING? BPL 3$ ;;;IF PL NO BIS #CCPN,ATERS(R3) ;;;TRY FOR AN MCR PROMPT BR 7$ ;;; .ENDC .DSABL LSB .SBTTL CONTROLLER-DEPENDENT POWERFAIL CODE ;+ ; TTPWF - POWERFAIL AND LOADED AS LOADABLE DRIVER ENTRY POINT ; ; ENTERED AT FORK LEVEL WITH ; R5 -> UCB ; R4 -> SCB ; R3 = CONTROLLER INDEX ;- TTPWF: MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR .IF DF D$$H11!D$$J11!D$$Z11 MOV U.CW2(R5),R0 ;MULTIPLEXED TERMINAL? .IF DF D$$L11 ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 20$ ;IF PL NO .ENDC MOVB U.UNIT(R5),R1 ;GET PHYSICAL UNIT NUMBER .IF DF D$$H11 ASL R0 ;DJ11 TERMINAL? .IF DF D$$J11 ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 15$ ;IF MI YES .ENDC .IF DF D$$Z11 ; NEXT INSTRUCTION DEPENDS ON U2.DZ1=100 TSTB R0 ;DZ11 TERMINAL? BMI 18$ ;IF MI YES .ENDC TST R1 ;LINE ZERO? BNE 5$ ;IF NE NO MOV #4000,(R2) ;CLEAR SILO, UARTS, AND DH11 CONTROLLER MOV #20100,(R2) ;ENABLE INTERRUPTS 5$: MOV R2,DHCSR(R3) ;SAVE ADDRESS OF DH11 CSR MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS CALL SETLIN ;;;SET LINE PARAMETERS ;TMM035 ASL R1 ;;;CONVERT UNIT TO WORD INDEX ;**-3 ADD DHTBL(R3),R1 ;;;CALCULATE ADDRESS TO STORE UCB ADDRESS MOV R5,(R1) ;;;SAVE ADDRESS OF UCB BICB #US.CRW!US.DSB,U.STS(R5) ;;;ASSUME LOCAL UNIT .IF DF D$$M11 ; NEXT INSTRUCTION DEPENDS ON U2.RMT=U2.DJ1/2 ASL R0 ;;;LOCAL UNIT? BPL 14$ ;;;IF PL YES MOV U.CNT+2+DMCSR(R5),R1 ;;;GET ADDRESS OF DM11-BB CSR MOV @#4,-(SP) ;;;SAVE ADDRESS OF TRAP PC MOV #13$,@#4 ;;;CHANGE SO TRAP WILL COME TO US TST (R1) ;;;LIED ABOUT EXISTENCE OF DM11? MOV (SP)+,@#4 ;;;RESTORE SYSTEM TRAP 4 PC BCS 35$ ;;;IF CS YES (13$ LOWERED ;;; PRIORITY AND SET C) MOV R1,DMTBL(R3) ;;;SAVE ADDRESS OF DM11-BB CSR CALL DMHUP ;;;HANG UP UNIT IF NOT READY MTPS #0 ;;;ALLOW DEVICE INTERRUPTS .IF DF L$$DRV&LD$TT MOV CLKSW,R0 ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV U.DCB(R5),R0 ;POINT AT DCB MOV D.UCB(R0),R0 ;POINT AT FIRST UCB MOV U.SCB(R0),R0 ;POINT AT FIRST SCB ADD #S.DHCK,R0 ;POINT AT CLOCK QUEUE ENTRY MOV #DMTMO,12(R0) ;INSERT SUBROUTINE ENTRY POINT MOV R0,CLKSW ;SAVE POINTER TO CLOCK QUEUE ENTRY .IFF MOV #CLKSW,R0 ;POINT TO CLOCK SWITCH WORD TST (R0) ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV PC,(R0)+ ;INDICATE CLOCK QUEUE ENTRY MADE .ENDC CALLR DMCLK ;INSERT ENTRY IN CLOCK QUEUE ; ; CONTROL GOES TO 13$ IF CSR OF DM11 IS NOT IN PRESENT ADDRESS SPACE ; 13$: MOVB #1,2(SP) ;;;LOWER PRIORITY TO ZERO, SET C ;;; AND DEVESTATE T BIT RTI ;;;BACK TO DH POWERFAIL .ENDC ;;; DF D$$M11 14$: MTPS #0 ;;;ALLOW DEVICE INTERRUPTS .IF DF D$$J11!D$$Z11!D$$L11 BR 35$ ;;; .ENDC .IFF ; DF D$$H11 .IF DF D$$J11&D$$Z11 ASL R0 ;DZ11 TERMINAL? BPL 18$ ;IF PL YES .ENDC .ENDC ; DF D$$H11 .IF DF D$$J11 15$: MOV R2,DJCSR(R3) ;SAVE ADDRESS OF DJ11 CSR ASL R1 ;CONVERT UNIT TO WORD INDEX BNE 17$ ;IF NE NOT LINE ZERO MOV #10,(R2) ;CLEAR SILO, UARTS, AND DJ11 CONTROLLER 16$: BIT #20,(R2) ;CLR COMPLETED? BNE 16$ ;IF NE NO BIS #40501,(R2) ;ENABLE INTERRUPTS 17$: ADD DJTBL(R3),R1 ;CALCULATE ADDRESS TO STORE UCB .IF DF D$$Z11 .IF NDF D$$ZMD BR 192$ ;EXIT COMMONLY .IFF MOV R5,(R1) ;SAVE ADDRESS OF UCB BR 35$ ; .ENDC .IFF ; DF D$$Z11 MOV R5,(R1) ;SAVE ADDRESS OF UCB .IF DF D$$H11!D$$L11 BR 35$ ; .ENDC .ENDC ; DF D$$Z11 .ENDC ; DF D$$J11 .IF DF D$$Z11 18$: MOV R2,DZCSR(R3) ;SAVE ADDR OF DZ11 CSR ASL R1 ;CONVERT UNIT # TO WORD INDEX BNE 191$ ;IF NE NOT FIRST UNIT MOV #20,(R2) ;CLR SILO, UARTS, AND CONTROLLER 19$: BIT #20,(R2) ;CLR DONE YET? BNE 19$ ;IF NE NO BIS #40140,(R2) ;ENABLE INTERRUPTS 191$: ADD DZTBL(R3),R1 ;FORM ADDR TO STORE UCB CALL SETLIN ;SET INITIAL LINE CHARACTERISTICS ;TMM035 192$: MOV R5,(R1) ;SAVE ADDRESS OF UCB ;**-1 .IF DF D$$ZMD .IF DF L$$DRV&LD$TT MOV DZCLKS,R0 ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV U.DCB(R5),R0 ;POINT AT DCB MOV D.UCB(R0),R0 ;POINT AT FIRST UCB MOV U.SCB(R0),R0 ;POINT AT FIRST SCB ADD #S.DZCK,R0 ;POINT AT CLOCK QUEUE ENTRY MOV #DZTMO,12(R0) ;INSERT SUBROUTINE ADDRESS MOV R0,DZCLKS ;SAVE POINTER TO CLOCK QUEUE ENTRY .IFF MOV #DZCLKS,R0 ;POINT AT CLOCK SWITCH WORD TST (R0) ;CLOCK ENTRY ALREADY QUEUED? BNE 35$ ;IF NE YES MOV PC,(R0)+ ;MARK ENTRY AS QUEUED .ENDC CALLR DZCLK ;INSERT ENTRY IN CLOCK QUEUE .IFF .IF DF D$$L11 BR 35$ ; .ENDC .ENDC ; DF D$$ZMD .ENDC ; DF D$$Z11 .ENDC ; DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 20$: MOV R5,CNTBL(R3) ;SAVE ADDRESS OF UCB MOVB 2(R2),R0 ;CLEAR DL11 INPUT DATA BUFFER REGISTER BIS #100,(R2) ;ENABLE RECEIVER INTERRUPTS .ENDC 35$: RETURN .SBTTL MISCELLANEOUS CONTROLLER-DEPENDENT SUBROUTINES .ENABL LSB ; ; DH11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$H11 DHSAV: TTSET$ DH,D$$H11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$Z11!D$$J11!D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$H11 ; ; DZ11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$Z11 DZSAV: TTSET$ DZ,D$$Z11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$J11!D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$Z11 ; ; DJ11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$J11 DJSAV: TTSET$ DJ,D$$J11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$J11 ; ; DL11 TERMINAL SAVE ROUTINE ; .IF DF D$$L11 DLSAV: TTSET$ DL,D$$L11 ;;;SAVE R3 ;;; SET R5=ADDR OF UCB MOV U.SCB(R5),R4 ;;;RETRIEVE ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL ADD #U.CNT+2+STATS,R3 ;;; CONTROL BLOCK .ENDC 20$: CALL @(SP)+ ;;;CALL THE CALLER BACK MOV (SP)+,R3 ;;;RESTORE R3 RETURN ;;;EXIT FROM INTERRUPT .DSABL LSB ;+ ; **-$DM11B-DM11-BB MODEM CONTROL MULTIPLEXER INTERRUPTS ;- .IF DF D$$M11 $DM11B:: ;;;REF LABEL .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$M11-1 MFPS DHTMP ;;;SAVE CONTROLLER NUMBER .IFTF CALL $INTSV,PR5 ;;;SAVE REGISTERS AND SET PRIORITY MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IFT MOV DHTMP,R3 ;;;RETRIEVE SAVED PS WORD BIC #177760,R3 ;;;CLEAR ALL BUT CONTROLLER NUMBER ASL R3 ;;;CONVERT TO WORD INDEX .IFF CLR R3 ;;;SET CONTROLLER NUMBER TO ZERO .ENDC .IFF ;;; NDF L$$DRV!M$$MGE!LD$TT MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IF GT D$$M11-1 MOV R4,R3 ;;;EXEC INTERRUPT ROUTINES PUT ;;; CONTROLLER NUMBER IN R4 .IFF CLR R3 ;;;SET CONTROLLER NUMBER TO ZERO .ENDC .ENDC ;;; NDF L$$DRV!M$$MGE!LD$TT  MOV DMTBL(R3),R4 ;;;GET ADDRESS OF DM11-BB CSR BEQ 50$ ;;;IF EQ SPURIOUS INTERRUPT MOV (R4)+,R5 ;;;GET INTERRUPT STATUS MOV R5,-(SP) ;;;SAVE INTERRUPT STATUS BIC #177760,R5 ;;;CLEAR ALL BUT UNIT NUMBER ASL R5 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD DHTBL(R3),R5 ;;;CALCULATE ADDRESS OF UCB ADDRESS MOV (R5),R5 ;;;GET ADDRESS OF UCB BNE 4$ ;;;IF NE CORRESPONDING DH11 UCB EXISTS TST (SP)+ ;;;REMOVE INTERRUPT STATUS FROM STACK BR 50$ ;;;IGNORE INTERRUPT 4$: BIS #7,(R4) ;;;SET REQUEST SEND+DATA ENABLE+ ;;; RING ENABLE MOV (R4),R2 ;;;GET UNIT STATUS COM R2 ;;;COMPLEMENT UNIT STATUS BIC #1200,-(R4) ;;;REENABLE SCANNING ASL (SP) ;;;RING, CARRIER, CLEAR TO SEND ; EB269 ; EB269 .IF DF XONSIG ; EB269 ; EB269 BIT #,(SP)+ ;;; OR XON SIGNAL? ; EB269 ; EB269 .IFTF ; EB269 ; EB269 BCS 10$ ;;;IF CS RING ;**-1 ; EB269 .IFT ; EB269 ; EB269 BEQ 7$ ;;;IF EQ NOT XON SIGNAL ; EB269 ; EB269 ; ; EB269 ; XON SIGNAL TRANSITION ; EB269 ; ; EB269 ; EB269 BIT #U2.HFF,U.CW2(R5) ;;;IGNORE XON SIGNAL? ; EB269 BEQ 7$ ;;;IF EQ YES ; EB269 BITB #XONBI2,R2 ;;;XON SIGNAL ASSERTED? ; EB269 BEQ 6$ ;;;IF EQ YES ; EB269 BIS #UOFF,U.CNT+2+ATERS(R5) ;;;ACT LIKE GOT AN XOFF ; EB269 BR 7$ ;;; ; EB269 6$: BIC #UOFF,U.CNT+2+ATERS(R5) ;;;ACT LIKE GOT AN XON ; EB269 ; EB269 .IIF NE UPND-200, .ERROR UPND ; EB269 ; EB269 TSTB U.CNT+2+ATERS(R5) ;;;OUTPUT BYTE PENDING? ; EB269 BPL 7$ ;;;IF PL NO ; EB269 MOV R3,-(SP) ;;;SAVE R3 ; EB269 MOVB U.CNT+2+DHBUF(R5),-(SP) ;;;GET HELD UP BYTE ; EB269 BIC #UPND,U.CNT+2+ATERS(R5) ;;;CLEAR OUTPUT BYTE ; EB269 ;;;PENDING FLAG ; EB269 MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS ; EB269 CALL FCHAR ;;;OUTPUT BYTE (DESTROYS R3) ; EB269 MOV (SP)+,R3 ;;;RESTORE R3 ; EB269 ; EB269 .ENDC ; EB269 ; EB269 7$: ;;;REFERENCE LABEL ; EB269 ; ; CARRIER OR CLEAR TO SEND TRANSITION ; MOVB #DMGLTC,U.CNT+2+DMTIM(R5) ;;;ASSUME CARRIER OR CLEAR ; EB266 ;;;TO SEND NOT SET ; EB266 BIT #140,R2 ;;;CARRIER AND CLEAR TO SEND SET? ;**-1 BNE 40$ ;;;IF NE NO BITB #US.DSB,U.STS(R5) ;;;UNIT DISABLED? BEQ 30$ ;;;IF EQ NO BR 20$ ;;;FINISH IN COMMON CODE ; ; RING TRANSITION ; 10$: MOVB #7,U.CNT+2+DMTIM(R5) ;;;ASSUME CARRIER OR CLR TO SEND NOT SET BIT #140,R2 ;;;CARRIER AND CLEAR TO SEND SET? BNE 40$ ;;;IF NE NO 20$: BICB #US.DSB,U.STS(R5) ;;;ENABLE UNIT CALL COPASP ;;;COPY ANSWER BAUD RATE TO CURRENT ;TMM035 ;;;TRANSMIT AND RECEIVE BAUD RATES ;TMM035 MOV DHCSR(R3),R2 ;;;GET ADDRESS OF DH11 CSR ;TMM035 CALL SETLIN ;;;SET NEW LINE CHARACTERISTICS ;TMM035 ; EB267 .IF DF USECDH ; EB267 .IFF ; EB267 ; EB267 BIC #U2.CRT!U2.ESC!U2.HLD!U2.L3S!U2.VT5!U2.LWC,U.CW2(R5) ;;; ;**-12 BIC #U3.UPC,U.CW3(R5) ;;;CLEAR OUT ASR33 TYPE ON ANSWER ;TMM036 MOV #72.,U.CW4(R5) ;;;SET INITIAL BUFFER SIZE ; EB267 .ENDC ; EB267 ; EB267 MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS TSTB S.STS(R4) ;;;IS I/O IN PROGRESS? BNE 30$ ;;;IF NE YES BICB #US.BSY!US.ECH!US.OUT,U.STS(R5) ;;;CLEAR BITS THAT ;;;SHOULD NEVER BE SET 30$: BICB #US.CRW,U.STS(R5) ;;;CLEAR CARRIER WAIT BR 50$ ;;; 40$: BISB #US.CRW,U.STS(R5) ;;;SET CARRIER WAIT 50$: MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; RETURN ;;;EXIT FROM INTERRUPT ; ; SUBROUTINE TO HANG UP A DM11-BB UNIT IF NOT READY ; ; INPUTS: ; ; R1=CSR ADDR OF DM11-BB ; R5=UCB ADDR ; ; OUTPUTS: ; ; NO REGISTERS ARE DESTROYED ; UCB AND DM11-BB STATUSES ARE MODIFIED ; DMHUP: BICB #US.CRW!US.DSB,U.STS(R5) ;;;CLEAR CARRIER WAIT AND ENABLE UNIT BIC #1040,(R1) ;;;DISABLE SCAN 10$: BIT #20,(R1) ;;;SCAN STOPPED? BNE 10$ ;;;IF NE NO MOV (R1),-(SP) ;;;CANNOT USE BYTE INSTRUCTIONS ;;; ON DM11-BB (UNDOCUMENTED) BIC #1017,(SP) ;;;CLEAR CURRENT UNIT BISB U.UNIT(R5),(SP) ;;;SET DESIRED UNIT MOV (SP)+,(R1)+ ;;;TELL DM11-BB ABOUT IT BIS #7,(R1) ;;;SET REQUEST SEND+DATA ENABLE+RING ENABLE MOV (R1),-(SP) ;;;GET CURRENT UNIT STATUS COM (SP) ;;;COMPLEMENT UNIT STATUS BIT #140,(SP)+ ;;;CARRIER AND CLEAR TO SEND SET? BEQ 20$ ;;;IF EQ YES BISB #US.DSB,U.STS(R5) ;;;DISABLE UNIT BIC #17,(R1) ;;;CLEAR CURRENT UNIT STATUS INC (R1) ;;;ENABLE RING INTERRUPT CLC ;;;INDICATE UNIT HUNG UP 20$: BIS #140,-(R1) ;;;RESTART SCAN AND ENABLE INTERRUPT RETURN ;;; ; ; DMTMO - DM11-BB TIME OUT ROUTINE ; ; THIS ROUTINE IS ENTERED EVERY 4 SECONDS FROM THE TIME DEPENDENT SCHEDULER ; TO CHECK FOR DM11-BB TIMEOUTS. ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; ALL DM11-BB UNITS ARE EXAMINED FOR TIMEOUT. IF A TIMEOUT OCCURS, ; THEN THE UNIT IS HUNG UP. ; DMTMO: MOV #D$$M11,R0 ;SET NUMBER OF DM11-BB'S CLR R3 ;CLEAR CONTROLLER INDEX 10$: MOV DHTBL(R3),R2 ;GET ADDRESS OF UCB TABLE 20$: MTPS #0 ;ALLOW DEVICE INTERRUTPS MOV (R2)+,R5 ;GET ADDRESS OF NEXT UCB BEQ 30$ ;IF EQ END OF LIST BITB #US.OFL,U.ST2(R5) ;IS THE LINE OFFLINE? BNE 30$ ;IF NE YES -- OTHERS ARE ALSO MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS BITB #US.CRW,U.STS(R5) ;;;WAITING FOR CARRIER? BEQ 20$ ;;;IF EQ NO DECB U.CNT+2+DMTIM(R5) ;;;ANY TIME REMAINING? BNE 20$ ;;;IF NE YES MOV DMTBL(R3),R1 ;;;GET ADDRESS OF DM11-BB CSR CALL DMHUP ;;;HANG UP UNIT BCS 20$ ;;;IF CS UNIT NOT HUNG UP CALL TTHUP ;;;DO SPECIAL I/O CANCEL FOR HANGUP BR 20$ ;;; 30$: TST (R3)+ ;ADVANCE CONTROLLER INDEX DEC R0 ;ANY MORE DM11-BB'S? BGT 10$ ;IF GT YES .IF DF L$$DRV&LD$TT MOV CLKSW,R0 ;POINT AT CLOCK QUEUE CONTROL BLOCK .IFF MOV #CLKSW+2,R0 ;GET ADDRESS OF CLOCK QUEUE CONTROL BLOCK .ENDC DMCLK: CLR R1 ;ZERO HIGH ORDER DELTA TIME MOV $TKPS,R2 ;GET CLOCK TICKS PER SECOND ASL R2 ;CONVERT TO 4 SECOND INTERVAL ASL R2 ; INSCLK: MOV #C.SYST,R4 ;SET TYPE TO SYSTEM SUBROUTINE  CALLR $CLINS ;INSERT ENTRY IN CLOCK QUEUE .ENDC ; DF D$$M11 .IF DF D$$ZMD ;+ ; DZTMO - DZ11 TIME OUT ROUTINE ; ; THIS ROUTINE IS ENTERED EVERY HALF SECOND TO CHECK FOR ANY ; CHANGE IN CARRIER STATUS ON ANY DZ11 REMOTE LINE. ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; DESTROYS R0, R1, R2, R3, R4, R5 ; ; IF A REMOTE ENABLED LINE LOSES CARRIER, IT IS HUNG UP. IF ; A REMOTE, DISABLED LINE ASSERTS CARRIER, IT IS ENABLED ON THE ; ASSUMPTION THAT IT HAS RUNG AND HAS BEEN ANSWERED. ANSWERING ; IS AUTOMATIC FOR LINES THAT HAVE DATA TERMINAL READY ASSERTED, ; AND LINE HANG UP IS AUTOMATIC WHEN DTR IS DEASSERTED. ; DISABLED IS A LOGICAL STATUS WHERE TTDRV IGNORES ANY INPUT ; FROM THE LINE AND REJECTS ANY OUTPUT TO IT. ; ; NOTE: NOT ALL MODEMS CAN BE CORRECTLY HANDLED BY THIS CODE. ; THIS IS A CONSEQUENCE OF SOME TELEPHONE EXCHANGES, ; SOME MODEMS, AND THE DZ11. THE PRIMARY CONSTRAINTS ; ARE: ; ; 1) THE DZ11 PROVIDES ONLY A FEW MODEM CONTROL SIGNALS. ; ; 2) THE DZ11 DOES NOT INTERRUPT ON CHANGES IN STATE OF ; MODEM CONTROL SIGNALS. AS A CONSEQUENCE, THE ; SIGNALS MUST BE POLLED. ANY POLLING PUTS A LOAD ON ; THE CPU. POLLING FAST ENOUGH TO HAVE A SIGNIFICANT ; CHANCE OF CATCHING TRANSIENT SIGNALS PLACES AN ; UNACCEPTABLE, FOR MOST INSTALLATIONS, BURDEN ON ; THE CPU. ; ; 3) THE RING SIGNAL IS NOT CONDITIONED OR LATCHED. ; ITS SMOOTHNESS, SPIKINESS, DURATION, INTERVALS, ; ETC. ARE A DIRECT FUNCTION OF THE TELEPHONE ; EXCHANGE. COMBINED WITH NUMBER 2 ABOVE, THIS ; MEANS THAT, IN GENERAL, RING CANNOT BE USED. ; THE LARGEST PART OF DEALING WITH THE TELEPHONE ; SYSTEM IS PLACED ON THE MODEM. ;- DZTMO: MOV #D$$Z11,R0 ;SAVE NUMBER OF DZ11'S IN SYSTEM CLR R3 ;START AT MULTIPLEXER ZERO 10$: MOV DZTBL(R3),R1 ;GET ADDRESS OF UCB'S FOR THIS MUX ;TMM035 MOV DZCSR(R3),R2 ;GET CSR ADDRESS FOR THIS MUX ;TMM035 20$: MOV (R1)+,R5 ;GET UCB ADDRESS FOR NEXT LINE ON MUX ;TMM035 BEQ 30$ ;IF EQ NO MORE LINES TO EXAMINE ;**-3 BIT #U2.RMT,U.CW2(R5) ;THIS A REMOTE LINE? BEQ 20$ ;IF EQ NO BITB #US.OFL,U.ST2(R5) ;IS THE LINE OFFLINE? BNE 30$ ;IF NE YES -- OTHER UNITS ARE ALSO MOVB U.UNIT(R5),R4 ;GET LINE NUMBER ASL R4 ;CONVERT TO WORD INDEX MOV $BTMSK(R4),R4 ;IN R4, ASSERT BIT N FOR UNIT N BITB R4,5(R2) ;DTR ENABLED? ;TMM013 BNE 21$ ;IF NE YES ;TMM013 BISB R4,5(R2) ;ENABLE DTR FOR THIS LINE ;TMM013 BR 20$ ;DON'T CHECK FOR CARRIER UNTIL AFTER ;TMM013 ;NOISE FROM PREVIOUSLY ENABLING DTR SETTLES ;TMM013 ;LINE WILL GET CHECKED IN ANOTHER HALF SECOND ;TMM013 21$: BITB R4,7(R2) ;CARRIER ASSERTED? ;TMM013 BEQ 25$ ;IF EQ NO ;**-2 BITB #US.DSB,U.STS(R5) ;UNIT HUNGUP? BEQ 20$ ;IF EQ NO CALL COPASP ;COPY DEFAULT ANSWER BAUD RATE INTO RSP AND TSP ;TMM035 MOV DZCSR(R3),R2 ;RESTORE CSR ADDRESS ;TMM035 CALL SETLIN ;SET UP LINE PARAMETERS ;TMM035 ; EB267 .IF DF USECDZ ; EB267 .IFF ; EB267 ;**-14 BIC #U2.CRT!U2.ESC!U2.HLD!U2.L3S!U2.VT5!U2.LWC,U.CW2(R5) ; BIC #U3.UPC,U.CW3(R5) ;RESET ASR33 TERMINAL TYPE ON ANSWER ;TMM036 MOV #72.,U.CW4(R5) ;START LINE IN A KNOWN STATE ; EB267 .ENDC ; EB267 ; EB267 MOV U.SCB(R5),R4 ;GET SCB ADDRESS TSTB S.STS(R4) ;IS I/O IN PROGRESS? BNE 23$ ;IF NE YES BICB #US.BSY!US.ECH!US.OUT,U.STS(R5) ;CLEAR BITS THAT ;SHOULD NEVER BE SET 23$: BICB #US.DSB!US.CRW,U.STS(R5) ;ENABLE LINE (LOGICALLY BR 20$ ;ANSWER IT) 25$: BITB #US.CRW,U.STS(R5) ;WAITING FOR CARRIER? BEQ 27$ ;IF EQ NO DECB U.CNT+2+DZTIM(R5) ;WAITED TOO LONG? BNE 20$ ;IF EQ NO BICB #US.CRW,U.STS(R5) ;SHOW NOT WAITING FOR CARRIER BICB R4,5(R2) ;CLEAR MODEM (TELL IT TO HANG UP) ;TMM035 BR 20$ ; ;**-1 27$: BITB #US.DSB,U.STS(R5) ;LINE ALREADY HUNG UP? BEQ 28$ ;IF EQ NO BISB #US.CRW,U.STS(R5) ;SHOW WAITING FOR CARRIER MOVB #50,U.CNT+2+DZTIM(R5) ;INITIALIZE COUNTER BR 20$ ; 28$: BICB R4,5(R2) ;LOWER DTR TO HANG UP ;TMM035 MOV U.SCB(R5),R4 ;TTHUP MAY NEED SCB ADDRESS ;**-1 CALL TTHUP ;LOG OUT USER IF NECESSARY BCS 20$ ;IF CS TRY TO SAY BYE LATER BISB #US.DSB,U.STS(R5) ;DISABLE LINE (LOGICALLY HANGUP) BR 20$ ; 30$: TST (R3)+ ;INDEX TO NEXT MULTIPLEXER DEC R0 ;LOOKED AT THEM ALL? BGT 10$ ;IF GT NO .IF DF L$$DRV&LD$TT MOV DZCLKS,R0 ;POINT AT CLOCK QUEUE ENTRY .IFF MOV #DZCLKS+2,R0 ;REINSERT CLOCK ENTRY .ENDC DZCLK: CLR R1 ;ZERO HIGH ORDER DELTA TIME MOV $TKPS,R2 ;GET CLOCK TICKS PER SECOND ASR R2 ;WANT A HALF SECOND INTERVAL .IF DF D$$M11  BR INSCLK ;INSERT ENTRY INTO CLOCK QUEUE .IFF MOV #C.SYST,R4 ;SET TYPE TO SYSTEM SUBROUTINE CALLR $CLINS ;INSERT ENTRY IN CLOCK QUEUE .ENDC .ENDC ; DF D$$ZMD ;+ ;TMM035 ;** SETLIN ** ;TMM035 ; ;TMM035 ; THIS ROUTINE SETS UP A DZ OR DH LINE AS SPECIFIED BY THE ;TMM035 ; LINE CHARACTERISTICS (RSP,TSP,PARITY) IN U.CW3. ;TMM035 ; ;TMM035 ; INPUTS: ;TMM035 ; R5 -> UCB ;TMM035 ; R2 -> CSR ;TMM035 ; ;TMM035 ; ;TMM035 ; OUTPUT: ;TMM035 ; APPROPRIATE LPR VALUE CHANGED ;TMM035 ; NO REGISTERS MODIFIED ;TMM035 ; ;TMM035 ; RESTRICTIONS: ;TMM035 ; THIS ROUTINE MUST BE CALLED AT DEVICE PRIORITY ;TMM035 ; THIS ROUTINE MAY ONLY BE CALLED FOR DZ'S OR DH'S ;TMM035 ; ;TMM035 ;- ;TMM035 .IF DF D$$Z11!D$$H11 ;TMM035 ;TMM035 SETLIN: MOV U.CW3(R5),-(SP) ;;; GET CURRENT VALUE OF U.CW3 ;TMM035 SWAB (SP) ;;; REFORMAT U.CW3 FOR LPR TRANSFORMATIO;TMM035 ;TMM035 .IF DF D$$Z11&D$$H11 ;TMM035 ;TMM035 BIT #U2.DZ1,U.CW2(R5) ;;; IS THIS A DZ OR DZV ? ;TMM035 BEQ 2$ ;;; IF EQ NO, MUST BE A DH ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$Z11 ;TMM035 ;TMM035 BIC #^C<7720>,(SP) ;;; CLEAR ALL BUT SPEED AND PARITY BITS ;TMM035 ;;; AND "FORCE TWO STOPBITS" BIT ;TMM035 BIT #20,(SP) ;;; FORCE TWO STOPBITS? ;TMM035 BNE 4$ ;;; IF NE YES ;TMM035 CMP (SP),#2000 ;;; IS BAUD RATE 110 OR LESS? ;TMM035 BHIS 1$ ;;; IF HIS NO ;TMM035 4$: BIS #40,(SP) ;;; SET TWO STOP BITS ;TMM035 1$: BIS #10030,(SP) ;;; SET FOR EIGHT BIT CHARACTERS ;TMM035 BISB U.UNIT(R5),(SP) ;;; SET UP UNIT NUM ;TMM035 MOV (SP)+,2(R2) ;;; FINALLY, SET UP LPR ;TMM035 RETURN ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .IF DF D$$H11 ;TMM035 ;TMM035 2$: ASR (SP) ;;; SHIFT SPEED AND PARITY BITS ;TMM035 ASR (SP) ;;; INTO THEIR LPR PLACES ;TMM035 BIC #^C<37764>,(SP) ;;; CLEAR ALL BUT TSP,RSP, AND PARITY ;TMM035 ;;; AND "FORCE TWO STOP BITS" BIT ;TMM035 BIT #4,(SP) ;;; FORCE TWO STOP BITS? ;TMM035 BNE 3$ ;;; IF NE YES ;TMM035 BIT #1400,(SP) ;;; TRANSMIT SPEED <= 110 BAUD ? ;TMM035 BNE 3$ ;;; IF NE NO ;TMM035 BIS #4,(SP) ;;; SET TWO STOP BITS ;TMM035 3$: BIS #3,(SP) ;;; SET FOR EIGHT BIT CHARACTERS ;TMM035 BIC #1077,(R2) ;;; RESET MAIN,MEM EXT, AND LINE NUM BIT;TMM035 BISB U.UNIT(R5),(R2) ;;; SET LINE NUMBER ;TMM035 MOV (SP)+,4(R2) ;;; FINALLY, SET UP LPR ;TMM035 RETURN ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 .ENDC ;TMM035 ;TMM035 ;+ ;TMM035 ; ** COPASP -- COPY ANSWER BAUD RATE TO RECEIVE AND TRANSMIT SPEEDS ;TMM035 ; ;TMM035 ; THIS ROUTINE COPIES THE ANSWER BAUD RATE IN U.CW3 BITS (8-11) INTO ;TMM035 ; THE RECEIVE SPEED (BITS 0-3) AND THE TRANSMIT SPEED (BITS 4-7). ;TMM035 ; ;TMM035 ; INPUTS: ;TMM035 ; NONE ;TMM035 ; ;TMM035 ; OUTPUTS: ;TMM035 ; U.CW3 IS ALTERED AS DESCRIBED ABOVE ;TMM035 ; ;TMM035 ; R2 IS DESTROYED ;TMM035 ;- ;TMM035 ;TMM035 .IF DF D$$ZMD!D$$M11 ;TMM035 ;TMM035 COPASP: CLRB U.CW3(R5) ;CLR LOW ORDER BYTE (TSP AND RSP) ;TMM035 MOV U.CW3(R5),R2 ;PICK UP ANSWER SPEED (BITS 8-11) ;TMM035 ;TMM035 .ENDC ;TMM035  ;TMM035 .IF DF T$$SMC!D$$ZMD!D$$M11 ;TMM035 ;TMM035 .IF DF D$$H11!D$$Z11!D$$ZMD!D$$M11 ;TMM035 ;TMM035 SSSZSP: CALL SSSCW3 ;DO SOME MAGIC TWICE ;TMM035 SSSCW3: ASL R2 ;SHIFT LEFT FOUR TIMES, A NIBBLE IF U WILL ;TMM035 ASL R2 ;TMM035 ASL R2 ;TMM035 ASL R2 ;TMM035 SWAB R2 ;ANSWER BAUD RATE IN BITS (0-3)FIRST PASS ;TMM035 BISB R2,U.CW3(R5) ;BITS (4-8) SECOND PASS ;TMM035 RETURN ;TMM035 ;TMM035 .ENDC ;T:MM035 ;TMM035 .ENDC ;TMM035 .END :# kQ ›c, .TITLE EXDBT .IDENT /05.11/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.11 ; ; D. N. CUTLER 7-DEC-74 ; ; PREVIOUSLY MODIFIED BY: ; ; E. L. BAATZ ; T. J. MILLER ; E. L. BAATZ ; J. E. PROVINO ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 22-DEC-80 ; MSH045 -- DRQIO FAULTS CAN ONLY OCCUR IF EXECUTIVE ; COMMON MAPPED ; ; M. S. HARVEY 24-DEC-80 ; MSH136 -- HANDLE FLOATING POINT EXCEPTION TRAPS FOR ; PROCESSORS WITH FIS ; ; M. S. HARVEY 29-DEC-80 ; MSH137 -- OUTPUT ENTIRE SYSTEM ID ON VIRGIN BOOT AND ; MAKE SURE ALL OUTPUT IS ECHOED BEFORE ; TRANSFERRING TO $INITL ON VIRGIN BOOT ; ; M. S. HARVEY 3-MAR-81 ; MSH155 -- ADD XON/XOFF SUPPORT ; ; M. S. HARVEY 5-MAY-81 ; MSH165 -- MODIFY COMMON SUPPORT TO REFLECT THE ; EXISTENCE OF BOTH COMMONS ; ; M. S. HARVEY 17-SEP-81 ; MSH125 -- SET FATAL CRASH INDICATOR FOR CRASH ANALYSIS ; ; EXECUTIVE ODT ; ; THIS IS A VERSION OF ODT THAT MAY BE USED TO DEBUG RSX-11M EXECUTIVE ; MODULES. IT IS AN OUTGROWTH OF THE STANDARD RSX-11 ODT WHICH WAS PRO- ; DUCED BY M. SMITH , H. LEV ET. AL. ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ; ; EQUATED SYMBOLS ; BPT=3 ;BREAKPOINT INSTRUCTION CODE BKP=16 ;NUMBER OF BREAKPOINTS -1 X 2 LPB=177516 ;LINE PRINTER BUFFER REGISTER LPS=177514 ;LINE PRINTER STATUS REGISTER RLR=16 ;NUMBER OF RELOCATION REGISTERS -1 X 2 TBT=20 ;T-BIT MASK FOR PROCESSOR STATUS WORD TKB=177562 ;CONSOLE TERMINAL INPUT BUFFER REGISTER TKS=177560 ;CONSOLE TERMINAL INPUT STATUS REGISTER TPB=177566 ;CONSOLE TERMINAL OUTPUT BUFFER REGISTER TPS=177564 ;CONSOLE TERMINAL OUTPUT STATUS REGISTER ; ; LOCAL MACROS ; ; DECODE NEXT COMMAND ; .MACRO DECODE IOT .ENDM ; ; ERROR ; .MACRO ERROR EMT 0 .ENDM ; ; TEST MODE FOR EXEC OR USER ; .MACRO TESTM ADDR JSR R5,TESTM .WORD ADDR .ENDM ; ; TYPE OUT CHARACTER(S) ; ; TYPE OUT IS EFFECTED WITH A TRAP INSTRUCTION WITH THE BOTTOM ; BYTE ENCODED AS FOLLOWS: ; ; 300 = OUTPUT BOTH BYTES IN R0. ; 200 = OUTPUT LOW BYTE IN R0. ; 340 = OUTPUT A SEQUENCE. ; 240 = OUTPUT A SEQUENCE. ; ; ALL OTHER COMBINATIONS ARE TREATED AS THE ACTUAL BYTE ; TO OUTPUT. .MACRO TYPE ARG .IF IDN , TRAP 200 .IFF .IF IDN , TRAP 300 .IFF .IF IDN , TRAP 340 .IFF .IF IDN , TRAP 240 .IFF TRAP ARG&177 .ENDC .ENDC .ENDC .ENDC .ENDM ; ; LOCAL DATA ; ; CONTEXT VARIABLES ; THE ORDER OF THESE ITEMS IS INTENTIONAL, SEE REGISTER MAPPING SCHEME ; INTBEG =. ;STARTING ADDRESS OF INTERNAL REGISTERS UR0: 0 ;USER R0 $0 0 ; R1 $1 0 ; R2 $2 0 ; R3 $3 0 ; R4 $4 0 ; R5 $5 USP: 0 ;USER SP $6 UPC: $INITL ;USER PC $7 UST: PR7 ;USER PS  $S ARG: 0 ;ARGUMENT REGISTER $A LOW: 0 ;LOW LIMIT $L HI: 0 ;HIGH LIMIT $H CNST: $XDT ;CONSTANT REGISTER $C QUAN: 0 ;QUANTITY REGISTER $Q FORM: 0 ;FORMAT REGISTER $F ; ; INTERNAL TABLES ; INTINX =. ;STARTING ADDRESS OF INTERNAL TABLES ; ; BREAKPOINT CONTROL LISTS, AND EXTRA SLOT FOR SINGLE STEP ; ADR1: ;ADDRESS OF THE BREAKPOINT ($0B-$7B) .WORD TRTC,TRTC,TRTC,TRTC,TRTC,TRTC,TRTC,TRTC,TRTC CT: ;PROCEED COUNT ($0G-$7G) .WORD 1,1,1,1,1,1,1,1,1 UIN: ;USER INSTRUCTION SAVE LOCATION ($0I-$7I) .WORD BPT,BPT,BPT,BPT,BPT,BPT,BPT,BPT,BPT ; ; RELOCATION REGISTERS ; RELT: ;RELOCATION TABLES ($0R-$7R) .WORD -1,-1,-1,-1,-1,-1,-1,-1 INTEND=.-2 ;END OF INTERNAL REGISTERS AND TABLES ; ; EXEC SST TRAP VECTOR ADDRESSES ; SSTVEC: + ODDA ;0-ODD ADDRESS, OR HALT, VECTOR @4 .IF DF M$$MGE + SGMT ;1-SEGMENT FAULT .IFF + $NONSI ; NO SEGMENT FAULT POSSIBLE .ENDC + BPTI ;2-T-BIT OR BPT + IOTX ;3-IOT + ILLI ;4-RESERVED OR ILLEGAL INSTRUCTION + NEMT ;5-EMT + TRPI ;6-TRAP .IF DF F$$LTP ;MSH136 ;MSH136 + FPPE ;7-FLOATING POINT TRAP ;MSH136 ;MSH136 .ENDC ;MSH136 ; ; WORDS AND ORDERED BYTES, ITEMS MUST BE KEPT FROM COMMAND TO COMMAND ; CAD: .WORD 0 ;ADDRESS OF CURRENTLY OPEN REGISTER DOT: .WORD 0 ;ADDRESS OF LAST EXPLICITLY OPENED CELL BW: .WORD 0 ;LAST OPEN MODE 1=BYTE, 2=WORD OPN: .WORD 0 ;LOCATION OPEN FLAG 0=NOT OPEN, NON-ZERO=OPEN D.ARGS: .WORD 0 ;SEMI COLON PUSH WORD ; ; THE FOLLOWING ITEMS NEED NOT BE KEPT FROM COMMAND TO COMMAND ; THEIR ORDER IS INTENTIONAL SO KNOW THY MAKER! ; OP: .BYTE 0 ;CURRENT ARITHMETIC OPERATOR SMFD: .BYTE 0 ;SEMI-COLON COUNTER EXP: .WORD 0 ;EXPRESSION BUCKET OUTB: .WORD TPB ;CONSOLE PRINTER BUFFER ADDRESS OUTS: .WORD TPS ;CONSOLE PRINTER STATUS REGISTER PPC: .BLKW 1 ;SAVED PC LAST BREAKPOINT ; ; THE FOLLOWING ITEMS MUST BE KEPT FROM COMMAND TO COMMAND. ; T: .BYTE 0 ;T BIT IN USE FLAG P: .BYTE -1 ;PROCEED ALLOW FLAG S: .BYTE 0 ;SINGLE INSTRUCTION MODE, 0=NORMAL, >0=ENABLE FM: .BYTE 2 ;OUTPUT FORMAT MODE, BYTE, WORD, ANSII, RAD50 OBW: .BYTE 2 ;OPEN CELL TYPE, 1=BYTE, 2=WORD SEQ: .BYTE 0 ;CHANGE SEQUENCE INDICATIOR ; ; THE BELOW LOCATION IS USED IN BREAKPOINT PROCESSING ; TRTC: BPT ;TRACE TRAP PROTOTYPE ; ; ALL XDT TYPE ERRORS JUST GO TO "ERR" OR SOMEWHERE ELSE ; SSTXDT: + ERR ;0-ODD ADDRESS + ERR ;1-SEGMENT FAULT + ERR ;2-BPT OR T-BIT ("MCR" CALL) + DCD ;3-IOT ("DECODE") + ERR ;4-RESERVED OR ILLEGAL INSTRUCTION + ERR ;5-EMT ("ERROR") + TYPE ;6-TRAP ;MSH136 .IF DF F$$LTP ;MSH136 ;MSH136 + ERR ;7-FLOATING POINT EXCEPTION ;MSH136 ;MSH136 .IFTF ;MSH136 ;MSH136 ; ; SST VECTOR ADDRESS TABLE ; SSTADR: .WORD 4 ;ODD ADDRESS .WORD 250 ;SEGMENT FAULT .WORD 14 ;BPT .WORD 20 ;IOT .WORD 10 ;ILLEGAL INSTRUCTION .WORD 30 ;EMT .WORD 34 ;TRAP ;MSH136 .IFT ;MSH136 ;MSH136 .WORD 244 ;FLOATING POINT ;MSH136 ;MSH136 .ENDC ;F$$LTP ;MSH136 ;MSH136 ; ; INTERNAL REGISTER NAME AND CONTROL TABLES ; ; NON-INDEXED REGISTER NAMES ; NIXMAP: .ASCII /01234567/ ;USER REGISTER NAMES FOR MAPPING NIXREG: .BYTE 'S ;UST USER STATUS .BYTE 'A ;ARG ARGUMENT .BYTE 'L ;LOW LOW SCAN LIMIT .BYTE 'H ;HI HIGH SCAN LIMIT .BYTE 'C ;CNST CONSTANT .BYTE 'Q ;QUAN QUANTITY .BYTE 'F ;FORM FORMAT CONTROL .BYTE 0 ;END OF THIS LIST ; ; INDEXED REGISTER NAMES ; INXREG: .BYTE 'B ;ADR1 BKPT ADDRESSES .BYTE 'G ;CT BKPT PROCEED COUNTS .BYTE 'I ;UIN BKPT USER INSTRUCTIONS .BYTE 'R ;RELT RELOCATION REGISTERS .BYTE 0 ;END OF THIS LIST ; ; INDEXED REGISTER TABLE BASES ; .EVEN INXTBL: .WORD ADR1 ;BKPT ADDRESS TABLE .WORD CT ;BKPT PROCEED COUNTS .WORD UIN ;BKPT'D INSTRUCTION .WORD RELT ;RELOCATION TABLES .WORD INTEND+2 ;END OF TABLE AREA FOR ADDRESS MAPPING ; ; CHARACTER CONVERSION LISTS. ;  ALTTAB: .BYTE 033,175,176 ;ALTERNATE ALT-MODE FORMS .BYTE 0 ;END OF THIS LIST TOO ; ; COMMAND NAME AND DISPATCH TABLES ; COMTAB: ;ADDRESS OF THE CHARACTER TABLE ; ; OPEN REGISTER COMMANDS (ORDER AND POSITION CRITICAL) ; .BYTE '\,'/,'','",'% ; ; CLOSE REGISTER COMMANDS ; .BYTE 015,012,'^,'_,'@,'>,'< ; ; SPECIAL FORMS ; .BYTE 021,'$,'=,'C,'Q,'. ;MSH155 ;**-1 ; ; OPERATORS (ORDER OF -+* IS CRITCAL) ; .BYTE ';,'-,'+,'*,', ; ; COMMANDS ; .ASCII /BGKLOPRSX/ .BYTE 0 ;******* END OF THE LIST ******* .EVEN ; ; THE DISPATCH TABLE, ORDERED ON ABOVE TABLE ; ; OPEN REGISTER COMMANDS ; COMDIS: .WORD OCBYTE ;\ OPEN OCTAL BYTE .WORD OCWORD ;/ OPEN OCTAL WORD .WORD ANBYTE ;' OPEN ANSII BYTE .WORD ANWORD ;" OPEN ANSII WORD .WORD MODULO ;% OPEN RADIX 50 WORD ; ; CLOSE REGISTER COMMANDS ; .WORD CLCRET ; CLOSE, NO SUCESSIVE OPEN .WORD CLLNFD ; CLOSE, OPEN NEXT .WORD CLUPAR ;^ CLOSE, OPEN PREVIOUS .WORD CLBACK ;_ CLOSE, OPEN PC RELATIVE MODE .WORD CLATSG ;@ CLOSE, OPEN INDIRECT .WORD CLGRTH ;> CLOSE, OPEN PC OFFSET AS BRANCH .WORD CLLSTH ;< CLOSE, OPEN OLD SEQUENCE ; ; SPECIAL FORMS ; .WORD DCD ;^Q NULL, TERMINATE INPUT STRING ;MSH155 .WORD REGT ;$ INTERNAL REGISTER REFERENCE .WORD EQUALS ;= PRINT LEFT SIDE IN OCTAL .WORD CHRCEE ;C CONSTANT REGISTER CONTENTS .WORD CHRQUE ;Q QUANTITY REGISTER CONTENTS .WORD CHRDOT ;. LAST OPENED LOCATION'S ADDRESS ; ; OPERATORS ; .WORD SEMI ;; MULTIPLE ARGUMENT DELIMITER .WORD MINS ;- SUBTRACTION .WORD PLUS ;+ .WORD ADDITION .WORD STAR ;* MULTIPLY BY 50 .WORD COMM ;, RELOCATION COMPUTE ; ; COMMANDS ; .WORD SEBK ;B SET / CLEAR BREAKPOINTS .WORD GOTO ;G GO TO USER'S DATA .WORD KILO ;K KOMPUTE AND TYPE RELOCATION DATA .WORD LIST ;L LIST MEMORY ON SPECIFIED DEVICE .WORD OFST ;O TYPE PC RELATIVE OFFSETS .WORD PROC ;P PROCEED FROM BREAKPOINT .WORD RELO ;R SET / RESET RELOCATION REGISTERS .WORD SNGL ;S SET / RESET SINGLE STEP MODE .WORD EXIT ;X EXIT TO CRASH ROUTINE ;+ ; **-$XDT-RSX-11M EXECUTIVE ODT ;- .ENABL LSB $XDT:: MTPS #PR7 ;LOCK OUT INTERRUPTS MOV SP,USP ;SAVE ENTRY STACK POINTER MOV #USP,SP ;SET NEW STACK POINTER ADDRESS MOV R5,-(SP) ;SAVE REGISTERS R5 THRU R0 MOV R4,-(SP) ; MOV R3,-(SP) ; MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; MOV PC,SP ;CHANGE STACK POINTER MOV #SSTADR,R0 ;POINT TO TRAP VECTOR ADDRESS TABLE MOV #SSTXDT,R1 ;POINT TO XDT TRAP VECTOR TABLE 10$: MOV (R1)+,@(R0)+ ;INSERT XDT TRAP VECTOR ADDRESSES CMP R1,#SSTADR ;ANY MORE TO SET? BLO 10$ ;IF LO YES MOV PC,SP ;LENGTHEN STACK TYPE CRLF ;PLACE TERMINAL CARRIAGE IN PROPER POSITION TYPE 'X ;OUTPUT XDT IDENTIFICATION TYPE 'D ; TYPE 'T ; TYPE ': ; TYPE 40 ; MOV $SYSID,R0 ;GET SYSTEM IDENTIFICATION TYPE R0+R0 ;OUTPUT SYSTEM IDENTIFICATION MOV $SYSID+2,R0 ;GET SECOND HALF OF SYSTEM ID ;MSH137 TYPE R0+R0 ;OUTPUT SECOND HALF ;MSH137 TYPE CRLF ;PLACE TERMINAL CARRIAGE IN PROPER POSITION JSR SP,DCD ;DECODE NEXT COMMAND XDTSTK: ;REF LABEL - START OF XDT STACK .DSABL LSB .SBTTL COMMAND PROCESSORS, SECTION ONE ( $ B R K A Q . ) .SBTTL "$," PROCESSOR - INTERNAL REGISTER MAPPER ;SYNTAX-- ;$L DELIVER INTERNAL ADDRESS OF L ;$NL DELIVER INTERNAL ADDRESS OF L+2N ;$N DELIVER INTERNAL ADDRESS OF USER REGISTER N ;SEE MAPPING TABLES, RANGE OF N IS 0-7 REGT: JSR PC,GETNUM ;GET AN OCTAL NUMBER JSR PC,RTST ;CHECK FOR ERROR BCS ERR0  ;MPY R4 X 2 TST R2 ;SEE IF ANYTHING TYPED BNE 10$ ;IF SO IS INDEXED OR USER REGISTER JSR R5,LOOKUP ;SEE IF NON-INDEXED + NIXREG BCS 12$ ;NON-INDEXED TURNS INTO A COMMAND MOV R1,R4 ;PLACE IN LIST IS INTERNAL ORDER ADD #UST,R4 ;GET ADDRESS IN R4, GOTTA READ CHAR BR 20$ 10$: JSR R5,LOOKUP ;SEE IF INDEXED + INXREG BCC 15$ ;WAS TRULY INDEXED 12$: CMP #7+7,R4 ;INTERNAL USER REGISTER RANGE CHECK BLO ERR0 ADD #UR0,R4 ;SET ACCESS TO R0-R7 OF THE USER BR 25$ ;AVOID READING OF COMMAND 15$: ADD INXTBL(R1),R4 ;COMPUTE ADDRESS TO INDEXED TABLE 20$: JSR PC,GET ;GET THE ASSUMED TERMINATOR 25$: INC R2 ;SHOW THEM THAT R4 GOT VALID DATA JMP CLGL ;RE-USE CHARACTER, R2 IS NON-ZERO .SBTTL "B" PROCESSOR - SET AND REMOVE BREAKPOINTS ;SYNTAX-- ;B CLEAR ALL BREAKPOINTS ;NB CLEAR BKPT N ;A;B SET BKPT AT A, USE FIRST FREE BKPT ;A;NB SET BKPT N AT A ;DEPENDS MIGHTILY UPON LOCATION "TRTC" CONTAINING A TRAP INST. ;AND THAT A FREE BKPT CONTAINS THE ADDRESS "TRTC". SEBK: ASL R4 ;MPY R4 X2, JUST IN CASE ALL IS GO MOV #TRTC,R0 ;SET MAGIC VALUE IN R0, JUST IN CASE TST R3 ;CHECK FOR THE REAL CASE BEQ REMB ;REMOVAL CASES, CLEAR THEM UP BIT #1,R5 ;LOOK AT ADDRESS BNE ERR ;THAT'S ODD ? TST R2 ;SEE IF I GET TO PICK IT OR NOT BNE 15$ ;OR NOT, DISAPPOINTMENT 10$: CMP R0,ADR1(R4) ;LOOK FOR LOCATION WITH FREE ADDRESS BEQ 15$ ;A HIT TST (R4)+ ;KEEP AT FOR A LONG WHILE BR 10$ ;LOOOOOOOOP 15$: MOV R5,R0 ;R0 HAS ADDRESS OF BREAKPOINT BR RE02 ;GO TUCK IT IN ;REMOVE SOME BREAKPOINTS REMB: TST R2 ;SEE IF ONE OR ALL BEQ RALL ;ALL RE02: JSR PC,SETBRK ;SET THE ONE SET UP TO SET BCC DCD ;IT HAPPENED ERR0: ERROR ;SOME THING WENT WRONG ; ; REMOVE ALL BREAKPOINTS ; RALL: CLR R4 ;R4 IS ZERO 10$: JSR PC,SETBRK ;SET THEM TILL BCC 10$ ;THEY GET OUTTA DECODE ;HAND!!!! ; ; SUBROUTINE TO SET/CLEAR BREAKPOINTS ; SETBRK: CMP #BKP,R4 ;LEGAL BREAKPOINT NUMBER? BLO 10$ ;IF LO NO MOV R0,ADR1(R4) ;SET BREAKPOINT ADDRESS MOV (R0),UIN(R4) ;SAVE CONTENTS OF BREAKPOINT LOCATION MOV #1,CT(R4) ;SET INITIAL PROCEED COUNT TST (R4)+ ;ADVANCE BREAKPOINT NUMBER 10$: RETURN ; .SBTTL "R" PROCESSOR - RELOCATION REGISTER PROCESSING ;DETERMINE IF CLEAR OR SET RELO: TSTB SMFD ;SEMI-COLON ABSENT MEANS CLEAR BEQ 10$ ;CLEAR DISPATCH, OR FALL TO SETTING ;FORMS HERE-- ; A;NR SET RELOC(N) TO A ;ABSENT A OR N DEFAULTS TO 0 JSR PC,RTST ;PROTECTION EDITING BCS ERR ;ILLEGAL REGISTER NUMBER ? MOV R5,RELT(R4) ;SET THE APPROPRIATE REGISTER DECODE ;GO GET NEXT COMMAND ;FORMS HERE-- ;R RESET ALL TO -1 FOR RELOC(0-7) ;NR RESET ONLY RELOC(N) 10$: TST R2 ;SEE IF NR OR JUST R BEQ 15$ ;CLEAR ALL JSR PC,RUCL ;CLEAR THE ONE IN R4 BCS ERR ;ERROR, INVALID REGISTER ? DECODE ;NEXT COMMAND 15$: JSR PC,RUAL ;DO THEM ALL DECODE ;OFF AND ON ; ; SUBROUTINE TO RESET RELOCATION BASE REGISTER ; .ENABL LSB RUCL: CALL RTST ;TEST FOR LEGAL REGISTER BCS 10$ ;IF CS ILLEGAL REGISTER MOV #-1,RELT(R4) ;RESET RELOCATION REGISTER ASR R4 ;CONVERT BACK TO REGISTER NUMBER 10$: RETURN ; ; ; SUBROUTINE TO CLEAR ALL RELOCATION REGISTERS ; RUAL: CLR R4 ;START WITH REGISTER 0 20$: CALL RUCL ;CLEAR NEXT RELOCATION REGISTER BCS 10$ ;IF CS ALL DONE INC R4 ;ADVANCE TO NEXT REGISTER BR 20$ ; .DSABL LSB .SBTTL "K" PROCESSOR - COMPUTE AND PRINT RELOCATION ;SYNTAX-- ;AK TYPE RELOCATION DEAL FROM DOT TO A ;L;AK TYPE RELOCATION DEAL FROM L TO A ;IF A IS NULL THE THE OLD BEST FIT RULE APPLIES ;TYPES =N,DDDDDD WHERE N IS THE RELOCATION REGISTER ; AND D-D IS THE RELOCATION BIAS KILO: TST R2 ;SEE WHO PICKS THE REGISTER BNE 10$ TST R3 ; ADDRESS SPECIFIED? BNE 5$ ; YES MOV CAD,R4 ; NO, GET CURRENT ADDRESS BR 7$ ; 5$: MOV R5,R4 ; GET ADDRESS SPECIFIED ON COMMAND 7$: JSR PC,LOCA ; GET CLOSEST RELOCATION REGISTER MOV R0,R4 ;DID WE FIND A RELOCATION REGISTER? BMI ERR ;CAN'T FIND ONE THATS GOOD 10$: BIC #177770,R4 ;EDIT REGISTER TYPE '= ;OUTPUT CUE TYPE 40 ; MOVB R4,R0 ;TYPE REGISTER & A , ADD #"0,,R0 TYPE R0+R0 ; ASL R4 ;GO GET IT AS TABLE INDEX TST R3 ;SEE WHO TYPED THE ADDRESS BNE 15$ MOV CAD,R5 ;THAT CAD! 15$: SUB RELT(R4),R5 MOV R5,R0 ;BIAS COMPUTE JSR PC,CADW ;PRINT AS WORD DECODE .SBTTL "A-Q-." PROCESSORS - SPECIAL VALUES ;MERELY SUBSTITUTE THE VALUE IN R4 WITH THE CONTENTS OF THE SPECIFIED ;REGISTER. CHRQUE: MOV QUAN,R4 ;LAST QUANTITY PRINTED BR CHR001 CHRCEE: MOV CNST,R4 ;CONSTANT REGISTER BR CHR001 CHRDOT: MOV CAD,R4 ;CURRENT LOCATION CHR001: INC R2 ;ALLOW AS R4 IS REAL JSR PC,GET ;GET NEXT CHARACTER AND ASSUME BR CLGL ;IT IS A TERMINATOR .SBTTL COMMAND DE-CODER AND MAIN LOOP OF ODT ; COMMAND DECODER - ODT ; ALL REGISTERS MAY BE USED (R0-R5), ;ERROR ENTRY, TYPE FLAG AND GO DO COMMAND ERR: CALL SETCN ;SET OUTPUT FOR CONSOLE TYPE '? ;OUTPUT ERROR INDICATION ; ; DECODE FROM THE TOP, CLOSE ALL AND DO CR/LF/_ ; DCD: MOV #XDTSTK,SP ;SET THE STACK FOR SANITY CALL SETCN ;SET OUTPUT FOR CONSOLE TYPE CRLF ;PLACE TERMINAL CARRIAGE IN PROPER POSITION CLR OPN ;SET NO LOCATION OPEN TYPE 'X ;OUTPUT INPUT SOLICITATION TYPE 'D ; TYPE 'T ; TYPE 76 ;'>' ;MAINTAIN OPENED LOCATION, RE-INIT INPUT NEWC: CLRB SMFD ;CLEAR SEMI-COLON FLAG/COUNT CLR R3 ;ZERO SECONDARY ARGUMENT FLAG CLR R5 ;AND ARGUMENT ;NEW SUB-EXPRESSION ENTRY NEWE: CLRB OP ;CLEAR OPERATOR FOUND CLR EXP ;SET ZERO IN EXPRESSION SO FAR LOCATION ;GET NUMBER AND THEN SCAN FOR COMMAND  NEWN: JSR PC,GETNUM ;GET AN OCTAL NUMBER AND TERMINATOR ;NON-OCTAL CHAR TYPED WHAT ARE WE TO DO? CLGL: JSR R5,LOOKUP ;GO SEE IF IT IS REAL + COMTAB ;THIS DEFINES REAL BCS ERR ;EASY ENOUGH IF NOT REAL TST R2 ;IF NOTHING TYPE BOTHER NOT BEQ CL01 ;WITH THE EXPRESSION JSR PC,EXPCOM ;COMPUTE EXPRESSION CL01: JMP @COMDIS(R1) ;GO TO PROPER ROUTINE ;FOR THE BENEFIT ALL REGISTERS ARE AS FOLLOWS ;R0 LAST CHARACTER TYPED, THE COMMAND ITSELF! ;R1 TABLE INDEX TO COMMAND ADDRESSES, IT IS USED. ;R2,R4 FIRST ARGUMENT, IF R2<>0 THEN R4 IS DATA ;R3,R5 SECOND ARGUMENT, IF R3<>0 THEN R5 IS DATA ; ; SET OUTPUT DEVICE TO CONSOLE TERMINAL ; SETCN: MOV #TPB,OUTB ;SET OUTPUT BUFFER ADDRESS MOV #TPS,OUTS ;SET OUTPUT STATUS ADDRESS RETURN ; .SBTTL EXPRESSION SETUP COMMANDS ( ; + - * , ) ;SEMI-COLON PROCESSOR SEMI: INCB SMFD ;COUNT SEMI-COLON CMPB #2,SMFD ;PUSH CONTENTS INTO MULTI BNE SEM1 ;SEMI COLON ARG LIST MOV R5,D.ARGS SEM1: MOV R2,R3 ;PUSH R2 AND R4 INTO MOV R4,R5 ;R3 AND R5 (FLAG AND CONTENTS) BR NEWE ;CONTINUE SCANNER ;ADDITION SETUP PLUS: CLRB OP ;OP IS 0 FOR + BR CO00 ;SUBTRACT SET UP MINS: MOVB #2,OP BR CO00 ;MULTIPLY BY 50 AND ADD STAR: MOVB #-2,OP ;OP IS -2 FOR * CO00: CLR R4 ;R4 IS RESET BR NEWN ;MEMORY RELOCATION CHECK COMM: ASL R4 ;ALL NEED IT X 2 CMP R4,#RLR ;SEE IF REGISTER IS OUT OF RANGE BGT ERR MOV RELT(R4),EXP ;COMPUTE REAL CORE ADDRESS BR PLUS .SBTTL OPEN AND CLOSE PROCESSORS .SBTTL "\-/-'-"-%-:" PROCESSOR - OPEN AND TYPE CONTENT COMMANDS ;SYNTAX-- ;NC OPEN LOC N IN MODE C, SET MODE FOR NEXT ;C TYPE LAST OPENED LOC IN MODE C OCWORD: ;OCTAL WORD - R1=2 ANWORD: ;ANSII WORD - R1=6 MODULO: ;RADIX 50 WORD - R1=10 ;OPEN WORD MODE ENTRY, R1 CONTAINS FORMAT INDEX MOV #2,R0 ;SET BYTE FLAG TO WORD FLAG BR OPE004 ;GO TO IT ACE HOLE OCBYTE: ;OCTAL BYTE - R1=0 ANBYTE: ;ANSII BYTE - R1=4 OPE001: MOV #1,R0 ;SET WORD FLAG TO BYTE FLAG OPE004: TST R2 ;IF NO VALUE TYPED NO MODE SET BEQ 10$ MOV R0,BW ;SET MODE AND FORMAT FLAGS MOVB R0,OBW ;SET THE LATER USE MODE MOVB R1,FM ;SET THE MODE FLAG FOR SOOTH MOV R4,CAD ;SET ADDRESS FOR EXPLICIT OPEN MOV R4,DOT ;RESET RETURN PTR. 10$: CMP #1,R0 ;CHECK ON BYTE MODE BEQ 15$ ;NOT BYTE MODE BIT #1,CAD ;SEE IF ADDRESS IS ODD BEQ 15$ ;ALL IS GOOD CLR R1 ;THEY GET BYTE MODE ONLY BR OPE001 15$: MOV R1,-(SP) ;SAVE FORMAT MAINLY JSR PC,GETCAD ;GET THE DATA MOV (SP)+,R1 ;GET FORMAT JSR PC,@TYFORM(R1) ;PRINT DATA IN PROPER FORMAT BR NEWC ;GO GETTA NEW COMMAND TO DO .SBTTL "-->-<-^-_-@" PROCESSOR - CLOSE AND OPEN REGISTERS ;CARRIAGE RETURN CLCRET: JSR PC,PUTCAD ;CLOSE LOCATION BR DCD ;RETURN TO DECODER ;LESS THAN, BACK TO MAIN STREAM CLLSTH: INCB SEQ ;SET FLAG TO LATER RESTORE CAD ;LINE FEED, NEXT ONE DOWN CLLNFD: JSR PC,PUTCAD ;CLOSE PRESENT CELL TSTB SEQ ;SHOULD CAD BE RESTORED? BEQ OP5 ;BRANCH IF NOT MOV DOT,CAD ;RESTORE PREVIOUS SEQUENCE CLRB SEQ ;RESET FLAG; NO LONGER NEEDED BR OP2A ; OP5: ADD BW,CAD ;GENERATE NEW ADDRESS OP2: MOV CAD,DOT ;INITIALIZE DOT OP2A: TYPE CRLF ;PLACE CARRIAGE IN PROPER POSITION MOV CAD,R0 ;NUMBER TO TYPE JSR PC,RORA ; CHECK FORMAT MOVB FM,R0 ;SET FORMAT ASR R0 ;SPLIT R0 IN HALF MOVB COMTAB(R0),R0 ;SET SUFFIX CHARACTER TYPE R0 ;PRINT CHARACTER MOV CAD,R4 ;SET UP THE DATA CLR R2 ; SET TO USE CAD ADDRESS CLRB OP ;THIS IS BECUZE CLR EXP JMP CLGL ;R0 HAS TERMIN, R4- DATA, R2= FLAG ;UP ARROW, NEXT ONE UP CLUPAR: JSR PC,PUTCAD SUB BW,CAD ;GENERATE NEW ADDRESS BR OP2 ;GO DO THE REST ;BACK ARROW, PC RELATIVE COMPUTE CLBACK: JSR PC,TCLS ;TEST WORD MODE AND CLOSE ADD @R2,R2 ;COMPUTE CMPB (R2)+,(R2)+ ;NEW ADDRESS PCS: MOV R2,CAD ;UPDATE CAD BR OP2A ;GO FINISH UP ;AT SIGN, ABSOLUTE OR INDIRECT CHAIN CLATSG: JSR PC,TCLS ;TEST WORD MODE AND CLOSE MOV @R2,R2 ;GET ABSOLUTE ADDRESS BR PCS ;GREATER THAN, PC OFFSET BRANCH ADDRESS CLGRTH: JSR PC,TCLS ;TEST AND CLOSE MOVB @R2,R1 ;COMPUTE NEW ADDRESS, EXTEND SIGN ASL R1 ;R2=2@R2) ADD #2,R1 ;+2 ADD R1,R2 ; +PC BR PCS ;HANDY DANDY TO DO SOME LEG WORK TCLS: JSR PC,PUTCAD ;CLOSE CURRENT CELL CMP #2,BW ;ONLY WORD MODE ALLOWED BNE ERR1 ;BRANCH IF ERROR MOV CAD,R2 ;CURRENT ADDRESS IN R2 RTS PC .SBTTL COMMAND PROCESSORS, SECTION TWO ( O = G S P ) .SBTTL "O" PROCESSOR - COMPUTE AND PRINT OFFSETS ;SYNTAX-- ;AO TYPE OFFSETS FROM . TO A ;L;AO TYPE OFFSETS FROM L TO A ;TYPES _PPPPPP >DDDDDD WHERE P-P IS PC RELATIVE ; AND D-D IS BRANCH OFFSET OFST: TST R3 ;HOW ABOUT A VALUE OTHER BNE 10$ ;THAN CAD MOV CAD,R5 ;RELUCTANTLY 10$: SUB R5,R4 SUB #2,R4 ;NO TRICKS, ODD AND NON-EXIST THINGS TYPE '_ ;TYPE PC RELATIVE CUE TYPE 40 ; MOV R4,R0 MOV R4,-(SP) ;GOOD IDEA TO SAVE THIS JSR PC,CADW ;TYPE VALUE + BLANK TYPE 76 ;TYPE OFFSET BRANCH CUE MOV (SP)+,R0 ASR R0 ;DIVIDE OF09: JSR PC,CADW ;16 BITS SO YOU CAN SEE HOW FAR OFF JMP DCD ; GET NEXT COMMAND  .SBTTL "=" PROCESSOR - PRINT LEFT SIDE EXPRESSION ON RIGHT SIDE EQUALS: MOV R4,R0 ;PROPER PRIOR PLANNING PREVENTS BR OF09 ;POOR PERFORMANCE ;JUST ANOTHER ERROR CALL ERR1: ERROR .SBTTL SST INTERRUPT VECTOR ENTRY POINTS .IF DF M$$MGE ; ; SEGMENT FAULT - V1 - "MP" - NO PROCEED ; SGMT: TESTM $SGFLT ;TEST IF IN EXEC MODE BIC #160000,SR0 ;UNFREEZE SEGMENT UNIT MOV #"MP,EXP ;ENTRY PREFIX BR NIXP ; .ENDC ; ; STACK OVERFLOW - - "SO" - NO PROCEED ; ODD ADDRESS - V0 - "OD" - NO PROCEED ; BPT - V2 - "BE" - SPECIAL CASES ; T-BIT - V2 - "TE" - PROCEED ; IOT - V3 - "IO" - PROCEED ; RESERVED OR ILLEGAL - V4 - "IL" - NO PROCEED ; ODDA: MOV #"SO,EXP ;ASSUME STACK OVERFLOW CMP SP,#V$$CTR+4 ;STACK OVERFLOW? BLO NIXP ;IF LO YES TESTM $TRP04 ;TEST IF IN EXEC MODE MOV #"OD,EXP ;"OD:" FOR ODD ONE BR NIXP ;NIX ON PROCEED BPTI: TESTM $TRACE ;TEST IF IN EXEC MODE MOV #"BE,EXP ;"BE:" FOR MAYBE A BAD ENTRY CLRB P ;ALLOW PROCEED DEAL BR INTR ;SPECIAL NUMBER FOR THIS ONE IOTX: TESTM $IOTRP ;TEST IF IN EXEC MODE MOV #"IO,EXP ;"IO:" FOR IOTEE BR ALOP ;ALLOW PROCEED ILLI: TESTM $ILINS ;TEST IF IN EXEC MODE MOV #"IL,EXP ;"IL:" FOR ILL INSTRUCTION NIXP: MOVB #-1,P ;NO PROCEED ;MSH125 .IF DF C$$RSH ;MSH125 ;MSH125 BIS #F3.CRA,$FMASK+4 ;SET FATAL SYSTEM CRASH BIT ;MSH125 ;MSH125 .ENDC ;MSH125 ;MSH125 BR INTR ; .IF DF F$$LTP ;MSH136 ;MSH136 ; ;MSH136 ; FLOATING POINT EXCEPTION - V7 - "FP" - NO PROCEED ;MSH136 ; ;MSH136 ;MSH136 FPPE: TESTM $FLTRP ;TEST IF IN EXEC MODE ;MSH136 MOV #"FP,EXP ;"FP:" FOR FLOATING POINT ;MSH136 BR NIXP ;NIX ON PROCEED ;MSH136 ;MSH136 .ENDC ;MSH136 ;MSH136 ; ; EMT - V5 - "EM" - PROCEED ; TRAP - V6 - "TR" - NO PROCEED ; NEMT: TESTM $EMTRP ;TEST IF IN EXEC MODE MOV #"EM,EXP ;"EM:" FOR EMTEE ALOP: MOVB #BKP+2,P ;ALLOW PROCEED ; ; COMMON INTERRUPT SERVICE AND DISPATCHER ; INTR: BIT #TBT,2(SP) ;T-BIT SET IN STACKED PS WORD? BEQ 1$ ;IF EQ NO CMP PPC,(SP) ;PC CHANGE FROM LAST TRAP? BNE 1$ ;IF NE YES JMP RTN ;RTT MUST HAVE BEEN CHANGED TO AN RTI 1$: MOV (SP)+,UPC ;SET THE USER PC VALUE MOV (SP)+,UST ;AND HIS ENTRY STATUS MOV R0,UR0 ;SAVE EXEC REGISTERS MOV #UR0+2,R0 ;POINT TO REGISTER SAVE AREA MOV R1,(R0)+ ;SAVE REGISTERS R1 THRU SP MOV R2,(R0)+ ; MOV R3,(R0)+ ; MOV R4,(R0)+ ; MOV R5,(R0)+ ; MOV SP,(R0)+ ; MOV #XDTSTK,SP ;SET XDT STACK POINTER MOV #SSTADR,R0 ;POINT TO TRAP VECTOR ADDRESS TABLE MOV #SSTXDT,R1 ;POINT TO XDT TRAP VECTOR TABLE 5$: MOV (R1)+,@(R0)+ ;SET XDT TRAP VECTOR ADDRESSES CMP R1,#SSTADR ;ANY MORE TO SET? BLO 5$ ;IF LO YES ;TRY AND FIND OUT WHAT TO DO TSTB P ;SEE IF CONTROLLED BREAKPOINT BNE 10$ ;NOT DUE TO A PLANNED INTERRUPT TSTB T ;IS A BPT OR T-BIT, SEE IF A PROCEED BNE TBIT ;COMMAND IS BEING DONE, GO FINISH IT TSTB S ;NO REMOVAL OF BREAKS ON S.I. MODE BNE 12$ ;SKIP NEXT TWO WORDS ; ; REMOVE EXEC BREAKPOINTS ; 10$: MOV #ADR1,R4 ;POINT TO BREAKPOINT VECTOR 11$: MOV UIN-ADR1(R4),@(R4)+ ;REINSERT CORRECT CONTENTS CMP #ADR1+BKP,R4 ;ANY LEFT TO RESTORE? BHIS 11$ ;IF HIS YES 12$: MOV UPC,R5 ;GET A COPY OF THE PC AT INTERRUPT TSTB P ;BREAKPOINT OR T-BIT CHECK BNE 30$ ;DEFINITELY NOT A BREAKPOINT MOVB S,R4 ;SEE IF SINGLE STEPPING BNE 22$ ;AND PRETEND ;AT THIS POINT IT MAY BE DUE TO T-BIT OR A BPT MOVB #BKP+2,P ;SET ALLOW TO THE 8'TH ONE CMP -(R5),TRTC ;BACK-UP R5 AND SEE WHAT'S UP BEQ 30$ ;IT WAS A NON-BREAK BPT MOV #BKP,R4 ;SET ADDRESS OF LEGIT BREAKS 15$: CMP R5,ADR1(R4) ;LOOK IT UP IN THE TABLE BEQ 20$ ;FOUND THE NASTY LITTLE BUGGER SUB #2,R4 ;KEEP AT IT BGE 15$ ;UNLESS NO MORE MOV #"TE,R4 ;NOT THERE, MUST BE T-BIT ERROR TST (R5)+ ;RESET PC TO MAKE IT RIGHT BR 26$ ;LABOR 20$: MOV R5,UPC ;BACK-UP PC FOR BREAKPOINT 22$: MOVB R4,P ;BREAKPOINT IS A REAL ONE DEC CT(R4) ;CHECK OUT THE PROCEED COUNT BNE C990 ;LABOR ON A MIS-CONCEPTION INC CT(R4) ;RESET PROCEED COUNT ASR R4 ;OCTAL TO UN-BIASED ASCII ADD #"0B,R4 ;BIAS TO ASCII 26$: MOV R4,EXP ;SET THE PREFIX UP ;COMMON TYPE ROUTINE FOR SST VECTORS USED UP 30$: TYPE CRLF ;PLACE CARRIAGE IN PROPER POSITION MOV EXP,R0 ;THE PREFIX TYPE R0+R0 ; TYPE ': ; MOV R5,R0 ;TYPE ADDRESS OF INTERRUPT JSR PC,RORA ;AND THE REST OF THE ENTRY DECODE ; ; TRAPS ARE ALWAYS HANDLED BY EXEC ; TRPI: JMP $TRTRP ; ; ; "G" PROCESSOR - GO TO PROGRAM ;SYNTAX-- ;LG START PROGRAM AT LOCATION L ;G START PROGRAM AT CURRENT PC GOTO: CLR R0 ;MAKE SURE THAT LAST CHARACTER TYPED IS ;MSH137 5$: INC R0 ;OUTPUT BEFORE EXECUTING RESET IN INITL ;MSH137 BNE 5$ ; ;MSH137 TST R2 ;SEE IF SPECIFIC ADDRESS ;MSH137 BEQ 10$ ;NO ;**-1 MOV R4,UPC ;SET THE PC 10$: CLRB S ;NO SINGLE INSTRUCTIONS TBIT: CLRB T ;CLEAR T-BIT FLAGS BIS #TBT,UST ;BOTH TSTB S ;SEE IF WE NEED A T-BIT BIT BNE GRTT ;NO GO ON BIC #TBT,UST ;SET THE TEE BIT ; ; SET EXEC BREAKPOINTS ; 10$: MOV #ADR1,R4 ;POINT TO BREAKPOINT VECTOR 20$: MOV @(R4),UIN-ADR1(R4) ;SAVE CONTENTS OF LOCATION MOV TRTC,@(R4)+ ;SET BREAKPOINT CMP #ADR1+BKP,R4 ;ANY MORE TO INSERT? BHIS 20$ ;IF HIS YES GRTT: MOV #PR7,-(SP) ;SET RTT PS WORD MOV #20$,-(SP) ;SET RTT PC WORD MOV #10$,@#10 ;PLUG ILLEGAL INSTRUCTION TRAP MOV (PC),R0 ;GET RTT INSTRUCTION CODE RTT ;EXECUTE RTT INSTRUCTION 10$: ADD #4,SP ;CLEAN STACK MOV (PC)+,R0 ;GET RTI INSTRUCTION CODE RTI ; 20$: MOV R0,RTN ;SET PROPER RETURN INSTRUCTION MOV #SSTADR,R0 ;POINT TO TRAP VECTOR ADDRESS TABLE MOV #SSTVEC,R1 ;POINT TO EXEC TRAP VECTOR TABLE 30$: MOV (R1)+,@(R0)+ ;SET EXEC TRAP VECTORS CMP R0,#SSTADR+ ;ANY MORE TO SET? BLO 30$ ;IF LO YES MOV #UR0+2,R0 ;POINT TO SAVED R1 MOV (R0)+,R1 ;RESTORE REGISTERS R1 THRU SP THEN R0 MOV (R0)+,R2 ; MOV (R0)+,R3 ; MOV (R0)+,R4 ; MOV (R0)+,R5 ; MOV (R0)+,SP ; MOV UR0,R0 ; MOV UST,-(SP) ;SET EXEC PS WORD MOV UPC,-(SP) ;SET EXEC PC WORD MOV (SP),PPC ;SET PREVIOUS PC WORD RTN: RTI ;RETURN TO EXEC (MAY BE CHANGED TO RTT) ; ; "S" PROCESSOR - SINGLE STEP PROCEED ;SYNTAX-- ;NS EXECUTE N INSTRUCTIONS AND THEN STOP ;S EXECUTE ONE INSTRUCTION SNGL: MOVB #BKP+2,R0 ;FAKE THE BREAK MOVB R0,S ;SET THE FLAG FOR S.I. MODE BR PR01 ;FAKE A PROCEED IN S.I. MOOD ; ; "P" PROCESSOR - PROCEED FROM BREAKPOINT ;SYNTAX-- ;NP PROCEED THRU THIS BREAKPOINT N TIMES ;P ASSUME N=1 PROC: CLRB S ;SET FAST MODE MOVB P,R0 ;GET NUMBER OF BREAK BMI PR02 ;THERE WASN'T ONE SO FAR ? PR01: TST R2 ;SEE IF VALUE IN R4 VIA R2 BNE 10$ ;SEE IF AND WHAT SETTING FOR COUNT MOV #1,R4 ;INIT IT TO ONE FOR A START 10$: MOV R4,CT(R0) ;SET USER'S COUNT C990: CMPB P,#BKP ;SEE IF A REAL ONE OR A FAKE BGT TBIT ;BRANCH IF FAKE TSTB S ;SEE IF SINGLE INSTRUCTION MODE BNE TBIT ;IF SO EXIT NOW INCB T ;SET T-BIT FLAG BIS #TBT,UST ;SET T-BIT BR GRTT PR02: ERROR ;ANNOUNCE ERROR ; ; TEST IF IN EXEC MODE ; TESTM: MOV (R5)+,-(SP) ;PICK UP EXEC TRAP ROUTINE ADDRESS .IF DF M$$MGE TST $STKDP ;ALLOW EXEC TO HANDLE TRAP? BGT 20$ ;IF GT YES, TRAP WAS IN USER MODE BLT 10$ ;IF LT NO, BAD STACK DEPTH ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 CMP KISAR5,$XCOM1 ;FIRST EXEC COMMON MAPPED? ;MSH165 BNE 10$ ;IF NE NO, SKIP EXEC BOUNDS CHECKS ;MSH165 ;MSH045 .ENDC ;D$$PAR ;MSH045 ;MSH045 CMP 4(SP),#$DRLM1 ;TRAP OCCUR IN DIRECTIVE DISPATCHER? BLO 5$ ;IF LO NO CMP 4(SP),#$DRLM2 ;TRAP OCCUR IN DIRECTIVE DISPATCHER? BLOS 20$ ;IF LO YES, PASS TRAP TO EXEC 5$: CMP 4(SP),#$DQLM1 ;TRAP OCCUR IN QIO DIRECTIVE? BLO 6$ ;IF LO NO CMP 4(SP),#$DQLM2 ;TRAP OCCUR IN QIO DIRECTIVE? BLOS 20$ ;IF LOS YES, ALLOW EXEC TO HANDLE TRAP 6$: ;REF LABEL .IF DF P$$LAS CMP 4(SP),#$DPLM1 ;FAULT OCCUR RETRIEVING DEF BLOCK ADDR? BLO 10$ ;IF LO NO CMP 4(SP),#$DPLM2 ;FAULT OCCUR RETRIEVING DEF BLOCK ADDR? BLOS 20$ ;IF LOS YES, ALLOW EXEC TO HANDLE TRAP .ENDC .IFF TST $STKDP ;TRAP IN EXEC? BLE 10$ ;IF LE YES CMP 4(SP),$EXSIZ ;TRAP OCCUR IN EXEC CODE? BHIS 20$ ;IF HIS NO BIT #PR7,6(SP) ;EXECUTING AT PRIORITY OTHER THAN ZERO? BEQ 20$ ;IF EQ NO .ENDC 10$: MOV R5,(SP) ;SET TO XDT ADDRESS 20$: MOV (SP)+,R5 ;SET RETURN ADDRESS RTS R5 ;PROCESS TRAP .SBTTL COMMAND PROCESSORS, SECTION THREE ( L V X W N E F ) .SBTTL "L" PROCESSOR - LIST MEMORY ON THE SPECIFIED DEVICE ;SYNTAX-- ; D;S;FL WHERE D IS DEV, <> OR 0 = CONSOLE, 1 = LPT ; S IS START ADDRESS, SETS $L IF THERE ; F IS STOP ADDRESS, SETS $H IF THERE LIST: TST R2 ;SET UPPER AND LOWER LIMITS BEQ 10$ ;IF SPECIFIED TO DO SO MOV R4,HI 10$: TST R3 ;DO THE LOW ONE BEQ 15$ MOV R5,LOW 15$: CMPB #2,SMFD ;SEE IF AN EXTRA ARGUMENT BNE 17$ ;USE THE CONSOLE TST D.ARGS ;LOOK AT THE ARGUMENT BEQ 17$ ;DO NOT ARGUE MOV #LPS,OUTS ;SET OUTPUT STATUS REGISTER TO LINE PRINTER MOV #LPB,OUTB ; TYPE 14 ;OUTPUT A FORM FEED 17$: MOV LOW,R5 ;GET STARTING DUMP ADDRESS MOVB OBW,R0 ;GET ADDRESS INCREMENT SUB R0,R5 ;BIAS ADDRESS BY ADDRESS INCREMENT MOV R5,CAD ;SET CURRENT ADDRESS TST -(SP) ;MAKE A HOLE IN THE STACK 20$: CLR (SP) ;NEW LINE UP JSR PC,SNAGIT ;ACCESS DEVICE FOR DATA JSR PC,SPRINT ;PRINT ADDRESS AND FIRST ITEM 25$: JSR PC,SNAGIT ;GET MORE DATA JSR PC,DPRINT ;JUST PRINT THE DATA INC (SP) ;COUNT THE DATA CMP #7,(SP) ;CHECK THE COUNT BNE 25$ ;JUST LIKE THEY TOLD YOU AT THE BR 20$ ;FAMOUS PROGRAMMERS SCHOOL ; ; EXIT COMMAND ; ; SYNTAX X ; ; THE EXIT COMMAND IN XDT EFFECTS A JUMP TO THE EXECUTIVE $CRASH ROUTINE. ; EXIT: MOV #UR0+2,R0 ;POINT TO SAVED R1 MOV (R0)+,R1 ;RESTORE REGISTERS R1 THRU SP THEN R0 MOV (R0)+,R2 ; MOV (R0)+,R3 ; MOV (R0)+,R4 ; MOV (R0)+,R5 ; MOV (R0)+,SP ; MOV UR0,R0 ; .IF DF C$$RSH ;MSH137 ; MOVING THE DATA DIRECTLY PREVENTS A POSSIBLE STACK OVERFLOW ERROR ;MSH137 MOV UST,$CRUST ; MOVE USER PS FOR THE CRASH MODULE MOV UPC,$CRUPC ; MOVE USER PC FOR THE CRASH MODULE JMP $CRALT ; ALTERNATE ENTRY POINT TO THE CRASH MODULE .IFF JMP $CRASH ;IF NO CRASH SUPPORT, JUST CRASH .ENDC .SBTTL UTILITIES - COMMAND SUPPORT ROUTINES ;TEST FOR VALID RELOCATION REGISTER IN R4 RTST: CMP #RLR/2,R4 ;GET A GOOD NUMBER FOR A REGISTER BLO 10$ ;NOT TOO GOOD, QUESTION IT ASL R4 10$: RETURN ; ;SNAG MEMORY LOCATION JSR PC,SNAGIT ;NEEDS-- ;CAD POINTS TO MEMORY WORD (APPROXIMATELY THAT IS) ;R0,R5 CONTAINS REAL WORD UPON EXIT TO "SRCHEK" SNAGIT: MOVB OBW,R0 ;SET THE INCREMENT ADD R0,CAD ;INCREMENT AND NOW CMP CAD,HI ;SEE IF MORE TO DO BLOS 10$ ;IF NOT DO NOT DECODE ;GO RESET STACK AND NO NEXT COMMAND 10$: JSR PC,GETCAD ;ACCESS METHOD MOV R0,R5 ;MAKE A COPY FOR LATER RETURN ; ;SEARCH HIT PRINT JSR PC,SPRINT ;CAD POINTS TO THE LOC TO BE PRINTED ;R5 CONTAINS THE CONTENTS OF THE LOCATION TO BE PRINTED SPRINT: TYPE CRLF ;PLACE CARRIAGE IN PROPER POSITION MOV CAD,R0 ;THE LOCATION JSR PC,RORA ;THE MODE MOVB FM,R0 ;PICK UP OLD CURENT MODE ASR R0 ;HALVES MOVB COMTAB(R0),R0 ;AH HA TYPE R0 ;TYPE THE MODE REGISTER ;DATA PRINT ROUTINE JSR PC,DPRINT ;PRINTS DATA IN R5 IN CURRENT MODE DPRINT: MOVB FM,R1 ;SET THE MODE MOV R5,R0 ;THIS IS THE POOR DATA MOV R5,-(SP) ;SAVE THE DATA JSR PC,@TYFORM(R1) ;DO THAT __ TO THE POOR DATA MOV (SP)+,R5 ;RESTORE THE DATA RTS PC ;RESTORE THE PC ;EXPRESSION COMPUTATION ROUTINE JSR PC,EXPCOM ;NEEDS-- ;OP THE OPERATION (-2=*, 0=+, *=2) ;EXP THE LEFT SIDE ;R4 THE RIGHT SIDE ;SETS UP-- ;OP BACK TO 0 FOR ADD ;EXP,R4 ALL SO FAR EXPCOM: TSTB OP ;SEE WHAT'S UP CHUCK BMI 20$ BEQ 10$ NEG R4 ;MINUS, OP=2 10$: ADD EXP,R4 ;PLUS, OP=0 15$: MOV R4,EXP ;COMMON OUT, SET EXP TO WHATEVER CLRB OP ;IS IN R4 TOO INC R2 ;SET R2 SO THAT R4 IS, OP=0 RTS PC 20$: MOV EXP,-(SP) ;GET THE LEFT SIDE OF EXPRESSION ASL (SP) ; MULTIPLY BY 10 ASL (SP) ; ASL (SP) ; ADD (SP),R4 ; ADD IT ASL (SP) ; MULTIPLY BY 40 ASL (SP) ; WHICH IS LIKE MULTIPLYING BY 50 ADD (SP)+,R4 ;AND ADD IT TO THE RIGHT BR 15$ ;COMMON OUT ;BUILD AN OCTAL NUMBER JSR PC,GETNUM ;NEEDS AND RETURNS-- ;R0 NON-OCTAL TERMINATING CHARACTER ;R2 OCTAL CHARACTER COUNT ;R4 OCTAL NUMBER THAT I GOT, YOU GET GETNUM: CLR R2 ;NEW R2 AND R4 CLR R4 10$: JSR PC,GET ;GET 1 CHARACTER CMPB #'0,R0 ;NON-OCTAL, LESS THAN "0" BHI GETC99 CMPB #'7,R0 ;NON-OCTAL, LESS THAN "7" BLO GETC99 BIC #177770,R0 ;MAKE INTO ACCEPTABLE RANGE ASL R4 ; SHIFT LEFT ASL R4 ; 3 BITS ASL R4 ; ADD R0,R4 ;PLANT LO PLACE INC R2 ;ACCOUNT FOR NEW ONE BR 10$ ;NEXT ONE OR OTHER ;SCAN A LIST OF CHARACTERS JSR R5,LOOKUP ;CALL-- ; R0 HAS THE CHARACTER ; JSR R5,LOOKUP ;THAT IS IT ; + LIST TO USE, 00 BYTE IS END OF LIST ;RETURNS AT CALL + 2 WITH-- ;R0 STILL HAS CHARACTER ;R1 HAS INDEX X2 OF FOUND CHARACTER IF C=0 ;C=1 CHARACTER WAS NOT FOUND LOOKUP: MOV (R5),R1 ;GET LIST START 10$: CMPB R0,(R1) ;IS THIS THE ONE BNE 20$ ;RIGHT IT WASN'T SUB (R5)+,R1 ;COMPUTE INDEX AND RETURN ASL R1 ;DO THIS FOR EVERBODY, C=0 BR 30$ 20$: TSTB (R1)+ ;CHECK FOR END OF LIST BNE 10$ ;IF NOT LOOK AT NEXT ITEM TST (R5)+ ;END, AVOID ILLEGAL INSTRUCTION SEC ;SECURITY EXCHANGE COMMISION 30$: RTS R5 ;SECURITY ELSEWHERE ;GET CONTENTS OF ADDRESS IN THE MODE JSR PC,GETCAD ;NEEDS-- ;R0 THE MODE 1=BYTE, 2=WORD ;CAD THE ADDRESS ;DEVI THE DEVICE CODE ;RETURNS-- ;R0 HAS THE DATA YOU ASKED FOR GETCAD: MOV CAD,R3 ; GET CORE ADDRESS MOV SP,OPN ; SET LOCATION OPEN ASR R0 ;PUSH BW FLAG INTO CARRY BIT BCC 10$ ;2 WON'T FIT SO IS WORD MOVB (R3),R0 ;ACCESS BYTE BR GETC99 10$: MOV (R3),R0 ;ACCESS WORD GETC99: RTS PC ;STACK ACCESS ;PUT R4 INTO ADDRESS IN THE MODE JSR PC,PUTCAD ;NEEDS-- ;R2 CONTENT FLAG, 0 FOR NONE, ELSE R4 IS GOLD ;R4 THE DATA ;BW THE MODE FLAG, IF 0 THEN NO LOCATION OPEN PUTCAD: TST R2 ;CHECK FOR TYPED VALUE BEQ 12$ ;NO DATA NO DODO MOV BW,R0 ;PICK UP MODE AN CC'S TST OPN ; IS A LOCATION OPEN AT PRESENT? BEQ 12$ ;NOT OPEN NOT STORED MOV CAD,R3 ; GET CORE ADDRESS BIT #177776,R0 ;CHECK MODE BNE 10$ ;WORD MODE MOVB R4,(R3) ;BYTE MODE BR 12$ ;BRANCH MODE 10$: MOV R4,(R3) ;WORD MODE 12$: RTS PC ; ; GET CHARACTER FROM CONSOLE TERMINAL ; GET: TSTB TKS ;CHARACTER READY? BPL GET ;IF PL NO MOVB TKB,R0 ;READ INPUT BYTE BIC #177600,R0 ;CLEAR EXCESS BITS CMPB R0,#23 ;CONTROL-S TYPED? ;MSH155 BNE 10$ ;IF NE NO ;MSH155 5$: TSTB @#TKS ;HAS A CHARACTER BEEN TYPED? ;MSH155 BPL 5$ ;IF PL NO ;MSH155 MOVB @#TKB,R0 ;READ INPUT BYTE ;MSH155 BIC #177600,R0 ;CLEAR EXCESS BITS ;MSH155 CMPB R0,#21 ;CONTROL-Q TYPED? ;MSH155 BNE 5$ ;IF NE NO, IGNORE THIS INPUT ;MSH155 BR 40$ ;DON'T ECHO CONTROL-Q ;MSH155 ;MSH155 10$: CMPB R0,#12 ;BRANCH IF ;MSH155 BEQ 40$ ;NO ECHO 'S ;**-1 JSR R5,LOOKUP ;CHECK IF ALTMODE + ALTTAB BCS 20$ ; MOVB #'$,R0 ;CHANGE TO $ IF SO 20$: MOV R0,-(SP) ;SAVE INPUT CHARACTER TYPE R0 ;ECHO CHARACTER MOV (SP)+,R0 ;RESTORE INPUT CHARACTER CMP #141,R0 ;LOWER CASE CHARACTER? BHI 30$ ;IF HI NO CMP #172,R0 ;LOWER CASE CHARACTER? BLO 30$ ;IF LO NO SUB #40,R0 ;CONVERT TO UPPER CASE CHARACTER 30$: CMPB #' ,R0 ;CVT BLANK BNE 40$ MOVB #'+,R0 ;INTO + 40$: RETURN ; ; ; TYPE CHARACTER ON OUTPUT DEVICE ; TYPE: MOV (SP),-(SP) ;DUPLICATE RETURN ADDRESS SUB #2,(SP) ;POINT TO TRAP INSTRUCTION MOVB @(SP)+,-(SP) ;GET LOW BYTE OF INSTRUCTION BMI 10$ ;IF MI CONTROL BYTE MOV (SP)+,R0 ;SET BYTE TO OUTPUT BR 30$ ; 10$: BIT #40,(SP) ;OUTPUT CONTENTS OF R0? BEQ 20$ ;IF EQ YES MOV (PC)+,R0 ;SET TO OUTPUT .BYTE 15,12 ; 20$: ASLB (SP)+ ;OUTPUT TWO BYTES? BPL 30$ ;IF PL NO TYPE R0 ;TYPE OUT FIRST BYTE SWAB R0 ;SET UP HIGH BYTE 30$: CMP OUTS,#TPS ;IS OUTPUT DEVICE A TERMINAL? ;MSH155 BNE 34$ ;IF NE NO ;MSH155 TSTB @#TKS ;HAS A CHARACTER BEEN TYPED IN? ;MSH155 BPL 34$ ;IF PL NO ;MSH155 MOVB @#TKB,-(SP) ;GET THE CHARACTER ;MSH155 BICB #200,(SP) ;REMOVE PARITY BIT ;MSH155 CMPB (SP)+,#23 ;IS IT A CONTROL-S? ;MSH155 BNE 34$ ;IF NE NO, IGNORE IT ;MSH155 33$: TSTB @#TKS ;HAS A CHARACTER BEEN TYPED IN? ;MSH155 BPL 33$ ;IF PL NO ;MSH155 MOVB @#TKB,-(SP) ;GET THE CHARACTER ;MSH155 BICB #200,(SP) ;CLEAR PARITY BIT ;MSH155 CMPB (SP)+,#21 ;IS IT A CONTROL-Q? ;MSH155 BNE 33$ ;IF NE NO, IGNORE IT ;MSH155 34$: TSTB @OUTS ;OUTPUT DEVICE READY? ;MSH155 BPL 34$ ;IF PL NO  ;MSH155 MOVB R0,@OUTB ;OUTPUT BYTE ;**-2 35$: TSTB @OUTS ;OUTPUT DEVICE READY? BPL 35$ ;IF PL YES CMPB #15,R0 ;WAS OUTPUT BYTE A CARRIAGE RETURN? BNE 50$ ;IF NE NO CMP #LPS,OUTS ;OUTPUT DEVICE LINE PRINTER? BEQ 50$ ;IF EQ YES MOV #5,-(SP) ;SET FILL COUNT TO 5 CLRB R0 ;SET OUTPUT NULLS 40$: TYPE R0 ;OUTPUT A NULL DEC (SP) ;ANY MORE TO OUTPUT? BGT 40$ ;IF GT YES TST (SP)+ ;CLEAN STACK 50$: RTI ; .SBTTL UTILITIES - PRETTY PRINTERS ;PRINT ADDRESS- RELOC, SYMBOLIC, OR ABSL JSR PC.RORA ;R0 ADDRESS TO BE PRINTED ;FORM CORE ADDRESS FORMAT (0-RELOC 1-ABSOL) ;REGISTER '$R ' OR '$DR ' ;CORE 'D,XXXXXX ' OR 'XXXXXX ' RORA: MOV R0,-(SP) ;CALLING VALUE ONA TOPPA SATCK CMP #INTBEG,(SP) BHI 50$ ;BELOW FIRST NON-INDEXED CMP #INTEND,(SP) BLO 50$ ;ABOVE LAST NON-INDEXED TYPE '$ ;ANNOUNCE INTENSIONS CMP #INTINX,(SP) BLOS 20$ ;GO TO DO INDEXED MOV (SP)+,R0 ;NON-INDEXED REGISTER ----- "$R " SUB #INTBEG,R0 ;CLEANED UP STACK, GET OFFSET ASR R0 ;BYTE THAT WORD, WORD THAT BYTE MOVB NIXMAP(R0),R0 ;MAGIC CHARACTER FROM TABLE 15$: BIS (PC)+,R0 .BYTE 000,' ;CHARACTER PLUSSA BLANK TYPE R0+R0 ;NAME PLUS BLANK AND SPLIT RETURN ; 20$: CLR R1 ;SEE WHICH SET OF TABLES WE GOT 22$: CMP INXTBL+2(R1),(SP) ;LOOK ON AHEAD TO FIND BEHIND BHI 24$ ;R1 POINTS TO BASE OF SET TST (R1)+ ;THINK ABOUT THOSE DUMMY ENTRIES DUMMY BR 22$ 24$: MOV (SP)+,R0 ;INDEXED REGISTER ---- "$DR " SUB INXTBL(R1),R0 ;GET ADDRESS AND COMPUTE OFFSET IN WORDS ASR R0 ;AND FINALLY IN PLAIN TALK ADD #'0,R0 ;CONVERT TO ASCII TYPE R0 ;TYPE OUT REGISTER NUMBER ASR R1 MOVB INXREG(R1),R0 ;PICK UP THE REAL CHARACTER BR 15$ ;GO PRINT REST OF IT 50$: TST FORM ;CORE ADDRESS SEE WHAT USER WANTS BNE 80$ ;TYPE AS ABSOLUTE. MOV (SP),R4 ;RELOCATE ---- "R,XXXXXX " JSR PC,LOCA ;WE ALWAYS PICK, XDT KNOWS BEST BMI 80$ ;BUT NOT ALL THE TIME MOV R1,(SP) ;SET THE DISPLACEMENT ADD #"0,,R0 ;PRINT REGISTER AND COMMA TYPE R0+R0 ;DISK AND CORE 80$: MOV (SP)+,R0 ;PRINT R0 AS A WORD ;TYPE R0 AS BYTE OR WORD, TWO ENTRIES ; FOR A WORD JSR PC,CADW ; FOR A BITE JSR PC,CADB CADW: MOV R0,QUAN ;SET THE FAMOUS QUANTITY VALUE MOV #6,R3 ;# OF DIGITS MOV #-2,R4 ;# OF BITS FIRST-3 BR CA01 ;DO THE COMMON THING CADB: CLR QUAN ;SET FOR ALL OF QUAN A BYTE MOVB R0,QUAN ;SET THE QUANTITY THING AGAIN MOV #3,R3 ;THERE ARE THREE DIGITS MOV #-1,R4 ;AND ONLY TWO BITS SWAB R0 ;SWITCH ENDS CA01: MOV R0,-(SP) ;SAVE R0 10$: ADD #3,R4 ;COMPUTE THE NUMBER OF BITS TO DO CLR R0 15$: ROL (SP) ;GET A BIT ROL R0 ;STORE IT AWAY DEC R4 ;DECREMENT COUNTER BGT 15$ ;LOOP IF MORE BITS NEEDED ADD #'0,R0 ;CONVERT TO ASCII TYPE R0 ;TYPE IT DEC R3 ;SEE IF MORE DIGITS TO DO BGT 10$ ;LOOP IF SO MOVB #' ,R0 ;SET UP FOR TRAILING SPACE TST (SP)+ ;GET RID OF JUNK FT01: TYPE R0 ; RETURN ; ;TYPE CONTENTS OF WORD IN FORMAT JSR PC,@TYFORM(R1) ;R0 WORD OR BYTE TO BE TYPED, RHJ ;R1 CODE- ENTRY PT, FORMAT, CODE TYFORM: + CADB ;BYTE OCTAL - 0 + CADW ;WORD OCTAL - 2 + 30$ ;BYTE ANSII - 4 + 20$ ;WORD ANSII - 6 + 10$ ;RADIX 50 - 10 10$: JSR PC,TYRADX ;R0 GETS THE RADIX 50 TREATMENT BR 35$ ;APPEND A BLANK TO 3 CHAR'S 20$: TYPE R0 ;TYPE BYTE IN R0 SWAB R0 ;SWAP EM AND TYPE IT 30$: TYPE R0 ;TYPE BYTE IN R0 35$: TYPE 40 ;TYPE A SPACE RETURN ; ;TYPE CONTENTS OF R0 IN RADIX 50 JSR PC,TYRADX TYRADX: MOV #3,R5 ;COUNT OF CHARACTERS MOV #50$,R2 ;POINTER TO COEFFICENT TABLE MOV R0,R1 ;COPY OF RADIX 50 WORD 10$: MOV R1,R0 ; GET DIVIDEND MOV (R2)+,R1 ; GET DIVISOR JSR PC,$DIV ; DIVIDE, R0=QUOTIENT, R1 =REMAINDER TST R0 ; IS QUOTIENT ZERO? (SP)? BEQ 12$ ;"SP" = 040 CMPB R0,#33 ;RAD50-$ =33 BEQ 16$ ;"$" = 044 BGT 14$ ;"." OR "0-9" = 056 OR 060-071 ADD #40,R0 ;RAD50-A = 1, "A" = 101 12$: ADD #16,R0 ;40+16+11+11 = 100 + (A-Z) 14$: ADD #11,R0 ;16+11+11 = 40 + (SP) 16$: ADD #11,R0 ;11+11 = 22 + (.,0-9) TYPE R0 ;TYPE CHARACTER IN R0 DEC R5 ;COUNT THE CHARACTERS BNE 10$ ; LOOP  RTS PC ;COEFFICENT TABLE, RADIX 50 CONVERT 50$: .WORD +1600.,+40.,+1. ;40.^2, 40.^1, 40.^0 ;SELECT RELOCATION REGISTER JSR PC,LOC ;CAD ADDRESS TO USE IN SELECTION ;RETURNS-- ;R0 REGISTER NUMBER FOUND, -1 IF NONE FOUND ;R1 DISTANCE, RELOCATION FACTOR ;SUBROUTINE TO LOCATE RELOCATION REGISTER NEAREST BUT STILL ;BELOW THE ADDRESS IN CAD. RETURNS WITH THE REGISTER ;NUMBER IN R0, AND WITH THE DISTANCE BETWEEN THE REGISTER ;AND (CAD) IN R1 ;IF NO GOOD RELOC. REG. FOUND, R0 WILL = -1 LOC: MOV CAD,R4 ;SET UP CAD DATA LOCA: CLR R0 MOV #-1,-(SP) ;INITIALIZE RELOC. REG. INDEX MOV (SP),R1 ;INITIALIZE DISTANCE TO A HIGH VALUE 10$: CMP R0,#RLR ;ARE WE DONE COMPARING? BHI 20$ ;BRANCH IF DONE CMP RELT(R0),R4 ;IS CURR. RELOC. BIAS > (R4)? BHI 15$ ;IF SO, BRANCH -- DON'T SUBTRACT, GET NEXT MOV R4,R2 ;OTHERWISE TAKE THE DIFFERENCE SUB RELT(R0),R2 ;OF CURR. RELOC. REG. AND CAD CMP R1,R2 ;IS THE RESULT THE SMALLEST SO FAR? BHI 25$ ;BRANCH IF YES (UNSIGNED CONDITIONAzL) 15$: TST (R0)+ ;OTHERWISE, BUMP R0 FOR NEXT RELOC. REG. BR 10$ ;LOOP BACK FOR NEXT COMPARISON 20$: MOV (SP)+,R0 ;PUT REG.# IN R0 RTS PC ;JOB OVER, RETURN 25$: MOV R2,R1 ;REMEMBER SMALLEST DIFFERENCE IN XXY ASR R0 ;AND ASSOCIATED REGISTER NUMBER MOV R0,(SP) ; IN (SP) ASL R0 ;RESTORE R0 TO ORIGINAL VALUE BR 15$ ;GO FO NEXT COMPARISON. .END $XDT zäðskQ ›c, .TITLE ADDRV .IDENT /04/ ; ; COPYRIGHT (C) 1974, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 04 ; ; D. N. CUTLER 24-NOV-73 ; ; AD01-D ANALOG TO DIGITAL CONVERTER CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; LOCAL DATA ; ; DRIVER DISPATCH TABLE ; $ADTBL::.WORD ADINI ;DEVICE INITIATOR ENTRY POINT .WORD ADCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD ADCAN ;DEVICE TIMEOUT ENTRY POINT .WORD ADCAN ;POWERFAIL ENTRY POINT ;+ ; **-ADINI-AD01-D ANALOG TO DIGITAL CONVERTER CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS RECEIVED FOR THE AD01-D ANALOG TO DIGITAL CONVERTOR. THE AD01-D HAS SUCH A ; FAST CONVERSION RATE (APPROXIMATELY 30US) THAT CONVERSIONS ARE PROGRAM ; RATHER THAN INTERRUPT DRIVEN. THUS REQUESTS ARE NOT QUEUED BY THE QUEUE I/O ; DIRECTIVE AND THE QUEUING/DEQUEUING OVERHEAD IS BYPASSED. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLER TO BE INITIATED. ; ; AD01-D I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RBC). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER. ; WD. 15 -- VIRTUAL ADDRESS OF CONTROL BUFFER. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; ; THE DATA BUFFER RECEIVES CONVERTED VALUES AND THE CONTROL BUFFER CONTAINS ; CONTROL WORDS THAT CONTROL THE CONVERSION PROCESS. EACH WORD IN THE CONTROL ; BUFFER HAS THE FORMAT: ; ; BITS 15-12 -- GAIN CODE. ; ; LEGAL GAIN CODES ARE: ; ; 0000=GAIN OF 1. ; 0001=GAIN OF 2. ; 0010=GAIN OF 4. ; 0011=GAIN OF 8. ; ; BITS 11-0 -- CHANNEL NUMBER. ; ; EACH AD01-D MAY HAVE 64. CHANNELS. THE LEGALITY OF ; A PARTICULAR CHANNEL NUMBER IS DETERMINED BY THE ; SECOND DEVICE CHARACTERISTICS WORD. ; ; OUTPUTS: ; ; EACH CHANNEL IS CONVERTED ACCORDING TO THE CORRESPONDING WORD IN ; THE CONTROL BUFFER AND THE RESULTANT VALUE IS PLACED IN THE ; DATA BUFFER. IF AN ILLEGAL CONTROL WORD OR AD01-D ERROR IS DE- ; TECTED, THEN THE CONVERSION PROCESS IS TERMINATED. THE SECOND I/O ; STATUS WORD SPECIFIES THE NUMBER OF CHANNELS THAT WERE CONVERTED. ;- ADINI: MOV R1,R3 ;COPY ADDRESS OF I/O PACKET MOV I.PRM+6(R3),R0 ;GET VIRTUAL ADDRESS OF CONTROL BUFFER .IF DF A$$CHK!M$$MGE MOV I.PRM+4(R3),R1 ;SET LENGTH OF BUFFER TO CHECK CALL $ACHCK ;ADDRESS CHECK CONTROL BUFFER BCS 50$ ;IF CS ADDRESS CHECK FAILURE .IFTF CALL $RELOC ;RELOCATE CONTROL BUFFER ADDRESS MOV R5,R0 ;COPY ADDRESS OF UCB ADD #U.BUF,R0 ;POINT TO BUFFER RELOCATION BIAS MOV I.PRM(R3),(R0)+ ;INSERT DATA BUFFER RELOCATION BIAS MOV I.PRM+2(R3),(R0)+ ;INSERT DATA BUFFER ADDRESS CLR (R0)+ ;CLEAR NUMBER OF SAMPLES PERFORMED MOV R1,(R0)+ ;INSERT CONTROL BUFFER RELOCATION BIAS MOV R2,(R0) ;INSERT CONTROL BUFFER ADDRESS MOV S.CSR(R4),R4 ;GET ADDRESS OF CONTROL STATUS REGISTER ; ; INITIATE I/O OPERATION ; 10$: CALL $GTCWD ;GET NEXT WORD FROM CONTROL BUFFER MOV (SP)+,R1 ;RETRIEVE CONTROL WORD BIT #147700,R1 ;BAD GAIN OR CHANNEL? BNE 60$ ;IF NE YES CMPB R1,U.CW2(R5) ;LEGAL CHANNEL THIS CONTROLLER? BHIS 60$ ;IF HIS NO SWAB R1 ;SWAP CHANNEL AND GAIN FIELDS RORB R1 ;ADJUST GAIN TO PROPER POSITION MOV R1,(R4) ;START CONVERSION MOV #6,R2 ;SET REPEAT COUNT 20$: BIT #100200,(R4) ;ERROR OR READY? BMI 30$ ;IF MI ERROR BNE 40$ ;IF NE READY DEC R2 ;TIMEOUT? BGT 20$ ;IF GT NO 30$: MOV #IE.DNR&377,R0 ;SET DEVICE NOT READY STATUS BR 70$ ; 40$: INC U.CNT(R5) ;INCREMENT NUMBER OF SAMPLES TAKEN MOV 2(R4),-(SP) ;GET CONVERTED VALUE CALL $PTWRD ;PUT VALUE IN DATA BUFFER SUB #2,I.PRM+4(R3) ;ANY MORE SAMPLES TO TAKE? BGT 10$ ;IF GT YES MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS BR 70$ ; V.IFT 50$: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS BR 70$ ; .ENDC 60$: MOV #IE.BAD&377,R0 ;SET BAD PARAMETER STATUS 70$: MOV U.CNT(R5),R1 ;SET NUMBER OF CHANNELS SAMPLED CALL $IOFIN ;FINISH I/O OPERATION ; ; CANCEL I/O OPERATION, DEVICE TIMEOUT, AND POWERFAIL ARE NOP'ED. ; ADCAN: RETURN ; .END V4ðskQ ›c, .TITLE AFDRV .IDENT /06/ ; ; COPYRIGHT (C) 1974, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 06 ; ; D. N. CUTLER 30-NOV-73 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; AFC11 ANALOG TO DIGITAL CONVERTER CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; LOCAL DATA ; ; CONTROLLER IMPURE TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW A$$F11 ;ADDRESS OF UNIT CONTROL BLOCK .IF GT A$$F11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; HARDWARE GAIN CODE TABLE ; GAINTB: .BYTE 160 ;GAIN OF 1 .BYTE 140 ;GAIN OF 2 .BYTE 100 ;GAIN OF 10 .BYTE 120 ;GAIN OF 20 .BYTE 60 ;GAIN OF 50 .BYTE 40 ;GAIN OF 100 .BYTE 20 ;GAIN OF 200 .BYTE 0 ;GAIN OF 1000 ; ; DRIVER DISPATCH TABLE ; $AFTBL::.WORD AFCHK ;DEVICE INITIATOR ENTRY POINT .WORD AFCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD AFOUT ;DEVICE TIMEOUT ENTRY POINT .WORD AFPWF ;POWERFAIL ENTRY POINT ;+ ; **-AFCHK-AFC11 ANALOG TO DIGITAL CONVERTER CONTROLLER PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS RECEIVED FOR THE AFC11 ANALOG TO DIGITAL CONVERTOR. AFC11 I/O REQUESTS ; CONTAIN DEVICE DEPENDENT INFORMATION THAT MUST BE CHECKED IN THE CONTEXT ; OF THE ISSUING TASK. THEREFORE THE I/O REQUEST IS NOT QUEUED BEFORE CALLING ; THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLER TO BE INITIATED. ; ; OUTPUTS: ; ; THE CONTROL BUFFER IS ADDRESS CHECKED TO DETERMINE WHETHER IT LIES ; WITHIN THE ISSUING TASK'S ADDRESS SPACE. IF THE ADDRESS CHECK ; SUCCEEDS, THEN THE CONTROL BUFFER ADDRESS IS RELOCATED AND STORED ; IN THE I/O PACKET, THE I/O PACKET IS INSERTED IN THE CONTROLLER ; QUEUE, AND THE DEVICE INITIATOR IS ENTERED TO START THE CONTROLLER. ; ELSE AN ILLEGAL BUFFER STATUS IS RETURNED AS THE FINAL I/O STATUS ; OF THE REQUEST. ;- AFCHK: MOV R1,R3 ;COPY ADDRESS OF I/O PACKET MOV I.PRM+6(R3),R0 ;GET VIRTUAL ADDRESS OF CONTROL BUFFER .IF DF A$$CHK!M$$MGE MOV I.PRM+4(R3),R1 ;SET LENGTH OF BUFFER TO CHECK CALL $ACHCK ;ADDRESS CHECK CONTROL BUFFER BCC 10$ ;IF CC ADDRESS OKAY MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS CALLR $IOFIN ;FINISH I/O OPERATION .ENDC 10$: CALL $RELOC ;RELOCATE CONTROL BUFFER ADDRESS MOV R1,I.PRM+6(R3) ;SET RELOCATION BIAS OF CONTROL BUFFER MOV R2,I.PRM+10(R3) ;SET ADDRESS OF CONTROL BUFFER MOV R3,R1 ;SET ADDRESS OF I/O PACKET MOV R4,R0 ;SET ADDRESS OF I/O QUEUE LISTHEAD CALL $QINSP ;INSERT I/O PACKET IN REQUEST QUEUE ;+ ; **-AFINI-AFC11 ANALOG TO DIGITAL CONVERTOR CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB AFINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS AFCAN ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; AFC11 I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RBC). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER. ; WD. 15 -- RELOCATION BIAS OF CONTROL BUFFER. ; WD. 16 -- CONTROL BUFFER ADDRESS. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; ; THE DATA BUFFER RECEIVES CONVERTED VALUES AND THE CONTROL BUFFER CONTAINS ; CONTROL WORDS THAT CONTROL THE CONVERSION PROCESS. EACH WORD IN THE CONTROL ; BUFFER HAS THE FORMAT: ; ; BITS 15-12 -- GAIN CODE. ; ; LEGAL GAIN CODES ARE: ; ; 0000=GAIN OF 1. ; 0001=GAIN OF 2. ; 0100=GAIN OF 10. ; 0101=GAIN OF 20. ; 1000=GAIN OF 50. ; 1001=GAIN OF 100. ; 1100=GAIN OF 200. ; 1101=GAIN OF 1000. ; ; BITS 11-0 -- CHANNEL NUMBER. ; ; EACH AFC11 MAY HAVE 2048. CHANNELS. THE LEGALITY OF ; A PARTICULAR CHANNEL NUMBER IS DETERMINED BY THE ; SECOND DEVICE CHARACTERISTICS WORD. ; ; EACH CHANNEL IS CONVERTED ACCORDING TO THE CORRESPONDING WORD IN THE CONTROL ; BUFFER AND THE RESULTANT VALUE IS PLACED IN THE DATA BUFFER. IF AN ILLEGAL ; CONTROL WORD IS DETECTED THEN THE CONVERSION PROCESS IS TERMINATED. THE SECOND ; I/O STATUS WORD SPECIFIES THE NUMBER OF CHANNELS THAT WERE CONVERTED. ;- MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS MOV I.PRM+6(R1),U.CBF(R5) ;SET RELOCATION BIAS OF CONTROL BUFFER MOV I.PRM+10(R1),U.CBF+2(R5) ;SET ADDRESS OF CONTROL BUFFER ; ; INITIATE I/O OPERATION ; 10$: CALL $GTCWD ;GET NEXT WORD FROM CONTROL BUFFER MOV #IE.BAD&377,R0 ;ASSUME ILLEGAL GAIN OR CHANNEL MOV (SP)+,R1 ;RETRIEVE CONTROL WORD MOV R1,R2 ;COPY CONTROL WORD BIC #170000,R1 ;CLEAR GAIN CODE BITS CMP R1,U.CW2(R5) ;LEGAL CHANNEL THIS CONTROLLER? BHIS AFOUT ;IF HIS NO BIC #7777,R2 ;CLEAR CHANNEL NUMBER ASL R2 ;ISOLATE HARDWARE GAIN ROL R2 ; ROL R2 ; BCS AFOUT ;IF CS ILLEGAL GAIN CODE ASRB R2 ;DROP BIT 13 OF SOFTWARE GAIN ROL R2 ;RETRIEVE REMAINING GAIN BITS ROL R2 ; FOR GAIN TABLE OFFSET SWAB R1 ;GET HIGH BYTE OF GAIN COMMAND BISB GAINTB(R2),R1 ;SET GAIN CODE SWAB R1 ;RESTORE COMMAND MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT MOV S.CSR(R4),R4 ;GET ADDRESS OF CONTROL STATUS REGISTER MOV R1,4(R4) ;LOAD CHANNEL AND GAIN REGISTER MOV #100,(R4) ;ENABLE INTERRUPT ; ; CANCEL I/O OPERATION IS A NOP FOR THE AFC11. ; AFCAN: ;REF LABEL ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. ; AFPWF: RETURN ; ;+ ; **$AFINT-AFC11 ANALOG TO DIGITAL CONVERTOR CONTROLLER INTERRUPTS ;- $AFINT:: ;REF LABEL INTSV$ AF,PR5,A$$F11 ;;;GENERATE INTERRUPT SAVE CODE CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV S.CSR(R4),R3 ;GET ADDRESS OF CONTROL STATUS REGISTER MOV 2(R3),-(SP) ;GET CONVERTED DIGITAL VALUE CALL $PTWRD ;PUT CONVERTED VALUE IN DATA BUFFER SUB #2,U.CNT(R5) ;ANY MORE TO CONVERT? BGT 10$ ;IF GT YES MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED WITH A FINAL ; I/O STATUS OF DEVICE NOT READY. THE SECOND I/O STATUS WORD CONTAINS THE ; NUMBER OF CHANNELS THAT WERE SAMPLED BEFORE THE TIMEOUT OCCURRED. TIMEOUTS ; ARE USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A ; HARDWARE FAILURE. ; AFOUT: CLR @S.CSR(R4) ;;;CLEAR INTERRUPT ENABLE CLRB PS ;;;ALLOW INTERRUPTS MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV I.PRM+4(R3),R1 ;ÚGET SIZE OF ORIGINAL BUFFER SUB U.CNT(R5),R1 ;CALCULATE NUMBER OF BYTES PROCESSED ROR R1 ;CONVERT TO NUMBER OF SAMPLES PROCESSED CALL $IODON ;FINISH I/O OPERATION BR AFINI ;GO AGAIN .DSABL LSB .END Ú ðskQ ›c, .TITLE ARDRV .IDENT /04.1/ ; ; COPYRIGHT (C) 1974, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 04 ; ; D.N. CUTLER / C.A. D'ELIA 1-JAN-75 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; C. A. D'ELIA 24-MAR-77 ; ; CD037 -- REPLACE MISTYPED CONDITIONAL THAT CAUSES CRASH. ; ; B. SCHREIBER 2-NOV-77 ; ;  BS033 -- CLEAR I.PRM+16 BEFORE CALLING $IOFIN ; ; B. SCHREIBER 19-MAY-78 ; ; BS049 -- FIX HANDLING OF DIGITAL INPUT WD. AT INTERRUPT ; ; AR11 LABORATORY PERIPHERAL SYSTEM CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,TCBDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; EQUATED SYMBOLS ; ; SAMPLE CONTROL BLOCK OFFSET DEFINITIONS ; .PSECT ARCTLQ,D,ABS SLINK: .BLKW 1 ;SAMPLE QUEUE THREAD WORD RQPKT: .BLKW 1 ;ADDRESS OF I/O REQUEST PACKET STATE: .BLKW 1 ;CURRENT SAMPLE STATE RSTAT: .BLKB 1 ;SAMPLE STATUS BYTE FINST: .BLKB 1 ;FINAL I/O STATUS IOSB2: .BLKW 2 ;SECOND I/O STATUS WORD ADDRESS AND REL BIAS STRBF: .BLKW 1 ;STARTING BUFFER ADDRESS AND RELOCATION BIAS CURBF: .BLKW 3 ;CURRENT BUFFER ADDRESS AND RELOCATION BIAS FULBF: .BLKW 1 ;SIZE OF FULL BUFFER IN WORDS SMCNT: .BLKW 1 ;SPACE REMAINING TO END OF BUFFER HAFBF: .BLKW 1 ;SIZE OF HALF BUFFER IN WORDS .IF DF D$$R11 DBMSK: .BLKW 1 ;DIGITAL INPUT/OUTPUT START MASK DSMSK: .BLKW 1 ;DIGITAL INPUT STOP MASK .ENDC CYCNT: .BLKW 1 ;NUMBER OF CLOCK TICKS TO NEXT SAMPLE CRSET: .BLKW 1 ;RESET VALUE FOR CLOCK TICKS TO NEXT SAMPLE SAMCT: .BLKW 1 ;NUMBER OF SAMPLE BUFFERS BEFORE BUFFER RUNOUT DATAW: .BLKW 1 ;FUNCTION DEPENDENT DATA WORD STRST: .BLKW 1 ;STARTING SAMPLE STATE SLGTH: ;LENGTH OF SAMPLE CONTROL BLOCK .PSECT ; ; SAMPLE CONTROL BLOCK STATUS BYTE BIT DEFINITIONS ;  SPARE=200 ;SPARE BIT STROT=100 ;SET DIGITAL OUTPUT BIT AT START (1=YES) STPIN=40 ;STOP ON DIGITAL INPUT BIT CLEAR (1=YES) STPBR=20 ;STOP ON BUFFER RUNOUT (1=YES) GAINR=10 ;(LPS11 ONLY) ;AUTOGAIN RANGING REQUESTED (1=YES) SPARE=4 ;SPARE BIT RQEFN=2 ;REQUEST EFN SETTING (1=YES) STPRQ=1 ;STOP SAMPLE REQUEST (1=YES) ; ; A/D TIMEOUT LOOP COUNT ; TMOCNT=20. ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW A$$R11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK .IF DF D$$R11 DGIWD: .BLKW A$$R11 ;DIGITAL INPUT WORD LAST SYNCHRONOUS SAMPLE .ENDC TEMP: .BLKW 1 ;TEMPORARY STORAGE ; ; FORK REQUEST FLAG ; FKFLG: .WORD 0 ; ; LEGAL FUNCTION VECTOR ; LGFCN: .BYTE IO.SDO/256. ;WRITE DIGITAL OUTPUT REGISTER .BYTE IO.SDI/256. ;READ DIGITAL INPUT REGISTER .BYTE IO.STP/256. ;STOP IN-PROGRESS REQUEST .BYTE IO.ADS/256. ;SYNCHRONOUS A/D SAMPLING .BYTE IO.MDA/256. ;SYNCHRONOUS D/A OUTPUT .BYTE IO.MDO/256. ;SYNCHRONOUS DIGITAL OUTPUT .EVEN ; ; DRIVER DISPATCH TABLE ; $ARTBL::.WORD ARINI ;DEVICE INITIATOR ENTRY POINT .WORD ARCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD AROUT ;DEVICE TIMEOUT ENTRY POINT .WORD ARPWF ;POWERFAIL ENTRY POINT ;+ ; **-ARINI-AR11 LABORATORY PERIPHERAL SYSTEM CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS RECEIVED FOR THE AR11 LABORATORY PERIPHERAL SYSTEM. SEVEN FUNCTIONS ARE ; RECOGNIZED BY THE AR11 DRIVER. FUNCTIONS ARE EITHER EXECUTED IMMEDITATELY ; OR PLACED IN A SAMPLE REQUEST QUEUE THAT IS MAINTAINED BY THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; FUNCTION INDEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE. ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; ; OUTPUTS: ; ; IF THE FUNCTION IS STOP IN-PROGRESS REQUEST, WRITE DIGITAL OUTPUT ; REGISTER, OR READ DIGITAL INPUT REGISTER, THEN THE FUNCTION IS ; EXECUTED IMMEDIATELY. ELSE A SECONDARY CONTROL BLOCK IS ; CONSTRUCTED AND LINKED INTO THE SAMPLE REQUEST QUEUE. ;- ARINI: MOV R4,R2 ;GET ADDRESS OF SCB MOV R1,R3 ;SAVE I/O PACKET ADDRESS ADD #I.PRM,R1 ;POINT TO FIRST PARAMETER MOV S.CSR(R2),R4 ;GET ADDRESS OF CONTROL STATUS REGISTER MOV #LGFCN,R0 ;POINT TO LEGAL FUNCTION VECTOR MOVB I.FCN+1(R3),-(SP) ;GET I/O FUNCTION CODE CMPB (SP),(R0)+ ;WRITE DIGITAL OUTPUT REGISTER? .IF DF D$$R11 BEQ DIGIO ;IF EQ YES CMPB (SP),(R0)+ ;READ DIGITAL INPUT REGISTER? BEQ RDDIN ;IF EQ YES .IFF BEQ ARONP ;IF EQ YES CMPB (SP),(R0)+ ;READ DIGITAL INPUT REGISTER? BEQ ARONP ;IF EQ YES .ENDC CMPB (SP),(R0)+ ;STOP IN-PROGRESS REQUEST? BNE ARFCN ;IF NE NO ; ; **-STOPR-STOP IN-PROGRESS REQUEST ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- BUFFER ADDRESS OF PREVIOUS REQUEST. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WD. 21 -- NOT USED. ; STOPR: MOV (R1),R0 ;GET ADDRESS OF BUFFER MOV R2,R4 ;SAVE ADDRESS OF SCB CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R3,-(SP) ;SAVE I/O PACKET ADDRESS MOV R5,R3 ;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R3 ; MOVB S.PRI(R4),PS ;;;LOCK OUT DEVICE INTERRUPTS 10$: MOV (R3),R3 ;;;GET ADDRESS OF NEXT ENTRY BEQ 20$ ;;;IF EQ DONE MOV RQPKT(R3),R0 ;;;GET ADDRESS OF I/O PACKET CMP $TKTCB,I.TCB(R0) ;;;REQUEST FOR CURRENT TASK? BNE 10$ ;;;IF NE NO CMP R1,STRBF(R3) ;;;RELOCATION BIAS MATCH? BNE 10$ ;;;IF NE NO CMP R2,STRBF+4(R3) ;;;BUFFER ADDRESS MATCH? BNE 10$ ;;;IF NE NO MOVB #IE.ABO,FINST(R3) ;;;SET FINAL STATUS ABORT CALL TERMS ;;;TERMINATE SAMPLE REQUEST 20$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS MOV (SP)+,R3 ;RESTORE I/O PACKET ADDRESS BR ARSUC ;TAKE COMMON EXIT .IF DF D$$R11 ; ; **-RDDIN-READ DIGITAL INPUT REGISTER ; ; INPUTS: ; ; R1=POINTS TO WD. 12 OF I/O PACKET ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- DIGITAL INPUT MASK WORD. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WD. 21 -- NOT USED. ; RDDIN: SEC ;INDICATE DIGITAL INPUT REQUEST DIGIO: BITB #20,U.CW2+1(R5) ;DR11-K PRESENT? BEQ ARONP ;IF EQ NO MOV U.CNT+4(R5),R4 ;GET ITS CSR ADDRESS BCC WRDOT ;BRANCH IF DIGITAL OUTPUT REQUESTED .IF GT A$$R11-1 MOVB S.CON(R2),R2 ;GET CONTROLLER INDEX MOV DGIWD(R2),R2 ;GET DIGITAL INPUT WORD LAST SYNCHRONOUS SAMPLE .IFF MOV DGIWD,R2 ;GET DIGITAL INPUT WORD LAST SYNCHRONOUS SAMPLE .ENDC TSTB U.STS(R5) ;UNIT BUSY? BMI 10$ ;IF MI YES MOV 2(R4),R2 ;READ DIGITAL INPUT REGISTER MOV R2,2(R4) ;CLEAR BITS IN DIGITAL INPUT REGISTER 10$: COM (R1) ;COMPLEMENT MASK WORD BIC (R1),R2 ;CLEAR UNWANTED BITS IN DATA WORD MOV R2,R1 ;SET SECOND I/O STATUS WORD BR ARSUC1 ;TAKE COMMON EXIT ; ; **-WRDOT-WRITE DIGITAL OUTPUT REGISTER ; ; INPUTS: ; ; R1=POINTS TO WD. 12 OF I/O PACKET ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- DIGITAL OUTPUT MASK WORD. ; WD. 13 -- DIGITAL OUTPUT VALUE. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WD. 21 -- NOT USED. ; WRDOT: BIT (R1),U.CNT+2(R5) ;DIGITAL OUTPUT BITS IN USE? BNE ARRSU ;IF NE YES ADD #4,R4 ;POINT TO DIGITAL OUTPUT REGISTER COM (R1) ;COMPLEMENT MASK WORD  BIC (R1)+,(R1) ;CLEAR EXCESS BITS IN DATA WORD BIS (R1),(R4) ;SET BITS IN DIGITAL OUTPUT REGISTER COM (R1) ;COMPLEMENT DATA WORD BIC -2(R1),(R1) ;CLEAR EXCESS BITS IN DATA WORD BIC (R1),(R4) ;CLEAR BITS IN DIGITAL OUTPUT REGISTER MOV (R4),R1 ;SET SECOND I/O STATUS WORD BR ARSUC1 ;TAKE COMMON EXIT .ENDC ; ; SUCCESS COMPLETION OF FUNCTION ; ARSUC: CLR R1 ;CLEAR SECOND I/O STATUS WORD ARSUC1: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS CODE BR ARCMN1 ; ;  ; BAD PARAMETER ; ARBAD: MOV #IE.BAD&377,R0 ;SET BAD PARAMETER STATUS CODE BR ARCMN ; .IF DF D$$R11 ; ; RESOURCE IN USE ; ARRSU: MOV #IE.RSU&377,R0 ;SET RESOURCE IN USE STATUS CODE BR ARCMN ; .ENDC ; ; PRIVILEGE VIOLATION ; ARPRI: MOV #IE.PRI&377,R0 ;SET PRIVILEGE VIOLATION STATUS BR ARCMN ; ; ; OPTION NOT PRESENT ; ARONP: MOV #IE.ONP&377,R0 ;SET OPTION NOT PRESENT STATUS BR ARCMN ; ; ; DYNAMIC MEMORY NOT AVAILABLE ; ARNOD: MOV #IE.NOD&377,R0 ;SET MEMORY NOT AVAILABLE STATUS ; ; COMMON STATUS EXIT ; ARCMN: CLR R1 ;CLEAR SECOND I/O STATUS WORD ARCMN1: TST (SP)+ ;REMOVE FUNCTION CODE FROM STACK CLR I.PRM+16(R3) ;CLEAR BLOCK LOCKING WORD FOR $IOFIN CALLR $IOFIN ;FINISH I/O OPERATION ; ; ALL REMAINING FUNCTIONS REQUIRE THE REQUESTING TASK TO BE EITHER FIXED ; IN MEMORY OR NOT CHECKPOINTABLE AND AN I/O STATUS DOUBLEWORD TO BE ; SPECIFIED. ; ; INPUTS: ; ; R1=POINTS TO WD. 12 OF I/O PACKET ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF BUFFER. ; WD. 13 -- BUFFER ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 14 -- BUFFER SIZE IN BYTES. ; WD. 15 -- DIGITAL INPUT/OUTPUT POINT NUMBERS. ; WD. 16 -- AR11 CLOCK TICKS BETWEEN SAMPLES. ; WD. 17 -- NUMBER OF BUFFERS. ; WD. 20 -- FUNCTION DEPENDENT DATA WORD. ; WD. 21 -- SCRATCH. ; ARFCN: MOV I.TCB(R3),R2 ;GET REQUESTING TASK TCB ADDRESS BIT #T2.CHK!T2.FXD,T.ST2(R2) ;TASK FXED OR NOT CHKPOINTABLE? BEQ ARPRI ;IF EQ NO TST I.IOSB+4(R3) ;I/O STATUS DOUBLEWORD SPECIFIED? BEQ ARBAD ;IF EQ NO ADD #6,R1 ;POINT TO DIGITAL I/O BIT NUMBERS BITB #340,I.FCN(R3) ;DIGITAL I/O SUB-FUNCTION REQUESTED? .IF DF D$$R11 BEQ 35$ ;IF EQ NO BITB #20,U.CW2+1(R5) ;DR11-K PRESENT? BEQ ARONP ;IF EQ NO MOVB I.FCN(R3),R2 ;GET SUBFUNCTION MODIFIER BITS BPL 10$ ;IF PL START IMMEDIATELY CMPB (R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS ARBAD ;IF HIS NO 10$: ASLB R2 ;SET DIGITAL OUTPUT ON START? BPL 20$ ;IF PL NO  CMPB (R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS ARBAD ;IF HIS NO MOVB (R1),R4 ;GET DIGITAL OUTPUT POINT NUMBER ASL R4 ;CONVERT TO WORD INDEX BIT $BTMSK(R4),U.CNT+2(R5) ;DIGITAL OUTPUT BIT IN USE? BNE ARRSU ;IF NE YES 20$: ASLB R2 ;STOP ON DIGITAL INPUT? BPL 30$ ;IF PL NO CMPB 1(R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS ARBAD ;IF HIS NO 30$: ASL (R1) ;CONVERT BOTH POINT NUMBERS TO WORD INDICES .IFF BNE ARONP ;IF NE YES .ENDC 35$: ADD #8.,R1 ;POINT TO LAST (SCRATCH) WORD IN I/O PACKET CMPB (SP),(R0)+ ;SYNCHRONOUS A/D SAMPLING? BEQ 60$ ;IF EQ YES CMPB (SP),(R0)+ ;SYNCHRONOUS D/A OUTPUT? .IF DF A$$RDA BEQ 50$ ;IF EQ YES .IFF BEQ ARONP ;D/A NOT PRESENT .ENDC .IF DF D$$R11 BITB #20,U.CW2+1(R5) ;DR11-K SUPPORT? BEQ ARONP ;IF EQ NO CMPB (SP),(R0)+ ;SYNCHRONOUS DIGITAL OUTPUT? BNE 40$ ;IF NE NO (SYNCHRONOUS DIGITAL INPUT) ; ; SYNCHRONOUS DIGITAL OUTPUT ; ; CONTENTS OF FUNCTION DEPENDENT WORD IN I/O PACKET ; WD. 20 -- DIGITAL OUTPUT BIT MASK. ; MOV #SYNDO,(R1) ;SET SYNCHRONOUS DIGITAL OUTPUT STATE BIT -(R1),U.CNT+2(R5) ;ANY DIGITAL OUTPUT BITS IN USE? BR 45$ ;CONTINUE IN COMMON CODE ; ; SYNCHRONOUS DIGITAL INPUT ; ; CONTENTS OF FUNCTION DEPENDENT WORD IN I/O PACKET ; WD. 20 -- DIGITAL INPUT BIT MASK. ; 40$: MOV #SYNDI,(R1) ;SET SYNCHRONOUS DIGITAL INPUT STATE BIT -(R1),U.CNT(R5) ;ANY DIGITAL INPUT BITS IN USE? 45$: BNE ARRSU ;IF NE YES BR 120$ ;CONTINUE IN COMMON CODE  .IFF BR ARONP ;DIGITAL I/O NOT PRESENT .ENDC ; ; SYNCHRONOUS D/A OUTPUT ; ; CONTENTS OF FUNCTION DEPENDENT WORD IN I/O PACKET ; WD. 20 -- D/A CHANNELS. ; .IF DF A$$RDA 50$: MOV #SYNDA,(R1) ;SET SYNCHRONOUS D/A OUTPUT STATE MOVB U.CW2+1(R5),R0 ;GET OPTION FLAGS AND NUMBER OF D/A'S BIT #100,R0 ;D/A OPTION PRESENT? BEQ ARONP ;IF EQ NO BIC #^C<17>,R0 ;CLEAR ALL BUT NUMBER OF D/A'S MOVB -(R1),R2 ;GET NUMBER OF OUTPUT D/A'S MOVB -(R1),R4 ;GET STARTING D/A NUMBER BR 90$ ;FINISH IN COMMON CODE .ENDC ; ; SYNCHRONOUS A/D SAMPLING ; ; CONTENTS OF FUNCTION DEPENDENT WORD IN I/O PACKET ; WD. 20 -- A/D CHANNELS. ; 60$: MOV #SYNAD,(R1) ;SET SYNCHRONOUS A/D SAMPLING STATE MOVB -(R1),R2 ;GET NUMBER OF CHANNELS MOVB -(R1),R4 ;GET STARTING CHANNEL MOVB U.CW2(R5),R0 ;GET NUMBER OF A/D CHANNELS 90$: DEC R2 ;REDUCE NUMBER OF CHANNELS ADD R2,R4 ;CALCULATE HIGHEST CHANNEL BCS ARBAD ;IF CS BAD RANGE CMP R4,R0 ;LEGAL CHANNEL? BHIS ARBAD ;IF HIS NO 120$: MOV R3,R4 ;SAVE I/O PACKET ADDRESS MOV #SLGTH,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $ALOCB ;ALLOCATE SECONDARY CONTROL BLOCK MOV R4,R3 ;RESTORE I/O PACKET ADDRESS BCS ARNOD ;IF CS NO MEMORY AVAILABLE MOV R0,R1 ;COPY SECONDARY CONTROL BLOCK ADDRESS CLR (R1)+ ;CLEAR LINK WORD MOV R3,(R1)+ ;INSERT I/O PACKET ADDRESS ADD #I.FCN,R3 ;POINT TO SUBFUNCTION MODIFIER BITS .IF DF D$$R11 MOV #SDOUT,(R1)+ ;ASSUME INITIAL STATE IS DIGITAL OUTPUT .IFF  MOV I.PRM+14.(R4),(R1)+ ;SET INITIAL STATE TO CONVERT REQUEST .ENDC MOV (R3),(R1) ;INSERT SUBFUNCTION MODIFIER BITS BIC #^C,(R1)+ ;CLEAR EXTRANEOUS BITS ADD #I.IOSB+2,R4 ;POINT TO I/O STATUS DOUBLEWORD ADDRESS MOV (R4)+,(R1)+ ;INSERT RELOCATION BIAS MOV (R4)+,(R1) ;INSERT DISPLACEMENT ADDRESS ADD #2,(R1)+ ;CALCULATE ADDRESS OF SECOND I/O STATUS TST (R4)+ ;BYPASS AST ADDRESS AND CLEAR CARRY MOV (R4),(R1)+ ;INSERT BUFFER RELOCATION BIAS MOV (R4)+,(R1)+ ; MOV (R4),(R1)+ ;INSERT BUFFER DISPLACEMENT ADDRESS MOV (R4)+,(R1)+ ; MOV (R4)+,(R1) ;INSERT SIZE OF BUFFER IN BYTES ROR (R1) ;CONVERT TO SIZE IN WORDS MOV (R1)+,(R1) ;INSERT SIZE OF BUFFER IN WORDS MOV (R1)+,(R1) ;INSERT SIZE OF BUFFER IN WORDS ASR (R1)+ ;CONVERT TO SIZE IN DOUBLEWORDS .IF DF D$$R11 MOVB (R4)+,R2 ;GET DIGITAL INPUT/OUTPUT POINT INDEX CLR (R1) ;ASSUME NO DIGITAL INPUT/OUTPUT POINT ASLB (R3) ;START ON DIGITAL INPUT POINT? BCC 130$ ;IF CC NO MOV #SWAIT,STATE(R0) ;ALTER STATE TO WAIT ON DIGITAL INPUT BR 140$ ; 130$: BPL 150$ ;IF PL NO DIGITAL OUTPUT ON START 140$: MOV $BTMSK(R2),(R1) ;INSERT DIGITAL INPUT/OUTPUT POINT MASK TSTB (R3) ;SET DIGITAL OUTPUT POINT AT START? BPL 150$ ;IF PL NO BIS (R1),U.CNT+2(R5) ;SET DIGITAL OUTPUT POINT IN USE 150$: TST (R1)+ ;ADVANCE TO NEXT WORD CLR (R1) ;ASSUME NO DIGITAL INPUT POINT MOVB (R4)+,R2 ;GET DIGITAL INPUT POINT INDEX ASLB (R3) ;STOP ON DIGITAL INPUT POINT? BPL 160$ ;IF PL NO MOV $BTMSK(R2),(R1) ;INSERT DIGITAL INPUT POINT MASK 160$: CMP (R1)+,(SP)+ ;ADVANCE TO NEXT WORD AND CLEAN STACK .IFF CMP (R4)+,(SP)+ ;SKIP DIGITAL I/O WORD AND CLEAN STACK .IFTF MOV #1,(R1)+ ;INSERT INITIAL CLOCK TICKS TO NEXT SAMPLE MOV (R4)+,(R1)+ ;INSERT CLOCK TICKS RESET VALUE MOV (R4)+,(R1)+ ;INSERT NUMBER OF BUFFERS TO COLLECT MOV (R4)+,(R1)+ ;INSERT FUNCTION DEPENDENT (CHANNELS) DATA WORD MOV (R4),(R1) ;INSERT STARTING SAMPLE STATE .IFT CMP #SYNDO,(R1) ;SYNCHRONOUS DIGITAL OUTPUT? BEQ 170$ ;IF EQ YES CMP #SYNDI,(R1) ;SYNCHRONOUS DIGITAL INPUT? BNE 190$ ;IF NE NO BIS -(R1),U.CNT(R5) ;SET DIGITAL INPUT BITS IN USE BR 180$ ; 170$: BIS -(R1),U.CNT+2(R5) ;SET DIGITAL OUTPUT BITS IN USE 180$: COM (R1) ;COMPLEMENT MASK WORD .ENDC 190$: MOV U.BUF(R5),(R0) ;INSERT REQUEST IN SAMPLE QUEUE MOV R0,U.BUF(R5) ; MOVB I.EFN-(R4),R0 ;GET SPECIFIED EVENT FLAG NUMBER MOV R5,-(SP) ;SAVE UCB ADDRESS MOV I.TCB-(R4),R5 ;GET TCB ADDRESS OF REQUESTER TASK CALL $CEFI ;CONVERT EFN TO MASK AND ADDRESS MOV R1,(R4) ;INSERT EFN MASK ADDRESS MOV R0,-(R4) ;INSERT EFN MASK WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS MOV U.SCB(R5),R3 ;GET ADDRESS OF SCB TSTB U.STS(R5) ;UNIT BUSY? BMI 200$ ;IF MI YES MOV S.CSR(R3),R2 ;GET ADDRESS OF CONTROL STATUS REGISTER CMP (R2)+,(R2)+ ;POINT TO CLOCK STATUS REGISTER MOV #506,(R2)+ ;SET REPEAT MODE, 10KHZ, AND ENABLE INT MOV U.CW4(R5),(R2) ;LOAD COUNTER PRESET REGISTER NEG (R2) ;NEGATE PRESET VALUE INC -(R2) ;START CLOCK RUNNING 200$: BISB #US.BSY,U.STS(R5) ;SET UNIT BUSY MOVB #1,S.STS(R3) ;SET CONTROLLER BUSY MOVB S.ITM(R3),S.CTM(R3) ;SET CURRENT TIMEOUT COUNT RETURN ; ;+ ; ; **-$ARCLK-AR11 LABORATORY PERIPHERAL SYSTEM CLOCK INTERRUPT ; ;- $ARCLK:: ;;;REF LABEL $ARINT:: ;;;REF LABEL INTSV$ AR,PR6,A$$R11 ;;;GENERATE INTERRUPT SAVE CODE MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IF GT A$$R11-1 MOV R1,-(SP) ;;;SAVE R1 MOV R4,R1 ;;;PUT CONTROLLER INDEX IN R1 .ENDC MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT MOV S.CSR(R4),R4 ;;;GET ADDRESS OF CONTROL STATUS REGISTER .IF DF D$$R11 MOV R0,-(SP) ;;;SAVE R0 MOV U.CNT+4(R5),R0 ;;;GET CSR ADDRESS OF DR11-K .IF GT A$$R11-1 BEQ 10$ ;;;SKIP IF NO DR11-K FOR THIS CONTROLLER .IFTF MOV 2(R0),R3 ;;;READ DIGITAL INPUT REGISTER .IFT MOV R3,DGIWD(R1) ;;;SAVE DIGITAL INPUT WORD .IFF MOV R3,DGIWD ;;;SAVE DIGITAL INPUT WORD .ENDC MOV R3,TEMP ;;;SAVE COMPLEMENT OF DIGITAL INPUT WORD COM TEMP ;;; MOV R3,2(R0) ;;;CLEAR BITS IN DIGITAL INPUT REGISTER 10$: ;;;REF LABEL .ENDC MOV R5,R3 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R3 ;;; .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE CURRENT APR6 MAPPING .ENDC ; ; GET NEXT REQUEST FROM SAMPLE QUEUE AND PROCESS ; .ENABL LSB NXTRQ: MOV (R3),R3 ;;;GET ADDRESS OF NEXT SAMPLE REQUEST BEQ 20$ ;;;IF EQ END OF REQUEST QUEUE DEC CYCNT(R3) ;;;TIME TO SAMPLE? BNE NXTRQ ;;;IF NE NO 10$: MOV CRSET(R3),CYCNT(R3) ;;;RESET SAMPLE CYCLE COUNT JMP @STATE(R3) ;;;PROCESS SAMPLE REQUEST 20$: JMP ENDRQ ;;; .IF DF D$$R11 ; ; START SAMPLING IF DIGITAL INPUT BIT SET ; SWAIT: MOV #1,CYCNT(R3) ;;;SET TO REPEAT TEST AT NEXT INTERVAL BIT DBMSK(R3),TEMP ;;;START SAMPLING? BNE NXTRQ ;;;IF NE NO BITB #STROT,RSTAT(R3) ;;;SET DIGITAL OUTPUT BIT AT START? BEQ 30$ ;;;IF EQ NO ; ; SET DIGITAL OUTPUT BIT ; SDOUT: BIS DBMSK(R3),4(R0) ;;;SET DIGITAL OUTPUT BIT 30$: MOV STRST(R3),STATE(R3) ;;;CHANGE STATE TO STARTING VALUE BR 10$ ;;;DISPATCH ON NEW STATE ; ; SYNCHRONOUS DIGITAL OUTPUT ; SYNDO: ;;;REF LABEL CALL RDWRD ;;;READ WORD FROM USER BUFFER BCS NXTRQ ;;;IF CS BUFFER OVERRUN MOV 4(R0),-(SP) ;;;READ DIGITAL OUTPUT REGISTER MOV DATAW(R3),-(SP) ;;;GET OUTPUT MASK WORD BIC (SP),R2 ;;;CLEAR EXCESS BITS IN DATA WORD COM (SP) ;;;COMPLEMENT MASK WORD BIC (SP)+,(SP) ;;;CLEAR FIELD BITS IN OUTPUT WORD BIS (SP)+,R2 ;;;MERGE DATA AND OUTPUT WORD MOV R2,4(R0) ;;;WRITE VALUE INTO DIGITAL OUTPUT REGISTER BR NXTRQ ;;;CONTINUE SCAN .ENDC .DSABL LSB ; ; SYNCHRONOUS A/D SAMPLING ; SYNAD: MOV DATAW(R3),-(SP) ;;;SET COUNT AND STARTING CHANNEL .IF DF U$$NIP 10$: MOVB (SP),R2 ;;;GET CHANNEL NUMBER ASL R2 ;;;CONVERT NUMBER TO OFFSET BIT $BTMSK(R2),U.CW3(R5) ;;;EXAMINE CHANNEL POLARITY BEQ 15$ ;;;IF EQ BIPOLAR  BIS #100,R2 ;;;SET UNIPOLAR 15$: ASR R2 ;;;CONVERT BACK TO CHANNEL NUMBER MOVB R2,1(R4) ;;;SET CHANNEL NUMBER AND POLARITY .IFF 10$: MOVB (SP),1(R4) ;;;SET CHANNEL NUMBER (BIPOLAR SAMPLE) .ENDC MOVB #1,(R4) ;;;START CONVERSION MOV #TMOCNT,R2 ;;;SET TIMEOUT LOOP COUNT 20$: TSTB (R4) ;;;DONE? BMI 90$ ;;;IF MI DONE DEC R2 ;;;TIMEOUT? BGT 20$ ;;;IF GT NO 70$: MOV #177777,R2 ;;;SET TIMEOUT ERROR VALUE BR 100$ ;;; 90$: MOV 2(R4),R2 ;;;READ CONVERTED VALUE 100$: CALL WRWRD ;;;WRITE WORD INTO USER BUFFER BCS 110$ ;;;IF CS BUFFER OVERRUN INCB (SP) ;;;INCREMENT CHANNEL NUMBER DECB 1(SP) ;;;ANY MORE CHANNELS TO SAMPLE? BGT 10$ ;;;IF GT YES 110$: TST (SP)+ ;;;CLEAN STACK JMP NXTRQ ;;;CONTINUE SCAN .IF DF A$$RDA ; ; SYNCHRONOUS D/A OUTPUT ; SYNDA: MOV DATAW(R3),-(SP) ;;;SET COUNT AND STARTING D/A NUMBER 10$: CALL RDWRD ;;;READ WORD FROM USER BUFFER BCS 60$ ;;;IF CS BUFFER OVERRUN BIC #176000,R2 ;;;CLEAR D/A NUMBER FIELD MOVB (SP),-(SP) ;;;COPY D/A NUMBER DECB (SP) ;;;D/A 0 OR 1 ONLY BEQ 30$ ;;;IF EQ D/A 1 (Y-REG) MOV R2,12(R4) ;;;OUTPUT TO X-REG D/A BR 40$ ;;; 30$: MOV R2,14(R4) ;;;OUTPUT TO Y-REG D/A 40$: TST (SP)+ ;;;CLEAN STACK 50$: INC (SP) ;;;INCREMENT D/A NUMBER DECB 1(SP) ;;;ANY MORE TO GO? BGT 10$ ;;;IF GT YES 60$: TST (SP)+ ;;;CLEAN STACK JMP NXTRQ ;;;CONTINUE SCAN .ENDC .IF DF D$$R11 ; ; SYNCHRONOUS DIGITAL INPUT SAMPLING ; SYNDI: ;;;REF LABEL .IF GT A$$R11-1  MOV DGIWD(R1),R2 ;;;GET SAVED DIGITAL INPUT WORD .IFF MOV DGIWD,R2 ;;;GET SAVED DIGITAL INPUT WORD .ENDC MOV DATAW(R3),-(SP) ;;;GET INPUT MASK WORD BIC (SP)+,R2 ;;;CLEAR EXCESS BITS IN DATA WORD CALL WRWRD ;;;WRITE WORD INTO USER BUFFER JMP NXTRQ ;;;CONTINUE SCAN .ENDC ; ; END OF REQUEST QUEUE--CHECK IF FORK REQUIRED ; ENDRQ: ;;;REF LABEL .IF DF M$$MGE MOV (SP)+,KISAR6 ;;;RESTORE APR6 MAPPING .ENDC .IF DF D$$R11 MOV (SP)+,R0 ;;;RESTORE R0 .ENDC .IF GT A$$R11-1 MOV (SP)+,R1 ;;;RESTORE R1 .ENDC MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; TST FKFLG ;;;FORK REQUESTED? BEQ 10$ ;;;IF EQ NO CLR FKFLG ;;;CLEAR FORK REQUESTED FLAG BITB #US.FRK,U.STS(R5) ;;;FORK ALREADY IN PROGRESS? BEQ ENDRQ1 ;;;IF EQ NO 10$: JMP $INTXT ;;;EXIT INTERRUPT ;+ ; **-ARCAN-CANCEL I/O REQUESTS ; ; THIS ROUTINE IS ENTERED TO CANCEL ALL I/O REQUESTS THAT ARE IN PROGRESS FOR ; THE CURRENT TASK. THE SAMPLE QUEUE IS SCANNED AND ALL REQUESTS FOR THE CURRENT ; TASK ARE MARKED FOR TERMINATION WITH A FINAL REQUEST STATUS OF 'IE.ABO'. ; ; INPUTS: ; ; R0=ADDRESS OF THE CURRENT I/O PACKET (MEANINGLESS). ; R1=ADDRESS OF THE TCB OF THE CURRENT TASK. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; ALL REQUESTS FOR THE CURRENT TASK ARE MARKED FOR TERMINATION WITH ; A FINAL STATUS OF 'IE.ABO'. ;- .ENABL LSB ARCAN: MOV #IE.ABO&377,R0 ;;;SET FINAL STATUS CODE TO ABORT BR 10$ ;;;FINISH IN COMMON CODE ;+ ; **-AROUT-DEVICE TIMEOUT ; ; THIS ROUTINE IS ENTERED WHEN AN AR11 OPERATION TIMES OUT. ALL REQUESTS IN THE ; SAMPLE QUEUE ARE MARKED FOR TERMINATION WITH A FINAL STATUS OF 'IE.DNR'. ; TIMEOUTS ARE USUALLY CAUSED BY A POWER FAILURE BUT MAY ALSO BE THE RESULT ; OF A HARDWARE FAILURE. ; ; INPUTS: ; ; R0=DEVICE TIMEOUT STATUS 'IE.DNR'. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; ALL REQUESTS ARE MARKED FOR TERMINATION WITH A FINAL STATUS OF ; 'IE.DNR'. ;- AROUT: MOV S.CSR(R4),R2 ;;;GET ADDRESS OF CONTROL STATUS REGISTER CLR (R2) ;;;CLEAR A/D INTERRUPTS CLR 4(R2) ;;;CLEAR CLOCK INTERRUPTS 10$: MOV R5,R2 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R2 ;;; 20$: MOV (R2),R2 ;;;GET ADDRESS OF NEXT ENTRY BEQ 40$ ;;;IF EQ NONE CMPB #IE.ABO,R0 ;;;CANCEL I/O? BNE 30$ ;;;IF NE NO MOV RQPKT(R2),R3 ;;;GET ADDRESS OF I/O PACKET CMP R1,I.TCB(R3) ;;;REQUEST FOR CURRENT TASK? BNE 20$ ;;;IF NE NO 30$: BISB #STPRQ,RSTAT(R2) ;;;SET TO TERMINATE SAMPLE REQUEST MOVB R0,FINST(R2) ;;;SET FINAL REQUEST STATUS MOV #NXTRQ,STATE(R2) ;;;SET STATE TO TERMINATION IN PROGRESS BR 20$ ;;; 40$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS BR ENDRQ2 ;FINISH IN COMMON CODE .DSABL LSB ;+ ; **-ARPWF-POWERFAIL ; ; THIS ROUTINE IS ENTERED AS THE RESULT OF A POWER FAILURE. POWERFAIL IS HANDLED ; VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES NO IMMEDIATE ACTION ON ; THE DEVICE. THE UNIT CONTROL BLOCK ADDRESS IS STORED IN THE DRIVER CONTROLLER ; TABLE. ; ; INPUTS: ; ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; THE UNIT CONTROL BLOCK ADDRESS IS STORED IN THE DRIVER CONTROLLER TABLE. ;- ARPWF: MOV R5,CNTBL(R3) ;SET ADDRESS OF UNIT CONTROL BLOCK RETURN ; ; ; FORK REQUESTED AND NO FORK IN PROGRESS ; ENDRQ1: BISB #US.FRK,U.STS(R5) ;;;SET FORK IN PROGRESS FLAG CALL $FORK ;;;CREATE A SYSTEM PROCESS BICB #US.FRK,U.STS(R5) ;CLEAR FORK IN PROGRESS FLAG ; ; SCAN SAMPLE QUEUE FOR EVENT FLAG AND TERMINATION REQUESTS ; ENDRQ2: MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOVB S.PRI(R4),PS ;;;LOCK OUT DEVICE INTERRUPTS MOV R5,R4 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R4 ;;; 10$: MOV R4,R3 ;;;SAVE ADDRESS OF PREVIOUS ENTRY MOV (R3),R4 ;;;GET ADDRESS OF NEXT ENTRY BEQ 70$ ;;;IF EQ NONE BITB #STPRQ,RSTAT(R4) ;;;TERMINATE REQUEST? BNE 20$ ;;;IF NE YES BITB #RQEFN,RSTAT(R4) ;;;REQUEST EFN SETTING? BEQ 10$ ;;;IF EQ NO BICB #RQEFN,RSTAT(R4) ;;;CLEAR EFN REQUEST FLAG CLRB PS ;;;ALLOW DEVICE INTERRUPTS MOV RQPKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV I.TCB(R3),R0 ;GET TCB ADDRESS OF REQUESTING TASK BIT #T2.ABO,T.ST2(R0) ;TASK BEING ABORTED? BNE ENDRQ2 ;IF NE YES BIS I.PRM+14(R3),@I.PRM+16(R3) ;SET SPECIFIED EVENT FLAG CALL $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST BR ENDRQ2 ;TRY AGAIN 20$: MOV (R4),(R3) ;;;REMOVE ENTRY FROM QUEUE 30$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS .IF DF D$$R11 MOV DATAW(R4),R3 ;GET DATA MASK WORD COM R3 ;CONVERT MASK TO IN USE BITS CMP #SYNDO,STRST(R4) ;SYNCRHONOUS DIGITAL OUTPUT? BEQ 40$ ;IF EQ YES CMP #SYNDI,STRST(R4) ;SYNCHRONOUS DIGITAL INPUT BNE 50$ ;IF NE NO BIC R3,U.CNT(R5) ;CLEAR INPUT BITS IN USE MASK BR 50$ ; 40$: BIC R3,U.CNT+2(R5) ;CLEAR OUTPUT BITS IN USE MASK 50$: BITB #STROT,RSTAT(R4) ;SET DIGITAL OUTPUT BIT ON START? BEQ 60$ ;IF EQ NO BIC DBMSK(R4),U.CNT+2(R5) ;CLEAR OUTPUT BIT IN USE MASK .ENDC 60$: CLR R0 ;PICKUP FINAL I/O STATUS BISB FINST(R4),R0 ; .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT APR6 MAPPING MOV IOSB2(R4),KISAR6 ;MAP TO SECOND I/O STATUS WORD .IFTF MOV @IOSB2+2(R4),R1 ;RETRIEVE CONTENTS OF SECOND I/O STATUS WORD .IFT MOV (SP)+,KISAR6 ;RESTORE CURRENT APR6 MAPPING .ENDC MOV RQPKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV R4,-(SP) ;SAVE ADDRESS OF SECONDARY CONTROL BLOCK CLR I.PRM+16(R3) ;CLEAR BLOCK LOCKING WORD FOR $IOFIN CALL $IOFIN ;FINISH I/O OPERATION MOV (SP)+,R0 ;RETRIEVE ADDRESS OF SECONDARY CONTROL BLOCK MOV #SLGTH,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $DEACB ;RELEASE SECONDARY CONTROL BLOCK BR ENDRQ2 ;GO AGAIN ; ; SCAN OF SAMPLE QUEUE COMPLETE--CHECK IF ANYTHING IS STILL ACTIVE ; 70$: MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;;;RESET DEVICE TIMEOUT COUNT TST U.BUF(R5) ;;;ANY REQUESTS IN SAMPLE QUEUE BNE 80$ ;;;IF NE YES MOV S.CSR(R4),R3 ;;;GET ADDRESS OF CONTROL STATUS REGISTER CLR (R3) ;;;CLEAR A/D INTERRUPTS CLR 4(R3) ;;;CLEAR CLOCK INTERRUPTS BICB #US.BSY,U.STS(R5) ;;;CLEAR UNIT BUSY CLRB S.STS(R4) ;;;CLEAR CONTROLLER BUSY 80$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS RETURN ; ; ; SUBROUTINE TO READ A VALUE FROM USER BUFFER ; .ENABL LSB RDWRD: ;;;REF LABEL .IF DF M$$MGE MOV IOSB2(R3),KISAR6 ;;;MAP TO SECOND I/O STATUS WORD .IFTF INC @IOSB2+2(R3) ;;;INCREMENT FREE POSITIONS IN BUFFER CMP FULBF(R3),@IOSB2+2(R3) ;;;BUFFER OVERRUN? BLO 70$ ;;;IF LO YES .IFT MOV CURBF(R3),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV @CURBF+4(R3),R2 ;;;READ VALUE FROM USER BUFFER BR 10$ ;;;FINISH IN COMMON CODE ; ; SUBROUTINE TO WRITE A VALUE INTO USER BUFFER ; WRWRD: ;;;REF LABEL .IFT MOV IOSB2(R3),KISAR6 ;;;MAP TO SECOND I/O STATUS WORD .IFTF INC @IOSB2+2(R3) ;;;INCREMENT NUMBER OF ENTRIES IN BUFFER CMP FULBF(R3),@IOSB2+2(R3) ;;;BUFFER OVERRUN? BLO 70$ ;;;IF LO YES .IFT MOV CURBF(R3),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV R2,@CURBF+4(R3) ;;;WRITE VALUE INTO USER BUFFER 10$: ADD #2,CURBF+4(R3) ;;;UPDATE USER BUFFER ADDRESS .IFT BIT #20000,CURBF+4(R3) ;;;OVERFLOW 4K BOUNDRY? BEQ 20$ ;;;IF EQ NO BIC #20000,CURBF+4(R3) ;;;CLEAR OVERFLOW BIT ADD #200,CURBF(R3) ;;;ADVANCE TO NEXT 4K BOUNDRY .IFTF 20$: DEC SMCNT(R3) ;;;END OF BUFFER? BNE 30$ ;;;IF NE NO .IFT MOV STRBF(R3),CURBF(R3) ;;;RESET RELOCATION BIAS .ENDC MOV STRBF+4(R3),CURBF+4(R3) ;;;RESET BUFFER ADDRESS MOV FULBF(R3),SMCNT(R3) ;;;RESET SAMPLE BUFFER COUNT BITB #STPBR,RSTAT(R3) ;;;STOP ON BUFFER RUNOUT? BEQ 40$ ;;;IF EQ NO DEC SAMCT(R3) ;;;DECREMENT BUFFER COUNT BEQ 60$ ;;;IF EQ BUFFER RUNOUT BR 40$ ;;; 30$: CMP SMCNT(R3),HAFBF(R3) ;;;EXACTLY AT HALF BUFFER? BNE 50$ ;;;IF NE NO 40$: BISB #RQEFN,RSTAT(R3) ;;;REQUEST EFN SETTING INC FKFLG ;;;SET FORK REQUEST 50$: CLC ;;;CLEAR OVERRUN INDICATOR .IF DF D$$R11 BIT DSMSK(R3),TEMP ;;;STOP BIT CLEAR? BEQ 90$ ;;;IF EQ NO .IFF BR 90$ ;;; .ENDC 60$: MOVB #IS.SUC,FINST(R3) ;;;SET SUCCESSFUL COMPLETION STATUS BR TERMS ;;; 70$: MOVB #IE.DAO,FINST(R3) ;;;SET FINAL STATUS TO BUFFER OVERRUN DEC @IOSB2+2(R3) ;;;READJUST BUFFER FREE COUNT TERMS: BISB #STPRQ,RSTAT(R3) ;;;SET TO TERMINATE SAMPLE REQUEST MOV #NXTRQ,STATE(R3) ¢;;;SET STATE TO TERMINATION IN PROGRESS INC FKFLG ;;;SET FORK REQUEST SEC ;;;SET OVERRUN/TERMINATION INDICATOR 90$: RETURN ;;; .DSABL LSB .END ¢s à~kQ ›c, .TITLE BFCTL .IDENT /08.03/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 08.03 ; ; D. N. CUTLER 26-DEC-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; G. H. KUENNING ; H. D. COFFMAN ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 5-NOV-79 ; MSH071 -- CORRECT CONDITIONAL ASSEMBLY COMMAND ; ; ; BUFFER CONTROL ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ;+ ; **-$GTBYT-GET NEXT BYTE FROM USER BUFFER ; ; THIS ROUTINE IS CALLED TO GET THE NEXT BYTE FROM THE USER BUFFER ; AND RETURN IT TO THE CALLER ON THE STACK. AFTER THE BYTE HAS BEEN ; FETCHED, THE NEXT BYTE ADDRESS IS INCREMENTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB THAT CONTAINS THE BUFFER POINTERS. ; ; OUTPUTS: ; ; THE NEXT BYTE IS FETCHED FROM THE USER BUFFER AND RETURNED ; TO THE CALLER ON THE STACK. THE NEXT BYTE ADDRESS IS INCREMENTED. ; ; ALL REGISTERS ARE PRESERVED ACROSS CALL. ;- .ENABL LSB $GTBYT::MOV (SP),-(SP) ;DUPLICATE RETURN ADDRESS .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.BUF(R5),KISAR6 ;MAP TO USER BUFFER MOVB @U.BUF+2(R5),4(SP) ;GET NEXT BYTE FROM USER BUFFER MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .IFF MOVB @U.BUF+2(R5),2(SP) ;GET NEXT BYTE FROM USER BUFFER .ENDC BR 20$ ;TAKE COMMON EXIT FOR ADDRESS UPDATE ;+ ; **-$PTBYT-PUT NEXT BYTE IN USER BUFFER ; ; THIS ROUTINE IS CALLED TO PUT A BYTE IN THE NEXT LOCATION IN ; USER BUFFER. AFTER THE BYTE HAS BEEN STORED, THE NEXT BYTE ADDRESS ; IS INCREMENTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB THAT CONTAINS THE BUFFER POINTERS. ; 2(SP)=BYTE TO BE STORED IN THE NEXT LOCATION OF THE USER BUFFER. ; ; OUTPUTS: ; ; THE BYTE IS STORED IN THE USER BUFFER AND REMOVED FROM ; THE STACK. THE NEXT BYTE ADDRESS IS INCREMENTED. ; ; ALL REGISTERS ARE PRESERVED ACROSS CALL. ;- $PTBYT:: ;REF LABEL .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.BUF(R5),KISAR6 ;MAP TO USER BUFFER MOVB 4(SP),@U.BUF+2(R5) ;STORE BYTE IN USER BUFFER MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .IFF MOVB 2(SP),@U.BUF+2(R5) ;STORE BYTE IN USER BUFFER .ENDC MOV (SP)+,(SP) ;COLLAPSE STACK REMOVING BYTE .IF DF G$$WRD!P$$WRD BR 20$ ;TAKE COMMON EXIT FOR ADDRESS UPDATE ;+ ; **-$GTWRD-GET NEXT WORD FROM USER BUFFER ; ; THIS ROUTINE IS CALLED TO GET THE NEXT WORD FROM THE USER BUFFER ; AND RETURN IT TO THE CALLER ON THE STACK. AFTER THE WORD HAS BEEN ; FETCHED, THE NEXT WORD ADDRESS IS CALCULATED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB THAT CONTAINS THE BUFFER POINTERS. ; ; OUTPUTS: ; ; THE NEXT WORD IS FETCHED FROM THE USER BUFFER AND RETURNED ; TO THE CALLER ON THE STACK. THE NEXT WORD ADDRESS IS CALCULATED. ; ; ALL REGISTERS ARE PRESERVED ACROSS CALL. ;- .IFTF .IF DF G$$WRD $GTWRD:: ;REF LABEL MOV (SP),-(SP) ;DUPLICATE RETURN ADDRESS .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.BUF(R5),KISAR6 ;MAP TO USER BUFFER MOV @U.BUF+2(R5),4(SP) ;GET NEXT WORD FROM USER BUFFER MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .IFF MOV @U.BUF+2(R5),2(SP) ;GET NEXT WORD FROM USER BUFFER .ENDC BR 10$ ;TAKE COMMON EXIT FOR ADDRESS UPDATE .IFF $GTWRD==-1 ;CRASH IF REFERENCED .ENDC ;+ ; **-$PTWRD-PUT NEXT WORD IN USER BUFFER ; ; THIS ROUTINE IS CALED TO PUT A WORD IN THE NEXT LOCATION IN ; USER BUFFER. AFTER THE WORD HAS BEEN STORED, THE NEXT WORD ADDRESS ; IS CALCULATED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB THAT CONTAINS THE BUFFER POINTERS. ; 2(SP)=WORD TO BE STORED IN THE NEXT LOCATION OF THE BUFFER. ; ; OUTPUTS: ; ; THE WORD IS STORED IN THE USER BUFFER AND REMOVED FROM ; THE STACK. THE NEXT WORD ADDRESS IS CALCULATED. ; ; ALL REGISTERS ARE PRESERVED ACROSS CALL. ;- .IF DF P$$WRD $PTWRD:: ;REF LABEL .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.BUF(R5),KISAR6 ;MAP TO USER BUFFER MOV 4(SP),@U.BUF+2(R5);STORE WORD IN USER BUFFER MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .IFF MOV 2(SP),@U.BUF+2(R5) ;STORE WORD IN USER BUFFER .ENDC MOV (SP)+,(SP) ;COLLAPSE STACK REMOVING WORD .IFF $PTWRD==-1 ;CRASH IF REFERENCED .ENDC .IFT 10$: INC U.BUF+2(R5) ;CALCULATE ADDRESS OF NEXT WORD .ENDC 20$: INC U.BUF+2(R5) ;INCREMENT NEXT BYTE ADDRESS .IF DF M$$MGE CMP U.BUF+2(R5),#160000 ;OVERFLOW 28K BOUNDARY? BLO 30$ ;IF LO NO SUB #20000,U.BUF+2(R5) ;REDUCE BY 4K ADD #200,U.BUF(R5) ;ADJUST RELOCATION BIAS .ENDC 30$: RETURN .DSABL LSB ;+ ; **-$GTCWD-GET NEXT WORD FROM USER CONTROL BUFFER ; ; THIS ROUTINE IS CALLED TO GET THE NEXT WORD FROM THE USER CONTROL ; BUFFER AND RETURN IT TO THE CALLER ON THE STACK. AFTER THE WORD HAS ; BEEN FETCHED, THE NEXT WORD ADDRESS IS CALCULATED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB THAT CONTAINS THE BUFFER POINTERS. ; ; OUTPUTS: ; ; THE NEXT WORD IS FETCHED FROM THE USER CONTROL BUFFER AND RETURNED ; TO THE CALLER ON THE STACK. THE NEXT WORD ADDRESS IS CALCULATED. ; ; ALL REGISTERS ARE PRESERVED ACROSS CALL. ;- .IF DF A$$D01!A$$F11!I$$CAD!I$$PAD!I$$P14!U$$ADM ;MSH071 ;**-1 $GTCWD::MOV (SP),-(SP) ;DUPLICATE RETURN ADDRESS .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV U.CBF(R5),KISAR6 ;MAP TO USER CONTROL BUFFER MOV @U.CBF+2(R5),4(SP) ;GET NEXT WORD FROM USER BUFFER MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .IFF MOV @U.CBF+2(R5),2(SP) ;GET NEXT WORD FROM USER BUFFER .IFTF ADD #2,U.CBF+2(R5) ;CALCULATE ADDRESS OF NEXT WORD .IFT BIT #20000,U.CBF+2(R5) ;OVERFLOW 4K BOUNDRY? BEQ 10$ ;IF EQ NO BIC #20000,U.CBF+2(R5) ;CLEAR OVERFLOW BIT ADD #200,U.CBF(R5) ;ADJUST RELOCATION BIAS .ENDC 10$: RETURN ; .ENDC ;+ ; **-$BLXIO-MOVE BLOCK OF DATA. ; ; THIS ROUTINE IS CALLED TO MOVE DATA IN MEMORY IN A MAPPED SYSTEM. ; ; INPUTS: ; ; R0=NUMBER OF BYTES TO MOVE. ; R1=SOURCE APR5 BIAS. ; R2=SOURCE DISPLACEMENT. ; R3=DESTINATION APR6 BIAS. ; R4=DESTINATION DISPLACEMENT. ; ; OUTPUTS: ; ; DESCRIBED MOVE IS ACCOMPLISHED. ; R0 ALTERED. ; R1,R3 PRESERVED ; R2,R4 POINT TO LAST BYTE OF SOURCE AND DESTINATION + 1 ; ; NOTE: THE COUNT INPUT IN R0 MUST NOT BE ZERO AND IT MUST NOT ; BE LARGE ENOUGH TO CROSS APR BOUNDARIES (THIS TYPICALLY ; MEANS A MAXIMUM OF 4K-63). ; ; NOTE2: IF THE COUNT IN R0 EQUALS ZERO OR IS GREATER THAN ; 4K-63. WORDS, A RETURN IS EXECUTED WITH NO REGISTERS ; ALTERED. ;- .IF DF M$$MGE $BLXIO::TST R0 ;ZERO BYTES TO MOVE? BEQ 100$ ;IF EQ YES -- RETURN CMP #17701,R0 ;MOVING MORE THAN AN APR-63. WORDS? BLOS 100$ ;IF LOS YES -- RETURN MOV R5,-(SP) ;SAVE R5 MOV #KISAR6,R5 ;POINT TO KERNEL APR6 MOV (R5),-(SP) ;SAVE KERNEL APR6 MOV R3,(R5) ;SET UP KERNEL APR6 FOR TRANSFER MOV -(R5),-(SP) ;SAVE KERNEL APR5 MOV R1,(R5) ;SET UP KERNEL APR5 FOR TRANSFER .IF NDF N$$MOV 10$: MOVB (R2)+,(R4)+ ;MOVE NEXT BYTE DEC R0 ;MORE TO MOVE? BNE 10$ ;IF NE YES .IFF MOV #1,-(SP) ;PUSH LOW BIT MASK BIT (SP),R2 ;SOURCE ADDRESS ODD? BEQ 10$ ;IF EQ NO MOVB (R2)+,(R4)+ ;MOVE FIRST BYTE DEC R0 ;REDUCE COUNT 10$: BIT (SP),R4 ;DESTINATION ADDRESS ODD? BNE 50$ ;IF NE YES, PERFORM BYTE MOVES 20$: SUB #N$$MOV*2,R0 ;MOVE ENTIRE BLOCK? BCC 40$ ;IF CC YES BIC R0,(SP) ;REMAINING COUNT ODD? BNE 30$ ;IF NE NO DEC R0 ;ADJUST NEGATIVE COUNT 30$: SUB R0,PC ;INDEX INTO MOVE INSTRUCTIONS 40$: ;REF LABEL .REPT N$$MOV MOV (R2)+,(R4)+ ;MOVE A WORD .ENDR BCC 20$ ;IF CC MORE TO GO BR 80$ ;EXIT THROUGH COMMON CODE 50$: ASL R0 ;DOUBLE COUNT 60$: SUB #N$$MOV*2,R0 ;MOVE ENTIRE BLOCK? BCC 70$ ;IF CC YES SUB R0,PC ;ELSE INDEX INTO MOVE INSTRUCTIONS 70$: ;REF LABEL .REPT N$$MOV MOVB (R2)+,(R4)+ ;MOVE A BYTE .ENDR BCC 60$ ;IF CC MORE TO GO 80$: TST (SP)+ ;POP CONSTANT BNE 90$ ;IF NE NO MORE TO MOVE Ô MOVB (R2)+,(R4)+ ;MOVE LAST BYTE 90$: ;REF LABEL .ENDC MOV (SP)+,(R5)+ ;RESTORE KERNEL APR5 MOV (SP)+,(R5) ;RESTORE KENREN APR6 MOV (SP)+,R5 ;RESTORE R5 100$: RETURN ; .ENDC .END ÔYqwkQ ›c, .TITLE REQSB .IDENT /13.64/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 13.64 ; ; D. N. CUTLER 10-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; P. WANNHEDEN ; CHUCK SPITZ ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 23-JUL-79 ; MSH008 -- CORRECT CONDITIONAL FOR NO SEND/REC BY REF ; ; M. S. HARVEY 3-AUG-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 13-AUG-79 ; MSH048 -- CLEAR CHECKPOINT REQUEST FOR TASKS THAT ; ARE NOT ELIGIBLE FOR CHECKPOINTING ; ; M. S. HARVEY 16-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 8-OCT-79 ; MSH021 -- CONDITIONALIZE ACP TEST ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 23-APR-80 ; MSH069 -- ALLOW STOPPING FOR GLOBAL EVENT FLAGS ; ; M. S. HARVEY 25-APR-80 ; MSH096 -- SUPPORT ALTERNATE HEADER REFRESH AREAS ; FOR SYSTEM-CONTROLLED PARTITIONS ; ; M. S. HARVEY 2-JUN-80 ; MSH102 -- STORE SENDER'S TASK NAME WHEN CLEARING ; TCB POINTER FROM RREF PACKET ; ; E. A. FLOYD 9-JUN-80 ; EF012 -- CONDITIONALIZE $FNDSP FOR ASSEMBLY ; WITH RSX11S V3.0 ; ; M. S. HARVEY 30-JUN-80 ; MSH091 -- USE KERNEL AST SYMBOL ; ; M. S. HARVEY 19-AUG-80 ; MSH111 -- PROPERLY CONDITIONALIZE TKTN SPECIFIC CODE ; ; M. S. HARVEY 6-OCT-80 ; MSH121 -- SUPPORT REQUESTED EXIT ASTS ; ; M. S. HARVEY 10-OCT-80 ; MSH122 -- EXTERNALLY BLOCKED TASKS MUST BE ; INELIGIBLE FOR MEMORY RESIDENCE ; ; M. S. HARVEY 24-NOV-80 ; MSH129 -- RETURN SECONDARY EXIT STATUS CODE IN ESB ; ; M. S. FOX 07-JAN-81 ; MF203 -- INITIAL ALTERNATE CLI SUPPORT ; ; M. S. FOX 30-JAN-81 ; MF208 -- SUPPORT COMMAND ARRIVAL ASTS FOR CLIS ; ; M. S. HARVEY 23-MAR-81 ; MSH142 -- DON'T REQUEST CERTAIN TASKS DURING LOW ; POOL CONTROL ; ; M. S. HARVEY 30-APR-81 ; MSH166 -- ELIMINATE THRASHING CAUSED BY OVERLAPPING ; SWAPPING PRIORITY RANGES OF TASKS BEING ; CHECKPOINTED WITH OUTSTANDING I/O ; ; M. S. HARVEY 6-MAY-81 ; MSH168 -- REDUCE THE CHANCES OF DEADLOCK IN SYSTEM- ; CONTROLLED PARTITIONS WITH CHECKPOINTABLE ; TASKS WITH OUTSTANDING I/O ; ; M. S. HARVEY 6-AUG-81 ; MSH184 -- DO NOT REQUEST MEMORY SHUFFLER TOO OFTEN ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 22-SEP-81 ; MSH172 -- STOPFOR STATE CANNOT EXIST AT AST STATE ; ; M. S. HARVEY 13-OCT-81 ; MSH196 -- MOVE $CLSRF CODE DIRECTLY INTO DREIF. ; THIS INCLUDES MSH008 AND MSH102. ; ; M. S. HARVEY 13-NOV-81 ; MSH205 -- GENERALIZE AST SEARCH MECHANISM TO ALLOW ; MCR TO HANDLE ABORT ASTS CORRECTLY ; ; ; TASK REQUEST RELATED SUBROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,ITBDF$,PCBDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS ITBDF$ ;DEFINE INTERRUPT TRANSFER BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$ABCTK-ABORT CURRENT TASK ; **-$ABTSK-ABORT TASK ; ; THIS ROUTINE IS CALLED TO MARK A TASK FOR ABORT AND TO FORCE A TASK EXIT. ; THE REASON FOR ABORT AND THE CURRENT OUTSTANDING I/O COUNT ARE STORED ; IN THE FIRST TASK EVENT FLAG WORD. ; ; INPUTS: ; ; R0=REASON FOR ABORT. ; R1=ADDRESS OF THE TCB OF THE TASK TO BE ABORTED (ENTRY AT $ABTSK ONLY). ; R2=EXTENDED ABORTER INFORMATION (ONLY IF R0=S.CABO OR S.CPMD) ;MSH121 ; ; OUTPUTS: ; ; THE TASK IS MARKED FOR ABORT OR AN ABORT AST IS DECLARED. ;MSH121 ; THE TASK IS UNBLOCKED AND A CONDITIONAL SCHEDULE REQUEST ;MSH121 ; IS SET. ;MSH121 ;- ;**-2 $ABCTK::MOV $TKTCB,R1 ;SET TCB ADDRESS TO CURRENT TASK $ABTSK::BIC #TS.STP,T.STAT(R1) ;UNBLOCK THE TASK ;MSH122 ;MSH121 ; ;MSH121 ; IF THE TASK WAS REQUESTED TO EXIT AND A REQUESTED EXIT AST WAS ;MSH121 ; SPECIFIED BY THE TASK, THAT AST MUST BE DECLARED INSTEAD OF ;MSH121 ; ACTUALLY ABORTING THE TASK. IF A NONPRIVILEGED TASK HAS ALREADY ;MSH121 ; HAD SUCH AN AST DECLARED PREVIOUSLY, ALWAYS ABORT THE TASK. ;MSH121 ; ;MSH121 ;MSH121 .IF DF A$$TRP&A$$BRT ;MSH121 ;MSH121 CMP R0,#S.CABO ;ABORT BY DIRECTIVE OR CLI? ;MSH121 BEQ 2$ ;IF EQ YES ;MSH121 CMP R0,#S.CPMD ;ABORT WITH PMD? ;MSH121 BNE 5$ ;IF NE NO, ABORT THE TASK ;MSH121 2$: SAVNR ;SAVE R4 AND R5 ;MSH121 MOV #AS.REA,R4 ;GET CODE FOR REQUESTED EXIT AST ;MSH121 MOV R1,-(SP) ;SAVE TCB ADDRESS ;MSH121 MOV R0,-(SP) ;SAVE ABORT CODE ;MSH121 MOV R1,R5 ;COPY TCB ADDRESS ;MSH121 MOV R2,-(SP) ;SAVE ABORTER INFORMATION ;MSH121 CALL $DASTT ;DECLARE REQUESTED EXIT AST FOR TASK ;MSH121 MOV (SP)+,R2 ;RESTORE ABORTER INFORMATION ;MSH121 MOV (SP)+,R0 ;RESTORE ABORT CODE ;MSH121 BCC 3$ ;IF CC AST SET UP ;MSH121 MOV (SP)+,R1 ;RESTORE TCB ADDRESS ;MSH121 BIT #T3.PRV,T.ST3(R1) ;ABORTED TASK PRIVILEGED? ;MSH121 BEQ 5$ ;IF EQ NO, ABORT IT ;MSH121 BIT #T2.REX,T.ST2(R1) ;ABORT AST IN PROGRESS ALREADY? ;MSH121 BEQ 5$ ;IF EQ NO, ABORT IT ;MSH121 MOV R1,R0 ;COPY TCB ADDRESS ;MSH121 BR 10$ ;RESCHEDULE TASK ;MSH121 3$: TST (SP)+ ;CLEAN STACK ;MSH121 MOV #4,A.PRM(R1) ;STORE NUMBER OF AST PARAMETER BYTES ;MSH121 MOV R2,A.PRM+2(R1) ;STORE ABORTER INFORMATION ;MSH121 RETURN ;$NXTSK ALREADY CALLED, SIMPLY RETURN ;MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 ; ;MSH121 ; COME HERE TO ACTUALLY ABORT THE TASK. NOTE THAT ABORTED ACPS DO ;MSH121 ; NOT GET AN ABORT STATUS STUFFED INTO T.EFLG+2 BECAUSE SOME USE ;MSH121 ; THAT OFFSET FOR OTHER USES (SUCH AS MOUNTED VOLUME COUNTS). ;MSH121 ; ;MSH121 ;MSH121 5$: ;MSH046 .IF DF T$$BUF ;MSH046 ;MSH046 BIS #177400,R0 ;DEFAULT TO MAXIMUM I/O COUNT ;MSH046 MOV R0,T.EFLG(R1) ;INSERT REASON TO ABORT AND I/O COUNT ;MSH046 ;MSH046 ; THE FOLLOWING DEPENDS ON THE LOW BYTE OF T.TIO-1 BEING ZERO. ;MSH046 ;MSH046 MOV T.TIO-1(R1),R0 ;GET BUFFERED I/O COUNT (T.TIO) ;MSH046 ADD T.PRI(R1),R0 ;ADD NON-BUFFERED I/O (T.IOC) ;MSH046 BCS 7$ ;IF CS BYTE NOT LARGE ENUFF, USE MAX ;MSH046 SWAB R0 ;ISOLATE TOTAL I/O COUNT ;MSH046 MOVB R0,T.EFLG+1(R1) ;SAVE OUTSTANDING I/O COUNT ;MSH046 7$: ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 MOV R0,T.EFLG(R1) ;INSERT REASON FOR ABORT ;MSH046 MOVB T.IOC(R1),T.EFLG+1(R1) ;SAVE OUTSTANDING I/O COUNT ;**-1 ;MSH046 .ENDC ;MSH046 .IF DF P$$OFF .IF DF A$$CPS ;MSH021 ;MSH021 BIT #T3.ACP,T.ST3(R1) ;IS THIS AN ACP? BNE 9$ ;IF NE YES ;MSH021 .ENDC ;MSH021 ;MSH021 MOV #EX$SEV,T.EFLG+2(R1) ;SET SEVERE ERROR EXIT STATUS 9$: ;REF LABEL .ENDC MOV R1,R0 ;COPY TCB ADDRESS ADD #T.STAT,R1 ;POINT TO FIRST TASK STATUS WORD BIC #TS.CKR,(R1)+ ;CLEAR STATUS BITS BIC #T2.SEF!T2.STP!T2.SPN,(R1) ;MAKE TASK RUNNABLE BIS #T2.AST!T2.DST!T2.HLT!T2.ABO,(R1) ;DSBL AST'S & FRC EXIT TST -(R1) ;OUT FOR INITIAL LOAD OR OTHERWISE BLKD? BNE 10$ ;IF NE YES CALL $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST 10$: MOV T.PCB(R0),R0 ;POINT TO TASK PCB .IF DF D$$ISK CALLR $NXTSK ;REALLOCATE TASK PARTITION IF NECESSARY .IFF RETURN ; .ENDC ;+ ; **-$BILDS-BUILD STACK AND INITIALIZE HEADER ; ; THIS ROUTINE SETS UP THE TASK STACK AND INITIALIZES THE HEADER. IT IS ; CALLED PRIOR TO PLACING A TASK INTO CONTENTION FOR THE PROCESSOR WHEN ; AN EXECUTION REQUEST IS MADE FOR A TASK THAT IS FIXED IN MEMORY OR ; WHEN A DISK RESIDENT TASK HAS FINISHED LOADING. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO INITIALIZE. ; ; OUTPUTS: ; ; 1-TASK LOCAL EVENT FLAGS 1.-32. ARE CLEARED. ; 2-CURRENT UIC IS SETUP IN THE HEADER. ; 3-TASK CONTEXT IS SETUP TO CAUSE THE TASK TO START EXECUTION AT ITS ENTR ; 4-REDISPATCHING OF THE PROCESSOR IS CONDITIONALLY REQUESTED. ; ; R3 IS PRESERVED ACROSS CALL. ;-  $BILDS::MOV T.PCB(R0),R1 ;GET ADDRESS OF TASK PCB MOV P.HDR(R1),R1 ;POINT TO TASK HEADER MOV T.EFLG(R0),H.CUIC(R1) ;SET SPECIFIED UIC BNE 10$ ;IF NE UIC WAS SPECIFIED MOV H.DUIC(R1),H.CUIC(R1) ;SET DEFAULT UIC .IF DF M$$MUP BR 15$ ; .IFTF 10$: ;REF LABEL .IFT MOV T.ACTL(R0),H.DUIC(R1) ;SET DEFAULT UIC .ENDC 15$: BIT #T2.ABO,T.ST2(R0) ;TASK MARKED FOR ABORT? BNE 20$ ;IF NE YES CLR T.EFLG(R0) ;CLEAR TASK LOCAL EVENT FLAGS ;MSH021 .IF DF A$$CPS  ;MSH021 ;MSH021 BIT #T3.ACP,T.ST3(R0) ;TASK ACP? BNE 20$ ;IF NE YES ;MSH021 .ENDC ;MSH021 ;MSH021 CLR T.EFLG+2(R0) ; 20$: ;REF LABEL .IF DF M$$MGE MOV H.ISP(R1),(R1) ;SET INITIAL STACK POINTER MOV H.GARD(R1),R2 ;POINT TO CONTEXT SAVE AREA SUB #16,R2 ;POINT TO SAVED PC MOV H.IPC(R1),(R2) ;SET INITIAL PC WORD MOV H.IPS(R1),-(R2) ;SET INITIAL PS WORD .IFF MOV H.ISP(R1),R2 ;GET INITIAL STACK POINTER MOV H.IPS(R1),-(R2) ;SET INITIAL PS WORD MOV H.IPC(R1),-(R2) ;SET INITIAL PC WORD CMP -(R2),-(R2) ;ADJUST TO BOTTOM OF STACK MOV R2,(R1) ;SET INITIAL STACK POINTER .ENDC ;+ ; **-$ACTTK-PUT TASK IN ACTIVE TASK LIST ; ; THIS ROUTINE IS CALLED TO PUT AN ACTIVE TASK IN THE ACTIVE TASK LIST. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO PUT IN THE ACTIVE LIST. ; ; OUTPUTS: ; THE SPECIFIED TASK IS MERGED INTO THE ACTIVE TASK LIST BY ; PRIORITY. ; ; R3 IS PRESERVED ACROSS CALL. ;- $ACTTK::MOV #$ACTHD-T.ACTL,R1 ;SET ADDRESS OF PREVIOUS TCB 10$: MOV R1,R2 ;SAVE ADDRESS OF PREVIOUS TCB MOV T.ACTL(R2),R1 ;GET ADDRESS OF NEXT TCB CMPB T.PRI(R1),T.PRI(R0) ;TASK HIGHER OR SAME PRIORITY? BHIS 10$ ;IF HIS YES MOV R0,T.ACTL(R2) ;LINK NEW TASK TO PREVIOUS MOV R1,T.ACTL(R0) ;SET LINK TO NEXT IN NEW TASK ;+ ; **-$SETCR-SET CONDITIONAL SCHEDULE REQUEST ; **-$SETRQ-SET SCHEDULE REQUEST ; **-$SETRT-SET SCHEDULE REQUEST FOR CURRENT TASK ; ; THIS ROUTINE IS CALLED TO FORCE REDISPATCHING OF THE PROCESSOR ; FROM A SPECIFIED POSITION IN THE TASK LIST. IF A PREVIOUS REQUEST ; HAS BEEN SET, THEN REDISPATCHING STARTS AT WHICH EVER REQUEST ; HAS THE HIGHEST PRIORITY. ; ; INPUTS: ; ; IF ENTRY AT $SETRT, THEN ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; IF ENTRY AT $SETRQ OR $SETCR, THEN ; R0=ADDRESS OF THE TCB TO START DISPATCHING AT. ; ; OUTPUTS: ; ; A SCHEDULE REQUEST IS SET WHICH WILL FORCE A REDISPATCH- ; ING OF THE PROCESSOR WHEN A SYSTEM EXIT IS EXECUTED. ; ; R2 AND R3 ARE PRESERVED ACROSS CALL. ; R0 IS PRESERVED ACROSS CALL IF ENTRY IS NOT AT $SETRT. ;- .ENABL LSB $SETCR::CMP R0,$TKTCB ;REQUESTED TASK SAME AS CURRENT? BEQ $SETRQ ;IF EQ YES CMPB $CURPR,T.PRI(R0) ;CURRENT TASK HIGHER PRIORITY? BHI 30$ ;IF HI YES BLO $SETRQ ;IF LO NO 10$: CALLR $DRDSE ;SAME PRIORITY-DECLARE SIGNIFICANT EVENT $SETRT::MOV R5,R0 ;SET ADDRESS OF DISPATCH TCB $SETRQ::MOV $RQSCH,R1 ;GET PREVIOUS SCHEDULE REQUEST BEQ 20$ ;IF EQ NO PREVIOUS REQUEST CMP R0,R1 ;TASK ALREADY RESCHEDULED? BEQ 30$ ;IF EQ YES CMPB T.PRI(R1),T.PRI(R0) ;COMPARE PRIORITIES BHI 30$ ;IF HI PREVIOUS IS HIGHER PRIORITY BEQ 10$ ;IF EQ SAME PRIORITY 20$: MOV R0,$RQSCH ;SET SCHEDULE REQUEST 30$: RETURN ; .DSABL LSB ;MSH049 ;+ ;MSH049 ; **-$SETMG/$SETFG-SET EVENT FLAG AND UNLOCK IF GROUP GLOBAL ;MSH049 ; ;MSH049 ; THESE ROUTINES SET AN EVENT FLAG AND TAKE CARE OF THE REQUIRED ;MSH049 ; SCHEDULING. IF THE EVENT FLAG WAS GROUP GLOBAL, THE USE COUNT ;MSH049 ; FOR THAT FLAG'S GROUP GLOBAL CONTROL BLOCK IS DECREMENTED. IF ;MSH049 ; THE CONTROL BLOCK IS MARKED FOR DELETE AND THE COUNT GOES TO ;MSH049 ; ZERO, IT WILL BE DEALLOCATED. ;MSH049 ; ;MSH049 ; INPUTS: ;MSH049 ; ;MSH049 ; R0=EVENT FLAG NUMBER ($SETFG) OR EVENT FLAG MASK ($SETMG). ;MSH049 ; R1=EVENT FLAG WORD ADDRESS ($SETMG ONLY). ;MSH049 ; R5=TCB ADDRESS FOR WHICH FLAG IS BEING SET. ;MSH049 ; ;MSH049 ; OUTPUTS: ;MSH049 ; ;MSH049 ; R0=TCB ADDRESS OF TASK WHOSE FLAG WAS SET ;MSH049 ; R3 IS PRESERVED. ;MSH049 ; ;MSH049 ;- ;MSH049 ;MSH049 .ENABL LSB ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 $SETMG::CALL $SETM ;SET THE EVENT FLAG ;MSH049 BR 5$ ;JOIN COMMON CODE ;MSH049 $SETFG::CALL $SETF ;SET THE EVENT FLAG ;MSH049 5$: BNE 15$ ;IF NE FLAG WAS COMMON OR LOCAL ;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 DECB T.GGF(R5) ;DECR GRP GLOBAL USE COUNT FOR TASK ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 ASR R1 ;ISOLATE SECOND EVENT FLAG WORD INDICATO;MSH049 SBC R1 ;SUBTRACT FOR IT IF IT EXISTS ;MSH049 ASL R1 ;RESTORE TO WORD ADDRESS (G.EFLG) ;MSH049 DEC -(R1) ;DECR GROUP GLOBAL USE COUNT (G.CNT) ;MSH049 BNE 15$ ;IF NE THESE EVENT FLAGS STILL IN USE ;MSH049 ; ;MSH049 ; THIS CODE DEPENDS ON THE FACT THAT GS.DEL IS THE ONLY DEFINED STATUS ;MSH049 ; BIT IN G.STAT AND ITS VALUE IS '1'. ;MSH049 ; ;MSH049 ASSUME 1,GS.DEL ;MSH049 ASRB -(R1) ;FLAGS MARKED FOR DELETE? ;MSH049 BCC 15$ ;IF CC NO ;MSH049 MOV R0,-(SP) ;SAVE TCB ADDRESS ;MSH049 MOV R3,-(SP) ;SAVE R3 ;MSH049 MOV R4,-(SP) ;SAVE R4 ;MSH049 MOVB -(R1),R4 ;GET GROUP NUMBER (G.GRP) ;MSH049 CALL $SRGEF ;FIND THESE FLAGS IN GROUP GLOBAL LIST ;MSH049 CALL $ELGEF ;ELIMINATE THIS GROUP GLOBAL CONTROL BLK;MSH049 MOV (SP)+,R4 ;RESTORE R4 ;MSH049 MOV (SP)+,R3 ;RESTORE R3 ;MSH049 MOV (SP)+,R0 ;RESTORE TCB ADDRESS ;MSH049 15$: RETURN ;MSH049 ;MSH049 .DSABL LSB ;MSH049 ;+ ; **-$SETF/$SETM-SET EVENT FLAG ; ; THESE ROUTINES SET AN EVENT FLAG AND TAKE CARE OF THE REQUIRED ; RESCHEDULING. ; ; INPUTS: ; ; R0=EVENT FLAG NUMBER ($SETF) OR EVENT FLAG MASK ($SETM). ; R1=EVENT FLAG WORD ADDRESS ($SETM ONLY). ; R5=TCB ADDRESS FOR WHICH FLAG IS BEING SET. ; ; OUTPUTS: ; ; R0=TCB ADDRESS OF TASK WHOSE FLAG WAS SET ; R1=EVENT FLAG WORD ADDRESS (IF GROUP GLOBALS SUPPORTED) ;MSH049 ; R3 IS PRESERVED. ; ;MSH049 ; IF GROUP GLOBAL EVENT FLAGS ARE SUPPORTED: ;MSH049 ; Z=0 IF LOCAL OR COMMON EVENT FLAG SET ;MSH049 ; Z=1 IF GROUP GLOBAL EVENT FLAG SET ;MSH049 ; ;MSH049 ;- .IFF ;MSH049 ;MSH049 $SETFG:: ;REF LABEL ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 $SETF:: CALL $CEFI ;CONVERT EVENT FLAG TO MASK AND ADDRESS ;MSH049 .IFF ;MSH049 ;MSH049 $SETMG:: ;REF LABEL  ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 $SETM:: ;REF LABEL ;MSH049 ;MSH049 .IFT ;MSH049 ;MSH049 CLR -(SP) ;CLR GROUP GLOBAL INDICATOR ;MSH049 MOV R1,-(SP) ;SAVE EVENT FLAG WORD ADDRESS ;MSH049 BIC #1,R1 ;CLEAR GROUP GLOBAL SECOND WORD FLAG ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 BIT #T2.ABO,T.ST2(R5) ;IS TASK MARKED FOR ABORT? ;MSH049 BNE 10$ ;IF NE YES, DO NOT TOUCH EVENT FLAG WORD;**-1 BIS R0,(R1) ;SET THE EVENT FLAG 10$: MOV R5,R0 ;COPY TCB ADDRESS FOR $SETCR TST R1 ;WAS AN EVENT FLAG SPECIFIED? ;MSH049 BEQ 19$ ;IF EQ NO, PREVENT UNNECESSARY SCHEDULIN;MSH049 CMP R1,#$COMEF+2 ;IS IT A COMMON EVENT FLAG? ;**-1 BLOS 20$ ;IF LOS YES ;MSH049 .IFT ;MSH049 ;MSH049 SUB R5,R1 ;IS IT GROUP GLOBAL? ;MSH049 BLO 15$ ;IF LO YES ;MSH049 SUB #T.EFLG+2,R1 ;IS IT LOCAL? ;MSH049 BLE 18$ ;IF LE YES ;MSH049 15$: DEC 2(SP) ;INDICATE SETTING GROUP GLOBAL FLAG ;MSH049 BR 20$ ;JOIN COMMON CODE ;MSH049 18$: ;REF LABEL ;MSH049 .IFTF ;MSH049 ;MSH172 ; ;MSH172 ; NOTE THAT IF THE TASK IS IN A STOPFOR STATE, IT WILL ONLY BE ;MSH172 ; UNSTOPPED IF THE EVENT FLAG BEING SET IS LOCAL. IF IT IS LOCAL, ;MSH172 ; PERFORMANCE CAN BE ENHANCED IF THE TASK IS IMMEDIATELY UNSTOPPED, ;MSH172 ; RATHER THAN WAITING FOR THE SCHEDULER TO DO IT. ;MSH172 ; ;MSH172 ; IF THE EVENT FLAG IS COMMON OR GROUP GLOBAL, THEN A SIGNIFICANT ;MSH172 ; EVENT IS DECLARED. SINCE ACCESS TO THESE FLAGS SHOULD BE ALLOWED ;MSH172 ; IN A STRICTLY PRIORITY ORIENTED ORDER, THE UNSTOP PROCEDURE WILL ;MSH172 ; BE DEFERRED TO THE SCHEDULER. THE SCHEDULER WILL START WITH THE ;MSH172 ; HIGHEST PRIORITY TASK AND GIVE IT FIRST ACCESS TO THE GLOBAL FLAG. ;MSH172 ; UNSTOPPING THE CURRENT TASK NOW MIGHT UPSET THE NATURAL FLOW OF ;MSH172 ; FLAG ACCESS IN CASE A HIGHER PRIORITY TASK HAPPENS TO BE STOPPED ;MSH172 ; FOR THE SAME EVENT FLAG. WE CANNOT ALLOW A LOWER PRIORITY TASK ;MSH172 ; (THIS ONE) TO PERHAPS ERASE THE EVENT FLAG BEFORE THE HIGHER ;MSH172 ; PRIORITY TASK HAS A CHANCE TO AT LEAST RECOGNISE THAT THE EVENT ;MSH172 ; FLAG WAS SET. THIS IS PREVENTED BY NOT UNSTOPPING THE CURRENT TASK ;MSH172 ; HERE AND NOW. ;MSH172 ; ;MSH172 ;MSH046 .IF DF S$$TOP!T$$BUF ;MSH046 ;MSH046 BIT #T2.AST!T2.SEF,T.ST2(R0) ;TASK IN STOPFOR STATE? ;MSH172 ;MSH172 .IF DF A$$TRP ;MSH172 ;MSH172 BMI 30$ ;IF MI NO, TASK IN AST STATE ;MSH172 ;MSH172 .ENDC ;MSH172 ;MSH046 .IF DF T$$BUF ;MSH046 ;MSH046 BNE 185$ ;IF NE YES ;MSH046 TSTB T.TIO(R0) ;OUTSTANDING BUFFERED I/O? ;MSH046 BEQ 30$ ;IF EQ NO, NO STOPFOR POSSIBLE ;MSH172 BIT #T2.WFR,T.ST2(R0) ;TASK STOPPED FOR BUFFERED I/O? ;MSH172 ;MSH046 .ENDC ;MSH046 ;MSH046 BEQ 30$ ;IF EQ NO, DON'T UNSTOP IT ;MSH046 185$: BIT T.EFLM(R0),@T.EFLM+2(R0) ;STOPFOR CONDITION SATISFIED? ;MSH046 BEQ 30$ ;IF EQ NO ;MSH046 MOV R3,-(SP) ;SAVE R3 ;MSH046 MOV R0,-(SP) ;SAVE TCB ;MSH046 CALL $EXRQN ;UNSTOP AND REQUEST TASK TO RUN ;MSH046 MOV (SP)+,R0 ;RESTORE TCB ;MSH046 MOV (SP)+,R3 ;RESTORE R3 ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH049 19$: TST $SIGFL ;TASK WAITING FOR SIGNIFICANT EVENT? ;MSH049 BEQ 30$ ;IF EQ NO ;MSH049 ;MSH049 .IFF ;MSH049 ;MSH049 20$: CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT ;MSH049 30$: CALLR $SETCR ;FORCE CONDITIONAL REDISPATCH ;MSH049 ;MSH049 .IFT ;MSH049 ;MSH049 20$: CALL $DRDSE ;DECLARE SIGNIFICANT EVENT ;MSH049 BR 40$ ;JOIN COMMON CODE ;MSH049 30$: CALL $SETCR ;FORCE CONDITIONAL REDISPATCH ;MSH049 40$: MOV (SP)+,R1 ;RESTORE EVENT FLAG WORD ADDRESS ;MSH049 INC (SP)+ ;CLEAN STACK AND SET Z-BIT FOR RETURN ;MSH049 RETURN ; ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 ;+ ; MF208 ; **-$DCAST-DECLARE COMMAND ARRIVAL AST TRAP FOR CLIS ; MF208 ; ; MF208 ; THIS ROUTINE IS CALLED BY THE COMMAND QUEUEING ROUTINE $QCLIL ; MF208 ; WHEN IT IS QUEUEING A COMMAND TO A CLI TASK. IF THE CLI ; MF208 ; HAS SPECIFIED THE COMMAND ARRIVAL AST, AN ATTEMPT IS MADE TO ; MF208 ; ALLOCATE A NEW AST BLOCK FROM THE POOL. THIS IS DONE IN ORDER ; MF208 ; TO ELIMINATE THE WINDOW THAT OCCURS WHEN THE AST BLOCK WOULD ; MF208 ; NORMALLY BE UNLINKED FROM T.SAST AND LINKED INTO T.ASTL. ; MF208 ; IT WOULD BE UNACCEPTABLE FOR A CLI TO LOSE A COMMAND DURING THIS ; MF208 ; WINDOW. IF THE ALLOCATION FAILS HOWEVER, THE CURRENT EXISTING ; MF208 ; AST BLOCK IS USED. THE WORD AT A.PRM+2 IN THE AST BLOCK IS USED ; MF208 ; AS A FLAG TO THE SYSXT CODE TO INFORM IT IF IT SHOULD DEALLOCATE ; MF208 ; OR RELINK THE AST BLOCK. ; MF208 ; ; MF208 ; INPUTS: ; MF208 ; ; MF208 ; R0=TCB ADDRESS OF CLI ; MF208 ; R1=ADDRESS OF COMMAND BUFFER ; MF208 ; ; MF208 ; OUTPUTS: ; MF208 ; ; MF208 ; C=1 IF THE TASK IS NOT SETUP FOR THE SPECIFIED AST ; MF208 ; C=0 IF THE TASK IS SETUP FOR THE AST AND THE AST HAS ; MF208 ; BEEN DECLARED ; MF208 ; R1=ADDRESS OF THE AST CONTROL BLOCK ; MF208 ; ; MF208 ;- ; MF208 ; MF208 ; MF208 .IF DF A$$CLI ; MF208 ; MF208 .IF DF A$$TRP ; MF208 ; MF208 $DCAST::SAVNR ;SAVE R4 AND R5 ; MF208 MOV #AS.CAA,R4 ;SET AST TYPE ; MF208 MOV R0,R5 ;COPY CLI'S TCB ADDRESS ; MF208 MOV R1,R3 ;COPY COMMAND ADDRESS ; MF208 ; MF208 .IFF ;A$$TRP ; MF208 ; MF208 $DCAST::.WORD SEC!SEZ ;SET C AND Z ; MF208 RETURN ; MF208 ; MF208 .ENDC ;A$$TRP ; MF208 ; MF208 ; MF208 .IFF ;A$$CLI ; MF208 ; MF208 $DCAST:: ;DEFINE FOR MCR ; MF208 ; MF208 .ENDC ;A$$CLI ; MF208 ; MF208 ; MF208 ;**-19 ;+ ; **-$DASTT-DECLARE AST TRAP ; ; THIS ROUTINE IS CALLED TO DECLARE A NON-I/O RELATED AST TRAP. THE ; TCB OF THE SPECIFIED TASK IS EXAMINED TO DETERMINE IF THE SPECIFIED ; AST IS ENABLED (SETUP). IF IT IS THEN THE AST IS DECLARED. ; ; INPUTS: ; ; R3=COMMAND BUFFER ADDRESS IF AST TYPE IS AS.CAA ; MF208 ; R4=AST TYPE ; R5=ADDRESS OF THE TCB OF THE TASK TO DECLARE THE AST FOR. ; ; OUTPUTS: ; ; C=1 IF THE TASK IS NOT SETUP FOR THE SPECIFIED AST. ; C=0 IF THE TASK IS SETUP FOR THE AST AND THE AST HAS BEEN DECLARED. ; R1=ADDRESS OF THE AST CONTROL BLOCK. ; ;- .IF DF A$$TRP!F$$LPP!P$$RFL!R$$SND!P$$SRF!A$$BRT ;MSH121 ;**-1 .ENABL LSB $DASTT::CALL $SRAST ;SEARCH FOR SPECIFIED AST BLOCK BCS 10$ ;IF CS, THERE IS NONE ; MF208 ; MF208 .IF DF A$$CLI&A$$TRP ; MF208 ; MF208 CMP A.CBL(R0),# ;DECLARING CMD ARRIVAL AST ; MF208 BNE 1$ ;IF NE NO ; MF208 MOV R1,-(SP) ;SAVE POINTER TO AST BLOCK ADDRESS ; MF208 MOV #C.LGTH,R1 ;GET LENGTH OF AN AST BLOCK ; MF208 CALL $ALOCB ;ALLOCATE ONE FROM THE POOL ; MF208 MOV (SP)+,R4 ;RESTORE POINTER TO AST BLOCK ADDRESS ; MF208 MOV (R4),R1 ;GET ADDRESS OF EXISTING AST BLOCK ; MF208 BCC 105$ ;IF CC, SUCCESSFUL ALLOCATION ; MF208 MOV SP,A.PRM+2(R1) ;NON-ZERO TO FORCE SYSXT TO RELINK ; MF208 MOV (R1),(R4) ;REMOVE AST BLOCK FROM LIST ; MF208 BR 107$ ; ; MF208 105$: MOV R1,R4 ;COPY POINTER TO OLD BLOCK ; MF208 MOV R0,R1 ;COPY NEW AST BLOCK ADDR ; MF208 CMP (R4)+,(R0)+ ;SKIP LINK WORDS ; MF208 MOV (R4)+,(R0)+ ;COPY A.CBL ; MF208 MOV (R4)+,(R0)+ ;COPY A.BYT ; MF208 MOV (R4)+,(R0)+ ;COPY A.AST ; MF208 MOV (R4)+,(R0)+ ;COPY A.NPR ; MF208 CLR A.PRM+2(R1) ;ZERO TO FORCE SYSXT TO DEALLOCATE ; MF208 107$: MOV R3,A.PRM(R1) ;SET COMMAND ADDRESS IN AST BLOCK ; MF208 MOV R5,R0 ;SET TCB ADDRESS OF CLI ; MF208 BR $QASTT ;QUEUE AST ; MF208 1$: ; MF208 ; MF208 .ENDC ;A$$CLI&A$$TRP ; MF208 ; MF208 ;MSH121 .IF DF A$$TRP&A$$BRT ;MSH121 ;MSH121 CMP A.CBL(R0),# ;DECLARING ABORT AST? ;MSH121 BNE 2$ ;IF NE NO ;MSH121 BIS #T2.REX,T.ST2(R5) ;SET ABORT AST IN PROGRESS ;MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 2$: MOV (R0),(R1) ;REMOVE CONTROL BLOCK FROM THE LIST ;MSH121 MOV R0,R1 ;SAVE ADDRESS OF THE AST CONTROL BLOCK ;**-1 MOV R5,R0 ;COPY TCB ADDRESS .IF DF C$$INT&A$$TRP BR $QASTT ;GO QUEUE THE AST ;+ ; **-$DQAC-DEQUEUE AST BLOCK QUEUED BY $QASTC. ; (TO BE CALLED FROM SYSXT ONLY). ; ; INPUT: ; R0 POINTER TO AST BLOCK ; ; OUTPUT: ; A.CBL SET TO 1 TO INDICATE AST BLOCK FREE ; (NOT IN AST QUEUE). ; ; REGISTERS ALTERED: NONE ;- $DQAC:: INC A.CBL(R0) ; SET AST BLOCK FREE RETURN ;+ ; **-$QASTC-QUEUE AST TO TASK. ; ; THIS IS A VARIANT OF $QASTT TO BE USED BY A TASK ISR, ENTERED ; VIA A VECTOR CONNECTED TO VIA THE CINT$ DIRECTIVE. ; ; INPUT: ; R5 POINTER TO FORK BLOCK IN ITB ; ; OUTPUT: ; CC-C 0 IF OK, 1 IF AST ADDRESS NOT SPECIFIED IN CINT$ CALL. ; ; NOTE - IF THE AST BLOCK IS ALREADY QUEUED FOR THE TASK, ; NO ACTION IS TAKEN. RETURN CC-C = 0. ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- $QASTC::MOV R5,R1 ADD #X.AST-X.FORK,R1 ;GET AST BLOCK TST A.CBL(R1) ;AST BLOCK ALREADY IN AST QUEUE? BEQ 10$ ;Y - EXIT WITH CC-C = 0 TST A.AST(R1) ;AST ADDRESS SPECIFIED? SEC ;ASSUME NO BEQ 10$ ;N - EXIT WITH CC-C = 1 CLR A.CBL(R1) ;INDICATE AST BLOCK IN USE MOV X.TCB-X.FORK(R5),R0 ;GET TCB ADDRESS ;FALL THRU TO $QASTT .ENDC ;C$$INT&A$$TRP ;+ ; **-$QASTT-QUEUE AST TO TASK ; ; THIS ROUTINE IS USED TO QUEUE AN AST TO A TASK AND INSURE THE TASK ; WILL BE SCHEDULED AND RECONSIDERED FOR ELIGIBILITY IN THE PARTITION. ; ; INPUTS: ; ; R0=TCB ADDRESS OF TASK TO RECEIVE AST ; R1=ADDRESS OF AST CONTROL BLOCK TO BE USED ; ; OUTPUTS: ; ; C=0 ; R1 IS PRESERVED ;- $QASTT::ADD #T.ASTL,R0 ;POINT TO TASK AST LISTHEAD MOV R1,-(SP) ;SAVE ADDRESS OF AST CONTROL BLOCK CALL $QINSF ;INSERT CONTROL BLOCK IN AST QUEUE SUB #T.ASTL,R0 ;POINT BACK TO TCB ADDRESS CALL $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST .IF DF D$$ISK&C$$CKP BIT #T2.STP,T.ST2(R0) ;IS TASK STOPPED? BEQ 5$ ;IF EQ NO MOV T.PCB(R0),R0 ;POINT TO TASK PCB CALL $NXTSK ;REALLOCATE TASK PARTITION .ENDC 5$: MOV (SP)+,R1 ;RESTORE AST CONTROL BLOCK ADDRESS CLC ;RETURN CARRY CLEAR 10$: RETURN ; .DSABL LSB ;+ ; **-$SRAST-SEARCH SPECIFIED AST QUEUE FOR SPECIFIED AST BLOCK ;MSH205 ; **-$SASTQ-SEARCH QUEUE FOR SPECIFIED AST BLOCK ;MSH205 ; ;**-1 ; THIS ROUTINE IS CALLED TO SEARCH FOR A SPECIFIED TYPE OF AST CONTROL ; BLOCK ON THE REQUESTED QUEUE. ;MSH205 ; ;**-1 ; INPUTS: ; ; R0=POSITION IN QUEUE TO SEARCH FROM (IF CALLED AT $SASTQ ONLY) ;MSH205 ; R4=CODE INDICATING TYPE OF BLOCK TO BE SEARCHED FOR ; R5=TCB ADDRESS OF TASK WHOSE SAST LIST IS TO BE SEARCHED ; ; OUTPUTS: ; ; C=1 IF SPECIFED TYPE OF AST BLOCK NOT FOUND ; C=0 IF SPECIFIED TYPE OF AST BLOCK IS FOUND ; R0=ADDRESS OF THE BLOCK ; R1=ADDRESS OF WORD POINTING TO THE BLOCK ;- .IFTF ;MSH121 ;MSH121 $SRAST:: ;DEFINE FOR MCR ;MSH121 ;MSH121 .IFT ;MSH121 ;MSH121 MOV R5,R0 ;GET TCB ADDRESS ;MSH121 ADD #T.SAST,R0 ;POINT TO SPECIFIED AST BLOCK ADDRESS ;**-1 ;MSH205 .IFTF ;MSH205 ;MSH205 $SASTQ:: ;DEFINE FOR MCR ;MSH205 ;MSH205 .IFT ;MSH205 ;MSH205 SEC ;ASSUME FAILURE ;MSH205 MOV R0,R1  ;GET POINTER TO NEXT BLOCK ;**-1 MOV (R0),R0 ;GET LINK WORD BEQ 20$ ;IF EQ, END OF LIST CMPB R4,A.CBL+1(R0) ;IS THIS THE BLOCK OF THE SPECIFIED TYPE BNE $SASTQ ;IF NE NO, CONTINUE SEARCH ;MSH205 20$: RETURN ;**-1 .ENDC ;+ ; **-$SRSTD-SEARCH SYSTEM TASK DIRECTORY ; ; THIS ROUTINE IS CALLED TO SEARCH THE TASK DIRECTORY FOR A TASK OF THE ; SPECIFIED NAME. ; ; INPUTS: ; ; R3=ADDRESS OF THE TASK NAME TO SEARCH FOR. ; ; OUTPUTS: ; ; C=1 IF SPECIFIED TASK IS NOT FOUND. ; C=0 IF SPECIFIED TASK IS FOUND. ; R0=ADDRESS OF THE TCB. ; ; R1,R2, AND R3 ARE PRESERVED ACROSS CALL. ;- .ENABL LSB $SRSTD:: ; MF203 ; MF203 ; MF203 .IF DF A$$CLI!P$$OFF ; MF203 ; MF203 CMP #^RCLI,(R3) ;SEARCHING FOR CLI... ; MF203 BNE 5$ ;IF NE NO ; MF203 CMP #^R...,2(R3) ;MAY HAVE IT ; MF203 BNE 5$ ;IF NE NO ; MF203 MOV $MCRPT,R0 ;TCB FOR MCR... IS DESIRED ; MF203 RETURN ; MF203 ; MF203 .ENDC ;A$$CLI!P$$OFF ; MF203 ; MF203 ; MF203 5$: MOV $TSKHD,R0 ;POINT TO START OF TASK LIST ; MF203 10$: CMP T.NAM(R0),(R3) ;FIRST HALF OF NAME MATCH? ;**-1 BNE 20$ ;IF NE NO CMP T.NAM+2(R0),2(R3) ;SECOND HALF OF NAME MATCH? BEQ 30$ ;IF EQ YES 20$: MOV T.TCBL(R0),R0 ;GET LINK TO NEXT TCB TST T.TCBL(R0) ;NULL TASK? BNE 10$ ;IF NE NO 25$: SEC ;INDICATE FAILURE 30$: RETURN ; ;+ ; **-$ACTRM-REMOVE TASK FROM THE ACTIVE TASK LIST ; ; THIS ROUTINE IS CALLED TO REMOVE A TCB FROM THE ACTIVE TASK LIST. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB TO REMOVE. ; ; OUTPUTS: ; ; C=1 IF THERE IS NO ENTRY IN THE LIST THAT MATCHES THE TCB ADDRES ; C=0 IF A MATCHING ENTRY IS REMOVED FROM THE LIST. ; ; R0 IS PRESERVED ACROSS THE CALL. ; ;- $ACTRM::MOV #$ACTHD-T.ACTL,R1 ;GET ADDR OF LISTHEAD 40$: MOV R1,R2 ;SAVE PREVIOUS TCB ADDR MOV T.ACTL(R2),R1 ;GET NEXT TCB ADDR BEQ 25$ ;IF EQ END OF LIST FOUND CMP R0,R1 ;DOES NEXT TCB ADDR EQ OURS? BNE 40$ ;IF NE NO -- KEEP LOOKING MOV T.ACTL(R0),T.ACTL(R2) ;REMOVE ENTRY RETURN ;EXIT .DSABL LSB ;**-45 ;+ ; **-$DRTHR/$ERTHR-DIRECTIVE ERROR AND GENERAL ERROR THREADING ROUTINES ; ; THESE ROUTINES ARE USED IN CONJUNCTION WITH THE FOLLOWING ERROR ; RECOVERY ROUTINE TO DYNAMICALLY THREAD ERROR RECOVERY INFORMATION ; ONTO THE STACK. AFTER INITIALIZATION, THE INTERFACE IS VIA A ; COROUTINE CALL (CALL @(SP)+) FOLLOWED BY TWO ROUTINE ADDRESSES. ; THE FIRST ROUTINE IS CALLED AND THEN THE SECOND ROUTINE ADDRESS IS ; PUSHED ONTO THE STACK ALONG WITH THE CONTENTS OF R0 AND R1. IT IS ; INTENDED THAT THE SECOND ROUTINE, ALONG WITH THE SAVED CONTENTS OF ; R0 AND R1, CAN UNDO THE ACTION OF THE FIRST ROUTINE IF AN ERROR ; CONDITION IS ENCOUNTERED LATER. ANOTHER POSSIBILITY IS THAT THE FIRST ; ROUTINE IS NULL, AND THE SECOND ROUTINE CAN UNDO SOME PREVIOUS ACTION. ; $DRTHR MAY BE CALLED WHEN THE FINAL DESIRED ACTION ON ERROR WILL BE ; TO RETURN A DIRECTIVE STATUS PASSED IN R5 (IN THE FORM 'DRSTS D.RSX'). ; $ERTHR IS A GENERAL ERROR RECOVERY THREADING ROUTINE. EXAMPLE USES OF ; THESE ROUTINES MAY BE FOUND IN THE MODULE DRSPW. ; ; INPUTS: ; ; AS REQUIRED FOR CALL TO FIRST ROUTINE. ; ; OUTPUTS: ; ; C-BIT AND R0-R3 ARE PRESERVED FROM RETURN OF FIRST ROUTINE. ; R4 IS DESTROYED. ;- .IF DF P$$OFF .ENABL LSB $DRTHR::MOV (SP),R4 ;PICK UP RETURN PC MOV #10$,(SP) ;SET ADDRESS OF ROUTINE TO RETURN STATUS CMP -(SP),-(SP) ;ALLOCATE WORDS FOR R0 AND R1 MOV R4,-(SP) ;RESTORE RETURN PC ADDRESS $ERTHR::MOV (SP),R4 ;PICK UP RETURN PC CALL @(R4)+ ;CALL THE FIRST ROUTINE ADDRESS MOV (R4)+,(SP) ;SAVE THE RECOVERY ROUTINE ADDRESS MOV R1,-(SP) ;SAVE CURRENT CONTENTS OF R1 MOV R0,-(SP) ;SAVE CURRENT CONTENTS OF R0 CALL (R4) ;CALL THE CALLER BACK BR $ERTHR ;DO IT AGAIN 10$: MOV R5,-(SP) ;PUSH DIRECTIVE STATUS TRAP INSTRUCTION JMP (SP) ;EXECUTE TRAP .DSABL LSB ;+ ; **-$ERREC-ERROR RECOVERY ROUTINE ; ; THIS ROUTINE IS USED IN CONJUNCTION WITH THE ABOVE ROUTINES TO ; EFFECT A SERIES OF SUBROUTINE CALLS STORED ON THE STACK FOR ERROR ; RECOVERY. THE NORMAL CALLING SEQUENCE IS VIA A JUMP. SUCCESSIVE ; R0 AND R1 CONTENTS ARE POPPED FROM THE STACK WITH CALLS TO THE ; SAVED ROUTINE ADDRESSES. THE LAST ROUTINE ON THE STACK MUST FORCE ; THE PROCESS TO STOP. ; ; INPUTS: ; ; R5=DIRECTIVE STATUS (IF INITIALIZED BY $DRTHR). ; ; OUTPUTS: ; ; NONE. ;- $ERREC::TST (SP)+ ;POP COROUTINE ADDRESS 10$: MOV (SP)+,R0 ;PICK UP SAVED R0 MOV (SP)+,R1 ;PICK UP SAVED R1 CALL @(SP)+ ;CALL THE RECOVERY ROUTINE BR 10$ ; ;+ ; **-$QUEXT-QUEUE EXIT "AST" BLOCK ; ; THIS ROUTINE FILLS IN THE STATUS IN AN OFFSPRING CONTROL BLOCK, ; AND QUEUES IT AS A SPECIAL AST BLOCK TO THE PARENT TASK TCB. ; ; INPUTS: ; ; R0=EXIT STATUS WORD. ; R1=OCB ADDRESS. ; R2=SECONDARY EXIT STATUS CODE (BYTE) ;MSH129 ; ; OUTPUTS: ; ; R3 IS PRESERVED. ;- .IFTF ;P$$OFF $QUEXT:: ;ALWAYS DEFINE FOR MCR .IFT ;P$$OFF MOV R2,-(SP) ;SAVE SECONDARY EXIT STATUS CODE ;MSH129 MOV O.PTCB(R1),R2 ;PICK UP PARENT TCB ADDRESS BEQ 30$ ;IF EQ PARENT HAS EXITTED DEC T.RDCT(R2) ;DECREMENT RUNDOWN COUNT MOV T.ASTL(R2),(R1) ;LINK OCB TO FRONT OF AST LIST BNE 10$ ; MOV R1,T.ASTL+2(R2) ; 10$: MOV R1,T.ASTL(R2) ; MOV #AK.OCB,A.CBL(R1) ;SET EXIT "AST" KERNEL AST TYPE ;MSH091 MOV R0,O.STAT(R1) ;SET EXIT STATUS ;**-1 MOV (SP)+,O.STAT+2(R1) ;STORE SECONDARY EXIT STATUS CODE ;MSH129 MOV R2,R0 ;COPY PARENT TCB POINTER .IF DF D$$ISK&C$$CKP CALL $SETCR ;SET CONDITIONAL SCHEDULE REQUEST MOV T.PCB(R0),R0 ;POINT TO PARENT PCB CALLR $NXTSK ;REALLOCATE (AST ENTRY CAN UNSTOP) .IFF ;D$$ISK&C$$CKP CALLR $SETCR ;SET CONDITIONAL SCHEDULE REQUEST .ENDC ;D$$ISK&C$$CKP 30$: MOV R1,R0 ;COPY OCB POINTER TO DEALLOCATE TST (SP)+ ;CLEAN STACK ;MSH129 MOV #O.LGTH,R1 ;SET LENGTH TO DEALLOCATE CALLR $DEACB ;DEALLOCATE OCB .ENDC ;P$$OFF ;+ ; **-$STPCT-STOP CURRENT TASK ; **-$STPTK-STOP TASK ; ; THESE ROUTINES ARE CALLED TO STOP A TASK AND REALLOCATE THE TASK'S ; PARTITION. ; ; INPUTS: ; ; R0=TCB ADDRESS OF TASK TO STOP (IF ENTRY AT $STPTK) ; ; OUTPUTS: ; ; NONE ;- $STPCT::MOV $TKTCB,R0 ;PICK UP ADDRESS OF CURRENT TASK TCB $STPTK::BIS #T2.STP,T.ST2(R0) ;SET STOP BIT IN TASK'S TCB .IF DF D$$ISK CALL $SETCR ;INSURE THAT TASK WILL STOP MOV T.PCB(R0),R0 ;POINT TO TASK PCB BR $NXTSK ;REALLOCATE TASK PARTITION .IFF CALLR $SETCR ;INSURE THAT TASK WILL STOP .IFT ;+ ; **-$RLPAR-RELEASE TASK PARTITION ; **-$RLPR1-RELEASE PARTITION ; ; THIS ROUTINE IS CALLED TO RELEASE A PARTITION OWNED BY A TASK AND TO ; ASSIGN THE PARTITION TO THE NEXT HIGHEST PRIORITY TASK WAITING TO ; OCCUPY THE PARTITION. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE OWNER TASK (IF ENTRY AT $RLPAR) ; R1=ADDR OF SUBPARTITION PCB TO RELEASE (IF ENTRY AT $RLPR1) ; R3=ADDRESS OF MAIN PARTITION PCB (IF ENTRY AT $RLPR1) ; ; OUTPUTS: ; ; THE PARTITION IS RELEASED AND ASSIGNED TO THE NEXT HIGHEST ; PRIORITY TASK WAITING TO OCCUPY THE PARTITION. ;- $RLPAR::MOV T.PCB(R0),R1 ;GET ADDRESS OF PARTITION PCB MOV P.MAIN(R1),R0 ;GET MAIN PCB ADDRESS MOV R0,R3 ;COPY MAIN PCB ADDRESS .IF DF D$$YNM&M$$MGE BIT #PS.SYS,P.STAT(R0) ;SYSTEM CONTROLLED PARTITION? BEQ $RLPR1 ;IF EQ NO 10$: MOV R0,R2 ;SAVE ADDRESS OF PREVIOUS PCB MOV P.SUB(R2),R0 ;GET ADDRESS OF NEXT PCB CMP R0,R1 ;TASK PCB? BNE 10$ ;IF NE NO MOV P.SUB(R0),P.SUB(R2) ;REMOVE PCB FROM LIST .ENDC $RLPR1::ADD #P.BUSY,R1 ;POINT TO BUSY FLAG BICB (R1)+,(R1) ;CLEAR SUBPARTITION BUSY  BICB -(R1),P.BUSY+1(R3) ;CLEAR MAIN PARTITION BUSY ;+ ; **-$NXTSK-ASSIGN NEXT TASK TO PARTITION ; ; THIS ROUTINE IS CALLED TO ASSIGN A PARTITION TO THE HIGHEST PRIORITY ; TASK WAITING TO OCCUPY THE PARTITION. A TASK IS CONSIDERED ELIGIBLE ;MSH168 ; TO BE ASSIGNED A PARTITION IF IT IS NOT STOPPED OR EXTERNALLY ;MSH168 ; BLOCKED, IT IS STOPPED BUT HAS A PENDING AST, OR IT IS NOT WAITING ;MSH168 ; FOR A PARTITION AS A RESULT OF A PREVIOUS CHECKPOINT OPERATION AND ;MSH168 ; THE LOW POOL FLAG CONTROLLING TASK REQUESTS IS NOT SET. ;MSH168 ; ;**-1 ; INPUTS: ; ; R0=ADDRESS OF THE PCB OF THE PARTITION TO ASSIGN. ; ; OUTPUTS: ; ; FOR TASK-CONTROLLED PARTITIONS, THERE ARE FIVE POSSIBLE OUTPUTS:;MSH168 ; ;**-1 ; 1-THE PARTITION IS NOT CURRENTLY BUSY AND A TASK IS WAITING TO ; OCCUPY THE PARTITION. THE PARTITION IS ASSIGNED TO THE ; WAITING TASK AND A REQUEST IS PLACED IN THE LOADER ; QUEUE TO LOAD THE TASK. ; ; 2-THE PARTITION IS CURRENTLY OCCUPIED BY A TASK THAT IS EITHER OF ; HIGHER PRIORITY THAN ALL WAITING TASKS OR IS NOT CHECK- ;MSH168 ; POINTABLE. THE PARTITION CANNOT BE ASSIGNED TO ANOTHER ;**-1 ; TASK. ; ; 3-THE PARTITION IS CURRENTLY OCCUPIED BY A LOWER PRIORITY CHECK- ; POINTABLE TASK. A REQUEST IS PLACED IN THE LOADER QUEUE ; TO CHECKPOINT THE OWNER TASK. ; ; 4-THE HIGHEST PRIORITY TASK WAITING TO OCCUPY THE PARTITION ; REQUIRES THE MAIN PARTITION WHICH IS CURRENTLY ;MSH168 ; OCCUPIED BY ONE OR MORE TASKS THAT ARE EITHER OF ;MSH168 ; HIGHER PRIORITY OR ARE NOT CHECKPOINTABLE. THE PARTITION;**-2 ; CANNOT BE ASSIGNED. ; ; 5-THE HIGHEST PRIORITY TASK WAITING TO OCCUPY THE PARTITION ; REQUIRES THE MAIN PARTITION WHICH IS CURRENTLY ; OCCUPIED BY ONE OR MORE TASKS OF LOWER PRIORITY ; THAT ARE CHECKPOINTABLE. A REQUEST IS PLACED IN THE ; LOADER QUEUE TO CHECKPOINT EACH TASK. ; ;MSH168 ; FOR SYSTEM-CONTROLLED PARTITIONS, THERE ARE THREE POSSIBLE OUTPU;MSH168 ; ;MSH168 ; 1-THERE IS ENOUGH CONTIGUOUS UNALLOCATED SPACE IN THE PARTITION ;MSH168 ; IN WHICH TO FIT THE WAITING TASK. THE REQUIRED MEMORY ;MSH168 ; SPACE IS ALLOCATED FOR THE TASK AND A REQUEST IS PLACED ;MSH168 ; IN THE LOADER QUEUE TO LOAD THE TASK. ;MSH168 ; ;MSH168 ; 2-THERE IS NOT ENOUGH CONTIGUOUS UNALLOCATED SPACE IN THE ;MSH168 ; PARTITION TO ALLOCATE FOR THE WAITING TASK, BUT A ;MSH168 ; BLOCK OF MEMORY WITHIN THE PARTITION OCCUPIED BY ONE ;MSH168 ; OR MORE CHECKPOINTABLE TASKS OF LOWER PRIORITY EXISTS ;MSH168 ; THAT IS SUFFICIENTLY LARGE TO MAKE ROOM FOR THE ;MSH168 ; WAITING TASK. A REQUEST IS PLACED IN THE LOADER QUEUE ;MSH168 ; FOR EACH TASK OCCUPYING THAT BLOCK TO BE CHECKPOINTED. ;MSH168 ; ;MSH168 ; 3-THERE IS NOT ENOUGH CONTIGUOUS UNALLOCATED SPACE IN THE ;MSH168 ; PARTITION TO ALLOCATE FOR THE WAITING TASK AND THERE ;MSH168 ; IS NO SUFFICIENTLY LARGE BLOCK OF MEMORY WITHIN THE ;MSH168 ; PARTITION CONTAINING CHECKPOINTABLE TASKS OF LOWER ;MSH168 ; PRIORITY TO MAKE ROOM FOR THE WAITING TASK. THE ;MSH168 ;  MEMORY SHUFFLER IS REQUESTED TO RUN IN AN ATTEMPT ;MSH168 ; TO COMPACT THE PARTITIONS'S CONTENTS. ;MSH168 ;- $NXTSK::SAVNR ;SAVE R4 AND R5 MOV P.MAIN(R0),R5 ;GET MAIN PARTITION PCB ADDRESS 10$: MOV P.WAIT(R5),R4 ;GET 1ST TCB IN WAIT LIST 20$: BEQ 100$ ;IF EQ END OF LIST ;MSH142 .IF DF P$$CTL ;MSH142 ;MSH142 TSTB $POLFL ;LOW POOL CONTROL IN EFFECT? (PF.REQ) ;MSH142 BPL 204$ ;IF PL NO ;MSH142 TSTB T.STAT(R4) ;INITIAL TASK REQUEST? (TS.CKP) ;MSH142 BMI 204$ ;IF MI NO, TASK CHECKPOINTED ;MSH142 BIT #T3.PRV,T.ST3(R4) ;PRIVILEGED TASK REQUEST? ;MSH142 BNE 204$ ;IF NE YES ;MSH142 BIT #T2.ABO!T2.REX,T.ST2(R4) ;TASK BEING ABORTED? ;MSH142 BNE 204$ ;IF NE YES, ELIGIBLE FOR MEMORY ;MSH142 CMPB T.PRI(R4),$POLBP ;TASK OF MINIMUM PRIORITY? ;MSH142 BLO 40$ ;IF LO NO, SKIP THIS TASK ;MSH142 ;MSH142 .ENDC ;MSH142 ;MSH142 204$: BIT #TS.STP,T.STAT(R4) ;TASK BLOCKED FROM EXECUTION? ;MSH122 BNE 40$ ;IF NE YES, SKIP IT ;MSH122 BIT #T2.STP,T.ST2(R4) ;TASK STOPPED? .IF DF A$$TRP BEQ 21$ ;IF EQ NO TST T.ASTL(R4) ;DOES TASK HAVE PENDING AST? BEQ 40$ ;IF EQ NO 21$: ;REF LABEL .IFF BNE 40$ ;IF NE YES .ENDC .IF DF D$$YNM&M$$MGE BIT #PS.SYS,P.STAT(R5) ;SYSTEM CONTROLLED PARTITION? BNE 110$ ;IF NE YES .ENDC TSTB P.BUSY+1(R5) ;MAIN PARTITION OCCUPIED? BMI 50$ ;IF MI YES MOV T.PCB(R4),R2 ;GET REQUESTED PARTITION PCB ADDRESS TSTB P.BUSY+1(R2) ;REQUESTED PARTITION BUSY? BNE 30$ ;IF NE YES 25$: MOV R5,R0 ;COPY MAIN PARTITION PCB ADDRESS ADD #P.WAIT,R0 ;CALCULATE PCB LISTHEAD ADDRESS MOV R4,R1 ;COPY TCB ADDRESS CALL $QRMVT ;REMOVE TCB FROM LIST MOV T.PCB(R4),R0 ;GET PCB ADDRESS MOV R4,P.TCB(R0) ;PUT TCB ADDRESS IN PCB ADD #P.BUSY,R0 ;POINT TO BUSY FLAG BISB (R0)+,(R0) ;SET SUBPARTITION BUSY BISB -(R0),P.BUSY+1(R5) ;SET MAIN PARTITION BUSY CALL $LOADT ;PUT TASK IN LOADER QUEUE BR 10$ ;GO AGAIN 30$: ;REF LABEL .IF DF C$$CKP TSTB P.BUSY(R2) ;MAIN PARTITION REQUESTED BMI 50$ ;IF MI YES MOV P.TCB(R2),R1 ;GET OWNER TASK TCB ADDRESS CALL $TSTCP ;SHOULD TASK BE CHECKPOINTED? BCS 40$ ;IF CS NO CALL $ICHKP ;INITIATE CHECKPOINT .IFTF 40$: MOV (R4),R4 ;POINT TO NEXT TCB BR 20$ ; .IFT 50$: MOV R5,R0 ;COPY MAIN PCB ADDRESS 60$: BITB P.BUSY(R0),P.BUSY+1(R0) ;IS THIS PARTITION BUSY? BEQ 70$ ;IF EQ NO MOV P.TCB(R0),R1 ;GET OWNER TCB ADDRESS CALL $TSTCP ;SHOULD TASK BE CHECKPOINTED? BCS 100$ ;IF CS NO 70$: MOV P.SUB(R0),R0 ;GET NEXT PARTITION PCB ADDRESS BNE 60$ ;IF NE MORE TO GO 80$: BITB P.BUSY(R5),P.BUSY+1(R5) ;IS THIS PARTITION BUSY? BEQ 90$ ;IF EQ NO MOV P.TCB(R5),R1 ;GET OWNER TCB ADDRESS CALL $ICHKP ;INITIATE CHECKPOINT 90$: MOV P.SUB(R5),R5 ;GET NEXT SUBPARTITION PCB BNE 80$ ;IF NE MORE TO GO .IFF 50$: ;REF LABEL .IFTF 100$: RETURN ;EXIT ; ;MSH168 ; THE FOLLOWING STEPS ARE TAKEN TO ASSIGN A PIECE OF THE SYSTEM ;MSH168 ; CONTROLLED PARTITION TO THE WAITING TASK: ;MSH168 ; ;MSH168 ; 1-TRY TO FIND ENOUGH FREE SPACE TO ALLOCATE FOR THE TASK. ;MSH168 ; ;MSH168 ; 2A-TRY TO FIND A BLOCK OF MEMORY WITHIN THE PARTITION ;MSH168 ; CONTAINING CHECKPOINTABLE TASKS OF LOWER PRIORITY ;MSH168 ; WITHOUT OUTSTANDING I/O THAT IS SUFFICIENTLY LARGE ;MSH168 ; TO MAKE ROOM FOR THE WAITING TASK. ;MSH168 ; ;MSH168 ; 2B-TRY TO FIND A BLOCK OF MEMORY WITHIN THE PARTITION ;MSH168 ; CONTAINING CHECKPOINTABLE TASKS OF LOWER PRIORITY ;MSH168 ; THAT IS SUFFICIENTLY LARGE TO MAKE ROOM FOR THE ;MSH168 ; WAITING TASK. ;MSH168 ; ;MSH168 ; 3-INVOKE THE MEMORY SHUFFLER TO COMPACT THE CONTENTS OF THE ;MSH168 ; SYSTEM-CONTROLLED PARTITION. ;MSH168 ; ;MSH168 .IF DF D$$YNM&M$$MGE 110$: MOV T.PCB(R4),R4 ;POINT TO TASK PCB CALL $FNDSP ;ATTEMPT TO FIND SPACE IN PARTITION MOV P.SIZE(R4),R0 ;SAVE SIZE OF PARTITION MOV P.TCB(R4),R4 ;RESTORE TCB ADDRESS BCC 25$ ;IF CC SPACE WAS FOUND .IF DF C$$CKP  MOV P.REL(R5),R3 ;SET BASE ADDRESS OF FIRST HOLE ;MSH168 MOV R5,R2 ;SET ADDRESS OF PREVIOUS PCB ;**-1 MOV #$TCPIO,-(SP) ;FIRST SCAN, I/O IS BLOCKING FACTOR ;MSH168 CALL 160$ ;TRY TO ALLOCATE SOME SPACE ;MSH168 MOV P.MAIN(R5),R5 ;POINT TO MAIN PCB ;MSH168 MOV P.REL(R5),R3 ;SET BASE ADDRESS OF FIRST HOLE ;MSH168 MOV R5,R2 ;SET ADDRESS OF PREVIOUS PCB ;MSH168 MOV #$TSTCP,(SP) ;SECOND SCAN, IGNORE I/O COUNTS ;MSH168 CALL 160$ ;TRY TO ALLOCATE SOME SPACE AGAIN ;MSH168 TST (SP)+ ;CLEAN STACK - ALLOCATION FAILURE ;MSH168 ;MSH168 .IF DF D$$SHF ;MSH168 ;MSH168 TST $SHFTM ;TOO SOON TO REQUEST SHUFFLER ;MSH184 BNE 210$ ;IF NE YES, FORGET IT FOR NOW ;MSH184 MOV $SHFPT,R0 ;GET MEMORY SHUFFLER TCB ADDRESS ;MSH168 BEQ 210$ ;IF EQ SHUFFLER NOT INSTALLED ;MSH168 CALLR $EXRQC ;REQUEST SHUFFLER TO RUN ;MSH168 ;MSH168 .IFF ;MSH168 ;MSH168 RETURN ; ;MSH168 ;MSH168 .ENDC ;MSH168 ;MSH168  160$: MOV P.SUB(R2),R2 ;GET ADDRESS OF NEXT PCB BEQ 210$ ;IF EQ ALLOCATION FAILURE .IF DF L$$DRV!P$$LAS BIT #PS.DRV!PS.COM,P.STAT(R2) ;DRIVER OR COMMON PARTITION? BNE 165$ ;IF NE YES .ENDC MOV P.TCB(R2),R1 ;GET TCB ADDRESS OF OWNER TASK CALL @2(SP) ;CAN TASK BE CHECKPOINTED? ;MSH168 BCC 170$ ;IF CC YES ;**-1 165$: MOV R2,R5 ;SAVE ADDRESS OF PREVIOUS PCB MOV P.REL(R5),R3 ;CALCULATE NEW HOLE BASE ADDRESS ADD P.SIZE(R5),R3 ; BR 160$ ; 170$: CLR -(SP) ;INITIALIZE TOP OF HOLE MOV P.SUB(R2),R1 ;GET ADDRESS OF NEXT PCB BNE 180$ ;IF NE ONE EXISTS MOV P.MAIN(R2),R1 ;RETRIEVE ADDRESS OF MAIN PCB ADD P.SIZE(R1),(SP) ;CALCULATE ADDRESS OF TOP OF HOLE 180$: ADD P.REL(R1),(SP) ; SUB R3,(SP) ;CALCULATE SIZE OF HOLE ;MSH168 CMP (SP)+,R0 ;HOLE BIG ENOUGH? ;**-1 BLO 160$ ;IF LO NO MOV R2,R4 ;SAVE ADDRESS OF LAST PCB 200$: MOV P.SUB(R5),R5 ;GET ADDRESS OF NEXT PCB MOV P.TCB(R5),R1 ;GET ADDRESS OF TASK TCB CALL $ICHKP ;INITIATE CHECKPOINT CMP R4,R5  ;LAST PCB TO EXAMINE? BNE 200$ ;IF NE NO CMP (SP)+,(SP)+ ;CLEAN STACK ;MSH168 ;MSH168 .ENDC ;C$$CKP ;MSH168 ;MSH168 210$: RETURN ; ;MSH168 ;**-22 .ENDC ;+ ; **-$FNDSP-FIND SPACE IN PCB LIST ; ; THIS ROUTINE IS CALLED TO FIND SPACE WITHIN A DYNAMICALLY ALLOCATED ; PCB LIST REPRESENTING THE ALLOCATION STATE OF A SYSTEM CONTROLLED ; PARTITION OR DYNAMIC CHECKPOINT FILE. ; ; INPUTS: ; ; R4=ADDRESS OF PCB TO FIND SPACE FOR ; R5=ADDRESS OF MAIN PCB FOR SPACE IN WHICH TO ALLOCATE ; ; OUTPUTS: ; ; C=0 IF ALLOCATION WAS SUCCESSFUL ; SUB PCB IS LINKED INTO ALLOCATION LIST ; C=1 IF ALLOCATION FAILURE ; ; R0,R1,R2 ARE MODIFIED. ;- ;EF012 .ENDC ;C$$CKP ;EF012 ;EF012 .IFTF ;D$$ISK ;EF012 ;EF012 .IF DF D$$YNM&M$$MGE!D$$YNC $FNDSP::MOV R5,R0 ;COPY ADDRESS OF MAIN PCB MOV P.REL(R5),R2 ;SET HIGHEST ADDRESS IN LAST PARTITION 10$: MOV P.SUB(R0),R1 ;GET ADDRESS OF NEXT PCB BEQ 20$ ;IF EQ END OF LIST MOV P.REL(R1),-(SP) ;CALCULATE SIZE OF HOLE SUB R2,(SP) ; CMP (SP)+,P.SIZE(R4) ;HOLE BIG ENOUGH? BHIS 30$ ;IF HIS YES MOV R1,R0 ;SAVE ADDRESS OF PREVIOUS PCB MOV P.REL(R1),R2 ;CALCULATE BASE ADDRESS OF NEXT HOLE ADD P.SIZE(R1),R2 ; BR 10$ ; 20$: MOV P.REL(R5),-(SP) ;CALCULATE SIZE OF LAST HOLE ADD P.SIZE(R5),(SP) ; SUB R2,(SP) ; CMP (SP)+,P.SIZE(R4) ;HOLE BIG ENOUGH? BLO 40$ ;IF LO NO 30$: MOV R2,P.REL(R4) ;SET ADDRESS OF TASK PARTITION MOV R4,P.SUB(R0) ;LINK ALLOCATED PARTITION TO PREVIOUS MOV R1,P.SUB(R4) ;LINK NEXT TO TASK PCB 40$: RETURN ; .ENDC .IFT ;D$$ISK ;EF012 ;EF012 .IF DF C$$CKP ;EF012 ;MSH168 .ENABL LSB ;MSH168 ;MSH168 .IF DF D$$YNM&M$$MGE ;MSH168 ;MSH168 ;+ ;MSH168 ; **-$TCPIO-TEST IF CHECKPOINT SHOULD BE INITIATED IF NO I/O ;MSH168 ; ;MSH168 ; INPUTS: ;MSH168 ; ;MSH168 ; R1=ADDRESS OF THE TCB OF THE OWNER TASK. ;MSH168 ; R4=ADDRESS OF THE TCB OF THE REQUESTED TASK. ;MSH168 ; ;MSH168 ; OUTPUTS: ;MSH168 ; ;MSH168 ; C=0 IF CHECKPOINT SHOULD BE INITIATED. ;MSH168 ; C=1 IF CHECKPOINT SHOULD NOT BE INITIATED. ;MSH168 ;- ;MSH168 ;MSH168 $TCPIO::TSTB T.IOC(R1) ;OUTSTANDING I/O? ;MSH168 ;MSH168 .IF DF S$$WPC&D$$ISK ;MSH168 ;MSH168 BEQ $TSTCP ;IF EQ NO, JOIN COMMON CODE ;MSH168 SEC ;TASK NOT CHECKPOINTABLE WITH ;MSH168 RETURN ;OUTSTANDING I/O ;MSH168 ;MSH168 .IFF ;MSH168 ;MSH168 BNE 15$ ;IF NE YES, TASK NOT ELIGIBLE FOR CKP ;MSH168 ;MSH168 .ENDC ;MSH168 ;MSH168 .ENDC ;D$$YNM&M$$MGE ;MSH168 ;**-1 ;+ ; **-$TSTCP-TEST IF CHECKPOINT SHOULD BE INITIATED ; ; INPUTS: ; ; R1=ADDRESS OF THE TCB OF THE OWNER TASK. ; R4=ADDRESS OF THE TCB OF THE REQUESTED TASK. ; ; OUTPUTS: ; ; C=0 IF CHECKPOINT SHOULD BE INITIATED. ; C=1 IF CHECKPOINT SHOULD NOT BE INITIATED. ;- $TSTCP:: ; .IF DF S$$WPC&D$$ISK MOV R5,-(SP) ;SAVE R5 .IFTF BIT #TS.STP,T.STAT(R1) ;TASK BLOCKED FROM EXECUTION? ;MSH122 BNE 5$ ;IF NE YES, EFFECTIVE PRIORITY OF ZERO ;MSH122 BIT #T2.STP,T.ST2(R1) ;TASK STOPPED FOR TERMINAL INPUT? .IF DF A$$TRP BEQ 3$ ;IF EQ NO TST T.ASTL(R1) ;TASK HAVE PENDING AST? BEQ 5$ ;IF EQ NO 3$: ;REF LABEL .IFF BNE 5$ ;IF NE YES .ENDC .IFT MOV #S$$WPR,R5 ;PICK UP INITIAL PRIORITY DIFFERENCE BIT #TS.CKP!TS.OUT,T.STAT(R1) ;TASK IN MEMORY? ;MSH166 BNE 4$ ;IF NE NO ;**-1 MOV T.PCB(R1),R5 ;POINT TO TASK PCB MOV P.HDR(R5),R5 ;POINT TO TASK HEADER MOVB H.SPRI(R5),R5 ;PICK UP SWAPPING PRIORITY 4$: CLR -(SP) ;EXTRACT TASK PRIORITY BYTE BISB T.PRI(R1),(SP) ; ADD (SP)+,R5 ;CALCULATE EFFECTIVE PRIORITY CMP T.PRI(R4),R5 ;REQUESTED TASK HIGHER PRIORITY? BLE 10$ ;IF LE NO .IFF CMPB T.PRI(R4),T.PRI(R1) ;REQUESTED TASK HIGHER PRIORITY? BLOS 10$ ;IF LOS NO .IFTF 5$: CLC ;ASSUME TASK CHECKPOINTABLE BIT #T2.CKD!T2.CHK!T2.FXD!T2.HLT,T.ST2(R1) ;IS IT? BEQ 20$ ;IF EQ TASK CAN BE CHECKPOINTED 10$: BIC #TS.CKR,T.STAT(R1) ;CLEAR PENDING CHECKPOINT REQUESTS ;MSH048 15$: SEC ;INDICATE NO CHECKPOINT ;MSH048 20$: ;REF LABEL ;**-1 .IFT MOV (SP)+,R5 ;RESTORE R5 .ENDC RETURN ; ;MSH168 .DSABL LSB ;MSH168 ;+ ; **-$ICHKP-INITIATE CHECKPOINT ; ; INPUTS: ; ; R1=ADDRESS OF THE TCB OF THE TASK TO BE CHECKPOINTED. ;- $ICHKP::BIT #TS.OUT,T.STAT(R1) ;TASK BEING READ IN? BNE 20$ ;IF NE YES BIT #TS.CKP,T.STAT(R1) ;TASK ALREADY BEING CHECKPOINTED? BNE 30$ ;IF NE YES MOV R1,R0 ;SET ADDRESS OF TCB CALL $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST MOV R0,R1 ;RESTORE ADDRESS OF TCB TSTB T.IOC(R1) ;I/O IN PROGRESS BEQ $CHKPT ;IF EQ NO 20$: BIS #TS.CKR,T.STAT(R1) ;SET CHECKPOINT REQUEST 30$: RETURN ; ;+ ; ***-$CHKPT-CHECKPOINT TASK ; ; THIS ROUTINE IS CALLED TO CHECKPOINT A TASK. ; ; INPUTS: ; ; R1=ADDRESS OF THE TCB OF THE TASK TO BE CHECKPOINTED. ; ; OUTPUTS: ; ; THE CHECKPOINT FLAG IS SET IN THE TASK STATUS WORD, THE TASK ; IS PLACED IN THE LOADER QUEUE, AND THE LOADER IS REQUESTED ; TO CHECKPOINT THE TASK. ;- $CHKPT:: ; .IF DF D$$YNC SAVNR ;SAVE R4 AND R5 BIC #T2.CAF,T.ST2(R1) ;CLEAR CHECKPOINT ALLOCATION FAILURE MOV R1,R3 ;COPY TCB ADDRESS MOV #P.SIZE+2,R1 ;SET SIZE OF CHECKPOINT PCB CALL $ALOCB ;ATTEMPT TO ALLOCATE PCB BCS 20$ ;IF CS ALLOCATION FAILURE MOV R0,R4 ;COPY ADDRESS OF ALLOCATED PCB ADD R1,R0 ;POINT TO END OF ALLOCATED PCB MOV T.PCB(R3),R1 ;POINT TO TASK PCB MOV P.SIZE(R1),-(R0) ;SET SIZE OF TASK PCB .IF DF M$$MGE ADD #7,(R0) ;ROUND TO NEXT DISK BLOCK ROR (R0) ;CONVERT TO DISK BLOCKS ASR (R0) ; ASR (R0) ; .IFF ADD #777,(R0) ;ROUND TO NEXT BLOCK BOUNDARY CLRB (R0) ;CLEAR EXCESS BITS SWAB (R0) ;CONVERT TO 256. WORD BLOCKS ASR (R0) ; .ENDC MOV #$CFLPT,R5 ;POINT TO FIRST CHECKPOINT FILE PTR 10$: MOV (R5),R5 ;GET NEXT CHECKPOINT FILE PCB ADDRESS BNE 30$ ;IF NE THERE IS ONE MOV R4,R0 ;ELSE GET ADDRESS OF CHECKPOINT PCB MOV #P.SIZE+2,R1 ;SET ITS SIZE MOV R3,R5 ;SAVE TCB ADDRESS CALL $DEACB ;DEALLOCATE CHECKPOINT PCB MOV R5,R3 ;RESTORE TCB ADDRESS 20$: MOV R3,R1 ;RESTORE TCB ADDRESS BIS #T2.CAF,T.ST2(R3) ;SET CHECKPOINT ALLOCATION FAILURE BIT #T3.CAL,T.ST3(R3) ;CHECKPOINT SPACE ALLOCATED WITH TASK? BNE 50$ ;IF NE YES ;MSH111 .IF DF T$$KMG ;MSH111 ;MSH111 MOV $TKNPT,R0 ;ELSE POINT TO TKTN TCB BEQ 25$ ;IF EQ TKTN NOT INSTALLED TST T.STAT(R0) ;TKTN ALREADY ACTIVE? BMI $EXRQN ;IF MI NO ;MSH111 .ENDC ;MSH111 ;MSH111 25$: RETURN ; 30$: TST P.REL(R5) ;ALLOCATION IN THIS FILE TURNED OFF? BNE 10$ ;IF NE YES CALL $FNDSP ;ATTEMPT TO ALLOCATE SPACE IN FILE BCS 10$ ;IF CS ALLOCATION FAILURE MOV R5,P.MAIN(R4) ;SET MAIN PCB POINTER MOV R3,R1 ;COPY TCB POINTER MOV R4,T.CPCB(R1) ;SET ADDRESS OF CHECKPOINT PCB 50$: ;REF LABEL .ENDC  BIS #TS.CKP,T.STAT(R1) ;SET CHECKPOINT IN PROGRESS BIT .ENDC ;+ ; **-$LOADT-PUT TASK IN LOADER QUEUE ; ; THIS ROUTINE PUTS A TASK IN THE LOADER QUEUE FOR AN INITIAL LOAD OR ; A CHECKPOINT OPERATION. ; ; INPUTS: ; ; R1=ADDRESS OF TASK CONTROL BLOCK ; ; OUTPUTS: ; ; NONE ;- $LOADT::MOV $LDRPT,R0 ;PICK UP TCB ADDRESS OF LOADER .ENDC ;+ ; **-$EXRQP-EXECUTIVE REQUEST WITH QUEUE INSERT BY PRIORITY ; **-$EXRQF-EXECUTIVE REQUEST WITH QUEUE INSERT FIFO ; **-$EXRQN-EXECUTIVE REQUEST WITH NO QUEUE INSERTION ; **-$EXRQU-EXECUTIVE UNSTOP AND REQUEST WITH NO QUEUE INSERTION ;MSH046 ; **-$EXRQC-EXECUTIVE REQUEST - NO UNSTOP, W/CONDITIONAL SCHEDULE REQ ;MSH168 ; **-$EXRQS-EXECUTIVE REQUEST WITH NO CONDITIONAL SCHEDULE REQUEST ;MSH069 ; ; THESE ROUTINES PROVIDE A STANDARD INTERFACE TO ALL TASKS REQUESTED BY ; THE EXECUTIVE. ; ; INPUTS: ; ; R0=TCB ADDRESS OF TASK TO REQUEST ; R1=ADDR OF PACKET TO QUEUE TO TASK (IF ENTRY AT $EXRQP/$EXRQF) ; ; OUTPUTS: ; ; C=0 IF THE REQUEST WAS SUCCESSFULLY COMPLETED. ; C=1 IF THE TASK WAS NOT SUCCESSFULLY REQUESTED. ; Z=0 IF PCB ALLOCATION FAILURE. ; Z=1 IF TASK ACTIVE, BEING REMOVED, OR BEING FIXED. ;- .ENABL LSB $EXRQP::MOV #$QINSP,-(SP) ;PUSH ADDR OF QUEUE INSERT BY PRIORITY BR 1$ ;JOIN COMMON CODE $EXRQF::MOV #$QINSF,-(SP) ;PUSH ADDR OF QUEUE INSERT FIFO 1$: ADD #T.RCVL,R0 ;POINT TO TASK RECEIVE LIST CALL @(SP)+ ;INSERT PACKET IN RECEIVE QUEUE SUB #T.RCVL,R0 ;POINT BACK TO START OF TCB $EXRQN::BIT #T2.STP*2!T2.STP,T.ST2(R0) ;TASK STOPPED? BEQ $EXRQS ;IF EQ NO ;MSH069 $EXRQU::BIC #T2.STP*2!T2.STP,T.ST2(R0) ;CLEAR TASK STOP BIT ;MSH046 $EXRQC::CALL $SETCR ;SET CONDITIONAL SCHEDULE REQUEST ;MSH168 $EXRQS::CLR R1 ;USE DEFAULT UIC ;MSH069 .DSABL LSB ;**-4 ;+ ; **-$TSKRT-TASK REQUEST (DEFAULT UCB) ; **-$TSKRQ-TASK REQUEST (SPECIFY UCB) ; **-$TSKRP-TASK REQUEST (SPECIFY DEFAULT UIC) ; ; THIS ROUTINE IS CALLED TO REQUEST THE EXECUTION OF A TASK. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO BE REQUESTED. ; R1=REQUEST UIC. ; R2=UCB ADDRESS IF ENTRY AT $TSKRQ. ; R3=DEFAULT UIC IF ENTRY AT $TSKRP. ; ; OUTPUTS: ; ; C=1 IF TASK IS ALREADY ACTIVE OR IS BEING FIXED IN MEMORY. ; Z=1 IF TASK ACTIVE OR BEING FIXED. ; Z=0 IF PCB ALLOCATION FAILURE. ; C=0 IF THE REQUEST IS SUCCESSFULLY COMPLETED. ;- .IF NDF M$$MUP $TSKRT::MOV $COPT,R2 ;GET ADDRESS OF COMMAND OUTPUT UCB $TSKRP:: ;REF LABEL $TSKRQ::MOV R0,R3 ;POINT TO TASK STATUS WORD ADD #T.STAT,R3 ; MOV #TS.EXE,-(SP) ;ASSUME TASK IS ACTIVE OR BEING FIXED BIT (SP),(R3)+ ;TASK ALREADY ACTIVE? BEQ 10$ ;IF EQ YES BIT #T2.FXD,(R3)+ ;TASK POSSIBLY BEING FIXED? BEQ 1$ ;IF EQ NO BIT #TS.OUT,T.STAT(R0) ;TASK BEING FIXED? BNE 10$ ;IF NE YES 1$: BIT #T3.REM,(R3) ;TASK BEING REMOVED BY MCR? ; MF203 BNE 10$ ;IF NE YES ;**-1 CMP -(R3),-(R3) ;POINT BACK TO FIRST STATUS WORD .IFF $TSKRT::MOV $COPT,R2 ;GET ADDRESS OF COMMAND OUTPUT UCB $TSKRQ::MOV R1,R3 ;MAKE CURRENT UIC DEFAULT UIC $TSKRP::MOV #TS.EXE,-(SP) ;ASSUME TASK IS ACTIVE OR BEING FIXED BIT (SP),T.STAT(R0) ;TASK ALREADY ACTIVE? BEQ 10$ ;IF EQ YES BIT #TS.OUT,T.STAT(R0) ;TASK POSSIBLY BEING FIXED? BEQ 1$ ;NO BIT #T2.FXD,T.ST2(R0) ;TASK BEING FIXED? BNE 10$ ;IF NE YES 1$: BIT #T3.REM,T.ST3(R0) ;TASK BEING REMOVED BY MCR? ; MF203 BNE 10$ ;IF NE YES ;**-1 MOV R3,T.ACTL(R0) ;SET DEFAULT UIC MOV R0,R3 ;POINT TO TASK STATUS WORD ADD #T.STAT,R3 ; .ENDC BIC (SP),(R3)+ ;SET TASK ACTIVE CLR (SP) ;CLEAR FAILURE INDICATOR MOV R1,T.EFLG(R0) ;SAVE REQUEST UIC MOV R2,T.UCB(R0) ;SET ADDRESS OF 'TI' UCB .IF DF D$$ISK BIT #T2.FXD,(R3) ;TASK FIXED IN MEMORY? BNE 20$ ;IF NE YES .IF DF D$$YNM&M$$MGE MOV T.PCB(R0),R1 ;GET ADDRESS OF TASK PCB BIT #PS.SYS,P.STAT(R1) ;SYSTEM CONTROLLED PARTITION? BEQ 7$ ;IF EQ NO MOV R0,-(SP) ;SAVE TASK TCB ADDRESS MOV #P.LGTH,R1 ;SET LENGTH OF BLOCK NEEDED CALL $ALOCB ;ALLOCATE PCB MOV R0,R2 ;SAVE ADDRESS OF ALLOCATED BLOCK MOV (SP)+,R0 ;RETRIEVE TASK TCB ADDRESS ROR (SP) ;CAPTURE CARRY BIT BEQ 3$ ;IF EQ ALLOCATION WAS SUCCESSFUL BIS (SP),T.STAT(R0) ;SET TASK INACTIVE INC (SP) ;SET ALLOCATION FAILURE ;MSH111 .IF DF T$$KMG ;MSH111 ;MSH111 CMP R0,$TKNPT ;TRYING TO BRING IN TKTN? BEQ 30$ ;YES, EXIT RECURSIVE LOOP ;MSH111 .ENDC ;MSH111 ;MSH111 BR 10$ ; 3$: MOV T.PCB(R0),R1 ;GET MAIN PARTITION PCB ADDRESS MOV R2,T.PCB(R0) ;SET ADDRESS OF ALLOCATED PCB TST (R2)+ ;SKIP OVER LINK WORD MOV T.PRI(R0),(R2)+ ;SET PRIORITY AND I/O COUNT MOV P.NAM(R1),(R2)+ ;INSERT PARTITION NAME MOV P.NAM+2(R1),(R2)+ ; CLR (R2)+ ;CLEAR POINTER TO NEXT SUBPARTITION MOV R1,(R2)+ ;SET BACK POINTER TO MAIN PARTITION PCB CLR (R2)+ ;CLEAR RELOCATION BASE MOV T.MXSZ(R0),(R2)+ ;SET PARTITION SIZE IN 32W BLOCKS CLR (R2)+ ;CLEAR WAIT QUEUE POINTER MOV T.MXSZ(R0),(R2)+ ;INITIALLIZE SWAP SIZE CLR (R2)+ ;CLEAR PARTITION BUSY FLAGS MOV R0,(R2)+ ;SET OWNER TCB ADDRESS MOV #PS.SYS!PS.DEL,(R2)+ ;SYSTEM CONTROLLED, MARKED FOR DEL CLR (R2)+ ;INITIALLY CLEAR HEADER POINTER .IF DF P$$LAS CLR (R2)+ ;CLEAR PROTECTION WORD MOV R2,R1 ;SAVE POINTER TO ATTACHMENT LISTHEAD CLR (R2)+ ;SET UP ATTACHMENT LISTHEAD MOV R1,(R2)+ ; .ENDC .ENDC 7$: MOV R0,R1 ;COPY TASK TCB ADDRESS MOV T.PCB(R0),R0 ;GET ADDRESS OF TASK PCB MOV P.MAIN(R0),R0 ;GET ADDRESS OF MAIN PARTITION PCB ADD #P.WAIT,R0 ;POINT TO PARTITION WAIT QUEUE LISTHEAD CALL $QINSP ;PUT TASK IN PARTITION WAIT QUEUE MOV R1,R0 ;RESTORE TCB ADDRESS 10$: MOV T.PCB(R0),R0 ;GET ADDRESS OF TASK PARTITION PCB CALL $NXTSK ;SELECT NEXT TASK BR 30$ ; .IFTF 20$: CALL $BILDS ;BUILD A STACK FOR TASK .IFT 30$: ASL (SP)+ ;SET SUCCESS/FAILURE INDICATION .IFF 10$: ASL (SP)+ ;SET SUCCESS/FAILURE INDICATION .ENDC RETURN ; ;+ ; **-$UISET-ESTABLISH DEFAULT UIC AND CURRENT UIC ; ; THIS ROUTINE ESTABLISHES DEFAULT AND CURRENT FOR REQUESTED TASKS ; IN MULTI-USER SYSTEMS. ; ; INPUTS: ; ; R1=REQUEST UIC ; R2=ADDRESS OF SECOND STATUS WORD OF CURRENT TASK ; R4=ADDRESS OF HEADER OF CURRENT TASK ; ; OUTPUTS: ; ; R1=CURRENT UIC ; R3=DEFAULT UIC ; C=1 IF NONPRIVILEGED TASK IS TRYING TO CHANGE UIC ; C=0 OTHERWISE ;- .IF DF M$$MUP $UISET::MOV H.DUIC(R4),R3 ;PROPAGATE DEFAULT UIC TST R1 ;UIC SPECIFIED? BEQ 10$ ;IF EQ NO MOV R1,R3 ;USE SPECIFIED UIC BIT #T3.PRV,2(R2) ;CURRENT TASK PRIVILEGED? BNE 20$ ;IF NE YES CMP R1,H.CUIC(R4) ;NONPRIVILEGED TASK CHANGING UIC? BEQ 10$ ;IF EQ NO SEC ;ELSE RETURN C-BIT SET 10$: MOV H.CUIC(R4),R1 ;FORCE PROPAGATION OF CURRENT UIC 20$: RETURN ; .ENDC ;+ ; **-$MAPTK-MAP TASK ADDRESS WINDOW ; ; THIS ROUTINE IS CALLED TO MAP THE FIRST WINDOW BLOCK IN A TASK'S ; HEADER IN A MAPPED SYSTEM FROM ITS PCB AND TCB. ; ; INPUTS: ; ; R1=POINTER TO NUMBER OF WINDOW BLOCKS IN THE TASK HEADER. ; R5=ADDRESS OF THE TASK CONTROL BLOCK FOR THE TASK. ; ; OUTPUTS: ; ; R1=ADDRESS OF LAST PDR IMAGE IN TASK HEADER. ; R2 IS MODIFIED. ; R3 IS PRESERVED. ;MSH096 ;- .IF DF M$$MGE $MAPTK::TST (R1)+ ;POINT TO TASK WINDOW BLOCK MOV T.PCB(R5),R2 ;PICK UP TASK PCB ADDRESS MOV R2,(R1)+ ;SET TASK PCB ADDRESS (W.BPCB) .IF DF P$$LAS BIT #T3.ROV,T.ST3(R5) ;TASK HAVE RESIDENT OVERLAYS? BNE 20$ ;IF NE YES, DON'T CHANGE WINDOW BLOCK .IFTF MOV (R1)+,(R1) ;INIT HIGH VIRT ADDR (W.BLVR)(W.BHVR) MOV P.SIZE(R2),R2 ;PICK UP PARTITION SIZE ;MSH096 .IFF ;MSH096 ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 MOV R3,-(SP) ;PRESERVE R3 ;MSH096 CLR R3 ;INITIALIZE WINDOW OFFSET ;MSH096 BIT #T2.CHK,T.ST2(R5) ;TASK HAVE ALTERNATE HEADER AREA ;MSH096 BNE 5$ ;IF NE NO, NONCHECKPOINTABLE TASK ;MSH096 MOVB T.HDLN(R5),R3 ;GET ALTERNATE HEADER REFRESH AREA LNGTH;MSH096 SUB R3,R2 ;REDUCE BY ALT. HDR REFRESH AREA LENGTH ;MSH096 5$: ;MSH096 .ENDC ;MSH096 .IFT SUB T.OFF(R5),R2 ;REDUCE BY TASK OFFSET IN PARTITION .IFTF MOV R2,-(SP) ;PUSH REQUIRED WINDOW SIZE SWAB (SP) ;CONVERT TO BYTES RORB (SP) ; ROR (SP) ; ROR (SP) ; ADD (SP)+,(R1) ;COMPLETE HIGH VIRTUAL ADDRESS (W.BHVR) DEC (R1)+ ; .IF DF P$$LAS!A$$HDR ;MSH096 ;**-1 TST (R1)+ ;POINT TO WINDOW SIZE (W.BATT) MOV R2,(R1)+ ;SET WINDOW SIZE (W.BSIZ) ;MSH096 .IF DF P$$LAS ;MSH096 ;MSH096 MOV T.OFF(R5),(R1)+ ;SET OFFSET IN PARTITION (W.BOFF) ;MSH096 .IFF ;MSH096 ;MSH096 MOV R3,(R1)+ ;SET OFFSET IN PARTITION (W.BOFF) ;MSH096 ;MSH096 .ENDC ;MSH096 ;MSH096 INC R1 ;POINT TO NUMBER OF PDR'S .IFF ADD #W.BNPD-W.BATT,R1 ;POINT TO NUMBER OF PDR'S BYTE ;MSH096 .ENDC ;P$$LAS!A$$HDR ;MSH096 ;MSH096 .IFF ;MSH096 ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 MOV (SP)+,R3 ;RESTORE CONTENTS OF R3 ;MSH096 ;MSH096 .ENDC ;MSH096 .IFTF ASL R2 ;SHIFT # PDR'S TO HIGH BYTE SWAB R2 ;# PDR'¶S TO LO BYTE, LAST PDR SIZE TO HI SUB #377,R2 ;INC # PDR'S & DEC LAST PDR SIZE SBC R2 ;IF CS, EVEN BOUNDARY, REDUCE # PDR'S MOVB R2,(R1)+ ;SET NUMBER OF PDR'S (W.BNPD) ROR R2 ;ADJUST CORRECT SIZE MOV R2,(R1) ;SET SIZE FOR LAST PDR (W.BLPD) MOVB #6,(R1) ;SET FOR READ/WRITE ACCESS (W.BLPD) 10$: RETURN ; .IFT 20$: ADD #W.BLPD-W.BLVR,R1 ;POINT TO LAST WORD OF WINDOW BLOCK RETURN .ENDC .ENDC .END ¶«:ƒkQ ›c, .TITLE IOSUB .IDENT /11.49/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 11.49 ; ; D. N. CUTLER 4-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; C. SPITZ ; M. S. HARVEY ; B. S. MCCARTHY ; B. A. O'CONNELL ; ; MODIFIED BY: ; ; M. S. HARVEY 19-JUN-79 ; MSH037 -- CLEAN UP COMMENTS A BIT. ; ; M. S. HARVEY 25-JUL-79 ; MSH046 -- IMPLEMENT ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 15-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 25-OCT-79 ; MSH070 -- ALLOW LOAD OVERLAYS FOR TASKS INSTALLED FROM ; AN UNMOUNTED DISK, EVEN IF ANOTHER TASK HAS ; THE DISK ATTACHED. ; ; M. S. HARVEY 19-DEC-79 ; MSH073 -- CORRECT NORMALIZATION CONSTANT ; ; M. S. HARVEY 7-APR-80 ; MSH090 -- REMOVE UNNECESSARY RESTRICTIONS ON BUFFERED I/O ; ; M. S. HARVEY 30-JUN-80 ; MSH091 -- USE KERNEL AST SYMBOL ; ; M. S. HARVEY 20-AUG-80 ; MSH096 -- ADD ALTERNATE HEADER REFRESH SUPPORT ; ; M. S. HARVEY 21-AUG-80 ; MSH112 -- SPLIT IOSUB INTO THE FOLLOWING MODULES: ; IOSUB - GENERAL I/O FUNCTIONS ; MDSUB - MASS STORAGE DRIVER FUNCTIONS ; MEMAP - MEMORY MAPPING FUNCTIONS ; EXESB - EXEC-I/O FUNCTIONS ; ; M. S. HARVEY 8-SEP-80 ; MSH114 -- REMOVE SCS-11 SPECIFIC CODE ; ; C. H. FRANKS 18-NOV-80 ;  CHF020 -- ADD SOFTWARE WRITE LOCK TO $GTPKT ; ; R. T. PERRON 21-NOV-80 ; RP041 -- CHANGE INTERFACE TO COMMON ECC ROUTINE ; ; DAN BROWN 7-JAN-81 ; DTB006 -- MODIFY FOR NEW ERROR LOG INTERFACE ; ; C. H. FRANKS 20-FEB-81 ; CHF021 -- CONDITIONALIZE SOFTWARE WRITE LOCK ; ; C. H. FRANKS 11-MAR-81 ; CHF023 -- MOVE SOFTWARE WRITE LOCK FROM $GTPKT TO $DRQIO ; ; R. T. PERRON 13-MAR-81 ; RP053 -- CHANGE CONDITIONALIZATION OF $GTPKT/$GSPKT FOR ; UDA50 SUPPORT ; ; P. J. BEZEREDI 05-MAY-81 ; PB241 -- ENHANCE ERROR LOG FUNCTIONALITY. ; ; M. S. HARVEY 7-MAY-81 ; MSH169 -- ALLOW TASKS TO BE SHUFFLED IF NECESSARY ; AFTER BUFFERING AN I/O REQUEST ; ; M. S. HARVEY 18-MAY-81 ; MSH170 -- ADD CODE TO TRAP DIVERGENT I/O PROCESSING ; ; M. S. HARVEY 17-JUN-81 ; MSH164 -- ALLOW QUEUE FLUSH FOR FOREIGN MOUNTED ; DEVICES WITH NO ASSOCIATED ACP ; ; T. M. MARTIN 16-DEC-81 ; TMM087 -- ALLOW CLI TASKS WHICH MAY BE NON-PRIV ; TO BREAK-THRU ATTACHES ; ; ; ; I/O RELATED ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,HWDDF$,PCBDF$,PKTDF$,TCBDF$,EPKDF$ ;MSH112 EPKDF$ ;DEFINE ERROR PACKET OFFSETS ;DTB006 HDRDF$ ;DEFINE TASK HEADER OFFSETS ;**-2 HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;**-260 ;+ ; **-$GTPKT-GET I/O PACKET FROM REQUEST QUEUE ; **-$GSPKT-GET SELECTIVE I/O PACKET FROM REQUEST QUEUE ; ; THIS ROUTINE IS CALLED BY DEVICE DRIVERS TO DEQUEUE THE NEXT I/O REQUEST TO ; PROCESS. IF THE DEVICE CONTROLLER IS BUSY, THEN A CARRY SET INDICATION IS ; RETURNED TO THE CALLER. ELSE AN ATTEMPT IS MADE TO DEQUEUE THE NEXT REQUEST ; FROM THE CONTROLLER QUEUE. IF NO REQUEST CAN BE DEQUEUED, THEN A CARRY ; SET INDICATION IS RETURNED TO THE CALLER. ELSE THE CONTROLLER IS SET BUSY AND ; A CARRY CLEAR INDICATION IS RETURNED TO THE CALLER. ; ; THE ALTERNATE ENTRY POINT $GSPKT IS INTENDED FOR USE BY DRIVERS WHICH ; SUPPORT PARALLEL OPERATIONS ON A SINGLE UNIT, A COMMON EXAMPLE BEING ; FULL DUPLEX. SUCH DRIVERS ARE EXPECTED TO LOOK TO THE SYSTEM AS IF ; THEY ARE ALWAYS FREE, WHILE MAINTAINING THE STATUS OF ALL PARALLEL ; OPERATIONS INTERNALLY WITHIN THEIR OWN DEVICE DATA STRUCTURES. ; PARALLELISM IS ACCOMPLISHED BY HANDLING DRIVER-DEFINED CLASSES OF I/O ; FUNCTION CODES IN PARALLEL WITH EACH OTHER. FOR EXAMPLE A FULL-DUPLEX ; DRIVER WOULD HANDLE INPUT REQUESTS IN PARALLEL WITH OUTPUT REQUESTS. ; A DRIVER CALLS $GSPKT WHEN IT WANTS TO DEQUEUE A PACKET WHOSE I/O ; FUNCTION CODE BELONGS TO A CERTAIN CLASS. WHICH FUNCTIONS QUALIFY IS ; DETERMINED BY AN ACCEPTANCE ROUTINE IN THE DRIVER WHOSE ADDRESS IS ; PASSED TO $GSPKT IN R2. THE ACCEPTANCE ROUTINE IS CALLED BY $GSPKT ; EACH TIME A PACKET IS FOUND IN THE QUEUE WHICH IS ELIGIBLE TO BE ; DEQUEUED. THE ACCEPTANCE ROUTINE IS THEN EXPECTED TO TAKE ONE OF THE ; FOLLOWING THREE ACTIONS: ; ; 1. RETURN WITH CARRY CLEAR IF THE PACKET SHOULD BE ; DEQUEUED. IN THIS CASE $GSPKT PROCEEDS AS $GTPKT ; NORMALLY WOULD ON DEQUEUEING THE PACKET. ; ; 2. RETURN WITH CARRY SET IF THE PACKET SHOULD NOT BE ; DEQUEUED. IN THIS CASE $GSPKT WILL CONTINUE THE SCAN ; OF THE I/O QUEUE. ; ; 3. ADD THE CONSTANT G$$SPA TO THE STACK POINTER TO ABORT ;MSH037 ; THE SCAN WITH NO FURTHER ACTION. ;**-1 ; ; THE ACCEPTANCE ROUTINE MUST SAVE AND RESTORE ANY REGISTERS WHICH IT ; INTENDS TO MODIFY. WHEN A PACKET IS DEQUEUED VIA $GSPKT, THE ; FOLLOWING NORMAL $GTPKT ACTIONS DO NOT OCCUR: ; ; 1. FILLING IN OF U.BUF, U.BUF+2 AND U.CNT. THESE FIELDS ; ARE AVAILABLE FOR DRIVER-SPECIFIC USE. ; ; 2. BUSYING OF UCB AND SCB. ; ; INPUTS: ;**-3 ; ; R2=ADDRESS OF DRIVER'S ACCEPTANCE ROUTINE (IF CALL AT $GSPKT). ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO GET A PACKET FOR. ; ; OUTPUTS: ; ; C=1 IF CONTROLLER IS BUSY OR NO REQUEST CAN BE DEQUEUED. ; C=0 IF A REQUEST WAS SUCCESSFULLY DEQUEUED. ; R1=ADDRESS OF THE I/O PACKET. ; R2=PHYSICAL UNIT NUMBER. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; NOTE: R4 AND R5 ARE DESTROYED BY THIS ROUTINE. ;- .ENABL LSB .IF DF A$$BIO!R$$UDA ; RP053 ;**-1 G$$SPA==4 ;CONSTANT TO ADD TO SP TO ABORT SCAN $GTPKT::MOV #128$,R2 ;ACCEPT ALL PACKETS $GSPKT::MOV R2,$TEMP2 ;SAVE ADDRESS OF ACCEPTANCE ROUTINE 5$: MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB .IFF $GTPKT::MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB .ENDC ;A$$BIO!R$$UDA ; RP053 ;**-1 TSTB S.STS(R4) ;CONTROLLER BUSY? BNE 70$ ;IF NE CONTROLLER IS BUSY .IF DF E$$LOG ;DTB006 ;**-1 BICB #SP.EIP,S.PRI(R4) ;CLEAR ERROR IN PROGRESS .ENDC MOV R4,R1 ;SET POINTER TO I/O QUEUE LISTHEAD 10$: MOV R1,R0 ;SAVE ADDRESS OF PREVIOUS PACKET MOV (R0),R1 ;GET ADDRESS OF NEXT PACKET BEQ 70$ ;IF EQ NO MORE PACKETS TO SCAN MOV I.UCB(R1),R5 ;GET ADDRESS OF UNIT CONTROL BLOCK MOV U.ATT(R5),R3 ;UNIT ATTACHED? BEQ 20$ ;IF EQ NO  CMP #IO.LOV,I.FCN(R1) ;LOAD OVERLAY I/O FUNCTION? ;MSH070 BNE 12$ ;IF NE NO ;MSH070 TST U.CW1(R5) ;IS IT A MOUNTABLE DEVICE? ;MSH070 BMI 20$ ;IF MI YES, BREAK THRU ATTACH ;MSH070 12$: MOV I.TCB(R1),R2 ;GET ADDRESS OF REQUESTOR TASK TCB ;MSH070 BIT #T3.PRV!T3.CLI,T.ST3(R2) ;TASK PRIVILEGED OR CLI? ;TMM087 BEQ 15$ ;IF EQ NO ;**-2 .IF DF D$$ISK CMP R2,$LDRPT ;REQUESTING TASK THE LOADER? BEQ 20$ ;IF EQ YES-ALWAYS BREAK THRU ATTACH .ENDC BIT #DV.TTY,U.CW1(R5) ;DEVICE A TERMINAL? BEQ 15$ ;IF EQ NO CMPB #IO.WLB/256.,I.FCN+1(R1) ;WRITE LOGICAL FUNCTION ;**-8 BEQ 20$ ;IF EQ YES-BREAK THRU ATTACH 15$: CMP R2,R3 ;IS THIS THE APPROPRIATE TASK? ;**-3 BNE 10$ ;IF NE NO .IF DF A$$BIO!R$$UDA ; RP053 ;**-1 20$: CALL @$TEMP2 ;CALL DRIVER ACCEPTANCE ROUTINE BCS 10$ ;IF CS PACKET NOT ACCEPTED MOV (R1),(R0) ;CLOSE UP LIST REMOVING ENTRY .IFF 20$: MOV (R1),(R0) ;CLOSE UP LIST REMOVING ENTRY .ENDC ;A$$BIO!R$$UDA ; RP053 ;**-1 BNE 30$ ;IF NE LAST ENTRY WAS NOT REMOVED MOV R0,2(R4) ;SET ADDRESS OF NEW LAST IN LIST 30$: MOV R1,S.PKT(R4) ;SET ADDRESS OF CURRENT I/O PACKET MOVB I.FCN+1(R1),R2 ;GET I/O FUNCTION CODE CMPB #IO.ATT/256.,R2 ;ATTACH FUNCTION? BNE 40$ ;IF NE NO .IF DF A$$CPS MOV #IE.PRI&377,R0 ;ASSUME PRIVILEGE VIOLATION TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL 35$ ;IF PL NO BITB #US.MNT!US.FOR,U.STS(R5) ;NOT MOUNTED OR FOREIGN? BEQ 60$ ;IF EQ NO .IFTF 35$: MOV I.TCB(R1),R0 ;ASSUME SUCCESSFUL ATTACH TST R3 ;UNIT ALREADY ATTACHED? .IF DF D$$IAG BEQ 36$ ;IF EQ NO .IFF BEQ 50$ ;IF EQ NO .IFTF MOV #IE.DAA&377,R0 ;SET STATUS OF DEVICE ALREADY ATTACHED BR 60$ ; .IFT 36$: BITB #IQ.UMD,I.FCN(R1) ;IS THIS A DIAGNOSTIC ATTACH? BEQ 50$ ;IF EQ NO BIT #DV.UMD,U.CW1(R5) ;USER MODE DIAGNOSTICS SUPPORTED? BEQ 37$ ;IF EQ NO BISB #US.UMD,U.ST2(R5) ;INDICATE DIAGNOSTIC ATTACH BR 50$ ; 37$: MOV #IE.IFC&377,R0 ;SET STATUS OF ILLEGAL FUNCTION BR 60$ ; .IFTF 40$: CMPB #IO.DET/256.,R2 ;DETACH FUNCTION BNE 80$ ;IF NE NO MOV #IE.DNA&377,R0 ;ASSUME DEVICE NOT ATTCHED TST R3 ;UNIT ATTACHED? BEQ 60$ ;IF EQ NO CLR R0 ;SET TO DETACH UNIT .IFT BICB #US.UMD,U.ST2(R5) ;RESET DIAGNOSTIC BIT .ENDC 50$: MOV R0,U.ATT(R5) ;ATTACH/DETACH UNIT BITB #UC.ATT,U.CTL(R5) ;DOES DRIVER WANT CONTROL ON ATTACH/DETACH? BNE 120$ ;IF NE YES MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS 60$: CALL $IOALT ;FINISH I/O OPERATION  .IF DF A$$BIO!R$$UDA ; RP053 ;**-1 65$: BR 5$ ;GO AGAIN .IFF 65$: BR $GTPKT ;GO AGAIN .ENDC ;A$$BIO!R$$UDA ; RP053 ;**-1 70$: SEC ;SET CONTROLLER BUSY OR NO REQUEST BR 130$ ; 80$: ;REF LABEL .IFT TST U.CW1(R5) ;DEVICE MOUNTABLE? BPL 120$ ;IF PL NO .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;IS THIS A DIAGNOSTIC FUNCTION? BNE 120$ ;IF NE YES, IT CAN'T BE AN ACP FUNCTION .ENDC ; ; DETERMINE IF FUNCTION IS ACP FUNCTION ; APPLICABLE TO ALL MOUNTED DEVICES - NATIVE AND FOREIGN ; FILES 11 - MAPPING OF VIRTUAL TO LOGICAL NOW DONE BY ; DRQIO. ONLY VIRTUAL & ACP FUNCTIONS THAT ; NEED CORRECT SEQUENCING ARE ROUTED THRU DRIVER. ; MOV U.ACP(R5),R0 ;GET ADDRESS OF ACP BEQ 120$ ;NO ACP - PASS IT ON TO DRIVER ; ; NATIVE REQUESTS ARE ROUTED TO THE ACP IF THE FCTN CODE > 7. ; THIS IS REQUIRED BECAUSE IO.CLN IS NOT CURRENTLY DEFINED ; IN DCB BITS. HOPEFULLY THIS WILL BE FIXED. ; BITB #US.MNT!US.FOR,U.STS(R5) ;MOUNTED NATIVE? BNE 85$ ;BRANCH IF MOUNTED FOREIGN CMP #7,R2 ;NATIVE-IS IT ACP FCTN? BHI 120$ ;IF HI NO -DRIVER FCTN BR 95$ ;ACP 85$: MOV (R5),R3 ;GET DCB ADDRESS CMP R2,#15. ;NORMALIZE FCTN CODE BLOS 90$ ; SUB #16.,R2 ;NORMALIZE ;MSH073 ADD #10,R3 ;ADJUST PTR TO 2ND MASK SET ;**-1 90$: ASL R2 ;CONVERT TO WORD INDEX BIT $BTMSK(R2),D.MSK+6(R3) ;IS IT ACP FUNCTION? BEQ 120$ ;NO - DRIVER 95$: ; CALL $EXRQP ;INSURE FILE SYSTEM IS ACTIVE BR 65$ ;GO AGAIN .ENDC .IF DF A$$BIO!R$$UDA ; RP053 ;**-1 120$: CMP $TEMP2,#128$ ;$GSPKT CALL? BNE 127$ ;IF NE YES, SKIP TO DRIVER CALL .IFF 120$: .ENDC ;A$$BIO!R$$UDA ; RP053 ;**-1 MOV I.PRM(R1),U.BUF(R5) ;INSERT RELOCATION BIAS IN UCB MOV I.PRM+2(R1),U.BUF+2(R5) ;INSERT BUFFER ADDRESS IN UCB MOV I.PRM+4(R1),U.CNT(R5) ;INSERT BYTE COUNT IN UCB 126$: INCB S.STS(R4) ;SET CONTROLLER BUSY BISB #US.BSY,U.STS(R5) ;SET UNIT BUSY 127$: MOVB S.CON(R4),R3 ;GET CONTROLLER INDEX MOVB U.UNIT(R5),R2 ;SET PHYSICAL UNIT NUMBER ;DTB006 .IF DF E$$LOG ;DTB006 ;DTB006 BIT #DV.MSD,U.CW1(R5) ;IS IT A MASS STORAGE DEVICE? ;DTB006 BEQ 128$ ;IF EQ NOT A MASS STORAGE DEVICE ;DTB006 ADD #1,U.IOC(R5) ;COUNT ANOTHER I/O ;DTB006 ADC U.IOC+2(R5) ; AND INCREMENT THE HIGH ORDER ;DTB006 ;DTB006 .ENDC ;DTB006 ;DTB006 128$: CLC ;INDICATE PACKET BEING RETURNED 130$: RETURN ; .DSABL LSB .IF DF A$$BIO ;MSH046 ;**-1 ;+ ; **-$TSTBF-TEST IF I/O BUFFERING CAN BE INITIATED ; ; THIS ROUTINE DETERMINES IF A GIVEN I/O REQUEST IS ELIGIBLE FOR I/O ; BUFFERING, AND IF SO (FOR SYSTEMS THAT SUPPORT SYSTEM-CONTROLLED ;MSH046 ; PARTITIONS) IT STORES THE PCB ADDRESS OF THE REGION INTO WHICH ;MSH046 ; THE TRANSFER IS TO OCCUR IN I.PRM+16 OF THE I/O PACKET. ;MSH046 ; ;**-2 ; INPUTS: ; ; R3=ADDRESS OF I/O PACKET FOR I/O REQUEST ; ; OUTPUTS: ; ; R3 IS PRESERVED. ; ; C=0 IF I/O BUFFERING CAN BE INITIATED. ; ; C=1 IF I/O BUFFERING CAN NOT BE INITIATED. ;- $TSTBF::MOV I.TCB(R3),R0 ;GET ADDRESS OF REQUESTOR TCB SEC ;ASSUME TASK CANNOT BE STOPPED? BIT #T2.CHK!T2.CKD,T.ST2(R0) ;STOP IT? ;MSH090 BNE 20$ ;IF NE NO ;**-1 ;MSH046 .IF DF M$$MGE&D$$YNM ;MSH046 ;MSH046 SAVNR ;SAVE R4 AND R5 MOV T.PCB(R0),R1 ;GET ADDRESS OF REQUESTER HEADER MOV P.HDR(R1),R1 ; MOV H.WND(R1),R1 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R1)+,R2 ;GET COUNT OF WINDOWS 10$: SEC ;ASSUME NO MORE WINDOWS DEC R2 ;ANY MORE WINDOWS TO EXAMINE? BLT 20$ ;IF LT NO, DON'T CHECKPOINT MOV (R1)+,R4 ;GET ADDRESS OF DESCRIPTOR PCB BEQ 30$ ;IF EQ WINDOW NOT MAPPED MOV (R1)+,-(SP) ;GET LOW VIRTUAL ADDRESS MOV (R1)+,R5 ;GET HIGH VIRTUAL ADDRESS SUB (SP),R5 ;CALCULATE NUMBER OF BYTES MINUS 1 SUB #77,R5 ;REDUCE TO ACTUAL NUMBER OF BYTES - 64B ASL R5 ;CONVERT TO 32W BLOCKS ROL R5 ; ROLB R5 ; SWAB R5 ; MOV P.REL(R4),(SP) ;GET RELOCATION BIAS OF PCB .IF DF P$$LAS!A$$HDR ;MSH096 ;**-1 ADD W.BOFF-W.BATT(R1),(SP) ;ADD IN OFFSET IN PARTITION .ENDC ADD (SP),R5 ;CALCULATE HIGHEST 32W BLOCK ADD #W.BLGH-W.BATT,R1 ;POINT TO NEXT DESCRIPTOR CMP I.PRM(R3),(SP)+ ;TRANSFER IN THIS PARTITION? BLO 10$ ;IF LO NO CMP R5,I.PRM(R3) ;TRANSFER IN THIS PARTITION? BLO 10$ ;IF LO NO MOV R4,I.PRM+16(R3) ;STORE PCB ADDRESS IN I/O PACKET ;MSH046 .IFF ;M$$MGE&D$$YNM ;MSH046 ;MSH046 CLC ;I/O BUFFERING CAN BE INITIATED ;MSH046 ;MSH046 .IFTF ;MSH046 ;MSH046 20$: RETURN ; ;MSH046 .IFT ;MSH046 ;MSH046 30$: ADD #W.BLGH-W.BLVR,R1 ;POINT TO NEXT WINDOW BLOCK BR 10$ ; ;MSH046 ;MSH046 .IFTF ;MSH046 ;**-1 ;+ ; **-$INIBF-INITIATE I/O BUFFERING ; ; THIS ROUTINE INITIATES I/O BUFFERING BY DOING THE FOLLOWING: ; ; 1. DECREMENT THE TASK'S I/O COUNT. ; 2. INCREMENT THE TASK'S BUFFERED I/O COUNT. ;MSH046 ; 3. INITIATE CHECKPOINTING IF A REQUEST IS PENDING. ;MSH046 ; 4. REENABLE SHUFFLING OF THE TASK ;MSH169 ; ;**-6 ; INPUTS: ; ; R3=ADDRESS OF I/O PACKET FOR I/O REQUEST. ; ; OUTPUTS: ; ; R3 IS PRESERVED. ;- $INIBF::MOV R5,-(SP) ;SAVE R5 ;MSH046 MOV I.TCB(R3),R5 ;POINT TO ISSUING TASK'S TCB ;MSH046 INCB T.TIO(R5) ;TALLY THE BUFFERED I/O ;MSH046 DECB T.IOC(R5) ;ADJUST OUTSTANDING I/O REQUEST COUNT ;MSH046 ;MSH046 .IFT ;MSH046 ;MSH046 MOV I.PRM+16(R3),R1 ;GET PCB ;**-4 SUB P.REL(R1),I.PRM(R3) ;CONVERT TO RELATIVE RELOCATION BIAS ;MSH046 .ENDC ;M$$MGE&D$$YNM ;MSH046 ;**-1 .IF DF D$$ISK&C$$CKP ;MSH046 ;**-1 BIT #TS.CKR,T.STAT(R5) ;CHECKPOINT REQUEST PENDING? ;MSH046 BEQ 20$ ;IF EQ NO ;**-1 BIC #TS.CKR,T.STAT(R5) ;CLEAR CHECKPOINT REQUEST ;MSH046 MOV R5,R1 ;COPY TCB ADDRESS ;MSH046 MOV R3,-(SP) ;SAVE PACKET ADDRESS ;MSH046 ;MSH169 .IF DF D$$YNM&D$$SHF ;MSH169 ;MSH169 MOV R5,-(SP) ;SAVE THE TCB ADDRESS ;MSH169 ;MSH169 .IFTF ;MSH169 ;MSH169 CALL $ICHKP ;INITIATE CHECKPOINT OF TASK ;MSH169 ;MSH169 .IFT ;MSH169 ;MSH169 MOV (SP)+,R5 ;RESTORE TCB ADDRESS ;MSH169 TSTB T.IOC(R5) ;I/O COUNT NOW ZERO? ;MSH169 BNE 15$ ;IF NE NO ;MSH169 MOV T.PCB(R5),R0 ;GET TASK'S PCB ADDRESS ;MSH169 BIT #PS.LIO,P.STAT(R0) ;DID SHUFFLER DETECT LONG I/O? ;MSH169 BEQ 15$ ;IF EQ NO ;MSH169 BIC #PS.LIO,P.STAT(R0) ;CLEAR LONG I/O BIT ;MSH169 CALL $NXTSK ;REALLOCATE PARTITION ;MSH169 ;MSH169 .ENDC ;MSH169 ;MSH169 15$: MOV (SP)+,R3 ;RESTORE PACKET ADDRESS IN R3 ;MSH046 ;**-5 .ENDC 20$: MOV (SP)+,R5 ;RESTORE R5 ;MSH046 RETURN ; ;**-2 ;+ ; **-$QUEBF-QUEUE BUFFERED I/O FOR COMPLETION ; ; THIS ROUTINE QUEUES A SPECIAL ENTRY TO A TASK'S AST QUEUE TO COMPLETE ; A BUFFERED I/O REQUEST THE NEXT TIME THE TASK IS SCHEDULED. IT ALSO ; DECREMENTS THE TASK'S BUFFERED I/O COUNT. ;MSH046 ; ;**-1 ; NOTE: THIS ROUTINE IS EQUIVALENT TO CALLING $IOFIN AND IT DOES NOT ; UNBUSY THE DEVICE. ; ; INPUTS: ; ; R0=FIRST WORD OF I/O STATUS ; R1=SECOND WORD OF I/O STATUS ; R3=ADDRESS OF I/O PACKET ; ; OUTPUTS: ; ; NONE ;- $QUEBF::MOV R0,I.PRM+6(R3) ;STORE OFFSPRING I/O RETURN STATUS MOV R1,I.PRM+10(R3) ; MOV I.TCB(R3),R0 ;PICK UP OFFSPRING TCB ADDRESS BIC #TS.RDN,T.STAT(R0) ;CLEAR RUNDOWN IN PROG MOV R0,R2 ;COPY TCB ADDRESS ADD #T.ASTL,R2 ;POINT TO AST LISTHEAD MOV (R2),(R3) ;LINK PACKET TO FRONT OF LIST BNE 10$ ; MOV R3,2(R2) ; 10$: MOV R3,(R2) ; MOVB #AK.BUF,A.CBL(R3) ;SET BUFFERED I/O KERNEL AST TYPE ;MSH091 DECB T.TIO(R0) ;DECREMENT BUFFERED I/O COUNT ;MSH046 BIT #T2.WFR,T.ST2(R0) ;TASK STOPPED FOR BUFFERED I/O? ;MSH046 BNE 12$ ;IF NE YES ;MSH046 CALLR $SETCR ;SET CONDITIONAL SCHEDULE REQUEST ;MSH046 ;MSH046 12$: CALLR $EXRQU ;UNSTOP TASK AND RETURN ;MSH046 ;**-3 .ENDC ;A$$BIO ;MSH046  ;**-1 ;**-59 ;+ ; **-$IOALT-I/O DONE (ALTERNATE ENTRY) ; **-$IODON-I/O DONE ; ; THIS ROUTINE IS CALLED BY DEVICE DRIVERS AT THE COMPLETION OF AN I/O REQUEST ; TO DO FINAL PROCESSING. THE UNIT AND CONTROLLER ARE SET IDLE AND $IOFIN IS ; ENTERED TO FINISH THE PROCESSING. ; ; INPUTS: ; ; R0=FIRST I/O STATUS WORD. ; R1=SECOND I/O STATUS WORD. ; R2=STARTING AND FINAL ERROR RETRY COUNTS IF ERROR LOGGING ; DEVICE. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK OF THE UNIT BEING COMPLETED.  ; (SP)=RETURN ADDRESS TO DRIVER'S CALLER. ; ; NOTE: IF ENTRY IS AT $IOALT, THEN R1 IS CLEAR TO SIGNIFY THAT THE ; SECOND STATUS WORD IS ZERO. ; ; OUTPUTS: ; ; THE UNIT AND CONTROLLER ARE SET IDLE. ; ; R3=ADDRESS OF THE CURRENT I/O PACKET. ;- $IOALT::CLR R1 ;ZERO SECOND I/O STATUS WORD $IODON::MOV U.SCB(R5),R4 ;GET ADDRESS OF STATUS CONTROL BLOCK BICB #US.BSY,U.STS(R5) ;CLEAR UNIT BUSY CLRB S.STS(R4) ;CLEAR CONTROLLER BUSY .IF DF E$$LOG ;DTB006 ;**-1 BITB #SP.EIP,S.PRI(R4) ;ERROR IN PROGRESS? BEQ 15$ ;IF EQ NO MOV R1,-(SP) ;SAVE SECOND I/O STATUS WORD CALL $FNERL ;FINISH ERROR LOGGING PROCESS ; PB241 MOV (SP)+,R1 ;RESTORE I/O STATUS CODE ; PB241 15$: ;REF LABEL ;**-10 .ENDC .IF DF M$$EXT BITB #UC.NPR,U.CTL(R5) ;IS IT AN NPR DEVICE? BEQ 20$ ;IF EQ NO, DOES NOT USE UMR'S BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BNE 20$ ;IF NE YES ;**-1 MOV R4,R2 ;COPY SCB POINTER ADD #S.MPR,R2 ;POINT TO MAPPING ASSIGNMENT BLOCK CALL $DEUMR ;DEASSIGN ANY UMR'S MOV #$DQUMR,-(SP) ;PUSH ADDRESS TO CHECK FOR UMR WAIT .ENDC 20$: MOV S.PKT(R4),R3 ;RETRIEVE ADDRESS OF I/O PACKET .IF DF Q$$OPT TST (R4) ;ANY OTHER I/O REQUESTS TO INITIATE? BEQ $IOFIN ;IF EQ NO MOV R3,R4 ;COPY I/O PACKET POINTER ADD #I.PRM+14,R4 ;POINT TO LAST WORD FOR FORK BLOCK MOV R0,(R4) ;STORE I/O STATUS BLOCK CONTENTS MOV R1,-(R4) ; CALL $FORK0 ;FORK HERE TO ALLOW NEXT I/O INITIATION MOV R4,R0 ;RESTORE I/O STATUS BLOCK CONTENTS MOV R5,R1 ; SUB #I.PRM+10,R3 ;POINT TO BEGINNING OF FORK BLOCK .ENDC ;+ ; **-$IOFIN-I/O FINISH ; ; THIS ROUTINE IS CALLED TO FINISH I/O PROCESSING IN CASES WHERE THE UNIT AND ; CONTROLLER ARE NOT TO BE DECLARED IDLE. ; ; INPUTS: ; ; R0=FIRST I/O STATUS WORD. ; R1=SECOND I/O STATUS WORD. ; R3=ADDRESS OF THE I/O REQUEST PACKET. ; ; OUTPUTS: ; ; THE FOLLOWING ACTIONS ARE PERFORMED ; ; 1-THE FINAL I/O STATUS VALUES ARE STORED IN THE I/O STATUS BLOCK IF ; ONE WAS SPECIFIED. ; ; 2-THE I/O COUNT IS DECREMENTED AND TS.RDN IS CLEARED IN CASE ; THE TASK WAS BLOCKED FOR I/O RUNDOWN. ; ; 3-IF 'TS.CKR' IS SET, THEN IT IS CLEARED AND CHECKPOINTING OF ; THE TASK IS INITIATED. ; ; 4-IF AN AST SERVICE ROUTINE WAS SPECIFIED, THEN AN AST IS QUEUED ; FOR THE TASK. ELSE THE I/O PACKET IS DEALLOCATED. ; ; 5-A SIGNIFICANT EVENT OR EQUIVALENT IS DECLARED. ; ; NOTE: R4 IS DESTROYED BY THIS ROUTINE. ;- $IOFIN:: ; ;MSH170 ;MSH170 .IF DF A$$TRP&R$$DER ;MSH170 ;MSH170 CMP I.TCB(R3),#8.*2 ;PACKET CONVERTED TO AST CONTROL BLOCK? ;MSH170 BNE 5$ ;IF NE NO ;MSH170 CRASH ;DOUBLE PROCESSING OF I/O PACKET ;MSH170 ;MSH170 .ENDC ;MSH170 ;MSH170 5$: MOV I.IOSB+4(R3),R2 ;GET ADDRESS OF I/O STATUS BLOCK ;MSH170 BEQ 10$ ;IF EQ NO I/O STATUS BLOCK SPECIFIED ;**-1 .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV I.IOSB+2(R3),KISAR6 ;MAP TO I/O STATUS BLOCK .IFTF MOV R0,(R2)+ ;SET FINAL I/O STATUS VALUES MOV R1,(R2) ; .IFT MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .ENDC 10$: MOV I.TCB(R3),R1 ;GET ADDRESS OF TASK CONTROL BLOCK MOV R1,R2 ;POINT TO FIRST TASK STATUS WORD ADD #T.STAT,R2 ; DECB T.IOC(R1) ;DECREMENT I/O REQUEST COUNT BIC #TS.RDN,(R2) ;FREE TASK IF I/O RUNDOWN IS IN PROGRESS .IF DF R$$LKL MOV I.PRM+16(R3),R0 ;PICK UP LOCK BLOCK ADDRESS BEQ 20$ ;IF EQ THERE IS NONE CMP R0,#140000 ;IS IT A RELOCATED USER ADDRESS? BHIS 20$ ;IF HIS YES DEC (R0) ;FREE LOCK FOR UNLOCKING 20$: ;REF LABEL .ENDC .IF DF C$$CKP&D$$ISK MOV R3,R4 ;SAVE PACKET ADDRESS BIT #TS.CKR,(R2) ;CHECKPOINT REQUESTED? BEQ 30$ ;IF EQ NO BIC #TS.CKR,(R2) ;CLEAR CHECKPOINT REQUEST FLAG CALL $ICHKP ;INITIATE TASK CHECKPOINTING 30$: ;REF LABEL .IF DF D$$YNM&D$$SHF MOV I.TCB(R4),R1 ;PICK UP ISSUING TASK'S TCB ADDRESS MOV T.PCB(R1),R0 ;POINT TO TASK PCB BIT #PS.LIO,P.STAT(R0) ;DID SHUFFLER DETECT A LONG I/O? BEQ 35$ ;IF EQ NO  TSTB T.IOC(R1) ;IS I/O COUNT NOW ZERO? BNE 35$ ;IF NE NO BIC #PS.LIO,P.STAT(R0) ;CLEAR LONG I/O BIT CALL $NXTSK ;REALLOCATE PARTITION 35$: ;REF LABEL .ENDC MOV R4,R3 ;RESTORE PACKET ADDRESS .ENDC MOV R5,-(SP) ;SAVE UCB ADDRESS MOV I.TCB(R3),R5 ;SET TCB ADDRESS MOVB I.EFN(R3),R0 ;GET EVENT FLAG NUMBER CALL $SETFG ;SET EFN AND UNLOCK IF GROUP GLOBAL ;MSH049 MOV R3,R0 ;COPY I/O PACKET ADDRESS ;**-1 .IF DF A$$TRP TST (R3)+ ;POINT TO SECOND WORD MOV #I.LGTH,(R3)+ ;INSERT LENGTH OF BLOCK IN BYTES MOV #8.*2,(R3)+ ;SET NUMBER OF BYTES TO ALLOCATE ON USER STACK MOV I.AST(R0),(R3)+ ;INSERT AST ADDRESS BEQ 70$ ;IF EQ NONE SPECIFIED MOV #1,(R3)+ ;INSERT NUMBER OF AST PARAMETERS MOV I.IOSB(R0),(R3) ;INSERT VIRTUAL ADDRESS OF I/O STATUS BLOCK MOV R0,R1 ;COPY ADDRESS OF I/O PACKET MOV R5,R0 ;CALCULATE ADDRESS OF AST LISTHEAD ADD #T.ASTL,R0 ; CALL $QINSF ;INSERT AST IN QUEUE MOV R5,R0 ;COPY TCB ADDRESS CALL $SETCR ;SET A SCHEDULE REQUEST FOR THE TASK BR 80$ ; .ENDC 70$: CALL $DEPKT ;DEALLOCATE I/O PACKET 80$: MOV (SP)+,R5 ;RESTORE UCB ADDRESS RETURN ; ;+ ; **-$IOKIL-I/O KILL ; ; THIS ROUTINE IS CALLED TO FLUSH ALL I/O REQUESTS FOR THE CURRENT TASK FROM ; A DEVICE QUEUE AND TO CANCEL THE CURRENT I/O OPERATION IN PROGRESS IF IT ; IS ALSO FOR THE CURRENT TASK. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE DEVICE TO FLUSH REQUESTS FOR. ; ; OUTPUTS: ; ; IF THE SPECIFIED DEVICE IS NOT FILE STRUCTURED, THEN THE I/O RE- ; REQUEST QUEUE IS FLUSHED AND THE CURRENT I/O OPERATION IN PROGRESS ; IS CANCELLED. ; ; NOTE: R4 IS DESTROYED BY THIS ROUTINE. ;- $IOKIL::MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV $TKTCB,R1 ;GET TCB ADDRESS OF CURRENT TASK TST U.CW1(R5) ;DEVICE-UNIT MOUNTABLE? BPL 10$ ;IF PL NO BITB #US.MNT,U.STS(R5) ;DEVICE-UNIT MOUNTED? ;MSH164 .IF DF A$$CPS ;MSH164 ;MSH164 BNE 10$ ;IF NE NO, FLUSH I/O QUEUE ;MSH164 TST U.ACP(R5) ;ACP ASSOCIATED WITH DEVICE? ;MSH164  BNE 40$ ;IF NE YES, CAN'T FLUSH QUEUE ;MSH164 ;MSH164 .IFF ;MSH164 ;MSH164 BEQ 40$ ;IF EQ YES ;MSH164 .ENDC ;MSH164 ;MSH164 10$: MOV R4,R3 ;COPY ADDRESS OF I/O QUEUE LISTHEAD 20$: MOV R3,R2 ;SAVE ADDRESS OF CURRENT ENTRY MOV (R2),R3 ;GET ADDRESS OF NEXT ENTRY BEQ 40$ ;IF EQ END OF LIST CMP R1,I.TCB(R3) ;REQUEST FOR CURRENT TASK? BNE 20$ ;IF NE NO CMP R5,I.UCB(R3) ;REQUEST FOR SPECIFIED UCB? BNE 20$ ;IF NE NO MOV (R3),(R2) ;CLOSE UP LIST BNE 30$ ;IF NE NO NEW LAST MOV R2,2(R4) ;SET ADDRESS OF NEW LAST 30$: MOV #IE.ABO&377,R0 ;SET FINAL STATUS TO ABORT CLR I.AST(R3) ;MAKE SURE THERE IS NO AST DECLARED CALL $IOFIN ;FINISH I/O REQUEST BR $IOKIL ;GO AGAIN 40$: BITB #UC.KIL,U.CTL(R5) ;CALL DRIVER REGARDLESS OF ACTIVITY? BNE 45$ ;IF NE YES TSTB U.STS(R5) ;UNIT BUSY? BPL 50$ ;IF PL NO 45$: MOV S.PKT(R4),R0 ;GET ADDRESS OF CURRENT I/O PACKET MOV (R5),R2 ;RETRIEVE ADDRESS OF DEVICE CONTROL BLOCK .IF DF L$$DRV&M$$MGE MOV KISAR5,-(SP) ;SAVE APR5 MOV D.PCB(R2),R3 ;GET DRIVER PCB ADDRESS BEQ 47$ ;IF EQ DRIVER IS PART OF EXEC MOV P.REL(R3),KISAR5 ;MAP THE DRIVER 47$: ; .ENDC MOV D.DSP(R2),R2 ;GET ADDRESS OF DRIVER DISPATCH TABLE .IF DF L$$DRV BEQ 49$ ;IF EQ DRIVER IS UNLOADED .ENDC ;L$$DRV MOVB S.CON(R4),R3 ;GET CONTROLLER INDEX ; ; CALL DRIVER AT CANCEL I/O OPERATION ENTRY POINT WITH THE ARGUMENTS: ; ; R0=ADDRESS OF THE CURRENT I/O PACKET. ; R1=ADDRESS OF THE TCB OF THE CURRENT TASK. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS CALL @D.VCAN(R2) ;;;CANCEL CURRENT REQUEST MTPS #0 ;;;ALLOW DEVICE INTERRUPTS 49$: .IF DF L$$DRV&M$$MGE MOV (SP)+,KISAR5 ;RESTORE APR5 .ENDC 50$: RETURN ; ;**-709 ;+ ; **-$SCDVT-SCAN DEVICE TABLES ; **-$SCDV1-SCAN DEVICE TABLES (ALTERNATE ENTRY) ; ; THIS ROUTINE IS A CO-ROUTINE THAT IS CALLED TO SCAN THE DEVICE TABLES. FOR EAC ; UNIT CONTROL BLOCK THE CALLER IS RECALLED. ; ; INPUTS: ; ; R3=LIST POINTER (IF ENTRY AT $SCDV1) ; ; OUTPUTS: ; ; C=1 IF NO MORE ENTRIES EXIST IN THE DEVICE TABLES. ; C=0 IF THE NEXT DEVICE TABLE ENTRY IS BEING RETURNED. ; R3=ADDRESS OF THE DEVICE CONTROL BLOCK. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ;- S$$SPA==10 ;SYMBOL TO ADD TO SP TO ABORT SCAN S$$SPC==6 ;OFFSET ON SP TO SET TO 1 TO SKIP CURRENT DCB $SCDVT::MOV #$DEVHD,R3 ;GET ADDRESS OF FIRST DCB ADDRESS $SCDV1::MOV (SP)+,R4 ;REMOVE RETURN ADDRESS FROM STACK 10$: MOV (R3),R3 ;GET ADDRESS OF NEXT DCB BEQ 30$ ;IF EQ NO MORE MOV D.UCB(R3),R5 ;POINT TO FIRST UCB BIT #DV.PSE,U.CW1(R5) ;PSEUDO DEVICE? BNE 10$ ;IF NE YES MOVB D.UNIT+1(R3),-(SP) ;CALCULATE NUMBER OF UCB'S TO SCAN SUB D.UNIT(R3),(SP) ; INCB (SP) ; 20$: MOV R3,-(SP) ;SAVE DCB ADDRESS MOV R5,-(SP) ;SAVE UCB ADDRESS MOV R4,-(SP) ;SET RETURN ADDRESS MOV U.SCB¾(R5),R4 ;GET ADDRESS OF STATUS CONTROL BLOCK CLC ;INDICATE ENTRY CALL @(SP)+ ;CALL THE CALLER MOV (SP)+,R4 ;REMOVE RETURN ADDRESS MOV (SP)+,R5 ;RESTORE UCB ADDRESS MOV (SP)+,R3 ;RESTORE DCB ADDRESS ADD D.UCBL(R3),R5 ;POINT TO NEXT UCB DECB (SP) ;ANY MORE UCB'S TO SCAN? BNE 20$ ;IF NE YES TST (SP)+ ;CLEAN STACK BR 10$ ;GO AGAIN 30$: SEC ;INDICATE NO ENTRY JMP (R4) ;RETURN TO CALLER ;**-601 .END ¾ ðskQ ›c, .TITLE DMDRV .IDENT /05.10/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 05.10 ; ; P. J. BEZEREDI 23-SEP-76 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; ; MODIFIED BY: ; ; R. T. PERRON 03-AUG-79 ; ; RP020 -- CORRECT ECC AND OFFSET RECOVERY ERROR HANDLING ; ; R. T. PERRON 06-AUG-79 ; ; RP021 -- CORRECT ERROR RECOVERY FOR LAST BLOCK TRANSFERED ; ; R. T. PERRON 17-AUG-79 ; ; RP022 -- CORRECT BRANCH OUT OF RANGE ; ; P. J. CARR 4-APR-80 ; ; PJC002 -- CORRECT WRITE CHECK FUNCTION ; ; R. T. PERRON 21-NOV-80 ; ; RP041 -- CHANGE INTERFACE TO COMMON ECC ROUTINE ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; P. J. CARR 15-JUN-81 ; ; PJC030 -- OPTIMIZE DATA LATE RECOVERY ; ; R. T. PERRON 16-OCT-81 ; ; RP075 -- CORRECT NON-EIS ADDRESS CALCULATION IN ECC CODE ; ; P. J. CARR 27-OCT-81 ; ; PJC038 -- CLEAN UP CODE ; ; P. J. CARR 16-DEC-81 ; ; PJC041 -- CORRECT ECC CORRECTION REGISTER USAGE ; ; RK611-RK06/RK07 DISK CARTRIDGE DRIVER ; ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ;**************** ; ; EQUATED SYMBOLS ; RETRY= ^D<8> ;CONTROLLER ERROR RETRY COUNT OFFTRY= ^D<2> ;OFFSET POSITION RETRY COUNT RMCNT= ^D<22> ;NUMBER OF REGISTERS TO LOG ON ERROR RCL= 1 ;RECALIBRATE IN PROGRESS (1=YES) ; RP020 OFS= 2 ;OFFSET IN PROGRESS (1=YES) ; RP020 OFM= 10 ;IN OFFSET MODE (1=YES) ; RP020 POP= 20 ;POSITIONING OPERATION (1=YES) ; RP020 DLT= 40 ;DATA LATE OCCURRED (1=YES) ; RP020 ; ;**************** ; ; RK611 DEVICE REGISTER OFFSETS ; RMCS1= 0 ;CONTROL STATUS REGISTER 1 RMWC= 2 ;WORD COUNT RMBA= 4 ;BUS ADDRESS RMDA= 6 ;DISK ADDRESS RMCS2= 10 ;CONTROL STATUS REGISTER 2 RMDS= 12 ;DRIVE STATUS RMER= 14 ;ERROR REGISTER RMOF= 16 ;OFFSET/ATTENTION REGISTER RMDC= 20 ;DESIRED CYLINDER RMDB= 24 ;DATA BUFFER RMMR1= 26 ;MAINTENANCE REGISTER 1 RMECPS= 30 ;ECC POSITION RMECPT= 32 ;ECC PATTERN RMMR2= 34 ;MAINTENANCE REGISTER 2 RMMR3= 36 ;MAINTENANCE REGISTER 3 ; ;**************** ; ; RMCS1 BIT ASSIGNMENTS ; SD= 1 ;SELECT DRIVE & GET STATUS WRT= 2 ;WRITE OFFSET ACK= 3 ;PACK ACKNOWLEDGE DC= 5 ;DRIVE CLEAR IE= 100 ;INTERRUPT ENABLE RDY= 200 ;CONTROLLER READY HMS= 113 ;IE + RECALIBRATE + GO OFF= 115 ;IE + OFFSET + GO BLS= 117 ;IE + SEEK + GO READ= 121 ;IE + READ + GO RDH= 125 ;IE + READ HEADER + GO WDH= 127 ;IE + WRITE HEADER + GO WCK= 131 ;IE + WRITE CHECK + GO CERR= 100000 ;CONTROLLER ERROR/CONTROLLER CLEAR DI= 040000 ;DRIVE INTERRUPT DCPAR= 020000 ;DRIVE TO CONTROLLER PARITY ERROR CTO= 004000 ;CONTROLLER TIMEOUT CDT= 002000 ;CONTROLLER DRIVE TYPE ; ;**************** ; ; RMCS2 BIT ASSIGNMENTS ; DLT= 100000 ;DATA LATE WCE= 040000 ;WRITE CHECK ERROR UPE= 020000 ;UNIBUS PARITY NED= 010000 ;NON EXISTANT DISK NEM= 004000 ;NON EXISTANT MEMORY PGE= 002000 ;PROGRAMMING ERROR MDS= 001000 ;MULTIPLE DRIVE SELECT UFE= 000400 ;UNIT FIELD ERROR SCLR= 000040 ;RESET CONTROLLER AND ALL DRIVES ; ;**************** ; ; RMDS BIT ASSIGNMENTS ; SVAL= 100000 ;STATUS VALID DDT= 000400 ;DISK DRIVE TYPE DRDY= 000200 ;DRIVE READY VV= 000100 ;VOLUME VALID DRA= 000001 ;DRIVE AVAILABLE ; ;**************** ; ; RMER BIT ASSIGNMENTS ; DCK= 100000 ;DATA CHECK ERROR UNS= 040000 ;DRIVE UNSAFE OPI= 020000 ;OPERATION INCOMPLETE DTE= 010000 ;DRIVE TIMING ERROR WLE= 004000 ;WRITE LOCK ERROR IDAE= 002000 ;INVALID DISK ADDRESS COE= 001000 ;CYLINDER OVERFLOW HVRC= 000400 ;HEADER VRC ERROR BSE= 000200 ;BAD SECTOR ERROR ECH= 000100 ;ERROR CORRECTION HARD FMTE= 000020 ;FORMAT ERROR CDPAR= 000010 ;CONTROLLER TO DRIVE PARITY ERROR NXF= 000004 ;NON-EXECUTABLE FUNCTION SKI= 000002 ;SEEK INCOMPLETE ILF= 000001 ;ILLEGAL FUNCTION ; ;****************  ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES ; THESE ARE INDEXED BY THE CONTROLLER NUMBER ; CNTBL: .BLKW R$$611 ;ADRS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$611 ;RETRY COUNT FOR CURRENT OPERATION .IF GT R$$611-1 TEMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS ; ; DIAGNOSTIC FUNCTION TABLE ; FUNTBL: .BYTE HMS, IO.HMS!IQ.UMD&377 .BYTE BLS, IO.BLS!IQ.UMD&377 .BYTE OFF, IO.OFF!IQ.UMD&377 .BYTE RDH, IO.RDH!IQ.UMD&377 .BYTE WDH, IO.WDH!IQ.UMD&377 .BYTE WCK, IO.WCK!IQ.UMD&377 FUNTBE: .ENDC .IF DF R$$6OF ; ; OFFSET POSITIONING DATA ; OFFTB: ;POSITIONING VALUE TABLE .BYTE 000 ;RETURN TO CENTERLINE .BYTE 020 ; +400 .BYTE 220 ; -400 .BYTE 040 ; +800 .BYTE 240 ; -800 .BYTE 060 ; +1200 .BYTE 260 ; -1200 OFFTBE: .BYTE 000 ;RETURN TO CENTERLINE ; OFFAD: .BLKW R$$611 ;ADRS OF CURRENT OFFSET VALUE .ENDC ; ;**************** ; ;DRIVER DISPATCH TABLE ; $DMTBL::.WORD DMINI ;DEVICE INITIATOR ENTRY POINT .WORD DMCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DMOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DMPWF ;POWERFAIL ENTRY POINT ; ;**************** ; ;+ ; **-DMINI-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO ; PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER ; IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ; ELSE A RETURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT ; IS SUCCESSFUL, THEN THE NEXT I/O OPERATION IS INITIATED. A RETURN ; TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; R5= ADRS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS ; WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE ; DRIVER INITIATES THE REQUESTED I/O FUNCTION ;- .ENABL LSB 10$: RETURN ;RETURN TO CALLER ; PJC038 DMINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS ;**-1 BCS 10$ ;IF CS, CONTROLLER IS BUSY OR NO REQUEST; PJC038 ; ;**-1 ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1= ADRS OF THE I/O REQUEST PACKET ; R2= PHYSICAL UNIT NUMBER OF THE REQUESTED DRIVE ; R3= CONTROLLER INDEX ; R4= ADRS OF THE STATUS CONTROL BLOCK (SCB) ; R5= ADRS OF THE UCB OF THE DRIVE TO BE INITIATED ; ; RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER I/O REQUEST PACKET FORMAT ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD. 02 -- ADRS OF THE TCB OF THE REQUESTOR TASK ; WD. 03 -- POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER ; WD. 04 -- CONTENTS OF FIRST LUN WORD (UCB ADRS) ; WD. 05 -- I/O FUNCTION CODE ; WD. 06 -- VIRTUAL ADRS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADRS (REAL OR DISPL.+140000) ; WD. 11 -- VIRTUAL ADRS OF AST SERVICE ROUTINE ; WD. 12 -- MEMORY EXTENSION BITS OF I/O TRANSFER ; WD. 13 -- BUFFER ADRS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED ; WD. 15 -- DIAGNOSTIC SUPPLIMENTAL PARAMETER OR TEMP. STORAGE ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE IS NOT USED ; WD. 17 -- LOW PART OF LOGICAL BLK NUMBER OF I/O REQUEST ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK ADRS ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; ;**************** ; ; THIS SECTION CALCULATES THE ACTUAL DISK ADDRESS FROM THE ; LOGIGAL BLOCK INFORMATION SUPPLIED IN THE I/O PACKET. IT ALSO ; DETERMINES THE FUNCTION TO PERFORM (DIAGNOSTIC OR READ/WRITE). ; MOV R5,CNTBL(R3) ;SAVE ADRS OF REQUEST UCB .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP 11/70 UNIBUS MAPPING ADRS .ENDC .IF DF M$$MGE ASL U.BUF(R5) ;POSITION EXTENDED MEMORY BITS ASL U.BUF(R5) ASL U.BUF(R5) ASL U.BUF(R5) .ENDC .IF DF D$$IAG 20$: CMPB #>,I.FCN+1(R1) ;DIAGNOSTIC FUNCTION? ; PJC038 BNE 40$ ;IF NE NO ; PJC038 MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE ;**-2 30$: MOVB (R0)+,U.BUF(R5) ;LOAD CONTROLLER FUNCTION CODE ; PJC038 CMPB (R0)+,I.FCN(R1) ;IS IT THE CORRECT CODE? ;**-1 BEQ 60$ ;IF EQ YES ; PJC038 CMP #FUNTBE,R0 ;END OF FUNCTION TABLE? ;**-1 BNE 30$ ;IF NE NO ; PJC038 ;**-1 .ENDC 40$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION ; PJC038 MOVB #READ,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION ;**-1 CMPB #>,I.FCN+1(R1) ;REALLY? BHIS 50$ ;IF HIS FUNCTION IS LEGAL ; PJC038 JMP 310$ ;FUNCTION IS ILLEGAL ; PJC038 50$: BEQ 60$ ;IF EQ FUNCTION WAS A READ ; PJC038 ADD #WRT,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION ;**-3 60$: MOV #RETRY,RTTBL(R3) ;SET INITIAL RETRY COUNT ; PJC038 ;**-1 .IF DF R$$6OF CALL 530$ ;RESET OFFSET RECOVERY VALUES ; PJC038 ;**-1 .ENDC CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER CMPB #IO.WLB/^D<256>,I.FCN+1(R3) ;WRITE FUNCTION? BNE 70$ ;IF NE NO ; PJC038 BITB #IO.WLT&377,I.FCN(R3) ;OK TO WRITE ON LAST TRACK? ;**-1 BNE 70$ ;IF NE YES ; PJC038 MOV R0,I.PRM+6(R3) ;YES, SAVE STARTING BLOCK NUMBER ;**-1 ADD #^D<22>,I.PRM+12(R3) ;ADD 1 TRACK'S WORTH OF BLOCKS CALL $BLKC1 ;CHECK IF WRITE ON LAST TRACK OF DISK MOV I.PRM+6(R3),R0 ;RESTORE ORIGINAL STARTING BLOCK NUMBER 70$: MOV #^D<22>*3,R1 ;SET DIVISOR=BLOCKS PER CYLINDER ; PJC038 CALL $DIV ;FIND CYLINDER ADDRESS (R0=LBN) ;**-1 MOV R0,I.PRM+10(R3) ;SAVE DESIRED CYLINDER ADRS MOV R1,R0 ;SET DIVIDEND=TRACK/SECTOR (REMAINDER) MOV #^D<22>,R1 ;SET DIVISOR=BLOCKS PER TRACK CALL $DIV ;FIND TRACK AND SECTOR ADDRESS SWAB R0 ;SWAP TRACK TO HIGH BYTE BIS R1,R0 ;MERGE SECTOR WITH TRACK MOV R0,I.PRM+12(R3) ;SAVE TRACK AND SECTOR ADRS ; ; THIS NEXT SECTION WILL INITIATE THE I/O OPERATION ; DMINIO: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $MPUBM ;MAP 11/70 UNIBUS TO TRANSFER .ENDC 80$: CLRB U.CW2+1(R5) ;CLEAR ALL POSITIONING OPERATION FLAGS ; PJC038 MOV S.CSR(R4),R2 ;GET CSR ADRS ;**-1 MOV S.PKT(R4),R3 ;GET ADRS OF I/O PACKET MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT COUNT ADD #RMCS2,R2 ;POINT TO RMCS2 MOV #SCLR,(R2) ;CLEAR CONTROLLER AND INIT ALL DRIVES MOVB U.UNIT(R5),R0 ;FETCH DRIVE UNIT NUMBER MOV R0,(R2) ;SELECT THE DRIVE MOV I.PRM+12(R3),-(R2) ;SET TRACK AND SECTOR ADRS MOV U.BUF+2(R5),-(R2) ;SET USER BUFFER ADRS MOV U.CNT(R5),-(R2) ;SET BYTES TO TRANSFER ROR (R2) ;MAKE THAT WORDS TO TRANSFER NEG (R2) ;MAKE IT A NEGATIVE WORD COUNT TST -(R2) ;POINT TO CSR MOV #ACK,R0 ;GET PACK ACKNOWLEDGE FUNCTION CALL XCUTE ;EXECUTE PACK ACK TO SET VV ; PJC038 90$: TSTB (R2) ;WAIT FOR THE SERIAL MESSAGE ... ; PJC038 BPL 90$ ;... TO RETURN ; PJC038 MOV #IE.DNR&377,R0 ;ASSUME SELECTED UNIT NOT READY ;**-3 MOV I.PRM+10(R3),RMDC(R2) ;SET CYLINDER ADDRESS MOV RMDS(R2),R1 ;GET CURRENT DRIVE STATUS COM R1 ;COMPLEMENT STATUS BIT #SVAL!DRDY!VV!DRA,R1 ;DRIVE READY? BNE 100$ ;IF NE NO ; PJC038 BIT #UNS,RMER(R2) ;DRIVE UNSAFE? ;**-1 BEQ 120$ ;IF EQ NO ; PJC038 100$: ;REF LABEL ; PJC038 ;**-2 .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 150$ ;IF NE YES ; PJC038 ;**-1 .IFTF .IF DF D$$IAG CALL DMDINT ;TEST FOR DIAGNOSTIC DRIVE NOT READY BCS 110$ ;IF CS DIAGNOSTIC ; PJC038 ;**-1 .ENDC .IF DF E$$DVC CALL DMDVER ;LOG DRIVE NOT READY ERROR .ENDC 110$: JMP 290$ ;FINISH I/O ; PJC038 120$: ;REF LABEL ; PJC038 ;**-2 .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC .IF DF D$$IAG CMPB U.BUF(R5),#BLS ;IS THIS A POSITIONING FUNCTION? BHI 130$ ;IF HI NO ; PJC038 BISB #POP!OFM,U.CW2+1(R5) ;ASSUME OFFSET OR POSITIONING OPER; RP020 CMPB U.BUF(R5),#OFF ;IS IT AN OFFSET OPERATION? ; RP020 BNE 130$ ;IF NE NO ; PJC038 MOV I.PRM+6(R3),RMOF(R2) ;YES, SET OFFSET VALUE ;**-4 130$: ;REF LABEL ; PJC038 ;**-1 .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC 140$: MOV U.BUF(R5),R0 ;;;GET FUNCTION AND MEMORY BITS ; PJC038 CALLR XCUTE ;;;SET CDT, LOAD FUNCTION AND GO ; PJC038 ;**-2 ;+ ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ;- DMCAN: RETURN ;;;NOP FOR THE RK611 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DMPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS DRIVE CURRENTLY BUSY? BEQ 160$ ;IF EQ NO ; PJC038 150$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC038 160$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ; PJC038 ;**-4 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DMINT-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER ; INTERRUPT AND ERROR SERVICE ROUTINES ; ; HARD ERRORS ---> $IODON ; SOFT ERRORS ---> RETRY LAST FUNCTION ; DATA ERRORS ---> RETRY FUNCTION AND CORRECT IF POSSIBLE ;- INTSE$ DM,PR5,R$$611 ;;;SAVE REGISTERS AND SET PRIORITY MOV R3,-(SP) ;;;SAVE REGISTER 3 MOV U.SCB(R5),R3 ;;;GET ADDRESS OF SCB MOV S.CSR(R3),R3 ;;;GET ADDRESS OF CSR BITB #POP,U.CW2+1(R5) ;;;POSITIONING OPERATION? ; RP020 BEQ 170$ ;;;IF EQ NO ; PJC038 BIT #CERR!DI,(R3) ;;;POSITIONING COMPLETE OR ERROR? ;**-2 BNE 170$ ;;;IF NE YES ; PJC038 MOV (SP)+,R3 ;;;RESTORE R3 ;**-1 RETURN ;;;WAIT FOR POSITIONING TO COMPLETE 170$: BIC #CERR!IE,(R3) ;;;KILL IE WITHOUT HURTING CERR ; PJC038 MOV (SP)+,R3 ;;;RESTORE R3 ;**-2 CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADRS OF SCB MOV S.CSR(R4),R2 ;GET CSR ADDRESS TST (R2) ;ERRORS ALREADY PRESENT? BMI 180$ ;IF MI YES, FORGET STATUS UPDATE ; PJC038 TST RMDS(R2) ;IS THE CURRENT STATUS VALID? ;**-1 BMI 180$ ;IF MI YES ; PJC038 CALL 560$ ;NO, SELECT DRIVE TO GET FRESH STATUS ; PJC038 180$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER ; PJC038 ;**-3 .IF DF D$$IAG CALL DMDINT ;PROCESS DIAGNOSTIC INTERRUPT BCS 260$ ;IF CS, INTERRUPT PROCESSING COMPLETE ; PJC038 ;**-1 .ENDC BITB #OFM,U.CW2+1(R5) ;OFFSET POSITIONING OPERATION? ; RP020 BEQ 190$ ;IF EQ NO ; PJC038 MOVB U.CW2+1(R5),R0 ;GET POSITIONING FLAGS ; RP020 COM R0 ;TOGGLE THEM ; RP020 BIT #OFM!RCL,R0 ;IN OFFSET MODE AND DOING A RECAL? ; RP020 BNE 210$ ;IF NE NO ; PJC038 CLR R0 ;GET READY FOR THE BISB ; RP020 BISB RTTBL+1(R3),R0 ;RETRIEVE ERROR/SUCCESS CODE (?) ; RP020 BICB #OFM!RCL,U.CW2+1(R5) ;CLEAR FLAGS ; RP020 JMP DMDONE ;NOW SAY GOOD-BYE ; RP020 190$: TST (R2) ;ANY ERRORS? ; PJC038 BPL 240$ ;IF PL NO ; PJC038 ;**-4 .IF DF E$$DVC CALL DMDVER ;YES, LOG THE DEVICE ERROR .ENDC MOV RMER(R2),R1 ;COPY ERROR REGISTER BITS MOV #IE.WLK&377,R0 ;ASSUME WRITE LOCK ERROR BIT #WLE,R1 ;WRITE LOCK ERROR? BNE 200$ ;IF NE YES ; PJC038 MOV #IE.BBE&377,R0 ;ASSUME BAD BLOCK ERROR ;**-1 BIT #BSE,R1 ;BAD BLOCK ERROR? BNE 200$ ;IF NE YES ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ;**-1 BIT #UNS!DTE!IDAE!COE!FMTE!NXF!ILF,R1 ;HARD ERROR? BNE 200$ ;IF NE YES ; PJC028 BIT #UPE!NED!NEM!PGE!MDS!UFE,RMCS2(R2) ;HARD ERROR? ;**-1 BNE 200$ ;IF NE YES ; PJC028 MOV S.PKT(R4),R3 ;RETREIVE I/O PACKET ADDRESS ;**-1 BITB #IQ.X,I.FCN(R3) ;INHIBIT RETRIES? BNE 290$ ;IF NE YES, FINISH UP ; PJC038 JMP 320$ ;NO, TRY FOR SOFT/DATA ERRORS ; PJC038 200$: BR 290$ ;FINISH UP ; PJC038 210$: MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ; PJC038 ;**-3 .IF DF R$$6OF BITB #RCL,U.CW2+1(R5) ;RECALIBRATE FUNCTION? ; RP020 BEQ 220$ ;IF EQ NO ; PJC038 ;**-2 .IFTF TST (R2) ;ERRORS DURING RECALIBRATE? BPL 280$ ;IF PL NO ; PJC038 BR 290$ ;YES, FINISH UP ; PJC038 ;**-2 .IFT 220$: CMP #OFFTBE,OFFAD(R3) ;FINAL OFFSET TRIED? ; PJC038 BEQ 290$ ;IF EQ YES, ALL DONE ; PJC038 TST (R2) ;ERRORS ATTEMPTING TO OFFSET HEADS? ;**-2 BMI 280$ ;IF MI YES ; PJC038 ;**-1 .ENDC 230$: ;REF LABEL ; PJC038 ;**-1 .IF DF E$$DVC CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 ;**-1 .ENDC JMP DMINIO ;RETRY ORIGINAL FUNCTION 240$: ;REF LABEL ; PJC038  ;**-1 .IF DF D$$WCK MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK? ; PJC002 BNE 250$ ;IF NE YES ; PJC038 BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR? ;**-2 BEQ 260$ ;IF EQ NO ; PJC038 250$: CMPB #READ,U.BUF(R5) ;WAS LAST FUNCTION A READ? ; PJC038 BEQ 260$ ;IF EQ YES ; PJC038 CMPB #READ+WRT,U.BUF(R5) ;WAS LAST FUNCTION A WRITE? ;**-3 BNE 260$ ;IF NE NO ; PJC038 MOVB #WCK,U.BUF(R5) ;SET WRITE CHECK FUNCTION ;**-1 MOV #RETRY,RTTBL(R3);REINITIALIZE RETRY COUNT BR 230$ ;START WRITE CHECK OPERATION ; PJC038 ;**-1 .ENDC 260$: CLR U.CNT(R5) ;NO ERRORS, SET ALL BYTES TRANSFERRED ; PJC038 JMP DMDONE ;FINISH I/O ; RP020 ;**-2 ;+ ; **-DMOUT-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER ; DEVICE TIMEOUT ROUTINE ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE OPERATION WAS DIAGNOSTIC. TIMEOUTS ARE USUALLY CAUSED ; BY POWER FAILURE BUT MAY ALSO BE THE RESULT OF NO RESPONSE ; FROM THE HARDWARE. ;- DMOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 270$ ;;;IF EQ NO ; PJC038 INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #16.,S.STS(R4) ;;;HAVE WE WAITED 1 MINUTE YET? ; PJC029 BEQ 270$ ;;;IF EQ YES ; PJC038 MTPS #0 ;;;ALLOW INTERRUPTS ;**-3 JMP DMINIO ;RETRY ENTIRE OPERATION 270$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC038 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-1 .ENDC .IF DF D$$IAG CALL DMDINT ;;;TEST FOR DIAGNOSTIC TIMEOUT BCS 290$ ;IF CS IT WAS ; PJC038 ;**-1 .ENDC .IF DF E$$DVC CALL DMDVTO ;;;LOG DEVICE TIMEOUT .IFF CALL $DTOER ;;;LOG DEVICE TIMEOUT .ENDC BITB #POP,U.CW2+1(R5) ;TIMEOUT DURING POSITIONING OPERATION ; RP020 BNE 290$ ;IF NE YES ; PJC038 280$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS ; PJC038 BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? ;**-3 BNE 290$ ;IF NE YES ; PJC038 MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX ;**-1 DECB RTTBL(R3) ;RETRY FUNCTION? BGT 230$ ;IF GT YES ; PJC038 ; ;**-1 ;**************** ; ; AT THIS POINT ALL I/O IS FINISHED. WE WILL CALCULATE THE ; BYTES ACTUALLY TRANSFERED AND SET THE ERROR LOGGING RETRY COUNTS. ; THEN $IODON IS CALLED TO TERMINATE THE I/O OPERATION. ; 290$: ;REF LABEL ; PJC038 ;**-1 .IF DF D$$WCK BIT #WCE,RMCS2(R2) ;WRITE CHECK ERROR? BEQ 300$ ;IF EQ NO ; PJC038 MOV #IE.WCK&377,R0 ;SET WRITE CHECK ERROR ;**-1 .ENDC 300$: MOV RMWC(R2),R1 ;GET RESIDUAL WORD COUNT ; PJC038 ASL R1 ;CONVERT TO BYTE COUNT ;**-1 NEG R1 ;CONVERT TO POSITIVE BYTES REMAINING MOV R1,U.CNT(R5) ;SAVE BYTES REMAINING TO TRANSFER BITB #OFM,U.CW2+1(R5) ;IN OFFSET MODE? ; RP020 BEQ DMDONE ;IF EQ NO ; RP020 MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX ; RP020 MOVB R0,RTTBL+1(R3) ;SAVE ERROR/SUCCESS CODE ; RP020 BR 340$ ;NOW DO A RECALIBRATE  ; PJC038 DMDONE: ;REF LABEL ; RP020 ;**-1 .IF DF E$$DVC CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX ;**-1 MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #>,R2 ;MERGE STARTING RETRY COUNT .ENDC 310$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS ; PJC038 MOV I.PRM+4(R1),R1 ;GET ACTUAL BYTES TO TRANSFER ;**-1 SUB U.CNT(R5),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED CALL $IODON ;FINISH I/O OPERATION JMP DMINI ;PROCESS NEXT REQUEST ; ;**************** ; 320$: BIT #WCE,RMCS2(R2) ;WRITE CHECK ERROR? ; PJC038 BNE 280$ ;IF NE YES ; PJC038 ; PJC030 ; PJC030 .IF DF R$$6OF ; PJC030 ; PJC030 TST RMCS2(R2) ;DATA LATE ERROR? ; PJC030 BPL 330$ ;IF PL NO ; PJC038 JMP DMDLT ;YES ; PJC030 ; PJC030 .ENDC ; PJC030 ; PJC030 ; PJC030 330$: BIT #DCPAR!CTO,(R2) ;CONTROLLER TIMEOUT OR PARITY ERROR? ; PJC038 BNE 280$ ;IF NE YES ; PJC038 BIT #CDPAR,R1 ;CONTROLLER TO DRIVE PARITY ERROR? ;**-4 BNE 280$ ;IF NE YES ; PJC038 BIT #OPI!SKI,R1 ;DRIVE POSITIONING ERROR? ;**-1 BEQ 360$ ;IF EQ NO ; PJC038 ;**-1 .IF DF E$$DVC CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 ;**-1 .ENDC CALL 590$ ;CLEAR CONTROLLER ; PJC038 CALL 550$ ;ISSUE DRIVE CLEAR FUNCTION ; PJC038 340$: MOV #HMS,R0 ;SET RECALIBRATE FUNCTION ; PJC038 BISB #RCL,U.CW2+1(R5) ;INDICATE RECALIBRATE OPERATION ; PJC038 350$: MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT ; PJC038 CALLR XCUTE ;ISSUE FUNCTION ; PJC038 360$: ;REF LABEL ; PJC038 ;**-7 .IF DF R$$6OF BIT #HVRC,R1 ;HEADER VRC ERROR? BNE DMECC ;YES, DO ECC .IFTF TST R1 ;DATA CHECK ERROR? BPL 280$ ;IF PL NO, MUST BE SOFT ERROR ; PJC038 ;**-1 .IFF BIT #ECH,R1 ;ECC HARD ERROR? BNE 280$ ;IF NE YES, RETRY IT ; PJC038 ;**-1 .ENDC ; ; START ECC CORRECTION PROCEDURE ; RP041 ; ;**-11 DMECC: CMPB #READ,U.BUF(R5) ;IS THIS A READ OPERATION? BNE 280$ ;IF NE NO ; PJC038 MOV S.PKT(R4),R3 ;RETRIEVE I/O PACKET ADDRESS ; RP020 BITB #IQ.X,I.FCN(R3) ;INHIBIT RETRIES? ; RP020 BNE 290$ ;IF NE YES ; PJC038 MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX ; PJC038 DECB RTTBL(R3) ;RE-READ THE DATA? ; PJC038 BLE 370$ ;IF LE NO ; PJC038 JMP 230$ ;YES ; PJC038 370$: MOVB #RETRY,RTTBL(R3) ;RESET RETRY COUNT ; PJC038 MOV RMWC(R2),R0 ;GET NEGATIVE WORDS REMAINING ; RP041 ASL R0 ;CONVERT TO BYTES ; RP041 ADD U.CNT(R5),R0 ;CALCULATE BYTES ACTUALLY TRANSFERRED ; RP041 ; RP041 ; RP041 .IF DF R$$6OF ; RP041 ; RP041 BEQ DMOFST ;IF EQ NONE TRANSFERRED ; RP041 ; RP041 .IFF ;R$$6OF ; RP041 ; RP041 BEQ 280$ ;IF EQ NONE TRANSFERRED ; PJC038 ; RP041 .ENDC ;R$$6OF ; RP041 ; RP041 ; RP041 CMP #DCK,R1 ;ONLY DATA CHECK ERROR? ; RP041 ; RP041 .IF DF R$$6OF ; RP041 ; RP041 BNE DMOFST ;IF NE NO ; RP041 ; RP041 .IFF ;R$$6OF ; RP041 ; RP041 BNE 280$ ;IF NE NO ; PJC038 ; RP041 .ENDC ;R$$6OF ; RP041 ; RP041 ; RP041 MOV R2,-(SP) ;SAVE CORE BLOCK ADDRESS ; PJC041 MOV RMECPS,R1 ;GET ECC ERROR POSITION ; RP041 MOV RMECPT,R3 ;GET ECC CORRECTION PATTERN ; RP041 MOV RMWC(R2),R2 ;GET REMAINING WORD COUNT ; RP041  ;**-1 .IF DF S$$ECC CALL $ECCOR ;CALL SHARED ECC ROUTINE ;**-2 ;**-8 .IFF MOV R0,-(SP) ;SAVE BYTE COUNT ; RP041 CLR R0 ;CLEAR HIGH ORDER ERROR POSITION ; RP041 DEC R1 ;CONVERT TO RELATIVE BIT NUMBER ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 DIV #20,R0 ;DIVIDE FOR: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 ; RP041 .IFF ;M$$EIS ; RP041 ; RP041 MOV R1,R0 ;COPY ECC ERROR POSITION ; RP041 MOV #20,R1 ;SET DIVISOR TO CALCULATE: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 CALL $DIV ;PERFORM DIVISION ; RP041 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 MOV R0,-(SP) ;SAVE WORD POSITION ; RP041 MOV R2,-(SP) ;SAVE REMAINING WORD COUNT ; RP041 CLR R2 ;CLEAR HIGH ORDER ERROR PATTERN ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 380$: ASHC R1,R2 ;SHIFT PATTERN INTO CORRECT POSITION ; PJC038 ; RP041 .IFF ;M$$EIS ; RP041 ; RP041 380$: DEC R1 ;ANY MORE SHIFTS LEFT TO PERFORM ; PJC038 BLT 390$ ;IF LT NO ; PJC038 ASL R3 ;DOUBLE LEFT SHIFT ; RP041 ROL R2 ; ; RP041 BR 380$ ; ; PJC038 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 390$: MOV 4(SP),R0 ;RETRIEVE ACTUALL BYTE TRANSFERRED ; PJC038 SUB #510.,R0 ;BACKUP TO BLOCK IN ERROR ... ; RP041 ;... OFFSET TO HIGH WORD IN ERROR ; RP041 ; RP041 ; RP041 .IF DF D$$IAG ; RP041 ; RP041 CALL $RELOP ;COMPUTE LOCATION IN PHYSICAL MEMORY ; RP041 ; RP041 .IFF ;D$$IAG ; RP041 ; RP041 MOV R0,-(SP) ;SAVE BYTE OFFSET ON STACK ; RP041 MOV U.BUF+2(R5),R1 ;GET LOW 16 BITS OF ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 MOVB U.BUF+1(R5),R0 ;GET HIGH BITS OF REAL ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$EXT ; RP041 ; RP041 ADD #,R4 ;POINT PAST PHYSICAL BUFFER ADDRESS ; RP041 ;CONTAINED IN UMR AREA ; RP041 MOV -(R4),R1 ;GET LOW 16 BITS OF PHYSICAL BUFFER ADDR; RP041 TSTB -(R4) ;SKIP NEXT BYTE ; RP041 MOVB -(R4),R0 ;GET HIGH 6 BITS OF PHYSICAL BUFFER ADDR; RP041 MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; RP041 ; RP041 .ENDC ;M$$EXT ; RP041 ; RP041 ; RP041 .IFF ;M$$MGE ; RP041 ; RP041 CLR R0 ; ; RP041 ; RP041 .ENDC ;M$$MGE ; RP041 ; RP041 ; RP041 400$: ADD (SP)+,R1 ;CALCULATE NEW STARTING ADDRESS ... ; PJC038 ADC R0 ;... ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ; RP041 ASHC #-10.,R1 ;... ; RP041 ; RP041  .IFF ;M$$EIS ; RP041 ; RP041 MOV #10.,-(SP) ;SET COUNT FOR 10 SHIFTS ; RP041 410$: DEC (SP) ;ANY MORE SHIFTS TO PERFORM ; PJC038 BLT 420$ ;IF LT NO ; PJC038 ASL R1 ;DOUBLE LEFT SHIFT R1 ... ; RP075 ROL R0 ;... INTO R0 ; RP075 BR 410$ ; ; PJC038 420$: SWAB R1 ;SWAP BYTES ; PJC038 ASR R1 ;SHIFT RIGHT R1 ; RP075 ASR R1 ;... ; RP075 TST (SP)+ ;CLR THE STACK ; RP075 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 MOV R0,KISAR6 ;SET RELOCATION BIAS ; RP041 ADD #140000,R1 ;SET DISPLACEMENT ; RP041 ; RP041 .ENDC ;M$$MGE ; RP041 ; RP041 ; RP041 .ENDC ;D$$IAG ; RP041 ; RP041 ; RP041 MOV (SP)+,R0 ;RETRIEVE REMAINING WORD COUNT ; RP041 BPL 430$ ;IF PL, THIS MAY HAVE BEEN A PARTIAL BLO; PJC038 ;TRANSFER ; PJC038 CLR R0 ;ASSUME A WHOLE BLOCK WAS TRANSFERRED ; RP041 430$: ADD (SP),R1 ;ADD IN ERROR WORD POSITION OFFSET ... ; PJC038 ADD (SP),R1 ;... FOR BYTE ADDRESSING ; RP041 ADD (SP)+,R0 ;ADD CORECTION OFFSET TO CORRECTION LIMI; RP041 CMP R0,#377 ;IS THE CORRECTION ENTRELY IN THIS BLOCK; RP041 BHI 450$ ;IF HI, NOT AT ALL ; PJC038 BEQ 440$ ;IF EQ, THEN ONLY ONE WORD ; PJC038 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 XOR R2,(R1) ;CORRECT HIGH ORDER WORD ; RP041 440$: XOR R3,-(R1) ;CORRECT LOW ORDER WORD ; PJC038 ; RP041 .IFF ;M$$EIS ; RP041  ; RP041 MOV (R1),R0 ;COPY HIGH ORDER DATA WORD ; RP041 BIC R2,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R2 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R2,(R1) ;PATTERN.OR.DATA WORD ; RP041 440$: MOV -(R1),R0 ;COPY LOW ORDER DATA WORD ; PJC038 BIC R3,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R3 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R3,(R1) ;PATTERN.OR.DATA WORD ; RP041 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 450$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER ; PJC038 MOV (SP)+,R1 ;RESTORE BYTES TRANSFERRED ; RP041 MOV S.CSR(R4),R2 ;RESTORE CSR ADDRESS ; RP041 MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX ; RP041 ;**-49 .ENDC .IF DF R$$6OF CALL 530$ ;RESET OFFSET RECOVERY PARAMETERS ; PJC038 ;**-1 .ENDC MOV (SP)+,R2 ;GET CORE BLOCK ADDRESS ; PJC041 SUB R1,U.CNT(R5) ;ANY MORE BYTES TO TRANSFER? BNE 460$ ;IF NE YES ; PJC038 JMP 290$ ;NO ; PJC038 460$: ;REF LABEL ; PJC038 ;**-1 .IF DF M$$MGE MOV (R2),R1 ;RETREIVE RMCS1 CONTENTS SWAB R1 ;REPOSITION BYTES BICB #^C<3>,R1 ;ISOLATE MEMORY EXTENSION BITS MOVB R1,U.BUF+1(R5) ;SAVE FOR NEXT FUNCTION .ENDC MOV RMBA(R2),U.BUF+2(R5) ;SAVE BUFFER ADRS MOV S.PKT(R4),R1 ;GET ADRS OF I/O PACKET MOV RMDC(R2),I.PRM+10(R1) ;SAVE CYLINDER ADRS MOV RMDA(R2),I.PRM+12(R1) ;SAVE TRACK/SECTOR ADRS .IF DF E$$DVC CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 ;**-1 .IFTF CALL 590$ ;CLEAR CONTROLLER ; PJC038 CALL 550$ ;ISSUE DRIVE CLEAR FUNCTION ; PJC038 MOV U.BUF+2(R5),RMBA(R2) ;SET PREVIOUS BUFFER ADDRESS ;**-2 .IFT MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS .ENDC MOV I.PRM+10(R1),RMDC(R2) ;SET PREVIOUS CYLINDER ADDRESS MOV I.PRM+12(R1),RMDA(R2) ;SET PREVIOUS DISK ADDRESS JMP 140$ ;RESTART FROM WHERE WE LEFT OFF ; PJC038 ;**-1 .IF DF R$$6OF ;**-71 ;+ ; OFFSET POSITIONING READ RECOVERY ; ; THE TRANSFER ENDED IN AN ECC HARD ERROR BUT THERE WERE SECTORS ; TRANSFERED THAT CONTAINED GOOD DATA. SINCE THE ECC HARD ERROR ; COULD HAVE BEEN CAUSED BY A CYLINDER CROSSING, THE GOOD DATA IS ; SAVED AND THE TRANSFER IS RETRIED FROM THE POINT OF ERROR. ;- DMOFST: TST R0 ;ANY GOOD SECTORS TRANSFERRED? ; RP020 BEQ 490$ ;IF EQ NO ; PJC038 SUB R0,U.CNT(R5) ;REDUCE BYTES REMAINING TO TRANSFER ; RP021 BNE 470$ ;IF NE, MORE SECTORS TO TRANSFER ; PJC038 ADD R0,U.CNT(R5) ;LAST SECTOR TO TRANSFER, CORRECT BYTES ; RP021 BR 500$ ;AND CONTINUE ; PJC038 470$: ADD R0,U.BUF+2(R5) ;UPDATE STARTING BUFFER ADRS ; PJC038 ADCB U.BUF+1(R5) ;PROPAGATE CARRY INTO EXTENSION BITS ; RP021 SWAB R0 ;CALCULATE THE NUMBER OF... ;**-6 ASR R0 ;...SECTORS TRANSFERED CALL DMCALC ;UPDATE THE DISK ADDRESS ; PJC030 480$: CALL 540$ ;RESET OFFSET TABLE ADRS ; PJC038 BR 500$ ; ; PJC038 ; ;**-14 ; NO GOOD DATA WAS TRANSFERED SO CHECK TO SEE IF THE OFFSET ; FROM TRACK CENTERLINE SHOULD BE CHANGED. ; 490$: DECB RTTBL+1(R3) ;CHANGE OFFSET? ; PJC038 BGT 520$ ;IF GT NO ; PJC038 MOVB #OFFTRY,RTTBL+1(R3) ;SET RECOVERY RETRY COUNT ;**-2 500$: INC OFFAD(R3) ;UPDATE OFFSET POINTER ; PJC038 ;**-1 .IF DF E$$DVC CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 ;**-1 .ENDC MOVB @OFFAD(R3),R0 ;GET NEXT OFFSET VALUE BNE 510$ ;IF NE, NOT RETURNING TO CENTERLINE ; PJC038 MOVB #RETRY*2,RTTBL+1(R3) ;TRY 16 TIMES AT CENTERLINE ;**-1 510$: CALL 590$ ;CLEAR CONTROLLER ; PJC038 CALL 550$ ;ISSUE DRIVE CLEAR FUNCTION ; PJC038 MOV R0,RMOF(R2) ;LOAD NEXT OFFSET VALUE ;**-2 MOV #OFF,R0 ;SET OFFSET FUNCTION BISB #OFS!OFM,U.CW2+1(R5) ;INDICATE OFFSET FUNCTION ; RP020 JMP 350$ ; ; PJC038 520$: JMP 230$ ;RETRY FUNCTION ; PJC038 ; ;**-2 ;**************** ; ; RESET THE OFFSET RECOVERY PARAMETERS ; 530$: MOVB #1,RTTBL+1(R3) ;SET RECOVERY COUNT TO ONE ; PJC038 540$: MOV #OFFTB-1,OFFAD(R3) ;SET OFFSET TABLE POINTER ; PJC038 RETURN ;**-2 .ENDC ;+ ; INITIATE A CONTROLLER/DRIVE CLEAR OR SELECT DRIVE FUNCTION ; AND WAIT FOR THE SERIAL MESSAGE. ; ; NOTE: THE TIMING LOOP AT 153$ IS TO ALLOW TIME FOR THE ; SERIAL MESSAGE TO BE SENT TO THE DRIVE AND THE STATUS ; TO BE RECEIVED BY THE RK611. AVERAGE TIME = 15US. ;- 550$: MOV R0,-(SP) ;SAVE REGISTER ; PJC038 MOV #DC,R0 ;ISSUE DRIVE CLEAR FUNCTION ;**-1 BR 570$ ; ; PJC038 560$: MOV R0,-(SP) ;SAVE REGISTER ; PJC038 MOV #SD,R0 ;ISSUE SELECT DRIVE FUNCTION ;**-2 570$: CALL XCUTE ;LOAD RMCS1 ; PJC038 580$: TSTB (R2) ;WAIT FOR THE SERIAL MESSAGE ... ; PJC038 BPL 580$ ;... TO DO ITS THING ; PJC038 MOV (SP)+,R0 ;RESTORE REGISTER ;**-3 RETURN ; 590$: MOV #CERR,(R2) ;CLEAR CONTROLLER ; PJC038 MOVB U.UNIT(R5),-(SP) ;GET CURRENT UNIT NUMBER ;**-1 MOV (SP)+,RMCS2(R2) ;RE-SELECT THE UNIT RETURN XCUTE: TST U.CW3(R5) ;RK07 BLOCK NUMBER? ; PJC038 BPL 600$ ;IF PL NO, IT'S AN RK06 ; PJC038 BIS #CDT,R0 ;SET CDT FOR RK07  ;**-2 600$: MOV R0,(R2) ;EXECUTE THE FUNCTION ; PJC038 RETURN ; ;**-1 .IF DF R$$6OF ; PJC030 ; PJC030 ;+ ; PJC030 ; DATA LATE RECOVERY ; PJC030 ; ; PJC030 ; THIS ROUTINE IS ENTERED IF A DATA LATE ERROR IS DETECTED. WE WILL ; PJC030 ; BACK UP THE WORD COUNT, BUS ADDRESS AND CYLINDER/TRACK/SECTOR ; PJC030 ; ADDRESS TO THE POINT OF ERROR AND RETRY THE TRANSFER FROM THERE. THIS ; PJC030 ; IS DONE TO PREVENT A RECURRING DATA LATE ERROR DUE TO A LONG TRANSFER.; PJC030 ;- ; PJC030 DMDLT: MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX ; PJC030 DECB RTTBL(R3) ;ANY RETRIES LEFT? ; PJC030 BGT 610$ ;IF GT YES ; PJC038 JMP 300$ ;NO ; PJC038 610$: MOV RMWC(R2),R0 ;GET NEGATIVE WORDS REMAINING ; PJC038 BNE 620$ ;IF NE, WE HAD A PARTIAL TRANSFER ; PJC038 MOV #-1,R0 ;FAKE A PARTIAL TRANSFER ; PJC030 620$: ASL R0 ;CONVERT TO NEGATIVE BYTES ; PJC038 ADD U.CNT(R5),R0 ;CALCULATE BYTES ACTUALLY TRANSFERRED ; PJC030 BIC #777,R0 ;GET BLOCKS ACTUALLY TRANSFERRED ; PJC030 SUB R0,U.CNT(R5) ;REDUCE BYTES REMAINING TO TRANSFER ; PJC030 BEQ 630$ ;IF EQ, NONE LEFT ; PJC038 ADD R0,U.BUF+2(R5) ;UPDATE STARTING BUFFER ADDRESS ; PJC030 ADCB U.BUF+1(R5) ;PROPAGATE CARRY INTO EXTENSION BITS ; PJC030 ; PJC030 ; PJC030 .IF DF M$$EXT ; PJC030 ; PJC030 ADD #,R4 ;POINT PAST PHYSICAL BUFFER ADDRESS ; PJC030 ;CONTAINED IN UMR AREA ; PJC030 ADD R0,-(R4) ;CALCULATE NEW REAL ADDRESS ; PJC030 ADCB -(R4) ;... ; PJC030 MOV U.SCB(R5),R4 ;RESTORE ADDRESS OF SCB ; PJC030 ; PJC030 .ENDC ;M$$EXT ; PJC030 ; PJC030 ; PJC030 SWAB R0 ;CALCULATE THE NUMBER OF... ; PJC030 ASR R0 ;... SECTORS TRANSFERRED ; PJC030 CALL DMCALC ;UPDATE THE DISK ADDRESS ; PJC030 TST U.CNT(R5) ;LAST BLOCK TRANSFERRED? ; PJC030 BNE 640$ ;IF NE NO ; PJC038 630$: ADD R0,U.CNT(R5) ;NORMALIZE BYTE COUNT ; PJC038 640$: ;REF LABEL ; PJC038  ; PJC030 ; PJC030 .IF DF E$$DVC ; PJC030 ; PJC030 CALL 720$ ;DEALLOCATE REGISTER CORE BLOCK ; PJC038 ; PJC030 .ENDC ; PJC030 ; PJC030 ; PJC030 JMP 80$ ;FINISH THE I/O OPERATION ; PJC038 ; PJC030 ;+ ; PJC030 ; CALCULATE UPDATED DISK ADDRESS ; PJC030 ; ; PJC030 ; THIS ROUTINE WILL CALCULATE THE NEW DISK ADDRESS BASED ON THE NUMBER ; PJC030 ; OF BYTES ACTUALLY TRANSFERRED. ; PJC030 ;-  ; PJC030 DMCALC: MOV S.PKT(R4),R1 ;GET ADRS OF I/O PACKET ; PJC030 ADD I.PRM+12(R1),R0 ;UPDATE TRACK/SECTOR ADRS ; PJC030 650$: CMPB #22.,R0 ;SECTOR OVERFLOW? ; PJC038 BHI 660$ ;IF HI NO ; PJC038 SUB #22.,R0 ;SUBTRACT OUT A SECTOR ; PJC030 ADD #400,R0 ;ADD IN A TRACK ; PJC030 CMP #3*400,R0 ;TRACK OVERFLOW? ; PJC030 BHI 650$ ;IF HI NO ; PJC038 SUB #3*400,R0 ;SUBTRACT OUT A TRACK ; PJC030 INC I.PRM+10(R1) ;UPDATE CYLINDER ADRS ; PJC030 BR 650$ ; ; PJC038  660$: MOV R0,I.PRM+12(R1) ;SET UPDATED TRACK/SECTOR ADRS ; PJC038 RETURN ; ; PJC030 ; PJC030 .ENDC ;R$$6OF ; PJC030 ; PJC030 ; PJC030 .IF DF E$$DVC ;+ ; **-DMDVXX-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER ; ERROR LOGGING ROUTINES ; ; THIS ROUTINE IS CALLED WHENEVER A DEVICE ERROR OR DEVICE TIMEOUT ; OCCURS. A CORE BLOCK THE SIZE OF THE REGISTER BUFFER IS ; ALLOCATED AND THE REGISTERS (INCLUDING THE SIX EXTRA MAINTENANCE ; REGISTERS) ARE TRANSFERED INTO THE CORE BLOCK. THEN THE CSR ; ADDRESS IN THE SCB IS SET TO THE CORE BLOCK ADDRESS AND THE ; APPROPRIATE EXECUTIVE ERROR LOGGING ROUTINE IS CALLED. THE CORE ; BLOCK ADDRESS IS THEN USED AS A PSEUDO REGISTER BASE ADDRESS BY ; THE ERROR HANDLING ROUTINES. BEFORE THE NEXT FUNCTION IS ISSUED, ; THE DEALLOCATION ROUTINE AT 190$ MUST BE CALLED TO DEALLOCATE THE ; CORE BLOCK AND RESTORE THE REAL CSR BASE ADDRESS. ; ; IF FOR ANY REASON THE CORE BLOCK CANNOT BE ALLOCATED THEN ; THE EXECUTIVE ERROR LOGGING ROUTINE WILL NOT BE CALLED AND ; THE ERROR SEQUENCE NUMBER WILL BE UPDATED TO INDICATE THAT ; A MISSED ERROR CONDITION OCCURRED. ; ; NOTE: IF ENTRY IS THE RESULT OF A DEVICE TIMEOUT THEN THIS ; ROUTINE IS EXECUTED AT THE RK611 DEVICE PRIORITY LEVEL (PR5) ; UNTIL THE EXEC ERROR LOGGING ROUTINE IS CALLED. ; ; INPUTS: ; R2 = CSR ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; R2 = ADDRESS OF REGISTER CORE BLOCK IF ONE WAS ALLOCATED ; OR CSR ADDRESS IF ONE WAS NOT. ; R4 = SCB ADDRESS  ; ; R0,R3 ARE PRESERVED ACROSS CALL ;- DMDVER: MOV #$DVERR,R1 ;GET ADRS OF DEVICE ERROR ROUTINE BR 670$ ; ; PJC038 DMDVTO: MOV #$DTOER,R1 ;;;GET ADRS OF DEVICE TIMEOUT ROUTINE ;**-1 670$: MOV R3,-(SP) ;PRESERVE CONTROLLER INDEX ; PJC038 MOV R0,-(SP) ;SAVE I/O STATUS CODE ;**-1 MOV R2,-(SP) ;SAVE CSR ADDRESS MOV R1,-(SP) ;SET CO-ROUTINE ADDRESS MOV #RMCNT*2,R1 ;GET NUMBER OF BYTES TO ALLOCATE CALL $ALOCB ;ALLOCATE A CORE BLOCK BCC 680$ ;IF CC, BLOCK WAS ALLOCATED ; PJC038 INC $ERRSQ ;INDICATE A MISSED ERROR CONDITION ;**-1 CMP (SP)+,#$DTOER ;ALLOCATION FAILURE, TIMEOUT IN PROGRESS? BNE 690$ ;IF NE, DON'T LOG ERROR ; PJC038 BIC #CERR!IE,@S.CSR(R4) ;;;CLEAR IE WITHOUT DOING A CCLR ;**-1 MTPS #0 ;;;ALLOW INTERRUPTS BR 690$ ;DON'T LOG ERROR IF ALLOCATION FAILURE ; PJC038 680$: MOV R0,S.CSR(R4) ;REPLACE CSR WITH ADDRESS OF CORE BLOCK ; PJC038 MOV 2(SP),R2 ;GET REAL CSR ADDRESS ;**-2 CALL DMRPAS ;XFER THE REGISTERS CALL @(SP)+ ;CALL THE EXEC ERROR LOGGING ROUTINE MOV S.CSR(R4),R0 ;GET ADDRESS OF CORE BLOCK MOV (SP),S.CSR(R4) ;RESTORE CSR ADDRESS MOV R0,(SP) ;PUT CORE BLOCK ADRS IN SAVED CSR ADRS 690$: MOV (SP)+,R2 ;RESTORE CSR ADDRESS ; PJC038 700$: MOV (SP)+,R0 ;RESTORE I/O STATUS CODE ; PJC038 MOV (SP)+,R3 ;RESTORE CONTROLLER INDEX ;**-2 710$: RETURN ; ; PJC038 720$: CMP R2,S.CSR(R4) ;SHOULD WE DEALLOCATE? ; PJC038 BEQ 710$ ;IF EQ NO ; PJC038 MOV R3,-(SP) ;SAVE CONTROLLER INDEX ;**-4 MOV R0,-(SP) ;SAVE POSSIBLE I/O STATUS CODE MOV #RMCNT*2,R1 ;GET NUMBER OF BYTES TO DEALLOCATE MOV R2,R0 ;SET ADDRESS OF CORE BLOCK IN R0 CALL $DEACB ;DEALLOCATE THE BLOCK MOV S.CSR(R4),R2 ;RESET REAL CSR ADDRESS BR 700$ ; ; PJC038 ;**-1 .ENDC .IF DF E$$DVC!D$$IAG ;+ ; **-DMRPAS-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER ; CONTROLLER REGISTER PASS ROUTINE ; ; THIS ROUTINE WILL TRANSFER THE CONTENTS OF THE CONTROLLER ; REGISTERS (INCLUDING THE SIX EXTRA MAINTENANCE REGISTERS) ; INTO A PREVIOUSLY ALLOCATED BUFFER. ; ; INPUTS: ; R0 = BUFFER ADDRESS ; R2 = CSR ADDRESS ; R5 = UCB ADDRESS ; OUTPUTS: ; R2 = CSR ADDRESS ; R3 = DESTROYED ;- DMRPAS: MOV #^D<14>,R3 ;LOOP COUNT FOR MAJOR REGISTERS MOV R2,-(SP) ;SAVE CSR ADDRESS 730$: MOV (R2)+,(R0)+ ;TRANSFER THE REGISTER ; PJC038 DEC R3 ;HAVE TRANSFERRED ONE MORE ; PJC038 BNE 730$ ;IF NE, KEEP GOING ; PJC038 MOV (SP)+,R2 ;RESTORE CSR ADDRESS ;**-3 740$: CALL 590$ ;CLEAR CONTROLLER ; PJC038 MOV R3,RMMR1(R2) ;SELECT DRIVE SERIAL MESSAGE ;**-1 CALL 560$ ;SELECT DRIVE TO GET PROPER MESSAGE ; PJC038 MOV RMMR2(R2),(R0)+ ;SAVE CONTENTS OF MR2 ;**-1 MOV RMMR3(R2),(R0)+ ;SAVE CONTENTS OF MR3 INC R3 ;INCREMENT DRIVE SERIAL MESSAGE COUNT CMP R3,#4 ;DONE FOUR MESSAGES YET? BNE 740$ ;NO, LOOP ; PJC038 CALL 590$ ;CLEAR CONTROLLER ; PJC038 CALLR 550$ ;FINISH UP BY CLEARING THE DRIVE ; PJC038 ;**-3 .ENDC .IF DF D$$IAG ;+ ; **-DMDINT-RK611-RK06/RK07 DISK CARTRIDGE CONTROLLER ; DIAGNOSTIC INTERRUPT HANDLER ; ; THIS SUBROUTINE HANDLES INTERUPTS FROM DIAGNOSTIC OPERATIONS. ; IF THE FUNCTION WAS DIAGNOSTIC THEN THE DEVICE REGISTERS ; ARE PASSED BACK TO THE DIAGNOSTIC TASK, THE CONTROLLER (VIA DMRPAS) ; AND THE DRIVE ARE CLEARED AND THE I/O STATUS IS RETURNED. ; ; INPUTS: ; R2 = ADRS OF CSR ; R4 = ADRS OF SCB ; R5 = ADRS OF UCB ; ; OUTPUTS: ; R1 = I/O PACKET ADDRESS (IF DIAGNOSTIC FUNCTION) ; R2 = ADDRESS OF CSR ; R4 = ADDRESS OF SCB ; C = 1 IF INTERRUPT WAS FROM DIAGNOSTIC FUNCTION ; ; R0,R3 ARE PRESERVED ACROSS CALL ;- DMDINT: MOV R3,-(SP) ;PRESERVE CONTROLLER INDEX MOV S.PKT(R4),R3 ;GET ADRS OF I/O PACKET CLC ;ASSUME NOT DIAGNOSTIC INTERRUPT BITB #IQ.UMD,I.FCN(R3) ;DIAGNOSTIC FUNCTION? BEQ 770$ ;IF EQ NO, EXIT ; PJC038 MOV R0,-(SP) ;SAVE CURRENT I/O STATUS CODE ;**-1 TSTB R0 ;WAS THIS A SUCCESSFUL INTERRUPT? BPL 750$ ;IF PL YES ; PJC038 CALL $DTOER ;;;TIMEOUT, CLEAN-UP AFTER IT ;**-1 BR 760$ ;JUST PASS THE REGISTERS ; PJC038 750$: CMP #IO.RDH!IQ.UMD,I.FCN(R3) ;READ HEADERS? ; PJC038 BNE 760$ ;IF NE NO, PROCESS NORMAL ; PJC038 CLR R0 ;CLEAR BYTE OFFSET INTO BUFFER ;**-3 CALL $RELOP ;RELOCATE PHYSICAL ADDRESS MOV RMDB(R2),(R1)+ ;TRANSFER FIRST HEADER WORD MOV RMDB(R2),(R1)+ ;TRANSFER SECOND HEADER WORD MOV RMDB(R2),(R1)+ ;TRANSFER THIRD HEADER WORD 760$: MOV R3,R1 ;SAVE I/O PACKET ADDRESS ; PJC038 ;**-1 .IF DF M$$MGE MOV I.PRM+14(R3),KISAR6 ;SET BUFFER RELOCATION BIAS .ENDC MOV I.PRM+16(R3),R0 ;GET REGISTER BUFFER ADDRESS CALL DMRPAS ;PASS THE CONTROLLER REGISTERS SEC ;SET DIAGNOSTIC INTERRUPT RETURN MOV (SP)+,R0 ;RESTORE I/O STATUS CODE 770$: MOV (SP)+,R3 ;RESTORE CONTROLLER INDEX ; PJC038 RETURN ;**-1 .ENDC .DSABL LSB .END Óp:kQ ›c, .TITLE DRCIN .IDENT /02.02/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 02.02 ; ; P. WANNHEDEN 24-MAY-77 ; ; PREVIOUSLY MODIFIED BY: ; ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 1-OCT-79 ; MSH045 -- ENSURE THAT ENABLE/DISABLE ROUTINE IS CALLED ; FROM EXECUTIVE SPACE RATHER THAN DIRECTIVE ;  COMMON SPACE ; ; M. S. HARVEY 26-JUN-81 ; MSH147 -- CORRECT ERROR LOGGING CONDITIONAL SYMBOL ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,TCBDF$,PCBDF$,ITBDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS TCBDF$ ; DEFINE TCB OFFSETS PCBDF$ ; DEFINE PCB OFFSETS ITBDF$ ; DEFINE ITB OFFSETS ;+ ; **-$DRCIN-CONNECT TO INTERRUPT. ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CONNECT A SPECIFIED INTERRUPT ; VECTOR TO AN INTERRUPT SERVICE ROUTINE (ISR) IN THE TASK'S OWN SPACE, ; OR TO DISCONNECT A PREVIOUSLY CONNECTED INTERRUPT VECTOR. ; ; IF THE FUNCTION "CONNECT" IS REQUESTED, THE OPERATION IS AS FOLLOWS: ; A BLOCK OF DYNAMIC MEMORY IS ALLOCATED AND SET UP AS AN INTERRUPT ; TRANSFER BLOCK (ITB). THE ITB IS LINKED TO THE ITB LIST OF THE ; TASK WITH LISTHEAD (SINGLE WORD!!) IN T.CPCB OF THE TCB. ; CHECKPOINTING AND SHUFFLING IS DISABLED FOR THE TASK. ; THE VECTOR IS SET UP TO POINT TO THE OFFSET X.JSR IN THE ITB, ; WHICH CONTAINS A SUBROUTINE CALL TO THE SPECIAL INTERRUPT SAVE ; ROUTINE $INTSC. ; ; IF THE FUNCTION "DISCONNECT" IS REQUESTED, THE OPERATION IS ; ESSENTIALLY THE REVERSE OF WHAT IS DESCRIBED FOR "CONNECT". ; ; ************************************************* ; * NOTE - THE DISCONNECT FUNCTION, WHEN * ; * DISCONNECTING THE LAST VECTOR (OR * ; * ONLY), CLEARS THE CHECKPOINT-DISABLE * ; * BIT (T2.CKD) AND NO-SHUFFLE BIT (PS.NSF) * ; * REGARDLESS OF WHAT THE STATE WAS BEFORE * ; * VECTORS WERE CONNECTED OR ANY CHANGE IN * ; * STATE WHILE VECTORS WERE CONNECTED. * ; * (EXCEPTION - IF THE TASK IS MARKED FOR * ; * ABORT BECAUSE OF MEMORY PARITY ERROR, * ; * IT IS NOT MADE SHUFFLABLE). * ; ************************************************* ; ; DPB FORMAT: ; ; WD. 00 -- DIC(129.),DPB SIZE(7.). ; WD. 01 -- INTERRUPT VECTOR ADDRESS. ; WD. 02 -- BASE ADDRESS FOR MAPPING OF ISR AND ; ENABLE/DISABLE-INTERRUPT ROUTINES. ; IGNORED IN AN UNMAPPED SYSTEM. ; WD. 03 -- ADDRESS OF INTERRUPT SERVICE ROUTINE. IF ZERO, DIRECTIVE ; IS "DISCONNECT FROM INTERRUPTS" AND REMAINING ARGUMENTS ; ARE IGNORED. ; WD. 04 -- ADDRESS OF ENABLE/DISABLE-INTERRUPT ROUTINE. ; WD. 05 -- (LOW BYTE) LOW BYTE OF PSW TO BE SET ; BEFORE CALLING ISR. ; WD. 06 -- ADDRESS OF AST ROUTINE. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=POINTER TO WD. 01 IN DPB ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK). ; ; IF SUCCESSFUL COMPLETION: ; CC-C 0 ; DIRECTIVE STATUS: ; +1 ; BEFORE RETURN, THE ENABLE/DISABLE-INTERRUPTS ROUTINE ; (IF SPECIFIED) IS CALLED IN KERNEL MODE WITH CC-C CLEAR. ; ; IF DIRECTIVE IS REJECTED: ; CC-C 1 ; DIRECTIVE STATUS: ; D.RS1 AN ITB COULD NOT BE ALLOCATED (NO POOL SPACE). ; D.RS8 THE FUNCTION REQUESTED IS "DISCONNECT" ; AND THE TASK IS NOT OWNER OF THE VECTOR. ; D.RS16 ISSUING TASK IS NOT PRIVILEGED. ; D.RS17 THE SPECIFIED VECTOR IS ALREADY IN USE. ; D.RS19 THE SPECIFIED VECTOR IS ILLEGAL (LOWER THAN 60 ; OR HIGHER THAN HIGHEST VECTOR SPECIFIED AT SYSGEN, ; OR NOT A MULTIPLE OF 4). ; D.RS81 ISR OR ENABLE/DISABLE-INTERRUPT ROUTINE IS NOT ; WITHIN 4K WORDS FROM (BASE ADDRESS & 177700). ;- .IF DF C$$INT .ENABL LSB $DRCIN:: .IF DF M$$MGE BIT #T3.PRV,T.ST3(R5) ; IS TASK PRIVILEGED? BEQ 95$ ; N - ILLEGAL, JUMP .ENDC MOV (R3)+,R4 ; GET VECTOR ADDRESS BIT #3,R4 ; MULTIPLE OF 4? BNE 60$ ; N - ILLEGAL VECTOR, JUMP CMP R4,#60 ; VECTOR IN RANGE? BLO 60$ ; N - JUMP CMP R4,#V$$CTR BHIS 60$ ; N - JUMP MOV (R3)+,R0 ; GET BASE ADDRESS MOV (R3)+,-(SP) ; GET ISR ADDRESS BEQ 40$ ; ZERO - DISCONNECT, JUMP ; ; DIRECTIVE IS "CONNECT" ; .IF NDF E$$LOG ;MSH147 ;**-1 CMP @R4,#$NONSI ; VECTOR IN USE? BNE 70$ ; Y - ILLEGAL, JUMP .IFF CMP @R4,#$NONSI ;VECTOR IN USE? BEQ 10$ ;IF EQ NO, CONTINUE PROCESSING CMP @R4,#$NS0 ; VECTOR IN USE? BLO 70$ ; Y - ILLEGAL, JUMP CMP @R4,#$NS7 BHI 70$ ; Y - ILLEGAL, JUMP  .ENDC 10$: BIT #T2.CKD,@R2 ; CHECKPOINTING DISABLED? BNE 15$ ; Y - JUMP BIS #T2.CKD,@R2 ; N - DO IT CLR T.CPCB(R5) ; INITIALIZE LIST OF ITB'S 15$: .IF DF D$$YNM & D$$SHF MOV T.PCB(R5),R1 ; GET PCB BIT #PS.SYS,P.STAT(R1) ; SYSTEM CONTROLLED? BEQ 20$ ; N - JUMP BIS #PS.NSF,P.STAT(R1) ; SET NON-SHUFFLABLE 20$: .ENDC .IF DF M$$MGE BIC #77,R0 ; CLEAR LOWER 6 BITS IN BASE ADDRESS CALL $RELOC ; RELOCATE TO APR 6 ADDRESS SUB #20000,R2 ; RELOCATE TO APR 5 ADDRESS BCS 90$ ; OUT OF RANGE - JUMP SUB R0,@SP ; GET DISPLACEMENT FROM "BASE" TO "ISR" CMP @SP,#20000 ; .GT. 4K WORDS? BHIS 90$ ; Y - ILLEGAL, JUMP .IFTF MOV (R3)+,-(SP) ; GET ENB./DIS.INT. ROUTINE ADDRESS .IFT BEQ 30$ ; NO SUCH ROUTINE - JUMP SUB R0,@SP ; GET DISPLACEMENT FROM BASE BCS 90$ ; OUT OF RANGE - JUMP CMP @SP,#20000 ; .GT. 4K WORDS? BHIS 90$ ; Y - ILLEGAL, JUMP ADD R2,@SP ; MAKE APR 5 ADDRESSES 30$: ADD R2,2(SP) MOV R1,-(SP) ; SAVE APR 5 VALUE .IFTF MOV #X.LEN,R1 ; GET SIZE OF ITB IN BYTES CALL $ALOCB ; ALLOCATE AN ITB BCS 80$ ; FAILURE - JUMP MOV T.CPCB(R5),@R0 ; LINK ITB TO ITB LIST IN TCB (X.LNK) MOV R0,T.CPCB(R5) TST (R0)+ ; STEP PAST LINK WORD IN ITB MOV R0,R1 ; SAVE INTERRUPT ENTRY POINT MOV #4537,(R0)+ ; "JSR R5,@#$INTSC" (X.JSR) MOV #$INTSC,(R0)+ ; (X.JSR+2) MOV (R3)+,@R0 ; PSW AND UNUSED BYTE (X.PSW) .IFT ADD #X.REL-X.PSW,R0 ; POINT TO X.REL IN ITB MOV (SP)+,(R0)+ ; STORE APR 5 VALUE (X.REL) .IFF ADD #X.DSI-X.PSW,R0 ; POINT TO X.DSI IN ITB .ENDC ;MSH045 ;**-1 MOV (SP)+,(R0)+ ; STORE ENB./DIS.INT. ROUTINE ADDRESS (X.DSI) MOV R5,(R0)+ ; STORE TCB ADDRESS (X.TCB) MOV (SP)+,X.ISR-(R0) ; STORE ISR ADDRESS (X.ISR) CLR X.FORK+2-(R0) ; CLEAR FORK PC WORD (X.FORK+2) .IF DF A$$TRP MOV #$DQAC,(R0)+ ; STORE ADDRESS OF ROUTINE TO DEQUEUE ; AST BLOCK QUEUED BY $QASTC TST (R0)+ ; STEP PAST AST QUEUE THREAD WORD MOV PC,(R0)+ ; SET NON-ZERO TO INDICATE ; AST BLOCK FREE (A.CBL) MOV #7*2+2,(R0)+ ; NUMBER OF WORDS TO ALLOCATE ON AST STACK ; (A.BYT) MOV @R3,(R0)+ ; AST ADDRESS (A.AST) MOV #1,(R0)+ ; NUMBER OF AST PARAMETERS = 1 (A.NPR) .ENDC MOV R4,(R0)+ ; AST PARAMETER = VECTOR ADDRESS (X.VEC) MOV @R4,@R0 ; SAVE VECTOR PC (X.VPC) MOV R1,@R4 ; SET VECTOR TO POINT TO ITB TST -(R1) ; BACK UP TO START OF ITB AND CLEAR CC-C 35$: MOV X.DSI(R1),R2 ; GET ADDRESS OF USER ROUTINE TO ; ENABLE/DISABLE INTERRUPTS BEQ 130$ ; NONE - EXIT  CALLR $CITFR ;CALL ROUTINE FROM EXEC SPACE ;MSH045 ; ;**-11 ; ; DIRECTIVE IS "DISCONNECT" ; 40$: MOV @R4,R1 ; GET PC FROM VECTOR SUB #X.JSR,R1 ; GET START OF ITB (X.LNK) BIT #T2.CKD,@R2 ; CHECKPOINTING DISABLED? BEQ 100$ ; N - TASK HAS NO ITB'S, JUMP CALL $DISIN ; DISABLE INTERRUPTS, DEALLOCATE THE ; ITB ETCETERA BCS 100$ ; ERROR (TASK IS NOT OWNER OF VECTOR) - JUMP DRSTS +1 ; EXIT WITH SUCCESS 60$: DRSTS D.RS19 ; ILLEGAL VECTOR 70$: DRSTS D.RS17 ; VECTOR ALREADY IN USE 80$: DRSTS D.RS1 ; NO POOL SPACE .IF DF M$$MGE 90$: DRSTS D.RS81 ; ISR OR ENB./DIS.INT. ROUTINE ADDRESS NOT ; WITHIN RANGE (BASE&177700, BASE&177700+4K) 95$: DRSTS D.RS16 ; PRIVILEGE VIOLATION .ENDC 100$: DRSTS D.RS8 ; DISCONNECT - TASK IS NOT OWNER OF VECTOR ; ; ;+ ; **-$DISIN-DISCONNECT INTERRUPT VECTOR. ; ; INPUT: ; R1 POINTER TO ITB ; R5 POINTER TO TASK TCB ; ; OUTPUT: ; IF SUCCESS: ; CC-C 0 ; THE FOLLOWING OPERATIONS ARE PERFORMED: ; 1. THE ITB IS REMOVED FROM THE ITB LIST STARTING ; IN T.CPCB OF THE TASK'S TCB. ; 2. IF A USER ROUTINE TO DISABLE INTERRUPTS WAS SUPPLIED ; WHEN THE VECTOR WAS CONNECTED TO, THAT ROUTINE IS CALLED ; IN KERNEL MODE WITH CC-C SET. ; 3. VECTOR PC IS RESTORED TO POINT TO THE NONSENSE INTERRUPT ROUTINE. ; 4. IF THE FORK BLOCK OF THE ITB IS IN THE FORK QUEUE, IT ; IS REMOVED. ; 5. IF THE AST BLOCK OF THE ITB IS IN THE AST QUEUE FOR THE TASK, ; IT IS REMOVED. ; 6. IF THIS WAS THE ONLY VECTOR CONNECTED TO THE TASK, ; CHECKPOINTING IS ENABLED FOR THE TASK. IF THE TASK RUNS IN ; A SYSTEM CONTROLLED PARTITION, THE TASK IS MADE SHUFFLABLE. ; 7. FINALLY, THE ITB IS DEALLOCATED. ; ; IF ERROR (TASK IS NOT OWNER OF VECTOR): ; CC-C 1 ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; $DISIN::MOV R5,R0 ; GET TCB ADD #T.CPCB,R0 ; POINT TO ITB LISTHEAD MOV 2(R0),-(SP) ; SAVE WORD FOLLOWING LISTHEAD CALL $QRMVT ; REMOVE FROM ITB LIST MOV (SP)+,2(R0) ; RESTORE WORD FOLLOWING LISTHEAD BCS 130$ ; ITB NOT IN LIST - EXIT WITH ERROR SEC CALL 35$ ; CALL USER ROUTINE TO DISABLE INTERRUPTS ; WITH CC-C SET MOV X.VPC(R1),@X.VEC(R1) ; RESTORE VECTOR PC ADD #X.FORK,R1 ; POINT AT FORK BLOCK IN ITB MOV #$FRKHD,R0 ; GET FORK LISTHEAD MTPS #PR7 ; DISABLE INTERRUPTS CALL $QRMVT ;;; REMOVE FROM FORK LIST IF IT IS THERE MTPS #0 ;;; ENABLE INTERRUPTS .IF DF A$$TRP ADD #X.AST-X.FORK,R1 ; POINT AT AST BLOCK IN ITB MOV R5,R0 ADD #T.ASTL,R0 ; GET AST LIST LISTHEAD CALL $QRMVT ; REMOVE FROM AST LIST IF IT IS THERE SUB #X.AST,R1 ; RESTORE ITB POINTER .IFF SUB #X.FORK,R1 ; RESTORE ITB POINTER .ENDC MOV R1,R0 ; GET ITB POINTER IN R0 TST T.CPCB(R5) ; ITB LIST NOW EMPTY? BNE 120$ ; N - JUMP BIC #T2.CKD,T.ST2(R5) ; Y - ENABLE CHECKPOINTING .IF DF D$$YNM & D$$SHF MOV T.PCB(R5),R1 ; GET PCB BIT #PS.SYS,P.STAT(R1) ; SYSTEM CONTROLLED PARTITION? BEQ 120$ ; N - JUMP BIT #T2.ABO,T.ST2(R5) ; TASK MARKED FOR ABORT? BEQ 110$ ; N - JUMP CMP T.EFLG(R5),#S.PRTY ; Y - IS REASON MEMORY PARITY ERROR? BEQ 120$ ; Y - DON'T MAKE SHUFFLABLE 110$: BIC #PS.NSF,P.STAT(R1) ; MAKE SHUFFLABLE .ENDC 120$: MOV #X.LEN,R1 ; GET LENGTH OF ITB CALL $DEACB ; DEALLOCATE ITB CLC ; SUCCESS 130$: RETURN .DSABL LSB .ENDC .END äðskQ ›c, .TITLE DLDRV .IDENT /02.11/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.11 ; ; P. J. BEZEREDI 07-OCT-77 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; ; MODIFIED BY: ; ; P. J. BEZEREDI 03-DEC-79 ; ; PB141 -- CONDITIONALIZE WRITE CHECK SUPPORT. ; ; P. J. BEZEREDI 06-DEC-79 ; ; PB144 -- RETURN IE.BBE IF MANUFACTURER BAD HEADER IS FOUND. ; ; R. T. PERRON 12-DEC-79 ; ; RP026 -- CORRECT MULTI-CONTROLLER OPERATION ; ; R. T. PERRON 15-JAN-80 ; ; RP027 -- CORRECT OPERATION WHEN WRITE CHECK SUPPORT DISABLED ; ; P. J. CARR 25-NOV-80 ; ; PJC008 -- ADD SUPPORT FOR 22-BIT SYSTEMS WITHOUT ; AN I/O MAP ; ; P. J. CARR 3-APR-81 ; ; PJC021 -- ADD EIS SUPPORT ; ; P. J. CARR 8-APR-81 ; ; PJC028 -- CORRECT ISR HANDLING OF REVERSE SEEKS ; ; P. J. CARR 11-MAY-81 ; ; PJC018 -- CHANGE SUPPORT FOR NEW ERROR LOGGER ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; P. J. CARR 8-SEP-81 ; ; PJC017 -- ADD VOLUME CHECKING FOR RTEM-11 ; ; P. J. CARR 22-OCT-81 ; ; PJC038 -- CLEAN UP CODE ; ; RL11/RL01 DISK DRIVER ; ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ;**************** ; ; EQUATED SYMBOLS ; RETRY= ^D<8> ;CONTROLLER ERROR RETRY COUNT ; PJC018 ; PJC018 .IF DF M$$EXT ; PJC018 ; PJC018 RLCNT= ^D<7> ;ERROR LOGGING REGISTER COUNT ; PJC018 ; PJC018 .IFF ; PJC018 ; PJC018 RLCNT= ^D<5> ;ERROR LOGGING REGISTER COUNT ; PJC018 ; PJC018 .ENDC ; PJC018 ; PJC018 ; PJC018 RLBPT= ^D<512*20> ;BYTES PER RL01 SURFACE ;**-1 .IF DF D$$IAG ;NO DIAGNOSTIC FUNCTIONS YET .ENDC ; ;**************** ; ; RL11 DEVICE REGISTER OFFSETS ; RLCS= 0 ;CONTROL STATUS REGISTER RLBA= 2 ;BUS ADDRESS REGISTER RLDA= 4 ;DISK ADDRESS REGISTER RLMP= 6 ;MULTI-PURPOSE REGISTER RLBAE= 10 ;ADRS EXT REGISTER FOR Q22 SYSTEM ; PJC008 ; ;**************** ; ; RLCS BIT ASSIGNMENTS ; ERR= 100000 ;COMPOSITE ERROR DE= 040000 ;DRIVE ERROR NXM= 020000 ;NON-EXISTANT MEMORY DLT= 010000 ;DATA LATE HNF= 010000 ;HEADER NOT FOUND DCK= 004000 ;DATA CHECK ERROR HCRC= 004000 ;HEADER CRC ERROR OPI= 002000 ;OPERATION INCOMPLETE DRDY= 1 ;DRIVE READY WCHK= 2 ;WRITE CHECK FUNCTION WRITE= 2 ;WRITE OFFSET GSTS= 4 ;GET DRIVE STATUS FUNCTION SEEK= 6 ;SEEK FUNCTION RDH= 10 ;READ HEADERS FUNCTION READ= 14 ;READ DATA FUNCTION IE= 100 ;INTERRUPT ENABLE CRDY= 200 ;CONTROLLER READY ; ;**************** ; ; RLDA STATUS CODES ; MRK= 1 ;MARKER BIT STS= 2 ;GET STATUS BIT SN= 4 ;SIGN BIT FOR SEEK RST= 10 ;DRIVE RESET BIT HS= 20 ;HEAD SELECT BIT FOR DIFFERENCE REV= 200!MRK ;REVERSE SEEK DIFFERENCE WORD ; ;**************** ; ; RLMP GET STATUS BIT ASSIGNMENTS ; WDE= 100000 ;WRITE DATA ERROR CHE= 040000 ;CURRENT HEAD ERROR WLS= 020000 ;WRITE LOCK STATUS SKTO= 010000 ;SEEK TIMEOUT ERROR SPD= 004000 ;SPEED ERROR WGE= 002000 ;WRITE GATE ERROR VC= 001000 ;VOLUME CHECK DSE= 000400 ;DRIVE SELECT ERROR DT= 000200 ;DRIVE TYPE HSS= 000100 ;HEAD SELECT STATUS CO= 000040 ;COVER OPEN HH= 000020 ;HEADS HOME BH= 000010 ;BRUSHES HOME SLM= 000005 ;DRIVE IN SEEK-LINEAR MODE STATE ; ;**************** ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES ; THESE ARE INDEXED BY THE CONTROLLER NUMBER ; CNTBL: .BLKW R$$L11 ;ADRS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$L11 ;RETRY COUNT FOR CURRENT OPERATION ; PB141 ; PB141 .IF DF D$$WCK ; PB141 ; PB141 PRMSV: .BLKW R$$L11*6 ;PARAMETER SAVE AREA FOR WRITE CHECK ; PJC008 ; PB141 .ENDC ; PB141 ;**-1 .IF GT R$$L11-1 TEMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC ; ;**************** ; ;DRIVER DISPATCH TABLE ; $DLTBL::.WORD DLINI ;DEVICE INITIATOR ENTRY POINT .WORD DLCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DLOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DLPWF ;POWERFAIL ENTRY POINT ; ;**************** ; ;+ ; **-DLINI-RL11/RL01 DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO ; PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER ; IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ; ELSE A RETURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT ; IS SUCCESSFUL, THEN THE NEXT I/O OPERATION IS INITIATED. A RETURN ; TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; R5= ADRS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS ; WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE ; DRIVER INITIATES THE REQUESTED I/O FUNCTION ;- .ENABL LSB DLINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCC 10$ ;IF CC PROCESS REQUEST ; PJC038 RETURN ;RETURN IF BUSY OR NO REQUEST ;**-1 ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1= ADRS OF THE I/O REQUEST PACKET ; R2= PHYSICAL UNIT NUMBER OF THE REQUESTED DRIVE ; R3= CONTROLLER INDEX ; R4= ADRS OF THE STATUS CONTROL BLOCK (SCB) ; R5= ADRS OF THE UCB OF THE DRIVE TO BE INITIATED ; ; RL11/RL01 DISK CONTROLLER I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD. 02 -- ADRS OF THE TCB OF THE REQUESTOR TASK ; WD. 03 -- POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER ; WD. 04 -- CONTENTS OF FIRST LUN WORD (UCB ADRS) ; WD. 05 -- I/O FUNCTION CODE ; WD. 06 -- VIRTUAL ADRS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADRS (REAL OR DISPL.+140000) ; WD. 11 -- VIRTUAL ADRS OF AST SERVICE ROUTINE ; WD. 12 -- MEMORY EXTENSION BITS OF I/O TRANSFER ; WD. 13 -- BUFFER ADRS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE IS NOT USED ; WD. 17 -- LOW PART OF LOGICAL BLK NUMBER OF I/O REQUEST ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK. ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG BLK ADR (REAL OR DSPL+140000) ELSE NOT USED ; ; DRIVER USAGE OF WORDS IN I/O PACKET: ; I.PRM+6 (WD. 15) - EXTENDED ADDRESS BITS ; PJC018 ; I.PRM+10 (WD. 16) - STARTING DISK ADDRESS FOR THIS TRANSFER ;**-1 ; I.PRM+12 (WD. 17) - BYTES REMAINING TO TRANSFER ; PJC018 ; ;**-1 ;**************** ; ; THIS SECTION CALCULATES THE ACTUAL DISK ADDRESS FROM THE ; LOGIGAL BLOCK INFORMATION SUPPLIED IN THE I/O PACKET. IT ALSO ; DETERMINES THE FUNCTION TO PERFORM (DIAGNOSTIC OR READ/WRITE). ; 10$: MOV R5,CNTBL(R3) ;SAVE ADRS OF REQUEST UCB ; PJC038 MOV #RETRY,RTTBL(R3) ;SET INITIAL RETRY COUNT ; PJC018 ; PJC017 ; PJC017 .IF DF A$$HDR ; PJC017 ; PJC017 CALL DLVOL ;SET CHARACTERISTICS (IO.STC) FUNCTION? ; PJC017 BCS 40$ ;IF CS YES ; PJC038 ; PJC017 .ENDC ; PJC017 ;**-1 .IF DF M$$EXT ; PJC008 ; PJC008 BIT #DV.EXT,U.CW1(R5) ;BAE EXIST? ; PJC008 BEQ 20$ ;IF EQ NO ; PJC038 MOVB U.BUF+1(R5),R0 ;GET ADRS EXT BITS ; PJC008 MOVB R0,I.PRM+6(R1) ;STORE FOR BUS ADRS EXT REGISTER ; PJC018 ; PJC021 ; PJC021 .IF DF M$$EIS ; PJC021 ; PJC021 ASH #4,R0 ;SHIFT ADRS EXT BITS ; PJC021 ; PJC021 .IFF ; PJC021 ; PJC021 .REPT 4 ; PJC008 ASL R0 ;SHIFT ADRS EXT BITS ; PJC008 .ENDR ; PJC008 ; PJC021 .ENDC ; PJC021 ; PJC021 ; PJC021 BICB #^C<60>,R0 ;ISOLATE AE BITS 16 AND 17 ; PJC008 MOVB R0,U.BUF(R5) ;STORE IN FUNCTION CODE WORD ; PJC008 BR 30$ ;DON'T CALL $STMAP ; PJC038 20$: CALL $STMAP ;SET UP 11/70 UNIBUS MAPPING REGISTERS ; PJC038 ; PJC008 .ENDC ; PJC008 ; PJC008 ; PJC008 30$: MOVB R2,U.BUF+1(R5) ;SET CURRENT UNIT NUMBER ; PJC038 MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION ;**-8 BIS #READ!IE,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/^D<256>,I.FCN+1(R1) ;REALLY? BHIS 50$ ;IF HIS FUNCTION IS LEGAL ; PJC038 40$: JMP 350$ ;EXIT ; PJC038 50$: BEQ 60$ ;IF EQ YES ; PJC038 SUB #WRITE,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION ;**-3 60$: MOV I.PRM+12(R1),R0 ;RETRIEVE BLOCK NUMBER ; PJC038 CLR R2  ;CLEAR HIGH ORDER BLOCK NUMBER ;**-2 BITB #IO.WPB&377,I.FCN(R1) ;PHYSICAL BLOCK FUNCTION? BNE 80$ ;IF NE YES ; PJC038 CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER ;**-1 CMPB #IO.WLB/^D<256>,I.FCN+1(R3) ;WRITE FUNCTION? BNE 70$ ;IF NE NO ; PJC038 BITB #IO.WLT&377,I.FCN(R3) ;OK TO WRITE ON LAST TRACK? ;**-1 BNE 70$ ;IF NE YES ; PJC038 MOV R0,R4 ;SAVE ORIGINAL BLOCK NUMBER ; PJC018 ADD #^D<20>,I.PRM+12(R3) ;ADD 1 TRACK'S WORTH OF BLOCKS ;**-2 CALL $BLKC1 ;CHECK IF WRITE ON LAST TRACK OF DISK MOV R4,R0 ;RESTORE ORIGINAL BLOCK NUMBER ; PJC018 70$: ASL R0 ;CONVERT BLOCKS TO SECTORS ; PJC038 80$: MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; PJC038 MOV S.PKT(R4),R3 ;RESTORE I/O PACKET ADDRESS ; PJC018 MOV #^D<40>,R1 ;DIVIDE BY SECTORS/SURFACE ;**-3 CALL $DIV ;CALCULATE CYLINDER NUMBER ; PJC021 ; PJC021 .IF DF M$$EIS ; PJC021 ; PJC021 ASH #6,R0 ;POSITION CYLINDER AND SURFACE ; PJC021 ; PJC021 .IFF ; PJC021  ; PJC021 .REPT 6. ASL R0 ;POSITION CYLINDER AND SURFACE .ENDR ; PJC021 .ENDC ; PJC021 ; PJC021 ; PJC021 BIS R1,R0 ;MERGE SECTOR WITH CYLINDER AND SURFACE MOV R0,I.PRM+10(R3) ;SAVE STARTING DISK ADDRESS MOV U.CNT(R5),I.PRM+12(R3) ;ASSUME ONLY ONE XFER NEEDED MOV #^D<40>,R0 ;SET SECTORS/SURFACE SUB R1,R0 ;CALCULATE SECTORS LEFT ON SURFACE SWAB R0 ;GET BYTES LEFT ON SURFACE CMP U.CNT(R5),R0 ;ARE ADDITIONAL TRANSFERS REQUIRED? BLOS 90$ ;IF LOS NO ; PJC038 MOV R0,U.CNT(R5) ;SET BYTE COUNT FOR FIRST TRANSFER ; PJC018 90$: ;REF LABEL ; PJC038 ; PB141 .IF DF D$$WCK ; PB141 ; PB141 MOVB S.CON(R4),R0 ;RETRIEVE CONTROLLER INDEX ; PB141 MOV #6,R1 ;SET UP REGISTER R1 ; PJC008 CALL $MUL ;FORM INDEX INTO PARAMETER SAVE AREA ;**-4 ADD #PRMSV,R1 ;POINT TO THIS ENTRY MOV U.BUF(R5),(R1)+ ;SAVE INITIAL PARAMETERS MOV U.BUF+2(R5),(R1)+ ;... MOV U.CNT(R5),(R1)+ ;... MOV I.PRM+10(R3),(R1)+ ;...  MOV I.PRM+12(R3),(R1)+ ;... MOV I.PRM+6(R3),(R1) ;... ; PJC018 ; PB141 .ENDC ; PB141 ; PB141 ;+ ; THIS SECTION WILL INITIATE THE OPERATION ;- DLINIO: ;REF LABEL .IF DF M$$EXT ; PJC008 ; PJC008 BIT #DV.EXT,U.CW1(R5) ;BAE EXIST? ; PJC008 BNE 110$ ;IF NE YES ; PJC038 100$: CALL $MPUBM ;MAP 11/70 UNIBUS TO TRANSFER ; PJC038 ; PJC008 .ENDC ; PJC008 ; PJC008 ; PJC008 110$: MOV S.CSR(R4),R2 ;GET CSR ADDRESS ; PJC038 MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET ;**-8 .IF DF E$$DVC CLRB U.CW2+1(R5) ;RESET DRIVE SETTLE DOWN FLAG ;**-1 .ENDC MOVB S.ITM(R4),S.CTM(R4) ;SET DEVICE TIMEOUT COUNTER ; PJC017 ; PJC017 .IF DF A$$HDR ; PJC017 ; PJC017 BITB #US.VV,U.STS(R5) ;DO HARDWARE VOLUME CHECKING? ; PJC017 BEQ 120$ ;IF EQ NO ; PJC038 CALL DLGST ;GET STATUS ; PJC017 BR 130$ ;SKIP RESET ; PJC038 ; PJC017 .IFTF ; PJC017 ; PJC017 120$: CALL DLRST ;RESET DRIVE AND GET STATUS ; PJC038 130$: MOV RLMP(R2),R1 ;GET THE STATUS INFO ; PJC038 MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY ;**-2 BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS BIT #DRDY,(R2) ;IS THE DRIVE READY? BEQ 150$ ;IF EQ NO ; PJC038 ; PJC017 .IFT ; PJC017 ; PJC017 BITB #US.VV,U.STS(R5) ;DO HARDWARE VOLUME CHECKING? ; PJC017 BEQ 140$ ;IF EQ NO ; PJC038 BIT #VC,R1 ;VOLUME CHECK? ; PJC017 BNE 160$ ;IF NE YES ; PJC038 CALL DLRST ;CLEAR ANY OTHER DRIVE ERROR CONDITIONS ; PJC017 MOV RLMP(R2),R1 ;GET THE STATUS INFO ; PJC017 BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS ; PJC017 BIT #DRDY,(R2) ;IS THE DRIVE READY? ; PJC017 BEQ 150$ ;IF EQ NO ; PJC038 ; PJC017 .ENDC ; PJC017 ; PJC017 ; PJC017 140$: CMP #HH!BH!SLM,R1 ;HEADS, BRUSHES AND STATE OK? ; PJC038 BEQ 170$ ;IF EQ YES ; PJC038 150$: ;REF LABEL ; PJC038 ;**-4 .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 210$ ;IF NE YES ; PJC038 ;**-1 .IFTF .IF DF E$$DVC CALL DLDVER ;LOG THE DEVICE NOT READY .ENDC 160$: JMP 350$ ;EXIT ; PJC038 ;**-1 170$: ;REF LABEL ; PJC038 ;**-1 .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC MOV I.PRM+10(R3),R0 ;RETREIVE STARTING DISK ADDRESS CALL DLDIFF ;CALCULATE DIFFERENCE WORD 180$: BEQ 190$ ;IF EQ, NO SEEK IS NECESSARY ; PJC038 MOV #SEEK,R1 ;GET CODE FOR SEEK FUNCTION ;**-1 CALL DLXCT ;EXECUTE THE SEEK BMI 250$ ;IF MI, ERROR DURING SEEK FUNCTION ; PJC038 190$: ;REF LABEL ; PJC038 ; PJC008 ; PJC008 .IF DF M$$EXT ; PJC008 ; PJC008 BIT #DV.EXT,U.CW1(R5) ;BAE EXIST? ; PJC008 BEQ 200$ ;IF EQ NO ; PJC038 MOV I.PRM+6(R3),RLBAE(R2) ;LOAD ADDRESS EXTENSION BITS ; PJC018 ; PJC008 .ENDC ; PJC008 ; PJC008  ; PJC008 200$: ADD #RLMP,R2 ;POINT TO RLMP ; PJC038 MOV U.CNT(R5),R1 ;GET BYTE COUNT ; PJC018 ROR R1 ;MAKE IT A WORD COUNT ;**-3 NEG R1 ;ALSO NEGATIVE MOV R1,(R2) ;LOAD WORD COUNT MOV I.PRM+10(R3),-(R2) ;LOAD STARTING DISK ADDRESS MOV U.BUF+2(R5),-(R2) ;LOAD BUS ADDRESS .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC MOV U.BUF(R5),-(R2) ;LOAD FUNCTION AND GO ;+ ;+ ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ;- DLCAN: RETURN ;;;NOP FOR RL11 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DLPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS DRIVE CURRENTLY BUSY? BEQ 220$ ;IF EQ NO  ; PJC038 210$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC038 220$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ; PJC038 ;**-4 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DLINT-RL11/RL01 DISK CONTROLLER ; INTERRUPT AND ERROR SERVICE ROUTINES ;- INTSE$ DL,PR5,R$$L11 ;;;SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB ; PJC028 ASRB RTTBL+1(R3) ;REVERSE SEEK IN PROGRESS? ; PJC028 BCS DLINIO ;IF CS YES ;**-1 MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR ;**-1 MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL OPERATION MOV (R2),R1 ;GET CONTENTS OF RLCS BMI 250$ ;IF MI, AN ERROR OCCURRED ; PJC038 MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET ;**-1 SUB U.CNT(R5),I.PRM+12(R3) ;CALCULATE BYTES LEFT TO XFER ; PJC018 BEQ 310$ ;IF EQ, NONE LEFT - COMPLETE WRITE CHECK; PJC038 MOV I.PRM+12(R3),U.CNT(R5) ;ASSUME LAST XFER COMING ; PJC018 CMP I.PRM+12(R3),#RLBPT ;IS THIS THE LAST TRANSFER? ; PJC018 BLOS 230$ ;IF LOS YES ; PJC038 MOV #RLBPT,U.CNT(R5) ;TRANSFER A WHOLE TRACKS WORTH ; PJC018 230$: BIC #CRDY,R1 ;CLEAR CRDY TO START FUNCTION ; PJC038 MOV R1,U.BUF(R5) ;SAVE CURRENT FUNCTION AND ADDRESS BITS ;**-7 MOV RLBA(R2),U.BUF+2(R5) ;SAVE CURRENT BUS ADDRESS ; PJC008 ; PJC008 .IF DF M$$EXT ; PJC008 ; PJC008 BIT #DV.EXT,U.CW1(R5) ;BAE EXIST? ; PJC008 BEQ 240$ ;IF EQ NO ; PJC038 MOV RLBAE(R2),I.PRM+6(R3) ;SAVE CURRENT BUS ADRS EXT ; PJC018 ; PJC008 .ENDC ; PJC008 ; PJC008 ; PJC008 240$: MOV I.PRM+10(R3),R0 ;GET INITIAL DISK ADDRESS ; PJC038 MOV R0,R1 ;COPY DISK ADDRESS ;**-1 BIC #77,R0 ;ISOLATE CYLINDER AND SURFACE ADD #100,R0 ;UPDATE SURFACE/CYLINDER ADDRESS MOV R0,I.PRM+10(R3) ;SAVE NEW DISK ADDRESS CALL DLDIF0 ;CALCULATE MID-TRANSFER DIFFERENCE JMP 180$ ;GO DO THE OPERATION ; PJC038 250$: BIT #DRDY,R1 ;IS THE DRIVE READY? ; PJC038 BNE 270$ ;IF NE YES ; PJC038 260$: MOVB #3,S.CTM(R4) ;SET 3 SECOND TIMEOUT FOR DRIVE ; PJC038 INCB U.CW2+1(R5) ;FLAG DRIVE IS SETTLING DOWN ;**-5 RETURN ; 270$: MOV (R2),R1 ;RETRIEVE RLCS CONTENTS ; PJC038 ;**-2 .IF DF E$$DVC MOV R1,-(SP) ;SAVE CONTENTS OF RLCS CALL DLDVER ;LOG DEVICE ERROR MOV (SP)+,R1 ;RESTORE RLCS CONTENTS .ENDC MOV #IE.BBE&377,R0 ;ASSUME BAD BLOCK ERROR ; PB144 MOV R1,-(SP) ;COPY CONTENTS OF RLCS ; PB144 COM (SP) ;TOGGLE THE BITS ; PB144 BIT #HCRC!OPI,(SP)+ ;BAD BLOCK ERROR? ; PB144 BEQ 350$ ;IF EQ YES ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR BIT #NXM,R1 ;NON-EXISTANT MEMORY? BNE 340$ ;IF NE YES ; PJC038 BIT #DE,R1 ;DRIVE PROBLEMS? ;**-1 BEQ 280$ ;IF EQ NO ; PJC038 CALL DLGST ;EXECUTE GET DRIVE STATUS FUNCTION ;**-1 BIT #WGE,RLMP(R2) ;WRITE GATE ERROR? BEQ 340$ ;IF EQ NO ; PJC038 BIT #WLS,RLMP(R2) ;IS DRIVE WRITE LOCKED? ;**-1 BEQ 290$ ;IF EQ NO ; PJC038 MOV #IE.WLK&377,R0 ;SET WRITE LOCK ERROR CODE ;**-1 BR 350$ ; ; PJC038 280$: ;REF LABEL ; PJC038 ; PB141 ; PB141 .IF DF D$$WCK ; PB141 ; PB141 BIT #10,U.BUF(R5) ;WRITE CHECK FUNCTION? ; PB141 BNE 290$ ;IF NE NO ; PJC038 BIT #OPI,R1 ;OPERATION INCOMPLETE? ;**-3 BNE 290$ ;IF NE YES ; PJC038 BIT #DCK,R1 ;WRITE CHECK ERROR? ;**-1 BEQ 290$ ;IF EQ NO ; PJC038 MOV #IE.WCK&377,R0 ;YES, SET WRITE CHECK ERROR CODE ;**-1 ; PB141 .IFTF ; PB141 ; PB141 290$: MOV S.PKT(R4),R1 ;RETRIEVE I/O PACKET ADDRESS ; PJC038 BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? ;**-1 BNE 350$ ;IF NE YES ; PJC038 DECB RTTBL(R3) ;ANY MORE RETRIES LEFT? ;**-1 BLE 350$ ;IF LE NO ; PJC038 300$: JMP DLINIO ;RETRY ENTIRE OPERATION ; PJC038 310$: ;REF LABEL ; PJC038 ; PB141 .IFT ; PB141 ; PB141 BITB #IO.WLC&377,I.FCN(R3) ;WRITE WITH WRITE CHECK? ; PB141 BNE 320$ ;IF NE YES ; PJC038 BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED? ;**-4 BEQ 350$ ;IF EQ NO ; PJC038 320$: MOV U.BUF(R5),R1 ;GET CURRENT FUNCTION CODE ; PJC038 BIT #WCHK,R1 ;WRITE OR WRITE CHECK FUNCTION? ;**-2 BEQ 350$ ;IF EQ NO ; PJC038 BIT #10,R1 ;WAS FUNCTION WRITE CHECK? ;**-1 BEQ 350$ ;IF EQ YES ; PJC038 MOVB S.CON(R4),R1 ;RETREIVE CONTROLLER INDEX ;**-1 MOV #RETRY,RTTBL(R1);RESET RETRY COUNT MOV #6,R0 ;SET UP R0 ; PJC008 CALL $MUL ;FORM INDEX INTO PARAMETER SAVE AREA ;**-1 ADD #PRMSV,R1 ;... MOV (R1)+,U.BUF(R5) ;RESTORE STARTING PARAMETERS MOV (R1)+,U.BUF+2(R5) ;... MOV (R1)+,U.CNT(R5) ;... MOV (R1)+,I.PRM+10(R3) ;... MOV (R1)+,I.PRM+12(R3) ;... MOV (R1),I.PRM+6(R3) ;... ; PJC018 BIC #10,U.BUF(R5) ;CONVERT TO WRITE CHECK FUNCTION BR 300$ ;START THE WRITE CHECK OPERATION ; PJC038 ; PB141 .ENDC ; PB141 ; PB141 330$: BEQ 350$ ;IF EQ, COMPLETED TRANSFER SUCCESSFULLY ; PJC038 340$: MOV #IE.VER&377,R0 ;SET UNSUCCESSFUL OPERATION ; PJC038 350$: MOV S.PKT(R4),R2 ;GET ADDRESS OF I/O PACKET ; PJC038 MOV I.PRM+4(R2),R1 ;GET TOTAL TRANSFER SIZE ;**-3 SUB I.PRM+12(R2),R1 ;CALCULATE BYTES TRANSFERRED ; PJC018 ;**-1 .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL RETRY COUNT BIS #RETRY*^D<256>,R2 ;MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION JMP DLINI ;PROCESS NEXT REQUEST ;+ ; **-DLOUT-RL11/RL01 DISK CONTROLLER ; DEVICE TIMEOUT ROUTINE ; ; DEVICE TIMEOUT RESULTS IN THE OPERATION BEING REPEATED. ; TIMEOUTS ARE USUALLY CAUSED BY A POWER FAILURE BUT MAY ALSO ; BE THE RESULT OF A HARDWARE MALFUNCTION. ;- DLOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 370$ ;;;IF EQ NO ; PJC038 INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #16.,S.STS(R4) ;;;HAVE WE WAITED 1 MINUTE YET? ; PJC029 BEQ 360$ ;;;IF EQ YES ; PJC038 MTPS #0 ;;;ALLOW INTERRUPTS ; PJC029 JMP DLINIO ;RETRY ENTIRE OPERATION ; PJC029 360$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC038 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-4 BR 380$ ;;; ; PJC038 ;**-3 .ENDC 370$: TSTB U.CW2+1(R5) ;;;IS THE DRIVE SETTLING DOWN? ; PJC038 BEQ 380$ ;;;IF EQ NO ; PJC038 MTPS #0 ;;;YES, ALLOW INTERRUPTS ;**-2 JMP 270$ ;PROCESS THE ERROR ; PJC038 380$: ;;;REF LABEL ; PJC038 ;**-2 .IF DF E$$DVC CALL DLDTER ;;;LOG DEVICE TIMEOUT .IFF CALL $DTOER ;;;LOG DEVICE TIMEOUT .ENDC CALL DLRST ;RESET DRIVE BR 290$ ;REPEAT THE OPERATION ; PJC038 ;**-1 ;+ ; **-DLXCT,DLGST,DLRST-RL11/RL01 DISK CONTROLLER ; FUNCTION EXECUTION ROUTINES ; ; THIS ROUTINE WILL EXECUTE A GET DRIVE STATUS OR ANY ; NON-INTERRUPTABLE FUNCTION AND WAIT FOR ITS COMPLETION. ; ; INPUTS: ; R1 = FUNCTION CODE ; R2 = CSR ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; R1 = CONTENTS OF RLCS (TESTED) ; FUNCTION EXECUTED ;-  DLRST: MOV #RST!STS!MRK,RLDA(R2) ;SET MESSAGE CODES IN RLDA CALL 390$ ;DO THE DRIVE RESET FIRST ; PJC038 DLGST: MOV #STS!MRK,RLDA(R2) ;SET MESSAGE CODES IN RLDA ;**-1 390$: MOV #GSTS,R1 ;SET GET STATUS OPERATION ; PJC038 DLXCT: MOV R1,-(SP) ;SAVE FUNCTION CODE ;**-1 MOVB U.UNIT(R5),1(SP);MERGE CURRENT DRIVE BITS MOV (SP)+,(R2) ;LOAD RLCS 400$: TSTB (R2) ;FUNCTION COMPLETED? ; PJC038 BPL 400$ ;IF PL NO ; PJC038 MOV (R2),R1 ;SAVE RLCS AND TEST FOR ERRORS ;**-2 RETURN ;  ;+ ; **-DLDIFF-RL11/RL01 DISK CONTROLLER ; CYLINDER ADDRESS DIFFERENCE CALCULATOR ; ; THIS SUBROUTINE CALCULATES THE DIFFERENCE WORD USED IN THE ; SEEK OPERATION. IF A HEADER CANNOT BE READ AFTER 16. RETRIES, ; AN ERROR WILL BE LOGGEN AND A ONE CYLINDER REVERSE SEEK WILL ; BE ISSUED. THE SEEK IS FOLLOWED BY A READ HEADERS TO CAUSE AN ; INTERRUPT. ; ; INPUTS: ; R0 = DESIRED DISK ADDRESS ; R3 = I/O PACKET ADDRESS ; ; OUTPUTS: ; R1 = DIFFERENCE WORD ; RLDA = LOADED WITH DIFFERENCE WORD ; IF EQ NO SEEK IS NECESSARY ;**-1 ;- DLDIFF: MOV #RETRY*2,-(SP) ;SET READ HEADER RETRY COUNT 410$: MOV #RDH,R1 ;SET CODE FOR READ HEADERS FUNCTION ; PJC038 CALL DLXCT ;EXECUTE THE FUNCTION ;**-1 BPL 420$ ;IF PL, FUNCTION EXECUTED OK ; PJC038 DEC (SP) ;ANY RETRIES LEFT? ;**-1 BGT 410$ ;IF GT YES ; PJC038 CMP (SP)+,(SP)+ ;REMOVE RETRY COUNT AND CALLERS ADDRESS ;**-1 .IF DF E$$DVC CALL DLDVER ;LOG HEADER ERROR .IFF MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX  .ENDC ; PJC018 ;**-1 CALL DLRST ;RESET DRIVE MOV #REV,RLDA(R2) ;LOAD REVERSE SEEK DIFFERENCE WORD MOV #SEEK,R1 ;GET CODE FOR SEEK FUNCTION CALL DLXCT ;EXECUTE THE SEEK BMI 340$ ;IF MI IT FAILED ; PJC038 BIC #377,R1 ;CLEAR OUT FUNCTION BITS ;**-1 BIS #IE!RDH,R1 ;LOAD CODES FOR READ HEADER MOVB #1,RTTBL+1(R3) ;INDICATE REVERSE SEEK IN PROGRESS MOVB S.ITM(R4),S.CTM(R4) ;SET DEVICE TIMEOUT COUNTER MOV R1,(R2) ;LOAD FUNCTION AND GO RETURN ;WAIT FOR THE INTERRUPT 420$: TST (SP)+ ;REMOVE RETRY COUNT ; PJC038 MOV RLMP(R2),R1 ;RETREIVE HEADER WORD ;**-1 DLDIF0: BIC #77,R0 ;MASK OUT SECTOR BITS ; PJC018 BIC #77,R1 ;... ;**-9 CMP R0,R1 ;DO WE NEED TO DO A SEEK? BEQ 440$ ;IF EQ NO ; PJC038 MOV R0,-(SP) ;SAVE DESIRED DISK ADDRESS ;**-1 BIC #^C<100>,(SP) ;ISOLATE SURFACE BIT ASR (SP) ;PUT INTO THE PROPER POSITION ASR (SP) ;... BIC #100,R0 ;REMOVE SURFACE BIT BIC #100,R1 ;... SUB R0,R1 ;SUBTRACT DESIRED FROM ACTUAL ; BEQ 430$ ;IF EQ, ONLY CHANGE SURFACE ; PJC038 BCC 430$ ;IF CC, ACTUAL >= DESIRED ; PJC038 NEG R1 ;ACTUAL < DESIRED, MAKE POSITIVE DIFFERE;**-2 BIS #SN,R1 ;SET SIGN FOR MOVE TO CENTER OF DISK 430$: INC R1 ;SET MARKER BIT ; PJC038 BIS (SP)+,R1 ;MERGE IN SURFACE BIT ;**-1 MOV R1,RLDA(R2) ;LOAD DIFFERENCE WORD 440$: RETURN ; ; PJC038 ;**-9 .IF DF E$$DVC ;+ ; **-DLDXXX-RL11/RL01 DISK CONTROLLER ; ERROR LOGGING ROUTINES ; ; THIS ROUTINE IS CALLED WHENEVER A DEVICE ERROR OR DEVICE TIMEOUT ; OCCURS. A CORE BLOCK THE SIZE OF THE REGISTER BUFFER IS ALLOCATED ; AND THE UNIBUS REGISTERS ALONG WITH THE DRIVE STATUS INFORMATION ; ARE TRANSFERED INTO THE CORE BLOCK. THEN THE CSR ADDRESS IN THE ; SCB IS SET TO THE CORE BLOCK ADDRESS AND THE APPROPRIATE EXECUTIVE ; ERROR LOGGING ROUTINE IS CALLED. THE CORE BLOCK IS THEN ; DEALLOCATED AND THE CSR ADRESS IN THE SCB RESTORED. ; ; IF FOR ANY REASON THE CORE BLOCK CANNOT BE ALLOCATED THEN THE ; EXECUTIVE ERROR LOGGING ROUTINE WILL NOT BE CALLED AND THE ERROR ; SEQUENCE NUMBER WILL BE UPDATED TO INDICATE THAT A MISSED ERROR ; CONDITION OCCURRED. ; ; INPUTS: ; R2 = CSR ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; R1 = DESTROYED ; R3 = CONTROLLER INDEX ;- DLDVER: MOV #$DVERR,R1 ;GET ADRS OF DEVICE ERROR ROUTINE BR 450$ ; ; PJC038 DLDTER: MOV #$DTOER,R1 ;;;GET ADRS OF DEVICE TIMEOUT ROUTINE ;**-1 450$: MOV R0,-(SP) ;SAVE I/O STATUS CODE ; PJC038 MOV R1,-(SP) ;SET CO-ROUTINE ADDRESS ;**-1 MOV #RLCNT*2,R1 ;GET NUMBER OF BYTES TO ALLOCATE CALL $ALOCB ;ALLOCATE A CORE BLOCK BCC 460$ ;IF CC, BLOCK WAS ALLOCATED ; PJC038 INC $ERRSQ ;INDICATE A MISSED ERROR CONDITION ;**-1 CMP (SP)+,#$DTOER ;ALLOCATION FAILURE, TIMEOUT IN PROGRESS? BNE 480$ ;IF NE NO ; PJC038 BIC #IE,@S.CSR(R4) ;;;CLEAR INTERRUPT ENABLE ;**-1 MTPS #0 ;;;ALLOW INTERRUPTS BR 480$ ;DON'T LOG ERROR IS ALLOCATION FAILURE ; PJC038 460$: MOV R0,R3 ;SET POINTER TO CORE BLOCK ; PJC038 MOV S.CSR(R4),R2 ;GET REAL CSR ADDRESS  ;**-2 MOV (R2),(R3)+ ;TRANSFER RLCS ; PJC018 MOV RLBA(R2),(R3)+ ;TRANSFER RLBA ; PJC018 MOV RLDA(R2),(R3)+ ;TRANSFER RLDA ; PJC018 MOV RLMP(R2),(R3)+ ;TRANSFER RLMP ; PJC018 ; PJC018 ; PJC018 .IF DF M$$EXT ; PJC018 ; PJC018 BIT #DV.EXT,U.CW1(R5) ;BAE EXIST? ; PJC018 BEQ 470$ ;IF EQ NO ; PJC038 MOV RLBAE(R2),(R3)+ ;TRANSFER RLBAE ; PJC018 CLR (R3)+ ;ZERO EXTRA STORAGE WORD ; PJC018 ; PJC018 .ENDC ; PJC018  ; PJC018 ; PJC018 470$: CALL DLGST ;EXECUTE GET DRIVE STATUS FUNCTION ; PJC038 MOV RLMP(R2),(R3) ;SAVE DRIVE STATUS ; PJC018 MOV R0,S.CSR(R4) ;REPLACE CSR WITH CORE BLOCK ADDRESS ;**-6 CALL @(SP)+ ;CALL EXEC ERROR LOGGING ROUTINE MOV R2,S.CSR(R4) ;RESTORE CSR ADDRESS MOV #RLCNT*2,R1 ;GET NUMBER OF BYTES TO DEALLOCATE CALL $DEACB ;DEALLOCATE THE CORE BLOCK 480$: MOV S.CSR(R4),R2 ;RESTORE CSR ADDRESS ; PJC038 MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX ;**-1 MOV (SP)+,R0 ;RESTORE I/O STATUS CODE RETURN .ENDC .DSABL LSB ; PJC017 ; PJC017 .IF DF A$$HDR ; PJC017 ; PJC017 ;+ ; PJC017 ; **-DLVOL-PREPROCESS VOLUME VALID CHECKING ; PJC017 ; ; PJC017 ; THIS ROUTINE WILL DETERMINE IF VOLUME CHECKING IS TO BE DONE. ; PJC017 ; ; PJC017 ; INPUTS: ; PJC017 ; ; PJC017 ; R1=I/O PACKET ADDRESS ; PJC017 ; I.PRM+2=0 TO DESELECT VOLUME CHECKING ; PJC017 ; 1 TO SELECT VOLUME CHECKING ; PJC017 ; ; PJC017 ; R4=SCB ADDRESS ; PJC017 ; R5=UCB ADDRESS ; PJC017 ; ; PJC017 ; OUTPUTS: ; PJC017 ; ; PJC017 ; C=0 THEN THE FUNCTION WAS NOT A SET CHARACTERISTICS (IO.STC) ; PJC017 ; ; PJC017 ; C=1 THEN THE FUNCTION WAS A SET CHARACTERISTICS (IO.STC) ; PJC017 ; US.VV=0 DO NOT DO VOLUME CHECKING ; PJC017 ; US.VV=1 DO VOLUME CHECKING ; PJC017 ; R0=IS.SUC&377 OR ERROR CODE ; PJC017 ;- ; PJC017 VV$SET= 1 ;SET/CLEAR VOLUME VALID ; PJC017 DLVOL: MOV I.FCN(R1),-(SP) ;GET FUNCTION CODE ; PJC017 BIC #7,(SP) ;REMOVE QUALIFIER BITS ; PJC017 CMP #IO.STC,(SP)+ ;SET CHARACTERISTICS? ; PJC017 BEQ 10$ ;IF EQ YES ; PJC038 CLC ;SHOW NOT AN IO.STC FUNCTION ; PJC017 RETURN ; ; PJC017 10$: MOV I.PRM+2(R1),R0 ;GET PARAMETER SPECIFICATION ; PJC038 BIT #VV$SET,R0 ;SET VOLUME VALID? ; PJC017 BNE 30$ ;IF NE YES ; PJC038 BIT #^C,R0 ;BAD PARAMETERS? ; PJC017 BNE 20$ ;IF NE YES ; PJC038 BICB #US.VV,U.STS(R5) ;TURN OFF VOLUME CHECKING ; PJC017 BR 40$ ; ; PJC038 20$: MOV #IE.BAD&377,R0 ;SET BAD PARAMETERS ERROR ; PJC038 BR 60$ ; ; PJC038 30$: MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR ; PJC038 CALL DLRST ;RESET DRIVE AND GET STATUS ; PJC017 MOV RLMP(R2),R3 ;GET THE STATUS INFO ; PJC018 BIT #DRDY,(R2) ;DRIVE READY? ; PJC017 BEQ 50$ ;IF EQ NO ; PJC038 BIC #WLS!DT!HSS,R3 ;REMOVE IRRELEVANT BITS ; PJC018 CMP #HH!BH!SLM,R3 ;HEADS, BRUSHES AND STATE’ OK? ; PJC018 BNE 50$ ;IF NE NO ; PJC038 BISB #US.VV,U.STS(R5) ;TURN ON VOLUME CHECKING ; PJC017 40$: MOV #IS.SUC&377,R0 ;SHOW SUCCESSFUL I/O CODE ; PJC038 BR 60$ ; ; PJC038 50$: MOV #IE.DNR&377,R0 ;SET DRIVE NOT READY ERROR ; PJC038 60$: SEC ;SHOW AN IO.STC FUNCTION ; PJC038 RETURN ; ; PJC017 ; PJC017 .ENDC ; PJC017 ; PJC017 .END ’»zÈkQ ›c, .TITLE SYSCM .IDENT /16.69/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 16.69 ; ; D. N. CUTLER 11-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; B. SCHREIBER ; CHUCK SPITZ ; J. E. PROVINO ; ; MODIFIED BY: ; ; M. S. HARVEY 15-JAN-81 ; MSH043 -- USE SYSGEN SYMBOLS TO DRIVE THE SYSTEM ID ; ; M. S. HARVEY 23-JUL-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT ; ; M. S. HARVEY 17-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 30-SEP-79 ; MSH065 -- SET APPROPRIATE FEATURE MASK BIT IF INSTALL, ; REQUEST AND REMOVE SUPPORT IS DEFINED ; ; M. S. HARVEY 30-OCT-79 ; MSH069 -- UPDATE NULL TASK TCB. DEFINE F2.STP TO BE ZERO ; IF EVENT FLAG MASKS IN HEADER, ONE IF IN TCB. ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 2-JAN-80 ; MSH079 -- STORE THE NODE NAME FOR A SYSTEM IN $SYSNM ; ; M. S. HARVEY 2-JAN-80 ; MSH080 -- ADD A WORD CONTAINING THE NETWORK UIC ; ; M. S. HARVEY 25-APR-80 ; MSH096 -- IF ALTERNATE HEADER REFRESH SUPPORT IS ; CHOSEN, SET F2.AHR IN THE FEATURE MASK ; ; M. S. HARVEY 30-APR-80 ; MSH097 -- ADD THE HARDWARE FEATURE MASK AND SUPPORT FOR ; NON-UNIBUS 22-BIT SYSTEMS ; ; M. S. HARVEY 1-MAY-80 ; MSH098 -- ADD DYNAMIC SYSTEM TUNING SUPPORT ; ; M. S. HARVEY 5-JUN-80 ; MSH105 -- ADD MULTIPLE CLI SUPPORT ; ; M. S. HARVEY 20-AUG-80 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 20-AUG-80 ; MSH112 -- ADD SUPPORT FOR EXTENDED INST. SET ; ; M. S. HARVEY 15-SEP-80 ; MSH118 -- ADD SUPPORT OF SYSTEM-CONTROLLED PARTITIONS ; FOR RSX-11S SYSTEMS ; ; M. S. HARVEY 17-OCT-80 ; MSH123 -- ADD SUPPORT OF THE SET SYSTEM TIME DIRECTIVE ; ; M. S. HARVEY 30-OCT-80 ; MSH121 -- EXTERNALLY DEFINE AST SUPPORT IF THERE ; ; M. S. HARVEY 13-NOV-80 ; MSH128 -- ADD SUPPORT FOR NETWORK POWERFAIL RECOVERY ; ; M. S. FOX 07-JAN-81 ; MF203 -- INITIAL ALTERNATE CLI SUPPORT ; ; DAN BROWN 07-JAN-81 ; DTB004 -- ADD SUPPORT FOR NEW ERROR LOGGER ; ; M. S. FOX 26-JAN-81 ; MF207 -- ADD RPOI$ AND SDRP$ DIRECTIVES ; ; M. S. HARVEY 3-FEB-81 ; MSH141 -- CLEAN UP IDLE PATTERN STORAGE ; ; M. S. HARVEY 12-FEB-81 ; MSH149 -- ASSUME NO FLOATING POINT PROCESSOR PRESENT ; ; M. S. HARVEY 13-FEB-81 ; MSH142 -- DEFINE POOL MONITORING DATA ELEMENTS ; ; M. S. HARVEY 28-FEB-81 ; MSH150 -- DEFINE AVR LISTHEAD FOR ANSI MAGTAPE CONTROL ; ; M. S. HARVEY 5-MAR-81 ; MSH156 -- ADD TRANSPORTABILITY SUPPORT FOR THE ; WATCHDOG TIMER ; ; M. S. HARVEY 14-MAR-81 ; MSH158 -- ADD SYMBOL FOR THE LIBRARY UIC ; ; M. S. HARVEY 15-MAR-81 ; MSH159 -- ADD SUPPORT FOR THE UDA ; ; M. S. HARVEY 31-MAR-81 ; MSH160 -- SET F3.RLK FOR 'RMS' RECORD LOCKING ; ; M. S. HARVEY 21-APR-81 ; MSH165 -- ADD OFFSET POINTER FOR SECOND DIRECTIVE COMMON ; ; D. R. DONCHIN 09-JUN-81 ; DD098 -- ADD LISTHEAD FOR ANCILLARY CONTROL DRIVER ; ; M. S. HARVEY 16-JUN-81 ; MSH177 -- ADD NETWORK SUPPORT FEATURE MASK BIT ; ; M. S. HARVEY 6-AUG-81 ; MSH184 -- ADD SUPPORT FOR SHUFFLER RUN LIMITING ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; SYSTEM COMMON DATA AREA ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,HWDDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; MAKE CLOCK PARAMETERS GLOBAL ; S$$RTZ==H$$RTZ ;LINE FREQUENCY S$$IEN==K$$IEN ;ENABLE BITS PATTERN S$$LDC==K$$LDC ;LOAD VALUE FOR COUNT REGISTER S$$TPS==K$$TPS ;TICKS PER SECOND ON P CLOCK ; ; LOCAL SYMBOL DEFINITIONS ; ;MSH080 ; DEFAULT SYSTEM AND NETWORK UIC ;MSH080 ;MSH080 .IF DF M$$MGE ;MSH080 ;MSH080 SYUIC=454 ;MAPPED UIC = [1,54] ;MSH080 ;MSH080 .IFF  ;MSH080 ;MSH080 SYUIC=450 ;UNMAPPED UIC = [1,50] ;MSH080 ;MSH080 .ENDC ;MSH080 ;MSH080 ; ;MSH080 ; FUNCTION MASK LITERAL ; FMASK= 0 ;INITIALIZE FUNCTION MASK .IF DF M$$EXT&M$$MGE FMASK= FMASK!FE.EXT ;INCLUDE EXTENDED MEMORY MASK .ENDC .IF DF M$$MUP FMASK= FMASK!FE.MUP ;INCLUDE MULTI-USER PROTECTION MASK .ENDC .IF DF R$$EXV FMASK= FMASK!FE.EXV ;INCLUDE EXTENDED VIRT ADDR MASK .ENDC .IF DF L$$DRV  FMASK= FMASK!FE.DRV ;LOADABLE DRIVER SUPPORT ;MSH069 ;**-1 .ENDC .IF DF P$$LAS FMASK= FMASK!FE.PLA ;PLAS SUPPORT .ENDC .IF DF Q$$OPT FMASK= FMASK!FE.PKT ;QIO PACKET PREALLOCATION .ENDC .IF DF C$$CKP&D$$YNC FMASK= FMASK!FE.CAL ;DYNAMIC CHECKPOINT SPACE ALLOCATION .ENDC .IF DF E$$XPR&M$$MGE&D$$YNM FMASK= FMASK!FE.EXP ;EXTEND TASK DIRECTIVE .ENDC .IF DF L$$SI1 FMASK= FMASK!FE.LSI ;PROCESSOR IS AN LSI-11 .ENDC .IF DF P$$OFF FMASK= FMASK!FE.OFF ;PARENT OFFSPRING TASKING .ENDC .IF DF T$$CPW FMASK= FMASK!FE.FDT ;FULL DUPLEX TERMINAL DRIVER .ENDC .IF DF M$$MGE&D$$YNM FMASK= FMASK!FE.DYM ;DYNAMIC MEMORY ALLOCATION .ENDC ; ;MSH045 ; FUNCTION MASK LITERAL (2ND WORD) ;MSH045 ; ;MSH045 ;MSH045 FMASK2= 0 ;INITIALIZE FUNCTION MASK (2ND WORD) ;MSH045 ;MSH045 ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 FMASK2= FMASK2!F2.DPR ;DIRECTIVE PARTITION SUPPORT ;MSH045 ;MSH045 .ENDC ;MSH045 ;MSH045 .IF DF I$$RAR ;MSH065 ;MSH065 FMASK2= FMASK2!F2.IRR ;INSTALL, REQUEST AND REMOVE TASKS ;MSH065 ;MSH065 .ENDC ;MSH065 ;MSH065 .IF DF G$$EFN ;MSH049 ;MSH049 FMASK2= FMASK2!F2.GGF ;GROUP GLOBAL EVENT FLAG SUPPORT ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 .IF DF R$$SND ;MSH076 ;MSH076 FMASK2=FMASK2!F2.RAS ;RECEIVE/SEND DATA PACKET SUPPORT ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 .IF DF A$$HDR ;MSH096 ;MSH096 FMASK2=FMASK2!F2.AHR ;ALT. HEADER REFRESH AREAS SUPPORTED ;MSH096 ;MSH096 .ENDC ;MSH096 ;MSH096 .IF DF R$$NDC ;MSH098 ;MSH098 FMASK2=FMASK2!F2.RBN ;ROUND ROBIN SCHEDULING ;MSH098 ;MSH098 .ENDC ;MSH098 ;MSH098 .IF DF S$$WPC ;MSH098 ;MSH098 FMASK2=FMASK2!F2.SWP ;EXECUTIVE LEVEL DISK SWAPPING ;MSH098 ;MSH098 .ENDC ;MSH098 ;MSH098 .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 FMASK2=FMASK2!F2.STP ;EVENT FLAG MASK AND MASK ADDR. IN TCBS ;MSH069 ;MSH069 .ENDC ;S$$TOP!T$$BUF ;MSH069 ;MSH069 ;MSH112 ; ;MSH112 ; FUNCTION MASK LITERAL (3RD WORD) ;MSH112 ; ;MSH112 ;MSH112 FMASK3= 0 ;INITIALIZE FUNCTION MASK (3RD WORD) ;MSH112 ;MSH112 ;MSH112 .IF DF M$$NET ;MSH177 ;MSH177 FMASK3=FMASK3!F3.NWK ;NETWORK SUPPORT ;MSH177 ;MSH177 .ENDC ;MSH177 ;MSH177 .IF DF M$$EIS ;MSH112 ;MSH112 FMASK3=FMASK3!F3.EIS ;EXTENDED INSTRUCTION SET REQUIRED ;MSH112 ;MSH112 .ENDC ;MSH112 ;MSH112 .IF DF S$$TIM ;MSH123 ;MSH123 FMASK3=FMASK3!F3.STM ;SET SYSTEM TIME DIRECTIVE ;MSH123 ;MSH123 .ENDC ;MSH123 ;MSH123 .IF DF A$$TRP ;MSH121 ;MSH121 FMASK3=FMASK3!F3.AST ;SYSTEM HAS AST SUPPORT ;MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 .IF DF R$$11S ;MSH118 ;MSH118 FMASK3=FMASK3!F3.11S ;RSX-11S SYSTEM ;MSH118 ;MSH118 .ENDC ;MSH118 ;MSH118 .IF DF A$$CLI ; MF203 ; MF203 FMASK3=FMASK3!F3.CLI ;ALTERNATE CLI SUPPORT ; MF203 ; MF203 .ENDC ; MF203 ; MF203 .IF DF P$$CTL ;MSH142 ;MSH142 FMASK3=FMASK3!F3.PMN ;POOL MONITOR SUPPORT ;MSH142 ;MSH142 .ENDC ;MSH142 ;MSH142 .IF DF K$$W11 ;MSH156 ;MSH156 FMASK3=FMASK3!F3.WAT ;WATCHDOG TIMER SUPPORTED ;MSH156 ;MSH156 .ENDC ;MSH156 ;MSH156 .IF DF R$$LKL ;MSH160 ;MSH160 FMASK3=FMASK3!F3.RLK ;RECORD LOCKING SUPPORT ;MSH160 ;MSH160 .ENDC ;MSH160 ;MSH160 .IF DF D$$SHF ;MSH184 ;MSH184 FMASK3=FMASK3!F3.SHF ;SYSTEM SUPPORTS THE MEMORY SHUFFLER ;MSH184 ;MSH184 .ENDC ;MSH184 ;MSH184 ; ; NULL TASK CONTROL BLOCK ; ; THIS TCB TERMINATES THE SYSTEM AND ACTIVE TASK LISTS. IT MUST HAVE ; A PRIORITY OF ZERO AND ALWAYS BE BLOCKED. REQUIRED POSITIONS ARE ; ENFORCED BY THE "ASSUME" MACRO. ; $CMBEG:: ;BEGINNING OF SYSCM AREA FOR CDA $HEADR::.WORD 0 ;T.LNK-POINTER TO CURRENT TASK HEADER ASSUME .-$HEADR,T.PRI ;T.PRI MUST BE ZERO .BYTE 0 ;T.PRI-NULL TASK PRIORITY IS ZERO $CURPR::.BYTE 0 ;T.IOC-CURRENT TASK PRIORITY $COMEF::.WORD 0 ;T.TCB-COMMON EVENT FLAGS 1-16 .WORD 0 ;T.NAM-COMMON EVENT FLAGS 17-32 $SYSID::.WORD B$$LV1 ;T.NAME+2-SYSTEM IDENTIFICATION ;MSH043 .WORD B$$LV2 ;T.RCVL-SYSTEM IDENTIFICATION ;MSH043 $TKNPT::.WORD 0 ;T.RCVL+2-POINTER TO TKTN TCB ;**-1 $SHFPT::.WORD 0 ;T.ASTL-POINTER TO SHUFFLER TCB $CKCNT::.WORD K$$CNT ;T.ASTL+2-ADDRESS OF CLOCK COUNT REG $CKCSR::.WORD K$$CSR ;T.EFLG-ADDR OF CLOCK CNTRL STATUS REG .IF EQ K$$CSR-177546 $CKLDC::.WORD 0 ;T.EFLG+2-CLOCK LOAD COUNT .IFF $CKLDC::.WORD K$$LDC ;T.EFLG+2-CLOCK LOAD COUNT .ENDC .IF NDF M$$NET ;MSH080 ;MSH080 $NTUIC:: ;DEFINED FOR MCR ;MSH080 ;MSH080 .ENDC ;MSH080 ;MSH080 $LBUIC:: ;LIBRARY UIC ;MSH158 $SYUIC::.WORD SYUIC ;T.UCB-DEFAULT SYSTEM UIC ;MSH080 ;**-12 ASSUME .-$HEADR,T.TCBL ;T.TCBL MUST BE ZERO .IF NDF E$$LOG ;DTB004 ;**-1 $ERRSQ:: ;ERROR SEQ # ALWAYS ZERO IF NO LOGGING .ENDC .WORD 0 ;T.TCBL-LINK TO NEXT TCB ASSUME .-$HEADR,T.STAT ;T.STAT MUST BE NONZERO $EXSIZ::.WORD $SYTOP ;T.STAT-ADDR OF LAST BYTE IN EXEC $PWRFL::.WORD 1 ;T.ST2-POWERFAIL RECOVERY REQUEST FLAG $SIGFL::.WORD 0 ;T.ST3-TASK WAITING FOR SIG EVENT $LOGHD::.WORD 0 ;T.DPRI-LOGICAL DEVICE ASSIGNMENT LIST ;MSH069 $MCRCB::.WORD 0 ;T.LBN+1-MCR COMMAND BLOCK ADDRESS ;**-1 $LSTLK::.WORD 0 ;T.LDV-LOCK WORD (TCB ADDRESS OF OWNER) .WORD 3 ;T.PCB-CONSTANT FOR ALLOCATION ROUTINES $CRAVL::.WORD $SYBEG ;T.MXSZ-POOL FREE BLOCK LISTHEAD ;MSH069 ASSUME .-$HEADR,T.ACTL ;T.ACTL MUST BE ZERO ;**-1 .WORD 0 ;T.ACTL-NEXT ACTIVE TASK-DUMMY BLK SIZE $ACTHD::.WORD $HEADR ;T.SAST-ACTIVE TASK LIST LISTHEAD ;MSH069 $DICSV::.WORD 1 ; ,T.TIO-SAVED DIC AND DPB LENGTH ;MSH069 $TKTCB::.WORD $HEADR ;T.TKSZ-POINTER TO CURRENT TASK TCB ;MSH069 ASSUME .-$HEADR,T.TKSZ+2 ;MSH069 ; ; END OF SUPERIMPOSED AREA-REMAINING SYSTEM COMMON AREA ; $ABTIM::.WORD 0 ;ABSOLUTE TIME COUNTER ;**-1 $RQSCH::.WORD $HEADR ;SCHEDULE REQUEST TCB ADDRESS ;**-1 $STKDP::.WORD 0 ;STACK DEPTH INDICATOR $DEVHD::.WORD $DEVTB ;POINTER TO FIRST DEVICE CONTROL BLOCK $RNDCT:: ;DEFINE FOR MCR ;MSH098 ;MSH098 .IF DF R$$NDC ;MSH098 ;MSH098 .WORD R$$NDC ;ROUND ROBIN SCHEDULING INTERVAL ;MSH098 ;MSH098 .ENDC ;MSH098 ;MSH098 $SWPCT:: ;DEFINE FOR MCR ;MSH098 ;MSH098 .IF DF S$$WPC&D$$ISK ;MSH098 ;MSH098 .WORD S$$WPC ;DISK SWAPPING INTERVAL ;MSH098 ;MSH098 .ENDC ;MSH098 ; MF203 .IF NDF A$$CLI ; MF203 ; MF203 $MCRPT::.WORD 0 ;POINTER TO MCR TCB .IF DF M$$CLI .ASCIZ <15><12>/MCR>/ ;MCR PROMPT STRING .EVEN .ENDC ;M$$CLI ; MF203 .ENDC ;A$$CLI ; MF203 $ERRPT::.WORD 0 ;POINTER TO ERROR LOGGER TCB $CFLPT::.WORD 0 ;POINTER TO FIRST CHECKPOINT FILE PCB .BLKW 1 ;CLOCK INTERRUPT FORK BLOCK LINK .BLKW 1 ;CLOCK INTERRUPT FORK BLOCK PC $INTCT::.WORD -1 ;CLOCK INTERRUPT TICKS COUNT $FRKHD::.WORD 0 ;FORK QUEUE LISTHEAD .WORD $FRKHD ;(LAST POINTS TO FIRST INITIALLY) $FMASK::.WORD FMASK ;SYSTEM FEATURE MASK .WORD FMASK2 ;SYSTEM FEATURE MASK (2ND WORD) ;MSH045 .WORD FMASK3 ;SYSTEM FEATURE MASK (3RD WORD) ;MSH097 $HFMSK:: ;HARDWARE FEATURE MASK ;MSH149 ;MSH149 .IF DF M$$EIS ;MSH149 ;MSH149 .WORD HF.FPP!HF.EIS ;EIS, NO FPP ASSUMED ;MSH149 ;MSH149 .IFF ;MSH149 ;MSH149 .WORD HF.FPP ;NO FPP ASSUMED ;MSH149 ;MSH149 .ENDC ;MSH149 ;MSH142 ; ;MSH142 ; THE FOLLOWING WORDS ARE USED FOR THE POOL MONITOR INTERFACE. ;MSH142 ; THE ORDERING OF THESE WORDS CANNOT BE CHANGED BECAUSE PMT AND VMR ;MSH142 ; ARE WRITTEN TO DEPEND ON IT. ;MSH142 ; ;MSH142 ;MSH142 .IF DF P$$CTL ;MSH142 ;MSH142 $PTTCB::.WORD 0 ;TCB ADDRESS OF POOL RECOVERY TASK ;MSH142 $PRISZ::.WORD 0 ;TOTAL SIZE OF FREE POOL ;MSH142 $POLST::.WORD 0 ;EXEC/POOL TASK COMMUNICATIONS WORD ;MSH142 $PRIHL::.WORD P$$HIL ;HIGH WATER MARK FOR POOL MONITORING ;MSH142 $PRILL::.WORD P$$LOL ;LOW WATER MARK FOR POOL MONITORING ;MSH142 $PFRSZ::.WORD P$$FRS ;MINIMUM SIZE OF LARGEST FRAGMENT ;MSH142 $POLBP::.WORD P$$BPR ;MINIMUM PRIORITY OF NONPRIVILEGED ;MSH142 ;TASKS TO EXECUTE DURING LOW POOL ;MSH142 $POLFL::.WORD 0 ;EXECUTIVE POOL USAGE CONTROL FLAGS ;MSH142 ;MSH142 .IFF ;MSH142 ;MSH142 $PTTCB:: ;ALWAYS DEFINE THESE LABELS ;MSH142 $PRISZ:: ;MSH142 $POLST:: ;MSH142 $PRIHL:: ;MSH142 $PRILL:: ;MSH142 $PFRSZ:: ;MSH142 $POLBP:: ;MSH142 $POLFL:: ;MSH142 ;MSH142 .ENDC ;MSH142 ;MSH156 $WTDUM:: ;MSH156 ;MSH156 .IF DF K$$W11 ;MSH156 ;MSH156 .WORD 0 ;DUMMY WATCHDOG TIMER CSR BLOCK ;MSH156 .WORD 0 ; ;MSH156 ;MSH156 .IFTF ;MSH156 ;MSH156 $WTCSR::  ;MSH156 ;MSH156 .IFT ;MSH156 ;MSH156 .WORD $WTDUM ;WATCHDOG TIMER CSR POINTER ;MSH156 .WORD 0 ; ;MSH156 ;MSH156 .ENDC ;MSH156 .IF DF P$$RTY $PARPT::.WORD $PARTB ;PARITY ADDRESS VECTOR TABLE POINTER .IFF $PARPT::.WORD 0 ;PARITY ADDRESS VECTOR TABLE POINTER .ENDC $CLKHD::.WORD 0 ;CLOCK QUEUE $COPT:: .WORD .CO0 ;POINTER TO COMMAND OUTPUT UCB .IF NDF L$$LDR&R$$11S $PARHD::.WORD $PCBS ;POINTER TO PARTITION LIST  $LDRPT::.WORD .LDR ;POINTER TO LOADER TCB $TSKHD::.WORD $STD ;POINTER TO SYSTEM TASK DIRECTORY .IFF $PARHD::.WORD 0 ;POINTER TO PARTITION LIST $LDRPT::.WORD 0 ;POINTER TO LOADER TCB $TSKHD::.WORD $HEADR ;POINTER TO SYSTEM TASK DIRECTORY .ENDC ; ;MSH045 ; IF D$$PAR IS DEFINED, THEN A SIGNIFICANT AMOUNT OF EXECUTIVE ;MSH045 ; CODE IS PLACED IN TWO EXTERNAL 'EXECUTIVE COMMONS' IN AN EFFORT ;MSH045 ; TO MAXIMIZE THE AMOUNT OF ADDRESS SPACE TO BE DEVOTED TO MAPPING ;MSH045 ; THE DYNAMIC STORAGE REGION (POOL). THE FOLLOWING TWO POINTERS ;MSH045 ; CONTAIN THE OFFSET IN 32-WORD BLOCKS OF EACH EXECUTIVE COMMON. ;MSH045 ; THESE TWO POINTERS ARE ASSUMED TO BE CONTIGUOUS BY PRIVILEGED ;MSH045 ; CODE SUCH AS VMR. ;MSH045 ; ;MSH045 ; IF THESE POINTERS ARE ZERO, THEN THE EXECUTIVE COMMONS CANNOT ;MSH045 ; BE MAPPED (THROUGH KERNEL APR5) AND THE OPERATING SYSTEM CANNOT ;MSH045 ; FUNCTION. ;MSH045 ; ;MSH045 $XCOM1:: ;REF LABEL ;MSH045  ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 .WORD 0 ;DIRECTIVE PARTITION RELOCATION BIAS ;MSH045 ;MSH045 .IFTF ;MSH165 ;MSH165 $XCOM2:: ;REF LABEL ;MSH165 ;MSH165 .IFT ;MSH165 ;MSH165 .WORD 0 ;SECOND DIRECTIVE PAR RELOCATION BIAS ;MSH165 ;MSH165 .ENDC ;MSH045 ;MSH045 $GGEF:: ;REF LABEL ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 .WORD 0 ;GROUP GLOBAL CONTROL BLOCKS LISTHEAD ;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 $GFTCB::.WORD $GEFDM ;GRP GLOBAL USER TCB POINTER ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 $GEFPT::.WORD $GEFDM ;GROUP GLOBAL MASK ADDRESS POINTER ;MSH049 $GEFDM::.WORD 0 ;DUMMY MASK ADDRESS WORD ;MSH049 ;MSH049 .ENDC ;MSH049 ;**-1 $IDLCT::.BYTE 0 ;IDLE PATTERN COUNT BYTE $IDLFL::.BYTE 0 ;IDLE PATTERN FLAG BYTE $IDLPT:: ;MSH141 ;MSH141 .IF DF P$$P45 ;MSH141 ;MSH141 .WORD 7760 ;IDLE PATTERN WORD ;MSH141 ;MSH141 .ENDC ;MSH141 ;**-1 ; ; DAYS PER MONTH TABLE (ENTRY CONTAINS DAYS PER MONTH + 1) ; $DYPMN::.BYTE 29.,32. ;FEBRUARY, MARCH .BYTE 31.,32. ;APRIL, MAY .BYTE 31.,32. ;JUNE, JULY .BYTE 32.,31. ;AUGUST, SEPTEMBER .BYTE 32.,31. ;OCTOBER, NOVEMBER .BYTE 32.,32. ;DECEMBER, JANUARY ; ; BIT MASK TABLE ; $BTMSK::.WORD 1 ;BIT 0. .WORD 2 ;BIT 1. .WORD 4 ;BIT 2. .WORD 10 ;BIT 3. .WORD 20 ;BIT 4. .WORD 40 ;BIT 5. .WORD 100 ;BIT 6. .WORD 200 ;BIT 7. .WORD 400 ;BIT 8. .WORD 1000 ;BIT 9. .WORD 2000 ;BIT 10. .WORD 4000 ;BIT 11. .WORD 10000 ;BIT 12. .WORD 20000 ;BIT 13. .WORD 40000 ;BIT 14. .WORD 100000 ;BIT 15. ;MSH184 ; ;MSH184 ; MEMORY SHUFFLER RUN LIMITER SCRATCH AREA. $SHFTM IS LOADED WITH ;MSH184 ; THE NUMBER OF TICKS STORED IN $SHFCT WHENEVER THE SHUFFLER ENDS ;MSH184 ; EXECUTION. THIS VALUE REPRESENTS THE AMOUNT OF TIME THAT MUST ;MSH184 ; EXPIRE BEFORE THE EXECUTIVE CAN AGAIN REQUEST THE SHUFFLER. ;MSH184 ; ;MSH184 ;MSH184 $SHFTM:: ;MSH184 ;MSH184 .IF DF D$$YNM&D$$SHF ;MSH184 ;MSH184 .WORD 0 ;SHUFFLER RUN LIMITING TIMER ;MSH184 ;MSH184 .IFTF ;MSH184 ;MSH184 $SHFCT:: ;MSH184 ;MSH184 .IFT ;MSH184 ;MSH184 .WORD S$$HFC ;MINIMUM TICKS BETWEEN SHUFFLER REQUESTS;MSH184  ;MSH184 .ENDC ;MSH184 ; ; ONLINE ERROR LOGGING DATA BASE ; .IF DF E$$LOG ;DTB004 ;DTB004 $ERHEA::.WORD 0 ;ERROR LOGGING MESSAGE QUEUE LISTHEAD ;DTB004 .WORD $ERHEA ; ;DTB004 ;DTB004 $ENTSQ::.WORD 0 ;ENTRY SEQUENCE NUMBER ;DTB004 $ERRSQ::.WORD 0 ;ERROR SEQUENCE NUMBER ;DTB004 ;DTB004 $ERFLA::.BYTE 0 ;FLAG BYTE ;DTB004 ;DTB004 ES.INI == 1 ;ERRLOG INITIALIZED ;DTB004 ES.DAT == 2 ;ERRLOG RECEIVING DATA PACKETS ;DTB004 ES.LIM == 4 ;ERRLOG LIMITING ;DTB004 ES.LOG == 10 ;ERRLOG LOGGING ;DTB004 ;DTB004 $ERLOF::.BYTE 0 ;LOG FILE NAME LENGTH ;DTB004 .BLKB 34. ;LOG FILE NAME ;DTB004 ;DTB004 $ERBAF::.BYTE 0 ;BACKUP FILE NAME LENGTH ;DTB004 .BLKB 34. ;BACKUP FILE NAME ;DTB004 ;DTB004 .EVEN ;DTB004 ;DTB004 $ERFID::.BLKW 1 ;DEVICE NAME FOR LOG FILE ;DTB004 .BLKB 2 ;UNIT NUMBER AND RESERVED BYTE ;DTB004 .BLKW 3 ;FILE ID OF LOG FILE ;DTB004 ;DTB004 .ENDC ;DTB004 ;DTB004 $PRMOD::.WORD 0 ;PROCESSOR MODEL NUMBER ;DTB004 ;**-11 ; ; SYSTEM BOOTSTRAP AND SAVE CONFIGURATION VECTOR ; $SYSIZ::.WORD S$$YSZ ;SIZE OF MEMORY IN 32W BLOCKS .BLKB 1 ;PHYSICAL UNIT NUMBER OF LOAD DEVICE .BLKB 3 ;LBN OF LOAD/SAVE IMAGE ON DISK .BLKW 1 ;NAME OF LOAD DEVICE IN ASCII .BLKW 1 ;SIZE OF LOAD IMAGE IN 256W BLOCKS ; ; TIME LIMIT PARAMETERS ; .WORD -1 ;YEARS PER UNIVERSE .WORD 13. ;MONTHS PER YEAR $DPM:: .WORD 31. ;DAYS PER MONTH (CALCULATED) ;MSH123 .WORD 24. ;HOURS PER DAY ;**-1 .WORD 60. ;MINUTES PER HOUR .WORD 60. ;SECONDS PER MINUTE .IF EQ K$$CSR-177546 $TKPS:: .WORD H$$RTZ ;TICKS PER SECOND .IFF $TKPS:: .WORD K$$TPS ;TICKS PER SECOND .ENDC ; ; CURRENT TIME VECTOR ; .WORD 74. ;YEAR OF UNIVERSE .WORD 4 ;MONTH OF YEAR .WORD 29. ;DAY OF MONTH .WORD 0 ;HOUR OF DAY .WORD 0 ;MINUTE OF HOUR .WORD 0 ;SECOND OF MINUTE $TTNS:: .WORD 0  ;TICK OF SECOND ;MSH123 ; ;MSH123 ; SET SYSTEM TIME DIRECTIVE PARAMETER VALIDATION TABLE. NOTE THAT ;MSH123 ; THE HIGH LIMIT FOR THE YEAR PARAMETER CORRESPONDS TO THE ;MSH123 ; YEAR 2128. THIS SEEMINGLY RESTRICTIVE HIGH LIMIT PREVENTS USERS ;MSH123 ; FROM SPECIFYING THEIR YEAR PARAMETER BASED ON ZERO, RATHER THAN ;MSH123 ; THE YEAR 1900. ;MSH123 ; ;MSH123 ;MSH123 .IF DF S$$TIM ;MSH123 ;MSH123 $TLMTS::.WORD 200,0 ;YEAR LIMITS (BASED ON 1900) ;MSH123 .WORD 12.,1 ;MONTH LIMITS ;MSH123 .WORD 0,1 ;DAY LIMITS (HIGH DYNAMICALLY DETERMINED;MSH123 .WORD 23.,0 ;HOUR LIMITS ;MSH123 .WORD 59.,0 ;MINUTE LIMITS ;MSH123 .WORD 59.,0 ;SECOND LIMITS ;MSH123 $TIKLM::.WORD 0,0 ;TICK LIMITS (HIGH DETERMINED AT BOOT) ;MSH123 ;MSH123 .IFF ;MSH123 ;MSH123 $TIKLM:: ;REF LABEL FOR SAV ;MSH123 ;MSH123 .ENDC ;MSH123 ; ; LIFO SEND AND I/O PREALLOCATION LIST POINTER AND PARAMETERS ; .IF DF Q$$OPT $PKAVL::.WORD 0 ;POINTER TO FIRST PACKET IN LIST $PKNUM::.BYTE 0 ;NUMBER OF PACKETS CURRENTLY IN LIST $PKMAX::.BYTE Q$$OPT ;MAXIMUM NUMBER ALLOWED IN LIST .IFF $PKNUM:: ;REF LABEL FOR MCR $PKMAX:: ;REF LABEL FOR MCR .ENDC ; ; GLOBAL TASK SIZE LIMIT FOR EXTEND TASK DIRECTIVE ; .IF DF E$$XPR&M$$MGE&D$$YNM $MXEXT::.WORD 177777 ;INITIALIZE TO NO LIMIT .IFF $MXEXT:: ;REF LABEL .ENDC ; ; UMR ALLOCATION LISTHEAD AND WAIT QUEUE LISTHEAD. THE ALLOCATION ; LISTHEAD DOUBLES AS A DESCRIPTOR OF THE UMR'S STATICLY ALLOCATED TO ; THE EXEC AND ANYONE ELSE. ; .IF DF M$$EXT $UMRHD::.WORD 0 ;MAPPING ASSIGNMENT BLOCK LISTHEAD $UMRPT::.WORD UBMPR ;ADDRESS OF FIRST ASSIGNED UMR ;MSH097 .WORD N$$UMR ;NUMBER OF UMR'S STATICLY ASSIGNED * 4 ;**-1 $UMRWT::.WORD 0,.-2 ;UMR WAIT QUEUE LISTHEAD ;MSH097 .IFF ;MSH097 ;MSH097 $UMRPT:: ;REF LABEL FOR MAPPED SAV ;MSH097 .ENDC ; ;**-11 ; TEMPORARY STORAGE FOR SPAWN ; .IF DF P$$OFF $TEMP0::.WORD 0 $TEMP1::.WORD 0 .ENDC ;P$$OFF ; ;MSH046 ; TEMPORARY STORAGE AREA FOR $GSPKT AND GCCI$ DIRECTIVE ;MSH046 ; ;MSH046 ;MSH046 .IF DF A$$BIO!A$$CLI!R$$POI!R$$UDA ;MSH159 ;MSH046 $TEMP2::.BLKW 1 ;TEMPORARY STORAGE ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 ; ; MF207 ; TEMPORARY STORAGE FOR THE RPOI$ AND SDRP$ DIRECTIVES ; MF207 ; ; MF207 ; MF207 ; MF207 .IF DF R$$POI&P$$OFF ; MF207 ; MF207 $TEMP4::.WORD 0 ; MF207 ; MF207 .ENDC ;R$$POI&P$$OFF ; MF207 ; MF207 .IF DF A$$NSI ;MSH150 ;MSH150 $AVRHD::.WORD 0 ;AVR UNIT TABLE LISTHEAD ;MSH150 ;MSH150 .ENDC ;MSH150 ;MSH150 $MOULS::.WORD 0 ;MOUNTED DEVICE LISTHEAD ;**-1 $CXDBL::.BYTE 0 ;CONTEXT SWITCHING DISABLED FLAG (0=NO) .BYTE 0 ;UNUSED BYTE ;MSH079 ;MSH079 $SYSNM::.WORD S$$NM1,S$$NM2,S$$NM3 ;SYSTEM NAME ;MSH079 ;MSH079 .IF DF M$$NET ;MSH079 ;MSH080 $NTUIC::.WORD SYUIC ;NETWORK UIC ;MSH080 $NETPF::.WORD 0 ;NETWORK POWERFAIL RECOVERY ROUTINE ;MSH128 ;MSH128 .ENDC ;MSH079 ; MF203 .IF DF A$$CLI ; MF203 ; MF203 ; ; MF203 ; THE FOLLOWING STRUCTURES FORM THE DATA BASE FOR ALTERNATE CLI SUPPORT ; MF203 ; ; MF203 ; MF203 $CLICQ::.WORD 0 ;COMMAND QUEUE FOR CLIS ; MF203 .WORD $CLICQ ; ; MF203 ; ; MF203 ; THE FOLLOWING TABLE CONTAINS POINTERS TO THE CPB BLOCKS FOR CLIS THAT ; MF203 ; THE SYSTEM KNOWS ABOUT. THIS TABLE IS INDEXED BY BITS 1 - 4 OF U.MUP I; MF203 ; THE TERMINALS UCB, TO DETERMINE THE CLI ASSOCIATED WITH THAT TERMINAL ; MF203 ; MF203 $CPTBL::.WORD $MCRPT ;ENTRY FOR MCR TERMINALS ; MF203 ; MF203 .REPT A$$CLI-1 ; MF203 ; MF203 .WORD 0 ;SPACE FOR USER WRITTEN CLIS ; MF203 ; MF203 .ENDR ; MF203 ; MF203 $NMCLI==A$$CLI ;NUMBER OF CLIS SYSTEM WILL SUPPORT ; MF203 ; MF203 ; ; MF203 ; CLI PARSER BLOCK (CPB) FOR THE MCR CLI ; MF203 ; ; MF203 $MCRPT::.WORD 0 ;POINTER TO MCR TCB ; MF203 .RAD50 /MCR / ;NAME OF CLI ; MF203 .WORD CP.SGL!CP.LGO ;NO CONT. LINES, ALLOW LOGGED OFF TT'S ; MF203 .BYTE MDPL ;LENGTH OF DEFAULT PROMPT ; MF203 .BYTE MCPL ;LENGTH OF CNTRL/C PROMPT ; MF203 $$$=. ; MF203 .ASCIZ <15><12>/>/ ;DEFAULT PROMPT STRING ; MF203 MDPL=.-$$$ ; MF203 $$$=. ; MF203 .ASCIZ <15><12>/MCR>/ ;CNTRL/C PROMPT STRING ; MF203 MCPL=.-$$$ ; MF203 ; MF203 .EVEN ; MF203 ; MF203 .IFF ;A$$CLI ; MF203 ; MF203 $CLICQ:: ; MF203 $CPTBL:: ; MF203 $NMCLI==0 ;NO ALTERNATE CLI SUPPORT ; MF203 ; MF203 .ENDC ;A$$CLI ; MF203 ; DD098 .IF DF T$$CPW&T$$ACD ; DD098 ; DD098 $ACDHD::.WORD 0 ;ANCILL ARY CONTROL DRIVER BLOCK LISTHEAD; DD098 ; DD098 .ENDC ;T$$CPW&T$$ACD ; DD098 ;**-1 $CMFIN:: ;END OF SYSCM AREA FOR CDA .END  ¼8ðskQ ›c, .TITLE ICDRV .IDENT /02.05/ ; ; COPYRIGHT (C) 1975,1978,1979,1980 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.05 ; ; C. MONIA 05-APR-75 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; C. A. MONIA ; ; MODIFIED BY: ; ; G. H. KUENNING 09-AUG-77 ; ; GK001 -- CHECK FOR EXISTENCE OF CIRCULAR BUFFER ; BEFORE USING IT. (SPR # 11-12905). ; ; G. H. KUENNING 13-OCT-77 ; ; GK002 -- WHEN UNLINKING INTERRUPTS FROM TASKS, DON'T ; RESTORE REGISTERS THAT WEREN'T SAVED. ; ; G. H. KUENNING 17-JAN-78 ; ; GK004 -- MOVE A MISPLACED LABEL THAT CAUSES A SYSTEM ; CRASH WHEN AN I/O CANCEL IS DONE ON AN ICS/ICR. ; ; G. H. KUENNING 30-JAN-79 ; ; GK005 -- ON STARTUP, READ THE CURRENT STATE OF THE ; DIGITAL INTERRUPT POINTS RATHER THAN SETTING THE ; CURRENT STATE TO ZERO. ; ; J. H. MATTHEWS 1-OCT-79 ; ; JM043 -- RESTORE R4 AT END OF "READDI" (FROM S. HIMMELSTEIN) ; ; T. LEKAS 27-MAY-80 ; ; TL045 -- FIX CONDITIONAL ASSEMBLY ; ; H. BERNSTEIN 8-DEC-80 ; ; HB001 -- FIX CONDITIONAL ASSEMBLY ; ; ICR/ICS-11 INDUSTRIAL CONTROL SUBSYSTEM DRIVER ; ; EQUATED SYMBOLS ; ; A/D CONVERTER TABLE OFFSETS ; .ASECT .=0 ADMXC: .BLKW 1 ; MAXIMUM A/D CHANNEL NUMBER ADFR: .BLKB 1 ; FORK REQUEST FLAG ADIP: .BLKB 1 ; I/O CONVERSIONS IN-PROGRESS COUNT ADNXT: .BLKW 1 ; TABLE ADDRESS OF NEXT ADU02 ADNXA: .BLKW 2 ; USER BUFFER ADDRESS DOUBLEWORD OF NEXT ADNXB: .BLKW 1 ; BYTE COUNT FOR NEXT TRANSFER ADNXC: .BLKW 1 ; CONTROL WORD FOR NEXT TRANSFER ADFBC: .BLKW 1 ; FINAL BYTE COUNT ADSTS: .BLKW 1 ; I/O COMPLETION STATUS ; ; A/D CONVERTER TABLE ENTRY OFFSETS ; .=0 ADHCH: .BLKB 1 ; HIGHEST CHANNEL NUMBER ON THIS MODULE ADBSY: .BLKB 1 ; ADU02 BUSY FLAG ADUAD: .BLKW 2 ; ADDRESS DOUBLEWORD ADBTC: .BLKW 1 ; BYTE COUNT FOR THIS CONVERSION ADMBA: .BLKW 1 ; ADU02 BUS ADDRESS ADLGH: .BLKW 0 ; LENGTH OF A/D MODULE ENTRY  ; ; CIRCULAR BUFFER HEADER OFFSETS ; .=0 CBSY: .BLKW 1 ; BUSY COUNT COUT: .BLKW 1 ; OUTPUT POINTER CIN: .BLKW 1 ; INPUT POINTER CMAX: .BLKW 1 ; ADDRESS OF END OF BUFFER CDAT: .BLKW 16. ; DATA AREA CLGH: .BLKW 0 ; LENGTH OF CIRCULAR BUFFER ; ; ICR DEVICE TABLE OFFSETS ; .=0 ICMAX: .BLKW 1 ; MAXIMUM PHYSICAL UNIT NUMBER ICRES: .BLKW 1 ; ERROR RESOURCE MASK ICELH: .BLKW 2 ; ERROR INTERRUPT LISTHEAD ICLTL: .BLKW 2 ; LINKED TASK LISTHEAD ; ; INTERRUPT LINKAGE ENTRY OFFSETS ; .=0 ILNXT: .BLKW 1 ; LINK TO NEXT ILMSK: .BLKW 1 ; RESOURCE MASK WORD ILTE: .BLKW 1 ; ADDRESS OF LINKED TASK ENTRY ILEVM: .BLKW 1 ; EVENT FLAG MASK WORD ILEVA: .BLKW 1 ; EVENT FLAG MASK ADDRESS ILRUN: .BLKW 1 ; RUN FLAG ILGH: .BLKW 0 ; LENGTH OF ENTRY ; ; UNSOLICITED INTERRUPTING MODULE OFFSETS ; .=0 IMAX: .BLKW 1 ; HIGHEST POINT OR CHANNEL IMBPE: .BLKB 1 ; BYTES PER CIRCULAR BUFFER ENTRY IMFIP: .BLKB 1 ; FORK-IN-PROGRESS FLAG IMSBF: .BLKW 1 ; STARTING BUFFER RELOCATION BIAS IMCBF: .BLKW 1 ; CURRENT BUFFER RELOCATION BIAS IMSAD: .BLKW 1 ; ADDRESS OF START OF BUFFER IMSDA: .BLKW 1 ; ADDRESS OF START OF DATA IMCUR: .BLKW 1 ; ADDRESS OF CURRENT ENTRY IMFIL: .BLKW 1 ; CURRENT FORTRAN FILL INDEX IMLGH: .BLKW 1 ; LENGTH OF CIRCULAR BUFFER IN WORDS IMEVM: .BLKW 1 ; EVENT FLAG MASK WORD IMEVA: .BLKW 1 ; EVENT FLAG MASK ADDRESS IMLST: .BLKW 1 ; LOST DATA COUNT IMTCB: .BLKW 1 ; TCB ADDRESS OF CONNECTED TASK IMFRK: .BLKW 3 ; INTERRUPT FORK BLOCK IMSCB: .BLKW 1  ; SCB BACKPOINTER IMDAT: .BLKW 0 ; OFFSET TO MODULE DATA ; ; INTERRUPT MODULE ENTRY OFFSETS ; .=0 IMRES: .BLKW 1 ; DIGITAL INTERRUPT RESOURCE MASK IMLH: .BLKW 2 ; INTERRUPT LINK LISTHEAD IMPRV: .BLKW 1 ; PREVIOUS STATE OF MODULE RTLGH: .BLKW 0 ; LENGTH OF REMOTE TERMINAL ENTRY IMBA: .BLKW 1 ; BUS ADDRESS OF MODULE CILGH: .BLKW 0 ; LENGTH OF DIGITAL INTERRUPT ENTRY CTLGH: .BLKW 0 ; LENGTH OF COUNTER MODULE ENTRY ; ; LINKED TASK ENTRY OFFSETS ; .=0 LNEXT: .BLKW 1 ; LINK TO NEXT (0=NONE) LUSE: .BLKW 1 ; NUMBER OF LINKAGES IN USE LTCB: .BLKW 1 ; TASK TCB ADDRESS LACT: .BLKW 1 ; ACTIVITY COUNT LPHY: .BLKW 1 ; PHYSICAL UNIT NUMBER LGEN: .BLKW 1 ; GENERIC CODE LREL: .BLKW 1 ; RELATIVE MODULE NUMBER LHWR: .BLKW 2 ; HARDWARE DEPENDANT DATA LPAD: .BLKW 1 ; PAD ENTRY TO MULTIPLE OF ALLOCATION INCREMENT LLGH: .BLKW 0 ; LENGTH OF ENTRY ; ; QIO ADDRESS CHECKING FLAGS ; CHADR=000001 ; BUFFER ADDRESS MUST BE ON WORD BOUNDARY (1=YES) CHBYT=000002 ; BYTE COUNT MUST BE EVEN(1=YES) ; ; SCB FLAGS WORD BIT DEFINITIONS ; UFL=000001 ; UNIT OFFLINE (1=YES) UNR=000002 ; UNIT NOT-READY (1=YES) TUND=000004 ; TERMINAL OUTPUT UNDERWAY (1=YES) TUSE=000010 ; TERMINAL IN USE (1=YES) NORSP=000020 ; NO RESPONSE FROM CONTROLLER (1=YES) TABO=000040 ; ABORT TERMINAL OUTPUT (1=YES) ; ; ICS/ICR INTERRUPT TIMEOUT COUNT ; TMOUT=50. ; ; ; FIRST EXTERNAL PAGE ADDRESS ; ICMD=171000 ; .PSECT ; ; LOCAL DATA ; ; DRIVER DISPATCH TABLE ;  $ICTBL::.WORD ICHK ; DEVICE INITIATOR ENTRY POINT .WORD ICAN ; CANCEL I/O OPERATION ENTRY POINT .WORD ICOUT ; DEVICE TIMEOUT ENTRY POINT .WORD ICPWF ; POWER RECOVERY ENTRY POINT ; ; UCB ADDRESSES ; .IF DF I$$CAD!I$$CIM!I$$CTI!I$$CR CNTBL: .BLKW I$$C11 ; ; ; ADDRESS OF CURRENT CSR ; CSR: .BLKW 1 ; ; ; ICR DEVICE TABLE ; .IF DF I$$CLK ICDVT: .WORD I$$C11-1 ; MAXIMUM PHYSICAL UNIT NUMBER .WORD 0 ; ERROR INTERRUPT RESOURCE MASK .WORD 0 ; ERROR INTERRUPT LISTHEAD .WORD .-2 ; LAST POINTS TO FIRST INITIALLY .WORD 0 ; LINKED TASK LISTHEAD .WORD .-2 ; LAST POINTS TO FIRST INITIALLY .ENDC .ENDC ; ; LEGAL FUNCTION CODES AND DISPATCH TABLE ; ; EACH ENTRY CONSISTS OF TWO WORDS CONTAINING THE FOLLOWING ; INFORMATION: ; ; WD. 00 -- QIO FUNCTION CODE. ; WD. 01 -- ADDRESS OF PROCESSOR/2 ! CONTROL FUNCTION FLAG (MSB). ; ; IF MSB .EQ. 1 THEN THE FUNCTION REQUIRES THE TRANSMISSION OF DATA ; TO OR FROM THE DEVICE. ; ICDIS: ; .IF DF I$$CDA .WORD IO.SAO,100000! ; ANALOG OUTPUT .ENDC .IF DF I$$CSS .WORD IO.MSO,100000! ; MOMENTARY DIGITAL OUTPUTS .ENDC .IF DF I$$CLT .WORD IO.MLO,100000! ; LATCHING OUTPUTS .ENDC .IF DF I$$CAD .WORD IO.RBC!CHADR!CHBYT,100000! ; READ MULTIPLE A/D CHANNELS .ENDC .IF DF I$$CIM .WORD IO.CCI!CHADR!CHBYT,CICNT/2&77777 ; CONTACT INTERRUPT CONNECT .WORD IO.DCI,CIDCT/2&77777 ; CONTACT INTERRUPT DISCONNECT  .IF DF I$$CLK .WORD IO.LDI,CILNK/2&77777 ; LINK TO DIGITAL INTERRUPTS .WORD IO.UDI,CIUNL/2&77777 ; UNLINK DIGITIAL INTERRUPTS .ENDC .ENDC .IF DF I$$CTI .WORD IO.CTI!CHADR!CHBYT,100000! ; COUNTER MODULE CONNECT .WORD IO.DTI,CTDCT/2&77777 ; COUNTER MODULE DISCONNECT .IF DF I$$CLK .WORD IO.LTI,CTLNK/2&77777 ; LINK TO COUNTER MODULE INTERRUPTS .WORD IO.UTI,CTUNL/2&77777 ; UNLINK FROM COUNTER INTERRUPTS .ENDC .WORD IO.ITI,100000! ; INITIALIZE COUNTER .ENDC .IF DF I$$CR .WORD IO.WLB,100000! ; OUTPUT TO REMOTE TERMINAL .WORD IO.CTY!CHADR!CHBYT,RTCNT/2&77777 ; REMOTE TERMINAL CONNECT .WORD IO.DTY,RTDCT/2&77777 ; REMOTE TERMINAL DISCONNECT .IF DF I$$CLK .WORD IO.LTY,RTLNK/2&77777 ; LINK TO REMOTE TERMINAL INTERRUPTS .WORD IO.UTY,RTUNL/2&77777 ; UNLINK REMOTE TERMINAL INTERRUPTS .WORD IO.LKE,ERLNK/2&77777 ; LINK TO ERROR INTERRUPTS .WORD IO.UER,ERUNL/2&77777 ; UNLINK ERROR INTERRUPTS .ENDC .ENDC .IF DF I$$CIM!I$$CTI!I$$CR&I$$CLK .WORD IO.NLK,UNLNK/2&77777 ; UNLINK FROM ALL INTERRUPTS .IFTF .WORD IO.ONL,ICONL/2&77777 ; UNIT TO ONLINE .WORD IO.FLN,ICFLN/2&77777 ; UNIT TO OFFLINE .IFT .WORD IO.RAD,RDACT/2&77777 ; READ ACTIVATING DATA .ENDC .IF DF I$$CDB .WORD IO.ATT,ICDON/2&77777 ; NO-OP THE ATTACH FUNCTION .WORD IO.DET,ICDON/2&77777 ; NO-OP THE DETACH FUNCTION .ENDC .WORD 0 ; END OF TABLE ; ; ADDRESS OF CURRENT UCB ; .IF DF I$$CAD!I$$CIM!I$$CR!I$$CTI .IF GT I$$C11-1 ICUCB: .BLKW 1 ; .ENDC ; ; FLAG TO INTIATE FORK PROCESSING FOR UNSOLICITED INTERRUPTS ; RUN: .BLKW 1 ; ; ; NAME OF TASK BEING UNLINKED ; .IF DF I$$CLK TASK: .BLKW 2 ; .ENDC ; ; TEMPORARY INTERRUPT PSW STORAGE ; TMP: .WORD 0 ; ; ; WATCHDOG TIMER FLAG ; .IF DF I$$CR WDFLG: .WORD 0 ; IF NE 0 THEN TIMER SCHEDULED .BLKW 5 ; CLOCK QUEUE ENTRY .WORD ICWDT ; ADDRESS OF INTERNAL SUBROUTINE .IF DF L$$DRV&M$$MGE  .WORD 0 ; .ENDC .ENDC .ENDC ;+ ; ; **-ICHK-ICS/ICR-11 INDUSTRIAL CONTROL SUBSYSTEM PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM QIO DIRECTIVE PROCESSING WHEN AN ; I/O REQUEST IS RECIEVED FOR THE ICS/ICR-11 INDUSTRIAL CONTROL ; SUBSYSTEMS DEVICES. ICS/ICR-11 REQUESTS CONTAIN PARAMETERS THAT ; MUST BE CHECKED IN THE CONTEXT OF THE ISSUING TASK. THEREFORE ; THE I/O REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET ; R4=ADDRESS OF THE STATUS CONTROL BLOCK ; R5=ADDRESS OF THE UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; DEPENDANT UPON FUNCTION TO BE PERFORMED ; ; ICS/ICR-11 FUNCTION INDEPENDANT I/O PACKET ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF REQUESTER TASK TCB. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE. ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; ;- ICHK: ; MOV R1,-(SP) ; SAVE I/O PACKET ADDRESS MOV I.FCN(R1),R2 ; GET FUNCTION CODE BIC #7,R2 ; CLEAR UNRECOGNIZED FLAGS ADD #I.PRM,R1 ; POINT TO PARAMETER BLOCK MOV #ICDIS-2,R3 ; POINT TO DISPATCH TABLE 10$: ; TST (R3)+ ; STEP TO NEXT ENTRY TST (R3) ; AT END OF LIST? BEQ ICIF  ; IF EQ YES - ILLEGAL FUNCTION MOV (R3)+,-(SP) ; PUSH FUNCTION CODE BIC #7,(SP) ; CLEAR FLAGS CMP (SP)+,R2 ; TEST FUNCTION CODE BNE 10$ ; IF NE TRY NEXT FUNCTION MOV R1,R0 ; COPY PARAMETER BLOCK ADDRESS MOV -2(R3),R2 ; GET FUNCTION CODE AGAIN 12$: ; BIC #^C<7>,R2 ; CLEAR ALL BUT ALIGNMENT FLAGS BEQ 15$ ; IF EQ NO MORE TESTS TO MAKE TST (R0)+ ; STEP TO NEXT PARAMETER ROR R2 ; ROTATE ALIGNMENT FLAGS BCC 12$ ; IF C/C BYPASS CHECK BIT #1,(R0) ; PARAMETER WORD ALIGNED? BNE ICBY ; IF NE NO BR 12$ ; GO AGAIN 15$: ; MOV (R3),R3 ; GET ADDRESS OF PROCESSOR ASL R3 ; CONVERT TO WORD ADDRESS, PUT CONTROL FLAG IN C MOV I.TCB-I.PRM(R1),R0 ; GET TCB ADDRESS BCC 20$ ; IF C/C NOT A CONTROLLER FUNCTION BIT #UFL,S.FLG(R4) ; UNIT OFFLINE? .IF DF I$$CR BNE 17$ ; IF NE YES BIT #UNR,S.FLG(R4) ; UNIT NOT READY? BNE ICDN ; IF NE YES BR 20$ ; ALLOW I/O .IFF BEQ 20$ ; IF EQ NOT OFFLINE .ENDC 17$: ; BIT #T3.PRV,T.ST3(R0) ; TASK PRIVILEGED?  BEQ ICPR ; IF EQ NO, PRIVELEGE VIOLATION 20$: ; JMP (R3) ; TRANSFER CONTROL TO PROCESSOR ;+ ; ; **-ICFLN-PUT CONTROLLER OFFLINE ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- UNUSED ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- ICFLN: ; BIT #T3.PRV,T.ST3(R0) ; TASK PRIVILEGED? BEQ ICPR ; IF EQ NO BIT #UFL,S.FLG(R4) ; UNIT ALREADY OFFLINE? BNE ICFLE ; IF NE YES MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS BIC #22,@S.CSR(R4) ;;; DISABLE ERROR INTERRUPTS BIS #UFL,S.FLG(R4) ;;; SET UNIT OFFLINE CLRB PS ; ALLOW DEVICE INTERRUPTS BR ICD ; ;+ ; ; **-ICONL-PLACE CONTROLLER ONLINE ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- UNUSED ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- ICONL: ; BIT #T3.PRV,T.ST3(R0) ; TASK PRIVILEGED? BEQ ICPR ; IF EQ NO MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS BIS #26,@S.CSR(R4) ;;; ENABLE INTERRUPTS BIC #UFL!UNR,S.FLG(R4) ;;; CLEAR NOT-READY, OFFLINE BITS CLRB PS ; ALLOW DEVICE INTERRUPTS ; ; INTERMEDIATE BRANCH POINTS TO ERROR EXITS ; ICD: JMP ICDON ; SUCCESSFUL COMPLETION ICBY: JMP ICBYT ; BUFFER BYTE ALIGNED ICIF: JMP ICIFC ; ILLEGAL FUNCTION CODE ICDN: JMP ICDNR ; DEVICE NOT READY ICPR: JMP ICPRI ; PRIVELEGE VIOLATION ICMO: JMP ICMOD ; ILLEGAL MODULE NUMBER .IF DF I$$CLK ICIE: JMP ICIEF ; ILLEGAL EVENT FLAG .ENDC ; ; REQUEST HAS BAD PARAMETERS ; ICBAD: ; MOV #IE.BAD&377,R0 ; BR ICFLE1 ; ; ; RESOURCE IN USE ; .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK ICRSU: ; MOV #IE.RSU&377,R0 ; BR ICFLE1 ; .ENDC ; ; DEVICE ALREADY OFFLINE ; ICFLE: ; MOV #IE.FLN&377,R0 ; ICFLE1: ; JMP ICOMN ; ;+ ; ; **-CILNK-LINK TO CONTACT INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- POINT NUMBER ; WD. 17 -- CHANGE OF STATE MASK ; ;- .ENABL LSB .IF DF I$$CLK .IF DF I$$CIM CILNK: ; MOV S.DI(R4),R0 ; GET ADDRESS OF CONTACT INTERRUPT TABLE MOV 10(R1),R2 ; GET POINT NUMBER BIT #17,R2 ; POINT ON MODULE BOUNDARY? BNE ICMO ; IF NE NO ASR R2 ; COMPUTE TABLE INDEX ASR R2 ; ... ADD 10(R1),R2 ; ... ASR R2 ; ... MOV 12(R1),4(R1) ; SET RESOURCE MASK BEQ ICBAD ; IF EQ BAD PARAMETERS CLR 12(R1) ; CLEAR COUNTER FLAG BR 20$ ; .ENDC ;+ ; ; **-CTLNK-LINK TO COUNTER MODULE INTERRUPTS: ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- RELATIVE COUNTER NUMBER ; WD. 17 -- COUNTER INITIAL VALUE ; ;- .IF DF I$$CTI CTLNK: ; MOV S.CT(R4),R0 ; GET ADDRESS OF COUNTER TABLES MOV 10(R1),R2 ; GET COUNTER NUMBER ASL R2 ; COMPUTE TABLE INDEX ASL R2 ; ... ADD 10(R1),R2 ; ...  ASL R2 ; ... BR 10$ ; .ENDC ;+ ; ; **-ERLNK-LINK TO ERROR INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CR ERLNK: ; MOV #ICDVT+ICRES,R2 ; POINT TO RESOURCE MASK MOV #-1,4(R1) ; SET RESOURCE MASK FOR REQUEST CLR 12(R1) ; CLEAR COUNTER FLAG BR 30$ ; ;+ ; ; **-RTLNK-LINK TO REMOTE TERMINAL INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 __ WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- RTLNK: ; MOV S.RTI(R4),R0 ; GET REMOTE TERMINAL TABLE ADDRESS CLR R2 ; CLEAR OFFSET TO MODULE ENTRY CLR 10(R1) ; CLEAR MODULE NUMBER CLR 12(R1) ; CLEAR COUNTER FLAG .ENDC .IF DF I$$CIM!I$$CR!I$$CTI 10$: ; MOV #-1,4(R1) ; SET RESOURCE MASK 20$: ; TST R0 ; MODULE EXIST BEQ ICMO ; IF EQ NO CMP 10(R1),(R0) ; LEGAL POINT NUMBER BHI ICMO ; IF HI NO ADD R0,R2 ; COMPUTE MODULE ENTRY ADDRESS ADD #IMDAT+IMRES,R2 ; POINT TO RESOURCE MASK 30$: ; BIT 4(R1),(R2)+ ; RESOURCE IN USE? BNE ICRSU ; IF NE YES MOV R1,R3 ; COPY ADDRESS OF TASK NAME CALL $SRSTD ; SEARCH TCB LIST FOR TASK BCS ICNST ; IF C/S TASK NOT INSTALLED CMP 6(R1),#64. ; LEGAL EVENT FLAG SPECIFIED? BHI ICIE ; IF HI NO MOV R2,(R1)+ ; SAVE LISTHEAD ADDRESS MOV R5,-(SP) ; SAVE R5 MOV R1,-(SP) ; SAVE ADDRESS OF PARAMETER BLOCK MOV R0,R5 ; COPY TCB ADDRESS MOV 4(R1),R0 ; GET EVENT FLAG NUMBER CALL $CEFI ; CONVERT TO MASK AND ADDRESS MOV (SP),R3 ; COPY PARAMETER BLOCK ADDRESS MOV R0,(R3)+ ; SAVE MASK MOV (R3)+,(R3) ; MOVE RESOURCE MASK OUT OF THE WAY MOV R1,-(R3) ; SAVE ADDRESS MOV #LLGH+ILGH,R1 ; GET LENGTH OF LINKED TASK+INTERRUPT LINK ENTRIES MOV #ICDVT+ICLTL,R3 ; POINT TO INTERRUPT LINK LISTHEAD 40$: ; MOV (R3),R3 ; GET ADDRESS OF NEXT ENTRY BEQ 50$ ; IF EQ REACHED END OF LIST CMP R5,LTCB(R3) ; THIS TASK LINKED ONCE? BEQ 60$ ; IF EQ YES BR 40$ ; GO AGAIN 50$: ; CALL $ALOCB ; ALLOCATE BLOCK BCS ICNOD ; IF C/S NO MORE STORAGE CLR (R0) ; CLEAR LINK TO NEXT MOV R0,@ICDVT+ICLTL+2 ; LINK TO LAST ENTRY MOV R0,ICDVT+ICLTL+2 ; SET NEW LAST MOV R5,LTCB(R0) ; SET TCB ADDRESS CLR LUSE(R0) ; CLEAR USE COUNT CLR LACT(R0) ; CLEAR ACTIVITY COUNT MOV R0,R5 ; COPY LINKED TASK ENTRY ADDRESS ADD #LLGH,R0 ; POINT TO INTERRUPT LINK ENTRY BR 70$ ; 60$: ; MOV R3,R5 ; COPY LINKED TASK ENTRY MOV #ILGH,R1 ; SET LENGTH OF INTERRUPT LINK ENTRY CALL $ALOCB ; ALLOCATE BLOCK BCS ICNOD ; IF C/S NO STORAGE AVAILABLE 70$: ; INC LUSE(R5) ; INCREMENT USE COUNT MOV R5,ILTE(R0) ; SET POINTER TO LINKED ENTRY MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R5 ; RESTORE R5 MOV -2(R1),R2 ; RETRIEVE INTERRUPT LINK LISTHEAD MOV R0,R3 ; COPY ADDRESS OF INTERRUPT LINK ENTRY CLR (R3)+ ; CLEAR LINK TO NEXT CMP (R3)+,(R3)+ ; POINT TO EVENT FLAG MASK MOV (R1)+,(R3)+ ; SAVE EVENT FLAG MASK MOV (R1)+,(R3)+ ; SAVE EVENT FLAG ADDRESS CLR (R3) ; CLEAR RUN FLAG MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS MOV R0,@2(R2) ;;; LINK THIS ENTRY AS LAST MOV R0,2(R2) ;;; SET NEW LAST BIS (R1),-(R2) ;;; SET RESOURCE MASK MOV (R1)+,ILMSK(R0) ;;; SET INTERRUPT MASK CLRB PS ; ALLOW DEVICE INTERRUPTS .IF DF I$$CTI MOV IMBA(R2),(R1) ; COPY BUS ADDRESS MOV 2(R1),-(R1) ; COPY COUNTER VALUE BEQ 80$ ; IF EQ COUNTER NOT TO BE SET MOV (R1),IMPRV(R2) ; RESET PREVIOUS STATE MOV R1,R3 ; SET ADDRESS OF MODULE ENTRY CALL SETCT ; INITIALIZE COUNTER 80$: ; .ENDC BR ICDO ; .ENDC .ENDC .DSABL LSB ; ; TASK NOT INSTALLED ; .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK ICNST: ; MOV #IE.NST&377,R0 ; BR ICOM ; .ENDC ;+ ; ; **-RDACT-READ ACTIVATING DATA ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- ADDRESS OF BUFFER TO RECEIVE ACTIVATING INFORMATION ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK RDACT: ; BIT #1,(R1) ; BUFFER WORD ALIGNED? BNE ICBYT ; IF NE NO MOV #ICDVT+ICLTL,R4 ; GET ADDRESS OF LINKED TASK LISTHEAD 10$: ; MOV (R4),R4 ; GET ADDRESS OF NEXT ENTRY BEQ ICNLK ; IF EQ TASK NOT LINKED TO INTERRUPTS CMP LTCB(R4),R0 ; THIS ENTRY BELONG TO TASK? BNE 10$ ; IF NE NO MOV (R1),R0 ; GET ADDRESS OF BUFFER TO RECEIVE DATA MOV #LPAD-LACT,R3 ; SET BYTE COUNT .IF DF A$$CHK!M$$MGE MOV R3,R1 ; COPY BYTE COUNT CALL $ACHCK ; ADDRESS CHECK BUFFER BCS ICSP ; IF C/S BUFFER NOT IN REQUESTORS SPACE .ENDC .IF DF M$$MGE CALL $RELOM ; RELOCATE AND MAP BUFFER .ENDC ADD #LACT,R4 ; POINT TO ACTIVITY COUNT ASR R3 ; SHIFT BYTE COUNT TO WORD COUNT MOVB #PR6,PS ;;; INHIBIT INTERRUPTS 20$: ;;; MOV (R4),(R0)+ ;;; COPY ENTRY CLR (R4)+ ;;; CLEAR ENTRY DEC R3 ;;; DECREMENT COUNT BNE 20$ ;;; IF NE GO AGAIN CLRB PS ; ALLOW DEVICE INTERRUPTS BR ICDO ; .ENDC ; ; TASK NOT LINKED TO INTERRUPTS ; .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK ICNLK: ; MOV #IE.NLK&377,R0 ; BR ICOM ; ; ; BUFFER IS BYTE ALIGNED ; .IFTF ICBYT: ; MOV #IE.BYT&377,R0 ; .IFT BR ICOM ; ; ; INSUFFICIENT DYNAMIC STORAGE AVAILABLE TO ALLOCATE SECODARY CONTROL BLOCK ; ; NOTE: AT THIS POINT THE STACK CONTAINS: ; ; (SP)+00 - PREVIOUS CONTENTS OF R1 (MAY BE DISCARDED), ; (SP)+02 - PREVIOUS CONTENTS OF R5 (MUST BE RESTORED). ; ; ICNOD: ; MOV (SP)+,R1 ; RESTORE R1 MOV (SP)+,R5 ; RESTORE UCB ADDRESS MOV #IE.NOD&377,R0 ; ; ; INTERMEDIATE BRANCH POINTS TO ERROR EXITS ; .IFTF ICOM: JMP ICOMN ; COMMON ERROR EXIT .IFT ICDO: JMP ICDON ; SUCCESFUL COMPLETION ICSP: JMP ICSPC ; BUFFER OUT OF REQUESTORS ADDRESSS SPACE .ENDC ;+ ; ; **-UNLNK-UNLINK A TASK FROM ALL INTERRUPTS ON UNIT ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK UNLNK: ; CLR -(SP) ; RESET SUCCESS FLAG .IF DF I$$CIM CALL CIUNL1 ; UNLINK FROM CONTACT INTERRUPTS BCS 40$ ; IF C/S NOT LINKED TO ANY INTERRUPTS BMI 10$ ; IF MI NOT LINKED TO THIS TYPE INC (SP) ; SET SUCCESS FLAG 10$: ; .ENDC .IF DF I$$CTI CALL CTUNL1 ; UNLINK FROM COUNTER MODULE INTERRUPTS BCS 40$ ; IF C/S NOT LINKED TO ANY INTERRUPTS BMI 20$ ; IF MI NOT LINKED TO THIS TYPE INC (SP) ; SET SUCCESS 20$: ; .ENDC .IF DF I$$CR CALL RTUNL1 ; UNLINK FROM REMOTE TERMINAL INTERRUPTS BCS 40$ ; IF C/S NOT LINKED TO ANY INTERRUPTS BMI 30$ ; IF MI NOT LINKED TO THIS TYPE INC (SP) ; SET SUCCESS 30$: ; CALL ERUNL1 ; UNLINK FROM ERRORS BMI 40$ ; IF MI NOT LINKED TO ERRORS INC (SP) ; SET SUCCESS .ENDC 40$: ; MOV #IE.NLK&377,R0 ; ASSUME NOT LINKED TO ANY INTERRUPTS TST (SP)+ ; TEST SUCCESS FLAG BEQ ICOM ; IF EQ NOT LINKED TO ANY INTERRUPTS BR ICDO ; SUCCESFUL EXIT ;+ ; ; **-CIUNL-UNLINK TASK FROM CONTACT INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .ENABL LSB .IF DF I$$CIM CIUNL: ; MOV #ICOMN,-(SP) ; SET TRANSFER ADDRESS CIUNL1: ; MOV #IE.MOD&377,-(SP) ; ASSUME NON-EXISTENT MODULE TYPE MOV S.DI(R4),R4 ; GET TABLE ADDRESS BEQ 80$ ; IF EQ MODULE NOT INSTALLED MOV (R4),R2 ; GET POINT COUNT-15. ASR R2 ; CONVERT TO NUMBER OF MODULES ASR R2 ; ... ASR R2 ; ... ASR R2 ; ... MOV R2,6(R1) ; SAVE MODULE-1 COUNT MOV #CILGH,4(R1) ; SAVE ENTRY SIZE BR UNL ; TO COMMON UNLINK CODE .ENDC ;+ ; ; **-CTUNL-UNLINK TASK FROM COUNTER INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 O F RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CTI CTUNL: ; MOV #ICOMN,-(SP) ; PUSH TRANSFER ADDRESS CTUNL1: ; MOV #IE.MOD&377,-(SP) ; ASSUME NON-EXISTENT MODULE TYPE MOV S.CT(R4),R4 ; GET ADDRESS OF TABLES BEQ 80$ ; IF EQ NONE MOV (R4),6(R1) ; SET NUMBER OF HIGHEST MODULE MOV #CTLGH,4(R1) ; SET ENTRY SIZE BR UNL ; .ENDC ;+ ; ; **-RTUNL-UNLINK TASK FROM REMOTE TERMINAL ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CR RTUNL: ; MOV #ICOMN,-(SP) ; PUSH TRANSFER ADDRESS RTUNL1: ; MOV #IE.MOD&377,-(SP) ; ASSUME NONEXISTENT MODULE TYPE MOV S.RTI(R4),R4 ; GET MODULE TABLE ADDRESS BEQ 80$ ; IF EQ NON-EXISTENT MODULE BR ERUNL2 ; ;+ ; ; **-ERUNL-UNLINK FROM ERROR INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- WORD 0 OF RADIX-50 TASK NAME ; WD. 13 -- WORD 1 OF RADIX-50 TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- ERUNL: ; MOV #ICOMN,-(SP) ; PUSH TRANSFER ADDRESS ERUNL1: ; MOV #ICDVT+ICRES-IMDAT,R4 ; POINT TO ERROR RESOURCE MASK MINUS OFFSET CLR -(SP) ; RESERVE A WORD ON THE STACK ERUNL2: ; CLR 6(R1) ; SET MODULE-1 COUNT TO ZERO .ENDC UNL: ; MOV #TASK,R2 ; POINT TO TASK NAME STORAGE MOV R1,R3 ; COPY ADDRESS OF PARAMETER BLOCK MOV (R1)+,(R2)+ ; SAVE TASK NAME MOV (R1)+,(R2)+ ; ... MOV R3,U.CW2(R5) ; SAVE ADDRESS OF PARAMETER LIST ADD #IMDAT,R4 ; POINT TO MODULE ENTRIES MOV #IE.NST&377,(SP) ; ASSUME TASK NOT INSTALLED CALL $SRSTD ; SEARCH TCB LIST FOR TASK BCS 60$ ; IF C/S TASK NOT INSTALLED MOV R3,R1 ; RESTORE ADDRESS OF PARAMETER LIST MOV #IE.NLK&377,(SP) ; ASSUME TASK NOT LINKED MOV #ICDVT+ICLTL,R2 ; POINT TO LINKED TASK LISTHEAD 10$: ; MOV R2,10(R1) ; SAVE LINK TO PREVIOUS MOV (R2),R2 ; GET LINK TO NEXT SEC ; ASSUME TASK NOT LINKED ANYWHERE BEQ 60$ ; IF EQ TASK NOT LINKED ANYWHERE CMP LTCB(R2),R0 ; THIS ENTRY BELONG TO TASK? BNE 10$ ; IF NE NO MOV R2,(R1)+ ; SAVE ADDRESS OF LINKED TASK ENTRY MOV R4,(R1) ; SAVE ADDRESS OF FIRST ENTRY MOV R1,R4 ; SAVE PARAMETER LIST ADDRESS 20$: ; MOV (R4),R0 ; GET ADDRESS OF CURRENT ENTRY TST (R0)+ ; POINT TO INTERRUPT LINKAGE LISTHEAD MOV -(R4),R1 ; GET ADDRESS OF LINKED TASK ENTRY MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS CALL $QRMVT ;;; ATTEMPT TO REMOVE AN ENTRY FROM LIST BCS 40$ ;;; IF C/S NO ENTRY IN LIST THIS TIME BIC ILMSK(R1),-(R0) ;;; CLEAR RESOURCE MASK BITS CLRB PS ; ALLOW DEVICE INTERRUPTS MOV #IS.SUC&377,(SP) ; SET SUCCESS MOV R1,R0 ; COPY ADDRESS OF NODE MOV #ILGH,R1 ; SET LENGTH OF NODE CALL $DEACB ; DEALLOCATE BLOCK MOV (R4)+,R0 ; GET ADDRESS OF LINKED TASK ENTRY DEC LUSE(R0) ; DECREMENT USE COUNT BNE 20$ ; IF NE GO AGAIN MOV 10-2(R4),R1 ; GET ADDRESS OF PREVIOUS MOV (R0),(R1) ; RELINK REMAINING ENTRIES BNE 30$ ; IF NE NO NEW LAST MOV R1,ICDVT+ICLTL+2 ; SET NEW LAST 30$: ; MOV #LLGH,R1 ; SET LENGTH OF ENTRY CALL $DEACB ; DEALLOCATE BLOCK BR 50$ ; EXIT 40$: ; CLRB PS ; ALLOW DEVICE INTERRUPTS CMP (R4)+,(R4)+ ; POINT TO ENTRY SIZE ADD (R4),-(R4) ; OFFSET TO NEXT ENTRY DEC 4(R4) ; DECREMENT ENTRY COUNT BPL 20$ ; IF PL GO AGAIN 50$: ; CLC ; SET SUCCESS 60$:  ; MOV U.CW2(R5),R1 ; RESTORE ADDRESS OF PARAMETER LIST MOV TASK,(R1) ; RESTORE TASK NAME MOV TASK+2,2(R1) ; ... 70$: ; MOV U.SCB(R5),R4 ; RESTORE ADDRESS OF SCB MOV (SP)+,R0 ; RETRIEVE STATUS BISB R0,R0 ; SET CONDITION CODES RETURN ; 80$: CLC ; SET SUCCESS BR 70$ ; GO GET STATUS AND EXIT .DSABL LSB .ENDC ;+ ; ; **-CICNT-CONNECT TO CONTACT INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF CIRCULAR BUFFER ; WD. 13 -- ADDRESS OF CIRCULAR BUFFER ; WD. 14 -- LENGTH OF BUFFER ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .ENABL LSB .IF DF I$$CIM CICNT: ; MOV S.DI(R4),R3 ; GET ADDRESS OF DIGITAL INTERRUPT TABLES BR CNCT ; .ENDC ;+ ; ;**-CTCNT-CONNECT TO COUNTER MODULE INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF CIRCULAR BUFFER ; WD. 13 -- ADDRESS OF CIRCULAR BUFFER ; WD. 14 -- LENGTH OF CIRCULAR BUFFER ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- ADDRESS OF COUNTER INITIAL VALUE TABLE ; WD. 17 -- UNUSED ; ;+ .IF DF I$$CTI CTCNT: ; MOV S.CT(R4),R3 ; GET ADDRESS OF COUNTER TABLES BR CNCT ; .ENDC ;+ ; ; **-RTCNT-CONNECT REMOTE TERMINAL INPUTS TO CIRCULAR BUFFER ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF CIRCULAR BUFFER ; WD. 13 -- ADDRESS OF CIRCULAR BUFFER ; WD. 14 -- LENGTH OF CIRCULAR BUFFER ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CR RTCNT: ; MOV S.RTI(R4),R3 ; GET ADDRESS OF REMOTE TERMINAL TABLE .ENDC .IF DF I$$CIM!I$$CR!I$$CTI CNCT: ; BEQ ICM ; IF EQ MODULE DOESN'T EXIST BIT #T2.CHK!T2.FXD,T.ST2(R0) ; TASK NOT CHKPOINTABLE OR FXD? BEQ ICPRI ; IF EQ NO TST IMTCB(R3) ; OTHER TASK CONNECTED? BNE ICON ; IF NE YES CMP (R1)+,(R1)+ ; POINT TO DATA BUFFER SIZE MOVB IMBPE(R3),R0 ; GET SIZE OF ENTRY CMP (R0)+,(R0)+ ; ADJUST FOR BUFFER HEADER CMP (R1)+,R0 ; BUFFER BIG ENOUGH BLO ICSPC ; IF LO NO MOV (R1)+,R0 ; GET EVENT FLAG NUMBER BEQ ICIEF ; IF EQ ILLEGAL EFN CMP R0,#64. ; LEGAL EFN? BHI ICIEF ; IF HI NO .IF DF I$$CTI CLR 2(R1) ; CLEAR COUNTER FLAG CMP R3,S.CT(R4) ; PROCESSING COUNTERS? BNE 20$ ; IF NE NO MOV (R1)+,R0 ; GET ADDRESS OF COUNTER INITIAL VALUE TABLE MOV R3,(R1) ; SET COUNTER FLAG MOV (R3),R4 ; GET NUMBER OF HIGHEST COUNTER INC R4 ; CONVERT TO NUMBER OF COUNTERS .IF DF A$$CHK!M$$MGE MOV R4,R1 ; COPY NUMBER OF COUNTERS ASL R1 ; CONVERT TO BYTE COUNT CALL $ACHCK ; ADDRESS CHECK TABLE BCS ICSPC ; IF C/S OUT OF REQUESTOR'S TASK SPACE .ENDC .IF DF M$$MGE CALL $RELOM ; RELOCATE AND MAP TO INITIAL VALUE TABLE .ENDC MOV R3,R1 ; COPY MODULE TABLE ADDRESS ADD #IMDAT+IMPRV,R1 ; POINT TO INITIAL VALUE CELL 10$: ; MOV (R0)+,(R1) ; SET INITIAL VALUE ADD #CTLGH,R1 ; POINT TO NEXT ENTRY DEC R4 ; DECREMENT COUNT BNE 10$ ; IF NE GO AGAIN .ENDC 20$: ; MOV (SP),R4 ; RETRIEVE I/O PACKET ADDRESS MOV R5,-(SP) ; SAVE ADDRESS OF UCB MOV I.TCB(R4),R5 ; GET REQUESTER TASK TCB ADDRESS ADD #I.PRM,R4 ; POINT TO I/O PACKET ADDRESS TST (R3)+ ; POINT TO BYTES OF INTERRUPT DATA MOVB (R3)+,(R3) ; SET FORK NOT IN PROGRESS MOVB (R3)+,-(SP) ; SAVE BYTES PER ENTRY MOV (R4)+,(R3) ; INSERT STARTING BUFFER RELOCATION BIAS MOV (R3)+,(R3)+ ; INSERT CURRENT BUFFER RELOCATION BIAS MOV (R4)+,(R3) ; INSERT STARTING ADDRESS OF BUFFER MOV (R3)+,(R3) ; COPY STARTING ADDRESS OF BUFFER ADD #4,(R3) ; COMPUTE STARTING ADDRESS OF DATA MOV (R3)+,(R3)+ ; SET CURRENT BUFFER ADDRESS MOV #3,(R3)+ ; SET CURRENT FORTRAN FILL INDEX MOV (R4)+,(R3) ; SET LENGTH OF BUFFER IN BYTES ROR (R3)+ ; CONVERT TO LENGTH IN WORDS MOV (R4)+,R0 ; GET EVENT FLAG NUMBER CALL $CEFI ; CONVERT TO MASK AND ADDRESS MOV R0,(R3)+ ; INSERT EVENT FLAG MASK MOV R1,(R3)+ ; INSERT EVENT FLAG ADDRESS CLR (R3)+ ; CLEAR LOST DATA COUNT MOV R5,(R3) ; CONNECT TASK TO INTERRUPTS INCB T.IOC(R5) ; BIAS TASK'S OUTSTANDING I/O COUNT .IF DF D$$SHF MOV T.PCB(R5),R0 ; GET ADDRESS OF PCB BIS #PS.NSF,P.STAT(R0) ; DISABLE TASK SHUFFLING .ENDC MOVB (SP)+,R0 ; RETRIEVE BYTES PASSED PER INTERRUPT MOV (SP)+,R5 ; RETRIEVE ADDRESS OF UCB .IF DF I$$CTI MOV 2(R4),R3 ; GET COUNTER FLAG BEQ 30$ ; IF EQ NOT CONNECTING TO COUNTERS CALL RSETC ; INITIALIZE ALL COUNTERS 30$: ; .ENDC ASR R0 ; CONVERT BYTES TO WORD COUNT DEC R0 ; ADJUST FOR EXISTENCE INDICATOR BIS #3*256.,R0 ; INCLUDE INITIAL FORTRAN INDEX MOV R0,R1 ; COPY RESULT BR ICDON1 ; COMPLETE REQUEST ; ; INTERMEDIATE ERROR BRANCH POINTS ; ICB: JMP ICBYT ; BUFFER BYTE ALIGNED ICM: JMP ICMOD ; ILLEGAL MODULE NUMBER SPECIFIED .ENDC .DSABL LSB ;+ ; ; **-DISCONNECT CIRCULAR BUFFER FROM CONTACT INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- UNUSED ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .ENABL LSB .IF DF I$$CIM CIDCT: ; MOV S.DI(R4),R3 ; GET ADDRESS OF CONTACT INTERRUPT TABLES BR 10$ ; .ENDC ;+ ; ; **-CTDCT-DISCONNECT CIRCULAR BUFFER FROM COUNTER INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- UNUSED ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CTI CTDCT: ; MOV S.CT(R4),R3 ; GET ADDRESS OF COUNTER TABLES BR 10$ ; .ENDC ;+ ; ; **-RTDCT-DISCONNECT REMOTE TERMINAL FROM CIRCULAR BUFFER ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- UNUSED ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CR RTDCT: ; MOV S.RTI(R4),R3 ; GET ADDRESS OF REMOTE TERMINAL TABLES .ENDC .IF DF I$$CIM!I$$CR!I$$CTI 10$: ; CALL ICAN1 ; DISCONNECT TASK FROM INTERRUPTS BCC ICDON ; IF C/C DISCONNECT SUCCEEDED BEQ ICMOD ; IF EQ MODULE DOESN'T EXIST ; ; TASK NOT CONNECTED OR OTHER TASK CONNECTED ; ICON: ; MOV #IE.CON&377,R0 ; BR ICOMN ; .ENDC ; ; ILLEGAL OR NONEXISTENT EVENT FLAG SPECIFIED ; .IF DF I$$CLK!I$$CIM!I$$CR!I$$CTI ICIEF: ; MOV #IE.IEF&377,R0 ; BR ICOMN ; .ENDC ; ; PRIVELEGE VIOLATION - TASK REQUESTING CONNECTION WAS ; CHECKPOINTABLE BUT NOT FIXED ; ICPRI: ; MOV #IE.PRI&377,R0 ; BR ICOMN ; ; ; INVALID FUNCTION CODE ISSUED OR NONEXISTENT MODULE ; TYPE REFERENCED ; ICIFC: ; MOV #IE.IFC&377,R0 ; BR ICOMN ; ; ; BUFFER OUT OF REQUESTORS ADDRESS SPACE ; ICSPC: ; MOV #IE.SPC&377,R0 ; BR ICOMN ; ; ; DEVICE NOT READY ; ICNRD: ; MOV #IE.DNR&377,R0 ; BR ICOMN ; ;+ ; ; **-CTINI-INITIALIZE COUNTER MODULE ; ; FUNCTION DEPENDANT I/O PACKET FORMAT ; ; WD. 12 -- COUNTER NUMBER ; WD. 13 -- COUNTER INITIAL VALUE ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- .IF DF I$$CTI CTINI: ; MOV S.CT(R4),R3 ; GET ADDRESS OF COUNTER TABLES BEQ ICMOD ; IF EQ MODULE DOES NOT EXIST CMP (R1),(R3) ; LEGAL COUNTER NUMBER? BHI ICMOD ; IF HI NO MOV (R1),R2 ; GET COUNTER NUMBER ASL R2 ; CONVERT TO TABLE INDEX ASL R2 ; ... ADD (R1)+,R2 ; ... ASL R2 ; ... ADD R2,R3 ; POINT TO MODULE ENTRY ADD #IMDAT+IMPRV,R3 ; ... MOV (R1),(R3) ; SET NEW INITIAL VALUE CALL SETCT ; RE-INITIALIZE COUNTERS BR ICDON ; EXIT .ENDC ;+ ; ; **-AOUT-SINGLE CHANNEL ANALOG OUTPUT ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELATIVE CHANNEL NUMBER ; WD. 13 -- OUTPUT VOLTAGE REPRESENTATION ; ;- .IF DF I$$CDA AOUT: ; MOV R4,R3 ; COPY ADDRESS OF SCB ADD #S.DAC,R3 ; POINT TO D/A ENTRY TST (R3)+ ; ANY D/A CONVERTER MODULES? BEQ ICMOD ; IF EQ NO MOV R1,R2 ; COPY PARAMETER BLOCK ADDRESS CMP (R2)+,2(R3) ; LEGAL CHANNEL? BHI ICMOD ; IF HI NO TST (R2)+ ; POINT TO PARAMETER WORD 3 MOV (R1),(R2) ; COPY CHANNEL NUMBER ASL (R2) ; CONVERT TO WORD OFFSET ADD (R3),(R2) ; COMPUTE CONTEXT SAVE LOCATION SWAB -(R2) ; SWAP DATA WORD BYTES RORB (R2) ; LEFT JUSTIFY DATA ROR (R2) ; ... ROR (R2) ; ... ASR (R1) ; INCLUDE CHANNEL NUMBER WITHIN MODULE ROR (R2) ; ... ASR (R1) ; ... ROR (R2) ; ... MOV (R2)+,@(R2)+ ; SAVE CONTROL WORD BR OUTCM ; TO COMMON OUTPUT CODE .ENDC ;+ ; ; **-LTOUT-BI-STABLE DIGITAL OUTPUT ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- STARTING RELATIVE POINT NUMBER ; WD. 13 -- DATA MASK WORD ; WD. 14 -- DATA VALUE ; ;- .IF DF I$$CLT LTOUT: ; MOV R4,R3 ; COPY SCB ADDRESS ADD #S.LTO,R3 ; POINT TO BI-STABLE SCB ENTRY TST (R3)+ ; ANY BI-STABLE OUTPUTS ON THIS CONTROLLER? BEQ ICMOD ; IF EQ NO CMP (R1),2(R3) ; LEGAL POINT NUMBER? BHI ICMOD ; IF HI NO BIT #17,(R1) ; POINT ON MODULE BOUNDARY? BNE ICMOD ; IF EQ NO ASR (R1) ; CONVERT POINT TO WORD INDEX ASR (R1) ; ... ASR (R1) ; ... MOV (R1)+,R2 ; GET INDEX ADD (R3),R2 ; COMPUTE ADDRESS OF PREVIOUS STATE ENTRY BIC (R1),(R2) ; CLEAR ALL BITS THAT WILL CHANGE STATE COM (R1) ; COMPLEMENT MASK BIC (R1)+,(R1) ; CLEAR ALL BITS THAT WILL NOT CHANGE STATE BIS (R1),(R2) ; ESTABLISH NEW 'CURRENT STATE' MOV (R2),-(R1) ; COPY NEW STATE ASR -(R1) ; CONVERT WORD OFFSET TO BYTE OFFSET BR OUTCM ; TO COMMON CODE .ENDC ;+ ; ; **-SSOUT-MOMENTARY DIGITAL OUTPUTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- STARTING RELATIVE POINT NUMBER ; WD. 13 -- DATA VALUE ; ;- .IF DF I$$CSS SSOUT: ; MOV R4,R3 ; COPY SCB ADDRESS ADD #S.SSO,R3 ; POINT TO 'MOMENTARY' ENTRY TST (R3)+ ; ANY MOMENTARY OUTPUTS? BEQ ICMOD ; IF EQ NO CMP (R1),2(R3) ; LEGAL POINT NUMBER? BHI ICMOD ; IF HI NO BIT #17,(R1) ; POINT ON MODULE BOUNDARY? BNE ICMOD ; IF NE NO ASR (R1) ; CONVERT TO MODULE NUMBER ASR (R1) ; ... ASR (R1) ; ... ASR (R1) ; ... .ENDC ; ; COMMON CODE TO PERFORM OUTPUT FOR NON- ; INTERRUPTING FUNCTIONS ; .IF DF I$$CDA!I$$CLT!I$$CSS OUTCM: ; ADD -(R3),(R1)+ ; COMPUTE MODULE MAPPING TABLE ENTRY ADDRESS MOVB @-(R1),(R1)+ ; CONVERT LOGICAL TO PHYSICAL SLOT NUMBER CLRB (R1)+ ; CLEAR HIGH BYTE ADD #ICMD/2&77777,-(R1) ; COMPUTE BUS ADDRESS/2 CALL CBINS ; ATTEMPT TO INSERT IN CIRCULAR BUFFER .IF DF I$$CR BCS ICDNR ; IF C/S UNIT NOT READY .ENDC BR ICDON ; SET SUCCESFUL COMPLETION STATUS .ENDC ; ; ILLEGAL OR NONEXISTENT MODULE SPECIFIED ; ICMOD: ; MOV #IE.MOD&377,R0 ; BR ICOMN ; ; ; RETURN SUCCESS STATUS, SET WORD 2 OF I/O STATUS BLOCK ; TO ZERO ; ICDON: ; CLR R1 ; CLEAR SECOND WORD OF I/O STATUS ICDON1: ; MOV #IS.SUC&377,R0 ; SET STATUS BR ICOMN1 ; ; ; DEVICE NOT READY ; ICDNR: ; MOV #IE.DNR&377,R0 ; ; ; COMMON EXIT FROM ALL FUNCTION CODE PROCESSING ; ICOMN: ; CLR R1 ; CLEAR SECOND WORD OF I/O STATUS ICOMN1: ; MOV (SP)+,R3 ; RESTORE ADDRESS OF I/O PACKET CALLR $IOFIN ; TERMINATE REQUEST ;+ ; ; **-ADINI-INITIATE BUFFERED A/D CONVERSION ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- DATA BUFFER ADDRESS ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER ; WD. 15 -- CONTROL BUFFER ADDRESS ; ;- .ENABL LSB .IF DF I$$CAD ADINI: ; TST S.ADC(R4) ; ANY A/D CONVERTERS ON THIS CONTROLLER? BEQ ICMOD ; IF EQ NO MOV 6(R1),R0 ; GET VIRTUAL ADDRESS OF CONTROL BUFFER .IF DF A$$CHK!M$$MGE MOV 4(R1),R1 ; GET LENGTH OF BUFFER TO CHECK CALL $ACHCK ; ADDRESS CHECK CONTROL BUFFER BCS ICSPC ; IF C/S ADDRESS CHECK FAILURE .ENDC MOV (SP),R3 ; GET ADDRESS OF I/O PACKET CALL $RELOC ; RELOCATE AND MAP BUFFER ADD #I.PRM+4,R3 ; POINT TO BYTE COUNT (C/CLEAR) ROR (R3)+ ; CONVERT TO NUMBER OF CHANNELS MOV R1,(R3)+ ; SAVE CONTROL BUFFER ADDRESS BIAS MOV R2,(R3) ; SAVE CONTROL BUFFER ADDRESS .ENDC ;+ ; ; **-RTINI-INITIATE REMOTE TERMINAL I/O ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF CONTROL BUFFER ; WD. 13 -- DATA BUFFER ADDRESS ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER ; ;- .IF DF I$$CAD!I$$CR RTINI: ; MOV (SP)+,R1 ; RETRIEVE I/O PACKET ADDRESS MOV R4,R0 ; SET ADDRESS OF I/O LISTHEAD CALL $QINSP ; INSERT I/O PACKET IN REQUEST QUEUE .ENDC .DSABL LSB ;+ ; ; **-IMRQ-ICS/ICR-11 INTERRUPT MODULE REQUEST PROCESSING ; ; THIS ROUTINE IS ENTERED FROM QIO DIRECTIVE PROCESSING ; WHEN AN I/O REQUEST IS QUEUED AND AT THE END OF A PRE- ; VIOUS I/O REQUEST TO CONTINUE REQUEST PROCESSING. IF ; THE SPECIFIED CONTROLLER IS NOT BUSY THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT REQUEST. OTHERWISE A RE- ; TURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT ; IS SUCCESFUL THE NEXT I/O OPERATION IS INITIATED, A RE- ; TURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; IF THE CONTROLLER IS NOT BUSY AND AN I/O REQUEST ; IS WAITING TO BE PROCESSED, THEN THE REQUEST IS DE- ; QUEUED AND THE I/O OPERATION IS INITIATED. ; ;- .ENABL LSB .IF DF I$$CAD!I$$CR IMRQ: ; CALL $GTPKT ; DEQUEUE AN I/O PACKET  .IF DF I$$CR BCS 20$ ; IF C/S NO WORK OR CONTROLLER BUSY .IFF BCC ADRQ ; IF C/CLEAR HAVE PACKET TO PROCESS .ENDC .ENDC ;+ ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=I/O REQUEST PACKET ADDRESS ; R2=REQUEST UCB PHYSICAL UNIT NUMBER ; R3=CONTROLLER INDEX ; R4=STATUS CONTROL BLOCK ADDRESS ; R5=UNIT CONTROL BLOCK ADDRESS ; ; ICR/ICS-11 INTERRUPT MODULE REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER  ; WD. 02 -- ADDRESS OF REQUESTING TASK TCB ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB) ; WD. 05 -- I/O FUNCTION CODE (IO.RBC OR IO.WLB) ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT+140000) ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- DATA BUFFER ADDRESS ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER ; WD. 15 -- RELOCATION BIAS OF CONTROL BUFFER (ADU02 INPUT ONLY) ; WD. 16 -- CONTROL BUFFER ADDRESS (ADU02 ONLY) ; WD. 17 -- NOT USED ; WD. 20 -- NOT USED ; ;- .IF DF I$$CAD&I$$CR CMPB #IO.WLB/256.,I.FCN+1(R1) ; REMOTE TERMINAL OUTPUT? BNE ADRQ ; IF NE A/D CONVERSION REQUEST .ENDC .IF DF I$$CR MOV #IE.MOD&377,R0 ; ASSUME DEVICE IS ICS11 TST S.RTI(R4) ; DEVICE ICS11 CONTROLLER? BEQ 27$ ; IF EQ YES 10$: ; MOV #IE.ABO&377,R0 ; ASSUME I/O CANCEL IS ASSERTED BIT #TABO,S.FLG(R4) ; ABORT TRANSFER? BNE 25$ ; IF NE YES CALL $GTBYT ; GET AN OUTPUT BYTE MOV #ICMD/2,-(SP) ; PUSH BUS ADDRESS/2!TERMINAL FLAG BISB S.CON(R4),(SP) ; MERGE WITH CONTROLLER INDEX ASLB (SP) ; MULTIPLY CONTROLLER INDEX BY 8 ASLB (SP) ; ... ASLB (SP) ; ... MOV SP,R1 ; COPY STACK ADDRESS BIS #TUND!TUSE,S.FLG(R4) ; SET TERMINAL BUSY AND IN USE MOVB S.ITM(R4),S.CTM(R4) ; ENABLE DEVICE TIME-OUTS CALL CBINS ; INSERT IN CIRCULAR BUFFER MOV (SP)+,(SP)+ ; CLEAN STACK .IFTF .IF DF I$$CAD!I$$CR 20$: ; RETURN ; .ENDC ;+ ; ; **-RTINT-REMOTE TERMINAL INTERRUPT PROCESSING ; ;- .IFT RTINT: ;;; BIC #1000,@S.CSR(R4) ;;; DISABLE TERMINAL OUTPUT INTERRUPTS ADD #6,SP ;;; REMOVE DATA, MOD. NO., GENERIC CODE FROM STACK TSTB R2 ;;; TERMINAL BUFFER EMPTY? BPL 30$ ;;; IF PL NO, ERROR .IF GT I$$C11-1 MOV ICUCB,R5 ;;; GET UCB ADDRESS .IFF MOV CNTBL,R5 ;;; GET UCB ADDRESS .ENDC BIT #TUND,S.FLG(R4) ;;; TERMINAL INTERRUPTS EXPECTED? BEQ 30$ ;;; IF EQ NO BIC #TUND,S.FLG(R4) ;;; CLEAR UNDERWAY FLAG CLRB S.CTM(R4) ;;; DISABLE DEVICE TIMEOUTS CALL $FORK ;;; CREATE A SYSTEM PROCESS DEC U.CNT(R5) ; DECREMENT BYTE COUNT BGT 10$ ; IF GT MORE TO OUTPUT MOV #IS.SUC&377,R0 ; SET SUCCESFUL COMPLETION STATUS 25$: ; BIC #TABO!TUSE,S.FLG(R4) ; CLEAR TERMINAL IN USE FLAG, ABORT FLAG 27$: ; JMP IMFIN ; COMPLETE REQUEST PROCESSING 30$: ; RETURN ;;; EXIT ISR .ENDC .DSABL LSB ;+ ; ; **-ADRQ-INITIATE BUFFERED, PARALLEL A/D CONVERSION ; ; THIS ROUTINE IS INVOKED TO INITIATE BUFFERED, PARALLEL A/D ; CONVERSION ON THE ICS/ICR-11 INDUSTRIAL CONTROL SUBSYSTEM ; CONVERSIONS ARE INITIATED UNTIL A BUSY CHANNEL IS ENCOUNTERED ; WHEREUPON PROCESSING IS SUSPENDED UNTIL THE CHANNEL BECOMES ; IDLE. SCANNING IS THEN RESUMED AND TERMINATES WHEN ALL TRANS- ; FERS HAVE BEEN COMPLETED OR UPON DETECTION OF AN ERROR. ; ; INPUTS: ; ; R1=I/O REQUEST PACKET ADDRESS ; R2=REQUEST UCB PHYSICAL UNIT NUMBER ; R3=CONTROLLER INDEX ; R4=ADDRESS OF STATUS CONTROL BLOCK ; R5=ADDRESS OF UNIT CONTROL BLOCK ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- DATA BUFFER ADDRESS ; WD. 14 -- BYTE COUNT ; WD. 15 -- RELOCATION BIAS OF CONTROL BUFFER ; WD. 16 -- CONTROL BUFFER ADDRESS ; ; THE DATA BUFFER RECEIVES VALUES THAT ARE CONVERTED IN ; ACCORDANCE WITH THE GAIN AND CHANNEL SPECIFIED IN THE ; CORRESPONDING CONTROL WORD. EACH WORD IN THE CONTROL BUFF- ; ER CONSISTS OF CHANNEL AND GAIN IN THE FOLLOWING FORMAT: ; ; BITS 15 - 12 -- GAIN CODE. ; ; LEGAL GAIN CODES ARE ; ; 0000=GAIN OF 1. ; 0001=GAIN OF 2. ; 0100=GAIN OF 10. ; 0101=GAIN OF 20. ; 1000=GAIN OF 50. ; 1001=GAIN OF 100. ; 1100=GAIN OF 200. ; 1101=GAIN OF 1000. ; ; BITS 11-0 -- CHANNEL NUMBER. ; ; EACH ICS/ICR-11 CONTROLLER MAY HAVE UP TO 240 ; PHYSICAL CHANNELS INSTALLED. HOWEVER SINCE EACH ; ADU02 OCCUPIES A BLOCK OF 120 ADDRESSES THE MAX- ; IMUM NUMBER OF LOGICAL CHANNELS PER CONTROLLER ; IS 1920. THE LEGALITY OF A PARTICULAR CHANNEL ; IS DETERMINED BY THE ENTRIES IN THE A/D MODULE ; DESCRIPTOR TABLES. ; ;- .ENABL LSB .IF DF I$$CAD ADRQ: ; MOV I.PRM+6(R1),U.CBF(R5) ; SET RELOCATION BIAS OF CONTROL BUFFER MOV I.PRM+10(R1),U.CBF+2(R5) ; SET ADDRESS OF CONTROL BUFFER MOV S.ADC(R4),R3 ; GET ADDRESS OF A/D DESCRIPTOR TABLE CLR ADFBC(R3) ; CLEAR FINAL BYTE COUNT 10$: ; CALL $GTCWD ; GET CONTROL WORD MOV (SP)+,R0 ; POP CONTROL WORD MOV R0,R2 ; COPY WORD BIC #7777,R2 ; CLEAR ALL BUT GAIN CODE BIC R2,R0 ; CLEAR ALL BUT CHANNEL NUMBER CMP R0,(R3) ; LEGAL CHANNEL NUMBER? BHI 50$ ; IF HIGH NO MOV #120.,R1 ; GET NUMBER OF CHANNELS PER MODULE CALL $DIV ; GET MODULE NUMBER IN R0, CHANNEL IN R1 MOV R0,-(SP) ; COPY CHANNEL NUMBER ASL R0 ; COMPUTE OFFSET INTO DESCRIPTOR ABLE ASL R0 ; ... ADD (SP)+,R0 ; ... ASL R0 ; ... ADD #ADSTS+2,R0 ; COMPUTE ADDRESS OF DESCRIPTOR ENTRY  ADD R3,R0 ; ... CMPB R1,(R0)+ ; LEGAL MODULE NUMBER? BHI 50$ ; IF HI NO INC R2 ; SET CONVERT BIT SWAB R2 ; POSITION GAIN CODE TO LOW BYTE ASL R2 ; BIT 15 TO HIGH BYTE ASL R2 ; BIT 14 TO HIGH BYTE ASLB R2 ; DROP BIT 13 BCS 50$ ; IF C/S ILLEGAL GAIN CODE ASL R2 ; BIT 12 TO HIGH BYTE ADD #8.,R1 ; BIAS CHANNEL NUMBER BISB R1,R2 ; MERGE CHANNEL AND GAIN ASL R2 ; POSITION CONTROL INFORMATION ASL R2 ; ... ASL R2 ; ... ASL R2 ; ... MOV R2,-(SP) ; PLACE CONTROL WORD ON STACK MOV R0,R1 ; COPY ENTRY ADDRESS MOVB #PR6,PS ;;; LOCKOUT DEVICE INTERRUPTS MOVB (R1)+,-(SP) ;;; MODULE BUSY? BEQ 20$ ;;; IF EQ NO INCB ADFR(R3) ;;; REQUEST FORK ON COMPLETION MOV R3,R1 ;;; COPY TABLE ADDRESS ADD #ADNXT,R1 ;;; POINT TO DESCRIPTOR CONTEXT ADDRESS MOV R0,(R1)+ ;;; SAVE ENTRY+1 ADDRESS 20$: ;;; CLRB PS ; ALLOW DEVICE INTERRUPTS MOV R5,R2 ; COPY UCB ADDRESS ADD #U.BUF,R2 ; POINT TO BUFFER ADDRESS 30$: ; MOV (R2)+,(R1)+ ; SAVE BUFFER ADDRESS MOV (R2)+,(R1)+ ; ... MOV (R2),(R1)+ ; SAVE CHANNEL COUNT TSTB (SP)+ ; FIND MODULE BUSY? BEQ 40$ ; IF EQ NO MOV (SP)+,(R1)+ ; SAVE CONTROL WORD BR 90$ ; EXIT 40$: ; INCB (R0)+ ; SET MODULE BUSY MOVB S.ITM(R4),S.CTM(R4) ; ENABLE DEVICE TIMEOUTS MOV ADMBA-2(R0),-(SP) ; PUSH BUS ADDRESS MOV SP,R1 ; SET ADDRESS OF BLOCK INCB ADIP(R3) ; INCREMENT IN-PROGRESS COUNT MOV R3,R0 ; SAVE TABLE ADDRESS CALL CBINS ; INSERT IN CIRCULAR BUFFER MOV R0,R3 ; RESTORE TABLE ADDRESS MOV (SP)+,(SP)+ ; CLEAN STACK MOV R5,R2 ; COPY ADDRESS OF UCB ADD #U.BUF+2,R2 ; POINT TO BUFFER ADDRESS ADD #2,(R2)+ ; UPDATE ADDRESS DEC (R2) ; ANY MORE TO CONVERT? BLE 60$ ; IF LE NO .IF DF M$$MGE BIT #20000,-(R2) ; OVERFLOW 4K BOUNDARY? BEQ 10$ ; IF EQ NO BIC #20000,(R2) ; CLEAR APR 7 OFFSET ADD #200,-(R2) ; ADJUST ADDRESS BIAS .ENDC BR 10$ ; PROCESS NEXT REQUEST 50$: ; MOV #IE.BAD&377,R0 ; GET ERROR CODE BR 70$ ; 60$: ; MOV #IS.SUC&377,R0 ; GET STATUS 70$: ; MOV U.CNT(R5),R1 ; GET CHANNEL COUNT MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS MOV ADFR(R3),R2 ;;; GET FORK REQUEST, IN-PROGRESS COUNT BEQ 80$ ;;; IF EQ NO INTERRUPTS PENDING INCB ADFR(R3) ;;; POST FORK REQUEST 80$: ;;; CLRB PS ; ALLOW DEVICE INTERRUPTS TST R2 ; INTERRUPTS PENDING? BNE 85$ ; IF NE YES, SET STATUS, EXIT MOV #130$,-(SP) ; SET RETURN ADDRESS 85$: ; CMP R1,ADFBC(R3) ; COMPARE AGAINST CURRENT RETURN COUNT BLO 90$ ; IF LO DO NOT OVERRIDE STATUS MOV R1,ADFBC(R3) ; SET NEW COUNT MOV R0,ADSTS(R3) ; SET NEW STATUS 90$: ; RETURN ; ;+ ; ; **-ADINT-A/D INTERRUPT SERVICE ROUTINE ; ;- ADINT: ;;; MOV (SP)+,R1 ;;; GET CONVERTED DATA MOV S.ADC(R4),R5 ;;; GET ADDRESS OF A/D TABLES BEQ 140$ ;;; IF EQ NONE TSTB ADIP(R5) ;;; A/D IN PROGRESS? BEQ 140$ ;;; IF EQ NO, EXIT ISR ASL R3 ;;; COMPUTE MODULE ENTRY OFFSET ASL R3 ;;; ... ADD (SP)+,R3 ;;; ... ASL R3 ;;; ... ADD #ADSTS+ADBSY+2,R3 ;;; COMPUTE OFFSET TO BUSY FLAG ADD R5,R3 ;;; CONVERT TO ADDRESS TSTB (R3) ;;; MODULE BUSY? BEQ 150$ ;;; IF EQ NO CLRB (R3)+ ;;; CLEAR BUSY FLAG .IF DF M$$MGE MOV KISAR6,-(SP) ;;; SAVE ASR 6 CONTENTS MOV (R3)+,KISAR6 ;;; MAP TO USER BUFFER MOV R1,@(R3)+ ;;; TRANSFER DATA TO USER MOV (SP)+,KISAR6 ;;; RESTORE ASR 6 .IFF MOV R1,@2(R3) ;;; TRANSFER DATA TO USER .ENDC DECB ADIP(R5) ;;; DECREMENT IN PROGRESS COUNT BNE 150$ ;;; IF NE MORE INTERRUPTS PENDING TSTB ADFR(R5) ;;; INITIATE FORK ON COMPLETION? BEQ 150$ ;;; IF EQ NO CLRB ADFR(R5) ;;; CLEAR FORK REQUEST FLAG CLRB S.CTM(R4) ;;; DISABLE DEVICE TIMEOUTS .IF GT I$$C11-1 MOV ICUCB,R5 ;;; GET ADDRESS OF UCB .IFF MOV CNTBL,R5 ;;; GET ADDRESS OF UCB .ENDC INC (SP)+ ;;; CLEAN THE STACK CALL $FORK ;;; CREATE A SYSTEM PROCESS MOV S.ADC(R4),R3 ; GET ADDRESS OF A/D TABLES TST U.CNT(R5) ; MORE TO PROCESS? BEQ 130$ ; IF EQ NO MOV R3,R2 ; COPY ADDRESS OF A/D TABLES ADD #ADNXT,R2 ; POINT TO ENTRY+1 ADDRESS MOV (R2)+,R0 ; RESTORE ENTRY+1 ADDDRESS MOV R0,R1 ; COPY ADDRESS INC R1 ; POINT TO MODULE CONTEXT MOV ADNXC(R3),-(SP) ; RESTORE CONTROL WORD CLR -(SP) ; SET 'NOT BUSY' CONDITION BR 30$ ; INITIATE DEVICE ;+ ; ; **-ICOUT-ICS/ICR-11 DEVICE TIMEOUT PROCESSING ; ; THIS ROUTINE IS CALLED AT DEVICE PRIORITY BY THE EXEC- ; UTIVE WHEN AN INTERRUPT RESPONSE WAS NOT RECEIVED FROM ; THE A/D OR TERMINAL DEVICES WITHIN THE SPECIFIED INTER- ; VAL AFTER INITIATION. TIMEOUT CAUSES THE CURRENT OPERA- ; TION TO BE TERMINATED WITH A FINAL STATUS OF DEVICE NOT ; READY. IF THE CONTROLLER WAS PLACED OFFLINE MANUALLY THE ; REQUEST IS TERMINATED WITH A STATUS OF REQUEST ABORTED. IN ; EITHER CASE A COUNT OF THE NUMBER OF CHANNELS SAMPLED OR ; THE NUMBER OF BYTES TRANSFERRED IS PLACED IN THE SECOND ; STATUS WORD. ; ;- .IFTF ICOUT: ;;; .IF DF I$$CR MOV S.FLG(R4),R2 ;;; GET DEVICE FLAGS BIC #TABO!TUND!TUSE,S.FLG(R4) ;;; CLEAR TERMINAL BUSY, IN-USE, ABORT FLAGS .ENDC .IF DF I$$CAD!I$$CR CLRB PS  ; ALLOW INTERRUPTS MOV #IE.DNR&377,R0 ; ASSUME DEVICE NOT READY BIT #UFL,R2 ; UNIT OFFLINE? BEQ 100$ ; IF EQ NO MOV #IE.ABO&377,R0 ; GET ABORT STATUS 100$: ; .ENDC .IFT .IF DF I$$CR BIT #TUND,R2 ; TERMINAL UNDERWAY? BNE IMFIN ; IF NE YES, TERMINATE REQUEST .ENDC CLR R1 ; CLEAR CHANNEL COUNT MOV S.ADC(R4),R3 ; GET ADDRESS OF A/D TABLES MOV R3,R2 ; COPY A/D TABLE ADDRESS MOV (R2)+,-(SP) ; PUSH HIGHEST CHANNEL NUMBER CLR (R2) ; CLEAR IN-PROGRESS, FORK REQUEST FLAGS ADD #ADSTS,R2 ; POINT TO FIRST MODULE ENTRY 110$: ; TSTB ADBSY(R2) ; THIS MODULE BUSY? BEQ 120$ ; IF EQ NO CLRB ADBSY(R2) ; RESET BUSY FLAG MOV ADBTC(R2),R1 ; GET BYTE COUNT CALL 85$ ; UPDATE FINAL STATUS 120$: ; ADD #ADLGH,R2 ; POINT TO NEXT ENTRY SUB #120.,(SP) ; DECREMENT CHANNEL COUNT BY ONE BLOCK BPL 110$ ; IF PL GO AGAIN INC (SP)+ ; CLEAN THE STACK 130$: ; MOV ADSTS(R3),R0 ; SET FINAL STATUS MOV ADFBC(R3),U.CNT(R5) ; SET FINAL BYTE COUNT .IFTF .IF DF I$$CAD!I$$CR IMFIN: ; MOV S.PKT(R4),R3 ; GET ADDRESS OF I/O PACKET MOV I.PRM+4(R3),R1 ; GET INITIAL BYTE COUNT SUB U.CNT(R5),R1 ; COMPUTE NUMBER OF BYTES TRANSFERRED CALL $IODON ; TERMINATE REQUEST JMP IMRQ ; LOOK FOR MORE WORK .ENDC .IFT 140$: ;;; INC (SP)+ ;;; POP RELATIVE MODULE NUMBER 150$: ;;; INC (SP)+ ;;; POP GENERIC CODE .ENDC RETURN ;;; EXIT ISR .DSABL LSB ;+ ; ; **-$ICINT-ICS/ICR-11 INTERRUPT SERVICE ROUTINE ; ;- $ICINT:: ;;;  .IF NDF I$$CAD&I$$CIM&I$$CR&I$$CTI RTI ;;; DISMISS SPURIOUS INTERRUPT .IFF .ENABL LSB .IF GT I$$C11-1 MOVB PS,TMP ;;; SAVE CONTROLLER INDEX .IFTF CALL $INTSV,PR6 ;;; SAVE R4,R5, SET PRIORITY JSR R3,SAVE ;;; SAVE R3 - R0 .IFT MOV TMP,R5 ;;; GET INDEX BIC #^C<17>,R5 ;;; CLEAR ALL BUT INDEX BITS MOV R5,TMP ;;; SAVE PHYSICAL UNIT NUMBER ASL R5 ;;; CONVERT TO WORD INDEX .IFF CLR R5 ;;; SET INDEX TO CONTROLLER 0 .IFTF MOV CNTBL(R5),R5 ;;; GET UCB ADDRESS .IFT MOV R5,ICUCB ;;; SAVE UCB ADDRESS .ENDC MOV U.SCB(R5),R4 ;;; GET SCB ADDRESS MOV S.CSR(R4),R5 ;;; GET ADDRESS OF CSR MOV R5,CSR ;;; SAVE ADDRESS OF CSR .IF DF I$$CR MOV (R5),R0 ;;; GET CSR CONTENTS BIT #22,R0 ;;; ERROR INTERRUPTS RECOGNIZED? BEQ 50$ ;;; IF EQ NO BIT #12000,R0 ;;; ANY ERRORS? BEQ 50$ ;;; IF EQ NO BIT #2000,R0 ;;; POWER FAIL? BNE 10$ ;;; IF NE YES TST -2(R5) ;;; CLEAR ERROR FLAGS INC S.ERR(R4) ;;; INCREMENT ERROR COUNT BMI 50$ ;;; IF MI ERROR NOT FATAL 10$: ;;; BIS #UNR,S.FLG(R4) ;;; MARK UNIT NOT READY MOV TMP,R1 ;;; GET CONTROLLER NUMBER CALL STERR ;;; INITIATE ERROR PROCESSORS .IF GT I$$C11-1 MOV ICUCB,R5 ;;; GET ADDRESS OF CURRENT UCB .IFF MOV CNTBL,R5 ;;; GET ADDRESS OF UCB .ENDC TSTB U.EIP(R5) ;;; FORK IN PROGRESS? BNE 40$ ;;; IF NE YES INCB U.EIP(R5) ;;; SET FORK UNDERWAY MOV R5,R4 ;;; COPY ADDRESS OF UCB ADD #U.EFB+6,R4 ;;; POINT TO ERROR FORK BLOCK CALL $FORK1 ;;; CREATE A SYSTEM PROCESS CLRB U.EIP(R5) ; CLEAR IN-PROGRESS FLAG ;+ ; **-INIER-INITIATE ERROR PROCESSES ; ; THIS ROUTINE IS CALLED AT FORK LEVEL AFTER A FATAL ERROR ; HAS BEEN DETECTED TO INITIATE ALL TASKS THAT HAVE RECEIVED ; 'ALARM' INFORMATION FOR PROCESSING. SUCH INFORMATION IS CON- ; VEYED TO ALL TASKS THAT ARE CONNECTED TO INTERRUPTS ON THE ; PHYSICAL UNIT AND TO A SINGLE TASK THAT IS LINKED TO ERROR ; INTERRUPTS FROM ALL UNITS ; ; INPUTS: ; ; R5=UCB ADDRESS OF FAULTY UNIT ; ; OUTPUTS: ; ; THE UNIT IS PLACED IN THE 'NOT READY' STATE AND ; ALL SPECIFIED TASKS ARE ACTIVATED. ; ; REGISTERS MODIFIED: ; ; R0 - R5 ; ;- INIER: ; MOV U.SCB(R5),R4 ; GET ADDRESS OF SCB .IF DF I$$CLK MOV #ICDVT+ICELH,R3 ; POINT TO ERROR INTERRUPT LISTHEAD CALL ALINK ; ACTIVATE THE LINKED TASK .ENDC ADD #S.DI,R4 ; POINT TO MODULE TABLES MOV #3,-(SP) ; SET TABLE COUNT 20$: ; MOV (R4)+,R5 ; GET TABLE ADDRESS BEQ 25$ ; IF EQ NONE CALL ACBUF ; ACTIVATE CONNECTED TASK 25$: ; DEC (SP) ; DECREMENT TABLE COUNT BNE 20$ ; IF NE GO AGAIN INC (SP)+ ; CLEAN STACK 40$: ;;; REF. LABEL RETURN ;;; EXIT INTERRUPT SERVICE ROUTINE 50$: ;;; TST R0 ;;; SERIAL LINE BUFFER EMPTY? BMI 60$ ;;; IF MI NO MOVB S.ITMC(R4),R2 ;;; SET INITIAL TIMEOUT COUNT MOV S.CBF(R4),R3 ;;; GET ADDRESS OF CIRCULAR BUFFER BEQ 60$ ;;; IF EQ, NO CIRCULAR BUFFER TST (R3) ;;; ANY DATA SENT? BMI 60$ ;;; IF MI NO BIC #NORSP,S.FLG(R4) ;;; CLEAR NO-RESPONSE CONDITION DEC (R3) ;;; ACKNOWLEDGE INTERRUPTS BGT 55$ ;;; IF GT MORE THAN ONE OUTPUT QUEUED BMI 60$ ;;; IF MI BUFFER NOW EMPTY BIC #10,(R5) ;;; DISABLE BUFFER EMPTY INTERRUPTS CLR R2 ;;; CLEAR TIMEOUT COUNT 55$: ;;; MOVB R2,S.CTMC(R4) ;;; SET DEVICE TIMEOUT COUNT CALL CBOUT ;;; OUTPUT DATA TO CONTROLLER 60$: ;;; TSTB R0 ;;; MODULE INTERRUPTS? BPL 40$ ;;; IF PL NO .IFF MOV (R5),R0 ;;; GET CSR CONTENTS TSTB R0 ;;; MODULE INTERRUPTS? BMI 60$ ;;; IF MI YES RETURN ;;; EXIT ISR 60$: ;;; .ENDC MOV -2(R5),R2 ;;; GET ICAR CONTENTS CLR R1 ;;; SET FOR MOVB WITHOUT SIGN EXTENSION BISB R2,R1 ;;; GET MODULE OFFSET CLRB R2 ;;; CLEAR LOW BYTE OF ICAR COPY SWAB R2 ;;; POSITION GENERIC CODE AND FLAGS TO LOW BYTE .IF DF I$$CAD!I$$CIM!I$$CTI MOV R1,R3 ;;; COPY MODULE OFFSET BIC #^C<17>,R3 ;;; CONVERT TO MODULO 16. MOV R2,-(SP) ;;; PUSH GENERIC CODE BIC #^C<7>,(SP) ;;; CLEAR EXTRANEOUS BITS .IF DF I$$CR BEQ 70$ ;;; IF EQ REMOTE TERMINAL .ENDC  ADD S.IM(R4),R3 ;;; COMPUTE MAPPING TABLE ADDRESS MOVB (R3),R3 ;;; GET RELATIVE MODULE NUMBER BR 80$ ;;; .IFF CLR -(SP) ;;; CLEAR GENERIC CODE .ENDC .IF DF I$$CR 70$: ;;; CLR R3 ;;; FORCE RELATIVE MODULE NUMBER OF ZERO BIS #40,(R5) ;;; SET TERMINAL MODE .IFTF 80$: ;;; MOV R3,-(SP) ;;; PUSH RELATIVE MODULE NUMBER ASL R1 ;;; CONVERT MODULE OFFSET TO WORD BIAS BIS #1,(R5) ;;; SET THE RIF BIT MOV ICMD(R1),-(SP) ;;; PUSH MODULE DATA .IFT BIC #40,(R5) ;;; CLEAR TERMINAL MODE .IF DF I$$CAD!I$$CIM!I$$CTI BIT #7,R2 ;;; TERMINAL INPUT? BNE 83$ ;;; IF NE NO .ENDC BIT #20,R2 ;;; TERMINAL DATA AVAILABLE? BNE 82$ ;;; IF NE YES JMP RTINT ;;; PROCESS OUTPUT INTERRUPT 82$: ;;; BICB #200,(SP) ;;; CLEAR PARITY BIT MOV S.RTI(R4),R5 ;;; GET ADDRESS OF REMOTE TERMINAL TABLE BR 90$ ;;; 83$: ;;; .ENDC .IF DF I$$CIM!I$$CTI&I$$CAD CMP #7,4(SP) ;;; A/D INPUT? BNE 85$ ;;; IF NE NO .ENDC .IF DF I$$CAD JMP ADINT ;;; PROCESS A/D INPUT 85$: ;;; .ENDC .IF DF I$$CIM MOV S.DI(R4),R5 ;;; GET DIGITAL INTERRUPT TABLE ADDRESS .ENDC .IF DF I$$CTI&I$$CIM BIT #4,R2 ;;; CONTACT INTERRUPT MODULE? BEQ 90$ ;;; IF EQ YES .ENDC .IF DF I$$CTI MOV S.CT(R4),R5 ;;; GET COUNTER TABLES .ENDC 90$: ;;; .IF DF I$$CIM!I$$CR!I$$CTI CLR RUN ;;; RESET RUN FLAG MOV #6,R1 ;;; SET NUMBER OF BYTES CURRENTLY ON STACK TST R5 ;;; SPURIOUS INTERRUPT? BEQ 172$ ;;; IF EQ YES  .IF DF I$$CIM!I$$CTI&I$$CR CLR -(SP) ;;; CLEAR A WORD CMP R5,S.RTI(R4) ;;; PROCESSING TERMINAL INTERRUPTS? BEQ 100$ ;;; IF EQ YES MOV R3,(SP) ;;; COPY RELATIVE MODULE NUMBER .IFF .IF DF I$$CTI!I$$CIM ;HB001 ;HB001 MOV R3,-(SP) ;;; COPY RELATIVE MODULE NUMBER ;TL045 .ENDC ;TL045 .ENDC 100$: ;;; .IF DF I$$CIM!I$$CTI ASL R3 ;;; MULTIPLY BY TABLE ENTRY SIZE ASL R3 ;;; ... ADD (SP)+,R3 ;;; ASL R3 ;;; ... .ENDC ADD #IMDAT,R3 ;;; OFFSET TO MODULE DATA ENTRIES ADD R5,R3 ;;; .IF DF I$$CR!I$$CTI&I$$CIM CMP R5,S.DI(R4) ;;; DIGITAL INTERRUPTS? BNE 130$ ;;; IF NE NO .ENDC .IF DF I$$CIM MOV (SP),R1 ;;; COPY DATA WORD MOV IMPRV(R3),R0 ;;; COPY PREVIOUS STATE MOV R1,IMPRV(R3) ;;; SET NEW 'PREVIOUS' BIC R0,R1 ;;; CLEAR ALL NEW BITS THAT DID NOT CHANGE BIC (SP),R0 ;;; CLEAR ALL OLD BITS THAT DID NOT CHANGE BIS R0,R1 ;;; COMBINE ALL THAT CHANGED STATE CLR R0 ;;; ASSUME ALL COS WANTED COM R2 ;;; COMPLEMENT PCL, POP FLAGS BIT #140,R2 ;;; BOTH PCL AND POP WANTED BEQ 110$ ;;; IF EQ YES MOV (SP),R0 ;;; GET DATA AGAIN BIT #100,R2 ;;; PCL WANTED? BNE 110$ ;;; IF NE NO COM R0 ;;; SET ALL OPEN POINTS 110$: ;;; BIC R0,R1 ;;; CLEAR UNWANTED COS BITS BNE 120$ ;;; IF NE SOME CHANGED STATE ADD #6,SP ;;; CLEAN STACK BR 175$ ;;; EXIT ISR 120$: ;;; MOV R1,-(SP) ;;; SAVE CHANGE OF STATE MOV R1,-(SP) ;;; SET RESOURCE MASK .IF DF I$$CLK CALL SLINK ;;; ACTIVATE ANY LINKED TASKS ADC RUN ;;; UPDATE RUN FLAG .ENDC BR 170$ ;;; CONTINUE .ENDC 130$: ;;; .IF DF I$$CR!I$$CTI CLR -(SP) ;;; CLEAR SECOND HARDWARE WORD .IF DF I$$CLK MOV #-1,-(SP) ;;; SET RESOURCE MASK .IFTF .IF DF I$$CTI&I$$CR CMP R5,S.CT(R4) ;;; PROCESSING COUNTERS? BNE 140$ ;;; IF NE NO .ENDC .IF DF I$$CTI TST IMTCB(R5) ;;; TASK CONNECTED? BEQ 150$ ;;; IF EQ NO MOV 4(SP),R1 ;;; COPY COUNTER DATA ROL R1 ;;; TIME TO UPDATE COUNTER?  BVS 150$ ;;; IF VS NO (INTERRUPTED ON HALF-COUNT) .IF DF I$$CR BIS #100000,IMBA(R3) ;;; SET 'REFRESH' FLAG INC RUN ;;; FORCE PASS THROUGH FORK PROCESSOR .IFF MOV IMBA(R3),R1 ;;; GET BUS ADDRESS/2 ASL R1 ;;; CONVERT TO BUS ADDRESS MOV IMPRV(R3),(R1) ;;; REFRESH COUNTER .ENDC BR 150$ ;;; .ENDC 140$: ;;; REF. LABEL .IF DF I$$CR CMPB 4(SP),#3 ;;; CONTROL-C? BNE 160$ ;;; IF NE NO .ENDC 150$: ;;; REF. LABEL .IFT CALL SLINK ;;; ACTIVATE LINKED TASKS ADC RUN ;;; UPDATE RUN FLAG .IFTF 160$: ;;; REF. LABEL .IFT MOV (SP)+,(SP) ;;; COLLAPSE STACK .ENDC .ENDC 170$: ;;; REF. LABEL CLR R2 ;;; FLAG ENTRY NOT FORCED CALL CENTR ;;; ENTER DATA IN CIRCULAR BUFFER ADC RUN ;;; UPDATE RUN FLAG MOV R5,R4 ;;; COPY TABLE ADDRESS MOVB IMBPE(R4),R1 ;;; GET BYTES PER ENTRY 172$: ;;; ADD R1,SP ;;; CLEAN STACK 175$: ;;; TST RUN ;;; FORK PROCESSING REQUIRED? BEQ 220$ ;;; IF EQ NO, EXIT ISR TSTB IMFIP(R4) ;;; FORK NOW IN PROGRESS? BEQ 220$ ;;; IF EQ YES CLRB IMFIP(R4) ;;; SET FORK PENDING ADD #IMFRK+6,R4 ;;; POINT TO FORK BLOCK CALL $FORK1 ;;; CREATE A SYSTEM PROCESS INCB IMFIP(R5) ; CLEAR FORK-PENDING FLAG .IF DF I$$CLK!I$$CR MOV IMSCB(R5),R4 ; GET SCB ADDRESS .ENDC .IF DF I$$CLK CMP -(SP),-(SP) ; RESERVE TWO WORDS ON THE STACK .ENDC .IF DF I$$CIM!I$$CR&I$$CLK MOV #CILGH,2(SP) ; SET LENGTH OF CONTACT INTERRUPT ENTRY MOV (R5),(SP) ; PUSH MAX POINT OR CHANNEL .ENDC .IF DF I$$CIM&I$$CLK ASR (SP) ; CONVERT TO NUMBER OF HIGHEST MODULE ASR (SP) ; ... ASR (SP) ; ... ASR (SP) ; ... .ENDC .IF DF I$$CLK!I$$CR .IF DF I$$CIM!I$$CR&I$$CTI CMP S.CT(R4),R5 ; PROCESSING COUNTERS? BNE 200$ ; IF NE NO .ENDC .ENDC .IF DF I$$CLK&I$$CTI MOV #CTLGH,2(SP) ; SET LENGTH OF COUNTER ENTRY MOV (R5),(SP) ; SET NUMBER OF HIGHEST COUNTER .ENDC .IF DF I$$CR&I$$CTI MOV R5,R3 ; SET ADDRESS OF COUNTER TABLES TST IMTCB(R3) ; ANY TASK CONNECTED? BEQ 200$ ; IF EQ NO MOV (R3),R0 ; GET HIGHEST COUNTER NUMBER ADD #IMDAT+IMPRV,R3 ; POINT TO PREVIOUS STATE ENTRY 180$: ; TST IMBA-IMPRV(R3) ; REFRESH BIT SET? BPL 190$ ; IF PL NO CALL SETCT ; REFRESH COUNTER 190$: ; ADD #CTLGH,R3 ; STEP TO NEXT MODULE ENTRY DEC R0 ; DECREMENT COUNT BPL 180$ ; IF PL GO AGAIN .ENDC 200$: ; REF. LABEL .IF DF I$$CLK MOV R5,R4 ; COPY TABLE ADDRESS ADD #IMDAT+IMLH,R4 ; POINT TO MODULE ENTRIES 210$: ; MOV R4,R3 ; COPY ADDRESS OF ENTRY CALL ALINK ; ACTIVATE LINKED TASK ADD 2(SP),R4 ; POINT TO NEXT ENTRY DEC (SP) ; DECREMENT MODULE COUNT BPL 210$ ; IF PL GO AGAIN CMP (SP)+,(SP)+ ; CLEAN STACK .ENDC ;+ ; **-ACBUF-ACTIVATE TASK CONNECTED TO CIRCULAR BUFFER ; ; THIS SUBROUTINE IS CALLED TO ACTIVATE A TASK THAT IS ; CONNECTED TO A CIRCULAR BUFFER AND SET THE TRIGGER ; EVENT FLAG. ; ; INPUTS: ; ; R5=INTERRUPT MODULE TABLE ADDRESS ; ; OUTPUTS: ; ; IF A TASK IS CONNECTED THE TRIGGER EVENT FLAG IS SET ; AND THE TASK IS MADE ACTIVE. ; ; REGISTERS MODIFIED: ; ; RO - R3 ; ;- ACBUF: ; MOV IMTCB(R5),R0 ; GET TCB ADDRESS BEQ 220$ ; IF EQ NONE, EXIT BIS IMEVM(R5),@IMEVA(R5) ; SET EVENT FLAG MASK CALL $SETCR ; CONDITIONALY SCHEDULE TASK 220$: ;;; RETURN ;;; EXIT INTERRUPT SERVICE ROUTINE .ENDC .ENDC .DSABL LSB ;+ ; **-ICAN-CANCEL I/O OPERATION ; ; THIS ROUTINE IS CALLED BY THE EXECUTIVE TO CANCEL ALL I/O IN ; PROGRESS FOR THE CURRENT TASK. IF THE TASK IS CONNECTED TO ; EITHER CONTACT INTERRUPTS, COUNTERS OR REMOTE TERMINAL ; INTERRUPTS IT IS DISCONNECTED. ALL A/D INPUT IS ALLOWED TO ; COMPLETE SINCE IT WILL DO SO WITHIN A REASONABLE AMOUNT OF TIME. ; ALL TERMINAL OUTPUT IS SET TO TERMINATE ON THE OCCURENCE OF THE ; NEXT OUTPUT INTERRUPT. ; ;- .ENABL LSB ICAN: ;;; .IF DF I$$CIM!I$$CR!I$$CTI MOV R1,R0 ;;; SET TCB ADDRESS OF CURRENT TASK .IF DF I$$CIM MOV S.DI(R4),R3 ;;; GET ADDRESS OF CONTACT INTERRUPT TABLES .ENDC .IF DF I$$CR!I$$CTI&I$$CIM CALL ICAN1 ;;; DISCONNECT TASK .ENDC .IF DF I$$CTI MOV S.CT(R4),R3 ;;; GET ADDRESS OF COUNTER TABLES .ENDC .IF DF I$$CR&I$$CTI CALL ICAN1 ;;; DISCONNECT TASK .ENDC .IF DF I$$CR BIT #TUSE,S.FLG(R4) ;;; TERMINAL IN USE? BEQ 5$ ;;; IF EQ NO MOV S.PKT(R4),R1 ;;; GET ADDRESS OF I/O PACKET CMP R0,I.TCB(R1) ;;; TERMINAL IN USE BY THIS TASK? BNE 5$ ;;; IF NE NO BIS #TABO,S.FLG(R4) ;;; FORCE I/O COMPLETION ON NEXT TERMINAL INTERRUPT 5$: ;;; MOV S.RTI(R4),R3 ;;; GET ADDRESS OF REMOTE TERMINAL TABLES .ENDC ;+ ; ; **-ICAN1-CONDITIONALLY DISCONNECT A TASK FROM INTERRUPTS ; ; THIS SUBROUTINE IS CALLED TO CONDITIONALLY DISCONNECT A TASK FROM ; ICS/ICR UNSOLICITED INTERRUPTS. IF THE MODULE IS INSTALLED ON THE ; CONTROLLER AND THE TCB ADDRESS MATCHES THAT OF THE CONNECTED TASK THEN ; THE TASK IS DISCONNECTED. ; ; INPUTS: ; ; Z/CLEAR IF SPECIFIED MODULE TYPE IS INSTALLED ON THIS CONTROLLER ; ; R0 = TCB ADDRESS OF TASK TO BE DISCONNECTED ; R3 = MODULE TABLE ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; C/CLEAR: TASK DISCONNECTED FROM INTERRUPTS ; ; THE TCB ADDRESS, EVENT FLAG MASK AND ADDRESS IN THE DEVICE TABLE ; ARE CLEARED. ; ; ; C/SET: TASK NOT CONNECTED OR NON-EXISTENT MODULE TYPE SPECIFIED. ; Z/SET: NON EXISTENT MODULE TYPE SPECIFIED. ; ; REGISTERS MODIFIED: ; ; R1 ; ;- ICAN1: ;;; BEQ 10$ ;;; IF EQ MODULE DOES NOT EXIST CMP R0,IMTCB(R3) ;;; THIS TASK CONNECTED? BNE 10$ ;;; IF NE NO CLR IMTCB(R3) ;;; DISCONNECT TASK CLR IMEVA(R3) ;;; CLEAR ADDRESS OF EVENT FLAG MASK CLR IMEVM(R3) ;;; CLEAR EVENT FLAG MASK DECB T.IOC(R0) ;;; DECREMENT OUTSTANDING I/O COUNT .IF DF D$$SHF MOV T.PCB(R0),R1 ;;; GET ADDRESS OF PCB BIC #PS.NSF,P.STAT(R1) ;;; ENABLE SHUFFLING .ENDC BR 20$ ;;; 10$: ;;; SEC ;;; SET NO-CONNECT FLAG 20$: ;;; .ENDC RETURN ;;; .DSABL LSB ;+ ; ; **-ICPWF-DEVICE DEPENDANT POWER RECOVERY CODE ; ; POWER FAILURE IS HANDLED VIA THE DEVICE TIMEOUT FACILITIES AND ; THEREFORE CAUSES NO IMMEDIATE ACTION. THE ICS/ICR-11 CONTROL BLOCK ; ADDRESS IS STORED, THE STATE OF ALL VOLATILE OUTPUT MODULES IS ; RESTORED AND ALL ICS/ICR-11 INTERRUPTS ARE ENABLED. ;- .ENABL LSB ICPWF: ; .IF DF I$$CAD!I$$CIM!I$$CTI!I$$CR MOV R5,CNTBL(R3) ; SAVE ADDRESS OF UCB .ENDC .IF DF I$$CR MOV #WDFLG,R0 ; GET ADDRESS OF WATCHDOG FLAG TST (R0) ; WATCHDOG TIMER SCHEDULED? BNE RSTOR ; IF NE YES MOV PC,(R0)+ ; SET TIMER FLAG CALL SWDT ; INITIATE WATCHDOG TIMER .IFTF MOV U.SCB(R5),R4 ; RESTORE ADDRESS OF SCB ;+ ; **-RSTOR-RESTORE THE STATE OF THE ICS/ICR CONTROLLER ; ; THIS SUBROUTINE IS CALLED TO RESTORE THE STATE OF THE ICR CIRCULAR ; OUTPUT BUFFER, ANALOG OUTPUTS, COUNTER MODULES AND LATCHING OUTPUTS ; FOLLOWING A POWER FAIL AT THE PROCESSOR OR A FAULT AT THE REMOTE SITE. ; THE STATE OF EACH COUNTER IS RESTORED PROVIDED THAT: ; ; (1) A TASK IS CONNECTED OR, ; (2) A TASK IS LINKED TO RECEIVE COUNTER INTERRUPTS AND ; A NON-ZERO COUNTER VALUE WAS SPECIFIED. ; ; INPUTS: ; ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; THE CIRCULAR OUTPUT BUFFER IS PLACED IN THE EMPTY STATE AND ; THE STATE OF EACH COUNTER MODULE, ANALOG OUTPUT CHANNEL AND ; LATCHING OUTPUT MODULE IS RESTORED AS PREVIOUSLY DESCRIBED. ; ; REGISTERS MODIFIED: ; ; R0 - R3 ; ;- RSTOR: ; .IFT MOV S.CBF(R4),R3 ; GET ADDRESS OF CIRCULAR BUFFER BEQ 5$ ; IF EQ, NO CIRC. BFR (ICS11) MOV #-1,(R3)+ ; SET BUFFER EMPTY MOV R3,(R3) ; SET ADDRESS OF BUFFER+2 ADD #CDAT-2,(R3) ; COMPUTE ADDRESS OF OUTPUT POINTER MOV (R3)+,(R3) ; INSERT ADDRESS OF INPUT POINTER MOV (R3)+,(R3) ; COPY ADDRESS OF INPUT POINTER ADD #CLGH-CDAT-2,(R3) ; COMPUTE END ADDRESS 5$: ; BIT #UFL,S.FLG(R4) ; ERROR INTERRUPTS RECOGNIZED? BNE 10$ ; IF NE NO BIS #22,@S.CSR(R4) ; ENABLE ERROR INTERRUPTS BIT #UNR,S.FLG(R4) ; UNIT READY? BNE 60$ ; IF NE NO .ENDC 10$: ; REF. LABEL BIS #4,@S.CSR(R4) ; ENABLE MODULE INTERRUPTS .IF DF I$$CIM!I$$CLT!I$$CDA TSTB U.RST(R5) ; RESTORE STATE OF THIS CONTROLLER? BEQ 60$ ; IF EQ NO .ENDC .IF DF I$$CTI MOV S.CT(R4),R3 ; GET ADDRESS OF COUNTER TABLES BEQ 20$ ; IF EQ NONE CALL RSETC ; RESET ALL COUNTERS 20$: ; .ENDC .IF DF I$$CIM MOV S.DI(R4),R3 ; GET ADDRESS OF DIGITAL INTERRUPT TABLE BEQ 25$ ; IF EQ NONE CALL READDI ; READ IN CURRENT STATES 25$: .ENDC .IF DF I$$CDA MOV R4,R0 ; COPY SCB ADDRESS ADD #S.DAC,R0 ; POINT TO D/A TABLES MOV (R0)+,R3 ; GET MAPPING TABLE ADDRESS BEQ 40$ ; IF EQ NONE MOV 2(R0),-(SP) ; PUSH NUMBER OF CHANNELS-1 MOV (R0),R0 ; POINT TO PREVIOUS STATE TABLE CLR -(SP) ; RESERVE SPACE ON THE STACK 30$: ; MOV (R0)+,R1 ; GET PREVIOUS STATE BIC #140000,R1 ; CLEAR CHANNEL NUMBER BIC #37777,(SP) ; CLEAR VOLTAGE REPRESENTATION BIS R1,(SP) ; MERGE CHANNEL AND VOLTAGE MOV #ICMD/2&77777,-(SP) ; PUSH BUS ADDRESS OF ICR/2 BISB (R3),(SP) ; MERGE MODULE OFFSET MOV SP,R1 ; SET ADDRESS OF BLOCK CALL CBINS ; OUTPUT TO DEVICE TST (SP)+ ; CLEAN STACK ADD #40000,(SP) ; INCREMENT CHANNEL NUMBER ADC R3 ; STEP TO NEXT MODULE ON OVERFLOW DEC 2(SP) ; DECREMENT COUNT BPL 30$ ; IF PL GO AGAIN CMP (SP)+,(SP)+ ; CLEAN STACK 40$: ; .ENDC .IF DF I$$CLT MOV R4,R0 ; COPY ADDRESS OF SCB ADD #S.LTO,R0 ; POINT TO LATCHING OUTPUT TABLE ADDRESSES MOV (R0)+,R3 ; GET MAPPING TABLE ADDRESS BEQ 60$ ; IF EQ NONE MOV 2(R0),-(SP) ; SET POINT COUNT-1 MOV (R0),R0 ; GET ADDRESS OF PREVIOUS STATE TABLE 50$: ; MOV (R0)+,-(SP) ; PUSH PREVIOUS STATE MOV #ICMD/2&77777,-(SP) ; PUSH BUS ADDRESS/2 BISB (R3)+,(SP) ; COMBINE WITH MODULE OFFSET BIAS MOV SP,R1 ; COPY ADDRESS OF BLOCK CALL CBINS ; INSERT IN CIRCULAR BUFFER CMP (SP)+,(SP)+ ; CLEAN STACK SUB #16.,(SP) ; DECREMENT POINT COUNT BPL 50$ ; IF PL GO AGAIN INC (SP)+ ; CLEAN THE STACK .ENDC 60$: ; RETURN .DSABL LSB ;+ ; **-ICWDT-WATCHDOG TIMER ROUTINE ; ; THIS ROUTINE IS SCHEDULED BY THE DRIVER TO PERIODICALY RE- ; SET THE SOFTWARE WATCHDOG TIMERS FOR ALL CONTROLLERS AND PER- ; FORM ERROR RECOVERY FOR ANY CONTROLLER THAT IS IN THE NOT-READY ; STATE. ; ;- .ENABL LSB .IF DF I$$CR ICWDT: ; MOV #I$$C11,-(SP) ; SET COUNT OF CONTROLLERS 10$: ; MOV #CNTBL-2,R5 ; GET ADDRESS OF UCB TABLE ADD (SP),R5 ; OFFSET TO CONTROLLER SLOT ADD (SP),R5 ; ... MOV (R5),R5 ; GET UCB ADDRESS BEQ 40$ ; IF EQ CONTROLLER OFFLINE BITB #US.OFL,U.ST2(R5) ; CONTROLLER OFFLINE? BNE 40$ ; IF NE YES MOV U.SCB(R5),R4 ; GET ADDRESS OF SCB MOV #-I$$CWD,S.ERR(R4) ; RESET WATCHDOG TIMER TSTB S.CTMC(R4) ; CONTROLLER TIMEOUT ACTIVE? BEQ 20$ ; IF EQ NO DECB S.CTMC(R4) ; DECREMENT TIMEOUT COUNT BNE 40$ ; IF NE OK CALL CTOUT ; INITIATE TIMEOUT PROCESSING BR 40$ ; 20$: ; MOV S.CSR(R4),R2 ; GET CSR ADDRESS BIT #UNR,S.FLG(R4) ; DEVICE NOT READY? BEQ 40$ ; IF EQ NO BIT #12000,(R2) ; ERROR CONDITIONS PRESENT? BNE 30$ ; IF NE YES BIC #UNR,S.FLG(R4) ; CLEAR NOT-READY FLAG CALL RSTOR ; RESTORE CONTROLLER BR 40$ ; 30$: ; MOV -(R2),R2 ; CLEAR ERROR FLAGS 40$: ; DEC (SP) ; DECREMENT CONTROLLER COUNT BGT 10$ ; IF GT MORE TO GO INC (SP)+ ; CLEAN STACK MOV #WDFLG+2,R0 ; GET ADDRESS OF TIMER PACKET SWDT: ; CLR R1 ; CLEAR HIGH ORDER DELTA TIME MOV $TKPS,R2 ; GET TICKS PER SECOND MOV #C.SYST,R4 ; SET REQUEST TYPE CALLR $CLINS ; INSERT IN CLOCK QUEUE .ENDC .DSABL LSB ;+ ; ; **-ALINK-ACTIVATE A LINKED TASK ; ; THIS SUBROUTINE IS CALLED TO ACTIVATE ALL TASKS LINKED ; TO A GIVEN INTERRUPT LIST. IF THE SPECIFIED TASK IS AC- ; TIVE THEN THE EVENT FLAG DEFINED THROUGH THE LINK FUNC- ; TION IS SET ELSE THE TASK IS REQUESTED TO RUN. ; ; INPUTS: ; ; R3=ADDRESS OF INTERRUPT LINK LIST ; ; OUTPUTS: ; ; IF THE 'RUN' FLAG IS SET IN THE ENTRY, THEN THE ; TASK IS MADE ACTIVE AS DESCRIBED ABOVE ELSE THE ; SPECIFIED EVENT FLAG IS SET. ; ; REGISTERS MODIFIED: ; ; R0 - R3 ; ;- .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK ALINK: ; MOV R3,-(SP) ; SAVE LISTHEAD ADDRESS 10$: ; MOV @(SP)+,R3 ; GET LINK TO NEXT BEQ 30$ ; IF EQ DONE WITH LIST MOV R3,-(SP) ; SAVE ADDRESS OF THIS ENTRY TST ILRUN(R3) ; RUN FLAG SET? BEQ 10$ ; IF EQ NO CLR ILRUN(R3) ; CLEAR RUN FLAG MOV ILTE(R3),R0 ; GET ADDRESS OF LINKED TASK ENTRY MOV LTCB(R0),R0 ; GET ADDRESS OF TCB MOV T.STAT(R0),R1 ; GET TASK STATUS FLAGS BIT #TS.EXE,R1 ; TASK ACTIVE? BNE 20$ ; IF NE NO BIT #T2.ABO,T.ST2(R0) ; TASK BEING ABORTED? BNE 10$ ; IF NE YES BIT #TS.OUT,R1 ; TASK OUT OF MEMORY? BEQ 15$ ; IF EQ NO BIT #TS.CKP,R1 ; TASK CHECKPOINTED? BEQ 10$ ; IF EQ NO 15$: ; MOV ILEVA(R3),R2 ; GET ADDRESS OF EVENT FLAG MASK BEQ 10$ ; IF EQ NONE BIS ILEVM(R3),(R2) ; SET EVENT FLAG CALL $SETCR ; ISSUE CONDITIONAL SCHEDULE REQUEST BR 10$ ; GO AGAIN 20$: ; CLR R1 ; SET DEFAULT UIC CALL $TSKRT ; REQUEST TASK BR 10$ ; GO AGAIN 30$: ; RETURN ; .ENDC ;+ ; ; **-CBINS-INSERT AN ENTRY IN THE CIRCULAR BUFFER ; ; INPUTS: ; ; R1=ADDRESS OF TWO-WORD DATA BLOCK CONTAINING THE ; FOLLOWING: ; ; WD. 00 -- BUS ADDRESS/2!REMOTE TERMINAL BIT(MSB) ; WD. 01 -- BUS DATA ; ; R4=ADDRESS OF STATUS CONTROL BLOCK ; ; OUTPUTS: ; ; C/CLEAR: ENTRY INSERTED IN BUFFER ; ; C/SET: CONTROLLER TIME-OUT DETECTED. ; ; ; IF CONTROLLER TIME-OUT IS DETECTED THE APPROPRIATE ERROR ; PROCESSING IS INITIATED. ; ; R1 AND R2 ARE MODIFIED ; ;- CBINS: ; .IF DF I$$CR MOV R3,-(SP) ; SAVE R3 MOV S.CBF(R4),R3 ; GET ADDRESS OF CIRCULAR BUFFER BEQ 60$ ; IF EQ 0, NO CBF (THIS IS ICS11) MOV #TMOUT,-(SP) ; SET DEVICE TIME-OUT COUNT 10$: ; CMP #/4-1,(R3) ; ROOM IN BUFFER? BGT 20$ ; IF GT YES DEC (SP) ; DECREMENT TIME-OUT COUNT BNE 10$ ; IF NE TRY AGAIN MOV R0,(SP) ; SAVE R0 CALL CTOUT ; INITIATE DEVICE TIME-OUT PROCESSING MOV (SP),R0 ; RESTORE R0 BR 50$ ; EXIT 20$: ; CMP (R3)+,(R3)+ ; POINT TO INPUT POINTER MOVB #PR6,PS ;;; LOCKOUT DEVICE INTERRUPTS MOV (R3)+,R2 ;;; GET INPUT POINTER MOV 2(R1),(R2)+ ;;; SET OUTPUT DATA MOV (R1),(R2)+ ;;; SET BUS ADDRESS CMP R2,(R3)+ ;;; AT END OF BUFFER? BLO 30$ ;;; IF LO NO MOV R3,R2 ;;; RESET POINTER TO START OF DATA 30$: ;;; MOV R2,CIN-CDAT(R3) ;;; SAVE INPUT POINTER INC CBSY-CDAT(R3) ;;; INCREMENT BUSY COUNT BEQ 35$ ;;; IF EQ NO INTERRUPTS WANTED BIS #10,@S.CSR(R4) ;;; ENABLE INTERRUPTS MOVB S.ITMC(R4),S.CTMC(R4) ;;; ENABLE CONTROLLER TIMEOUTS BR 40$ ;;; 35$: ;;; CALL CBOUT ;;; STARTUP INTERRUPTS 40$: ;;; CLRB PS ; ALLOW DEVICE INTERRUPTS 50$: ; INC (SP)+ ; CLEAN STACK MOV (SP)+,R3 ; RESTORE R3 RETURN ; 60$: ; MOV (SP)+,R3 ; RESTORE R3 .IFTF MOV (R1)+,R2 ; GET BUS ADDRESS/2 ASL R2 ; CONVERT TO BUS ADDRESS MOV (R1),(R2) ; TRANSFER MODULE DATA RETURN ; ;+ ; **-CBOUT-TRANSMIT CIRCULAR BUFFER DATA TO DEVICE ; ; THIS SUBROUTINE IS CALLED AT DEVICE PRIORITY LEVEL TO TRANS- ; FER DATA FROM THE CIRCULAR BUFFER TO THE SPECIFIED BUS AD- ; DRESS. ; ; INPUTS: ; ; R4=ADDRESS OF STATUS CONTROL BLOCK ; ; OUTPUTS: ; ; DATA (IF PRESENT) IS TRANSMITTED TO THE BUS ADDRESS ; CONTAINED IN THE BUFFER. ; ; R1, R2, AND R3 ARE MODIFIED ; ;- .IFT CBOUT: ;;; MOV S.CSR(R4),R1 ;;; GET CSR ADDRESS MOV S.CBF(R4),R3 ;;; GET CIRCULAR BUFFER ADDRESS BEQ 40$ ;;; IF EQ, ICS-11 & THUS NO CBF TST (R3)+ ;;; POINT TO OUTPUT POINTER MOV (R3)+,R2 ;;; GET OUTPUT POINTER ASL 2(R2) ;;; SHIFT BUS ADDRESS BCC 10$ ;;; IF C/CLEAR NO REMOTE TERMINAL OUTPUT BIS #40,(R1) ;;; ENABLE REMOTE TERMINAL I/O 10$: ;;; MOV (R2)+,@(R2)+ ;;; MOVE DATA TO DEVICE BCC 15$ ;;; IF C/C NOT REMOTE TERMINAL I/O BIS #1000,(R1) ;;; ENABLE REMOTE TERMINAL OUTPUT INTERRUPT BIC #40,(R1) ;;; DISABLE REMOTE TERMINAL MODE 15$: ;;; TST (R3)+ ;;; POINT TO END ADDRESS OF BUFFER CMP R2,(R3)+ ;;; REACHED END OF BUFFER? BLO 20$ ;;; IF LO NO MOV R3,R2 ;;; RESET OUTPUT POINTER 20$: ;;; MOV R2,COUT-CDAT(R3) ;;; SAVE OUTPUT POINTER 30$: ;;; RETURN ;;; 40$: ; CRASH ;;; CBOUT CALLED ON AN ICS-11 .ENDC ;+ ; ; **-CENTR-CONDITIONALLY ENTER DATA IN A CIRCULAR BUFFER ; ; THIS ROUTINE IS CALLED AT DEVICE PRIORITY LEVEL TO CONDITIONALLY ; INSERT AN ENTRY IN A CIRCULAR BUFFER. ; ; INPUTS: ; ; R2=FORCE ENTRY FLAG ; ; R2=0 - INSERT NEW ENTRY ONLY IF BUFFER IS FREE ; R2=-1 - INSERT NEW ENTRY EVEN IF BUFFER NOT READ BY TASK ; ; R5=MODULE TABLE ADDRESS ; ; STACK CONTENTS: ; ; (SP)+00 -- RETURN TO CALLER ; (SP)+02 -- UNDEFINED ; (SP)+04 -- CIRCULAR BUFFER ENTRY WD. 01 ; . . ; . . ; (SP)+NN -- CIRCULAR BUFFER ENTRY WD. NN ; ; OUTPUTS: ; ; C/SET: A TASK IS CONNECTED TO INTERRUPTS ; ; IF R2 WAS NEGATIVE, THE ENTRY IS UNCONDITIONALLY ; INSERTED IN THE CIRCULAR BUFFER. ELSE THE ENTRY ; EXISTENCE INDICATOR IS TESTED. IF NON-ZERO THE ; ENTRY IS DISCARDED AND A COUNT OF OVERRUNS IS ; INCREMENTED AND PLACED IN THE BUFFER. IF ZERO ; THE ENTRY IS PLACED IN THE BUFFER AND THE INDI- ; CATOR IS SET TO +1 ; ; ; C/CLEAR: NO TASK CONNECTED OR OVERRUN EXISTS ; ; REGISTERS MODIFIED: ; ; R0 - R2 ; ;- .IF DF I$$CIM!I$$CR!I$$CTI CENTR: ;;; MOV SP,R0 ;;; GET ADDRESS OF STACK TST (R0)+ ;;; POINT TO FIRST WORD OF BUFFER ENTRY MOV #1,(R0) ;;; ASSUME NO FORCED ENTRY .IF DF M$$MGE MOV KISAR6,-(SP) ;;; SAVE ASR 6 MOV IMCBF(R5),KISAR6 ;;; MAP TO USER'S BUFFER .IFTF TST IMTCB(R5) ;;; TASK CONNECTED? BEQ 60$ ;;; IF EQ NO MOV IMCUR(R5),R1 ;;; GET CURRENT BUFFER ADDRESS TST (R1) ;;; ENTRY FREE BEQ 10$ ;;; IF EQ YES TST R2 ;;; FORCED ENTRY? BPL 50$ ;;; IF PL NO 10$: ;;; SUB R2,(R0) ;;; INCLUDE FORCED ENTRY CONDITION MOVB IMBPE(R5),R2 ;;; GET BYTES PER ENTRY ASR R2 ;;; CONVERT TO WORD BIAS CLR IMLST(R5) ;;; CLEAR LOST DATA COUNT 20$: ;;; MOV (R0)+,(R1)+ ;;; MOVE A WORD TO USERS'S BUFFER .IFT BIT #20000,R1 ;;; CROSS 4K BOUNDARY? BEQ 30$ ;;; IF EQ NO BIC #20000,R1 ;;; RESET BUFFER ADDRESS ADD #200,KISAR6 ;;; RESET ADDRESS BIAS  ADD #200,IMCBF(R5) ;;; ... .IFTF 30$: ;;; INC IMFIL(R5) ;;; INCREMENT FILL INDEX CMP IMLGH(R5),IMFIL(R5) ;;; REACHED END OF BUFFER? BHIS 40$ ;;; IF HIS NO MOV #3,IMFIL(R5) ;;; RESET FILL INDEX .IFT MOV IMSBF(R5),IMCBF(R5) ;;; RESET ADDRESS TO START MOV IMCBF(R5),KISAR6 ;;; ... .IFTF MOV IMSDA(R5),R1 ;;; POINT TO START OF DATA 40$: ;;; DEC R2 ;;; DECREMENT WORD COUNT BGT 20$ ;;; IF GT MORE TO MOVE MOV R1,IMCUR(R5) ;;; SAVE CURRENT ADDRESS .IFT MOV IMSBF(R5),KISAR6 ;;; POINT TO START OF BUFFER .IFTF MOV IMFIL(R5),@IMSAD(R5) ;;; RESET FILL INDEX SEC ;;; SET SUCCESS BR 70$ ;;; 50$: ;;; CMP IMLST(R5),#100001 ;;; OVERRUN COUNT PEGGED? BEQ 55$ ;;; IF EQ YES DEC IMLST(R5) ;;; 'INCREMENT' LOST DATA COUNT 55$: ;;; MOV IMLST(R5),(R1) ;;; SET OVERRUN COUNT 60$: ;;; CLC ;;; SET FAILURE 70$: ;;; .IFT MOV (SP)+,KISAR6 ;;; RESTORE ASR 6 .ENDC RETURN ;;; .ENDC ;+ ; ; **-CTOUT-ACTIVATE ERROR PROCESSING ON CONTROLLER TIME-OUT ; ; THIS SUBROUTINE IS CALLED WHENEVER CONTROLLER TIMEOUT IS DE- ; TECTED. IF THE UNIT IS ONLINE ERROR ALARMING IS INITIATED. ; ; INPUTS: ; ; R4=ADDRESS OF STATUS CONTROL BLOCK ; R5=ADDRESS OF UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; C BIT CLEAR: UNIT ONLINE. ; ; C BIT CLEAR: UNIT OFFLINE OR PREVIOUS NO-RESPONSE CONDITION IN EFFECT. ; ; IF THE UNIT IS ON-LINE ALL ERROR ALARMING TASKS ARE ; INITIATED. THE UNIT IS PLACED IN THE NOT READY STATE. ; ; REGISTERS MODIFIED ; R0 - R3 ; ;- .IF DF I$$CR CTOUT: ; CLC ; ASSUME UNIT OFFLINE MOV U.UNIT(R5),R1 ; GET UNIT NUMBER MOV R4,-(SP) ; SAVE SCB ADDRESS MOV R5,-(SP) ; SAVE UCB ADDRESS MOV S.CSR(R4),R5 ; GET ADDRESS OF CSR MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS BIT #UNR!NORSP,S.FLG(R4) ;;; UNIT NOT READY OR NO RESPONSE? BNE 5$ ;;; IF NE YES BIS #UNR!NORSP,S.FLG(R4) ;;; SET NOT-READY, NO RESPONSE CONDITIONS MOV (R5),R0 ;;; GET ICSR CONTENTS CALL STERR ;;; INITIATE ERROR PROCESSING CLRB PS ; ALLOW DEVICE INTERRUPTS MOV (SP),R5 ; SET UCB ADDRESS CALL INIER ; INITIATE ERROR PROCESSING 5$: ;;; CLRB PS ; ALLOW DEVICE INTERRUPTS MOV (SP)+,R5 ; RESTORE UCB ADDRESS MOV (SP)+,R4 ; RESTORE SCB ADDRESS SEC ; FLAG UNIT ONLINE 10$: ; RETURN ; .ENDC ;+ ; ; **-RSETC-SUBROUTINE TO RESET ALL COUNTER MODULES ; ; THIS ROUTINE IS CALLED WHENEVER IT IS NECESSARY TO UNCONDITIONALLY ; RESET THE STATE OF ALL COUNTERS ON A CONTROLLER. ; ; INPUTS: ; ; R3=ADDRESS OF COUNTER TABLE ; R5=ADDRESS OF UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; R4=ADDRESS OF STATUS CONTROL BLOCK ; ALL COUNTERS ARE RESET WITH THE CURRENT STATE ; ; REGISTERS MODIFIED: ; ; R1 - R3 ; ;- .IF DF I$$CTI RSETC: ; MOV U.SCB(R5),R4 ; GET ADDRESS OF SCB MOV IMTCB(R3),-(SP) ; PUSH TCB ADDRESS OF CONNECTED TASK MOV (R3),-(SP) ; SET NUMBER OF COUNTERS-1 ADD #IMDAT+IMPRV,R3 ; OFFSET TO MODULE DATA 10$: ; TST 2(SP) ; TASK CONNECTED? BNE 20$ ; IF NE YES TST IMRES-IMPRV(R3) ; TASK LINKED? BEQ 30$ ; IF EQ NO TST (R3) ; PREVIOUS STATE 0 BEQ 30$ ; IF EQ YES - DON'T RESET COUNTER 20$: ; CALL SETCT ; INITIALIZE THE COUNTER 30$: ; ADD #CTLGH,R3 ; POINT TO NEXT ENTRY DEC (SP) ; DECREMENT COUNT BPL 10$ ; IF PL GO AGAIN MOV (SP)+,(SP)+ ; CLEAN STACK RETURN ; .ENDC ;+ ; ; **-READDI-SUBROUTINE TO READ THE CURRENT STATE OF ALL DI MODULES ; ; THIS ROUTINE IS CALLED WHEN POWER IS APPLIED, IN ORDER TO READ IN THE ; CURRENT STATE OF ALL THE DIGITAL INTERRUPT MODULES ON A CONTROLLER. ; ; INPUTS: ; ; R3=ADDRESS OF DIGITAL INTERRUPT TABLE ; R4=ADDRESS OF STATUS CONTROL BLOCK ; R5=ADDRESS OF UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; ALL "IMPRV" ENTRIES IN THE MODULE DATA FOR THE CONTROLLER HAVE ; BEEN FILLED IN. ; ; REGISTERS MODIFIED: ; ; R2 - R3 ; ;- .IF DF I$$CIM READDI: ; MOV R4,-(SP) ; SAVE R4 MOV (R3),R2 ; GET HIGHEST POINT - 15 ASR R2 ; CONVERT TO NO. MODULES - 1 ASR R2 ; ... ASR R2 ; ... ASR R2 ; ... ADD #IMDAT,R3 ; POINT AT MODULE DATA 10$: MOV IMBA(R3),R4 ; GET MODULE BUS ADDRESS / 2 ASL R4 ; CALCULATE BUS ADDRESS MOV (R4),IMPRV(R3) ; READ CURRENT MODULE STATE DEC R2 ; COUNT PASSES BPL 10$ ; ... MOV (SP)+,R4 ; RESTORE SCB TO R4 ;JM043 RETURN .ENDC ;+ ; ; **-SAVE-SAVE REGISTERS R3 - R0 ; ; THIS SUBROUTINE IS CALLED VIA A 'JSR R3,SAVE' TO SAVE ; REGISTERS R3 - R0. A CO-ROUTINE CALL IS THEN MADE TO ; THE CALLER. A SUBSEQUENT RETURN WILL CAUSE THE REGISTERS ; TO BE RESTORED AND THE INTERRUPT ENABLE BITS TO BE TOGGLED ; IN ORDER TO PERMIT THE ASSERTION OF ANY PENDING BUT UNRE- ; COGNIZED INTERRUPTS. EXIT IS VIA A RETURN. ; ;- .IF DF I$$CAD!I$$CIM!I$$CTI!I$$CR SAVE: ;;; MOV R2,-(SP) ;;; SAVE R2 MOV R1,-(SP) ;;; SAVE R1 MOV R0,-(SP) ;;; SAVE R0 CALL (R3) ;;; CALL THE CALLER MOV CSR,R0 ;;; GET THE CSR ADDRESS MOV (R0),R1 ;;; READ THE CSR CONTENTS BIC #^C<1036>,R1 ;;; CLEAR ALL BUT THE INTERRUPT ENABLE BITS BIC R1,(R0) ;;; DISABLE ALL ENABLED INTERRUPTS BIS R1,(R0) ;;; RE-ENABLE APPROPRIATE INTERRUPTS MOV (SP)+,R0 ;;; RESTORE R0 MOV (SP)+,R1 ;;; RESTORE R1 MOV (SP)+,R2 ;;; RESTORE R2 MOV (SP)+,R3 ;;; RESTORE R3 RETURN ;;; EXIT .ENDC ;+ ; ; **-SETCT-INITIALIZE A COUNTER MODULE ; ; THIS SUBROUTINE IS CALLED TO INITIALIZE A SINGLE COUNTER MODULE. ; ; INPUTS: ; ; R3=ADDRESS OF COUNTER MODULE ENTRY IN MODULE TABLE ; R4=ADDRESS OF STATUS CONTROL BLOCK ; ; OUTPUTS: ; ; THE SPECIFIED COUNTER IS INITIALIZED WITH THE VALUE ; CONTAINED IN THE INITIAL VALUE CELL WITHIN THE TABLE. ; ; REGISTERS MODIFIED: ; ; R1 - R2 ; ;- .IF DF I$$CTI SETCT: ; .IF DF I$$CR MOV (R3)+,-(SP) ; PUSH MODULE DATA MOV #100000,R1 ; GET REFRESH FLAG MOV (R3),-(SP) ; PUSH BUS ADDRESS/2 BIC R1,(R3) ; CLEAR POSSIBLE REFRESH FLAG BIC R1,(SP) ; ... .IFF MOV (R3)+,-(SP) ; PUSH MODULE DATA MOV (R3),-(SP) ; PUSH BUS ADDRESS .IFTF MOV SP,R1 ; COPY ADDRESS OF BLOCK .IFT TST S.RTI(R4) ; ICS-11 CONTROLLER? BEQ 10$ ; IF EQ YES CALL CBINS ; TRANSMIT DATA TO DEVICE BR 20$ ; EXIT 10$: ; .IFTF ASL (R1)+ ; SHIFT BUS ADDRESS MOVB #PR6,PS ;;; INHIBIT DEVICE INTERRUPTS BIS #1,@S.CSR(R4) ;;; SET RIF BIT MOV (R1),@-(R1) ;;; RESET COUNTER CLRB PS ; ALLOW DEVICE INTERRUPTS .ENDC 20$: ; MOV (SP)+,(SP)+ ; CLEAN STACK TST -(R3) ; RESET R3 RETURN ; .ENDC ;+ ; ; **-SLINK-SCAN LINKED INTERRUPT LIST FOR A MATCH ; ; THIS SUBROUTINE IS CALLED AT DEVICE PRIORITY LEVEL TO  ; SCAN A LINKED INTERRUPT LIST FOR A MATCH. IF A MATCH ; IS FOUND THE ENTRY IS FLAGGED FOR SCHEDULING AT FORK ; LEVEL. ; ; INPUTS: ; ; R3=ADDRESS OF ENTRY IN MODULE TABLE ; TMP=PHYSICAL UNIT NUMBER ; ; STACK CONTENTS AS FOLLOWS: ; ; (SP)+00 -- RETURN TO CALLER ; (SP)+02 -- RESOURCE MASK ; (SP)+04 -- HARDWARE DEPENDANT DATA - WD. 01 ; (SP)+06 -- HARDWARE DEPENDANT DATA - WD. 00 ; (SP)+10 -- RELATIVE MODULE NUMBER ; (SP)+12 -- GENERIC CODE ; ; OUTPUTS: ; ; C/SET: ONE OR MORE ENTRIES LINKED TO THE RESOURCE WERE ; FOUND. THE LINKED TASK ENTRY FOR EACH SUCH TASK ; IS CONDITIONALLY UPDATED AND THE 'SCHEDULE' FLAG ; IS SET IN THE INTERRUPT LINKAGE LIST. ; ; C/CLEAR: NO TASKS ARE LINKED TO THE RESOURCE ; ; REGISTERS MODIFIED: ; ; R0 - R3 ; ;- .IF DF I$$CIM!I$$CR!I$$CTI&I$$CLK SLINK: ;;; CLR R0 ;;; ASSUME NO LINKED ENTRIES BIT 2(SP),(R3)+ ;;; ANY TASKS LINKED? BEQ 30$ ;;; IF EQ NO 10$: ;;; MOV (R3),R3 ;;; GET NEXT ENTRY BEQ 30$ ;;; IF EQ REACHED END OF LIST BIT 2(SP),ILMSK(R3) ;;; THIS TASK LINKED? BEQ 10$ ;;; IF EQ NO MOV PC,R0 ;;; ASSUME NO LINKED ENTRIES MOV ILTE(R3),R1 ;;; GET ADDRESS OF LINKED TASK ENTRY INC ILRUN(R3) ;;; SET RUN FLAG ADD #LACT,R1 ;;; POINT TO ACTIVITY COUNT TST (R1) ;;; PREVIOUS ENTRY READ BY USER? BNE 20$ ;;; IF NE NO INC (R1)+ ;;; SET COUNT TO +1 MOV SP,R2 ;;; GET STACK ADDRESS ADD #12,R2 ;;; POINT TO GENERIC CODE MOV TMP,(R1)+ ;;; RECORD PHYSICAL UNIT NUMBER MOV (R2),(R1)+ ;;; RECORD GENERIC CODE MOV -(R2),(R1)+ ;;; RECORD RELATIVE MODULE NUMBER MOV -(R2),(R1)+ ;;; SAVE HARDWARE DEPENDANT DATA MOV -(R2),(R1)+ ;;; ... BR 10$ ;;; LOOK FOR ANOTHER LINKED ENTRY 20$: ;;; DEC (R1) ;;; DECREMENT ACTIVATION COUNT BMI 10$ ;;; IF MI ALREADY MISSED AT LEAST ONE DEC (R1) ;;; SET COUNT NEGATIVE BR 10$ ;;; GO AGAIN 30$: ;;; NEG R0 ;;; SET SUCCESS/FAIL FLAG RETURN ;;; .ENDC ;+ ; ; **-STERR-PERFORM ERROR ALARMING FUNCTIONS ; ; THIS SUBROUTINE IS CALLED AT DEVICE PRIORITY TO INITIATE ; PROCESSING FOR ALL TASKS THAT ARE TO BE NOTIFIED WHEN- ; EVER A FATAL CONTROLLER ERROR IS DETECTED. ; ; INPUTS: ; ; R0=ICSR CONTENTS ; R1=PHYSICAL UNIT NUMBER ; R4=ADDRESS OF SCB ; R5=ADDRESS OF ICSR ; ; OUTPUTS: ; ; ALL ICS/ICR INTERRUPTS ARE DISABLED. ERROR DATA IS ; SUPPLIED TO ALL CONNECTED TASKS AND THE ALARMING ; TASK IS FLAGGED FOR SCHEDULING AT FORK LEVEL. ; ; REGISTERS MODIFIED: ; ; R0, R1, R2, R3, AND R5 ;- .IF DF I$$CR STERR: ;;; CLRB S.CTMC(R4) ;;; DISABLE DEVICE TIME-OUTS MOV R1,TMP ;;; SET PHYSICAL UNIT NUMBER MOV #177770,-(SP) ;;; SET GENERIC CODE MOV R1,-(SP) ;;; SET PHYSICAL UNIT NUMBER MOV R0,-(SP) ;;; SET ICSR CONTENTS BIC #22,(R5) ;;; DISABLE ERROR INTERRUPTS MOV -(R5),-(SP) ;;; SAVE ICAR CONTERNTS MOV #-1,-(SP) ;;; SET RESOURCE MASK .IF DF I$$CLK MOV #ICDVT+ICRES,R3 ;;; POINT TO RESOURCE MASK FOR ERRORS CALL SLINK ;;; SET ALARMING TASK FOR SCHEDULING .ENDC .IF DF I$$CIM MOV S.DI(R4),R5 ;;; GET ADDRESS OF DIGITAL INTERRUPT TABLES BEQ 10$ ;;; IF EQ NONE CALL 40$ ;;; ENTER DATA IN CIRCULAR BUFFER .ENDC 10$: ;;; MOV (SP)+,(SP) ;;; COLLAPSE STACK .IF DF I$$CTI MOV S.CT(R4),R5 ;;; GET ADDRESS OF COUNTER TABLES BEQ 20$ ;;; IF EQ NONE CALL 40$ ;;; ENTER DATA IN CIRCULAR BUFFER .ENDC 20$: ;;; MOV S.RTI(R4),R5 ;;; GET ADDRESS OF REMOTE TERMINAL TABLES BEQ 30$ ;;; IF EQ NONE CALL 40$ ;;; ENTER DATA IN CIRCULAR BUFFER 30$: ;;; ADD #10,SP ;;; CLEAN STACK ˆRETURN ;;; 40$: ;;; MOV #-1,R2 ;;; SET FORCED ENTRY FLAG CALLR CENTR ;;; MOVE ENTRY TO CIRCULAR BUFFER .ENDC .END ˆãàkQ ›c, .TITLE DRSED .IDENT /10.21/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 10.21 ; ; D. N. CUTLER 2-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 9-JUL-79 ; MSH040 -- CORRECT BUG READING GROUP GLOBAL EFN'S ; ; M. S. HARVEY 19-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 10-SEP-79 ; MSH061 -- PUT TASK IN WAITFOR USING BIS INSTEAD OF INC. ; ; M. S. HARVEY 25-SEP-79 ; MSH063 -- PRESERVE SEF BIT IF STOP FOR EVENT FLAG ; DIRECTIVE ISSUED AT AST STATE ; ; M. S. HARVEY 30-SEP-79 ; MSH045 -- MOVE SIGNIFICANT EVENT ROUTINES INTO DRSUB ; ; M. S. HARVEY 9-OCT-79 ; MSH069 -- ALLOW TASKS TO STOP FOR GLOBAL EVENT FLAGS ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 22-JUL-80 ; MSH106 -- RECOGNIZE 'READ ALL EVENT FLAGS' DIRECTIVE ; FOR UNMAPPED SYSTEMS WITH GROUP GLOBAL EFNS ; ; M. S. HARVEY 8-JAN-81 ; MSH139 -- MAP STOPFOR DIRECTIVES INTO WAITFOR DIRECTIVES ; IF STOP-BIT SYNCHRONIZATION NOT SUPPORTED ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 6-OCT-81 ; MSH194 -- EXTERNALIZE WAITFOR ROUTINE ; ; SIGNIFICANT EVENT AND EVENT FLAG DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,TCBDF$,PKTDF$ PKTDF$ ;DEFINE EVENT FLAG GROUP OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRCEF-CLEAR EVENT FLAG ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CLEAR AN EVENT FLAG AND ; REPORT ITS POLARITY BEFORE CLEARING. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(31.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF FLAG TO BE CLEARED. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF 'D.RS00' IF THE FLAG WAS ; CLEAR OR 'D.RS22' IF THE FLAG WAS SET. ;- .ENABL LSB $DRCEF::BIT R0,(R1) ;TEST FLAG BEQ 20$ ;IF EQ FLAG IS CLEAR BIC R0,(R1) ;CLEAR FLAG 10$: DRSTS D.RS22 ;SET DIRECTIVE STATUS  ;+ ;**-27 ; **$DRRAF-READ ALL EVENT FLAGS OR READ EXTENDED EVENT FLAGS ; ; THESE DIRECTIVES INSTRUCT THE SYSTEM TO FILL A FOUR (OR SIX) WORD ; BUFFER WITH THE ISSUING TASKS LOCAL, COMMON, AND GROUP GLOBAL ; EVENT FLAGS. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(39.),DPB SIZE(2. OR 3.). ; WD. 01 -- ADDRESS OF A FOUR OR SIX WORD BUFFER. ; ; BUFFER FORMAT (DPB SIZE=2.): ;MSH106 ; ;MSH106 ; WD. 00 -- TASK LOCAL EVENT FLAGS 1-16. ;MSH106 ; WD. 01 -- TASK LOCAL EVENT FLAGS 17-32.  ;MSH106 ; WD. 02 -- COMMON EVENT FLAGS 33-48. ;MSH106 ; WD. 03 -- COMMON EVENT FLAGS 49-64. ;MSH106 ; ;MSH106 ; BUFFER FORMAT (DPB SIZE=3.): ;MSH106 ; ;**-1 ; WD. 00 -- TASK LOCAL EVENT FLAGS 1-16. ; WD. 01 -- TASK LOCAL EVENT FLAGS 17-32. ; WD. 02 -- COMMON EVENT FLAGS 33-48. ; WD. 03 -- COMMON EVENT FLAGS 49-64. ; WD. 04 -- GROUP GLOBAL EVENT FLAGS 65.-80. ; WD. 05 -- GROUP GLOBAL EVENT FLAGS 81.-96. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE BUFFER ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED FOR READ ALL EVENT ; FLAGS. ; DIRECTIVE STATUS OF +1 IS RETURNED FOR READ EXTENDED ; EVENT FLAGS IF THE ISSUING TASKS GROUP GLOBAL ; EVENT FLAGS EXIST. ; DIRECTIVE STATUS OF 'D.RS00' IS RETURNED FOR READ ; EXTENDED EVENT FLAGS IF THE ISSUING TASK'S GROUP ; GLOBAL EVENT FLAGS DO NOT EXIST. IN THIS CASE, ; WORDS 4 AND 5 OF THE BUFFER ARE CLEARED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF BUFFER IS ; OUTSIDE OF ISSUING TASK'S ADDRESS SPACE. ;- $DRRAF:: ; ;MSH106 ;**-2 .IF DF A$$CHK!M$$MGE MOV #4*2,R1 ;SET LENGTH OF BUFFER IN BYTES .IFTF ;MSH106 ;MSH106 .IF DF G$$EFN MOVB -(R3),R4 ;GET DPB SIZE ;MSH106 CMPB (R3)+,#2 ;READ ALL EVENT FLAGS DIRECTIVE? ;MSH106 BEQ 12$ ;IF EQ, YES ;**-2 CMPB #3,R4 ;READ EXTENDED EVENT FLAGS DIRECTIVE? BNE 14$ ;IF NE, NO, INVALID DPB SIZE ;MSH106 .IF DF A$$CHK!M$$MGE ;MSH106 ;MSH106 CMP (R1)+,(R1)+ ;ADD 2 TO SIZE OF BUFFER ;MSH106 .ENDC ;MSH106 ;MSH106 .ENDC ;G$$EFN ;MSH106 ;MSH106 12$: MOV (R3),R3 ;GET ADDRESS OF EVENT FLAG BUFFER ;MSH106 ;**-1 .IFT ;MSH106  ;**-1 CALL $ACHKP ;ADDRESS CHECK PARAMETER BUFFER .ENDC MOV T.EFLG(R5),(R3)+ ;INSERT LOCAL FLAGS 1-16 MOV T.EFLG+2(R5),(R3)+ ;INSERT LOCAL FLAGS 17-32 MOV $COMEF,(R3)+ ;INSERT COMMON FLAGS 33-48 MOV $COMEF+2,(R3)+ ;INSERT COMMON FLAGS 49.-64. .IF DF G$$EFN CMPB #2,R4 ;READ ALL EVENT FLAGS DIRECTIVE? BEQ 13$ ;IF EQ, YES CLR (R3)+ ;CLEAR WORD 4 OF BUFFER CLR (R3) ;CLEAR WORD 5 OF BUFFER MOV $HEADR,R4 ;GET CURRENT TASK HEADER MOVB H.CUIC+1(R4),R4 ;GET TASK'S GROUP NUMBER ;MSH040 CALL $SRGEF ;SEARCH FOR GROUP GLOBAL EVENT FLAGS ;**-1 BCS 20$ ;IF CS, THEY DON'T EXIST MOV G.EFLG+2(R1),(R3) ;MOVE FLAGS 81.-96. TO BUFFER MOV G.EFLG(R1),-(R3) ;MOVE FLAGS 65.-80. TO BUFFER 13$: ;REF LABEL .IFTF ;G$$EFN RETURN ; .IFT ;G$$EFN 14$: DRSTS D.RS99 ;INVALID DPB SIZE .ENDC ;G$$EFN ;+ ; **-$DRSEF-SET EVENT FLAG ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SET AN EVENT FLAG AND ; REPORT IS POLARITY BEFORE SETTING. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(33.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF FLAG TO BE SET. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R3=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF 'D.RS00' IF THE FLAG WAS ; CLEAR OR 'D.RS22' IF THE FLAG WAS SET. ;- $DRSEF::BIT R0,(R1) ;TEST FLAG ;MSH069 BNE 10$ ;IF NE FLAG IS SET ;**-14 BIS R0,(R1) ;SET FLAG 20$: DRSTS D.RS00 ;SET DIRECTIVE STATUS .DSABL LSB ;+ ;**-47 ; **-$DRSTS-STOP FOR SINGLE EVENT FLAG ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO STOP THE ISSUING TASK UNTIL ; A SPECIFIED EVENT FLAG IS SET. ;MSH069 ; ;**-1 ; DPB FORMAT: ; ; WD. 00 -- DIC(135.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF FLAG TO WAITFOR. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THE ISSUING ; TASK IS AT AST STATE. ;-  ;**-3 .ENABL LSB $DRSTS::TST (R2) ;TASK AT AST STATE? ;MSH063 BPL 27$ ;IF PL NO, PUT TASK IN STOPFOR STATE ;MSH063 1$: DRSTS D.RS80 ;ISSUEING TASK AT AST STATE ;MSH063 ;**-16 ;+ ; **-$DRSTL-STOP FOR LOGICAL OR OF EVENT FLAGS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO STOP THE ISSUING TASK UNTIL ; ANY OF THE SPECIFIED EVENT FLAGS IS SET. ;MSH069 ; ;**-1 ; DPB FORMAT: ; ; WD. 00 -- DIC(137.),DPB SIZE(3.). ; WD. 01 -- EVENT FLAG SET INDICATOR. ; WD. 02 -- EVENT FLAG MASK WORD. ; ; EVENT FLAG SETS: ; ; SET 0 -- EVENT FLAGS 1.-16. LOCAL ; SET 1 -- EVENT FLAGS 17.-32. LOCAL ; SET 2 -- EVENT FLAGS 33.-48. GLOBAL ;MSH069 ; SET 3 -- EVENT FLAGS 49.-64. GLOBAL ;MSH069 ; SET 4 -- EVENT FLAGS 65.-80. GROUP GLOBAL ;MSH069 ; SET 5 -- EVENT FLAGS 81.-96. GROUP GLOBAL ;MSH069 ; ;**-4 ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THE ; ISSUING TASK IS AT AST STATE. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN ; ILLEGAL EVENT FLAG SET OR A ZERO EVENT ; FLAG MASK IS SPECIFIED. ;- $DRSTL::TST (R2) ;TASK AT AST STATE? ;MSH063 BMI 1$ ;IF MI YES, CANCEL DIRECTIVE ;MSH063 ;**-7 ;+ ;**-1 ; **-$DRWFL-WAIT FOR LOGICAL OR OF EVENT FLAGS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SUSPEND THE EXECUTION OF THE ; ISSUING TASK UNTIL ANY OF THE SPECIFIED EVENT FLAGS IS SET. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(43.),DPB SIZE(3.). ; WD. 01 -- EVENT FLAG SET INDICATOR. ; WD. 02 -- EVENT FLAG MASK WORD. ; ; EVENT FLAG SETS: ; ; SET 0 -- EVENT FLAGS 1.-16. ; SET 1 -- EVENT FLAGS 17.-32. ; SET 2 -- EVENT FLAGS 33.-48. ; SET 3 -- EVENT FLAGS 49.-64. ; SET 4 -- EVENT FLAGS 65.-80. ; SET 5 -- EVENT FLAGS 81.-96. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN ; ILLEGAL EVENT FLAG SET OR A ZERO EVENT ; FLAG MASK IS SPECIFIED. ;- $DRWFL::MOV (R3)+,R1 ;GET EVENT FLAG SET ;**-1 .IF DF G$$EFN CMP R1,#5 ;LEGAL SET? .IFF ;G$$EFN CMP R1,#3 ;LEGAL SET? .ENDC ;G$$EFN BHI 10$ ;IF HI NO ASL R1 ;CONVERT TO WORD INDEX MOV (R3),R0 ;GET EVENT FLAG MASK WORD BEQ 10$ ;IF EQ NO FLAGS SPECIFIED CMP R1,#3 ;COMMON GLOBAL FLAG SET? BLT 20$ ;IF LT NO .IF DF G$$EFN CMP R1,#7 ;GROUP GLOBAL SET? BLT 5$ ;IF LT NO, COMMON GLOBAL MOV R4,-(SP) ;SAVE REGISTERS MOV R0,-(SP) ; MOV R1,-(SP) ;SAVE EVENT FLAG SET INDEX MOVB H.CUIC+1(R4),R4 ;GET GROUP NUMBER CALL $SRGEF ;SEARCH FOR GROUP GLOBAL EVENT FLAGS BCS 10$ ;IF CS GROUP NOT FOUND ADD (SP)+,R1 ;POINT TO PROPER GROUP GLOBAL EF WORD ADD #G.EFLG-10,R1 ; IN THE GROUP GLOBAL EVENT FLAG BLOCK MOV (SP)+,R0 ;RESTORE REGISTERS MOV (SP)+,R4 ; ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 INCB T.GGF(R5) ;INC GRP GLOBAL USE COUNT FOR TASK ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 CMP -2(R3),#4 ;IN FIRST SIXTEEN GROUP GLOBAL FLAGS? BEQ 3$ ;IF EQ YES ;MSH049 INC G.CNT-(R1) ;INC GROUPS ACCESS COUNT ;MSH049 BR 25$ ;JOIN COMMON CODE ;MSH049 3$: INC G.CNT-G.EFLG(R1) ;INC GROUPS ACCESS COUNT ;MSH049 BR 25$ ;JOIN COMMON CODE ;MSH049 5$: ;REF LABEL ;**-2 .ENDC ;G$$EFN ADD #$COMEF-4,R1 ;POINT TO PROPER COMMON FLAG WORD BR 25$ ;FINISH UP AS IF SINGLE FLAG ;MSH049 10$: DRSTS D.RS97 ;SET DIRECTIVE STATUS ;**-1 20$: ADD R5,R1 ;ADD ADDRESS OF TASK TCB ADD #T.EFLG,R1 ;POINT TO PROPER TASK FLAGS WORD 25$: ; ;MSH069 ;MSH069 .IF DF S$$TOP ;MSH069 ;MSH069 CMPB #137.,$DICSV ;STOP FOR LOGICAL 'OR' DIRECTIVE? ;MSH069 BNE 50$ ;IF NE NO, DON'T STOP TASK ;MSH069 ;MSH069 .IFTF ;MSH069 ;MSH069 27$: ;REF LABEL ;MSH069 ;MSH069 .IFT ;MSH069 ;MSH069 BIS #T2.SEF,(R2) ;PUT TASK IN STOPFOR STATE ;MSH069 ;MSH069 .ENDC ;S$$TOP ;MSH069 ;+ ; **-$DRWFD-WAITFOR SINGLE EVENT FLAG FOR DIRECTIVE ;MSH194 ; **-$DRWFS-WAITFOR SINGLE EVENT FLAG (NON-EXEC COMMON SYSTEM ONLY) ;MSH194 ; ;**-1 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SUSPEND THE EXECUTION OF THE ; ISSUING TASK UNTIL A SPECIFIED EVENT FLAG IS SET. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(41.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF FLAG TO WAITFOR. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ;- $DRWFD:: ;REF LABEL ;MSH194 ;MSH194 .IF DF M$$NET ;MSH194 .IF NDF D$$PAR ;MSH194 ;MSH194 $DRWFS:: ;REF LABEL  ;MSH194 .ENDC ;MSH194 .ENDC ;MSH194 .IF DF G$$EFN BIC #1,R1 ;CLR GRP GLOBAL 2ND WORD INDICATOR ;MSH049 ;**-7 .ENDC ;G$$EFN 50$: BIS #T2.WFR,T.ST2(R5) ;PUT TASK IN WAIT FOR STATE ;MSH061 ;MSH069 .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 MOV R0,T.EFLM(R5) ;SET WAITFOR MASK ;MSH069 MOV R1,T.EFLM+2(R5) ;SET WAITFOR MASK ADDRESS ;MSH069 ;MSH069 .IFF ;MSH069 ;MSH069 MOV R0,H.EFLM(R4) ;SET WAITFOR MASK WORD ´ ;**-1 MOV R1,H.EFLM+2(R4) ;SET WAITFOR MASK ADDRESS ;MSH069 .ENDC ;MSH069 ;MSH069 CALLR $SETRT ;SET A SCHEDULE REQUEST .DSABLE LSB .END ´”.ðskQ ›c, .TITLE GRDRV .IDENT /03.02/ ; ; COPYRIGHT (C) 1976, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VT11/VS60 DISPLAY PROCESSOR DRIVER ; ; VERSION 01 ; ; NOTE: THIS IS A SINGLE CONTROLLER DRIVER ; ; WRITTEN BY HANK MAURER 13-JUL-75 ; ; PREVIOUSLY MODIFIED BY: ; ; E. L. BAATZ ; H. MAURER ; ; MODIFIED BY: ; ; HANK MAURER 11-JUN-78 ; HM002 -- CORRECT DPUERR MACRO ; ; HANK MAURER 11-JUN-78 ; HM003 -- MOVE TRACKING CROSS ONLY WHEN TIP SWITCH IS ON ; ; ERIC BAATZ 20-JAN-79 ; EB189 -- SET PS.NSF WHEN CONNECTING ; ;**NEW** ; EQUATED SYMBOLS ; DNR=20 ;DPU NAME REGISTER DOS=36 ;DPU OFFSET SIGN REGISTER BFHDR=52. ;DISPLAY BUFFER HEADER SIZE NAMSIZ=18. ;NAME LIST SIZE DPC=172000 ;DPU PROGRAM COUNTER ADDRESS DSR=2 ;DPU STATUS REGISTER DRB=10 ;DPU RELOCATION REGISTER DSRX=12 ;DPU EXTENDED STATUS REGISTER DST=26 ;DPU STACK READ REGISTER DSP=32 ;DPU STACK POINTER DCS=22 ;DPU CONSOLE STATUS REGISTER DJSR=173400 ;DPU JSR INSTRUCTION DJMPA=160000 ;DPU JMP INSTRUCTION DJMP=173500 ;DPU JMP RELATIVE INSTRUCTION DHALT=173400 ;DPU HALT AND INTERRUPT LSRA=170000 ;DPU LOAD STATUS REGISTER A LPINT=200 ;DPU INTENSIFY LP HITS NOITAL=40 ;DPU NON-ITALICS LINE0=4 ;DPU SOLID LINE TYPE EXTSTP=200 ;DPU EXTERNAL STOP BIT (VS60) LVECT=110000 ;DPU LONG VECTOR INSTRUCTION NBLINK=20 ;DPU BLINK OFF MINUS=20000 ;DPU LONG VECTOR SIGN BIT POINT=114000 ;DPU ABSOLUTE POINT INSTRUCTION LPOFF=100 ;DPU LIGHT PEN INTERRUPT OFF BLINK=30 ;DPU BLINK ON INT3=2600 ;DPU INTENSITY LEVEL 3 CHAR=100000 ;DPU CHARACTER MODE NOMENU=2 ;DPU MENU OFF OFFSET=10000 ;DPU SET OFFSET MODE BIT S1=164000 ;DPU SELECT SCOPE 1 S2=164400 ;DPU SELECT SCOPE 2 SON=300 ;DPU TURN SCOPE ON (INTENSIFY) SOFF=200 ;DPU TYURN SCOPE OFF TIPION=14 ;DPU TURN ON TIP SWITCH INTERRUPTS LPIOFF=40 ;DPU TURN LIGHT PEN INTERRUPTS OFF LSRC=154000 ;DPU LOAD STATUS REGISTER C CROFF=1000 ;DPU TURN CHARACTER ROTATE OFF CSNORM=240 ;DPU CHARACTER SCALE NORMAL VSNORM=24 ;DPU VECTOR SCALE NORMAL SRESET=40 ;DPU STACK POINTER RESET LP0=40000 ;DPU LIGHT PEN INTERRUPT FOR SCOPE 1 TON0=20000 ;DPU TIP SWITCH ON FOR SCOPE 1 TOFF0=10000 ;DPU TIP SWITCH OFF FOR SCOPE 1 LP1=400 ;DPU LIGHT PEN INTERRUPT FOR SCOPE 2 TON1=200 ;DPU TIP SWITCH ON FOR SCOPE 2 TOFF1=100 ;DPU TIP SWITCH OFF FOR SCOPE 2  ; ; LOCAL DATA *** WARNING *** THE ORDER OF THE LOCAL DATA IS FIXED ; .IF DF V$$S60 GR.PC: .WORD 0 ;DPU PROGRAM COUNTER ADDRESS LOCAL: ;REFERENCE TAG BUFST: .WORD 0 ;DISPLAY BUFFER .IF DF M$$MGE BUFRB: .WORD 0 ;DISPLAY BUFFER RELOCATION BIAS BUFDB: .WORD 0 ;DISPLAY BUFFER DIB TASRB: .WORD 0 ;EQUIVALENT TASK RELOCATION BIAS DPCFIX: .WORD 0 ;LOW 16 BITS OF PHYSICAL TASK ORIGIN ; (FOR FUDGING DPC ON LP) .ENDC .IFF GRSTK: .BLKW 16. ;DPU JSR STACK  .IF DF M$$MGE TASK0: .WORD 0 ;PHYSICAL ADDRESS OF USER VIRTUAL 0 ; (FOR RELOCATION) .IFTF GR.PC: .WORD 0 ;DPU PROGRAM COUNTER GR.SP: .WORD GRSTK ;DPU STACK POINTER LOCAL: ;REFERENCE TAG .IFT BUFRB: .WORD 0 ;RELOCATION BIAS FOR DISPLAY BUFFER .IFTF BUFST: .WORD 0 ;PHYSICAL ADDRESS OF DISPLAY BUFFER BUFSZ: .WORD 0 ;SIZE OF DISPLAY BUFFER IN BYTES .IFT BUFDB: .WORD 0 ;DISPLAY BUFFER DIB (FOR SAR6) .ENDC .IFTF ; DF V$$S60 .IF DF A$$TRP LPAST: .WORD 0 ;LIGHT PEN AST VIRTUAL ADDRESS .ENDC EFNAD: .WORD 0 ;EVENT FLAG ADDRESS WORD EFNMK: .WORD 0 ;EVENT FLAG MASK WORD (FOR LP HITS) CONTK: .WORD 0 ;TCB ADDRESS OF CONNECTED TASK FRKIP: .WORD 0 ;LP FORK IN PROGRESS TIP1: .WORD 0 ;TIP SWITCH 1 STATUS .IF DF V$$S2S TIP2: .WORD 0 ;TIP SWITCH 2 STATUS LPFLAG: .WORD 0 ;SCOPE 1 OR 2 FLAG ON LP HIT .ENDC HLTFLG: .WORD 100001 ;LEAVE DPU HALTED FLAG ; ; DELAY IN CASE THE USER'S DISPLAY LIST IS VERY SHORT ; DELAY: .WORD POINT+LPOFF+NBLINK+INT3+LINE0 .IFT ; DF V$$S60 .WORD OFFSET,0 .IFTF .WORD 1023.,1023. .WORD LVECT .WORD MINUS+1023.,MINUS+1023. .IFT .WORD 1023.,1023.,MINUS+1023.,MINUS+1023. .WORD 1023.,1023.,MINUS+1023.,MINUS+1023. .WORD 1023.,1023.,MINUS+1023.,MINUS+1023. .IFTF .WORD CHAR .BYTE 17,17 .WORD LSRA+LPINT+NOITAL+NOMENU .IFT .WORD S1+SON+LPIOFF+TIPION .WORD S2+SOFF+LPIOFF+TIPION .WORD LSRC+CROFF+CSNORM+VSNORM .IF DF M$$MGE DSTART: .WORD DHALT,0 .IFF DSTART: DJMPA,0 .ENDC .IFF DSTART: .WORD DJMPA,0 .ENDC ; DF V$$S60 ; ; COUNT LIGHT PEN INTERRUPTS THAT ARE NOT LIGHT PEN INTERRUPTS ; LPERRS: .WORD 0 ; ; ; DRIVER DISPATCH TABLE ; $GRTBL::.WORD GRCHK ;DEVICE INITIATOR ENTRY POINT .WORD GRCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD GROUT ;DEVICE TIMEOUT ENTRY POINT .WORD GRPWF ;POWERFAIL ENTRY POINT ; ; MACRO DEFINITIONS ; .MACRO DPUERR TEXT,?X MOV #X,DSTART+2 BR 90$ X: .WORD CHAR .ASCII "TEXT" .EVEN .WORD DJMPA,DELAY .ENDM ;+ ; **-GRCHK-VT11/VS60 DISPLAY PROCESSOR PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS RECEIVED FOR THE VT11/VS60 DISPLAY PROCESSOR. ; VT11/VS60 I/O REQUESTS CONTAIN DEVICE DEPENDENT INFORMA- ; ATION THAT MUST BE CHECKED IN THE CONTEXT OF THE ISSUING TASK. ; THEREFORE THE I/O REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; DEPENDENT UPON FUNCTION TO BE PERFORMED. ; ; VT11/VS60 FUNCTION INDEPENDENT I/O PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE . ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ;- GRCHK: MOV R1,-(SP) ;SAVE I/O PACKET ADDRESS MOV I.FCN(R1),R2 ;GET I/O FUNCTION CODE MOV I.PRM(R1),R0 ;GET VIRTUAL BUFFER ADDRESS (IF IO.CON) MOV I.TCB(R1),R1 ;GET REQUESTING TASK'S TCB ADDRESS CMP R2,#IO.CON ;CONNECT ? BEQ GRCON ;YES CMP R1,CONTK ;IS THE REQUESTING TASK CONNECTED ? BNE GRNCN ;NO, IT CAN'T REQUEST THINGS CMP R2,#IO.STP ;STOP ? BEQ GRSTP ;YES CMP R2,#IO.DIS ;DISCONNECT ? BEQ GRDIS ;YES BR GRCNT ;NO, CONTINUE ;+ ; **-GRSTP-STOP VT11/VS60 (SO USER CAN MODIFY HIS DISPLAY BUFFER) ; ; FUNCTION DEPENDENT IO PACKET FORMAT: ; ; WD. 12 -- NOT USED ; WD. 13 -- NOT USED ; WD. 14 -- NOT USED ; WD. 15 -- NOT USED ; WD. 16 -- NOT USED ; WD. 17 -- NOT USED ; WD. 20 -- NOT USED ;- GRSTP: CALL GRHLT  ;HALT DPU BR GRSUC ;TAKE COMMON SUCCESS EXIT ;+ ; **-GRCON-CONNECT DISPLAY BUFFER TO DRIVER ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- USER VIRTUAL ADDRESS OF DISPLAY BUFFER. ; WD. 13 -- SIZE OF DISPLAY BUFFER IN BYTES. ; WD. 14 -- LIGHT PEN HIT TRIGGER EVENT FLAG. ; WD. 15 -- LIGHT PEN AST ADDRESS. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- GRCON: TST CONTK ;ANOTHER TASK ALREADY CONNECTED? BNE GRNCN ;IF NE YES MOV #LOCAL,R3 ;SET UP POINTER TO LOCAL DATA BASE BIT #1,R0 ;IS VIRTUAL BUFFER ADDRESS ODD ? BNE GRSPC ;YES, ILLEGAL .IF DF V$$S60 MOV R0,(R3)+ ;SAVE BUFFER ADDRESS .IF DF M$$MGE CALL $RELOC ;MAP BUFFER ADDRESS MOV R1,(R3)+ ;SAVE RELOCATION BIAS MOV R2,(R3)+ ;AND DIB ASR R0 ;GET RB OF BUFFER VIRTUAL ADDRESS ASR R0 ASR R0 ASR R0 ASR R0 ASR R0 BIC #176000,R0 ;CLEAN IT OFF SUB R0,R1 ;GET EQUIVALENT RB OF TASK 0 MOV R1,(R3)+ ;AND SAVE IT ASL R1 ;GET LOW 16 BITS OF PHYSICAL ASL R1 ; START OF TASK ADDRESS ASL R1 ASL R1 ASL R1 ASL R1 MOV R1,(R3)+ ;SAVE IT .IFF MOV R0,DSTART+2 ;PUT BUFFER ADDRESS INTO STARTER ADD #BFHDR,DSTART+2 ;SKIPPING HEADER .ENDC MOV (SP),R1 ;RESTORE PACKET POINTER ADD #I.PRM+4,R1 ;POINT TO LIGHT PEN EFN PARAMETER .IFF .IF DF M$$MGE CALL $RELOC ;MAP BUFFER ADDRESS MOV R1,(R3)+ ;SAVE RELOCATION BIAS MOV R2,R4 ;SAVE DIB FOR BUFFER CALL $MPPHY ;MAP INTO PHYSICAL ADDRESS (2 WORDS) MOV R2,(R3) ;SAVE LOW 16 BITS OF PHYSICAL ADDRESS MOV (R3)+,DSTART+2 ;PHYSICAL BUFFER ADDRESS TO STARTER ADD #BFHDR,DSTART+2 ;SKIPPING HEADER SUB R2,R0 ;VIRTUAL-PHYSICAL BUFFER ADDRESS NEG R0 ;PHYSICAL-VIRTUAL (TO RELOCATE DJSR, DJMP) MOV R0,TASK0 ;SAVE IT TST R1 ;ANY HIGH ORDER PHYSICAL ADDR. BITS ? BNE GRSPC ;YES, BUFFER OUT OF 32K .IFF MOV R0,(R3)+ ;SAVE BUFFER ADDRESS MOV R0,DSTART+2 ;PHYSICAL ADDRESS TO STARTER ADD #BFHDR,DSTART+2 ;SKIPPING HEADER .IFTF MOV (SP),R1 ;RESTORE PACKET POINTER ADD #I.PRM+2,R1 ;POINT TO BUFFER SIZE PARAMETER .IFT MOV (R1)+,(R3) ;SAVE SIZE ADD (R3)+,R2 ;GET ADDRESS OF BUFFER END BCS GRSPC ;END IS OUT OF 32K CMP R2,#160000 ;ABOVE 28K ? BHIS GRSPC ;YES, ERROR MOV R4,(R3)+ ;SAVE DIB FOR BUFFER START (SAR6) .IFF MOV (R1)+,(R3)+ ;SAVE SIZE .ENDC .ENDC ; DF V$$S60 MOV (R1)+,R0 ;GET LP TRIGGER EFN BEQ GRIEF ;ZERO IS ILLEGAL CMP R0,#64. ;CHECK AGAINST MAX BGT GRIEF ;>64 IS ILLEGAL MOV R5,-(SP) ;SAVE UCB ADDRESS .IF DF A$$TRP MOV (R1),(R3)+ ;SAVE AST ADDRESS .ENDC MOV I.TCB-I.PRM-6(R1),R5 ;GET CONNECTING TASK'S TCB ADDRESS CALL $CEFI ;CONVERT EFN TO MASK AND POINTER MOV R1,(R3)+ ;SAVE EFN ADDRESS MOV R0,(R3)+ ;SAVE EFN MASK BIC R0,(R1) ;CLEAR THE USER'S EVENT FLAG INCB T.IOC(R5) ;INCREMENT IO PENDING COUNT MOV R5,(R3) ;CONNECT TASK TO DRIVER MOV T.PCB(R5),R5 ;GET TASK'S PCB ADDRESS BIS #PS.NSF,P.STAT(R5) ;DISABLE SHUFFLING MOV (SP)+,R5 ;RESTORE UCB ADDRESS ;+ ; **-GRCNT-CONTINUE AFTER STOP ; ; FUNCTION DEPENDENT IO PACKET FORMAT: ; ; WD. 12 -- NOT USED. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- GRCNT: TST HLTFLG ;IS DISPLAY RUNNING ? BEQ GRSUC ;YES .IF DF V$$S60 MOV GR.PC,R0 ;GET DPU PC ADDRESS MOV #SRESET,DSP(R0) ;RESET DPU STACK .IF DF M$$MGE CLR DRB(R0) ;CLEAR RELOCATION BIAS .ENDC CLR HLTFLG ;CLEAR HALT FLAG MOV #DELAY,(R0) ;START UP THE DISPLAY .IFF MOV #GRSTK,GR.SP ;RESET DPU STACK CLR HLTFLG ;CLEAR HALT FLAG MOV #DELAY,@GR.PC ;START UP THE DISPLAY .ENDC BR GRSUC ;TAKE COMMON EXIT ;+ ; **-GRDIS-DISCONNECT TASK FROM DRIVER ; ; FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- NOT USED. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- GRDIS: CALL GRCAN ;DISCONNECT TASK FROM DRIVER BR GRSUC ;TAKE COMMON EXIT ; ; EXITS FROM VT11/VS60 DRIVER ; ; ; ILLEGAL CONNECT/DISCONNECT TO/FROM DRIVER ; GRNCN: MOV #IE.CNR&377,R0 ;SET CONNECT REFUSED STATUS BR GRCMN ;BUT DON'T DISTURB THE DISPLAY ; ; ILLEGAL EVENT FLAG NUMBER ; GRIEF: MOV #IE.IEF&377,R0 ;SET ILLEGAL EVENT FLAG STATUS BR GRCMN ; ; ; ILLEGAL BUFFER SPECIFICATION ; GRSPC: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS BR GRCMN ;TAKE COMMON EXIT ; ; SUCCESSFUL COMPLETION ; GRSUC: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS ; ; COMMON FUNCTION EXIT ; GRCMN: CLR R1 ;CLEAR SECOND I/O STATUS WORD MOV (SP)+,R3 ;RETRIEVE I/O PACKET ADDRESS CALLR $IOFIN ;FINISH I/O OPERATION ; ; CANCEL I/O OPERATION ; ; THIS ROUTINE IS CALLED TO CANCEL ALL I/O IN PROGRESS FOR THE CURRENT ; TASK. IF THE TASK IS CONNECTED TO THE DRIVER, IT WILL BE ; DISCONNECTED AND THE DPU WILL BE SET TO THE IDLE DISPLAY. ; ; INPUTS: ; ; R1=ADDRESS OF TCB OF CURRENT TASK ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ; GRCAN: MOV #CONTK,R2 ;;;POINT AT LOCAL DATA CMP R1,(R2) ;;;IS THIS THE CONNECTED TASK ? BNE GROUT ;;;NO, DON'T DO ANYTHING CLR (R2) ;;;YES, DISCONNECT IT CLR -(R2) ;;;CLEAR EFN MASK CLR -(R2) ;;;AND ADDRESS IN CASE FORK ALREADY QUEUED .IF DF A$$TRP CLR -(R2) ;;;AND AST ADDRESS .ENDC DECB T.IOC(R1) ;;;DECREMENT OUTSTANDING I/O COUNT MOV T.PCB(R1),R3 ;;;GET TASK'S PCB ADDRESS BIC #PS.NSF,P.STAT(R3) ;;;ENABLE SHUFFLING MTPS #0 ;;;ALLOW DEVICE INTERRUPTS ; ; SUBROUTINE TO HALT DPU ; ; INPUTS: ; ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ; GRHLT: MOV #HLTFLG,R3 ;;;OFT USED TST (R3) ;;;ALREADY HALTED ? BNE 30$ ;;;YES MOV #1,(R3) ;;;SET THE 'PLEASE HALT' INDICATOR 5$: MOV #1000.,-(SP) ;;;PUSH DELAY COUNTER MOV (SP),-(SP) ;;;TWICE 10$: TST (R3) ;;;HALTED YET ? BMI 20$ ;;;YES, EXIT DEC (SP) ;;;INNER COUNTER BGT 10$ ;;;INNER LOOP MOV 2(SP),(SP) ;;;RESTORE INNER COUNTER DEC 2(SP) ;;;OUTER COUNTER BGT 10$ ;;;OUTER LOOP CMP (SP)+,(SP)+ ;;;PURGE DEPLETED COUNTERS .IF DF V$$S60 MOV GR.PC,R2 ;;;GET DPC ADDRESS BIS #EXTSTP,DSRX(R2);;;DO AN EXTERNAL STOP .IFF MOV #DELAY,@GR.PC ;;;FORCE DPC AND TRY AGAIN .ENDC BR 5$ ;;;TRY AGAIN 20$: CMP (SP)+,(SP)+ ;;;PURGE COUNTERS 30$: RETURN ; ; POWERFAILURE ; ; ; POWERFAILURE MERELY CAUSES THE DPU TO BE RESTARTED AT THE START OF ; THE DISPLAY BUFFER WITH THE DPU STACK RESET. ; ; INPUTS: ; ; R3=ADDRESS OF CONTROLLER INDEX (ALWAYS ZERO) ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ; GRPWF: MOV S.CSR(R4),R2 ;;;GET VT11/VS60 DPC ADDRESS MOV R2,GR.PC ;;;SAVE DPC ADDRESS .IF DF V$$S60 MOV #SRESET,DSP(R2) ;;;RESET THE DPU STACK CLR DRB(R2) ;;;CLEAR THE DPU RB .IFF MOV #GRSTK,GR.SP ;;;SET UP THE STACK POINTER .ENDC TST HLTFLG ;;;SHOULD DISPLAY REMAIN HALTED ? BNE GROUT ;;;YES MOV #DELAY,(R2) ;;;NO, START IT UP ; ; DEVICE TIMEOUT ; ; DEVICE TIMEOUT CANNOT OCCUR SINCE THE TIMEOUT COUNT IS NEVER SET. ; GROUT: RETURN ;;; ; ; BUS-ERROR / SHIFT-OUT INTERRUPT ; ; A BUS ERROR OCCURS WHEN THE DPU ATTEMPTS TO EXECUTE DISPLAY ; INSTRUCTIONS FROM NON-EXISTENT MEMORY. A SHIFT OUT INTERRUPT OCCURS ; WHEN A CHARACTER >40(8) IS ENCOUNTERED WHILE IN THE SHIFT OUT MODE. ; IN EITHER CASE, MERELY RESTART THE DPU AT THE BEGINNING OF THE BUFFER ; .IF DF V$$S60 $GRBSE:: .ENDC ; ; DPU STOP INTERRUPT ; ; THE DPU STOP INTERRUPT OCCURS IN THE VT11 ON EITHER A DJSR, DJMP, ; OR DRET PSEUDO INSTRUCTION. IN EACH CASE THE INTERRUPT HANDLER ; PERFORMS THE NECESSARY FUNCTIONS. FOR THE VS60, IT OCCURS ONLY ; AT THE END OF THE DELAY LIST AND AT THE END OF THE DISPLAY LIST ; $GRSTP::CALL $INTSV,PR4 ;;;START INTERRUPT ROUTINE .IF DF V$$S60 MOV GR.PC,R4 ;;;GET THE DPC ADDRESS .IF DF M$$MGE TST DRB(R4) ;;;END OF DELAY OR LIST ? BNE 10$ ;;;END OF MAIN LIST MOV #SRESET,DSP(R4) ;;;RESET DPU STACK MOV TASRB,DRB(R4) ;;;GET EQUIVALENT RB FOR MAIN LIST MOV BUFST,R5 ;;;ADDRESS OF USER'S SPACE ADD #BFHDR,R5 ;;;PLUS HEADER SIZE MOV R5,(R4) ;;;START IN USER'S LIST RETURN ;;;EXIT FROM INTERRUPT 10$: CLR DRB(R4) ;;;CLEAR DPU RB TST HLTFLG ;;;SHOULD WE REMAIN HALTED ? BEQ 20$ ;;;NO BIS #100000,HLTFLG ;;;YES, SET INDICATOR THAT WE SUCCEEDED RETURN ;;;EXIT FROM INTERRUPT 20$: MOV #DELAY,(R4) ;;;START DPU IN DELAY LIST RETURN ;;;EXIT FROM INTERRUPT .IFF MOV #SRESET,DSP(R4) ;;;RESET DPU STACK TST HLTFLG ;;;REMAIN HALTED ? BEQ 20$ ;;;NO BIS #100000,HLTFLG ;;;YES, SET SUCCESS BIT RETURN ;;;EXIT FROM INTERRUPT 20$: MOV #DELAY,(R4) ;;;RESTART IN DELAY LIST RETURN ;;;EXIT FROM INTERRUPT .ENDC .IFF ;;; DF V$$S60 MOV R2,-(SP) ;;;SAVE ADDITIONAL REGISTERS MOV R3,-(SP) MOV #GR.PC,R4 ;;;POINT AT LOCAL DATA BASE MOV (R4)+,R2 ;;;GET DPC ADDRESS MOV (R4)+,R3 ;;;GET DPU STACK POINTER .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE SAR6 MOV (R4)+,KISAR6 ;;;AND SET UP FOR USER'S BUFFER .IFTF MOV (R2),R5 ;;;GET PHYSICAL ADDRESS OF DHALT +2 SUB (R4)+,R5 ;;;SUBTRACT PHYSICAL START OF BUFFER BCS 70$ ;;;UNDER BUFFER CMP (R4)+,R5 ;;;COMPARE WITH MAX BUFFER SIZE BLO 70$ ;;;ABOVE BUFFER .IFT ADD (R4)+,R5 ;;;ADD DIB 10$: CMP R5,#157700 ;;;AT THE END OF THE SAR ? BLOS 15$ ;;;NO, WE'RE IN RANGE SUB #17700,R5 ;;;MOVE IT UP BY ABOUT 4000. WDS ADD #177,KISAR6 ;;;AND ALSO FIX THE RB BR 10$ ;;;TEST AGAIN 15$: .IFF MOV (R2),R5 ;;;RESTORE ADDRESS OF DHALT+2 .IFTF MOV -2(R5),R4 ;;;GET PSEUDO INSTRUCTION BIC #13,R4 ;;;IGNORE SPARE BITS CMP R4,#DJSR ;;;DJSR ? BNE 80$ ;;;NO MOV (R5)+,R4 ;;;GET RETURN ADDRESS BEQ 40$ ;;;0 MEANS DRET CMP #GRSTK+32.,R3 ;;;FULL STACK ? BLOS 50$ ;;;YES MOV (R2),(R3)+ ;;;PUSH PHYSICAL ADDR OF DHALT+2 ;;; FOR LP STUFF MOV R4,(R3)+ ;;;PUSH VIRTUAL RETURN ADDRESS MOV (R5)+,R4 ;;;GET SUBPICTURE VIRTUAL ADDRESS 17$: .IFT ADD TASK0,R4 ;;;MAKE ADDRESS PHYSICAL .IFTF MOV R4,(R2) ;;;JUMP TO ADDRESS AND RESTART DPU 20$:  .IFT MOV (SP)+,KISAR6 ;;;RESTORE MAPPING .ENDC ;;; DF M$$MGE MOV R3,GR.SP ;;;SAVE DPU STACK POINTER MOV (SP)+,R3 ;;;RESTORE REGS MOV (SP)+,R2 ;;; RETURN ;;;EXIT FROM INTERRUPT 40$: CMP R3,#GRSTK ;;;STACK EMPTY ? BLOS 90$ ;;;YES, RESTART AT THE TOP MOV -(R3),R4 ;;;GET VIRTUAL RETURN ADDRESS TST -(R3) ;;;WASTE PHYSICAL ADDR OF DHALT+2 BR 17$ ;;;GO RELOCATE IT AND RESTART THERE 50$: DPUERR 70$: DPUERR 80$: CMP R4,#DJMP ;;;IS IT A RELATIVE DJMP ? BNE 90$ ;;;NO, UNKNOWN DHALT MOV (R5),R4 ;;;GET ADDRESS BR 17$ ;;;GO RELOCATE IT AND RESTART THERE 90$: MOV #GRSTK,R3 ;;;UNRECOGNIZED DHALT, RESET STACK TST HLTFLG ;;;REMAIN HALTED ? BEQ 100$ ;;;NO BIS #100000,HLTFLG ;;;SET SUCCESS BIT BR 20$ ;;;EXIT 100$: MOV #DELAY,(R2) ;;;RESTART DISPLAY AT THE BEGINNING BR 20$ .ENDC ;;; DF V$$S60 .ENABL LSB 60$: ;;;REF LABEL .IF DF M$$MGE MOV (SP)+,KISAR6 ;;;RESTORE MAPPING  .ENDC 65$: INC (R5) ;;;RESTART DPU 66$: RETURN ;;;EXIT 67$: INC LPERRS ;;;COUNT UNKNOWN INTERRUPTS BR 65$ ;;; ; ; LIGHT PEN INTERRUPT ; ; THE LIGHT PEN SERVICE ROUTINE STORES THE STATUS OF THE DPU AT THE ; LIGHT PEN HIT INTO THE USER'S DISPLAY BUFFER HEADER, SETS THE LIGHT ; PEN TRIGGER EVENT FLAG, AND INITIATES THE AST. ; $GRLPI::CALL $INTSV,PR4 ;;;START INTERRUPT CODE MOV GR.PC,R5 ;;;GET DPC ADDRESS .IF DF V$$S60 MOV DCS(R5),R4 ;;;GET THE CONSOLE STATUS REG BIT #TON0,R4 ;;;TIP SWITCH FOR SCOPE 1 ON ? BEQ 10$ ;;;NO INC TIP1 ;;;YES, SET FLAG BR 65$ ;;;EXIT 10$: BIT #TOFF0,R4 ;;;TIP SWITCH FOR SCOPE 1 OFF ? BEQ 15$ ;;;NO CLR TIP1 ;;;YES, CLEAR FLAG BR 65$ ;;;EXIT 15$: .IF DF V$$S2S BIT #TON1,R4 ;;;TIP SWITCH FOR SCOPE 2 ON ? BEQ 20$ ;;;NO INC TIP2 ;;;YES SET FLAG BR 65$ ;;;EXIT 20$: BIT #TOFF1,R4 ;;;TIP SWITCH FOR SCOPE 2 OFF ? BEQ 25$ ;;;NO CLR TIP2 ;;;YES, CLEAR FLAG BR 65$ ;;;EXIT 25$: BIT #LP0+LP1,R4 ;;;LIGHT PEN INTERRUPT ? BEQ 67$ ;;;NO, WHAT INTERRUPT ? MOV #1,LPFLAG ;;;YES, SET FLAG BIT #LP1,R4 ;;;WAS IT SCOPE 2 BEQ 30$ ;;;NO, MUST HAVE BEEN 1 INC LPFLAG ;;;YES, SET FLAG TO 2 30$: .IFF BIT #LP0,R4 ;;;LP INTERRUPT ? BEQ 67$ ;;;NO, WHAT INTERRUPT ? .ENDC .ENDC ;;; DF V$$S60 TST FRKIP ;;;FORK CURRENTLY IN PROGRESS ? BNE 65$ ;;;YES, FORGET INTERRUPT .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE SAR6 MOV BUFRB,KISAR6 ;;;SETUP SAR FOR BUFFER MOV BUFDB,R4 ;;;ALSO DIB .IFF MOV BUFST,R4 ;;;GET ADDRESS OF LP STUFF .IFTF TST (R4)+ ;;;IS THE LOCK SET ? BNE 60$ ;;;YES, DON'T CHANGE INFO WHILE ITS BEING READ MOV R4,-(SP) ;;;SAVE NAME LIST ADDRESS ADD #NAMSIZ,R4 ;;;SKIP OVER IT FOR NOW .IF DF V$$S60 .IF DF M$$MGE MOV (R5)+,(R4) ;;;PUT IN DPC AT HIT SUB DPCFIX,(R4)+ ;;;SUBTRACT LOW BITS OF RELOCATION VALUE .IFF MOV (R5)+,(R4)+ ;;;PUT IN DPC AT HIT .ENDC MOV (R5)+,(R4)+ ;;;PUT IN CSR AT HIT MOV (R5)+,(R4)+ ;;;PUT IN X POS AT HIT MOV (R5)+,(R4)+ ;;;PUT IN Y POS AT HIT TST (R5)+ ;;;SKIP DPU RB MOV (R5)+,(R4)+ ;;;COPY EXTENDED STATUS MOV (R5)+,(R4)+ ;;;X OFFSET MOV (R5)+,(R4)+ ;;;Y OFFSET MOV DOS-DNR(R5),(R4)+ ;;;OFFSET SIGNS .IFF .IF DF M$$MGE MOV (R5)+,(R4) ;;;RETRIEVE DPC AT HIT SUB TASK0,(R4)+ ;;;CONVERT TO PHYSICAL AND STORE .IFF MOV (R5)+,(R4)+ ;;;PUT IN DPC AT HIT .ENDC MOV (R5)+,(R4)+ ;;;PUT IN CSR AT HIT MOV (R5)+,(R4)+ ;;;PUT IN X POS AT HIT MOV (R5)+,(R4)+ ;;;PUT IN Y POS AT HIT CLR (R4)+ ;;;NO EXTENDED STATUS FOR VT11 CLR (R4)+ ;;;ALSO NO X OFFSET CLR (R4)+ ;;;ALSO NO Y OFFSET CLR (R4)+ ;;;ALSO NO XY OFFSET SIGNS .IFTF MOV TIP1,(R4)+ ;;;COPY TIP SWITCH 1 STATUS .IF NDF V$$S2S CLR (R4)+ ;;;NO TIP SWITCH 2 MOV #1,(R4) ;;;SET LP FLAG .IFF MOV TIP2,(R4)+ ;;;COPY TIP SWITCH 2 MOV LPFLAG,(R4) ;;;COPY IN LP FLAG .ENDC MOV (SP),R4 ;;;RESTORE NAME LIST ADDRESS MOV R3,(SP) ;;;SAVE R3 .IFT ;;; DF V$$S60 MOV DSP-DNR(R5),R3 ;;;GET CURRENT STACK POINTER BIC #177703,R3 ;;;ISOLATE WORD SELECT BITS MOV R3,-(SP) ;;;SAVE 'EM 40$: CMP R3,#SRESET ;;;TOP OF STACK ? BHIS 45$ ;;;YES MOV R3,DSP-DNR(R5) ;;;NO, SELECT THIS LEVEL MOV DST-DNR(R5),(R4)+ ;;;COPY DPC FOR THIS LEVEL ADD #4,R3 ;;;MOVE UP ONE LEVEL BR 40$ ;;;LOOP 45$: MOV (SP)+,DSP-DNR(R5) ;;;RESTORE ORIGINAL LEVEL .IFF MOV GR.SP,R3 ;;;GET DPU STACK POINTER 40$: CMP R3,#GRSTK ;;;AT TOP YET ? BLOS 45$ ;;;YES  TST -(R3) ;;;SKIP VIRTUAL RETURN ADDRESS .IF NDF M$$MGE MOV -(R3),(R4)+ ;;;POINT TO VIRTUAL RETURN ADDR .IFF MOV -(R3),(R4) ;;;PHYSICAL POINTER TO VRA SUB TASK0,(R4)+ ;;;VIRTUAL POINTER TO VRA .ENDC BR 40$ ;;;LOOP 45$: .ENDC ;;; DF V$$S60 .ENDC ;;; DF M$$MGE MOV (SP)+,R3 ;;;RESTORE R3 MOV #-2,(R4) ;;;INSERT TERMINATOR .IF DF M$$MGE MOV (SP)+,KISAR6 ;;;RESTORE MAPPING .IFTF MOV #$GRFRK+6,R4 ;;;SET ADDRESS OF FORK BLOCK MOV #FRKIP,R5 ;;;POINT AT LOCAL DATA INC (R5) ;;;SET FORK IN PROGRESS FLAG INC @GR.PC ;;;RESTART DPU CALL $FORK1 ;;;FORK CLR (R5) ;CLEAR FORK IN PROGRESS FLAG MOV -(R5),R4 ;GET TCB ADDRESS OF CONNECTED TASK BIT #T2.ABO,T.ST2(R4) ;TASK CURRENTLY BEING ABORTED ? BNE 66$ ;YES, DON'T MEDDLE BIS -(R5),@-(R5) ;SET LIGHT PEN TRIGGER EVENT FLAG .IF DF A$$TRP TST -(R5) ;AST DEFINED ? BEQ 50$ ;NO, COOL IT BIT #T2.AST!T2.DST,T.ST2(R4) ;AST IN PROGRESS OR DISABLED ? BNE 50$ ;YES, DON'T START ANOTHER (Q MIGHT GET FULL) TST T.ASTL(R4) ;AST QUEUED ALREADY ? BNE 50$ ;YES, ASSUME ITS OURS AND COOL IT MOV #5*2,R1 ;SIZE OF AST CONTROL BLOCK CALL $ALOCB ;ALLOCATE SOME CORE BCS 50$ ;NONE AVAILABLE, FORGET IT MOV R0,R1 ;COPY ADDRESS OF BLOCK CLR (R0)+ ;SKIP LINK WORD MOV #5*2,(R0)+ ;SAVE BLOCK SIZE MOV #7*2,(R0)+ ;SPACE TO ALLOCATE ON USER STACK MOV (R5),(R0)+ ;AST ADDRESS CLR (R0) ;NO PARAMETERS MOV R4,R0 ;GET TCB ADDRESS ADD #T.ASTL,R0 ;MAKE IT POINTER TO AST LISTHEAD CALL $QINSF ;INSERT AST IN Q .ENDC 50$: MOV R4,R0 ;COPY TCB ADDRESS CALLR $SETCR ;REQUEST USER'S TASK .ENDC ; DF M$$MGE .DSABL LSB ; ; BUS-ERROR / SHIFT-OUT INTERRUPT ; ; A BUS ERROR OCCURS WHEN THE DPU ATTEMPTS TO EXECUTE DISPLAY ; INSTRUCTIONS FROM NON-EXISTENT MEMORY. A SHIFT OUT INTERRUPT OCCURS ; WHEN A CHARACTER >40(8) IS ENCOUNTERED WHILE IN SHIFT OUT MODE. ; IN EITHER CASE, MERELY RESTART THE DPU AT THE BEGINNING OF THE BUFFER ; .IF DF V$$T11 $G¤RBSE:: MOV #GRSTK,GR.SP ;;;RESET DPU STACK POINTER MOV #DELAY,@GR.PC ;;;RESTART DISPLAY AT THE BEGINNING RTI ;;;INTERRUPT FINISHED .ENDC .END ¤Ô@kQ ›c, .TITLE DRDCP .IDENT /05.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.00 ; ; D. N. CUTLER 5-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; ; MODIFIED BY: ; ; T. J. MILLER 6-JUN-77 ; ; TM088 -- CLEAR CHECKPOINT PCB WORD ON DISABLE CHECK- ; POINTING. ; ; H. D. COFFMAN 6-NOV-78 ; ; HDC021 -- CHECK CHECKPOINTABILITY OF TASKS BEFORE ; ENABLING CHECKPOINTING. ENSURE TASKS ; CONNECTED TO INTERRUPTS CANNOT BE CHECKPOINTED. ; ; CHUCK SPITZ 6-MAR-79 ; CS037 -- ALWAYS DEFINE $DRECP AND $DRDCP FOR MCR ; ; DISABLE/ENABLE CHECKPOINTING DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL TCBDF$ TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRDCP-DISABLE CHECKPOINTING ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DISABLE THE CHECKPOINTABILITY ; OF THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(95.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK). ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF CHECKPOINTING ;  IS ALREADY DISABLED FOR ISSUING TASK. ; DIRECTIVE STATUS OF 'D.RS10' IS RETURNED IF THE ISSUING ; TASK IS NOT CHECKPOINTABLE. ;- .IF DF C$$CKP&D$$ISK .ENABL LSB $DRDCP::BIT #T2.CHK,(R2) ;TASK CHECKPOINTABLE? BNE 20$ ;IF NE NO BIT #T2.CKD,(R2) ;CHECKPOINTING ALREADY DISABLED? BNE 30$ ;IF NE YES BIS #T2.CKD,(R2) ;DISABLE CHECKPOINTING .IF DF C$$INT CLR T.CPCB(R5) ;CLEAR CHECKPOINT PCB PTR (ICB LISTHEAD) .ENDC 10$: RETURN ;RETURN DIRECTIVE STATUS OF +1 20$: DRSTS D.RS10 ;SET DIRECTIVE STATUS ;+ ; **-$DRECP-ENABLE CHECKPOINTING ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO ENABLE THE CHECKPOINTABILITY ; OF THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(97.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF CHECKPOINTING ; IS ALREADY DISABLED FOR THE ISSUING TASK OR ; THE ISSUING TASK IS CONNECTED TO INTERRUPTS ; DIRECTIVE STATUS OF 'D.RS10' IS RETURNED IF THE ; ISSUING TASK IS NOT CHECKPOINTABLE. ; ;- $DRECP::BIT #T2.CHK,(R2) ;IS TASK CHECKPOINTABLE? BNE 20$ ;IF NE NO BIT #T2.CKD,(R2) ;CHECKPOINTING DISABLED? BEQ 30$ ;IF EQ YES .IF DF C$$INT MOV T.CPCB(R5),R0 ;TASK CONNECTED TO INTERRUPTS? BNE 30$ ;IF NE YES, CANNOT ENABLE CHECKPOINTING .ENDC ;C$$INT BIC #T2.CKD,(R2) ;ENABLE CHECKPOINTING MOV T.PCB(R5),R0 ;GET ADDRESS OF TASK PARTITION PCB CALLR $NXTSK ;REASSIGN PARTITION IF NECESSARY 30$: DRSTS D.RS8 ;SET DIRECTIVE STATUS .DSABL LSB .IFF ;C$$CKP&D$$ISK .IF DF M$$CRX $DRECP:: $DRDCP::RETURN ;IF NO CHECKPOINTING, JUST RETURN FOR MCR .ENDC ;M$$CRX .ENDC ;C$$CKP&D$$ISK .END ¼zkQ ›c, .TITLE SYTAB .IDENT /10.11/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 10.11 ; ; H. LEV 23-AUG-75 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 13-AUG-79 ; MSH042 -- ADD TASK IMAGE SIZE WORD TO LOADER TCB ; ; M. S. HARVEY 13-AUG-79 ; MSH046 -- ADD BUFFERED I/O COUNT BYTE TO LOADER TCB ; ; M. S. HARVEY 9-OCT-79 ; MSH069 -- ADD EVENT FLAG MASK AND MASK ADDRESS WORDS ; TO THE LOADER'S TCB ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 29-APR-80 ; MSH096 -- ADD ALTERNATE HEADER REFRESH AREA SUPPORT ; ; M. S. HARVEY 14-SEP-81 ; MSH190 -- ADD ALTERNATE CLI CONDITIONALIZATION TO THE ; GROUP GLOBAL CONTEXT BYTE ; ; SYSTEM TABLES NEEDED TO BOOTSTRAP SYSTEM AND FOR RESIDENT TASKS ; ; MACRO LIBRARY CALLS ; .IF NDF L$$LDR&R$$11S .MCALL HWDDF$,PCBDF$,TCBDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS PCBDF$ TCBDF$ ; DEFINE TASK CONTROL BLOCK OFFSETS ; ; LOCAL DATA ; ; LOADER TASK HEADER ; .LDRHD::.BLKW 1 ;H.CSP-CURRENT STACK POINTER .WORD $PCBS-.LDRHD ;H.HDLN-HEADER LENGTH IN BYTES .BLKW 2 ;H.EFLM-EVENT FLAG MASK WORD AND ADDRESS .BYTE 1,1 ;H.CUIC-CURRENT TASK UIC .BYTE 1,1 ;H.DUIC-DEFAULT TASK UIC .IF DF M$$MGE .WORD 170000 ;H.IPS-INITIAL PROCESSOR STATUS WORD .IFF .WORD 0 ;H.IPS-INITIAL PROCESSOR STATUS WORD .IFTF .WORD $LOADR ;H.IPC-INITIAL PROGRAM COUNTER .WORD 20$ ;H.ISP-INITIAL STACK POINTER 10$: .WORD 1 ;H.ODVA-NUMBER OF WINDOW BLOCKS .WORD $PCBS ;H.ODVL-W.BPCB-PARTITION CNTRL BLK ADDR .WORD 2 ;H.TKVA-W.BLVR-LOW VIRTUAL ADDRESS .WORD 117777 ;H.TKVL-W.BHVR-HIGH VIRTUAL ADDRESS .BLKW 1 ;H.PFVA-W.BATT-ATTACHMENT DESCR ADDRESS .BLKW 1 ;H.FPVA-W.BSIZ-WINDOW SIZE .BLKW 1 ;H.RCVA-W.BOFF-OFFSET IN PARTITION .BYTE UISDR5 ;H.EFSV-W.BFPD-FIRST USER PDR .BYTE 1 ;H.EFSV+1-W.BNPD-NUMBER OF PDR'S .WORD 0 ;H.FPSA-W.BLPD-CONTENTS OF LAST PDR .WORD 10$ ;H.WND-POINTER TO NUMBER OF WINDOW BLKS .BLKW 1 ;H.DSW-DIRECTIVE STATUS WORD .BLKW 9. ;H.FCS THRU H.GARD-2-LOADER'S STACK 20$: .WORD 30$ ;H.GARD-POINTER TO HEADER GUARD WORD .WORD 1 ;H.NLUN-NUMBER OF LUNS .WORD .SY0 ;UCB POINTER FOR FIRST LUN .WORD 0 ;WINDOW POINTER FOR FIRST LUN .IFT .BLKW 4  ;SAVE AREA FOR R4,R5,PC,PS .IFTF .BLKW 4 ;SAVE AREA FOR R0,R1,R2,R3 30$: .WORD 0 ;HEADER GUARD WORD ; ; LOADER PARTITION CONTROL BLOCK ; $PCBS:: .WORD 0 ;P.LNK-LINK TO NEXT PARTITION PCB .BYTE 248. ;P.PRI-PRIORITY .BYTE 0 ;P.IOC-I/O COUNT .RAD50 /LDR/ ;P.NAM-FIRST WORD OF PARTITION NAME .WORD 0 ;P.NAM+2-SECOND WORD OF PARTITION NAME .WORD 0 ;P.SUB-SUBPARTITION LINK .WORD $PCBS ;P.MAIN-LINK TO MAIN PARTITION .IFT .WORD 0 ;P.REL-RELOCATION BIAS OF PARTITION .IFF .WORD .LDRHD ;P.HDR-POINTER TO LOADER HEADER .IFTF .BLKW 4 ;P.SIZE THRU P.BUSY-UNUSED .WORD $STD ;P.TCB-LOADER TCB ADDRESS .WORD 0 ;P.STAT-PARTITION STATUS .IFT .WORD .LDRHD ;P.HDR-POINT TO LOADER TASK HEADER .ENDC ; ; LOADER TASK CONTROL BLOCK ; $STD:: ;START OF TASK LIST .LDR:: .WORD 0 ;T.LNK-UTILITY LINK WORD .BYTE 248. ;T.PRI-TASK PRIORITY .BYTE 0 ;T.IOC-TASK I/O COUNT .WORD $STD ;T.TCB-POINTER TO THIS TCB .RAD50 /. LDR./ ;T.NAM-TASK NAME  .WORD 0,.-2 ;T.RCVL-RECEIVE LISTHEAD .WORD 0,.-2 ;T.ASTL-AST QUEUE LISTHEAD .WORD 0,0 ;T.EFLG-TASK LOCAL EVENT FLAGS .WORD 0 ;T.UCB-TI UCB ADDRESS .WORD $HEADR ;T.TCBL-TASK LIST THREAD WORD .WORD TS.EXE ;T.STAT-BLOCKING BITS .WORD T2.CHK!T2.FXD ;T.ST2-STATE BITS .WORD T3.PRV!T3.NSD ;T.ST3-ATTRIBUTE BITS .BYTE 248. ;T.DPRI-NONRESIDENT PARTITION COUNTER .BLKB 3 ;T.LBN-LBN OF TASK IMAGE .WORD .LB0 ;T.LDV-LOAD DEVICE UCB .WORD $PCBS ;T.PCB-TASK PCB ADDRESS .WORD 0 ;T.MXSZ-MAXIMUM SIZE OF TASK IMAGE .WORD 0 ;T.ACTL-ACTIVE TASK LIST THREAD .WORD 0 ;T.SAST-SPECIFIED AST LISTHEAD ;MSH046 .BYTE 0 ; UNUSED BYTE ;MSH046 .BYTE 0 ;T.TIO-BUFFERED I/O COUNT ;MSH046 .WORD 0 ;T.TKSZ-TASK IMAGE SIZE ;MSH042 ;**-1 .IF DF P$$LAS .WORD 0,.-2 ;T.ATT-ATTACHMENT DESCRIPTOR LISTHEAD .WORD 0 ;T.OFF-OFFSET IN TASK PARTITION .BYTE 0 ;(UNUSED) .BYTE 0 ;T.SRCT-SEND BY REF WITH EFN COUNT .WORD 0,.-2 ;T.RRFL-RECEIVE BY REFERENCE LISTHEAD .ENDC  .IF DF P$$OFF .WORD 0,.-2 ;T.OCBH-OFFSPRING CONTROL BLOCK LIST .WORD 0 ;T.RDCT-OFFSPRING RUNDOWN COUNT .ENDC ;P$$OFF .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 .WORD 0,0 ;T.EFLM-EVENT FLAG MASK WORD ;MSH069 ;T.EFLM+2-EVENT FLAG MASK ADDRESS WORD ;MSH069 ;MSH069 .ENDC ;MSH069 ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 .BYTE 0 ;T.HDLN-TASK HEADER LENGTH (32W BLOCKS) ;MSH096 ;MSH096 .ENDC ;MSH096 ;MSH09ô6 .IF DF R$$SND&G$$EFN!A$$CLI&G$$EFN ;MSH190 ;MSH076 .BYTE 0 ;T.GGF-GRP GBL EVENT FLAG USE COUNTER ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH096 .EVEN ;MSH096 ;**-1 .ENDC .END ôüMðskQ ›c, .TITLE LSDRV .IDENT /09.1/ ; ; COPYRIGHT (C) 1974, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 08 ; ; D. N. CUTLER 7-JAN-74 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; B. SCHREIBER 30-NOV-77 ; ; BS033 -- CLEAR I.PRM+16 BEFORE CALLING $IOFIN ; (IN CASE RMS BLOCK LOCKING). ; ; B. SCHREIBER 19-MAY-78 ; ; BS049 -- FIX HANDLING OF DIGITAL INPUT WD. AT INTERRUPT ; ; LPS11 LABORATORY PERIPHERAL SYSTEM CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,TCBDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; EQUATED SYMBOLS ; ; SAMPLE CONTROL BLOCK OFFSET DEFINITIONS ; .PSECT LSCTLQ,D,ABS SLINK: .BLKW 1 ;SAMPLE QUEUE THREAD WORD RQPKT: .BLKW 1 ;ADDRESS OF I/O REQUEST PACKET STATE: .BLKW 1 ;CURRENT SAMPLE STATE RSTAT: .BLKB 1 ;SAMPLE STATUS BYTE FINST: .BLKB 1 ;FINAL I/O STATUS IOSB2: .BLKW 2 ;SECOND I/O STATUS WORD ADDR & REL BIAS STRBF: .BLKW 1 ;STARTING BUFFER ADDR & RELOCATION BIAS CURBF: .BLKW 3 ;CURRENT BUFFER ADDR & RELOCATION BIAS FULBF: .BLKW 1 ;SIZE OF FULL BUFFER IN WORDS SMCNT: .BLKW 1 ;SPACE REMAINING TO END OF BUFFER HAFBF: .BLKW 1 ;SIZE OF HALF BUFFER IN WORDS .IF DF L$$SDR DBMSK: .BLKW 1 ;DIGITAL INPUT/OUTPUT START MASK DSMSK: .BLKW 1  ;DIGITAL INPUT STOP MASK .ENDC CYCNT: .BLKW 1 ;NUMBER OF CLOCK TICKS TO NEXT SAMPLE CRSET: .BLKW 1 ;CLOCK TICKS RESET VALUE TO NEXT SAMPLE SAMCT: .BLKW 1 ;# OF SAMPLE BUFFERS REMAINING IN RQST DATAW: .BLKW 1 ;FUNCTION DEPENDENT DATA WORD STRST: .BLKW 1 ;STARTING SAMPLE STATE .IF DF L$$SBF STKSAV: .BLKW 1 ;CHANNEL (DATAW) SAVE WORD .ENDC SLGTH: ;LENGTH OF SYNCH SAMPLE CONTROL BLOCK .PSECT ; ; SAMPLE CONTROL BLOCK STATUS BYTE BIT DEFINITIONS ; SPARE=200 ;SPARE BIT STROT=100 ;SET DIGITAL OUTPUT BIT AT START (1=YES) STPIN=40 ;STOP ON DIGITAL INPUT BIT CLEAR (1=YES) STPBR=20 ;STOP ON BUFFER RUNOUT (1=YES) GAINR=10 ;AUTOGAIN RANGING REQUESTED (1=YES) SPARE=4 ;SPARE BIT RQEFN=2 ;REQUEST EFN SETTING (1=YES) STPRQ=1 ;STOP SAMPLE REQUEST (1=YES) ; ; A/D TIMEOUT LOOP COUNT ; TMOCNT=20. ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW L$$PS1 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK .IF DF L$$SDR DGIWD: .BLKW L$$PS1 ;DIGITAL INPUT WORD LAST SYNCHRONOUS SAMPLE .ENDC TEMP: .BLKW 1 ;TEMPORARY STORAGE .IF DF L$$SBF DLYCNT: .BLKW L$$PS1 ;CLOCK COUNT FOR A/D DELAY ADCHN: ;CURRENT A/D CHANNEL NUMBER ADFLG=ADCHN+1 ;A/D CONVERSION ENABLE FLAG .REPT L$$PS1 .BYTE 377,0 .ENDR .ENDC ; ; FORK REQUEST FLAG ; FKFLG: .WORD 0 ; ; LEGAL FUNCTION VECTOR ; LGFCN: .BYTE IO.SDO/256. ;WRITE DIGITAL OUTPUT REGISTER .BYTE IO.LED/256. ;WRITE LED DISPLAY LIGHTS .BYTE IO.REL/256. ;WRITE RELAY .BYTE IO.SDI/256. ;READ DIGITAL INPUT REGISTER .BYTE IO.STP/256. ;STOP IN PROGRESS REQUEST .BYTE IO.HIS/256. ;SYNCHRONOUS HISTOGRAM SAMPLING .BYTE IO.MDO/256. ;SYNCHRONOUS DIGITAL OUTPUT .BYTE IO.ADS/256. ;SYNCHRONOUS A/D SAMPLING .BYTE IO.MDA/256. ;SYNCHRONOUS D/A OUTPUT .EVEN ; ; DRIVER DISPATCH TABLE ; $LSTBL::.WORD LSINI ;DEVICE INITIATOR ENTRY POINT .WORD LSCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD LSOUT ;DEVICE TIMEOUT ENTRY POINT .WORD LSPWF ;POWERFAIL ENTRY POINT ;+ ; **-LSINI-LPS11 LABORATORY PERIPHERAL SYSTEM CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS RECEIVED FOR THE LPS11 LABORATORY PERIPHERAL SYSTEM. NINE FUNCTIONS ARE ; RECOGNIZED BY THE LPS11 DRIVER. FUNCTIONS ARE EITHER EXECUTED IMMEDITATELY ; OR PLACED IN A SAMPLE REQUEST QUEUE THAT IS MAINTAINED BY THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; FUNCTION INDEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE. ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; ; OUTPUTS: ; ; IF THE FUNCTION IS READ SINGLE A/D CHANNEL, WRITE DIGITAL OUTPUT ; REGISTER, WRITE LED DISPLAY LIGHTS, OR WRITE RELAY, THEN THE ; FUNCTION IS EXECUTED IMMEDIATEDLY. ELSE A SECONDARY CONTROL BLOCK ; IS CONSTRUCTED AND LINKED INTO THE SAMPLE REQUEST QUEUE. ;- LSINI: MOV U.SCB(R5),R2 ;GET ADDRESS OF SCB MOV R1,R3 ;SAVE I/O PACKET ADDRESS ADD #I.PRM,R1 ;POINT TO FIRST PARAMETER MOV S.CSR(R2),R4 ;GET ADDRESS OF CONTROL STATUS REGISTER MOV #LGFCN,R0 ;POINT TO LEGAL FUNCTION VECTOR MOVB I.FCN+1(R3),-(SP) ;GET I/O FUNCTION CODE CMPB (SP),(R0)+ ;WRITE DIGITAL OUTPUT REGISTER? .IF DF L$$SDR BEQ DIGIO ;IF EQ YES .IFF BEQ LSONP ;IF EQ YES .IFTF CMPB (SP),(R0)+ ;WRITE LED DISPLAY LIGHTS? BEQ WRLED ;IF EQ YES CMPB (SP),(R0)+ ;WRITE RELAY? .IFT BEQ WRRLY ;IF EQ YES CMPB (SP),(R0)+ ;READ DIGITAL INPUT REGISTER? BEQ RDDIN ;IF EQ YES .IFF BEQ LSONP ;IF EQ YES CMPB (SP),(R0)+ ;READ DIGITAL INPUT REGISTER? BEQ LSONP ;IF EQ YES .ENDC CMPB (SP),(R0)+ ;STOP IN PROGRESS REQUEST? BEQ STOPR ;IF EQ YES JMP LSFCN ;ELSE HANDLE FUNCTION ; ; **-STOPR-STOP IN PROGRESS REQUST ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- BUFFER ADDRESS OF PREVIOUS REQUEST. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; STOPR: MOV (R1),R0 ;GET ADDRESS OF BUFFER MOV R2,R4 ;SAVE ADDRESS OF SCB CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R3,-(SP) ;SAVE I/O PACKET ADDRESS MOV R5,R3 ;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R3 ; MOVB S.PRI(R4),PS ;;;LOCK OUT DEVICE INTERRUPTS 10$: MOV (R3),R3 ;;;GET ADDRESS OF NEXT ENTRY BEQ 20$ ;;;IF EQ DONE MOV RQPKT(R3),R0 ;;;GET ADDRESS OF I/O PACKET CMP $TKTCB,I.TCB(R0) ;;;REQUEST FOR CURRENT TASK? BNE 10$ ;;;IF NE NO CMP R1,STRBF(R3) ;;;RELOCATION BIAS MATCH? BNE 10$ ;;;IF NE NO CMP R2,STRBF+4(R3) ;;;BUFFER ADDRESS MATCH? BNE 10$ ;;;IF NE NO MOVB #IE.ABO,FINST(R3) ;;;SET FINAL STATUS ABORT CALL TERMS ;;;TERMINATE SAMPLE REQUEST 20$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS MOV (SP)+,R3 ;RESTORE I/O PACKET ADDRESS BR LSSUC ;TAKE COMMON EXIT .IF DF L$$SDR ; ; **-RDDIN-READ DIGITAL INPUT REGISTER ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- DIGITAL INPUT MASK WORD. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; RDDIN: SEC ;INDICATE DIGITAL INPUT REQUEST DIGIO: BITB #20,U.CW2+1(R5) ;LPSDR-A PRESENT? BEQ LSONP ;IF EQ NO BCC WRDOT ;BRANCH IF DIGITAL OUTPUT REQUEST .IF GT L$$PS1-1 MOVB S.CON(R2),R2 ;GET CONTROLLER INDEX MOV DGIWD(R2),R2 ;GET DIGITAL INPUT WORD LAST SYNCHRONOUS .IFF MOV DGIWD,R2 ;GET DIGITAL INPUT OF LAST SYNCH SAMPLE .ENDC TSTB U.STS(R5) ;UNIT BUSY? BMI 10$ ;IF MI YES MOV 12(R4),R2 ;READ DIGITAL INPUT REGISTER MOV R2,12(R4) ;CLEAR BITS IN DIGITAL INPUT REGISTER 10$: COM (R1) ;COMPLEMENT MASK WORD BIC (R1),R2 ;CLEAR UNWANTED BITS IN DATA WORD MOV R2,R1 ;SET SECOND I/O STATUS WORD BR LSSUC1 ;TAKE COMMON EXIT ; ; **-WRDOT-WRITE DIGITAL OUTPUT REGISTER ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- DIGITAL OUTPUT MASK WORD. ; WD. 13 -- DIGITAL OUTPUT VALUE. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WRDOT: BIT (R1),U.CNT+2(R5) ;DIGITAL OUTPUT BITS IN USE? BNE LSRSU ;IF NE YES ADD #14,R4 ;POINT TO DIGITAL OUTPUT REGISTER COM (R1) ;COMPLEMENT MASK WORD BIC (R1)+,(R1) ;CLEAR EXCESS BITS IN DATA WORD BIS (R1),(R4) ;SET BITS IN DIGITAL OUTPUT REGISTER COM (R1) ;COMPLEMENT DATA WORD BIC -2(R1),(R1) ;CLEAR EXCESS BITS IN DATA WORD BIC (R1),(R4) ;CLEAR BITS IN DIGITAL OUTPUT REGISTER MOV (R4),R1 ;SET SECOND I/O STATUS WORD BR LSSUC1 ;TAKE COMMON EXIT .ENDC ; ; **-WRLED-WRITE LED DISPLAY LIGHTS ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- 16 BIT SIGNED BINARY NUMBER TO BE DISPLAYED IN LED LIGHTS. ; WD. 13 -- LED DIGIT NUMBER OF DECIMAL POINT. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WRLED: TST (R4)+ ;POINT TO LED DISPLAY REGISTER MOV R1,R2 ;COPY ADDRESS OF FIRST PARAMETER WORD MOV #16,-(SP) ;ASSUME POSITIVE NUMBER MOV (R2)+,R0 ;GET NUMBER TO BE DISPLAYED BPL 10$ ;IF PL POSITIVE NUMBER DEC (SP) ;SET MINUS SIGN AS LAST DIGIT NEG R0 ;CONVERT TO POSITIVE NUMBER 10$: CLR -(SP) ;CLEAR DIGIT COUNTER DEC (R2) ;CALCULATE ACTUAL DIGIT POSITION SWAB (R2) ;SWAP POSITION INTO LEFT BYTE CLRB (R2) ;CLEAR LOW BYTE OF POSITION 20$: MOV #10.,R1 ;SET DIVISOR CALL $DIV ;CONVERT DIGIT BIS (SP),R1 ;MERGE DIGIT AND DIGIT COUNTER CMP (SP),(R2) ;DIGIT POSITION MATCH? BNE 30$ ;IF NE NO BIS #20,R1 ;SET TO DISPLAY DECIMAL POINT 30$: MOV R1,(R4) ;OUTPUT DISPLAY DIGIT ADD #1*400,(SP) ;INCREMENT DIGIT COUNTER CMP #5*400,(SP) ;NUMBER CONVERTED? BGT 20$ ;IF GT NO BIS (SP)+,(SP) ;MERGE LAST DIGIT WITH DIGIT COUNTER MOV (SP)+,(R4) ;OUTPUT LAST DIGIT (MINUS OR BLANK) .IF DF L$$SDR BR LSSUC ;TAKE COMMON EXIT ; ; **-WRRLY-WRITE RELAY ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- RELAY NUMBER (0 OR 1). ; WD. 13 -- POLARITY DESIRED (ZERO=OPEN, NONZERO=CLOSED). ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; WRRLY: ;REF LABEL BITB #20,U.CW2+1(R5) ;LPSDR-A PRESENT? BEQ LSONP ;IF EQ NO ADD #10,R4 ;POINT TO RELAY 1 ASR (R1)+ ;TEST RELAY NUMBER BNE LSBAD ;IF NE ILLEGAL RELAY NUMBER BCC 10$ ;IF CC RELAY 1 INC R4 ;POINT TO RELAY 2 10$: TST (R1) ;ZERO POLARITY? BEQ 20$ ;IF EQ YES BISB #1,(R4) ;SET POLARITY TO ONE BR LSSUC ; 20$: BICB #1,(R4) ;SET POLARITY TO ZERO .IFTF ; ; SUCCESS COMPLETION OF FUNCTION ; LSSUC: CLR R1 ;CLEAR SECOND I/O STATUS WORD LSSUC1: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS CODE BR LSCMN1 ; ; ; BAD PARAMETER ; LSBAD: MOV #IE.BAD&377,R0 ;SET BAD PARAMETER STATUS CODE BR LSCMN ; .IFT ; ; RESOURCE IN USE ; LSRSU: MOV #IE.RSU&377,R0 ;SET RESOURCE IN USE STATUS CODE BR LSCMN ; .ENDC ; ; PRIVILEGE VIOLATION ; LSPRI: MOV #IE.PRI&377,R0 ;SET PRIVILEGE VIOLATION STATUS BR LSCMN ; ; ; OPTION NOT PRESENT ; LSONP: MOV #IE.ONP&377,R0 ;SET OPTION NOT PRESENT STATUS BR LSCMN ; ; ; DYNAMIC MEMORY NOT AVAILABLE ; LSNOD: MOV #IE.NOD&377,R0 ;SET MEMORY NOT AVAILABLE STATUS ; ; COMMON STATUS EXIT ; LSCMN: CLR R1 ;CLEAR SECOND I/O STATUS WORD LSCMN1: TST (SP)+ ;REMOVE FUNCTION CODE FROM STACK CLR I.PRM+16(R3) ;CLEAR BLOCK LOCKING WORD FOR $IOFIN CALLR $IOFIN ;FINISH I/O OPERATION ; ; ALL REMAINING FUNCTIONS REQUIRE THE REQUESTING TASK TO BE EITHER FIXED ; IN MEMORY OR NOT CHECKPOINTABLE AND AN I/O STATUS DOUBLEWORD TO BE ; SPECIFIED. ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF BUFFER. ; WD. 13 -- BUFFER ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 14 -- BUFFER SIZE IN BYTES. ; WD. 15 -- DIGITAL INPUT/OUTPUT POINT NUMBERS. ; WD. 16 -- LPS CLOCK TICKS BETWEEN SAMPLES. ; WD. 17 -- NUMBER OF BUFFERS. ; WD. 20 -- FUNCTION DEPENDENT DATA WORD. ; LSFCN: MOV I.TCB(R3),R2 ;GET REQUESTING TASK TCB ADDRESS BIT #T2.CHK!T2.FXD,T.ST2(R2) ;TASK FXD OR NOT CHKPOINTABLE? BEQ LSPRI ;IF EQ NO TST I.IOSB+4(R3) ;I/O STATUS DOUBLEWORD SPECIFIED? BEQ LSBAD ;IF EQ NO ADD #6,R1 ;POINT TO DIGITAL POINT NUMBERS BITB #340,I.FCN(R3) ;DIGITAL I/O SUB-FUNCTION REQUESTED? .IF DF L$$SDR BEQ 35$ ;IF EQ NO BITB #20,U.CW2+1(R5) ;LPSDR-A PRESENT? BEQ LSONP ;IF EQ NO MOVB I.FCN(R3),R2 ;GET SUBFUNCTION MODIFIER BITS BPL 10$ ;IF PL START IMMEDIATELY CMPB (R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS LSBAD ;IF HIS NO 10$: ASLB R2 ;SET DIGITAL OUTPUT ON START? BPL 20$ ;IF PL NO CMPB (R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS LSBAD ;IF HIS NO MOVB (R1),R4 ;GET DIGITAL OUTPUT POINT NUMBER ASL R4 ;CONVERT TO WORD INDEX BIT $BTMSK(R4),U.CNT+2(R5) ;DIGITAL OUTPUT BIT IN USE? BNE LSRSU ;IF NE YES 20$: ASLB R2 ;STOP ON DIGITAL INPUT? BPL 30$ ;IF PL NO CMPB 1(R1),#16. ;LEGAL DIGITAL POINT NUMBER? BHIS LSBAD ;IF HIS NO 30$: ASL (R1) ;CONVERT BOTH POINT NUMBERS TO WORD INDICES .IFF BNE LSONP ;IF NE YES .IFTF 35$: ;REF LABEL ADD #8.,R1 ;POINT TO LAST WORD IN I/O PACKET CMPB (SP),(R0)+ ;SYNCHRONOUS HISTOGRAM SAMPLING? BEQ 40$ ;IF EQ YES CMPB (SP),(R0)+ ;SYNCHRONOUS DIGITAL OUTPUT? .IFT BEQ 50$ ;IF EQ YES .IFF BEQ LSONP ;IF EQ YES .IFTF CMPB (SP),(R0)+ ;SYNCHRONOUS A/D SAMPLING?  BEQ 60$ ;IF EQ YES CMPB (SP),(R0)+ ;SYNCHRONOUS D/A OUTPUT? .IFT BNE 100$ ;IF NE NO .IFF BNE LSONP ;IF NE NO (NO DIGITAL INPUT) .ENDC .IF DF L$$SDA ; ; SYNCHRONOUS D/A OUTPUT ; MOV #SYNDA,(R1) ;SET SYNCHRONOUS D/A OUTPUT STATE MOVB U.CW2+1(R5),R0 ;GET OPTION FLAGS AND NUMBER OF D/A'S BIT #100,R0 ;D/A OPTION PRESENT? BEQ LSONP ;IF EQ NO BIC #^C<37>,R0 ;CLEAR ALL BUT NUMBER OF D/A'S MOVB -(R1),R2 ;GET NUMBER OF OUTPUT D/A'S MOVB -(R1),R4 ;GET STARTING D/A NUMBER BR 90$ ;FINISH IN COMMON CODE .IFF BR LSONP ;D/A OPTION NOT PRESENT .ENDC ; ; SYNCHRONOUS HISTOGRAM SAMPLING ; 40$: MOV #SYNHS,(R1) ;SET SYNCHRONOUS HISTOGRAM SAMPLING STATE CLR -(R1) ;CLEAR DATA WORD BR 120$ ; .IF DF L$$SDR ; ; SYNCHRONOUS DIGITAL OUTPUT ; 50$: MOV #SYNDO,(R1) ;SET SYNCHRONOUS DIGITAL OUTPUT STATE BIT -(R1),U.CNT+2(R5) ;ANY DIGITAL OUTPUT BITS IN USE? BR 110$ ;FINISH IN COMMON CODE .IFTF ; ; SYNCHRONOUS A/D SAMPLING ; 60$: MOV #SYNAD,(R1) ;SET SYNCHRONOUS A/D SAMPLING STATE MOVB -(R1),R2 ;GET NUMBER OF CHANNELS MOVB -(R1),R4 ;GET STARTING CHANNEL AND GAIN BITB #GAINR,I.FCN(R3) ;AUTOGAIN RANGING SPECIFIED? BNE 70$ ;IF NE YES BIT #60,R4 ;GAIN OTHER THAN 1 SPECIFIED? BEQ 80$ ;IF EQ NO TST U.CW2(R5) ;GAIN OPTION PRESENT? BPL 80$ ;IF PL NO BIC #60,R4 ;CLEAR GAIN CODE BITS 70$: TST U.CW2(R5) ;GAIN OPTION PRESENT? BPL LSONP ;IF PL NO 80$: MOVB U.CW2(R5),R0 ;GET NUMBER OF A/D CHANNELS BIC #^C<177>,R0 ; 90$: DEC R2 ;REDUCE NUMBER OF CHANNELS ADD R2,R4 ;CALCULATE HIGHEST CHANNEL BCS LSBAD ;IF CS BAD RANGE CMP R4,R0 ;LEGAL CHANNEL? BHIS LSBAD ;IF HIS NO .IFT BR 120$ ;FINISH IN COMMON CODE ; ; SYNCHRONOUS DIGITAL INPUT ; 100$: MOV #SYNDI,(R1) ;SET SYNCHRONOUS DIGITAL INPUT STATE BIT -(R1),U.CNT(R5) ;ANY DIGITAL INPUT BITS IN USE? 110$: BNE LSRSU ;IF NE YES .IFTF 120$: MOV R3,R4 ;SAVE I/O PACKET ADDRESS MOV #SLGTH,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $ALOCB ;ALLOCATE SECONDARY CONTROL BLOCK MOV R4,R3 ;RESTORE I/O PACKET ADDRESS BCS LSNOD ;IF CS NO MEMORY AVAILABLE MOV R0,R1 ;COPY SECONDARY CONTROL BLOCK ADDRESS CLR (R1)+ ;CLEAR LINK WORD MOV R3,(R1)+ ;INSERT I/O PACKET ADDRESS ADD #I.FCN,R3 ;POINT TO SUBFUNCTION MODIFIER BITS .IFT MOV #SDOUT,(R1)+ ;SET INITIAL STATE TO DIGITAL OUTPUT .IFF MOV I.PRM+14.(R4),(R1)+ ;SET INITIAL SAMPLING STATE .IFTF MOV (R3),(R1) ;INSERT SUBFUNCTION MODIFIER BITS BIC #^C,(R1)+ ;CLEAR EXTRANEOUS BITS ADD #I.IOSB+2,R4 ;POINT TO I/O STATUS DOUBLEWORD ADDRESS MOV (R4)+,(R1)+ ;INSERT RELOCATION BIAS MOV (R4)+,(R1) ;INSERT DISPLACEMENT ADDRESS ADD #2,(R1)+ ;CALCULATE ADDRESS OF SECOND I/O STATUS TST (R4)+ ;BYPASS AST ADDRESS AND CLEAR CARRY MOV (R4),(R1)+ ;INSERT BUFFER RELOCATION BIAS MOV (R4)+,(R1)+ ; MOV (R4),(R1)+ ;INSERT BUFFER DISPLACEMENT ADDRESS MOV (R4)+,(R1)+ ; MOV (R4)+,(R1) ;INSERT SIZE OF BUFFER IN BYTES ROR (R1) ;CONVERT TO SIZE IN WORDS MOV (R1)+,(R1) ;INSERT SIZE OF BUFFER IN WORDS MOV (R1)+,(R1) ;INSERT SIZE OF BUFFER IN WORDS ASR (R1)+ ;CONVERT TO SIZE IN DOUBLEWORDS .IFT MOVB (R4)+,R2 ;GET DIGITAL INPUT/OUTPUT POINT INDEX CLR (R1) ;ASSUME NO DIGITAL INPUT/OUTPUT POINT ASLB (R3) ;START ON DIGITAL INPUT POINT? BCC 130$ ;IF CC NO MOV #SWAIT,STATE(R0) ;ALTER STATE TO WAIT ON DIGITAL INPUT BR 140$ ; 130$: BPL 150$ ;IF PL NO DIGITAL OUTPUT ON START 140$: MOV $BTMSK(R2),(R1) ;INSERT DIGITAL INPUT/OUTPUT POINT MASK TSTB (R3) ;SET DIGITAL OUTPUT POINT AT START? BPL 150$ ;IF PL NO BIS (R1),U.CNT+2(R5) ;SET DIGITAL OUTPUT POINT IN USE 150$: TST (R1)+ ;ADVANCE TO NEXT WORD CLR (R1) ;ASSUME NO DIGITAL INPUT POINT MOVB (R4)+,R2 ;GET DIGITAL INPUT POINT INDEX ASLB (R3) ;STOP ON DIGITAL INPUT POINT? BPL 160$ ;IF PL NO MOV $BTMSK(R2),(R1) ;INSERT DIGITAL INPUT POINT MASK 160$: CMP (R1)+,(SP)+ ;ADVANCE TO NEXT WORD AND CLEAN STACK .IFF CMP (R4)+,(SP)+ ;SKIP DIGITAL I/O WORD AND CLEAN STACK .IFTF MOV #1,(R1)+ ;INSERT INITIAL CLOCK TICKS TO NEXT SAMPLE MOV (R4)+,(R1)+ ;INSERT CLOCK TICKS RESET VALUE MOV (R4)+,(R1)+ ;INSERT NUMBER OF BUFFERS TO COLLECT MOV (R4)+,(R1)+ ;INSERT FUNCTION DEPENDENT DATA WORD MOV (R4),(R1) ;INSERT STARTING SAMPLE STATE .IFT CMP #SYNDO,(R1) ;SYNCHRONOUS DIGITAL OUTPUT? BEQ 170$ ;IF EQ YES CMP #SYNDI,(R1) ;SYNCHRONOUS DIGITAL INPUT? BNE 190$ ;IF NE NO BIS -(R1),U.CNT(R5) ;SET DIGITAL INPUT BITS IN USE BR 180$ ; 170$: BIS -(R1),U.CNT+2(R5) ;SET DIGITAL OUTPUT BITS IN USE 180$: COM (R1) ;COMPLEMENT MASK WORD .ENDC 190$: MOV U.BUF(R5),(R0) ;INSERT REQUEST IN SAMPLE QUEUE MOV R0,U.BUF(R5) ; MOVB I.EFN-(R4),R0 ;GET SPECIFIED EVENT FLAG NUMBER MOV R5,-(SP) ;SAVE UCB ADDRESS MOV I.TCB-(R4),R5 ;GET TCB ADDRESS OF REQUESTOR TASK CALL $CEFI ;CONVERT EFN TO MASK AND ADDRESS MOV R1,(R4) ;INSERT EFN MASK ADDRESS MOV R0,-(R4) ;INSERT EFN MASK WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS MOV U.SCB(R5),R3 ;GET ADDRESS OF SCB TSTB U.STS(R5) ;UNIT BUSY? BMI 200$ ;IF MI YES .IF DF L$$SBF TSTB U.CW2(R5) ;BANDWIDTH FILTERS IN USE? BPL 198$ ;IF PL NO MOV U.BUF+2(R5),R0 ;GET DELAY COUNTDOWN FOR 10KHZ MOV U.CW4(R5),R1 ;GET CLOCK INTERRUPT COUNTDOWN CALL $DIV ;CALCULATE INTERRUPT COUNT TST R1 ;WAS THERE A REMAINDER? BEQ 195$ ;IF EQ NO INC R0 ;ELSE, INCREMENT COUNT 195$: ;REF LABEL .IF GT L$$PS1-1 MOVB S.CON(R3),R1 ;GET CONTROLLER INDEX MOV R0,DLYCNT(R1) ;STORE DELAY COUNT .IFF MOV R0,DLYCNT ;STORE DELAY COUNT .ENDC 198$: ;REF LABEL .ENDC MOV S.CSR(R3),R2 ;GET ADDRESS OF CONTROL STATUS REGISTER CMP (R2)+,(R2)+ ;POINT TO CLOCK STATUS REGISTER MOV #506,(R2)+ ;SET REPEAT MODE, 10KHZ, AND ENABLE INT MOV U.CW4(R5),(R2) ;LOAD COUNTER PRESET REGISTER NEG (R2) ;NEGATE PRESET VALUE INC -(R2) ;START CLOCK RUNNING 200$: BISB #US.BSY,U.STS(R5) ;SET UNIT BUSY MOVB #1,S.STS(R3) ;SET CONTROLLER BUSY MOVB S.ITM(R3),S.CTM(R3) ;SET CURRENT TIMEOUT COUNT RETURN ; ;+ ; **-$LSCLK-LPS11 LABORATORY PERIPHERAL SYSTEM CLOCK INTERRUPT ;- $LSCLK:: ;;;REF LABEL $LSINT:: ;;;REF LABEL INTSV$ LS,PR6,L$$PS1 ;;;GENERATE INTERRUPT SAVE CODE MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IF GT L$$PS1-1 MOV R1,-(SP) ;;;SAVE R1 MOV R4,R1 ;;;PUT CONTROLLER INDEX IN R1 .ENDC MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT MOV S.CSR(R4),R4 ;;;GET ADDRESS OF CONTROL STATUS REGISTER .IF DF L$$SDR .IF GT L$$PS1-1 BITB #20,U.CW2+1(R5) ;;;LPSDR-A PRESENT? BEQ 10$ ;;;IF EQ NO .IFTF MOV 12(R4),R3 ;;;READ DIGITAL INPUT REGISTER .IFT MOV R3,DGIWD(R1) ;;;SAVE DIGITAL INPUT WORD .IFF MOV R3,DGIWD ;;;SAVE DIGITAL INPUT WORD .ENDC MOV R3,TEMP ;;;SAVE COMPLEMENT OF DIGITAL INPUT WORD COM TEMP ;;; MOV R3,12(R4) ;;;CLEAR BITS IN DIGITAL INPUT REGISTER 10$: ;;;REF LABEL .ENDC MOV R5,R3 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R3 ;;; .IF DF M$$MGE MOV KISAR6,-(SP) ;;;SAVE CURRENT APR6 MAPPING .ENDC ; ; GET NEXT REQUEST FROM SAMPLE QUEUE AND PROCESS ; .ENABL LSB NXTRQ: MOV (R3),R3 ;;;GET ADDRESS OF NEXT SAMPLE REQUEST BEQ 20$ ;;;IF EQ END OF REQUEST QUEUE DEC CYCNT(R3) ;;;TIME TO SAMPLE? BNE NXTRQ ;;;IF NE NO 10$: MOV CRSET(R3),CYCNT(R3) ;;;RESET SAMPLE CYCLE COUNT JMP @STATE(R3) ;;;PROCESS SAMPLE REQUEST 20$: JMP ENDRQ ;;; .IF DF L$$SDR ; ; START SAMPLING IF DIGITAL INPUT BIT SET ; SWAIT: MOV #1,CYCNT(R3) ;;;SET TO REPEAT TEST AT NEXT INTERVAL BIT DBMSK(R3),TEMP ;;;START SAMPLING? BNE NXTRQ ;;;IF NE NO BITB #STROT,RSTAT(R3) ;;;SET DIGITAL OUTPUT BIT AT START? BEQ 30$ ;;;IF EQ NO ; ; SET DIGITAL OUTPUT BIT ; SDOUT: BIS DBMSK(R3),14(R4) ;;;SET DIGITAL OUTPUT BIT 30$: MOV STRST(R3),STATE(R3) ;;;CHANGE STATE TO STARTING VALUE BR 10$ ;;;DISPATCH ON NEW STATE .IFTF .DSABL LSB ; ; SYNCHRONOUS HISTOGRAM SAMPLING ; SYNHS: INC DATAW(R3) ;;;INCREMENT EVENT COUNTER BEQ 10$ ;;;IF EQ COUNTER OVERFLOW TST 4(R4) ;;;SCHMITT TRIGGER 1 FIRE? BPL NXTRQ ;;;IF PL NO 10$: BIC #100000,4(R4) ;;;CLEAR SCHMITT TRIGGER 1 FLAG MOV DATAW(R3),R2 ;;;GET EVENT COUNTER CLR DATAW(R3) ;;;CLEAR EVENT COUNTER CALL WRWRD ;;;WRITE WORD INTO USER BUFFER BR NXTRQ ;;;CONTINUE SCAN .IFT ; ; SYNCHRONOUS DIGITAL OUTPUT ;  SYNDO: ;;;REF LABEL CALL RDWRD ;;;READ WORD FROM USER BUFFER BCS NXTRQ ;;;IF CS BUFFER OVERRUN MOV 14(R4),-(SP) ;;;READ DIGITAL OUTPUT REGISTER MOV DATAW(R3),-(SP) ;;;GET OUTPUT MASK WORD BIC (SP),R2 ;;;CLEAR EXCESS BITS IN DATA WORD COM (SP) ;;;COMPLEMENT MASK WORD BIC (SP)+,(SP) ;;;CLEAR FIELD BITS IN OUTPUT WORD BIS (SP)+,R2 ;;;MERGE DATA AND OUTPUT WORD MOV R2,14(R4) ;;;WRITE VALUE INTO DIGITAL OUTPUT REGISTER BR NXTRQ ;;;CONTINUE SCAN .ENDC ; ; SYNCHRONOUS A/D SAMPLING ; SYNAD: ;;;REF LABEL .IF DF L$$SBF .IF GT L$$PS1-1 TSTB ADFLG(R1) ;;;A/D CONVERSIONS DISABLED? .IFF TSTB ADFLG ;;;A/D CONVERSIONS DISABLED? .ENDC BNE NXTRQ ;;;IF NE YES -- IGNORE REQUEST .ENDC MOV DATAW(R3),-(SP) ;;;SET COUNT & STARTING CHANNEL ADSLCT: ;;;REF LABEL .IF DF L$$SBF .IF GT L$$PS1-1 TSTB U.CW2(R5) ;;;BANDWIDTH FILTERING ENABLED? BPL 10$ ;;;IF PL NO CMPB (SP),ADCHN(R1) ;;;IS A/D CHANNEL SELECTED? .IFF CMPB (SP),ADCHN ;;;IS A/D CHANNEL SELECTED? .ENDC BEQ ADSMPL ;;;IF EQ YES JMP SDELAY ;;;SELECT CHANNEL AND DELAY .ENDC 10$: MOVB (SP),1(R4) ;;;SET NUMBER OF CHANNEL TO CONVERT ADSMPL: ;;;REF LABEL MOVB #1,(R4) ;;;START CONVERSION MOV #TMOCNT,R2 ;;;SET TIMEOUT LOOP COUNT 20$: BIT #100200,(R4) ;;;ERROR OR DONE? BMI 80$ ;;;IF MI ERROR .IF DF L$$SGR BNE 30$ ;;;IF NE DONE .IFF BNE 90$ ;;;IF NE DONE .IFTF DEC R2 ;;;TIMEOUT? BGT 20$ ;;;IF GT NO .IFT BR 70$ ;;;TIMEOUT 30$: BITB #GAINR,RSTAT(R3) ;;;GAIN RANGING REQUESTED? BEQ 90$ ;;;IF EQ NO MOVB (SP),R2 ;;;GET A/D CHANNEL NUMBER ASL R2 ;;;CONVERT TO WORD INDEX MOV 2(R4),-(SP) ;;;READ CONVERTED VALUE BIT $BTMSK(R2),U.CW3(R5) ;;;UNIPOLAR CHANNEL? BNE 40$ ;;;IF NE YES SUB #4000,(SP) ;;;SUBTRACT OUT OFFSET BIAS BPL 35$ ;;;IF PL OKAY NEG (SP) ;;;NEGATE RESULT 35$: ASL (SP) ;;;NORMALIZE RESULT 40$: MOV (SP)+,R2 ;;;COPY NORMALIZED VALUE BIT #6000,R2 ;;;SAMPLE AT GAIN 1? BNE 90$ ;;;IF NE YES ADD #<1*20>*400,(R4) ;;;SET TO SAMPLE AT GAIN 4 BIT #1400,R2 ;;;SAMPLE AT GAIN 4? BNE 50$ ;;;IF NE YES ADD #<1*20>*400,(R4) ;;;SET TO SAMPLE AT GAIN 16. BIT #300,R2 ;;;SAMPLE AT GAIN 16.? BNE 50$ ;;;IF NE YES ADD #<1*20>*400,(R4) ;;;SET TO SAMPLE AT GAIN 64. 50$: INC (R4) ;;;START CONVERSION MOV #TMOCNT,R2 ;;;SET TIMEOUT LOOP COUNT 60$: BIT #100200,(R4) ;;;ERROR OR DONE? BMI 80$ ;;;IF MI ERROR BNE 90$ ;;;IF NE DONE DEC R2 ;;;TIMEOUT? BGT 60$ ;;;IF GT NO .IFTF 70$: MOV #177777,R2 ;;;SET TIMEOUT ERROR VALUE BR 100$ ;;; 80$: MOV #177776,R2 ;;;SET CONVERSION ERROR VALUE BR 100$ ;;; 90$: MOV 2(R4),R2 ;;;READ CONVERTED VALUE .IFT BIC #147777,(R4) ;;;CLEAR ALL BUT GAIN BITS BIS (R4),R2 ;;;INSERT GAIN CODE .ENDC 100$: CALL WRWRD ;;;WRITE WORD INTO USER BUFFER BCS 110$ ;;;IF CS BUFFER OVERRUN INCB (SP) ;;;INCREMENT CHANNEL NUMBER DECB 1(SP) ;;;ANY MORE CHANNELS TO SAMPLE?  BGT ADSLCT ;;;IF GT YES 110$: TST (SP)+ ;;;CLEAN STACK JMP NXTRQ ;;;CONTINUE SCAN .IF DF L$$SDA ; ; SYNCHRONOUS D/A OUTPUT ; SYNDA: ;;;REF LABEL MOV DATAW(R3),-(SP) ;;;SET COUNT AND STARTING D/A NUMBER 10$: CALL RDWRD ;;;READ WORD FROM USER BUFFER BCS 60$ ;;;IF CS BUFFER OVERRUN BIC #170000,R2 ;;;CLEAR D/A NUMBER FIELD MOVB (SP),-(SP) ;;;COPY D/A NUMBER DECB (SP) ;;;D/A 0 OR 1? BMI 20$ ;;;IF MI D/A 0 (X-REG) BEQ 30$ ;;;IF EQ D/A 1 (Y-REG) DECB (SP) ;;;NORMALIZE EXTERNAL D/A NUMBER RORB (SP) ;;;ROTATE D/A NUMBER INTO PLACE RORB (SP) ;;; RORB (SP) ;;; RORB (SP) ;;; SWAB R2 ;;;SWAP DATA BYTES BISB (SP)+,R2 ;;;MERGE D/A NUMBER WITH DATA SWAB R2 ;;;SWAP BACK DATA BYTES MOV R2,24(R4) ;;;OUTPUT DATA TO PROPER D/A BR 50$ ;;; 20$: MOV R2,20(R4) ;;;OUTPUT TO X-REG D/A BR 40$ ;;; 30$: MOV R2,22(R4) ;;;OUTPUT TO Y-REG D/A 40$: TST (SP)+ ;;;CLEAN STACK 50$: INC (SP) ;;;INCREMENT D/A NUMBER DECB 1(SP) ;;;ANY MORE TO GO? BGT 10$ ;;;IF GT YES 60$: TST (SP)+ ;;;CLEAN STACK JMP NXTRQ ;;;CONTINUE SCAN .ENDC .IF DF L$$SDR ; ; SYNCHRONOUS DIGITAL INPUT SAMPLING ; SYNDI: ;;;REF LABEL .IF GT L$$PS1-1 MOV DGIWD(R1),R2 ;;;GET SAVED DIGITAL INPUT WORD .IFF MOV DGIWD,R2 ;;;GET SAVED DIGITAL INPUT WORD .ENDC MOV DATAW(R3),-(SP) ;;;GET INPUT MASK WORD BIC (SP)+,R2 ;;;CLEAR EXCESS BITS IN DATA WORD CALL WRWRD ;;;WRITE WORD INTO USER BUFFER JMP NXTRQ ;;;CONTINUE SCAN .ENDC ; ; END OF REQUEST QUEUE-CHECK IF FORK REQUIRED ; ENDRQ: ;;;REF LABEL .IF DF M$$MGE MOV (SP)+,KISAR6 ;;;RESTORE APR6 MAPPING .ENDC .IF GT L$$PS1-1 MOV (SP)+,R1 ;;;RESTORE R1 .ENDC MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; TST FKFLG ;;;FORK REQUESTED? BEQ 10$ ;;;IF EQ NO CLR FKFLG ;;;CLEAR FORK REQUESTED FLAG BITB #US.FRK,U.STS(R5) ;;;FORK ALREADY IN PROGRESS? BEQ ENDRQ1 ;;;IF EQ NO 10$: JMP $INTXT ;;;EXIT INTERRUPT ;+ ; **-LSCAN-CANCEL I/O REQUESTS ; ; THIS ROUTINE IS ENTERED TO CANCEL ALL I/O REQUESTS THAT ARE IN PROGRESS FOR ; THE CURRENT TASK. THE SAMPLE QUEUE IS SCANNED AND ALL REQUESTS FOR THE CURRENT ; TASK ARE MARKED FOR TERMINATION WITH A FINAL REQUEST STATUS OF 'IE.ABO'. ; ; INPUTS: ; ; R0=ADDRESS OF THE CURRENT I/O PACKET (MEANINGLESS). ; R1=ADDRESS OF THE TCB OF THE CURRENT TASK. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; ALL REQUESTS FOR THE CURRENT TASK ARE MARKED FOR TERMINATION WITH ; A FINAL STATUS OF 'IE.ABO'. ;- .ENABL LSB LSCAN: MOV #IE.ABO&377,R0 ;;;SET FINAL STATUS CODE TO ABORT BR 10$ ;;;FINISH IN COMMON CODE ;+ ; **-LSOUT-DEVICE TIMEOUT ; ; THIS ROUTINE IS ENTERED WHEN AN LPS11 OPERATION TIMES OUT. ALL REQUESTS IN THE ; SAMPLE QUEUE ARE MARKED FOR TERMINATION WITH A FINAL STATUS OF 'IE.DNR'. ; TIMEOUTS ARE USUALLY CAUSED BY A POWERFAILURE BUT MAY ALSO BE THE RESULT ; OF A HARDWARE FAILURE. ; ; INPUTS: ; ; R0=DEVICE TIMEOUT STATUS 'IE.DNR'. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; ALL REQUESTS ARE MARKED FOR TERMINATION WITH A FINAL STATUS OF ; 'IE.DNR'. ;- LSOUT: MOV S.CSR(R4),R2 ;;;GET ADDRESS OF CONTROL STATUS REGISTER CLR (R2) ;;;CLEAR A/D INTERRUPTS CLR 4(R2) ;;;CLEAR CLOCK INTERRUPTS 10$: MOV R5,R2 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R2 ;;; 20$: MOV (R2),R2 ;;;GET ADDRESS OF NEXT ENTRY BEQ 40$ ;;;IF EQ NONE CMPB #IE.ABO,R0 ;;;CANCEL I/O? BNE 30$ ;;;IF NE NO MOV RQPKT(R2),R3 ;;;GET ADDRESS OF I/O PACKET CMP R1,I.TCB(R3) ;;;REQUEST FOR CURRENT TASK? BNE 20$ ;;;IF NE NO 30$: BISB #STPRQ,RSTAT(R2) ;;;SET TO TERMINATE SAMPLE REQUEST MOVB R0,FINST(R2) ;;;SET FINAL REQUEST STATUS MOV #NXTRQ,STATE(R2) ;;;SET STATE TO TERMINATION IN PROGRESS BR 20$ ;;; 40$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS BR ENDRQ2 ;FINISH IN COMMON CODE .DSABL LSB ;+ ; **-LSPWF-POWERFAIL ; ; THIS ROUTINE IS ENTERED AS THE RESULT OF A POWERFAILURE. POWERFAIL IS HANDLED ; VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES NO IMMEDIATE ACTION ON ; THE DEVICE. THE UNIT CONTROL BLOCK ADDRESS IS STORED IN THE DRIVER CONTROLLER ; TABLE. ; ; INPUTS: ; ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; THE UNIT CONTROL BLOCK ADDRESS IS STORED IN THE DRIVER CONTROLLER TABLE. ;- LSPWF: MOV R5,CNTBL(R3) ;SET ADDRESS OF UNIT CONTROL BLOCK RETURN ; ; ; FORK REQUESTED AND NO FORK IN PROGRESS ; ENDRQ1: BISB #US.FRK,U.STS(R5) ;;;SET FORK IN PROGRESS FLAG CALL $FORK ;;;CREATE A SYSTEM PROCESS BICB #US.FRK,U.STS(R5) ;CLEAR FORK IN PROGRESS FLAG ; ; SCAN SAMPLE QUEUE FOR EVENT FLAG AND TERMINATION REQUESTS ; ENDRQ2: MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOVB S.PRI(R4),PS ;;;LOCK OUT DEVICE INTERRUPTS MOV R5,R4 ;;;CALCULATE ADDRESS OF SAMPLE QUEUE LISTHEAD ADD #U.BUF,R4 ;;; 10$: MOV R4,R3 ;;;SAVE ADDRESS OF PREVIOUS ENTRY MOV (R3),R4 ;;;GET ADDRESS OF NEXT ENTRY BEQ 70$ ;;;IF EQ NONE BITB #STPRQ,RSTAT(R4) ;;;TERMINATE REQUEST? BNE 20$ ;;;IF NE YES BITB #RQEFN,RSTAT(R4) ;;;REQUEST EFN SETTING? BEQ 10$ ;;;IF EQ NO BICB #RQEFN,RSTAT(R4) ;;;CLEAR EFN REQUEST FLAG CLRB PS ;;;ALLOW DEVICE INTERRUPTS MOV RQPKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV I.TCB(R3),R0 ;GET TCB ADDRESS OF REQUESTING TASK BIT #T2.ABO,T.ST2(R0) ;TASK BEING ABORTED? BNE ENDRQ2 ;IF NE YES BIS I.PRM+14(R3),@I.PRM+16(R3) ;SET SPECIFIED EVENT FLAG CALL $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST BR ENDRQ2 ;TRY AGAIN 20$: MOV (R4),(R3) ;;;REMOVE ENTRY FROM QUEUE 30$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS .IF DF L$$SDR MOV DATAW(R4),R3 ;GET DATA MASK WORD COM R3 ;CONVERT MASK TO IN USE BITS CMP #SYNDO,STRST(R4) ;SYNCRHONOUS DIGITAL OUTPUT? BEQ 40$ ;IF EQ YES CMP #SYNDI,STRST(R4) ;SYNCHRONOUS DIGITAL INPUT BNE 50$ ;IF NE NO BIC R3,U.CNT(R5) ;CLEAR INPUT BITS IN USE MASK BR 50$ ; 40$: BIC R3,U.CNT+2(R5) ;CLEAR OUTPUT BITS IN USE MASK 50$: BITB #STROT,RSTAT(R4) ;SET DIGITAL OUTPUT BIT ON START? BEQ 60$ ;IF EQ NO BIC DBMSK(R4),U.CNT+2(R5) ;CLEAR OUTPUT BIT IN USE MASK .ENDC 60$: CLR R0 ;PICKUP FINAL I/O STATUS BISB FINST(R4),R0 ; .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT APR6 MAPPING MOV IOSB2(R4),KISAR6 ;MAP TO SECOND I/O STATUS WORD .IFTF MOV @IOSB2+2(R4),R1 ;RETRIEVE CONTENTS OF SECOND I/O STATUS WORD .IFT MOV (SP)+,KISAR6 ;RESTORE APR6 .ENDC MOV RQPKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV R4,-(SP) ;SAVE ADDRESS OF SECONDARY CONTROL BLOCK CLR I.PRM+16(R3) ;CLEAR BLOCK LOCKING WORD FOR $IOFIN CALL $IOFIN ;FINISH I/O OPERATION MOV (SP)+,R0 ;RETRIEVE ADDRESS OF SECONDARY CONTROL BLOCK MOV #SLGTH,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $DEACB ;RELEASE SECONDARY CONTROL BLOCK BR ENDRQ2 ;GO AGAIN ; ; SCAN OF SAMPLE QUEUE COMPLETE-CHECK IF ANYTHING IS STILL ACTIVE ; 70$: MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;;;RESET DEVICE TIMEOUT COUNT TST U.BUF(R5) ;;;ANY REQUESTS IN SAMPLE QUEUE BNE 80$ ;;;IF NE YES MOV S.CSR(R4),R3 ;;;GET ADDRESS OF CONTROL STATUS REGISTER CLR (R3) ;;;CLEAR A/D INTERRUPTS CLR 4(R3) ;;;CLEAR CLOCK INTERRUPTS BICB #US.BSY,U.STS(R5) ;;;CLEAR UNIT BUSY CLRB S.STS(R4) ;;;CLEAR CONTROLLER BUSY .IF DF L$$SBF .IF GT L$$PS1-1 MOVB S.CON(R4),R1 ;;;GET CONTROLLER INDEX MOV #377,ADCHN(R1) ;;;INVALIDATE A/D CHANNEL INFO .IFF MOV #377,ADCHN ;;;INVALIDATE A/D CHANNEL INFO .ENDC .ENDC 80$: CLRB PS ;;;ALLOW DEVICE INTERRUPTS RETURN ; ; ; SUBROUTINE TO READ A VALUE FROM USER BUFFER ; .ENABL LSB RDWRD: ;;;REF LABEL .IF DF M$$MGE MOV IOSB2(R3),KISAR6 ;;;MAP TO SECOND I/O STATUS WORD .IFTF INC @IOSB2+2(R3) ;;;INCREMENT FREE POSITIONS IN BUFFER CMP FULBF(R3),@IOSB2+2(R3) ;;;BUFFER OVERRUN? BLO 70$ ;;;IF LO YES .IFT MOV CURBF(R3),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV @CURBF+4(R3),R2 ;;;READ VALUE FROM USER BUFFER BR 10$ ;;;FINISH IN COMMON CODE ; ; SUBROUTINE TO WRITE A VALUE INTO USER BUFFER ; WRWRD: ;;;REF LABEL .IFT MOV IOSB2(R3),KISAR6 ;;;MAP TO SECOND I/O STATUS WORD .IFTF INC @IOSB2+2(R3) ;;;INCREMENT NUMBER OF ENTRIES IN BUFFER CMP FULBF(R3),@IOSB2+2(R3) ;;;BUFFER OVERRUN? BLO 70$ ;;;IF LO YES .IFT MOV CURBF(R3),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV R2,@CURBF+4(R3) ;;;WRITE VALUE INTO USER BUFFER 10$: ADD #2,CURBF+4(R3) ;;;UPDATE USER BUFFER ADDRESS .IFT BIT #20000,CURBF+4(R3) ;;;OVERFLOW 4K BOUNDRY? BEQ 20$ ;;;IF EQ NO BIC #20000,CURBF+4(R3) ;;;CLEAR OVERFLOW BIT ADD #200,CURBF(R3) ;;;ADVANCE TO NEXT 4K BOUNDRY .IFTF 20$: DEC SMCNT(R3) ;;;END OF BUFFER? BNE 30$ ;;;IF NE NO .IFT MOV STRBF(R3),CURBF(R3) ;;;RESET RELOCATION BIAS .ENDC MOV STRBF+4(R3),CURBF+4(R3) ;;;RESET BUFFER ADDRESS MOV FULBF(R3),SMCNT(R3) ;;;RESET SAMPLE BUFFER COUNT BITB #STPBR,RSTAT(R3) ;;;STOP ON BUFFER RUNOUT? BEQ 40$ ;;;IF EQ NO DEC SAMCT(R3) ;;;DECREMENT BUFFER COUNT BEQ 60$ ;;;IF EQ BUFFER RUNOUT BR 40$ ;;; 30$: CMP SMCNT(R3),HAFBF(R3) ;;;EXACTLY AT HALF BUFFER? BNE 50$ ;;;IF NE NO 40$: BISB #RQEFN,RSTAT(R3) ;;;REQUEST EFN SETTING INC FKFLG ;;;SET FORK REQUEST 50$: CLC ;;;CLEAR OVERRUN INDICATOR .IF DF L$$SDR BIT DSMSK(R3),TEMP ;;;STOP BIT CLEAR? BEQ 90$ ;;;IF EQ NO .IFF BR 90$ ;;;RETURN .ENDC 60$: MOVB #IS.SUC,FINST(R3) ;;;SET SUCCESSFUL COMPLETION STATUS BR TERMS ;;; 70$: MOVB #IE.DAO,FINST(R3) ;;;SET FINAL STATUS TO BUFFER OVERRUN DEC @IOSB2+2(R3) ;;;READJUST BUFFER FREE COUNT TERMS: BISB #STPRQ,RSTAT(R3) ;;;SET TO TERMINATE SAMPLE REQUEST MOV #NXTRQ,STATE(R3) ;;;SET STATE TO TERMINATION IN PROGRESS INC FKFLG ;;;SET FORK REQUEST SEC ;;;SET OVERRUN/TERMINATION INDICATOR 90$: RETURN ;;; .DSABL LSB  ; ; SELECT A/D CHANNEL AND SETUP A DELAY ; .IF DF L$$SBF SDELAY: MOVB (SP),1(R4) ;;;SELECT THE A/D CHANNEL MOV (SP),STKSAV(R3) ;;;SAVE CHANNEL (DATAW) INFO MOV #ENDLAY,STATE(R3) ;;;SET NEW DISPATCH ADDRESS .IF GT L$$PS1-1 MOV DLYCNT(R1),CYCNT(R3) ;;;SET DELAY COUNT MOV (SP)+,ADCHN(R1) ;;;STORE A/D CHANNEL NUMBER AND ;;; DISABLE A/D CONVERSIONS .IFF MOV DLYCNT,CYCNT(R3) ;;;SET DELAY COUNT MOV (SP)+,ADCHN ;;;STORE A/D CHANNEL NUMBER AND ;;; DISABL¸E A/D CONVERSIONS .ENDC JMP NXTRQ ;;;DEQUEUE NEXT REQUEST ; ; END OF CHANNEL SELECT DELAY PERIOD ; ENDLAY: MOV STKSAV(R3),-(SP) ;;;PUT CHANNEL INFO ON STACK MOV #SYNAD,STATE(R3) ;;;RESTORE A/D DISPATCH ADDR .IF GT L$$PS1-1 CLRB ADFLG(R1) ;;;ENABLE A/D SAMPLING .IFF CLRB ADFLG ;;;ENABLE A/D SAMPLING .ENDC JMP ADSMPL ;;;CONTINUE A/D SAMPLING .ENDC .END ¸â8"kQ ›c, .TITLE DRRES .IDENT /07.08/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 07.08 ; ; D. N. CUTLER 31-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 25-JUL-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 5-OCT-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT ; ; M. S. HARVEY 4-JUN-81 ; MSH172 -- BUFFERED I/O STOPFOR STATE CAN ONLY ; EXIST AT PRE-AST LEVEL ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,PKTDF$,PCBDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS .ENABL LSB .IF DF S$$TOP ;+ ; **-$DRUNS-UNSTOP TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO UNSTOP A TASK THAT HAS STOPPED ; ITSELF VIA A STOP DIRECTIVE OR A RECEIVE OR STOP DIRECTIVE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(133.),DPB SIZE(3.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO BE UNSTOPPED. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO BE UNSTOPPED. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF THE SPECIFIED ; TASK IS NOT ACTIVE. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THE SPECIFIED ; TASK IS NOT STOPPED, OR STOPPED FOR EVENT ; FLAG(S) OR BUFFERED I/O. ;- $DRUNS::TST (R1)+ ;SPECIFIED TASK ACTIVE? BMI 20$ ;IF MI NO MOV #T2.STP,R2 ;PICK UP STOP BIT ;MSH046 BIT #T2.SEF,(R1) ;TASK IN A STOPFOR STATE? ;MSH046 BNE 30$ ;IF NE YES ;MSH046 ;MSH046 .IF DF T$$BUF ;MSH046 ;MSH046 TSTB T.TIO(R0) ;OUTSTANDING BUFFERED I/O? ;MSH046 BEQ 5$ ;IF EQ NO, UNSTOP TASK ;MSH046 MOV #T2.AST!T2.WFR,R3 ;GET STOPFOR TEST MASK ;MSH172 BIT R3,(R1) ;TASK AT AST STATE? ;MSH172 BPL 3$ ;IF PL NO ;MSH172 ASL R3 ;CONVERT TO PRE-AST WFR MASK ;MSH172 BIT R3,(R1) ;TASK IN BUFFERED I/O STOPFOR STATE? ;MSH172 3$: BNE 30$ ;IF NE TASK IN STOPFOR STATE ;MSH172 ;MSH046 .ENDC ;MSH046 ;MSH046 BR 5$ ;UNSTOP THE TASK ;MSH046 ;**-4 .IFTF ;S$$TOP ;+ ; **-$DRRES-RESUME TASK EXECUTION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO RESUME THE EXECUTION OF A TASK THAT ; HAS ISSUED A SUSPEND DIRECTIVE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(47.),DPB SIZE(3.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO BE RESUMED. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO BE RESUMED. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS7 IS RETURNED IF THE SPECIFIED ; TASK IS NOT ACTIVE. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THE SPECIFIED ; TASK IS NOT SUSPENDED. ;- $DRRES::TST (R1)+ ;TASK ACTIVE? BMI 20$ ;IF MI NO MOV #T2.SPN,R2 ;GET SUSPEND BIT 5$: BIT R2,(R1) ;TASK CURRENTLY SUSPENDED? BNE 10$ ;IF NE YES TST (R1) ;AST IN PROGRESS? BPL 30$ ;IF PL NO ASL R2 ;SET PRE AST SUSPEND BIT BIT R2,(R1) ;WAS TASK SUSPENDED? BEQ 30$ ;IF EQ NO 10$: ;REF LABEL .IFT ;S$$TOP CMPB $DICSV,#133. ;IS THIS AN UNSTOP DIRECTIVE? BEQ 15$ ;IF EQ YES .IFTF ;S$$TOP BIC R2,(R1) ;CLEAR TASK'S SUSPEND BIT CALLR $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST .IFT ;S$$TOP 15$: CALLR $EXRQN ;UNSTOP SPECIFIED TASK .IFTF ;S$$TOP 20$: DRSTS D.RS7 ;SET DIRECTIVE STATUS 30$: DRSTS D.RS8 ;SET DIRECTIVE STATUS .IFT ;S$$TOP ;+ ; **-$DRSTP-STOP TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO STOP THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(131.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF 'D.RS22' IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THE ISSUING ; TASK IS AT AST STATE. ;- $DRSTP::TST (R2)  ;IS ISSUING TASK AT AST STATE? BMI 33$ ;IF MI YES CALL $STPCT ;STOP ISSUING TASK DRSTS D.RS22 ;RETURN SUCCESS WITH +2 33$: DRSTS D.RS80 ;ISSUING TASK IS AT AST STATE .ENDC ;S$$TOP ;+ ; **-$DRSPN-SUSPEND EXECUTION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SUSPEND THE EXECUTION OF THE ISSUING ; TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(45.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRxESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF 'D.RS22'. ;- $DRSPN::BIS #T2.SPN,(R2) ;SUSPEND CURRENT TASK CALL $SETRT ;FORCE A REDISPATCHING OF PROCESSOR DRSTS D.RS22 ;SET DIRECTIVE STATUS ;**-156 .DSABL LSB .END x$ðskQ ›c, .TITLE DTDRV .IDENT /08.02/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 08.02 ; ; D. N. CUTLER 1-DEC-73 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; F. L. STRAIGHT ; ; MODIFIED BY: ; ; E. L. BAATZ 18-JUN-78 ; ; DAN BROWN 20-JAN-81 ; ; DTB013 -- REMOVE REFERENCES TO S.BMSK FOR NEW ; ERROR LOG. ; ; TC11 DECTAPE CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HWDDF$,PKTDF$ ABODF$ ;DEFINE TASK ABORT CODES HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; WAIT=100000 ;WAITING TO SELECT UNIT (1=YES) ABRT=40000 ;ABORT CURRENT FUNCTION (1=YES) RETRY=5. ;ERROR RETRY COUNT .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; ; DIAGNOSTIC FUNCTIONS IO.RNF AND IO.RNR USE BIT 7 OF RTTBL AS ; A FLAG FOR INTERRUPT SERVICING. CNTBL: .BLKW T$$C11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW T$$C11 ;ERROR RETRY COUNT AND DRIVE RESET FLAG .IF GT T$$C11-1 TEMP: .BLKW 1 ;TEMPORY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $DTTBL::.WORD DTINI ;DEVICE INITIATOR ENTRY POINT .WORD DTCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DTOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DTPWF ;POWERFAIL ENTRY POINT ;+ ; **-DTINI-TC11 DECTAPE CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB DTINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS DTPWF ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R3=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; TC11 DECTAPE I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB,IO.RLV,IO.WLB, OR IO.WLV). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK. ADDRESS ; WD. 21 -- DIAGNOSTIC REG. BLK. ADDRESS (REAL OR DISPL. + 140000) ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS .ENDC MOV #<8.*256.>+RETRY,RTTBL(R3) ;SET ROCK AND RETRY COUNTS .IF DF D$$IAG MOV R1,R0 ;COPY I/O PACKET ADDRESS ADD #I.FCN,R0 ;POINT TO FUNCTION CODE BITB #IQ.UMD,(R0) ;DIAGNOSTIC FUNCTION CALL? BEQ 4$ ;IF EQ NO CLRB RTTBL(R3) ;NO RETRIES FOR DIAGNOSTIC OPERATIONS CMP #IO.RNF!IQ.UMD,(R0) ;READ BLOCK FORWARD? BNE 2$ ;IF NE NO MOV #IO.RLB!IQ.UMD,(R0) ;CONVERT TO READ LOGICAL FORWARD BR 3$ ; 2$: CMP #IO.RNR!IQ.UMD,(R0) ;READ BLOCK REVERSE? BNE 4$ ;IF NE NO MOV #IO.RLV!IQ.UMD,(R0) ;CONVERT TO READ LOGICAL REVERSE 3$: BIS #200,RTTBL(R3) ;SET READ BLOCK NUMBER FLAG .ENDC 4$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION MOV R5,R3 ;COPY ADDRESS OF UCB ADD #U.BUF+1,R3 ;POINT TO HIGH BYTE OF MEM.EXT WORD MOVB R2,(R3) ;INSERT DRIVE NUMBER BISB #105,-(R3) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 5$ ;IF HIS FUNCTION IS LEGAL JMP 195$ ;ILLEGAL FUNCTION 5$: BEQ 10$ ;IF EQ FUNCTION IS READ BIS #10,(R3) ;CONVERT TO WRITE LOGICAL FUNCTION 10$: BIT #IO.WLV&377,I.FCN(R1) ;REVERSE DIRECTION? BEQ 20$ ;IF EQ NO BIS #4000,(R3) ;SET REVERSE DIRECTION BIT 20$: CLRB U.CW2+1(R5) ;CLEAR ABORT FLAG CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER MOV R0,U.VCB+2(R5) ;SAVE LOGICAL BLOCK NUMBER ; ; INITIATE I/O OPERATION ; 30$: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $MPUBM ;MAP UNIBUS TO TRANSFER .ENDC MOV S.CSR(R4),R0 ;GET ADDRESS OF CSR CMP (R0)+,(R0)+ ;POINT TO BUFFER ADDRESS REGISTER MOV U.BUF+2(R5),(R0) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R0) ;INSERT LENGTH OF TRANSFER IN BYTES CLR U.VCB+4(R5) ;CLEAR FINAL ERROR STATUS ROR (R0) ;CONVERT LENGTH TO WORD COUNT NEG (R0) ;MAKE NEGATIVE WORD COUNT MOVB U.BUF+1(R5),-(R0) ;INSERT UNIT AND DIRECTION BIT BIS #WAIT,U.CW2(R5) ;SET WAITING TO SELECT UNIT MOVB #11,-(R0) ;STOP TRANSPORT (SELECT UNIT) 35$: BIT #100200,(R0) ;SELECT ERROR? BMI 40$ ;IF MI YES BEQ 35$ ;IF EQ DRIVE NOT SELECTED BIC #WAIT,U.CW2(R5) ;CLEAR WAITING TO SELECT UNIT MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT MOVB #103,(R0) ;START SEARCH FOR BLOCK.  ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ; DTPWF: RETURN ; ; ; OUTPUT SELECT ERROR MESSAGE ; 40$: MOV #T.NDSE,R0 ;SET FOR DEVICE SELECT ERROR MESSAGE MOVB #1,S.CTM(R4) ;RESET CURRENT DEVICE TIMEOUT COUNT DECB S.STS(R4) ;TIME TO OUTPUT MESSAGE? BNE DTPWF ;IF NE NO MOVB #15.,S.STS(R4) ;SET TO OUTPUT NEXT MESSAGE IN 15. SECONDS CALLR $DVMSG ;OUTPUT MESSAGE ; ; CANCEL I/O OPERATION - FORCE I/O TO COMPLETE IF DEVICE NOT READY ; DTCAN: CMP R1,I.TCB(R0) ;;;REQUEST FOR CURRENT TASK? BNE 50$ ;;;IF NE NO BIS #ABRT,U.CW2(R5) ;;;SET FOR ABORT IF DEVICE NOT READY 50$: RETURN ;;; ; ; DEVICE TIMEOUT USUALLY OCCURS BECAUSE THE DRIVER IS WAITING TO ; SELECT A UNIT. TIMEOUTS MAY ALSO OCCUR AS A RESULT OF A HARDWARE ; FAILURE OR A POWERFAILURE. ; DTOUT: ;REF LABEL .IF DF D$$IAG MOV S.PKT(R4),R1 ;;;GET I/O PACKET ADDRESS BITB #IQ.UMD,I.FCN(R1) ;;;DIAGNOSTIC FUNCTION CALL? BNE 165$ ;;;IF NE YES .ENDC MOV U.CW2(R5),R1 ;;;WAITING TO SELECT A UNIT? BMI 55$ ;;;IF MI YES CALL $DTOER ;;;LOG DEVICE TIMEOUT 55$: MTPS #0 ;;;ALLOW DEVICE INTERRUPTS MOV #IE.ABO&377,R0 ;ASSUME REQUEST IS TO BE ABORTED ASL R1 ;ABORT REQUEST? BPL 30$ ;IF PL NO .IF DF D$$IAG JMP 190$ ;ABORT REQUEST .IFF BR 190$ ; .ENDC ;+ ; **-$DTINT-TC11 DECTAPE CONTROLLER INTERUPTS ;- INTSE$ DT,PR6,T$$C11 ;;;SAVE REGISTERS AND SET PRIORITY MOV R3,-(SP) ;;;SAVE R3 MOV U.SCB(R5),R3 ;;;GET ADDRESS OF STATUS CONTROL BLOCK MOVB S.ITM(R3),S.CTM(R3) ;;;RESET CURRENT DEVICE TIMEOUT COUNT MOV S.CSR(R3),R3 ;;;GET ADDRESS OF COMMAND REGISTER .IF DF D$$IAG TSTB RTTBL(R4) ;DIAGNOSTIC READ BLOCK NO.? BMI 150$ ;IF MI YES .ENDC BIT #2,(R3) ;;;BLOCK SEARCH IN PROGRESS? BEQ 150$ ;;;IF EQ NO TST (R3) ;;;SEARCH ERROR? BPL 70$ ;;;IF PL NO TST -(R3) ;;;END ZONE? BMI 110$ ;;;IF MI YES BIT #20000,(R3)+ ;;;MARK TRACK ERROR? BNE 120$ ;;;IF NE YES-TRY TO BYPASS IT 60$: MOV #100000,U.VCB+4(R5) ;;;SET UNRECOVERABLE ERROR BIC #100,(R3) ;;;CLEAR INTERRUPT ENABLE BR 160$ ;;; 70$: MOV 6(R3),-(SP) ;;;GET CURRENT BLOCK NUMBER CMPB U.BUF+1(R5),1(R3) ;;;MOVING IN FINAL DIRECTION? BNE 80$ ;;;IF NE NO CMP (SP),U.VCB+2(R5) ;;;BLOCK NUMBER MATCH? BEQ 130$ ;;;IF EQ YES 80$: BIT #4000,(R3) ;;;MOVING IN FORWARD DIRECTION? BEQ 90$ ;;;IF EQ YES ADD #2,(SP) ;;;ADD TURN AROUND BIAS CMP U.VCB+2(R5),(SP)+ ;;;TURN AROUND NECESSARY? BR 100$ ;;; 90$: SUB #2,(SP) ;;;SUBTRACT TURN AROUND BIAS CMP (SP)+,U.VCB+2(R5) ;;;TURN AROUND NECESSARY? 100$: BLE 120$ ;;;IF LE NO TST -(R3) ;;;POINT TO ERROR REGISTER 110$: TST (R3)+ ;;;POINT TO COMMAND REGISTER DECB RTTBL+1(R4) ;;;DRIVE HUNG? BLT 60$ ;;;IF LT YES MOV #4000,-(SP) ;;;GET DIRECTION BIT BIC (R3),(SP) ;;;.NOT.COMMAND REGISTER.AND.DIRECTION BIT BIC #4000,(R3) ;;;.NOT.DIRECTION BIT.AND.COMMAND REGISTER BIS (SP)+,(R3) ;;;DIRECTION BIT.OR.COMMAND REGISTER 120$: INC (R3) ;;;CONTINUE SEARCH BR 140$ ;;; 130$: TST (SP)+ ;;;REMOVE BLOCK NUMBER FROM STACK MOV U.BUF(R5),(R3) ;;;START READ/WRITE FUNCTION ;**-8 140$: MOV (SP)+,R3 ;;;RESTORE R3 RETURN ;;; 150$: BICB #100,(R3) ;;;CLEAR INTERRUPT ENABLE TST (R3) ;;;ANY ERRORS? BPL 160$ ;;;IF PL NO ERRORS MOV -(R3),U.VCB+4(R5) ;;;SAVE ERROR STATUS 160$: MOV (SP)+,R3 ;;;RESTORE R3 CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF STATUS CONTROL BLOCK MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL COMPLETION .IF DF D$$IAG MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION CALL? 165$: BNE 180$ ;IF NE YES .ENDC MOV U.VCB+4(R5),R2 ;RETRIEVE ERROR STATUS BEQ 180$ ;IF EQ SUCCESS .IF DF E$$DVC ; DTB013 ;**-1 CALL $DVERR ;LOG DEVICE ERROR .IFTF BIT #63000,R2 ;RECOVERABLE ERROR? BEQ 170$ ;IF EQ NO DECB RTTBL(R3) ;ANY MORE RETRIES? BLE 170$ ;IF LE NO MOVB #8.,RTTBL+1(R3) ;RESET ROCK COUNT JMP 30$ ;TRY AGAIN 170$: MOV #IE.WLK&377,R0 ;ASSUME DRIVE WRITE LOCKED BIT #10000,R2 ;DRIVE WRITE LOCKED? BNE 180$ ;IF NE YES MOV #IE.VER&377,R0 ;UNRECOVERABLE ERROR 180$: MOV S.CSR(R4),R2 ;GET ADDRESS OF COMMAND REGISTER .IF DF D$$IAG 185$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION CALL? BEQ 187$ ;IF EQ NO CALL $CRPAS ;PASS UNIBUS DEV ICE REGISTERS 187$: ;REF. LABEL .ENDC MOV U.CNT(R5),R1 ;GET ORIGINAL BYTE COUNT ADD 2(R2),R1 ;CALCULATE NUMBER OF BYTES TRANSFERED ADD 2(R2),R1 ; 190$: MOVB #11,(R2) ;STOP TAPE MOTION .IFT MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC 195$: CALL $IODON ;FINISH I/O OPERATION JMP DTINI ;GO AGAIN .DSABL LSB .END  „fðskQ ›c, .TITLE PPDRV .IDENT /02.01/ ; ; COPYRIGHT (C) 1975, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.01 ; ; THOMAS J. MILLER 25-NOV-74 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; E. L. BAATZ 18-JUN-78 ; ; EB148 -- REMOVE EXPLICIT PS REFERENCE ; ; PC11 PAPER TAPE PUNCH DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HWDDF$,PKTDF$,TCBDF$ ABODF$ ;DEFINE TASK ABORT CODES HWDDF$ ;DEFINE HARDWARE REGISTER SYMBOLS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; EQUATED SYMBOLS ; ; PAPER TAPE PUNCH STATUS WORD BIT DEFINITIONS (U.CW2) ; WAIT=100000 ;WAITING FOR DEVICE TO COME ON-LINE (1=YES) ABORT=40000 ;ABORT CURRENT I/O REQUEST (1=YES) TRAIL=200 ;CURRENTLY PUNCHING TRAILER (1=YES) ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW P$$P11 ;ADDRESS OF UNIT CONTROL BLOCK .IF GT P$$P11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $PPTBL::.WORD PPINI ;DEVICE INITIATOR ENTRY POINT .WORD PPCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD PPOUT ;DEVICE TIMEOUT ENTRY POINT .WORD PPPWF ;POWERFAIL ENTRY POINT ;+ ; **-PPINI-PC11 PAPER TAPE PUNCH CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB PPINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS PPPWF ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; PAPER TAPE PUNCH I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.WLB, IO.ATT OR IO.DET). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; MOV R5,CNTBL(R3) ;SAVE UCB POINTER FOR INTERRUPT ROUTINE CLR U.CW2(R5) ;CLEAR ALL SWITCHES CMPB I.FCN+1(R1),#IO.WLB/256. ;WRITE LOGICAL BLOCK FUNCTION? BEQ 10$ ;IF EQ YES MOV I.TCB(R1),R0 ;GET REQUESTOR TCB ADDRESS BIT #T2.ABO,T.ST2(R0) ;TASK BEING ABORTED? BNE 65$ ;IF NE YES - DON'T PUNCH TRAILER BIS #TRAIL,U.CW2(R5) ;OTHERWISE FUNCTION IS ATTACH OR DETACH ; SET FLAG TO PUNCH TRAILER MOV #170.,U.CNT(R5) ;SET COUNT FOR 170 NULLS 10$: BIS #WAIT,U.CW2(R5) ;ASSUME WAIT FOR DEVICE OFF LINE TST @S.CSR(R4) ;DEVICE OFF LINE? BMI 80$ ;IF MI YES 20$: BIC #WAIT,U.CW2(R5) ;DEVICE ON LINE, CLEAR WAIT CONDITION MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT COUNT MOV #100,@S.CSR(R4) ;ENABLE INTERRUPTS ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION ; PPPWF: RETURN ; ;+ ; **-$PPINT-PC11 PAPER TAPE PUNCH CONTROLLER INTERUPTS ;- $PPINT:: ;;;REF LABEL INTSV$ PP,PR4,P$$P11 ;;;GENERATE INTERRUPT SAVE CODE MOV U.SCB(R5),R4 ;;;GET ADDRESS OF STATUS CONTROL BLOCK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT MOV S.CSR(R4),R4 ;;;POINT R4 TO CONTROL STATUS REGISTER MOV (R4)+,U.CW3(R5) ;;;SAVE STATUS BMI 60$ ;;;IF MI, ERROR SUB #1,U.CNT(R5) ;;;DECREMENT CHARACTER COUNT BCS 50$ ;;;IF CS, THEN DONE TSTB U.CW2(R5) ;;;CURRENTLY PUNCHING TRAILER? BPL 30$ ;;;IF PL NO CLRB (R4) ;;;LOAD NULL INTO OUTPUT REGISTER BR 40$ ;;;BRANCH TO LOAD IT 30$: CALL $GTBYT ;;;GET NEXT BYTE FROM USER BUFFER MOVB (SP)+,(R4) ;;;LOAD BYTE INTO OUTPUT REGISTER 40$: JMP $INTXT ;;;EXIT FROM INTERRUPT 50$: INC U.CNT(R5) ;;;RESET BYTE COUNT 60$: CLR -(R4) ;;;DISABLE PUNCH INTERRUPTS CALL $FORK ;;;CREATE SYSTEM PROCESS MOV U.SCB(R5),R4 ;POINT R4 TO SCB MOV S.PKT(R4),R1 ;POINT R1 TO I/O PACKET MOV I.PRM+4(R1),R1 ; AND PICK UP CHARACTER COUNT SUB U.CNT(R5),R1 ;CALCULATE CHARACTERS TRANSFERRED MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER TST U.CW3(R5) ;DEVICE ERROR? BPL 70$ ;IF PL NO 65$: MOV #IE.VER&377,R0 ;UNRECOVERABLE HARDWARE ERROR CODE 70$: CALL $IODON ;INITIATE I/O COMPLETION BR PPINI ;BRANCH BACK FOR NEXT REQUEST ; ; DEVICE TIMEOUT RESULTS IN A NOT READY MESSAGE BEING PUT OUT 4 TIMES A ; MINUTE. TIMEOUTS ARE CAUSED BY POWERFAILURE AND PUNCH FAULT CONDITIONS. ; PPOUT: CLRB @S.CSR(R4) ;;;DISABLE PUNCH INTERRUPT MTPS #0 ;;;ALLOW INTERRUPTS 80$: MOV #IE.DNR&377,R0 ;ASSUME DEVICE NOT READY ERROR MOV U.CW2(R5),R1 ;ARE WE WAITING FOR DEVICE READY? BPL 70$ ;IF PL NO, TERMINATE I/O REQUEST MOV #IE.ABO&377,R0 ;ASSUME REQUEST IS TO BE ABORTED ASL R1 ;ABORT REQUEST? BMI 70$ ;IF MI YES TST @S.CSR(R4) ;PUNCH READY? BPL 20$ ;IF PL YES MOV #T.NDNR,R0 ;SET FOR NOT READY MESSAGE MOVB #1,S.CTM(R4) ;SET TIMEOUT FOR 1 SECOND DECB S.STS(R4) ;TIME TO OUTPUT MESSAGE? BNE PPPWF ;IF NE NO MOVB #15.,S.STS(R4) ;SET TO OUTPUT NEXT MESSAGE IN 15. SECONDS CALLR $DVMSG ;OUTPUT MESSAGE .DSABL LSB ; ; CANCEL I/O OPERATION-FORCE I/O TO COMPLETE IF DEVICE IS NOT READY ; PPCAN: CMP R1,I.TCB(R0) ;;;ŒREQUEST FOR CURRENT TASK? BNE 10$ ;;;IF NE NO BIS #ABORT,U.CW2(R5) ;;;SET FOR ABORT IF DEVICE NOT READY 10$: RETURN ;;; .END Œ‘xkQ ›c, .TITLE CRASH .IDENT /05.20/ ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.20 ; ; J. MASSE / P. J. BEZEREDI 24-OCT-77 ; ; PREVIOUSLY MODIFIED BY: ; ; M. B. GROSSMAN ; A. PROTIN ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 2-JUL-79 ; MSH038 -- DON'T WASTE 159. WORDS IF PANIC DUMP ; SUPPORT IS CHOSEN OVER CDA SUPPORT ; ; M. S. HARVEY 2-JUL-79 ; MSH039 -- DON'T RELY ON NXM TRAPS TO STOP RL11 ; MEMORY DUMPING FOR QBUS MACHINES ; ; M. S. HARVEY 7-SEP-79 ; MSH054 -- CLEAN UP AND IMPROVE DOCUMENTATION ; ; M. S. HARVEY 7-SEP-79 ; MSH055 -- DON'T ALLOW DUMPING OFF THE END OF RK05 ; ; M. S. HARVEY 7-SEP-79 ; MSH056 -- SHORTEN SETTLING TIME FOR MT: ; ; M. S. HARVEY 9-SEP-79 ; MSH057 -- PREVENT RK06 ROUTINE FROM CORRUPTING THE ; DISK BY A NXM TRAP ; ; M. S. HARVEY 9-SEP-79 ; MSH058 -- WRITE MEMORY TO TU58 IN 1K WORD SEGMENTS ; AND DO NOT ATTEMPT TO CLEAR R-ONLY REGISTER ; ; M. S. HARVEY 9-SEP-79 ; MSH059 -- FIX TS04 BUGS ; ; M. S. HARVEY 9-SEP-79 ; MSH060 -- CATCH NXM TRAPS FROM CPUS WHERE THE MEMORY ; SIZE REGISTER IS SET HIGHER THAN THE TOP ; OF MEMORY ; ; M. S. HARVEY 2-JUN-80 ; MSH101 -- ENSURE THAT CURRENT MODE IS KERNEL AND ; PREVIOUS MODE IS USER BEFORE ATTEMPTING ; TO READ THE USER MODE STACK POINTER ; ; M. S. HARVEY 20-AUG-80 ; MSH112 -- GLOBALLY DEFINE TRAP INTERCEPT ROUTINE ; ; M. S. HARVEY 22-AUG-80 ; MSH113 -- USE UMR#1 FOR TS11 MEMORY DUMPING ; ; M. S. HARVEY 13-NOV-80 ; MSH125 -- GLOBALIZE $CRALT ; ; M. S. HARVEY 3-MAR-81 ; MSH154 -- CONSOLIDATE POWERFAIL AND CRASH STACKS ; ; P. J. CARR 13-MAR-81 ; PJC015 -- ADD RX01/02 SUPPORT ; ; R. T. PERRON 22-JUL-81 ; RP066 -- CORRECT CRASHING OF EXTENDED MEMORY SYSTEMS ; THRU CONTROLLERS WITHOUT BAE REGISTERS ; ; R. T. PERRON 22-JUL-81 ; RP067 -- CORRECT CONDITIONALIZATION OF TS11 CRASH ; DRIVER TO WORK IN UNMAPPED SYSTEMS ; ; M. S. HARVEY 27-JUL-81 ; MSH181 -- PROVIDE POWERFAIL STACK SPACE FOR SAVING THE ; BPT/T-BIT VECTOR ON LSI11/02 PROCESSORS ; ; M. S. HARVEY 6-NOV-81 ; MSH203 -- ENSURE MULTIPLE DUMP CAPABILITY ON RLV12 ; ; P. J. CARR 23-NOV-81 ; PJC040 -- CORRECT CRASHING TO RX02 FLOPPY DRIVE UNIT #1 ; ; ; CRASH DUMP ROUTINES ; .IF DF C$$RSH ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ; ; LOCAL DATA ;  ; ; $CRUPC::.WORD 0 ; USER PC IS STORED HERE $CRUST::.WORD 0 ; USER PS IS STORED HERE .IF DF C$$CDA .NLIST BEX ; RP066 ;MSH203 .IIF EQ C$$CDA-5 ILDVM=0 ;MSH203 .IIF EQ C$$CDA-11 ILDVM=0 ;MSH203 ;MSH203 .IF DF ILDVM ;MSH203 ;MSH203 ILDEV: .ASCIZ <15><12><12>/CRASH -- ILLEGAL CRASH DEVICE/ ;MSH203 ;MSH203 .ENDC ;MSH203 ;MSH203 IOERR: .ASCIZ <15><12><12>! I/O DEVICE ERROR! CRSMSG: .ASCII <15><12><12>/CRASH -- CONT WITH SCRATCH MEDIA ON / .IIF EQ C$$CDA-1, .ASCII /DT/ .IIF EQ C$$CDA-2, .ASCII /DK/ .IIF EQ C$$CDA-3, .ASCII /MT/ .IIF EQ C$$CDA-4, .ASCII /MM/ .IIF EQ C$$CDA-5, .ASCII /DB/ .IIF EQ C$$CDA-6, .ASCII /DM/ .IIF EQ C$$CDA-7, .ASCII /DL/ .IIF EQ C$$CDA-10, .ASCII /DD/ .IIF EQ C$$CDA-11, .ASCII /DR/ .IIF EQ C$$CDA-12, .ASCII /MS/ .IIF EQ C$$CDA-13, .ASCII /DX/ ; PJC015 .IIF EQ C$$CDA-14, .ASCII /DY/ ; PJC015 UNIT: .ASCIZ /0/<15><12><12> .EVEN .LIST BEX ; RP066  ;MSH203 .IF EQ C$$CDA-4 ;MSH203 ;MSH203 CRBAE: .WORD C$$CSR+34 ;BUS ADDRESS EXTENSION REGISTER ADDR. ;MSH203 ;MSH203 .ENDC ;MSH203 ;MSH203 .IF DF ILDVM ;MSH203 ;MSH203 CRBAE: .WORD C$$CSR+50 ;BUS ADDRESS EXTENSION REGISTER ADDR. ;MSH203 ;MSH203 .ENDC ;MSH203 .ENDC .IF DF C$$TTY .NLIST BEX ; RP066 MSG1: .ASCIZ <15><12><12>/SYSTEM CRASH AT LOCATION / MSG2: .ASCII <15><12><12>/REGISTERS/<15><12><12>  .ASCIZ / R0=/ MSG3: .ASCIZ /R1=/ MSG4: .ASCIZ /R2=/ MSG5: .ASCIZ /R3=/ MSG6: .ASCIZ <15><12><12>/ R4=/ MSG7: .ASCIZ /R5=/ MSG8: .ASCIZ /SP=/ MSG9: .ASCIZ /PS=/<0> MSG10: .ASCII <15><12><12>/SYSTEM STACK DUMP/ .ASCIZ <15><12><12>/ LOCATION CONTENTS/<15><12><12> .EVEN .LIST BEX ; RP066 .ENDC ; *** THE FOLLOWING MUST BE ADJACENT $CRPBF::.BLKW 4 ;STACK AREA FOR SUBROUTINE CALLS $CRSBF::.BLKW 14. ;INTERNAL CRASH STACK ... $CRPST:: ;TOP OF PANIC STACK .IF DF C$$CDA  ;MSH038 .IF DF M$$MGE .BLKW 159. ;... MAPPED STACK IS THIS LARGE .IFF ;MSH154 ;MSH154 UNMAP=0 ;ALLOCATE POWERFAIL STACK IF NECESSARY ;MSH154 ;MSH154 .ENDC ;M$$MGE ;MSH154 ;MSH154 .IFF ;MSH154 ;MSH154 UNMAP=0 ;ALLOCATE POWERFAIL STACK IF NECESSARY ;MSH154 ;MSH154 .ENDC ;C$$CDA ;MSH154 ;MSH154 .IF DF UNMAP&P$$RFL ;MSH154 ;MSH154 .=$CRPBF ;RESET TOP OF POWERFAIL STACK ;MSH154 ;MSH154 .BLKW 7 ;R0 THRU R5 AND SP ;MSH154 ;MSH181 .IF DF L$$SI1 ;MSH181 ;MSH181 .BLKW 1 ;SAVED BPT/T-BIT VECTOR CONTENTS ;MSH181 ;MSH181 .ENDC ;MSH181 ;MSH154 .IF DF M$$MGE ;MSH154 ;MSH154 .IF DF M$$EXT ;MSH154 ;MSH154 .BLKW <31.-5.>*2 ;UNIBUS MAPPING REGISTERS ;MSH154 ;MSH154 .ENDC ;MSH154 ;MSH154 .BLKW 25. ;MEMORY MANAGEMENT REGISTERS ;MSH154 ;MSH154 .IFF ;MSH154 ;MSH154 .IF DF E$$EAE ;MSH154 ;MSH154 .BLKW 3 ;EAE REGISTERS ;MSH154 ;MSH154 .ENDC ;MSH154 ;MSH154 .ENDC ;MSH154 ;MSH154 .IF DF F$$LPP ;MSH154 ;MSH154 .BLKW 27. ;FLOATING POINT REGISTERS ;MSH154 ;MSH154 .ENDC ;MSH154 ;MSH154 .ENDC ;UNMAP&P$$RFL ;MSH154 ;MSH154 ;MSH154 .IF DF C$$CDA ;MSH154 ;**-2 $CRSST==.-2 ;TOP OF CRASH STACK ; *** ABOVE MUST BE ADJACENT ;**-2 $CRSBN::.WORD PBNH,PBNL ;STARTING DEVICE ADDRESS $CRSCS::.WORD PBNH+PBNL ;CHECKSUM OF DEVICE ADDRESS ; ; LOCAL MACROS ; .MACRO PUSH ARG SUB #2,SP MOV ARG,(SP) .ENDM PUSH .ENDC .ENDC ;+ ;MSH112 ; **-$TRINT-TRAP INTERCEPT ROUTINE ;MSH112 ; ;MSH112 ; THE ENTRY POINT OF THIS ROUTINE IS USED TO PLUG VECTORS TO TRAP ;MSH112 ; ANY TRAPS THROUGH 4, ILLEGAL INSTRUCTION TRAPS, ETC. ;MSH112  ; ;MSH112 ; INPUTS: ;MSH112 ; ;MSH112 ; NONE ;MSH112 ; ;MSH112 ; OUTPUTS: ;MSH112 ; ;MSH112 ; 2(SP) = PS OF TRAP. THIS ROUTINE SETS THE C-BIT, THEN ;MSH112 ; RETURNS FROM THE TRAP WITH AN RTI. ;MSH112 ;- ;MSH112 ;MSH112 $TRINT::BIS #1,2(SP) ;SET CARRY IN TRAP PS ;MSH112 RTI ;RETURN FROM TRAP ;MSH112 ;MSH112 ;+ ; **-$CRASH-SYSTEM CRASH DUMP ROUTINE ; ; THIS ROUTINE IS ENTERED VIA A JUMP WHENEVER A FATAL SYSTEM ERROR ; (IOT) IS DETECTED. ; ; THIS ROUTINE PERFORMS A MEMORY DUMP THAT CAN BE DIRECTED TO A ; HARD COPY DEVICE, DECTAPE, RK05, TU10, TU/E16 OR TU45/77, RP04/5/6, ; RP066 ; RK06/7, RL01/2, TU58, RM02/3/5, TS11, OR RX01/2. ; RP066 ; ONCE THE DUMP IS FINISHED THE SYSTEM MAY BE ;**-2 ; RE-BOOTED OR ANOTHER DUMP MAY BE TAKEN. IF THE DUMP IS DIRECTED ; TO A HARD COPY DEVICE THE DUMP WILL CONTAIN ONLY THE REGISTER ; CONTENTS AND THE SYSTEM STACK. ; ; INPUTS: ; ; 02(SP)=PS WORD AT CRASH. ; 00(SP)=PC WORD AT CRASH. ; ; OUTPUTS: ; ; THE INTERNAL CRASH STACK AND A CORE IMAGE OF THE SYSTEM, ; UP TO 128K, ARE DUMPED ONTO THE MASS STORAGE CRASH DUMP DEVICE. ; THE REGISTER CONTENTS AND THE SYSTEM STACK ARE DUMPED IF A ; HARD COPY DUMP IS REGUESTED. ;- ;**-6 $CRASH:: ;CRASH DUMP ROUTINE ;**-1 .IF DF C$$RSH ;MSH125 MOV (SP)+,$CRUPC ; SAVE USER PC FROM THE STACK ;**-1 MOV (SP)+,$CRUST ; SAVE USER PS FROM THE STACK ;MSH125 .IFTF  ;MSH125 ;MSH125 $CRALT:: ;MSH125 .IFT ;MSH125 ;**-2 .IF DF C$$TTY MOV $CRUPC,$CRPBF ; MOV R0,$CRPBF+2 ;SAVE R0 MOV #$CRPBF+4,R0 ;SET UP SAVE AREA MOV R1,(R0)+ ;SAVE R1 THRU R5 MOV R2,(R0)+ ; MOV R3,(R0)+ ; MOV R4,(R0)+ ; MOV R5,(R0)+ ; MOV $CRUST,2(R0) ; MOV SP,(R0) ;SAVE SP MOV #$CRPST,SP ;SETUP TEMPORARY STACK MOV #C$$TTY,R5 ;SPECIFY OUTPUT DEVICE CSR MOV #$CRPBF,R1 ;POINT TO DATA VECTOR MOV #MSG1,R4 ;POINT TO MESSAGE TEXT 1$: MOVB (R4)+,R2 ;GET A BYTE OF MESSAGE BEQ 5$ ;IF EQ AT MESSAGE BREAK BR 3$ ;ELSE ALREADY HAVE A BYTE 2$: MOVB (R4)+,R2 ;GET A BYTE OF MESSAGE BEQ 4$ ;IF EQ END OF THIS MESSAGE 3$: CALL $OUT ;OUTPUT THIS CHARACTER BR 2$ ;GO AGAIN 4$: MOV (R1)+,R3 ;GET DATA WORD CALL $EDIT ;PRINT IN PLACE BR 1$ ;GET NEXT MESSAGE 5$: MOVB (R4)+,R2 ;GET NEXT CHARACTER TO OUTPUT BEQ 6$ ;IF EQ END OF STRING CALL $OUT ;OUTPUT CHARACTER BR 5$ ;GO AGAIN 6$: MOV $CRPBF+16,R1 ;POINT TO BOTTOM OF SYSTEM STACK 7$: MOV R1,R3 ;SET ADDRESS OF LOCATION TO EDIT CALL 8$ ;EDIT ADDRESS MOV (R1)+,R3 ;GET CONTENTS OF LOCATION CALL 8$ ;EDIT CONTENTS CALL $CRLF ;ISSUE CARRIAGE RETURN, LINE FEED CMP R1,#$STACK ;END OF SYSTEM STACK? BLO 7$ ;IF LO NO MOV #$CRPBF+16,R0 ;POINT TO SAVED STACK POINTER MOV (R0),SP ;RESTORE SP MOV -(R0),R5 ;RESTORE R5 THRU R0 MOV -(R0),R4 ; MOV -(R0),R3 ; MOV -(R0),R2 ; MOV -(R0),R1 ; MOV -(R0),R0 ; BR 9$ ;BR AROUND SUBROUTINE 8$: CALL $OUTB ;OUTPUT TWO BLANKS CALL $OUTB ; CALLR $EDIT ;PRINT CONTENTS OF R3 AND RETURN 9$: ;REF LABEL .ENDC .IF DF C$$CDA MOV #$TRINT,@#4 ;SET UP TO SET CARRY ON TRAPS THRU 4 ;MSH112 ;**-2 .IF DF L$$SI1 CLR $CRSST ;CLEAR PS STORAGE WORD MFPS $CRSST ;STORE LOW BYTE OF PS MTPS #PR7 ;LOCK OUT INTERRUPTS .IFF MOV PS,$CRSST ;STORE FULL PS ;MSH101 .IF DF M$$MGE ;MSH101 ;MSH101 MOV #PMODE!PR7,@#PS ;LOCK OUT INTERRUPTS AND SET ;MSH101 ;PREVIOUS MODE=USER, CURRENT MODE=KERNEL;MSH101 .IFF ;MSH101 ;MSH101 MOVB #PR7,PS ;LOCK OUT INTERRUPTS ;MSH101 .ENDC ;MSH101 .ENDC MOV SP,$CRSST-2 ;;;SAVE SP MOV $CRUPC,$CRSST-4 ;;;SAVE PC BEFORE IOT CRASH MOV $CRUST,$CRSST-6 ;;;SAVE PS BEFORE IOT CRASH MOV #$CRSST-6,SP ;;;RESET SP TO INTERNAL STACK .IF DF M$$MGE MFPI SP ;;;SAVE USER'S SP .IFF CLR -(SP) ;;;NO USER SP IF UNMAPPED .IFTF MOV R0,-(SP) ;;;SAVE REGISTER SET 1 MOV R1,-(SP) ;;;  MOV R2,-(SP) ;;; MOV R3,-(SP) ;;; MOV R4,-(SP) ;;; MOV R5,-(SP) ;;; .IFT PUSH SR0 ;;;SAVE MEMORY MANAGEMENT REGISTERS PUSH SR0+2 ;;; PUSH SR0+4 ;;; PUSH SR3 ;;; BIC #67,SR3 ;;;DISABLE UNIBUS MAP AND D-SPACE MOV #UISDR0,R0 ;;;SETUP TO SAVE FIRST SET OF APR'S MOV #32.,R1 ;;; 10$: PUSH (R0) ;;;SAVE APR ADD #2,R0 ;;;MOVE TO NEXT ONE DEC R1 ;;;DONE YET? BNE 10$ ;;;IF NE NO MOV #SISDR0,R0 ;;;SETUP TO SAVE SECOND SET OF APR'S MOV #64.,R1 ;;; 20$: PUSH (R0) ;;;SAVE APR ADD #2,R0 ;;;MOVE TO NEXT ONE DEC R1 ;;;DONE YET? BNE 20$ ;;;IF NE NO MOV #UBMPR,R0 ;;;GET ADDRESS OF FIRST UMR MOV #62.,R1 ;;;NUMBER OF UMR'S TO SAVE 30$: PUSH (R0) ;;;SAVE A UMR ADD #2,R0 ;;;MOVE TO NEXT ONE DEC R1 ;;;DONE YET? BNE 30$ ;;;IF NE NO .ENDC ; ; TYPE MESSAGE AND WAIT FOR USER ; AGAIN: MOV $CRSUN,R0 ;;;GET CRASH UNIT NUMBER ADD #'0,R0 ;;;ADD ASCII BIAS MOVB R0,UNIT ;;;MOVE IT INTO TEXT STRING MOV #CRSMSG,R1 ;;;TYPE USER MESSAGE CALL TYPE ;;;TYPE OUT MESSAGE BR $CRSHT ;;;BRANCH TO BEFORE UNIT # STORAGE TYPE: MOV #C$$RSH,R5 ;;;GET CSR ADD. OF PRINT DEVICE 10$: MOVB (R1)+,R2 ;;;GET CHARACTER BEQ 20$ ;;;IF EQ FINISHED CALL $OUT ;;;OUTPUT THE CHARACTER BR 10$ ;;;LOOP FOR MORE 20$: RETURN ;;;RETURN TO CALLER $CRSHT:: HALT ;;;WAIT FOR USER BR DUMP ;;;AFTER CONTINUE - PROCEED WITH DUMP ; ; FOR CONVENIENCE THE CRASH DEVICE UNIT NUMBER IS STORED ; HERE SO THAT THE CONSOLE DISPLAY +2 WILL GIVE THE ; ADDRESS OF THE NEXT WORD, THUS ALLOWING THE USER TO PATCH ; A DIFFERENT UNIT NUMBER (IGNORING THE PRINTOUT). ; $CRSUN::.WORD C$$RUN ;;;CRASH UNIT NUMBER (DEFAULT=0) ;+ ; **-CKSUM-VERIFY CHECKSUM OF DEVICE ADDRESS ; ; THIS ROUTINE WILL VERIFY THAT THE DEVICE ADDRESS FOR THE RK11 ; AND TC11 HAS NOT BEEN CORRUPTED BY THE CRASH. ;- CKSUM: MOV $CRSBN,-(SP) ;;;GET HIGH ORDER BITS ADD $CRSBN+2,(SP) ;;;ADD LOW ORDER BITS CMP (SP)+,$CRSCS ;;;COMPARE WITH CHECKSUM BEQ 10$ ;;;IF EQ OK HALT ;;;WAIT FOR USER  BR CKSUM ;;;TRY AGAIN 10$: RETURN ;;; ;+ ; **-DUMP-DUMP THE SYSTEM IMAGE ; ; THIS ROUTINE IS USED TO DUMP THE INTERNAL CRASH STACK ; AND THE SYSTEM IMAGE ONTO A SCTATCH DUMP MEDIA. WHEN THE DUMP ; IS FINISHED THE SYSTEM IS EITHER RE-BOOTED OR THE USER IS ASKED ; IF HE WANTS TO DUMP ANOTHER COPY OF THE IMAGE. ; ; INPUTS: ; NONE. ; ; OUTUTS: ; IMAGE DUMPED. ;- DUMP: ;;;DUMP IMAGE ONTO MEDIA MOV #C$$CSR,R0 ;;;GET CSR ADDRESS OF DUMP DEVICE MOV $CRSUN,R3 ;;;GET UNIT NUMBER  .IF EQ C$$CDA-1 ; ;MSH054 ; DT ;MSH054 ; ;MSH054 ; THIS ROUTINE DUMPS ALL OF PHYSICAL MEMORY UP TO A MAXIMUM OF ;MSH054 ; 124K WORDS ;MSH054 ; ;MSH054 PBNH= 0 ;;;HIGH ORDER TC11 BLOCK NUMBER PBNL= 1 ;;;LOW ORDER TC11 BLOCK NUMBER CALL CKSUM ;;;CHECK BLOCK NUMBER AGAINST CHECKSUM SWAB R3 ;;;POSITION UNIT BITS MOV R3,R1 ;;;COPY BIS #4003,R1 ;;;SET FOR READ LBN IN REVERSE MOV R1,(R0) ;;;START THE TAPE 10$: BIT #100200,(R0) ;;;ERROR OR READY? BEQ 10$ ;;;IF EQ NO BPL DUMP ;;;IF PL MOVE UNTIL ENDZONE 20$: MOV R3,R1 ;;;RETREIVE UNIT BITS BIS #3,R1 ;;;SET TO READ LBN FORWARD MOV R1,(R0) ;;;START THE TAPE 30$: BIT #100200,(R0) ;;;ERROR OR READY? BMI DUMP ;;;IF MI ERROR, RESTART BEQ 30$ ;;;IF EQ WAIT SUB $CRSBN+2,6(R0) ;;;ARE WE AT THE BLOCK WE WANT? BNE 20$ ;;;IF NE NO CLR 2(R0) ;;;SET TO WRITE ALL MEMORY CLR 4(R0) ;;; MOV R3,R1 ;;;RETREIVE UNIT BITS BIS #15,R1 ;;;SET TO WRITE DATA FORWARD MOV R1,(R0) ;;;WRITE THE BLOCK 50$: CLR 2(R0) ;;;KEEP WRITING TST (R0) ;;;ANY ERRORS? BPL 50$ ;;;IF PL NO BIT #400,-2(R0) ;;;NON-EXISTANT MEMORY? BEQ WERR ;;;IF EQ NO, RETRY BIS #1,R3 ;;;SET TO STOP TAPE MOV R3,(R0) ;;;STOP TAPE BR $CRCMP ;;;SUCCESS, FINISH .ENDC .IF EQ C$$CDA-2 ;MSH054 ; ;MSH054 ; DK ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE DOES NOT SUPPORT 22-BIT ADDRESSING, THIS ;MSH054 ; ROUTINE DUMPS ALL OF PHYSICAL MEMORY UP TO A MAXIMUM OF ;MSH054 ; 124K WORDS. ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE SUPPORTS 22-BIT ADDRESSING, THIS ROUTINE ;MSH054 ; DUMPS ALL OF PHYSICAL MEMORY UP TO A MAXIMUM OF APPROXIMATELY ;MSH054 ; 1.2 MEGAWORDS OF MEMORY (FILLS UP THE RK05). ;MSH054 ; ;MSH054 PBNH= 0 ;;;HIGH ORDER RK11 DISK ADDRESS PBNL= 001 ;;;LOW ORDER RK11 DISK ADDRESS CALL CKSUM ;;;CHECK DISK ADDRESS AGAINST CHECKSUM CLC ;;;SET TO POSITION UNIT BITS ROR R3 ;;; ROR R3 ;;; ROR R3 ;;; ROR R3 ;;; MOV #401,(R0) ;;;RESET RK11 CONTROLLER BIS $CRSBN+2,R3 ;;;SET STARTING DISK ADDRESS MOV R3,6(R0) ;;;SET DISK ADDRESS .IF NDF M$$EXT CLR 4(R0) ;;;SETUP TO WRITE ALL MEMORY CLR 2(R0) ;;; MOV #403,(R0) ;;;START THE WRITE 20$: CLR 2(R0) ;;;KEEP WRITING TST (R0) ;;;ANY ERROR BITS SET? BPL 20$ ;;;IF PL NO BIT #2000,-2(R0) ;;;NON-EXISTANT MEMORY? BNE $CRCMP ;;;IF NE YES, FINISHED .IFF CLR UBMPR ;;;INITIALIZE FIRST UNIBUS MAPPING REGISTER CLR UBMPR+2 ;;; CLR KISAR0 ;;; BIS #60,SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP BIS #1,SR0 ;;;MAKE SURE MEM MGMT IS ON 40$: MOV 6(R0),R3 ;;;GET DISK ADDRESS ;MSH055 BIC #160017,R3 ;;;EXTRACT CYLINDER AND SURFACE ;MSH055 CMP #14420,R3 ;;;ABOUT TO WRITE TO CYLINDER THAT ;MSH055 ;;;CANNOT ORDINARILY BE READ? ;MSH055 BEQ $CRCMP ;;;IF EQ YES, STOP WRITING ;MSH055 CLR 4(R0) ;;;INITIALIZE TRANSFER ADDRESS ;MSH055 MOV #-6000,2(R0) ;;;WRITE 3K WORDS (1 CYLINDER) ;MSH055 MOV #403,(R0) ;;;START THE WRITE ;**-2 45$: BIT #100200,(R0) ;;;ERROR OR READY? BEQ 45$ ;;;IF EQ NO BMI 50$ ;;;IF MI ERROR ADD #14000,@#UBMPR ;;;POINT TO NEXT 3K WORD SEGMENT ;MSH055 ADC UBMPR+2 ;;;DOUBLE WORD ADD ;**-1 BR 40$ ;;;GO AGAIN UNTIL END OF MEMORY 50$: BIT #2000,-2(R0) ;;;NON EXISTENT MEMORY? BNE $CRCMP ;;;YES IF NE HALT .ENDC .ENDC .IF EQ C$$CDA-3 ;MSH054 ; ;MSH054 ; MT ;MSH054 ; ;MSH054 ; THIS ROUTINE DUMPS ALL OF PHYSICAL MEMORY (UP TO A MAXIMUM ;MSH054 ; OF 124K WORDS) IN 512 BYTE RECORDS AT 800 BPI (9-TRACK) ;MSH054 ; ;MSH054 PBNH= 0 ;BLOCK NUMBER IGNORED FOR TM11 PBNL= 0 ; SWAB R3 ;;;POSITION UNIT SELECT BITS BIS #60001,R3 ;;;MERGE DENSITY AND GO BITS MOV R3,R2 ;;;COPY BIS #16,R2 ;;;SET REWIND FUNCTION MOV R2,(R0) ;;;START THE REWIND 10$: BIT #100200,(R0) ;;;ERROR OR READY? BMI WERR ;;;IF MI ERROR, RETRY BEQ 10$ ;;;IF EQ NO CLR (R0) ;;;CLEAR MTC REGISTER CLR 4(R0) ;;;START TO WRITE ALL OF MEMORY MOV R3,R2 ;;;RETREIVE MTC BITS BIS #4,R2 ;;;SET WRITE DATA FUNCTION BIC #1,R2 ;;;CLEAR GO BIT MOV R2,(R0) ;;;START THE WRITE 30$: MOV #500,R1 ;;;WAIT FOR TAPE TO SETTLE DOWN ;MSH056 35$: DEC R1 ;;;WAIT ;**-1 BNE 35$ ;;;IF NE LOOP MOV #-512.,2(R0) ;;;SET 512. BYTE RECORDS BIS #1,(R0) ;;;START THE WRITE 40$: BIT #100200,(R0) ;;;ERROR OR READY? BEQ 40$ ;;;IF EQ NO BPL 30$ ;;;IF PL WRITE FINISHED TSTB -2(R0) ;;;NON-EXISTANT MEMORY? BPL WERR ;;;IF PL NO, RETRY MOV R3,R2 ;;;RETREIVE MTC BITS BIS #10000,R2 ;;;SET CLEAR FUNCTION MOV R2,(R0) ;;;LOAD FUNCTION 50$: TSTB (R0) ;;;READY? BPL 50$ ;;;IF PL NO BIS #6,R3 ;;;SET WRITE EOF FUNCTION MOV R3,(R0) ;;;DO THE WRITE EOF 60$: TSTB (R0) ;;;READY? BPL 60$ ;;;IF PL NO CLR (R0) ;;;CLEAR MTC REGISTER BR $CRCMP ;;;SUCCESSFUL COMPLETION .ENDC .IF EQ C$$CDA-4 ;MSH054 ; ;MSH054 ; MM ;MSH054 ; ;MSH054 ; THIS ROUTINE DUMPS ALL OF PHYSICAL MEMORY IN 512 BYTE ;MSH054 ; RECORDS AT 800 BPI ;MSH054 ; ;MSH054 PBNH= 0 ;BLOCK NUMBER IGNORED FOR TJU16 PBNL= 0 ; ; RP066 ; RP066 .IF DF M$$EXT ; RP066 ; RP066 MOV CRBAE,R1 ;;;GET BAE REGISTER ADDRESS ;MSH203 BEQ 3$ ;;;IF EQ DOES NOT EXIST ;MSH203 TST (R1) ;;;DOES IT EXIST ;MSH203 BCC 5$ ;;;IF CC YES, USE IT ;MSH203 CLR CRBAE ;;;INHIBIT REFERENCING OF REGISTER ;MSH203 3$: CLR @#UBMPR ;;;INITIALIZE FIRST UNIBUS ... ;MSH203 CLR @#UBMPR+2 ;;;... MAPPING REGISTERS ; RP066 5$: BIS #60,@#SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP ; RP066 BIS #1,@#SR0 ;;;MAKE SURE MEM MGNT IS ON ; RP066 MOV #<4*4>,R5 ;;;NUMBER OF 512 BYTE RECORDS/4K BLOCK ; RP066 ; RP066 .ENDC ;M$$EXT ; RP066 ; RP066 ; RP066 BIS (PC)+,R3 ;;;SET MODE AND DENSITY $TDNSY::.WORD 1300 ;;;DEFAULT TO 800 BPI, NORMAL MODE ;MSH054 BIS #40,10(R0) ;;;RESET CONTROLLER ;**-1 10$: TSTB 12(R0) ;;;IS THE TAPE DRIVE READY? BPL 10$ ;;;IF PL NO MOV R3,32(R0) ;;;SET FORMAT BITS MOV #7,(R0) ;;;START THE TAPE REWINDING MOV #40000,R1 ;;;DELAY UNTIL REWIND OPERATION ;MSH054 15$: DEC R1 ;;;IS ACTUALLY IN PROGRESS ;MSH054 BNE 15$ ;;; ;**-2 20$: BIT #20000,12(R0) ;;;POSITIONING STILL IN PROGRESS? BNE 20$ ;;;IF NE YES TSTB 12(R0) ;;;DRIVE READY? BPL 20$ ;;;IF PL NO MOV #60,(R0) ;;;LOAD THE WRITE FUNCTION CLR 4(R0) ;;;SET TO WRITE ALL OF MEMORY 40$: MOV #-256.,2(R0) ;;;SET WORD COUNT MOV #-512.,6(R0) ;;;SET FRAME COUNT BIS #1,(R0) ;;;START TO WRITE ALL OF MEMORY 50$: TSTB 12(R0) ;;;DRIVE READY? BPL 50$ ;;;IF PL NO BIT #40000,(R0) ;;;TRANSFER ERRORS? BNE 60$ ;;;IF NE YES ; RP066 ; RP066 ; RP066 .IF DF M$$EXT ; RP066 ; RP066 DEC R5 ;;;DECREMENT BLOCK COUNT ; RP066 BNE 40$ ;;;IF NE USE SAME UMR ; RP066 TST CRBAE ;;;IS THE BAE REGISTER THERE? ;MSH203 BNE 55$ ;;;IF NE YES ;MSH203 ADD #20000,@#UBMPR ;;;NO, POINT UMR TO NEXT 4K OF MEMORY ; RP066 ADC @#UBMPR+2 ;;;DOUBLE WORD ADD ; RP066 CLR 4(R0) ;;;AND RESET BUS ADDRESS ; RP066 55$: MOV #<4*4>,R5 ;;;RESET TO # BLOCKS PER 4K ; RP066 ; RP066 .ENDC ;M$$EXT ; RP066 ; RP066 ; RP066 BR 40$ ;;;CONTINUE XFER ; RP066 60$: BIT #4000,10(R0) ;;;NONEXISTENT MEMORY ; RP066 BEQ WERR ;;;IF EQ NO, RETRY ; RP066 BIS #40,10(R0) ;;;RESET CONTROLLER ;**-3 65$: TSTB 12(R0) ;;;DRIVE READY? ; RP066 BPL 65$ ;;;IF PL NO ; RP066 MOV R3,32(R0) ;;;RESET FORMAT BITS ;**-2  MOV #27,(R0) ;;;WRITE EOF ON TAPE 70$: TSTB 12(R0) ;;;IS DRIVE READY? BPL 70$ ;;;IF PL NO CLR (R0) ;;;CLEAR CONTROLLER REGISTER BR $CRCMP ;;;SUCCESSFUL COMPLETION .ENDC ; RP066 ; RP066 .IIF EQ C$$CDA-5 CDA$DB=0 ; RP066 ; RP066 .IIF EQ C$$CDA-11 CDA$DR=0 ; RP066 .IF DF CDA$DB!CDA$DR ; RP066 ;MSH054 ; ;MSH054 ; DB AND DR ;MSH054 ; ;MSH054 ; THIS ROUTINE DUMPS ALL OF PHYSICAL MEMORY ;MSH054 ;  ;MSH054 ;MSH054 ;**-1 PBNH= 0 ;;;RP04/5/6 OR RM02/3/5 DEFAULT CYL. ADD; RP066 PBNL= 1 ;;;DEFAULT TRACK AND SECTOR ADD. ;**-1 CALL CKSUM ;;;CHECK DISK ADDRESS AGAINST CHECKSUM MOV 26(R0),R1 ;;;RETRIEVE DEVICE TYPE REGISTER ; RP066 BIC #^C<777>,R1 ;;;CLR EXTRANEOUS BITS ; RP066 CMP #25,R1 ;;;IS IT RP04/5/6 OR RM02/3? ; RP066 BHIS 10$ ;;;IF HIS YES ; RP066 CMP #27,R1 ;;;IS IT RM05? ; RP066 BEQ 10$ ;;;IF EQ YES ; RP066 MOV #ILDEV,R1 ;;;NO, ILLEGAL DEVICE ; RP066 CALL TYPE ;;;PRINT MESSAGE ; RP066 BR AGAIN ;;;TRY AGAIN ; RP066 10$: ;;;REF LABEL ; RP066 ; RP066 ; RP066 .IF DF M$$EXT ; RP066 ; RP066 MOV CRBAE,R1 ;;;GET BAE REGISTER ADDRESS ;MSH203 BEQ 18$ ;;;IF EQ DOES NOT EXIST ;MSH203 TST (R1) ;;;BAE REGISTER EXIST? ;MSH203 BCC 20$ ;;;IF CC YES, USE IT ;MSH203 CLR CRBAE ;;;INHIBIT REFERENCING OF REGISTER ;MSH203 18$: CLR @#UBMPR ;;;INITIALIZE FIRST UNIBUS ... ;MSH203 CLR @#UBMPR+2 ;;;... MAPPING REGISTERS ; RP066 20$: BIS #60,@#SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP ; RP066 BIS #1,@#SR0 ;;;MAKE SURE MEM MGNT IS ON ; RP066 MOV #<4*4>,R5 ;;;NUMBER OF 512 BYTE SECTORS/4K BLOCK ; RP066 ; RP066 .ENDC ;M$$EXT ; RP066 ; RP066 ; RP066 ADD #10,R0 ;;;POINT TO RCS2 MOV #40,(R0) ;;;CLEAR CONTROLLER BIS R3,(R0) ;;;SELECT UNIT MOV #23,-10(R0) ;;;DO A PACK ACKNOWLEDGE MOV $CRSBN,24(R0) ;;;SELECT CYLINDER MOV $CRSBN+2,-(R0) ;;;SET SECTOR AND TRACK CLR -(R0) ;;;ZERO BUFFER ADDRESS MOV #14000,26(R0) ;;;SET 16 BIT FORMAT CMP -(R0),-(R0) ;;;POINT TO CSR 30$: MOV #-256.,2(R0) ;;;WORD COUNT = 1 SECTOR ; RP066 BIC #77,(R0) ;;;CLEAR FUNCTION CODE ;**-1 BIS #61,(R0) ;;;EXECUTE A WRITE 40$: BIT #100200,(R0) ;;;READY OR ERROR? ; RP066 BEQ 40$ ;;;IF EQ NO ; RP066 BIT #40000,(R0) ;;;TRANSFER ERROR? ; RP066 BNE 60$ ;;;IF NE YES ; RP066 ; RP066 .IF DF M$$EXT ; RP066 ; RP066 DEC R5 ;;;DECREMENT BLOCK COUNT ; RP066 BNE 30$ ;;;IF NE USE SAME UMR ; RP066 TST CRBAE ;;;BAE REGISTER THERE? ;MSH203 BNE 50$ ;;;IF NE YES ;MSH203 ADD #20000,@#UBMPR ;;;NO, POINT UMR TO NEXT 4K OF MEMORY ; RP066 ADC @#UBMPR+2 ;;;DOUBLE WORD ADD ; RP066 CLR 4(R0) ;;;AND RESET BUS ADDRESS ; RP066 50$: MOV #<4*4>,R5 ;;;RESET TO # SECTORS PER 4K ; RP066 ; RP066 .ENDC ;M$$EXT ; RP066 ; RP066 ; RP066 BR 30$ ;;;CONTINUE XFER ; RP066 60$: BIT #4000,10(R0) ;;;NON-EXISTENT MEMORY ERROR? ; RP066 BNE $CRCMP ;;;IF NE YES, ELSE I/O ERROR ; RP066 ;**-6 .ENDC .IF EQ C$$CDA-6 ;MSH054 ; ;MSH054 ; DM ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE DOES NOT SUPPORT 22-BIT ADDRESSING, THIS ;MSH054 ; ROUTINE DUMPS ALL OOF PHYSICAL MEMORY UP TO A MAXIMUM OF ;MSH054 ; 124K WORDS. ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE SUPPORTS 22-BIT ADDRESSING, THIS ROUTINE ;MSH054 ; DUMPS ALL OF PHYSICAL MEMORY. ;MSH054 ; ;MSH054 ; NOTE THAT THE STANDARD METHOD OF DUMPING ALL OF PHYSICAL ;MSH057 ; MEMORY (DUMPING UNTIL THE CONTROLLER DETECTS NONEXISTENT ;MSH057 ; MEMORY) DOES NOT WORK, BECAUSE THE RK611 WRITES AN UNCORRECTABLE ;MSH057 ; ECC ERROR IN THE LAST SECTOR IT WRITES UNDER THOSE CONDITIONS. ;MSH057 ; ;MSH057 PBNH= 0 ;;;RK06 DEFAULT CYLINDER ADDRESS PBNL= 1 ;;;DEFAULT SECTOR AND TRACK ADDRESS MOV #$TRINT,@#114 ;;;POSITION TRAP CATCHER FOR NON- ;MSH060 ;;;EXISTENT MEMORY TRAPS WHEN SIZE ;MSH060 ;;;REGISTER > SIZE OF MEMORY ;MSH060 CALL CKSUM ;;;CHECK BLOCK NUMBER AGAINST CHECKSUM CLR R2 ;;;ASSUME DRIVE IS AN RK06 MOV #40,10(R0) ;;;CLEAR THE RK611 SUBSYSTEM MOV R3,10(R0) ;;;SELECT THE UNIT MOV #1,(R0) ;;;SELECT THE DRIVE FUNCTION 10$: TSTB (R0) ;;;READY? BPL 10$ ;;;IF PL NO BIT #400,12(R0) ;;;IF THIS AN RK07? BEQ 20$ ;;;IF EQ NO, IT'S AN RK06 BIS #2000,R2 ;;;SET RK07 BIT 20$: MOV #40,10(R0) ;;;CLEAR THE RK611 SUBSYSTEM MOV R3,10(R0) ;;;SELECT THE UNIT MOV R2,R1 ;;;COPY DRIVE TYPE BIT BIS #3,R1 ;;;GET PACK ACK FUNCTION CODE MOV R1,(R0) ;;;DO A PACK ACKNOWLEDGE 30$: TSTB (R0) ;;;READY? BPL 30$ ;;;IF PL NO MOV 12(R0),R1 ;;;GET DRIVE STATUS COM R1 ;;;COMPLEMENT BIT #100301,R1 ;;;DRIVE READY TO GO? BNE WERR ;;;IF NE NO, TRY AGAIN MOV $CRSBN,20(R0) ;;;LOAD CYLINDER MOV $CRSBN+2,6(R0) ;;;LOAD SECTOR/TRACK BIS #23,R2 ;;;SET WRITE FUNCTION .IF DF M$$EXT CLR UBMPR ;;;INITIALIZE FIRST UNIBUS MAPPING REG. CLR UBMPR+2 ;;; CLR KISAR0 ;;; BIS #60,SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP BIS #1,SR0 ;;;MAKE SURE MEM MGMT IS ON ;MSH057 .IFTF ;M$$EXT ;MSH057 ;MSH057 .IF DF M$$MGE ;MSH057 ;MSH057 MOV #140000,R5 ;;;SET TO MAP THROUGH APR6 ;MSH057 CLR @#KISAR6 ;;;POINT TO FIRST BYTE OF 1K SEGMENT ;MSH057 ;MSH057 .IFF ;M$$MGE ;MSH057 ;MSH057 CLR R5 ;;;R5 TRACKS THE DUMP PROCESS ;MSH057 ;MSH057 .ENDC ;M$$MGE ;MSH057 ;MSH057 .IFT ;M$$EXT ;MSH057 ;MSH057 50$: CLR 4(R0) ;;;START AT BEGINNING OF UNIBUS MAP ;MSH057 ;MSH057 .IFF ;M$$EXT ;MSH057 ;MSH057 CLR 4(R0) ;;;START AT BEGINNING OF MEMORY ;MSH057 50$: ;;;REF LABEL ;MSH057 ;MSH057 .IFTF ;M$$EXT ;MSH057 ;MSH057 MOV #-2000,2(R0) ;;;WRITE 1K WORDS PER TRANSFER ;MSH057 BIS R2,(R0) ;;;START WRITING ;**-10 60$: BIT #100200,(R0) ;;;READY OR ERROR? BEQ 60$ ;;;IF EQ NEITHER BMI 80$ ;;;IF MI ERROR ;MSH057 ;MSH057 .IFT ;M$$EXT ;MSH057 ;MSH057 ADD #4000,@#UBMPR ;;;POINT TO NEXT 1K WORD BOUNDARY ;MSH057 ADC @#UBMPR+2 ;;;DON'T FORGET THE CARRY ;MSH057 ADD #40,@#KISAR6 ;;;ADJUST DUMP TRACKING POINTER ;MSH057 CMP #170000,@#KISAR6 ;;;HAVE WE HIT THE I/O PAGE? ;MSH057 ;MSH057 .IFF ;M$$EXT ;MSH057 ;MSH057 .IF DF M$$MGE ;MSH057 ;MSH057 ADD #40,@#KISAR6 ;;;ADJUST DUMP TRACKING POINTER ;MSH057 CMP #7600,@#KISAR6 ;;;HAVE WE HIT THE I/O PAGE? ;MSH057 ;MSH057 .IFF ;M$$MGE ;MSH057 ;MSH057 ADD #4000,R5 ;;;ADJUST DUMP TRACKING POINTER ;MSH057 CMP #160000,R5 ;;;HAVE WE HIT THE I/O PAGE? ;MSH057 ;MSH057 .ENDC ;M$$MGE ;MSH057 ;MSH057 .ENDC ;M$$EXT ;MSH057 ;MSH057 BEQ $CRCMP ;;;IF EQ YES, DUMP IS DONE ;MSH057 TST (R5) ;;;DOES FIRST WORD OF NEXT TRANSFER EXIS;MSH057 BCC 50$ ;;;IF CC YES ;MSH057 BR $CRCMP ;;;IF CS NO, DUMP IS DONE ;MSH057 80$: ;;;REF LABEL ;MSH057 ;**-14 .ENDC .IF EQ C$$CDA-7 ;MSH054 ; ;MSH054 ; DL ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE DOES NOT SUPPORT 22-BIT ADDRESSING, THIS ROUTINE ;MSH054 ; DUMPS ALL OF PHYSICAL MEMORY UP TO A MAXIMUM OF 124K WORDS FOR A ;MSH054 ; MAPPED SYSTEM AND 28K WORDS FOR AN UNMAPPED SYSTEM. ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE SUPPORTS 22-BIT ADDRESSING, THIS ROUTINE ;MSH054 ; DUMPS ALL OF PHYSICAL MEMORY. ;MSH054 ; ;MSH054 ; NOTE THAT THE STANDARD METHOD OF DUMPING ALL OF PHYSICAL ;MSH039 ; MEMORY (DUMP MEMORY UNTIL THE CONTROLLER DETECTS NONEXISTENT ;MSH039 ; MEMORY) DOES NOT WORK ON A Q-BUS CPU WHERE SOME MEMORY IS UNUSED ;MSH039 ; BECAUSE IT "OVERLAPS" THE I/O PAGE. FOR EXAMPLE, A 124K WORD CPU ;MSH039 ; WITH FOUR 32K WORD MEMORY BOARDS. UNDER THOSE CIRCUMSTANCES, ;MSH039 ; BECAUSE THE RL01/02 CONTROLLER DOES NOT ASSERT THE Q-BUS SIGNAL ;MSH039 ; DECLARING AN I/O PAGE ADDRESS TO BE AN I/O PAGE ADDRESS, THE ;MSH039 ; MEMORY WILL ANSWER I/O PAGE ADDRESSES. ;MSH039 ; ;MSH039 PBNH= 0 ;;;NOT USED PBNL= 2 ;;;DEFAULT CYLINDER,TRACK AND SECTOR -RL11 CREXT= 10 ;;;BAE OFFSET FROM CSR ;MSH203 CALL CKSUM .IF DF M$$EXT CLR CREXT(R0) ;;;CLEAR AND TEST FOR BAE REGISTER ;MSH203 BCC 5$ ;;;IF CC IT EXISTS ;MSH203 CLR @#UBMPR ;;;INITIALIZE FIRST UNIBUS ... ; RP066 CLR @#UBMPR+2 ;;;... MAPPING REGISTERS ; RP066 5$: BIS #60,@#SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP ; RP066 BIS #1,SR0 ;;;MAKE SURE MEM MGMT IS ON ;**-4 MOV #4*4,R5 ;;;STORE BLOCKS PER 4K WORDS MOV #1920.*4,-(SP) ;;;DUMP MAXIMUM 1920.K WORDS ;MSH039 ;MSH039 .IFF ;MSH039 ;MSH039 .IF DF M$$MGE ;MSH039 ;MSH039 MOV #124.*4,-(SP) ;;;DUMP MAXIMUM 124.K WORDS ;MSH039 ;MSH039 .IFF ;M$$MGE ;MSH039 ;MSH039 MOV #28.*4,-(SP) ;;;DUMP MAXIMUM 28.K WORDS ;MSH039 ;MSH039  .ENDC ;MSH039 .ENDC SWAB R3 ;;;MOVE UNIT NUMBER TO HIGH BYTE BIS #4,R3 ;;;SET GET STATUS FUNCTION MOV #13,4(R0) ;;;SET CODES TO CLEAR DRIVER MOV R3,(R0) ;;;EXECUTE THE FUNCTION 10$: BIT #100200,(R0) ;;;READY OR ERROR? BEQ 10$ ;;;IF EQ NEITHER BMI WERRX ;;;IF MINUS I/O ERROR ;MSH039 ADD #4,R3 ;;;CONVERT TO READ HEADER FUNCTION ;**-1 MOV $CRSBN+2,R4 ;;;SAVE STARTING DISK ADDRESS CLR 2(R0) ;;;SET BUFFER ADDRESS FOR FIRST WRITE 15$: MOV R3,(R0) ;;;READ HEADER 20$: BIT #100200,(R0) ;;;DONE OR ERROR? BEQ 20$ ;;;IF EQ NEITHER BMI WERRX ;;;IF MINUS I/O ERROR ;MSH039 MOV 6(R0),R1 ;;;GET HEADER INFORMATION ;**-1 MOV R4,R2 ;;;COPY DESIRED DISK ADDRESS MOV R1,-(SP) ;;;STORE VALUE MOV R2,-(SP) ;;; FORM A DIFF. XOR BIC R1,R2 ;;; BIC (SP)+,R1 ;;; BIS R1,R2 ;;; MOV (SP)+,R1 ;;;RESTORE R1 BIC #77,R2 ;;;IGNORE SECTOR BITS BEQ 40$ ;;;IF EQ NO SEEK REQUIRED MOV R4,R2 ;;;COPY DESIRED DISK ADDRESS BIC #177,R1 ;;;ISOLATE CYLINDER ADDRESS BIC #177,R2 ;;;ISOLATE CYLINDER ADDRESS DESIRED SUB R2,R1 ;;;SUBTRACT DESIRED FROM ACTUAL BHIS 25$ ;;;IF HIS ACTUAL >=DESIRED NEG R1 ;;;ACTUAL < DESIRED, MAKE POS. DIFF. BIS #4,R1 ;;;SET SIGN FOR MOVE TO CENTER OF DISK 25$: INC R1 ;;;SET MARKER BIT BIT #100,R4 ;;;WHICH HEAD DO WE WANT BEQ 30$ ;;;IF EQ IT'S HEAD 0 BIS #20,R1 ;;;SET HEAD 1 30$: MOV R1,4(R0) ;;;LOAD DIFFERENCE WORD SUB #2,R3 ;;;CONVERT TO SEEK FUNCTION MOV R3,(R0) ;;;START THE SEEK 35$: BIT #100200,(R0) ;;;READY OR ERROR? BEQ 35$ ;;;IF EQ NEITHER BMI WERRX ;;;IF MINUS I/O ERROR ;MSH039 40$: MOV R4,4(R0) ;;;LOAD DESIRED DISK ADDRESS ;**-1 MOV #-256.,6(R0) ;;;LOAD ONE BLOCK WORD COUNT BIC #17,R3 ;;;REMOVE FUNCTION BITS BIS #12,R3 ;;;SET WRITE FUNCTION MOV R3,(R0) ;;;START THE WRITE 45$: BIT #100200,(R0) ;;;ERROR OR READY? BEQ 45$ ;;;IF EQ NEITHER BMI 70$ ;;;IF MINUS, ERROR DEC (SP) ;;;DECREMENT MAXIMUM BLOCK DUMP ;MSH039 BEQ 75$ ;;;IF EQ, DUMP IS DONE ;MSH039 .IF DF M$$EXT DEC R5 ;;;DECREMENT BLOCK COUNT BNE 60$ ;;;IF NE USE SAME UMR TST CREXT(R0) ;;;IS THE BAE REGISTER THERE? ;MSH203 BCC 50$ ;;;IF CC YES ;MSH203 ADD #20000,@#UBMPR ;;;NO, POINT UMR TO NEXT 4K OF MEMORY ; RP066 ADC @#UBMPR+2 ;;;DOUBLE WORD ADD ; RP066 CLR 2(R0) ;;;AND RESET BUS ADDRESS ; RP066 50$: MOV #4*4,R5 ;;;RESET TO # BLOCKS PER 4K ; RP066 ;**-4 .ENDC 60$: MOV (R0),R3 ;;;GET CSR BIC #^C<1460>,R3 ;;;ISOLATE UNIT AND EX MEM BITS ADD #2,R4 ;;;MOVE TO NEXT SECTOR MOV R4,R1 ;;;COPY DISK ADDRESS BIC #^C<77>,R1 ;;;GET THE SECTOR BITS CMP #50,R1 ;;;OVERRUN COMING? BNE 40$ ;;;IF NE, NO BIS #77,R4 ;;;INCREMENT TRACK... INC R4 ;;;...SET SECTOR TO 0 BIS #10,R3 ;;;SET READ HEADER FUNCTION BR 15$ ;;;AND GO AGAIN 70$: BIT #20000,(R0) ;;;NON-EXISTENT MEMORY? BEQ WERRX ;;;IF EQ NO, I/O ERROR ;MSH039 75$: TST (SP)+ ;;;CLEAN STACK ;MSH039 BR $CRCMP ;;;DUMP DONE ;MSH039 ;MSH039 WERRX: TST (SP)+ ;;;CLEAN STACK ;MSH039  ;**-1 .ENDC .IF EQ C$$CDA-10 ;MSH054 ; ;MSH054 ; DD ;MSH054 ; ;MSH054 ; THIS ROUTINE DUMPS ALL OF PHYSICAL MEMORY UP TO A LIMIT OF 124K WORDS.;MSH054 ; ;MSH054 PBNH= 0 ;;;NOT USED BY TU-58 TAPE CARTRIDGE PBNL= 1 ;;;STARTING BLOCK NUMBER ;THIS CODE INTERFACES WITH A TU-58 VIA A DL-11 ASYNCHRONOUS INTERFACE CALL CKSUM MOV #$TRINT,@#114 ;;;POSITION NONEXISTENT MEMORY TRAP ;MSH060 ;;;CATCHER FOR CPUS WHERE MEMORY SIZE ;MSH060 ;;;REGISTER > SIZE OF MEMORY ;MSH060 ;**-1 .IF NDF M$$MGE CLR R1 ;;;POINT TO BEGINNING OF MEM. .IFF CLR KISAR6 ;;;CLEAR MAPPING REG. CLR KISAR0 ;;; BIS #1,SR0 ;;;ENSURE MAPPING TURNED ON ;**-2 .ENDC ;INITIALIZE TU-58 CLR -(SP) ;;;RESERVE SPACE ON STACK ;MSH058 MOV R3,-(SP) ;;;SAVE UNIT NUMBER BIS #1,4(R0) ;;;SEND BREAK MOV #6,R2 ;;;SET TO SEND 6 NULLS 5$: CLRB 6(R0) ;;;SEND A NULL CALL XWAIT DEC R2 ;;;6 NULLS SENT? BNE 5$ ;;;IF NE, NO CLR 4(R0) ;;;CLEAR BREAK TST 2(R0) ;;;DUMP REC. BUFFER MOVB #4,6(R0) ;;;SEND INIT. CALL XWAIT MOVB #4,6(R0) ;;;SEND ANOTHER INIT. CALL XWAIT 10$: TSTB (R0) ;;;RECEIVED A BYTE? BPL 10$ ;;;IF PL NO CMPB #20,2(R0) ;;;RECEIVED A CONTINUE? BNE 35$ ;;;IF NE NO, I/O ERROR ;MSH058 ;**-2 ;SEND COMMAND PACKET MOV $CRSBN+2,R2 ;;;SAVE STARTING TU-58 ADDRESS ;MSH058 15$: ;;;REF LABEL ;MSH058 .IF DF M$$MGE ;MSH058 ;MSH058 MOV #140000,R1 ;;;RESET CURRENT MEMORY ADDRESS ;MSH058 ;MSH058 .ENDC ;MSH058 ;MSH058 CALL XWAIT ;MSH058 MOVB #2,6(R0) ;;;SEND COMMAND FLAG ;**-2 CALL XWAIT MOVB #12,6(R0) ;;;SEND PACKET BYTE COUNT MOV #5002,R4 ;;;CREATE 1ST CHECKSUM WD. CALL XWAIT MOVB #3,6(R0) ;;;SEND WRITE OP CODE CALL XWAIT CLRB 6(R0) MOV #3,R5 ;;;CREATE 2ND CHECKSUM WD. CALL CKSM MOVB (SP),6(R0) ;;;SEND UNIT NUMBER MOV #4,R3 ;;;SET COUNTER TO SEND 3 CLRS 20$: CALL XWAIT CLR 6(R0) DEC R3 BNE 20$ MOV (SP),R5 ;;;CHECKSUM CALL CKSM MOVB #<1024.*2/400>,6(R0) ;;;SEND HIGH ORDER BYTE OF ;MSH058 ;;;NUMBER OF BYTES TO TRANSFER ;MSH058 MOV #<1024.*2>,R5 ;;;UPDATE PACKET CHECKSUM FOR TRANSFER ;MSH058 CALL CKSM ;;;BYTE COUNT AND THEN WAIT ;MSH058 MOV R2,R3 ;;;COPY TU-58 BLOCK NO. ;**-3 MOVB R3,6(R0) ;;;SEND LOW ORDER BLOCK NO. SWAB R3 ;;;SWAP BYTES CALL XWAIT MOVB R3,6(R0) ;;;SEND HIGH ORDER BLOCK NO. MOV R2,R5 ;;;CHECKSUM CALL CKSM MOVB R4,6(R0) ;;;SEND LOW ORDER BYTE OF CKSM SWAB R4 ;;;SWAP BYTES CALL XWAIT MOVB R4,6(R0) ;;;SEND HIGH ORDER CKSM BYTE ; SEND WRITE DATA TO TU-58 MOV #<1024.*2/128.>,2(SP) ;;;NUMBER PACKETS/1K WORDS ;MSH058 30$: BIT #200,(R0) ;;;RECEIVED A CHARACTER? ;**-1 BEQ 30$ ;;;IF EQ NO CMPB #20,2(R0) ;;;REC. A CONTINUE? 35$: BNE DEND ;;;IF NE NO ;MSH058 MOV #64.,R3 ;;;STORE WORDS/PACKET ;**-1 CALL XWAIT MOVB #1,6(R0) ;;;SEND DATA PACKET COMMAND FLAG CALL XWAIT MOVB #200,6(R0) ;;;SEND PACKET BYTE COUNT MOV #100001,R4 ;;;CREATE FIRST CHECKSUM WORD CALL XWAIT 40$: MOV (R1),R5 ;;;WILL USE DATA WORD IN CHECKSUM ;MSH058 MOVB (R1)+,6(R0) ;;;WRITE FIRST BYTE ;MSH058 CALL XWAIT ;**-9 MOVB (R1)+,6(R0) ;;;SEND SECOND BYTE CALL CKSM DEC R3 ;;;DECREMENT PACKET COUNT BNE 40$ ;;;IF NE TRANSFER ANOTHER 2 BYTES MOVB R4,6(R0) ;;;SEND LOW ORDER CHECKSUM SWAB R4 ;;;SWAP BYTES CALL XWAIT MOVB R4,6(R0) ;;;SEND HIGH ORDER CHECKSUM DEC 2(SP) ;;;DECREMENT PACKET COUNT ;MSH058 BNE 30$ ;;;IF NE SEND ANOTHER PACKET ;**-1 ;**-1 ;CLEAR OUT END PACKET MESSAGE FROM TU-58 MOV #14.,R3 ;;;SET DUMP REC. BYTE COUNTER 50$: BIT #200,(R0) ;;;RECEIVE END PACKET CHAR. BEQ 50$ ;;;IF EQ NO TST 2(R0) ;;;DUMP CHAR. ;MSH058 DEC R3 ;;;DECREMENT COUNT ;**-1 BNE 50$ ;;;IF NE DUMP AGAIN ;MSH058 .IF DF M$$MGE ;MSH058 ;MSH058 CMP #<7600-40>,@#KISAR6 ;;;HAVE WE HIT THE I/O PAGE? ;MSH058 ;MSH058 .IFF ;M$$MGE ;MSH058 ;MSH058 CMP #<28.*4-3>,R2 ;;;HAVE WE HIT THE I/O PAGE? ;MSH058 ;MSH058 .IFTF ;M$$MGE ;MSH058 ;MSH058 BNE 70$ ;;;IF NE NO, MORE TO DUMP ;MSH058 60$: CMP (SP)+,(SP)+ ;;;CLEAN STACK ;MSH058 BR $CRCMP ;;;DUMP IS DONE ;MSH058 70$: TST (R1) ;;;DOES NEXT MEMORY LOCATION EXIST? ;MSH058 BCS 60$ ;;;IF CS NO, DUMP IS DONE ;MSH058 ;MSH058 .IFT ;M$$MGE ;MSH058 ;MSH058 ADD #40,@#KISAR6 ;;;POINT TO NEXT 1K WORD SEGMENT ;MSH058 ;MSH058 .IFTF ;M$$MGE  ;MSH058 ;MSH058 ADD #4,R2 ;;;ADJUST TU-58 BLOCK ADDRESS ;MSH058 JMP 15$ ;MSH058 ;**-14 CKSM: ADD R5,R4 ;;;ADD 2ND WORD TO FIRST ADC R4 ;;;ADD CARRY -END AROUND CARRY CHECKSUM XWAIT: BIT #200,4(R0) ;;;DL-11 TRANSMIT READY? BEQ XWAIT ;;;IF EQ NO RETURN DEND: CMP (SP)+,(SP)+ ;;;CLEAN STACK ;MSH058 ;**-2 .IFT ;M$$MGE ;MSH058 ;**-2 CMP R2,#497. ;;;HAVE WE TRANSFERED ENOUGH DATA ;;;TO PUT US AT THE END OF THE TAPE BEQ $CRCMP ;;;IF EQ YES, SUCCESSFUL TRANSFER ;;;OF ALL MEMORY THAT WILL FIT ON TAPE .ENDC .ENDC ;**-30 .IF EQ C$$CDA-12 ;MSH054 ; ;MSH054 ; MS ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE DOES NOT SUPPORT 22-BIT ADDRESSING, THIS ;MSH054 ; ROUTINE DUMPS ALL OF PHYSICAL MEMORY (UP TO A MAXIMUM OF ;MSH054 ; 124K WORDS MAPPED OR 28K WORDS UMAPPED) IN 512 BYTE BLOCKS ;MSH054 ; AT 1600 BPI. ;MSH054 ; ;MSH054 ; IF THE EXECUTIVE SUPPORTS 22-BIT ADDRESSING, THIS ROUTINE ;MSH054 ; DUMPS ALL OF PHYSICAL MEMORY IN 512 BYTE BLOCKS AT 1600 BPI. ;MSH054 ; ;MSH054 PBNH= 0 PBNL= 0 BR 100$ 1$: .BLKW 5. ;;;THE COMMAND BUFFER PLUS ONE. 2$: ;;;THE CHARACTERISTICS DATA. .WORD 3$ ;;; LSW OF MESSAGE BUFFER ADDRESS. .WORD 0 ;;; MSW OF " " " .WORD 14. ;;; THE SIZE OF THE MESSAGE BUFFER. .WORD 0 ;;; THE FLAG WORD. 3$: .BLKW 3 ;;;THE MESSAGE BUFFER. 4$: .BLKW 4 ;;; XSTAT0 WITHIN MESSAGE BUFFER. 100$: MOV #<1$+12>,R5 ;;;WE NOW COMPUTE ADDRESS OF COMMAND ;MSH059 BIC #3,R5 ;;;BUFFER. (NEEDS DOUBLE WORD BOUNDARY) ;MSH059 MOV #8.,-(R5) ;;;LENGTH OF COMMAND PACKET IN BYTES ;MSH059 CLR -(R5) ;;;UPPER 2 BITS OF COMMAND PACKET ADDRES;MSH059 MOV #2$,-(R5) ;;;LOW ORDER 16 BITS ;MSH059 MOV #100004,-(R5) ;;;WANT TO "WRITE CHARACTERISTICS" ;MSH059 MOV R5,R4 ;;;COPY POINTER TO COMMAND PACKET. ;MSH059 ;;;R4=R5 IS FLAG THAT TS11 IS ;MSH059 ;;;BEING INITIALIZED (SEE 180$) ;MSH059 MOV R0,R1 ;;;COPY CSR POINTER TO CONVERT IT TO ;**-7 TST -(R1) ;;; COMMAND REGISTER ADDRESS. CALL 200$ ;;;ISSUE COMMAND, WAIT FOR SSR, TREAT ER;**-1 MOV #142010,(R5) ;;;REWIND AND CLEAR VOLUME CHECK ;MSH059 CALL 200$ ;;;ISSUE, WAIT, TREAT ERRORS. ;**-1 MOV #100005,(R5)+ ;;; MAKE A WRITE COMMAND WITH HEADER ;**-1 ;MSH113 .IF DF M$$EXT ;MSH113 ;MSH113 MOV #20000,(R5)+ ;;;POINT BUFFER TO SECOND UMR ;MSH113 ;MSH113 .IFF ;MSH113 ;MSH113 CLR (R5)+ ;;;START AT LOCATION 0 ;MSH113 ;MSH113 .ENDC ;MSH113 ;MSH113 CLR (R5)+ ;;; ;MSH113 MOV #512.,(R5) ;;;NUMBER OF BYTES IN A RECORD ;MSH059 ;;;(R5 NOT EQUAL R4 AS FLAG !!) ;**-3 .IF DF M$$EXT CLR @#UBMPR+4 ;;;INITIALIZE SECOND UMR TO ADDRESS 0 ;MSH113 CLR @#UBMPR+6 ;;; ;MSH113 BIS #60,SR3 ;;;ENABLE 22 BIT MAPPING AND UNIBUS MAP.;**-3 BIS #1,SR0 ;;;MAKE SURE MEMORY MANAGEMENT ENABLED. MOV #<1920./4>,R3 ;;;MAXIMUM NUMBER OF 4K WORD BLOCKS ;MSH059 40$: MOV #<1024.*4*2/512.>,R2 ;;;NUMBER OF 512 BYTE RECORDS/BLOCK;MSH059 ;**-2 .IFF ; RP067 .IF DF M$$MGE ; RP067 ; RP067 MOV #<124.*4>,R2 ;;;NUMBER OF 512 BYTE RECORDS ; RP067 ; RP067 .IFF ;M$$MGE ; RP067 ; RP067 MOV #<28.*4>,R2 ;;;NUMBER OF 512 BYTE RECORDS ; RP067 ; RP067 .ENDC ;M$$MGE ; RP067 ; RP067 ;**-1 .IFTF 50$: MOV #9.,R5 ;;;RETRY COUNT+1 ;MSH059 CALL 200$ ;;;ISSUE WRITE AND WAIT ;MSH059 ADD #512.,2(R4) ;;;BUMP START ADDRESS OF DATA. ;**-1 ADC 4(R4) ;;; (DOUBLE PRECISION ADDRESS.) DEC R2 ;;;LIMIT CHECK ON RECORDS COUNT ? BNE 50$ ;;; LOOP TILL LIMIT (OR ERR IN 200$) .IFT ADD #<1024.*4*2>,@#UBMPR+4 ;;;BUMP ADDRESS OF UMR 1 BY ;MSH113 ADC @#UBMPR+6 ;;; 4K WORDS ;MSH113 MOV #20000,2(R4) ;;;REINITIALIZE POINTER WITHIN 4K ;MSH113 ;;; WINDOW TO START OF UMR 1 ;MSH113 DEC R3 ;;;LIMIT CHECK ON BLOCK COUNT ? ;**-3 BNE 40$ ;;;IF NE BLOCK LIMIT NOT REACHED ;MSH059 ;MSH059 .IFTF ;MSH059 ;MSH059 ; ;MSH059 ; NOTE THAT THE FOLLOWING BRANCH IS NEVER TAKEN IF 180$ IS FALLEN ;MSH059 ; INTO (R5 IS NEVER EQUAL TO R4, BECAUSE R5 IS A RETRY COUNT AND ;MSH059 ; R4 IS AN ADDRESS, UNLESS 180$ IS BRANCHED TO FROM BELOW). ;MSH059 ; ;MSH059 ;MSH059 180$: CMP R4,R5 ;;;IS TS11 BEING INITIALIZED? ;MSH059 BEQ 280$ ;;;IF EQ YES, ERROR EXIT ;MSH059 MOV #100011,(R4) ;;;WANT TO FORMAT (WRITE TAPE MARK) ;MSH059 MOV R4,(R1) ;;;ISSUE COMMAND ;MSH059 190$: TSTB (R0) ;;;SUBSYSTEM READY? ;MSH059 BPL 190$ ;;;IF PL NO ;MSH059 BR $CRCMP ;;;SUCCESSFUL TERMINATION ;MSH059 ;MSH059 200$: ;;;REF LABEL ;MSH059 .IFT ;MSH059 ;MSH059 MOV R3,-(SP) ;;;SAVE BLOCK COUNTER ;MSH059 ;MSH059 .IFTF ;MSH059 ;MSH059 210$: MOV R4,(R1) ;;;ISSUE COMMAND ;MSH059 225$: TSTB (R0) ;;;TEST FOR SSR (SUBSYSTEM READY) ? ;**-11 BPL 225$ ;;;NO=> LOOP; ELSE .... MOV (R0),R3 ;;;GET STATUS ;MSH059 BMI 250$ ;;;PROBLEM=> GO CHECK OUT; ELSE ... ;**-1 ;MSH059 .IFT ;MSH059 ;MSH059 MOV (SP)+,R3 ;;;RESTORE BLOCK COUNTER ;MSH059 ;MSH059 .ENDC ;MSH059 ;MSH059 BIC #1000,(R4) ;;;CLEAR "WRITE DATA RETRY" BIT ;MSH059 RETURN ;;; GO ON WITH THE DUMP. 250$: BIT #1,4$ ;;;EOT SEEN ON THIS OPERATION ? BNE 180$ ;;;IF NE YES ;MSH059 BIT #4000,R3 ;;;NONEXISTENT MEMORY? ;MSH059 BNE 180$ ;;;IF NE YES ;MSH059 BIC #^C<16>,R3 ;;;ISOLATE TERMINATION CODE ;MSH059 CMP #12,R3 ;;;RECOVERABLE ERROR (TAPE HAS NOT MOVED;MSH059 BEQ 270$ ;;;IF EQ YES ;MSH059 CMP #10,R3 ;;;RECOVERABLE ERROR (TAPE HAS MOVED ONE;MSH059 ;;;RECORD? ;MSH059 BNE 280$ ;;;IF NE NO, I/O ERROR ;MSH059 BIS #1000,(R4) ;;;CHANGE COMMAND TO "SPACE REVERSE, ;MSH059 ;;;ERASE, WRITE DATA" ;MSH059 270$: DEC R5 ;;;EXHAUSTED RETRY COUNT? ;MSH059 BNE 210$ ;;;IF NE NO ;MSH059 280$: TST (SP)+ ;;;DISCARD RETURN ADDRESS ;MSH059 ;**-20 .ENDC .IIF EQ C$$CDA-13, CDA$DX=0 ; PJC015 ; PJC015 ; PJC015 .IIF EQ C$$CDA-14, CDA$DY=0 ; PJC015 ; PJC015 ; PJC015 .IF DF CDA$DX!CDA$DY ; PJC015 ; PJC015 ; PJC015 ; ; PJC015 ; DX AND DY ; PJC015 ; ; PJC015 ; THE LOCAL SYMBOLS REFERENCED ABOVE, CDA$DX AND CDA$DY, ARE ; PJC015 ; USED WITHIN THE FOLLOWING COMMON CODE DRIVER BELOW TO ; PJC015 ; DIFFERENTIATE BETWEEN RX01 AND RX02 TYPE DRIVES. ; PJC015 ; ; PJC015 ; IF THE EXECUTIVE DOES NOT SUPPORT 22-BIT ADDRESSING, THIS ; PJC015 ; ROUTINE DUMPS A MAXIMUM OF 123K WORDS FOR A MAPPED SYSTEM ; PJC015 ; AND 28K WORDS FOR AN UNMAPPED SYSTEM. ; PJC015 ; ; PJC015 ; IF THE EXECUTIVE DOES SUPPORT 22-BIT ADDRESSING, THIS ROUTINE ; PJC015 ; DUMPS A MAXIMUM OF 123K WORDS TO A SINGLE DENSITY FLOPPY, BE ; PJC015 ; IT A DX OR DY, AND UP TO A MAXIMUM OF 246K WORDS TO A DOUBLE ; PJC015 ; DENSITY DY FLOPPY. ; PJC015 ; ; PJC015 ; PJC015 PBNH= 0 ;;;HIGH ORDER RX11/211 BLOCK NUMBER ; PJC015 PBNL= 1 ;;;LOW ORDER RX11/211 BLOCK NUMBER ; PJC015 ; PJC015 CALL CKSUM ;;;CHECK LBN AGAINST CHECKSUM ; PJC015 MOV #$TRINT,@#114 ;;;SET UP NXM TRAP CATCHER ; PJC015 ; PJC015 ; PJC015 .IF DF M$$MGE ; PJC015 ; PJC015 ; PJC015 .IF NDF CDA$DY ; PJC015 ; PJC015 MOV #123.*4,-(SP) ;;;DUMP 123.K WORDS MAX ; PJC015 CLR @#KISAR6 ;;;POINT TO FIRST BYTE TO TRANSFER ; PJC015 BIS #1,@#SR0 ;;;ENSURE MEM MGMT IS ON ; PJC015 ; PJC015 .IFF ;CDA$DY ; PJC015 ; PJC015 ; PJC015 .IF DF M$$EXT ; PJC015 ; PJC015 MOV #256.*4,-(SP) ;;;DUMP 256.K WORDS MAX ; PJC015 CLR @#UBMPR ;;;INITIALIZE FIRST UNIBUS MAPPING REGS.; PJC015 CLR @#UBMPR+2 ;;; ; PJC015 CLR @#KISAR0 ;;; ; PJC015 BIS #60,@#SR3 ;;;ENABLE 22-BIT MAPPING AND UNIBUS MAP ; PJC015 BIS #1,@#SR0 ;;;ENSURE MEM MGMT IS ON ; PJC015 ; PJC015 .IFF ;M$$EXT ; PJC015 ; PJC015 MOV #123.*4,-(SP) ;;;DUMP 123.K WORDS MAX ; PJC015 ; PJC015 .ENDC ;M$$EXT ; PJC015 ; PJC015 ; PJC015 .ENDC ;CDA$DY ; PJC015 ; PJC015 ; PJC015 .IFF ;M$$MGE ; PJC015 ; PJC015 MOV #28.*4,-(SP) ;;;DUMP 28.K WORDS MAX ; PJC015 ; PJC015 .ENDC ;M$$MGE ; PJC015 ; PJC015 ; PJC015 ASL R3 ;;;POSITION UNIT SELECT BITS ; PJC015 ASL R3 ;;; ; PJC015 ASL R3 ;;; ; PJC015 ASL R3 ;;; ; PJC039 MOV #13,R5 ;;;READ STATUS FUNCTION CODE ; PJC015 BIS R3,R5 ;;;MERGE UNIT NUMBER ; PJC015 MOV R5,(R0) ;;;DO A READ STATUS ; PJC015 5$: BITB #40,(R0) ;;;DONE? ; PJC015 BEQ 5$ ;;;IF EQ NO ; PJC015 TST (R0) ;;;ANY ERRORS? ; PJC015 ; PJC015 ; PJC015 .IF DF CDA$DY ; PJC015 ; PJC015 BPL 15$ ;;;IF PL NO ; PJC015 BITB #20,2(R0) ;;;DENSITY ERROR? ; PJC015 BEQ 105$ ;;;IF EQ NO ; PJC015 10$: MOV #40000,(R0) ;;;INITIALIZE RX211 SUBSYSTEM ; PJC015 BIS #400,R3 ;;;SHOW DOUBLE DENSITY ; PJC039 BR 5$ ;;;OK NOW? ; PJC015 ; PJC015 .IFF ;CDA$DY ; PJC015 ; PJC015 BMI 105$ ;;;IF MI YES ; PJC015 ; PJC015 .IFTF ;CDA$DY ; PJC015 ; PJC015 15$: MOV #128.,R1 ;;;WORD TRANSFER COUNT ; PJC015 CLR R2 ;;;STARTING BUFFER ADDRESS ; PJC015 MOV $CRSBN+2,R4 ;;;GET LOGICAL BLOCK # ; PJC015 ; PJC015 .IFT ;CDA$DY ; PJC015 ; PJC015 BIT #400,R3 ;;;DOUBLE DENSITY? ; PJC039 BNE 20$ ;;;IF NE YES ; PJC015 ASR R1 ;;;POSITION WC FOR SINGLE DENSITY ; PJC015 BR 25$ ;;; ; PJC015 20$: ASR (SP) ;;;BLOCK COUNT FOR MAX MEMORY DUMP ; PJC039 BR 30$ ;;; ; PJC015 ; PJC015 .IFTF ;CDA$DY ; PJC015 ; PJC015 25$: ASL R4 ;;;SHIFT STARTING LBN... ; PJC015 30$: ASL R4  ;;;...FOR CORRECT DENSITY ; PJC015 ; PJC015 ; ; PJC015 ; THE ABOVE CODE IS EXECUTED ONLY ONCE DURING A CRASH DUMP. ; PJC015 ; ; PJC015 ; PJC015 35$: CALL TRKSEC ;;;CONVERT LBN TO TRACK/SECTOR ; PJC015 40$: MOV #1,R5 ;;;FILL SILO ; PJC015 BIS R3,R5 ;;;MERGE UNIT AND DENSITY BIT ; PJC015 MOV R5,(R0) ;;;INITIATE FILL SILO ; PJC015 ; PJC015 .IFT ;CDA$DY ; PJC015 ; PJC015 45$: CALL TRWAIT ;;;WAIT ; PJC015 MOV R1,2(R0) ;;;LOAD WORD COUNT ; PJC015 CALL TRWAIT ;;;WAIT ; PJC015 MOV R2,2(R0) ;;;LOAD BUFFER ADDRESS ; PJC015 50$: BITB #40,(R0) ;;;DONE? ; PJC015 BEQ 50$ ;;;IF EQ NO ; PJC015 TST (R0) ;;;ANY ERRORS? ; PJC015 BMI 105$ ;;;IF MI YES ; PJC015 ; PJC015 .IFF ;CDA$DY ; PJC015 ; PJC015 ; PJC015 .IF DF M$$MGE ; PJC015 ; PJC015 MOV #140000,R2 ;;;SET TO USE APR6 ; PJC015 ; PJC015 .IFTF ;M$$MGE ; PJC015 ; PJC015 55$: TST (R2) ;;;DOES NEXT MEMORY LOCATION EXIST? ; PJC015 BCC 60$ ;;;IF CC YES ; PJC015 CMP (SP)+,(SP)+ ;;;NO, CLEAN STACK ; PJC015 BR 135$ ;;; ; PJC015 60$: BITB #240,(R0) ;;;TRANSFER REQUEST? ; PJC015 BMI 65$ ;;;IF MI YES ; PJC015 BEQ 60$ ;;;IF EQ NO ; PJC015 BR 70$ ;;;SILO IS FULL ; PJC015 65$: MOVB (R2)+,2(R0) ;;;PUT NEXT BYTE IN SILO ; PJC015 DEC R1 ;;;DONE? ; PJC015 BR 60$ ;;;WAIT TILL IT'S ACCEPTED ; PJC015 70$: TSTB R1 ;;;ALL BYTES TRANSFERRED? ; PJC015 BNE 105$ ;;;IF PL NO, ERROR ; PJC015 ; PJC015 .IFT ;M$$MGE ; PJC015 ; PJC015 ADD #2,@#KISAR6 ;;;UPDATE BUFFER POINTER ; PJC015 ; PJC015 .ENDC ;M$$MGE ; PJC015 ; PJC015 ; PJC015 .IFTF ;CDA$DY ; PJC015 ; PJC015 75$: MOV #5,R5 ;;;SET WITH WRITE FUNCTION ; PJC015 BIS R3,R5 ;;;MERGE UNIT NUMBER ; PJC015 MOV R5,(R0) ;;;INITIATE WRITE ; PJC015 80$: CALL TRWAIT ;;;WAIT ; PJC015 85$: MOVB SECTOR,2(R0) ;;;LOAD SECTOR ; PJC015 90$: CALL TRWAIT ;;;WAIT ; PJC015 95$: MOVB TRACK,2(R0) ;;;LOAD TRACK ; PJC015 100$: BITB #40,(R0) ;;;DONE? ; PJC015 BEQ 100$ ;;;IF EQ NO ; PJC015 TST (R0) ;;;ANY ERRORS? ; PJC015 BPL 110$ ;;;IF PL NO ; PJC015 ; PJC015 .IFT ;CDA$DY ; PJC015 ; PJC015 BIT #4000,2(R0) ;;;NON-EXISTANT MEMORY? ; PJC015 BNE 135$ ;;;IF NE YES ; PJC015 ; PJC015 .IFTF ;CDA$DY ; PJC015 ; PJC015 105$: JMP WERR ;;;ERROR ; PJC015 110$: DEC (SP) ;;;DONE? ; PJC015 BEQ 135$ ;;;IF EQ YES ; PJC015 ; PJC015 .IFT ;CDA$DY ; PJC015 ; PJC015 ; PJC015 .IF DF M$$EXT ; PJC015 ; PJC015 DEC BLKCNT ;;;DECREMENT LBN COUNT ; PJC015 BNE 115$ ;;;IF NE USE SAME UMR ; PJC015 ADD #20000,@#UBMPR ;;;POINT TO NEXT 4K OF MEMORY ; PJC015 ADC @#UBMPR+2 ;;;DOUBLE WORD ADD ; PJC015 MOV #16.*2,BLKCNT ;;;LBN'S PER 4K WORDS ; PJC015 CLR R2 ;;;RESET BUFFER ADDRESS ; PJC015 BR 130$ ;;; ; PJC015 ; PJC015 .ENDC ;M$$EXT ; PJC015 ; PJC015 ; PJC015 115$: BIT #400,R3 ;;;DOUBLE DENSITY? ; PJC015 BEQ 120$ ;;;IF EQ NO ; PJC015 ADD #256.,R2 ;;;UPDATE BUFFER ADDRESS FOR DOUBLE DENS; PJC015 BR 125$ ;;; ; PJC015 120$: ADD #128.,R2 ;;;UPDATE BUFFER ADDRESS FOR SINGLE DENS; PJC015 125$: BCC 130$ ;;;IF CC, NO OVERFLOW ; PJC015 ; PJC015 ; PJC015 .IF DF M$$MGE ; PJC015 ; PJC015 ADD #10000,R3 ;;;CARRY INTO EXTENDED MEMORY BITS ; PJC015 ; PJC015 .ENDC ;M$$MGE ; PJC015 ; PJC015 ; PJC015 .IFF ;CDA$DY ; PJC015 ; PJC015 MOV #128.,R1 ;;;SET UP WC AGAIN ; PJC015 ; PJC015 .IFTF ;CDA$DY ; PJC015 ; PJC015 130$: MOV #1,R5 ;;;FILL SILO ; PJC015 INC R4 ;;;INCREMENT LBN ; PJC015 BR 35$ ;;;GO AGAIN ; PJC015 135$: TST (SP)+ ;;;CLEAN STACK ; PJC015 BR $CRCMP ;;;DUMP IS DONE ; PJC015 ; PJC015 SECTOR: .WORD 0 ;;;SECTOR NUMBER ; PJC015 TRACK: .WORD 0 ;;;TRACK NUMBER ; PJC015 ; PJC015 .IFT ;CDA$DY ; PJC015 ; PJC015 ; PJC015 .IF DF M$$EXT ; PJC015 ; PJC015 BLKCNT: .WORD 16.*2 ;;;LBN'S PER 4K WORDS ; PJC015 ; PJC015 .ENDC ;M$$EXT ; PJC015 ; PJC015 ; PJC015 .ENDC ;CDA$DY ; PJC015 ; PJC015 ; PJC015 TRWAIT: BITB #240,(R0) ;;;TRANSFER REQUEST? ; PJC015 BMI 5$ ;;;IF MI YES ; PJC015 BEQ TRWAIT ;;;IF EQ NEITHER ; PJC015 BR WERR ;;;ERROR ; PJC015 5$: RETURN ;;; ; PJC015 ; PJC015 ; ; PJC015 ; CONVERT LOGICAL BLOCK NUMBER TO PHYSICAL TRACK/SECTOR PAIR ; PJC015 ; ; PJC015 ; INPUT: ; PJC015 ; R4 = LOGICAL BLOCK NUMBER ; PJC015 ; ; PJC015 ; OUTPUT: ; PJC015 ; SECTOR - SECTOR (1-26.) ; PJC015 ; TRACK - TRACK (0-76.) ; PJC015 ; ; PJC015  ; PJC015 TRKSEC: MOV R0,-(SP) ;;;SAVE REGISTERS ; PJC015 MOV R1,-(SP) ;;; ; PJC015 MOV R2,-(SP) ;;; ; PJC015 MOV R4,R1 ;;;GET LOGICAL BLOCK # ; PJC015 MOV #8.,R0 ;;;SET LOOP COUNT ; PJC015 MOV #6400,R2 ;;;AND DIVISOR ; PJC015 5$: CMP R2,R1 ;;;DOES 26. GO INTO DIVIDEND? ; PJC015 BHI 10$ ;;;IF HI NO, C=0 ; PJC015 SUB R2,R1 ;;;SUBTRACT 26. ; PJC015 SEC ;;; ; PJC015 10$: ROL R1 ;;;SHIFT DIVIDEND AND QUOTIENT ; PJC015 DEC R0 ;;;DONE? ; PJC015 BGT 5$ ;;;IF GT NO ; PJC015 BISB R1,R0 ;;;GET TRACK NUMBER ; PJC015 15$: CLRB R1 ;;;CLEAR TRACK NUMBER ; PJC015 SWAB R1 ;;;POSITION SECTOR NUMBER ; PJC015 CMP #12.,R1 ;;;C=1 IF 13<=R1<=25 ; PJC015 ROL R1 ;;;DOUBLE FOR INTERLEAVE FACTOR ; PJC015 ASL R0 ;;;ADD TRACK - TRACK SKEW ; PJC015 ADD R0,R1 ;;;SKEW BY 2*TRACK ; PJC015 ADD R0,R1 ;;;SKEW BY 4*TRACK ; PJC015 ADD R0,R1 ;;;SKEW BY 6*TRACK ; PJC015 ASR R0 ;;;RESTORE TRACK NUMBER ; PJC015 MOV #26.,R2 ;;;SET MODULUS ; PJC015 20$: SUB R2,R1 ;;;MODULO SECTOR INTO RANGE -26. TO -1. ; PJC015 BGE 20$ ;;;IF GE LOOP TIL NEGATIVE ; PJC015 ADD R2,R1 ;;;CONVERT TO RANGE 0-25. ; PJC015 INC R0 ;;;LBN0 STARTS ON TRACK 1 ; PJC015 25$: INC R1 ;;;CONVERT TO RANGE 1-26. ; PJC015 MOVB R1,SECTOR ;;;SAVE SECTOR NUMBER ; PJC015 MOVB R0,TRACK ;;;SAVE TRACK NUMBER ; PJC015 MOV (SP)+,R2 ;;;RESTORE REGISTERS ; PJC015 MOV (SP)+,R1 ;;; ; PJC015 MOV (SP)+,R0 ;;; ; PJC015 RETURN ; PJC015 ; PJC015 ; PJC015 .ENDC ;CDA$DX!CDA$DY ; PJC015 ; PJC015 ; PJC015 WERR: MOV #IOERR,R1 ;;;INDICATE I/O ERROR CALL TYPE ;;;TYPE OUT MESSAGE JMP AGAIN ;;;WAIT FOR THE USER $CRCMP: .ENDC .IF DF P$$NIC JMP $PANIC ;;;JUMP TO PANIC DUMP ROUTINE .ENDC .ENDC ;C$$RSH ;MSH054 ;**-1 ;+ ; IF B$$OOT IS DEFINED, RE-BOOT THE SYSTEM BY JUMPING TO THE ; BOOTSTRAP ROM ADDRESS SPECIFIED BY B$$OOT. ELSE, RE-ISSUE ; THE CRASH äMESSAGE IF THE USER WISHES ANOTHER DUMP. IF NO ; CRASH DUMP WAS CONFIGURED, SIMPLY RE-BOOT OR HALT FOREVER. ;- $BTSTP:: ;;;RE-BOOT THE SYSTEM .IF DF B$$OOT HALT ;;;WAIT FOR THE USER BEFORE BOOTING RESET ;;;RESET THE WORLD JMP @#B$$OOT ;RE-BOOT THE SYSTEM .IFF HALT ;;;WAIT FOR THE USER .IF DF C$$RSH .IF DF C$$CDA JMP AGAIN ;;;DO IT ALL OVER AGAIN .ENDC .IFF BR .-2 ;;;LOOP FOREVER .ENDC .ENDC .END äÔfðskQ ›c, .TITLE PRDRV .IDENT /02.01/ ; ; COPYRIGHT (C) 1975, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.01 ; ; THOMAS J. MILLER 2-DEC-74 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; ; MODIFIED BY: ; ; E. L. BAATZ 18-JUN-78 ; ; EB148 -- REMOVE EXPLICIT PS REFERENCE ; ; PC11/PR11 PAPER TAPE READER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HWDDF$,PKTDF$ ABODF$ ;DEFINE TASK ABORT CODES HWDDF$ ;DEFINE HARDWARE REGISTER SYMBOLS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; ; PAPER TAPE READER STATUS WORD BIT DEFINITIONS (U.CW2) ; TRAIL=100000 ;CURRENTLY READING TRAILER ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW P$$R11 ;ADDRESS OF UNIT CONTROL BLOCK .IF GT P$$R11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER  .ENDC ; ; DRIVER DISPATCH TABLE ; $PRTBL::.WORD PRINI ;DEVICE INITIATOR ENTRY POINT .WORD PRCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD PROUT ;DEVICE TIMEOUT ENTRY POINT .WORD PRPWF ;POWERFAIL ENTRY POINT ;+ ; **-PRINI-PC11/PR11 PAPER TAPE READER CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB PRINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS PRPWF ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; PAPER TAPE READER I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.ATT OR IO.DET). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; MOV R5,CNTBL(R3) ;SAVE UCB POINTER FOR INTERRUPT ROUTINE MOVB I.FCN+1(R1),R2 ;MOVE FUNCTION CODE TO R2 CMPB R2,#IO.RLB/256. ;READ LOGICAL BLOCK FUNCTION? BEQ 10$ ;IF EQ YES MOV #IS.SUC&377,R0 ;OTHER FUNCTIONS ALWAYS SUCCEED CLR R1 ;RETURN 0 IN SECOND WORD OF STATUS BUFFER CMPB R2,#IO.ATT/256. ;ATTACH FUNCTION? BNE 50$ ;IF NE NO, CALL $IODON BIS #TRAIL,U.CW2(R5) ;SET FLAG TO READ TRAILER IF ATTACH BR 60$ ;CALL $IODON 10$: MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT COUNT TST @S.CSR(R4) ;ERROR BIT SET IN STATUS REGISTER? BPL 15$ ;IF PL NO, INITIATE IO TST U.CW2(R5) ;IS THIS THE FIRST READ FOR ATTACHED PROCESS? BMI 70$ ;IF MI YES, RETURN DEVICE NOT READY CODE ; (OTHERWISE HANDLE AS EOF UPON INTERRUPT) 15$: MOV #101,@S.CSR(R4) ;ENABLE READER WITH INTERRUPTS ; ; IN-PROGRESS TRANSFERS ARE NOT TERMINATED. ; PRCAN: ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION ; PRPWF: RETURN ; ;+ ; **-$PRINT-PC11/PR11 PAPER TAPE READER CONTROLLER INTERUPTS ;- $PRINT:: ;;;REF LABEL INTSV$ PR,PR4,P$$R11 ;;;GENERATE INTERRUPT SAVE CODE MOV U.SCB(R5),R4 ;;;GET ADDRESS OF STATUS CONTROL BLOCK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT MOV S.CSR(R4),R4 ;;;POINT R4 TO CONTROL STATUS REGISTER MOV (R4)+,U.CW3(R5) ;;;SAVE STATUS BMI 40$ ;;;IF MI, ERROR TST U.CW2(R5) ;;;READING TRAILER? BPL 20$ ;;;IF PL NO TSTB (R4) ;;;IS BYTE READ A NULL? BEQ 30$ ;;;IF EQ YES CLR U.CW2(R5) ;;;NO LONGER READING TRAILER 20$: MOVB (R4),-(SP) ;;;PUSH BYTE READ CALL $PTBYT ;;;PLACE IT IN USER BUFFER DEC U.CNT(R5) ;;;DECREMENT BYTE COUNT BEQ 40$ ;;;IF EQ READ COMPLETE 30$: INC -(R4) ;;;ENABLE READER JMP $INTXT ;;;EXIT FROM INTERRUPT 40$: CLR -(R4) ;;;DISABLE INTERRUPTS CALL $FORK ;;;CREATE SYSTEM PROCESS MOV U.SCB(R5),R4 ;POINT R4 TO SCB MOV S.PKT(R4),R1 ;POINT R1 TO I/O PACKET MOV I.PRM+4(R1),R1 ; AND PICK UP CHARACTER COUNT SUB U.CNT(R5),R1 ;CALCULATE CHARACTERS TRANSFERRED MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER TST U.CW3(R5) ;DEVICE ERROR? BPL 50$ ;IF PL NO MOV #IE.EOF&377,R0 ;RETURN END OF FILE CODE 50$: CLR U.CW2(R5) ;CLEAR FLAG WORD 60$: CALL $RIODON ;INITIATE I/O COMPLETION BR PRINI ;BRANCH BACK FOR NEXT REQUEST ; ; DEVICE TIMEOUT RESULTS IN THE RETURN OF A DEVICE NOT READY ERROR CODE. ; PROUT: CLR @S.CSR(R4) ;;;DISABLE READER INTERRUPTS MTPS #0 ;;;ALLOW INTERRUPTS 70$: MOV #IE.DNR&377,R0 ;DEVICE NOT READY CODE BR 50$ ;CALL $IODON .DSABL LSB .END RäðskQ ›c, .TITLE CTDRV .IDENT /07/ ; ; COPYRIGHT (C) 1974, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 07 ; ; D. N. CUTLER 13-MAR-74 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; B. LYONS ; ; MODIFIED BY: ; ; P. J. BEZEREDI 04-MAR-77 ; ; PB019 -- FIX A BUG IN THE ERROR LOGGING LOGIC. ; ; TA11 TAPE CASSETTE CONTROLLER DRIVER ; ; NOTE: THIS IS A MINIMAL DRIVER AND CONTAINS NO ERROR RECOVERY. ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLER NUMBER) ; CNTBL: .BLKW T$$A11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK .IF GT T$$A11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; ERROR PROCESSING CONTROL TABLE ; ERRTB: .BYTE IE.DNR&377,1000/400 ;DEVICE NOT READY .BYTE IE.WLK&377,10000/400 ;DRIVE WRITE LOCKED .BYTE IE.EOT&377,20000/400 ;END OF TAPE .BYTE IE.EOF&377,4000/400 ;END OF FILE .BYTE IE.DAO&377,2000/400 ;DATA OVERRUN .BYTE IE.VER&377,377 ;BLOCK CHECK ERROR ; ; LEGAL FUNCTION DISPATCH TABLE ; LGFCN: .WORD IO.RLB ;READ LOGICAL BLOCK .BYTE 105,10. ; .WORD RDBLK ; .WORD IO.WLB ;WRITE LOGICAL BLOCK .BYTE 103,10. ; .WORD WRBLK ; .WORD IO.EOF ;WRITE END OF FILE .BYTE 101,10. ; .WORD WREOF ; .WORD IO.RWD ;REWIND .BYTE 117,34. ; .WORD WREOF ; .WORD IO.SPB ;SPACE BLOCK .BYTE 115,128. ; .WORD SPCBK ; .WORD IO.SPF ;SPACE FILE .BYTE 113,128. ; .WORD SPCBK ; ; ; DRIVER DISPATCH TABLE ; $CTTBL::.WORD CTINI ;DEVICE INITIATOR ENTRY POINT .WORD CTCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD CTOUT ;DEVICE TIMEOUT ENTRY POINT .WORD CTPWF ;POWERFAIL ENTRY POINT ;+ ; **-CTINI-TA11 TAPE CASSETTE CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB CTINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS CTPWF ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; TA11 TAPE CASSETTE FUNCTION INDEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO. RLB 1 IO.RWD/IO.SPB/IO.SPF/IO.EOF). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB MOV #LGFCN,R3 ;POINT TO LEGAL FUNCTION TABLE MOV #6,R0 ;SET NUMBER OF ENTRIES IN TABLE 10$: CMP I.FCN(R1),(R3)+ ;FUNCTION CODE MATCH? BEQ 20$ ;IF EQ YES CMP (R3)+,(R3)+ ;POINT TO NEXT TABLE ENTRY DEC R0 ;ANY MORE TABLE ENTRIES? BGT 10$ ;IF GT YES MOV #IE.IFC&377,R0 ;SET ILLEGAL FUNCTION STATUS BR 50$ ;FINISH IN COMMON CODE ; ; FUNCTION CODE MATCH FOUND ; 20$: SWAB R2 ;SWAP UNIT NUMBER TO LEFT BYTE BISB (R3)+,R2 ;MERGE FUNCTION CODE WITH UNIT MOVB (R3)+,S.ITM(R4) ;SPACING FUNCTION? BPL 30$ ;IF PL NO ; ; SPACING FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- SPACING COUNT (POSITIVE=FORWARD, NEGATIVE=BACKWARD). ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; MOV U.BUF(R5),I.PRM+4(R1) ;MOVE SPACING COUNT TO COMMON PLACE MOV U.BUF(R5),U.CNT(R5) ;MOVE SPACING COUNT TO COMMON PLACE BEQ 40$ ;IF EQ NO SPACING REQUIRED BPL 30$ ;IF PL SPACE FORWARD NEG U.CNT(R5) ;CONVERT TO POSITIVE COUNT NEG I.PRM+4(R1) ;CONVERT TO POSITIVE COUNT SUB #4,R2 ;CONVERT TO REVERSE FUNCTION ; ; READ/WRITE LOGICAL FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; ; NO FUNCTION DEPENDENT PARAMETERS ARE REQUIRED FOR REWIND AND WRITE EOF ; 30$: MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT MOV (R3),U.CW2(R5) ;SET INITIAL INTERRUPT ADDRESS .IF DF E$$DVC CALL $BMSET ; SET I/O ACTIVE IN BITMAP .ENDC MOV R2,@S.CSR(R4) ;INITIATE FUNCTION ; ; CANCEL I/O OPERATION IS A NOP FOR TA11 TAPE CASSETTES. ; CTCAN: ;REF LABEL ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ; CTPWF: RETURN ; ; ; NO SPACING REQUIRED ; 40$: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS 50$: BR 110$ ; ;+ ; **-$CTINT-TA11 TAPE CASSETTE CONTROLLER INTERRUPTS ;- INTSE$ CT,PR6,T$$A11 ;;;GENERATE INTERRUPT SAVE CODE MOV R3,-(SP) ;;;SAVE R3 MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;;;RESET CURRENT DEVICE TIMEOUT COUNT MOV S.CSR(R4),R3 ;;;GET ADDRESS OF CSR BIT #200,(R3)+ ;;;TRANSFER REQUEST? BNE 60$ ;;;IF NE YES MOV -2(R3),U.CW3(R5) ;;;SAVE CURRENT STATUS 60$: CALL @U.CW2(R5) ;;;CALL INTERRUPT ROUTINE MOV (SP)+,U.CW2(R5) ;;;SAVE INTERRUPT RETURN ADDRESS MOV (SP)+,R3 ;;;RESTORE R3 JMP $INTXT ;;;EXIT FROM INTERRUPT ; ; SPACING FUNCTION (FILE AND BLOCK) ; SPCBK: BMI 70$ ;;;IF MI ERROR DEC U.CNT(R5) ;;;DECREMENT SPACING COUNT BLE 70$ ;;;IF LE DONE INC -(R3) ;;;INITIATE NEXT OPERATION CALL @(SP)+ ;;;SET INTERRUPT RETURN ADDRESS BR SPCBK ;;;GO AGAIN 70$: CLR -(R3) ;;;CLEAR INTERRUPT ENABLE TST (SP)+ ;;;REMOVE RETURN FROM STACK MOV (SP)+,R3 ;;;RESTORE R3 CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV U.CW3(R5),R1 ;GET FINAL STATUS BPL 90$ ;IF PL SUCCESS BICB #^C<7*2>,R1 ;CLEAR ALL BUT FUNCTION CODE CMPB #5*2,R1 ;FORWARD OR REVERSE FUNCTION? BLE 100$ ;IF LE FORWARD BIC #120777,R1 ;CLEAR ERROR, BOT, UNIT, AND FUNCTION BEQ 40$ ;IF EQ NO ERRORS BR 100$ ;ANALYZE ERROR ; ; READ LOGICAL FUNCTION ; RDBLK: BMI WREOF ;;;IF MI ERROR DEC U.CNT(R5) ;;;DECREMENT BYTE COUNT BLT 80$ ;;;IF LT NO MORE TO READ MOV (R3),-(SP) ;;;READ BYTE FROM DATA REGISTER CALL $PTBYT ;;;PUT BYTE IN USER BUFFER CALL @(SP)+ ;;;SET INTERRUPT RETURN ADDRESS BR RDBLK ;;;GO AGAIN ; ; WRITE LOGICAL FUNCTION ; WRBLK: BMI WREOF ;;;IF MI ERROR DEC U.CNT(R5) ;;;DECREMENT BYTE COUNT BLT 80$ ;;;IF LT NO MORE TO WRITE CALL $GTBYT ;;;GET BYTE FROM USER BUFFER MOVB (SP)+,(R3) ;;;WRITE BYTE INTO DATA REGISTER CALL @(SP)+ ;;;SET INTERRUPT RETURN ADDRESS BR WRBLK ;;;GO AGAIN 80$: INC U.CNT(R5) ;;;ADJUST BYTE COUNT BIS #20,-(R3) ;;;INITIATE LAST BYTE SEQUENCE CALL @(SP)+ ;;;SET INTERRUPT RETURN ADDRESS ; ; REWIND AND WRITE END OF FILE FUNCTIONS ; WREOF: CLR -(R3) ;;;CLEAR INTERRUPT ENABLE TST (SP)+ ;;;REMOVE RETURN FROM STACK MOV (SP)+,R3 ;;;RESTORE R3 CALL $FORK ;;;CREATE A SYSTEM PROCESS 90$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL COMPLETION STATUS MOV U.CW3(R5),R1 ;GET FINAL STATUS BPL 110$ ;IF PL SUCCESS 100$: SWAB R1 ;SWAP ERROR BITS TO LOW BYTE MOV #ERRTB,R2 ;GET ADDRESS OF ERROR CONTROL TABLE 105$: CLR R0 ;PICKUP NEXT ERROR STATUS CODE BISB (R2)+,R0 ; BITB (R2)+,R1 ;ERROR BIT SET? BEQ 105$ ;IF EQ NO .IF DF E$$DVC BITB #26,R1 ;WRITE LOCK, TIMING OR OFF-LINE? BEQ 110$ ;IF EQ NO CALL $DVERR ;LOG DEVICE ERROR .ENDC BR 110$ ;FINISH I/O ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED. TIMEOUTS ARE ; USUALLY CAUSED BY POWERFAILURE BUT ALSO MAY BE THE RESULT OF A HARD- ; WARE FAILURE. ; CTOUT: CALL $DTOER ;;;LOG DEVICE TIMEOUT 110$: MOV S.PKT(R4),R1 ;RETRIEVE ADDRESS OF I/O PACKET MOV I.PRM+4(R1),R1 ;GET ORIGINAL COUNT VALUE SUB U.CNT(R5),R1 ;SUBTRACT COUNT REMAINING .IF DF E$$DVC MOV #401,R2 ; SET CURRENT & FINAL RETRY COUNT TOh 1 .ENDC CALL $IODON ;FINISH I/O OPERATION JMP CTINI ;GO AGAIN .DSABL LSB .END hBkQ ›c, .TITLE CVRTM .IDENT /03.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 03.00 ; ; D. N. CUTLER 12-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; ; MODIFIED BY: ; ;+ ; **-$CVRTM-CONVERT TIME ; ; THIS ROUTINE IS CALLED TO CONVERT A TIME INTERVAL-TIME UNITS PAIR ; TO A CLOCK TICKS COUNT. ; ; INPUTS: ; ; R3=ADDRESS OF TIME INTERVAL-TIME UNITS PAIR. ; ; OUTPUTS: ; ; IF AN ILLEGAL TIME INTERVAL (GREATER THAN 15 BITS) OR ; ILLEGAL TIME UNITS (ZERO OR GREATER THAN 4) IS SPECIFIED, ; THEN A DIRECTIVE STATUS OF 'D.RS93' IS RETURNED. ELSE THE ; TICKS COUNT IS RETURNED WITH THE HIGH ORDER PART IN R0 AND ; THE LOW ORDER PART IN R1. R3 IS ADVANCED BY 4 THUS POINTING ; PAST THE TIME INTERVAL-TIME UNITS PAIR. ;- $CVRTM::MOV (R3)+,R1 ;GET TIME INTERVAL BMI 70$ ;IF MI ILLEGAL TIME INTERVAL MOV (R3)+,R0 ;GET TIME UNITS DEC R0 ;BACK OFF BY ONE CMP R0,#3 ;LEGAL UNITS? BHI 70$ ;IF HI NO ASL R0 ;CONVERT TO DISPATCH INDEX ADD R0,PC ;DISPATCH 10$: BR 50$ ;1=TICKS BR 30$ ;2=SECONDS BR 20$ ;3=MINUTES MOV #60.,R0 ;4=HOURS CALL $MUL ;CALCULATE NUMBER OF MINUTES TST R0 ;OVERFLOW 16 BITS? BNE 70$ ;IF NE YES 20$: CMP R1,#1440. ;MORE THAN ONE DAY OF MINUTES? BHI 70$ ;IF HI YES MOV #30.,R0 ;MULTIPLY BY 60. SECONDS/2 CALL $MUL ;PRODUCT CANNOT OVERFLOW 16 BITS. MOV $@TKPS,R0 ;GET TICKS PER SECOND ASL R0 ;MULTIPLY BY 2 BR 40$ ; 30$: MOV $TKPS,R0 ;GET TICKS PER SECOND 40$: CALL $MUL ;CALCULATE TICKS COUNT 50$: MOV R0,R2 ;TICKS COUNT ZERO? BIS R1,R2 ; BNE 60$ ;IF NE NO INC R1 ;MAKE TICKS COUNT 1 60$: RETURN ; 70$: DRSTS D.RS93 ;SET DIRECTIVE STATUS .END @TðskQ ›c, .TITLE DBDRV .IDENT /06.10/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 06.10 ; ; D. N. CUTLER 2-JUL-74 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; R. T. PERRON ; ; MODIFIED BY: ; ; R. T. PERRON 25-JUN-79 ; ; RP015 -- CORRECTION TO OFFSET RECOVERY AND HEADER ; COMPARE ERRORS FIX ; ; R. T. PERRON 06-AUG-79 ; ; RP021 -- CORRECT ERROR RECOVERY FOR LAST BLOCK TRANSFERED ; ; R. T. PERRON 01-APR-80 ; ; RP030 -- CORRECT ECC ERROR RECOVERY ON RH11 CONTROLLERS ; ; P. J. CARR 18-APR-80 ; ; PJC003 -- REMOVE M$$IXD STUFF ; ; R. T. PERRON 21-NOV-80 ; ; RP041 -- CHANGE INTERFACE TO COMMON ECC ROUTINE ; ; P. J. CARR 1-APR-81 ; ; PJC026 -- CORRECT MORE ERROR RECOVERY PROCEDURES ; ; P. J. BEZEREDI 15-APR-81 ; ; PB237 -- MAKE BETTER USE OF EIS. ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; R. T. PERRON 16-OCT-81 ; ; RP075 -- CORRECT NON-EIS ADDRESS CALCULATION IN ECC CODE ; ; P. J. CARR 27-OCT-81 ; ; PJC038 -- CLEAN UP CODE ; ; RH11-RP04/05/06 DISK PACK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; ; DEVICE REGISTER AND STATUS BIT DEFINITIONS ; RPCS1=0 ;CONTROL STATUS REGISTER 1 TRE=40000 ;TRANSFER ERROR MCPE=20000 ;MASSBUS CONTROL PARITY ERROR RPWC=2 ;WORD COUNT REGISTER RPBA=4 ;BUFFER ADDRESS REGISTER RPDA=6 ;DESIRED TRACK/SECTOR REGISTER RPCS2=10 ;CONTROL STATUS REGISTER 2 DLT=100000 ;DATA LATE ERROR WCE=40000 ;WRITE CHECK ERROR UPE=20000 ;UNIBUS PARITY ERROR NED=10000 ;NONEXISTENT DISK ERROR NEM=4000 ;NONEXISTENT MEMORY ERROR PGE=2000 ;PROGRAMMING ERROR MXF=1000 ;MISSED TRANSFER ERROR MDPE=400 ;MASSBUS DATA PARITY ERROR RPDS=12 ;DRIVE STATUS REGISTER ERR=40000 ;ERROR SUMMARY BIT PIP=20000 ;POSITIONING IN PROGRESS ; PJC026 MOL=10000 ;MEDIUM ONLINE WRL=4000 ;WRITE LOCKED DRIVE DRY=200 ;DRIVE READY VV=100 ;VOLUME VALID RPER1=14 ;ERROR SUMMARY REGISTER DCK=100000 ;DATA CHECK ERROR UNS=40000 ;DRIVE UNSAFE OPI=20000 ;OPERATION INCOMPLETE DTE=10000 ;DRIVE TIMING ERROR WLE=4000 ;WRITE LOCK ERROR IAE=2000 ;INVALID DISK ADDRESS AOE=1000 ;ADDRESS OVERFLOW HCRC=400 ;HEADER CRC ERROR HCE=200 ;HEADER COMPARE ERROR ECH=100 ;ECC HARD ERROR WCF=40 ;WRITE CLOCK FAILURE FER=20 ;FORMAT ERROR CPE=10 ;CONTROL BUS PARITY ERROR RMR=4 ;REGISTER MODIFY REFUSED ILR=2 ;ILLEGAL REGISTER ILF=1 ;ILLEGAL FUNCTION RPAS=16 ;ATTENTION SUMMARY REGISTER RPLA=20 ;LOOKAHEAD REGISTER RPDBR=22 ;DATA BUFFER REGISTER RPMR=24 ;MAINTENENCE REGISTER RPDT=26 ;DRIVE TYPE REGISTER RPSN=30 ;DRIVE SERIAL NUMBER RPOF=32 ;DRIVE OFFSET REGISTER FMT22=10000 ;FORMAT (1=16 BIT) ECI=4000 ;ECC INHIBIT HCI=2000 ;HEADER COMPARE INHIBIT RPDC=34 ;DESIRED CYLINDER NUMBER RPER2=40 ;ERROR REGISTER 2 RPEC1=44 ;ECC POSITION REGISTER RPEC2=46 ;ECC PATTERN REGISTER RPBAE=50 ;BUS ADDRESS EXTENSION REGISTER ;**-7 ; ; LOCAL EQUATED SYMBOLS ; RETRY=8. ;CONTROLLER ERROR RETRY COUNT IHC=1 ;INHIBIT HEADER COMPARE OFA=10 ;OFFSET ACTIVE BIT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLER NUMBER) ; CNTBL: .BLKW R$$JP1 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$JP1 ;RETRY COUNT FOR CURRENT OPERATION .IF GT R$$JP1-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC .IF DF R$$JPO OFFAD: .BLKW R$$JP1 ;ADDRESS OF CURRENT OFFSET VALUE ; ; OFFSET POSITIONING VALUE TABLE ; OFFTB: .WORD FMT22!20 ;+400 .WORD FMT22!220 ;-400 .WORD FMT22!40 ;+800 .WORD FMT22!240 ;-800 .WORD FMT22!60 ;+1200 .WORD FMT22!260 ;-1200 .WORD 0 ;RETURN TO CENTERLINE .ENDC .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS ; ; DIAGNOSTIC FUNCTION TABLE ; FUNTBL: .BYTE 107, IO.HMS!IQ.UMD&377 .BYTE 105, IO.BLS!IQ.UMD&377 .BYTE 115, IO.OFF!IQ.UMD&377 .BYTE 173, IO.RDH!IQ.UMD&377 .BYTE 163, IO.WDH!IQ.UMD&377 .BYTE 151, IO.WCK!IQ.UMD&377 FUNTBE: .ENDC ; ; DRIVER DISPATCH TABLE ; $DBTBL::.WORD DBINI ;DEVICE INITIATOR ENTRY POINT .WORD DBCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DBOUT ;DEVICE TIMEOUT ENTRY POINT  .WORD DBPWF ;POWERFAIL ENTRY POINT ;+ ; **-DBINI-RH11-RP04/05/06 DISK PACK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB 10$: RETURN ;RETURN TO CALLER ; PJC038 DBINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS ;**-1 BCS 10$ ;IF CS, CONTROLLER BUSY OR NO REQUEST ; PJC038 ;**-1 ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RH11-RP04/05/06 DISK PACK I/O REQUEST PACKET FORMAT ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- DIAGNOSTIC SUPPLIMENTAL PARAMETER ELSE NOT USED. ; WD. 16 -- HIGH PART OF LOGICAL BLOCK NUMBER AND HIGH BYTE NOT US ; WD. 17 -- LOW PART OF LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK ADRS. ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000). ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;IS IT A MASS BUS DEVICE? BNE 20$ ;IF NE YES -- DOES NOT USE UMR'S ; PJC038 CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS ;**-1 .ENDC ASL U.BUF(R5) ;SHIFT ADDRESS EXTENSION BITS INTO PLACE ASL U.BUF(R5) ; ASL U.BUF(R5) ; ASL U.BUF(R5) ; 20$: ;REF LABEL ; PJC038 ;**-1 .IF DF D$$IAG CMPB #IO.HMS/^D<256>,I.FCN+1(R1) ;DIAGNOSTIC FUNCTION? BNE 40$ ;IF NE NO ; PJC038 MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE ;**-1 30$: MOVB (R0)+,U.BUF(R5) ;LOAD CONTROLLER FUNCTION CODE ; PJC038 CMPB (R0)+,I.FCN(R1) ;IS IT THE CORRECT CODE? ;**-1 BEQ 60$ ;IF EQ YES ; PJC038 CMP #FUNTBE,R0 ;END OF FUNCTION TABLE? ;**-1 BNE 30$ ;IF NE NO ; PJC038 ;**-1 .ENDC 40$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION ; PJC038 MOVB #171,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION ;**-1 CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 50$ ;IF HIS, FUNCTION IS LEGAL ; PJC038 JMP 300$ ;FUNCTION IS ILLEGAL ; PJC038 50$: BEQ 60$ ;IF EQ, FUNCTION IS READ ; PJC038 SUB #10,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION ;**-3 60$: MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT ; PJC038 ;**-1 .IF DF R$$JPO CLRB U.CW2+1(R5) ;INITIALIZE RECOVERY VALUES CALL 540$ ;SET INITIAL OFFSET RECOVERY VALUES ; PJC038 ;**-1 .ENDC CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER ; PB237 ; PB237 .IF DF M$$EIS ; PB237 ; PB237 MOV R0,R1 ;REPOSITION LBN ; PB237 MOV R2,R0 ;... ; PB237 DIV #22.,R0 ;CALCULATE SECTOR NUMBER ; PB237 MOVB R1,I.PRM+12(R3) ;SAVE SECTOR NUMBER ; PB237 MOV R0,R1 ;SET NEW DIVIDEND ; PB237 CLR R0 ;CLEAR HIGH BITS ; PB237 DIV #19.,R0 ;CALCULATE CYLINDER AND TRACK ; PB237 MOV R0,I.PRM+10(R3) ;SAVE CYLINDER NUMBER ; PB237 MOVB R1,I.PRM+13(R3) ;SAVE TRACK NUMBER ; PB237 ; PB237 .IFF ; PB237 ; PB237 MOV #16.,R1 ;SET DIVIDE LOOP COUNT 70$: ASL R0 ;DOUBLE LEFT SHIFT ; PJC038 ROL R2 ; ;**-1 CMP R2,#19.*22. ;PARTIAL REMAINDER LARGER THAN DIVISOR? BLO 80$ ;IF LO NO ; PJC038 SUB #19.*22.,R2 ;SUBTRACT OUT DIVISOR ;**-1 INC R0 ;ACCUMULATE QUOTIENT 80$: DEC R1 ;ANY MORE PARTIAL DIVIDES? ; PJC038 BGT 70$ ;IF GT YES ; PJC038 MOV R0,I.PRM+10(R3) ;SAVE DESIRED CYLINDER ADDRESS ;**-2 MOV R2,R0 ;SET DIVIDEND TO TRACK/SECTOR REMAINDER MOV #22.,R1 ;SET DIVISOR TO NUMBER OF SECTORS/TRACK CALL $DIV ;CALCULATE TRACK AND SECTOR SWAB R0 ;SWAP TRACK TO HIGH BYTE BIS R1,R0 ;MERGE TRACK MOV R0,I.PRM+12(R3) ;SAVE DESIRED TRACK AND SECTOR ADDRESS ; PB237 .ENDC ; PB237 ;**-7 ; ; INITIATE I/O OPERATION ; 90$: ;REF LABEL ; PJC038 ;**-1 .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;IS IT A MASS BUS DEVIS? BNE 100$ ;IF NE YES -- DOES NOT USE UMR'S ; PJC038 CALL $MPUBM ;MAP UNIBUS TO MEMORY ;**-1 100$: ;REF LABEL ; PJC038 ;**-1 .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT ADD #10,R2 ;POINT TO SECOND CSR MOV #40,(R2) ;CLEAR RH11 CONTROLLER AND ALL DRIVES MOVB U.UNIT(R5),(R2) ;SELECT PROPER DRIVE MOV I.PRM+12(R1),-(R2) ;INSERT TRACK/SECTOR ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;MAKE NEGATIVE WORD COUNT MOV #23,-(R2) ;EXECUTE PACK ACK FUNCTION TO SET VV .IF NDF R$$JPO!D$$IAG MOV #FMT22,RPOF(R2) ;SET 16 BIT FORMAT .IFF MOV #FMT22,-(SP) ;GET FORMAT BIT .IF DF D$$IAG CMP #IO.OFF!IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OFFSET FUNCTION? BNE 110$ ;IF NE NO ; PJC038 BIS I.PRM+6(R1),(SP) ;YES, SET OFFSET VALUE ;**-1 110$: ;REF LABEL ; PJC038 ;**-1 .ENDC .IF DF R$$JPO BITB #IHC,U.CW2+1(R5) ;INHIBIT HEADER COMPARE BEQ 120$ ;IF EQ NO ; PJC038 BIS #HCI,(SP) ;SET HEADER COMPARE INHIBIT ;**-1 .ENDC 120$: MOV (SP)+,RPOF(R2) ;SET OFFSET REGISTER ; PJC038 ;**-1 .ENDC MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY MOV I.PRM+10(R1),RPDC(R2) ;SET DESIRED CYLINDER ADDRESS MOV RPDS(R2),R3 ;GET CURRENT DRIVE STATUS COM R3 ;COMPLEMENT STATUS BIT #MOL!DRY!VV,R3 ;DRIVE READY AND ON-LINE? BNE 130$ ;IF NE NO ; PJC038 BIT #UNS,RPER1(R2) ;DRIVE UNSAFE? ;**-1 BEQ 150$ ;IF EQ NO ; PJC038 130$: ;REF LABEL ; PJC038 ;**-2 .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 170$ ;IF NE YES ; PJC038 ;**-1 .IFTF .IF DF D$$IAG  BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BEQ 140$ ;IF EQ NO ; PJC038 JMP 230$ ;PROCESS DIAGNOSTIC NOT READY ; PJC038 140$: ;REF LABEL ; PJC038 ;**-3 .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR .ENDC JMP 300$ ;FINISH UP ; PJC038 150$: ;REF LABEL ; PJC038 ;**-2 .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE IN BIT MAP .ENDC .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;;;IS IT A MASS BUS DEVICE? BEQ 160$ ;;;IF EQ NO -- DOES NOT USE UMR'S ; PJC038 MOVB U.BUF+1(R5),RPBAE(R2) ;;;SET ADDRESS EXTENSION BITS ;**-1 MOVB U.BUF(R5),(R2) ;;;START FUNCTION RETURN ;;; .ENDC 160$: MOV U.BUF(R5),(R2) ;;;START FUNCTION ; PJC038 ;**-1 ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DBCAN: RETURN ;;;NOP FOR RP04/05/06 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DBPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS THIS UNIT CURRENTLY BUSY? BEQ 180$ ;IF EQ NO ; PJC038 170$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC038 180$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ; PJC038 ;**-4 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DBINT-RH11-RP04/05/06 DISK PACK CONTROLLER ; INTERRUPT HANDLER ;- INTSE$ DB,PR5,R$$JP1 ;;;SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER .IF DF D$$IAG  BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION EXECUTED? BNE 230$ ;IF NE YES ; PJC038 ;**-1 .ENDC .IF DF R$$JPO BIT #40,(R2) ;OFFSET OR RTC FUNCTION? BEQ 200$ ;IF EQ YES ; PJC038 ;**-1 .ENDC BIT #TRE!MCPE,(R2) ;ANY ERRORS? BEQ 260$ ;IF EQ NO ; PJC038 ;**-1 .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC 190$: BIT #PIP,RPDS(R2) ;POSITIONING IN PROGRESS? ; PJC038 BNE 190$ ;IF NE YES, WAIT TIL DONE ; PJC038 MOV #IE.WLK&377,R0 ;ASSUME WRITE LOCK ERROR BIT #WLE,RPER1(R2) ;WRITE LOCK ERROR? BNE 290$ ;IF NE YES ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ;**-1 MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE 280$ ;IF NE YES ; PJC038 MOV RPER1(R2),R1 ;GET CONTENTS OF ERROR REGISTER ;**-1 BIT #UNS!IAE!AOE!RMR!ILR!ILF,R1 ;HARD ERROR? BNE 290$ ;IF NE YES ; PJC038 BIT #NED!NEM,RPCS2(R2) ;HARD ERROR? ;**-1 BNE 290$ ;IF NE YES ; PJC038 BIT #DLT!WCE!UPE!PGE!MXF!MDPE,RPCS2(R2) ;CONTROLLER ERROR? ;**-1 BNE 240$ ;IF NE YES, RETRY OPERATION ; PJC038 BIT #HCE,R1 ;HEADER COMPARE ERROR? ; RP041 BEQ 320$ ;IF EQ NO ; PJC038 ;**-2 .IF DF R$$JPO DEC RTTBL(R3) ;ANY RETRIES LEFT? ; PJC026 BLE 290$ ;IF LE NO ; PJC038 JMP 560$ ;GO ISSUE RECALIBRATE TO RECOVER ; PJC038 200$: MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ; PJC038 CMP #OFFTB+14,OFFAD(R3) ;FINAL OFFSET TRIED? ;**-1 BEQ 290$ ;IF EQ YES, ALL DONE ; PJC038 BIT #ERR,RPDS(R2) ;ANY ERRORS? ;**-1 BNE 250$ ;IF NE YES ; PJC038 ;**-1 .ENDC 210$: JMP 90$ ;RETRY ORIGINAL FUNCTION ; PJC038 ;**-1 ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE OPERATION WAS DIAGNOSTIC. TIMEOUTS ARE USUALLY CAUSED ; BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A HARDWARE FAILURE. ; DBOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP?  BEQ 220$ ;;;IF EQ NO ; PJC038 INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #16.,S.STS(R4) ;;;HAVE WE WAITED 1 MINUTE YET? ; PJC029 BEQ 220$ ;;;IF EQ YES ; PJC038 MTPS #0 ;;;ALLOW INTERRUPTS ;**-3 BR 210$ ;RETRY OPERATION ; PJC038 220$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC038 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-2 .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 240$ ;IF CC, TIMEOUT DURING NORMAL FUNCTION ; PJC038 230$: CALL $CRPAS ;PASS CONTROLLER REGISTER TO TASK ; PJC038 BR 290$ ;DIAGNOSTIC PROCESSING COMPLETE ; PJC038 ;**-3 .ENDC 240$: MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET ; PJC038 BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? ;**-1 BNE 280$ ;IF NE YES ; PJC038 ;**-1 .IF DF R$$JPO BITB #OFA,U.CW2+1(R5) ;TEST OFFSET ACTIVE? BEQ 250$ ;IF EQ NO ; PJC038 JMP 510$ ;CONTINUE OFFSET RECOVERY ; PJC038 250$: DECB RTTBL(R3) ;RETRY FUNCTION? ; PJC038 BGT 310$ ;IF GT YES ; PJC038 ;**-4 .IFF DECB RTTBL(R3) ;RETRY FUNCTION? BGT 210$ ;IF GT YES ; PJC038 ;**-1 .ENDC .IF DF D$$WCK BR 280$ ;FINISH UP ; PJC038 ;**-1 .IFTF 260$: ;REF LABEL ; PJC038 ;**-1 .IFT BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK? BNE 270$ ;IF NE YES ; PJC038 BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR? ;**-1 BEQ 290$ ;IF EQ NO ; PJC038 270$: CMPB #171,U.BUF(R5) ;WAS LAST FUNCTION A READ? ; PJC038 BEQ 290$ ;IF EQ YES ; PJC038 CMPB #161,U.BUF(R5) ;WAS LAST FUNCTION A WRITE? ;**-3 BNE 290$ ;IF NE NO ; PJC038 MOVB #151,U.BUF(R5) ;SET WRITE CHECK FUNCTION ;**-1 MOV #RETRY,RTTBL(R3);REINITIALIZE RETRY COUNT BR 210$ ;START WRITE CHECK OPERATION ; PJC038 ;**-1 .IFTF 280$: ;REF LABEL ; PJC038 ;**-1 .IFT BIT #WCE,RPCS2(R2) ;WRITE CHECK ERROR? BEQ 290$ ;IF EQ NO ; PJC038 MOV #IE.WCK&377,R0 ;SET WRITE CHECK ERROR ;**-1 .ENDC 290$: MOV S.PKT(R4),R3 ;GET I/O PACKET ADDRESS ; PJC038 MOV RPWC(R2),R1 ;GET WORDS REMAINING TO TRANSFER ;**-1 ASL R1 ;CONVERT TO BYTES LEFT TO TRANSFER ADD I.PRM+4(R3),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED MOV #40011,(R2) ;CLEAR CONTROLLER AND DRIVE 300$: ;REF LABEL ; PJC038 ;**-1 .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC  ;**-7 CALL $IODON ;FINISH I/O OPERATION JMP DBINI ;PROCESS NEXT REQUEST .IF DF R$$JPO 310$: CMPB #171,U.BUF(R5) ;IS THIS A READ OPERATION? ; PJC038 BNE 210$ ;IF NE NO ; PJC038 BISB #OFA,U.CW2+1(R5) ;SET OFFSET ACTIVE ;**-2 JMP 480$ ;RESET OFFSET TO ZERO ; PJC038 ;**-24 .ENDC ; ; START ECC CORRECTION PROCEDURE ; ; ;**-1 320$: CMPB #171,U.BUF(R5) ;IS THIS A READ OPERATION? ; PJC038 BNE 240$ ;IF NE NO ; PJC038 BIS RPER2(R2),R1 ;.OR.ERROR REGISTER 2 ; RP015 BISB RPCS2+1(R2),R1 ;.OR.HIGH BYTE OF STATUS REGISTER 2 ; RP015 CMP #DCK,R1 ;IS IT ONLY A DATA CHECK ERROR ? ; RP015 BNE 240$ ;IF NE NO, SOME OTHER ERROR ; PJC038 MOV RPWC(R2),R0 ;GET NEGATIVE # OF WORDS REMAINING ; RP041 ASL R0 ;CONVERT TO BYTES ; RP041 ADD U.CNT(R5),R0 ;CALCULATE BYTES ACTUALLY TRANSFERED ; RP041 ; RP041 ; RP041 .IF DF R$$JPO ; RP041 ; RP041 BEQ 440$ ;IF EQ NONE TRANSFERED, TRY OFFSET RECOV; PJC038  ; RP041 .IFF ; RP041 ; RP041 BNE 330$ ;IF NE SOME TRANSFERED ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ; RP041 BR 240$ ;AND GO ON ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 330$: MOV RPEC1,R1 ;GET ECC ERROR POSITION ; PJC038 MOV RPEC2,R3 ;GET ECC CORRECTION PATTERN ; RP041 MOV RPWC(R2),R2 ;GET REMAINING WORD COUNT ; RP041 ;**-7 .IF DF S$$ECC CALL $ECCOR ;CALL SHARED ECC ROUTINE ;**-2 ;**-8 .IFF MOV R0,-(SP) ;SAVE BYTE COUNT ; RP041 CLR R0 ;CLEAR HIGH ORDER ERROR POSITION ; RP041 DEC R1 ;CONVERT TO RELATIVE BIT NUMBER ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 DIV #20,R0 ;DIVIDE FOR: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV R1,R0 ;COPY ECC ERROR POSITION ; RP041 MOV #20,R1 ;SET DIVISOR TO CALCULATE: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 CALL $DIV ;PERFORM DIVISION ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 MOV R0,-(SP) ;SAVE WORD POSITION ; RP041 MOV R2,-(SP) ;SAVE REMAINING WORD COUNT ; RP041 CLR R2 ;CLEAR HIGH ORDER ERROR PATTERN ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 340$: ASHC R1,R2 ;SHIFT PATTERN INTO CORRECT POSITION ; PJC038  ; RP041 .IFF ; RP041 ; RP041 340$: DEC R1 ;ANY MORE SHIFTS LEFT TO PERFORM ; PJC038 BLT 350$ ;IF LT NO ; PJC038 ASL R3 ;DOUBLE LEFT SHIFT ; RP041 ROL R2 ; ; RP041 BR 340$ ; ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 350$: MOV 4(SP),R0 ;RETRIEVE BYTES ACTUALLY TRANSFERED ; PJC038 SUB #510.,R0 ;BACKUP TO BLOCK IN ERROR ... ; RP041 ;... OFFSET TO HIGH WORD IN ERROR ; RP041 ; RP041 ; RP041 .IF DF D$$IAG ; RP041 ; RP041 CALL $RELOP ;COMPUTE LOCATION IN PHYSICAL MEMORY ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV R0,-(SP) ;SAVE BYTE OFFSET ON STACK ; RP041 MOV U.BUF+2(R5),R1 ;GET LOW 16 BITS OF ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 MOVB U.BUF+1(R5),R0 ;GET HIGH BITS OF REAL ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$EXT ; RP041 ; RP041 BIT #DV.MBC,U.CW1(R5) ;CAN THIS CONTROLLER/UNIT DIRECTLY ..; RP041 ;... ADDRESS ALL OF PHYSICAL MEMORY ; RP041 BNE 360$ ;IF NE YES ; PJC038 ADD #,R4 ;POINT PAST PHYSICAL BUFFER ADDRESS ; RP041 ;CONTAINED IN THE UMR AREA ; RP041 MOV -(R4),R1 ;GET LOW 16 BITS OF PHYSICAL BUFFER ADDR; RP041 TSTB -(R4) ;SKIP THE NEXT BYTE ; RP041 MOVB -(R4),R0 ;GET HIGH 6 BITS OF PHYSICAL BUFFER ADDR; RP041 360$: MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 .IFF ; RP041 ; RP041 CLR R0 ; ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 ADD (SP)+,R1 ;CALCULATE NEW STARTING ADDRESS ... ; RP041 ADC R0 ;... ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ; RP041 ASHC #-10.,R1 ;...  ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV #10.,-(SP) ;SET COUNT FOR 10 SHIFTS ; RP041 370$: DEC (SP) ;ANY MORE SHIFTS TO PERFORM ; PJC038 BLT 380$ ;IF LT NO ; PJC038 ASL R1 ;DOUBLE LEFT SHIFT R1 ... ; RP075 ROL R0 ;... INTO R0 ; RP075 BR 370$ ; ; PJC038 380$: SWAB R1 ;SWAP BYTES ; PJC038 ASR R1 ;SHIFT RIGHT R1 ; RP075 ASR R1 ;... ; RP075 TST (SP)+ ;CLR THE STACK ; RP075 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 MOV R0,KISAR6 ;SET RELOCATION BIAS ; RP041 ADD #140000,R1 ;SET DISPLACEMENT ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 MOV (SP)+,R0 ;RETRIEVE REMAINING WORD COUNT ; RP041 BPL 390$ ;IF PL, THIS MAY HAVE BEEN A PARTIAL BLO; PJC038 ;TRANSFER ; PJC038 CLR R0 ;ASSUME A WHOLE BLOCK WAS TRANSFERRED ; RP041 390$: ADD (SP),R1 ;ADD IN ERROR WORD POSITION OFFSET ... ; PJC038 ADD (SP),R1 ;... FOR BYTE ADDRESSING ; RP041 ADD (SP)+,R0 ;ADD CORRECTION OFFSET TO CORRECTION LIM; RP041 CMP R0,#377 ;IS THE CORRECTION ENTIRELY IN THIS BLOC; RP041 BHI 410$ ;IF HI NOT AT ALL ; PJC038 BEQ 400$ ;IF EQ THEN ONLY ONE WORD ; PJC038 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 XOR R2,(R1) ;CORRECT HIGH ORDER WORD ; RP041 400$: XOR R3,-(R1) ;CORRECT LOW ORDER WORD ; PJC038 ; RP041 .IFF ; RP041 ; RP041 MOV (R1),R0 ;COPY HIGH ORDER DATA WORD ; RP041 BIC R2,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R2 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R2,(R1) ;PATTERN.OR.DATA WORD ; RP041 400$: MOV -(R1),R0 ;COPY LOW ORDER DATA WORD ; PJC038 BIC R3,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R3 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R3,(R1) ;PATTERN.OR.DATA WORD ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 410$: MOV (SP)+,R1 ;RESTORE BYTES TRANSFERRED ; PJC038 MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX ; RP041 MOV S.CSR(R4),R2 ;RESTORE CSR ADDRESS ; RP041 MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER ;**-70 ;**-8 .ENDC ; RP041 MOVB #11,(R2) ;CLEAR DRIVE ERRORS ; RP041 ; RP041 .IF DF R$$JPO CALL 540$ ;RESET RECOVERY PARAMETERS ; PJC038 SUB R1,U.CNT(R5) ;ANY MORE WORDS TO TRANSFER? ;**-2 .IFF TST RPWC(R2) ;ANY MORE WORDS TO TRANSFER? .IFTF BEQ 290$ ;IF EQ NO ; PJC038 ;**-1 .IFT .IF DF M$$MGE .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;IS IT A MASS BUS DEVICE? BEQ 420$ ;IF EQ NO -- DOES USE UMR'S ; PJC038 MOVB RPBAE(R2),U.BUF+1(R5) ;SAVE MEMORY EXTENSION BITS ;**-1 BR 430$ ; ; PJC038 ;**-1 .ENDC 420$: MOVB RPCS1+1(R2),U.BUF+1(R5) ;SAVE MEMORY EXTENSION BITS ; PJC038 BICB #^C<3>,U.BUF+1(R5) ;CLEAR EXCESS BITS ;**-1 430$: ;REF LABEL ; PJC038 ;**-1 .ENDC MOV RPBA(R2),U.BUF+2(R5) ;SAVE BUFFER ADDRESS MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET MOV RPDC(R2),I.PRM+10(R1) ;SAVE CYLINDER ADDRESS MOV RPDA(R2),I.PRM+12(R1) ;SAVE TRACK/SECTOR ADDRESS .ENDC MOVB U.BUF(R5),(R2) ;RESTART PREVIOUS OPERATION RETURN ; ;**-70 ; ; OFFSET RECOVERY ; .IF DF R$$JPO 440$: TST R0 ;ANY GOOD SECTORS TRANSFERRED? ; PJC038 BEQ 500$ ;IF EQ NO ; PJC038 ;**-3 ; ; THE TRANSFER ENDED IN AN ECC HARD ERROR BUT THERE WERE SECTORS ; TRANSFERED THAT CONTAINED GOOD DATA. SINCE THE ECC HARD ERROR COULD ; HAVE BEEN CAUSED BY A CYLINDER CROSSING, THE GOOD DATA IS SAVED ; AND THE TRANSFER IS RETRIED FROM THE POINT OF ERROR. ; SUB R0,U.CNT(R5) ;REDUCE BYTES REMAINING TO TRANSFER ; RP021 BNE 450$ ;IF NE MORE SECTORS TO TRANSFER ; PJC038 ADD R0,U.CNT(R5) ;LAST SECTOR, CORRECT BYTES REMAINING ; RP021 BR 480$ ;AND CONTINUE ; PJC038 450$: ADD R0,U.BUF+2(R5) ;UPDATE STARTING BUFFER ADDRESS ; PJC038 ADCB U.BUF+1(R5) ;PROPAGATE CARRY INTO EXTENSION BITS ; RP021 SWAB R0 ;CALCULATE NUMBER OF SECTORS TRANSFERED ;**-3 ASR R0 ; MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET ADD I.PRM+12(R1),R0 ;UPDATE TRACK/SECTOR ADDRESS 460$: CMPB #22.,R0 ;SECTOR OVERFLOW? ; PJC038 BHI 470$ ;IF HI NO ; PJC038 SUB #22.,R0 ;SUBTRACT OUT A SECTOR ;**-2 ADD #1*256.,R0 ;ADD IN A TRACK CMP #19.*256.,R0 ;TRACK OVERFLOW? BHI 460$ ;IF HI NO ; PJC038 SUB #19.*256.,R0 ;NORMALIZE TRACK ADDRESS ;**-1 INC I.PRM+10(R1) ;UPDATE CYLINDER ADDRESS BR 460$ ; ; PJC038 470$: MOV R0,I.PRM+12(R1) ;SET UPDATED TRACK/SECTOR ADDRESS ; PJC038 480$: CALL 550$ ;RESET OFFSET TABLE ADDRESS ; PJC038 490$: MOV #117,R1 ;SET RTC FUNCTION ; PJC038 MOVB #16.,RTTBL+1(R3) ;TRY 16. TIMES AT CENTERLINE ;**-4 MOV #FMT22,R0 ;RESET OFFSET VALUE TO ZERO BR 520$ ; ; PJC038 ;**-1 ; ; NO GOOD DATA WAS TRANSFERED - CHECK IF OFFSET SHOULD BE CHANGED ; 500$: BIT #DCK!DTE!ECH,R1 ;DATA CHECK OR DRIVE TIMING ERROR? ; PJC038 BNE 510$ ;IF NE YES ; PJC038 BISB #IHC,U.CW2+1(R5) ;SET HEADER COMPARE INHIBIT FLAG ;**-2 510$: DECB RTTBL+1(R3) ;CHANGE OFFSET? ; PJC038 BGT 530$ ;IF GT NO ; PJC038 ADD #2,OFFAD(R3) ;UPDATE OFFSET POINTER ;**-2 MOV @OFFAD(R3),R0 ;GET NEXT OFFSET VALUE BEQ 490$ ;IF EQ, RETURN TO CENTERLINE ; PJC038 MOV #115,R1 ;SET OFFSET FUNCTION ;**-1 MOVB #2,RTTBL+1(R3) ;SET RECOVERY RETRY COUNT BIT #2,RPDT(R2) ;IS THIS DRIVE AN RP04? BEQ 520$ ;IF EQ YES ; PJC038 ASRB R0 ;NO, IT'S AN RP06 SO ADJUST OFFSET ... ;**-1 BIC #100,R0 ;... VALUE AND SIGN ACCORDINGLY 520$: MOV #TRE!11,(R2) ;CLEAR CONTROLLER AND DRIVE ; PJC038 MOV R0,RPOF(R2) ;LOAD NEXT OFFSET VALUE ;**-1 BICB #IHC,U.CW2+1(R5) ;CLEAR HEADER COMPARE INHIBIT FLAG MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT MOVB R1,(R2) ;INITIATE OFFSET FUNCTION RETURN ; 530$: JMP 90$ ;RETRY FUNCTION ; PJC038 ;**-1 ; ; SET OFFSET RECOVERY PARAMETERS ; 540$: MOVB #1,RTTBL+1(R3) ;SET RECOVERY COUNT TO ONE ; PJC03j8 550$: MOV #OFFTB-2,OFFAD(R3) ;SET OFFSET TABLE POINTER ; PJC038 RETURN ; ;**-2 ; ; SET RECOVERY RECALIBRATION FOR 'HCE' ERROR ; 560$: MOV #TRE!11,(R2) ;CLEAR CONTROLLER AND DRIVE ; PJC038 MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT ;**-1 MOV #107,(R2) ;LOAD THE RECALIBRATE COMMAND RETURN ; .ENDC .DSABL LSB .END j¤ðskQ ›c, .TITLE DDDRV .IDENT /01.06/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 01.06 ; ; M. B. GROSSMAN 9/15/78 ; ; MODIFIED BY: ; ; P. J. CARR 5-AUG-80 ; ; PJC013 -- CORRECT MULTI-CONTROLLER OPERATION ; ; DAN BROWN 20-JAN-81 ; ; DTB012 -- REMOVE REFERENCES TO S.BMSK FOR NEW ; ERROR LOG. ; ; P. J. CARR 2-APR-81 ; ; PJC024 -- CLEAN UP INEFFICIENT CODE ; ; P. J. CARR 2-APR-81 ; ; PJC025 -- CORRECT TYPOGRAPHICAL ERRORS ; ; P. J. CARR 1-SEP-81 ; ; PJC031 -- CORRECT I/O PROCESSING DURING RETRIES ; ; P. J. CARR 28-DEC-81 ; ; PJC039 -- MODIFY ERROR LOGGING ROUTINE FOR ; NEW ERROR LOGGER ; ; TU58 TAPE CARTRIDGE DRIVER ; ; THIS DRIVER INTERFACES WITH THE TU58 VIA A DL11 AT 9600 BAUD. ; PJC025 ; COMMANDS, DATA AND DEVICE STATUS ARE FORMATTED INTO STRUCTURED ; PJC025 ; PACKETS OF BYTES IN ACCORDANCE WITH RADIAL SERIAL PROTOCOL. ; PJC025 ; ;**-4 ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RTRY= 2 ;RETRY COUNT ; PJC031 DDNUM= 6 ;NUMBER OF REGISTERS TO LOG ON ERROR ; PJC039 ; ;**-1 ; TU58 RADIAL SERIAL PROTOCOL SYMBOLS ; PJC025 ; ;**-1 ; INSTRUCITON SET ; PJC025 ; ; PJC025 READ= 2 ;READ INSTRUCTION ;**-1 WRITE= 3 ;WRITE INSTRUCTION POSIT= 5 ;POSITION INSTRUCTION -USER MODE DIAG. DIAG= 7 ;DIAGONOSE INSTRUCTION -USER MODE DIAG. ; ; PJC025 ; FLAGS ; PJC025 ; ; PJC025 DATA= 1 ;DATA FLAG ;**-1 CNTL= 2 ;CONTROL FLAG INIT= 4 ;INITIALIZE FLAG CONT= 20 ;CONTINUE FLAG ; ; THE TU58 NORMALLY INTERFACES VIA A DL11. AN EXCEPTION TO THIS IS ; PJC025 ; THE PDT 130. IN THE CASE OF THE PDT (R$$PDT DEFINED) THE NUMBER AND ;**-2 ; LOCATION OF THE DEVICE REGISTERS ARE DIFFERENT FROM THOSE OF THE ; DL11.  ; PJC025 ; ; PJC025 ;*** NOTE: AT THIS TIME THE PDT 130 TU58 CODE IS INTESTED! ; PJC025 ; ; PJC025 ; PJC025 ;**-2 .IF DF R$$PDT DDRCS= 0 ;RECEIVE CONTROL STATUS REGISTER DDRBF= 2 ;BUFFER REGISTER FOR BOTH RECEIVE DDXBF= 2 ; AND TRANSMIT DDXCS= 4 ;TRANSMITTER CONTROL STATUS REGISTER .IFF ; ; PJC025 ; DL11 INTERFACE REGISTER OFFSETS ; PJC025 ; ; PJC025 DDRCS= 0 ;RECEIVE CONTROL STATUS REGISTER ;**-2 DDRBF= 2  ;RECEIVE BUFFER REGISTER DDXCS= 4 ;TRANSMITTER CONTROL STATUS REGISTER DDXBF= 6 ;TRANSMITTER BUFFER REGISTER ;**-1 .ENDC ; PJC025 ; ; DL11 BIT ASSIGNMENTS ; PJC025 ; ;**-1 RDONE= 200 ;RECEIVER DONE RIE= 100 ;RECEIVER INTERRUPT ENABLE ERR= 100000 ;RECEIVER DATA ERROR TRDY= 200 ;TRANSMITTER READY TIE= 100 ;TRANSMITTER INTERRUPT ENABLE BRK= 1 ;TRANSMIT BREAK ; ; LOCAL DATA ; ; PJC025 CNTBL: .BLKW T$$U58 ;ADDRESS OF UCB ; PJC025 .IF GT T$$U58-1 TEMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC ; PJC025 .IF DF E$$DVC ; PJC039 ; PJC039 WORD1: .BLKW T$$U58 ;STORAGE FOR LAST THREE WORDS THAT ARE ; PJC039 WORD2: .BLKW T$$U58 ;TO GO IN ERROR PACKET ; PJC039 WORD3: .BLKW T$$U58 ; ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 ; ;DRIVER DISPATCH TABLE ; $DDTBL::.WORD DDINI ; PJC025 .WORD DDCAN ;**-1 .WORD DDOUT  .WORD DDPWF ; ; PJC025 ; PROGRAM SEQUENCE CONTROL ; PJC025 ; ; PJC025 ; PROGRAM FLOW IS CONTROLLED BY A POINTER TO A TABLE OF ; PJC025 ; ADDRESSES. THIS SEQUENCE CREATES AND DECODES THE RADIAL ; PJC025 ; SERIAL PACKET INFORMATION. THE ACTUAL USER DATA IS ; PJC025 ; TRANSFERRED WITHIN THE INTERRUPT SERVICE ROUTINE (ISR). ; PJC025 ; THIS METHOD PERMITS US TO WAIT FOR INTERRUPTS WITHOUT ; PJC025 ; HAVING TO PRESERVE ANY PROCESSOR REGISTERS (INCLUDING THE ; PJC025 ; STACK). REPETITIVE SECTIONS OF CODE CAN BE EXECUTED A ; PJC025 ; NUMBER OF TIMES WITHOUT LOOP COUNTERS. THIS METHOD ALSO ; PJC025 ; DECREASES PROGRAM SIZE BY ALLOWING US TO USE BRANCHES ; PJC025 ; RATHER THAN JSR'S. ; PJC025 ; ; PJC025 ; THE POINTER (LOCATION RADD) IS INCREMENTED VIA THE CODE ; PJC025 ; IN RTBK (RETURN BACK). RTBK THEN SHIFTS CONTROL TO THE ;**-14 ; ADDRESS POINTED TO BY RADD. RTBK IS CALLED BY RMSG/SMSG OR ; THE INTERRUPT SERVICE ROUTINE WHENEVER THE DL11 IS READY  ; PJC025 ; TO PERFORM THE NEXT NON-DATA TRANSFER OPERATION. ;**-1 ; ; PJC025 ; ; PJC025 ; CTAB- COMMAND PACKET SEQUENCE ; PJC025 ; ; PJC025 ; CONE IS THE ADDRESS RETURNED TO WHEN THE DL11 IS READY TO ; PJC025 ; SEND THE FIRST BYTE OF THE 14. BYTE COMMAND PACKET. CTWO ; PJC025 ; IS THE ADDRESS RETURNED TO WHEN READY FOR THE SECOND BYTE, ; PJC025 ; ETC. CFIF IS EXECUTED AFTER ALL BYTES IN THE COMMAND PACKET ; PJC025 ; ARE SENT. ; PJC025 ; ;**-8 CTAB: .WORD CONE,CTWO,CTHR,CFOUA,CFOUB,CFIV,CSIX,CSEV .WORD CEIG,CNIN,CTEN,CELE,CTWE,CTHI,CFOR,CFIF ; ; ITAB- INITIALIZATION SEQUENCE ; ITAB: .WORD IONE,ITWOA,ITWOB,ITWOC,ITWOD,ITWOE,ITHR,IFOU,IFIV,ISIX ;INIT. SEQ. ; ; TTAB- TRANSMIT DATA SEQUENCE ; TTAB: .WORD TONE,TTWO,TTHR,TFOU,TFIV,TSIX ;OUTGOING (WRITE) DATA P; PJC025 ; ;**-1 ; RTAB- RECEIVE DATA SEQUENCE ; RTAB: .WORD RONE,RTWO,RTHR,RFOU ;INCOMING (READ) DATA PACKET ADDRESSES ; ; ETAB- END PACKET DECODE SEQUENCE ; ETAB: .WORD EONE,ETWO,ETHR,EFOU,EFIV,ESIX,ESEV ;READ END PACKET .WORD EEIG,ENIN,ETEN,EELE,ETWE,ETHI ;FROM TU58 ; PJC025 ; ;**-1 ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; RDAT: .BLKW T$$U58 ;RECEIVED DATA RADD: .BLKW T$$U58 ;RETURN ADDRESS POINTER DBUF: .BLKW T$$U58 ;DL11 BUFFER ADDRESS ; PJC025 CKSM1: .BLKW T$$U58 ;CHECKSUM STORAGE-1ST WORD ;**-1 ;ALSO TEMPORARY DRIVER STORAGE ; PJC025 CKSM2: .BLKW T$$U58 ;CHECKSUM STORAGE-2ND WORD ;**-1 ;ALSO TEMPORARY DRIVER STORAGE ; PJC025 FLAG: .BLKW T$$U58 ;LOW BYTE-BYTE COUNT ;**-1 ;HIGH BYTE-SEND/REC. FLAG WCNT: .BLKW T$$U58 ;BYTES LEFT TO BE WRITTEN ;ALSO USED FOR RETURN ADDRESS ;DURING IOPKT SUBROUTINE ;ALSO USED FOR INITIALIZATION RETRY COUN; PJC025 ;**-1 ;+ ; **-DDINI- TU58 TAPE CARTRIDGE INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN ; PJC025 ; I/O REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION ; PJC025 ; TO PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED ; PJC025 ; CONNTROLLER IS NOT BUSY, THEN AN ATTEPMT IS MADE TO DEQUEUE THE ; PJC025 ; NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS EXECUTED. IF ; PJC025 ; THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPERATION ; PJC025 ; IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; PJC025 ; ; PJC025 ; INPUT: ; PJC025 ; ; PJC025 ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; PJC025 ; ; PJC025 ; OUTPUT:  ; PJC025 ; ; PJC025 ; IF THE SPECIFIED CONTROLLER IS NOT BUST AND AN I/O REQUEST ; PJC025 ; IS WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED ; PJC025 ; AND THE DRIVER INITIATES THE REQUESTED I/O FUNCTION ; PJC025 ;- ;**-19 .ENABL LSB ; PJC025 DDINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS ;**-1 BCC 10$ RETURN ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ;**-1 ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; TU58 TAPE CARTRIDGE DRIVE I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF 1ST LUN WORD IN REQUESTOR TASK HEADER. ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.WLB, IO.DGN, IO.BLS) ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO TRANSFER ; WD. 15 -- NOT USED ; WD. 16 -- LOW BYTE MUST BE ZERO, HIGH BYTE NOT USED ; WD. 17 -- LOGICAL OR PHYSICAL BLOCK NUMBER ; WD. 20 -- NOT USED ; ; DRIVER USAGE OF UCB: ; PJC025 ; ; PJC025 ; U.CW2+1 --- STORES DRIVER'S RETRY COUNT ;**-1 ; ; THE TU58 UTILIZES RADIAL SERIAL PROTOCOL. ALL I/O ;**-1 ; COMMANDS ARE INITIATED BY SENDING A COMMAND MESSAGE ; PACKET CONSISTING OF 14. BYTES OF INFORMATION. DATA ; IS THEN TRANSFERRED TO THE UNIT (WRITE) OR TO THE ; USER'S BUFFER (READ) IN MESSAGE PACKETS OF UP TO 128 ; BYTES EACH. TERMINATION OF AN OPERATION BY THE TU58 ; IS SIGNALED BY THE UNIT'S SENDING AN END MESSAGE ; PACKET WHICH CONTAINS INFORMATION CONCERNING THE ; SUCCESS OF THE TRANSFER. ; ;**-1 10$: MOV R5,CNTBL(R3) ;STORE UCB ADDRESS MOVB #RTRY,U.CW2+1(R5) ;STORE RETRY COUNT MOV S.CSR(R4),DBUF(R3) ;STORE CONTROLLER NUMBER ; PJC024 MOV R3,R4 ;R4 IS USED FOR CONTROLLER INDEXING ; PJC024 CALL $BLKCK ;CHECK PARAMETERS ;**-3 ADD #DDXBF,DBUF(R4) ;SAVE DL11 XMITTER BUFFER ; PJC025 ; ;**-1 ; ENTRY POINT FOR FUNCTION RETRY ; PJC025 ; ;**-1 RINI: MOV #CTAB-2,RADD(R4) ;POINT TO WORD PRIOR TO COMMAND TABLE CLR FLAG(R4) ;SET FLAG FOR TRANSMIT INTERRUPTS BR 145$ ;PREPARE TO SEND BYTE ; ; SEND COMMAND PACKET ; CONE: MOVB #CNTL,@DBUF(R4) ;SEND COMMAND FLAG BYTE BR 145$ ;PREPARE TO SEND BYTE CTWO: MOV #10.,@DBUF(R4) ;SEND BYTE COUNT MOVB #10.,CKSM1+1(R4) ;CREATE CHECKSUM WORD FROM MOVB #CNTL,CKSM1(R4) ; FIRST TWO BYTES BR 145$ CTHR: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 ; ; POSITION AND DIAGNOSE FUNCTIONS ARE USER MODE DIAGNOSTIC FUNCTIONS ; ; PJC025 .IF DF D$$IAG  CMP #IO.DGN!IQ.UMD,I.FCN(R1) ;TU58 INTERNAL DIAGNOSTICS? ; PJC025 BNE 40$ ;IF NE NO ;**-1 MOV #DIAG,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #DIAG,@DBUF(R4) ;SEND DIAGNOSTIC OP CODE BR 140$ ;CONTINUE OPERATION 40$: CMP #IO.BLS!IQ.UMD,I.FCN(R1) ;POSITION FUNCTION? BNE 60$ ;IF NE NO MOV #POSIT,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #POSIT,@DBUF(R4) ;SEND OP CODE BR 140$ ;CONTINUE .ENDC ; PJC025 60$: CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL BLOCK? BNE 70$ ;IF NE NO MOV #READ,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #READ,@DBUF(R4) ;SEND READ OPCODE BR 110$ ;CONTINUE 70$: CMPB #IO.WLB/256.,I.FCN+1(R1) ;WRITE LOGICAL BLOCK? BEQ 100$ ;IF EQ YES MOV (SP)+,R1 ;RESTORE R1 CALL $FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED MOV #IE.IFC&377,R0 ;ILLEGAL FUNCTION CODE CLR CKSM2(R4) ;CLEAR BYTES TRANSFERRED JMP IOCMP ;EXIT 100$: MOV #WRITE,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #WRITE,@DBUF(R4) ;SEND WRITE OPCODE 110$: BITB #US.WCK,U.STS(R5) ;WRITE CHECK SET? BNE 141$ CMPB #20,I.FCN(R1) ;IS WLC OR RLC REQUESTED? BNE 140$ ;IF NE NO BR 141$ ; ; SEND A MODIFIER BYTE OF ONE FOR WRITECHECKS AND READCHECKS ; PJC025 ; ;**-1 CFOUA: MOVB #1,CKSM2+1(R4) ;ALTER CHECKSUM MOVB #1,@DBUF(R4) ;SEND MODIFIER ADD #2,RADD(R4) ;SKIP OVER NEXT RETURN ADDRESS BR 160$ ;CONTINUE 140$: ADD #2,RADD(R4) ;SKIP OVER NEXT RETURN ADDRESS 141$: MOV (SP)+,R1 ;RESTORE R1 ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039  ; PJC039 MOV CKSM2(R4),WORD1(R4) ;STORE OP CODE AND COMMAND MODIFIER ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 145$: JMP SMSG ; ; SEND A ZERO MODIFIER BYTE FOR READS AND WRITES ; PJC025 ; ;**-1 CFOUB: CLRB @DBUF(R4) ;SEND MODIFIER 160$: CALL CHKPT ;CHECKSUM CALCULATION BR 145$ CFIV: MOVB U.UNIT(R5),@DBUF(R4) ;SEND UNIT # ; PJC013 MOVB U.UNIT(R5),CKSM2(R4) ;**-1 BR 145$ CSIX: CLRB @DBUF(R4) ;SEND 0 CLRB CKSM2+1(R4) BR 160$ CSEV: CEIG: CLRB @DBUF(R4) ;SEND TWO ZERO BYTES BR 145$ CNIN: CALL IOPKT ;STORE I/O PACKET ADDRESS IN R1 ; PJC031 ADD #I.PRM,R1 ;POINT TO PARAMETER LIST ; PJC031 MOV (R1)+,U.BUF(R5) ;INSERT RELOCATION BIAS ; PJC031 MOV (R1)+,U.BUF+2(R5) ;INSERT BUFFER ADDRESS ; PJC031 MOV (R1),CKSM2(R4) ;CREATE CHECKSUM ; PJC031 MOVB (R1),@DBUF(R4) ;SEND LOW BYTE COUNT ; PJC031 BR 141$ ;**-3 ; ; NOTE: ; PJC025 ; ; PJC025 ; THE TU58 REQUIRES THAT THE NUMBER OF BYTES TO BE TRANSFERRED ; PJC025 ; BE EVEN AND THAT THE STARTING ADDRESS OF THE DATA TRANSFER BE ; PJC025 ; ON A WORD BOUNDARY. ; PJC025 ; ;**-3 CTWE: ;SEND HIGH BLOCK NO. CTEN: MOVB CKSM2+1(R4),@DBUF(R4) ;SEND HIGH BYTE COUNT BR 160$ CELE: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 MOVB I.PRM+12(R1),@DBUF(R4) ;SEND LOW BLOCK NO. MOV I.PRM+12(R1),CKSM2(R4) BR 141$ CTHI: MOVB CKSM1(R4),@DBUF(R4) ;SEND LOW CHECKSUM BR 145$ CFOR: MOVB CKSM1+1(R4),@DBUF(R4) ;SEND HIGH CHECKSUM .DSABL LSB ; ; PJC025 ; AFTER THE COMMAND PACKET IS SENT THE TU58 RESPONDS. ;**-1 ; ITS RESPONSE DEPENDS ON THE OPERATION REQUESTED. ; A CONTINUE IS SENT IN RESPONSE TO A WRITE, THE FIRST ; DATA PACKET IS SENT IN RESPONSE TO A READ, AND AN ; END PACKET IS SENT IN RESPONSE TO A DIAGNOSTIC OR ; POSITION COMMAND. ALSO AN END PACKET MAY BE RECEIVED ; ON A FAILURE TO READ THE FIRST RECORD PROPERLY. ; ; PJC025 ; DETERMINE THE APPROPRIATE INITIAL RESPONSE FROM THE TU58 ; PJC025 ; AND RECEIVE THE FIRST BYTE FROM THE UNIT. ; PJC025 ; ;**-5 .ENABL LSB ; PJC025 INCB FLAG+1(R4) ;SET FLAG FOR RECEIVE SUB #DDXBF-DDRBF,DBUF(R4) ;SET RECEIVE BUFFER BR 25$ ;READ RESPONSE BYTE FROM TU58 ; PJC025 CFIF: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 ;**-1 ; PJC025 .IF DF D$$IAG CMPB #IO.DGN/256.,I.FCN+1(R1) ;DIAGNOSTIC? BEQ 10$ ;IF EQ YES .ENDC ; PJC025 JMP DPACK ;ELSE RECEIVE DATA PACKET OR CONTINUE 10$: MOV (SP)+,R1 ;RESTORE R1 ; ; PJC025 ; RECEIVE AND MANUPILATE THE TU58'S END PACKET INFORMATION ; PJC025 ; ; PJC025 ENDP: MOV #ETAB-2,RADD(R4) ;POINT TO END PACKET SEQUENCE ;**-4 CMPB RDAT(R4),#CNTL ;COMMAND/END PACKET? BR 24$ ; ; AT EONE WE SHOULD HAVE RECEIVED THE BYTE COUNT OF AN END PACKET ; WHICH IS ALWAYS EQUAL TO 10. ; EONE: CMPB RDAT(R4),#10. ;BYTE COUNT=10.? 24$: BEQ 25$ ;IF EQ YES ; PJC039 JMP NTRY ; ; PJC039 25$: JMP RMSG ;READ A BYTE ;**-1 ETWO: CMPB RDAT(R4),#100 ;OP CODE=END PACKET? BR 24$ ETHR: MOVB RDAT(R4),CKSM1(R4) ;STORE SUCCESS CODE ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039 ; PJC039 MOVB RDAT(R4),WORD2(R4) ; ; PJC039 BR 25$ ; ; PJC039 EFOU: MOVB RDAT(R4),WORD2+1(R4) ;STORE UNIT SELECT ; PJC039 ; PJC039 .IFF ; PJC039 ; PJC039 EFOU: ;DUMP BYTES ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 EFIV: ;DUMP BYTES ; PJC039 ESIX: ;**-2 ESEV: BR 25$ EEIG: MOVB RDAT(R4),CKSM2(R4) ;STORE BYTE TRANSFERRED COUNT -LOW ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039 ; PJC039 MOVB RDAT(R4),WORD3(R4) ; ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 BR 25$ ENIN: MOVB RDAT(R4),CKSM2+1(R4) ;STORE BYTE TRANSFERRED COUNT -HIGH ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039 ; PJC039 MOVB RDAT(R4),WORD3+1(R4) ; ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 ETEN: EELE: ETWE: BR 25$ ;DUMP BYTES ETHI: CALL $FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED MOV #IS.SUC&377,R0 ;ASSUME SUCCESS TSTB CKSM1(R4) ;SUCCESSFUL? BGT ERRPT ;IF GT YES, BUT HAD RETRIES BEQ ENDOP ;IF EQ, COMPLETE SUCCESS ; PJC039 MOV #IE.DNR&377,R0 ;ASSUME DEVICE NOT READY ;**-1 CMPB CKSM1(R4),#-9. ;CARTRIDGE NOT IN PLACE? BEQ ERRPT ;IF EQ YES ; PJC039 MOV #IE.WLK&377,R0 ;ASSUME WRITE-LOCKED ;**-1 CMPB CKSM1(R4),#-11. ;WRITE-LOCKED? BEQ ERRPT ;IF EQ YES ; PJC039 MOV #IE.FHE,R0 ;ASSUME FATAL HARDWARE ERROR ;**-1 CMPB CKSM1(R4),#-33. ;MOTOR STOPPED? BEQ ERRPT ;IF EQ YES MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ERRPT: ; PJC039 ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039 ; PJC039 CALL LOGERR ;LOG DEVICE ERROR ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 BR ENDOP ; ; PJC039 ; PJC025 ; PJC025 .IF DF E$$DVC ;**-1 ;+ ; PJC039 ; **-LOGERR-LOG DEVICE ERROR ; PJC039 ; **-LOGTMO-LOG DEVICE TIMEOUT ; PJC039 ; ; PJC039 ; THESE ROUTINES WILL ALLOCATE A CORE BLOCK, FILL IT WITH THE ; PJC039 ; APPROPRIATE INFORMATION, CALL THE APPROPRIATE EXECUTIVE ERROR ; PJC039 ; LOGGING ROUTINE, DEALLOCATE THE CORE BLOCK, AND RETURN BACK ; PJC039 ; TO THE CALLER. ; PJC039 ; ;**-7 ; IF FOR ANY REASON THE CORE BLOCK CANNOT BE ALLOCATED THEN ; THE EXECUTIVE ERROR LOGGING ROUTINE WILL NOT BE CALLED ; AND THE ERROR SEQUENCE NUMBER WILL BE UPDATED TO INDICATE ; THAT A MISSED ERROR CONDITION OCCURRED. ;- ; PJC025 LOGERR: MOV R0,-(SP) ;SAVE STATUS CODE ; PJC039 MOV #$DVERR,-(SP) ;LOG DEVICE ERROR ; PJC039 BR 70$ ; ; PJC039 LOGTMO: MOV R0,-(SP) ;SAVE STATUS CODE ; PJC039 MOV #$DTOER,-(SP) ;LOG TIMEOUT ERROR ; PJC039 70$: MOV #DDNUM*2,R1 ;NUMBER OF BYTES TO ALLOCATE ; PJC039 CALL $ALOCB ;ALLOCATE A CORE BLOCK ;**-3 BCC 80$ ;IF CC BLOCK WAS ALLOCATED INC $ERRSQ ;INDICATE A MISSED ERROR CONDITION BR 90$ ;END I/O ROUTINE 80$: MOV R0,R1 ;COPY CORE BUFFER POINTER MOV DBUF(R4),R3 ;STORE BUFFER ADDRESS TST -(R3) ;POINT TO DL11 CSR ; PJC025 MOV (R3)+,(R1)+ ;MOVE DL11 RECEIVE CSR INTO CORE BUFFER ; PJC025 MOV (R3)+,(R1)+ ;...DL11 RECEIVE BUFFER ; PJC025 MOV (R3),(R1)+ ;...DL11 TRANSMITTER CSR ; PJC039 MOV WORD1(R4),(R1)+ ;OPCODE AND COMMAND MODIFIER ; PJC025 MOV WORD2(R4),(R1)+ ;SUCCESS CODE AND UNIT SELECT ; PJC025 MOV WORD3(R4),(R1) ;BYTE COUNT LOW AND BYTE COUNT HIGH ; PJC039 MOV R4,R3 ;SAVE CONTROLLER INDEX ; PJC039 MOV U.SCB(R5),R4 ;GET SCB ADDRESS ; PJC039 MOV R0,S.CSR(R4) ;COPY CORE BUFFER POINTER ; PJC039 CALL @(SP)+ ;CALL ERROR LOGGING ROUTINE ; PJC039 MOV DBUF(R3),R2 ;GET DL11 BUFFER ADDRESS ; PJC039 TST -(R2) ;POINT TO DL11 CSR REGISTER ADDRESS ; PJC039 MOV R2,S.CSR(R4) ;RESTORE CSR ADDRESS ; PJC039 MOV R3,R4 ;RESTORE CONTROLLER INDEX ; PJC039  MOV #DDNUM*2,R1 ;GET NUMER OF BYTES TO DEALLOCATE ; PJC039 CALL $DEACB ;DEALLOCATE CORE BLOCK ;**-11 90$: MOV (SP)+,R0 ;RESTORE I/O STATUS CODE RETURN ; ; PJC039 .ENDC ; PJC025 ENDOP: ; PJC025 .IF DF D$$IAG CALL IOPKT CMPB #IO.DGN/256.,I.FCN+1(R1) ;DIAGNOSTIC? BNE 100$ ;IF NE NO ; PJC025 .IF DF M$$MGE MOV I.PRM+14(R1),KISAR6 ;SET BUFFER RELOCATION BIAS .ENDC ; PJC025 MOV I.PRM+16(R1),R0 ;GET REGISTER BUFFER ADDRESS MOV DBUF(R4),R3 ;GET DL11 RECEIVE BUFFER ADDRESS ; PJC025 TST -(R3) ;POINT TO REC. CSR ADDRESS ;**-1 MOV (R3)+,(R0)+ ;MOV REC. CSR CONTENTS TO USER BUFF. MOV (R3)+,(R0)+ ;MOV REC. BUFF CONTENTS MOV (R3)+,(R0)+ ;MOV TRANS. CSR CONTENTS MOV (R3)+,(R0)+ ;MOV TRANS. BUFF CONTENTS MOV CKSM1(R4),R1 ;MOV TU58 END PACKET INFO ; PJC025 MOV #IS.SUC&377,R0 ;STORE I/O COMPLETION STATUS ;**-1 100$: TST (SP)+ ;RESTORE STACK .ENDC ; PJC025 ; ; COMMON EXIT CODE- ALL OPERATIONS COMPLETE HERE ; ;**-4 IOCMP: MOV CKSM2(R4),R1 ;PICKUP BYTES TRANSFERRED COUNT ; PJC025 .IF DF E$$DVC MOVB U.CW2+1(R5),R2 ;STORE FINAL RETRY COUNT BIS #RTRY*^D<256>,R2 ;MERGE INITIAL RETRY COUNT .ENDC ; PJC025 CALL $IODON JMP DDINI ;NEXT I/O PACKET .DSABL LSB ; PJC025 ; ; PJC025 ; WE ENTER HERE WHEN AN UNEXPECTED AND UNDESIRED BYTE IS RECEIVED. ; PJC025 ; THE TU58 IS REINITIALIZED AND IF THE RETRY COUNT IS => 0, THE ; PJC025 ; I/O FUNCTION IS STARTED OVER. OTHERWISE, AN ERROR IS LOGGED AND ; PJC025 ; THE OPERATION IS ABORTED. ; PJC025 ; ; PJC025 .ENABL LSB ; PJC025 NTRY: DECB U.CW2+1(R5) ;DECREMENT RETRY COUNT ;**-10 ADD #DDXBF-DDRBF,DBUF(R4) ;POINT TO TRANS. BUFFER ; ; TINIT TRIES TO REINITIALIZE THE TU58. IT WILL ATTEMPT THE ; PJC025 ; INITIALIZATION ROUTINE OF SENDING BREAK, CLEARING BREAK, ; PJC025 ; SENDING TWO INIT'S, AND RECEIVING A CONTINUE. ; PJC025 ; ;**-4 TINIT: CLR FLAG(R4) ;SET FOR TRANSMIT WITH NO USER DATA TRANSFER MOV #ITAB-2,RADD(R4) ;POINT TO INITIALIZE TABLE BR 50$ ;WAIT ; ; NULL TIMING CHARACTERS ARE SENT AT IONE AND ITWO TO ALLOW ; ENOUGH TIME FOR THE BREAK BIT TO CAUSE A FRAMING ERROR. THIS ; SIGNALS THE TU58 TO STOP TRANSMITTING AND LISTEN. ; PJC025 ; ;**-1 IONE: MOV DBUF(R4),CKSM1(R4) ;TEMP. STORE BUFFER SUB #DDXBF-DDXCS,CKSM1(R4) ;POINT TO XCSR BIS #BRK,@CKSM1(R4) ;SEND BREAK TO TU58 ; PJC025 ITWOA: ;SEND TIMING NULLS ;**-1 ITWOB: ITWOC: ITWOD: ITWOE: CLRB @DBUF(R4) ; 50$: JMP SMSG ;WAIT ; ; ITHR AND IFOU WILL CLEAR THE BREAK CONDITION AND ISSUE ; TWO INITIALIZE COMMANDS TO THE TU58. (THE FIRST IS IGNORED ; PJC025 ; BY THE CONTROLLER). ;**-1 ; ITHR: BIC #BRK,@CKSM1(R4) ;CLEAR BREAK SUB #DDXCS-DDRBF,CKSM1(R4) ;TEMP. STORE REC. BUFFER TSTB @CKSM1(R4) ;DUMP REC. BUFFER IFOU: MOVB #INIT,@DBUF(R4) ;SEND ANOTHER INIT. BR 50$ ;WAIT ; ; A CHARACTER IS RECEIVED AT ISIX. IF IT IS A CONTINUE, WE ; PJC025 ; HAVE SUCCESSFULLY INITIALIZED THE DEVICE. ; PJC025 ; ;**-3 IFIV: SUB #DDXBF-DDRBF,DBUF(R4) ;POINT TO REC. BUFF. INCB FLAG+1(R4) ;SET FLAG FOR RECEIVE JMP RMSG ;WAIT ISIX: ADD #DDXBF-DDRBF,DBUF(R4) ;POINT TO XBUF TSTB U.CW2+1(R5) ;RETRY? ;**-1 BGT 60$ ;IF GT YES ; PJC031 CALL $FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED ;**-1 MOV #IE.FHE&377,R0 ;FATAL ERROR CLR CKSM2(R4) ;CLEAR BYTE TRANSFER COUNT ; PJC025 .IF DF E$$DVC MOV #200,CKSM1(R4) ;SET ERROR CODE .ENDC  ; PJC025 JMP ERRPT ;ERROR LOG AND EXIT ; PJC039 60$: JMP RINI ;RETRY ;**-1 ; ; PJC025 ; HERE DATA PACKETS SENT BY THE TU58 ARE READ. THE NUMBER OF ; PJC025 ; DATA BYTES IN THE PACKET IS RECEIVED AT RONE. IT IS STORED ; PJC025 ; IN LOCATION FLAG AND THE CHECKSUM IS INITIALIZED. THE DATA ; PJC025 ; IS TRANSFERRED WITHIN THE INTERRUPT SERVICE ROUTINE WHERE ; PJC025 ; THE CHECKSUM IS ALSO VERIFIED. THE FIRST BYTE OF THE NEXT ; PJC025 ; PACKET IS RECEIVED AT RFOU AND IF IT IS A DATA FLAG, THIS ; PJC025 ; CODE IS ENTERED AGAIN. ; PJC025 ; ; PJC025 DPACK: CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ? ;**-11 BNE 102$ ;IF NE NO -IT'S A WRITE MOV (SP)+,R1 ;RESTORE R1 RFOU: CMPB RDAT(R4),#DATA ;DATA PACKET? BEQ 96$ ;IF EQ YES 94$: JMP ENDP 96$: MOVB #DATA,CKSM1(R4) ;START CHECKSUM MOV #RTAB-2,RADD(R4) ;POINT TO READ TABLE BR 100$ ;READ A BYTE RONE: MOVB RDAT(R4),FLAG(R4) ;STORE BYTE COUNT MOVB RDAT(R4),CKSM1+1(R4) ;STORE HIGH BYTE OF FIRST CHECKSUM 100$: JMP RMSG ; ; PJC025 ; AT THIS POINT WE SEND A DATA PACKET TO THE TU58. ; PJC025 ; THE DATA FLAG BYTE IS SENT AT TONE. THE NUMBER OF DATA ;**-3 ; BYTES IN THIS PACKET IS SENT AT TTWO. DATA IS THEN ; TRANSFERRED ALONG WITH THE CHECKSUM WITHIN THE INTERRUPT ; SERVICE ROUTINE. RETURN TO THIS SEGMENT IS MADE AT TFIV ; AND THE FIRST BYTE OF THE NEXT PACKET IS RECEIVED AT ; TSIX, IF IT IS A CONTINUE ANOTHER PACKET IS SENT. ; WHEN THE TU58 HAS RECEIVED ALL THE DATA, IT SENDS AN ; PJC025 ; END PACKET FLAG INSTEAD OF A CONTINUE (THIS ALSO OCCURS ;**-1 ; IF THE TU58 ENCOUNTERS AN ERROR WRITING THE DATA). ; PJC025 ; ; PJC025 102$: MOV I.PRM+4(R1),WCNT(R4) ;DUPLICATE BYTE COUNT ;**-3 MOV (SP)+,R1 ;RESTORE R1 TSIX: CMPB RDAT(R4),#CONT ;CONTINUE FLAG? BNE 94$ ;IF NE NO MOV #TTAB-2,RADD(R4) ;POINT TO TRANSMIT (WRITE) TABLE ; PJC025 CLRB FLAG+1(R4) ;SET TRANSMIT FLAG ;**-1 ADD #DDXBF-DDRBF,DBUF(R4) ;SET TRANSMIT BUFFER BR 130$ ;PREPARE TO SEND FIRST BYTE TONE: MOVB #DATA,@DBUF(R4) ;SEND FLAG BYTE MOVB #DATA,CKSM1(R4) ;START CHECKSUM CMP #128.,WCNT(R4) ;MORE THAN 1 PACKET LEFT? BLO 120$ ;IF L0 YES 125$: MOVB WCNT(R4),CKSM1+1(R4) ;CREATE HIGH BYTE OF CHECKSUM CLRB WCNT(R4) ;ZERO REMAINING BYTE COUNT BR 130$ 120$: MOVB #128.,CKSM1+1(R4) ;CREATE HIGH BYTE OF CHECKSUM SUB #128.,WCNT(R4) ;ADJUST REMAINING COUNT 130$: JMP SMSG TTWO: MOVB CKSM1+1(R4),@DBUF(R4) ;SEND BYTE COUNT MOVB CKSM1+1(R4),FLAG(R4) ;SET UP FLAG BYTE COUNT BR 130$ TFIV: INCB FLAG+1(R4) ;SET RECEIVE BYTE SUB #DDXBF-DDRBF,DBUF(R4) ;SET RECEIVE BUFFER BR 100$ ;READ A BYTE .DSABL LSB ; PJC025 ; ; PJC025 ; IOPKT PUTS I/O PACKET ADDRESS IN R1 ;**-7 ; ; PJC025 ; OUTPUT: ; PJC025 ; ; PJC025 ; R1 = I/O PACKET ADDRESS ; PJC025 ; (SP) = FORMER CONTENTS OF R1 TO BE RESTORED BY THE CALLER ; PJC025 ; ; PJC025 IOPKT: MOV (SP)+,WCNT(R4) ;SAVE RETURN ADDRESS ;**-5 MOV R1,-(SP) ;PRESERVE R1 MOV R4,-(SP) ;PRESERVE R4 MOV U.SCB(R5),R4 ;GET SCB ADDRESS MOV S.PKT(R4),R1 ;GET I/O PKT ADDRESS MOV (SP)+,R4 ;RESTORE R4 JMP @WCNT(R4) ;NOTE R1 WILL BE RESTORED BY PROGRAM ; ; PJC025 ; RTBK (RETURN BACK) INCREMENTS THE RETURN ADDRESS POINTER AND ; PJC025 ; THEN JUMPS THERE. ; PJC025 ; ; PJC025 RTBK: ADD #2,RADD(R4) ;POINT TO NEXT LOCATION ;**-6 MOV @RADD(R4),-(SP) ;MOVE RETURN ADDRESS LOCATION ONTO STACK JMP @(SP)+ ;RETURN TO ADDRESS IN TABLE ; ; PJC025 ; THIS ROUTINE IS JUMPED TO IN ORDER TO SEND INFORMATION. ; PJC025 ; THE MAIN PROGRAM CONTINUES VIA THE INTERRUPT SERVICE ROUTINE ; PJC025 ; CODE (SPT), UNLESS WRITE DATA IS TO BE TRANSFERRED (DATA COUNT ; PJC025 ; FLAG = NON-ZERO). ; PJC025 ; ; PJC025 .ENABL LSB ;**-12 SMSG: SUB #DDXBF-DDXCS,DBUF(R4) ;POINT TO CSR BIT #TRDY,@DBUF(R4) ;IS TRANSMITTER READY BEQ 20$ SREC: ADD #DDXBF-DDXCS,DBUF(R4) ;POINT TO BUFFER TSTB FLAG(R4) ;BYTE COUNT 0 BEQ RTBK ;IF EQ YES JMP SPT ;GO TO SEND DATA ROUTINE 20$: BIS #TIE,@DBUF(R4) ;SET XMITTER INTERRUPT ENABLE ; PJC024 MOV U.SCB(R5),R4 ;STORE SCB ADDRESS ;**-9 MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT RETURN .DSABL LSB ; ; PJC025 ; THIS ROUTINE IS JUMPED TO IN ORDER TO RECEIVE INFORMATION VIA ; PJC025 ; THE DL11. IF RECEIVER DONE IS SET, THEN A RETURN TO THE MAIN ; PJC025 ; PROGRAM IS INITIATED VIA THE INTERRUPT SERVICE ROUTINE (RPT). ; PJC025 ; IF THE DL11 DONE BIT IS CLEAR, A RETURN IS EXECUTED AND THE ; PJC025 ; INTERRUPT SERVICE ROUTINE WILL RETURN CONTROL TO THE PROGRAM ; PJC025 ; WHEN THE DONE BIT IS SET AND WHEN ALL READ DATA HAS BEEN ; PJC025 ; TRANSFERRED TO THE USER'S BUFFER. ; PJC025 ; ; PJC025 .ENABL LSB ;**-14 RMSG: SUB #DDRBF-DDRCS,DBUF(R4) ;POINT TO CSR BIT #RDONE,@DBUF(R4) ; READY? BEQ 20$ ;IF EQ NO RREC: JMP RPT ;IF YES ENTER READ ROUTINE 20$: BIS #RIE,@DBUF(R4) ;SET RE. INTERRUPT ENABLE ; PJC024 MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ;**-9 MOVB #40.,S.CTM(R4) ;SET TIMEOUT RETURN .DSABL LSB ; ; PJC025 ; CHPKT CREATES A CHECKSUM ; PJC025 ; ; PJC025 ; INPUT: ; PJC025 ; ; PJC025 ; CKSM2(R4) = WORD TO BE ADDED ; PJC025 ; CKSM1(R4) = OLD CHECKSUM ; PJC025 ; ; PJC025 ; OUTPUT: ; PJC025 ; ; PJC025 ; CKSM1(R4) = NEW CHECKSUM ; PJC025 ; ; PJC025 CHKPT: ADD CKSM2(R4),CKSM1(R4) ;ADD TWO WORDS ;**-7 ADC CKSM1(R4) ;ADD CARRY ;FALL THROUGH AND RETURN ; ; PJC025 ; END LOCAL ROUTINES ;**-1 ;  ; PJC025 ;+ ;**-1 ; DDCAN-CANCEL I/O ENTRY POINT ; ; PJC025 ; CANCEL I/O IS A NOP FOR FILE STRUCTURED DEVICES. ; PJC025 ;- ;**-1 DDCAN: ;+ ;**-1 ; POWERFAIL REQUIRES NO OPERATION. REINITIALIZATION ; OF THE TU58 WILL OCCUR DURING NORMAL OPERATION IF REQUIRED. ; PJC025 ;- ;**-1 DDPWF: RETURN ;+ ; **-$DDINT TU58 INTERRUPT SERVICE ROUTINE ; PJC025 ;- ;**-8 .ENABL LSB $DDOUT:: ;;;OUTPUT AS WELL AS INPUT ($DDINT) ;;;INTERRUPT ENTRY POINT INTSE$ DD,PR4,T$$U58 ;;;SAVE REGISTERS & SET PRIORITY BIC #,@DBUF(R4) ;;;CLEAR INTERRUPTS ;**-3 MOV R1,-(SP) ;;;SAVE R1 MOV U.SCB(R5),R1 ;;;GET SCB ADDRESS CLRB S.CTM(R1) ;;;CLEAR TIMEOUT MOV (SP)+,R1 ;;;RESTORE R1 ; ; FLAG+1 IS SET FOR A TRANSMIT OPERATION AND CLEARED FOR A ; PJC025 ; A RECEIVE OPERATION. FLAG IS CHECKED TO DETERMINE IF WE ; PJC025 ; HAVE DATA TO TRANSFER. ; PJC025 ; ;**-4 TSTB FLAG+1(R4) ;;;RECEIVE INTERRUPT? BNE RPT ;;;IF NE YES  ADD #DDXBF-DDXCS,DBUF(R4) ;;;POINT TO BUFFER TSTB FLAG(R4) ;;;TRANSMIT DATA PACKET? BNE SPT ;;;IF NE YES 5$: JMP RTBK ;;;ELSE RETURN ; ; SPT IS THE CODE USED TO SEND USER DATA TO THE TU58. A RUNNING ; PJC025 ; CHECKSUM IS KEPT AND IS SENT AS THE LAST TWO CHARACTERS OF A ; PJC025 ; DATA PACKET (TTHR,TFOU). AFTER ALL DATA HAS BEEN SENT, CONTROL ; PJC025 ; IS PASSED TO THE MAIN PROGRAM. ; PJC025 ; ;**-5 SPT: CALL $GTBYT ;;;PUT USER'S DATA BYTE ON STACK BITB #1,FLAG(R4) ;;;CHECK FOR EVEN OR ODD BYTE NO. BNE 20$ ;;;IF NE ODD,THEREFORE HIGH ORDER ;;;BYTE IN CHECKSUM MOVB (SP)+,CKSM2(R4) ;;;SAVE LOW ORDER CHECKSUM BYTE MOVB CKSM2(R4),@DBUF(R4) ;;;TRANSMIT BYTE BR 30$ 20$: MOVB (SP)+,CKSM2+1(R4) ;;;SAVE HIGH ORDER CHECKSUM BYTE MOVB CKSM2+1(R4),@DBUF(R4) ;;;TRANSMIT BYTE CALL CHKPT ;;;GENERATE CHECKSUM 30$: DECB FLAG(R4) ;;;DECREMENT DATA COUNT 35$: JMP SMSG TTHR: MOVB CKSM1(R4),@DBUF(R4) ;;;SEND LOW ORDER CHECKSUM BYTE BR 35$ TFOU: MOVB CKSM1+1(R4),@DBUF(R4) ;;;SEND HIGH ORDER BYTE BR 35$ ; ; RPT CHECKS FOR AN ERROR CONDITION IN THE DL11'S RECEIVE ; PJC025 ; TIMEOUT IS ENTERED WHEN THE DL11 DOES NOT RESPOND WITHIN ; PJC025 ; BUFFER. IF DATA IS TO BE RECEIVED THIS ROUTINE ;**-1 ; TRANSFERS THE CHARACTER IN THE USER'S BUFFER AND KEEPS ; A RUNNING CHECKSUM. AFTER ALL DATA IS RECEIVED THE FINAL ; TWO BYTES OF THE PACKET ARE PRESENT AT RTWO AND RTHR AND ; IF THEY EQUAL THE CHECKSUM THEN CONTROL IS RETURNED TO ; THE MAIN PROGRAM. ; RPT: ADD #DDRBF-DDRCS,DBUF(R4) ;;;POINT TO RECEIVE BUFFER MOV @DBUF(R4),RDAT(R4) ;;;STORE RECEIVED INFO. BPL 80$ ;;;IF PL NO ERROR 40$: JMP NTRY ;;;ATTEMPT RETRY 80$: TSTB FLAG(R4) ;;;DATA TO RECEIVE BEQ 5$ ;;;IF EQ NO MOVB RDAT(R4),-(SP) ;;;PUT DATA ON STACK CALL $PTBYT ;;;PUT DATA INTO USER'S BUFFER BITB #1,FLAG(R4) ;;;ODD OR EVEN BYTE (FOR CHECKSUM) BNE 90$ ;;;IF NE ODD (HIGH ORDER CHECKSUM BYTE) MOVB RDAT(R4),CKSM2(R4) ;;;LOW ORDER CHECKSUM BYTE BR 100$ 90$: MOVB RDAT(R4),CKSM2+1(R4) ;;;HIGH ORDER CHECKSUM BYTE CALL CHKPT 100$: DECB FLAG(R4) ;;;DECREMENT DATA COUNT BR 160$ RTWO: MOVB RDAT(R4),CKSM2(R4) ;;;RECEIVE LOW ORDER CHECKSUM BR 160$ RTHR: MOVB RDAT(R4),CKSM2+1(R4) ;;;RECEIVE HIGH ORDER CMP CKSM1(R4),CKSM2(R4) ;;;ARE CHECKSUMS CORRECT? BNE 40$ ;;;IF NE NO 160$: JMP RMSG ;;;READ FIRST BYTE OF NEXT PACKET .DSABL LSB ;+ ;**-1 ; TIMEOUT IS ENTERED WHEN THE DL11 DOES NOT RESPOND WITHIN ; PJC025 ; A CERTAIN PRESET TIME TO THE SUBROUTINES SMSG AND RMSG ;**-1 ; SETTING INTERRUPT ENABLE AND ISSUING A RETURN. THIS ; INDICATES A HARDWARE FAILURE OF THE DL11 OR TU58. ; PJC025 ;- ;**-2 DDOUT: BIC #,@DBUF(R3) ;;;CLEAR INTERRUPTS ; PJC025 MOV R3,R4 ;COPY CONTROLLER INDEX ; PJC039 ; PJC039 ; PJC039 .IF DF E$$DVC ; PJC039 ; PJC039 ADD #DDRBF-DDRCS,DBUF(R4) ;;;POINT TO DL11 BUFFER ADDRESS ; PJC039 CALL LOGTMO ;;;LOG TIMEOUT ERROR ; PJC039 MOV R4,R3 ;COPY CONTROLLER INDEX ; PJC039 SUB #DDRBF-DDRCS,DBUF(R4) ;POINT TO DL11 CSR ADDRESS ; PJC039 ; PJC039 .ENDC ; PJC039 ; PJC039 ; PJC039 TSTB FLAG+1(R4) ;RECEIVE TIME OUT? ;**-4 BNE 2$ ;IF NE YES ADD #DDXBF-DDXCS,DBUF(R4) ;POINT TO TRANSMIT BUFFER BR 4$ ; 2$: ADD #DDXBF-DDRCS,DBUF(R4) ;POINT TO TRANSMIT BUFFER 4$: DECB U.CW2+1(R5) ;DECREMENT RETRY COUNT BLE 10$ ;IN LE, NO RETRIES LEFT ; PJC031 JMP TINIT ;RE-INIT AND RETRY ;**-1 10$: CLR CKSM2(R3) ;CLEAR BYTE TRANSFERRED COUNT MOV #IE.TMO&3>77,R0 ;TIMEOUT ERROR JMP ENDOP ; PJC025 .END >ôðskQ ›c, .TITLE DFDRV .IDENT /09/ ; ; COPYRIGHT (C) 1974, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 09 ; ; D. N. CUTLER 19-OCT-73 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; ; MODIFIED BY: ; ; P. J. BEZEREDI 30-NOV-76 ; ; PB009 -- CORRECT OUT OF RANGE BRANCHES WHEN A ; MULTI-CONTROLLER DRIVER IS GENERATED. ; ; P. J. BEZEREDI 07-FEB-77 ; ; PB013 -- ADDITION OF EXPANDED WRITE CHECK CAPABILITY. ; ; P. J. BEZEREDI 14-FEB-77 ; ; PB014 -- LOAD SECOND STATUS WORD WITH BYTES ACTUALLY ; TRANSFERED BEFORE CALLING $IODON. ; P. J. BEZEREDI 16-MAY-77 ; ; PB030 -- POWERFAIL RECOVERY SUPPORT. ; ; RF11 FIXED HEAD DISK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; EQUATED SYMBOLS ; RETRY=8. ;ERROR RETRY COUNT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLER NUMBER) ; CNTBL: .BLKW R$$F11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$F11 ;RETRY COUNT FOR CURRENT OPERATION .IF GT R$$F11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $DFTBL::.WORD DFINI ;DEVICE INITIATOR ENTRY POINT .WORD DFCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DFOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DFPWF ;POWERFAIL ENTRY POINT ;+ ; **-DFINI-RF11 FIXED HEAD DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB DFINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS DFCAN ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RF11 FIXED HEAD DISK I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. ADRS ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS .ENDC .IF DF D$$IAG CMP #IO.WCK!IQ.UMD,I.FCN(R1) ;DIAGNOSTIC WRITE CHECK? BNE 5$ ;IF NE NO BIS #107,U.BUF(R5) ;YES, SET WRITE CHECK FUNCTION BR 10$ ; .ENDC 5$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION BIS #105,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 7$ ;IF HIS FUNCTION IS LEGAL 6$: JMP 70$ ;FUNCTION IS ILLEGAL 7$: BEQ 10$ ;IF EQ FUNCTION IS READ SUB #2,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION 10$: MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT MOV #IE.BLK&377,R0 ;ASSUME ILLEGAL BLOCK NUMBER MOVB I.PRM+10(R1),R2 ;GET HIGH BYTE OF LOGICAL BLOCK NUMBER BNE 6$ ;IF NE ILLEGAL BLOCK NUMBER MOV I.PRM+12(R1),R3 ;GET LOW PART OF LOGICAL BLOCK NUMBER SWAB R3 ;MULTIPLY LOW BYTE BY 256. BISB R3,R2 ;SET HIGH BITS OF DISK ADDRESS CLRB R3 ;CLEAR EXCESS BITS FROM LOW PART BIT #177740,R2 ;HIGH PART OF ADDRESS TOO BIG? BNE 6$ ;IF NE YES MOV R2,I.PRM+10(R1) ;SAVE HIGH PART OF DISK ADDRESS MOV R3,I.PRM+12(R1) ;SAVE LOW PART OF DISK ADDRESS ; ; INITIATE I/O OPERATION ; 20$: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $MPUBM ;MAP UNIBUS TO TRANSFER .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET MOV #401,(R2) ;CLEAR RF11 CONTROLLER MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT TIMEOUT COUNT ADD #10,R2 ;POINT TO DISK ADDRESS EXT. REGISTER MOV I.PRM+10(R1),(R2) ;INSERT HIGH PART OF DISK ADDRESS MOV I.PRM+12(R1),-(R2) ;INSERT LOW PART OF DISK ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;CONVERT TO NEGATIVE WORD COUNT MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY BIT #200,-(R2) ;DISK READY TO ACCEPT COMMAND? BNE 21$ ;IF NE YES .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 23$ ;IF NE YES .IFTF .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BNE 45$ ;IF NE YES .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR  .ENDC JMP 60$ ;FINISH I/O 21$: ;REF LABEL .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC MOV U.BUF(R5),(R2) ;LOAD FUNCTION AND GO ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DFCAN: RETURN ;;;NOP FOR RF11 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DFPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS THE DRIVE CURRENTLY BUSY? BEQ 23$ ;IF EQ NO MOVB #2,S.STS(R4) ;WAIT A MAXIMUM OF 30 SECONDS 22$: MOVB #15.,S.CTM(R4) ;15 SECONDS AT A TIME 23$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DFINT-RF11 DISK CONTROLLER INTERRUPTS ;- INTSE$ DF,PR5,R$$F11 ;;;SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;;CREATES A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF STATUS CONTROL BLOCK MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION EXECUTED? BNE 45$ ;IF NE YES .ENDC TST (R2) ;ANY ERRORS? BPL 50$ ;IF PL NO .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC MOV (R2),R1 ;GET CONTENTS OF CSR MOV #IE.WLK&377,R0 ;ASSUME WRITE LOCK BIT #2000,R1 ;WRITE LOCK? BNE 60$ ;IF NE YES MOV #IE.BLK&377,R0 ;ASSUME NONEXISTENT DISK BIT #4000,R1 ;NONEXISTENT DISK? BNE 60$ ;IF NE YES MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR BIT #40000,R1 ;UNRECOVERBLE ERROR? BNE 60$ ;IF NE YES BR 46$ ;FINISH IN COMMON CODE ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE REQUEST WAS DIAGNOSTIC. TIMEOUTS ARE USUALLY CAUSED ; BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A HARDWARE FAILURE. ; DFOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 40$ ;;;IF EQ NO DECB S.STS(R4) ;;;HAVE WE WAITED ENOUGH YET? BEQ 40$ ;;;IF EQ YES MTPS #0 ;;;ALLOW INTERRUPTS JMP 20$ ;RETRY ENTIRE OPERATION 40$: INCB S.STS(R4) ;;;LEAVE CONTROLLER BUSY BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 46$ ;IF CC TIMEOUT DURING NORMAL FUNCTION 45$: CALL $CRPAS ;PASS CONTROLLER REGISTERS TO TASK BR 60$ ;DIAGNOSTIC PROCESSING COMPLETE .ENDC 46$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE 52$ ;IF NE YES DECB RTTBL(R3) ;RETRY FUNCTION? BLE 52$ ;IF LE NO 47$: JMP 20$ ;RETRY OPERATION 50$: ;REF LABEL .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK? BNE 51$ ;IF NE YES BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR? BEQ 60$ ;IF EQ NO 51$: MOVB U.BUF(R5),R1 ;GET LAST FUNCTION BIT #1*2,R1 ;WRITE OR WRITE CHECK FUNCTION? BEQ 60$ ;IF EQ NO BIS #2*2,U.BUF(R5) ;SET WRITE CHECK FUNCTION BIT #2*2,R1 ;WAS LAST FUNCTION A WRITE CHECK? BNE 60$ ;IF NE YES MOV #RETRY,RTTBL(R3);REINITIALIZE RETRY COUNT BR 47$ ;START WRITE CHECK OPERATION .IFTF  52$: ;REF LABEL .IFT BIT #20000,(R2) ;WRITE CHECK ERROR? BEQ 60$ ;IF EQ NO MOV #IE.WCK&377,R0 ;SET WRITE CHECK ERROR .ENDC 60$: MOV 2(R2),R1 ;GET WORDS REMAINING TO TRANSFER ASL R1 ;CONVERT TO BYTES LEFT TO TRANSFER ADD U.CNT(R5),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED MOV #401,(R2) ;CLEAR RF11 CONTROLLER 70$: ;REF LABEL .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STŠARTING ERROR RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION JMP DFINI ;PROCESS NEXT REQUEST .DSABL LSB .END мðskQ ›c, .TITLE DKDRV .IDENT /08.01/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 08.01 ; ; D. N. CUTLER 19-OCT-73 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; ; MODIFIED BY: ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; RK11 CARTRIDGE DISK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RETRY=8. ;ERROR RETRY COUNT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW R$$K11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$K11 ;ERROR RETRY COUNT AND DRIVE RESET FLAG .IF GT R$$K11-1 TEMP: .BLKW 1 ;TEMPORY STORAGE FOR CONTROLLER NUMBER .ENDC .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS ; ; DIAGNOSTIC FUNCTION TABLE ; FUNTBL: .WORD IO.HMS!IQ.UMD, 0515 .WORD IO.BLS!IQ.UMD, 0511 FUNTB0: .WORD IO.RDH!IQ.UMD, 2505 .WORD IO.WDH!IQ.UMD, 2503 .WORD IO.WCK!IQ.UMD, 0507 FUNTBE: .ENDC ; ; DRIVER DISPATCH TABLE ; $DKTBL::.WORD DKINI ;DEVICE INITIATOR ENTRY POINT .WORD DKCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DKOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DKPWF ;POWERFAIL ENTRY POINT ;+ ; **-DKINI-RK11 CARTRIDGE DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB 1$: RETURN ;CONTROLLER BUSY OR NO REQUEST DKINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 1$ ;IF CS NO PACKET ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RK11 CARTRIDGE DISK I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. ADRS ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS .ENDC MOV #RETRY&377,RTTBL(R3) ;CLEAR POSITIONING & SET RETRIES .IF DF D$$IAG CMPB #IO.HMS/^D<256>,I.FCN+1(R1) ;DIAGNOSTIC FUNCTION? BNE 5$ ;IF NE NO MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE 2$: CMP (R0)+,I.FCN(R1) ;FUNCTION CODE MATCH? BEQ 3$ ;IF EQ YES TST (R0)+ ;BYPASS CONTROLLER CODE CMP #FUNTBE,R0 ;END OF FUNCTION TABLE? BEQ 5$ ;IF EQ YES BR 2$ ;TRY AGAIN 3$: CMP R0,#FUNTB0 ;POSITIONING FUNCTION? BHI 4$ ;IF HI NO INCB RTTBL+1(R3) ;YES, INDICATE POSITIONING OPERATION 4$: BIS (R0),U.BUF(R5) ;SET CONTROLLER FUNCTION BITS BR 10$ ;GO CHECK BLOCK NUMBER .ENDC 5$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION BIS #505,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 6$ ;IF HIS FUNCTION IS LEGAL JMP 120$ ;FUNCTION IS ILLEGAL 6$: BEQ 10$ ;IF EQ FUNCTION IS READ SUB #2,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION 10$: CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER MOV #12.,R1 ;SET DIVISOR CALL $DIV ;CALCULATE SECTOR NUMBER ASR R0 ;WHICH SURFACE? BCC 20$ ;IF CC SURFACE 0 BIS #20,R1 ;SET SURFACE 1 BIT 20$: SWAB R0 ;SWAP CYLINDER TO HIGH BYTE MOVB U.UNIT(R5),R2 ;RETRIEVE DRIVE NUMBER ASR R2 ;COLLECT DRIVE NUMBER AND CYLINDER ROR R0 ; ASR R2 ; ROR R0 ; ASR R2 ; ROR R0 ; BIS R1,R0 ;MERGE SURFACE AND SECTOR MOV R0,I.PRM+10(R3) ;SAVE DISK ADDRESS ; ; INITIATE I/O OPERATION ; 30$: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $MPUBM ;MAP UNIBUS TO TRANSFER .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;RETRIEVE ADDRESS OF I/O REQUEST PACKET MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT ADD #6,R2 ;POINT TO DISK ADDRESS REGISTER MOV I.PRM+10(R1),(R2) ;INSERT DISK ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;MAKE NEGATIVE WORD COUNT TST -(R2) ;POINT BACK TO CSR MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY TSTB -4(R2) ;IS DRIVE READY? BMI 31$ ;IF MI YES .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 35$ ;IF NE YES .IFTF .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BNE 51$ ;IF NE YES .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR .ENDC JMP 110$ ;FINISH UP 31$: ;REF LABEL .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC MOV U.BUF(R5),(R2) ;SET FUNCTION AND GO ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DKCAN: RETURN ;;;NOP FOR RK11 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DKPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS THE DRIVE CURRENTLY BUSY? BEQ 36$ ;IF EQ NO 35$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC029 36$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ;**-2 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DKINT-RK11 DISK CONTROLLER INTERUPTS ;- INTSE$ DK,PR5,R$$K11 ;;;SAVE REGISTERS AND SET PRIORITY TSTB RTTBL+1(R4) ;;;DRIVE RESET IN PROGRESS? BEQ 50$ ;;;IF EQ NO MOV R4,-(SP) ;;;SAVE CONTROLLER INDEX MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV @S.CSR(R4),R4 ;;;GET CONTENTS OF CSR BMI 40$ ;;;IF MI DRIVE RESET ERROR BIT #20000,R4 ;;;DRIVE RESET COMPLETE? BNE 40$ ;;;IF NE YES TST (SP)+ ;;;CLEAN STACK RETURN ;;; 40$: MOV (SP)+,R4 ;;;RESTORE CONTROLLER INDEX 50$: CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION EXECUTED? 51$: BNE 130$ ;IF NE YES .ENDC TST (R2) ;ANY ERRORS? BPL 65$ ;IF PL NO .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC MOV -2(R2),R1 ;SAVE ERROR STATUS REGISTER 53$: MOV S.PKT(R4),R0 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R0) ;INHIBIT RETRIES BNE 80$ ;IF NE YES DECB RTTBL(R3) ;ANY MORE RETRIES? BLE 80$ ;IF LE NO MOV #1,(R2) ;CLEAR CONTROLLER CLRB RTTBL+1(R3) ;CLEAR POSSIBLE DRIVE RESET IN PROGRESS 55$: BIT #110000,R1 ;DRIVE RESET REQUIRED? BEQ 70$ ;IF EQ NO 60$: MOVB #1,RTTBL+1(R3) ;SET DRIVE RESET IN PROGRESS MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET MOV I.PRM+10(R1),6(R2) ;SET PROPER DRIVE NUMBER MOV #515,(R2) ;RESET DRIVE RETURN ; 65$: ASRB RTTBL+1(R3) ;DRIVE RESET IN PROGRESS? BCC 75$ ;IF CC NO 70$: JMP 30$ ;RETRY FUNCTION 75$: ;REF LABEL .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ;WRITE WITH WRITE CHECK? BNE 76$ ;IF NE YES BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED? BEQ 110$ ;IF EQ NO 76$: MOV U.BUF(R5),R1 ;GET CURRENT FUNCTION CODE BIT #1*2,R1 ;WRITE OR WRITE CHECK FUNCTION? BEQ 110$ ;IF EQ NO BIS #2*2,U.BUF(R5) ;SET WRITE CHECK FUNCTION BIT #2*2,R1 ;WAS FUNCTION A WRITE CHECK? BNE 110$ ;IF NE YES MOV #RETRY&377,RTTBL(R3) ;REINITIALIZE RETRY COUNT BR 70$ ;START WRITE CHECK OPERATION .IFF BR 110$ ;FINISH OPERATION .ENDC 80$: MOV #IE.WLK&377,R0 ;ASSUME WRITE LOCK ERROR BIT #20000,R1 ;WRITE LOCK ERROR? BNE 110$ ;IF NE YES .IF DF D$$WCK MOV #IE.WCK&377,R0 ;ASSUME WRITE CHECK ERROR ASR R1 ;GOOD ASSUMPTION? BCS 110$ ;IF CS WRITE CHECK ERROR .ENDC MOV #IE.VER&377,R0 ;SET UNRECOVERABLE ERROR 110$: MOV 2(R2),R1 ;GET WORDS LEFT TO TRANSFER ASL R1 ;CONVERT TO BYTES LEFT TO TRANSFER ADD U.CNT(R5),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED MOV #1,(R2) ;CLEAR CONTROLLER 120$: ;REF LABEL .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION JMP DKINI ;PROCESS NEXT REQUEST ; ; DEVICE TIMEOUT RESULTS IN A CONTROL AND DRIVE RESET FOLLOWED BY THE ; I/O OPERATION BEING REPEATED UNLESS THE OPERATION WAS DIAGNOSTIC. ; TIMEOUTS ARE USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE ; RESULT OF A HARDWARE FAILURE. ; DKOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 125$ ;;;IF EQ NO INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #12.,S.STS(R4) ;;;HAVE WE WAITED 44 SECONDS YET? ; PJC029 BEQ 125$ ;;;IF EQ YES ;**-1 MTPS #0 ;;;ALLOW INTERRUPTS JMP 30$ ;RETRY OPERATION 125$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC029 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-1 .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 140$ ;IF CC TIMEOUT DURING NORMAL FUNCTION 130$: CALL $CRPAS ;PASS CONTROLLER REGISTERS TO TASK BR 110$ ;DIAGNOSTIC PROCESSING COMPLETE 140$: ;REF LABEL .ENDC MOV #110000,R1 ;8SET FOR DRIVE RESET BR 53$ ; .DSABL LSB .END 86d¸8kQ ›c, .TITLE PANIC .IDENT /05.07/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.07 ; ; D. N. CUTLER 4-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; J. M. GILBERT ; D. N. CUTLER ; K. E. KINNEAR ; P. J. BEZEREDI ; M. S. HARVEY ; ; MODIFIED BY: ; ; D. R. DONCHIN 09-OCT-80 ; DD080 -- ADD ^S/^Q SUPPORT TO CRASH AND PANIC ; ; ; PANIC DUMP ROUTINE ; .IF DF P$$NIC ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ; ; LOCAL DATA ; .IF NDF C$$RSH $CRPBF::.BLKW 18. ;PANIC'S REGISTER BUFFER AND STACK $CRPST:: ;TOP OF PANIC'S TEMPORARY STACK .ENDC .ENDC ;+ ; **-$PANIC-PANIC DUMP ; ; THIS ROUTINE IS ENTERED WHEN THE SYSTEM CRASHES OR BY FORCING AN ; ENTRY VIA THE CONSOLE SWITCHES. ON ENTRY THE PROCESSOR STATUS AND ; REGISTERS ARE SAVED IN A TEMPORARY STORAGE AREA. PANIC THEN HALTS ; AWAITING A SET OF DUMP LIMITS TO BE ENTERED IN THE SWITCH REGISTER. ; THE FOLLOWING PROCEDURE IS USED TO OBTAIN A DUMP: ; ; 1-WITH THE PROCESSOR HALTED ENTER THE LOW DUMP LIMIT IN THE ; SWITCH REGISTER. ; 2-DEPRESS CONTINUE. THE PROCESSOR WILL AGAIN HALT. ; 3-WITH THE PROCESSOR HALTED ENTER THE HIGH DUMP LIMIT IN THE ; SWITCH REGISTER. ; 4-DEPRESS CONTINUE. THE DUMP WILL BE OUTPUT ON THE DEVICE ; 'P$$NIC'. ; ; THE FIRST LINE OF OUTPUT IS THE DUMP OF PS,R0,R1,R2,R3,R4,R5, AND SP. ; SUCCEEDING LINES OF OUTPUT ARE THE ACTUAL DUMP. WHEN THE DUMP IS ; FINISHED, PANIC AGAIN HALTS AWAITING A NEW SET OF DUMP LIMITS TO ; BE INPUT. ;- .ENABL LSB $PANIC:: ;PANIC DUMP ROUTINE .IF NDF P$$NIC JMP $BTSTP ;RE-BOOT SYSTEM IF NO PANIC DUMP .IFF .IF DF M$$MGE MOV PS,$CRPBF ;SAVE PS WORD .IFF MFPS $CRPBF ;SAVE PS WORD .ENDC MTPS #PR7 ;LOCK OUT INTERRUPTS MOV R0,$CRPBF+2 ;;;SAVE RR0 MOV #$CRPBF+4,R0 ;;;POINT TO SAVE AREA MOV R1,(R0)+ ;SAVE REGISTER R1 TO SP MOV R2,(R0)+ ; MOV R3,(R0)+ ; MOV R4,(R0)+ ; MOV R5,(R0)+ ; MOV SP,(R0) ; 10$: HALT ;GET LOWER DUMP LIMIT MOV #$CRPST,SP ;SET NEW STACK POINTER .IF NDF S$$WRG MOV @#0,-(SP) ; .IFF MOV SWR,-(SP) ; .IFTF HALT ;GET ENDING DUMP LIMIT MOV #$CRPBF,R0 ;ALWAYS DUMP REGISTERS FIRST MOV #$CRPBF+16,R1 ; CALL $PDMP ;DUMP REGISTERS .IFT MOV @#0,R1 ;GET LAST WORD ADDRESS .IFF MOV SWR,R1 ;GET LAST WORD ADDRESS .ENDC MOV (SP)+,R0 ;AND FIRST WORD ADDRESS BIC #1,R0 ;MAKE SURE START IS EVEN CALL 20$ ;DUMP MEMORY BR 10$ ;GO AGAIN ; ; DUMP SELECTED BLOCK OF MEMORY ; $PDMP:: MOV #P$$NIC,R5 ;SET OUTPUT DEVICE CSR MOV #14,R2 ;OUTPUT A FORM FEED CALL $OUT ; 20$: MOV R0,-(SP) ;SAVE FOR RELATIVE ADDRESS 30$: MOV R0,-(SP) ;SAVE START OF LINE ADDRESS MOV R0,R2 ;SAVE CURRENT LINE 40$: MOV #8.,R4 ;COUNT FOR 1 LINE 50$: CMP (R0)+,@(SP) ;ARE WORDS EQUAL? BNE 60$ ;IF NOT, PRINT LINE DEC R4 ;COUNT THROUGH LINE BGT 50$ ;IF GT, NOT THROUGH YET MOV R0,R2 ;UPDATE LINE STARTING ADDRESS CMP R0,R1 ;AT END OF DUMP? BLOS 40$ ;IF NOT, CHECK NEXT LINE 60$: CMP R2,(SP) ;ANY LINES SUPPRESSED? BEQ 70$ ;NO, IF STARTING ADDRESS SAME MOV (SP),R3 ;EDIT OUT OLD STARTING ADDRESS MOV @(SP),R0 ;GET MASTER WORD MOV R2,(SP) ;NOW HAVE NEW STARTING ADDRESS CALL $EDIT ;WORD EDIT MOV #'-,R2 ;SEPARATE ADDRESSES WITH MINUS CALL $OUT ;OUTPUT MINUS CALL $OUTB ;AND NOW A BLANK MOV (SP),R3 ;NOW OUTPUT LAST SUPPRESSED WORD ADDRESS TST -(R3) ;2 LESS THAN NEW START OF LINE CALL $EDIT ;OUTPUT LAST WORD OF IDENTICAL BLOCK CALL $OUTB ;ISSUE ANOTHER BLANK MOV R0,R3 ;NOW GET REPEATED WORD CALL $EDIT ;OUTPUT REPEATED WORD CALL $CRLF ;ISSUE CARRIAGE RETURN/LINE FEED CALL $OUT ;OUTPUT ANOTHER LINE FEED MOV (SP)+,R0 ;PUT START OF LINE IN R0 CMP R0,R1 ;AT END OF DUMP? BHI 110$ ;IF HI, AT END MOV R0,-(SP) ;GET BACK IN SYNC WITH NEXT ROUTINE 70$: MOV (SP),R0 ;RECAPTURE NEW START OF LINE CALL WORD ;EDIT WORDS MOV (SP),R0 ;RETRIEVE STARTING ADDRESS CALL BYTE ;EDIT BYTES MOV (SP)+,R0 ;RETRIEVE STARTING ADDRESS MOV #5,R4 ;SET LOOP COUNT 80$: CALL $OUTB ;OUTPUT A BLANK DEC R4 ;ANY MORE? BGT 80$ ;IF GT YES MOV #8.,R4 ;SET REPEAT COUNT 90$: MOV (R0)+,R3 ;GET NEXT WORD CALL 120$ ;OUTPUT LOW BYTE SWAB R3 ;SWAP BYTES CALL 120$ ;OUTPUT HIGH BYTE DEC R4 ;ANY MORE THIS LINE? BGT 90$ ;IF GT YES 100$: CALL $CRLF ;OUTPUT A CR-LF CALL $OUT ;OUTPUT ANOTHER LF CMP R0,R1 ;END OF EDIT YET? BLOS 30$ ;IF NOT, GO AGAIN 110$: TST (SP)+ ;REMOVE START FOR RELATIVE ADDRESS CALL $OUT ;OUTPUT 2 MORE LINE FEEDS BR $OUT ;AND DON'T RETURN HERE 120$: CALL $OUTB ;OUTPUT TWO BLANKS CALL $OUTB ; BICB #200,R3 ;CLEAR PARITY BIT CMPB R2,R3 ;CONTROL CHARACTER? BLOS 130$ ;IF LOS NO BISB #100,R3 ;CONVERT TO CHARACTER MOVB #136,R2 ;SET TO OUTPUT CARET 130$: CALL $OUT ;OUTPUT BLANK OR CARET MOVB R3,R2 ;SET BYTE TO OUTPUT INCB R3 ;CHARACTER A RUBOUT? BMI $OUTB ;IF MI YES OUTPUT A BLANK BR $OUT ;OUTPUT CHARACTER .DSABL LSB ; ; WORD EDIT ; WORD: MOV R0,R3 ;EDIT LINE ADDRESS MOV #9.,R4 ;SET LOOP COUNT BR 20$ ; 10$: MOV (R0)+,R3 ;GET NEXT WORD 20$: CALL $EDIT ;EDIT WORD CALL $OUTB ;OUTPUT ANOTHER BLANK DEC R4 ;ANY MORE THIS LINE? BGT 10$ ;IF GT YES BR $CRLF ; ; ; BYTE EDIT ; BYTE: MOV R0,R3 ;COPY ADDRESS OF LINE SUB 4(SP),R3 ;CALCULATE BLOCK OFFSET CALL $EDIT ;EDIT OFFSET FROM START OF BLOCK MOV #8.,R4 ;SET LOOP COUNT 10$: MOV (R0)+,R3 ;GET NEXT WORD CALL EBYT ;EDIT HIGH BYTE CALL EBYT ;EDIT LOW BYTE DEC R4 ;ANY MORE THIS LINE? BGT 10$ ;IF GT YES .ENDC .IF DF C$$TTY!P$$NIC ; ; SUBROUTINE TO OUTPUT CR-LF ; $CRLF:: MOVB #15,R2 ;OUTPUT CR CALL $OUT ; MOVB #12,R2 ;OUTPUT A LF BR $OUT ; ; ; SUBROUTINE TO EDIT ONE BYTE ; EBYT: CLR R2 ;CLEAR CHARACTER ACCUMULATOR MOV #3,-(SP) ;SET CHARACTER COUNT BR EDT2 ;COLLECT HIGH ORDER 2 BITS  ; ; SUBROUTINE TO EDIT ONE WORD ; $EDIT:: CLR R2 ;CLEAR CHARACTER ACCUMULATOR MOV #6,-(SP) ;SET CHARACTER COUNT BR EDT3 ;COLLECT HIGH ORDER BIT EDT1: CLR R2 ;COLLECT NEXT 3 BITS ASL R3 ; ROL R2 ; EDT2: ASL R3 ; ROL R2 ; EDT3: ASL R3 ; ROL R2 ; ADD #'0,R2 ;ADD DIGIT BIAS CALL $OUT ;OUTPUT CHARACTER DEC (SP) ;ANY MORE? BGT EDT1 ;IF GT YES TST (SP)+ ;CLEAR STACK ; ; OUTPUT SUBROUTINES ; $OUTB:: MOVB #40,R2 ;SET TO OUTPUT BLANK .ENDC .IF DF C$$RSH!P$$NIC $OUT:: CMP #177564,R5 ;OUTPUT DEVICE A TERMINAL? ; DD080 BNE 6$ ;IF NE NO ; DD080 TSTB -4(R5) ;WAS A CHARACTER ENTERED FROM TERMINAL? ; DD080 BPL 6$ ;IF PL NO ; DD080 MOVB -2(R5),-(SP) ;GET CHARACTER ; DD080 BICB #200,(SP) ;CLEAR POSSIBLE PARITY BIT ; DD080 CMPB (SP)+,#23 ;IS CHARACTER A CONTROL-S? ; DD080 BNE 6$ ;IF NE NO, IGNORE IT ; DD080 4$: TSTB -4(R5) ;WAIT FOR NEXT CHARACTER TO BE INPUT ; DD080 BPL 4$ ;IF PL NOT YET ; DD080 MOVB -2(R5),-(SP) ;GET CHARACTER ; DD080 BICB #200,(SP) ;CLEAR POSSIBLE PARITY BIT ; DD080 CMPB (SP)+,#21 ;IS CHARACTER A CONTROL-Q? ; DD080 BNE 4$ ;IF NE NO, IGNORE IT ; DD080 6$: TSTB (R5) ;OUTPUT DEVICE READY? ; DD080 BPL $OUT ;IF PL NO ;**-1 MOVB R2,2(R5) ;OUTPUT CHARACTER CMPB #15,R2 ;CARRIAGE RETURN? BNE 20$ ;IF NE NO CMP #177514,R5 ;OUTPUT DEVICE LINE PRINTER? BEQ 20$ ;IF EQ YES CLR R2 ;SET ZERO FILL CHARACTER MOV #5,-(SP) ;SET FILL COUNT 10$: CALL $OUT ;OUTPUT A FILL CHARACTER tDEC (SP) ;ANY MORE TO FILL? BGT 10$ ;IF GT YES TST (SP)+ ;CLEAN STACK 20$: RETURN ; .ENDC .END t„ðskQ ›c, .TITLE DPDRV .IDENT /07.01/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 07.01 ; ; D. N. CUTLER 9-FEB-74 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; RP11-C/E DISK PACK CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RETRY=8. ;ERROR RETRY COUNT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW R$$P11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$P11 ;ERROR RETRY COUNT AND POSITIONING FLAG .IF GT R$$P11-1 TEMP: .BLKW 1 ;TEMPORY STORAGE FOR CONTROLLER NUMBER .ENDC .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS ; ; DIAGNOSTIC FUNCTION CODE TABLE ; FUNTBL: .WORD IO.HMS!IQ.UMD, 20015 .WORD IO.BLS!IQ.UMD, 20011 .WORD IO.RDH!IQ.UMD, 14105 .WORD IO.WDH!IQ.UMD, 14103 .WORD IO.WCK!IQ.UMD, 00107 FUNTBE: .ENDC ; ; DRIVER DISPATCH TABLE ; $DPTBL::.WORD DPINI ;DEVICE INITIATOR ENTRY POINT .WORD DPCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DPOUT ;DEVICE TIMEOUT .WORD DPPWF ;POWERFAIL ENTRY POINT ;+ ; **-DPINI-RP11-C/E DISK PACK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB 1$: RETURN ;CONTROLLER BUSY OR NO REQUEST DPINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 1$ ;IF CS NO PACKET ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R3=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RP11-C/E DISK PACK CONTROLLER I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. ADRS ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS .ENDC MOVB R2,U.BUF+1(R5) ;INSERT DRIVE NUMBER .IF DF D$$IAG CMPB #IO.HMS/^D<256>,I.FCN+1(R1) ;DIAGNOSTIC FUNCTION? BNE 5$ ;IF NE NO MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE 3$: CMP (R0)+,I.FCN(R1) ;FUNCTION CODE MATCH? BEQ 4$ ;IF EQ YES TST (R0)+ ;BYPASS CONTROLLER CODE CMP #FUNTBE,R0 ;END OF FUNCTION TABLE? BEQ 5$ ;IF EQ YES BR 3$ ;TRY AGAIN 4$: BIS (R0),U.BUF(R5) ;SET CONTROLLER FUNCTION BITS BR 10$ ;GO CHECK LOGICAL BLOCK NUMBER .ENDC 5$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION BIS #105,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 6$ ;IF HIS FUNCTION IS LEGAL JMP 100$ ;FUNCTION IS ILLEGAL 6$: BEQ 10$ ;IF EQ FUNCTION WAS READ SUB #2,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION 10$: MOV #RETRY&377,RTTBL(R3) ;CLEAR HOME SEEK FLAG AND SET RETRY COUNT CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER ASR R2 ;DIVIDE LOGICAL BLOCK NUMBER BY 2 ROR R0 ; ROL R2 ;SAVE 1 BIT REMAINDER MOV #100.,R1 ;SET CYLINDER DIVISOR CALL $DIV ;CALCULATE CYLINDER NUMBER MOV R0,I.PRM+10(R3) ;SAVE CYLINDER NUMBER ASL R1 ;MULTIPLY REMAINDER BY 2 BIS R2,R1 ;MERGE PREVIOUS 1 BIT REMAINDER MOV R1,R0 ;SET DIVIDEND MOV #10.,R1 ;SET TRACK DIVISOR CALL $DIV ;CALCULATE TRACK AND SECTOR SWAB R0 ;SWAP TRACK NUMBER TO LEFT BYTE BIS R1,R0 ;MERGE SECTOR NUMBER MOV R0,I.PRM+12(R3) ;SAVE TRACK AND SECTOR ADDRESS ; ; INITIATE I/O OPERATION ; 30$: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $MPUBM ;MAP UNIBUS TO TRANSFER .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;RETRIEVE ADDRESS OF I/O REQUEST PACKET MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT CALL 200$ ;ABORT CONTROLLER AND SELECT UNIT ADD #10,R2 ;POINT TO DISK ADDRESS REGISTER MOV I.PRM+12(R1),(R2) ;INSERT TRACK AND SECTOR ADDRESS MOV I.PRM+10(R1),-(R2) ;INSERT CYLINDER ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;MAKE NEGATIVE WORD COUNT TST -(R2) ;POINT BACK TO CSR MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY MOV -4(R2),-(SP) ;GET CONTENTS OF DRIVE STATUS REGISTER COM (SP) ;COMPLEMENT STATUS BIT #140000,(SP)+ ;DRIVE READY AND ON-LINE? BEQ 31$ ;IF EQ YES .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 35$ ;IF NE YES .IFTF .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BNE 39$ ;IF NE YES .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR .ENDC JMP 90$ ;FINISH I/O 31$: ;REF LABEL .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC  .IF DF D$$IAG CMPB #IO.RDH!IQ.UMD&377,I.FCN(R1) ;READ HEADER FUNCTION? BEQ 33$ ;IF EQ YES CMPB #IO.WDH!IQ.UMD&377,I.FCN(R1) ;WRITE HEADER FUNCTION? BNE 34$ ;IF NE NO 33$: BIT #360,10(R2) ;SYNCHRONIZE THE SECTOR COUNTER ... BNE 33$ ;... ON THE NEXT INDEX PULSE IN CASE ... BIT #360,10(R2) ;... A UNIT OTHER THAN 0 WAS ... BNE 33$ ;... SELECTED FOR HEADER OPERATIONS. 34$: ;REF LABEL .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC MOVB U.BUF(R5),(R2) ;LOAD FUNCTION AND GO ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DPCAN: RETURN ;;;NOP FOR RP11 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DPPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS DRIVE CURRENTLY BUSY? BEQ 36$ ;IF EQ NO 35$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC029 36$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ;**-2 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DPINT-RP11-C/E DISK PACK CONTROLLER INTERRUPTS ;- INTSE$ DP,PR5,R$$P11 ;;;SAVE REGISTERS AND SET PRIORITY MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV S.CSR(R4),R4 ;;;GET ADDRESS OF CSR BIC #20100,(R4) ;;;CLEAR INTERRUPT ENABLE MOVB #377,-4(R4) ;;;CLEAR ATTENTION SUMMARY BITS ON CLRB -4(R4) ;;;BOTH OLD AND ECO'D CONTROLLERS CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R2 ;COPY ADDRESS OF CSR MOV U.SCB(R5),R4 ;RETRIEVE ADDRESS OF SCB MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION EXECUTED? 39$: BNE 105$ ;IF NE YES .ENDC ASRB RTTBL+1(R3) ;HOME SEEK IN PROGRESS? BCS 59$ ;IF CS YES TST (R2) ;ANY ERRORS? BPL 50$ ;IF PL NO .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC 40$: BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE 60$ ;IF NE YES DECB RTTBL(R3) ;ANY MORE RETRIES? BLE 60$ ;IF LE NO BIT #1371,-2(R2) ;RECOVERABLE ERROR? BEQ 60$ ;IF EQ NO BIT #14000,-4(R2) ;SKI OR HNF ERRORS? BEQ 46$ ;IF EQ NO 45$: MOVB #1,RTTBL+1(R3) ;SET HOME SEEK IN PROGRESS FLAG MOVB S.ITM(R4),S.CTM(R4) ;RESET DEVICE TIMEOUT COUNT CALL 200$ ;ABORT CONTROLLER AND SELECT UNIT BIS #20015,(R2) ;INITIATE HOME SEEK FUNCTION RETURN ; 46$: JMP 30$ ;RETRY ENTIRE OPERATION 50$: ;REF LABEL .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK? BNE 51$ ;IF NE YES BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR? BEQ 90$ ;IF EQ NO 51$: MOVB U.BUF(R5),R1 ;GET LAST FUNCTION BIT #1*2,R1 ;WRITE OR WRITE CHECK FUNCTION? BEQ 90$ ;IF EQ NO BIS #2*2,U.BUF(R5) ;SET WRITE CHECK FUNCTION BIT #2*2,R1 ;WAS LAST FUNCTION A WRITE CHECK? BNE 90$ ;IF NE YES MOV #RETRY,RTTBL(R3);REINITIALIZE RETRY COUNT BR 46$ ;START WRITE CHECK OPERATION .IFF BR 90$ ;FINISH OPERATION .ENDC 59$: TST (R2) ;HOME SEEK SUCCESSFUL? BPL 46$ ;IF PL YES 60$: MOV #IE.WLK&377,R0 ;ASSUME DRIVE WRITE LOCKED MOV -2(R2),R1 ;GET CONTENTS OF ERROR REGISTER BMI 90$ ;IF MI WRITE LOCK ERROR .IF DF D$$WCK MOV #IE.WCK&377,R0 ;ASSUME WRITE CHECK ERROR BIT #10,R1 ;WRITE CHECK ERROR? BNE 90$ ;IF NE YES .ENDC MOV #IE.VER&377,R0 ;UNRECOVERABLE ERROR 90$: MOV 2(R2),R1 ;GET WORDS REMAINING TO TRANSFER ASL R1 ;CONVERT TO BYTES LEFT TO TRANSFER ADD U.CNT(R5),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED CALL 200$ ;ABORT THE CONTROLLER 100$: ;REF LABEL .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION JMP DPINI ;PROCESS NEXT REQUEST ; ; DEVICE TIMEOUT RESULTS IN A HOME SEEK FOLLOWED BY THE I/O OPERATION ; BEING REPEATED UNLESS THE OPERATION WAS DIAGNOSTIC. TIMEOUTS ARE ; USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A ; HARDWARE FAILURE. ; DPOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 104$ ;;;IF EQ NO INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #20.,S.STS(R4) ;;;HAVE WE WAITED 76 SECONDS YET? ; PJC029 BEQ 104$ ;;;IF EQ YES ;**-1 MTPS #0 ;;;ALLOW INTERRUPTS BR 46$ ;RETRY ENTIRE OPERATION 104$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC029 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-1 .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 110$ ;IF CC TIMEOUT DURING NORMAL FUNCTION 105$: CALL $CRPAS ;PASS CONTROLLER REGISTERS TO TASK BR 90$ ;DIAGNOSTIC PROCESSING COMPLETE 110$: ;REF LABEL .ENDC MOVB U.UNIT(R5),1(R2) ;SET CURRENT UNIT NUMBER MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE 90$ ;IF NE YES DECB RTTBL(R3) ;ANY RETRIES LEFT? BLE 90$ ;IF LE NO BR 45$ ; ;+ ; THIS ROUTINE WILL ABORT THE CONTROLLER AND SELECT THE CURRENT ; UNIT. A DELAY IS INITIATED BETWEEN EACH CONTROLLER ABORT TO ; ALLOW THE HARDWARE TIME TO SETTLE DOWN ON FAST PROCESSORS. ;- 200$: MOV #1,(R2) ;ABORT THE CONTROLLER BICB -(SP),(SP)+ ;DELAY TO ALLOW THE HARDWARE ... BICB -(SP),(SP)+ ;... TIøME TO SETTLE DOWN MOV #1,(R2) ;CLEAR ANY ERRORS CAUSED BY THE ABORT BICB -(SP),(SP)+ ;DELAY TO ALLOW THE HARDWARE ... BICB -(SP),(SP)+ ;... TIME TO SETTLE DOWN MOVB U.BUF+1(R5),1(R2) ;SELECT THE UNIT RETURN ; .DSABL LSB .END øÑØkQ ›c, .TITLE DRABO .IDENT /04.02/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.02 ; ; D. N. CUTLER 11-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; ; MODIFIED BY: ; ; M. S. HARVEY 6-OCT-80 ; MSH121 -- ADD SUPPORT FOR REQUESTED EXIT ASTS ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$ ABODF$ ;DEFINE TASK ABORT CODES ;+ ; **-$DRABO-ABORT TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF A ; SPECIFIED TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(83.),DPB SIZE(3.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO TERMINATE. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO TERMINATE. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2.  ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF THE SPECIFIED ; TASK IS NOT ACTIVE. ;- $DRABO::TST (R1)+ ;SPECIFIED TASK ACTIVE? (T.STAT) ;MSH121 BMI 10$ ;IF MI NO ;**-1 TSTB (R1) ;TASK ALREADY BEING TERMINATED? (T2.HLT);MSH121 BMI 10$ ;IF MI YES ;**-1 ;MSH121 .IF DF A$$TRP&A$$BRT ;MSH121 ;MSH121 CLR R2 ;INIT SUB-CODE (AB.TYP!AB.NPV=0) ;MSH121 BIT #T3.PRV,T.ST3(R5) ;ISSUING TASK PRIVILEGED? ;MSH121 BNE 5$ ;IF NE YES, R2 OK ;MSH121 INC R2 ;NONPRIVILEGED TASK'S DIRECTIVE (AB.NPV);MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 5$: MOV R0,R1 ;SET TCB ADDRESS OF TASK TO ABORT ;MSH121 MOV #S.CABO,R0 ;SET REASON FOR ABORT ;**-1 CALLR $ABTSK ;ABORT TASK 100$: DRSTS D.RS7 ;SET DIRECTIVE STATUS .END 0ÑÀ€kQ ›c, .TITLE DRATX .IDENT /07.04/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 07.04 ; ; D. N. CUTLER 31-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 9-OCT-79 ; MSH069 -- EVENT FLAG MASK AND MASK ADDRESS NOW ; RESIDE IN THE TCB INSTEAD OF THE HEADER  ; ; M. S. HARVEY 12-SEP-80 ; MSH115 -- CLEAR PRE-AST STOP,SUSPEND AND WAITFOR BITS ; FOR GROUP GLOBAL RUNDOWN OF ABORTED TASKS ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HDRDF$,HWDDF$,TCBDF$ ABODF$ ;DEFINE TASK ABORT CODES HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRATX-AST SERVICE EXIT ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF AN ; ASYNCHRONOUS SYSTEM TRAP SERVICE ROUTINE. IF ANOTHER AST IS QUEUED AND ; AST'S ARE NOT DISABLED, THEN THE NEXT AST IS EFFECTED IMMEDIATELY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(115.),DPB SIZE(1.). ; ; AT ISSUANCE THE TASK STACK CONTAINS: ; ; 14(SP)=EVENT FLAG MASK WORD FOR FLAGS 1.-16. ; 12(SP)=EVENT FLAG MASK WORD FOR FLAGS 17.-32. ; 10(SP)=EVENT FLAG MASK WORD FOR FLAGS 33.-48. ; 06(SP)=EVENT FLAG MASK WORD FOR FLAGS 49.-64. ; 04(SP)=PRE AST TASK PS. ; 02(SP)=PRE AST TASK PC. ; 00(SP)=PRE AST TASK DIRECTIVE STATUS WORD. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS WORD RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF PRE AST STATE IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THE DIRECTIVE ; WAS NOT EXECUTED FROM AN AST SERVICE ROUTINE. ; ; NOTE: IF AN ADDRESS CHECK FAILURE OCCURS WHILE REMOVING ARGU- ; MENTS FROM THE TASK STACK, THEN THE ISSUING TASK IS ; ABORTED. ;- .IF DF A$$TRP $DRATX::MOV (R2),-(SP) ;DIRECTIVE EXECUTED FROM AST? BPL 10$ ;IF PL NO BIC #^C*2>>,(SP) ;ISOLATE BIT;MSH115 BIC (SP),(R2) ;CLEAR AST STATE AND PRE-AST BITS ;MSH115 ASR (SP) ;SET UP TASK'S CURRENT STATUS BITS ;MSH115 BISB (SP)+,(R2) ;RESTORE PRE AST STATE ;**-3 .IF DF C$$CKP&D$$ISK BIT #T2.STP,(R2) ;WAS TASK STOPPED? BEQ 5$ ;IF EQ NO MOV T.PCB(R5),R0 ;POINT TO TASK PCB CALL $NXTSK ;REALLOCATE TASK PARTITION .ENDC 5$: MOV @$HEADR,R3 ;GET SAVED STACK POINTER .IF DF M$$MGE MFPI SP ;GET USER STACK POINTER MOV (SP),R0 ;COPY STACK POINTER ADD #2,R0 ;STEP OVER DPB WORD ADD #16,(SP) ;ADJUST TO NEW TOP OF STACK MTPI SP ;RESTORE USER STACK POINTER .IFF MOV R3,R0 ;COPY SAVED STACK POINTER ADD #4*2+2,R0 ;POINT TO FIRST USER STACK WORD .IFTF .IF DF A$$CHK!M$$MGE MOV #7*2,R1 ;SET NUMBER OF BYTES TO CHECK CALL $ACHCK ;ADDRESS CHECK TASK STACK WORDS BCS 20$ ;IF CS ADDRESS CHECK FAILURE .ENDC .IFT CALL $RELOM ;RELOCATE AND MAP STACK ADDRESS .IFTF MOV (R0)+,2(SP) ;SET DIRECTIVE STATUS TO RETURN CMP (R3)+,(R3)+ ;POINT TO SAVED PC MOV (R0)+,(R3)+ ;RESTORE PRE AST PC MOV (R0)+,(R3)+ ;RESTORE PRE AST PS .IFT BIS #CMODE!PMODE,-(R3) ;MAKE SURE CURRENT AND PREVIOUS IS USER BIC #PR7,(R3)+ ;MAKE SURE PRIORITY IS ZERO .IFTF .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 MOV (R0)+,T.EFLM(R5) ;RESTORE WAITFOR MASK WORD ;MSH069 MOV H.EFSV(R4),T.EFLM+2(R5) ;RESTORE WAITFOR MASK ADDRESS ;MSH069 ;MSH069 .IFF ;MSH069 ;MSH069 MOV (R0)+,H.EFLM(R4) ;RESTORE WAITFOR MASK WORD MOV H.EFSV(R4),H.EFLM+2(R4) ;RESTORE WAITFOR MASK ADDRESS ;MSH069 .ENDC ;MSH069 .IFF TST (R0)+ ;ADJUST TO PROPER LOCATION MOV -(R3),(R0) ;MOVE TASK PS WORD MOV -(R3),-(„R0) ;MOVE TASK PC WORD MOV -(R3),-(R0) ;MOVE SAVED R5 MOV -(R3),-(R0) ;MOVE SAVED R4 MOV R0,@$HEADR ;SET ADDRESS OF NEW TASK STACK POINTER .ENDC CALLR $SETRT ;FORCE A REDISPATCHING OF PROCESSOR 10$: DRSTS D.RS80 ;SET DIRECTIVE STATUS .IF DF A$$CHK!M$$MGE 20$: MOV #S.CAST,R0 ;SET AST ABORT CALLR $ABCTK ;ABORT CURRENT TASK .ENDC .ENDC .END „Ô kQ ›c, .TITLE DRDAR .IDENT /04.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.00 ; ; D. N. CUTLER 30-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; ; MODIFIED BY: ; ; DISABLE/ENABLE AST RECOGNITION DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL TCBDF$ TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS  ;+ ; **-$DRDAR-DISABLE AST RECOGNITION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DISABLE RECOGNITION OF ASYNCHRONOUS ; SYSTEM TRAPS FOR THE ISSUING TASK. FURTHER AST'S ARE QUEUED AS THEY OCCUR ; AND WILL BE EFFECTED WHEN AST RECOGNITION IS ENABLED. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(99.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST RECOG- ; NITION IS ALREADY DISABLED. ;- .IF DF A$$TRP .ENABL LSB $DRDAR::BIT #T2.DST,(R2) ;AST RECOGNITION ALREADY DISABLED? BNE 10$ ;IF NE YES BIS #T2.DST,(R2) ;DISABLE AST RECOGNITION RETURN ;RETURN DIRECTIVE STATUS OF +1 ;+ ; **-$DREAR-ENABLE AST RECOGNITION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO RECOGNIZE ASYNCHORONOUS SYSTEM ; TRAPS FOR THE ISSUING TASK. AST'S THAT HAVE BEEN QUEUED WHILE AST RECOG- ; NITION WAS DISABLED ARE EFFECTED IMMEDIATELY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(101.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTüS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST RECOG- ; NITION IS NOT DISABLED. ;- $DREAR::BIT #T2.DST,(R2) ;AST RECOGNITION DISABLED? BEQ 10$ ;IF EQ NO BIC #T2.DST,(R2) ;ENABLE AST RECOGNITION CALLR $SETRT ;FORCE A REDISPATCHING OF PROCESSOR 10$: DRSTS D.RS8 ;SET DIRECTIVE STATUS .DSABL LSB .ENDC .END üìðskQ ›c, .TITLE DYDRV .IDENT /02.16/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.16 ; ; M. BAGGETT/R. PERRON 22-MAR-79 ; ; MODIFIED BY: ; ; R. T. PERRON 12-DEC-79 ; ; RP025 -- CORRECT BUFFER OVERFLOW DETECTION ; ; P. J. CARR 4-MAR-80 ; ; PJC001 -- CORRECT INVALID DEVICE NOT READY (IE.DNR) ERROR ; ; P. J. CARR 29-APR-80 ; ; PJC006 -- REMOVE SECOND-SIDE SUPPORT ; ; P. J. CARR 11-JUN-80 ; ; PJC007 -- CORRECT REGISTER USAGE ; ; P. J. CARR 23-JUN-80 ; ; PJC009 -- CORRECT THE ROUTINE WHICH DETERMINES THE ; I/O ERROR CODE (REPLACES PJC001) ; ; P. J. CARR 24-JUN-80 ; ; PJC010 -- CORRECT IO.SEC FUNCTION ; ; P. J. CARR 25-JUN-80 ; ; PJC011 -- DON'T ALLOW IO.SMD IF DEVICE IS MOUNTED FILES-11 ; ; P. J. CARR 2-JUL-80 ; ; PJC012 -- FIX PHYSICAL BLOCK TRANSFERS TO TRACKS ; GREATER THAN 64. ; ; P. J. CARR 13-MAR-81 ; ; PJC014 -- CORRECT DETECTION OF DELETED DATA ; ; DAN BROWN 25-MAR-81 ; ; DTB012 -- REMOVE REFERENCES TO $IOABM FOR NEW ERROR LOG ; ; P. J. CARR 27-MAR-81 ; ; PJC022 -- CORRECT DENSITY ERROR RECOVERY ; ; D. S. SUMMERS 15-APR-81 ; ; DS004 -- ADD INIT AFTER SEEK ERROR ; ; P. J. CARR 9-NOV-81 ; ; PJC037 -- ADD ROUTINE TO LOG ERROR PACKET ; ; P. J. CARR 9-NOV-81 ; ; PJC038 -- CLEAN UP CODE ; ; D. S. SUMMERS 9-NOV-81 ; ; DS010 -- CORRECT ERROR AND RETRY CODE ; ; RX211- NPR FLOPPY DISK DRIVER ; ; FUNCTIONS RECOGNIZED: ; IO.RPB - READ PHYSICAL BLOCK (MAY READ ANY SECTOR ON DISK) ; IO.WPB - WRITE PHYSICAL BLOCK (MAY WRITE ANY SECTOR ON DISK) ; IO.WDD - WRITE DELETED DATA - WRITE ANY SECTOR ON DISK ; SETTING THE DELETED DATA MARK IN SECTOR HEADER ; ; THE FOLLOWING FUNCTION CODES OPERATE ON 256. WORD BLOCKS OF DATA ; (4 SECTORS FOR SINGLE DENSITY OR 2 SECTORS FOR DOUBLE DENSITY). ; THE DRIVER AUTOMATICALLY INTERLEAVES AND SKEWS SECTORS TO OPTIMIZE  ; THE TRANSFER OF DATA SO THAT A LONG TRANSFER MAY BE DONE WITHOUT ; LOOSING A REVOLUTION OF THE DISK. THE INTERLEAVE FACTOR IS 2 AND ; THE SKEW FACTOR IS 6. ; IO.RLB - READ LOGICAL BLOCKS OF 256. WORDS ; IO.WLB - WRITE LOGICAL BLOCKS OF 256. WORDS. ; ; THE FOLLOWING FUNCTION CODES ARE USED TO INITIALIZE THE FLOPPY ; TO SINGLE OR DOUBLE DENSITY AND TO REPORT WHICH DENSITY THE CURRENT ; FLOPPY IS. ; IO.SMD - SET MEDIA DENSITY ; IO.SEC - SENSE MEDIA CHARACTERISTICS ; ; IF DELETED DATA IS READ, THE STATUS CODE RETURNED WILL BE IS.RDD, ; OTHERWISE IT WILL BE IS.SUC. ; .MCALL HWDDF$,PKTDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS PKTDF$ ; DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RETRY = 10 ; ERROR RETRY COUNT DYNUM = 6 ; REGISTERS TO LOG ON ERROR ; PJC037 ; PJC038 ; ; PJC038 ; U.CW2 BITS USAGE ; PJC038 ; ; PJC038 ; PJC038 DELDAT = 100 ; DELETED DATA READ ; PJC038 ERR1 = 2000 ; TIMEOUT ERROR ; PJC038 DEN = 4000 ; DENSITY BIT (1=DOUBLE) ; PJC038 RSAE = 10000 ; READ STATUS AFTER ERROR ; PJC038 SCHAR = 40000 ; SENSE MEDIA CHARACTERISTICS FUNTION ; PJC038 SILO = 100000 ; FCN ISSUED WAS A SILO FUNCTION ; PJC038 ; PJC038 ; ; PJC038 ; U.CW3 WORD USAGE ; PJC038 ; ; PJC038 ; PJC038 SINGLE = 494. ; SINGLE DENSITY ; PJC038 DOUBLE = 988. ; DOUBLE DENSITY ; PJC038 ; PJC038 ;**-8 ; ; DEVICE REGISTER OFFSETS AND BIT DEFINITIONS ; RXCS= 0 ; CONTROL STATUS REGISTER GO = 1 ; GO BIT UNIT = 20 ; UNIT SELECT BIT DONE = 40 ; DONE BIT INTEBL = 100 ; INTERRUPT ENABLE TR = 200 ; TRANSFER READY BIT (CPU-SILO) SDEN = 400 ; DENSITY BIT RX211 = 4000 ; RX211 INDICATOR BIT ;**-1 INIT = 40000 ; INITIALIZATION BIT ERR = 100000 ; ERROR BIT RXDB = 2 ; DATA BUFFER REGISTER RXES = 2 ; RX211 ERROR STATUS REGISTER CRCERR = 1 ; CRC ERROR BIT INITDN = 4 ; INITIALIZE DONE BIT ;**-1 RXACLO = 10 ; RX221 AC LOW BIT DENERR = 20 ; DENSITY ERROR BIT DRVDEN = 40 ; SELECTED DRIVE'S DENSITY BIT DELDAT = 100 ; DELETED DATA BIT (USED IN U.CW2 ALSO) ; PJC014 DRVRDY = 200 ; SELECTED DRIVE READY BIT ;**-1 UNTSEL = 400 ; UNIT SELECTED BIT WCOVFL = 2000 ; WORD COUNT OVERFLOW BIT NXM = 4000 ; NON-EXISTENT MEMORY BIT ; ; FUNCTION CODES ; FILL = INTEBL!0!GO ; FILL SILO EMPTY = INTEBL!2!GO ; EMPTY SILO WRITE = INTEBL!4!GO ; WRITE A SECTOR READ = INTEBL!6!GO ; READ A SECTOR SETDEN = INTEBL!10!GO ; SET MEDIA DENSITY MRDS = INTEBL!12!GO ; MAINTENANCE READ STATUS WRTDD = INTEBL!14!GO ; WRITE DELETED DATA RDERC = INTEBL!16!GO ; READ ERROR CODE ; ; LOCAL DATA ; ; IMPURE DATA TABLES INDEXED BY CONTROLLER NUMBER ; CNTBL: .BLKW R$$X21 ; ADDRESS OF CURRENT UCB FOR CONTROLLER RTTBL: .BLKW R$$X21 ; ERROR RETRY COUNT FOR CURRENT UNIT ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 CSRSV: .BLKW R$$X21 ; WORD TO SAVE CSR FUNCTION CODE ; PJC037 ; PJC037 .ENDC ; PJC037 .IF GT R$$X21-1 TEMP: .BLKW 1 ; TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $DYTBL::.WORD DYINI ; DEVICE INITIATOR ENTRY .WORD DYCAN ; CANCEL I/O OPERATION ENTRY .WORD DYOUT ; DEVICE TIME OUT ENTRY .WORD DYPWF ; POWERFAIL ENTRY POINT ;+ ; *** - DYINI FLOPPY DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QIO DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPOGATE THE ; EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, ; THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O REQUEST. OTHERWISE ; A RETURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL ; THE NEXT I/O OPERATION IS INITIATED. A RETURN TO THE CALLER IS THEN ; EXECUTED. ; ; INPUTS: ; R5 - ADDRESS OF UCB OF CONTROLLER TO BE INITIATED ; ; OUTPUTS: ; IF THE CONTROLLER ASSOCIATED WITH THE SPECIFIED UCB IS NOT ; BUSY AND AN I/O REQUEST IS WAITING TO BE PROCESSED, THE REQUEST ; IS DEQUEUED AND THE DRIVER INITIATES THE REQUESTED FUNCTION. ; ;- .ENABL LSB DYINI: CALL $GTPKT ; TRY TO GET AN I/O PACKET BCC 10$ ; ; PJC038 JMP DYPWF ; IF CS BUSY OR NO PACKET ;**-1 ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT ; ; R1 - ADDRESS OF THE I/O PACKET ; R2 - PHYSICAL UNIT NUMBER OF DEVICE TO BE INITIATED ; R3 - CONTROLLER INDEX ; R4 - ADDRESS OF SCB ; R5 - ADDRESS OF THE UCB ; ; FLOPPY DISK I/O REQUEST PACKET FORMAT ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD. 02 -- ADDRESS OF TCB OF THE REQUESTING TASK ; WD. 03 -- POINTER TO SECOND LUN WORD OF REQUESTING TASKS HEADER ; WD. 04 -- CONTENTS OF FIRST LUN WORD ( UCB ADDRESS) ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.RPB, IO.WLB, IO.WPB, ; IO.WDD, IO.SMD OR IO.SEC) ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE  ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO TRANSFER ; WD. 15 -- NOT USED (IGNORED) ; WD. 16 -- LOW BYTE MUST BE ZERO, HIGH BYTE NOT USED ; WD. 17 -- LOGICAL OR PHYSICAL BLOCK NUMBER ; WD. 20 -- NOT USED ; ; DRIVER USAGE OF WORDS IN I/O PACKET ; I.PRM+6 (WD. 15) - STATUS REGISTER AFTER INTERRUPT ; I.PRM+10 (WD. 16) - LOGICAL OR PHYSICAL BLOCK NUMBER ; I.PRM+12 (WD. 17) - SIZE OF "THIS" TRANSFER ; I.PRM+14 (WD. 20) - PHYSICAL SECTOR NUMBER (1-26.) ; I.PRM+15 (WD. 20) - PHYSICAL TRACK NUMBER (0-76.) ; ; ; INITIALIZE DRIVER ; 10$: MOV R5,CNTBL(R3) ; SAVE UCB ADDRESS OF CURRENT REQUEST ; PJC038 MOV #RETRY,RTTBL(R3); SET RETRY COUNT ;**-1 TSTB I.PRM+10(R1) ; HIGH BLOCK SPECIFIED? BEQ 30$ ; IF EQ NO ; PJC038 20$: JMP 360$ ; YES, ERROR ; PJC038 ; ;**-2 ; CHECK FOR A VALID FUNCTION ; 30$: MOV S.CSR(R4),R2 ; GET CSR ADDRESS ; PJC038 CMPB #IO.SEC/256.,I.FCN+1(R1) ; VALID FUNCTION? ;**-1 BNE 60$ ; IF NE, IT MUST BE A READ OR WRITE ; PJC038 MOV #4,RTTBL(R3) ; SET AND SMD FUNC'S ONLY 4 RETRIES ; DS010 MOV I.FCN(R1),R0 ; GET FUNCTION CODE ;**-1 BIC #7,R0 ; REMOVE QUALIFIER BITS CMP #IO.SEC,R0 ; SENSE CHARACTERISTICS? BNE 40$ ; IF NE NO ; PJC038 JMP DYSEC ; GET DISKETTE CHARACTERISTICS ;**-1 40$: CMP #IO.SMD,R0 ; SET MEDIA DENSITY? ; PJC038 BNE 50$ ; IF NE NO ; PJC038 BITB #US.MNT!US.FOR,U.STS(R5) ; DEVICE MOUNTED? ; PJC011 BEQ 50$ ; IF EQ YES ; PJC038 MOV R0,I.FCN(R1) ; SET FUNCTION CODE WITHOUT MODIFIERS ;**-2 JMP DYSMD ; SET DISKETTE DENSITY 50$: MOV #IE.IFC&377,R0 ; RETURN ERROR CODE ; PJC038 JMP 400$ ; EXIT ; PJC038 60$: ; REF LABEL ; PJC038 ; ;**-3 ; SET UP MAPPING AND FIRST DISK ADDRESS ; .IF DF M$$EXT&M$$MGE CALL $STMAP ; SET UP 11/70 UNIBUS MAPPING ADDRS .ENDC .IF DF M$$MGE SWAB U.BUF(R5) ; POSITION EXTENDED MEMORY BITS .ENDC MOV I.PRM+12(R1),R0 ; GET PHYSICAL OR LOGICAL BLOCK NUMBER  BITB #IO.RPB&377,I.FCN(R1) ; IS IT READ/WRITE PHYSICAL? BNE 70$ ; IF NE YES ; PJC038 ASL R0 ; CONVERT TO LOGICAL SECTOR NO. (LBN*2) ;**-1 BIT #DEN,U.CW2(R5) ; DOUBLE DENSITY? BNE 70$ ; IF NE YES ; PJC038 ASL R0 ; SINGLE DEN - LBN*4 ;**-1 70$: MOV R0,I.PRM+10(R1) ; STORE IT ; PJC038 80$: MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS ; PJC038 CALL TRKSEC ; CONVERT BLOCK # TO TRACK/SECTOR ;**-2 BCS 20$ ; IF CS, BAD BLOCK ERROR ; PJC038 MOV S.CSR(R4),R2 ; GET ADDRESS OF CSR ;**-1 CMPB #IO.WLB/256.,I.FCN+1(R3) ; WRITE FUNCTION? BNE 190$ ; IF NE NO ; PJC038 ; ;**-1 ; FILL SILO BEFORE WRITE ; MOVB #FILL,U.BUF(R5) ; SET FILL SILO FUNCTION 90$: BIT #DEN,U.CW2(R5) ; DOUBLE DENSITY? ; PJC038 BEQ 100$ ; IF EQ NO ; PJC038 BIS #SDEN,U.BUF(R5) ; YES-SET DOUBLE DENSITY BIT ;**-2 100$: BIS #SILO,U.CW2(R5) ; SILO FUNCTION FLAG ; PJC038 MOV U.BUF(R5),(R2) ; INITIATE FUNCTION ;**-1 .IF DF M$$MGE&M$$EXT MOV R2,-(SP) ; SAVE REGISTER CALL $MPUBM ; MAP 11/70 UNIBUS TO TRANSFER MOV (SP)+,R2 ; RESTORE REGISTER .ENDC MOV U.BUF+2(R5),R0 ; GET BUFFER ADDRESS MOV #128.,R1 ; DEFAULT TO A 128. BYTE TRANSFER BIT #DEN,U.CW2(R5) ; DOUBLE DENSITY DISKETTE? BEQ 110$ ; IF EQ NO ; PJC038 ASL R1 ; CHANGE DEFAULT TO 256. BYTES ;**-1 110$: CMP U.CNT(R5),R1 ; FULL TRANSFER LEFT? ; PJC038 BHIS 120$ ; IF HIS YES ; PJC038 MOV U.CNT(R5),R1 ; NO, GET RESIDUAL COUNT ;**-2 120$: MOV R1,I.PRM+12(R3) ; STORE BYTES BEING TRANSFERRED ; PJC038 130$: BITB #TR!DONE,(R2) ; TRANSFERRED? ; PJC038 BMI 140$ ; IF MI YES ; PJC038 BEQ 130$ ; IF EQ LOOP ; PJC038 BR 160$ ; ERROR ; PJC038 140$: ASR R1 ; WORD COUNT ; PJC038 MOV R1,RXDB(R2) ; LOAD WORD COUNT ;**-6 150$: BITB #TR!DONE,(R2) ; TRANSFERRED? ; DS010 BMI 162$ ; IF MI YES - R0 HAS BUFFER ADRS ; DS010 BEQ 150$ ; IF EQ LOOP ; DS010 160$: MOV S.PKT(R4),R3 ; GET IO PKT ADDRESS ; DS010 MOV RXES(R2),I.PRM+6(R3); SAVE RXES IN SAVE WORD ; DS010 161$: JMP DYRTY ; RETRY ; DS010 162$: MOV S.PKT(R4),R3 ; GET IO PKT ADDRESS ; DS010 BR 270$ ; DS010 ; ;**-5 ; EMPTY SILO AFTER READ ; 170$: MOVB #EMPTY,U.BUF(R5) ; SET EMPTY SILO FUNCTION ; PJC038 BR 90$ ; SAME AS FILL SILO ; PJC038 ; ;**-2 ; INITIATE TRANSFER BETWEEN SILO AND DISK ; 180$: MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS ; PJC038 MOV S.CSR(R4),R2 ; GET CSR ADDR ;**-1 MOVB #WRITE,U.BUF(R5);ASSUME WRITE FUNCTION MOV I.FCN(R3),R1 ; GET FUNCTION CODE  BIC #7,R1 ; REMOVE QUALIFIER BITS CMP #IO.WDD,R1 ; WRITE WITH DELETED DATA? BNE 200$ ; IF NE NO ; PJC038 MOVB #WRTDD,U.BUF(R5) ; SET "WRITE DELETED DATA" FUNCTION ;**-1 BR 200$ ; SKIP ; PJC038 190$: MOVB #READ,U.BUF(R5) ; SET READ FUNCTION ; PJC038 200$: BIT #DEN,U.CW2(R5) ; DOUBLE DENSITY? ; PJC038 BEQ 210$ ; IF EQ NO ; PJC038 BIS #SDEN,U.BUF(R5) ; YES-SET DENSITY BIT ;**-4 210$: TSTB U.UNIT(R5) ; UNIT 1? ; PJC038 BEQ 220$ ; IF EQ NO ; PJC038 BIS #UNIT,U.BUF(R5) ; YES, SET TO SELECT UNIT 1 ;**-2 220$: ; REF LABEL ; PJC038 ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 MOVB S.CON(R4),R1 ; RETRIEVE CONTROLLER INDEX ; PJC037 MOV U.BUF(R5),CSRSV(R1) ; SAVE FUNCTION CODE ; PJC037 ; PJC037 .ENDC ; PJC037 ; PJC037 ; PJC037 MOV U.BUF(R5),(R2) ; INITIATE FUNCTION ; PJC037 230$: BITB #TR!DONE,(R2) ; TRANSFER READY OR DONE? ; PJC038 BMI 240$ ; IF MI, TRANSFER READY ; PJC038 BEQ 230$ ; IF EQ LOOP ; PJC038 240$: MOVB I.PRM+14(R3),RXDB(R2) ; LOAD SECTOR NUMBER ; PJC038 250$: BITB #TR!DONE,(R2) ; TRANSFER READY OR DONE? ; PJC038 BMI 260$ ; IF MI, TRANSFER READY ; PJC038 BEQ 250$ ; IF EQ LOOP ; PJC038 BR 160$ ; ERROR ; PJC038 260$: MOVB I.PRM+15(R3),R0 ; LOAD TRACK NUMBER IN R0 ; PJC038 270$: MOVB S.ITM(R4),S.CTM(R4) ; SET TIMEOUT COUNT ; PJC038 280$: MOV R0,RXDB(R2) ; LOAD TRACK, BUFFER ADDRESS OR ASCII I ; PJC038 ; ;**-26 ; DYPWF - POWER FAIL ENTRY POINT ; POWER FAIL IS HANDLED BY THE DEVICE TIMING OUT, THEREFORE ; NO WORK IS DONE HERE. IT WILL BE HANDLED WHEN THE DEVICE ; TIME OUT ENTRY IS EXECUTED. ; DYPWF: ;;; ; PJC038 ; ; DYCAN - CANCEL I/O ENTRY POINT ; CANCEL I/O IS A NOP OP FOR FILE STRUCTURED DEVICES ; DYCAN: RETURN ;;; ;**-1 ;+ ; *** - $DYINT - RX11 FLOPPY DISK INTERRUPT ENTRY POINT ; ;- INTSE$ DY,PR5,R$$X21 ;;; GENERATE INTERRUPT SAVE CODE MOV R3,-(SP) ;;; SAVE REGISTER MOV U.SCB(R5),R4 ;;; GET SCB ADDRESS MOV S.PKT(R4),R3 ;;; GET I/O PACKET ADDRESS MOV S.CSR(R4),R4 ;;; GET CSR ADDRESS MOV RXDB(R4),I.PRM+6(R3) ;;; SAVE CONTROLLER STATUS MOV (SP)+,R3 ;;; RESTORE REGISTER CLR (R4) ;;; DISABLE INTERRUPTS CALL $FORK ;;; CREATE A SYSTEM PROCESS MOV R4,R2 ; COPY CSR ADDRESS MOV U.SCB(R5),R4 ; GET SCB ADDRESS MOVB S.CON(R4),R3 ; GET CONTROLLER INDEX TSTB RTTBL(R3) ; RETRIES ZERO ; DS010 BNE 281$ ; IF NE NO ; DS010 BIT #RSAE,U.CW2(R5) ; READ STATUS AFTER ERROR ; DS010 BNE 281$ ; IF NE YES ; DS010 JMP DYINI ; TREAT AS SPURIOUS ; DS010 281$: BIT #SCHAR,U.CW2(R5); SENSE CHARACTERICS ; DS010 BNE DYSEN ; IF NE YES ;**-1 TST (R2) ; ANY ERRORS? BPL 290$ ; IF PL, NO ERRORS ; PJC038 ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 CALL LOGERR ; LOG DEVICE ERROR ; PJC037 ; PJC037 .ENDC ; PJC037 ; PJC037 ; PJC037 JMP DYRTY ; RETRY FUNCTION ; PJC037 290$: ASRB RTTBL+1(R3) ; INITIALIZE IN PROGRESS? ; PJC038 BCS 350$ ; IF CS YES ; PJC038 MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS ;**-4 CMP #IO.SMD,I.FCN(R3) ; SET MEDIA DENSITY? BNE 300$ ; IF NE NO ; PJC038 JMP 390$ ; YES, FINISH I/O ; PJC038 300$: CMPB #IO.RLB/256.,I.FCN+1(R3) ; READ? ; PJC038 BNE 330$ ; IF NE NO ; PJC038 TST U.CW2(R5) ; SILO FUNCTION? ;**-4 BMI 320$ ; IF MI YES ; PJC038 BITB #DELDAT,I.PRM+6(R3) ; DELETED DATA READ? ; PJC014 BEQ 310$ ; IF EQ NO ; PJC038 BISB #DELDAT,U.CW2(R5) ; YES ; PJC014 310$: JMP 170$ ; GO EMPTY SILO ; PJC038 320$: BIC #SILO,U.CW2(R5) ; CLEAR SILO BIT ; PJC038 CALL NXTSEC ; UPDATE TO NEXT SECTOR ;**-3 BEQ 380$ ; IF EQ, ALL FINISHED ; PJC038 BR 350$ ; INITIATE NEXT READ ; PJC038 330$: TST U.CW2(R5) ; FILL SILO FUNCTION? ; PJC038 BPL 340$ ; IF PL NO ; PJC038 BIC #SILO,U.CW2(R5) ; YES - CLEAR SILO BIT ;**-4 JMP 180$ ; GO WRITE SECTOR ; PJC038 340$: CALL NXTSEC ; UPDATE TO NEXT SECTOR ; PJC038 BEQ 390$ ; IF EQ, ALL FINISHED ; PJC038 350$: BIC #ERR1,U.CW2(R5) ; CLEAR TIMEOUT ERROR BIT ; DS010 MOV S.PKT(R4),R3 ; GET IO PACKET ADR ; DS010 CMP #IO.SMD,I.FCN(R3); IO.SMD FUNC ; DS010 BNE 351$ ; IF NE NO ; DS010 JMP DYSMD ; RETRY FUNC ; DS010 351$: JMP 80$ ; RETRY CURRENT OPERATION NOW ; PJC038 360$: MOV #IE.BLK&377,R0 ; SET BAD BLOCK ERROR ; PJC038 BR 420$ ; ; PJC038 370$: MOV #IE.VER&377,R0 ; SET UNRECOVERABLE ERROR ; PJC038 BR 400$ ; ; PJC038 380$: MOV I.FCN(R3),R1 ; GET FUNCTION CODE ; PJC038 BIC #7,R1 ; REMOVE QUAILFIER BITS ;**-10 CMP #IO.RPB,R1 ; READ PHYSICAL BLOCK? BNE 390$ ; IF NE NO ; PJC038 BITB #DELDAT,U.CW2(R5) ; DELETED DATA READ? ; PJC014 BEQ 390$ ; IF EQ NO ; PJC038 BICB #DELDAT,U.CW2(R5) ; YES ; PJC014 MOV #IS.RDD&377,R0 ; READ DELETED DATA ; PJC038 BR 400$ ; ; PJC038 390$: MOV #IS.SUC&377,R0 ; SET SUCCESSFUL COMPLETION ; PJC038 400$: MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS ; PJC038 MOV I.PRM+4(R1),R1 ; SET BYTES TRANSFERED ;**-6 SUB U.CNT(R5),R1 ; CALCULATE BYTES ACTUALLY TRANSFERED 410$: ; PJC038 ;**-1 .IF DF E$$DVC MOVB S.CON(R4),R3 ; RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ; SET FINAL RETRY COUNT MOV R1,-(SP) ; SAVE R1 ; DS010 MOV S.PKT(R4),R1 ; GET IO PKT ADDRESS ; DS010 CMPB #IO.SEC,I.FCN+1(R1); IO.SEC OR IO.SMD FUNC'S ; DS010 BNE 411$ ; IF NE NO ; DS010 BIS #4*256.,R2 ; SET INIT RETRY COUNT IO.SEC/SMD'S ; DS010 BR 412$ ; DS010 411$: BIS #RETRY*256.,R2 ; SET INIT RETRY COU T FOR READ WRITE FU; DS010 412$: MOV (SP)+,R1 ; RESTORE R1 ; DS010 .ENDC ;**-2 420$: BIC #SILO!SCHAR!ERR1,U.CW2(R5) ; CLEAR ALL BUT DENSITY BITS ; PJC038 CALL $IODON ; SET DONE ;**-2 JMP DYINI ; TRY FOR ANOTHER REQUEST ; ; INTERRUPT PROCESSING POINT FOR DETERMINING THE ; DISKETTE UNIT STATUS. ; DYSEN: MOV S.PKT(R4),R1 ; RETRIEVE I/O PACKET ADDRESS ; PJC007 BIT #RSAE,U.CW2(R5) ; READ STATUS AFTER ERROR? ; PJC009 BEQ 430$ ; IF EQ NO ; PJC038 BIC #RSAE,U.CW2(R5) ; CLEAR FLAG ; PJC009 JMP 590$ ; GO DETERMINE ERROR TYPE ; PJC038 430$: ASRB RTTBL+1(R3) ; INIT IN PROGRESS ; DS010 BCC 431$ ; IF CC NO ; DS010 BIT #RXACLO,I.PRM+6(R1); AC LOW ; DS010 BEQ DYSEC ; IF EQ NO - RETRY IO.SEC ; DS010 JMP 590$ ; EXIT ; DS010 431$: BIT #DRVRDY,I.PRM+6(R1) ; DRIVE READY? ; DS010 BEQ DYRTY ; IF EQ NO ; PJC010 TST (R2) ; ANY ERRORS ? ;**-1 BPL 440$ ; IF PL NO ; PJC038 BIT #DENERR,I.PRM+6(R1) ; IS IT A DENSITY ERROR? ; PJC007 BEQ DYRTY ; IF EQ NO ;**-2 440$: BIC #SCHAR!DEN,U.CW2(R5) ; CLEAR FLAGS ; PJC038 MOV #SINGLE,U.CW3(R5) ; ASSUME SINGLE DENSITY ; PJC038 BIT #DRVDEN,I.PRM+6(R1) ; IS IT DOUBLE DENSITY? ; PJC007 BEQ 450$ ; IF EQ NO ; PJC038 ASL U.CW3(R5) ; DOUBLE THE MAXIMUM LBN'S ;**-4 BIS #DEN,U.CW2(R5) ; SET THE DENSITY BIT 450$: MOV #IS.SUC&377,R0 ; SET SUCCESS ; PJC038 MOV U.CW2(R5),R1 ; RETURN DEVICE CHARACTERISTICS ;**-5  BR 410$ ; ; PJC038 ; ;**-1 ; SENSE CHARACTERISTIC PROCESSING ; DYSEC: BIS #SCHAR,U.CW2(R5) ; INDICATE SENSE CHARACTERISTIC MOV #MRDS,R0 ; SET MAINTENANCE READ STATUS TSTB U.UNIT(R5) ; UNIT 1 ? BEQ 460$ ; IF EQ NO ; PJC038 BIS #UNIT,R0 ; YES SELECT UNIT 1 ;**-1 460$: MOV R0,(R2) ; INITIATE FUNCTION ; PJC038 MOVB S.ITM(R4),S.CTM(R4) ; SET TIMEOUT COUNT ;**-1 RETURN ; ;**-9 ; ; SET MEDIA DENSITY ; DYSMD: MOV #SETDEN,R0 ; SET FUNCTION CODE BIC #DEN,U.CW2(R5) ; CLEAR FLAG MOV #SINGLE,U.CW3(R5) ; ASSUME SINGLE DENSITY ; PJC038 TST I.PRM(R1) ; SINGLE DENSITY? ;**-1 BEQ 470$ ; IF EQ YES ; PJC038 CMP #2,I.PRM(R1) ; DOUBLE DENSITY? ;**-1 BNE 470$ ; IF NE NO, TREAT AS SINGLE DENSITY ; PJC038 BIS #SDEN,R0 ; DOUBLE DENSITY ;**-1 BIS #DEN,U.CW2(R5) ; UPDATE STATUS ASL U.CW3(R5) ; DOUBLE MAXIMUM LBN'S 470$: TSTB U.UNIT(R5) ; UNIT 1? ; PJC038 BEQ 480$ ; IF EQ NO ; PJC038 BIS #UNIT,R0 ; YES SELECT UNIT 1 ;**-2 480$: MOV R0,(R2)  ; INITIATE FUNCTION ; PJC038 MOV S.PKT(R4),R3 ; GET IO PKT ADR ; DS010 490$: BITB #TR!DONE,(R2) ; TRANSFERRED? ; DS010 BMI 500$ ; IF MI YES ; DS010 BEQ 490$ ; IF EQ LOOP ; DS010 JMP 160$ ; SAVE STATUS REG AND RETRY ; DS010 500$: MOV #'I,R0 ; ASCII "I" ; PJC038 MOVB #30.,S.CTM(R4) ; TIMEOUT COUNT ;**-8 JMP 280$ ; ; PJC038 ;**-1 ;+ ; **-DYOUT-FLOPPY DISK TIMEOUT ENTRY POINT ;- DYOUT: BIS #ERR1,U.CW2(R5) ;;; TIMEOUT ENTRY POINT ; PJC037 ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 CALL LOGTMO ;;; LOG DEVICE TIMEOUT ; PJC037 ; PJC037 .ENDC ; PJC037 ; PJC037 ; PJC037 DYRTY: MOVB S.CON(R4),R3 ; RESTORE CONTROLLER INDEX ; PJC037 MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS ;**-18 BITB #RSAE,U.CW2(R5) ; READ STATUS AFTER ERROR? ; DS010 BNE 600$ ; IF NE YES ; DS010 BITB #IQ.X,I.FCN(R1) ; INHIBIT RETRIES ? BEQ 510$ ; IF EQ NO ; PJC038 CMP #IO.SEC,I.FCN(R1); IO.SEC FUNC ; DS010 BEQ 590$ ; IF EQ YES ; DS010 BIS #RSAE,U.CW2(R5) ; SET READ STATUS AFTER ERROR FLAG ; PJC009 JMP DYSEC ; GO DO READ STATUS ; PJC009 510$: DECB RTTBL(R3) ; ANY RETRIES LEFT? ; PJC038 BNE 520$ ; IF NE YES ; PJC038 CMP #IO.SEC,I.FCN(R1); DONT'T REPEAT IO.SEC ; DS010 BEQ 590$ ; IF EQ EXIT ; DS010 BIS #RSAE,U.CW2(R5) ; SET READ STATUS AFTER ERROR FLAG ; PJC009 JMP DYSEC ; GO DO READ STATUS ; PJC009 520$: BIT #ERR1,U.CW2(R5) ; TIMEOUT ERROR? ; PJC038 BNE 580$ ; IF NE YES ; PJC038 ASRB RTTBL+1(R3) ; INIT IN PROGRESS ; DS010 BCC 530$ ; IF CC NO ; DS010 BIT #RXACLO,I.PRM+6(R1); AC LOW ; DS010 BNE 590$ ; IF NE YES - EXIT ; DS010 530$: BIT #SCHAR,U.CW2(R3); SENCE CHARACTERICS ; DS010 BNE 580$ ; IF NE YES ; DS010 CMP #IO.SMD,I.FCN(R1); SET MEDIA DENSITY ; DS010 BEQ 580$ ; IF EQ YES ; DS010 BIT #CRCERR,I.PRM+6(R1); CRC ERROR ; DS010 BNE 570$ ; IF NE YES ; PJC038 540$: MOV I.PRM+10(R1),R0 ; GET LOGICAL SECTOR NUMBER ; PJC038 BIT #WCOVFL!DENERR,I.PRM+6(R1) ; WORD COUNT OVERFLOW OR ;**-11 ; DENSITY ERROR ? BEQ 580$ ; IF EQ NO ; PJC038 BIT #DRVDEN,I.PRM+6(R1) ; IS IT DOUBLE DENSITY ? ;**-1 BNE 550$ ; IF NE YES ; PJC038 BIC #DEN,U.CW2(R5) ; CORRECT IT TO SINGLE DENSITY ;**-1 BIC #SDEN,U.BUF(R5) ; HERE TOO ; PJC022 ASL R0 ; MULTIPLY LSN BY 2 MOV #SINGLE,U.CW3(R5) ; CHANGE MAX LBN'S TO SINGLE DENSITY ; PJC038 BR 560$ ; ; PJC038 550$: BIS #DEN,U.CW2(R5) ; CHANGE TO DOUBLE DENSITY ; PJC038 ASR R0 ; DIVIDE LSN BY 2 ;**-4 MOV #DOUBLE,U.CW3(R5) ; CHANGE MAX LBN'S TO DOUBLE DENSITY ; PJC038 560$: MOV R0,I.PRM+10(R1) ; STORE LOGICAL SECTOR NUMBER ; PJC038 570$: BIC #ERR1,U.CW2(R5) ; CLEAR TIMEOUT ERROR ; PJC038 JMP 80$ ; RETRY FUNCTION ; PJC038 580$: BIC #ERR1,U.CW2(R5) ; CLR TIMEOUT ERROR ; PJC038 MOVB #1,RTTBL+1(R3) ; SET INITIALIZE IN PROGRESS ; PJC038 ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 MOV #INIT!INTEBL,CSRSV(R3) ; SAVE FUNCTION CODE ; PJC037 ; PJC037 .ENDC ; PJC037 ; PJC037 ; PJC037 MOV #INIT!INTEBL,(R2) ; INITIALIZE RX211 DRIVES ;**-10 MOVB S.ITM(R4),S.CTM(R4) ; SET TIMEOUT COUNTER RETURN ; 590$: BIT #DRVRDY,I.PRM+6(R1) ; DRIVE READY? ; PJC038 BEQ 600$ ; IF EQ NO ; PJC038 JMP 370$ ; EXIT WITH IE.VER ; PJC038 600$: MOV #IE.DNR&377,R0 ; SET DEVICE NOT READY ERROR ; PJC038 JMP 400$ ; EXIT WITH IE.DNR ; PJC038 .DSABL LSB ;**-7 ; PJC037 ; PJC037 .IF DF E$$DVC ; PJC037 ; PJC037 ; ; PJC037 ; **LOGERR-LOG DEVICE ERROR ; PJC037 ; **LOGTM0-LOG TIMEOUT ERROR ; PJC037 ; ; PJC037 ; THESE ROUTINES ARE CALLED IN THE CASE OF EITHER A DEVICE ERROR ; PJC037 ; OR TIMEOUT ERROR. WE WILL ALLOCATE A CORE BLOCK, FILL IT WITH ; PJC037 ; THE APPROPRIATE REGISTER INFORMATION, CALL THE EXECUTIVE ; PJC037 ; ERROR LOGGING ROUTINE, DEALLOCATE THE CORE BLOCK, AND RETURN  ; PJC037 ; BACK TO THE CALLER. ; PJC037 ; ; PJC037 ; INPUT: ; PJC037 ; R3 = CONTROLLER INDEX ; PJC037 ; R4 = SCB ADDRESS ; PJC037 ; R5 = UCB ADDRESS ; PJC037 ; ; PJC037 ; OUTPUT: ; PJC037 ; R2 = CSR ADDRESS ; PJC037 ; R4 = SCB ADDRESS ; PJC037 ; R5 = UCB ADDRESS ; PJC037 ; ; PJC037 ; R0, R1 AND R3 ARE DESTROYED. ; PJC037 ; ; PJC037 .ENABL LSB ; PJC037 LOGERR: MOV #$DVERR,-(SP) ; LOG DEVICE ERROR ; PJC037 BR 10$ ; ; PJC037 LOGTMO: MOV #$DTOER,-(SP) ;;; LOG TIMEOUT ERROR ; PJC037 10$: MOV #DYNUM*2,R1 ; NUMBER OF BYTES TO ALLOCATE ; PJC037 CALL $ALOCB ; ALLOCATE THE ERROR BLOCK ; PJC037 BCC 20$ ; IF CC OK ; PJC037 INC $ERRSQ ; INDICATE A MISSED ERROR ; PJC037 CMP (SP)+,#$DTOER ; TIMEOUT? ; PJC037 BNE 80$ ; IF NE NO ; PJC037 BIC #INTEBL,@S.CSR(R4) ;;; CLEAR INTERRUPT ENABLE ; PJC037 MTPS #0 ;;; ALLOW INTERRUPTS ; PJC037 20$: MOV R0,R1 ; COPY CORE BLOCK ADDRESS ; PJC037 MOV S.CSR(R4),R2 ; RETRIEVE CSR ADDRESS ; PJC037 MOV (R2),(R1) ; SAVE CSR CONTENTS ; PJC037 BIC #^C<17>,CSRSV(R3) ; ISOLATE BITS 0-4 ; PJC037 BIS CSRSV(R3),(R1)+ ; INCLUDE FUNCTION CODE ; PJC037 MOV RXDB(R2),(R1)+ ; SAVE RXDB ; PJC037 MOV #17,(R2) ; EXECUTE READ ERROR CODE FUNCTION ; PJC037 30$: MOV #5,R3 ; SET UP LOOP COUNT ; PJC037 40$: BIT #TR,(R2) ; TRANSFER REQUEST? ; PJC037 BNE 60$ ; IF NE YES ; PJC037 BMI 50$ ; IF MI ERROR ; PJC037 DEC R3 ; IF EQ, DECREMENT LOOP COUNT ; PJC037 BEQ 50$ ; TIMED OUT ; PJC037 BR 40$ ; KEEP CHECKING ; PJC037 50$: ; REF LABEL ; PJC037 ; PJC037 .REPT 4 ; PJC037 ; PJC037 CLR (R1)+ ; ZERO 4 WORDS WHEN ERROR ON RDERC ; PJC037 ; PJC037 .ENDR ; PJC037 ; PJC037 BR 70$ ; SKIP REST OF RDERC FUNCTION ; PJC037 60$: MOV R1,RXDB(R2) ; GIVE ADRS TO FILL WITH ERROR STATUS ; PJC037 BITB #DONE,(R2) ; DONE? ; PJC037 BEQ 60$ ; IF EQ NO ; PJC037 70$: MOV R0,S.CSR(R4) ; FAKE CSR ADRS WITH ERROR BLOCK ADRS ; PJC037 CALL @(SP)+ ; LOG THE ERROR ; PJC037 MOV R2,S.CSR(R4) ; RESTORE THE CSR ADRS IN SCB ; PJC037 MOV #DYNUM*2,R1 ; NUMBER OF BYTES TO DEALLOCATE ; PJC037 CALL $DEACB ; DEALLOCATE THE ERROR BLOCK ; PJC037 80$: MOV S.CSR(R4),R2 ; RETRIEVE CSR ADDRESS ; PJC037 RETURN ; ; PJC037 .DSABL LSB ; PJC037 ; PJC037 .ENDC ;E$$DVC ; PJC037 ; PJC037 ;+ ; *** - TRKSEC - CONVERT LOGICAL OR PHYSICAL BLOCK NUMBER TO ; TRACK-SECTOR PAIR ; ; INPUT: ; R3 - I/O PACKET ADDRESS ; I.PRM+10(R3) - LOGICAL OR PHYSICAL SECTOR ; ; OUTPUT: ; I.PRM+14(R3) - SECTOR (1-26.) ; I.PRM+15(R3) - TRACK (0-76.) ; R3 - UNCHANGED ; C CLEAR - VALID BLOCK ; C SET - BAD BLOCK NUMBER (PHYSICAL OR LOGICAL) ; ;- TRKSEC: MOV I.PRM+10(R3),R1 ; GET LOGICAL OR PHYSICAL BLOCK MOV #8.,R0 ; SET LOOP COUNT MOV #6400,R2 ; SET DIVISOR 10$: CMP R2,R1 ; DOES 26 GO INTO DIVIDEND? ; PJC038 BHI 20$ ; IF HI NO (C=0) ; PJC038 SUB R2,R1 ; SUBTRACT 26 FROM DIVIDEND ;**-2 SEC ; SET CARRY 20$: ROL R1 ; SHIFT DIVIDEND AND QUOTIENT ; PJC038 DEC R0 ; DONE? ;**-1 BGT 10$ ; IF GT NO ; PJC038 BISB R1,R0 ; GET TRACK NUMBER ; PJC012 CMP R0,#77. ; IS IT A LEGITIMATE TRACK NUMBER? ; PJC006 BHI 60$ ; IF HI NO ; PJC038 BLO 30$ ; IF LO YES ; PJC038 BITB #IO.RPB&377,I.FCN(R3) ; PHYSICAL BLOCK FUNCTION? ; PJC006 BEQ 60$ ; IF EQ NO, BAD BLOCK ERROR ; PJC038 30$: CLRB R1 ; CLEAR TRACK NUMBER ; PJC038 SWAB R1 ; SHIFT DONE SECTOR NUMBER ;**-15 BITB #IO.RPB&377,I.FCN(R3) ; IS IT A PHYSICAL BLOCK NUMBER? BNE 50$ ; IF NE YES ; PJC038 CMP #12.,R1 ; NO, C=1 IF 13<=R1<=25 ;**-1 ROL R1 ; DOUBLE FOR INTERLEAVE FACTOR ASL R0 ; ADD TRACK -TRACK SKEW ADD R0,R1 ; SKEW BY 2*TRACK ADD R0,R1 ; SKEW BY 4*TRACK ADD R0,R1 ; SKEW BY 6*TRACK ASR R0 ; RESTORE TRACK NUMBER MOV #26.,R2 ; SET MODULUS 40$: SUB R2,R1 ; MODULO SECTOR INTO RANGE -26. TO -1. ; PJC038 BGE 40$ ; IF GE, LOOP UNTIL NEGATIVE ; PJC038 ADD R2,R1 ; CONVERT TO RANGE 0-25. ;**-2 INC R0 ; LBN0 STARTS ON TRACK 1 50$: INC R1 ; CONVERT TO RANGE 1-26. ; PJC038 MOV R1,I.PRM+14(R3) ; SAVE SECTOR NUMBER ;**-1 BR 70$ ; ; PJC038 60$: SEC ; SIGNAL BAD BLOCK ERROR ; PJC038 MOVB R0,I.PRM+15(R3) ; SAVE TRACK NUMBER ;**-2 BR 80$ ; ; PJC038 70$: MOVB R0,I.PRM+15(R3) ; SAVE TRACK NUMBER ; PJC038 CMP #77.*256.,I.PRM+14(R3) ; IS IT A VALID TRACK/SECTOR? ;**-2 80$: RETURN  ; ; PJC038 ;**-1 ;+ ; *** - NXTSEC - UPDATE BLOCK NUMBER , BUFFER ADDRESS ; AND BUFFER POINTER ; ; INPUT: ; R3 - I/O PACKET ADDRESS ; R5 - UCB ADDRESS ; I.PRM+10(R3) - CURRENT BLOCK NUMBER ; I.PRM+12(R3) - BYTES TRANSFERED DURING LAST FUNCTION ; U.CNT(R5) - BYTES LEFT TO TRANSFER ; U.BUF(R5) - BUFFER ADDRESS ; ; OUTPUT: ; I.PRM+10(R3) - UPDATED BLOCK NUMBER ; U.BUF(R5) - UPDATED BY 128./256. BYTES ; U.CNT(R5) - UPDATED BY NUMBER OF WORDS TRANSFERED ; Z SET - ALL BYTES TRANSFERED ; Z CLEAR - MORE BYTES TO TRANSFER ; C CLEAR - VALID TRACK/SECTOR ; C SET - BAD BLOCK NUMBER ; ;+ NXTSEC: INC I.PRM+10(R3) ; UPDATE BLOCK NUMBER BIT #DEN,U.CW2(R5) ; SINGLE DENSITY? ; RP025 BEQ 5$ ; IF EQ YES ; RP025 ADD #256.,U.BUF+2(R5) ; UPDATE BUFFER ADDRESS FOR DOUBLE DE; RP025 BR 10$ ; AND CONTINUE ; RP025 5$: ADD #128.,U.BUF+2(R5) ; UPDATE BUFFER ADDRESS FOR SINGLE DE; RP025 10$: BCC 15$ ; IF CC, NO OVERFLOW ; RP025 ;**-5 .IF DF M$$MGE ADD #š10000,U.BUF(R5) ; CARRY INTO EXTENDED MEMORY BITS .ENDC 15$: SUB I.PRM+12(R3),U.CNT(R5) ; UPDATE BYTES LEFT TO TRANSFER RETURN ; .END š×0 kQ ›c, .TITLE DRGEF .IDENT /02.10/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 02.10 ; ; J. E. PROVINO 21-SEP-78 ; ; FOR RSX-11M: CHUCK SPITZ 8-DEC-78 ; ; MODIFIED BY: ; ; M. S. HARVEY 15-AUG-79 ; MSH049 -- DON'T RETURN DIRECTIVE STATUS FROM $GTGEF. ; ALSO, CLEAN UP $DRCRE CODE. ; ; M. S. HARVEY 30-SEP-79  ; MSH045 -- MOVE COMMONLY USED SUBROUTINES TO DRSUB ; ; M. S. HARVEY 11-FEB-81 ; MSH148 -- ADD LOCK/UNLOCK GROUP GLOBAL CONTROL ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; GROUP GLOBAL EVENT FLAG ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,TCBDF$,HDRDF$,PCBDF$ PKTDF$ ;DEFINE GROUP GLOBAL OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS ;+ ; **-$DRCRE-CREATE GROUP GLOBAL EVENT FLAGS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CREATE GROUP GLOBAL EVENT ; FLAGS FOR A SPECIFIED GROUP. IF THE SPECIFIED GROUP MATCHES THE ;MSH148 ; TASK'S OWN GROUP, THE EVENT FLAG USE COUNT IS INCREMENTED, EFFECTING ;MSH148 ; A 'LOCK' OPERATION FOR THE FLAGS WHICH PREVENTS PREMATURE ELIMINATION ;MSH148 ; OF THE FLAGS BY A TASK THAT SHARES THEM. ;MSH148 ; ;MSH148 ; IF THE EVENT FLAGS ALREADY EXIST, THE SPECIFIED GROUP IS EQUAL TO ;MSH148 ; THE TASK'S OWN GROUP, AND THE EVENT FLAGS ARE UNLOCKED, THIS ;MSH148 ; DIRECTIVE WILL LOCK THE EVENT FLAGS FOR THE ISSUING TASK. ;MSH148 ; ;**-1 ; DPB FORMAT: ; ; WD. 00 -- DIC(157.),DPB SIZE(2.). ; WD. 01 -- GROUP NUMBER ; ; INPUTS: ; ; R2=ADDRESS OF SECOND STATUS WORD OF CURRENT TASK ; R3=POINTER TO WD. 1 IN THE DPB ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IF ALLOCATION FAILURE. ; DIRECTIVE STATUS OF 'D.RS16' IF NON-PRIVILEGED TASK ; ATTEMPTS TO CREATE EVENT FLAGS FOR ANOTHER GROUP. ; DIRECTIVE STATUS OF 'D.RS17' IS RETURNED IF GROUP GLOBAL ; EVENT FLAGS ALREADY EXIST. ; DIRECTIVE STATUS OF 'D.RS91' IS RETURNED IF GROUP IS ; INVALID. ;- .IF DF G$$EFN .ENABL LSB $DRCRE::CALL 300$ ;DO FLAGS ALREADY EXIST? ;MSH148 BCC 40$ ;IF CC YES ;MSH148 MOV R0,-(SP) ;SAVE CONTROL BLOCK LIST POSITION ;MSH148 MOV #G.LGTH,R1 ;GET LENGTH OF GROUP GLOBAL CONTROL BLK ;MSH148 MOV R2,R3 ;COPY TASK'S GROUP NUMBER ;MSH148 CALL $ALOCB ;ALLOCATE A BLOCK FOR GROUP GLOBAL FLAGS;**-15 BCS 70$ ;IF CS ALLOCATION FAILURE MOV @(SP),(R0) ;POINT NEW BLOCK TO REMAINDER OF LIST ;MSH049 MOV R0,@(SP)+ ;LINK NEW BLOCK INTO LIST ;MSH049 TST (R0)+ ;POINT PAST LINK WORD (G.LNK) ;MSH049 MOVB R4,(R0)+ ;STORE GROUP NUMBER (G.GRP) ;MSH049 CLRB (R0)+ ;CLEAR STATUS BYTE (G.STAT) ;MSH049 CLR (R0)+ ;INITIALIZE ACCESS COUNT (G.CNT) ;MSH049 CMP R3,R4 ;ARE THESE FLAGS FOR THE TASK'S OWN GRP?;MSH148 BNE 20$ ;IF NE NO, DO NOT LOCK THEM ;MSH148 INC -2(R0) ;LOCK THE FLAGS IN POOL BY ACCESSING THE;MSH148 BIS #T3.GFL,(R5) ;MARK TCB AS HAVING THE FLAGS LOCKED ;MSH148 ;MSH148 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH148 INCB T.GGF-T.ST3(R5) ;RECORD THIS ACCESS ;MSH148 ;MSH148 .ENDC ;MSH148  ;MSH148 20$: CLR (R0)+ ;CLR FIRST EVENT FLAG WORD (G.EFLG) ;MSH148 CLR (R0) ;CLR SECOND EVENT FLAG WORD (G.EFLG+2) ;MSH049 30$: RETURN ; ;**-9 40$: CLRB G.STAT(R1) ;CLEAR MARKED FOR DELETE ;MSH148 CMP R2,R4 ;TASK'S OWN GROUP? ;MSH148 BNE 110$ ;IF NE NO ;MSH148 BIT #T3.GFL,(R5) ;ALREADY LOCKED? ;MSH148 BNE 110$ ;IF NE YES ;MSH148 BIS #T3.GFL,(R5) ;MARK TCB AS HAVING LOCKED EVENT FLAGS ;MSH148 INC G.CNT(R1) ;LOCK THESE EVENT FLAGS IN POOL ;MSH148 ;MSH148 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH148 INCB T.GGF-T.ST3(R5) ;RECORD ACCESS ;MSH148 ;MSH148 .ENDC ;MSH148 ;MSH148 BR 110$ ;INDICATE FLAGS ALREADY EXIST ;**-1 ;+ ; **-$DRELE-ELIMINATE/UNLOCK GROUP GLOBAL EVENT FLAGS FOR DIRECTIVE ;MSH148 ; **-$ELIM-ELIMINATE GROUP GLOBAL EVENT FLAGS FOR EXECUTIVE ;MSH148 ; ;**-1 ; THE ELIMINATE GROUP GLOBAL EVENT FLAGS DIRECTIVE ELIMINATES THE ;MSH148 ; GROUP GLOBAL EVENT FLAGS FOR A SPECIFIED GROUP. IF THE ISSUING ;MSH148 ; TASK HAD LOCKED THE EVENT FLAGS VIA A PREVIOUSLY ISSUED CREATE ;MSH148 ; GROUP GLOBAL EVENT FLAGS DIRECTIVE, THEY WILL ALSO BE UNLOCKED. ;MSH148 ; ;MSH148 ; THE UNLOCK GROUP GLOBAL EVENT FLAGS DIRECTIVE UNLOCKS THE EVENT ;MSH148 ; FLAGS FOR THE ISSUING TASK'S GROUP. ;MSH148 ; ;**-1 ; DPB FORMAT FOR THE ELIMINATE DIRECTIVE: ;MSH148 ; ;**-1 ; WD. 0 -- DIC. (159.),DBP SIZE(2.) ; WD. 1 -- GROUP NUMBER ; ;MSH148 ; DPB FORMAT FOR THE UNLOCK DIRECTIVE: ;MSH148 ; ;MSH148 ; WD. 0 -- DIC(159.),DPB SIZE(1.) ;MSH148 ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK ; R3=ADDRESS OF THE DBP + 2 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF NON-PRIVILEGED ; TASK ATTEMPTS TO ELIMINATE FLAGS FOR ANOTHER GROUP. ; DIRECTIVE STATUS OF 'D.RS17' IS RETURNED IF EVENT FLAG ; BLOCK IS ALREADY MARKED FOR DELETE, OR ;MSH148 ; ALREADY UNLOCKED. ;MSH148 ; DIRECTIVE STATUS OF 'D.RS91' IS RETURNED IF THE SPECIFIE;**-1 ; EVENT FLAG GROUP IS GREATER THAN 377. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF THE SPECIFIED ; EVENT FLAG GROUP DOES NOT EXIST. ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE ;MSH148 ; DPB SIZE IS ILLEGAL. ;MSH148 ;- $DRELE::MOVB -(R3),R0 ;GET DPB SIZE ;MSH148 CMPB (R3)+,#2 ;IS THIS THE ELIMINATE DIRECTIVE? ;MSH148 BEQ 50$ ;IF EQ YES ;MSH148 ASR R0 ;IS THIS THE UNLOCK DIRECTIVE? ;MSH148 BNE 120$ ;IF NE NO, ILLEGAL DPB SIZE ;MSH148 CALL $UNLCK ;ATTEMPT TO UNLOCK THE EVENT FLAGS ;MSH148 BCS 110$ ;IF CS ALREADY UNLOCKED ;MSH148 $ELIM:: BNE 45$ ;IF NE G.CNT<>0, DON'T ELIMINATE FLAGS ;MSH148 TSTB G.STAT(R1) ;MARKED FOR ELIMINATION? ;MSH148 BNE 65$ ;IF NE YES, ELIMINATE THE FLAGS ;MSH148 45$: RETURN ; ;MSH148 ;MSH148 50$: CALL 300$ ;LOOK FOR THE SPECIFIED EVENT FLAGS ;MSH148 BCS 100$ ;IF CS NOT FOUND ;**-12 CMP R2,R4 ;ELIMINATING TASK'S OWN GROUP? ;MSH148 BNE 60$ ;IF NE NO, DON'T UNLOCK THEM ;MSH148 BIT #T3.GFL,(R5) ;ARE THE EVENT FLAGS LOCKED? ;MSH148 BEQ 60$ ;IF EQ NO ;MSH148 BISB #GS.DEL,G.STAT(R1) ;MARK THE FLAGS FOR DELETION ;MSH148 CALL 200$ ;UNLOCK THE EVENT FLAGS ;MSH148 BEQ 65$ ;IF EQ G.CNT=0, ELIMINATE THE FLAGS ;MSH148 RETURN ;CAN'T ELIMINATE THEM WHILE STILL USED ;MSH148 ;MSH148 60$: TSTB G.STAT(R1) ;ALREADY MARKED FOR DELETE? ;MSH148 BNE 110$ ;IF NE YES ;**-1 ASSUME 1,GS.DEL ;MSH049 INCB G.STAT(R1) ;MARK IT FOR DELETE (GS.DEL) ;MSH049 TST G.CNT(R1) ;STILL BEING USED? ;**-1 BNE 210$ ;IF NE YES, DON'T ELIMINATE THEM YET ;MSH148 65$: CALLR $ELGEF ;ELIMINATE IT NOW ;MSH148 70$: DRSTS D.RS1 ;ALLOCATION FAILURE ;**-2 80$: DRSTS D.RS91 ;INVALID GROUP 90$: DRSTS D.RS16 ;PRIVILEGE VIOLATION 100$: DRSTS D.RS97 ;GROUP NOT FOUND 110$: DRSTS D.RS17 ;FLAGS ALREADY EXIST OR MARKED FOR DELETE 120$: DRSTS D.RS99 ;ILLEGAL DPB SIZE ;MSH148 ;MSH148 200$: BIC #T3.GFL,(R5) ;MARK TCB AS NOT HAVING LOCKED EFNS ;MSH148 ;MSH148 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH148 DECB T.GGF-T.ST3(R5) ;UNLOCK ;MSH148 ;MSH148 .ENDC ;MSH148 ;MSH148 DEC G.CNT(R1) ;UNLOCK THE EVENT FLAGS ;MSH148 210$: RETURN ; ;MSH148  ;MSH148 300$: ADD #T.ST3,R5 ;POINT TO THIRD STATUS WORD OF TCB ;MSH148 MOVB H.CUIC+1(R4),R2 ;GET TASK'S GROUP NUMBER ;MSH148 MOV (R3),R4 ;GET SPECIFIED GROUP NUMBER ;MSH148 BNE 310$ ;IF NE ONE WAS SPECIFIED ;MSH148 MOV R2,R4 ;ASSUME TASK'S OWN GROUP ;MSH148 BR 325$ ;JOIN COMMON CODE ;MSH148 310$: BIT #T3.PRV,(R5) ;ALLOWED TO SPECIFY ANY GROUP? ;MSH148 BNE 320$ ;IF NE YES ;MSH148 CMPB R4,R2 ;ATTEMPTING TO SPECIFY ANOTHER GROUP? ;MSH148 BNE 90$ ;IF NE YES ;MSH148 320$: CMP R4,#377 ;LEGAL GROUP NUMBER? ;MSH148 BHI 80$ ;IF HI NO ;MSH148 325$: CALLR $SRGEF ;TRY TO FIND THE GROUP'S CONTROL BLOCK ;MSH148 ;MSH148 ;+ ;MSH148 ; **-$UNLCK-UNLOCK GROUP GLOBAL EVENT FLAGS ;MSH148 ; ;MSH148 ; THIS ROUTINE WILL UNLOCK THE GROUP GLOBAL EVENT FLAGS FOR THE ;MSH148 ; TASK'S GROUP IF THE TASK HAS THEM LOCKED FROM A PREVIOUSLY ;MSH148 ; ISSUED CREATE GROUP GLOBAL EVENT FLAGS DIRECTIVE. ;MSH148 ; ;MSH148 ; INPUTS: ;MSH148 ; ;MSH148 ; R4=ADDRESS OF THE CURRENT TASK'S HEADER ;MSH148 ; R5=ADDRESS OF THE CURRENT TASK'S TCB ;MSH148 ; ;MSH148 ; OUTPUTS: ;MSH148 ; ;MSH148 ; C=1 IF THE EVENT FLAGS FOR THE TASK'S GROUP WERE NOT ;MSH148 ; LOCKED BY THE TASK ;MSH148 ; C=0 IF THE EVENT FLAGS ARE SUCCESSFULLY UNLOCKED. ;MSH148 ; ;MSH148 ; R4 IS DESTROYED BY THIS ROUTINE ;MSH148 ; R5 HAS #T.ST3 ADDED TO IT ;MSH148 ; ;MSH148 ;- ;MSH148 ;MSH148 $UNLCK::ADD #T.ST3,R5 ;POINT TO THIRD TASK STATUS WORD ;MSH148 BIT #T3.GFL,(R5) ;ARE THE TASK'S GRP GLOBALS LOCKED? ;MSH148 BEQ 400$ ;IF EQ NO, DON'T UNLOCK THEM ;MSH148 MOVB H.CUIC+1(R4),R4 ;GET TASK'S GROUP CODE ;MSH148 CALL $SRGEF ;FIND THE EVENT FLAG CONTROL BLOCK ;MSH148 BCC 200$ ;JOIN COMMON CODE WITH DIRECTIVE ;MSH148 CRASH ;ERROR-TASK LOCKED TO NONEXISTENT FLAGS ;MSH148 ;MSH148 400$: SEC ;TASK NOT LOCKED TO EVENT FLAGS ;MSH148 RETURN ; ;MSH148 .DSABL LSB ;+ ;**-56 ; **-$GTGEF-GET ADDRESS OF GROUP GLOBAL EVENT FLAGS ; ; THIS ROUTINE SEARCHES FOR THE GROUP GLOBAL EVENT FLAGS ASSOCIATED WITH ; A TASK. IF THE EVENT FLAGS EXIST, THE ADDRESS OF THE EVENT FLAG ;MSH049 ; WORD IS RETURNED IN R1. ;MSH049 ; ;**-2 ; INPUTS: ; ; R5=TCB ADDRESS OF TASK. ; ; OUTPUTS: ; ; C=0 IF GROUP GLOBAL EVENT FLAGS WERE FOUND ; R1=ADDRESS OF GROUP GLOBAL EVENT FLAGS ; ; C=1 IF EVENT FLAGS WERE NOT FOUND OR IF THE SPECIFIED ;MSH049 ; TASK IS CHECKPOINTED. ;MSH049 ; ;**-2 ;- ;**-2 $GTGEF::MOV R0,-(SP) ;SAVE REGISTERS MOV R4,-(SP) ; MOV T.PCB(R5),R4 ;GET TASK REGION PCB ADDRESS BIT #TS.OUT,T.STAT(R5) ;TASK CHECKPOINTED? SEC ;ASSUME IT WAS ;MSH049 BNE 10$ ;IF NE YES ;MSH049 MOV P.HDR(R4),R4 ;GET TASK HEADER ADDRESS ;**-3 MOVB H.CUIC+1(R4),R4 ;GET GROUP NUMBER CALL $SRGEF ;SEARCH FOR GROUP GLOBAL EVENT FLAGS BCS 10$ ;IF CS NOT FOUND ;MSH049 ADD #6,R1 ;POINT TO FIRST EVENT FLAG WORD” ;**-1 10$: MOV (SP)+,R4 ;RESTORE REGISTERS ;MSH049 MOV (SP)+,R0 ; ;**-1 RETURN ;**-1 .ENDC ;G$$EFN ;**-28 .END ”ÔðskQ ›c, .TITLE DRDRV .IDENT /02.14/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02.14 ; ; P. J. BEZEREDI 08-SEP-77 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; R. T. PERRON ; ; MODIFIED BY: ; ; R. T. PERRON 13-JUN-79 ; ; RP014 -- CORRECT RH11 SUPPORT FOR 22-BIT ADDRESSING ; ; R. T. PERRON 02-JUL-79 ; ; RP016 -- ADD RM80 SUPPORT ; ; R. T. PERRON 01-AUG-79 ; ; RP017 -- ADD RM05 SUPPORT ; ; R. T. PERRON 02-AUG-79 ; ; RP018 -- CORRECT RP07 SUPPORT ; ; R. T. PERRON 06-AUG-79 ; ; RP021 -- CORRECT ERROR RECOVERY FOR LAST BLOCK TRANSFERED ; ; R. T. PERRON 12-DEC-79 ; ; RP024 -- CORRECT REGISTER USAGE FOR FORMAT ERROR ; ; P. J. CARR 18-APR-80 ; ; PJC004 -- REMOVE M$$IXD STUFF ; ; P. J. CARR 28-APR-80 ; ; PJC005 -- CORRECT ERROR RECOVERY FOR CLASS B ERRORS ; DURING HEADER ; ; R. T. PERRON 21-NOV-80 ; ; RP041 -- CHANGE INTERFACE TO COMMON ECC ROUTINE ; ; P. J. CARR 27-MAR-81 ; ; PJC023 -- CORRECT ILLEGAL FUNCTION CODE (IE.IFC) HANDLING ; ; P. J. BEZEREDI 15-APR-81 ; ; PB237 -- MAKE BETTER USE OF EIS. ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; R. T. PERRON 16-OCT-81 ; ; RP075 -- CORRECT NON-EIS ADDRESS CALCULATION IN ECC CODE ; ; P. J. CARR 19-OCT-81 ; ; PJC038 -- CLEAN UP CODE ; ; RH70/11 - RM03/RM05/RP07/RM80 DISK PACK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; ; DEVICE REGISTER AND STATUS BIT DEFINITIONS ; RMCS1=0 ;CONTROL STATUS REGISTER 1 TRE=40000 ;TRANSFER ERROR MCPE=20000 ;MASSBUS CONTROL PARITY ERROR RMWC=2 ;WORD COUNT REGISTER RMBA=4 ;BUFFER ADDRESS REGISTER RMDA=6 ;DESIRED TRACK/SECTOR REGISTER RMCS2=10 ;CONTROL STATUS REGISTER 2 DLT=100000 ;DATA LATE ERROR WCE=40000 ;WRITE CHECK ERROR UPE=20000 ;UNIBUS PARITY ERROR NED=10000 ;NONEXISTENT DISK ERROR NEM=4000 ;NONEXISTENT MEMORY ERROR PGE=2000 ;PROGRAMMING ERROR MXF=1000 ;MISSED TRANSFER ERROR MDPE=400 ;MASSBUS DATA PARITY ERROR RMDS=12 ;DRIVE STATUS REGISTER ERR=40000 ;ERROR SUMMARY BIT MOL=10000 ;MEDIUM ONLINE WRL=4000 ;WRITE LOCKED DRIVE DRY=200 ;DRIVE READY VV=100 ;VOLUME VALID OM=1 ;OFFSET MODE ACTIVE RMER1=14 ;ERROR SUMMARY REGISTER DCK=100000 ;DATA CHECK ERROR UNS=40000 ;DRIVE UNSAFE OPI=20000 ;OPERATION INCOMPLETE DTE=10000 ;DRIVE TIMING ERROR WLE=4000 ;WRITE LOCK ERROR IAE=2000 ;INVALID DISK ADDRESS AOE=1000 ;ADDRESS OVERFLOW HCRC=400 ;HEADER CRC ERROR HCE=200 ;HEADER COMPARE ERROR ECH=100 ;ECC HARD ERROR WCF=40 ;WRITE CLOCK FAILURE FER=20 ;FORMAT ERROR PAR=10 ;MASSBUS CONTROL/DATA BUS PARITY ERROR RMR=4 ;REGISTER MODIFY REFUSED ILR=2 ;ILLEGAL REGISTER ILF=1 ;ILLEGAL FUNCTION RMAS=16 ;ATTENTION SUMMARY REGISTER RMLA=20 ;LOOKAHEAD REGISTER RMDBR=22 ;DATA BUFFER REGISTER RMMR=24 ;MAINTENENCE REGISTER RMDT=26 ;DRIVE TYPE REGISTER RMSN=30 ;DRIVE SERIAL NUMBER RMOF=32 ;DRIVE OFFSET REGISTER CMOD=100000 ;COMMAND MODIFIER MTD=40000 ;MOVE TRACK DESCRIPTOR FMT16=10000 ;FORMAT (1=16 BIT) ECI=4000 ;ECC INHIBIT HCI=2000 ;HEADER COMPARE INHIBIT SSEI=1000 ;SKIP SECTOR ERROR INHIBIT ; RP016 RMDC=34 ;DESIRED CYLINDER NUMBER RMER2=42 ;ERROR REGISTER #2 BSE=100000 ;BAD SECTOR ERROR SKI=40000 ;SEEK INCOMPLETE ERROR IVC=10000 ;INVALID COMMAND ERROR LSC=4000 ;LOSS OF SECTOR CLOCK ERROR LBC=2000 ;LOSS OF BIT CLOCK ERROR DVC=200 ;DEVICE CHECK ERROR SSE=40 ;SKIP SECTOR ERROR ; RP016 DPE=10 ;MASSBUS DATA PARITY ERROR RMEC1=44 ;ECC POSITION REGISTER RMEC2=46 ;ECC PATTERN REGISTER RMBAE=50 ;BUS ADDRESS EXTENSION REGISTER ; ;**-7 ; ERROR RETRY COUNT ; RETRY=8. ;CONTROLLER ERROR RETRY COUNT (NON-ECC ERRORS) ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLER NUMBER) ; CNTBL: .BLKW R$$M11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$M11 ;RETRY COUNT FOR CURRENT OPERATION .IF DF D$$IAG DGTBL: .BLKW R$$M11 ;DIAGNOSTIC PARAMETER TABLE .ENDC .IF GT R$$M11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC .IF DF R$$MOF OFFAD: .BLKW R$$M11 ;ADDRESS OF CURRENT OFFSET VALUE ; ; OFFSET POSITIONING VALUE TABLE ; OFFTB: .WORD FMT16!0 ;PLUS OFFSET .WORD FMT16!200 ;MINUS OFFSET .WORD 0 ;TERMINATOR .ENDC ;+ ; RP016 ; **-PRMTBL-DEVICE SPECIFIC PARAMETER TABLE ; RP016 ; ; RP016 ; MACRO FORMAT: LBN, TRK, SEC, CE ; RP016 ; WHERE: ; RP016 ; LBN - MAXIMUM NUMBER OF BLOCKS ON DEVICE (DOUBLE WORD); RP016 ; TRK - NUMBER OF TRACKS PER CYLINDER ; RP016 ; SEC - NUMBER OF SECTORS PER TRACK ; RP016 ; CE - MAXIMUM NUMBER OF BLOCKS IN CE CYLINDERS ; RP016 ;- ; RP016 .MACRO DVPRM LBN, TRK, SEC, CE ; RP016 .WORD LBN ; RP016 .BYTE SEC ; RP016 .BYTE TRK ; RP016 .WORD CE ; RP016 .ENDM DVPRM ; RP016 ; RP016 .WORD 0 ;POINTER TO DEVICE SPECIFIC PARAMETERS ; RP016 PRMTBL: ;DEVICE SPECIFIC PARAMETER TABLE ; RP016 DVPRM <2,1140>, 5, 32., 0 ; RM03 ; RP016 DVPRM <2,1140>, 5, 32., 0 ; RM03 PHYSICAL GEOMETRY ; RP016 DVPRM <3,131656>, 14., 31., 2*14.*31. ; RM80 ; RP016 DVPRM <3,152700>, 14., 32., 2*14.*32. ; RM80 PHYSICAL GEOMETRY ; RP016 DVPRM <7,121240>, 19., 32., 0 ; RM05 ; RP017 DVPRM <7,121240>, 19., 32., 0 ; RM05 PHYSICAL GEOMETRY ; RP017 DVPRM <17,60600>, 32., 50., 2*32.*50. ; RP07 ; RP018 DVPRM <17,60600>, 32., 50., 2*32.*50. ; RP07 PHYSCIAL GEOMETRY ; RP018 .WORD 0 ;END OF TABLE ; RP018 ; RP018 ; RP018 .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS ; ; DIAGNOSTIC FUNCTION TABLE ; FUNTBL: .BYTE 107, IO.HMS!IQ.UMD&377 .BYTE 105, IO.BLS!IQ.UMD&377 FUNTB0: .BYTE 115, IO.OFF!IQ.UMD&377 .BYTE 135, IO.DGN!IQ.UMD&377 .BYTE 151, IO.WCK!IQ.UMD&377 FUNTB1: .BYTE 171, IO.RPD!IQ.UMD&377 ; RP016 .BYTE 161, IO.WPD!IQ.UMD&377 ; RP016 .BYTE 171, IO.CER!IQ.UMD&377 ; RP016 .BYTE 161, IO.CEW!IQ.UMD&377 ; RP016 FUNTB2: .BYTE 173, IO.RDH!IQ.UMD&377 ; RP016 .BYTE 163, IO.WDH!IQ.UMD&377 ;**-1 .BYTE 175, IO.RTD!IQ.UMD&377 .BYTE 165, IO.WTD!IQ.UMD&377 FUNTB3: .BYTE 165, IO.TDD!IQ.UMD&377 ; RP016 FUNTBE:  .ENDC ; ; DRIVER DISPATCH TABLE ; $DRTBL::.WORD DRINI ;DEVICE INITIATOR ENTRY POINT .WORD DRCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DROUT ;DEVICE TIMEOUT ENTRY POINT .WORD DRPWF ;POWER FAIL ENTRY POINT ;+ ; **-DRINI-RH70/11 - RM03/RM05/RP07/RM80 DISK PACK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB 10$: RETURN ;REF LABEL DRINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 10$ ;IF CS, CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RH70/11 - RM03/RM05/RP07/RM80 DISK PACK I/O REQUEST PACKET FORMAT ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- DIAGNOSTIC SUPPLIMENTAL PARAMETER ELSE NOT USED. ; WD. 16 -- HIGH PART OF LOGICAL BLOCK NUMBER AND HIGH BYTE NOT USED ; WD. 17 -- LOW PART OF LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK ADRS. ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000). ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF D$$IAG MOV I.PRM+6(R1),DGTBL(R3) ;SAVE DIAGNOSTIC PARAMETERS .ENDC CLR I.PRM+6(R1) ;INITIALIZE FLAGS CALL 660$ ;DETERMINE DEVICE TYPE ; PJC038 .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BNE 20$ ;IF NE YES -- DOES NOT UMR'S ; PJC038 CALL $STMAP ;MAP UNIBUS TO MEMORY ;**-2 .ENDC ASL U.BUF(R5) ;SHIFT ADDRESS EXTENSION BITS INTO PLACE ASL U.BUF(R5) ; ASL U.BUF(R5) ; ASL U.BUF(R5) ; 20$: ;REF LABEL ; PJC038 ;**-1 .IF DF D$$IAG CMPB #IO.HMS/256.,I.FCN+1(R1) ;DIAGNOSTIC FUNCTION? BNE 50$ ;IF NE NO ; PJC038 MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE ;**-1 MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT ; RP016 CALL 600$ ;SET OTHER RECOVERY PARAMETERS ; PJC038 30$: MOVB (R0)+,U.BUF(R5) ;LOAD CONTROLLER FUNCTION CODE ; PJC038 CMPB (R0)+,I.FCN(R1) ;IS IT THE CORRECT CODE? ;**-1 BEQ 40$ ;IF EQ YES ; PJC038 CMP #FUNTBE,R0 ;END OF TABLE? ;**-1 BNE 30$ ;IF NE NO ; PJC038 MOV #IE.IFC&377,R0 ;FUNCTION IS ILLEGAL ;**-1 JMP 390$ ;GO REPORT IT ; PJC038 40$: CMPB #10,U.CW2(R5) ;IS IT AN RP07? ; PJC038 BNE 80$ ;IF NE NO ; PJC038 CMP #FUNTB2,R0 ;IS IT A HEADER FUNCTION? ; RP016 BLO 80$ ;IF LO NO ; PJC038 BIS #CMOD,I.PRM+6(R1) ;SET COMMAND MODIFIER ; RP016 CMP #FUNTB3,R0 ;IS TRACK DESCRIPTOR DISPLACED? ; RP016 BNE 80$ ;IF NE NO ; PJC038 BIS #MTD,I.PRM+6(R1) ;SET MOVE TRACK DESCRIPTOR BIT ; RP016 BR 80$ ; ; PJC038 ;**-10 .ENDC 50$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION ; PJC038 MOVB #171,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION ;**-1 CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 60$ ;IF HIS, FUNCTION IS LEGAL ; PJC038 JMP 390$ ;FUNCTION IS ILLEGAL ; PJC038 60$: BEQ 70$ ;IF EQ, FUNCTION IS READ ; PJC038 SUB #10,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION ;**-3 70$: MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT ; PJC038 CALL 600$ ;SET OTHER RECOVERY PARAMETERS ; PJC038 CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER ;**-2 CMPB #IO.WLB/256.,I.FCN+1(R3) ;WRITE COMMAND ? BNE 100$ ;IF NE NO ; PJC038 BITB #IO.WLT&377,I.FCN(R3) ;WRITE LAST TRACK FUNCTION ? ;**-1 BNE 100$ ;IF NE YES ; PJC038 MOV R1,-(SP) ;SAVE POINTER FOR $BLKC1 ; RP016 MOV PRMTBL-2,R1 ;GET POINTER FOR PROPER DEVICE ; RP016 CLR -(SP) ;GET A WORKING REGISTER ; RP016 BISB 4(R1),(SP) ;GET SETORS/TRACK ; RP016 ADD (SP)+,I.PRM+12(R3) ;INCREMENT BLOCK NUMBER BY 1 TRACK ; RP016 ADCB I.PRM+10(R3) ;ADD THE CARRY ; RP016 MOV (SP)+,R1 ;RETIEVE POINTER FOR $BLKC1 ; RP016 CALL $BLKC1 ;SEE IF WRITE IS TO BAD SECTOR FILE ; RP016 MOV PRMTBL-2,R1 ;GET POINTER FOR PROPER DEVICE ; RP016 CLR -(SP) ;GET A WORKING REGISTER ; RP016 BISB 4(R1),(SP) ;GET SECTORS/TRACK ; RP016 SUB (SP)+,R0 ;CORRECT THE BLOCK NUMBER ; RP016 SBC R2 ;AND THE HIGH BLOCK NUMBER ; RP016 BR 100$ ;CONTINUE ; PJC038 80$: CALL 760$ ;CHECK FOR DIAGNOSTIC FUNCTION ; PJC038 BCC 90$ ;IF CC NO ; PJC038 BIS #SSEI,I.PRM+6(R1) ;SET SKIP SECTOR INHIBIT BIT ; RP016 90$: MOV R1,R3 ;SAVE I/O PACKET ADDRESS ; PJC038 ADD #I.PRM+11,R1 ;POINT PAST HIGH PART OF LBN ; RP016 CLRB (R1)+ ;CLEAR EXCESS BYTE ; RP016 MOV (R1),R0 ;GET LOW PART OF LBN ; RP016 MOV -(R1),R2 ;GET HIGH PART OF LBN ; RP016 100$: CALL 630$ ;SPECIAL ADDRESS CALCULATION ROUTINE ; PJC038 ;**-26 .IF DF R$$MOF BIS #1,I.PRM+6(R3) ;SET OFFSET MODE INACTIVE .ENDC  ; ;**-7 ; INITIATE I/O OPERATION ; 110$: ;REF LABEL ; PJC038 ;**-2 .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BNE 120$ ;IF NE YES -- DOES NOT USE UMR'S ; PJC038 CALL $MPUBM ;MAP UNIBUS TO MEMORY ;**-2 120$: ;REF LABEL ; PJC038 ;**-1 .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR ; RP014 MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT ADD #10,R2 ;POINT TO SECOND CSR MOV #40,(R2) ;CLEAR RH11 CONTROLLER AND ALL DRIVES MOVB U.UNIT(R5),(R2) ;SELECT PROPER DRIVE MOV I.PRM+12(R1),-(R2) ;INSERT TRACK/SECTOR ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;MAKE NEGATIVE WORD COUNT MOV #23,-(R2) ;EXECUTE PACK ACK FUNCTION TO SET VV .IF DF D$$IAG BIT #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? ; RP016 BEQ 130$ ;IF EQ NO ; PJC038 MOVB S.CON(R4),R0 ;GET CONTROLLER NUMBER ;**-2 MOV DGTBL(R0),RMMR(R2) ;SET DIAGNOSTIC PARAMETERS ; RP016 130$: ;REF LABEL ; PJC038 ;**-2 .ENDC MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY MOV I.PRM+10(R1),RMDC(R2) ;SET DESIRED CYLINDER ADDRESS MOV RMDS(R2),R3 ;GET CURRENT DRIVE STATUS COM R3 ;COMPLEMENT STATUS BIT #MOL!DRY!VV,R3 ;DRIVE READY? BNE 140$ ;IF NE NO ; PJC038 BIT #UNS,RMER1(R2) ;DRIVE UNSAFE? ;**-1 BEQ 160$ ;IF EQ NO ; PJC038 140$: ;REF LABEL ; PJC038 ;**-2 .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 190$ ;IF NE YES ; PJC038 ;**-1 .IFTF .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BEQ 150$ ;IF EQ NO ; PJC038 JMP 320$ ;PROCESS DIAGNOSTIC NOT READY ; PJC038 150$: ;REF LABEL ; PJC038 ;**-3 .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR .ENDC JMP 380$ ;FINSH I/O ; PJC038 160$: ;REF LABEL ; PJC038 ;**-2 .IFT BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC MOV #FMT16,-(SP) ;GET FORMAT BIT .IF DF R$$MOF!D$$IAG BIT #40,RMDT(R2) ;IS IT AN RP07? BNE 170$ ;IF NE YES ; PJC038 BITB #1,I.PRM+6(R1) ;WAS OFFSET ACTIVE ? ;**-1 BNE 170$ ;IF NE NO ; PJC038 MOVB #15,(R2) ;LOAD OFFSET FUNCTION ;**-1 170$: BIS I.PRM+6(R1),(SP) ;SET OTHER BITS ; PJC038 ;**-1 .ENDC MOV (SP)+,RMOF(R2) ;LOAD THE OFFSET REGISTER .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE IN BIT MAP .ENDC .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BEQ 180$ ;;;IF EQ NO -- DOES USE UMR'S ; PJC038 MOVB U.BUF+1(R5),RMBAE(R2) ;;;SET ADDRESS EXTENSION BITS ;**-2 MOVB U.BUF(R5),(R2) ;;;START FUNCTION RETURN ;;;; .ENDC 180$: MOV U.BUF(R5),(R2) ;;;START FUNCTION ; PJC038 ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DRCAN:: RETURN ;;;NOP FOR RM03/RM05/RP07/RM80 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DRPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS DRIVE CURRENTLY BUSY? BEQ 200$ ;IF EQ NO ; PJC038 190$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC038 200$: BISB #US.SPU,U.STS(R5) ;SET DRIVE SPINNING UP ; PJC038 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DRINT RH70/RH11 - RM03/RM05/RP07/RM80 DISK PACK CONTROLLER ; INTERRUPT HANDLER ;- INTSE$ DR,PR5,R$$M11 ;;;SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BIT #HCRC!HCE,RMER1(R2) ;HEADER CRC OR HEADER COMPARE ERROR?; PJC005 BNE 240$ ;IF NE YES ; PJC038 BIT #SSE,RMER2(R2) ;SKIP SECTOR ERROR? ; PJC005 BEQ 240$ ;IF EQ NO ; PJC038 BIS #SSEI,I.PRM+6(R1) ;SET SKIP SECTOR ERROR INHIBIT ; RP016 MOVB #11,(R2) ;CLEAR SELECTED DRIVE ERRORS ; RP016 MOV RMOF(R2),-(SP) ;GET OFFSET REGISTER ; RP016 BIS I.PRM+6(R1),(SP) ;SET REMAINING BITS IN REGISTER ; RP016 MOV (SP)+,RMOF(R2) ;RE-LOAD OFFSET REGISTER ; RP016 MOV RMWC(R2),R0 ;GET NEGATIVE WORDS REMAINING ; RP016 BNE 210$ ;IF NE WE HAD A PARTIAL TRANSFER ; PJC038 MOV #-1,R0 ;FAKE A PARTIAL TRANSFER ; PJC005 210$: ASL R0 ;CONVERT TO NEGATIVE BYTES ; PJC038 ADD U.CNT(R5),R0 ;CALCULATE BYTES ACTUALLY TRANSFERRED ; PJC005 BIC #777,R0 ;GET BLOCKS ACTUALLY TRANSFERRED ; PJC005 CALL 700$ ;BACKUP TO START OF BLOCK IN ERROR ; PJC038 CALL 760$ ;CHECK FOR DIAGNOSTIC FUNCTION ; PJC038 BCS 230$ ;IF CS YES ; PJC038 220$: INCB I.PRM+12(R1) ;INC TO NEXT SEQUENTIAL SECTOR ; PJC038 230$: JMP 110$ ;RESTART FUNCTION ; PJC038 240$: BIT #SSEI,RMOF(R2) ;SKIP SECTOR ERROR INHIBIT SET? ; PJC038 BNE 250$ ;IF NE YES ; PJC038 BIC #SSEI,I.PRM+6(R1) ;RESET SKIP SECTOR ERROR INHIBIT ; PJC005 250$: ;REF LABEL ; PJC038 .IF DF D$$IAG CALL 760$ ;CHECK FOR DIAGNOSTIC FUNCTION ; PJC038 BCS 320$ ;IF CS YES ; PJC038 ;**-2 .ENDC BIT #70,(R2) ;RECALIBRATE COMMAND ? BNE 260$ ;IF NE NO ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ;**-1 BITB #IQ.X,I.FCN(R1) ;RETIRES INHIBITED ? BNE 340$ ;IF NE YES ; PJC038 BIT #ERR,RMDS(R2) ;ERROR SET ? ;**-1 BEQ 330$ ;IF EQ NO ; PJC038 CLR R1 ;SHOW NO BYTES TRANSFERED ;**-1 JMP 390$ ;FINSH UP ; PJC038 260$: BIT #TRE!MCPE,(R2) ;ANY ERRORS DURING TRANSFER? ; PJC038 BEQ 350$ ;IF EQ NO ; PJC038 ;**-3 .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR BITB #IQ.X,I.FCN(R1) ;INHIBIT RETIRES ? BNE 270$ ;IF NE YES, SEE IF DRIVE NEEDS A RECAL ; PJC038 BIT #IVC!LSC!LBC!DVC!DPE,RMER2(R2) ;CLOCK ERROR OR OTHER SE;**-1 BNE 330$ ;IF NE YES ; PJC038 BIT #NED!NEM!PGE,RMCS2(R2) ;HARD ERROR ? ;**-1 BNE 380$ ;IF NE YES ; PJC038 MOV RMER1(R2),R1 ;COPY ERROR REGISTER 1 ; PJC005 BIT #UNS!IAE!AOE!RMR!ILR!ILF,R1 ;HARD ERROR? ; PJC005 BNE 380$ ;IF NE YES ; PJC038 270$: BIT #SKI,RMER2(R2) ;SEEK INCOMPLETE? ; PJC038 BNE 280$ ;IF NE YES ; PJC038 BIT #HCRC,R1 ;HEADER CRC ERROR? ; PJC005 BNE 410$ ;IF NE YES ; PJC038 BIT #HCE,R1 ;HEADER COMPARE ERROR? ; PJC005 BNE 280$ ;IF NE YES ; PJC038 BIT #FER,R1 ;FORMAT ERROR? ; RP024 BEQ 290$ ;IF EQ NO ; PJC038 BR 380$ ;YES ; PJC038 280$: JMP 620$ ;PROCESS SKI OR HCE ERRORS ; PJC038 290$: BIT #BSE,RMER2(R2) ;BAD SECTOR ERROR? ; PJC038 BEQ 300$ ;IF EQ NO ; PJC038 MOV #IE.BBE&377,R0 ;BAD BLOCK ERROR ;**-19 BR 380$ ;HARD ERROR ; PJC038 300$: BIT #WLE,RMER1(R2) ;WRITE LOCK ERROR? ; PJC038 BEQ 330$ ;IF EQ NO ; PJC038 CLR R1 ; ; PJC005 BR 390$ ; ; PJC038 ;**-5 ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE OPERATION WAS DIAGNOSTIC. TIMEOUTS ARE USUALLY CAUSED ; BY POWER FAILURE BUT MAY ALSO BE THE RESULT OF A HARDWARE FAILURE. ; DROUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 310$ ;;;IF EQ NO ; PJC038 INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #16.,S.STS(R4) ;;;HAVE WE WAITED 1 MINUTE YET? ; PJC029 BEQ 310$ ;;;IF EQ YES ; PJC038 MTPS #0 ;;;ALLOW INTERRUPTS ;**-3 JMP 110$ ;RETRY ENTIRE OPERATION ; PJC038 310$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC038 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-2 .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 330$ ;IF CC, TIMEOUT DURING NORMAL FUNCTION ; PJC038  320$: CALL $CRPAS ;PASS CONTROLLER REGISTERS TO TASK ; PJC038 BR 380$ ;DIAGNOSTIC PROCESSING COMPLETE ; PJC038 ;**-3 .ENDC 330$: MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET ; PJC038 BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? ;**-1 340$: BNE 370$ ;IF NE YES ; PJC038 DECB RTTBL(R3) ;ANY MORE RETRIES ? ;**-1 .IF DF R$$MOF BGT 400$ ;IF GT YES ; PJC038 ;**-1 .IFF BLE 370$ ;IF LE NO ; PJC038 JMP 110$ ; ; PJC038 ;**-2 .ENDC 350$: ;REF LABEL ; PJC038 ;**-1 .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK ? BNE 360$ ;IF NE YES ; PJC038 BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR ? ;**-1 BEQ 380$ ;IF EQ NO ; PJC038 360$: CMPB #171,U.BUF(R5) ;WAS LAST FUNCTION A READ? ; PJC038 BEQ 380$ ;IF EQ YES ; PJC038 CMPB #161,U.BUF(R5) ;WAS LAST OPERATION A WRITE ? ;**-3 BNE 380$ ;IF NE NO ; PJC038 MOVB #151,U.BUF(R5) ;CHANGE OPERATION TO WRITE CHECK ;**-1 MOV #RETRY,RTTBL(R3) ;REINITIALIZE RETRY COUNT JMP 110$ ;START WRITE CHECK ; PJC038 ;**-1 .IFTF 370$: ;REF LABEL ; PJC038 ;**-1 .IFT BIT #WCE,RMCS2(R2) ; WRITE CHECK ERROR ? BEQ 380$ ;IF EQ NO ; PJC038 MOV #IE.WCK&377,R0 ;SET WRITE CHECK ERROR ;**-1 .ENDC 380$: MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET ; PJC038 MOV RMWC(R2),R1 ;WORDS NOT TRANSFER (2'S COMPLEMENT) ;**-1 ASL R1 ;MAKE INTO A BYTE COUNT ADD I.PRM+4(R3),R1 ;CALCULATE BYTES TRANSFERED MOV #TRE!11,(R2) ;CLEAR RH11 CONTROLLER AND DRIVE 390$: ;REF LABEL ; PJC038 ;**-1 .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION ;**-7 JMP DRINI ;PROCESS NEXT REQUEST .IF DF R$$MOF 400$: JMP 540$ ;RETURN TO CENTERLINE ; PJC038 ;**-1 .ENDC ; ; START ECC CORRECTION PROCEDURE ; ;**-2 410$: ;REF LABEL ; PJC038 CMPB #171,U.BUF(R5) ;IS THIS A READ FUNCTION? ; RP041 BEQ 330$ ;IF EQ NO ; PJC038 BIS RMER2(R2),R1 ;.OR. ERROR REGISTER 2 ; RP041 BISB RMCS2+1,R1 ;.OR. CONTROLLER REGISTERS ; RP041 CMP #DCK,R1 ;ONLY DATA CHECK ERROR? ; RP041 BNE 330$ ;IF NE NO ; PJC038 MOV RMWC(R2),R0 ;GET NEGATIVE NUMBER OF WORDS REMAINING ;**-12 ASL R0 ;CONVERT TO NEGATIVE BYTES REMAINING ADD U.CNT(R5),R0 ;CALCULATE NUMBER OF BYTES TRANSFERED ; RP041 ; RP041 .IF DF R$$MOF ; RP041 ; RP041 BEQ 530$ ;IF EQ NONE TRANSFERED, TRY OFFSET RECOV; PJC038 ; RP041 .IFF ; RP041 ; RP041 BNE 420$ ;IF NE SOME TRANSFERED ; PJC038 MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ; RP041 BR 330$ ;AND GO ON ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 420$: MOV RMEC1,R1 ;GET ECC ERROR POSITION ; PJC038 MOV RMEC2,R3 ;GET ECC CORRECTION PATTERN ; PJC038 MOV RMWC(R2),R2 ;GET REMAINING WORD COUNT ; PJC038 ; PJC038 .IF DF S$$ECC ; PJC038 ; PJC038 CALL $ECCOR ;CALL SHARED ECC ROUTINE ; PJC038 ; PJC038 .IFF ; PJC038 ; PJC038 ;**-8 ; ; SECOND CALCULATE BYTE OFFSET IN BLOCK AND POSITION PATTERN SHIFT COUNT ; MOV R0,-(SP) ;SAVE BYTE COUNT ; RP041 CLR R0 ;CLEAR HIGH ORDER ERROR POSITION ; RP041 DEC R1 ;CONVERT TO RELATIVE BIT NUMBER ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 DIV #20,R0 ;DIVIDE FOR: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV R1,R0 ;COPY ECC ERROR POSITION ; RP041 MOV #20,R1 ;SET DIVISOR TO CALCULATE: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 CALL $DIV ;PERFORM DIVISION ; RP041 ; RP041 .ENDC ; RP041 ; RP041  ; RP041 MOV R0,-(SP) ;SAVE WORD POSITION ; RP041 MOV R2,-(SP) ;SAVE REMAINING WORD COUNT ; RP041 CLR R2 ;CLEAR HIGH ORDER ERROR PATTERN ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 430$: ASHC R1,R2 ;SHIFT PATTERN INTO CORRECT POSITION ; PJC038 ; RP041 .IFF ; RP041 ; RP041 430$: DEC R1 ;ANY MORE SHIFTS LEFT TO PERFORM ; PJC038 BLT 440$ ;IF LT NO ; PJC038 ASL R3 ;DOUBLE LEFT SHIFT ; RP041 ROL R2 ; ; RP041 BR 430$ ; ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 440$: MOV 4(SP),R0 ;RETRIEVE BYTES ACTUALLY TRANSFERED ; PJC038 SUB #510.,R0 ;BACKUP TO BLOCK IN ERROR ... ; RP041 ;... OFFSET TO HIGH WORD IN ERROR ; RP041 ; RP041 ; RP041 .IF DF D$$IAG ; RP041 ; RP041 CALL $RELOP ;COMPUTE LOCATION IN PHYSICAL MEMORY ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV R0,-(SP) ;SAVE BYTE OFFSET ON STACK ; RP041 MOV U.BUF+2(R5),R1 ;GET LOW 16 BITS OF ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 MOVB U.BUF+1(R5),R0 ;GET HIGH BITS OF REAL ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$EXT ; RP041 ; RP041 BIT #DV.EXT,U.CW1(R5) ;CAN THIS CONTROLLER/UNIT DIRECTLY ..; RP041 ;... ADDRESS ALL OF PHYSICAL MEMORY ; RP041 BNE 450$ ;IF NE YES ; PJC038 ADD #,R4 ;POINT PAST PHYSCIAL BUFFER ADDRESS ; RP041 ;CONTAINED IN UMR AREA ; RP041 MOV -(R4),R1 ;GET LOW 16 BITS OF PHYSICAL BUFFER ADDR; RP041 TSTB -(R4) ;SKIP NEXT BYTE ; RP041 MOVB -(R4),R0 ;GET HIGH 6 BITS OF PHYSICAL BUFFER ADDR; RP041 450$: MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; PJC038 ; RP041 .ENDC ; RP041 ; RP041 .IFF ; RP041 ; RP041 CLR R0 ; ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 ADD (SP)+,R1 ;CALCULATE NEW STARTING ADDRESS ... ; RP041 ADC R0 ;... ; RP041 ; RP041 ; RP041 .IF DF M$$MGE ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ; RP041 ASHC #-10.,R1 ;... ; RP041 ; RP041 .IFF ; RP041 ; RP041 MOV #10.,-(SP) ;SET COUNT FOR 10 SHIFTS ; RP041 460$: DEC (SP) ;ANY MORE SHIFTS TO PERFORM ; PJC038 BLT 470$ ;IF LT NO ; PJC038 ASL R1 ;DOUBLE LEFT SHIFT R1 ... ; RP075 ROL R0 ;... INTO R0 ; RP075 BR 460$ ; ; PJC038 470$: SWAB R1 ;SWAP BYTS ; PJC038 ASR R1 ;SHIFT RIGHT R1 ; RP075 ASR R1 ;... ; RP075 TST (SP)+ ;CLR THE STACK ; RP075 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 MOV R0,KISAR6 ;SET RELOCATION BIAS ; RP041 ADD #140000,R1 ;SET DISPLACEMENT ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 .ENDC ; RP041 ; RP041  ; RP041 MOV (SP)+,R0 ;RETRIEVE REMAINING WORD COUNT ; RP041 BPL 480$ ;IF PL THIS MAY HAVE BEEN A PARTIAL BLOC; PJC038 ;TRANSFER ; PJC038 CLR R0 ;ASSUME A WHOLE BLOCK WAS TRANSFERRED ; RP041 480$: ADD (SP),R1 ;ADD IN ERROR WORD POSITION OFFSET ... ; PJC038 ADD (SP),R1 ;... FOR BYTE ADDRESSING ; RP041 ADD (SP)+,R0 ;ADD CORECTION OFFSET TO CORRECTION LIMI; RP041 CMP R0,#377 ; ; RP041 BHI 500$ ;IF HI NOT AT ALL ; PJC038 BEQ 490$ ;IF EQ THEN ONLY ONE WORD ; PJC038 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 XOR R2,(R1) ;CORRECT HIGH ORDER WORD ; RP041 490$: XOR R3,-(R1) ;CORRECT LOW ORDER WORD ; PJC038 ; RP041 .IFF ; RP041 ; RP041 MOV (R1),R0 ;COPY HIGH ORDER DATA WORD ; RP041 BIC R2,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R2 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R2,(R1) ;PATTERN.OR.DATA WORD ; RP041 490$: MOV -(R1),R0 ;COPY LOW ORDER DATA WORD ; PJC038 BIC R3,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R3 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R3,(R1) ;PATTERN.OR.DATA WORD ; RP041 ; RP041 .ENDC ; RP041 ; RP041 ; RP041 500$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER ; PJC038 MOV (SP)+,R1 ;RESTORE BYTES TRANSFERRED ; RP041 MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX ; RP041 MOV S.CSR(R4),R2 ;RESTORE CSR ADDRESS ; RP041 ;**-44 .ENDC MOVB #11,(R2) ;CLEAR DRIVE ERRORS CALL 600$ ;RESET RECOVERY PARAMETERS ; PJC038 SUB R1,U.CNT(R5) ;ANY MORE WORDS TO TRANSFER? ;**-1 BEQ 380$ ;IF EQ NO ; PJC038 ;**-1 .IF DF M$$MGE .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BEQ 510$ ;IF EQ NO -- DOES USE UMR'S ; PJC038 MOVB RMBAE(R2),U.BUF+1(R5) ;SAVE MEMORY EXTENSION BITS ;**-2 BR 520$ ; ; PJC038 ;**-1 .ENDC 510$: MOVB RMCS1+1(R2),U.BUF+1(R5) ;SAVE MEMORY EXTENSION BITS ; PJC038 BICB #^C<3>,U.BUF+1(R5) ;CLEAR EXCESS BITS ;**-1 520$: ;REF LABEL ; PJC038 ;**-1 .ENDC MOV RMBA(R2),U.BUF+2(R5) ;SAVE BUFFER ADDRESS MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET MOV RMDC(R2),I.PRM+10(R1) ;SAVE CYLINDER ADDRESS MOV RMDA(R2),I.PRM+12(R1) ;SAVE TRACK/SECTOR ADDRESS MOVB U.BUF(R5),(R2) ;RESTART PREVIOUS OPERATION RETURN ; ;**-71 ; ; DATA ERROR & HEADER ERROR RECOVERY ; 530$: MOV S.PKT(R4),R1 ;GET ADDRESS OF I/O PACKET ; PJC038 TST R0 ;ANY GOOD SECTORS TRANSFERED ? ;**-2 BEQ 550$ ;IF EQ NO ; PJC038 ;**-1 ; ; THE TRANSFER ENDED IN A DATA ERROR (EG, ECH, DTE, OR HCRC) BUT THERE ; WERE SECTORS TRANSFERED THAT CONTAINED GOOD DATA; THE GOOD DATA ; IS SAVED AND THE TRANSFER IS RETRIED FROM THE POINT OF ERROR. ; CALL 700$ ;CALCULATE UPDATED DISK ADDRESS ; PJC038 540$: BISB #1,I.PRM+6(R1) ;SET UP RTC FLAG ; PJC038 CALL 600$ ;RESTORE OFFSET TABLE AND RETRY COUNT ; PJC038 BR 590$ ; ; PJC038 ;**-29 ; ; NO GOOD DATA WAS TRANSFERED - CHECK IF OFFSET SHOULD BE CHANGED ; 550$: ;REF LABEL ; PJC038 ;**-1 .IF DF R$$MOF BIT #DCK!DTE!ECH,RMER1(R2) ;DATA CHECK OR DRIVE TIMING ERROR? BNE 560$ ;IF NE YES ; PJC038 CMP OFFAD(R3),#OFFTB ;AT OFFSET ALREADY ? ;**-1 BLO 560$ ;IF LO NO ; PJC038 BIS #HCI,I.PRM+6(R1) ;SET 'HCI' BIT ;**-1 .IFTF 560$: DECB RTTBL+1(R3) ;CHANGE OFFSET? ; PJC038 BGT 590$ ;IF GT NO ; PJC038 BIT #40,RMDT(R2) ;IS IT AN RP07? ;**-2 BNE 570$ ;IF NE YES ; PJC038 ;**-1 .IFT ADD #2,OFFAD(R3) ;UPDATE OFFSET POINTER CMP #OFFTB+4,OFFAD(R3) ;FINISHED ? BNE 580$ ;IF NE NO ; PJC038 ;**-1 .IFTF 570$: MOV #IE.VER&377,R0 ;SET UNRECOVERABLE ERROR COUNT ; PJC038 CLRB RTTBL(R3) ;ZERO RETRY COUNT ; RP016 JMP 380$ ;DONE ; PJC038 ;**-3 .IFT 580$: MOVB #2,RTTBL+1(R3) ;SET RECOVERY RETRY COUNT ; PJC038 ;**-2 .ENDC 590$: JMP 110$ ;RETRY FUNCTION ; PJC038 ;**-1 ; ; SET RECOVERY & OFFSET PARAMETERS ; 600$: MOVB #16.,RTTBL+1(R3) ;INITIALIZE THE RETRY COUNT ; PJC038 ;**-1 .IF DF R$$MOF 610$: MOV #OFFTB-2,OFFAD(R3) ;SET OFFSET TABLE POINTER ; PJC038 ;**-1 .ENDC RETURN ; ; ;SET RECOVERY RECALIBRATION FOR 'HCE' AND 'SKI' ERRORS ; 620$: MOV #TRE!11,(R2) ;CLEAR CONTROLLER AND DRIVE ; PJC038 MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT ;**-1 MOVB #107,(R2) ;LOAD THE RECALIBRATE COMMAND RETURN ; ;  ; RP016 ; SPECIAL ADDRESS CALCULATION ROUTINE ; RP016 ; ; RP016 630$: ; PJC038 ; RP016 .IF DF M$$EIS ; PB237 ; PB237 MOV R0,R1 ;REPOSITION LBN ; PB237 MOV R2,R0 ;... ; PB237 MOV PRMTBL-2,R2 ;GET POINTER FOR PROPER DEVICE ; PB237 CLR R4 ;GET A WORKING REGISTER ; PB237 BISB 4(R2),R4 ;GET SECTORS PER TRACK ; PB237 DIV R4,R0 ;CALCULATE SECTOR NUMBER ; PB237 MOVB R1,I.PRM+12(R3) ;SAVE SECTOR NUMBER ; PB237 MOV R0,R1 ;SET NEW DIVIDEND ; PB237 CLR R0 ;CLEAR HIGH BITS ; PB237 CLR R4 ;GET READY FOR THE BISB ; PB237 BISB 5(R2),R4 ;GET TRACKS PER CYLINDER ; PB237 DIV R4,R0 ;CALCULATE CYLINDER AND TRACK ; PB237 MOV R0,I.PRM+10(R3) ;SAVE CYLINDER NUMBER ; PB237 MOVB R1,I.PRM+13(R3) ;SAVE TRACK NUMBER ; PB237 MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; PB237 ; PB237 .IFF ; PB237 ; PB237 MOV PRMTBL-2,R1 ;GET POINTER FOR PROPER DEVICE ; RP016 CLR -(SP) ;GET A WORKING REGISTER  ; RP016 BISB 4(R1),(SP) ;GET TRACKS/CYLINDER ; RP016 MOV (SP)+,R1 ; ; RP016 ; ; SPECIAL 32-BIT INTEGER DIVIDE ROUTINE ; ; INPUTS: ; R0=LOW-ORDER PART OF DIVIDEND ; R1=POSITIVE DIVISOR ; R2=HIGH-ORDER PART OF DIVIDEND ; ; OUTPUTS: ; R0=LOW-ORDER PART OF QUOTIENT ; R1=UNDEFINED, FOR POSSIBLE FUTURE USE ; R2=REMAINDER ; MOV #16.,-(SP) ;SET DIVIDE LOOP COUNT ; RP016 640$: ASL R0 ;DOUBLE LEFT SHIFT ; PJC038 ROL R2 ;THESE TWO INSTRUCTIONS ;**-2 CMP R2,R1 ;PARTIAL REMAINDER LARGER THAN DIVISOR? BLO 650$ ;IF LO NO ; PJC038 SUB R1,R2 ;SUBTRACT OUT DIVISOR ;**-1 INC R0 ;ACCUMULATE QUOTIENT 650$: DEC (SP) ;ANY MORE PARTIAL DIVIDES? ; PJC038 BGT 640$ ;IF GT YES ; PJC038 TST (SP)+ ;PRUNE THE STACK ;**-2 ; ; RP016 ; FINISH UP CALCULATING DEVICE ADDRESSING ; RP016 ; ; RP016 MOV PRMTBL-2,R1 ;GET POINTER TO PARAMETER TABLE ; RP016 CLR -(SP) ;GET A WORKING REGISTER ; RP016 BISB 5(R1),(SP) ;GET TRACKS/CYLINDER ; RP016 MOV (SP)+,R1 ; ; RP016 CALL $DIV ;CALCULATE TRACK AND CYLINDER ; RP016 MOV R0,I.PRM+10(R3) ;SAVE DESIRED CYLINDER ADDRESS ; RP016 SWAB R1 ;SWAP TRACK ADDRESS TO HIGH BYTE ; RP016 BIS R1,R2 ;MERGE TRACK ADDRESS WITH SECTOR ADDRESS; RP016 MOV R2,I.PRM+12(R3) ;SAVED DESIRED TRACK AND SECTOR ADDRESS; RP016 ; PB237 .ENDC ; PB237 ; PB237 ; PB237 RETURN ;**-2 ; ; RP016 ; SPECIAL ROUTINE TO DETERMINE DEVICE PARAMETERS ; RP016 ;  ; RP016 660$: MOV #PRMTBL,R0 ;GET POINTER TO PARAMETER TABLE ; PJC038 670$: CMPB (R0),U.CW2(R5) ;IS THIS THE PROPER DEVICE? ; PJC038 BNE 690$ ;IF NE NO ; PJC038 CALL 760$ ;CHECK FOR DIAGNOSTIC FUNCTION ; PJC038 BCC 680$ ;IF CC NO ; PJC038 ADD #10,R0 ;POINT TO DEVICE'S PHYSICAL GEOMETRY ; RP016 680$: MOV R0,PRMTBL-2 ;SAVE POINTER FOR LATER USE ; PJC038 RETURN ; ; RP016 690$: ADD #10,R0 ;INC TO NEXT DEVICE ; PJC038 TST (R0) ;END OF TABLE? ; RP016 BNE 670$ ;IF NE NO ; PJC038 MOV #IE.BAD&377,R0 ;DEVICE NOT IN TABLE, BAD PARAMETERS ; RP016 TST (SP)+ ;PRUNE RETURN FROM STACK ; RP016 JMP 390$ ;GO REPORT IT ; PJC038 ; ; RP016 ; CALCULATE UPDATED DISK ADDRESS ; RP016 ; ; RP016 700$: SUB R0,U.CNT(R5) ;REDUCE BYTES REMAINING TO TRANSFER ; PJC038 BNE 710$ ;IF NE MORE SECTORS TO TRANSFER ; PJC038 ADD R0,U.CNT(R5) ;LAST SECTOR TO TRANSFER, CORRECT BYTES ; RP021 RETURN ;AND EXIT ; RP021 710$: ADD R0,U.BUF+2(R5) ;UPDATE STARTING BUFFER ADDRESS ; PJC038 ; RP016 ; RP016 .IF DF M$$MGE ; RP016 ; RP016 ; RP016 .IF DF M$$EXT ; RP016 ; RP016 BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP016 BEQ 720$ ;IF EQ NO ; PJC038 ADCB U.BUF+1(R5) ;UPDATE MEMORY EXTENSION BITS ; RP016 BR 730$ ; ; PJC038 ; RP016 .ENDC ; RP016 ; RP016 ; RP016 720$: ADCB U.BUF+1(R5) ;UPDATE MEMORY EXTENSION BITS ; PJC038 BICB #^C<3>,U.BUF+1(R5) ;CLEAR EXCESS BITS ; RP016 730$: ;REF LABEL ; PJC038 ; RP016 .ENDC ; RP016 ; RP016 ; RP016 SWAB R0 ;CALCULATE NUMBER OF SECTORS TRANSFERED ; RP016 ASR R0 ; ; RP016 ADD I.PRM+12(R1),R0 ;UPDATE TRACK/SECTOR ADDRESS ; RP016 CLR -(SP) ;GET A WORKING REGISTER ; RP016 MOV PRMTBL-2,R3 ;GET POINTER TO PROPER DEVICE ; RP016 740$: CMPB 4(R3),R0 ;SECTOR OVERFLOW ; PJC038 BHI 750$ ;IF HI NO ; PJC038 BISB 4(R3),(SP) ;COPY SECTORS/TRACK ; RP016 SUB (SP),R0 ;SUBTRACT A TRACKS WORTH OF SECTORS ; RP016 ADD #1*256.,R0 ;ADD IN A TRACK ; RP016 MOV 4(R3),(SP) ;GET TRACKS AND SECTORS ; RP016 CLRB (SP) ;ISOLATE TRACKS/CYLINDER ; RP016 CMP (SP),R0 ;TRACK OVERFLOW ? ; RP016 BHI 740$ ;IF HI NO ; PJC038 SUB (SP),R0 ;NORMALIZE TRACK ADDRESS ; RP016 INC I.PRM+10(R1) ;UPDATE CYLINDER ADDRESS ; RP016 BR 740$ ; ; PJC038 750$: MOV R0,I.PRM+12(R1) ;SET UPDATED SECTOR/TRACK ADDRESS ; PJC038 TST (SP)+ ;PRUNE STACK ; RP016 MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX ; RP016 RETURN ; ; RP016 ; ; RP016 ; SPECIAL ROUTINE TO CHECK FOR DIAGNOSTIC FUNCTIONS ; RP016 ; TWO EXCEPTIONS: IO.CER AND IO.CEW ; RP016 ; ; RP016 ; INPUTS: ; RP016 ; ; RP016 ; R1=ADDRESS OF I/O PACKET ; RP016 ; ; RP016 ; OUTPUTS: ; RP016 ; ; RP016 ; C/S=DIAGNOSTIC FUNCTION (EXCEPT AS NOTED) ; RP016 ; C/C=NORMAL FUNCTION ; RP016 ; ;À RP016 760$: CMPB #IO.CER!IQ.UMD&377,I.FCN(R1) ;IS IT READ CE CYLINDER ? ; PJC038 BEQ 770$ ;IF EQ YES ; PJC038 CMPB #IO.CEW!IQ.UMD&377,I.FCN(R1) ;IS IT WRITE CE CYLINDER ?; RP016 BEQ 770$ ;IF EQ YES ; PJC038 BIT #IQ.UMD,I.FCN(R1) ;IS IT A DIAGNOSTIC FUNCTION ? ; RP016 BEQ 770$ ;IF EQ NO ; PJC038 SEC ; ; RP016 RETURN ; ; RP016 770$: CLC ; ; PJC038 RETURN ; ; RP016 .DSABL LSB .END ÀÕ€˜kQ ›c, .TITLE DREXP .IDENT /03.15/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 03.15 ; ; T. J. MILLER 8-JUL-76 ; ; PREVIOUSLY MODIFIED BY: ; ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 25-JUL-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 27-AUG-79 ; MSH050 -- ALLOW RESIDENT OVERLAID TASKS TO REDUCE SIZE ; ; M. S. HARVEY 7-SEP-79 ; MSH053 -- RETURN DIFFERENT STATUS FOR EACH TYPE ERROR ; ; M. S. HARVEY 30-JAN-80 ; MSH086 -- EXTEND TASK REGION FROM TASK VIRTUAL ZERO, ; NOT FROM START OF MAPPED ARRAY AREA ; ; M. S. HARVEY 28-APR-80 ; MSH096 -- SUPPORT THE ALTERNATE HEADER REFRESH AREA ; ; M. S. HARVEY 15-SEP-80 ; MSH118 -- DON'T ASSEMBLE THIS DIRECTIVE FOR RSX-11S ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,HDRDF$,PCBDF$,TCBDF$ HWDDF$ ;DEFINE HARDWARE OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DREXP-EXTEND PARTITION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EXTEND THE PARTITION OF THE ; ISSUING TASK BY A POSITIVE OR NEGATIVE INCREMENT. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(89.),DPB SIZE(3.). ; WD. 01 -- EXTEND INCREMENT. ; WD. 02 -- RESERVED. ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE EXTEND INCREMENT IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF '+1' IS RETURNED. ; ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IF INSUFFICIENT DYNAMIC ;MSH053 ; MEMORY, OR INSUFFICIENT SPACE IN A SYSTEM ;MSH053 ; CHECKPOINT FILE. ;MSH053 ; DIRECTIVE STATUS OF 'D.RS8' IF TASK NOT IN SYSTEM CON- ; TROLLED PARTITION. ;MSH053 ; DIRECTIVE STATUS OF 'D.RS10' IF TASK IS NOT CHECK- ;MSH053 ; POINTABLE AND SPECIFIED A POSITIVE INCREMENT. ;MSH053 ; DIRECTIVE STATUS OF 'D.RS18' IF TASK HAS PREALLOCATED ;MSH053 ; CHECKPOINT SPACE AND IS EXTENDING GREATER THAN ;MSH053 ; INSTALLED SIZE. ;MSH053 ; DIRECTIVE STATUS OF 'D.RS83' IF TASK HAS I/O IN ;MSH053 ; PROGRESS. ;MSH053 ; DIRECTIVE STATUS OF 'D.RS84' IF SPECIFIED INCREMENT IS ;MSH053 ; INVALID. ;**-5 ;-  .IF DF D$$YNM&E$$XPR&M$$MGE&D$$ISK&C$$CKP ;MSH118 ;**-1 $DREXP::TSTB T.IOC(R5) ;TASK HAVE OUTSTANDING I/O? BEQ 7$ ;IF EQ NO ;MSH053 5$: DRSTS D.RS83 ;I/O IN PROGRESS FOR TASK ;MSH053 7$: MOV T.PCB(R5),R0 ;POINT TO TASK PCB ;MSH053 BIT #PS.SYS,P.STAT(R0) ;IS IT A SYSTEM CONTROLLED PARTITION?;**-12 BEQ 15$ ;IF EQ NO ;MSH053 MOV T.MXSZ(R5),R1 ;ASSUME RETURNING TO INSTALLED SIZE ;**-1 MOV (R3),R3 ;PICK UP SPECIFIED INCREMENT BEQ 10$ ;IF EQ DEFAULT TO INSTALLED SIZE  ADD P.SWSZ(R0),R3 ;CALCULATE NEW SIZE MOV R3,R1 ;COPY NEW SIZE 10$: CMP R1,P.SWSZ(R0) ;TASK INCREASING SIZE? BLOS 25$ ;IF LOS NO ;MSH046 BIT #T2.CHK!T2.CKD!T2.FXD,(R2) ;TASK CHECKPOINTABLE? ;**-3 BEQ 20$ ;IF EQ YES ;MSH053 DRSTS D.RS10 ;NOT CHECKPOINTABLE, CAN'T INCREASE SIZE;MSH053 15$: DRSTS D.RS8 ;NOT IN SYSTEM CONTROLLED PARTITION ;MSH053 20$: ;REF LABEL ;**-1 .IF DF D$$YNC BIT #T3.CAL,2(R2) ;TASK HAVE CHECKPOINT SPACE ALLOCATED? BEQ 30$ ;IF EQ NO .ENDC  CMP R1,T.MXSZ(R5) ;EXTENDING TO LARGER THAN INSTALLED SIZE? BLOS 30$ ;IF LOS NO ;MSH053 DRSTS D.RS18 ;EXTENDING TO LARGER THAN INSTALLED SIZE;MSH053 ;MSH046 25$: ; ;MSH046 ;MSH046 .IF DF A$$TRP&C$$CKP&T$$BUF ;MSH046 ;MSH046 TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O? ;MSH046 BNE 5$ ;IF NE YES, MIGHT WIPE OUT BUFFERS ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 30$: ; ;MSH096 ;MSH096 .IF DF P$$LAS!A$$HDR ;MSH096 ;MSH096 MOV R1,-(SP) ;SAVE NEW TASK REGION SIZE ;MSH096 ;MSH096 .IF DF P$$LAS ;MSH086 ;MSH086 SUB T.OFF(R5),R1 ;NORMALIZE TO TASK REGION ZERO ;MSH086 ;MSH096 .IFF ;MSH096 ;MSH096 BIT #T2.CHK,(R2) ;TASK HAVE ALTERNATE HEADER AREA? ;MSH096 BNE 32$ ;IF NE NO, NONCHECKPOINTABLE TASK ;MSH096 MOVB T.HDLN(R5),R2 ;GET LENGTH OF ALT. HEADER REFRESH AREA ;MSH096 SUB R2,R1 ;NORMALIZE TO TASK REGION ZERO ;MSH096 32$: ;MSH096 .ENDC ;MSH086 ;MSH086 .ENDC ;P$$LAS!A$$HDR ;MSH086 ;MSH086 CMP R1,$MXEXT ;NEW SIZE GREATER THAN MAXIMUM? ;MSH086 BHI 45$ ;IF HI YES ;MSH086 MOV R1,-(SP) ;COPY NEW SIZE FROM VIRTUAL ZERO ;MSH086 SWAB (SP) ;CONVERT SIZE TO BYTES ;**-2 RORB (SP) ; ROR (SP) ; ROR (SP) ; .IF DF P$$LAS CMP R1,#200 ;NEW SIZE GREATER THAN 4K? BHI 35$ ;IF HI YES .ENDC ;MSH050 ;**-1 CMP (SP),H.HDLN(R4) ;NEW TASK SIZE SMALLER THAN HEADER? BLO 45$ ;IF LO YES ;MSH086 35$: MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOW BLOCKS ;MSH050 MOV (R4)+,R2 ;PICK UP NUMBER OF WINDOW BLOCKS ;**-11 TST (R4)+ ;POINT TO TASK LOW VIRTUAL ADDRESS ;MSH050 .IF DF P$$LAS ;MSH050 ;MSH050 BIT #T3.ROV,T.ST3(R5) ;IS TASK RESIDENT OVERLAID? ;MSH050 BNE 42$ ;IF NE YES, KEEP WINDOW ZERO INTACT ;MSH050 ;MSH050 .ENDC ;MSH050 ;MSH050 MOV (R4),R3 ;PICK UP TASK LOW VIRTUAL ADDRESS  ASL R3 ;CONVERT TO 32W BLOCKS ROL R3 ; ROLB R3 ; SWAB R3 ; ADD R1,R3 ;CALC HIGH VIRTUAL ADDRESS IN 32W BLOCKS CMP R3,#2000 ;LEGAL SIZE? BHIS 90$ ;IF HIS NO ADD (R4),(SP) ;CALCULATE NEW TOP VIRTUAL ADDRESS 40$: DEC R2 ;MORE WINDOW BLOCKS TO GO? BLE 50$ ;IF LE NO ADD #W.BLGH,R4 ;POINT TO LOW VIRTUAL ADDRESS OF NEXT TST W.BSIZ-W.BLVR(R4) ;ESTABLISHED WINDOW? BEQ 40$ ;IF EQ NO .IF DF P$$LAS CMP -2(R4),R0 ;WINDOW MAPPED TO TASK REGION? (W.BPCB) BNE 44$ ;IF NE NO 42$: MOV 2(R4),R3 ;PICK UP HIGH VIRTUAL ADDRESS (W.BHVR) ;MSH050 SUB (R4),R3 ;CALCULATE LENGTH OF MAP - 1 (W.BLVR) ;**-1 INC R3 ;CALCULATE LENGTH OF MAP ASL R3 ;CONVERT TO 32W BLOCKS ROL R3 ; ROLB R3 ; SWAB R3 ; ADD W.BOFF-W.BLVR(R4),R3 ;CALCULATE LAST 32W BLOCK MAPPED ; (OFFSET FROM START OF TASK REGION) ;MSH086 CMP 2(SP),R3 ;WINDOW STILL BOUNDED BY REGION? ;MSH086 BLO 90$ ;IF LO NO, WINDOW ILLEGALLY MAPPED ;MSH086 44$: BIT #T3.ROV,T.ST3(R5) ;IS TASK RESIDENT OVERLAID? ;MSH050 BNE 40$ ;IF NE YES, UNCHANGED VIRTUAL ADDRESSING;MSH050 ;MSH050 .ENDC ;**-3 CMP (SP),(R4) ;VIRTUAL ADDRESS OVERLAP? (W.BLVR) ;MSH050 BLOS 40$ ;IF LOS NO ;**-2 45$: BR 90$ ;ILLEGAL SIZE 50$: TST (SP)+ ;CLEAN STACK ;MSH096 .IF DF P$$LAS!A$$HDR ;MSH096 ;MSH096 MOV (SP)+,R1 ;RESTORE NEW TASK REGION SIZE ;MSH096 ;MSH096 .ENDC ;MSH096 ;MSH096 MOV P.MAIN(R0),R2 ;POINT TO MAIN PARTITION PCB CMP R1,P.SIZE(R2) ;MAIN PARTITION LARGE ENOUGH? BHI 90$ ;IF HI NO MOV R1,P.SWSZ(R0) ;SET SWAP SIZE FOR TASK PARTITION CLR R4 ;INITIALIZE END OF HOLE CALCULATION MOV P.SUB(R0),R3 ;POINT TO NEXT SUBPAR AFTER TASK PAR BNE 60$ ;IF NE THERE IS ONE MOV R2,R3 ;ELSE POINT TO MAIN PARTITION ADD P.SIZE(R3),R4 ;CALCULATE END OF HOLE 60$: ADD P.REL(R3),R4 ; MOV P.REL(R0),R3 ;CALCULATE END OF DESIRED SPACE ADD R1,R3 ; CMP R3,R4 ;WILL EXTEND WORK IN PLACE? BLOS 70$ ;IF LOS YES CALL $SETRT ;FORCE RESCHEDULING MOV R5,R1 ;COPY TASK TCB ADDRESS .IF DF D$$YNC CALL $CHKPT ;ATTEMPT TO CHECKPOINT TASK TSTB T.STAT(R5) ;WAS THE CHECKPOINT INITIATED? (TS.CKP) ;MSH086 BPL 65$ ;IF PL NO ;MSH086 RETURN ; ;**-2 65$: MOV T.PCB(R5),R4 ;PICK UP TASK PCB ADDRESS MOV P.SIZE(R4),P.SWSZ(R4) ;RESET SWAP SIZE DRSTS D.RS1 ;POOL OR CHECKPOINT FILE ALLOC FAILURE .IFF CALLR $CHKPT ;INITIATE CHECKPOINT OF TASK .ENDC 70$: CMP R1,P.SIZE(R0) ;DECREASING TASK SIZE? ;**-1 BHIS 71$ ;IF HIS NO MOV #$NXTSK,-(SP) ;INSURE PARTITION WILL BE REALLOCATED 71$: MOV R1,P.SIZE(R0) ;EXTEND TASK IN PLACE .IF DF P$$LAS BIT #T3.ROV,T.ST3(R5) ;TASK HAVE RESIDENT OVERLAYS? BNE 80$ ;IF NE YES, DO NOT CHANGE MAPPING .ENDC MOV P.HDR(R0),R1 ;POINT TO TASK'S HEADER MOV H.WND(R1),R1 ;POINT TO NUMBER OF WINDOW BLOCKS MOVB W.BFPD+2(R1),R3 ;PICK UP FIRST PDR ADDRESS 74$: CLR (R3)+ ;UNMAP NEXT PDR DECB W.BNPD+2(R1) ;MORE TO GO? BNE 74$ ;IF NE YES CALL $MAPTK ;MAP TASK ADDRESS WINDOW MOV P.REL(R0),R3 ;CALCULATE FIRST APR OFFSET .IF DF P$$LAS!A$$HDR ;MSH096 ;**-1 ADD W.BOFF-W.BLPD(R1),R3 ; .ENDC MOV (R1),R2 ;PICK UP LAST PDR IMAGE MOVB -(R1),R4 ;PICK UP NUMBER OF PDR'S MOVB -(R1),R1 ;PICK UP FIRST PDR ADDRESS 75$: MOV R3,UISAR0-UISDR0(R1) ;LOAD NEXT APR MOVB R2,(R1)+ ;SET ACCESS NEXT PDR MOVB #177,(R1)+ ;SET SIZE NEXT PDR ADD #200,R3 ;ADVANCE APR BASE DEC R4 ;MORE TO GO? BNE 75$ ;IF NE YES MOV R2,-(R1) ;SET LAST PDR 80$: RETURN J ; 90$: DRSTS D.RS84 ;INVALID INCREMENT SPECIFIED .ENDC .END J× kQ ›c, .TITLE DRGCL .IDENT /03.11/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 03.11 ; ; D. N. CUTLER 20-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; ; MODIFIED BY: ; ; M. S. HARVEY 30-SEP-79 ; MSH066 -- BRING THE COMMENTS BACK UP TO SNUFF ; ; M. S. FOX 07-JAN-81 ; MF204 -- ADD GCCI$ DIRECTIVE ; ; M. S. FOX 03-FEB-81 ; MF210 -- ADD $SRCCQ ROUTINE TO SEARCH COMMAND QUEUE ; ; M. S. HARVEY 24-AUG-81 ; MSH186 -- CLI MUST ASSUME THE PROTECTION AND DEFAULT ; UICS OF THE TERMINAL ISSUING THE COMMAND ; IN CASE THE CLI WAS NOT ACTIVATED IN RESPONSE ; TO THE COMMAND ; ; M. S. HARVEY 10-SEP-81 ; MSH188 -- ALWAYS RETURN VALID PROTECTION UIC, REGARDLESS ; OF THE PRESENCE OF MULTI-USER PROTECTION ; ; M. S. HARVEY 14-SEP-81 ; MSH190 -- RETURN ERROR BEFORE CLI WITH ACTIVE GROUP ; GLOBAL CONTEXT IS FORCED TO CHANGE ITS GROUP ; ;+ ; **-$DRGCL-GET MCR/CLI COMMAND LINE ;MSH066 ; ;MSH066 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SEARCH FOR A CLI COMMAND ;MSH066 ; BUFFER AND TRANSFER IT BACK TO THE ISSUING TASK. ;MSH066 ; ;MSH066 ; TWO FORMS OF THIS DIRECTIVE ARE AVAILABLE. ONE FORM ALWAYS ASSUMES ;MSH066 ; THAT THE CLI IS MCR AND IF A COMMAND IS FOUND, IT IS TRANSFERED ;MSH066 ; TO THE ISSUING TASK VIA THE DPB. THE OTHER FORM, ONLY AVAILABLE TO ;MSH066 ; CLI TASKS, WILL TRANSFER THE COMMAND BACK TO A BUFFER WITHIN THE ;MSH066 ; TASK'S ADDRESS SPACE. ALSO, THE SECOND FORM CAN RETURN INFORMATION ;MSH066 ; ABOUT THE ISSUING TERMINAL. ;MSH066 ; ;MSH066 ; DPB FORMAT FOR GET MCR COMMAND: ;MSH066 ; ;MSH066 ; WD. 00 -- DIC(127.),DPB SIZE(41.). ;MSH066 ; WD. 01 -- FIRST WORD OF 80. BYTE BUFFER. ;MSH066 ; . ;MSH066 ; . ;MSH066 ; . ;MSH066 ; WD. 50 -- LAST WORD OF 80. BYTE BUFFER. ;MSH066 ; ; MF204 ; DPB FORMAT FOR GET CLI COMMAND: ; MF204 ; ; MF204 ; WD. 00 -- DIC(127.),DPB SIZE(7.). ; MF204 ; WD. 01 -- NO COMMAND PRESENT ACTION, HIGH BYTE RESERVED. ; MF204 ; WD. 02 -- ADDRESS OF COMMAND TO BE RETURNED. ; MF204 ; WD. 03 -- ADDRESS OF COMMAND BUFFER INSIDE TASK. ; MF204 ; WD. 04 -- LENGTH OF TASK'S COMMAND BUFFER. ; MF204 ; WD. 05 -- ADDRESS OF OPTIONAL INFORMATION BUFFER IN TASK. ; MF204 ; WD. 06 -- LENGTH OF TASK'S INFORMATION BUFFER. ; MF204 ;  ; MF204 ; INPUTS: ; MF204 ; ; MF204 ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; MF204 ; R3=ADDRESS OF THE SECOND WORD OF THE DPB. ; MF204 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; MF204 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; MF204 ; ; MF204 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; MF204 ; ; MF204 ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; MF204 ; DIRECTIVE STATUS OF +1 IS RETURNED IF A COMMAND HAS ; MF204 ; BEEN SUCCESSFULLY RETURNED TO THE CLI ; MF204 ; DIRECTIVE STATUS OF 'D.RS00' IS RETURNED IF NO COMMAND ; MF204 ; IS QUEUED FOR THE CLI, AND THE CLI INDICATED ; MF204 ; THAT IT WANTED TO BE STOPPED. THE CLI WILL GET ; MF204 ; THIS STATUS AFTER IT IS UNSTOPPED. ; MF204 ; C=1 IF DIRECTIVE IS REJECTED. ; MF204 ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF AN ILLEGAL ; MF204 ; DPB SIZE IS SPECIFIED. ; MF204 ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF EITHER ; MF204 ; BUFFER OR THE DPB ARE NOT ENTIRELY WITHING ; MF204 ; THE TASK'S ADDRESS SPACE. ; MF204 ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THERE IS ; MF204 ; NO MCR COMMAND FOR THE ISSUING TASK, OR IF ; MF204 ; A GCCI$ WITH STOP ON NO COMMAND OPTION WAS ISSUE; MF204 ; FROM AST STATE ; MF204 ; DIRECTIVE STATUS OF 'D.RS17' IS RETURNED IF THE ;MSH190 ; ISSUING CLI TASK ATTEMPTED TO RECEIVE A COMMAND ;MSH190 ; FROM A TERMINAL WITH A DIFFERENT PROTECTION ;MSH190 ; GROUP FROM THE CLI'S CURRENT GROUP (WHICH CAUSES;MSH190 ; THE CLI TO ASSUME THE TERMINAL'S GROUP) AND ;MSH190 ; THE TASK HAD ACTIVE GROUP GLOBAL CONTEXT FOR ;MSH190 ; THE FORMER GROUP. ;MSH190 ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF A TASK ; MF204 ; WHICH IS NOT A CLI ATTEMPTED TO GET A CLI ; MF204 ; COMMAND LINE. ; MF204 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED FROM A GCCI$ ; MF204 ; DIRECTIVE IF THERE IS NO COMMAND QUEUED FOR THE ; MF204 ; CLI, AND THE TASK WANTED AN ERROR RETURNED IN ; MF204 ; THIS CASE. ; MF204 ;- ;**-30 .IF DF M$$CRX .ENABL LSB $DRGCL:: ; MF204 ; MF204 .IF DF A$$CLI ; MF204 ; MF204 MOVB -(R3),R0 ;GET THE DPB SIZE OF THIS DIRECTIVE ; MF204 CMPB (R3)+,#41. ;GET MCR COMMAND DIRECTIVE? ; MF204 BEQ 5$ ;IF EQ YES ; MF204 CMPB R0,#7. ;GET CLI COMMAND DIRECTIVE? ; MF204 BEQ GCCI ;IF EQ YES ; MF204 DRSTS D.RS99 ;ILLEGAL DPB SIZE ; MF204 5$: ;REFERENCE LABEL ; MF204 ; MF204 .ENDC ;A$$CLI ; MF204 ; MF204 ; MF204 CALL 30$ ;SEARCH FOR TASK COMMAND BUFFER ; MF204 BCC 10$ ;IF CC ONE FOUND ;**-1 DRSTS D.RS80 ;SET DIRECTIVE STATUS 10$: CMP (R0)+,(R0)+ ;POINT TO COMMAND TEXT 20$: INC 2(SP) ;INCREMENT BYTE COUNT MOVB (R0),(R3) ;INSERT BYTE INTO USER BUFFER CMPB #33,(R0)+ ;ALTMODE TERMINATOR? BEQ 25$ ;IF EQ YES CMPB #15,(R3)+ ;CARRIAGE RETURN? BNE 20$ ;IF NE NO 25$: SUB #2,2(SP) ;ADJUST TO PROPER BYTE COUNT ;+ ; **-$RLMCB-RELEASE MCR COMMAND BUFFER ; ; INPUTS: ; ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: ; ; IF THERE IS A COMMAND BUFFER IN THE LIST FOR THE CURRENT ;MSH066 ; TASK, THEN IT IS REMOVED FROM THE LIST AND DEALLOCATED. ;MSH066 ;- ;**-3 $RLMCB::CALL 30$ ;SEARCH FOR TASK COMMAND BUFFER BCS 50$ ;IF CS NONE FOUND MOV (R0),(R1) ;REMOVE BUFFER FROM LIST MOV #84.,R1 ;SET LENGTH OF BUFFER TO RELEASE CALLR $DEACB ;DEALLOCATE BUFFER ; ; SUBROUTINE TO SEARCH FOR COMMAND BUFFER FOR CURRENT TASK ; 30$: MOV #$MCRCB,R0 ;POINT TO COMMAND BUFFER LISTHEAD CALLR $SRCCQ ;SEARCH FOR COMMAND ; MF210 50$: RETURN ; MF210 ; MF204 ;+ ; MF204 ; **-$RLCIB-RELEASE ALL COMMANDS FOR A CLI TASK ; MF204 ; ; MF204 ; INPUTS: ; MF204 ; ; MF204 ; R5=ADDRESS OF TCB OF THE CURRENT TASK (ALWAYS A CLI) ; MF204 ; ; MF204 ; OUTPUTS: ; MF204 ; ; MF204 ; ALL COMMAND BUFFERS IN THE $CLICQ LIST FOR THIS CLIS ; MF204 ; ARE REMOVED FROM THE LIST AND DEALLOCATED ; MF204 ; ; MF204 ;- ; MF204 ; MF204 .IF DF A$$CLI ; MF204 ; MF204 $RLCIB::MOV $CLICQ,R1 ;POINT TO FIRST ENTRY ; MF204 BEQ 50$ ;IF EQ, LIST EMPTY ; MF204 TST 2(R1) ;IS THERE A ELIMINATE ALL PACKET ; MF204 BNE 60$ ;IF NE NO ; MF204 CALL ELIMCD ;PROCESS IT ; MF204 60$: MOV #$CLICQ,R0 ;POINT TO LISTHEAD ; MF204 CALL $SRCCQ ;SEARCH FOR A COMMAND ; MF204 BCS 50$ ;IF CS, NO COMMANDS LEFT ; MF204 MOV R0,R1 ;COPY COMMAND BUFFER ADDRESS ; MF204 CALL ELIMCD ;ELIMINATE COMMAND ; MF204 BR 60$ ;TRY FOR ANOTHER ONE ; MF204 .DSABL LSB ; MF204 ; MF204 ; ; MF204 ; THE FOLLOWING CODE EXECUTES THE GCCI$ DIRECTIVE ; MF204 ; ; MF204 ; THIS DIRECTIVE CAN ONLY BE ISSUED BY CLI TASKS ON SYSTEMS THAT SUPPORT; MF204 ; ALTERNATE CLIS (A$$CLI). IT COPIES A COMMAND BUFFER FROM THE POOL INTO; MF204 ; THE CLI TASK, AND EITHER DEALLOCATES IT OR LEAVES IT QUEUED FOR ; MF204 ; RETREIVAL BY A SUBSEQUENT GCCI$ DIRECTIVE AT THE CLI'S OPTION. ; MF204 ; IT CAN ALSO FILL IN AN INFORMATION BUFFER IN THE CLI WITH DATA ; MF204 ; ABOUT THE TERMINAL AND TASK FROM WHICH THE COMMAND ORIGINATED. ; MF204 ; ; MF204 ; THE FORMAT OF THE COMMAND BUFFER IN THE POOL IS SHOWN BELOW. THE ; MF204 ; LISTHEAD IS AT $CLICQ. ; MF204 ; ; MF204 ; +---------------------------------------+ ; MF204 ; ! LINK ! ; MF204 ; !---------------------------------------!  ; MF204 ; ! TCB ADDR OF CLI TO RECEIVE CMD ! ; MF204 ; !---------------------------------------! ; MF204 ; ! UCB ADDR OF ISSUING TERMINAL ! OR ZERO ON SYSTEM MESS; MF204 ; !---------------------------------------! ; MF204 ; ! SIZE OF THIS BUFFER IN POOL ! ; MF204 ; !---------------------------------------! ; MF204 ; ! STATUS ! TERMINATOR ! ZERO ON SYSTEM MESSAGE; MF204 ; !---------------------------------------! ; MF204 ; ! ! ; MF204 ; ! COMMAND TEXT IN ASCII ! ; MF204 ; ! ! ; MF204 ; ! ! ; MF204 ; +---------------------------------------+ ; MF204 ; ; MF204 ; THE SYSTEM MESSAGE THAT RESULTS FROM A CLI /ELIM=* COMMAND ; MF204 ; (ELIMINATE ALL CLIS FOR SYSTEM SHUTDOWN) HAS A DIFFERENT FORMAT. ; MF204 ; THE TCB ADDRESS FIELD IS ZERO, SINCE ONE PACKET IS USED FOR ALL ; MF204 ; CLIS THAT HAVE THE CP.MSG ATTRIBUTE. THE TEXT PART OF THE PACKET ; MF204 ; IS VARIABLE LENGTH, AND CONTAINS A LIST OF TCB ADDRESSES THAT SHOULD ; MF204 ; RECEIVE IT. THE NUMBER OF TCB ADDRESS INITIALLY PRESENT IS AT OFFSET ; MF204 ; 12 FROM THE BEGINNING. THIS IS USED IN DETERMINING THE NUMBER OF ; MF204 ; WORDS TO SCAN TO DETERMINE IF THE CURRENT CLI SHOULD GET THIS PACKET. ; MF204 ; OFFSET 14 CONTAINS A COUNT WHICH IS DECREMENTED EVERY TIME THIS ; MF204 ; PACKET IS GIVEN TO A CLI. THE WORD CONTAINING THE TCB ADDRESS FOR ; MF204 ; THIS CLI IS THEN CLEARED SO IT WILL NOT SEE THIS PACKET AGAIN. ; MF204 ; WHEN THIS COUNT GOES TO ZERO, THE PACKET IS DEALLOCATED. ; MF204 ; ; MF204 ; THE FORMAT OF THE COMMAND BUFFER SET UP IN THE CLI TASK SPACE IS: ; MF204 ; ; MF204 ; +---------------------------------------+ ; MF204 ; ! ASCII DEV NAME OF ISSUING TTY ! ; MF204 ; !---------------------------------------! ; MF204 ; ! NUM OF CHAR RETURNED ! OCTAL UNIT NUM.! ; MF204 ; !---------------------------------------! ; MF204 ; ! COMMAND SIZE ! ; MF204 ; !---------------------------------------! ; MF204 ; ! STATUS ! TERMINATOR ! ; MF204 ; !---------------------------------------! ; MF204 ; ! ! ; MF204 ; ! COMMAND TEXT IN ASCII ! ; MF204 ; ! ! ; MF204 ; +---------------------------------------+ ; MF204 ; ; MF204 ; ; MF204 ; THE FORMAT OF THE INFORMATION BUFFER IN THE CLI TASK SPACE IS: ; MF204 ; ; MF204 ; +---------------------------------------+ ; MF204 ; ! U.CW2 OF ISSUING TERMINAL ! ; MF204 ; !---------------------------------------! ; MF204 ; ! NAME OF PARENT TASK (IF ANY) ! ; MF204 ; ! (2 WORDS) ! ; MF204 ; !---------------------------------------! ; MF204 ; ! ADDRESS OF OCB FROM PARENT ! ; MF204 ; !---------------------------------------! ; MF204 ; ! LOGIN UIC OF ISSUING TERMINAL ! ; MF204 ; !---------------------------------------! ; MF204 ; ! CURRENT UIC OF ISSUING TERMINAL ! ; MF204 ; !---------------------------------------! ; MF204 ; ! ADDR OF CMD. IF NOT DEQUEUED ! ; MF204 ; +---------------------------------------+ ; MF204 ; ; MF204 ; EXTRA FIELDS CAN BE ADDED TO THE END OFF THIS BUFFER IF REQUIRED, BECA; MF204 ; THE TASK SUPPLIES BOTH THE ADDR AND LENGTH OF ITS TASK BUFFER. ONLY ; MF204 ; THAT MUCH DATA IS COPIED BACK TO THE TASK. THE TASK BUFFER IS FILLED ; MF204 ; FROM THE FRONT WITH THE FIELDS IN THE ABOVE ORDER. IF THE BUFFER ; MF204 ; IS NOT LONG ENOUGH TO HOLD ALL OF THE DATA, THE FIELDS THAT WOULD ; MF204 ; NOT FIT ARE NOT SUPPLIED, BUT NO INDICATION OF THIS DATA TRUNCATION ; MF204 ; IS GIVEN TO THE TASK. THUS IF MORE FIELDS ARE ADDED IN A FUTURE RELEAS; MF204 ; OLD TASKS WOULD STILL WORK SINCE THEY WILL GET EXACTLY WHAT THEY GOT ; MF204 ; BEFORE, THEY JUST WOULD NOT GET THE NEW DATA. ; MF204 ; ; MF204 ; MF204 .ENABL LSB ; MF204 GCCI: BIT #T3.CLI,T.ST3(R5) ;IS TASK A CLI ; MF204 BNE 100$ ;IF NE YES ; MF204 DRSTS D.RS16 ;SET DIRECTIVE STATUS ; MF204 100$: MOV (R3)+,-(SP) ;SAVE NO CMD ACTION ; MF204 TST T.ST2(R5) ;TASK AT AST STATE?? ; MF204 BPL 103$ ;IF PL NO ; MF204 BIT #2,(SP) ;IS STOP ON NO COMMAND OPTION SPECIFIED ; MF204 BEQ 103$ ;IF EQ NO ; MF204 DRSTS D.RS80 ;SET DIRECTIVE STATUS ; MF204 103$: MOV (R3)+,R4 ;SAVE DESIRED CMD ADDR ; MF204 MOV (R3)+,R0 ;GET CMD BUFFER ADDRESS ; MF204 BNE 110$ ;IF NE, THERE IS A BUFFER ; MF204 105$: DRSTS D.RS98 ;SET DIRECTIVE STATUS ; MF204 110$: MOV (R3)+,R1 ;GET LENGTH ; MF204 CMP #11,R1 ;IS IT ABOVE MINIMUM LENGTH ; MF204 BHI 105$ ;IF HI NO ; MF204 MOV R1,-(SP) ;SAVE LENGTH OF TASK CMD BUFFER ; MF204 MOV R0,-(SP) ;SAVE ADDRESS OF TASK CMD BUFFER ; MF204 CALL $ACHKW ;ADDRESS CHECK COMMAND BUFFER ; MF204 CLR R2 ;ASSUME NO INFO BUFFER ; MF204 MOV (R3)+,R0 ;GET INFO BUFFER ADDRESS ; MF204 BEQ 120$ ;IF EQ, NO BUFFER ; MF204 MOV (R3)+,R1 ;GET INFO BUFFER LENGTH ; MF204 BMI 105$ ;IF MI, ILLEGAL LENGTH ; MF204 MOV R1,R3 ;SAVE BUFFER LENGTH ; MF204 CALL $ACHKW ;ADDRESS CHECK INFO BUFFER ; MF204 CALL $RELOC ;RELOCATE INFO BUFFER ADDRESS ; MF204 MOV R1,KISAR6 ;MAP INFO BUFFER ; MF204 120$: MOV #$CLICQ,R0 ;POINT TO COMMAND LISTHEAD ; MF204 MOV (R0),R1 ;POINT TO FIRST PACKET IN LIST ; MF204 BEQ 130$ ;IF EQ, LIST EMPTY ; MF204 TST 2(R1) ;IS THIS AN ELIMINATE ALL? ; MF204 BNE 130$ ;IF NE NO ; MF204 ADD #12,R1 ;POINT TO NUMBER OF TCB COUNT ; MF204 MOV (R1)+,R4 ;GET NUMBER OF SLOTS ; MF204 TST (R1)+ ;SKIP OVER REMAINING TCB COUNT ; MF204 125$: CMP R5,(R1)+ ;DOES CURRENT CLI GET THIS PACKET ; MF204 BEQ 137$ ;IF EQ YES  ; MF204 DEC R4 ;MORE SLOTS TO CHECK ; MF204 BNE 125$ ;IF NE YES ; MF204 130$: CALL $SRCCQ ;FIND A COMMAND FOR THIS CLI ; MF204 BCC 140$ ;IF CC, FOUND ONE ; MF204 ; ; MF204 ; NO COMMAND EXISTS FOR THIS CLI ; MF204 ; ; MF204 CMP (SP)+,(SP)+ ;CLEAN STACK ; MF204 MOV (SP)+,R0 ;GET DESIRED ACTION CODE ; MF204 BEQ 135$ ;IF EQ, RETURN ERROR ; MF204 ASR R0 ;FORCE TASK TO EXIT?? ; MF204 BCS 133$ ;IF CS YES ; MF204 ASR R0 ;FORCE TASK TO STOP ; MF204 BCC 135$ ;IF CC NO, RETURN ERROR ; MF204 CALL $STPCT ;STOP THE TASK ; MF204 DRSTS D.RS00 ;SET IS.CLR ; MF204 133$: JMP $DREXT ;FORCE THE TASK TO EXIT ; MF204 135$: DRSTS D.RS8 ;SET ERROR CONDITION ; MF204 ; ; MF204 ; FIND A COMMAND FOR THE CLI ; MF204 ; ; MF204 137$: MOV (R0),R0 ;POINT TO ELIMINATE ALL PACKET ; MF204 BR 190$ ;USE IT ; MF204 ; ; MF204 140$: CMP R4,R0 ;IS IT THE DESIRED ONE? ; MF204 BEQ 150$ ;IF EQ YES ; MF204  TST R4 ;TAKE ANY ONE? ; MF204 BNE 130$ ;IF NE NO ; MF204 150$: MOV 4(R0),R4 ;GET ADDRESS OF ISSUING TERMINAL UCB ;MSH186 BEQ 155$ ;IF EQ BUFFER IS A MESSAGE ;MSH186 MOV $HEADR,R1 ;POINT TO CLI TASK'S HEADER ;MSH186 ;MSH190 .IF DF G$$EFN ;MSH190 ;MSH190 TSTB T.GGF(R5) ;TASK HAVE ACTIVE GROUP GLOBAL CONTEXT? ;MSH190 BEQ 152$ ;IF EQ NO ;MSH190 ;MSH190 .IF DF M$$MUP ;MSH190 ;MSH190 CMPB U.LUIC+1(R4),H.CUIC+1(R1) ;WILL TASK CHANGE GROUP? ;MSH190 ;MSH190 .IFF ;MSH190 ;MSH190 CMPB U.UIC+1(R4),H.CUIC+1(R1) ;WILL TASK CHANGE GROUP? ;MSH190 ;MSH190 .ENDC ;MSH190 ;MSH190 BEQ 152$ ;IF EQ NO, ALLOW COMMAND RECEPTION ;MSH190 DRSTS D.RS17 ;CLI TASK HAS GRP GBL CONTEXT ACTIVE ;MSH190 152$: ; ;MSH190 .ENDC ;G$$EFN ;MSH190 ;MSH186 .IF DF M$$MUP ;MSH186 ;MSH186 MOV U.LUIC(R4),H.CUIC(R1) ;ESTABLISH PROTECTION UIC ;MSH186 ;MSH186 .IFF ;MSH186 ;MSH186 MOV U.UIC(R4),H.CUIC(R1) ;ESTABLISH PROTECTION UIC ;MSH186 ;MSH186 .ENDC ;MSH186 ;MSH186 MOV U.UIC(R4),H.DUIC(R1) ;ESTABLISH DEFAULT UIC ;MSH186 155$: TST R2 ;INFO BUFFER PRESENT ;MSH186 BEQ 190$ ;IF EQ NO ; MF204 ; ; MF204 ; FILL INFORMATION BUFFER IN TASK SPACE; ; MF204 ; ; MF204 ASR R3 ;CONVERT TO WORD COUNT ; MF204 BCS 105$ ;IF CS, LENGTH IS NOT EVEN ; MF204 BEQ 190$ ;IF EQ, BUFFER HAS LENGTH ZERO ; MF204 TST R4 ;IS THIS A MESSAGE BUFFER? ;MSH186 BEQ 190$ ;IF EQ, BUFFER IS A MESSAGE SO IGNORE IN; MF204 MOV U.CW2(R4),(R2)+ ;GET U.CW2 ; MF204 SUB #3,R3 ;ARE THERE 3 WORDS LEFT IN INFO BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 ; MF204 ; MF204 .IF DF P$$OFF ; MF204 ; MF204 MOV T.OCBH(R5),R1 ;POINT TO OCB LIST ; MF204 BR 164$ ; ; MF204 160$: MOV (R1),R1 ;POINT TO NEXT OCB ; MF204 164$: BEQ 170$ ;IF EQ, END OF OCB LIST ; MF204 CMP O.MCRL(R1),R0 ;IS THIS OCB FOR THIS COMMAND ; MF204 BNE 160$ ;IF NE NO ; MF204 MOV O.STAT(R1),(R2)+ ;COPY FIRST HALF OF PARENT NAME ; MF204 MOV O.STAT+2(R1),(R2)+ ;COPY SECOND HALF OF PARENT NAME ; MF204 DEC R3 ;ANOTHER WORD IN BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 MOV R1,(R2)+ ;SAVE OCB ADDRESS ; MF204 BR 180$ ; ; MF204 ; MF204 .ENDC ; MF204 ; MF204 ; MF204 170$: CLR (R2)+ ;CLEAR PARENT NAME FIELD ; MF204 CLR (R2)+ ; ; MF204 DEC R3 ;ANOTHER WORD IN BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 CLR (R2)+ ;CLEAR OCB ADDRESS FIELD ; MF204 180$: DEC R3 ;ANOTHER WORD IN BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 ; MF204 ; MF204 .IF DF M$$MUP ; MF204 ; MF204 MOV U.LUIC(R4),(R2)+ ;COPY PROTECTION UIC ; MF204 ; MF204 .IFF ;M$$MUP ; MF204 ; MF204 MOV U.UIC(R4),(R2)+ ;ESTABLISH PROTECTION UIC ;MSH188 ; MF204  .ENDC ; MF204 ; MF204 ; MF204 DEC R3 ;ROOM LEFT IN BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 MOV U.UIC(R4),(R2)+ ;COPY CURRENT UIC CODE ; MF204 DEC R3 ;ROOM LEFT IN BUFFER ; MF204 BLT 190$ ;IF LT NO ; MF204 CLR (R2) ;ASSUME DO NOT SUPPLY COMMAND ADDRESS ; MF204 TSTB 4(SP) ;IS COMMAND TO BE DEQUEUED ; MF204 BPL 190$ ;IF PL YES ; MF204 MOV R0,(R2) ;SUPPLY ADDRESS OF COMMAND BUFFER ; MF204 ; ; MF204 ; COPY COMMAND FROM POOL INTO THE TASK'S BUFFER ; MF204 ; ; MF204 190$: BIC #T3.MCR,T.ST3(R5) ;ASSUME CLI SHOULD NOT PROMPT ON EXIT ; MF204 MOV R0,R5 ;COPY POINTER TO BUFFER IN POOL ; MF204 CMP (R5)+,(R5)+ ;SKIP LINK AND TCB ADDRESS ; MF204 MOV (SP)+,R0 ;GET ADDRESS OF BUFFER IN TASK ; MF204 CALL $RELOC ;RELOCATE BUFFER ADDRESS ; MF204 MOV R1,KISAR6 ;MAP BUFFER ; MF204 MOV R2,R4 ;SAVE DESTINATION DISPLACEMENT ; MF204 MOV R1,R3 ;SAVE APR BIAS ; MF204 ADD #10,R4 ;POINT TO WHERE COMMAND WILL START ; MF204 MOV (R5)+,R0 ;GET UCB THAT ISSUED COMMAND ; MF204 BEQ 200$ ;IF EQ, BUFFER IS A SYSTEM MESSAGE ; MF204 MOV (R0),R1 ;POINT TO DCB ; MF204 TST (R1)+ ;POINT TO ADDRESS OF FIRST UCB ; MF204 SUB (R1)+,R0 ;CALC RELATIVE ADDRESS OF UCB ; MF204 MOV (R1)+,(R2)+ ;COPY DEVICE NAME ; MF204 MOV (R1)+,(R2) ;GET LOW UNIT NUMBER FOR DCB ; MF204 MOV (R1),R1 ;GET LENGTH OF UCB ; MF204 CALL $DIV ;CALC RELATIVE UNIT NUMBER ; MF204 ADD R0,(R2)+ ;CALC LOGICAL UNIT NUMBER IN LOW BYTE ; MF204 BR 210$ ; ; MF204 200$: CLR (R2)+ ;ZERO TO INDICATE MESSAGE ; MF204 MOV (R5),(R2) ;COPY MESSAGE CODE ; MF204 SWAB (R2)+ ;PUT CODE IN LOW BYTE IN USER BUFFER ; MF204 CLR 2(SP) ;FORCE MESSAGE BUFFER TO BE DEQUEUED ; MF204 TST -4(R5) ;IS MESSAGE AN ELIMINATE ALL ; MF204 BNE 210$ ;IF NE NO ; MF204 CLR R1 ;DO NOT RETURN ANY TEXT ; MF204 TST (R5)+ ;SKIP SIZE WORD IN BUFFER ; MF204 BR 214$ ; ; MF204 210$: MOV (R5)+,R1 ;GET SIZE OF BUFFER IN POOL ; MF204 SUB #12,R1 ;GET NUMBER OF CHARACTERS TO COPY ; MF204 BIC #177400,R1 ;CLEAR HIGH BYTE ; MF204 214$: MOV (SP)+,R0 ;GET LENGTH OF TASK'S BUFFER ; MF204 SUB #10,R0 ;CALC SPACE AVAILABLE FOR COMMAND ; MF204 CLR -(SP) ;ASSUME LENGTHS WILL BE CORRECT ; MF204 CMP R0,R1 ;COMPARE SIZE OF POOL AND TASK BUFFERS ; MF204 BLO 220$ ;IF LO, USE TASK BUFFER SIZE ; MF204 MOV R1,R0 ;USE POOL BUFFER SIZE ; MF204 MOV #400,(SP) ;HAVE TO DECREMENT COUNT IN UPPER BYTE ; MF204 220$: MOVB R0,-1(R2) ;PUT ACTUAL COUNT IN TASK BUFFER ; MF204 MOV R1,(R2)+ ;PUT BUFFER SIZE IN TASK BUFFER ; MF204 TST -10(R4) ;SYSTEM MESSAGE? ; MF204 BEQ 230$ ;IF EQ YES ; MF204 DEC -2(R2) ;REMOVE TERMINATOR FROM BUFFER SIZE ; MF204 SUB (SP),-4(R2) ;POSSIBLY DECREMENT SUPPLIED CHAR COUNT ; MF204 230$: TST (SP)+ ;CLEAN STACK ; MF204 MOV (R5)+,(R2) ;INSERT TERMINATOR AND STATUS BYTE ; MF204 TST R0 ;ANY CHARACTERS TO COPY ; MF204 BEQ 240$ ;IF EQ NO ; MF204 MOV R5,R2 ;POINT TO START OF CMD TEXT IN POOL ; MF204 CALL $BLXIO ;COPY COMMAND INTO TASK'S BUFFER ; MF204 240$: SUB #6,R5 ;POINT TO UCB ADDRESS IN POOL BUFFER ; MF204 TST (R5)+ ;IS THIS A SYSTEM MESSAGE ; MF204 BEQ 250$ ;IF EQ YES ; MF204 CMP #13,(R5) ;DOES PACKET JUST CONTAIN A TERMINATOR ; MF204 BEQ 250$ ;IF EQ YES, NEVER PROMPT ; MF204 CMPB #33,2(R5) ;IS TERMINATOR AN ESCAPE ; MF204 BEQ 250$ ;IF EQ YES ; MF204 MOV $TKTCB,R1 ;POINT TO CURRENT TASKS TCB ; MF204 BIS #T3.MCR,T.ST3(R1) ;FORCE PROMPT ON EXIT ; MF204 250$: SUB #6,R5 ;POINT TO START OF POOL BUFFER ; MF204 TSTB (SP)+ ;LEAVE POOL BUFFER QUEUED ; MF204 BMI 310$ ;IF MI YES ; MF204 260$: MOV R5,R1 ;POINT TO BUFFER IN POOL ; MF204 ELIMCD: MOV #$CLICQ,R0 ;POINT TO COMMAND QUEUE LISTHEAD ; MF204 TST 2(R1) ;ELIMINATE ALL PACKET? ; MF204 BNE 280$ ;IF NE NO ; MF204 ADD #12,R1 ;POINT TO SLOT COUNT ; MF204 MOV (R1)+,R2 ;GET NUMBER OF SLOTS ; MF204 TST (R1)+ ;SKIP REMAINING TCB COUNT ; MF204 270$: CMP $TKTCB,(R1)+ ;DOES THIS CLI GET THE ELIMINATE ALL ; MF204 BEQ 300$ ;IF EQ YES ; MF204 DEC R2 ;ANOTHER SLOT TO CHECK ; MF204 BGT 270$ ;IF GT YES ; MF204 RETURN ; MF204 280$: CALL $QRMVT ;DEQUEUE BUFFER ; MF204 MOV R1,R0 ;POINT TO BUFFER AGAIN ; MF204 MOV 6(R1),R1 ;GET LENGTH OF BUFFER ; MF204 TST 4(R0) ;DOES BUFFER CONTAIN A SYSTEM MESSAGE ; MF204 BNE 290$ ;IF NE NO ; MF204 BIC #177400,R1 ;CLEAR OUT MESSAGE CODE ; MF204 290$: CALLR $DEACB ;DEALLOCATE IT ; MF204 300$: CLR R-(R1) ;CLEAR POINTER TO TCB ; MF204 MOV (R0),R1 ;POINT TO PACKET AGAIN ; MF204 DEC 14(R1) ;DECREMENT REMAINING TCB COUNT ; MF204 BEQ 280$ ;IF EQ, ALL TCBS HAVE SEEN PACKET ; MF204 310$: RETURN ; MF204 ; MF204 .ENDC ;A$$CLI ; MF204 ; MF204 .DSABL LSB ;**-7 .ENDC .END R×hLkQ ›c, .TITLE DRGLI .IDENT /07.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 07.00 ; ; D. N. CUTLER 18-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; ; MODIFIED BY: ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ;+ ; **-$DRGLI-GET LUN INFORMATION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO FILL A SIX WORD BUFFER WITH ; INFORMATION ABOUT A DEVICE THAT IS ASSIGNED TO A SPECIFIED LUN. IF RE- ; QUESTS TO THE DEVICE HAVE BEEN RE-DIRECTED, THEN THE INFORMATION RETURN- ; ED PERTAINS TO THE RE-DIRECT DEVICE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(5.),DPB SIZE(3.). ; WD. 01 -- LUN TO RETURN INFORMATION FOR. ; WD. 02 -- ADDRESS OF A SIX WORD BUFFER. ; ; BUFFER FORMAT: ; ; WD. 00 -- NAME OF ASSIGNED DEVICE. ; WD. 01 -- UNIT NUMBER OF ASSIGNED DEVICE AND FLAGS BYTE. ; WD. 02 -- FIRST DEVICE CHARACTERISTICS WORD. ; WD. 03 -- SECOND DEVICE CHARACTERISTICS WORD. ; WD. 04 -- THIRD DEVICE CHARACTERISTICS WORD. ; WD. 05 -- FOURTH DEVICE CHARACTERISTICS WORD. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LUN IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS5' IS RETURNED IF NO DEVICE ; IS ASSIGNED TO THE SPECIFIED LUN. ;- $DRGLI::CALL $MPLUN ;MAP LUN TO UCB ADDRESS BCS 10$ ;IF CS NO DEVICE ASSIGNED MOV R0,R4 ;SAVE ADDRESS OF DEVICE UCB MOV (R3),R3 ;GET ADDRESS OF BUFFER .IF DF A$$CHK!M$$MGE MOV #6*2,R1 ;SET LENGTH OF BUFFER CALL $ACHKP ;ADDRESS CHECK BUFFER .ENDC MOV (R4),R2 ;GET ADDRESS OF DEVICE DCB TST (R2)+ ;POINT TO ADDRESS OF FIRST UCB MOV R4,R0 ;COPY ADDRESS OF UCB SUB (R2)+,R0 ;CALCULATE RELATIVE ADDRESS OF UCB MOV (R2)+,(R3)+ ;INSERT GENERIC DEVICE NAME MOV (R2)+,(R3) ;PICK UP LOW UNIT NUMBER FOR DCB MOV (R2)+,R1 ;PICK UP UCB LENGTH CALL $DIV ;CALCULATE RELATIVE UNIT NUMBER ADD R0,(R3)+ ;CALCULATE LOGICAL UNIT NUMBER MOVB #200,-(R3) ;ASSUME RESIDENT DRIVER .IF DF L$$DRV TST (R2) ;DRIVER RESIDENT? BNE 5$ ;IF NE YES CLRB (R3) ;ELSE INDICATE DRIVER IS NONRESIDENT 0 .ENDC 5$: INC R3 ;ADVANCE POINTER ADD #U.CW1,R4 ;POINT TO FIRST CHARACTERISTICS WORD MOV (R4)+,(R3)+ ;INSERT DEVICE CHARACTERISTICS WORDS MOV (R4)+,(R3)+ ; MOV (R4)+,(R3)+ ; MOV (R4),(R3) ; RETURN ;RETURN DIRECTIVE STATUS OF +1 10$: DRSTS D.RS5 ;SET DIRECTIVE STATUS .END 0×€fkQ ›c, .TITLE DRGPP .IDENT /06.06/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 06.06 ; ; D. N. CUTLER 3-JAN-74 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 1-JUL-80 ; MSH096 -- IGNORE ALTERNATE HEADER REFRESH AREA WHEN ; RETURNING PARTITION PARAMETERS ; ; M. S. HARVEY 23-JUL-81 ; MSH182 -- RETURN CORRECT VIRTUAL STARTING ADDRESS ; FOR THE TASK REGION ; ; MACRO LIBRARY CALLS ; .MCALL PCBDF$,TCBDF$ PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRGPP-GET PARTITION PARAMETERS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO FILL A THREE WORD BUFFER WITH ; PARTITION PARAMETERS. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(65.),DPB SIZE(4.). ; WD. 01 -- FIRST HALF OF OPTIONAL PARTITION NAME. ; WD. 02 -- SECOND HALF OF OPTIONAL PARTITION NAME. ; WD. 03 -- ADDRESS OF A THREE WORD BUFFER. ; ; BUFFER FORMAT: ; ; WD. 00 -- BASE ADDRESS OF PARTITION IN 32W BLOCKS. ; WD. 01 -- SIZE OF PARTITION IN 32W BLOCKS. ; WD. 02 -- PARTITION FLAGS WORD. ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ;MSH096 ; R3=ADDRESS OF THE PARTITION NAME IN THE DPB. ;**-1 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS EQUAL TO THE STARTING VIRTUAL ADDRESS ; OF THE SPECIFIED PARTITION IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF SPECIFIED ; PARTITION IS NOT IN SYSTEM. ;- .IF DF G$$TPP $DRGPP:: ; ;MSH182 ;MSH182 .IF DF M$$MGE ;MSH182 ;MSH182 MOV H.WND(R4),-(SP) ;SAVE POINTER TO WINDOW BLOCKS ;MSH182 ;MSH182 .ENDC ;MSH182 .IF DF P$$LAS TST (R3)+ ;PARTITION NAME SPECIFIED? ;MSH182 BNE 10$ ;IF NE YES ;**-1 ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 MOV R5,-(SP) ;SAVE TCB ADDRESS ;MSH096 ;MSH096 .IFTF ;MSH096 ;MSH096 CALL $SRATT ;SEARCH FOR REGION ID MOV A.PCB(R5),R2 ;PICK UP PCB ADDRESS ;MSH096 .IFT ;MSH096 ;MSH096 MOV (SP)+,R5 ;RESTORE TCB ADDRESS ;MSH096 ;MSH096 .ENDC ;A$$HDR  ;MSH096 ;MSH096 BR 30$ ; 10$: TST -(R3) ;POINT TO FIRST WORD OF PARTITION NAME CALL $SRNAM ;SEARCH FOR NAMED PARTITION BCC 20$ ;IF CC NAMED PARTITION FOUND DRSTS D.RS2 ;INVALID PARTITION NAME 20$: TST (R3)+ ;ADVANCE POINTER 30$: MOV R2,R4 ;COPY PCB POINTER .IFF MOV (R3)+,R0 ;PARTITION SPECIFIED? ;MSH182 BEQ 30$ ;IF EQ NO ;**-1 MOV $PARHD,R4 ;GET ADDRESS OF FIRST PARTITION PCB 10$: CMP R0,P.NAM(R4) ;FIRST HALF OF NAME MATCH? BNE 20$ ;IF NE NO CMP (R3),P.NAM+2(R4) ;SECOND HALF OF NAME MATCH? BEQ 40$ ;IF EQ YES 20$: MOV (R4),R4 ;GET ADDRESS OF NEXT PCB BNE 10$ ;IF NE MORE TO SCAN DRSTS D.RS2 ;SET DIRECTIVE STATUS 30$: MOV T.PCB(R5),R4 ;GET PCB ADDRESS OF CURRENT TASK .ENDC 40$: MOV 2(R3),R3 ;GET ADDRESS OF 3 WORD BUFFER .IF DF A$$CHK!M$$MGE MOV #3*2,R1 ;SET LENGTH OF BUFFER CALL $ACHKP ;ADDRESS CHECK BUFFER .ENDC ; ;MSH096 ; IF THE PARTITION IS A TASK PARTITION, THE ALTERNATE HEADER ;MSH096 ; REFRESH AREA MUST NOT BE INCLUDED IN THE PARTITION PARAMETERS ;MSH096 ; BECAUSE IT IS NOT MAPPED BY THE TASK. THE ALTERNATE HEADER ;MSH096 ; REFRESH AREA IS TOTALLY TRANSPARENT TO THE TASK'S EXECUTION. ;MSH096 ; TO DO THIS, SIMPLY ADD THE LENGTH OF THE ALTERNATE HEADER REFRESH ;MSH096 ; AREA TO THE STARTING ADDRESS OF THE TASK PARTITION AND SUBTRACT ;MSH096 ; IT FROM THAT PARTITION'S LENGTH. ;MSH096 ; ;MSH096 ; THE ALTERNATE HEADER REFRESH AREA CANNOT EXIST FOR NONCHECKPOINTABLE ;MSH096 ; TASKS. ;MSH096 ; ;MSH096 ;MSH096 .IF DF M$$MGE MOV (SP)+,R2 ;GET POINTER TO WINDOW BLOCKS (H.WND) ;MSH182 TST (R2)+ ;POINT TO WINDOW ZERO ;MSH182 CLR 2(SP) ;SET DIRECTIVE STATUS WORD ;**-1 ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 MOV P.REL(R4),(R3) ;INSERT PHYSICAL ADDRESS OF PARTITION ;MSH096 CLR R1 ;INIT ALTERNATE HEADER AREA LENGTH ;MSH096 ;MSH182 .IFTF ;MSH182 ;MSH182 CMP (R2)+,R4 ;IS THIS THE TASK REGION? (W.BPCB) ;MSH182 BNE 45$ ;IF NE NO, DON'T WORRY ABOUT ALT HDR ;MSH096 MOV (R2),2(SP) ;RETURN VIRTUAL STARTING ADDRESS (W.BLVR;MSH182 ;MSH182 .IFT ;MSH182 ;MSH182 BIT #T2.CHK,T.ST2(R5) ;DOES THE TASK HAVE ONE? ;MSH096 BNE 45$ ;IF NE NO, TASK IS NONCHECKPOINTABLE ;MSH096 MOVB T.HDLN(R5),R1 ;GET ALT HEADER REFRESH AREA LENGTH ;MSH096 ;MSH182 .IFTF ;MSH182 ;MSH182 45$: ; ;MSH182 ;MSH182 .IFT ;MSH182 ;MSH182 ADD R1,(R3)+ ;CORRECT REPORTED STARTING ADDRESS ;MSH182 MOV P.SIZE(R4),(R3) ;INSERT SIZE OF PARTITION ;MSH096 SUB R1,(R3)+ ;CORRECT REPORTED SIZE OF PARTITION ;MSH096 ;MSH096 .IFF ;A$$HDR ;MSH096 ;MSH096 MOV P.REL(R4),(R3)+ ;INSERT PHYSICAL ADDRESS OF PARTITION ;MSH096 MOV P.SIZE(R4),(R3)+ ;INSERT SIZE OF PARTITION ;MSH096 ;MSH096 .ENDC ;A$$HDR ;MSH096 .IFF MOV P.REL(R4),R1 ;GET STARTING VIRTUAL ADDRESS OF PARTITION MOV R1,(R3)+ ;INSERT PHYSICAL ADDRESS OF PARTITION MOV R1,2(SP) ;SET DIRECTIVE STATUS WORD MOV P.SIZE(R4),(R3)+ ;INSERT SIZE OF PARTITION ;MSH096 .IFTF CLR (R3) ;ASSUME SYSTEM CONTROLLED PARTITION ;**-1 .IF DF D$$YNM&M$$MGE BIT #PS.SYS,P.STAT(R4) ;SYSTEM CONTROLLED PARTITION? BNE 60$ ;IF NE YES .ENDC INC (R3) ;SET USER CONTROLLED PARTITION .IFF CALL (PC) ;CONVERT LENGTH TO 32W BLOCKS SWAB -(R3) ;CONVERT TO 32W BLOCKS ASLB 1(R3) ; ROL (R3) ; ROL (R3) ; .ENDC 60$ : RETURN .ENDC .END ׸ykQ ›c, .TITLE DRGSS .IDENT /04.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.00 ; ; D. N. CUTLER 31-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; ; MODIFIED BY: ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ;+ ; **-$DRGSS-GET SENSE SWITCHES ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO STORE THE CONTENTS OF THE CONSOLE ; SWITCH REGISTER IN THE ISSUING TASK'S DIRECTIVE STATUS WORD. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(125.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS EQUAL TO THE CONTENTS ¸OF THE ; CONSOLE SWITCH REGISTER. ;- .IF DF G$$TSS $DRGSS::MOV SWR,2(SP) ;SET CONTENTS OF CONSOLE SWITCH REGISTER RETURN ;RETURN DIRECTIVE STATUS .ENDC .END ¸×¸~kQ ›c, .TITLE DRGTK .IDENT /06.03/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 06.03 ; ; D. N. CUTLER 27-MAR-74 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 19-SEP-80 ; MSH120 -- DON'T RETURN NON-BUFFERED I/O COUNT TO TASK ; ; DAN BROWN 7-JAN-80 ; DTB005 -- RETURN PROCESSOR MODEL ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,PCBDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRGTK-GET TASK PARAMETERS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO FILL A SIXTEEN WORD BUFFER WITH ; TASK PARAMETERS. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(63.),DPB SIZE(2.). ; WD. 01 -- ADDRESS OF A SIXTEEN WORD BUFFER. ; ; BUFFER FORMAT: ; ; WD. 00 -- FIRST HALF OF ISSUING TASK'S NAME. ; WD. 01 -- SECOND HALF OF ISSUING TASK'S NAME. ; WD. 02 -- FIRST HALF OF TASK'S PARTITION NAME. ; WD. 03 -- SECOND HALF OF TASK'S PARTITION NAME. ; WD. 04 -- FIRST HALF OF REQUESTER TASK NAME (NOT SUPPORTED). ; WD. 05 -- SECOND HALF OF REQUESTER TASK NAME (NOT SUPPORTED). ; WD. 06 -- TASK PRIORITY. ; WD. 07 -- CURRENT TASK UIC. ; WD. 10 -- NUMBER OF LOGICAL UNITS. ; WD. 11 -- MACHINE TYPE INDICATOR. ;DTB005 ; WD. 12 -- STD FLAGS WORD (NOT SUPPORTED). ;**-1 ; WD. 13 -- ADDRESS OF TASK SST VECTOR TABLE. ; WD. 14 -- SIZE OF TASK SST VECTOR TABLE IN WORDS. ; WD. 15 -- SIZE OF TASK IN BYTES. ; WD. 16 -- SYSTEM TYPE CODE. ; WD. 17 -- PROTECTION UIC WORD. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SIXTEEN WORD BUFFER IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ;- .IF DF G$$TTK $DRGTK::MOV (R3),R3 ;GET ADDRESS OF 16. WORD BUFFER .IF DF A$$CHK!M$$MGE MOV #16.*2,R1 ;SET LENGTH OF BUFFER IN BYTES CALL $ACHKP ;ADDRESS CHECK PARAMETER BLOCK .ENDC MOV T.NAM(R5),(R3)+ ;INSERT NAME OF TASK MOV T.NAM+2(R5),(R3)+ ; MOV T.PCB(R5),R0 ;GET ADDRESS OF TASK PCB MOV P.NAM(R0),(R3)+ ;INSERT NAME OF PARTITION MOV P.NAM+2(R0),(R3)+ ; CMP (R3)+,(R3)+ ;POINT TO TASK PRIORITY ADDRESS MOVB T.PRI(R5),(R3)+ ;INSERT TASK PRIORITY ;MSH120 CLRB (R3)+ ;POINT TO CURRENT UIC WORD ;MSH120 ;**-1 .IF DF M$$MUP MOV H.DUIC(R4),(R3)+ ;INSERT DEFAULT UIC .IFF MOV H.CUIC(R4),(R3)+ ;INSERT CURRENT UIC .ENDC MOV H.NLUN(R4),(R3)+ ;INSERT NUMBER OF LUNS MOV $PRMOD,(R3)+ ;INSERT PROCESSOR TYPE ;DTB005 CLR (R3)+ ;POINT TO TASK SST VECTOR ADDRESS ;DTB005 MOV H.TKVA(R4),(R3)+ ;INSERT TASK SST VECTOR ADDRESS ;**-1 MOV H.TKVL(R4),(R3) ;INSERT LENGTH OF SST VECTOR IN WORDS ASR (R3)+ ;CONVERT TO LENGTH IN WORDS MOV HX.WND(R4),R1 ;POINT TO NUMBER OF WINDOW BLOCKS MOV W.BHVR+2(R1),(R3) ;CALCULATE TASK SIZE IN BYTES SUB W.BLVR+2(R1),(R3) ; INC (R3)+ ; .IF NDF R$$11S MOV #1,(R3)+ ;SET CODE FOR RSX-11M .IFF MOV #2,(R3)+ ;SET CODE FOR RSX-11S .ENDC MOV H.CUIC(R4),(R3) ;RETURN PROTECTION UIC RETURN ; .ENDC .END X×€kQ ›c, .TITLE DRGTP .IDENT /04.07/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.07 ; ; D. N. CUTLER 30-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 16-OCT-80 ; MSH123 -- ADD SET SYSTEM TIME DIRECTIVE ; ; DAN BROWN 8-JAN-81 ; DTB008 -- ADD ERROR LOG HANDLING TO SET SYSTEM TIME ;+ ; **-$DRGTP-GET TIME PARAMETERS / SET SYSTEM TIME ;MSH123 ; ;**-1 ; THE GET TIME PARAMETERS DIRECTIVE INSTRUCTS THE SYSTEM TO FILL ;MSH123 ; A SPECIFIED EIGHT WORD BUFFER WITH THE CURRENT TIME PARAMETERS. ;MSH123 ; ;MSH123 ; THE SET SYSTEM TIME DIRECTIVE INSTRUCTS THE SYSTEM TO OPTIONALLY ;MSH123 ; FILL A SPECIFIED EIGHT WORD BUFFER WITH THE CURRENT TIME ;MSH123 ; PARAMETERS, AND TO RESET THE SYSTEM TIME PARAMETERS USING A ;MSH123 ; SPECIFIED TIME AND DATE. ;MSH123 ; ;**-2 ; DPB FORMAT FOR GET TIME PARAMETERS DIRECTIVE: ;MSH123 ; ;**-1 ; WD. 00 -- DIC(61.),DPB SIZE(2.). ; WD. 01 -- ADDRESS OF AN EIGHT WORD BUFFER. ; ;MSH123 ; DPB FORMAT FOR SET SYSTEM TIME DIRECTIVE: ;MSH123 ; ;MSH123 ; WD. 00 -- DIC(61.),DBP SIZE(3.) ;MSH123 ; WD. 01 -- ADDRESS OF AN EIGHT WORD NEW TIME SPECIFICATION ;MSH123 ; WD. 02 -- ADDRESS OF AN EIGHT WORD OUTPUT BUFFER ;MSH123 ; ; BUFFER FORMAT: ; ; WD. 00 -- YEAR SINCE 1900. ; WD. 01 -- MONTH OF YEAR. ; WD. 02 -- DAY OF MONTH. ; WD. 03 -- HOUR OF DAY. ; WD. 04 -- MINUTE OF HOUR. ; WD. 05 -- SECOND OF MINUTE. ; WD. 06 -- TICK OF SECOND. ; WD. 07 -- TICKS PER SECOND. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF A ;MSH123 ; NONPRIVILEGED TASK ATTEMPTED TO SET THE ;MSH123 ; SYSTEM TIME TO A SPECIFIED VALUE. ;MSH123 ; DIRECTIVE STATUS OF 'D.RS93' IS RETURNED IF ONE OF ;MSH123 ; THE SPECIFIED TIME PARAMETERS IS OUT OF RANGE, ;MSH123 ; OR BOTH THE 'TICK OF SECOND' PARAMETER AND ;MSH123 ; THE 'TICKS PER SECOND' PARAMETER WERE SPECIFIED ;MSH123 ; AND THE 'TICKS PER SECOND' PARAMETER DOES NOT ;MSH123 ; MATCH THE SYSTEM'S CLOCK FREQUENCY. ;MSH123 ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF ONE OF THE ;MSH123 ; BUFFERS IS OUTSIDE OF THE ISSUING TASK'S ;MSH123 ; ADDRESS SPACE. ;MSH123 ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE DPB ;MSH123 ; LENGTH IS ILLEGAL. ;MSH123 ;- ;**-2 .IF DF E$$LOG&S$$TIM ;DTB008 ;DTB008 .MCALL EPKDF$ ;DTB008 EPKDF$ ;ERROR LOG PACKET OFFSETS ;DTB008  ;DTB008 .ENDC ;DTB008 ;DTB008 $DRGTP:: ; ;MSH123 ;MSH123 .IF DF S$$TIM ;MSH123 ;MSH123 MOVB -(R3),R4 ;GET DBP LENGTH ;MSH123 CMPB (R3)+,#2 ;GET TIME PARAMETERS DIRECTIVE? ;MSH123 BEQ 5$ ;IF EQ YES, COMPLETE THE DIRECTIVE ;MSH123 CMPB R4,#3 ;SET SYSTEM TIME DIRECTIVE? ;MSH123 BNE 65$ ;IF NE NO, ILLEGAL DPB LENGTH ;MSH123 BIT #T3.PRV,T.ST3(R5) ;TASK PRIVILEGED? ;MSH123 BNE 3$ ;IF NE YES, OK TO USE THIS DIRECTIVE ;MSH123 DRSTS D.RS16 ;PRIVILEGE VIOLATION ;MSH123 ;MSH123 3$: MOV (R3)+,R5 ;COPY NEW TIME ARRAY ADDRESS ;MSH123 ;MSH123 .IFTF ;MSH123 ;MSH123 5$: MOV (R3),R3 ;GET PREVIOUS TIME BUFFER ADDRESS ;MSH123 ;MSH123 .IFT ;MSH123 ;MSH123 BNE 7$ ;IF NE THERE IS ONE ;MSH123 CMPB R4,#2 ;LEGAL TO DEFAULT THIS BUFFER? ;MSH123 BNE 15$ ;IF NE YES ;MSH123 7$: ; ;MSH123 ;MSH123 .IFTF ;MSH123 ;**-1 .IF DF A$$CHK!M$$MGE MOV #8.*2,R1 ;SET LENGTH OF BUFFER IN BYTES CALL $ACHKP ;ADDRESS CHECK AND MAP PARAMETER BUFFER ;MSH123 ;**-1 .ENDC MOV #$TTNS-14,R1 ;POINT TO CURRENT TIME VECTOR 10$: MOV (R1)+,(R3)+ ;INSERT TIME PARAMETER IN TASK BUFFER CMP R1,#$TTNS ;ANY MORE TO INSERT? BLOS 10$ ;IF LOS YES MOV $TKPS,(R3) ;SET TICKS PER SECOND ;MSH123 .IFT ;MSH123 ;MSH123 15$: ROR R4 ;SET SYSTEM TIME DIRECTIVE? ;MSH123 BCC 48$ ;IF CC NO, DIRECTIVE FINISHED ;MSH123 MOV R5,R3 ;GET NEW TIME ARRAY ADDRESS ;MSH123 ;MSH123 .IF DF A$$CHK!M$$MGE ;MSH123 ;MSH123 MOV #8.*2,R1 ;SET LENGTH OF BUFFER IN BYTES ;MSH123 CALL $ACHKP ;ADDRESS CHECK AND MAP PARAMETER BUFFER ;MSH123 ;MSH123 .ENDC ;MSH123 ;MSH123 MOV #$TTNS+2,R4 ;POINT TO CURRENT TIME VECTOR ;MSH123 MOV SP,R2 ;SAVE TOP-OF-STACK POINTER ;MSH123 20$: MOV -(R4),-(SP) ;COPY TIME PARAMETER ;MSH123 CMP R4,#$TTNS-14 ;ANY MORE TO COPY? ;MSH123 BHI 20$ ;IF HI YES ;MSH123 ; ;MSH123 ; WE NOW HAVE A WORKING COPY OF THE TIME VECTOR ON THE STACK. USING ;MSH123 ; THIS TO SUPPLY VALUES FOR USER DEFAULTED TIME PARAMETERS, AN ;MSH123 ; ATTEMPT TO BUILD A VALID TIME VECTOR WILL NOW BE MADE. ;MSH123 ; ;MSH123 MOV #$TLMTS,R1 ;POINT TO PARAMETER VALIDATION TABLE ;MSH123 MOV SP,R5 ;POINT TO CURRENT YEAR PARAMETER ;MSH123 MOV R2,-(SP) ;SAVE OLD TOP-OF-STACK POINTER ;MSH123 CLR R2 ;ASSUME NO LEAP YEAR ;MSH123 CALL 50$ ;VALIDATE USER-SPECIFIED YEAR ;MSH123 BIC #^C<3>,R0 ;IS THIS A LEAP YEAR? ;MSH123 BNE 25$ ;IF NE NO ;MSH123 INC R2 ;SET THE FEBRUARY CONSTANT ;MSH123 25$: CALL 50$ ;VALIDATE USER-SPECIFIED MONTH ;MSH123 DEC R0 ;NORMALIZE TO ZERO ;MSH123 DEC R0 ;IS THIS FEBRUARY? ;MSH123 BEQ 30$ ;IF EQ YES, MAINTAIN FEBRUARY CONSTANT ;MSH123 CLR R2 ;IF NE NO, ELIMINATE FEBRUARY CONSTANT ;MSH123 30$: INC R0 ;IS THIS JANUARY? ;MSH123 BNE 35$ ;IF NE NO ;MSH123 ADD #12.,R0 ;ADJUST FOR DAYS-PER-MONTH TABLE ;MSH123 35$: MOVB $DYPMN-1(R0),R4 ;GET NUMBER OF DAYS FOR THIS MONTH ;MSH123 ADD R2,R4 ;ADD THE FEBRUARY CONSTANT ;MSH123 DEC R4 ;CORRECT DAYS-PER-MONTH ENTRY BIAS ;MSH123 MOV R4,(R1) ;ESTABLISH UPPER LIMIT FOR DAY ;MSH123 MOV #4,R2 ;SET VALIDATION LOOP COUNT ;MSH123 40$: CALL 50$ ;VALIDATE DAY,HOUR,MINUTE AND SECOND ;MSH123 DEC R2 ;DONE? ;MSH123 BGT 40$ ;IF GT NO ;MSH123 MOV 2(R3),R2 ;GET USER'S INTENDED FREQUENCY ;MSH123 BLT 43$ ;IF LT, DEFAULTED. DEFAULT TICK OF SEC ;MSH123 DEC R2 ;CONVERT TO TICK-OF-SEC HIGH LIMIT ;MSH123 CMP R2,(R1) ;CORRECT TICK GRANULARITY? ;MSH123 BNE 60$ ;IF NE SURPRISE!, UNEXPECTED FREQUENCY ;MSH123 CALL 50$ ;VALIDATE TICK OF SECOND ;MSH123 ; ;MSH123 ; AT THIS POINT, THE ENTIRE SPECIFIED TIME VECTOR HAS BEEN ;MSH123 ; VALIDATED AND INCORPORATED INTO THE CURRENT TIME VECTOR ;MSH123 ; STORED ON THE STACK. IT'S TIME TO MOVE THE NEW SYSTEM ;MSH123 ; TIME VECTOR INTO PLACE, THUS ESTABLISHING THE SYSTEM'S TIME. ;MSH123 ; ;MSH123 43$: INC R4 ;BIAS FOR DAYS-PER-MONTH ENTRY ;MSH123 MOV R4,$DPM ;ESTABLISH CURRENT DAYS/MONTH ;MSH123 MOV (SP)+,R5 ;RESTORE TOP-OF-STACK POINTER ;MSH123 ;DTB008 .IF DF E$$LOG ;DTB008 ;DTB008 BIT #ES.DAT,$ERFLA ;CHECK TO SEE IF LOGGING TURNED ON ;DTB008 BEQ 44$ ;IF EQ NO ;DTB008 MOV #E$CCTL+<400*E$STIM>,R0 ;GET THE ENTRY CODE ;DTB008 MOV #12.,R1 ;DATA SUBPACKET IS 12 BYTES LONG ;DTB008 MOV #SM.HDR!SM.TSK!SM.DAT,R2 ;GET INFORMATION TO RECORD ;DTB008 MOV SP,R3 ;GET POINTER TO DATA ON STACK ;DTB008 MOV $TKTCB,R4 ;GET THE CURRENT TASK TCB ;DTB008 CALL $CRPKT ;CREATE THE PACKET ;DTB008 BCS 44$ ;FAILURE ;DTB008 CALL $QUPKT ;AND QUEUE IT ;DTB008 44$: ;REF LABEL ;DTB008 ;DTB008 .ENDC ; E$$LOG ;DTB008 ;DTB008 MOV #$TTNS-14,R4 ;POINT PAST CURRENT TIME VECTOR ;MSH123 45$: MOV (SP)+,(R4)+ ;SET NEW TIME PARAMETER ;MSH123 CMP SP,R5 ;VECTOR IN PLACE? ;MSH123 BLO 45$ ;IF LO NOT YET ;MSH123 ;MSH123 .IFTF ;MSH123 ;MSH123 48$: RETURN ;DONE! ;MSH123 ;MSH123 .IFT ;MSH123 ;MSH123 ; ;MSH123 ; SUBROUTINE CALLED FOR EACH TIME PARAMETER. IF THE USER ;MSH123 ; DEFAULTED ANY GIVEN PARAMETER, THE CURRENT SYSTEM'S PARAMETER ;MSH123 ; IS SUBSTITUTED. THEN THE PARAMETER MUST PASS THE HIGH/LOW ;MSH123 ; LIMITS ESTABLISHED FOR IT STATICALLY OR DYNAMICALLY. ;MSH123 ; ;MSH123 50$: MOV (R3)+,R0 ;GET USER-SPECIFIED TIME PARAMETER ;MSH123 BPL 55$ ;IF PL PARAMETER NOT DEFAULTED ;MSH123 MOV (R5),R0 ;PULL IN VALUE FROM CURRENT TIME VECTOR ;MSH123 55$: CMP R0,(R1)+ ;VALUE TOO HIGH? ;MSH123 BGT 60$ ;IF GT YES ;MSH123 CMP R0,(R1)+ ;VALUE TOO LOW? ;MSH123 BLT 60$ ;IF LT YES ;MSH123 MOV R0,(R5)+ ;MOV PARAMETER TO VECTOR ON THE STACK ;MSH123 RETURN ;PARAMETER IS VALID ;MSH123 ;MSH123 60$: DRSTS D.RS93 ;PARAMETER OUT OF RANGE ;MSH123 65$: DRSTS D.RS99 ;ILLEbGAL DPB LENGTH ;MSH123 ;MSH123 .ENDC ;S$$TIM ;MSH123 ;**-1 .END bÝÀkQ ›c, .TITLE DRMAP .IDENT /04.02/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.02 ; ; T. J. MILLER 8-MAR-76 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; CHUCK SPITZ ; JOHN COVERT ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 16-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 28-APR-80 ; MSH096 -- DON'T ALLOW TASKS TO MAP TO THE ALTERNATE ; HEADER REFRESH AREA OF THE TASK REGION ; .PAGE ; ; THE FOLLOWING DIRECTIVES RECEIVE AS INPUT POINTERS TO A WINDOW DEFINITION ; BLOCK, WHICH SERVES AS A COMMUNICATION AREA BETWEEN THE ISSUING TASK AND ; THE EXECUTIVE. THE FORMAT OF THE WINDOW DEFINITION BLOCK IS: ; ; ------------------------------------------------- ; W.NID ! ! ! ; W.NAPR ! BASE APR ! WINDOW ID ! ; ! ! ! ; !-----------------------------------------------! ; ! ! ; W.NBAS ! VIRTUAL BASE ADDRESS (BYTES) ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NSIZ ! WINDOW SIZE (32W BLOCKS) ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NRID ! REGION ID ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NOFF ! OFFSET IN PARTITION (32W BLOCKS) ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NLEN ! LENGTH TO MAP (32W BLOCKS) ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NSTS ! STATUS WORD ! ; ! ! ; !-----------------------------------------------! ; ! ! ; W.NSRB ! SEND/RECEIVE BUFFER ADDR (BYTES) ! ; ! ! ; ------------------------------------------------- ; ; MACRO LIBRARY CALLS ; .IF DF P$$LAS .MCALL HDRDF$,PCBDF$,TCBDF$,WDBDF$ HDRDF$ ;DEFINE HEADER AND WINDOW BLOCK OFFSETS PCBDF$ ;DEFINE PCB AND ATTACHMENT DESCR OFFSETS TCBDF$ ;DEFINE TCB OFFSETS WDBDF$ ;DEFINE WINDOW DEFINITION BLOCK OFFSETS ;+ ; **-$DRCRW-CREATE ADDRESS WINDOW ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO ALLOCATE AN ADDRESS WINDOW IN THE ; HEADER OF THE ISSUING TASK, UNMAPPING AND ELIMINATING ANY OVERLAPPING ; ADDRESS WINDOWS, AND OPTIONALLY TO MAP THE NEW WINDOW. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(117.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE WINDOW DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NAPR=BASE APR OF REGION. ; W.NSIZ=DESIRED SIZE OF ADDRESS WINDOW. ; W.NRID=ID OF REGION TO MAP OR 0 FOR TASK REGION (IF WS.MAP=1). ; W.NOFF=OFFSET WITHIN REGION TO MAP (IF WS.MAP=1). ; W.NLEN=LENGTH TO MAP OR 0 TO DEFAULT TO SMALLER OF WINDOW SIZE ; OR SIZE LEFT IN PARTITION (IF WS.MAP=1). ; W.NSTS=CONTROL INFORMATION. ; WS.MAP=1 IF MAPPING IS TO OCCUR. ; WS.WRT=1 IF MAPPING IS TO OCCUR WITH WRITE ACCESS. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE SPECIFIED ; ACCESS IS DENIED IN THE MAPPING STAGE. ; DIRECTIVE STATUS OF 'D.RS84' IS RETURNED IF AN INVALID APR- ; WINDOW SIZE COMBINATION IS SPECIFIED OR IF AN ; INVALID REGION OFFSET-LENGTH COMBINATION IS SPECIFIED ; IN THE MAPPING STAGE. ; DIRECTIVE STATUS OF 'D.RS85' IS RETURNED IF THERE ARE NO ; AVAILABLE WINDOW BLOCKS. ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF AN INVALID REGION ; ID IS SPECIFIED IN THE MAPPING STAGE. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NID=ASSIGNED WINDOW ID. ; W.NBAS=VIRTUAL BASE ADDRESS OF WINDOW. ; W.NLEN=LENGTH ACTUALLY MAPPED. ; W.NSTS=INDICATION OF ANY CHANGES IN MAPPING STATUS. ; WS.CRW=1 IF ADDRESS WINDOW SUCCESSFULLY ESTABLISHED. ; WS.ELW=1 IF ANY ADDRESS WINDOWS WERE ELIMINATED. ; WS.UNM=1 IF ANY ADDRESS WINDOWS WERE UNMAPPED. ;- $DRCRW::MOV R4,-(SP) ;SAVE ADDRESS OF TASK HEADER MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R4)+,R1 ;PICK UP NUMBER OF WINDOW BLOCKS MOV (R3)+,R2 ;PICK UP APR NUMBER IN HIGH BYTE (W.NID) CLRB R2 ;CLEAR OUT LOW BYTE CMP R2,#7*256. ;LEGAL APR NUMBER? BHI 40$ ;IF HI NO ASR R2 ;CONVERT TO BASE ADDRESS IN 32W BLOCKS MOV R2,(R3) ;STORE VIRTUAL BASE ADDRESS (W.NBAS) ASR (R3) ;CONVERT TO BYTES (W.NBAS) ASR (R3) ; SWAB (R3)+ ; TST (R3) ;IS W.NSIZ=0 (NOT A VALID WINDOW SIZE) BEQ 40$ ;IF EQ YES -- RETURN ALIGNMENT ERROR MOV R2,-(SP) ;CALCULATE HIGH ADDRESS ADD (R3),(SP) ;(W.NSIZ) BCS 40$ ;IF CS ILLEGAL SIZE CMP (SP),#2000 ;LEGAL TOP ADDRESS? BHI 40$ ;IF HI NO MOV R1,-(SP) ;SAVE NUMBER OF WINDOWS CMP -(R3),-(R3) ;POINT TO START OF WINDOW BLOCK (W.NBAS)(W.NID) 10$: TST W.BSIZ(R4) ;POINTING TO AN ESTABLISHED ADDRESS WINDOW? BEQ 20$ ;IF EQ NO MOV W.BLVR(R4),R0 ;PICK UP LOW VIRTUAL ADDRESS SWAB R0 ;CONVERT TO 32W BLOCKS ASL R0 ; ASL R0 ; CMP 2(SP),R0 ;POSSIBLE VIRTUAL ADDRESS OVERLAP? BLOS 30$ ;IF LOS NO ADD W.BSIZ(R4),R0 ;CALCULATE HIGH ADDRESS CMP R2,R0 ;VIRTUAL ADDRESS OVERLAP? BHIS 30$ ;IF HIS NO CMP R1,(SP) ;OVERLAPPING WINDOW 0? BEQ 40$ ;IF EQ YES CALL ELAW ;ELIMINATE ADDRESS WINDOW 20$: TST (SP) ;HAS A WINDOW BEEN ESTABLISHED?  BEQ 30$ ;IF EQ YES CMP (R3)+,(R3)+ ;POINT TO WINDOW SIZE IN BLOCK (W.NID)(W.NBAS) MOV (R3),W.BSIZ(R4) ;STORE SIZE, ESTABLISHING WINDOW (W.NSIZ) MOV -(R3),W.BLVR(R4) ;SET LOW VIRTUAL ADDRESS (W.NBAS) MOVB -(R3),R0 ;PICK UP FIRST APR NUMBER (W.NAPR) ASL R0 ;CONVERT APR NUMBER TO WORD OFFSET ADD #UISDR0,R0 ;POINT TO FIRST PDR MOVB R0,W.BFPD(R4) ;SET FIRST PDR ADDRESS MOVB (SP),-(R3) ;PICK UP TOTAL NUMBER OF WINDOWS (W.NID) SUB R1,(R3) ;SET ADDRESS WINDOW ID (W.NID) CLR (SP) ;INDICATE WINDOW HAS BEEN ESTABLISHED 30$: ADD #W.BLGH,R4 ;POINT TO NEXT WINDOW BLOCK DEC R1 ;MORE WINDOW BLOCKS? BGT 10$ ;IF GT YES TST (SP)+ ;WAS AN ADDRESS WINDOW ESTABLISHED? BNE 50$ ;IF NE NO TST (SP)+ ;POP CALCULATED HIGH ADDRESS MOV (SP)+,R4 ;RESTORE TASK HEADER ADDRESS BIS #WS.CRW,W.NSTS(R3) ;INDICATE ADDRESS WINDOW WAS CREATED BIT #WS.MAP,W.NSTS(R3) ;IS WINDOW TO BE MAPPED? BNE $DRMAP ;MAP ADDRESS WINDOW AND EXIT RETURN ; 40$: DRSTS D.RS84 ;ALIGNMENT ERROR 50$: DRSTS D.RS85 ;NO AVAILABLE WINDOWS ;+ ; **-$DRELW-ELIMINATE ADDRESS WINDOW ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO ELIMINATE THE SPECIFIED ADDRESS ; WINDOW, UNMAPPING IT FIRST IF NECESSARY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(119.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE WINDOW DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NID=ID OF ADDRESS WINDOW TO ELIMINATE. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS87' IS RETURNED IF AN INVALID ; ADDRESS WINDOW WAS SPECIFIED. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NSTS=INDICATION OF ANY CHANGES IN MAPPING STATUS. ; WS.ELW=1 IF ADDRESS WINDOW SUCCESSFULLY ELIMINATED. ; WS.UNM=1 IF THE ADDRESS WINDOW WAS UNMAPPED. ;- $DRELW::CALL $SRWND ;SEARCH FOR AND VERIFY SPECIFIED WINDOW ELAW: CALL $UNMAP ;UNMAP IF NECESSARY BCC 10$ ;IF CC UNMAPPING WAS NOT PERFORMED BIS #WS.UNM,W.NSTS(R3) ;INDICATE A WINDOW WAS UNMAPPED 10$: CLR W.BSIZ(R4) ;INDICATE ADDRESS WINDOW IS ELIMINATED BIS #WS.ELW,W.NSTS(R3) ;INDICATE ADDRESS WINDOW ELIMINATED RETURN ; ;+ ; **-$DRMAP-MAP WINDOW TO REGION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO MAP THE SPECIFIED ADDRESS ; WINDOW TO AN OFFSET IN THE SPECIFIED REGION, UNMAPPING IF NECESSARY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(121.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE WINDOW DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NID=ID OF WINDOW TO MAP. ; W.NRID=ID OF REGION TO MAP TO OR 0 TO DEFAULT TO TASK REGION. ; W.NOFF=OFFSET WITHIN REGION TO MAP TO. ; W.NLEN=LENGTH TO MAP OR 0 TO DEFAULT TO SMALLER OF WINDOW ; SIZE OR SIZE LEFT IN PARTITION. ; W.NSTS=CONTROL INFORMATION. ; WS.WRT=1 IF WRITE ACCESS IS DESIRED. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE DESIRED ; ACCESS TO THE REGION IS DENIED. ; DIRECTIVE STATUS OF 'D.RS84' IS RETURNED IF AN INVALID ; REGION OFFSET-SIZE COMBINATION IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF AN INVALID ; REGION ID IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS87' IS RETURNED IF AN INVALID ; ADDRESS WINDOW ID IS SPECIFIED. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NLEN=LENGTH ACTUALLY MAPPED. ; W.NSTS=INDICATION OF ANY CHANGES IN MAPPING STATUS. ; WS.UNM=1 IF THE WINDOW WAS UNMAPPED FIRST. ; ; THIS DIRECTIVE FIRST BUILDS AN IMAGE OF A MAPPED WINDOW BLOCK ON THE ; STACK. THEN IF NO ERRORS ARE ENCOUNTERED, THE CORRESPONDING WINDOW IS ; UNMAPPED, IF NECESSARY, AND SET UP FROM THE STACK IMAGE. ;- $DRMAP::CALL $SRWND ;SEARCH FOR AND VERIFY ADDRESS WINDOW ID ADD #W.NRID,R3 ;POINT TO SPECIFIED REGION ID CALL $SRATT ;SEARCH FOR MATCHING ATTACHMENT DESCRIPTOR MOV A.PCB(R5),R2 ;POINT TO ATTACHED PCB MOV R2,-(SP) ;SET PCB ADDRESS (W.BPCB) MOV W.BLVR(R4),-(SP) ;COPY LOW VIRTUAL ADDRESS (W.BLVR) TST (R3)+ ;POINT TO OFFSET (W.NRID) MOV (R3)+,R0 ;PICK UP SPECIFIED OFFSET (W.NOFF) ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 MOV $TKTCB,R1 ;RETRIEVE CURRENT TCB ADDRESS ;MSH096 CMP R2,T.PCB(R1) ;MAPPING TO THE TASK REGION? ;MSH096 BNE 15$ ;IF NE NO ;MSH096 BIT #T2.CHK,T.ST2(R5) ;TASK HAVE ALTERNATE HEADER AREA? ;MSH096 BNE 15$ ;IF NE NO, NONCHECKPOINTABLE TASK ;MSH096 MOVB T.HDLN(R1),R1 ;GET ALTERNATE HEADER REFRESH AREA SIZE ;MSH096 ADD R1,R0 ;ADD OFFSET PAST THIS AREA ;MSH096 15$: ;MSH096 .ENDC ;A$$HDR ;MSH096 ;MSH096 CMP R0,P.SIZE(R2) ;WITHIN PARTITION? BHIS 70$ ;IF HIS NO MOV (R3),R1 ;PICK UP LENGTH TO MAP (W.NLEN) BNE 20$ ;IF NE ONE WAS SPECIFIED MOV P.SIZE(R2),R1 ;CALCULATE SIZE TO END OF PARTITION SUB R0,R1 ; CMP R1,W.BSIZ(R4) ;SIZE TO END GREATER THAN WINDOW SIZE? (W.BSIZ) BLOS 20$ ;IF LOS NO MOV W.BSIZ(R4),R1 ;DEFAULT TO WINDOW SIZE (W.BSIZ) 20$: MOV R1,(R3)+ ;PASS BACK SIZE USED (W.NLEN) MOV R1,-(SP) ;CALCULATE HIGH VIRTUAL ADDRESS (W.BHVR) SWAB (SP) ;MULTIPLY BY 64 RORB (SP) ; ROR (SP) ; ROR (SP) ; DEC (SP) ;POINT TO LAST ADDRESSABLE BYTE ADD 2(SP),(SP) ; MOV R5,-(SP) ;STORE ADDR OF ATTACHMENT DESCRIPTOR (W.BATT) MOV W.BSIZ(R4),-(SP) ;COPY WINDOW SIZE (W.BSIZ) CMP R1,(SP) ;LEGAL SIZE? (W.BSIZ) BHI 70$ ;IF HI NO BIT #7,R0 ;64-BYTE ALIGNMENT? BEQ 30$ ;IF EQ NO BIT #WS.64B,(R3) ;64-BYTE ALIGNMENT BEING ALLOWED? BEQ 70$ ;IF EQ NO 30$: MOV R0,-(SP) ;SET OFFSET IN PARTITION (W.BOFF) ADD R1,R0 ;POINT PAST LAST 32W BLOCK MAPPED TO CMP R0,P.SIZE(R2) ;WITHIN PARTITION? BHI 70$ ;IF HI NO MOV W.BFPD(R4),-(SP) ;SAVE FIRST PDR ADDRESS (W.BFPD) BITB #AS.RED!AS.WRT,A.STAT(R5) ;READ ACCESS ALLOWED? BEQ 80$ ;IF NE NO MOV #77402,-(SP) ;SET FOR READ ACCESS, 4K SIZE (W.BLPD) BIT #WS.WRT,(R3) ;WRITE ACCESS DESIRED? (W.NSTS) BEQ 40$ ;IF EQ NO BIT #AS.WRT,A.STAT(R5) ;WRITE ACCESS ALLOWED? BEQ 80$ ;IF NE NO MOV #77406,(SP) ;SET FOR 4K SIZE, READ/WRITE ACCESS (W.BLPD) 40$: INCB A.MPCT(R5) ;INC MAP COUNT IN ATTACHMENT DESCRIPTOR CALL $UNMAP ;UNMAP WINDOW IF NECESSARY BCC 45$ ;IF CC WINDOW WAS NOT MAPPED BIS #WS.UNM,(R3) ;INDICATE A WINDOW WAS UNMAPPED (W.NSTS) 45$: MOVB W.BFPD(R4),R0 ;POINT TO FIRST PDR MOV P.REL(R2),R2 ;CALCULATE OFFSET FOR FIRST PDR ADD 4(SP),R2 ;(W.BOFF) CLRB 3(SP) ;INIT NUMBER OF PDR'S (W.BNPD) 50$: INCB 3(SP) ;INC NUMBER OF PDR'S (W.BNPD) MOV R2,UISAR0-UISDR0(R0) ;SET UP USER APR MOV (SP),(R0)+ ;SET UP NEXT USER PDR ADD #200,R2 ;ADVANCE APR OFFSET SUB #200,R1 ;DONE YET? BGT 50$ ;IF GT NO SWAB R1 ;SHIFT UNUSED SIZE TO HIGH BYTE CLRB R1 ;CLEAR LOW BYTE ADD R1,(SP) ;CALCULATE SIZE IN LAST PDR ADD R1,-(R0) ;SET LAST PDR MOV R4,R3 ;COPY POINTER TO WINDOW BLOCK ADD #W.BLGH,R3 ;POINT PAST END OF WINDOW BLOCK 60$: MOV (SP)+,-(R3) ;COPY IMAGE OF WINDOW BLOCK INTO REAL BLOCK CMP R3,R4 ;DONE YET? BHI 60$ ;IF HI NO RETURN ; 70$: DRSTS D.RS84 ;INVALID OFFSET-LENGTH COMBINATION 80$: DRSTS D.RS16 ;DESIRED ACCESS TO REGION DENIED ;+ ; **-$DRUNM-UNMAP ADDRESS WINDOW ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO UNMAP THE SPECIFIED ADDRESS ; WINDOW. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(123.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE WINDOW DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ;  ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NID=ID OF WINDOW TO UNMAP. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS WORD RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THE SPECIFIED ; ADDRESS WINDOW NOT MAPPED. ; DIRECTIVE STATUS OF 'D.RS87' IS RETURNED IF AN INVALID ; ADDRESS WINDOW ID IS SPECIFIED. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NSTS=INDICATION OF ANY CHANGES IN MAPPING STATUS. ; WS.UNM=1 IF THE WINDOW WAS SUCCESSFULLY UNMAPPED. ;- $DRUNM::CALL $SRWND ;SEARCH FOR AND VERIFY WINDOW ID CALL $UNMAP ;UNMAP IF NECESSARY BCC 10$ ;IF CC WINDOW WAS NOT MAPPED BIS #WS.UNM,W.NSTS(R3) ;INDICATE ADDRESS WINDOW WAS UNMAPPED RETURN ; 10$: DRSTS D.RS8 ;ADDRESS WINDOW WAS NOT MAPPED ;+ ; **-$DRSRF-SEND BY REFERENCE ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CREATE A SPECIALLY FORMATTED ; PACKET INCLUDING A REFERENCE TO A SPECIFIED REGION WITH ADDITIONAL ; OPTIONAL INFORMATION SUPPLIED BY THE ISSUING TASK. THE SENDER TASK ; MUST ITSELF HAVE THE ACCESS SPECIFIED IN THE REFERENCE. THE REFERENCED ; REGION IS ATTACHED TO THE RECEIVING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(69.),DPB SIZE(5.) ; WD. 01 -- FIRST HALF OF RECEIVER TASK NAME ; WD. 02 -- SECOND HALF OF RECEIVER TASK NAME ; WD. 03 -- OPTIONAL EVENT FLAG TO SET WHEN RECEIVE OCCURS ; WD. 04 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE RECEIVER TASK ; R1=ADDRESS OF THE TASK STATUS WORD OF THE RECEIVER TASK ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE EFN NUMBER IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NRID=ID OF REGION TO BE SENT BY REFERENCE. ; W.NOFF=OFFSET WORD PASSED WITHOUT CHECKING. ; W.NLEN=LENGTH WORD PASSED WITHOUT CHECKING. ; W.NSTS=ALLOWED ACCESS (DEFAULTS TO ACCESS OF SENDER TASK). ; WS.RED=1 IF READ ACCESS IS TO BE ALLOWED. ; WS.WRT=1 IF WRITE ACCESS IS TO BE ALLOWED. ; WS.EXT=1 IF EXTEND ACCESS IS TO BE ALLOWED. ; WS.DEL=1 IF DELETE ACCESS IS TO BE ALLOWED. ; W.NSRB=OPTIONAL ADDRESS OF 8 WORD BUFFER OF ADDITIONAL INFO. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF A SEND PACKET ; OR ATTACHMENT DESCRIPTOR COULD NOT BE ALLOCATED. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF AN ATTEMPT IS ; MADE TO SEND TO AN ACP TASK. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE DESIRED ; ACCESS TO THE REGION IS DENIED. ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF AN INVALID ; REGION ID WAS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN INVALID EFN ; NUMBER IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE ADDRESS ; CHECK OF THE WINDOW DEF BLOCK OR SEND BUFFER FAILS. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; NONE. ; ; THE FORMAT OF THE SEND BY REFERENCE PACKET IS: ; WD. 00 -- RECEIVE QUEUE THREAD. ; WD. 01 -- TCB ADDRESS IF EFN SPECIFIED / 0 IF NOT. ; WD. 02 -- EFN MASK / FIRST WORD OF SENDER TASK NAME. ; WD. 03 -- EFN ADDRESS / SECOND WORD OF SENDER TASK NAME. ; WD. 04 -- REGION ID (ATTACHMENT DESCRIPTOR ADDRESS). ; WD. 05 -- OFFSET IN REGION WORD. ; WD. 06 -- LENGTH OF MAP WORD. ; WD. 07 -- STATUS WORD. ; WD. 08 THRU WD. 017 -- CONTENTS OF SEND BUFFER. ;- .IF DF P$$SRF $DRSRF::BIT #T3.ACP!T3.NSD,T.ST3(R0) ;SENDS LEGAL TO RECEIVER? BNE 60$ ;IF NE NO MOV R0,-(SP) ;SAVE RECEIVER TASK TCB ADDRESS CALL $CEFNG ;CONVERT EFN AND LOCK IF GROUP GLOBAL ;MSH049 BCS 4$ ;IF CS NO EFN WAS SPECIFIED ;**-1 INCB T.SRCT(R5) ;INCREMENT NUMBER OF INCOMPLETE SREFS MOV R5,-(SP) ;SAVE SENDER TCB ADDRESS MOV R0,-(SP) ;SAVE EFN MASK MOV R1,-(SP) ;SAVE EFN ADDRESS BR 5$ ; 4$: CLR -(SP) ;INDICATE NO EFN SPECIFIED MOV T.NAM(R5),-(SP) ;SAVE SENDER TASK NAME MOV T.NAM+2(R5),-(SP) ; 5$: MOV (R3),R3 ;PICK UP ADDRESS OF WINDOW DEF BLOCK MOV #8.*2,R1 ;SET SIZE TO ADDRESS CHECK CALL $ACHKP ;ADDRESS CHECK AND MAP WINDOW DEF BLOCK ADD #W.NRID,R3 ;POINT TO REGION ID IN BLOCK CALL $SRATT ;SEARCH FOR SPECIFIED ATTACHMENT DESCRIPTOR CMP (R3)+,-(SP) ;BUMP POINTERS FOR REGION ID (W.NRID) MOV (R3)+,-(SP) ;SAVE OFFSET WORD (W.NOFF) MOV (R3)+,-(SP) ;SAVE LENGTH WORD (W.NLEN) MOV (R3)+,-(SP) ;SAVE STATUS WORD (W.NSTS) BIC #^C17,(SP) ;CLEAR ALL BUT ACCESS BNE 6$ ;IF NE ACCESS SPECIFIED MOVB A.STAT(R5),(SP) ;DEFAULT TO ACCESS OF SENDER TASK 6$: MOVB A.STAT(R5),-(SP) ;PUSH ATTACHMENT DESCRIPTOR ADDRESS COMB (SP) ;COMPUTE ACCESS DENIED MASK BITB (SP)+,(SP) ;CHECK SPECIFIED ACCESS AGAINST SENDER TASK BNE 70$ ;IF NE ACCESS DENIED MOV (R3),R3 ;POINT TO SEND BUFFER BEQ 10$ ;IF EQ THERE IS NONE MOV #8.*2,R1 ;SET SIZE TO ADDRESS CHECK CALL $ACHKP ;ADDRESS CHECK AND MAP SEND BUFFER ADD #8.*2,R3 ;POINT TO END OF SEND BUFFER 10$: CALL $ALPKT ;ALLOCATE A SEND PACKET ADD #16.*2,R0 ;POINT PAST END OF SEND BY REFERENCE DATA MOV #8.,R1 ;SET LOOP COUNT FOR COPY MOV R1,R2 ;COPY LOOP COUNT 20$: MOV R3,-(R0) ;WAS A SEND BUFFER SPECIFIED? BEQ 30$ ;IF EQ NO MOV -(R3),(R0) ;ELSE COPY NEXT WORD 30$: DEC R2 ;DONE YET? BGT 20$ ;IF GT NO MOV (SP),R4 ;PICK UP STATUS WORD 40$: MOV (SP)+,-(R0) ;INSERT SAVED WORDS ON STACK DEC R1 ;DONE YET? BGT 40$ ;IF GT NO MOV A.PCB(R5),R2 ;PICK UP PCB ADDRESS FROM ATT DESCRIPTOR BIT #PS.COM,P.STAT(R2) ;COMMON PARTITION? BEQ 90$ ;IF EQ NO, TASK PARTITION IS ILLEGAL MOV (R0),R5 ;PICK UP SAVED RECEIVER TASK ADDRESS MOV R0,-(SP) ;SAVE ADDRESS OF SEND PACKET CALL $CRATT ;ATTACH RECEIVER TASK TO REGION MOV (SP)+,R0 ;RETRIEVE ADDRESS OF PACKET BCS 80$ ;IF CS ALLOCATION FAILURE MOV R1,10(R0) ;SET REGION ID IN PACKET MOV R0,R1 ;COPY POINTER TO PACKET TST (R0)+ ;POINT TO TCB ADDRESS TST (R0)+ ;EFN SPECIFIED? BEQ 50$ ;IF EQ NO ;MSH049 .IF NDF G$$EFN ;MSH049 ;MSH049 BIC (R0)+,@(R0)+ ;CLEAR SPECIFIED EVENT FLAG NOW ;MSH049 .IFF ;MSH049 ;MSH049 MOV (R0)+,-(SP) ;GET EVENT FLAG MASK ;MSH049 MOV (R0),R0 ;GET EVENT FLAG MASK ADDRESS ;MSH049 BIC #1,R0 ;CLR GRP GLOBAL 2ND WORD INDICATOR ;MSH049 BIC (SP)+,(R0) ;CLEAR SPECIFIED EVENT FLAG NOW ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 50$: MOV R5,R0 ;POINT TO RECEIVE BY REFERENCE LISTHEAD ADD #T.RRFL,R0 ; .IF DF A$$TRP CALL $QINSF ;INSERT IN RECEIVE QUEUE MOV #AS.RRA,R4 ;SET RECEIVE BY REF AST TYPE CALL $DASTT ;DECLARE RECEIVE BY REFERENCE AST CALLR $DRDSE ;DECLARE A SIGNIFICANT EVENT .IFF CALLR $QINSF ;INSERT IN RECEIVE QUEUE AND EXIT .ENDC 60$: DRSTS D.RS2 ;ATTEMPT TO SEND TO AN ACP TASK 70$: DRSTS D.RS16 ;PRIVILEGE VIOLATION 80$: CALL $DEPKT ;DEALLOCATE SEND PACKET DRSTS D.RS1 ;ALLOCATION FAILURE 90$: CALL $DEPKT ;DEALLOCATE SEND PACKET DRSTS D.RS86 ;INVALID REGION ID (NOT COMMON BLOCK) ;+ ; **-$DRRRF-RECEIVE BY REFERENCE ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DEQUEUE THE NEXT RECEIVE BY ; REFERENCE PACKET IN THE RECEIVE QUEUE, OPTIONALLY EXITING IF THERE IS ; NOT ONE THERE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(81.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF WINDOW DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE WINDOW DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NSTS=CONTROL INFORMATION. ; WS.MAP=1 IF RECEIVED REFERENCE IS TO BE MAPPED. ; WS.RCX=1 IF TASK EXIT DESIRED IF NO PACKET FOUND. ; W.NSRB=OPTIONAL ADDRESS OF 10 WORD BUFFER FOR ADDITIONAL INFO. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THERE IS NO ; RECEIVE BY REFERENCE ENTRY IN THE QUEUE. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE ADDRESS ; CHECK OF THE RECEIVE BUFFER FAILS. ; ; OUTPUT FIELDS IN THE WINDOW DEFINITION BLOCK ARE: ; W.NRID=ASSIGNED REGION ID OF THE REFERENCED REGION. ; W.NOFF=OFFSET WORD SPECIFIED BY SENDER TASK. ; W.NLEN=LENGTH WORD SPECIFIED BY SENDER TASK. ; W.NSTS=STATUS WORD SPECIFIED BY SENDER TASK. ;  WS.RED=1 IF ATTACHED WITH READ ACCESS. ; WS.WRT=1 IF ATTACHED WITH WRITE ACCESS. ; WS.EXT=1 IF ATTACHED WITH EXTEND ACCESS. ; WS.DEL=1 IF ATTACHED WITH DELETE ACCESS. ; WS.RRF=1 IF RECEIVE WAS SUCCESSFUL. ;- $DRRRF::MOV KISAR6,-(SP) ;SAVE APR6 BIAS MOV R3,-(SP) ;SAVE WINDOW DEFINITION BLOCK POINTER MOV T.RRFL(R5),R2 ;PICK UP FIRST RECEIVE BY REF PACKET BEQ 60$ ;IF EQ THERE IS NONE CLR -(SP) ;INIT EFN ADDRESS CLR -(SP) ;INIT EFN MASK TST (R2)+ ;POINT TO RECEIVER TCB ADDRESS IN PACKET MOV (R2)+,R0 ;PICK UP TCB ADDRESS BEQ 20$ ;IF EQ NONE SPECIFIED DECB T.SRCT(R0) ;DECREMENT SENDER'S OUTSTANDING SREFS MOV (R2),(SP) ;SET REAL EFN MASK MOV 2(R2),2(SP) ;SET REAL EFN ADDRESS 20$: MOV R0,-(SP) ;SAVE TCB ADDRESS CMP (R2)+,(R2)+ ;SKIP TO REGION ID ADD #W.NRID,R3 ;POINT TO REGION ID WORD IN DEF BLOCK MOV (R2)+,(R3)+ ;STORE REGION ID MOV (R2)+,(R3)+ ;STORE OFFSET MOV (R2)+,(R3)+ ;STORE LENGTH BIS (R2)+,(R3)+ ;STORE ACCESS MOV (R3),R3 ;PICK UP VIRTUAL ADDR OF EXTENDED INFO BUFFER BEQ 40$ ;IF EQ THERE ONE WAS NOT SPECIFIED MOV #10.*2,R1 ;SET SIZE TO ADDRESS CHECK MOV R2,-(SP) ;SAVE R2 CALL $ACHKP ;ADDRESS CHECK THE BUFFER MOV (SP)+,R2 ;RESTORE R2 MOV -14(R2),(R3)+ ;STORE THE TASK NAME IN THE BUFFER MOV -12(R2),(R3)+ ; MOV -16(R2),R0 ;PICK UP SENDER TCB ADDRESS BEQ 25$ ;IF EQ THERE IS NONE MOV T.NAM+2(R0),-(R3) ;SET REAL TASK NAME MOV T.NAM(R0),-(R3) ; CMP (R3)+,(R3)+ ;POINT PAST TASK NAME 25$: MOV #8.,R0 ;SET LOOP COUNT FOR REST OF INFO  30$: MOV (R2)+,(R3)+ ;MOVE REST OF EXTRA INFO DEC R0 ;DONE YET? BGT 30$ ;IF GT NO 40$: MOV R5,R3 ;SAVE RECEIVER TASK TCB ADDRESS MOV (SP)+,R5 ;RETRIEVE SENDER TASK TCB ADDRESS MOV (SP)+,R0 ;RETRIEVE EVENT FLAG MASK MOV (SP)+,R1 ;RETRIEVE EVENT FLAG WORD ADDRESS BEQ 50$ ;IF EQ NO FLAG TO SET CALL $SETMG ;SET EFN AND UNLOCK IF GROUP GLOBAL ;MSH049 50$: MOV R3,R5 ;RESTORE TCB ADDRESS ;**-1 MOV R5,R0 ;POINT TO RECEIVE BY REFERENCE LISTHEAD ADD #T.RRFL,R0 ; CALL $QRMVF ;REMOVE PROCESSED PACKET MOV R1,R0 ;COPY POINTER TO PACKET CALL $DEPKT ;DEALLOCATE PACKET MOV (SP)+,R3 ;RESTORE WINDOW DEFINITION POINTER MOV (SP)+,KISAR6 ;RESTORE KERNAL APR6 BIAS BIS #WS.RRF,W.NSTS(R3) ;INDICATE SUCCESSFUL RECEIVE BY REFERENCE BIT #WS.MAP,W.NSTS(R3) ;WINDOW MAP DESIRED? BEQ 80$ ;IF EQ NO CALLR $DRMAP ;MAP WINDOW 60$: BIT #WS.RCX,W.NSTS(R3) ;DOES TASK WISH TO EXIT? BEQ 70$ ;IF EQ NO CMP (SP)+,(SP)+ ;CLEAN STACK JMP $DREXT ;PERFORM TASK EXIT 70$: DRSTS D.RS8 ;NO REFERENCES IN QUEUE 80$: RETURN ; .ENDC ;+ ; **-$DRGMX-GET MAPPING CONTEXT ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO RETURN THE MAPPING CONTEXT OF ; THE TASK, I.E. TO FILL IN UP TO N WINDOW DEFINITION BLOCKS, ; WHERE N IS THE TOTAL NUMBER OF WINDOW BLOCKS IN THE TASK HEADER. ; NO INFORMATION IS RETURNED ON UNUSED WINDOW BLOCKS. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(113.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF THE N WINDOW DEFINITION BLOCKS ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; (R3)=ADDRESS OF N WINDOW DEFINITION BLOCKS ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE WINDOW DEFINITION BLOCKS ARE: ; NONE. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE ADDRESS ; CHECK OF THE N WINDOW BLOCKS PLUS TERMINATOR WORD ; FAILS. ; ; OUTPUT FIELDS IN EACH WINDOW DEFINITION BLOCK ARE: ; W.NID=ADDRESS WINDOW ID OF NEXT ESTABLISHED ADDRESS WINDOW. ; W.NAPR=BASE APR OF THE WINDOW. ; W.NBAS=VIRTUAL BASE ADDRESS OF THE WINDOW. ; W.NSIZ=SIZE OF THE ADDRESS WINDOW. ; W.NRID=REGION ID IF MAPPED OR UNMODIFIED. ; W.NOFF=OFFSET IN REGION IF MAPPED OR UNMODIFIED. ; W.NLEN=LENGTH OF MAP IF MAPPED OR UNMODIFIED. ; W.NSTS=NECESSARY BITS TO RESTORE MAPPING OR 0 IF NOT MAPPED. ; WS.MAP=1 IF WINDOW IS MAPPED.  ; WS.WRT=1 IF WINDOW IS MAPPED WITH WRITE ACCESS. ;- .IF DF P$$GMX $DRGMX::MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOW BLOCKS IN HEADER MOV (R4)+,R1 ;PICK UP NUMBER OF WINDOW BLOCKS MOV R1,-(SP) ;SAVE NUMBER OF WINDOW BLOCKS ASL R1 ;CONVERT TO BYTES TO ADDRESS CHECK ASL R1 ; ASL R1 ; INC R1 ;(INCLUDE WORD FOR TERMINATOR) ASL R1 ; MOV (R3),R3 ;PICK UP VIRTUAL ADDRESS OF WINDOW BLOCKS CALL $ACHKP ;ADDRESS CHECK AND MAP TO WINDOW BLOCKS CLR -(SP) ;INITIALIZE WINDOW ID COUNTER 10$: TST W.BSIZ(R4) ;IS NEXT BLOCK AN ESTABLISHED WINDOW? BNE 11$ ;IF NE YES ADD #W.BLGH,R4 ;POINT TO NEXT WINDOW BLOCK BR 40$ ;BRANCH TO DETERMINE IF MORE BLOCKS 11$: MOVB (SP),(R3)+ ;SET WINDOW ID (W.NID) MOV (R4)+,-(SP) ;SAVE PCB ADDRESS (W.BPCB) MOV (R4)+,R1 ;PICK UP LOW VIRTUAL ADDRESS (W.BLVR) MOVB -1(R4),(R3) ;GET ITS HIGH BYTE (W.BLVR+1)(W.NAPR) ASLB (R3) ;SHIFT TO FORM APR NUMBER (W.NAPR) ROLB (R3) ; ROLB (R3) ; ROLB (R3)+ ; MOV R1,(R3)+ ;SET VIRTUAL BASE ADDRESS (W.NBAS) MOV (R4)+,R2 ;PICK UP HIGH VIRTUAL ADDRESS (W.BHVR) MOV (R4)+,R0 ;PICK ATT DESCRIPTOR ADDRESS (W.BATT) MOV (R4)+,(R3)+ ;SET WINDOW SIZE (W.BSIZ)(W.NSIZ) TST (SP)+ ;IS THIS WINDOW MAPPED? BEQ 20$ ;IF EQ NO MOV R0,(R3)+ ;SET REGION ID (W.NRID) MOV T.ATT(R5),-(SP) ;PUSH ADDRESS OF FIRST ATTACHMENT DESCRIPTOR SUB #A.TCBL,(SP) ;POINT TO FIRST WORD CMP R0,(SP)+ ;TASK REGION? BNE 15$ ;IF NE NO CLR -2(R3) ;SET IT TO DEFAULT TO TASK REGION (W.NRID) 15$: MOV (R4)+,(R3)+ ;SET OFFSET (W.BOFF)(W.NOFF) SUB R1,R2 ;CALCULATE LENGTH ADD #1,R2 ; ROL R2 ;CONVERT TO 32W BLOCKS ROL R2 ; ROLB R2 ; SWAB R2 ; MOV R2,(R3)+ ;SET THE LENGTH (W.NLEN) TST (R4)+ ;ADVANCE TO LAST PDR IMAGE (W.BFPD) MOV (R4)+,(R3) ;PICK UP LAST PDR IMAGE (W.BLPD)(W.NSTS) BIC #^C4,(R3) ;CLEAR ALL BUT WRITE ACCESS BIT (W.NSTS) ASR (R3) ;SHIFT INTO PLACE (W.NSTS) BIS #WS.MAP,(R3)+ ;INDICATE WINDOW IS MAPPED (W.NSTS) BR 30$ ; 20$: ADD #W.NSTS-W.NRID,R3 ;POINT TO NEXT WINDOW ID BLOCK ADD€ #W.BLGH-W.BOFF,R4 ;POINT TO NEXT WINDOW BLOCK CLR (R3)+ ;CLEAR STATUS WORD 30$: TST (R3)+ ;SKIP OVER SEND/RECEIVE BUFFER ADDRESS (W.NSRB) 40$: INC (SP) ;BUMP WINDOW ID CMP (SP),2(SP) ;DONE YET? BLO 10$ ;IF LO NO MOV (SP)+,(R3) ;STORE NUMBER OF HEADER SLOTS AS TERMINATOR NEG (R3) ;AND NEGATE TST (SP)+ ;CLEAN STACK RETURN ; .ENDC .ENDC .END €ÝàGkQ ›c, .TITLE DRMKT .IDENT /05.01/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.01 ; ; D. N. CUTLER 5-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 17-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; MARK TIME AND RUN DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$ CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSETS ;+ ; **-$DRMKT-MARK TIME ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DECLARE A SIGNIFICANT EVENT AT A ; SPECIFIED INTERVAL FROM INSSUANCE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(23.),DPB SIZE(5.). ; WD. 01 -- EVENT FLAG NUMBER OF EVENT FLAG TO BE SET. ; WD. 02 -- TIME INTERVAL MAGNITUDE. ; WD. 03 -- TIME INTERVAL UNITS. ; WD. 04 -- AST ENTRY POINT ADDRESS. ; ; IF AN EVENT FLAG IS SPECIFIED, THEN IT IS CLEARED AT ISSUANCE AND ; SET AT THE TIME OF THE SIGNIFICANT EVENT. ; ; IF AN AST ENTRY POINT IS SPECIFIED, THEN AN ASYNCHRONOUS TRAP ; WILL OCCUR AT THE TIME OF THE SIGNIFICANT EVENT. PS, PC, THE ; DIRECTIVE STATUS WORD, AND THE SPECIFIED EVENT FLAG NUMBER ; ARE PUSHED ONTO THE TASK STACK WHEN THE AST IS EFFECTED. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE THIRD WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS WORD RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF INSUFFICIENT ; CORE IS AVAILABLE TO ALLOCATE CLOCK QUEUE ENTRY. ;- .ENABL LSB $DRMKT::MOV -2(R3),-(SP) ;SAVE EVENT FLAG NUMBER MOV R1,-(SP) ;SAVE EVENT FLAG MASK ADDRESS ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 BIC #1,R1 ;CLR GRP GLOBAL EFN 2ND WORD INDICATOR ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 BIC R0,(R1) ;CLEAR EVENT FLAG MOV R0,R4 ;SAVE EVENT FLAG MASK ;**-1 CALL $CVRTM ;CONVERT TIME TO CLOCK TICKS MOV R0,-(SP) ;SAVE HIGH ORDER PART OF TIME MOV R1,-(SP) ;SAVE LOW ORDER PART OF TIME MOV R4,-(SP) ;SAVE EVENT FLAG MASK CLR R4 ;SET TYPE OF CLOCK QUEUE ENTRY MOV (R3),-(SP) ;SAVE AST ENTRY POINT ADDRESS BR 20$ ; ;+ ; **-$DRRUN-RUN TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO GENERATE A CLOCK QUEUE ENTRY ; TO CAUSE A TASK TO BE REQUESTED AT A SPECIFIED DELTA TIME FROM ; ISSUANCE AND TO OPTIONALLY REPEAT THE REQUEST PERIODICALLY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(17.),DPB SIZE (11.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; WD. 03 -- PARTITION NAME-NOT SUPPORTED BUT MUST BE PRESENT. ; WD. 04 -- PARTITION NAME-NOT SUPPORTED BUT MUST BE PRESENT. ; WD. 05 -- REQUEST PRIORITY-NOT SUPPORTED BUT MUST BE PRESENT. ; WD. 06 -- REQUEST UIC. ; WD. 07 -- DELTA TIME MAGNITUDE. ; WD. 10 -- DELTA TIME UNITS. ; WD. 11 -- RESCHEDULE INTERVAL MAGNITUDE. ; WD. 12 -- RESCHEDULE INTERVAL UNITS. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE OF THE TASK TO BE RUN. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO BE RUN. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE PARTITION NAME IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF INSUFFICIENT ; CORE IS AVAILABLE TO ALLOCATE CLOCK QUEUE ENTRY. ;- $DRRUN::MOV R0,R5 ;SAVE TCB ADDRESS OF TASK TO RUN ADD #6,R3 ;POINT TO REQUEST UIC IN DPB CLR -(SP) ;SET DUMMY EFN NUMBER .IF DF M$$MUP MOV (R3)+,R1 ;PICK UP SPECIFIED UIC MOV R3,-(SP) ;SAVE R3 CALL $UISET ;ESTABLISH DEFAULT AND CURRENT UIC'S MOV (SP)+,R3 ;RESTORE R3 BCS 30$ ;IF CS NONPRV TASK SPECIFIED DIFF UIC MOV R1,-(SP) ;SAVE CURRENT UIC .IFF MOV (R3)+,-(SP) ;SAVE SPECIFIED UIC .ENDC CALL $CVRTM ;CONVERT DELTA TIME TO CLOCK TICKS MOV R0,-(SP) ;SAVE HIGH ORDER PART OF TIME MOV R1,-(SP) ;SAVE LOW ORDER PART OF TIME MOV #C.SSHT,R4 ;ASSUME SINGLE SHOT REQUEST MOV (R3)+,R0 ;ANY RESCHEDULE INTERNAL SPECIFIED? BEQ 10$  ;IF EQ NO CMP -(R3),-(R4) ;ADJUST DPB ADDRESS AND ENTRY TYPE CALL $CVRTM ;CONVERT RESCHEDULE INTERNAL TO CLOCK TICKS 10$: MOV R0,-(SP) ;SAVE HIGH ORDER PART OF TIME MOV R1,-(SP) ;SAVE LOW ORDER PART OF TIME 20$: CALL $ALCLK ;ALLOCATE A CLOCK QUEUE CONTROL BLOCK MOV (SP)+,C.RSI(R0) ;INSERT AST ADDRESS/LOW PART OF RSI MOV (SP)+,C.RSI+2(R0) ;INSERT EFN MASK/HIGH PART OF RSI MOV (SP)+,R2 ;RETRIEVE DELTA TIME TICKS COUNT MOV (SP)+,R1 ; MOV (SP)+,C.UIC(R0) ;INSERT EFN MASK ADDRESS/UIC MOVB ²(SP)+,C.EFN(R0) ;INSERT EFN/ZERO BYTE CALLR $CLINS ;INSERT IN CLOCK QUEUE .IF DF M$$MUP 30$: DRSTS D.RS16 ;PRIVILEGE VIOLATION .ENDC .DSABL LSB .END ²à`†kQ ›c, .TITLE DRPUT .IDENT /10.03/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 10.03 ; ; D. N. CUTLER 6-SEPT-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; JOHN COVERT ; ; MODIFIED BY: ; ; M. S. HARVEY 6-OCT-80 ; MSH121 -- ADD SPECIFY REQUESTED EXIT AST DIRECTIVE ; ; M. S. FOX 30-JAN-81 ; MF208 -- ADD COMMAND ARRIVAL AST FOR CLIS ; ; SPECIFY FLOATING POINT, POWERFAIL, AND RECEIVE AST TRAPS ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,TCBDF$,PKTDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE SPECIFIED AST TYPES ;+ ;MSH121 ; **-$DRREX-SPECIFY REQUESTED EXIT AST ;MSH121 ; ;MSH121 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT ;MSH121 ; REQUESTED EXIT ASTS ARE DESIRED OR NOT DESIRED FOR THE ISSUING ;MSH121 ; TASK. WHEN THE AST OCCURS, IT BECOMES DESPECIFIED FOR ;MSH121 ; NONPRIVILEGED TASKS. NONPRIVILEGED TASKS MAY NOT RESPECIFY ;MSH121 ; THIS AST AFTER IT HAS BEEN EFFECTED ONCE. ;MSH121 ; ;MSH121 ; DPB FORMAT: ;MSH121 ; ;MSH121 ; WD. 00 -- DIC(167.),DPB SIZE(2. OR 3.). ;MSH121 ; WD. 01 -- AST ENTRY POINT ADDRESS OR ZERO. ;MSH121 ; WD. 02 -- RESERVED FOR FUTURE USE. ;MSH121 ; ;MSH121 ; INPUTS: ;MSH121 ; ;MSH121 ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ;MSH121 ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB ;MSH121 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ;MSH121 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ;MSH121 ; ;MSH121 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ;MSH121 ; ;MSH121 ; C=0 IF DIRECTIVE SUCCESSFULLY COMPLETED ;MSH121 ; DIRECTIVE STATUS OF +1 IS RETURNED. ;MSH121 ; C=1 IF DIRECTIVE REJECTED. ;MSH121 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF ASTS ARE ;MSH121 ; ALREADY NOT DESIRED, OR NONPRIVILEGED TASK ;MSH121 ; ATTEMPTED TO RESPECIFY THIS AST AFTER ONE ;MSH121 ; HAD ALREADY BEEN EFFECTED, OR NONPRIVILEGED ;MSH121 ; TASK ATTEMPTED TO CANCEL A REQUESTED EXIT ;MSH121 ; AST AFTER IT HAD ALREADY BEEN DESPECIFIED ;MSH121 ; WHEN THE AST OCCURRED. ;MSH121 ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF ;MSH121 ; DIRECTIVE WAS ISSUED FROM AN AST ROUTINE, ;MSH121 ; OR ISSUING TASK HAD AST RECOGNITION DISABLED. ;MSH121 ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE DPB ;MSH121 ; SIZE IS ILLEGAL ;MSH121 ;- ;MSH121 ;MSH121 .ENABL LSB ;MSH121 ;MSH121 ;MSH121 .IF DF A$$TRP&A$$BRT ;MSH121 ;MSH121 $DRREX::BIT #T2.REX,T.ST2(R5) ;ABORT AST ALREADY EFFECTED? ;MSH121 BEQ 5$ ;IF EQ NO ;MSH121 BIT #T3.PRV,T.ST3(R5) ;ISSUING TASK PRIVILEGED? ;MSH121 BNE 50$ ;IF NE YES, TASK AT AST OR DST STATE ;MSH121 BR 60$ ;NON-PRV. TASK CAN'T REISSUE DIRECTIVE ;MSH121 ;MSH121 5$: CLR -(SP) ;ASSUME NO PARAMETERS TO RETURN ;MSH121 MOV #7.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE ;MSH121 MOVB -(R3),R4 ;GET DPB SIZE BYTE ;MSH121 CMPB (R3)+,#2 ;CORRECT SIZE FOR OLD FORM OF DIRECTIVE?;MSH121 BEQ 7$ ;IF EQ YES, FINISH AST SPECIFICATION ;MSH121 CMPB R4,#3 ;CORRECT SIZE FOR EXTENDED FORM? ;MSH121 BNE 9$ ;IF NE NO ;MSH121 ADD #2.*2,(SP) ;ADJUST NUMBER OF BYTES TO ALLOCATE AND ;MSH121 MOV #2,2(SP) ;NUMBER OF PARAMS FOR EXTENDED DIRECTIVE;MSH121 7$: MOV #AS.REA,R4 ;SET TYPE FOR ABORT AST ;MSH121 MOV #,-(SP) ;PUSH TYPE FOR ABORT AST ;MSH121 BR 10$ ;JOIN COMMON CODE ;MSH121 ;MSH121 9$: DRSTS D.RS99 ;ILLEGAL DPB LENGTH ;MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 ;MSH121 ; MF208 ;+ ; MF208 ; **-$CAAST-COMMAND ARRIVAL AST FOR CLIS ; MF208 ; ; MF208 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT COMMAND ; MF208 ; ARRIVAL ASTS ARE DESIRED OR NOT DESIRED FOR THE CLI TASK ; MF208 ; THAT ISSUED THE DIRECTIVE. THIS ROUTINE IS ENTERED WHEN THE DRCLI ; MF208 ; MODULE DETECTS THIS DIRECTIVE. ; MF208 ; ; MF208 ; DPB FORMAT: ; MF208 ; ; MF208 ; WD. 01 -- DIC(173.),DPB SIZE (2.) ; MF208 ; WD. 02 -- AST ENTRY POINT ADDRESS OR ZERO ; MF208 ; ; MF208 ; INPUTS: ; MF208 ; ; MF208 ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK ; MF208 ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB ; MF208 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK ; MF208 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK ; MF208 ; ; MF208 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; MF208 ; ; MF208 ; C=0 IF DIRECTIVE SUCCESSFULLY COMPLETED. ; MF208 ; DIRECTIVE STATUS OF +1 IS RETURNED ; MF208 ; C=1 IF DIRECTIVE IS REJECTED ; MF208 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST'S ARE ; MF208 ; ALREADY NOT DESIRED. ; MF208 ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF DIRECTIVE ; MF208 ; WAS ISSUED FROM AN AST ROUTINE. ; MF208 ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF DIRECTIVE ; MF208 ; WAS ISSUED BY A TASK WHICH IS NOT A CLI. ; MF208 ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF THERE ; MF208 ; IS INSUFFICIENT POOL TO ALLOCATE AN AST BLOCK ; MF208 ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE DPB ; MF208 ; SIZE IS ILLEGAL. ; MF208 ; ; MF208 ;- ; MF208 ; MF208 .IF DF A$$CLI&A$$TRP ; MF208 ; MF208 $CAAST::BIT #T3.CLI,T.ST3(R5) ;IS CURRENT TASK A CLI ; MF208 BEQ 70$ ;IF EQ NO ; MF208 MOV #AS.CAA,R4 ;SET TYPE FOR CMD ARRIVAL AST ; MF208 MOV #1,-(SP) ;SET NUMBER OF AST PARAMETERS ; MF208 MOV #8.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE ; MF208 MOV #,-(SP) ;PUSH TYPE FOR CMD ARRIVAL AST ; MF208 BR 10$ ;FINISH IN COMMON CODE ; MF208 ; MF208 .ENDC ;A$$CLI&A$$TRP ; MF208 ; MF208 ;+ ; **-$DRFEX-SPECIFY FLOATING POINT EXCEPTION AST ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT FLOATING POINT ; AST'S ARE DESIRED OR NOT DESIRED FOR THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(111.),DPB SIZE(2.). ; WD. 01 -- AST ENTRY POINT ADDRESS OR ZERO. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST'S ARE ALREADY ; NOT DESIRED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF DIRECTIVE WAS ; ISSUED FROM AN AST ROUTINE. ;- ;**-2 .IF DF A$$TRP&F$$LPP $DRFEX::TST H.FPSA(R4) ;IS THE TASK BUILT WITH FLOATING POINT BEQ 60$ ;IF EQ NO -- BUILT /-FP, GIVE IE.ITS MOV #AS.FPA,R4 ;SET TYPE FOR FLOATING POINT AST MOV #2,-(SP) ;SET NUMBER OF AST PARAMETERS MOV #9.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE MOV #,-(SP) ;PUSH TYPE FOR FLOATING POINT AST BR 10$ ;FINISH IN COMMON CODE .ENDC ;+ ; **-$DRPUT-SPECIFY POWER RECOVERY AST ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT POWER RECOVERY ; AST'S ARE DESIRED OR NOT DESIRED FOR THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(109.),DPB SIZE(2.). ; WD. 01 -- AST ENTRY POINT ADDRESS OR ZERO. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST'S ARE ALREADY ; NOT DESIRED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF DIRECTIVE WAS ; ISSUED FROM AN AST ROUTINE. ;- .IF DF A$$TRP&P$$RFL $DRPUT::MOV #AS.PFA,R4 ;SET TYPE FOR POWERFAIL AST CLR -(SP) ;SET NUMBER OF AST PARAMETERS MOV #7.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE MOV #,-(SP) ;PUSH TYPE FOR POWERFAIL AST BR 10$ ;FINISH IN COMMON CODE .ENDC ;+ ; **-$DRRRA-SPECIFY RECEIVE BY REFERENCE AST ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT RECEIVE ; BY REFERENCE AST'S ARE DESIRED OR NOT DESIRED FOR THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(21.),DPB SIZE(2.). ; WD. 01 -- AST ENTRY POINT ADDRESS OR ZERO. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF THE DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF THE DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST'S ARE ; ALREADY NOT DESIRED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF DIRECTIVE ; WAS ISSUED FROM AN AST ROUTINE. ;- .IF DF A$$TRP&P$$LAS&P$$SRF $DRRRA::MOV #AS.RRA,R4 ;SET TYPE FOR RECEIVE BY REF AST CLR -(SP) ;SET NUMBER OF AST PARAMETERS MOV #7.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE MOV #,-(SP) ;PUSH TYPE FOR RECEIVE BY REF AST BR 10$ ;FINISH IN COMMON CODE .ENDC ;+ ; **-$DRRCV-SPECIFY RECEIVE AST ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EITHER RECORD THAT RECEIVE ; AST'S ARE DESIRED OR NOT DESIRED FOR THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(107.),DPB SIZE(2.). ; WD. 01 -- AST ENTRY POINT ADDRESS OR ZERO. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE AST ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF THE DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF THE DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AST'S ARE ALREADY ; NOT DESIRED. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF DIRECTIVE WAS ; ISSUED FROM AN AST ROUTINE. ;- .IF DF A$$TRP&R$$SND $DRRCV::MOV #AS.RCA,R4 ;SET TYPE FOR RECEIVE DATA AST CLR -(SP) ;SET NUMBER OF AST PARAMETERS MOV #7.*2,-(SP) ;SET NUMBER OF BYTES TO ALLOCATE MOV #,-(SP) ;PUSH TYPE FOR RECEIVE DATA AST .ENDC ; ;MSH121 ; COMMON AST SPECIFICATION AND CANCELLATION CODE ;MSH121 ; ;MSH121 ;MSH121 .IF DF F$$LPP!P$$RFL!P$$SRF!R$$SND!A$$BRT!A$$CLI ;MSH121 ;**-1 .IF DF A$$TRP 10$: BIT #T2.AST!T2.DST,(R2) ;ISSUED FROM AST OR AST'S DISABLED? BNE 50$ ;IF NE YES MOV (R3),R3 ;GET AST TRAP ADDRESS BEQ 30$ ;IF EQ AST'S NOT DESIRED CALL $SRAST ;SEARCH FOR SPECIFIED AST CONTROL BLOCK BCC 20$ ;IF CC, ONE ALREADY EXISTS CALL $ALCLK ;ALLOCATE AN AST CONTROL BLOCK MOV R5,R1 ;COPY TCB ADDRESS OF CURRENT TASK MOV T.SAST(R1),(R0) ;LINK LIST TO NEW CONTROL BLOCK MOV R0,T.SAST(R1) ;LINK NEW CONTROL BLOCK TO LISTHEAD 20$: MOV R0,R1 ;COPY CONTROL BLOCK ADDRESS TST (R1)+ ;POINT TO AST TYPE IN CONTROL BLOCK MOV (SP)+,(R1)+ ;SET AST TYPE MOV (SP)+,(R1)+ ;SET NUMBER OF BYTES PER AST MOV R3,(R1)+ ;SET AST TRAP ADDRESS MOV (SP)+,(R1) ;SET NUMBER OF PARAMETERS PER AST BR 40$ ;TAKE COMMON EXIT ;MSH121 ; ;MSH121 ; CANCEL SPECIFIABLE ASTS HERE ;MSH121 ; ;MSH121 ;MSH121 30$: CALL $SRAST ;SEARCH FOR SPECIFIED AST CONTROL BLOCK BCS 60$ ;IF CS, THIS TYPE NOT ENABLED MOV (R0),(R1) ;REMOVE THIS TYPE FROM LIST CALL $DECLK ;DEALLOCATE THIS CONTROL BLOCK 40$: DRSTS +1 ;RETURN SUCCESSFUL DIRECTIVE STATUS 50$: DRSTS D.RS80 ;SET DIRECTIVE STATUS 60$: DRSTS D.RS8 ;SET DIRECTIVE STATUS ; MF208 ; MF208 .IF DF A$$CLI ;À MF208 ; MF208 70$: DRSTS D.RS16 ;SET DIRECTIVE STATUS ; MF208 ; MF208 .ENDC ;A$$CLI ; MF208 ; MF208 .ENDC .ENDC .DSABL LSB .END Àâ8 kQ ›c, .TITLE DRRAS .IDENT /09.10/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 09.10 ; ; D. N. CUTLER 4-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; CHUCK SPITZ ; ALAN GROUPE ; ; MODIFIED BY: ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 8-JAN-80 ; MSH083 -- CORRECT HEADER ADDRESS HANDLING AND CLEAN ; UP THE CODE AND COMMENTS ; ; M. S. HARVEY 20-JAN-81 ; MSH143 -- DON'T SET EVENT FLAG WHEN 'SEND DATA' REJECTED ; DUE TO INSUFFICIENT POOL ; ; RECEIVE AND SEND DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRREC-RECEIVE DATA AND RECEIVE DATA OR EXIT ; **-$DRRCS-RECEIVE DATA OR STOP ; ; THESE DIRECTIVES INSTRUCT THE SYSTEM TO DEQUEUE A DATA BLOCK FROM THE ; ISSUING TASK'S RECEIVE QUEUE. IF THE DIRECTIVE IS RECEIVE DATA OR EXIT, ; THEN A TASK EXIT WILL BE EFFECTED IF NO DATA IS QUEUED. IF THE ; DIRECTIVE IS RECEIVE OR STOP, THEN THE ISSUING TASAK WILL BE SUSPENDED ; IF NO DATA IS QUEUED. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(75., 77. OR 139.),DPB SIZE(4.). ; WD. 01 -- FIRST HALF OF SENDER TASK NAME OR 0 FOR ANY TASK. ; WD. 02 -- SECOND HALF OF SENDER TASK NAME. ; WD. 03 -- ADDRESS OF A FIFTEEN WORD RECEIVE BUFFER. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; DIRECTIVE STATUS OF 'D.RS22' IS RETURNED IF NO DATA ; IS RECEIVED ON RECEIVE OR STOP. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF NO DATA ; IS QUEUED IN TASK'S RECEIVE QUEUE ON RECEIVE ; DATA DIRECTIVE. ; DIRECTIVE STATUS OF 'D.RS80' IS RETURNED IF THE ISSUING ; TASK IS AT AST STATE AND ISSUED THE RECEIVE OR ; STOP DIRECTIVE. ; DIRECTIVE STATUS OF 'D.RS17' IS RETURNED IF THE ;MSH076 ; ISSUING TASK IS A SLAVE TASK AND HAS AN ;MSH076 ; ACTIVE GROUP GLOBAL EVENT FLAG CONTEXT ;MSH076 ; AND THE NEXT RECEIVE PACKET WILL CHANGE ;MSH076 ; THE TASK'S GROUP NUMBER. ;MSH076 ; ;- .IF DF R$$SND .IF DF S$$TOP $DRRCS::TST (R2) ;ISSUING TASK AT AST STATE? ;**-2 BPL $DRREC ;IF PL NO ;MSH083 DRSTS D.RS80 ;ISSUING TASK IS AT AST STATE ;MSH083 ;**-1 .ENDC ;S$$TOP $DRREC::MOV R4,-(SP) ;SAVE HEADER ADDRESS ;MSH083 MOV (R3)+,-(SP) ;SAVE FIRST HALF OF SENDER TASK NAME ;**-1 MOV (R3)+,-(SP) ;SAVE SECOND HALF OF SENDER TASK NAME MOV (R3),R3 ;GET ADDRESS OF RECEIVE BUFFER .IF DF A$$CHK!M$$MGE MOV #15.*2,R1 ;SET SIZE OF BUFFER CALL $ACHKP ;ADDRESS CHECK AND RELOCATE RECEIVE BUF ;MSH083 ;**-1 .ENDC MOV R3,R4 ;SAVE APR6 DISPLACEMENT OF RECEIVE BUF ;MSH083 MOV (SP)+,R3 ;RETRIEVE 2ND HALF OF SENDER TASK NAME ;**-1 MOV (SP)+,R2 ;RETRIEVE FIRST HALF OF SENDER TASK NAME MOV R5,R0 ;CALCULATE ADDRESS OF TASK RECEIVE ADD #T.RCVL,R0 ;QUEUE LISTHEAD MOV R0,R1 ;COPY LISTHEAD ADDRESS 3$: MOV (R1),R1 ;POINT TO NEXT ENTRY IN RECEIVE LIST BEQ 20$ ;IF EQ THERE IS NONE TST R2 ;TASK NAME SPECIFIED?  BEQ 4$ ;IF EQ NO, DEQUEUE FIRST BLOCK CMP 2(R1),R2 ;MATCH ON FIRST WORD OF TASK NAME? BNE 3$ ;IF NE NO CMP 4(R1),R3 ;MATCH ON SECOND WORD OF TASK NAME? BNE 3$ ;IF NE NO 4$: MOV (SP)+,R2 ;RETRIEVE HEADER ADDRESS ;MSH083 ;MSH083 .IF DF G$$EFN ;MSH076 ;MSH076 BIT #T3.SLV,T.ST3(R5) ;IS THIS TASK A SLAVE TASK? ;MSH076 BEQ 45$ ;IF EQ NO ;MSH076 TSTB T.GGF(R5) ;TASK HAVE ACTIVE GRP GLOBAL CONTEXT? ;MSH076 BEQ 45$ ;IF EQ NO, ALLOW RECEIVE ;MSH076 CMPB H.CUIC+1(R2),43(R1) ;WILL GROUP CHANGE WITH THIS PACKET?;MSH083 BEQ 45$ ;IF EQ NO, ALLOW RECEIVE ;MSH076 DRSTS D.RS17 ;SLAVE TASK HAS GRP GBL CONTEXT ACTIVE ;MSH076 ;MSH076 .ENDC ;G$$EFN ;MSH076 ;MSH076 45$: CALL $QRMVT ;DEQUEUE THE APPROPRIATE PACKET ;MSH076 BIT #T3.SLV,T.ST3(R5) ;IS RECEIVER A SLAVE TASK? ;**-5 BEQ 5$ ;IF EQ NO MOV 40(R1),T.UCB(R5) ;SET TI ADDRESS OF RECEIVER MOV $HEADR,R2 ;PICK UP CURRENT TASK HEADER ADDRESS MOV 42(R1),H.CUIC(R2) ;SET CURRENT UIC OF RECEIVER MOV 42(R1),H.DUIC(R2) ;SET DEFAULT UIC OF RECEIVER 5$: MOV R1,R0 ;SAVE ADDRESS OF ENTRY REMOVED ;**-4 TST (R1)+ ;POINT TO SENDER TASK NAME ;MSH083 MOV #15.,R2 ;SET LOOP COUNT ;**-1 10$: MOV (R1)+,(R4)+ ;MOVE DATA BLOCK TO TASK BUFFER DEC R2 ;ANY MORE WORDS TO MOVE? BGT 10$ ;IF GT YES CALLR $DEPKT ;DEALLOCATE RECEIVE QUEUE PACKET 20$: MOV (SP)+,R4 ;RETRIEVE HEADER ADDRESS ;MSH083 CMPB #77.,$DICSV ;RECEIVE DATA OR EXIT DIRECTIVE? ;MSH083 BNE 30$ ;IF NE NO ;MSH083 CALLR $DREXT ;EXIT TASK ;MSH083 30$: ;MSH083 .IF DF S$$TOP ;MSH083 ;MSH083 CMPB #139.,$DICSV ;RECEIVE OR STOP DIRECTIVE? ;MSH083 BNE 50$ ;IF NE NO, JUST A RECEIVE DATA ;MSH083 CALL $STPCT ;STOP CURRENT TASK ;MSH083 DRSTS D.RS22 ;RETURN IS.SET ;MSH083 ;MSH083 .ENDC ;MSH083 ;MSH083 50$: DRSTS D.RS8 ;NO PACKET TO RECEIVE ;MSH083 ;**-36 ;+ ; **-$DRSND-SEND DATA ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO QUEUE A THIRTEEN WORD DATA BLOCK ; IN A SPECIFIED TASK'S RECEIVE QUEUE. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(71.),DPB SIZE(5.). ; WD. 01 -- FIRST HALF OF RECEIVER TASK NAME. ; WD. 02 -- SECOND HALF OF RECEIVER TASK NAME. ; WD. 03 -- ADDRESS OF THIRTEEN WORD DATA BLOCK. ; WD. 04 -- EVENT FLAG NUMBER (OPTIONAL). ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE RECEIVER TASK. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE RECEIVER TASK. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE DATA BLOCK ADDRESS IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF INSUFFICIENT ; CORE IS AVAILABLE TO QUEUE THE DATA BLOCK. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF RECEIVER ; TASK IS AN ANCILLARY CONTROL PROCESSOR. ;- $DRSND::BIT #T3.ACP!T3.NSD,T.ST3(R0) ;SENDS ALLOWED TO RECEIVER? BNE 20$ ;IF NE NO MOV R0,-(SP) ;SAVE TCB ADDRESS OF RECEIVER TASK MOVB 2(R3),-(SP) ;SAVE EVENT FLAG NUMBER MOV (R3),R3 ;GET ADDRESS OF DATA BUFFER .IF DF A$$CHK!M$$MGE MOV #13.*2,R1 ;SET SIZE OF BUFFER CALL $ACHKP ;ADDRESS CHECK DATA BUFFER .ENDC CALL $ALPKT ;ALLOCATE SEND PACKET ;**-2 MOV T.UCB(R5),40(R0) ;SET UCB ADDRESS ;**-4 MOV H.CUIC(R4),42(R0) ;SET CURRENT (PROTECTION) UIC MOV R0,R4 ;SAVE PACKET ADDRESS ;MSH143 MOVB (SP)+,R0 ;RETRIEVE OPTIONAL EVENT FLAG NUMBER ;MSH143 CALL $SETF ;SET THE EVENT FLAG ;MSH143 MOV R3,R0 ;SAVE ADDRESS OF DATA BUFFER ;MSH143 MOV R4,R1 ;COPY ADDRESS OF ALLOCATED PACKET ;MSH143 TST (R4)+ ;POINT TO SECOND WORD OF PACKET ;MSH143 MOV T.NAM(R5),(R4)+ ;INSERT SENDER TASK NAME IN SEND PACKET ;MSH143 MOV T.NAM+2(R5),(R4)+ ; ;MSH143 MOV #13.,R2 ;SET LOOP COUNT ;**-9 10$: MOV (R0)+,(R4)+ ;MOVE DATA TO SEND PACKET ;MSH143 Æ DEC R2 ;ANY MORE WORDS TO MOVE? ;**-1 BGT 10$ ;IF GT YES MOV (SP),R0 ;CALCULATE ADDRESS OF RECEIVER TASK'S ADD #T.RCVL,R0 ;RECEIVE QUEUE LISTHEAD CALL $QINSF ;INSERT SEND PACKET IN RECEIVE QUEUE MOV #AS.RCA,R4 ;SET CODE FOR RECEIVE DATA AST MOV (SP)+,R5 ;RETRIEVE RECEIVER TASK TCB ADDRESS CALL $DASTT ;DECLARE RECEIVE AST CALLR $DRDSE ;DECLARE A SIGNIFICANT EVENT 20$: DRSTS D.RS2 ;SET DIRECTIVE STATUS .ENDC .END Æâè!kQ ›c, .TITLE DRREQ .IDENT /05.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 05.00 ; ; D. N. CUTLER 13-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 22-DEC-80 ; MSH066 -- CORRECT COMMENTS ; ; REQUEST TASK DIRECTIVE ; ; MACRO LIBRARY CALLS ; .IF NDF P$$OFF .MCALL TCBDF$ TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRREQ-REQUEST TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO REQUEST THE EXECUTION ; OF A SPECIFIED TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(11.),DPB SIZE(7.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; WD. 03 -- PARTITION NAME-NOT SUPPORTED BUT MUST BE PRESENT. ; WD. 04 -- PARTITION NAME-NOT SUPPORTED BUT BUST BE PRESENT. ; WD. 05 -- REQUEST PRIORITY-NOT SUPPORTED BUT MUST BE PRESENT. ; WD. 06 -- REQUEST UIC. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO BE REQUESTED. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO BE REQUESTED. ; R2=ADDRESS OF SECOND TASK STATUS WORD OF THE CURRENT TASK. ;MSH066 ; R3=ADDRESS OF THE PARTITION NAME IN THE DPB. ;**-1 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF PARTITION ; CONTROL BLOCK CANNOT BE ALLOCATED. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF SPECIFIED. ; TASK IS ALREADY ACTIVE. ;- $DRREQ::MOV 6(R3),R1 ;GET REQUEST UIC .IF DF M$$MUP CALL $UISET ;ESTABLISH DEFAULT AND CURRENT UIC'S .ENDC MOV T.UCB(R5),R2 ;GET ADDRESS OF REQUESTER TI UCB CALL $TSKRP ;REQUEST TASK EXECUTION BCS 10$ ;IF CS TASK. ALREADY ACTIVE RETURN ;RETURN DIRECTIVE STATUS OF +1 .IF DF D$$YNM&M$$MGE 10$: BEQ 20$ ;IF EQ TASK ALREADY ACTIVE DRSTS D.RS1 ;SET DIRECTIVE STATUS 20$: DRSTS D.RS7 ;SET DIRECTIVE STATUS .IFF 10$: DRSTS D.RS7 ;SET DIRECTIVE STATUS .ENDC .ENDC ;NDF P$$OFF .END .LSðskQ ›c, .TITLE MMDRV .IDENT /5.38/ ; ; COPYRIGHT (C) 1978, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ;VERSION 5.38 ; ; JANICE CLEARY 15-SEP-75 ; ; J. CLEARY 27-DEC-78 ; ; JC026 -- ADD CHECK FOR IQ.X IN SELERR ; ; J. CLEARY 27-DEC-78 ; ; JC027 -- CLEAN UP TIMEOUT FOR CASE WHERE DRIVE HANGS CNTRLR ; ; J. CLEARY 23-JAN-79 ; ; JC028 -- ADD SUPPORT FOR MULTI-CONTROLLERS ; ; J. CLEARY 23-JAN-79 ; ; JC029 -- ADD RH11 SUPPORT FOR 22-BIT ADDRESSING ; ; J. CLEARY 9-FEB-79 ; ; JC030 -- INCLUDE POWERFAIL CODE ; ; J. CLEARY 10-MAR-79 ; ; JC033 -- FIX PROBLEM IN CHKEOV ; ; J. CLEARY 4-APR-79 ; ; JC038 -- FIX DENSITY SELECTION ON TM03 ; ; E. BAATZ 21-APR-79 ; ; EB205 -- INCREASE SIMILARITY WITH M-PLUS MMDRV ; ; J. CLEARY 24-MAY-79 ; ; JC040 -- FIX PROBLEM WITH EXTRA TAPE MARK COUNT WHEN ; EOT ENCOUNTERED ON SPACE FILES ; ; ; TL002 -- FIX RH11 SUPPORT ; ; TL003 -- FIX MULTIPLE FORMATTER SUPPORT ; ; TL004 -- FIX POWERFAIL RECOVERY ; ; TL005 -- FIX ERROR RETURNS (IE.BBE) ; ; TL008 -- FIX IO.SMO FOR THE TM03 ; ; TL009 -- GET AROUND HARDWARE SPACE QUIRKS ; ; TL010 -- FIX END OF VOLUME STATUS RETURN IN STATUS BITS ; ; TL011 -- FIX EOT STATUS RETURN FOR SPACE OPERATIONS ; ; ** TL011 -SUPERCEDED BY CS002 ; ; TL026 -- FIX CONTROLLER ERROR RECOVERY ; ; TL030 -- FIX CANCEL TASK CHECKING ; ; TL048 -- FIX CONTROLLER RESET AFTER AN ABORT ; ; TL049 -- UPDATE DENSITY STATUS FOR THE TM03 ; ; TL063 -- RETURN THE CORRECT BLOCK COUNT FOR IO.SPB,IO.SPF ; ; TL064 -- RETURN THE CORRECT BYTE COUNT FOR READ TM ; ; TL093 -- IGNORE OPI ERRORS AFTER A SPACE REVERSE ; AT BOT. (TM03 HARDWARE QUIRK) ; ; ** TL093 - SUPERCEDED BY CS002 ; ; TL100 -- USE CURRENT TIMEOUT, NOT INTERNAL VALUE ; IGNORE NOISE RECORDS <14 BYTES ; ; TL120 -- USE U.SPC INSTEAD OF U.CW3 FOR SPACING COUNT ; ; CS001 -- NO M.PEOV FOR IO.SMO ; ; CS002 -- CORRECT ERROR RECOVERY AND OTHER DRIVER PROBLEMS ; ; RH11/RH70 TM02/TM03 MAGNETIC TAPE CONTROLLER DRIVER .PAGE ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,ABODF$ HWDDF$ PKTDF$ ABODF$ .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; EQUATED SYMBOLS ; US.ABO=1 ;ABORT IN PROGRESS - U.STS US.SUP=2 ;SUPRESS ERROR RECOVERY US.PWF=10 ;POWER FAIL STATUS RETRY=12 ;RETRY COUNT RQFLAG=76 ;USED TO SEE WHETHER $RLCH SHOULD BE CALLED MINREC=14. ;MINIMUM RECORD SIZE REV = 2 ;REVERSE BIT FOR SPACE OPERATIONS NOISE=MINREC ;ANYTHING SMALLER THAN THIS IS NOISE ;TL100 .PAGE ;**-1 ; REGISTER DEFINITION AND OFFSETS ;**-2 ; ;**-1 RHCS1 = +0 ;RH CONTROL AND STATUS C1.GO=1 ;GO C1.IE=100 ;INTERRUPT ENABLE C1.RDY=200 ;CONTROLLER READY BIT C1.PSL=2000 ;PORT SELECT C1.DVA=4000 ;DEVICE AVAILABLE C1.TRE=40000 ;TRANSFER ERROR C1.CPE=20000 ;CONTROL PARITY ERROR C1.SC=100000 ;SPECIAL CONDITION ;**-1 FC.RWU=103 ;REWIND, OFF-LINE FC.RWD=107 ;REWIND FC.ERS=125 ;ERASE COMMAND FC.WEF=127 ;WRITE EOF (TAPE MARK) FC.SPF=131 ;SPACE FORWARD FC.SPR=133 ;SPACE REVERSE COMMAND FC.WRT=161 ;WRITE FC.RED=171 ;READ FC.REV=177 ;READ REVERSE FC.CLR=11 ;DRIVE CLEAR RHWC = +2 ;RH WORD COUNT REGISTER RHBA = +4 ;RH BUS ADDRESS REGISTER (LOW ORDER 16 BITS) MTFC = +6 ;TM02/TM03 FRAME COUNT REGISTER RHCS2 = +10 ;RH CONTROL AND STATUS REGISTER 2 C2.CLR= 40 ;CONTROLLER CLEAR C2.IR= 100 ;INPUT READY ;CS002 C2.OR= 200 ;OUTPUT READY ;CS002 C2.DPE= 400 ;PAR ERR ON RH MASSBUS DATA BUS ;CS002 C2.MXF= 1000 ;MISSED TRANSFER ;**-3 C2.PGE= 2000 ;PROGRAM ERROR C2.NEM= 4000 ;NON-EXISTENT MEMORY C2.NED= 10000 ;NON-EXISTENT DRIVE C2.UPE= 20000 ;UNIBUS PARITY ERROR C2.WCE= 40000 ;WRITE CHECK ERROR C2.DLT= 100000 ;DATA LATE CS2ERR= C2.DLT!C2.WCE!C2.UPE!C2.NED!C2.NEM!C2.PGE!C2.MXF!C2.DPE ;CS002 ;CS002 MTDS = +12 ;TM02/TM03 DRIVE STATUS REGISTER ;**-2 DS.SLA=1 ;SLAVE ATTENTION DS.BOT=2 ;BEGINNING OF TAPE DS.TM=4 ;TAPE MARK DETECTED DS.IDB=10 ;IDENTIFICATION BURST DS.SDN=20 ;SETTLE DOWN DS.PES=40 ;PHASE ENCODED STATUS DS.SSC=100 ;SLAVE STATUS CHANGE DS.DRY=200 ;DRIVE READY DS.DPR=400 ;DRIVE PRESENT DS.EOT=2000 ;END OF TAPE DETECTED DS.WRL=4000 ;WRITE LOCK DS.MOL=10000 ;MEDIUM ON LINE DS.PIP=20000 ;POSITIONING IN PROGRESS DS.ERR=40000 ;ERROR COMPOSITE DS.ATA=100000 ;ATTENTION MTER = +14 ;TM02/TM03 ERROR REGISTER ER.ILF=1 ;ILLEGAL FUNCTION ER.ILR=2 ;ILLEGAL REGISTER ER.RMR=4 ;REGISTER MODIFICATION REFUSED ER.CPR=10 ;CONTROL BUS PARITY ERROR ER.FMT=20 ;FORMAT ERROR ER.DPR=40 ;DATA PARITY ERROR ER.INC=100 ;INCORRECTABLE DATA (PE ONLY) ER.VPE=ER.INC ;VERTICAL PARITY ERROR (NRZI ONLY) ER.PEF=200 ;FORMAT ERROR (PE ONLY) ER.LRC=ER.PEF ;LRCC ERROR (NRZI ONLY) ER.NSG=400 ;NON-STANDARD GAP ER.FCE=1000 ;FRAME COUNT ERROR ER.CS=2000 ;CORRECTABLE SKEW -- PE MODE ER.ITM=ER.CS ;ILLEGAL TAPE MARK -- NRZI MODE ER.NEF=4000 ;NON-EXECUTABLE FUNCTION ER.DTE=10000 ;DRIVE TIMING ERROR ER.OPI=20000 ;OPERATION INCOMPLETE ER.UNS=40000 ;DRIVE UNSAFE ER.COR=100000 ;CORRECTABLE DATA (PE ONLY) ER.CRC=ER.COR ;CRC ERROR (NRZI ONLY) ER.DAT= ER.CS! ER.NSG! ER.PEF! ER.INC ;DATA DETECTION ERRORS ;CS002 ;**-1 RHAS = +16 ;RH ATTENTION SUMMARY REGISTER MTCK = +20 ;TM02/TM03 CRC OR DEAD TRACK REGISTER MTDB = +22 ;TM02/TM03 DATA BUFFER MTMR = +24 ;TM02/TM03 MAINTENANCE REGISTER MTDT = +26 ;TM02/TM03 DRIVE TYPE REGISTER DT.SPR=200 ;SLAVE PRESENT DT.DRQ=4000 ;DRIVE REGISTER REQUEST DT.7CH=10000 ;SEVEN CHANNEL DRIVE DT.MOH=20000 ;MOVING HEAD DEVICE DT.TAP=40000 ;TAPE DT.NSA=100000 ;NOT SECTOR ADDRESSED MTSN = +30 ;TM02/TM03 SERIEL NUMBER MTTC = +32 ;TM02/TM03 TAPE CONTROL REGISTER TC.1600=2000 ;1600 BPI TC.800=1000 ;800 BPI TC.FMT=300 ;FORMATTING BITS - PDP-11 NORMAL TC.EVN=10 ;EVEN PARITY ;**-1 .IF DF M$$IXD RHBAE= 74 ;MIXED MASSBUS ADDRESS EXT. REGISTER ;THIS CANNOT BE=74 IF CSR=XXXXXX40 .IFF ;**-1 RHBAE= 34 ;BUS ADDRESS EXTENSION REGISTER .ENDC ; ;**-1 ; THE FOLLOWING DEFINITIONS ARE THE BIT POSITIONS IN THE MAG TAPE STATUS ; REGISTER. UNFORTUNATELY, THEY WERE DEFINED ORIGINALLY FOR A TM11 DRIVER, ; SO THAT SOME OF THE BIT POSITIONS REFLECT THE HARDWARE REGISTERS FOR ; THAT CONTROLLER ; M.PEOV=100000 ;TAPE PAST LOGICAL END OF VOLUME M.AEOV=40000 ;TAPE AT LOGICAL END OF VOLUME M.BOT=20000 ;TAPE AT BOT M.1600=4000 ;1600 BPI PHASE ENCODED (9 CHANNEL ONLY) M.HWL=2000 ;HARDWARE WRITE LOCK M.RWD=1000 ;UNIT IS REWINDING M.SER=400 ;SELECT ERROR HAS OCCURRED M.IXG=200 ;INHIBIT WRITE WITH EXTENDED INTERRECORD M.SWL=100 ;SOFTWARE WRITE LOCK M.EOF=40 ;LAST COMMAND ENCOUNTERED TAPE MARK M.EOT=20 ;LAST COMMAND ENCOUNTERED EOT M.EVN=10 ;EVEN PARITY USRBTS=4310 ;STATUS BITS CONTROLLED BY THE USER ; M.1600! M.IXG! M.SWL! M.EVN ;CS002 ;CS002 NEWBTS=M.BOT!M.EOF!M.EOT ;BITS TO BE SET BEFORE $IODON CALLED ;TL010 ;CS002 ;CS002 ; LOCAL DATA ;**-35 ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; ; DIAGNOSTIC FUNCTIONS USE BIT 15 OF RTTBL AS A FLAG FOR INTERRUPT ; SERVICING. CNTBL: .BLKW T$$J16 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW T$$J16 ;ERROR RETRY COUNT SPTBL: .BLKW T$$J16 ;FOR SPACE CHECKING SPTOTL: .BLKW T$$J16 ;TOTAL BLOCKS SPACED ;TL009 FMTBL: .BLKW T$$J16 ;FORMAT CODE SAVE AREA FCCDE: .BLKW T$$J16 ;FUNCTION CODE SAVE AREA CMDCNT: .BLKW T$$J16 ;COMMAND COUNT SAVE AREA BUFADR: .BLKW T$$J16 ;U.BUF SAVE AREA IOFCN: .BLKW T$$J16 ; > I/O FUNCTION. ;CS002 ;CS002 ;**-1 .IF GT T$$J16-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC .PAGE ;CS002 ;+ ;CS002 ; VALID I/O FUNCTION TABLE ;CS002 ;- ;CS002 .MACRO DFENT FUNC,INDX,RQSTCD,RTRADR,RTRYCD ;CS002 .WORD FUNC ;I/O FUNCTION CODE ;CS002 .BYTE INDX ;I/O HANDLING (TABLES) INDEX ;CS002 .BYTE RQSTCD ;DEVICE I/O REQUEST CODE ;CS002 .WORD RTRADR ;TAPE REPOSITIONED RETURN ;CS002 .WORD RTRYCD ;DEVICE ERROR RECOVERY REQUEST CODE ;CS002 .ENDM DFENT ;CS002 ;CS002 ;CS002 LGFCN: DFENT IO.RLB,FREAD,FC.RED,RTYCMD,FC.SPR ;READ FORWARD ;CS002 DFENT IO.WLB,FWRTE,FC.WRT,RTYCMD,FC.ERS ;WRITE ;CS002 DFENT IO.RLV,FRREV,FC.REV,RTYCMD,FC.SPF ;READ REVERSE ;CS002 DFENT IO.EOF,FWEOF,FC.WEF,RTYCMD,FC.ERS ;WRITE TAPE MARK ;CS002 DFENT IO.ERS,FERSE,FC.ERS, 0, 0 ;ERASE 3" GAP ;CS002 DFENT IO.RWD,FRWND,FC.RWD, 0, 0 ;REWIND ;CS002 DFENT IO.RWU,FRWDU,FC.RWU, 0, 0 ;RWND OFFLINE/UNLOAD ;CS002 DFENT IO.SPB,FSPCR,FC.SPF,SPCONT,FC.SPR ;SPACE BLOCKS ;CS002 DFENT IO.SPF,FSPCF,FC.SPF,SPCONT,FC.SPR ;SPACE FILES ;CS002 DFENT IO.STC,FSETC, 0, 0, 0 ;SET CHAR ;CS002 DFENT IO.SEC,FSENC, 0, 0, 0  ;SENSE CHAR ;CS002 SMOU: DFENT IO.SMO,FSMOU, 0, 0, 0 ;MOUNT/SET CHAR ;CS002 ;CS002 ENDFCN=. ;CS002 ;CS002 LNGHT=.-SMOU ;CS002 ;CS002 .PAGE ;CS002 ; ;**-1 ; FUNCTION CODE INDEX TABLE ; FREAD = 0 ;READ LOGICAL BLOCK ;**-1 FWRTE = 2 ;WRITE LOGICAL BLOCK FRREV = 4 ;READ LOGICAL BLOCK REVERSE FWEOF = 6 ;WRITE TAPE MARK FERSE = 10 ;ERASE TAPE FRWND = 12 ;REWIND TAPE FRWDU = 14 ;REWIND AND UNLOAD FSPCR = 16 ;SPACE RECORDS FSPCF = 20 ;SPACE FILES FSETC = 22 ;SET TAPE CHARACTERISTICS FSENC = 24 ;SENSE TAPE CHARACTERISTICS FSMOU = 26 ;SET AND MOUNT CHARACTERISTICS FRTRY = 30 ;RETRY IN PROGRESS FSPRR = 22 ;SPACE RECORD REVERSE FSPFR = 24 ;SPACE FILE REVERSE ;CS002 ; ;**-18 ; PRE-INITIATION PROCESSING ROUTINES ; PRETBL: ;**-1 .WORD PRERED ;READ .WORD PREWRT ;WRITE PRE-INITIATION ENTRY .WORD PREREV ;READ REVERSE PRE-INITIATION ROUTINE .WORD PREEOF ;WRITE TAPEMARK PRE-INITIATION ENTRY .WORD PREERS ;ERASE PRE-INITIATION ENTRY .WORD PRECOM ;REWIND PRE-INITIATION ENTRY .WORD PRECOM ;REWIND AND UNLOAD PRE-INITIATION ENTRY .WORD PRESPC ;SPACE RECORDS INITIATION .WORD PRESPC ;SPACE FILES INITIATION ENTRY .WORD PRESTC ;SET CHARACTERISTICS FUNCTION ROUTINE .WORD PRESEC ;SENSE CHARACTERISTICS FUNCTION ROUTINE .WORD PRESMO ;MOUNT AND SET CHARACTERISTICS FUNCTION ;CS002 ;CS002 ; ;**-1 ; SUCCESFUL COMPLETION TABLE ; DONTBL:  ;**-1 .WORD REDDON ;READ FORWARD COMPLETION .WORD WRTDON ;WRITE FORWARD COMPLETION .WORD REVDON ;READ REVERSE COMPLETION .WORD EOFDON ;WRITE TAPE MARK COMPLETION .WORD EXTNST ;ERASE COMPLETION .WORD RWDDON ;REWIND COMPLETION .WORD RWDDON ;REWIND AND UNLOAD COMPLETION .WORD SPFEXT ;SPACE RECORD FORWARD COMPLETION .WORD SPFEXT ;SPACE FILE FORWARD COMPLETION .WORD SPFEXT ;SPACE RECORD REVERSE COMPLETION .WORD SPFEXT ;SPACE FILE REVERSE COMPLETION .WORD SMODON ;IO.SMO REWIND COMPLETION (TM03 PROBLEM);CS002 .WORD FATAL ;COMPLETION ROUTINE FOR RECOVERY ;**-1 .PAGE ; MASK TABLE - RETRIABLE ERRORS ;CS002 ; ER.DAT= ER.CS! ER.NSG! ER.PEF! ER.INC ;CS002 ERRMSK: ;CS002 .WORD ER.COR! ER.DTE! ER.DAT! ER.FCE! ER.FMT! ER.CPR ;RD FWD ;CS002 .WORD ER.COR!ER.DTE!ER.DAT!ER.FCE!ER.DPR!ER.FMT!ER.CPR ;WRT ;CS002 .WORD ER.COR!ER.OPI!ER.DTE!ER.DAT!ER.FCE!ER.FMT!ER.CPR ;RD REV;CS002 .WORD ER.COR! ER.DAT! ER.CPR ;WTMK ;CS002 .WORD 0 ;ERS ;CS002 .WORD ER.NEF! ER.FMT ;RWD ;CS002 .WORD ER.NEF! ER.FMT ;RWU ;CS002 .WORD ER.OPI! ER.FCE ;SRFWD ;CS002 .WORD ER.OPI! ER.FCE ;SFFWD ;CS002 .WORD ER.OPI! ER.FCE ;SRREV ;CS002 .WORD ER.OPI! ER.FCE ;SFREV ;CS002 .WORD 0 ;NO FNCT;CS002 .WORD 0 ;RETRY ;CS002 ; ;**-20 ; RETRY TABLE ; RTYTBL: ;**-1 .WORD REDRTY ;READ FORWARD RETRY ENTRY POINT .WORD WRTRTY ;WRITE RETRY ENTRY POINT .WORD REVRTY ;READ REVERSE RETRY ENTRY POINT .WORD WRTRTY ;WRITE TAPE MARK RETRY ENTRY POINT .WORD FATAL ;ERASE - NOT RETRIABLE .WORD RWDRTY ;REWIND RETRY RETRY ENTRY POINT ;CS002 .WORD RWDRTY ;UNLOAD/OFFLINE RETRY ENTRY POINT ;CS002 .WORD SPRRTY ;SPACE RECORD RETRY ENTRY POINT ;**-2 .WORD SPFRTY ;SPACE FILE FORWARD RETRY ENTRY POINT .WORD SPRRTY ;SPACE RECORD REVERSE RETRY ENTRY POINT .WORD SPFRTY ;SPACE FILE REVERSE RETRY ENTRY POINT .WORD FATAL ;NO RETRY FOR IO.SMO REWIND ;TL008 ; (FOR TM03 PROBLEM) ;TL008  .WORD FATAL ;RETRY NOT APPLICABLE ON ERROR ;**-1 ;CS002 ; FUNCTION SPECIFIC ERROR CHECK TABLE OF ENTRY POINTS ;**-2 ; CHKTBL: ;**-1 .WORD REDERR ;READ FORWARD ERROR CHECKING .WORD COMRTY ;WRITE FORWARD ERROR CHECKING .WORD REVERR ;READ REVERSE ERROR CHECKING .WORD COMRTY ;WRITE TAPE MARK ERROR CHECKING .WORD FATAL ;ERASE - ALL ERRORS FATAL .WORD RWDRTY ;REWIND ERROR CHECKING ;CS002 .WORD RWDRTY ;UNLOAD/OFFLINE ERROR CHECKING ;CS002 .WORD SPFEXT ;SPACE FWD BLKS ERR CHECKING ;CS002 .WORD SPFEXT ;SPACE FWD FILES ERR CHECKING ;CS002 .WORD SPRERR ;SPACE REV BLKS ERR CHECKING ;CS002 .WORD SPRERR ;SPACE REV FILES ERR CHECKING ;CS002 .WORD FATAL ;IO.SMO REWIND - ALL ERRORS FATAL ;TL008 ; (FOR TM03 PROBLEM) ;TL008 .WORD RTYCON ;CONTINUE RETRY ON FRAME COUNT ERRORS ;**-7 .PAGE ; ; DRIVER DISPATCH TABLE ; $MMTBL::.WORD MMINI ;DEVICE INITIATOR ENTRY POINT .WORD MMCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD MMOUT ;DEVICE TIMEOUT ENTRY POINT .WORD MMPWF ;POWERFAIL ENTRY POINT ;+ ; **-MMINI-RH11/RH70 TM02/TM03 MAGNETIC TAPE CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER-  ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- MMINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS ;**-1 BCC 10$ ;IF CC PROCESS REQUEST RETURN ;NOTHING TO DO OR CONTROLLER BUSY ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RH11/RH70 TM02/TM03 MAGNETIC TAPE FUNCTION INDEPENDENT I/O REQUEST ; PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB/IO.RWD/IO.SPB/IO.SPF/IO.EOF). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; 10$: MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS ;CS002 MOV #LGFCN,R2 ;RETRIEVE ADDRESS OF LEGAL FUNC ;**-3 MOV I.FCN(R1),R0 ;RETREIVE FUNCTION CODE BICB #US.SUP,U.STS(R5) ;CLEAR RETRY SUPPRESS .IF DF D$$IAG CLRB RTTBL+1(R3) ;CLEAR DIAGNOSTIC FLAG BITB #IQ.UMD,R0 ;DIAGNOSTIC FUNCTION? BEQ 20$ ;IF EQ NO MOV #100000,RTTBL(R3) ;STOP RETRIES AND SET DIAG. FLAG BISB #US.SUP,U.STS(R5) ;SUPRESS RETRIES ;**-1 ;CS002 20$: .ENDC ; D$$IAG ;CS002 ;CS002 BITB #IQ.X,R0 ;SUPPRESS ERROR RECOVERY? ;**-4 BEQ 25$ ;IF EQ, NO. ;CS002 BISB #US.SUP,U.STS(R5) ;SUPPRESS ERROR RECOVERY ;**-1 25$: BICB #IQ.X!IQ.UMD!IQ.Q,R0 ;FUNCTION CODE FOR VALIDATION ;CS002 30$: CMP R0,(R2) ;FUNCTION CODE MATCH ? ;CS002 BEQ 50$ ;IF EQ, YES. ;CS002 ADD #LNGHT,R2 ;NEXT I/O FUNCTION. ;CS002 CMP R2,#ENDFCN ;END OF TABLE? ;**-7 BLO 30$ ;NO CHECK NEXT ENTRY 40$: MOV #IE.IFC&377,R0 ;YES - ILLEGAL FUNCTION JMP EXTNST ;EXIT ;CS002 50$: MOV R2,IOFCN(R3) ;REMEMBER I/O REQUEST ;CS002 TST (R2)+ ; AND ;CS002 MOV (R2),U.FCDE(R5) ; QIO INDEX. ;CS002 MOVB U.FCDE(R5),R0 ;SET FUNCTION INDEX IN R0 ;**-31 CLR SPTBL(R3) ;CLEAR OUT SPACING INDICATOR .IF DF D$$IAG TST RTTBL(R3) ;DIAGNOSTIC FUNCTION? BMI 80$ ;IF MI YES - NO RETRIES .ENDC MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT 80$: CALL SELECT ;GET TAPE UNIT STATUS CALLR @PRETBL(R0) ;JMP TO PRE-INITIATION ROUTINE .PAGE ;**-2 ;+ ; **-PRESPC - INITIATION ROUTINE FOR SPACE FUNCTIONS ; ; THIS ROUTINE DOES ALL PRE-PROCESSING FOR SPACE FUNCTIONS. ; STATUS CONDITIONS ARE CHECKED TO SEE IF SPACEING SHOULD OCCUR ; IF NOT THE DRIVER EXITS WITH STATUS RETURN IN R0. ; ; IF SPACING TO OCCUR U.CNT(R5),I.PRM+4(R1),SPTBL(R3) AND ; U.SPC(R5) (IF SPACE FILES) ARE SET WITH THE SPACE COUNT. ;TL120 ; THE FUNCTION CODE IS SET IN U.BUF(R5) AND THE FUNCTION INDEX ;**-1 ; SET APPROPRIATLY IN U.FCDE(R5). A BRANCH TO FNCEX IS THEN MADE. ;- ;**-10 ;**-1 PRESPC: MOV #IS.SUC&377,R0 ;ASSUME 0 SPACE COUNT CLR SPTOTL(R3) ;CLEAR BLOCKS SPACED TABLE ENTRY ;TL009 MOV U.BUF(R5),-(SP) ;RETRIEVE SPACE COUNT BEQ 40$ ;ZER0 - DONE BMI 10$ ;IF MI REVERSE SPACE ;SPACE FWD ;CS002 MOV #IE.EOV&377,R0 ;MAY BE AT EOV ;**-1 BIT #M.AEOV,U.CW2(R5) ;AT EOV? ;TL010 BNE 40$ ;YES CAN'T SPACE FORWARD FROM HERE ;**-1 NEG (SP) ;NEED 2'S COMPLEMENT FOR FUNCTION BR 20$ ;CONTINUE ;CS002 ;SPACE REV ;CS002 10$: BIC #M.AEOV,U.CW2(R5) ;CLEAR AT END OF VOLUME STATUS ;TL010 MOVB #FC.SPR,U.FCDE+1(R5) ;SPACE REV FNCTN ;CS002 ADD #4,U.FCDE(R5) ;RESET FUNCTION INDEX ;**-2 20$: CLR U.BUF(R5) ;INIT FOR FUNCTION CODE ;CS002 CMP #IO.SPF,@IOFCN(R3) ;SPACE FILES? ;CS002 BNE 30$ ;IF NE NO ;**-1 MOV (SP),U.SPC(R5) ;YES SAVE REQUESTED COUNT ;TL120 MOV (SP),I.PRM+4(R1) ;SAVE FOR LATER CALCULATIONS ;**-1 MOV #1,(SP) ;SET FOR MAX SPACE COUNT 30$: MOV (SP),U.CNT(R5) ;SET U.CNT MOV (SP)+,SPTBL(R3) ;SAVE FOR TIMEOUT SITUATION BR PWFTST ;INIT REQUEST IF NO PWRFL INDICATION. ;CS002 ;**-3 40$: TST (SP)+ ;CLEAN UP STACK FOR RETURN JMP EXTNST ;EXIT .PAGE ;+ ;**-16 ; **-PRESMO - IF TAPE AT BOT, SET TAPE CHARACHTERISTICS ;CS002 ; PER USER REQUEST. ;CS002 ;- ;**-4 .ENABL LSB ;CS002 PRESMO: BIT #M.BOT,U.CW2(R5) ;TAPE AT BOT? ;**-7 BNE SMORWD ;YES SET CHARACTERISTICS ;TL008 MOV #IE.FHE&377,R0 ;NO FATAL ERROR ;**-1 BR 20$ ;+ ;TL008 ; **-SMORWD - ISSUE REWIND TO CLEAR HUNG EOT STATUS IN TM03'S ;TL008 ; CAUSED BY MANUALLY REWINDING AN ONLINE TAPE PREVIOUSLY AT EOT. ;TL008 ;- ;TL008 SMORWD: BIC #M.AEOV,U.CW2(R5) ;CLEAR AT END OF VOLUME STATUS ;TL008 BIC #USRBTS!7,U.CW2(R5) ;CLEAR USER BITS ;TL008 BIC #^C,U.BUF(R5) ;CLEAR ALL BUT USER BITS ;TL008 BIS U.BUF(R5),U.CW2(R5) ;SET NEW CHARACTERISTICS ;TL008 MOV #FC.RWD,U.BUF(R5) ;SET THE FUNCTION CODE (REWIND) ;TL008 JMP PRCOM ;DOIT! ;TL008 ;TL008 SMODON: .IF DF P$$RFL ;CS002 BICB #US.PWF,U.STS(R5) ;CLEAR PWRFLD STATUS ;CS002 .ENDC ;CS002 ;CS002 CALL SELECT ;CS002 BR PRESEC  ;CS002 ;CS002 ;+ ; ; **-PRESTC - SET CHARACTERISTICS COMMAND ; SETS THE CHARACTERISTICS DEFINED BY THE USER IN U.CW2(R5) ; ;- PRESTC: BIC #USRBTS!7,U.CW2(R5) ;CLEAR USER BITS BIC #^C,U.BUF(R5) ;CLEAR ALL BUT USER BITS BIS U.BUF(R5),U.CW2(R5) ;SET NEW CHARACTERISTICS ;CS002 ;CS002 ;+ ; **-PRESEC - RETURN TAPE CHARACTERISTIC WORD ;CS002 ;- ;**-7 PRESEC: BIC #M.PEOV,U.CW2(R5) ;NO M.PEOV FOR IO.SMO REQUEST ;CS001 MOV U.CW2(R5),R1 ;GET THE STATUS ;TL049 MOV #IS.SUC&377,R0 ;SET SUCCESS ;**-9 20$: JMP EXIT ;RETRUN ;CS002 .DSABL LSB ;CS002 .PAGE ;+ ;**-31 ; **-PREWRT - WRITE REQUEST PREPROCESSING: ;CS002 ; ;CS002 ; VERIFY AT LEAST MINIMUN RECORD SIZE AND WRITE ENABLED ;CS002 ; ;CS002 ;- ;**-8 .ENABL LSB ;CS002 PREWRT: MOV #IE.SPC&377,R0 ;ASSUME PARAMETER PROBLEMS CMP #MINREC,I.PRM+4(R1) ;MINIMUM RECORD SIZE? ;**-2 BHI 30$ ;IF HI RECORD TOO SMALL ;+ ; **-PREEOF - INITIATION ROUTINE FOR WRITE TAPE MARK ;**-1 ; **-PREERS - INITIATION ROUTINE FOR ERASE ; ; VERIFY THAT WRITE ENABLED ;CS002 ; ;CS002 ;- ;**-3 PREEOF: PREERS: 20$: MOV #IE.WLK&377,R0 ;ASSUME WRITE LOCKED BIT #M.SWL!M.HWL,U.CW2(R5) ;WRITE LOCKED? BNE 30$ ;IF EQ YES - EXIT CMPB #FRREV,U.FCDE(R5) ;DATA TRANSFER ? ;CS002 BLT PWFTST ;IF LT, NO. ;CS002 ;+ ;**-1 ; ; **-PRERED - INITIATION FOR READ FORWARD ; PREREV - READ REVERSE ;CS002 ;-  ;**-7 PRERED: PREREV: ;CS002 .IF DF M$$EXT ;TL002 ;TL002 BIT #DV.MBC,U.CW1(R5) ; RH11 ? ;TL002 BNE 21$ ;IF NE, NO - RH70. ;TL002 CALL $STMAP ;SET UP UNIBUS MAPPING ;TL002 ASL U.BUF(R5) ;SHIFT BITS <4:5> ;TL002 ASL U.BUF(R5) ;INTO BITS <8:9> ;TL002 ASL U.BUF(R5) ;... ;TL002 ASL U.BUF(R5) ;... ;TL002 CALL $MPUBM ; SETUP UMR'S FOR TRANSFER ;TL002 MOV S.CSR(R4),R2 ;RESTORE R2 ;TL002 ;TL002 21$: .ENDC ; M$$EXT ;TL002  ;TL002 MOV R5,R1 ; R1 > ;CS002 ADD #U.BUF,R1 ; U.BUF. ;CS002 ;CS002 .IF NDF M$$EXT ;CS002 ;CS002 .IF DF M$$MGE ;CS002 ;CS002 ROL (R1) ; SETUP ;CS002 ROL (R1) ; A17, A16 ;CS002 ROL (R1) ; INTO ;CS002 ROL (R1) ; HI BYTE ;CS002 ;CS002 .ENDC ; M$$MGE ;CS002 ;CS002 .ENDC ; M$$EXT ;CS002 ;CS002 CMPB #4,U.FCDE(R5) ; READ REVERSE ? ;CS002 BNE PWFTST ; IF NE, NO. ;CS002 SUB #2,U.CNT(R5) ; READ REVERSE - ;CS002 ADD U.CNT(R5),2(R1) ; ADJUST BUFFER POINTER ;CS002 BCC 22$ ; TO END OF ;CS002 ADCB 1(R1) ; BUFFER AREA. ;CS002 22$: ADD #2,U.CNT(R5) ; RESTORE TRANSFER COUNT. ;CS002 PWFTST: MOV #IE.ABO&377,R0 ;REQUEST ABORTED IF PWRFLD STATU;CS002 BITB #US.PWF,U.STS(R5) ;POWER FAIL OCCUR? ;**-2 BEQ PRECOM ;IF EQ NO - CONTINUE 30$: JMP EXTNST ;EXIT ;CS002 .DSABL LSB ;CS002 ;CS002 ;+ ; **-PRECOM - COMMON PREPROCESSING ENTRY ;**-1 ; AT THIS POINT ALL COMMANDS WHICH REQUIRE HARDWARE ; PROCESSING AND HAVE SUCCESSFULLY PASSED ALL THE PRE-SCREENING ; ARE JOINED. A CALL TO SETNDT IS MADE TO SET THE FORMAT,THE ; FUNCTION CODE IS THEN MOVED TO U.BUF AND WE FALL THROUGH ; TO FNCEX - FUNCTION EXECUTION. ;- PRECOM: MOVB U.FCDE+1(R5),U.BUF(R5) ;RETRIEVE FUNCTION. ;CS002 PRCOM: MOVB U.UNIT(R5),R0 ;SET TAPE UNIT #. ;CS002 BIS #TC.1600,R0 ;ASSUME 1600BPI. ;CS002 BIT #M.1600,U.CW2(R5) ;CORRECT ASSUMPTION? ;CS002 BNE 10$ ;IF NE, YES. ;CS002 BIC #TC.1600,R0 ;SETUP FOR ;CS002 BIS #TC.800,R0 ; 800BPI. ;CS002 BIT #M.EVN,U.CW2(R5) ;EVEN PARITY MODE? ;CS002 BEQ 10$ ;IF EQ, NO. ;CS002 BIS #TC.EVN,R0 ;EVEN PARITY MODE. ;CS002 10$: BIS #TC.FMT,R0 ;NORMAL ASSY/DISASSY OF DATA ;CS002 MOV R0,FMTBL(R3) ;TAPE DRIVE CONTROL MODE. ;CS002 .PAGE ;**-9 ;+ ; **-FNCEX - FUNCTION EXECUTION ;**-1 ; ; INPUT: R2 = CSR ADDRESS ;**-3 ; R3 = CONTROLLER NUMBER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- ;**-1 FNCEX: BIT #M.SER,U.CW2(R5) ;SELECT ERROR? BNE SELERR ;IF NE YES SELECT ERROR BIT #DS.PIP,MTDS(R2) ;TAPE MOVING ? ;CS002 BNE TIMER ;IF NE YES - WAIT ;**-1 MOV U.FNUM(R5),RHCS2(R2) ;SELECT FORMATTER ;TL120 MOV FMTBL(R3),MTTC(R2) ;SET FORMAT AND SELECT UNIT ;**-1 MOV #C1.TRE!FC.CLR,RHCS1(R2) ;CLEAR DRIVE/CONTROLLER ERRORS ;CS002 MOV RHAS(R2),RHAS(R2) ;CLEAR ALL ATTENTION BITS ;TL003 MOV U.CNT(R5),MTFC(R2) ;SET COMMAND COUNT ;**-1 CMPB #FRREV,U.FCDE(R5) ;DATA TRANSFER? BLT NDATIO ;IF LE NO DATAIO: NEG MTFC(R2) ;NEGATE BYTE COUNT ;CS002 MOV MTFC(R2),RHWC(R2) ;MOVE BYTE COUNT TO RHWC ;**-27 ROR RHWC(R2) ;AND MAKE IT A WORD COUNT MOV U.BUF+2(R5),RHBA(R2) ;SET LOW ORDER 16 BIT ADDRESS NDATIO: MOVB S.ITM(R4),S.CTM(R4) ;START TIMER ;CS002 BIC #M.PEOV!M.SER!M.RWD,U.CW2(R5) ;CLEAR STATUS BITS ;TL010 ;CS002 MTPS #PR7 ; INHIBIT INTERRUPTS ;CS002 ;CS002 CMPB #FRREV,U.FCDE(R5) ;DATA TRANSFER ? ;CS002 BLT 20$ ;IF LT, NO. ;CS002 ;CS002 ;**-8 .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;RH11? BEQ 20$ ;IF EQ YES MOVB U.BUF+1(R5),RHBAE(R2) ;SET EX MEM BITS MOVB U.BUF(R5),RHCS1(R2) ;INITIATE COMMAND BR 30$ ; . . CONT ;CS002 ;**-1 .IFTF 20$: MOV U.BUF(R5),RHCS1(R2) ;INITIATE COMMAND ;**-1 .ENDC ;CS002 30$: MTPS #0 ; ALLOW INTERRUPTS ;CS002 RETURN ;CS002 .PAGE ;**-22 ;+ ;**-1 ; ; **-SELERR - SELECT ERROR HAS OCCURED THIS ROUTINE WILL ISSUE ; A SLECT ERROR MESSAGE TO THE CONSOLE TERMINAL EVERY ; 15 SECODS. THE UNIT IS CHECKED ONCE A SECOND ; UNTIL IT COMESREADY OR AN ABORT IS DONE. ; ;- .ENABL LSB ;CS002 SELERR: MOV #IE.DNR&377,R0 ;INSURE DNR IS SET BITB #US.SUP,U.STS(R5) ;USER MODE OR IQ.X? BNE 10$ ;IF NE YES EXIT TST U.ACP(R5) ; ACP WANTS RETURN? BNE 10$ ; IF NE YES BIS #M.SER,U.CW2(R5) ; SET SELECT ERROR DECB S.STS(R4) ;TIME FOR A MSG? BNE TIMER ;IF NE NO MOV #T.NDSE,R0 ;ERROR MESSAGE CODE MOVB #15.,S.STS(R4) ;SET UP TIMEOUT CALL $DVMSG ;SEND THE MESSAGE TIMER: MOVB #1,S.CTM(R4) ;SET UP A TIMEOUT RETURN ;THAT IS ALL FOR NOW 10$: JMP EXTNST ; EXIT ;CS002 .DSABL LSB .PAGE ;+ ; **-MMOUT - DEIVE TIMEOUT ENTRY POINT ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED. ; IF THE OPERATION WAS DIAGNOSTIC, THE QIO REQUEST IS TERMINATED. ; TIMEOUTS ARE USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE ; RESULT OF HARDWARE CONSIDERATIONS. ; ; INPUTS: R0 = I/O COMPLETION CODE IE.DNR ; R2 = CSR ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- MMOUT: BITB #US.ABO,U.STS(R5) ;;;ABORTING? ;**-1 BNE 40$ ;;;IF NE YES BIT #M.RWD,U.CW2(R5) ;;;REWIND IN PROGRESS BEQ 10$ ;;;IF EQ NO BIT #DS.MOL,MTDS(R2) ;;;UNIT ONLINE? BEQ SELERR ;;;IF EQ NO SELECT ERROR BIT #DS.PIP,MTDS(R2) ;;;POSITIONING IN PROGRESS? BNE TIMER ;;;IF NE YES - RESET TIMER BIT #DS.BOT,MTDS(R2) ;;;TAPE AT BOT BEQ TIMER ;;;IF EQ NO RESET TIMER BIS #M.BOT,U.CW2(R5) ;;;SET BOT STATUS BIC #M.RWD,U.CW2(R5) ;;;CLEAR REWINDING BIT BIS #M.SER,U.CW2(R5) ;;;FORCE A RETRY BR 30$ ;;;ISSUE COMMAND 10$: MOV SPTBL(R3),R1 ;;;SPACING? BEQ 20$ ;;;IF EQ NO CMP R1,MTFC(R2) ;;;BLANK TAPE BEQ 20$ ;;;IF EQ YES EXIT MOV MTFC(R2),SPTBL(R3) ;;;SAVE FOR LATER USE MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT RETURN ;CS002 20$: CALL $DTOER ;;;LOG DEVICE ERROR .IF DF D$$IAG BCS 40$ ;;;IF C-SETABORT DIAGNOSTIC FUNC;**-1 .ENDC ;**-1 30$: MTPS #0 ;;;ALLOW INTERRUPTS BIT #M.SER,U.CW2(R5) ;SELECT ERROR? BEQ 50$ ;IF EQ NO - ERROR CALL SELECT ;SEE IF RDY YET BCS SELERR ;IF C-SET NO SELECT ERROR CALLR FNCEX ;ALL'S WELL GO EXECUTE FUNCTION ;CS002 40$: ;;;REFERENCE LABEL .IF DF D$$IAG ;**-1 CALL MMDINT ;;;PASS DIAGNOSTIC DEVICE REGIST;**-1 .ENDC ;**-1 BIS #C2.CLR,RHCS2(R2) ;;;CLEAR CONTROLLER AND DRIVES ;TL048 BITB #US.ABO,U.STS(R5) ;;;ABORTING? ;TL048 BEQ 45$ ;;;BRANCH IF NOT ;TL048 JMP EXTNST ;;;EXIT NO STATUS ;TL048 ;TL048 45$: ;;;REF LABEL ;TL048 .IF DF D$$IAG ;**-3 MOV S.PKT(R4),R1 ;;;GET I/O PACKET ADDRESS BITB #IQ.UMD,I.FCN(R1) ;;;USER MODE FUNCTION? BEQ FATAL ;;;IF EQ NO .ENDC 50$: BIS #C2.CLR,RHCS2(R2) ;INSURE CONTROLLER CLEARED AND ;ABLE TO ACCEPT A NEW COMMAND JMP EXTNST ;EXIT NO STATUS ;CS002 ;+ ;**-1 ; **-MMCAN - CANCEL I/O ENTRY POINT ; CANCEL I/O OPERATION ; ; INPUTS: R0 = I/O PACKET ADDRESS ; R1 = TCB ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- MMCAN: CMP I.TCB(R0),R1 ;CANCEL FOR THIS TASK? ;TL030 BNE 10$ ;BRANCH IF NOT ;TL030 BISB #US.ABO,U.STS(R5) ;FLAG THE ABORT CONDITION ;TL030 10$: RETURN ;TL030 ;CS002 ;CS002 ;+ ;**-2 ; **-MMPWF - POWER FAIL RECOVERY ENTRY ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ;- MMPWF: ;POWERFAIL ENTRY POINT ;**-1 .IF DF P$$RFL BISB #US.PWF,U.STS(R5) ;SET POWER FAIL INDICATOR .ENDC RETURN ; ;**-1 .PAGE ;**-2 ;+ ; **-$MMINT-RH11/RH70 TM02/TM03 MAGNETIC TAPE CONTROLLER INTERRUPTS ;- INTSE$ MM,PR5,T$$J16 ;;;GENERATE INTERRUPT SAVE CODE CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMOUT COUNT MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR BITB #US.ABO,U.STS(R5) ;TOLD TO ABORT ? ;CS002 BEQ 5$ ;IF EQ, NO. ;CS002 MOV #IE.ABO&377,R0 ; ABORTING ;CS002 BR ENDRQS ; REQUEST. ;CS002 5$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESS. ;CS002 MOVB U.FCDE(R5),R1 ;RETRIEVE FUNCTION INDEX ;**-1 BIT #M.EOF!M.BOT,U.CW2(R5) ;TAPE MARK SEEN LAST TIME? BEQ 10$ ;IF EQ NO BIS #M.PEOV,U.CW2(R5) ;YES SET FOR EOV CHECK ;TL010 10$: BIC #NEWBTS,U.CW2(R5) ;CLEAR STATUS BITS TO DETERMINE ;**-1 BIT #C1.TRE,RHCS1(R2) ;TRANSFER TYPE ERROR? ;**-1 BNE 20$ ;IF NE YES BIT #DS.ERR,MTDS(R2) ;DRIVE ERROR? BNE 30$ ;IF NE YES CALLR @DONTBL(R1) ;NO ERRORS FUNCTION COMPLETE ;CS002 ; ;CS002 ; RH CONTROLLER TRANSFER ERROR - ;CS002 ; ;CS002 20$: BIT #C1.CPE,RHCS1(R2) ;PAR ERR, MASSBUS CONTROL BUS ? ;CS002 BNE FATAL ;IF NE, YES - UNRECOVERABLE. ;CS002 MOV RHCS2(R2),R0 ;R0 - POSSIBLE ;CS002 BIC #^C,R0 ; RH ERROR INDICATION. ;CS002 BEQ 30$ ;IF EQ, NO. ;CS002 BIT #C2.DLT!C2.UPE!C2.DPE,R0 ;REPOSITIONING ERROR ? ;CS002 BNE 37$ ;IF NE, YES. ;CS002 BIT #C2.PGE!C2.NED!C2.MXF,R0 ;RETRY ERROR ? ;CS002 BNE 27$ ;IF NE, YES. ;CS002 BIT #C2.WCE,R0 ;WRITE CHECK ERROR ? ;CS002 BNE FATAL ;IF NE, YES. (ELSE, C2.NEM) ;CS002 25$: MOV U.CNT(R5),R0 ;R0 - FRAME COUNT ;CS002 NEG R0 ; REQUEST. ;CS002 ADD MTFC(R2),R0 ;FRAME COUNT AS REQUESTED? ;CS002 BNE 37$ ;IF NE, MOVED. ;CS002 27$: ;CS002 .IF DF E$$DVC ;CS002 CALL LOGERR ;LOG ERROR ;CS002 .ENDC ;E$$DVC ;CS002 ;CS002 CALLR FNCEX ;REISSUE REQUEST. ;CS002 ;CS002 ; ;CS002 ; DRIVE ERROR INDICATION - DETERMINE IF RECOVERABLE ;CS002 ; ;CS002 30$: MOV MTER(R2),R0 ;R0 - ERROR REG. ;CS002 BIT ERRMSK(R1),R0 ;RECOVERABLE ERROR ? ;CS002 BEQ FATAL ;IF EQ, NO. ;CS002 BIT #ER.FMT!ER.CPR!ER.DTE,R0 ;POSITIONING KNOWN ? ;CS002 BNE 25$ ;IF NE, NO. ;CS002 35$: BIT #DS.MOL,MTDS(R2) ;DRIVE READY ? ;CS002 BEQ FATAL ;IF EQ, NO - FATAL. ;CS002 37$: CALLR @CHKTBL(R1) ;RECOVER PER SPECIFIC REQUEST ;CS002 ;CS002 ; ;CS002 ; UNRECOVERABLE ERROR - END REQUEST ;CS002 ; ;CS002 FATAL: .IF DF E$$DVC ;CS002 CALL LOGERR ;LOG ERROR ;CS002 .ENDC ; E$$DVC ;CS002 ;CS002 MOV #IE.FHE&377,R0 ;UNRECOVERABLE ERROR. ;CS002 ENDRQS: JMP EXTNST ;END REQUEST. ;CS002 .PAGE ;**-36 ;+ ;**-1 ; **-REVERR - READ REVERSE SPECIAL ERROR CHEKING ; ; TEST FOR READ REVERSE INTO BOT. ;CS002 ; IF BOT THEN IS.SUC AND ZERO BYTE COUNT ;CS002 ;- ;CS002 .ENABL LSB ;CS002 REVERR: BIT #ER.OPI,R0 ;OPERATION INCOMPLETE ? ;CS002 BEQ REDERR ;IF EQ NO THEREFORE NOT A BOT CONDITION ;**-8 BIT #DS.BOT,MTDS(R2) ;TAPE AT BOT? BEQ FATAL ;IF EQ NOT AT BOT IN THAT CASE THESE ERRORS ;ARE FATAL! BIS #M.BOT,U.CW2(R5) ;SET BOT STATUS CLR MTFC(R2) ;CLEAR OUT FRAME COUNT FOR RETURN BR 50$ ;RETURN SUCCESS ;+ ;**-1 ; **-REDERR - READ ERROR CHECKING ;- ;CS002 REDERR: BIT #ER.INC!ER.PEF!ER.NSG!ER.DTE!ER.FMT!ER.CPR,R0 ;RETRY ? ;CS002 BNE 20$ ;IF NE YES ;**-5 BIT #ER.FCE,R0 ;FRAME COUNT ERROR BNE 30$ ;IF NE YES 10$: BIT #DS.PES,MTDS(R2) ;PE TAPE? BNE 40$ ;IF NE, PE - CORRECTED DATA ;CS002 20$: CALLR COMRTY ;JMP TO RETRY ENTRY ;**-1 ;CS002 30$: BIT #DS.TM,MTDS(R2) ;TAPE MARK? BEQ 50$ ;IF EQ NO MOV #IE.EOF&377,R0 ;SET EOF STATUS BIS #M.EOF,U.CW2(R5) ;SET IN CHARACTERISTICS WORD BR 60$ ;GO TO COMPLETION ROUTINE ;**-1 ;CS002 40$: .IF DF E$$DVC ;CS002 CALL LOGERR ;LOG ERROR ;CS002 .ENDC ;CS002 ;CS002 50$: MOV #IS.SUC&377,R0 ;SHORT RECORD IS SUCESS 60$: CALLR @DONTBL(R1) ;EXIT ;CS002 .DSABL LSB ;CS002 ;CS002 ;+ ;CS002 ; **-RWDERR/RWDRTY - REWIND.OR.UNLOAD/OFFLINE ERROR RETRY ;CS002 ;- ;CS002 RWDERR: ;CS002 RWDRTY: BIC #M.1600,U.CW2(R5) ;SETUP FOR 800BPI. ;CS002 BIT #TC.1600,FMTBL(R3) ;LAST REQUEST AT 1600? ;**-16 BNE 10$ ;IF NE YES TRY 800 BIS #M.1600,U.CW2(R5) ;SET TO TRY AT 1600 10$: CMP #RETRY,RTTBL(R3) ;RETRIED AT LEAST ONCE ? ;CS002 BNE FATAL ;IF NE, YES. ;CS002 DECB RTTBL(R3) ;RTRY ;CS002 CALLR PRCOM ; ONLY ONCE. ;CS002 .PAGE ;**-1 ;+ ; **-SPRERR - SPACE REVERSE - ERROR HANDLING ;**-1 ;- ;**-1 .ENABL LSB SPRERR: BIT #DS.BOT,MTDS(R2) ;BOT ENCOUNTERED? BEQ SPFEXT ;IF EQ NO NOT BOT BIS #M.BOT,U.CW2(R5) ;SET STATUS BIT MOV #IS.SUC&377,R0 ;SET SUCCESS BR 30$ ;DONE ;+ ; **-SPERR - SPACE FORWARD - ERROR HANDLING ;CS002 ; SPACE FUNCTIONS - COMPLETION ROUTINES ;CS002 ;- ;**-1 SPFEXT: BIT #ER.OPI,R0 ;OPERATION INCOMPLETE? ;CS002 BNE FATAL ;IF NE YES FATAL ERROR ;**-1 MOV #IS.SUC&377,R0 ;SET SUCCESS ;TL009 10$: BIT #DS.TM,MTDS(R2) ;TAPEMARK SEEN? ;**-4 BEQ 30$ ;IF EQ NO MOV #IE.EOF&377,R0 ;SET TAPEMARK STATUS CALL CHKEOV ;CHECK FOR END OF VOLUME BCC 15$ ;IF CC, NOT EOV. ;CS002 MOV #FRTRY,U.FCDE(R5) ;SET FOR BACKSPACE ;**-1 JMP BACK ;BACKSPACE ONE RECORD. ;CS002 ;CS002 15$: CALLR @RTYTBL(R1) ;ANY MORE FILES? ;CS002 ;TL063 ; ;TL063 ; THIS WORKS BECAUSE WE ONLY GET TO SPRRTY: FOR SUCCESSFUL COMPLETION ;TL063 ; OF THE BACKUP (ALSO MTFC=0), AND IO.SPB CANNOT DETECT EOV AFTER ;TL063 ; SPACING OVER ANY BLOCKS. (IO.SPF DOESN'T USE U.CNT) ;TL063 ; ;TL063 SPCONT: CLR U.CNT(R5) ;CLEAR REQUESTED COUNT FOR CALC ;TL063 MOV #IE.EOV&377,R0 ;SET EOV STATUS ;**-4 BIS #M.AEOV,U.CW2(R5) ;SET AT EOV IN CHARACTERISTICS ;TL010 30$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS ;**-1 CMPB #IO.SPF,I.FCN(R1) ;SPACE FILES? BEQ SPFDON ;YES DO FILES COMPLETION ; SPACE BLOCKS - FWD/REV ;CS002 SPRRTY: TST MTFC(R2) ;WERE ENOUGH BLOCKS PASSED? ;TL009 BEQ 35$ ;YES, ALL DONE ;TL009 BIT #DS.TM!DS.BOT,MTDS(R2) ;TAPEMARK SEEN, OR BOT? ;TL009 BNE 35$ ;YES, ALL DONE ;TL009 MOV U.CNT(R5),R0 ;RETRIEVE REQUESTED COUNT ;TL009 SUB MTFC(R2),R0 ;CALCULATE ACTUAL NO. SPACED ;TL009 ADD R0,SPTOTL(R3) ;ADD IT IN TO THE TOTAL SPACED ;TL009 MOV MTFC(R2),U.CNT(R5) ;REMAINING COUNT IS NEW COUNT ;TL009 MOV MTFC(R2),SPTBL(R3) ;SAVE IT FOR TIMEOUT ;TL009 BR 70$ ;TRY TO DO SOME MORE ;TL009 ;TL009 35$: MOV U.CNT(R5),R1 ;RETRIEVE REQUESTED COUNT ;TL009 SUB MTFC(R2),R1 ;CALCULATE ACTUAL NO. SPACED ;**-1 ADD SPTOTL(R3),R1 ;ADDITIONAL SPACE OPERATIONS ;TL009 ; DONE IF AFTER EOT ;TL009 BR 60$ ;EXIT ;CS002 ;CS002 ;+ ;**-1 ; **-SPFRTY - SPACE FILES FWD/REV ;CS002 ;- ;**-4 SPFRTY: INC U.SPC(R5) ;DONE? ;TL120 BNE 70$ ;IF NE NO - CONTINUE ;**-1 MOV #IS.SUC&377,R0 ;YES - SUCCESS BR 50$ ;FIX POSITION AND EXIT ;CS002 ;CS002 SPFDON: BIT #DS.BOT!DS.TM,MTDS(R2) ;BOT OR TAPEMARK? ;TL009 BEQ 70$ ;NO - CONTINUE ;TL009 BIT #DS.BOT,MTDS(R2) ;IF WE STOPPED FOR BOT OR EOV ;TL063 BNE 50$ ;DON'T INCREMENT THE FILE ;TL063 BIT #M.AEOV,U.CW2(R5) ;COUNT BECAUSE WE DIDN'T ;TL063 BNE 50$ ;PASS A FILE ;TL063 INC U.SPC(R5) ;INCREMENT TAPE MARK COUNT ;TL120 50$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS ;**-3 MOV I.PRM+4(R1),R1 ;RETREIVE COUNT REQUESTED SUB U.SPC(R5),R1 ;SUBTRACT NUMBER REMAINING ;TL120 60$: NEG R1 ;SET FOR POSITIVE RETURN VALUE ;**-1 JMP EXIT ;EXIT ;CS002 70$: CALLR FNCEX ;CS002 .DSABL LSB ;CS002 .PAGE ;+ ; **-COMRTY - COMMON RETRY ROUTINE ; ; THIS ROUTINE CHECKS FOR RETRIES BEING SUPPRESSED ; IF SO EXIT RETURN STATUS IE.VER. OTHERWISE, ; SAVE THE REQUEST AND CALL THE FUNCTION SPECIFIC RETRY ; ROUTINE. ; ;- .ENABL LSB COMRTY: .IF DF E$$DVC CALL LOGERR ;LOG THE ERROR ;**-1 .ENDC ;**-1 BITB #US.SUP,U.STS(R5) ;RETRIES ENABLED? BNE 10$ ;IF NE NO EXIT DECB RTTBL(R3) ;RETRIES EXHAUSTED? BEQ 10$ ;IF EQ YES EXIT MOV U.FCDE(R5),FCCDE(R3) ;SAVE FUNCTION INDEX MOV U.CNT(R5),CMDCNT(R3) ;SAVE COMMAND COUNT MOV U.BUF(R5),BUFADR(R3) ;SAVE BUFFER ADDRESS MOV #FRTRY,U.FCDE(R5) ;SET RETRY COMMAND CALLR @RTYTBL(R1) ;BR TO FUNCTION SPECIFIC RETRY 10$: BIT #ER.PEF!ER.NSG!ER.OPI,R0 ;TAPE FORMAT ERROR ;TL005 BEQ 12$ ;NO ;TL005 MOV #IE.BBE&377,R0 ;RETURN ERROR IN R0 ;TL005 RTYCON: CALLR @DONTBL(R1) ;EXIT ;TL005 ;TL005 12$: MOV #IE.VER&377,R0 ;RETURN ERROR IN R0 ;TL005 BR RTYCON ;EXIT ;TL005 .PAGE ;**-2 ;+ ;CS002 ; -- WRITE/WTMK RETRY -- ;CS002 ;- ;CS002 WRTRTY: MOV #FRTRY,R1 ;R1 - RETRY INDEX. ;CS002 MOV #RTNWRT,DONTBL(R1) ;I/O CONT AFTER REPOSITION. ;CS002 MOV #FC.SPR,U.BUF(R5) ;SET UP I/O REQUEST CODE. ;CS002 BR 15$ ;REPOSITION TAPE. ;CS002 ;CS002 RTNWRT: BIT #M.IXG,U.CW2(R5) ;NO EXTENDED IRG ? ;CS002 BNE RTYCMD ;IF NE, YES. ;CS002 MOV #FRTRY,R1 ;R1 - RETRY INDEX. ;CS002 MOV #BACK,DONTBL(R1) ;I/O CONT AFTER ERASE. ;CS002 MOV #FC.ERS,U.BUF(R5) ;SET UP I/O REQUEST CODE. ;CS002 BR 15$ ;ERASE TAPE. ;CS002 ;CS002 ;+ ;CS002 ; -- READ FWD/REV RETRY -- ;CS002 ;- ;CS002 REDRTY: ;CS002 REVRTY: CMP MTFC(R2),#NOISE ;800BPI - MIN RECORD? ;CS002 BLO RTYCMD ;IF LO, NO - IGNORE IT. ;CS002 ;CS002 ;CS002 BACK: MOV #FRTRY,R1 ;R1 - RETRY INDEX. ;CS002 MOV IOFCN(R3),R0 ;R0 > ;CS002 ADD #4,R0 ; REPOSITION RETURN. ;CS002 MOV (R0)+,DONTBL(R1) ;I/O CONT AFTER REPOSITION. ;CS002 MOV (R0),U.BUF(R5) ;SET UP I/O REQUEST CODE. ;CS002 15$: MOV #-1,U.CNT(R5) ;REPOSITON BY ONE BLOCK. ;CS002 BR 20$ ;CS002 ;CS002 ;+ ;CS002 ; REISSUE ORIGINAL I/O REQUEST ;CS002 ;- ;CS002 RTYCMD: MOV FCCDE(R3),U.FCDE(R5) ;RESTORE FUNCTION INDEX ;**-38 MOV CMDCNT(R3),U.CNT(R5) ;RESTORE COMMAND COUNT MOV BUFADR(R3),U.BUF(R5) ;RESTORE BUFFER ADDRESS 20$: CALLR FNCEX ;EXECUTE FUNCTION ;CS002 .DSABL LSB ;CS002 .PAGE ;+ ; **-REDDON - READ FORWARD COMPLETION ROUTINE ;- ;**-3 REVDON: BIC #M.EOF!M.AEOV,U.CW2(R5) ;CLEAR OUT INTERNAL STATUS FOR R;TL010 REDDON: MOV MTFC(R2),R1 ;SET FRAME COUNT FOR REQUESTER ;**-2 ; TM03 FORMATTER AUTO SELECTS DENSITY CONTROL ON READS. ;TL049 ; IF TM03, UPDATE DRIVER INTERNAL DENSITY STATUS FOR THAT TAPE UNIT. ;TL049 TM03DN: BIT #40,MTDT(R2) ;TM03? ;TL049 BEQ 5$ ;IF EQ, NO. ;TL049 BIT #M.BOT!M.RWD,U.CW2(R5) ;TAPE AT BOT OR REWINDING? ;TL049 BNE 5$ ;IF NE, YES. ;TL049 BIC #M.1600,U.CW2(R5) ;ASSUME 800BPI. ;TL049 BIT #DS.PES,MTDS(R2) ;800 BPI ? ;TL049 BEQ 5$ ;IF EQ, YES. ;TL049 BIS #M.1600,U.CW2(R5) ;1600 BPI. ;TL049 5$: TSTB R0 ;ALREADY RETURNING ERROR? ;TL049 BMI EXIT ;YES MUST BE MORE IMPORTANT ;**-1 BIT #DS.BOT,MTDS(R2) ;READ REV INTO BOT ? ;CS002 BNE EXIT ;IF NE, YES. ;CS002 CMP MTFC(R2),#NOISE ;RECORD AT LEAST MIN SIZE ? ;TL100 BHIS 10$ ;IF HIS, YES. ;TL100 BIT #M.1600,U.CW2(R5) ;1600BPI TAPE? ;CS002 BNE EXIT ;IF NE, YES - LT MIN ALLOWED FOR 1600BPI;CS002 JMP COMRTY ;LT MIN NOT ALLOWED FOR 800BPI. ;TL100 10$: CMP R1,U.CNT(R5) ;TAPE DATA - MORE THAN REQUESTED ? ;TL100 BLOS EXIT ;NO EXIT SUCCESS ;**-1 MOV #IE.DAO&377,R0 ;YES INFORM THE USER BR EXIT ;EXIT ;+ ; **-EOFDON - WRITE TAPE MARK COMPLETION ROUTINE ; **-WRTDON - WRITE LOGICAL BLOCK COMPLETION ROUTINE ;- ;CS002 EOFDON: BIS #M.EOF,U.CW2(R5) ;SET TM STATUS ;**-3 WRTDON: MOV U.CNT(R5),R1 ;RETREIVE REQUESTED COUNT ADD MTFC(R2),R1 ;CALCULATE ACTUAL LENGTH BIT #DS.EOT,MTDS(R2) ;AT EOT? BEQ EXIT ;IF EQ NO MOV #IE.EOT&377,R0 ;SET EOT STATUS BIS #M.EOT,U.CW2(R5) ;SET EOT IN CHARACTERISTICS WORD BR EXIT ;EXIT ;CS002 RWDDON: BIT #DS.PIP,MTDS(R2) ;REWIND IN PROGRESS? ;CS002 BEQ 10$ ;IF EQ, DONE. ;CS002 BIS #M.RWD,U.CW2(R5) ;REWIND IN PROGRESS. ;CS002 10$: BIC #M.AEOV,U.CW2(R5) ;CLEAR OUT END OF VOLUME STATUS ;TL010 ;CS002 .IF DF P$$RFL ;CS002 BICB #US.PWF,U.STS(R5) ;CLEAR PWRFLD STATUS ;CS002 .ENDC ;CS002 ;CS002 ;**-1 EXTNST: CLR R1 ;NO STATUS TO RETURN EXIT: .IF DF D$$IAG ;**-1 CALL MMDINT ;**-1 .ENDC ;**-1 .IF DF E$$DVC MOVB RTTBL(R3),R2 ;SET RETRY COUNT ;**-1 BIS #RETRY*256.,R2 ;SET ORIGINAL COUNT .ENDC ;**-1 BIC #M.PEOV!7,U.CW2(R5) ;CLEAR PAST END OF VOLUME STATUS ;CS002 BICB #US.ABO,U.STS(R5) ;CLEAR ABORT INDICATION ;CS002 CALL $IODON ;FINISH I/O OPERATION ;**-1 JMP MMINI ;GO AGAIN ;CS002 ;CS002 ;**-1 ;+ ; **-CHKEOV - CHECK FOR LOGICAL END OF VOLUME ; THIS SUBROUTINE CHECKS FOR THE LOGICAL END-OF-VOLUME CONDITION ; ; RETURNS WITH CC IF NOT EOV. ; RETURNS WITH CS IF EOV. ;- CHKEOV: CLC ;CLEAR CARRY FOR RETURN BIT #REV,RHCS1(R2) ; READ REVERSE OPERATION? BNE 20$ ; IF NE YES CAN'T BE EOV ; AND DON'T SET EOF MOV MTFC(R2),-(SP) ; RETRIEVE FRAME COUNT SUB U.CNT(R5),(SP) ;GET NUMBER ACTUALLY SPACED CMP (SP)+,#1 ;EXACTLY ONE? (STARTED WITH 1) CLC ;ASSUME NOT EOV BNE 10$ ;IF NE NO, NOT EOV BITB #US.LAB,U.STS(R5) ;MOUNTED ANSII MAGTAPE? BNE 10$ ;IF NE YES, DO NOT REPORT EOV BIT #M.PEOV,U.CW2(R5) ;TAPE MARK OR BOT SEEN LAST TIME? ;TL010 BEQ 10$ ;IF EQ NO - EXIT WITH CC ;**-1 SEC ;EOV DETECTED 10$: BIS #M.EOF,U.CW2(R5) ;SET EOF STATUS 20$: RETURN ; .PAGE ;+ ;**-1 ; ; **-SELECT - TAPE UNIT SELECT ROUTINE ; THIS ROUTINE ATTEMPTS TO SELECT A DRIVE. IT SETS UP ; THE BOT AND HWL BITS IN THE CHARACTERISTICS WORD. ; ; ON RETURN: CC==>GOOD SELECT ; CS==>BAD SELECT ;- ;CS002 ;**-1 SELECT: MOV S.CSR(R4),R2 ;PICK UP CSR ADDRESS MOV U.FNUM(R5),RHCS2(R2) ;SELECT FORMATTER ;TL120 ;TL120 MOV MTTC(R2),-(SP) ;SAVE UNIT SELECT REGISTER ;**-1 MOVB U.UNIT(R5),(SP) ;SELECT DESIRED UNIT MOV (SP)+,MTTC(R2) ; ... BIC #M.BOT!M.EOT!M.HWL!M.SER,U.CW2(R5) ;STATUS TO BE UPDATED;CS002 SEC ;ASSUME BAD SELECT ;**-1 BIT #DS.MOL,MTDS(R2) ;IS THE DRIVE READY? BNE 10$ ;IF NE YES BIS #M.SER,U.CW2(R5) ;SET SELECT ERROR BIT BR 40$ ; BAD SELECT ;CS002 ;CS002 10$: BIT #DS.PIP,MTDS(R2) ;POSITIONING IN PROGRESS? ;**-1 BNE 20$ ;IF NE NO BIT #DS.BOT,MTDS(R2) ;IS DRIVE AT BOT? BEQ 20$ ;IF EQ NO BIS #M.BOT,U.CW2(R5) ;SET THE BIT BIC #M.RWD,U.CW2(R5) ;IF AT BOT RWD DONE 20$: BIT #DS.WRL,MTDS(R2) ;IS DRIVE WRITE-LOCKED? BEQ 30$ ;IF EQ NO BIS #M.HWL,U.CW2(R5) ;SET THE BIT 30$: BIT #DS.EOT,MTDS(R2) ;TAPE AT EOT? ;CS002 BEQ 35$ ;IF EQ, NO. ;CS002 BIS #M.EOT,U.CW2(R5) ;INDICATE EOT STATUS. ;CS002 35$: CLC ;TAPE DRIVE AVAILABLE. ;CS002 40$: RETURN ;**-1 ;CS002 ;+ ;**-45 ; **-LOGERR - SUBROUTINE TO LOG DEVICE ERRORS ;**-1 ;- ;**-1 LOGERR: .IF DF E$$DVC ;**-1 .IF DF D$$IAG TST RTTBL(R3) ;USER MODE FUNCTION? ;**-1 BMI 10$ ;IF MI, YES - THEY HANDLE ERRORS. ;CS002 .ENDC ;**-2 CALL $DVERR ;LOG THE ERROR 10$: RETURN .ENDC .PAGE .IF DF D$$IAG ; ; **-MMDINT-TU16 DIAGNOSTIC INTERRUPT AND TIMEOUT HANDLER ; ; IF ENTRY WAS FROM A DIAGNOSTIC CONTROL FUNCTION THEN MOVE I/O ; PACKET WORDS 17-20 TO WORDS 20-21 FOR $CRPAS ROUTINE. ; FOR ANY DIAGNOSTIC FUNCTION PASS THE UNIBUS DEVICE REGISTERS VIA ; THE $CRPAS ROUTINE. ; ; INPUTS ; R2= CSR ADDRESS ; R4= SCB ADDRESS ; ; OUTPUTS ; R1= IO PACKET ADDRESS ;- MMDINT: MOV R1,-(SP) ;SAVE R1 MOV S.PKT(R4),R1 ;GET IO PACKET ADDRESS BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION CALL? BEQ 3$ ;IF EQ NO MOV R1,-(SP) ;SAVE IO PACKET ADDRESS CMPB #IO.EOF/256.,I.FCN+1(R1) ;WRITE EOF CONTROL FUNCTION? BEQ 1$ ;IF EQ YES CMPB #IO.RWD/256.,I.FCN+1(R1) ; CNTRL OTHER THAN IO.EOF? BEQ 1$ ;IF EQ YES CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC MOV (SP)+,R1 ;RESTORE IO PACKET ADDRESS BR 3$ ;.. CONT ;CS002 1$: MOV I.PRM+14(R1),I.PRM+16(R1) ;MOVE WD20 TO WD21 ;**-2 MOV I.PRM+12(R1),I.PRM+14(R1) ;MOVE WD17 TO WD20 2$: CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC MOV (SP)+,R1 ;RESTORE IO PACKEªT ADDRESS MOV I.PRM+14(R1),I.PRM+12(R1) ;MOVE WD20 BACK TO WD17 MOV I.PRM+16(R1),I.PRM+14(R1) ;MOVE WD21 BACK TO WD20 3$: MOV (SP)+,R1 RETURN .ENDC .END ªãàykQ ›c, .TITLE DRSST .IDENT /04.01/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 04.01 ; ; D. N. CUTLER 30-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; ; MODIFIED BY: ; ; M. S. HARVEY 14-SEP-81 ; MSH189 -- ALLOW SST VECTORS TO BE SPECIFIED FROM ; READ-ONLY REGIONS ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS ;+ ; **-$DRSDV-SPECIFY DEBUGGING AID SST VECTOR ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO RECORD THE ADDRESS AND LENGTH ; OF A VECTOR OF SST SERVICE ROUTINE ENTRY POINTS FOR USE BY AN INTRA- ; TASK DEGUGGING AID (E.G. ODT) ; ; DPB FORMAT: ; ; WD. 00 -- DIC (103.),DPB SIZE(3.). ; WD. 01 -- ADDRESS OF THE SST VECTOR. ; WD. 02 -- NUMBER OF ENTRIES IN THE SST VECTOR. ; ; SST VECTOR FORMAT: ; ; WD. 00 -- TRAPS TO 4 (ODD ADDRESS, NONEX MEM, ETC.). ; WD. 01 -- SEGMENT FAULT. ; WD. 02 -- TRACE TRAP (T-BIT) OR EXECUTION OF BPT INSTRUCTION. ; WD. 03 -- EXECUTION OF AN IOT INSTRUCTION. ; WD. 04 -- EXECUTION OF AN ILLEGAL OR RESERVED INSTRUCTION. ; WD. 05 -- EXECUTION OF A NON RSX EMT INSTRUCTION. ; WD. 06 -- EXECUTION OF A TRAP INSTRUCTION. ; WD. 07 -- PDP 11/40 FLOATING POINT EXCEPTION FAULT. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF PART OF VECTOR ; IS OUTSIDE OF ISSUING TASK'S ADDRESS SPACE, ; VECTOR ADDRESS OF ZERO IS SPECIFIED, OR THE ; VECTOR SIZE IS GREATER THAN 31. WORDS. ;- .ENABL LSB $DRSDV::ADD #H.ODVL,R4 ;POINT TO ODT VECTOR LENGTH IN HEADER BR 10$ ;FINISH UP IN COMMON CODE ;+ ; **-$DRSTV-SPECIFY TASK SST VECTOR ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO RECORD THE ADDRESS AND LENGTH OF ; A VECTOR OF SST SERVICE ROUTINE ENTRY POINT FOR USE BY THE ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(105.),DPB SIZE(3.). ; WD. 01 -- ADDRESS OF THE SST VECTOR. ; WD. 02 -- NUMBER OF ENTRIES IN THE SST VECTOR. ; ; SST VECTOR FORMAT: ; ; WD. 00 -- TRAPS TO 4 (ODD ADDRESS, NONEX MEM, ETC.). ; WD. 01 -- SEGMENT FAULT. ; WD. 02 -- TRACE TRAP (T-BIT) OR EXECUTION OF A BPT INSTRUCTION. ; WD. 03 -- EXECUTION OF AN IOT INSTRUCTION. ; WD. 04 -- EXECUTION OF AN ILLEGAL OR RESERVED INSTRUCTION. ; WD. 05 -- EXECUTION OF A NON RSX EMT INSTRUCTION. ; WD. 06 -- EXECUTION OF A TRAP INSTRUCTION. ; WD. 07 -- PDP 11/40 FLOATING POINT EXCEPTION FAULT. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE SECOND WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IF RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF PART OF VECTOR ; IS OUTSIDE OF ISSUING TASK'S ADDRESS SPACE, ; VECTOR ADDRESS OF ZERO IS SPECIFIED, OR THE ; VECTOR SIZE IS GREATER THAN 31. WORDS. ;- $DRSTV::ADD #H.TKVL,R4 ;POINT TO TASK VECTOR LENGTH IN HEADER 10$: MOV (R3)+,R0 ;GET ADDRESS OF VECTOR BEQ 20$ ;IF EQ DEASSIGN VECTOR MOV (R3),R1 ;GET LENGTH OF SST VECTOR BEQ 15$ ;IF EQ DEASSIGN VECTOR CMP (R3),#31. ;VECTOR TOO BIG? BHI 30$ ;IF HI YES .IF DF A$$CHK!M$$MGE ASL R1 ;CONVERT LENGTH TO BYTES CALL $ACHCK ;ADDRESS CHECK SST VECTOR ;MSH189 BCC 15$ ;IF CC, ADDRESS CHECK OK ;MSH189 BMI 30$ ;IF MI, SERIOUS ADDRESS CHECK FAILURE ;MSH189 ;**-1 .ENDC 15$: MOV (R3),(R4) ;SET SST VECTOR LENGTH ASL (R4) ;CONVERT LENGTH¤ TO BYTES 20$: MOV -(R3),-(R4) ;SET SST VECTOR ADDRESS RETURN ;RETURN DIRECTIVE STATUS OF +1 30$: DRSTS D.RS98 ;SET DIRECTIVE STATUS .DSABL LSB .END ¤ hkQ ›c, .TITLE DSSDI .IDENT /00/ ; ; COPYRIGHT (C) 1975, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 00 ; ; C. A. MONIA 18-JUL-75 ; ; FORTRAN INTERFACE TO READ CONTACT SENSE MODULES ; ; LOCAL DATA ; ; LINK TO DSS11 DEVICE COMMON BLOCK ; .IF DF M$$MGE!I$$SCM .PSECT ISCOM,RW,GBL,OVR,D .BLKB I$$SSC&77 ; COMPUTE OFFSET FROM 32W BOUNDARY  ISCOM: ; REF LABEL .IFF .ASECT .=I$$SSC ISCOM: ; REF LABEL .ENDC .PSECT ; ; TABLE OF OFFSETS TO DSS11 DATA REGISTERS ; DSSMP: ; OFFST=2 .REPT I$$SDS .REPT 3 .BYTE OFFST OFFST=OFFST+2 .ENDR OFFST=OFFST+2 .ENDR .EVEN ;+ ; **-DI; DIW - FORTRAN CALLABLE SUBROUTINE TO READ CONTACT SENSE ; DSS11 MODULES ; ; CALLING SEQUENCE ; ; CALL DI(INM,ICNT,IDATA,[ISTS],[IUN]) ; ; WHERE: ; ; INM = INTEGER SPECIFYING NUMBER OF SAMPLES ; ICNT = INTEGER ARRAY. EACH ELEMENT CONTAINS AN INITIAL POINT ; DEFINING A 16 BIT FIELD. ; ; IDATA = INTEGER ARRAY TO RECEIVE CONTACT SENSE INFORMATION. ; ; ISTS = 2-WORD, INTEGER ARRAY TO RECEIVE STATUS. ; ; ISTS(1) RECEIVES STATUS PER ISA/DEC CONVENTION AS FOLLOWS: ; ; STATUS DEFINITION ; ------ ----------- ; ; +1 SUCCESS ALL DATA READ ; =>3 FAILURE ; 3 '0' SAMPLES REQUESTED ; >300 INVALID POINT SPECIFIED ; ; IUN = UNIT SPECIFICATION (IGNORED) ; ; THIS CALL DOES NOT PERFORM A QIO, INSTEAD THE EXTERNAL PAGE IS ACCESSED ; DIRECTLY. ; ; ACCESS IN A MAPPED SYSTEM IS VIA A SPECIAL COMMON AREA. THE UNMAPPED ; SYSTEM MAY ACCESS THE DSS DIRECTLY. ;- DI:: ; DIW:: ; MOV #3,R0 ; GET ARGUMENT COUNT-2 CALL .MLTPH ; SET FOR MULTIPOINT SAMPLE ; ; THE ABOVE CALL RETURNS THE FOLLOWING: ; ; C-CLEAR: ; R3=NUMBER OF SAMPLES ; R4=POINTER TO CONTROL ARRAY ; R5=POINTER TO DATA ARRAY ; ; (SP)+2=UNDEFINED ; (SP) =TWO-WORD I/O STATUS BLOCK ADDRESS ; ; C-SET: ; ; NUMBER OF SAMPLES=0 ; ; STACK SETUP AS DESCRIBED ABOVE ; BCS 40$ ; IF C/S 0 SAMPLES REQUESTED 10$: ; MOV (R4),R0 ; GET POINT NUMBER CALL .DIV16 ; DIVIDE BY 16 MOV R0,R2 ; SAVE BUS INDEX CALL RDSS ; READ DSS11 INPUT BCS 50$ ; IF C/S ILLEGAL POINT OR MODULE MOV R0,(R5) ; RETURN RESULT TO CALLER TST R1 ; POINT ON MODULE BOUNDARY? BEQ 30$ ; IF EQ YES MOV R2,R0 ; GET MODULE NUMBER AGAIN INC R0 ; INCREMENT TO NEXT IN SEQUENCE CALL RDSS ; READ DSS11 INPUT BCS 50$ ; IF C/S ILLEGAL POINT OR MODULE 20$: ; ASR R0 ; ROTATE MASK1 ROR (R5) ; ROTATE MASK2 DEC R1 ; DECREMENT REMAINDER BGT 20$ ; IF GT GO AGAIN 30$: ; CMP (R4)+,(R5)+ ; POINT TO NEXT SET OF ARGUMENTS DEC R3 ; DECREMENT POINT COUNT BNE 10$ ; IF NE GO AGAIN JMP .NRMRT ; TAKE NORMAL EXIT 40$: ; JMP .ILCSQ ; ILLEGAL CALLING SEQUENCE 50$: ; JMP .ILMRQ ; NONEXISTENT MODULE REQUESTED ; ; READ DSS11 INPUT REGISTER ; RDSS: ; CMP #-1,R0 ; LEGAL POINT? BLO 10$ „ ; IF LO NO MOVB DSSMP(R0),R0 ; GET OFFSET TO BUS ADDRESS MOV ISCOM(R0),R0 ; GET MODULE DATA 10$: ; RETURN ; .END „ÄðskQ ›c, .TITLE DXDRV .IDENT /03.04/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 03.03 ; ; H. LEV 16-JAN-75 ; ; PREVIOUSLY MODIFIED BY: ; ; C. A. D'ELIA ; ; MODIFIED BY: ; ; P. J. BEZEREDI 30-NOV-76 ; ; PB009 -- CORRECT OUT OF RANGE BRANCHES WHEN A ; MULTI-CONTROLLER DRIVER IS GENERATED. ; ; P. J. BEZEREDI 03-FEB-77  ; ; PB012 -- ADDITION OF ONLINE ERROR LOGGING AND ; INHIBIT RETRY SUPPORT. ; ; P. J. BEZEREDI 12-DEC-77 ; ; PB045 - ALLOW ALL RX11 REGISTERS TO BE ERROR LOGGED. ; ; P. J. BEZEREDI 13-DEC-77 ; ; PB049 -- PRESET BYTES TO TRANSFER TO 128. ; ; P. J. BEZEREDI 05-APR-78 ; ; PB070 -- REMOVE IO.WDD FUNCTION CODE CONFLICTS. ; ; D. S. SUMMERS -- 09-JUN-81 ; DS002 -- CORRECT ERRORLOG LOGGING ; ; RX01 - RX11 FLOPPY DISK DRIVER ; ; FUNCTIONS RECOGNIZED: ; IO.RPB - READ PHYSICAL BLOCK (MAY READ ANY SECTOR ON DISK) ; IO.WPB - WRITE PHYSICAL BLOCK (MAY WRITE ANY SECTOR ON DISK) ; IO.WDD - WRITE DELETED DATA - WRITE ANY SECTOR ON DISK ; SETTING THE DELETED DATA MARK IN SECTOR HEADER ; THE FOLLOWING TWO FUNCTION CODES OPERATE ON 256 WORD BLOCKS ; OF DATA (4 SECTORS) THE DRIVER AUTOMATICALLY INTERLEAVES ; AND SKEWS SECTORS TO OPTIMIZE THE TRANSFER OF DATA ; SO THAT A LONG READ/WRITE MAY BE DONE WITHOUT LOOSING ; A REVOLUTION OF THE DISK. THE INTERLEAVE FACTOR IS 2 ; AND THE SKEW FACTOR IS 6. ; IO.RLB - READ LOGICAL BLOCKS OF 256. WORDS ; IO.WLB - WRITE LOGICAL BLOCKS OF 256. WORDS. ; ; IF DELETED DATA IS READ, THE STATUS CODE RETURNED WILL ; BE IS.RDD, OTHERWISE IT IS IS.SUC ; .MCALL HWDDF$,PKTDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS PKTDF$ ; DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RETRY = 8. ; ERROR RETRY COUNT DXNUM = 4 ; NUMBER OF REGISTERS TO ERROR LOG ; PB045 ; ; RX11 DEVICE REGISTER OFFSETS AND BIT DEFINITIONS ; RXCS = 0 ; CONTROL STATUS REGISTER RXDB = 2 ; DATA BUFFER UNIT = 20 ; UNIT SELECT BIT DONE = 40 ; RX11 DONE INTEBL = 100 ; INTERRUPT ENABLE TR = 200 ; RX11 TRANSFER READY BIT (CPU-SILO) INIT = 40000 ; INITIALIZE RX11 ; ; FUNCTION CODES ; GO = 1 ; GO BIT FILL = 0+GO ; FILL SILO EMPTY = 2+GO ; EMPTY SILO WRITE = 4+GO ; WRITE A SECTOR READ = 6+GO ; READ A SECTOR WRTDD = 14+GO ; WRITE DELETED DATA RDERC = 16+GO ; READ ERROR CODE ; PB045 ; ; PB070 ; STATUS REGISTER BIT DEFINITIONS ; PB070 ; ; PB070 ; PB070 DD = 100 ; DELETED DATA READ ; PB070 ; PB070 ; ; LOCAL DATA ; ; ; CONTROLLER TABLE AND RETRY COUNT TABLE ( INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW R$$X11 ; ADDRESS OF CURRENT UCB FOR CONTROLLER RTTBL: .BLKW R$$X11 ; ERROR RETRY COUNT FOR CURRENT UNIT ; PB045 ; PB045 .IF DF E$$DVC ; PB045 ; PB045 CSRSV: .BLKW R$$X11 ; CSR SAVE AREA ; PB045 ; PB045 .ENDC ; PB045 ; PB045  ; PB045 .IF GT R$$X11-1 TEMP: .BLKW 1 ; TEMPORARY STORAGE FOR CURRENT CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $DXTBL::.WORD DXINI ; DEVICE INITIATOR ENTRY .WORD DXCAN ; CANCEL I/O OPERATION ENTRY .WORD DXOUT ; DEVICE TIME OUT ENTRY .WORD DXPWF ; POWERFAIL ENTRY POINT ;+ ; *** - DXINI FLOPPY DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QIO DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPOGATE THE ; EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, ; THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O REQUEST. OTHERWISE ; A RETURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL ; THE NEXT I/O OPERATION IS INITIATED. A RETURN TO THE CALLER IS THEN ; EXECUTED. ; ; INPUTS: ; R5 - ADDRESS OF UCB WHICH IS ASSOCIATED WITH CONTROLLER TO BE INITIATED ; ; OUTPUTS: ; IF THE CONTROLLER ASSOCIATED WITH THE SPECIFIED UCB IS NOT ; BUSY AND AN I/O REQUEST IS WAITING TO BE PROCESSED, THE REQUEST ; IS DEQUEUED AND THE DRIVER INITIATES THE REQUESTED FUNCTION. ; ;- .ENABL LSB 1$: RETURN ; ; PB070 DXINI: CALL $GTPKT ; GET NEXT I/O PACKET TO PROCESS ; PB070 BCS 1$ ; IF CS BUSY OR NO PACKET ; PB070 ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT ; ; R1 - ADDRESS OF THE I/O PACKET ; R2 - PHYSICAL UNIT NUMBER OF THE DEVICE TO PERFORM FUNCTION ON ; R3 - CONTROLLER NUMBER MULTIPLIED BY TWO ; R4 - ADDRESS OF SCB ; R5 - ADDRESS OF UCB FOR DEVICE TO PERFORM FUNCTION ON ; ; RX11 FLOPPY DISK I/O REQUEST PACKET FORMAT ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD. 02 -- ADDRESS OF TCB OF THE REQUESTING TASK ; WD. 03 -- POINTER TO SECOND LUN WORD OF REQUESTING TASKS HEADER ; WD. 04 -- CONTENTS OF FIRST LUN WORD ( UCB ADDRESS) ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.RPB, IO.WLB, OR IO.WPB) ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO TRANSFER ; WD. 15 -- NOT USED (IGNORED) ; WD. 16 -- LOW BYTE MUST BE ZERO, HIGH BYTE NOT USED ; WD. 17 -- LOGICAL OR PHYSICAL BLOCK NUMBER ; WD. 20 -- NOT USED ; ; DRIVER USAGE OF WORDS IN I/O PACKET ; I.PRM+6 (WD. 15) - STATUS REGISTER AFTER INTERRUPT ; I.PRM+10 (WD. 16) - LOGICAL OR PHYSICAL SECTOR NUMBER ; I.PRM+12 (WD. 17) - SIZE OF "THIS" TRANSFER ; I.PRM+14 (WD. 20) - PHYSICAL SECTOR NUMBER (1-26.) ; I.PRM+15 (WD. 20) - PHYSICAL TRACK NUMBER (0-77.) ; ; ; INITIALIZE DRIVER ; MOV R5,CNTBL(R3) ; SAVE UCB ADDRESS OF CURRENT REQUEST 10$: MOV #RETRY,RTTBL(R3) ; SET RETRY COUNT TSTB I.PRM+10(R1) ; HIGH BLOCK SPECIFIED? BEQ 20$ ; NO 15$: JMP 180$ ; YES, ERROR ; ; SET UP FIRST BLOCK OR SECTOR NUMBER ; 20$: MOV I.PRM+12(R1),R0 ; GET PHYSICAL OR LOGICAL BLOCK NUMBER MOV #128.,I.PRM+12(R1) ; PRESET TRANSFER SIZE ; PB049 BITB #IO.RPB&377,I.FCN(R1) ; PHYSICAL BLOCK FUNCTION? ; PB070 BNE 30$ ; YES ASL R0 ; CONVERT TO LOGICAL SECTOR NUMBER ASL R0 ; WHICH IS LBN*4 30$: MOV R0,I.PRM+10(R1) ; STORE IT 35$: MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS CALL TRKSEC ; CONVERT BLOCK # TO TRACK/SECTOR BCS 15$ ; IF CS BAD BLOCK NUMBER MOV S.CSR(R4),R2 ; GET ADDRESS OF CSR CMPB #IO.WLB/256.,I.FCN+1(R3) ; WRITE FUNCTION? BNE 140$ ;IF NE NO ; ; FILL SILO BEFORE WRITE ; CALL SETBUF ; SET UP BUFFER POINTER AND MAPPING REGISTER MOV #FILL,(R2) ; SET "FILL BUFFER" FUNCTION 70$: CLR R3 ; ASSUME NO DATA TO TRANSFER DEC R1 ; MORE DATA TO TRANSFER? BLT 74$ ; NO MOVB (R0)+,R3 ; YES, GET NEXT BYTE 74$: BITB #TR!DONE,(R2) ; CONTROLLER DONE? BMI 75$ ; IF MI YES BEQ 74$ ; IF EQ NO BR 90$ ; SILO IS FULL 75$: MOVB R3,RXDB(R2) ; PUT NEXT BYTE IN SILO BR 70$ ; AND WAIT TILL IT'S ACCEPTED 90$: TST R1 ; ALL BYTES TRANSFERED? BMI 130$ ; IF MI YES 95$: JMP DXRTY ; RETRY LAST FUNCTION ; ; EMPTY SILO AFTER READ ; 100$: MOV #EMPTY,(R2) ; SET "EMPTY BUFFER" FUNCTION CALL SETBUF ; SET BUFFER POINTER AND MAPPING REGISTER 110$: BITB #TR!DONE,(R2) ; CONTROLLER DONE? BMI 111$ ; IF MI YES BEQ 110$ ; IF EQ NO BR 120$ ; SILO IS EMPTY 111$: MOVB RXDB(R2),R3 ; GET NEXT BYTE FROM SILO DEC R1 ; DO WE WANT IT? BLT 110$ ; NO MOVB R3,(R0)+ ; YES, PUT IT IN BUFFER BR 110$ ; GET NEXT BYTE 120$: TST R1 ; ALL BYTES TRANSFERED? BGT 95$ ; IF GT ERROR MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS CALL NXTSEC ; UPDATE TO NEXT SECTOR BEQ 193$ ; ALL DONE BR 35$ ; CONTINUE ; ; INITIATE TRANSFER BETWEEN SILO AND DISK ; 130$: MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS MOV #WRITE,R0 ; ASSUME WRITE FUNCTION MOV I.FCN(R3),R1 ; COPY FUNCTION CODE ; PB070 BIC #7,R1 ; REMOVE QUALIFIER BITS ; PB070 CMP #IO.WDD,R1 ; WRITE DELETED DATA? ; PB070 BNE 141$ ; IF NE NO ; PB070 MOV #WRTDD,R0 ; SET "WRITE DELETED DATA" FUNCTION BR 141$ ; 140$: MOV #READ,R0 ; SET READ FUNCTION 141$: TSTB U.UNIT(R5) ; UNIT 1? BEQ 142$ ; IF EQ YES BIS #UNIT,R0 ; YES, SET TO SELECT UNIT 1 142$: ; REF LABEL ; PB045 ; PB045 ; PB045 .IF DF E$$DVC ; PB045 ; PB045 MOVB S.CON(R4),R1 ; RETREIVE CONTROLLER INDEX ; PB045 MOV R0,CSRSV(R1) ; SAVE FUNCTION AND UNIT NUMBER ; PB045 ; PB045 .ENDC ; PB045 ; PB045 ; PB045 MOV R0,(R2) ; INITIATE THE FUNCTION ; PB045 143$: BITB #TR!DONE,(R2) ; TRANSFER READY OR DONE? BMI 150$ ; IF MI TRANSFER READY BEQ 143$ ; IF EQ LOOP BR 95$ ; ERROR, NO TRANSFER REQUEST 150$: MOVB I.PRM+14(R3),RXDB(R2) ; LOAD SECTOR NUMBER 151$: BITB #TR!DONE,(R2) ; TRANSFER READY OR DONE? BMI 152$ ; IF MI TRANSFER READY BEQ 151$ ; IF EQ LOOP BR 95$ ; ERROR, NO TRANSFER REQUEST 152$: MOVB I.PRM+15(R3),RXDB(R2) ; LOAD TRACK NUMBER 155$: MOVB S.ITM(R4),S.CTM(R4) ; SET TIME OUT COUNT .IF DF E$$DVC CALL $BMSET ; SET I/O ACTIVE IN BITMAP .ENDC BIS #INTEBL,(R2) ; SET INTERRUPT ENABLE ; ; DXPWF - POWER FAIL ENTRY POINT ; POWER FAIL IS HANDLED BY THE DEVICE TIMING OUT, THEREFORE ; NO WNRK IS DNNE HERE. IT WILL BE HANDLED WHEN THE DEVICE ; TIME OUT ENTRY IS EXECUTED. ; DXPWF: ; ; DXCAN - CANCEL I/O ENTRY POINT ; CANCEL I/O IS A NOP OP FOR FILE STRUCTURED DEVICES ; DXCAN: RETURN ; ;+ ; *** - $DXINT - RX11 FLOPPY DISK INTERRUPT ENTRY POINT ; ;- INTSE$ DX,PR5,R$$X11 ;;; GENERATE INTERRUPT SAVE CODE MOV R3,-(SP) ;;; SAVE REGISTER MOV U.SCB(R5),R4 ;;; GET SCB ADDRESS MOV S.PKT(R4),R3 ;;; GET I/O PACKET ADDRESS MOV S.CSR(R4),R4 ;;; GET CSR ADDRESS MOV RXDB(R4),I.PRM+6(R3) ;;; SAVE CONTROLLER STATUS MOV (SP)+,R3 ;;; RESTORE REGISTER BIC #INTEBL,(R4) ;;; DISABLE INTERRUPTS CALL $FORK ;;; CREATE A SYSTEM PROCESS MOV R4,R2 ; COPY CSR ADDRESS MOV U.SCB(R5),R4 ; GET SCB ADDRESS MOVB S.CON(R4),R3 ; GET CONTROLLER INDEX TST (R2) ; ANY ERRORS? BPL 160$ ; IF PL NO .IF DF E$$DVC CALL LOGERR ; LOG DEVICE ERROR ; PB045 .ENDC BR DXRTY ; RETRY FUNCTION 160$: ASRB RTTBL+1(R3) ; INITIALIZE IN PROGRESS? BCS 170$ ; IF CS YES MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS CMPB #IO.RLB/256.,I.FCN+1(R3) ; READ? BNE 165$ ; IF NE NO JMP 100$ ; GO EMPTY SILO 165$: CALL NXTSEC ; UPDATE TO NEXT SECTOR BEQ 195$ ; ALL DONE 170$: JMP 35$ ; WRITE MORE DATA 180$: MOV #IE.BLK&377,R0 ; SET BAD BLOCK ERROR BR 210$ ; 190$: MOV #IE.VER&377,R0 ; SET UNRECOVERABLE ERROR BR 200$ ; 193$: BITB #IO.RPB&377,I.FCN(R3) ; READ PHYSICAL BLOCK FUNCTION? ; PB070 BEQ 195$ ; NO, THEN IGNORE DELETED DATA MARK MOV #IS.RDD&377,R0 ; YES, DEFAULT ON READ TO DELETED DATA BIT #DD,I.PRM+6(R3) ; WAS DELETED DATA READ? ; PB070 BNE 200$ ; YES 195$: MOV #IS.SUC&377,R0 ; NO, SET NORMAL SUCCESS 200$: MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS MOV I.PRM+4(R1),R1 ; SET BYTES TRANSFERED SUB U.CNT(R5),R1 ; CALCULATE BYTES ACTUALLY TRANSFERED .IF DF E$$DVC MOVB S.CON(R4),R3 ; RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ; SET FINAL RETRY COUNT BIS #RETRY*256.,R2 ; SET INITIAL RETRY COUNT .ENDC 210$: CALL $IODON ; SET DONE JMP DXINI ; TRY FOR ANOTHER REQUEST ; ;+ ; *** - DXOUT - FLOPPY DISK TIMEOUT ENTRY POINT ;- DXOUT: ;;; TIMEOUT ENTRY POINT ; PB045 ; PB045 ; PB045 .IF DF E$$DVC ; PB045 ; PB045 CALL LOGTMO ;;; LOG DEVICE TIMEOUT ; PB045 ; PB045 .IFF ; PB045 ; PB045  CALL $DTOER ;;; LOG DEVICE TIMEOUT ; PB045 ; PB045 .ENDC ; PB045 ; PB045 ; ; RETRY LAST FUNCTION ; DXRTY: MOVB S.CON(R4),R3 ; RESTORE CONTROLLER INDEX MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ; INHIBIT RETRIES? BNE 190$ ; IF NE YES DECB RTTBL(R3) ; ANY RETRIES LEFT? BEQ 190$ ; NO, ERROR MOVB #1,RTTBL+1(R3) ; YES, SET INITIALIZE IN PROGRESS ; PB045 ; PB045 .IF DF E$$DVC ; PB045 ; PB045 MOV #INIT,CSRSV(R3) ; SAVE FUNCTION CODE ; PB045 ; PB045 .ENDC ; PB045 ; PB045 ; PB045 MOV #INIT,(R2) ; INITIALIZE RX01 DRIVES JMP 155$ ; AND DO IT .DSABL LSB ; PB045 .IF DF E$$DVC ; PB045 ; PB045 ;+ ; PB045 ; **-LOGERR-LOG DEVICE ERROR ; PB045 ; **-LOGTMO-LOG DEVICE TIMEOUT ; PB045 ; ; PB045 ; THESE ROUTINES WILL ALLOCATE A CORE BLOCK, FILL IT WITH THE ; PB045 ; REGISTER INFORMATION, CALL THE APPROPRIATE EXECUTIVE ERROR ; PB045 ; LOGGING ROUTINE, DEALLOCATE THE CORE BLOCK, AND RETURN BACK TO ; PB045 ; THE CALLER. ; PB045 ; ; PB045 ; INPUTS: ; PB045 ; R3=CONTROLLER INDEX ; PB045 ; R4=SCB ADDRESS ; PB045 ; R5=UCB ADDRESS ; PB045 ; ; PB045 ; OUTPUTS: ; PB045 ; R2=CSR ADDRESS ; PB045 ; R4=SCB ADDRESS ; PB045 ; R5=UCB ADDRESS ; PB045 ; ; PB045 ; R0, R1 AND R3 ARE DESTROYED. ; PB045 ;- ; PB045 ; PB045 .ENABL LSB ; PB045 LOGERR: MOV #$DVERR,-(SP) ; LOG DEVICE ERROR ; PB045 BR 10$ ; ; PB045 LOGTMO: MOV #$DTOER,-(SP) ;;; LOG DEVICE TIMEOUT ; PB045 10$: MOV #DXNUM*2,R1 ; GET NUMBER OF BYTES TO ALLOCATE ; PB045 CALL $ALOCB ; ALLOCATE THE ERROR BLOCK ; PB045 BCC 20$ ; IF CC OK ; PB045 INC $ERRSQ ; INDICATE A MISSED ERRO ; PB045 CMP (SP)+,#$DTOER ; TIMEOUT? ; PB045 BNE 30$ ; IF NE NO ; PB045 BIC #INTEBL,@S.CSR(R4) ;;; CLEAR INTERRUPT ENABLE ; PB045 MTPS #0 ;;; ALLOW INTERRUPTS ; PB045 BR 30$ ; ; PB045 20$: MOV R0,R1 ; COPY CORE BLOCK ADDRESS ; PB045 MOV S.CSR(R4),R2 ; RETREIVE CSR ADDRESS ; PB045 MOV (R2),(R1) ; SAVE CSR CONTENTS ; PB045 BIS CSRSV(R3),(R1)+ ; SET BITS 0-4 IN RXCS ; PB045 MOV RXDB(R2),(R1)+ ; SAVE RXDB ; PB045 MOV S.PKT(R4),R3 ; GET I/O PACKET ADDRESS ; PB045 MOV I.PRM+6(R3),(R1)+ ; SAVE RXES ; PB045 MOV #RDERC,(R2) ; EXECUTE READ ERROR CODE FUNCTION ; PB045 25$: BITB #DONE,(R2) ; WAIT UNTIL DONE  ; PB045 BEQ 25$ ; IF EQ NO ; PB045 MOV RXDB(R2),(R1)+ ; SAVE RXER ; PB045 MOV R0,S.CSR(R4) ; FAKE CSR ADR WITH ERR BLOCK ADR ; DS002 CALL @(SP)+ ; LOG THE ERROR ; DS002 MOV R2,S.CSR(R4) ; RESTORE THE CSR ADR IN SCB ; DS002 MOV #DXNUM*2,R1 ; GET NUMBER OF BYTES TO DEALLOCATE ;**-5 CALL $DEACB ; DEALLOCATE THE ERROR BLOCK ; PB045 30$: MOV S.CSR(R4),R2 ; RETREIVE CSR ADDRESS ; PB045 RETURN ; ; PB045 .DSABL LSB ; PB045 ; PB045 .ENDC ; PB045  ; PB045 ; PB045 ;+ ; *** - TRKSEC - CONVERT LOGICAL OR PHYSICAL BLOCK NUMBER TO ; TRACK-SECTOR PAIR ; FROM ALGORITHM BY J GILBERT MODIFIED BY H. JACOBS ; ; INPUT: ; R3 - I/O PACKET ADDRESS ; I.PRM+10(R3) - LOGICAL OR PHYSICAL SECTOR ; ; OUTPUT: ; I.PRM+14(R3) - SECTOR (1-26.) ; I.PRM+15(R3) - TRACK (0-77.) ; R3 - UNCHANGED ; C CLEAR - VALID BLOCK ; C SET - BAD BLOCK NUMBER (PHYSICAL OR LOGICAL) ; ;- TRKSEC: MOV I.PRM+10(R3),R1 ; GET LOGICAL OR PHYSICAL BLOCK MOV #8.,R0  ; SET LOOP COUNT MOV #6400,R2 ; SET DIVISOR 1$: CMP R2,R1 ; DOES 26 GO INTO DIVIDEND? BHI 2$ ; BRANCH IF NOT, C CLEAR SUB R2,R1 ; SUBTRACT 26 FROM DIVIDEND SEC ; SET CARRY 2$: ROL R1 ; SHIFT DIVIDEND AND QUOTIENT DEC R0 ; DONE? BGT 1$ ; NO, LOOP MOVB R1,R0 ; GET TRACK NUMBER CLRB R1 ; CLEAR TRACK NUMBER SWAB R1 ; SHIFT DONE SECTOR NUMBER BITB #IO.RPB&377,I.FCN(R3) ; PHYSICAL BLOCK WANTED? ; PB070 BNE 10$ ; YES CMP #12.,R1 ; NO, C=1 IF 13<=R1<=25 ROL R1 ; DOUBLE FOR INTERLEAVE FACTOR ASL R0 ; ADD TRACK -TRACK SKEW ADD R0,R1 ; SKEW BY 2*TRACK ADD R0,R1 ; SKEW BY 4*TRACK ADD R0,R1 ; SKEW BY 6*TRACK ASR R0 ; RESTORE TRACK NUMBER MOV #26.,R2 ; SET MODULUS 5$: SUB R2,R1 ; MODULO SECTOR INTO RANGE -26. TO -1. BGE 5$ ; LOOP TILL REMAINDER GOES NEG ADD R2,R1 ; CONVERT TO RANGE 0-25. INC R0 ; LBN0 STARTS ON TRACK 1 10$: INC R1 ; CONVERT TO RANGE 1-26. MOV R1,I.PRM+14(R3) ; SAVE SECTOR NUMBER MOVB R0,I.PRM+15(R3) ; SAVE TRACK NUMBER CMP #77.*256.,I.PRM+14(R3) ; IS IT A VALID TRACK/SECTOR? RETURN ; ;+ ; *** - NXTSEC - UPDATE BLOCK NUMBER , BUFFER ADDRESS ; AND BUFFER POINTER ; ; INPUT: ; R3 - I/O PACKET ADDRESS ; R5 - UCB ADDRESS ; I.PRM+10(R3) - CURRENT BLOCK NUMBER ; I.PRM+12(R3) - BYTES TRANSFERED DURING LAST FUNCTION ; U.CNT(R5) - BYTES LEFT TO TRANSFER ; U.BUF(R5) - BUFFER ADDRESS ; ; OUTPUT: ; I.PRM+10(R3) - UPDATED BLOCK NUMBER ; U.BUF(R5) - UPDATED BY 128. BYTES ; U.CNT(R5) - UPDATED BY NUMBER OF WORDS TRANSFERED ; Z SET - ALL BYTES TRANSFERED ; Z CLEAR - MORE BYTES TO TRANSFER ; C CLEAR - VALID TRACK/SECTOR ; C SET - BAD BLOCK NUMBER ; ;+ NXTSEC: INC I.PRM+10(R3) ; UPDATE BLOCK NUMBER .IF NDF M$$MGE ADD #128.,U.BUF+2(R5) ; UPDATE BUFFER POINTER .IFF ADD #2.,U.BUF(R5) ; UPDATE MEMORY BLOCK NUMBER .ENDC SUB I.PRM+12(R3),U.CNT(R5) ; UPDATE BYTES LEFT TO TRANSFER RETURN ; ;+ ; *** - SETBUF - SET UP BUFFER POINTER FOR CPU - SILO TRANSFERS ; ; INPUT: ; R3 - I/O PACKET ADDRESS ; R5 - UCB ADDRESS ; ; OUTPUT: ; I.PRM+12(R3) - BYTES TO TRANSFER ; R0 - BUFFER ADDRESS ; R1 - BYTES TO TRANSFER ; IF MAPPED SYSTEM KISAR6 IS MAPPED TO BUFFER AND R1 IS BASE 140000 ; ;- SETBUF: MOV U.BUF+2(R5),R0 ; GET BUFFER ADDRESS MOV #128.,R1 ; DEFAULT TO 128. BYTE TRANSFER CMP U.CNT(R5),R1 ; 128. BYTES LEFT TO TRANSFER? BHIS 10$ ; YES MOV U.CNT(R5),R1 ; NO, GET RESIDUAL COUNT 10$: MOV R1,I.PRM+12(R3) ; STORE BYTES TO TRANSFER .IF DF M$$MGE MOV U.BUF(R5),@#KISAR6 :; SET MAPPING REGISTER .ENDC RETURN ; .END :""`kQ ›c, .TITLE ERROR .IDENT /07.07/ ; ; COPYRIGHT (C) 1981 BY DIGITAL EQUIPMENT CORPORATION ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 07.07 ; ; D. BROWN/P. J. BEZEREDI 15-MAY-81 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; C. PUTNAM 4-JUN-81 ; ; R. T. PERRON 2-JUL-81 ; ; P. J. BEZEREDI 13-AUG-81 ; ; P. J. BEZEREDI 2-NOV-81 ; UCB ADDRESS NOT VALID DURING NONSENSE INTERRUPT ; ; M. S. HARVEY 6-NOV-81 ; PRESERVE C-BIT ON PACKET CREATION FAILURE ; ; ERROR LOGGING ; ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$,EPKDF$,HDRDF$,HWDDF$,PKTDF$,F11DF$ CLKDF$ ;DEFINE CLOCK QUEUE OFFSETS EPKDF$ ;DEFINE ERROR PACKET OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE CPU REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS F11DF$ ;DEFINE VCB OFFSETS .IF DF E$$LOG ; ; LOCAL STORAGE ; DTOTMP: .BLKW 1 ;SAVED CSR CONTENTS FOR DEVICE TIMEOUT ; ; NONSENSE INTERRUPT STORAGE ; ; ADJACENCY ASSUMED ; .BLKW 2 ;FORK BLOCK NSIPSW: .BLKB 1 ;SAVED PS NSICNT: .BYTE -1 ;RECURSION COUNTER. ; RECURSION COUNTER=0 IMPLIES THAT A ; NONSENSE INTERRUPT IS BEING HANDLED. ; RECURSION COUNTER=-1 IMPLIES THAT A ; NONSENSE INTERRUPT IS NOT BEING ; HANDLED AT THE MOMENT. ; RECURSION COUNTER=N IMPLIES THAT N ; NONSENSE INTERRUPTS WERE LOST ;+ ; **-$NS0, $NS1, $NS2, $NS3, $NS4, $NS5, $NS6, $NS7- ; UNEXPECTED INTERRUPT IDENTIFIER ROUTINES. ; ; EACH OF THESE ROUTINES IS VECTORED TO BY ONE OF A GROUP OF 16 ; UNUSED VECTORS. THE VECTORS ARE SUB-CODED IN THE PS CONDITION ; CODES. ;- $NS0:: CALL NSIER ;;; CALL THE COMMON CODE .WORD 000 ;;; GROUP 000-017 (VECTORS 000-074) $NS1:: CALL NSIER ;;; .WORD 020 ;;; GROUP 020-037 (VECTORS 100-174) $NS2:: CALL NSIER ;;; .WORD 040 ;;; GROUP 040-057 (VECTORS 200-274) $NS3:: CALL NSIER ;;; .WORD 060 ;;; GROUP 060-077 (VECTORS 300-374) $NS4:: CALL NSIER ;;; .WORD 100 ;;; GROUP 100-117 (VECTORS 400-474) $NS5:: CALL NSIER ;;; .WORD 120 ;;; GROUP 120-137 (VECTORS 500-574) $NS6:: CALL NSIER ;;; .WORD 140 ;;; GROUP 140-157 (VECTORS 600-674) $NS7:: CALL NSIER ;;; .WORD 160 ;;; GROUP 160-177 (VECTORS 700-774) ; ; TEMPORARY ENTRIES TO NO-OP PREVIOUS ERROR LOGGING SYSTEM CALLS ; .IFTF $ALEMB:: $ALEB1:: MOV (SP)+,(SP) ;DISCARD THE ERROR CODE SEC ;INDICATE ALLOCATION FAILURE $QEMB:: RETURN ;DONE. .IFT ;+ ; **-$BMSET-SET A DRIVER'S BIT IN THE I/O ACTIVE BITMAP ; ; THIS COROUTINE RAISES THE PROCESSOR PRIORITY TO 7 AND THEN RECALLS ; THE CALLER WHO WILL START THE I/O FUNCTION AND RETURN HERE TO ALLOW ; INTERRUPTS. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; PRIORITY SET TO PR7. ;- $BMSET::MTPS #PR7 ;LOCK OUT INTERRUPTS CALL @(SP)+ ;;;RECALL THE CALLER MTPS #0 ;;;ALLOW INTERRUPTS RETURN ;EXIT .ENDC ;+ ; **-$DVTMO-LOG DEVICE TIMEOUT AT PR0 ; **-$DTOER-LOG DEVICE TIMEOUTS AT DEVICE PRIORITY ; ; THIS ROUTINE IS CALLED TO LOG A DEVICE TIMEOUT ERROR CONDITION. THE ; CONTROLLER'S INTERRUPT ENABLE BIT IS RESET AND THE PROCESSOR PRIORITY ; IS DROPPED TO ZERO. IF A DIAGNOSTIC FUNCTION WAS IN PROGRESS, NO ; ERROR IS LOGGED. ; ; INPUTS: ; ; R2=CSR ADDRESS ; R4=SCB ADDRESS ; ; OUTPUTS: ; ; R1=ADDRESS OF I/O PACKET (IF DIAGNOSTIC ENABLED) ; ; C=0 IF FUNCTION WAS NOT A USER MODE DIAGNOSTIC FUNTION. ; THE ERROR LOG PACKET IS FILLED AND THE SCB CONTAINS ; A POINTER TO IT. THE ERROR IN PROGRESS FLAG IS SET IN ; THE SCB. ; C=1 IF FUNCTION WAS A USER MODE DIAGNOSTIC FUNCTION. IN THIS ; CASE ONLY THE INTERRUPT ENABLE BIT IS CLEARED AND THE ; PRIORITY IS LOWERED TO ZERO. ;- .ENABL LSB $DVTMO:: ;LOG DEVICE TIMEOUTS .IF DF E$$LOG MOV (R2),DTOTMP ;SAVE THE CSR CONTENTS .ENDC BR 5$ ; $DTOER:: ;;;LOG DEVICE TIMEOUTS .IF DF E$$LOG MOV (R2),DTOTMP ;;;SAVE THE CSR CONTENTS .IFTF BIC #100,(R2) ;;;DISABLE THE DEVICE INTERRUPT MTPS #0 ;;;ALLOW INTERRUPTS 5$: ;REF LABEL .IF DF D$$IAG MOV S.PKT(R4),R1 ;PICK UP THE ADDRESS OF THE I/O PACKET SEC ;ASSUME IT IS A DIAGNOSTIC FUNCTION BITB #IQ.UMD,I.FCN(R1) ;IS IT A DIAGNOSTIC FUNCTION? BNE 60$ ;IF NE IT IS A DIAGNOSTIC FUNCTION .ENDC .IFT MOV R0,-(SP) ;SAVE FOR THE ERROR CODE MOV #E$CERR+<400*E$STMO>,R0 ;SET PACKET CODE BR 10$ ;GO PROCESS THE ERROR ;+ ; **-$DVCER-LOG A DEVICE ERROR ; ; THIS ROUTINE IS CALLED TO LOG A DEVICE ERROR. AN ERROR LOG PACKET ; WILL BE ALLOCATED AND THE CONTEXT OF THE CURRENT TRANSFER WILL BE ; SAVED. IF AN ERROR IS ALREADY IN PROGRESS FOR THIS DEVICE, THE ERROR ; WILL BE IGNORED. ; ; INPUTS: ; ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; IF THIS IS THE FIRST OCCURENCE OF THE ERROR, THE ERROR LOG ; PACKET IS FILED AND THE SCB IS SET TO POINT TO THE PACKET ; ADDRESS AND THE ERROR IN PROGRESS BIT IS SET. ; ; NOTE: ALL REGISTERS ARE PRESERVED. ;- $DVERR:: $DVCER::MOV R0,-(SP) ;SAVE FOR USE BY THE ERROR CODE MOV #E$CERR+<400*E$SDVH>,R0 ;GET THE HARD ERROR CODE 10$: CALL LOGTST ;SEE IF WE CAN LOG THE ERROR BCS 50$ ;IF CS WE CAN'T MOV R1,-(SP) ;SAVE FOR USE BY ERROR PACKET ROUTINES MOV R2,-(SP) ; MOV R3,-(SP) ; MOV R4,-(SP) ; MOVB S.RCNT(R4),R1 ;GET THE NUMBER OF REGISTERS TO SAVE ASL R1 ;CONVERT IT INTO A NUMBER OF BYTES .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;BAE REGISTERS PERSENT? BEQ 30$ ;IF EQ NO ADD #4,R1 ;FOUR BYTES FOR THE TWO EXTRA REGISTERS .ENDC 30$: MOVB S.ROFF(R4),R3 ;GET THE OFFSET TO THE FIRST REGISTER ADD S.CSR(R4),R3 ;COMPUTE THE ACTUAL REGISTER START .IF DF E$$ACT MOV #SM.HDR!SM.DID!SM.DOP!SM.DAT!SM.DAC,R2 ;SET FLAGS .IFF MOV #SM.HDR!SM.DID!SM.DOP!SM.DAT,R2 ;SET FLAGS .ENDC ; ; AT THIS POINT THE REGISTERS ARE: ; ; R0 = ENTRY TYPE CODE AND SUBTYPE CODE ; R1 = LENGTH OF DEVICE REGISTERS IN BYTES ; R2 = CONTROL MASK WORD ; R3 = BEGINNING ADDRESS OF DEVICE REGISTERS ; R4 = SCB ADDRESS (UNUSED BY $CRPKT) ; R5 = UCB ADDRESS CALL $CRPKT ;CREATE THE PACKET BCS 45$ ;IF CS FAILURE CMP R0,#E$CERR+<400*E$STMO> ;IS IT A TIMEOUT? BNE 40$ ;IF NE NOT A TIMEOUT MOVB S.ROFF(R4),R2 ;GET THE NUMBER OF REGISTERS TO OFFSET ASL R2 ;TURN IT INTO A NUMBER OF BYTES SUB R2,R1 ;COMPUTE THE ADDRESS OF THE CSR STORAGE MOV DTOTMP,(R1) ;INSERT THE SAVED CSR ADDRESS 40$: MOV R3,S.BMSV(R4) ;SAVE THE ERROR LOG PACKET ADDRESS BISB #SP.EIP,S.PRI(R4) ;SET ERROR IN PROGRESS 45$: MOV (SP)+,R4 ;RESTORE THE REGISTERS SAVED MOV (SP)+,R3 ;  MOV (SP)+,R2 ; MOV (SP)+,R1 ; 50$: MOV (SP)+,R0 ; .ENDC CLC ;SHOW PACKET OK 60$: RETURN ;DONE .DSABL LSB ;+ ; **-NSIER-UNEXPECTED (NONSENSE) INTERRUPT ERRORS ; ; THIS ROUTINE IDENTIFIES THE INTERRUPTING VECTOR AND LOGS THE ERROR. ; ; INPUTS: ; ; @(SP)=BITS 06:04 OF THE UNUSED VECTOR NUMBER ; ; OUTPUTS: ; ; AN ERROR LOG PACKET IS ALLOCATED AND QUEUED TO THE ERROR LOGGER. ;- .IF DF E$$LOG NSIER: MFPS -(SP) ;;;SAVE THE VECTOR ID (MODULO 20) INCB NSICNT ;;;NSI IN PROGRESS? BNE 10$ ;;;IF NE THEN NSI ALREADY IN PROGRESS BIT #ES.LOG,$ERFLA ;;;LOGGING ERRORS? BNE 20$ ;;;IF NE THEN OK TO LOG. DECB NSICNT ;;;RESTORE THE COUNTER 10$: CMP (SP)+,(SP)+ ;;;YES, SO CLEAR THE STACK RTI ;;;AND RETURN. ; ; THE NONSENSE INTERRUPT HAS NOT INTERRUPTED THE HANDLING OF A PREVIOUS ; NONSENSE INTERRUPT, SO GO AHEAD AND PROCESS IT. ; 20$: BIC #177760,(SP) ;;;ISOLATE THE VECTOR ID IN THE PS MOV (SP)+,NSIPSW ;;;SAVE THE VECTOR ID. BIS @(SP)+,NSIPSW ;;;ADD IN THE GROUP BIAS CALL $INTSV,PR7 ;;;SWITCH STACKS MOV #NSIPSW,R4 ;GET THE POINTER TO THE FORK BLOCK CALL $FORK0 ;AND FORK MOV #E$CCPU+<400*E$SINT>,R0 ;GET THE ERROR CODE MOV #2,R1 ;THE BUFFER LENGTH IS TWO BYTES .IF DF E$$ACT MOV #SM.HDR!SM.DAT!SM.DAC,R2 ;SET SUBPACKET FLAGS .IFF MOV #SM.HDR!SM.DAT,R2 ;SET SUBPACKET FLAGS .ENDC MOV #NSIPSW,R3 ;GET THE ADDRESS OF THE DATA SUBPACKET INC $ERRSQ ;COUNT ONE MORE ERROR LOGGED CALL $CRPKT ;CREATE THE PACKET BCS 30$ ;IF CS FAILURE TO ALLOCATE POOL CALL $QUPKT ;AND QUEUE IT. 30$: MOVB #-1,NSICNT ;RESTORE THE COUNTER RETURN ;DONE - RETURN TO FORK HANDLING ;+ ; **-$FNERL-FINISH ERROR LOGGING PROCESS ; ; THIS ROUTINE IS CALLED AT I/O DONE TIME OR WHEN IT IS NECESSARY ; TO QUEUE AN ERROR LOG PACKET AFTER A SUCCESSFUL RECOVERY OF A ; MID-TRANSFER ERROR. ; ; INPUTS: ; ; R0=FIRST I/O STATUS WORD ; R2=STARTING AND FINAL ERROR RETRY COUNTS ; (IF R2=0, DO NOT UPDATE HARD/SOFT LIMIT COUNTS) ; R3=ERROR LOG PACKET ADDRESS (IF R4=0) ; R4=SCB ADDRESS OR ZERO ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; THE ERROR PACKET IS QUEUED TO THE ERROR LOGGER. ; THE ERROR IN PROGRESS BIT IS CLEARED. ; ; R1, R2 AND R3 MAY BE DESTROYED ;- $FNERL::TST R4 ;DO WE HAVE AN SCB? BEQ 10$ ;IF EQ NO, R3 HAS PACKET ADDRESS MOV S.BMSV(R4),R3 ;YES, GET ADDRESS OF ERROR PACKET BEQ 40$ ;IF EQ THERE IS NONE 10$: MOV R0,-(SP) ;SAVE REGISTER MOV R2,(R3) ;INSERT RETRY COUNTS BEQ 35$ ;IF EQ DON'T UPDATE HARD/SOFT LIMIT COUNTS MOV R5,R2 ;COPY UCB ADDRESS ADD #U.ERHC,R2 ;ASSUME THIS IS A HARD ERROR TSTB R0 ;SUCCESSFUL FUNCTION? BMI 20$ ;IF MI NO ADD #U.ERSC-U.ERHC,R2 ;POINT TO SOFT ERROR COUNT MOVB #E$SDVS,E$HTYS+4(R3) ;SET SOFT ERROR CODE 20$: INCB (R2) ;COUNT ANOTHER ERROR INCB (R2) ;ADD ONE MORE FOR OVERFLOW TEST BNE 30$ ;IF NE NO OVERFLOW DECB (R2) ;NORMALIZE ERROR COUNT 30$: DECB (R2) ;... 35$: CALL $QUPKT ;QUEUE THE ERROR PACKET MOV (SP)+,R0 ;RESTORE REGISTERS TST R4 ;DO WE HAVE AN SCB? BEQ 50$ ;IF EQ NO 40$: BICB #SP.EIP,S.PRI(R4) ;CLEAR ERROR IN PROGRESS CLR S.BMSV(R4) ;SHOW NO ERROR LOG PACKET 50$: RETURN ; ;+ ; **-$LOGER-LOG AN ERROR LOG PACKET (NO ERROR NEED BE PRESENT) ; ; THIS ROUTINE IS CALLED BY DRIVERS THAT WISH TO CREATE AN ERROR LOG ; PACKET WHEN NO ERROR IS PRESENT, IE. FOR AN UNSOLICITED INTERRUPT. ; THE PACKET WILL BE CREATED AND THE DRIVER IS RESPONSIBLE FOR FILLING ; IN THE NECESSARY DATA INFORMATION. ; ; INPUTS: ; ; R1=LENGTH OF DATA TO BE LOGGED IN BYTES ; R4=SCB ADDRESS (IF ZERO THEN NO I/O PACKET IS PRESENT) ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; C=1 IF ERROR CANNOT BE LOGGED FOR ANY REASON ; C=0 IF ERROR CAN BE LOGGED ; R1=ADDRESS OF DATA AREA IN ERROR LOG PACKET ; R3=ADDRESS OF ERROR LOG PACKET ; ; R4 AND R5 ARE PRESERVED ; R0, R2 AND R3 ARE DESTROYED ;- $LOGER::CALL LOGTST ;SEE IF WE CAN LOG THE ERROR BCS 20$ ;IF CS WE CAN'T MOV #E$CDVI+<400*E$SDVI>,R0 ;SET ERROR CODE .IF DF E$$ACT MOV #SM.HDR!SM.DAT!SM.DAC!SM.DID,R2 ;SET FLAGS .IFF MOV #SM.HDR!SM.DAT!SM.DID,R2 ;SET FLAGS .ENDC TST R4 ;IS THERE AN SCB ADDRESS BEQ 10$ ;IF EQ NO BIS #SM.DOP,R2 ;YES, LOG I/O PACKET INFORMATION MOV #E$CERR+<400*E$SDVH>,R0 ;SET ERROR CODE 10$: CLR R3 ;DO NOT FILL DATA SUBPACKET AREA CALL $CRPKT ;CREATE THE ERROR LOG PACKET BCS 20$ ;IF CS FAILURE TST R4 ;SCB ADDRESS PRESENT? (C=0) BEQ 20$ ;IF EQ NO MOV R3,S.BMSV(R4) ;YES, SAVE ERROR LOG PACKET ADDRESS BISB #SP.EIP,S.PRI(R4) ;SET ERROR IN PROGRESS 20$: RETURN ; ;+ ; **-LOGTST-SEE IF WE CAN LOG AN ERROR ; ; THIS ROUTINE WILL CHECK AND SEE IF THE ERROR CAN BE SUCCESSFULLY ; LOGGED. IF IT CAN BE, THEN THE ERROR SEQUENCE NUMBER IS INCREMENTED. ; ; INPUTS: ; ; R4=SCB ADDRESS OR ZERO IF NO SCB ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; C=0 IF ERROR CAN BE LOGGED ; C=1 IF ERROR CANNOT BE LOGGED ;- LOGTST: BIT #ES.LOG,$ERFLA ;IS LOGGING OF ERRORS TURNED ON? BEQ 20$ ;IF EQ NO TST R4 ;SCB PRESENT? BEQ 5$ ;IF EQ NO BITB #SP.EIP!SP.ENB,S.PRI(R4) ;ERROR IN PROGRESS/LOGGING OFF? BNE 20$ ;IF NE YES 5$: INC $ERRSQ ;ONE MORE ERROR IN THE SYSTEM BITB #ES.LIM,$ERFLA ;IS LIMITING ENABLED? BEQ 10$ ;NO, SO DON'T PERFORM LIMITING CMPB U.ERHC(R5),U.ERHL(R5) ;IS THE HARD THRESHOLD EXCEEDED? BHIS 20$ ;IF HIS YES CMPB U.ERSC(R5),U.ERSL(R5) ;IS THE SOFT THRESHOLD EXCEEDED? BHIS 20$ ;IF HIS YES 10$: TST R4 ;SCB PRESENT? (C=0) BEQ 15$ ;IF EQ NO CLR S.BMSV(R4) ;MARK THAT WE DO NOT YET HAVE A PACKET 15$: RETURN ; 20$: SEC ;TOO BAD RETURN ; ;+ ; **-$CRPKT-CREATE ERROR LOG PACKET ; ; THIS ROUTINE IS CALLED TO CREATE AN ERROR LOG PACKET, EITHER FROM THE ; SEND MESSAGE DIRECTIVE PROCESSING, OR WITHIN THE EXECUTIVE AS PART OF ; THE PROCESSING OF A MEMORY ERROR, NONSENSE INTERRUPT, TIME CHANGE, ; POWER FAIL RECOVERY, OR DEVICE ERROR. ; ; INPUTS: ; ; R0=PACKET CODE ; R1=LENGTH OF DATA SUBPACKET ; R2=CONTROL MASK WORD ; R3=BEGINNING ADDRESS OF DATA FOR DATA SUBPACKET ; R4=TCB ADDRESS (FOR TASK SUBPACKET) ; R5=UCB ADDRESS (FOR DEVICE IDENTIFICATION SUBPACKET) ; ; OUTPUTS: ; ; R0=UNCHANGED ; R1=BEGINNING ADDRESS OF DATA SUBPACKET DATA ; R2=UNCHANGED ; R3=BEGINNING ADDRESS OF PACKET ; R4=UNCHANGED ; R5=UNCHANGED ; ; C=0 IF A PACKET WAS CREATED ; C=1 IF A PACKET WAS NOT CREATED ; ; OUTPUT PACKET FORMAT: ; ; +-----------------------------------------------+ ; | RESERVED FOR PACKET LINK WORD | ; +-----------------------------------------------+ ; | PACKET LENGTH (LENGTH OF REMAINDER OF PACKET) | ; +-----------------------------------------------+ ; | HEADER SUBPACKET | ; . . ; ; | | ; +-----------------------------------------------+ ; | OTHER SUBPACKETS | ; . . ; ; | | ; +-----------------------------------------------+ ;- $CRPKT::MOV R5,-(SP) ;SAVE ALL REGISTERS MOV R4,-(SP) ;... MOV R3,-(SP) ;... MOV R2,-(SP) ;... MOV R1,-(SP) ;... MOV R0,-(SP) ;... ; ; CHECK FOR A HEADER SUBPACKET. BECAUSE THERE WILL ALWAYS BE A HEADER ; SUBPACKET, THERE IS NO NEED TO ACTUALLY CHECK FOR WHETHER OR NOT A ; HEADER SUBPACKET HAS BEEN REQUESTED. NOTE THAT THE ACCUMULATED TOTAL ; LENGTH IS INITIALIZED BY JAMMING IT WITH THE LENGTH OF A HEADER ; SUBPACKET. THIS SAVES CODE OVER PERFORMING A SEPARATE INITIALIZATION ; SINCE THE HEADER SUBPACKET IS ALWAYS PRESENT. ; ; AN EXTRA FOUR BYTES IS ADDED TO THE LENGTH OF THE HEADER SUBPACKET TO ; ACCOUNT FOR THE PRECEEDING LINK WORD AND PACKET LENGTH. ; ROR R2 ;CHECK FOR A HEADER SUBPACKET BCS 5$ ;IF CS IT'S THERE CRASH ;CRASH -- SOMEONE GOOFED!! 5$: MOV #E$HLEN+4,R1 ;ADD IN THE LENGTH OF THE SUBPACKET ROR R2 ;CHECK FOR A TASK SUBPACKET BCC 10$ ;IF CC NO TASK SUBPACKET ADD #E$TLEN,R1 ;ADD IN THE SUBPACKET LENGTH 10$: ROR R2 ;CHECK FOR A DEVICE ID SUBPACKET BCC 20$ ;IF CC NO DEVICE ID SUBPACKET ADD #E$ILEN,R1 ;ADD IN THE SUBPACKET LENGTH 20$: ROR R2 ;CHECK FOR A DEVICE OP. SUBPACKET BCC 30$ ;IF CC NO DEVICE OP SUBPACKET ADD #E$OLEN,R1 ;ADD IN THE SUBPACKET LENGTH ; ; CHECK FOR A DEVICE ACTIVITY SUBPACKET ; ; IF THERE IS A DEVICE ACTIVITY SUBPACKET, THERE WILL BE ONE ENTRY IN ; THE SUBPACKET FOR EACH ACTIVE DEVICE (LESS ONE IF THERE IS ALSO A ; DEVICE OPERATION SUBPACKET) PLUS THE PREFIX HEADER LENGTH WORD. ; 30$: ROR R2 ;CHECK FOR A DEVICE ACTIVITY SUBPACKET .IF DF E$$ACT BCC 60$ ;IF CC NO DEVICE ACTIVITY SUBPACKET BIT #SM.DOP,4(SP) ;IS THERE A DEVICE OPERATION SUBPACKET? BNE 35$ ;IF NE YES CLR R5 ;CLEAR FOR NO UCB 35$: MOV R5,R0 ;SAVE FOR COMPARISON MOV R2,-(SP) ;SAVE THE MASK FOR FUTURE USE MOV #$SCDVT,-(SP) ;SETUP FOR COROUTINE CALL 40$: CALL @(SP)+ ;GET THE NEXT UCB BCS 50$ ;IF CS NO MORE ENTRIES BIT #DV.MSD,U.CW1(R5) ;IS IT A MASS STORAGE DEVICE? BNE 45$ ;IF NE NO MOV #1,S$$SPC(SP) ;MARK THAT WE ARE NOT INTERESTED IN THIS DCB BR 40$ ;GO TRY AGAIN 45$: TSTB S.STS(R4) ;CHECK TO SEE IF THE SCB HAS I/O ACTIVE BEQ 40$ ;IF EQ NO, IGNORE IT MOV S.PKT(R4),R3 ;GET THE I/O PACKET ADDRESS CMP I.UCB(R3),R5 ;IS THE I/O QUEUED TO THIS UCB? BNE 40$ ;IF NE NO, IGNORE IT CMP R5,R0 ;IS THIS OUR UCB? BEQ 40$ ;IF EQ YES, DON'T COUNT IT ADD #E$ALEN,R1 ;COUNT THE I/O. BR 40$ ;LOOP 50$: ADD #2,R1 ;ADD IN THE LENGTH OF THE PREFIX MOV (SP)+,R2 ;RESTORE THE MASK .ENDC ; ; CHECK FOR A DATA SUBPACKET ; 60$: ROR R2 ;CHECK FOR A DATA SUBPACKET BCC 70$ ;IF CC NO DATA SUBPACKET ADD 2(SP),R1 ;ADD IN THE LENGTH OF THE SUBPACKET ADD #2,R1 ;AND ADD IN THE PREFIX LENGTH WORD ; ; ALLOCATE THE PACKET ; 70$: CMP #512.,R1 ;IS THE PACKET A REASONABLE LENGTH? BLO 75$ ;IF LO NO CALL $ALOCB ;ALLOCATE THE CORE BLOCK BCC 80$ ;IF CC OK 75$: CALLR PKTXIT ;FAILURE, RESTORE REGISTERS AND EXIT 80$: MOV R0,-(SP) ;SAVE THE ADDRESS FOR FUTURE USE MOV 14(SP),R5 ;RETRIEVE POSSIBLE UCB ADDRESS ; ; CREATE THE PACKET ; ; AT THIS POINT: ; ; R0=ADDRESS OF ALLOCATED BLOCK ; R1=LENGTH OF ALLOCATED BLOCK ; R2=UNDEFINED ; R3=UNDEFINED ; R4=UNDEFINED ; R5=UCB ADDRESS ; CREPKT: CLR (R0)+ ;SETUP THE LINK WORD SUB #4,R1 ;THE DATA LENGTH IS LESS THE HEADER MOV R1,(R0)+ ;PUT IN THE PACKET LENGTH MOV #E$HLEN,(R0)+ ;PUT IN THE SUBPACKET LENGTH MOV 6(SP),R2 ;GET THE SAVED CONTROL MASK WORD MOV R2,(R0)+ ;INSERT IT INTO THE SUBPACKET MOV #1+,(R0)+ ;INSERT RSX-11M CODE MOV $SYSID,(R0)+ ;PUT IN THE FOUR BYTES OF OPERATING MOV $SYSID+2,(R0)+ ; SYSTEM IDENTIFICATION .IF DF M$$MGE&M$$EXT MOV #EH$NOR!<*400>,(R0)+ ;SET FLAGS .IFF .IF DF M$$MGE MOV #EH$NOR!<*400>,(R0)+ ;SET FLAGS .IFF MOV #EH$NOR!,(R0)+ ;INSERT FLAGS .ENDC .ENDC INC $ENTSQ ;COUNT THE NEXT ENTRY MOV $ENTSQ,(R0)+ ;WRITE IT MOV $ERRSQ,(R0)+ ;PUT IN THE ERROR SEQUENCE COUNT MOV 2(SP),(R0)+ ;PUT IN THE ENTRY TYPE CODE AND SUBCODE MOV #$TTNS-<6*2>,R3 ;GET THE POINTER TO THE SYSTEM TIME MOV #6,R1 ;GET THE NUMBER OF PARAMETERS TO INSERT 10$: MOVB (R3)+,(R0)+ ;INSERT THE ITEM IN THE TIME STAMP TSTB (R3)+ ;MOVE TO NEXT ITEM SOB R1,10$ ;LOOP UNTIL DONE. MOVB $PRMOD,(R0)+ ;PUT IN THE PROCESSOR INFORMATION CLRB (R0)+ ;CLEAR THE RESERVED BYTE MOV #1,(R0)+ ;SETUP THE URM AS CPA ROR R2 ;DISCARD THE FLAG FOR THE HEADER ; ; CREATE THE TASK SUBPACKET ; ; ; AT THIS POINT: ; ; R0=POINTER TO NEXT FREE ENTRY IN ALLOCATED BLOCK ; R1=UNDEFIED ; R2=CONTROL MASK WORD, SHIFTED RIGHT 1 ; R3=UNDEFINED ; R4=UNDEFINED ; R5=UCB ADDRESS ; CRETSK: ROR R2 ;CHECK THE FLAG FOR TASK SUBPACKET BCC CREDID ;IF CC NO TASK SUBPACKET MOV #E$TLEN,(R0)+ ;PUT IN THE SUBPACKET LENGTH MOV 12(SP),R1 ;GET THE SAVED TCB ADDRESS CALL CRTASP ;CREATE THE TASK SUBPACKET ; ; CREATE THE DEVICE IDENTIFICATION SUBPACKET ; ; AT THIS POINT: ; ; R0=POINTER TO NEXT FREE ENTRY IN ALLOCATED BLOCK ; R1=UNDEFINED ; R2=CONTROL MASK WORD, SHIFTED RIGHT 2 ; R3=UNDEFINED ; R4=UNDEFINED ; R5=UCB ADDRESS ; CREDID: ROR R2 ;IS THERE A DEVICE ID SUBPACKET? BCC CREDOP ;IF CC NO MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS MOV #E$ILEN,(R0)+ ;INSERT THE LENGTH OF THE SUBPACKET CALL CRDEVP ;CREATE DEVICE INFORMATION BIT #DV.DIR,U.CW1(R5) ;IS THIS A DIRECTORY DEVICE? BEQ 5$ ;IF EQ NO, DON'T INTERPRET VCB MOV U.VCB(R5),R3 ;GET A POINTER TO THE VCB BNE 15$ ;IF NE VCB EXISTS ASSUME V.PKSR,V.LABL+12. 5$: MOV #/2,R3 ;GET THE NUMBER OF WORDS TO CLEAR 10$: CLR (R0)+ ;CLEAR OUT THE VOLUME NAME AND PACK ID. SOB R3,10$ ;LOOP UNTIL DONE CLEARING BR 30$ ;DONE WITH THE VOLUME INFORMATION 15$: ADD #V.LABL,R3 ;POINT AT THE LABEL MOV #/2,R1 ;GET THE NUMBER OF WORDS TO MOVE 20$: MOV (R3)+,(R0)+ ;TRANSFER VOLUME NAME AND PACK ID. SOB R1,20$ ;LOOP UNTIL DONE BIT #DV.SQD,U.CW1(R5) ;IS THIS A DISK? BEQ 30$ ;IF EQ YES CMP -(R0),-(R0) ;NO, BACKUP TO PACK SERIAL NUMBER CLR (R0)+ ;CLEAR THE PACK SERIAL NUMBER CLR (R0)+ ;... 30$: MOV #1,(R0)+ ;ALL DEVICES ARE OF TYPE 1 MOV U.CW3(R5),(R0)+ ;GET LOW ORDER BLOCKS IN DEVICE MOVB U.CW2(R5),(R0)+ ;GET HIGH ORDER BLOCKS IN DEVICE CLRB (R0)+ ; MOV U.IOC(R5),(R0)+ ;INSERT THE I/O COUNT LOW ORDER MOV U.IOC+2(R5),(R0)+ ;INSERT THE I/O COUNT HIGH ORDER MOV U.ERSC(R5),(R0)+;INSERT THE SOFT AND HARD COUNTS BIT #SM.ZER,6(SP) ;ZERO THE COUNTS? BEQ CREDOP ;IF EQ NO .IF DF M$$MUP TST -(R5) ;IGNORE U.OWN .ENDC CLR -(R5) ;CLEAR THE HARD AND SOFT COUNTS TST -(R5) ;DON'T TOUCH THE LIMITS CLR -(R5) ;CLEAR THE HIGH ORDER I/O COUNT CLR -(R5) ;CLEAR THE LOW ORDER I/O COUNT .IF DF M$$MUP ADD #2*5.,R5 ;POINT BACK TO THE UCB ITSELF .IFF ADD #2*4,R5 ;POINT BACK TO THE UCB ITSELF .ENDC ; ; CREATE THE DEVICE OPERATION SUBPACKET ; ; AT THIS POINT: ; ; R0=POINTER TO NEXT FREE ENTRY IN ALLOCATED BLOCK ; R1=UNDEFINED ; R2=CONTROL MASK WORD, SHIFTED RIGHT 3 ; R3=UNDEFINED ; R4=UNDEFINED ; R5=UCB ADDRESS ; CREDOP: ROR R2 ;CHECK FOR PRESENCE OF SUBPACKET BCC CREIOA ;IF CC NO SUCH SUBPACKET MOV #E$OLEN,(R0)+ ;INSERT THE SUBPACKET LENGTH MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS MOV S.PKT(R4),R1 ;GET THE I/O PACKET POINTER MOV I.TCB(R1),R1 ;GET THE TCB POINTER CALL CRTASP ;INSERT THE TASK INFORMATION CALL CRIOPP ;INSERT THE I/O PACKET INFORMATION CLR (R0)+ ;NO CURRENT RETRY COUNT ; ; I/O ACTIVITY SUBPACKET ; ; AT THIS POINT: ; ; R0=POINTER TO NEXT FREE ENTRY IN ALLOCATED BLOCK ; R1=UNDEFINED ; R2=CONTROL MASK WORD, SHIFTED RIGHT 4 ; R3=UNDEFINED ; R4=UNDEFINED ; R5=UCB ADDRESS ; CREIOA: ROR R2 ;CHECK FOR AN I/O ACTIVITY SUBPACKET .IF DF E$$ACT BCC CREDAT ;IF CC NO I/O ACTIVITY SUBPACKET ; ; THE LENGTH OF THE I/O ACTIVITY SUBPACKET WILL BE COMPUTED WHEN THE ; ENTIRE SUBPACKET HAS BEEN CREATED. SAVE THE BEGINNING ADDRESS OF ; THE SUBPACKET FOR FUTURE USE. ; MOV R0,-(SP) ;SAVE THE BEGINNING SUBPACKET ADDRESS CLR (R0)+ ;GET RID OF ANYTHING IN THE LENGTH WORD MOV R5,R2 ;SAVE UCB ADDRESS FOR REFERENCE MOV #$SCDVT,-(SP) ;SETUP FOR THE COROUTINE CALL 10$: CALL @(SP)+ ;GET THE NEXT DEVICE BCS 30$ ;IF CS ALL DONE BIT #DV.MSD,U.CW1(R5) ;IS IT A MASS STORAGE DEVICE? BNE 20$ ;IF NE YES, PROCESS IT MOV #1,S$$SPC(SP) ;MARK TO SKIP THIS SCB BR 10$ ;LOOP UNTIL DONE 20$: CMP R5,R2 ;IS THIS UCB US? BEQ 10$ ;IF EQ IGNORE IT TSTB S.STS(R4) ;CHECK FOR THE SCB ACTIVE BEQ 10$ ;IF EQ DEVICE IS NOT ACTIVE MOV S.PKT(R4),R3 ;GET A COPY OF THE I/O PACKET ADDRESS CMP I.UCB(R3),R5 ;IS THE I/O QUEUED TO THIS UCB? BNE 10$ ;IF NE NO CALL CRDEVP ;CREATE THE DEVICE INFORMATION MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOV I.TCB(R1),R1 ;GET ACTIVE TCB ADDRESS CALL CRTASP ;CREATE THE TASK INFORMATION TST -(R0) ;POINT BACK TO THE TI: UNIT NUMBER MOVB (R0),E$ATIU-E$AFNC(R0) ;INSERT THE TI: UNIT NUMBER CALL CRIOPP ;CREATE THE I/O PACKET INFORMATION BR 10$ ;LOOP UNTIL DONE 30$: MOV R0,R2 ;GET A COPY OF THE CURRENT PACKET ADDRESS SUB (SP),R2 ;COMPUTE THE SUBPACKET LENGTH MOV R2,@(SP)+ ;INSERT THE LENGTH IN THE SUBPACKET PREFIX .ENDC ; ; CREATE THE DATA SUBPACKET ; ; AT THIS POINT: ; ; R0=POINTER TO NEXT FREE ENTRY IN ALLOCATED BLOCK ; ALL AOTHER REGISTERS ARE UNDEFINED ; CREDAT: BIT #SM.DAT,6(SP) ;DO WE HAVE A DATA SUBPACKET? BEQ 20$ ;IF EQ NO MOV 4(SP),R3 ;GET THE DATA SUBPACKET LENGTH MOV R3,(R0) ;PUT IN THE LENGTH OF THE DATA ITSELF ADD #2,(R0)+ ;ADD IN THE SUBPACKET HEADER LENGTH ASR R3 ;CONVERT # OF BYTES TO # OF WORDS MOV R0,R1 ;COPY SUBPACKET DATA ADDRESS MOV 10(SP),R2 ;GET THE DATA ADDRESS BEQ 20$ ;DON'T MOVE THE DATA IN 10$: MOV (R2)+,(R0)+ ;MOVE IN A DATA ITEM SOB R3,10$ ;LOOP UNTIL DONE 20$: CLC ;PACKET COULD BE CREATED MOV (SP)+,R3 ;RESTORE THE PACKET ADDRESS ; ; CLEAN STACK WHILE PRESERVING CARRY BIT ; PKTXIT: MOV (SP)+,R0 ;RESTORE THE ENTRY CODE MOV (SP)+,R2 ;DISCARD THE DATA SUBPACKET LENGTH MOV (SP)+,R2 ;RESTORE THE CONTROL MASK WORD MOV (SP)+,R4 ;DISCARD THE DATA ADDRESS MOV (SP)+,R4 ;RESTORE THE TCB ADDRESS MOV (SP)+,R5 ;RESTORE THE UCB ADDRESS RETURN ;DONE ;+ ; **-CRTASP-CREATE TASK INFORMATION ; ; CREATES THE FOLLOWING INFORMATION IN THE CURRENT SUBPACKET: ; ; +-----------------------------------------------+ ; | TASK NAME IN RAD50 | ; | | ; +-----------------------------------------------+ ; | TASK UIC | ; +-----------------------------------------------+ ; | TASK TI: DEVICE NAME | ; +-----------------------+-----------------------+ ; | FLAGS | TASK TI: UNIT NUMBER | ; +-----------------------+-----------------------+ ; ; FLAGS: ; ; ET$PRV TASK IS PRIVILEGED ; ET$PRI TERMINAL IS PRIVILEGED ; ; INPUTS: ; ; R0=POINTER TO SUBPACKET FOR INSERTION ; R1=POINTER TO TASK TCB ; ; OUTPUTS: ; ; R0=UPDATED ; R1 AND R3 ARE DESTROYED ; R4 AND R5 ARE PRESERVED ;- CRTASP: SAVNR ;SAVE R4 AND R5 MOV T.NAM(R1),(R0)+ ;PUT IN THE TASK NAME MOV T.NAM+2(R1),(R0)+ ;... MOV T.PCB(R1),R4 ;GET A POINTER TO THE PCB MOV P.HDR(R4),R4 ;GET A POINTER TO THE HEADER MOV H.CUIC(R4),(R0)+;INSERT THE UIC MOV T.UCB(R1),R5 ;GET THE TI: UCB POINTER 10$: MOV U.RED(R5),R5 ;FOLLOW THE REDIRECT POINTER CMP R5,U.RED(R5) ;IS THE DEVICE REDIRECTED? BNE 10$ ;IF NE YES MOV (R5),R3 ;GET THE TI: DCB POINTER MOV D.NAM(R3),(R0)+ ;INSERT THE DEVICE NAME CLR (R0) ;INITIALIZE THE FLAG AND UNIT # WORD BIT #U2.PRV,U.CW2(R5) ;IS THE TI: PRIVILEGED? BEQ 20$ ;IF EQ NO BIS #ET$PRI*400,(R0); MARK THE TI: PRIVILEGED 20$: BIT #T3.PRV,T.ST3(R1) ;IS THE TASK PRIVILEGED? BEQ 25$ ;IF EQ NO BIS #ET$PRV*400,(R0);MARK THE TASK PRIVILEGED 25$: MOVB D.UNIT(R3),(R0) ;GET THE STARTING UNIT # FOR THIS DCB SUB D.UCB(R3),R5 ;FORM OFFSET TO THIS UCB BEQ 40$ ;IF EQ THIS IS THE FIRST ONE 30$: INC (R0) ;COUNT ONE MORE UNIT NUMBER SUB D.UCBL(R3),R5 ;GET THE LENGTH OF A UCB BNE 30$ ;IF NE LOOP UNTIL WE GET THE RIGHT ONE 40$: TST (R0)+ ;POINT PAST THE FLAG ENTRY RETURN ;DONE ;+ ; **-CRDEVP-CREATE DEVICE INFORMATION ; ; CREATES THE FOLLOWING INFORMATION IN THE CURRENT SUBPACKET: ; ; +-----------------------------------------------+ ; | LOGICAL DEVICE NAME MNEMONIC | ; +-----------------------+-----------------------+ ; | CONTROLLER NUMBER | DEVICE UNIT NUMBER | ; +-----------------------+-----------------------+ ; | PHYSICAL SUBUNIT # | PHYSICAL UNIT # | ; +-----------------------+-----------------------+ ; | RESERVED | FLAGS | ; +-----------------------+-----------------------+ ; ; INPUTS: ; ; R0=POINTER TO DATA AREA ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; R0=UPDATED ; R1 AND R3 ARE DESTROYED ; R4 AND R5 ARE PRESERVED ;- CRDEVP: CLR -(SP) ;CLEAR FLAG WORD MOV (R5),R3 ;GET A POINTER TO OUR DCB MOV D.NAM(R3),(R0)+ ;PUT IN THE LOGICAL DEVICE MNEMONIC MOVB D.UNIT(R3),(R0) ;SETUP THE FIRST UNIT COVERED MOV R5,R1 ;COPY UCB ADDRESS SUB D.UCB(R3),R1 ;GET THE LENGTH OF THE UCB'S BEQ 20$ ;IF EQ NO MORE UCB'S TO COUNT 10$: INC (R0) ;COUNT ANOTHER UCB SUB D.UCBL(R3),R1 ;ACCOUNT FOR THE LENGTH BNE 10$ ;IF NE LOOP 20$: TSTB (R0)+ ;POINT TO THE CONTROLLER NUMBER MOVB S.CON(R4),(R0) ;GET THE CONTROLLER INDEX ASRB (R0)+ ;AND MAKE IT A CONTROLLER NUMBER MOVB U.UNIT(R5),(R0)+;GET THE PHYSICAL UNIT NUMBER CLRB (R0)+ ;CLEAR THE SUBUNIT NUMBER CMP D.NAM(R3),#"MM ;MM MAGTAPE? BEQ 30$ ;IF EQ YES CMP D.NAM(R3),#"MF ;MF MAGTAPE? BNE 40$ ;IF NE NO 30$: MOVB U.UNIT(R5),-(R0);SET SUBUNIT NUMBER MOVB U.VCB+2(R5),-(R0) ;SET FORMATTER NUMBER BIS #EI$SUB,(SP) ;FLAG AS A SUBCONTROLLER DEVICE TST (R0)+ ;POINT TO FLAG WORD 40$: MOV (SP)+,(R0)+ ;SET FLAG WORD RETURN ;+ ; **-CRIOPP-INSERT I/O PACKET PARAMETERS ; ; INSERTS THE FOLLOWING I/O PACKET PARAMETERS: ; ; +-----------------------------------------------+ ; | I/O FUNCTION CODE | ; +-----------------------+-----------------------+ ; | RESERVED | FLAGS | ; +-----------------------+-----------------------+ ; | TRANSFER OPERATION ADDRESS | ; | | ; +-----------------------------------------------+ ; | TRANSFER OPERATION BYTE COUNT | ; +-----------------------------------------------+ ; ; INPUTS: ; ; R0=POINTER TO SUBPACKET DATA ; R4=SCB ADDRESS ; R5=UCB ADDRESS  ; ; OUTPUTS: ; ; R0=UPDATED ; R1 AND R3 ARE DESTROYED ; R4 AND R5 ARE PRESERVED ;- CRIOPP: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOV I.FCN(R1),R3 ;GET FUNCTION CODE MOV R3,(R0)+ ;INSERT IT CLR (R0) ;SETUP FOR THE FLAGS ; ; OBTAIN A MASK BIT FOR THE I/O FUNCTION CODE ; MOV (R5),R1 ;GET THE DCB POINTER ADD #D.MSK+2,R1 ;AND POINT TO THE FUNCTION MASK CLRB R3 ;CLR MODIFIER FLAGS SWAB R3 ;PUT FUNCTION CODE IN LOW BYTE CMP R3,#15. ;IS THE FUNCTION IN THE SECOND MASKS? BLOS 10$ ;IF LOS FUNCTION IN FIRST MASK SUB #16.,R3 ;FIX THE FUNCTION CODE ADD #8.,R1 ;POINT TO THE SECOND SET 10$: ASL R3 ;MAKE FUNCTION CODE A WORD INDEX MOV $BTMSK(R3),R3 ;GET BIT THAT CORRESPONDS TO FUNCTION CODE ; ; SEE IF THE FUNCTION IS OTHER THAN A TRANSFER FUNCTION ; BIT R3,(R1)+ ;IS IT A CONTROL FUNCTION? BNE 20$ ;IF NE IT IS BIT R3,(R1)+ ;IS IT A NOOPED FUNCTION? BNE 20$ ;IF NE IT IS BIT R3,(R1)+ ;IS IT AN ACP FUNCTION? BNE 20$ ;IF NE IT IS BIS #EO$TRA,(R0) ;TRANSFER FUNCTION ; ; INSERT THE OTHER FLAGS ; 20$: BITB #UC.NPR,U.CTL(R5) ;IS IT A DMA DEVICE? BEQ 30$ ;IF EQ NO BIS #EO$DMA,(R0) ;DMA DEVICE .IF DF M$$EXT BIT #DV.MBC!DV.EXT,U.CW1(R5) ;IS IT A 22-BIT DEVICE? BEQ 30$ ;IF EQ NO BIS #EO$EXT,(R0) ;SET 22-BIT DEVICE .IFTF 30$: MOV (R0)+,R3 ;GET FLAG WORD .IFT BIT #EO$EXT,R3 ;22-BIT DEVICE? BNE 80$ ;IF NE YES BIT #EO$DMA,R3 ;DMA DEVICE? BEQ 90$ ;IF EQ NO ; ; INSERT THE TRANSFER OPERATION ADDRESS AND LENGTH ;  MOV R4,R3 ;COPY SCB ADDRESS ADD #,R3 ;POINT PAST PHYSICAL ADDRESS MOV -(R3),2(R0) ;INSERT LOW BITS OF ADDRESS MOVB -(R3),(R0)+ ;INSERT HIGH BITS OF ADDRESS CLRB (R0)+ ;FORGET ANY GARBAGE TST (R0)+ ;POINT PAST LOW BITS BR 100$ ; 80$: MOVB U.BUF+1(R5),(R0);ASSUME HIGH BITS ARE IN UCB MOV (R5),R1 ;GET DCB ADDRESS CMP D.NAM(R1),#"DL ;IS THIS THE RLV12? BNE 85$ ;IF NE NO MOV S.PKT(R4),R1 ;RETRIEVE I/O PACKET ADDRESS MOV I.PRM+6(R1),(R0);GET HIGH BITS OF ADDRESS 85$: BIC #^C<377>,(R0)+ ;CLEAR GARBAGE BR 95$ ; .ENDC 90$: MOV U.BUF(R5),(R0)+ ;MOVE IN THE RELOCATION BIAS 95$: MOV U.BUF+2(R5),(R0)+ ;MOVE IN THE BUFFER ADDRESS 100$: MOV U.CNT(R5),(R0)+ ;MOVE IN THE BYTE COUNT RETURN ;+ ; **-$QUPKT-QUEUE ERROR LOG PACKET ; ; THIS ROUTINE IS CALLED TO QUEUE AN ERROR LOG PACKET. IF THERE IS NO ; OTHER PACKET IN THE QUEUE, THE ERROR LOGGER IS REQUESTED WITH A DELAY. ; IF THERE IS ANOTHER PACKET ALREADY IN THE QUEUE, THE ERROR LOGGER IS ; REQUESTED IMMEDIATLY. ; ; INPUTS: ; ; R3=POINTER TO PACKET FOR INSERTION IN QUEUE ; ; OUTPUTS: ; ; R0, R1, R2 AND R3 ARE UPDATED ;- $QUPKT::SAVNR ;SAVE R5 AND R4 MOV R3,R1 ;COPY THE POINTER TO THE PACKET MOV $ERRPT,R5 ;SAVE FOR USE WHEN REQUESTING THE TASK BEQ 40$ ;IF EQ NO ERROR LOG TASK MOV #$ERHEA,R0 ;GET A POINTER TO THE QUEUE LIST HEAD CALL $QINSF ;INSERT THE ENTRY FIFO IN THE QUEUE CMP (R0)+,(R0) ;WAS LIST EMPTY? BNE 20$ ;IF NE NO, REQUEST ERRLOG BIT #SM.CMD,4+E$HSBF(R1) ;IS THIS A COMMAND PACKET? BNE 20$ ;IF NE YES ; ; THERE IS NO OTHER PACKET IN THE QUEUE, SO MAKE UP A DEFERRED REQUEST ; MOV #C.LGTH,R1 ;SIZE OF A CLOCK QUEUE ENTRY CALL $ALOCB ;ALLOCATE THE CORE BLOCK BCS 20$ ;IF CS FAILURE, TRY IMMEDIATE REQUEST CLR C.UIC(R0) ;INDICATE DEFAULT UIC CLR R1 ;HIGH TIME = 0 MOV #,R2 ;LOW TIME = 2 SECONDS MOV #C.SSHT,R4 ;SINGLE SHOT TASK REQUEST CALLR $CLINS ;INSERT THE ENTRY IN THE QUEUE ; ; THERE IS ANOTHER PACKET IN THE QUEUE, SO IMMEDIATLY REQUEST ; 20$: MOV R5,R0 ;COPY THE ERROR LOG TCB TST T.STAT(R0) ;IS IT ALREADY RUNNING? BPL 30$ ;IF PL YES, DON'T REQUEST IT CLR R1 ;INDICATE DEFAULT UIC CALLR $TSKRT ;REQUEST THE TASK ; ; THE ERROR LOG TASK IS ALREADY RUNNING, SO DISMISS THE REQUEST ; 30$: RETURN ;EXIT ; ; THE ERROR LOG TASK HAS BEEN REMOVED. DISCARD THE QUEUED ENTRY ; 40$: MOV R1,R0 ;COPY THE ERROR LOG PACKET POINTER MOV 2(R0),R1 ;GET THE SIZE OF THE PACKET ADD #4,R1 ;ACCOUNT FOR THE LINK WORD AND LENGTH CALLR $DEACB ;DEALLOCATE THE SPACE ;+ ; **-$QERMV-REMOVE ENTRY FROM ERROR LOG QUEUE ; ; THIS ROUTINE REMOVES AN ENTRY FROM THE ERROR LOG QUEUE AND TRANSFERS ; IT INTO A USER BUFFER. ; ; INPUTS: ; ; R4=LENGTH OF USER BUFFER ; R5=ADDRESS OF USER BUFFER ; ; OUTPUTS: ; ; R1=LENGTH OF PACKET ; R4=UNCHANGED ; R5=UNCHANGED ; ; C=0 PACKET WAS REMOVED SUCCESSFULLY ; C=1 NO PACKET TO REMOVE OR PACKET TOO LONG. IF R1<>0 THE ; PACKET WAS TOO LONG, AND R1 CONTAINS THE PACKET LENGTH. ;- $QERMV::CLR R1 ;SAY THE PACKET HAS A LENGTH OF ZERO MOV #$ERHEA,R0 ;GET THE QUEUE POINTER CALL $QRMVF ;REMOVE THE PACKET FROM THE QUEUE BCS 30$ ;IF CS NO SUCH PACKET MOV R5,R3 ;SAVE A COPY OF THE USER BUFFER ADDRESS MOV R1,R0 ;COPY THE CORE BLOCK ADDRESS TST (R1)+ ;IGNORE THE LINK WORD MOV (R1)+,R2 ;GET THE LENGTH OF THE PACKET CMP R2,R4 ;IS THE PACKET TOO LONG? BHI 20$ ;IF HI PACKET IS TOO LONG. ASR R2 ;CONVERT THE NUMBER OF BYTES TO WORDS 10$: MOV (R1)+,(R3)+ ;MOVE THE DATA ITEM SOB R2,10$ ;LOOP UNTIL DONE 20$: MOV 2(R0),R1 ;GET A COPY OF THE PACKET LENGTH MOV R3,-(SP) ;SAVE THE END USER BLOCK POINTER MOV R1,-(SP) ;SAVE THE PACKET LENGTH ADD #4,R1 ;ADD IN THE LINK AND LENGTH WORD CALL $DEACB ;AND DEALLOCATE THE BLOCK MOV (SP)+,R1 ;RESTORE THE PACKET LENGTH DEC (SP) ;ADJUST SO THAT IF: ; (SP)>R5 WE TRANSFERRED DATA ; (SP) 4K ON 22 BIT SYSTEMS ; ; C. H. FRANKS 21-OCT-81 ; ; CHF034 -- USE MTPS MACRO ; DA11-B INTERPROCESSOR COMMUNICATIONS DRIVER ; ; ***************************************************************************** ; ; KNOWN HACKS FOR THIS DEVICE ; ; 1) CYCLE BIT IS READ/WRITE INSTEAD OF WRITE ONLY. IT IS SET EVERY TIME ; A WORD IS TRANSFERED FROM ONE SYSTEM TO ANOTHER, AND THEREFORE ; ITS STATE AT ANY TIME IS INDETERMINATE. THEREFORE ALL "BIS" AND ; "BIC" INSTRUCTIONS ARE FORBIDDEN AS THEY CAN REWRITE THE CYCLE BIT ; INITIATING AN UNWANTED NPR CYCLE OR CYCLES. ; ; 2) BOTH SIDES CANNOT TRY TO TRANSMIT AT THE SAME TIME BECAUSE THIS ; DEVICE IS HALF DUPLEX ONLY. THEREFORE A DEVICE PROTOCOL MUST ; BE WRITEN INTO THE DRIVER TO ARBITRATE THE LINK. ; ; 3) THE DEVICE NPR LOGIC WILL NOT CROSS 32K WORD BOUNDRIES BECAUSE ; THE BUFFER REGISTER IS ONLY A 16 BIT COUNTER. WHEN A 32K WORD ; BOUNDARY IS CROSSED, THE MEMORY EXTENSION BITS MUST BE INCREMENTED ; FOR A RESTART. ALSO, DUE TO THE CYCLE REQUEST LOGIC, THE ; NEXT TRANSMIT WORD IS PLACED IN THE DATA BUFFER AND MUST BE ; REMOVED (VIA SOFTWARE) AND STORED IN THE RECEIVE DATA BUFFER ; BEFORE RESUMING THE TRANSFER. ; ; ; 4) ACCESSING THE CSR AFTER SETTING THE GO BIT MAY CAUSE THE ; DEVICE TO LOSE A CYCLE REQUEST AND THEREBY HALT NPR TRANSFERS ; WITHOUT SETTING DONE OR ERROR. RECOVERY IN THIS CASE IS ; BY TIMEOUT ALONE. ; ; ***************************************************************************** ; ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,HWDDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ;**-11 ; EQUATED SYMBOLS ; ; ; LOCAL DEFINITIONS ; DBGO= 1 ;SET TO START TRANSFERS (RCV) MDOUT= 2 ;OUTPUT MODE,1= WORD DROUT= 4 ;OUTPUT DIRECT,1= RCV INTENB= 100 ;INTERRUPT ENABLE IREQO= 10 ;SET TO REQ INTR IN COMPANION RDY= 200 ;INDICATES DEVICE READY CYCLE= 400 ;SET W/GO TO START XMIT XFER MDINP= 1000 ;INP MODE, 1= WORD DRINP= 2000 ;INP DIRECT 1= COMPANION IS RCV IREQN= 4000 ;INTR REQ FROM COMPANION NEX= 40000 ;NON EXISTENT MEMORY ERROR= 100000 ;=1 WHEN DEVICE ERROR DIS0= DROUT!MDOUT!IREQO!CYCLE ;RESTORE DB TO IDLE STATE ATTN= 20000 MBIT=60 ;MEMORY EXTENSION BIT POSITIONS BUMP=20 ;MEMORY EXTEN BIT INCREMENT ; ; UNIT IMPURE DATA TABLE ; CNTBL: ;REF LABEL UNITBL: .REPT D$$B11 .WORD 0 .ENDM .IF GT D$$B11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 .ENDC ; ; DEVICE DISPATCH TABLE ; $XBTBL::.WORD DBINIT ;DEVICE INITIATION ENTRY .WORD DBCANC ;I/O CANCELLATION ENTRY .WORD DBTMO ;DEVICE TIMEOUT ENTRY .WORD DBPWRF ;POWERFAIL ENTRY ;+ ;**- DBINIT - DA11-B PARALLEL COMMUNICATIONS LINK CONTROLLER I/O INITIATOR ; ; DBINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE NORMAL ; RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, THE ; REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS BUSY, ; AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF THE ; NATURE OF THE DA11-B, EACH UNIT IS A CONTROLLER ITSELF, HAS ; ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DBINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. ; ; INPUTS: ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED ; ; OUTPUTS: ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ; ;- .ENABL LSB DBINIT: ;REFERENCE LABEL CALL $GTPKT ;ANY WORK TO DO? ;**-13 BCC 20$ ;BR IF WORK TO DO XBRET: ;REFERENCE LABEL ;**-10 RETURN ;RETURN TO CALLER ;**-7 ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT ; ; R1= ADDRESS OF I/O REQUEST PACKET ; R2= PHYSICAL UNIT NUMBER OF THE REQUEST UCB ; R3= CONTROLLER INDEX ; R4= ADDRESS OF THE STATUS CONTROL BLOCK ; R5= ADDRESS OF THE UCB SPECIFIED IN THE DBINIT CALL ; ; DA11-B I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDR (REAL OF DISPLACEMENT + 140000) ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 MEMORY EXTENSION BITS FOR I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 NOT USED ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; 20$: MOV S.CSR(R4),R2 ;PUT CSR INTO R2 ADD #I.FCN+1,R1 ;R1 POINTS TO I/O FUNCTION CODE CMPB #IO.INL/256.,(R1) ;CONTROL FUNCTION? BLOS 40$ ;BR IF CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;DEVICE ONLINE? BEQ 50$ ;RETURN IE.DNR IF NOT ONLINE .IF DF M$$MGE&M$$EXT 25$: CALL $STMAP ;SET DEVICE'S UNIBUS ADDRESS ;**-5 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;AND R2 CALL $MPUBM ;SET UP 11/70 UNIBUS MAPPING MOV (SP)+,R2 ;RESTORE R2 AND R1 MOV (SP)+,R1 .ENDC CMPB #IO.RLB/256.,(R1) ;RECEIVE FUNCTION? BEQ 30$ ;BR IF RECEIVE FUNCTION ; FALL THROUGH ON TRANSMIT REQUEST CMP -(R2),-(R2) ;POINT TO WORD CNT REG ;**-7 CLR -(SP) ;INITIALIZE CSR, CLEAR C BIT MOV U.CNT(R5),-(SP) ;GET DATA COUNT IN BYTES ROR (SP) ;CONVERT TO WORD COUNT ADC (SP) ;ADJUST FOR ODD BYTE COUNT MOV (SP),6(R2) ;PASS COUNT IN DATA BUFFER NEG (SP) ;COUNT IN 2'S COMPLEMENT MOV (SP)+,(R2)+ ;LOAD COUNT MOV U.BUF+2(R5),(R2)+ ;LOAD ADDRESS MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT COUNT INCB U.CW3(R5) ;SET SENDER STATUS IN UCB .IF DF M$$MGE BIS U.BUF(R5),(SP) ;OR IN MEMORY EXTENSION BITS .ENDC BIS #IREQO!INTENB!DBGO,(SP) ;SETUP TO GO MOV (SP)+,(R2) ;START DEVICE RETURN ;INTERRUPTS PROPAGATE TRANSMIT ; RECEIVE FUNCTION INITIATION 30$: ;REFERENCE LABEL MOV R5,R0 ;R0 POINTS TO UCB ;**-3 ADD #U.RBUF,R0 ;R0 POINTS TO RCV BUF ADDR AREA MOV U.BUF(R5),(R0)+ ;TRANSFER BUFFER ADDR TO U.RBUF MOV U.BUF+2(R5),(R0)+ ; MOV U.CNT(R5),(R0) ;TRANSFER COUNT ROR (R0) ;CHANGE BYTE CONT TO WORD COUNT ADC (R0) ;ADJUST FOR ODD BYTE COUNT MOV #U3.RPD,U.CW3(R5) ;SET RECEIVE PENDING MOV #INTENB,(R2) ;ENABLE INTERRUPTS (CAUSING ONE) RETURN ;RETURN, INTERRUPT PROPAGATES RX ; REQUEST WAS CONTROL FUNCTION ;**-8 40$: BNE SUCC ;CHANGE MODE IS NO-OP TSTB -(R1) BNE 60$ ;BR IF FUNCTION WAS TERMINATE ; INITIALIZE DEVICE FUNCTION MOV R5,UNITBL(R3) ;PUT UCB ADDR INTO TABLE CLR (R2) ;CLEAR CSR REGISTER CLR -2(R2) ;CLEAR BUFFER ADDR REGISTER TST (R2) ;ERROR BIT SET? BMI 50$ ;BR IF MODULE NOT IN PLACE BIS #U2.ONL,U.CW2(R5) ;MARK DEVICE ONLINE ;**-3 BR 70$ ;COMPLETE SUCCESSFUL I/O ;**-7 ; SIGNAL DEVICE NOT READY 50$: MOV #IE.DNR&377,R0 ;SIGNAL DEVICE NOT READY BR UNSUCC ;COMPLETE UNSUCCESSFUL I/O ; FUNCTION WAS TERMINATE 60$: CLR UNITBL(R3) ;REMOVE UCB ADDR FROM TABLE BIC #U2.ONL,U.CW2(R5) ;MARK DEVICE OFFLINE CLR (R2) ;CLEAR CSR REGISTER 70$: CLR U.CW3(R5) ;CLEAR DEVICE STATUS IN UCB CLR 2(R2) ;CLEAR DATA BUFFER REGISTER CLR -(R2) ;CLEAR ADDRESS REGISTER CLR -(R2) ;CLEAR WORD COUNT REGISTER SUCC: MOV #IS.SUC&377,R0 ;SUCCESSFUL COMPLETION ENTRY UNSUCC: CLRB S.STS(R4) ;IDLE CONTROLLER BICB #US.BSY,U.STS(R5) ;MARK UNIT IDLE MOV R0,-(SP) ;SAVE STATUS WORD ONE MOV S.PKT(R4),-(SP) ;SAVE OLD PACKET ADDR ; TM001 .IF DF,M$$MGE&M$$EXT ; TM001 MOV R4,R2 ;COPY SCB POINTER ; TM001 ADD #S.MPR,R2 ;POINT TO MAPPING ASSIGNMENT BLK ; TM001 CALL $DEUMR ;DEASSIGN ANY UMR'S ; TM001 .ENDC ; TM001 CALL DBINIT ;TRY TO ACTIVATE NEXT REQUEST MOV (SP)+,R3 ;GET OLD I/O PACKET MOV I.PRM+4(R3),R1 ;RETURN REQUESTED ITEM COUNT MOV (SP)+,R0 ;GET STATUS WORD 1 CALLR $IOFIN ;TERMINATE OLD PACKET .DSABL LSB ; ; DEVICE TIMEOUT ENTRY ; ; THIS CODE IS ENTERED WHEN THE TRANSMIT TIMEOUT COUNT GOES TO ZERO. ; DBTMO: ;;;REFERENCE LABEL CLR U.CW3(R5) ;;;CLEAR DEVICE STATUS ;**-10 CLR @S.CSR(R4) ;;;DISABLE DEVICE MTPS #0 ;;; ENABLE INTERRUPTS ; CHF034 BR UNSUCC ;FINISH UNSUCCESSFUL ;**-1 ; DEVICE CANCELLATION AND POWERFAIL ENTRYS ; ; FOR NETWORKS CANCELLATION AND POWERFAIL ARE NO-OPED AND THE ; TRANSMIT EITHER COMPLETES OR TIMES OUT. IT IS THEN FINISHED ; IN THE NORMAL MANNER. ; FOR NON-NETWORKS, THE DEVICE IS DISABLED AND A TIMEOUT FORCED SO ; THAT THE PACKET IS FINISHED BY DBTMO, AVOIDING ANY RACE CONDITIONS ; ARISING FROM I/O TERMINATION. ; .ENABL LSB ;**-8 DBCANC: CMP I.TCB(R0),R1 ;;;I/O FOR THIS TASK? BNE 5$ ;;;RETURN IF NOT TSTB U.CW3(R5) ;;;TRANSFER IN PROGRESS? BNE 5$ ;;;LET FINISH IF YES MOV #IE.ABO&377,R0 ;;;RETURN ABORT STATUS BR DBTMO ;;;FINISH AS TIMEOUT DBPWRF: MOVB #2,S.CTM(R4) ;;;FORCE TIMEOUT 5$: RETURN ;;;RETURN TO CALLER .DSABL LSB ; ;**-3 ; DA11-B INTERRUPT ROUTINE ; .ENABL LSB $XBINT:: ;;;REFERENCE LABEL INTSV$ XB,PR5,D$$B11 ;;;GENERATE INTERRUPT SAVE CODE CALL DBSET ;;;PUT CSR ADDRESS IN R4 TSTB (R4) ;;;DEVICE READY? BMI 5$ ;;;CONTINUE IF YES RETURN ;;;EXIT INTERRUPT IF NOT 5$: TSTB U.CW3(R5) ;;;TX OR RCV ACTIVE BEQ NOTHNG ;;;BR IF NOTHING ACTIVE BMI 10$ ;;;BR IF RECEIVE ACTIVE ; AM CURRENTLY TRYING TO TRANSMIT, CHECK FOR SUCCESSFUL COMPLETION BIT #IREQN,(R4) ;;;HE INTERRUPTING ME? BEQ 10$ ;;;CHECK ON IF NOT BIT #MDINP,(R4) ;;;DOES HE WANT ME TO FLUSH TX? BNE IEVER ;;;RETURN ERROR IF YES ; AM CURRENTLY RECEIVING, CHECK FOR SUCESSFUL COMLETION 10$: TST (R4) ;;;ERROR BIT SET? BPL 20$ ;;;CHECK ON IF NOT JMP ERR ;;;CHECK ON ERROR 20$: TST -4(R4) ;;;ALL DATA TRANSFERRED? BEQ SUCDN ;;;RETURN GOOD STAUTS IF YES IEVER: MOV #IE.VER&377,-(SP) ;;;UNRECOVERABLE ERROR FINISH BR INTDN ;;;FINISH I/O SUCDN: ;;;SUCCESSFUL COMPLETION MOV #IS.SUC&377,-(SP) ;;;RETURN SUCESSFUL STATUS ;**-7 INTDN: ;;;REFERENCE LABEL ;**-3 CLR (R4) ;;;DISABLE DEVICE ;**-3 MOV (SP)+,R4 ;;;SAVE STATUS IN R4 CALL $FORK ;;;GO TO FORK LEVEL CLR U.CW3(R5) ;SAY DEVICE NOT ACTIVE MOV R4,R0 ;RETURN STATUS IN R0 MOV U.SCB(R5),R4 ;GET SCB ADDR FOR I/O DONE CALLR UNSUCC ;FINISH I/O NOTHNG: BIT #IREQN,(R4) ;;;DID HE INTERRUPT ME? ;**-80 BEQ EXIT ;;;EXIT IF NOT BIT #MDINP!ERROR,(R4) ;;;ERROR OR FLUSH TX SET? BNE EXIT ;;;EXIT IF YES TSTB U.CW3+1(R5) ;;;IS A RECEIVE PENDING? BEQ EXIT ;;;EXIT IF NOT CMP 2(R4),U.RCNT(R5) ;;;TX COUNT = RECV COUNT/ ;**-3 BNE VER ;;;RETURN ERR IF NOT CMP -(R4),-(R4) ;;;XFER REQUEST, SET UP TO GO ;**-8 MOV U.RCNT(R5),(R4) ;;;GET RECEIVE COUNT NEG (R4)+ ;;;COUNT IN 2'S COMPLEMENT MOV U.RBUF+2(R5),(R4)+ ;;;ADDR INTO BUFFER ADDR REG BIS #U3.RAC,U.CW3(R5) ;;;SET RECEIVE ACTIVE IN UCB MOV #DROUT!DBGO!INTENB,-(SP) ;;;SETUP TO GO .IF DF M$$MGE BIS U.RBUF(R5),(SP) ;;;OR IN MEMORY EXENSION BITS .ENDC MOV (SP)+,(R4) ;;;ENABLE DEVICE EXIT: RETURN ;;;WAIT FOR XFER TO FINISH  .DSABL LSB .ENABL LSB ERR: BIT #NEX,(R4) ;;;NON EXISTENT MEMORY ERROR? BNE 20$ ;;;BR IF YES BIT #ATTN,(R4) ;;;POSSIBLE INIT ON OTHER SYSTEM? BNE 30$ ;;;BR IF YES CLR -2(R4) ;;;REMOVE POSSIBLE OVERFLOW TST (R4) ;;;ERROR STILL SET? BMI 30$ ;;;BR IF YES .IF DF M$$MGE MOV #DBGO!INTENB!CYCLE,-(SP) ;;;SETUP FOR TRANSMIT CONTINUE MOV (R4),-(SP) ;;;COPY CURRENT CSR BITS BIC #^CMBIT,(SP) ;;;CLEAR ALL BUT EXTENSION BITS ADD #BUMP,(SP) ;;;INCREMENT MEMORY EXTENSION BITS BIS (SP),2(SP) ;;;OR IN EXTENSION BITS TSTB U.CW3(R5) ;;;WAS I TRANSMITTING? BPL 10$ ;;;BR IF YES SWAB (SP) ;;;PUT MEMORY EXTENSION BITS ;**-14 ASR (SP) ;;;IN POSITIONS 10 & 11 ASR (SP) MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV 2(SP),KISAR6 ;;;SET NEW MAPPING MOV 2(R4),@#140000 ;;;PUT CHAR INTO USER'S BUFFER MOV (SP)+,KISAR6 ;;;RESTORE MAPPING CMP -(R4),-(R4) ;;;POINT TO WORD CNT REG INC (R4)+ ;;;INCR COUNT ADD #2,(R4)+ ;;;INCR BUFFER ADDRESS REG BIC #CYCLE,2(SP) ;;;CLR CYCLE FOR RECEIVE BIS #DROUT,2(SP) ;;;SET RECEIVE DIRECTION 10$: TST -4(R4) ;;;I/O FINISHED? BNE 15$ ;;;BRANCH IF NOT CMP (SP)+,(SP)+ ;;;YES--CLEAN STACK JMP SUCDN ;;;FINISH SUCCESSFULLY 15$: TST (SP)+ ;;;CLEAN STACK ;**-3 MOV (SP)+,(R4) ;;;START UP DEVICE .ENDC BR DBEXIT ;;;EXIT FROM INTERRUPT VER: ;;;REFERENCE LABEL 20$: JMP IEVER ;;;RETURN UNRECOVERABLE ERROR 30$: MOV #IE.DNR&377,-(SP) ;;;SIGNAL DEVICE NOT READY 40$: JMP INTDN ;;;FINISÈH I/O .DSABL LSB DBSET: ;;;REFERENCE LABEL TST R5 ;;;CHECK FOR VALID UCB ADDRESS BEQ 10$ ;;;BR IF NO UCB IN TABLE BIT #U2.ONL,U.CW2(R5) ;;;DEVICE ONLINE? BEQ 10$ ;;;IGNORE INTERRUPT IF OFFLINE MOV U.SCB(R5),R4 ;;;GET SCB ADDR IN R4 MOV S.CSR(R4),R4 ;;;PUT CSR ADDR INTO R4 RETURN ;;;RETURN TO CALLER 10$: TST (SP)+ ;;;CLEAR STACK OF RETURN ADDR DBEXIT: JMP $INTXT ;;;EXIT FROM INTERRUPT .END ;**-59 È»z ™kQ ›c, .TITLE SYSXT .IDENT /12.49/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 12.49 ; ; D. N. CUTLER 10-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; P. WANNHEDEN ; CHUCK SPITZ ; B. S. MCCARTHY ; ; MODIFIED BY: ; ; M. S. HARVEY 19-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 28-AUG-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 10-SEP-79 ; MSH061 -- CORRECT MISLEADING COMMENTS ; ; M. S. HARVEY 9-OCT-79 ; MSH069 -- ADD STOP FOR GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 8-APR-80 ; MSH091 -- CLEANUP AND GENERALIZE KERNEL AST HANDLING. ; ADD GENERAL BUFFERED I/O SUPPORT. ; ; M. S. HARVEY 9-APR-80 ; MSH088 -- CLEAN UP $SGFIN ; ; MSH092 -- DO NOT USE ILLEGAL INSTRUCTION IN $FINXT ; ; M. S. HARVEY 28-APR-80 ; MSH096 -- SUPPORT ALTERNATE HEADER REFRESH AREAS ; ; M. S. HARVEY 20-AUG-80 ; MSH112 -- MODIFY $SGFIN TO REFER TO $TRINT ; ; M. S. HARVEY 12-SEP-80 ; MSH115 -- CLEAN UP GROUP GLOBAL USE FOR ABORTED TASKS ; ; M. S. HARVEY 6-OCT-80 ; MSH121 -- ADD SUPPORT FOR REQUESTED EXIT ASTS ; ; M. S. HARVEY 13-NOV-80 ; MSH126 -- DO NOT QUEUE EXIT STATUS AST ON SYSTEMS ; WITHOUT AST SUPPORT ; ; MSH127 -- CLEAN UP CACHE MEMORY CONDITIONALIZATION ; ; M. S. HARVEY 25-NOV-80 ; MSH129 -- ALLOW FULL USE OF EXIT STATUS BLOCK ; ; M. S. HARVEY 19-DEC-80 ; MSH132 -- ENSURE KISAR5 MAPPING OF CONNECT-TO-INTERRUPT ; FORK BLOCKS AND REMOVE UNNECESSARY CODE ; ; M. S. HARVEY 23-DEC-80 ; MSH134 -- PREVENT UNDEFINED VARIABLE INTERRUPTS WHEN ; RESTORING FLOATING POINT CONTEXT ; ; M. S. HARVEY 8-JAN-81 ; MSH140 -- NO NEED TO MAP FLOATING POINT SAVE AREA FOR ; EMULATOR TASKS ; ; DAN BROWN 8-JAN-81 ; DTB011 -- MODIFY FOR NEW ERROR LOGGING SYSTEM ; ; M. S. FOX 06-FEB-81 ; MF208 -- SUPPORT COMMAND ARRIVAL ASTS FOR CLIS ; ; M. S. HARVEY 12-FEB-81 ; MSH149 -- ADD FLOATING POINT TRANSPORTABILITY ; ; M. S. HARVEY 11-JUN-81 ; MSH175 -- ADD SUPPORT FOR ANCILLARY CONTROL DRIVER ; ; M. S. HARVEY 15-JUL-81 ; MSH178 -- DO NOT IGNORE LOADER IF REQUESTED AS A ; RESULT OF STOPPING A TASK DURING THE ; SCHEDULER'S TASK SCAN ; ; M. S. HARVEY 29-JUL-81 ; MSH183 -- ADD GROUP GLOBAL RUNDOWN KERNEL AST ROUTINE ; ; M. S. HARVEY 22-SEP-81 ; MSH172 -- STOPFOR STATE CANNOT EXIST IN AST STATE ; ; M. S. HARVEY 3-NOV-81 ; MSH199 -- $FINBF MUST EXIST ON SYSTEMS SUPPORTING ; ASYNCHRONOUS BUFFERED I/O ; ; ; SYSTEM ENTRANCE, EXIT, AND PROCESSOR DISPATCHING ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HDRDF$,HWDDF$,PCBDF$,TCBDF$ .MCALL ITBDF$,DCBDF$ ABODF$ ;DEFINE TASK ABORT CODES HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS  ITBDF$ ;DEFINE INTERRUPT TRANSFER BLOCK OFFSETS DCBDF$ ;DEFINE DEVICE CONTROL BLOCK OFFSETS ; ;MSH091 ; LOCAL MACROS ;MSH091 ; ;MSH091 ;MSH091 ; THIS MACRO GENERATES ENTRIES IN THE KERNEL AST DISPATCHING TABLE. ;MSH091 ; THE FORMAT OF THE MACRO IS: ;MSH091 ; ;MSH091 ; KAST SYM,COND ;MSH091 ; ;MSH091 ; WHERE- SYM IS THE ADDRESS OF THE KERNEL AST PROCESSING ;MSH091 ; ROUTINE ;MSH091 ; ;MSH091 ; COND IS THE CONDITIONAL THAT MUST BE DEFINED ;MSH091 ; IF THE KERNEL AST ROUTINE SPECIFIED IN SYM ;MSH091 ; IS TO BE DEFINED ;MSH091 ; ;MSH091 ; IF COND IS UNDEFINED, AN ENTRY IN THE DISPATCH TABLE IS CREATED ;MSH091 ; THAT WILL CAUSE A SYSTEM CRASH SHOULD THE UNDEFINED KERNEL AST ;MSH091 ; TYPE BE ENCOUNTERED. ;MSH091 ; ;MSH091 ;MSH091 .MACRO KAST,SYM,COND ;MSH091 ;MSH091 .IF DF 'COND' ;MSH091 ;MSH091 .WORD SYM ;KERNEL AST PROCESSING ROUTINE ;MSH091 ;MSH091 .IFF ;'COND' ;MSH091 ;MSH091 .WORD CRSH ;CRASH - ILLEGAL KERNEL AST FOR SYSTEM ;MSH091 ;MSH091 .ENDC ;'COND' ;MSH091 ;MSH091 .ENDM ;MSH091 ;MSH091 ;+ ; **-$DIRSV-DIRECTIVE SAVE ; ; THIS ROUTINE IS CALLED FROM DIRECTIVE LEVEL TRAP SERVICE ROUTINES. THE ; STACK DEPTH IS +1, THUS A SWITCH TO THE SYSTEM STACK IS ALWAYS NEC- ; ESSARY. AT THE END OF TRAP PROCESSING A RETURN IS EXECUTED TO EXIT ; FROM THE SYSTEM. ; ; INPUTS: ; ; 4(SP)=PS WORD PUSHED BY TRAP. ; 2(SP)=PC WORD PUSHED BY TRAP. ; 0(SP)=SAVED R5 PUSHED BY 'JSR R5,$DIRSV'. ; ; OUTPUTS: ; ; REGISTER R4 IS PUSHED ONTO THE CURRENT STACK AND THEN A SWITCH ; TO THE SYSTEM STACK IS EXECUTED. REGISTERS R3 THRU R0 ARE ; PUSHED ON THE SYSTEM STACK, THE NEW PROCESSOR PRIORITY IS ; SET, AND A CALL TO THE CALLER IS EXECUTED. ;- $DIRSV::MOV R4,-(SP) ;;;SAVE REGISTER R4 DEC $STKDP ;;;SET PROPER STACK DEPTH BNE 10$ ;;;IF NE DON'T SWITCH STACKS MOV SP,@$HEADR ;;;SAVE CURRENT STACK POINTER .IF NDF M$$MGE MOV #$STACK,SP ;;;LOAD SYSTEM STACK POINTER .ENDC 10$: MTPS #0 ;;;ALLOW INTERRUPTS MOV R3,-(SP) ;SAVE REGISTERS R3 THRU R0 MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; CALL (R5) ;CALL SYNCHRONOUS TRAP ROUTINE BR $DIRXT ;EXIT FROM TRAP ;+ ; **-$FORK-FORK AND CREATE SYSTEM PROCESS ; ; THIS ROUTINE IS CALLED FROM AN I/O DRIVER TO CREATE A SYSTEM PROCESS THAT ; WILL RETURN TO THE DRIVER AT STACK DEPTH ZERO TO FINISH PROCESSING. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB FOR THE UNIT BEING PROCESSED. ; ; OUTPUTS: ; ; REGISTERS R5 AND R4 ARE SAVED IN THE CONTROLLER FORK BLOCK AND ; A SYSTEM PROCESS IS CREATED. THE PROCESS IS LINKED TO THE FORK ; QUEUE AND A JUMP TO $INTXT IS EXECUTED. ;- $FORK:: MOV R4,-(SP) ;SAVE REGISTER R4 MOV U.SCB(R5),R4 ;POINT TO CONTROLLER STATUS BLOCK CLRB S.CTM(R4) ;DISABLE TIMEOUT ADD #S.FRK+6,R4 ;POINT TO END OF FORK BLOCK MOV (SP)+,(R4) ;PUT SAVED R4 IN FORK BLOCK ;+  ; **-$FORK1-FORK AND CREATE SYSTEM PROCESS ; ; THIS ROUTINE IS AN ALTERNATE ENTRY TO CREATE A SYSTEM PROCESS AND ; SAVE REGISTER R5. ; ; INPUTS: ; ; R4=ADDRESS OF THE LAST WORD OF A 3 WORD FORK BLOCK PLUS 2. ; R5=REGISTER TO BE SAVED IN THE FORK BLOCK. ; ; OUTPUTS: ; ; REGISTER R5 IS SAVED IN THE SPECIFIED FORK BLOCK AND A SYSTEM ; PROCESS IS CREATED. THE PROCESS IS LINKED TO THE FORK QUEUE ; AND A JUMP TO $INTXT IS EXECUTED. ;- $FORK1::MOV R5,-(R4) ;SAVE REGISTER R5 ;+ ; **-$FORK0-FORK AND CREATE SYSTEM PROCESS ; ; THIS ROUTINE IS AN ALTERNATE ENTRY TO CREATE A SYSTEM PROCESS. ; ; INPUTS: ; ; R4=ADDRESS OF THE LAST WORD OF A 2 WORD FORK BLOCK PLUS 2. ; ; OUTPUTS: ; ; A SYSTEM PROCESS IS CREATED, LINKED TO THE FORK QUEUE AND A ; JUMP TO $INTXT IS EXECUTED. ;- $FORK0::MOV (SP)+,-(R4) ;SET FORK PC CLR -(R4) ;CLEAR LINK TO NEXT FORK BLOCK MFPS -(SP) ;SAVE CURRENT PROCESSOR PRIORITY MTPS #PR7 ;;;LOCK OUT INTERRUPTS MOV R4,@$FRKHD+2 ;;;LINK NEW ENTRY TO OLD LAST MOV R4,$FRKHD+2 ;;;SET ADDRESS OF NEW LAST MTPS (SP)+ ;;;RESTORE PROCESSOR PRIORITY ASRB $IDLFL ;INTERRUPT OF IDLE LOOP? BCC $INTXT ;IF CC NO .IF DF M$$MGE MOV #$DIRXT,$STACK-24 ;FORCE DEQUEUE FROM FORK LIST .IFF MOV #$DIRXT,$STACK-14 ;FORCE DEQUEUE FROM FORK LIST .ENDC .IF DF C$$INT RETURN ; ;+ ; **-$FORK2-FORK ROUTINE FOR USE IN CONJUNCTION WITH ; THE CINT$ DIRECTIVE. ; ; INPUT: ; R5 POINTING TO FORK BLOCK IN ITB ; ; OUTPUT: ; IF THE FORK BLOCK IS NOT ALREADY IN USE (FORK PC ZERO), ;MSH061 ; A SYSTEM PROCESS IS CREATED, LINKED TO THE FORK QUEUE AND A ;**-1 ; JUMP TO $INTXT IS EXECUTED. ; ELSE THE INTERRUPT IS DISMISSED (NO RETURN TO CALLER). ; ; IMMEDIATELY ON RETURN FROM THIS ROUTINE, THE FOLLOWING ; INSTRUCTION SHOULD BE EXECUTED: ; ; CLR @R3 ; ; WHICH DECLARES THE FORK BLOCK FREE. ;- $FORK2::TST 2(R5) ;;;FORK BLOCK ALREADY IN USE? BNE 10$ ;;;Y - JUMP MOV R4,6(R5) ;;;SAVE R4 IN FORK BLOCK MOV R5,R4 ;;; ADD #6,R4 ;;;POINT JUST AFTER 3-WORD FORK BLOCK BR $FORK1 ;;; 10$: TST (SP)+ ;;;CLEAR STACK ;;;FALL THRU TO $INTXT .ENDC ;+ ; **-$INTXT-INTERRUPT EXIT ; ; THIS ROUTINE MAY BE CALLED VIA A JMP TO EXIT FROM AN INTERRUPT. ; ; INPUTS: ; ; 0(SP)=INTERRUPT SAVE RETURN ADDRESS. ; ; OUTPUTS: ; ; A RETURN TO INTERRUPT SAVE IS EXECUTED. ;- $INTXT::RETURN ; ;+ ; **-$INTSC-INTERRUPT SAVE (INTERRUPT FROM VECTOR CONNECTED ; TO VIA CINT$ DIRECTIVE). ; ; CALLS ISR WITH R4 AND R5 SAVED AND: ; ; R5 POINTER TO FORK BLOCK IN ITB ; PRI TAKEN FROM ITB ; CONDITION CODES TAKEN FROM ITB ;- .IF DF C$$INT $INTSC::MOV R4,-(SP) ;;;SAVE R4 DEC $STKDP ;;;SWITCH STACKS? BNE 10$ ;;;N - JUMP MOV SP,@$HEADR ;;;Y - SAVE STACK POINTER .IF NDF M$$MGE MOV #$STACK,SP ;;;LOAD SYSTEM STACK POINTER .IFTF 10$: ;;;REF LABEL .IFF MOV KISAR5,-(SP) ;;;SAVE KERNEL APR 5 MOV X.REL-X.PSW(R5),KISAR5 ;;;MAP ISR IN KERNEL APR5 .ENDC $INTS2: MTPS (R5)+ ;;;LOAD ISR PRIORITY INC R5 ;;;SKIP OVER UNUSED BYTE CALL @(R5)+ ;;;CALL ISR .IF DF M$$MGE MOV (SP)+,KISAR5 ;;;RESTORE KERNEL APR 5 .ENDC BR $INTX1 ;;;EXIT FROM INTERRUPT .ENDC ;+ ; **-$INTSE-INTERRUPT SAVE (ERROR LOGGING DEVICES) ; ; THIS ROUTINE IS CALLED FROM AN INTERRUPT SERVICE ROUTINE WHEN AN ; INTERRUPT IS NOT GOING TO BE IMMEDIATELY DISMISSED. REGISTER R4 IS ; SAVED AND THEN LOADED WITH THE ADDRESS OF THE SCB OF THE CONTROLLER ; THAT CAUSED THE INTERRUPT. A CHECK IS THEN MADE TO SEE IF AN ERROR IS ; ALREADY IN PROGRESS. IF IT IS NOT, THEN THE CURRENT I/O ACTIVE BITMAP ; IS SAVED IN THE SCB. THE APPROPRIATE BIT IS THEN CLEARED IN THE ACTIVE ; BITMAP AND REGISTER R4 IS LOADED WITH THE CONTROLLER INDEX. A NORMAL ; INTERRUPT SAVE IS THEN EXECUTED. ; ; INPUTS: ; ; 4(SP)=PS WORD PUSHED BY INTERRUPT. ; 2(SP)=PC WORD PUSHED BY INTERRUPT. ; 0(SP)=SAVED R5 PUSHED BY 'JSR R5,$INTSE'. ; 0(R5)=ADDRESS OF THE SCB OF INTERRUPTING CONTROLLER. ; 2(R5)=NEW PROCESSOR PRIORITY. ; ; OUTPUTS: ; ; REGISTER R4 IS PUSHED ONTO THE CURRENT STACK AND THEN LOADED ; WITH THE ADDRESS OF THE SCB OF THE CONTROLLER THAT CAUSED THE ; INTERRUPT. IF AN ERROR IS NOT IN PROGRESS, THEN THE I/O ACTIVE ; BITMAP IS SAVE IN THE SCB. THE APPROPRIATE BIT IS CLEARED IN THE ; ACTIVE BITMAP AND REGISTER R4 IS LOADED WITH THE CONTROLLER ; INDEX. ;- .ENABL LSB $INTSE::MOV R4,-(SP) ;;;SAVE REGISTER R4 MOV (R5)+,R4 ;;;GET ADDRESS OF SCB MOVB S.CON(R4),R4 ;;;GET CONTROLLER INDEX ;**-12 BR 2$ ;;;FINISH IN COMMON CODE  ;+ ; **-$INTSV-INTERRUPT SAVE ; ; THIS ROUTINE IS CALLED FROM AN INTERRUPT SERVICE ROUTINE WHEN AN ; INTERRUPT IS NOT GOING TO BE IMMEDIATELY DISMISSED. A SWITCH TO ; THE SYSTEM STACK IS EXECUTED IF THE CURRENT STACK DEPTH IS +1. WHEN ; THE INTERRUPT SERVICE ROUTINE FINISHES ITS PROCESSING, IT EITHER FORKS ; , JUMPS TO $INTXT, OR EXECUTES A RETURN. ; ; INPUTS: ; ; 4(SP)=PS WORD PUSHED BY INTERRUPT. ; 2(SP)=PC WORD PUSHED BY INTERRUPT. ; 0(SP)=SAVED R5 PUSHED BY 'JSR R5,$INTSV'. ; 0(R5)=NEW PROCESSOR PRIORITY. ; ; OUTPUTS: ; ; REGISTER R4 IS PUSHED ONTO THE CURRENT STACK AND THE CURRENT ; STACK DEPTH IS DECREMENTED. IF THE RESULT IS ZERO, THEN ; A SWITCH TO THE SYSTEM STACK IS EXECUTED. THE NEW PROCESSOR ; STATUS IS SET AND A CO-ROUTINE CALL TO THE CALLER IS EXECUTED ;- $INTSV::MOV R4,-(SP) ;;;SAVE REGISTER R4 2$: DEC $STKDP ;;;SWITCH STACKS? BNE 3$ ;;;IF NE NO MOV SP,@$HEADR ;;;SAVE CURRENT STACK POINTER .IF NDF M$$MGE MOV #$STACK,SP ;;;LOAD SYSTEM STACK POINTER  .ENDC .IF DF L$$SI1 3$: MTPS (R5) ;;;LOAD NEW PRIORITY CALL 2(R5) ;;;CALL THE CALLER BACK .IFF 3$: BIC (R5)+,PS ;;;LOAD NEW PRIORITY CALL (R5) ;;;CALL THE CALLER BACK .ENDC ;+ ; **-$INTXT-INTERRUPT EXIT ; ; THIS ROUTINE IS ENTERED VIA A RETURN TO EXIT FROM AN INTERRUPT. IF THE ; STACK DEPTH IS NOT EQUAL TO ZERO, THEN REGISTERS R4 AND R5 ARE ; RESTORED AND AN RTI IS EXECUTED. ELSE A CHECK IS MADE TO SEE ; IF THERE ARE ANY ENTRIES IN THE FORK QUEUE. IF NONE, THEN R4 AND  ; R5 ARE RESTORED AND AN RTI IS EXECUTED. ELSE REGISTERS R3 THRU ; R0 ARE SAVED ON THE CURRENT STACK AND A DIRECTIVE EXIT IS EXECUTED. ; ; INPUTS: (MAPPED SYSTEM) ; ; 06(SP)=PS WORD PUSHED BY INTERRUPT. ; 04(SP)=PC WORD PUSHED BY INTERRUPT. ; 02(SP)=SAVED R5. ; 00(SP)=SAVED R4. ; ; INPUTS: (REAL MEMORY SYSTEM) ; ; NONE. ;- $INTX1::MTPS #PR7 ;;;LOCK OUT INTERRUPTS TST $STKDP ;;;STACK DEPTH ZERO? BNE 10$ ;;;IF NE NO TST $FRKHD ;;;ANYTHING IN FORK QUEUE? BEQ 5$ ;;;IF EQ NO MTPS #0 ;;;ALLOW INTERRUPTS MOV R3,-(SP) ;SAVE REGISTERS R3 THRU R0 MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; ;+ ; **-$DIRXT-DIRECTIVE EXIT ; ; THIS ROUTINE IS CALLED VIA A JUMP TO EXIT FROM A DIRECTIVE OR TRAP ; SERVICE ROUTINE. IF THERE ARE ANY ENTRIES IN THE FORK QUEUE, THEN ; THE FIRST ENTRY IS REMOVED AND THE FORK ROUTINE IS EXECUTED. ELSE ; A CHECK IS MADE TO SEE IF REDISPATCHING OF THE PROCESSOR IS NECES- ; SARY. IF NOT, THEN REGISTERS R0 THRU R5 ARE RESTORED AND AN RTI ; IS EXECUTED. ELSE THE PROCESSOR IS REDISPATCHED AND THE EXIT ; SEQUENCE IS EXECUTED AGAIN. ; ; INPUTS: (MAPPED SYSTEM) ; ; 16(SP)=PS WORD PUSHED BY INTERRUPT OR TRAP. ; 14(SP)=PC WORD PUSHED BY INTERRUPT OR TRAP. ; 12(SP)=SAVED R5. ; 10(SP)=SAVED R4. ; 06(SP)=SAVED R3. ; 04(SP)=SAVED R2. ; 02(SP)=SAVED R1. ; 00(SP)=SAVED R0. ; ; INPUTS: (REAL MEMORY (SYSTEM) ; ; 06(SP)=SAVED R3. ; 04(SP)=SAVED R2. ; 01(SP)=SAVED R1. ; 00(SP)=SAVED R0. ;- $DIRXT::MTPS #PR7 ;;;LOCK OUT INTERRUPTS MOV $FRKHD,R3 ;;;ANYTHING IN FORK QUEUE BNE 20$ ;;;IF NE YES TSTB $CXDBL ;;;IS CONTEXT SWITCHING DISABLED? BEQ 31$ ;;;IF EQ NO MOV $TKTCB,R5 ;;;PICK UP CURRECT TASK TCB TSTB T.ST2(R5) ;;;TASK EXITING? ;MSH061 BPL 4$ ;;;IF PL NO ;**-1 JMP TEXIT ;;;INITIATE TASK EXIT 31$: ;;;REF LABEL MOV $RQSCH,R5 ;;;SCHEDULING REQUESTED? BNE 40$ ;;;IF NE YES 4$: ;;;REF LABEL MOV (SP)+,R0 ;;;RESTORE REGISTERS R0 THRU R3 MOV (SP)+,R1 ;;; MOV (SP)+,R2 ;;; MOV (SP)+,R3 ;;; 5$: ;;;REF LABEL  .IF NDF M$$MGE MOV @$HEADR,SP ;;;RELOAD USER STACK POINTER .ENDC 10$: INC $STKDP ;;;INCREMENT STACK DEPTH MOV (SP)+,R4 ;;;RESTORE REGISTERS R4 AND R5 MOV (SP)+,R5 ;;; ;+ ; NONSENSE INTERRUPT ENTRY/EXIT ;- .IF NDF E$$LOG ;DTB011 ;**-1 ; ; IF ERROR LOGGING OF UNDEFINED INTERRUPTS IS NOT SUPPORTED, ; ALL UNUSED VECTORS POINT TO THE NONSENSE INTERRUPT ADDRESS. ; $NS0:: ; $NS1:: ; $NS2:: ; $NS3:: ; $NS4:: ; $NS5:: ; $NS6:: ; $NS7:: ; .ENDC $NONSI::RTI ;;; ; ; EXECUTE FORK ROUTINE ; ; FORK ROUTINES ARE ENTERED VIA A CALL WITH THE ARGUMENTS: ; ; R3=ADDRESS OF THE BEGINNING OF THE FORK BLOCK+2. ; R4=RESTORED FROM FORK BLOCK. ; R5=RESTORED FROM FORK BLOCK. ; 20$: MOV (R3),$FRKHD ;;;REMOVE ENTRY FROM FORK QUEUE BNE 30$ ;;;IF NE MORE ENTRIES MOV #$FRKHD,$FRKHD+2 ;;;RESET FORK QUEUE LISTHEAD 30$: MTPS #0 ;;;ALLOW INTERRUPTS ADD #10,R3 ;POINT PAST SAVED R4 .IF DF L$$DRV&M$$MGE!C$$INT&M$$MGE ;MSH132 ;**-1 MOV (R3),KISAR5 ;MAP DRIVER OR INTERRUPT SERVICE ROUTINE;MSH132 ;**-2 .ENDC ;MSH132 ;**-1 MOV -(R3),R4 ;RESTORE REGISTERS R4 AND R5 MOV -(R3),R5 ; CALL @-(R3) ;CALL FORK ROUTINE BR $DIRXT ;TRY EXIT AGAIN ;**-8 ; ; RESCHEDULING OR POWERFAIL ; 40$: MTPS #0 ;;;ALLOW INTERRUPTS TST $PWRFL ;POWER FAILURE? BEQ RESCH ;IF EQ NO CALL $POWER ;EXECUTE POWER RECOVERY ROUTINES DIRXT: BR $DIRXT ;TRY EXIT AGAIN .DSABL LSB ; ; RESCHEDULING REQUESTED ; .ENABL LSB RESCH: CLR $RQSCH ;CLEAR SCHEDULE REQUEST .IF NDF M$$MGE MOV $HEADR,R4 ;GET ADDRESS OF CURRENT HEADER BEQ 5$ ;IF EQ NO CURRENT TASK TST @H.GARD(R4) ;STACK OVERFLOW? BEQ 5$ ;IF EQ NO CLR @H.GARD(R4) ;CLEAR HEADER GUARD WORD MOV #S.CSST,R0 ;SET SST ABORT-BAD STACK CALL $ABCTK ;ABORT CURRENT TASK .ENDC 5$: MOV #T2.STP!T2.SPN!T2.WFR,R1 ;SET SUSPEND-WAITFOR MASK MOV #T2.WFR,R4 ;SET WAITFOR MASK 10$: MOV T.ST2(R5),R0 ;GET CONTENTS OF SECOND STATUS WORD ;MSH069 MOV T.STAT(R5),R2 ;TASK BLOCKED? ;MSH069 BNE 25$ ;IF NE YES ;MSH069 ;**-3 .IF DF K$$AST!A$$TRP ;MSH091 ;**-1 MOV T.ASTL(R5),R2 ;AST QUEUED? BEQ 20$ ;IF EQ NO BIT #T2.AST!T2.DST,R0 ;AST IN PROGRESS OR DISABLED? BEQ 70$ ;IF EQ NO ;MSH091 .IF DF K$$AST ;MSH091 ;MSH091 TSTB A.CBL(R2) ;KERNEL AST QUEUED? ;MSH091 BMI 70$ ;IF MI YES ;**-1 ;MSH091 .ENDC ;K$$AST ;MSH091 .IFTF 20$: BIT R1,R0 ;STOPPED, SUSPENDED OR IN WAITFOR? BEQ 60$ ;IF EQ NO BIT R4,R0 ;IN WAITFOR? BEQ 30$ ;IF EQ, NO ;MSH069 .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 .IFF ;MSH069 ;MSH069 MOV T.PCB(R5),R3 ;GET PCB ADDRESS OF TASK PARTITION MOV P.HDR(R3),R2 ;POINT TO TASK HEADER ;MSH069 .IFTF ;MSH069 ;MSH069 BIT #T2.ABO,R0 ;TASK MARKED FOR ABORT? ;MSH069 BNE 50$ ;IF NE YES, FINISH HIM OFF ;**-1 ;MSH069 .IFF ;MSH069 ;MSH069 BIT H.EFLM(R2),@H.EFLM+2(R2) ;WAITFOR SATISFIED? ;MSH069 .IFT ;MSH069 ;MSH069 BIT T.EFLM(R5),@T.EFLM+2(R5) ;WAITFOR SATISFIED? ;MSH069 ;MSH069 .IFTF ;MSH069 ;MSH069 BNE 50$ ;IF NE YES ;MSH046 .IFT ;MSH046 ;MSH046 BIT #T2.SEF,R0 ;TASK STOPPED FOR EVENT FLAG? ;MSH069 ;MSH046 .IF DF T$$BUF ;MSH046 ;MSH046 BNE 22$ ;IF NE YES ;MSH046 TSTB T.TIO(R5) ;OUTSTANDING BUFFERED I/O? ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 BEQ 30$ ;NO ;**-4 22$: BIT #T2.AST!T2.STP,R0 ;TASK ALREADY STOPPED OR AT AST? ;MSH046 BNE 30$ ;IF NE YES, DON'T STOP HIM. ;**-1 MOV R5,R0 ;COPY TCB ADDRESS ;MSH046 CALL $STPTK ;STOP THE TASK ;**-1 ;MSH178 .IF DF D$$ISK ;MSH178 ;MSH178 MOV $RQSCH,R1 ;WAS LOADER REQUESTED TO RUN? ;MSH178 BEQ 5$ ;IF EQ NO, OR CURRENTLY ABOVE LDR IN ATL;MSH178 MOV R1,R5 ;COPY LOADER'S TCB ;MSH178 BR RESCH ;RESTART ATL SCAN FROM LOADER'S POSITION;MSH178 ;MSH178 .IFF ;MSH178 ;MSH178 BR 5$ ;RESET REGISTERS AND GO AGAIN ;MSH178 .ENDC ;MSH178 .IFTF ;MSH069 ;MSH069 25$: ;MSH069 ;MSH069 .IFT ;MSH069 ;MSH069 BIC #TS.CKP!TS.OUT,R2 ;TASK BLOCKED BY CHECKPOINT BITS ONLY?;MSH069 BNE 30$ ;IF NE NO, CANNOT REQUEST THIS TASK ;MSH069 BIT #T2.AST!T2.STP,R0 ;TASK STOPPED OR IN WAITFOR STATE? ;MSH172 ;MSH172 .IF DF A$$TRP ;MSH172 ;MSH172 BMI 30$ ;IF MI, STOPFOR STATE IMPOSSIBLE ;MSH172 ;MSH172 .ENDC ;MSH172 ;MSH172 BEQ 30$ ;IF EQ, NO POINT IN UNSTOPPING ANYWAY ;MSH172 BIT #T2.SEF,R0 ;TASK STOPPED FOR EVENT FLAG? ;MSH069 ;MSH069 .IF DF T$$BUF ;MSH069 ;MSH069 BNE 27$ ;IF NE YES ;MSH069 TSTB T.TIO(R5) ;OUTSTANDING BUFFERED I/O? ;MSH069 BEQ 30$ ;IF EQ NO ;MSH172 BIT #T2.WFR,R0 ;TASK STOPPED FOR BUFFERED I/O? ;MSH172 ;MSH069 .ENDC ;MSH069 ;MSH069 BEQ 30$ ;IF EQ NO, DON'T UNSTOP TASK ;MSH069 27$: BIT T.EFLM(R5),@T.EFLM+2(R5) ;STOPFOR SATISFIED? ;MSH069 BEQ 30$ ;IF EQ NO, DON'T REQUEST TASK ;MSH069 MOV T.ACTL(R5),-(SP) ;GET ADDRESS OF NEXT TCB ;MSH069 MOV R5,R0 ;COPY TASK TCB ;MSH069 BIC #T2.STP*2!T2.STP,T.ST2(R0) ;UNSTOP TASK ;MSH069 CALL $EXRQS ;REQUEST TASK TO RUN ;MSH069 MOV (SP)+,R5 ;LOAD ADDRESS OF NEXT TCB ;MSH069 BR RESCH ;CONTINUE SCAN OF ATL ;MSH069 ;MSH069 .ENDC ;S$$TOP!T$$BUF ;MSH069 ;**-1 30$: MOV T.ACTL(R5),R5 ;GET ADDRESS OF NEXT TCB BNE 10$ ;IF NE OKAY ; ; EXECUTIVE IDLE LOOP ; ; THE EXECUTIVE IDLE LOOP IS ENTERED WHEN THERE ARE NO RUNNABLE TASKS. ; THE NULL TCB AT THE END OF THE TASK LIST IS ALWAYS GUARANTEED TO BE ; BLOCKED. TWO FLAGS ARE SET FOR OTHER EXECUTIVE ROUTINES IN THE IDLE ; LOOP. ; ; 1. THE ADDRESS OF THE NULL TCB (#$HEADR) IS SET INTO THE RESCHEDULE ; POINTER ($RQSCH) TO PREVENT $DIRXT FROM EVER RETURNING TO SYSTEM ; STATE WHILE THE EXEC IS IDLE. THIS FORCES EXECUTION BACK TO THE ; IDLE LOOP IN LIEU OF A REAL SCHEDULE REQUEST. ; ; 2. AN IDLE FLAG IS SET ($IDLFL) FOR THE FORK ROUTINES TO CAUSE THEM ; TO FORCE CONTROL BACK TO $DIRXT WHEN NECESSARY TO DEQUEUE A ; FORK. (IT IS IMPOSSIBLE FOR THE IDLE LOOP TO ALWAYS RETURN TO ; $DIRXT WHEN NECESSARY BECAUSE OF A WINDOW BETWEEN THE CHECK OF ; THE FORK LIST AND THE WAIT INSTRUCTION.) ; MOV #$HEADR,$RQSCH ;PREVENT $DIRXT RETURN TO USER STATE MOV #$IDLPT,R1 ;POINT TO IDLE PATTERN WORD CLRB $CURPR ;CLEAR CURRENT TASK PRIORITY 40$: ;REF LABEL .IF DF P$$P45 DECB $IDLCT ;TIME TO MOVE PATTERN? BGE 45$ ;IF GE NO MOVB #4,$IDLCT ;RESET COUNT ASLB (R1)+ ;MOVE PATTERN ($IDLPT) RORB (R1) ;($IDLPT+1) ADCB -(R1) ;($IDLPT) 45$: MOV (R1),R0 ;PUT IT WHERE IT CAN BE SEEN ($IDLPT) .ENDC INCB -(R1) ;INDICATE IN IDLE STATE ($IDLFL) TST $FRKHD ;FORK QUEUED SINCE LAST TIME IN $DIRXT? BNE 46$ ;IF NE YES WAIT ;WAIT FOR INTERRUPT CLRB (R1)+ ;RESET IDLE FLAG ($IDLFL) BR 40$ ; 46$: CLRB (R1) ;RESET IDLE FLAG ($IDLFL) BR DIRXT ;BR TO DEQUEUE FORK ($DIRXT) ; ; WAITFOR SATISFIED-CLEAR WAIT STATE ; 50$: ;REF LABEL .IF DF G$$EFN .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 MOV T.PCB(R5),R4 ;GET TASK'S PCB ADDRESS ;MSH069 MOV P.HDR(R4),R4 ;GET TASK'S HEADER ADDRESS ;MSH069 MOV T.EFLM+2(R5),R3 ;GET WAITFOR MASK ADDRESS ;MSH069  ;MSH069 .IFF ;MSH069 ;MSH069 MOV H.EFLM+2(R2),R3 ;GET WAITFOR MASK ADDRESS ;MSH069 MOV R2,R4 ;GET TASK'S HEADER ADDRESS ;MSH069 ;MSH069 .ENDC ;MSH069 ;MSH069 CALL $DEAGF ;DEACCESS GROUP GLOBAL EF'S .ENDC ;G$$EFN DEC T.ST2(R5) ;CLEAR WAITFOR STATE .IF DF S$$TOP!T$$BUF ;MSH046 ;**-1 BMI 60$ ;IF MI, AT AST STATE BIC #T2.SEF!T2.STP,T.ST2(R5) ;CLEAR STOPFOR STATE ;MSH046 ;MSH046 .ENDC ;S$$TOP!T$$BUF ;MSH046 ;**-3 ; ; RESTART OR CONTINUE A TASK ; 60$: ;REF LABEL .IFT CLR R4 ;SET FLAG TO SIGNIFY RESTART OF TASK .ENDC 70$: MOV #H.DSW,R0 ;POINT TO DIRECTIVE STATUS WORD MOVB T.PRI(R5),$CURPR ;SET CURRENT TASK PRIORITY MOV $HEADR,R3 ;GET ADDRESS OF CURRENT TASK HEADER BEQ 80$ ;IF EQ NO CURRENT TASK CMP R5,$TKTCB ;NEW TASK SAME AS CURRENT? BNE 73$ ;IF NE NO JMP 130$ ;NO CONTEXT SWITCH NECESSARY ; ; SAVE CONTEXT OF CURRENT TASK ; 73$: MOV H.GARD(R3),R2 ;POINT TO HEADER GUARD WORD MOV SP,R1 ;POINT TO SAVED R0 MOV (R1)+,-(R2) ;SAVE R0 MOV (R1)+,-(R2) ;SAVE R1 MOV (R1)+,-(R2) ;SAVE R2 MOV (R1)+,-(R2) ;SAVE R3 .IF DF M$$MGE MOV (R1)+,-(R2) ;SAVE R4 MOV (R1)+,-(R2) ;SAVE R5 MOV (R1)+,-(R2) ;SAVE PC MOV (R1),-(R2) ;SAVE PS MFPI SP ;GET USER STACK POINTER MOV (SP)+,(R3) ;SAVE USER STACK POINTER IN HEADER .IFF .IF DF E$$EAE MOV H.FPSA(R3),R2 ;POINT TO EAE SAVE AREA BEQ 75$ ;IF EQ TASK DOES NOT USE EAE MOV SC,(R2)+ ;SAVE EAE REGISTERS MOV AC,(R2)+ ; MOV MQ,(R2) ; .ENDC .IFTF 75$: MOV (R0),H.DSW(R3) ;SAVE DIRECTIVE STATUS WORD .IF DF F$$LPP MOV H.FPSA(R3),R2 ;POINT TO FLOATING POINT SAVE AREA BEQ 80$ ;IF EQ TASK DOES NOT USE FLOATING POINT TST $HFMSK ;FLOATING POINT PROCESSOR PRESENT? ;MSH149 BMI 80$ ;IF MI NO, DON'T SAVE FPP CONTEXT ;MSH149 .IF DF M$$MGE MOV $TKTCB,R3 ;GET TCB ADDRESS OF CURRENT TASK ;MSH140 .IF DF A$$HDR ;MSH140 ;MSH140  TSTB T.HDLN(R3) ;EMULATOR TASK? ;MSH140 BNE 78$ ;IF NE YES, SAVE AREA IN HEADER ;MSH140 ;MSH140 .ENDC ;MSH140 ;MSH140 MOV T.PCB(R3),R1 ;GET ADDRESS OF TASK PARTITION PCB MOV P.REL(R1),KISAR6 ;MAP TO TASK PARTITION .IF DF P$$LAS ADD T.OFF(R3),KISAR6 ;ADD IN OFFSET TO TASK IMAGE .ENDC 78$: ; ;MSH140 .ENDC STFPS (R2)+ ;SAVE FLOATING POINT STATUS SETD ;SET FLOATING DOUBLE MODE STD R0,(R2)+ ;SAVE FIRST FL. POINT ACCUMULATOR (FACC);MSH134 LDD R4,R0 ;MOVE FIFTH FACC TO FIRST FACC ;MSH134 STD R0,(R2)+ ;SAVE FIFTH FACC ;MSH134 LDD R5,R0 ;MOVE SIXTH FACC TO FIRST FACC ;MSH134 STD R0,(R2)+ ;SAVE SIXTH FACC ;MSH134 STD R1,(R2)+ ;SAVE SECOND FACC ;MSH134 STD R2,(R2)+ ;SAVE THIRD FACC ;MSH134 STD R3,(R2)+ ;SAVE FOURTH FACC ;MSH134 ;**-8 .ENDC ; ; LOAD CONTEXT OF NEW TASK ; 80$: MOV R5,$TKTCB ;SET ADDRESS OF NEW TCB MOV T.PCB(R5),R3 ;GET ADDRESS OF TASK PARTITION PCB MOV P.HDR(R3),R2 ;GET ADDRESS OF TASK HEADER MOV R2,$HEADR ;SET ADDRESS OF TASK HEADER .IFT .IF DF C$$CKP&T$$BUF!A$$TRP!P$$OFF MOV R4,-(SP) ;SAVE EFFECT AST FLAG .ENDC MOV H.WND(R2),R4 ;POINT TO NUMBER OF WINDOW BLOCKS TST W.BLVR+2(R4) ;IS TASK MAPPED TO THE EXEC? BEQ 85$ ;IF EQ NO .IFTF MOV R2,R1 ;COPY ADDRESS OF TASK HEADER ADD R0,R1 ;POINT TO DIRECTIVE STATUS WORD MOV (R1)+,(R0)+ ;RESTORE DIRECTIVE STATUS WORD MOV (R1)+,(R0)+ ;RESTORE POINTER TO FCS IMPURE AREA MOV (R1)+,(R0)+ ;RESTORE POINTER TO FORTRAN IMPURE AREA MOV (R1)+,(R0)+ ;RESTORE POINTER TO OVERLAY IMPURE AREA MOV (R1)+,(R0)+ ;RESTORE PTR TO VECTOR OF IMPURE PTRS .IFT MOV #UISDR0,R0 ;POINT TO USER DESCRIPTOR REGISTER 0 MOV #77406,(R0) ;SETUP PRIVILEGED TASK DESCRIPTOR REGISTERS MOV (R0)+,(R0) ; MOV (R0)+,(R0) ; MOV (R0)+,(R0) ; .IF DF R$$EXV MOV (R0)+,(R0) ; .ENDC MOV (R0),UISDR0+14. ;ALLOW FULL ACCESS TO I/O PAGE MOV #UISAR0,R1 ;POINT TO USER ADDRESS REGISTER 0 MOV #KISAR0,R0 ;POINT TO KERNAL ADDRESS REGISTER 0 MOV (R0)+,(R1)+ ;SETUP PRIVILEGED TASK ADDRESS REGISTERS MOV (R0)+,(R1)+ ; MOV (R0)+,(R1)+ ; .IF DF R$$EXV MOV (R0)+,(R1)+ ; .ENDC MOV (R0),(R1) ; MOV #177600,UISAR0+14. ;SET ADDRESS REGISTER 7 FOR I/O PAGE BR 90$ ; 85$: MOV #UISDR0,R0 ;POINT TO USER DESCRIPTOR REGISTER 0 CLR (R0)+ ;CLEAR ALL USER DESCRIPTOR REGISTERS CLR (R0)+ ; CLR (R0)+ ; CLR (R0)+ ; CLR (R0)+ ; CLR (R0)+ ; CLR (R0)+ ; CLR (R0) ; 90$: MOV (R4)+,-(SP) ;PUSH NUMBER OF WINDOW BLOCKS 100$: ADD #W.BLGH,R4 ;POINT PAST CURRENT WINDOW BLOCK MOV -W.BLGH(R4),R3 ;PICK UP NEXT PCB ADDRESS BEQ 115$ ;IF EQ WINDOW IS NOT MAPPED CMP -(R4),-(R4) ;POINT TO FIRST PDR ADDRESS MOV P.REL(R3),R0 ;PICK UP PARTITION RELOCATION BIAS .IF DF P$$LAS!A$$HDR ;MSH096 ;**-1 ADD -2(R4),R0 ;ADD IN WINDOW OFFSET .ENDC MOVB (R4)+,R1 ;POINT TO FIRST PDR MOVB (R4)+,R3 ;PICK UP NUMBER OF PDR'S TO LOAD 110$: MOVB (R4),(R1)+ ;SET USER DESCRIPTOR ACCESS CODE MOVB #177,(R1)+ ;SET BLOCK LENGTH MOV R0,UISAR0-UISDR0-2(R1) ;LOAD USER ADDRESS REGISTER ADD #200,R0 ;ADVANCE TO NEXT 4K BOUNDARY DEC R3 ;ANY MORE TO LOAD? BGT 110$ ;IF GT NO MOV (R4)+,-(R1) ;LOAD LAST USER DESCRIPTOR REGISTER 115$: DEC (SP) ;ANY MORE WINDOW BLOCKS? BGT 100$ ;IF GT YES MOV (R2),(SP) ;LOAD USER STACK POINTER MTPI SP ; .IF DF C$$CKP&T$$BUF!A$$TRP!P$$OFF MOV (SP)+,R4 ;RESTORE EFFECT AST INDICATOR .ENDC .IFF .IF DF E$$EAE MOV H.FPSA(R2),R0 ;POINT TO EAE SAVE AREA BEQ 120$ ;IF EQ TASK DOES NOT USE EAE CMP (R0)+,(R0)+ ;POINT TO SAVED MQ REGISTER MOV (R0),MQ ;RESTORE EAE REGISTERS MOV -(R0),AC ; MOV -(R0),SC ; .ENDC .IFTF .IF DF F$$LPP MOV H.FPSA(R2),R0 ;POINT TO FLOATING POINT SAVE AREA BEQ 120$ ;IF EQ TASK DOES NOT USE FLOATING POINT TST $HFMSK ;FLOATING POINT PROCESSOR PRESENT? ;MSH149 BMI 120$ ;IF MI NO, DON'T RESTORE FPP CONTEXT ;MSH149 .IF DF M$$MGE .IF DF A$$HDR ;MSH140 ;MSH140 TSTB T.HDLN(R5) ;EMULATOR TASK? ;MSH140 BNE 118$ ;IF NE YES, SAVE AREA IN HEADER ;MSH140 ;MSH140 .ENDC ;MSH140 ;MSH140 MOV T.PCB(R5),R1 ;GET ADDRESS OF TCB OF NEXT TASK MOV P.REL(R1),KISAR6 ;MAP TO TASK PARTITION .IF DF P$$LAS ADD T.OFF(R5),KISAR6 ;ADD IN OFFSET TO TASK IMAGE .ENDC 118$: ; ;MSH140 .ENDC TST (R0)+ ;POINT TO SAVED FLOATING POINT REGISTERS LDFPS #200 ;SET DOUBLE MODE - CLEAR EXCEPTION INTS.;MSH134 LDD (R0)+,R0 ;LOAD FIRST FACC ;MSH134 LDD (R0)+,R1 ;LOAD FIFTH FACC INTO SECOND FACC ;MSH134 STD R1,R4 ;MOVE FIFTH FACC INTO POSITION ;MSH134 LDD (R0)+,R1 ;LOAD SIXTH FACC INTO SECOND FACC ;MSH134 STD R1,R5 ;MOVE SIXTH FACC INTO POSITION ;MSH134 LDD (R0)+,R1 ;LOAD SECOND FACC ;MSH134 LDD (R0)+,R2 ;LOAD THIRD FACC ;MSH134 LDD (R0)+,R3 ;LOAD FOURTH FACC ;MSH134 LDFPS @H.FPSA(R2) ;RESTORE FLOATING POINT STATUS ;**-9 .ENDC 120$: MOV H.GARD(R2),R0 ;POINT TO HEADER GUARD WORD MOV SP,R1 ;POINT TO CURRENT CONTEXT MOV -(R0),(R1)+ ;RESTORE R0 MOV -(R0),(R1)+ ;RESTORE R1 MOV -(R0),(R1)+ ;RESTORE R2 MOV -(R0),(R1)+ ;RESTORE R3 .IFT MOV -(R0),(R1)+ ;RESTORE R4 MOV -(R0),(R1)+ ;RESTORE R5 MOV -(R0),(R1)+ ;RESTORE PC MOV -(R0),(R1) ;RESTORE PS .ENDC 130$: ;REF LABEL ; ;MSH091 ; AST CONTROL BLOCKS: ;MSH091 ; ;MSH091 ; AST CONTROL BLOCKS FALL INTO SEVERAL DISTINCT CATEGORIES BASED ;MSH091 ; UPON THE VALUE OF A.CBL. THE FORMATS OF A.CBL ARE AS FOLLOWS: ;MSH091 ; ;MSH091 ; A.CBL+1 A.CBL DESCRIPTION ;MSH091 ; ------- ----- ----------- ;MSH091 ; ;MSH091 ; 0 0 AST DEQUEUED BY A SYSTEM SUBROUTINE. THE;MSH091 ; ROUTINE IS MAPPED BY THE CONTENTS OF ;MSH091 ; A.KSR5 AND CALLED VIA THE ADDRESS IN ;MSH091 ; A.DQSR. DEALLOCATION OF THE CONTROL ;MSH091 ; BLOCK IS THE RESPONSIBILITY OF THE ;MSH091 ; DEQUEUE ROUTINE. AN EXAMPLE IS THE ;MSH091 ; PROCESSING OF UNSOLICITED INPUT ASTS ;MSH091 ; BY THE FULL DUPLEX TERMINAL DRIVER. ;MSH091 ; ;MSH091 ; N 0 SPECIFIABLE AST CONTROL BLOCK OF LENGTH ;MSH091 ; C.LGTH. N IS THE SPECIFIED AST TYPE. ;MSH091 ; THESE BLOCKS ARE RELINKED IN THE T.SAST ;MSH091 ; LIST AFTER THE AST IS DECLARED (EXCEPT ;MSH091 ; FOR REQUESTED EXIT ASTS, WHICH ARE ;MSH091 ; DEALLOCATED AFTER USE BY A NON-PRIVILEGE;MSH091 ; TASK). ;MSH091 ; ;MSH091 ; 0 >0 DYNAMIC AST CONTROL BLOCK (I/O COMPLETIO;MSH091 ;  MARK TIME) OF LENGTH A.CBL. AFTER THE ;MSH091 ; PARAMETERS ARE MOVED TO THE TASK STACK ;MSH091 ; AND THE AST EFFECTED THE BLOCK IS ;MSH091 ; DEALLOCATED. ;MSH091 ; ;MSH091 ; X <0 KERNEL AST CONTROL BLOCK. BIT 6 IS SET ;MSH091 ; IF $SGFIN SHOULD NOT BE CALLED PRIOR TO ;MSH091 ; EXECUTING THE KERNEL AST CODE. BITS ;MSH091 ; 0 THROUGH 5 REPRESENT A WORD INDEX ;MSH091 ; INTO A KERNEL AST DISPATCH TABLE. ;MSH091 ; DEALLOCATION OF THE CONTROL BLOCK IS ;MSH091 ;  THE RESPONSIBILITY OF THE PROCESSING ;MSH091 ; ROUTINE. KERNEL ASTS EFFECT EXECUTIVE ;MSH091 ; LEVEL FUNCTIONS THAT MUST OCCUR AFTER ;MSH091 ; THE TASK'S CONTEXT IS RELOADED. AN ;MSH091 ; EXAMPLE IS BUFFERED I/O COMPLETION. ;MSH091 ; ;MSH091 ;MSH091 .IF DF K$$AST!A$$TRP ;MSH091 ;**-1 TST R4 ;EFFECT AST? BEQ 190$ ;IF EQ NO MOV R5,R0 ;CALCULATE ADDRESS OF AST LISTHEAD ADD #T.ASTL,R0 ; CALL $QRMVF ;REMOVE AST ENTRY FROM QUEUE .IF DF K$$AST ;MSH091 ;**-1 MOVB A.CBL(R1),R4 ;KERNEL AST? ;MSH091 BMI 210$ ;IF MI YES ;**-1 .ENDC .ENDC .IF DF A$$TRP MOV R5,R4 ;CALCULATE ADDRESS OF STATUS WORD ADD #T.ST2,R4 ; MOVB (R4),-(SP) ;COPY CURRENT EXTENSION BYTE BIC #^C,(SP) ;CLEAR ALL BUT WAIT STATE ASL (SP) ;SHIFT INTO POSITITON FOR SAVE BIC #*2!T2.STP!T2.SPN!T2.WFR,(R4) ; BIS (SP)+,(R4) ;SAVE WAIT STATE BIS #T2.AST,(R4) ;SET AST IN PROGRESS MOV R1,R3 ;COPY AST CONTROL BLOCK ADDRESS MOV R3,-(SP) ;SAVE AST CONTROL BLOCK ADDRESS CMP (R3)+,(R3)+ ;POINT TO NUMBER OF BYTES TO ALLOCATE MOV $HEADR,R4 ;POINT TO TASK HEADER .IF DF M$$MGE MFPI SP ;GET CURRENT STACK POINTER MOV (SP)+,R0 ; .IFF MOV (R4),R0 ;GET CURRENT STACK POINTER .ENDC MOV (R3)+,R1 ;GET NUMBER OF BYTES TO ALLOCATE ON TASK STACK SUB R1,R0 ;CALCULATE NEW TOP OF STACK .IF DF A$$CHK!M$$MGE CALL $ACHCK ;ADDRESS CHECK STACK SPACE BCS 160$ ;IS CS ADDRESS CHECK FAILURE .ENDC .IF DF M$$MGE MOV R0,-(SP) ;SET NEW TASK STACK POINTER MTPI SP ; CALL $RELOM ;RELOCATE AND MAP STACK ADDRESS MOV SP,R1 ;CALCULATE ADDRESS OF TRAP PC ADD #7*2,R1 ; .IFF MOV (R4),R1 ;RETRIEVE OLD TOP OF STACK MOV R0,(R4) ;SET NEW TASK STACK POINTER MOV (R1)+,(R0)+ ;MOVE SAVED R4 MOV (R1)+,(R0)+ ;MOVE SAVED R5 MOV (R3)+,(R0)+ ;SET AST TRAP PC CLR (R0)+ ;SET AST TRAP PS .IFTF MOV (R1)+,-(SP) ;SAVE PC AT TRAP MOV (R1),R2 ;SAVE PS AT TRAP .IFT MOV #CMODE!PMODE,(R1) ;SET AST TRAP PS MOV (R3)+,-(R1) ;SET AST TRAP PC .IFTF MOV (R3)+,-(SP) ;GET NUMBER OF PARAMETERS TO MOVE 140$: DEC (SP) ;ANY MORE PARAMETERS TO MOVE? BLT 150$ ;IF LT NO MOV (R3)+,(R0)+ ;MOVE PARAMETER TO USER STACK BR 140$ ; 150$: TST (SP)+ ;CLEAN STACK .IFF MOV @.DSW,(R0)+ ;MOVE DSW TO TASK STACK .IFT MFPI @#H.DSW ;GET USER DSW MOV (SP)+,(R0)+ ;MOVE DSW TO TASK STACK .ENDC MOV (SP)+,(R0)+ ;MOVE PC AT TRAP TO TASK STACK MOV R2,(R0)+ ;MOVE PS AT TRAP TO TASK STACK ;MSH069 .IF DF S$$TOP!T$$BUF ;MSH069 ;MSH069 MOV T.EFLM(R5),(R0) ;SAVE WAITFOR MASK WORD ;MSH069 MOV T.EFLM+2(R5),H.EFSV(R4) ;SAVE WAITFOR MASK ADDRESS ;MSH069 ;MSH069 .IFF ;MSH069 ;MSH069 MOV H.EFLM(R4),(R0) ;SAVE WAITFOR MASK WORD MOV H.EFLM+2(R4),H.EFSV(R4) ;SAVE WAITFOR MASK ADDRESS ;MSH069 .ENDC ;MSH069 .IF DF A$$CHK!M$$MGE BR 170$ ;TAKE COMMON EXIT 160$: MOV #S.CAST,R0 ;SET AST ABORT CALL $ABCTK ;ABORT CURRENT TASK .ENDC 170$: MOV (SP)+,R0 ;RETRIEVE AST CONTROL BLOCK ADDRESS MOV A.CBL(R0),R1 ;GET LENGTH OF BLOCK TO RELEASE BNE 175$ ;JUMP IF NON-ZERO .IF DF M$$MGE CMP -(R0),-(R0) ;ZERO - POINT TO A.KSR5 MOV (R0)+,KISAR5 ;MAP DEQUEUE SUBROUTINE IN APR 5 CALL @(R0)+ ;CALL DEQUEUE SUBROUTINE .IFF CALL @-2(R0) ;CALL DEQUEUE SUBROUTINE .ENDC BR 200$ ;EXIT 175$: TSTB R1 ;LENGTH NON-ZERO? BNE 180$ ;Y - JUMP ; MF208 .IF DF A$$CLI ; MF208 ; MF208 CMP R1,# ;COMMAND ARRIVAL AST FOR CLI ; MF208 BNE 176$ ;IF NE NO ; MF208 TST A.PRM+2(R0) ;SHOULD AST BLOCK BE DEALLOCATED ; MF208 BNE 178$ ;IF NE NO ; MF208 ; MF208 ; MF208 .IF DF A$$BRT ; MF208 ; MF208 BR 1765$ ;DEALLOCATE AST BLOCK ; MF208 ; MF208 .IFF ;A$$BRT ; MF208 ; MF208 CALL $DECLK ;DEALLOCATE AST BLOCK ; MF208 BR 200$ ;TRY EXIT AGAIN ; MF208 ; MF208 .ENDC ;A$$BRT ; MF208 176$: ; MF208 .ENDC ;A$$CLI ; MF208 ; MF208 ;MSH121 .IF DF A$$BRT ;MSH121 ;MSH121 CMP R1,# ;REQUESTED EXIT AST? ;MSH121 BNE 178$ ;IF NE NO ;MSH121 BIT #T3.PRV,T.ST3(R5) ;TASK PRIVILEGED? ;MSH121 BNE 177$ ;IF NE YES, ALLOW RESPECIFICATION ;MSH121 1765$: CALL $DECLK ;DEALLOCATE AST CONTROL BLOCK ;MSH121 BR 200$ ;TRY EXIT AGAIN ;MSH121 177$: BIC #T2.REX,T.ST2(R5) ;ALLOW AST RESPECIFICATION ;MSH121 ;MSH121 .ENDC ;MSH121 ;MSH121 178$: MOV T.SAST(R5),(R0) ;LINK SPEC AST CONTROL BLOCK ONTO ;MSH121 MOV R0,T.SAST(R5) ; SPEC AST LISTHEAD ;**-1 BR 200$ ;TRY EXIT AGAIN 180$: CALL $DEACB ;DEALLOCATE CONTROL BLOCK BR 200$ ;TRY EXIT AGAIN .ENDC 190$: TSTB T.ST2(R5) ;TASK BEING HALTED? BPL 200$ ;IF PL NO TEXIT: CALL $DREX1 ;FORCE TASK EXIT ;MSH115 200$: JMP $DIRXT ; ;**-1 ; ;MSH091 ; KERNEL AST DISPATCHING ;MSH091 ; ;MSH091 ;MSH091 .IF DF K$$AST ;MSH091 ;**-1 210$: MOV #$DIRXT,-(SP) ;SET RETURN ADDRESS MOV R1,R0 ;SET ADDRESS OF AST CONTROL BLOCK ASLB R4 ;CONVERT AST CODE TO NEGATIVE BYTE INDEX;MSH091 BMI 215$ ;IF MI DO NOT CALL $SGFIN ;MSH091 ;MSH091 .IF DF A$$BIO!P$$OFF ;MSH091 ;MSH091 CALL $SGFIN ;INGNORE SEGMENT FAULTS ;MSH091 ;MSH091 .ENDC ;MSH091 ;MSH091 JMP @(R4) ;DISPATCH KERNEL AST (NO $SGFIN BIT) ;MSH091 215$: JMP @(R4) ;DISPATCH KERNEL AST (W/ $SGFIN BIT) ;MSH091 ;MSH091 KTBL: KAST $FINBF,A$$BIO!C$$CKP&T$$BUF ;TERM I/O COMPLETION (AK.BUF;MSH199 KAST $FINXT,P$$OFF ;OFFSPRING EXIT STATUS (AK.OCB) ;MSH091 KAST $GENBF,T$$BUF&A$$BIO ;GENERAL BUFFERED I/O (AK.GBI) ;MSH091 KAST $GGFRN,P$$SRF&G$$EFN ;GROUP GLOBAL RUNDOWN (AK.GGF) ;MSH183 ;MSH091 CRSH: CRASH ;CRASH, ILLEGAL KERNEL AST TYPE ;MSH091 ;MSH091 .ENDC ;MSH091 ;MSH091 .DSABL LSB ;MSH091 ;MSH183 .IF DF P$$SRF&G$$EFN ;MSH183 ;MSH183 ;+ ;MSH183 ; **-$GGFRN-GROUP GLOBAL EVENT FLAG USE COUNT RUNDOWN ;MSH183 ; ;MSH183 ; DEACCESS THIS TASK'S GROUP GLOBAL EVENT FLAGS IF THE EVENT FLAG ;MSH183 ; MASK IN THE AST CONTROL BLOCK IS GROUP GLOBAL, AND DEALLOCATE ;MSH183 ; THE AST CONTROL BLOCK. ;MSH183 ; ;MSH183 ; INPUTS: ;MSH183 ; ;MSH183 ; R0=ADDRESS OF THE KERNEL AST CONTROL BLOCK ;MSH183 ; ;MSH183 ; OUTPUTS: ;MSH183 ; ;MSH183 ; THE GROUP GLOBAL EVENT FLAGS ARE DEACCESSES AND THE CONTROL ;MSH183 ; BLOCK IS DEALLOCATED. ;MSH183 ; ;MSH183 ; FORMAT OF THE AST CONTROL BLOCK: ;MSH183 ; ;MSH183 ; WD.00 -- UNKNOWN ;MSH183 ; WD.01 -- KERNEL AST TYPE = AK.GGF ;MSH183 ; WD.02 -- UNKNOWN ;MSH183 ; WD.04 -- EVENT FLAG MASK ADDRESS ;MSH183 ; WD.05 THRU WD.17 -- UNKNOWN ;MSH183 ; ;MSH183 ;- ;MSH183 ;MSH183 $GGFRN::MOV $HEADR,R4 ;GET CURRENT TASK'S HEADER ADDRESS ;MSH183 MOV R0,-(SP) ;SAVE CONTROL BLOCK ADDRESS ;MSH183 MOV 6(R0),R3 ;GET EVENT FLAG MASK ADDRESS ;MSH183 CALL $DEAGF ;DEACCESS IF GROUP GLOBAL ;MSH183 MOV (SP)+,R0 ;RESTORE CONTROL BLOCK ADDRESS ;MSH183 CALL $DEPKT ;DEALLOCATE THE CONTROL BLOCK ;MSH183 CALLR $SETRT ;MAKE SURE ALL KERNEL ASTS ARE FOUND ;MSH183 ;MSH183 .ENDC ;P$$SRF&G$$EFN ;MSH183 ;MSH091 .IF DF P$$OFF ;MSH091 ;**-24 ;+ ; **-$FINXT-FINISH OFFSPRING TASK EXIT PROCESSING ; ; QUEUE AST AND RETURN EXIT STATUS TO A PARENT TASK ONCE THAT TASK ; HAS BEEN SCHEDULED. $SGFIN HAS BEEN CALLED. ;MSH091 ; ;**-1 ; INPUTS: ; ; R0=ADDRESS OF OFFSPRING CONTROL BLOCK. ; ; OUTPUTS: ; ; ALL EXIT CONDITIONS ARE EFFECTED AND THE OFFSPRING CONTROL BLOCK ; IS DEALLOCATED IF IT IS NOT USED AS AN AST CONTROL BLOCK. ;- $FINXT::MOV R0,R3 ;COPY OCB POINTER MOV R0,R4 ;COPY OCB POINTER TST (R3)+ ;SKIP OVER LINK WORD (O.LNK) MOV #O.LGTH,(R3)+ ;SET LENGTH TO DEALLOCATE (O.LNK=A.CBL) MOV (R3),R5 ;PICK UP PARENT TCB ADDR (O.PTCB=A.BYT) MOV #8.*2,(R3)+ ;BYTES ON USER STACK (O.PTCB=A.BYT) TST (R3)+ ;SKIP OVER AST WORD (O.AST=A.AST) MOV (R3),R0 ;PICK UP EFN NUMBER (O.EFN=A.NPR) CALL $SETFG ;SET EFN AND UNLOCK IF GRP GLOBAL ;MSH049 MOV #1,(R3) ;SET NUMBER OF AST PARMS (O.EFN=A.NPR) ;MSH129 MOV (R3)+,R2 ;ASSUME EXIT STATUS BLOCK LENGTH=1 WORD ;MSH129 MOV (R3),R0  ;PICK UP VIRTUAL EXB ADDR (O.ESB=A.PRM) ;MSH129 ASR R0 ;FULL LENGTH EXIT STATUS BLOCK? ;MSH129 BCC 35$ ;IF CC NO, 1 WORD LONG ;MSH129 MOV #8.,R2 ;SET UP FOR FULL LENGTH EXIT STATUS BLK ;MSH129 35$: ASL R0 ;RESTORE EXIT STATUS BLOCK ADDRESS ;MSH129 MOV R0,(R3)+ ;RESTORE CORRECTED ESB ADDRESS ;MSH129 BEQ 40$ ;IF EQ THERE IS NONE ;**-3 37$: ;REF LABEL ;MSH129 ;MSH092 .IF DF M$$MGE ;MSH092 ;MSH092 MOV (R3)+,-(SP) ;PICK UP NEXT WORD OF STATUS ;MSH129  MTPI (R0)+ ;STORE WORD IN USER BUFFER (CAN TRAP) ;MSH129 ;MSH092 .IFF ;MSH092 ;MSH092 MOV (R3)+,(R0)+ ;STORE WORD IN USER BUFFER ;MSH129 ;MSH092 .ENDC ;MSH092 ;MSH092 DEC R2 ;DONE TRANSFERRING EXIT STATUS BLOCK? ;MSH129 BGT 37$ ;IF GT NO ;MSH129 40$: ;REF LABEL ;MSH126 ;MSH126 .IF DF A$$TRP ;MSH126 ;MSH126 TST O.AST(R4) ;EFFECT AST? ;MSH126 BEQ 50$ ;IF EQ NO ;**-3 MOV R5,R0 ;SET PARENT TCB ADDRESS MOV R4,R1 ;SET AST BLOCK ADDRESS CALLR $QASTT ;QUEUE AST FOR PARENT AND RETURN ;MSH126 .ENDC ;MSH126 ;MSH126 50$: MOV R4,R0 ;POINT TO BLOCK TO RELEASE MOV #O.LGTH,R1 ;PICK UP SIZE TO RELEASE CALL $DEACB ;DEALLOCATE OCB CALLR $SETRT ;INSURE RESCAN OF TASK .ENDC ;P$$OFF .IF DF T$$BUF&A$$BIO ;MSH091 ;MSH091 ;+ ;MSH091 ; **-$GENBF-GENERAL BUFFERED I/O COMPLETION ;MSH091 ; ;MSH091 ; THIS ROUTINE IS CALLED TO TRANSFER KERNEL AST CONTROL TO A DRIVER ;MSH091 ; FOR PROCESSING OF FUNCTIONS WHICH MUST BE DONE WITH TASK CONTEXT ;MSH091 ; LOADED. THE KERNEL AST CONTROL BLOCK IS STRUCTURED AS FOLLOWS: ;MSH091 ; ;MSH091 ; WD. 00 -- LINK WORD ;MSH091 ; WD. 01 -- KERNEL AST TYPE (A.CBL=AK.GBI) ;MSH091 ; WD. 02 -- SUBROUTINE KISAR5 BIAS ;MSH091 ; WD. 03 -- SUBROUTINE ADDRESS ;MSH091 ; ;MSH091 ; $SGFIN HAS BEEN CALLED. ;MSH091 ; ;MSH091 ; INPUTS: ;MSH091 ;  ;MSH091 ; R0=ADDRESS OF KERNEL AST CONTROL BLOCK ;MSH091 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK ;MSH091 ; ;MSH091 ; OUTPUTS: ;MSH091 ; ;MSH091 ;- ;MSH091 ;MSH091 ;MSH091 $GENBF::SAVNR ;SAVE NONVOLITILE REGISTERS ;MSH091 MOV R0,R3 ;COPY AST CONTROL BLOCK ADDRESS ;MSH091 CALL $SETRT ;FORCE REDISPATCHING OF PROCESSOR ;MSH091 MOV 4(R3),KISAR5 ;MAP DRIVER ACCEPTANCE ROUTINE ;MSH091 CALLR @6(R3) ;CALL DRIVER ACCEPTANCE ROUTINE ;MSH091 ;MSH091 .ENDC ;T$$BUF&A$$BIO ;MSH091 ;MSH091 .IF DF A$$BIO!C$$CKP&T$$BUF ;MSH199 ;MSH046 ;+ ;MSH046 ; **-$FINBF-FINISH TERMINAL BUFFERED I/O ;MSH046 ; ;MSH046 ; THIS ROUTINE IS CALLED TO COMPLETE A BUFFERED TERMINAL REQUEST ;MSH046 ; THAT HAS BEEN PLACED IN THE AST QUEUE AS A KERNEL AST (TYPE=AK.BUF). ;MSH046 ; $SGFIN HAS BEEN CALLED. ;MSH046 ; ;MSH046 ; INPUTS: ;MSH046 ; ;MSH046 ; R0=ADDRESS OF I/O PACKET ;MSH046 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK ;MSH046 ; ;MSH046 ; THE RELEVENT FIELDS IN THE I/O PACKET ARE AS FOLLOWS: ;MSH046 ; ;MSH046 ; I.PRM+00 - KISAR6 BIAS FOR USER I/O BUFFER ;MSH046 ; I.PRM+02 - STARTING ADDRESS OF USER I/O BUFFER ;MSH046 ; I.PRM+04 - ;MSH046 ; I.PRM+06 - FINAL I/O STATUS (FIRST WORD OF IOSB) ;MSH046 ; I.PRM+10 - NUMBER OF BYTES TRANSFERRED (SECOND WORD OF IOSB) ;MSH046 ; I.PRM+12 - FIRST TRANSFER BUFFER ADDRESS ;MSH046 ; I.PRM+14 - ;MSH046 ; I.PRM+16 - USER BUFFER PCB ADDRESS ;MSH046 ; ;MSH046 ; OUTPUTS: ;MSH046 ; ;MSH046 ; BUFFERED INPUT I/O IS TRANSFERRED TO THE USER TASK AND ;MSH046 ; $IOFIN IS CALLED TO FINISH THE I/O REQUEST. BUFFERED ;MSH046 ; OUTPUT I/O IS SIMPLY FINISHED WITH $IOFIN. THE I/O STATUS ;MSH046 ; BLOCK IS FILLED IN BEFORE CALLING $IOFIN. IT IS ASSUMED THAT ;MSH046 ; THE I/O STATUS BLOCK'S VIRTUAL ADDRESS IS STILL VALID. ;MSH046 ;- ;MSH046 ;MSH046 ;MSH046 ;MSH046 $FINBF::SAVNR ;SAVE NONVOLITILE REGISTERS ;MSH046 MOV R0,R3 ;COPY I/O PACKET ADDRESS ;MSH046 INCB T.IOC(R5) ;INCREMENT OUTSTANDING I/O COUNT ;MSH046 MOV I.IOSB(R3),R5 ;GET VIRTUAL I/O STATUS BLOCK ADDRESS ;MSH046 BEQ 10$ ;IF EQ NO I/O STATUS BLOCK TO FILL IN ;MSH046 ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV I.PRM+6(R3),-(SP) ;PUSH FINAL I/O STATUS ;MSH046 MTPI (R5)+ ;PUT FINAL I/O STATUS IN IOSB (MAY TRAP);MSH046 MOV I.PRM+10(R3),-(SP) ;PUSH NUMBER OF BYTES TRANSFERRED ;MSH046 MTPI (R5) ;PUT NUMBER BYTES IN IOSB+2 (MAY TRAP) ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 MOV I.PRM+6(R3),(R5)+ ;PUT FINAL I/O STATUS IN IOSB ;MSH046 MOV I.PRM+10(R3),(R5) ;PUT NUMBER OF BYTES IN IOSB+2 ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 CLR I.IOSB+4(R3) ;PREVENT $IOFIN FROM TOUCHING IOSB ;MSH046 10$: MOV R3,-(SP) ;SAVE I/O PACKET ADDRESS ;MSH046 ;MSH046 ; ;MSH046 ; IF SYSTEM-CONTROLLED PARTITIONS EXIST, TASK MAY HAVE MOVED IN MEMORY. ;MSH046 ; IF SO, THE PHYSICAL ADDRESS DOUBLEWORD FOR THE USER BUFFER IS RELATIVE;MSH046 ; TO THE BASE ADDRESS OF ITS REGION. NOW THAT THE TASK'S CONTEXT IS ;MSH046 ; ACTIVE, GET THE PCB ADDRESS OF THAT REGION FROM WHICH THE BASE ;MSH046 ; ADDRESS WILL BE EXTRACTED LATER. ;MSH046 ; ;MSH046 ;MSH046 .IF DF D$$YNM&M$$MGE ;MSH046 ;MSH046 ADD #I.PRM+16,R3 ;POINT TO USER BUFFER PCB ADDRESS ;MSH046 MOV (R3),R5 ;GET USER BUFFER PCB (I.PRM+16) ;MSH046 ;MSH046 .IF DF R$$LKL ;MSH046 ;MSH046 CLR (R3) ;CLEAR LAST PARAMETER WORD (I.PRM+16) ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 TST -(R3) ;BACKUP POINTER (I.PRM+14) ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 ADD #I.PRM+14,R3 ;POINT PAST TRANSFER BUFFER ADDRESS ;MSH046 ;MSH046 .ENDC ;D$$YNM&M$$MGE ;MSH046 ;MSH046 MOV -(R3),R2 ;GET TRANSFER BUFFER ADDRESS (I.PRM+12) ;MSH046 ;MSH046 ; ;MSH046 ; IF ASYNCHRONOUS BUFFERED I/O IS SUPPORTED, SIMPLY FINISH THE I/O IF IT;MSH046 ; WAS AN OUTPUT FUNCTION. ELSE, BUFFERED OUTPUTS DON'T EXIST. ;MSH046 ; ;MSH046 ;MSH046 .IF DF A$$BIO ;MSH046 ;MSH046 BEQ 20$ ;IF EQ, OUTPUT FUNCTION - TRANSFER DONE ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV R3,-(SP) ;SAVE POINTER INTO I/O PACKET (I.PRM+12);MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 MOV -(R3),R4 ;GET USER BUFFER ADDRESS ;MSH046 ;MSH046 ; ;MSH046 ; IF ASYNCHRONOUS BUFFERED I/O IS SUPPORTED, THE TRANSFER BUFFER MAY BE ;MSH046 ; ONE OF TWO PLACES, SYSTEM POOL OR IN THE DRIVER'S PRIVATE BUFFER AREA.;MSH046 ; IF NOT IN POOL, THEN THE BUFFER MUST BE MAPPED THRU KISAR5 BEFORE ;MSH046 ; ACCESSING IT. ;MSH046 ;  ;MSH046 ; NOTE THAT IF THE DRIVER IS RESIDENT, THE BUFFER ADDRESS WILL NOT BE ;MSH046 ; KISAR5 RELOCATABLE AND NEED NOT BE MAPPED. ;MSH046 ; ;MSH046 ; IF THE PCB ADDRESS IN R5 IS ZERO, THEN THE BUFFER STRUCTURE IS ;MSH175 ; UNKNOWN AND IT IS LEFT TO THE DRIVER TO COPY THE NECESSARY DATA. ;MSH175 ; IT IS ASSUMED THAT SYSTEMS WITH SUCH FOREIGN BUFFER STRUCTURES ;MSH175 ; WILL BE USING THE FULL DUPLEX TERMINAL DRIVER (WHICH IS ALWAYS ;MSH175 ; LOADABLE AND LOADED). ;MSH175 ; ;MSH175 ;MSH046 .IF DF A$$BIO&M$$MGE ;MSH046 ;MSH046 MOV @I.UCB-(R3),R0 ;GET DRIVER'S DCB ;MSH046 CLR -(SP) ;ASSUME DRIVER IS RESIDENT ;MSH046 MOV D.PCB(R0),R0 ;GET DRIVER'S PCB ;MSH046 BEQ 15$ ;IF EQ DRIVER IS RESIDENT ;MSH046 MOV P.REL(R0),(SP) ;PUSH DRIVER'S PARTITION BASE ;MSH046 ;MSH175 .IF DF T$$ACD&D$$YNM ;MSH175 ;MSH175 TST R5 ;IS THIS A FOREIGN BUFFER STRUCTURE? ;MSH175 BEQ 193$ ;IF EQ YES, LET THE DRIVER HANDLE IT ;MSH175 ;MSH175 .ENDC ;MSH175 ;MSH046 .IFTF ;MSH046 11$: ;MSH046 .IFT ;MSH046 ;MSH046 CMP R2,#120000 ;TRANSFER BUFFER IN DRIVER SPACE? ;MSH046 BLO 15$ ;IF LO NO, MUST BE IN POOL ;MSH046 MOV R2,R1 ;COPY BUFFER ADDRESS ;MSH046 BIC #77,R1 ;REMOVE DISPLACEMENT IN BLOCK BITS ;MSH046 SUB #120000,R1 ;CALC OFFSET IN DRIVER PAR IN BYTES ;MSH046 SUB R1,R2 ;REDUCE ADDRESS TO FIT IN KERNEL 5 ;MSH046 ASL R1 ;CONVERT BYTE OFFSET TO 32W BLOCKS ;MSH046 ASL R1 ; ;MSH046 SWAB R1 ; ;MSH046 ADD (SP),R1 ;CALCULATE PHYSICAL MEMORY OFFSET ;MSH046 MOV R1,KISAR5 ;MAP TRANSFER BUFFER ;MSH046 15$: ; ;MSH046 ;MSH046 .ENDC ;A$$BIO&M$$MGE ;MSH046 ;MSH046 ; ;MSH046 ; FOR SYSTEMS THAT DO NOT SUPPORT ASYNCHRONOUS BUFFERED I/O: ;MSH046 ; ;MSH046 ; THE FIRST WORD OF THE INPUT TRANFER BUFFER IS EXPECTED TO ;MSH046 ; BE ZERO. SINGLE BUFFERED I/O SYSTEMS (HDX TTDRV ONLY) WILL ;MSH046 ; NOT HAVE LINKED BUFFERS. THE BUFFER SPECIFIED IN I.PRM+12 ;MSH046 ; WILL CONTAIN ALL OF THE INPUT DATA COUNTED BY I.PRM+10. ;MSH046 ; ;MSH046 ; I.PRM+10 CONTAINS THE TOTAL BYTE TRANSFER COUNT. ;MSH046 ; THE SECOND WORD OF THE INPUT TRANSFER BUFFER IS IGNORED ;MSH046 ; BY $FINBF. I.PRM+10 IS USED EXCLUSIVELY TO DRIVE $FINBF. ;MSH046 ; ;MSH046 ; FOR SYSTEMS SUPPORTING ASYNCHRONOUS BUFFERED I/O: ;MSH046 ; ;MSH046 ; THE FIRST WORD OF THE INPUT TRANSFER BUFFER IS A LINK TO ;MSH046 ; CONTINUATION BUFFERS, OR ZERO. ;MSH046 ; ;MSH046 ; THE SECOND WORD OF THE INPUT TRANSFER BUFFER CONTAINS THE ;MSH046 ; BUFFER'S LENGTH, INCLUDING THE FIRST TWO WORDS. THIS ;MSH046 ; LENGTH-4 MAY ONLY BE A PART OF THE TOTAL CONTAINED IN ;MSH046 ; I.PRM+10 OF THE I/O PACKET. $FINBF WILL FOLLOW THE BUFFER ;MSH046 ; LINKS UNTIL I.PRM+10 BYTES HAVE BEEN TRANSFERRED TO THE ;MSH046 ; USER'S BUFFER. ;MSH046 ; ;MSH046 ;MSH046 .IF DF A$$BIO ;MSH046 ;MSH046 MOV (R2)+,-(SP) ;PUSH POINTER TO NEXT BUFFER ;MSH046 MOV (R2)+,R0 ;GET BLOCK SIZE ;MSH046 ;MSH046 .IFF ;A$$BIO ;MSH046 ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV -(R3),R0 ;GET #BYTES TRANSFERRED (I.PRM+10) ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 MOV -2(R3),R0 ;GET #BYTES TRANSFERRED (I.PRM+10) ;MSH046 ;MSH046 .ENDC ;M$$MGE ;MSH046 ;MSH046 CMP (R2)+,(R2)+ ;SKIP HEADER BYTES  ;MSH046 ;MSH046 .IFT ;A$$BIO ;MSH046 ;MSH046 CMP -(R0),-(R0) ;REDUCE BY HEADER BYTES (4) ;MSH046 SUB R0,-(R3) ;BLOCK OVERSIZED? (I.PRI+10) ;MSH046 BCC 16$ ;IF CC NO ;MSH046 ADD (R3),R0 ;ELSE, CORRECT COUNT (I.PRM+10) ;MSH046 CLR (R3) ;CLEAR REMAINING BYTE COUNT (I.PRM+10) ;MSH046 16$: ;MSH046 .IFTF ;MSH046 ;MSH046 ; ;MSH046 ; FINISH RELOCATING THE USER'S BUFFER IF THE TASK MIGHT HAVE MOVED. ;MSH046 ; ;MSH046  ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV I.PRM-(R3),R3 ;GET USER BUFFER APR6 BIAS ;MSH046 ;MSH046 .IF DF D$$YNM ;MSH046 ;MSH046 ADD P.REL(R5),R3 ;ADD IN PARTITION BASE ;MSH046 ;MSH046 .ENDC ;MSH046 ;MSH046 ; ;MSH046 ; EXECUTE THE ACTUAL TRANSFER OF BUFFERED DATA FROM THIS BLOCK TO ;MSH046 ; THE USER'S BUFFER. THE REGISTER CONTENTS AT THIS POINT ARE: ;MSH046 ; ;MSH046 ; R0=LENGTH OF TRANSFER ;MSH046 ; R1=BLOCK'S APR5 BIAS (MAPPED SYS W/ ASYNCH. BUFRD. I/O SUPPORT) ;MSH046 ; R2=BLOCK ADDRESS ;MSH046 ; R3=APR6 BIAS OF USER BUFFER (MAPPED ONLY) ;MSH046 ; R4=USER BUFFER ADDRESS ;MSH046 ; R5=USER BUFFER REGION PCB ADDRESS (MAPPED SYSTEMS WITH ;MSH046 ; SYSTEM-CONTROLLED PARTITION SUPPORT ONLY) ;MSH046 ; ;MSH046 ;MSH046 CALL $BLXIO ;TRANSFER TO USER BUFFER ;MSH046 ;MSH046 .IFF ;MSH046 ;MSH046 17$: DEC R0 ;ANY MORE BYTES TO COPY? ;MSH046 BLT 19$ ;IF LT NO ;MSH046 MOVB (R2)+,(R4)+ ;TRANSFER BYTE TO USER BUFFER ;MSH046 BR 17$ ; ;MSH046 19$: ;MSH046 .ENDC ;M$$MGE ;MSH046 ;MSH046 ; ;MSH046 ; IF ASYNCHRONOUS BUFFERED I/O IS SUPPORTED, THERE MAY BE MORE THAN ;MSH046 ; ONE INPUT TRANSFER BUFFER CONTAINING THE DATA FOR THE USER'S ;MSH046 ; REQUEST. AT THIS POINT, WE HANDLE MULTIPLE BUFFERS. ;MSH046 ; ;MSH046 ;MSH046 .IFT ;A$$BIO ;MSH046 ;MSH046 MOV (SP)+,R2 ;RETRIEVE NEXT BUFFER POINTER ;MSH046 ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV 2(SP),R3 ;GET I/O PACKET ADDRESS ;MSH046 ADD #I.PRM+10,R3 ;POINT TO REMAINING BYTE COUNT ;MSH046 ;MSH046 .IFTF ;M$$MGE ;MSH046 ;MSH046 TST (R3)+ ;ANY REMAINING BYTES? (I.PRM+10) ;MSH046 BNE 11$ ;IF NE YES ;MSH046 ;MSH046 ; ;MSH046 ; THE TRANSFER TO THE USER'S BUFFER IS DONE. SET UP AND CALL THE ;MSH046 ; DRIVER'S TRANSFER BUFFER DEALLOCATION ROUTINE. THE REGISTERS ;MSH046 ; AT THE CALL ARE: ;MSH046 ; ;MSH046 ; R0=ADDRESS OF FIRST TRANSFER BUFFER (FROM I.PRM+12) ;MSH046 ; R2=DRIVER DISPATCH TABLE ;MSH046 ; ;MSH046 ; NOTE THAT IF THE BUFFER STRUCTURE IS FOREIGN (R5=0), WE WILL COME ;MSH175 ; HERE WITHOUT TRANSFERRING ANY DATA. ;MSH175 ; ;MSH175 ; ;MSH046 ;MSH046 .IFT ;M$$MGE ;MSH046 ;MSH046 193$: MOV (SP)+,KISAR5 ;MAP THE DRIVER ;MSH046 ;MSH046 .ENDC ;M$$MGE ;MSH046 ;MSH046 .IFF ;A$$BIO ;MSH046 ;MSH046 .IF DF M$$MGE ;MSH046 ;MSH046 MOV (SP)+,R3 ;RESTORE XFER BUFFER POINTER (I.PRM+12) ;MSH046 ;MSH046 .ENDC ;M$$MGE ;MSH046 ;MSH046 .IFTF ;A$$BIO ;MSH046 ;MSH046 MOV (R3),R0 ;POINT TO FIRST BUFFER (I.PRM+12) ;MSH046 MOV @I.UCB-(R3),R2 ;GET DRIVER DCB ;MSH046 ;MSH046 .IFF ;A$$BIO ;MSH046  ;MSH046 .IF DF L$$DRV&M$$MGE ;MSH046 ;MSH046 MOV D.PCB(R2),R3 ;GET DRIVER'S PCB ;MSH046 BEQ 195$ ;IF EQ DRIVER RESIDENT ;MSH046 MOV P.REL(R3),KISAR5 ;MAP BUFFER DEALLOCATION ROUTINE ;MSH046 195$: ; ;MSH046 .ENDC ;MSH046 ;MSH046 .ENDC ;A$$BIO ;MSH046 ;MSH046 MOV D.DSP(R2),R2 ;GET DRIVER DISPATCH TABLE ;MSH046 CALL @D.VDEB(R2) ;CALL DRIVER DEALLOCATION ROUTINE ;MSH046 ;MSH046 ; ;MSH046 ; THE DUTIES OF THE KERNEL AST FOR BUFFERED I/O ARE NOW ;MSH046 ; COMPLETE. CALL $IOFIN TO FINISH THE I/O REQUEST. ;MSH046 ; ;MSH046 ;MSH046 20$: MOV (SP)+,R3 ;GET I/O PACKET ADDRESS ;MSH046 CALLR $IOFIN ;FINISH THE I/O ;MSH046 ;MSH046 .ENDC ;C$$CKP&T$$BUF ;MSH046 ;**-168 ;**-1 ;+ ; **-$SGFIN-SEGMENT FAULT AND TRAP 4 INTERCEPT ROUTINE ; ; THIS ROUTINE IS A CO-ROUTINE WHICH SETS UP TO IGNORE SEGMENT FAULTS ; AND TRAPS THROUGH 4. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; NONE. ;- $SGFIN::MOV @#4,-(SP) ;SAVE CONTENTS OF TRAP 4 VECTOR .IF DF C$$CHE ;MSH127 ;**-2 MOV @#114,-(SP) ;SAVE MAIN MEMORY TIMEOUT AND PARITY MOV 4(SP),-(SP) ;COPY RETURN ADDRESS MOV @#250,6(SP) ;SAVE SEGMENT TRAP ADDRESS MOV #$TRINT,@#114 ;TRAP THESE FAULTS ;MSH112 ;**-1 .IFF ;C$$CHE ;MSH127 ;**-1 MOV 2(SP),-(SP) ;COPY RETURN ADDRESS MOV @#250,4(SP) ;SAVE CONTENTS OF SEGMENT FAULT VECTOR .IFTF ;C$$CHE ;MSH127  ;**-1 MOV #$TRINT,@#4 ;POINT TO ROUTINE TO SET CARRY ;MSH112 MOV #$TRINT,@#250 ; ;MSH112 ;**-2 ; ; CONTENTS OF STACK AT THIS POINT: ; ; 0(SP)=COROUTINE RETURN ADDRESS TO CALLER. ; 2(SP)=CONTENTS OF @#114 (IF PROCESSOR HAS CACHE MEMORY) ;MSH127 ; 4(SP)=CONTENTS OF @#4 ;**-1 ; 6(SP)=CONTENTS OF @#250 ; CALL @(SP)+ ;RETURN TO CALLER .IFT ;C$$CHE ;MSH127 ;**-1 MOV (SP)+,@#114 ;RESTORE MAIN MEMORY TIMEOUT TRAP .ENDC ;C$$CHE ;MSH127  ;**-1 MOV (SP)+,@#4 ;RESTORE TRAP 4 VECTOR ;MSH088 .IF DF M$$MGE ;MSH088 ;MSH088 BIC #160000,@#SR0 ;UNFREEZE MEMORY MANAGEMENT UNIT ;MSH088 ;MSH088 .ENDC ;MSH088 ;MSH088 MOV (SP)+,@#250 ;RESTORE SEGMENT FAULT VECTOR RETURN ;RETURN TO CALLER'S CALLER ;+ ;**-4 ; **-$SAVNR-SAVE NONVOLATILE REGISTERS ; ; THIS ROUTINE IS A CO-ROUTINE THAT SAVES REGISTERS R4 AND R5. ;- $SAVNR::MOV R4,-(SP) ;SAVE R4 MOV R5,-(SP) ;SET RETURN ADDRESS MOV 4(SP),R5 ;RESTORE R5 CALL @(SP)+ ;CALL THE CALLER MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R5 ;RESTORE R5 RETURN ;RETURN TO ORIGINAL CALLER ;+ ; **$SWSTK-SWITCH STACKS ; ; THIS ROUTINE IS CALLED FROM TASK LEVEL TO SWITCH TO THE SYSTEM ; STACK THUS INHIBITING TASK SWITCHING. THE CALLING TASK MUST BE ; PRIVILEGED IF RUNNING IN A MAPPED SYSTEM AND MAPPED TO THE EXEC. ; CONTROL IS PASSED HERE FROM DRDSP AFTER THE TRAP HAS OCCURED AND ; $DIRSV HAS BEEN CALLED. ; ; CALLING SEQUENCE: ; ; EMT 376 ;TRAP TO $EMSST IN DRDSP ; .WORD ADDR ;ADDRESS FOR RETURN TO USER STATE ; ; INPUTS AT THIS POINT: ; ; R3=ADDRESS OF PC WORD OF TRAP ON STACK + 2 ; ; MAPPED SYSTEM: ; ; 22(SP)=PS PUSHED BY TRAP ; 20(SP)=PC PUSHED BY TRAP ; 16(SP)=SAVED R5 ; 14(SP)=SAVED R4 ; 12(SP)=SAVED R3 ; 10(SP)=SAVED R2 ; 06(SP)=SAVED R1 ; 04(SP)=SAVED R0 ; 02(SP)=RETURN ADDRESS FOR SYSTEM EXIT ; 00(SP)=104376 ; ; UNMAPPED SYSTEM: ; ; 10(SP)=SAVED R3 ; 06(SP)=SAVED R2 ; 04(SP)=SAVED R1 ; 02(SP)=SAVED R0 ; 00(SP)=RETURN ADDRESS FOR SYSTEM EXIT ; ; OUTPUTS: ; ; THE USER IS CALLED BACK ON THE SYSTEM STACK WITH ALL REGISTERS ; PRESERVED. TO RETURN TO TASK LEVEL THE CALLER MERELY EXECUTES ; A RETURN. ; ;- $SWSTK::CLRB (R3) ;SET INITIAL PS WORD .IF DF M$$MGE MOV #KISAR6,R5 ;POINT TO KERNAL APR 6 MOV UISAR6,(R5) ;SET UP KERNAL APR 6 MOV UISAR5,-(R5) ;SET UP KERNAL APR 5 .IF NDF R$$EXV MOV UISAR4,-(R5) ;SET UP KERNAL APR 4 .ENDC .IFTF MOV -(R3), R5 ;PICK UP TRAP PC WORD MOV (R5)+,(R3) ;SET ADDRESS FOR RETURN TO USER STATE .IFT MOV R5,(SP) ;SET CALLER'S ADDRESS .IFF MOV R5,-(SP) ;SET CALLER'S ADDRESS .ENDC MOV -(R3),R5 ;RESTORE R5 MOV 12(SP),R3 ;RESTORE R3 CALLR @(SP)+ ;CALL THE CALLER .END Ç8@QkQ ›c, .TITLE ICOM .IDENT /00/ ; ; COPYRIGHT (C) 1975, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 00 ; ; C. MONIA 05-JUN-75 ; ; ICS/ICR-11 DEVICE COMMON BLOCK ; ; EQUATED SYMBOLS ; ; DEFINE NUMBER OF ICS/ICR CONTROLLERS GLOBALLY ; .IF DF I$$C11 .GLOBL I$$C11 .ENDC ;+ ; ; **-.ICOM-ICS/ICR-11 DEVICE COMMON BLOCK ; ; THIS COMMON BLOCK MUST BE BUILT WHENEVER ANY ICS/ICR-11 ; MODULES ARE REFERENCED DIRECTLY. IN GENERAL SUCH DIRECT REFERENCES ; OCCUR AS THE RESULT OF CALLS TO THE FORTRAN PROCESS CONTROL SUB- ; ROUTINES THAT PERFORM INPUT FROM CONTACT SENSE, CONTACT INTERRUPT ; AND TIMER MODULES. THE EXTENT OF THE BLOCK IS SET TO ; PREVENT ACCESS TO THE DEVICE CONTROL AND STATUS REGISTERS BY THE TASK. ; ; ASSEMBLING THE COMMON BLOCK: ; ; THE COMMON BLOCK MUST BE ASSEMBLED WITH THE PREFIX FILE [11,10] ; RSXMC.MAC TO DEFINE  CONDITIONALS THAT CONTROL THE SIZE AND COMMON BLOCK ; ATTRIBUTES AS FOLLOWS: ; ; CONDITIONAL EFFECT ; ----------- ------ ; ; I$$C11 CONTROLS EXTENT OF COMMON BLOCK ; M$$MGE ESTABLISHES RELOCATABILITY OF COMMON BLOCK. ; COMMON BLOCK IS RELOCATABLE (PIC) IF DEFINED. ; OTHERWISE COMMON BLOCK IS ABSOLUTE. ; ; ; THE USER MAY FORCE THE COMMON BLOCK TO BE PIC BY INCLUDING THE ; CONDITIONAL 'I$$COM' IN RSXMC.MAC BY MEANS OF THE TEXT EDITOR. ; ;- .IF DF I$$C11 .IF DF M$$MGE!I$$C¤OM .PSECT ICOM,REL,GBL,OVR,D .IFF .ASECT .=171000 .ENDC .ICMD:: ; .BLKW I$$C11*16. ; SET LENGTH OF COMMON BLOCK .ENDC .END ¤Ã:È_kQ ›c, .TITLE PCSCOM .IDENT /00/ ; COPYRIGHT (C) 1977 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ; TRANSFERRED. ; ; THE INFORMATION ÄIN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ; CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ; .IF DF N$$PCS .GLOBL N$$PCS .IF DF M$$MGE!I$$POM .PSECT PCSCOM,REL,GBL,OVR,D .IFF .ASECT .=I$$PB0 .ENDC .PCSAD:: .BLKW 255. .ENDC .END ÄsÖQkQ ›c,S$$HFC=30. ;MINIMUM TICKS BETWEEN SHUFFLER RUNS M$$CRB=84. ;MCR COMMAND BUFFER LENGTH R$$11M=0 ;RSX-11M SYSTEM ; .IIF DF A$$BIO!C$$CKP&T$$BUF K$$AST=0 .IIF DF A$$BIO&T$$BUF K$$AST=0 .IIF DF P$$OFF K$$AST=0 .IIF DF P$$SRF&G$$EFN K$$AST=0 ; ; ; EXEC MACROS ; ; ; ASSUME MACRO FOR CHECKING ADJACENCY AND OFFSET VALUE ASSUMPTIONS ; .MACRO ASSUME A,B=0 .IF NE - .ERROR ;EXPRESSION(S) NOT EQUAL .ENDC .ENDM ; ; CALL SUBROUTINE ; .MACRO CALL SUBR ARG .IF IDN <$INTSV>, JSR R5,$INTSV .IF DF L$$SI1 .WORD ARG .IFF .WORD ^C&PR7 .ENDC .IFF .IF IDN <$SAVNR>, JSR R5,$SAVNR .IFF .IF IDN <$SWSTK>, EMT 376 .WORD ARG .IFF JSR PC,SUBR .ENDC .ENDC .ENDC .ENDM ; ; CALL AND RETURN FROM SUBROUTINE ; .MACRO CALLR SUBR JMP SUBR .ENDM ; ; CRASH SYSTEM ; .MACRO CRASH IOT .ENDM ; ; DIRECTIVE REGISTER SAVE AND SET PRIORITY ; .MACRO DIRSV$ JSR R5,$DIRSV .ENDM ; ; SET DIRECTIVE STATUS ; .MACRO DRSTS VALUE TRAP VALUE .ENDM ; ; GENERATE INTERRUPT ROUTINE ENTRY POINT LABEL ; .IF DF E$$DVC .MACRO INTLB NUM,NAM $'NAM'NUM'T:: .ENDM .ENDC ; ; INTERRUPT SAVE GENERATION MACRO FOR ERROR LOGGING DEVICES ; .MACRO INTSE$ DEV,PRI,NCTRLR,PSWSV,UCBSV,?LAB .IF DF L$$DRV & LD$'DEV & M$$MGE $'DEV'INT:: .IF NDF E$$DVC .IF EQ NCTRLR-1 CLR R4 .ENDC .ENDC .IFF .IF NDF E$$DVC $'DEV'INT::INTSV$ DEV,PRI,NCTRLR,PSWSV,UCBSV .IF EQ NCTRLR-1 CLR R4 .ENDC .MEXIT .IFF $$$=0 .REPT NCTRLR INTLB \$$$,DEV JSR R5,$INTSE SCBLB \$$$,DEV .IF DF L$$SI1 .WORD PRI .IFF .WORD ^C&PR7 .ENDC .IF GT NCTRLR-$$$-1 BR LAB .ENDC $$$=$$$+1 .ENDR LAB: .ENDC .ENDC GTUCB$ UCBSV,NCTRLR .ENDM ; ; INTERRUPT SAVE GENERATION FOR NON-ERROR LOGGING DEVICES ; .MACRO INTSV$ DEV,PRI,NCTRLR,PSWSV,UCBSV .IF NDF L$$DRV ! M$$MGE ! LD$'DEV .IF GT NCTRLR-1 .IF B MFPS TEMP .IFF MFPS PSWSV .ENDC .IFTF JSR R5,$INTSV  .IF DF L$$SI1 .WORD PRI .IFF .WORD ^C&PR7 .ENDC .IFT .IF B MOV TEMP,R4 .IFF MOV PSWSV,R4 .ENDC BIC #177760,R4 ASL R4 .ENDC .ENDC GTUCB$ UCBSV,NCTRLR .ENDM ; ; GENERATE CODE TO LOAD UCB ADDRESS INTO R5 -- CALLED ; ONLY BY INTSE$ AND INTSV$ ; .MACRO GTUCB$ UCBSV,NCTRLR .IF NB .IF GT NCTRLR-1 MOV UCBSV(R4),R5 .IFF MOV UCBSV,R5 .ENDC .IFF .IF GT NCTRLR-1 MOV CNTBL(R4),R5 .IFF MOV CNTBL,R5 .ENDC .ENDC .ENDM ; ; PROCESSOR STATUS READ/WRITE ; .IF NDF L$$SI1 .MACRO MFPS DST MOVB @#PS,DST .ENDM .MACRO MTPS SRC .IF IDN <#0>, CLRB @#PS .IFF MOVB SRC,@#PS .ENDC .ENDM .ENDC ; ; SAVE NONVOLATILE REGISTERS ; .MACRO SAVNR JSR R5,$SAVNR .ENDM ; ; GENERATE STATUS CONTROL BLOCK REFERENCE LABEL ; .IF DF E$$DVC .MACRO SCBLB NUM,NAM .WORD $'NAM'NUM .ENDM .ENDC ; ; RETURN FROM SUBROUTINE ; .MACRO RETURN RTS PC .ENDM ; ; SOB LOOP INSTRUCTION ; .IF NDF M$$EIS .MACRO SOB A,B DEC A BNE B .ENDM .ENDC ; ; STATE SWITCHING MACRO ; .MACRO SWSTK$ ARG CALL $SWSTK,ARG .ENDM ; ; GET I/O PACKET MACRO -- USED FOR RSX-11M-PLUS COMPATIBILITY ; .MACRO GTPKT$ DEV,NCTRLR,ADDR,UCBSV,SUC CALL $GTPKT .IF B BCC 65535$ RETURN 65535$: .IFF BCS ADDR .ENDC .IF B .IFF .IF GT NCTRLR-1 MOV R5,UCBSV(R3) .IFF MOV R5,UCBSV .ENDC .ENDC .ENDM ; ; GENERATE THE DRIVER DISPATCH TABLE -- DDT (USED FOR RSX-T11M-PLUS COMPATIBILITY) ; .MACRO DDT$ DEV,NCTRLR,INY,INX,UCBSV,NEW $'DEV'TBL:: .IF B .WORD DEV'INI .IFF .WORD DEV'INX .ENDC .WORD DEV'CAN .WORD DEV'OUT .WORD DEV'PWF .IF NB NEW .ERR NEW ; UNSUPPORTED RSX-11M-PLUS FEATURE .ENDC .IF NB UCBSV: .BLKW NCTRLR .ENDC .ENDM .IIF NDF S$$YDF , .LIST T;;È_kQ ›c, .TITLE ISCOM .IDENT /00/ ; ; COPYRIGHT (C) 1975, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 00 ; ; C. A. MONIA 18-JUL-75 ; ; DSS11 DEVICE COMMON BLOCK ; ;+ ; ; **-ISCOM-DSS11 DIGITAL INPUT SUBSYSTEM DEVICE COMMON BLOCK ; ; THIS MODULE DEFINES THE DSS11 DEVICE COMMON BLOCK THAT IS REFERENCED ; WHENEVER A TASK READS DSS11 DIGITAL INPUT POI¨NTS. ; ;- .PSECT ISCOM,RW,GBL,OVR,D .BLKB I$$SSC&77 ; COMPUTE OFFSET FROM 32W BOUNDARY .BLKW I$$SDS*4 ; ALLOCATE SPACE FOR DEVICE REGISTERS .END ¨<;ðskQ ›c, .TITLE ISDRV .IDENT /01.01/ ; ; COPYRIGHT (C) 1975, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 01.01 ; ; C. MONIA 17-JUL-75 ; ; PREVIOUSLY MODIFIED BY: ; ; T. J. MILLER ; ; MODIFIED BY: ; ; T. LEKAS 28-FEB-80 ; TL020 -- SET THE DEVICE OFFLINE IN THE POWERFAIL ; ROUTINE IF THE REGISTERS ARE NOT PRESENT ; ; DRS/DSS11 DIGITAL I/O SUBSYSTEM DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,TCBDF$ HWDDF$ ; DEFINE HARDWARE OFFSETS PKTDF$ ; DEFINE I/O PACKET OFFSETS TCBDF$ ; DEFINE TCB OFFSETS ; ; EQUATED SYMBOLS ; ; INTERRUPT LINK OFFSETS ; .ASECT .=0 ILTE: .BLKW 1 ; ADDRESS OF LINKED TASK ENTRY(0=NONE) ILEVM: .BLKW 1 ; EVENT FLAG MASK ILEVA: .BLKW 1 ; EVENT FLAG ADDRESS ILRUN: .BLKW 1 ; RUN FLAG (1=RUN TASK) ILCSR: .BLKW 1 ; BUS ADDRESS OF CSR REGISTER ILGH: .BLKW 0 ; LENGTH OF INTERRUPT ENTRY ; ; LINKED TASK ENTRY OFFSETS ; .=0 LNEXT: .BLKW 1 ; LINK TO NEXT (0=NONE) LTCB: .BLKW 1 ; TCB ADDRESS OF LINKED TASK LACT: .BLKW 1 ; ACTIVITY COUNT LHWR: .BLKW 1 ; HARDWARE DEPENDANT DATA LLGH: .BLKW 0 ; LENGTH OF ENTRY ; ; ILLEGAL INTERRUPT POINT MASK ; IPMSK=0 .IF NE 16.-I$$S11 IPMSK=100000 .REPT 16.-I$$S11-1 IPMSK=IPMSK/2 .ENDR .ENDC .PSECT ; ; LOCAL DATA ; ; DRIVER DISPATCH TABLE ; $ISTBL::.WORD ISCHK ; DEVICE INITIATOR ENTRY POINT .WORD ISCAN ; CANCEL I/O ENTRY POINT .WORD ISCAN ; DEVICE TIMEOUT ENTRY POINT .WORD ISPWF ; POWER RECOVERY ENTRY POINT ; ; FORK REQUEST FLAG ; .IF DF I$$SLK FORK: .BLKW 1 ; ; ; DIGITAL INTERRUPT LINKED TASK LISTHEAD ; ISLNK: .WORD 0 ; LIST INITIALLY EMPTY .WORD .-2 ; LAST POINTS TO FIRST ; ; DIGITAL INTERRUPT RESOURCE MASK ; ISRES: .WORD 0 ; ALL RESOURCES AVAILABLE INITIALLY. ; ; DIGITAL INTERRUPT LINKAGE TABLE ; ILTBL: ; .IF DF I$$SDR&I$$SDS BUS0=I$$SSC BUS1=I$$SRC REP0=I$$SDS REP1=I$$SDR .IF LT I$$SRC-I$$SSC BUS0=I$$SRC BUS1=I$$SSC REP0=I$$SDR REP1=I$$SDS .ENDC .IFF BUS1=0 REP1=0 .IF DF I$$SDR REP0=I$$SDR BUS0=I$$SRC .IFF REP0=I$$SDS BUS0=I$$SSC .ENDC .ENDC .REPT REP0 .BLKB ILGH-2 .WORD BUS0 BUS0=BUS0+10 .ENDR .REPT REP1 .BLKB ILGH-2 .WORD BUS1 BUS1=BUS1+10 .ENDR .ENDC ; ; DIGITAL OUTPUT PREVIOUS STATE TABLE ; .IF DF I$$SDR ISPRV: .BLKW I$$SDR*3 ; ; ; DIGITAL OUTPUT BUS ADDRESS LIST ; ISBUS: ; ADDR=I$$SRC+2 .REPT I$$SDR .REPT 3 .WORD ADDR ADDR=ADDR+2 .ENDR ADDR=ADDR+2 .ENDR .ENDC ; ; ADDRESS OF UCB ; ISUCB: .BLKW 1 ; ; ; TEMPORARY PSW STORAGE ; TMP: .BLKW 1 ; ;+ ; ; **-ISCHK-DRS/DSS-11 DIGITAL I/O SUBSYSTEM PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM QIO DIRECTIVE PROCESSING WHEN AN ; I/O REQUEST IS RECIEVED FOR THE DRS/DSS-11 DIGITAL INPUT-OUTPUT ; SUBSYSTEMS DEVICES. DRS/DSS-11 REQUESTS CONTAIN PARAMETERS THAT ; MUST BE CHECKED IN THE CONTEXT OF THE ISSUING TASK. THEREFORE ; THE I/O REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET ; R4=ADDRESS OF THE STATUS CONTROL BLOCK ; R5=ADDRESS OF THE UNIT CONTROL BLOCK ; ; OUTPUTS: ; ; DEPENDANT UPON FUNCTION TO BE PERFORMED ; ; DRS/DSS-11 FUNCTION INDEPENDANT I/O PACKET ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF REQUESTER TASK TCB. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE. ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; ;- ISCHK: ; MOV R1,-(SP) ; SAVE I/O PACKET ADDRESS MOV I.TCB(R1),R0 ; GET ADDRESS OF TCB  MOV I.FCN(R1),R2 ; GET FUNCTION CODE BIC #7,R2 ; CLEAR FUNCTION BITS ADD #I.PRM,R1 ; POINT TO PARAMETER BLOCK .IF DF I$$SLK CMP R2,#IO.RAD ; READ ACTIVATING DATA? BEQ ISRAD ; IF EQ YES CMP R2,#IO.LDI ; LINK TO DIGITAL INTERRUPTS? BEQ ISLD ; IF EQ YES CMP R2,#IO.NLK ; UNLINK FROM INTERRUPTS BEQ ISUNL ; IF EQ YES CMP R2,#IO.UDI ; UNLINK FROM DIGITAL INTERRUPTS .ENDC .IF DF I$$SDR&I$$SLK BEQ ISUNL ; IF EQ YES .ENDC .IF DF I$$SDR CMP R2,#IO.MLO ; LATCHING OUTPUT? .IFTF BNE ISIFC ; IF NE NO ILLEGAL FUNCTION ;+ ; ; **-ISLAT-PERFORM BISTABLE DIGITAL OUTPUT ; ; FUNCTION DEPENDANT I/O PACKET FORMAT ; ; WD. 12 -- INITIAL POINT ; WD. 13 -- MASK WORD ; WD. 14 -- DATA WORD ; WD. 15 -- NOT USED ; WD. 16 -- NOT USED ; WD. 17 -- NOT USED ; ;- .IFT ISLAT: ; MOV (R1)+,R2 ; GET POINT NUMBER BIT #17,R2 ; POINT ON MODULE BOUNDARY? BNE ISMOD ; IF NE NO CMP R2,#*48.-1 ; POINT EXIST? BHI ISMOD ; IF HI NO ASR R2 ; CONVERT TO WORD OFFSET ASR R2 ; ... ASR R2 ; ... BIC (R1),ISPRV(R2) ; CLEAR ALL BITS THAT WILL CHANGE STATE COM (R1) ; SET ALL BITS THAT WILL NOT CHANGE BIC (R1)+,(R1) ; CLEAR ALL BITS THAT WILL NOT CHANGE BIS (R1),ISPRV(R2) ; SET NEW PREVIOUS STATE MOV ISPRV(R2),@ISBUS(R2) ; SET NEW MODULE STATE BR ISSUC ; .ENDC ;+ ; ; **-ISUNL-UNLINK A TASK FROM INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT ; ; WD. 12 -- FIRST HALF OF TASK NAME ; WD. 13 -- SECOND HALF OF TASK NAME ; WD. 14 -- NOT USED ; WD. 15 -- NOT USED ; WD. 16 -- NOT USED ; WD. 17 -- NOT USED ; ;- .IF DF I$$SLK ISUNL: ; MOV R1,R3 ; COPY ADDRESS OF PARAMETER BLOCK CALL $SRSTD ; SEARCH FOR TASK TCB ADDRESS BCS ISNLK ; IF C/S TASK NOT INSTALLED MOV #ISLNK,R2 ; GET ADDRESS OF LINKED TASK LISTHEAD 10$: ; MOV R2,R4 ; SAVE ADDRESS OF PREVIOUS FOR RELINK MOV (R2),R2 ; GET ADDRESS OF NEXT BEQ ISNLK ; IF EQ TASK NOT LINKED CMP LTCB(R2),R0 ; ENTRY BELONG TO THIS TASK? BNE 10$ ; IF NE NO MOV #ILTBL,R0 ; GET ADDRESS OF INTERRUPT LINK TABLE MOV #I$$S11,R1 ; GET NUMBER OF DRS/DSS MODULES MOV #1,R3 ; SET 1-BIT MASK 20$: ; CMP (R0),R2 ; TASK LINKED TO THIS INTERRUPT? BNE 30$ ; IF NE NO MOVB #PR4,PS ;;; INHIBIT DEVICE INTERRUPTS CLR (R0) ;;; UNLINK THIS TASK BIC R3,ISRES ;;; FREE UP THE RESOURCE CLR @ILCSR(R0) ;;; DISABLE DEVICE INTERRUPTS CLRB PS ; ALLOW DEVICE INTERRUPTS 30$: ; ADD #ILGH,R0 ; POINT TO NEXT ENTRY ASL R3 ; SHIFT MASK DEC R1 ; DECREMENT DEVICE COUNT BNE 20$ ; IF NE GO AGAIN MOV R2,R0 ; COPY ADDRESS OF BLOCK MOV (R2),(R4) ; RELINK REMAINING ENTRIES BNE 40$ ; IF NE NO NEW LAST MOV R4,ISLNK+2 ; SET NEW LAST 40$: ; MOV #LLGH,R1 ; GET LENGTH OF ENTRY CALL $DEACB ; DEALLOCATE BLOCK ; ; RETURN SUCCESS STATUS ; .IFTF ISSUC: ; MOV #IS.SUC&377,R0 ; BR ISCMN ; ; ; BAD PARAMETER SPECIFIED ; .IFT ISBAD: ; MOV #IE.BAD&377,R0 ; BR ISCMN ; ; ; BUFFER BYTE ALIGNED ; ISBYT: ; MOV #IE.BYT&377,R0 ; BR ISCMN ; ; ILLEGAL EVENT FLAG SPECIFIED ; ISIEF: ; MOV #IE.IEF&377,R0 ; BR ISCMN ; ; ; ILLEGAL FUNCTION CODE ; .IFTF ISIFC: ; MOV #IE.IFC&377,R0 ; BR ISCMN ; ; ; NON-EXISTENT MODULE OR POINT SPECIFIED ; ISMOD: ; MOV #IE.MOD&377,R0 ; BR ISCMN ; ; ; TASK NOT LINKED ; .IFT ISNLK: ; MOV #IE.NLK&377,R0 ; BR ISCMN ; ; ; NO DYNAMIC STORAGE AVAILABLE TO LINK TASK ; ISNOD: ; MOV #IE.UPN&377,R0 ; BR ISCMN ; ;  ; TASK NOT INSTALLED ; ISNST: ; MOV #IE.NST&377,R0 ; BR ISCMN ; ; ; RESOURCE IN USE ; ISRSU: ; MOV #IE.RSU&377,R0 ; BR ISCMN ; ; ; BUFFER OUTSIDE OF TASK'S ADDRESS SPACE ; ISPC: ; MOV #IE.SPC&377,R0 ; ; ; COMMON EXIT FOR ALL FUNCTIONS ; .IFTF ISCMN: ; CLR R1 ; CLEAR CONTENTS OF SECOND I/O STATUS WORD MOV (SP)+,R3 ; GET ADDRESS OF I/O PACKET MOV ISUCB,R5 ; GET UCB ADDRESS CALLR $IOFIN ; COMPLETE REQUEST ; ; BRANCH POINT - LINK TO DIGITAL INTERRUPT ; .IFT ISLD: ; BR ISLDI ; ;+ ; ; **-ISRAD-READ ACTIVATING DATA ; ; FUNCTION DEPENDANT I/O PACKET FORMAT ; ; WD. 12 -- ADDRESS OF 6-WORD BUFFER TO RECEIVE ACTIVATING DATA ; WD. 13 -- UNUSED ; WD. 14 -- UNUSED ; WD. 15 -- UNUSED ; WD. 16 -- UNUSED ; WD. 17 -- UNUSED ; ;- ISRAD: ; BIT #1,(R1) ; BUFFER ALIGNED PROPERLY? BNE ISBYT ; IF NE NO MOV #ISLNK,R4 ; GET ADDRESS OF LINKED TASK LISTHEAD 10$: ; MOV (R4),R4 ; GET LINK TO NEXT BEQ ISNLK ; IF EQ TASK NOT LINKED CMP LTCB(R4),R0 ; THIS TASK LINKED? BNE 10$ ; IF NE NO MOV (R1),R0 ; GET BUFFER ADDRESS .IF DF A$$CHK!M$$MGE MOV #12.,R1 ; GET SIZE REQUIRED CALL $ACHCK ; ADDRESS-CHECK THE BUFFER BCS ISPC ; IF C/S BUFFER OUTSIDE OF TASK SPACE .ENDC .IF DF M$$MGE CALL $RELOM ; RELOCATE AND MAP TO USER SPACE .ENDC ADD #LACT,R4 ; POINT TO THE ACTIVATION COUNT MOVB #PR4,PS ;;; INHIBIT DEVICE INTERRUPTS MOV (R4),(R0)+ ;;; COPY ACTIVATION COUNT CLR (R4)+ ;;; RESET THE COUNT CLR (R0)+ ;;; SET PHYSICAL UNIT TO ZERO MOV #1,(R0)+ ;;; RETURN GENERIC CODE FOR DIGITAL INTERRUPTS CLR (R0)+ ;;; SET MODULE NUMBER TO ZERO MOV (R4),(R0)+ ;;; RETURN MODULE DATA MOV (R4),(R0) ;;; RETURN CHANGE-OF STATE CLRB PS ; ALLOW DEVICE INTERRUPTS BR ISSUC ; ;+ ; ; **-ISLDI-LINK TO DIGITAL INTERRUPTS ; ; FUNCTION DEPENDANT I/O PACKET FORMAT: ; ; WD. 12 -- FIRST HALF OF TASK NAME ; WD. 13 -- SECOND HALF OF TASK NAME ; WD. 14 -- UNUSED ; WD. 15 -- EVENT FLAG NUMBER ; WD. 16 -- MODULE NUMBER (MUST BE ZERO) ; WD. 17 -- CHANGE-OF-STATE MASK ; ;- ISLDI: ; MOV R1,R3 ; COPY ADDRESS OF PARAMETER BLOCK CALL $SRSTD ; SEARCH FOR TCB ADDRESS BCS ISNST ; IF C/S TASK NOT INSTALLED MOV R0,R5 ; SAVE TCB ADDRESS ADD #6,R1 ; POINT TO EVENT FLAG NUMBER MOV (R1)+,R0 ; GET EFN CMP R0,#64. ; LEGAL EVENT FLAG NUMBER? BHI ISIEF ; IF HI NO TST (R1)+ ; LEGAL INITIAL POINT? BNE ISMOD ; IF NE NO MOV (R1),R4 ; GET CHANGE-OF-STATE MASK BEQ ISBAD ; IF EQ BAD PARAMETERS BIT R4,#IPMSK ; DOES POINT EXIST? BNE ISMOD ; IF NE NO BIT R4,ISRES ; RESOURCE AVAILABLE? BNE ISRSU ; IF NE NO MOV R0,-(SP) ; SAVE EVENT FLAG NUMBER MOV #LLGH,R1 ; GET ADDRESS OF LINKED TASK ENTRY CALL $ALOCB ; ALLOCATE BLOCK MOV (SP)+,R3 ; RESTORE EVENT FLAG NUMBER BCS ISNOD ; IF C/S NO DYNAMIC STORAGE MOV R0,-(SP) ; SAVE ADDRESS OF ENTRY MOV R3,R0 ; COPY EVENT FLAG NUMBER CALL $CEFI ; CONVERT TO MASK AND ADDRESS MOV (SP)+,R2 ; RESTORE ADDRESS OF LINKED TASK ENTRY CLR (R2) ; CLEAR LINK TO NEXT MOV R2,@ISLNK+2 ; LINK ENTRY TO LAST MOV R2,ISLNK+2 ; SET NEW LAST TST (R2)+ ; POINT TO TCB ADDRESS MOV R5,(R2)+ ; SET ADDRESS OF TCB CLR (R2)+ ; CLEAR ACTIVATION COUNT MOV #ILTBL-ILGH,R2 ; GET ADDRESS OF INTERRUPT LINK TABLE MINUS OFFSET MOV R4,R3 ; COPY RESOURCE MASK 10$: ; ADD #ILGH,R2 ; POINT TO NEXT ENTRY 20$: ; ROR R3 ; ROTATE MASK BCS 30$ ; IF C/S LINK THIS MODULE BNE 10$ ; IF NE GO AGAIN BR 40$ ; ELSE TESTED ALL ENTRIES 30$: ; MOV ISLNK+2,(R2)+ ; ALLOCATE THIS RESOURCE MOV R0,(R2)+ ; SET EVENT FLAG MASK MOV R1,(R2)+ ; SET EVENT FLAG ADRESS CLR (R2)+ ; CLEAR RUN FLAG BIS #100,@(R2)+ ; ENABLE DEVICE INTERRUPTS BR 20$ ; GO AGAIN 40$: ; BIS R4,ISRES ; ALLOCATE ALL REQUESTED BITS JMP ISSUC ; ;+ ; ; **-$ISINT-DRS/DSS11 INTERRUPT SERVICE ROUTINE ; ;- .IFTF $ISINT:: ;;; .IFF RTI ;;; IGNORE SPURIOUS INTERRUPT .IFT MOVB PS,TMP ;;; SAVE PROCESSOR STATUS WORD CALL $INTSV,PR4 ;;; SAVE R4-R5, SET PRIORITY MOV TMP,R5 ;;; GET PS WORD BIC #^C<17>,R5 ;;; CLEAR ALL BUT DEVICE NUMBER CMP R5,#I$$S11 ;;; LEGAL DEVICE NUMBER BHIS ISCAN ;;; IF HI NO EXIT ISR ASL R5 ;;; CONVERT TO WORD OFFSET MOV $BTMSK(R5),R4 ;;; GET CORRESPONDING BIT MASK MOV R5,-(SP) ;;; COPY WORD OFFSET ASL R5 ;;; CONVERT TO INTERRUPT LINK TABLE OFFSET ASL R5 ;;; ... ADD (SP)+,R5 ;;; ADD #ILTBL,R5 ;;; COMPUTE ENTRY ADDRESS TST @ILCSR(R5) ;;; RESET INTERRUPT REQUEST BIT R4,ISRES ;;; RESOURCE ALLOCATED BEQ ISCAN ;;; IF EQ NO INC ILRUN(R5) ;;; SET RUN FLAG MOV (R5),R5 ;;; GET ADDRESS OF LINKED TASK ENTRY ADD #LACT,R5 ;;; POINT TO ACTIVITY COUNT TST (R5) ;;; PREVIOUS DATA READ BY TASK BNE 10$ ;;; IF NE NO INC (R5)+ ;;; SET ACTIVATION COUNT MOV R4,(R5) ;;; RECORD MODULE DATA BR 30$ ;;; 10$: ;;; BMI 20$ ;;; IF MI TASK ALREADY MISSED ONE COUNT CLR (R5) ;;; SET COUNT TO ZERO 20$: ;;; DEC (R5)+ ;;; DECREMENT COUNT BIS R4,(R5) ;;; MERGE MODULE DATA 30$: ;;; TST FORK ;;; FORK PENDING? BNE ISCAN ;;; IF NE YES INC FORK ;;; SET FORK PENDING MOV ISUCB,R5 ;;; GET ADDRESS OF UCB CALL $FORK ;;; CREATE A SYSTEM PROCESS CLR FORK ; CLEAR FORK-PENDING MOV #I$$S11,R5 ; GET NUMBER OF DRS/DSS INSTALLED MOV #ILTBL,R4 ; GET ADDRESS OF INTERRUPT LINK TABLE 40$: ; TST (R4) ; ANY TASK LINKED? BEQ 70$ ; IF EQ NO TST ILRUN(R4) ; RUN FLAG SET BEQ 70$ ; IF EQ NO CLR ILRUN(R4) ; RESET RUN FLAG MOV (R4),R0 ; GET ADDRESS OF LINKED TASK ENTRY MOV LTCB(R0),R0 ; GET TCB ADDRESS MOV T.STAT(R0),R1 ; COPY TASK STATUS WORD BIT #TS.EXE,R1 ; TASK ACTIVE? BNE 60$ ; IF NE NO BIT #T2.ABO,T.ST2(R0) ; TASK BEING ABORTED? BNE 70$ ; IF NE YES BIT #TS.OUT,R1 ; TASK OUT OF MEMORY? BEQ 50$ ; IF EQ NO BIT #TS.CKP,R1 ; TASK CHECKPOINTED? BEQ 70$ ; IF EQ NO 50$: ; MOV ILEVA(R4),R2 ; GET ADDRESS OF EVENT FLAG MASK BEQ 70$ ; IF EQ NONE SPECIFIED BIS ILEVM(R4),(R2) ; SET EVENT FLAG CALL $SETCR ; ISSUE CONDITIONAL SCHEDULE REQUEST BR 70$ ; GO AGAIN 60$: ; CLR R1 ; SET DEFAULT UIC CALL $TSKRT ; REQUEST TASK 70$: ; ADD #ILGH,R4 ; POINT TO NEXT INTERRUPT LINK ENTRY DEC R5 ; DECREMENT MODULE COUNT BNE 40$ ; IF NE GO AGAIN .IFTF ;+ ; ; **-ISCAN-CANCEL I/O AND DEVICE TIMEOUT ENTRY POINT ; ;- ISCAN: ;;; RETURN ;;; ;+ ; ; **-ISPWF-DEVICE DEPENDANT POWER RECOVERY CODE ; ; THIS CODE IS ENTERED TO RESTORE THE STATE OF ALL INTERRUPT ENABLE BITS AND ; LATCHING OUTPUTS UPON POWER RECOVERY. ; ;- ISPWF: ; CALL $SGFIN ; COROUTINE TO SET CARRY IF A TRAP ;TL020 ; THROUGH 4 (NONEXISTANT MEMORY) ;TL020 ; OCCURS ;TL020 MOV R5,ISUCB ; SAVE THE UCB ADDRESS .IFT MOV #ILTBL,R0 ; GET ADDRESS OF INTERRUPT LINK TABLE MOV #I$$S11,R1 ; SET NUMBER OF MODULES 10$: ; TST (R0) ; TASK LINKED? BEQ 20$ ; IF EQ NO BIS #100,@ILCSR(R0) ; ENABLE MODULE INTERRUPTS BCS 40$ ; BRANCH IF THE REGISTER WASN'T THERE ;TL020 20$: ; ADD #ILGH,R0 ; POINT TO NEXT ENTRY DEC R1 ; DECREMENT MODULE COUNT BNE 10$ ; IF NE GO AGAIN .ENDC .IF DF I$$SDR&I$$SPW MOV #ISPRV,R0 ; GET ADDRESS OF PREVIOUS STATE TABLE MOV #ISBUS,R1 ; GET ADDRESS OF BUS VECTOR TABLE MOV #I$$SDR*3,R2 ; GET COUNT OF ADDRESSES TO REFRESH CLC ; CLEAR CARRY FOR $SGFIN ;TL020 30$: ; MOV (R0)+,@(R1)+ ; REFRESH BISTABLE OUTPUTS BCS 40$ ; BRANCH IF THE REGISTER WASN'T THERE ;TL020 DEC R2 ; DECREMENT ADDRESS COUNT BNE 30$ ; IF NE GO AGAIN .ENDC 35$: RETURN ; ;TL020  ;TL020 ; ;TL020 ; THE UNIT IS SET OFFLINE IF ANY OF THE DEVICE REGISTERS DO NOT ;TL020 ; EXIST ;TL020 ; ;TL020 40$: BISB #US.OFL,U.ST2(R5) ; SET UNIT OFFLINE ;TL020 BR 35$ ; RETURN ;TL020 ;**-1 .END ¼LðskQ ›c, .TITLE LKDRV .IDENT /01.04/ ; ; COPYRIGHT (C) 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 01.04 ; ; B. S. MCCARTHY 22-MAR-78 ; B. SCHREIBER 14-SEP-78 ; ; ; MODIFIED BY: ; ; B. S. MCCARTHY 21-NOV-78 ; ; BM002 -- CORRECT SENSE OF 'LS11' BIT ; ; B. S. MCCARTHY 26-SEP-79 ; ; BM038 -- RELEASE KMC BEFORE CALLING FORK ; ; B. S. MCCARTHY 29-NOV-79 ; ; BM055 -- CLOSE TIMING WINDOW OPENED BY BM038 ; ; R. T. PERRON 22-MAY-81 ; ; RP058 -- CONDITIONALIZE SUPPORT TO PASS RUBOUTS/NULLS ; ; LP11/LS11 LINE PRINTER CONTROLLER DRIVER ; FOR USE WITH COMM-IOP-LP OPTION ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$, HWDDF$, PKTDF$, UCBDF$ ABODF$ ; DEFINE TASK ABORT CODES HWDDF$ ; DEFINE HARDWARE REGISTERS PKTDF$ ; DEFINE I/O PACKET OFFSETS UCBDF$ ; DEFINE UCB OFFSETS .PAGE ; LOCAL DATA BIT DEFINITIONS ; SOME OF THESE DEFINITIONS ARE INCLUDED FOR INFORMATION ONLY ; AND ARE NOT REFERENCED IN THE DRIVER ; LINE PRINTER STATUS WORD BIT DEFINITIONS (U.CW2) LS11 = 100000 ; LS11 PRINTER (1=YES) LOWER = 40000 ; PRINTER KNOWN TO KMC-11 (1=YES) ABRT = 20000 ; ABORT ISSUED PWRFLG = 10000 ; POWER FAIL RECOVERY IN PROGRESS RQINPR = 4000 ; REQUEST IN PROGRESS WHEN POWER FAILED KNOWN = 2000 ; PRINTER KNOWN TO KMC-11 (1=YES) ; LINE PRINTER WIDTH KNOWN TO KMC (LOW BYTE OF U.CW3) SAVWID = 377 ; CURRENT SET WIDTH IN LOW BYTE ; KMC-11/COMM-IOP-LP BIT DEFINITIONS ; KMC CSR WORD 0 (SEL0) RUN = 100000 ; RUN BIT (1=KMC RUNNING) MC = 40000 ; MASTER CLEAR (SET TO 1 TO CLEAR KMC) RQI = 200 ; REQUEST INPUT (SET TO REQUEST KMC INPUT_ IEO = 20 ; OUTPUT INTERRUPT ENABLE (SET TO ENABLE) IEI = 1 ; INPUT INTERRUPT ENABLE (SET TO ENABLE) ; KMC CSR WORD 1 (SEL2) PRTNUM = 3400 ; PRINTER NUMBER MASK RDYO = 200 ; READY OUTPUT (1=READY) RDYI = 20 ; READY INPUT (1=READY) FNCBSI = 3 ; BASE IN FUNCTION FNCCTI = 1 ; CONTROL IN FUNCTION FNCBAI = 0 ; BASE IN FUNCTION ; KMC CSR WORD 2 (SEL4) POLCNT = 177400 ; POLLING COUNT FOR BASE IN FUNCTION ; KMC CSR WORD 3 (SEL6) KOPKOE = 200 ; KILL ON ERROR OPTION (FOR CONTROL IN) KOPNXT = 40 ; DON'T EXPAND TABS OPTION KOPVTL = 20 ; CONVERT VT TO LF OPTION KOPDRN = 10 ; DISCARD RUBOUTS/NULLS OPTION KOPDNP = 4 ; DISCARD NON-PRINTING CHARACTERS OPTION KOPLUC = 2 ; CONVERT LOWER TO UPPER CASE OPTION KOPFPR = 1 ; FAST PRINTER OPTIMIZATIONS OPTION KMCABF = 10 ; KILL (ABORT) FINISHED ON CONTROL OUT KMCNXM = 6 ; NON-EXISTENT MEMORY (WE CAN'T GET THIS?) KMCONL = 4 ; PRINTER ERROR CONDITION CLEAR KMCOFL = 2 ; PRINTER ERROR OCCURED (PAPER JAM,ETC.) BEXT = 140000 ; BUS EXTENSION BITS FOR BUFF. ADDR. IN KILASN = 20000 ; KILL ASSIGN BIT KILL = 10000 ; KILL BIT ; BUFFER DESCRIPTOR BITS LASTBF = 100000 ; LAST DESCRIPTOR IN LIST ; ; RP058 ; DEFINE THE SYMBOL "L$$PRN" EITHER IN THE RSXMC.MAC CONDITIONAL ; RP058 ; ASSEMBLY FILE FOR YOUR SYSTEM OR REMOVE THE SEMICOLON (;) FROM ; RP058 ; THE LINE CONTAINING THE SYMBOL IN THE KMC LINE PRINTER DRIVER ; RP058 ; (LKDRV). ; RP058 ;  ; RP058 ;L$$PRN=0 ;SYMBOL TO PASS RUBOUTS/NULLS ; RP058 ; ; RP058 ; LOCAL DATA LDNAM: .RAD50 /LPINIT/ ; MICROCODE LOADER TASK NAME PWFCNT: .WORD 0 ; POWERFAIL INITIALIZATION COUNT KMCSR2: .WORD 0 ; KMC-11 CSR ADDRESS +2 ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW L$$P11 ;ADDRESS OF UNIT CONTROL BLOCK .PAGE ; ; DRIVER DISPATCH TABLE ; $LPTBL::.WORD LKINI  ;DEVICE INITIATOR ENTRY POINT .WORD LKCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD LKOUT ;DEVICE TIMEOUT ENTRY POINT .WORD LKPWF ;POWERFAIL ENTRY POINT .PAGE ;+ ; **-LKINI-LP11/LS11 LINE PRINTER CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB LKINI: CALL $GTPKT ; GET AN I/O PACKET TO PROCESS BCS 25$ ; IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; LINE PRINTER I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- CARRIAGE CONTROL BYTE. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; .PAGE MOV R5,CNTBL(R3) ; SAVE ADDRESS OF REQUEST UCB BIC #ABRT,U.CW2(R5) ; CLEAR REQUEST ABORTED .IF DF M$$MGE&M$$EXT CALL $STMAP ; SETUP UNIBUS MAP .ENDC ; M$$MGE&M$$EXT ; TEST TO SEE IF KMC KNOW'S ABOUT THIS PRINTER ; AND ISSUE BASE IN IF NECESSARY LKIN1: BIT #KNOWN,U.CW2(R5) ; PRINTER KNOWN ? BNE 10$ ; IF NE YES CALL WTKMC ; WAIT FOR KMC READY MOV U.KCS6(R5),R0 ; POINT TO LAST REGISTER OF KMC MOV S.CSR(R4),(R0) ; FILL IN CSR ADDRESS MOV #L$$KPC*256.,-(R0) ; SET UP POLLING COUNT CLR R4 ; SCRATCH FOR UNIT/FUNCTION BISB U.UNIT(R5),R4 ; SET UNIT NUMBER SWAB R4 ; PUT IT IN HIGH BYTE BIS #FNCBSI,R4 ; SET BASE IN FUNCTION MOV R4,-(R0) ; AND ISSUE FUNCTION MOV U.SCB(R5),R4 ; RESTORE SCB ADDRESS BIS #KNOWN,U.CW2(R5) ; SET PRINTER KNOWN ; TEST TO SEE IF PRINTER HAS BEEN INITIALIZED FOR CORRECT WIDTH ; (CURRENT SET WIDTH IN U.CW3) 10$: CMPB U.CW4(R5),U.CW3(R5) ; BUF SIZE CURRENT WIDTH ? BEQ 20$ ; IF EQ YES, CONTROL IN WAS ISSUED CALL WTKMC ; WAIT FOR KMC READY MOV U.KCS6(R5),R0 ; POINT TO END OF REGISTERS. ; RP058 ; RP058 .IF NDF L$$PRN ; RP058 ; RP058 MOV #KOPDRN,R4 ; SET FUNCTION TO DISCARD RUBOUTS/NULLS ; RP058 ; RP058 .IFF ; RP058 ; RP058 CLR R4 ; SET FUNCTION TO PASS RUBOUTS/NULLS ; RP058 ; RP058 .ENDC ; RP058 ; RP058 ; RP058 BIT #LOWER,U.CW2(R5) ; LOWER CASE PRINTER ;**-1 BNE 11$ ; IF NE YES, OK BIS #KOPLUC,R4 ; SET LOWER TO UPPER CASE SUPPORT 11$: ; REF LABEL .IF DF L$$11R BIT #LS11,U.CW2(R5) ; FAST PRINTER ? BNE 12$ ; IF NE NO BIS #KOPFPR,R4 ; SET FAST PRINTER OPTIMIZATIONS .ENDC ; DF L$$11R 12$: MOV R4,(R0) ; SET OPTIONS WORD MOV U.CW4(R5),-(R0) ; SET PRINTER WIDTH CLR R4 ; SCRATCH FOR UNIT NUMBER/FUNCTION BISB U.UNIT(R5),R4 ; SET IN UNIT NUMBER SWAB R4 ; PUT IT IN HIGH BYTE BIS #FNCCTI,R4 ; SET CONTROL IN FUNCTION MOV R4,-(R0) ; ISSUE FUNCTION MOV U.SCB(R5),R4 ; RESTORE SCB ADDRESS MOVB U.CW4(R5),U.CW3(R5) ; SET PRINTER SIZE SET .PAGE ; BUILD ADDRESS BUFFER IN I/O PACKET AND ISSUE REQUEST 20$: ; REFERENCE LABEL .IF DF M$$MGE & M$$EXT MOV R1,-(SP) ; SAVE I/O PACKET ADDRESS CALL $MPUBM ; MAP UNIBUS TO MEMORY MOV (SP)+,R1 ; RESTORE I/O PACKET ADDRESS .ENDC ; M$$MGE & M$$EXT CALL WTKMC ; WAIT FOR KMC READY MOV U.BUF+2(R5),I.PRM+10(R1) ; SET LOW PART OF BUFFER ADDR. MOV U.CNT(R5),I.PRM+12(R1) ; AND LENGTH OF BUFFER MOV U.BUF(R5),R0 ; GET HIGH TWO BITS OF ADDR. SWAB R0 ; PUT IN HIGH BYTE ASR R0 ; SHIFT INTO BITS 10/11 ASR R0 ; BIS #LASTBF,R0 ; SET FOR LAST FUNCTION BISB I.PRM+6(R1),R0 ; SET VFC BITS IN MOV R0,I.PRM+14(R1) ; STORE INTO BUFF ADDR DESC. ; BUFFER DESCRIPTOR BUILT IN WORDS 4,5,6 OF PARAM LIST MOV U.KCS6(R5),R0 ; POINT TO LAST ADDRESS OF KMC CLR (R0) ; CLEAR OUT KILL BITS MOV R1,R4 ; COPY PACKET ADDRESS ADD #I.PRM+10,R4 ; POINT TO BUFFER DESCRIPTOR MOV R4,-(R0) ; FILL IN BUFFER ADDRESS CLR R4 ; SCRATCH FOR UNIT NUMBER BISB U.UNIT(R5),R4 ; SET IN UNIT NUMBER SWAB R4 ; PUT IT IN HIGH BYTE MOV R4,-(R0) ; AND START TRANSFER 25$: RETURN ; EXIT FROM DRIVER .PAGE ; ; POWERFAIL PROCESSING MARKS A DEVICE AS UNKNOWN AND OF UNKNOWN ; WIDTH. THE CONTROLLER IS MARKED AS BUSY EVEN IF IT IS IDLE, TO ; PREVENT EARLY DEQUEUEING OF REQUESTS. A TIMEOUT IS FORCED IN 5 ; SECONDS, AND THE MICROCODE LOADER (LPINIT) IS REQUESTED. IF ; LPINIT IS NOT INSTALLED AN ERROR MESSAGE IS ISSUED. WHEN ; THE TIMEOUT OCCURS WE CHECK TO SEE IF THE KMC IS RUNNING. ; LKPWF: BIS #PWRFLG,U.CW2(R5) ; SET POWERFAIL IN PROGRESS TST CNTBL(R3) ; REQUEST IN PROGRESS BEQ LKPWF0 ; IF EQ NO BIS #RQINPR,U.CW2(R5) ; SET REQUEST IN PROGRESS FLAG LKPWF0: BIC #KNOWN,U.CW2(R5) ; SET PRINTER UNKNOWN CLRB U.CW3(R5) ; AND SET WIDTH TO 0 (FORCING ZERO) BISB #US.KPF!US.BSY,U.STS(R5) ; SET POWERFAIL INTERLOCK MOVB #1,S.STS(R4) ; FAKE CONTROLLER BUSY MOVB #5,S.CTM(R4) ; FORCE 5 SECOND TIMEOUT DEC PWFCNT ; IS THIS FIRST PRINTER ? BLT 30$ ; IF LT YES, INVOKE REST OF POWERFAIL RETURN ; ELSE EXIT FROM DRIVER 30$: MOV #L$$P11-1,PWFCNT ; SET UP COUNT OF REST OF PRINTERS MOV U.KCSR(R5),R0 ; GET CSR ADDRESS OF PRINTER MOV #MC,(R0)+ ; MASTER CLEAR KMC-11 MOV R0,KMCSR2 ; SAVE ADDRESS OF SECOND CSR ; REQUEST MICROCODE LOADER IF INSTALLED MOV #LDNAM,R3 ; GET NAME OF MICROCODE LOADER CALL $SRSTD ; LOOK IT UP BCS 40$ ; IF CS NOT THERE, ISSUE MESSAGE CALLR $EXRQN ; REQUEST LOADER 40$: MOV #T.NKLF,R0 ; MESSAGE NUM "MICROCODE LOADER NOT ..." CALLR $DVMSG ; PRINT MESSAGE AND EXIT .PAGE ;+ ; **-$LPINT-LP11/LS11 LINE PRINTER CONTROLLER INTERUPTS ; (INTERRRUPTS ARE FROM COMM IOP, NOT PRINTER) ; ; INPUT INTERRUPTS SHOULD NOT OCCUR, AND ARE THEREFORE ; DISMISSED IMMEDIATELY. ; ; OUTPUT INTERRUPTS ARE CAUSED FOUR WAYS: ; ; 1) - BUFFER ADDRESS OUT - INDICATES SUCCESSFUL COMPLETION ; OF AN OUTPUT OPERATION ; 2) - CONTROL OUT - KMCABF SET IN KCS3 - ABORT COMPLETED ; 3) - CONTROL OUT - KMCONL SET IN KCS3 - PREVIOUS ERROR CLEARED ; 4) - CONTROL OUT - OTHER - ERROR CONDITION ON PRINTER ;- $LPINP:: ; IGNORE INPUT INTERRUPTS ; ($LPINP IS NEEDED TO MAKE DRIVER LOAD ; CORRECTLY) .IF NDF L$$DRV ! M$$MGE ! LD$LP  RTI .IFF RETURN .ENDC .PAGE $LPOUT:: ;;; REF LABEL .IF NDF L$$DRV ! M$$MGE ! LD$LP JSR R5,$INTSV ;;; SINCE THERE'S ONE KMC VECTOR, .WORD ^C&PR7 ;;; NORMAL UCB CALC. DOESN'T WORK .ENDC MOV @KMCSR2,R4 ;;; GET PRINTER NUMBER FROM KMC BIC #^C,R4 ;;; STRIP OFF JUNK SWAB R4 ;;; INTO LOW HALF OF REG ASL R4 ;;; AND CREATE WORD INDEX MOV CNTBL(R4),R5 ;;; GET UCB ADDRESS BEQ 90$ ;;; IF EQ DISMISS SPURIOUS INTERRUPT MOV KMCSR2,R4 ;;; GET ADDRESS OF KMC CSR ; BM038 MOV 4(R4),R4 ;;; GET PRINTER ERROR CODE ; BM038 SWAB R4 ;;; PUT INTO HIGH BYTE ; BM038 CLRB R4 ;;; CLEAR OUT LOW BYTE ; BM038 BISB @KMCSR2,R4 ;;; AND MERGE IN INTERRUPT CAUSE ; BM038 BIC #IEO,@U.KCSR(R5) ;;; DISABLE KMC INTERRUPTS ; BM055 BIC #RDYO,@KMCSR2 ;;; RELEASE KMC ; BM038 CALL $FORK ;;; CREATE A SYSTEM PROCESS ; BM038 BIS #IEO,@U.KCSR(R5) ; RE-ENABLE KMC INTERRUPTS ; BM055 MOV R4,R0 ; COPY INTERRUPT CAUSE ; BM038 MOV R4,R1 ; COPY POSSIBLE ERROR BYTE ; BM038 SWAB R1 ; AND MOVE IT TO LOW BYTE ; BM038 MOV U.SCB(R5),R4 ; GET SCB ; BM038 BIT #1,R0 ; WAS IT A CONTROL OUT ? ;**-7 BNE 70$ ; IF NE YES MOV #IS.SUC,R0 ; SET SUCCESS STATUS 60$: MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS MOV I.PRM+4(R1),R1 ; GET REQUESTED BYTE COUNT CALL $IODON ; FINISH I/O OPERATION MOV U.SCB(R5),R4 ; GET SCB ADDRESS MOVB S.CON(R4),R4 ; AND CONTROLLER INDEX CLR CNTBL(R4) ; CLEAR UCB TABLE ENTRY JMP LKINI ; AND START DRIVER AGAIN 70$: CMPB #KMCABF,R1 ; ABORT FINISHED ? BNE 80$ ; IF EQ NO 75$: MOV #IE.ABO,R0 ; SET ABORT STATUS BR 60$ ; AND OUT NORMALLY 80$: CMPB #KMCONL,R1 ; PRINTER BACK NOW ? BNE LKOUT ; IF EQ NO, MUST BE ERROR RETURN ; ELSE YES, THAT'S NICE. 90$: BIC #RDYO,@KMCSR2 ; RELEASE KMC RETURN ; AND EXIT FROM DRIVER .PAGE ; ; TIMEOUT PROCESSING IS ENTERED FOR ANY OF THE FOLLOWING ; ; 1. 5 SECONDS AFTER POWER FAIL RECOVERY (ALSO LOAD,BOOT) ; THE DRIVER IS ENTERED AND TESTS TO SEE IF RECOVERY ; IS COMPLETE. IF IT IS, THE DRIVER STARTS OR RESTARTS ; AN OPERATION AS NECESSARY. IF NOT, THE TIMEOUT COUNT ; IS RESET TO 5 AND THE DRIVER EXITS. ; ; 2. FOLLOWING AN IO.KIL, IF THE REQUEST IS NOT COMPLETED ; NORMALLY BEFORE THE NEXT TIMEOUT CHECK, THEN A HARDWARE ; ABORT IS ISSUED HERE. ; ; 3. AFTER A DEVICE ERROR, THE TIMEOUT SECTION TAKES CARE OF ; ISSUING NOT READY MESSAGES. ; LKOUT: MTPS #0 ;;;ALLOW INTERRUPTS BIT #PWRFLG,U.CW2(R5) ; POWERFAIL RECOVERY IN PROGRESS ? BEQ 99$ ; IF EQ NO BITB #US.KPF,U.STS(R5) ; KMC RECOVERY COMPLETE ? BEQ 93$ ; IF EQ YES MOVB #5,S.CTM(R4) ; BETTER LUCK NEXT TIME RETURN ; (IN 5 SECONDS OR SO) 93$: BIC #PWRFLG,U.CW2(R5) ; CLEAR POWERFAIL FLAG BIT #ABRT,U.CW2(R5) ; ABORT REQUESTED ? BNE 75$ ; IF EQ YES, BUT REQUEST IS ALREADY ; ABORTED (AND HOW) DUE TO KMC FAILURE BIT #RQINPR,U.CW2(R5) ; REQUEST IN PROGRESS WHEN WE WENT DOWN ? BEQ 96$ ; IF NE NO BIC #RQINPR,U.CW2(R5) ; CLEAR REQUEST IN PROGRESS MOV S.PKT(R4),R1 ; RESTORE I/O PACKET ADDRESS JMP LKIN1 ; AND RESTART REQUEST 96$: CLRB S.STS(R4) ; CLEAR FAKE CONTROLLER BUSY BICB #US.BSY,U.STS(R5) ; AND DECLARE UNIT IDLE JMP LKINI ; TRY TO ACTIVATE CONTROLLER 99$: BIT #ABRT,U.CW2(R5) ; ABORT REQUESTED ? BEQ 100$ ; IF NE NO CALL WTKMC ; WAIT TILL IT'S READY MOV U.KCS6(R5),R0 ; POINT TO LAST CSR MOV #KILL,(R0) ; SET KILL FUNCTION CLR -(R0) ; NO BUFF ADDR CLR R1 ; SCRATCH FOR PRINTER NUMBER BISB U.UNIT(R5),R1 ; SET IN UNIT NUMBER SWAB R1 ; PUT IT IN HIGH BYTE MOV R1,-(R0) ; FILL IN PRINTER NUMBER AND START KILL RETURN ; WAIT TIL IT'S ALL OVER .PAGE ; PROCESS DEVICE NOT READY MESSAGES 100$: ; REF LABEL .IF DF T$$KMG MOV #T.NDNR,R0 ; SET FOR DEVICE NOT READY MESSAGE .IFTF ; DF T$$KMG MOVB #1,S.CTM(R4) ; SET TIMEOUT FOR 1 SECOND .IFT ; DF T$$KMG DECB S.STS(R4) ; TIME TO OUTPUT MESSAGE ? BNE 120$ ; IF NE NO .IF NDF L$$PTO MOVB #15.,S.STS(R4) ; SET TO OUTPUT NEXT MESSAGE IN ; 15. SECONDS .IFF ; NDF L$$PTO MOVB #L$$PTO,S.STS(R4) ; SET TO OUTPUT NEXT MESSAGE IN ; L$$PTO SECONDS BNE 110$ ; IF NE LP NOT READY MESSAGES ENABLED INCB S.STS(R4) ; LP NOT READY MESSAGE NOT WANTED, SO BR 120$ ; RE-BUSY CONTROLLER .ENDC ; NDF L$$PTO 110$: CALLR $DVMSG ; OUTPUT MESSAGE .ENDC ; DF T$$KMG 120$: RETURN ; OUT ! .DSABL LSB .PAGE ; ; CANCEL I/O OPERATION-FORCE I/O TO COMPLETE IF DEVICE IS NOT READY ; LKCAN: CMP R1,I.TCB(R0) ;;; REQUEST FOR CURRENT TASK? BNE 10$ ;;; IF NE NO BIS #ABRT,U.CW2(R5) ;;; SET FOR ABORT IF DEVICE NOT READY MOVB #1,S.CTM(R4) ;;; FORCE TIMEOUT IN 1 SECOND (OR LESS) 10$: RETURN ;;; ; ; SUBROUTINE TO WAIT FOR THE KMC TO BE READY ; ; INPUTS: ; ; R5 = UCB ADDRESS OF THE PRINTER ; ; R0 IS DESTROYED. WTKMC: MOV U.KCSR(R5),R0 ; G¼ET KMC CSR ADDRESS BIS #RQI,(R0) ; REQUEST KMC INPUT 10$: TST (R0) ; IS THE KMC-11 RUNNING ? BPL 20$ ; IF IT CAN'T TAKE A JOKE, POWERFAIL BIT #RDYI,@KMCSR2 ; READY BIT SET ? BEQ 10$ ; IF EQ NO, WAIT SOME MORE BIC #RQI,(R0) ; CLEAR REQUEST INPUT RETURN ; YES, BO BACK 20$: BIS #PWRFLG!RQINPR,U.CW2(R5) ; SET POWERFAIL IN PROGRESS TST (SP)+ ; WE WON'T BE RETURNING TO CALLER JMP LKPWF0 ; FINISH IN COMMON CODE .END ¼¬˜ðskQ ›c, .TITLE XQDRV .IDENT /03.3/ ; ; COPYRIGHT (C) 1974, 1976, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 03.3 ; ; EARL D. WALDIN 10-MAR-75 ; ; PREVIOUSLY MODIFIED BY: ; ; L. GILLESPIE ; E. D. WALDIN ; ; MODIFIED BY: ; ; B. SCHREIBER 30-JUN-78 ; ; BLS056 -- CORRECT UMR ALLOCATION HANDLING ; ; C. SPITZ 9-AUG-78 ; ; CS015 -- CORRECT HANDLING OF I/O KILLS ; ; R. E. CALDWELL 29-OCT-79 ; ; RC024 -- REMOVE UNNEEDED CONDITIONALIZATION. ; ; ; DQ11 SYNCHRONOUS COMMUNICATIONS DRIVER ; ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,CLKDF$,HWDDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS CLKDF$ ;DEFINE CLOCK QUEUE PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ; EQUATED SYMBOLS ; ; ; RXCSR BIT ASSIGNMENTS ; RXGO= 1 ;RECEIVE GO, SET TO START RECEIVER STRSYN= 2 ;STRIP SYNC CHARACTERS WHEN SET RXPS= 4 ;RX PRIMARY OF SECONDARY REG ACTIVE(0=PR) HDPX= 10 ;HALF DUPLEX IF SET RXDNIE= 40 ;RECEIVER DONE INTERRUPT ENABLE RXDNP= 200 ;RECEIVE PRIMARY REGISTER DONE RXDNS= 100 ;RECEIVE SECONDARY REGISTER DONE RXACT= 10000 ;RECEIVER ACTIVE FLAG RXDIS= RXDNIE!RXDNP!RXDNS ;DISABLE RECIEVER MASK ; ; TXCSR BIT ASSIGN ; TXGO= 1 ;TRANSMIT GO IDLSYN= 2 ;IDLE SYNC MODE BIT TXPS= 4 ;TX PRI OF SEC REG ACTIVE (0=PRI) ERRIE= 10 ;ERROR INTERRUPT ENABLE DTSIE= 20 ;DATA SET INTR ENABLE TXDNIE= 40 ;TX DONE INTR ENABLE TXDNP= 200 ;TX DONE PRIMARY REG TXDNS= 100 ;TX DONE SECONDARY REG RTS= 400 ;REQUEST TO SEND DTR= 1000 ;DATA TERMINAL READY DSR= 2000 ;DATA SET READY CTS= 20000 ;CLEAR TO SEND WHEN SET DSFLG= 100000 ;DATA SET FLG (RI!CTS!SQDT) TXDISF= ^C ;TX DISABLE FOR FULL DUPLEX TXDISH= ^C ;TX DISABLE FOR HALF DUPLEX TXNDIS= TXDISF&<^CERRIE> ;TX NETWORK DISABLE ; ;REG/ERR REGISTER BIT ASSIGNMENTS ; ERRINT= 100000 ;ERROR INTERRUPT WRTEN= 20 ;WRITE ENABLE BIT FOR EXTENSION BITS TEXIT= 60 ;EXIT TRANSPARENCY BITS TENTR= 120 ;ENTER TRANSPARENCY BITS CCRG= 1!WRTEN ;CCRG!= COUNT REG TXCLK= 1 ;TX CLOCK LOSS ERROR TXLAT =4 ;TX BUSS LATENCY ERROR TXNEX= 20 ;TX NON EXISTENT MEMORY ERROR RXCLK= 2 ;RX CLOCK LOSS ERROR RXLAT= 10 ;RX BUS LATENCY ERROR RXNEX= 40 ;RX NON EXISTENT MEMORY ERROR BCCERR=100 ;BCC (RX) ERROR BIT TXERR=TXCLK!TXLAT!TXNEX ;OR OF TRANSMIT ERROR BITS RXERR=RXCLK!RXLAT!RXNEX!BCCERR ;OR OF RECEIVE ERROR BITS ; ;MISC SECONDARY REGISTER BIT ASSIGNMENTS ; TXACT= 40000 ;=1 WHEN TX IS ACTIVE MSCLR=40 ;MASTER CLEAR ; ; SECONDARY REGISTER ADDRESS ASSIGNMENTS ; RXBAP= 0 ;RX BUS ADDR PRIMARY REG RXCCP= 1 ;RX CHAR COUNT PRIMARY TXBAP= 2 ;TX BUS ADDR PRIMARY TXCCP= 3 ;TX CHAR COUNT PRIMARY RXBAS= 4 ;RX BUS ADDR SECONDARY RXCCS= 5 ;RX CHAR COUNT SECONDARY TXBAS= 6 ;TX BUS ADDR SECONDARY TXCCS= 7 ;TX CHAR COUNT SECONDARY SYNREG= 4400 ;SYNC CHAR REGISTER MISCRG= 5000 ;MISC REGISTER MISCRB= 12 ;MISC REGISTER ADDR, HIGH BYTE POLY= 7400 ;POLYNOMIAL REGISTER FOR CRC SEQREG= 6000 ;SEQUENCE REGISTER FOR PROTOCOL OPTION ; ; MISC ASSIGNMENTS ; TERM= U2.CTS!U2.HDX!U2.ONL!U2.SNC!U2.RCV ;U.CW2 BITS WHICH ;ARE CLEARED ON TERMINATE CLNGTH=4000 ;SETS CHAR LENGTH TO 8 BITS CRC16=120001 ;POLYNOMIAL REG BITS FOR CRC 16 IE.BCC=-64. ;RX BCC ERROR CODE MXSYNC=10. ; ; LOCAL DATA ; ; ; UNIT IMPURE DATA TABLE ; CNTBL: ;REF LABEL UNITBL: .REPT D$$Q11 ;UCB ADDRESS TABLE ;INDEXED BY CONTROLLER NUMBER .WORD 0 .ENDM .IF GT D$$Q11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 .ENDC ; ;**-3 ; DEVICE DISPATCH TABLE ; $XQTBL:: .WORD DQINIT ;DEVICE INITILIZATION .WORD DQCANC ;DEVICE I/O CANCEL ENTRY .WORD DQTMO ;TIMEOUT ENTRY .WORD DQPWRF ;POWER FAIL ROUTINE ;+ ;**- DQINIT - DQ-11 SYNCHRONOUS COMMUNICATION CONTROLLER I/O INITIATOR ; ; DQINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE ; NORMAL RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, ; THE REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS BUSY, ; AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF THE ; NATURE OF THE DQ-11, EACH UNIT IS A CONTROLLER ITSELF, HAS ; ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DQINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. ; ; INPUTS: ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED. ; ; OUTPUTS; ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ; ;- .ENABL LSB ;**-5 DQINIT: ;REFERENCE LABEL CALL $GTPKT ;GET I/O PACKET TO PROCESS ;**-9 BCC 10$ ;CC MEANS WORK TO DO DQRET: RETURN ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1= ADDRESS OF I/O REQUEST PACKET ; R2= PHYSICAL UNIT NUMBER OF REQUEST UCB ; R3= CONTROLLER INDEX ; R4= ADDRESS OF STATUS CONTROL BLOCK ; R5= ADDRESS OF THE UCB SPECIFIED IN THE DQINIT CALL ; ; DQ11 I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 RELOCATION BIAS OF I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 NOT USED ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; 10$: MOV S.CSR(R4),R2 ;GET RX CSR ADDR ADD #I.FCN+1,R1 ;POINT TO I/O FUNC CODE CMPB #IO.INL/256.,(R1) ;CHECK IF TRANSFER FUNC BLOS 110$ ;BR IF CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;IS DEVICE ONLINE BNE 30$ ;CONTINUE 20$: JMP 210$ ;DEVICE NOT READY 30$: ;REFERENCE LABEL BIT #DSR,2(R2) ;DATA SET READY? ;**-3 BEQ 20$ ;BRANCH IF NOT READY .IF DF M$$MGE ;**-3 .IF DF M$$EXT CMP #4096.,U.CNT(R5) ;BUFFER TOO BIG? BHIS 33$ ;CONTINUE IF NOT MOV #IE.SPC&377,R0 ;SIGNAL BUFFER TOO BIG JMP UNSUCC ;FINISH I/O 33$: CALL $STMAP ;GET DEVICE'S BUS ADDRESS MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;AND R2 CALL $MPUBM ;MAP 11/70 UNIBUS FOR DEVICE MOV (SP)+,R2 ;RESTORE R2 AND R1 MOV (SP)+,R1 .ENDC MOV U.BUF(R5),R0 ;GET MEMORY EXTENSION BITS ASL R0 ;PUT THEM IN BITS 5 & 6 BIS #WRTEN,R0 ;OR IN WRITE ENABLE BIT .IFF MOV #WRTEN,R0 ;ZERO MEMORY EXTENSION BITS .ENDC CMPB #IO.RLB/256.,(R1) ;IS FUNC READ LOGICAL? BEQ 100$ ;YES, GO TO READ REQ ; FALL THROUGH ON TRANSMIT REQUEST TST (R2)+ ;POINT TO TXCSR ;**-13 BIS #RTS,(R2)+ ;SET REQUEST TO SEND INC R2 ;POINT TO ERR/REG HIGH BYTE CALL TNEXT ;GET NEXT BUFFER REGISTER ADDR BIS #WRTEN,R3 ;CLEAR MEM EXT BITS MOVB R3,(R2)+ ;SET UP SECONDARY REGISTER PTR MOV U.QSYN(R5),(R2) ;LOAD ADDRESS OF SYNC BUFFER BIS #CCRG,R3 ;SELECT CHAR COUNT REG MOVB R3,-(R2) ;SET UP SECONDARY REG PTR MOVB U.NSYN(R5),R1 ;GET NO.OF SYNCS TO SEND CMPB #MXSYNC,R1 ;COUNT EXCEED SPACE? BHIS 40$ ;BR IF NOT MOV #MXSYNC,R1 ;SET COUNT TO MAX OF 8 SYNCS 40$: NEG R1 ;COUNT IN 2'S COMPLEMENT MOV R1,1(R2) ;COUNT INTO DQ BIS #U2.SNC,U.CW2(R5) ;SAY SENDING SYNCS CALL TOAN ;SETUP SECOND BUFFER 50$: BIS R0,R3 ;OR IN MEM EXT BITS MOVB R3,(R2)+ ;SET UP SECONDARY REG PTR MOV U.BUF+2(R5),(R2) ;USER BUFFER ADDR INTO DQ ;**-7 BIC R0,R3 ;CLR OUT MEM EXT BITS .IF DF Q$$CRC BIS #CCRG!TENTR,R3 ;SELECT COUNT REG, START CRC .IFF BIS #CCRG,R3 ;JUST SELECT COUNT REG .ENDC 55$: MOVB R3,-1(R2) ;SET UP SECONDARY REG PTR NEG U.CNT(R5) ;COUNT IN 2'S COMPLEMENT MOV U.CNT(R5),(R2) ;LOAD COUNT INTO DQ MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT TST -(R2) ;POINT TO ERR/REG REG BIT #CTS,-(R2) ;CTS SET YET? BEQ 70$ ;BR IF NOT SET YET BIS #TXGO!TXDNIE!ERRIE,(R2) ;START XMIT, ENABLE INTERRUPTS BR 80$ ;RETURN 70$: BIS #U2.CTS,U.CW2(R5) ;SAY CTS EXPECTED IN UCB BIS #DTSIE,(R2) ;ENABLE DATA SET INTERRUPTS 80$: RETURN ;RETURN, INTR PROPAGATES XMIT ; ; RECEIVE FUNCTION INITIATION ; 100$: ;REFERENCE LABEL ADD #5,R2 ;POINT TO ERR/REG HIGH BYTE ;**-4 CALL RNEXT ;SETUP FIRST BUFFER BIS R0,R3 ;OR IN MEMORY EXTENSION BITS MOVB R3,(R2)+ ;SET UP SECONDARY REG PTR MOV U.BUF+2(R5),(R2) ;USER BUFFER ADDR INTO DQ BIC R0,R3 ;CLR OUT MEM EXT BITS BIS #TENTR!CCRG,R3 ;SELECT CC REG AND ENTER TRANS MOVB R3,-1(R2) ;SET UP SECONDARY REG PTR MOV U.CNT(R5),(R2) ;DATA COUNT INTO DQ NEG (R2) ;COUNT IN 2'S COMPLEMENT DEC R2 ;POINT TO ERR/REG HIGH BYTE .IF DF Q$$CRC CALL ROAN ;SETUP SECOND BUFFER BIS #TEXIT!CCRG,R3 ;SELECT CC AND EXIT TRANS MOVB R3,(R2) ;SET UP SECONDARY REG PTR CLR 1(R2) .ENDC DEC R2 ;POINT TO ERR/REG REGISTER BIS #ERRIE,-(R2) ;ENABLE ERROR INTERRUPTS BIS #RXGO!RXDNIE,-(R2) ;START RECEIVER RETURN ;RETURN, INTERRUPTS PROPAGATE RECEIVE ; FUNCTION WAS CONTROL FUNCTION ;**-8 110$: BNE 160$ ;BR IF CHANGE MODE FUNCTION TSTB -(R1) ;TEST SUBCODE BNE 220$ ;FUNCTION WAS TERMINATE ; START FUNCTION INITIATION CMP (R2)+,(R2)+ ;POINT TO ER/REG MOV #MISCRG,(R2) ;SELECT MISCELL REG MOV #MSCLR,2(R2) ;AND DO A MASTER CLEAR MOVB #20,R0 ;SET UP TO CLEAR SEC REGS 120$: MOVB R0,1(R2) ;SELECT SECONDARY REGISTER CLR 2(R2) ;CLEAR SECONDARY REGISTER INC R0 ;NEXT SEC REG ADDR CMPB #30,R0 ;LAST REG TO CLEAR BHI 120$ ;BR IF MORE TO CLEAR .IF DF Q$$HPT BIT #U2.HPT,U.CW2(R5) ;DOES DEVICE HAVE PROTOCOL OPTION? BEQ 125$ ;BR IF NO MOV #17,R0 ;SET UP TO CLR SEQUENCE SCRATCHPAD MOV #SEQREG,(R2) ;SELECT SEQUENCE REG 122$: MOVB R0,-3(R2) ;INDEX INTO SEQUENCE SCRATCHPAD CLR 2(R2) ;CLEAR ENTRY DEC R0 BGE 122$ ;BR IF MORE TO GO .ENDC 125$: MOV #MISCRG,(R2)+ ;SELECT MISC REGISTER MOV #CLNGTH,(R2) ;SET CHARACTER LENGTH MOV #SYNREG,-(R2) ;SELECT SYNC REGISTER MOVB U.SYNC(R5),-(SP) ;GET SYNC CHAR FROM UCB MOVB (SP),1(SP) ;COPY LOW BYTE INTO HIGH BYTE MOV (SP)+,2(R2) ;LOAD DQ SYNC REG .IF DF Q$$CRC MOV #POLY,(R2) ;SELECT POLYNOMIAL REG MOV #CRC16,2(R2) ;LOAD POLYNOMIAL FOR CRC16 .ENDC BIS #DTR,-(R2) ;SET DATA TERMINAL READY TST U.CW2(R5) ;IN HALF DUPLEX? BPL 130$ ;BR IF FULL DUPLEX BIS #HDPX,-(R2) ;SET HALF DUPLEX IN RXCSR 130$: MOV R5,UNITBL(R3) ;PUT UCB INTO TABLE MOV U.QSYN(R5),R0 ;SYNC BUFFER ALREADY ALLOCATED? BNE 135$ ;DON'T RE-ALLOCATE BUFFER MOV #MXSYNC,R1 ;GET SIZE OF SYNC BUFFER CALL $ALOCB ;TRY TO ALLOCATE BUFFER BCS 210$ ;BR IF COULDN'T MOV R0,U.QSYN(R5) ;SAVE POINTER TO AREA 135$: BIS #U2.ONL,U.CW2(R5) ;MARK DEVICE ONLINE MOV #MXSYNC,R2 ;SET UP TO LOAD SYNC BUFFER ;**-12 150$: MOVB U.SYNC(R5),(R0)+ ;MOV SYNC CHAR INTO BUFFER DEC R2 ;MORE TO PUT IN? BGT 150$ ;BR IF MORE TO GO BR SUCC ;COMPLETE I/O DONE ; SERVICE DEVICE MODE CHANGE REQUEST 160$: BITB #IO.HDX,-(R1) ;HALF DUPLEX SUBFUNCTION? BEQ 170$ ;BR IF NOT BIS #U2.HDX,U.CW2(R5) ;SET HALF DUPLEX 170$: BITB #IO.FDX,(R1) ;FULL DUPLEX SUBFUNCTION? BEQ 200$ ;BR IF NOT BIT #U2.LIN,U.CW2(R5) ;DEVICE CAPABLE OF FULL DUPLEX? BEQ 190$ ;BR IF YES 180$: MOV #IE.IFC&377,R0 ;SIGNAL ILLEGAL FUNCTION CODE BR UNSUCC ;FINISH I/O UNSUCCESSFUL 190$: BIC #U2.HDX,U.CW2(R5) ;SET FULL DUPLEX CHARACTERISTIC 200$: BITB #IO.SYN,(R1) ;SYNC CHARACTER SPECIFIED? BEQ SUCC ;DO I/O DONE IF NOT MOVB I.PRM-I.FCN(R1),U.SYNC(R5) ;MARK NEW SYNC CHAR BR SUCC ;COMPLETE I/O DONE ; CAN'T ESTABLISH COMMUNICATIONS 210$: MOV #IE.DNR&377,R0 ;SAY DEVICE NOT READY BR UNSUCC ;DO I/O DONE ;FUNCTION WAS TERMINATE LINE 220$: CMP (R2)+,(R2)+ ;POINT TO ER/REG MOV #MISCRG,(R2)+ ;SELECT MISC REG MOV #MSCLR,(R2) ;AND DO A MASTER CLEAR BIC #TERM,U.CW2(R5) ;CLR STATUS BITS IN UCB CLR UNITBL(R3) ;REMOVE UCB FROM UNITBL MOV U.QSYN(R5),R0 ;GET FORK BLOCK AREA BEQ SUCC ;DON'T RELEASE IF NOT ALLOCATED MOV #MXSYNC,R1 ;SET SIZE OF FORK AREA CALL $DEACB ;RELEASE BLOCK AREA CLR U.QSYN(R5) ;SIGNAL NOTHING THERE SUCC: MOV #IS.SUC&377,R0 ;SUCC COMP ENTRY UNSUCC: CLRB S.STS(R4) ;IDLE CONTROLLER BICB #US.BSY,U.STS(R5) ;MARK UNIT IDLE MOV R0,-(SP) ;SAVE STATUS WORD 1 MOV S.PKT(R4),-(SP) ;SAVE OLD PACKET ADDR CALL DQINIT ;TRY TO ACT NEXT REQ MOV (SP)+,R3 ;GET OLD I/O PACKET MOV I.PRM+4(R3),R1 ;RETURN REQ ITEM CNT MOV (SP)+,R0 ;GET STATUS WORD 1 CALLR $IOFIN ;TERMINATE OLD PACKET ; I/O CANCELLATION ENTRY ; ; INPUTS: ; R5 = ADDRESS OF UNIT CONTROL BLOCK ; R4 = ADDRESS OF STATUS CONTROL BLOCK ; R1 = TCB ADDRESS OF TASK FOR CANCELL ; R0 = ADDRESS OF CURRENT PACKET ; DQCANC: ;;;REFERENCE LABEL CMP R1,I.TCB(R0) ;;;CURRENT PACKET FOR THIS TASK?;**-7 BNE 225$ ;;;RETURN IF NOT CMPB #IO.WLB/256.,I.FCN+1(R0);;;TRANSMIT? BEQ 225$ ;;;JUST LET FINISH IF YES MOV #IE.ABO&377,R0 ;;;ASSUME WE WILL ABORT BIT #RXACT,@S.CSR(R4) ;;;IS RECEIVER ACTIVE? BNE 217$ ;RECEIVER IS ACTIVE BIT #RXDNP!RXDNS,@S.CSR(R4) ;HAS RECEIVE FINISHED? BNE 225$ ;IF NE, YES, LET IT BE SUCCESSFUL 217$: BIC #RXDIS!RXGO,@S.CSR(R4) ;DISABLE RECEIVER BR UNSUCC ;FINISH UNSUCCESSFUL I/O 225$: RETURN ;;;RETURN TO CALLER ; POWERFAIL ENTRY FOR NON NETWORKS DQPWRF: MOV S.CSR(R4),R2 ;;;GET DEVICE CSR ADDRESS BIC #RXDIS!RXGO,(R2)+ ;;;DISABLE RECEIVER BIC #TXDISH,(R2)+ ;;;DISABLE TRANSMITTER CLRB (R2) ;;;CLEAR ALL ERROR BITS MOVB #2,S.CTM(R4) ;;;FORCE TIMEOUT 230$: RETURN ;;;RETURN TO CALLER ; TIMEOUT ENTRY ;**-10 ; THIS CODE IS ENTERED WHEN THE TRANSMIT TIMEOUT COUNT GOES TO ZERO. DQTMO: MOV S.CSR(R4),R2 ;;;GET CSR IN R2 BIC #TXDISH,2(R2) ;;;DISABLE TRANSMITTER BIC #U2.CTS,U.CW2(R5) ;;;CLR WAITING FOR CTS FLAG MTPS #0 ;;;DROP PRIORITY LEVEL BR UNSUCC ;FINISH I/O UNSUCCESSFUL ;**-3 .DSABL LSB ;**-7 ;+ ; TNEXT,TOAN,RNEXT AND ROAN ARE SUBROUTINES WHICH SELECT THE ; APPROPRIATE BUFFER ADDRESS REGISTER TO USE. TNEXT (TRANSMIT) ; AND RNEXT (RECEIVE) SELECT THE NEXT BUFFER AS INDICATED BY THE ; TXPS AND TXPS STATUS BITS RESPECTIVELY. TOAN AND ROAN SELECT THE ; BUFFER WHICH IS THE ONE AFTER THE NEXT BUFFER TO BE USED. (IE. ; FOR DOUBLE BUFFERING AHEAD) ; ; INPUTS: ; R2 = ADDR OF DQ ERR/REG REGISTER, HIGH BYTE ; ; OUTPUTS: ; R3 = APPROPRIATE SECONDARY REGISTER ADDRESS ;- .ENABL LSB TNEXT: BIT #TXGO,-3(R2) ;CURRENT BUFFER ACTIVE? BNE TOAN ;USE OTHER IF YES BIT #TXPS,-3(R2) ;PRIMARY OR SEC REG ACTIVE? BNE 20$ ;BR IF SECONDARY BR 10$ ;BR IF PRIMARY TOAN: BIT #TXPS,-3(R2) ;PRIMARY OR SECONDARY ACTIVE? BEQ 20$ ;BR IF SECONDARY NOT ACTIVE 10$: MOV #TXBAP,R3 ;SELECT PRIMARY TX REG RETURN ;RETURN 20$: MOV #TXBAS,R3 ;SELECT SECONDARY TX REG RETURN ;RETURN .IF DF Q$$CRC ; RC024 ;**-1 ROAN: BIT #RXPS,-5(R2) ;PRIMARY OR SECONDARY ACTIVE? BEQ 40$ ;BR IF SEC NOT ACTIVE BR 30$ ;BR IF PRI NOT ACTIVE .IFTF RNEXT: ;REFERENCE LABEL .IFT BIT #RXACT,-5(R2) ;RECEIVER ACTIVE? BNE ROAN ;USE ROAN IF ACTIVE .ENDC BIT #RXPS,-5(R2) ;PRIMARY OR SECONDARY ACTIVE? BNE 40$ ;BR IF SEC ACTIVE 30$: CLR R3 ;SELECT PRIMARY RECEIVE REG RETURN ;RETURN 40$: MOV #RXBAS,R3 ;SELECT SECONDARY RECEIVE REG RETURN .DSABL LSB ; ; TRANSMIT INTERRUPT ROUTINE ; .ENABL LSB $XQOUT:: ;;;REFERENCE LABLE INTSV$ XQ,PR5,D$$Q11 ;;;GENERATE INTERRUPT SAVE CODE CALL DQSET ;;;RXCSR->R4, UCB->R5 TST (R4)+ ;;;POINT TO TXSCR BIT #U2.CTS,U.CW2(R5) ;;;CTS EXPECTED? BEQ 20$ ;;;BR IF NOT EXPECTED BIT #CTS,(R4) ;;;IS CTS SET? BEQ 10$ ;;;BR IF NOT SET YET BIC #DTSIE,(R4) ;;;DISABL DATASET INTERRUPTS BIS #TXGO!TXDNIE!ERRIE,(R4) ;;;START TRANSMIT BIC #U2.CTS,U.CW2(R5) ;;;CLR CTS EXPECTED IN UCB 10$: BIC #DSFLG,(R4) ;;;RESET DATA SET FLAG 20$: TST 2(R4) ;;;ANY ERRORS? BPL 22$ ;;;BR IF NO ERRORS JMP ERROR ;;;GO TO ERROR ROUTINE 22$: ;;;REFERENCE LABEL BIT #TXDNP,(R4) ;;;PRIMARY BUFFER FINISH? BNE 70$ ;;;BR IF YES BIT #TXDNS,(R4) ;;;SECONDARY BUFFER FINISH? BNE 25$ ;;;BR IF YES JMP DQEXIT ;;;EXIT FROM INTERRUPT 25$: BIC #TXDNS,(R4) ;;;CLR SECONDARY DONE BR 80$ ;;;CONTINUE 70$: BIC #TXDNP,(R4) ;;;CLR PRIMARY DONE 80$: BIT #U2.SNC,U.CW2(R5) ;;;SENDING SYNCS? BEQ 180$ ;;;BR IF SENDING DATA BIC #U2.SNC,U.CW2(R5) ;;;CLR SENDING SYNCS IN UCB MOV R2,-(SP) ;;;SAVE R2 .IF DF Q$$CRC MOV R3,-(SP) ;;;SAVE R3 MOV R4,R2 ;;;COPY CSR ADDR ADD #3,R2 ;;;POINT TO ERR/REG HIGH BYTE CALL TNEXT ;;;GET NEXT REGISTER POINTER BISB #CCRG!TEXIT,R3 ;;;FORCE EXIT TRANSPARENCY MOVB (R2),-(SP) ;;;SAVE OLD SECONDARY POINTER MOVB R3,(R2)+ ;;;SETUP SECONDARY ADDR CLR (R2) ;;;SET COUNT OF ZERO MOVB (SP)+,-(R2) ;;;RESTORE OLD SECONDARY POINTER .IFTF MOV U.SCB(R5),R2 ;;;GET SCB ADDR MOVB S.ITM(R2),S.CTM(R2) ;;;RESET TIMEOUT .IFT MOV (SP)+,R3 ;;;RESTORE R3 .ENDC MOV (SP)+,R2 ;;;RESTORE R2 BR 20$ ;;;CHECK FOR NEW FLAGS 180$: BIC #TXDISF,(R4) ;;;DISABLE TRANSMITTER CALL $FORK ;GO TO FORK LEVEL TXTRN: MOV U.SCB(R5),R4 ;GET SCB ADDRESS INTO R4 MOV S.CSR(R4),R2 ;GET DEVICE RXCSR TST (R2)+ ;POINT TO TXCSR TST U.CW2(R5) ;IN HALF DUPLEX? ;**-7 BPL 220$ ;BR IF FULL DUPLEX ;**-3 MOVB #MISCRB,3(R2) ;SELECT MISCELLANEOUS REG BIT #TXACT,4(R2) ;TX STILL ACTIVE? BEQ 210$ ;BR IF FINISHED MOV R4,R0 ;SCB ADDR INTO R0 ADD #S.XQCK,R0 ;POINT TO CLOCK QUEUE BLOCK CLR R1 ;CLR HIGH TIME MOV #1,R2 ;SET TIMEOUT OF ONE TICK MOV #C.SYST,R4 ;SIGNAL INTERNAL REQUEST MOV #200$,C.SUB(R0) ;SET TIMEOUT ADDRESS CALLR $CLINS ;QUEUE A CLOCK PACKET 200$: MOV C.TCB(R4),R5 ;RECOVER UCB ADDR BR TXTRN ;CHECK ACTIVE AGAIN 210$: BIC #RTS,(R2) ;CLEAR REQUEST TO SEND 220$: ;REFERENCE LABEL JMP SUCC ;FINISH I/O ;**-3 .DSABL LSB ;**-10 ERROR: ;;;REFERENCE LABEL TST -(R4) ;;;POINT TO RXCSR ;**-3 BIC #RXDIS,(R4)+ ;;;DISABLE RECEIVER BIC #TXDISH,(R4)+ ;;;DISABLE TRANSMITTER CALL $FORK ;;;GO TO FORK LEVEL RBCERR: MOV (R4),R0 ;;;GET ERROR BITS IN R0 CLRB (R4) ;;;CLR ERROR BITS IN DEVICE BIT #TXCLK!TXLAT!RXCLK!RXLAT,R0 ;;;CLOCK OR LATENCY ERROR? BEQ 10$ ;;;BR IF NOT MOV #IE.DAO&377,R0 ;;;SIGNAL DATA OVERRUN ERROR BR 30$ ;;;CONTINUE 10$: BIT #RXNEX!TXNEX,R0 ;;;NON EXISTENT MEMORY ERROR? BEQ 20$ ;;;BR IF NOT MOV #IE.SPC&377,R0 ;;;SIGNAL SPACE ERROR BR 30$ ;;;CONTINUE 20$: MOV #IE.BCC&377,R0 ;;;MUST BE BCC ERROR 30$: MOV U.SCB(R5),R4 ;;;GET SCB ADDR FOR I/O DONE CALLR UNSUCC ;;;FINISH I/O ; ;DQSET - SET UP REGISTER R4 WITH RXCSR ADDR, R5 WITH ; UCB ADDR. UNIT NUMBER IN LOW ORDER 4 BITS OF UNIT DQSET: TST R5 ;;;CHECK FOR UCB ADDRESS BEQ 10$ ;;;NO UNIT, EXIT INTR BIT #U2.ONL,U.CW2(R5) ;;;UNIT ONLINE? BEQ 10$ ;;;DISMIS IF NOT MOV U.SCB(R5),R4 ;;;GET SCB ADDR MOV S.CSR(R4),R4 ;;;NOW GET RXCSR ADDR RETURN ;;;RETURN 10$: TST (SP)+ ;;;CLEAR STACK DQEXIT: JMP $INTXT ;;;DISMISS INTERRUPT ; ; RECEIVE INTERRUPT ROUTINE ; .ENABL LSB $XQINP:: INTSV$ XQ,PR5,D$$Q11 ;;;GENERATE INTERRUPT SAVE CODE CALL DQSET ;;;R4=RXCSR, R5=UCB ADDR BIT #RXDNP!RXDNS,(R4) ;;;DID BUFFER COMPLETE? BEQ DQEXIT ;;;BR IF NOT BIC #RXDIS,(R4L)+ ;;;DISABLE RECEIVER ;**-4 BIC #ERRIE,(R4)+ ;DISABLE ERROR INTERRUPTS CALL $FORK ;;;GO TO FORK LEVEL BIC #RXCLK,(R4) ;CLR RECEIVE CLOCK ERROR BIT #BCCERR,(R4) ;WAS THERE A BCC ERROR? BNE RBCERR ;BR IF YES MOV U.SCB(R5),R4 ;GET SCB ADDR FOR I/O DONE JMP SUCC ;FINISH SUCCESSFUL I/O .END ;**-155 L .WORD TCL'X'ER .ENDM ; ;+ ; SETRTY - SETUP RETRY COMMAND FOR COMMANDS OTHER THAN FUNCTION IN PROGRESS ; ;- ; .MACRO SETRTY FCDE,ADR,CNT MOV (R2),CMDHDR(R3) ; SAVE COMMAND HEADER MOV #CC.'FCDE,(R2) ; SET NEW COMMAND MOVB #15.,S.STS(R4) ; SET 1 MINUTE TIMEOUT ; RP023 MOVB #4.,S.ITM(R4) ; FOUR SECONDS AT A TIME ; RP023 MOV INTADD(R3),RTYINT(R3) ;SAVE INTERRUPT ADDRESS MOV #'ADR,INTADD(R3) ; SET INTERMEDIATE INT ADDR .IIF NB ,MOV #'CNT,2(R2) ; PB116 .ENDM SETRTY ; PB116 ; PB116 ; ; VALID TS11/TS04 FUNCTION TABLE ; ; FORMAT OF EACH TABLE ENTRY: ; FCN=I/O FUNCTION CODE ; HCC=EQUIVALENT HARDWARE COMMAND CODE ; EXT=COMMAND'S EXTENDED TIMEOUT VALUE ; RP023 ; TMO=COMMAND'S TIMEOUT COUNT IN SECONDS ; RP023 ; ADR=INITIATION PROCESSING ADDRESS OR I/O COMMON ADDRESS ; .MACRO FUNCT FCN,HCC,EXT,TMO,INT,ADR ; RP023 .WORD IO.'FCN .WORD CC.'HCC .BYTE EXT,TMO ; RP023 .WORD I'INT .WORD P'ADR .ENDM FUNCT ; RP023 VFTBL: FUNCT RLB,RDN,1,12.,OCOM,IOCOM ; READ LOGICAL BLOCK FORWARD ; RP023 FUNCT WLB,WRD,1,12.,OCOM,WRITE ; WRITE LOGICAL BLOCK ; RP023 FUNCT RLV,RDP,1,12.,RREV,IOCOM ; READ LOGICAL BLOCK REVERSE ; RP023 FUNCT EOF,WTM,1,4.,WRMK,WRTMK ; WRITE TAPE MARK ; RP023 FUNCT RWD,RWD,60.,5.,ODON,REWND ; REWIND ; RP023 FUNCT RWU,UNL,1,2.,ODON,UNLOD ; REWIND AND UNLOAD ; RP023 FUNCT SPB,SRF,132.,5.,SPCB,SPACE ; SPACE BLOCKS ; RP023 FUNCT SPF,STF,132.,5.,SPCF,SPACE ; SPACE FILES ; RP023 FUNCT STC,MST,1,2.,STAT,SET ; SET CHARACTERISTICS ; RP023 FUNCT SEC,GST,1,2.,STAT,GSTAT ; SENSE CHARACTERISTICS ; RP023 FUNCT SMO,MST,1,2.,MOUNT,SET ; MOUNT/SET CHARACTERISTICS ; RP023 FUNCT ERS,ERS,1,12.,ODON,WRTMK ; ERASE TAPE ; RP023 EVFTBL: ; ; MESSAGE HEADER TABLE ; MESSAG: .IRP X, ; RP023 .WORD MC.'X ; RP023 .ENDM ; RP023 ;+ ; **-MSINI-TS11/TS04 MAGNETIC TAPE CONTROLLER I/O INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO ; PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER ; IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O ; REQUEST. ELSE A RETURN TO THE CALLER IS EXECUTED. IF THE ; DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPERATION IS ; INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST ; IS WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED ; AND THE I/O OPERATION IS INITIATED. ;- ;+ ; THE FOLLOWING REGISTERS CONTENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB ; R3=CONTROLLER INDEX ; R4=ADDRESS OF THE STATUS CONTROL BLOCK ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ;  ; TS11 MAGNETIC TAPE FUNCTION INDEPENDENT I/O REQUEST PACKET FORMAT: ; ;I.LNK WD. 00 = I/O QUEUE THREAD WORD. ;I.PRI WD. 01 = REQUEST PRIORITY (LOW BYTE). ;I.EFN WD. 01 = EVENT FLAG NUMBER (HIGH BYTE). ;I.TCB WD. 02 = ADDRESS OF THE TCB OF THE REQUESTOR TASK. ;I.LN2 WD. 03 = POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER. ;I.UCB WD. 04 = CONTENTS OF 1ST LUN WORD IN REQUESTOR TASK HEADER (UCB) ;I.FCN WD. 05 = I/O FUNCTION CODE (IO.RLB/IO.RWD/IO.SPB/ETC.). ;I.IOSB WD. 06 = VIRTUAL ADDRESS OF I/O STATUS BLOCK. ;IOSB+2 WD. 07 = RELOCATION BIAS OF I/O STATUS BLOCK. ;IOSB+4 WD. 10 = I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT+140000). ;I.AST WD. 11 = VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; ; ; READ/WRITE LOGICAL FUNCTION DEPENDENT I/O PACKET FORMAT: ; ;I.PRM WD. 12 = HIGH 2 BITS (BITS 4 & 5) OF 18 BIT DATA BUFFER ADDRESS. ;PRM+2 WD. 13 = LOW 16 BITS OF 18 BIT DATA BUFFER ADDRESS. ;PRM+4 WD. 14 = NUMBER OF BYTES TO BE TRANSFERRED. ;PRM+6 WD. 15 = NOT USED. ;PRM+10 WD. 16 = NOT USED. ;PRM+12 WD. 17 = NOT USED. ;PRM+14 WD. 20 = RELOCATION BIAS OF DIAGNOSTIC REGISTER BLOCK ADDRESS. ;PRM+16 WD. 21 = DIAG. REG. BUFFER ADDRESS (REAL/DISPLACEMENT+140000). ; ; ; BLOCK AND FILE SPACING FUNCTIONS DEPENDENT I/O PACKET FORMAT: ; ;I.PRM WD. 12 = SPACING COUNT (POSITIVE=FORWARD, NEGATIVE=BACKWARD). ;PRM+2 WD. 13 = NOT USED. ;PRM+4 WD. 14 = NOT USED. ;PRM+6 WD. 15 = NOT USED. ;PRM+10 WD. 16 = NOT USED. ;PRM+12 WD. 17 = RELOCATION BIAS OF DIAGNOSTIC REGISTER BLOCK ADDRESS. ;PRM+14 WD. 20 = DIAG. REG. BUFFER ADDRESS (REAL/DISPLACEMENT+140000). ;PRM+16 WD. 21 = NOT USED. ; ; ; (MOUNT AND) SET CHARACTERISTICS FUNCTION DEPENDENT I/O PACKET FORMAT. ; FOR SENSE CHARACTERISTICS, I.PRM (WD. 12) IS NOT USED: ; ;I.PRM WD. 12 = NEW CHARACTERISTICS WORD. ;PRM+2 WD. 13 = NOT USED. ;PRM+4 WD. 14 = NOT USED. ;PRM+6 WD. 15 = NOT USED. ;PRM+10 WD. 16 = NOT USED. ;PRM+12 WD. 17 = NOT USED. ;PRM+14 WD. 20 = NOT USED. ;PRM+16 WD. 21 = NOT USED. ; ; ; WREOF, REWIND, AND UNLOAD FUNCTIONS DEPENDENT I/O PACKET FORMAT: ; ;I.PRM WD. 12 = NOT USED. ;PRM+2 WD. 13 = NOT USED. ;PRM+4 WD. 14 = NOT USED. ;PRM+6 WD. 15 = NOT USED. ;PRM+10 WD. 16 = NOT USED. ;PRM+12 WD. 17 = RELOCATION BIAS OF DIAGNOSTIC REGISTER BLOCK ADDRESS. ;PRM+14 WD. 20 = DIAG. REG. BUFFER ADDRESS (REAL/DISPLACEMENT+140000). ;PRM+16 WD. 21 = NOT USED. ;- .ENABL LSB MSINI: CALL $GTPKT ;ATTEMPT TO GET AN I/O PACKET BCC 10$ ; IF CC WE HAVE A PACKET RETURN ; ELSE RETURN 10$: MOV R5,CNTBL(R3) ; SAVE ADDRESS OF CURRENT UCB CLR CSTAT(R3) ;CLEAR CONTROLLER STATE FLAGS ; RP046 BIC #CH.EAI,U.CHAR(R5) ;CLEAR ATTENTION ENABLE INT ;**-1 MOV U.CHAR(R5),R0 ; RETRIEVE CHARACTERISTICS WORD ; RP023 .IF DF A$$NSI BIC #CH.ESS,R0 ;CLEAR LET FLAG ; RP023 BITB #US.LAB,U.STS(R5) ; MOUNTED ANSII TAPE? BNE 20$ ; IF NE YES - DON'T STOP ON DOUBLE TMK BIS #CH.ESS,R0 ;NOT ANSII - ENABLE LET FLAG ; RP023 20$: CMP R0,U.CHAR(R5) ;CHARACTERISTICS WORD SET CORRECTLY? ; RP023 BNE GCR ;IF NE NO, GO WRITE CHARACTERISTICS WORD; RP023 .ENDC ; RP023 ; RP023 BIT #SR.NBA,@S.CSR(R4) ;IS THE TS04 TALKING? ; RP023 BNE GCR ;IF NE NO ; RP023 ILDBA: MOV S.PKT(R4),R1 ;RELOAD PACKET POINTER. MOV #VFTBL,R2 ;POINT AT VALID FUNCTIONS TABLE MOV I.FCN(R1),R0 ;GET FUNCTION CODE FROM PACKET BIT #IQ.X,R0 ;ERROR RECOVERY PROHIBITED ? BEQ 50$ ;NO=> SKIP AHEAD; ELSE SET BIS #CS.NER,CSTAT(R3) ; CORRESPONDING FLAG ; RP046 BIC #IQ.X,R0 ; AND CLEAR BIT FOR COMPARE. ;**-1 50$: ;REFERENCE LABEL. ; RP023 .IF DF D$$IAG ;%%% 1 %%% ; RP023 BITB #IQ.UMD,R0 ;DIAGNOSTIC FUNCTION CALL? BEQ 60$ ;IF EQ NO BIS #CS.UMD,CSTAT(R3) ;COPY DIAGNOSTIC FLAG ; RP046 BIC #IQ.UMD,R0 ;CLEAR BIT FOR FUNCTION CHECK ;**-1 ; RP023 .ENDC ;%%% 1 %%% ; RP023 60$: CMP R0,(R2)+ ;FUNCTION CODES MATCH? BEQ 70$ ;IF EQ YES ADD #10,R2 ; POINT TO NEXT TABLE ENTRY CMP #EVFTBL,R2 ;END OF TABLE? ; RP023 BNE 60$ ;IF NE NO MOV #IE.IFC&377,R0 ;SET UP ILLEGAL FUNCTION CODE BR ALT ;GO TO EXIT 70$: MOVB #RETRY,RTTBL(R3) ;SET RETRY COUNT MOV (R2)+,R1 ; RETRIEVE HARDWARE COMMAND CODE MOVB (R2)+,S.STS(R4) ;SET EXTENDED TIMEOUT VALUE ; RP023 MOVB (R2)+,S.ITM(R4) ;SET INITIAL TIMEOUT VALUE ; RP023 MOV (R2)+,INTADD(R3) ; STORE INTERRUPT ADDRESS CALLR @(R2) ;GO TO PRE-PROCESSING FOR THIS FUNCTION ; RP023 ;+ ; RP023 ; **-GCR-GENERATE CHARACTERISTICS ROUTINE ; RP023 ; ; RP023 ; THIS ROUTINE WILL SEND THE CHARACTERISTICS WORD TO THE TS11/TS04 ; RP023 ; SUB-SYSTEM. ; RP023 ; ; RP023 ; INPUTS: ; RP023 ; ; RP023 ; R4= SCB ADDRESS ; RP023 ; R5 = UCB ADDRESS ; RP023 ; ; RP023 ; OUTPUTS: ; RP023 ; ; RP023 ; THE TS11/TS04 SUB-SYSTEM IS GIVEN THE MESSAGE BUFFER ADDRESS ; RP023 ; ; RP023 ;- ; RP023 ; RP023 GCR: MOVB #2.,S.ITM(R4) ;SET TIMEOUT ; RP023 BIS #CS.LBA,CSTAT(R3) ;SET WRITE CHARACTERISTICS FLAG ; RP046 TST U.CBP(R5) ;HAVE WE SET UP COMMAND BUFFER POINTER? ; RP052 BNE 72$ ;IF NE YES ; RP052 CALL MSPWF ;NO, CALCULATE COMMAND BUFFER POINTER ; RP052 72$: MOV U.CBP(R5),R2 ;RETRIEVE COMMAND BUFFER POINTER ; RP052 MOV #CC.WRC,(R2)+ ;SET WRITE CHARACTERISTICS FUNCTION ;**-2 MOV U.CRP(R5),(R2)+ ;LOAD LOW ADDRESS OF MESSAGE BUFFER ; RP023 CLR (R2)+ ;LOAD HIGH ADDRESS OF MESSAGE BUFFER ; RP023 MOV #10,(R2) ;LOAD BYTE COUNT ; RP023 BR INITIO ;GO INITIATE I/O ; RP023 ; RP023 ;- ; PRE-PROCESSING ROUTINES FOR I/O OPERATIONS ; ; INPUTS: ; R1 = HARDWARE FUNCTION CODE ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- ; ; WRITE DATA ; PWRITE: CMP U.CNT(R5),#14. ;ENOUGH BYTES FOR WRITE? BHIS 75$ ;IF HIS YES TST U.CNT(R5) ;IS IT MAX COUNT? BEQ 75$ ;IF EQ YES MOV #IE.SPC&377,R0 ;SET UP PARAMETER ERROR CODE BR ALT ;GO TO EXIT ; ; WRITE TAPE MARK ; PWRTMK: CLR U.CNT(R5) ;INSURE COUNT IS 0 75$: BIT #M.SWL,U.CW2(R5) ;SOFTWARE WRITE LOCK IN EFFECT? BEQ PIOCOM ;IF EQ NO MOV #IE.WLK&377,R0 ;SET UP WRITE LOCK ERROR CODE BR ALT ;GO TO EXIT ; ; SPACE BLOCKS AND SPACE FILES ; PSPACE: MOV #IS.SUC&377,R0 ;ASSUME 0 SPACING COUNT MOV U.BUF(R5),U.CNT(R5) ;PUT SPACING COUNT IN PLACE BEQ ALT ;IF EQ NO I/O NEEDED (U.BUF=0) BMI 90$ ;IF MI SPACE REVERSE (U.BUF=NEGATIVE) BIT #M.AEOV,U.CW2(R5) ;ALREADY AT EOV? ; RP047 BEQ 100$ ;IF EQ NO ;**-1 MOV #IE.EOV&377,R0 ;SET UP END OF VOLUME CODE ALT: CALL $IOALT ;TERMINATE THIS REQUEST BR MSINI ;GO CHECK FOR ANOTHER PACKET ; RP023 90$: BIS #CC.SRR-CC.SRF,R1 ;MAKE CMND SPACE/SKIP REVERSE NEG U.CNT(R5) ;MAKE COUNT POSITIVE 100$: BIS #CS.RSP,CSTAT(R3) ;SET "REWIND/SPACE INP PROGRESS" FLAG; RP046 BR PIOCOM ;GO TO COMMON PROCESSING ;**-1 ; PB116 ; ; (MOUNT AND) SET CHARACTERISTICS ; RP023 ; PSET: BIC #USRBTS,U.CW2(R5) ;CLEAR USER SETTABLE BITS BIC #^C,U.BUF(R5) ;REMOVE NON-SETABLE BITS. BIS U.BUF(R5),U.CW2(R5) ;UPDATE USER SETABLE BITS. ; RP023 ; ; GET STATUS (FOR SENSE, (MOUNT AND) SET CHARACTERISTICS) ; ; RP023 PGSTAT: BIS #CS.GST,CSTAT(R3) ;SET GET STATUS FLAG ; RP046 BR PUNLOD ;CONTINUE ;**-1 ; ; REWIND TAPE ; PREWND: BIS #M.RWD,U.CW2(R5) ;SET TAPE REWINDING FLAG. BIS #CS.RSP,CSTAT(R3) ;SET "REWIND/SPACE INP PROGRESS" FLAG; RP046 ;**-1 ; ; UNLOAD TAPE ; PUNLOD: CLR U.CNT(R5) ;INSURE COUNT IS 0 ; PB116 ; ; I/O OPERATION COMMON PRE-PROCESSING ; PIOCOM: MOV U.CBP(R5),R2 ; GET COMMAND BUFFER POINTER MOV R1,(R2)+ ; LOAD COMMAND HEADER IN BUFFER BIC #^C,R1 ;ISOLATE COMMAND CODE BITS CMP R1,#CC.SRF&CM.COD ;COMMAND NEED AN ADDRESS? BHIS 130$ ;IF HIS NO BIT #M.SWAP,U.CW2(R5) ;SWAP BYTES ON DATA? BEQ 120$ ;IF EQ NO BIS #CM.SWB,-2(R2) ; SET SWAP BITS BYTE IN HEADER WORD 120$: ;REF LABEL ; RP023 .IF DF M$$EXT&M$$MGE ;%%% 1 %%% ; RP023 CALL $STMAP ; SET UP UNIBUS MAPPING MOV R2,-(SP) ; SAVE R2 CALL $MPUBM ; MAP UNIBUS TO TRANSFER  MOV (SP)+,R2 ; RESTORE R2 ; RP023 .ENDC ;%%% 1 %%% ; RP023 MOV U.BUF+2(R5),(R2)+ ; PUT LOW ORDER 16 BITS IN BUFFER ; RP023 .IF DF M$$MGE ;%%% 1 %%% ; RP023 MOV U.BUF(R5),(R2) ; LOAD HIGH 2 BITS OF ADDRESS ASR (R2) ; AND MOVE FROM ASR (R2) ; BITS 4 AND 5 ASR (R2) ; TO ASR (R2)+ ; BITS 0 AND 1 .IFF CLR (R2)+ ; CLEAR HIGH BITS .ENDC ; RP023 130$: MOV U.CNT(R5),(R2) ; LOAD BYTE/RECORD/FILE COUNT ; PB116 ;+ ; INITIATE I/O OPERATION ; ; INPUTS: ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- INITIO: MOVB S.ITM(R4),S.CTM(R4) ;START THE TIMER ; RP023 .IF DF E$$DVC ;%%% 1 %%% ; RP023 CALL $BMSET ;;;SET BIT IN I/O ACTIVE MAP .IFF ;%%% 1 %%% ; RP023 MTPS #PR7 ;;;INHIBIT INTERRUPTS .IFTF ;%%% 1 %%% ; RP023 MOV S.CSR(R4),R2 ;;;RETRIEVE CSR ADDRESS ; RP023 TSTB (R2) ;;;SUB-SYSTEM READY? ; RP023 BPL 140$ ;;;IF PL NO ; RP023 MOV U.CBP(R5),TSDB(R2) ;;;LOAD COMMAND POINTER ; RP023 BIS #CS.CIP,CSTAT(R3) ;;;SET COMMAND IN PROGRESS ; RP046 BR 150$ ;;;EXIT ;**-1 140$: MOVB #4.,S.CTM(R4) ;;;SET TIMER ; RP023 MOV #INITIO,SSRRTY(R3) ;;;SETUP SUB-SYSTEM READY RETRY ; RP023 ;;;HANDLER ; RP023 BIS #CS.WSS,CSTAT(R3) ;;;SET WAITING FOR SUB-SYSTEM READY ; RP046 ;;;FLAG ;**-1 150$: ;;;REF LABEL ; RP023 .IFF ;%%% 1 %%% ; RP023 MTPS #0 ;;;ALLOW INTERRUPTS ; RP023 .ENDC ;%%% 1 %%% ; RP023 RETURN ;EXIT WHILE I/O IN PROGRESS .DSABL LSB ; PB116 ; PB116 ;+ ; **-MSCAN-TS11/TS04 CANCEL I/O ENTRY POINT ; ; THE CANCEL I/O OPERATION IS BASICALLY A NOP FOR TS11 ; MAGNETIC TAPES. HOWEVER, IF A "NOT READY" MESSAGE IS ; BEING ISSUED DUE TO A SELECT ERROR, THE CANCEL I/O WILL ; CAUSE THE MESSAGES TO BE TERMINATED AND THE I/O ABORTED. ; ; INPUTS: ; R0 = ACTIVE I/O PACKET ADDRESS ; R1 = CURRENT TCB ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- MSCAN: CMP I.TCB(R0),R1 ;;;IS THIS THE CORRECT TASK? ; RP034 BNE 10$ ;;;IF NE NO ; RP034 BIS #CS.ABO,CSTAT(R3) ;;;YES, INDICATE AN ABORT CONDITION ; RP046 10$: RETURN ;;;RETURN ; RP034 ;**-2 ;+ ; **-MSPWF-TS11/TS04 POWERFAIL ENTRY POINT ; ; POWERFAIL IS THE SAME AS INITIALIZE. OUTSTANDING REQUESTS ARE ; HANDLED VIA THE DEVICE TIMEOUT FACILITY. THIS IS DONE TO AVOID ; A RACE CONDITION THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ; THIS IS A GOOD TIME TO CALCULATE ALL SEMI-STATIC POINTERS. ; ; INPUTS: ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- MSPWF: BISB #US.PWF,U.STS(R5) ;SET POWERFAIL FLAG ; RP046 MOV R5,R0 ;COPY UCB BASE ADDRESS ; RP046 ADD #U.CDAT,R0 ;ADD OFFSET TO PRODUCE VIRTUAL ... ; RP046 MOV R0,U.CRP(R5) ;... ADDRESS OF CHARACTERISTICS DATA ; RP046 ADD #U.MSGB-U.CDAT,R0 ;ADD OFFSET FROM OFFSET ... ; RP046 MOV R0,U.CDAT(R5) ;... TO COMPUTE POINTER TO MESSAGE ... ; RP046 CLR U.CDAT+2(R5) ;... AND CLEAR HIGH ORDER BITS ; RP046 ADD #U.CMDB+2-U.MSGB,R0 ;ADD OFFSET FROM OFFSET ... ; RP046 BIC #MODUL4,R0 ;... AND ALIGN ON DOUBLE WORD BOUNDARY .; RP046 MOV R0,U.CBP(R5) ;... TO MAKER POINTER TO COMMAND BUFFER ; RP046 RETURN ;EXIT ; RP046 ;**-10 ;+ ; **-MSOUT-TS11/TS04 TIMEOUT ENTRY POINT ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED. ; IF THE OPERATION WAS DIAGNOSTIC, THE QIO REQUEST IS TERMINATED. ; TIMEOUTS ARE USUALLY CAUSED BY POWER FAILURE BUT MAY ALSO BE THE ; RESULT OF HARDWARE CONSIDERATIONS. IN PARTICULAR, A LENGTHY ; SPACING OPERATION OR A REWIND ON THIS MODEL TAPE DRIVE MAY ; RESULT IN A TIMEOUT WHICH WILL BE IGNORED. ; ; INPUTS: ; R0 = LITERAL CONSTANT IE.DNR ; R2 = CSR ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- .ENABL LSB ; RP023 MSOUT: BIT #CS.ABO,CSTAT(R3) ;;;BEEN TOLD TO ABORT? ; RP046 BNE 10$ ;;;IF NE YES - ABORT ;**-1 BIT #CS.WSS,CSTAT(R3) ;;;WAITING FOR SUB-SYSTEM READY? ; RP046 BNE 30$ ;;;IF NE YES ;**-1 BIT #CS.RSP,CSTAT(R3) ;;;REWIND/SPACE IN PROGRESS ; RP046 BNE 40$ ;;;IF NE YES ;**-1 BIS #CS.TMO,CSTAT(R3) ;;;SET TIMEOUT IN PROGRESS ; RP046 ;**-1 ; RP023 .IF DF E$$DVC ; RP023 ; RP023 CALL DVER ;;;LOG TIMEOUT ERROR ; RP023 ; RP023 .ENDC ; RP023 ; RP023 ; RP023 10$: MTPS #0 ;;;LOWER PRIORITY ; RP023 BIT #M.SER,U.CW2(R5) ;SELECT ERROR IN PROGRESS? ; RP023  BNE NORDY ;IF NE YES ; RP023 MSOUT1: CLR R1 ;ZERO STATUS RETURN ; RP023 CALLR IODON ;EXIT ; RP023 20$: MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMER ; RP023 RETURN ;;;EXIT ; RP023 30$: TSTB (R2) ;;;SUB-SYSTEM READY? ; RP023 BPL 40$ ;;;IF PL NO ; RP023 MTPS #0 ;LOWER PRIORITY ; RP023 INCB S.STS(R4) ;SET CONTROLLER BUSY ; RP023 BIC #CS.WSS,CSTAT(R3) ;RESET WAITING FOR SUB-SYSTEM READY ; RP046 ;FLAG ;**-1 CALLR @SSRRTY(R3) ;RETRY AT SUB-SYSTEM READY RETRY HANDLER; RP023 40$: DECB S.STS(R4) ;;;SUB-SYSTEM RECOVERY TIMED OUT? ; RP023 BEQ 10$ ;;;IF EQ YES, RETURN IE.DNR ; RP023 BR 20$ ;;;OTHERWISE GIVE IT MORE TIME ; RP023 .DSABL LSB ; RP023 ;+ ; RP023 ; **-NORDY - TAPE UNIT NOT READY ROUTINE ; RP023 ; ; RP023 ; THIS ROUTINE WILL SEND OPERATOR "SELECT ERROR" ; RP023 ; MESSAGE AND DETERMINE WHETHER TO RETURN TO USER OR ; RP023 ; RETRY THE REQUESTED OPERATION ; RP023 ; ; RP023 ; INPUTS: ; RP023 ; R3 = CONTROLLER INDEX ; RP023 ; R4 = SCB ADDRESS ; RP023 ; R5 = UCB ADDRESS ; RP023 ; ; RP023 ;- ; RP023 ; RP023 NORDY: BIT #CS.NER!CS.UMD!CS.ABO,CSTAT(R3) ;RETURN TO REQUESTOR? ; RP046 BNE 10$ ;IF NE YES ;**-1 TST U.ACP(R5) ; ACP ALSO WANTS RETURN BEQ 20$ ;IF EQ NO ; RP023 10$: MOV #IE.DNR&377,R0 ;INSURE PROPER MESSAGE RETURNED ; RP023 BR MSOUT1 ;AND EXIT ; RP023 20$: MOV U.CBP(R5),R2 ;RETRIEVE COMMAND BUFFER POINTER ; RP023 CMP #NORDY1,INTADD(R3) ;HAVE WE BEEN HERE BEFORE? ; RP023 BEQ NORDY0 ;IF EQ YES ; RP023 MOV (R2),CMDHDR(R3) ;SAVE COMMAND HEADER ; RP023 MOV #CC.GST,(R2) ;SET GET STATUS COMMAND ; RP023 MOVB S.ITM(R4),TMOCNT(R3) ;SAVE TIMEOUT COUNT ; RP023 MOVB #2.,S.ITM(R4) ;SET TIMEOUT ; RP023 MOV INTADD(R3),RTYINT(R3) ;SAVE INTERRUPT ADDRESS ; RP023 MOV #NORDY1,INTADD(R3) ;SET INTERMEDIATE INTERRUPT ADDRESS ; RP023 NORDY0: CALLR INITIO ;GO GET STATUS ; RP023 NORDY1: BIT #M.SER,U.CW2(R5)  ;SELECT ERROR REMAIN SET? ; RP023 BNE 10$ ;IF NE YES ; RP023 MOV U.CBP(R5),R2 ;RETRIEVE COMMAND BUFFER POINTER ; RP023 MOV CMDHDR(R3),(R2) ;RETRIEVE COMMAND HEADER ; RP023 MOV RTYINT(R3),INTADD(R3) ;RETRIEVE INTERRUPT ADDRESS ; RP023 MOVB TMOCNT(R3),S.ITM(R4) ;RETRIEVE TIMEOUT COUNT ; RP023 BR NORDY0 ;RETRY PREVIOUS COMMAND ; RP023 10$: MOVB #8.,S.STS(R4) ;SET EXTENDED TIMEOUT VALUE ; RP023 MOVB #2.,S.CTM(R4) ;SET TIMEOUT VALUE ; RP023 MOV #T.NDSE,R0 ;INSURE PROPER MESSAGE RETURNED ; RP023 CALLR $DVMSG ;SEND OPERATOR MESSAGE ; RP023 ; PB116 ;+ ; **-$MSINT-TS11/TS04 MAGNETIC TAPE CONTROLLER INTERRUPTS ;- INTSE$ MS,PR5,T$$S11 ;;;SAVE REGISTERS & SET PRIORITY BIT #CS.CIP,CSTAT(R4) ;;;IS A COMMAND IN PROGRESS? ; RP046 BNE 5$ ;;;IF NE YES ;**-1 RETURN ;;;OTHERWISE EXIT ; RP023 5$: CALL $FORK ;;;CREATE A SYSTEM PROCESS ; RP023 MOV R4,R3 ;COPY CONTROLLER INDEX ; RP023 MOV U.SCB(R5),R4 ;PICK UP SCB ADDRESS MOV @S.CSR(R4),R1 ;SAVE DEVICE STATUS. MOV R1,U.MSGB+TSSRC(R5) ;SAVE DEVICE STATUS. MOV R5,R2 ;COPY UCB ADDRESS ; RP023 ADD #U.MSGB+TSXSR0,R2 ;AND POINT TO EXTENDED STATUS ; RP023 ;REGISTER ; RP023 BIT #M.TMK!M.BOT,U.CW2(R5) ;TAPE MARK SEEN LAST TIME? ; RP023 BEQ 10$ ;IF EQ NO ; RP023 BIS #M.PEOV,U.CW2(R5) ;YES, SET FLAG FOR EOV CHECK ; RP047 10$: BIC #NEWBTS!M.TMK,U.CW2(R5) ;CLEAR STATUS BITS TO BE ;**-1 ;DETERMINED ; RP023 BIT #X0.PED,(R2) ;PHASE ENCODED DRIVE? ; RP023 BEQ 20$ ;IF EQ NO ; RP023 BIS #M.1600,U.CW2(R5) ;YES, SET 1600 BPI PHASE ENCODED ; RP023 ;STATUS ; RP023 20$: BIT #X0.BOT,(R2) ;TAPE AT BOT? ; RP023 BEQ 30$ ;IF EQ NO ; RP023 BIS #M.BOT,U.CW2(R5) ;YES, SET BOT STATUS ; RP023 30$: BIT #X0.EOT,(R2) ;TAPE AT EOT? ; RP023 BEQ 40$ ;IF EQ NO ; RP023 BIS #M.EOT,U.CW2(R5) ;YES, SET EOT STATUS ; RP023 40$: BIT #X0.TMK,(R2) ;TAPE MARK DETECTED? ; RP023 BEQ 50$ ;IF EQ NO ; RP023 BIS #M.TMK,U.CW2(R5) ;YES, SET TAPE MARK DETECTED STATUS ; RP023 50$: BIT #X0.WLK,(R2) ;WRITE LOCK STATUS? ; RP063 BEQ 60$ ;IF EQ NO ;**-1 BIS #M.HWL,U.CW2(R5) ;YES, SET HARDWARE WRITE LOCK STATUS ; RP023 60$: BIT #SR.OFL,R1 ;UNIT GO OFFLINE? ; RP023 BEQ 70$ ;IF EQ NO ; RP023 BIS #M.SER,U.CW2(R5) ;YES, SET SELECT ERROR STATUS ; RP023 70$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESS ; RP023 MOV U.CW2(R5),R2 ;COPY STATUS BITS ; RP048 BIC #^C,R1 ;CLEAR ALL BUT TERMINATION CODE ; RP023 CMPB U.MSGB(R5),MESSAG(R1) ;DOES MESSAGE MATCH TC? BEQ 80$ ;IF EQ YES ; RP023 MOV #SR.TC2!SR.TC1,R1 ;SETUP FATAL ERROR CODE ; RP023 80$: CALLR @ERJTBL(R1) ;GO PROCESS INTERRUPT ; RP023 ; PB116 ;+ ; CODE FOR THE TREATMENT OF THE EIGHT (10) TERMINATION CODES ; RETURNED WITH FAIL, ERROR, AND ATTENTION MESSAGES. ; ; INPUTS: ; R0 = IS.SUC&377 ; RP023 ; R2 = CONTENTS OF U.CW2(R5) ; RP048 ; R3 = CONTROLLER INDEX ;**-1 ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- ; RP023 ; RP023 ; ; TERMINATION CLASS 0 (AN END MSG) ; TCL0ER: BIT #CS.LBA,CSTAT(R3) ;WRITTEN CHARACTERISTICS? ; RP046 BEQ TCEXIT ;IF EQ NO - FINISH PROCESSING ;**-1 ; ; TERMINATION CLASS CODE 1 (ATTENTION CONDITION) ; TCL1ER: BIC #CS.LBA,CSTAT(R3) ;CLEAR LOADING BUFFER ADDRESS FLAG ; RP046 CALLR ILDBA ;RESTART THE USER'S REQUEST ;**-1 ; PB116 ; ; TERMINATION CLASS 2 (TAPE STATUS ALERT) ; TCL2ER: BIT #M.EOT,R2 ;EOT DETECTED? ; RP048 BEQ 10$ ; IF EQ NO ;**-1 CMPB #CC.WRD,@U.CBP(R5) ;IS IT A WRITE COMMAND? ; RP045 BEQ 5$ ;IF EQ YES ; RP031 ; ; RP031 ; WRITE COMMANDS MUST LOOK FOR PHYSICAL END-OF-TAPE (M.EOT) ; RP031 ; ; RP031 CMPB #CC.WTM,@U.CBP(R5) ;IS IT A WRITE TAPE MARK COMMAND? ; RP045 BEQ 5$ ;IF EQ YES ; RP031 ; ; RP031 ; WRITE TAPE MARK COMMANDS MUST LOOK FOR PHYSICAL END-OF-TAPE (M.EOT) ; RP031 ; ; RP031 CMPB #CC.ERS,@U.CBP(R5) ;IS IT AN ERASE COMMAND? ; RP045 BNE 10$ ;IF NE NO ; RP031 ; ; RP031 ; ERASE COMMANDS MUST LOOK AT PHYSICAL END-OF-TAPE ; RP031 ; ; RP031 5$: MOV #IE.EOT&377,R0 ;SET EOT FOR RETURN ; RP031 10$: BIT #M.TMK,R2 ;TAPE MARK DETECTED? ; RP048 BEQ 20$ ;IF EQ NO ;**-2 MOV #IE.EOF&377,R0 ;SET EOF FOR RETURN ; RP023 ; ; RP023 ; NOTE: EOF OVERRIDES EOT IF OCCURRING ON THE SAME COMMAND ; RP023 ; ; RP023 20$: BIT #X0.RLL,U.MSGB+TSXSR0(R5) ; RECORD LENGTH LONG? BEQ TCEXIT ;FINISH PROCESSING ; RP023 MOV #IE.DAO&377,R0 ; SET RECORD LONG  BR TCEXIT ;FINISH PROCESSING ; RP023 ; PB116 ; ; TERMINATION CLASS CODE 3 (FUNCTION REJECT) ; TCL3ER: BIT #CS.GST,CSTAT(R3) ;IS A GET STATUS IN PROGRESS? ; RP046 BNE TCEXIT ;IF NE YES ;**-1 BIT #M.SER,R2 ;UNIT GO OFFLINE? ; RP048 BEQ 10$ ; IF EQ NO ;**-1 CALLR NORDY ;SEND SELECT ERROR MESSAGE ; RP023 10$: BIT #X0.VCK!X0.ILC!X0.ILA,U.MSGB+TSXSR0(R5) ;HARD ERROR? BNE TCL6ER ;IF NE YES, FATAL ; RP023 BIT #M.HWL,R2 ;WRITE LOCK STATUS? ; RP048 BEQ TCEXIT ;IF EQ NO ;**-1 MOV #IE.WLK&377,R0 ; SET WRITE LOCK TCEXIT: CALLR @INTADD(R3) ;PROCESS TO COMPLETION ; RP023 ; PB116 .ENABL LSB ; PB116 ; ; TERMINATION CLASS CODE 4 (RECOVERABLE ERROR - 1 BLOCK DOWN) ; TCL4ER: ;REF LABEL ; RP023 ; RP023 ; RP023 .IF DF E$$DVC ; RP023 ; RP023 CALL DVER ;LOG ERROR ; RP023 ; RP023 .ENDC ; RP023 ; RP023 ; RP023 BIT #CS.NER!CS.UMD,CSTAT(R3) ;RETRIES PROHIBITED? ; RP046 BNE 50$ ; IF NE YES - EXIT ;**-1 MOV U.CBP(R5),R2 ; RETRIEVE COMMAND BUFFER POINTER MOV (R2),R0 ; RETRIEVE COMMAND HEADER WORD CMP #CC.WRD,R0 ; WRITE COMMAND? BNE 10$ ; IF NE NO SKIP CHECK BIT #M.IWR,U.CW2(R5) ;WRITE EXTEND PROHIBITED? BNE 50$ ; IF NE YES - EXIT 10$: BIC #^C,R0 ; CLEAR ALL BUT LOW 2 BITS CMP #1,R0 ; RETRYABLE COMMAND? BNE TCL6ER ;IF NE NO, FATAL HARDWARE ERROR ; RP023 DECB RTTBL(R3) ; DECREMENT RETRY COUNT BEQ 50$ ; IF EQ RETRIES EXHAUSTED  CMPB #THRES1,RTTBL(R3) ; REACHED FIRST THRESHOLD? BHIS 20$ ; YES TIME FOR OPPOSITE RETRY BIS #CM.RTY,(R2) ; SET RETRY COMMAND BIT BR AGAIN ;AND RE-ISSUE COMMAND ; RP023 ; ; AN OPPOSITE RETRY CAN ONLY OCCUR FOR READ OPERATIONS. ALL OTHER ; COMMANDS WILL SKIP THIS RETRY SET AND PROCEED IMMEDIATLY TO THE ; NEXT STEP WHICH CONSISTS OF DOING A CLEAN OPERATION BEFORE ISSUANCE ; OF THE COMMAND. READ OPERATIONS WHICH INDICATE THAT THE ACTUAL RECORD ; SIZE ON TAPE DOES NOT EQUAL THE BUFFER SIZE SPECIFIED MUST ALSO SKIP THIS ; STEP. ; 20$: CMPB #THRES2,RTTBL(R3) ; TIME FOR CLEAN ? BHIS 30$ ; YES GO TO ALTERNATE RCOVERY BIT #X0.RLL!X0.RLS,U.MSGB+TSXSR0(R5) ; RECORD LENGTH OFF? BNE 30$ ; YES CAN'T DO OPPOSITE MOV (R2),R0 ; RETRIEVE COMMAND HEADER BIC #^C,R0 ; CLEAR ALL BUT COMMAND CODE CMP #CC.RDN,R0 ; IS IT A READ OPERATION? BNE 30$ ; IF NE NO GO DO CLEAN BIS #CM.OPP,(R2) ; ALLS WELL SET OPPOSITE BR AGAIN ;ISSUE OPPOSITE COMMAND ; RP023 30$: SETRTY CLN,RTNCLN ; SETUP FOR CLEAN FUNCTION BR AGAIN ;ISSUE CLEAN ; RP023 ; ; TERMINATION CLASS CODE 5 (RECOVERABLE ERROR - TAPE NOT MOVED) ; TCL5ER: ;REF LABEL ; RP023 ; RP023 ; RP023 .IF DF E$$DVC ; RP023 ; RP023 CALL DVER ;LOG ERROR ; RP023 ; RP023 .ENDC ; RP023 ; RP023 ; RP023 DECB RTTBL(R3) ; DECREMENT RETRY COUNT BNE AGAIN ;RE-ISSUE COMMAND ; RP023 50$: MOV #IE.VER&377,R0 ;SET UNRECOVERABLE ERROR ; RP023 BR TCEXIT ;FINISH PROCESSING ; RP023 ; ; TERMINATION CLASS CODE 7 (FATAL CONTROLLER ERROR) ; RP023 ; ; RP023 TCL7ER: CLR @S.CSR(R4) ; INIT CONTROLLER MOV #TCL6ER,SSRRTY(R3) ;SETUP SUB-SYSTEM READY RETRY ; RP023 ;HANDLER ; RP023 BIS #CS.WSS,CSTAT(R3) ;SET WAITING FOR SUB-SYSTEM READY ; RP046 ;FLAG ;**-1 MOV #5.*256.+5.,S.CTM(R4) ;SET 5 SECOND TIMER ; RP023 MOVB #60.,S.STS(R4) ;SET EXTENDED TIMEOUT (5 MINUTES) ; RP023 RETURN ;EXIT ; RP023 ; RP023 ; ; TERMINATION CLASS CODE 6 (UNRECOVERABLE ERROR) ; TCL6ER: MOV #IE.FHE&377,R0 ; SET FATAL ERROR STATUS ; RP023 ; RP023 .IF DF E$$DVC ; RP023 ; RP023 CALL DVER ;LOG ERROR ; RP023 ; RP023 .ENDC ; RP023 ; RP023 ; RP023 BR TCEXIT ;FINISH PROCESSING ; RP023 .DSABL LSB ; PB116 ; PB116 ;+ ; **- IRREV - READ REVERSE COMPLETION ;- ; RP023 IRREV: BIC #M.TMK,U.CW2(R5) ; DON'T SET FOR REVERSE OPERATIO BR IOCOM ; DO COMMON COMPLETION FOR TRANSFER ;+ ; **- IWRMK - WRITE TAPE MARK COMPLETION ;- ; RP023 IWRMK: BIT #M.HWL,R2 ;UNIT HARDWARE WRITE LOCKED? ; RP063 BNE IOCOM ;IF NE YES ; RP063 MOV #IS.SUC&377,R0 ;NO, SET SUCCESS STATUS ; RP063 BR IOCOM ; AND GO TO COMMON EXIT ;**-1 ;+ ; RP023 ; **- IMOUNT - CHECK FOR BOT DURING MOUNT AND SET CHARACTERISTICS ; RP023 ;- ; RP023 ; RP023 IMOUNT: BIT #M.SER,R2 ;UNIT OFFLINE? ; RP048 BNE 10$ ;IF NE YES ;**-1 BIT #M.BOT,R2 ;AT BOT? ; RP048 BNE ISTAT ;IF NE YES ;**-1 10$: MOV #IE.FHE&377,R0 ;NO, FATAL HARDWARE ERROR ; RP023 ; RP023 ;+ ; **- ISTAT - STATUS EXIT FOR SET, SENSE, AND MOUNT AND SET ;- ; RP023 ISTAT: MOV U.CW2(R5),R1 ;SET STATUS WORD 1 IN R1 ; RP023 BR IODON ;AND EXIT ; RP023 ; RP023 ;+ ; **-RTNCLN - RETRY COMMAND AFTER CLEAN ;- ; RP023 RTNCLN: MOV RTYINT(R3),INTADD(R3) ; RESTORE INTERRUPT ADDRES TSTB R0 ; ERROR ON CLEAN? BMI TCL6ER ;IF MI YES, TAPE POSITION LOST - EXIT ; RP023 MOV U.CBP(R5),R2 ; RETRIEVE COMMAND BUFFER POINTER MOV CMDHDR(R3),(R2) ; RESTORE ORIGINAL COMMAND MOVB #8.,S.ITM(R4) ; RESET TIMEOUT COUNT AGAIN: CALLR INITIO ;RE-ISSUE COMMAND ; RP023 ; PB116 ;+ ; PB116 ; **- ISPCB - SPACE BLOCKS COMPLETION ;- ; RP023 ; RP023 ISPCB: BIT #CC.SRR-CC.SRF,@U.CBP(R5) ;SPACE REVERSE FUNCTION? BEQ 10$ ; IF EQ NO - CHECK FOR EOV BIC #M.TMK,U.CW2(R5) ; CLEAR TAPE MARK ON REVERSE BR IOCOM ; GO TO COMMON EXIT 10$: ; REFERENCE LABEL ; RP023 ; RP023 .IF DF A$$NSI BITB #US.LAB,U.STS(R5) ;ANSII LABELED TAPE? BNE IOCOM ; IF NE YES CAN'T BE EOV .ENDC ; RP023 BIT #M.PEOV,U.CW2(R5) ;TAPE MARK DETECTED LAST TIME ; RP047 BEQ IOCOM ; IF EQ NO - CAN'T BE EOV ;**-1 BIT #M.TMK,U.CW2(R5) ; TAPE MARK SEEN THIS TIME? BEQ IOCOM ; IF EQ NO - CAN'T BE EOV MOV U.CNT(R5),R1 ; RETRIEVE REQUESTED COUNT SUB U.MSGB+TSRBPC(R5),R1 ; LESS RESIDUAL CMP #1,R1 ; ONLY ONE SPACED? BNE IOCOM ; IF NE NO - NOT EOV ; ; AT EOV - DOING SPACE BLOCKS - NEED TO REPOSITION TAPE ; MOV U.CBP(R5),R2 ; SET COMMAND BUFFER POINTER SETRTY SRR,SBRPOS,1 ;SET OPERATION ; RP023 BR AGAIN ;RE-ISSUE COMMAND ; RP023 ; RP023 ;+ ; **-SBRPOS - RETURN FROM REPOSITIONING DURING SPACE BLOCKS ; RP023 ;- ; RP023 SBRPOS: MOV #IE.EOV&377,R0 ;SET EOV STATUS ; RP023 CLR R1 ; SET COUNT BIS #M.AEOV,U.CW2(R5) ;SET POSITIONED AT EOV ; RP047 BR IODON ;AND EXIT ;**-1 ; RP023 ;+ ; **- ISPCF - SPACE FILES COMPLETION ;- ISPCF: BIT #CC.STR-CC.STF,@U.CBP(R5) ;SPACE REVERSE? ; PB116 BEQ 10$ ; IF EQ NO - CHECKK EOV BIC #M.TMK,U.CW2(R5) ;CLR BIT FOR REVERSE BR IOCOM ; AND EXIT 10$: BIT #X0.LET,U.MSGB+TSXSR0(R5) ; AT LEOT? BEQ IOCOM ; IF EQ NO - EXIT ; ; RP023 ; AT EOV - DOING SPACE FILE - NEED TO REPOSITION TAPE ; RP023 ; ; RP023 MOV U.CBP(R5),R2 ;GET COMMAND BUFFER POINTER ; RP023 SETRTY STR,SFRPOS,1 ;SPACE ONE TAPE MARK REVERSE ; RP023 BR AGAIN ;DO IT ; RP023 ; RP023 ;+ ; RP023 ; **-SFRPOS - RETURN FROM REPOSITIONING DURING SPACE FILES ; RP023 ;- ; RP023 ; RP023 SFRPOS: MOV #IE.EOV&377,R0 ;SET EOV STATUS ; RP023 BIS #M.AEOV,U.CW2(R5) ;SET POSITIONED AT EOV ; RP047 ;**-1 ;+ ; ; **- IOCOM - COMMON EXIT ROUTINE FOR ALL ROUTINES REQUIRING STATUS ;- ; RP023 IOCOM: MOV U.CNT(R5),R1 ; RETRIEVE REQUESTED COUNT SUB U.MSGB+TSRBPC(R5),R1 ; LESS RESIDUAL COUNT ;+ ; **- IODON - COMMON EXIT FOR ALL FUNCTIONS ; RP023 ;- ; RP023 IODON: ;REF LABEL ; RP023 ; RP023 ; RP023 .IF DF D$$IAG CALL MSDINT ; CALL DIAGNOSTIC COMPLETION .ENDC ; RP023 .IF DF E$$DVC MOVB RTTBL(R3),R2 ;GET REMAINING RETRY COUNT ; RP023 BIS #RETRY*256.,R2 ;MERGE ORIGINAL RETRY COUNT ; RP023 .ENDC ; RP023 BIC #CS.CIP,CSTAT(R3) ;RESET COMMAND IN PROGRESS FLAG ; RP046 BIC #M.PEOV!M.RWD,U.CW2(R5) ;RESET EOV STATUS CHECK AND ...; RP047 ;... REWINDING FLAG ; RP047 CALL $IODON ; CALL COMPLETION ;**-2 JMP MSINI ; GO CHECK FOR ANOTHER REQUEST ; PB116 ; PB116 .IF DF E$$DVC ;%%% 1 %%% ; RP023 ;+ ; **-DVER-TO INTERFACE WITH THE ERROR LOGGER. ; ; THE ERROR LOGGER ASSUMES (ERRONEOUSLY) THAT THE REGISTERS OF ; INTEREST ARE THE HARDWARE REGISTERS IN THE I/O PAGE POINTED TO ; BY S.CSR. MOST OF THE STATUS INFORMATION FOR THE TS04 IS FOUND ; IN THE MESSAGE BUFFER ("EXTENDED STATUS REGISTERS") IN THE UCB. ; WE MUST, THEREFORE, CORRUPT OUR SCB TO MAKE S.CSR CONTAIN THE ; ADDRESS OF THE MESSAGE BUFFER AND THEN RESTORE IT ON RETURN. ; "TSSR", THE ONLY REAL HARDWARE REGISTER, IS COPIED INTO A SLOT IN ; THE MESSAGE BUFFER NORMALLY WHEN WE LOOK AT IT. ; ; INPUT: ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ERROR MESSAGE BUFFER (EMB) FILLED "CORRECTLY". ; ;- DVER: BIT #CS.UMD,CSTAT(R3) ;USER MODE DIAGNOSTIC IN PROGRESS? ; RP046 BNE 10$ ;YES=> SKIP THIS REPORT; ELSE ;**-1 MOV S.CSR(R4),-(SP) ;PUSH (SAVE) CSR ADDRESS. MOV #U.CBP,S.CSR(R4) ;USE DRIVER SPECIFIC DDB ADD R5,S.CSR(R4) ; ADDRESS TO FOOL ERR LOG. BIT #CS.TMO,CSTAT(R3) ;TIMEOUT TO LOG? ; RP046 beq 3$ ;no=>plain log; else ;**-1 call $dtoer ;log the error with timeout. br 7$ ;restore the data base. 3$: CALL $DVERR ;LOG THE ERROR 7$: MOV (SP)+,S.CSR(R4) ;RESTORE THE CSR ADDRESS. 10$: RETURN ;RETURN TO CALLER. ; RP023 .ENDC ;%%% 1 %%% ; PB116 .IF DF D$$IAG ;%%% 1 %%% ;+ ; **-MSDINT-TS11 DIAGNOSTIC INTERRUPT AND TIMEOUT HANDLER ; ; IF ENTRY WAS FROM A DIAGNOSTIC CONTROL FUNCTION, THEN MOVE THE ; I/O PACKET WORDS 17 & 20 TO WORDS 20 & 21 FOR THE $CRPAS ROUTINE. ; FOR ANY DIAGNOSTIC FUNCTION, PASS THE UNIBUS DEVICE REGISTERS ; AND THE EXTENDED STATUS REGISTERS VIA THE $CRPAS ROUTINE. ; ; INPUTS: ; ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; RP023 ; ; OUTPUTS: ; CARRY BIT CLEAR = NON-DIAGNOSTIC FUNCTION ; CARRY BIT SET = DIAGNOSTIC FUNCTION ; ;- MSDINT: BIT #CS.UMD,CSTAT(R3) ;NON-DIAGNOSTIC FUNCTION? ; RP046 BEQ 30$ ;TRUE=> FINISHED; ELSE DO THINGS ... ;**-1 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOV #U.MSGB,R2 ;LOAD MESSAGE BUFFER OFFSET. ADD R5,R2 ;ADD IN UCB ADDRESS. CMPB #IO.EOF/256.,I.FCN+1(R1) ;WRITE EOF FUNCTION? BEQ 10$ ;IF EQ YES CMPB #IO.RWD/256.,I.FCN+1(R1) ;REWIND FUNCTION?  BEQ 10$ ;IF EQ YES CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC BR 20$ ;GO TO EXIT 10$: MOV I.PRM+14(R1),I.PRM+16(R1) ;MOVE PACKET WD20 TO WD21 MOV I.PRM+12(R1),I.PRM+14(R1) ;MOVE PACKET WD17 TO WD20 CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS ; RP023 MOV I.PRM+14(R1),I.PRM+12(R1) ;MOVE WD20 BACK TO WD 17 MOV I.PRM+16(R1),I.PRM+14(R1) ;MOVE WD21 BACK TO WD20 20$: MOV (SP)+,R2 ;RESTORE R2 ; RP023 MOV (SP)+,R1 ;RESTORE R1. 30$: REJTURN ;EXIT TO CALLER .ENDC ;%%% 1 %%% ; RP023 .END JdTðskQ ›c, .TITLE MTDRV .IDENT /04.15/ ; ; COPYRIGHT (C) 1974,1978,1979,1980,1981 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 04.15/ ; ; SCOTT G. DAVIS 9-JUL-74 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; S. G. DAVIS ; C. A. D'ELIA ; B. LYONS ; T. J. MILLER ; F. L. STRAIGHT ; ; MODIFIED BY: ; ; J. CLEARY 26-APR-77 ; ; JC001 -- POWERFAIL SUPPORT FOR TE10. ; ; P. J. BEZEREDI 04-MAY-77 ; ; PB027 -- TIGHTEN UP DOUBLE INTERRUPT TIMING WINDOW. ; ; P. J. BEZEREDI 06-MAY-77 ; ; PB028 -- CLEAN UP SPACE FUNCTION EXECUTION. ; ; J. CLEARY 20-SEP-77 ; ; JC006 -- INSURE INTERRUPT ENABLE IS CLEARED. ; ; J. CLEARY 23-MAR-78 ; ; JC011 -- CLEAN UP SPACE FUNCTION PATCH ; ; J. CLEARY 24-APR-78 ; ; JC014 -- IGNORE EOT ON READS ; ; J. CLEARY 21-JUN-78 ; ; JC017 -- FIX BUG IN UMR ALLOCATION ; ; J. CLEARY 4-DEC-78 ; ; JC024 -- CLEAR US.ABO TO PREVENT UNINTENDED ABORTS ; ; J. CLEARY 4-DEC-78 ; ; JC025 -- IMPLEMENT IQ.X SUPPRESS RETRIES ; ; J. CLEARY 3-APR-79 ; ; JC036 -- BYPASS CALL TO ERRLOG WHEN SMO RETURNS ERROR ; ; ; JC041 -- FIX PROBLEM IN SENSE CHARACTERISTICS ; ; TL030 -- CHECK THAT A CANCEL IS ISSUED BY THE TASK ; WHICH ISSUED THE CURRENT OPERATION ; ; TL067 -- RETURN THE CORRECT BLOCK COUNT FOR ; IO.SPB AT EOV ; ; TL068 -- FIX BRANCH OUT OF RANGE ; ; TL072 -- DO NOT LOG DATA OVERRUN ; ; TL073 -- RETURN EOV FOR IO.SPF, NOT EOT ; ; CS001 -- TAPE DENSITY SUPPORT IDENTIFICATION IN U.CW3 ; ; CS002 -- DEVICE NOT READY IF TAPE UNIT OFF LINE ; ; CS003 -- BOT STATUS IF TAPE UNIT READY ; ; TM11 MAGNETIC TAPE CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,ABODF$,CLKDF$,UCBDF$ ;CS001 HWDDF$ ;**-1 PKTDF$ ABODF$ CLKDF$ UCBDF$ ; UNIT CONTROL BLOCK OFFSETS ;CS001 .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; EQUATED SYMBOLS ; US.ABO=1 ;ABORT IN PROGRESS - U.STS US.BSP=2 ;INTERNAL BACKSPACE IN PROGRESS - U.STS US.PWF=10 ;POWER FAIL STATUS RETRY=12 ;RETRY COUNT ; ; REGISTER BIT SYMBOLS ; CS.GO=1 ;GO CS.EXM=60 ;EXTENDED MEMORY BITS CS.IE=100 ;INTERRUPT ENABLE CS.RDY=200 ;CONTROLLER READY BIT CS.EVN=4000 ;EVEN PARITY CS.CLR=10000 ;POWER CLEAR CS.DN5=20000 ;556 BPI DENSITY BIT CS.DN8=40000 ;800 BPI DENSITY BIT DS.TUR=1 ;TAPE UNIT READY DS.RWS=2 ;REWINDING DS.HWL=4 ;WRITE LOCK DS.SDN=10 ;SETTLE DOWN DS.7CH=20 ;UNIT IS 7 CHANNEL DS.BOT=40 ;BEGINNING OF TAPE DS.MOL=100 ;MEDIUM ON LINE DS.BTE=400 ;BAD TAPE ERROR DS.RLE=1000 ;RECORD LENGTH ERROR DS.EOT=2000 ;END OF TAPE DETECTED DS.BGL=4000 ;BUS GRANT LATE DS.PAE=10000 ;PARITY ERROR DS.CRE=20000 ;CYCLICAL REDUNDANCY ERROR DS.TM=40000 ;TAPE MARK DETECTED DS.ILG=100000 ;ILLEGAL COMMAND RD.GAP=10000 ;GAP SHUTDOWN IN PROGRESS RD.LPC=40000 ;READ LPC CHARACTER AND RTTBL FLAG ; ; MAG TAPE STATUS REGISTER BIT DEFINITIONS (SENSE AND SET CHARACTERISTICS) ; M.PEOV=100000 ;TAPE PAST LOGICAL END OF VOLUME M.AEOV=40000 ;TAPE AT LOGICAL END OF VOLUME M.BOT=20000 ;TAPE AT BOT M.7CH=10000 ;UNIT IS 7 CHANNEL M.HWL=2000 ;HARDWARE WRITE LOCK M.RWD=1000 ;UNIT IS REWINDING M.SER=400 ;SELECT ERROR HAS OCCURED M.IXG=200 ;INHIBIT WRITE WITH EXTENDED INTERRECORD M.SWL=100 ;SOFTWARE WRITE LOCK M.EOF=40 ;LAST COMMAND ENCOUNTERED TAPE MARK M.EOT=20 ;LAST COMMAND ENCOUNTERED EOT M.EVN=10 ;EVEN PARITY M.CDM=4 ;CORE DUMP MODE (7 CHANNEL ONLY) M.200=2 ;200 BPI (7 CHANNEL ONLY) M.556=1 ;556 BPI (7 CHANNEL ONLY) USRBTS=317 ;STATUS BITS CONTROLLED BY THE USER NEWBTS=M.PEOV!M.BOT!M.EOF!M.EOT ;STATUS BITS TO BE SET BEFORE $IODON ; ; COMMANDS ; RWU=101 ;REWIND AND OFFLINE RED=103 ;READ WRT=105 ;WRITE WEF=107 ;WRITE END-OF-FILE SPF=111 ;SPACE FORWARD SPR=113 ;SPACE REVERSE WTE=115 ;WRITE WITH EXTENDED GAP RWD=117 ;REWIND U.SPC = U.VCB+2 ; SPACING COUNT, RDBLK TEMP. ;CS001 ;CS001 ; ; LOCAL MACROS ; ; ; THE FOLLOWING MACRO DEFINES ENTRIES IN THE FUNCTION TABLE ; .MACRO DFENT COM,TIMOUT,PWF,OPCODE,TYPE,INTADD .WORD COM .BYTE PWF,TIMOUT .BYTE TYPE,OPCODE .WORD INTADD .ENDM DFENT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; ; DIAGNOSTIC FUNCTIONS USE BITS 14-15 OF RTTBL AS FLAGS FOR ; INTERRUPT AND FUNCTION HANDLING. CNTBL: .BLKW T$$M11 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW T$$M11 ;ERROR RETRY COUNT SPTBL: .BLKW T$$M11 ;FOR SPACE CHECKING INTADD: .BLKW T$$M11 ;CURRENT INTERRUPT SERVICE ADDRESS .IF GT T$$M11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; LEGAL FUNCTION DISPATCH TABLE ; LGFCN: DFENT IO.RLB,8.,0,RED,0,RDBLK ;READ LOGICAL BLOCK DFENT IO.WLB,6.,0,WRT,0,WRBLK ;WRITE LOGICAL BLOCK DFENT IO.EOF,2.,0,WEF,0,WREOF ;WRITE TAPE MARK DFENT IO.RWD,2.,1,RWD,0,REWND ;REWIND DFENT IO.RWU,2.,1,RWU,0,REWND ;REWIND THEN OFF-LINE DFENT IO.SPB,8.,0,SPF,1,SPCBK ;SPACE BLOCK DFENT IO.SPF,8.,0,SPF,2,SPCFL ;SPACE FILE DFENT IO.STC,0,-1,0,-1,-1 ;SET CHARACTERISTICS DFENT IO.SEC,0,-1,1,-1,-1 ;SENSE CHARACTERISTICS DFENT IO.SMO,0,1,-1,-1,-1 ;MOUNT AND SET CHARACTERISTICS ENDFCN=. ;END OF FUNCTION TABLE ; ; DRIVER DISPATCH TABLE ; $MTTBL::.WORD MTINI ;DEVICE INITIATOR ENTRY POINT .WORD MTCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD MTOUT ;DEVICE TIMEOUT ENTRY POINT .WORD MTPWF ;POWERFAIL ENTRY POINT ;+ ; **-MTINI-TM11 MAGNETIC TAPE CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB MTINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCC 10$ ;IF CC PROCESS REQUEST RETURN ;NOTHING TO DO OR CONTROLLER BUSY ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; TM11 MAGNETIC TAPE FUNCTION INDEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB/IO.RWD/IO.SPB/IO.SPF/IO.EOF). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; 10$: MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB MOV #$MTCLK,S.MTCK+C.SUB(R4) ;SET ADDR OF CLOCK ROUTINE CLR S.FRK+2(R4) ;INIT FORK PC WORD MOV #LGFCN,R2 ;POINT TO LEGAL FUNCTION TABLE MOV I.FCN(R1),R0 ;GET FUNCTION CODE .IF DF D$$IAG CLRB RTTBL+1(R3) ;CLEAR DIAGNOSTIC FLAG MOV I.FCN(R1),R0 ;GET FUNCTION CODE BITB #IQ.UMD,R0 ;DIAGNOSTIC FUNCTION CALL? BEQ 20$ ;IF EQ NO MOV #100000,RTTBL(R3) ;STOP RETRIES AND SET DIAG. FLAG CMP #IO.LPC!IQ.UMD,R0 ;READ LPC CHARACTER FUNCTION? BNE 15$ ;IF NE NO BIS #RD.LPC,RTTBL(R3) ;SET LPC READ FLAG MOV #IO.RLB!IQ.UMD,R0 ;CONVERT TO READ LOGICAL MOV R0,I.FCN(R1) ;SAVE FOR LATER USE 15$: BIC #IQ.UMD,R0 ;CLEAR FOR FUNCTION CHECK .IFTF 20$: BICB #IQ.X,R0 ;CLEAR IQ.X IT WILL BE ;CHECKED LATER .ENDC CMP R0,(R2)+ ;FUNCTION CODE MATCH? BEQ 35$ ;IF EQ YES ADD #6,R2 ;POINT TO NEXT TABLE ENTRY CMP R2,#ENDFCN ;AT END OF TABLE? BNE 20$ ;IF NE NO BR 40$ ;ILLEGAL FUNCTION ; ; FUNCTION CODE MATCH FOUND ; .IF DF P$$RFL 35$: BITB #US.PWF,U.STS(R5) ;POWER FAIL OCCUR? BEQ 45$ ;IF EQ NO TSTB (R2) ;LEGAL FUNCTION?  BMI 45$ ;IF MI YES BNE 43$ ;IF NE THIS IS A BETTER ONE .IFTF 40$: MOV #IE.IFC&377,R0 ;SET ILLEGAL FUNCTION JMP 230$ ;INFORM THE USER 43$: BICB #US.PWF,U.STS(R5) ;ALLOW ALL FUNCTIONS .IFF 35$: ;REF LABEL .ENDC 45$: MOV (R2)+,S.CTM(R4) ;SET UP FOR PROPER TIMEOUT CLRB S.CTM(R4) ;CLEAR OUT PWF INFO CLR SPTBL(R3) ;RESET SPACING FLAG CLR U.SPC(R5) ;NOT SPACING FILE ;CS001 TSTB (R2)+ ;DETERMINE TYPE OF OPERATION ;**-1 BPL 50$ ;IF PL NOT STATUS FUNCTION JMP 190$ ;STATUS FUNCTION 50$: BEQ 90$ ;IF EQ NON-SPACING FUNCTION ; ; SPACING FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- SPACING COUNT (POSITIVE=FORWARD, NEGATIVE=BACKWARD). ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- RELOCATON BIAS OF DIAGNOSTIC REG. BLK. ADDRESS ; WD. 20 -- DIAG. REG. BUFFER ADDRESS (REAL OR DISPL. + 140000) ; MOV U.BUF(R5),I.PRM+4(R1) ;MOVE SPACING COUNT TO COMMON PLACE CLR U.BUF(R5) ;RESET TO TAKE ON OPCODE BELOW MOV I.PRM+4(R1),U.CNT(R5) ;MOVE SPACING COUNT TO COMMON PLACE BNE 60$ ;IF NE SOME SPACING REQUIRED CLR I.PRM+4(R1) ;CLEAR COUNT FOR STATUS RETURN ;TL067 JMP 220$ ;NO SPACING REQUIRED 60$: BMI 65$ ;IF MI SPACE REVERS BIT #M.AEOV,U.CW2(R5) ;AT EOV? BEQ 70$ ;IF EQ NO - PROCEED MOV #IE.EOV&377,R0 ;STILL AT EOV CLR I.PRM+4(R1) ;CLEAR COUNT FOR STATUS RETURN ;TL067 JMP 230$ ;TELL THE USER 65$: ;REFERENCE LABEL NEG U.CNT(R5) ;CONVERT TO POSITIVE COUNT NEG I.PRM+4(R1) ;THIS ONE, TOO BIS #2,U.BUF(R5) ;CHANGE SPACE FORWARD TO SPACE REVERSE 70$: CMPB -1(R2),#1 ;SPACE FILE OR SPACE BLOCK? BEQ 80$ ;IF EQ SPACE BLOCK MOV U.CNT(R5),U.SPC(R5) ;SAVE COUNT OF FILES TO SPACE ;CS001 NEG U.SPC(R5) ;SET UP FOR FINAL ACCOUNTING ;CS001 MOV #-1,U.CNT(R5) ;SET UP FOR BIG SPACE ;**-2 80$: MOV U.CNT(R5),SPTBL(R3) ;SAVE SPACING COUNT NEG SPTBL(R3) ;MAKE IT MATCH REGISTER CONTENTS BR 110$ ;SKIP SOME CHECKS AND BIC'S ; ; READ/WRITE LOGICAL FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- RELOCATON BIAS OF DIAGNOSTIC REG. BLK. ADDRESS ; WD. 21 -- DIAG. REG. BUFFER ADDRESS (REAL OR DISPL. + 140000) ; ; NO FUNCTION DEPENDENT PARAMETERS ARE REQUIRED FOR REWIND OR WRITE EOF ; 90$: ;REF LABEL .IF DF M$$EXT&M$$MGE CALL $STMAP ;SET UP UNIBUS MAPPING ADDRESS .ENDC CMPB -2(R2),#2 ;WRITE EOF, REWIND OR REWIND & OFFLINE? BEQ 100$ ;IF EQ YES - SEE IF WRITELOCK SET CMPB (R2),#WRT ;WRITE? BNE 110$ ;IF NE NO MOV #IE.SPC&377,R0 ;ASSUME PARAMETER PROBLEMS CMP I.PRM+4(R1),#14. ;TOO SHORT? BLO 163$ ;IF LO YES BR 105$ ;SKIP EXMEM BIT CLEAR 100$: CLR U.BUF(R5) ;NOTHING THERE FOR WEF CMPB (R2),#WEF ;WRITE EOF? BNE 110$ ;IF NE NO, SKIP CHECK FOR WRITE LOCK 105$: MOV #IE.WLK&377,R0 ;ASSUME (SOFTWARE) WRITE LOCK BIT #M.SWL,U.CW2(R5) ;LOCKED? BNE 163$ ;IF NE YES 110$: BISB (R2)+,U.BUF(R5) ;PICK UP FUNCTION CODE FROM COMMAND TABLE MOV (R2),INTADD(R3) ;SET INITIAL INTERRUPT ADDRESS .IF DF D$$IAG TST RTTBL(R3) ;DIAGNOSTIC FUNCTION CALL? BMI 120$ ;IF MI YES -STOP RETRIES .ENDC MOV #RETRY,RTTBL(R3) ;SET UP RETRY COUNTS 120$: CALL SELECT ;SELECT THE REQUIRED DRIVE BCS SELERR ;IF CS SELECT ERROR OCCURRED MOV U.CW2(R5),R1 ;PICK UP DRIVE'S CHARACTERISTICS BIT #M.EVN,R1 ;EVEN PARITY REQUIRED? BEQ 140$ ;IF EQ NO BIS #CS.EVN,U.BUF(R5) ;SET BIT IN STATUS REGISTER 140$: BIS #CS.DN5!CS.DN8,U.BUF(R5) ;ASSUME 9-CHANNEL, 800BPI BIT #M.7CH,R1 ;7-CHANNEL DRIVE? BEQ 151$ ; IF EQ NO BIT #M.CDM,R1 ;CORE DUMP MODE? BNE 151$ ; IF NE YES BIT #M.556,R1 ;556 BPI? BNE 150$ ;IF NE YES BIC #CS.DN5,U.BUF(R5) ;RESET BIT FOR COMMAND BIT #M.200,R1 ;200 BPI? BEQ 151$ ; IF EQ NO 150$: BIC #CS.DN8,U.BUF(R5) ;RESET COMMAND BIT 151$: JMP 170$ ; RETURN ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED.  ; IF THE OPERATION WAS DIAGNOSTIC, THE QIO REQUEST IS TERMINATED. ; TIMEOUTS ARE USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE ; RESULT OF HARDWARE CONSIDERATIONS. IN PARTICULAR, A LENGTHY SPACING ; OPERATION MAY RESULT IN A TIMEOUT WHICH WILL BE IGNORED. ; MTOUT: MOV S.CSR(R4),R2 ;;;PICK UP ADDRESS OF CSR BITB #US.ABO,U.STS(R5) ;;;ABORTING? BEQ 152$ ;;;IF EQ NO BICB #US.ABO,U.STS(R5) ;CLEAR ABORT FLAG BIC #M.RWD,U.CW2(R5) ;;;REWIND NOT IN PROGRESS BR 162$ ;;;TERMINATE 152$: ;;;REFERENCE LABEL MOVB S.CON(R4),R3 ;;;FETCH CONTROLLER NO. BIT #M.RWD,U.CW2(R5) ;;;REWINDING? BNE 155$ ;;;IF NE YES MOV SPTBL(R3),R0 ;;;SPACE IN PROGRESS? BEQ 154$ ;;; IF EQ THEN NO CMP R0,2(R2) ;;;IS THE TAPE BLANK? BNE 153$ ;;; IF NE THEN NO CALL $DTOER ;;; LOG DEVICE TIMEOUT BR 161$ ;;; EXIT WITH IE.DNR ERROR CODE 153$: ;;; REF. LABEL MOV 2(R2),SPTBL(R3) ;;;SAVE VALUE FOR NEXT COMPARISON MOVB S.ITM(R4),S.CTM(R4) ;;;RESUME TIMEOUT RETURN ;;;THAT IS ALL FOR NOW 154$: CALL $DTOER ;;; LOG DEVICE TIMEOUT .IF DF D$$IAG BCS 161$ ;ABORT DIAGNOSTIC CALL .ENDC 155$: BIC #CS.IE,(R2) ;;;CLEAR INTERRUPT ENABLE MTPS #0 ;;;ALLOW INTERRUPTS BIT #M.SER,U.CW2(R5) ;WAS THERE A SELECT ERROR? BEQ 160$ ;IF EQ NO BIC #M.SER,U.CW2(R5) ;RESET STATUS BIT BIT #M.RWD,U.CW2(R5) ;REWINDING? BEQ 120$ ;IF EQ NO - REISSUE ORIGINAL COMMAND BIT #DS.MOL,-2(R2) ;IS THE DRIVE ON-LINE NOW? BEQ SELERR ;IF EQ NO MOVB #RWD-CS.IE,(R2) ;START THE REWIND AGAIN BR 172$ ;START UP TIMEOUT 160$: BIT #M.RWD,U.CW2(R5) ;REWINDING? BNE 164$ ;IF NE YES 161$: MOV #IE.DNR&377,R0 ;INDICATE DEVICE NOT READY 162$: .IF DF D$$IAG CALL MTDINT ;PASS DIAGNOSTIC DEVICE REGISTERS .ENDC BIS #CS.CLR,(R2) ;RESET CONTROLLER 163$: JMP 230$ ; REPORT FATAL ERROR 164$: BIT #DS.MOL,-2(R2) ;EVERYTHING COPASETIC? BEQ SELERR ;IF EQ NO BIT #DS.BOT!DS.RWS,-2(R2) ;TAPE OK? BNE 165$ ;IF NE OK SELERR: MOV #IE.DNR&377,R0 ;NOT READY - IF TAPE OFF LINE ;CS002 .IF DF D$$IAG TST RTTBL(R3) ;DIAGNOSTIC FUNCTION CALL? BMI 230$ ;IF MI YES - STOP SELECT MSG. .ENDC MOV S.PKT(R4),R1 ;RETREIVE I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;RETRIES SUPPRESSED? BNE 230$ ;IF NE YES - SKIPP SELERR TST U.ACP(R5) ; ACP WANTS RETURN? BNE 230$ ; IF NE YES EXIT BIS #M.SER,U.CW2(R5) ;SET SELECT ERROR BIT DECB S.STS(R4) ;TIME FOR A MSG? BNE 172$ ;IF NE NO MOV #T.NDSE,R0 ;SET UP TO DELIVER MESSAGE MOVB #15.,S.STS(R4) ;SET UP TIMEOUT CALL $DVMSG ;SEND THE MESSAGE BR 172$ ;SET THE TIMOUT 165$: BIT #DS.TUR,-2(R2) ;REWIND COMPLETE? BEQ 172$ ;IF EQ NO BIT #DS.BOT,-2(R2) ;DID WE GET TO BOT? BNE 175$ ;IF NE YES - REWIND COMPLETE 170$: BIT #M.RWD,U.CW2(R5) ;REWINDING? BEQ 177$ ;IF EQ NO 172$: MOVB #1,S.CTM(R4) ;SET UP A TIMEOUT RETURN ;THAT IS ALL FOR NOW 175$: BIS #M.BOT,U.CW2(R5) ;SAY AT BOT 177$: ;REF LABEL .IF DF M$$EXT&M$$MGE CMPB #SPF,U.BUF(R5) ;SPACE FORWARD? BEQ 178$ ;YES UMRS NOT NEEDED CMPB #SPR,U.BUF(R5) ;SPACE REVERSE? BEQ 178$ ;YES UMRS NOT NEEDED MOV R2,-(SP) ;SAVE R2 CALL $MPUBM ;MAP UNIBUS TO TRANSFER MOV (SP)+,R2 ;RESTORE R2 .ENDC 178$: CMP (R2)+,(R2)+ ;POINT TO MEMORY ADDRESS REGISTER MOV U.BUF+2(R5),(R2) ;SET UP BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;SET UP BYTE COUNT REGISTER NEG (R2) ;NEED 2S COMPLEMENT 180$: MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT BIC #M.AEOV!M.SER!M.RWD,U.CW2(R5) ;RESET VARIOUS FLAGS BICB #US.BSP,U.STS(R5) ;RESET FLAGS .IF DF D$$IAG BIT #RD.LPC,RTTBL(R3) ;READ LPC CHAR FUNCTION? BEQ 185$ ;IF EQ NO BIS #RD.LPC,6(R2) ;SET LPC READ IN MTRD REG. 185$: ;REF. LABEL .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE IN BITMAP .ENDC MOV U.BUF(R5),-(R2) ;INITIATE THE FUNCTION RETURN ;DONE ; ; CANCEL I/O OPERATION IS A NOP FOR TM11 MAGNETIC TAPES ; MTCAN: CMP I.TCB(R0),R1 ;CANCEL FOR THIS TASK? ;TL030 BNE 111$ ;BRANCH IF NOT ;TL030 BISB #US.ABO,U.STS(R5) ;FLAG THE ABORT CONDITION ;TL030 111$: RETURN ;TL030 ; ;**-2 ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ; MTPWF: ; POWERFAIL ENTRY POINT .IF DF P$$RFL BISB #US.PWF,U.STS(R5) ;SET POWER FAIL INDICATOR .ENDC CALL DRVSTS ;INDICATE TAPE DENSITY SUPPORT ;CS001 RETURN ; ; ; STATUS FUNCTION PROCESSING ; 190$: ;REFERENCE LABEL MOV R2,-(SP) ;SAVE TABLE POINTER CALL SELECT ;SET BOT, HWL, AND 7CH STATUS MOV (SP)+,R2 ;RESTORE POINTER MOV U.CW2(R5),I.PRM+4(R1) ;ASSUME SENSE CHARACTERISTICS TSTB (R2)+ ;DETERMINE FUNCTION REQUIRED BEQ 210$ ;IF EQ SET CHARACTERISTICS BPL 220$ ;IF PL "SENSE CHARACTERISTICS" 200$: ;REF. LABEL ;**-21 BIT #M.BOT,U.CW2(R5) ;AT BOT? ;**-8 BEQ 245$ ;IF EQ NO - FATAL ERROR ;**-1 210$: BIC #USRBTS,U.CW2(R5) ;PREPARE TO SET NEW BITS BIC #^C,U.BUF(R5) ;LEAVE ONLY USER CONTROLLED BITS BIS U.BUF(R5),U.CW2(R5) ;NEW STATUS WORD ; ; NO SPACING REQUIRED ; 220$: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS 230$: MOV S.CSR(R4),R2 ;PICK UP CSR ADDRESS BIC #CS.IE!CS.EXM,(R2) ;CLEAR IE AND EX. MEM. BITS CLR 2(R2) ;ASSURE PROPER VALUE FOR RETURN JMP 540$ ;CLEAN UP AND EXIT ;+ ; **-$MTINT-TM11 MAGNETIC TAPE CONTROLLER INTERRUPTS ;- INTSE$ MT,PR5,T$$M11 ;;;GENERATE INTERRUPT SAVE CODE MOV U.SCB(R5),R4 ;;;RETRIEVE ADDRESS OF SCB TST S.FRK+2(R4) ;;;HAVE WE FORKED ALREADY? BNE 300$ ;;;IF NE YES, RETURN FROM INTERRUPT CALL $FORK ;;;CREATE A SYSTEM PROCESS 240$: MOV U.SCB(R5),R4 ;GET SCB ADDRESS MOV S.CSR(R4),R2 ;PICK UP COMMAND REGISTER ADDRESS BICB #US.ABO,U.STS(R5) ;CLEAR ABORT FLAG BIT #DS.TUR!DS.RWS!DS.ILG!DS.EOT!DS.BOT,-(R2) ;UNIT DONE? BNE 250$ ;IF NE YES CMPB U.BUF(R5),#RWU ;WAS IT A REWIND AND OFFLINE FUNCTION? BEQ 220$ ;IF EQ YES, COMPLETE WITH SUCCESS MOV R4,R0 ;GET ADDR OF CLOCK QUEUE BLOCK ADD #S.MTCK,R0 ; CLR R1 ;SET UP HIGH TICKS MOV #1,R2 ;TIMEOUT UNTIL TUR MOV #C.SYST,R4 ;TYPE OF CLOCK ENTRY CALLR $CLINS ;TIMEOUT $MTCLK:: ;REF LABEL FOR TIMEOUT MOV C.TCB(R4),R5 ;RESTORE UCB ADDRESS BR 240$ ;SEE IF UNIT READY 245$: MOV #IE.FHE&377,R0 ; SET FATAL ERROR STATUS JMP 540$ ; EXIT 250$: MOVB S.CON(R4),R3 ;PICK UP CONTROLLER NO. BIT #DS.MOL,(R2)+ ;IS THE DRIVE STILL ON-LINE? BNE 260$ ;IF NE YES JMP 161$ ;ISSUE "DEVICE-NOT-READY" MSG 260$: BIC #CS.IE!CS.EXM,(R2) ;CLEAR INT. ENABLE AND EX.MEM BITS MOVB S.ITM(R4),S.CTM(R4) ;RESET TIMEOUT COUNT CLR S.FRK+2(R4) ;ALLOW INTERRUPT PROCESSING MOV -2(R2),R1 ;GET CONTENTS OF DRIVE STATUS REGISTER BITB #US.BSP,U.STS(R5) ;INTERNAL BACKSPACE IN PROGRESS? BNE 280$ ;IF NE YES - CALL SERVICE ROUTINE 270$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESS FOR VARIOUS REASONS TST (R2) ;ANY ERRORS? BMI 280$ ;IF MI YES TST U.SPC(R5) ;SPACING FILE? ;CS001 BNE 280$ ;IF NE, YES. TREAT AS ERROR ANYWAY. ;CS001 CMPB (R2),#RWD+CS.RDY-CS.GO-CS.IE ;WAS THAT A REWIND? ;**-2 BNE 275$ ;IF NE NO BIS #M.RWD,U.CW2(R5) ;SET STATUS BIT 275$: JMP 500$ ;SUCCESS!! 280$: ; REF LABEL .IF DF D$$IAG&E$$DVC TST RTTBL(R3) ; DIAGNOSTIC FUNCTION CALL? BMI 290$ ; IF MI YES .ENDC .IF DF E$$DVC BIT #DS.ILG!DS.CRE!DS.PAE!DS.BGL!DS.BTE,R1 ;TL072 ; ANY ERRORS IN STATUS REG (MTS)? ;**-1 BEQ 290$ ; IF EQ THEN NO CALL $DVERR ; LOG DEVICE ERROR .ENDC 290$: ; REF LABEL CALL @INTADD(R3) ; CALL THE INTERRUPT ROUTINE MOV (SP)+,INTADD(R3) ;SAVE INTERRUPT ADDRESS 300$: RETURN ;WAIT FOR END OF NEXT COMMAND STEP ; ; WRITE LOGICAL FUNCTION ; WRBLK: BIT #DS.TM,R1 ;DID WRITE SEE EOF? BNE 320$ ;IF NE YES ; ; WRITE TAPE MARK FUNCTION ; WREOF: BIT #34404,R1 ;ANY OTHER ERRORS? BEQ 325$ ;IF EQ NO - REALLY SUCCESSFUL ;TL068 MOV #IE.WLK&377,R0 ;ASSUME WRITE-LOCK ;**-1 BIT #DS.HWL,R1 ;WRITE LOCK? BNE 325$ ;IF NE YES ;TL068 BIT #34400,R1 ;RECOVERABLE ERROR? ;**-1 BNE 320$ ;IF NE YES ; ; REWIND FUNCTIONS ; REWND: MOV #IE.FHE&377,R0 ;FATAL ERROR BR 490$ ;THAT'S ALL, FOLKS! 320$: MOV #IE.BBE&377,R0 ;ASSUME BAD TAPE OR EQUIVALENT TSTB U.CW2(R5) ;SHOULD WE REWRITE? BMI 490$ ;IF MI USER SAID "NO" BIT #2,@R2 ;IS THIS A WRITE EOF? BNE 420$ ;IF NE YES BIS #WTE-WRT,U.BUF(R5) ;DO WRITE WITH EXTENDED GAP FROM NOW ON BR 420$ ;DO THE OPERATION ; ;TL068 325$: BR 490$ ;GO FINISH UP INT SERVICE ;TL068 ; ; SPACE FILE FUNCTION ; SPCFL: BIT #DS.TM,R1 ;TAPE MARK ENCOUNTERED? BNE 350$ ;IF NE YES MOV U.SPC(R5),2(R2) ;SOMETHING ELSE STOPPED US ;CS001 ;**-1 ; ; SPACE BLOCK FUNCTION ; SPCBK: BIT #DS.BOT,R1 ;AT BOT? BNE 490$ ;IF NE YES, NOT AN ERROR, BUT NEED STACK CLEAR BIT #DS.TM,R1 ;EOF? BEQ 340$ ;IF EQ NO CALL CHKEOV ;SEE IF AT END OF VOLUME BCC 410$ ;IF CC NOT FOUND BR 360$ ;POSITION TAPE AT EOV 340$: BIT #DS.BTE!DS.EOT,R1 ;BAD TAPE ERROR OR EOT? BNE RDBLK ;IF NE YES - NOT RECOVERABLE BR REWND ;FATAL 350$: CALL CHKEOV ;DID TAPE REACH LOGICAL END OF VOLUME? BCC 370$ ;IF CC NO, TRY NEXT FILE 360$: CALL BSPACE ;BACKSPACE THE TAPE CALL @(SP)+ ;WAIT FOR COMPLETION MOV #IE.EOV&377,R0 ;INFORM USER THAT EOV HAS BEEN DETECTED BIS #M.AEOV,U.CW2(R5) ;SET STATUS BIT BR 380$ ;FIX COUNT AND RETURN 370$: INC U.SPC(R5) ;ANOTHER TAPE MARK DETECTED ;CS001 BNE 390$ ;IF NE NOT DONE ;**-1 380$: MOV U.SPC(R5),2(R2) ;SET UP FINAL COUNT ;CS001 MOV S.PKT(R4),R3 ;GET THE I/O PACKET ADDRESS ;TL067 MOV I.FCN(R3),-(SP) ;GET THE FUNCTION CODE ;TL067 BIC #IQ.UMD!IQ.X,(SP) ;CLEAR EXTRA BITS ;TL067 CMP #IO.SPB,(SP)+ ;SPACE BLOCKS? ;TL067 BNE 385$ ;NO -- LEAVE STATUS ALONE ;TL067 CLR I.PRM+4(R3) ;CLEAR FOR STATUS RETURN ;TL067 CLR 2(R2) ;... ;TL067 385$: BR 490$ ;RETURN TO USER ;**-1 390$: BIS #M.EOF,U.CW2(R5) ;I SAW AN EOF MOV #1,2(R2) ;SET RECORD COUNT FOR SPACING MOV 2(R2),SPTBL(R3) ;SAVE RECORD COUNT ADD #-CS.RDY+CS.GO+CS.IE,(R2) ;REISSUE SPACING COMMAND CALL @(SP)+ ;WAIT FOR COMPLETION BR SPCFL ;SEE WHAT HAPPENED ; ; READ LOGICAL FUNCTION ; RDBLK: MOV #IE.BBE&377,R0 ;ASSUME BAD TAPE BIT #DS.BTE,R1 ;BAD TAPE? BNE 490$ ;IF NE YES MOV #IE.DAO&377,R0 ;ASSUME RECORD LENGTH ERROR BIT #DS.RLE,R1 ;RECORD LTH ERROR? BNE 490$ ;IF NE YES 410$: MOV #IE.EOF&377,R0 ;TRY EOF BIT #DS.TM,R1 ;EOF DETECTED? BNE 490$ ;IF NE YES MOV #IS.SUC&377,R0 ; EOT ON READ IS SUCCESS BIT #DS.EOT,R1 ;EOT? BNE 490$ ;IF NE NO MOV #IE.VER&377,R0 ;ASSUME DATA ERROR 420$: MOV R1,-(SP) ;SAVE R1 MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;RETRIES SUPPRESSED? BEQ 430$ ;IF EQ NO MOV (SP)+,R1 ;RESTORE R1 BR 490$ ;AND EXIT 430$: MOV (SP)+,R1 ;RESTORE R1 AND CONTINUE DECB RTTBL(R3) ;ANY MORE RETRIES? BLE 490$ ; IF LE NO MOV INTADD(R3),U.SPC(R5) ;SAVE ORIGINAL ADDRESS ;CS001 CALL BSPACE ;BACKSPACE THE TAPE ;**-1 CALL @(SP)+ ;WAIT FOR BACKSPACE MOV U.SPC(R5),INTADD(R3) ;RESTORE INT ADDRESS ;CS001 CLR U.SPC(R5) ;RESET TO INDICATE NOT SPACING FILE ;CS001 TST (SP)+ ;CLEAN UP THE STACK ;**-2 JMP 177$ ;RETRY ; ; END OF INTERRUPT SERVICE ROUTINE PROCESSING ; 490$: TST (SP)+ ;CLEAN UP THE STACK 500$: MOV R5,R3 ;MAKE A COPY OF UCB BASE ADD #U.CW2,R3 ;COMPUTE OFFSET TO MAG TAPE STATUS MOV (R3),-(SP) ;SAVE CURRENT STATUS BIC #NEWBTS,(R3) ;CLEAR STATUS BITS TO BE DETERMINED BIT #DS.BOT,R1 ;AT BOT? BEQ 510$ ;IF EQ NO BIS #M.BOT,(R3) ;SET STATUS BIT 510$: BIT #DS.TM,R1 ;TAPE MARK? BEQ 520$ ;IF EQ NOT TAPE MARK  CMPB (R2),#SPR+CS.RDY-CS.IE-CS.GO ;WAS THAT A BACKSPACE? BEQ 520$ ;IF EQ YES - DON'T SET INTERNAL EOF BIT BIS #M.EOF,(R3) ;SET STATUS BIT 520$: .IF DF D$$IAG MOV R1,-(SP) ;SAVE R1 CALL MTDINT ;PASS DIAGNOSTIC DEVICE REGISTERS MOV (SP)+,R1 ;RESTORE R1 AND CLEAN STACK .ENDC .IF DF D$$IAG&E$$DVC BCS 530$ ; .ENDC .IF DF E$$DVC BIT #DS.ILG!DS.CRE!DS.PAE!DS.BGL!DS.BTE,R1 ;TL072 ; ANY ERRORS IN STATUS REG (MTS)? ;**-1 BEQ 530$ ; IF EQ THEN NO CALL $DVERR ; LOG DEVICE ERROR .ENDC 530$: ; REF LABEL CMPB (R2),#RED+CS.RDY-CS.IE-CS.GO ;WAS THAT A READ? BEQ 539$ ;YES IGNORE EOT BIT #DS.EOT,R1 ;EOT? BEQ 539$ ;IF EQ NO TSTB R0 ;ALREADY RETURNING AN ERROR? ;**-2 BMI 538$ ;IF MI YES 535$: MOV #IE.EOT&377,R0 ;SET FOR EOT STATUS 538$: BIS #M.EOT,(R3) ;REMEMBER EOT FOR NEXT COMMAND MOV 2(R2),-(SP) ;PRESERVE THE COUNT REGISTER BIS #CS.CLR,@R2 ;STOP THE DRIVE IF RUNNING AWAY MOV (SP)+,2(R2) ;RESTORE THE COUNT REGISTER 539$: TST (SP)+ ;CLEAN STACK 540$: MOV S.PKT(R4),R1 ;RETRIEVE ADDRESS OF I/O PACKET MOV I.PRM+4(R1),R1 ;GET ORIGINAL COUNT VALUE ADD 2(R2),R1 ;FIX COUNT REMAINING .IF DF E$$DVC MOVB S.CON(R4),R3 ; RETRIEVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ; GET FINAL RETRY COUNT BIS #RETRY*256.,R2 ; MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION JMP MTINI ;GO AGAIN .DSABL LSB ; ; THIS SUBROUTINE CHECKS FOR THE LOGICAL END-OF-VOLUME CONDITION ; ; RETURNS WITH CC IF NOT EOV. ; RETURNS WITH CS IF EOV. ; CHKEOV: MOV 2(R2),-(SP) ;SAVE FRAME COUNT ADD U.CNT(R5),(SP) ;GET NUMBER ACTUALLY SPACED CMP (SP)+,#1 ;EXACTLY ONE? (COUNT STARTED WITH 1) CLC ;ASSUME NOT EOV BNE 30$ ;IF NE NO, NOT EOV .IF DF A$$NSI BITB #US.LAB,U.STS(R5) ;MOUNTED ANSII TAPE? BNE 30$ ;IF NE YES - EXIT WITH CC .ENDC BIT #2,(R2) ;FORWARD SPACE? BNE 30$ ;IF NE NO - CANNOT BE EOV BIT #M.EOF!M.BOT,U.CW2(R5) ;AT EOV? BEQ 30$ ;IF EQ NO - EXIT WITH CC SEC ;EOV DETECTED 30$: RETURN ; ; ; THIS SUBROUTINE ISSUES A COMMAND TO BACKSPACE ONE RECORD ; BSPACE: BISB #US.BSP,U.STS(R5) ;SET INTERNAL BACKSPACE IN PROGRESS MOV #-1,2(R2) ;BACKSPACE ONE RECORD MOVB #SPR,(R2) ;ISSUE BACKSPACE FUNCTION RETURN ; ; THIS ROUTINE ATTEMPTS TO SELECT A TAPE DRIVE. ; THE CURRENT STATUS OF THE DRIVE WITH REGARD TO 7CH, ; BOT, AND HWL IS SET AT THIS TIME. ; ; ON RETURN: CC==>GOOD SELECT ; CS==>BAD SELECT ; SELECT: CALL DRVSTS ;GET TAPE UNIT STATUS ;CS001 MOVB 1(R2),U.BUF+1(R5) ;SET UP FOR COMMAND ;**-5 MOV -2(R2),-(SP) ;SAVE THE TAPE UNIT STATUS. ;CS001 BIC #,U.CW2(R5) ;CLEAR EXCESS;**-1 SEC ;ASSUME SELECT ERROR BIT #DS.MOL,(SP) ;DID DRIVE SELECT? BEQ 10$ ;IF EQ NO - SELECT ERROR BIT #DS.TUR!DS.RWS!DS.SDN,(SP) ;MAKE SURE DRIVE IS OK BNE 7$ ;IF NE OK BIT #RD.GAP,10(R2) ;LAST CHANCE BEQ 10$ ;IF EQ VACUUM IS GONE - FATAL 7$: BIT #DS.TUR,(SP) ;TRUST BOT ? ;CS003 BNE 8$ ;IF NE, YES. ;CS003 BIC #DS.BOT,(SP) ;MAY BE INTERMITTENT. ;CS003 8$: SWAB (SP) ;UNIT SELECTABLE. CARRY CLEARED. ;CS003 BIC #^C,(SP) ;CLEAR EXTRA BITS ;**-1 BIS (SP),U.CW2(R5) ; BICB #US.ABO,U.STS(R5) ;NOT ABORTING 10$: INC (SP)+ ;CLEAN UP STACK WITHOUT AFFECTING CARRY ;**-1 BCC 20$ ;IF CC GOOD SELECT BIS #M.SER,U.CW2(R5) ;SET SELECT ERROR BIT 20$: RETURN ; ;+ ;CS001 ; SUBROUTINE SELECTS A TAPE UNIT AND TRIES TO OBTAIN TAPE UNIT STATUS. ;CS001 ; ;CS001 ; IF TAPE UNIT READY, DETERMINE 7/9 TRACK STATUS AND UPDATE U.CW3 ACCORD;CS001 ;- ;CS001 ;CS001 DRVSTS: MOV S.CSR(R4),R2 ;R2=CSR. ;CS001 MOVB U.UNIT(R5),1(R2) ;SELECT TAPE UNIT ;CS001 MOV #50.,-(SP) ;INTERVAL TILL DEV REG RDY. ;CS001 5$: DEC (SP) ;INTERVAL OVER ? ;CS001 BNE 5$ ;IF NE, NO. ;CS001 BIT #DS.TUR,-2(R2) ;TAPE UNIT READY ? ;CS001 BEQ 10$ ;IF EQ, NO. BITS 0-5 NOT AVAILABLE. ;CS001 MOVB #UD.800,U.CW3(R5) ;INDICATE (ONLY) ;CS001 MOVB #UD.UNS,U.CW3+1(R5) ;9TRACK/800BPI. ;CS001 BIT #DS.7CH,-2(R2) ;7 TRACK TAPE UNIT? ;CS001 BEQ 10$ ;IF EQ, NO. ;CS001 MOVB #UD.200,U.CW3(R5) ;INDICATE 7 TRACK, ;CS001 MOVB #UD.800,U.CW3+1(R5) ;200 TO 800BPI SUPPORT. ;CS001 10$: TST (SP)+ ;RETURN STACK AS FOUND. ;CS001 RETURN ;CS001 ;CS001 ;CS001 .IF DF D$$IAG ;+ ; **-MTDINT-TM11 DIAGNOSTIC INTERRUPT AND TIMEOUT HANDLER ; ; IF ENTRY WAS FROM A DIAGNOSTIC CONTROL FUNCTION THEN MOVE I/O ; PACKET WORDS 17-20 TO WORDS 20-21 FOR $CRPAS ROUTINE. ; FOR ANY DIAGNOSTIC FUNCTION PASS THE UNIBUS DEVICE REGISTERS VIA ; THE $CRPAS ROUTINE. ; ; INPUTS ; R2= CSR ADDRESS ; R4= SCB ADDRESS ; ; OUTPUTS ; R1= IO PACKET ADDRESS ;- MTDINT: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS CLC ; BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION CALL? BEQ 4$ ;IF EQ NO MOV R1,-(SP) ;SAVE IO PACKET ADDRESS CMPB #IO.EOF/256.,I.FCN+1(R1) ;WRITE EOF FUNCTION? BEQ 1$ ;IF EQ YES CMPB #IO.RWD/256.,I.FCN+1(R1) ;CNTRL FUNCT.OTHER THAN IO.EOF? BEQ 1$ ;IF EQ YES CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC MOV (SP)+,R1 ;RESTORE IO PACKET ADDRESS BR 3$ ;RETURN 1$: MOV I.PRM+14(R1),I.PRM+16(R1) ;MOVE WD20 TO WD21 MOV I.PRM+12(R1),I.PRM+14(R1) ;MOVE WD17 TO WD20 2$: CALL $CRPAS ;PASS DEVICE REGISTERS TO DIAGNOSTIC MOV (SP)+,R1 ;RESTORE IO PACKET ADDRESS MOV I.PRM+14(R1),I.PRM+12(R1) ;MOVE WD20 BACK TO WD17 MOV I.PRM+16(R1),I.PRM+14(R1) ;MOVE WD21 BACK TO WD20 3$: BIC #RD.LPC,10(R2) ;CLEAR LPC MODE BIT IN MTRD REG. N SEC ;SET DIAGNOSTIC FUNCTION CALL RETURN 4$: RETURN .ENDC .END NdYðskQ ›c, .TITLE NLDRV .IDENT /03/ ; ; COPYRIGHT (C) 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 03 ; ; E. L. BAATZ 22-JUL-76 ; ; NULL DEVICE DRIVER. ; ; MACRO LIBRARY CALLS ; ; EQUATED SYMBOLS ; ; LOCAL DATA ; ; NO CONTROLLER IMPURE DATA TABLES (THERE IS NO DEVICE TO ; CAUSE INTERRUPTS) ; ; DRIVER DISPATCH TABLE ; $NLTBL:: .WORD NLINI ;INITIATION .WORD $INTXT ;CANCEL ($INTXT IS A "RETURN") .WORD $INTXT ;TIMEOUT .WORD $INTXT ;POWERFAIL ;+ ; NLDRV AND DRQIO IMPLEMENT A DEVICE NL:, WHICH ACTS AS ; 1) A SINK FOR ALL INFORMATION SEND TO IT (IO.WLB) ; 2) A SOURCE FOR AN INFINITE NUMBER OF END OF FILES (IO.RLB) ; 3) A SOURCE FOR AN INFINITE NUMBER OF NULL RECORDS (IO.RLB) ; IF "IE.EOF" IS CHANGED TO "IS.SUC" ;- ; ; DRQIO (BECAUSE THE UC.QUE BIT IS SET IN THE UCB) SETS THE REGISTERS ; TO THE FOLLOWING: ; ; R1 = ADDRESS OF I/O PACKET ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; ; ONLY TWO FIELDS OF AN I/O PACKET MATTER ; I.FCN+1 = THE I/O FUNCTION CODE. ONLY IO.WLB ; AND IO.RLB MAKE IT TO NLDRV ; I.PRM+4 = IF I.FCN+1 IS IO.WLB, THIS IS THE ; NUMBER OF BYTES THE CALLER WANTS TO WRITE ; NLINI: MOV R1,R3 ;POINT AT PACKET FOR $IOFIN MOV #IS.SUC&377,R0 ;A WRITE ALWAYS SUCCEEDS MOV I.PRM+4(R1),R1 ;SAY EVERYTHING WAS WRITTEN CMPB #IO.WLB/400,I.FCN+1(R3) ;WANTS TO WRITE? BEQ 10$ ;IF EQ YES MOV #IE.EOF&f377,R0 ;IT IS A READ CLR R1 ;READ NO CHARACTERS 10$: CALLR $IOFIN ;FINISH OFF PACKET .END f¤ZðskQ ›c, .TITLE NTDRV .IDENT /03/ ; ; COPYRIGHT (C) 1974, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 03 ; ; J. M. GILBERT 9-MAY-75 ; ; LG005 - MODIFIED 8-SEP-76 FOR LOADABLE DRIVER SUPPORT ; ; RSX-11M NETWORK DEVICE DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,DEVDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS DEVDF$ ;DEFINE DEVICE TABLE OFFSETS  .MCALL PCBDF$ PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS ; ; DRIVER DISPATCH TABLE ; .IF DF M$$NET $NTTBL::.WORD NTINIT ;INITIALIZATION .WORD NTCANC ;I/O CANCELLATION .WORD NTTMO ;TIMEOUT .WORD NTPWRF ;POWER FAIL .WORD NTRCV ;UNSOLICITED RECEIVE ENTRY .WORD NTRXER ;RECEIVER ERROR CLEAR ;+ ;**- NTINIT - NT DEVICE SERVICE. PROVIDED SO ; THAT STAND-ALONE TESTING OF NETWORKS CAN TAKE PLACE ; ON A SYSTEM WITHOUT NETWORK COMMUNICATION DEVICES. ; PRIMARY FUNCTION OF INITIATOR IS TO CALL $GTPKT, FORCING ; DISPATCH OF PACKET TO ACP. ONLY ACP FUNCTIONS ARE ; LEGAL ON THIS DEVICE. HOWEVER, THE FUNCTION IO.LOV IS ALSO ; ACCEPTED AND IS MAPPED INTO A FUNCTION CODE 30. THE PACKET ; IS THEN REQUEUED TO NT:; HOWEVER, NOW THAT THE FUNCTION IS ; AN ACP FUNCTION, THE PACKET IS QUEUED TO THE ACP. ; ; INPUTS: ; ; R1 = PACKET ADDRESS ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB OF THE NT DEVICES ; ; OUTPUTS: ; ; THE PACKET WILL BE QUEUED TO THE ACP. ;- NTINIT: CALL $GTPKT ;QUEUE PACKET TO ACP BCS 10$ ;IF CS, NO PACKETS ; ; R1 NOW CONTAINS PACKET ADDRESS ; R5 CONTAINS UCB ADDRESS ; FUNCTION MUST BE IO.RLB, ; SPECIFICALLY IO.LOV ; CLRB S.STS(R4) ;CLEAR CONTROLLER STATUS BICB #US.BSY,U.STS(R5) ;MARK UNIT IDLE MOV #30*256.,I.FCN(R1) ;SET FUNCTION TO 30 CALL $DRQRQ ;QUEUE PACKET TO ACP 10$: ;REFERENCE LABEL ;+ ;**- NTCANC,NTTMO,NTPWRF,NTRCV,NTRXER ARE ALL ; NO-OP'D, SINCE THIS IS A LOGICAL DEVICE. ;- NTCANC: ;I/O CANCELLATION NTTMO: ;DEVICE TIMEOUT NTPWRF: ;POWER FAILURE NTRCV: ;RECEIVE INITIATION NTRXER: ;RECEIVER RESET RETURN .IF DF M$$MGE&L$$DRV ;+ ; **-$MLDC-MAP LOADABLE DRIVER TO APR5 AND CALL DRIVER ; **-$MLDCS-ENTRY POINT IF ALREADY ON SYSTEM STACK ; ; INPUTS: ; R0=DISPLACEMENT IN DISPATCH TABLE OF ENTRY POINT ; R5=UCB ADDRESS ; ; OUTPUTS: ; DRIVER CALLED WITH ALL REGISTERS EXCEPT R0 UNCHANGED ; R0=DESTROYED ;- $MLDC:: SWSTK$ EXIT ;GO TO SYSTEM STATE $MLDCS::¦MOV KISAR5,-(SP) ;SAVE APR5 MOV R0,-(SP) ;DISPATCH TABLE DISPLACEMENT MOV (R5),R0 ;DCB ADDRESS ADD D.DSP(R0),(SP) ;DISPATCH TABLE ADDRESS MOV D.PCB(R0),R0 ;DRIVER PCB ADDRESS BEQ 10$ ;IF EQ, DRIVER IS PART OF EXEC MOV P.REL(R0),KISAR5 ;MAP THE DRIVER 10$: MOV @(SP)+,R0 ;DRIVER ENTRY POINT CALL (R0) ;CALL THE DRIVER MOV (SP)+,KISAR5 ;RESTORE APR5 EXIT: RETURN .ENDC .ENDC .END ¦y:à~kQ ›c, .TITLE INITL .IDENT /14.29/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 14.29 ; ; D. N. CUTLER 23-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; B. SCHREIBER ; C. SPITZ ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 18-JUL-79 ; MSH044 -- HANDLE SYSTEM CLOCK WITH NO CSR. ;  ALSO, CLEAN UP UNNECESSARY CODE. ; ; M. S. HARVEY 25-OCT-79 ; MSH045 -- DIRECTIVE COMMON VALIDATION CHECKS ; ; M. S. HARVEY 19-DEC-79 ; MSH043 -- UPDATE RSX VERSION NUMBERS ; ; P. J. BEZEREDI 19-AUG-80 ; PB175 -- ADD SUPPORT FOR EXTENDED INSTRUCTION SET. ; ; M. S. HARVEY 20-AUG-80 ; MSH112 -- USE $TRINT TO TRAP ILLEGAL INSTRUCTIONS ; ; M. S. HARVEY 25-AUG-80 ; MSH097 -- ADD SUPPORT FOR 22-BIT SYSTEMS WITHOUT ; AN I/O MAP ; ; M. S. HARVEY 17-OCT-80 ; MSH123 -- INITIALIZE TICKS PER SECOND PARAMETER IN ; SET SYSTEM TIME VALIDATION TABLE ; ; M. S. HARVEY 12-FEB-81 ; MSH149 -- DETERMINE THE EXISTENCE OF THE FLOATING ; POINT PROCESSOR ; ; M. S. HARVEY 5-MAR-81 ; MSH142 -- INITIALIZE THE POOL MONITOR CONTROL WORDS ; ; MSH156 -- INITIALIZE THE WATCHDOG TIMER CSR POINTER ; ; M. S. HARVEY 31-MAR-81 ; MSH161 -- FOR RSX-11S ONLY, ALLOW LAST PARTITION TO ; ENCOMPASS REMAINDER OF MEMORY IF SYSTEM ; CONTROLLED ; ; M. S. HARVEY 1-MAY-81 ; MSH165 -- ADD SUPPORT FOR SECOND DIRECTIVE COMMON ; ; M. S. HARVEY 29-MAY-81 ; MSH171 -- FOR RSX-11S ONLY, INITIALIZE MEMORY ; ABOVE $SYSIZ AND CLEAN UP COMMENTS ; ; M. S. HARVEY 16-JUL-81 ; MSH179 -- CLEAN UP THE EIS TESTING CODE ; ; M. S. HARVEY 21-JUL-81 ; MSH181 -- HANDLE POSSIBLE T-BIT TRAP AFTER POWER UP ; ON PDP 11/02 PROCESSORS ; ; M. S. HARVEY 5-NOV-81 ; MSH201 -- ENHANCE PARITY CSR DETECTION FOR ERROR LOGGING ; ; M. S. HARVEY 28-DEC-81 ; MSH208 -- CORRECTLY SIZE MEMORY ON Q22-BUS SYSTEMS ; ; MSH209 -- FORCE RLV12 TO USE BAE REGISTER IF NECESSARY ; ; ; SYSTEM START UP AND INITIALIZATION ROUTINE ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ; ; LOCAL DATA ; ; SYSTEM IDENTIFICATION MESSAGES ; ; ; MAKE SURE THAT INITL TASK BUILDS AS THE LAST MODULE IN THE EXEC ; .PSECT ...... $POOL:: ;START OF POOL .IF NDF R$$11S SYSMG: .ASCII <15><12>/RSX11M V4.0 BL/ ;MSH043 ;**-1 .IFF SYSMG: .ASCII <15><12>/RSX11S V4.0 BL/ ;MSH043 ;**-1 .ENDC SYSID: .ASCIZ /XXXX/<15><12><12> ; ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 NDCOM: .ASCII <15><177><177><12>/ MISSING EXECUTIVE COMMON(S)/ ;MSH045 .ASCIZ <15><12> ;MSH045 ;MSH045 .ENDC ;MSH045 ;MSH045 .IF DF M$$EIS ; PB175 ; PB175 NOEIS: .ASCII <15><177><177><12>/ PROCESSOR DOES NOT SUPPORT EIS/ ; PB175 .ASCIZ <15><12> ; PB175 ; PB175 .ENDC ; PB175  ; PB175 DEVMG: .ASCIZ <15><177><177><12>/ DEVICE DDUU: NOT IN CONFIGURATION/<15> ; PROMT: .ASCIZ <15><12>/>/ ; .EVEN ;+ ; **-$INITL-SYSTEM TRANSFER ADDRESS ; ; THIS ROUTINE CONTAINS THE TRANSFER POINT OF THE RESIDENT EXECUTIVE. WHEN ; THE SYSTEM IS BOOTED, CONTROL IS TRANSFERED HERE TO INITIALIZE AND START ; UP THE SYSTEM ;- $INITL::RESET ;RESET PROCESSOR ;MSH181 .IF NDF X$$DBT ;MSH181 .IF DF L$$SI1 ;MSH181 ;MSH181 MOV #$TRACE,@#14 ;SET THE BPT/T-BIT (TRACE) VECTOR ;MSH181 ;MSH181 .ENDC ;MSH181 .ENDC ;MSH181 ;MSH181 MOV #$SYSIZ+2,R0 ;POINT TO SYSTEM CONFIGURATION VECTOR MOVB R3,(R0)+ ;SAVE UNIT NUMBER MOVB R1,(R0)+ ;SAVE LBN OF LOAD IMAGE MOV R2,(R0)+ ; MOV R4,(R0)+ ;SAVE DEVICE NAME MOV R5,(R0)+ ;SAVE LENGTH OF LOAD FILE .IF DF M$$MGE MOV #PMODE+PR7,PS ;SET MODE BITS AND LOCK OUT INTERRUPTS MOV #$STACK-20,SP ;SETUP EXEC STACK POINTER MOV #KISAR0,R0 ;POINT TO KERNEL PAR 0 MOV #KISDR0,R1 ;POINT TO KERNEL PDR 0 MOV #UISAR0,R2 ;POINT TO USER PAR 0 MOV #UISDR0,R3 ;POINT TO USER PDR 0 MOV #8.,R4 ;SET LOOP COUNT CLR R5 ;START AT BOTTOM OF MEMORY 10$: MOV R5,(R0)+ ;SET KERNEL AND USER RELOCATION BIAS MOV R5,(R2)+ ; MOV #77406,(R1) ;SET KERNEL AND USER DESCRIPTOR REGISTERS MOV (R1)+,(R3)+ ; ADD #200,R5 ;ADVANCE TO NEXT 4K BLOCK DEC R4 ;ANY MORE REGISTERS TO LOAD? BGT 10$ ;IF GT YES MOV #177600,-(R0) ;SET KERNEL PAR 7 TO I/O PAGE INC SR0 ;AND AWAY WE GO .IFF  ;MSH097 ;MSH097 MTPS #PR7 ;LOCK OUT INTERRUPTS ;MSH097 MOV #$STACK-10,SP ;SETUP EXEC STACK POINTER ;MSH097 ;MSH097 .IFTF ;MSH097 ;MSH097 MOV #$DIRXT,-(SP) ;SET UP RETURN FOR $SGFIN ;MSH097 CALL $SGFIN ;TRAP NON-EXISTENT MEMORY ;MSH097 ;MSH097 .IFT ;MSH097 .IF DF M$$EXT MOV #UBMPR,R0 ;POINT TO FIRST UNIBUS MAPPING REG TST (R0) ;DOES I/O MAP EXIST? ;MSH097 BCS 12$ ;IF CS NO, DON'T INITIALIZE MAP ;MSH097 CLR R1 ;SET INITIAL ADDRESS TO ZERO MOV #5.,R2 ;SET NUMBER OF REGISTER PAIRS TO LOAD 11$: MOV R1,(R0)+ ;LOAD LOW 16 BITS OF ADDRESS CLR (R0)+ ;CLEAR HIGH 6 BITS OF ADDRESS ADD #20000,R1 ;ADVANCE 8K BYTES DEC R2 ;ANY MORE TO LOAD? BGT 11$ ;IF GT YES BR 125$ ;JOIN COMMON CODE ;MSH097 12$: CLR $UMRPT ;INDICATE NO I/O MAP IN THIS SYSTEM ;MSH097 125$: MOV #60,SR3 ;ENABLE 22 BIT ADDRESSING AND UB MAP ;MSH097 ;**-1 .ENDC .IFTF ;**-6 ; ;MSH097 ; THIS SECTION SIZES MEMORY FOR THE SYSTEM. IF THIS IS AN RSX-11S ;MSH097 ; SYSTEM, THEN ALL MEMORY ABOVE $SYSIZ MUST BE INITIALIZED. ;MSH097 ; ;MSH097 ;MSH097 MOV #$SYSID,R0 ;POINT TO SYSTEM IDENTIFICATION ;**-2 MOV #SYSID,R1 ;POINT TO IDENTIFICATION MESSAGE MOVB (R0)+,(R1)+ ;MOVE SYSTEM IDENTIFICATION INTO MESSAGE MOVB (R0)+,(R1)+ ; MOVB (R0)+,(R1)+ ; MOVB (R0),(R1) ; JSR R5,OPMSG ;TELL EVERYBODY WE'RE ON THE AIR .WORD SYSMG ; ;MSH208 CLR R1 ;ZERO NUMBER OF 32W BLOCKS IN SYSTEM ;MSH208 .IFT MOV #140000,R0 ;SET INITIAL MEMORY ADDRESS MOV #KISAR6,R4 ;LOAD KERNEL APR6 ADDRESS ;MSH171 ;MSH208 .IF DF M$$EXT ;MSH208 ;MSH208 MOV #10000,(R4) ;POINT TO 128K ;MSH208 MOV (R1),-(SP) ;SAVE CONTENTS OF LOCATION ZERO ;MSH208 MOV SP,(R1) ;MOVE NONZERO VALUE INTO LOC ZERO ;MSH208 MOV #0,(R0) ;ATTEMPT TO ACCESS WORD AT 128K ;MSH208 TST (R1) ;ADDRESS WRAPAROUND TO LOCATION ZERO? ;MSH208 BNE 127$ ;IF NE NO, SYSTEM HAS MORE THAN 128KW ;MSH208 MOV #10000,16$ ;SET UPPER LIMIT TO 128KW ;MSH208 127$: MOV (SP)+,(R1) ;RESTORE CONTENTS OF LOCATION ZERO ;MSH208 ;MSH208 .ENDC ;MSH208 ;MSH208 CLR (R4) ;SET ZERO RELOCATION BIAS ;MSH171 ;MSH171 .IF DF R$$11S ;MSH171 ;MSH171 MOV $SYSIZ,R5 ;GET TOP OF INITIALIZED MEMORY ;MSH171 ;MSH171 .ENDC ;MSH171 ;**-1 .IFF CLR R0 ;SET INITIAL MEMORY ADDRESS .IFTF 13$: TST (R0) ;MEMORY EXIST? ;**-1 BCS 17$ ;IF CS NO ADD #40,R1 ;UPDATE NUMBER OF 32W BLOCKS .IFT .IF DF R$$11S ;MSH171 ;MSH171 CMP R1,R5 ;HIGHER THAN LAST INITIALIZED MEMORY? ;MSH171 BLOS 15$ ;IF LOS NO, NO NEED TO CLEAR MEMORY ;MSH171 MOV R1,R3 ;GET TOP OF CURRENT 1K SEGMENT ;MSH171 SUB R5,R3 ;GET SIZE OF MEMORY TO BE CLEARED ;MSH171 SWAB R3 ;CONVERT TO WORD COUNT ;MSH171 ASR R3 ; ;MSH171 ASR R3 ; ;MSH171 ASR R3 ; ;MSH171 MOV R5,(R4) ;POINT TO SEGMENT TO BE CLEARED ;MSH171  MOV R0,R2 ;SET SCRATCH POINTER ;MSH171 14$: MOV #0,(R2)+ ;INIT MEMORY (NOTE-CLR CAN'T BE USED) ;MSH171 DEC R3 ;DONE WITH THIS SEGMENT YET? ;MSH171 BNE 14$ ;IF NE NO, CLEAR MORE MEMORY ;MSH171 MOV R1,R5 ;SET TOP OF INITIALIZED MEMORY ;MSH171 ;MSH171 .ENDC ;MSH171 ;MSH171 15$: MOV R1,(R4) ;POINT TO NEXT 1K BLOCK OF MEMORY ;MSH171 ;MSH171 .IF DF M$$EXT ;**-3 CMP (R4),(PC)+ ;END OF MEMORY? ;MSH208 16$: .WORD 170000 ;ASSUME UPPER LIMIT TO BE 2MW ;MSH208 ;**-1 .IFF CMP (R4),#7600 ;END OF MEMORY? ;MSH171 ;**-1 .ENDC ;**-1 BLO 13$ ;IF LO NO .IFF ADD #4000,R0 ;UPDATE MEMORY ADDRESS BY 1K CMP R0,#160000 ;END OF MEMORY? BLO 13$ ;IF LO NO .IFTF 17$: MOV R1,$SYSIZ ;SET SIZE OF MEMORY IN 32W BLOCKS ;MSH161 ; ;MSH161 ; IF THE LAST PARTITION IN AN RSX-11S SYSTEM IS DYNAMIC, EXTEND ITS ;MSH161 ; SIZE TO THE END OF MEMORY. ;MSH161 ; ;MSH161 ;MSH161 .IFT ;M$$MGE ;MSH161 ;MSH161 .IF DF R$$11S&D$$YNM ;MSH161 ;MSH161 MOV #$PARHD,R0 ;PICK UP PCB LIST HEAD ;MSH161 173$: MOV (R0),R2 ;GET ADDRESS OF NEXT PCB ;MSH161 BEQ 177$ ;IF EQ END OF LIST ;MSH161 ;MSH161 .IF DF M$$EXT ;MSH161 ;MSH161 CMP P.REL(R2),#177600 ;IS IT A DEVICE PARTITION PCB? ;MSH161 ;MSH161 .IFF ;MSH161 ;MSH161 CMP P.REL(R2),#7600 ;IS IT A DEVICE PARTITION PCB? ;MSH161 ;MSH161 .ENDC ;MSH161 ;MSH161 BHIS 177$ ;IF HIS YES, LAST REAL PAR FOUND ;MSH161 MOV R2,R0 ;GET NEXT PCB IN LIST ;MSH161 BR 173$ ; ;MSH161 ;MSH161 177$: BIT #PS.SYS,P.STAT(R0) ;SYSTEM CONTROLLED PARTITION? ;MSH161 BEQ 179$ ;IF EQ NO ;MSH161 MOV R1,R2 ;COPY SYSTEM SIZE IN 32-WORD BLOCKS ;MSH161 SUB P.REL(R0),R2 ;COMPUTE SIZE OF LAST PARTITION ;MSH161 MOV R2,P.SIZE(R0) ;AND SET IT ;MSH161 179$: ;MSH161 ;MSH161 .ENDC ;MSH161 MOV #1400,(R4) ;RESET MAPPING RELOCATION BIAS ;MSH171 ;MSH045 ; ;MSH045 ; VERIFY THE EXISTENCE OF THE EXTERNAL EXECUTIVE COMMONS. IF NOT ;MSH045 ; THERE, THEN OBVIOUSLY THE SYSTEM WILL NOT RUN. ;MSH045 ; ;MSH045 ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 18$: MOV $XCOM1,R0 ;GET FIRST EXEC COMMON OFFSET ;MSH045 BNE 19$ ;IF NE POINTER IS LOADED ;MSH045 181$: JSR R5,OPMSG ;ERROR - MISSING EXECUTIVE COMMON ;MSH045 .WORD NDCOM ;MSH045  ;MSH045 .IF DF X$$DBT ;MSH045 ;MSH045 BPT ;TRAP TO XDT ;MSH045 ;MSH045 .IFF ;MSH045 ;MSH045 HALT ;HALT THE BOOT PROCESS ;MSH045 ;MSH045 .ENDC ;MSH045 ;MSH045 BR 181$ ;NO MORE EXECUTION ALLOWED! ;MSH045 ;MSH045 19$: CALL PARCK ;GO VALIDATE THE COMMON'S OFFSET ;MSH165 BCS 181$ ;IF CS INVALID POINTER ;MSH165 MOV $XCOM2,R0 ;GET SECOND EXEC COMMON OFFSET ;MSH165 BEQ 181$ ;IF EQ NOT THERE ;MSH165 CALL PARCK ;GO VALIDATE THE COMMON'S OFFSET ;MSH165 BCS 181$ ;IF CS INVALID POINTER ;MSH165 ;MSH165 .ENDC ;MSH045 ;**-3 .ENDC ; ;MSH149 ; DETECT WHETHER OR NOT THE FLOATING POINT PROCESSOR IS PRESENT. ;MSH149 ; ALSO, DETECT WHETHER OR NOT EIS IS PRESENT. IF NOT AND IT IS ;MSH149 ; SUPPORTED, THE SYSTEM CANNOT RUN. ;MSH149 ; ;MSH149 ;MSH149 .IF DF F$$LPP!M$$EIS ;MSH149 ; PB175 MOV @#10,-(SP) ;SAVE ILLEGAL INSTR. VECTOR ; PB175 MOV #$TRINT,@#10 ;PLUG VECTOR WITH TRAP ADDRESS ;MSH112 ;MSH149 .IF DF F$$LPP ;MSH149 ;MSH149 CLC ;MAKE SURE CARRY IS CLEAR ;MSH149 SETI ;ISSUE A FLOATING POINT INSTRUCTON ;MSH149 BCS 193$ ;IF CS, NO FLOATING POINT PROCESSOR ;MSH149 BIC #HF.FPP,$HFMSK ;SHOW FPP PRESENT ;MSH149 193$: ;MSH149 .ENDC ;MSH149 ;MSH149 .IF DF M$$EIS ;MSH149 ;MSH149 CLR R0 ;SET UP NULL SHIFT, CLR'S C ON SUCCESS ;MSH179 ASH R0,R0 ;EXECUTE AN EIS INSTRUCTION ;MSH179 BCC 195$ ;IF CC THE ASH WORKED, SO EIS IS HERE ;MSH179 JSR R5,OPMSG ;ERROR - NO EIS ON THIS CPU ; PB175 .WORD NOEIS ; ; PB175 HALT ;STOP RIGHT HERE ; PB175 BR .-2 ;GO NO FURTHER!! ; PB175 ;MSH149 .ENDC ;MSH149 ;MSH149 195$: MOV (SP)+,@#10 ;RESTORE ILLEGAL INSTR. VECTOR ; PB175 ; PB175 .ENDC ; PB175 ; PB175 ; ; PB175 ; MAKE SURE THAT ALL SELECTED DEVICES ARE ONLINE. ; PB175 ; ; PB175 ; PB175 MOV #$DEVHD,R5 ;GET ADDRESS OF FIRST DCB ADDRESS 20$: MOV (R5),R5 ;GET ADDRESS OF NEXT DCB BEQ 80$ ;IF EQ NO MORE TO SCAN MOV D.UCB(R5),R4 ;POINT TO FIRST UCB BIT #DV.PSE,U.CW1(R4) ;PSEUDO DEVICE? BNE 20$ ;IF NE YES MOVB D.UNIT(R5),-(SP) ;SET STARTING LOGICAL UNIT NUMBER MOVB D.UNIT+1(R5),-(SP) ;CALCULATE NUMBER OF UCB'S TO SCAN SUB D.UNIT(R5),(SP) ; INCB (SP) ; 40$: CMP $SYSIZ+6,D.NAM(R5) ;DEVICE NAMES MATCH? ;**-5 BNE 45$ ;IF NE NO CMPB $SYSIZ+2,2(SP) ;UNIT NUMBERS MATCH? BNE 45$ ;IF NE NO MOV R4,.SY0+2 ;REDIRECT SYSTEM DEVICE MOV R4,.LB0+2 ;REDIRECT LB: AS WELL 45$: MOV U.SCB(R4),R2 ;GET ADDRESS OF SCB TSTB @S.CSR(R2) ;DEVICE IN SYSTEM? ;**-1 BCC 60$ ;IF CC YES BISB #US.OFL,U.ST2(R4) ;SET DEVICE OFFLINE MOVB D.NAM(R5),DEVMG+12. ;INSERT GENERIC DEVICE NAME MOVB D.NAM+1(R5),DEVMG+13. ; MOV R4,R0 ;COPY ADDRESS OF UCB CLR R0 ;GET LOGICAL UNIT NUMBER ;MSH044 BISB 2(SP),R0 ; ;MSH044 MOV #8.,R1 ;SET DIVISOR ;**-5 CALL $DIV ;CONVERT UNIT NUMBER TO 2 DIGITS ADD #'0,R0 ;ADD CHARACTER BIAS ADD #'0,R1 ;ADD CHARACTER BIAS MOVB R0,DEVMG+14. ;INSERT DEVICE UNIT NUMBER MOVB R1,DEVMG+15. ; JSR R5,OPMSG ;OUTPUT DEVICE MESSAGE .WORD DEVMG ; 60$: ; ;MSH209 ;MSH209 .IF DF M$$EXT&R$$L11 ;MSH209 ;MSH209 CMP #"DL,D.NAM(R5) ;'DL' DEVICE? ;MSH209 BNE 65$ ;IF NE NO ;MSH209 BIC #DV.EXT,U.CW1(R4) ;ASSUME DRIVER MUST USE UNIBUS MAP ;MSH209 TST $UMRPT ;Q22-BUS MACHINE? ;MSH209 BNE 65$ ;IF NE NO, UNIBUS MAP EXISTS ;MSH209 BIS #DV.EXT,U.CW1(R4) ;FORCE DRIVER TO ACCESS BAE REGISTER ;MSH209 ;MSH209 .ENDC ;MSH209 ;MSH209 65$: ADD D.UCBL(R5),R4 ;CALCULATE ADDRESS OF NEXT UCB ;MSH209 INCB 2(SP) ;UPDATE LOGICAL UNIT NUMBER ;MSH044 DECB (SP) ;ANY MORE UCB'S TO SCAN? ;MSH044 BNE 40$ ;IF NE YES ;MSH044 CMP (SP)+,(SP)+ ;CLEAN STACK ;MSH044 BR 20$ ;LOOK AT NEXT DCB ;MSH044 80$: ;REF LABEL ;**-2 ; ;MSH156 ; VERIFY THE PRESENCE OF THE WATCHDOG TIMER. IF NOT THERE, DISABLE ;MSH156 ; ACCESS TO IT. ;MSH156 ; ;MSH156 ;MSH156 .IF DF K$$W11 ;MSH156 ;MSH156 MOV #K$$W11,R0 ;GET THE WATCHDOG TIMER CSR ADDRESS ;MSH156 TST (R0) ;DOES THE WATCHDOG TIMER EXIST? ;MSH156 BCS 85$ ;IF CS NO ;MSH156 MOV R0,$WTCSR ;SET WATCHDOG TIMER CSR POINTER ;MSH156 85$: ;MSH156 .ENDC ;MSH156 ;MSH156 ; ;MSH201 ; INITIALIZE THE PARITY MEMORY CONTROL STRUCTURE. ;MSH201 ; ;MSH201 .IF DF P$$RTY MOV #$PARTB,R0 ;GET ADDRESS OF PARITY CSR ADDRESS TABLE MOV R0,R1 ;COPY ADDRESS OF TABLE MOV #1,(R1)+ ;INSERT A ONE IN FIRST TABLE ENTRY MOV (R0),R5 ;INIT CSR MASK BIT ;MSH201 MOV R0,R4 ;COPY ADDRESS OF TABLE ;MSH201 TST -(R4) ;POINT TO PARITY CSR MASK WORD ;MSH201 MOV #MPAR-2,R2 ;GET ADDRESS OF FIRST PARITY REGISTER-2 MOV #16.,R3 ;SET NUMBER OF PARITY REGISTERS 90$: ADD #2,R2 ;ADVANCE TO NEXT PARITY CSR REGISTER MOV R2,(R1)+ ;ASSUME PARITY REGISTER PRESENT TST (R2) ;PARITY CSR REGISTER PRESENT? BCC 100$ ;IF CC YES MOV R0,-2(R1) ;POINT TO FIRST WORD OF TABLE BIC R5,(R4) ;MARK THIS CSR AS MISSING ;MSH201 100$: ASL R5 ;ADVANCE MASK BIT ;MSH201 DEC R3 ;ANY MORE TO SCAN? ;MSH201 BGT 90$ ;IF GT YES ;**-1 MOV (R1),R1 ;11/70 CACHE PARITY CSR SEARCH DONE? BEQ 105$ ;IF EQ YES MOV (R0),R5 ;INIT CACHE CSR MASK BIT ;MSH201 TST -(R4) ;POINT TO CACHE CSR MASK WORD ;MSH201 MOV #MPCSR-10,R2 ;POINT TO FIRST CSR ADDRESS - 2 MOV #6,R3 ;SET COUNT OF REGISTERS BR 90$ ;SEARCH FOR THEM 105$: ;REF LABEL .ENDC ; ;MSH171 ; MAKE SURE THAT THE FLOATING POINT EXCEPTION VECTOR IS CORRECT. ;MSH171 ; ;MSH171 .IF DF F$$LPP TST PIRQ ;IS THERE A PIRQ REGISTER? BCS 106$ ;IF CS NO MOV #$FPPRQ,@#240 ;SET UP PIRQ VECTOR MOV #$FPPR8,@#244 ;SET UP FLOATING POINT EXCEPTION VECTOR 106$: ;REF LABEL .ENDC JSR R5,OPMSG ;OUTPUT INITIAL PROMPT MESSAGE .WORD PROMT ; ; ;MSH171 ; SET UP CORRECT SYSTEM CLOCK. IF THE SET SYSTEM TIME DIRECTIVE IS ;MSH171 ; SUPPORTED, INITIALIZE SOME CRITICAL CONTROL DATA FOR IT. ;MSH171 ; ;MSH171 MOV $CKCSR,R0 ;GET ADDRESS OF CLOCK CSR TST (R0) ;IS THE GENERATED CLOCK AVAILABLE? BCC 110$ ;IF CC YES MOV #172540,R0 ;GET ADDRESS OF KW11-P CSR MOV R0,$CKCSR ;SETUP FOR KW11-P MOV #172542,$CKCNT ; MOV #K$$LDC,$CKLDC ;SET COUNT REGISTER LOAD COUNT MOV #K$$TPS,$TKPS ;SET TICKS PER SECOND TST (R0) ;KW11-P? BCC 110$ ;IF CC YES MOV #177546,R0 ;GET ADDRESS OF KW11-L CSR MOV R0,$CKCSR ;SETUP FOR KW11-L MOV R0,$CKCNT ; CLR $CKLDC ; MOV #H$$RTZ,$TKPS ;SET TICKS PER SECOND TO LINE FREQUENCY 110$: MOV #$NONSI,@#100 ;RESET KW11-L INTERRUPT VECTOR MOV #$CKINT,104 ;SETUP KW11-P VECTOR CMP #172540,R0 ;KW11-P? BEQ 120$ ;IF EQ YES MOV #$CKINT,100 ;SETUP KW11-L VECTOR MOV #$NONSI,104 ;RESET KW11-P VECTOR TST (R0) ;KW11-L? ;MSH044 BCC 120$ ;IF CC YES ;MSH044 CLR $CKCSR ;CLEAR CLOCK CSR POINTER ;MSH044 CLR $CKCNT ;CLEAR CLOCK COUNTER POINTER ;MSH044 BR 130$ ;MSH044 120$: MOV $CKCNT,R1 ;GET ADDRESS OF COUNT REGISTER MOV $CKLDC,(R1) ;SETUP CLOCK COUNT REGISTER MOV #K$$IEN,(R0) ;START CLOCK 130$: ;REF LABEL ;MSH044 ;MSH123 .IF DF S$$TIM ;MSH123 ;MSH123 MOV $TKPS,$TIKLM ;INIT TICKS/SECOND HIGH CHECK ;MSH123 DEC $TIKLM ;CONVERT FROM FREQUENCY TO HIGH LIMIT ;MSH123 ;MSH123 .ENDC ;MSH123 .IF DF M$$MGE MOV #PMODE+PR7,PS ;MAKE SURE PS IS SETUP PROPERLY .ENDC ; ;MSH142 ; INITIALIZE THE POOL MONITOR CONTROL STRUCTURE. ;MSH142 ; ;MSH142 ;MSH142 .IF DF P$$CTL ;MSH142 ;MSH142 MOV $CRAVL,R0 ;GET POINTER TO SECOND FREE POOL BLOCK ;MSH142 CLR R1 ;INITIALIZE SIZE COUNTER ;MSH142 140$: ADD 2(R0),R1 ;ADD LENGTH OF FREE POOL BLOCK ;MSH142 MOV (R0),R0 ;POINT TO NEXT FREE POOL BLOCK IN LIST ;MSH142 BNE 140$ ;IF NE THERE IS ONE ;MSH142 MOV R1,$PRISZ ;STORE IT AWAY FOR THE POOL MONITOR ;MSH142 CLR $POLST ;INITIALIZE EXEC/POOL TASK FLAGS ;MSH142 ;MSH142 .ENDC ;MSH142 ;MSH171 ; ;MSH171 ; NOW THAT INITL IS DONE, DEALLOCATE IT INTO THE DYNAMIC STORAGE ;MSH171 ; REGION. CORRECT THE STARTING ADDRESS OF THE NEW POOL BLOCK TO ;MSH171 ; BEGIN ON A DOUBLEWORD BOUNDARY. ;MSH171 ; ;MSH171 MOV #SYSMG,R0 ;SET ADDRESS OF BLOCK TO RELEASE ADD $CRAVL-2,R0 ;ROUND TO NEXT BOUNDARY BIC $CRAVL-2,R0 ; MOV #$SYBEG-SYSMG,R1 ;SET LENGTH OF BLOCK TO RELEASE CALLR $DEACB ;DEALLOCATE INITIALIZATION CODE ;MSH165 ; ;MSH165 ; SUBROUTINE TO VALIDATE EXECUTIVE COMMON POINTERS ;MSH165 ; ;MSH165 ; INPUTS: R0=COMMON PARTITION OFFSET IN 32-WORD BLOCKS ;MSH165 ; R1=SYSTEM SIZE IN 32-WORD BLOCKS ;MSH165 ; ;MSH165 ;MSH165 PARCK: MOV #$PARHD,R5 ;LOAD PARTITION LISTHEAD ;MSH165 10$: MOV (R5),R5 ;GET NEXT PCB IN LIST ;MSH165 BEQ 20$ ;IF EQ NO MATCH ;MSH165 CMP P.REL(R5),R0 ;IS THIS THE CORRECT PCB? ;MSH165 BNE 10$ ;IF NE NO, LOOK AT THE NEXT ONE ;MSH165 ADD P.SIZE(R5),R0 ;FOUND IT, CALCULATE TOP OF COMMON ;MSH165 BCS 20$ ;IF CS, THEN 6 X 9 MUST BE 42 ;MSH165 CMP R0,R1 ;IS COMMON LOADED IN MEMORY? ;MSH165 BHI 20$ ;IF HI NO, CAN'T BOOT THIS SYSTEM ;MSH165 TST P.BUSY(R5) ;IS COMMON ACTUALLY INSTALLED? ;MSH165 BPL 20$ ;IF PL NO, CAN'T BOOT ;MSH165 TSTB P.STAT(R5) ;IS THIS A COMMON PARTITION? ;MSH165 BPL 20$ ;IF PL NO, CANNOT BE AN EXEC COMMON ;MSH165 RETURN ;COMMON POINTER IS VALID ;MSH165 ;MSH165 20$: SEC ;COMMON POINTER IS INVALID ;MSH165 RETURN ; ;MSH165 ; ; SUBROUTINE TO OUTPUT A MESSAGE TO THE SYSTEM CONSOLE TERMINAL ; OPMSG: MOV (R5)+,R1 ;GET ADDRESS OF OUTPUT MESSAGE 10$: MOVB (R1)+,R0 ;GET NEXT BYTE TO OUTPUT BEQ 30$ ;IF EQ DONE MOVB R0,TPS+2 ;LOAD BYTE IN OUTPUT BUFFER 20$: TSTB TPS ;PRINTER BUSY? BCS 30$ ;IF CS NO CONSOLE TERMINAL BPL 20$ ;IF PL YES BR 10$ ;GO AGAIN 30$: RTS R5 ; ;MSH181 ; ;MSH181 ; SUBROUTINE TO INTERCEPT UNEXPECTED T-BIT TRAPS AFTER LSI POWER UP. ;MSH181 ; THIS ROUTINE CLEARS THE T-BIT AND DISMISSES IT. IT IS ASSUMED THAT ;MSH181 ; THE BPT/T-BIT VECTOR WILL BE RESET TO THE EXECUTIVE'S SST ROUTINE ;MSH181 ; SOON AFTER BOOTING RSX. ;MSH181 ; ;MSH181 ;MSH181 .IF NDF P$$RFL ;MSH181 .IF DF L$$SI1 ;MSH181 ;MSH181 $TBIT:: BIC #20,2(SP) ;CLEAR T-BIT IN SAVED PS ;MSH181 RTI ;DISMISS THE TRAP ;MSH181 ;MSH181 .ENDC ;MSH181 .ENDC ;MSH181 ;**-7 ; ; MAKE SURE THAT INITL IS OF DOUBLEWORD LENGTH. NOTE THAT THIS CAUSES ;MSH171 ; $SYBEG TO BE ON A MATCHING BOUNDARY TYPE AS THAT OF $POOL. ;MSH171 ; ;**-1 .EVEN ;MSH171 .IF NE <.-SYSMG>&3 .BLKB <.-SYSMG>&3 .ENDC ; ; BEGINNING OF DYNAMIC STORAGE REGION. NOTE THAT AFTER TASK BUILDING, ;MSH171 ; $SYBEG MAY NOT BE ON A DOUBLEWORD BOUNDARY. THIS IS CORRECTED AS ;MSH171 ; SOON AS THE SYSTEM IS VMR'ED. ALSO, A COMPARABLE CORRECTION IS MADE ;MSH171 ; TO $POOL WHEN INITL DEALLOCATES ITSELF. WE ARE GUARANTEED THAT SINCE ;MSH171 ; $POOL AND $SYBEG HAVE TO BE EQUALLY CORRECTED (BECAUSE INITL IS ALWAYS;MSH171 ; OF DOUBLEWORD LENGTH) WE DO NOT HAVE TO ADJUST THE AMOUNT TO ;MSH171 ; DEALLOCATE AND THAT INITL WILL BE CORRECTLY AGGLOMERATED INTO POOL. ;MSH171 ; ;**-1 $SYBEG::.WORD 0 ;LINK TO NEXT BLOCK IN FREE LIST .WORD <<+3>&17’7774> ;LENGTH OF FREE BLOCK .BLKB <<+3>&177774>-4 ;ALLOCATE REMAINING STORAGE $SYTOP:: ;LAST ADDRESS IN EXECUTIVE .END $INITL ’óeƒkQ ›c, .TITLE PLSUB .IDENT /01.00/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.00 ; ; T. J. MILLER 8-MAR-76 ; ; PROGRAM LOGICAL ADDRESS SPACE (PLAS) COMMON SUBROUTINES ; ; MACRO LIBRARY CALLS ; .IF DF P$$LAS .MCALL HDRDF$,HWDDF$,PCBDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$SRNAM-SEARCH FOR NAMED PARTITION ; ; THIS ROUTINE SEARCHES FOR A NAMED PARTITION AND RETURNS A SUCCESS/ ; FAILURE INDICATION AND A POINTER TO THE PCB IF FOUND. ; ; INPUTS: ; ; R3=POINTER TO DOUBLE-WORD RAD50 NAME ; ; OUTPUTS: ; ; C=1 IF NO MATCH ON NAME ; ; C=0 IF NAMED PARTITION FOUND ; R2=PCB ADDRESS ;- $SRNAM::MOV $PARHD,R2 ;POINT TO FIRST PCB IN THE LIST 10$: CMP P.NAM(R2),(R3) ;MATCH ON FIRST WORD OF NAME? BNE 20$ ;IF NE NO CMP P.NAM+2(R2),2(R3) ;MATCH ON SECOND WORD OF NAME? BEQ 50$ ;IF EQ YES 20$: ;REF LABEL .IF DF D$$YNM&M$$MGE BIT #PS.SYS,P.STAT(R2) ;SYSTEM CONTROLLED PARTITION? BEQ 40$ ;IF EQ NO TST P.SUB(R2) ;IS THERE ANOTHER SUBPARTITION? BEQ 30$ ;IF EQ NO MOV P.SUB(R2),R2 ;POINT TO NEXT SYS SUBPARTITION BR 10$ ; 30$: MOV P.MAIN(R2),R2 ;POINT BACK TO MAIN PCB .ENDC 40$: MOV (R2),R2 ;POINT TO NEXT PCB (P.LNK)  BNE 10$ ;IF NE THERE IS ONE SEC ;RETURN C=1 50$: RETURN ; ;+ ; **-$CKACC-CHECK DESIRED ACCESS ; ; THIS ROUTINE CHECKS IF THE DESIRED ACCESS OF A TASK TO A REGION ; IS ALLOWED. THE BITS IN THE PROTECTION WORD ARE ARRANGED IN THE ; FOLLOWING ORDER: ; ; [WORLD,GROUP,OWNER,SYSTEM] ; 15 0 ; ; THE BITS WITHIN EACH CATEGORY IN THE PROTECTION WORD ARE ARRANGED ; IN THE FOLLOWING ORDER: ; ; DELETE EXTEND WRITE READ ; 3 2 1 0 ; ; A BIT SET MEANS THE CORRESPONDING ACCESS IS NOT ALLOWED. ; ; INPUTS: ; ; R0=DESIRED ACCESS MASK IN LOW FOUR BITS ; R1=CURRENT UIC OF TASK ; R2=PCB ADDRESS OF REGION ; ; OUTPUTS: ; ; R0,R1 ARE MODIFIED ; ; DIRECTIVE STATUS OF D.RS16 RETURNED IF ACCESS DENIED. ;- $CKACC::MOV #30$,-(SP) ;PUSH COROUTINE ADDRESS BIC #^C17,R0 ;CLEAR ALL BUT DESIRED ACCESS MASK 10$: SWAB R1 ;REVERSE GROUP AND OWNER IN UIC WORD CALL @(SP)+ ;CHECK IF QUALIFIED IN NEXT CATEGORY BNE 20$ ;IF NE NO BIT R0,P.PRO(R2) ;ALLOWED ACCESS IN THIS CATEGORY? BNE 20$ ;IF NE NO TST (SP)+ ;POP COROUTINE ADDRESS RETURN ;RETURN TO CALLER 20$: ASL R0 ;SHIFT MASK TO NEXT CATEGORY ASL R0 ; ASL R0 ; ASL R0 ; BR 10$ ;CHECK ACCESS IN THIS CATEGORY 30$: CMPB R1,#10 ;SYSTEM UIC? BHI 40$ ;IF HI NO SEZ ;SET FLAG FOR ACCESS CHECK 40$: CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK CMP R1,P.OWN(R2) ;OWNER UIC? CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK CMPB R1,P.OWN+1(R2) ;SAME GROUP? CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK SEZ ;INSURE CHECK FOR WORLD ACCESS CALL @(SP)+ ;CHECK ACCESS DRSTS D.RS16 ;ACCESS DENIED IF WE GET HERE ;+ ; **-$CRATT-CREATE ATTACHMENT DESCRIPTOR ; ; THIS ROUTINE CREATES AN ATTACHMENT DESCRIPTOR AND INSERTS IT IN THE ; NECESSARY QUEUES. ; ; INPUTS: ; ; R2=PCB ADDRESS OF REGION BEING ATTACHED TO ; R4=ACCESS CODE ; R5=TCB ADDRESS OF ATTACHING TASK ; ; OUTPUTS: ; ; C=0 IF SUCCESSFUL ; R1=ADDRESS OF ATTACHMENT DESCRIPTOR ; R0 IS MODIFIED ; C=1 IF AN ATTACHMENT DESCRIPTOR COULD NOT BE ALLOCATED ; R0,R1 ARE MODIFIED ;- $CRATT::MOV R3,-(SP) ;SAVE R3 MOV R2,-(SP) ;SAVE PCB ADDRESS MOV #A.LGTH,R1 ;PICK UP ATTACHMENT DESCRIPTOR SIZE CALL $ALOCB ;ALLOCATE THE ATTACHMENT DESCRIPTOR BCS 10$ ;IF CS ALLOCATION FAILURE ADD R0,R1 ;POINT PAST END OF ATTACHMENT DESCRIPTOR MOV (SP),-(R1) ;SET PCB ADDRESS (A.PCB) MOV R4,-(R1) ;INIT STATUS AND MAP COUNT (A.STS) BIC #^C17,(R1) ;CLEAR ALL BUT ACCESS BITS (A.STS) TST -(R1) ;POINT TO TCBL THREAD WORD (A.TCBL) MOV R5,R0 ;POINT TO TCB ATTACHMENT LISTHEAD ADD #T.ATT,R0 ; CALL $QINSF ;INSERT DESCRIPTOR AT END OF QUEUE MOV R5,-(R1) ;SET TCB ADDRESS (A.TCB) CLRB -(R1) ;ZERO I/O COUNT (A.IOC) MOVB T.PRI(R5),-(R1) ;INIT PRIORITY TO TASK PRIORITY (A.PRI) TST -(R1) ;POINT TO PCBL THREAD (A.PCBL) MOV (SP),R0 ;POINT TO PCB ATTACHMENT LISTHEAD ADD #P.ATT,R0 ; CALL $QINSP ;INSERT IN QUEUE BY PRIORITY CLC ;INDICATE SUCCESS 10$: MOV (SP)+,R2 ;RESTORE PCB ADDRESS MOV (SP)+,R3 ;RESTORE R3 RETURN ; ;+ ; **-$SRATT-SEARCH FOR ATTACHMENT DESCRIPTOR ; ; THIS ROUTINE VERFIES IF A VALID REGION ID WAS PASSED IN A PLAS DIRECTIVE ; BY SEARCHING FOR THE CORRESPONDING ATTACHMENT DESCRIPTOR IN THE TCB'S ; ATTACHMENT QUEUE. ; ; INPUTS: ; ; (R3)=REGION ID TO VERIFY (OR 0 TO IMPLY TASK REGION) ; R5=TCB ADDRESS OF CURRENT TASK ; ; OUTPUTS: ; ; R5=ADDRESS OF ATTACHMENT DESCRIPTOR ; ; D.RS86 IS RETURNED IF THE ATTACHMENT DESCRIPTOR CANNOT BE FOUND. ;- $SRATT::MOV T.ATT(R5),R5 ;POINT TO FIRST ATTACHMENT DESCRIPTOR  MOV (R3),-(SP) ;DEFAULT TO TASK REGION? BEQ 20$ ;IF EQ YES ADD #A.TCBL,(SP) ;ADD BIAS TO LINK WORD 10$: CMP R5,(SP) ;MATCH ON THIS DESCRIPTOR? BEQ 20$ ;IF EQ YES MOV (R5),R5 ;ELSE POINT TO NEXT DESCRIPTOR (A.TCBL) BNE 10$ ;IF NE THERE IS ONE DRSTS D.RS86 ;INVALID REGION ID 20$: SUB #A.TCBL,R5 ;POINT TO START OF ATTACHMENT DESCRIPTOR TST (SP)+ ;CLEAN STACK RETURN ; ;+ ; **-$SRWND-SEARCH FOR SPECIFIED ADDRESS WINDOW ; ; THIS ROUTINE VERIFIES THAT THE SPECIFIED ADDRESS WINDOW ID CORRESPONDS ; TO A VALID ESTABLISHED ADDRESS WINDOW. ; ; INPUTS: ; ; (R3)=ADDRESS WINDOW ID ; R4=ADDRESS OF CURRENT TASK HEADER ; ; OUTPUTS: ; ; R4=POINTER TO SPECIFIED WINDOW BLOCK ; R0 IS MODIFIED. ; ; D.RS87 IS RETURNED IF THE SPECIFIED ADDRESS WINDOW IS INVALID ;- $SRWND::MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOWS MOVB (R3),R0 ;PICK UP ADDRESS WINDOW ID (W.NID) BEQ 10$ ;IF EQ ILLEGAL CMP R0,(R4)+ ;WINDOW ID TOO LARGE? BHIS 10$ ;IF HIS YES ASL R0 ;CONVERT WINDOW ID TO 8 WORD OFFSET ASL R0 ; ASL R0 ; ASL R0 ; ADD R0,R4 ;POINT TO ADDRESS WINDOW TST W.BSIZ(R4) ;IS IT AN ESTABLISHED ADDRESS WINDOW? BEQ 10$ ;IF EQ NO RETURN ; 10$: DRSTS D.RS87 ;INVALID ADDRESS WINDOW ;+ ; **-$UNMAP-UNMAP ADDRESS WINDOW ; ; THIS ROUTINE SEARCHES FOR AND CONDITIONALLY UNMAPS THE SPECIFIED ; ADDRESS WINDOW. ; ; INPUTS: ; ; R4=ADDRESS OF WINDOW TO BE UNMAPPED ; ; OUTPUTS: ; ; R0 IS MODIFIED ; ; C=1 IF UNMAPPING WAS PERFORMED ;- .ENABL LSB $UNMAP::TST (R4) ;IS WINDOW MAPPED? (W.BPCB) BEQ 20$ ;IF EQ IT IS NOT MAPPED MOV R1,-(SP) ;SAVE R1 CLR (R4) ;UNMAP ADDRESS WINDOW (W.BPCB) MOV W.BATT(R4),R0 ;PICK UP ADDRESS OF ATTACHMENT DESCRIPTOR CLR W.BATT(R4) ;CLEAR ATTACHMENT DESCRIPTOR POINTER DECB A.MPCT(R0) ;DECREMENT MAPPING COUNT MOV A.TCB(R0),R1 ;POINT TO TASK TCB ADDRESS MOVB W.BFPD(R4),R0 ;POINT TO FIRST USER PDR 10$: BIT #T3.PRV,T.ST3(R1) ;IS THE TASK PRIVILEGED? BEQ 14$ ;IF EQ NO MOV KISAR0-UISDR0(R0),UISAR0-UISDR0(R0) ;RESTOREô PRV MAPPING MOV #77406,(R0)+ ; BR 15$ ; 14$: CLR (R0)+ ;CLEAR NEXT USER PDR 15$: DECB W.BNPD(R4) ;DONE YET? BGT 10$ ;IF GT NO MOV (SP)+,R1 ;RESTORE R1 SEC ;RETURN CS FOR WINDOW UNMAPPED 20$: RETURN ; .ENDC .END ôÔ@ykQ ›c, .TITLE DRDSP .IDENT /15.35/ ; ; COPYRIGHT (c) 1981 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD ; MASSACHUSETTS. ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED AND COPIED ONLY IN ACCORDANCE WITH THE ; TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE ; ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE ; MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO ; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO ; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED ; AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR ; RELIABILITY OF ITS SOFTWARE ON EQUIPMENT THAT IS ; NOT SUPPLIED BY DIGITAL. ; ; VERSION 15.35 ; ; D. N. CUTLER 12-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 24-JUL-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT ; ; M. S. HARVEY 17-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 1-SEP-79 ; MSH052 -- ENABLE CANCEL SELECTIVE MARK TIME DIRECTIVE ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 2-JAN-80 ; MSH078 -- ADD GET/PUT INFORMATION DIRECTIVE ; ; M. S. HARVEY 19-MAY-80 ; MSH100 -- RETURN CORRECT DIRECTIVE STATUS FROM ERROR ; THREADED DIRECTIVES ; ; M. S. HARVEY 3-JUN-80 ; MSH104 -- EMIT STATUS DIRECTIVE SUPPORT ; SEND, REQUEST AND CONNECT DIRECTIVE SUPPORT ; ; M. S. HARVEY 15-SEP-80 ; MSH118 -- EXTEND PARTITION DIRECTIVE MUST BE ILLEGAL ; FOR RSX-11S SYSTEMS ; ; M. S. HARVEY 6-OCT-80 ; MSH121 -- ADD SPECIFY REQUESTED EXIT AST DIRECTIVE ; ; M. S. HARVEY 17-OCT-80 ; MSH123 -- ADD SUPPORT FOR SET SYSTEM TIME DIRECTIVE ; ; M. S. FOX 07-JAN-81 ; MF204 -- ADD GCCI$ DIRECTIVE ; ; M. S. HARVEY 8-JAN-81 ; MSH139 -- MAP STOPFOR DIRECTIVES INTO WAITFOR DIRECTIVES ; IF THE FORMER WERE NOT CHOSEN DURING SYSGEN ; ; DAN BROWN 7-JAN-81 ; DTB003 -- ADD SUPPORT FOR SEND MESSAGE DIRECTIVE ; ; M. S. FOX 26-JAN-81 ; MF207 -- ADD RPOI$ AND SDRP$ DIRECTIVES ; ; M. S. FOX 03-FEB-81 ; MF208 -- ADD CLI CONTROL DIRECTIVES ; ; M. S. HARVEY 11-FEB-81 ; MSH148 -- ADD THE UNLOCK GROUP GLOBAL DIRECTIVE ; ; M. S. HARVEY 21-APR-81 ; MSH165 -- ADD SUPPORT FOR SECOND DIRECTIVE COMMON ; ; M. S. HARVEY 12-JUN-81 ; MSH176 -- MAP 'EXIT WITH STATUS' INTO 'EXIT TASK' ; IF NO PARENT/OFFSPRING TASKING SUPPORT ; ; M. S. HARVEY 21-JUL-81 ; MSH180 -- ALLOW UNSTOP TO CONSISTENTLY ALLOW DEFAULTED ; TASK NAME ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 6-OCT-81 ; MSH194 -- EXTERNALIZE WAITFOR ROUTINE ; ; DIRECTIVE DISPATCHER ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,HWDDF$,TCBDF$,WDBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS WDBDF$ ;DEFINE USER WINDOW DEF BLOCK OFFSETS ; LOCAL MACROS ; ; MACRO TO DEFINE SUCCESSIVE DIRECTIVE MASK BITS ; .MACRO DEFINE SYM SYM=N N=N/2 .ENDM ; THE SIZ MACRO IS USED TO DETERMINE THE HIGHEST DIC CODE USED, AS ; WELL AS THE TOTAL NUMBER OF DIC'S IN USE. IT'S PARAMETERS ARE THE ; SAME AS THE GEN MACRO BELOW, THOUGH IT ONLY NEEDS THE DIC AND COND. .MACRO SIZ,DIC,DPBSIZ,DIRADR,MASK,COND,SECOND .IF NB .IF DF COND NUMDIR=NUMDIR+1 .IF GT DIC-HIDIR HIDIR=DIC .ENDC .ENDC ;COND .IFF ;NB COND NUMDIR=NUMDIR+1 .IF GT DIC-HIDIR HIDIR=DIC .ENDC .ENDC ;NB COND .ENDM ; THE GEN MACRO IS USED TO FILL IN THE ABOVE TABLES, BASED UPON THE ; CONDITIONAL ASSEMBLY PARAMETERS DEFINED IN RSXMC.MAC. RSXMC.MAC ; IS CREATED BY SYSGEN PART 1. THE PARAMETERS FOR THE GEN MACRO ARE: ; DIC - DIRECTIVE IDENTIFICATION CODE (MUST BE ODD). ;MSH165 ; DPBSIZ - SIZE OF THE DIRECTIVE PARAMETER BLOCK IN BYTES. ;MSH165 ; DIRADR - ADDRESS OF THE DIRECTIVE PROCESSING ROUTINE. IF ;MSH165 ; THE ODD BIT IS SET, THEN THE ROUTINE RESIDES IN ;MSH165 ; THE SECOND EXTERNAL EXECUTIVE COMMON. ;MSH165 ; MASK - DIRECTIVE PROCESSING CONTROL MASK. ;MSH165 ; COND - CONDITIONAL ASSEMBLY PARAMETERS WHICH IF SPECIFIED ;MSH165 ; MUST BE DEFINED IF THE DIRECTIVE IS SUPPORTED. IF ;MSH165 ; NONE SPECIFIED, THEN 'R$$11M' IS SPECIFIED BY DEFAULT. ;MSH165 ; SECOND - CONDITIONAL ASSEMBLY PARAMETERS WHICH IF DEFINED ;MSH165 ; ALLOWS THE DIRECTIVE TO HAVE A VARIABLE LENGTH ;MSH165 ; DIRECTIVE PARAMETER BLOCK. THE PROCESSING ROUTINES ;MSH165 ; FOR SUCH DIRECTIVES MUST VALIDATE THE SIZE OF THE ;MSH165 ; DPB THEMSELVES. ;MSH165 ; ;**-8 .MACRO GEN,DIC,DPBSIZ,DIRADR,MASK,COND,SECOND .IF B GEN ,,,,R$$11M, .IFF ;B .IF DF COND .IF DF BYTTAB .=> .BYTE DSPPTR .=DSPTBL+DSPPTR DSPPTR=DSPPTR+4 .IFF ;BYTTAB .= .ENDC ;BYTTAB .WORD DIRADR .IF NB .IF DF SECOND .BYTE 0 VARDPB=0 .IFF ;SECOND .BYTE DPBSIZ*2 .ENDC ;SECOND .IFF ;NB SECOND .BYTE DPBSIZ*2 .ENDC ;NB SECOND DSPMK=0 .IF NB .IRP X, DSPMK=DSPMK!X .ENDM .ENDC .BYTE DSPMK .ENDC ;COND .ENDC ;B .ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MSH165 ; ;MSH165 ; R S X - 1 1 M / S D I R E C T I V E S ;MSH165 ; --------------------------------------- ;MSH165 ; ;MSH165 ; EACH DIRECTIVE IS REPRESENTED AS A LINE IN THE DIREC MACRO. ; THE ONLY PARAMETER FOR THE DIREC MACRO IS THE NAME OF THE MACRO ; TO BE INVOKED UPON EACH LINE. THE FIRST CALL OF DIREC SPECIFIES ; THE SIZ MACRO TO DETERMINE WHETHER THE SINGLE OR DOUBLE TABLE ; SCHEME IS TO BE USED. THE SECOND CALL SPECIFIES THE GEN MACRO ; TO ACTUALLY GENERATE THE PROPER TABLE STRUCTURE. .MACRO DIREC,MAC ; QUEUE I/O REQUEST ;MSH165 MAC 1.,12.,$DRQIO ;MSH165 ;MSH165 ; QUEUE I/O REQUEST AND WAIT ;MSH165 MAC 3.,12.,$DRQIO ;MSH165 ;MSH165 ; GET LUN INFORMATION ;MSH165 MAC 5.,3.,$DRGLI ;MSH165 ;MSH165 ; ASSIGN LUN ;MSH165 MAC 7.,4.,$DRASG!PAG ;MSH165 ;MSH165 ; ALTER TASK PRIORITY ;MSH165 MAC 9.,4.,$DRAP1!PAG,,A$$PRI ;MSH165 ;MSH165 ; REQUEST TASK OR SPAWN OFFSPRING TASK ;MSH165 MAC 11.,7.,$DRREQ,,,P$$OFF ;MSH165 ;MSH165 ; RUN TASK ;MSH165 MAC 17.,11.,$DRRUN, ;MSH165 ;MSH165 ; SPECIFY RECEIVE-BY-REFERENCE AST ;MSH165 MAC 21.,2.,$DRRRA,,A$$TRP&P$$LAS&P$$SRF ;MSH165 ;MSH165 ; MARK TIME ;MSH165 MAC 23.,5.,$DRMKT, ;MSH165 ;MSH165 ; CANCEL SCHEDULE REQUESTS ;MSH165 MAC 25.,3.,$DRCSR, ;MSH165 ;MSH165 ; CANCEL (SELECTIVE) MARK TIME ;MSH052 MAC 27.,1.,$DRCMS,,,C$$SMT ;MSH052 ;MSH052 ; EXIT WITH STATUS ;MSH165 ;MSH176 .IF DF P$$OFF ;MSH176 ;MSH176 MAC 29.,2.,$DREXS ;MSH176 ;MSH176 .IFF ;MSH176 ;MSH176 MAC 29.,2.,$DREXT ;MSH176 ;MSH176 .ENDC ;P$$OFF ;MSH176 ;MSH165 ; CLEAR EVENT FLAG ;MSH049 MAC 31.,2.,$DRCEF, ;MSH049 ;MSH049 ; SET EVENT FLAG ;MSH049 MAC 33.,2.,$DRSEF, ;MSH049 ;MSH049 ; DECLARE SIGNIFICANT EVENT ;MSH165 MAC 35.,1.,$DRDSE ;MSH165 ;MSH165 ; READ ALL/EXTENDED EVENT FLAGS ;MSH165 MAC 39.,2.,$DRRAF,,,G$$EFN ;MSH165 ;MSH165 ; WAIT FOR SINGLE EVENT FLAG ;MSH165 MAC 41.,2.,$DRWFD, ;MSH194 ;MSH165 ; WAIT FOR LOGICAL 'OR' OF EVENT FLAGS ;MSH165 MAC 43.,3.,$DRWFL ;MSH165 ;MSH165 ; SUSPEND TASK EXECUTION ;MSH165 MAC 45.,1.,$DRSPN ;MSH165 ;MSH165 ; RESUME TASK EXECUTION ;MSH165 MAC 47.,3.,$DRRES, ;MSH165 ;MSH165 ; WAIT FOR SIGNIFICANT EVENT ;MSH165 MAC 49.,1.,$DRWSE ;MSH165 ;MSH165 ; TASK EXIT ;MSH165 MAC 51.,1.,$DREXT ;MSH165 ;MSH165 ; EXIT IF EVENT FLAG IS SET ;MSH049 MAC 53.,2.,$DREIF, ;MSH049 ;MSH049 ; CREATE DYNAMIC REGION ;MSH165 MAC 55.,2.,$DRCRR!PAG,,P$$LAS ;MSH165 ;MSH165 ; ATTACH REGION ;MSH165 MAC 57.,2.,$DRATR!PAG,,P$$LAS ;MSH165 ;MSH165 ; DETACH REGION ;MSH165 MAC 59.,2.,$DRDTR!PAG,,P$$LAS ;MSH165 ;MSH165 ; GET TIME PARAMETERS / SET SYSTEM TIME ;MSH123 MAC 61.,2.,$DRGTP!PAG,,,S$$TIM ;MSH123 ;MSH165 ; GET TASK PARAMETERS ;MSH165 MAC 63.,2.,$DRGTK,,G$$TTK ;MSH165 ;MSH165 ; GET PARTITION PARAMETERS ;MSH165 MAC 65.,4.,$DRGPP,,G$$TPP ;MSH165 ;MSH165 ; SEND BY REFERENCE ;MSH165 MAC 69.,5.,$DRSRF!PAG,,P$$LAS&P$$SRF ;MSH165 ;MSH165 ; SEND DATA TO TASK ;MSH165 MAC 71.,5.,$DRSND,,R$$SND ;MSH165 ;MSH165 ; RECEIVE DATA FROM TASK ;MSH165 MAC 75.,4.,$DRREC,,R$$SND ;MSH165 ;MSH165 ; RECEIVE DATA FROM TASK OR EXIT ;MSH165 MAC 77.,4.,$DRREC,,R$$SND ;MSH165 ;MSH165 ; RECEIVE BY REFERENCE ;MSH165 MAC 81.,2.,$DRRRF!PAG,,P$$LAS&P$$SRF ;MSH165 ;MSH165 ; ABORT TASK  ;MSH165 MAC 83.,3.,$DRABO, ;MSH165 ;MSH165 ; EXTEND TASK PARTITION ;MSH118 MAC 89.,3.,$DREXP!PAG,,D$$YNM&E$$XPR&M$$MGE&D$$ISK&C$$CKP ;MSH118 ;MSH118 ; DISABLE CHECKPOINTING FOR TASK ;MSH165 MAC 95.,1.,$DRDCP,,C$$CKP&D$$ISK ;MSH165 ;MSH165 ; ENABLE CHECKPOINTING FOR TASK ;MSH165 MAC 97.,1.,$DRECP,,C$$CKP&D$$ISK ;MSH165 ;MSH165 ; DISABLE AST RECOGNITION ;MSH165 MAC 99.,1.,$DRDAR,,A$$TRP ;MSH165 ;MSH165 ; ENABLE AST RECOGNITION ;MSH165 MAC 101.,1.,$DREAR,,A$$TRP ;MSH165 ;MSH165 ; SPECIFY SST VECTOR FOR DEBUGGING AID ;MSH165 MAC 103.,3.,$DRSDV ;MSH165 ;MSH165 ; SPECIFY SST VECTOR FOR TASK ;MSH165 MAC 105.,3.,$DRSTV ;MSH165 ;MSH165 ; SPECIFY RECEIVE DATA AST ;MSH165 MAC 107.,2.,$DRRCV,,A$$TRP&R$$SND ;MSH165 ;MSH165 ; SPECIFY POWERFAIL RECOVERY AST ;MSH165 MAC 109.,2.,$DRPUT,,A$$TRP&P$$RFL ;MSH165  ;MSH165 ; SPECIFY FLOATING POINT EXCEPTION AST ;MSH165 MAC 111.,2.,$DRFEX,,A$$TRP&F$$LPP ;MSH165 ;MSH165 ; GET MAPPING CONTEXT ;MSH165 MAC 113.,2.,$DRGMX!PAG,,P$$LAS&P$$GMX ;MSH165 ;MSH165 ; ASYNCHRONOUS SYSTEM TRAP ROUTINE EXIT ;MSH165 MAC 115.,1.,$DRATX,,A$$TRP ;MSH165 ;MSH165 ; CREATE ADDRESS WINDOW ;MSH165 MAC 117.,2.,$DRCRW!PAG,,P$$LAS ;MSH165 ;MSH165 ; ELIMINATE ADDRESS WINDOW ;MSH165 MAC 119.,2.,$DRELW!PAG,,P$$LAS ;MSH165 ;MSH165 ; MAP ADDRESS WINDOW ;MSH165 MAC 121.,2.,$DRMAP!PAG,,P$$LAS ;MSH165 ;MSH165 ; UNMAP ADDRESS WINDOW ;MSH165 MAC 123.,2.,$DRUNM!PAG,,P$$LAS ;MSH165 ;MSH165 ; GET SENSE SWITCHES ;MSH165 MAC 125.,1.,$DRGSS,,G$$TSS ;MSH165 ;MSH165 ; GET COMMAND LINE ; MF204 MAC 127.,41.,$DRGCL,,M$$CRX,A$$CLI ; MF204 ; MF204 ; CONNECT TO INTERRUPT ;MSH165 MAC 129.,7.,$DRCIN!PAG,,C$$INT ;MSH165 ;MSH165 ; STOP TASK ;MSH165 MAC 131.,1.,$DRSTP,,S$$TOP ;MSH165 ;MSH165 ; UNSTOP TASK ;MSH165 MAC 133.,3.,$DRUNS,,S$$TOP ;MSH165 ;MSH165 ; STOP FOR SINGLE EVENT FLAG ;MSH139 MAC 135.,2.,$DRSTS, ;MSH139 ;MSH139 ; STOP FOR LOGICAL 'OR' OF EVENT FLAGS ;MSH139 MAC 137.,3.,$DRSTL ;MSH139 ;MSH139 ; RECEIVE DATA FROM TASK OR STOP ;MSH165 MAC 139.,4.,$DRRCS,,S$$TOP&R$$SND ;MSH165 ;MSH165 ; SEND, REQUEST AND CONNECT / SEND, REQUEST AND CHAIN ; MF207 MAC 141.,7.,$DRSRC,,P$$OFF&R$$SND,R$$POI ; MF207 ; MF207 ; CONNECT TO TASK ;MSH165 MAC 143.,6.,$DRCNC,,P$$OFF ;MSH165 ;MSH165 ; EMIT STATUS ;MSH104 MAC 147.,4.,$DREMS,,P$$OFF ;MSH104 ;MSH104 ; CREATE GROUP GLOBAL EVENT FLAGS ;MSH165 MAC 157.,2.,$DRCRE!PAG,,G$$EFN ;MSH165 ;MSH165 ; ELIMINATE / UNLOCK GROUP GLOBAL EVENT FLAGS ;MSH148 MAC 159.,2.,$DRELE!PAG,,G$$EFN,G$$EFN ;MSH148 ;MSH148 ; SPECIFY REQUESTED EXIT AST ;MSH121 MAC 167.,2.,$DRREX,,A$$TRP&A$$BRT,A$$BRT ;MSH121 ;MSH121 ; GET / PUT INFORMATION ;MSH078 MAC 169.,0.,$DRGIN,,D$$GIN,D$$GIN ;MSH078 ;MSH078 ; SEND MESSAGE ;DTB003 MAC 171.,0.,$DRSMG!PAG,,E$$LOG,E$$LOG ;DTB003 ;DTB003 ; COMMAND LINE INTERPRETER CONTROL DIRECTIVES ; MF208 MAC 173.,0.,$DRCLI,,A$$CLI,A$$CLI  ; MF208 ; MF208 ; ;MSH165 ; DIRECTIVE IDENTIFICATION CODES 191. THRU 199. ARE GUARANTEED ;MSH165 ; TO BE AVAILABLE FOR USER-WRITTEN DIRECTIVES. ;MSH165 ; ;MSH165 ; ALL OTHER UNUSED DICS ARE RESERVED BY DIGITAL FOR FUTURE USE. ;MSH165 ; ;MSH165 ;MSH165 ;MSH165 ; ;MSH165 ; END OF DIRECTIVE LIST ;MSH165 ; ;MSH165 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MSH165 ;**-69 .ENDM  ; ; THE DIRECTIVE DISPATCHER IS ASSEMBLED TO USE ONE OF THE FOLLOWING ; DISPATCH TABLE STRUCTURES, DEPENDING UPON WHICH REQUIRES THE LEAST ; AMOUNT OF MEMORY. THE FIRST SCHEME USES A DISPATCH TABLE, DSPTBL, ; THAT CONTAINS 2 WORDS FOR EACH POSSIBLE DIC. THE FORMAT OF EACH ENTRY ; IS: ; .WORD ADDRESS ;ADDRESS OF DIRECTIVE PROCESSING ROUTINE ; ; OR 0 IF DIRECTIVE IS NOT SUPPORTED. ; .BYTE DBPSIZ ;SIZE OF DPB FOR THIS DIRECTIVE OR 0 IF ; ; THIS DIRECTIVE HAS A VAIRABLE LENGTH DPB. ; .BYTE MASK ;CONTROL BITS USED BY THE DISPATCHER. ; ; THE MEMORY USED FOR THIS TABLE IS EQUAL TO THE HIGHEST DIC VALUE ; TIMES 2 MINUS 2 BYTES. ; ; IF THE ABOVE TABLE WOULD BE LESS THAN 3/4 FULL, WE USE THE FOLLOWING ; TWO TABLES FOR DIRECTIVE DISPATCHING. THE FIRST TABLE, BTAB, CONTAINS A ; BYTE FOR EACH POSSIBLE DIC. THE BYTE CONTAINS THE OFFSET INTO THE ; DISPATCH TABLE DSPTBL IF THE DIRECTIVE IS SUPPORTED, OR 0 IF IT IS NOT. ; THE SECOND TABLE, DSPTBL, IS THE SAME FORMAT AS ABOVE, HOWEVER, IT IS ; ONLY REQUIRED TO HAVE ENTRIES FOR THE DIC'S IN USE. THE FIRST ELEMENT IN ; DSPTBL IS 2(DSPTBL) BECAUSE WE USE 0 TO REPRESENT INVALID DIC'S. ; ; THE CONDITIONAL ASSEMBLY PARAMETER BYTTAB IS DEFINED IF THE TWO TABLE ; SCHEME IS USED. ; ; LOCAL SYMBOLS NUMDIR=0 ;NUMBER OF DIC'S IN USE HIDIR=0 ;HIGHEST DIC IN USE ;MSH165 .IF DF D$$PAR ;MSH165 ;MSH165 PAG=1 ;SECOND DIRECTIVE COMMON EXISTS ;MSH165 ;MSH165 .IFF ;MSH165 ;MSH165 PAG=0 ;SECOND DIRECTIVE COMMON DOES NOT EXIST ;MSH165 ;MSH165 .ENDC ;MSH165 ; ;MSH165 ; DIRECTIVE PRE-PROCESSING MASK BITS. ALL UNDEFINED MASK BITS ;MSH165 ; ARE RESERVED BY DIGITAL FOR FUTURE EXPANSION. ;MSH165 ; ;MSH165 ;**-1 DSPNX=2 ;INITIAL DIRECTIVE MAPPING TABLE INDEX N=200 ;INITIAL MASK VALUE DEFINE ACHKDB ;ADDRESS CHECK PLAS DEFINITION BLOCK DEFINE CEFNCL ;BIT SET INDICATES THAT THE NEXT DPB ;MSH165 ; ARGUMENT IS AN EVENT FLAG THAT MUST ;MSH165 ; BE CONVERTED INTO A MASK (R0) AND ;MSH165 ; MASK ADDRESS (R1). ;MSH165 DEFINE GEFUSE ;USED WITH CEFNCL AND HAS MEANING ONLY ;MSH049 ; IF THE EVENT FLAG BEING CONVERTED IS ;MSH049 ; GROUP GLOBAL. ASYNCHRONOUS GGEF USAGE ;MSH049 ; REQUIRES THAT THE FLAGS BE LOCKED FOR ;MSH049 ; THE DIRECTIVE TO PREVENT PREMATURE ;MSH049 ; FLAG ELIMINATION. THIS REVERSE-POLARIT;MSH049 ; BIT, WHEN CLEAR, CAUSES THE FLAGS TO ;MSH049 ; BE LOCKED ON A SUCCESSFUL DIRECTIVE ;MSH049 ; COMPLETION. ;MSH049 DEFINE CEFNMT ;BIT SET INDICATES THAT THE DIRECTIVE ;MSH165 ; REQUIRES AN EVENT FLAG TO BE SPECIFIED;MSH165 ;MSH165 ; THE REMAINING BITS EACH INDICATE, WHEN SET, THAT THE NEXT DPB ;MSH165 ; ARGUMENT IS A RAD50 TASK NAME SPECIFICATION THAT MUST BE ;MSH165 ; VALIDATED. ;MSH165 ;MSH165 DEFINE DFCTSK ;BIT SET INDICATES THAT THE TASK NAME ;MSH165 ; MAY BE DEFAULTED TO THAT OF THE ;MSH165 ; CURRENT TASK. ;MSH165 DEFINE MUPCHK ;BIT SET INDICATES THAT THE DIRECTIVE ;MSH165 ; MUST BE SUBJECTED TO SOME STANDARD ;MSH165 ; MULTIUSER PROTECTION CHECKS. ;MSH165 DEFINE SRSTCL ;NO SPECIAL ACTION. BIT SET INDICATES ;MSH165 ; THAT NEXT ARGUMENT IS A TASK NAME THAT;MSH165 ; MUST BE VALIDATED. ;MSH165 ;MSH165 ;MSH165 ;MSH165 ;**-5 DIREC SIZ ;DETERMINE HIGHEST DIC AND NUMBER OF DIC'S ;IN USE .IF LE NUMDIR- ;IF WE ARE USING LESS THAN ;3/4 OF THE DIC'S, WE WILL BYTTAB=0 ;USE THE TWO TABLE SCHEME .ENDC ; ; LOCAL DATA - ADJACENCY ASSUMED ; USRPS: .BLKW 1 ;POINTER TO USER PS WORD BTRMV: .BLKW 1 ;BYTES TO REMOVE ON EXIT .IF DF BYTTAB BTAB: .BLKB HIDIR/2+1 ;BYTE INDEX TABLE .EVEN .=.-2 DSPTBL: .BLKW NUMDIR*2+1 ;DISPATCH TABLE DSPPTR=2 ;POINTER INTO DISPATCH TABLE .IFF ;BYTTAB DSPTBL: .BLKW HIDIR+1 .ENDC ;BYTTAB $$$=. DIREC GEN ;GENERATE DIRECTIVE DISPATCH TABLE .=$$$ ;+ ; **-$TRTRP-TRAP TRAP ; **-$DRTRP-TRAP TRAP (EXECUTIVE COMMON ENTRY POINT) ;MSH165 ; ; THIS ROUTINE IS TRAPPED TO WHEN A TRAP INSTRUCTION IS EXECUTED. IF THE ; STACK DEPTH IS ZERO, THEN A DIRECTIVE STATUS IS TO BE RETURNED. ELSE ; CONTROL IS TRANSFERED TO THE EMT/TRAP SST HANDLING ROUTINE. ; ; INPUTS: ; ; 2(SP)=PS WORD PUSHED BY TRAP INSTRUCTION. ; 0(SP)=PC WORD PUSHED BY TRAP INSTRUCTION. ; ; OUTPUTS: ; ; IF THE STACK DEPTH IS ZERO, THEN A DIRECTIVE STATUS IS RETURNED. ; ELSE CONTROL IS TRANSFERED TO THE EMT/TRAP SST HANDLING ROUTINE. ;- .ENABL LSB ;MSH165 .IF NDF D$$PAR ;MSH165 ;MSH165 $TRTRP::TST $STKDP ;;;STACK DEPTH ZERO? BNE $EMTRP ;;;IF NE NO MTPS #0 ;;;ALLOW INTERRUPTS MOV (SP),R0 ;GET ADDRESS PLUS 2 OF TRAP INSTRUCTION MOVB -2(R0),R0 ;PICK UP DIRECTIVE STATUS ;MSH100 ;MSH165 .ENDC ;MSH165 ;MSH165 $DRTRP:: ; ;MSH165 ;**-1 .IF DF M$$MGE BIS #PMODE,PS ;SET PREVIOUS MODE TO USER MOV #$STACK-22,SP ;RELOAD EXEC STACK POINTER .IFF MOV #$STACK-12,SP ;RELOAD EXEC STACK POINTER .ENDC MOV R0,-(SP) ;SAVE DIRECTIVE STATUS ;**-1 BPL 259$ ;IF PL OKAY AS IS ;MSH049 INC @USRPS ;SET CARRY IN USER PS WORD ;**-1 JMP 60$ ; ;MSH049 259$: JMP $DRSOK ; ;MSH049 ;**-1 ;+ ; **-$EMTRP-EMT TRAP ; **-$DRDSP-DIRECTIVE DISPATCHER - EMT TRAP (EXECUTIVE COMMON ENTRY PT.);MSH165 ; ; THIS ROUTINE IS TRAPPED TO WHEN AN EMT INSTRUCTION IS EXECUTED. IF THE ; STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED. ELSE A TEST IS ; MADE TO SEE IF THE EMT INSTRUCTION HAD A CODE OF 377. IF NOT, THEN ; CONTROL IS TRANSFERED TO THE EMT/TRAP SST HANDLING ROUTINE. ELSE THE ; APPROPRIATE DIRECTIVE IS EXECUTED. ; ; INPUTS: ; ; 2(SP)=PS WORD PUSHED BY EMT INSTRUCTION. ; 0(SP)=PC WORD PUSHED BY EMT INSTRUCTION. ; ; OUTPUTS: ; ; IF THE STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED. ELSE ; CONTROL IS GIVEN TO THE EMT/TRAP SST ROUTINE OR A DIRECTIVE ROUTINE ; DEPENDENT ON WHETHER THE EMT HAD A CODE OF 377. ;- ;MSH165 .IF NDF D$$PAR ;MSH165 ;MSH165 $EMTRP::DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY TST $STKDP ;WERE WE AT STACK DEPTH +1? BEQ $DRDSP ;IF EQ YES ;MSH165 CRASH ;EMT/TRAP WITH $STKDP NOT +1 ;MSH165 ;MSH165 .ENDC ;MSH165 ;MSH165 $DRDSP::MOV @$HEADR,R3 ;GET SAVED STACK POINTER ;MSH165 CMP (R3)+,(R3)+ ;POINT TO USER PC WORD ;**-2 MOV (R3)+,R5 ;GET ADDRESS OF EMT PLUS 2 .IF DF M$$MGE MFPI -(R5) ;GET DIRECTIVE WORD CMP #104377,(SP) ;DIRECTIVE EMT? BEQ 7$ ;IF EQ YES ;MSH049 JMP 80$ ;CHECK THIS EMT'S VALIDITY ;MSH049 7$: MOV #1,(SP) ;SET SUCCESSFUL DIRECTIVE STATUS ;MSH049 ;**-2 .IFF CMP #104377,-(R5) ;DIRECTIVE EMT? BEQ 7$ ;IF EQ YES ;MSH049 JMP 80$ ;CHECK THIS EMT'S VALIDITY ;MSH049 7$: MOV #1,-(SP) ;SET SUCCESSFUL DIRECTIVE STATUS ;MSH049 ;**-2 .IFTF MOV #USRPS,R5 ;POINT TO LOCAL DATA MOV R3,(R5)+ ;SAVE ADDRESS OF USER PS BIC (SP),(R3)+ ;CLEAR CARRY IN USER PS WORD CLR (R5) ;INDICATE NO BYTES .IFT MFPI SP ;GET USER STACK POINTER MOV (SP)+,R3 ; $DRLM1::MFPI (R3) ;GET FIRST WORD ON USER STACK BIT #1,(SP) ;DPB ON STACK? BNE $DRLM2 ;IF NE YES MOV #2,(R5) ;INDICATE DPB POINTED TO BY STACK MOV (SP),R3 ;SET ADDRESS OF DPB MFPI @(SP)+ ;GET FIRST WORD OF DPB $DRLM2::MOV (SP)+,R1 ;PICK UP FIRST DPB WORD CLR R0 ;EXTRACT DIC CODE BISB R1,R0 ; MOV R1,$DICSV ;SAVE DIC AND DPB SIZE CLRB R1 ;CLEAR DIC BYTE SWAB R1 ;SWAP DPB SIZE TO LOW BYTE .IFF BIT (SP),(R3) ;DPB ON STACK? BNE 10$ ;IF NE YES MOV (R3),R3 ;GET ADDRESS OF DPB MOV #2,(R5) ;INDICATE DPB POINTED TO BY STACK .IF DF A$$CHK CALL $ACHK2 ;ADDRESS CHECK FIRST DPB WORD .ENDC 10$: CLR R0 ;EXTRACT DIC CODE BISB (R3),R0 ; MOV (R3),$DICSV ;SAVE DIC AND DPB SIZE MOVB 1(R3),R1 ;EXTRACT DPB SIZE .ENDC ASL R1 ;CONVERT TO BYTES TO REMOVE AT EXIT MOV R1,R4 ;COPY SIZE CLR -(SP) ;ASSUME ILLEGAL DIC OR DPB SIZE ASR R0 ;DIVIDE CODE BY 2 BCC 35$ ;IF CC ILLEGAL DIC CODE CMP R0,#HIDIR/2 ;LEGAL DIC CODE? ;**-2 BHI 35$ ;IF HI NO .IF DF BYTTAB CLR R2 ;MAP TO DIRECTIVE DISPATCH TABLE BISB BTAB(R0),R2 ; BEQ 35$ ;IF EQ ILLEGAL DIRECTIVE ADD #DSPTBL,R2 ;POINT TO PROPER TABLE ENTRY .IFF ;BYTTAB MOV #DSPTBL,R2 ;MAP TO DIRECTIVE DISPATCH TABLE ASL R0 ASL R0 ADD R0,R2 TST (R2) ;VALID DIRCTIVE? BEQ 35$ ;IF EQ, NO .ENDC ;BYTTAB CMPB R1,2(R2) ;DPB SIZE MATCH? .IF DF VARDPB BEQ 20$ ;IF EQ YES TSTB 2(R2) ;VARIABLE LENGTH DPB? .ENDC ;VARDPB BNE 35$ ;IF NE NO 20$: MOV (R2)+,(SP) ;GET ADDRESS OF DIRECTIVE ROUTINE ;MSH049 BIS (R2),R4 ;PICK UP DIRECTIVE SIZE AND MASK BYTE ;**-2 .IF DF P$$LAS&M$$MGE BPL 35$ ;IF PL NOT A PLAS DIRECTIVE $DPLM1::MFPI 2(R3) ;PICK UP POINTER TO DEFINITION BLOCK $DPLM2::MOV (SP)+,R3 ; MOV #8.*2,R1 ;PICK UP SIZE OF DEFINITION BLOCK .ENDC 35$: ;REFERENCE LABEL .IF DF G$$EFN ;MSH049 ;MSH049 MOV #$GEFDM,$GEFPT ;INIT GRP GLOBAL USE COUNT POINTER ;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 MOV #$GEFDM,$GFTCB ;INIT GRP GLOBAL USER POINTER ;MSH076 ;MSH076 .ENDC ;R$$SND ;MSH076 ;MSH049 .ENDC ;MSH049 .IF DF A$$CHK!M$$MGE CALL $ACHKP ;ADDRESS CHECK AND MAP DEFINITION BLOCK .ENDC TST (R3)+ ;SKIP OVER FIRST DPB WORD TST (R5) ;DPB ON STACK? BNE 36$ ;IF NE NO MOVB R4,(R5) ;SET NUMBER OF BYTES TO REMOVE AT EXIT 36$: CLRB R4 ;CLEAR OUT SIZE BYTE TST (SP) ;LEGAL DIC AND DPB SIZE? BEQ 90$ ;IF EQ NO MOV $TKTCB,R5 ;PICK UP CURRENT TASK TCB ASL R4 ;PLAS DIRECTIVE? ;MSH049 ;**-1 .IF DF P$$LAS BCC 37$ ;IF CC NOT A PLAS DIRECTIVE TST -(R3) ;POINT BACK TO FIRST WORD OF BLOCK BIC #WS.CRW!WS.UNM!WS.ELW!WS.RRF,W.NSTS(R3) ;INIT OUTPUTS 37$: ;REFERENCE LABEL .ENDC ASL R4 ;CALL $CEFN OR $CEFNG? ;MSH049 BCC 40$ ;IF CC NO ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 BMI 38$ ;IF MI DON'T INCREMENT GRP GBL USE COUNT;MSH049 CALL $CEFNG ;CONVERT EFN AND LOCK IF GROUP GLOBAL ;MSH049 BR 39$ ;JOIN COMMON CODE ;MSH049 38$: ;MSH049 .IFTF ;MSH049 ;MSH049 CALL $CEFN ;CONVERT EVENT FLAG NUMBER ;**-1 ;MSH049 .IFT ;MSH049 ;MSH049 BIC #1,R1 ;CLR GROUP GLOBAL 2ND MASK INDICATOR ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 39$: BCC 50$ ;IF CC EVENT FLAG SPECIFIED ;MSH049 40$: ASL R4 ;EVENT FLAG REQUIRED? ;**-1 BEQ 50$ ;IF EQ NO BMI 100$ ;IF MI EVENT FLAG WAS REQUIRED .IF DF A$$PRI!M$$MUP!S$$TOP ;MSH180 ;**-1 ASL R4 ;TASK NAME DEFAULT TO CURRENT TASK? BPL 45$ ;IF PL NO MOV R5,R0 ;PICK UP CURRENT TASK TCB TST (R3) ;TASK NAME SPECIFIED? BEQ 46$ ;IF EQ NO .ENDC 45$: CALL $SRSTD ;SEARCH STD FOR TASK NAME BCS 110$ ;IF CS NAME NOT FOUND 46$: CMP (R3)+,(R3)+ ;ADVANCE PAST TASK NAME .IF DF M$$MUP ASL R4 ;PERFORM MULTI-USER PROTECTION CHECK? BPL 47$ ;IF PL NO BIT #T3.PRV,T.ST3(R5) ;ISSUING TASK PRIVILEGED? BNE 47$ ;IF NE YES BIT #T3.SLV,T.ST3(R0) ;TARGET TASK A SLAVE TASK? BNE 120$ ;IF NE YES, DON'T ALLOW CMP T.UCB(R5),T.UCB(R0) ;CURRENT AND TARGET TASK UCBS MATCH? BNE 120$ ;IF NE NO .ENDC 47$: MOV R0,R1 ;COPY TCB ADDRESS ADD #T.STAT,R1 ;POINT TO TASK STATUS WORD 50$: MOV R5,R2 ;SET POINTER TO SECOND TASK STATUS WORD ADD #T.ST2,R2 ; MOV $HEADR,R4 ;POINT TO CURRENT TASK HEADER ; ;MSH045 ; THE DIRECTIVE PROCESSING ROUTINE MAY RESIDE IN ONE OF THREE PLACES, ;MSH045 ; THE MAIN BODY OF THE EXECUTIVE, OR ONE OF THE TWO EXTERNAL EXECUTIVE ;MSH045 ; COMMONS, IF SUPPORTED. IT IS ASSUMED THAT THE DIRECTIVE IS IN EITHER ;MSH045 ; THE RESIDENT EXECUTIVE OR IN THE FIRST EXEC COMMON. IF IT ISN'T, THE ;MSH045 ; ODD BIT OF THE ROUTINE ADDRESS IN (SP) IS SET. THE FOLLOWING CODE ;MSH045 ; DETECTS THAT AND REMAPS KERNEL APR5 TO THE SECOND COMMON IF ;MSH045 ; NECESSARY. ;MSH045 ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 ASR (SP) ;DIRECTIVE IN SECOND EXTERNAL COMMON? ;MSH165 BCC 58$ ;IF CC NO ;MSH165 CALLR $OTHR1 ;CALL DIRECTIVE ROUTINE W/ARGS BELOW ;MSH165 ;MSH165 58$: ASL (SP) ;RESTORE TO BYTE ADDRESS ;MSH165 ;MSH045 .ENDC ;MSH045 ; ; CALL DIRECTIVE ROUTINE WITH THE FOLLOWING ARGUMENTS: ; ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK.  ; R3=ADDRESS OF THE NEXT WORD IN THE DIRECTIVE DPB. ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R1=DEPENDENT ON DIRECTIVE. ; R0=DEPENDENT ON DIRECTIVE. ; CALL @(SP)+ ;CALL DIRECTIVE ROUTINE ;MSH049 ; ;MSH049 ; IF THE SPECIFIED DIRECTIVE CAUSES AN ASYNCHRONOUS UTILIZATION OF ;MSH049 ; AN EVENT FLAG TO BEGIN AND THAT EVENT FLAG IS A GROUP GLOBAL EVENT ;MSH049 ; FLAG, THEN THE USE COUNT FOR THE FLAG IS INCREMENTED HERE BECAUSE ;MSH049 ; IT IS KNOWN THAT THE DIRECTIVE SUCCEEDED. THIS PREVENTS ELIMINATION ;MSH049 ; OF THE EVENT FLAGS BEFORE THAT ASYNCHRONOUS UTILIZATION COMPLETES. ;MSH049 ; ;MSH049 ;MSH049 $DRSOK:: ; ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 INC @$GEFPT ;INCREMENT GROUP GLOBAL USE COUNT ;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 INCB @$GFTCB ;INC GRP GLOBAL USE COUNT FOR TASK ;MSH076 ;MSH076 .ENDC ;R$$SND ;MSH076 ;MSH049 .ENDC ;MSH049 ;MSH049 ; ;MSH049 ; RETURN THE DIRECTIVE'S COMPLETION STATUS TO THE DIRECTIVE STATUS ;MSH049 ; WORD IN THE ISSUING TASK'S HEADER AND CLEAN UP THE TASK'S STACK. ;MSH049 ; ;MSH049 ;MSH049 60$: ;REF LABEL .IF DF M$$MGE MTPI @#H.DSW ;SET DIRECTIVE STATUS WORD MFPI SP ;GET USER STACK POINTER ADD BTRMV,(SP) ;REMOVE BYTES FROM USER STACK MTPI SP ;RESTORE USER STACK POINTER .IFF MOV (SP)+,@.DSW ;SET DIRECTIVE STATUS WORD MOV $HEADR,R0 ;GET ADDRESS OF TASK HEADER BEQ 65$ ;IF EQ TASK TERMINATED MOV (R0),R0 ;GET TASK STACK POINTER ADD #8.,R0 ;POINT TO FIRST STACK WORD MOV R0,R1 ;COPY ADDRESS ADD BTRMV,R1 ;POINT TO NEW TOP OF USER STACK MOV -(R0),-(R1) ;MOVE RETURN PS WORD MOV -(R0),-(R1) ;MOVE RETURN PC WORD MOV -(R0),-(R1) ;MOVE SAVED R5 MOV -(R0),-(R1) ;MOVE SAVED R4 MOV R1,@$HEADR ;SET NEW STACK POINTER .ENDC ;**-8 65$: RETURN ;EXIT FROM TRAP ; ;**-6 ; EMT/TRAP SST ROUTINE TRANSFER ; 80$: ;REF LABEL .IF DF M$$MGE MOV $HEADR,R5 ;POINT TO CURRENT TASK HEADER MOV H.WND(R5),R5 ;POINT TO NUMBER OF WINDOW BLOCKS TST W.BLVR+2(R5) ;CURRENT TASK MAPPED TO EXEC? BEQ 85$ ;IF EQ NO CMP (SP),#104376 ;IS THIS A CALL TO $SWSTK? .IFF CMP (R5),#104376 ;IS THIS A CALL TO $SWSTK? .ENDC BNE 85$ ;IF NE NO JMP $SWSTK ;PROCESS CALL TO $SWSTK 85$: JMP $EMSST ;PROCESS SST FAULT ; ; ILLEGAL DIRECTIVE ; 90$: DRSTS D.RS99 ;SET DIRECTIVVE STATUS ; ; REQUIRED EVENT FLAG NUMBER NOT SPECIFIED ; 100$: DRSTS D.RS97 ;SET DIRECTIVE STATUS ; ; SPECIFIED TASK NAME NOT FOUND IN TASK DIRECTORY ; 110$: DRSTS D.RS2 ;SET DIRECTIVE STATUS ; ; PRIVILEGE VIOLATION ; .IF DF M$$MUP 120$: DRSTS D.RS16 ;SET DIRECTIVE STATUS .ENDC .DSABL LSB .END V»zðkQ ›c, .TITLE SYSDF .IDENT /09.10/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 09.10 ; ; D. N. CUTLER 23-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; P. WANNHEDEN ; J. PROVINO ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 11-SEP-79 ; MSH053 -- DEFINE NEW SYMBOLS FOR EXTK$ DIRECTIVE: ; D.RS18 - NO SWAP SPACE AVAILABLE ; D.RS83 - WINDOW HAS I/O IN PROGRESS ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 9-MAY-80 ; MSH099 -- GET FILES-11 BLOCK OFFSETS AND UCB OFFSETS ; ; DAN BROWN 7-JAN-81 ; DTB002 -- DEFINE NEW MEANING OF D.RS8 ; ; M. S. HARVEY 27-JAN-81 ; MSH145 -- DEFINE SYMBOL INDICATING BASELINE STATUS ; ; M. S. FOX 13-FEB-81 ; MF207 -- ADD D.RS89 FOR SDRP$ ; ; M. S. HARVEY 30-APR-81 ; MSH156 -- DEFINE K$$W11 GLOBALLY ; ; SYSTEM GLOBAL AND CONTROL BLOCK OFFSET DEFINITIONS ; ; GLOBALLY DEFINE THE HIGHEST VECTOR ADDRESS ; .GLOBL V$$CTR ; ; DEFINE SYSTEM DEPENDENT CONTROL BLOCK OFFSETS AND LENGTHS GLOBALLY ; .MCALL ITBDF$,PCBDF$,PKTDF$,SCBDF$,TCBDF$,HWDDF$,F11DF$ ;MSH099 .MCALL UCBDF$ ;MSH099 UCBDF$ <:>,,,SYSDEF ;DEFINE UCB OFFSETS ;MSH099 F11DF$ <:>,<=>,SYSDEF ;DEFINE FILES-11 OFFSETS ;MSH099 ITBDF$ <:>,<=>,SYSDEF ;DEFINE ITB OFFSETS AND LENGTH ;**-1 PCBDF$ <:>,<=>,SYSDEF ;DEFINE PCB OFFSETS AND LENGTH SCBDF$ <:>,,SYSDEF ;DEFINE SCB OFFSETS TCBDF$ <:>,<=>,SYSDEF ;DEFINE TCB OFFSETS HWDDF$ ,<=> ;DEFINE HARDWARE OFFSETS ; ; CAUSE OFFSET DEFINITIONS FROM PREFIX FILES TO BE LISTED ; S$$YDF=0 ; ; SYSTEM GLOBAL SYMBOL DEFINITIONS ; ; DIRECTIVE STATUS CODES ; ; INSUFFICIENT DYNAMIC CORE AVAILABLE TO SATISFY REQUEST ; D.RS1==-1. ; ; ; SPECIFIED TASK NOT INSTALLED IN THE SYSTEM ; D.RS2==-2. ;  ; ; UNASSIGNED LUN ; D.RS5==-5. ; ; ; DRIVER NOT LOADED ; D.RS6==-6. ; ; ; TASK NOT ACTIVE ; D.RS7==-7. ; ; ; TASK NOT SUSPENDED/NO DATA QUEUED/TASK CHECKPOINTING ALREADY ENABLED ; OR DISABLED/AST RECOGNITION ALREADY ENABLED OR DISABLED/AST ENTRY ALREADY ; UNSPECIFIED/ILLEGAL SMSG$ TARGET ;DTB002 ; ;**-1 D.RS8==-8. ; ; ; ISSUING TASK NOT CHECKPOINTABLE ; D.RS10==-10. ; ; ; PRIVILEGE VIOLATION ; D.RS16==-16. ; ; ; VECTOR ALREADY IN USE (CINT$) / GROUP GLOBAL EVENT FLAGS IN USE ;MSH076 ; ;**-1 D.RS17==-17. ;MSH053 ; ;MSH053 ; NO SWAP SPACE AVAILABLE, OR TASK HAS PREALLOCATED CHECKPOINT SPACE ;MSH053 ; AND IS ATTEMPTING TO EXTEND TO GREATER THAN INSTALLED SIZE (EXTK$) ;MSH053 ; ;MSH053 ;MSH053 D.RS18==-18. ;MSH053 ; ; ILLEGAL VECTOR (CINT$) ; D.RS19==-19. ; ; DIRECTIVE ISSUED/NOT ISSUED FROM AST ROUTINE ; D.RS80==-80. ; ; ; CANNOT MAP ISR OR DISABLE-INTERRUPT ROUTINE (CINT$) ; D.RS81==-81. ;MSH053 ; ;MSH053 ; WINDOW HAS I/O IN PROGRESS, OR TASK HAS I/O IN PROGRESS (EXTK$) ;MSH053 ; ;MSH053 ;MSH053 D.RS83==-83. ;MSH053 ; ; ALIGNMENT ERROR ; D.RS84==-84. ; ; ; ADDRESS WINDOW OVERFLOW ; D.RS85==-85. ; ; ; INVALID REGION ID ; D.RS86==-86. ; ; ; INVALID WINDOW ID ; D.RS87==-87. ; ; MF207 ; ; MF207 ; ILLEGAL SEND BUFFER LENGTH ; MF207 ; ; MF207 ; MF207 D.RS89==-89. ; MF207 ; ; SPECIFIED LUN IS LOCKED IN USE. ; D.RS90==-90. ; ; ; INVALID UIC ; D.RS91==-91. ; ; ; INVALID DEVICE AND/OR UNIT SPECIFIED. ; D.RS92==-92. ; ; ; INVALID TIME PARAMETER ; D.RS93==-93. ; ; ; PARTITION/REGION NOT IN SYSTEM ; D.RS94==-94. ; ; ; INVALID PRIORITY ; D.RS95==-95. ; ; ; INVALID LUN ; D.RS96==-96. ; ; ; INVALID EFN OR REQUIRED EFN NOT SPECIFIED ; D.RS97==-97. ; ; ; PART OF DPB IS OUTSIDE OF ISSUING TASK'S ADDRESS SPACE ; D.RS98==-98. ; ; ; INVALID DIC OR DPB SIZE ; D.RS99==-99. ; ; ; EFN WAS SET ; D.RS22==2. ; ; ; EFN WAS CLEAR ; D.RS00==0. ; ; ; IF DYNAMIC ALLOCATION IS PRESENT DEFINE D$$YNM GLOBALLY ; .IIF DF D$$YNM , D$$YNM==0 ; ; ; IF 11/70 EXTENDED MEMORY IS PRESENT DEFINE M$$EXT GLOBALLY ; .IIF DF M$$EXT , M$$EXT==0 ; ; ; IF MEMORY MANAGEMENT IS PRESENT DEFINE M$$MGE GLOBALLY ; .IIF DF M$$MGE , M$$MGE==0 ; ; ;**-1 ; IF SEND / RECEIVE BY REFERENCE SUPPORTED, DEFINE P$$SRF GLOBALLY ; .IIF DF P$$SRF , P$$SRF==P$$SRF ; ;MSH145 ; DEFINE THE BASELINE STATUS OF THIS SYSTEM ;MSH145 ; ;MSH145 ;MSH145 .IF DF B$$LIN ;MSH145 ;MSH145 $BASLN==1 ;THE SYSTEM IS A BASELINE SYSTEM ;MSH145 ;MSH145 .IFF ;MSH145 ;MSH145 $BASLN==0 ;THE SYSTEM IS NOT A BASELINE SYSTEM ;MSH145 ;MSH145 .ENDC ;MSH145 œ ;MSH145 ; ;MSH156 ; DEFINE K$$W11 GLOBALLY FOR PRIVILEGED TASKS ;MSH156 ; ;MSH156 ;MSH156 .IF DF K$$W11 ;MSH156 ;MSH156 K$$W11==K$$W11 ;DEFINE WATCHDOG CSR GLOBALLY ;MSH156 ;MSH156 .IFF ;MSH156 ;MSH156 K$$W11==-1 ;DEFINE SYMBOL FOR REFERENCE ONLY ;MSH156 ;MSH156 .ENDC ;MSH156 ;MSH156 .END œÕ09kQ ›c, .TITLE DREIF .IDENT /16.37/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 16.37 ; ; D. N. CUTLER 13-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 23-JUL-79 ; MSH008 -- CLEAR TCB ADDRESS FROM ALL RREF PACKETS ; ; M. S. HARVEY 25-JUL-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 20-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 11-SEP-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT ; ; M. S. HARVEY 8-OCT-79 ; MSH021 -- CONDITIONALIZE ACP TEST ; ; M. S. HARVEY 29-AUG-80 ; MSH091 -- UPDATE KERNEL AST SUPPORT ; ; M. S. HARVEY 29-AUG-80 ; MSH103 -- ALWAYS QUEUE REMOVE COMMAND TO MCR ; ; M. S. HARVEY 12-SEP-80 ; MSH115 -- CLEANUP GROUP GLOBAL USE FOR ABORTED TASKS ; ; M. S. HARVEY 12-SEP-80 ; MSH116 -- FIX BUG LEAVING TASKS IN I/O RUNDOWN STATE ; ; M. S. HARVEY 8-OCT-80 ; MSH121 -- CLEAN UP ABORT ASTS FOR EXITING TASKS ; ; M. S. HARVEY 24-NOV-80 ; MSH129 -- PASS SECONDARY EXIT CODE TO PARENT TASK ; ; M. S. FOX 07-JAN-81 ; MF203 -- INITIAL ALTERNATE CLI SUPPORT ; ; M. S. HARVEY 12-FEB-81 ; MSH148 -- UNLOCK GROUP GLOBAL EVENT FLAGS ON EXIT ; ; M. S. FOX 11-MAR-81 ; MF211 -- IFDF A$$CLI, SEND 6 BYTE PACKET FOR PROMPT ; ; M. S. HARVEY 5-MAY-81 ; MSH165 -- ENSURE CORRECT EXECUTIVE COMMON MAPPING ; ; M. S. HARVEY 10-JUN-81 ; MSH174 -- FORCIBLY DEACCESS TASK FROM GROUP GLOBALS ; IN CASE ABORTED BECAUSE OF CHECKPOINT READ ; FAILURE WHERE THE HEADER MAY BE GARBAGE ; ; M. S. HARVEY 29-JUL-81 ; MSH183 -- ADD SUPPORT FOR GROUP GLOBAL RUNDOWN FROM ; RECEIVE-BY-REFERENCE PACKETS ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 13-OCT-81 ; MSH196 -- MOVE FORMER $CLSRF SUBROUTINE DIRECTLY ; INTO EXIT PROCESSING CODE PATH. THIS ; SWALLOWS UP MSH008. $CLSRF WAS ORIGINALLY ; LOCATED IN MODULE REQSB. ; ; M. S. HARVEY 20-OCT-81 ; MSH197 -- MAKE SURE THAT ANY ASTS QUEUED DURING ; I/O RUNDOWN ARE CLEANED UP ; ; EXIT DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,CLKDF$,HDRDF$,PCBDF$,PKTDF$,TCBDF$ CLKDF$ ;DEFINE CLOCK BLOCK OFFSETS ABODF$ ;DEFINE TASK ABORT CODES HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; LOCAL SYMBOL DEFINITION ; CLRMSK=T2.AST!T2.DST!T2.CKD!T2.HLT!T2.ABO!T2.CAF!T2.REX ;MSH121 CLRMSK=CLRMSK!<*2>!T2.STP!T2.SPN!T2.WFR ;**-1 ;+ ; **-$DREIF-EXIT IF ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF THE ; ISSUING TASK IF, AND ONLY IF, AN INDICATED EVENT FLAG IS CLEAR. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(53.),DPB SIZE(2.). ; WD. 01 -- EVENT FLAG NUMBER OF EVENT FLAG THAT MUST BE CLEAR. ; ; INPUTS: ; ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF 'D.RS22' IS RETURNED IF THE SPECIFIED ; EVENT FLAG IS SET. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS97' IF NO OR AN INVALID EVENT ; FLAG NUMBER IS SPECIFIED. ;- $DREIF::BIT R0,(R1) ;EVENT FLAG CLEAR? BEQ $DREXT ;IF EQ YES DRSTS D.RS22 ;SET DIRECTIVE STATUS ;+ ; **-$DREXT-EXIT ; ;**-1 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO TERMINATE THE EXECUTION OF THE ; ISSUING TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(51.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; NOTE: $DREXT IS ALSO JUMPED TO FROM PRIVILEGED TASKS DIRECTLY. ;MSH129 ; IN THIS CASE, ONLY R5 IS REQUIRED TO BE LOADED AS ;MSH129 ; DESCRIBED ABOVE. ALSO, ON SYSTEMS SUPPORTING THE ;MSH165 ; EXECUTIVE COMMONS, THIS MEANS THAT KERNEL APR5 ;MSH165 ; CANNOT BE ASSUMED TO BE MAPPED TO THE DIRECTIVE ;MSH165 ; DISPATCHER IN THE FIRST COMMON AT $DREXT. ;MSH165 ;  ;MSH174 ; SPECIAL NOTE: THIS ROUTINE IS ENTERED DIRECTLY WHEN A TASK ;MSH174 ; IS ABORTED AND ASSUMES THAT THE TASK HEADER IN ;MSH174 ; POOL IS INTACT. IF NOT, GROUP GLOBAL CONTEXT AND ;MSH174 ; FILE RESOURCE CLEANUP CANNOT BE DONE CORRECTLY. ;MSH174 ; THIS CAN ONLY HAPPEN AFTER A CHECKPOINT READ FAILURE, ;MSH174 ; WHICH IS HARDWARE RELATED. UNEXPECTED SYSTEM BEHAVIOR ;MSH174 ; MAY OCCUR IN THIS CASE. ;MSH174 ; ;**-2 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; NO STATUS IS RETURNED TO THE ISSUING TASK SINCE THIS DIRECTIVE ; TERMINATES ITS EXECUTION. ;- $DREXT:: ;REFERENCE LABEL .IF DF P$$OFF .IF DF A$$CPS ;MSH021 ;MSH021 BIT #T3.ACP,T.ST3(R5) ;IS TASK AN ACP? BNE $DREX1 ;IF NE YES ;MSH115 ;MSH021 .ENDC ;MSH021 ;MSH021 MOV #EX$SUC,T.EFLG+2(R5) ;SET SUCCESSFUL EXIT STATUS ;**-1 $DREX2::MOV #S.CEXT,T.EFLG(R5) ;SET 'TASK EXIT' SECONDARY EXIT CODE ;MSH129 ;**-1 .ENDC ;P$$OFF $DREX1:: ;REF LABEL ;MSH115 ;MSH115 .IF DF G$$EFN MOV $HEADR,R4 ;GET TASK HEADER ADDRESS ;MSH115 BIT #T2.WFR*2,T.ST2(R5) ;WAS TASK IN PRE-AST WAITFOR? ;MSH115 BEQ 55$ ;IF EQ NO ;MSH115 MOV H.EFSV(R4),R3 ;GET EVENT FLAG MASK ADDRESS ;MSH049 CALL $DEAGF ;DEACCESS GROUP GLOBAL EVENT FLAGS ;**-5 BIC #T2.WFR*2,T.ST2(R5) ;DEACCESS PRE-AST WFR ONLY ONCE ;MSH115 55$: ; ;MSH115 .IF DF D$$PAR ;MSH045 ;MSH045 MOV $XCOM2,KISAR5 ;MAP SECOND EXECUTIVE COMMON ;MSH165 ;MSH045 .ENDC ;MSH045 ;MSH045 CALL $UNLCK ;UNLOCK GROUP GLOBAL EVENT FLAGS ;MSH148 BCS 57$ ;IF CS ALREADY UNLOCKED ;MSH148 CALL $ELIM ;ELIMINATE THEM IF NECESSARY ;MSH148 57$: MOV $TKTCB,R5 ;RESTORE TCB POINTER ;MSH148 ;MSH148 .ENDC ;MSH148 ;MSH165 .IF DF D$$PAR ;MSH165 ;MSH165 CLR R4 ;SET TYPE OF REQUEST TO REMOVE ;MSH165 CALL $CLRMV ;CANCEL MARK TIME REQUESTS ;MSH165 ;MSH165 .IFF ;MSH165 ;MSH045 CALL $DRCMT ;CANCEL MARK TIME REQUESTS ;MSH045 ;MSH165 .ENDC ;MSH165 ;**-4 .IF DF C$$INT BIT #T2.CKD,T.ST2(R5) ;DOES TASK POSSIBLY HAVE ANY ITB'S? BEQ 2$ ;IF EQ NO ;MSH165 .IF DF D$$PAR ;MSH165 .IF NDF G$$EFN ;MSH165 ;MSH165 MOV $XCOM2,KISAR5 ;MAP 2ND EXEC COMMON ;MSH165 ;MSH165 .ENDC ;MSH165 .ENDC ;MSH165 ;MSH165 1$: MOV T.CPCB(R5),R1 ;PICK UP NEXT ITB POINTER BEQ 2$ ;IF EQ NONE LEFT CALL $DISIN ;DISCONNECT INTERRUPT VECTOR BR 1$ ; 2$: ;REF LABEL .ENDC .IF DF M$$CRX .IF DF D$$PAR ;MSH165 ;MSH165 MOV $XCOM1,KISAR5 ;ESTABLISH 1ST EXEC COMMON MAPPING ;MSH165 ;MSH165 .ENDC ;MSH165 ;MSH165 .IF DF A$$CLI ; MF203 ; MF203 BIT #T3.CLI,T.ST3(R5) ;IS TASK A CLI ; MF203 BEQ 205$ ;IF EQ NO ; MF203 CALL $RLCIB ;RELEASE CLI COMMAND BUFFERS ; MF203 BR 207$ ; ; MF203  ; MF203 .ENDC ; MF203 ; MF203 ; MF203 205$: CALL $RLMCB ;RELEASE MCR COMMAND BUFFER ; MF203 207$: ;REFERENCE LABEL ; MF203 ;**-1 .ENDC CMP R5,$LSTLK ;TASK OWN MCR DATA BASE LOCK? BNE 3$ ;IF NE NO CLR $LSTLK ;CLEAR OWNER TCB ADDRESS 3$: BIS #T2.HLT,T.ST2(R5) ;SET TO HALT TASK CLRB $CXDBL ;MAKE SURE CONTEXT SWITCHING ENABLED .IF DF F$$LPP!P$$RFL!R$$SND!P$$SRF!A$$BRT&A$$TRP ;MSH121 ;**-1 MOV T.SAST(R5),R0 ;GET ADDRESS OF SPEC AST BLOCK BEQ 35$ ;IF EQ LIST IS EMPTY MOV R0,@T.ASTL+2(R5) ;LINK BLOCK TO NORMAL AST LIST 32$: MOV R0,R1 ;SAVE ADDRESS OF SPEC AST BLOCK MOV (R0),R0 ;GET NEXT BLOCK BNE 32$ ;IF NE MORE BLOCKS IN LIST MOV R1,T.ASTL+2(R5) ;FIX UP LAST POINTER IN LISTHEAD CLR T.SAST(R5) ;NO MORE SPEC ASTS 35$: ;REF LABEL .ENDC ;MSH121 ;**-1 .IF DF K$$AST!A$$TRP ;MSH091 ;**-1 JSR R5,MTQUE ;EMPTY AST QUEUE .WORD T.ASTL ;OFFSET TO AST QUEUE LISTHEAD .WORD $DEACB ;ADDRESS OF DEALLOCATION ROUTINE .ENDC .IF DF R$$SND BIT #T3.NSD!T3.ACP,T.ST3(R5) ;FLUSH RECEIVE QUEUE? BNE 4$ ;IF NE NO JSR R5,MTQUE ;EMPTY RECEIVE QUEUE .WORD T.RCVL ;OFFSET TO RECEIVE QUEUE LISTHEAD .WORD $DEPKT ;ADDRESS OF DEALLOCATION ROUTINE 4$: ;REF LABEL .ENDC .IF DF P$$LAS&P$$SRF .IF DF G$$EFN ;MSH049 ;MSH049 MOV $HEADR,R4 ;GET CURRENT TASK HEADER ADDRESS ;MSH049 ;MSH049 .ENDC ;G$$EFN ;MSH049 ;MSH196 ; CLEAR CURRENT TCB FROM ALL UNRECEIVED SEND-BY-REFERENCE PACKETS ;MSH196 ;MSH196 MOV $TSKHD,R1 ;GET FIRST TCB IN ATL ;MSH196 410$: TSTB T.SRCT(R5) ;ANY UNRECEIVED SREF PACKETS? ;MSH196 BEQ 440$ ;IF EQ NO ;MSH196 MOV T.TCBL(R1),-(SP) ;END OF LIST? ;MSH196 BEQ 430$ ;IF EQ YES ;MSH196 ADD #T.RRFL,R1 ;POINT TO RECEIVE BY REFERENCE LIST ;MSH196 420$: MOV (R1),R1 ;GET NEXT REC BY REF PACKET ;MSH196 BEQ 430$ ;IF EQ END OF LIST ;MSH196 CMP 2(R1),R5 ;DOES IT POINT TO EXITING TASK? ;MSH196 BNE 420$ ;IF NE NO ;MSH196 DECB T.SRCT(R5) ;DECREMENT UNRECEIVED SREF COUNT ;MSH196 ;MSH196 .IF DF G$$EFN ;MSH196 ;MSH196 MOV R1,-(SP) ;SAVE PACKET ADDRESS ;MSH196 MOV 6(R1),R3 ;GET EVENT FLAG MASK ADDRESS ;MSH196 CALL $DEAGF ;DEACCESS IF GROUP GLOBAL ;MSH196 MOV (SP)+,R1 ;RESTORE PACKET ADDRESS ;MSH196 ;MSH196 .ENDC ;MSH196 ;MSH196 MOV R1,R3 ;COPY PACKET ADDRESS ;MSH196 TST (R3)+ ;POINT TO SENDER TCB POINTER ;MSH196 CLR (R3)+ ;CLEAR POINTER TO EXITING TASK ;MSH196 MOV T.NAM(R5),(R3)+ ;STORE SENDER TASK NAME ;MSH196 MOV T.NAM+2(R5),(R3) ; ;MSH196 BR 420$ ;GO AGAIN ;MSH196 430$: MOV (SP)+,R1 ;GET ADDRESS OF NEXT TCB IN LIST ;MSH196 BNE 410$ ;IF NE, NOT NULL TASK ;MSH196 ;MSH196 440$: JSR R5,MTQUE ;EMPTY RECEIVE BY REFERENCE QUEUE ;MSH196 .WORD T.RRFL ;OFFSET TO RECEIVE BY REF LISTHEAD ;**-1 .WORD $DEPKT ;ADDRESS OF DEALLOCATION ROUTINE .ENDC .IF DF D$$PAR  ;MSH165 ;MSH165 MOV $XCOM1,KISAR5 ;MAP DISPATCHER RETURN ADDRESS ;MSH165 ;MSH165 .ENDC ;MSH165 .IF DF I$$RAR!I$$RDN!M$$MGE 5$: MOV #SCNLN,-(SP) ;SET ADDRESS OF LUT SCANNING CO-ROUTINE TSTB T.IOC(R5) ;ANY I/O OUTSTANDING? .IF DF T$$BUF BNE 6$ ;IF NE YES TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O? ;MSH046 ;**-1 .ENDC BEQ 30$ ;IF EQ NO 6$: BIT #T2.ABO,T.ST2(R5) ;TASK ALREADY MARKED FOR ABORT? BNE 10$ ;IF NE YES MOV #S.IOMG,R0 ;SET REASON FOR ABORT CALL $ABCTK ;ABORT CURRENT TASK 10$: MOV (SP),-(SP) ;DUPLICATE ADDRESS OF LUT SCANNING CO-ROUTINE 20$: CALL @(SP)+ ;GET NEXT ASSIGNED LUN BCS 30$ ;IF CS END OF LOGICAL UNIT TABLE CALL $IOKIL ;KILL I/O ON UNIT FOR CURRENT TASK BR 20$ ;GO AGAIN 30$: CALL @(SP)+ ;GET NEXT ASSIGNED LUN BCS 100$ ;IF CS END OF LOGICAL UNIT TABLE CMP $TKTCB,U.ATT(R5) ;UNIT ATTACHED TO CURRENT TASK? BNE 40$ ;IF NE NO MOV #IO.DET,R4 ;SET DETACH I/O FUNCTION BR 50$ ; 40$: MOV (R1),R2 ;FILE OPEN ON UNIT? BEQ 30$ ;IF EQ NO ASR R2 ;ACCESS OR DEACCESS PENDING? BCS 30$ ;IF CS YES MOV #IO.CLN,R4 ;SET CLOSE LUN I/O FUNCTION 50$: CMP (SP)+,(SP)+ ;CLEAN STACK MOV R1,-(SP) ;SAVE ADDRESS OF SECOND LUN WORD MOV #I.LGTH,R1 ;SET LENGTH OF BLOCK NEEDED CALL $ALOCB ;ALLOCATE I/O PACKET MOV (SP)+,R3 ;RETRIEVE ADDRESS OF SECOND LUN WORD BCS 90$ ;IF CS NO CORE AVAILABLE MOV R0,R1 ;COPY ADDRESS OF I/O PACKET TST (R0)+ ;POINT TO SECOND WORD MOV $TKTCB,R2 ;GET ADDRESS OF TCB OF CURRENT TASK MOVB T.IOC(R2),-(SP) ;SAVE CURRENT I/O COUNT INCB T.IOC(R2) ;INCREMENT OUTSTANDING I/O COUNT MOVB T.PRI(R2),(R0)+ ;SET REQUEST PRIORITY CLRB (R0)+ ;CLEAR EVENT FLAG NUMBER MOV R2,(R0)+ ;INSERT CURRENT TASK TCB ADDRESS MOV R3,(R0)+ ;INSERT ADDRESS OF SECOND LUN WORD MOV R5,(R0)+ ;INSERT UCB ADDRESS MOV R4,(R0)+ ;INSERT I/O FUNCTION CODE CMP #IO.CLN,R4 ;CLOSE LUN I/O FUNCTION? BNE 60$ ;IF NE NO INC @U.VCB(R5) ;INCREMENT VOLUME TRANSACTION COUNT INC (R3) ;INTERLOCK LUN USAGE 60$: MOV #/2,R2 ;SET LOOP COUNT ;MSH046 70$: CLR (R0)+ ;CLEAR REMAINDER OF I/O PACKET ;**-1 DEC R2 ;ANY MORE TO CLEAR? BGT 70$ ;IF GT YES CALL $DRQRQ ;QUEUE I/O REQUEST MOV $TKTCB,R5 ;GET ADDRESS OF TCB OF CURRENT TASK CMPB T.IOC(R5),(SP)+ ;REQUEST ALREADY FINISHED? BLOS 5$ ;IF LOS YES ;MSH116 80$: BIS #TS.RDN,T.STAT(R5) ;SET I/O RUNDOWN IN PROGRESS ;**-1 90$: CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 100$: TSTB T.IOC(R5) ;ANY I/O STILL OUTSTANDING? BNE 80$ ;IF NE YES .IF DF T$$BUF TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O? ;MSH046 BNE 80$ ;IF NE YES ;**-1 .ENDC ;MSH197 .IF DF A$$TRP!K$$AST ;MSH197 ;MSH197 TST T.ASTL(R5) ;ASTS DECLARED DURING I/O RUNDOWN? ;MSH197 BEQ 91$ ;IF EQ NO, CONTINUE EXIT PROCESSING ;MSH197 RETURN ;RESCHEDULE CURRENT TASK ($SETCR CALLED);MSH197 ;MSH197 .ENDC ;MSH197 .ENDC 91$: MOV $HEADR,R4 ;GET ADDRESS OF CURRENT TASK HEADER ;MSH197 ;MSH197 .IF DF P$$OFF MOV $TSKHD,R0 ;POINT TO FIRST INSTALLED TASK TCB 92$: TST T.RDCT(R5) ;ANY RUNDOWN OPERATIONS REMAINING? BEQ 98$ ;IF EQ NO MOV T.TCBL(R0),-(SP) ;SAVE POINTER TO NEXT INSTALLED TASK BEQ 96$ ;IF EQ CURRENT TASK IS NULL TASK ADD #T.OCBH,R0 ;POINT TO OCB QUEUE OF TASK 94$: MOV (R0),R0 ;POINT TO NEXT ENTRY IN LIST BEQ 96$ ;IF EQ THERE IS NONE CMP O.PTCB(R0),R5 ;IS EXITING TASK THE PARENT? BNE 94$ ;IF NE NO DEC T.RDCT(R5) ;DECREMENT RUNDOWN COUNT CLR O.PTCB(R0) ;INDICATE PARENT TASK HAS EXITTED ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 CMP O.EFN(R0),#64. ;GROUP GLOBAL EVENT FLAG? ;MSH049 BLOS 94$ ;IF LOS NO ;MSH049 MOV R0,-(SP) ;SAVE OCB POINTER ;MSH049 MOV O.EFN(R0),R0 ;GET EVENT FLAG NUMBER ;MSH049 CALL $CEFI ;CONVERT TO MASK AND MASK ADDRESS ;MSH049 MOV R1,R3 ;COPY EVENT FLAG MASK ADDRESS ;MSH049 CALL $DEAGF ;DEACCESS GROUP GLOBAL EVENT FLAGS ;MSH049 MOV (SP)+,R0 ;RESTORE OCB POINTER ;MSH049  ;MSH049 .ENDC ;MSH049 ;MSH049 BR 94$ ;TRY TO REMOVE ANY MORE 96$: MOV (SP)+,R0 ;RESTORE TCB ADDRESS BNE 92$ ;IF NE NO 98$: ;REF LABEL .ENDC ;P$$OFF ADD #T.ST2,R5 ;POINT TO SECOND TASK STATUS WORD .IF DF T$$KMG BIT #T2.ABO,(R5) ;TASK MARKED FOR ABORT? BEQ 110$ ;IF EQ NO MOV $TKNPT,R0 ;GET TERMINATION NOTIFICATION TCB ADDRESS BEQ 110$ ;IF EQ NOT IN SYSTEM CMP $TKTCB,R0 ;TERMINATION NOTIFICATION TASK BEING TERMINATED? BEQ 103$ ;IF EQ YES BIS #TS.MSG,-(R5) ;SET ABORT MESSAGE IN PROGRESS CALL $EXRQN ;REQUEST TERMINATION NOTIFICATION TASK ;MSH165 .IF DF I$$RAR!I$$RDN!M$$MGE ;MSH165 ;MSH165 BR 90$ ;WAITFOR SIGNIFICANT EVENT ;MSH165 ;MSH165 .IFF ;MSH165 ;MSH165 CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT ;MSH165 .ENDC ;MSH165 ;MSH165 103$: MOV $ACTHD,R0 ;GET ADDRESS OF FIRST TCB 107$: BIC #TS.MSG,T.STAT(R0) ;CLEAR WAITING FOR MESSAGE BIC #T2.ABO,T.ST2(R0) ;CLEAR MARKED FOR ABORT MOV T.ACTL(R0),R0 ;GET ADDRESS OF NEXT TCB TST T.ACTL(R0) ;NULL TASK? BNE 107$ ;IF NE MORE TO GO 110$: ;REF LABEL .ENDC .IF DF I$$RAR BIT #T3.REM,2(R5) ;REMOVE TASK AT EXIT? BEQ 120$ ;IF EQ NO MOV #M$$CRB,R1 ;SET LENGTH OF BLOCK NEEDED CALL $ALOCB ;ALLOCATE CORE BLOCK BCS 90$ ;IF CS WAITFOR SIGNIFICANT EVENT MOV R0,-(SP) ;SAVE ADDRESS OF CORE BLOCK TST (R0)+ ;POINT TO SECOND WORD IN BLOCK MOV T.UCB-T.ST2(R5),(R0)+ ;INSERT TI UCB ADDRESS MOV (PC)+,(R0)+ ;INSERT REMOVE COMMAND .ASCII /RE/ ; MOV (PC)+,(R0)+ ; .ASCII /M / ; MOV T.NAM-T.ST2(R5),R1 ;GET FIRST HALF OF TASK NAME CALL $C5TA ;CONVERT TO ASCII MOV T.NAM+2-T.ST2(R5),R1 ;GET SECOND HALF OF TASK NAME CALL $C5TA ;CONVERT TO ASCII MOVB #33,(R0) ;INSERT ALTMODE AS TERMINAL BYTE MOV (SP)+,R1 ;RETRIEVE ADDRESS OF CORE BLOCK CALL $QMCR ;QUEUE MCR COMMAND LINE TO MCR ;MSH103 ;**-1 .ENDC 120$: ;REF LABEL ;MSH174 ;MSH174 ; ;MSH174 ; IN CASE OF CHECKPOINT READ FAILURE, IT IS LIKELY THAT THE TASK ;MSH174 ; HEADER IS GARBAGE. THUS, IF THE TASK HAD GROUP GLOBAL CONTEXT ;MSH174 ; ACTIVE, IT IS LIKELY THAT IT HAS NOT AND WILL NEVER BE RUN DOWN ;MSH174 ; CORRECTLY. THE FOLLOWING CODE ENSURES A 'CLEAN SLATE' CONCERNING ;MSH174 ; GROUP GLOBAL CONTEXT IN CASE THIS TASK IS INVOKED AGAIN. ;MSH174 ; ;MSH174 ;MSH174 .IF DF G$$EFN ;MSH174 ;MSH174 BIC #T3.GFL,2(R5) ;UNLOCK TASK FROM GROUP GLOBAL EFNS ;MSH174 ;MSH174 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH174 CLRB T.GGF-T.ST2(R5) ;CLEAR USE COUNT FOR TASK ;MSH174 ;MSH174 .ENDC ;MSH174 ;MSH174 .ENDC ;MSH174 ;MSH174 BIS #TS.EXE,-(R5) ;DEACTIVATE TASK ;MSH174 BIC #TS.CKR!TS.MSG,(R5)+ ;CLEAR STATUS BITS ;**-1 BIC #CLRMSK,(R5) ; .IF DF A$$PRI MOVB T.DPRI-T.ST2(R5),T.PRI-T.ST2(R5) ;RESTORE TASK PRIORITY .ENDC .IF DF D$$ISK BIT #T2.FXD,(R5)+ ;TASK FIXED IN MEMORY? BNE 130$ ;IF NE YES BIS #TS.OUT,-4(R5) ;SET TASK OUT OF MEMORY .IF DF P$$LAS MOV T.PCB-T.ST3(R5),R0 ;POINT TO TASK PCB MOV R0,-(SP) ;SAVE CURRENT PCB POINTER BIT #PS.SYS,P.STAT(R0) ;IS IT A SYSTEM CONTROLLED PARTITION? BEQ 124$ ;IF EQ NO MOV P.MAIN(R0),(SP) ;POINT BACK TO MAIN PCB 124$: MOV R5,-(SP) ;SAVE ADDRESS OF THIRD STATUS WORD TST T.ATT-T.ST3(R5) ;ATTACH QUEUE EMPTY (IF EQ LOAD FAILURE) BNE 125$ ;IF NE NO MOV R5,R0 ;COPY TCB POINTER SUB #T.ST3,R0 ;POINT TO START OF TCB CALL $RLPAR ;RELEASE TASK PARTITION MOV T.PCB-T.ST3(R5),R0 ;PICK UP TASK PCB ADDRESS BIT #PS.SYS,P.STAT(R0) ;SYSTEM CONTROLLED PARTITION? BEQ 125$ ;IF EQ NO MOV #P.LGTH,R1 ;SET SIZE TO RELEASE CALL $DEACB ;DEALLOCATE TASK PCB 125$: MOV (SP),R5 ;PICK UP ADDRESS OF THIRD STATUS WORD MOV T.ATT-T.ST3(R5),R5 ;POINT TO NEXT ATTACHMENT DESCRIPTOR BEQ 126$ ;IF EQ THERE IS NONE SUB #A.TCBL,R5 ;POINT TO START OF ATTACHMENT DESCRIPTOR CALL $DETRG ;DETACH THE REGION BR 125$ ; 126$: MOV (SP)+,R5 ;RESTORE ADDRESS OF THIRD STATUS WORD MOV (SP)+,T.PCB-T.ST3(R5) ;RESET TASK PCB ADDRESS .ENDC .IF DF M$$MGE MOV R4,R0 ;SET ADDRESS OF TASK HEADER MOV H.HDLN(R0),R1 ;GET LENGTH OF HEADER IN BYTES CALL $DEACB ;DEALLOCATE HEADER .ENDC MOV $TKTCB,R0 ;SET ADDRESS OF TASK TCB .IF NDF P$$LAS .IF DF D$$YNM&M$$MGE MOV T.PCB(R0),R4 ;SAVE ADDRESS OF TASK PCB .IFTF ;MSH165 CALL $RLPAR ;RELEASE TASK PARTITION .IFT BIT #PS.SYS,P.STAT(R4) ;SYSTEM CONTROLLED PARTITION? BEQ 130$ ;IF EQ NO MOV $TKTCB,R0 ;RETRIEVE ADDRESS OF TCB MOV P.MAIN(R4),T.PCB(R0) ;RESET TASK PCB POINTER MOV R4,R0 ;SET ADDRESS OF BLOCK TO RELEASE MOV #P.LGTH,R1 ;SET LENGTH OF BLOCK TO RELEASE CALL $DEACB ;DEALLOCATE PARTITION CONTROL BLOCK .ENDC .ENDC 130$: ;REFERENCE LABEL .ENDC .IF DF P$$OFF 132$: MOV R5,R0 ;COPY POINTER TO THIRD STATUS WORD .IF DF D$$ISK ADD #T.OCBH-T.ST3,R0 ;POINT TO OCB QUEUE LISTHEAD .IFF ;D$$ISK ADD #T.OCBH-T.ST2,R0 ;POINT TO OCB QUEUE LISTHEAD .IFTF ;D$$ISK CALL $QRMVF ;REMOVE NEXT OCB BCS 134$ ;IF CS, THERE IS NONE .IFT ;D$$ISK MOVB T.EFLG-T.ST3(R5),R2 ;GET SECONDARY EXIT STATUS CODE ;MSH129 MOV T.EFLG+2-T.ST3(R5),R0 ;PICK UP SAVED EXIT STATUS .IFF ;D$$ISK MOVB T.EFLG-T.ST2(R5),R2 ;GET SECONDARY EXIT STATUS CODE ;MSH129 MOV T.EFLG+2-T.ST2(R5),R0 ;PICK UP SAVED EXIT STATUS .ENDC ;D$$ISK CALL $QUEXT ;QUEUE EXIT STATUS TO PARENT BR 132$ ;GO AGAIN 134$: ;REF LABEL .ENDC ;P$$OFF CLR $HEADR ;DO NOT SAVE CONTEXT OF CURRENT TASK MOV $TKTCB,R0 ;GET ADDRESS OF CURRENT TCB CALL $ACTRM ;REMOVE TCB FROM THE ATL QUEUE .IF DF M$$CRX BIT #T3.MCR,(R5) ;MCR EXTERNAL FUNCTION TASK? BEQ 140$ ;IF EQ NO BIC #T3.MCR,(R5) ;CLEAR MCR FUNCTION FLAG ; MF211 ; MF211 .IF DF A$$CLI ; MF211 ; MF211 MOV #6,R1 ;SET SIZE OF TASK EXIT BLOCK ; MF211 ; MF211 .IFF ;A$$CLI ; MF211  ; MF211 MOV #4,R1 ;SET SIZE OF BLOCK REQUIRED ; MF211 .IFTF ;A$$CLI ; MF211 ; MF211 CALL $ALOCB ;ALLOCATE CORE BLOCK BCS 140$ ;IF CS ALLOCATION FAILURE MOV R0,R1 ;COPY ADDRESS OF BLOCK TST (R0)+ ;POINT TO SECOND WORD OF BLOCK ; MF211 .IFT ;A$$CLI ; MF211 ; MF211 MOV #1,(R0)+ ;SET SECOND WORD ; MF211 ; MF211 .ENDC ;A$$CLI ; MF211 ; MF211 ; MF211 MOV T.UCB-T.ST3(R5),(R0) ;INSERT TI UCB ADDRESS INC (R0) ;SET FLAG TO SIGNIFY MCR PROMPT CALL $QMCRL ;QUEUE MCR COMMAND LINE .ENDC 140$: CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT ; ; SUBROUTINE TO EMPTY QUEUE ; .IF DF K$$AST!A$$TRP!R$$SND!P$$SRF ;MSH091 ;**-1 MTQUE: MOV (R5)+,R4 ;GET OFFSET TO QUEUE LISTHEAD ADD (SP),R4 ;CALCULATE ADDRESS OF QUEUE LISTHEAD 10$: TST (R5)+ ;ADVANCE TO RETURN ADDRESS 13$: MOV R4,R0 ;SET ADDRESS OF LISTHEAD CALL $QRMVF ;REMOVE AN ENTRY FROM QUEUE BCS 40$ ;IF CS NO ENTRIES LEFT MOV R1,R0 ;SET ADDRESS OF BLOCK TO DEALLOCATE .IF DF A$$TRP!K$$AST ;MSH091 ;**-1 CMP #T.ASTL,-4(R5) ;PROCESSING AST QUEUE? BNE 20$ ;IF NE, NO, JUST DEALLOCATE PACKET MOVB A.CBL(R0),R1 ;SET LENGTH OF BLOCK (FOR ASTS ONLY) ;MSH091 BGT 20$ ;IF GT LENGTH SPECIFIED (AST'S ONLY) ;**-1 ;MSH091 .IF DF K$$AST ;MSH091 ;MSH091 BMI 30$ ;IF MI, ITS A KERNEL AST ;MSH091 ;MSH091 .ENDC ;MSH091 ;**-1 .IF DF A$$TRP TST A.CBL(R0) ;IS IT UNSOL CHAR AST? ;MSH091 BNE 18$ ;IF NE, NO, ITS A SPECIFIED AST ;**-1 MOV R4,-(SP) ;SAVE R4 MOV R5,-(SP) ;SAVE R5 .IF DF M$$MGE CMP -(R0),-(R0) ;POINT TO KISAR5 VALUE OF DEALL SUBR MOV (R0)+,KISAR5 ;MAP THE SUBROUTINE CALL @(R0)+ ;DEALLOCATE THE BLOCK .IFF ;M$$MGE CALL @-2(R0) ;CALL THE DEALLOCATION ROUTINE .ENDC ;M$$MGE MOV (SP)+,R5 ;RESTORE REGS MOV (SP)+,R4 ; BR 13$ ;GO AGAIN 18$: MOV #C.LGTH,R1 ;SET SIZE OF SPECIFIED AST BLOCK .ENDC ;A$$TRP .ENDC ;K$$AST!A$$TRP ;MSH091 ;**-1 20$: ; ;MSH183 ;MSH183 .IF DF P$$SRF&G$$EFN ;MSH183 ;MSH183 CMP #T.RRFL,-4(R5) ;PROCESSING RREF QUEUE? ;MSH183 BNE 23$ ;IF NE NO ;MSH183 MOV 2(R0),R1 ;GET SENDER'S TCB ADDRESS ;MSH183 BEQ 23$ ;IF EQ NO EVENT FLAG RUNDOWN POSSIBLE ;MSH183 MOV #AK.GGF,A.CBL(R0) ;CONVERT TO KERNEL AST CONTROL BLOCK ;MSH183 ADD #T.ASTL,R1 ;POINT TO SENDER'S AST QUEUE ;MSH183 MOV (R1),(R0) ;ESTABLISH PACKET'S POSITION IN QUEUE ;MSH183 BNE 21$ ;IF NE QUEUE WAS NOT EMPTY ;MSH183 MOV R0,2(R1) ;ESTABLISH END OF QUEUE ;MSH183 21$: MOV R0,(R1) ;ESTABLISH BEGINNING OF QUEUE ;MSH183 BR 13$ ;DEALLOCATE NEXT PACKET ;MSH183 23$: ; ;MSH183 ;MSH183 .ENDC ;MSH183 ;MSH183 CALL @-(R5) ;DEALLOCATE CORE BLOCK ;MSH183 BR 10$ ;GO AGAIN ;**-1 ;MSH091 .IF DF K$$AST ;MSH091 ;MSH091 30$: CRASH ;TASK CAN'T EXIT WITH KERNEL ASTS ;MSH091 ;MSH091 .ENDC ;K$$AST ;MSH091 ;**-23 40$: RTS R5 ; .ENDC ; ; CO-ROUTINE TO SCAN LOGICAL UNIT TABLE ; .IF DF I$$RAR!I$$RDN!M$$MGE SCNLN: MOV (SP),R3 ;SAVE RETURN ADDRESS CLR (SP) ;START AT LUN ZERO 10$: MOV $TKTCB,R5 ;GET ADDRESS OF CURRENT TASK TCB MOV $HEADR,R4 ;GET ADDRESS OF HEADER OF CURRENT TASK 20$: MOV (SP),R1 ;GET NEXT LUN NUMBER INC (SP) ;INCREMENT LUN NUMBER CMP H.NLUN(R4),(SP) ;END OF LUT? BLO 30$ ;IF LO YES CALL $MPLNE ;MAP LUN NUMBER TO UCB ADDRESS BCS 20$ ;IF CS NO DEVICE ASSIGNED TO LUN MOV R0,R5 ;COPY UCB ADDRESS CALL (R3) ;CALL THE CALLER BACK MOV (SP)+,R3 ;RETRIEVE RETURN ADDRESS BR 10$ ;GO AGAIN 30$: MOV R3,(SP) ;SET RETURN ADDRESS RETURN ; .ENDC .END ÌyykQ ›c, .TITLE SSTSR .IDENT /11.08/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 11.08 ; ; D. N. CUTLER 27-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; J. R. COVERT ; ; MODIFIED BY: ; ; M. S. HARVEY 25-AUG-80 ; MSH045 -- DRQIO FAULTS CAN ONLY OCCUR IF DIRCOM MAPPED ; ; M. S. HARVEY 13-NOV-80 ; MSH125 -- SET CRASH ORIGINATION BIT FOR CRASH ANALYSIS ; ; M. S. HARVEY 5-MAY-81 ; MSH165 -- MODIFY MSH045 TO INCORPORATE SUPPORT FOR ; THE SECOND DIRECTIVE COMMON ; ; SYNCHRONOUS SYSTEM TRAP (SST) SERVICE ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL ABODF$,HDRDF$,HWDDF$,PKTDF$ ABODF$ ;DEFINE TASK ABORT CODES HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; LOCAL DATA ; ; FLOATING POINT EXCEPTION VECTOR (FINAL SETUP OF THIS VECTOR AND, IF ; NECESSARY, THE PIRQ VECTOR IS PERFORMED IN INITL AND THE MCR SAVE ; COMMAND.) ; .IF DF F$$LPP!F$$LTP .ASECT .=244 .WORD $FLTRP ; .WORD PR7 ; .PSECT .ENDC ; ; FLOATING POINT STATUS AND FORK BLOCK ; .IF DF F$$LPP FLSTS: .BLKW 2 ;FLOATING POINT STATUS FLFRK: .BLKW 2 ;FLOATING POINT FORK BLOCK FLTCB: .BLKW 1 ;ADDRESS OF TCB CAUSING EXCEPTION TRAP .ENDC ; ; SEGMENT FAULT VECTOR ; .IF DF M$$MGE  .ASECT .=250 .WORD $SGFLT ; .WORD PR7 ; .CSECT .ENDC ;+ ; ; **-$EMSST-NON RSX EMT/TRAP INSTRUCTION ; ; THIS ROUTINE IS TRANSFERED TO BY THE DIRECTIVE DISPATCHER WHEN A NON RSX ; EMT OR A TRAP INSTRUCTION IS EXECUTED. THE MACHINE STATE HAS ALREADY BEEN ; SAVED. THE EMT/TRAP CODE (LOW BYTE OF INSTRUCTION) IS SETUP TO BE ; PASSED TO THE USER AND CONTROL IS TRANSFERED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; R5=ADDRESS OF THE EMT/TRAP INSTRUCTION. ; ; OUTPUTS: ; ; 04(SP)=EMT/TRAP CODE MULTIPLIED BY 2. ; 02(SP)=SST CODE (S.CEMT=EMT, S.CTRP=TRAP) ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO USER STACK (6). ;**-1 ;- .ENABL LSB $EMSST:: ;REF LABEL .IF DF M$$MGE MOV (SP),R5 ;GET EMT/TRAP INSTRUCTION BIC #177400,(SP) ;CLEAR INSTRUCTION CODE ASL (SP) ;MULTIPLY CODE BY 2 MOV #S.CEMT,-(SP) ;ASSUME NON-RSX EMT INSTRUCTION BIT #400,R5 ;EMT INSTRUCTION? .IFF CLR -(SP) ;PICKUP SST CODE BISB (R5)+,(SP) ; ASL (SP) ;MULTIPLY CODE BY 2 MOV #S.CEMT,-(SP) ;ASSUME NON-RSX EMT INSTRUCTION BITB #1,(R5) ;EMT INSTRUCTION .ENDC BEQ 10$ ;IF EQ YES-SET NUMBER OF BYTES MOV #S.CTRP,(SP) ;SET FOR TRAP INSTRUCTION 10$: MOV #3*2,-(SP) ;SET NUMBER OF BYTES BR SSTXT ;TAKE COMMON SST EXIT ROUTINE ;+ ; **-$FLTRP-FLOATING POINT EXCEPTION (11/40) ; ; THIS ROUTINE IS TRAPPED TO WHEN AN 11/40 FLOATING POINT EXCEPTION FAULT ; OCCURS. THE CURRENT MACHINE STATE IS SAVED AND CONTROL IS TRANSFERED TO ; THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; 02(SP)=SST CODE (S.CFLT). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO USER STACK (4). ;**-1 ;- $FLTRP:: ;DEFINE UNCONDITIONALLY FOR VECTOR SETUP .IF DF F$$LTP DIRSV$ ;;;SAVE REGISTERS AND CLEAR PRIORITY MOV #S.CFLT,-(SP) ;SET FOR FLOATING POINT EXCEPTION FAULT BR 20$ ;SET NUMBER OF BYTES .ENDC ;+ ; **-$FPPR7-$FPPR8-$FPPRQ-FLOATING POINT PROCESSOR EXCEPTION HANDLING ; ; THESE ROUTINES HANDLE EXCEPTION FAULTS FROM THE FLOATING POINT ; PROCESSOR. THE FLOATING POINT EXCEPTION AND ADDRESS REGISTERS AND ; THE CURRENT TASK TCB ARE SAVED AND THEN AN ATTEMPT IS MADE TO QUEUE AN ; AST TO THE TASK AT FORK LEVEL. THESE ROUTINES SUPPORT TWO MODES OF ; OPERATION DEPENDING ON WHETHER THE FPP'S EXCEPTION FAULTS CAN OCCUR ; WHILE THE PROCESSOR IS AT PRIORITY 7 OR NOT. IF THE FPP'S EXCEPTION ; FAULT CAN OCCUR WHILE THE PROCESSOR IS AT PRIORITY 7, THEN THE ; PROCESSOR MUST HAVE A PIRQ REGISTER. INITL AND THE MCR SAVE ; COMMAND DETERMINE WHICH MODE OF OPERATION IS TO BE USED OR NOT ; DEPENDING ON WHETHER THE PROCESSOR HAS A PROGRAM INTERRUPT REQUEST ; REGISTER (PIRQ) OR NOT, AND SET UP THE FPP AND PIRQ VECTORS ; ACCORDINGLY. THE ROUTINES OPERATE AS FOLLOWS. ; ; 1. IF THE PROCESSOR DOES NOT HAVE A PIRQ REGISTER THEN THE FPP MUST ; NEVER FAULT WHEN THE PROCESSOR IS AT PRIORITY 7 OR IT MUST BE ; SYNCHRONOUS. IN THIS CASE THE FLOATING POINT EXCEPTION VECTOR ; POINTS TO $FPPR7, AND THE PROCESSOR SIMPLY CALLS INTERRUPT SAVE ; AND FORK TO GET TO SYSTEM STATE. ; ; 2. IF THE PROCESSOR HAS A PIRQ REGISTER, THE FLOATING POINT EXCEP- ; TION TRAP VECTOR POINTS TO $FPPR8 AND THE PIRQ VECTOR POINTS TO ; $FPPRQ. FLOATING POINT TRAPS ARE CONVERTED TO PIRQ PRIORITY 1 ; INTERRUPTS AFTER SAVING THE FLOATING POINT STATUS. ON THE PIRQ ; TRAP AN INT SAVE AND FORK IS USED TO GET TO SYSTEM STATE. NOTE ; THAT THIS STRATEGY WOULD ALSO WORK FOR PROCESSORS DESCRIBED IN 1 ; ABOVE. ; ; INPUTS: ; ; THE FLOATING POINT EXCEPTION REGISTER CONTAINS THE REASON FOR THE ; FAULT AND THE FLOATING POINT ADDRESS REGISTER CONTAINS THE ADDRESS ; OF THE FAULTING INSTRUCTION. ; ; OUTPUTS: ; ; AN ATTEMPT IS MADE TO QUEUE AN AST TO THE TASK CAUSING THE FAULT ; WITH THE CONTENTS OF THE FLOATING POINT EXCEPTION REGISTER AND ; AND ADDRESS REGISTER. ;- .IF DF F$$LPP $FPPR7::STST FLSTS ;;;STORE FLOATING POINT EXCEP AND ADDR BR 14$ ;;; $FPPR8::STST FLSTS ;;;STORE FLOATING POINT EXCEP AND ADDR BIS #<2*256.>,PIRQ ;;;POST PROGRAMMED INTERRUPT REQUEST RTI ;;;WAIT FOR PIRQ INTERRUPT $FPPRQ::CLR PIRQ ;;;DISABLE PROGRAM INTERRUPT REQUEST 14$: MOV $TKTCB,FLTCB ;;;MUST SAVE FAULTING TCB NOW CALL $INTSV,PR1 ;;;GO TO PRIORITY 1 MOV #FLFRK+4,R4 ;;;SET ADDRESS OF FORK BLOCK CALL $FORK0 ;;;CREATE A SYSTEM PROCESS MOV #AS.FPA,R4 ;SET FLOATING POINT TYPE AST MOV FLTCB,R5 ;GET TCB ADDRESS OF FAULTING TASK CALL $DASTT ;DECLARE FLOATING POINT AST BCS 15$ ;IF CS NO AST DECLARED MOV FLSTS,A.PRM+2(R1) ;INSERT AST PARAMETERS MOV FLSTS+2,A.PRM(R1) ; 15$: RETURN ; .IFF $FPPR7:: ;DEFINE LABELS FOR SAVE $FPPR8:: ; $FPPRQ:: ; .ENDC ;+ ; **-$ILINS-ILLEGAL OR RESERVED INSTRUCTION ; ; THIS ROUTINE IS TRAPPED TO WHEN AN ILLEGAL OR RESERVED INSTRUCTION ; IS EXECUTED. THE CURRENT MACHINE STATE IS SAVED AND CONTROL IS TRANS- ; FERRED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; 02(SP)=SST CODE (S.CILI). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO THE USER STACK (4). ;**-1 ;- $ILINS::DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY MOV #S.CILI,-(SP) ;SET FOR ILLEGAL OR RESERVED INSTRUCTION BR 20$ ;SET NUMBER OF BYTES ;+ ; **-$IOTRP-IOT INSTRUCTION ; ; THIS ROUTINE IS TRAPPED TO WHEN AN IOT INSTRUCTION IS EXECUTED. IF THE ; STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED VIA A JUMP TO ; $CRASH. ELSE THE CURRENT MACHINE STATE IS SAVED AND CONTROL IS TRANS- ; FERED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; IF THE CURRENT STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED. ; ELSE THE FOLLOWING ARGUMENTS ARE SETUP ON THE CURRENT STACK: ; ; 02(SP)=SST CODE (S.CIOT). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERRED TO THE USER STACK (4). ;**-1 ;- $IOTRP::TST $STKDP ;;;RUNNING ON SYSTEM STACK? BLE 16$ ;;;IF LE YES, FATAL SYSTEM ERROR ;MSH125 DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY ;**-1 MOV #S.CIOT,-(SP) ;SET FOR IOT INSTRUCTION BR 20$ ;SET NUMBER OF BYTES ;+ ; **-$SGFLT-SEGMENT FAULT ; ; THIS ROUTINE IS TRAPPED TO WHEN A SEGMENT FAULT OCCURS. THE CURRENT ; MACHINE STATE IS SAVED, SR0 THRU SR2 ARE SETUP TO BE PASSED TO THE USER, ; AND CONTROL IS TRANSFERED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; 10(SP)=CONTENTS OF SR0. ; 06(SP)=CONTENTS OF SR2. ; 04(SP)=CONTENTS OF SR1. ; 02(SP)=SST CODE (S.CSGF). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO THE USER STACK (10.).;MSH125 ;- ;**-2 .IF DF M$$MGE $SGFLT::DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY MOV #SR0+4,R5 ;POINT SR2 MOV (R5),-(SP) ;SAVE SR2 MOV (SP),-(SP) ;COPY SAVED SR2 MOV -(R5),-(SP) ;SAVE SR1 MOV -(R5),4(SP) ;SAVE SR0 BIC #160000,(R5) ;UNFREEZE MEMORY MANAGEMENT UNIT MOV #S.CSGF,-(SP) ;SET FOR SEGMENT FAULT MOV #5*2,-(SP) ;SET NUMBER OF BYTES BR SSTXT ;TAKE COMMON SST EXIT ROUTINE .ENDC ;+ ; **-$TRACE-TRACE (T-BIT) OR BREAK POINT INSTRUCTION (BPT) TRAP ; ; THIS ROUTINE IS TRAPPED TO WHEN A TRACE TRAP (T-BIT) OCCURS OR A BREAK- ; POINT TRAP INSTRUCTION IS EXECUTED. THE CURRENT MACHINE STATE IS SAVED ; AND CONTROL IS TRANSFERED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; 02(SP)=SST CODE (S.CBPT). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO THE USER STACK (4). ;**-1 ;- $TRACE::DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY MOV #S.CBPT,-(SP) ;SET FOR TRACE OR BREAKPOINT TRAP BR 20$ ;SET NUMBER OF BYTES ;+ ; **-$TRP04-TRAPS AT 4 (ODD ADDRESS, NONEX MEM, ETC.) ; ; THIS ROUTINE IS TRAPPED TO WHEN A TRAP AT 4 OCCURS. IF A STACK VIOLATION ; HAS CAUSED THE TRAP (I.E. A STACKPOINTER OF LESS THAN 400), THEN THE ; THE SYSTEM IS CRASHED. ELSE THE CURRENT MACHINE STATE IS SAVED AND ; CONTROL IS TRANSFERED TO THE SST EXIT ROUTINE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; 02(SP)=SST CODE (S.COAD). ;MSH125 ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO THE USER STACK (4). ;**-1 ;- $TRP04::CMP SP,#400 ;;;STACK VIOLATION? BHIS 17$ ;;;IF HIS NO ;MSH125 16$: ;;; ;MSH125 .IF DF C$$RSH ;MSH125  ;MSH125 INC $FMASK+4 ;;;SET SYSTEM CRASH BIT (F3.CRA) ;MSH125 ;MSH125 .ENDC ;C$$RSH ;MSH125 ;MSH125 JMP $CRASH ;;;CRASH THE SYSTEM ;MSH125 17$: DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY ;MSH125 CLR -(SP) ;SET FOR ODD ADDRESS TRAP ;**-2 20$: MOV #2*2,-(SP) ;SET NUMBER OF BYTES ;MSH125 .DSABL LSB ;**-2 ;+ ; **-SSTXT-COMMON SST EXIT ROUTINE ; ; CONTROL IS TRANSFERED TO THIS ROUTINE TO EFFECT AN SST. IF THE CURRENT ; STACK DEPTH IS NOT ZERO, THEN THE SYSTEM IS CRASHED. ELSE AN ATTEMPT IS ; MADE TO EFFECT AN SST FOR THE CURRENT TASK. IF THE TASK DOES NOT HAVE ; AN APPROPRIATE SST VECTOR ENTRY OR A PUSH OF THE SST PARAMETERS ONTO THE ; TASK STACK CANNOT BE EFFECTED, THEN THE TASK IS ABORTED. ELSE THE SST ; IS SETUP AND A DIRECTIVE EXIT IS EXECUTED. ; ; INPUTS: (MAPPED SYSTEM) ; ; 24(SP)=PS WORD SAVED BY SST TRAP. ; 22(SP)=PC WORD SAVED BY SST TRAP. ; 20(SP)=SAVED R5. ; 16(SP)=SAVED R4. ; 14(SP)=SAVED R3. ; 12(SP)=SAVED R2. ; 10(SP)=SAVED R1. ; 06(SP)=SAVED R0. ; 04(SP)=SST PARAMETER (ZERO OR MORE PARAMETERS MAY BE SPECIFIED). ; 02(SP)=SST CODE. ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO USER STACK. ; ; INPUTS: (REAL MEMORY SYSTEM) ; ; 14(SP)=SAVED R3. ; 12(SP)=SAVED R2. ; 10(SP)=SAVED R1. ; 06(SP)=SAVED R0. ; 04(SP)=SST PARAMETER (ZERO OR MORE PARAMETERS MAY BE SPECIFIED). ; 02(SP)=SST CODE. ; 00(SP)=NUMBER OF BYTES TO BE TRANSFERED TO USER STACK. ; ; OUTPUTS: ; ; AN ATTEMPT IS MADE TO EFFECT THE SPECIFIED SST FOR THE CURRENT TASK. ;- SSTXT: MOV $HEADR,R5 ;GET ADDRESS OF TASK HEADER .IF DF M$$MGE CMP #-1,$STKDP ;FAULT OCCUR AT STACK DEPTH ZERO? BNE 7$ ;IF NE NO MOV SP,R0 ;COPY CURRENT STACK POINTER ADD (SP),R0 ;ADD NUMBER OF BYTES TO BE TRANSFERED MOV 16(R0),R0 ;GET FAULT PC ADDRESS ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 CMP KISAR5,$XCOM1 ;FIRST EXEC COMMON MAPPED? ;MSH165 BNE 7$ ;IF NE NO, SKIP EXEC BOUNDS CHECKS ;MSH165 ;MSH045 .ENDC ;D$$PAR ;MSH045 ;MSH045 CMP R0,#$DRLM1 ;FAULT OCCUR IN DIRECTIVE DISPATCHER? BLO 3$ ;IF LO NO CMP R0,#$DRLM2 ;FAULT OCCUR IN DIRECTIVE DISPATCHER? BLOS 90$ ;IF LOS YES 3$: CMP R0,#$DQLM1 ;FAULT OCCUR IN QIO DIRECTIVE? BLO 4$ ;IF LO NO CMP R0,#$DQLM2 ;FAULT OCCUR IN QIO DIRECTIVE? BLOS 90$ ;IF LOS YES 4$: ;REFERENCE LABEL .IF DF P$$LAS CMP R0,#$DPLM1 ;FAULT OCCUR RETRIEVING DEF BLOCK ADDR? BLO 7$ ;IF LO NO CMP R0,#$DPLM2 ;FAULT OCCUR RETRIEVING DEF BLOCK ADDR? BLOS 90$ ;IF LOS YES .ENDC .IFTF 7$: TST $STKDP ;STACK DEPTH ZERO? BNE 60$ ;IF NE NO - FATAL SYSTEM ERROR MOV R5,R4 ;COPY ADDRESS OF HEADER ADD #H.ODVA,R4 ;POINT TO ODT SST VECTOR DESCRIPTOR CALL 10$ ;SST ADDRESS IN ODT VECTOR? MOV #80$,-(SP) ;SST ADDRESS IN TASK VECTOR? 10$: MOV (R4)+,R3 ;GET ADDRESS OF SST VECTOR BEQ 20$ ;IF EQ NO VECTOR THIS DESCRIPTOR CMP 4(SP),(R4) ;VECTOR LONG ENOUGH TO COVER SST? BHIS 20$ ;IF HIS NO ADD 4(SP),R3 ;POINT TO APPROPRIATE VECTOR ENTRY .IF DF A$$CHK!M$$MGE MOV R3,R0 ;SUPPLY VECTOR ELEMENT ADDRESS AND MOV #2,R1 ;TWO BYTE SIZE FOR CALL CALL $ACHCK ;ADDRESS CHECK VECTOR ELEMENT BCS 20$ ;IF CS THEN VECTOR ELEMENT NOT VALID .ENDC ;DF A$$CHK!M$$MGE .IFT MFPI (R3) ;GET ADDRESS OF SST ROUTINE MOV (SP)+,R3 ; .IFF MOV (R3),R3 ;GET ADDRESS OF SST ROUTINE .IFTF BNE 30$ ;IF NE SST ROUTINE FOUND 20$: TST (R4)+ ;POINT TO NEXT VECTOR DESCRIPTOR RETURN ; 30$: TST (SP)+ ;REMOVE RETURN ADDRESS  MOV (SP),R1 ;GET NUMBER OF BYTES TO BE TRANSFERED .IFT MFPI SP ;GET CURRENT TASK STACK POINTER SUB R1,(SP) ;CALCULATE NEW TOP OF STACK MOV (SP),R0 ;COPY NEW TOP OF STACK ADDRESS MTPI SP ;RESTORE NEW TASK STACK POINTER .IFF MOV (R5),R0 ;GET CURRENT TASK STACK POINTER SUB R1,R0 ;CALCULATE NEW TOP OF STACK MOV (R5),R4 ;SAVE CURRENT TASK STACK POINTER MOV R0,(R5) ;RESTORE NEW TASK STACK POINTER .IFTF .IF DF A$$CHK!M$$MGE CALL $ACHCK ;ADDRESS CHECK PUSH ONTO TASK STACK BCS 70$ ;IF CS ADDRESS CHECK FAILURE .ENDC .IFT CALL $RELOM ;RELOCATE AND MAP STACK ADDRESS .IFF MOV (R4)+,(R0)+ ;MOVE SAVED R4 MOV (R4),(R0)+ ;MOVE SAVED R5 MOV R3,(R0)+ ;SET SST PC WORD CLR (R0)+ ;SET SST PS WORD .IFTF MOV (SP)+,R1 ;GET NUMBER OF BYTES TO TRANSFER CMP -(R1),-(R1) ;ADJUST BY 4 BYTES (PS AND PC WORDS) ASR R1 ;CONVERT TO WORD COUNT TST (SP)+ ;REMOVE SST CODE FROM STACK 40$: DEC R1 ;ANY MORE PARAMETERS TO TRANSFER? BLT 50$ ;IF LT NO MOV (SP)+,(R0)+ ;TRANSFER PARAMETER TO TASK STACK BR 40$ ; 50$: ;REF LABEL .IFT MOV #$STACK-4,R4 ;POINT TO SAVED PC WORD MOV (R4),(R0)+ ;SAVE PC AT TRAP ON USER STACK MOV R3,(R4)+ ;SET SST PC WORD MOV (R4),(R0) ;SAVE PS AT TRAP ON USER STACK MOV #CMODE!PMODE,(R4) ;SET SST PS WORD .IFTF RETURN ;EXIT FROM TRAP ; ; SST FAULT AT NON ZERO STACK DEPTH-FATAL SYSTEM ERROR ; 60$: CRASH ;CRASH SYSTEM ; ; SST CANNOT BE EFFECTED BECAUSE OF BAD TASK STACK ; .IF DF A$$CHK!M$$MGE 70$: MOV #S.CSST,2(SP) ;SET BAD STACK SST ABORT CODE .ENDC ; ; SST CANNOT BE EFFECTED BECAUSE OF NO SST VECTOR ENTRY ; 80$: MOV 2(SP),R0 ;SET SST ABORT CODE .IFT MOV #$STACK-22,SP ;RELOAD EXEC STACK POINTER .IFF MOV #$STACK-12,SP ;RELOAD EXEC STACK POINTER .IFTF CALLR $ABCTK ;ABORT CURRENT TASK ; ; FAULT FROM PROTECTED LIMITS IN DRDSP OR DRQIO ; .IFT 90$: INC $STKDP ;CORRECT STACK DEPTH INDICATOR DRSTS D.RS98 ;SET DIRECTIVE STATUS  .ENDC .END of"kQ ›c, .TITLE POWER .IDENT /09.12/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 09.12 ; ; D. N. CUTLER 1-OCT-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; CHUCK SPITZ ; M. S. HARVEY ; R. R. ADAMS ; ; MODIFIED BY: ; ; M. S. HARVEY 19-SEP-80 ; MSH119 -- DEFINE GLOBAL ENTRY POINT FOR AUTOCONFIGURE ; ; M. S. HARVEY 19-SEP-80 ; MSH097 -- DON'T ACCESS UNIBUS MAP IF NOT THERE ; ; M. S. HARVEY 13-NOV-80 ; MSH127 -- CLEAN UP CACHE MEMORY CONDITIONALIZATION ; ; MSH128 -- IMPLEMENT NETWORK POWERFAIL RECOVERY ; ; M. S. HARVEY 23-DEC-80 ; MSH134 -- PREVENT UNDEFINED VARIABLE INTERRUPTS WHEN ; RESTORING FLOATING POINT CONTEXT ; ; DAN BROWN 7-JAN-81 ; DTB009 -- MODIFY HANDLING OF ERROR LOG ENTRIES FOR NEW ; ERROR LOGGER. ; ; M. S. HARVEY 3-MAR-81 ; MSH154 -- CONSOLIDATE POWERFAIL AND CRASH STACKS ; ; M. S. HARVEY 5-MAR-81 ; MSH156 -- ADD TRANSPORTABILITY SUPPORT FOR THE ; WATCHDOG TIMER ; ; M. S. HARVEY 27-JUL-81 ; MSH181 -- HANDLE POSSIBLE T-BIT TRAPS FOLLOWING ; POWER UP ON LSI11/02 PROCESSORS ; ; M. S. HARVEY 30-NOV-81 ; MSH149 -- ADD FLOATING POINT TRANSPORTABILITY ; ; POWERFAIL RECOVERY ; ; MACRO LIBRARY CALLS ; .MCALL EPKDF$,HDRDF$,HWDDF$,PCBDF$,TCBDF$ ;DTB009 EPKDF$ ;DEFINE ERROR LOG PACKET OFFSETS ;DTB009 HDRDF$  ;DEFINE TASK HEADER OFFSETS ;**-2 HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; LOCAL DATA ; ; VOLATILE REGISTER STORAGE ; .IF DF P$$RFL ; ;MSH154 ; NOTE THAT THE POWERFAIL STACK IS ACTUALLY ALLOCATED IN THE ;MSH154 ; CRASH MODULE WHERE IT DOES DOUBLE DUTY AS THE CRASH STACK, ;MSH154 ; ON SYSTEMS WITH CRASH NOTIFICATION SUPPORT. OTHERWISE, THE ;MSH154 ; POWERFAIL STACK IS ALLOCATED HERE. NOTE THAT ANY CHANGES TO ;MSH154 ; THE DEFINITION OF THE STACK HERE MUST BE REFLECTED IN THE ;MSH154 ; DEFINITION OF THE CRASH STACK AS WELL. ;MSH154 ; ;MSH154 ;MSH154 .IF DF C$$RSH ;MSH154 ;MSH154 .ASECT ;MSH154 ;MSH154 .=0 ;MSH154 ;MSH154 .IFF ;MSH154 ;MSH154 $CRPBF:: ;BEGINNING OF POWERFAIL STACK ;MSH154 ;MSH154 .IFTF ;MSH154 ;MSH154 .BLKW 7 ;R0 THRU R5 AND SP ;MSH154 ;**-1 .IF DF L$$SI1 ;MSH181 ;MSH181 .BLKW 1 ;SAVE BPT/T-BIT TRAP VECTOR CONTENTS ;MSH181 ;MSH181 .ENDC ;MSH181 .IF DF M$$MGE .IF DF M$$EXT .BLKW <31.-5.>*2 ;UNIBUS MAPPING REGISTERS .ENDC .BLKW 25. ;MEMORY MANAGEMENT REGISTERS .IFF .IF DF E$$EAE .BLKW 3 ;EAE REGISTERS .ENDC .ENDC .IF DF F$$LPP .BLKW 27. ;FLOATING POINT REGISTERS .ENDC PWSTK=.-2 ;MSH154 ;MSH154 .IFT ;MSH154 ;MSH154 .PSECT ;MSH154 ;MSH154 .ENDC ;C$$RSH ;MSH154 ;**-1 ; ; POWERFAIL VECTOR ; .IFTF .ASECT .=24 PWVCT: .WORD PDOWN ; .WORD PR7 ; .PSECT ;+ ; **-PDOWN-POWERFAIL INTERRUPT (DOWN) ; ; THIS ROUTINE IS ENTERED AS A RESULT OF A POWER DOWN INTERRUPT. ALL ; VOLATILE MACHINE REGISTERS ARE SAVED, THE POWERFAIL VECTOR IS SWITCHED ; TO THE POWER UP ROUTINE, AND THE PROCESSOR IS HALTED TO AWAIT THE ; POWER UP INTERRUPT. ;-  PDOWN: ;REF LABEL .IFT MOV SP,$CRPBF+PWSTK ;;;SAVE CURRENT STACK POINTER ;MSH154 MOV #$CRPBF+PWSTK,SP ;;;SET ADDRESS OF REGISTER SAVE AREA ;MSH154 MOV R5,-(SP) ;;;SAVE REGISTERS R5 THRU R0 ;**-2 MOV R4,-(SP) ;;; MOV R3,-(SP) ;;; MOV R2,-(SP) ;;; MOV R1,-(SP) ;;; MOV R0,-(SP) ;;; .IF DF L$$SI1 ;MSH181 ;MSH181 MOV @#14,-(SP) ;;;SAVE BPT/T-BIT SERVICE ROUTINE ADDR. ;MSH181 MOV #$TBIT,@#14 ;;;RESET TO DISMISS T-BIT TRAPS ;MSH181 ;MSH181 .ENDC  ;MSH181 .IF DF M$$MGE .IF DF M$$EXT TST $UMRPT ;;;UNIBUS MAP EXISTS? ;MSH097 BEQ 7$ ;;;IF EQ NO, SKIP SAVING IT ;MSH097 MOV #UBMPR+<31.*4>,R0 ;;;POINT PAST LAST MAP REGISTER MOV #31.-5.,R1 ;;;SET COUNT OF REGISTERS TO SAVE 5$: MOV -(R0),-(SP) ;;;SAVE HIGH 6 BITS OF ADDRESS ;MSH097 MOV -(R0),-(SP) ;;;SAVE LOW 16 BITS OF ADDRESS ;**-1 DEC R1 ;;;ANY MORE TO SAVE? BGT 5$ ;;;IF GT YES ;MSH097 7$: ;;;REFERENCE LABEL ;MSH097 ;**-1 .ENDC BIS #PMODE,PS ;;;MAKE SURE PREVIOUS MODE IS USER MFPI SP ;;;SAVE USER STACK POINTER MOV #KISAR0+16.,R0 ;;;POINT TO KERNEL ADDRESS REGISTER 7+2 MOV #UISAR0+16.,R1 ;;;POINT TO USER ADDRESS REGISTER 7+2 MOV #UISDR0+16.,R2 ;;;POINT TO USER DESCRIPTOR REGISTER 7+2 MOV #8.,R3 ;;;SET LOOP COUNT 10$: MOV -(R0),-(SP) ;;;SAVE KERNEL ADDRESS REGISTER MOV -(R1),-(SP) ;;;SAVE USER ADDRESS REGISTER MOV -(R2),-(SP) ;;;SAVE USER DESCRIPTOR REGISTER DEC R3 ;;;ANYMORE TO SAVE? BGT 10$ ;;;IF GT YES .IFF  .IF DF E$$EAE MOV SC,-(SP) ;;;SAVE EAE SHIFT COUNT MOV AC,-(SP) ;;;SAVE EAE ACCUMULATOR MOV MQ,-(SP) ;;;SAVE EAE MULTIPLIER-QUOTIENT .ENDC .ENDC .IF DF F$$LPP TST $HFMSK ;;;FPU PRESENT? ;MSH149 BMI 35$ ;;;IF MI NO, DON'T TRY TO ACCESS IT ;MSH149 STFPS -(SP) ;;;STORE FLOATING POINT STATUS SETD ;;;SET FLOATING DOUBLE MODE STD R0,-(SP) ;;;SAVE FIRST FL. PT. ACCUMULATOR (FACC);MSH134 STD R1,-(SP) ;;;SAVE SECOND FACC ;MSH134 STD R2,-(SP) ;;;SAVE THIRD FACC ;MSH134 STD R3,-(SP) ;;;SAVE FOURTH FACC ;MSH134 LDD R4,R0 ;;;MOVE FIFTH FACC TO FIRST FACC ;MSH134 STD R0,-(SP) ;;;SAVE FIFTH FACC ;MSH134 LDD R5,R0 ;;;MOVE SIXTH FACC TO FIRST FACC ;MSH134 STD R0,-(SP) ;;;SAVE SIXTH FACC ;MSH134 CLR -(SP) ;;;PUSH AN ADDRESS OF ZERO ;**-8 CMP @#244,#$FPPR7 ;;;IS THERE A PIRQ REGISTER TO SAVE? BEQ 30$ ;;;IF EQ NO, DO DUMMY SAVE OF LOCATION 0 MOV #PIRQ,(SP) ;;;SET FOR SAVE OF PIRQ 30$: MOV @(SP),-(SP) ;;;SAVE PIRQ REGISTER OR CONTENTS OF 0 .ENDC 35$: MOV #PUP,PWVCT ;;;SWITCH TO POWER UP ROUTINE ;MSH149 ;**-1 .IFTF .IF DF I$$PPF .IF DF LD$IP MOV #.IP0,R0 ;;;GET IP UCB MOV (R0),R0 ;;;GET IP DCB MOV D.DSP(R0),R1 ;;;GET IP DRIVER DISPATCH TABLE BEQ 40$ ;;;DRIVER NOT LOADED OR RESIDENT MOV D.PCB(R0),R0 ;;;GET IPDRV PCB BEQ 40$ ;;;IF EQ, DRIVER RESIDENT (LD$IP ?) MOV P.REL(R0),KISAR5 ;;;MAP IPDRV MOV D.VINI-2(R1),SP ;;;GET POWER-DOWN ENTRY POINT CALL (SP) ;;;CALL DRIVER 40$: .IFF MOV #$PCSPF,SP ;;;SET STACK POINTER CALL (SP) ;;;CALL USER POWER FAIL ROUTINE .ENDC .ENDC HALT ;;;WAIT FOR SOME JUICE! .IFT ;+ ; **-PUP-POWERFAIL INTERRUPT (UP) ; ; THIS ROUTINE IS ENTERED AS A RESULT OF A POWER UP INTERRUPT. ALL VOLATILE ; MACHINE REGISTERS ARE RESTORED, A SCHEDULE REQUEST IS FORCED FOR THE ; NULL TASK, THE POWERFAIL INDICATOR IS INCREMENTED, AND AN RTI IS ; EXECUTED. AT THE APPROPRIATE TIME THE DISPATCHER WILL CALL THE POWER ; RECOVERY ROUTINE TO ACTUALLY PROCESS THE POWER FAILURE. ;- PUP: MOV #$CRPBF,SP ;;;POINT TO LAST REGISTER SAVED ;MSH154 ;**-1 .IF DF F$$LPP TST $HFMSK ;;;FPU PRESENT? ;MSH149 BMI 5$ ;;;IF MI NO, DON'T TRY TO ACCESS IT ;MSH149 MOV (SP)+,@(SP)+ ;;;CONDITIONALLY RESTORE PIRQ OR LOC. 0 LDFPS #200 ;;;SET DOUBLE MODE - CLR INTERRUPT BITS ;MSH134 LDD (SP)+,R0 ;;;LOAD SIXTH FACC INTO FIRST FACC ;MSH134 STD R0,R5 ;;;MOVE SIXTH FACC INTO POSITION ;MSH134 LDD (SP)+,R0 ;;;LOAD FIFTH FACC INTO FIRST FACC ;MSH134 STD R0,R4 ;;;MOVE FIFTH FACC INTO POSITION ;MSH134 LDD (SP)+,R3 ;;;LOAD FOURTH FACC ;MSH134 LDD (SP)+,R2 ;;;LOAD THIRD FACC ;MSH134 LDD (SP)+,R1 ;;;LOAD SECOND FACC ;MSH134 LDD (SP)+,R0 ;;;LOAD FIRST FACC ;MSH134 LDFPS (SP)+ ;;;RESTORE FLOATING POINT STATUS ;**-9 .ENDC 5$: ;;; ;MSH149 .IF DF M$$MGE BIS #PMODE,PS ;;;SET PREVIOUS MODE TO USER MOV #KISAR0,R0 ;;;POINT TO KERNEL ADDRESS REGISTER 0 MOV #KISDR0,R1 ;;;POINT TO KERNEL DESCRIPTOR REGISTER 0 MOV #UISAR0,R2 ;;;POINT TO USER ADDRESS REGISTER 0 MOV #UISDR0,R3 ;;;POINT TO USER DESCRIPTOR REGISTER 0 MOV #8.,R4 ;;;SET LOOP COUNT 10$: MOV (SP)+,(R3)+ ;;;RESTORE USER DESCRIPTOR REGISTER MOV (SP)+,(R2)+ ;;;RESTORE USER ADDRESS REGISTER MOV #77406,(R1)+ ;;;RESTORE KERNEL DESCRIPTOR REGISTER MOV (SP)+,(R0)+ ;;;RESTORE KERNEL ADDRESS REGISTER DEC R4 ;;;ANY MORE TO RESTORE? BGT 10$ ;;;IF GT YES INC SR0 ;;;TURN ON MEMORY MANAGEMENT MTPI SP ;;;RESTORE USER STACK POINTER .IF DF M$$EXT TST $UMRPT ;;;UNIBUS MAP EXISTS? ;MSH097 BEQ 35$ ;;;IF EQ NO, SKIP INITIALIZING IT ;MSH097 MOV #UBMPR,R0 ;;;POINT TO FIRST MAP REGISTER MOV #5.,R1 ;;;SET COUNT OF EXEC REGISTERS CLR R2 ;;;CLEAR STARTING ADDRESS 20$: MOV R2,(R0)+ ;;;LOAD LOW 16 BITS OF ADDRESS CLR (R0)+ ;;;CLEAR HIGH 6 BITS OF ADDRESS ADD #20000,R2 ;;;ADVANCE 8K BYTES DEC R1 ;;;ANY MORE TO LOAD? BGT 20$ ;;;IF GT YES MOV #31.-5.,R1 ;;;SET COUNT OF REGISTERS 30$: MOV (SP)+,(R0)+ ;;;RESTORE LOW 16 BITS OF ADDRESS MOV (SP)+,(R0)+ ;;;RESTORE HIGH 6 BITS OF ADDRESS DEC R1 ;;;ANY MORE REGISTERS BGT 30$ ;;;IF GT YES 35$: MOV #60,SR3 ;;;ENABLE 22 BIT AND UNIBUS MAP ;MSH097 ;**-1 .ENDC .IFF .IF DF E$$EAE MOV (SP)+,MQ ;;;RESTORE EAE MULTIPLIER-QUOTIENT MOV (SP)+,AC ;;;RESTORE EAE ACCUMULATOR MOV (SP)+,SC ;;;RESTORE EAE SHIFT COUNT .ENDC .ENDC .IF DF L$$SI1 ;MSH181 ;MSH181 MOV (SP)+,@#14 ;;;RESTORE BPT/T-BIT VECTOR CONTENTS ;MSH181 ;MSH181 .ENDC  ;MSH181 MOV (SP)+,R0 ;;;RESTORE R0 THRU R5 MOV (SP)+,R1 ;;; MOV (SP)+,R2 ;;; MOV (SP)+,R3 ;;; MOV (SP)+,R4 ;;; MOV (SP)+,R5 ;;; MOV (SP),SP ;;;RESTORE STACK POINTER INC $PWRFL ;;;INDICATE A POWER FAILURE HAS OCCURED MOV #$HEADR,$RQSCH ;;;FORCE REDISPATCHING MOV #PDOWN,PWVCT ;;;SWITCH TO POWER DOWN ROUTINE MOV #40$,-(SP) ;;;GIVE A RETURN ADDRESS FOR $SGFIN CALL $SGFIN ;;;PLUG VECTORS (IF NO CLOCK) MOV $CKLDC,@$CKCNT ;;;RELOAD CLOCK COUNT REGISTER MOV #K$$IEN,@$CKCSR ;;;TURN CLOCK BACK ON RETURN ;;;RETURN TO $SGFIN, WHICH WILL RETURN TO 40$ 40$: RTI ;;; ;+ ; **-$POWER-POWER FAIL RECOVERY ; ;- .IFTF .ENABL LSB $POWER::CLR $PWRFL ;CLEAR FAILURE INDICATOR CALL $DRDSE ;DECLARE A SIGNIFICANT EVENT .IF DF K$$W11 MOV $WTCSR,R0 ;GET WATCHDOG TIMER CSR POINTER ;MSH156 CLR 2(R0) ;CLEAR CLOCK ERROR FLAGS ;MSH156 MOV #1,6(R0) ;ENERGIZE OUTPUT RELAY ;MSH156 ;**-2 .ENDC .IF DF P$$RTY CALL $CLPAR ;CLEAR MEMORY PARITY CSR'S MOV $MPCSR+6,R0 ;PICK UP CACHE CSR REGISTER ;MSH127 ;**-1 .IF DF C$$CHE ;MSH127 ;**-1 BIC #^C<14>,(R0) ;PRESERVE FORCE MISS BITS MOV (R0),$MPCTL ;SAVE PARITY CONTROL REGISTER ;MSH127 ;**-1 .IFF MOV #3,(R0) ;DISABLE TRAPS .ENDC MOV #177777,-(R0) ;CLEAR MEMORY ERROR REGISTER .ENDC .IF DF E$$LOG ;DTB009 ;DTB009 BIT #ES.DAT,$ERFLA ;ARE WE LOGGING? ;DTB009 BEQ 6$ ;IF EQ NO ;DTB009 MOV #E$CSYS+,R0 ;GET ERROR CODE ;DTB009 CLR R1 ;NO DATA SUBPACKET ;DTB009 MOV #SM.HDR,R2 ;ONLY A HEADER SUBPACKET ;DTB009 CALL $CRPKT ;CREATE THE PACKET ;DTB009 BCS 6$ ;IF CS ALLOCATION FAILURE ;DTB009 CALL $QUPKT ;QUEUE THE PACKET ;DTB009 6$: ;DTB009 ;**-8 .ENDC ; ; EFFECT POWERFAIL AST'S FOR TASKS THAT ARE ACTIVE AND IN CORE ; .IFT .IF DF A$$TRP MOV $ACTHD,R5 ;GET ADDRESS OF FIRST TCB 10$: MOV #AS.PFA,R4 ;SET POWERFAIL TYPE AST MOV T.ACTL(R5),-(SP) ;SAVE POINTER TO NEXT ACTIVE TASK BEQ 15$ ;IF EQ THERE IS NONE CALL $DASTT ;DECLARE POWERFAIL AST 15$: MOV (SP)+,R5 ;GET ADDRESS OF NEXT ACTIVE TASK BNE 10$ ;IF NE NO .ENDC .IFTF ;MSH128 ;MSH128 ; ;MSH128 ; DO POWERFAIL RECOVERY FOR THE NETWORK ;MSH128 ; ;MSH128 ;MSH128 .IF DF M$$NET ;MSH128 ;MSH128 MOV $NETPF,R5 ;GET NETWORK POWERFAIL ROUTINE ADDRESS ;MSH128 BEQ $DRVPF ;IF EQ THERE IS NONE ;MSH128 CALL (R5) ;RECOVER FROM POWERFAIL ;MSH128 ;MSH128 .ENDC ;MSH128 ;MSH128 ; ;**-1 ; DO POWERFAIL RECOVERY FOR ALL ACTIVE DEVICES ; $DRVPF::MOV #$SCDVT,-(SP) ;SCAN THE DEVICE TABLES (CO-ROUTINE) ;MSH119 30$: CALL @(SP)+ ;GET NEXT UCB ADDRESS ;**-3 BCC 40$ ;IF CC GOT ONE RETURN ; 40$: BITB #US.OFL,U.ST2(R5) ;DEVICE IN CONFIGURATION? BNE 30$ ;IF NE NO BITB #UC.PWF,U.CTL(R5) ;CALL DRIVER REGARDLESS OF ACTIVITY? BNE 50$ ;IF NE YES TSTB U.STS(R5) ;IS UNIT ACTIVE? BPL 30$ ;IF PL NO 50$: MOV D.DSP(R3),R2 ;GET ADDRESS OF DRIVER DISPATCH TABLE BEQ 30$ ;IF EQ DRIVER NOT LOADED .IF DF L$$DRV&M$$MGE $LDPWF::MOV KISAR5,-(SP) ;SAVE APR5 (REF LABEL FOR 'LOAD') MOV D.PCB(R3),R3 ;GET DRIVER PCB ADDRESS BEQ 55$ ;IF EQ DRIVER IS PART OF EXEC MOV P.REL(R3),KISAR5 ;MAP THE DRIVER 55$: ; .IFTF MOVB S.CON(R4),R3 ;GET CONTROLLER INDEX ; ; CALL DRIVER AT POWERFAIL ENTRY POINT WITH THE ARGUMENTS: ; ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; CALL @D.VPWF(R2) ;ENTER DRIVER .IFT MOV (SP)+,KISAR5 ;RESTORE APR5 .ENDC BR 30$ ;GO AGAIN ;MSH181 .IFT ;P$$RFL ;MSH181 ;MSH181 .IF DF L$$SI1 ;MSH181 ;MSH181 ; ;MSH181 ; SUBROUTINE TO INTERCEPT UNEXPECTED T-BIT TRAPS AFTER LSI POWER UP. ;MSH181 ; THIS ROUTINE CLEARS THE T-BIT IN THE SAVED PS ON THE STACK AND ;MSH181 ; DISMISSES THE TRAP. ;MSH181 ; ;MSH181Ä ;MSH181 $TBIT:: BIC #20,2(SP) ;;;CLEAR T-BIT IN SAVED PS ;MSH181 RTI ;;;DISMISS THE TRAP ;MSH181 ;MSH181 .ENDC ;MSH181 .ENDC .DSABL LSB .END Ä:dè€kQ ›c, .TITLE PARTY .IDENT /10.07/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 10.07 ; ; D. N. CUTLER 14-FEB-74 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 9-APR-80 ; MSH094 -- CLEAN UP AND ENHANCE PARITY CODE ; ; M. S. HARVEY 13-NOV-80 ; MSH127 -- CLEAN UP CACHE MEMORY CONDITIONALIZATION ; ; DAN BROWN 7-JAN-80 ; DTB007 -- MODIFY FOR NEW ERROR LOGGER ; ; M. S. HARVEY 4-NOV-81 ; MSH200 -- PASS TCB ADDRESS TO ERROR LOGGING SUBSYSTEM ; ; M. S. HARVEY 5-NOV-81 ; MSH201 -- PASS CSR EXISTENCE BITMASK TO ERROR LOGGER ; ; MSH202 -- MAKE SURE REGISTERS ARE AVAILABLE FOR ; USER-WRITTEN CODE ON KERNEL MODE CACHE ; PARITY ERROR ; ; ; ; MEMORY PARITY INTERRUPT HANDLING ; ; MACRO LIBRARY CALLS ; .IF DF P$$RTY .MCALL ABODF$,HWDDF$,PCBDF$,TCBDF$,EPKDF$ ;MSH094 ABODF$ ;DEFINE TASK ABORT CODES ;**-1 HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS EPKDF$ ;DEFINE ERROR LOG PACKET OFFSETS ;DTB007 ; ; LOCAL DATA ; ; EXEC PARITY ERROR MESSAGE ; EXMSG: .ASCIZ <15><12>/***EXEC PARITY ERROR STOP***/<15><12><12> ; ; ; INTERRUPT RECURSION LEVEL COUNTER ; PARLV: .WORD -1 ; ; ; PARITY CONTROL STATUS REGISTER ADDRESS TABLE ; .WORD 77 ;CACHE CSR BIT MASK (PRESENCE ASSUMED) ;MSH201 .WORD 177777 ;MEMORY CSR BIT MASK (PRESENCE ASSUMED) ;MSH201 $PARTB::.WORD 1 ;DUMMY CSR FOR NONEXISTANT REGISTERS ;**-1 .BLKW 16. ;MEMORY PARITY CSR TABLE .WORD $MPCSR ;POINT TO 11/70 CSR TABLE ; ; CACHE MEMORY PARITY STATUS TABLE ;MSH127 ; ;**-1 .IF DF C$$CHE ;MSH127 ;**-1 .IF DF E$$LOG ;DTB007 ;**-1 MSTAT: .BLKW 2 ;FIRST TWO PARITY CSR'S STAT: .BLKW 1 ;MEMORY STATUS REGISTER .BLKW 3 ;LAST THREE PARITY CSR'S .IFF STAT: .BLKW 1 ;MEMORY STATUS REGISTER .ENDC ERTRK: .BYTE 44,120 ;ADDRESS/DATA GROUP 0 .WORD 0 ;TIME OF LAST ERROR .BYTE 30,240 ;ADDRESS/DATA GROUP 1 .WORD 0 ;TIME OF LAST ERROR .WORD 0 ;END OF TABLE ; ; NEW CACHE PARITY CSR CONTENTS ; $MPCTL::.BLKW 1 ; .ENDC ; ; VECTOR OF CACHE CSR ADDRESSES ; $MPCSR::.BLKW 6 ;ALL SIX REGISTERS .WORD 0 ;TERMINATOR LINK FOR INITL AND SAVE ; ; PARITY VECTOR ; .ASECT .=114 .WORD $PARER .WORD PR7 ; .PSECT ;+ ; **-$PARER-MEMORY PARITY ERROR INTERRUPT ; ; THIS ROUTINE IS ENTERED AS THE RESULT OF A MEMORY PARITY ERROR INTERRUPT. IF ; THE ERROR OCCURED IN THE EXECUTIVE OR WHILE ON THE SYSTEM STACK, THEN A ; MESSAGE IS PRINTED ON THE CONSOLE TERMINAL AND THE SYSTEM IS HALTED. ; ELSE A SWITCH TO THE SYSTEM STACK IS EXECUTED AND THE TASK IN WHICH ; THE PARITY ERROR OCCURED IS LOCKED IN MEMORY. ;- .ENABL LSB RECURS: JMP 60$ ;;;JUMP TO HALT PROCESSOR $PARER:: ;;;REF LABEL .IF DF C$$CHE ;MSH127 ;**-1 .IF DF E$$LOG ;MSH094 ;MSH094 MOV @$MPCSR+6,MSTAT+6 ;;;SAVE MEMORY CONTROL REGISTER ;MSH094 ;MSH094 .ENDC ;MSH094 ;MSH094 BIS #3,@$MPCSR+6 ;;;TURN CACHE TRAPS OFF .IFTF ;C$$CHE ;MSH127 ;**-1 INC PARLV ;;;INTERRUPT RECURSION? BNE RECURS ;;;IF NE YES .IFT ;C$$CHE ;MSH127 ;**-1 MOV R0,-(SP) ;;;SAVE R0 MOV R1,-(SP) ;;;SAVE R1 .IF DF E$$LOG ;DTB007 ;**-1 MOV #$MPCSR,R0 ;POINT TO PARITY CSR TABLE MOV #MSTAT,R1 ;POINT TO PARITY CSR SAVE AREA MOV @(R0)+,(R1)+ ;SAVE LOW ADDRESS REGISTER MOV @(R0)+,(R1)+ ;SAVE HIGH ADDRESS REGISTER .IFF MOV #$MPCSR+4,R0 ;POINT INTO PARITY CSR TABLE MOV #STAT,R1 ;POINT TO STATUS WORD SAVE AREA .IFTF MOV #-1,(R1) ;ASSUME MEM PARITY ON NONCACHE MACHINE CMP (R0)+,#MPCSR-2 ;RUNNING ON CACHE MACHINE? BNE 2$ ;IF NE NO MOV @-2(R0),(R1)+ ;SAVE MEMORY ERROR REGISTER ;MSH094 ;**-2 .IFT CMP (R0)+,(R1)+ ;SKIP MEMORY CONTROL REGISTER ;MSH094 MOV @(R0)+,(R1)+ ;SAVE MAINTENANCE REGISTER ;**-1 MOV @(R0)+,(R1)+ ;SAVE CACHE HIT REGISTER .ENDC 2$: MOV (SP)+,R1 ;;;RESTORE R1 MOV (SP)+,R0 ;;;RESTORE R0 .IFTF .IF DF M$$MGE BIT #CMODE,2(SP) ;;;PREVIOUS MODE USER? BNE 4$ ;;;IF NE YES .IFF CMP (SP),$EXSIZ ;;;PARITY ERROR PC IN EXEC? BLO 3$ ;;;IF LO YES TST $STKDP ;;;PARITY ERROR ON SYSTEM STACK? BGT 4$ ;;;IF LE YES .ENDC .IFT 3$: TST STAT ;;;FATAL MEMORY ERROR? BLE 20$ ;;;IF LE YES DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY ;MSH202 MOV #ERTRK,R1 ;POINT TO ERROR TRACKING TABLE ;MSH202 CALL 14$ ;EXECUTE CACHE ALGORITHM ;MSH202 CALL MECLR ;RESET PARITY CSR'S ;MSH094 BR 9$ ;RETURN FROM PARITY TRAP ;MSH202 ;**-7 .IFF 3$: BR 20$ ;;;FATAL MEMORY PARITY ERROR .IFTF 4$: DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY ; ; LOG PARITY ERROR IN TASK ; ; THE DATA SUBPACKET CONTAINS THE FOLLOWING INFORMATION: ;DTB007 ; ;DTB007 ; WD.00 - (15:6) RESERVED, (5:0) BITMAP INDICATING WHICH ;MSH201 ; CACHE CSRS ARE PRESENT ON THE SYSTEM ;MSH201 ; WD.01 - MEMORY PARITY CSR BITMAP INDICATING WHICH CSRS ;MSH201 ; EXIST ON THE SYSTEM ;MSH201 ; WD.02 THRU WD.17- CONTENTS OF THE MEMORY PARITY CSRS ;MSH201 ; WD.18 THRU WD.23- CONTENTS OF CACHE CSRS ;MSH201 ; ;DTB007 ;DTB007 ;DTB007 .IF DF E$$LOG ;DTB007 ;DTB007 BIT #ES.LOG,$ERFLA ;ARE WE LOGGING ERRORS? ;DTB007 BEQ 8$ ;NO, SO IGNORE THIS ;DTB007 INC $ERRSQ ;COUNT ONE MORE ERROR IN SYSTEM ;DTB007 MOV #E$CCPU+,R0 ;GET THE ERROR CODE ;DTB007 MOV #24.*2,R1 ;GET THE SIZE OF THE DATA SUBPACKET ;MSH201 MOV #SM.HDR!SM.TSK!SM.DAT,R2 ;GET THE CONTROL MASK ;DTB007 CLR R3 ;NO BEGINNING ADDRESS FOR DATA ;DTB007 MOV $TKTCB,R4 ;LOAD CURRENT TASK TCB ADDRESS ;MSH200 CLR R5 ;NO UCB ;DTB007 CALL $CRPKT ;CREATE THE PACKET ;DTB007 BCS 8$ ;IF CS POOL ALLOCATION FAILURE ;DTB007 ;DTB007 MOV #$PARTB-4,R2 ;POINT TO CSR BITMAPS ;MSH201 MOV (R2)+,(R1)+ ;STORE CACHE CSR BIT MAP ;MSH201 MOV (R2)+,(R1)+ ;STORE PARITY CSR BIT MAP ;MSH201 TST (R2)+ ;SKIP DUMMY CSR WORD ;MSH201 6$: MOV @(R2)+,(R1)+ ;STORE MEMORY PARITY CSR CONTENTS ;DTB007 CMP R2,#$PARTB+2+<16.*2> ;DONE YET? ;DTB007 BLO 6$ ;IF LO NO ;DTB007 ;DTB007 .IF DF C$$CHE ;DTB007 ;DTB007 TST (R2)+ ;POINT TO CACHE PARITY CSR'S ;DTB007 7$: MOV (R2)+,(R1)+ ;STORE SAVED CACHE CSR CONTENTS ;DTB007 CMP R2,#MSTAT+14 ;DONE YET? ;**-62 BLO 7$ ;IF LO NO .ENDC ;DTB007 CALL $QUPKT ;QUEUE ERROR MESSAGE BLOCK ;DTB007 8$: ;REF LABEL ;**-3 .ENDC .IFTF ;MSH094 ;MSH094 ; ;MSH094 ; CLEAR ALL PARITY REGISTERS AND REENABLE FOR PARITY ERRORS ;MSH094 ; ;MSH094 ;MSH094 CALL $CLPAR ;RESET ALL PARITY CSR'S ;MSH094 .IFT  MOV #ERTRK,R1 ;POINT TO ERROR TRACKING TABLE TST STAT ;WAS IT ONLY A CACHE ERROR? BLE 10$ ;IF LE NO ;MSH202 CALL 14$ ;EXECUTE CACHE ALGORITHM ;MSH202 9$: DEC PARLV ;RESET RECURSION LEVEL ;MSH202 RETURN ;EXIT FROM PARITY ERROR PROCESSING ;MSH202 ;**-2 .IFTF ; ;**-6 ; FREEZE CURRENT TASK IN MEMORY AND THEN ABORT TASK ; 10$: MOV $TKTCB,R1 ;GET TCB ADDRESS OF CURRENT TASK ;MSH202 BIS #T2.FXD,T.ST2(R1) ;FIX TASK IN MEMORY ;**-1 BIC #T3.REM,T.ST3(R1) ;CLEAR REMOVE ON EXIT BIT .IF DF D$$SHF MOV T.PCB(R1),R0 ;GET ADDRESS OF TASK PCB BIT #PS.SYS,P.STAT(R0) ;SYSTEM CONTROLLED PARTITION? BEQ 11$ ;IF EQ NO BIS #PS.NSF,P.STAT(R0) ;FREEZE PARTITION FOR SHUFFLER .ENDC 11$: MOV #S.PRTY,R0 ;SET REASON FOR ABORT CALL $ABTSK ;ABORT TASK ;MSH202 .IFF ;MSH202 ;MSH202 DEC PARLV ;RESET RECURSION LEVEL ;MSH202 .IFT CALL 16$ ;DO FINAL PARITY ERROR PROCESSING ;MSH202 BR 9$ ;ALL DONE ;MSH202 ;**-1 ; ; PDP-11/70 CACHE TRAP ; 12$: MOV $TTNS-4,-(R1) ;;;SAVE TIME OF LAST ERROR 13$: TST (R1)+ ;;;POINT TO NEXT GROUP 14$: MOVB (R1)+,R0 ;;;GET CACHE DISABLE BITS BEQ 16$ ;;;IF EQ END OF TABLE BITB (R1)+,STAT ;;;ERROR IN THIS GROUP? BEQ 13$ ;;;IF EQ NO CMP (R1)+,$TTNS-4 ;;;OCCUR IN SAME MINUTE? BNE 12$ ;;;IF NE NO BIS R0,$MPCTL ;;;DISABLE THAT PART OF CACHE BR 14$ ;;;PROCESS NEXT GROUP 16$: MOV $MPCTL,@$MPCSR+6 ;RELOAD 11/70 PARTIY CSR ;**-1 .ENDC ; ; AT THIS POINT EVERYTHING HAS BEEN CLEANED UP AND THE USER MAY ; INSERT CODE SPECIFIC TO HIS APPLICATION. ; ;*************** ; INSERT CODE HERE-ALL REGISTERS ARE AVAILABLE ;*************** ;MSH202 RETURN ;EXIT FROM TRAP ;**-5 ; ; PARITY ERROR OCCURED WHILE IN EXEC CODE. THIS IS A FATAL SITUATION ; AND THE SYSTEM IS SHUT DOWN. THE USER MAY INSERT CODE SPECIFIC ; TO HIS APPLICATION AT THIS POINT. ; 20$: ;;;REF LABEL ;;;*************** ;;; INSERT CODE HERE-ALL REGISTERS HAVE NOT BEEN SAVED ;;;*************** MOV #60$,@#4 ;;;PLUG NONEX MEMORY VECTOR MOV R0,-(SP) ;;;SAVE R0 MOV #EXMSG,R0 ;;;GET ADDRESS OF PARITY STOP MESSAGE 30$: MOVB (R0)+,TPS+2 ;;;OUTPUT NEXT BYTE BEQ 50$ ;;;IF EQ DONE 40$: TSTB TPS ;;;OUTPUT DONE? BPL 40$ ;;;IF PL NO BR 30$ ;;;GO AGAIN 50$: MOV (SP)+,R0 ;;;RESTORE R0 60$: HALT ;;;HALT SYSTEM BR 60$ ;;;IF CONTINUED HALT AGAIN .DSABL LSB ;+ ; **-$CLPAR-CLEAR PARITY REGISTERS ; ; THIS ROUTINE CLEARS OUT ALL PARITY ERRORS IN THE MEMORY PARITY ERROR ; REGISTERS AND ENABLES PARITY ERROR NOTIFICATION. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; NONE. ; ; NOTE: IF THE SYMBOL M$$K11 IS DEFINED (11/70 TYPE ECC MEMORY), ; THIS ROUTINE WILL NOT PROPERLY HANDLE UNIBUS ECC MEMORY ; (SUCH AS MF11S-K) SINCE THE ROUTINE ASSUMES THAT ANY ; OTHER MEMORY ON THE SYSTEM MUST BE PARITY MEMORY AND ; THAT AN ATTEMPT TO SET THE SINGLE-BIT ECC ERROR BIT ON ; SUCH A MEMORY WILL FAIL. THIS ASSUMPTION IS USED TO ; DISTINGUISH MK11 ECC MEMORY FROM PARITY MEMORY. ;- $CLPAR::MOV #$PARTB+2,R0 ;POINT TO PARITY CSR VECTOR 10$: ;REF LABEL .IF DF M$$K11 TST (R0) ;EVEN WORD CSR PRESENT? BPL 20$ ;IF PL NO MOV #21,@(R0)+ ;SET ENABLE AND SINGLE-BIT ECC ERROR BIT #20,@-(R0) ;SINGLE-BIT ECC ERROR BIT SET (MK11)? BEQ 20$ ;IF EQ NO MOV #1,@(R0)+ ;SET ENABLE BIT AND CLR REST IN 1ST WORD BIC #100000,@(R0)+ ;CLEAR ERROR BIT IN SECOND WORD BR 30$ ; 20$: MOV #1,@(R0)+ ;ENABLE PARITY ERROR NOTIFICATION .ENDC MOV #1,@(R0)+ ;ENABLE PARITY (OR UNIBUS MEM ECC) NOTIF 30$: CMP R0,#$PARTB+2+<16.*2> ;DONE YET? BLO 10$ ;IF LO NO .IF DF C$$CHE ;MSH127 ;**-1 MECLR: MOV @$MPCSR+4,-(SP) ;CLEAR MEMORY SYSTEM ERROR REGISTER MOV (SP)+,@$MPCSR+4 .ENDC RETURN ; .ENDC .END ³}kQ ›c, .TITLE TDSCH .IDENT /09.11/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 09.11 ; ; D. N. CUTLER 11-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; ; MODIFIED BY: ; ; M. S. HARVEY 16-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 3-FEB-81 ; MSH132 -- DEFINE C.SYST CLOCK BLOCK CODE FOR USE BY ; CINT$ INTERRUPT ROUTINES ; ; M. S. HARVEY 5-MAR-81 ; MSH156 -- ADD TRANSPORTABILITY SUPPORT FOR THE ; WATCHDOG TIMER ; ; M. S. HARVEY 3-APR-81 ; MSH098 -- ADD SUPPORT FOR DYNAMIC SYSTEM TUNING ; ; M. S. HARVEY 6-AUG-81 ; MSH184 -- IMPLEMENT SHUFFLER RUN LIMITING ; ; M. S. HARVEY 10-NOV-81 ; MSH204 -- REDUCE CHANCES OF T1 TIMEOUT ; ; TIME DEPENDENT SCHEDULING AND DEVICE TIME OUT ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$,HDRDF$,HWDDF$,TCBDF$,PCBDF$ CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSET HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS ; ; LOCAL DATA ; .IF DF R$$NDC RNDCT: .WORD R$$NDC ;CLOCK TICKS TO NEXT SCHEDULE INTERVAL .ENDC .IF DF S$$WPC&D$$ISK SWPCT: .WORD S$$WPC ;CLOCK TICKS TO NEXT SWAPPING INTERVAL .ENDC ;+ ; **-$CKINT-CLOCK INTERRUPT ; ; THIS ROUTINE IS ENTERED AS THE RESULT OF A CLOCK INTERRUPT. $INTSV ; IS CALLED TO SAVE REGISTERS R4 AND R5 AND $INTCT IS INCREMENT. IF ; THE RESULT IS NONZERO, THEN A JUMP TO $INTXT IS EXECUTED. ELSE ; A FORK IS EXECUTED SO THAT PENDING CLOCK INTERRUPTS CAN BE PRO- ; CESSED. ; ;MSH204 ; NOTE THAT IF A WATCHDOG TIMER EXISTS, PUNCH ITS CSR AT PR7 LEVEL. ;MSH204 ; THIS ENSURES THAT THE WATCHDOG TIMER IS NOT ACCESSED TOO OFTEN ;MSH204 ; BY NOT ALLOWING THE NESTING OF CLOCK INTERRUPTS TO DELAY TIMER ;MSH204 ; ACCESS. SUCH A DELAY COULD RESULT IN MULTIPLE ACCESSES BEFORE ;MSH204 ; THE T1 TIMEOUT. ;MSH204 ;- $CKINT:: ;;;CLOCK INTERRUPT SERVICE ROUTINE ;MSH204 ;MSH204 .IF DF K$$W11 ;MSH204 ;MSH204 MOV #3,@$WTCSR ;;;ENABLE AND START TIMER ;MSH156 ;MSH204 .ENDC ;MSH204 ;MSH204 CALL $INTSV,PR6 ;;;SAVE REGISTERS AND SET PRIORITY ;MSH204 MOV #$INTCT,R4 ;;;POINT TO INTERRUPT COUNT ;**-10 INC (R4) ;;;INCREMENT INTERRUPT COUNT BEQ 10$ ;;;IF EQ FORK RETURN ;;;EXIT FROM INTERRUPT 10$: CALL $FORK0 ;;;EXECUTE FORK ; ; UPDATE ABSOLUTE AND REAL TIME OF DAY AND DATE ; UPTIM: MOV #$TKPS+2,R4 ;POINT PAST CONVERSION VECTOR MOV #$TTNS+2,R5 ;POINT PAST CURRENT TIME VECTOR 10$: MOV #$TTNS-10,R2 ;POINT TO DAY INC -(R5) ;UPDATE A COUNTER CMP -(R4),(R5) ;EXCEEDED LIMIT? BHI 20$ ;IF HI NO CLR (R5) ;RESET COUNTER CMP R5,R2 ;CHECK FOR LAST DAY OR MONTH BHI 10$ ;IF HI NO INC (R5) ;DAY AND MONTH ARE 1 ORIGIN BCS 10$ ;IF CS NOT DAY MOV -(R2),R1 ;GET CURRENT MONTH MOVB $DYPMN-1(R1),R0 ;GET DAYS FOR NEXT MONTH PLUS 1 MOV R0,(R4) ;MOVE TO DAYS PER MONTH LIMIT DEC R1 ;IS CURRENT MONTH ENDING JANUARY? BNE 10$ ;IF NE NO BIT #3,-(R2) ;IS THIS A LEAP YEAR? BNE 10$ ;IF NE NO INC (R4) ;INCREMENT DAYS FOR FEBRUARY BR 10$ ; 20$: ; ;MSH184 ;MSH184 .IF DF D$$YNM&D$$SHF ;MSH184 ;MSH184 TST $SHFTM ;SHUFFLER RUN LIMITER EXPIRED? ;MSH184 BEQ 30$ ;IF EQ YES ;MSH184 DEC $SHFTM ;RUN DOWN THE LIMITER TIMER ;MSH184 ;MSH184 .ENDC ;MSH184 ;MSH184 30$: INC $ABTIM ;UPDATE ABSOLUTE TIME COUNTER ;MSH184 BNE TDS ;IF NE NO OVERFLOW ;**-1 MOV #$CLKHD,R0 ;POINT TO CLOCK QUEUE LISTHEAD 40$: MOV (R0),R0 ;GET ADDRESS OF NEXT ENTRY BEQ TDS ;IF EQ NO MORE IN LIST DEC C.TIM+2(R0) ;ADJUST HIGH ORDER TIME BR 40$ ; ; ; TIME DEPENDENT SCHEDULING ; TDS: MOV $CLKHD,R4 ;GET ADDRESS OF NEXT IN QUEUE BEQ DVOUT ;IF EQ NONE IN LIST TST C.TIM+2(R4) ;HIGH ORDER PART NONZERO? BNE DVOUT ;IF NE YES CMP $ABTIM,C.TIM(R4) ;TIME TO GO? BLO DVOUT ;IF LO NO MOV (R4),$CLKHD ;REMOVE ENTRY FROM CLOCK QUEUE MOVB C.RQT(R4),R5 ;GET ENTRY REQUEST TYPE ADD R5,PC ;DISPATCH TO PROCESSING ROUTINE 10$: BR 20$ ;MARK TIME REQUEST BR 30$ ;TASK REQUEST WITH PERIODIC RESCHEDULE BR 30$ ;SINGLE SHOT TASK REQUEST BR 15$ ;SINGLE SHOT INTERNAL SUBROUTINE .IF DF D$$SHF&D$$YNM BR 15$ ;SINGLE SHOT INTERNAL SUBROUTINE ; ; CLEAR STOP BIT AND REALLOCATE PARTITION ; MOV C.TCB(R4),R0 ;PICK UP TCB ADDRESS CALL $EXRQN ;CLEAR STOP BIT AND REALLOCATE PARTITION BR TDS ; .ENDC ; ; SINGLE SHOT INTERNAL SYSTEM SUBROUTINE (TYPE 6 OR 8) ; 15$: ; .IF DF L$$DRV&M$$MGE!C$$INT&M$$MGE ;MSH132 ;**-1 MOV KISAR5,-(SP) ;SAVE APR5 MOV C.AR5(R4),KISAR5 ;MAP TO SYSTEM ROUTINE (DRIVER) .IFTF CALL @C.SUB(R4) ;CALL SYSTEM SUBROUTINE .IFT MOV (SP)+,KISAR5 ;RESTORE APR5 .ENDC BR TDS ; ; ; MARK TIME REQUEST ; 20$: MOV C.SRC(R4),R0 ;PICK UP EVENT FLAG MASK WORD MOV C.DST(R4),R1 ;PICK UP EVENT FLAG MASK ADDRESS MOV C.TCB(R4),R5 ;PICK UP TCB ADDRESS CALL $SETMG ;SET EFN AND UNLOCK IF GROUP GLOBAL ;MSH049 CLR R5 ;RESET CLOCK BLOCK TYPE ;**-1 .IF DF A$$TRP MOV C.AST(R4),R3 ;GET AST TRAP ADDRESS BEQ 40$ ;IF EQ NO AST SPECIFIED MOVB C.EFN(R4),R2 ;GET EFN NUMBER MOV R4,R1 ;COPY ADDRESS OF CLOCK QUEUE ENTRY TST (R4)+ ;POINT TO CONTROL BLOCK LENGTH MOV #C.LGTH,(R4)+ ;SET LENGTH OF AST CONTROL BLOCK MOV #8.*2,(R4)+ ;SET BYTES TO ALLOCATE ON TASK STACK MOV R3,(R4)+ ;INSERT AST TRAP ADDRESS MOV #1,(R4)+ ;SET NUMBER OF AST PARAMETERS MOV R2,(R4) ;INSERT EFN AS AST PARAMETER CALL $QASTT ;QUEUE AST TO TASK BR TDS ; .IFF BR 40$ ;RELEASE CLOCK CONTROL BLOCK .ENDC ; ; SCHEDULE REQUEST ; 30$: MOV C.TCB(R4),R0 ;GET TASK TCB ADDRESS MOV C.UIC(R4),R1 ;GET REQUEST UIC CALL $TSKRT ;REQUEST TASK EXECUTION 40$: MOV R4,R0 ;SET ADDRESS OF BLOCK TO RELEASE CMPB #C.SCHD,R5 ;PERIODIC REQUEST? BEQ 50$ ;IF EQ YES CALL $DECLK ;DEALLOCATE CONTROL BLOCK BR TDS ; 50$: MOV C.RSI+2(R0),R1 ;SET HIGH ORDER PART OF TIME MOV C.RSI(R0),R2 ;SET LOW ORDER PART OF TIME MOV R5,R4 ;SET REQUEST TYPE MOV C.TCB(R0),R5 ;SET ADDRESS OF REQUEST TASK TCB CALL $CLINS ;REINSERT ENTRY IN CLOCK QUEUE BR TDS ; ; ; DEVICE TIME OUT ; DVOUT: TST $TTNS ;ONE SECOND ELAPSED? BNE ROBIN ;IF NE NO MOV #$SCDVT,-(SP) ;SET ADDRESS OF DEVICE TABLE SCANNING CO-ROUTINE 10$: CALL @(SP)+ ;GET NEXT UCB ADDRESS BCS ROBIN ;IF CS END OF TABLE MTPS S.PRI(R4) ;;;RAISE PRIORITY TO DEVICE LEVEL TSTB U.STS(R5) ;;;UNIT BUSY? BPL 20$ ;;;IF PL NO TSTB S.CTM(R4) ;;;TIMEOUT ACTIVE? BEQ 20$ ;;;IF EQ NO DECB S.CTM(R4) ;;;DECREMENT TIMEOUT COUNT BNE 20$ ;;;IF NE MORE TIME TO GO MOV #IE.DNR&377,R0 ;;;SET DEVICE TIMEOUT STATUS MOV D.DSP(R3),R1 ;;;GET ADDRESS OF DRIVER DISPATCH TABLE MOV S.CSR(R4),R2 ;;;GET ADDRESS OF DEVICE CSR  .IF DF L$$DRV&M$$MGE MOV KISAR5,-(SP) ;;;SAVE APR5 MOV D.PCB(R3),R3 ;;;GET DRIVER PCB ADDRESS BEQ 15$ ;;;IF EQ DRIVER IS PART OF EXEC MOV P.REL(R3),KISAR5 ;;;MAP THE DRIVER 15$: ;;; .IFTF MOVB S.CON(R4),R3 ;;;GET CONTROLLER INDEX ; ; CALL DRIVER AT TIMEOUT ENTRY POINT WITH THE ARGUMENTS: ; ; R0=DEVICE TIMEOUT STATUS 'IE.DNR'. ; R2=ADDRESS OF DEVICE CSR. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; CALL @D.VOUT(R1) ;;;ENTER DRIVER .IFT MOV (SP)+,KISAR5 ;;;RESTORE APR5 .ENDC 20$: MTPS #0 ;;;ALLOW INTERRUPTS BR 10$ ;GO AGAIN ; ; EXECUTIVE LEVEL ROUND ROBIN SCHEDULING ; ROBIN: ;REF LABEL .IF DF R$$NDC DEC RNDCT ;TIME TO SCHEDULE? BNE SWAP ;IF NE NO MOV $RNDCT,RNDCT ;RESET CLOCK TICKS TO NEXT INTERVAL ;MSH098 CALL $DRDSE ;CAUSE A REDISPATCH OF PROCESSOR ;**-1 MOV #$ACTHD-T.ACTL,R1 ;SET ADDRESS OF PREVIOUS ENTRY 10$: MOV R1,R0 ;SAVE ADDRESS OF PREVIOUS ENTRY  MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY BEQ SWAP ;IF EQ END OF LIST CMPB #R$$NDH,T.PRI(R1) ;PRIORITY IN RANGE? BLO 10$ ;IF LO NO 20$: CMPB #R$$NDL,T.PRI(R1) ;PRIORITY IN RANGE? BHI SWAP ;IF HI NO TST T.STAT(R1) ;TASK BLOCKED? BNE 30$ ;IF NE YES BIT #T2.SPN!T2.WFR,T.ST2(R1) ;TASK IN WAITFOR OR SUSPEND? BEQ 40$ ;IF EQ NO 30$: MOV R1,R0 ;SAVE ADDRESS OF LAST ENTRY MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY BR 20$ ; 40$: TST T.ACTL(R1) ;NULL TASK? BEQ SWAP ;IF EQ YES MOV T.ACTL(R1),T.ACTL(R0) ;REMOVE TCB FROM TASK LIST MOV R1,R2 ;SAVE ADDRESS OF TCB MOV R0,R1 ;SET ADDRESS OF LAST ENTRY 50$: MOV R1,R0 ;SAVE ADDRESS OF LAST ENTRY MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY CMPB T.PRI(R1),T.PRI(R2) ;IN SAME PRIORITY CLASS? BEQ 50$ ;IF EQ YES MOV R2,T.ACTL(R0) ;SET ADDRESS OF NEXT IN LAST MOV R1,T.ACTL(R2) ;SET ADDRESS OF NEXT IN REMOVED ENTRY MOV R2,R0 ;SET ADDRESS OF LAST ENTRY BR 20$ ; .ENDC ; ; DISK SWAPPING ALGORITHM - REDUCE SWAPPING PRIORITY OF RESIDENT TASKS ; SWAP: ;REF LABEL .IF DF C$$CKP&S$$WPC&D$$ISK DEC SWPCT ;TIME TO MODIFY PRIORITY DIFFERENCES? BNE 70$ ;IF NE NO MOV $SWPCT,SWPCT ;RESET CLOCK TICKS TO NEXT INTERVAL ;MSH098 MOV $PARHD,R5 ;POINT TO FIRST PCB IN LIST ;**-1 10$: ;REF LABEL .IF DF D$$YNM&M$$MGE BIT #PS.SYS,P.STAT(R5) ;SYSTEM CONTROLLED PARTITION? BNE 30$ ;IF NE YES .IFTF BITB P.BUSY(R5),P.BUSY+1(R5) ;PARTITION OCCUPIED? BEQ 20$ ;IF EQ NO 15$: BIT #PS.COM!PS.DRV,P.STAT(R5) ;COMMON OR DRIVER PARTITION? BNE 40$ ;IF NE YES MOV P.TCB(R5),R4 ;PICK UP OWNER TCB ADDRESS BIT #TS.CKP!TS.CKR!TS.OUT,T.STAT(R4) ;TASK IN MEMORY? BNE 40$ ;IF NE NO MOV P.HDR(R5),R4 ;POINT TO TASK HEADER CMPB H.SPRI(R4),#-S$$WPR ;SWAPPING PRIORITY AT MINIMUM? BLE 40$ ;IF LE YES DECB H.SPRI(R4) ;REDUCE SWAPPING PRIORITY 20$: CMP R5,P.MAIN(R5) ;IS THIS THE MAIN PARTITION? BNE 40$ ;IF NE NO 30$: MOV R5,R0 ;COPY PCB ADDRESS CALL $NXTSK ;REALLOCATE PARTITION 40$: ;REF LABEL .IFT BIT #PS.SYS,P.STAT(R5) ;SYSTEM CONTROLLED PARTITION? BEQ 60$ ;IF EQ NO TST P.SUB(R5) ;IS THERE ANOTHER SUBPARTITION? BEQ 50$ ;IF EQ NO MOV P.SUB(R5),R5 ;POINT TO NEXT SUBPARTITION PCB BR 15$ ; 50$: MOV P.MAIN(R5),R5 ;POINT TO MAIN SYS PARTITION PCB .ENDC 60$: MOV (R5),R5 ;POINT TO NEXT PCB IN LIST BNE 10$ ;IF NE THERE IS ONE 70$: ;REF LABEL .ENDC ; ; EXIT TIME DEPENDENT SCHEDULE IF THERE ARE NOT REMAINING UNPROCESSED CLOCK TICK ; TIMXT: DEC $INT`CT ;ANY MORE TICKS TO PROCESS? BGE 10$ ;IF GE YES RETURN ; 10$: JMP UPTIM ; .END `* kQ ›c, .TITLE CORAL .IDENT /08.13/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 08.13 ; ; D. N. CUTLER 3-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; H. D. COFFMAN ; D. N. CUTLER ; T. J. MILLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; B. S. MCCARTHY 03-FEB-81 ; BM113 -- ADDITION OF EXECUTIVE POOL USAGE ; CONTROL HOOKS ; ; M. S. HARVEY 13-FEB-81 ; MSH142 -- ENHANCE POOL USAGE HOOKS (REPLACES MOST ; OF BM113 ABOVE) ; ; CORE BUFFER ALLOCATION ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$,PKTDF$ CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS ;+ ; **-$ALOCB-ALLOCATE CORE BUFFER ; **-$ALOC1-ALLOCATE CORE BUFFER (ALTERNATE ENTRY) ; ; THIS ROUTINE IS CALLED TO ALLOCATE AN EXEC CORE BUFFER. THE ALLOCATION ; ALGORITHM IS FIRST FIT AND BLOCKS ARE ALLOCATED IN MULTIPLES OF FOUR ; BYTES. ; ; INPUTS: ; ; R0=ADDRESS OF CORE ALLOCATION LISTHEAD-2 IF ENTRY AT $ALOC1. ; R1=SIZE OF THE CORE BUFFER TO ALLOCATE IN BYTES. ; ; OUTPUTS: ; ; C=1 IF INSUFFICIENT CORE IS AVAILABLE TO ALLOCATE THE BLOCK. ; C=0 IF THE BLOCK IS ALLOCATED. ; R0=ADDRESS OF THE ALLOCATED BLOCK. ; R1=LENGTH OF BLOCK ALLOCATED ; ;MSH142 ; R3 IS PRESERVED. ;MSH142 ;- .ENABL LSB $ALOCB::MOV #$CRAVL-2,R0 ;POINT TO ALLOCATION MASK WORD .IF DF Q$$OPT ADD (R0),R1 ;ROUND TO NEXT BOUNDARY BIC (R0)+,R1 ; BEQ 5$ ;IF EQ ZERO LENGTH REQUEST CMP R1,#I.LGTH ;REQUEST SIZE OF PACKET? BNE 5$ ;IF NE NO MOV #$PKAVL,R2 ;POINT TO PACKET AVAILABLE POINTER MOV (R2),R0 ;PICK UP PACKET POINTER BEQ 4$ ;IF EQ THERE IS NONE MOV (R0),(R2)+ ;UNLINK PACKET FROM LIFO LIST DEC (R2) ;INDICATE ONE PACKET LESS IN LIST RETURN ; 4$: MOV #$CRAVL-2,R0 ;POINT BACK TO ALLOCATION MASK WORD .ENDC $ALOC1::ADD (R0),R1 ;ROUND TO NEXT BOUNDARY BIC (R0)+,R1 ;CLEAR EXCESS 5$: SEC ;ASSUME ZERO LENGTH REQUEST BEQ 35$ ;IF EQ, ZERO LENGTH REQUEST .IF DF R$$DER!P$$CTL ; BM113 ;**-1 MOV R0,-(SP) ;SAVE ADDRESS OF LISTHEAD .ENDC ;MSH142 ;**-1 10$: MOV R0,R2 ;SAVE ADDRESS OF CURRENT BLOCK MOV (R2),R0 ;GET ADDRESS OF NEXT BLOCK BEQ 30$ ;IF EQ END OF CHAIN .IF DF,R$$DER CMP R0,R2 ;BACKWARD REFERENCE? BLO 40$ ;IF LE YES CMP #$CRAVL,(SP) ;ALLOCATION IN EXEC'S POOL? BNE 15$ ;IF NE, NO CMP R0,#$POOL ;ALLOCATION BEFORE EXEC POOL? BLO 40$ ;IF LO YES CMP R0,$EXSIZ ;ALLOCATION PAST END OF POOL? BHI 40$ ;IF HI YES 15$: ;REF LABEL .ENDC ;R$$DER CMP 2(R0),R1 ;BLOCK BIG ENOUGH? BLO 10$ ;IF LO NO BEQ 20$ ;IF EQ BLOCK IS EXACT SIZE TST (R0)+ ;POINT TO SIZE OF FREE BLOCK SUB R1,(R0) ;CALCULATE SIZE REMAINING ADD R0,R1 ;POINT TO NEW FREE BLOCK MOV (R0),(R1) ;COPY SIZE MOV -(R0),-(R1) ;COPY LINK MOV R1,(R0) ;STORE LINK TO NEW FREE BLOCK SUB R0,R1 ;RESTORE SIZE OF BLOCK 20$: MOV (R0),(R2) ;UPDATE LINK TO NEW FREE BLOCK 30$: ;REF LABEL .IF DF P$$CTL ;MSH142 ;MSH142 BIT #^C<$CRAVL>,(SP)+ ;ALLOCATION FROM EXEC'S POOL? ;MSH142 BNE 35$ ;IF NE NO, SKIP POOL SIZE TRACKING ;MSH142 ROR (R0) ;ALLOCATION FAILURE? (SAVE C-BIT) ;MSH142 BPL 32$ ;IF PL NO ;MSH142 MOV #PC.ALF!,R2 ;SET LOW POOL MASK ;MSH142 BR 33$ ;REPORT THE ALLOCATION FAILURE ;MSH142 32$: SUB R1,$PRISZ ;SUBTRACT FROM TOTAL FREE POOL SIZE ;MSH142 CMP $PRISZ,$PRILL ;DID WE CROSS LOWER POOL LIMIT? ;MSH142 BHIS 34$ ;IF HIS NO, ALLOCATION OK ;MSH142 MOV #PC.LOW!,R2 ;SET UP LOW POOL CONDITION ;MSH142 33$: CALL $PLTRQ ;REQUEST POOL MONITOR TASK ;MSH142 34$: ASL (R0) ;RECOVER THE CARRY BIT ;MSH142 ;MSH142 .IFF ;P$$CTL ;MSH142 ;MSH142 .IF DF R$$DER INC (SP)+ ;CLEAN STACK W/O AFFECTING C-BIT .ENDC ;R$$DER ;MSH142 .ENDC ;P$$CTL ;MSH142 35$: RETURN ; .IF DF,R$$DER 40$: CRASH ;POOL CLOBBERED .ENDC ;R$$DER .DSABL LSB ;+ ; **-$ALCLK-ALLOCATE CLOCK QUEUE CORE BLOCK ; ; THIS ROUTINE IS CALLED TO ALLOCATE A CORE BLOCK FOR A CLOCK QUEUE ENTRY. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; IF INSUFFICIENT CORE IS AVAILABLE TO ALLOCATE THE BLOCK, THEN A ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED. ELSE THE ADDRESS OF ; THE ALLOCATED BLOCK IS RETURNED TO THE CALLER IN R0. ;- .ENABL LSB $ALCLK::MOV #C.LGTH,R1 ;PICK UP LENGTH OF CLOCK BLOCK BR 10$ ; ;+ ; **-$DECLK-DEALLOCATE CLOCK QUEUE CORE BLOCK ; ; THIS ROUTINE IS CALLED TO DEALLOCATE A CORE BLOCK THAT WAS BEING USED ; FOR A CLOCK QUEUE ENTRY. ; ; INPUTS: ; ; R0=ADDRESS OF THE CORE BLOCK TO BE DEALLOCATED. ; ; OUTPUTS: ; ; THE CLOCK QUEUE ENTRY CORE BLOCK IS DEALLOCATED. ;- $DECLK::MOV #C.LGTH,R1 ;PICK UP LENGTH OF CLOCK BLOCK BR $DEACB ; ;+ ; **-$ALPKT-ALLOCATE SEND OR I/O REQUEST CORE BLOCK ; ; THIS ROUTINE IS CALLED TO ALLOCATE A CORE BLOCK FOR A SEND OR I/O ; REQUEST QUEUE ENTRY. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; IF INSUFFICIENT CORE IS AVAILABLE TO ALLOCATE THE BLOCK, THEN A ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED. ELSE THE ADDRESS OF ; THE ALLOCATED BLOCK IS RETURNED TO THE CALLER IN R0. ;- $ALPKT::MOV #I.LGTH,R1 ;SET LENGTH OF I/O PACKET 10$: CALL $ALOCB ;ATTEMPT TO ALLOCATE BLOCK BCC 80$ ;IF CC SUCCESSFUL DRSTS D.RS1 ;ALLOCATION FAILURE ;+ ; **-$DEPKT-DEALLOCATE SEND OR I/O REQUEST CORE BLOCK ; ; THIS ROUTINE IS CALLED TO DEALLOCATE A CORE BLOCK THAT WAS BEING USED ; FOR A SEND OR I/O REQUEST QUEUE ENTRY. ; ; INPUTS: ; ; R0=ADDRESS OF THE CORE BLOCK TO BE DEALLOCATED. ; ; OUTPUTS: ; ; THE SEND OR I/O REQUEST QUEUE ENTRY CORE BLOCK IS DEALLOCATED. ;- $DEPKT::MOV #I.LGTH,R1 ;SET LENGTH OF I/O PACKET ;+ ; **-$DEACB-DEALLOCATE CORE BUFFER ; **-$DEAC1-DEALLOCATE CORE BUFFER (ALTERNATE ENTRY) ; ; THIS ROUTINE IS CALLED TO DEALLOCATE AN EXEC CORE BUFFER. THE BLOCK IS ; INSERTED INTO THE FREE BLOCK CHAIN BY CORE ADDRESS. IF AN ADJACENT ; BLOCK IS CURRENTLY FREE, THEN THE TWO BLOCKS ARE MERGED AND INSERTED ; IN THE FREE BLOCK CHAIN. ; ; INPUTS: ; ; R0=ADDRESS OF THE CORE BUFFER TO BE DEALLOCATED. ; R1=SIZE OF THE CORE BUFFER TO DEALLOCATE IN BYTES. ; R3=ADDRESS OF CORE ALLOCATION LISTHEAD-2 IF ENTRY AT $DEAC1. ; ; OUTPUTS: ; ; THE CORE BLOCK IS MERGED INTO THE FREE CORE CHAIN BY CORE ; ADDRESS AND IS AGCOMERATED IF NECESSARY WITH ADJACENT BLOCKS. ;- $DEACB::MOV #$CRAVL-2,R3 ;POINT TO ALLOCATION MASK WORD .IF DF Q$$OPT  ADD (R3),R1 ;ROUND TO NEXT BOUNDARY BIC (R3)+,R1 ; BEQ 80$ ;IF EQ NO BLOCK TO RELEASE CMP R1,#I.LGTH ;LENGTH EQUAL TO I/O PACKET? BNE 30$ ;IF NE NO MOV #$PKMAX,R2 ;PNT TO MAX # OF PACKETS TO PREALLOCATE CMPB (R2),-(R2) ;MAX NUMBER PREALLOCATED? BLOS 30$ ;IF LOS YES INC (R2) ;INDICATE ONE MORE AVAILABLE MOV -(R2),(R0) ;LINK PACKET INTO LIFO LIST MOV R0,(R2) ; RETURN ; .ENDC $DEAC1::ADD (R3),R1 ;ROUND TO NEXT BOUNDARY BIC (R3)+,R1 ;CLEAR EXCESS BEQ 80$ ;IF EQ NO BLOCK TO RELEASE 30$: ;REF LABEL .IF DF R$$DER!P$$CTL ;MSH142 ;**-1 MOV R3,-(SP) ;SAVE ADDRESS OF LISTHEAD .ENDC ;MSH142 ;**-1 40$: MOV R3,R2 ;SAVE ADDRESS OF CURRENT BLOCK MOV (R2),R3 ;GET ADDRESS OF NEXT BLOCK BEQ 50$ ;IF EQ END OF CHAIN CMP R0,R3 ;BLOCK GO HERE? BHIS 40$ ;IF HIS NO 50$: MOV R3,(R0) ;ASSUME NO AGLOMERATION ; BM113 .IF DF P$$CTL ; BM113 ; BM113 CMP #$CRAVL,(SP) ;DEALLOCATION OF EXEC'S POOL? ;MSH142 BNE 53$ ;IF NE NO, SKIP POOL TRACKING ;MSH142 ADD R1,$PRISZ ;COUNT SIZE IN POOL TOTAL ; BM113 53$: ; ;MSH142 ; BM113 .ENDC ; DF P$$CTL ; BM113 ; BM113 MOV R0,-(SP) ;CALCULATE ADDRESS OF NEW BLOCK ADD R1,(SP) ; .IF DF R$$DER ;MSH142 ;**-1 BCS 100$ ;IF CS ILLEGAL DEALLOCATION CMP 2(SP),#$CRAVL ;DEALLOCATION IN EXECUTIVE POOL? BNE 55$ ;IF NE NO CMP R0,#$POOL ;DEALLOCATION BEFORE FRONT OF LIST? BLO 100$ ;IF LO YES CMP (SP),$EXSIZ ;DEALLOCATION PAST END OF POOL? BHI 100$ ;IF HI YES 55$: ;REFERENCE LABEL .IFTF CMP R3,(SP)+ ;EQUAL TO NEXT IN CHAIN? .IFT BLO 90$ ;IF LO, DEALLOCATION OVERLAPS .IFTF BNE 60$ ;IF NE NO MOV (R3)+,(R0) ;MOVE LINK WORD TO BLOCK RELEASED ADD (R3),R1 ;MERGE TWO BLOCKS 60$: MOV R2,-(SP) ;SAVE ADDRESS OF PREVIOUS BLOCK MOV R0,(R2)+ ;ASSUME NO AGLOMERATION ADD (R2),(SP) ;CALCULATE ADDRESS OF NEXT BLOCK CMP R0,(SP)+ ;EQUAL TO BLOCK BEING RELEASED? .IFT BHIS 65$  ;IF HIS, NO OVERLAP CMP (SP),#$CRAVL ;DEALLOCATION IN EXECUTIVE CORE POOL? BEQ 100$ ;IF EQ YES (ELSE NOT SURE OF OVERLAP) 65$: ;REF LABEL .ENDC ;MSH142 ;**-1 BNE 70$ ;IF NE NO ADD (R2),R1 ;MERGE TWO BLOCKS MOV (R0),-(R2) ;MOVE LINK WORD TO PREVIOUS BLOCK MOV R2,R0 ;SET NEW ADDRESS OF BLOCK 70$: MOV R1,2(R0) ;SET SIZE OF BLOCK RELEASED ;MSH142 .IF DF P$$CTL ;MSH142 ;MSH142 CMP #$CRAVL,(SP)+ ;ALLOCATION IN EXEC CORE POOL ? ;MSH142 BNE 80$ ;IF EQ NO, SKIP DEALLOCATION CHECKS ;MSH142 CMP $PRISZ,$PRIHL ;DID WE CROSS UPPER POOL LIMIT? ;MSH142 BLOS 80$ ;IF LOS NO ;MSH142 MOV #PC.HIH!,R2 ;SET UP HIGH POOL CONDITION ;MSH142 BR $PLTRQ ;REQUEST POOL MONITOR TASK ;MSH142 ;MSH142 .IFF ;MSH142 ;MSH142 .IF DF R$$DER ;MSH142 ;**-1 TST (SP)+ ;POP ADDRESS OF LISTHEAD .ENDC ;MSH142 ; BM113 $PLTRQ:: ;MAKE SURE $PLTRQ IS ALWAYS DEFINED ; BM113  ; BM113 .ENDC ; NDF P$$CTL ; BM113 ;**-1 80$: RETURN ; .IF DF R$$DER ;MSH142 ;**-1 90$: TST R3 ;INSERT AT END OF LIST? BEQ 60$ ;IF EQ YES, OK 100$: CRASH ;CRASH SYSTEM, BAD CORE DEALLOCATION .ENDC ;+ ; BM113 ; **-$PLTRQ-REQUEST POOL MONITOR TASK ; BM113 ; ; BM113 ; THIS ROUTINE IS USED TO REQUEST THE EXECUTION OF THE POOL ;MSH142 ; MONITOR TASK, IF INSTALLED. THE FORMAT OF THE POOL TASK/EXECUTIVE ;MSH142 ; COMMUNICATIONS WORD IS AS FOLLOWS: ;MSH142 ; ;MSH142 ; $POLST CONTAINS CONDITION BITS INDICATING THE CUMULATIVE ;MSH142 ; HISTORY OF THE POOL'S CONDITION SINCE THE LAST TIME ;MSH142 ; THAT THE POOL MONITOR TASK CLEARED THEM. THESE BITS ;MSH142 ; ARE SET BY THIS ROUTINE AND MAY BE CLEARED BY THE ;MSH142 ; POOL MONITOR TASK. NOTE THAT MORE THAN ONE BIT MAY ;MSH142 ; BE SET IN THIS BYTE AT ANY ONE TIME. ;MSH142 ; $POLST+1 CONTAINS INHIBIT BITS INDICATING WHAT POOL CONDITIONS ;MSH142 ; THE POOL MONITOR TASK IS CURRENTLY AWARE OF. A BIT SET ;MSH142 ; IN THIS BYTE INDICATES TO THIS ROUTINE A POOL CONDITION ;MSH142 ; THAT DOES NOT REQUIRE EXECUTION OF THE POOL MONITOR ;MSH142 ; TASK. THESE BITS ARE ONLY MODIFIED BY THE POOL TASK. ;MSH142 ; GENERALLY, THERE IS NEVER MORE THAN ONE BIT SET IN ;MSH142 ; THIS BYTE AT ANY GIVEN TIME. ;MSH142 ; ;MSH142 ; THE CALLER OF THIS ROUTINE PROVIDES A BIT MASK INDICATING A ;MSH142 ; POOL CONDITION THAT IT WISHES TO MAKE KNOWN TO THE POOL MONITOR ;MSH142 ; TASK. THE GENERAL FORM OF THIS BIT MASK IS #>, ;MSH142 ; WHERE 'XXX DENOTES WHICH OF THE EIGHT POTENTIAL CONDITIONS THE ;MSH142 ; USER WISHES TO MAKE KNOWN TO THE POOL MONITOR TASK (BY STORING ;MSH142 ; THE PC.XXX BIT IN THE LOW BYTE OF $POLST). THE FOLLOWING ACTIONS ;MSH142 ; CAN OCCUR: ;MSH142 ; ;MSH142 ; 1) IF THE SPECIFIED LOW BYTE MASK BIT IS ALREADY SET IN THE ;MSH142 ; LOW BYTE OF $POLST, THEN THIS INDICATES THAT THIS ROUTINE HAS ;MSH142 ; BEEN CALLED MULTIPLE TIMES FOR THE SAME POOL CONDITION BEFORE ;MSH142 ; THE POOL TASK COULD EXECUTE AND CLEAR THE BIT. IN THIS CASE, ;MSH142 ; THE ROUTINE RETURNS. ;MSH142 ; ;MSH142 ; 2) IF THE BIT IS NOT ALREADY SET IN THE LOW BYTE OF $POLST, ;MSH142 ; THEN THIS INDICATES THAT THE POOL PROGRAM MIGHT NOT BE AWARE ;MSH142 ; OF THIS POOL CONDITION AND A SECOND CHECK MUST BE MADE USING ;MSH142 ; THE HIGH BYTE OF $POLST. IF THE SPECIFIED HIGH BYTE MASK BIT ;MSH142 ; IS ALREADY SET IN THE HIGH BYTE, THEN THE POOL TASK IS ;MSH142 ; CURRENTLY AWARE OF THE CONDITION AND DOES NOT WISH TO EXECUTE. ;MSH142 ; IF THE BIT IS NOT SET IN THE HIGH BYTE, THEN THE POOL CONDITION ;MSH142 ; IS A NEW ONE AND THE POOL MONITOR TASK IS REQUESTED TO RUN. ;MSH142 ; ;MSH142 ; THIS INTERFACE IS FLEXIBLE ENOUGH TO ALLOW OTHER INTERFACE PROTOCOLS: ;MSH142 ; ;MSH142 ; - ONE INHIBIT BIT ($POLST+1) COULD BE DEFINED TO 'COVER' MORE ;MSH142 ; THAN ONE CONDITION BIT ($POLST+0). FOR INSTANCE, $PLTRQ CAN ;MSH142 ; BE CALLED WITH R2=403, WHERE THERE ARE TWO CONDITION BITS ;MSH142 ; SET, BUT ONLY ONE INHIBIT BIT SPECIFIED FOR BOTH. ;MSH142 ; ;MSH142 ; - THERE NEED NOT BE A MIRROR-IMAGE RELATIONSHIP BETWEEN THE ;MSH142 ; INHIBIT BITS AND THE CONDITION BITS. FOR VARYING CONDITIONS ;MSH142 ; AND STATES, VARIOUS COMBINATIONS OF THESE BITS CAN BE ENCODED. ;MSH142 ; ;MSH142 ; - NO INHIBIT BIT NEED BE SPECIFIED AT ALL. IN THIS CASE, EVEN ;MSH142 ; IF THE POOL MONITOR TASK HAD SET THE CORRESPONDING INHIBIT BIT ;MSH142 ; IN $POLST+1 FOR THE CONDITION ABOUT TO BE REPORTED, LEAVING ;MSH142 ; THE HIGH BYTE OF R2 CLEAR WILL FORCE THE POOL MONITOR TASK TO ;MSH142 ; EXECUTE FOR THAT CONDITION REPORTED IN THE LOW BYTE OF ;MSH142 ; R2 (UNLESS, OF COURSE, THAT BIT IS ALREADY SET IN $POLST+0, ;MSH142 ; INDICATING A MULTIPLE REQUEST). FOR INSTANCE, IF $PLTRQ IS ;MSH142 ; CALLED WITH R2=1, THE POOL TASK MAY EXECUTE AND SET $POLST ;MSH142 ; TO 400, THE INHIBIT BIT FOR POOL CONDITION '1'. IF $PLTRQ ;MSH142 ; WERE THEN CALLED AGAIN WITH R2=1, THE POOL TASK WOULD AGAIN ;MSH142 ; BE CALLED BECAUSE R2 DID NOT HAVE THE INHIBIT BIT SPECIFIED. ;MSH142 ; THIS OPERATION FORCES THE POOL TASK TO RESPOND ANYWAY. ;MSH142 ; ;MSH142 ; THE REASON FOR SUCH FLEXIBILITY IS TO GENERALIZE THE INTERFACE TO ;MSH142 ; BE USEFUL FOR A VARIETY OF CHORES. THE INTERFACE NEED NOT BE LIMITED ;MSH142 ; TO POOL STATUS REPORTING. ;MSH142 ; ;MSH142 ; INPUTS: ;MSH142 ; ;MSH142 ; R2=POOL CONDITION BIT MASK (PC.XXX OR'ED WITH PC.XXX*400). ;MSH142 ; ;MSH142 ; OUTPUTS: ;MSH142 ; ;MSH142 ; IF NO BITS IN THE LOW BYTE OF R2 ARE SET IN $POLST AND NO ;MSH142 ; BITS IN THE HIGH BYTE OF R2 ARE SET IN $POLST+1, THEN THE ;MSH142 ; POOL TASK IS REQUESTED WITH THE REASON FOR THE REQUEST ;MSH142 ; (PC.XXX) STORED IN THE LOW BYTE OF $POLST. OTHERWISE, RETURN. ;MSH142 ; ;MSH142 ; R0, R1 AND R3 ARE PRESERVED. ;MSH142 ;- ; BM113 ; BM113 .IF DF P$$CTL ; BM113 ;MSH142 .ENABL LSB ;MSH142 $PLTRQ::BITB R2,$POLST ;ALREADY REQUESTED FOR THIS CONDITION? ;MSH142 BNE 20$ ;IF NE YES, AVOID MULTIPLE REQUESTS ;MSH142 BISB R2,$POLST ;INDICATE CURRENT POOL CONDITION ;MSH142 CLRB R2 ;CHECK POOL TASK INHIBIT BITS ;MSH142 BIT R2,$POLST ;REQUEST POOL TASK FOR THIS CONDITION? ;MSH142 BNE 20$ ;IF NE NO, TASK AWARE OF POOL CONDITION ;MSH142 MOV R0,-(SP) ;SAVE R0 ;MSH142 MOV $PTTCB,R0 ;POOL MONITOR TASK INSTALLED? ;MSH142 BEQ ²10$ ;IF EQ NO, CAN'T REQUEST IT ;MSH142 MOV R1,-(SP) ;SAVE R1 ;MSH142 MOV R3,-(SP) ;SAVE R3 ;MSH142 CALL $EXRQN ;REQUEST THE POOL MONITOR TASK ;MSH142 MOV (SP)+,R3 ;RESTORE R3 ;MSH142 MOV (SP)+,R1 ;RESTORE R1 ;MSH142 10$: MOV (SP)+,R0 ;RESTORE R0 ;MSH142 20$: RETURN ; ;MSH142 .DSABL LSB ;MSH142 ;MSH142 .ENDC ; DF P$$CTL ; BM113 ; BM113 .DSABL LSB .END ²á˜:kQ ›c, .TITLE DRQIO .IDENT /11.22/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 11.22 ; ; D. N. CUTLER 8-OCT-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; B. A. O'CONNELL ; ; MODIFIED BY: ; ; M. S. HARVEY 17-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 13-OCT-79 ; MSH045 -- DO NOT ALLOW $DRQRQ TO BE IN DIRECTIVE COMMON ; AND CLEAN UP SOME COMMENTS ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 1-AUG-80 ; MSH109 -- PREVENT TRANSLATION OF IO.RVB TO IO.WLB ; ; M. S. HARVEY 25-FEB-81 ; MSH152 -- REJECT IO.ATT OR IO.DET IF IQ.X SUBFUNCTION ; BIT IS SET ; ; C. H. FRANKS 11-MAR-81 ; CHF023 -- ADD SOFTWARE WRITE LOCK ; ; M. S. HARVEY 14-MAR-81 ; MSH151 -- DO NOT ALLOW GROUP GLOBAL USE COUNT TO ; BE DECREMENTED BEFORE BEING INCREMENTED ; ; M. S. HARVEY 14-APR-81 ; MSH163 -- CLEAN UP SOME OF THE CODE ; ; M. S. HARVEY 1-SEP-81 ; MSH187 -- ADD EXPLICIT CHECK FOR ODD IOSB ADDRESSES ; FOR PROCESSORS WITHOUT THE ODD ADDRESS ; TRAP MECHANISM ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 6-OCT-81 ; MSH194 -- EXTERNALIZE WAITFOR ROUTINE ; ; ; MACRO LIBRARY CALLS ; .MCALL F11DF$,HWDDF$,PKTDF$,TCBDF$,PCBDF$ F11DF$ ;DEFINE FILES-11 CONTROL BLOCK OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS ; ; LOCAL DATA ; ; TEMPORARY LOCATION TO MARK STACK ADDRESS ; MSTK: .BLKW 1 ; ; POLISH INTERPRETER DATA BASE ; ; FUNCTION CODE DISPATCH VECTOR ; .IF DF A$$CPS FCDSP: .WORD FCIFC ;10-ILLEGAL FUNCTION .WORD FCPKT ;11-FIND FILE NAME IN DIRECTORY .IF DF R$$LKL .WORD UNLCK ;12-UNLOCK BLOCK .IFF .WORD FCIFC ;12-ILLEGAL FUNCTION .ENDC .WORD FCPKT ;13-REMOVE FILE NAME FROM DIRECTIRY .WORD FCPKT ;14-ENTER FILE NAME IN DIRECTORY .WORD FCACC ;15-ACCESS FILE FOR READ .WORD FCACC ;16-ACCESS FILE FOR READ AND WRITE .WORD FCACC ;17-ACCESS FILE FOR READ, WRITE, AND EXTEND .WORD FCDAC ;20-DEACCESS FILE .WORD FCRVB ;21-READ VIRTUAL BLOCK .WORD FCWVB ;22-WRITE VIRTUAL BLOCK .WORD FCEXT ;23-EXTEND FILE .WORD FCCRE ;24-CREATE FILE .WORD FCDEL ;25-MARK FILE FOR DELETE/TRUNCATE FILE .WORD FCPKT ;26-READ FILE ATTRIBUTES .WORD FCPKT ;27-WRITE FILE ATTRIBUTES .WORD FCPKT ;30-USER MAGTAPE CONTROLL FUNCTION .WORD FCWVB ;31-TRANSMIT PROCESS MESSAGE .WORD FCRVB ;32-RECEIVE PROCESS MESSAGE .WORD FCCON ;33-CONNECT TO PROCESS .WORD FCDIS ;34-DISCONNECT FROM PROCESS .WORD FCNCT ;35-NETWORK CONTROL FUNCTION .WORD FCIFC ;36-ILLEGAL FUNCTION .WORD FCIFC ;37-ILLEGAL FUNCTION .IF NDF M$$NET FCCON: ;REF LABEL IF NO NETWORK SUPPORT FCDIS: ;REF LABEL IF NO NETWORK SUPPORT FCNCT: ;REF LABEL IF NO NETWORK SUPPORT .IFTF ; ; ILLEGAL FUNCTION ; FCIFC: .WORD IEIFC ;SET ILLEGAL FUNCTION STATUS ; ; ACCESS FILE FOR READ, READ/WRITE, OR READ/WRITE/EXTEND ; FCACC: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKALN ;CHECK IF FILE ALREADY ACCESSED ON LUN .WORD CKMOU ;CHECK VOLUME MOUNTED THIS USER .WORD CKACP ;SET FLAG TO QUEUE TO ACP .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKRLK ;SYNCHRONIZE ACCESS AND EXIT ; ; DEACCESS FILE ; FCDAC: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .IF DF,A$$NSI .WORD CKQMT ;QUEUE TO MTAACP IF ANSI .ENDC .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKRLK ;EXIT ; ; READ VIRTUAL BLOCK ; FCRVB: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD CKRAC ;CHECK READ ACCESS AND EXIT ; ; WRITE VIRTUAL BLOCK ; FCWVB: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD CKWAC ;CHECK WRITE ACCESS AND EXIT ; ; CREATE FILE ; CREATE & ACCESS NOT LEGAL COMBINATION ; FCCRE: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKALN ;CHECK IF FILE ACCESSED ON LUN .WORD CKPKT ;JOIN COMMON ACP & CHECK MOUNT ; ; DELETE FILE -- CHECK IF REALLY TRUNCATE ; DON'T MOVE THIS - FALLS THRU TO FCPKT ; FCDEL: .WORD CKTRN ;CHECK IF REALLY TRUNCATE ; ; BUILD AN I/O PACKET FOR FIND, ENTER, REMOVE, READ ATTRIBUTES ; AND WRITE ATTRIBUTES ; FCPKT: .WORD CKACP ;SET FLAG TO QUEUE TO ACP .WORD CKMOU ;CHECK VOLUME MOUNTED THIS USER .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKXIT ;EXIT ; ; EXTEND FILE -- INCR WINDOW TURN PENDING COUNT ; FCEXT: .WORD CKPND ;INCR WINDOW TURN PENDING CNT FOR EXTEND ; ; EXPLICIT UNLOCK BLOCK FUNCTION ; .IF DF R$$LKL UNLCK: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD UNLXT ;SET REGISTERS AND EXIT .ENDC .IFF ; ; CONNECT TO PROCESS ; FCCON: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKALN ;CHECK IF PROCESS ALREADY CONNECTED ON LUN .WORD CKCON ;ADDRESS CHECK CONNECT BUFFER AND EXIT .WORD CKRLK ;INTERLOCK LUN USAGE AND EXIT ; ; DISCONNECT FROM PROCESS ; FCDIS: .WORD CKNLN ;CHECK IF PROCESS CONNECTED ON LUN .WORD CKDIS ;CHECK BUFFER AND COPY PARAMETERS .WORD CKRLK ;INTERLOCK LUN USAGE AND EXIT ; ; NETWORK CONTROL FUNCTION ; FCNCT: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKCON ;ADDRESS CHECK BUFFER .WORD CKXIT ;EXIT .ENDC .ENDC ;CHF023 ; ;CHF023 ; TABLE OF SPECIAL FUNCTION CODES TO BE CHECKED BY SOFTWARE WRITE LOCK ;CHF023 ; ;CHF023 ;CHF023 .IF DF S$$WLK ;CHF023 ;CHF023 WLKTB: ;CHF023 ;DEVICE DEPENDENT CODES ;CHF023 .WORD IO.SMD ;SET MEDIA DENSITY ;CHF023 .WORD IO.EOF ;WRITE END OF FILE ;CHF023 .WORD IO.ERS ;ERASE TAPE ;CHF023 .WORD IO.DSE ;DATA SECURITY ERASE ;CHF023 ;CHF023 .IF DF D$$IAG ;CHF023 ;DIAGNOSTIC CODES ;CHF023 .WORD IO.WDH ;WRITE DATA AND HEADER ;CHF023 .WORD IO.WTD ;WRITE TRACK DESCRIPTOR ;CHF023 .WORD IO.TDD ;WRITE TRACK DESCRIPTOR DISPLACED ;CHF023 .WORD IO.CEW ;WRITE BLOCK ON CE TRACK ;CHF023 ;CHF023 .ENDC ;D$$IAG ;CHF023 ;CHF023 .WORD 0 ;TERMINATOR FOR WRITE LOCK TABLE ;CHF023 ;CHF023 .ENDC ;S$$WLK ;CHF023 ;CHF023 ;CHF023 ;+ ; **-$DRQIO-QUEUE I/O REQUEST ; **-$DRQIW-QUEUE I/O REQUEST AND WAIT. ; ; THESE DIRECTIVES INSTRUCT THE SYSTEM TO PLACE AN I/O REQUEST IN A ; QUEUE OF PRIORITY ORDERED REQUESTS FOR A DEVICE-UNIT SPECIFIED BY ; A LOGICAL UNIT NUMBER. IN ADDITION, IF THE DIRECTIVE IS QIO AND ; WAIT AND AN EVENT FLAG IS SPECIFIED, THE TASK IS PUT INTO A WAIT STATE ; FOR THE SPECIFIED EVENT FLAG. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(1./3.),DPB SIZE(12.). ; WD. 01 -- I/O FUNCTION CODE. ; WD. 02 -- LUN AND UNUSED BYTE. ; WD. 03 -- EVENT FLAG NUMBER AND PRIORITY (PRIORITY IS IGNORED). ; WD. 04 -- ADDRESS OF I/O STATUS BLOCK. ; WD. 05 -- ADDRESS OF AST SERVICE ROUTINE. ; WD. 06 -- PARAMETER 1. ; WD. 07 -- PARAMETER 2. ; WD. 10 -- PARAMETER 3. ; WD. 11 -- PARAMETER 4. ; WD. 12 -- PARAMETER 5. ; WD. 13 -- PARAMETER 6. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE I/O FUNCTION CODE IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK)  ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS5' IS RETURNED IF SPECIFIED ; LUN IS NOT ASSIGNED. ; DIRECTIVE STATUS OF 'D.RS6' IS RETURNED IF DEVICE ;MSH045 ; DRIVER NOT LOADED. ;MSH045 ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE ;MSH187 ; SPECIFIED I/O STATUS BLOCK IS ODD OR NOT ;MSH187 ; WITHIN THE CURRENT VIRTUAL ADDRESS SPACE ;MSH187 ;- .ENABL LSB $DRQIO::MOV (R3)+,-(SP) ;SAVE I/O FUNCTION CODE CALL $MPLUN ;MAP LUN TO UCB ADDRESS BCC 10$ ;IF CC LUN ASSIGNED DRSTS D.RS5 ;SET DIRECTIVE STATUS 10$: BIT #1,(R1) ;OPERATION PENDING? BEQ 15$ ;IF EQ NO ADD #6,SP ;REMOV FUNC, RETURN AND +1 FROM STACK MOV (R4),R0 ;GET SAVED TASK STACK POINTER SUB #2,4(R0) ;BACKUP TASK PC SO EMT WILL BE RE-EXECUTED CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 15$: ; .IF DF L$$DRV MOV (R0),R2 ;GET DCB ADDRESS TST D.DSP(R2) ;IS THE DRIVER RESIDENT? BNE 16$ ;IF NE YES DRSTS D.RS6 ;SET DIRECTIVE STATUS 16$: ; .ENDC MOV R0,-(SP) ;SAVE POINTER TO UCB MOV R1,-(SP) ;SAVE POINTER TO SECOND LUN WORD MOVB (R3),-(SP) ;SAVE EVENT FLAG NUMBER CALL $CEFNG ;CONVERT EVENT FLAG NUMBER ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 BIC #1,R1 ;CLR GRP GLOBAL 2ND WORD INDICATOR ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 BIC R0,(R1) ;CLEAR SPECIFIED EVENT FLAG ;**-1 MOV R3,-(SP) ;SAVE ADDRESS OF I/O STATUS BLOCK ADDRESS MOV (R3),R0 ;GET ADDRESS OF I/O STATUS BLOCK ADDRESS BEQ 20$ ;IF EQ NO I/O STATUS BLOCK SPECIFIED .IF DF M$$MGE BIT #1,R0 ;SPECIFIED I/O STATUS BLOCK ODD? ;MSH187 BEQ $DQLM1 ;IF EQ NO ;MSH187 DRSTS D.RS98 ;I/O STATUS BLOCK MUST WORD ALIGNED ;MSH187 $DQLM1::CLR -(SP) ;ZERO I/O STATUS BLOCK MTPI (R0)+ ; CLR -(SP) ; MTPI (R0) ; $DQLM2:: ;REF LABEL .IFF .IF DF A$$CHK MOV #4,R1 ;SET LENGTH OF I/O STATUS BLOCK CALL $ACHKW ;ADDRESS CHECK I/O STATUS BLOCK .ENDC CLR (R0)+ ;CLEAR I/O STATUS BLOCK CLR (R0) ; .ENDC 20$: CALL $ALPKT ;ALLOCATE AN I/O PACKET ; ;MSH151 ; AT THIS POINT, THE QIO DIRECTIVE ITSELF IS SUCCESSFUL. ANY ERRORS ;MSH151 ; ENCOUNTERED AFTER THIS POINT WILL BE REPORTED AS I/O STATUS IN ;MSH151 ; THE SPECIFIED IOSB. THE DSW WILL SHOW SUCCESS. ;MSH151 ; ;MSH151 ; IF THE SPECIFIED EVENT FLAG WAS GROUP GLOBAL, THE USE COUNT MUST ;MSH151 ; BE INCREMENTED NOW RATHER THAN IN THE DISPATCHER. THIS PREVENTS ;MSH151 ; DECREMENTING BEFORE INCREMENTING IN CASE THE I/O PACKET IS FLUSHED ;MSH151 ; BEFORE RETURNING TO THE DISPATCHER. ;MSH151 ; ;MSH151 ;MSH151 .IF DF G$$EFN ;MSH151 ;MSH151 INC @$GEFPT ;LOCK GROUP GLOBALS PENDING I/O COMPLETI;MSH151 ;MSH151 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH151 INCB @$GFTCB ;DON'T ALLOW SLAVE TASKS TO CHANGE UIC ;MSH151 ;MSH151 .ENDC ;MSH151 ;MSH151 .ENDC  ;MSH151 .IF DF R$$LKL CLR I.PRM+16(R0) ;INITIALLY CLEAR LOCK ENTRY POINTER .ENDC INCB T.IOC(R5) ;INCREMENT I/O REQUEST COUNT MOV (SP)+,R3 ;RETRIEVE ADDRESS OF I/O STATUS BLOCK ADDRESS CMPB -10(R3),#3 ;IS FUNCTION QIO AND WAIT? BNE 25$ ;IF NE NO MOV R0,-(SP) ;SAVE PACKET ADDRESS MOVB 2(SP),R0 ;PICK UP EVENT FLAG NUMBER BEQ 24$ ;IF EQ NONE SPECIFIED CALL $CEFI ;CONVERT FLAG TO MASK AND ADDRESS CALL $DRWFD ;PUT TASK IN WAITFOR STATE ;MSH194 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 INC @$GEFPT ;KEEP GROUP GLOBALS AROUND FOR WAITFOR T;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 INCB @$GFTCB ;INC GRP GLOBAL USE COUNT FOR TASK ;MSH076 ;MSH076 .ENDC ;R$$SND ;MSH076 ;MSH049 .ENDC ;MSH049 ;MSH049 24$: MOV (SP)+,R0 ;RESTORE PACKET ADDRESS ;MSH151 25$: ; ;MSH151 ;MSH151 .IF DF G$$EFN ;MSH151 ;MSH151 MOV #$GEFDM,$GEFPT ;PREVENT USE COUNT INCREMENT IN DISPATCH;MSH151 ;MSH151 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH151 MOV #$GEFDM,$GFTCB ;DON'T LOCK SLAVE TASKS AGAIN ;MSH151 ;MSH151 .ENDC ;MSH151 ;MSH151 .ENDC ;MSH151 ;MSH151 MOV R0,R4 ;COPY PACKET ADDRESS ;MSH151 TST (R4)+ ;POINT TO SECOND WORD IN PACKET ;**-3 MOVB T.PRI(R5),(R4)+ ;PRIORITY IS THAT OF ISSUING TASK MOVB (SP)+,(R4)+ ;INSERT EVENT FLAG NUMBER MOV R5,(R4)+ ;INSERT TCB ADDRESS MOV (SP)+,(R4)+ ;INSERT POINTER TO SECOND LUN WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS MOV R5,(R4)+ ;INSERT UCB ADDRESS MOV (SP)+,(R4) ;INSERT I/O FUNCTION CODE .IF DF,A$$CPS CLR -(SP) ;SET FLAG TO QUEUE TO DRIVER (NE 0=ACP) .ENDC MOV R0,-(SP) ;SAVE ADDRESS OF I/O PACKET CLR -(SP) ;CLEAR ADDRESS OF SECONDARY CONTROL BLOCK MOV SP,MSTK ;MARK STACK ADDRESS MOV (R4)+,-(SP) ;SAVE I/O FUNCTION CODE CLR R2 ;ASSUME NO I/O STATUS BLOCK SPECIFIED MOV (R3)+,R0 ;GET ADDRESS OF I/O STATUS BLOCK BEQ 30$ ;IF EQ NONE SPECIFIED CALL $RELOC ;RELOCATE I/O STATUS BLOCK ADDRESS 30$: MOV R0,(R4)+ ;INSERT VIRTUAL ADDRESS OF I/O STATUS BLOCK MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT DISPLACEMENT ADDRESS MOV (R3)+,(R4)+ ;INSERT AST SERVICE ROUTINE ADDRESS MOV (SP),R2 ;RETRIEVE I/O FUNCTION CODE CLRB R2 ;CLEAR MODIFIER FLAGS SWAB R2 ;SWAP FUNCTION CODE INTO RIGHT BYTE BEQ FCKIL ;IF EQ KILL I/O FUNCTION .IF DF M$$MUP MOV U.OWN(R5),R0 ;IS THE DEVICE OWNED? BEQ 35$ ;IF EQ NO BITB #US.PUB,U.ST2(R5) ;PUBLIC ACCESS ALLOWED? BNE 35$ ;IF NE YES MOV $TKTCB,R1 ;POINT TO CURRENT TASK'S TCB CMP T.UCB(R1),R0 ;DEVICE OWNED BY CURRENT TASK? BEQ 35$ ;IF EQ YES BIT #T3.PRV,T.ST3(R1) ;CURRENT TASK PRIVILEGED? BNE 35$ ;IF NE YES JMP IEPRI ;ELSE PRIVILEGE VIOLATION 35$: ;ACCESS ALLOWED .ENDC CMP R2,#31. ;FUNCTION CODE IN RANGE? BHI IEIFC ;IF HI NO MOV (R5),R1 ;GET ADDRESS OF DEVICE DCB ADD #D.MSK,R1 ;ASSUME FUNCTION CODE IN 0-15. RANGE CMP R2,#15. ;0-15. FUNCTION CODE? BLOS 40$ ;IF LOS YES ADD #10,R1 ;POINT TO SECOND MASK SET SUB #16.,R2 ;REDUCE FUNCTION CODE 40$: ASL R2 ;CONVERT TO WORD INDEX MOV $BTMSK(R2),R2 ;GET FUNCTION MASK WORD BIT R2,(R1)+ ;IS THIS A LEGAL FUNCTION? BEQ IEIFC ;IF EQ NO BITB #US.OFL,U.ST2(R5) ;DEVICE OFFLINE? BNE IEOFL ;IF NE YES BIT R2,(R1)+ ;IS THIS A CONTROL FUNCTION? BNE FCCTL ;IF NE YES BIT R2,(R1)+ ;IS FUNCTION NOP'ED? BNE ISSUC ;IF NE YES .IF DF A$$CPS TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL 80$ ;IF PL NO MOVB U.STS(R5),R0 ;GET STATUS BYTE FOR TESTS BELOW BITB #US.MNT!US.FOR,R0 ;DEVICE MOUNTED AND NOT FOREIGN? BNE 60$ ;IF NE NO BIT R2,(R1) ;ACP FUNCTION? BEQ 70$ ;IF EQ NO MOVB 1(SP),R2 ;RETRIEVE I/O FUNCTION CODE SUB #10,R2 ;NORMALIZE FOR POLISH DISPATCH BLT 50$ ;IF LT TABLE INCONSISTANCY ASL R2 ;CONVERT TO WORD INDEX MOV R5,-(SP) ;SAVE UCB ADDRESS FOR POLISH ROUTINES MOV R5,R0 ; MOV I.LN2-I.PRM(R4),R1 ;SAVE ADDRESS OF SECOND LUN WORD MOV R1,-(SP) ;FOR POLISH ROUTINES MOV FCDSP(R2),R5 ;GET ADDRESS OF POLISH VECTOR JMP @(R5)+ ;EXECUTE POLISH ROUTINE ; ; REGISTERS AT POLISH DISPATCH: ; ; R0 - UCB ; R1 - ADDRESS 2ND LUN WORD ; R2 - NORMALIZED FCTN CODE ; R3 - POINTER TO PARAMETERS, INITIALLY -> PARAMETER 1 ; R4 - POINTER INTO I/O PACKET, INITIALLY -> I.PRM ; ; SP-> 2ND LUN WORD ADDRESS ; UCB ADDRESS ; FUNCTION CODE ; MSTK -> SECONDARY CONTROL BLOCK ADDRESS (OR 0) ; I/O PACKET ADDRESS ; QUEUE FLAG (0=DRIVER; NE=ACP) ; ; SEE COMMENT LOCATED BETWEEN FCXIT AND $DRQRQ FOR DETAILS ON QUEUING ; AND INTERLOCKING INTERFACES FOR MOUNTABLE DEVICES. ; ; ; DEVICE TABLE MASK WORD INCONSISTANCY ; 50$: CRASH ; ; ; DEVICE NOT MOUNTED OR MOUNTED AS FOREIGN ; 60$: BITB #US.MNT,R0 ;DEVICE NOT MOUNTED OR FOR? BEQ 65$ ;BRANCH IF MOUNTED FOREIGN ; ; DEVICE NOT MOUNTED ; ALLOW TRANSFER FUNTCTION ; ACP FUNCTIONS ARE ILLEGAL ; BIT R2,(R1) ;ACP FUNCTION BNE 75$ ;IF NE YES BR FCTRN ; ; ; MOUNTED FOREIGN ; CHECK IF VOLUME MOUNTED THIS USER ; IF ACP FUNCTION: ; ERROR IF NO ACP ; COPY PARAMETERS 1-6 (NO POLISH IF FOREIGN) ; QUEUE TO ACP UNLESS UC.QUE SET (U.CTL) ; IF TRANSFER FUNCTION: ; ADDRESS CHECK AND RELOCATE BUFFER ADDRESS-PARM 1 ; MAP ADDRESS TO 18/22 BIT PHYSICAL ADDRESS ; INCREMENT VOLUME TRANSACTION COUNT ; COPY PARAMETERS 2-6 ; QUEUE TO DRIVER ; 65$: ; .IF DF,M$$MUP CALL CXMOU ;CHECK VOLUME MOUNTED THIS USER BCS 75$ ;ERROR .ENDC BIT R2,(R1) ;ACP FUNCTION? BEQ FCTRN ;NOT ACP--TRANSFER TST U.ACP(R5) ;MOUNTED WITH AN ACP? BEQ 75$ ;ERROR IF NO ACP INC 6(SP) ;SET FLAG TO QUEUE TO ACP MOV U.VCB(R5),R1 ;HAVE A VCB? BEQ FCXOP ;NO VCB THEN DON'T DO ANYTHING INC (R1) ;INCREMENT VOL TRANS CNT IN VCB BR FCXOP ;INSERT PARAMETERS 1-6 ; ; DEVICE MOUNTED AND NOT FOREIGN BUT NOT ACP FUNCTION ; 70$: CMP #IO.LOV,(SP) ;LOAD OVERLAY FUNCTION? BEQ FCTRN ;IF EQ YES MOV $TKTCB,R0 ;GET ADDRESS OF TCB OF CURRENT TASK BIT #T3.PRV,T.ST3(R0) ;TASK PRIVILEGED? BNE FCTRN ;IF NE YES 75$: JMP IEPRI ;PRIVILEGE VIOLATION .ENDC ; ; DEVICE IS NOT MOUNTABLE ; 80$: BIT R2,(R1) ;ACP FUNCTION? BEQ FCTRN ;IF EQ NO ; ; FUNCTION IS A FILE STRUCTURE FUNCTION FOR A NONFILE STRUCTURED DEVICE. BY DEF- ; INITION THIS MUST BE A READ OR WRITE VIRUTAL SINCE ALL OTHER FUNCTIONS WOULD ; HAVE BEEN EITHER ILLEGAL OR NOP'ED. MAP FUNCTION TO IT LOGICAL COUNTERPART. ; ; NOTE THAT THE SUBFUNCTION BITS ARE IGNORED SINCE READ VIRTUAL ;MSH109  ; AND WRITE VIRTUAL FUNCTIONS ARE INTENDED TO BE DEVICE INDEPENDENT. ;MSH109 ; ;MSH109 MOV #IO.RLB,I.FCN-I.PRM(R4) ;ASSUME FUNCTION IS READ VIRTUAL CMPB #IO.RVB/256.,1(SP) ;READ VIRTUAL FUNCTION? ;MSH109 BEQ FCTRN ;IF EQ YES ;**-1 MOV #IO.WLB,I.FCN-I.PRM(R4) ;SET FUNCTION TO WRITE LOGICAL BLOCK .DSABL LSB ; ; FUNCTION IS A TRANSFER FUNCTION-ADDRESS CHECK AND MAP TRANSFER ; FCTRN: CALL FACHK ;PERFORM ADDRES CHECK .IF DF,M$$MGE CALL $MPPHY ;MAP TO 18/22 BIT PHYS ADDR .ENDC CALL FCXR1 ;INSERT RELOC DISP & BIAS; & PARM 2-6 BR FCXTR ; ; ; FUNCTION IS A KILL I/O FUNCTION-FLUSH I/O QUEUE OF TASK REQUESTS ; FCKIL: CALL $IOKIL ;FLUSH I/O QUEUE ; ; FUNCTION IS A NOP'ED FUNCTION-DECLARE SUCCESSFUL COMPLETION STATUS ; ISSUC: MOV #IS.SUC&377,R4 ;SET SUCCESSFUL COMPLETION CODE BR IECM1 ; ;CHF023 ;**-1 ; ; FUNCTION IS AN ILLEGAL FUNCTION-DECLARE ILLEGAL FUNCTION CODE STATUS ; IEIFC: MOV #IE.IFC&377,R4 ;SET ILLEGAL FUNCTION CODE  BR IECM1 ; ;CHF023 ;**-1 ; ; SPECIFIED DEVICE IS OFFLINE ; IEOFL: MOV #IE.OFL&377,R4 ;SET DEVICE OFFLINE STATUS IECM1: JMP IECMN ; ;CHF023 ;**-1 ; ; FUNCTION IS A CONTROL FUNCTION-COPY REMAINDER OF DPB ; FCCTL: ;REF LABEL .IF DF A$$NSI TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL 10$ ;IF PL NO BITB #US.MNT!US.FOR,U.STS(R5) ;MOUNTED AND NOT FOREIGN? BNE 10$ ;IF NE NO BITB #US.LAB,U.STS(R5) ;IS IT AN ANSI TAPE? BEQ 10$ ;IF EQ NO MOV $TKTCB,R0 ;POINT TO CURRENT TASK TCB BIT #T3.PRV,T.ST3(R0) ;TASK PRIVILEGED? BNE 10$ ;IF NE YES ;CHF023 JMP IEPRI ; ;CHF023 ;**-1 .ENDC 10$: ; FCXOP: CALL FCXP1 ;INSERT PARAMETERS 1 TO 6 FCXTR: ;REFERENCE LABEL CMPB 1(SP),#IO.ATT/256. ;ATTACH FUNCTION? ;MSH152 BEQ 5$ ;IF EQ YES, CHECK IQ.X BIT ;MSH152 CMPB 1(SP),#IO.DET/256. ;DETACH FUNCTION? ;MSH152 BNE 7$ ;IF NE NO ;MSH152 5$: TST U.ATT(R5) ;DEVICE ALREADY ATTACHED? ;MSH152 BEQ 6$ ;IF EQ NO ;MSH152  BITB #IQ.X,(SP) ;REJECT IF ATTACHED BY ANOTHER TASK? ;MSH152 BEQ 10$ ;IF EQ NO ;MSH152 CMP $TKTCB,U.ATT(R5) ;ATTACHED BY ISSUING TASK? ;MSH152 BNE IERSU ;IF NE NO, REJECT THE REQUEST ;MSH152 6$: MOV 4(SP),R0 ;GET I/O PACKET ADDRESS ;MSH152 BIC #IQ.X,I.FCN(R0) ;CLEAR IQ.X BIT ;MSH152 ;MSH152 .IF DF D$$IAG ;MSH152 ;MSH152 BR 10$ ;JOIN COMMON CODE ;MSH152 ;MSH152 .IFTF ;MSH152 ;MSH152 7$: ; ;MSH152 .IFT ;D$$IAG  ;MSH152 ;**-1 BITB #IQ.UMD,(SP) ;IS THIS A DIAGNOSTIC FUNCTION? BEQ 10$ ;IF EQ NO BIT #DV.UMD,U.CW1(R5) ;DOES DEVICE SUPPORT DIAGNOSTICS? BEQ 10$ ;IF EQ NO BITB #US.UMD,U.ST2(R5) ;IS DEVICE ATTACHED FOR DIAGNOSTICS? ;**-4 BEQ IEPRI ;IF EQ NO, PRIVILEGE VIOLATION MOV (R4),R0 ;PICK UP REGISTER BUFFER ADDRESS .IF DF A$$CHK!M$$MGE MOV #40.*2,R1 ;PICK UP MAX LENGTH CALL $ACHCK ;ADDRESS CHECK REGISTER BUFFER BCS IESPC ;IF CS ADDRESS CHECK FAILED .ENDC CALL $RELOC ;RELOCATE REGISTER BUFFER MOV R1,(R4)+ ;STORE KISAR6 BIAS MOV R2,(R4) ;STORE DISPLACEMENT ;**-1 .ENDC 10$: CMP #IO.LOV,(SP)+ ;IS THIS A LOAD OVERLAY FUNCTION? ;MSH152 BNE FCXIT ;IN NE NO ;**-1 TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL FCXIT ;IF PL NO MOV $TKTCB,R3 ;GET ADDRESS OF TCB OF CURRENT TASK MOV T.LDV(R3),R0 ;GET UCB ADDRESS OF LOAD DEVICE CALL $MPLND ;MAP TO ACTUAL UCB ADDRESS CMP R0,R5 ;LOAD DEVICE UCB MATCH SPECIFIED UCB? BNE IEOVR ;IF NE NO ADD T.LBN+1(R3),-(R4) ;ADD IN LOW PART OF TASK LOGICAL ADC -(R4) ;BLOCK NUMBER MOVB T.LBN(R3),R0 ;GET HIGH BYTE OF TASK LOGICAL BLOCK NUMBER ADD R0,(R4) ;ADD IN HIGH PART FCXIT: TST (SP)+ ;CLEAN STACK MOV (SP)+,R1 ;RETRIEVE ADDRESS OF I/O PACKET .IF DF,A$$CPS TST (SP)+ ;QUEUE TO DRIVER?? BEQ DRQRQ ;IF EQ YES; IF NE Q ACP ;MSH045 BITB #UC.QUE,U.CTL(R5) ;IF SET QUEUE TO DRIVER ;**-1 BNE DRQRQ ;EVEN IF ACP FUNCTION ;MSH045 MOV U.ACP(R5),R0 ; ;**-1 CALLR $EXRQP ;INSURE FILE SYSTEM ACTIVE .ENDC ; ; DESCIPTION OF QUEUING AND INTERLOCKING INTERFACES ; FOR MOUNTABLE DEVICES. ; ; I. NOT MOUNTED - ALLOW TRANSFER FUNCTIONS. ; ACP FCTNS ARE ILLEGAL. ; ADDRESS CHECK & AND MAP BUFFER ADDRESS IN ; PARAMETER 1 ; QUEUE TO DRIVER. ; ; II. MOUNTED ; A. ALL CASES - IF 'UC.QUE' SET IN 'U.CTL' THEN QUEUE ; TO DRIVER. (NECESSARY TO SUPPORT EXISTING ; DRIVERS THAT ARE REALLY ALSO LIKE ACP'S) ; ; B. MOUNTED FOREIGN ; 1. XFER FCTN - ADDRESS CHECK AND MAP ;  BUFFER ADDRESS IN PARAMETER 1. COPY ; PARAMETERS 2-6. QUEUE TO DRIVER. ; 2. ACP FCTN - ERROR IF NO ACP. COPY PARAMETERS ; 1-6. NO POLISH ROUTINE PROCESSING. ; INCREMENT VOLUME TRANSACTION COUNT. ; QUEUE TO ACP. ; ; C. MOUNTED NOT FOREIGN ; 1. XFER FCTN - EITHER OVERLAY OR PRIVILEGED ; TASK I/O. ADDRESS CHECK AND MAP ; BUFFER ADDRESS IN PARAMETER 1. COPY ; PARAMETERS 2-6. QUEUE TO DRIVER. ; 2. DECNET ACP - I/O FUNCTION CODES ARE DISJOINT ; FROM FILES ACPS' FUNCTION CODES. POLISH ; ROUTINE PROCESSING. QUEUED TO DRIVER ; BECAUSE 'UC.QUE' SET. ; 3. ANSI MAGTAPE ACP (MTAACP) - SAME FUNCTION ; CODES AS DISK FILE ACP (F11ACP) BUT ; NOT ALL ARE ALLOWED. POLISH ROUTINE ; PROCESSING. ALL OPERATIONS QUEUED TO ; MTAACP. NO BLOCK LOCKING. ACCESS/DEACCESS ; INTERLOCK BUT NO WINDOW-TURN PENDING ; COUNT BECAUSE EVERYTHING QUEUED TO ACP. ; INCREMENT VOLUME TRANSACTION COUNT. ; 4. FILES-11 DISK ACP (F11ACP) - POLISH ROUTINE ; PROCESSING. TABLE BELOW DESCIBES QUEUING ; AND INTERLOCKING. LEGEND: A=QUEUE TO ACP; ; D=QUEUE TO DRIVER; I=INTERLOCK LUN; ; P=INCREMENT WINDOW TURN PENDING COUNT. ; VOLUME TRANSACTION COUNT INCREMENTED. ; SEE COMMENT LOCATED NEAR CKRAC AND CKWAC ; FOR DESCRIPTION OF WINDOW TURN PENDING ; COUNT ALGORITHM. ; ; ; OPERATION QUEUE INTERLOCK ; ; FIND NAME IN DIRECTORY A 0 ; ENTER NAME IN DIRECTORY A 0 ; REMOVE NAME FROM DIRECTORY A 0 ; ACCESS FILE A I ; DEACCESS FILE D I ; READ/WRITE VIRTUAL BLOCK-MAP OK D 0 ; READ/WRITE VIRTUAL BLOCK-MAP FAIL A P ; READ/WRITE VIRTUAL BLOCK-PARTIAL MAP D I ; EXTEND FILE A P ; CREATE FILE A 0 ; MARK FILE FOR DELETE A 0 ; TRUNCATE FILE D I ; READ ATTRIBUTES A 0 ; WRITE ATTRIBUTES A 0 ; ; DRQRQ: ;MSH045 ;CHF023 ; ;CHF023 ; CHECK SOFTWARE WRITE LOCK ;CHF023 ; ;CHF023 ;CHF023 .IF DF S$$WLK ;CHF023 ;CHF023 BIT #DV.MSD,U.CW1(R5) ;MASS STORAGE DEVICE? ;CHF023 BEQ 20$ ;IF EQ NO ;CHF023 BIT #DV.SWL,U.CW1(R5) ;SOFTWARE WRITE LOCKED? ;CHF023 BEQ 20$ ;IF EQ NO ;CHF023 CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? ;CHF023 BEQ 20$ ;IF EQ YES ;CHF023 CMPB #IO.WLB/256.,I.FCN+1(R1) ;WRITE LOGICAL FUNCTION? ;CHF023 BEQ IEWLK ;IF EQ YES ;CHF023 MOV #WLKTB,R4 ;POINT TO TABLE ;CHF023 MOV I.FCN(R1),R0 ;GET FUNCTION CODE ;CHF023 BIC #7,R0 ;GET RID OF MODIFIERS ;CHF023 10$: CMP (R4)+,R0 ;IS THIS THE FUNCTION CODE? ;CHF023 BEQ IEWLK ;IF EQ YES ;CHF023 TST (R4) ;END OF TABLE? ;CHF023 BNE 10$ ;IF NE NO ;CHF023 20$: ;CHF023 ;CHF023 .ENDC ;S$$WLK ;CHF023 ;CHF023 CALLR $DRQRQ ;QUEUE I/O REQUEST ;MSH045 ;MSH045 ;**-50 ; ;CHF023 ; WRITE ATTEMPTED TO WRITE LOCKED UNIT (WRITE LOCK ERROR) ;CHF023 ; ;CHF023 ;CHF023 IEWLK: MOV #IE.WLK&377,R4 ;SET WRITE LOCK ERROR ;CHF023 BR IECMN ;  ;CHF023 ;CHF023 ; ;MSH152 ; DEVICE ALREADY ATTACHED BY ANOTHER TASK (RESOURCE IN USE) ;MSH152 ; ;MSH152 ;MSH152 IERSU: MOV #IE.RSU&377,R4 ;SET RESOURCE IN USE ;MSH152 BR IECMN ; ;MSH152 ;MSH152 ; ; ILLEGAL BUFFER ADDRESS SPECIFIED-DECLARE ILLEGAL BUFFER STATUS ; IESPC: MOV #IE.SPC&377,R4 ;SET ILLEGAL BUFFER CODE IECOM: BR IECMN ; ; ; ILLEGAL LOAD OVERLAY UCB-DECLARE ILLEGAL LOAD OVERLAY FUNCTION STATUS ; IEOVR: MOV #IE.OVR&377,R4 ;SET ILLEGAL LOAD OVERLAY CODE BR IECMN ; ; ; ILLEGAL BYTE COUNT OR ALIGNMENT-DECLARE ODD BYTE STATUS ; IEBYT: MOV #IE.BYT&377,R4 ;SET ODD BYTE STATUS .IF DF A$$CPS BR IECMN ; ; ; NO BUFFER SPACE AVAILABLE-SET NO BUFFER AVAILABLE STATUS ; IENOD: MOV #IE.NOD&377,R4 ;SET NO BUFFER AVAILABLE CODE BR IECMN ; ; ; BAD PARAMETER-SET BAD PARAMETER STATUS ; IEBAD: MOV #IE.BAD&377,R4 ;SET BAD PARAMETER CODE BR IECMN ; ; ; PRIVILEGE VIOLATION-SET PRIVILEGE VIOLATION STATUS ; .IFTF .IF DF A$$CPS!D$$IAG IEPRI: MOV #IE.PRI&377,R4 ;SET PRIVILEGE VIOLATION CODE BR IECMN ; .ENDC .IFT ; ; FILE ALREADY ACCESSED ON LUN-SET FILE ALREADY ACCESSED STATSU ; IEALN: MOV #IE.ALN&377,R4 ;SET FILE ALREADY ACCESSED CODE BR IECMN ; ; ; NO FILE ACCESSED ON LUN-SET NO FILE ACCESSED STATUS ; IENLN: MOV #IE.NLN&377,R4 ;SET NO FILE ACCESSED STATUS .IF DF,R$$LKL BR IECMN ; ; ; BLOCK LOCKING ERROR OR UNLOCK PERFORMED ; IELCK: MOV R0,R4 ;STATUS IN R0 .ENDC ; ; COMMON ERROR EXIT ; .IFTF IECMN: MOV MSTK,SP ;RESET STACK POINTER MOV (SP)+,R0 ;RETRIEVE ADDRESS OF SECONDARY CONTROL BLOCK BEQ 10$ ;IF EQ NONE CALL $DEPKT ;DEALLOCATE SECONDARY CONTROL BLOCK 10$: MOV R4,R0 ;SET FINAL I/O STATUS CLR R1 ;CLEAR SECOND I/O STATUS WORD MOV (SP)+,R3 ;RETRIEVE ADDRESS OF I/O PACKET .IF DF,A$$CPS TST (SP)+ ;CLEAN STACK .ENDC MOV I.UCB(R3),R5 ;RETRIEVE UCB ADDRESS CALLR $IOFIN ;FINISH OFF I/O OPERATION  ; ; BUILD AN I/O PACKET ; .IFT BDPKT: MOV #2*2,R1 ;SET LENGTH OF FILE ID BLOCK CALL OPPRM ;INSERT OPTIONAL FILE ID BLOCK ; ; BUILD ATTRIBUTE POINTER BLOCK ; ATRBK: MOV (R3)+,(R4)+ ;ATTRIBUTE DESCRIPTOR BLOCK SPECIFIED? BEQ MOVE3 ;IF EQ NO MOV R3,-(SP) ;SAVE ADDRESS OF NEXT DPB WORD MOV #I.LGTH,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $ALOCB ;ALLOCATE SECONDARY CONTROL BLOCK BCS IENOD ;IF CS NO STORAGE AVAILABLE MOV R0,@MSTK ;SAVE ADDRESS OF SECONDARY CONTROL BLOCK  .IF DF M$$MGE MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING .ENDC MOV -(R4),R3 ;RETRIEVE ADDRESS OF ATTRIBUTE DESCRIPTOR BLOCK MOV R0,(R4)+ ;SET POINTER TO SECONDARY CONTROL BLOCK MOV R4,-(SP) ;SAVE ADDRESS OF NEXT WORD IN I/O PACKET MOV R0,R4 ;SET ADDRESS OF FIRST ATTRIBUTE POINTER MOV #6,-(SP) ;SET MAXIMUM NUMBER OF ATTRIBUTE POINTERS 10$: MOV R3,R0 ;SET ADDRESS OF NEXT ATTRIBUTE DESCRIPTOR .IF DF A$$CHK!M$$MGE MOV #4,R1 ;SET SIZE OF ATTRIBUTE DESCRIPTOR CALL $ACHCK ;ADDRESS CHECK ATTRIBUTE DESCRIPTOR BCS IESPC ;IF CS ADDRESS CHECK FAILURE .ENDC .IF DF M$$MGE CALL $RELOM ;RELOCATE AND MAP ATTRIBUTE DESCRIPTOR ADD #4,R3 ;POINT TO NEXT ATTRIBUTE DESCRIPTOR .IFF CMP (R3)+,(R3)+ ;POINT TO NEXT ATTRIBUTE DESCRIPTOR .ENDC MOVB (R0)+,(R4)+ ;INSERT ATTRIBUTE NUMBER BEQ 20$ ;IF EQ END OF ATTRIBUTE DESCRIPTOR BLOCK CLR R1 ;PICKUP SIZE OF ATTRIBUTE BLOCK BISB (R0)+,R1 ; MOVB R1,(R4)+ ;INSERT LENGTH OF ATTRIBUTE BLOCK BNE 15$ ;IF NE LENGTH OKAY MOV #256.*2,R1 ;SET LENGTH FOR ZERO CASE 15$: MOV (R0),R0 ;GET ADDRESS OF ATTRIBUTE BLOCK .IF DF A$$CHK!M$$MGE CALL $ACHCK ;ADDRESS CHECK ATTRIBUTE BLOCK BCS IESPC ;IF CS ADDRESS FAILURE .ENDC CALL $RELOC ;RELOCATE ATTRIBUTE BLOCK ADDRESS MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT ATTRIBUTE BLOCK ADDRESS DEC (SP) ;ANY MORE SPACE IN POINTER BLOCK? BGT 10$ ;IF GT YES 20$: TST (SP)+ ;CLEAN STACK MOV (SP)+,R4 ;RETRIEVE ADDRESS OF NEXT WORD IN I/O PACKET .IF DF M$$MGE MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING .ENDC MOV (SP)+,R3 ;RETRIEVE ADDRESS OF NEXT WORD IN DPB ; ; MOVE EXTEND AND ACCESS CONTROL WORDS INTO I/O PACKET ; MOVE3: MOV (R3)+,(R4)+ ;INSERT EXTEND CONTROL WORDS MOV (R3)+,(R4)+ ; MOV (R3)+,(R4)+ ;INSERT ACCESS CONTROL WORD ; ; INSERT OPTIONAL FILENAME BLOCK ; FILNM: MOV #13.*2,R1 ;SET LENGTH OF FILENAME BLOCK CALL OPPRM ;INSERT OPTIONAL FILENAME BLOCK BR POLJMP ; ;MSH163 ;**-1 ; ; INTERPRET REQUIRED BLOCK ADDRESS ; .ENABL LSB RQPRM: MOV SP,R2 ;SET REQUIRED PARAMETER FLAG BR 10$ ; ; ; INTERPRET OPTIONAL BLOCK ADDRESS ; OPPRM: CLR R2 ;CLEAR REQUIRED PARAMETER FLAG 10$: MOV (R3)+,R0 ;GET ADDRESS OF CONTROL BLOCK BEQ 20$ ;IF EQ NONE SPECIFIED .IF DF A$$CHK!M$$MGE CALL $ACHCK ;ADDRESS CHECK BLOCK BCS IESPC ;IF CS ADDRESS CHECK FAILURE .ENDC CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT BLOCK ADDRESS BR 30$ ; 20$: MOV R2,(R4)+ ;PARAMETER REQUIRED? BNE IEBAD ;IF NE YES CLR (R4)+ ;CLEAR SECOND WORD 30$: RETURN ; .DSABL LSB ; ; FILL DISCONNECT PARAMETER BUFFER AND INTERLOCK LUN USAGE ; .IF DF M$$NET .ENABL LSB CKDIS: MOV (R3)+,(R4)+ ;COPY FIRST PARAMETER TO I/O PACKET BR 10$ ;FINISH IN COMMON CODE ; ; CHECK CONNECT PARAMETER BUFFER ; CKCON: MOV 2(R3),R1 ;GET LENGTH OF BUFFER IN BYTES BEQ IESPC ;IF EQ ZERO LENGTH CALL RQPRM ;INSERT REQUIRED PARAMETER 10$: CALL FCXP2 ;INSERT PARAMETERS BR POLJMP ; ;MSH163 .DSABL LSB ;**-1 .ENDC ; ; CHECK FOR VOLUME MARKED FOR DISMOUNT ; CKDMO: BITB #US.MDM,U.STS(R0) ;VOLUME MARKED FOR DISMOUNT? BNE IEPRI ;IF NE YES BR POLJMP ; ;MSH163 ;**-1 ; ; CHECK VOLUME MOUNTED BY THIS USER ; .ENABL LSB CKMOU: ; .IF DF,M$$MUP MOV R5,-(SP) ;SAVE REGISTER MOV 4(SP),R5 ;GET UCB ADDRESS CALL CXMOU ;CHECK MOUNT LIST BCS 15$ ;ERROR MOV (SP)+,R5 ;RESTORE REGISTER .IFTF POLJMP: JMP @(R5)+ ; ;MSH163 ;**-1 .IFT ; ; SUBROUTINE TO SEARCH MOUNT LIST TO SEE IF VOLUME ; REALLY MOUNTED BY THIS USER ; CXMOU: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; BITB #US.PUB,U.ST2(R5) ;PUBLIC DEVICE? BNE 8$ ;PUBLIC DEVICE OK MOV $TKTCB,R1 ;IS TASK PRIVILEGED? BIT #T3.PRV,T.ST3(R1) BNE 8$ ;PRIVILEGED TASK OK MOV T.UCB(R1),R1 ;GET USER TI: UCB ADDR AS ID MOV #$MOULS,R2 ;GET MOUNT LIST 5$: SEC ;ASSUME FAIL MOV (R2),R2 ;GET MOUNT LIST ENTRY BEQ 9$ ;NONE=DONE=FAIL CMPB #MT.MLS,M.TYPE(R2) ;RIGHT TYPE OF ENTRY? ;MSH163 BNE 5$ ;BRANCH NOT MOUNT ENTRY ;**-1 CMP M.DEV(R2),R5 ;SAME DEVICE UCB? ;MSH163 BNE 5$ ;BRANCH DIFFERENT DEVICE ;**-1 CMP M.TI(R2),R1 ;SAME USER TI:? ;MSH163 BNE 5$ ;BRANCH DIFFERENT USER ;**-1 8$: CLC ;SUCCESS 9$: MOV (SP)+,R2 ;RESTORE REGISTERS MOV (SP)+,R1 ; RETURN ; .ENDC ; ; CHECK FOR READ ACCESS PRIVILEGES ; CKRAC: MOV #WI.RDV,R2 ;SET READ ACCESS MASK WORD BR 10$ ; ; ; CHECK FOR WRITE ACCESS PRIVILEGES ; CKWAC: MOV #WI.WRV,R2 ;SET WRITE ACCESS MASK WORD 10$: BIT R2,@(R1)+ ;DESIRED ACCESS PERMITTED? BNE 20$ ;IF NE YES 15$: JMP IEPRI ;PRIVILEGE VIOLATION ; ; ADDRESS CHECK & INSERT RELOC BIAS, DISP & PARM 2-6 ; 20$: MOV R0,R5 ;GET UCB ADDRESS CALL FACHK ;PERFORM ADDRESS CHECK CALL FCXR1 ;COPY PARAMETERS .IF DF,M$$NET CMP #IO.WVB,4(SP) ;DECNET FUNCTION?? BLT 50$ ;EXIT HERE IF DECNET .ENDC ; ; ONLY READ/WRITE VIRTUAL FUNCTIONS COME HERE ; ; IF ANSI - QUEUE TO MTAACP ; IF F11ACP - PERFORM BLOCK LOCKING AND MAP VIRTUAL TO LOGICAL ; MAP OK - QUEUE TO DRIVER ; MAP FAIL - INCREMENT PENDING & QUEUE TO ACP ; PARTIAL MAP - INTERLOCK & QUEUE TO DRIVER ; ; ; THE ROUTING OF WINDOW TURN REQUESTS DEPENDS ON THE ABILITY ; TO DISTINGUISH BETWEEN REQUESTS THAT MAP TO DISJOINT LBN'S. ; ANY NUMBER OF (SUCCESSFULLY MAPPED) REQUESTS FOR THIS LUN ; MAY BE IN THE DRIVER QUEUE ALREADY. IF THE ACP QUEUE IS EMPTY ; THEN ANY NEXT REQUEST IS OK. IF THE ACP QUEUE CONTAINS ONE ; REQUEST (FROM THE TRANSITION ZERO TO ONE) THEN ANY REQUEST ; THAT MAPS SUCCESSFULLY IS DISJOINT AND OK. IF THE ACP QUEUE ; HAS TWO REQUESTS (OR ONE FROM THE TRANSITION TWO TO ONE) THEN ; WE MUST WAIT FOR ZERO IN ORDER FOR THE SUCCESSFUL MAPPING OF ; VIRTUAL TO LOGICAL TO INDICATE DISJOINT LBNS. AT THIS POINT ; THE LUN IS INTERLOCKED. (EXAMPLE: THREE REQUESTS TO SAME BLOCK; ; FIRST CAUSES WINDOW TURN AND IS COMPLETED; SECOND STILL REMAINS ; IN ACP QUEUE; THE THIRD WILL MAP OK BUT IT CAN NOT BE PERFORMED ; SAFELY UNTIL THE SECOND IS COMPLETE.) ; AN ALTERNATIVE ALGORITHM WOULD BE TO ROUTE ALL VIRTUAL I/O ; REQUESTS TO THE ACP IF THE 'ACP VIRTUAL PENDING COUNT' WERE ; GREATER THAN ZERO. INTERLOCK WOULD OCCUR WHEN COUNT=MAX ; (I.E. NO BITS TO COUNT HIGHER). THE IMPLEMENTED ALGORITHM ; YIELDS BETTER PERFORMANCE WHEN LIMITED TO TWO BITS FOR PENDING ; COUNT AND INTERLOCK: THERE IS LESS LATENCY FOR ANY SECOND ; REQUEST-IT IS QUEUED TO THE DRIVER IF IT CAN BE MAPPED ; SUCCESSFULLY; BOTH ALGORITHMS CAN HANDLE ABOUT THE SAME ; NUMBER OF REQUESTS BEFORE FORCED INTERLOCK OCCURS. IRRESPECTIVE ; OF THE NUMBER OF BITS AVAILABLE, THE ALTERNATIVE ALGORITHM ; ALWAYS HAS THE PROBLEM OF POSSIBLY ROUTING VIRTUAL REQUESTS ; INDEFINITELY TO THE ACP INSTEAD OF THE DRIVER. ; ; PARTIALLY MAPPED REQUESTS OBVIOUSLY SCREW UP EVERYTHING ; BECAUSE OF THE POSSIBILITY OF ACCESSING THE SAME DISK ; BLOCKS SEPARATELY, ONE BLOCK AT A TIME. ; PARTIALLY MAPPED REQUESTS ARE QUEUED TO DRIVER FOR CORRECT ; SEQUENCING: THEY WILL BE PROCESSED AFTER THE OUTSTANDING ; MAPPED REQUESTS IN THE DISK QUEUE; $GTPKT WILL ROUTE ; THESE REQUESTS TO THE ACP SO THEY WILL ALSO FOLLOW ANY ; OUTSTANDING REQUESTS IN THE ACP QUEUE. INTERLOCK IS SET ; SO THAT ANY NEW REQUESTS WILL BE PROCESSED AFTER THE ; PARTIALLY MAPPED ONE IS COMPLETE AND THE WINDOW TURNED. ; ; ; WINDOW TURN PENDING COUNT ALGORITHM ; ; CURRENT ARRIVE ARRIVE DEPART ; STATE 'P' CASES 'I' CASES ALL ; (RWVB MAP (ACCESS, CASES ; FAIL, EXTEND) DEACCESS, ; RWVB PARTIAL ; MAP, TRUNCATE) ; ; 0 0 0 P I 0 XXXX ; 0 P I P I P 0 0 ; I 0 XXXX XXXX 0 0 ; I P XXXX XXXX I 0 ; ; ; NOTE: F11ACP RAISES WINDOW TURN PENDING TO INTERLOCK WHILE ; A WINDOW TURN OPERATION IS IN PROGRESS. THIS MAY INVOLVE ; THE FOLLOWING STATE TRANSITION: ; 0 P -> I 0 ; CKLCK: .IF DF,A$$NSI BITB #US.LAB,U.STS(R5) ;ANSI MAGTAPE?? BNE 40$ ;IF ANSI-NO LOCKING, Q TO ACP .ENDC MOV 10(SP),R1 ;GET ADDRESS I/O PACKET .IF DF,R$$LKL CALL $LCKPR ;PERFORM LOCK PROCESSING BCC 22$ ;CS IF ERROR OR UNLOCK DONE JMP IELCK ; 22$: ;REFERENCE LABEL .ENDC CALL $MPPKT ;MAP VBN TO LBN MOV (SP),R1 ;GET ADDRESS 2ND LUN WORD BCS 30$ ;MAP FAILURE TST R0 ;ALL BLOCKS MAPPED?? BEQ 50$ ; IF .EQ. YES INC (R1) ;PARTIAL MAP-SET INTERLOCK BR 50$ ;AND EXIT HERE 30$: CALL FCPND ;MAP FAILURE - INCR WINDOW PENDING 40$: INC 12(SP) ;MAG TAPE OR MAP FAIL - Q TO ACP 50$: TST (SP)+ ;CLEAN STACK MOV (SP)+,R5 ;RESTORE TO UCB ADDRESS TST (SP)+ ;CLEAN STACK CKJXT: JMP FCXIT .DSABL LSB ; ; CHECK FOR FILE ALREADY ACCESSED ON LUN ; .ENABL LSB CKALN: TST (R1) ;FILE ACCESSED ON LUN? BEQ CKJR5 ;IF EQ NO JMP IEALN ;ERROR ; ; CHECK FOR FILE ACCESSED ON LUN ; CKNLN: TST (R1) ;FILE ACCESSED ON LUN? BNE CKJR5 ;IF NE YES JMP IENLN ;ERROR ; ; SET UP REGISTERS FOR UNLOCK AND EXIT TO CONTROL FUNCTION ; .IF DF R$$LKL UNLXT: TST (R4)+ ;ADVANCE POINTER MOV R0,R5 ;UCB ADDRESS CALL FCXP1 ;COPY PARAMETERS BR CKLCK ; .ENDC ; ; SET ACCESS/DEACCESS INTERLOCK ; CKRLK: INC @(SP) ;SET ACCESS/DEACCESS PENDING INTERLOCK ; ; EXIT POLISH TO FUNCTION EXIT ; CKXIT: TST (SP)+ ;REMOVE ADDRESS OF SECOND LUN WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS TST (SP)+ ;ADJUST STACK PTR MOV U.VCB(R5),R1 ;INCREMENT VOLUME TRANSACTION COUNT BEQ CKJXT ;IN ANY VCB INC (R1) ; BR CKJXT ;EXIT POLISH .ENABL LSB ; ; SET FLAG TO QUEUE TO ACP IF ANSI MAGTAPE ; .IF DF,A$$NSI CKQMT:: BITB #US.LAB,U.STS(R0) ; ANSI MAGTAPE? BEQ 10$ ; IF .EQ. NOT ANSI .ENDC ; ; SET FLAG TO QUEUE TO ACP ; CKACP:: INC 12(SP) ;SET FLAG TO QUEUE TO ACP 10$: JMP @(R5)+ ; .DSABL LSB ; ; INCREMENT WINDOW TURN PENDING COUNT FOR EXTEND ; PENDING COUNT NOT MAINTAINED ANSI MAGTAPE ; CKPND:: .IF DF,A$$NSI BITB #US.LAB,U.STS(R0) ; ANSI MAGTAPE? BNE CKPKT ; IF .NE. YES - SKIP INCR PEND .ENDC TST (R1) ;HAVE A WINDOW? BEQ CKPKT ;NO - DON'T INCR WINDOW PEND NO WINDOW CALL FCPND ;INCREMENT WINDOW TURN PENDING COUNT CKPKT: MOV #FCPKT,R5 ;JOIN COMMON ACP REQUESTS CKJR5: JMP @(R5)+ ; ; ; CHECK IF DELETE OR TRUNCATE OPERATION ; ONLY F11ACP ALLOWS DELETE, ILLEGAL DECNET & MTAACP ; DELETE - FALL THRU SO QUEUE TO ACP ; TRUNCATE BUT NO WINDOW - TREAT LIKE DELETE ; CANT SET INTERLOCK SO MUST Q TO ACP ; TRUNCATE - ADVANCE R5 SO NO QUEUE TO ACP ; & SET INTERLOCK ; CKTRN:: TST (R1) ;HAVE A WINDOW BEQ 10$ ;NO WINDOW - DON'T DO ANYTHING TST 4(R3) ;NEG PARAMETER = TRUNCATE BPL 10$ ;FALL THRU IF NORMAL DELETE TST (R5)+ ;SKIP OVER Q TO ACP INC (R1) ;SET INTERLOCK 10$: JMP @(R5)+ ; ; ; SUBROUTINE TO INCREMENT WINDOW TURN PENDING COUNT ; ; INPUTS: R1 - ADDRESS OF 2ND LUN WORD ; ; OUTPUTS: ALL REGISTERS PRESERVED ; WI.PND SET IN WINDOW ; INTERLOCK SET IF WI.PND WAS ALREADY SET ; FCPND: BIT #WI.PND,@(R1)+ ;PENDING BIT ALREADY SET?? ;**-4 BNE 10$ ;BR IF SET - DO INTERLOCK BIS #WI.PND,@-(R1) ;SET PENDING BIT RETURN 10$: INC -(R1) ;SET INTERLOCK RETURN .ENDC ; END A$$CPS ; ; SUBROUTINES TO COPY PARAMETERS INTO I/O PACKET ; ; INPUTS: ; FCXR1 - R1 RELOCATION BIAS ; R2 DISPLACEMENT BIAS ; R3 PARAMETER PTR ; R4 I/O PACKET PTR ; COPIES R1, R2, AND PARAMETERS 2-6 ; ; FCXP2 - R3, R4 ; COPIES PARAMETERS 2-6 ; ; FCXP1 - R3,R4 ; COPIES PARAMETERS 1-6 ; ; OUTPUTS: R3, R4 UPDATED PTR'S ; FCXR1: MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT DISPLACEMENT BIAS BR FCXP2 ;COPY PARAMETERS 2-6 FCXP1: MOV (R3)+,(R4)+ ;INSERT PARAMETER 1 FCXP2: MOV (R3)+,(R4)+ ;INSERT PARAMETER 2 MOV (R3)+,(R4)+ ;INSERT PARAMETER 3 MOV (R3)+,(R4)+ ;INSERT PARAMETER 4 MOV (R3)+,(R4)+ ;INSERT PARAMETER 5 MOV (R3),(R4) ;INSERT PARAMETER 6 RETURN ; ; ; SUBROUTINE TO PERFORM ADDRESS CHECK AND MAP TRANSFER ; FACHK: MOV (R3)+,R0 ;GET ADDRESS OF USER BUFFER .IF DF,A$$CHK ! M$$MGE MOVB U.CTL(R5),R1 ;GET CONTROL BYTE BPL 10$ ;IF PL BYTE ALLOWED BIT #1,R0 ;IS BUFFER BYE ALIGNED BNE 30$ ;IF NE YES-ALIGNMENT ERROR 10$: BIC #^C,R1 ;CLEAR ALL BUT LENGTH MODULO BITS BIT R1,(R3) ;DOES LENGTH HAVE CORRECT MODULUS BNE 30$ ;IF NE NO ALIGNMENT ERROR MOV (R3),R1 ;GET LENGTH OF BUFFER IN BYTES BEQ 40$ ;IF EQ ILLEGAL BUFFER CALL $ACHKB ;ADDRESS CHECK BUFFER BCS 40$ ;IF CS ADDRESS CHECK ERROR .IFTF CALLR $RELOC ;RELOCATE USER BUFFERR ADDRESS .IFT 30$: JMP IEBYT ; 40$: JMP IESPC ;ILLEGAL *BUFFER ADDRESS .ENDC .END *üðskQ ›c, .TITLE DSDRV .IDENT /08.03/ ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 08.03 ; ; D. N. CUTLER 14-FEB-74 ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; D. N. CUTLER ; C. A. D'ELIA ; ; MODIFIED BY: ; ; P. J. CARR 30-JAN-81 ; ; PJC019 -- REMOVE M$$IXD STUFF ; ; P. J. CARR 30-JAN-81 ; ; PJC020 -- ADD PHYSICAL BLOCK ACCESSING SUPPORT ; FOR RTEM-11 ; ; P. J. CARR 12-JUN-81 ; ; PJC029 -- CORRECT POWERFAIL RECOVERY ; ; RH11-RS03/RS04 FIXED HEAD DISK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; EQUATED SYMBOLS ; RETRY=8. ;ERROR RETRY COUNT RSWC=2 ;WORD COUNT REGISTER RSCS2=10 ;SECOND STATUS REGISTER RSDS=12 ;DRIVE STATUS REGISTER RSER=14 ;ERROR REGISTER RSBAE=30 ;BUS ADDRESS EXTENSION REGISTER ; ;**-7 ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLER NUMBER) ; CNTBL: .BLKW R$$JS1 ;ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW R$$JS1 ;RETRY COUNT FOR CURRENT OPERATION .IF GT R$$JS1-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $DSTBL::.WORD DSINI ;DEVICE INITIATOR ENTRY POINT .WORD DSCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD DSOUT ;DEVICE TIMEOUT ENTRY POINT .WORD DSPWF ;POWERFAIL ENTRY POINT ;+ ; **-DSINI-RH11-RS03/RS04 FIXED HEAD DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB DSINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS DSCAN ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RH11-RS03/RS04 FIXED HEAD DISK I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. ADRS ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; MOV R5,CNTBL(R3) ;SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;IS IT A MASS BUSS DEVICE? BNE 1$ ;IF NE YES -- DOES NOT USE UMR'S CALL $STMAP ;SET UP UNIBUS MAP .ENDC ASL U.BUF(R5) ;SHIFT ADDRESS EXTENSION BITS INTO PLACE ASL U.BUF(R5) ; ASL U.BUF(R5) ; ASL U.BUF(R5) ; 1$: ;REF LABEL .IF DF D$$IAG CMP #IO.WCK!IQ.UMD,I.FCN(R1) ;DIAGNOSTIC WRITE CHECK? BNE 5$ ;IF NE NO BIS #151,U.BUF(R5) ;YES, SET FUNCTION CODE BR 10$ ; .ENDC 5$: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION BIS #171,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BHIS 6$ ;IF HIS FUNCTION IS LEGAL JMP 70$ ;FUNCTION IS ILLEGAL 6$: BEQ 10$ ;IF EQ FUNCTION IS READ SUB #10,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION 10$: MOV #RETRY,RTTBL(R3) ;SET RETRY COUNT ; PJC020 ; PJC020 .IF DF A$$HDR ; PJC020 ; PJC020 BITB #IO.WPB&377,I.FCN(R1) ;PHYSICAL BLOCK FUNCTION? ; PJC020 BNE 30$ ;IF NE YES ; PJC020 ; PJC020 .ENDC ; PJC020 ; PJC020 ; PJC020 CALL $BLKCK ;CHECK LOGICAL BLOCK NUMBER TST U.CW2(R5) ;RS04 DRIVE? BMI 20$ ;IF MI YES ASL R0 ;MULTIPLY RS03 BLOCK 20$: ASL R0 ;CONVERT TO SECTOR AND TRACK ADDRESS MOV R0,I.PRM+12(R3) ;SAVE DISK ADDRESS ; ;**-7 ; INITIATE I/O OPERATION ; 30$: ;REF LABEL .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;IS IT A MASS BUS DEVICE? BNE 300$ ;IF NE YES -- DOES NOT USE UMR'S CALL $MPUBM ;MAP UNIBUS TO MEMORY 300$: ;REF LABEL .ENDC MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS MOVB S.ITM(R4),S.CTM(R4) ;SET CURRENT DEVICE TIMEOUT COUNT ADD #RSCS2,R2 ;POINT TO SECOND CSR MOV #40,(R2) ;CLEAR RH11 CONTROLLER AND ALL DRIVES MOVB U.UNIT(R5),(R2) ;SELECT PROPER DRIVE MOV I.PRM+12(R1),-(R2) ;INSERT DISK ADDRESS MOV U.BUF+2(R5),-(R2) ;INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ;INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ;CONVERT TO WORD COUNT NEG (R2) ;MAKE NEGATIVE WORD COUNT TST -(R2) ;POINT TO CSR REGISTER MOV #IE.DNR&377,R0 ;ASSUME DRIVE NOT READY MOV RSDS(R2),R3 ;GET CONTENTS OF DRIVE STATUS REGISTER COM R3 ;COMPLEMENT STATUS BIT #10200,R3 ;DRIVE READY AND ON-LINE? BEQ 32$ ;IF EQ YES .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;IS DRIVE SPINNING UP? BNE 35$ ;IF NE YES .IFTF .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC OPERATION? BEQ 31$ ;IF EQ NO JMP 45$ ;LOG DIAGNOSTIC DRIVE NOT READY 31$: ;REF LABEL .ENDC .IF DF E$$DVC CALL $DVERR ;LOG DRIVE NOT READY ERROR .ENDC JMP 60$ ;FINISH I/O 32$: ;REF LABEL .IFT  BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP .ENDC .IF DF E$$DVC CALL $BMSET ;SET I/O ACTIVE BIT IN MAP .ENDC .IF DF M$$EXT&M$$MGE BIT #DV.MBC,U.CW1(R5) ;;;IS IT A MASS BUS DEVICE? BEQ 34$ ;;;IF EQ NO -- DOES USE UMR'S MOVB U.BUF+1(R5),RSBAE(R2) ;;;SET ADDRESS EXTENSION BITS MOVB U.BUF(R5),(R2) ;;;START FUNCTION RETURN ;;; .ENDC 34$: MOV U.BUF(R5),(R2) ;;;START FUNCTION ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; DSCAN: RETURN ;;;NOP FOR RS03/RS04 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DSPWF: ;POWERFAIL ENTRY POINT .IF DF P$$RFL TSTB S.STS(R4) ;IS THE DRIVE CURRENTLY BUSY? BEQ 36$ ;IF EQ NO 35$: MOVB #4,S.CTM(R4) ;TIMEOUT IN 4-SECOND INCREMENTS ; PJC029 36$: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP ;**-2 .ENDC RETURN ;WAIT FOR UNIT TO RESPOND ;+ ; **-$DSINT-RH11-RS03/RS04 FIXED HEAD DISK CONTROLLER INTERRUPTS ;- INTSE$ DS,PR5,R$$JS1 ;;;SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,R3 ;COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION EXECUTED? BNE 45$ ;IF NE YES .ENDC BIT #60000,(R2) ;ANY ERRORS? BEQ 55$ ;IF EQ NO .IF DF E$$DVC CALL $DVERR ;LOG DEVICE ERROR .ENDC MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR MOV RSER(R2),R1 ;GET CONTENTS OF ERROR REGISTER BIT #47007,R1 ;HARD ERROR? BNE 40$ ;IF NE YES BIT #14000,RSCS2(R2) ;NEM OR NED? BEQ 50$ ;IF EQ NO 40$: BIT #4000,R1 ;WRITE LOCK ERROR? BEQ 57$ ;IF EQ NO MOV #IE.WLK&377,R0 ;SET WRITE LOCK ERROR BR 60$ ; ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE REQUEST WAS DIAGNOSTIC. TIMEOUTS ARE USUALLY CAUSED ; BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A HARDWARE FAILURE. ; DSOUT: ;;;TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 44$ ;;;IF EQ NO INCB S.STS(R4) ;;;COUNT TIMEOUTS ; PJC029 CMPB #9.,S.STS(R4) ;;;HAVE WE WAITED 32 SECONDS YET? ; PJC029 BEQ 44$ ;;;IF EQ YES ;**-1 MTPS #0 ;;;ALLOW INTERRUPTS JMP 30$ ;RETRY ENTIRE OPERATION 44$: MOVB #1,S.STS(R4) ;;;LEAVE CONTROLLER BUSY ; PJC029 BICB #US.SPU,U.STS(R5) ;;;RESET DRIVE SPINNING UP ;**-1 .ENDC CALL $DTOER ;;;LOG DEVICE TIMEOUT .IF DF D$$IAG BCC 50$ ;IF CC TIMEOUT DURING NORMAL FUNCTION 45$: CALL $CRPAS ;PASS CONTROLLER REGISTERS TO TASK BR 60$ ;DIAGNOSTIC PROCESSING COMPLETE .ENDC 50$: MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE 57$ ;IF NE YES DEC RTTBL(R3) ;RETRY FUNCTION? BLE 57$ ;IF LE NO 51$: JMP 30$ ;RETRY OPERATION 55$: ;REF LABEL .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ;WRITE FOLLOWED BY WRITE CHECK? BNE 56$ ;IF NE YES BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED BY MCR? BEQ 60$ ;IF EQ NO 56$: MOVB U.BUF(R5),R1 ;GET LAST FUNCTION CMPB #171,R1 ;WAS IT A READ? BEQ 60$ ;IF EQ YES MOVB #151,U.BUF(R5) ;ASSUME A WRITE CHECK OPERATION CMPB #161,R1 ;WAS LAST FUNCTION A WRITE? BNE 60$ ;IF NE NO MOV #RETRY,RTTBL(R3);REINITIALIZE RETRY COUNT BR 51$ ;START WRTIE CHECK OPERATION .IFTF 57$: ;REF LABEL .IFT BIT #40000,RSCS2(R2) ;WRITE CHECK ERROR? BEQ 60$ ;IF EQ NO MOV #IE.WCK&377,R0 ;SET WRITE CHECK ERROR .ENDC 60$: MOV RSWC(R2),R1 ;GET WORDS REMAINING TO TRANSFER ASL R1 ;CONVERT TO BYTES LEFT TO TRANSFER ADD U.CNT(R5),R1 ;CALCULATE BYTES ACTUALLY TRANSFERED MOV #40011,(R2) ;LCLEAR CONTROLLER AND DRIVE 70$: ;REF LABEL .IF DF E$$DVC MOVB S.CON(R4),R3 ;RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ;MERGE STARTING RETRY COUNT .ENDC CALL $IODON ;FINISH I/O OPERATION ;**-7 JMP DSINI ;PROCESS NEXT REQUEST .DSABL LSB .END LÑØwkQ ›c, .TITLE DRASG .IDENT /06.05/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 06.05 ; ; D. N. CUTLER 18-SEP-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 19-DEC-79 ; MSH074 -- CLEANUP CODE AND COMMENTS ; ; M. S. HARVEY 9-JAN-80 ; MSH084 -- HANDLE UNASSIGNED LUN DURING SEARCH ; ; MACRO LIBRARY CALLS ; .MCALL TCBDF$ TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$DRASG-ASSIGN LUN ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO ASSIGN A DEVICE UNIT TO A ; LOGICAL UNIT NUMBER (LUN). ; ; DPB FORMAT: ; ; WD. 00 -- DIC(7.),DPB SIZE(4.). ; WD. 01 -- LUN TO BE ASSIGNED. ; WD. 02 -- NAME OF DEVICE TO BE ASSIGNED. ; WD. 03 -- UNIT NUMBER OF DEVICE TO BE ASSIGNED. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LUN IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS90' IS RETURNED IF A FILE ; IS OPEN OR UNIT ATTACHED ON THE SPECIFIED LUN ;MSH074 ; AND NO OTHER LUN IS ASSIGNED TO THAT UNIT. ;MSH074 ; DIRECTIVE STATUS OF 'D.RS92' IS RETURNED IF DEVICE ;**-1 ; AND/OR UNIT IS INVALID. ;- $DRASG::CALL $MPLUN ;MAP LUN TO DEVICE UCB TST (R1) ;FILE ACCESSED ON LUN? BNE 40$ ;IF NE YES MOV R0,-(SP) ;SAVE ADDRESS OF UCB MOV R1,R4 ;SAVE ADDRESS OF SECOND LUN WORD MOV (R3)+,R2 ;GET NAME OF DEVICE MOVB (R3),R0 ;GET UNIT NUMBER .IF DF L$$ASG .IF DF M$$MUP BIT #T3.SLV,T.ST3(R5) ;SLAVE TASK? BNE 17$ ;IF NE YES, BYPASS LOGICAL DEVICE TABLE .ENDC MOV #$LOGHD,R3 ;POINT TO LOGICAL ASSIGNMENT LIST 13$: MOV (R3),R3 ;GET ADDRESS OF NEXT ENTRY BEQ 17$ ;IF EQ END OF LIST TSTB L.TYPE(R3) ;SYSTEM WIDE ASSIGNMENT? BEQ 15$ ;IF EQ YES CMP L.UCB(R3),T.UCB(R5) ;TI UCB ADDRESS MATCH? BNE 13$ ;IF NE NO 15$: CMP R2,L.NAM(R3) ;DEVICE NAME MATCH? BNE 13$ ;IF NE NO CMPB R0,L.UNIT(R3) ;UNIT NUMBER MATCH? BNE 13$ ;IF NE NO MOV L.ASG(R3),R1 ;GET ASSIGNMENT UCB ADDRESS BR 25$ ;FINISH IN COMMON CODE .ENDC 17$: MOV #$DEVHD,R3 ;POINT TO PHYSICAL DEVICE TABLES 20$: MOV (R3),R3 ;GET ADDRESS OF NEXT DCB BEQ 50$ ;IF EQ END OF TABLES CMP R2,D.NAM(R3) ;DEVICE NAME MATCH? BNE 20$ ;IF NE NO CMPB R0,D.UNIT(R3) ;UNIT GREATER THAN OR EQUAL TO LOW BOUNDRY? BLO 20$ ;IF LO NO CMPB R0,D.UNIT+1(R3) ;UNIT LESS THAN OR EQUAL TO HIGH BOUNDRY? BHI 20$ ;IF HI NO SUB D.UNIT(R3),R0 ;CALCULATE RELATIVE UNIT NUMBER BIC #177400,R0 ;CLEAR EXCESS BITS MOV D.UCBL(R3),R1 ;GET LENGTH OF UCB IN BYTES CALL $MUL ;CALCULATE NUMBER OF BYTES ADD D.UCB(R3),R1 ;CALCULATE ADDRESS OF UCB 25$: MOV (SP)+,R3 ;WAS LUN PREVIOUSLY ASSIGNED? BEQ 30$ ;IF EQ NO CMP R5,U.ATT(R3) ;UNIT ATTACHED TO CURRENT TASK? BNE 27$ ;IF NE NO MOV R1,-(SP) ;SAVE NEW ASSIGNMENT UCB ADDRESS MOV R1,R0 ;COPY UCB ADDRESS CALL $MPLND ;MAP TO REAL UCB ADDRESS CMP R0,R3 ;NEW ASSIGNMENT TO SAME FINAL UCB? ;**-1 BNE 35$ ;IF EQ NO MOV (SP)+,R1 ;RETRIEVE NEW ASSIGNMENT UCB ADDRESS ;MSH074 27$: MOV R3,R5 ;COPY OLD ASSIGNMENT UCB ADDRESS ;MSH074 ; ;MSH074 ; BEFORE REASSIGNING THIS LUN, MAKE SURE THAT ALL I/O REQUESTS ;MSH074 ; ASSOCIATED WITH THE OLD ASSIGNMENT ARE ELIMINATED SO THAT THEY ;MSH074 ; CANNOT POSSIBLY BE ASSOCIATED WITH THE NEW LUN CONTEXT. (THE ;MSH074 ; I/O PACKET HAS A POINTER TO THE SECOND WORD OF ITS LUN.) ALSO, ;MSH074 ; SINCE I/O KILL INCLUDES NO MECHANISM FOR HANDLING LUN SPECIFIC ;MSH074 ; KILLING, ESPECIALLY AT THE DRIVER/CURRENT-PACKET LEVEL, ALL I/O ;MSH074 ; ASSOCIATED WITH THE DEVICE ACCESSED THRU THE OLD ASSIGNMENT MUST ;MSH074 ; BE ELIMINATED, REGARDLESS OF WHICH LUN THE I/O WAS ORIGINALLY ;MSH074 ; ISSUED FROM. ;MSH074 ; ;MSH074 ;MSH074 MOV #$IOKIL,-(SP) ;SET TO KILL I/O ON PREVIOUS ASSIGNMENT 30$: MOV R1,-(R4) ;ASSIGN LUN TO NEW UNIT RETURN ; ;MSH074 35$: MOV $HEADR,R1 ;GET TASK HEADER ;MSH074 ADD #H.NLUN,R1 ;POINT TO THE NUMBER OF LUNS ;**-2 MOV (R1),-(SP) ;PICK UP COUNT 37$: CMP (R1)+,(R1)+ ;ADVANCE TO NEXT UCB POINTER + 2 CMP R1,R4 ;SAME LUN AS BEING REASSIGNED? BEQ 39$ ;IF EQ YES MÚOV -2(R1),R0 ;GET THIS LUN ASSIGNMENT BEQ 39$ ;IF EQ LUN IS UNASSIGNED, SKIP IT ;MSH084 CALL $MPLND ;FOLLOW ANY REDIRECT; HANDLE TI: CMP R0,R3 ;LUN ASSIGNED TO SAME DEV AS REASS LUN? BNE 39$ ;NO, BRANCH TST (SP)+ ;REMOVE COUNT MOV (SP)+,R1 ;GET NEW LUN ASSIGNMENT BR 27$ ;ATTACH CAN BE IGNORED 39$: DEC (SP) ;POINT TO NEXT LUN BGT 37$ ;TRY AGAIN 40$: DRSTS D.RS90 ;SET DIRECTIVE STATUS ;**-1 50$: DRSTS D.RS92 ;SET DIRECTIVE STATUS .END Úm„kQ ›c, .TITLE QUEUE .IDENT /06.07/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 06.07 ; ; D. N. CUTLER 3-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; C. A. D'ELIA ; T. J. MILLER ; J. A. SCHRIESHEIM ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 20-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 2-JUN-80 ; MSH103 -- CLEAN UP COMMAND LINE INTERPRETER REQUESTING ; ; M. S. FOX 07-JAN-81 ; MF203 -- INITIAL ALTERNATE CLI SUPPORT ; ; M. S. HARVEY 3-FEB-81 ; MSH132 -- DEFINE C.SYST CLOCK BLOCK CODE FOR USE BY ; CINT$ INTERRUPT ROUTINES ; ; M. S. FOX 03-FEB-81 ; MF208 -- ADD COMMAND ARRIVAL ASTS FOR CLIS ; ; GENERAL QUEUE MANIPULATION ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$,TCBDF$ CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSETS TCBDF$  ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$CLINS-CLOCK QUEUE INSERTION ; ; THIS ROUTINE IS CALLED TO MAKE AN ENTRY IN THE CLOCK QUEUE. THE ENTRY ; IS INSERTED SUCH THAT THE CLOCK QUEUE IS ORDERED IN ASCENDING TIME. ; THUS THE FRONT ENTRIES ARE MOST IMMINENT AND THE BACK LEAST. ; ; INPUTS: ; ; R0=ADDRESS OF THE CLOCK QUEUE ENTRY CORE BLOCK. ; R1=HIGH ORDER HALF OF DELTA TIME. ; R2=LOW ORDER HALF OF DELTA TIME. ; R4=REQUEST TYPE. ; R5=ADDRESS OF REQUESTING TCB OR REQUEST IDENTIFIER. ; ; OUTPUTS: ; ; THE CLOCK QUEUE ENTRY IS INSERTED IN THE CLOCK QUEUE ACCORDING ; TO THE TIME THAT IT WILL COME DUE. ;- .ENABL LSB $CLINS::CLR (R0)+ ;POINT TO TYPE FIELD AND CLEAR LINK MOVB R4,(R0)+ ;SET REQUEST TYPE INC R0 ;ADVANCE TO TCB ADDRESS MOV R5,(R0)+ ;SET TCB OR REQUEST IDENTIFIER ADD $ABTIM,R2 ;CALCULATE ABSOLUTE TIME WHEN ADC R1 ;REQUEST WILL COME DUE MOV R2,(R0)+ ;SET LOW ORDER PART OF TIME MOV R1,(R0) ;SET HIGH ORDER PART OF TIME MOV #$CLKHD,R2 ;POINT TO CLOCK QUEUE LIST HEAD 10$: MOV R2,R1 ;SAVE ADDRESS OF PREVIOUS ENTRY MOV (R1),R2 ;GET ADDRESS OF NEXT ENTRY BEQ 20$ ;IF EQ END OF LIST CMP (R0),C.TIM+2(R2) ;COMPARE HIGH ORDER TIMES BHI 10$ ;IF HI NOT THIS ENTRY BLO 20$ ;IF LO ENTRY GOES HERE CMP -2(R0),C.TIM(R2) ;COMPARE LOW ORDER TIMES BHIS 10$ ;IF HIS NOT THIS ENTRY 20$: SUB #8.,R0 ;BACK UP TO FRONT OF BLOCK MOV R0,(R1) ;SET NEW NEXT IN PREVIOUS ENTRY MOV R2,(R0) ;SET NEXT IN NEW ENTRY .IF DF L$$DRV&M$$MGE!C$$INT&M$$MGE ;MSH132  ;**-1 CMPB #C.SYST,R4 ;A SYSTEM ROUTINE REQUEST (DRIVER)? BNE 30$ ;IF NE NO MOV KISAR5,C.AR5(R0) ;SAVE APR5 MAPPING .ENDC 30$: RETURN ; ;+ ; **-$CLRMV-CLOCK QUEUE REMOVAL ; **-$CLRSM-CLOCK QUEUE REMOVAL - SELECTIVE MARK TIME ; ; THIS ROUTINE IS CALLED TO REMOVE ALL ENTRIES FOR A SPECIFIED TCB ADDRESS ; AND REQUEST TYPE FROM THE CLOCK QUEUE, OR SELECTIVELY BY EFN OR AST ; ADDRESS IF ENTRY AT $CLRSM. ; ; INPUTS: ; ; R1=EFN NUMBER OR 0 (IF ENTRY AT $CLRSM). ; R2=AST ADDRESS OR 0 (IF ENTRY AT $CLRSM). ; R4=REQUEST TYPE. ; R5=ADDRESS OF REQUESTING TCB OR SYSTEM SUBROUTINE. ; ; OUTPUTS: ; ; ALL OF THE MATCHING ENTRIES FOR THE SPECIFIED TCB ADDRESS ARE ; REMOVED FROM THE CLOCK QUEUE. IF THE REQUEST TYPE IS NOT 'C.SYST', ; THEN THE CLOCK QUEUE ENTRY CORE BLOCK IS RELEASED. ;- $CLRMV:: ;REF LABEL .IF DF C$$SMT CLR R1 ;MATCH ON ANY EVENT FLAG (MKTM ONLY) CLR R2 ;MATCH ON ANY AST ADDRESS (MKTM ONLY) $CLRSM:: ;REF LABEL .IFTF ;C$$SMT MOV #$CLKHD,R0 ;POINT TO CLOCK QUEUE LISTHEAD 40$: MOV R0,R3 ;SAVE ADDRESS OF PREVIOUS ENTRY MOV (R3),R0 ;GET ADDRESS OF NEXT ENTRY BEQ 30$ ;IF EQ END OF LIST CMPB R4,C.RQT(R0) ;REQUEST TYPE MATCH? BNE 40$ ;IF NE NO CMP R5,C.TCB(R0) ;TCB OR SYSTEM SUBROUTINE ADDRESS MATCH? BNE 40$ ;IF NE NO .IF DF C$$SMT!G$$EFN ;MSH049 ;**-1 TST R4 ;MARK TIME ENTRY? BNE 60$ ;IF NE NO ;MSH049 .ENDC ;MSH049 ;MSH049 .IFT ;C$$SMT ;MSH049 ;MSH049 TSTB R1 ;EFN SPECIFIED? BEQ 50$ ;IF EQ NO CMPB R1,C.EFN(R0) ;MATCH ON EFN? BEQ 55$ ;IF EQ YES, REMOVE ENTRY ;MSH049 TST R2 ;AST ADDRESS SPECIFIED? ;**-1 BEQ 40$ ;IGNORE PACKET 50$: TST R2 ;AST SPECIFIED? BEQ 55$ ;IF EQ NO ;MSH049 CMP R2,C.AST(R0) ;MATCH ON AST? ;**-1 BNE 40$ ;IF NE NO 55$: ;REF LABEL ;MSH049 ;**-1 .IFTF ;C$$SMT .IF DF G$$EFN ;MSH049 ;MSH049 MOV R2,-(SP) ;SAVE AST ADDRESS ;MSH049 MOV R1,-(SP) ;SAVE EVENT FLAG ;MSH049 MOV R3,-(SP) ;SAVE ADDRESS OF PREVIOUS ENTRY ;MSH049 MOV C.DST(R0),R3 ;GET EVENT FLAG MASK ADDRESS ;MSH049 MOV T.PCB(R5),R4 ;GET TASK PCB ;MSH049 MOV P.HDR(R4),R4 ;GET HEADER ;MSH049 CALL $DEAGF ;DEACCESS IF GROUP GLOBAL ;MSH049 MOV (SP)+,R3 ;RESTORE ADDRESS OF PREVIOUS ENTRY ;MSH049 MOV (SP)+,R1 ;RESTORE EVENT FLAG ;MSH049 MOV (SP)+,R2 ;RESTORE AST ADDRESS ;MSH049 MOV (R3),R0 ;RESTORE ADDRESS OF CURRENT CLOCK BLK ;MSH049 CLR R4 ;RESTORE MARK TIME REQUEST TYPE ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 60$: MOV (R0),(R3) ;REMOVE ENTRY FROM LIST ;MSH049 CMPB #C.SYST,C.RQT(R0) ;SYSTEM SUBROUTINE REQUEST? ;**-1 BEQ 40$ ;IF EQ YES CONTINUE .IFT ;C$$SMT MOV R2,-(SP) ;SAVE NECESSARY REGISTERS MOV R1,-(SP) ; .IFTF ;C$$SMT CALL $DECLK ;DEALLOCATE ENTRY CORE BLOCK .IFT ;C$$SMT MOV (SP)+,R1 ;RESTORE SAVED REGISTERS MOV (SP)+,R2 ; BR $CLRSM ;GO AGAIN .IFF ;C$$SMT BR $CLRMV ;GO AGAIN .ENDC ;C$$SMT .DSABL LSB ;+ ; **-$QINSF-QUEUE INSERTION AT END OF LIST (FIFO) ; ; THIS ROUTINE IS CALLED TO MAKE AN ENTRY IN A FIRST IN FIRST OUT ; LIST. THE ENTRY IS LINKED TO THE END OF THE LIST. ; ; INPUTS: ; ; R0=ADDRESS OF THE TWO WORD LISTHEAD. ; R1=ADDRESS OF THE ENTRY TO BE INSERTED. ; ; OUTPUTS: ; ; THE ENTRY IS LINKED TO THE END OF THE QUEUE. ; ; R0 AND R1 ARE PRESERVED ACROSS CALL. ;- .ENABL LSB $QINSF::MOV 2(R0),R2 ;GET ADDRESS OF LAST ENTRY IN LIST BR 20$ ;FINISH IN COMMON CODE ;+ ; **-$QINSP-QUEUE INSERTION BY PRIORITY ; ; THIS ROUTINE IS CALLED TO INSERT AN ENTRY IN A PRIORITY ORDERED ; LIST. THE LIST IS SEARCHED UNTIL AN ENTRY IS FOUND THAT HAS A ; LOWER PRIORITY OR THE END OF THE LIST IS REACHED. THE NEW ; ENTRY IS THEN LINKED INTO THE LIST AT THE APPROPRIATE POINT. ; ; INPUTS: ; ; R0=ADDRESS OF THE TWO WORD LISTHEAD. ; R1=ADDRESS OF THE ENTRY TO BE INSERTED. ; ; ; OUTPUTS: ; ; THE ENTRY IS LINKED INTO THE LIST BY PRIORITY. ; ; R0 AND R1 ARE PRESERVED ACROSS CALL. ;- $QINSP::MOV R0,R3 ;COPY ADDRESS OF LISTHEAD 10$: MOV R3,R2 ;SAVE ADDRESS OF CURRENT ENTRY MOV (R2),R3 ;GET ADDRESS OF NEXT ENTRY BEQ 20$ ;IF EQ END OF LIST CMPB T.PRI(R1),T.PRI(R3) ;NEW ENTRY LOWER OR SAME PRIORITY? BLOS 10$ ;IF LOS YES MOV R3,(R1) ;LINK CURRENT TO NEW ENTRY BR 30$ ; 20$: MOV R1,2(R0) ;SET ADDRESS OF NEW LAST CLR (R1) ;CLEAR LINK TO NEXT ENTRY 30$: MOV R1,(R2) ;LINK NEW TO PREVIOUS ENTRY RETURN ; .DSABL LSB ;+ ; MF203 ; **-$QMCRL-QUEUE A COMMAND LINE TO THE CLI OF A TERMINAL ; MF203 ; **-$QCLIL-QUEUE A COMMAND LINE TO A SPECIFIED CLI ; MF203 ; **-$QMCR -QUEUE A COMMAND LINE TO MCR ; MF203 ; **-$QCLNR-QUEUE A COMMAND BUT NO CLI REQUEST (A$$CLI SYSTEMS ONLY) ; MF203 ; ; MF203 ; THESE ROUTINES ARE CALLED TO QUEUE A COMMAND LINE TO A COMMAND ; MF203 ; LINE INTERPRETER AND REQUEST EXECUTION OF THE CLI. ; MF203 ; ; MF203 ; INPUTS: ; MF203 ; ; MF203 ; R0=TCB ADDRESS OF CLI ($QCLIL ONLY) ; MF203 ; R1=ADDRESS OF THE COMMAND LINE CONTROL BLOCK ; MF203 ; ; MF203 ; OUTPUTS: ; MF203 ; ; MF203 ; THE CLI THE COMMAND IS INTENDED FOR IS DETERMINED AND REQUESTED ; MF203 ; WITH THE SPECIFIED COMMAND LINE. ; MF203 ;- ; MF203 ; MF203 .IF NDF A$$CLI ; MF203 ; MF203 $QMCRL:: ;REF LABEL ; MF203 .IF DF M$$CLI ; MF203 ; MF203 MOV 2(R1),R0 ;GET TERMINAL UCB ADDRESS ; MF203 BIC #1,R0 ;CLEAR PROMPT FLAG ; MF203 CALL $MPLND ;FOLLOW REDIRECTION ; MF203 MOV @U.CLI(R0),R0 ;EXTRACT TERMINAL'S CLI TCB ADDRESS ; MF203 BR $QCLIL ;QUEUE COMMAND LINE AND REQUEST CLI ; MF203 ; MF203 .ENDC ;M$$CLI ; MF203 ; MF203 ; MF203 $QMCR:: MOV $MCRPT,R0 ;EXTRACT MCR'S TCB ADDRESS ; MF203 $QCLIL::CALLR $EXRQF ;PASS LINE TO CLI AND REQUEST CLI ; MF203 $QCLNR:: ;ROUTINE DOES NOT EXIST WITHOUT A$$CLI ; MF203 ; MF203 .IFF ; NDF A$$CLI ; MF203 ; MF203 .ENABL LSB  ; MF203 $QCLIL::CMP $MCRPT,R0 ;IS TARGET CLI THE DISPATCHER ; MF203 BEQ $QMCR ;IF EQ YES, SEND CMD TO MCR ; MF203 MOV R0,-(SP) ;SAVE CLI TCB ADDRESS ; MF203 BR 10$ ; ; MF203 $QCLNR::CLR -(SP) ;DO NOT REQUEST CLI ; MF203 10$: ; MF203 ; MF208 .IF DF A$$TRP ; MF208 ; MF208 MOV R0,-(SP) ;SAVE TCB ADDRESS AGAIN ; MF208 ; MF208 .IFTF ; MF208 ; MF208 MOV #$CLICQ,R0 ;POINT TO CMD QUEUE LISTHEAD ; MF208 CALL $QINSF ;INSERT COMMAND IN QUEUE ; MF208 ; MF208 .IFT ;A$$TRP ; MF208 ; MF208 MOV (SP)+,R0 ;RETREIVE TCB ADDRESS OF CLI ; MF208 MOV R1,-(SP) ;SAVE ADDRESS OF COMMAND ; MF208 CALL $DCAST ;DECLARE COMMAND ARRIVAL AST ; MF208 MOV (SP)+,R1 ;RESTORE CMD ADDRESS ; MF208 BCS 20$ ;IF CS, NO AST SO REQUEST ; MF208 TST (SP)+ ;CLEAN STACK ; MF208 RETURN ; MF208 ; MF208 .ENDC ;A$$TRP ; MF208 ; MF203 ; MF203 20$: MOV (SP)+,R0 ;RESTORE TCB ADDR OR ZERO ; MF203 BNE 25$ ;IF NE, REQUEST CLI ; MF203 RETURN ; MF203 25$: CALLR $EXRQN ;REQUEST CLI AND RETURN ; MF203 $QMCR:: MOV #40,R2 ;SET FLAG TO SPECIFY MCR ; MF203 BR 30$ ; ; MF203 $QMCRL::CLR R2 ;GO WITH DEFAULT CLI ; MF203 30$: BIT #1,2(R1) ;IS BUFFER A PROMPT REQUEST ; MF203 BNE 50$ ;IF NE YES ; MF203 CMPB M$$CRB-1(R1),#33 ;IS LAST CHAR AN ESCAPE ; MF203 BEQ 40$ ;IF EQ YES ; MF203 MOVB #15,M$$CRB-1(R1) ;FORCE A CARRIAGE RETURN ; MF203 40$: BISB R2,M$$CRB-1(R1) ;SET FORCE TO MCR INDICATOR ; MF203 50$: MOV $MCRPT,R0 ;POINT TO MCR'S TCB ; MF203 CALLR $EXRQF ;INSERT COMMAND IN QUEUE AND REQUEST ; MF203 .DSABL LSB ; MF203 ; MF203 .ENDC ;A$$CLI ; MF203 ; MF203 ;**-34 ;+ ; **-$QRMVF-QUEUE REMOVAL FROM FRONT OF LIST ; ; THIS ROUTINE IS CALLED TO REMOVE THE NEXT (FRONT) ENTRY FROM A ; LIST. THE LIST ORGANIZATION MAY BE EITHER FIFO OR BY PRIORITY. ; ; INPUTS: ; ; R0=ADDRESS OF THE TWO WORD LISTHEAD. ; ; OUTPUTS: ; ; C=1 IF THERE ARE NO ENTRIES IN THE LIST. ; C=0 IF THE NEXT ENTRY IS REMOVED FROM THE LIST. ; R1=ADDRESS OF THE ENTRY REMOVED. ; ; R0 IS PRESERVED ACROSS CALL. ;- .ENABL LSB $QRMVF::MOV R0,R2 ;COPY ADDRESS OF LISTHEAD MOV (R2),R3 ;GET ADDRESS OF NEXT ENTRY BNE 30$ ;IF NE LIST HAS AN ENTRY 10$: SEC ;NO ENTRIES IN LIST RETURN ; ;+ ; **-$QRMVT-QUEUE REMOVAL BY TCB ADDRESS ; ; THIS ROUTINE IS CALLED TO REMOVE THE NEXT ENTRY FROM A LIST THAT ; MATCHES A SPECIFIED TCB ADDRESS. THE LIST ORGANIZATION MAY BE ; EITHER FIFO OR BY PRIORITY. ; ; INPUTS: ; ; R0=ADDRESS OF THE TWO WORD LISTEAD. ; R1=ADDRESS OF THE TCB TO SEARCH FOR. ; ; OUTPUTS: ; ; C=1 IF THERE IS NO ENTRY IN THE LIST THAT MATCHES THE TCB ADDRESS. ; C=0 IF A MATCHING ENTRY IS REMOVED FROM THE LIST. ; R1=ADDRESS OF THE ENTRY REMOVED. ; ; R0 IS PRESERVED ACROSS CALL. ;- $QRMVT::MOV R0,R3 ;COPY ADDRESS OF LISTHEAD 20$: MOV R3,R2 ;SAVE ADDRESS OF CURRENT ENTRY MOV ˆ(R2),R3 ;GET ADDRESS OF NEXT ENTRY BEQ 10$ ;IF EQ END OF LIST CMP R1,R3 ;MATCH ON TCB ADDRESS? BEQ 30$ ;IF EQ YES CMP R1,C.TCB(R3) ;MATCHING TCB ADDRESS? BNE 20$ ;IF NE NO 30$: MOV (R3),(R2) ;CLOSE UP LIST BNE 40$ ;IF NE NO NEW LAST MOV R2,2(R0) ;SET ADDRESS OF NEW LAST 40$: MOV R3,R1 ;SET ADDRESS OF ENTRY REMOVED CLC ;SUCCESS RETURN ; .DSABL LSB .END ˆÓ`TkQ ›c, .TITLE DRCMT .IDENT /06.03/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 06.03 ; ; D. N. CUTLER 31-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 1-SEP-79 ; MSH052 -- ALWAYS DEFINE CANCEL SELECTIVE MARK TIME ; ENTRY POINT FOR DIRECTIVE DISPATCHER  ; ; M. S. HARVEY 19-DEC-79 ; MSH075 -- DEFINE SPECIAL ENTRY POINT FOR ERROR LOGGING ; ON NON-DIRECTIVE COMMON SYSTEMS ; ** RETRACTED FOR NEW ERROR LOGGER - 20-JAN-81 ** ; ; CANCEL MARK TIME AND SCHEDULE REQUESTS DIRECTIVES ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$ CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSETS ;+ ; **-$DRCMT-CANCEL MARK TIME REQUESTS ; **-$DRCMS-CANCEL SELECTIVE MARK TIME REQUESTS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CANCEL ALL MARK TIME REQUESTS ; (DPB SIZE=1) OR ALL REQUESTS WITH MATCHING EVENT FLAG OR AST ADDRESS ; (DPB SIZE=3). ; ; DPB FORMAT. ; ; WD. 00 -- DIC(27.), DPB SIZE(1. OR 3.) ; WD. 01 -- EFN NUMBER ; WD. 02 -- AST ADDRESS ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF WD. 00 + 2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; NOTE: $DRCMT IS ALSO CALLED FROM THE EXIT DIRECTIVE AND ; ONLY REQUIRES R5 TO BE LOADED ON ENTRANCE. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ;- .ENABL LSB $DRCMS:: ;REF LABEL ;MSH052 .IF DF C$$SMT ;**-1 CMPB -(R3),#1 ;DPB SIZE = 1? ;MSH052 BEQ $DRCMT ;IF EQ YES, CANCEL ALL MARK TIMES ;**-1 CMPB (R3)+,#3 ;DPB SIZE = 3? BNE 5$ ;IF NE NO, INVALID DPB SIZE MOV (R3)+,R1 ;PICK UP SPECIFIED EFN MOV (R3),R2 ;PICK UP SPECIFIED AST ADDRESS CLR R4 ;SET MARK TIME CODE CALLR $CLRSM ;CANCEL SELECTED MARK TIME ENTRIES .IFTF ;C$$SMT $DRCMT::CLR R4 ;SET TYPE OF REQUEST TO REMOVE BR 10$ ;REMOVE ALL MARK TIME ENTRIES. .IFT ;C$$SMT 5$: DRSTS D.RS99 ;INVALID DPB SIZE .ENDC ;C$$SMT ;+ ; **-$DRCSR-CANCEL SCHEDULE REQUESTS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CANCEL ALL SCHEDULE REQUESTS FOR A ; SPECIFIED TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(25.),DPB SIZE(3.). ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB TO CANCEL SCHEDULE REQUESTS FOR. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO CANCEL SCHEDULE REQUES ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ;- $DRCSR::MOV R0,R5 ;SET TCB ADDRESS CLR R4 ;SET INITIAL ENTRY TYPE MINUS 2 CALL (PC) ;REMOVE PERIODIC/SINGLE €SHOT REQUESTS TST (R4)+ ;ADVANCE TO NEXT ENTRY TYPE 10$: CALLR $CLRMV ;REMOVE ALL REMAINING ENTRIES .DSABL LSB .END €âX kQ ›c, .TITLE DRREG .IDENT /03.13/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 03.13 ; ; T. J. MILLER 12-MAR-76 ; ; PREVIOUSLY MODIFIED BY: ; ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 25-JUL-79 ; MSH046 -- ADD ASYNCHRONOUS BUFFERED I/O SUPPORT ; ; M. S. HARVEY 3-OCT-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT ; ; M. S. HARVEY 19-DEC-79 ; MSH072 -- DON'T ALLOW REGIONS TO BE CREATED OUTSIDE ; THE TARGET SYSTEM-CONTROLLED PARTITION ; ; M. S. HARVEY 2-JUL-80 ; MSH096 -- SUPPORT ALTERNATE HEADER REFRESH AREAS ; ; M. S. HARVEY 7-AUG-80 ; MSH110 -- DON'T DESTROY STATIC COMMON ON DETACH ; ; M. S. HARVEY 15-DEC-80 ; MSH130 -- ALLOW RETURN OF SUCCESS STATUS FOR CREATE ; REGION WITHOUT SYS-CONTROLLED PARTITIONS ; ; M. S. HARVEY 14-SEP-81 ; MSH191 -- DON'T DUPLICATE EXISTING ATTACHMENT ; ; J. M. LAWLER 7-DEC-81 ; JML095 -- RETRACT MSH191 ; .PAGE ; ; THE FOLLOWING DIRECTIVES RECEIVE AS INPUT A POINTER TO A REGION DEFINITION ; BLOCK WHICH SERVES AS A COMMUNICATION AREA BETWEEN THE ISSUING TASK AND ; THE EXECUTIVE. THE REGION DEFINITION BLOCK HAS THE FOLLOWING FORMAT: ; ; ------------------------------------------------- ; ! ! ; R.GID ! REGION ID ! ; ! ! ; !-----------------------------------------------! ; ! ! ; R.GSIZ ! SIZE OF REGION (32W BLOCKS) ! ; ! ! ; !-----------------------------------------------! ; ! ! ; ! ! ; ! ! ; R.GNAM ! NAME OF REGION (RAD50) ! ; ! ! ; ! ! ; ! ! ; !-----------------------------------------------! ; ! ! ; ! ! ; ! ! ; R.GPAR ! REGION'S MAIN PARTITION NAME (RAD50) ! ; ! ! ; ! ! ; ! ! ; !-----------------------------------------------! ; ! ! ; R.GSTS ! REGION STATUS WORD ! ; ! ! ; !-----------------------------------------------! ; ! ! ; R.GPRO ! PROTECTION CODE OF REGION ! ; ! ! ; ------------------------------------------------- ; ; ; GLOBAL SYMBOL DEFINITION ; .IF DF P$$LAS ;MSH045 ;**-9 ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,PCBDF$,RDBDF$,TCBDF$ HDRDF$ ;DEFINE HEADER AND WINDOW BLOCK OFFSETS PCBDF$ ;DEFINE PCB AND ATTACHMENT DESCRIPTOR OFFSETS RDBDF$ ;DEFINE REGION DEFINITION BLOCK OFFSETS TCBDF$ ;DEFINE TCB OFFSETS ;+ ; **-$DRCRR-CREATE REGION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CREATE A REGION AND OPTIONALLY ; ATTACH TO IT. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(55.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF REGION DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE REGION DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GSIZ=SIZE OF REGION TO CREATE. ; R.GNAM=NAME OF REGION TO CREATE OR 0 FOR NO NAME. ; R.GPAR=NAME OF SYSTEM PARTITION IN WHICH TO ALLOCATE REGION ; OR 0 FOR MAIN SYSTEM PARTITION OF TASK. ; R.GSTS=CONTROL INFORMATION. ; RS.NDL=1 IF REGION SHOULD NOT BE DELETED ON LAST ; DETACH. ; RS.ATT=1 IF CREATED REGION SHOULD BE ATTACHED. ; RS.RED=1 IF READ ACCESS IS DESIRED ON ATTACH. ; RS.WRT=1 IF WRITE ACCESS IS DESIRED ON ATTACH. ; RS.EXT=1 IF EXTEND ACCESS IS DESIRED ON ATTACH. ; RS.DEL=1 IF DELETE ACCESS IS DESIRED ON ATTACH. ; R.GPRO=PROTECTION CODE FOR REGION [DEWR,DEWR,DEWR,DEWR]. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF A PCB OR ATTACH- ; MENT DESCRIPTOR COULD NOT BE ALLOCATED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE DESIRED ; ACCESS IS DENIED IN THE ATTACHMENT STAGE. ; DIRECTIVE STATUS OF 'D.RS94' IS RETURNED IF THE SPECIFIE;MSH072 ; PARTITION IN WHICH THE REGION IS TO BE ALLOCATED;**-1 ; DOES NOT EXIST, OR IF NO PARTITION NAME HAS BEEN ; SPECIFIED AND RS.ATT=0. ; ; OUTPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GID=ASSIGNED REGION ID (RS.ATT=1). ; R.GSTS=DIRECTIVE COMPLETION INFORMATION. ; RS.CRR=1 IF REGION WAS CREATED. ;- .ENABL LSB $DRCRR:: ; .IF DF D$$YNM&M$$MGE ADD #R.GPAR,R3 ;PNT TO NAME OF PAR IN WHICH TO ALLOCATE MOV T.PCB(R5),R2 ;ASSUME ALLOCATING IN TASK'S PARTITION MOV P.MAIN(R2),R2 ;POINT TO MAIN PARTITION PCB TST (R3) ;PARTITION NAME SPECIFIED? BEQ 5$ ;IF EQ NO CALL $SRNAM ;SEARCH FOR NAMED PARTITION'S PCB BCS 90$ ;IF CS, PARTITION NOT IN SYSTEM CMP R2,P.MAIN(R2) ;IS IT A MAIN PARTITION? BNE 90$ ;IF NE NO 5$: BIT #PS.SYS,P.STAT(R2) ;IS IT A SYSTEM CONTROLLED PARTITION? BEQ 90$ ;IF EQ NO MOV R2,R0 ;COPY POINTER TO PCB TST -(R3) ;POINT TO REGION NAME (R.GNAM+2) TST -(R3) ;REGION NAME SPECIFIED? (R.GNAM) BEQ 10$ ;IF EQ NO .IFF CMP (R3)+,(R3)+ ;POINT TO REGION NAME (R.GID)(R.GSIZ) .IFTF CALL $SRNAM ;DETERMINE IF NAME IS UNIQUE .IFF BCS 90$ ;IF CS REGION DOES NOT EXIST .IFT BCC 35$ ;IF CC, NAME IS NOT UNIQUE 10$: MOV R3,-(SP) ;PUSH NONZERO WORD (P.ATT+2) CLR -(SP) ;(P.ATT) MOV R.GPRO-R.GNAM(R3),-(SP) ;SET PROTECTION MASK (P.PRO) BIC #210,(SP) ;INSURE OWNER AND SYSTEM DELETE ACCESS (P.PRO) CLR -(SP) ;CLEAR HEADER POINTER (P.HDR) MOV #PS.COM!PS.DEL!PS.PIC!PS.SYS,-(SP) ;SET STATUS WORD (P.STAT) MOV H.CUIC(R4),-(SP) ;SET OWNER UIC (P.OWN) CLR -(SP) ;CLEAR BUSY FLAGS (P.BUSY) CLR -(SP) ;CLEAR SWAP SIZE (P.SWSZ) CLR -(SP) ;CLEAR WAIT QUEUE POINTER (P.WAIT) MOV R.GSIZ-R.GNAM(R3),-(SP) ;STORE SIZE OF REGION (P.SIZE) CLR -(SP) ;CLEAR RELOCATION BIAS (P.REL) MOV R0,-(SP) ;SET MAIN PCB POINTER (P.MAIN) CLR -(SP) ;CLEAR SUBPARTITION LINK (P.SUB) ;MSH072 MOV 2(R3),-(SP) ;SET SECOND WORD OF PAR NAME (R.GNAM+2)(;**-1 MOV (R3),-(SP) ;SET FIRST WORD OF PAR NAME (R.GNAM)(P.NAM) BNE 30$ ;IF NE NAME WAS SPECIFIED BIT #RS.ATT,R.GSTS-R.GNAM(R3) ;IS REGION TO BE ATTACHED BEQ 90$ ;IF EQ NO, PARTITION NAME ERROR CLR 2(SP) ;ELSE CLEAR SECOND WORD OF NAME (P.NAM+2) 30$: CLR -(SP) ;ZERO I/O COUNT AND PRIORITY (P.IOC) CLR -(SP) ;CLEAR LINK WORD (P.LNK) MOV SP,R2 ;COPY POINTER TO PCB ON STACK .IFTF 35$: BIT #RS.ATT,R.GSTS-R.GNAM(R3) ;ATTACH DESIRED? ;MSH130 .IFF ;MSH130 ;MSH130 BNE ATT ;IF NE YES ;MSH130 RETURN  ; ;MSH130 ;MSH130 .IFT ;MSH130 ;MSH130 BEQ 36$ ;IF EQ NO CALL ATT ;ATTACH REGION 36$: ;REF LABEL .IFT TST (SP) ;WAS THE REGION CREATED? BNE 80$ ;IF NE NO, DONE MOV R1,R5 ;COPY POINTER TO ATTACHMENT DESCRIPTOR MOV #P.LGTH,R1 ;PICK UP PCB SIZE CALL $ALOCB ;ALLOCATE A PCB BCS 110$ ;IF CS ALLOCATION FAILURE MOV #P.LGTH/2,R1 ;PICK UP PCB SIZE IN WORDS MOV R0,R4 ;COPY POINTER TO PCB 40$: MOV (SP)+,(R0)+ ;FILL IN PCB DEC R1 ;DONE YET? BGT 40$ ;IF GT NO CMP -(R0),-(R0) ;WAS THE PCB ATTACHED? BEQ 50$ ;IF EQ YES MOV R0,2(R0) ;SET UP LISTHEAD CMP -(R3),-(R3) ;POINT TO REGION ID (R.GSIZ)(R.GID) BR 60$ ; .IFTF 90$: DRSTS D.RS94 ;PARTITITON NAME ERROR .IFT 50$: MOV (R0),R5 ;PICK UP ADDRESS OF ATTACHMENT DESCRIPTOR MOV R4,A.PCB(R5) ;POINT IT TO THE REAL PCB 60$: MOV P.MAIN(R4),R5 ;POINT TO MAIN PCB CLR -(SP) ;INDICATE NO PCB FOUND YET CLR -(SP) ;NOT A SUBPARTITION; SIZE MUST BE ZERO ;MSH072 MOV R5,R0 ;COPY MAIN PCB ADDRESS 62$: MOV P.SUB(R0),R1 ;POINT TO NEXT SUBPARTITION BEQ 66$ ;IF EQ, THIS IS THE LAST ONE MOV P.REL(R1),R2 ;GET BASE OF NEXT SUBPARTITION SUB P.REL(R0),R2 ;SUBTRACT BASE OF THIS SUBPARTITION BEQ 64$ ;IF EQ, FIRST SUB STARTS AT BEGINNING ;OF MAIN, GO ON TO NEXT SUB SUB (SP),R2 ;SUBTRACT SIZE OF THIS SUBPARTITION, ;MSH072 ;GIVING THE SPACE ABOVE IT ;**-1 CMP P.SIZE(R4),R2 ;IS THERE ENOUGH ROOM FOR THE NEW PAR? BHI 64$ ;IF HI, NO, GO ON TO NEXT SUBPARTITION MOV R0,2(SP) ;INDICATE A HOLE BIG ENOUGH ;MSH072 64$: MOV R1,R0 ;**-1 MOV P.SIZE(R0),(SP) ;GET SIZE OF NEXT SUBPARTITION ;MSH072 BR 62$ ;GO ON TO NEXT SUBPARTITION 66$: MOV P.REL(R5),R2 ;PICK UP BASE OF MAIN PARTITION ADD P.SIZE(R5),R2 ;ADD SIZE, GIVING TOP OF PARTITION SUB P.REL(R0),R2 ;SUBTRACT BASE OF LAST SUB SUB (SP)+,R2 ;R2 GETS SIZE OF HOLE AT END OF MAIN ;MSH072 CMP P.SIZE(R4),R2 ;IS THERE ENOUGH ROOM FOR NEW PAR? ;MSH072 BHI 70$ ;IF HI, NO ;**-4 MOV R0,(SP) ;INDICATE SPACE FOUND 70$: MOV (SP)+,R2 ;WAS THERE SPACE? BEQ 120$ ;IF EQ, NO MOV P.SUB(R2),R0 ;COPY POINTER TO NEXT SUB MOV R0,P.SUB(R4) ;POINT NEW SUB TO IT BNE 72$ ;IF NE, THERES A SUB ABOVE NEW MOV R5,R0 ;NEW IS GOING IN AT END OF MAIN 72$: MOV R4,P.SUB(R2) ;POINT LAST SUB TO NEW ONE CMP R0,R5 ;PUTTING NEW AT END OF MAIN? BNE 74$ ;IF NE NO ;MSH072 MOV P.SIZE(R0),R1 ;PICK UP SIZE OF MAIN ;**-1 74$: ADD P.REL(R0),R1 ;POINT TO TOP OF NEW SUB SUB P.SIZE(R4),R1 ;SUBTRACT SIZE, GIVING BASE MOV R1,P.REL(R4) ;PLUG IN BASE BIS #RS.CRR,R.GSTS(R3) ;INDICATE REGION WAS CREATED BIT #RS.NDL,R.GSTS(R3) ;IS NO DELETION DESIRED? BEQ 80$ ;IF EQ NO BIC #PS.DEL,P.STAT(R4) ;CLEAR DELETE ON LAST DETACH FLAG 80$: RETURN ; ;**-3 ;MSH130 110$: BIC #PS.SYS,P.STAT(SP) ;INSURE DETACH DOES NOT ATTEMPT TO DE;**-3 MOV SP,R4 ;POINT TO PCB ON STACK MOV #80$,(SP) ;POINT TO NULL ROUTINE BR 125$ ;JOIN COMMON CODE 120$: MOV #$DEACB,(SP) ;ASSUME PCB MUST BE DEALLOCATED 125$: MOV (R3),R5 ;PICK UP ATT DESCRIPTOR ADDRESS (R.GID) MOV R4,R0 ;POINT TO PCB TO DEALLOCATE MOV #P.LGTH,R1 ;PICK UP PCB SIZE TST P.ATT(R4) ;WAS THE PCB ATTACHED? BEQ 126$ ;IF EQ NO MOV #$DTRG1,(SP) ;SET TO DETACH REGION ;MSH045 126$: CALL @(SP)+ ;CALL APPRORIATE ROUTINE ;**-1 DRSTS D.RS1 ;ALLOCATION FAILURE .IFTF ;+ ; **-$DRATR-ATTACH REGION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO ATTACH THE SPECIFIED REGION ; TO THE CURRENT TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(57.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF REGION DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE REGION DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GNAM=NAME OF REGION TO ATTACH TO OR 0 FOR TASK REGION. ; R.GSTS=DESIRED ACCESS TO REGION. ; RS.RED=1 IF READ ACCESS IS DESIRED. ; RS.WRT=1 IF WRITE ACCESS IS DESIRED. ; RS.EXT=1 IF EXTEND ACCESS IS DESIRED. ; RS.DEL=1 IF DELETE ACCESS IS DESIRED. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF AN ATTACHMENT ; DESCRIPTOR CANNOT BE ALLOCATED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE DESIRED ; ACCESS IS DENIED. ; DIRECTIVE STATUS OF 'D.RS84' IS RETURNED IF THE SPECIFIED ; REGION NAME DOES NOT EXIST. ; ; OUTPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GID=ASSIGNED REGION ID. ; R.GSIZ=SIZE OF ATTACHED REGION. ;- $DRATR::ADD #R.GNAM,R3 ;POINT TO SPECIFIED REGION NAME TST (R3) ;REGION NAME SPECIFIED? BEQ 90$ ;IF EQ NO, ILLEGAL CALL $SRNAM ;SEARCH FOR NAMED REGION BCS 90$ ;IF CS NAMED REGION DOES NOT EXIST ATT: BIT #PS.COM,P.STAT(R2) ;IS THE PARTITION COMMON? BEQ 90$ ;IF EQ NO .IFT BIT #PS.SYS,P.STAT(R2) ;IS IT A SYSTEM CONTROLLED PARTITION? BEQ 130$ ;IF EQ NO CMP R2,P.MAIN(R2) ;IS IT THE MAIN SYSTEM CONTROLLED PARTITION? BR 140$ ; .IFTF 130$: BITB P.BUSY(R2),P.BUSY+1(R2) ;IS COMMON BLOCK NOT LOADED? 140$: BEQ 90$ ;IF EQ YES MOV R.GSTS-R.GNAM(R3),R0 ;PICK UP STATUS WORD BIT #17,R0 ;ATTACH DESIRED? BNE 147$ ;IF NE YES MOV T.ATT(R5),R1 ;POINT TO FIRST ATTACHMENT DESCRIPTOR 146$: SUB #A.TCBL,R1 ;POINT TO START OF DESCRIPTOR CMP A.PCB(R1),R2 ;ATTACHED TO THIS PCB? BEQ 155$ ;IF EQ YES MOV A.TCBL(R1),R1 ;POINT TO NEXT ATTACHMENT DESCRIPTOR BNE 146$ ;IF NE THERE IS ONE DRSTS D.RS86 ;NO SUCH REGION ID 147$: MOV H.CUIC(R4),R1 ;PICK UP CURRENT TASK UIC MOV R0,R4 ;COPY STATUS WORD .IFT .IF DF D$$PAR ;MSH045 ;MSH045 CMP R2,#$STACK ;IS REGION BEING CREATED? ;MSH045 ;MSH045 .IFF ;MSH045 ;MSH045 CMP R2,PC ;IS REGION BEING CREATED? ;MSH045 .ENDC ;MSH045 ;MSH045 BLO 150$ ;IF LO YES, SKIP PROTECTION CHECK .IFTF BIT #T3.PRV,T.ST3(R5) ;ISSUING TASK PRIVILEGED? BNE 150$ ;IF NE YES, SKIP ACCESS CHECK CALL $CKACC ;DETERMINE IF DESIRED ACCESS IS ALLOWED 150$: CALL $CRATT ;CREATE ATT DESCRIPTOR AND LINK IT IN BCS 160$ ;IF CS ALLOCATION FAILURE 155$: MOV P.SIZE(R2),-(R3) ;RETURN SIZE OF REGION (R.GSIZ) ;MSH096 .IF DF A$$HDR ;MSH096 ;MSH096 CMP R2,T.PCB(R5) ;IS THIS THE TASK REGION? ;MSH096 BNE 157$ ;IF NE NO ;MSH096 BIT #T2.CHK,T.ST2(R5) ;TASK HAVE ALTERNATE HEADER AREA? ;MSH096 BNE 157$ ;IF NE NO, NONCHECKPOINTABLE TASK ;MSH096 MOVB T.HDLN(R5),R2 ;GET LGTH OF ALT. HDR REFRESH AREA ;MSH096 SUB R2,(R3) ;CORRECT REPORTED SIZE OF TASK REGION ;MSH096 157$: ; ;MSH096 .ENDC ;MSH096 ;MSH096 MOV R1,-(R3) ;STORE DESCRIPTOR ADDR AS REG ID (R.GID) RETURN ; 160$: DRSTS D.RS1 ;ALLOCATION FAILURE .DSABL LSB ;+ ; **-$DRDTR-DETACH REGION ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DETACH THE SPECIFIED REGION, ; UNMAPPING IF NECESSARY. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(59.),DPB SIZE(2.) ; WD. 01 -- ADDRESS OF REGION DEFINITION BLOCK ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE REGION DEFINITION BLOCK. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; INPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GID=REGION ID OF REGION TO DETACH. ; R.GSTS=CONTROL INFORMATION. ; RS.MDL=1 IF REGION SHOULD BE MARKED FOR DELETE ON ; THE LAST DETACH. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF AN ATTEMPT IS MADE ; TO MARK THE REGION FOR DELETE WITHOUT DELETE ACCESS. ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF AN INVALID REGION ; ID IS SPECIFIED OR IF AN ATTEMPT IS MADE TO DETACH ; REGION 0. ; ; OUTPUT FIELDS IN THE REGION DEFINITION BLOCK ARE: ; R.GSTS=INDICATION OF ANY CHANGES IN MAPPING CONTEXT. ; RS.UNM=1 IF ANY WINDOWS WERE UNMAPPED. ;- .ENABL LSB $DRDTR::TSTB T.IOC(R5) ;ANY OUTSTANDING I/O? BNE 70$ ;IF NE YES, REJECT FOR NOW .IF DF A$$TRP&C$$CKP&T$$BUF TSTB T.TIO(R5) ;TASK HAVE OUTSTANDING BUFFERED I/O? ;MSH046 BNE 70$ ;IF NE YES ;**-1 .ENDC CALL $SRATT ;SEARCH FOR AND VERIFY REGION ID MOV A.PCB(R5),R0 ;POINT TO PCB BIT #PS.COM,P.STAT(R0) ;DETACHING FROM COMMON REGION? BEQ 60$ ;IF EQ NO, DETACHING FROM TASK REGION MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOW BLOCKS TST (R4)+ ;POINT TO FIRST WINDOW BLOCK .IFT BIT #PS.SYS,P.STAT(R0) ;SYSTEM CONTROLLED PARTITION? BEQ 10$ ;IF EQ NO BIT #RS.MDL,R.GSTS(R3) ;MARK FOR DELETE DESIRED? BEQ 10$ ;IF EQ NO BITB #AS.DEL,A.STAT(R5) ;DOES TASK HAVE DELETE ACCESS? BEQ 70$ ;IF EQ NO BIS #PS.DEL,P.STAT(R0) ;MARK REGION FOR DELETE .IFTF 10$: CMP W.BATT(R4),R5 ;THIS WINDOW MAPPED TO REGION TO DETACH BNE 20$ ;IF NE NO CALL $UNMAP ;UNMAP WINDOW BIS #RS.UNM,R.GSTS(R3) ;INDICATE WINDOW WAS UNMAPPED 20$: ADD #W.BLGH,R4 ;POINT TO NEXT WINDOW BLOCK TSTB A.MPCT(R5) ;ANY MORE WINDOWS MAPPED TO THIS REGION? BNE 10$ ;IF NE YES ;+ ; **-$DETRG-DETACH REGION BY ATTACHMENT DESCRIPTOR ADDRESS ; **-$DTRG1-DETACH REGION BY ATTACHMENT DESCRIPTOR ADDRESS ;MSH045 ; ; THIS ROUTINE DETACHES A TASK FROM A REGION AND DEALLOCATES THE ATTACHMENT ; DESCRIPTOR. ON THE LAST DETACH OF A REGION IT IS CHECKED FOR DELETION. ; WHEN APPRORIATE, $NXTSK IS CALLED. ; ; INPUTS: ; ; R5=ADDRESS OF ATTACHMENT DESCRIPTOR ; ; OUTPUTS: ; ; R0,R1,R2,R3 ARE MODIFIED. ;- .IF NDF D$$PAR ;MSH045 ;MSH045 $DETRG:: ;REF LABEL ;MSH045 ;MSH045 .ENDC ;MSH045 ;MSH045 $DTRG1::MOV A.PCB(R5),R0 ;POINT TO PCB OF REGION ;MSH045 ADD #P.ATT,R0 ;POINT TO ATTACHMENT DESCR LISTHEAD ;**-1 CLR R1 ;CLEAR SEARCH KEY MOV A.TCB(R5),-(SP) ;SAVE TCB ADDRESS CLR A.TCB(R5) ;MARK ATTACHMENT DESCRIPTOR FOR REMOVAL CALL $QRMVT ;REMOVE DESCRIPTOR FROM PCB'S QUEUE .IFT TST (R0) ;IS ANYONE ELSE ATTACHED? (P.ATT) BNE 50$ ;IF NE YES BIT #PS.SYS,P.STAT-P.ATT(R0) ;IS PARTITION SYSTEM CONTROLLED? BEQ 50$ ;IF EQ NO TST P.NAM-P.ATT(R0) ;IS THIS A NAMED REGION? BEQ 25$ ;IF EQ NO, FORCE DELETION BIT #PS.DEL,P.STAT-P.ATT(R0) ;IS REGION MARKED FOR DELETE? BEQ 55$ ;IF EQ NO 25$: SUB #P.ATT,R0 ;POINT TO START OF PCB MOV P.MAIN(R0),R1 ;POINT TO MAIN PARTITION PCB 30$: CMP P.SUB(R1),R0 ;DOES THIS PARTITION LINK TO ONE TO DELETE? BEQ 40$ ;IF EQ YES MOV P.SUB(R1),R1 ;POINT TO NEXT SUBPARTITION BNE 30$ ;IF NE THERE IS ONE BR 45$ ;SKIP UNLINK OF PCB (THIS INDICATES $DRCRR CALL) 40$: MOV P.SUB(R0),P.SUB(R1) ;UNLINK DETACHED PARTITION 45$: MOV #P.LGTH,R1 ;PICK UP SIZE FOR DELETE CALL $DEACB ;DEALLOCATE PCB .ENDC .IF DF D$$ISK .IF NDF D$$YNM!M$$MGE ;MSH110 ;MSH110 BIT #PS.COM,P.STAT-P.ATT(R0) ;STATIC COMMON PARTITION? ;MSH110 BNE 55$ ;IF NE YES, DON'T REALLOCATE PARTITION ;MSH110 ;MSH110 .IFTF ;MSH110 ;MSH110 49$: MOV A.PCB(R5),R0 ;POINT TO DETACHED PCB MOV R0,R1 ;COPY PCB POINTER MOV P.MAIN(R1),R3 ;POINT TO MAIN PARTITION PCB CALL $RLPR1 ;RELEASE THE PARTITION ;MSH110 .IFF ;MSH110 ;MSH110 BR 55$ ; 50$: BIT #PS.COM!PS.SYS,P.STAT-P.ATT(R0) ;FIXED TASK PARTITION? BEQ 49$ ;IF EQ NO, RELEASE FIXED TASK PARTITION .ENDC ;MSH110 ;MSH110 .IFF 50$: ;REF LABEL .ENDC 55$: MOV (SP)+,R0 ;RESTORE ÖTCB ADDRESS ADD #T.ATT,R0 ;POINT TO ATTACHMENT DESCRIPTOR LISTHEAD CLR R1 ;CLEAR SEARCH KEY CLR A.PCB(R5) ;MARK ATTACHMENT DESCRIPTOR FOR REMOVAL CALL $QRMVT ;REMOVE DESCRIPTOR FROM TCB'S LIST MOV R5,R0 ;COPY DESCRIPTOR ADDRESS MOV #A.LGTH,R1 ;SET SIZE TO DEALLOCATE CALLR $DEACB ;DEALLOCATE ATTACHMENT DESCRIPTOR 60$: DRSTS D.RS86 ;INVALID REGION ID 70$: DRSTS D.RS16 ;ATTEMPT TO MARK FOR DELETE WITHOUT ACCESS .DSABL LSB .ENDC .END ÖoMkQ ›c, .TITLE LOWCR .IDENT /10.05/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 10.05 ; ; D. N. CUTLER 11-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; P. J. BEZEREDI ; CHUCK SPITZ ; ; MODIFIED BY: ; ; M. S. HARVEY 3-APR-80 ; MSH089 -- PRESERVE ENTIRE STACK ON FORCED CRASH ; ; M. S. HARVEY 2-FEB-81 ; MSH146 -- DEFINE ENOUGH EXTRA ROOM ON THE STACK TO ; HANDLE FOR THE LOAD IMPOSED BY ERROR THREADING ; ; M. S. HARVEY 3-FEB-81 ; MSH147 -- INITIALIZE NONSENSE INTERRUPT VECTORS FOR ; ERROR LOGGING SYSTEMS ; ; M. S. HARVEY 21-JUL-81 ; MSH181 -- HANDLE POSSIBLE T-BIT TRAP AFTER POWER UP ; ON PDP 11/02 PROCESSORS ; ; ; LOW CORE POINTERS, TRAP VECTORS, AND INTERRUPT VECTORS ; ; THIS FILE MUST BE FIRST IN THE TASK BUILDER COMMAND FILE SINCE ; IT OCCUPIES LOCATIONS STARTING AT REAL ZERO. ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PCBDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ,,SYSDEF ;DEFINE PCB OFFSETS AND SIZE .PSECT ; ; LOCAL MACROS ; ; GENVT-GENERATE VECTOR ENTRY ; .MACRO GENVT ARG .IF DF E$$LOG ;MSH147 .WORD $NS'ARG ;**-1 .IFF .WORD $NONSI .ENDC .WORD PR7!<<<$$$-START>/4>&17> .ENDM START: .REPT V$$CTR/4 $$$=. GENVT \<<$$$-START>/<4*20>> .ENDR .=START+4 .WORD $TRP04 ;TRAPS TO 4 (ODD,STACK,NONEX MEM) .WORD PR7 ; .WORD $ILINS ;ILLEGAL (RESERVED) INSTRUCTION TRAPS .WORD PR7 ; ;MSH181 .IF DF L$$SI1 ;MSH181 ;MSH181 .WORD $TBIT ;TEMPORARY T-BIT TRAP HANDLER ;MSH181 ;MSH181 .IFF ;MSH181 ;MSH181 .WORD $TRACE ;BREAK POINT (TRACE) TRAPS ;MSH181 .ENDC ;MSH181 ;MSH181 .WORD PR7 ; .WORD $IOTRP ; .WORD PR7 ; .WORD $NONSI ;NONSENSE INTERRUPT .WORD PR7 ; .WORD $EMTRP ;EMT INSTRUCTION TRAPS .WORD PR7 ; .WORD $TRTRP ;TRAP INSTRUCTION TRAPS .WORD PR7 ; JMP $CRALT ;JUMP TO CRASH DUMP ROUTINE ;MSH089 .DSW:: .WORD .+2 ;ADDRESS OF DIRECTIVE STATUS ;**-1 .BLKW 1 ;DIRECTIVE STATUS WORD .BLKW 1 ;FCS IMPURE AREA POINTER .BLKW 1 ;FORTRAN IMPURE AREA POINTER .BLKW 1 ;OVERLAY RUN TIME SYSTEM IMPURE AREA POINTER .BLKW 1 ;RESERVED FOR EXPANSION .BLKB V$$CTR-60 ; ; ; EXECUTIVE STACK AREA ; .BLKW 40. ;SYSTEM STACK FOR MAPPED AND REAL SYSTEMS. .IF DF D$$H11!M$$MGE!M$$ÆNET .BLKW 20. ; .ENDC .IF DF I$$C11 .BLKW 30. ; .ENDC .IF DF P$$LAS .BLKW P.LGTH/2 ;DEFINE EXTRA STACK FOR PLAS SYSTEMS .ENDC .IF DF M$$NET .BLKW 20. ;DEFINE EXTRA STACK FOR DECNET .ENDC ;M$$NET ;MSH146 .IF DF P$$OFF ;MSH146 ;MSH146 .BLKW 20. ;ROOM ON STACK FOR ERROR THREADING ;MSH146 ;MSH146 .ENDC ;P$$OFF ;MSH146 $STACK:: ;REF LABEL .END Æã˜gkQ ›c, .TITLE DRSPW .IDENT /02.33/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 02.33 ; ; T. J. MILLER 26-MAY-77 ; ; PREVIOUSLY MODIFIED BY: ; ; CHUCK SPITZ ; B. S. MCCARTHY ; M. S. HARVEY ; ; MODIFIED BY: ; ; M. S. HARVEY 19-AUG-79 ; MSH049 -- ADD MORE GROUP GLOBAL EVENT FLAG SUPPORT ; ; M. S. HARVEY 27-AUG-79 ; MSH051 -- CALCULATE DEFAULT UIC FOR NON-MULTI-USER SYSTEMS ; ; M. S. HARVEY 8-OCT-79 ; MSH021 -- CONDITIONALIZE ACP TEST ; ; M. S. HARVEY 2-JUN-80 ; MSH103 -- QUEUE COMMAND TO CORRECT CLI ; ; M. S. HARVEY 3-JUN-80 ; MSH104 -- ADD EMIT STATUS DIRECTIVE ; ADD SEND, REQUEST AND CONNECT DIRECTIVE ; ; M. S. HARVEY 12-SEP-80 ; MSH115 -- CLEAN UP GROUP GLOBALS FOR TASK EXITTING FROM ; EXIT WITH STATUS DIRECTIVE ; ; M. S. HARVEY 15-SEP-80 ; MSH117 -- SPAWN TASKS THROUGH CLI WITH CORRECT UIC ; ; M. S. HARVEY 25-NOV-80 ; MSH129 -- ALLOW FULL USE OF THE EXIT STATUS BLOCK ; ; M. S. HARVEY 18-DEC-80 ; MSH131 -- ALWAYS ALLOW SPECIFICATION OF OWN TI: ; ; M. S. FOX 07-JAN-81 ; MF203 -- INITIAL ALTERNATE CLI SUPPORT ; ; M. S. FOX 26-JAN-81 ; MF207 -- IMPLEMENT RPOI$ AND SDRP$ ; ; M. S. FOX 01-FEB-81 ; MF209 -- CALL $GTUCB ROUTINE CREATED FOR OTHER DIRECTIVES ; ; M. S. HARVEY 28-FEB-81 ; MSH153 -- CORRECT MINOR BUGS IN ALTERNATE CLI CODE ; ; M. S. HARVEY 7-AUG-81  ; MSH185 -- ALLOW SPECIFICATION OF OLDEST OCB WITHOUT ; KNOWING THE PARENT NAME OR OCB ID ; ; M. S. HARVEY 14-SEP-81 ; MSH190 -- ADD ALTERNATE CLI CONDITIONALIZATION TO ; ACTIVE GROUP GLOBAL CONTEXT BYTE ; ; M. S. HARVEY 6-OCT-81 ; MSH193 -- CONVERT BUFFER LENGTH TO WORD VALUE ; ; ; THIS MODULE CONTAINS THE DIRECTIVE ROUTINES AND PRIMARY SUBROUTINES ; WHICH PROVIDE PARENT-OFFSPRING TASKING SUPPORT. ; ; MACRO LIBRARY CALLS ; .IF DF P$$OFF .MCALL DCBDF$,PKTDF$,TCBDF$,UCBDF$ DCBDF$ ;DEFINE DEVICE CONTROL BLOCK SYMBOLS PKTDF$ ;DEFINE I/O PACKET AND OCB OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK SYMBOLS UCBDF$ ;DEFINE UNIT CONTROL BLOCK SYMBOLS ;+ ;MSH104 ; **-$DRSRC-SEND REQUEST AND CONNECT / SEND REQUEST AND PASS OCB ;MSH104 ; ;MSH104 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO QUEUE A SEND DATA PACKET FOR ;MSH104 ; THE SPECIFIED TASK, CONNECT TO THE TASK AND REQUEST IT IF IT IS NOT ;MSH104 ; ALREADY ACTIVE. ;MSH104 ; ;MSH104 ; DPB FORMAT: (FOR SDRC$) ;MSH104 ; ;MSH104 ; WD. 00 -- DIC(141.),DPB SIZE(7.). ;MSH104 ; WD. 01 -- FIRST HALF OF TASK NAME IN RAD50. ;MSH104 ; WD. 02 -- SECOND HALF OF TASK NAME IN RAD50. ;MSH104 ; WD. 03 -- ADDRESS OF SEND BUFFER. ;MSH104 ; WD. 04 -- EFN, LENGTH OF ESB (0 = 1 WORD, >0 = 8. WORDS). ;MSH104 ; WD. 05 -- ADDRESS OF AST ROUTINE TO ENTER UPON STATUS RETURN. ;MSH104 ; WD. 06 -- ADDRESS OF EXIT STATUS BLOCK. ;MSH104 ; ; MF207 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO QUEUE A SEND DATA PECKET FOR ; MF207 ; THE SPECIFIED TASK, UNLINK ALL OR A SELECTED OCB FROM THE CURRENT ; MF207 ; TASK, LINK THE OCB(S) OFF THE SPECIFIED TASK, AND REQUEST IT IF IT ; MF207 ; IS NOT ALREADY ACTIVE. ; MF207 ; ; MF207 ; DPB FORMAT: (FOR SDRP$) ; MF207 ; ; MF207 ; WD. 00 -- DIC(141.),DPB SIZE(9.) ; MF207 ; WD. 01 -- FIRST HALF OF TASK NAME IN RAD50 ; MF207 ; WD. 02 -- SECOND HALF OF TASK NAME IN RAD50 ; MF207 ; WD. 03 -- ADDRESS OF SEND BUFFER ; MF207 ; WD. 04 -- EFN, FLAGS BYTE ; MF207 ; WD. 05 -- RESERVED FOR LENGTH OF SEND BUFFER ON M-PLUS ; MF207 ; WD. 06 -- FIRST HALF OF NAME OF PARENT WHOSE OCB SHOULD BE PASSE; MF207 ; WD. 07 -- SECOND HALF OF PARENT'S TASK NAME ; MF207 ; WD. 08 -- ADDRESS OF OCB TO PASS (CLI TASKS ONLY); ; MF207 ; ;MSH104 ; INPUTS: ;MSH104 ; ;MSH104 ; R0=ADDRESS OF THE TCB OF THE TARGET TASK. ;MSH104 ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TARGET TASK. ;MSH104 ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ;MSH104 ; R3=ADDRESS OF THE SEND BUFFER ADDRESS IN THE DPB. ;MSH104 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ;MSH104 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ;MSH104 ; ;MSH104 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ;MSH104 ; ;MSH104 ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ;MSH104 ; DIRECTIVE STATUS OF +1 IS RETURNED. ;MSH104 ; C=1 IF DIRECTIVE IS REJECTED. ;MSH104 ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF A SEND ;MSH104 ; PACKET, OFFSPRING CONTROL BLOCK OR PARTITION ;MSH104 ; CONTROL BLOCK COULD NOT BE ALLOCATED. ;MSH104 ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF IT IS ILLEGAL;MSH104 ; TO SEND TO THE TARGET TASK. ;MSH104 ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN INVALID ;MSH104 ; EVENT FLAG NUMBER IS SPECIFIED. ;MSH104 ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE EXIT ;MSH104 ; STATUS BLOCK IS NOT ENTIRELY WITHIN THE USER'S ;MSH104 ; SPACE. ;MSH104 ; ; MF207 ; THE SDRP$ DIRECTIVE CAN RETURN ALL OF THE ABOVE ERRORS, PLUS THE FOLLO; MF207 ; THREE: ; MF207 ; ; MF207 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF A PARAMETER ; MF207 ; RESERVED FOR A CLI ONLY IS USED BY A NON-CLI TAS; MF207 ; OR AN ATTEMPT IS MADE TO PASS ALL OCBS TO A CLI.; MF207 ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF THERE IS ; MF207 ; NO OCB FROM THE SPECIFIED PARENT ; MF207 ; DIRECTIVE STATUS OF 'D.RS84' IS RETURNED IF A CLI TASK ; MF207 ; SPECIFIED BOTH A PARENT NAME AND OCB ADDRESS, AN; MF207 ; THE TWO DO NOT IDENTIFY THE SAME OCB, OR EITHER ; MF207 ; FIELD IS SUPPLIED WITH THE FLAG TO PASS ALL OCBS; MF207 ; DIRECTIVE STATUS OF 'D.RS89' IS RETURNED IF A VALUE ; MF207 ; OTHER THAN 13. IS SUPPLIED AS THE LENGTH OF THE ; MF207 ; SEND PACKET. ; MF207 ;- ;MSH104 ;MSH104 .IF DF R$$SND ;MSH104 ;MSH104 $DRSRC::MOV R3,R1 ;COPY DPB ADDRESS TO SAVE ;MSH104  ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 MOV SP,$TEMP4 ;SAVE CURRENT STACK, TO EASE UNWIND ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 ; MF207 CALL ERRSV ;PUSH CONTEXT TO REVERSE SEND OPERATION ;MSH104 .WORD NULL ;NO ROUTINE TO CALL NOW ;MSH104 .WORD 10$ ;ADDRESS OF RECOVERY ROUTINE ;MSH104 ;MSH104 .IF DF M$$MGE ;MSH104 ;MSH104 MOV KISAR6,-(SP) ;SAVE DPB MAPPING ;MSH104 ;MSH104 .IFTF ;MSH104 ;MSH104 MOV $HEADR,R4 ;GET HEADER (DESTROYED BY ERROR THREADIN;MSH104 CALL $DRSND ;PERFORM SEND OPERATION ;MSH104 ;MSH104 .IFT ;MSH104 ;MSH104 MOV (SP)+,KISAR6 ;RESTORE DPB MAPPING ;MSH104 ;MSH104 .ENDC ;M$$MGE ;MSH104 ;MSH104 MOV 4(SP),R3 ;RESTORE DPB ADDRESS+6 ;MSH104 TST (R3)+ ;POINT TO EVENT FLAG WORD ;MSH104 ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 CMPB $DICSV+1,#7. ;IS IT AN SDRC$ ; MF207 BEQ CNRQT ;IF EQ YES ; MF207 CMPB $DICSV+1,#9. ;IS IT AN SDRP$ ; MF207 BEQ 20$ ;IF EQ YES ; MF207 BR DPBER ;SET ILLEGAL DPB SIZE ; MF207 ; MF207 .IFF ;R$$POI ; MF207 ; MF207 BR CNRQT ;COMMON CONNECT PROCESSING ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 ; MF207 ;MSH104 10$: ADD #T.RCVL,R0 ;POINT TO TARGET TASK RECEIVE QUEUE ;MSH104 MOV 2(R0),R1 ;GET ADDRESS OF PACKET JUST QUEUED ;MSH104 CALL $QRMVT ;REMOVE IT FROM THE QUEUE ;MSH104 MOV R1,R0 ;COPY POINTER TO PACKET ;MSH104 CALLR $DEPKT ;DEALLOCATE THE PACKET ;MSH104 ;MSH104 ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 20$: MOVB 1(R3),R2 ;GET FLAGS BYTE, FORCE TASK EXIT?? ; MF207 BMI 30$ ;IF MI YES ; MF207 MOV #1,$TEMP4 ;NO EXIT, BUT IT IS AN SDRP$ ; MF207 30$: TST (R3)+ ;POINT TO LENGTH OF SEND PACKET ; MF207 CMP #13.,(R3)+ ;IS LENGTH = 13. WORDS ; MF207 BNE 40$ ;IF NE NO ; MF207 CALL LOCOCB ;LOCATE THE OCB(S) TO PASS ; MF207 MOV $TKTCB,R5 ;GET CURRENT TASK'S TCB ADDRESS ; MF207 JMP RQST2 ;REQUEST THE TASK TO RUN ; MF207 ; MF207 40$: MOV (PC)+,R5 ;SET ILLEGAL SEND PACKET SIZE ; MF207 DRSTS D.RS89 ; MF207 JMP ERROR ;GO TO COMMON ERROR CODE ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 .ENDC ;R$$SND ; MF207 ; MF207 ; MF207 ;+ ;**-1  ; **-$DRCNC-CONNECT TO TASK ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CONNECT THE ISSUING TASK TO ; THE SPECIFIED (ACTIVE) TARGET TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(143.),DPB SIZE(6.). ; WD. 01 -- FIRST WORD OF TASK NAME IN RAD50. ; WD. 02 -- SECOND WORD OF TASK NAME IN RAD50. ; WD. 03 -- EFN, LENGTH OF ESB (0 = 1 WORD, >0 = 8. WORDS) ;MSH129 ; WD. 04 -- ADDRESS OF AST ROUTINE TO ENTER UPON STATUS. ;**-1 ; WD. 05 -- ADDRESS OF THE EXIT STATUS BLOCK. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TARGET TASK. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TARGET TASK. ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE EVENT FLAG NUMBER IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF AN OFFSPRING ; CONTROL BLOCK COULD NOT BE ALLOCATED. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF AN ATTEMPT IS ; BEING MADE TO CONNECT TO A CLI TASK. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF THE TARGET ; TASK IS NOT ACTIVE. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN INVALID ; EVENT FLAG NUMBER IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE EXIT ; STATUS BLOCK IS NOT ENTIRELY IN THE USER'S ; SPACE. ;- $DRCNC::MOV #ERRSV,-(SP) ;PUSH ADDRESS OF ERROR SAVE ROUTINE TST (R1) ;IS TARGET TASK ACTIVE? BMI 10$ ;IF MI NO BIT #T3.CLI,T.ST3(R0) ;TARGET TASK A CLI? BEQ CNRQT ;IF EQ NO DRSTS D.RS2 ;CONNECTING TO CLI TASK 10$: DRSTS D.RS7 ;SPECIFIED TASK NOT ACTIVE ;+ ; **-$DRREQ-REQUEST, SPAWN, OR CHAIN TO A TASK ; MF207 ; ;**-1 ; THIS ROUTINE INSTRUCTS THE SYSTEM TO REQUEST OR SPAWN THE SPECIFIED ; TASK, DEPENDING ON THE DPB SIZE. ; IF THE DIRECTIVE IS RPOI$, THE TASK IS CHAINED TO BY UNLINKING ; MF207 ; ALL OR A SELECTED OCB FROM THE CURRENT TASK, AND LINK IT TO THE ; MF207 ; TARGET TASK. THIS DIFFERS FROM SPWN$ IN THAT NO NEW OCB IS CREATED ; MF207 ; ; DPB FORMAT (FOR REQUEST OR SPAWN): ; MF207 ; ;**-1 ; WD. 00 -- DIC(11.),DPB SIZE(7., 13., OR 14.). ; WD. 01 -- FIRST HALF OF TASK NAME IN RAD50. ; WD. 02 -- SECOND HALF OF TASK NAME IN RAD50. ; WD. 03 -- FIRST WORD OF PARTITION NAME - NOT SUPPORTED. ; WD. 04 -- SECOND WORD OF PARTITION NAME - NOT SUPPORTED. ; WD. 05 -- REQUEST PRIORITY - NOT SUPPORTED. ; WD. 06 -- REQUEST UIC. ; WD. 07 -- EFN, LENGTH OF ESB (0 = 1 WORD, >0 = 8. WORDS) ;MSH129 ; WD. 08 -- ADDRESS OF AST ROUTINE TO ENTER UPON STATUS. ;**-1 ; WD. 09 -- EXIT STATUS BLOCK ADDRESS. ; WD. 10 -- ADDRESS OF COMMAND LINE TO QUEUE FOR TARGET TASK. ; WD. 11 -- LENGTH OF COMMAND LINE. ; WD. 12 -- TERMINAL UNIT NUMBER FOR TI:. ; WD. 13 -- ASCII DEVICE NAME FOR TI:. ; ; MF207 ; DPB FORMAT FOR RPOI$ DIRECTIVE ; MF207 ; ; MF207 ; WD. 00 -- DIC (11.),DPB SIZE(16.) ; MF207 ; WD. 01 -- FIRST HALF OF TARGET TASK NAME IN RAD50 ; MF207 ; WD. 02 -- SECOND HALF OF TARGET TASK NAME IN RAD50 ; MF207 ; WD. 03 -- FIRST WORD OF PARTITION NAME - NOT SUPPORTED ; MF207 ; WD. 04 -- SECOND WORD OF PARTITION NAME - NOT SUPPORTED ; MF207 ; WD. 05 -- REQUEST PRIORITY - NOT SUPPORTED ; MF207 ; WD. 06 -- REQUEST UIC ; MF207 ; WD. 07 -- FIRST HALF OF NAME OF PARENT, WHOSE OCB SHOULD BE PASS; MF207 ; WD. 08 -- SECOND HALF OF NAME OF PARENT, WHOSE OCB SHOULD BE PAS; MF207 ; WD. 09 -- ADDRESS OF OCB TO PASS (CLI TASKS ONLY) ; MF207 ; WD. 10 -- ADDRESS OF COMMAND BUFFER ; MF207 ; WD. 11 -- LENGTH OF COMMAND ; MF207 ; WD. 12 -- UNIT NUMBER OF TASK TI:, FLAGS BYTE ; MF207 ; WD. 13 -- ASCII DEVICE NAME FOR TI: ; MF207 ; WD. 14 -- FIRST HALF OF RAD50 NAME OF TASK TO BE STARTED (CLIS O; MF207 ; WD. 15 -- SECOND HALF OF NAME OF TASK TO BE STARTED (CLI TASKS O; MF207 ; ; MF207 ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TARGET TASK. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TARGET TASK. ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE PARTITION NAME WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF AN ALLOCATION ; FAILURE OCCURS ON A PARTITION CONTROL BLOCK, ; OFFSPRING CONTROL BLOCK, OR A COMMAND LINE BUFFER. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF AN ATTEMPT IS ; MADE TO ISSUE A SPAWN TO A COMMAND LINE INTER- ; PRETER WITHOUT SPECIFYING A COMMAND LINE. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF THE SPECIFIED ; TASK IS ALREADY ACTIVE (WITH EXCEPTION OF A ; SPAWN TO A COMMAND LINE INTERPRETER). ; DIRECTIVE STATUS OF 'D.RS92' IS RETURNED IF AN INVALID ; TERMINAL UNIT IS SPECIFIED FOR TI:. ; DIRECTIVE STATUS OF 'D.RS97' IS RETURNED IF AN INVALID ; EVENT FLAG NUMBER IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE EXIT ; STATUS BLOCK OR THE COMMAND LINE IS NOT ENTIRELY ; IN THE TASK'S ADDRESSING SPACE. ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF AN ILLEGAL ; DPB SIZE IS SPECIFIED (NOT 7., 13., 14., OR 16.); MF207 ; ; MF207 ; THE ABOVE ERRORS ALSO APPLY TO THE RPOI$ DIRECTIVE, EXCEPT FOR 'D.RS97; MF207 ; WHICH IT CANNOT RETURN. THE RPOI$ DIRECTIVE CAN ALSO RETURN THE FOLLOW; MF207 ; ERRORS: ; MF207 ; ; MF207 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF A PARAMETER ; MF207 ; RESERVED FOR A CLI ONLY IS USED BY A NON-CLI TAS; MF207 ; OR AN ATTEMPT IS MADE TO PASS ALL OCBS TO A CLI.; MF207 ; DIRECTIVE STATUS OF 'D.RS86' IS RETURNED IF THERE IS ; MF207 ; NO OCB FROM THE SPECIFIED PARENT ; MF207 ; DIRECTIVE STATUS OF 'D.RS84' IS RETURNED IF A CLI TASK ; MF207 ; SPECIFIED BOTH A PARENT NAME AND OCB ADDRESS, AN; MF207 ; THE TWO DO NOT IDENTIFY THE SAME OCB, OR EITHER ; MF207 ; FIELD IS SUPPLIED WITH THE FLAG TO PASS ALL OCBS; MF207 ; DIRECTIVE STATUS OF 'D.RS94' IS RETURNED IF AN ATTEMPT I; MF207 ; MADE TO CREATE A NEW TCB, BUT IT CANNOT GO THE ; MF207 ; PARTITION THE PROTOTYPE TCB IS INSTALLED IN ; MF207 ;- ;**-1 .ENABL LSB $DRREQ:: ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 MOV SP,$TEMP4 ;SAVE CURRENT STACK TO EASE UNWIND ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 CALL ERRSV ;INITIALIZE ERROR RECOVERY ; MF207 .WORD NULL ;NO IMMEDIATE ACTION ;**-1 .WORD NULL ;NO RECOVERY ACTION ADD #6,R3 ;POINT TO UIC WORD IN DPB MOV (R3)+,R4 ;PICK UP SPECIFIED UIC FOR REQUEST CMPB $DICSV+1,#7. ;IS THIS A SIMPLE REQUEST? ;**-1 BNE 5$ ;IF NE NO MOV T.UCB(R5),R5 ;GET UCB ADDRESS OF TASK'S TI: ; MF207 ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 CLR $TEMP4 ;NOT AN RPOI$ OR SDRP$ ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 JMP RQST ;DO REQUEST PROCESSING 5$: ;REFERENCE LABEL ; MF207 CMPB $DICSV+1,#13. ;IS IT A VALID SPAWN REQUEST? ;**-2 BEQ CNRQT ;IF EQ YES CMPB $DICSV+1,#14. ;IS IT A SPAWN REQUEST WITH TI SPECIFIED BEQ CNRQT ;IF EQ YES ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 CMPB $DICSV+1,#16. ;IS IT A RPOI$ DIRECTIVE ; MF207 BNE 10$ ;IF NE NO ; MF207 MOVB 13(R3),R2 ;GET FLAGS BYTE, FORCE TASK EXIT?? ; MF207 BMI 7$ ;IF MI YES ; MF207 MOV #1,$TEMP4 ;NO EXIT, BUT REMEMBER IT IS AN RPOI$ ; MF207 7$: CALL LOCOCB ;LOCATE THE OCB(S) TO BE PASSED ; MF207 ADD #6,R3 ;POINT TO CMD BUFFER IN DPB ; MF207 BR 35$ ;JOIN COMMON CODE ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 ; MF207 DPBER: ;REF LABEL ; MF207 10$: MOV (PC)+,R5 ;SET ILLEGAL DPB SIZE ; MF207 DRSTS D.RS99 ; ; MF207 JMP ERROR ;ILLEGAL DPB SIZE ERROR ; MF207 ;**-1 ; ; CONNECT PROCESSING (CNCT,SDRC,SPWN). ;MSH104 ; ;**-1 ; COMMON CONNECT AND REQUEST PROCESSING BEGINS HERE FOR REQUEST/SPAWN, ;MSH104 ; CONNECT, AND SEND REQUEST AND CONNECT DIRECTIVES. THE FOLLOWING ;MSH104 ; SECTION PERFORMS THE CONNECT PROCESSING. AN OFFSPRING CONTROL BLOCK ;**-2 ; IS ALLOCATED AND QUEUED TO THE OFFSPRING TASK'S OCB QUEUE. THEN THE ; EVENT FLAG AND EXIT STATUS BLOCK PARAMETERS ARE CHECKED AS THE OFF- ; SPRING CONTROL BLOCK IS INITIALIZED. IF AN OCB IS SUCCESSFULLY ; ALLOCATED, ITS ADDRESS IS STORED IN $TEMP1 AS A FLAG THAT IT MUST BE ; QUEUED TO THE TARGET TASK ON SUCCESSFUL EXIT. ; ; REGISTER CONTENTS AT THIS POINT: ; ; R0=ADDRESS OF THE TCB OF THE OFFSPRING TASK ; R3=PTR TO THE EVENT FLAG NUMBER IN THE DPB. ; CNRQT: MOV #O.LGTH,R1 ;PICK UP OCB SIZE ; MF207 .IF DF R$$POI ; MF207 ; MF207 CLR $TEMP4 ;NOT AN RPOI$ OR SDRP$ ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 CALL @(SP)+ ;ALLOCATE OCB WITH TRAIL TO DEALLOCATE .WORD $ALOCB ;ALLOCATION ROUTINE ADDRESS .WORD $DEACB ;DEALLOCATION ROUTINE ADDRESS BCC 20$ ;IF CC ALLOCATION SUCCESSFUL JMP ALLER ;ELSE REPORT ALLOCATION FAILURE 20$: MOV R0,$TEMP1 ;STORE OCB ADDRESS FOR CONNECT MOV (PC)+,R5 ;ASSUME INVALID EVENT FLAG NUMBER DRSTS D.RS97 ; MOV R0,R4 ;COPY OCB POINTER MOVB (R3)+,R0 ;PICK UP SPECIFIED EVENT FLAG ;MSH129 ;**-1 .IF DF G$$EFN CMP R0,#96. ;VALID EVENT FLAG NUMBER?  .IFF ;G$$EFN CMP R0,#64. ;VALID EVENT FLAG NUMBER? .IFTF ;G$$EFN BHI 10$ ;IF HI NO .IFT ;G$$EFN CMP R0,#64. ;IS IT A GROUP GLOBAL EVENT FLAG? BLOS 25$ ;IF LOS NO MOV R4,-(SP) ;SAVE OCB POINTER ;MSH049 MOV $HEADR,R4 ;GET ADDRESS OF CURRENT TASK'S HEADER ;**-1 MOVB H.CUIC+1(R4),R4 ;GET CUURRENT TASK'S GROUP NUMBER MOV R0,-(SP) ;SAVE EVENT FLAG NUMBER ;MSH049 CALL $SRGEF ;SEARCH FOR GROUP GLOBAL EVENT FLAGS MOV (SP)+,R0 ;RESTORE EVENT FLAG NUMBER ;MSH049 MOV (SP)+,R4 ;RESTORE OCB POINTER ;MSH049 BCS 10$ ;IF CS, INVALID EVENT FLAG SPECIFIED 25$: ;REFERENCE LABEL ;**-1 .ENDC ;G$$EFN MOV $TKTCB,R5 ;PICK UP CURRENT TASK TCB ADDRESS MOV R0,-(SP) ;SAVE EVENT FLAG NUMBER CALL $CEFIG ;CONVERT EVENT FLAG TO MASK AND ADDRESS ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 BIC #1,R1 ;CLR GRP GLOBAL 2ND WORD INDICATOR ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 BIC R0,(R1) ;CLEAR EVENT FLAG ;**-1 TST (R4)+ ;SKIP OVER OCB LINK WORD (O.LNK) CLR (R4)+ ;INITIALLY CLR MCR LINE PTR (O.MCRL) MOV R5,(R4)+ ;SET PARENT TCB ADDRESS (O.PTCB) ;MSH129 ; ;MSH129 ; THE EXIT STATUS BLOCK COMES IN TWO LENGTHS. THE DEFAULT LENGTH ;MSH129 ; AS SET UP BY THE PARENT/OFFSPRING DIRECTIVE MACROS IS 1. WORD. ;MSH129 ; THIS IS INDICATED BY HAVING A ZERO VALUE IN THE EXIT STATUS ;MSH129 ; BLOCK LENGTH FIELD IN THE DPB. THE OTHER POSSIBLE LENGTH OF THE ;MSH129 ; EXIT STATUS BLOCK IS 8. WORDS. THIS IS INDICATED BY A NON-ZERO ;MSH129 ; IN THE EXIT STATUS BLOCK LENGTH FIELD. ;MSH129 ; ;MSH129 ;MSH129 CLR R2 ;ASSUME 1-WORD EXIT STATUS BLOCK ;MSH129 ;MSH129 .IF DF A$$CHK!M$$MGE ;MSH129 ;MSH129 MOV #2,R1 ;SET APPROPRIATE LENGTH TO ADDRESS CHECK;MSH129 ;MSH129 .IFTF ;MSH129 ;MSH129 TSTB (R3)+ ;FULL LENGTH EXIT STATUS BLOCK? ;MSH129 BEQ 27$ ;IF EQ NO ;MSH129 INC R2 ;MARK AS FULL LENGTH EXIT STATUS BLOCK ;MSH129 ;MSH129 .IFT ;MSH129 ;MSH129 MOV #16.,R1 ;CORRECT ADDRESS CHECK LENGTH ;MSH129 ;MSH129 .ENDC ;A$$CHK!M$$MGE ;MSH129 ;MSH129 27$: MOV (R3)+,(R4)+ ;SET AST ADDRESS (O.AST) ;MSH129 MOV (SP)+,(R4)+ ;SET EVENT FLAG NUMBER (O.EFN) ;**-1 MOV (R3)+,R0 ;PICK UP EXIT STATUS BLOCK ADDRESS MOV R0,(R4) ;STORE IT IN OCB (O.ESB) ;MSH129 BIS R2,(R4)+ ;SET LENGTH OF EXIT STATUS BLOCK ;MSH129 MOV T.NAM(R5),(R4)+ ;STORE PARENT TASK NAME (O.STAT) ;**-1 MOV T.NAM+2(R5),(R4)+ ;(O.STAT+2) ;MSH117 ;MSH117 .IF DF M$$CRX ;MSH117 ;MSH117 CLR (R4)+ ;INITIALIZE PROTECTION UIC (O.STAT+4) ;MSH117 ;MSH117 .IF DF M$$MUP ;MSH117 ;MSH117 CLR (R4) ;INITIALIZE DEFAULT UIC (O.STAT+6) ;MSH117 ;MSH117 .ENDC ;M$$MUP ;MSH117 ;MSH117 .ENDC ;M$$CRX ;MSH117 ;**-1 .IF DF A$$CHK!M$$MGE TST R0 ;EXIT STATUS BLOCK SPECIFIED? BEQ 30$ ;IF EQ NO, BYPASS ADDRESS CHECK CALL $ACHCK ;ADDRESS CHECK EXIT STATUS BLOCK ;**-1 BCC 30$ ;IF CS ADDRESS CHECK OK JMP ADCER ;ADDRESS CHECK FAILURE .ENDC ;A$$CHK!M$$MGE 30$: CMPB $DICSV,#141. ;IS DIRECTIVE A SEND, REQUEST & CONNECT?;MSH104 BEQ 80$ ;IF EQ YES, BRANCH TO REQUEST TASK ;MSH104 BLO 35$ ;IF LO IT IS SPAWN ;**-1 JMP SUCCESS ;IF HI IT IS CONNECT, RETURN SUCCESS ;MSH104 35$: ;**-1 ; ; TI: DETERMINATION AND COMMAND LINE PROCESSING (SPWN). ; ; HERE THE TARGET TASK'S TI: IS DETERMINED FOR THE SUBSEQUENT REQUEST ; AND COMMAND LINE PROCESSING IS INITIATED. IF A TERMINAL UNIT ; HAS BEEN SPECIFIED, THEN IT IS VERIFIED AND ITS UCB IS FOUND. ; OTHERWISE THE ISSUING TASK'S UCB IS PROPAGATED. ; ; REGISTER CONTENTS AT THIS POINT: ; ; R3=PTR TO COMMAND LINE BUFFER ADDRESS IN THE DPB. ; MOV R5,R2 ;COPY ISSUING TASK'S TCB ADDRESS ;MSH131 MOV T.UCB(R5),R5 ;GET ISSUING TASK'S TI: UCB ;MSH131 CMPB $DICSV+1,#14. ;WAS TI: SPECIFIED? BLT 75$ ;IF LT NO ; MF207 TST 6(R3) ;DEVICE NAME SPECIFIED? ;**-1 BEQ 75$ ;IF EQ NO ;MSH131 MOV R3,R1 ;SAVE POINTER TO CMD LINE BUF ADD IN DPB;**-16 CMP (R1)+,(R1)+ ;POINT TO DEV AND UNIT IN DPB ; MF209 CALL $GTUCB ;GET UCB ADDRESS OF DEVICE ; MF209 BCS ILUER ;IF CS, DEVICE DOES NOT EXIST ; MF209 BIT #DV.TTY,U.CW1(R5) ;IS DEVICE A TERMINAL ; MF209 BEQ ILUER ;IF EQ NO ; MF209 MOV R1,R3 ;COPY POINTER ; MF209 CMP -(R3),-(R3) ;POINT TO COMMAND BUFFER IN DPB AGAIN ; MF209 BIT #T3.PRV!T3.CLI,T.ST3(R2) ;TASK ALLOWED TO SPECIFY OTHER ; MF203 BNE 75$ ;IF NE YES ;MSH131 CMP T.UCB(R2),R5 ;SAME TI: SPECIFIED? ;MSH131 BNE PRVER ;IF NE NO, NOT ALLOWED BY NONPRIV TASK ;MSH131 75$: ; ;MSH131 ;MSH131 .IF DF M$$CRX ;MSH131 ;MSH131 JMP CMLPR ;PERFORM COMMAND LINE PROCESSING ;MSH131 ;MSH131 .IFF ;MSH131 ;MSH131 MOV -10(R3),R4 ;PICK UP SPECIFIED UIC FOR REQUEST ;MSH131 BR RQST ;REQUEST OFFSPRING TASK ;MSH131 ;MSH131 .ENDC ;M$$CRX  ;MSH131 ;**-19 ; ; COMMON REQUEST PROCESSING (RQST, SPWN). ; ; HERE THE COMMON REQUEST PROCESSING IS PERFORMED FOR REQUEST AND ; SPAWN. DEFAULT AND PROTECTION UIC DETERMINATION IS ; PERFORMED AND THE TASK IS REQUESTED VIA $TSKRP. A TASK REQUEST ; FAILURE IS JUDGED IN LIGHT OF THE DIRECTIVE BEING PERFORMED. ; ; REGISTER CONTENTS AT RQST: ; ; R4=REQUEST UIC ; R5=TARGET TASK UCB ADDRESS ; RQST2: ;REFERENCE LABEL FOR SDRP$ ; MF207 80$: CLR R4 ;SET TO PROPAGATE ISSUING TASK'S UIC MOV T.UCB(R5),R5 ;SET TI: UCB ADDRESS RQST: MOV $TEMP0,R0 ;RESTORE POINTER TO TARGET TCB ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 BIC #1,R0 ;CLEAR TCB COPIED INDICATOR ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 110$: MOV $MCRCB,R2 ;PICK UP FIRST ENTRY IN GMCR QUEUE BEQ 120$ ;IF EQ THERE IS NONE TST (R2)+ ;POINT TO TCB ADDRESS TST (R2) ;QUEUED IN THIS DIRECTIVE? BNE 120$ ;IF NE NO MOV R0,(R2) ;SET TCB ADDRESS IN COMMAND LINE 120$: MOV R4,R1 ;COPY SPECIFIED UIC ADDRESS CALL UISET ;CALCULATE DEFAULT AND PROTECTION UICS ;MSH117 MOV R5,R2 ;PICK UP TARGET UCB ADDRESS ;**-12 MOV R0,R5 ;SAVE ADDRESS OF TARGET TASK TCB CALL $TSKRP ;REQUEST THE TASK BCC RQSUC ;IF CC SUCCESS BNE ALER1 ;IF NE ALLOCATION FAILURE CMPB $DICSV,#141. ;IS IT LEGAL FOR TASK TO BE ACTIVE? ;MSH104 BEQ SUCCES ;IF EQ YES ;MSH104 MOV (PC)+,R5 ;PICK UP TASK ALREADY ACTIVE STATUS DRSTS D.RS7 ; BR ERROR ;RETURN ERROR STATUS .DSABL LSB ; ; LOCAL ERROR RETURN ROUTINES. ; ; THE FOLLOWING ROUTINES INTERFACE TO $DRTHR AND $ERREC FOR DIRECTIVE ; ERROR STATUS RETURNS AND ERROR RECOVERY. R5 IS USED TO STORE THE ; ERROR STATUS TRAP INSTRUCTION. ; ALLER: ADD #6,SP ;POP THREAD TO DEALLOCATE ROUTINE ;**-4 ALER1: MOV (PC)+,R5 ;PICK UP ALLOCATION FAILURE STATUS DRSTS D.RS1 ; ERROR: JMP $ERREC ;THREAD THROUGH ERROR RECOVERY CMLER: MOV (PC)+,R5 ;PICK UP COMMAND LINE ERROR STATUS DRSTS D.RS2 ; BR ERROR  ;RETURN ERROR STATUS ILUER: MOV (PC)+,R5 ;PICK UP ILLEGAL DEVICE UNIT ERROR DRSTS D.RS92 ; BR ERROR ;RETURN ERROR STATUS PRVER: MOV (PC)+,R5 ;PICK PRIVILEGE VIOLATION ERROR DRSTS D.RS16 ; BR ERROR ;RETURN ERROR STATUS RQSUC: SUCCES: MOV $TEMP1,R1 ;IS THERE AN OCB TO QUEUE? ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 .IFF ;R$$POI ; MF207 ; MF207 BEQ 30$ ;IF EQ NO ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 MOV $TEMP0,R4 ;GET ADDRESS OF TARGET TASK ; MF207 BIT #1,R4 ;WAS TARGET TCB CREATED IN THIS DIRECTIV; MF207 BEQ 5$ ;IF EQ NO ; MF207 DEC R4 ;GET RID OF INDICATOR BIT ; MF207 BIS #T3.REM,T.ST3(R4) ;SET TO REMOVE ON EXIT ; MF207 5$: MOV R4,R2 ;COPY ADDRESS ; MF207 ADD #T.OCBH,R4 ;POINT TO ITS OCB LISTHEAD ; MF207 TST $TEMP4 ;IS IT AN RPOI$ OR SDRP$ ; MF207 BEQ 10$ ;IF EQ NO ; MF207 MOV $TKTCB,R0 ;POINT TO CURRENT TASKS TCB ; MF207 ADD #T.OCBH,R0 ;ACTUALLY TO ITS OCB LISTHEAD ; MF207 CMP #1,R1 ;PASS ALL OCBS ; MF207 BEQ 40$ ;IF EQ YES ; MF207 ; MF207 ; MF207 .IF DF A$$CLI ; MF207 ; MF207 BIT #T3.CLI,T.ST3-T.OCBH(R4) ;IS OBJECT TASK A CLI ; MF207 BNE 505$ ;IF NE YES ; MF207 BIT #T3.CLI,T.ST3-T.OCBH(R0) ;IS CURRENT TASK A CLI ; MF207 BEQ 6$ ;IF EQ NO ; MF207 505$: CALL PSPRMT ;PASS PROMPT CONTROL ; MF207 6$: TST R1 ;IS THERE AN OCB TO PASS ; MF207 BEQ 60$ ;IF EQ NO ; MF207 ; MF207 .IFF ;A$$CLI ; MF207 ; MF207 BHI 60$ ;IF HI, NO OCB TO PASS ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 CALL $QRMVT ;REMOVE THE OCB, THERE MUST BE ONE ; MF207 BR 20$ ;DO NOT TOUCH PARENT'S RUNDOWN COUNT ; MF207 10$: TST R1 ;IS THERE AN OCB TO PASS ; MF207 BEQ 70$ ;IF EQ NO ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 MOV O.PTCB(R1),R2 ;PICK UP PARENT TCB ADDRESS ; MF207 INC T.RDCT(R2) ;INCREMENT PARENT'S RUNDOWN COUNT ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 20$: MOV R4,R0 ;GET OFFSPRING ADDRESS ; MF207 ; MF207 .IFF ;R$$POI ; MF207 ; MF207 MOV $TEMP0,R0 ;PICK UP TARGET TCB ADDRESS ; MF207 ADD #T.OCBH,R0 ;POINT TO OCB LISTHEAD ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 CALL $QINSF ;INSERT OCB IN ITS QUEUE ; MF207 ; MF207 .IFF ;R$$POI ; MF207 ; MF207 30$: DRSTS +1 ;ALL DONE ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 BR 60$ ; ; MF207 40$: CALL PSPRMT ;PASS PROMPT CONTROL ; MF207 MOV (R0),R1 ;GET ADDRESS OF FIRST OCB ; MF207 BEQ 60$ ;THERE MAY NOT BE ANY ; MF207 CLR (R0) ;FORCE THE LIST TO EMPTY ; MF207 MOV R0,2(R0) ;SET SECOND HALF OF LISTHEAD ; MF207 MOV R1,@2(R4) ;LINK IT AFTER PREVIOUS LAST OCB ; MF207 50$: MOV R1,2(R4) ;SET NEW POINTER TO LAST ENTRY ; MF207 MOV (R1),R1 ;POINT TO NEXT OCB IN QUEUE ; MF207 BNE 50$ ;IF NE, THERE IS ANOTHER ONE ; MF207 60$: CMP #1,$TEMP4 ;FORCE CURRENT TASK TO EXIT ; MF207 BHIS 70$ ;IF HIS NO ; MF207 MOV $TEMP4,SP ;RELOAD STACK TO RETURN TO DRDSP ; MF207 MOV $TKTCB,R5 ;POINT TO CURRENT TASK TCB ; MF207 CALLR $DREXT ;FORCE CURRENT TASK TO EXIT ; MF207 70$: DRSTS +1 ;ALL DONE ; MF207 ; ; MF207 ; MF207 .IF DF A$$CLI&I$$RAR&D$$YNM&C$$CKP&D$$YNC ; MF207 ; MF207 PARERR: MOV (PC)+,R5 ;COPIED TCB CANNOT GO IN THIS PARTITION ; MF207 DRSTS D.RS94 ; ; MF207 BR ERROR ;RETURN ERROR STATUS ; MF207 ; MF207 ; MF207 .ENDC ;A$$CLI&I$$RAR&D$$YNM&C$$CKP&D$$YNC ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 ADCPOP: TST (SP)+ ;CLEAN STACK BEFORE RETURNING ERROR ; MF207 ADCER: MOV (PC)+,R5 ;PICK UP ADDRESS CHECK ERROR STATUS ; MF207 DRSTS D.RS98 ; ; MF207 BR ERROR ;RETURN ERROR STATUS ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 ILPARM: MOV (PC)+,R5 ;PICK UP PARAMETER ILLEGAL FOR THIS TASK; MF207 DRSTS D.RS8 ; ; MF207 BR ERROR ;RETURN ERROR STATUS ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 ; MF207 ;**-7 ; ; COMMAND LINE PROCESSING (SPWN). ; ; THIS SECTION PERFORMS THE COMMAND LINE PROCESSING FOR THE SPWN$ AND RP; MF207 ; DIRECTIVE. FIRST A STANDARD SIZE COMMAND LINE BUFFER IS ALLOCATED ;**-1 ; AND THEN ADDRESS CHECKING OF THE USER SPECIFIED COMMAND LINE IS ; PERFORMED. THE COMMAND LINE IS THEN TRANSFERRED TO THE ALLOCATED ; BUFFER AND TERMINATED WITH AN ESCAPE CHARACTER. IF THE TARGET TASK ; IS NOT A COMMAND LINE INTERPRETER, THEN THE COMMAND LINE IS QUEUED ;MSH103 ; FOR THE TASK TO $MCRCB, MAKING IT AVAILABLE VIA THE GET MCR COMMAND ;**-1 ; LINE DIRECTIVE. IF THE TARGET TASK IS A COMMAND LINE INTERPRETER, ;MSH103 ; ON A SYSTEM WITHOUT A$$CLI, OR THE DISPATCHER ON A SYSTEM WITH A$$CLI ; MF203 ; THEN THE COMMAND LINE IS QUEUED TO THE CLI'S RECEIVE QUEUE AND $EXRQN ;MSH103 ; IS CALLED TO INSURE THE CLI IS ACTIVE AND NOT STOPPED (VIA THE ROUTINE;MSH103 ; $QCLIL). SPAWN PROCESSING FOR A CLI IS COMPLETE AT THIS POINT. ;MSH103 ; IF THE SYSTEM SUPPORTS A$$CLI AND THE CLI IS NOT THE DISPATCHER (MCR..; MF203 ; THE SIZE OF THE COMMAND BUFFER IS NOT STANDARD. IT IS LONG ENOUGH TO ; MF203 ; CONTAIN THE COMMAND AND 5 HEADER WORDS. THESE WORDS ARE A LINK WORD, ; MF203 ; CLI'S TCB ADDRESS, ISSUING TERMINAL'S UCB ADDRESS, THE SIZE OF ; MF203 ; THE BUFFER, THE TERMINATOR CHARACTER, AND A STATUS BYTE. ; MF203 ; THE BUFFER IS LINKED INTO THE $CLICQ LIST AND THE CLI ; MF203 ; STARTED BY THE $QCLIL ROUTINE. ; MF203 ; ;**-4 ; THIS SECTION LOGICALLY FALLS IN LINE AFTER THE TI: DETERMINATION ABOVE ; BUT HAS BEEN PLACED HERE FOR CONVENIENCE TO MAKE ALL BRANCHES REACH. ; ; REGISTER CONTENTS AT THIS POINT: ; ; R3=PTR TO COMMAND LINE ADDRESS IN THE DPB. ; R5=TARGET TASK UCB ADDRESS. ; .IF DF M$$CRX .IF DF A$$CLI ; MF203 ; MF203 BRALER: BR ALLER ;BR TO ALLOCATION FAILURE ; MF203 ; MF203 .IFTF ;A$$CLI ; MF203 ; MF203 CMLPR: MOV (R3),R1 ;COMMAND LINE SPECIFIED? BEQ 10$ ;IF EQ NO CMP 2(R3),#79. ;COMMAND LINE TOO LONG ; MF203 BHI ADCER ;IF HI YES ; MF203 MOV #M$$CRB,R1 ;ASSUME STANDARD LENGTH ; MF203 ; MF203 .IFT ;A$$CLI ; MF203 ; MF203 MOV $TEMP0,R0 ;POINT TO OBJECT TASK ; MF203 CLR $TEMP2 ;ASSUME COMMAND GOING TO NON-CLI ; MF203 CMP $MCRPT,R0 ;IS IT THE DISPATCHER ; MF203 BEQ 2$ ;IF EQ YES ; MF203 BIT #T3.CLI,T.ST3(R0) ;IS TARGET TASK A CLI ; MF203 BEQ 2$ ;IF EQ NO ; MF203 MOV 2(R3),R1 ;GET NUMBER OF CHARACTERS IN COMMAND ; MF203 ADD #12+1,R1 ;ALLOW FOR LONGER HEADER + TERMINATOR ; MF203 MOVB #6,$TEMP2 ;SKIP OVER LINK, TCB AND UCB ADDRESSES ; MF203 MOVB R1,$TEMP2+1 ;SAVE SIZE OF COMMAND BUFFER ; MF203 2$: ;REFERENCE LABEL ; MF203 ; MF203 .IFTF ;A$$CLI ; MF203 ; MF203 CALL @(SP)+ ;ALLOCATE BUF WITH TRAIL TO DEALLOCATE ;**-1 .WORD $ALOCB ;ALLOCATION ROUTINE ADDRESS .WORD $DEACB ;DEALLOCATION ROUTINE ADDRESS 3$: ; MF207 .IFF ;A$$CLI ; MF207 ; MF207 BCS ALLER ;IF CS, ALLOCATION FAILURE ; MF207 ; MF207 .IFT ;A$$CLI ; MF207 ; MF207 BCS BRALER ;IF CS, BR TO ALLOCATION FAILURE ; MF207 MOVB $TEMP2,R4 ;GET OFFSET TO PACKET SIZE IN BUFFER ; MF203 ADD R0,R4 ;POINT TO UCB ADDR IN BUFFER ; MF203 ; MF203 .IFF ; MF203 ; MF203 MOV R0,R4 ;SAVE ADDRESS OF ALLOCATED BUFFER ; MF203 ; MF203 .ENDC ;A$$CLI ; MF203 ; MF203 ; MF203 TST (R4)+ ;SKIP OVER LINK WORD ;**-2 CLR (R4)+ ;CLEAR TCB ADDRESS MOV 2(R3),R1 ;PICK UP SIZE OF COMMAND LINE BEQ 6$ ;IF EQ, DON'T BOTHER MOVING IT MOV (R3),R0 ;PICK UP ADDRESS ;**-2 .IF DF A$$CHK!M$$MGE MOV R1,-(SP) ;SAVE BUFFER LENGTH CALL $ACHKB ;ADDRESS CHECK COMMAND LINE BUFFER BCS ADCPOP ;IF CS ADDRESS CHECK FAILURE .ENDC ;A$$CHK!M$$MGE .IF DF M$$MGE CALL $RELOC ;RELOCATE USER ADDRESS SUB #20000,R2 ;CONVERT SOURCE TO KISAR5 DISPLACEMENT MOV (SP)+,R0 ;RESTORE COUNT FOR $BLXIO CALL $BLXIO ;COPY USER'S COMMAND LINE .IFF ;M$$MGE .IF DF A$$CHK MOV (SP)+,R1 ;PICK UP SIZE OF COMMAND LINE .ENDC ;A$$CHK 4$: MOVB (R0)+,(R4)+ ;MOVE IT DEC R1 ;MORE TO MOVE? BGT 4$ ;IF GT, YES .ENDC ;M$$MGE 6$: MOVB #33,(R4) ;TERMINATE LINE WITH ESCAPE MOV 2(SP),R1 ;RETRIEVE SAVED BUFFER ADDRESS 10$: MOV $TEMP0,R0 ;PICK UP TARGET TASK TCB ADDRESS BIT #T3.CLI,T.ST3(R0) ;TARGET TASK A CLI? BNE 20$ ;IF NE, YES ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 CLR $TEMP2 ;ASSUME NO COMMAND LINE ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 TST R1 ;COMMAND LINE SPECIFIED? BEQ 11$ ;IF EQ NO ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 MOV R4,$TEMP2 ;SAVE ADDRESS OF TERMINATOR IN BUFFER ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 MOV #$MCRCB,R0 ;POINT TO GET MCR LINE LISTHEAD ;**-1 CALL @(SP)+ ;QUEUE THE COMMAND WITH TRAIL TO DEQUEUE .WORD QMCRB ;ROUTINE TO QUEUE THE COMMAND LINE .WORD DMCRB ;ROUTINE TO DEQUEUE THE LINE 11$: ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 MOV $TEMP4,R4 ;IS THIS AN RPOI$ DIRECTIVE ; MF207 BEQ 15$ ;IF EQ NO ; MF207 ; MF207 .IF DF I$$RAR&D$$YNM&C$$CKP&D$$YNC&A$$CLI ; MF207 ; MF207 ADD #10,R3 ;POINT TO NAME FOR NEW TASK ; MF207 MOV $TKTCB,R2 ;GET CURRENT TASK'S TCB ADDR ; MF207 BIT #T3.CLI,T.ST3(R2) ;IS CURRENT TASK A CLI ; MF207 BEQ 13$ ;IF EQ NO ; MF207 MOV $TEMP0,R0 ;GET OFFSPRING TCB ADDR ; MF207 CMP #^R...,T.NAM(R0) ;IS IT THE MU TYPE ; MF207 BNE 13$ ;IF NE NO ; MF207 TST (R3) ;IS A NEW NAME PRESENT ; MF207 BEQ 14$ ;IF NE NO, GO WITH EXISTING TCB ; MF207 CALL $SRSTD ;DOES TASK ALREADY EXIST ; MF207 BCS 12$ ;IF CS, TASK DOES NOT EXIST ; MF207 CMP R0,R2 ;DID WE FIND OURSELF ; MF207 BNE 115$ ;IF NE NO ; MF207 CMP #1,R4 ;WILL CURRENT TASK EXIT ; MF207 BNE 12$ ;IF NE YES ; MF207 115$: MOV R0,$TEMP0 ;USE IT ; MF207 BR 14$ ; ; MF207 12$: MOV #T.LGTH,R1 ;GET LENGTH OF A TCB ; MF207 CALL @(SP)+ ;ALLOCATE A TCB ; MF207 .WORD $ALOCB ;ALLOCATION ROUTINE ; MF207 .WORD $DEACB ;DEALLOCATION ROUTINE ; MF207 BCS 3$ ;ALLOCATION FAILURE ; MF207 MOV $TEMP0,R1 ;POINT TO TCB TO BE COPIED ; MF207 CALL @(SP)+ ;PUSH UNLINK ROUTINE FOR FUTURE ERRORS ; MF207 .WORD NULL ;NOTHING TO DO NOW ; MF207 .WORD UNLTCB ;UNLINK TCB ; MF207 CALL CPYTCB ;COPY TCB AND LINK IT INTO THE STD ; MF207 BCC 125$ ;IF CC OK ; MF207 JMP PARERR ;IF CS NEW TASK CANNOT GO IN PARTITION ; MF207 125$: INC R0 ;INDICATE TCB CREATED BY THIS DIRECTIVE ; MF207 MOV R0,$TEMP0 ;USE NEW TCB ; MF207 BR 14$ ; ; MF207 13$: TST (R3) ;WAS A NEW NAME SUPPLIED ; MF207 BEQ 14$  ;IF EQ NO ; MF207 JMP ILPARM ;ILLEGAL PARAMETER SPECIFIED ; MF207 14$: SUB #10,R3 ;POINT TO COMMAND BUFFER ADDR IN DPB ; MF207 ; MF207 .IFF ;I$$RAR&D$$YNM&C$$CKP&D$$YNC&A$$CLI ; MF207 ; MF207 TST 10(R3) ;WAS A NEW TASK NAME SPECIFIED ; MF207 BNE ILPARM ;ILLEGAL PARAMETER SPECIFIED ; MF207 ; MF207 .ENDC ;I$$RAR&D$$YNM&C$$CKP&D$$YNC&A$$CLI ; MF207 ; MF207 .IFTF ;R$$POI ; MF207 ; MF207 ; MF207 15$: MOV -10(R3),R4 ;PICK UP SPECIFIED UIC FOR REQUEST JMP RQST ;JUMP TO REQUEST TASK 20$: TST R1 ;IS THERE A COMMAND LINE? ; MF207 BNE 21$ ;IF NE YES (MUST BE FOR A CLI) ; MF207 MOV (PC)+,R5 ;PICK UP COMMAND LINE ERROR STATUS ; MF207 DRSTS D.RS2 ; ; MF207 JMP ERROR ;RETURN ERROR STATUS ; MF207 21$: MOV $TEMP1,R2 ;PICK UP OCB ADDRESS ; MF207 BEQ 22$ ;IF EQ, NO OCB TO PASS ; MF207 MOV R1,O.MCRL(R2) ;STORE POINTER TO MCR COMMAND LINE ; MF207 22$: MOV R5,2(R1) ;STORE UCB ADDRESS IN COMMAND LINE BUF ; MF207 ; MF207 .IFT ;R$$POI ; MF207 ; MF207 MOV R4,(R1) ;STORE TERMINATOR ADDRESS IN BUFFER ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 ; MF207 CALL @(SP)+ ;PUSH ROUTINE TO REMOVE LINE ;**-4 .WORD NULL ;NO IMMEDIATE ACTION .WORD 40$ ;ROUTINE TO REMOVE LINE MOV R1,-(SP) ;SAVE COMMAND LINE POINTER ;MSH117 MOV -10(R3),R1 ;PICK UP SPECIFIED UIC FOR REQUEST ;MSH117 BEQ 25$ ;IF EQ NONE SPECIFIED ;MSH117 MOV R2,R5 ;COPY OCB POINTER ;MSH117 BEQ 25$ ;IF EQ, NO OCB TO PASS ; MF207 ;MSH153 .IF DF A$$CLI&M$$MUP ;MSH153 ;MSH153 MOV R3,-(SP) ;SAVE DPB POINTER ;MSH153 ;MSH153 .ENDC ;MSH153 ;MSH153 CALL UISET ;CALCULATE DEFAULT AND PROTECTION UICS ;MSH117 MOV R1,O.STAT+4(R5) ;SAVE PROTECTION UIC FOR CLI TO PICK UP ;MSH117 ;MSH117 .IF DF M$$MUP ;MSH117 ;MSH117 MOV R3,O.STAT+6(R5) ;SAVE DEFAULT UIC FOR CLI TO PICK UP ;MSH117  ;MSH153 .IF DF A$$CLI ;MSH153 ;MSH153 MOV (SP)+,R3 ;RESTORE DPB POINTER ;MSH153 ;MSH153 .ENDC ;MSH153 ;MSH117 .ENDC ;M$$MUP ;MSH117 ;MSH117 25$: MOV (SP)+,R1 ;RETRIEVE COMMAND LINE POINTER ;MSH117 ; MF203 ; MF203 .IF DF A$$CLI ; MF203 ; MF203 MOV #$QCLIL,-(SP) ;ASSUME OBJECT TASK IS NOT DISPATCHER ; MF203 CMP $MCRPT,R0 ;IS IT THE DISPATCHER? ; MF203 BEQ 26$ ;IF EQ YES ; MF203 MOV 2(R1),4(R1) ;PUT UCB ADDRESS IN PROPER PLACE ; MF203 MOV R0,2(R1) ;INSERT TCB ADDRESS IN BUFFER ; MF203 MOVB $TEMP2+1,6(R1) ;PUT NUMBER OF CHARS IN CMD IN BUFFER ; MF203 CLRB 7(R1) ;CLEAR OUT GARBAGE IN HIGH BYTE ;MSH193 MOV #33,10(R1) ;ASSUME TERMINATOR IS ESC ; MF203 ; MF203 .IF DF R$$POI ; MF203 ; MF203 MOV R1,$TEMP2 ;POINT TO LOCATION IN BUFFER FOR TERMINA; MF203 ADD #10,$TEMP2 ; ; MF203 MOVB #15,@(R1) ;PUT A CR IN BUFFER FOR CONSISTANCY ; MF203 ; MF203 .IFTF ;R$$POI ; MF203 ; MF203 BR 27$ ; ; MF203 26$: ; MF203 ; MF203 .IFT ;R$$POI ; MF203 ; MF203 MOV (R1),$TEMP2 ;POINT TO LOCATION FOR TERMINATOR ; MF203 ; MF203 .ENDC ;R$$POI ; MF203 ; MF203 ; MF203 CMP #^RCLI,-22(R3) ;DOES USER WANT TTY'S CURRENT CLI ; MF203 BNE 27$ ;IF NE NO, MCR IS DESIRED CLI ; MF203 MOV #$QMCRL,(SP) ;QUEUE CMD TO TERMINAL'S CLI ; MF203 27$: CALL @(SP)+ ;QUEUE COMMAND AND REQUEST CLI ; MF203 BCC 28$ ;IF CC, SUCCESSFUL REQUEST ; MF203 BEQ 28$ ;IF EQ, SUCCESSFUL REQUEST ; MF203 JMP ALER1 ;PCB ALLOCATION FAILURE ; MF203 28$: JMP SUCCES ;SUCCESS ; MF203 ; MF203 .IFF ;A$$CLI ; MF203 ; MF203 CALL $EXRQF ;QUEUE COMMAND TO CLI AND REQUEST ; MF203 ;MSH153 .IF DF R$$POI ;MSH153 ;MSH153 BCC 31$ ;IF CC SUCCESSFUL REQUEST ;MSH153 BEQ 31$ ;IF EQ CLI ALREADY ACTIVE - SUCCESS ;MSH153 JMP ALER1 ;ELSE REQUEST FAILED FOR PCB ALLOCATION ;MSH153 31$: JMP SUCCES ; ;MSH153 ;MSH153 .IFF ;MSH153 ;MSH153 BCC SUCCES ;IF CC SUCCESSFUL REQUEST ;**-1 BEQ SUCCES ;IF EQ CLI WAS ALREADY ACTIVE - SUCCESS BR ALER1 ;ELSE REQUEST FAILED FOR PCB ALLOCATION ;MSH153 .ENDC ;R$$POI ;MSH153 ;MSH153 40$: ;REFERENCE LABEL ; MF203 .IFT ;A$$CLI ; MF203 ; MF203 40$: CMP $MCRPT,R0 ;IS COMMAND QUEUED TO MCR... ; MF203 BEQ 45$ ;IF EQ YS ; MF203 MOV #$CLICQ-T.RCVL,R0 ;SET POINTER TO CMD QUEUE LISTHEAD ; MF203 45$: ;REFERENCE LABEL ; MF203 ; MF203 .ENDC ;A$$CLI ; MF203 ; MF203 ; MF203 ADD #T.RCVL,R0 ;POINT TO CLI'S RECEIVE QUEUE ; MF203 CALLR $QRMVT ;REMOVE THE COMMAND LINE ;**-1 .ENDC ;M$$CRX ;+ ; **-$DREXS-EXIT WITH STATUS ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO PASS A STATUS WORD TO ALL ; PARENT TASKS AND EXIT. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(29.),DPB SIZE(2.)  ; WD. 01 -- STATUS WORD. ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE STATUS WORD IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; NO STATUS IS RETURNED TO THE ISSUING TASK SINCE THIS DIRECTIVE ; TERMINATES ITS EXECUTION. ;- $DREXS:: ;REF LABEL ;MSH021 ;MSH021 .IF DF A$$CPS ;MSH021 ;MSH021 BIT #T3.ACP,T.ST3(R5) ;IS THIS AN ACP? ;MSH021 BNE 5$ ;IF NE YES ;**-1 ;MSH021 .ENDC ;MSH021 ;MSH021 MOV (R3),T.EFLG+2(R5) ;SET EXIT STATUS IN TCB 5$: CALLR $DREX2 ;INITIATE TASK EXIT PROCESS ;MSH115 ;**-1 ;+ ;MSH104 ; **-$DREMS-EMIT STATUS ;MSH104 ; ;MSH104 ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO EMIT A STATUS WORD TO ALL ;MSH104 ; OR A SPECIFIED PARENT TASK WITHOUT EXITTING. ;MSH104 ; ;MSH104 ; DPB FORMAT: ;MSH104 ; ;MSH104 ; WD. 00 -- DIC(147.),DPB SIZE(4.). ;MSH104 ; WD. 01 -- FIRST WORD OF PARENT TASK NAME OR 0 FOR ALL. ;MSH104 ; WD. 02 -- SECOND WORD OF PARENT TASK NAME. ;MSH104 ; WD. 03 -- STATUS WORD. ;MSH104 ; ;MSH104 ; INPUTS: ;MSH104 ; ;MSH104 ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ;MSH104 ; R3=ADDRESS OF THE PARENT TASK NAME IN THE DPB. ;MSH104 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ;MSH104 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ;MSH104 ; ;MSH104 ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ;MSH104 ; ;MSH104 ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ;MSH104 ; DIRECTIVE STATUS OF +1 IS RETURNED. ;MSH104 ; C=1 IF DIRECTIVE IS REJECTED. ;MSH104 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THE SPECIFIED;MSH104 ; TASK IS NOT A PARENT OF THE ISSUING TASK. ;MSH104 ;- ;MSH104 ;MSH104 $DREMS::MOV 4(R3),-(SP) ;SAVE SPECIFIED STATUS WORD ;MSH104  MOV R3,R4 ;COPY TASK NAME POINTER ;MSH104 20$: MOV R5,R0 ;COPY ISSUING TASK TCB POINTER ;MSH104 ADD #T.OCBH,R0 ;POINT TO OCB QUEUE ;MSH104 MOV R0,R1 ;COPY LISTHEAD POINTER ;MSH104 30$: MOV (R1),R1 ;POINT TO NEXT IN QUEUE ;MSH104 BEQ 60$ ;IF EQ THERE IS NONE ;MSH104 TST (R4) ;TASK NAME SPECIFIED? ;MSH104 BEQ 40$ ;IF EQ NO (PASSING STATUS TO ALL) ;MSH104 CMP (R4),O.STAT(R1) ;MATCH ON FIRST WORD OF TASK NAME? ;MSH104 BNE 30$ ;IF NE NO ;MSH104 CMP 2(R4),O.STAT+2(R1) ;MATCH ON SECOND WORD OF TASK NAME? ;MSH104 BNE 30$ ;IF NE NO ;MSH104 40$: CALL $QRMVT ;REMOVE THE ENTRY ;MSH104 MOV (SP),R0 ;PICK UP SPECIFIED STATUS WORD ;MSH104 MOV #S.CACT,R2 ;TASK STILL ACTIVE ;MSH104 CALL $QUEXT ;QUEUE THE OCB TO PARENT TASK ;MSH104 TST (R4) ;PASSING STATUS TO ALL PARENTS? ;MSH104 BEQ 20$ ;IF EQ YES ;MSH104 50$: TST (SP)+ ;CLEAN STACK ;MSH104 RETURN ; ;MSH104 ;MSH104 60$: TST (R4) ;WAS A TASK NAME SPECIFIED? ;MSH104 BEQ 50$ ;IF EQ NO ;MSH104 DRSTS D.RS8 ;INCONSISTENT WITH CURRENT TASK STATE ;MSH104 ;MSH104 ;MSH104 ;MSH104 ; ; LOCAL ROUTINES. ; ; THE FOLLOWING ROUTINES ARE USED TO INSERT AND REMOVE AN ELEMENT FROM ; THE FRONT OF A LIST. SPECIFICALLY THESE ROUTINES ARE CALLED TO ; OPERATE ON THE MCR COMMAND LINE LIST AT $MCRCB. ; QMCRB: MOV (R0),(R1) ;LINK NEW LINE TO FIRST IN LIST MOV R1,(R0) ;LINK LISTHEAD TO NEW LINE RETURN ; DMCRB: MOV (R1),(R0) ;UNLINK NEW COMMAND LINE NULL: RETURN ;(NULL ROUTINE) ; ; ROUTINE TO INITIALIZE ERROR RECOVERY FOR CONNECT, REQUEST, SEND ; REQUEST AND CONNECT, AND SPAWN. ; ERRSV: MOV R0,$TEMP0 ;SAVE TARGET TCB ADDRESS CLR $TEMP1 ;INITIALIZE OCB POINTER JMP $DRTHR ;INITIALIZE ERROR RECOVERY THREADING ;MSH117 ; ;MSH117 ; THIS ROUTINE CALCULATES THE DEFAULT AND PROTECTION UICS FOR ;MSH117 ; THE CURRENT TASK. ;MSH117 ; ;MSH117 ; INPUTS: ;MSH117 ; ;MSH117 ; R1=REQUEST UIC ;MSH117 ; ;MSH117 ; OUTPUTS: ;MSH117 ; ;MSH117 ; R1=PROTECTION UIC ;MSH117 ; R3=DEFAULT UIC (FOR MULTIUSER SYSTEMS ONLY) ;MSH117 ; R4=ADDRESS OF THE CURRENT TASK'S HEADER ;MSH117 ; ;MSH117 ; R0 AND R5 ARE PRESERVED ACROSS THIS CALL ;MSH117 ; ;MSH117 ;MSH117 UISET: MOV $TKTCB,R2 ;GET CURRENT TASK'S TCB ;MSH117 ADD #T.ST2,R2 ;POINT TO THE TASK STATUS WORD ;MSH117 MOV $HEADR,R4 ;GET CURRENT TASK'S HEADER ADDRESS ;MSH117 ;MSH117 .IF DF M$$MUP ;MSH117 ;MSH117 CALL $UISET ;CALCULATE DEFAULT AND PROTECTION UICS ;MSH117 ;MSH117 .IFF ;MSH051 ;MSH051 TST R1 ;UIC DEFAULTED? ;MSH051 BNE 70$ ;IF NE NO ;MSH051 MOV H.CUIC(R4),R1 ;DEFAULT THE CURRENT UIC VALUE ;MSH051 70$: ; ;MSH051 .ENDC ;M$$MUP ;MSH117 ;MSH117 RETURN ;DONE ;MSH117 ;MSH117 ; ; MF207 ; THIS ROUTINE PASSES THE PROMPTING CONTROL BIT (T3.MCR) FROM THE CURREN; MF207 ; TASK TO THE TARGET. IT IS CALLED ONLY IF THE CURRENT TASK HAS PASSED ; MF207 ; ALL ITS OCB(S) TO THE TARGET, OR IF THE CURRENT TASK IS A CLI ; MF207 ; ON SYSTEMS THAT SUPPORT ALTERNATE CLIS ; MF207 ; ; MF207 ; INPUTS: ; MF207 ; ; MF207 ; R0=POINTER TO OCB LISTHEAD (T.OCBH) OF CURRENT TASK ; MF207 ; R2=TCB ADDRESS OF THE TARGET TASK ; MF207 ; $TEMP2=ADDRESS OF LOCATION TO PUT TERMINATOR ; MF207 ; ; MF207 ; OUTPUTS: ; MF207 ; ; MF207 ; NONE ; MF207 ; ; MF207 ; ALL REGISTERS PRESERVED ; MF207 ; ; MF207 ; MF207 .IF DF R$$POI ; MF207 ; MF207 PSPRMT: MOV #T3.MCR,-(SP) ;GET PROMPT BIT PATTERN ; MF207 BIC (SP),T.ST3(R2) ;ASSUME TARGET SHOULD NOT PROMPT ; MF207 BIT (SP),T.ST3-T.OCBH(R0) ;WILL CURRENT TASK PROMPT ; MF207 BEQ 10$ ;IF EQ NO ; MF207 BIS (SP),T.ST3(R2) ;TARGET SHOULD PROMPT ; MF207 TST $TEMP2 ;IS THERE A CMD LINE ; MF207 BEQ 10$ ;IF EQ NO ; MF207 MOVB #15,@$TEMP2 ;SET CR AS TERMINATOR ; MF207 10$: BIC (SP)+,T.ST3-T.OCBH(R0) ;CURRENT TASK SHOULD NOT PROMPT ; MF207 RETURN ; MF207 ; MF207 ; ; MF207 ; THIS ROUTINE LOCATES THE OCB(S) TO BE PASSED BY THE RPOI$ AND SDRP$ ; MF207 ; DIRECTIVES. ; MF207 ; ; MF207 ; INPUTS: ; MF207 ; ; MF207 ; R2=FLAGS BYTE ; MF207 ; R3=ADDRESS OF THE PARENT'S TASK NAME IN THE DPB ; MF207 ; ; MF207 ; ; MF207 ; OUTPUTS: ; MF207 ; ; MF207 ; $TEMP1 IS SET WITH THE ADDRESS OF THE OCB TO PASS, CLEAR IF ; MF207 ; NO OCB IS TO BE PASSED, OR ONE TO PASS ALL OCBS ; MF207 ; ; MF207 ; MF207 LOCOCB: MOV (SP)+,R4 ;RETURN ADDR OFF STACK (ERROR THREADING); MF207 CLR $TEMP1 ;ASSUME NO OCB TO PASS ; MF207 ASR R2 ;PASS ALL OCBS? ; MF207 BCS 5$ ;IF CS YES ;MSH185 ASR R2 ;PASS OLDEST OCB? ;MSH185 BCC 10$ ;IF CC NO, PASS SPECIFIC OCB ;MSH185 MOV (R3),-(SP) ;PARENT NAME SPECIFIED, OR ;MSH185 BIS 4(R3),(SP)+ ;AN OCB ID (ADDRESS)? ;MSH185 BNE 120$ ;IF NE YES, ILLEGAL COMBINATION ;MSH185 MOV $TKTCB,R2 ;GET CURRENT TASK'S TCB ADDRESS ;MSH185 MOV T.OCBH(R2),$TEMP1 ;INDICATE WHICH OCB TO PASS ;MSH185 JMP (R4) ;RETURN ;MSH185 ;MSH185 5$: ; ;MSH185 ; MF207 .IF DF A$$CLI ; MF207 ; MF207 MOV $TEMP0,R2 ;POINT TO OBJECT TASK ; MF207 BIT #T3.CLI,T.ST3(R2) ;IS OBJECT TASK A CLI ; MF207 BNE 100$ ;IF NE YES, ILLEGAL ; MF207 ; MF207 .IFTF ; MF207 ; MF207 MOV (R3),-(SP) ;WAS A PARENT NAME SUPPLIED ; MF207 BIS 4(R3),(SP)+ ;OR AN OCB ADDRESS ; MF207 BNE 120$ ;IF NE YES ; MF207 INC $TEMP1 ;INDICATE PASS ALL ; MF207 BR 70$ ;ALL DONE ; MF207 10$: MOV $TKTCB,R2 ;POINT TO CURRENT TASK'S TCB ; MF207 ADD #T.OCBH,R2 ;ITS OCB LISTHEAD ; MF207 ; MF207 .IFT ;A$$CLI ; MF207 ; MF207 BIT #T3.CLI,T.ST3-T.OCBH(R2) ;IS ISSUING TASK A CLI ; MF207 BEQ 30$  ;IF EQ NO ; MF207 TST (R3) ;WAS A SPECIFIC PARENT REQUESTED ; MF207 BNE 40$ ;IF NE YES ; MF207 TST 4(R3) ;WAS AN OCB ADDRESS SUPPLIED ; MF207 BEQ 70$ ;IF EQ NO ; MF207 20$: MOV (R2),R2 ;POINT TO THE NEXT OCB ; MF207 BEQ 110$ ;IF EQ, THERE ARE NO MORE ; MF207 CMP 4(R3),R2 ;IS THIS THE SPECIFIED OCB ; MF207 BNE 20$ ;IF NE NO ; MF207 BR 60$ ; ; MF207 ; MF207 .IFTF ; MF207 ; MF207 30$: TST 4(R3) ;WAS AN OCB ADDRESS SPECIFIED ; MF207  BNE 100$ ;IF NE YES ; MF207 TST (R3) ;WAS A SPECIFIC PARENT REQUESTED ; MF207 BEQ 70$ ;IF EQ NO ; MF207 40$: MOV (R2),R2 ;POINT TO NEXT OCB IN LIST ; MF207 BEQ 110$ ;IF EQ, THERE ARE NO MORE ; MF207 CMP O.STAT(R2),(R3) ;IS THIS THE OCB FOR THE CORRECT PARENT ; MF207 BNE 40$ ;IF NE NO ; MF207 CMP O.STAT+2(R2),2(R3) ;MAYBE?? ; MF207 BNE 40$ ;IF NE NO ; MF207 ; MF207 .IFT ;A$$CLI ; MF207 ; MF207 TST 4(R3) ;HAS OCB ADDR BEEN SPECIFIED ; MF207 BEQ 60$ ;IF EQ NO ; MF207 CMP 4(R3),R2 ;ARE THEY THE SAME ENTRIES ; MF207 BNE 120$ ;IF NE NO ; MF207 ; MF207 .ENDC ;A$$CLI ; MF207 ; MF207 ; MF207 60$: MOV R2,$TEMP1 ;SAVE ADDRESS OF OCB TO PASS ; MF207 70$: JMP (R4) ;RETURN ; MF207 ; MF207 ; ; MF207 ; ERROR HANDLING ; MF207 ; ; MF207 100$: JMP ILPARM ;THIS TASK CANNOT USE THIS PARAMETER ; MF207 110$: MOV (PC)+,R5 ;PICK UP SPECIFIED OCB DOESN'T EXIST STA; MF207 DRSTS D.RS86 ; ; MF207 BR 150$ ;RETURN ERROR STATUS ; MF207 120$: MOV (PC)+,R5 ;PICK UP NAME AND OCB ADDR DON'T MATCH S; MF207 DRSTS D.RS84 ; ; MF207 150$: JMP ERROR ;ISSUE ERROR ; MF207 ; MF207 ; MF207 ; ; MF207 ; THIS ROUTINE COPIES THE TCB OF A TASK INSTALLED WITH A NAME OF THE ; MF207 ; FORM ...XXX, LINKS IT INTO THE STD, AND SETS ITS REMOVE ON EXIT BIT. ; MF207 ; IT WILL ONLY BE CALLED IF THE SPWN$ OR RPOI$ DIRECTIVE IS ISSUED BY ; MF207 ; A CLI TASK ON A SYSTEM WITH ALTERNATE CLI SUPPORT. ; MF207 ; ; MF207 ; **** I M P O R T A N T ****** ; MF207 ; ; MF207 ; THIS ROUTINE MUST BE KEPT CURRENT WITH ALL TCB FORMAT CHANGES ; MF207 ; ; MF207 ; ; MF207 ; INPUTS: ; MF207 ; ; MF207 ; R0=ADDRESS OF NEW TCB BEING CREATED ; MF207 ; R1=ADDRESS OF TCB BEING COPIED ; MF207 ; R3=ADDRESS OF NEW TASK NAME IN DPB ; MF207 ; R5=UCB ADDRESS OF CURRENT TASK'S TI: ; MF207 ;  ; MF207 ; OUTPUTS: ; MF207 ; ; MF207 ; THE NEW TCB IS CREATED AND LINKED INTO THE STD ; MF207 ; ; MF207 ; R1, R2 AND R4 ARE MODIFIED ; MF207 ; ; MF207 ; MF207 .IF DF A$$CLI&I$$RAR&D$$YNM&C$$CKP&D$$YNC ; MF207 ; MF207 CPYTCB: MOV T.PCB(R1),R4 ;GET ADDRESS OF TASK'S PARTITION PCB ; MF207 MOV P.MAIN(R4),R4 ;LOCATE MAIN PARTITION ; MF207 MOV R0,R2 ;COPY ADDRESS OF NEW TCB ; MF207 CLR (R2)+ ;T.LNK ; MF207 MOVB T.DPRI(R1),(R2)+ ;SET TASKS PRIORITY ; MF207 CLRB (R2)+ ;T.IOC ; MF207 CLR (R2)+ ;T.CPCB ; MF207 MOV (R3),(R2)+ ;SET FIRST HALF OF T.NAM ; MF207 MOV 2(R3),(R2)+ ;SET SECOND HALF OF T.NAM ; MF207 CALL INILST ;INITIALIZE T.RCVL LISTHEAD ; MF207 CALL @(SP)+ ;T.ASTL ; MF207 CLR (R2)+ ;T.EFLG ; MF207 CLR (R2)+ ; ; MF207 MOV R5,(R2)+ ;T.UCB ; MF207 ADD #T.TCBL-10,R1 ;POINT TO T.TCBL IN SOURCE TCB ; MF207 MOV (R1),(R2)+ ;POINT TO NEXT TASK IN STD ; MF207 MOV R0,(R1)+ ;LINK NEW TCB AFTER ONE BEING COPIED ; MF207 ; ; MF207 ; THE SYSTEM CONTROLLED PARTITION CHECK MUST NOT BE DONE UNTIL ; MF207 ; THE TCB HAS BEEN LINKED INTO THE STD, SINCE THE ERROR CODE TO ; MF207 ; UNLINK IT HAS ALREADY BEEN PUSHED ONTO THE STACK ; MF207 ; ; MF207 BIT #PS.SYS,P.STAT(R4) ;IS PARTITION SYSTEM CONTROLLED ; MF207 BNE 10$ ;IF NE YES ; MF207 COM (SP)+ ;POP STACK AND SET CARRY ; MF207 RETURN ; MF207 10$: MOV #TS.EXE!TS.OUT,(R2)+ ;SET T.STAT TO NOT ACTIVE AND OUT ; MF207 TST (R1)+ ;POINT TO T.ST2 ; MF207 MOV (R1)+,(R2) ;COPY T.ST2 ; MF207 BIC #^C,(R2)+ ;CLEAR ALL BITS EXCEPT T2.CHK ; MF207 MOV (R1)+,(R2) ;COPY T.ST3 ; MF207 BIC #^C,(R2)+ ;CLEAR BIT; MF207 MOV (R1)+,(R2)+ ;T.DPRI AND T.LBN ; MF207 MOV (R1)+,(R2)+ ;T.LBN (3 BYTE FIELD) ; MF207 MOV (R1)+,(R2)+ ;T.LDV ; MF207 MOV R4,(R2)+ ;T.PCB ; MF207 TST (R1)+ ; ; MF207 MOV (R1)+,(R2)+ ;T.MXSZ ; MF207 CLR (R2)+ ;T.ACTL ; MF207 CLR (R2)+ ;T.SAST ; MF207 CLR (R2)+ ;T.TIO ; MF207 ADD #T.TKSZ-T.ACTL,R1 ;POINT TO T.TKSZ ; MF207 MOV (R1)+,(R2)+ ;T.TKSZ ; MF207 ; MF207 ; MF207 .IF DF P$$LAS ; MF207 ; MF207 CALL @(SP)+ ;T.ATT ; MF207 MOV (R1)+,(R2)+ ;T.OFF ; MF207 CLR (R2)+ ;T.SRCT ; MF207 TST (R1)+ ; ; MF207 CALL @(SP)+ ;T.RRFL ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 CALL @(SP)+ ;T.OCBH ; MF207 TST (R1)+ ; ; MF207 CLR (R2)+ ;T.RDCT ; MF207 ; MF207 ; MF207 .IF DF S$$TOP!T$$BUF ; MF207 ; MF207 CMP (R2)+,(R2)+ ;T.EFLM ; MF207 CMP (R1)+,(R1)+ ; ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 .IF DF A$$HDR ; MF207 ; MF207 MOVB (R1)+,(R2)+ ;T.HDLN ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 .IF DF R$$SND&G$$EFN!A$$CLI&G$$EFN ;MSH190 ; MF207 CLRB (R2)+ ;T.GGF ; MF207 ; MF207 .ENDC ; MF207 ; MF207 ; MF207 CLR (SP)+ ;POP COROUTINE ADDRESS AND CLEAR CARRY ; MF207 RETURN ; MF207 ; MF207 ; ; MF207 ; COROUTINE TO INIT STANDARD DOUBLE WORD LISTHEAD TO EMPTY ; MF207 ; ; MF207 INILST: MOV R2,2(R2) ;SET SECOND WORD TO POINT TO FIRST ; MF207 CLR (R2)+ ;CLEAR FIRST WORD ; MF207 TST (R2)+ ;POINT TO NEXT WORD AFTER LISTHEAD ; MF207 CMP (R1)+,(R1)+ ;SKIP OVER LISTHEAD IN PROTO TCB ; MF207 CALL @(SP)+ ;CALL CALLER BACK ; MF207 BR INILST ; ; MF207 ; MF207 ; ; MF207 ; ROUTINE TO UNLINK THE TCB JUST CREATED FROM THE STD IN THE EVENT ; MF207 ; OF AN ERROR LATER IN THE DIRECTIVE PROCESSING. THIS ROUTINE IS ; MF207 ; CALLED OUT OF THE ERROR THREADING MECHINISM ; MF207 ; ; MF207 ; MF207 UNLTCB: MOV T.TCBL(R0),T.TCBL(R1) ;UNLINK THE NEW TCB ; MF207 RETURN ; MF20ª7 ; MF207 .ENDC ;A$$CLI&I$$RAR&D$$YNM&C$$CKP&D$$YNC ; MF207 ; MF207 .ENDC ;R$$POI ; MF207 ; MF207 .ENDC ;P$$OFF .END ªãƒÈ_kQ ›c, .IIF DF M$$MGE!U$$DCM .TITLE UDCOM .IIF NDF M$$MGE&U$$DCM .TITLE UDCDF .IDENT /01/ ; ; COPYRIGHT (C) 1974, 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE ; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ; ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE ; MADE AVAILABLE TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH ; SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE ; TO AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN ; IN DEC. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ; ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; VERSION 01 ; ; C. MONIA 17-JUL-74 ; ; ALLOCATE UDC COMMON BLOCK AND DEFINE OFFSETS FOR MODULE TYPES ; ; LOCAL MACROS ; ; DEFINE STORAGE AND OFFSETS FOR UDC-11 MODULES ; ; DFUDC TYP ; ; WHERE: ; ; TYP = GENERIC MODULE TYPE. ONE OF THE FOLLOWING ; RECOGNIZED: ; ; 'ADM' - ADU01 A/D CONVERTER ; 'AOM' - ANALOG OUTPUT MODULE ; 'CIM' - CONTACT INTERRUPT MODULE ; 'CSM' - CONTACT SENSE MODULE ; 'LTM' - LATCHING MODULE ; 'SSM' - SINGLE SHOT DIGITAL OUTPUT ; 'TIM' - TIMER MODULE ; ; THE SYMBOL "U$$'TYP", IF DEFINED, ENCODES THE FOLLOWING ; INFORMATION: ; ; BITS 15 - 8 = NUMBER OF MODULES ; BITS 7 - 0 = RELATIVE MODULE NUMBER ; ; THIS MACRO GENERATES GLOBAL CONSTANTS OF THE FOLLWING FORMS ; FOR EACH GENERIC MODULE TYPE: ; ; $.'TYP = STARTING ADDRESS OF MODULE TYPE ; M$.'TYP = HIGHEST RELATIVE MODULE NUMBER ; P$.'TYP = HIGHEST ALLOWABLE POINT NUMBER ; .MACRO DFUDC TYP .IF DF U$$'TYP ...PC=*2 .=UDCBA .BLKB ...PC ...SIZ=&377 $.'TYP:: .BLKW ...SIZ M$.'TYP==<...SIZ>-1 P$.'TYP==<...SIZ*16.>-1 .ENDC .ENDM ;+ ; **-UDCOM-MODULE TO ALLOCATE UDC-11 COMMON BLOCK STORAGE, DEFINE UDC ; MODULE OFFSETS. ; ; THIS MODULE, WHEN ASSEMBLED WITH PREFIX FILE RSXMC.MAC, WILL: ; ; (1) GENERATE SYMBOLIC ADDRESSES AND LENGTHS FOR GENERIC ; UDC MODULE TYPES ; ; (2) IF 'M$$MGE' OR 'U$$DCM' IS DEFINED ALLOCATE STORAGE FOR ; THE UDC GLOBAL COMMON BLOCK ; ; THE GLOBAL COMMON AREA RESIDES IN A RELOCATABLE PROGRAM SECTION ; NAMED 'UDCOM' HAVING '.CSECT' ATTRIBUTES (IE. 'GBL', 'OVR', 'I'). IN ; THIS CASE THE SYMBOLIC OFFSETS ARE RELOCATABLE. THE NAMED ; SECTION MAY BE REFERENCED DIRECTLY BY THE FORTRAN PROGRAM. ; ; IF THE COMMON AREA IS NOT TO BE GENERATED . THEN ; THE OFFSETS ARE ABSOLUTE LOCATIONS ON THE EXTERNAL PAGE. IN THIS CASE ; DIRECT FORTRAN ACCESS IS NOT POSSIBLE. ; ; THE VARIABLE 'M$$MGE' IS DEFINED IN 'RSXMC.MAC' IF MEMORY MANAGE- ; MENT IS PRESENT. ; ; ;- .IF DF M$$MGE!U$$DCM .PSECT UDCOM,GBL,D,OVR .IFF .PSECT $$UDAB,ABS .BLKB 171000 .ENDC UDCBA=. ; REF LABEL DFUDC dADM ; DEFINE ANALOG INPUT CONFIGURATION DFUDC AOM ; DEFINE ANALOG OUTPUT CONFIGURATION DFUDC CIM ; DEFINE CONTACT INTERRUPT CONFIGURATION DFUDC CSM ; DEFINE CONTACT SENSE CONFIGURATION DFUDC LTM ; DEFINE LATCHING MODULE CONFIGURATION DFUDC SSM ; DEFINE SINGLE SHOT CONFIGURATION DFUDC TIM ; DEFINE TIMER MODULE CONFIGURATION .END däƒðskQ ›c, .TITLE UDDRV .IDENT /07/ ; ; COPYRIGHT (C) 1974, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 07 ; ; D. N. CUTLER 20-FEB-74 ; ; PREVIOUSLY MODIFIED BY: ; ; D. N. CUTLER ; T. J. MILLER ; C. A. MONIA ; ; MODIFIED BY: ; ; C. A. MONIA 03-MAR-77 ; ; CM085 -- CLEAR OUT SCAN ERROR INDICATIONS CORRECTLY ; ; UDC11 UNIVERSAL DIGITAL INPUT/OUTPUT CONTROLLER ; ; NOTE: THIS IS A SINGLE CONTROLLER DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,TCBDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ; ; EQUATED SYMBOLS ; ; UDC11 HARDWARE REGISTER DEFINITIONS ; UDCR=171776 ;ADDRESS OF UDC11 CSR UDSR=171774 ;ADDRESS OF UDC11 SCAN REGISTER UDMD=171000 ;ADDRESS OF FIRST FUNCTIONAL MODULE ; ; MODULE TABLE AND INTERUPT CONTROL BLOCK OFFSET DEFINITIONS ; MDCNT=0 ;NUMBER OF POINTS OR MODULES MDBAS=2 ;ADDRESS IN I/O PAGE OF FIRST MODULE NMBYT=4 ;NUMBER OF BYTES OF INTERRUPT DATA STATS=5 ;FORK STATUS BYTE (0=FORK IN PROGRESS) STRBF=6 ;STARTING BUFFER RELOCATION BIAS CURBF=10 ;CURRENT BUFFER RELOCATION BIAS BUFAD=12 ;ADDRESS OF START OF BUFFER CURNX=20 ;CURRENT FORTRAN BUFFER FILL INDEX BFLGH=22 ;LENGTH OF BUFFER IN WORDS EFNMK=24 ;EVENT FLAG MASK WORD EFNAD=26 ;EVENT FLAG MASK ADDRESS LSCNT=30 ;LOST DATA COUNT CONTK=32 ;TCB ADDRESS OF CONNECTED TASK FRBLK=34 ;INTERRUPT FORK BLOCK (3 WORDS) ; ; LOCAL DATA ; ; UDC11 UCB ADDRESS ; UDUCB: .BLKW 1 ;SAVED UCB ADDRESS ; ; A/D MODULE TABLE ; .IF DF U$$ADM ADTBL: .WORD <&377>*U$$ACH ;NUMBER OF A/D CHANNELS .WORD UDMD+<*2> ;ADDRESS OF BASE MODULE ADMOD: .BLKW 1 ;INTERRUPT MODULE ADDRESS .ENDC ; ; CONTACT INTERRUPT MODULE TABLE, INTERRUPT CONTROL BLOCK, AND PREVIOUS STATE TA ; ; .IF DF U$$CIM CITBL: .WORD <&377>*16. ;NUMBER OF CONTACT INTERRUPT POINTS .WORD UDMD+<*2> ;ADDRESS OF BASE MODULE .WORD 5*2 ;NUMBER OF BYTES OF INTERRUPT DATA .BLKB FRBLK+4-NMBYT ;INTERRUPT CONTROL BLOCK CIPRV: .BLKW &377 ;CONTACT POINT PREVIOUS STATE TABLE .ENDC ; ; LATCHING OUTPUT MODULE TABLE ; .IF DF U$$LTM LTTBL: .WORD <&377>*16. ;NUMBER OF LATCHING OUTPUT POINTS .WORD UDMD+<*2> ;ADDRESS OF BASE MODULE LTPRV: .BLKW &377 ;LATCHING OUTPUT PREVIOUS STATE TABLE .ENDC ; ; TIMER INTERRUPT MODULE TABLE, INTERRUPT CONTROL BLOCK, AND INITIAL VALUE TABLE ; .IF DF U$$TIM TMTBL: .WORD <&377> ;NUMBER OF TIMER INTERRUPT MODULES .WORD UDMD+<*2> ;ADDRESS OF BASE MODULE .WORD 4*2 ;NUMBER OF BYTES OF INTERRUPT DATA .BLKB FRBLK+4-NMBYT ;INTERRUPT CONTROL BLOCK TMINI: .BLKW <&377> ;INITIAL TIMER VALUE TABLE .ENDC ; ; DRIVER DISPATCH TABLE ; $UDTBL::.WORD UDCHK ;DEVICE INITIATOR ENTRY POINT .WORD UDCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD UDOUT ;DEVICE TIMEOUT ENTRY POINT .WORD UDPWF ;POWERFAIL ENTRY POINT ;+ ; **-UDCHK-UDC11 UNIVERSAL DIGITAL INPUT/OUTPUT CONTROLLER PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS RECEIVED FOR THE UDC11 UNIVERSAL DIGIT INPUT/OUTPUT ; CONTROLLER. UDC11 I/O REQUESTS CONTAIN DEVICE DEPENDENT INFORMA- ; ATION THAT MUST BE CHECKED IN THE CONTEXT OF THE ISSUING TASK. ; THEREFORE THE I/O REQUEST IS NOT QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; DEPENDENT UPON FUNCTION TO BE PERFORMED. ; ; UDC11 FUNCTION INDEPENDENT I/O PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE . ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ;- UDCHK: MOV R1,-(SP) ;SAVE I/O PACKET ADDRESS MOV I.TCB(R1),R0 ;GET TCB ADDRESS OF REQUESTER TASK MOVB I.FCN+1(R1),R2 ;GET I/O FUNCTION CODE ADD #I.PRM,R1 ;POINT TO FIRST I/O PARAMETER .IF DF U$$CIM MOV #CITBL,R3 ;ASSUME CONTACT INTERRUPT FUNCTION CMPB #IO.CCI/256.,R2 ;CONNECT CONTACT INTERRUPTS? BEQ UDCNT ;IF EQ YES CMPB #IO.DCI/256.,R2 ;DISCONNECT CONTACT INTERRUPTS? BEQ UDDIS ;IF EQ YES .ENDC .IF DF U$$TIM MOV #TMTBL,R3 ;ASSUME TIMER FUNCTION CMPB #IO.CTI/256.,R2 ;CONNECT TIMER INTERRUPTS? BEQ UDCNT ;IF EQ YES CMPB #IO.DTI/256.,R2 ;DISCONNECT TIMER INTERRUPTS? BEQ UDDIS ;IF EQ YES CMPB #IO.ITI/256.,R2 ;INITIALIZE TIMER MODULE? BEQ UDITM ;IF EQ YES .ENDC .IF DF U$$LTM CMPB #IO.MLO/256.,R2 ;MULTILATCHING DIGITAL OUTPUT? BEQ UDLTM ;IF EQ YES .ENDC .IF DF U$$ADM CMPB #IO.RBC/256.,R2 ;READ BUFFERED A/D MODULES? .IFTF BNE UDIFC ;IF NE NO ILLEGAL FUNCTION .IFT JMP UDRAD ; .ENDC ;+ ; **-UDCNT-CONNECT TASK TO INTERRUPTS ; ; FUNCTION DEPENDENT I/O REQUEST PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER. ; WD. 15 -- TRIGGER EVENT FLAG NUMBER. ; WD. 16 -- INITIAL TIMER BUFFER (IO.CTI ONLY). ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .IF DF U$$CIM!U$$TIM UDCNT: BIT #T2.CHK!T2.FXD,T.ST2(R0) ;TASK FXD OR NOT CHKPOINTABLE? BEQ UDPRI ;IF EQ NO TST CONTK(R3) ;ANOTHER TASK ALREADY CONNECTED? BNE UDCON ;IF NE YES CMP (R1)+,(R1)+ ;POINT TO DATA BUFFER SIZE MOVB NMBYT(R3),R0 ;GET NUMBER OF BYTES OF INTERRUPT DATA CMP (R0)+,(R0)+ ;ADJUST FOR BUFFER HEADER CMP (R1)+,R0 ;BUFFER BIG ENOUGH? BLO UDSPC ;IF LO NO MOV (R1)+,R0 ;GET EVENT FLAG NUMBER BEQ UDIEF ;IF EQ NO EVENT FLAG SPECIFIED CMP R0,#64. ;LEGAL EVENT FLAG NUMBER? BHI UDIEF ;IF HI NO .IF DF U$$TIM CMP #TMTBL,R3 ;TIMER CONNECT? BNE 20$ ;IF NE NO MOV (R1),R0 ;GET ADDRESS OF INITIAL VALUE BUFFER MOV (R3)+,R4 ;GET NUMBER OF TIMER MODULES .IF DF A$$CHK!M$$MGE MOV R4,R1 ;SET NUMBER OF TIMER MODULES ASL R1 ;CONVERT TO BYTE COUNT CALL $ACHCK ;ADDRESS CHECK INITIAL VALUE BUFFER BCS UDSPC ;IF CS ILLEGAL BUFFER .ENDC .IF DF M$$MGE CALL $RELOM ;RELOCATE AND MAP TO INITIAL VALUE BUFFER .ENDC BIC #36,UDCR ;DISABLE UDC INTERRUPTS MOV (R3),R1 ;GET ADDRESS OF FIRST TIMER MODULE MOV #TMINI,R2 ;GET ADDRESS OF INITIAL VALUE TABLE 10$: MOV (R0)+,(R2) ;SET VALUE IN INITIAL VALUE TABLE BIS #1,UDCR ;SET RIF BIT MOV (R2)+,(R1)+ ;SET COUNTER VALUE AND RESET MODULE BIC #1,UDCR ;CLEAR RIF BIT DEC R4 ;ANY MORE INITIALIZE? BGT 10$ ;IF GT YES TST -(R3) ;POINT TO MODULE COUNT .IFTF 20$: MOV (SP),R4 ;RETRIEVE ADDRESS OF I/O PACKET MOV R5,-(SP) ;SAVE ADDRESS OF UCB MOV I.TCB(R4),R5 ;GET REQUESTER TASK TCB ADDRESS ADD #I.PRM,R4 ;POINT TO FIRST I/O PARAMETER ADD #NMBYT,R3 ;POINT TO NUMBER OF BYTES OF INT DATA MOVB (R3)+,(R3)+ ;SET FORK NOT IN PROGRESS MOV (R4)+,(R3) ;INSERT STARTING BUFFER RELOCATION BIAS MOV (R3)+,(R3)+ ;COPY STARTING BUFFER RELOCATION BIAS MOV (R4)+,(R3) ;INSERT STARTING BUFFER ADDRESS MOV (R3)+,(R3) ;COPY STARTING BUFFER ADDRESS ADD #4,(R3) ;CALCULATE ADDRESS OF FIRST DATA WORD MOV (R3)+,(R3)+ ;COPY ADDRESS OF FIRST DATA WORD MOV #3,(R3)+ ;SET CURRENT FORTRAN INDEX MOV (R4)+,(R3) ;GET SIZE OF BUFFER IN BYTES ROR (R3)+ ;CONVERT TO SIZE IN WORDS MOV (R4),R0 ;GET EVENT FLAG NUMBER CALL $CEFI ;CONVERT TO MASK AND MASK ADDRESS MOV R0,(R3)+ ;INSERT EVENT FLAG MASK MOV R1,(R3)+ ;INSERT EVENT FLAG MASK ADDRESS BIC R0,(R1) ;CLEAR EVENT FLAG CLR (R3)+ ;CLEAR LOST DATA COUNT MOV R5,(R3)+ ;CONNECT TASK TO INTERRUPTS INCB T.IOC(R5) ;BIAS TASK'S OUTSTANDING I/O COUNT .IF DF D$$SHF MOV T.PCB(R5),R1 ;GET ADDRESS OF TASK PCB BIS #PS.NSF,P.STAT(R1) ;DISABLE TASK SHUFFLING .ENDC MOV (SP)+,R5 ;RETRIEVE ADDRESS OF UCB MOVB NMBYT-FRBLK(R3),R1 ;GET NUMBER OF BYTES OF INTERRUPT DATA ASR R1 ;CONVERT TO WORD COUNT DEC R1 ;ADJUST FOR EXISTANCE INDICATOR BIS #3*256.,R1 ;INSERT INITIAL FORTRAN INDEX .IFT BIS #36,UDCR ;ENABLE UDC INTERRUPTS .ENDC BR UDSUC1 ; .ENDC .IF DF U$$LTM UDLTM: BR UDLAT ;MULTILATCHING OUTPUT .ENDC ;+ ; **-UDDIS-DISCONNECT TASK FROM INTERRUPTS ; ; FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- NOT USED. ; WD. 13 -- NOT USED. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .IF DF U$$CIM!U$$TIM UDDIS: CALL UDCAN1 ;DISCONNECT TASK FROM INTERRUPTS BCC UDSUC ;IF CC OKAY ; ; ILLEGAL CONNECT/DISCONNECT TO/FROM INTERRUPTS ; UDCON: MOV #IE.CON&377,R0 ;SET ILLEGAL CONNECT/DISCONNECT STATUS BR UDCMN ; ; ; ILLEGAL EVENT FLAG NUMBER ; UDIEF: MOV #IE.IEF&377,R0 ;SET ILLEGAL EVENT FLAG STATUS BR UDCMN ; ; ; PRIVILEGE VIOLATION ; UDPRI: MOV #IE.PRI&377,R0 ;SET PRIVILEGE VIOLATION STATUS BR UDCMN ; .ENDC ; ; ILLEGAL FUNCTION ; UDIFC: MOV #IE.IFC&377,R0 ;SET ILLEGAL FUNCTION STATUS BR UDCMN ; ; ; ILLEGAL BUFFER SPECIFICATION ; .IF DF U$$ADM!U$$CIM!U$$TIM UDSPC: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS BR UDCMN ; .ENDC ;+ ; **-UDITM-INITIALIZE TIMER VALUE ; ; FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- RELATIVE MODULE NUMBER. ; WD. 13 -- NEW TIMER VALUE. ; WD. 14 -- NOT USED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .IF DF U$$TIM UDITM: CMP R0,CONTK(R3) ;CURRENT TASK CONNECTED TO TIMER INTERRUPTS? BNE UDIFC ;IF NE NO MOV (R1)+,R2 ;GET RELATIVE MODULE NUMBER CMP R2,(R3)+ ;LEGAL TIMER MODULE? BHIS UDMOD ;IF HIS NO ASL R2 ;CONVERT TO WORD INDEX MOV (R1),TMINI(R2) ;SET NEW TIMER PRESET VALUE ADD (R3),R2 ;CALCULATE ADDRESS OF TIMER MODULE MOVB #PR6,PS ;;;LOCKOUT DEVICE INTERRUPTS BIS #1,UDCR ;;;SET RIF BIT MOV (R1),(R2) ;;;SET TIMER VALUE AND RESET MODULE BIC #1,UDCR ;;;RESET RIF BIT CLRB PS ;;;ALLOW DEVICE INTERRUPTS BR UDSUC ; .ENDC ;+ ; **-UDLAT-MULTIPLE LATCHING OUTPUT ; ; FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- STARTING RELATIVE RELAY POINT NUMBER. ; WD. 13 -- DATA MASK WORD. ; WD. 14 -- DATA VALUE. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .IF DF U$$LTM UDLAT: MOV (R1)+,R0 ;GET STARTING RELATIVE RELAY POINT NUMBER CMP R0,LTTBL+MDCNT ;LEGAL STARTING POINT NUMBER? BHIS UDMOD ;IF HIS NO BIT #17,R0 ;ALL POINTS WITHIN ONE MODULE? BNE UDMOD ;IF NE NO ASR R0 ;CONVERT STARTING POINT NUMBER TO ASR R0 ;RELATIVE INDEX ASR R0 ; MOV LTPRV(R0),R4 ;GET LAST DATA WRITTEN BIC (R1),R4 ;CLEAR BITS TO BE WRITTEN COM (R1) ;COMPLEMENT MASK WORD BIC (R1)+,(R1) ;CLEAR EXTRANEOUS BITS IN DATA WORD BIS (R1),R4 ;MERGE NEW DATA WITH LAST WRITTEN MOV R4,LTPRV(R0) ;SAVE RESULT AS LAST DATA WRITTEN ADD LTTBL+MDBAS,R0 ;CALCULATE ADDRESS OF OUTPUT MODULE MOV R4,(R0) ;OUTPUT NEW VALUE .ENDC ; ; SUCCESSFUL COMPLETION ; UDSUC: CLR R1 ;CLEAR SECOND I/O STATUS WORD UDSUC1: MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS BR UDCMN1 ; ; ; BAD MODULE NUMBER ; .IF DF U$$LTM!U$$TIM UDMOD: MOV #IE.MOD&377,R0 ;SET BAD MODULE NUMBER STATUS .ENDC ; ; COMMON FUNCTION EXIT ; UDCMN: CLR R1 ;CLEAR SECOND I/O STATUS WORD UDCMN1: MOV (SP)+,R3 ;RETRIEVE I/O PACKET ADDRESS CALLR $IOFIN ;FINISH I/O OPERATION ;+ ; **-UDRAD-READ A/D CHANNELS ; ; FUNCTION DEPENDENT I/O PACKET FORMAT: ; ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER. ; WD. 15 -- CONTROL BUFFER ADDRESS. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .IF DF U$$ADM UDRAD: MOV 6(R1),R0 ;GET VIRTUAL ADDRESS OF CONTROL BUFFER .IF DF A$$CHK!M$$MGE MOV 4(R1),R1 ;SET LENGTH OF BUFFER TO CHECK CALL $ACHCK ;ADDRESS CHECK CONTROL BUFFER BCS UDSPC ;IF CS ADDRESS CHECK FAILURE .ENDC  MOV (SP)+,R3 ;RETRIEVE ADDRESS OF I/O PACKET CALL $RELOC ;RELOCATE CONTROL BUFFER ADDRESS MOV R1,I.PRM+6(R3) ;SET RELOCATION BIAS OF CONTROL BUFFER MOV R2,I.PRM+10(R3) ;SET ADDRESS OF CONTROL BUFFER MOV R3,R1 ;SET ADDRESS OF I/O PACKET MOV R4,R0 ;SET ADDRESS OF I/O LISTHEAD CALL $QINSP ;INSERT I/O PACKET IN REQUEST QUEUE ;+ ; **-UNINI-UDC11 ANALOG TO DIGITAL CONVERSION INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS EXE- ; CUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPERATION ; IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUET IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ;- .ENABL LSB UDINI: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 20$ ;IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE UDC11 CONTROLLER. ; ; UDC11 A/D CONVERSION I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RBC). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER. ; WD. 13 -- DATA BUFFER ADDRESS. ; WD. 14 -- NUMBER OF BYTES IN DATA BUFFER. ; WD. 15 -- RELOCATION BIAS OF CONTROL BUFFER. ; WD. 16 -- CONTROL BUFFER ADDRESS. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; ; THE DATA BUFFER RECEIVES CONVERTED VALUES AND THE CONTROL BUFFER CONTAINS ; CONTROL WORDS THAT CONTROL THE CONVERSION PROCESS. EACH WORD IN THE CONTROL ; BUFFER HAS THE FORMAT: ; ; BITS 15-12 -- GAIN CODE. ; ; LEGAL GAIN CODES ARE: ; ; 0000=GAIN OF 1. ; 0001=GAIN OF 2. ; 0100=GAIN OF 10. ; 0101=GAIN OF 20. ; 1000=GAIN OF 50. ; 1001=GAIN OF 100. ; 1100=GAIN OF 200. ; 1101=GAIN OF 1000. ; ; BITS 11-0 -- CHANNEL NUMBER. ; ; EACH UDC11 MAY HAVE 2016. CHANNELS. THE LEGALITY OF ; A PARTICULAR CHANNEL NUMBER IS DETERMINED BY THE A/D ; MODULE TABLE DISCRIPTOR. ; ; EACH CHANNEL IS CONVERTED ACCORDING TO THE CORRESPONDING WORD IN THE CONTROL ; BUFFER AND THE RESULTANT VALUE IS PLACED IN THE DATA BUFFER. IF AN ILLEGAL ; CONTROL WORD IS DETECTED THEN THE CONVERSION PROCESS IS TERMINATED. THE SECOND ; I/O STATUS WORD SPECIFIES THE NUMBER OF CHANNELS THAT WERE CONVERTED. ;- MOV I.PRM+6(R1),U.CBF(R5) ;SET RELOCATION BIAS OF CONTROL BUFFER MOV I.PRM+10(R1),U.CBF+2(R5) ;SET ADDRESS OF CONTROL BUFFER ; ; INITIATE I/O OPERATION ; 10$: CALL $GTCWD ;GET NEXT WORD FROM CONTROL BUFFER MOV #IE.BAD&377,R0 ;ASSUME ILLEGAL GAIN OR CHANNEL MOV (SP)+,R1 ;RETRIEVE CONTROL WORD MOV R1,R2 ;COPY CONTROL WORD BIC #170000,R1 ;CLEAR GAIN CODE BITS CMP R1,ADTBL+MDCNT ;LEGAL CHANNEL NUMBER? BHIS 30$ ;IF HIS NO BIC R1,R2 ;CLEAR CHANNEL NUMBER BITS ASL R2 ;ISOLATE GAIN CODE BY DROPPING BIT 13 ROL R2 ; ROL R2 ; BCS 30$ ;IF CS ILLEGAL GAIN CODE ASRB R2 ;DROP BIT 13 ROR R2 ;SHIFT BITS 15 AND 14 BACK INTO PLACE ROR R2 ; SEC ;SET CARRY ROR R2 ;SHIFT CARRY INTO START CONVERSION MOV R1,R0 ;COPY CHANNEL NUMBER .IF EQ U$$ACH-8. ASR R0 ;ISOLATE AND MERGE CHANNEL NUMBER RORB R2 ;WITH GAIN CODE ASR R0 ; RORB R2 ; ASR R0 ; RORB R2 ; RORB R2 ;SHIFT CHANNEL NUMBER INTO POSITION .IFF MOV #U$$ACH,R1 ;GET NUMBER OF CHANNELS PER MODULE CALL $DIV ;CALCULATE MODULE AND CHANNEL NUMBER ADD #8.,R1 ;BIAS CHANNEL NUMBER BY 8. ASL R1 ;SHIFT CHANNEL NUMBER INTO POSITION ASL R1 ; ASL R1 ; ASL R1 ; BIS R1,R2 ;MERGE CHANNEL NUMBER WITH GAIN CODE ASL R0 ;CONVERT TO IAD-IA MODULE INDEX ASL R0 ; ASL R0 ; .ENDC  ASL R0 ;CONVERT MODULE NUMBER TO WORD INDEX ADD ADTBL+MDBAS,R0 ;CALCULATE ADDRESS OF A/D MODULE MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT COUNT MOV R0,ADMOD ;SAVE ADDRESS OF A/D MODULE MOV R2,(R0) ;START CONVERSION 20$: RETURN ; ;+ ; **-UDADI-UDC11 ANALOG TO DIGITAL CONVERSION INTERRUPT ;- UDADI: TST (SP)+ ;;;REMOVE GENERIC CODE FROM STACK MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; CMP R5,ADMOD ;;;CORRECT MODULE INTERRUPT? BNE 40$ ;;;IF NE NO CLR ADMOD ;;;CLEAR A/D MODULE ADDRESS MOV UDUCB,R5 ;;;RETRIEVE ADDRESS OF UCB CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV R4,-(SP) ;SET CONVERTED DIGITAL VALUE MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB CALL $PTWRD ;PUT CONVERTED VALUE IN DATA BUFFER SUB #2,U.CNT(R5) ;ANY MORE TO CONVERT? BGT 10$ ;IF GT YES MOV #IS.SUC&377,R0 ; ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED WITH A FINAL ; I/O STATUS OF DEVICE NOT READY, THE SECOND I/O STATUS WORD CONTAINS THE NUM- ; BER OF CHANNELS THAT WERE SAMPLED BEFORE THE TIMEOUT OCCURRED. TIMEOUTS ARE ; USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE RESULT OF A HARDWARE ; FAILURE. ; .IFTF UDOUT: ;;;REF LABEL .IFT CLR ADMOD ;;;CLEAR A/D MODULE ADDRESS CLRB PS ;;;ALLOW DEVICE INTERRUPTS 30$: MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV I.PRM+4(R3),R1 ;GET SIZE OF ORIGINAL BUFFER SUB U.CNT(R5),R1 ;CALCULATE NUMBER OF BYTES PROCESSED ROR R1 ;CONVERT TO NUMBER OF SAMPLES PROCESSED CALL $IODON ;FINISH I/O OPERATION BR UDINI ; 40$: JMP $INTXT ;;;EXIT FROM INTERRUPT .DSABL LSB .ENDC ; ; CANCEL I/O OPERATION ; ; THIS ROUTINE IS CALLED TO CANCEL ALL I/O IN PROGRESS FOR THE CURRENT ; TASK. IF THE TASK IS CONNECTED TO EITHER CONTACT OR TIMER INTERRUPTS, THEN ; IT IS DISCONNECTED. ALL A/D INPUT IS ALLOWED TO COMPLETE SINCE IT WILL ; DO SO WITHIN A REASONABLE AMOUNT OF TIME. ; UDCAN: ;;;REF LABEL .IF DF U$$CIM!U$$TIM MOV R1,R0 ;;;SET TCB ADDRESS OF CURRENT TASK .IF DF U$$CIM MOV #CITBL,R3 ;;;POINT TO CONTACT INTERRUPT TABLE .ENDC .IF DF U$$CIM&U$$TIM CALL UDCAN1 ;;;DISCONNECT CONTACT INTERRUPTS .ENDC .IF DF U$$TIM MOV #TMTBL,R3 ;;;POINT TO TIMER INTERRUPT TABLE .ENDC UDCAN1: CMP R0,CONTK(R3) ;;;CURRENT TASK CONNECTED? SEC ;;;ASSUME NO BNE 10$ ;;;IF NE NO CLR CONTK(R3) ;;;DISCONNECT TASK CLR EFNMK(R3) ;;;CLEAR EVENT FLAG WORD IN CASE A CLR EFNAD(R3) ;;;FORK IS ALREADY QUEUED DECB T.IOC(R0) ;;;DECREMENT OUTSTANDING I/O COUNT .IF DF D$$SHF MOV T.PCB(R0),R1 ;;;GET ADDRESS OF TASK PCB BIC #PS.NSF,P.STAT(R1) ;;;ENABLE TASK SHUFFLING .ENDC .ENDC 10$: RETURN ;;; ; ; POWERFAILURE IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE ; CAUSES NO IMMEDIATE ACTION ON THE DEVICE. THE UDC11 UNIT CONTROL BLOCK ; ADDRESS IS STORED AND UDC11 INTERRUPTS ARE ENABLED. ; UDPWF: MOV R5,UDUCB ;SAVE ADDRESS OF UDC11 UCB .IF DF U$$ADM!U$$CIM!U$$TIM MOV #36,@S.CSR(R4) ;INITIALIZE UDC11 INTERRUPTS .IF DF U$$TIM MOV #&377,R0 ;GET NUMBER OF TIMER MODULES MOV TMTBL+2,R1 ;GET ADDRESS OF FIRST TIMER MODULE MOV #TMINI,R2 ;GET ADDRESS OF INITIAL VALUE TABLE 10$: MOV (R2)+,(R1)+ ;SET INITIAL TIMER VALUE DEC R0 ;ANY MORE TIMERS TO SET? BGT 10$ ;IF GT YES .ENDC .ENDC .IF DF U$$LTM MOV #&377,R0 ;GET NUMBER OF LATCHING MODULES MOV LTTBL+2,R1 ;GET ADDRESS OF FIRST LATCHING MODULE MOV #LTPRV,R2 ;GET ADDRESS OF PREVIOUS STATE TABLE 20$: MOV (R2)+,(R1)+ ;RELOAD LATCHING OUTPUT MODULES DEC R0 ;ANY MORE TO LOAD? BGT 20$ ;IF GT YES .ENDC 30$: RETURN ; ;+ ; **-$UDINT-UDC11 UNIVERSAL DIGITAL INPUT/OUTPUT CONTROLLER INTERRUPTS ;- $UDINT::CALL $INTSV,PR6 ;;;SAVE REGISTERS AND SET PRIORITY .IF DF U$$ADM!U$$CIM!U$$TIM MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; MOV #UDCR,R3 ;;;GET ADDRESS OF CSR BIT #140000,(R3) ;;;ANY ERRORS? BNE 60$ ;;;IF NE YES TSTB (R3) ;;;IMMEDIATE SCAN DONE? BMI 10$ ;;;IF MI YES MOV -(R3),R2 ;;;READ SCAN REGISTER BMI 50$ ;;;IF MI SCAN DISPLACED BR 20$ ;;; 10$: MOV -(R3),R2 ;;;READ SCAN REGISTER 20$: TST (R3)+ ;;;POINT BACK TO CSR CLR R5 ;;;PICKUP INTERRUPTING MODULE NUMBER BISB R2,R5 ;;; ASL R5 ;;;CALCULATE ADDRESS OF INTERRUPTING ADD #UDMD,R5 ;;;MODULE BIS #1,(R3) ;;;SET RIF BIT MOV (R5),R4 ;;;READ MODULE DATA RESETTING INTERRUPT BIC #1,(R3) ;;;RESET RIF BIT MOV R2,-(SP) ;;;COPY CONTENTS OF SCAN REGISTER SWAB (SP) ;;;SWAP GENERIC CODE TO RIGHT BYTE BIC #^C<7>,(SP) ;;;CLEAR ALL BUT GENERIC CODE .IF DF U$$ADM CMP #7,(SP) ;;;A/D MODULE? BEQ UDADI ;;;IF EQ YES .IF NDF U$$CIM&U$$TIM TST (SP)+ ;;;REMOVE GENERIC CODE FROM STACK .ENDC .ENDC .IF DF U$$CIM MOV #CITBL+2,R3 ;;;GET ADDRESS OF CONTACT TABLE .ENDC .IF DF U$$CIM&U$$TIM BIT #4,(SP) ;;;CONTACT INTERRUPT MODULE? BEQ 30$ ;;;IF EQ YES .ENDC .IF DF U$$TIM  MOV #TMTBL+2,R3 ;;;GET ADDRESS OF TIMER TABLE .ENDC 30$: ;;;REF LABEL .IF DF U$$CIM!U$$TIM SUB (R3),R5 ;;;CALCULATE RELATIVE MODULE INDEX MOV R5,-(SP) ;;;CONVERT TO RELATIVE MODULE NUMBER ASR (SP) ;;; MOV R4,-(SP) ;;;SET CURRENT MODULE DATA .IF DF U$$CIM&U$$TIM CMP #TMTBL+2,R3 ;;;TIMER MODULE? BEQ 70$ ;;;IF EQ YES .ENDC ; ; CONTACT INTERRUPT MODULE ; .IF DF U$$CIM ADD #CIPRV,R5 ;;;POINT TO PREVIOUS MODULE STATE BIC (R5),R4 ;;;.NOT.PREVIOUS.AND.CURRENT BIC (SP),(R5) ;;;.NOT.CURRENT.AND.PREVIOUS BIS (R5),R4 ;;;PREVIOUS.OR.CURRENT MOV (SP),(R5) ;;;SET PREVIOUS VALUE TO CURRENT MOV R4,-(SP) ;;;SET CHANGE OF STATE BITS MOV (R5),R4 ;;;RETRIEVE CURRENT VALUE COM R2 ;;;COMPLEMENT SCAN REGISTER BIT #60000,R2 ;;;BOTH PCL AND POP? BEQ 80$ ;;;IF EQ YES BIT #40000,R2 ;;;PCL? BNE 40$ ;;;IF NE NO COM R4 ;;;COMPLEMENT CURRENT STATE 40$: BIC R4,(SP) ;;;CLEAR UNWANTED COS BITS BNE 80$ ;;;IF NE SOME CHANGED BITS  ADD #10,SP ;;;REMOVE DATA FROM STACK .ENDC .ENDC 50$: BR 140$ ;;;TAKE COMMON EXIT 60$: MOV #37,(R3) ;;;RESET UDC CONTROLLER BIC #1,(R3) ;;;CLEAR RIF BIT BR 140$ ;;;TAKE COMMON EXIT ; ; TIMER MODULE ; .IF DF U$$CIM!U$$TIM .IF DF U$$TIM 70$: MOV R4,R2 ;;;COPY MODULE DATA ROL R2 ;;;TEST FOR OVERFLOW TO ZERO BVS 80$ ;;;IF VS NO OVERFLOW TST CONTK-2(R3) ;;;TASK CONNECTED? BEQ 80$ ;;;IF EQ NO MOV R5,R2 ;;;COPY RELATIVE INDEX ADD (R3),R5 ;;;CALCULATE ADDRESS OF TIMER MODULE MOV TMINI(R2),(R5) ;;;RELOAD TIMER MODULE .ENDC ; ; COMMON EXIT FOR CONTACT AND TIMER MODULES ; 80$: MOVB NMBYT-2(R3),R2 ;;;GET NUMBER OF BYTES OF DATA MOV #1,-(SP) ;;;SET EXISTANCE INDICATOR TST CONTK-2(R3) ;;;TASK CONNECTED? BEQ 130$ ;;;IF EQ NO .IF DF M$$MGE MOV KISAR6,R5 ;;;SAVE CURRENT MAPPING MOV CURBF-2(R3),KISAR6 ;;;MAP TO USER BUFFER .IFTF MOV CURBF+6-2(R3),R4 ;;;GET CURRENT BUFFER ADDRESS TST (R4) ;;;BUFFER ENTRY FREE? BNE 120$ ;;;IF NE NO CLR LSCNT-2(R3) ;;;CLEAR LOST DATA COUNT ASR R2 ;;;CONVERT BYTE COUNT TO WORD COUNT 90$: MOV (SP)+,(R4)+ ;;;PUT DATA IN USER BUFFER .IFT BIT #20000,R4 ;;;OVERFLOW 4K BOUNDRY? BEQ 100$ ;;;IF EQ NO BIC #20000,R4 ;;;RESET TO APR6 ADDRESS ADD #200,CURBF-2(R3) ;;;ADVANCE TO NEXT 4K BLOCK ADD #200,KISAR6 ;;;ADVANCE TO NEXT 4K BLOCK .IFTF 100$: INC CURNX-2(R3) ;;;INCREMENT FORTRAN INDEX CMP BFLGH-2(R3),CURNX-2(R3) ;;;END OF BUFFER? BHIS 110$ ;;;IF HIS NO MOV #3,CURNX-2(R3) ;;;RESET CURRENT FORTRAN INDEX .IFT MOV STRBF-2(R3),CURBF-2(R3) ;;;RESET CURRENT RELOCATION BIAS MOV CURBF-2(R3),KISAR6 ;;;RESET CURRENT APR6 BIAS .IFTF MOV STRBF+6-2(R3),R4 ;;;RESET CURRENT BUFFER ADDRESS 110$: DEC R2 ;;;ANY MORE DATA? BGT 90$ ;;;IF GT YES MOV R4,CURBF+6-2(R3) ;;;SAVE CURRENT BUFFER ADDRESS .IFT MOV STRBF-2(R3),KISAR6 ;;;MAP TO START OF BUFFER .IFTF MOV CURNX-2(R3),@BUFAD-2(R3) ;;;SET FORTRAN INDEX .IFT MOV R5,KISAR6 ;;;RESTORE CURRENT MAPPING .IFTF TSTB STATS-2(R3) ;;;FORK ALREADY IN PROGRESS? BNE 150$ ;;;IF NE NO BR 140$ ;;; 120$: ADD #LSCNT-2,R3 ;;;POINT TO LOST DATA COUNT CMP #100001,(R3) ;;;MAXIMUM VALUE? BEQ 125$ ;;;IF EQ YES DEC (R3) ;;;DECREMENT LOST DATA COUNT 125$: MOV (R3),(R4) ;;;SET LOST DATA COUNT .IFT MOV R5,KISAR6 ;;;RESTORE CURRENT MAPPING .ENDC 130$: ADD R2,SP ;;;REMOVE ENTRIES FROM STACK .ENDC 140$: MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; .ENDC JMP $INTXT ;;;EXIT FROM INTERRUPT ; ; CREATE FORK PROCESS AND WAKE UP TASK ; .IF DF U$$CIM!U$$TIM 150$: CLRB STATS-2(R3) ;;;SET FORK IN PROGRESS MOV R3,R4 ;;;COPY DATA CONTROL BLOCK ADDRESS MOV R3,R5 ;;; ADD #FRBLK+6-2,R4 ;;;POINT TO FORK BLOCK MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; CALL $FORK1 ;;;CREATE A SYSTEM PROCESS INCB STATS-2(R5) ;CLEAR FORK IN PROGRESS FLAG MOV CONTK-2(R5),R0 ;GET CONNECTED TASK TCB ØADDRESS BIT #T2.ABO,T.ST2(R0) ;TASK BEING ABORTED? BNE 160$ ;IF NE YES BIS EFNMK-2(R5),@EFNAD-2(R5) ;SET SPECIFIED EVENT FLAG 160$: CALLR $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST .ENDC .END Øä—ðskQ ›c, .TITLE XLDRV .IDENT /12.1/ ; ; ; COPYRIGHT (C) 1974, 1976, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 12.1 ; ; J. M. GILBERT, 31-MAR-74 ; ; PREVIOUSLY MODIFIED BY: ; ; S. G. DAVIS ; J. M. GILBERT ; L. GILLESPIE ; E. D. WALDIN ; ; MODIFIED BY: ; ; R. E. CALDWELL 30-OCT-79 ; ; RC024 -- REMOVE UNNEEDED CONDITIONALIZATION. ; ; DL11 ASYNCHRONOUS COMMUNICATIONS DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ; CONFIGURATION DEPENDENT PARAMETERS ; MDMCTL= 0 ;SET IF DL-11E (MODEM CONTROL) ;**-1 ; ; EQUATED SYMBOLS ; ; ; RXCSR BIT ASSIGNMENTS ; DTSTCH= 100000 ;DATA SET CHANGE RING= 40000 ;RING LINE ASSERTED CTS= 20000 ;CLEAR TO SEND CRRIER= 10000 ;CARRIER STATE RECACT= 4000 ;RECEIVER ACTIVE RXDONE= 200 ;RECEIVER DONE RCVENB= 100 ;RECEIVER INTERRUPT ENABLE DSINTE= 40 ;DATA SET CHANGE INTERRUPT ENABLE RTS= 4 ;REQUEST TO SEND TRMRDY= 2 ;DATA TERMINAL READY ; ; RXDBUF BIT ASSIGNMENTS ; RXERR= 100000 ;RECEIVER ERROR "OR" BIT OVRNER= 40000 ;RECEIVER OVERRUN ERROR IF SET FRMERR= 20000 ;RECEIVER FRAMING ERROR ; ; TXCSR BIT ASSIGNMENTS ; TXRDY= 200 ;TRANSMITTER DONE BIT TXINTE= 100 ;TRANSMITTER INTERRUPT ENABLE BIT BREAK= 1 ;CLAMP OUTPUT TO SPACE ; ; LOCAL DATA ; ; ; UNIT IMPURE DATA TABLE (INDEXED BY UNIT, POINTS TO UCB) ; CNTBL: ;REF LABEL UNITBL: ;UCB ADDRESSES .REPT D$$E11 .WORD 0 ;ENSURE SET TO ZERO .ENDM .IF GT D$$E11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 ;TEMPORARY STORAGE FOR UNIT NUMBER .ENDC .ENABL LSB ; ; DRIVER DISPATCH TABLE ; $XLTBL::.WORD DLINIT ;DEVICE INITIALIZATION .WORD DLCANC ;DEVICE I/O CANCELLATION .WORD DLTMO ;TIMEOUT ENTRY POINT .WORD DLPWRF ;POWER FAIL ROUTINE ;+ ;**- DLINIT - DL-11 SYNCHRONOUS COMMUNICATION CONTROLLER I/O INITIATOR ; ; DLINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE, ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE ; NORMAL RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, ; THE REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS ; BUSY, AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF ; THE NATURE OF THE DL-11, EACH UNIT IS A CONTROLLER ITSELF, ; HAS ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DLINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. NOTE ALSO THAT ONLY ; 8-BIT, NO PARITY DATA IS SUPPORTED. ; MESSAGE SYNCHRONIZATION IS PROVIDED BY PRECEDING KEY ; MESSAGES WITH A SYNC TRAIN, MUCH AS WITH A SYNCHRONOUS ; DEVICE. THE DIFFERENCE, OF COURSE, IS THAT THIS SYNC ; TRAIN IS SOLELY FOR MESSAGE SYNCHRONIZATION. THE LEADING ; SYNC TRAIN IS UNDER PROGRAM CONTROL, AS IT IS WITH THE ; RSX-11M SYNCHRONOUS LINE CONTROLLERS. ; ; INPUTS: ; ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED. ; ; OUTPUTS: ; ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ;- DLINIT: TSTB U.CW2(R5) ;UNSOLICITED (HDPX) RECEIVE ACTIVE? BMI 15$ ;IF SET, NOTHING TO DO - EXIT CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCS 15$ ;NO REQUEST OR UNIT BUSY ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O REQUEST PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB SPECIFIED IN THE ; DLINIT CALL. ; ; DL11 I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 RELOCATION BIAS OF I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 BYTE COUNT FOR SECOND PART OF TRANSMISSION OR 0 ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; MOV S.CSR(R4),R2 ;GET RECEIVER CSR ADDRESS ADD #I.FCN+1,R1 ;POINT TO I/O FUNCTION CODE CMPB #IO.INL/256.,(R1) ;CHECK IF TRANSFER FUNCTION BLOS 40$ ;BRANCH ON CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;IS DEVICE ON LINE (INITIALIZED?) BEQ 50$ ;CAN'T TRANSFER IF NOT CMPB #IO.RLB/256.,(R1) ;READ LOGICAL? BEQ 20$ ;YES, SERVICE READ REQUEST ; ; FALL THROUGH ON TRANSMIT (WRITE LOGICAL) ; MOVB S.ITM(R4),S.CTM(R4) ;INITIALIZE TIMEOUT COUNT ;**-8 MOVB U.NSYN(R5),R3 ;NO. OF SYNCS IN LEADER BITB #IO.WNS,-(R1) ;TRANSPARENT WRITE? BEQ 5$ ;IF EQ NO CLR R3 ;SHOW NO SYNCS 5$: MOVB R3,U.NSYC(R5) ;SET NO. OF SYNCS NEEDED .IF DF MDMCTL BIT #CTS,(R2) ;CLEAR TO SEND SET YET? BNE 10$ ;IF SO, START TRANSMITTING BIS #U2.CTS,U.CW2(R5) ;SAY CLEAR TO SEND EXPECTED BIS #RTS!DSINTE,(R2) ;ASSERT REQUEST TO SEND BR 140$ ;RETURN - INTERRUPT PROPAGATES TRANSFER .ENDC 10$: BIS #TXINTE,4(R2) ;ENABLE TRANSMITTER 15$: BR 140$ ;RETURN, INTERRUPT PROPAGATES TX ; ; RECEIVE FUNCTION INITIATION ; 20$: ;REFERENCE LABEL BIC #U2.FTM!U2.SYC,U.CW2(R5) ; ASSUME TRANSPARENT OP ;**-4 BITB #IO.RNS,-(R1) ;TRANSPARENT READ? BNE 30$ ;IF NE YES BIS #U2.FTM!U2.SYC,U.CW2(R5) ;NON-TRANSPARENT READ 30$: ;REF LABEL MOV R5,R0 ;SET UP TRANSFER VECTOR ADD #U.RBUF,R0 ;RECEIVE TRANSFER INFORMATION HERE MOV U.BUF(R5),(R0)+ ;TRANSFER BIAS MOV U.BUF+2(R5),(R0)+ ;AND VIRTUAL ADDRESS MOV U.CNT(R5),(R0) ;AND COUNT TSTB 2(R2) ; CLEAR RECEIVE BUFFER STATUS BIS #RCVENB,(R2) ; ENABLE RECEIVER BR 140$ ;RETURN - INTERRUPT CODE PROPAGATES RECEIVE ; ;**-8 ; CONTROL FUNCTION INITIATION (INITIATE OR TERMINATE CONTROLLER, ; OR CHANGE OPERATING MODE) ; 40$: BNE 70$ ;IF NOT EQUAL, MODE CHANGE REQUEST CLR (R2) ;CLEAR RXCSR TSTB -(R1) ;START FUNCTION? BNE 60$ ;IF NON-ZERO, TERMINATE ; ; DO START FUNCTION INITIATION ; .IF DF MDMCTL BIS #TRMRDY,(R2) ;INITIALIZE CONTROLLER .ENDC MOV R5,UNITBL(R3) ;INITIALIZE UCB ADDRESS IN UNIT TABLE BIS #U2.ONL,U.CW2(R5) ;MARK UNIT ON LINE BIC #U2.SYC,U.CW2(R5) ;CLEAR RECEIVER SYNC COUNT BR 120$ ;RETURN SUCCESSFUL ; ; CAN'T ESTABLISH COMMUNICATIONS ; 50$: MOV #IE.DNR&377,R0 ;SAY CAN'T INITIALIZE DEVICE (NOT READY) BR 130$ ;DO I/O DONE ; ; FUNCTION WAS TERMINATE LINE ; 60$: BIC #^C,U.CW2(R5) ;CLEAR OPERATING STATUS CLR UNITBL(R3) ;UNIT TABLE CLEARED OF UCB BR 120$ ;RETURN SUCCESSFUL STATUS ; ; SERVICE DEVICE MODE CHANGE REQUEST ; 70$: BITB #IO.HDX,-(R1) ; SUBFUNCTION SAY HALF DUPLEX? BEQ 80$ ;IF ZERO, NO BIS #U2.HDX,U.CW2(R5) ;SAY HALF DUPLEX CHARACTERISTIC 80$: BITB #IO.FDX,(R1) ;SET MODE TO FULL DUPLEX? BEQ 110$ ;DON'T SET FULL DUPLEX BIT #U2.LIN,U.CW2(R5) ;IS LINK FULL DUPLEX? BEQ 100$ ;IF SO, RUN FULL DUPLEX 90$: MOV #IE.IFC&377,R0 ;MARK AS ILLEGAL FUNCTION BR 130$ ;AND TERMINATE 100$: BIC #U2.HDX,U.CW2(R5) ;PUT IN FULL DUPLEX IN UCB 110$: BITB #IO.SYN,(R1) ;SYNC CHARACTER SPECIFIED? BEQ 120$ ;NO, IF NOT SET MOVB I.PRM-I.FCN(R1),U.SYNC(R5) ;RESET SYNC CHARACTER DLSUCC: ;REFERENCE LABEL 120$: MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS DLFIN: ;REFERENCE LABEL 130$: CLRB S.STS(R4) ;CLEAR CONTROLLER STATUS BICB #US.BSY,U.STS(R5) ;CLEAR UNIT STATUS MOV R0,-(SP) ;SAVE STATUS WORD 1 MOV S.PKT(R4),-(SP) ;SAVE PACKET ADDRESS CALL DLINIT ;ATTEMPT TO INITIATE SOMETHING MOV (SP)+,R3 ;RESTORE PACKET ADDRESS MOV I.PRM+4(R3),R1 ;RETURN REQUESTED COUNT MOV (SP)+,R0 ;RESTORE STATUS WORD 1 CALLR $IOFIN ;TERMINATE LAST PACKET 140$: RETURN  ; ; POWER FAIL SERVICE ; DLPWRF: ;REFERENCE LABEL CLRB S.CTM(R4) ;DISABLE TIMEOUTS ;**-8 BR 50$ ;FINISH I/O ; ;**-3 ; I/O CANCELLATION ; DLCANC: ;;;REFERENCE LABEL CMP R1,I.TCB(R0) ;;;CANCEL FOR THIS TASK? ;**-7 BNE 140$ ;;;JUST RETURN IF NOT CMPB #IO.WLB/256.,I.FCN+1(R0) ;;;WAS FUNCTION TRANSMIT? BEQ 140$ ;;;JUST LET FINISH IF YES TST U.RCNT(R5) ;;;RECEIVE FINISHED? BLE 140$ ;;;BR IF YES BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVER MOV #IE.ABO&377,R0 ;;;PUT ERROR CODE IN R0 CLR U.RCNT(R5) ;;;MARK COUNT SATISFIED BR 150$ ;;;FINISH OFF I/O ; ;**-4 ; TIMEOUT SERVICE ROUTINE ; ; INPUTS: ; ; R0 = DEVICE TIMEOUT STATUS 'IE.DNR' ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; DLTMO: ;;;TIMEOUT ENTRY POINT MOV S.CSR(R4),R3 ;;;GET RECEIVER CSR BIC #TXINTE,4(R3) ;;;DISABLE TRANSMITTER .IF DF MDMCTL BIC #RTS!DSINTE,(R3);;;CLEAR RTS AND DATA SET ENABLE BIC #U2.CTS,U.CW2(R5);;;CLEAR WAITING FOR CTS .ENDC 150$: ;;;REFERENCE LABEL MTPS #0 ;;;ALLOW INTERRUPTS JMP DLTXND ;;;WAIT FOR SOFTWARE TIMEOUT TO FINISH .DSABL LSB ; ; **- $XLINP - DL-11 INPUT INTERRUPT SERVICE ; $XLINP:: ;;;REFERENCE LABEL INTSV$ XL,PR5,D$$E11 ;;;GENERATE INTERRUPT SAVE CODE CALL DLSET ;;;SET CSR IN R4, UCB IN R5 MOV (R4),-(SP) ;;;SAVE CSR, TEST DATA SET CHANGE ;**-11 .IF DF MDMCTL BPL 10$ ;;;NO DATA SET CHANGE, IF NOT SET BIT #U2.CTS,U.CW2(R5) ;;;CTS EXPECTED? BEQ 5$ ;;;NO, IF NOT SET BIT #CTS,(R4) ;;;CLEAR TO SEND? BEQ 10$ ;;;NO, CHECK ON ERROR BIS #TXINTE,4(R4) ;;;ENABLE TRANSMITTER INTERRUPT BIC #U2.CTS,U.CW2(R5) ;;;HAVE CTS 5$: BIC #DSINTE,(R4) ;;;DISABLE DATA SET INTERRUPTS .IFTF 10$: MOV 2(R4),R4 ;;;CAPTURE BUFFER REGISTER IN R4 .ENDC ;**-10 20$: TSTB (SP)+ ;;;RECEIVER DONE? BPL 70$ ;;;IF NOT, DISMISS INTERRUPT TST U.RCNT(R5) ;;;COUNT ALREADY SATISFIED? BLE 70$ ;;;IF SO, DISMISS INTERRUPT BIT #U2.FTM,U.CW2(R5) ;;;IN MESSAGE SYNCH? BEQ 60$ ;;;IF NOT SET, YES CMPB U.SYNC(R5),R4 ;;;IS CHARACTER A SYNC? ;**-17 BNE 30$ ;;;IF NOT, MAY BE DATA BIT #U2.SYC,U.CW2(R5) ;;;WERE WE SYNCHING? BEQ 70$ ;;;ALREADY SYNCHED - JUST DISCARD DECB U.CW2(R5) ;;;DECREMENT RECEIVER SYNC COUNT RETURN ;;;DISMISS INTERRUPT 30$: BIT #U2.SYC,U.CW2(R5) ;;;COUNT SATISFIED? BEQ 50$ ;;;YES, IF EQUAL BISB #2,U.CW2(R5) ;;;TRY TO SYNC AGAIN RETURN ;;;DISMISS INTERRUPT 50$: BIC #U2.FTM,U.CW2(R5) ;;;NOW PAST LEADING SYNCS ;**-3 60$: ;;;REFERENCE LABEL .IF DF M$$MGE ; RC024 ;**-1 MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.RBUF(R5),KISAR6 ;;;MAP TO USER BUFFER MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER .IFTF DEC U.RCNT(R5) ;;;SEE IF COUNT SATISFIED BEQ 80$ ;;;YES, IF EQUAL INC U.RBUF+2(R5) ;;;BUMP BYTE ADDRESS .IFT BIT #20000,U.RBUF+2(R5) ;;;OVERFLOWED 4K BOUNDARY? BEQ 70$ ;;;NO, IF ZERO BIC #20000,U.RBUF+2(R5) ;;;CLEAR OVERFLOW BIT ADD #200,U.RBUF(R5) ;;;BUMP BIAS .ENDC 70$: ;;;REFERENCE LABEL RETURN ;;;EXIT INTERRUPT ;**-9 ; ; REQUEST SATISFIED ; 80$: ;;;REFERENCE LABEL MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS ;**-3 BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVER CALL $FORK ;;;GO TO FORK LEVEL JMP DLSUCC ;FINISH I/O SUCESSFUL ; ; **- $XLOUT - TRANSMITTER INTERRUPT SERVICE ; $XLOUT:: ;;;REFERENCE LABEL INTSV$ XL,PR5,D$$E11 ;;;GENERATE INTERRUPT SAVE CODE CALL DLSET ;;;SET RECEIVE CSR IN R4, UCB IN R5 ADD #6,R4 ;;; POINT TO TRANSMITTER BUFFER ; ; SET UP AND TRANSMIT A BYTE ; DECB U.NSYC(R5) ;;;DECREMENT LEADING SYNC COUNT BLT 10$ ;;;IF LT GO TO DATA MOVB U.SYNC(R5),(R4) ;;;SEND ANOTHER SYNC CHARACTER BR 30$ ;;;RESET TIMEOUT, EXIT 10$: INCB U.NSYC(R5) ;;; OFFSET DECREMENT ABOVE DEC U.CNT(R5) ;;; CHECK COUNT BGE 20$ ;;;IF GE, CONTINUE TST U.CW2(R5) ;;;IN HALF DUPLEX? ;**-3 BPL 50$ ;;;IF NOT, NO LINE TURNAROUND CMP #-3,U.CNT(R5) ;;;SENT 2 MARKS? ;**-10 BGE 40$ ;;;IF SO, TURN LINE AROUND MOVB #-1,(R4) ;;;SEND A MARK BR 30$ ;;;DISMISS INTERRUPT 20$: CALL $GTBYT ;;;GET NEXT BYTE FROM BUFFER MOVB (SP)+,(R4) ;;;OUTPUT CHARACTER 30$: MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS BACK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT RETURN ;;;EXIT INTERRUPT 40$: ;;;REFERENCE LABEL .IF DF MDMCTL BIC #RTS,-6(R4) ;;;CLR REQUEST TO SEND .ENDC 50$: BIC #TXINTE,-(R4) ;;;DISABLE TRANSMITTER ;**-9 CALL $FORK ;;;CREATE SYSTEM PROCESS MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS ;**-3 DLTXND: ;REFERENCE LABEL ;**-3 MOV U.SCB(R5),R4 ;RESTORE SCB TO R4 ;**-10 JMP DLFIN ;MARK COMPLETION ; ;**-49 ; DLSET - SET UP REGISTER R4 WITH CSR ADDRESS, R5 WITH ; UCB ADDRESS. UNIT NUMBER IN LOW ORDER 4 BITS OF UNIT. ; DLSET: ;;;REFERENCE LABEL TST R5 ;;;CHECK FOR UCB ADDRESS BEQ 10$ ;;;IF NO UCB, TROUBLE BIT #U2.ONL,U.CW2(R5) ;;;UNIT ON LINE? BEQ 1þ0$ ;;;IF NOT ON LINE, NONSENSE MOV U.SCB(R5),R4 ;;;FIRST GET SCB ADDRESS MOV S.CSR(R4),R4 ;;;NOW DEVICE CSR ADDRESS RETURN ;;;AND NOW RETURN 10$: TST (SP)+ ;;;CLEAR STACK OF RETURN ADDRESS DLSXT: JMP $INTXT ;;;DISMISS INTERRUPT .END þ„˜ðskQ ›c, .TITLE XPDRV .IDENT /13.1/ ; ; COPYRIGHT (C) 1974, 1976, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 13.1 ; ; J. M. GILBERT, 31-JAN-74 ; ; PREVIOUSLY MODIFIED BY: ; ; J. M. GILBERT ; L. GILLESPIE ; E. D. WALDIN ; ; MODIFIED BY: ; ; R. E. CALDWELL 30-OCT-79 ; ; RC024 -- REMOVE UNNEEDED CONDITIONALIZATION. ; ; DP11 SYNCHRONOUS COMMUNICATIONS DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,HWDDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ; CONFIGURATION DEPENDENT PARAMETERS ; ;**-1 ; ; EQUATED SYMBOLS ; ; ; RXCSR BIT ASSIGNMENTS ; RECACT= 4000 ;RECEIVER ACTIVE (IN SYNCH) RCVENB= 100 ;RECEIVER INTERRUPT ENABLE HDPX= 2 ;HALF DUPLEX IF SET STRSYN= 1 ;STRIP SYNC CHARACTERS ; ; TXCSR BIT ASSIGNMENTS ; CRRTRN= 100000 ;CARRIER TRANSITION FLAG OVRNER= 40000 ;RECEIVER OVERRUN IF SET RING= 20000 ;RING ASSERTED DSRDY= 10000 ;DATA SET (MODEM) READY CRRIER= 4000 ;CARRIER STATE FLAG CTS= 2000 ;CLEAR TO SEND RTS= 1000 ;REQUEST TO SEND TXDONE= 200 ;TRANSMITTER DONE BIT TXINTE= 100 ;TRANSMITTER INTERRUPT ENABLE STINTE= 40 ;STATUS INTERRUPT ENABLE IDLSYN= 2 ;IDLE SYNC CHARACTERS TRMRDY= 1 ;DATA TERMINAL READY ; ; LOCAL DATA ; ; ; UNIT IMPURE DATA TABLE (INDEXED BY UNIT, POINTS TO UCB) ; CNTBL: ;REF LABEL UNITBL: ;UCB ADDRESSES .REPT D$$P11 ;NUMBER OF UNITS ASSIGNED .WORD 0 ;INITIALIZE TO 0 .ENDM .IF GT D$$P11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 ;TEMPORARY STORAGE FOR UNIT NUMBER .ENDC .ENABL LSB ; ; DRIVER DISPATCH TABLE ; $XPTBL::.WORD DPINIT ;DEVICE INITIALIZATION .WORD DPCANC ;DEVICE I/O CANCELLATION .WORD DPTMO ;TIMEOUT ENTRY POINT .WORD DPPWRF ;POWER FAIL ROUTINE ;+ ;**- DPINIT - DP-11 SYNCHRONOUS COMMUNICATION CONTROLLER I/O INITIATOR ; ; DPINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE, ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE ; NORMAL RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, ; THE REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS ; BUSY, AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF ; THE NATURE OF THE DP-11, EACH UNIT IS A CONTROLLER ITSELF, ; HAS ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DPINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. ; ; INPUTS: ; ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED. ; ; OUTPUTS: ; ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ;- DPINIT: TSTB U.CW2(R5) ;UNSOLICITED (HDPX) RECEIVE ACTIVE? BPL 10$ ;IF NOT, PROCEED JMP 180$ ;ACTIVATE NO NEW OPERATION 10$: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCC 20$ ;CC MEANS HAVE REQUEST JMP 180$ ;NONE TO DO - EXIT ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O REQUEST PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB SPECIFIED IN THE ; DPINIT CALL. ; ; DP11 I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 RELOCATION BIAS OF I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 BYTE COUNT FOR SECOND PART OF TRANSMISSION OR 0 ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; 20$: MOV S.CSR(R4),R2 ;GET RECEIVER CSR ADDRESS ADD #I.FCN+1,R1 ;POINT TO I/O FUNCTION CODE CMPB #IO.INL/256.,(R1) ;CHECK IF TRANSFER FUNCTION BLOS 70$ ;BRANCH ON CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;IS DEVICE ON LINE (INITIALIZED?) BEQ 90$ ;CAN'T TRANSFER IF NOT BIT #DSRDY,4(R2) ;DATA SET READY? ;**-3 BEQ 90$ ;NO, IF BIT NOT SET CMPB #IO.RLB/256.,(R1) ;READ LOGICAL? ;**-3 BEQ 40$ ;YES, SERVICE READ REQUEST ; ; FALL THROUGH HERE ON TRANSMIT (WRITE LOGICAL) ; ADD #6,R2 ;POINT TO TX BUFFER ;**-9 MOVB U.SYNC(R5),R0 ;LOAD FIRST SYNC MOVB S.ITM(R4),S.CTM(R4) ;INITIALIZE TIMEOUT COUNT MOVB U.NSYN(R5),R3 ;SYNC COUNT 30$: MOVB R3,U.NSYC(R5) ;SET COUNT OF SYNCS TO ISSUE ;**-13 MOVB R0,(R2) ;ISSUE A CHARACTER BIS #IDLSYN!TXINTE,-(R2) ;ENABLE INTERRUPTS ON DEVICE BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES TRANSMISSION ; ; RECEIVE FUNCTION INITIATION ; 40$: ;REFERENCE LABEL MOV R5,R0 ;SET UP TRANSFER VECTOR ;**-4 ADD #U.RBUF,R0 ;RECEIVE TRANSFER INFORMATION HERE MOV U.BUF(R5),(R0)+ ;TRANSFER BIAS MOV U.BUF+2(R5),(R0)+ ;AND OFFSET MOV U.CNT(R5),(R0) ;AND COUNT BIC #RECACT,(R2) ;FORCE RESYNCHING BIS #STRSYN!RCVENB,(R2) ; ENABLE RECEIVER BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES RECEIVE ; ;**-8 ; CONTROL FUNCTION INITIATION (INITIATE OR TERMINATE CONTROLLER, ; OR CHANGE OPERATING MODE) ; 70$: BNE 110$ ;IF NOT EQUAL, MODE CHANGE REQUEST TSTB -(R1) ;START FUNCTION? BNE 100$ ;IF NON-ZERO, TERMINATE ; ; DO START FUNCTION INITIATION ; MOV #STRSYN,(R2) ;NOW INITIALIZE CONTROLLER TST U.CW2(R5) ;HALF DUPLEX MODE SELECTED? BPL 80$ ;NO, IF PLUS BIS #HDPX,(R2) ;PUT DEVICE IN HALF DUPLEX 80$: MOV #TRMRDY,4(R2) ;PUT TRANSMITTER ON LINE MOVB U.SYNC(R5),3(R2) ;INITIALIZE SYNC CHARACTER MOV R5,UNITBL(R3) ;INITIALIZE UCB ADDRESS IN UNIT TABLE BIS #U2.ONL,U.CW2(R5) ;MARK UNIT ON LINE BR 160$ ;RETURN SUCCESSFUL ; ; CAN'T ESTABLISH COMMUNICATIONS ; 90$: MOV #IE.DNR&377,R0 ;SAY CAN'T INITIALIZE DEVICE (NOT READY) BR 170$ ;DO I/O DONE ; ; FUNCTION WAS TERMINATE LINE ; 100$: CLR (R2) ;CLEAR UNIT READY CLR 4(R2) ;CLEAR TRANSMIT CSR BIC #^C,U.CW2(R5) ;CLEAR OPERATING STATUS CLR UNITBL(R3) ;UNIT TABLE CLEARED OF UCB BR 160$ ;RETURN SUCCESSFUL STATUS ; ; SERVICE DEVICE MODE CHANGE REQUEST ; 110$: BITB #IO.HDX,-(R1) ;SUBFUNCTION SAY HALF DUPLEX? BEQ 120$ ;IF ZERO, NO BIS #U2.HDX,U.CW2(R5) ;SAY HALF DUPLEX CHARACTERISTIC 120$: BITB #IO.FDX,(R1) ;SET MODE TO FULL DUPLEX? BEQ 150$ ;DON'T SET FULL DUPLEX BIT #U2.LIN,U.CW2(R5) ;IS LINE CAPABLE OF FULL DUPLEX? BEQ 140$ ;YES, IF BIT NOT SET 130$: MOV #IE.IFC&377,R0 ;SET ILLEGAL FUNCTION CODE BR 170$ ;AND RETURN ERROR STATUS 140$: BIC #U2.HDX,U.CW2(R5) ;PUT IN FULL DUPLEX IN UCB 150$: BITB #IO.SYN,(R1) ;SYNC CHARACTER SPECIFIED? BEQ 160$ ;NO, IF NOT SET MOVB I.PRM-I.FCN(R1),U.SYNC(R5) ;MARK NEW SYNC CHARACTER  DPSUCC: ;REFERENCE LABEL 160$: MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS DPFIN: ;REFERENCE LABEL 170$: CLRB S.STS(R4) ;IDLE CONTROLLER BICB #US.BSY,U.STS(R5) ;AND MARK UNIT IDLE MOV R0,-(SP) ;SAVE STATUS WORD 1 MOV S.PKT(R4),-(SP) ;SAVE OLD PACKET ADDRESS CALL DPINIT ;TRY TO ACTIVATE ANOTHER REQUEST MOV (SP)+,R3 ;GET OLD I/O PACKET MOV I.PRM+4(R3),R1 ;RETURN REQUESTED ITEM COUNT MOV (SP)+,R0 ;GET STATUS WORD 1 CALLR $IOFIN ;TERMINATE OLD PACKET 180$: RETURN ; ; POWER FAIL SERVICE ; DPPWRF: ;REFERENCE LABEL CLRB S.CTM(R4) ;CLEAR DEVICE TIMEOUT COUNT ;**-8 MOV #IE.DNR&377,R0 ;PUT ERROR CODE IN R0 FOR DPTMO BR DPTMO ;FINISH I/O ABORT ; ;**-4 ; I/O CANCELLATION ENTRY ; ; INPUTS: ; R0=I/O PACKET ADDRESS ; R1=TCB ADDRESS OF TASK TO CANCEL ; R4=SCB ADDRESS ; R5=UCB ADDRESS DPCANC: ;;;REFERENCE LABEL CMP R1,I.TCB(R0) ;;;CANCEL FOR THIS TASK? ;**-7 BNE 180$ ;;;DON'T CANCEL IF NOT CMPB #IO.WLB/256.,I.FCN+1(R0) ;;;IS FUNCTION TRANSMIT? BEQ 180$ ;;;JUST LET TRANSMIT FINISH TST U.RCNT(R5) ;;;RECEIVE FINISHEED? BLE 180$ ;;;DON'T CANCEL IF YES BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVER MOV #IE.ABO&377,R0 ;;;PUT ERROR CODE IN R0 FOR DPTMO BR DPTMO ;;;FINISH OFF RECEIVE PACKET ; ;**-4 ; TIMEOUT SERVICE ROUTINE ; ; INPUTS: ; ; R0 = DEVICE TIMEOUT STATUS 'IE.DNR' ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; DPTMO: MOV S.CSR(R4),R4 ;;;GET DEVICE CSR BIC #TXINTE!IDLSYN,4(R4) ;;;DISABLE TRANSMITTER MTPS #0 ;;;ALLOW INTERRUPTS 210$: JMP DPTXND ;WAIT FOR SOFTWARE TIMEOUT .DSABL LSB ; ; **- $XPINP - DP-11 INPUT INTERRUPT SERVICE ; .ENABL LSB $XPINP:: ;;;REFERENCE LABEL INTSV$ XP,PR5,D$$P11 ;;;GENERATE INTERRUPT SAVE CODE CALL DPSET ;;;SET CSR IN R4, UCB IN R5 BIC #STRSYN,(R4)+ ;;;CLEAR STRIP SYNC MODE ;**-11 MOV (R4),R4 ;;;GET RECEIVED CHARACTER ;**-3 .IF DF M$$MGE ; RC024 ;**-1 MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.RBUF(R5),KISAR6 ;;;MAP TO USER BUFFER MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER .IFTF DEC U.RCNT(R5) ;;;SEE IF COUNT SATISFIED BEQ 20$ ;;;YES, IF EQ INC U.RBUF+2(R5) ;;;BUMP BYTE ADDRESS .IFT BIT #20000,U.RBUF+2(R5) ;;;OVERFLOWED 4K BOUNDARY? BEQ 10$ ;;;NO, IF ZERO BIC #20000,U.RBUF+2(R5) ;;;CLEAR OVERFLOW BIT ADD #200,U.RBUF(R5) ;;;BUMP BIAS .ENDC ;**-9 10$: RETURN ;;;EXIT FROM INTERRUPTS ; ; REQUEST SATISFIED ; 20$: ;;;REFERENCE LABEL MOV U.SCB(R5),R4 ;;;GET DEVICE SCB ADDRESS ;**-33 BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVE INTERRUPTS CALL $FORK ;;;CREATE A FORK PROCESS JMP DPSUCC ;END I/O SUCCESSFUL ;**-3 .DSABL LSB ; ; **- $XPOUT - TRANSMITTER INTERRUPT SERVICE ; $XPOUT:: ;;;REFERENCE LABEL INTSV$ XP,PR5,D$$P11 ;;;GENERATE INTERRUPT SAVE CODE CALL DPSET ;;;SET RECEIVE CSR IN R4, UCB IN R5 ADD #4,R4 ;;;POINT TO TX CSR BIT #CRRTRN!OVRNER!RING,(R4)+ ;;;ANY TRANSITIONS MADE? BEQ 20$ ;;;IF NOT, CHECK TRANSMIT INTERRUPT 10$: BIC #OVRNER!CRRTRN!RING,-(R4) ;;;CLEAR STATUS TRANSITION BIT;**-14 TSTB (R4)+ ;;;TRANSMITTER FLAG SET? BPL 60$ ;;;IF NOT, DISMISS INTERRUPT INC R4 ;;;POINT TO TRANSMITTER BUFFER 20$: TSTB U.NSYC(R5) ;;;SYNC COUNT 0? BEQ 30$ ;;;IF SO, TRANSMIT DECB U.NSYC(R5) ;;;DECREMENT LEADING SYNC COUNT BLE 40$ ;;;IF LE, BEGIN TRANSMITTING MOVB U.SYNC(R5),(R4) ;;;SEND ANOTHER SYNC BR 50$ ;;;AND EXIT ; ; SET UP AND TRANSMIT A BYTE ; 30$: DEC U.CNT(R5) ;;;CHECK COUNT (0 NOT VALID) BLE 70$ ;;;IF LE, COUNT SATISFIED 40$: CALL $GTBYT ;;;GET NEXT BYTE FROM BUFFER MOVB (SP)+,(R4) ;;;OUTPUT CHARACTER 50$: MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS BACK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT 60$: BR DPSXT ;;;EXIT FROM INTERRUPT ; ; COUNT SATISFIED - TERMINATE TRANSMISSION ; 70$: BIC #TXDONE!TXINTE,-(R4) ;;;DISABLE TRANSMITTER  TST U.CW2(R5) ;;;IN HALF DUPLEX? ;**-3 BPL 80$ ;;;IF PLUS NO BIC #IDLSYN,(R4) ;;;DON'T GO TO IDLE SYNC CMP -(R4),-(R4) ;;;POINT TO RECEIVER CSR BIC #RECACT,(R4) ;;;FORCE RE-SYNCHING 80$: CALL $FORK ;;;CREATE SYSTEM PROCESS ;**-11 MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS ;**-3 DPTXND: ;REFERENCE LABEL ;**-3 MOV U.SCB(R5),R4 ;RESTORE SCB TO R4 ;**-10 JMP DPFIN ;MARK COMPLETION ; ; DPSET - SET UP REGISTER R4 WITH CSR ADDRESS, R5 WITH ; UCB ADDRESS. UNIT NUMBER IN LOW O®RDER 4 BITS OF UNIT. ; DPSET: ;;;REFERENCE LABEL TST R5 ;;;CHECK FOR UCB ADDRESS BEQ 10$ ;;;IF NO UCB, TROUBLE BIT #U2.ONL,U.CW2(R5) ;;;UNIT ON LINE? BEQ 10$ ;;;IF NOT ON LINE, NONSENSE MOV U.SCB(R5),R4 ;;;FIRST GET SCB ADDRESS MOV S.CSR(R4),R4 ;;;NOW DEVICE CSR ADDRESS RETURN ;;;AND NOW RETURN 10$: TST (SP)+ ;;;CLEAR STACK OF RETURN ADDRESS DPSXT: JMP $INTXT ;;;DISMISS INTERRUPT .END ®L™ðskQ ›c, .TITLE XUDRV .IDENT /14.1/ ; ; COPYRIGHT (C) 1974, 1978, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 14.1 ; ; J. M. GILBERT, 31-JAN-74 ; ; PREVIOUSLY MODIFIED BY: ; ; J. M. GILBERT ; L. GILLESPIE ; E. D. WALDIN ; ; MODIFIED BY: ; ; J. H. MATTHEWS 19-OCT-77 ; ; JM001 -- MODIFIED TRANSMIT LINE TO IDLE WITH MARK ; INSTEAD OF SYNC. ; ; R. E. CALDWELL 30-OCT-79 ; ; RC024 -- REMOVE UNNEEDED CONDITIONALIZATION. ; ; DU11 SYNCHRONOUS COMMUNICATIONS DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,HWDDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ; CONFIGURATION DEPENDENT PARAMETERS ; ;**-1 ; ; EQUATED SYMBOLS ; ; ; RXCSR BIT ASSIGNMENTS ; DTSTCH= 100000 ;DATA SET CHANGE RING= 40000 ;RING LINE ASSERTED CTS= 20000 ;CLEAR TO SEND CRRIER= 10000 ;CARRIER STATE RECACT= 4000 ;RECEIVER ACTIVE DSRDY= 1000 ;DATA SET READY STRSYN= 400 ;STRIP SYNC RXDONE= 200 ;RECEIVER DONE RCVENB= 100 ;RECEIVER INTERRUPT ENABLE DSINTE= 40 ;DATA SET CHANGE INTERRUPT ENABLE SCHSYN= 20 ;SEARCH SYNC MODE BIT RTS= 4 ;REQUEST TO SEND TRMRDY= 2 ;DATA TERMINAL READY ; ; RXDBUF BIT ASSIGNMENTS ; RXERR= 100000 ;RECEIVER ERROR "OR" BIT OVRNER= 40000 ;RECEIVER OVERRUN ERROR IF SET ; ; PARCSR INITIALIZATION VALUES ; INTSYN= 30000 ;INTERNAL SYNC MODE PATTERN WRDLEN= 6000 ;WORD LENGTH (8 BITS STANDARD) PARENB= 0 ;NO PARITY CHECKING PARSEN= 0 ;PARITY SENSE (DEPENDS ON PARENB) INITMD= INTSYN!WRDLEN!PARENB!PARSEN ;ALL INITIALIZATION PARAMETERS ; ; TXCSR BIT ASSIGNMENTS ; DNAINT= 100000 ;SET ON DATA NOT AVAILABLE INTERRUPT MSTRST= 400 ;MASTER DEVICE RESET TXDONE= 200 ;TRANSMITTER DONE BIT TXINTE= 100 ;TRANSMITTER INTERRUPT ENABLE BIT DNAEN= 40 ;ENABLE DATA NOT AVAILABLE INTERRUPT SEND= 20 ;TRANSMITTER ENABLE (GO) BIT HDPX= 10 ;HALF DUPLEX IF SET ; ; LOCAL DATA ; ; ; UNIT IMPURE DATA TABLE (INDEXED BY UNIT, POINTS TO UCB) ; CNTBL: ;REF LABEL UNITBL: ;UCB ADDRESS TABLE .REPT D$$U11 ;ONE ENTRY PER UNIT .WORD 0 .ENDM .IF GT D$$U11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 ;TEMPORARY STORAGE FOR UNIT NUMBER .ENDC .ENABL LSB ; ; DRIVER DISPATCH TABLE ; $XUTBL::.WORD DUINIT ;DEVICE INITIALIZATION .WORD DUCANC ;DEVICE I/O CANCELLATION .WORD DUTMO ;TIMEOUT ENTRY POINT .WORD DUPWRF ;POWER FAIL ROUTINE ;+ ;**- DUINIT - DU-11 SYNCHRONOUS COMMUNICATION CONTROLLER I/O INITIATOR ; ; DUINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE, ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE ; NORMAL RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, ; THE REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS ; BUSY, AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF ; THE NATURE OF THE DU-11, EACH UNIT IS A CONTROLLER ITSELF, ; HAS ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DUINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. ; ; INPUTS: ; ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED. ; ; OUTPUTS: ; ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ;- DUINIT: TSTB U.CW2(R5) ;UNSOLICITED (HDPX) RECEIVE ACTIVE? BPL 10$ ;IF NOT, PROCEED JMP 180$ ;ACTIVATE NO NEW OPERATION 10$: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCC 20$ ;IF CC, SOMETHING TO DO JMP 180$ ;NO REQUEST OR UNIT BUSY ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O REQUEST PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB SPECIFIED IN THE ; DUINIT CALL. ; ; DU11 I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000)  ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 RELOCATION BIAS OF I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 BYTE COUNT FOR SECOND PART OF TRANSMISSION OR 0 ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; 20$: MOV S.CSR(R4),R2 ;GET RECEIVER CSR ADDRESS ADD #I.FCN+1,R1 ;POINT TO I/O FUNCTION CODE CMPB #IO.INL/256.,(R1) ;CHECK IF TRANSFER FUNCTION BLOS 70$ ;BRANCH ON CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;IS DEVICE ON LINE (INITIALIZED?) BEQ 90$ ;CAN'T TRANSFER IF NOT BIT #DSRDY,(R2) ;IS DATA SET READY? ;**-3 BEQ 90$ ;IF NOT, CAN'T TRANSFER CMPB #IO.RLB/256.,(R1) ;READ LOGICAL? ;**-3 BEQ 40$ ;YES, SERVICE READ REQUEST ; ; FALL THROUGH HERE ON TRANSMIT (WRITE LOGICAL) ; BIS #RTS,(R2) ;ASSERT REQUEST TO SEND ;**-8 MOVB U.SYNC(R5),R0 ;LOAD SYNC CHARACTER MOVB S.ITM(R4),S.CTM(R4) ;INITIALIZE TIMEOUT COUNT MOVB U.NSYN(R5),R3 ;NUMBER OF SYNCS IN LEADER 30$: MOVB R3,U.NSYC(R5) ;LOAD SYNC LEADER COUNT ;**-15 ADD #4,R2 ;POINT TO TRANSMIT CSR BIS #SEND,(R2)+ ;ENABLE TRANSMISSION MOVB R0,(R2) ;SEND FIRST CHARACTER TST -(R2) ;CLEAR DATA LATE ERRORS BIS #DNAEN!TXINTE,(R2) ;ENABLE INTERRUPTS BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES TRAN ; ; RECEIVE FUNCTION INITIATION ; 40$: ;REFERENCE LABEL MOV R5,R0 ;SET UP TRANSFER VECTOR ;**-4 ADD #U.RBUF,R0 ;RECEIVE TRANSFER INFORMATION HERE MOV U.BUF(R5),(R0)+ ;TRANSFER BIAS MOV U.BUF+2(R5),(R0)+ ;AND OFFSET MOV U.CNT(R5),(R0) ;AND COUNT BIC #SCHSYN,(R2) ;FORCE RE-SYNCHING TSTB 2(R2) ; ENSURE RECEIVE BUFFER CLEAR BIS #STRSYN!RCVENB!SCHSYN,(R2) ; ENABLE RECEIVER BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES RECEIVE ; ;**-8 ; CONTROL FUNCTION INITIATION (INITIATE OR TERMINATE CONTROLLER, ; OR CHANGE OPERATING MODE) ; 70$: BNE 110$ ;IF NOT EQUAL, MODE CHANGE REQUEST CMP (R2)+,(R2)+ ;POINT TO TXCSR BIS #MSTRST,(R2) ;RESET DEVICE TSTB -(R1) ;START FUNCTION? BNE 100$ ;IF NON-ZERO, TERMINATE ; ; DO START FUNCTION INITIATION ; TST U.CW2(R5) ;DEVICE TO BE IN HALF DUPLEX? BPL 80$ ;NO, IF PLUS BIS #HDPX,(R2) ;PUT IN HALF DUPLEX MODE 80$: MOV #INITMD,R0 ;GET WORD SIZE, SYNC MODE BISB U.SYNC(R5),R0 ;OR IN SYNC CHARACTER MOV R0,-(R2) ;INITIALIZE DEVICE PARAMETERS BIS #STRSYN!TRMRDY!SCHSYN,-(R2) ;NOW INITIALIZE CONTROLLER MOV R5,UNITBL(R3) ;INITIALIZE UCB ADDRESS IN UNIT TABLE BIS #U2.ONL,U.CW2(R5) ;MARK UNIT ON LINE BR 160$ ;RETURN SUCCESSFUL ; ; CAN'T ESTABLISH COMMUNICATIONS ; 90$: MOV #IE.DNR&377,R0 ;SAY CAN'T INITIALIZE DEVICE (NOT READY) BR 170$ ;DO I/O DONE ; ; FUNCTION WAS TERMINATE LINE ; 100$: BIC #^C,U.CW2(R5) ;CLEAR OPERATING STATUS CLR UNITBL(R3) ;UNIT TABLE CLEARED OF UCB BR 160$ ;RETURN SUCCESSFUL STATUS ; ; SERVICE DEVICE MODE CHANGE REQUEST ; 110$: BITB #IO.HDX,-(R1) ;SUBFUNCTION SAY HALF DUPLEX? BEQ 120$ ;IF ZERO, NO BIS #U2.HDX,U.CW2(R5) ;SAY HALF DUPLEX CHARACTERISTIC 120$: BITB #IO.FDX,(R1) ;SET MODE TO FULL DUPLEX? BEQ 150$ ;DON'T SET FULL DUPLEX BIT #U2.LIN,U.CW2(R5) ;IS LINK FULL DUPLEX? BEQ 140$ ;IF SO, RUN FULL DUPLEX 130$: MOV #IE.IFC&377,R0 ;MARK AS ILLEGAL FUNCTION BR 170$ ;AND TERMINATE 140$: BIC #U2.HDX,U.CW2(R5) ;PUT IN FULL DUPLEX IN UCB 150$: BITB #IO.SYN,(R1) ;SYNC CHARACTER SPECIFIED? BEQ 160$ ;NO, IF NOT SET MOVB I.PRM-I.FCN(R1),U.SYNC(R5) ;MARK NEW SYNC CHARACTER DUSUCC: ;REFERENCE LABEL 160$: MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS DUFIN: ;REFERENCE LABEL 170$: CLRB S.STS(R4) ;CLEAR CONTROLLER STATUS BICB #US.BSY,U.STS(R5) ;MARK UNIT IDLE, ALSO MOV R0,-(SP) ;SAVE STATUS WORD 1 MOV S.PKT(R4),-(SP) ;SAVE OLD PACKET ADDRESS CALL DUINIT ;INITIATE NEXT PACKET MOV (SP)+,R3 ;GET OLD PACKET ADDRESS MOV I.PRM+4(R3),R1 ;RETURN REQUESTED ITEM COUNT MOV (SP)+,R0 ;RESTORE STATUS WORD 1 CALLR $IOFIN ;TERMINATE OLD PACKET 180$: RETURN ; ; ; POWER FAIL SERVICE ; DUPWRF: ;REFERENCE LABEL CLRB S.CTM(R4) ;DISABLE DEVICE TIMEOUTS ;**-8 MOV #IE.DNR&377,R0 ;PUT ERROR CODE IN R0 FOR DUTMO BR DUTMO ;FINISH I/O ABORT ; ;**-3 ; I/O CANCELLATION SERVICE ; ; INPUTS: ; R0=I/O PACKET ADDRESS ; R1=TCB ADDRESS OF TASK TO CANCEL ; R4=SCB ADDRESS ; R5=UCB ADDRESS DUCANC: ;;;REFERENCE LABEL CMP R1,I.TCB(R0) ;;;CANCEL FOR THIS TASK? ;**-7 BNE 180$ ;;;JUST RETURN IF NOT CMPB #IO.WLB/256.,I.FCN+1(R0) ;;;TRANSMIT FUNCTION? BEQ 180$ ;;;LET TRANSMIT FINISH TST U.RCNT(R5) ;;;RECEIVER FINISHED? BLE 180$ ;;;RETURN IF YES BIC #RCVENB!SCHSYN,@S.CSR(R4) ;DISABLE RECEIVER MOV #IE.ABO&377,R0 ;;;PUT ERROR CODE IN R0 FOR DUTMO BR DUTMO ;;;FINISH OFF RECEIVE PACKET ; ;**-4 ; TIMEOUT SERVICE ROUTINE ; ; INPUTS: ; ; R0 = DEVICE TIMEOUT STATUS 'IE.DNR' ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; DUTMO: ;;;REFERENCE LABEL MOV S.CSR(R4),R4 ;GET RECEIVER CSR BIC #TXINTE!SEND!DNAEN,4(R4) ;;;DISABLE TRANSMITTER BIC #RTS,(R4) ;;;TURN OFF CARRIER MTPS #0 ;;;ALLOW INTERRUPTS 210$: JMP DUTXND ;WAIT FOR SOFTWARE TIMEOUT .DSABL LSB ; ; **- $XUINP - DU-11 INPUT INTERRUPT SERVICE ; $XUINP:: ;;;REFERENCE LABEL INTSV$ XU,PR5,D$$U11 ;;;GENERATE INTERRUPT SAVE CODE CALL DUSET ;;;SET CSR IN R4, UCB IN R5 BIC #STRSYN,(R4)+ ;;; EXIT STRIP SYNC MODE ;**-11 MOV (R4),R4 ;;;CONTENTS OF RCV BUFFER IN R4 .IF DF M$$MGE ; RC024 ;**-12 MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.RBUF(R5),KISAR6 ;;;MAP TO USER BUFFER MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER .IFTF DEC U.RCNT(R5) ;;;SEE IF COUNT SATISFIED BEQ 30$ ;;;YES, IF EQUAL INC U.RBUF+2(R5) ;;;BUMP BYTE ADDRESS .IFT BIT #20000,U.RBUF+2(R5) ;;;OVERFLOWED 4K BOUNDARY? BEQ 20$ ;;;NO, IF ZERO BIC #20000,U.RBUF+2(R5) ;;;CLEAR OVERFLOW BIT ADD #200,U.RBUF(R5) ;;;BUMP BIAS .ENDC ;**-10 20$: RETURN ;;;EXIT FROM INTERRUPT ; ; REQUEST SATISFIED ; 30$: ;REFERENCE LABEL MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS ;**-31 BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVER CALL $FORK ;;;GO TO FORK LEVEL JMP DUSUCC ;COMPLETE SUCCESSFUL I/O ; ; **- $XUOUT - TRANSMITTER INTERRUPT SERVICE ; $XUOUT:: ;;;REFERENCE LABEL INTSV$ XU,PR5,D$$U11 ;;;GENERATE INTERRUPT SAVE CODE CALL DUSET ;;;SET RECEIVE CSR IN R4, UCB IN R5 ADD #4,R4 ;;;POINT TO TX CSR TST (R4)+ ;;;DATA NOT AVAILABLE? BPL 10$ ;;;NO, IF NOT SET ; ; CHECK DATA LATE ; TSTB -2(R4) ;;;TRANSMITTER DONE SET? ;**-21 BPL 60$ ;;;IF NOT, DISMISS INTERRUPT 10$: BIT #CTS,-6(R4) ;;;CLEAR TO SEND SET? BEQ 20$ ;;;IF NOT, SEND A SYNC TSTB U.NSYC(R5) ;;;SYNC COUNT ZERO? BEQ 30$ ;;;IF YES, TRANSMIT DATA DECB U.NSYC(R5) ;;;DECREMENT SYNC LEADER COUNT BLE 30$ ;;;IF LE, TRANSMIT DATA 20$: MOVB U.SYNC(R5),(R4) ;;;SEND A SYNC CHARACTER BR 50$ ;;;EXIT ; ; SET UP AND TRANSMIT A BYTE ; 30$: DEC U.CNT(R5) ;;;CHECK COUNT (0 NOT VALID) BGE 40$ ;;;IF NOT, CONTINUE TST U.CW2(R5) ;;;IN HALF DUPLEX? BPL 80$ ;;;IF NOT, NO TURNAROUND CMP #-3,U.CNT(R5) ;;;SENT TWO MARKS? ;**-8 BGE 70$ ;;;IF SO, TURN LINE AROUND MOVB #-1,(R4) ;;;OUTPUT A MARK BR 50$ ;;;DISMISS INTERRUPT 40$: CALL $GTBYT ;;;GET NEXT BYTE FROM BUFFER MOVB (SP)+,(R4) ;;;OUTPUT CHARACTER 50$: MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS BACK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT 60$: BR DUSXT ;;;EXIT FROM INTERRUPT 70$: BIC #SEND,-(R4) ;;;DON'T IDLE SYNC TST -(R4) ;;;CLEAR RECEIVE DONE AND ERROR BIC #SCHSYN!RTS,-(R4) ;;;TURN OFF CARRIER BIS #SCHSYN,(R4) ;;;FORCE RESYNCHIBNG ;**-7 ADD #6,R4 ;;;POINT TO TRANSMIT BUFFER ;**-3 80$: BIC #TXINTE!DNAEN!SEND,-(R4) ;;;DISABLE TRANSMITTER CALL $FORK ;;;CREATE SYSTEM PROCESS MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS ;**-3 DUTXND: ;REFERENCE LABEL ;**-3 MOV U.SCB(R5),R4 ;RESTORE SCB TO R4 ;**-10 JMP DUFIN ;MARK COMPLETION ; ; DUSET - SET UP REGISTER R4 WITH CSR ADDRESS, R5 WITH ; UCB ADDRESS. UNIT NUMBER IN¾ LOW ORDER 4 BITS OF UNIT. ; DUSET: ;;;REFERENCE LABEL TST R5 ;;;TEST FOR VALID UCB ADDRESS BEQ 10$ ;;;IF NO UCB, TROUBLE BIT #U2.ONL,U.CW2(R5) ;;;UNIT ON LINE? BEQ 10$ ;;;IF NOT ON LINE, CAN'T TRANSFER MOV U.SCB(R5),R4 ;;;FIRST GET SCB ADDRESS MOV S.CSR(R4),R4 ;;;NOW DEVICE CSR ADDRESS RETURN ;;;AND NOW RETURN 10$: TST (SP)+ ;;;CLEAR STACK OF RETURN ADDRESS DUSXT: JMP $INTXT ;;;DISMISS INTERRUPT .END ¾œ™ðskQ ›c, .TITLE XWDRV .IDENT /1.1/ ; ; COPYRIGHT (C) 1976, 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 1.1 ; ; SCOTT G. DAVIS 21-JUL-76 ; ; DUE ALMOST ENTIRELY TO XUDRV ; ; ; DUP11 SYNCHRONOUS COMMUNICATIONS DRIVER ; ; MODIFIED BY ; ; R. E. CALDWELL 30-OCT-79 ; ; RC024 -- REMOVE UNNEEDED CONDITIONALIZATION. ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,HWDDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .MCALL UCBDF$,CUCDF$ UCBDF$ ; DEFINE UCB OFFSETS CUCDF$ ;COMMUNICATIONS UCB LABELS ; ; CONFIGURATION DEPENDENT PARAMETERS ; ;**-1 ; ; EQUATED SYMBOLS ; ; ; RXCSR BIT ASSIGNMENTS ; DTSTCH= 100000 ;DATA SET CHANGE RING= 40000 ;RING LINE ASSERTED CTS= 20000 ;CLEAR TO SEND CRRIER= 10000 ;CARRIER STATE RECACT= 4000 ;RECEIVER ACTIVE DSRDY= 1000 ;DATA SET READY STRSYN= 400 ;STRIP SYNC RXDONE= 200 ;RECEIVER DONE RCVENB= 100 ;RECEIVER INTERRUPT ENABLE DSINTE= 40 ;DATA SET CHANGE INTERRUPT ENABLE SCHSYN= 20 ;SEARCH SYNC MODE BIT RTS= 4 ;REQUEST TO SEND TRMRDY= 2 ;DATA TERMINAL READY ; ; RXDBUF BIT ASSIGNMENTS ; RXERR= 100000 ;RECEIVER ERROR "OR" BIT OVRNER= 40000 ;RECEIVER OVERRUN ERROR IF SET ; ; PARCSR INITIALIZATION VALUES ; DECMOD= 100000 ;SET DDCMP/BISYNCH MODE CRCINH=1000 ;INHIBIT CRC CALCULATION INITMD=DECMOD!CRCINH ;PARAMETER INITIALIZATION BITS ; TSOM=400 ;TRANSFER - START OF MESSAGE ; ; ; TXCSR BIT ASSIGNMENTS ; DNAINT= 100000 ;SET ON DATA NOT AVAILABLE INTERRUPT MSTRST= 400 ;MASTER DEVICE RESET TXDONE= 200 ;TRANSMITTER DONE BIT TXINTE= 100 ;TRANSMITTER INTERRUPT ENABLE BIT DNAEN= 40 ;ENABLE DATA NOT AVAILABLE INTERRUPT SEND= 20 ;TRANSMITTER ENABLE (GO) BIT HDPX= 10 ;HALF DUPLEX IF SET ; ; LOCAL DATA ; ; ; UNIT IMPURE DATA TABLE (INDEXED BY UNIT, POINTS TO UCB) ; CNTBL: ;REF LABEL UNITBL: ;UCB ADDRESS TABLE .REPT D$$W11 ;ONE ENTRY PER UNIT .WORD 0 .ENDM .IF GT D$$W11-1 TEMP: ;REF LABEL UNIT: .BLKW 1 ;TEMPORARY STORAGE FOR UNIT NUMBER .ENDC .ENABL LSB ; ; DRIVER DISPATCH TABLE ; $XWTBL::.WORD DWINIT ;DEVICE INITIALIZATION .WORD DWCANC ;DEVICE I/O CANCELLATION .WORD DWTMO ;TIMEOUT ENTRY POINT .WORD DUPWRF ;POWER FAIL ROUTINE ;+ ;**- DWINIT - DUP-11 SYNCHRONOUS COMMUNICATION CONTROLLER I/O INITIATOR ; ; DWINIT IS ENTERED WHEN AN I/O REQUEST IS QUEUED ON THE DEVICE, ; AND AT THE END OF EACH QIO REQUEST WHICH OBEYS THE ; NORMAL RSX-11M INPUT/OUTPUT LOGIC FLOW. IF THE DEVICE IS ; AVAILABLE AND A REQUEST IS IN THE QUEUE FOR THAT UNIT, ; THE REQUEST IS INITIATED. ; IF NO REQUEST EXISTS FOR THAT UNIT OR IF IT IS ; BUSY, AN EXIT IS TAKEN TO THE CALLER. NOTE THAT BECAUSE OF ; THE NATURE OF THE DUP-11, EACH UNIT IS A CONTROLLER ITSELF, ; HAS ITS OWN SCB, AND THEREFORE ITS OWN QUEUE. ; EACH TIME DWINIT IS CALLED, IT IS CALLED TO SERVICE ONLY ; THE UNIT SPECIFIED IN THE CALL. ; ; INPUTS: ; ; R4 = STATUS CONTROL BLOCK ADDRESS ; R5 = ADDRESS OF THE UCB TO BE INITIATED. ; ; OUTPUTS: ; ; IF A REQUEST IS SUCCESSFULLY DEQUEUED, THE ; DEVICE IS INITIATED APPROPRIATELY. ;- DWINIT: TSTB U.CW2(R5) ;UNSOLICITED (HDPX) RECEIVE ACTIVE? BPL 10$ ;IF NOT, PROCEED JMP 180$ ;ACTIVATE NO NEW OPERATION 10$: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS BCC 20$  ;IF CC, SOMETHING TO DO JMP 180$ ;NO REQUEST OR UNIT BUSY ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O REQUEST PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB SPECIFIED IN THE ; DWINIT CALL. ; ; DUP11 I/O REQUEST PACKET FORMAT ; ; WORD CONTENT ; ; 0 I/O QUEUE THREAD WORD ; 1 REQUEST PRIORITY, EVENT FLAG NUMBER ; 2 ADDRESS OF THE TCB OF THE REQUESTER TASK ; 3 POINTER TO SECOND LUN WORD IN TASK HEADER ; 4 CONTENTS OF FIRST LUN WORD (UCB) ; 5 I/O FUNCTION CODE ; 6 VIRTUAL ADDRESS OF I/O STATUS BLOCK ; 7 RELOCATION BIAS OF I/O STATUS BLOCK ; 10 I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT +140000) ; 11 VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; 12 RELOCATION BIAS OF I/O BUFFER ; 13 BUFFER ADDRESS FOR TRANSFER ; 14 TOTAL BYTE COUNT TO TRANSFER ; 15 BYTE COUNT FOR SECOND PART OF TRANSMISSION OR 0 ; 16 NOT USED ; 17 NOT USED ; 20 NOT USED ; 20$: MOV S.CSR(R4),R2 ;GET RECEIVER CSR ADDRESS ADD #I.FCN+1,R1 ;POINT TO I/O FUNCTION CODE CMPB #IO.INL/256.,(R1) ;CHECK IF TRANSFER FUNCTION BLOS 70$ ;BRANCH ON CONTROL FUNCTION BIT #U2.ONL,U.CW2(R5) ;IS DEVICE ON LINE (INITIALIZED?) BEQ 90$ ;CAN'T TRANSFER IF NOT BIT #DSRDY,(R2) ;IS DATA SET READY? ;**-3 BEQ 90$ ;IF NOT, CAN'T TRANSFER CMPB #IO.RLB/256.,(R1) ;READ LOGICAL? ;**-3 BEQ 40$ ;YES, SERVICE READ REQUEST ; ; FALL THROUGH HERE ON TRANSMIT (WRITE LOGICAL) ; BIS #RTS,(R2) ;ASSERT REQUEST TO SEND ;**-8 MOVB U.SYNC(R5),R0 ;LOAD SYNC CHARACTER MOVB S.ITM(R4),S.CTM(R4) ;INITIALIZE TIMEOUT COUNT MOVB U.NSYN(R5),R3 ;NUMBER OF SYNCS IN LEADER 30$: MOVB R3,U.NSYC(R5) ;LOAD SYNC LEADER COUNT ;**-15 ADD #4,R2 ;POINT TO TRANSMIT CSR BIS #SEND,(R2)+ ;ENABLE TRANSMISSION ; ; ***** NOTE ***** ; ; SINCE TSOM IS SET THROUGHOUT THE TRANSMISSION, DATA LATE ; ERRORS WILL NEVER BE DETECTED. ; ; ***** ***** ; BIC #177400,R0 ;CLEAR HIGH BYTE BIS #TSOM,R0 ;SET TSOM MOV R0,(R2) ;SEND CHAR+TSOM TST -(R2) ;CLEAR DATA LATE ERRORS BIS #DNAEN!TXINTE,(R2) ;ENABLE INTERRUPTS BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES TRANSMISSION ; ; RECEIVE FUNCTION INITIATION ; 40$: ;REFERENCE LABEL MOV R5,R0 ;SET UP TRANSFER VECTOR ;**-4 ADD #U.RBUF,R0 ;RECEIVE TRANSFER INFORMATION HERE MOV U.BUF(R5),(R0)+ ;TRANSFER BIAS MOV U.BUF+2(R5),(R0)+ ;AND OFFSET MOV U.CNT(R5),(R0) ;AND COUNT BIC #SCHSYN,(R2) ;FORCE RE-SYNCHING TSTB 2(R2) ; ENSURE RECEIVE BUFFER CLEAR BIS #STRSYN!RCVENB!SCHSYN,(R2) ; ENABLE RECEIVER BR 180$ ;RETURN - INTERRUPT CODE PROPAGATES RECEIVE ; ;**-8 ; CONTROL FUNCTION INITIATION (INITIATE OR TERMINATE CONTROLLER, ; OR CHANGE OPERATING MODE) ; 70$: BNE 110$ ;IF NOT EQUAL, MODE CHANGE REQUEST CMP (R2)+,(R2)+ ;POINT TO TXCSR BIS #MSTRST,(R2) ;RESET DEVICE TSTB -(R1) ;START FUNCTION? BNE 100$ ;IF NON-ZERO, TERMINATE ; ; DO START FUNCTION INITIATION ; TST U.CW2(R5) ;DEVICE TO BE IN HALF DUPLEX? BPL 80$ ;NO, IF PLUS BIS #HDPX,(R2) ;PUT IN HALF DUPLEX MODE 80$: MOV #INITMD,R0 ;GET WORD SIZE, SYNC MODE BISB U.SYNC(R5),R0 ;OR IN SYNC CHARACTER MOV R0,-(R2) ;INITIALIZE DEVICE PARAMETERS BIS #STRSYN!TRMRDY!SCHSYN,-(R2) ;NOW INITIALIZE CONTROLLER MOV R5,UNITBL(R3) ;INITIALIZE UCB ADDRESS IN UNIT TABLE BIS #U2.ONL,U.CW2(R5) ;MARK UNIT ON LINE BR 160$ ;RETURN SUCCESSFUL ; ; CAN'T ESTABLISH COMMUNICATIONS ; 90$: MOV #IE.DNR&377,R0 ;SAY CAN'T INITIALIZE DEVICE (NOT READY) BR 170$ ;DO I/O DONE ; ; FUNCTION WAS TERMINATE LINE ; 100$: BIC #^C,U.CW2(R5) ;CLEAR OPERATING STATUS CLR UNITBL(R3) ;UNIT TABLE CLEARED OF UCB BR 160$ ;RETURN SUCCESSFUL STATUS ; ; SERVICE DEVICE MODE CHANGE REQUEST ; 110$: BITB #IO.HDX,-(R1) ;SUBFUNCTION SAY HALF DUPLEX? BEQ 120$ ;IF ZERO, NO BIS #U2.HDX,U.CW2(R5) ;SAY HALF DUPLEX CHARACTERISTIC 120$: BITB #IO.FDX,(R1) ;SET MODE TO FULL DUPLEX? BEQ 150$ ;DON'T SET FULL DUPLEX BIT #U2.LIN,U.CW2(R5) ;IS LINK FULL DUPLEX? BEQ 140$ ;IF SO, RUN FULL DUPLEX 130$: MOV #IE.IFC&377,R0 ;MARK AS ILLEGAL FUNCTION BR 170$ ;AND TERMINATE 140$: BIC #U2.HDX,U.CW2(R5) ;PUT IN FULL DUPLEX IN UCB 150$: BITB #IO.SYN,(R1) ;SYNC CHARACTER SPECIFIED? BEQ 160$ ;NO, IF NOT SET MOVB I.PRM-I.FCN(R1),U.SYNC(R5) ;MARK NEW SYNC CHARACTER DWSUCC: ;REFERENCE LABEL 160$: MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS DWFIN: ;REFERENCE LABEL 170$: CLRB S.STS(R4) ;CLEAR CONTROLLER STATUS BICB #US.BSY,U.STS(R5) ;MARK UNIT IDLE, ALSO MOV R0,-(SP) ;SAVE STATUS WORD 1 MOV S.PKT(R4),-(SP) ;SAVE OLD PACKET ADDRESS CALL DWINIT ;INITIATE NEXT PACKET MOV (SP)+,R3 ;GET OLD PACKET ADDRESS MOV I.PRM+4(R3),R1 ;RETURN REQUESTED ITEM COUNT MOV (SP)+,R0 ;RESTORE STATUS WORD 1 CALLR $IOFIN ;TERMINATE OLD PACKET 180$: RETURN ; ; ; POWER FAIL SERVICE ; DUPWRF: ;REFERENCE LABEL CLRB S.CTM(R4) ;DISABLE DEVICE TIMEOUTS ;**-8 MOV #IE.DNR&377,R0 ;PUT ERROR CODE IN R0 FOR DWTMO BR DWTMO ;FINISH I/O ABORT ; ;**-3 ; I/O CANCELLATION SERVICE ; ; INPUTS: ; R0=I/O PACKET ADDRESS ; R1=TCB ADDRESS OF TASK TO CANCEL ; R4=SCB ADDRESS ; R5=UCB ADDRESS DWCANC: ;;;REFERENCE LABEL CMP R1,I.TCB(R0) ;;;CANCEL FOR THIS TASK? ;**-7 BNE 180$ ;;;JUST RETURN IF NOT CMPB #IO.WLB/256.,I.FCN+1(R0) ;;;TRANSMIT FUNCTION? BEQ 180$ ;;;LET TRANSMIT FINISH TST U.RCNT(R5) ;;;RECEIVER FINISHED? BLE 180$ ;;;RETURN IF YES BIC #RCVENB!SCHSYN,@S.CSR(R4) ;DISABLE RECEIVER MOV #IE.ABO&377,R0 ;;;PUT ERROR CODE IN R0 FOR DWTMO BR DWTMO ;;;FINISH OFF RECEIVE PACKET ; ;**-4 ; TIMEOUT SERVICE ROUTINE ; ; INPUTS: ; ; R0 = DEVICE TIMEOUT STATUS 'IE.DNR' ; R3 = CONTROLLER INDEX ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; DWTMO: ;;;REFERENCE LABEL MOV S.CSR(R4),R4 ;GET RECEIVER CSR BIC #TXINTE!SEND!DNAEN,4(R4) ;;;DISABLE TRANSMITTER BIC #RTS,(R4) ;;;TURN OFF CARRIER MTPS #0 ;;;ALLOW INTERRUPTS 210$: JMP DWTXND ;WAIT FOR SOFTWARE TIMEOUT  .DSABL LSB ; ; **- $XWINP - DUP-11 INPUT INTERRUPT SERVICE ; $XWINP:: ;;;REFERENCE LABEL INTSV$ XW,PR5,D$$W11 ;;;GENERATE INTERRUPT SAVE CODE CALL DWSET ;;;SET CSR IN R4, UCB IN R5 BIC #STRSYN,(R4)+ ;;; EXIT STRIP SYNC MODE ;**-11 MOV (R4),R4 ;;;CONTENTS OF RCV BUFFER IN R4 .IF DF M$$MGE ; RC024 ;**-12 MOV KISAR6,-(SP) ;;;SAVE CURRENT MAPPING MOV U.RBUF(R5),KISAR6 ;;;MAP TO USER BUFFER MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER MOV (SP)+,KISAR6 ;;;RESTORE CURRENT MAPPING .IFF MOVB R4,@U.RBUF+2(R5) ;;;STORE BYTE IN USER BUFFER .IFTF DEC U.RCNT(R5) ;;;SEE IF COUNT SATISFIED BEQ 30$ ;;;YES, IF EQUAL INC U.RBUF+2(R5) ;;;BUMP BYTE ADDRESS .IFT BIT #20000,U.RBUF+2(R5) ;;;OVERFLOWED 4K BOUNDARY? BEQ 20$ ;;;NO, IF ZERO BIC #20000,U.RBUF+2(R5) ;;;CLEAR OVERFLOW BIT ADD #200,U.RBUF(R5) ;;;BUMP BIAS .ENDC ;**-10 20$: RETURN ;;;EXIT FROM INTERRUPT ; ; REQUEST SATISFIED ; 30$: ;REFERENCE LABEL MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS ;**-31 BIC #RCVENB,@S.CSR(R4) ;;;DISABLE RECEIVER CALL $FORK ;;;GO TO FORK LEVEL JMP DWSUCC ;COMPLETE SUCCESSFUL I/O ; ; **- $XWOUT - TRANSMITTER INTERRUPT SERVICE ; $XWOUT:: ;;;REFERENCE LABEL INTSV$ XW,PR5,D$$W11 ;;;GENERATE INTERRUPT SAVE CODE CALL DWSET ;;;SET RECEIVE CSR IN R4, UCB IN R5 ADD #4,R4 ;;;POINT TO TX CSR TST (R4)+ ;;;DATA NOT AVAILABLE? BPL 10$ ;;;NO, IF NOT SET ; ; CHECK DATA LATE ; TSTB -2(R4) ;;;TRANSMITTER DONE SET? ;**-21 BPL 60$ ;;;IF NOT, DISMISS INTERRUPT 10$: BIT #CTS,-6(R4) ;;;CLEAR TO SEND SET? BEQ 20$ ;;;IF NOT, SEND A SYNC TSTB U.NSYC(R5) ;;;SYNC COUNT ZERO? BEQ 30$ ;;;IF YES, TRANSMIT DATA DECB U.NSYC(R5) ;;;DECREMENT SYNC LEADER COUNT BLE 30$ ;;;IF LE, TRANSMIT DATA 20$: MOVB U.SYNC(R5),(R4) ;;;SEND A SYNC CHARACTER BR 50$ ;;;EXIT ; ; SET UP AND TRANSMIT A BYTE ; 30$: DEC U.CNT(R5) ;;;CHECK COUNT (0 NOT VALID) BGE 40$ ;;;IF NOT, CONTINUE TST U.CW2(R5) ;;;IN HALF DUPLEX? BPL 80$ ;;;IF NOT, NO TURNAROUND CMP #-3,U.CNT(R5) ;;;SENT TWO MARKS? ;**-8 BGE 70$ ;;;IF SO, TURN LINE AROUND MOVB #-1,(R4) ;;;OUTPUT A MARK BR 50$ ;;;DISMISS INTERRUPT 40$: CALL $GTBYT ;;;GET NEXT BYTE FROM BUFFER MOVB (SP)+,(R4) ;;;OUTPUT CHARACTER 50$: MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS BACK MOVB S.ITM(R4),S.CTM(R4) ;;;RESET TIMEOUT COUNT 60$: BR DWSXT ;;;EXIT FROM INTERRUPT 70$: BIC #SEND,-(R4) ;;;DON'T IDLE SYNC TST -(R4) ;;;CLEAR RECEIVE DONE AND ERROR BIC #SCHSYN!RTS,-(R4) ;;;TURN OFF CARRIER BIS #SCHSYN,(R4) ;;;FORCE RESYNCHING ;**-7 ADD #6,R4 ;;;POINT TO TRANSMIT BUFFER ;**-3 80$: BIC #TXINTE!DNAEN!SEND,-(R4) ;;;DISABLE TRANSMITTER CALL $FORK ;;;CREATE SYSTEM PROCESS MOV #IS.SUC&377,R0 ;RETURN SUCCESSFUL STATUS ;**-3 DWTXND: ;REFERENCE LABEL ;**-3 MOV U.SCB(R5),R4 ;RESTORE SCB TO R4 ;**-10 JMP DWFIN ;MARK COMPLETION ; ; DWSET - SET UP REGISTER R4 WITH CSR ADDRESS, R5 WITH ; UCB ADDRESS. UNIT NUMBER IN LOW ORDER 4 BITS OF UNIT. ;¢ DWSET: ;;;REFERENCE LABEL TST R5 ;;;TEST FOR VALID UCB ADDRESS BEQ 10$ ;;;IF NO UCB, TROUBLE BIT #U2.ONL,U.CW2(R5) ;;;UNIT ON LINE? BEQ 10$ ;;;IF NOT ON LINE, CAN'T TRANSFER MOV U.SCB(R5),R4 ;;;FIRST GET SCB ADDRESS MOV S.CSR(R4),R4 ;;;NOW DEVICE CSR ADDRESS RETURN ;;;AND NOW RETURN 10$: TST (SP)+ ;;;CLEAR STACK OF RETURN ADDRESS DWSXT: JMP $INTXT ;;;DISMISS INTERRUPT .END ¢Í:ÀkQ ›c, .TITLE IPMAP ; ; AREA TO READ PCS MAP INTO BY ISA FORTRAN SUBROUTINES ; NMOD=13 IPMAP:: .BLKW NMOD*N$$PCS*4 .WORD 0 $I=0 IPMAPF:: .REPT N$$PCS .WORD $I*4*NMOD ; OFFSET IN IPMAP FOR THIS CONTROLLER $I=$I+1 .ENDR .IF DF I$$PUN LGIPMP==NMOD * N$$PCS * 4 * 2 ;BYTE LENGTH OF MAP ENTRY .IFF LGIPMP==NMOD * 4 * 2 .ENDC .PCSBS==I$$PB0 ; GLOBALLY DEFINE BASE ADDRESS .PCSNC==N$$PCS ;GLOBALLY DEFINE NUMBER OF CONTROLLERS .IIF DF I$$PUN,.PCSNC==1;(WE WANT NUMBER OF PERCEIVED CONTROLLERS) .END ÓhLkQ ›c, .TITLE DRCLI .IDENT /01.09/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.09 ; ; M. S. FOX 27-JAN-81 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; M. S. HARVEY 21-APR-81 ; MSH165 -- MOVE $STCLI FROM MODULE DRSUB INTO THIS ; MODULE SO THAT IT CAN BE EXTERNAL TO THE ; EXECUTIVE IF DIRECTIVE PARTITIONS SUPPORTED. ; $STCLI ORIGINALLY WRITTEN BY M. S. FOX. ; ; M. S. HARVEY 10-SEP-81 ; MSH188 -- CORRECT MANIPULATION OF PROTECTION UIC BY ; ESTABLISHING CORRECT MULTIUSER PROTECTION ; CONDITIONALIZATION ; ; M. S. FOX 15-SEP-81 ; ; MF225 -- FIX $STCLI HANDLING OF CP.RST, AND DO NOT ; ALLOW A CLI TO BE SET IF THE TTY IS LOGGED OFF ; AND CP.LGO IS NOT SET. ; ; M. S. HARVEY 28-OCT-81 ; MSH198 -- CLEAN UP SOME CODE ;+ ; **-$DRCLI-SET CLI / GET CLI INFO / DECLARE CMD ARRIVAL AST DIRECTIVES ; ; THIS MODULE CONTAINS THE GET CLI INFORMATION AND SET CLI ; DIRECTIVES. IT ALSO GETS CALLED BY DRDSP FOR THE DECLARE ; COMMAND ARRIVAL AST DIRECTIVE, BUT IMMEDIATEDLY JUMPS TO ; THE $CAAST ENTRY POINT OF THE DRPUT MODULE FOR PROCESSING. ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK ; R3=ADDRESS OF THE SECOND WORD IN THE DPB ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK ; ;- .IF DF A$$CLI  .IF DF M$$CLI .ERROR ;CANNOT DEFINE BOTH M$$CLI AND A$$CLI .ENDC ;M$$CLI .MCALL PKTDF$,UCBDF$ PKTDF$ ;DEFINE CPB OFFSETS UCBDF$ ;DEFINE UCB OFFSETS ASSUME UM.CLI,36 ;BITS TO INDICATE TERMINALS CLI ASSUME C.PTCB,0 ;TCB ADDRESS MUST BE AT OFFSET ZERO OF CPB $DRCLI::MOVB -(R3),R0 ;GET DPB SIZE CMPB #5,(R3)+ ;IS IT SET CLI (SCLI$) BEQ SCLI ;IF EQ YES, PROCESS SCLI$ DIRECTIVE .IF DF A$$TRP CMPB #2,R0 ;IS IT DECLARE CMD ARRIVAL AST (SCAA$) BNE 10$ ;IF NE NO JMP $CAAST ;PROCESS DIRECTIVE IN DRPUT .ENDC ;A$$TRP 10$: CMPB #7,R0 ;IS IT GET CLI INFORMATION (GCII$) BEQ GCII ;IF EQ YES, PROCESS GCII$ DRSTS D.RS99 ;ILLEGAL DPB SIZE ;+ ; **-SCLI- SET A TERMINAL'S CLI ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SET THE CLI OF THE ; CURRENT TASK'S TI: TERMINAL (OR SPECIFIED TERMINAL) TO BE THE ; SPECIFIED CLI. SYSTEM MESSAGES INFORMING BOTH THE PREVIOUS AND ; NEW CLIS OF THE CHANGE ARE SENT TO THE CLIS IF THEY DESIRE THEM. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(173.),DPB SIZE(5.) ; WD. 01 -- ASCII NAME OF THE TERMINAL WHOSE CLI SHOULD BE SET ; WD. 02 -- OCTAL UNIT NUMBER OF TERMINAL ; WD. 03 -- FIRST HALF OF RAD50 NAME OF THE DESIRED CLI ; WD. 04 -- SECOND HALF OF THE RAD50 NAME OF THE DESIRED CLI ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE ; LENGTH IS ILLEGAL ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IS THE ; ISSUING TASK IS NOT PRIVILEGED. ; DIRECTIVE STATUS OF 'D.RS92' IS RETURNED IF AN ; NON-EXISTANT OR NON-TERMINAL DEVICE IS SPECIFIED. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF THE SPECIFIED ; CLI DOES NOT EXIST. ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF THERE IS ; INSUFFICIENT POOL SPACE. ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF THE ; MF225 ; TERMINAL IS LOGGED OFF, AND CP.LGO IS CLEAR ; MF225 ; ;- .ENABL LSB  ;MSH198 SCLI: BIT #T3.PRV!T3.CLI,T.ST3(R5) ;CAN TASK USE THIS DIRECTIVE? BEQ 99$ ;IF EQ NO ;MSH198 TST (R3) ;IS A TERMINAL SUPPLIED ;**-1 BNE 15$ ;IF NE YES ;MSH198 MOV T.UCB(R5),R0 ;GET CURRENT TASK'S TI: ;**-1 CMP (R3)+,(R3)+ ;SKIP DEV NAME AND UNIT NUMBER FIELDS BR 25$ ; ;MSH198 15$: MOV (R3)+,-(SP) ;GET ASCII TERMINAL NAME ;MSH198 MOV (R3)+,-(SP) ;GET UNIT NUMBER ;**-2 MOV SP,R1 ;POINT TO THEM ON STACK MOV R3,-(SP) ;SAVE DPB POINTER CALL $GTUCB ;GET TERMINALS UCB ADDRESS BCS 120$ ;IF CS, DEVICE DOES NOT EXIST ;MSH198 MOV R5,R0 ;COPY UCB ADDRESS ;**-1 CALL $MPLND ;FOLLOW REDIRECT CHAIN BIT #DV.TTY,U.CW1(R0) ;IS DEVICE A TERMINAL BEQ 120$ ;IF EQ NO ;MSH198 MOV (SP)+,R3 ;POINT TO CLI NAME IN CPB ;**-1 CMP (SP)+,(SP)+ ;CLEAN STACK 25$: CALL $STCLI ;SET THE TERMINAL'S CLI ;MSH198 BCC 60$ ;IF CC, SUCCESS ;**-1 TST R0 ;IDENTIFY ERROR BEQ 99$ ;IF EQ PRIVILEGE VIOLATION ;MSH198 BMI 110$ ;IF MI, CLI NOT IN SYSTEM ;MSH198  DEC R0 ;ALLOCATION FAILURE?? ;MSH198 BNE 35$ ;IF NE YES ; MF225 DRSTS D.RS8 ;TERMINAL NOT LOGGED ON, CP.LGO CLEAR ; MF225 35$: DRSTS D.RS1 ;ALLOCATION FAILURE ; MF225 60$: RETURN ;SUCCESS ;**-6 ;+ ; **-GCII-GET CLI INFORMATION DIRECTIVE ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO FILL A BUFFER IN THE CURRENT ; TASK SPACE WITH INFORMATION ABOUT HIS OWN OR A SPECIFIED CLI. THE ; ISSUING TASK MUST BE PRIVILEGED TO GET INFORMATION ABOUT A CLI ; WHICH IS NOT THE CLI OF ITS TI: TERMINAL. IF THE BUFFER IS NOT ; LONG ENOUGH TO CONTAIN ALL THE DATA, IT IS FILLED FROM LEFT ; TO RIGHT WITH AS MUCH DATA AS WILL FIT. NO INDICATION WILL ; BE GIVEN TO THE TASK THAT ITS BUFFER IS TOO SHORT. THIS ALLOWS ; NEW DATA ITEMS TO BE RETURNED BY FUTURE VERSIONS OF THIS DIRECTIVE, ; SINCE OLD TASKS WILL CONTINUE TO WORK. THEY JUST WILL NOT SEE ; THE NEW DATA. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(173.),DPB SIZE(7). ; WD. 01 -- ADDRESS OF BUFFER IN CURRENT TASK'S SPACE ; WD. 02 -- LENGTH OF THE TASK'S BUFFER ; WD. 03 -- FIRST HALF OF NAME OF CLI TO RETURN DATA ON ; WD. 04 -- SECOND HALF OF NAME OF CLI TO RETURN DATA ON ; WD. 05 -- ASCII NAME OF TERMINAL WHOSE CLI SHOULD BE USED ; WD. 06 -- OCTAL UNIT NUMBER OF TERMINAL ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS99' IS RETURNED IF THE ; DPB LENGTH IS INVALID. ; DIRECTIVE STATUS OF 'D.RS98' IS RETURNED IF THE BUFFER ; IS NOT ENTIRELY WITHIN THE USER'S TASK SPACE. ; DIRECTIVE STATUS OF 'D.RS81' IS RETURNED IF BOTH THE ; NAMES OF THE CLI AND TERMINAL ARE SUPPLIED. ; DIRECTIVE STATUS OF 'D.RS2' IS RETURNED IF THE ; SPECIFIED CLI DOES NOT EXIST. ; DIRECTIVE STATUS OF 'D.RS92' IS RETURNED IF THE ; SPECIFIED DEVICE IS NOT A TERMINAL. ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF A NON-PRIV ; TASK ATTEMPTS TO GET INFO ON A CLI WHICH IS ; NOT ASSOCIATED WITH ITS TI: ; ;- ; ; THE FORMAT OF THE INFORMATION BUFFER IN THE TASK'S ADDRESS SPACE IS: ; ; +---------------------------------------+ ; ! NAME OF CLI ! ; ! (2 WORDS) ! ; !---------------------------------------! ; ! CLI STATUS WORD FROM CPB ! ; !---------------------------------------! ; ! NAME OF TASK SERVING AS CLI ! ; ! (2 WORDS) ! ; !---------------------------------------! ; ! TERMINAL'S U.CW2 ! ; !---------------------------------------! ; ! TERMINAL'S PROTECTION UIC ! ; !---------------------------------------! ; ! TERMINAL'S CURRENT UIC ! ; !---------------------------------------! ; ! ! ; ! DEFAULT PROMPT STRING ! ; ! (1 BYTE LENGTH, FOLLOWED BY ! ; ! 31. BYTES STRING) ! ; +---------------------------------------+ ; ; GCII: MOV (R3)+,R0 ;GET ADDRESS OF BUFFER MOV (R3)+,R1 ;GET LENGTH OF BUFFER MOV R1,-(SP) ;SAVE LENGTH CALL $ACHKW ;ADDRESS CHECK BUFFER MOV R5,R2 ;COPY CURRENT TASK'S TCB ADDRESS MOV T.UCB(R2),R5 ;POINT TO TASK'S TI: TST (R3) ;WAS A CLI NAME SPECIFIED BEQ 10$ ;IF EQ NO TST 4(R3) ;WAS A TERMINAL SPECIFIED BNE 100$ ;IF NE YES CALL $FNCLI ;FIND THE SPECIFIED CLI BCS 110$ ;IF CS, CLI DOES NOT EXIST MOV U.MUP(R5),R3 ;GET WORD CONTAINING TI:S CLI INDICATOR BIC #^CUM.CLI,R3 ;ISOLATE CLI INDICATOR BITS CMP R3,R1 ;LOOKING AT TI:S CLI?? BEQ 200$ ;IF EQ YES BR 30$ ;REQUIRE PRIVILEGE 10$: CMP (R3)+,(R3)+ ;SKIP OVER CLI NAME IN DPB TST (R3) ;TERMINAL SPECIFIED BEQ 20$ ;IF EQ NO MOV (R3)+,-(SP) ;PUT NAME ON STACK MOV (R3)+,-(SP) ;PUT UNIT NUMBER ON STACK MOV SP,R1 ;POINT TO UNIT NUMBER AND NAME MOV R0,-(SP) ;SAVE USERS BUFFER ADDRESS CALL $GTUCB ;GET UCB ADDRESS BCS 120$ ;IF CS, DEVICE DOES NOT EXIST MOV R5,R0 ;COPY UCB ADDRESS MOV R2,-(SP) ;SAVE R2 CALL $MPLND ;FOLLOW REDIRECT CHAIN MOV (SP)+,R2 ;RESTORE R2 MOV R0,R5 ;PUT UCB ADDRESS BACK IN R5 MOV (SP)+,R0 ;RESTORE BUFFER ADDRESS BIT #DV.TTY,U.CW1(R5) ;IS DEVICE A TERMINAL BEQ 120$ ;IF EQ NO CMP (SP)+,(SP)+ ;CLEAN STACK 20$: MOV U.MUP(R5),R4 ;GET CLI INDICATOR FROM UCB BIC #^CUM.CLI,R4 ;ISOLATE IT MOV $CPTBL(R4),R4 ;POINT TO THE CPB CMP T.UCB(R2),R5 ;LOOKING AT CURRENT TASK'S TI: BEQ 200$ ;IF EQ YES, DO NOT NEED PRIVILEGE 30$: BIT #T3.PRV!T3.CLI,T.ST3(R2) ;IS CURRENT TASK PRIVILEGED OR CLI BNE 200$ ;IF NE YES ;MSH198 99$: DRSTS D.RS16 ;PRIVILEGE VIOLATION ;MSH198 100$: DRSTS D.RS81 ;CANNOT SPECIFY BOTH TERMINAL AND CLI ;**-2 110$: DRSTS D.RS2 ;CLI DOES NOT EXIST 120$: DRSTS D.RS92 ;ILLEGAL DEVICE SPECIFIED ; 200$: CALL $RELOC ;RELOCATE USERS INFO BUFFER MOV (SP)+,R3 ;GET LENGTH OF BUFFER MOV R1,KISAR6 ;MAP BUFFER IN TASK SPACE MOV R4,-(SP) ;SAVE CPB ADDRESS ASR R3 ;CONVERT TO WORD OFFSET SUB #2,R3 ;SPACE LEFT IN BUFFER FOR CLI NAME BLT 210$ ;IF LT NO MOV C.PNAM(R4),(R2)+ ;PUT NAME IN BUFFER MOV C.PNAM+2(R4),(R2)+ ;SECOND HALF DEC R3 ;SPACE IN BUFFER FOR CPB STATUS WORD BLT 210$ ;IF LT NO MOV C.PSTS(R4),(R2)+ ;COPY STATUS WORD INTO BUFFER SUB #2,R3 ;SPACE LEFT IN BUFFER FOR TASK NAME BLT 210$ ;IF LT NO MOV (R4),R4 ;POINT TO CLI'S TCB MOV T.NAM(R4),(R2)+ ;COPY FIRST HALF OF TASK NAME MOV T.NAM+2(R4),(R2)+ ;AND SECOND HALF DEC R3 ;SPACE LEFT IN BUFFER FOR TERMINAL'S U.CW2 BLT 210$ ;IF LT NO MOV U.CW2(R5),(R2)+ ;COPY U.CW2 INTO BUFFER DEC R3 ;SPACE FOR PROTECTION UIC?? BLT 210$ ;IF LT NO ;MSH188 .IF DF M$$MUP ;MSH188 ;MSH188 MOV U.LUIC(R5),(R2)+ ;COPY PROTECTION UIC ;MSH188 .IFF ;MSH188 ;MSH188 MOV U.UIC(R5),(R2)+ ;ESTABLISH PROTECTION UIC ;MSH188 ;MSH188 .ENDC ;MSH188 ;MSH188 DEC R3 ;SPACE FOR CURRENT UIC BLT 210$ ;IF LT NO MOV U.UIC(R5),(R2)+ ;COPY CURRENT UIC SUB #16.,R3 ;ENOUGH ROOM LEFT FOR PROMPT STRING BLT 210$ ;IF LT NO MOV (SP),R4 ;GET CPB ADDRESS BACK MOVB C.PDPL(R4),R5 ;GET LENGTH OF DEFAULT PROMPT DEC R5 ;DO NOT RETURN ZERO AT END OF PROMPT MOVB R5,(R2)+ ;PUT LENGTH IN BUFFER BEQ 210$ ;IF EQ, NO PROMPT STRING ADD #C.PRMT,R4 ;POINT TO START OF STRING 205$: MOVB (R4)+,(R2)+ ;COPY CHARACTER DEC R5 ;MORE CHARS TO COPY? BGT 205$ ;IF GT YES 210$: DRSTS +1 ;SUCCESS .DSABL LSB ;MSH198 ; MF209 ;+ ; MF209 ; **-$STCLI-ROUTINE TO SET A TERMINAL'S CLI ; MF209 ; **-$STCL1-ROUTINE TO SET A TERMINAL'S CLI (ALTERNATE ENTRY) ;MSH165 ; ; MF209 ; THIS ROUTINE SETS THE CLI OF THE SPECIFIED TERMINAL FOR BOTH THE ; MF209 ; SCLI$ DIRECTIVE AND MCR. IF EITHER THE PREVIOUS OR NEW CLI HAVE ; MF209 ; THE CP.MSG BIT SET IN THEIR CPB'S, A MESSAGE PACKET IS CREATED AND ; MF209 ; PASSED TO THEM TO INFORM THEM OF THE CHANGE. NOTE THAT IF AN ALLOCATIO; MF209 ; FAILURE OCCURS WHEN ACTIVATING THE NEW CLI AFTER QUEUEING A MESSAGE ; MF209 ; TO IT, THE ERROR IS IGNORED SINCE IT WOULD BE IMPOSSIBLE TO UNWIND ; MF209 ; ACTIONS WHICH MAY HAVE ALREADY BEEN COMPLETED, SUCH AS DEACTIVATING ; MF209 ; THE PREVIOUS CLI AFTER A CALL TO $EXRQN. THE ONLY DRAWBACK TO THIS IS ; MF209 ; THAT THE NEW CLI WILL NOT GET THE MESSAGE IMMEDIATELY. THE BUFFER ; MF209 ; WILL BE LINKED IN ITS QUEUE, BUT THE CLI WILL NOT RECEIVE IT UNTIL IT ; MF209 ; GETS ACTIVATED AT A FUTURE POINT BY A COMMAND ARRIVAL OR ANOTHER ; MF209 ; SYSTEM MESSAGE. ; MF209 ; ; MF209 ; INPUTS: ; MF209 ; ; MF209 ; R0=UCB ADDRESS OF TERMINAL TO SET ; MF209 ; R3=POINTER TO THE NAME OF THE NEW CLI ($STCLI ONLY) ;MSH165 ; ; MF209 ; OUTPUTS: ; MF209 ; ; MF209 ; C=1 CLI COULD NOT BE SET ; MF209 ; R0=2 IF AN ALLOCATION FAILURE OCCURED ; MF225 ; R0=1 IF THE TERMINAL IS LOGGED OFF, AND CP.LGO IS CLEAR; MF225 ; SO THE CLI DOESN'T ACCEPT CMDS FROM LOGGED OFF TTY; MF225 ; R0=0 IF THE CP.RST BIT IS SET, AND A TASK OTHER THAN ; MF209 ; THE CLI IS ATTEMPTING TO SET A TERMINAL TO IT ; MF209 ; R0=-1 IF THE CLI DOES NOT EXIST ; MF209 ; C=0 THE CLI WAS SUCCESSFULLY SET UP FOR THE SPECIFIED TERMINAL ; MF209 ; ; MF209 ; ALL REGISTERS ARE MODIFIED ; MF209 ;  ; MF209 ;- ; MF209 ; MF209 ; ; MF209 MSGLEN=16 ;LENGTH OF MESSAGE PACKETS ; MF209 ; ; MF209 ;MSH165 .IF NDF D$$PAR ;MSH165 ;MSH165 $STCLI::CALL $FNCLI ;FIND THE SPECIFIED CLI ;MSH165 ;MSH165 .ENDC ;MSH165 ;MSH165 $STCL1::MOV #-1,-(SP) ;SET EXIT STATUS WORD FOR THIS ROUTINE ; MF209 BCS 40$ ;IF CS, CLI DOES NOT EXIST ;MSH165 INC (SP) ;SET EXIT STATUS TO RETURN R0=0 ;MSH165 MOV U.MUP(R0),R3 ;GET WORD CONTAINING CURRENT CLI ;MSH165 BIC #^CUM.CLI,R3 ;ISOLATE CLI BITS ;MSH165 MOV $CPTBL(R3),R3 ;GET CPB ADDRESS ;MSH165 MOV C.PSTS(R3),$TEMP2 ;SAVE CURRENT CLI'S STATUS WORD ;MSH165 BIT #CP.RST,$TEMP2 ;DOES CURRENT CLI HAVE RESTRICTED ACCESS; MF209 BEQ 3$ ;IF EQ NO ; MF225 CMP $TKTCB,(R3) ;IS THE CLI SWITCHING TTY AWAY FROM ITSE; MF225 BNE 80$ ;IF NE NO ; MF225 3$: BIT #CP.RST,C.PSTS(R4) ;IS ACCESS RESTRICTED TO NEW CLI ; MF225 BEQ 5$ ;IF EQ NO ; MF209 CMP $TKTCB,(R4) ;IS SETTING TASK THE CLI ITSELF ; MF209 BNE 80$ ;IF NE NO ; MF209 5$: INC (SP) ;SET EXIT STATUS TO RETURN R0=1 ; MF209 ;MSH198 .IF DF M$$MUP ;MSH198 ;MSH198 BIT #U2.LOG,U.CW2(R0) ;IS TERMINAL LOGGED IN ; MF225 BEQ 7$ ;IF EQ YES ; MF225 BIT #CP.LGO,C.PSTS(R4) ;DOES CLI ACCEPT CMDS FROM LOGGED OFF; MF225 BEQ 80$ ;IF EQ NO ; MF225 ;MSH198 .ENDC ;MSH198 ;MSH198 7$: INC (SP) ;SET EXIT STATUS TO RETURN R0=2 ; MF225 MOV R1,-(SP) ;SAVE OFFSET TO NEW CLI IN $CPTBL ; MF209 MOV R0,-(SP) ;SAVE UCB ADDRESS ; MF209 CLR R5 ;ASSUME NO MESSAGE FOR NEW CLI ; MF209 BIT #CP.MSG,C.PSTS(R4) ;DOES NEW CLI WANT A MESSAGE ; MF209 BEQ 10$ ;IF EQ NO ; MF209 MOV #MSGLEN,R1 ;GET LENGTH OF MESSAGE ; MF209 CALL $ALOCB ;ALLOCATE A MESSAGE ; MF209 BCS 70$ ;IF CS, NO POOL ; MF209 MOV R0,R5 ;SAVE BUFFER ADDRESS ; MF209 MOV R4,(R0) ;SAVE CPB ADDRESS IN BUFFER ; MF209 10$: BIT #CP.MSG,$TEMP2 ;DOES CURRENT CLI WANT A MESSAGE ; MF209 BEQ 25$ ;IF EQ NO ; MF209 MOV #MSGLEN,R1 ;GET MESSAGE LENGTH ; MF209 CALL $ALOCB ;ALLOCATE A MESSAGE BUFFER ; MF209 BCS 60$ ;IF CS, NO POOL ; MF209 MOV R0,R1 ;COPY BUFFER ADDRESS ; MF209 MOV (SP),R2 ;GET UCB ADDRESS ; MF209 MOV R3,R4 ;GET ADDRESS OF CURRENT CPB ; MF209 CALL STMSG ;SET UP MESSAGE BUFFER ; MF209 MOVB #CM.RMT,7(R1) ;INSERT MESSAGE CODE ; MF209 MOV R1,-(SP) ;SAVE BUFFER ADDRESS ; MF209 MOV (R4),R0 ;GET CLI'S TCB ADDRESS ; MF209 CALL $QCLIL ;QUEUE BUFFER AND REQUEST CLI ; MF209 BCC 20$ ;IF CC, OK ; MF209 BNE 50$ ;IF NE, ALLOCATION FAILURE ; MF209 ; ; MF209 ; AFTER THIS POINT, COMLETE ERROR RECOVERY IS IMPOSSIBLE, BECAUSE THE ; MF209 ; TASK MAY JUST HAVE BEEN ACTIVATED INSTEAD OF BEING MERELY UNSTOPPED. ; MF209 ; ; MF209 20$: TST (SP)+ ;DON'T NEED BUFFER ADDRESS ANYMORE ; MF209 25$: MOV R5,R1 ;POINT TO MESSAGE FOR NEW CLI ; MF209 BEQ 30$ ;IF EQ, NO MESSAGE FOR NEW CLI ; MF209 MOV (R1),R4 ;POINT TO NEW CPB ; MF209 MOV (SP),R2 ;GET UCB ADDRESS ; MF209 CALL STMSG ;SET UP MESSAGE ; MF209 MOVB #CM.LKT,7(R1) ;INSERT MESSAGE CODE ; MF209 MOV (R4),R0 ;GET CLI'S TCB ADDRESS ; MF209 CALL $QCLIL ;QUEUE MESSAGE AND REQUEST IT ; MF209 ;DO NOT CHECK ERROR RETURNS ; MF209 30$: MOV (SP)+,R0 ;GET UCB ADDRESS OF TERMINAL ; MF209 MOV (SP)+,R1 ;GET OFFSET TO NEW CLI IN $CPTBL ; MF209 MTPS #PR7 ;;;PREVENT TTDRV FROM ANSWERING PHONE WH; MF209 ;;;CLI SETTING IS INVALID ; MF209 BIC #UM.CLI!UM.DSB,U.MUP(R0) ;;;CLEAR OUT PREVIOUS CLI INDIC; MF209 BIS R1,U.MUP(R0) ;;;SET NEW CLI ; MF209 MTPS #0 ;ALLOW INTERRUPTS ; MF209 CLC ;SUCCESS ; MF209 40$: MOV (SP)+,R0 ;SET EXIT STATUS ; MF209 RETURN ;ALL DONE ; MF209 ; ; MF209 ; ERROR CLEANUP CODE ; MF209 ; ; MF209 ; MF209 ; ERROR WHILE ACTIVATING CURRENT CLI, SO UNLINK AND DEALLOCATE MESSAGE ; MF209 ; ; MF209 50$: MOV #$CLICQ,R0 ;POINT TO CLI COMMAND QUEUE ; MF209 MOV (SP)+,R1 ;POINT TO BUFFER JUST QUEUED ; MF209 CALL $QRMVT ;REMOVE MESSAGE JUST INSERTED IN QUEUE ; MF209 MOV R1,R0 ;COPY POINTER TO MESSAGE ; MF209 MOV #MSGLEN,R1 ;GET ITS LENGTH ; MF209 CALL $DEACB ;DEALLOCATE IT ; MF209 ; ; MF209 ; DEALLOCATE MESSAGE FOR NEW CLI IF IT EXISTS ; MF209 ; ; MF209 60$: MOV R5,R0 ;POINT TO BUFFER FOR NEW CLI ; MF209 BEQ 70$ ;IF EQ, IT DIDN'T WANT ONE ; MF209 MOV #MSGLEN,R1 ;SET LENGTH ; MF209 CALL $DEACB ;DEALLOCATE BUFFER FOR NEW CLI ; MF209 70$: CMP (SP)+,(SP)+ ;CLEAN STACK ; MF209 80$: SEC ;SET ERROR STATUS ; MF209 BR 40$ ;GO TO COMMON EXIT CODE ; MF209 ; MF209 ; ; MF209 ; LOCAL ROUTINE TO SET UP MESSAGE BUFFERS ; MF209 ; ; MF209 ; INPUTS: ; MF209 ; R1=ADDRESS OF MESSAGE BUFFER ; MF209 ; R2=ADDRESS OF TERMINAL UCB ; MF209 ; R4=ADDRESS OF CPB OF CLI TO RECEIVE MESSAGE ; MF209 ; ; MF209 ; OUTPUTS: ; MF209 ; ; MF209 ; NONE ; MF209 ; ; MF209 ; REGISTERS R0, R3 MODIFIED ; MF209 ; ; MF209 ; MF209 STMSG: MOV R1,-(SP) ;SAVE BUFFER ADDRESS ; MF209 MOV R1,R3 ;COPY BUFFER ADDRESS ; MF209 TST (R3)+ ;SKIP LINK WORD ; MF209 MOV (R4),(R3)+ ;SET TCB ADDRESS OF CLI ; MF209 CLR (R3)+ ;ZERO TO INDICATE IT IS A MESSAGE, NOT C; MF209 MOV #MSGLEN,(R3)+ ;PUT LENGTH OF MESSAGE IN BUFFER ; MF209 CLR (R3)+ ;CLEAR TERMINATOR WORD ; MF209 MOV R2,R0 ;COPY UCB ADDRESS ; MF209  MOV (R0),R1 ;POINT TO DCB ; MF209 TST (R1)+ ;POINT TO ADDRESS OF FIRST UCB ; MF209 SUB (R1)+,R0 ;CALC RELATIVE ADDRESS OF UCB ; MF209 MOV (R1)+,(R3)+ ;COPY DEVICE NAME ; MF209 MOV (R1)+,(R3) ;GET LOW UNIT NUMBER FOR DCB ; MF209 MOV (R1),R1 ;GET LENGTH OF UCB ; MF209 CALL $DIV ;CALC RELATIVE UNIT NUMBER ; MF209 ADD R0,(R3)+ ;CALC LOGICAL UNIT NUMBER ; MF209 CLRB -(R3) ;CLEAR STUFF LEFT IN HIGH BYTE ; MF209 MOV (SP)+,R1 ;RESTORE BUFFER ADDRESS ; MF209 RETURN ; ;4 MF209 ; MF209 .ENDC ;A$$CLI .END 4ãƒkQ ›c, .TITLE DRSUB .IDENT /01.20/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.20 ; ; M. S. HARVEY 30-SEP-79 ; ; MODIFIED BY: ; ; M. S. HARVEY 15-AUG-79, 30-SEP-79 ; MSH049 -- ALLOW $DEAGF TO BE MORE GENERAL ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL FLAG USE CONTROL ; FOR SLAVE TASKS  ; ; M. S. FOX 01-FEB-81 ; MF209 -- ADD ROUTINES ALTERNATE CLI SUPPORT ; ; M. S. HARVEY 11-FEB-81 ; MSH148 -- USE SYMBOL FOR LENGTH OF CONTROL BLOCK ; ; M. S. HARVEY 21-APR-81 ; MSH165 -- MOVE $STCLI TO MODULE DRCLI AND REPLACE WITH ; A TRANSFER ROUTINE FOR MCR'S USE IF THE ; DIRECTIVE COMMONS ARE SUPPORTED. ALSO, ADD ; TRANSFER CONTROL FOR THE DISPATCHER. ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; M. S. HARVEY 6-OCT-81 ; MSH194 -- EXTERNALIZE WAITFOR ROUTINE ; ; THIS EXECUTIVE MODULE CONTAINS ROUTINES THAT ORIGINALLY RESIDED ; IN THE DIRECTIVE MODULES INCLUDED IN THE DIRECTIVE COMMON, BUT WERE ; COMMONLY REFERENCED BY OTHER PARTS OF THE EXECUTIVE OR EXTERNAL ; PROGRAMS. ROUTINES ARE MOVED HERE TO ELIMINATE EXCESSIVE MAPPING ; CODE IN THE EXECUTIVE THAT WOULD OTHERWISE BE REQUIRED IN A SYSTEM ; THAT SUPPORTS THE DIRECTIVE COMMON. ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,TCBDF$,HDRDF$,PCBDF$,HWDDF$,ITBDF$ .MCALL UCBDF$ ; MF209 UCBDF$ ;DEFINE UCB OFFSETS ; MF209 PKTDF$ ;DEFINE GROUP GLOBAL OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS ITBDF$ ;DEFINE INTERRUPT TRANSFER BLOCK OFFSETS .IF DF G$$EFN ;+ ; **-$ELGEF-SUBROUTINE TO ELIMINATE A GROUP GLOBAL EVENT FLAG BLOCK ; ; THIS SUBROUTINE UNCONDITIONALLY UNLINKS A GROUP GLOBAL EVENT FLAG BLOCK ; AND DEALLOCATES IT. ; ; INPUTS: ; ; R0=ADDRESS OF BLOCK POINTING TO BLOCK TO BE DEALLOCATED ; R1=ADDRESS OF BLOCK TO BE ELIMINATED ; ; OUTPUTS: ; ; NONE. ;- $ELGEF::MOV (R1),(R0) ;UNLINK THE BLOCK MOV R1,R0 ;SET UP TO DEALLOCATE THE BLOCK MOV #G.LGTH,R1 ; ;MSH148 CALLR $DEACB ;DEALLOCATE THE BLOCK ;**-1 ;+ ; **-$DEAGF-DEACCESS GROUP GLOBAL EVENT FLAGS ; ; THIS ROUTINE DETERMINES IF THE SPECIFIED TASK IS WAITING FOR A ; GROUP GLOBAL EVENT FLAG. IF IT IS, THE ACCESS COUNT IN THE GROUP ; GLOBAL EVENT FLAG BLOCK IS DECREMENTED AND THE BLOCK IS DEALLOCATED ; IF IT IS MARKED FOR DELETE. ; ; INPUTS: ; ; R3=EVENT FLAG MASK ADDRESS ;MSH049 ; R4=TASK HEADER ADDRESS ;MSH049 ; R5=TASK TCB ADDRESS. ;**-1 ; ; OUTPUTS: ; ; NONE. ; ;- ;**-1 $DEAGF::SAVNR ;MSH049 MOVB H.CUIC+1(R4),R4 ;GET GROUP NUMBER ;MSH049 CALL $SRGEF ;SEARCH FOR GROUP GLOBAL EVENT FLAGS ;**-1 BCS 10$ ;IF CS NOT FOUND BIC #1,R3 ;CLR GRP GLOBAL 2ND WORD INDICATOR ;MSH049 CMP R3,R1 ;GROUP GLOBAL EVENT FLAG? ;**-1 BLO 10$ ;IF LO NO SUB #10.,R3 ;POINT TO LINK WORD CMP R3,R1 ;GROUP GLOBAL EVENT FLAG? BHIS 10$ ;IF HIS NO ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 DECB T.GGF(R5) ;DECR GRP GLOBAL USE COUNT FOR TASK ;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 DEC G.CNT(R1) ;DECREMENT ACCESS COUNT BNE 10$ ;IF NE, CAN'T ELIMINATE FLAGS YET BITB #GS.DEL,G.STAT(R1) ;MARKED FOR DELETE? BNE $ELGEF ;ELIMINATE GROUP GLOBAL EVENT FLAG GROUP 10$: RETURN ; ;+ ; **-$SRGEF-SEARCH FOR GROUP GLOBAL EVENT FLAGS ; ; THIS ROUTINE IS CALLED TO SEARCH FOR GROUP GLOBAL EVENT FLAGS ; ; INPUTS: ; ; R4=GROUP NUMBER ; ; OUTPUTS: ; ; C=1 IF SPECIFIED GROUP GLOBAL EVENT FLAGS NOT FOUND ; C=0 IF SPECIFIED GROUP GLOBAL EVENT FLAGS ARE FOUND ; R0=ADDRESS OF WORD POINTING TO BLOCK ; R1=ADDRESS OF THE BLOCK ; ;- .IFTF $SRGEF:: ;REF LABEL .IFT MOV #$GGEF,R1 ;GET ADDRESS OF GROUP GLOBAL EF HEAD 10$: MOV R1,R0 ;SAVE POINTER TO CURRENT BLOCK MOV (R1),R1 ;GET ADDRESS OF NEXT BLOCK BEQ 20$ ;IF EQ END OF LIST CMPB G.GRP(R1),R4 ;IS THIS THE CORRECT BLOCK? BEQ 30$ ;IF EQ YES BLO 10$ ;IF LO KEEP SEARCHING 20$: SEC ;SET CARRY TO INDICATE NOT FOUND 30$: RETURN ; .ENDC ;G$$EFN ;+ ; **-$DRDSE-DECLARE SIGNIFICANT EVENT ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO DECLARE A SIGNIFICANT EVENT. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(35.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ; ; NOTE: THIS DIRECTIVE IS ALSO CALLED AS A SUBROUTINE. ;- $DRDSE::MOV $ACTHD,$RQSCH ;SET DISPATCH TO FRONT OF LIST CLR $SIGFL ;CLEAR TASK WAITING FOR SIGNIFICANT EVENT ;MSH165 .IF NDF A$$PRI ;MSH165 ;MSH165 $DRATP:: ;DEFINE FOR MCR'S SAKE ;MSH165 ;MSH165 .ENDC ;MSH165 ;MSH165 RETURN ;RETURN DIRECTIVE STATUS OF +1 ;+ ; **-$TKWSE-TASK WAITFOR SIGNIFICANT EVENT ; ; THIS ROUTINE IS CALLED TO EXECUTE A WAITFOR SIGNIFICANT EVENT DIRECTIVE ; FOR THE CURRENT TASK FROM WITHIN THE EXECUTIVE. ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; A WAITFOR SIGNIFICANT EVENT DIRECTIVE IS EXECUTED FOR THE ; CURRENT TASK AND A RETURN TO THE CALLER IS EXECUTED. ;- $TKWSE::MOV $TKTCB,R5 ;GET ADDRESS OF CURRENT TASK TCB ;+ ; **-$DRWSE-WAITFOR SIGNIFICANT EVENT ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO SUSPEND THE EXECUTION OF THE ; ISSUING TASK UNTIL THE NEXT SIGNIFICANT EVENT. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(49.),DPB SIZE(1.). ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE LAST WORD IN THE DPB+2. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 WITH A DIRECTIVE STATUS OF +1. ;- $DRWSE::MOV T.ACTL(R5),R0 ;GET TCB ADDRESS OF NEXT TASK MOV R5,$SIGFL ;SET TASK WAITING FOR SIGNIFICANT EVENT CALLR $SETRQ ;FORCE REDISPATCHING OF THE PROCESSOR ;+ ; **-$MPXC1-MAP THE FIRST EXECUTIVE COMMON ;MSH165 ; **-$MPXC2-MAP THE SECOND EXECUTIVE COMMON ;MSH165 ; ;**-1 ; THIS COROUTINE IS CALLED TO PRESERVE KERNEL APR 5 FOR REMAPPING ; ONE OF THE EXECUTIVE COMMONS. THE CALLER IS CALLED AS A COROUTINE ;MSH165 ; WITH ONE OF THE EXECUTIVE COMMONS MAPPED. WHEN THE CALLER EXECUTES ;MSH165 ; A RETURN, CONTROL IS PASSED TO THIS COROUTINE WHERE KERNEL APR 5'S ;MSH165 ; ORIGINAL CONTENTS ARE RESTORED. ;**-3 ; ; INPUTS: ; ; (SP) HAS THE RETURN ADDRESS TO THE CALLER ; ; OUTPUTS: ; ; THE CALLER IS CALLED WITH THE DESIRED EXECUTIVE COMMON MAPPED. ;MSH165 ; ;**-1 ;- ;MSH165 .ENABL LSB ;MSH165 .IF DF D$$PAR&M$$MGE $MPXC1::MOV (SP),-(SP) ;COPY RETURN PC ;MSH165 MOV $XCOM1,-(SP) ;GET FIRST EXEC COMMON BIAS ;MSH165 BR 10$ ;JOIN COMMON CODE ;MSH165 $MPXC2::MOV (SP),-(SP) ;COPY RETURN PC ;MSH165 MOV $XCOM2,-(SP) ;GET SECOND EXEC COMMON BIAS ;MSH165 10$: MOV KISAR5,4(SP) ;SAVE OLD KERNEL APR 5 MAPPING ;MSH165 MOV (SP)+,KISAR5 ;MAP THE EXECUTIVE COMMON ;MSH165 CALL @(SP)+ ;CALL THE CALLER AS A COROUTINE ;MSH165 MOV (SP)+,KISAR5 ;RESTORE OLD KERNEL APR 5 MAPPING ;**-4 RETURN ; .ENDC ;MSH165 .DSABL LSB ;MSH165 ;+ ; **-$DETRG-DETACH REGION BY ATTACHMENT DESCRIPTOR (TRANSFER ROUTINE) ;MSH165 ; ;**-1 ; THIS ROUTINE PROVIDES ACCESS TO THE ROUTINE THAT DETACHES A TASK ; FROM A REGION AND DEALLOCATES THE ATTACHMENT DESCRIPTOR. THIS ; ROUTINE PROVIDES TRANSPARENCY TO THE EXISTENCE OF THE EXECUTIVE ;MSH165 ; COMMON. ;**-1 ; ; INPUTS: ; ; NONE. ; ; OUTPUTS: ; ; $DTRG1 IS CALLED TO DETACH THE TASK FROM A REGION. $DTRG1 IS ; LOCATED IN THE SECOND EXECUTIVE COMMON. ;MSH165 ; ;**-1 ;- .IF NDF P$$LAS $DETRG==-1 ;THIS LABEL MUST ALWAYS BE DEFINED FOR MCR .IFF .IF DF D$$PAR $DETRG::CALL $MPXC2 ;MAP THE SECOND EXECUTIVE COMMON ;MSH165 CALLR $DTRG1 ;CALL DETACH ROUTINE ;**-1 .ENDC .ENDC ;+ ;MSH194 ; **-$DRWFS-WAITFOR SINGLE EVENT FLAG (EXEC COMMON SYSTEMS ONLY) ;MSH194 ; ;MSH194 ; THIS ROUTINE INSTRUCTS THE SYSTEM TO SUSPEND THE EXECUTION OF ;MSH194 ; THE ISSUING TASK UNTIL A SPECIFIED EVENT FLAG IS SET. ;MSH194 ; ;MSH194 ; INPUTS: ;MSH194 ;  ;MSH194 ; R0=EVENT FLAG MASK WORD. ;MSH194 ; R1=EVENT FLAG MASK ADDRESS. ;MSH194 ; R4=ADDRESS OF THE HEADER OF THE TASK BEING BLOCKED. ;MSH194 ; R5=ADDRESS OF THE TCB OF THE TASK BEING BLOCKED. ;MSH194 ; ;MSH194 ; OUTPUTS: ;MSH194 ; ;MSH194 ; C=0 INDICATING SUCCESS ;MSH194 ;- ;MSH194 ;MSH194 .IF DF M$$NET ;MSH194 .IF DF D$$PAR ;MSH194 ;MSH194 $DRWFS::CALL $MPXC1 ;MAP THE FIRST EXECUTIVE COMMON ;MSH194 CALLR $DRWFD ;PLACE THE TASK IN A WAITFOR STATE ;MSH194 ;MSH194 .ENDC ;MSH194 .ENDC ;MSH194 ;MSH194 ;+ ; **-$CITFR-CONNECT TO INTERRUPT TRANSFER ROUTINE ; ; THIS ROUTINE WILL CALL A USER'S ENABLE/DISABLE INTERRUPT ROUTINE ; ASSOCIATED WITH THE CONNECT TO INTERRUPT DIRECTIVE. THE USER'S ; ROUTINE WILL BE MAPPED THROUGH KERNEL APR 5. ; ; INPUTS: ; ; R1=POINTER TO ITB ; R2=ADDRESS OF USER'S ENABLE/DISABLE INTERRUPT ROUTINE ; C=0 TO ENABLE INTERRUPTS ; C=1 TO DISABLE INTERRUPTS ; ; OUTPUTS: ; ; NONE. ;- .IF DF C$$INT $CITFR:: ;REF LABEL .IF DF D$$PAR MOV KISAR5,-(SP) ;SAVE DIRECTIVE COMMON MAPPING .IFTF .IF DF M$$MGE MOV X.REL(R1),KISAR5 ;MAP ROUTINE IN KERNEL APR 5 .ENDC .IFF CALLR @R2 ;CALL ROUTINE .IFT CALL @R2 ;CALL ROUTINE MOV (SP)+,KISAR5 ;RESTORE DIRECTIVE COMMON MAPPING RETURN ; .ENDC ;D$$PAR .ENDC ;C$$INT ;+ ; **-$DRQRQ-QUEUE I/O REQUEST ; ; THIS ROUTINE IS CALLED TO INSERT AN I/O PACKET IN A CONTROLLER QUEUE AND ; CALL THE DRIVER TO INITIATE ACTIVITY ON THE DEVICE. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O PACKET. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; THE I/O PACKET IS PLACED IN THE CONTROLLER QUEUE AND ACTIVITY ; IS INITIATED ON THE DEVICE. ; ; NOTE: R4 IS DESTROYED BY THIS ROUTINE. ;- $DRQRQ::MOV U.SCB(R5),R4 ;GET ADDRESS OF STATUS CONTROL BLOCK BITB #UC.QUE,U.CTL(R5) ;QUEUE PACKET BEFORE CALL? BNE 10$ ;IF NE NO MOV R4,R0 ;SET ADDRESS OF I/O QUEUE LISTHEAD CALL $QINSP ;QUEUE I/O PACKET IN DEVICE QUEUE 10$: MOV (R5),R2 ;RETRIEVE ADDRESS OF DEVICE CONTROL BLOCK .IF DF L$$DRV&M$$MGE MOV KISAR5,-(SP) ;SAVE APR5 MOV D.PCB(R2),R3 ;GET DRIVER PCB ADDRESS BEQ 20$ ;IF EQ DRIVER IS PART OF EXEC MOV P.REL(R3),KISAR5 ;MAP THE DRIVER 20$: ; .IFTF MOV D.DSP(R2),R2 ;GET ADDRESS OF DRIVER DISPATCH TABLE .IFF CALLR @D.VINI(R2) ;CALL DEVICE INITIATOR .IFT CALL @D.VINI(R2) ;CALL DRIVER INITIATOR MOV (SP)+,KISAR5 ;RESTORE APR5 RETURN ; .ENDC ; MF209 ;+ ; MF209 ; **-$$SRCCQ-SEARCH COMMAND QUEUE ; MF209 ; ; MF209 ; THIS SUBROUTINE SEARCHES A COMMAND QUEUE FOR COMMANDS TO THE SPECIFIED; MF209 ; TASK. ; MF209 ; ; MF209 ; INPUTS: ; MF209 ; ; MF209 ; R0=ADDRESS OF COMMAND QUEUE LISTHEAD ; MF209 ; R5=TCB ADDRESS OF TASK WHOSE COMMANDS SHOULD BE LOCATED ; MF209 ; ; MF209 ; OUTPUTS: ; MF209 ; ; MF209 ; C=1 IF NO COMMANDS PRESENT FOR TASK ; MF209 ; C=0 IF COMMAND IS PRESENT ; MF209 ; R0=ADDRESS OF COMMAND BUFFER ; MF209 ; ; MF209 ;- ; MF209 ; MF209 $SRCCQ:: ; MF209 ; MF209 .IF DF M$$CRX ; MF209 ; MF209 MOV R0,R1 ;SAVE ADDRESS OF PREVIOUS BUFFER ; MF209 MOV (R1),R0 ;GET ADDRESS OF NEXT BUFFER ; MF209 SEC ;ASSUME END OF LIST ; MF209 BEQ 10$ ;IF EQ YES ; MF209 CMP R5,2(R0) ;TCB ADDRESS MATCH ; MF209 BNE $SRCCQ ;IF NE NO ; MF209 10$: RETURN ; MF209 ; MF209 .ENDC ;M$$CRX ; MF209 ; MF209 ; MF209 ;+ ; MF209 ; **-$GTUCB-GET UCB ADDRESS FROM DEV AND UNIT NUMBER ; MF209 ; ; MF209 ; THIS ROUTINE ACCEPTS AND ASCII DEVICE NAME AND OCTAL UNIT NUMBER ; MF209 ; AND FINDS THE UCB ADDRESS FOR THAT DEVICE. ; MF209 ; ; MF209 ; INTPUTS: ; MF209 ; ; MF209 ; R1=ADDRESS OF OCTAL UNIT NUMBER (WORD FIELD), FOLLOWED ; MF209 ; BY ASCII DEVICE NAME ; MF209 ; ; MF209 ; OUTPUTS: ; MF209 ; ; MF209 ; C=1 DEVICE NOT IN SYSTEM ; MF209 ; C=0 IF DEVICE EXISTS ; MF209 ; R5=UCB ADDRESS OF DEVICE ; MF209 ; ; MF209 ; REGISTERS R0,R3,R4 MODIFIED ; MF209 ; ; MF209 ;- ; MF209 ; MF209 .IF DF P$$OFF!A$$CLI ; MF209 ; MF209 $GTUCB::MOV #$SCDVT,-(SP) ;SET UP TO SCAN DEVICE TABLES ; MF209 10$: CALL @(SP)+ ;GET ADDRESS OF NEXT DCB ; MF209 BCS 30$ ;IF CS DEVICE NOT FOUND ; MF209 MOV #1,S$$SPC(SP) ;SET UP TO SKIP THIS DCB IF NO MATCH ; MF209 CMP D.NAM(R3),2(R1) ;DEVICE NAMES MATCH? ; MF209 BNE 10$ ;IF NE NO ; MF209 CMPB D.UNIT+1(R3),(R1) ;UNIT ASSOCIATED WITH THIS DCB? ; MF209 BLO 10$ ;IF LO NO ; MF209 ADD #S$$SPA,SP ;ABORT DEVICE SCAN ; MF209 MOVB (R1),R0 ;GET UNIT NUMBER SPECIFIED ; MF209 SUB D.UNIT(R3),R0 ;CALCULATE NUMBER OF UCBS TO SKIP ; MF209 CLC ;SET SUCCESS ; MF209 20$: DECB R0 ;IS THIS THE CORRECT UCB? ; MF209 BLT 30$ ;IF LT R5 HAS THE ADDRESS OF THE UCB ; MF209 ADD D.UCBL(R3),R5 ;POINT TO NEXT UCB (NOTE THIS CLEARS CAR; MF209 BR 20$ ;CONTINUE SCAN ; MF209 30$: RETURN ; ; MF209 ; MF209 .ENDC ;P$$OFF!A$$CLI ; MF209 ; MF209 ;+ ;MSH165 ; **-$STCLI-SET A TERMINAL'S CLI ;MSH165 ; ;MSH165 ; THIS ROUTINE PROVIDES ACCESS TO THE ROUTINE THAT SETS THE CLI OF ;MSH165 ; THE SPECIFIED TERMINAL. THIS ROUTINE PROVIDES TRANSPARENCY TO THE ;MSH165 ; EXISTENCE OF THE EXECUTIVE COMMONS. ;MSH165 ; ;MSH165 ; INPUTS: ;MSH165 ; ;MSH165 ; R0=UCB ADDRESS OF TERMINAL TO SET ;MSH165 ; R3=POINTER TO THE NAME OF THE NEW CLI ;MSH165 ; ;MSH165 ; OUTPUTS: ;MSH165 ; ;MSH165 ; THE FIRST EXECUTIVE COMMON IS MAPPED AND THE TARGET ROUTINE ;MSH165 ; IS CALLED TO ACTUALLY DO THE WORK. SEE THE DESCRIPTION ;MSH165 ; OF THE TARGET ROUTINE, $STCL1, FOR OUTPUTS. ;MSH165 ;- ;MSH165 ;MSH165 .IF DF A$$CLI ;MSH165 ;MSH165 .IF DF D$$PAR ;MSH165 ;MSH165 ; ;MSH165 ; NOTE THAT $FNCLI WILL RETURN THE C-BIT AS OUTPUT. THE POLARITY OF ;MSH165 ; THE C-BIT MUST BE PRESERVED SO THAT ACTION ON THE C-BIT CAN BE ;MSH165 ; TAKEN IN $STCL1. $MPXC1 PRESERVES THE POLARITY OF THE C-BIT. ;MSH165 ; ;MSH165 ;MSH165 $STCLI::CALL $FNCLI ;FIND THE SPECIFIED CLI ;MSH165 CALL $MPXC1 ;MAP THE FIRST EXECUTIVE COMMON ;MSH165 CALLR $STCL1 ;CALL SET CLI ROUTINE ;MSH165 ;MSH165 .ENDC ;D$$PAR ;MSH165 ;MSH165 .IFF ;A$$CLI ;MSH165 ;MSH165 $STCLI==-1 ;ALWAYS DEFINED FOR MCR ;MSH165 ;MSH165 .IFT ;A$$CLI ;MSH165 ; MF209 ;+ ; MF209 ; **-$FNCLI-FIND CPB FOR SPECIFIED CLI ; MF209 ; ; MF209 ; THIS ROUTINE LOCATES THE CPB FOR THE SPECIFIED CLI ; MF209 ; ; MF209 ; INPUTS: ; MF209 ; ; MF209 ; R3=ADDRESS OF CLI NAME STORED IN RAD50 ; MF209 ; ; MF209 ; OUTPUTS: ; MF209 ; ; MF209 ; C=1 CLI DOES NOT EXIST ; MF209 ; C=0 CLI SUCCESSFULLY FOUND ; MF209 ; R1=OFFSET TO ENTRY FOR CLI IN $CPTBL ; MF209 ; R4=CPB ADDRESS ; MF209 ; ; MF209 ; REGISTERS R0, R2 AND R3 ARE PRESERVED ACROSS CALL ; MF209 ; ; MF209 ;- ; MF209 ; MF209 $FNCLI::MOV #$NMCLI!40000,-(SP) ;GET NUMBER OF CLIS SYSTEM CAN SUPPO; MF209 CLR R1 ;START AT BEGINNING OF TABLE ; MF209 10$: MOV $CPTBL(R1),R4 ;POINT TO NEXT CPB ; MF209 BEQ 20$ ;IF EQ, EMPTY SLOT ; MF209 CMP C.PNAM(R4),(R3) ;IS THIS THE CLI ; MF209 BNE 20$ ;IF NE NO ; MF209 CMP C.PNAM+2(R4),2(R3) ;MAYBE ; MF209 BEQ 30$ ;IF EQ YES ; MF209 20$: TST (R1)+ ;SET OFFSET FOR NEXT SLOT IN TABLE ; MF209 DECB (SP) ;IS THERE A SLOT LEFT ; MF209 BGT 10$ ;IF GT YES ; MF209 ASL (SP) ;PUT BIT IN POSITION TO SET CARRY ; MF209 30$: ASL (SP)+ ;POP STACK AND SET APPROPRIATE CARRY ; MF209 RETURN ; MF209 ; MF209 .IFF ;A$$CLI ; MF209 ; MF209 $FNCLI==-1 ;CANNOT USE THIS LABEL ;MSH165 ; MF209 .ENDC ;A$$CLI ; MF209 ;MSH165 ;+ ;MSH165 ; **-$TRTRP-TRAP TRAP (EXECUTIVE COMMON ENTRY) ;MSH165 ; ;MSH165 ; THIS ROUTINE IS TRAPPED TO WHEN A TRAP INSTRUCTION IS EXECUTED. IF ;MSH165 ; THE STACK DEPTH IS ZERO, THEN A DIRECTIVE STATUS IS TO BE RETURNED. ;MSH165 ; ELSE, CONTROL IS TRANSFERED TO THE EMT/TRAP SST HANDLING ROUTINE. ;MSH165 ; ;MSH165 ; IF DIRECTIVE STATUS IS TO BE RETURNED, THIS ROUTINE TRANSFERS CONTROL ;MSH165 ; BACK TO THE DIRECTIVE DISPATCHER FOR PROCESSING. ON SYSTEMS WITHOUT ;MSH165 ; EXECUTIVE COMMON SUPPORT, THIS ROUTINE EXISTS WHOLLY WITHIN THE ;MSH165 ; DISPATCHER ITSELF. ;MSH165 ; ;MSH165 ; INPUTS: ;MSH165 ; ;MSH165 ; 2(SP)=PS WORD PUSHED BY TRAP INSTRUCTION. ;MSH165 ; 0(SP)=PC WORD PUSHED BY TRAP INSTRUCTION. ;MSH165 ; ;MSH165 ; OUTPUTS: ;MSH165 ; ;MSH165 ; IF THE STACK DEPTH IS ZERO, THEN THE FIRST EXECUTIVE COMMON ;MSH165 ; IS MAPPED THROUGH KERNEL APR5 AND THE DIRECTIVE DISPATCHER ;MSH165 ; GIVEN CONTROL IN ORDER TO RETURN DIRECTIVE STATUS. NOTE ;MSH165 ; THAT IT IS UNNECESSARY TO SAVE THE CONTENTS OF KERNEL ;MSH165 ; APR5 SINCE WE ARE AT SYSTEM STATE. ;MSH165 ; ;MSH165 ; ELSE, CONTROL IS TRANSFERED TO THE EMT/TRAP SST HANDLING ;MSH165 ; ROUTINE. ;MSH165 ;- ;MSH165 ;MSH165 .IF DF D$$PAR  ;MSH165 ;MSH165 $TRTRP::TST $STKDP ;;;STACK DEPTH ZERO? ;MSH165 BNE $EMTRP ;;;IF NE NO ;MSH165 MTPS #0 ;;;ALLOW INTERRUPTS ;MSH165 MOV (SP),R0 ;GET ADDRESS PLUS 2 OF TRAP INSTRUCTION ;MSH165 MOVB -2(R0),R0 ;PICK UP DIRECTIVE STATUS ;MSH165 MOV $XCOM1,KISAR5 ;MAP THE DIRECTIVE DISPATCHER ;MSH165 JMP $DRTRP ;PROCESS THE DIRECTIVE STATUS ;MSH165 ;MSH165 ;+ ;MSH165 ; **-$EMTRP-EMT TRAP (EXECUTIVE COMMON ENTRY) ;MSH165 ; ;MSH165 ; THIS ROUTINE IS TRAPPED TO WHEN AN EMT INSTRUCTION IS EXECUTED. ;MSH165 ; IF THE STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED. ELSE, ;MSH165 ; CONTROL IS IMMEDIATELY TRANSFERED TO THE DIRECTIVE DISPATCHER ;MSH165 ; FOR EMT VALIDATION. ;MSH165 ; ;MSH165 ; ON SYSTEMS WITHOUT EXECUTIVE COMMON SUPPORT, THIS ROUTINE EXISTS ;MSH165 ; WHOLLY WITHIN THE DISPATCHER ITSELF. ;MSH165 ; ;MSH165 ; INPUTS: ;MSH165 ; ;MSH165 ; 2(SP)=PS WORD PUSHED BY EMT INSTRUCTION. ;MSH165 ; 0(SP)=PC WORD PUSHED BY EMT INSTRUCTION. ;MSH165 ; ;MSH165 ; OUTPUTS: ;MSH165 ; ;MSH165 ; IF THE STACK DEPTH IS NOT +1, THEN THE SYSTEM IS CRASHED. ELSE ;MSH165 ; THE DIRECTIVE DISPATCHER IS MAPPED THROUGH KERNEL APR5 AND ;MSH165 ; CONTROL TRANSFERED THERE FOR EMT VALIDATION. NOTE THAT IT ;MSH165 ; IS UNNECESSARY TO SAVE THE CONTENTS OF KERNEL APR5 SINCE ;MSH165 ; EMTS ARE CONSIDERED INVALID IF ISSUED FROM SYSTEM STATE. ;MSH165 ;- ;MSH165 ;MSH165 $EMTRP::DIRSV$ ;;;SAVE REGISTERS AND SET PRIORITY ;MSH165 TST $STKDP ;WERE WE AT STACK DEPTH +1? ;MSH165 BEQ 5$ ;IF EQ YES ;MSH165 CRASH ;EMT/TRAP WITH $STKDP NOT +1 ;MSH165 5$: MOV $XCOM1,KISAR5 ;MAP THE DIRECTIVE DISPATCHER ;MSH165 JMP $DRDSP ;TRANSFER CONTROL TO VALIDATE THE EMT ;MSH165 ;MSH165 ;+ ;MSH165 ; **-$OTHR1-CALL DIRECTIVE ROUTINE RESIDING IN SECOND EXEC COMMON ;MSH165 ; ;MSH165 ; THIS ROUTINE MAPS THE SECOND EXTERNAL EXECUTIVE COMMON THROUGH ;MSH165 ; KERNEL APR5 AND CALLS THE SPECIFIED DIRECTIVE SERVICE ROUTINE. ;MSH165 ; ;MSH165 ; INPUTS: ;MSH165 ; ;MSH165 ; 0(SP)=DIRECTIVE SERVICE ROUTINE / 2 ;MSH165 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ;MSH165 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ;MSH165 ; R3=ADDRESS OF THE NEXT WORD IN THE DIRECTIVE DPB. ;MSH165 ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ;MSH165 ; R1=DEPENDENT ON DIRECTIVE. ;MSH165 ; R0=DEPENDENT ON DIRECTIVE. ;MSH165 ; ;MSH165 ; OUTPUTS: ;MSH165 ; ;MSH165 ; THE SECOND EXECUTIVE COMMON IS MAPPED AND THE SPECIFIED ;MSH165 ; DIRECTIVE SERVICE ROUTINE IS CALLED. UPON SUCCESSFUL ;MSH165 ; DIRECTIVE COMPLETION, CONTROL IS RETURNED TO THE DIRECTIVE ;MSH165 ; DISPATCHER FOR PROCESS COMPLETION. ;MSH165 ;- ;MSH165 ;MSH165 $OTHR1::ASL (SP) ;RESTORE TO BYTE ADDRESS ;MSH165 MOV $XCOM2,KISAR5 ;MAP THE SECOND EXECUTIVE COMMON ;MSH165 CALL @(SP)+ ;CALL THE DIRECTIVE ROUTINE ;MSH165 MOV $XCOM1,KISAR5 ;MAP THE DIRECTIVE DISPATCHER ;MSH165 JMP $DRSOK ;SUCCESSFUL DIRECTIVE COMPLETION ;MSH165 ;MSH165 ;+ ;MSH165 ; **-$DRATP-ALTER TASK PRIORITY (EXECUTIVE COMMON TRANSFER ROUTINE) ;MSH165 ; ;MSH165 ; THIS ROUTINE MAPS THE SECOND EXECUTIVE COMMON AND TRANSFERS ;MSH165 ; CONTROL TO THE ALTER PRIORITY DIRECTIVE PROCESSING ROUTINE THERE. ;MSH165 ; THIS ROUTINE IS DESIGNED TO PROVIDE TRANSPARENCY TO THE EXISTENCE ;MSH165 ; OF THE EXECUTIVE COMMONS FOR THE CALLING PROGRAM. ;MSH165 ; ;MSH165 ; INPUTS: ;MSH165 ; ;MSH165 ; (R3)=NEW TASK PRIORITY ;MSH165 ; SEE DESCRIPTION OF $DRAP1 FOR MORE INPUTS ;MSH165 ; ;MSH165 ; OUTPUTS: ;MSH165 ; ;MSH165 ; THE SECOND EXECUTIVE COMMON IS MAPPED THROUGH KERNEL APR5 ;MSH165 ; AND THE ALTER PRIORITY DIRECTIVE CODE IS CALLED. ;MSH165 ;- ;MSH165 ;MSH165 .IF DF A$$PRI ;MSH165 ;MSH165 $DRATP::MOV (R3),R3 ;GET NEW TASK PRIORITY ;MSH165 CALL $MPXC2 ;MAP THE SECOND EXECUTIVE COMMON ;MSH165 CALLR $DRAP2 ;CALL THE ALTER PRIORITY CODE ;MSH165 ;MSH165 .ENDC ;MSH165 ;MSH165 .ENDC ;D$$PAR ;MSH165 ;MSH165 .END LðskQ ›c, .TITLE DUDRV .IDENT /01/ ; ; COPYRIGHT (c) 1981 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD ; MASSACHUSETTS. ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE ; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS ; SOFTWARE OR ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR ; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND ; OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERED. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ; ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. ; ; ; VERSION 01 ; ; R. T. PERRON 11-NOV-81 ; ; UDA50 CLASS DISK DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,UCBDF$,UDADF$ HWDDF$ ;HARDWARE REGISTERS PKTDF$ ;I/O PACKET OFFSETS UCBDF$ ;UNIT CONTROL BLOCK OFFSETS UDADF$ ;DISK CLASS MSCP SYMBOLS AND OFFSETS .PAGE ; ; EQUATED SYMBOLS ; ; UDA50 UNIBUS DEVICE REGISTER AND BIT DEFINITIONS ; UDAIP = 0 ;INITIALIZATION AND POLLING REGISTER UDASA = 2 ;STATUS AND ADDRESS REGISTER ;+ ; STATUS AND ADDRESS REGISTERS BITS (ERROR READ FORMAT) ; ; BIT 15 IS DEFINED AS THE FATAL ERROR FORMAT: ; ; BIT 15 = 1 ; ; BIT 14 - 11 ARE DEFINED AS THE LAST SUCCESSFULLY COMPLETED STEP FUNCTION: ; ; BIT 14 = 1 IS STEP 4 ; BIT 13 = 1 IS STEP 3 ; BIT 12 = 1 IS STEP 2 ; BIT 11 = 1 IS STEP 1 ;- ERROR = 100000 ;ERROR S4 = 40000 ;STEP 4 BIT S3 = 20000 ;STEP 3 BIT S2 = 10000 ;STEP 2 BIT S1 = 4000 ;STEP 1 BIT ERRCOD = 3777 ;ERROR CODE MASK ; ; ERROR CODE DEFINITIONS ; ER001 = 1 ;ENVELOPE READ (PARITY OR TIMEOUT) ER002 = 2 ;ENVELOPE WRITE (PARITY OR TIMEOUT) ER003 = 3 ;CONTROLLER ROM AND RAM PARITY ER004 = 4 ;CONTROLLER RAM PARITY ER005 = 5 ;CONTROLLER ROM PARITY ER006 = 6 ;RING READ (PARITY OR TIMEOUT) ER007 = 7 ;RING WRITE (PARITY OR TIMEOUT) ER008 = 8. ;INTERRUPT MASTER ER009 = 9. ;HOST ACCESS TIMEOUT (HIGHER-LEVEL PROTOCOL DEPENDENT) ER010 = 10. ;COMMAND LIMIT EXCEEDED ER011 = 11. ;DEVICE FATAL HARDWARE ERROR ER012 = 12. ;DIAGNOSTIC CONTROLLER FATAL ERROR ER013 = 13. ;INSTRUCTION LOOP TIMEOUT ER014 = 14. ;INVALID VIRTUAL CIRCUIT IDENTIFIER ER015 = 15. ;INTERRUPT WRITE ER016 = 16. ;MAINTENANCE READ/WRITE INVALID REGION IDENTIFIER ER017 = 17. ;MAINTENANCE WRITE LOAD TO NON-LOADABLE CONTROLLER ; ; ER018 - ER199 CODES UNASSIGNED ; ;+ ; STATUS AND ADDRESS REGISTERS BITS (STEP ONE READ FORMAT) ; ; BITS 15 - 11 ARE DEFINED THE SAME AS THE ERROR FORMAT EXCEPT: ; ; BIT 15 = 0 ; BIT 14 = 0 ; BIT 13 = 0 ; BIT 12 = 0 ; BIT 11 = 1 ; ; BITS 10 - 8 ARE THE CONTROLLER TYPE FIELD ; BITS 7 - 0 ARE RESERVED ;- STEP1 = S1 ;STEP ONE MASK NOVEC = 2000 ;INABILITY TO ACCEPT INTERRUPT VECTOR ;(I.E. CONTROLLER IS USING A HARD-WIRED ... ;... INTERRUPT VECTOR PLUG) EXTMEM = 1000 ;EXTENDED MEMORY SUPPORT DIAGI = 400 ;ENHANCED DIAGNOSTIC SUPPORT ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP ONE WRITE FORMAT) ; ; BIT 15 MUST SET TO ONE ; BIT 14 IS RESERVED FOR DIAGNOSTIC PURPOSES ; BITS 13 - 11 ARE DEFINED AS COMMAND RING LENGTH BITS ; BITS 10 - 8 ARE DEFINED AS RESPONSE RING LENGTH BITS ; BIT 7 IS DEFINED AS INTERRUPT ENABLE FLAG ; BITS 6 - 0 ARE DEFINED AS INTERRUPT VECTOR / 4 ;- ; ; HIGH BYTE FORMAT AS FOLLOWS: ; CRL2 = 40 ;COMMAND RING LENGTH BIT 2 CRL1 = 20 ;COMMAND RING LENGTH BIT 1 CRL0 = 10 ;COMMAND RING LENGTH BIT 0 CRLNG = CRL2+CRL1+CRL0 ;LENGTH BIT MASK ;LENGTH IS GIVEN AS A POWER OF TWO - ;I.E. 0 ALLOCATES ONE DESCRIPTOR FOR COMMAND RING MRL2 = 4 ;MESSAGE RING LENGTH BIT 2 MRL1 = 2 ;MESSAGE RING LENGTH BIT 1 MRL0 = 1 ;MESSAGE RING LENGTH BIT 0 MRLNG = MRL2+MRL1+MRL0 ;LENGTH BIT MASK ;LENGTH IS GIVEN AS A POWER OF TWO - ;I.E. 0 ALLOCATES ONE DESCRIPTOR FOR MESSAGE RING ; ; LOW BYTE FORMAT AS FOLLOWS: ; INTE = 200 ;INTERRUPT ENABLE INTVEC = 177 ;INTERRUPT VECTOR BYTE MASK ;INTERRUPT VECTOR / 4 ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP TWO READ FORMAT) ; ; BITS 15 - 11 ARE DEFINED THE SAME AS THE ERROR FORMAT EXCEPT: ; ; BIT 15 = 0 ; BIT 14 = 0 ; BIT 13 = 0 ; BIT 12 = 1 ; BIT 11 = 0 ; ; BITS 10 - 8 ARE THE PORT TYPE NUMBER ; BITS 7 - 0 WILL BE THE SAME AS IN LOW BYTE OF STEP ONE WRITE FORMAT ;- STEP2 = S2 ;STEP TWO MASK PRTYP = 7000 ;PORT TYPE MASK ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP TWO WRITE FORMAT) ; ; BITS 15 - 1 ARE THE LOW ORDER ADDRESS OF COMMUNICATIONS AREA ; (MUST BE ON A WORD BOUNDARY) ;- ; ; LOW ORDER 16-BITS OF THE BEGINNING ADDRESS IN COMMUNICATIONS AREA. ; (I.E. BASE ADDRESS OF THE RING BUFFERS FOR THIS CONTROLLER) ; ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP THREE READ FORMAT) ; ; BITS 15 - 11 ARE DEFINED THE SAME AS THE ERROR FORMAT EXCEPT: ; ; BIT 15 = 0 ; BIT 14 = 0 ; BIT 13 = 1 ; BIT 12 = 0 ; BIT 11 = 0 ; ; BITS 10 - 8 ARE RESERVED ; BITS 7 - 0 ARE IN THE SAME FORMAT AS LOW BYTE OF STEP ONE WRITE FORMAT ;- STEP3 = S3 ;STEP THREE MASK ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP THREE WRITE FORMAT) ; ; BIT 15 IS RESERVED ; BITS 14 - 0 ARE THE HIGH ORDER ADDRESS OF THE COMMUNICATIONS AREA ;- ; ; HIGH ORDER 14-BITS OF THE BEGINNING ADDRESS IN COMMUNICATIONS AREA. ; (I.E. BASE ADDRESS OF THE RING BUFFERS FOR THIS CONTROLLER) ; (MUST BE RIGHT JUSTIFIED) ; ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP FOUR READ FORMAT) ; ; BITS 15 - 11 ARE DEFINED THE SAME AS THE ERROR FORMAT EXCEPT: ; ; BIT 15 = 0 ; BIT 14 = 1 ; BIT 13 = 0 ; BIT 12 = 0 ; BIT 11 = 0 ; BITS 10 - 8 ARE RESERVED ; BITS 7 - 0 CONTROLLER MICRO-CODE VERSION NUMBER ;- STEP4 = S4 ;STEP FOUR MASK UCODE = 377 ;MICRO-CODE VERSION NUMBER MASK ;+ ; STATUS AND ADDRESS REGISTER BITS (STEP FOUR WRITE FORMAT) ; ; BITS 15 - 8 ARE RESERVED ; BITS 7 - 3 BURST TRANSFER CONTROL ; BIT 1 IS LAST FAILURE FLAG ; BIT 0 IS THE GO BIT ;- BURST = 374 ;BURST TRANSFER MASK LFAIL = 2 ;LAST FAILURE FLAG GO = 1 ;GO BIT ; ; COMMAND/MESSAGE DESCRIPTOR OFFSETS ; CMDINT = -4 ;COMMAND INTERRUPT OFFSET (FROM BASE OF RING) RSPINT = -2 ;RESPONSE INTERRUPT OFFSET (FROM BASE OF RING) LADDR = -2 ;LOW ORDER 16-BIT BYTE ADDRESS LOCATION HADDR = 0 ;HIGH ORDER 14-BIT BYTE ADDRESS LOCATION AND FLAGS ; ; COMMAND/MESSAGE DESCRIPTOR WORD 0 FORMAT ; ; ; 16-BIT LOW ORDER BYTE ADDRESS OF MSCP PACKET (MUST BE WORD ALIGNED) ;  ; ; COMMAND/MESSAGE DESCRIPTOR WORD 1 FORMAT ; OWN = 100000 ;OWN FLAG = 40000 ;FLAG ; ; 14-BITS HIGH ORDER BYTE ADDRESS OF MSCP PACKET ADDRESS ; ; ; MESSAGE ENVELOPE ; MSGLNG = -4 ;OFFSET TO MESSAGE LENGTH (IN BYTES) VCID = -1 ;OFFSET TO VIRTUAL CIRCUIT ID (IN BYTES) CREDIT = -2 ;OFFSET TO MESSAGE/CREDIT FIELD (IN BYTES) MSGTYP = 360 ;MESSAGE TYPE MASK CRDDBT = 17 ;CREDIT/DEBIT MASK ; ; VIRTUAL CIRCUIT IDENTIFIERS ; VCDSK = 0 ;DISK VIRTUAL CIRCUIT ID VCDIA = 255. ;DIAGNOSTIC VIRTUAL CIRCUIT ID ; ; MESSAGE TYPE IDENTIFIERS ; MSGMUL = 20 ;MESSAGE FIELD MULTIPLIER MSGSEQ = 0 ;SEQUENTIAL MESSAGE MSGDAT = 1 ;DATAGRAM MESSAGE MSGCRD = 2 ;CREDIT MESSAGE MSGMNT = 15. ;MAINTENANCE MESSAGE ; ; ERROR RETRY COUNT ; RETRY = 3. ;CONTROLLER ERROR RETRY COUNT ; ; INTERNAL BIT FLAG FUNCTION INDICATORS FOR CONTROLLER STATE ; ; ; FLAGS IN C.STAT+1 ; C2.INI = 200 ;INITIALIZATION IS IN PROGRESS C2.PWF = 100 ;POWERFAIL OCCURRED C2.ONL = 1 ;CONTROLLER ON-LINE IS IN PROGRESS ; ; FLAGS IN C.STAT ; C1.OFF = 200 ;CONTROLLER OFF-LINE C1.INI = 100 ;RE-INITIALIZATION REQUIRED C1.CQR = 10 ;CLOCK QUEUE REQUEST C1.CMD = 4 ;COMMAND RING BUFFER IS FULL C1.CLK = 2 ;CLOCK ACTIVE FLAG C1.ON = 1 ;CONTROLLER ON-LINE ; ; DRIVER SYMBOLS ; ENVLP = - ;ADDITIONAL SIZE OF PACKET (IN BYTES) ... ;... TO ACCOMMADATE THE ENVELOPE RNGSIZ = 4 ;LENGTH OF RING BUFFER ENTRY (IN BYTES) RSPLNG = L.LENG + ENVLP ;TOTAL LENGTH OF RESPONSE PACKET (IN BYTES) CMDLNG = P.LENG + ENVLP ;TOTAL LENGTH OF COMMAND PACKET (IN BYTES) ; ; FOR DEBUGGING PURPOSES (USING XDT) UNCOMMENT THE FOLLOWING LINE OF CODE ;.IIF DF X$$DBT, DEBUG = 0 ; ; ; LOCAL MACROS ; .MACRO LABEL NUM,NAM,SUFFIX .IF NB NAM'NUM'SUFFIX: .IFF ;NB NAM'NUM: .ENDC ;NB .ENDM LABEL .MACRO POINT NUM,NAM,SUFFIX .IF NB .WORD NAM'NUM'SUFFIX .IFF ;NB .WORD NAM'NUM .ENDC ;NB .ENDM POINT .MACRO SPACE NUM,NAM,LENG .BLKB NAM'NUM'*'LENG .ENDM SPACE .MACRO DURNG$ DEV,NCTRLR,NSIZE N=0 .REPT NCTRLR .BLKW 2 LABEL \N,DEV,RG SPACE \N,DEV'$R,NSIZE SPACE \N,DEV'$C,NSIZE N=N+1 .ENDR ;NCTRLR .MACRO DURNG$ X,Y,Z .ENDM DURNG$ .ENDM DURNG$ .MACRO DUPKT$ DEV,NCTRLR,RLENG,CLENG N=0 .REPT NCTRLR LABEL \N,DEV,PK SPACE \N,DEV'$R,RLENG SPACE \N,DEV'$C,CLENG N=N+1 .ENDR ;NCTRLR .MACRO DUPKT$ A,B,C,D .ENDM DUPKT$ .ENDM DUPKT$ .MACRO DULNG$ NUM,NAM .IF DF NAM'$R'NUM & NAM'$C'NUM .IIF EQ NAM'$R'NUM'-1,'NAM'LR'NUM'=0 .IIF EQ NAM'$C'NUM'-1,'NAM'LC'NUM'=0 .IIF EQ NAM'$R'NUM'-2,'NAM'LR'NUM'=1 .IIF EQ NAM'$C'NUM'-2,'NAM'LC'NUM'=1 .IIF EQ NAM'$R'NUM'-4,'NAM'LR'NUM'=2 .IIF EQ NAM'$C'NUM'-4,'NAM'LC'NUM'=2 .IIF EQ NAM'$R'NUM'-8.,'NAM'LR'NUM'=3 .IIF EQ NAM'$C'NUM'-8.,'NAM'LC'NUM'=3 .IIF EQ NAM'$R'NUM'-16.,'NAM'LR'NUM'=4 .IIF EQ NAM'$C'NUM'-16.,'NAM'LC'NUM'=4 .IIF EQ NAM'$R'NUM'-32.,'NAM'LR'NUM'=5 .IIF EQ NAM'$C'NUM'-32.,'NAM'LC'NUM'=5 .IIF EQ NAM'$R'NUM'-64.,'NAM'LR'NUM'=6 .IIF EQ NAM'$C'NUM'-64.,'NAM'LC'NUM'=6 .IIF EQ NAM'$R'NUM'-128.,'NAM'LR'NUM'=7 .IIF EQ NAM'$C'NUM'-128.,'NAM'LC'NUM'=7 .BYTE NAM'$R'NUM','NAM'LR'NUM .BYTE NAM'$C'NUM','NAM'LC'NUM .WORD 10*NAM'LC'NUM'+'NAM'LR'NUM .BYTE NAM'$C'NUM'+'NAM'$R'NUM .BYTE NAM'$C'NUM'+'NAM'$R'NUM .ENDC ;DF NAM'$C'NUM & NAM'$R'NUM .ENDM DULNG$ .MACRO DUCST$ DEV,NCTRLR N=0 .REPT NCTRLR POINT \N,'DEV',TB N=N+1 .ENDR ;NCTRLR .MACRO DUCST$ X,Y .ENDM DUCST$ .ENDM DUCST$ .MACRO DUTBL$ DEV,NCTRLR N=0 .REPT NCTRLR LABEL \N,DEV,TB .IF DF M$$MGE .BLKW 8. .IFF ;M$$MGE .BLKW 5. .ENDC ;M$$MGE POINT \N,'DEV',RG DULNG$ \N,DEV POINT \N,'DEV',PK POINT \N,'DEV',PK .BLKB C.LONG-C.PKT+4 N=N+1 .ENDR ;NCTRLR .MACRO DUTBL$ X,Y .ENDM DUTBL$ .ENDM DUTBL$ ; ; DUDRV CONTROLLER STATE TABLE FORMAT ; .ASECT .=0 C.STAT: .BLKW 1 ;CONTROLLER STATE FLAGS C.RTRY: .BLKW 1 ;RETRY COUNT C.CMDS: .BLKW 1 ;COUNT FOR COMMANDS ISSUED .IF DF M$$MGE C.PAR5: .BLKW 1 ;MAPPING SAVE AREA, APR5 C.PAR6: .BLKW 1 ;MAPPING SAVE AREA, APR6 C.SAPR: .BLKW 1 ;MAPPING SAVE AREA, PREVIOUS APR6 .ENDC ;M$$MGE C.RELC: .BLKW 2 ;RELOCATION CONSTANT (DOUBLE WORD) C.RING: .BLKW 1 ;BASE ADDRESS OF RINGS C.RSP: .BLKW 1 ;NUMBER OF RESPONSE RINGS/LOG BASE 2 OF NUMBER ;OF RESPONSE RINGS C.CMD: .BLKW 1 ;NUMBER OF COMMAND RINGS/LOG BASE 2 OF NUMBER ;OF COMMAND RINGS C.STP1: .BLKW 1 ;SIZE OF COMMAND/RESPONSE RINGS ROR STEP 1 (LOW BYTE) C.PKTS: .BLKB 1 ;NUMBER OF PACKETS C.NMBR: .BLKB 1 ;NUMBER OF AVAILABLE PACKETS C.PKT: .BLKW 2 ;BASE ADDRESS OF PACKETS ;SECOND WORD IS POINTER TO CURRENT PACKET ; ; CHARACTERISTICS OBTAINED FROM "SET CONTROLLER CHARACTERISTICS" END PACKET ; C.VRSN: .BLKW 1 ;MSCP VERSION C.CNTF: .BLKW 1 ;CONTROLLER FLAGS C.CTMO: .BLKW 1 ;CONTROLLER TIME OUT .BLKW 1 ;RESERVED C.CNTI: .BLKW 4 ;CONTROLLER ID .IF DF E$$DVC ; ; CONTROLLER ERROR LOG PACKET ; C.MLNG: .BLKW 1 ;LENGTH OF CONTROLLER TIMEOUT PACKET C.VCID: .BLKB 1 ;VIRTUAL CIRCUIT ID C.CRED: .BLKB 1 ;CREDIT/DEBIT FIELD C.IP: .BLKW 1 ;SAVED VALUE OF UDAIP REGISTER C.SA: .BLKW 1 ;SAVED VALUE OF UDASA REGISTER .ENDC ;E$$DVC ; ; DRIVER / CONTROLLER STATE ; C.IOPK:.BLKW 1 ;OUTSTANDING I/O PACKET STORAGE AREA C.CLCC: .BLKB 1 ;CURRENT LOOP COUNT CONTROL C.ILCC: .BLKB 1 ;INITIAL LOOP COUNT CONTROL C.INIT: .BLKW 2 ;CONTROLLER INITIALIZATION STATE C.ITBL: .BLKW 4 ;INITIALIZATION TABLE C.IOSB: .BLKW 2 ;TWO WORD STATUS BLOCK ;FIRST WORD IS STATUS CODE ;SECOND WORD IS BYTE COUNT TRANSFERED ; ; NOTE: FOR THE SAKE OF SPEED AND SIZE, THE RING BUFFER POINTERS POINT ; TO THE SECOND WORD OF A TWO-WORD RING ENTRY ; C.CRSP: .BLKW 2 ;CURRENT RESPONSE RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.FRSP: .BLKW 2 ;FIRST RESPONSE RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.LRSP: .BLKW 2 ;LAST RESPONSE RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.CCMD: .BLKW 2 ;CURRENT COMMAND RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.FCMD: .BLKW 2 ;FIRST COMMAND RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.LCMD: .BLKW 2 ;LAST COMMAND RING BUFFER POINTER ;AND VIRTUAL ADDRESS OF ITS PACKET C.LONG = . - C.STAT ;LENGTH OF CONTROLLER STATE TABLE (IN BYTES) .PSECT ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; DUSTRT: ;START OF DRIVER ; ; DRIVER DISPATCH TABLE ; $DUTBL::.WORD DUINI ;INITIATOR ENTRY POINT .WORD DUCAN ;CANCEL ENTRY POINT .WORD DUOUT ;TIMEOUT ENTRY POINT .WORD DUPWF ;POWERFAIL ENTRY POINT CNTBL: .BLKW R$$UDA ;UCB POINTER .IF GT R$$UDA-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ;R$$UDA-1 CTTBL: DUCST$ DU,R$$UDA ;CONTROLLER STATE TABLE POINTERS ; ; MISCELLANEOUS WORDS ; RCTNAM:.RAD50 /RCT.../ ;REPLACEMENT CONTROL TASK'S TASKNAME RCTTCB:.BLKW 1 ;REPLACEMENT CONTROL TASK'S TCB ADDRESS DUDCB: .BLKW 1 ;POINTER TO DU:'S FIRST DCB DUDCB2: .BLKW 1 ;POINTER TO DU:'S CURRENT DCB ; ; USER MODE DIAGNOSTIC SUPPORT DEFINITIONS ; .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ;DEFINE USER MODE DIAGNOSTIC FUNCTIONS DUDIAG: ;TABLE OF DEFINED USER MODE DIAGNOSTIC FUNCTIONS .WORD 0 ;TERMINATOR .ENDC ;D$$IAG .PAGE ;+ ; **- DUINI - UDA50 CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED AT THE END OF A PREVIOUS I/O OPERATION TO ; PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER/UNIT ; COMMAND LIMIT HAS NOT BEEN EXCEEDED THEN AN ATTEMPT IS MADE TO DEQUEUE ; THE NEXT I/O REQUEST. ELSE THE RESULTS FROM ANY PREVIOUS I/O REQUEST ; ARE CHECKED FOR COMPLETION. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN ; THAT I/O OPERATION IS INIITIATED. IF THERE ARE NO I/O REQUEST WHICH ; MAY BE DEQUEUED NOR ANY RESULTS FROM PREVIOUS I/O REQUESTS, THEN THE ; DRIVER WILL EXIT BACK TO THE SYSTEM. ; ; INPUTS: ; ; R5 = ADDRESS OF THE UCB OF THE UNIT TO BE INITIATED ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER/UNIT COMMAND LIMIT HAS NOT BEEN ; EXCEEDED AND AN I/O REQUEST IS WAITING TO BE PROCESSED, THEN THE ; REQUEST IS DEQUEUED AND THE I/O OPERATION IS INITIATED. ; ;- .ENABL LSB DUINI: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV #DURSP,-(SP) ;SET UP A RETURN ADDRESS IF WE FAIL MOV #PRTST,R2 ;POINT TO PORT TEST/ACCEPTANCE ROUTINE CALL $GSPKT ;GET AN I/O PACKET TO PROCESS BCC 10$ ;IF CC, GOT A PACKET RETURN ;NO, FAILED TO GET A PACKET EXIT ;TO CHECK RESPONE RINGS ; ; WE GOT A PACKET - ADDRESS IN R1 ; ;+ ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GSPKT ; ; R1 = ADDRESS OF THE I/O REQUEST PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX. ; R4 = ADDRESS OF THE STATUS CONTROLLER BLOCK. ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; UDA50 CLASS DISK I/O REQUEST PACKET FORMAT.  ; ; WD 00 -- I/O QUEUE THREAD WORD (I.LINK). ; WD 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER (I.EFN & I.PRI). ; WD 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK (I.TCB). ; WD 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER (I.LN2). ; WD 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (I.UCB). ; WD 05 -- I/O FUNCTION CODE (IO.RLB/IO.WLB) (I.FCN). ; WD 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK (I.IOSB). ; WD 07 -- RELOCATION BIAS OF I/O STATUS BLOCK (I.IOSB+2). ; WD 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000) (I.IOSB+4). ; WD 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE (I.AST). ; ; FOLLOWING FORMAT APPLIES TO ALL DATA TRANSFER FUNCTIONS: ; ; WD 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER (I.PRM). ; WD 13 -- BUFFER ADDRESS OF I/O TRANSFER (I.PRM+2). ; WD 14 -- NUMBER OF BYTES TO BE TRANSFERED (I.PRM+4). ; WD 15 -- DIAGNOSTIC SUPPLIMENTAL PARAMETER ELSE NOT USED (I.PRM+6). ; WD 16 -- HIGH PART OF LOGICAL BLOCK NUMBER AND HIGH BYTE NOT USED (I.PRM+10). ; WD 17 -- LOW PART OF LOGICAL BLOCK NUMBER OF I/O REQUEST (I.PRM+12). ; WD 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLOCK ADRS ELSE NOT USED (I.PRM+14). ; WD 21 -- DIAGNOSTIC REG. BLOCK ADRS (REAL OR DISPLACEMENT + 140000) (I.PRM+16). ; ; ; FOLLOWING FORMAT APPLIES TO ALL CONTROL FUNCTIONS: ; ; INITIALIZE FUNCTION CODE ; ; NO PARAMETERS REQUIRED ; ; REPLACEMENT FUNCTION CODE ; ; WD 12 -- HI PART OF REPLACEMENT BLOCK NUMBER AND HIGH BYTE NOT USED (I.PRM) ; WD 13 -- LO PART OF REPLACEMENT BLOCK NUMBER (I.PRMT+2) ; WD 14 -- HI PART OF LOGICAL BLOCK NUMBER AND HIGH BYTE NOT USED (I.PRM+6). ; WD 15 -- LO PART OF LOGICAL BLOCK NUMBER OF I/O REQUEST (I.PRM+10). ; WD 16 -- PRIMARY REPLACEMENT BLOCK MODIFIER (I.PRM+12). ; WD 17 -- ; WD 20 -- ; ; TERMINATE REPLACEMENT FUNCTION CODE ; ; WD 12 -- I/O PACKET ADDRESS TO COMPLETE I/O OPERATION IN PROGRESS ; WD 13 -- SUCCESS/FAILURE CODE OF REPLACEMENT ; IS.SUC = SUCCESS ; IE.VER = FAILURE ; ;- 10$: TST (SP)+ ;CLN THE STACK .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS FOR LATER MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER MOVB C.ILCC(R3),C.CLCC(R3) ;SET LOOP COUNT CONTROL ; ; CHECK AND VALIDATE THE I/O FUNCTION CODE ; MOV R1,S.PKT(R4) ;SAVE I/O PACKET .IF DF D$$IAG CMPB #IO.HMS/256.,I.FCN+1(R1) ;USER MODE DIAGNOSTIC FUNCTION? BNE 30$ ;IF NE NO MOV #DUDIAG,R0 ;YES, GET USER MODE DIAGNOSTIC TABLE 20$: TST (R0) ;DIAGNOSTIC FUNCTIONS DEFINED? BEQ ERRIFC ;IF EQ NO CMPB (R0)+,I.FCN(R1) ;LOCATE DESIRED DIAGNOSTIC FUNCTION? BNE 20$ ;IF NE NO BR 70$ ;YES, GO ON .ENDC ;D$$IAG 30$: MOV I.TCB(R1),R2 ;GET REQUESTING TASK'S TCB ADDRESS MOV I.FCN(R1),R0 ;GET FUNCTION CODE CMP #IO.LOV,R0 ;IS IT LOAD OVERLAY FUNCTION? BEQ 60$ ;IF EQ YES BIC #7,R0 ;NO, REMOVE QUALIFIER BITS CMPB #IO.RLB/256.,I.FCN+1(R1) ;DATA TRANSFER FUNCTION? BLO 80$ ;IF LO NO TSTB I.FCN(R1) ;ANY SUB-FUNCTION CODES SET? BEQ 60$ ;IF EQ NO CMPB #IO.WLC&IO.RLC,R0 ;COMPARE SUB-FUNCTION CODE SET? BEQ 60$ ;IF EQ YES CMP #IO.RSN,R0 ;READ VOLUME SERIAL NUMBER SUB-FUNCTION CODE SET? BEQ 40$ ;IF EQ YES BIT #T3.PRV,T.ST3(R2) ;IS TASK PRIVILEGED? BEQ 50$ ;IF EQ NO CMP RCTTCB,R2 ;YES, THEN IS THIS RCT? BNE 50$ ;IF NE NO CMPB #IO.RPB&IO.WPB,R0 ;PHYSICAL BLOCK SUB-FUNCTION CODE SET? BEQ 70$ ;IF EQ YES CMP #IO.WDD,R0 ;WRITE DELETED DATA FUNCTION? BEQ 70$ ;IF EQ YES ERRPRI: MOV #IE.PRI&377,R0 ;SET PRIVILEGE VIOLATION BR DUFIN ;AND FINISH UP ERRIFC: MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION DUFIN: MOV R1,R3 ;COPY I/O PACKET ADDRESS INTO R3 CLR R1 ;ZERO BYTE COUNT TRANSFERRED DUFIN1: CALL $IOFIN ;FINISH UP THIS I/O BR DUINI ;PROCESS NEXT REQUEST 40$: MOV #IE.BYT&377,R0 ;ASSUME ILLEGAL BYTE COUNT CMP #4,I.PRM+4(R1) ;IS BYTE COUNT .GE. 4 BHI DUFIN ;IF HI NO CALL DURSN ;COPY VOLUME SERIAL NUMBER INTO USER'S BUFFER BR DUFIN1 ;FINISH UP I/O 50$: BITB #IQ.X!IQ.Q!IQ.UMD,I.FCN(R1) ;ANY GENERAL SUB-FUNCTION BITS SET? BEQ ERRIFC ;IF EQ NO 60$: CALL $BLKCK ;VALIDATE THE LBN 70$: MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 100$ ;IF NE YES CALL DUMAP ;MAP THE BUFFER ADDRESS THRU UMR'S CALL $STMP1 ;SET-UP THE UNIBUS MAP CLR U.CNT(R5) ;CLR UMR MAPPING INTERLOCK MOV R1,R0 ;RESTORE POINTER TO UMR WAITING BLOCK ADD #10,R0 ;OFFSET TO UMR ASSIGNMENT BLOCK MOV R2,S.PKT(R4) ;SAVE I/O PACKET ADDRESS CALL $MPUB1 ;MAP UNIBUS TO TRANSFER .ENDC ;M$$EXT BR 100$ ;SKIP OVER NEXT 80$: CMP #IO.SEC,R0 ;SENSE CHARACTERISTICS FUNCTION? BEQ 90$ ;IF EQ YES BIT #T3.PRV,T.ST3(R2) ;TASK PRIVILEGED? BEQ ERRPRI ;IF EQ NO CMP RCTTCB,R2 ;YES, THEN IS THIS RCT? BNE ERRPRI ;IF NE NO CMP #IO.INL,R0 ;INITIALIZE FUNCTION? BEQ 90$ ;IF EQ YES .IF DF DEBUG 81$: BPT ;GET TO XDT MOV #NOP,81$ ;NOP THE BRK PNT .ENDC ;DEBUG CMP #IO.RPL,R0 ;REPLACE FUNCTION? BEQ 90$ ;IF EQ YES CMP #IO.TRM,R0 ;TERMINATE FUNCTION? BNE ERRIFC ;IF NE NO .IF DF DEBUG 83$: BPT ;GET TO XDT MOV #NOP,83$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER MOV I.PRM(R1),S.PKT(R4) ;SAVE I/O PACKET ADDRESS IN SCB MOVB I.PRM+2(R1),C.IOSB(R3) ;SAVE POTENTIAL STATUS CODE DUSUC: MOV #IS.SUC&377,R0 ;SET SUCCESS STATUS CODE MOV R1,R3 ;COPY I/O PACKET ADDRESS INTO R3 CLR R1 ;CLR R1 CALL $IOFIN ;FINISH THIS I/O MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS MOV R5,R0 ;COPY UCB ADDRESS TO R0 ADD #U.BPKT,R0 ;ADD OFFSET TO BAD BLOCK REPLACEMENT QUEUE MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS TO TERMINATE CALL $QRMVT ;GET I/O PACKET FROM BAD BLOCK REPLACEMENT QUEUE .IF DF DEBUG BCC 85$ ;IF CC OK CRASH ;SOMETHING'S WRONG 85$: ;REF LABEL .ENDC ;DEBUG MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER TSTB C.IOSB(R3) ;RESTART THE I/O FOR THIS PACKET? BPL 90$ ;IF PL YES JMP DUDON ;NO, FINISH IT UP 90$: MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX 100$: MOV S.PKT(R4),R2 ;COPY I/O PACKET ADDRESS INTO R2 MOV #DUINI,-(SP) ;SET RETURN ADDRESS ON STACK .DSABL LSB ;+ ; **- DUCMD - MSCP COMMAND PROCESSOR ; ; THE MSCP COMMAND PROCESSOR WILL INITIATE GETTING A COMMAND RING PACKET ; FILLED IN WITH THE APPROPRIATE VALUES, QUEUE THE I/O PACKET TO THE UNIT'S ; I/O ACTIVE QUEUE, AND CAUSE THE MSCP PACKET TO BE QUEUED TO THE CONTROLLER. ; ; INPUTS: ; ; R2 = I/O PACKET ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE SPECIFIED I/O PACKET IS TRANSFORMED INTO AN MSCP PACKET ; AND THAT PACKET IS GIVEN TO THE CONTROLLER. ; ;- DUCMD: MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS AWAY MOV CTTBL(R3),R3 ;GET POINTER TO CONTROLLER STATE TABLE DUCMD1: CALL MKPKT ;GO SET UP MSCP PACKET DUCMD2: MOV R1,-(SP) ;SAVE POINTER TO CURRENT COMMAND PACKET MOV R5,R0 ;SET-UP TO POINT TO UNIT'S I/O QUEUE LISTHEAD ADD #U.LHD,R0 ;BY ADDING THE OFFSET MOV S.PKT(R4),R1 ;GET THE I/O PACKET ADDRESS TST (R0) ;ANY I/O OUTSTANDING? BNE 10$ ;IF NE YES MOV C.CTMO(R3),U.UTMO(R5) ;NO, SET UP UNIT TIME OUT COUNT 10$: CALL $QINSF ;INSERT I/O PACKET INTO UNIT'S I/O QUEUE MOV (SP)+,R1 ;RESTORE POINTER TO CURRENT COMMAND PACKET ... DUCMD3: MOV #1,R0 ;SET-UP VIRTUAL CIRCUIT AND CREDIT CALL DUINIO ;INITIATE I/O BCS DUCMD4 ;IF CS ERROR INITIATING I/O RETURN ;ALL'S OK -- RETURN TO CALLER DUCMD4: TST (SP)+ ;FLUSH STACK CALLR REINIT ;ATTEMPT TO RE-INIT THE CONTROLLER ;+ ; **- DURSP - MSCP RESPONSE PROCESSOR ; ; THE MSCP RESPONSE PROCESSOR WILL CAUSE A SCAN OF THE RESPONSE RING ; FOR ANY RESPONSES. RESPONSES MAY COME FROM: ; ; 1. MSCP SET CONTROLLER CHARACTERISTICS COMMAND ; 2. MSCP SET UNIT ON-LINE COMMAND ; 3. MSCP ATTENTION RESPONSES ; 4. MSCP ERROR LOG RESPONSES ; 5. AN I/O PACKET QUEUED TO THE CONTROLLER ; ; EACH OF THESE MUST BE DISPATCHED PROPERLY ; ; INPUTS: ; ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF UNIT INITIALIZATION IS IN PROGRESS THEN UNITS ARE BROUGHT ON-LINE ; ELSE ; ; IF RE-INITIALIZATION IS IN PROGRESS THEN OUTSTANDING I/O IS RE-ISSUED ; ELSE ; ; THE RESPONSE RING IS SEARCHED FOR A RESPONSE AND ; IF THE RESPONSE IS NOT TO AN INTERNALLY GENERATED COMMAND ; THEN THE RESULTS ARE RETURNED TO THE ISSUING TASK. ; ;- DURSP: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV CTTBL(R3),R3 ;GET POINTER TO CONTROLLER STATE TABLE TSTB C.STAT+1(R3) ;CONTROLLER ON-LINE IN PROGRESS? BGT DURSP1 ;IF GT YES, SCAN RESPONSE RINGS BNE 60$ ;IF NE YES, EXIT .IF DF DEBUG BITB #C1.ON,C.STAT(R3) ;CONTROLLER ON-LINE? BNE 10$ ;IF NE YES 5$: CRASH ;NO, CRASH .ENDC ;DEBUG 10$: BITB #C1.INI,C.STAT(R3) ;RE-INITIALIZATION IN PROGRESS? BEQ DURSP1 ;IF EQ NO MOV #SCUCB,-(SP) ;YES, PUSH "SCAN UCB'S" ROUTINE ON THE STACK 20$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS DURSP1 ;IF CS ALL DONE CLR C.IOPK(R3) ;INITIALIZE OUTSTANDING I/O PACKET STORAGE AREA TST U.LHD(R5) ;ANY I/O OUTSTANDING ON THIS UNIT? BEQ 20$ ;IF EQ NO 30$: CMP C.IOPK(R3),U.LHD(R5) ;IS THIS THE FIRST ONE AGAIN? BEQ 20$ ;IF EQ YES MOV R3,-(SP) ;SAVE POINTER TO CONTROLLER STATE TABLE MOV R5,R0 ;SET-UP TO POINT TO UNIT'S I/O QUEUE LISTHEAD ADD #U.LHD,R0 ;BY ADDING THE OFFSET CALL $QRMVF ;REMOVE THE FRONT ENTRY FROM THE QUEUE .IF DF DEBUG BCC 40$ ;IF CC, ALL'S OK CRASH ;CRASH, UNABLE TO REMOVE ANY ENTRY .ENDC ;DEBUG 40$: MOV (SP)+,R3 ;RESTORE POINTER TO CONTROLLER STATE TABLE TST C.IOPK(R3) ;IS THIS THE FIRST ENTRY? BNE 50$ ;IF NE NO MOV R1,C.IOPK(R3) ;YES, SET ADDRESS INTO C.IOPK 50$: MOV R1,R2 ;COPY ADDRESS OF I/O PACKET TO R2 CALL DUCMD1 ;GO ISSUE I/O BR 30$ ;GO AGAIN 60$: RETURN ;EXIT, CONTROLLER INITIALIZATION IN PROGRESS ;+ ; **- DURSP1 - MSCP RESPONSE PROCESSING ROUTINE ; ; THE MSCP RESPONSE PROCESSING ROUTINE IS CALLED TO PROCESS THE NEXT SEQUENTIAL ; RESPONSE RECEIVED FROM THE UDA50. THERE ARE FOUR SPECIAL CASE RESPONSES WHICH ; ARE PROCESSED INTERNALLY, ALL OTHERS ARE IN RESPONES TO AN I/O PACKET OUT- ; STANDING. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; C = 0 AND IF THE RESPONSE END CODE IS: ; OP.END!OP.SCC, OP.END!OP.ONL, OR OP.END!OP.SUC ; THEN THESE ARE PROCESSED INTERNALLY. ; ; C = 1 IF THE RESPONSE END CODE IS NONE OF THE ABOVE AND ; C.IOSB = IS.SUC&377 OR IE.VER&377 DEPENDING ON THE STATUS/EVENT CODE ; C.IOSB+2 = P.BCNT FROM THE MSCP PACKET ; ;- DURSP1: CALL DUPOLL ;POLL RESPONSE RINGS BCC 10$ ;IF CC WE GOT A RESPONSE JMP DUEXIT ;OTHERWISE SEE IF WE SHOULD EXIT ; ; R0 = CONTENTS OF MESSAGE TYPE FIELD ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R2 = HI ORDER REF NUMBER FROM THE RESPONSE PACKET ; 10$: ;REF LABEL .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG BITB #OP.AVA,P.OPCD(R1) ;IS IT AN AVAILABLE ATTENTION RESPONSE? BEQ 20$ ;IF EQ NO CALL DUATN ;YES, HANDLE AVAILABLE ATTENTION MESSAGE BCS 69$ ;IF CS, NO UCB FOR THIS UNIT 15$: CALL RLPKT ;RELEASE PACKET BITB #US.OFL,U.ST2(R5) ;UNIT MARKED OFF-LINE? BNE DURSP1 ;IF NE YES BITB #US.SPU,U.STS(R5) ;UNIT MARKED SPINNING UP? BEQ DURSP1 ;IF EQ NO CALL DUSTAT ;ATTEMPT TO GET UNIT STATUS BCC DURSP1 ;IF CC EXIT CALLR REINIT  ;NO, RE-INIT THE CONTROLLER 20$: ;REF LABEL .IF DF DEBUG 21$: BPT ;GET TO XDT MOV #NOP,21$ ;NOP THE BRK PNT .ENDC ;DEBUG BITB #OP.END,P.OPCD(R1) ;DOES THIS PACKET HAVE AN END CODE? BEQ 69$ ;IF EQ NO, SOMETHING'S WRONG CMP R2,R5 ;IS THIS PACKET FOR THE CURRENT UCB? BEQ 30$ ;IF EQ YES .IF DF DEBUG CMP R2,R4 ;IS POSSIBLE UCB ADDRESS OUT OF RANGE? BLO 25$ ;IF LO NO CRASH ;YES, CRASH 25$: ;REF LABEL .ENDC ;DEBUG MOV R2,R5 ;YES, COPY HI ORDER REF NUMBER AS UCB ADDRESS 30$: ;REF LABEL .IF DF E$$DVC BITB #EF.LOG,P.FLGS(R1) ;ERROR LOG GENERATED? BNE 40$ ;IF NE YES TST P.STS(R3) ;STATUS INDICATE SUCCESS? BEQ 50$ ;IF EQ YES 40$: CALL DULERR ;NO, LOG ERROR LOG PACKET .ENDC ;E$$DVC 50$: CMP P.CRF+2(R1),R3 ;IS LO ORDER REF NUMBER SAME AS CONTROLLER ... ;... STATE TABLE POINTER? BNE 90$ ;IF NE NO CMPB #OP.END!OP.SCC,P.OPCD(R1) ;IS THIS A "SET CONTROLLER ;CHARACTERISTICS" END CODE? BNE 70$ ;IF NE NO CALL STCCR ;YES, SET CONTROLLER CHARACTERISTICS CALL RLPKT ;RELEASE PACKET ; ; MUST SCAN THROUGH ALL THE UCB'S ASSOCIATED WITH THIS CONTROLLER TO ; GET EACH UNIT "UNIT'S STATUS". ; .IF DF DEBUG 51$: BPT ;GET TO XDT MOV #NOP,51$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV #SCUCB,-(SP) ;PUSH "SCAN UCB'S" ROUTINE ON THE STACK 60$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS DURSP1 ;IF CS, ALL DONE ; ; GOT A UCB, TRY TO GET STATUS OF ITS ASSOCIATED UNIT ; .IF DF DEBUG 61$: BPT ;GET TO XDT MOV #NOP,61$ ;NOP THE BRK PNT .ENDC ;DEBUG CALL DUSTAT ;ATTEMPT TO GET UNIT STATUS BCC 60$ ;IF CC TRY FOR THE NEXT UCB ADD #10,SP ;FLUSH THE STACK CALLR REINIT ;ATTEMPT TO RE-INIT THE CONTROLLER 69$: ;REF LABEL .IF DF DEBUG CRASH ;SOMETHING'S WRONG .ENDC ;DEBUG CALL RLPKT ;RELEASE THE PACKET BR DURSP1 ;TRY AGAIN 70$: CMPB #OP.END!OP.ONL,P.OPCD(R1) ;IS THIS AN "ON-LINE" END CODE BNE 80$ ;IF NE NO CALL ONLINE ;YES, SET UNIT ON-LINE CALL RLPKT ;RELEASE PACKET BITB #US.OFL,U.ST2(R5) ;UNIT MARKED OFF-LINE? BNE DURSP1 ;IF NE YES CLR R1 ;CLR R1 TO NOTE INITIALIZATION REQUEST CALL RQRCT ;REQUEST RCT FOR UNIT INITIALIZATION BR DURSP1 ;TRY AGAIN 80$: CMPB #OP.END!OP.GUST,P.OPCD(R1) ;IS THIS A "GET UNIT STATUS" END CODE BNE 85$ ;IF NE NO CALL GTUST ;YES, SET UNIT'S STATUS CALL RLPKT ;RELEASE PACKET BR DURSP1 ;TRY AGAIN 85$: CMPB #OP.END!OP.GCS,P.OPCD(R1) ;IS THIS A "GET COMMAND STATUS" END CODE? BNE 69$ ;IF NE NO .IF DF E$$DVC CALL GTCST ;YES, GET COMMAND'S STATUS .ENDC ;E$$DVC CALL RLPKT ;RELEASE PACKET BR DURSP1 ;TRY AGAIN 90$: MOV #IS.SUC&377,C.IOSB(R3) ;ASSUME SUCCESS STATUS .IF DF D$$IAG MOV P.CRF+2(R1),R2 ;GET I/O PACKET POINTER FROM MSCP PACKET BIT #IQ.UMD,I.FCN(R2) ;IS IT A DIAGNOSTIC FUNCTION? BNE 100$ ;IF NE YES .ENDC ;D$$IAG MOV P.STS(R1),R2 ;GET STATUS/EVENT CODE BIC #^C,R2 ;SUCCESSFUL? BEQ 100$ ;IF EQ YES MOV #IE.WLK&377,C.IOSB(R3)  ;ASSUME WRITE LOCK STATUS CMP #ST.WPR,R2 ;DRIVE WRITE PROTECTED? BEQ 100$ ;IF EQ YES MOV #IE.DNR&377,C.IOSB(R3) ;ASSUME DRIVE NOT READY STATUS CMP #ST.OFL,R2 ;DRIVE OFF-LINE? BEQ 100$ ;IF EQ YES .IF DF DEBUG 91$: BPT ;GET TO XDT MOV #NOP,91$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV #IE.VER&377,C.IOSB(R3) ;NO, SET FAILURE IN STATUS CMP RCTTCB,U.ATT(R5) ;IS RCT ATTACHED? BNE 100$ ;IF NE NO CMP #ST.FER,P.STS(R1) ;IS IT A FORCED ERROR? BNE 100$ ;IF NE NO MOV #IS.RDD&377,C.IOSB(R3) ;YES, SET READ DELETED DATA IN STATUS 100$: CMPB #OP.END!OP.GUS,P.OPCD(R1) ;IS THIS A "GET UNIT STATUS" END CODE BNE 110$ ;IF NE NO CALL GTUST ;YES, GET UNIT'S STATUS BR 120$ ;AND GO ON 110$: CMP #ST.UNK,P.STS(R1) ;IS UNIT TOTALLY UNKOWN? BNE 120$ ;IF NE NO BISB #US.OFL,U.ST2(R5) ;YES, SET IT OFF-LINE BICB #US.SPU!US.VV,U.STS(R5) ;AND CLR SPIN-UP AND VOLUME VALID FLAGS 120$: BITB #EF.BBR,P.FLGS(R1) ;BAD BLOCK REPORTED? BEQ 130$ ;IF EQ NO .IF DF DEBUG 121$: BPT ;GET TO XDT MOV #NOP,121$ ;NOP THE BRK PNT .ENDC ;DEBUG CALL RQRCT ;YES, REQUEST RCT FOR BLOCK REPLACEMENT BCS 130$ ;IF CS, NO BLOCK REPLACEMENT REQUIRED ; ; REMOVE I/O PACKET FROM I/O ACTIVE QUEUE ; MOV R3,-(SP) ;SAVE CONTROLLER STATE TABLE POINTER MOV P.CRF+2(R1),R1 ;GET I/O PACKET ADDRESS FROM LO ORDER REF NUMBER MOV R5,R0 ;LOCATE THE I/O PACKET QUEUE FOR THIS UCB ADD #U.LHD,R0 ;ADD OFFSET TO I/O PACKET QUEUE CALL $QRMVT ;GET I/O PACKET FROM UNIT'S I/O QUEUE ; ; INSERT I/O PACKET INTO BAD BLOCK REPLACEMENT QUEUE ; MOV R5,R0 ;COPY UCB ADDRESS INTO R0 ADD #U.BPKT,R0 ;ADD OFFSET TO BAD BLOCK WAITING QUEUE CALL $QINSF ;INSERT I/O PACKET INTO BAD BLOCK WAITING QUEUE MOV (SP)+,R3 ;RESTORE CONTROLLER STATE TABLE POINTER CALL RLPKT ;RELEASE PACKET JMP DURSP1 ;TRY AGAIN 130$: MOV P.BCNT(R1),C.IOSB+2(R3) ;PUT BYTE COUNT FROM PACKET INTO ... ;... 2ND STATUS WORD OF CURRENT RESPONSE BLOCK 140$: ;REF LABEL .IF DF DEBUG 141$: BPT ;GET TO XDT MOV #NOP,141$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV P.CRF+2(R1),R1 ;GET I/O PACKET ADDRESS FROM LO ORDER REF NUMBER MOV R5,R0 ;LOCATE THE I/O PACKET QUEUE FOR THIS UCB ADD #U.LHD,R0 ;ADD OFFSET TO I/O PACKET QUEUE MOV (R0),-(SP) ;SAVE POINTER TO FIRST I/O PACKET MOV R3,-(SP) ;SAVE CONTROLLER STATE TABLE POINTER CALL $QRMVT ;GET I/O PACKET FROM UNIT'S I/O QUEUE MOV (SP)+,R3 ;RESTORE CONTROLLER STATE TABLE POINTER MOV R1,S.PKT(R4) ;STORE I/O PACKET ADDRESS IN SCB (FOR $IODON)  CMP R1,(SP)+ ;IS THIS THE FIRST ONE IN THE UNIT'S QUEUE? BNE 150$ ;IF NE NO TST U.LHD(R5) ;ARE THERE ANY MORE I/O PACKETS IN THE QUEUE? BEQ 150$ ;IF EQ NO MOV C.CTMO(R3),U.UTMO(R5) ;RESTART UNIT TIMEOUT COUNT MOV #-1,U.CMST(R5) ;INITIALIZE COMMAND STATUS PROGRESS REGISTER ... MOV #-1,U.CMST+2(R5) ;... AS A DOUBLE PRECISION VALUE 150$: ;REF LABEL .IF DF D$$IAG BIT #IQ.UMD,I.FCN(R1) ;DIAGNOSTIC FUNCTION? BEQ 170$ ;IF EQ NO MOV C.CRSP+2(R3),R2 ;GET POINTER TO CURRENT MSCP RESPONSE PACKET CLRB S.ROFF(R4) ;ZERO OFFSET TO FIRST REGISTER OF MSCP RESPONSE ;PACKET MOV #MSGLNG,R1 ;GET OFFSET TO FIRST REGISTER ADD R2,R1 ;ADD BASE ADDRESS OF RESPONSE PACKET MOV (R1),-(SP) ;GET MESSAGE LENGTH TSTB 1(SP) ;DID WE OVERFLOW A BYTE VALUE BEQ 160$ ;IF EQ NO MOV #IE.VER&377,C.IOSB(R3) ;NOTE FAILURE, UNABLE TO RETURN MSCP ;RESPONSE PACKET CLR C.IOSB+2(R3) ;ZERO BYTES TRANSFERRED TST (SP)+ ;CLN THE STACK BR 170$ ;AND CONTINUE 160$: ASR (SP) ;MAKE IT A WORD VALUE MOVB (SP)+,S.RCNT(R4) ;SET NUMBER OF REGISTERS TO COPY FOR MSCP ;RESPONSE PACKET CALL $CRPAS ;PASS MSCP PACKET BACK TO USER .ENDC ;D$$IAG 170$: CALL RLPKT ;RELEASE RESPONSE RING TO CONTROLLER ;+ ; **- DUDON - UDA50 DISK DRIVER I/O DONE ROUTINE ; ; THE UDA50 DISK DRIVER I/O DONE ROUTINE WILL COLLECT PERTINENT STATUS ; CONCERNING THE I/O FOR THE PACKET CONTAINED IN S.PKT(R4), RETURN ; THAT STATUS TO THE REQUESTING TASK, RELEASE SPECIAL RESOURCES ; (I.E. UMR'S), AND JUST GENERALLY FINISH UP. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; CURRENT I/O PACKET CONTAINED IN S.PKT(R4) IS FINISHED UP. ; STATUS IS OBTAINED FROM C.IOSB(R3) ; BYTES TRANSFERED IS OBTAINED FROM C.IOSB+2(R3) ; ;- DUDON: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG .IF DF M$$EXT MOV S.PKT(R4),R1 ;GET I/O PACKET ADDRESS CMPB #IO.RLB/256.,I.FCN+1(R1) ;DATA TRANSFER FUNCTION? BLO 10$ ;IF LO NO BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 10$ ;IF NE YES MOV R3,-(SP) ;SAVE R3 CALL DUUNMP ;UNMAP THE UMR MAPPING ASSIGNMENT BLOCK CALL $DEUMR ;DEASSIGN THESE UMR'S CLR (R2)+ ;FREE UP UMR WAIT BLOCK CLR (R2)+ ;... MOV (SP)+,R3 ;RESTORE R3 INC S.UMCT(R4) ;INC UMR ASSIGNMENT BLOCK COUNT .ENDC ;M$$EXT 10$: MOV C.IOSB(R3),R0 ;GET STATUS CODE FROM RESPONSE STATUS BLOCK MOV C.IOSB+2(R3),R1 ;GET BYTE COUNT FROM RESPONSE STATUS BLOCK MOV #RETRY*256.,R2 ;SET TOTAL RETRIES INTO R2 BISB C.RTRY(R3),R2 ;SET FINAL RETRY COUNT MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS CALL $IODON ;FINISH I/O OPERATION MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS CLR S.PKT(R4) ;CLR I/O PACKET POINTER IN SCB MOVB S.CON(R4),R3 ;GET CONTROLLER INDEX MOV CTTBL(R3),R3 ;GET CONTROLLER STATE TABLE POINTER ;+ ; **- DUEXIT - UDA50 DISK DRIVER EXIT ROUTINE ; ; THE UDA50 DISK DRIVER EXIT ROUTINE WILL DETERMINE IF THE DRIVER SHOULD EXIT ; TO THE SYSTEM OR IF IT HAS MORE WORK TO DO. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE DRIVER CHECKS FOR ANY MORE I/O PACKETS WAITING UNLESS THE DRIVER ; IS BLOCKED WAITING FOR UMR'S, IN WHICH CASE THE DRIVER TRIES TO EXIT ; BY QUEUING A CLOCK BLOCK IF THE DRIVER HAS I/O OUTSTANDING WITH THE ; CONTROLLER OTHERWISE THE DRIVER WILL JUST RETURN TO THE SYSTEM. ; ;- DUEXIT: TST (R4) ;MORE I/O TO DEQUEUE? BEQ 10$ ;IF EQ NO  .IF DF M$$EXT TST U.CNT(R5) ;YES, BUT ARE WE WAITING FOR UMR'S BNE 10$ ;IF NE YES .ENDC ;M$$EXT DECB C.CLCC(R3) ;LOOP COUNT CONTROL GO NEGATIVE? BMI DUCLIN ;IF MI YES CALLR DUINI ;NO, TRY TO DEQUEUE MORE I/O 10$: MOV #SCUCB,-(SP) ;PUSH "SCAN UCB'S" ROUTINE ON THE STACK 20$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 30$ ;IF CS, ALL DONE TST U.LHD(R5) ;ANY I/O OUTSTANDING? BEQ 20$ ;IF EQ NO BISB #C1.CQR,C.STAT(R3) ;YES, SET CLOCK QUEUE REQUEST BR 20$ ;TRY SOME MORE  30$: BITB #C1.CQR,C.STAT(R3) ;CLOCK QUEUE REQUEST SET? BNE DUCLIN ;IF NE YES RETURN ;NO, EXIT .PAGE ;+ ; **- DUCAN - CANCEL I/O ENTRY POINT ; ; THIS ROUTINE WILL CANCEL THE I/O OPERATION IN PROGRESS ; ; INPUTS: ; ; R0 = I/O PACKET ADDRESS ; R1 = TCB ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- DUCAN: ;;;CANCEL I/O ENTRY POINT .IF DF DU$KIL .IF DF DEBUG 1$: BPT ;;;GET TO XDT MOV #NOP,1$ ;;;NOP THE BRK PNT .ENDC ;DEBUG  MOV R1,-(SP) ;;;SAVE TCB ADDRESS MOV R5,R0 ;;;LOCATE THE I/O PACKET QUEUE FOR THIS UCB ADD #U.LHD,R0 ;;;ADD OFFSET TO I/O PACKET QUEUE CALL $QRMVT ;;;GET THE FIRST I/O PACKET IN THE QUEUE FOR ;;;THE TCB SPEICIFIED BY R1 BCC 10$ ;;;IF CC, FOUND THE DESIRED ENTRY ADD #,R0 ;;;ADD OFFSET TO BAD BLOCK REPLACEMENT QUEUE CALL $QRMVT ;;;GET THE FIRST I/O PACKET IN THE QUEUE FOR ;;;THE TCB SPECIFIED BY R1 .IF DF DEBUG BCC 10$ ;;;IF CC, ALL'S OK CRASH ;;;CRASH, CANNOT FIND THE I/O PACKET ANYWHERE .ENDC ;DEBUG 10$: MOV R1,R0 ;;;COPY THE REAL I/O PACKET ADDRESS INTO R0 MOV (SP)+,R1 ;;;RESTORE R1 .IF DF DEBUG 11$: BPT ;;;GET TO XDT MOV #NOP,11$ ;;;NOP THE BRK PNT .ENDC ;DEBUG RETURN ;;; .IFF ;DU$KIL RETURN ;;;NOP FOR FILE STRUCTURED DEVICES .ENDC ;DU$KIL .PAGE ;+ ; **- DUOUT - DEVICE TIMEOUT ENTRY POINT ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING TERMINATED. ; IF THE OPERATION WAS DIAGNOSTIC, THE QIO REQUEST IS TERMINATED. ; TIMEOUTS ARE USUALLY CAUSED BY POWERFAILURE BUT MAY ALSO BE THE ; RESULT OF HARDWARE CONSIDERATIONS. ; ; INPUTS: ; ; R0 = I/O COMPLETION CODE (IE.DNR) ; R2 = CSR ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- .ENABL LSB DUOUT: ;;;TIMEOUT ENTRY POINT .IF DF DEBUG 1$: BPT ;;;GET TO XDT MOV #NOP,1$ ;;;NOP THE BRK PNT .ENDC ;DEBUG INCB S.CTM(R4) ;;;RESET TIMEOUT COUNT 10$: RETURN ;;;EXIT ;+ ; **- DUCLIN - CLOCK QUEUE INSERTION ; ; THE CLOCK INSERTION ROUTINE CAUSES THE UDA50 DRIVER'S CLOCK BUFFER TO ; BE INSERTED INTO THE CLOCK QUEUE. IT IS SET FOR ONE SECOND. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE UDA50 DRIVER'S CLOCK BUFFER IS INSERTED INTO THE CLOCK QUEUE ; ;- DUCLIN: BICB #C1.CQR,C.STAT(R3) ;CLR CLOCK QUERE REQUEST FLAG BITB #C1.CLK,C.STAT(R3) ;CLOCK BLOCK ACTIVE? BNE 10$ ;IF NE YES BISB #C1.CLK,C.STAT(R3) ;SET CLOCK RUNNING FLAG MOV R4,R0 ;GET SCB ADDRESS ADD #S.DUCK,R0 ;COMPUTE ADDRESS OF CLOCK BLOCK MOV #DUTICK,C.SUB(R0) ;LOAD TIMEOUT ADDRESS CLR R1 ;ZERO HI ORDER DELTA TIME MOV $TKPS,R2 ;GET TICKS FOR ONE SECOND FOR LO ORDER DELTA TIME MOV #C.SYST,R4 ;DECLARE SYSTEM ROUTINE CALLR $CLINS ;REQUEST INSERTION INTO CLOCK QUEUE ;+ ; **- DUTICK - UDA50 CLOCK HANDLER ; ; THE UDA50 CLOCK HANDLER ROUTINE IS THE ENTRY POINT FOR ALL CLOCK QUEUE ; TIMEOUTS ; ; INPUTS: ; ; R4 = POINTER TO CLOCK BLOCK ; ; OUTPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS (RETRIEVED FROM "CNTBL(R3)") ; ;- DUTICK: ;REF LABEL .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG SUB #S.DUCK,R4 ;POINT BACK TO SCB MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV CNTBL(R3),R5 ;RETRIEVE LAST SAVED UCB ADDRESS MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE MOV U.DCB(R5),R0 ;YES, GET DCB ADDRESS TST D.DSP(R0) ;IS THE DRIVER IN MEMORY? BEQ 10$ ;IF EQ NO ;EXIT, DRIVER HAS JUST BEEN UNLOADED BICB #C1.CLK,C.STAT(R3) ;MARK CLOCK BLOCK AS FREE TST C.STAT(R3) ;INITIALIZATION IN PROGRESS? BMI 30$ ;IF MI YES BITB #C2.PWF,C.STAT+1(R3) ;POWERFAIL OCCUR? BEQ 20$ ;IF EQ NO CALLR DUINIT ;YES, INITIALIZE THE UDA50 20$: BITB #C2.ONL,C.STAT+1(R3) ;CONTROLLER ON-LINE IN PROGRESS? BEQ 50$ ;IF EQ NO BITB #C1.OFF,C.STAT(R3) ;CONTROLLER OFF-LINE? BNE 40$ ;IF NE YES 30$: ;REF LABEL .IF DF DEBUG 31$: BPT ;GET TO XDT MOV #NOP,31$ ;NOP THE BRK PNT .ENDC ;DEBUG DEC C.CTMO+2(R3) ;DEC CONTROLLER INITIALIZATION TIMEOUT, IS IT ZERO? BNE DUCLIN ;IF NE NO .IF DF E$$DVC CALL DUCERR ;LOG CONTROLLER TIME OUT PACKET .ENDC ;E$$DVC TST C.RTRY(R3) ;RETRIES EXHAUSTED? BNE 100$ ;IF NE NO BISB #C1.OFF,C.STAT(R3) ;HOPELESS, MARK CONTROLLER OFF-LINE ; ; MUST SCAN THROUGH ALL THE UCB'S ASSOCIATED WITH THIS CONTROLLER TO ; SET EACH UNIT OFF-LINE  ; 40$: CALLR OFFLIN ;SET ALL UNITS ASSOCIATED WITH THIS CONTROLLER ... ;... OFFLINE 50$: MOV #SCUCB,-(SP) ;PUSH "SCAN UCB'S" ROUTINE ON THE STACK 60$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 70$ ;IF CS, ALL DONE TST U.LHD(R5) ;ANY I/O OUTSTANDING? BEQ 60$ ;IF EQ NO DEC U.UTMO(R5) ;DEC TIMEOUT COUNT, IS IT ZERO? BNE 60$ ;IF NE NO .IF DF E$$DVC CALL DUGCS ;ISSUE "GET COMMAND STATUS" PACKET .ENDC ;E$$DVC BR 60$ ;GO AGAIN 70$: ;REF LABEL ; ; SEE IF THE CONTROLLER IS LURKING ABOUT ; .IF DF DEBUG 71$: BPT ;GET TO XDT MOV #NOP,71$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS TST UDASA(R2) ;DID CONTROLLER DIE? BNE 100$ ;IF NE YES 80$: ;REF LABEL .IF DF DEBUG 81$: BPT ;GET TO XDT MOV #NOP,81$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB C.ILCC(R3),C.CLCC(R3) ;INITIALIZE LOOP COUNT CONTROL MOV C.RING(R3),R0 ;RETRIEVE BASE OF RINGS TST RSPINT(R0) ;IS INTERRUPT FOR RESPONSE RING NOT EMPTY? BNE 90$ ;IF NE YES CALLR DUINI ;NO, ATTEMPT DEQUEUE ANY COMMANDS (IF AVAILABLE) 90$: CLR RSPINT(R0) ;CLR INTERRUPT STATUS WORD CALLR DURSP ;GO PROCESS ANY RESPONSES 100$: ;REF LABEL .IF DF DEBUG 101$: BPT ;GET TO XDT MOV #NOP,101$ ;NOP THE BRK PNT .ENDC ;DEBUG CALLR REINIT ;YES, RE-INITIALIZATION REUIRED .DSABL LSB .PAGE ;+ ; **- DUPWF - DEVICE POWERFAIL RECOVERY ENTRY ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND THEREFORE CAUSES ; NO IMMEDIATE ACTION ON THE DEVICE. THIS IS DONE TO AVOID A RACE CONDITION ; THAT COULD EXIST IN RESTARTING THE I/O OPERATION. ; ; INPUTS: ; ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; LOCATION OF DEVICE-COMMON RING AND PACKET AREA IS COMPUTED ; AND A REQUEST IS MADE TO INITIALIZE THE CONTROLLER. ; ;- DUPWF: ;POWERFAIL ENTRY POINT .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG BISB #US.SPU,U.STS(R5) ;MARK UNIT AS "SPINNING UP" BICB #US.VV,U.STS(R5) ;CLR VOLUME VALID FLAG BIT #C2.PWF*400,@CTTBL(R3) ;CONTROLLER ALREADY MARKED FOR POWERFAIL? BEQ DUPWF1 ;IF EQ NO RETURN ;EXIT DUPWF1: TST DUDCB ;DO WE HAVE DU:'S FIRST DCB ADDRESS BNE 10$ ;IF NE YES MOV U.DCB(R5),DUDCB ;NO, ASSUME THIS UCB POINTS TO THE FIRST DU: DCB 10$: MOV R5,CNTBL(R3) ;SAVE THE UCB ADDRESS FOR INITIALIZATION INTERRUPTS MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER BIC #^C,C.STAT(R3) ;RESET ALL FLAGS BUT CLOCK ACTIVE FLAG BISB #C2.PWF,C.STAT+1(R3) ;SET CONTROLLER POWERFAIL INDICATOR MOV #SCUCB,-(SP) ;PUSH ADDRESS OF "SCAN UCB'S" ON THE STACK 20$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS DUPWF2 ;IF CS, NO MORE UCB'S TST U.LHD+2(R5) ;I/O PACKET QUEUE ALREADY INITIALIZED? BNE 30$ ;IF NE YES MOV #U.LHD,U.LHD+2(R5) ;NO, SET UP FOR ZERO ENTRY QUEUE ADD R5,U.LHD+2(R5) ;SHOW IT IS EMPTY 30$: TST U.BPKT+2(R5) ;REPLACEMENT QUEUE ALREADY INITIALIZED? BNE 40$ ;IF NE YES MOV #U.BPKT,U.BPKT+2(R5) ;NO SET UP FOR ZERO ENTRY QUEUE ADD R5,U.BPKT+2(R5) ;SHOW IT IS EMPTY 40$: MOV #-1,U.CMST(R5) ;INITIALIZE COMMAND STATUS PROGRESS REGISTER ... MOV #-1,U.CMST+2(R5) ;... AS A DOUBLE PRECISION VALUE BR 20$ ;TRY FOR ANOTHER ONE DUPWF2: MOVB #RETRY,C.RTRY(R3) ;SET RETRY COUNT MOV C.PKT(R3),C.PKT+2(R3) ;POINT TO FIRST FREE PACKET MOVB C.PKTS(R3),C.NMBR(R3) ;INITIALIZE NUMBER OF AVAILABLE PACKETS CLR C.CMDS(R3) ;INITIALIZE COMMANDS ISSUED COUNT RETURN ;AND EXIT .PAGE ;+ ; **- DUINIT - UDA50 CONTROLLER INITIALIZATION ROUTINE ; ; THE UDA50 CONTROLLER INITIALIZATION ROUTINE WILL START THE INITIALIZATION ; PROCESS FOR THE UDA50 CONTROLLER. IT WILL INSURE THE PROPER PARAMETERS ; ARE SET UP AND INITIATE OPENING THE "VIRTUAL CIRCUIT". ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; SET INITIALIZATION BITS IN THE CONTROLLER STATE TABLE ; ;- DUINIT: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB #C2.INI,C.STAT+1(R3) ;SET CONTROLLER INITIALIZATION IN ;PROGRESS ... MOV #10.,C.CTMO(R3) ;SET 10 SEC TIMER IN CONTROLLER TIMEOUT MOV C.CTMO(R3),C.CTMO+2(R3) ;SET TIMER VALUE CALL STINT ;SET INITIALIZATION PARAMETERS MOVB S.VCT(R4),(R1) ;SET INTERRUPT VECTOR BISB #INTE,(R1)+ ;SET INTERRUPT ENABLE $STEPI == .-2 MOVB C.STP1(R3),(R1) ;STORE COMMAND/RESPONSE RING SIZE AWAY BISB #ERROR/256.,(R1)+ ;FINISH SET UP OF THIS ENTRY $STEP1 == .-2 MOV #DUCLIN,-(SP) ;RETURN BY INSERTING UDA50 CLOCK BLOCK CALLR DUOPEN ;INITIALIZE CONTROLLER ;+ ; **- DUINT1 - UDA50 INITIALIZATION CONTINUATION AFTER "VIRTUAL CIRCUIT" IS ; OPENED ; ; THE UDA50 INITIALIZATION CONTINUATION OCCURS AFTER THE FINAL INTERRRUPT ; FROM OPENING THE CONTROLLER'S "VIRTUAL CIRCUIT". AT THIS POINT, THOSE ; CONTROLLER CHARACTERISTICS WHICH ARE SETTABLE ARE SET. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; SET CONTROLLER ON-LINE AND THOSE CHARACTERISTICS OF INTEREST ; ;- DUINT1: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB #C2.ONL,C.STAT+1(R3) ;SET CONTROLLER ON-LINE IN PROGRESS FLAG MOV C.CTMO(R3),C.CTMO+2(R3) ;SET TIMER VALUE 10$: MOV #P.LENG,R0 ;SET-UP COMMAND PACKET LENGTH MOV #1,R1 ;SET-UP VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD CALL GTPKT ;DID WE GET THE CURRENT COMMAND PACKET IN THE RING? BCS 10$ ;IF CS NO, ... TRY, TRY AGAIN MOV R5,P.CRF(R1) ;YES, SET HI ORDER REF NUMBER TO UCB ADDRESS MOV R3,P.CRF+2(R1) ;SET LO ORDER REF NUMBER TO CONTROLLER STATE TABLE MOVB #OP.SCC,P.OPCD(R1) ;SET "SET CONTROLLER CHARACTERISTICS" ;OP CODE .IF DF E$$DVC MOV #CF.ATN!CF.MSC!CF.THS,P.CNTF(R1) ;SET HOST FLAGS ... ;... ALLOW ATTENTION MESSAGES, MISCELLANEOUS ;... ERROR LOGS, AND THIS HOST'S ERROR LOGS .IFF ;E$$DVC MOV #CF.ATN,P.CNTF(R1) ;SET HOST FLAGS ... ;... ALLOW ATTENTION MESSAGES .ENDC ;E$$DVC MOV #0,P.HTMO(R1) ;SET HOST TIMEOUT ;ZERO KEEPS THE UDA50 FROM TIMING THE HOST OUT CALLR DUCMD3 ;ISSUE I/O .PAGE ;+ ; **- SETR - SET UP RING BUFFER POINTERS TO MSCP PACKETS ; ; THIS ROUTINE SETS UP THE RING BUFFER POINTERS TO MSCP PACKETS ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; ; OUTPUTS: ; ; RING BUFFERS ARE POINTING TO MSCP PACKETS ; ;- SETR: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB C.RSP(R3),-(SP) ;GET NUMBER OF RESPONSE RINGS REQUIRED MOV #L.LENG,R0 ;SET LENGTH OF A RESPONSE PACKET MOV C.CRSP(R3),R1 ;GET POINTER TO CURRENT RESPONSE RING BUFFER ADD #LADDR,R1 ;ADD OFFSET TO LO ORDER ADDRESS WORD CALL ALPKT ;ALLOCATE AN MSCP PACKET .IF DF DEBUG BCC 10$ ;IF CC, ALL'S OK CRASH ;CRASH, FAILURE TO ALLOCATE A PACKET .ENDC ;DEBUG 10$: MOV R2,C.CRSP+2(R3) ;STORE PACKET POINTER IN CURRENT RESPONSE RING ;BUFFER POINTER TABLE MOV R2,C.FRSP+2(R3) ;AND IN THE FIRST RESPONSE RING BUFFER POINTER MOV R2,C.LRSP+2(R3) ;PREPARE TO FIND LAST RESPONSE RING BUFFER ;PACKET 20$: MOV R2,(R1) ;INSERT ADDRESS INTO THE LOW PART OF RING ADD C.RELC+2(R3),(R1)+ ;ADD RELOCATION CONSTANT ADC (R1) ;ADD CARRY ADD C.RELC(R3),(R1) ;NOW THE HIGH RELOCATION CONSTANT BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? .IF DF M$$EXT BNE 25$ ;IF NE YES BIC #^C<3>,(R1) ;BIT CLEAR ALL BUT LOW TWO ADDRESS BITS 25$: ;REF LABEL  .IFF ;M$$EXT BIC #^C<3>,(R1) ;BIT CLEAR ALL BUT LOW TWO ADDRESS BITS .ENDC ;M$$EXT BIS #OWN!FLAG,(R1)+ ;MARK RESPONSE RING BUFFER UDA "OWN'ED" AND ;INTERRUPTABLE DECB (SP) ;COUNT THIS ONE, ARE WE DONE? BEQ 40$ ;IF EQ YES CALL ALPKT ;ALLOCATE ANOTHER PACKET .IF DF DEBUG BCC 30$ ;IF CC, ALL'S WELL CRASH ;CRASH, FAILURE TO ALLOCATE A PACKET .ENDC ;DEBUG 30$: ADD R0,C.LRSP+2(R3) ;LOCATE NEW LAST RESPONSE PACKET BR 20$ ;TRY ANOTHER PACKET 40$: MOVB C.CMD(R3),(SP) ;GET NUMBER OF COMMAND RINGS MOV #P.LENG,R0 ;SET LENGTH OF A COMMAND PACKET MOV C.CCMD(R3),R1 ;GET CURRENT COMMAND PACKET POINTER ADD #LADDR,R1 ;ADD OFFSET TO LO ORDER ADDRESS WORD CALL ALPKT ;ALLOCATE AN MSCP PACKET .IF DF DEBUG BCC 50$ ;IF CC, ALL'S OK CRASH ;CRASH, FAILURE TO ALLOCATE A PACKET .ENDC ;DEBUG 50$: MOV R2,C.CCMD+2(R3) ;STORE PACKET POINTER IN CURRENT COMMAND RING ;BUFFER POINTER TABLE MOV R2,C.FCMD+2(R3) ;AND IN THE FIRST COMMAD RING BUFFER POINTER MOV R2,C.LCMD+2(R3) ;PREPARE TO FIND LAST COMMAND RING BUFFER ;PACKET 60$: MOV R2,(R1) ;INSERT ADDRESS INTO THE LOW PART OF RING ADD C.RELC+2(R3),(R1)+ ;ADD RELOCATION CONSTANT ADC (R1) ;ADD CARRY .IF DF M$$EXT ADD C.RELC(R3),(R1)+ ;NOW THE HIGH RELOCATION CONSTANT BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 65$ ;IF NE YES BIC #^C<3>,-2(R1) ;BIT CLEAR ALL BUT LOW TWO ADDRESS BITS 65$: ;REF LABEL .IFF ;M$$EXT ADD C.RELC(R3),(R1) ;NOW THE HIGH RELOCATION CONSTANT BIC #^C<3>,(R1)+ ;BIT CLEAR ALL BUT LOW TWO ADDRESS BITS .ENDC ;M$$EXT DECB (SP) ;COUNT THIS ONE, ARE WE DONE? BEQ 80$ ;IF EQ YES CALL ALPKT ;ALLOCATE ANOTHER PACKET .IF DF DEBUG BCC 70$ ;IF CC, ALL'S WELL CRASH ;CRASH, FAILURE TO ALLOCATE A PACKET .ENDC ;DEBUG 70$: ADD R0,C.LCMD+2(R3) ;LOCATE NEW LAST COMMAND PACKET BR 60$ ;TRY ANOTHER PACKET 80$: TST (SP)+ ;CLEAN UP THE STACK RETURN ;EXIT ;+ ; **- GTPKT - GET A COMMAND PACKET  ; ; THIS ROUTINE WILL CHECK THE COMMAND RING BUFFER FOR THE FIRST AVAILABLE ; COMMAND PACKET. IT WILL RETURN THE ADDRESS IF ONE IS FREE, OTHERWISE ; IT RETURNS CARRY SET IF THERE IS NONE. ; ; INPUTS: ; ; R0 = COMMAND PACKET LENGTH ; R1 = VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD VALUE ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF SUCCES: ; C = 0 IF COMMAND PACKET IS AVAILABLE ; R1 = ADDRESS OF CURRENT COMMAND RING PACKET ; ; IF FAILURE: ; C = 1 IF COMMAND PACKET IS NOT AVAILABLE ; ;- GTPKT: TST @C.CCMD(R3) ;DOES THE UDA50 OWN THE CURRENT COMMAND RING ;POINTER SEC ;ASSUME FAILURE BMI 20$ ;IF MI YES MOV R1,-(SP) ;SAVE R1 MOV C.CCMD+2(R3),R1 ;RETRIEVE CURRENT COMMAND PACKET POINTER MOV R0,MSGLNG(R1) ;SET MESSAGE LENGTH MOV (SP)+,CREDIT(R1) ;SET VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELDS MOV #P.LENG/2,R0 ;SET LENGTH OF AN MSCP COMMAND PACKET 10$: CLR (R1)+ ;INITIALIZE MSCP PACKET SOB R0,10$ ;LOOP MOV C.CCMD+2(R3),R1 ;RETRIEVE CURRENT COMMAND PACKET POINTER CLC ;CLR CARRY 20$: RETURN ;RETURN ;+ ; **- RLPKT - RELEASE A RESPONSE PACKET ; ; THIS ROUTINE WILL CHECK THE RESPONSE RING BUFFER FOR THE FIRST AVAILABLE ; RESPONSE PACKET. IT WILL MARK IT "UDA OWN". ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; RESPONSE PACKET IS MARKED "UDA OWN'ED" ; ;- RLPKT: TST @C.CRSP(R3) ;DOES THE UDA50 OWN THIS ENTRY? .IF DF DEBUG BPL 10$ ;IF PL NO CRASH ;SOMETHING'S WRONG BR RLPKT ;TRY AGAIN .IFF ;DEBUG BMI RLPKT ;IF MI YES, LOOP .ENDC ;DEBUG 10$: BIS #OWN!FLAG,@C.CRSP(R3) ;NO, THEN MARK IT UDA "OWN" AND INTERRUPTABLE ADD #RNGSIZ,C.CRSP(R3) ;POINT TO NEXT ENTRY IN RESPONSE RING ADD #RSPLNG,C.CRSP+2(R3) ;AND ITS PACKET CMP C.LRSP(R3),C.CRSP(R3) ;IS THIS THE LAST ONE? BHIS 20$ ;IF HIS NO MOV C.FRSP(R3),C.CRSP(R3) ;RESET POINTER TO FIRST ONE MOV C.FRSP+2(R3),C.CRSP+2(R3) ;AND ITS PACKET 20$: RETURN ;RETURN ;+ ; **- ALPKT - ALLOCATE MSCP PACKET ; ; THIS ROUTINE IS CALLED TO ALLOCATE AN MSCP PACKET. ; ; INPUTS: ; ; R0 = LENGTH OF PACKET TO BE ALLOCATED ; ; OUTPUTS: ; ; IF SUCCESS: ; C = 0 IF THE PACKET IS ALLOCATED. ; R2 = POINTER TO PACKET ; ; IF FAILURE: ; C = 1 IF INSUFFICIENT CORE IS AVAILABLE TO ALLOCATE THE PACKET. ; ;- ALPKT: SEC ;ASSUME FAILURE DECB C.NMBR(R3) ;ANY MORE PACKETS? BLT 20$ ;IF LT NO MOV C.PKT+2(R3),R2 ;FREE PACKET? .IF DF DEBUG CMP #DUEND,R2 BLO 1$ CMP DUEND,R2 BLOS 2$ 1$: BPT 2$: .ENDC ;DEBUG MOV R2,C.PKT+2(R3) ;COPY ADDRESS OF CURRENT PACKET TO FIND THE NEXT ADD R0,C.PKT+2(R3) ;ADD THE LENGTH OF THE PACKET ... ADD #ENVLP,C.PKT+2(R3) ;... PLUS THE ENVELOPE 10$: MOV R0,(R2)+ ;SET MSCP COMMAND/RESPONSE LENGTH CLR (R2)+ ;CLEAR VIRTUAL CIRCUIT IDENTIFIER 20$: RETURN ;EXIT ;+ ; **- DUPOLL - POLL RESPONSE RING ROUTINE ; ; THIS ROUTINE WILL SCAN THE RESPONSE RING LOOKING FOR ANY RESPONSES ; RETURNED BY THE UDA50. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF SUCCES: ; C = 0 IF RESPONSE PACKET IS AVAILABLE ; R0 = MESSAGE TYPE FIELD ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R2 = HI ORDER REF NUMBER FROM PACKET ; ; IF FAILURE: ; C = 1 IF RESPONSE PACKET IS NOT AVAILABLE ; ;- DUPOLL: TST C.STAT(R3) ;IS CONTROLLER OPERATIONAL? BLE 60$ ;IF LE NO TST @C.CRSP(R3) ;DOES THE UDA50 OWN THIS ENTRY? BMI 60$ ;IF MI YES MOV C.CRSP+2(R3),R1 ;GET CURRENT RESPONSE RING PACKET POINTER MOV P.CRF(R1),R2 ;GET HI ORDER REF NUMBER FROM PACKET CLR -(SP) ;GET A WORKING REGISTER MOVB CREDIT(R1),(SP) ;OBTAIN MESSAGE/CREDIT FIELDS BIC #^C,(SP) ;CLR ALL BUT CREDIT/DEBIT FIELD ADD (SP)+,C.CMDS(R3) ;INC CONTROLLER'S COMMAND LIMIT MOV CREDIT(R1),R0 ;OBTAIN MESSAGE/CREDIT FIELDS BIC #^C,R0 ;CLR ALL BUT MESSAGE TYPE FIELD .IF DF DEBUG TSTB VCID(R1) ;IS THIS FROM A DISK MSCP VIRTUAL CIRCUIT?  BEQ 10$ ;IF NE NO CRASH ;SOMETHING'S WRONG BR 60$ ;TRY TO EXIT .ENDC ;DEBUG ; ; R0 = CONTENTS OF MESSAGE TYPE FIELD ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R2 = HI ORDER REF NUMBER FROM THE RESPONSE PACKET ; 10$: CMPB #,R0 ;IS THIS RESPONSE FOR A MAINTENANCE PACKET? BNE 30$ ;IF NE NO .IF DF D$$IAG .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG CALL DUDPKT ;YES, HANDLE ALL DIAGNOSTIC PACKETS .ENDC ;D$$IAG 20$: CALL RLPKT ;RELEASE PACKET BR DUPOLL ; 30$: CMPB #,R0 ;IS THIS RESPONSE A CREDIT NOTICE PACKET? BEQ 20$ ;IF EQ YES CMPB #,R0 ;IS THIS RESPONSE A DATAGRAM PACKET? .IF DF E$$DVC BNE 40$ ;IF NE NO, .IF DF DEBUG 31$: BPT ;GET TO XDT MOV #NOP,31$ ;NOP THE BRK PNT .ENDC ;DEBUG CALL DULERR ;MUST BE SOME KIND OF ERROR LOG PACKET BR 20$ ; .IFF ;E$$DVC BEQ 20$ ;IF EQ YES .ENDC ;E$$DVC 40$: CMP #,R0 ;IS THIS RESPONSE A SEQENTIAL PACKET? BNE 60$ ;IF NE NO CLC ;YES, FORCE CARRY CLR 50$: RETURN ;AND EXIT 60$: SEC ;SET CARRY TO SHOW FAILURE RETURN ;AND EXIT ;+ ; **- DUINIO - DEVICE I/O INITIATION ENTRY POINT ; ; THE DEVICE I/O INITIATION ENTRY POINT IS USED TO PROVIDE ; A CENTRALIZED PLACE TO MAKE MSCP COMMAND PACKETS "KNOWN" ; TO THE HARDWARE SUBSYTEM. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF C = 0 THEN REQUESTED I/O IS INSERTED INTO COMMAND RING ; ; CURRENT COMMAND RING POINTER IS UPDATED TO POINT TO NEXT ; COMMAND RING ENTRY ; ; IF C = 1 THEN REQUESTED I/O IS NOT INSERTED INTO COMMAND RING ; ;- DUINIO: MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS TST UDASA(R2) ;IS UDA50 ON-LINE? SEC ;ASSUME NOT BNE 10$ ;IF NE NO BIS #OWN!FLAG,@C.CCMD(R3) ;SET RING TO UDA "OWN" AND INTERRUPTABLE TST UDAIP(R2) ;FORCE A POLL BIC #^C,R0 ;CLR ALL BUT CREDIT/DEBIT FIELD SUB R0,C.CMDS(R3) ;DEC CONTROLLER'S COMMAND LIMIT BY DEBIT AMOUNT ADD #RNGSIZ,C.CCMD(R3) ;POINT TO NEXT ENTRY IN COMMAND RING ADD #CMDLNG,C.CCMD+2(R3) ;AND ITS PACKET CMP C.LCMD(R3),C.CCMD(R3) ;IS THIS THE LAST ONE? BHIS 10$ ;IF HIS NO MOV C.FCMD(R3),C.CCMD(R3) ;RESET POINTER TO FIRST ONE MOV C.FCMD+2(R3),C.CCMD+2(R3) ;AND ITS PACKET CLC ;SHOW SUCCESS 10$: RETURN ;RETURN ;+ ; **- PRTST - TEST I/O PORT ; ; INPUTS: ; ; R1 = I/O PACKET ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF THERE IS (POTENTIALLY) A PACKET IN THE I/O QUEUE THAT ; CAN BE PROCESSED: ; ; RETURN TO THE CALLER ; ; IF NOT: ; ; RETURN TO THE CALLER'S CALLER ; ; EXCEPT WHEN A CONTROLLER POWERFAIL HAS OCCURRED, ; THEN ADJUST RETURN ADDRESS TO POINT TO UDA50 ; CONTROLLER INITIALIZATION ROUTINE. ; ;- PRTST: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R3,-(SP) ;SAVE R3 MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER BITB #C2.PWF,C.STAT+1(R3) ;CONTROLLER POWERFAIL INDICATED? BNE 50$ ;IF NE YES TST @C.CCMD(R3) ;DOES UDA50 "OWN" THIS ENTRY? BMI 60$ ;IF MI YES TST C.CMDS(R3) ;CONTROLLER COMMAND LIMIT EXHAUSTED? BLE 30$ ;IF LE YES BITB #US.VV,U.STS(R5) ;UNIT VOLUME VALID SET? BEQ 40$ ;IF EQ NO BITB #US.SPU,U.STS(R5) ;UNIT BEING BROUGHT ON-LINE? BNE 60$ ;IF NE YES CMPB #IO.RLB/256.,I.FCN+1(R1) ;DATA TRANSFER FUNCTION? BLO 10$ ;IF LO NO, ACCEPT THE PACKET .IF DF M$$EXT TST U.CNT(R5) ;IS THIS UNIT WAITING FOR UMR'S BNE 30$ ;IF NE YES TST S.UMCT(R4) ;DO WE HAVE ANY MORE UMR WAIT BLOCK(S)? BEQ 30$ ;IF EQ NO .ENDC ;M$$EXT ; ; ACCEPT PACKET ; 10$: CLC ;CLR CARRY -- ACCEPT THE PACKET 20$: MOV (SP)+,R3 ;RESTORE R3 RETURN ;RETURN ; ; REJECT PACKET ; 30$: SEC ;SET CARRY -- REJECT THE PACKET BR 20$ ;AND EXIT ; ; DRIVE NEEDS TO BE BROUGHT ON-LINE ; 40$: ;REF LABEL .IF DF DEBUG 41$: BPT ;GET TO XDT MOV #NOP,41$ ;NOP THE BRK PNT .ENDC ;DEBUG BISB #US.VV,U.STS(R5) ;NOTE THAT UNIT IS BEING BROUGHT ON-LINE MOV #DUONL,G$$SPA+2(SP) ;ADJUST THE RETURN ADDRESS IN ORDER ;TO GO TO UNIT ON-LINE ROUTINE BR 60$ ;AND GO ON ; ; CONTROLLER REQUIRES INITIALIZATION ; 50$: ;REF LABEL .IF DF DEBUG 51$: BPT ;GET TO XDT MOV #NOP,51$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV #DUINIT,G$$SPA+2(SP) ;ADJUST THE RETURN ADDRESS IN ORDER ;TO GO TO CONTROLLER INITIALIZATION ROUTINE ; ; FOUND A PACKET THAT CAN BE DEQUEUED IF THE CONTROLLER WILL FREE UP ; A COMMAND PACKET SLOT ; 60$: ;REF LABEL .IF DF DEBUG 61$: BPT ;GET TO XDT MOV #NOP,61$ ;NOP THE BRK PNT .ENDC ;DEBUG ADD #G$$SPA+2,SP ;FLUSH THE STACK RETURN ;RETURN TO ADDRESS ON THE STACK ;+ ; **- MAPR - MAP DRIVER'S RING BUFFER AREA ; ; THIS ROUTINE MAPS THE DRIVER'S PRIVATE DATA BASE OF RINGS AND ; PACKETS. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; DRIVER'S PRIVATE DATA BASE OF RINGS AND PACKETS ARE MAPPED ; ON A CONTROLLER SPECIFIC BASIS. ; ;- MAPR: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG CLR R0 ;CLR R0 ... CLR R1 ;... AND R1 CMP #DUSTRT,#120000 ;LOADABLE DRIVER? BLO 40$ ;IF LO NO MOV @#KINAR5,R0 ;GET START OF DRIVER CODE MOV R0,C.PAR5(R3) ;SAVE THE DRIVER'S MAPPING .IF DF DU$BIG MOV R0,C.PAR6(R3) ;COPY THE START FOR GREATER THAN 4K WORDS ADD #200,C.PAR6(R3) ;MAKE IT CONTIGUOUS TO THE START OF THE DRIVER .ENDC ;DU$BIG MOV R0,R1 ;COPY REAL START OF DRIVER AREA .IF DF M$$EIS CLR R0 ;INITIALIZE R0 ASHC #6.,R0 ;CALCULATE PHYSICAL ADDRESS .IFF ;M$$EIS MOV R1,R0 ;GET START OF PHYSICAL ADDRESS SWAB R0 ;USE NON-EIS EMULATION OF "ASHC #6.,R0" ... BIC #177400,R0 ;... TO CALCULATE PHYSICAL ADDRESS SWAB R1 ; BIC #377,R1 ; ROR R0 ; ROR R1 ; ROR R0 ; ROR R1 ; .ENDC ;M$$EIS .IF DF M$$EXT ; ; SET UP SELECTED UMR TO MAP ALL OF THE DRIVER DATA AREA. ; SAVE THE UMR VALUES IN THE UMR WORK AREA IN THIS CONTROLLER'S ; SCB. ; BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 40$ ;IF NE YES TST @#$UMRPT ;UNIBUS MAP AVAILABLE? BEQ 20$ ;IF EQ NO TST S.MPR+M.UMRN+2(R4) ;STATIC UMR ALREADY SET-UP? BNE 20$ ;IF NE YES MOV R1,S.MPR+M.BFVL+2(R4) ;SET UP LO 16-BITS OF ADDRESS MOVB R0,S.MPR+M.BFVH+2(R4) ;SET UP HI 6-BITS OF ADDRESS .IF NDF DU$BIG MOV #4,S.MPR+M.UMRN+2(R4) ;SET UP COUNT FOR 1 UMR .IFF ;DU$BIG MOV #8.,S.MPR+M.UMRN+2(R4) ;SET UP COUNT FOR 2 UMR'S .ENDC ;DU$BIG 10$: MOV R4,R0 ;COPY SCB POINT TO R0 ADD #S.MPR+2,R0 ;POINT R0 TO UMR MAPPING BLOCK + 2 CALL $ASUMR ;GO ASSIGN UMR'S BCS 10$ ;IF CS, TRY AGAIN ; ; LOAD SELECTED UMR FOR THIS CONTROLLER TO MAP DRIVER WITH 18-BIT ADDRESSES ; TRANSFORMED FROM DRIVER VIRTUAL ADDRESSES ; 20$: TST $UMRPT ;IS UNIBUS MAP AVAILABLE? BEQ 30$ ;IF EQ NO MOV R4,R0 ;COPY SCB ADDRESS ADD #S.MPR+2,R0 ;POINT TO UMR MAPPING BLOCK + 2 TST M.UMRN(R0) ;HAVE WE ASSIGNED THE UMR'S BEQ 30$ ;IF EQ YES CALL $MPUB1 ;MAP THE UNIBUS 30$: MOV S.MPR+M.UMVL+2(R4),R1 ;GET LO 16-BITS OF VIRTUAL ADDRESS MOVB S.MPR+M.UMVH+2(R4),R0 ;GET HI 2-BITS OF VIRTUAL ADDRESS ASR R0 ;SHIFT BITS <4:5> RIGHT TO <0:1> ASR R0 ;... ASR R0 ;... ASR R0 ;... SUB #120000,R1 ;SUBTRACT DRIVER BASE VIRTUAL ADDRESS SBC R0 ;SUBTRACT CARRY FROM R0 BIC #^C<3>,R0 ;CLEAR ALL BUT BITS <0:1> .IFF ;M$$EXT SUB #120000,R1 ;SUBTRACT DRIVER BASE VIRTUAL ADDRESS SBC R0 ;SUBTRACT CARRY FROM R0 BIC #^C<3>,R0 ;CLEAR ALL BUT BITS <0:1> .ENDC ;M$$EXT ; ; RELOCATION CONSTANT IS USED TO TRANSFORM A VIRTUAL ADDRESS WITHIN THE ; DRIVER TO A PHYSICAL ADDRESS. THIS RELOCATION IS REQUIRED WHENEVER MEMORY ; MANAGEMENT IS PRESENT. THE FORMAT OF THE DOUBLE WORD RELOCATION CONSTANT ; IS SUCH THAT WHEN IT IS ADDED TO A VIRTUAL ADDRESS IN THE RANGE ; 120000-157777 (CARRY IS ADDED TO BIT 0 OF THE HIGH ORDER WORD), THE RESULT ; IS THE 18-BIT PHYSICAL ADDRESS (2 HIGH BITS IN BITS 0-1 OF C.RELC, 16 LOW ; BITS IN C.RELC+2). ; ; THE RELOCATION CONSTANT IS CALCULATED AND STORED HERE BY THE ; INITIALIZATION CODE. ; ; ; COMPUTE AND SAVE THE DOUBLE WORD RELOCATION CONSTANT TO TRANSFORM A ; DRIVER VIRTUAL ADDRESS INTO AN 18-BIT ADDRESS. ; 40$: MOV R0,C.RELC(R3) ;SAVE RELOCATION CONSTANT MOV R1,C.RELC+2(R3) ;... .IF DF DU$BIG CMP #DUSTRT,#120000 ;LOADABLE DRIVER? BHIS 60$ ;IF HIS YES CMP #DUEND,#140000 ;DRIVER GREATER THAN 4K WORDS BLO 60$ ;IF LO NO .IF DF DEBUG 41$: BPT ;GET TO XDT MOV #NOP,41$ ;NOP THE BRK PNT .ENDC ;DEBUG 50$: CRASH ;SOMETHING'S WRONG HALT ;HALT THE PROCESS IF USER TRIES TO GO ON! BR 50$ ;DON'T GO ANY FURTHER .ENDC ;DU$BIG 60$: MOVB C.RSP(R3),R1 ;GET NUMBER ENTRIES IN RESPONSE RING BUFFER MOV #RNGSIZ,R0 ;GET SIZE OF A RING ENTRY CALL $MUL ;COMPUTE SIZE OF RESPONSE RING BUFFER MOV R1,-(SP) ;SAVE SIZE OF RESPONSE RINGS SUB #RNGSIZ,(SP) ;LESS ONE RING ENTRY MOV C.RING(R3),R1 ;DEFINE START OF RESPONSE RING FOR THIS CONTROLLER TST (R1)+ ;POINT HI ORDER ENTRY OF RING MOV R1,C.CRSP(R3) ;STORE IT IN CURRENT RESPONSE RING BUFFER ;POINTER MOV R1,C.FRSP(R3) ;AND IN FIRST RESPONSE RING BUFFER POINTER ADD (SP)+,R1 ;LOCATE LAST MESAGE RING BUFFER MOV R1,C.LRSP(R3) ;AND STORE IT IN LAST RESPONSE RING BUFFER ;POINTER ADD #RNGSIZ,R1 ;LOCATE COMMAND RING BUFFER MOV R1,C.CCMD(R3) ;STORE IT IN CURRENT COMMAND RING BUFFER ;POINTER MOV R1,C.FCMD(R3) ;AND IN FIRST COMMAND RING BUFFER POINTER MOVB C.CMD(R3),R1 ;GET NUMBER OF ENTRIES IN COMMAND RINGS MOV #RNGSIZ,R0 ;GET SIZE OF A RING ENTRY CALL $MUL ;COMPUTE SIZE OF COMMAND RING BUFFER SUB #RNGSIZ,R1 ;COMPENSATE FOR FIRST ENTRY ADD C.FCMD(R3),R1 ;LOCATE LAST COMMAND RING BUFFER MOV R1,C.LCMD(R3) ;AND STORE IT IN LAST COMMAND RING BUFFER ;POINTER MOV C.INIT+2(R3),R1 ;RETRIEVE CURRENT STEP WORD POINTER MOV C.FRSP(R3),(R1) ;START SET UP OF LO ORDER RING BYTE ADDRESS $STEP2 == .-2 ADD #LADDR,(R1) ;ADD OFFSET TO LO ORDER RING BYTE ADDRESS ADD C.RELC+2(R3),(R1)+ ;ADD LO ORDER RELOCATION CONSTANT MOV #HADDR,(R1) ;INITIALIZE HI BYTE ADDRESS ADC (R1) ;ADD CARRY ADD C.RELC(R3),(R1)+ ;NOW ADD THE HI ORDER RELOCATION CONSTANT $STEP3 == .-2 .IF DF E$$DVC MOV #LFAIL!GO,(R1)+ ;SET LAST FAILURE FLAG AND ... ;... CONTROLLER GO-BIT $STEP4 == .-2 .IFF ;E$$DVC MOV #GO,(R1)+ ;SET CONTROLLER GO-BIT $STEP4 == .-2 .ENDC ;E$$DVC RETURN ;EXIT ;+ ; **- DUOPEN - OPEN "VIRTUAL CIRCUIT" WITH UDA50 CONTROLLER ; ; THE OPEN "VIRTUAL CIRCUIT" ENTRY POINT IS USED TO INITIALIZE (RE-INIT) THE ; UDA50 PORT INTERFACE. CALLED ONCE PER CONTROLLER. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; C = 0 IF CONTROLLER IS INITIALIZED ; C = 1 IF CONTROLLER IS NOT INITIALIZED ; ;- .ENABL LSB DUOPEN: CALL MAPIT ;MAP TO INITIALIZATION TABLE MOV #STEP1,UDAIP(R2) ;HARD INIT CONTROLLER CALL 50$ ;STEP FUNCTION SUCCESSFUL? BCS 20$ ;IF CS, NO RETURN ;EXIT DUOPN2: CALL MAPIT ;MAP TO INITIALIZATION TABLE 10$: CMPB -1(R1),UDASA(R2) ;DID THE RING'S LENGTH ECHO SUCCESSFULLY? BNE 20$ ;IF NE NO CALL 50$ ;STEP FUNCTION SUCCESSFUL? BCS 20$ ;IF CS, NO RETURN ;WAIT FOR INTERRUPT DUOPN3: CALL MAPIT ;MAP TO INITIALIZATION TABLE CMPB -4(R1),UDASA(R2) ;DID THE INTERRUPT VECTOR ECHO SUCCESSFULLY? BNE 20$ ;IF NE NO CALL 50$ ;STEP FUNCTION SUCCESSFUL? BCS 20$ ;IF CS, NO RETURN ;WAIT FOR INTERRUPT DUOPN4: CALL SETR ;SET UP RING BUFFER AREA CALL MAPIT ;MAP TO INITIALIZATION TABLE CALL 50$ ;STEP FUNCTION SUCCESSFUL? BCS 20$ ;IF CS, NO RETURN ;EXIT 20$: DECB C.RTRY(R3) ;ANY MORE RETRIES? BEQ 40$ ;IF EQ NO CALL STINT ;SET INITIALIZATION PARAMETERS MOVB #C2.INI,C.STAT+1(R3) ;SET CONTROLLER INITIALIZATION IN PROGRESS BISB #C1.INI,C.STAT(R3) ;SET RE-INITIALIZATION REQUIRED FLAG TST (SP)+ ;FLUSH FIRST RETURN ADDRESS 30$: BR DUOPEN ;RESTART AND RE-INIT CONTROLLER 40$: BISB #C1.OFF,C.STAT(R3) ;MARK CONTROLLER OFF-LINE .IF DF E$$DVC CALL DUCERR ;LOG CONTROLLER ERROR LOG PACKET .ENDC ;E$$DVC ; ; MUST SCAN THROUGH ALL THE UCB'S ASSOCIATED WITH THIS CONTROLLER TO ; SET EACH UNIT OFF-LINE ; CALLR OFFLIN ;SET ALL UNITS ASSOCIATED WITH THIS CONTROLLER ... ;... OFFLINE 50$: TST UDASA(R2) ;ERROR BIT? BMI 60$ ;IF MI YES BIT R0,UDASA(R2) ;STEP BIT? BEQ 50$ ;IF EQ NO MOV (R1)+,UDASA(R2) ;WRITE INITIALIZATION WORD TO UDA50 RETURN ;EXIT 60$: SEC ;MARK FAILURE RETURN ;EXIT .DSABL LSB ;+ ; **- MAPIT - MAP TO DRIVER'S INITIALIZATION TABLE ; ; THIS ROUTINE MAPS TO THE DRIVER'S INITIALIZATION TABLE. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R0 = CURRENT STEP VALUE ; R1 = ADDRESS OF CURRENT STEP IN INITIALIZATION TABLE ; R2 = CSR ADDRESS ; ;- .ENABL LSB MAPIT: MOV C.INIT(R3),R0 ;GET CURRENT STEP VALUE MOV C.INIT+2(R3),R1 ;GET CURRENT STEP WORD POINTER MOV S.CSR(R4),R2 ;GET CSR ADDRESS CALL @(SP)+ ;CALL CALLER BACK AS CO-ROUTINE MOV R1,C.INIT+2(R3) ;SAVE INIT TABLE POINTER ASL C.INIT(R3) ;MOVE TO NEXT STEP BPL 10$ ;IF PL EXIT ;OTHERWISE SET UP INITIALIZATION PARAMETERS ;+ ; **- STINT - SET INITIALIZATION PARAMETERS ; ; THIS ROUTINE SETS THE INITIALIZATION PARAMETERS FOR CONTROLLER INITIALIZATION ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = ADDRESS OF BEGINNING OF INITIALIZATION TABLE ; ;- STINT: MOV R3,R1 ;COPY POINTER TO STATE TABLE ADD #C.ITBL,R1 ;ADJUST IT TO INITIALIZATION TABLE MOV #STEP1,C.INIT(R3) ;START CONTROLLER INIT AT STEP 1 AND ... MOV R1,C.INIT+2(R3) ;... AT BEGINNING OF INITIALIZATION TABLE 10$: RETURN ;EXIT .DSABL LSB ;+ ; **- $DUINT - UDA50 CONTROLLER INTERRUPT HANDLER ; ; INTERRUPTS ARE RECEIVED FROM A CONTROLLER UNDER FOUR CIRCUMSTANCES ; THEY ARE AS FOLLOWS: ; 1. DURING THE INITIALIZATION PROCESS (OPEN THE "VIRTUAL CIRCUIT") ; 2. WHEN THE "COMMAND RING BUFFER" TRANSITIONS FROM "FULL" TO "NOT FULL" ; 3. WHEN THE "RESPONSE RING BUFFER" TRANSITIONS FROM "EMPTY" TO "NOT EMPTY" ; 4. WHEN A FATAL CONTROLLER ERROR IS DETECTED AND AN INTERRUPT CAN BE GENERATED ; FATAL CONTROLLER ERRORS ARE: ; A. FAILURE TO BECOME UNIBUS MASTER FOR DATA TRANSFER ;  B. FAILURE TO BECOME UNIBUS MASTER FOR INTERRUPT ; C. FAILURE TO ACCESS I/O PAGE REGISTERS OR COMMUNICATIONS AREA ; (I.E. NON-EXISTENT MEMORY) ; D. UNIBUS PARITY ERROR DETECTED ; ;- INTSE$ DU,PR5,R$$UDA ;;;GENERATE INTERRUPT SAVE CODE MOV R4,-(SP) ;;;SAVE R4 MOV U.SCB(R5),R4 ;;;POINT TO CONTROLLER STATUS BLOCK CLRB S.CTM(R4) ;;;DISABLE TIMEOUT ADD #S.FRK+6,R4 ;;;POINT TO END OF FORK BLOCK TST -4(R4) ;;;FORK BLOCK ALREADY IN USE? BEQ 10$ ;;;IF EQ NO MOV (SP)+,R4 ;;;RESTORE R4 RETURN ;;;EXIT FROM INTERRUPT 10$: MOV (SP)+,(R4) ;;;PUT SAVED R4 IN FORK BLOCK CALL $FORK1 ;;;CREATE A SYSTEM PROCESS MOV CTTBL(R4),R3 ;RETRIEVE CONTROLLER STATE TABLE ADDRESS MOV U.SCB(R5),R4 ;RETREIVE SCB ADDRESS CLR S.FRK+2(R4) ;FREE FORK BLOCK FOR FURTHER INTERRUPTS .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS TST UDASA(R2) ;DID THE CONTROLLER SUFFER A FATAL ERROR? BMI 60$ ;IF MI YES TSTB C.STAT+1(R3) ;CONTROLLER INITIALIZATION IN PROGRESS? BPL 40$ ;IF PL NO .IF DF DEBUG 12$: BPT ;GET TO XDT MOV #NOP,12$ ;NOP THE BRK PNT .ENDC ;DEBUG BIT #STEP2,C.INIT(R3) ;READY FOR STEP 2? BEQ 20$ ;IF EQ NO .IF DF M$$EXT CALL DUEXTM ;CHECK EXTENDED MEMORY SUPPORT .ENDC ;M$$EXT CALL MAPR ;MAP DRIVER'S RINGS AND PACKETS CALLR DUOPN2 ;CONTINUE WITH STEP 2 20$: BIT #STEP3,C.INIT(R3) ;READY FOR STEP 3? BEQ 30$ ;IF EQ NO CALLR DUOPN3 ;CONTINUE WITH STEP 3 30$: CALL DUOPN4 ;CONTINUE WITH STEP 4 CALLR DUINT1 ;YES, GO SET CONTROLLER ON-LINE 40$: ;REF LABEL .IF DF DEBUG 41$: BPT ;GET TO XDT MOV #NOP,41$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV C.RING(R3),R0 ;RETRIEVE BASE OF RINGS TST CMDINT(R0) ;IS INTERRUPT FOR COMMAND RING NOT FULL? BNE 50$ ;IF NE YES CLR RSPINT(R0) ;CLR INTERRUPT STATUS WORD CALLR DURSP ;GO PROCESS ANY RESPONSES 50$: CLR CMDINT(R0) ;CLR INTERRUPT STATUS WORD CALLR DUINI ;GO DEQUEUE ANY COMMANDS (IF AVAILABLE) 60$: ;REF LABEL .IF DF DEBUG 61$: BPT ;GET TO XDT MOV #NOP,61$ ;NOP THE BRK PNT .ENDC ;DEBUG CALLR REINIT ;YES, RE-INITIALIZATION REUIRED .PAGE ;+ ; **- REGPAS - REGISTER PASS ROUTINE ; ; THE REGPAS ROUTINE IS USED TO MOVE VALUES FROM ONE SET OF LOCATIONS ; TO ANOTHER (I.E. FROM AN MSCP PACKET TO UCB). ; ; INPUTS: ; ; R0 = DESTINATION LOCATION ; R1 = SOURCE LOCATION ; R2 = NUMBER OF WORDS TO MOVE ; ; OUTPUTS: ; ; THE SPECIFIED WORDS ARE MOVED FROM SOURCE TO DESTINATION ; ;- REGPAS: MOV (R1)+,(R0)+ ;MOVE THEM A WORD AT A TIME SOB R2,REGPAS ;LOOP RETURN ;EXIT ;+ ; **- DUEXTM - EXTENDED MEMORY SUPPORTED ROUTINE ; ; THIS ROUTINE WILL DETERMINE IF THIS CONTROLLER SUPPORTS EXTENDED ; MEMORY ADDRESSING OR NOT. BASED ON THESE FINDINGS, IT WILL SET/CLR ; THE "DV.EXT" BIT IN U.CW1 FOR EACH UNIT ATTACHED TO THIS CONTROLLER. ; ; INPUTS: ; ; R2 = CSR ADDRESS ; R3 = POINTER TO CONTROLLER STATE TABLE ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R2 = CSR ADDRESS ; R3 = POINTER TO CONTROLLER STATE TABLE ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- .IF DF M$$EXT DUEXTM: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV #SCUCB,-(SP) ;PUSH "SCAN UCB'S" ROUTINE ON THE STACK 10$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 20$ ;IF CS, ALL DONE MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS BIC #DV.EXT,U.CW1(R5) ;ASSUME NO EXTENDED MEMORY SUPPORT BIT #EXTMEM,UDASA(R2) ;EXTENDED MEMORY SUPPORTED? BEQ 10$ ;IF EQ NO BIS #DV.EXT,U.CW1(R5) ;YES, SET EXTENDED MEMORY SUPPORT BR 10$ ;GO AGAIN 20$: MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS RETURN ;EXIT .ENDC ;M$$EXT ;+ ; **- RQRCT - REQUEST REPLACEMENT CONTROL TASK ; ; THIS ROUTINE IS CALLED TO REQUEST THE REPLACEMENT CONTROL TASK ; TO INITIALIZE THE SPECIFIED UNIT OR TO REPLACE A BAD BLOCK ON ; THE SPECIFIED UNIT. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET IF REPLACEMENT ; OR ELSE ZERO IF INITIALIZATION ; R3 = ADDRESS OF CONTROLLER STATE TABLE ; R4 = ADDRESS OF THE SCB ; R5 = ADDRESS OF THE UCB. ; ; OUTPUTS: ; ; THE REPLACEMENT CONTROL TASK IS REQUESTED TO REPLACE ; THE BAD BLOCK ON THE SPECIFIED UNIT. ; ;- RQRCT: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R1,-(SP) ;SAVE R1 AND ... MOV R3,-(SP) ;... CONTROLLER STATE TABLE POINTER BIT #UF.RPL,U.UNFL(R5) ;CONTROLLER INITIATED BAD BLOCK ... ;... REPLACEMENT? BNE 30$ ;IF NE YES MOV #RCTNAM,R3 ;NO, POINT TO RCT'S NAME CALL $SRSTD ;IS RCT INSTALLED? BCC 40$ ;IF CC YES MOV #T.NRCT,R0 ;NO, SET MESSAGE ... ;... "REPLACEMENT CONTROLL TASK NOT INSTALLED" 10$: CALL $DVMSG ;GO PRINT IT ... BR 30$ ;... AND GO ON 20$: ;REF LABEL .IF DF DEBUG 21$: BPT ;GET TO XDT MOV #NOP,21$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV (SP),R3 ;RETRIEVE CONTROLLER STATE TABLE POINTER MOV 2(SP),R1 ;RETRIEVE R1, DOES IT POINT TO CURRENT ... ;... RESPONSE RING PACKET? BEQ 30$ ;IF EQ NO MOVB P.FLGS(R1),C.IOSB+1(R3) ;SET FLAGS BYTE INTO HI BYTE OF ... ;... I/O STATUS BLOCK 30$: SEC ;SET CARRY TO INDICATE NO NEED TO REQUEST RCT BR 80$ ;EXIT 40$: ;REF LABEL .IF DF DEBUG 41$: BPT ;GET TO XDT MOV #NOP,41$ ;NOP THE BRK PNT .ENDC ;DEBUG CMP U.ATT(R5),R0 ;IS RCT ATTACHED? BEQ 20$ ;IF EQ YES MOV R0,RCTTCB ;SAVE TCB ADDRESS MOV #12.,R1 ;SET LENGTH OF BLOCK NEEDED CALL $ALOCB ;GET A CORE BLOCK BCC 50$ ;IF CC GOT ONE MOV #T.NUER,R0 ;SET MESSAGE BR 10$ ;GO ON 50$: MOV R0,R3 ;SET ADDRESS OF MESSAGE BLOCK TST (R0)+ ;POINT TO SECOND WORD IN BLOCK MOV 2(SP),R1 ;DO WE HAVE INITIALIZATION REQUEST? BEQ 60$ ;IF EQ YES MOV P.CRF+2(R1),(R0)+ ;NO, INSERT I/O PACKET ADDRESS (REPLACEMENT ;REQUIRED INDICATOR) MOV R5,(R0)+ ;INSERT UCB ADDRESS MOV P.FBBK+2(R1),(R0)+ ;INSERT HI LBN TO BE REPLACED MOV P.FBBK(R1),(R0)+ ;INSERT LO LBN TO BE REPLACED  BR 70$ ;AND CONTINUE 60$: CLR (R0)+ ;INSERT INITIALIZATION INDICATOR MOV R5,(R0)+ ;INSERT UCB ADDRESS CLR (R0)+ ;CLR HI LBN POSITION CLR (R0)+ ;CLR LO LBN POSITION 70$: MOV R3,R1 ;COPY ADDRESS OF MESSAGE BLOCK MOV RCTTCB,R0 ;PICK UP RCT'S TCB ADDRESS CALL $EXRQF ;REQUEST RCT TO RUN CLC ;CLR CARRY TO INDICATE RCT REQUESTED 80$: MOV (SP)+,R3 ;RESTORE CONTROLLER STATE TABLE POINTER AND ... MOV (SP)+,R1 ;... R1 RETURN ;EXIT ;+ ; **- DUGCS - UDA50 GET COMMAND STATUS ROUTINE ; ; THIS ROUTINE WILL ISSUE A "GET COMMAND STATUS" PACKET ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- .IF DF E$$DVC DUGCS: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG CMP U.LHD(R5),U.OTRF(R5) ;IS AN OUTSTANDING COMMAND STATUS REQUEST ... ;... PENDING FOR THE OLDEST I/O REQUEST? BEQ 20$ ;IF EQ YES 10$: MOV #P.LENG,R0 ;SET-UP COMMAND PACKET LENGTH MOV #1,R1 ;SET-UP VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD CALL GTPKT ;GET THE CURRENT COMMAND PACKET IN THE RING BCS 10$ ;IF CS NO, ... TRY, TRY AGAIN MOV R5,P.CRF(R1) ;YES SET HI ORDER REF NUMBER TO UCB ADDRESS MOV R3,P.CRF+2(R1) ;SET LO ORDER REF NUMBER TO CONTROLLER STATE TABLE MOVB #OP.GCS,P.OPCD(R1) ;SET "GET COMMAND STATUS" OP CODE MOVB U.UNIT(R5),P.UNIT(R1) ;SET UNIT MOV R5,P.OTRF(R1) ;SET HI ORDER OUTSTANDING COMMAND REF NUMBER MOV U.LHD(R5),P.OTRF+2(R1) ;SET LO ORDER OUTSTANDING COMMAND ... ;... REF NUMBER MOV U.LHD(R5),U.OTRF(R5) ;SAVE OLDEST I/O REQUEST IN OUTSTANDING ... ;... COMMAND REF NUMBER STATUS REGISTER CALLR DUCMD3 ;ISSUE I/O 20$: ;REF LABEL .IF DF DEBUG 21$: BPT ;GET TO XDT MOV #NOP,21$ ;NOP THE BRK PNT .ENDC ;DEBUG ; ; WE HAVE TIMED OUT THE OLDEST I/O REQUEST TWICE. ; IT WILL BE ASSUMED THAT THE CONTROLLER IS INSANE OR ; OR HOPELESSLY DEADLOCKED. RE-INITIALIZATION SEEMS ; APPROPRIATE AT THIS TIME. ; TST (SP)+ ;FLUSH THE STACK .ENDC ;E$$DVC ;+ ; **- REINIT - RE-INITIALIZE ROUTINE ; ; THE RE-INITIALIZE ROUTINE IS ENTERED WHENEVER THE CONTROLLER MUST BE RE- ; INITIALIZED. ; ; INPUTS: ; ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE CONTROLLER INITIALIZATION TABLE IS SET-UP AND THE CONTROLLER ; RE-INITIALIZATION IS STARTED. ; ;- REINIT: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINT MOV S.CSR(R4),R2 ;AND RETRIEVE CSR ADDRESS .IF DF E$$DVC CALL DUCERR ;LOG CONTROLLER ERROR LOG PACKET .ENDC ;E$$DVC DECB C.RTRY(R3) ;ANY MORE RETRIES LEFT? BEQ OFFLIN ;IF EQ NO TST UDASA(R2) ;DID CONTROLLER SUFFER A FATAL ERROR? BEQ 10$ ;IF EQ NO BISB #C1.INI,C.STAT(R3) ;SET RE-INITIALIZATION REQUIRED FLAG CALL DUPWF2 ;IN#NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOVB S.CON(R4),R3 ;RETRIEVE CONTROLLER INDEX MOV CTTBL(R3),R3 ;RETRIEVE CONTROLLER STATE TABLE POINT MOV S.CSR(R4),R2 ;AND RETRIEVE CSR ADDRESS .IF DF E$$DVC CALL DUCERR ;LOG CONTROLLER ERROR LOG PACKET .ENDC ;E$$DVC DECB C.RTRY(R3) ;ANY MORE RETRIES LEFT? BEQ OFFLIN ;IF EQ NO TST UDASA(R2) ;DID CONTROLLER SUFFER A FATAL ERROR? BEQ 10$ ;IF EQ NO BISB #C1.INI,C.STAT(R3) ;SET RE-INITIALIZATION REQUIRED FLAG CALL DUPWF2 ;INITIALIZE CONTROLLER PARAMETERS CALLR DUINIT ;RE-INITIALIZE THE UDA50 CONTROLLER 10$: ;REF LABEL .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV C.RING(R3),R0 ;RETRIEVE BASE OF RINGS TST CMDINT(R0) ;NEED TO SERVICE COMMAND RING FULL CASE? BNE 20$ ;IF NE YES TST RSPINT(R0) ;NEED TO SERVICE RESPONSE RING NOT EMPTY CASE? BEQ 30$ ;IF EQ NO CLR RSPINT(R0) ;CLR INTERRUPT STATUS WORD CALLR DURSP ;CHECK ON ANY RESPONSES (IF AVAILABLE) 20$: CLR CMDINT(R0) ;CLR INTERRUPT STATUS WORD CALLR DUINI ;GO DEQUEUE ANY COMMANDS (IF AVAILABLE) 30$: CALLR DUEXIT ;THEN SEE HOW WE SHOULD EXIT ;+ ; **- OFFLIN - UDA50 OFFLINE ROUTINE ; ; THE OFFLINE ROUTINE SCANS THROUGH ALL THE UCB'S ASSOCIATED WITH THIS ; CONTROLLER TO SET EACH UNIT OFF-LINE ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; ALL UNITS ASSOCIATED WITH THIS CONTROLLER HAVE BEEN SET OFFLINE. ; ;- OFFLIN: MOV #SCUCB,-(SP) ;PUSH "SCAN UCB'S" ROUTINE ON THE STACK 10$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 20$ ;IF CS, ALL DONE BISB #US.OFL,U.ST2(R5) ;MARK UNIT AS OFF-LINE BICB #US.SPU!US.VV,U.STS(R5) ;AND CLR SPIN-UP AND VOLUME VALID FLAGS BR 10$ ;GO AGAIN 20$: RETURN ;EXIT ;+ ; **- DUSTAT - UDA50 GET UNIT STATUS ROUTINE ; ; THE GET UNIT STATUS ROUTINE WILL OBTAIN THE SPECIFIED DEVICE'S ; CHARACTERISTICS. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE STATUS OF THE SPECIFIED UNIT IS OBTAINED ; ;- DUSTAT: MOV #P.LENG,R0 ;SET-UP COMMAND PACKET LENGTH MOV #1,R1 ;SET-UP VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD CALL GTPKT ;GET THE CURRENT COMMAND PACKET BCS DUSTAT ;IF CS TRY AGAIN MOV R5,P.CRF(R1) ;SET HI ORDER REF NUMBER TO UCB ADDRESS MOV R3,P.CRF+2(R1) ;SET LO ORDER REF NUMBER TO CONTROLLER ;STATE TABLE MOVB U.UNIT(R5),P.UNIT(R1) ;SET UNIT NUMBER MOV #0,P.MOD(R1) ;SET MODIFIERS MOVB #OP.GUS,P.OPCD(R1) ;ASSUME "GET UNIT STATUS" OP CODE CALLR DUCMD3 ;ISSUE I/O ;+ ; **- DUONL - UDA50 UNIT INITIALIZATION AND ON-LINE ROUTINE ; ; THE UNIT INITIALIZATION AND ON-LINE ROUTINE WILL DO WHAT IS ; NECESSARY TO OBTAIN THE SPECIFIED DEVICE'S CHARACTERISTICS AND, ; IF POSSIBLE, SET THE UNIT ON-LINE ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE SPECIFIED UNIT IS FIRST BROUGHT ON-LINE. ; ;- DUONL: MOV #P.LENG,R0 ;SET-UP COMMAND PACKET LENGTH MOV #1,R1 ;SET-UP VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD CALL GTPKT ;GET THE CURRENT COMMAND PACKET BCS DUONL ;IF CS TRY AGAIN MOV R5,P.CRF(R1) ;SET HI ORDER REF NUMBER TO UCB ADDRESS MOV R3,P.CRF+2(R1) ;SET LO ORDER REF NUMBER TO CONTROLLER ;STATE TABLE MOVB U.UNIT(R5),P.UNIT(R1) ;SET UNIT NUMBER MOV #0,P.MOD(R1) ;SET MODIFIERS MOVB #OP.ONL,P.OPCD(R1) ;ASSUME "ONLINE" OP CODE CALLR DUCMD3 ;ISSUE I/O ;+ ; **- STCCR - SET UDA50 CONTROLLER'S CHARACTERISTICS  ; ; THE STCCR ROUTINE WILL REQUEST A COMMAND PACKET, FILL IT IN WITH THE ; REQUIRED MSCP ITEMS, AND REQUEST THE PACKET TO BE ISSUED AS I/O. ; THE ENTIRE PROCEDURE IS REQUIRED TO SET THE UDA50 CONTROLLER'S CHARACTER- ; ISTICS ANY TIME THE CONTROLLER IS INITIALIZED. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; R2 IS DESTROYED ; ;- STCCR: MOV P.STS(R1),R2 ;GET STATUS/EVENT CODE BIC #^C,R2 ;CLR ALL BUT STATUS/EVENT ... ;... IS IT SUCCESS? SEC ;ASSUME FAILURE BNE 40$ ;IF NE NO BISB #C1.ON,C.STAT(R3) ;SET CONTROLLER ON-LINE FLAG BIC #^C,C.STAT(R3) ;CLR ALL OTHER FLAGS MOV R1,-(SP) ;YES, SAVE POINTER TO MSCP PACKET MOV R3,R0 ;COPY CONTROLLER STATE TABLE POINTER ADD #P.VRSN,R1 ;POINT TO CONTROLLER CHARACTERISTICS ADD #C.VRSN,R0 ;AND WHERE TO PUT THEM MOV #/2,R2 ;AND HOW MANY CALL REGPAS ;MOVE VALUES FROM MSCP PACKET TO CONTROLLER ;STATE TABLE MOV (SP)+,R1 ;RESTORE R1 MOVB C.CMDS(R3),C.ILCC(R3) ;DEFINE MAXIMUM VALUE FOR LOOP COUNT CONTROL .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 30$ ;IF NE YES TST S.UMHD(R4) ;HAVE WE ALLOCATED THE UMR WAIT BLOCK(S)? BNE 30$ ;IF NE YES MOV R1,-(SP) ;SAVE R1 MOV C.CMDS(R3),R0 ;GET CONTROLLER'S COMMAND LIMIT CLR -(SP) ;GET A WORKING REGISTER MOVB C.CMD(R3),(SP) ;GET COMMAND RING BUFFER SIZE ASL (SP) ;DOUBLE IT CMPB (SP)+,R0 ;IS COMMAND LIMIT TWICE COMMAND RING BUFFER SIZE? ; BR 10$ ;ALWAYS BRANCH FOR NOW BHIS 10$ ;IF HIS NO CLR R0 ;SET UP FOR "BISB" BISB C.CMD(R3),R0 ;YES, USE COMMAND RING BUFFER SIZE ... ASL R0 ;... AND DOUBLE IT 10$: MOV R0,C.CMDS(R3) ;SET CONTROLLER'S COMMAND LIMIT ... MOV R0,S.UMCT(R4) ;... AND THE NUMBER OF UMR WAITING BLOCK(S) MOV #20.,R1 ;NUMBER OF BYTES REQUIRED FOR A UMR ASSIGNMENT ;BLOCK CALL $MUL ;MULTIPLY THEM CALL $ALOCB ;ALLOCATE A CORE BLOCK FOR UMR ASSIGNMENTS MOV R0,S.UMHD(R4) ;SAVE THE POINTER TO CORE BLOCK ... MOV R1,S.UMHD+2(R4) ;... AND ITS LENGTH ADD R0,S.UMHD+2(R4) ;MAKE IT AN ADDRESS ASR R1 ;MAKE IN A WORD COUNT 20$: CLR (R0)+ ;CLR UMR WAIT BLOCK WORDS SOB R1,20$ ;LOOP UNTIL DONE MOV (SP)+,R1 ;RESTORE R1 30$: ;REF LABEL .ENDC ;M$$EXT 40$: RETURN ;EXIT ;+ ; **- GTUST - GET DRIVE'S UNIT STATUS ; ; THIS ROUTINE WILL GET THE DRIVE'S UNIT STATUS AFTER IT HAS ; BEEN BROUGHT ONLINE. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; R2 IS DESTROYED ; ;- GTUST: MOV P.STS(R1),R2 ;GET STATUS/EVENT CODE BIC #^C,R2 ;CLR ALL BUT STATUS/EVENT CODE ... ;... IS IT SUCCESS? BEQ 10$ ;IF EQ YES CMP #ST.OFL,R2 ;THEN IS IT OFF-LINE? BNE 10$ ;IF NE NO BISB #US.OFL,U.ST2(R5) ;YES, MARK UNIT AS BEING OFF-LINE BICB #US.SPU!US.VV,U.STS(R5) ;AND CLR SPIN-UP AND VOLUME VALID FLAGS BR 20$ ;AND EXIT 10$: MOV R1,-(SP) ;SAVE CURRENT MSCP PACKET POINTER MOV R5,R0 ;COPY POINTER TO UCB ADD #P.MLUN,R1 ;POINT TO UNIT CHARACTERISTICS ADD #U.MLUN,R0 ;AND WHERE TO PUT THEM MOV #/2,R2 ;AND HOW MANY CALL REGPAS ;MOVE VALUES FROM MSCP PACKET TO UCB MOV (SP)+,R1 ;RESTORE R1 20$: CLR C.IOSB+2(R3) ;ZERO 2ND STATUS WORD OF CURRENT RESPONSE BLOCK RETURN ;AND RETURN ;+ ; **- ONLINE - DRIVE ONLINE ROUTINE ; ; THIS ROUTINE IS USED TO PUT A DRIVE ON-LINE FROM THE AVAILABLE STATE. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; R2 IS DESTROYED ; ;- ONLINE: MOV P.STS(R1),R2 ;GET STATUS/EVENT CODE BIC #^C,R2 ;CLR ALL BUT STATUS/EVENT CODE ... ;... IS IT SUCCESS? BNE 10$ ;IF NE NO MOV R1,-(SP) ;YES, SAVE CURRENT MSCP PACKET POINTER MOV R5,R0 ;COPY POINTER TO UCB ADD #P.UNSZ,R1 ;POINT TO UNIT COMMAND LIMIT ADD #U.UNSZ,R0 ;AND WHERE TO PUT THEM MOV #/2,R2 ;AND HOW MANY CALL REGPAS ;MOVE VALUES FROM MSCP PACKET TO UCB MOV (SP)+,R1 ;... AND R1 MOV U.UNSZ(R5),U.CW3(R5) ;SET UP THE MAX LBN ... MOVB U.UNSZ+2(R5),U.CW2(R5) ;... FOR PROPER OPERATION BICB #US.SPU,U.STS(R5) ;CLR UNIT SPINNING UP BIT BICB #US.OFL,U.ST2(R5) ;CLR OFF-LINE BIT RETURN ; 10$: BISB #US.OFL,U.ST2(R5) ;MARK UNIT AS BEING OFF-LINE BICB #US.SPU!US.VV,U.STS(R5) ;AND CLR SPIN-UP AND VOLUME VALID FLAGS RETURN ; ;+ ; **- GTCST - GET DRIVE'S COMMAND STATUS ; ; THIS ROUTINE WILL GET THE DRIVE'S COMMAND STATUS AFTER IT HAS ; BEEN TIMED OUT. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; R2 IS DESTROYED ; ;- .IF DF E$$DVC GTCST: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV U.CMST+2(R5),P.CMST+6(R1) ;STORE PREVIOUS COMMAND'S STATUS ... MOV U.CMST(R5),P.CMST+4(R1) ;... AS A DOUBLE PRECISION VALUE ADD #4,MSGLNG(R1) ;CORRECT PACKET LENGTH FOR EXTRA INFO FOR ERROR LOG CALL DULERR ;LOG UNIT'S COMMAND STATUS MOV P.STS(R1),R2 ;GET STATUS/EVENT CODE BIC #^C,R2 ;CLR ALL BUT STATUS/EVENT CODE ... ;... IS IT SUCCESS? BNE 30$ ;IF NE NO CMP U.LHD(R5),P.OTRF(R1) ;IS THIS PACKET FOR CURRENT OLDEST ... ;... OUTSTANDING COMMAND BNE 20$ ;IF NE NO TST P.CMST(R1) ;IS THE COMMAND DONE? BNE 10$ ;IF NE NO TST P.CMST+2(R1) ;MAYBE? BEQ 20$ ;IF EQ YES 10$: ;REF LABEL .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG CMP U.CMST+2(R5),P.CMST+2(R1) ;IS PROGRESS BEING MADE? BHI 20$ ;IF HI YES CMP U.CMST(R5),P.CMST(R1) ;MAYBE? BLOS 30$ ;IF LOS NO 20$: ;REF LABEL ; ; SAVE THIS COMMAND'S STATUS FOR NEXT TIME WE TIME THIS COMMAND OUT OR ; WE HAVE JUST RECEIVED A COMMAND'S STATUS FOR AN I/O REQUEST WHICH ; MAY HAVE ALREADY COMPLETED. ;  .IF DF DEBUG 21$: BPT ;GET TO XDT MOV #NOP,21$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV P.CMST(R1),U.CMST(R5) ;SAVE THIS COMMAND'S STATUS ... MOV P.CMST+2(R1),U.CMST+2(R5) ;... AS A DOUBLE PRECISION VALUE CLR U.OTRF(R5) ;ZERO OLDEST OUTSTANDING I/O REQUEST RETURN ;AND EXIT 30$: ;REF LABEL .IF DF DEBUG 31$: BPT ;GET TO XDT MOV #NOP,31$ ;NOP THE BRK PNT .ENDC ;DEBUG ; ; NO PROGRESS IS BEING MADE ON THE OUTSTANDING I/O REQUEST WE ; JUST ISSUED A "GET COMMAND STATUS" FOR OR THE CONTROLLER RETURNED ; SOME KIND OF ERROR. THIS SITUATION IMPLIES THAT THE CONTROLLER HAS ; GONE INSANE OR IS IRREVOCABLY DEADLOCKED. LOOKS AS THOUGH WE SHOULD ; RE-INITIALIZE THE CONTROLLER, IF POSSIBLE. ; CALLR REINIT ;RE-INITIALIZE THE CONTROLLER .ENDC ;E$$DVC ;+ ; **- DUATN - UDA50 UNIT ATTENTION ROUTINE ; ; THE UNIT ATTENTION ROUTINE WILL OBTAIN THE SPECIFIED ; DEVICE'S CHARACTERISTICS. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE ATTENTION SPECIFIED UNIT'S UCB IS DETERMINED ; ;- DUATN: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG CMPB #OP.AVA,P.OPCD(R1) ;IS THIS RESPONSE AN AVAILABLE ATTENTION? BNE 30$ ;IF NE NO MOV #SCUCB,-(SP) ;YES, PUSH "SCAN UCB'S" ROUTINE ON THE STACK 10$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 20$ ;IF CS, NO MORE UCB'S CMPB P.UNIT(R1),U.UNIT(R5) ;IS THIS ATTENTION MESSAGE FOR THIS UCB BNE 10$ ;IF NE NO BICB #US.OFL,U.ST2(R5) ;YES, CLR ANY OFF-LINE CONDITION BICB #US.VV,U.STS(R5) ;CLR ANY VOLUME VALID CONDITIONS BISB #US.SPU,U.STS(R5) ;MARK THE UNIT AS SPINNING UP ADD #10,SP ;FLUSH THE STACK 20$: RETURN ;EXIT 30$: CLC ;FORCE CARRY CLR RETURN ; ;+ ; **- DUCERR - UDA50 CONTROLLER ERROR LOGGING ROUTINE ; ; THE CONTROLLER ERROR LOGGING ROUTINE WILL CAUSE THE CREATION OF AN ERROR ; LOG PACKET, COPY THE VALUES OF THE TWO I/O PAGE REGISTERS INTO THE ERROR ; LOG PACKET AND REQUEST THE ERROR LOGGING SUB-SYSTEM TO CAPTURE THE DATA. ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE ERROR (OR TIME OUT) FROM THE SPECIFIED CONTROLLER IS LOGGED ; ;- .IF DF E$$DVC .ENABL LSB DUCERR: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ;SAVE R3 MOV R4,-(SP) ;SAVE R4 CLRB C.STAT+1(R3) ;RESET INITIALIZATION IN PROGRESS FLAGS MOV S.CSR(R4),R2 ;RETRIEVE CSR ADDRESS ; ; SETUP CONTROLLER ERROR LOG PACKET ; MOV #4,C.MLNG(R3) ;SET PACKET LENGTH MOVB #-2,C.VCID(R3) ;SET VIRTUAL CIRCUIT ID MOVB #20,C.CRED(R3) ;SET CREDIT FIELD TO DATAGRAM MOV UDAIP(R2),C.IP(R3) ;SAVE UDAIP REGISTER MOV UDASA(R2),C.SA(R3) ;SAVE UDASA REGISTER MOV #C.IP,R1 ;ADJUST R1 TO ... ADD R3,R1 ;... POINT TO CONTROLLER ERROR LOG PACKET BR 30$ ;AND CONTINUE TO LOG PACKET ;+ ; **- DULERR - UDA50 UNIT ERROR LOGGING ROUTINE ; ; THE UNIT ERROR LOGGING ROUTINE WILL CAUSE THE CREATION OF AN ERROR LOG ; PACKET, COPY THE CONTENTS OF THE MSCP ERROR LOG PACKET INTO THE ERROR ; LOG PACKET AND REQUEST THE ERROR LOGGING SUB-SYSTEM TO CAPTURE THE DATA. ; ; INPUTS: ; ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE ERROR ON THE SPECIFIED UNIT IS LOGGED. ; ;- DULERR: ;REF LABEL .IF DF DEBUG 11$: BPT ;GET TO XDT MOV #NOP,11$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ;SAVE R3 MOV R4,-(SP) ;SAVE R4 MOV #SCUCB,-(SP) ;YES, PUSH "SCAN UCB'S" ROUTINE ON THE STACK 20$: CALL @(SP)+ ;CALL THE CO-ROUTINE BCS 80$ ;IF CS, NO MORE UCB'S CMPB P.UNIT(R1),U.UNIT(R5) ;IS THIS ERROR LOG PACKET FOR THIS UCB BNE 20$ ;IF NE NO ADD #10,SP ;YES, FLUSH THE STACK 30$: CLRB S.ROFF(R4) ;ZERO OFFSET TO FIRST REGISTER OF ERROR LOG PACKET MOV #MSGLNG,R2 ;GET OFFSET TO BEGINNING OF ENVELOPE ADD R1,R2 ;ADD BASE ADDRESS OF RESPONSE PACKET MOV (R2),-(SP) ;GET MESSAGE LENGTH ADD #ENVLP,(SP) ;ADD EXTRA FOR THE ENVELOPE CMP #64.,(SP) ;DID WE OVERFLOW MAXIMUM PACKET SIZE? BHIS 40$ ;IF HIS NO .IF DF DEBUG CRASH ;YES, CRASH ;PACKET GREATER THAN MAXIMUM SIZE .IFF ;DEBUG TST (SP)+ ;YES, FLUSH STACK ;PACKET GREATER THAN MAXIMUM SIZE BR 80$ ;AND EXIT .ENDC ;DEBUG 40$: MOV (SP),R2 ;COPY NUMBER OF BYTES TO R2 ASR (SP) ;MAKE IT REGISTERS (WORDS) MOVB (SP)+,S.RCNT(R4) ;SET NUMBER OF REGISTERS TO COPY FOR ERROR LOG CLR S.PKT(R4) ;ASSUME NO I/O PACKET ACTIVE CMP P.CRF+2(R1),R3 ;INTERNAL I/O FUNCTION? BEQ 50$ ;IF EQ YES MOV P.CRF+2(R1),S.PKT(R4) ;NO, COPY I/O PACKET ADDRESS FOR ERROR LOGGER ;IS I/O ACTIVE? BNE 60$ ;IF NE YES 50$: CLR R4 ;NO, CLR R4 60$: MOV R1,-(SP) ;SAVE R1 AGAIN MOV R2,R1 ;COPY NUMBER OF BYTES INTO R1 ; ; INTERFACE TO $LOGER: ; ; INPUTS: ; ; R1 = LENGTH OF DATA TO BE LOGGED, IN BYTES ; R4 = SCB ADDRESS (ZERO IF NO I/O PACKET) ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; C = 1 UNABLE TO LOG ERROR ; ; C = 0 ABLE TO LOG ERROR ; ; R1 = ADDRESS OF DATA AREA IN ERROR LOG PACKET ; R3 = ADDRESS OF ERROR LOG PACKET ; ; NOTE: ; ; R4 AND R5 ARE PRESERVED ; R0, R2, AND R3 MAY BE DESTROYED ; CALL $LOGER ;ATTEMPT TO LOG ERROR PACKET MOV R1,R0 ;COPY R1 INTO R0 FOR DESTINATION MOV (SP)+,R1 ;RESTORE POINTER TO MSCP PACKET FOR SOURCE BCS 80$ ;IF CS, UNABLE TO LOG ERROR PACKET ADD #MSGLNG,R1 ;OFFSET TO BEGINNING OF ENVELOPE MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS CLR R2 ;SETUP FOR "BISB" BISB S.RCNT(R4),R2 ;SET NUMBER OF REGISTERS (WORDS) TO COPY CALL REGPAS ;COPY MSCP PACKET INTO ERROR LOG PACKET MOV #IS.SUC&377,R0 ;ASSUME A SUCCESSFUL STATUS WORD CLR R2 ;AND ZERO RETRY COUNTS TST S.PKT(R4) ;IS I/O ACITVE? BNE 70$ ;IF NE YES CLR R4 ;NO, CLR R4 ; ; ; INTERFACE TO $FNERL: ; ; INPUTS: ; ; R0 = FIRST I/O STATUS WORD ; R2 = STARTING AND FINAL ERROR RETRY COUNTS ; R3 = ADDRESS OF ERROR LOG PACKET ; R4 = SCB ADDRESS (ZERO IF NO I/O PACKET) ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE SPECIFIED ERROR LOG PACKET IS LOGGED ; ; NOTE: ; ; R4 AND R5 ARE PRESERVED ; R1, R2, AND R3 MAY BE DESTROYED ; 70$: CALL $FNERL ;FINISH LOGGING THIS ERROR LOG PACKET 80$: MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R1 ;RESTORE R1 MOV (SP)+,R0 ;RESTORE R0 RETURN ;EXIT .DSABL LSB .ENDC ;E$$DVC ;+ ; **- DUDPKT - UDA50 UNIT DIAGNOSTIC PACKET PROCESSING ROUTINE ; ; THE UNIT DIAGNOSTIC PACKET PROCESSING ROUTINE WILL DO WHAT IS ; ; INPUTS: ; ; R0 = ADDRESS OF CURRENT RESPONSE RING POINTER ; R1 = ADDRESS OF CURRENT RESPONSE RING PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; THE SPECIFIED UNIT IS FIRST BROUGHT ON-LINE. ; ;- .IF DF D$$IAG DUDPKT: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT CRASH ;WHAT ARE WE DOING HERE? .ENDC ;DEBUG RETURN ;SHORT CIRCUIT .ENDC ;D$$IAG ;+ ; **- DURSN - UDA50 VOLUME SERIAL NUMBER ROUTINE ; ; THIS ROUTINE COPIES THE UDA50 VOLUME SERIAL NUMBER INTO A BUFFER ; SPECIFIED BY THE USER. ; ; INPUTS: ; ; R1 = I/O PACKET ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; VOLUME SERIAL NUMBER IS COPIED INTO USER'S BUFFER ; ;- DURSN: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG MOV R1,R3 ;COPY I/O PACKET ADDRESS INTO R3 MOV I.PRM+2(R3),R1 ;SET UP LO 16-BITS FOR RELOCATION .IF DF M$$MGE .IF DF M$$EXT MOVB I.PRM+1(R3),R0 ;SET UP HI 6-BITS FOR RELOCATION .IFF ;M$$EXT MOVB I.PRM(R3),R0 ;SET UP HI 2-BITS FOR RELOCATION ASR R0 ;ADJUST HI 2-BITS ASR R0 ;... ASR R0 ;... ASR R0 ;... .ENDC ;M$$EXT .IFF ;M$$MGE CLR R0 ; .IFT ;M$$MGE .IF DF M$$EIS ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ASHC #-10.,R1 ;... .IFF ;M$$EIS MOV #10.,-(SP) ;SET COUNT FOR 10 SHIFTS 10$: DEC (SP) ;ANY MORE SHIFTS TO PERFORM BLT 20$ ;IF LT NO ASL R1 ;DOUBLE LEFT SHIFT R1 ... ROL R0 ;... INTO R0 BR 10$ ; 20$: SWAB R1 ;SWAP BYTES ASR R1 ;SHIFT RIGHT R1 ASR R1 ;... TST (SP)+ ;CLR THE STACK .ENDC ;M$$EIS MOV @#KISAR6,-(SP) ;SAVE APR 6 MOV R0,@#KISAR6 ;SET RELOCATION BIAS ADD #140000,R1 ;SET DISPLACEMENT .IFTF ;M$$MGE MOV U.VSER(R5),(R1)+ ;COPY LO ORDER VOLUME SERIAL NUMBER MOV U.VSER+2(R5),(R1) ;COPY HI ORDER VOLUME SERIAL NUMBER .IFT ;M$$MGE MOV (SP)+,@#KISAR6 ;RESTORE APR 6 .ENDC ;M$$MGE MOV #IS.SUC&377,R0 ;SET SUCCESS MOV #4,R1 ;SET BYTES TRANSFERRED CLR R2 ; RETURN ;EXIT ;+ ; **- DUMAP - MAP UNIBUS TO EXTENDED MEMORY ROUTINE ; ; THE DUMAP ROUTINE WILL TAKE THE ADDRESS CONTAINED IN THE I/O ; PACKET TO BE INSERTED INTO THE UCB LOCATIONS REQUIRED TO SET ; UP THE UMR AND ALLOCATE AN UMR MAPPING ASSIGNMENT BLOCK FROM ; A POOL OF UMR ASSIGNMENT BLOCKS WHICH THE DRIVER OBTAINED WHEN ; IT SET THE CONTROLLER ON-LINE. ; ; INPUTS: ; ; R1 = I/O PACKET ADDRESS ; R2 = PHYSICAL UNIT NUMBER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = UMR MAPPING BLOCK POINTER ; R2 = I/O PACKET ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- .IF DF M$$EXT DUMAP: MOV S.PKT(R4),R2 ;RETRIEVE I/O PACKET ADDRESS MOV S.UMHD(R4),R0 ;RETRIEVE POINTER TO UMR WAIT BLOCK(S) DEC S.UMCT(R4) ;DEC COUNT OF UMR WAIT BLOCKS CLR R1 ;INITIALIZE UMR WAIT BLOCK INDEX 10$: TST 10(R0) ;IS THIS BLOCK FREE? BEQ 30$ ;IF EQ MAYBE 20$: ;REF LABEL .IF DF DEBUG 21$: BPT ;GET TO XDT MOV #NOP,21$ ;NOP THE BRK PNT .ENDC ;DEBUG ADD #20.,R0 ;NO, MOVE TO NEXT ONE .IF DF DEBUG CMP S.UMHD+2(R4),R0 ;AT THE END OF UMR WAIT BLOCK(S) BHI 25$ ;IF HI NO CRASH ;YES, SOMETHING'S WRONG 25$: ;REF LABEL .ENDC ;DEBUG INC R1 ;INC INDEX TO THE NEXT ONE ... BR 10$ ;... AND GO AGAIN 30$: TST M.UMRA+10(R0) ;IS IT REALLY FREE? BNE 20$ ;IF NE NO MOV I.PRM(R2),U.BUF(R5) ;SET UP FOR UMR ASSIGNMENT BLOCK PROCESSING ... MOV I.PRM+2(R2),U.BUF+2(R5) ;... BUFFER ADDRESS ... MOV I.PRM+4(R2),U.CNT(R5) ;... AND BYTE COUNT MOVB R1,I.PRM(R2) ;YES, SAVE UMR WAIT BLOCK INDEX IN I/O PACKET MOV R0,R1 ;... AND COPY UMR WAIT BLOCK POINTER TO R1 RETURN ; ;+ ; **- DUUNMP - UNMAP UNIBUS TO EXTENDED MEMORY ROUTINE ; ; THE DUUNMP ROUTINE WILL FIND THE UMR MAPPING ASSIGNMENT BLOCK ; TO ALLOW THE UMR'S USED TO BE DE-ALLOCATED ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R2 = POINTER TO UMR MAPPING AREA ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- DUUNMP: MOV S.UMHD(R4),R2 ;COPY POINTER TO HEAD OF UMR WAIT BLOCK(S) MOV S.PKT(R4),R1 ;RETRIEVE POINTER TO I/O PACKET MOVB I.PRM(R1),R1 ;RETRIEVE INDEX OF UMR WAIT BLOCK MOV #20.,R0 ;NUMBER OF BYTES / UMR WAIT BLOCK CALL $MUL ;OFFSET INTO UMR WAIT BLOCK(S) ADD R1,R2 ;ADD OFFSET INTO UMR WAIT BLOCK(S) ADD #10,R2 ;ADD OFFSET TO MAPPING INFO IN UMR WAITING BLOCK(S) RETURN ; .ENDC ;M$$EXT ;+ ; **- MKPKT - MAKE PACKET ROUTINE ; ; THE MKPKT ROUTINE IS CALLED TO FILL IN AN MSCP PACKET. ; ; INPUTS: ; ; R2 = I/O PACKET ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1 = POINTER TO CURRENT COMMAND RING BUFFER PACKET ; ; AN MSCP PACKET IS REQUESTED AND THE APPROPRIATE VALUES ; FROM THE I/O PACKET ARE FILLED IN. ; ; R2 IS DESTROYED ; ;- MKPKT: ;REF LABEL .IF DF DEBUG MOV #2,120$ ;INITIALIZE TIMEOUT LOOP .ENDC ;DEBUG 10$: MOV #P.LENG,R0 ;SET-UP COMMAND PACKET LENGTH MOV #1,R1 ;SET-UP VIRTUAL CIRCUIT AND CREDIT/DEBIT FIELD CALL GTPKT ;GET AN MSCP PACKET BCC 20$ ;IF CC -- ALL'S OK  .IF DF DEBUG DEC 120$ ;TIMEOUT? BNE 10$ ;IF NE NO 19$: CRASH ;SOMETHING'S WRONG .ENDC ;DEBUG BR MKPKT ;GO AGAIN 20$: MOV R5,P.CRF(R1) ;SET HI ORDER REF NUMBER TO UCB ADDRESS MOV R2,P.CRF+2(R1) ;SET LO ORDER REF NUMBER TO I/O PACKET MOVB U.UNIT(R5),P.UNIT(R1) ;SET UNIT NUMBER CMPB #IO.RLB/256.,I.FCN+1(R2) ;DATA TRANSFER FUNCTION? BHIS 50$ ;IF HIS YES CMPB #IO.RPL,I.FCN(R2) ;REPLACE FUNCTION? BNE 30$ ;IF NE NO MOV #OP.RPL,P.OPCD(R1) ;SET REPLACE OP-CODE MOV I.PRM(R2),P.RBN+2(R1) ;SET UP HI ORDER RBN MOV I.PRM+2(R2),P.RBN(R1) ;SET UP LO ORDER RBN MOV I.PRM+4(R2),P.LBN+2(R1) ;SET UP HI ORDER LBN MOV I.PRM+6(R2),P.LBN(R1) ;SET UP LO ORDER LBN MOV I.PRM+10(R2),P.MOD(R1) ;SET PRIMARY REPLACEMENT MODIFIER RETURN ;AND EXIT 30$: ;REF LABEL .IF DF DEBUG CMPB #IO.SEC,I.FCN(R2) ;SENSE CHARACTERISTIC? BEQ 40$ ;IF EQ YES CMPB #IO.TRM,I.FCN(R2) ;TERMINATE FUNCTION? BEQ 19$ ;IF EQ YES, WHAT ARE WE DOING HERE? CMPB #IO.INL,I.FCN(R2) ;INITIALIZE FUNCTION? BNE 19$ ;IF NE NO, THEN WHAT ARE WE DOING HERE? .ENDC ;DEBUG 40$: MOV #OP.GUS,P.OPCD(R1) ;SET GET UNIT STATUS OP-CODE MOV #0,P.MOD(R1) ;SET OP-CODE MODIFIERS RETURN ;AND EXIT 50$: MOVB #OP.RD,P.OPCD(R1) ;ASSUME READ OP-CODE CMPB #IO.RLB/256.,I.FCN+1(R2) ;IS FUNCTION CODE A READ? BEQ 60$ ;IF EQ YES MOVB #OP.WR,P.OPCD(R1) ;NO, SET WRITE OP-CODE .IF DF D$$WCK BITB #US.WCK,U.STS(R5) ;WRITE CHECK REQUIRED? BEQ 60$ ;IF EQ NO BIS #MD.CMP,P.MOD(R1) ;YES, SET COMPARE MODIFIER .ENDC ;D$$WCK 60$: MOVB I.FCN(R2),-(SP) ;ANY SUB-FUNCTION BITS SET? BEQ 100$ ;IF EQ NO BITB #IQ.Q,(SP) ;EXPRESS REQUEST? BEQ 70$ ;IF EQ NO BIS #MD.EXP,P.MOD(R1) ;YES, SET EXPRESS MODIFIER 70$: BICB #7,(SP) ;CLR ANY GENERAL MODIFIERS CMPB #IO.RLC&IO.WLC,(SP) ;WRITE/READ CHECK FUNCTION? BEQ 80$ ;IF EQ YES CMPB #IO.RPB&IO.WPB,(SP) ;SPECIAL WRITE/READ CHECK FUNCTION? BNE 90$ ;IF NE NO 80$: BIS #MD.CMP,P.MOD(R1) ;YES, SET COMPARE MODIFIER 90$: CMPB #IO.WDD,(SP) ;SPECIAL WRITE W/FORCED ERROR FUNCTION? BNE 100$ ;IF NE NO BIS #MD.ERR,P.MOD(R1) ;YES, SET FORCE ERROR MODIFIER 100$: TST (SP)+ ;CLN THE STACK MOVB I.PRM+10(R2),P.LBN+2(R1) ;SET HI ORDER LBN MOV I.PRM+12(R2),P.LBN(R1) ;SET LO ORDER LBN MOV I.PRM+4(R2),P.BCNT(R1) ;SET BYTE COUNT MOV I.PRM+2(R2),P.BUFF(R1) ;SET LO 16 BITS OF ADDRESS MOV R2,S.PKT(R4) ;SAVE I/O PACKET ADDRESS IN SCB .IF DF M$$EXT MOVB I.PRM+1(R2),P.BUFF+2(R1) ;SET HI 6 BITS OF ADDRESS BIT #DV.EXT,U.CW1(R5) ;EXTENDED MEMORY SUPPORTED? BNE 110$ ;IF NE YES MOV R1,-(SP) ;SAVE R1 CALL DUUNMP ;LOCATE UMR WAIT BLOCK MOV (SP)+,R1 ;RETRIEVE POINTER TO CURRENT MSCP COMMAND PACKET MOV M.UMVL(R2),P.BUFF(R1) ;SET LO 16 BITS OF VIRTUAL ADDRESS MOVB M.UMVH(R2),P.BUFF+2(R1) ;SET HI 2 BITS OF VIRTUAL ADDRESS ASR P.BUFF+2(R1) ;ADJUST HI 2 BITS OF ADDRESS ASR P.BUFF+2(R1) ;... ASR P.BUFF+2(R1) ;... ASR P.BUFF+2(R1) ;... BIC #^C<3>,P.BUFF+2(R1) ;CLEAR ALL BUT LO ORDER TWO BITS .IFF ;M$$EXT MOVB I.PRM(R2),P.BUFF+2(R1) ;SET HI 2 BITS OF ADDRESS ASR P.BUFF+2(R1) ;ADJUST HI 2 BITS OF ADDRESS ASR P.BUFF+2(R1) ;... ASR P.BUFF+2(R1) ;... ASR P.BUFF+2(R1) ;... BIC #^C<3>,P.BUFF+2(R1) ;CLEAR ALL BUT LO ORDER TWO BITS .ENDC ;M$$EXT 110$: RETURN ;RETURN .IF DF DEBUG 120$: .WORD 0 ;TIMEOUT LOOP COUNT .ENDC ;DEBUG ;+ ; ** - SCUCB - SCAN UCB'S ASSOCIATED WITH SPECIFIED CONTROLLER (SCB ADDRESS) ; ; ; INPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R3 = CONTROLLER STATE TABLE POINTER ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ;- SCUCB: MOV (SP)+,R2 ;RETRIEVE RETURN ADDRESS MOV R5,-(SP) ;SAVE R5 MOV R3,-(SP) ;SAVE R3 MOV #DUDCB,R3 ;GET ADDRESS OF DU:'S FIRST DCB 10$: MOV (R3),R3 ;GET ADDRESS OF NEXT DCB, IS IT THE LAST BEQ 40$ ;IF EQ YES MOV D.UCB(R3),R5 ;GET ADDRESS OF FIRST UCB BIT #DV.PSE,U.CW1(R5) ;IS IT A PSUEDO DEVICE? BNE 40$ ;IF NE YES CMP #"DU,D.NAM(R3) ;IS IT A DCB FOR "DU"? BNE 10$ ;IF NE NO MOV R3,DUDCB2 ;YES, SAVE THIS DU: DCB ADDRESS MOVB D.UNIT+1(R3),-(SP) ;GET HIGHEST UNIT NUMBER SUB D.UNIT(R3),(SP) ;SUBTRACT OFF LOWEST INCB (SP) ;BUT ACCOUNT FOR IT 20$: CMP U.SCB(R5),R4 ;IS THIS UCB FOR THIS CONTROLLER BNE 30$ ;IF NE NO MOV 2(SP),R3 ;RETRIEVE CALLER'S R3 MOV R2,-(SP) ;PUT RETURN ADDRESS BACK ON STACK CLC ;CLR CARRY TO SHOW WE FOUND ONE CALL @(SP)+ ;CALL THE CALLER BACK MOV (SP)+,R2 ;RETRIEVE THE RETURN ADDRESS MOV DUDCB2,R3 ;GET POINTER TO CURRENT DU:'S DCB 30$: ADD D.UCBL(R3),R5 ;ADD LENGTH OF UCB FOR NEXT DECB (SP) ;IS THIS THE LAST ONE? BNE 20$ ;IF NE NO TST (SP)+ ;YES, CLEAN UP THE STACK BR 10$ ;TRY THE NEXT DCB 40$: CLR DUDCB2 ;NO, RESET CURRENT DU:'S DCB ADDRESS MOV (SP)+,R3 ;RESTORE ORIGINAL R3 MOV (SP)+,R5 ;RESTORE ORIGINAL R5 MOV R2,-(SP) ;PUT RETURN ADDRESS BACK ON THE STACK SEC ;SET CARRY TO SHOW THE END RETURN ; .PAGE .IF DF DU$BIG ;+ ; **- MAPD - MAP DRIVER DATA SPACE ROUINE ; ; THIS ROUTINE WILL PRESERVE THE PREVIOUS VALUE FOR APR6 AND ; LOAD APR6 WITH THE VALUE TO MAP THE RINGS AND PACKETS WHEN ; THE DRIVER IS GREATER THAN 4K WORDS. ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; PREVIOUS VALUE OF APR6 IS SAVED AND APR6 IS LOADED ; WITH THE VALUE TO MAP THE DRIVER'S RINGS AND PACKETS ; ;- MAPD: ;REF LABEL .IF DF DEBUG 1$: BPT ;GET TO XDT MOV #NOP,1$ ;NOP THE BRK PNT .ENDC ;DEBUG CMP #DUSTRT,#120000 ;LOADABLE DRIVER? BLO 30$ ;IF LO NO MOV KINAR6,C.SAPR(R3) ;SAVE PREVIOUS MAPPING OF APR 6 CMP #DUEND,#140000 ;DRIVER GREATER THAN 4K WORDS BLO 20$ ;IF LO NO MOV C.PAR6(R6),KINAR6 ;YES, SET APR 6 TO MAP DRIVER'S RINGS AND PACKETS 10$: CALL @(SP)+ ;CALL CALLER BACK 20$: MOV C.SAPR(R3),KINAR6 ;RESTORE KISAR6 30$: RETURN ;EXIT .ENDC ;DU$BIG .PAGE ;+ ; DU DRIVER CONTROLLER STATE TABLES ;- DUTBL: DUTBL$ DU,R$$UDA ;CONTROLLER STATE TABLES ;+ ; DU DRIVER RING SPACE ;- DURNG: DURNG$ DU,R$$UDA,RNGSIZ p ;+ ; DU DRIVER PACKET SPACE ;- DUBUF: DUPKT$ DU,R$$UDA,RSPLNG,CMDLNG DUEND: .BLKW CMDLNG ; .END pÑ€kQ ›c, .TITLE DRATP .IDENT /01.04/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.04 ; ; D. N. CUTLER 31-AUG-73 ; ; MODIFIED BY: ; ; M. S. HARVEY 2-JAN-80 ; MSH045 -- CREATE THIS MODULE FROM DRRES TO REMOVE ; THIS CODE FROM THE DIRECTIVE COMMON ; ; M. S. HARVEY 5-MAY-81 ; MSH165 -- MODIFY SO THAT THIS DIRECTIVE CODE MAY BE ; PLACED IN THE SECOND EXECUTIVE COMMON ; ; ; THIS MODULE CONTAINS THE ALTER PRIORITY DIRECTIVE PROCESSING CODE. ; ; MACRO LIBRARY CALLS ; .MCALL TCBDF$,PCBDF$,HDRDF$,PKTDF$ TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS ;+ ; **-$DRATP-ALTER TASK PRIORITY ; **-$DRAP1-ALTER TASK PRIORITY FOR DIRECTIVE ;MSH165 ; **-$DRAP2-ALTER TASK PRIORITY FOR TASK ;MSH165 ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CHANGE THE TASK PRIORITY ; OF THE SPECIFIED TASK. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(9.),DPB SIZE(4.) ; WD. 01 -- FIRST HALF OF TASK NAME. ; WD. 02 -- SECOND HALF OF TASK NAME. ; WD. 03 -- NEW PRIORITY. ; ; INPUTS: ; ; R0=ADDRESS OF THE TCB OF THE TASK TO BE ALTERED. ; R1=ADDRESS OF THE TASK STATUS WORD OF THE TASK TO BE ALTERED. ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=POINTER TO DESIRED TASK PRIORITY IF ENTRY AT ;MSH165 ; $DRATP OR $DRAP1. ;MSH165 ; R3=DESIRED TASK PRIORITY IF ENTRY AT $DRAP2. ;MSH165 ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ;**-1 ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF THE ; TASK IS NOT ACTIVE. ; DIRECTIVE STATUS OF 'D.RS95' IS RETURNED IF THE ; NEW PRIORITY SPECIFIED IS INVALID. ; ;MSH165 ; NOTE: FOR SYSTEMS WITHOUT SUPPORT FOR THIS DIRECTIVE, THE GLOBAL ;MSH165 ; ENTRY POINT, $DRATP, IS DEFINED IN THE PROCESSING ROUTINE FOR THE ;MSH165 ; DECLARE SIGNIFICANT EVENT DIRECTIVE. ;MSH165 ; ;- .IF DF A$$PRI ;MSH165 .IF NDF D$$PAR ;MSH165 $DRATP:: ;REF LABEL .ENDC ;MSH165 ;MSH165 $DRAP1::MOV (R3),R3 ;GET NEW PRIORITY ;MSH165 $DRAP2:: ;REF LABEL ;MSH165 .IF DF M$$MUP BIT #T3.PRV,T.ST3(R5) ;ISSUING TASK PRIVILEGED? BNE 35$ ;IF NE YES CMP R0,R5 ;MODIFYING OWN PRIORITY? BNE 180$ ;IF NE NO - PRIVILEGE VIOLATION CMPB R3,T.DPRI(R0) ;RAISING ABOVE INSTALLED PRIORITY? ;MSH165 BHI 180$ ;IF HI YES - PRIVILEGE VIOLATION ;**-1 35$: ;REF LABEL .ENDC MOV R0,R5 ;SAVE TCB ADDR OF TASK TO BE ALTERED TST (R1) ;TASK ACTIVE? BMI 175$ ;IF MI NO TST R3 ;WAS A NEW PRIORITY SPECIFIED? ;MSH165 BNE 40$ ;IF NE ONE WAS SPECIFIED ;**-1 BISB T.DPRI(R5),R3 ;USE DEFAULT PRIORITY 40$: CMP R3,#250. ;NEW PRIORITY .GT. 250? BHI 170$ ;IF HI YES MOVB R3,T.PRI(R5) ;SET NEW PRIORITY TSTB T.IOC(R5) ;ANY I/O ACTIVE? BEQ 100$ ;IF EQ NO CLR -(SP) ;PUSH INITIAL LUN NUMBER - 1 50$: MOV T.PCB(R5),R4 ;GET PCB ADDR MOV P.HDR(R4),R4 ;GET TASK HEADER OF TASK TO BE ALTERED CMP (SP),H.NLUN(R4) ;PAST LAST LUN? BHIS 90$ ;IF HIS YES MOV (SP),R1 ;GET LUN -1 CALL $MPLNE ;MAP LUN TO UCB ADDRESS BCS 80$ ;IF CS LUN IS NOT ASSIGNED .IF DF A$$CPS MOV R0,-(SP) ;SAVE UCB ADDRESS .IFTF MOV U.SCB(R0),R4 ;GET PTR TO SCB FOR THIS UCB CALL 130$ ;REORDER I/O QUEUE .IFT MOV (SP)+,R0 ;RETRIEVE UCB ADDRESS TST U.CW1(R0) ;DEVICE MOUNTABLE? BPL 80$ ;IF PL NO BITB #US.MNT!US.FOR,U.STS(R0) ;MOUNTED AND NOT FOREIGN? BNE 80$ ;IF NE NO MOV U.ACP(R0),R4 ;PICK UP TCB OF ACP ADD #T.RCVL,R4 ;POINT TO RECEIVE QUEUE LISTHEAD CALL 130$ ;REORDER ACP QUEUE .ENDC 80$: INC (SP) ;UPDATE LUN NUMBER BR 50$ ;CONTINUE THROUGH LUN LOOP 90$: TST (SP)+ ;POP LUN NUMBER FROM STACK 100$: MOV R5,R0 ;GET TCB ADDR OF TASK TO BE ALTERED CALL $ACTRM ;REMOVE TCB FROM ATL BCS 110$ ;IF CS TCB NOT YET IN ATL CALL $ACTTK ;RE-INSERT TCB IN ATL 110$: ;REF LABEL .IF DF D$$ISK MOV T.PCB(R5),R4 ;GET PCB ADDR MOV P.MAIN(R4),R0 ;GET MAIN PCB ADDR ADD #P.WAIT,R0 ;GET LISTHEAD FOR PARTITION WAIT QUEUE MOV R5,R1 ;POINT TO TASK TCB CALL $QRMVT ;TRY TO REMOVE TCB FROM QUEUE BCS 120$ ;IF CS TCB NOT IN WAIT QUEUE CALL $QINSP ;RE-INSERT TCB BY NEW PRIORITY 120$: MOV R4,R0 ;GET PCB ADDR CALL $NXTSK ;RE-SCHEDULE PARTITION .ENDC CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT 130$: MOV #-2,-(SP) ;CONSTRUCT TEMPORARY LISTHEAD ON STACK ADD SP,(SP) ; CLR -(SP) ; 140$: MOV R4,R0 ;GET I/O PACKET LISTHEAD ADDR MOV R5,R1 ;GET TCB ADDR OF TASK TO BE ALTERED CALL $QRMVT ;REMOVE I/O PACKET BY TCB ADDR BCS 150$ ;IF CS NO I/O PACKET FOUND CMPB I.PRI(R1),#250. ;PRIORITY HIGHER THAN 250? BHI 145$ ;IF HI YES, DON'T CHANGE, BRKTHRU WRITE MOVB T.PRI(R5),I.PRI(R1) ;SET NEW PRIORITY 145$: MOV SP,R0 ;SET TEMPORARY LISTHEAD ADDR CALL $QINSF ;INSERT I/O PACKET IN TEMPORARY LIST BR 140$ ;CONTINUE THROUGH PACKET REMOVAL LOOP 150$: MOV SP,R0 ;SET TEMPORARY LISTHEAD ADDR CALL $QRMVF ;REMOVE FIRST I/O PACKET FROM LIST BCS 160$ ;IF CS NO I/O PACKET FOUND MOV R4,R0 ;GET I/O PACKET LISTHEAD ADDR CALL $QINSP ;RE-INSERT I/O PACKET BY NEW PRIORITY BR 150$ ;CONTINUE THROUGH PACKET INSERTION LOOP 16ü0$: CMP (SP)+,(SP)+ ;CLEAN TEMPORARY LISTHEAD OFF STACK RETURN ; 170$: DRSTS D.RS95 ;SET DIRECTIVE STATUS 175$: DRSTS D.RS7 ;SET DIRECTIVE STATUS .IF DF M$$MUP 180$: DRSTS D.RS16 ;PRIVILEGE VIOLATION .ENDC .ENDC .END ü×p:kQ ›c,š .TITLE DRGIN .IDENT /01.01/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.01 ; ; M. S. HARVEY 2-JAN-80 ; ; ; .IF DF D$$GIN $DRGIN:: DRSTS D.RS99 ;ILLEGAL DIRECTIVE FOR NOW !! .ENDC .END šóQƒkQ ›c, .TITLE MDSUB .IDENT /01.10/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.10 ; ; M. S. HARVEY 21-AUG-80 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; M. S. HARVEY 17-SEP-79 ; MSH062 -- DEFINE $BLKCK ROUTINE FOR TU58 DRIVER ; AND ML11 DRIVER ; ; P. J. CARR 18-APR-80 ; PJC003 -- REMOVE M$$IXD STUFF ; ; M. S. HARVEY 9-MAY-80 ; MSH099 -- CORRECT LOCK BLOCK LENGTH SYMBOL ; ; M. S. HARVEY 21-AUG-80 ; MSH112 -- CREATE THIS SOURCE MODULE FROM IOSUB. ; ALL CORRECTIONS LISTED ABOVE CAME FROM IOSUB. ; ; P. J. BEZEREDI 13-NOV-80 ; PB194 -- USE EIS INSTRUCTION SET WHERE APPLICABLE. ; ; R. T. PERRON 21-NOV-80 ; RP041 -- CHANGE INTERFACE TO COMMON ECC ROUTINE ; ; M. Pettengill 6-May-81 ; MLP035 -- Upgrade RMS block lock processing to include ; real reader locks and shared locks for all ; reader requests and specified writer reads ; MLP036 -- Support file by file write checking ; ; R. T. PERRON 24-AUG-81 ; RP072 -- DEFINE $BLKCK FOR RF11, RX01,RX02, ; AND THE UDA50 ; ; M. Pettengill 12-Oct-81 ; MLP066 -- Correct problem with lock without I/O and ; don't create a lock for a reader to allow use ; of RMS-11 V1.8 ; ; ; MASS STORAGE DEVICE RELATED ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL F11DF$,PKTDF$,HWDDF$ F11DF$ ;DEFINE WINDOW AND LOCK BLOCK OFFSETS  PKTDF$ ;DEFINE I/O PACKET OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS ;+ ; **-$BLKCK-LOGICAL BLOCK CHECK ROUTINE ; **-$BLKC1-LOGICAL BLOCK CHECK ROUTINE (ALTERNATE ENTRY) ; ; THIS ROUTINE IS CALLED BY I/O DEVICE DRIVERS TO CHECK THE STARTING ; AND ENDING LOGICAL BLOCK NUMBERS OF AN I/O TRANSFER TO A FILE ; STRUCTURED DEVICE. IF THE RANGE OF BLOCKS IS NOT LEGAL, THEN $IODON ; IS ENTERED WITH A FINAL STATUS OF "IE.BLK" AND A RETURN TO THE ; DRIVER'S INITIATOR ENTRY POINT IS EXECUTED. ELSE A RETURN TO THE ; DRIVER IS EXECUTED. ; ; INPUTS: ; ; R1=ADDRESS OF I/O PACKET. ; R5=ADDRESS OF THE UCB. ; ; OUTPUTS: ; ; IF THE CHECK FAILS, THEN $IODON IS ENTERED WITH A FINAL STATUS ; OF "IE.BLK" AND A RETURN TO THE DRIVER'S INITIATOR ENTRY POINT ; IS EXECUTED. ; ; IF THE CHECK SUCCEEDS, THEN THE FOLLOWING REGISTERS ARE RETURNED ; R0=LOW PART OF LOGICAL BLOCK NUMBER. ; R1=POINTS TO I.PRM+12 (LOW PART OF USER LBN) ; R2=HIGH PART OF LOGICAL BLOCK NUMBER. ; R3=ADDRESS OF I/O PACKET. ;- .IIF DF R$$JP1!R$$K11!R$$L11!R$$M11!R$$P11 BLKCK=0 ;MSH062 .IIF DF R$$JS1!R$$611!T$$C11!T$$U58!M$$L11 BLKCK=0 ;MSH062 .IIF DF R$$F11!R$$X11!R$$X21!R$$UDA BLKCK=0 ; RP072 ;MSH062 .IF DF BLKCK ;MSH062 ;**-1 $BLKCK::MOV R1,R3 ;SAVE ADDRESS OF I/O PACKET ADD #I.PRM+11,R1 ;POINT PAST HIGH PART OF LBN CLRB (R1)+ ;CLEAR EXCESS BYTE $BLKC1:: ;ALTERNATE ENTRY POINT MOV (R1),R0 ;GET LOW PART OF LBN MOV -(R1),R2 ;GET HIGH PART OF LBN MOV I.PRM+4(R3),-(SP) ;GET NUMBER OF BYTES TO TRANSFER ADD #777,(SP) ;ROUND TO NEXT BLOCK ROR (SP) ;CALCULATE NUMBER OF BLOCKS IN HIGH BYTE CLRB (SP) ;CLEAR EXCESS BYTE SWAB (SP) ;CALCULATE NUMBER OF BLOCK IN TRANSFER ADD (SP)+,R0 ;CALCULATE HIGHEST BLOCK NUMBER + 1 ADCB R2 ; BCS 20$ ;IF CS ILLEGAL BLOCK NUMBER CMPB R2,U.CW2(R5) ;HIGH PART OF LBN LEGAL? BHI 20$ ;IF HI NO BLO 10$ ;IF LO YES CMP R0,U.CW3(R5) ;LOW PART OF LBN LEGAL? BHI 20$ ;IF HI NO 10$: MOV (R1)+,R2 ;RETRIEVE HIGH PART OF LBN MOV (R1),R0 ;RETRIEVE LOW PART OF LBN RETURN ; 20$: MOV (R5),R0 ;GET ADDRESS OF DEVICE DCB MOV @D.DSP(R0),(SP) ;REPLACE RETURN ADDRESS TO INITIATOR MOV #IE.BLK&377,R0 ;SET FINAL I/O STATUS CALLR $IOALT ;FINISH THE I/O REQUEST ;MSH112 .ENDC ;+ ; **-$MPPKT-MAP I/O PACKET FUNCTION ; ; THIS ROUTINE IS CALLED TO MAP A READ/WRITE VIRTUAL FUNCTION IN AN I/O PACKET ; TO A READ/WRITE LOGICAL FUNCTION. IF THE CURRENT WINDOW DOES NOT MAP THE VIRTU ; FUNCTION, THEN A FAILURE INDICATION IS RETURNED. ELSE IF THE WINDOW COMPLETELY ; MAPS THE VIRTUAL FUNCTION, THEN THE LOGICAL BLOCK NUMBER IS STORED IN THE I/O ; PACKET AND THE READ/WRITE VIRTUAL FUNCTION IS CONVERTED TO ITS LOGICAL COUNTER ; PART. ELSE THE PARTIAL MAPPING RESULTS ARE RETURNED TO THE CALLER. ; ; INPUTS: ; ; R1=ADDRESS OF THE I/O PACKET. ; ; OUTPUTS: ; ; C=1 IF MAPPING FAILURE. ; C=0 IF MAPPING WAS SUCCESSFUL. ; IF R0 EQ 0, THEN ; I.FCN+1(R1)=IO.WLB/IO.RLB. ; I.PRM+10(R1)=HIGH PART OF MAPPED LBN. ; I.PRM+12(R1)=LOW PART OF MAPPED LBN.. ; ELSE ; R0=NUMBER OF BLOCKS NOT MAPPED. ; R2=HIGH PART OF MAPPED LBN. ; R3=LOW PART OF MAPPED LBN. ; ; R1 IS PRESERVED ACROSS CALL. ;- .IF DF A$$CPS $MPPKT::MOV I.PRM+12(R1),R3 ;PICKUP LOW PART OF VBN MOV I.PRM+10(R1),R2 ;PICKUP HIGH PART OF VBN MOV R1,-(SP) ;SAVE I/O PACKET ADDRESS MOV I.PRM+4(R1),R0 ;GET LENGTH OF TRANSFER IN BYTES MOV @I.LN2(R1),R1 ;GET ADDRESS OF WINDOW BLOCK BIC #1,R1 ;MAKE SURE LOW BIT OF ADDRESS IS ZERO CALL $MPVBN ;MAP VIRTUAL BLOCK NUMBER MOV (SP)+,R1 ;RETRIEVE I/O PACKET ADDRESS BCS 20$ ;IF CS MAPPING FAILURE TST R0 ;REQUEST COMPLETELY MAPPED? BNE 20$ ;IF NE NO MOVB R2,I.PRM+10(R1) ;SET HIGH PART OF LBN MOV R3,I.PRM+12(R1) ;SET LOW PART OF LBN MOV #IO.RLB,-(SP) ;ASSUME READ REQUEST ; MLP036 CMPB #IO.WVB/256.,I.FCN+1(R1) ;WRITE VIRTUAL FUNCTION? ;**-1 BNE 10$ ;IF NE NO ; MLP036 ; MLP036 .IF DF D$$WCH ; MLP036 ; MLP036 MOV #IO.WLC,(SP) ;ASSUME WRITE CHECK ; MLP036 MOV @I.LN2(R1),-(SP) ;GET ADDRESS OF WINDOW ; MLP036 BIC #1,(SP) ;CLEAR LUN INTERLOCK ; MLP036 ; ASSUME WI.WCK,100000 ; MLP036 TST @(SP)+ ;DATA CHECKING REQUESTED? ; MLP036 BMI 10$ ;IF MI YES ; MLP036 CLRB (SP) ;DEMOTE TO WRITE LOGICAL (IO.WLB) ; MLP036 ; MLP036 .IFF ; MLP036 ; MLP036 MOV #IO.WLB,(SP) ;CONVERT TO WRITE LOGICAL ; MLP036 ; MLP036 .ENDC ; MLP036 ; MLP036 10$: MOV (SP)+,I.FCN(R1) ;SET NEW FUNCTION CODE  ;**-2 .IF DF M$$MGE MOV R1,R3 ;SAVE I/O PACKET ADDRESS MOV I.PRM(R3),R1 ;GET RELOCATION BIAS MOV I.PRM+2(R3),R2 ;GET DISPLACEMENT ADDRESS CALL $MPPHY ;MAP TO 18 BIT PHYSICAL ADDRESS MOV R1,I.PRM(R3) ;INSERT 18 BIT PHYSICAL ADDRESS BACK MOV R2,I.PRM+2(R3) ;INTO I/O PACKET MOV R3,R1 ;RESTORE I/O PACKET ADDRESS CLC ;MAKE SURE CARRY IS CLEAR .ENDC 20$: RETURN ; ;+ ; **-$MPVBN-MAP VIRTUAL BLOCK NUMBER ; ; THIS ROUTINE IS CALLED TO MAP A VIRTUAL BLOCK NUMBER (VBN) TO A LOGICAL BLOCK ; NUMBER (LBN) VIA A WINDOW BLOCK THAT CONTAINS A SET OF MAPPING POINTERS. ; ; INPUTS: ; ; R0=NUMBER OF CONSECUTIVE BYTES THAT MUST BE MAPPED. ; R1=ADDRESS OF THE WINDOW BLOCK. ; R2=HIGH PART OF VBN. ; R3=LOW PART OF VBN. ; ; OUTPUTS: ; ; C=1 IF VBN CANNOT BE MAPPED VIA WINDOW BLOCK. ; C=0 IF VBN SUCCESSFULLY MAPPED TO LBN. ; PARTIAL MAPPING IS A SUCCESS ; R0=NUMBER OF UNMAPPED BLOCKS. ; R2=HIGH PART OF LBN. ; R3=LOW PART OF LBN. ;- $MPVBN::SAVNR ;SAVE NONVOLATILE REGISTERS MOVB (R1),R5 ;GET THE NUMBER OF ACTIVE PTRS BEQ 20$ ;IF EQ NO MAP POSSIBLE ADD #777,R0 ;ROUND BYTES TO NEXT 256. WORD BLOCK ROR R0 ;CONVERT TO WORDS CLRB R0 ;CLEAR RESIDUAL BITS SWAB R0 ;SWAP NUMBER OF BLOCKS TO LOW BYTE MOVB W.VBN(R1),R4 ;GET 7 BITS OF HI VBN SUB R4,R2 ;NORMALIZE HIGH PART OF VBN SUB W.VBN+2(R1),R3 ;NORMALIZE LOW VBN SBC R2 ; BLO 20$ ;BRANCH ON MAPPING FAILURE ADD #W.RTRV,R1 ;POINT R1 TO WINDOW MAPPING POINTERS 10$: SUB (R1)+,R3 ;SUBTRACT EXTENT SIZE FROM VBN SBC R2 ; ALSO HIGH VBN BLO 30$ ;BRANCH IF VBN IS IN THIS EXTENT CMP (R1)+,(R1)+ ;SKIP OVER THE LBN DEC R5 ;DECREMENT ACTIVE POINTER COUNT BGT 10$ ;IF GT YES 20$: SEC ;INDICATE MAPPING FAILURE BR 70$ ; ; 30$: ADD R3,R0 ;TEST FOR ALL BLOCKS IN EXTENT BGT 40$ ;BRANCH IF NOT - ONLY PARTIAL MAP CLR R0 ;ZERO R0 FOR FULL MAPPING 40$: ADD -2(R1),R3 ;R3=OFFSET WITHIN EXTENT ADC R2 ;R2=HIGH OFFSET (=0) ADD (R1)+,R2 ;ADD THE EXTENTS BEGINNING ADD (R1)+,R3 ; LBN TO THE OFFSET ADC R2 ; TO GET DESIRED LBN ; NOTE: AT THIS POINT THE CARRY IS CLEAR 70$: ; RETURN ; .ENDC ;+ ; **-$LCKPR-LOCK PROCESSING ROUTINE ; ; THIS ROUTINE FIRST DETERMINES IF A FILE I/O REQUEST IS TO A SHARED ; FILE. IF SO, IT DETERMINES IF THE REQUEST IS AN UNLOCK QIO OR A ; VIRTUAL BLOCK I/O REQUEST. IT THEN EITHER PERFORMS THE UNLOCK QIO ; OR THE LOCK PROCESSING RESPECTIVELY. ; ; INPUTS: ; ; R1=I/O PACKET ADDRESS OF THE REQUEST ; ; OUTPUTS: ; ; C=0 IF NO LOCK PROCESSING WAS REQUIRED. ; ; C=1 IF AN UNLOCK WAS PERFORMED OR AN ERROR CONDITION OCCURED ; DURING THE LOCK PROCESSING. ; R0=I/O STATUS ; ; R1 IS PRESERVED. ;- .IF DF R$$LKL $LCKPR::MOV @I.LN2(R1),R3 ;POINT TO WINDOW BLOCK BIC #1,R3 ;CLEAR INTERLOCK BIT MOV #IE.ULK&377,R0 ;SET FOR UNLOCK ERROR STATUS MOV W.LKL(R3),R2 ;POINT TO FIRST ENTRY IN LOCK LIST BEQ 50$ ;IF EQ THERE IS NONE ; MLP035 ; ; MLP035 ; At this point we know that block locking is enabled for the file. ; MLP035 ; ; MLP035 ; The type of lock requested is either shared or exclusive depending ; MLP035 ; on the type of accessor and the I/O function. ; MLP035 ; ; MLP035 ; If request is from a reader then I.FCN(R1) is ; MLP035 ; IO.RVB to read with shared lock ; MLP035 ; IO.ULK to unlock any or all existing locks ; MLP035 ; IO.ULK!IQ.LCK to request a shared lock without any I/O ; MLP035 ; ; MLP035 ; If the request is from a writer then I.FCN(R1) is ; MLP035  ; IO.RVB to read with an exclusive lock ; MLP035 ; IO.RVB!IQ.LCK to read with a shared lock ; MLP035 ; IO.WVB to write with exclusive lock ; MLP035 ; IO.ULK to unlock any or all existing locks ; MLP035 ; IO.ULK!IQ.LCK to request a exclusive lock without I/O ; MLP035 ; ; MLP035 ; MLP035 SAVNR ;SAVE R4 AND R5 MOV I.PRM+4(R1),R4 ;PICK UP BYTE COUNT FOR REQUEST ADD #777,R4 ;ROUND TO NEXT DISK BLOCK ROR R4 ;CONVERT TO SIZE IN BLOCKS CLRB R4 ; SWAB R4 ; CMPB I.FCN+1(R1),#IO.ULK/256. ;IS THIS AN UNLOCK REQUEST? BNE 100$ ;IF NE NO ; ASSUME IQ.LCK,200 ; MLP035 TSTB I.FCN(R1) ;LOCK WITHOUT I/O REQUEST? ; MLP035 BPL 5$ ;IF PL NO ; MLP035 CALL 100$ ;DO LOCK PROCESSING ; MLP035 DEC @I.PRM+16(R1) ;UNBUSY LOCK BLOCK SINCE NO I/O ; MLP066 CLR I.PRM+16(R1) ;DON'T DO IT TWICE ; MLP066 BR 50$ ;JOIN COMMON CODE ; MLP035 5$: ;REFERENCE LABEL ; MLP035 ; ; UNLOCK PROCESSING ; ; THIS SECTION OF THE ROUTINE PERFORMS THE UNLOCK PROCESSING. RELEVANT ; REGISTER CONTENTS AT THIS POINT ARE: ; ; R0=UNLOCK ERROR STATUS ; R1=I/O PACKET ADDRESS ; R2=ADDRESS OF THE FIRST LOCK BLOCK IN THE LOCK LIST ; R3=POINTER TO CURRENT WINDOW ; R4=BYTE COUNT OF CURRENT UNLOCK REQUEST ; MOV I.PRM+12(R1),R5 ;CREATE BLOCK NUMBER SPECIFIED FLAG BISB I.PRM+10(R1),R5 ; 10$: TSTB L.CNT(R2) ;THIS LOCK BLOCK IN USE? BEQ 40$ ;IF EQ NO TST R5 ;BLOCK NUMBER SPECIFIED? BEQ 20$ ;IF EQ NO CALL 180$ ;EXACT VBN AND COUNT MATCH? BNE 40$ ;IF NE NO 20$: CMP L.WI1(R2),R3 ;SAME OWNER? BNE 40$ ;IF NE NO CLRB L.CNT(R2) ;UNLOCK THE LOCK MOV #IS.SUC&377,R0 ;SET FOR SUCCESSFUL RETURN TST R5 ;WAS THIS FOR AN EXPLICIT BLOCK NUMBER? BNE 50$ ;IF NE YES 40$: MOV (R2),R2 ;POINT TO NEXT LOCK BLOCK BNE 10$ ;IF NE THERE IS ONE ; ; NO LOCK LIST EXISTS ; ; IF THE FUNCTION IS NOT AN UNLOCK FUNCTION, A SIMPLE RETURN OCCURS ; WITH CARRY CLEAR. AN UNLOCK IN THIS CASE IS AN ERROR. (NOTE THAT ; ALL UNLOCK REQUESTS FALL THROUGH HERE AS WELL.) ;  50$: CMPB I.FCN+1(R1),#+1 ;SET CARRY IF UNLOCK RETURN ; ; ; LOCK PROCESSING ; ; THIS ROUTINE CHECKS FOR ATTEMPTED LOCK OVERLAPS, ATTEMPTS TO SET THE ; NEW LOCK, AND PERFORMS THE IMPLIED UNLOCK. IF A NEW LOCK REQUEST ; FOR AN EXPLICIT UNLOCKER IS DETECTED WHICH EXACTLY MATCHES AN EXISTING ; LOCK FOR THAT WINDOW IN BOTH STARTING VBN AND SIZE, THE LOCK BLOCK IS ; SIMPLY REUSED. RELEVANT REGISTER CONTENTS AT THIS POINT ARE: ; ; R1=I/O PACKET ADDRESS ; R2=ADDRESS OF FIRST LOCK BLOCK IN LOCK LIST ; R3=ADDRESS OF FILE WINDOW ; R4=BLOCK COUNT FOR CURRENT REQUEST ; ; ; MLP035 ; The following cases are considered: ; MLP035 ; ; MLP035 ; 1. If the request is for a window with implicit (not explicit, ; MLP035 ; WI.EXL) unlocking and there exists a current lock for that ; MLP035 ; window with I/O still in progress then return a lock error ; MLP035 ; (IE.LCK). ; MLP035 ; ; MLP035 ; 2. If the request is an exact match for a lock which is an ; MLP035 ; exact match of window (owner), LBN, and size and which ; MLP035 ; has I/O still in progress then return a lock error (IE.LCK). ; MLP035 ; ; MLP035 ; 3. If the request is from a window with only read access or a ; MLP035 ; read request requesting only shared access from a writer ; MLP035 ; attempt to grant a shared lock. If there is no existing ; MLP035 ; lock with overlap then grant the shared lock. In the case ; MLP035 ; of a conflict see table below. ; MLP035 ; ; MLP035 ; 4. If the request is from a window with write access and is a ; MLP035 ; write or a read without a shared lock request attempt to ; MLP035 ; grant an exclusive lock. If there is no existing lock with ; MLP035 ; overlap then grant an exclusive lock. In the case of conflict ; MLP035 ; see table below. ; MLP035 ; ; MLP035 ; 5. Decision table for resolving conflicts: ; MLP035 ; ; MLP035 ; I/O request ; MLP035 ; Lock Shared Exclusive ; MLP035 ; ; MLP035 ; Exact match grant shared granted exclusive ; MLP035 ; if no other conflict ; MLP035 ; (reuse lock block) (reuse lock block) ; MLP035 ; ; MLP035 ; Conflict shared grant shared reject IE.LCK ; MLP035 ; ; MLP035 ; Conflict exclusive reject IE.LCK reject IE.LCK ; MLP035 ; ; MLP035 100$: CLR R5 ;INIT FREE NODE POINTER MOV #IE.LCK&377,-(SP) ;PUSH LOCK ERROR STATUS CLR -(SP) ;ASSUME SHARED LOCK ; MLP035 BIT #WI.WRV,(R3) ;IS THIS REQUEST FOR A WRITER? ; MLP035 BEQ 110$ ;IF EQ NO, ALWAYS SHARED LOCK ; MLP035 CMPB I.FCN+1(R1),#IO.RVB/400 ; IS THIS A READ REQUEST? ; MLP035 BNE 105$ ;IF NE NO, ALWAYS EXCLUSIVE LOCK ; MLP035 ; ASSUME IQ.LCK,200 ; MLP035 TSTB I.FCN(R1) ;SHARED LOCK REQUESTED? ; MLP035 BMI 110$ ;IF MI YES ; MLP035 105$: INC (SP) ;SET EXCLUSIVE LOCK REQUESTED ; MLP035 110$: TSTB L.CNT(R2) ;IS LOCK BLOCK IN USE? BNE 120$ ;IF NE YES TST R5 ;ALREADY HAVE FREE BLOCK? BNE 150$ ;IF NE YES, LOOK AT NEXT LOCK BLOCK BR 130$ ;ELSE CLAIM THIS BLOCK 120$: MOV L.WI1(R2),R0 ;PICK UP OWNER WORD BIC #1,R0 ;CLEAR BIT FOR NO UNLOCK FLAG CMP R0,R3 ;LOCK BELONG TO THIS WINDOW? BNE 140$ ;IF NE NO, CHECK FOR OVERLAPS BIT #WI.EXL,(R3) ;EXPLICIT UNLOCKER? BEQ 125$ ;IF EQ NO, SAVE BLOCK FOR IMPLIED UNLOCK CALL 180$ ;EXACT VBN AND COUNT? BNE 140$ ;IF NE NO ; MLP035 125$: MOV L.WI1(R2),R0 ;RETRIEVE OWNER WORD ;**-1 ROR R0 ;CAN LOCK BLOCK BE REUSED? BCS 153$ ;IF CS NO ; MLP035 130$: MOV R2,R5 ;SET TO REUSE THIS LOCK BLOCK ;**-1 BR 150$ ;LOOK AT NEXT LOCK BLOCK 140$: MOVB L.CNT(R2),R0 ;PICKUP LOCK BLOCK COUNT, EXCLUSIVE? ; MLP035 BMI 141$ ;IF MI YES ; MLP035 TST (SP) ;REQUEST EXCLUSIVE LOCK? ; MLP035 BEQ 150$ ;IF NE NO ; MLP035 BR 142$ ;DO CONFLICT CHECK ; MLP035 141$: NEG R0 ;CONVERT TO MAGNITUDE ; MLP035 142$: ADD L.VB1+2(R2),R0 ;CALCULATE NUMBER OF HIGHEST BLOCK + 1 ; MLP035 MOVB L.VB1(R2),-(SP) ;PUSH HIGH ORDER BYTE ;**-3 ADCB (SP) ;PROPAGATE CARRY CMPB I.PRM+10(R1),(SP)+ ;OVERLAP? BNE 145$ ;IF NE USE BRANCH BELOW CMP I.PRM+12(R1),R0 ;OVERLAP? 145$: BHIS 150$ ;IF HIS NO MOV R4,R0 ;COPY SIZE OF CURRENT REQUEST ADD I.PRM+12(R1),R0 ;CALCULATE NUMBER OF HIGHEST BLOCK +1 MOVB I.PRM+10(R1),-(SP) ;PUSH HIGH ORDER BYTE ADCB (SP) ;PROPAGATE CARRY CMPB L.VB1(R2),(SP)+ ;OVERLAP? BNE 146$ ;IF NE USE BRANCH BELOW CMP L.VB1+2(R2),R0 ;OVERLAP? 146$: BLO 153$ ;IF LO YES, (CARRY SET) ; MLP035 150$: MOV (R2),R2 ;POINT TO NEXT LOCK BLOCK ;**-1 BNE 110$ ;IF NE THERE IS ONE ; MLP066 ; ; MLP066 ; Hack: In order to phase in real reader locks which are not supported ; MLP066 ; by rms-11 v1.8, the following code is included to prevent them from ; MLP066 ; being created. At some future time this code will be removed. ; MLP066 ; ; MLP066 ; MLP066 .IF NE 1 ; MLP066 ; MLP066 BIT #WI.WRV,(R3) ;READER? ; MLP066 BEQ 170$ ;IF EQ YES ; MLP066 ; MLP066 .ENDC ; MLP066 ; MLP066 MOV R5,R0 ;COPY POINTER TO SAVED LOCK BLOCK ;**-3 BNE 160$ ;IF NE ONE WAS IN FACT SAVED MOV #IE.NOD&377,2(SP) ;ASSUME ALLOCATION FAILURE STATUS ; MLP035 MOV R1,-(SP) ;SAVE I/O PACKET ADDRESS ;**-1 MOV #L.LKSZ,R1 ;PICK UP SIZE OF LOCK BLOCK ;MSH099 CALL $ALOCB ;ALLOCATE LOCK BLOCK ;**-1 MOV (SP)+,R1 ;RESTORE I/O PACKET ADDRESS BCC 155$ ;IF CC SUCCESS ; MLP035 153$: ROL (SP) ;SAVE CARRY ; MLP035 BR 170$ ;JOIN COMMON EXIT CODE ; MLP035 155$: MOV @W.LKL(R3),(R0) ;POINT NEW BLOCK TO SECOND IN LIST ; MLP035 MOV R0,@W.LKL(R3) ;POINT FIRST BLOCK IN LIST TO NEW ONE ;**-2 160$: TST (R0)+ ;ADVANCE TO OWNER WORD MOV R0,I.PRM+16(R1) ;SAVE POINTER TO OWNER WORD MOV R3,(R0) ;SET OWNER WORD INC (R0)+ ;SET NO UNLOCK FLAG MOVB I.PRM+10(R1),(R0)+ ;SET HIGH PART OF VBN ROR (SP) ;EXCLUSIVE LOCK? ; MLP035 BCC 165$ ;IF CC NO ; MLP035 NEG R4 ;SET FOR EXCLUSVE LOCK ; MLP035 165$: MOVB R4,(R0)+ ;SET BLOCK COUNT ; MLP035 MOV I.PRM+12(R1),(R0) ;SET LOW PART OF VBN ;**-1 MOV #IS.SUC&377,2(SP) ;SET SUCCESS FOR LOCK WITHOUT I/O CASE; MLP035 170$: ROR (SP)+ ;SET CARRY, CLEAN STACK ; MLP035 MOV (SP)+,R0 ;PICKUP ERROR STATUS ; MLP035 RETURN ; ;**-1 ; ; ROUTINE TO CHECK FOR EXACT VBN AND BLOCK COUNT MATCH ; ; INPUTS: ; ; R1=I/O PACKET ADDRESS ; R2=LOCK BLOCK ADDRESS ; R4=BYTE COUNT ; ; OUTPUTS: ; ; ALL REGISTERS PRESERVED. ; ; Z=1 IF EXACT MATCH. ; ; Z=0 IT NO MATCH. ;  180$: CMP L.VB1+2(R2),I.PRM+12(R1) ;MATCH ON LOW ORDER? BNE 190$ ;IF NE NO CMPB L.VB1(R2),I.PRM+10(R1) ;MATCH ON HIGH ORDER? BNE 190$ ;IF NE NO TST R4 ;COUNT SPECIFIED? BEQ 190$ ;IF EQ NO MOVB L.CNT(R2),-(SP) ;GET LOCK BLOCK COUNT, NEGATIVE? ; MLP035 BPL 185$ ;IF PL NO ; MLP035 NEGB (SP) ;COMPUTE MAGNITUDE ; MLP035 185$: CMPB (SP)+,R4 ;CLEAN STACK, MATCH ON COUNT? ; MLP035 190$: RETURN ; ;**-1 .ENDC ;+ ; **-$ECCOR-COMMON ECC CORRECTION CODE FOR RP04/RK06. ; ; THIS ROUTINE APPLIES THE ECC CORRECTION ALGORITHM AND DETERMINES ; IF OFFSET RECOVERY IS REQUIRED (IF SUPPORTED). ; ; INPUTS: ; ; R0=BYTES ACTUALLY TRANSFERED ; RP041 ; R1=ECC ERROR POSITION (FROM HARDWARE REGISTER) ; RP041 ; R2=WORD COUNT (FROM HARDWARE REGISTER) ; RP041 ; R3=ECC ERROR CORRECTION PATTERN (FROM HARDWARE REGISTER) ; RP041 ; R5=UCB ADDRESS ;**-3 ; ; OUTPUTS: ; ; R0=IS.SUC&377 ; RP041 ; R1=BYTES ACTUALLY TRANSFERED ; RP041 ; R2=CSR ADDRESS ; RP041 ; R3=CONTROLLER INDEX ; RP041 ;- ;**-12 .IF DF S$$ECC ; RP041 $ECCOR::MOV R0,-(SP) ;SAVE BYTES ACCUTALLY TRANSFERED ; RP041 CLR R0 ;CLEAR HIGH ORDER ERROR POSITION ; RP041 DEC R1 ;CONVERT TO RELATIVE BIT NUMBER ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 DIV #20,R0 ;DIVIDE FOR: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 ; RP041 .IFF ;M$$EIS ; RP041  ; RP041 MOV R1,R0 ;COPY ECC ERROR POSITION ; RP041 MOV #20,R1 ;SET DIVISOR TO CALCULATE: ; RP041 ; R0=WORD POSITION (0-377) ; RP041 ; R1=BIT POSITION (0-17) ; RP041 CALL $DIV ;PERFORM DIVISION ; RP041 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 MOV R0,-(SP) ;SAVE WORD POSITION ; RP041 MOV R2,-(SP) ;SAVE REMAINING WORD COUNT ; RP041 CLR R2 ;CLEAR HIGH ORDER ERROR PATTERN ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 10$: ASHC R1,R2 ;SHIFT PATTERN INTO CORRECT POSITION ; RP041 ; RP041 .IFF ;M$$EIS ; RP041 ; RP041 10$: DEC R1 ;ANY MORE SHIFTS LEFT TO PERFORM ; RP041 BLT 20$ ;IF LT NO ; RP041 ASL R3 ;DOUBLE LEFT SHIFT ; RP041 ROL R2 ; ; RP041 BR 10$ ; ; RP041 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 20$: MOV 4(SP),R0 ;RETRIEVE ACTUAL BYTES TRANSFERED ; RP041 SUB #510.,R0 ;BACKUP TO BLOCK IN ERROR ... ; RP041 ;... OFFSET TO HIGH WORD IN ERROR ; RP041 CALL $RELOP ;COMPUTE LOCATION IN PHYSICAL MEMORY ; RP041 MOV (SP)+,R0 ;RETRIEVE REMAINING WORD COUNT ; RP041 BPL 30$ ;IF PL THIS MAY HAVE BEEN A PARTIAL BLOC; RP041 ;TRANSFER ; RP041 CLR R0 ;ASSUME A WHOLE BLOCK WAS TRANSFERRED ; RP041 30$: ADD (SP),R1 ;ADD IN ERROR WORD POSITION OFFSET ... ; RP041 ADD (SP),R1 ;... FOR BYTE ADDRESSING ; RP041 ADD (SP)+,R0 ;ADD CORRECTION OFFSET TO CORRECTION LIM; RP041 CMP R0,#377 ;IS THE CORRECTION ENTIRELY IN THIS BLOC; RP041 BHI 50$ ;IF HI NOT AT ALL ; RP041 BEQ 40$ ;IF EQ THEN ONLY ONE WORD ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041 ; RP041 XOR R2,(R1) ;CORRECT HIGH ORDER WORD ; RP041 40$: XOR R3,-(R1) ;CORRECT LOW ORDER WORD ; RP041 ; RP041 .IFF ;M$$EIS ; RP041 ; RP041 MOV (R1),R0 ;COPY HIGH ORDER DATA WORD ; RP041 BIC R2,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R2 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R2,(R1) ;PATTERN.OR.DATA WORD ; RP041 40$: MOV -(R1),R0 ;COPY LOW ORDER DATA WORD ; RP041 BIC R3,(R1) ;.NOT.PATTERN.AND.DATA WORD ; RP041 BIC R0,R3 ;.NOT.DATA WORD.AND.PATTERN ; RP041 BIS R3,(R1) ;PATTERN.OR.DATA WORD ; RP041 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 50$: MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL TRANSFER ; RP041 MOV (SP)+,R1 ;RESTORE BYTES TRANSFERRED ; RP041 MOV S.CSR(R4),R2 ;RESTORE CSR ADDRESS ; RP041 MOVB S.CON(R4),R3 ;RESTORE CONTROLLER INDEX ; RP041 RETURN ; ; RP041 ;**-89 .ENDC ;+ ; **-$CRPAS - COMMON REGISTER PASS ROUTINE ; ; THIS SUBROUTINE IS USED TO PASS THE CONTENTS OF THE DEVICE REGISTERS ; BACK TO THE DIAGNOSTIC TASK. ALL REGISTERS ARE PASSED IN THE ORDER ; IN WHICH THEY APPEAR ON THE UNIBUS. ; ; NOTE: THIS ROUTINE MAKES USE OF THE ERROR LOGGING ENTRIES S.ROFF AND ; S.RCNT IN THE SCB. THEREFORE ERROR LOGGING MUST BE ENABLED IN ; ORDER TO USE THIS ROUTINE. ; ; INPUTS: ; ; R1=I/O PACKET ADDRESS ; R2=CSR ADDRESS ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; ; R1=DESTROYED ; R0,R2 ARE PRESERVED ;- .IF DF D$$IAG $CRPAS::MOV R0,-(SP) ;SAVE R0 .IF DF M$$MGE MOV I.PRM+14(R1),KISAR6 ;SET RELOCATION BIAS .ENDC MOV I.PRM+16(R1),R0 ;GET REGISTER BUFFER ADDRESS MOV R2,-(SP) ;PRESERVE INITIAL CSR ADDRESS MOVB S.ROFF(R4),R2 ;GET OFFSET TO FIRST REGISTER ADD (SP),R2 ;ADD CSR ADDRESS MOVB S.RCNT(RÀ4),R1 ;GET NUMBER OF REGISTERS TO XFER 10$: MOV (R2)+,(R0)+ ;TRANSFER A REGISTER DEC R1 ;DONE YET? BNE 10$ ;IF NE NO .IF DF M$$EXT BIT #DV.EXT,U.CW1(R5) ;IS IT AN EXTENDED MEMORY DEVICE? ; RP041 BEQ 20$ ;IF EQ NO ;**-1 MOV (R2)+,(R0)+ ;TRANSFER RHBAE ;**-10 MOV (R2),(R0) ;TRANSFER RHCS3 ;**-3 .ENDC 20$: MOV (SP)+,R2 ;RESTORE CSR ADDRESS MOV (SP)+,R0 ;RESTORE R0 RETURN .ENDC .END À#wkQ ›c, .TITLE EXESB .IDENT /01.11/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.11 ; ; M. S. HARVEY 21-AUG-80 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; M. S. HARVEY 15-AUG-79 ; MSH049 -- DETECT GROUP GLOBAL EVENT FLAG CONVERSION. ; ; M. S. HARVEY 11-SEP-79 ; MSH045 -- ADD DIRECTIVE PARTITION SUPPORT  ; ; M. S. HARVEY 19-DEC-79 ; MSH076 -- IMPLEMENT GROUP GLOBAL EVENT FLAG USE CONTROL ; FOR SLAVE TASKS ; ; M. S. HARVEY 21-AUG-80 ; MSH112 -- CREATE THIS SOURCE MODULE FROM IOSUB. ; ALL CORRECTIONS LISTED ABOVE CAME FROM IOSUB. ; ; P. J. BEZEREDI 13-NOV-80 ; PB194 -- USE EIS INSTRUCTION SET WHERE APPLICABLE. ; ; M. S. HARVEY 5-MAY-81 ; MSH165 -- $GTGEF MOVED TO SECOND EXECUTIVE COMMON ; ; M. S. HARVEY 14-SEP-81 ; MSH189 -- RETURN MORE INFORMATION ABOUT ADDRESS ; CHECK FAILURE ; ; M. S. HARVEY 17-SEP-81 ; MSH190 -- UPDATE CONDITIONALIZATION ; ; EXECUTIVE GENERAL ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HDRDF$,HWDDF$,PKTDF$,TCBDF$ ;MSH049 HDRDF$ ;DEFINE TASK HEADER OFFSETS ;**-1 HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE GROUP GLOBAL CONTROL BLK OFFSETS;MSH049 TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS ;+ ; **-$ACHKP-ADDRESS CHECK PARAMETER BLOCK ; **-$ACHKW-ADDRESS CHECK PARAMETER BLOCK WORD ALIGNED ; **-$ACHK2-ADDRESS CHECK 2 BYTE DIRECTIVE PARAMETER BLOCK ; ; THESE ROUTINES ARE CALLED TO ADDRESS CHECK A TASK SPECIFIED PARAMETER ; BLOCK TO INSURE IT IS WITHIN THE TASK'S ADDRESS SPACE AND ALIGNED PROPERLY. ; IF EITHER CHECK FAILS, THEN A DIRECTIVE STATUS OF 'D.RS98' IS RETURNED. ; ; INPUTS: ; ; R0=STARTING ADDRESS OF THE BLOCK TO BE CHECKED. ; R1=LENGTH OF THE BLOCK TO BE CHECKED IN BYTES. ; ; OUTPUTS: ; ; THE SPECIFIED BLOCK IS CHECKED FOR PROPER ALIGNMENT AND WHETHER ; IT IS WITHIN THE TASK'S ADDRESS SPACE. IF EITHER CHECK FAILS, ; THEN A DIRECTIVE STATUS OF 'D.RS98' IS RETURNED. ELSE A RETURN ; TO THE CALLER IS EXECUTED. ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- .IF DF A$$CHK!M$$MGE .ENABL LSB .IF NDF M$$MGE $ACHK2::MOV #2,R1 ;SET TO CHECK 2 BYTES .IFTF $ACHKP::MOV R3,R0 ;SET ADDRESS OF BLOCK TO CHECK .IFF CALL $ACHCK ;ADDRESS CHECK WORD ALIGNED BCS 10$ ;IF CS CHECK FAILURE CALL $RELOC ;RELOCATE PARAMETER BLOCK ADDRESS MOV R1,KISAR6 ;MAP TO PARAMETER BLOCK MOV R2,R3 ;REDEFINE PARAMETER BLOCK ADDRESS RETURN ; .ENDC $ACHKW::CALL $ACHCK ;ADDRESS CHECK WORD ALIGNED BCC 50$ ;IF CC OKAY 10$: DRSTS D.RS98 ;SET DIRECTIVE STATUS ;+ ; **-$ACHKB-ADDRESS CHECK BYTE ALIGNED ; **-$ACHCK-ADDRESS CHECK WORD ALIGNED ; ; THIS ROUTINE IS CALLED TO ADDRESS CHECK A BLOCK OF MEMORY TO SEE WHETHER ; IT LIES WITHIN THE ADDRESS SPACE OF THE CURRENT TASK. ; ; INPUTS: ; ; R0=STARTING ADDRESS OF THE BLOCK TO BE CHECKED. ; R1=LENGTH OF THE BLOCK TO BE CHECKED IN BYTES. ; ; OUTPUTS: ; ; C=1 IF ADDRESS CHECK FAILED. ; N=0 IF FAILURE RETURNED ONLY BECAUSE THE BLOCK LIES ;MSH189 ; WITHIN A READ-ONLY REGION ;MSH189 ; N=1 IF FAILURE RETURNED FOR ANY OTHER REASON ;MSH189 ; C=0 IF ADDRESS CHECK SUCCEEDED. ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- $ACHCK::ASR R0 ;ODD ADDRESS? BCS 50$ ;IF CS YES ASL R0 ;REALIGN ADDRESS $ACHKB:: ;REFERENCE LABEL .IF NDF M$$MGE SAVNR ;SAVE R4 AND R5 .IFTF MOV $TKTCB,R2 ;GET TCB ADDRESS OF CURRENT TASK CLC ;ASSUME TASK IS PRIVILEGED BIT #T3.PRV,T.ST3(R2) ;PRIVILEGED TASK? BNE 50$ ;IF NE YES DEC R1 ;CALCULATE HIGHEST ADDRESS OF BLOCK ADD R0,R1 ; BCS 50$ ;IF CS ADDRESS WRAP AROUND .IFF MOV $HEADR,R2 ;GET ADDRESS OF CURRENT TASK HEADER MOV H.WND(R2),R2 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R2)+,-(SP) ;PUSH NUMBER OF WINDOW BLOCKS .IFT MOV $HEADR,R4 ;GET ADDRESS OF CURRENT TASK HEADER MOV H.WND(R4),R2 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R2)+,-(SP) ;PUSH NUMBER OF WINDOW BLOCKS MOV (R2),R5 ;SAVE PCB ADDRESS OF TASK PARTITION .IFTF 15$: TST (R2)+ ;IS NEXT WINDOW MAPPED? (W.BPCB) BEQ 20$ ;IF EQ NO CMP R0,(R2) ;COMPARE LOW LIMITS (W.BLVR) BLO 20$ ;IF LO NOT IN DESCRIPTOR CMP R1,2(R2) ;COMPARE HIGH LIMITS (W.BHVR) BLOS 25$ ;IF LOS BUFFER IS IN DESCRIPTOR 20$: ADD #W.BLGH-2,R2 ;POINT TO NEXT DESCRIPTOR DEC (SP) ;MORE DESCRIPTORS TO GO? BGT 15$ ;IF GT YES BR 30$ ;ELSE EXIT WITH CS 25$: ;REFERENCE LABEL .IFT CMP -(R2),R5 ;TASK PARTITION? BNE 40$ ;IF NE NO CMP R0,H.GARD(R4) ;HEADER VIOLATION? BHI 40$ ;IF HI NO .IFF BIT #4,W.BLPD-W.BLVR(R2) ;WRITE ACCESS PERMITTED? BNE 40$ ;IF NE YES COM (SP) ;READ-ONLY REGION, RETURN N=0 ;MSH189 .ENDC 30$: COM (SP)+ ;CLEAN STACK AND SET CARRY RETURN ; 40$: TST (SP)+ ;CLEAN STACK AND CLEAR CARRY 50$: RETURN ; .DSABL LSB .ENDC ;+ ;MSH049 ; **-$CEFNG-CONVERT EVENT FLAG AND LOCK GROUP GLOBALS FOR DIRECTIVE ;MSH049 ; **-$CEFIG-CONVERT EVENT FLAG AND LOCK GROUP GLOBALS FOR I/O ;MSH049 ; ;MSH049 ; THIS ROUTINE IS CALLED TO CONVERT AN EVENT FLAG NUMBER TO AN ;MSH049 ; EVENT FLAG MASK WORD AND EVENT FLAG MASK ADDRESS. IF THE EVENT ;MSH049 ; FLAG IS GROUP GLOBAL, POINT THE GROUP GLOBAL USE COUNT POINTER IN ;MSH049 ; SYSTEM COMMON TO THE FLAG WORD RETURNED IN R1. IF R1 IS ODD, R1 ;MSH049 ; IS POINTING TO THE SECOND GROUP OF GROUP GLOBAL EVENT FLAGS. ;MSH049 ; ;MSH049 ; INPUTS: ;MSH049 ; ;MSH049 ; R0=EVENT FLAG TO BE CONVERTED. ;MSH049 ; R3=ADDRESS CONTAINING EVENT FLAG NUMBER ($CEFNG ONLY) ;MSH049 ; R5=TCB ADDRESS OF THE TASK THE EFN APPLIES TO. ;MSH049 ; ;MSH049 ; OUTPUTS: ;MSH049 ; ;MSH049 ; C=1 IF NO EVENT FLAG NUMBER WAS SPECIFIED. ;MSH049 ; R0=ZERO. ;MSH049 ; R1=ZERO. ;MSH049 ; C=0 IF AN EVENT FLAG NUMBER WAS SPECIFIED. ;MSH049 ; R0=EVENT FLAG MASK WORD. ;MSH049 ; R1=EVENT FLAG MASK ADDRESS. ;MSH049 ; R1 IS EVEN IF THE EVENT FLAG NUMBER = 65.-80. ;MSH049 ; R1 IS ODD IF THE EVENT FLAG NUMBER = 81.-96. ;MSH049 ; ;MSH049 ; R3 IS PRESERVED ACROSS CALL IF ENTRY AT $CEFIG, ELSE R3 IS ;MSH049 ; ADVANCED BY 2. ;MSH049 ; ;MSH049 ;- ;MSH049 ;MSH049 .ENABLE LSB ;MSH049 ;MSH049 .IF DF G$$EFN ;MSH049 ;MSH049 $CEFIG::CALL $CEFI ;CONVERT THE EVENT FLAG ;MSH049 BR 5$ ;JOIN COMMON CODE ;MSH049 $CEFNG::CALL $CEFN ;CONVERT THE EVENT FLAG ;MSH049 5$: BCS 30$ ;IF CS RETURN ;MSH049 BNE 30$ ;IF NE RETURN ;MSH049 MOV R1,-(SP) ;SAVE GROUP GLOBAL MASK ADDRESS ;MSH049 ASSUME G.CNT+2,G.EFLG ;MUST BE CONTIGUOUS ;MSH049 ASR R1 ;GET SECOND MASK INDICATOR ;MSH049 SBC R1 ;IF SECOND MASK, SUBTRACT FOR IT ;MSH049 DEC R1 ;POINT TO GROUP GLOBAL USE COUNT ;MSH049 ASL R1 ;RESTORE TO WORD ADDRESS ;MSH049 MOV R1,@#$GEFPT ;LOAD GROUP GLOBAL USE COUNT POINTER ;MSH049 MOV (SP)+,R1 ;RESTORE EVENT FLAG MASK ADDRESS ;MSH049 ;MSH076 .IF DF R$$SND!A$$CLI ;MSH190 ;MSH076 MOV R5,$GFTCB ;DISPATCHER WILL MAINTAIN THE CORRECT ;MSH076 ADD #T.GGF,$GFTCB ; GRP GBL USE COUNT PER TASK W/THIS PNTR;MSH076 ;MSH076 .ENDC ;MSH076 ;MSH076 30$: RETURN ;MSH049 ;MSH049 .DSABL LSB ;MSH049 ;+ ; **-$CEFN-CONVERT EVENT FLAG NUMBER FOR DIRECTIVE ; **-$CEFI-CONVERT EVENT FLAG NUMBER FOR I/O ; ; THIS ROUTINE IS CALLED TO CONVERT AN EVENT FLAG NUMBER TO AN ; EVENT FLAG MASK WORD AND EVENT FLAG MASK ADDRESS. IF AN ILLEGAL ; EVENT FLAG IS SPECIFIED, THEN A DIRECTIVE STATUS OF 'D.RS97' IS ; RETURNED. ELSE THE EVENT FLAG NUMBER IS CONVERTED AND THE COM- ; PONENT PARTS ARE RETURNED TO THE CALLER. ; ; INPUTS: ; ; R0=EVENT FLAG NUMBER TO BE CONVERTED. ; R3=ADDRESS CONTAINING EVENT FLAG NUMBER ($CEFN ONLY) ;MSH049 ; R5=TCB ADDRESS OF THE TASK THE EFN APPLIES TO. ; ; OUTPUTS: ; ; C=1 IF NO EVENT FLAG NUMBER WAS SPECIFIED. ; R0=ZERO. ; R1=ZERO. ; C=0 IF AN EVENT FLAG NUMBER WAS SPECIFIED. ; R0=EVENT FLAG MASK WORD. ; R1=EVENT FLAG MASK ADDRESS. ; R1 IS EVEN IF THE EVENT FLAG < 81. ;MSH049 ; R1 IS ODD IF THE EVENT FLAG > 81. ;MSH049 ; Z=1 IF GROUP GLOBAL EVENT FLAG CONVERTED ;MSH049 ; Z=0 IF LOCAL OR COMMON EVENT FLAG CONVERTED ;MSH049 ; ; R3 IS PRESERVED ACROSS CALL IF ENTRY AT $CEFI, ELSE R3 IS ADVANCED BY 2. ;- .ENABL LSB ;MSH049 .IFF ;MSH049 ;MSH049 $CEFNG:: ;REF LABEL ;MSH049 ;MSH049 .IFTF  ;MSH049 ;MSH049 $CEFN:: MOVB (R3)+,R0 ;GET EVENT FLAG NUMBER INC R3 ;ADVANCE TO NEXT WORD ;MSH049 .IFF ;MSH049 ;MSH049 $CEFIG:: ;REF LABEL ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 $CEFI:: ;REF LABEL ;MSH049 ;MSH049 .IFT ;MSH049 ;MSH049 CLR -(SP) ;INIT GROUP GLOBAL INDICATOR ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 MOV R0,R1 ;COPY EFN ;MSH049 SEC ;ASSUME NONE SPECIFIED ;**-1 BEQ 30$ ;IF EQ NO EFN SPECIFIED DEC R0 ;BACK OFF EFN BY ONE MOV #32.,R2 ;SET EFN DIVIDER MOV R5,R1 ;POINT TO FIRST TASK MASK WORD ADD #T.EFLG,R1 ; CMP R0,R2 ;IN TASK EFN SET? BLO 10$ ;IF LO YES SUB R2,R0 ;NORMALIZE TO COMMON SET CMP R0,R2 ;LEGAL EFN? .IFT ;MSH049 ;**-1 BLO 5$ ;IF LO YES SUB R2,R0 ;NORMALIZE TO GROUP GLOBAL SET CMP R0,R2 ;LEGAL EFN? BHIS 40$ ;IF HIS NO ;MSH045 .IF DF D$$PAR ;MSH045 ;MSH045 MOV KISAR5,-(SP) ;SAVE OLD KERNEL APR 5 MAPPING ;MSH045 MOV $XCOM2,KISAR5 ;MAP THE SECOND EXECUTIVE COMMON ;MSH165 ;MSH045 .IFTF ;MSH045 ;MSH045 CALL $GTGEF ;GET ADDRESS OF GROUP GLOBAL EF'S ;MSH045 .IFT ;MSH045 ;MSH045 MOV (SP)+,KISAR5 ;RESTORE KISAR5 MAPPING ;MSH045 ;MSH045 .ENDC ;MSH045 ;MSH045 BCS 40$ ;IF CS NO SUCH FLAG OR TASK CHECKPOINTED;MSH049 DEC (SP) ;FLAG THAT FLAG WAS FOUND ;MSH049 BR 10$ ;USE GROUP GLOBAL SET 5$: ;REF LABEL .IFF ;MSH049 ;MSH049 BHIS 40$ ;IF HIS NO ;MSH049 .IFTF ;MSH049 ;MSH049 MOV #$COMEF,R1 ;POINT TO FIRST COMMON MASK WORD ;**-1 10$: ASR R2 ;HALVE DIVIDER CMP R0,R2 ;FIRST MASK WORD? BLO 20$ ;IF LO YES SUB R2,R0 ;NORMALIZE EFN TST (R1)+ ;POINT TO SECOND MASK WORD ;MSH049 .IFT ;MSH049 ;MSH049 TST (SP) ;GROUP GLOBAL FLAG FOUND? ;MSH049 BEQ 20$ ;IF EQ NO ;MSH049 INC R1 ;MARK AS SECOND GROUP GLOBAL WORD ;MSH049 ;MSH049 .IFTF ;MSH049 ;MSH049 20$: ASL R0 ;CONVERT EFN TO WORD INDEX MOV $BTMSK(R0),R0 ;GET PROPER MASK WORD 30$: ;REF LABEL ;MSH049 .IFT ;MSH049 ;MSH049 INC (SP)+ ;CLEAN STACK,PRESRV C-BIT,SET Z-BIT ;MSH049 ;MSH049 .ENDC ;MSH049 ;MSH049 35$: RETURN ;MSH049 40$: DRSTS D.RS97 ;SET DIRECTIVE STATUS ;**-1 ;+ ; **-$DVMSG-DEVICE MESSAGE OUTPUT ; ; THIS ROUTINE IS CALLED TO SUBMIT A MESSAGE TO THE TASK TERMINATION ; NOTIFICATION TASK. MESSAGES ARE EITHER DEVICE RELATED OR A CHECKPOINT ; WRITE FAILURE FROM THE LOADER. ; ; INPUTS: ; ; R4=ADDITIONAL PARAMETER ; R5=ADDRESS OF THE UCB OR TCB THAT THE MESSAGE APPLIES TO. ; ; OUTPUTS: ; ; A FOUR WORD PACKET IS ALLOCATED, R0 AND R5 ARE STORED IN THE ; SECOND AND THIRD WORDS RESPECTIVELY, AND THE PACKET IS THREADED ; INTO THE TASK TERMINATION NOTIFICATION TASK MESSAGE QUEUE. ; ; NOTE: IF THE TASK TERMINATION NOTIFICATION TASK IS NOT INSTALLED ; OR NO STORAGE CAN BE OBTAINED, THEN THE MESSAGE REQUEST ; IS IGNORED. ;- $DVMSG:: ;REF LABEL .IF DF T$$KMG MOV R0,R3 ;SAVE MESSAGE NUMBER TST $TKNPT ;TKTN INSTALLED? BEQ 35$ ;IF EQ NO ;MSH049 MOV #8.,R1 ;SET LENGTH OF BLOCK NEEDED ;**-1 CALL $ALOCB ;GET A CORE BLOCK BCS 35$ ;IF CS DIDN'T GET ONE ;MSH049 MOV R0,R1 ;SET ADDRESS OF MESSAGE BLOCK ;**-1 TST (R0)+ ;POINT TO SECOND WORD IN BLOCK MOV R3,(R0)+ ;INSERT MESSAGE NUMBER MOV R5,(R0)+ ;INSERT UCB OR TCB ADDRESS ;MSH049 MOV R4,(R0) ;INSERT ADDITIONAL PARAMETER ;**-2 MOV $TKNPT,R0 ;PICK UP TKTN TCB ADDRESS CALLR $EXRQF ;REQUEST TKTN AND QUEUE MESSAGE .IFF RETURN ; .ENDC .DSABL LSB ;+ ; **-$MPLNE-MAP LOGICAL UNIT NUMBER FOR EXIT ; **-$MPLUN-MAP LOGICAL UNIT NUMBER ; ; THIS ROUTINE IS CALLED TO VALIDATE A LOGICAL UNIT NUMBER (LUN) AND TO MAP ; THE LUN INTO A UCB POINTER. IF AN ILLEGAL LUN IS SPECIFIED, THEN A ; DIRECTIVE STATUS OF 'D.RS96' IS RETURNED. ELSE THE LUN IS MAPPED AND A ; POINTER TO THE LUN AND UCB ARE RETURNED TO THE CALLER. ; ; INPUTS: ; ; R3=ADDRESS OF THE LUN. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: ; ; C=1 IF NO DEVICE IS ASSIGNED TO THE SPECIFIED LUN. ; R0=0. ; C=0 IF A DEVICE IS ASSIGNED TO THE SPECIFIED LUN. ; R0=ADDRESS OF THE UCB OF THE ASSIGNED DEVICE. ; ; IN EITHER CASE R1 IS RETURNED AS THE ADDRESS OF THE SECOND LUN ; WORD IN THE TASK HEADER AND R3 IS ADVANCED BY 2. ;- .ENABL LSB $MPLUN::CLR R1 ;GET LOGICAL UNIT NUMBER BISB (R3)+,R1 ; INC R3 ;POINT TO NEXT WORD DEC R1 ;BACK OFF LUN BY 1 CMP R1,H.NLUN(R4) ;LEGAL LUN? BHIS 40$ ;IF HIS NO $MPLNE::ASL R1 ;MULTIPLY LUN-1 BY 4 ASL R1 ; ADD R4,R1 ;CALCULATE ADDRESS OF FIRST LUN WORD ADD #H.NLUN+2,R1 ;IN TASK HEADER SEC ;ASSUME LUN NOT ASSIGNED MOV (R1)+,R0 ;GET POINTER TO DEVICE UCB BEQ 30$ ;IF EQ NO DEVICE ASSIGNED $MPLND::CMP R0,U.RED(R0) ;IS DEVICE REDIRECTED? BEQ 10$ ;IF EQ NO MOV U.RED(R0),R0 ;GET POINTER TO REDIRECT UCB BR $MPLND ;TRY AGAIN 10$: MOV (R0),R2 ;GET ADDRESS OF DEVICE DCB CMP #"TI,D.NAM(R2) ;TERMINAL INPUT PSEUDO DEVICE? BNE 20$ ;IF NE NO MOV T.UCB(R5),R0 ;GET ADDRESS OF "TI" UCB BR $MPLND ; 20$: CLC ;INDICATE DEVICE ASSIGNED 30$: RETURN ; 40$: DRSTS D.RS96 ;SET DIRECTIVE STATUS .DSABL LSB ;+ ; **-$MUL-INTEGER MULTIPLY MAGNITUDE NUMBERS ; ; INPUTS: ; ; R0=MULTIPLIER. ; R1=MULTIPLICAND. ; ; OUTPUTS: ; ; DOUBLE WORD RESULT IS RETURNED WITH THE ; HIGH PART IN R0 AND THE LOW PART IN R1. ; ; REGISTERS R2, R3, R4, AND R5 ARE PRESERVED ACROSS CALL. ;- .ENABL LSB $MUL:: ;INTEGER MULTIPLY ; PB194 ; PB194 ; PB194 .IF DF M$$EIS ; PB194 ; PB194 MUL R1,R0 ;DO THE MULTIPLY ; PB194 RETURN ; ; PB194 ; PB194 .IFF ; PB194 ; PB194 MOV R0,-(SP) ;SAVE MULTIPLIER FOR ADDS ; PB194 MOV #21,-(SP) ;SET REPEAT COUNT ;**-1 CLR R0 ;CLEAR HIGH PART 10$: ROR R0 ;DOUBLE RIGHT SHIFT ROR R1 ; BCC 20$ ;IF CC DO NOT ADD ADD 2(SP),R0 ; 20$: DEC (SP) ;DECREMENT REPEAT COUNT BGT 10$ ;IF GT MORE TO GO BR 50$ ;EXIT TO CALLER .ENDC ; PB194 ; PB194 ;+ ; **-$DIV-INTEGER DIVIDE MAGNITUDE NUMBERS ; ; INPUTS: ; ; R0=DIVIDEND. ; R1=DIVISOR. ; ; OUTPUTS: ; ; QUOTIENT IS RETURNED IN R0 AND REMAINDER IN R1. ; ; REGISTERS R2, R3, R4, AND R5 ARE PRESERVED ACROSS CALL. ;- $DIV::  ;INTEGER DIVIDE ; PB194 ; PB194 ; PB194 .IF DF M$$EIS ; PB194 ; PB194 MOV R2,-(SP) ;SAVE WORKING REGISTER ; PB194 MOV R1,R2 ;COPY DIVISOR ; PB194 MOV R0,R1 ;MOVE DIVIDEND ; PB194 CLR R0 ;ZERO QUOTENT ; PB194 DIV R2,R0 ;DIVIDE ; PB194 MOV (SP)+,R2 ;RESTORE WORKING REGISTER ; PB194 RETURN ; ; PB194 ; PB194 .IFF ; PB194 ; PB194 MOV #20,-(SP) ;SET LOOP COUNT ; PB194 MOV R1,-(SP) ;SAVE DIVISOR FO°R SUBTRACTS ;**-1 CLR R1 ;CLEAR REMAINDER 30$: ASL R0 ;DOUBLE LEFT SHIFT ROL R1 ; CMP R1,(SP) ;SUBTRACT OUT DIVISOR? BLO 40$ ;IF LO NO SUB (SP),R1 ;SUBTRACT OUT DIVISOR INC R0 ;ADD IN LOW BIT 40$: DEC 2(SP) ;DECREMENT REPEAT COUNT BGT 30$ ;IF GT MORE TO GO 50$: CMP (SP)+,(SP)+ ;CLEAN STACK RETURN ; ; PB194 .ENDC ; PB194 ; PB194 ; PB194 .DSABL LSB .END °RÀkQ ›c, .TITLE MEMAP .IDENT /01.09/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.09 ; ; M. S. HARVEY 21-AUG-80 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; M. S. HARVEY 19-JUN-79 ; MSH037 -- DON'T ALLOCATE EXTRA UMR FOR N*4096 BUFFERS. ; ALSO, CLEAN UP CODE A BIT. ; ; M. S. HARVEY 21-AUG-80 ; MSH112 -- CREATE THIS SOURCE MODULE FROM IOSUB. ; ALL CORRECTIONS LISTED ABOVE CAME FROM IOSUB. ; ; P. J. BEZEREDI 13-NOV-80 ; PB194 -- USE EIS INSTRUCTION SET WHERE APPLICABLE. ; ; R. T. PERRON 21-NOV-80 ; RP041 -- CHANGE INTERFACE TO $RELOP ROUTINE. ; REQUIRED BY CHANGE TO $ECCOR ROUTINE. ; ; D. R. DONCHIN 09-JUN-81 ; DD098 -- ADD ANCILLARY CONTROL DRIVER SUPPORT. ; ; R. T. PERRON 24-AUG-81 ; RP071 -- CLARIFY COMMENTS CONCERNING EXTENDED MEMORY SUPPORT ; ; R. T. PERRON 16-OCT-81 ; ; RP075 -- CORRECT NON-EIS ADDRESS CALCULATION IN $RELOP ; ; MEMORY MAPPING ROUTINES ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS ;+ ; **-$MPPHY-MAP TO PHYSICAL ADDRESS ; ; THIS ROUTINE IS CALLED TO MAP A RELOCATION BIAS AND DISPLACEMENT ADDRESS TO AN ; 18 BIT PHYSICAL ADDRESS. IF THE INDICATED DEVICE IS NOT AN NPR AN DEVICE, ; THEN THE RELOCATION BIAS AND DISPLACEMENT ADDRESS ARE RETURNED TO THE CALLER. ; ELSE THE RELOCATION BIAS AND DISPLACEMENT ADDRESS ARE CONVERTED TO AN 18 BIT ; PHYSICAL ADDRESS WHICH IS RETURNED TO THE CALLER. ; ; INPUTS: ; ; R1=RELOCATION BIAS. ; R2=DISPLACEMENT ADDRESS. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; IF DEVICE IS AN NPR DEVICE ON AN 18-BIT MACHINE, THEN ; R1=HIGH ORDER 2 BITS OF PHYSICAL ADDRESS IN BITS 4 AND 5. ; R2=LOW ORDER 16 BITS OF PHYSICAL ADDRESS. ; IF DEVICE IS AN NPR DEVICE ON AN 11/70, THEN ; R1=HIGH ORDER 6 BITS OF PHYSICAL ADDRESS IN HIGH BYTE. ; R2=LOW ORDER 16 BITS OF PHYSICAL ADDRESS. ; IF DEVICE IS NOT AN NPR DEVICE, THEN ; R1=RELOCATION BIAS. ; R2=DISPLACEMENT ADDRESS. ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- .IF DF M$$MGE $MPPHY::BITB #UC.NPR,U.CTL(R5) ;NPR DEVICE? BEQ 10$ ;IF EQ NO ASL R2 ;REMOVE APR6 BIAS FROM DISPLACEMENT ASL R2 ; CLC ;GET 2 BITS OF RELOCATION BIAS ROR R1 ; RORB R2 ;TO FILL 8 LOW ORDER BITS OF ADDRESS ASR R1 ; RORB R2 ; SWAB R2 ;SWAP TO COLLECT 8 MORE BITS BISB R1,R2 ;INSERT UPPER 8 BITS OF ADDRESS  SWAB R2 ;SWAP BACK TO REAL ADDRESS CLRB R1 ;CLEAR LOW BYTE OF UPPER BITS .IF NDF M$$EXT ; PB194 .IF DF M$$EIS ; PB194 ; PB194 ASH #-4,R1 ;POSITION ADDRESS BITS ; PB194 ; PB194 .IFF ; PB194 ; PB194 ASR R1 ;SHIFT BITS 17 AND 18 OF ADDRESS ASR R1 ;INTO BITS 4 AND 5 ASR R1 ; ASR R1 ; ; PB194 .ENDC ; PB194 .ENDC 10$: RETURN ; .ENDC ;+ ; **-$MPUB1-MAP UNIBUS TO MEMORY (ALTERNATE ENTRY) ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO LOAD THE ; RP071 ; NECESSARY UNIBUS MAP REGISTERS TO EFFECT A TRANSFER TO MAIN ; RP071 ; MEMORY ON PDP-11 PROCESSORS WITH EXTENDED MEMORY. THIS ALTERNATE ; RP071 ; ENTRY POINT ALLOWS THE DRIVER TO SPECIFY A NON-STANDARD UMR MAPPING ; RP071 ; ASSIGNMENT BLOCK. ; RP071 ; ;**-5 ; INPUTS: ; ; R0=ADDRESS OF A UMR MAPPING ASSIGNMENT BLOCK ; R4=ADDRESS OF DEVICE SCB ;MSH037 ; R5=ADDRESS OF DEVICE UCB ;MSH037 ; ; OUTPUTS: ; ; THE UNIBUS MAP REGISTERS NECESSARY TO EFFECT THE ; TRANSFER ARE LOADED ; ; NOTE: REGISTER R3 IS PRESERVED ACROSS CALL. ;- .IF DF M$$EXT&M$$MGE $MPUB1::MOV M.UMRN(R0),-(SP) ;SET COUNT OF REGISTERS TO LOAD MOVB M.BFVH(R0),R1 ;GET HIGH 6 BITS OF ADDRESS MOV M.BFVL(R0),R2 ;GET LOW 16 BITS OF ADDRESS MOV M.UMRA(R0),R0 ;GET ADDRESS OF FIRST MAP REGISTER BR MPUB2 ;GO LOAD THE UMRS ;MSH037 ;**-4 ;+ ; **-$MPUBM-MAP UNIBUS TO MEMORY ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO LOAD THE ; RP071 ; NECESSARY UNIBUS MAP REGISTERS TO EFFECT A TRANSFER TO MAIN MEM- ; RP071 ; ORY ON PDP-11 PROCESSORS WITH EXTENDED MEMORY. ; RP071 ; ;**-3 ; INPUTS: ; ; R4=ADDRESS OF DEVICE SCB. ; R5=ADDRESS OF DEVICE UCB. ; ; OUTPUTS: ; ; THE UNIBUS MAP REGISTERS NECESSARY TO EFFECT THE TRANSFER ; ARE LOADED. ; ; NOTE: REGISTER R3 IS PRESERVED ACROSS CALL. ;- ;**-2 $MPUBM::MOV S.MPR+M.UMRA(R4),R0 ;GET ADDRESS OF FIRST MAP REGISTER MOV S.MPR+M.UMRN(R4),-(SP) ;SET COUNT OF REGISTERS TO LOAD MOVB S.MPR+M.BFVH(R4),R1 ;GET HIGH 6 BITS OF ADDRESS MOV S.MPR+M.BFVL(R4),R2 ;GET LOW 16 BITS OF ADDRESS MPUB2: MOV R2,(R0)+ ;LOAD LOW 16 BITS OF ADDRESS ;MSH037 MOV R1,(R0)+ ;LOAD HIGH 6 BITS OF ADDRESS ;**-1 ADD #20000,R2 ;ADVANCE 8K BYTES ADC R1 ; SUB #4,(SP) ;ALL REGISTERS LOADED? BGT MPUB2 ;IF GT NO ;MSH037 TST (SP)+ ;CLEAN STACK ;**-1 RETURN .ENDC ;+ ; **-$RELOC-RELOCATE USER VIRTUAL ADDRESS ; ; THIS ROUTINE IS CALLED TO TRANSFORM A 16 BIT USER VIRTUAL ADDRESS ; INTO A RELOCATION BIAS AND DISPLACEMENT IN BLOCK RELATIVE TO APR6. ; ; INPUTS: ; ; R0=USER VIRTUAL ADDRESS TO RELOCATE. ; ; OUTPUTS: ; ; R1=RELOCATION BIAS TO BE LOADED INTO PAR6. ; R2=DISPLACEMENT IN BLOCK PLUS 140000 (PAR6 BIAS). ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- $RELOC:: ;REF LABEL .IF NDF M$$MGE MOV R0,R2 ;COPY PHYSICAL ADDRESS CLR R1 ;CLEAR RELOCATION BIAS .IFF MOV R0,R1 ;COPY VIRTUAL ADDRESS  ; PB194 .IF DF M$$EIS ; PB194 ; PB194 ASH #-6,R1 ;CALCULATE BLOCK NUMBER ; PB194 BIC #177600,R1 ;ISOLATE IT ; PB194 MOV R0,R2 ;COPY VIRTUAL ADDRESS ; PB194 ASH #-12.,R2 ;CALCULATE APR INDEX ; PB194 BIC #177761,R2 ;ISOLATE IT ; PB194 ; PB194 .IFF ; PB194 ; PB194 CLR R2 ;ZERO APR NUMBER ACCUMULATOR ASL R1 ;COLLECT APR NUMBER ROL R2 ; ASL R1 ; ROL R2 ; ASL R1 ; ROL R2 ; ASL R2 ;CONVERT TO APR INDEX CLRB R1 ;CLEAR EXTRANEOUS BITS SWAB R1 ;COLLECT BLOCK NUMBER IN LOW BYTE ROR R1 ; ; PB194 .ENDC ; PB194 ; PB194 ; PB194 ADD UISAR0(R2),R1 ;CALCULATE RELOCATION BIAS MOV R0,R2 ;COPY VIRTUAL ADDRESS BIC #177700,R2 ;CLEAR ALL BUT DISPLACEMENT IN BLOCK BIS #140000,R2 ;SET APR 6 BIAS .ENDC RETURN ; ;+ ; **-$RELOM-RELOCATE AND MAP ADDRESS ; ; THIS ROUTINE IS CALLED TO TRANSFORM A 16 BIT USER VIRTUAL ADDRESS ; INTO A RELOCATION BIAS AND DISPLACEMENT IN BLOCK RELATIVE TO APR6 ; AND LOAD THESE VALUES FOR ACCESS BY THE CALLER. ; ; INPUTS: ; ; R0=USER VIRTUAL ADDRESS TO RELOCATE. ; ; OUTPUTS: ; ; R0=DISPLACEMENT IN BLOCK. ; KISAR6 IS LOADED WITH THE RELOCATION BIAS. ; ; R3 IS PRESERVED ACROSS CALL. ;- .IF DF M$$MGE $RELOM::CALL $RELOC ;RELOCATE USER VIRTUAL ADDRESS MOV R1,KISAR6 ;SET KERNEL MAPPING REGISTER MOV R2,R0 ;SET DISPLACEMENT IN BLOCK ADDRESS RETURN ; .ENDC ;+ ; **-$ASUMR-ASSIGN UNIBUS MAPPING REGISTERS ; ; THIS ROUTINE IS CALLED TO ASSIGN A CONTIGUOUS SET OF UMR'S. NOTE THAT ; FOR THE SAKE OF SPEED, THE LINK WORD OF EACH MAPPING ASSIGNMENT BLOCK ; POINTS TO THE UMR ADDRESS (2ND) WORD OF THE BLOCK, NOT THE FIRST WORD. ; THE CURRENT STATE OF UMR ASSIGNMENT IS REPRESENTED BY A LINKED LIST OF ; MAPPING ASSIGNMENT BLOCKS, EACH BLOCK CONTAINING THE ADDRESS OF THE ; FIRST UMR ASSIGNED AND THE NUMBER OF UMR'S ASSIGNED TIMES 4. THE ; BLOCKS ARE LINKED IN THE ORDER OF INCREASING FIRST UMR ADDRESS. ; ; INPUTS: ; ; R0=POINTER TO A MAPPING REGISTER ASSIGNMENT BLOCK. ; M.UMRN(R0)=NUMBER OF UMR'S REQUIRED * 4. ; ; OUTPUTS: ; ; ALL REGISTERS ARE PRESERVED. ; ; C=0 IF THE UMR'S WERE SUCCESSFULLY ASSIGNED. ; ALL FIELDS OF THE MAPPING REGISTER ASSIGNMENT BLOCK ; ARE INITIALIZED AND THE BLOCK IS LINKED INTO ; THE ASSIGNMENT LIST. ; C=1 IF THE UMR'S COULD NOT BE ASSIGNED. ;- .IF DF M$$EXT $ASUMR::SAVNR ;SAVE R4 AND R5 TST (R0)+ ;SKIP OVER LINK WORD (M.LNK) MOV #$UMRHD+2,R5 ;POINT TO UMR ASSIGNMENT LISTHEAD + 2 10$: MOV R5,R4 ;SAVE POINTER TO PREVIOUS BEQ 30$ ;IF EQ ASSIGNMENT FAILURE MOV (R5),(R0) ;POINT TO NEXT FREE UMR (M.UMRA)(M.UMRA) ADD M.UMRN-M.UMRA(R5),(R0) ;(M.UMRA) MOV #UBMPR+<31.*4>,-(SP) ;PUSH POINTER PAST LAST UMR MOV -(R5),R5 ;POINT TO NEXT ASSIGNMENT BLOCK (M.LNK) BEQ 20$ ;IF EQ THERE IS NONE MOV (R5),(SP) ;SET NEXT ALLOCATED UMR ADDRESS (M.UMRA) 20$: SUB (R0),(SP) ;CALCULATE # OF FREE UMR'S * 4 (M.UMRA) CMP (SP)+,M.UMRN-M.UMRA(R0) ;ENOUGH UMR'S AVAILABLE? BLO 10$ ;IF LO NO MOV R0,-(R4) ;LINK NEW BLOCK TO PREVIOUS (M.LNK) MOV (R0),R4 ;SAVE FIRST UMR ADDRESS (M.UMRA) MOV R5,-2(R0) ;POINT NEW BLOCK TO NEXT IN LIST (M.LNK) MOV R4,R5 ;DUPLICATE FIRST UMR ADDRESS BICB #UBMPR!34,R5 ;MASK OUT ALL BUT HI 2 BITS IN LOW BYTE BIC R5,R4 ;CLEAR OUT HIGH BYTE AND HIGH 2 BITS ASR R5 ;SHIFT HIGH 2 BITS TO BITS 4 & 5 ASLB R4 ;CALCULATE HIGH BYTE OF LOW 16 BITS ASL R4 ; (LOSING BIT 200 FIRST) ASL R4 ; SWAB R4 ;FORM LOW SIXTEEN BITS OF ADDRESS MOV M.BFVL-2(R0),M.UMVL-2(R0) ; GET ORIGINAL BUFFER ADDRESS BIC #^C<1>,M.UMVL-2(R0) ; WAS IT ODD ? ADD R4,M.UMVL-2(R0) ; IF IT WAS, THEN M.UMVL SHOULD BE MOVB R5,M.UMVH-2(R0) ;SET BITS 4 & 5 30$: DEC R0 ;PNT BACK TO LINK WORD PRESERVING CARRY DEC R0 ; RETURN ; ;+ ; **-$DEUMR-DEASSIGN UNIBUS MAPPING REGISTERS ; ; THIS ROUTINE IS CALLED TO DEASSIGN A CONTIGUOUS BLOCK OF UMR'S. IF ; THE MAPPING ASSIGNMENT BLOCK IS NOT IN THE LIST, NO ACTION IS TAKEN. ; NOTE THAT FOR THE SAKE OF ASSIGNMENT SPEED, THE LINK WORD POINTS TO ; THE UMR ADDRESS (2ND) WORD OF THE ASSIGNMENT BLOCK. ; ; INPUTS: ; ; R2=POINTER TO ASSIGNMENT BLOCK. ; ; OUTPUTS: ; ; R0 AND R1 ARE PRESERVED. ;- $DEUMR::TST (R2)+ ;SKIP OVER LINK WORD (M.LNK) MOV #$UMRHD+2,R3 ;POINT TO ASSIGNMENT LISTHEAD + 2 10$: CMP -(R3),R2 ;IS IT THE NEXT ONE? (M.LNK) BEQ 20$ ;IF EQ YES MOV (R3),R3 ;ELSE POINT TO NEXT IN LIST (M.LNK) BNE 10$ ;IF NE THERE IS ONE BR 30$ ;ELSE MAPPING ASSIGNMENT BLK NOT IN LIST 20$: MOV -(R2),(R3) ;UNLINK THE BLOCK (M.LNK)(M.LNK) 30$: RETURN ; ;+ ; **-$STMP1-SET UP UNIBUS MAPPING ADDRESS (ALTERNATE ENTRY) ; ; THIS ENTRY CODE SETS UP AN ALTERNATE DATA STRUCTURE USED AS ; A UMR MAPPING ASSIGNMENT BLOCK AND CONTEXT STORAGE BLOCK, IN ; THE SAME MANNER AS $STMAP USES THE FORK BLOCK AND MAPPING ; BLOCK IN THE SCB. THE FORMAT OF THE STRUCTURE IS AS FOLLOWS: ; ; --------------------- ; ! ! 4 WORDS USED FOR SAVING ; ! ! DRIVER'S CONTEXT IN CASE ; ! ! UMR'S CAN'T BE MAPPED ; ! ! IMMEDIATELY. ; --------------------- ; ! ! ; ! ! 6 WORDS USED AS A UMR ; ! ! MAPPING ASSIGNMENT BLOCK. ; ! ! ; ! ! ; ! ! ; --------------------- ; ; ; INPUTS: ; ; R0=ADDRESS OF THE DATA STRUCTURE DEPICTED ABOVE ; R4=ADDRESS OF DEVICE SCB ; R5=ADDRESS OF DEVICE UCB ; ; OUTPUTS: ; ; DATA STRUCTURE POINTERS SET UP FOR ENTRY TO $STMP2 IN $STMAP ; ;- $STMP1::MOV S.FRK+10(R4),6(R0) ;SAVE DRIVER'S MAPPING MOV R0,R4 ;COPY BLOCK POINTER ADD #M.LGTH+10,R0 ;POINT PAST MAPPING BLOCK CMP (R4)+,(R4)+ ;POINT TO CONTEXT SAVE BLOCK ;MSH037 BR STMP2 ;SET UP THE UMR ADDRESS ;MSH037 ;**-2 ;+ ; **-$STMAP-SET UP UNIBUS MAPPING ADDRESS ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO SET UP THE ; UNIBUS MAPPING ADDRESS, FIRST ASSIGNING THE UMR'S. IF THE UMR'S ; CANNOT BE ALLOCATED, THE DRIVER'S MAPPING ASSIGNMENT BLOCK IS PLACED ; IN A WAIT QUEUE AND A RETURN TO THE DRIVER'S CALLER IS EXECUTED. THE ; ASSIGNMENT BLOCK WILL EVENTUALLY BE DEQUEUED WHEN THE UMR'S ARE ; AVAILABLE AND THE DRIVER WILL BE REMAPPED AND RETURNED TO WITH R1-R5 ; PRESERVED AND THE NORMAL OUTPUTS OF THIS ROUTINE. THE DRIVER'S ; CONTEXT IS STORED IN THE ASSIGNMENT BLOCK AND FORK BLOCK WHILE IT IS ; BLOCKED AND IN THE WAIT QUEUE. ONCE A DRIVER'S MAPPING ASSIGNMENT ; BLOCK IS PLACED IN THE UMR WAIT QUEUE, IT IS NOT REMOVED FROM THE ; QUEUE UNTIL THE UMR'S ARE SUCCESSFULLY ASSIGNED. THIS STRATEGY ; ASSURES THAT WAITING DRIVERS WILL BE SERVICED FIFO AND THAT DRIVER'S ; WITH LARGE REQUESTS FOR UMR'S WILL NOT WAIT INDEFINATELY. ; ; INPUTS: ; ; R4=ADDRESS OF DEVICE SCB. ; R5=ADDRESS OF DEVICE UCB. ; (SP)=RETURN TO DRIVER'S CALLER. ; ; OUTPUTS: ; ; UNIBUS MAP ADDRESSES ARE SET UP IN THE DEVICE UCB AND THE ; ACTUAL PHYSICAL ADDRESS IS MOVED TO THE SCB. ; ; NOTE: REGISTERS R1, R2, AND R3 ARE PRESERVED ACROSS CALL. ;- $STMAP::MOV R4,R0 ;COPY SCB POINTER ADD #S.MPR+M.LGTH,R0 ;POINT PAST MAPPING ASSIGNMENT BLOCK  ADD #S.FRK+6,R4 ;POINT INTO FORK BLOCK STMP2: MOV U.BUF+2(R5),-(R0) ;SAVE LOW 16 BITS OF ADDRESS (M.BFVL) ;MSH037 MOVB U.BUF+1(R5),-(R0) ;SAVE HIGH 6 BITS OF ADDRESS (M.BFVH) ;**-1 DEC R0 ;POINT BACK TO NEXT WORD MOV U.CNT(R5),-(R0) ;TEMORARILY STORE BYTE COUNT (M.UMVL) CLR -(R0) ;INITIALIZE UMR COUNT (M.UMRN) BIT #1,M.BFVL-M.UMRN(R0) ; BUFFER ADDRESS ODD ? BEQ 10$ ; IF EQ NO, ALL IS NORMAL INC 2(R0) ; IT'S ODD, WE MUST MAP ONE EXTRA BYTE 10$: ADD #4,(R0) ;INCREASE COUNT FOR ONE UMR (M.UMRN) SUB #20000,2(R0) ;REDUCE BYTE COUNT BY 8K BYTES (M.UMVL) BHI 10$ ;IF HI MORE BYTES TO GO ;MSH037 TST -(R0) ;(M.UMRA) ;**-1 MOV -(R0),-(SP) ;SAVE POSSIBLE WAIT QUEUE LINK (M.LNK) CALL $ASUMR ;ATTEMPT TO ASSIGN REQUIRED UMR'S BCC 20$ ;IF CC SUCCESSFUL, CHECK FOR UMR WAIT TST (SP)+ ;CLEAR STACK MOV R5,(R4) ;SAVE R5 IN FORK BLOCK (S.FRK+6) MOV (SP)+,-(R4) ;SAVE DRIVER'S RETURN ADDRESS (S.FRK+4) MOV R0,-(R4) ;SAVE MAPPING BLOCK POINTER (S.FRK+2) CALL $WTUMR ;WAIT FOR CHANGE IN UMR ASSIGNMENT MOV (R4)+,R0 ;RESTORE MAPPING BLOCK POINTER (S.FRK+2) ADD #M.LGTH,R0 ;POINT PAST MAPPING BLOCK MOV (R4)+,-(SP) ;RESTORE DRIVER'S RETURN ADDR (S.FRK+4) MOV (R4),R5 ;RESTORE R5 (S.FRK+6) MOV 2(R4),KISAR5 ;REMAP DRIVER (S.FRK+10) BR STMP2 ;TRY AGAIN ;MSH037 20$: MOV U.SCB(R5),R4 ;RESTORE R4 ;**-1 MOV M.UMVL(R0),U.BUF+2(R5) ;STORE LOW WORD OF UMR VIRT ADDR MOVB M.UMVH(R0),U.BUF(R5) ;STORE HIGH SIX BITS CLRB U.BUF+1(R5) ;CLEAR HIGH-ORDER BYTE CMP $UMRWT,R0 ;WAS THIS CALLER WAITING? BNE 30$ ;IF NE NO MOV (SP),$UMRWT ;DEQUEUE CURRENT CALLER'S BLOCK BNE 30$ ;IF NE NOT END OF LIST MOV #$UMRWT,$UMRWT+2 ;UPDATE LAST IN LIST POINTER 30$: TST (SP)+ ;CLEAR STACK ;+ ; **-$DQUMR-DEQUEUE FROM UMR WAIT ; ; CONTROL IS TRANSFERRED HERE TO SEE IF A DRIVER IS WAITING FOR UMR ; ASSIGNMENT. FIRST THE CALLING DRIVER IS CALLED BACK AS A COROUTINE. ; WHEN THE CALLING DRIVER ISSUES A RETURN BACK TO THIS ROUTINE, A CHECK ; IS MADE TO SEE IF ANY DRIVERS ARE WAITING FOR UMR'S. IF SO THE WAIT- ; ING DRIVER'S CONTEXT IS RESTORED WITHOUT ACTUALLY DEQUEUEING THE ; MAPPING ASSIGNMENT BLOCK AND CONTROL IS PASSED BACK TO THE ORIGINAL ; UMR ASSIGNMENT ROUTINE. ; ; INPUTS: ; ; (SP)=RETURN ADDRESS TO DRIVER'S CALLER.. ; ; OUTPUTS: ; ; IF ANYONE IS WAITING THEIR CONTEXT IS RESTORED AND THE ALLOCA- ; TION ROUTINE IS CALLED BACK. ;- .ENABL LSB $DQUMR::CALL @(SP)+ ;CALL THE CALLER AS COROUTINE MOV $UMRWT,R0 ;ANYONE WAITING FOR UMR ASSIGNMENT? BEQ 10$ ;IF EQ HE HAS SINCE GONE AWAY TST (R0)+ ;POINT TO SAVED R1 MOV (R0)+,R1 ;RESTORE SAVED REGISTERS MOV (R0)+,R2 ; MOV (R0)+,R3 ; MOV (R0)+,R4 ; JMP @(R0)+ ;JUMP BACK TO ALLOCATION ROUTINE ;+ ; **-$WTUMR-WAIT FOR CHANGE IN UMR STATE ; ; THIS ROUTINE STORES R1-R4 AND THE RETURN PC IN THE MAPPING ASSIGNMENT ; AND QUEUES THE BLOCK IN THE UMR WAIT QUEUE FOR A SUBSEQUENT RECALL TO ; THE CALLER WHEN THE STATE OF UMR ASSIGNMENT CHANGES. NOTE THAT IT IS ; POSSIBLE FOR THE MAPPING ASSIGNMENT BLOCK TO ALREADY BE IN THE WAIT ; QUEUE, BUT IF IT IS IT CAN ONLY BE AT THE HEAD OF THE QUEUE. ; ; INPUTS: ; ; R0=POINTER TO UMR ASSIGNMENT BLOCK ; ; OUTPUTS: ; ; THE ASSIGNMENT BLOCK IS QUEUED IN THE UMR WAIT QUEUE. ; THE CALLER IS EVENTUALLY RETURNED TO AT SYSTEM STATE WITH R1-R4 ; PRESERVED. ;- $WTUMR::MOV (SP)+,12(R0) ;STORE RETURN ADDR TO ALLOCATE ROUTINE CMP R0,$UMRWT ;MAPPING ASSIGNMENT BLK ALREADY IN LIST? BEQ 5$ ;IF EQ YES MOV R0,@$UMRWT+2 ;LINK BLOCK TO LAST IN QUEUE MOV R0,$UMRWT+2 ;UPDATE LAST IN LIST POINTER CLR (R0) ;ZERO LINK WORD 5$: TST (R0)+ ;POINT PAST LINK WORD MOV R1,(R0)+ ;SAVE CALLER'S REGISTERS MOV R2,(R0)+ ; MOV R3,(R0)+ ; MOV R4,(R0)+ ; 10$: RETURN ;RETURN TO CALLER'S CALLER .DSABL LSB .ENDC ;+ ; **-$RELOP-RELOCATE UNIBUS PHYSICAL ADDRESS ; ; THIS ROUTINE RELOCATES A UNIBUS PHYSICAL ADDRESS TO A KISAR6 ; BIAS AND DISPLACEMENT. ; ; INPUTS: ; ; R0=BYTE OFFSET FROM ADDRESS IN U.BUF+1 AND U.BUF+2 ; RP041 ; R4=SCB ADDRESS ; RP041 ; R5=UCB ADDRESS ; RP041 ; ; RP041 ; IF DEVICE IS AN NPR DEVICE ON AN 18-BIT MACHINE, THEN ; RP041 ; U.BUF+1(R5)=HIGH ORDER BITS OF PHYSICAL ADDRESS ; RP041 ; U.BUF+2(R5)=LOW ORDER BITS OF PHYSICAL ADDRESS ; RP041 ; IF DEVICE IS AN NPR DEVICE ON A 22-BIT MACHINE, THEN ; RP041 ; M.BFVL+S.MPR(R4)=LOW ORDER BITS OF PHYSICAL BUFFER ADDRE; RP041 ; M.BFVH+S.MPR(R4)=HIGH ORDER BITS OF PHYSICAL BUFFER ADDR; RP041 ; IF DEVICE IS AN NPR DEVICE ON A 22-BIT MACHINE AND CAN DIRECTLY ; RP041 ; ADDRESS MAIN MEMORY, THEN ; RP041 ; U.BUF+1(R5)=HIGH ORDER BITS OF PHYSICAL ADDRESS ; RP041 ; U.BUF+2(R5)=LOW ORDER BITS OF PHYSICAL ADDRESS ; RP041 ; ;**-4 ; OUTPUTS: ; ; KISAR6=CALCULATED BIAS (MAPPED SYSTEM) ; R1=REAL ADDRESS OR DISPLACEMENT ;- .IF DF D$$IAG!S$$ECC $RELOP:: ; MOV R0,-(SP) ;SAVE BYTE OFFSET ON STACK ; RP041 MOV U.BUF+2(R5),R1 ;GET LOW 16 BITS OF ADDRESS ; RP041 .IF DF M$$MGE MOVB U.BUF+1(R5),R0 ;GET HIGH BITS OF REAL ADDRESS ; RP041 ; RP041 ; RP041 .IF DF M$$EXT ; RP041 ; RP041 BIT #DV.EXT,U.CW1(R5) ;CAN THIS CONTROLLER/UNIT DIRECTLY ..; RP041 ;... ADDRESS ALL OF PHYSICAL MEMORY ; RP041 BNE 10$ ;IF NE YES, ADDRESS IS OK ; RP041 ADD #,R4 ;POINT PAST PHYSICAL BUFFER ADDRESS ; RP041 ;... CONTAINED IN UMR AREA ; RP041 MOV -(R4),R1 ;REPLACE STARTING PHSYICAL BUFFER ... ; RP041 ;... ADDRESS IN R1 ; RP041 TSTB -(R4) ;SKIP NEXT BYTE ; RP041 MOVB -(R4),R0 ;MOVE HIGH BITS IN PLACE OF MEM EXT BITS; RP041 10$: MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS ; RP041 ; RP041 .ENDC ;M$$EXT ; RP041 ; RP041 .IFF ;M$$MGE ; RP041 ; RP041 CLR R0 ; ; RP041 ; RP041 .IFTF ;M$$MGE ; RP041 ; RP041 ADD (SP),R1 ;CALCULATE NEW STARTING ADDRESS ... ; RP041 ADC R0 ;... ; RP041 ; RP041 .IFT ;M$$MGE ; RP041 ; RP041 ; RP041 .IF DF M$$EIS ; RP041  ; RP041 ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ; RP041 ASHC #-10.,R1 ;... ; RP041 ; RP041 .IFF ;M$$EIS ; RP041 ; RP041 MOV #10.,-(SP) ;SET COUNT FOR 10 SHIFTS ; RP041 20$: DEC (SP) ;ANY MORE SHIFTS TO PERFORM ; RP041 BLT 30$ ;IF LT NO ; RP041 ASL R1 ;DOUBLE LEFT SHIFT R1 ... ; RP075 ROL R0 ;... INTO R0 ; RP075 BR 20$ ; ; RP075 30$: SWAB R1 ;SWAP BYTES ; RP075 ASR R1 ;SHIFT RIGHT R1 ; RP075 ASR R1 ;... ; RP075  TST (SP)+ ;CLR THE STACK ; RP075 ; RP041 .ENDC ;M$$EIS ; RP041 ; RP041 ; RP041 MOV R0,KISAR6 ;SET RELOCATION BIAS ; RP041 ADD #140000,R1 ;SET DISPLACEMENT ; RP041 ; RP041 .IFTF ;M$$MGE ; RP041 ; RP041 MOV (SP)+,R0 ;RETRIEVE BYTE OFFSET ; RP041 ; RP041 .ENDC ;M$$MGE ; RP041 ;**-36 RETURN ; .ENDC ;+ ; DD098 ; **-$SWACD-SAVE MAPPING, CALL ACD AS A CO-ROUTINE, THEN REMAP DRIVER ; DD098 ; **-$SWAC1-CALL ACD AS A CO-ROUTINE, THEN REMAP DRIVER ; DD098 ; ; DD098 ; THESE ROUTINES ARE CALLED BY THE FULL DUPLEX TERMINAL DRIVER TO ; DD098 ; SWITCH PROCESSING TO AN ANCILLARY CONTROL DRIVER (ACD). SINCE THE ; DD098 ; ACD REQUIRES APRS 5 AND 6, THE DRIVER MAPPING IS FIRST SAVED (IF ENTRY; DD098 ; AT $SWACD), THEN THE ACD IS CALLED AS A CO-ROUTINE VIA A DISPATCH ; DD098 ; TABLE CONTAINED IN THE ANCILLARY CONTROL BLOCK (ACB). WHEN THE ACD ; DD098 ; RETURNS, THIS ROUTINE REMAPS THE DRIVER AND RETURNS CONTROL TO IT. ; DD098 ; ; DD098 ; INPUTS: ; DD098 ; ; DD098 ; R0=DISPATCH TABLE OFFSET (IF ENTRY AT $SWACD). ; DD098 ; R0=ACB ADDRESS (IF ENTRY AT $SWAC1). ; DD098 ; R5=POINTER TO OFFSET U.TSTA WITHIN THE TERMINAL'S UCB. ; DD098 ; 2(SP)=DISPATCH TABLE OFFSET (IF ENTRY AT $SWAC1). ; DD098 ; 4(SP)=APR5 BIAS OF TERMINAL DRIVER (IF ENTRY AT $SWAC1). ; DD098 ; ; DD098 ; OUTPUTS: ; DD098 ; ; DD098 ; R0 IS DESTROYED.  ; DD098 ;- ; DD098 ; DD098 .IF DF T$$CPW&T$$ACD ; DD098 ; DD098 $SWACD::MOV KINAR5,-(SP) ;SAVE TERMINAL DRIVER MAPPING ; DD098 MOV R0,-(SP) ;PUT ENTRY POINT OFFSET ON STACK ; DD098 MOV U.ACD-U.TSTA(R5),R0 ;GET ACB ADDRESS ; DD098 $SWAC1::MOV (R0),KINAR5 ;MAP THE ANCILLARY CONTROL DRIVER ; DD098 ADD A.DIS(R0),(SP) ;ADD DISPATCH TABLE ADDR TO THE OFFSET ; DD098 MOV @(SP),(SP) ;GET THE ENTRY POINT ADDRESS ; DD098 CALL @(SP)+ ;CALL THE ACD ; DD098 MOV Ì(SP)+,KINAR5 ;UPON RETURN, REMAP THE TERMINAL DRIVER ; DD098 RETURN ;AND THEN RETURN TO IT ; DD098 ; DD098 .ENDC ;T$$CPW&T$$ACD ; DD098 ; DD098 ; DD098 .END ÌL!ðskQ ›c, .TITLE EMDRV .IDENT /01.0/ ; ; COPYRIGHT (C) 1981 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 01.0 ; ; T. LEKAS 2-FEB-81 ; ; RH11-ML-11 MEMORY SYSTEM DRIVER ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS PKTDF$ ; DEFINE I/O PACKET OFFSETS .IF DF D$$IAG .MCALL UMDIO$ UMDIO$ ; DEFINE USER-MODE DIAGNOSTIC DEFINITIONS .ENDC ; ; EQUATED SYMBOLS ; RETRY=8. ; ERROR RETRY COUNT MLWC=2 ; WORD COUNT REGISTER MLBA=4 ; UNIBUS ADDRESS REGISTER MLDS=12 ; DRIVE STATUS REGISTER MLCS2=10 ; SECOND STATUS REGISTER MLER1=14 ; ERROR REGISTER MLAS=16 ; ATTENTION SUMMARY REGISTER MLDA=6 ; DESIRED ADDRESS REGISTER MLBAE=50 ; BUS ADDRESS EXTENSION REGISTER ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW M$$L11 ; ADDRESS OF CURRENT UNIT CONTROL BLOCK RTTBL: .BLKW M$$L11 ; RETRY COUNT FOR CURRENT OPERATION .IF GT M$$L11-1 TEMP: .BLKW 1 ; TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $EMTBL::.WORD EMINI ; DEVICE INITIATOR ENTRY POINT .WORD EMCAN ; CANCEL I/O OPERATION ENTRY POINT .WORD EMOUT ; DEVICE TIMEOUT ENTRY POINT .WORD EMPWF ; POWERFAIL ENTRY POINT ; + ; **-EMINI-RH11-ML-11 MEMORY SYSTEM INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ; - .ENABL LSB EMINI: CALL $GTPKT ; GET AN I/O PACKET TO PROCESS BCS EMCAN ; IF CS CONTROLLER BUSY OR NO REQUEST ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; RH11-ML-11 MEMORY SYSTEM I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE NOT USED. ; WD. 17 -- LOGICAL BLOCK NUMBER OF I/O REQUEST. ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. ADRS ELSE NOT USED ; WD. 21 -- DIAGNOSTIC REG. BLK ADRS (REAL OR DISPL.+140000) ; MOV R5,CNTBL(R3) ; SAVE ADDRESS OF REQUEST UCB .IF DF M$$EXT&M$$MGE BIT #DV.MBC,U.CW1(R5) ; IS IT A 22 BIT MASS BUS DEVICE? BNE 1$ ; IF NE YES -- DOES NOT USE UMR'S CALL $STMAP ; SET UP UNIBUS MAP .ENDC ASL U.BUF(R5) ; SHIFT ADDRESS EXTENSION BITS INTO PLACE ASL U.BUF(R5) ; ASL U.BUF(R5) ; ASL U.BUF(R5) ; 1$: ; REF LABEL .IF DF D$$IAG CMP #IO.WCK!IQ.UMD,I.FCN(R1) ; DIAGNOSTIC WRITE CHECK? BNE 5$ ; IF NE NO BIS #151,U.BUF(R5) ; YES, SET FUNCTION CODE BR 10$ ; .ENDC 5$: MOV #IE.IFC&377,R0 ; ASSUME ILLEGAL FUNCTION BIS #171,U.BUF(R5) ; ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/256.,I.FCN+1(R1) ; READ LOGICAL FUNCTION? BHIS 6$ ; IF HIS FUNCTION IS LEGAL JMP 70$ ; FUNCTION IS ILLEGAL 6$: BEQ 10$ ; IF EQ FUNCTION IS READ SUB #10,U.BUF(R5) ; CONVERT TO WRITE LOGICAL FUNCTION 10$: MOV #RETRY,RTTBL(R3) ; SET RETRY COUNT CALL $BLKCK ; CHECK LOGICAL BLOCK NUMBER MOV R0,I.PRM+12(R3) ; SAVE DISK ADDRESS ; ; INITIATE I/O OPERATION ; 30$: ; REF LABEL .IF DF M$$EXT&M$$MGE BIT #DV.MBC,U.CW1(R5) ; IS IT A 22 BIT MASS BUS DEVICE? BNE 300$ ; IF NE YES -- DOES NOT USE UMR'S CALL $MPUBM ; MAP UNIBUS TO MEMORY 300$: ; REF LABEL .ENDC MOV S.CSR(R4),R2 ; GET ADDRESS OF CSR MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS MOVB S.ITM(R4),S.CTM(R4) ; SET CURRENT DEVICE TIMEOUT COUNT MOV #40,MLCS2(R2) ; CLEAR RH11 CONTROLLER AND ALL DRIVES MOVB U.UNIT(R5),MLCS2(R2) ; SELECT PROPER DRIVE MOV I.PRM+12(R1),MLDA(R2) ; INSERT DISK ADDRESS ADD #MLBA,R2 ; POINT TO BUS ADDRESS REGISTER MOV U.BUF+2(R5),(R2) ; INSERT BUFFER ADDRESS MOV U.CNT(R5),-(R2) ; INSERT NUMBER OF BYTES TO TRANSFER ROR (R2) ; CONVERT TO WORD COUNT NEG (R2) ; MAKE NEGATIVE WORD COUNT TST -(R2) ; POINT TO CSR REGISTER MOV #IE.DNR&377,R0 ; ASSUME DRIVE NOT READY MOV MLDS(R2),R3 ; GET CONTENTS OF DRIVE STATUS REGISTER COM R3 ; COMPLEMENT STATUS BIT #10600,R3 ; DRIVE READY AND ON-LINE? BEQ 32$ ; IF EQ YES .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ; DIAGNOSTIC OPERATION? BEQ 31$ ; IF EQ NO JMP 45$ ; LOG DIAGNOSTIC DRIVE NOT READY 31$: ; REF LABEL .ENDC .IF DF E$$DVC CALL $DVCER ; LOG DRIVE NOT READY ERROR .ENDC JMP 60$ ; FINISH I/O 32$: ; REF LABEL .IF DF E$$DVC CALL $BMSET ; SET I/O ACTIVE BIT IN MAP .ENDC .IF DF M$$EXT&M$$MGE BIT #DV.MBC,U.CW1(R5) ;;; IS IT A 22 BIT MASS BUS DEVICE? BEQ 34$ ;;; IF EQ NO -- DOES USE UMR'S MOVB U.BUF+1(R5),MLBAE(R2) ;;; SET ADDRESS EXTENSION BITS MOVB U.BUF(R5),(R2) ;;; START FUNCTION RETURN ;;; .ENDC 34$: MOV U.BUF(R5),(R2) ;;; START FUNCTION ; ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ; EMCAN: RETURN ;;; NOP FOR ML-11 ; + ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. ; - EMPWF: ; POWERFAIL ENTRY POINT .IF DF P$$RFL BISB #US.SPU,U.STS(R5) ; SET UNIT "SPINNING UP" .ENDC RETURN ; WAIT FOR UNIT TO RESPOND ; + ; **-$EMINT-RH11-ML-11 MEMORY SYSTEM CONTROLLER INTERRUPTS ; - INTSE$ EM,PR5,M$$L11 ;;; SAVE REGISTERS AND SET PRIORITY CALL $FORK ;;; CREATE A SYSTEM PROCESS MOV R4,R3 ; COPY CONTROLLER INDEX MOV U.SCB(R5),R4 ; GET ADDRESS OF SCB MOV #IS.SUC&377,R0 ; ASSUME SUCCESSFUL TRANSFER MOV S.CSR(R4),R2 ; GET ADDRESS OF CSR MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS .IF DF D$$IAG BITB #IQ.UMD,I.FCN(R1) ; DIAGNOSTIC FUNCTION EXECUTED? BNE 45$ ; IF NE YES .ENDC BIT #60000,(R2) ; ANY ERRORS? BEQ 55$ ; IF EQ NO .IF DF E$$DVC CALL $DVCER ; LOG DEVICE ERROR .ENDC MOV #IE.VER&377,R0 ; ASSUME UNRECOVERABLE ERROR MOV MLER1(R2),R1 ; GET CONTENTS OF ERROR REGISTER BIT #43007,R1 ; HARD ERROR? BNE 57$ ; IF NE YES BIT #14000,MLCS2(R2) ; NEM OR NED? BEQ 50$ ; IF EQ NO BR 57$ ; YES, HARD ERROR ; ; DEVICE TIMEOUT RESULTS IN THE CURRENT OPERATION BEING REPEATED ; UNLESS THE REQUEST WAS DIAGNOSTIC. ; EMOUT: ;;; TIMEOUT ENTRY POINT .IF DF P$$RFL BITB #US.SPU,U.STS(R5) ;;; IS DRIVE "SPINNING UP"? BEQ 44$ ;;; IF EQ NO BICB #US.SPU,U.STS(R5) ;;; RESET DRIVE "SPINNING UP" MTPS #0 ;;; ALLOW INTERRUPTS JMP 30$ ; RETRY ENTIRE OPERATION 44$: INCB S.STS(R4) ;;; LEAVE CONTROLLER BUSY .ENDC CALL $DTOER ;;; LOG DEVICE TIMEOUT  .IF DF D$$IAG BCC 50$ ; IF CC TIMEOUT DURING NORMAL FUNCTION 45$: CALL $CRPAS ; PASS CONTROLLER REGISTERS TO TASK BR 60$ ; DIAGNOSTIC PROCESSING COMPLETE .ENDC 50$: MOV S.PKT(R4),R1 ; GET I/O PACKET ADDRESS BITB #IQ.X,I.FCN(R1) ; INHIBIT RETRIES? BNE 57$ ; IF NE YES DEC RTTBL(R3) ; RETRY FUNCTION? BLE 57$ ; IF LE NO 51$: JMP 30$ ; RETRY OPERATION 55$: ; REF LABEL .IF DF D$$WCK BITB #IO.WLC&377,I.FCN(R1) ; WRITE FOLLOWED BY WRITE CHECK? BNE 56$ ; IF NE YES BITB #US.WCK,U.STS(R5) ; WRITE CHECK ENABLED BY MCR? BEQ 57$ ; IF EQ NO 56$: MOVB U.BUF(R5),R1 ; GET LAST FUNCTION CMPB #171,R1 ; WAS IT A READ? BEQ 60$ ; IF EQ YES MOVB #151,U.BUF(R5) ; ASSUME A WRITE CHECK OPERATION CMPB #161,R1 ; WAS LAST FUNCTION A WRITE? BNE 57$ ; IF NE NO MOV #RETRY,RTTBL(R3); REINITIALIZE RETRY COUNT BR 51$ ; START WRITE CHECK OPERATION .IFTF 57$: ; REF LABEL .IFT BIT #40000,MLCS2(R2) ; WRITE CHECK ERROR? BEQ 60$ ; IF EQ NO  MOV #IE.WCK&377,R0 ; SET WRITE CHECK ERROR .ENDC 60$: MOV MLWC(R2),R1 ; GET WORDS REMAINING TO TRANSFER ASL R1 ; CONVERT TO BYTES LEFT TO TRANSFER ADD U.CNT(R5),R1 ; CALCULATE BYTES ACTUALLY TRANSFERED MOV #40011,(R2) ; CLEAR CONTROLLER AND DRIVE 70$: ; REF LABEL .IF DF E$$DVC MOVB S.CON(R4),R3 ; RETREIVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ; GET FINAL ERROR RETRY COUNT BIS #RETRY*256.,R2 ; MERGE STARTING RETRY COUNT .ENDC CALL $IODON ; FINISH I/O OPERATION J:MP EMINI ; PROCESS NEXT REQUEST .DSABL LSB .END :ÔMðskQ ›c, .TITLE LRDRV .IDENT /05/ ; COPYRIGHT (C) 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; DIGITAL EQUIPMENT OF CANADA LTD, KANATA, ONTARIO ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 05 ; ; DAVID R. CROWE ; ; PREVIOUSLY MODIFIED BY: ; ; DAVID H. CHAN ; HELEN GORDON ; PATRICIA C. LEE ; ; MODIFIED BY: ; ; R. E. CALDWELL 21-AUG-79 ; ; RC011 -- USE CORRECT FORM OF GTPKT$. ; ; PARALLEL COMMUNICATIONS LINK (PCL) RECEIVER DRIVER FOR RSX-11M-PLUS. ; ; MACRO LIBRARY CALLS. ; .MCALL PKTDF$,TCBDF$,UCBDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS. UCBDF$ ;DEFINE UCB OFFSETS ;+ ; THIS DRIVER IS IN ONE OF A NUMBER OF SOFTWARE STATES DURING ITS ; OPERATION. ITS CURRENT STATE IS DEFINED IN THE LOW ORDER BYTE ; OF U.CW2 IN THE UCB. HANDLER STATES ARE DEFINED BELOW. ; ; INDEX MEANING ; 0 NO TASK CONNECTED. ; 2 TASK CONNECTED BUT NOT TRIGGERED. ; 4 TASK TRIGGERED & AWAITING ATF OR RTF. ; 6 TASK CONNECTED & TIMED OUT AWAITING ATF OR RTF. ; ; ... BUSY STATES ... ; THE CONTROLLER IS CONSIDERED BUSY BY RSX-11M WHILE THE ; HANDLER IS IN THESE STATES. THEREFORE ONLY THE INTERRUPT PROCESSOR ; NEED CONCERN ITSELF WITH THEM. BUSY STATES ARE AS FOLLOWS: ; ; -2 ATF IN PROGRESS. ; -4 TASK CONNECTED, NOT TRIGGERED, & HAS ATF PENDING. ; -6 RTF IN PROGRESS. ; ; LEGAL FUNCTIONS BY STATE. ; FUNCTION LEGAL STATES ; CRX 0 ; RTF 4, 6 ; ATF 2, 4, 6 ; DRX 2, 4, 6 ;- ;+ ; HANDLER UCB WORK AREA OFFSET DEFINITIONS. ;- U.TASK = U.CNT+2 ;TCB ADDR OF CONNECTED TASK [WORD] U.TEF = U.TASK+2 ;TRIGGER EVENT FLAG NO. [WORD] U.TRSB = U.TEF+2 ;REAL ADDRESS OF TRIGGER STATUS U.BUF1 = U.TRSB+4 ;ADDRESS OF RETURN BUFFER (2 WDS) U.AADA = U.BUF1+4 ;ATACHMENT DESCR. STORAGE ; BUFFER [2 WORDS] ;+ ; THE HARDWARE REGISTERS ARE DEFINED RELATIVE TO THE RCR, WHOSE ; ADDRESS IS FOUND IN THE S.CSR FIELD OF THE SCB AT RUN TIME. ;-  RCR = 0 ;RECEIVER COMMAND REGISTER. RSR = 2 ;RECEIVER STATUS REGISTER. RDDB = 4 ;RECEIVER DESTINATION DATA BUFFER. RDBC = 6 ;RECEIVER DESTINATION BYTE COUNT. RDBA = 10 ;RECEIVER DESTINATION BUS ADDRESS. RDCRC = 12 ;RECEIVER DESTINATION CRC ;+ ; RECEIVER COMMAND REGISTER (RCR). ;- REJ = 100000 ;REJECT (R/W) RCNPR = 40000 ;RECEIVER NPR (R/W) RCVWD = 20000 ;RECEIVE WORD (R/W) IB04 = 10000 ;IDENTIFICATION BITS (RO) IB03 = 4000 ; " IB02 = 2000 ; " IB01 = 1000 ; " IB00 = 400 ; " LDSILO = 200 ;LOAD SILO (R/W) IE = 100 ;INTERRUPT ENABLE (R/W) A17 = 40 ;EXTENDED ADDRESS BITS (R/W) A16 = 20 ; " DTIRDY = 10 ;DATA INPUT READY (RO) INHADI = 4 ;INHIBIT ADDRESS INCREMENT (R/W) BDINIT = 2 ;BOARD INITIALIZE (WO) RCVDAT = 1 ;RECEIVE DATA (R/W) IB = IB04!IB03!IB02!IB01!IB00 ;UNION OF IDENTIFICATION BITS ;+ ; RECEIVER STATUS REGISTER (RSR). ;- ERR = 100000 ;ERROR (RO) NEXLOC = 40000 ;NONEXISTENT LOCATION (RO) MEMOFL = 20000 ;MEMORY OVERFLOW (R/W) TXMERR = 10000 ;TRANSMISSION ERROR (R/W) PAR = 4000 ;PARITY (R/W) TIMOUT = 2000 ;TIME OUT (R/W) BCOFL = 1000 ;BYTE COUNT OVERFLOW (R/W) DTORDY = 400 ;DATA OUTPUT READY (RO) SUCTXF = 200 ;SUCCESSFUL TRANSFER (R/W) BUSY = 100 ;BUSY (RO) RECOM = 40 ;REJECT COMPLETE (R/W) CHNOPN = 20 ;CHANNEL OPEN (RO) RSPB1 = 10 ;RESPONSE B1 (RO) RSPB0 = 4 ;RESPONSE B0 (RO) RSPA1 = 2 ;RESPONSE A1 (RO) RSPA0 = 1 ;RESPONSE A0 (RO) ;+ ; FUNCTION DISPATCH TABLE ;- FUNTBL: .IRP X, .WORD IO.'X, X .ENDM .WORD 0 ;TERMINATOR ;+ ; DEVICE DISPATCH TABLE ;- DDT$ LR,L$$R11,,CHK ;GENERATE DISPATCH TABLE ;+ ; LRCHK - PCL RECEIVER DRIVER PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS RECEIVED FOR THE PARALLEL COMMUNICATIONS LINK RECEIVER. ; SOME PCL RECEIVER REQUESTS CONTAIN INFORMATION THAT MUST BE CHECKED ; IN THE CONTEXT OF THE ISSUING TASK; THEREFORE, THE I/O REQUEST IS NOT ; QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1 = ADDRESS OF THE I/O PACKET ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; ; OUTPUTS: ; ; IF FUNCTION IS IO.CRX, ADDRESS CHECK IS PERFORMED FOR IOSB(8 BYTES) ; ; IF THE QIO FUNCTION IS IO.ATF THEN THE RETURN BUFFER ADDRESS IS ; CHECKED TO DETERMINE WHETHER IT LIES WITHIN THE ISSUING ; TASK'S ADDRESS SPACE. IF IT DOES THEN THE RETURN BUFFER ADDRESS IS ; RELOCATED AND STORED IN THE I/O PACKET. IF IT IS NOT A VALID ; ADDRESS THEN AN ILLEGAL BUFFER STATUS IS RETURNED AS THE FINAL ; I/O STATUS OF THE REQUEST. ; ; FOR ALL FUNCTION CODES, THE I/O PACKET IS INSERTED IN THE ; CONTROLLER QUEUE AND THE DEVICE INITIATOR IS ENTERED TO START ; THE CONTROLLER. ;- LRCHK: CMP #IO.CRX,I.FCN(R1) ;IS FUNCTION 'CRX'? BNE 5$ ;IF NE NO MOV R1,R3 ;SAVE IO PACKET ADDRESS MOV I.PRM+2(R3),R0 ;GET VIRTUAL ADDRESS OF BUFFER MOV #4.,R1 ;GET LENGTH 4 BYTES CALL $ACHKB ;CHECK THE ADDRESS BCS 10$ ;IF CS BAD MOV W.BATT(R2),R2 ;GET ATT. DESC. ADD. INCB A.IOC(R2) ;INCREMENT I/O COUNT MOV R2,I.PRM+6(R3) ;SAVE ATT. DESC. ADDR CALL $RELOC ;RELOCATE THE BUFFER MOV R1,I.PRM+2(R3) ;STORE BIAS MOV R2,I.PRM+4(R3) ;STORE ADDRESS MOV R3,R1 ;RESTORE IO PACKET ADDRESS BR 20$ ;CONTINUE 5$: CMP #IO.ATF,I.FCN(R1) ;IS FUNCTION CODE = 'ATF'? BNE 20$ ;IF NE NO ; ; 'ATF' FUNCTION - SET UP REGISTERS FOR ADDRESS CHECK AND RELOCATION ; ; R0 = ADDRESS TO CHECK AND RELOCATE ; R3 = ADDRESS OF THE I/O PACKET ; MOV R1,R3 ;SAVE ADDRESS OF THE I/O PACKET MOV I.PRM+6(R3),R0 ;GET VIRTUAL ADDRESS OF RETURN BUFFER ; ; VALIDATE THE RETURN BUFFER ADDRESS FOR THIS TASK ; MOV #12.,R1 ;SET LENGTH OF RETURN BUFFER TO 6 WORDS CALL $ACHCK ;CHECK THE ADDRESS BCC 15$ ;IF CC OK ; ; INVALID RETURN BUFFER ADDRESS - SET ILLEGAL BUFFER STATUS AND FINISH ; 10$: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS CALLR $IOFIN ;FINISH I/O OPERATION ; ; RELOCATE THE RETURN BUFFER ADDRESS ; 15$: MOV W.BATT(R2),R2 ;GET ATT. DESC. ADDR. INCB A.IOC(R2) ;INCREMENT I/O COUNT MOV R2,I.AADA+2(R3) ;SAVE PTR FOR $IODONE CALL $RELOC ;RELOCATE ADDRESS MOV R1,I.PRM+6(R3) ;RELOCATION BIAS ==> I/O PACKET MOV R2,I.PRM+10(R3) ;16-BIT ADDRESS ==> I/O PACKET MOV R3,R1 ;RESTORE R1 TO I/O PACKET ; ; INSERT THE I/O PACKET IN THE QUEUE ; 20$: MOV R4,R0 ;R0 = I/O QUEUE LISTHEAD CALL $QINSP ;GO INSERT PACKET IN QUEUE ; ; NOW GET THE I/O PACKET TO PROCESS. ; LRINI: GTPKT$ LR,L$$R11,,,T ;GET I/O PACKET MACRO ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX. ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; I/O REQUEST PACKET FORMAT: ; ; WD.00 = I/O QUEUE THREAD WORD ; WD.01 = REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD.02 = TCB ADDRESS OF REQUESTER TASK. ; WD.03 = POINTER TO 2ND LUN WORD IN REQUESTER TASK HEADER. ; WD.04 = CONTENTS OF 1ST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD.05 = I/O FUNCTION CODE. ; WD.06 = VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD.07 = RELOCATION BIAS OF I/O STATUS BLOCK. ; WD.10 = I/O STATUS BLOCK ADDRESS DISPLACEMENT + 140000. ; WD.11 = VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD.12 = FIRST PARAMETER OR RELOCATION BIAS OF DATA BUFFER ; WD.13 = SECOND PARAMETER OR 16-BIT ADDRESS OF DATA BUFFER ; WD.14 = THIRD PARAMETER OR LENGTH OF DATA BUFFER ; WD.15 = FOURTH PARAMETER OR RELOCATION BIAS OF RETURN BUFFER ; WD.16 = FIFTH PARAMETER OR 16-BIT ADDRESS OF RETURN BUFFER ; MOV I.TCB(R1),R0 ;GET TCB ADDRESS OF REQUESTOR BITB #T2.ABO,T.ST2(R0) ;IS TASK BEING ABORTED? BEQ 10$ ;IF EQ NO CALLR IEVER ;YES, IT'S FATAL 10$: MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE 20$: CMP (R0),I.FCN(R1) ;FUNCTION CODES MATCH? BEQ 30$ ;IF EQ YES CMP (R0)+,(R0)+ ;MOVE TO NEXT ENTRY TST (R0) ;END OF TABLE? BNE 20$ ;IF NE NO CALLR IEIFC ;YES, ILLEGAL FUNCTION 30$: JMP @2(R0) ;GO TO FUNCTION PROCESSOR ;+ ; PROCESS 'CRX' FUNCTION ;- CRX: CMP I.PRM(R1),#96. ;IF TRIGGER EVENT FLAG > 64, BHI 20$ ;IF HI BAD TSTB U.CW2(R5) ;IS A TASK ALREADY CONNECTED ? BNE 10$ ;IF NE YES MOV I.PRM(R1),U.TEF(R5) ;SAVE TRIGGER EVENT FLAG NO. MOV I.PRM+2(R1),U.TRSB(R5) ;SAVE THE ADDRESS OF THE TRIGGER MOV I.PRM+4(R1),U.TRSB+2(R5) ;STATUS BUFFER MOV I.TCB(R1),U.TASK(R5) ;SAVE TCB ADDRESS MOV I.PRM+6(R1),U.AADA(R5) ;SAVE ATT. DESC. ADDR. CALL PRCRX ;CONNECT TASK FOR RECEPTION CALLR ISSUC ;INDICATE SUCCESS AND EXIT 10$: CALLR IEDAA ;SOMEONE ALREADY CONNECTED 20$: CALLR IEBAD ;BAD PARAMETER SPECIFIED ;+ ; **-PRCRX-PERFORM ACTUAL CONNECT FOR RECEPTION ; ; THIS ROUTINE IS CALLED TO CONNECT THE RECEIVER FOR RECEPTION. ; IT ACTIVATES THE HARDWARE TO RECEIVE A WORD, WHICH WILL BE ; TREATED AS A FLAGS WORD. IT SETS THE SOFTWARE STATE OF THE HANDLER ; TO 2. THE ROUTINE SHOULD BE CALLED WHENEVER THE HANDLER WISHES ; TO RECEIVE A FLAGS WORD. ; ; INPUTS: ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK (SCB) ; R5 = ADDRESS OF THE UNIT CONTROL BLOCK (UCB) ; ; OUTPUTS: ; THE RECEIVER IS INITIALIZED (BDINIT) & RCVWD IS SET. ; THE HANDLER IS SET TO SOFTWARE STATE 2. ; R0 IS SET POINTING TO THE RCR. ;- PRCRX: MOV U.BUF(R5),-(SP) ;SAVE BUFFER MOV U.BUF+2(R5),-(SP) ;ADDRESS MOV U.CNT(R5),-(SP) ;& COUNT. MOV U.TRSB(R5),U.BUF(R5) ;MOVE TRIGGER STATUS MOV U.TRSB+2(R5),U.BUF+2(R5) ;BUFFER ADDR TO U.BUF. MOV #4,U.CNT(R5) ;LOAD BYTE COUNT. CLR -(SP) ;SET STATUS BYTE TO ZERO. CALL $PTBYT ; " MOV (SP)+,U.CNT(R5) ;RESTORE BUFFER MOV (SP)+,U.BUF+2(R5) ;ADDRESS MOV (SP)+,U.BUF(R5) ;& COUNT. MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #BDINIT,(R0) ;INITIALIZE RECEIVER. BIS #RCVWD!IE,(R0) ;PREPARE TO RECEIVE A FLAG WD. MOVB #2,U.CW2(R5) ;SET HANDLER STATE TO 2. RETURN ; ;+ ; PROCESS 'RTF' FUNCTION ;- RTF: CMP I.TCB(R1),U.TASK(R5) ;RTF FROM CONNECTED TASK? BEQ 10$ ;IF EQ YES CALLR IEDNA ;NO, DEVICE NOT AVAILABLE 10$: MOVB U.CW2(R5),R0 ;GET HANDLER STATE. BIC #^C6,R0 ;MASK OUT UNWANTED BITS  JMP @RTFJMP(R0) ;PROCESS FUNCTION ACCORDING STATE RTFJMP: .WORD IEDNA ;STATE 0 .WORD IENTR ;STATE 2 .WORD RTFS4 ;STATE 4 .WORD RTFS6 ;STATE 6 RTFS4: MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #REJ!IE,(R0) ;SET REJECT & INT ENABLE. MOVB #-6,U.CW2(R5) ;SET HANDLER STATE TO -6. MOVB S.ITM(R4),S.CTM(R4) ;SET TIME OUT RETURN ; RTFS6: MOVB #2,U.CW2(R5) ;SET HANDLER STATE TO 2. CALLR IEDNR ;FORCE DRIVE NOT READY ;+ ; PROCESS 'ATF' FUNCTION ;- ATF: ;REF LABEL .IF DF M$$EXT CALL $STMAP ;SET UP UNIBUS MAP ADDRESS .ENDC MOV I.PRM+6(R1),U.BUF1(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+10(R1),U.BUF1+2(R5) ;16-BIT ADDRESS ==> UCB CMP I.TCB(R1),U.TASK(R5) ;ATF FROM CONNECTED TASK? BEQ 10$ ;IF EQ YES CALLR IEDNA ;NO, DEVICE NOT AVAILABLE 10$: MOVB U.CW2(R5),R0 ;GET HANDLER STATE. BIC #^C6,R0 ;CLEAR UNWANTED BITS JMP @ATFJMP(R0) ;PROCESS FUNCTION ACCORDING TO STATE ATFJMP: .WORD IEDNA ;STATE 0 .WORD ATFS2 ;STATE 2 .WORD PRATF ;STATE 4 .WORD RTFS6 ;STATE 6 ATFS2: MOVB #-4,U.CW2(R5) CLRB S.CTM(R4) ;NO TIME OUT ON THIS RETURN ; ;+ ; **-PRATF-PERFORM ACCEPTANCE OF TRANSFER ; ; THIS ROUTINE IS CALLED TO INITIATE THE RECEPTION OF THE MESSAGE ; WHICH HAS JUST BEEN ACCEPTED. THE STATE OF THE HANDLER IS SET ; TO -2, WHICH INDICATES THAT THE HANDLER IS BUSY PERFORMING ; THE ACCEPT TRANSFER FUNCTION. ; ; INPUTS: ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK (SCB) ; R5 = ADDRESS OF THE UNIT CONTROL BLOCK (UCB) ; ; OUTPUTS: ; THE RDBC & RDBA ARE SET UP, & AN NPR RCVDAT FUNCTION IS INITIATED. ; THE HANDLER IS SET TO STATE -2. ; R0 IS SET POINTING TO THE RCR. ; R2 IS DESTROYED. ;- PRATF: ;REF LABEL .IF DF M$$EXT CALL $MPUBM ;MAP UNIBUS TO MEMORY MOV S.PKT(R4),R1 ;RETREIVE I/O PACKET ADDRESS .ENDC MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR MOV U.BUF+2(R5),RDBA(R0) ;LOAD BUFFER ADDRESS REGISTER. MOV U.CNT(R5),R2 ;GET BYTE COUNT. NEG R2 ;NEGATE IT & LOAD MOV R2,RDBC(R0) ;BYTE COUNT REGISTER. MOVB #-2,U.CW2(R5) ;SET HANDLER STATE TO -2. BIS #RCNPR!RCVDAT!IE,U.BUF(R5) ;SET RCNPR, RCVDAT, IE, & BIS U.BUF(R5),(R0) ;EXTENDED ADDR BITS IN RCR. MOVB S.ITM(R4),S.CTM(R4) ;SET TIME OUT RETURN ; ;+ ; PROCESS 'DRX' FUNCTION ;- DRX: TSTB U.CW2(R5) ;IS ANY TASK CONNECTED ? BEQ 10$ ;IF EQ NO MOV I.TCB(R1),R1 ;YES, GET TCB ADDRESS. CMP R1,U.TASK(R5) ;IS THIS TASK CONNECTED ? BNE 10$ ;IF NE NO CALL PRDRX ;DO THE DISCONNECT CALLR ISSUC ;EXIT WITH SUCCESS 10$: CALLR IEDNA ;DEVICE NOT AVAILABLE ;+ ; **-PRDRX-PERFORM ACTUAL DISCONNECT FROM RECEPTION ; ; THIS ROUTINE DISCONNECTS THE RECEIVING TASK FROM RECEPTION. ; ; INPUTS: ; R1 = ADDRESS OF TCB FOR TASK. ; R4 = SCB ADDRESS. ; R5 = UCB ADDRESS. ; ; OUTPUTS: ; THE I/O REQUEST COUNT FOR THE TASK IS DECREMENTED. ; THE RECEIVER IS INITIALIZED (BDINIT). ; THE HANDLER STATE IS SET TO 0. ; R0 IS SET POINTING TO THE RCR. ;- PRDRX: MOV U.AADA(R5),R0 ;GET ATTACHMENT DESCRIPTOR ADDRESS DECB A.IOC(R0) ;DECREMENT I/O COUNT MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #BDINIT,(R0) ;INITIALIZE RECEIVER BOARD. CLR U.AADA(R5) ;CLEAR ATTACHED REGION DESC. CLR U.TASK(R5) ;CLEAR TCB ADDRESS OF CONNECTED TASK CLR U.TEF(R5) ;CLEAR EVENT FLAG ALSO CLRB U.CW2(R5) ;SET HANDLER STATE TO 0. RETURN ; ;+ ; **-$LRINT-PCL RECEIVER INTERRUPT PROCESSOR ; ; INTERRUPTS ARE PROCESSED DEPENDING UPON THE HANDLER STATE. ;- $LRINT:: INTSV$ LR,PR5,L$$R11 ;;;GENERATE INTERRUPT SAVE STUFF MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS.  MOV S.CSR(R4),R4 ;;;GET RCR ADDRESS. BIC #IE,(R4) ;;;DISABLE PCL INTERRUPTS. CALL $FORK ;;;CREATE A FORK PROCESS. MOV R4,R0 ;COPY RCR ADDRESS MOV U.SCB(R5),R4 ;GET SCB ADDRESS. MOVB U.CW2(R5),R2 ;GET HANDLER STATE. JMP @INTJMP(R2) ;PROCESS INTERRUPT ACCORDING TO STATE .WORD INTM6 ;STATE -6 .WORD INTM4 ;STATE -4 .WORD INTM2 ;STATE -2 INTJMP: .WORD INTP0 ;STATE 0 .WORD INTP2 ;STATE 2 .WORD INTP4 ;STATE 4 .WORD INTP6 ;STATE 6 ; ; THE VARIOUS INTERRUPT STATE PROCESSORS WHICH ARE JUMPED TO ; THROUGH THE INTJMP TABLE ARE ENTERED WITH REGISTERS SET AS FOLLOWS: ; R0 = RCR ADDRESS ; R2 = HANDLER STATE ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; INTM6: BIT #ERR!SUCTXF,RSR(R0) ;ERROR OF SUCTXF? BNE 10$ ;IF NE YES BIT #RECOM,RSR(R0) ;IS RECOM SET? BEQ 10$ ;IF EQ NO CALL PRCRX ;RECONNECT FOR RECEPTION CALLR ISSUC ;EXIT WITH SUCCESS 10$: CALLR IEFHE ;FATAL HARDWARE ERROR INTM4: INTP2: INTP6: TST RSR(R0) ;ANY ERRORS? BMI 10$ ;IF MI YES BIT #RECOM,RSR(R0) ;REJECT COMPLETION? BNE 20$ ;IF NE YES BIT #DTORDY,RSR(R0) ;DATA OUTPUT READY? BNE 40$ ;IF NE YES CALLR PRCRX ;RECONNECT FOR RECEPTION AND EXIT 10$: BIT #PAR,(R0) ;IS IT PARITY ERROR ? BNE 20$ ;IF NE YES NOP 20$: CALL PRCRX ;RECONNECT FOR RECEPTION MOVB R2,U.CW2(R5) ;MOVE STATE TO AS BEFORE. RETURN ; 40$: TST R2 ;IS HANDLER STATE -4 ? BGE 60$ ;IF GE NO, GIVE FLAGS WORD TO TASK TST RDDB(R0) ; CALLR PRATF ;ACCEPT TRANSFER 60$: MOV U.BUF(R5),-(SP) ;SAVE BUFFER ADDR & COUNT. MOV U.BUF+2(R5),-(SP) ; MOV U.CNT(R5),-(SP) ; MOV U.TRSB(R5),U.BUF(R5) ;LOAD TRIGGER STATUS BLOCK ADDRESS MOV U.TRSB+2(R5),U.BUF+2(R5) ; MOV #4,U.CNT(R5) ;LOAD A BIG ENOUGH COUNT. CMP R2,#2 ;IS THE STATUS=2? BEQ 70$ ;IF EQ YES MOV #&377,R2 ; STATE 6 ==> STATUS IE.DAO 70$: ASRB R2 ; MOV (R0),R3 ;GET CONTENTS OF RCR BIC #^C,R3 ;ISOLATE TRANSMITTER ID. BIS R3,R2 ;MERGE WITH STATUS. MOV R2,-(SP) ;GET FIRST STATUS WORD CALL $PTWRD ;PUT IN USERS BUFFER MOV RDDB(R0),-(SP) ;GET SECOND STATUS WORD CALL $PTWRD ;PUT IN USERS BUFFER MOV (SP)+,U.CNT(R5) ;RESTORE COUNT AND BUFFER ADDRESS MOV (SP)+,U.BUF+2(R5) ; MOV (SP)+,U.BUF(R5) ; MOVB #4,U.CW2(R5) ;SET STATE TO 4. BIS #IE,(R0) ;REENABLE INTERRUPTS. MOV U.TEF(R5),R0 ;GET TRIGGER EVENT FLAG NO. MOV U.TASK(R5),R5 ;GET TCB ADDR FOR CONNECTED TASK. BEQ 90$ ;IF EQ NONE CALL $CEFI ;CONV EVENT FLAG TO MASK & ADDR. BCS 90$ ;IF CS NO FLAG SPECIFIED BIS R0,(R1) ;SET FLAG 90$: CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT. INTM2: TST RSR(R0) ;ANY ERRORS? BMI M2ERR ;IF MI YES TSTB RSR(R0) ;SUCCESSFUL TRANSFER? BPL M2PAR ;IF PL NO M2SUC: MOV (R0),R2 ;GET CONTENTS OF RCR. BIC #^C,R2 ;RETRIEVE TRANSMITTER ID. BIS #IS.SUC,R2 ;MERGE IN RETURN STATUS BIT #RECOM,RSR(R0) ;REJECT COMPLETE? BEQ 10$ ;IF EQ NO INC R2 ; +2 FOR TRUNCATED RECEPTION 10$: MOV RDBC(R0),R1 ;COMPUTE LENGTH OF RECEPTION. ADD U.CNT(R5),R1 ; MOV U.BUF(R5),-(SP) ;SAVE U.BUF MOV U.BUF+2(R5),-(SP) ;SAVE U.BUF+2 MOV U.CNT(R5),-(SP) ;SAVE U.CNT MOV U.BUF1(R5),U.BUF(R5) ;RELOCATION BIAS ==> UCB BEQ 20$ ;IF EQ ZERO MOV U.BUF1+2(R5),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB BR 30$ ;GO MOVE THE REGISTERS ; ; RELOCATION BIAS = 0 CHECK FOR NON-ZERO 16-BIT ADDRESS ; 20$: MOV U.BUF1+2(R5),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB BEQ 40$ ;IF EQ NO RETURN ADDRESS ; ; REGISTERS REQUESTED - RETURN THEM ; 30$: MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER ; ; CONTINUE PROCESSING ; 40$: MOV (SP)+,U.CNT(R5) ;RESTORE U.CNT MOV (SP)+,U.BUF+2(R5) ;RESTORE U.BUF+2 MOV (SP)+,U.BUF(R5) ;RESTORE U.BUF CALL PRCRX ;RECONNECT FOR RECEPTION MOV R2,R0 ;COPY STATUS CODE CALLR IODON ;FINISH I/O AND EXIT M2ERR: MOV RSR(R0),R1 ;GET CONTENTS OF RSR BIT #BCOFL,R1 ;CHECK FOR BYTE COUNT BNE 10$ ;IF NE OVERFLOW BIT #PAR!TXMERR,R1 ;PARITY OR TRANSMISSION ERROR? BNE M2PAR ;IF NE YES BIT #TIMOUT,R1 ;CHECK FOR TIME OUT. BNE M2TIME ;IF NE YES BIT #MEMOFL!NEXLOC,R1 ;NEM OR OVERFLOW? BNE M2OFL ;IF NE YES CALLR IEBBE ;INDICATE TRANSMISSION ERROR ; ; BYTE COUNT OVERFLOW ; 10$: BIC #BCOFL,RSR(R0) ;CLEAR ERROR CONDITION. BIS #REJ!IE,(R0) ;TRUNCATE MESSAGE RETURN ; ; ; PARITY OR TRANSMISSION ERROR ; M2PAR: CALL PRCRX ;RECONNECT FOR RECEPTION BR IEBBE ;FLAG IE.BBE ; ; RECEIVER TIMEOUT ; M2TIME: CALL PRCRX ;RECONNECT FOR RECEPTION BR IEDNR ;FLAG DEVICE NOT READY ; ; NONEXISTENT LOCATION OR MEMORY OVERFLOW. ; M2OFL: CALL PRCRX ;RECONNECT FOR RECEPTION BR IESPC ;INDICATE NONEXISTENT LOCATION INTP0: BIS #BDINIT,(R0) ;INITIALIZE BOARD. RETURN ; INTP4: CALL PRCRX ;RECONNECT FOR RECEPTION MOVB #6,U.CW2(R5) ;SET HANDLER STATE TO 6. RETURN ; ;+ ; **-LRCAN-CANCEL I/O SERVICE ROUTINE ; ; THIS ENTRY POINT IS ENTERED WHEN AN IO.KIL FUNCTION IS ; ISSUED REGARDLESS OF WHETHER THE DEVICE IS BUSY OR NOT. ; ; INPUTS: ; R0 = ADDRESS OF ACTIVE I/O PACKET (IF ANY) ; R1 = ADDRESS OF TCB OF CURRENT TASK ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; 1. IF TASK TERMINATION IS IN PROGRESS, THEN BOARD IS ; INITIALIZED & TASK (IF ANY) IS DISCONNECTED. ; 2. OTHERWISE, IF REQUEST IS OUTSTANDING, THEN TASK IS ; RECONNECTED FOR RECEPTION. ; 3. REGARDLESS OF RUN DOWN STATUS, IF REQUEST IS OUTSTANDING, ; THEN COMPLETION IS INDICATED WITH STS=IE.ABO. ;- LRCAN: CMP R1,U.TASK(R5) ;;;REQUEST FOR CONNECTED TASK? BNE 10$ ;;;IF NE NO MOV S.CSR(R4),R3 ;;;GET RCR ADDRESS. BIC #IE,(R3) ;;;DISABLE INTERRUPTS. MTPS #0 ;;;LOWER PRIORITY BITB #T2.HLT,T.ST2(R1) ;TASK BEING TERMINATED? BEQ 20$ ;IF EQ NO MOVB U.CW2(R5),R2 ;YES, RETRIEVE HANDLER STATE. CALL PRDRX ;DISCONNECT TASK TSTB R2 ;IS UNIT BUSY? BLT 30$ ;IF LT YES 10$: RETURN ; 20$: TSTB U.CW2(R5) ;IS UNIT BUSY? BGE 10$ ;IF GE YES CALL PRCRX ;ABORT OPERATION AND RECONNECT 30$: BR IEABO ; ;+ ; POWERFAIL AND TIMEOUT ;- LROUT: TSTB U.CW2(R5) ;IS TASK CONNECTED? BEQ 10$ ;IF EQ YES CALL PRCRX ;RECONNECT FOR RECEPTION 10$: BITB #US.BSY,U.STS(R5) ;IS THE UNIT BUSY? BEQ LRPWF ;IF EQ NO BR IEDNR ;YES, ABORT OUTSTANDING REQUEST LRPWF: RETURN ; ;+ ; PROCESS ERROR CONDITIONS AND CALL I/O DONE. ;- IEABO: MOV #IE.ABO&377,R0 ;ABORT TASK BR IODON ; IEBAD: MOV #IE.BAD&377,R0 ;BAD PARAMETERS BR IODON ; IEDAA: MOV #IE.DAA&377,R0 ;DEVICE ALREADY CONNECTED BR IODON ; IEBBE: MOV #IE.BBE&377,R0 ;BAD TRANSMISSION ERROR BR IODON ; IEDNA: MOV #IE.DNA&377,R0 ;DEVICE NOT AVAILABLE BR IODON ; IEDNR: MOV #IE.DNR&377,R0 ;DEVICE NOT READY BR IODON ; IEFHE: MOV #IE.FHE&377,R0 ;FATAL HARDWARE ERROR BR IODON ; IEIFC: MOV #IE.IFC&377p,R0 ;INVALID FUNCTION CODE BR IODON ; IENTR: MOV #IE.NTR&377,R0 ;TASK NOT TRIGGERED BR IODON ; IESPC: MOV #IE.SPC&377,R0 ;ILLEGAL BUFFER BR IODON ; IEVER: MOV #IE.VER&377,R0 ;PARITY OR HARD DEVICE ERROR BR IODON ; ISSUC: MOV #IS.SUC&377,R0 ;SUCCESSFUL OPERATION IODON: CALL $IOALT ;PROCESS I/O DONE JMP LRINI ;AND TRY FOR MORE .END p$NðskQ ›c, .TITLE LTDRV .IDENT /05/ ; COPYRIGHT (C) 1979 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; DGITAL EQUIPMENT OF CANADA LTD, KANATA, ONTARIO ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 05 ; ; DAVID R. CROWE ; ; PREVIOUSLY MODIFIED BY: ; ; DAVID H. CHAN ; HELEN GORDON ; PATRICIA C. LEE ; ; ; MODIFIED BY: ; ; R. E. CALDWELL 21-AUG-79 ; ; RC010 -- FIX BUG IN CANCEL I/O ; AND USE CORRECT FORM OF GTPKT$. ; ; PARALLEL COMMUNICATION LINK (PCL) TRANSMITTER DRIVER FOR RSX-11M-PLUS. ; ; MACRO LIBRARY CALLS ; .MCALL PKTDF$,TCBDF$,UCBDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS. UCBDF$ ;DEFINE UCB OFFSETS ;+ ; STATE SETTINGS FOR 'STC' FUNCTION ;- SS.MAS = 1 ;MASTER STATE ;EVENT FLAG FEATURE AND SECONDARY STATE CAPABILITY HAVE BEEN REMOVED ;SS.SEC = 2 ;SECONDARY STATE SS.NEU = 4 ;NEUTRAL STATE ;+ ; MODE SETTINGS FOR 'STC' FUNCTION ;- MS.AUT = 20 ;AUTO ADDRESS MS.ADS = 40 ;ADDRESS SILO ;+ ; CHARACTERISTIC WORD USAGE. ; U.CW2 IS USED BY THE HANDLER AS FOLLOWS: ; BITS 7-0 CONTAIN NUMBER OF RETRIES TO BE PERFORMED AFTER CURRENT ; TRY IF NECESSARY. ;- ;+ ; HANDLER UCB WORK AREA OFFSET DEFINITIONS. ;- U.EFN = U.CNT+2 ;'NOWMST' EVENT FLAG NUMBER U.TCB = U.EFN+2 ;TCB ADDRESS OF EVENT FLAG REQUESTOR U.BUF1 = U.TCB+2 ;RELOCATION BIAS FOR RETURN REG. BUFFER ;+ ; THE HARDWARE REGISTERS ARE DEFINED RELATIVE TO THE TCR, WHOSE ; ADDRESS IS FOUND IN THE S.CSR FIELD OF THE SCB AT RUN TIME. ;- TCR = 0 ;TRANSMITTER COMMAND REGISTER. TSR = 2 ;TRANSMITTER STATUS REGISTER. TSDB = 4 ;TRANSMITTER SOURCE DATA BUFFER. TSBC = 6 ;TRANSMITTER SOURCE BYTE COUNT. TSBA = 10 ;TRANSMITTER SOURCE BUS ADDRESS. TMMR = 12 ;TRANSMITTER MASTER/MAINTENANCE REG. TSCRC = 14 ;TRANSMITTER SOURCE CRC ;+ ; TRANSMITTER COMMAND REGISTER (TCR). ;- RIB = 100000 ;RETRY IF BUSY (R/W). TXNPR = 40000 ;TRANSMITTER NPR (R/W). SNDWD = 20000 ;SEND WORD (R/W). DC04 = 10000 ;DESTINATION CODE BITS (R/W). DC03 = 4000 ; " DC02 = 2000 ; " DC01 = 1000 ; " DC00 = 400 ; " RDSILO = 200 ;READ SILO (R/W). IE = 100 ;INTERRUPT ENABLE (R/W). A17 = 40 ;EXTENDED ADDRESS BITS (R/W). A16 = 20 ; " DTORDY = 10 ;DATA OUTPUT READY (RO). INHADI = 4 ;INHIBIT ADDRESS INCREMENT (R/W). BDINIT = 2 ;BOARD INITIALIZE (WO). STTXM = 1 ;START TRANSMISSION (R/W). DC = DC04!DC03!DC02!DC01!DC00 ;UNION OF DESTINATION CODE BITS. ;+ ; TRANSMITTER STATUS REGISTER (TSR). ;- ERR = 100000 ;ERROR (RO). NEXLOC = 40000 ;NONEXISTENT LOCATION (RO). MEMOFL = 20000 ;MEMORY OVERFLOW (R/W). TXMERR = 10000 ;TRANSMISSION ERROR (R/W). MSTDWN = 4000 ;MASTER DOWN (R/W). TIMOUT = 2000 ;TIME OUT (R/W). OVERUN = 1000 ;OVERRUN (R/W). DTIRDY = 400 ;DATA INPUT READY (RO). SUCTXF = 200 ;SUCCESSFUL TRANSFER (R/W). BUSY = 100 ;BUSY (RO). SORE = 40 ;SOFTWARE REJECT (R/W). TDMBSY = 20 ;TDM BUS BUSY (R/W). RSPB1 = 10 ;RESPONSE B1 (RO). RSPB0 = 4 ;RESPONSE B0 (RO). RSPA1 = 2 ;RESPONSE A1 (RO). RSPA0 = 1 ;RESPONSE A0 (RO). ;+ ; TRANSMITTER MASTER/MAINTENANCE REGISTER (TMMR). ;- ; LOW ORDER BYTE (TMMR+0). TXMAD4 = 20 ;TRANSMITTER ADDRESS BITS (R/W). TXMAD3 = 10 ; " TXMAD2 = 4 ; " TXMAD1 = 2 ; " TXMAD0 = 1 ; " ; HIGH ORDER BYTE (TMMR+1). AOPRDY = 200 ;ADDRESS OUTPUT READY (RO). AIPRDY = 100 ;ADDRESS INPUT READY (RO). CLRADR = 40 ;CLEAR ADDRESS SILO (WO). AUTADR = 20 ;AUTO ADDRESS (R/W). CHNOPN = 10 ;CHANNEL OPEN (RO). NOWMST = 4 ;NOW MASTER (R/W). SEC = 2 ;SECONDARY MASTER (R/W). MASTER = 1 ;MASTER (R/W). ;+ ; PAD TRANSMITTER ID ;- PAD = 31. ;PAD TRANSMITTER ID ;+ ; DEVICE DISPATCH TABLE ;- DDT$ LT,L$$T11,,CHK ;GENERATE DISPATCH TABLE ;+ ; LOCAL IMPURE DATA TABLES ;- PRVAL: .BLKW L$$T11 ;PREVIOUS VALUE ASCNT: .BLKW L$$T11 ;ADDRESS SILO COUNTER LFVAL: .BLKW L$$T11 ;VALUES LEFT IN USER BUFFER FRVAL: .BLKW L$$T11 ;FIRST VALUE IN SILO ;+ ; LTCHK - PCL TRANSMITTER DRIVER PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS RECEIVED FOR THE PARALLEL COMMUNICATIONS LINK TRANSMITTER. SOME ; PCL TRANSMITTER REQUESTS CONTAIN INFORMATION THAT MUST BE CHECKED IN ; THE CONTEXT OF THE ISSUING TASK; THEREFORE, THE I/O REQUEST IS NOT ; QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1 = ADDRESS OF THE I/O PACKET ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; ; OUTPUTS: ; ; IF THE QIO FUNCTION IS IO.STC THEN NO PRIOR ADDRESS CHECKING HAS ; BEEN PERFORMED BY THE SYSTEM BECAUSE IO.STC IS CLASSED AS A CONTROL ; FUNCTION. IT IS THEREFORE NECESSARY TO FIRST MOVE ALL THE ; PARAMETERS SO THAT THE ADDRESS DOUBLEWORD FOR THE DATA BUFFER MAY ; BE MOVED TO I.PRM AND I.PRM+2 AFTER IS HAS BEEN ADDRESS CHECKED ; AND RELOCATED. IF THE LENGTH OF THE DATA BUFFER IS ZERO, THE ; ADDRESS CHECK WILL NOT TAKE PLACE AND THE ZERO LENGTH BUFFER WILL ; BE CONSIDERED VALID. ; ; IF THE QIO FUNCTION IS IO.STC OR IO.ATX THEN THE RETURN BUFFER ; ADDRESS IS CHECKED TO DETERMINE WHETHER IT LIES WITHIN THE ; ISSUING TASK'S ADDRESS SPACE. IF IT DOES THEN THE RETURN BUFFER ; ADDRESS IS RELOCATED AND STORED IN THE I/O PACKET. IF IT IS NOT ; A VALID ADDRESS THEN AN ILLEGAL BUFFER STATUS IS RETURNED AS THE ; FINAL I/O STATUS OF THE REQUEST. ; ; FOR ALL FUNCTION CODES, THE I/O PACKET IS INSERTED IN THE ; CONTROLLER QUEUE AND THE DEVICE INITIATOR IS ENTERED TO START ; THE CONTROLLER. ;- LTCHK: CMP #IO.ATX,I.FCN(R1) ;IS FUNCTION CODE = 'ATX'? BEQ 30$ ;IE EQ YES CMP #IO.STC,I.FCN(R1) ;IS FUNCTION CODE = 'STC'? BNE 60$ ;IF NE NO ; ; 'STC' FUNCTION - MOVE ALL PARAMETERS TO MAKE WAY FOR DATA BUFFER ; ADDRESS DOUBLEWORD ; 10$: MOV R1,R3 ;SAVE ADDRESS OF THE I/O PACKET MOV I.PRM+12(R3),I.PRM+14(R3) ;MOVE RETURN BUFFER ADDRESS MOV I.PRM+10(R3),I.PRM+12(R3) ;MOVE EVENT FLAG NUMBER MOV I.PRM+6(R3),I.PRM+10(R3) ;MOVE MODE MOV I.PRM+4(R3),I.PRM+6(R3) ;MOVE STATUS MOV I.PRM+2(R3),I.PRM+4(R3) ;MOVE LENGTH OF BUFFER BEQ 30$ ;IF EQ LENGTH = 0 BLT 15$ ;IF LT INVALID BUFFER LENGTH ; ; SET UP REGISTERS FOR ADDRESS CHECK AND RELOCATION ; MOV I.PRM(R3),R0 ;DATA BUFFER ADDRESS ==> R0 MOV I.PRM+2(R3),R1 ;LENGTH ==> REG 1 CALL $ACHCK ;CHECK THE LENGTH BCS 15$ ;IF CS, ERROR MOV W.BATT(R2),R2 ;PICK UP ATTACHMENT DESC. ADDR. INCB A.IOC(R2) ;LOCK REGION MOV R2,I.AADA(R3) ;SAVE PTR IN PKT FOR $IODONE BR 20$ ;CONTINUE ; ; INVALID BUFFER ; 15$: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS CALLR $IOFIN ;CALL FINISH I/O OPERATION AND EXIT ; ; RELOCATE THE DATA BUFFER ADDRESS ; 20$: CALL $RELOC ;GO RELOCATE THE DATA BUFFER ADDRESS MOV R1,I.PRM(R3) ;SET RELOCATION BIAS MOV R2,I.PRM+2(R3) ;SET 16-BIT ADDRESS BR 40$ ;GO CHECK RETURN BUFFER ADDRESS ; ; 'STC' OR 'ATX' FUNCTION ; 30$: MOV R1,R3 ;SAVE I/O PACKET 40$: MOV I.PRM+14(R3),R0 ;GET VIRTUAL ADDRESS OF RETURN BUFFER MOV #14.,R1 ;SET LENGTH OF RETURN BUFFER TO 7 WORDS CALL $ACHCK ;CHECK THE ADDRESS BCS 15$ ;IF CS BAD MOV W.BATT(R2),R2 ;PICK UP ATTACHMENT DESC. ADDR. INCB A.IOC(R2) ;LOCK REGION MOV R2,I.AADA+2(R3) ;SAVE PTR IN PKT FOR $IODONE ; ; RELOCATE THE RETURN BUFFER ADDRESS ; CALL $RELOC ;RELOCATE USER BUFFER MOV R1,I.PRM+14(R3) ;SET RELOCATION BIAS OF RETURN BUFFER MOV R2,I.PRM+16(R3) ;SET 16-BIT ADDRESS OF RETURN BUFFER MOV R3,R1 ;COPY I/O PACKET ADDRESS ; ; INSERT THE I/O PACKET IN THE QUEUE ; 60$: MOV R4,R0 ;SET R0 = I/O QUEUE LISTHEAD CALL $QINSP ;GO INSERT PACKET IN QUEUE ; ; GET THE QUEUED I/O PACKET ; LTINI: GTPKT$ LT,L$$T11,,,T ;GET I/O PACKET MACRO ; ; ANALYZE THE CONTENTS OF THE I/O PACKET ; ; R1 = I/O PACKET ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB ; R3 = CONTROLLER INDEX ; R4 = STATUS CONTROL BLOCK ; R5 = UNIT CONTROL BLOCK ; ; I/O REQUEST PACKET FORMAT ; ; WD.00 = I/O QUEUE THREAD WORD ; WD.01 = REQUEST PRIORITY, EVENT FLAG NUMBER ; WD.02 = TSB ADDRESS OF REQUESTER TASK ; WD.03 = POINTER TO 2ND LUN WORD IN REQUESTER TASK HEADER ; WD.04 = CONTENTS OF 1ST LUN WORD IN REQUESTER TASK HEADER ; WD.05 = I/O FUNCTION CODE ; WD.06 = VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WD.07 = RELOCATION BIAS OF I/O STATUS BLOCK ; WD.10 = I/O STATUS BLOCK ADDRESS ; WD.11 = VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WD.12 = RELOCATION BIAS OF DATA BUFFER ; WD.13 = 16-BIT ADDRESS OF DATA BUFFER ; WD.14 = LENGTH OF DATA BUFFER ; WD.15 = FLAG WORD OR STATE ; WD.16 = ID OR MODE ; WD.17 = NUMBER OF RETRIES OR EVENT FLAG NUMBER ; WD.20 = RELOCATION BIAS OF RETURN BUFFER ; WD.21 = 16-BIT ADDRESS OF RETURN BUFFER ; TST U.EFN(R5) ;WAS EFN FOR 'NOWMST' SPECIFIED? BEQ 5$ ;IF EQ NO MOV S.CSR(R4),R0 ;YES, RETREIVE CSR ADDRESS BIS #IE,(R0) ;ENABLE INTERRUPTS 5$: MOV I.TCB(R1),R0 ;GET REQUESTER TCB ADDRESS. BITB #T2.ABO,T.ST2(R0) ;IS TASK BEING ABORTED? BEQ 10$ ;IF EQ NO CALLR IEVER ;YES, REJECT REQUEST ; ; DISPATCH PACKET FOR PROCESSING ACCORDING TO FUNCTION CODE ; 10$: CMP #IO.ATX,I.FCN(R1) ;IS IT 'ATX' FUNCTION? BEQ ATX ;IF EQ YES CMP #IO.SEC,I.FCN(R1) ;IS IT 'SEC' FUNCTION? BEQ IOSEC ;IF EQ YES CMP #IO.STC,I.FCN(R1) ;IS IT 'STC' FUNCTION? BEQ STC ;IF EQ YES CALLR IEIFC ;INVALID FUNCTION CODE ;+ ; PROCESS 'ATX' FUNCTION ; ; REQUIRED INPUTS: ; R1 = I/O PACKET ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB ; R3 = CONTROLLER INDEX ; R4 = STATUS CONTROL BLOCK ; R5 = UNIT CONTROL BLOCK ;- ATX: ;REF LABEL .IF DF M$$EXT CALL $STMAP ;SET UP UNIBUS MAP ADDRESS CALL $MPUBM ;MAP UNIBUS TO MEMORY MOV S.PKT(R4),R1 ;RESTORE REG 1 .ENDC CMPB I.PRM+11(R1),#DC/400 ;CPU ID > MAXIMUM? BHI LTBAD ;IF HI YES TSTB I.PRM+11(R1) ;CPU ID = 0? BEQ LTBAD ;IF EQ YES TSTB I.PRM+13(R1) ;RETRY COUNT > 255? BNE LTBAD ;IF NE YES MOVB I.PRM+12(R1),U.CW2(R5) ;SAVE RETRY COUNT BYTE. ; ; SET UP RETURN REGISTER BUFFER ADDRESS IN UCB ; MOV I.PRM+14(R1),U.BUF1(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+16(R1),U.BUF1+2(R5) ;16-BIT ADDRESS==> UCB RETRY: MOV S.CSR(R4),R0 ;GET DEVICE ADDRESS (TSR). MOV #BDINIT,(R0) ;BOARD INITIALIZE. MOV I.PRM+6(R1),TSDB(R0) ;MOVE FLAGS WORD TO DATA SILO. MOV U.BUF+2(R5),TSBA(R0) ;SET UP BUFFER ADDRESS. MOV U.CNT(R5),R2 ;GET BYTE COUNT NEG R2 ;NEGATE IT. MOV R2,TSBC(R0) ;PUT IT IN PCL REGISTER. MOVB I.PRM+11(R1),TCR+1(R0) ;SET CPU ID. BIS #RIB!TXNPR!SNDWD!IE!STTXM,U.BUF(R5) ;SET EXTENDED BIS U.BUF(R5),(R0) ;ADDR & GO BITS IN TCR. MOVB S.ITM(R4),S.CTM(R4) ;- SET TIME OUT RETURN ; LTBAD: CALLR IEBAD ;BAD PARAMETERS ;+ ; PROCESS 'SEC' FUNCTION ; ; REQUIRED INPUTS: ; R4 = STATUS CONTROL BLOCK ;- IOSEC: MOV S.CSR(R4),R0 ;GET DEVICE ADDRESS MOV TMMR(R0),R1 ;MOVE SECOND WORD FOR IOSB TO R1 MOV #IS.SUC&377,R0 ;GET SUCCESS STATUS CODE CALL $IODON ;GO EXIT THIS REQUEST BR LTINI ;GO LOOK FOR MORE WORK ;+ ; PROCESS 'STC' FUNCTION ; ; REQUIRED INPUTS: ; R1 = I/O PACKET ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB ; R3 = CONTROLLER INDEX ; R4 = STATUS CONTROL BLOCK ; R5 = UNIT CONTROL BLOCK ;- STC: MOV I.TCB(R1),R0 ;GET TASK'S TCB ADDRESS BIT #T3.PRV,T.ST3(R0) ;IS THE TASK PRIVLEGED? BEQ 35$ ;IF EQ NO TST I.PRM+6(R1) ;'STATE' SPECIFIED? BEQ 10$ ;IF EQ NO CMP #SS.MAS,I.PRM+6(R1) ;IS IT 'MASTER'? BEQ 10$ ;IF EQ YES ;EVENT FLAG FEATURE AND SECONDARY STATE CAPABILITY HAVE BEEN REMOVED ; CMP #SS.SEC,I.PRM+6(R1) ;IS IT 'SECONDARY'? ; BEQ 10$ ;IF EQ YES CMP #SS.NEU,I.PRM+6(R1) ;IS IT 'NEUTRAL'? BNE LTBAD ;IF NE NO, BAD PARAMETERS ; ; VALIDATE THE 'MODE' PARAMETER ; 10$: TST I.PRM+10(R1) ;'MODE' SPECIFIED? BEQ 20$ ;IF EQ NO CMP #MS.AUT,I.PRM+10(R1) ;IS 'AUTO' SPECIFIED? BEQ 20$ ;IF EQ YES CMP #MS.ADS,I.PRM+10(R1) ;IS 'ADDRESS SILO' SPECIFIED? BNE LTBAD ;IF NE NO, BAD PARAMETERS ; ;EVENT FLAG FEATURE AND SECONDARY STATE CAPABILITY HAVE BEEN REMOVED ; VALIDATE THE EVENT FLAG NUMBER ; 20$: BR 40$ ; TST I.PRM+12(R1) ;EVENT FLAG > 0? ; BLE 30$ ;IF LE NO ; CMP #96.,I.PRM+12(R1) ;IS IT > 96? ; BGT 40$ ;IF GT NO 30$: CALLR IEIEF ;INVALID EVENT FLAG 35$: CALLR IEPRI ;PRIVLEGE VIOLATION ; ; VALIDATE THE SIZE AND CONTENTS OF THE DATA BUFFER ; 40$: TST I.PRM+4(R1) ;IS SIZE OF BUFFER > OR = 0? BLT 54$ ;IF LT NO BEQ 60$ ;IF EQ SIZE=0 ; ; INITIALIZE VALUES FOR LOOPING THROUGH BUFFER ; MOV #50.,ASCNT(R3) ;SAVE MAX NUMBER OF VALUES ALLOWED CMP I.PRM+4(R1),ASCNT(R3) ;IS # OF VALUES > MAXIMUM? BGT 54$ ;IF GT YES CLR PRVAL(R3) ;INITIALIZE PREVIOUS VALUE TO ZERO MOV I.PRM+4(R1),LFVAL(R3) ;GET # OF VALUES MOV I.PRM(R1),U.BUF(R5) ;GET RELOCATION BIAS MOV I.PRM+2(R1),U.BUF+2(R5) ;GET VITUAL ADDRESS ; ; CHECK ALL VALUES IN THE BUFFER FOR WITHIN VALID RANGE ; ; PRVAL(R3) = PREVIOUS VALUE ; ASCNT(R3) = # VALUES STILL POSSIBLE TO ADD TO SILO ; LFVAL(R3) = # VALUES STILL IN USER BUFFER ; 50$: CALL $GTBYT ;RETRIEVE NEXT BYTE ON THE STACK TSTB (SP) ;IS VALUE > 0? BEQ 51$ ;IF EQ NO CMPB (SP),#DC/400 ;IS VALUE > MAXIMUM? BLE 52$ ;IF LE NO 51$: MOVB (SP)+,PRVAL(R3) ;CLEAN UP THE STACK BR 54$ ;INVALID DATA BUFFER ; ; CHECK FOR PAD VALUE NEEDED ; 52$: CMPB (SP),PRVAL(R3) ;IS IT = LAST VALUE? BNE 53$ ;IF NE NO DEC ASCNT(R3) ;DECREMENT MAXIMUM VALUES ALLOWED ; ; DECREMENT COUNTERS AND SAVE PREVIOUS VALUE ; 53$: MOVB (SP)+,PRVAL(R3) ;SAVE THIS VALUE AS PREVIOUS DEC ASCNT(R3) ;DECREMENT MAXIMUM VALUES ALLOWED BGE 55$ ;IF GE STILL WITHIN LIMITS 54$: CALLR IESPC ;ILLEGAL BUFFER FORMAT ; ; DECREMENT NUMBER OF BYTES STILL IN USER BUFFER AND GO GET NEXT BYTE ; 55$: DEC LFVAL(R3) ;DECREMENT # BYTES YET TO CHECK BGT 50$ ;IF GT GET NEXT ; ; ALL PARAMETERS ARE VALID - PROCESS THE REQUEST ; 60$: BR 70$ ; TST U.TCB(R5) ;HAS A TASK REQUESTED AN EVENT FLAG? ; BEQ 62$ ;IF EQ NO ; CMP I.TCB(R1),U.TCB(R5) ;IS THIS THE SAME REQUESTOR? ; BEQ 61$ ;IF EQ YES ; CALLR IEFLG ;EVENT FLAG ALREADY SPECIFIED ; ; DECREMENT I/O COUNT FOR PREVIOUS EVENT FLAG ; ;61$: MOV U.TCB(R5),R0 ;GET PREVIOUS REQUESTOR ; DECB T.IOC(R0) ;DECREMENT REQUESTOR'S I/O COUNT ;; ; SET UP TCB & EVENT FLAG ; ;62$: MOV I.PRM+12(R1),U.EFN(R5) ;SET UP EVENT FLAG NUMBER ; BNE 63$ ;IF NE NON-ZERO EVENT FLAG ; CLR U.TCB(R5) ;ZERO REQUESTORS TCB ; BR 70$ ;GO PROCESS NEXT PARAMETER ; ; EVENT FLAG HAS BEEN SPECIFIED, SETUP TCB IN UCB AND INCREMENT ; I/O COUNT. ; ;63$: MOV I.TCB(R1),R0 ;SAVE REQUESTORS TCB ; MOV R0,U.TCB(R5) ; ; INCB T.IOC(R0) ;LOCK DOWN TASK ; ; INITIALIZE BASE REGISTER ADDRESS ; 70$: MOV S.CSR(R4),R0 ;TSR ==> REG 0 TST I.PRM+6(R1) ;WAS A 'STATE' SPECIFIED? BEQ 80$ ;IF EQ NO CMP #SS.MAS,I.PRM+6(R1) ;IS MASTER STATE DESIRED? BNE 71$ ;IF NE NO MOV #MASTER,ASCNT(R3) ;SET MASK FOR MASTER BR 73$ ;GO CHANGE TMMR 71$: ; CMP #SS.SEC,I.PRM+6(R1) ;IS SECONDARY STATE DESIRED? ; BNE 72$ ;IF NE NO ; MOV #SEC,ASCNT(R3) ;SET MASK FOR SECONDARY ; BR 73$ ;GO CHANGE TMMR 72$: CLR ASCNT(R3) ;SET NEUTRAL MASK 73$: MOVB TMMR+1(R0),PRVAL(R3);GET HIGH ORDER BYTE OF TMMR BICB #MASTER!SEC,PRVAL(R3) ;CLEAR PREVIOUS STATE BISB ASCNT(R3),PRVAL(R3) ;SET NEW STATE MOVB PRVAL(R3),TMMR+1(R0) ;STORE NEW HIGH ORDER BYTE MOVB TMMR+1(R0),PRVAL(R3) ;GET NEW HIGH ORDER BYTE AGAIN BICB #374,PRVAL(R3) ;CLEAR ALL BUT DESIRED BITS CMPB ASCNT(R3),PRVAL(R3) ;IS ACTUAL = DESIRED? BEQ 80$ ;IF EQ YES ; ; NOT DESIRED STATE - CHECK FOR VALID EXCEPTION (SECONDARY==>MASTER) ; BITB #MASTER,PRVAL(R3) ;IS IT NOW MASTER? BNE 80$ ;IF NE YES CALLR IEVER ;HARDWARE REJECTED STATE ; ; SET UP ADDRESS SILO ; 80$: TST I.PRM+4(R1) ;IS LENGTH OF DATA BUFFER = 0? BEQ 90$ ;IF EQ YES MOVB TMMR+1(R0),PRVAL(R3);RETRIEVE HIGH ORDER BYTE OF TMMR BISB #CLRADR!AUTADR,PRVAL(R3) ;CLEAR SILO AND SET AUTO ADRS MOVB PRVAL(R3),TMMR+1(R0) ;STORE NEW HIGH ORDER BYTE ; ; REINITIALIZE UCB FOR THE DATA TRANSFER ; MOV I.PRM(R1),U.BUF(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+2(R1),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB CLR ASCNT(R3) ;ZERO ADDRESS SILO ENTRY COUNTER CLR PRVAL(R3) ;SET PREVIOUS VALUE TO ZERO MOV I.PRM+4(R1),LFVAL(R3) ;INITIALIZE DATA BUFFER COUNTER ; ; MOVE EACH BYTE OF THE DATA BUFFER TO THE ADDRESS SILO ; ; PRVAL(R3) = PREVIOUS VALUE ; ASCNT(R3) = ADDRESS SILO COUNTER ; LFVAL(R3) = # BYTES STILL IN DATA BUFFER ; FRVAL(R3) = FIRST VALUE IN SILO ; 81$: CALL $GTBYT ;RETRIEVE A BYTE FROM USER BUFFER CMPB (SP),PRVAL(R3) ;IS IT = PREVIOUS? BNE 82$ ;IF NE NO MOVB #PAD,TMMR(R0) ;INSERT A PAD VALUE INC ASCNT(R3) ;INCREMENT ADDRESS SILO ENTRY COUNTER 82$: MOVB (SP),PRVAL(R3) ;SAVE THIS VALUE AS PREVIOUS TST ASCNT(R3) ;IS THIS FIRST BYTE? BGT 83$ ;IF GT NO MOVB (SP),FRVAL(R3) ;SAVE FIRST VALUE 83$: MOVB (SP)+,TMMR(R0) ;INSERT THE USER VALUE IN SILO INC ASCNT(R3) ;INCREMENT ADDRESS SILO COUNTER DEC LFVAL(R3) ;DECREMENT # BYTES YET TO MOVE BGT 81$ ;IF GT GET NEXT BYTE CMP #20.,ASCNT(R3) ;HAVE AT LEAST 20 VALUES BEEN INSERTED? BLE 84$ ;IF LE YES ; ; LESS THAN THE MINIMUM NUMBER OF VALUES HAVE BEEN MOVED - REPEAT THE ; PATTERN AGAIN ; MOV I.PRM(R1),U.BUF(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+2(R1),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB MOV I.PRM+4(R1),LFVAL(R3) ;SET UP # BYTES TO MOVE BR 81$ ;GO MOVE THE VALUES ; ; ALL BYTES MOVED - CHECK FOR FIRST = LAST ; 84$: CMPB PRVAL(R3),FRVAL(R3) ;IS FIRST = LAST? BNE 90$ ;IF NE NO MOVB #PAD,TMMR(R0) ;MOVE A PAD VALUE TO SILO 90$: TST I.PRM+10(R1) ;WAS A MODE SPECIFIED? BEQ 100$ ;IF EQ NO MOVB TMMR+1(R0),PRVAL(R3);RETRIEVE HIGH BYTE OF TMMR CMP #MS.AUT,I.PRM+10(R1) ;AUTO ADDRESS SPECIFIED? BNE 91$ ;IF NE NO BISB #AUTADR,PRVAL(R3) ;SET AUTO ADDRESS BR 92$ ;GO RESTORE TMMR+1 ; ; ADDRESS SILO REQUESTED ; 91$: BICB #AUTADR,PRVAL(R3) ;CLEAR AUTO ADDRESS (IMPLIES SILO) 92$: MOVB PRVAL(R3),TMMR+1(R0);RESTORE HIGH BYTE OF TMMR 100$: MOV I.PRM+14(R1),U.BUF1(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+16(R1),U.BUF1+2(R5) ;16-BIT ADDRESS ==> UCB BEQ 110$ ;IF EQ NO CALL REGRET ;GO RETURN REGISTERS 110$: CALLR ISSUC ;INDICATE SUCCESS AND EXIT ;+ ; REGRET -- SERVICE ROUTINE TO RETURN THE CONTENTS OF THE TRANSMITTER ; SIDE REGISTERS TO THE USER BUFFER WHOSE ADDRESS IS SPECIFIED IN ; U.BUF1 AND U.BUF1+2 IN THE UCB. THE CONTROL REGISTER ADDRESS IS ; CONTAINED IN R0. U.BUF AND U.BUF+2 ARE PRESERVED ACROSS CALL. ;- REGRET: TST U.BUF1(R5) ;RELOCATION BIAS = 0? BNE 10$ ;IF NE NO TST U.BUF1+2(R5) ;IS 16 BIT ADDRESS = 0? BEQ 20$ ;IF EQ YES 10$: MOV U.BUF(R5),-(SP) ;SAVE U.BUF MOV U.BUF+2(R5),-(SP) ;SAVE U.BUF+2 MOV U.BUF1(R5),U.BUF(R5) ;GET RELOCATION BIAS MOV U.BUF1+2(R5),U.BUF+2(R5) ;GET VIRTUAL ADDRESS .REPT 7 MOV (R0)+,-(SP) ;GET WORD TO STORE CALL $PTWRD ;PUT WORD INTO BUFFER .ENDR MOV (SP)+,U.BUF+2(R5) ;RESTORE U.BUF+2 MOV (SP)+,U.BUF(R5) ;RESTORE U.BUF 20$: RETURN ; ;+ ; INTERRUPT SERVICE ROUTINE ;- .ENABL LSB $LTINT:: INTSV$ LT,PR5,L$$T11 ;;;EXECUTE INTERRUPT SAVE CODE MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS. MOV S.CSR(R4),R4 ;;;GET TCR ADDRESS. BIC #IE,(R4) ;;;DISABLE INTERRUPTS. BITB #US.BSY,U.STS(R5) ;;;IS UNIT BUSY? BEQ 10$ ;;;IF EQ NO TST TSR(R4) ;;;ERROR CONDITION? BPL 5$ ;;;IF PL, NO ERROR CALL $FORK ;;;CREATE A SYSTEM PROCESS JMP ERROR ;GO HANDLE ERRORS 5$: TSTB TSR(R4) ;;;SUCTXF? BMI 30$ ;;;IF MI YES BIT #SORE,TSR(R4) ;;;HAVE WE A SOFTWARE REJECT ? BNE 20$ ;;;IF NE YES 10$: ;EVENT FLAG FEATURE AND SECONDARY STATE CAPABILITY HAVE BEEN REMOVED ; BITB #NOWMST,TMMR+1(R4) ;;;HAVE WE BECOME MASTER? ; BNE 50$ ;;;IF NE YES BIS #BDINIT,(R4) ;;;TX INIT JUST IN CASE RETURN ;;;RETURN FOR MORE ; ; PROCESS SOFTWARE REJECT ; 20$: BIC #SORE,(R4) ;;;CLEAR THE INTERRUPTING BIT CALL $FORK ;;;CREATE FORK PROCESS MOV R4,R0 ;COPY CSR ADDRESS CALL REGRET ;RESTORE REGISTERS CALLR IEREJ ;REJECT REQUEST 30$: BIC #SUCTXF,TSR(R4) ;;;CLEAR THE INTERRUPTING BIT CALL $FORK ;;;CREATE FORK PROCESS MOV R4,R0 ;COPY CSR ADDRESS CALL REGRET ;RESTORE REGISTERS MOV #IS.SUC&377,R0 ;GET SUCCESS STATUS CODE BIT #SORE,TSR(R4) ;WAS TRANSMISSION TRUNCATED? BEQ 40$ ;IF EQ NO BIC #SORE,TSR(R4) ;CLEAR THE SORE BIP ALSO INC R0 ;BUMP STATUS TO IS.TNR 40$: MOV U.CNT(R5),R1 ;GET # OF BYTES TRANSFERED CALL $IODON ;FINISH I/O JMP LTINI ;TRY FOR MORE ;EVENT FLAG FEATURE AND SECONDARY STATE CAPABILITY HAVE BEEN REMOVED ; ; NOWMST INTERRUPT - SET EVENT FLAG ; ;50$: CALL $FORK ;;;CREATE FORK PROCESS ; MOV U.SCB(R5),R3 ;RETREIVE SCB ADDRESS ; MOVB S.CON(R3),R3 ;RETREIVE CONTROLLER INDEX ; MOVB TMMR+1(R4),PRVAL(R3) ;RETRIEVE TMMR+1 ; BICB #NOWMST,PRVAL(R3) ;CLEAR 'NOWMST' BIT ; MOVB PRVAL(R3),TMMR+1(R4) ;RESTORE TMMR+1 ; MOV R5,PRVAL(R3) ;SAVE REG 5 ; MOV U.EFN(R5),R0 ;EVENT FLAG # ==> R0 ; MOV U.TCB(R5),R5 ;REQUESTORS TCB ==> R5 ; BEQ 51$ ;IF EQ NONE ; CALL $CEFI ;GO CONSTRUCT EVENT FLAG MASK ; BCS 51$ ;IF CS NO EVENT SPECIFIED ; BIS R0,(R1) ;SET EVENT FLAG ; CALL $DRDSE ;DECLARE SIGNIFICANT EVENT ; DECB T.IOC(R5) ;UNLOCK TCB, EFN IS GOING AWAY ;51$: MOV PRVAL(R3),R5 ;RESTORE REG 5 ; CLR U.EFN(R5) ; ; CLR U.TCB(R5) ; ; RETURN ;RETURN TO INTERRUPTED PROGRAM .DSABL LSB ;+ ; WE HAVE AN ERROR CONDITION. WE WILL DETERMINE THE CAUSE OF THE ; ERROR AND TAKE THE APPROPRIATE ACTION AS FOLLOWS: ; ; OVERRUN = IE.BBE ; TIMEOUT = IE.DNR ; MASTER DOWN = IE.DNR ; XMIT ERROR ; RSP B = 00 = IE.DNR ; RSP B = 01,10,11 = IE.BBE ; MEM OVERFLOW = INCREMENT A16-17, CLEAR ERROR, ENABLE IE, ; SET STTXM ; NEM = SET BDINIT, IE.SPC ;- ERROR: MOV R4,R0 ;COPY CSR ADDRESS CALL REGRET ;RESTORE REGISTERS MOV TSR(R4),R1 ;GET CONTENTS OF TSR. BIT #OVERUN,R1 ;CHECK FOR OVER RUN. BNE 110$ ;IF NE OVERRUN BIT #MSTDWN,R1 ;CHECK FOR MASTER DOWN. BNE 130$ ;IF NE MASTER DOWN BIT #TIMOUT,R1 ;CHECK FOR TIME OUT. BNE 120$ ;IF NE TIMEOUT BIT #TXMERR,R1 ;CHECK FOR TRANSMISSION ERROR. BNE 140$ ;IF NE TRANSMISSION ERROR BIT #MEMOFL!NEXLOC,R1 ;OVERFLOW OR NEM? BNE 170$ ;IF NE YES BIS #BDINIT,(R4) ;INIT THE BOARD AGAIN RETURN ; ;+ ; PROCESS OVERRUN CONDITION ;- 110$: BIC #OVERUN,TSR(R4) ;CLEAR THE INTERRUPTING BIT CALLR IEBBE ;TRANSMISSION ERROR ;+ ; PROCESS TIMEOUT ;- 120$: BIC #TIMOUT,TSR(R4) ;CLEAR THE INTERRUPTING BIT CALLR IEDNR ;DEVICE NOT READY ;+ ; PROCESS MASTER DOWN. ;- 130$: BIC #MSTDWN,TSR(R4) ;CLEAR THE INTERRUPTING BIT MOV #IE.DNR&377,R0 ;GET DEVICE NOT READY CODE BR 150$ ;GO TRY FOR A RETRY ;+ ; PROCESS TRANSMISSION ERROR. ;- 140$: BIC #TXMERR,TSR(R4) ;CLEAR INT BIT BIT #RSPB1!RSPB0,R1 ;IF RSPB IS 00 BEQ 120$ ;IF EQ TREAT AS TIMEOUT MOV #IE.BBE&377,R0 ;GET TRANSMIT ERROR STATUS CODE 150$: MOV U.SCB(R5),R4 ;GET SCB ADDRESS MOV S.PKT(R4),R1 ;LOAD ADDRESS OF I/O PACKET DECB U.CW2(R5) ;DECREMENT RETRY COUNT. BGE 160$ ;IF GE RETRY CALLR IODON ;FINISH UP 160$: JMP RETRY ;GO TRY AGAIN ;+ ; PROCESS MEMORY OVERFLOW & NONEXISTENT LOCATION. ;- 170$: BIS #BDINIT,(R4) ;INITIALIZE BOARD. CALLR IESPC ;RETURN NON-EXISTANT ERROR ;+ ; CANCEL I/O OPERATION ; ; INPUTS: ; ; R0 = I/O PACKET ADDRESS ; R1 = TCB ADDRESS ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- LTCAN: MTPS #0 ;;;LOWER PRIORITY CMP R1,U.TCB(R5) ;DID THIS TASK ASK FOR AN EVENT FLAG? BNE 10$ ;IF NE NO DECB T.IOC(R1) ;UNLOCK TCB, EFN IS GOING AWAY CLR U.EFN(R5) ;CLEAR EVENT FLAG NUMBER CLR U.TCB(R5) ;CLEAR REQUESTORS TCB 10$: TSTB S.STS(R4) ;IS UNIT BUSY? ;IZ003 BEQ LTPWF ;IF EQ THEN YES ;IZ003 CMP R1,I.TCB(R0) ;IS CANCEL REQUEST FOR THE CURRENT TASK?;IZ003 BNE LTPWF ;IF NE, NO SIMPLY RETURN ;**-1 MOV #IE.ABO&377,R0 ;LOAD ABORT STATUS CODE BR ABORT ;ABORT THIS OPERATION LTPWF: RETURN ;NO, JUST RETURN ;+ ; TIMEOUT SERVICE ;- LTOUT: MOV #IE.DNR&377,R0 ;LOAD NOT READY STATUS CODE. ABORT: MOV S.CSR(R4),R2 ;GET TSR ADDRESS. BIS #BDINIT,(R2) ;INITIALIZE PCL TRANSMITTER. BR IODON ;FINISH I/O ;+ ; PROCESS ERROR CONDITIONS AND CALL I/O DONE ;- IEBAD: MOV #IE.BAD&377,R0 ;BAD PARAMETERS BR IODON ; IEBBE: MOV #IE.BBE&377,R0 ;TRANSMISSION ERROR BR IODON ; IEDNR: MOV #IE.DNR&377,R0 ;DEVICE NOT READY BR IODON ; IEFLG: MOV #IE.FLG&377,R0 ;EVENT FLAG ALREADY SPECIFIED BR IODON ; IEIEF: MOV #IE.IEF&377,R0 ;INVALID EVENT FLAG BR IODON ; ² IEIFC: MOV #IE.IFC&377,R0 ;INVALID FUNCTION CODE BR IODON ; IEPRI: MOV #IE.PRI&377,R0 ;PRIVLEGE VIOLATION BR IODON ; IEREJ: MOV #IE.REJ&377,R0 ;TRANSFER REJECTED BR IODON ; IESPC: MOV #IE.SPC&377,R0 ;INVALID PARAMETERS BR IODON ; IEVER: MOV #IE.VER&377,R0 ;PARITY ERROR BR IODON ; ISSUC: MOV #IS.SUC&377,R0 ;SUCCESSFUL OPERATION IODON: CALL $IOALT ;FINISH I/O JMP LTINI ;TRY FOR MORE .END ²ãXRkQ ›c, .TITLE DRSMG .IDENT /01.03/ ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ; BE USED OR COPIED ONLY IN ACCORDANCE WITH THE TERMS ; OF SUCH LICENSE. ; ; COPYRIGHT (c) 1981 BY DIGITAL EQUIPMENT CORPORATION. ; ALL RIGHTS RESERVED. ; ; VERSION 01.03 ; ; D. T. BROWN 30-DEC-80 ; ; PREVIOUSLY MODIFIED BY: ; ; MODIFIED BY: ; ; DAN BROWN 22-FEB-81 ; DTB001 -- FIX PROBLEMS WITH INCORRECT PRIVILEGE CHECKING ; AND INCORRECT STACK USAGE. ; ; M. S. HARVEY 16-JUL-81 ; MSH179 -- CLEAN UP CODE A BIT ; ; M. S. HARVEY 2-OCT-81 ; MSH192 -- REJECT DIRECTIVE IF SPECIFIED LUN IS ; ASSIGNED TO NON-MASS STORAGE DEVICE ; ; MACRO LIBRARY CALLS ; .MCALL EPKDF$ EPKDF$ ;DEFINE ERROR PACKET OFFSETS .IF DF E$$LOG ;+ ; **-$DRSMG-SEND MESSAGE ; ; THIS DIRECTIVE SENDS A MESSAGE TO A SYSTEM PROCESS. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(171.),DPB SIZE ; WD. 01 -- TARGET IDENTIFIER ; WD. 02 -- BUFFER ADDRESS ; WD. 03 -- BUFFER LENGTH ; WD. 04 -- BEGINNING OF TARGET SPECIFIC PARAMETER LIST ; ; PARAMETER LIST FOR TARGET IDENTIFIER SM.SER: ;DTB001 ; ;**-1 ; WD. 04 -- ERROR LOG PACKET TYPE CODE ; WD. 05 -- ERROR LOG PACKET SUBTYPE CODE ; WD. 06 -- LOGICAL UNIT NUMBER (OPTIONAL) ; WD. 07 -- CONTROL MASK WORD (OPTIONAL) ; ; INPUTS: ; ; R2=ADDRESS OF THE SECOND TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE NEXT WORD IN THE DIRECTIVE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS:  ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ;MSH179 ; C=1 IF DIRECTIVE IS REJECTED. ;MSH179 ; DIRECTIVE STATUS OF 'D.RS1' IS RETURNED IF THERE IS ;MSH179 ; NOT ENOUGH POOL, OR IF THE TOTAL MESSAGE ;MSH179 ; LENGTH IS GREATER THAN 512. BYTES. ;MSH179 ; DIRECTIVE STATUS OF 'D.RS5' IS RETURNED IF THE ;MSH192 ; SPECIFIED LUN IS ASSIGNED TO A NON-MASS ;MSH192 ; STORAGE DEVICE, OR IF THE LUN IS NOT ;MSH192 ; ASSIGNED. ;MSH192 ; DIRECTIVE STATUS OF 'D.RS7' IS RETURNED IF ERROR ;MSH179 ; LOGGING IS NOT ACTIVE AND PACKET CANNOT ;MSH179 ; BE QUEUED. ;MSH179 ; DIRECTIVE STATUS OF 'D.RS8' IS RETURNED IF AN ;MSH179 ; INVALID MESSAGE TARGET IS SPECIFIED. ;MSH179 ; DIRECTIVE STATUS OF 'D.RS16' IS RETURNED IF THE ;MSH179 ; ISSUING TASK IS NOT PRIVILEGED. ;MSH179 ; DIRECTIVE STATUS OF 'D.RS99' IF THE SIZE OF THE ;MSH179 ; DPB IS INVALID. ;MSH179 ;- ;**-12 $DRSMG:: ; ; CHECK THE TARGET CODE ; MOVB -(R3),R0 ;GET THE DPB SIZE ;MSH179 CMPB (R3)+,#6. ;DPB OF MINIMUM LENGTH? ;MSH179 BHIS 10$ ;IF HIS YES ;MSH179 DRSTS D.RS99 ;DPB HAS INVALID DPB LENGTH ;MSH179 ;MSH179 10$: CMP (R3)+,#SM.SER ;IS THE TARGET ERROR LOGGING? ;MSH179 BEQ 30$ ;IF EQ YES ;MSH179 20$: DRSTS D.RS8 ;INVALID TARGET OR INCORRECT FLAGS ;MSH179 ; ;**-6 ; OBTAIN THE CONTROL MASK WORD ; 30$: MOV #SM.HDR!SM.TSK,-(SP) ;INITIALIZE THE FLAGS TO USE ;MSH179 CMPB R0,#8. ;CHECK IF A CONTROL MASK WORD EXISTS ;**-1 BLO 40$ ;IF LO THERE IS NO CONTROL MASK WORD ;MSH179 BIS 12(R3),(SP) ;OBTAIN THE CONTROL MASK WORD ;**-1 ; ; CHECK THE CONTROL MASK WORD FOR VALIDITY ; BIT #SM.DID!SM.DOP!SM.DAC!SM.DAT,(SP) ;DON'T ALLOW THESE ;DTB001 BNE 20$ ;IF NE USER ATTEMPTED TO SPECIFY THEM ;MSH179 BIT #SM.ZER,(SP) ;ZERO I/O COUNTS? ;MSH179 BEQ 40$ ;IF EQ NO ;MSH179 BIT #T3.PRV,T.ST3(R5) ;IS THE TASK PRIVILEGED? ;**-5 BNE 40$ ;IF NE YES ;DTB001 DRSTS D.RS16 ;PRIVILEGED OPERATION  ;**-4 ; ; VALIDATE MESSAGE CREATION ; 40$: TST $ERRPT ;IS THERE AN ERROR LOG TASK INSTALLED? ;MSH179 BEQ 45$ ;IF EQ NO ;MSH179 BIT #ES.DAT,$ERFLA ;DATA ALLOWED? ;**-2 BNE 50$ ;IF NE YES, LET IT THROUGH ;MSH179 BIT #SM.CMD,(SP) ;IF DATA NOT ALLOWED, MUST BE A COMMAND ;**-1 BNE 50$ ;IF NE YES, LET IT THROUGH ;MSH179 45$: DRSTS D.RS7 ;NOT ACTIVE ;MSH179 ; ;**-2 ; GET THE TYPE CODE AND SUBTYPE CODE INTO A SINGLE WORD ; 50$: CMP (R3)+,(R3)+ ;POINT AT THE CODE WORD ;MSH179 MOV (R3)+,-(SP) ;GET THE ENTIRE CODE WORD ;**-1 MOVB (R3)+,1(SP) ;OVERWRITE THE HIGH BYTE WITH THE ; SUBCODE. INC R3 ;ADJUST TO POINT TO THE LUN WORD ; ; GET THE UCB ADDRESS OF THE REFERENCED DEVICE, IF PRESENT, INTO R0, AND ; GET THE CONTROL MASK WORD INTO R1 WITH THE FLAG SET FOR THE DEVICE ; IDENTIFICATION SUBPACKET IF THERE IS A DEVICE REFERENCED. ; CMPB R0,#7. ;CHECK TO SEE IF A LUN WORD EXISTS BLO 60$ ;IF LO THERE IS NO LUN WORD ;MSH179 TST (R3) ;CHECK TO SEE IF A LUN IS PRESENT ;**-1 BEQ 60$ ;IF EQ THERE IS NO LUN SPECIFIED ;MSH179 CALL $MPLUN ;MAP THE LUN ;**-1 BCC 55$ ;IF CC LUN IS ASSIGNED TO SOMETHING ;MSH192 53$: DRSTS D.RS5 ;NOT ASSIGNED TO ERROR LOGGING DEVICE ;MSH192 ;MSH192 55$: BIT #DV.MSD,U.CW1(R0) ;MASS STORAGE DEVICE? ;MSH192 BEQ 53$ ;IF EQ NO, NOT AN ERROR LOGGING DEVICE ;MSH192 TST -(R3) ;POINT TO LUN (ADVANCED BY $MPLUN) ;MSH192 BIS #SM.DID,2(SP) ;FLAG THE PRESENCE OF A DEVICE ;**-3 ; IDENTIFICATION SUBPACKET.  ; ; SAVE THE UCB POINTER FUTURE USAGE. ; 60$: MOV R0,-(SP) ;SAVE THE UCB POINTER ;MSH179 ; NOTE THAT THE CONTENTS ARE UNDEFINED ;**-1 ; IF THERE WAS ACTUALLY NO LUN. ; ; GET AND ADDRESS CHECK THE BUFFER PARAMETERS ; CMP -(R3),-(R3) ;POINT BACK TO THE BUFFER LENGTH MOV -(R3),R1 ;GET THE BUFFER LENGTH IN BYTES BEQ 75$ ;IF EQ THERE IS NO BUFFER ;MSH179 BIS #SM.DAT,4(SP) ;FLAG THAT THERE IS A DATA SUBPACKET ;**-1 MOV -(R3), R3 ;GET THE BUFFER POINTER .IF DF A$$CHK!M$$MGE MOV R1,-(SP) ;SAVE THE BUFFER LENGTH CALL $ACHKP ;PERFORM ADDRESS CHECK AND MAP BUFFER MOV (SP)+,R1 ;RESTORE THE BUFFER LENGTH .ENDC ; A$$CHK!M$$ME ; ; WE NOW HAVE: ; ; R0 UNDEFINED ; R1 BUFFER LENGTH IN BYTES ; R2 UNDEFINED ; R3 BUFFER ADDRESS, POSSIBLY REMAPPED ; R4 UNDEFINED ; R5 UNDEFINED ; ; 0(SP) POINTER TO DEVICE UCB (UNDEFINED IF NO UCB) ; 2(SP) ENTRY TYPE CODE AND TYPE SUBCODE BYTES ; 4(SP) CONTROL MASK WORD ; 75$: MOV (SP)+,R5 ;OBTAIN THE UCB POINTER ;DTB001 MOV (SP)+,R0 ;OBTAIN THE ENTRY TYPE CODE AND SUBCODE ;DTB001 MOV (SP)+,R2 ;OBTAIN THE CONTROL MASK WORD ;**-2 MOV $TKTCB,R4 ;OBTAIN THE TASK TCB ; ; WE NOW HAVE: ; ; R0 ENTRY TYPE CODE AND SUBCODE ; R1 BUFFER LENGTH IN BYTES ; R2 CONTROL MASK WORD ; R3 BUFFER ADDRESS, POSSIBLY REMAPPED ; R4 POINTER TO TASK TCB OF CALLING TASK ; R5 POINTER TO DEVICE UCB ; CALL $CRPKT ;CREATE THE PACKET BCC 80$ ;IF CC PACKET CREATED ;MSH179 DRSTS D.RS1 ;INSUFFICIENT POOL ;**-1 80$: CALLR $QUPKT ;QUEUE THE PFACKET AND RETURN ;MSH179 ;**-1 .ENDC ; E$$LOG .END F4RðskQ ›c,; ; COPYRIGHT (c) 1981 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD ; MASSACHUSETTS. ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE ; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS ; SOFTWARE OR ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR ; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND ; OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERED. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ; ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. ; ; .TITLE MFDRV RSX11M TU78 MAG TAPE DRIVER .IDENT /V00.0/ ;+ ; MFDRV is the software interface between the RSX11M Operating ; System and TM78/TU78 DEC Magtape System. ; ; The TM78/TU78 DEC Magtape System has the following characteristics: ; ; TM78 Control Unit - May have up to four (4) TU78 Tape Units attached. ; TU78 Tape Unit - Data Recording Mode is 6250BPI (GCR) or 1600BPI (PE) ; at 125IPS (Inches/Sec.) Data recording is per ANSI X3.39 (1600BPI) ; and ANSI X3.54 (6250BPI). ;- ;+ ; ***** CAUTION - See Note on Page 5 for strapping Device Registers. ***** ;- ; ; C. SESTOKAS JUL '81 ; ; EDIT DATE AUTHOR REASON ; ____ ____ ______ ______ ; 001 ; ; ; .ENABL LC ; Lower Case - Comments Field, Only ! .PAGE .SBTTL MACROS ;+ ; MACRO LIBRARY CALLS ;- .MCALL HWDDF$,PKTDF$,UCBDF$ HWDDF$ ; Hardware Registers PKTDF$ ; I/O Packet Offsets UCBDF$ ; Unit Control Block Offsets ;+ ; MACRO DEFENITIONS ;- ; -- PUSH -- following forms: ; ; 1. Arguments may be defined or undefined. They are enclosed in < > ; and separated by commas. Undefined Arguments entered as null elements ; position signified by a comma. ; 2. No Arguments. .MACRO PUSH ARGS ; Push Items on Stack. .NARG HWMNY ; Number of Arguments in Call. .IF EQ HWMNY ; IF No Arguments, CLR -(SP) ; THEN Reserve Stack Space. .MEXIT ;HWMNY .IFF ; IF Arguments. .IRP X, .IF B X ; IF Argument missing, CLR -(SP) ; THEN Reserve Stack Space. .IFF ; IF Arguments MOV X,-(SP) ; THEN Put Them on Stack. .ENDC ;X .ENDM ;X, .ENDC ;HWMNY .ENDM PUSH ; -- POP -- same forms as for PUSH. .MACRO POP ARGS ; Pop Items from Stack. .NARG HWMNY ; Number of Arguments in Call. .IF EQ HWMNY ; IF No Arguments, TST (SP)+ ; THEN Skip Stack Element. .MEXIT ;HWMNY .IFF ; IF Arguments. .IRP X, .IF B X ; IF Argument missing, TST (SP)+ ; THEN Skip Stack Element. .IFF ; IF Arguments MOV (SP)+,X ; THEN Pop Them off Stack & to ARG. .ENDC ;X .ENDM ;X, .ENDC ;HWMNY .ENDM POP ; **** Note PUSH/POP Usage: IF PUSH R2,R3 THEN POP R3,R2. ;+ ; Linkage Macros - Used by this Driver servicing TM78/TU78 interrupts. ;- ; -- SUBR -- .MACRO SUBR ARG MOV #.+12,@#ARG-2 ; Setup Linkage Address JMP ARG ; and GO TO Subroutine. .ENDM SUBR ; -- RTRN -- .MACRO RTRN ARG JMP @ARG-2 ; Return from Subroutine. .ENDM RTRN .PAGE .SBTTL TM78 DEVICE, MASSBUS REGISTERS TMREGS = 22. ; # TM78 Device Registers - not including MFBAE, MFCS3. MFCS1 = +00 ; Control and Status 1 MFWC = + 2 ; Word Count MFBA = 4 ; UNIBUS Address MFBC = 6 ; Byte Count MFCS2 = 10 ; Control and Status 2 MFDI = 12 ; Data Interrupt MFDM = 14 ; Data Mode MFAS = 16 ; Attention Summary MFDS = 20 ; Drive Status MFDB = 22 ; Data Buffer MFDE = 24 ; Diagnostic Error MFDT = 26 ; Drive Type MFSN = 30 ; Serial Number MFDR = 32 ; Diagnostic Request MFDD = 34 ; Diagnostic Data MFNDI = 36 ; Non Data Interrupt MFND0 = 40 ; Non Data Command - Tape Unit 0 MFND1 = 42 ; | | | - Tape Unit 1 MFND2 = 44 ; | | | - Tape Unit 2 MFND3 = 46 ; Non Data Command - Tape Unit 3 MFIA = 50 ; Internal Address MFCR = 52 ; Control register ; ***** CAUTION ***** ; TM78 Attached to RH70 MASSBUS Controller - ; ; DEV REG(s) - MFBAE/MFCS3 Registers physical address is determined by ; strapping options in the RH70 Controller. ; ; IF TM78 ONLY DEVICE on the RH70, ; THEN MFBAE/MFCS3 expected to be adjacent to other DEVICE Registers. ; 1. Strap RH70 properly. ; 2. Remove the following defenition by placing a ; before the line. ; ; IF TM78.and.Other Devices on the same RH70, ; THEN MFBAE/MFCS3 expected to be at end of that MASSBUS ; controller address space. ; 1. Delete strapping in RH70. ; 2. Following defenition remains. ; XTREG=0 ; RH Controller - BAE and CS3 Reg's at end of 32 Word Boundary .IIF NDF XTREG, MFBAE = 54 ; Bus Address Extension Register .IIF DF XTREG, MFBAE = 74 .IIF NDF XTREG, MFCS3 = 56 ; Control and Status 3 .IIF DF XTREG, MFCS3 = 76 .PAGE .SBTTL REGISTER BIT/FIELD DEFENITIONS ;+ ; MFCS1 REGISTER RH/TM Shareable Register. ;- C1.SC = 100000 ; RH Reg - Special Condition C1.TRE = 40000 ; RH Reg - Transfer Error C1.CPE = 20000 ; RH Reg - Control Bus Parity Error C1.DVA = 4000 ; TM Reg - Drive Available C1.PSL = 2000 ; RH Reg - Port Select C1.A17 = 1000 ; RH Reg - UNIBUS @ - A17 C1.A16 = 400 ; RH Reg - Extension Bits - A16 C1.RDY = 200 ; RH Reg - Ready (for Data Transfer) C1.IE = 100 ; RH Reg - Interrupt Enable C1.DFC = 76 ; TM Reg - Data Transfer Function Code C1.GO = 1 ; TM Reg - Go. Initiate data transfer ;+ ; Data Transfer Function Codes - GO and IE Bit set. ;- FC.PE = 61 ! C1.IE ; Write 1600 (PE) FC.GCR = 63 ! C1.IE ; Write 6250 (GCR) FC.RDF = 71 ! C1.IE ; Read Forward FC.RDR = 77 ! C1.IE ; Read Reverse FC.XSN = 73 ! C1.IE ; Extended Sense ;+ ; MFWC REGISTER MASSBUS Word Count Register ;- 2's complement WORD COUNT. ;+ ; MFBA REGISTER UNIBUS Address Register. ;- 177776. LSB not used. ;+ ; MFBC REGISTER TM (Read/Write) Byte Count Register. ;- ;+ ; MFCS2 REGISTER RH REGISTER ;- C2.DLT = 100000 ; Data Late C2.WCE = 40000 ; Write Check Error C2.UPE = 20000 ; UNIBUS Parity Error C2.NED = 10000 ; Non-existent Drive C2.NEM = 4000 ; Non-existent Memory C2.PGE = 2000 ; Program Error C2.MXF = 1000 ; Missed Transfer C2.DPE = 400 ; MASSBUS Data Parity Error C2.OR = 200 ; Output Ready C2.IR = 100 ; Input Ready C2.CLR =  40 ; Controller Clear C2.PAT = 20 ; Parity Test C2.BAI = 10 ; UNIBUS Address Increment Inhibit C2.UNT = 7 ; TM Unit Select (0-7) ;+ ; MFDI REGISTER TM Register ;- DTFLCD = 176000 ; Data Transfer Failure Code DPR = 400 ; "1" - Drive Present DTINTC = 77 ; Data Interrupt Code ;+ ; MFDM REGISTER TM Register ;- DM.SER = 100000 ; Suppress Error Recovery DM.FMT = 70000 ; Data (assembly/disassembly) Format Mode DM.SKP = 7400 ; Skip Count - Read:'0' fill followed by data. DM.CNT = 374 ; Record Count - number of to be read/written. ;+ ; MFAS REGISTER TM Register ;- AS.BTS = 377 ; Attention Summary: Bit0-Drive0, Bit7-Drive7. ;+ ; MFDS REGISTER TM Register ;- DS.RDY = 100000 ; Unit online - ready for execution. DS.PRS = 40000 ; Unit has power applied. DS.ONL = 20000 ; Unit online. DS.REW = 10000 ; Unit is Rewinding. DS.PE = 4000 ; Unit in 1600(PE) recording mode. DS.BOT = 2000 ; Unit at tape BOT. DS.EOT = 1000 ; Unit detected tape EOT. DS.FPT = 400 ; Unit write protected (No Write Ring). DS.AVL = 200 ; Drive available to MASSBUS. DS.SHR = 100 ; Drive shareable to both MASSBUS ports. DS.MNT = 40 ; Drive in maintenance mode - unavailable for use. DS.DSE = 20 ; Unit in erase portion of DSE operation. ;+ ; MFDB REGISTER RH REGISTER - Data Buffer ;- ;+ ; MFDE REGISTER TM Register - Diagnostic Error ;- ;+ ; MFDT REGISTER TM Register - Drive Type ;- DT.TAP = 40000 ; '1' - Tape Device DT.DPT = 4000 ; Dual Port Feature DT.WCS = 2000 ; '1' - Writeable Control Store DT.DTP = 777 ; Drive Type - TM78 = 101 ;+ ; MFSN REGISTER TM Register - Serial Number ;- SN.SN3 = 170000 ; BCD Serial Number 3 SN.SN2 = 7400 ; | | | 2 SN.SN1 = 360 ; | | | 1 SN.SN0 = 17 ; BCD Serial Number 0 ;+ ; MFDR REGISTER TM Register - Diagnostic Request ;- ;+ ; MFDD REGISTER TM Register - Diagnostic Data ;- ;+ ; MFNDI REGISTER TM Register - Non Data Interrupt Status ;- NDFLCD = 176000 ; Non Data Failure Code NDUNIT = 1400 ; Tape Unit Number ;+ ; MFNDx REGISTER(S) TM Register - Non Data Command, Tape Unit (x) 0-4. ;- CMCNTx = 177400 ; Command Count for Tape Unit x. NDFCTx = 76 ; Non Data Function Code for Tape Unit x. GOBITx = 1 ; Go Bit for Non Data Command for Tape Unit x. ; Non Data Transfer Commands - GO Bit set. ERGGCR= 37 ; Erase 3" Gap, GCR. ERGPE= 35 ; Erase 3" Gap, PE. WTMGCR= 17 ; Write Tape Mark, GCR. WTMPE= 15 ; Write Tape Mark, PE. DSE= 13 ; Data Security Erase. SNSE= 11 ; Sense Tape Unit Characteristics. RWND= 7 ; Rewind Tape on Tape Unit. UNLD= 5 ; Rewind and Unload Tape on Tape Unit. SFTMK= 25 ; Space Forward TMK. SRTMK= 27 ; Space Reverse TMK. SLTMK= 47 ; Space Forward TMK/LEOT. IF LEOT, position AEOV. SFREC= 21 ; Space Forward REC. SRREC= 23 ; Space Reverse REC. ;+ ; MFIA REGISTER TM Register - TM78 Internal Address ;- ;+ ; MFCR REGISTER TM Register - TM78 Control Register ;- TMRDY = 100000 ; TM78 available for command execution TMCLR = 40000 ; TM78 Clear MCPE = 20000 ; TM78 ROM parity error ILR = 10000 ; TM78 reference to nonexistent MASSBUS register CPE = 4000 ; TM78 parity error detect - write to MASSBUS reg EVPAR = 2000 ; TM78 even parity generate/check on MASSBUS cntl bus HLDA = 1000 ; TM78 microprogram sequencing inhibited HOLD = 400 ; TM78 HOLD bit - inhibit microprogram sequencing INTDT = 377 ; Internal Data ;+ ; MFBAE REGISTER RH REGISTER - Bus Address Extension Register ;- BA.BTS = 77 ; Bus Address bits 21-16. Logical extn of MFBA register ;+ ; MFCS3 REGISTER RH REGISTER - Control and Status Reg 3 ;- C3.APE = 100000 ; Address Parity Error C3.PEO = 40000 ; Data Parity Error - Odd Word C3.PEE = 20000 ; Data Parity Error - Even Word C3.CEO = 10000 ; Write Check Error - Odd Word C3.CEE = 4000 ; Write Check Error - Even Word C3.DW = 2000 ; Double Word C3.IE = 100 ; Interrupt Enable C3.IPC = 17 ; Inverted Parity Check .PAGE .SBTTL TM78 INTERRUPT CODES ;+ ; TM78 INTERRUPT CODES - Data/Non Data Transfers and TM78 Initiated ;- ; Bit Mask Values Int Code ILG = 1 ; Illegal 0. DON = 2 ; NDT or DT. 1, Done. TMK = 4 ; NDT or DT. 2, Tape Mark. BOT = 10 ; NDT or DT. 3, Beginning of Tape. EOT = 20 ; NDT or DT. 4, End of Tape. LEOT = 40 ; NDT. 5, Logical End of Tape. NOOP = 100 ; NDT. 6, NO OP Command. RWD = 200 ; NDT. 7, Rewinding. FPT = 400 ; NDT or DT. 10, Write Protect. NRDY = 1000 ; NDT or DT. 11, TM78 not ready to execute command. NAVL = 2000 ; NDT or DT. 12, TU78 not avail to this port. OFLN = 4000 ; NDT or DT. 13, TU78 Offline. NTEX = 10000 ; NDT or DT. 14, TU78 Non Existant. NTCP = 20000 ; NDT or DT. 15, Read initiated, not performed. UNDF = 40000 ; Undefined. 16, ONLN = 100000 ; TM Initiated 17, TU78 < Online. TU78 Sense Data. RLL = 1 ; DT.  20, Read data OK. GT requested. RLS = 2 ; DT. 21, Read data OK. LT requested. RTRY = 4 ; DT. 22, Retry operation - same direction. RDOP = 10 ; DT. 23, Read Data in opposite direction. UNRD = 20 ; DT. 24, Data Unreadable after retries. ERR = 40 ; DT. 25, Data Transfer error - Surp Err Rcvry EOTE = 100 ; DT. 26, Write err after EOT - Surp Err Rcvry BDTP = 200 ; NDT or DT. 27, Bad tape- Write failure ! Lost Posit TMFA = 400 ; NDT or DT. 30, TM Fault A - Failure, I/O operation TUFA = 1000 ; NDT or DT. 31, TU Fault A - Failure, I/O operation TMFB = 2000 ; TM Initiated 32, TM Fault B - Failure, no I/O TMFB = 4000 ; Not Used. 33, MBFL = 10000 ; TM Initiated 34, Massbus Control Bus Fault. ; TM78 Initiated Interrupts. TMI1= ONLN TMI2= TMFB ! MBFL ; Data Transfer Operation Interrupts. ; WRITE WRTI1= DON ! EOT ! FPT ! NRDY ! NAVL ! OFLN ! NTEX WRTI2= RTRY ! ERR ! EOTE ! BDTP ! TMFA ! TUFA ; READ FWD RDFI1= DON ! TMK ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP RDFI2= RLL ! RLS ! RTRY ! RDOP ! UNRD ! ERR ! BDTP ! TMFA ! TUFA ; READ REV RDRI1= DON ! TMK ! BOT ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP RDRI2= RLL ! RLS ! RTRY ! RDOP ! UNRD ! ERR ! BDTP ! TMFA ! TUFA ; XTND SNS XNSI1= DON ; Non Data Transfer Operation Interrupts. ; WRITE TMK WTMI1= DON ! EOT ! FPT ! NRDY ! NAVL ! OFLN ! NTEX WTMI2= BDTP ! TMFA ! TUFA ; SENSE SNSI1= DON SNSI2= TMFA ! TUFA ; SPACE TMK, FWD SFTMI1= DON ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP SFTMI2= BDTP ! TMFA ! TUFA ; SPACE TMK, REV SRTMI1= DON ! BOT ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP SRTMI2= BDTP ! TMFA ! TUFA ; SPACE TMK/LEOT, FWD SLTMI1= DON ! LEOT ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP SLTMI2= BDTP ! TMFA ! TUFA ; SPACE RECORD, FWD SFRCI1= DON ! TMK ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP SFRCI2= BDTP ! TMFA ! TUFA ; SPACE RECORD, REV SRRCI1= DON ! TMK ! BOT ! NRDY ! NAVL ! OFLN ! NTEX ! NTCP SRRCI2= BDTP ! TMFA !TUFA ; ERASE 3" GAP ERGI1= DON ! EOT ! FPT ! NRDY ! NAVL ! OFLN ! NTEX ERGI2= BDTP ! TMFA ! TUFA ; DATA SECURITY ERASE DSEI1= DON ! FPT ! NRDY ! NAVL ! OFLN ! NTEX DSEI2= TMFA ! TUFA ; REWIND RWDI1= DON ! RWD ! NRDY ! NAVL ! OFLN ! NTEX RWDI2= TMFA ! TUFA ; UNLOAD UNLI1= DON ! NRDY ! NAVL ! OFLN ! NTEX UNLI2= TMFA ! TUFA .SBTTL Function Tables ;+ ;TM78/TU78 Spacing Subfunction Table ;- .MACRO SPCFCT SPCGCR,SPCPE,TIMOUT,TIMES,SPCVL1,SPCVL2 .BYTE SPCGCR ; Commands: 6250BPI, .BYTE SPCPE ; 1600BPI. .BYTE TIMOUT,TIMES ; Subcycle Time (S.CTM), Subcycles (S.STS). .WORD SPCVL1 ; Interrupt validation Mask 1. .WORD SPCVL2 ; Interrupt validation Mask 2. .ENDM SPCFCT SVALI1= +4 ; > Spacing Validation Mask(s). SPFTMK: SPCFCT SFTMK,SFTMK, 2,120., SFTMI1,SFTMI2 ;Space FWD TMK. SPRTMK: SPCFCT SRTMK,SRTMK, 2,120., SRTMI1,SRTMI2 ;Space REV TMK. SPLTMK: SPCFCT SLTMK,SLTMK, 2,120., SLTMI1,SLTMI2 ;Space FWD TMK/LEOT SPFREC: SPCFCT SFREC,SFREC, 2,120., SFRCI1,SFRCI2 ;Space FWD REC. SPRREC: SPCFCT SRREC,SRREC, 2,120., SRRCI1,SRRCI2 ;Space REV REC. ;+ ; Valid TM78/TU78 Function Table ;- .MACRO FUNCT FCT,PREPRO,CMNDGC,CMNDPE,TIMOUT,TIMES,VALI1,VALI2,ISRSRV .WORD IO.'FCT ; I/O Function Code .WORD PREPRO ; Preprocessing indications. .BYTE CMNDGC ; Commands: 6250BPI, .BYTE CMNDPE ; | 1600BPI. .BYTE TIMOUT,TIMES ; Subcycle Time (S.CTM), Subcycles (S.STS). .WORD VALI1 ; Interrupt Validation Mask 1. .WORD VALI2 ; Interrupt Validation Mask 2. .WORD ISRSRV ; > ISR Service Routine. .ENDM FUNCT PWR= 1 ; Test US.PWF Indication. WRT= 2 ; Test M.SWL Indication. WTPW= PWR!WRT ; Test US.PWF and M.SWL Indication. REV= 4 ; Test for Read Reverse. DT= 8. ; Test for Data Request. REWIND= 16. ; Test for Rewind Request. UNLOAD= 32. ; Test for Unload Request. PREPRO= +2 ; > Pre process I/O request. CMDGCR= +4 ; > GCR Command. CMDPE= +5 ; > PE Command. TMOUT= +6 ; > Time out information. VALI1= +10 ; > Validation Mask(s). ISRSRV= +14 ; > ISR Service Routine. IO.XSN= 37400 ; Function - Not in QIO.MAC. FTBL: FUNCT WLB, WTPW!DT, FC.GCR,FC.PE, 3,1, WRTI1,WRTI2, WRTISR ; WRITE FUNCT RLB, PWR!DT, FC.RDF,FC.RDF, 20.,1, RDFI1,RDFI2, RDFISR ; READ FWD FUNCT RLV, PWR!REV!DT, FC.RDR,FC.RDR, 20.,1, RDRI1,RDRI2, RDRISR ; READ REV FUNCT EOF, WTPW, WTMGCR,WTMPE, 3,1, WTMI1,WTMI2, WTMISR ; WRITE TMK FUNCT STC, 0, SNSE, SNSE, 2,1, SNSI1,SNSI2, SNSISR ; SET CHAR FUNCT SEC, 0, SNSE, SNSE, 2,1, SNSI1,SNSI2, SNSISR ; SNS CHAR FUNCT SMO, 0, SNSE, SNSE, 2,1, SNSI1,SNSI2, SNSISR ; S/MOU CHR FUNCT SPF, PWR, 0, 0, 2,120., 0, 0, 0 ; SPC TMKS FUNCT SPB, PWR, 0, 0, 2,120., 0, 0, 0 ; SPC BLCKS FUNCT ERS, WTPW, ERGGCR,ERGPE, 3,1, ERGI1,ERGI2, ERGISR ; ERS 3" GP FUNCT DSE, WTPW, DSE, DSE, 2,160., DSEI1,DSEI2, DSEISR ; DSE IORWD: FUNCT RWD, REWIND, RWND, RWND, 2,40., RWDI1,RWDI2, RWDISR ; REWIND LNGHT=.-IORWD FUNCT RWU, UNLOAD, UNLD, UNLD, 2,1, UNLI1,UNLI2, UNLISR ; RWND/UNLD .IF DF E$$DVC FUNCT XSN, 0, FC.XSN,FC.XSN, 2,1, XNSI1, 0, XNSISR ; XTND SNS .ENDC ;E$$DVC ENDFTB=. .PAGE .SBTTL OPERATION RETURN CODES ;+ ; I/O Operation Return Codes per TM78 Interrupt Code Values. ;- ; Interrupt Designation/Code RTRNTB: .BYTE 0 ; ILG 0 - Illegal. .BYTE IS.SUC ; DON 1 - Done. .BYTE IE.EOF ; TMK 2 - Tape Mark. .BYTE IS.SUC ; BOT 3 - Beginning of Tape. .BYTE IE.EOT ; EOT 4 - End of Tape. .BYTE IE.EOV ; LEOT 5 - Logical End of Tape. .BYTE 0 ; NOOP 6 - No operation. .BYTE IS.SUC ; RWD 7 - Start of Rewind. .BYTE IE.WLK ; FPT 10 - File Protected. .BYTE IE.DNR ; NRDY 11 - Not ready for Command. .BYTE IE.FHE ; NAVL 12 - Not available to this port. .BYTE IE.OFL ; OFLN 13 - TU78 Offline. .BYTE IE.FHE ; NTEX 14 - TU78 non-existant. .BYTE IE.FHE ; NTCP 15 - Not cpbl- Rd Init, Not Prfrmd. .BYTE 0 ; UNDF 16 - Undefined. .BYTE 0 ; ONLN 17 - Online (Unsolicited). .BYTE IE.DAO ; RLL 20 - Long Record. .BYTE IS.SUC ; RLS 21 - Short Record. .BYTE IE.VER ; RTRY 22 - Retry operation. .BYTE IE.VER ; RDOP 23 - Read opposite. .BYTE IE.VER ; UNRD 24 - Unreadable. .BYTE IE.VER ; ERR 25 - Error, Retries suppressed. .BYTE IE.VER ; EOTE 26 - Error/EOT. Retries suppressed. .BYTE IE.VER ; BDTP 27 - Bad Tape. Write err/Posit lost. .BYTE IE.FHE ; TMFA 30 - TM Fault A. .BYTE IE.FHE ; TUFA 31 - TU Fault A. .BYTE 0 ; TMFB 32 - TM Fault B (Unsolicited). .BYTE 0 ; TUFB 33 - Undefined. .BYTE 0 ; MBFL 34 - MASSBUS Control Bus Fault ; (Unsolicited). .EVEN .PAGE .SBTTL DEFENITION OF U.CW2/U.CW3 ;+ ; U.CW2 - Characteristics Word ; U.CW3 - Supported Tape Density Identification (Set up by SYSGEN) ;- ;+ ; TAPE CHARACTERISTICS (U.CW2) WORD ; Bits 6,7 and 11 user settable via IO.STC or IO.SMO. ; Bit 11 only allowed to be updated when tape unit not beyond BOT. ; Returned per IO.SEC request in second status word. ;- M.PEOV= 100000 ; Returned to user as '0' - Driver internal use. ; Unlabelled tape operation - Tape in gap after EOV ; (double TMK) having completed forward motion operation. M.AEOV= 40000 ; Unlabelled tape operation - Tape positioned in gap ; between double TMK's (EOV) after forward motion operation. M.BOT= 20000 ; Tape at BOT. M.1600= 4000 ; * Tape density control - '0'=6250BPI, '1'=1600. M.HWL= 2000 ; Hardware Write Lock. M.RWD= 1000 ; Driver indication that unit is rewinding. M.SER= 400 ; Tape Unit select error (Tape Unit Offline). M.IWR= 200 ; * Inhibit Write with Extended Inter-record gap (IRG). M.SWL= 100 ; * Software write locked. M.TMK= 40 ; Last Tape Command encountered TMK. M.EOT= 20 ; Last command encountered EOT mark. NEWBTS= M.AEOV ! M.BOT ! M.EOT ! M.HWL ! M.SER ! M.TMK NWBTS1= M.BOT ! M.EOT ! M.HWL ! M.SER NWBTS2= M.BOT ! M.EOT ! M.SER ;+ ; SUPPORTED TAPE DENSITY (U.CW3) IDENTIFICATION ; ; Low byte: U.CW2, Bit11='0' - UD.625, 6250BPI. ; High byte: U.CW2, Bit11='1' - UD.160, 1600BPI. ;- .PAGE .SBTTL DRIVER PARAMETERS US.SUP=2 ; Supress Error Recovery ;+ ; Driver Parameters - Indexed by RH Controller Number ;- CNTBL: .BLKW T$$M78 ; > UCB, I/O Dequeued. DQDIO: .BLKW T$$M78 ; I/O Dequeued - NEQ=Yes. INPROG: .BLKW T$$M78 ; I/O Status - NEQ= Lo Byte,I/O in Progress; ; Hi Byte,Passed DEV REG's(UMD). DTCMD: .BLKW T$$M78 ; I/O Status - NEQ=Data Transfer. XNSCMD: .BLKW T$$M78 ; I/O Status - NEQ= Lo Byte,XND SNS Operation; ; Hi Byte,Unsolicited I/O. IOFCT: .BLKW T$$M78 ; > FTBL, Current I/O Request. RTRNAD: .BLKW T$$M78 ; Driver Return @: TU78 Offline/TM78 Not Ready. DTCNT: .BLKW T$$M78 ; Current DATA I/O Byte Count. DTADR1: .BLKW T$$M78 ; Current Address - U.BUF,U.BUF+1. DTADR2: .BLKW T$$M78 ; | | | | - U.BUF+2. RDOPCM: .BLKW T$$M78 ; > FTBL - Read Opposite Function. INTCD1: .BLKW T$$M78 ; Interrupt code to Int 0 - 17 INTCD2: .BLKW T$$M78 ; Bit Code value: 20 - 34 RSTATN: .BLKW T$$M78 ; MFAS Reg Reset Mask - NDT Commands. IOSTAT: .BLKW T$$M78 ; I/O Operation Return Code. SPCNT: .BLKW T$$M78 ; Residual BLCK/TMK count - To be yet spaced ; .OR. Tape Char(s) - For SMO/STC. SPACED: .BLKW T$$M78 ; Spaced BLCK/TMK count - Already spaced. SPCIO: .BLKW T$$M78 ; Current I/O Space Count. SPCNG: .BLKW T$$M78 ; > Spacing Subfunction Table. RTTBL: .BLKW T$$M78 ; Retry count: +0,Rtrs left. +1,Total rtrs. ERRPKT: .BLKW T$$M78 ; > Error Log Packet. .IF GT T$$M78-1 TEMP: .BLKW 1 ; PS Save Area. Lo 4 bits - Controller #. .ENDC DCBPTR: .WORD 0 ; > DCB. WTRTRY= 50. ; # Re-write attempts. RDRTRY= 21. ; # Re-read attempts (embedded tape cleans). ;+ ; DRIVER DISPATCH TABLE ;- $MFTBL:: .WORD MFINI ; Initiate I/O Operation .WORD MFCAN ; Cancel I/O Operation .WORD MFOUT ; Device Timeout  .WORD MFPWF ; Powerfail Entry .PAGE .SBTTL INITIATE I/O OPERATIONS ;+ ; -- MFINI -- Initiate TU78/TM78 Mag Tape I/O Operation ; ; Service QIO Directive or Completed I/O request, services remaining requests. ; ; IF the Dqu successful, THEN service the request. ELSE RETURN to Caller. ; ; Prior to CALL $GTPKT: ; R5 - > UCB. ; ; Return from $GTPKT: ; ; C=1 - Dequeue unsuccessful. Controller Busy or No Request to DQU. ; ; C=0 - Dequeue successful. ; R1 - > I/O Pckt. ; R2 - Physical Tape Unit # (U.UNIT). ; R3 - RH Controller Index (S.CON). ; R4 - > SCB. ; R5 - > UCB. ;- MFINI: CALL $GTPKT ; Outstanding I/O request ? BCC 10$ ; IF CC, Yes. Service it. RETURN ; Controller Busy or No I/O Request. 10$: MOV S.CSR(R4),R2 ; R2=CSR. MOV R5,CNTBL(R3) ; Save > UCB, Dqud I/O Request. MOV I.FCN(R1),R1 ; R1 - Function code. MOV #FTBL,R0 ; R0 > TM78/TU78 Function Table. BICB #US.SUP,U.STS(R5) ; Assume Error recovery allowed. CLR RTTBL(R3) ; Assume recovery count = 0. .IF DF D$$IAG BITB #IQ.UMD,R1 ; Diagnostic function ? BEQ 15$ ; IF EQ, No. MOV #100000,RTTBL(R3) ; Diagnostic function, BISB #US.SUP,U.STS(R5) ; No error recovery. 15$: .ENDC ;D$$IAG BITB #IQ.X,R1 ; Suppress error recovery ? BEQ 20$ ; IF EQ, No. BISB #US.SUP,U.STS(R5) ; No error recovery. ; Validate I/O Request Support. 20$: BICB #IQ.X!IQ.UMD!IQ.Q,R1 ; Cleanup function code for validation. 22$: CMP R1,(R0) ; I/O supported by TM78/TU78 ? BEQ 30$ ; IF EQ, Yes. ADD #LNGHT,R0 ; Next I/O function. CMP R0,#ENDFTB ; Any more TM78/TU78 Functions ? BNE 22$ ; IF NE, No. Keep looking for match/end. MOV #IE.IFC&377,R0 ; Unsupported request. Notify user, 25$: SUBR ENDRQS ; End I/O request BR MFINI ; & Service other I/O requests. ; Preprocess I/O Request. 30$: MOV R0,IOFCT(R3) ; Save > FTBL, Dqud I/O request. TST (R0)+ ; > Preprocess functions. ; Function allowed if Powerfailure occured ? BIT #PWR,(R0) ; I/O allowed if powerfailure occured? BEQ 40$ ; IF EQ, Yes. BITB #US.PWF,U.STS(R5) ; Powerfailure occurence? BEQ 40$ ; IF EQ, No. MOV #IE.ABO&377,R0 ; Function not allowed until US.PWF Reset. BR 25$ ; Endup this request. ; Function allowed if Software write locked ? 40$: BIT #WRT,(R0) ; Verify user write locking? BEQ 50$ ; IF EQ, No. BIT #M.SWL,U.CW2(R5) ; User software write locked device? BEQ 50$ ; IF EQ, No. MOV #IE.WLK&377,R0 ; Indicate write locked and BR 25$ ; endup this request. ; No I/O to Rewinding Tape Unit. 50$: INC DQDIO(R3) ; Indicate DQD I/O pending. CLR INPROG(R3) ; In case, CLR DTCMD(R3) ; set. BIT #M.RWD,U.CW2(R5) ; Tape Unit Rewinding ? BEQ 60$ ; IF EQ, No. CMP #IO.SEC,-2(R0) ; Sense Characteristics Request ? BNE 55$ ; IF NE, No. BIC #NWBTS2,U.CW2(R5) ; M.BOT, M.EOT, M.SER bits unpredictable. MOV #IS.SUC&377,R0 ; Indicate success and MOV U.CW2(R5),R1 ; Characteristics Word. BR 25$ ; . . Cont. 55$: MOVB #40.,S.STS(R4) ; Must wait for tape unit RWD completion. BR 65$ ; . . Cont. ; I/O - only if TM78 Ready. 60$: MOV U.SUB(R5),MFCS2(R2) ; Select TM UNIT. TST MFCR(R2) ; TM78 Ready for command ? BMI INIOPR ; IF MI, Yes. 65$: MOV #INIOPR,RTRNAD(R3) ; Return to if TM becomes ready. MOVB S.ITM(R4),S.CTM(R4) ; TMO for TM78 to become ready and RETURN ; Defer Dqud I/O till TM78 becomes avail. ; To return here after RWD completes (have DQD PKT), need to re-establish: ; R0 - > FTBL, Preprocess, R2 - CSR, ; R3 - RH Cont Index(S.CON), R4 - > SCB, R5 - > UCB. ; ; GOTO I/O Initiate Routine. INIOPR: CLR DQDIO(R3) ; No DQD I/O pending. INC INPROG(R3) ; I/O Busy. BIT #DT,(R0) ; Data Transfer ? BNE DTIO ; IF NE, Yes. JMP NDTIO ; Initiate NDT I/O. .PAGE .SBTTL INITIATE DATA (I/O) SERVICING ;+ ; Register configuration - Initiate Data (I/O) servicing: ; R0 - > FTBL, Preprocess. R3 - Controller Index (S.CON). ; R2 - CSR. R4 - > SCB. ; R5 - > UCB. ;- DTIO: INC DTCMD(R3) ; Data transfer I/O. MOVB U.UNIT(R5),-(SP) ; Tape Unit selection. BIC #^C<3>,(SP) ; Perhaps won't suppress retries. BITB #US.SUP,U.STS(R5) ; No error recovery this I/O request? BNE 9$ ; IF NE, Yes. MOV #RDRTRY,RTTBL(R3) ; Read recovery retries. MOV IOFCT(R3),RDOPCM(R3) ; > Read Opposite ADD #LNGHT,RDOPCM(R3) ; Function. BIT #WRT,(R0) ; Write request? BEQ 10$ ; IF EQ, No. BIT #M.IWR,U.CW2(R5) ; Suppress recovery for user? BNE 8$ ; IF NE, Yes. MOV #WTRTRY,RTTBL(R3) ; Set up for Write recovery. BR 10$ ; . . Cont. 8$: CLR RTTBL(R3) ; No retries allowed. 9$: BIS #DM.SER,(SP) ; Inhibit error recovery. 10$: MOVB RTTBL(R3),RTTBL+1(R3) ; Error Recovery Retries. POP MFDM(R2) ; Data transfer for Tape Unit x. .IF DF M$$EXT ; 22 Bit Extnd Addr (11/70, 11/44). BIT #DV.MBC,U.CW1(R5) ; RH11 ? BNE 20$ ; IF NE, No - RH70. CALL $STMAP ; Setup UNIBUS mapping. ASL U.BUF(R5) ; Setup A17,A16 ASL U.BUF(R5) ; address bits ASL U.BUF(R5) ; into ASL U.BUF(R5) ; HI Byte. CALL $MPUBM ; Setup UMRs for transfer. MOV S.CSR(R4),R2 ; Restore R2 - CSR MOV IOFCT(R3),R0 ; R0 > TST (R0)+ ; Preprocessing. 20$: .ENDC ;M$$EXT MOV R5,R1 ; R1 > ADD #U.BUF,R1 ; U.BUF. .IF NDF M$$EXT .IF DF M$$MGE ; 18 Bit Addressing. ROL (R1) ; Setup A17,A16 ROL (R1) ; address bits ROL (R1) ; into ROL (R1) ; HI Byte. .ENDC ;M$$MGE .ENDC ;M$$EXT BIT #REV,(R0) ; Read Reverse request ? BEQ 30$ ; IF EQ, No. SUB #2,U.CNT(R5) ; Read Reverse - ADD U.CNT(R5),U.BUF+2(R5) ; Adjust Buffer Pointer BCC 28$ ; to end of ADCB U.BUF+1(R5) ; Buffer Area. 28$: ADD #2,U.CNT(R5) ; Restore Transfer Count. SUB #2*LNGHT,RDOPCM(R3) ; > Read Opposite Function. 30$: MOV #DTIOGO,RTRNAD(R3) ; Return @ if need restart operation. MOV U.CNT(R5),DTCNT(R3) ; Current Data I/O Byte Count, MOV U.BUF(R5),DTADR1(R3) ; HI BYTE: 6@ (RH70/22 bit @) bits or ; 2@ (RH11/18 bit @) bits ; [A16,A17/Bit8,9] MOV U.BUF+2(R5),DTADR2(R3) ; and low 16 Address bits. ;+ ; Register Configuration - per DTIO entry. ;- DTIOGO: MOV DTCNT(R3),MFBC(R2) ; Data byte count for TM. MOV MFBC(R2),MFWC(R2) ; Word CLC ; count ROR MFWC(R2) ; for RH. NEG MFWC(R2) ; (2's complement) MOV DTADR2(R3),MFBA(R2) ; Transfer address - 16 lo order bits. TST (R0)+ ; > I/O Function Code. MOVB (R0),DTADR1(R3) ; I/O code - 6250BPI mode. BIT #M.1600,U.CW2(R5) ; 1600BPI mode ? BEQ 10$ ; IF EQ, No. MOVB 1(R0),DTADR1(R3) ; I/O code - 1600BPI mode. 10$: BIC #NEWBTS,U.CW2(R5) ; I/O operation changes SENSE data. MOVB 2(R0),S.CTM(R4) ; Start I/O Timeout. MTPS #PR7 ; INHIBIT INTERRUPTS ; Start I/O .IF DF M$$EXT BIT #DV.MBC,U.CW1(R5) ;;; RH70 (MASSBUS Controller) ? BEQ 20$ ;;; IF EQ, No. MOVB DTADR1+1(R3),MFBAE(R2) ;;; Start transfer MOVB DTADR1(R3),MFCS1(R2) ;;; on 11/70. BR 22$ ;;; . . cont . .IFTF 20$: MOV DTADR1(R3),MFCS1(R2) ;;; Start transfer on others. 22$: .ENDC MTPS #0 ;;; ALLOW INTERRUPTS RETURN ; EXIT while I/O in progress. .PAGE .SBTTL INITIATE NONDATA (I/O) SERVICING ;+ ; Register configuration - Initiate Non Data (I/O) servicing: ; R0 - > FTBL, Preprocess. R3 - Controller Index (S.CON). ; R2 - CSR. R4 - > SCB. ; R5 - > UCB. ;- .ENABL LSB NDTIO: BIT #REWIND,(R0) ; Rewind request ? BEQ 5$ ; IF EQ, No. BIS #M.RWD,U.CW2(R5) ; Rewind indication. 5$: MOV U.BUF(R5),SPCNT(R3) ; Save Space Count/Tape Char(s). MOV #STRTIO,RTRNAD(R3) ; Return @ if need restart operation. TST (R0)+ ; > I/O Command. TST (R0) ; Space via TMKS or Blocks ? BEQ SPACE ; IF EQ, Yes. CLR U.BUF(R5) ; Setup NDT MOVB (R0),U.BUF(R5) ; 6250BPI Command Word. BIT #M.1600,U.CW2(R5) ; 1600BPI Command? BEQ STRTIO ; IF EQ, No. MOVB 1(R0),U.BUF(R5) ; Setup NDT 1600BPI Command Word. STRTIO: TST -2(R0) ; SENSE request ? BEQ 10$ ; IF EQ, Yes. SPSTRT: BIC #M.AEOV!M.TMK,U.CW2(R5) ; Update M.AEOV/M.TMK and 10$: BIC #NWBTS1,U.CW2(R5) ; M.BOT, M.EOT, M.HWL, M.SER bits. TST (R0)+ ; > Timeouts. MOVB (R0)+,S.CTM(R4) ; Start I/O MOVB (R0)+,S.STS(R4) ; Timeout. MTPS #PR7 ; INHIBIT INTERRUPTS MOV #C1.TRE,MFCS1(R2) ;;; Make sure no previous transfer BIC #C1.TRE,MFCS1(R2) ;;; error holds up this I/O transfer. MOV #C1.IE!C1.DVA,MFCS1(R2) ;;; Allow interrupts on this RH. MOVB U.UNIT(R5),R3 ;;; Prepare ASL R3 ;;; for MFNDx ADD R3,R2 ;;; accessing. MOV U.BUF(R5),MFND0(R2) ;;; Start Non Data Transfer. MTPS #0 ;;; ALLOW INTERRUPTS RETURN ; EXIT While I/O in progress. .DSABL LSB .ENABL LSB SPACE: TST SPCNT(R3) ; Space count =0 ? BNE 10$ ; IF NE, No. CLR INPROG(R3) ; No active I/O. MOV #IS.SUC&377,R0 ; Successful end, no Rcrds/TMKs CALL $IOALT ; spaced and endup request. JMP MFINI ; Service any pending requests. ; Handle Spacing Count. 10$: CLR R1 ; R1 - Space Dir; EQ-FWD, NEQ-REV. TST SPCNT(R3) ; Space Forward ? BPL 20$ ; IF PL, Yes. NEG SPCNT(R3) ; Count adjustment and INC R1 ; REV indication. ; Space Files/Block's ? 20$: CMP #IO.SPF,-4(R0) ; Space via TMK's ? BEQ 40$ ; IF EQ, Yes. ; Determine Space Blocks Command. MOV #SPFREC,SPCNG(R3) ; > Space FWD blocks. TST R1 ; Space records FWD ? BEQ 30$ ; IF EQ, Yes. MOV #SPRREC,SPCNG(R3) ; > Space REV blocks. ; Setup NDT Command. 30$: CLR SPACED(R3) ; No Blks/TMK's yet spaced. MOVB @SPCNG(R3),U.BUF(R5) ; Set up NDT Function Code. SPCAGN: MOV #255.,R1 ; R1 - Spacing command count. CMP SPCNT(R3),R1 ; Space GT 255 Blcks/TMKs ? BHI 35$ ; IF HI, Yes. MOV SPCNT(R3),R1 ; Space LT 255 Blcks/TMKs. 35$: SUB R1,SPCNT(R3) ; SPCNT - to yet space. MOVB R1,U.BUF+1(R5) ; Set up NDT command (spacing) count. MOV R1,SPCIO(R3) ; Current I/O space count. MOV SPCNG(R3),R0 ; R0 > Spacing Subfunction Table. BR SPSTRT ; Now issue I/O. ; Determine Space Files Command. 40$: MOV #SPRTMK,SPCNG(R3) ; > Space REV TMK. TST R1 ; REV TMK ? BNE 30$ ; IF NE, Yes. MOV #SPFTMK,SPCNG(R3) ; > Space FWD TMK. BITB #US.LAB,U.STS(R5) ; Labelled tape ? BNE 30$ ; IF NE, Yes. MOV #SPLTMK,SPCNG(R3) ; > Space FWD TMK/LEOT. BR 30$ ; . . cont . .DSABL LSB .PAGE .SBTTL CANCEL I/O OPERATION ;+ ; -- MFCAN -- ; ; Driver called as result of QIO IO.KIL request or EXEC Task rundown. ; Called because UC.KIL set in U.CTL or US.BSY set in U.STS. ; ; Inprogress I/O then ends by one of two ways. ; 1. Normal end - ISR, release packet. RD/WRT - Normal completion. ; If error recovery required and marked for abort, RD/WRT ended. ; 2. Abnormal end - Terminate other I/O requests via TMO routine. ; ; Register configuration upon entry to MFCAN: ; R0 - > Current I/O Packet. R3 - RH Controller Index. ; R1 - > Current Task TCB. R4 - > SCB. ; R5 - > UCB. ;- MFCAN: CMP I.TCB(R0),R1 ;; I/O owned by requesting task? BNE 10$ ;; IF NE, No. BISB #US.ABO,U.STS(R5) ;; Indicate I/O abort request (no recovery). 10$: RETURN .SBTTL POWERFAIL ENTRY POINT ;+ ; -- MFPWF -- ; ; Driver called after: ; 1. System power failure and subsequent recovery. ; 2. System Bootstrapped. ; 3. Driver loaded. ; ; The driver performs the following: ; 1. Sets US.PWF that powerfailure occured. Normal QIO functions are ; disallowed with the exception of IO.RWD, IO.RWU, IO.SEC, IO.STC, ; and IO.SMO. Successful IO.RWD, IO.RWU and IO.SMO reset the ; powerfailed indication and allow normal operations to resume. ; ; Register configuration upon entry to MFPWF: ; R3 - RH Controller index ; R4 - > SCB ; R5 - > UCB ;- MFPWF: .IF DF P$$RFL BISB #US.PWF,U.STS(R5) ; Set Powerfailed Indication. .ENDC ;P$$RFL MOV S.CSR(R4),R2 ; R2 > Device REGS. CLR U.CW2(R5) ; Reset Tape Characteristics word. BIS #C2.CLR,MFCS2(R2) ; Reset RH/TM78's. MOV #C1.IE!C1.DVA,MFCS1(R2) ; Allow Interrupts on this RH. MOV U.DCB(R5),DCBPTR ; DCB > - Driver restart fallback. MOV R5,CNTBL(R3) ; UCB > - Unsolicited Intrpt Hndlng. RETURN .PAGE .SBTTL TIMEOUT ENTRY POINT ;+ ; -- MFOUT -- ; ; Called by Exec due to S.CTM timeout per the following situations: ; ; 1. I/O in progress - may be I/O requested or spawned I/O. ; a. US.ABO pending - End request, abort I/O. ; b. Timeout - End request. Operation should have completed. ; 2. DQDIO - I/O busy. Could not issue I/O request. ; a. TU78 in previous Rewind mode. ; b. TM78 Clear issued. ; c. TM78 put Offline. ; ; Register configuration upon entry to MFOUT: ; R0 = IE.DNR, Device Not Ready. R3 - RH Cntrlr Index, S.CON. ; R2 - CSR, S.CSR. R4 - > SCB. ; R5 - > UCB.  ;- MFOUT: DECB S.STS(R4) ;; Completed Timeout Subcycle. BITB #US.ABO,U.STS(R5) ;; Abort I/O request ? BEQ 10$ ;; IF EQ, No. BICB #US.ABO,U.STS(R4) ;; Aborting request - MOV #IE.ABO&377,R0 ;; Request end status. 5$: BIC #C1.IE,@S.CSR(R4) ;; Disable TM Interrupt. MTPS #0 ;; Allow interrupts. SUBR ENDRQS ; End I/O request. CALL CLRTM ; Abort physical I/O. RETURN 10$: TST INPROG(R3) ;; I/O In Progress ? BEQ 20$ ;; IF EQ, No. TSTB S.STS(R4) ;; Timeout Subcycles left ? BNE 15$ ;; IF NE, Yes. Restart Timer. 12$: .IF DF D$$IAG ;; If Diagnostics. CALL MFDGNT ;; Pass TM78 REG's if diagnostics. .ENDC MOV #IE.TMO&377,R0 ;; Timeout occured. .IF DF E$$DVC ;; If Error Logging Device. CALL $DTOER ;; Log Device Timeout. .ENDC BR 5$ ;; End request. ; Restart TIMER. 15$: MOVB S.ITM(R4),S.CTM(R4) ;; Restart timer. RETURN ;; Until next Timeout. ; DQD Request. Could not previously issue I/O request. 20$: TSTB S.STS(R4) ;; Timeout Subcycles left ? BNE 15$ ;; IF NE, Yes. Restart Timer. ; DQD Request. Timeout. BIT #M.RWD,U.CW2(R5) ;; Tape Drive Rewinding ? BNE 12$ ;; IF NE, Yes. End request. MOV U.SUB(R5),MFCS2(R2) ;; Select TM UNIT. TST MFCR(R2) ;; TM78 Ready for Command ? BPL 12$ ;; IF PL, No. End request. MTPS #0 ; Allow interrupts. MOV IOFCT(R3),R0 ; > IOFCT table, TST (R0)+ ; Preprocess. JMP @RTRNAD(R3) ; Service DQD request. .PAGE .SBTTL INTERRUPT SERVICING ;+ ; $MFINT - TM78/TU78 Mag Tape Interrupt Service Routine ;- INTSE$ MF,PR5,T$$M78 ;;; Map ISR, Set Processor Priority. ; ; R5 > UCB. R4= RH Controller Index. ; MOV U.SCB(R5),R4 ;;; R4 > SCB BIC #C1.IE,@S.CSR(R4) ;;; Make sure no unsolicited INTRPTS. MOVB S.CON(R4),R4 ;;; Restore RH Controller Index. CALL $FORK ;;; MFINT - Another Intrptbl System Process. ; Current timeout count, S.CTM, cleared. ;+ ; The TM78 generates both solicited and unsolicited interrupts: ; Unsolicited interrupts can not be disabled. Unsolicited interrupts ; indicate tape units coming on line and hardware failure. ; Solicited interrupts occur as a result of Data/Non Data Transfer Requests. ; ; Starting a data transfer request defers non data transfer interrupts ; pending data transfer completion. ; ; Potential hazard: A data transfer is initiated. Driver resets and ; maintains C1.IE (MFCS1) reset at time Data Transfer Interrupt occurs. ; The data transfer interrupt will be lost. ; ; Interrupt servicing is prioritized to handle Data Transfer interrupts ; first - followed by servicing all Non Data Transfer Atentions present. ;- MOV R4,R3 ; R3 - RH Controller Index. MOV U.SCB(R5),R4 ; R4 - > SCB. R5 - > UCB. MOV S.CSR(R4),R2 ; R2=CSR. TST DTCMD(R3) ; Data Transfer started that RH ? BEQ 10$ ; IF EQ, No. BIT #C1.TRE,MFCS1(R2) ; RH transfer error indicated? BEQ 5$ ; IF EQ, No. ;+ ; **** INCOMPLETE **** ; DTCMD - TRANSFER ERRROR. Determine whether RECOVERABLE - Recovery procedure. ;- 5$: SUBR DTINT ; Service Data Transfer Interrupt. 10$: TST MFAS(R2) ; Attention Interrupts ? BEQ 20$ ; IF EQ, No. SUBR NDINT ; Service Non Data Transfer Interrupts. 20$: TST INPROG(R3) ; I/O still active on this RH (Rtry Oprt) ? BNE 30$ ; IF NE, Yes. TST DQDIO(R3) ; Request yet pending ? BNE 30$ ; IF NE, Yes. BIT #M.RWD,U.CW2(R5) ; Rewind incomplete ? BNE 30$ ; IF NE, Yes. JMP MFINI ; Dequeue another I/O request. 30$: MOV #C1.IE!C1.DVA,MFCS1(R2) ; Allow further interrupts on this RH. RETURN ; Till next interruption. .PAGE .SBTTL NDT INTERRUPT SERVICING ;+ ; Non Data Transfer Interrupt Servicing. ; ; Service active ATTNS - both solicited and unsolicited. ; ; The ATTN bit position identifies the TM Unit, Register MFNDI identifies ; NDT Interrupt Code/Tape Unit (Attn Adr). ; ; If unsolicited: appropriate measures are taken and ATTN is reset. ; ; If solicited: verify interrupt an expected value. ; Unexpected values end the request and driver dependencies. ; If expected, call I/O ending routine. ; ; Control is returned to the ATTN scan routine to service active ATTN's. ;- .BLKW ; Reserve space - Return address. NDINT: SUBR FNDUNT ; Obtain a TM Unit, ATTN pending. BCC 10$ ; IF CC, Found a TM Unit. RTRN NDINT ; No further ATTN's. 10$: SUBR UNSLCT ; Unsolicited Interrupt ? BCS NDINT ; IF CS, Yes. Any more ? SUBR VALNDI ; Reasonable Interrupt ? BCC 20$ ; IF CC, Yes. SUBR LOGERR ; Log Error. MOV #IE.FHE&377,R0 ; Indicate Unrecoverable Situation SUBR ENDRQS  ; and End Request. RTRN NDINT ; Service pending NDT Interrupts. 20$: CALL RTRNCD ; Set up I/O Return Code - R0. BIC #^C<377>,R1 ; R1 - MFAS Reset Mask. MOV IOFCT(R3),R4 ; R4 > I/O function. BIT #M.RWD,U.CW2(R5) ; Perhaps previous RWD operation ? BEQ 30$ ; IF EQ, No. MOV #IORWD,R4 ; R4 > RWD function. 30$: ADD #ISRSRV,R4 ; R4 > I/O Interrupt servicing. TST (R4) ; Spacing operation ? BEQ 35$ ; IF EQ, Yes. MOV (R4),R4 ; > and Service 33$: MOV #.+10,-2(R4) ; NDT I/O JMP (R4) ; Endup. BR NDINT ; Service other ATTN's. 35$: MOV #SPCISR,R4 ; R4 > Space ISR endup. BR 33$ ; . . Cont. .PAGE .SBTTL NDT INTRPT ROUTINES ;+ ; -- FNDUNT -- ; ; Find and service an ATTN request. ; ; The subroutine scans MFAS R -> L, to obtain a TM Unit #. ; IF NO TM Unit found, CS. ; IF TM Unit found, CC, NDT Interrupt code, TM UNIT#, MFAS Reset Mask. ; ; INPUTS - ; ; R2 - CSR, R3 - RH CNTRL INDX. ; ; OUTPUTS - ; ; ATTN Not Found - CS. ; ; ATTN Found - CC, ; R0 - [MFNDI] R1 - TM UNIT#, MFAS Reset Mask. ; R2 - CSR, R3 - RH CNTRL INDX. ; R4 - > SCB, R5 - > UCB. ;- .BLKW ; Reserve space - Return Address. FNDUNT: MOV #1,R1 ; R1- HI Byte,TM UNIT#. LO Byte,MFAS Rst Mask. MOV MFAS(R2),-(SP) ; (SP) - ATTN's, MOVB #8.,1(SP) ; 1(SP) - # of ATTN's to be checked. 10$: ASRB (SP) ; This ATTN ? BCS 20$ ; IF CS, Yes. ASLB R1 ; Update MFAS Rst Mask, SWAB R1 ; and INCB R1 ; next SWAB R1 ; UNIT. DECB 1(SP) ; One less ATTN to check.  BNE 10$ ; IF NE, Check for other ATTN's active. SEC ; No TM UNIT found. BR 30$ 20$: SWAB R1 ; Select MOVB R1,MFCS2(R2) ; TM UNIT. SWAB R1 ; R1- TM UNIT#, MFAS Rst Mask. MOV R1,RSTATN(R3) ; NDT Command - CLRB RSTATN+1(R3) ; ATTN Reset Mask. MOV MFNDI(R2),R0 ; R0- [MFNDI]. CLC ; TM UNIT found. 30$: INC (SP)+ ; Return Stack as found. RTRN FNDUNT .PAGE ;+ ; -- UNSLCT -- ; ; Validate NDT INTRPT for unsolicited input. ; ; ATTN's may come from TM UNITS I/O active (solicited)/inactive (unsolicited). ; ; Unsolicited ATTN's result from tape units coming ONLINE/equipment failure. ; ONLINE interrupts are dismissed. IF Driver has a request DQD, such I/O ; request is reissued. ; Equipment Failures require TM Clear's before any further I/O may proceed. ; ; INPUTS - ; ; R0 - [MFNDI] R1 - TM UNIT#, MFAS Rst Mask ; R2 - CSR R3 - RH CNTL INDX ; ; OUTPUTS - CS, Unsolicited. CC, Solicited. ; ; R0 - HI BYTE: Tape Unit #, LO BYTE: NDT INTRPT Code. ; R1 - HI BYTE: TM UNIT #, LO BYTE: MFAS Rst Mask. ; R2 - CSR ; R3 - RH CNTL INDX ;- .BLKW ; Reserve space - Return Address. UNSLCT: BIC #^C<1477>,R0 ; R0- HI Byte, Tape Unit#. LO Byte, INTRPT code CMPB #17,R0 ; Tape Unit put Online ? ; MFDS Valid if Online - until reset MFAS. BNE 5$ ; IF NE, No. MOVB R1,MFAS(R2) ; Reset ATTN. TST DQDIO(R3) ; Driver has a DQD pending request? BEQ 20$ ; IF EQ, No. JMP @RTRNAD(R3) ; Reissue pending request. 5$: CMPB #32,R0 ; TM Fault B (TM Detected Failure) ? BEQ 10$ ; IF EQ, Yes. CMPB #34,R0 ; MB Fault (MASSBUS Control Bus Fault) ? BEQ 10$ ; IF EQ, Yes. CLC ; Solicited interrupt. BR 22$ 10$: CLR R4 ; Indicate unsolicited interrupt and SUBR LOGERR ; Log Device Error - Device Regs, XND SNS Data CALL CLRTM ; Clear TM78 - Resets ATTN's. 20$: SEC ; Unsolicited interrupt. 22$: RTRN UNSLCT .PAGE ;+ ; -- VALNDI -- ; ; Validate Non Data Interrupts. Obtain UCB/SCB for ATTN. ; ; 1. If not in configuration, not INPROG or Tape Unit not ; previously set into Rewind - will take no action. ; Reset the ATTN and continue scanning for additional ATTN's. ; ; This happens when OS systems moved about without correcting the system data ; bases or by adding on equipment that data bases have not been generated for. ; ; 2. Validate NDT Interrupt for I/O INPROG or Tape Unit in previous RWD. ; ; INPUTS - ; R0 - Tape Unit#,Intrpt Code R2 - CSR ; R1 - TM UNIT#,MFAS Rst Mask R3 - RH CNTL INDX ; ; OUTPUTS - CS, INVALID. CC, Valid. Registers preserved. ;- .BLKW ; Reserve space - Return Address. VALNDI: MOV DCBPTR,R5 ; R5 > DCB. PUSH ; TM UNIT#, MFAS Rst Mask, Tape Unit#, INT Code MOV D.UCBL(R5),-(SP) ; UCB lenght, MOV D.UNIT(R5),-(SP) ; HI/LO UCB unit #s on Stack. MOV D.UCB(R5),R5 ; R5 > 1st UCB. 5$: CMP R5,U.RED(R5) ; UCB Redirected ? BNE 20$ ; IF NE, Yes. TST INPROG(R3) ; I/O Active ? BEQ 10$ ; IF EQ, No. CMP R5,CNTBL(R3) ; UCB same as for I/O INPROG ? BEQ 40$ ; IF EQ, Yes. 10$: BIT #M.RWD,U.CW2(R5) ; Tape Unit prev set RWD ? BEQ 20$ ; IF EQ, No. CMPB U.UNIT(R5),5(SP) ; Same Tape Unit ? BNE 20$ ; IF NE, No. CMPB U.SUB(R5),7(SP) ; Same TM UNIT ? BNE 20$ ; IF NE, No. MOV U.SCB(R5),R4 ; R4 > SCB. CMPB S.CON(R4),R3 ; Same RH ? BEQ 42$ ; IF EQ, Yes. 20$: CMPB (SP),1(SP) ; Last UCB ? BEQ 30$ ; IF EQ, Yes. ADD 2(SP),R5 ; R5 > next UCB. INCB (SP) ; LO # - Current UCB #. BR 5$ ; Keep Checking rest of MF UCB's. 30$: ADD #10,SP ; Adjust Stack ->. UCB not found. MOVB R1,MFAS(R2) ; Reset ATTN, SEC ; Unreasonable Interrupt. RTRN VALNDI 40$: MOV U.SCB(R5),R4 ; R4 > SCB. 42$: ADD #10,SP ; Maintain stack integrity. CALL VALIDT ; Validate NDT Interrupt. RTRN VALNDI .PAGE ;+ ; -- VALIDT -- ; ; Validate INTRPT Code for INPROG or prev RWD request. ; ; Verify INTRPT Code in range and per valid interrupt mask. ; Valid: CC. Invalid, CS. ; ; INPUTS - ; R0 - Tape Unit#,Intrpt Code R3 - RH CNTL INDX ; R1 - TM UNIT#,MFAS Rst Mask R4 - > SCB. ; R2 - CSR R5 - > UCB. ; ; OUTPUT - CS, Invalid. CC, Valid. Registers preserved. ;- VALIDT: PUSH ; Reference values. MOV IOFCT(R3),R1 ; R1 > I/O active table entry. CMP R5,CNTBL(R3) ; INPROG Validation ? BEQ 10$ ; IF EQ, Yes. MOV #IORWD,R1 ; R1 > RWD table entry. 10$: ADD #VALI1,R1 ; R1 > 1st validation mask. TST (R1) ; Spacing operation ? BNE 12$ ; IF NE, No. MOV SPCNG(R3),R1 ; R1 > 1st validation mask ADD #SVALI1,R1 ; in Spacing Subfunction table. 12$: MOVB (SP),R0 ; R0 - Interrupt Code. CMPB R0,#35 ; Interrupt code out of range ? BGE 30$ ; IF GE, Yes. CLR INTCD1(R3) ; Initialize 0-17 and 20-34 CLR INTCD2(R3) ; interrupt bit descriptors. MOV #INTCD1,R2 ; R2 > Interrupt 0-17 bit descriptor. CMP R0,#17 ; Interrupt 0-17 range? BLOS 20$ ; IF BLOS, Yes. MOV #INTCD2,R2 ; R2 > Interrupt 20-34 bit descriptor. BIC #20,R0 ; Interrupt code in binary/bit range. TST (R1)+ ; R1 > 2nd validation mask. 20$: ADD R3,R2 ; R2 now > correct Interrupt bit descriptor. ASL R0 ; Convert Interrupt Code ADD #$BTMSK,R0 ; TO MOV (R0),R0 ; Bit Mask Value. MOV R0,(R2) ; Current Interrupt code - per Bit descrition. BIT R0,(R1) ; Valid Interrupt ? BEQ 30$ ; IF EQ, No. CLC ; Indicate Interrupt Code Valid. 25$: POP ; Maintain stack integrity. RETURN 30$: SEC ; Indicate interrupt code Invalid. BR 25$ .PAGE .SBTTL NDT INTRPT SERVICING ;+ ; Non Data Interrupt Servicing. ;- ;+ ; Sense Tape Charecteristics - Completion. ; Result of servicing IO.SMO, IO.STC and IO.SEC requests. ; ; INPUTS - ; R0 - LO BYTE; I/O Request Return Code HI BYTE; 0's. ; R1 - MFAS Reg Reset Mask. ; R2 - CSR. R3 - RH CNTL INDX. R5 - > UCB. ; ; OUTPUTS - ; R2 - CSR, R3 - RH CNTL INDX, R4 - > SCB, R5 - > UCB. ;- .BLKW ; Reserve space - Return Address. SNSISR: CMPB #IS.SUC,R0 ; Successful ? BEQ 5$ ; IF EQ, Yes. SUBR LOGERR ; Log Error. 3$: MOV #IE.FHE&377,R0 ; Hardware problems. BIS #M.SER,U.CW2(R5) ; Select problems. BR 25$ 5$: PUSH MFDS(R2) ; Local copy - Tape Drive Status. BIT #DS.BOT,(SP) ; BOT ? BEQ 10$ ; IF EQ, No. BIS #M.BOT,U.CW2(R5) ; Status- BOT. 10$: BIT #DS.EOT,(SP) ; EOT ? BEQ 12$ ; IF EQ, No. BIS #M.EOT,U.CW2(R5) ; Status- EOT. 12$: BIT #DS.FPT,(SP) ; Write Locked ? BEQ 14$ ; IF EQ, No. BIS #M.HWL,U.CW2(R5) ; Status- Write locked. 14$: BIT #DS.RDY,(SP) ; Ready ? BEQ 15$ ; IF EQ, No. BIT #DS.AVL,(SP) ; Available to this MASSBUS ? BNE 20$ ; IF NE, Yes. 15$: BIS #M.SER,U.CW2(R5) ; Status- Select Error (Not available for use) 20$: POP ; Maintain Stack. CMP #IO.SEC,@IOFCT(R3) ; IO.SEC request ? BNE 30$ ; IF NE, No. 25$: MOV U.CW2(R5),R1 ; Second I/O Status Word - Tape Characteristics SUBR ENDRQS ; End Request. RTRN SNSISR ; Return to NDT Interrupt Servicing. ; IO.SMO.or.IO.STC - Tape Characteristics M.IWR, M.SWL, M.1600 bits involved. 30$: BIC #M.SWL!M.IWR,U.CW2(R5) ; Perhaps - No Soft Write Lock, IWR. BIT #M.SWL,SPCNT(R3) ; User - Software Write Lock ? BEQ 32$ ; IF EQ, No. BIS #M.SWL,U.CW2(R5) ; Software - No write to tape. 32$: BIT #M.IWR,SPCNT(R3) ; User - Inhibit writing with extended gap ? BEQ 34$ ; IF EQ, No. BIS #M.IWR,U.CW2(R5) ; User- No write extended gap(Error Recovery). 34$: BIT #M.1600,SPCNT(R3) ; User - 6250BPI Mode ? BEQ 40$ ; IF EQ, 6250BPI Mode. ; User desires 1600BPI mode. BIT #M.1600,U.CW2(R5) ; TM78 in 1600BPI Mode ? BNE 25$ ; IF NE, Yes. No change needed. End Request. BIT #M.BOT,U.CW2(R5) ; TU78 at BOT ? BEQ 3$ ; IF EQ, No. Can't change DENSITY CONTROL. BIS #M.1600,U.CW2(R5) ; TM78 Commands via 1600 BPI mode. BR 45$ ; End Request. ; User desires 6250BPI mode. 40$: BIT #M.1600,U.CW2(R5) ; TM78 in 6250BPI Mode ? BEQ 25$ ; IF EQ, Yes. No change needed. End Request. BIT #M.BOT,U.CW2(R5) ; TU78 at BOT ? BEQ 3$ ; IF EQ, No. Can't change DENSITY CONTROL. BIC #M.1600,U.CW2(R5) ; TM78 Commands via 6250 BPI mode. 45$: BICB #US.PWF,U.STS(R5) ; Reset Power Failed Indication. BR 25$ ; End Request.  ;+ ; Completed Space Tape Operation: ; FWD/REV via TMKS, FWD to LEOT, FWD/REV via Blocks (Records). ; ; INPUTS - ; R0 - LO BYTE; I/O Request Return Code HI BYTE; 0's. ; R1 - MFAS Reg Reset Mask. ; R2 - CSR. R3 - RH CNTL INDX. R5 - > UCB. ; ; OUTPUTS - ; R2 - CSR, R3 - RH CNTL INDX, R4 - > SCB, R5 - > UCB. ;- .BLKW ; Reserve space - Return Address. SPCISR: BIT #DON!TMK!BOT!LEOT!NAVL!NTEX!NTCP,INTCD1(R3) ; End request? BNE 20$ ; IF NE, Yes. BIT #NRDY!OFLN,INTCD1(R3) ; Not ready for command or Unit Offline ? BNE 40$ ; IF NE, Yes. SUBR LOGERR ; Log Error. 10$: MOV SPACED(R3),R1 ; Indicate TMK's/Blocks Spaced. SUBR ENDRQS ; End Request. 18$: RTRN SPCISR ; return to NDT Interrupt Servicing. ; IS.SUC (Normal End). IF Interrupt code is DON, THEN may need to Restart I/O. 20$: PUSH R0 ; Save R0 - Temp use. MOVB MFNDI+1(R2),R0 ; R0= BIC #^C<3>,R0 ; Tape Unit #. ASL R0 ; Make word index - ADD R2,R0 ; To access Residual MOVB MFND0+1(R0),R0 ; TMK/Block Count. BIC #^C<377>,R0 ; R0= Residual TMK/Block Count. BEQ 30$ ; IF EQ, Current requested count exhausted. SUB R0,SPCIO(R3) ; SPCIO - TMK's/Block's spaced. 30$: ADD SPCIO(R3),SPACED(R3) ; Maintain TMK's/Block's spaced. POP R0 ; Maintain Reg. BIT #DON,INTCD1(R3) ; Interrupt code DON ? BEQ 10$ ; IF EQ, No. End Request. TST SPCNT(R3) ; Further TMK's/Blocks to Space ? BEQ 10$ ; IF EQ, No. MOV U.SCB(R5),R4 ; R4 > SCB. JMP SPCAGN ; Restart I/O to complete request. ; Can't communicate with unit - Offline or Not Ready to Execute Command. 40$: TST U.ACP(R5) ; MTAACP ? BNE 10$ ; IF NE, Yes. End request. CALL MSG ; Console message - Unit condition. BR 18$ ; Return to NDT Interrupt Servicing. ;+ ; Completed: Write Tape Mark; Erase 3" Gap; Data Security Erase; ; Rewind Tape; Rewind/unload Tape. ; ; INPUTS - ; R0 - LO BYTE; I/O Request Return Code HI BYTE; 0's. ; R1 - MFAS Reg Reset Mask. ; R2 - CSR. R3 - RH CNTL INDX. R5 - > UCB. ; ; OUTPUTS - ; R2 - CSR, R3 - RH CNTL INDX, R4 - > SCB, R5 - > UCB. ;- RWDRET: .BLKW ; Reserve space - Return Address. RWDISR: TST INPROG(R3) ; Interrupt to initial Rewind ? BNE 30$ ; IF NE, Yes. BIC #M.RWD,U.CW2(R5) ; Rewind over. CMPB #IS.SUC,R0 ; Any complications. BEQ 10$ ; IF EQ, No. CLR R4 ; TMFA/TUFA error - Request previously ended. SUBR LOGERR ; Log it. 10$: MOVB R1,MFAS(R2) ; Reset ATTN. TST DQDIO(R3) ; Driver need complete previously DQD request? BEQ 20$ ; IF EQ, No. JMP @RTRNAD(R3) ; Execute DQD/pending request. 20$: RTRN RWDISR ; Return to NDT Interrupt Servicing. 30$: BIT #RWD,INTCD1(R3) ; Rewind initiated? BNE 40$ ; IF NE, Yes. BIC #M.RWD,U.CW2(R5) ; Rewind I/O completed. 40$: MOV RWDRET,WTMRET ; Maintain linkage. BR WTMISR ; End Request. WTMRET: .BLKW ; Reserve space - Return Address. WTMISR: ERGISR: DSEISR: UNLISR: BIT #DON!RWD,INTCD1(R3) ; Clear Power Failed Indication ? BEQ 5$ ; IF EQ, No. BICB #US.PWF,U.STS(R5) ; Reset Power Failed Indication. 5$: BIT #DON!EOT!FPT!NAVL!NTEX,INTCD1(R3) ; End Request ? BNE 10$ ; IF NE, Yes. BIT #NRDY!OFLN,INTCD1(R3) ; Not ready for command, Unit Offline ? BNE 30$ ; IF NE, Yes. SUBR LOGERR ; Log Error. 10$: SUBR ENDRQS ; End Request. 20$: RTRN WTMISR ; Return to NDT Interrupt Servicing. ; Can't communicate with unit - Offline or Not Ready to Execute Command. 30$: TST U.ACP(R5) ; MTAACP ? BNE 10$ ; IF NE, Yes. End request. CALL MSG ; Console message - Unit condition. BR 20$ ; . . Continue. ;+ ; Send 'Device Not Ready' Message if TU78 Offline ; and 'Select Error' Message if TM78 Not Ready for Command. ;- MSG: PUSH ; Save REG's. MOV #T.NDNR,R0 ; 'Device Not Ready' message. CMPB #IE.OFL,(SP) ; Tape Unit Offline? BEQ 10$ ; IF EQ, Yes. MOV #T.NDSE,R0 ; 'Select Error' message. 10$: CALL $DVMSG ; Output message. POP ; Restore REG's. CLR INPROG(R3) ; No I/O active, INC DQDIO(R3) ; I/O Request to be completed. MOVB R1,MFAS(R2) ; Reset ATTN.  MOV U.SCB(R5),R4 ; R4 > SCB. MOVB #1,S.STS(R4) ; Start 15 sec timeout. MOVB #15.,S.CTM(R4) ; Try again in 15 sec. RETURN .PAGE .SBTTL DT INTERRUPT SERVICING ;+ ; Data Transfer Interrupt Servicing. ; ; Service Read/Write/Extended Sense Requests. ; ; INPUTS - ; ; R2 - CSR R3 - RH CNTRL INDX ; R4 - > SCB R5 - > UCB ; ; XNSCMD - NEQ=XND SNS Operation. ;- .BLKW ; Reserve space - Return Address. DTINT: TST XNSCMD(R3) ; Extended Sense Request ? BEQ 5$ ; IF EQ, No. .IF DF E$$DVC JMP XNSISR ; Endup Extended Sense Request. .ENDC ;E$$DVC 5$: MOV MFDI(R2),R0 ; R0 - Dt Failure Cd, DPR, Dt Interrupt Cd. CALL VALIDT ; Validate DT Interrupt. BCC 10$ ; IF CC, Valid - Complete request. SUBR LOGERR ; Log Error. MOV #IE.FHE&377,R0 ; Indicate Unrecoverable Situation SUBR ENDRQS ; and end request. RTRN DTINT ; Service pending NDT Interrupts. 10$: CALL RTRNCD ; Set up I/O Return Code - R0. BIT #DON!TMK!BOT!EOT!FPT!NRDY!NAVL!OFLN!NTEX!NTCP,INTCD1(R3) ; Interrupt Code 0-17 range ? BEQ 100$ ; IF EQ, No. Code 20-34 Range. BIT #DON!EOT,INTCD1(R3) ; Successful end ? BNE 12$ ; IF NE, Yes. BIT #NRDY!OFLN,INTCD1(R3) ; Not ready for command, Unit Offline? BNE 20$ ; IF NE, Yes. BIT #BOT,INTCD1(R3) ; Backed into BOT? BEQ 15$ ; IF EQ, No. CLR R1 ; No Data Transfered. BR 15$ ; . . Continue. 12$: MOV U.CNT(R5),R1 ; Second I/O Status Word - # Bytes Transferred. 15$: SUBR ENDRQS ; End Request. 19$: RTRN DTINT ; Service NDT ATTN's. 20$: TST U.ACP(R5) ; MTAACP ? BNE 15$ ; IF NE, Yes. End request. CALL MSG ; Console message - Unit condition. BR 19$ ; . . Continue. 100$: WRTISR: RDFISR: RDRISR: RTRN DTINT .PAGE .SBTTL LOG DEVICE ERRORS ;+ ; -- LOGERR -- ; ; INPUTS - ; R2 - CSR R3 - RH CNTRL INDX R5 - > UCB ; R4 = EQ; Unsolicited I/O error, R0 - Don't care. ; R4 - >SCB; Solicited I/O error, R0 - I/O Status Code. ; ; OUTPUTS - REG's Preserved. R1 Altered. ;- .BLKW ; Reserve space - Return Address. LOGERR: .IF DF E$$DVC ; IF Log Device Errors - MOV #108.,R1 ; R1 - # Error Log Data Bytes - Assume RH70. ; 54. Reg's - 24. Dev Reg's, 30. Ext Sns Data. .IF DF M$$EXT ; IF 22 Bit Extended Addressing (11/70,11/44) - BIT #DV.MBC,U.CW1(R5) ; RH11 ? BNE 10$ ; IF NE, No - RH70. SUB #4,R1 ; No MFBAE/MFCS3 Reg(s) to log. 10$: .ENDC .IF DF D$$IAG ; If Diagnostics - TSTB INPROG+1(R3) ; Passed DEV REG's already ? BNE 15$ ; IF NE, Yes. CALL MFDGNT ; Pass TM78 REG's. BCC 15$ ; IF CC, Not UMD Request. INC INPROG+1(R3) ; Passed DEV REG's. .ENDC 15$: PUSH <,R3,R2,R0> ; > Error Packet, Save R3,R2,R0 Reg(s). CALL $LOGER ; Request Error Packet. MOV R3,-6(SP) ; Save > Error Packet. POP ; Restore R0,R2,R3 & > to Error Packet. BCS RTNLGR ; IF CS, Can't log error. PUSH ; Save R2,R0. R1 > Error Packet Data Area. MOV #TMREGS,R0 ; R0 - # Dev Reg(s). 20$: MOV (R2)+,(R1)+ ; Move a Device Register. DEC R0 ; One less Device Register to move.  BNE 20$ ; IF NE, more device registers to move. POP ; Restore R0,R2. .IF DF M$$EXT ; IF 22 bit Extended Addressing (11/70, 11/44) BIT #DV.MBC,U.CW1(R5) ; RH11 ? BEQ 30$ ; IF EQ, Yes. .IF DF M$$IXD ; IF Mixed MASSBUS MOV 74(R2),(R1)+ ; Move MFBAE Reg MOV 76(R2),(R1)+ ; Move MFCS3 Reg .IFF MOV MFBAE(R2),(R1)+ ; Move MFBAE Reg MOV MFCS3(R2),(R1)+ ; Move MFCS3 Reg .ENDC 30$: .ENDC MOV #60.,DTCNT(R3) ; Extended Sense - 60. bytes. CLR DTADR1(R3) ; Error Packet in Exec POOL area. MOV R1,DTADR2(R3) ; R1 > Dt Area in Error packet- after DEV REG's INC XNSCMD(R3) ; Almost ready to request Extended Sense data. TST R4 ; Logging error from Solicited I/O ? BNE 40$ ; IF NE, Yes. MOVB XNSCMD(R3),XNSCMD+1(R3) ; Remember - Log Error,Unsolicited I/O. 40$: JMP DTIOGO ; Request Extended Sense data. XNSISR: TSTB XNSCMD+1(R3) ; Log error (Unsolicited I/O) ? BEQ RTNLGR ; IF EQ, No. Return to caller. PUSH ; Save REG's. CLR R2 ; Retry count EQ. MOV ERRPKT(R3),R3 ; R3 > Error Packet. CLR R4 ; R4 .EQ. (Unsolicited I/O). CALL $FNERL ; End Error Logging. POP ; Restore REG's. MOV RSTATN(R3),MFAS(R2) ; Reset TM ATTN. .ENDC ;E$$DVC RTNLGR: RTRN LOGERR ; Return to Caller. .PAGE .SBTTL ABORT TM78 OPERATION/DRIVER DATA BASE DEPENDENCIES ;+ ; -- CLRTM -- ; ; Called to regain TM78 control. ; ; 1. Reset TM78 via TM CLR. ; 2. Update driver data base - for all TU78's on that TM78. ; a. U.CW2 - M.RWD bit. ; b. S.CTM/S.STS bytes. ; ; Caller need update/maintain other current driver dependencies. ; For RSX11M, for a given RH, the driver only supports single thread I/O. ; ; INPUTS - ; ; R2 - CSR, R3 - RH controller Index, S.CON. ; R4 - > SCB, R5 - > UCB. ; ; OUTPUTS - ; ; Registers preserved. ;- CLRTM: MOVB U.SUB(R5),MFCS2(R2) ; Select TM78 - BICB #C1.IE,MFCS1(R2) ; RH Interrupt Disabled, BIS #TMCLR,MFCR(R2) ; Reset/End TM I/O. PUSH ; Save 'em. MOV U.SUB(R5),R0 ; R0 - TM#. ASL R0 ; Compatibility with S.CON. MOV DCBPTR,R5 ; R5 > DCB. MOV D.UCBL(R5),-(SP) ; UCB lenght, MOV D.UNIT(R5),-(SP) ; HI/LO UCB unit #s on Stack. MOV D.UCB(R5),R5 ; R5 > 1st UCB. 10$: CMP U.SUB(R5),R0 ; Same TM Subcontroller ? BNE 20$ ; IF NE, NO. CMPB S.CON(R4),R0 ; Same RH Controler ? BNE 20$ ; IF NE, No. CMP R5,U.RED(R5) ; UCB Redirected ? BNE 20$ ; IF NE, Yes. BIC #M.RWD,U.CW2(R5) ; Tape unit not Rewinding. CLRB S.CTM(R4) ; No current timeout CLRB S.STS(R4) ; or timeout subcycles. 20$: CMPB (SP),1(SP) ; Last UCB ? BEQ 30$ ; IF EQ, Yes. ADD 2(SP),R5 ; R5 > next UCB. INCB (SP) ; LO # - Current UCB #. BR 10$ ; Handle other TU's on same RH/TM78. 30$: ADD #4,SP ; Maintain Stack integrity. POP ; Restore 'em. RETURN .PAGE .SBTTL SETUP I/O RETURN CODE ;+ ; -- RTRNCD -- ; ; INPUT - ; ; R0 - LO BYTE: Interrupt Code, Octal value. ; R3 - RH Cntl Index. ; ; OUTPUT - ; ; R0 - LO BYTE: I/O Request Return Code. ; HI BYTE: 0's.  ; ; Other Reg(s) preserved. ;- RTRNCD: BIC #^C<377>,R0 ; R0 - Interrupt Code only. ADD #RTRNTB,R0 ; > I/O Request Return Code MOVB (R0),R0 ; and provide it to BIC #^C<377>,R0 ; Caller. MOV R0,IOSTAT(R3) ; Save I/O Return Code. RETURN .PAGE .SBTTL END I/O REQUEST ;+ ; -- ENDRQS-- ; ; INPUT - ; ; R0 - I/O Request Return Code. ; R1 - 2nd I/O Status Word. ; R2 - CSR. ; R3 - RH CNTRL INDX. ; R5 - > UCB. ;- .BLKW ; Reserve space - Return Address. ENDRQS: MOV U.SCB(R5),R4 ; R4 > SCB. ; If Usermode Diagnostic - Pass Device Reg's. .IF DF D$$IAG ; If Diagnostics - TSTB INPROG+1(R3) ; Passed DEV REG's already ? BNE 5$ ; IF NE, Yes. CALL MFDGNT ; Pass TM78 REG's. 5$: .ENDC ; If Logged an Error - Endup Error Logging. .IF DF E$$DVC ; If Error Logging Device - BITB #SP.EIP,S.PRI(R4) ; Logged an Error ? BEQ 10$ ; IF EQ, No. MOV RTTBL(R3),R2 ; Setup Error Retry Counts, MOV ERRPKT(R3),R3 ; > Error Log Packet and CALL $FNERL ; Endup Error Logging for this request. 10$: .ENDC ; End Request. CALL $IODON ; End Request. MOV U.SCB(R5),R4 ; Restore R4, >SCB. MOVB S.CON(R4),R3 ; R3, RH CNTL INDX. MOV S.CSR(R4),R2 ; R2, CSR. TST DTCMD(R3) ; Completed Data request ? BNE 20$ ; IF NE, Yes. TST DQDIO(R3) ; Dequeued/never issued request ? BNE 20$ ; IF NE, Yes. TST INPROG(R3) ; I/O issued ? BEQ 20$ ; IF EQ, No. MOV RSTATN(R3),MFAS(R3) ; Reset TM ATTN. 20$: CLR DTCMD(R3) ; Clear CLR INPROG(R3) ; Driver CLR XNSCMD(R3) ; Request CLR DQDIO(R3) ; Processing indicators. RTRN ENDRQS .PAGE .SBTTL USER MODE DIAGNOSTIC REQUEST - ENDING SEQUENCING ;+ ; -- MFDGNT -- ; ; Determine if User Mode Diagnostic Function Call. ; ; If so - Then pass TM78 device registers. ; ; INPUTS - ; R2 - CSR ; R4 - > SCB. ; ; OUTPUTS - ; Reg(s) preserved ; CC - Not User Mode Diagnostic Function Call ; CS - User Mode Diagnostic Function Call. TM78 device reg(s) passed. ;- MFDGNT: MOV R1,-(SP) ; Save R1. $CRPAS mungs it. MOV S.PKT(R4),R1 ; R1 > current I/O packet. BITB #IQ.UMD,I.FCN(R1) ; User Mode Diagnostic Function Call? BEQ 20$ ; IF EQ, No. MOVB S.RCNT(R4),-(SP) ; Pass TM78 Device Reg(s)- MOVB #TMREGS,S.RCNT(R4) ; XND SNS not included. MOV R1,-(SP) ; Save > I/O packet. CMPB #IO.EOF/256.,I.FCN+1(R1) ; QIO Control Code #6 ? BEQ 10$ ; IF EQ, Yes. CMPB #IO.RWD/256.,I.FCN+1(R1) ; QIO Control Code #5 ? BEQ 10$ ; IF EQ, Yes. CALL $CRPAS ; Pass device reg(s) - Other QIO's. MOV (SP)+,R1 ; Maintain Stack. BR 15$ 10$: MOV I.PRM+14(R1),I.PRM+16(R1) ; Setup I/O packet MOV I.PRM+12(R1),I.PRM+14(R1) ; for $CRPAS. CALL $CRPAS ; Pass device reg(s). MOV (SP)+,R1 ; Maintain Stack. R1 > I/O packet. MOV I.PRM+14(R1),I.PRM+12(R1) ; Re-setup I/O packet MOV I.PRM+16(R1),I.PRM+14(R1) ; after $CRPAS. 15$: MOVB (SP)+,S.RCNT(R4) ; Restore # REG(s) passed to ERR LOG. SEC ; User Mode Diagnostic Function Call. 18$: MOV (SP)+,R1 ; Restore R1. RETURN 20$: CLC ; No Us:er Mode Diagnostic Function Call. BR 18$ .END :