ߋtv ?B-NO BOOT ON VOLUME @w p@w wP׭ ׭ w f& fwW#w v   @ @wP  @& 7 "  BLOCK@   IS BAD   -̂@ &   # p@ zw 7 P7 R & B g wD ѕ  Rì     s   p x] \Z 1  d s  -2&w* FWkQP.JkQf .rZkQX .FykQ .t 0 kQ .pkQ1.q8kQ .38kQ .8kQ .8kQ . 8kQ.kQ .kQ .8rkQ .pqkQ . kQ . kQ .MkQ .fkQ .fkQ .     c.%v(c.%v(c.%v(c.%v(c.%v(c.%v(c.%v(c.%v(c.   (rXz:c.bT  (   )]  +'jL^c+f  ,M0kQ ,"cw  {Qcw C-Krcw C-3cw  -}}  -Q$:  -jLp  -  -oQ  -cw #.cw  #. Ncw #.'jL^c. SINGLE USER, =1 => F/B UPDATE = 02. .RADIX 10. .IRP ...,<\UPDATE> .IF NE BF .TITLE RT-11FB V02C-0'... .IFF .TITLE RT-11SJ V02C-0'... .ENDC .ENDR .RADIX 8. .SBTTL EDIT LOG ; FOLLOWING ARE EDITS MADE FOR VERSION V02C: ;DV1 -- CORRECTS .CDFN CODE TO PROPERLY CHECK CHANNEL NUMBER. ; ;DV2 -- REMOVES ADDRESSING CHECK BY-PASS FOR KMON SO THAT ; ALL KMON .FETCHES ARE CHECKED. ; ;DV3 -- FIXES .ASS:DEV BUG. ; ;DV4 -- PREVENTS F/G JOB FROM .RELEASING HANDLER FETCHED IN B/G JOB. ; ;DV5 -- PREVENTS CRASH WHEN .DATE IS TYPED WITHOUT AN ARGUMENT ; BEFORE A DATE WAS ENTERED. ; ;DV6 -- PREVENTS CTRL/C FROM FRUN, WHICH COULD CAUSE LOSS OF ; MEMORY THAT WAS ALLOCATED FOR THE F/G JOB SPACE. ; ;DV7 -- PREVENTS A .LOCK THAT PROCEEDS A CSIGEN FROM PRODUCING A ; SPURIOUS ERROR MESSAGE. ; ;DV8 -- CORRECTS A TYPO IN QMANGR CODE THAT RESULTED IN A WRONG ; REGISTER BEING TESTED AND Q ELEMENTS ALWAYS BEING LINKED ; INTO THE HEAD OF AN I/O QUEUE. ; ;DV9 -- PRINTS ANOTHER CHARACTER AFTER A FILL SEQUENCE BEFORE ; SERVICING A TT: REQUEST FOR OUTPUT. PREVENTS OVERPRINT. ; ;DV10 - STRIPS PARITY BEFORE PRINTING A CHARACTER ON CONSOLE. ; ;DV11 - CORRECTIONS MADE TO TT HANDLER FOR S/J: A) TERMINATE ON ; CORRECT WORD COUNT AND B) RETURN EOF ONLY WHEN ; EOF CHARACTER ACTUALLY TYPED. KMON TABLE SIZE INCREASED. ; ;DV12 - .SYNCH FIXED IN S/J TO LOWER PRIORITY TO 0 PER F/B. ; ;DV13 - SCROLLER WIDTH TEST ADDED FOR S/J. ; ;DV14 - S/J TTY OUTPUT SERVICE CHANGED TO NOT HANG WHEN ECHOING A ; CHARACTER TYPED AND OUTPUT RING BUFFER IS FULL. ; ;DV15 - CHANGES MADE TO SUPPORT LSI11 PROCESSOR. ; ;DV16 - EDITS MADE FOR NETWORKS SUPPORT ; ;DV17 - ADDS SPFUN$ BIT TO DSTATUS WORD. BIT SET IN DSTATUS PERMITS ; .SPFUN REQUESTS TO BE SENT TO DRIVER (E.G., MT OR DX). ; ;DV18 - TTY FIXES FOR F/B TO IMPROVE .PRINT AND TT: INTERACTION. ; ;DV19 - CHANGES TO VT11 SCROLLER. NOW RUNS AT LEVEL 0, GOING TO 4 ; ONLY WHEN EXTRACTING A CHARACTER FROM THE RING BUFFER. ; ALSO ADDS A SCROLLER FIXED OFFSET LOCATION TO ALLOW SPECIFICATION ; OF TERMINAL PRINTER VECTOR. ; ;DV20 - FIXES CALUSR IN S/J TO REFRESH USR IN STANDARD LOCATION IF ; USR HAS BEEN SET "NO SWAP". ; ;DV21 - .CHCOPY WAS CHANGED TO CLEAR I/O COUNT IN CHANNEL WHEN ; COPYING FIFTH WORD OF CHANNEL. ; ;DV22 - .FRUN WAS MODIFIED TO CLOSE CHANNEL 17 IF PROGRAM NOT OVERLAYED. ; ;DV23 - THE SYSUPD FIXED OFFSET IN RMON WAS CHANGED TO REFLECT THE ; RELEASE NUMBER OF THE CURRENT VERSION, RATHER THAN THE EDIT #. ; ;LP1 - FLOPPY BOOT SPEED UP FOR THE LSI-11 PROCESSOR. ; ;DV24 - BOOT MODIFIED TO LOWER RX01 PRIORITY SO DX DRIVER RUNS AT ; LEVEL 0 WHEN DX IS SYSTEM DEVICE ON AN 11/03 CONFIGURATION. ; ;DV25 - CORRECTION FOR LOWER CASE SUPPORT IN F/B MONITOR WHEN TWO ; JOBS ARE ACTIVE. .SBTTL MACROS .MCALL ..V1.. ..V1.. .MCALL .CLOSE, .DSTATUS, .ENTER, .EXIT, .FETCH, .HRESET .MCALL .LOCK, .LOOKUP,.PRINT, .RCTRLO,.READW, .RELEASE .MCALL .SETTOP,.SRESET,.TTYIN, .TTYOUT,.UNLOCK,.WAIT, .WRITW ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A CALL TO THE KMON ERROR ROUTINE .MACRO KMEROR TEXT .IF GE OVLYN OJSR R0,MSGKM .IFF JSR R0,MSGKM .ENDC .ASCIZ "?TEXT?" .EVEN .ENDM KMEROR ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO COMPUTES AN ADDRESS IN A POSITION-INDEPENDENT MANNER ; IT CAN PUT THE ADDRESS IN A REGISTER OR ON THE STACK, ; AND CAN SAVE THE REGISTER FIRST ; ADR IS THE ADDRESS TO COMPUTE ; REG IS THE REGISTER (SP IF IT IS TO BE PUSHED) ; PUSH IS BLANK, 'ADD', OR 'PUSH' .MACRO ADDR ADR,REG,PUSH .IF IDN REG,SP MOV PC,-(SP) ADD #ADR-.,(SP) .IFF .IF B PUSH MOV PC,REG .IFF .IF IDN PUSH, ADD PC,REG .IFF JSR REG,(PC) .ENDC .ENDC ADD #ADR-.,REG .ENDC .ENDM ADDR ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A BLOCK OF ZERO WORDS IN CORE .MACRO BSS COUNT .NLIST .REPT COUNT .WORD 0 .ENDR .LIST .ENDM BSS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A FATAL MONITOR ERROR CALL .IF EQ BF .MACRO MONERR CODE,LEVEL,FTL EMT 376 .BYTE LEVEL .IF IDN , .BYTE ^C .IFF .BYTE CODE .ENDC .ENDM MONERR .IFF .MACRO MONERR CODE,LEVEL,FTL EMT 376 .BYTE LEVEL .IF IDN , .BYTE ^C .IFF .BYTE CODE'.E .ENDC .ENDM MONERR .ENDC ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MACRO TO GENERATE AN ERROR FROM THE CSI .MACRO CSIERR TEXT,CODE .NLIST JSR R0,MSG .BYTE CODE .ASCIZ "?TEXT?" .EVEN .LIST .ENDM CSIERR ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MACRO TO CHANGE PRIORITY LEVEL ; FOR USE IN RMON MODULE ONLY ;DV15 .MACRO SPL PRIO .IF NE PRIO MOV #PRIO*40,-(SP) ;DV15 .IFF CLR -(SP) ;DV15 .ENDC JSR PC,$MTPS ;DV15 .ENDM SPL ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MACRO TO LINK TO A KMON OVERLAY ; NOTE - THIS MACRO SHOULD ONLY BE USED FROM A KMON COMMAND .MACRO OVLINK CMD .IF GE OVLYN OJSR R2,OVLINK .IFF JSR R2,OVLINK .ENDC .BYTE N.'CMD,O.'CMD/2 .ENDM OVLINK ; ; MACROS DEFINED ELSEWHERE ARE ONLY USED IN THE VICINITY OF ; THEIR DEFINITION .SBTTL GLOBAL DEFINITIONS ; GLOBAL REFERENCES FOR SYSTEM DEVICE HANDLERS .GLOBL SYINDO, $PNAMO, SYENTO .GLOBL DTSYS,RFSYS,RKSYS,DPSYS,DXSYS ;DEFINED IN THE SYSTEM HANDLERS .GLOBL DSSYS ;THEY MAKE THE APPROPRIATE HANDLER ;RESIDENT IN ADDITION TO SY AND DK .GLOBL BLKEY, CHKEY, RTORG, $CSW .GLOBL TTIBUF, TTOBUF, TTYIN, TTYOUT ; THESE GLOBALS ARE FOR THE BOOTSTRAP MODULE .GLOBL $DVREC, $ENTRY, $PNAME ;SYSTEM TABLES .GLOBL $MONBL, $SWPBL, SYSLOW, KMLOC, QCOMP .GLOBL $USRLC, $SLOT, $KMLOC ;LOCS. TO MOVE .GLOBL BSTRNG, CORPTR, DKASSG, FILLER, HWDSP$, HWFPU$ .GLOBL KMON, KMONSZ, KW11L$, MAPOFF, RMONSZ, RT11SZ, RTLEN .GLOBL RTSIZE, USRSZ, SWAPSZ, SYASSG, SYNCH, USRLOC, $INTEN .GLOBL MAXSYH .GLOBL LSI11$,$MFPS,GETPSW ;DV15 .IF NE BF ; GLOBALS STRICTLY FOR F/B: .GLOBL BCNTXT, BKGND1, BKGND2, BKGND3, BLIMIT, CNTXT, FPPINT .GLOBL FUDGE1, FUDGE2, MSGENT, RMONSP, SWIPTR, SWOPTR, TTIUSR .GLOBL TTOUSR, .$CRTN ,IMPLOC ;DV15 .IFF ; GLOBALS FOR BACKGROUND ONLY MONITOR .GLOBL I.CSW, FPPADD, FPPIGN, MONLOC, TRAPLC, TRAPER .GLOBL TTOCLO, TTILCT, AVAIL, MONCAL .ENDC .SBTTL SYSTEM PARAMETERS ; REGISTER DEFINITIONS: R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 PS=177776 SR=177570 ; ASCII DEFINITIONS BELL = 7 BS = 10 TAB = 11 LF = 12 FF = 14 CR = 15 ESCAPE = 33 RUBOUT = 177 ; INTERRUPT PRIORITY DEFINITIONS: PR0 = 0 PR4 = 200 PR7 = 340 ; CONDITIONAL ASSEMBLY PARAMETERS .IIF NDF CLOCK, CLOCK=60. ; FOR 60 CYCLE .IF NDF $SLOT ;DEFAULT 14 DEVICES (DEFINE ONLY IN PASS 1) $SLOT = 14. .IIF DF BANDW, $SLOT = 18. .ENDC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THE WORD CONFIG (IN RMON) GIVES INFO ON THE OVERALL STATE ; AND CONFIGURATION OF THE SYSTEM. THE BITS CURRENTLY DEFINED ARE: ; ; BIT # MEANING ; ----- ------- ; 0 0 => THIS IS THE B ONLY MONITOR ; 1 => THIS IS F/B MONITOR ; 1 1 => TTY HAS HARDWARE TABS ; 2 1 => GT40 HARDWARE EXISTS ; 3 1 => BATCH IS RUNNING ; 4 1 => VT05 IS TERMINAL ; 5 1 => 50 CYCLE CLOCK ; 6 1 => FPU HARDWARE ; 7 0 => NO F JOB IS RUNNING ; 1 => A F JOB IS NOW RUNNING ; 8 1 => USER LINKED TO GT40 SCROLLER ; 9 1 => USR MAY NOT BE SET TO SWAP ; 10 1 => BATCH IS RUNNING ; 11 1 => LSI11 PROCESSOR (I.E., NO PS OR LKCS) ;DV15 ; 15 1 => KW11L CLOCK EXISTS FBMON$ = 1 HWDSP$ = 4 BATCH$ = 10 CLK50$ = 40 HWFPU$ = 100 FJOB$ = 200 GTLNK$ = 400 USR$ = 1000 LSI11$ = 4000 ;DV15 KW11L$ = 100000 .IF EQ CLOCK-50 CLK50 = CLK50$ .IFF CLK50 = 0 .ENDC ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THESE ARE PARAMETERS USED IN THE USR ; FOR SPECIAL DEVICES; E.G. CASSETTE AND MAGTAPE LOOK.. = 3 ;LOOKUP DELE.. = 2 ;DELETE CLOS.. = 1 ;CLOSE ENTR.. = 4 ;ENTER ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THE MONITOR USES WORDS 40-56 IN LOW CORE TO HOLD PARAMETER ; INFORMATION ON THE RUNNING JOB ; THESE LOCATIONS CONTAIN THE FOLLOWING INFORMATION: ; ; ADDRESS BIT(S) MEANING ; ------- ------ ------------------------------------------ ; 40 START ADDRESS OF PROGRAM ; 42 INITIAL STACK POINTER ; 44 JOB STATUS WORD ; 15 1 => USR DOES NOT NEED TO SWAP ; 0 => PROGRAM OVERLAYS USR ; 14 1 => UPPER CASE CONVERSION DISABLED ; 13 1 => PROGRAM MAY BE RESTARTED ; 12 1 => SPECIAL TTY INPUT MODE ; SINGLE CHAR. INPUT, WITH ONLY ^C ; AND ^O BEING INTERPRETED ; 9 1 => JOB IS AN OVERLAY JOB ; 8 1 => JOB WAS CHAINED TO ; 7 1 => HALT ON HARD ERROR FROM DEVICE (SU ONLY) ; 6 1 => IN F/B, .TTYIN/OUT RETURNS CARRY INSTEAD ; OF WAITING IF NOTHING IS AVAILABLE ; 46 LOCATION OF FLOATING USR. ; 0 => USR IS AT STANDARD LOCATION ; 50 HIGHEST ADDRESS OF USER PROGRAM ; 52 0-7 ERROR CODE ON RETURN FROM EMT ; 54 POINTER TO RMON ; 56 0-7 CHARACTER AFTER WHICH TO INSERT FILL ; CHARACTERS (NULLS) WHEN DOING OUTPUT TO ; THE CONSOLE DEVICE. 0 => NO FILLS ; 8-15 NUMBER OF FILL CHARACTERS ; REQUIRED FILLS ARE: ; LA30 -- 9 FILLS AFTER CR ; VT05 @ 2400 BAUD -- 4 FILLS AFTER LF ; VT05 @ 1200 BAUD -- 2 FILLS AFTER LF ; VT05 @ 600 BAUD -- 1 FILL AFTER LF PARMS = 40 USERPC = 40 USERSP = 42 JSW = 44 USWAP$ = 100000 TTLC$ = 40000 RSTRT$ = 20000 TTSPC$ = 10000 OVLY$ = 1000 CHAIN$ = 400 ;CAUTION - CHAIN$ MUST BE 400!!!! HLTER = 200 TCBIT$ = 100 UFLOAT = 46 USERTOP = 50 ERRBYT = 52 SYSPTR = 54 TTFILL = 56 TTNFIL = 57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; A DIRECTORY ENTRY FOR A FILE STRUCTURED DEVICE'S DIRECTORY ; IS ORGANIZED AS FOLLOWS: ; ; OFFSET MEANING ; ------ ------- ; 0 STATUS WORD ; 4000 = END OF DIRECTORY SEGMENT MARKER ; 2000 = PERMANENT FILE ; 1000 = EMPTY ENTRY ; 400 = TENTATIVE ENTRY ON CHANNEL ; 2-7 FILNAM.EXT IN RADIX 50 ; 10 LENGTH OF HOLE ALLOCATED ON DEVICE ; 12 DATA LENGTH (HIGHEST BLOCK USED) ; 12 IS ALSO USED IN ENTER TO HOLD ADDRESS WHICH ; FLAGS A TENTATIVE ENTRY, AND IDENTIFIES IT FOR CLOSE ; 14 CREATION DATE ; ; THESE WORDS MAY BE FOLLOWED BY EXTRA 'USER' WORDS ; ENDBLK = 4000 ;END OF BLOCK MARKER PERM = 2000 ;PERMANENT FILE EMPTY = 1000 ;EMPTY ENTRY TENT = 400 ;TENTATIVE FILE DOFSET = 4 ;DIRECTORY SEGMENT #1 STARTS AT BLOCK 6 E.NAME = 2 ;FILNAM.EXT STARTS AT WORD 2 E.LENG = 10 ;SIZE OF HOLE ALLOCATED E.USED = 12 ;HIGHEST BLOCK WRITTEN (NOW 0) E.CHAN = 12 ;WHILE TENTATIVE, HOLDS CHANNEL NUMBER E.JNUM = 13 ;FOR BF, HOLDS JOB NUM E.DATE = 14 ;CREATION DATE L.ENTR = 16 ;LENGTH OF DIR ENTRY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; THE ONLY DEVICES BESIDES THE SYSTEM DEVICE WHICH ARE ASSUMED ; TO BE PRESENT ARE THE TTY AND THE LINE-FREQUENCY CLOCK ; DEFINITIONS OF TTY STATUS WORDS: ; TKS = 177560 ;READER STATUS TKB = 177562 ;READER BUFFER TPS = 177564 ;PUNCH STATUS TPB = 177566 ;PUNCH BUFFER V.TKB = 60 ;KEYBOARD VECTOR V.TPS = 64 ;PRINTER VECTOR V.FPP = 244 ;FPP AND FIS VECTOR .IF EQ BF TTYIN = 82. ;82 CHARACTER INPUT RING TTYOUT = 32. ;32 CHARACTER OUTPUT RING .IFF TTYIN = 100. ;100 CHARACTER INPUT RING TTYOUT = 40. ;40 CHARACTER OUTPUT RING .ENDC ; ; DEFINITIONS OF LINE CLOCK STATUS WORDS: ; LKCS = 177546 ;CLOCK STATUS REGISTER LKVEC = 100 ;CLOCK VECTOR LOCATION ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; THE FOLLOWING MACRO AND MACRO CALLS GENERATE EQUATES ; FOR THE SIZE (IN BYTES) OF THE HANDLERS FOR EACH DEVICE ; IN THE SYSTEM ; HANDLERS WHICH ARE VALID SYSTEM DEVICES MUST HAVE TYPE 'SYS' ; OTHER HANDLERS FROM WHICH PROGRAMS CAN BE RUN MUST HAVE TYPE 'RUN' .MACRO HSIZE HAN,BYT,TYPE HAN'SIZE = BYT .IF NB TYPE .IIF GT BYT-MAXHAN, MAXHAN = BYT .ENDC .IF IDN , .GLOBL HAN'SIZE .IIF GT BYT-MAXSYH, MAXSYH = BYT .ENDC .ENDM HSIZE MAXHAN = 0 ;MAXHAN CONTAINS THE MAXIMUM HANDLER SIZE MAXSYH = 0 ;MAXSYH CONTAINS THE MAXIMUM SYS HANDLER SIZE HSIZE TT,500 HSIZE RK,342,SYS HSIZE DP,434,SYS HSIZE RF,270,SYS HSIZE PR,174 HSIZE PP,130 HSIZE MT,4300 HSIZE MM,4700 HSIZE LP,306 HSIZE DT,322,SYS HSIZE CT,3710 HSIZE CR,1326 HSIZE BA,4100 HSIZE DX,670,SYS HSIZE DS,320,SYS .IIF NDF BANDW, .NLIST .IF DF BANDW HSIZE AM,214,RUN .ENDC .IIF NDF BANDW, .LIST .IF NE BF OVLYSZ = 2 ;2 BLOCK OVERLAYS IN FB .IFF OVLYSZ = 1 ;1 BLOCK OVERLAYS IN SU .ENDC OVLYN = -OVLYSZ ;NO OVERLAYS YET EMTERR = 17*20+EMT ;ERROR SETTING EMT IENABL = 100 ;INTERRUPT ENABLE BIT .SBTTL ASECT - INITIAL VECTORS .ASECT . = 4 .WORD TRAP4,340 ;DV15 .WORD TRAP10,341 ;DV15 . = 24 .WORD 26,0 ;HALT ON POWER FAIL . = 30 .WORD EMTPRO,0 ;EMT TRAP . = 54 .WORD $RMON ;POINTER TO RESIDENT . = V.TKB .WORD TTIINT,PR7 ;KEYBOARD INTERRUPT . = V.TPS .WORD TTOINT ;TELETYPE INTERRUPT .IIF NE BF, PR7 ;F/B IN AT LEVEL 7 .IIF EQ BF, PR4 ;S/J IN AT LEVEL 4 . = 100 .WORD LKINT,PR7+1 ;TIMER VECTOR, PRIO=7, CARRY SET . = 114 .WORD 116,0 ;HALT ON MEMORY PARITY ERROR . = 300 BSTRNG: .ASCII <15><12>"RT-11" .RADIX 10. .IRP ...,<\UPDATE> .IF NE BF .ASCIZ "FB V02C-0'..." .IFF .ASCIZ "SJ V02C-0'..." .ENDC .ENDR .RADIX 8. .EVEN . = V.FPP FPPINT PR7 .SBTTL SLIDE KMON/USR UP OR DOWN .CSECT SWAP ;MAKE THE SWAP BLOCKS COME FIRST .CSECT RT11 ;PUT KMON & USR HERE ; "THE AWFUL SHADOW OF SOME UNSEEN POWER ; FLOATS, THO' UNSEEN, AMONGST US" ; - SHELLEY, "HYMN TO INTELLECTUAL BEAUTY" ; KUMOVE IS RESPONSIBLE FOR MOVING THE KMON AND USR ; EITHER UP OR DOWN WHEN A HANDLER IS LOADED OR UNLOADED, ; OR WHEN A FOREGROUND JOB IS INSTALLED OR REMOVED. ; CALLING SEQUENCE: ; R0 = AMOUNT TO MOVE (<0 => DOWN; >0 => UP) ; RETURNS: ; R4 -> KMON IF DOWN ; START OF FREED AREA IF UP ; DESTROYS R1, (R3 IF DOWN) KMON: .WORD 0 ;THIS WORD STOPS THE MOVE LOOP KUMOVE: MOV PC,R4 ;POINT R4 TO KMON CMP -(R4),-(R4) ;(MUST BE 3RD INSTRUCTION) JSR PC,CLRLOW ;CLEAR OUT 40-53 MOV R4,R1 ;COPY KMON PTR. ASL R0 ;FIX R0 TO BYTES. MOVE UP OR DOWN ? BCS 1$ ;DOWN, GO CALL MOVER ADD R0,R4 ;R4 IS DESTINATION PTR ADD #KMSIZE+USRSIZ,R1 ;CHANGE POINTERS TO TOP OF USR ADD #KMSIZE+USRSIZ,R4 ; AND TOP OF DESTINATION CLR -(SP) ;WORD TO FLAG WHEN WE PASS STACK TOP 2$: MOV -(R1),-(R4) ;MOVE A WORD BNE 2$ ;LOOP WHILE NON-0 CMP R1,PC ;WAS THE 0 WORD BELOW HERE ? BLO 4$ ;YES. DONE ! CMP R1,SP ;WAS IT STACK TOP ? BNE 2$ ;NO, JUST A STRANGE 0 MOV R4,SP ;MAKE THE NEW STACK POINTER TST (SP)+ ;PURGE THAT 0 WORD BR 2$ ;MOVE THE REST 4$: MOV R0,R1 ;MUST RELOCATE ADDR BR 3$ 1$: ADD R0,R4 ;R4 IS DESTINATION PTR BCC MEMERR ;CARRY CLEAR => TOO MUCH ASKED CMP R4,#1000 ;ARE WE MOVING TOO LOW ? BLO MEMERR ;YES. ERROR JSR PC,MOVEDN ;CALL MOVER-DOWNER CLR R1 ;NO NEED TO RELOCATE ADDR 3$: ADDR RELIST,R1,ADD ;POINT TO STUFF TO RELOCATE .REPT 5 ;RELOCATE POINTERS WITHIN RMON ADD R0,@(R1)+ .ENDR ADD R0,(R1)+ ;RELOCATE .USRBU ADD R0,(R1)+ ; AND .USRBO ADD R0,@R1 ; AND .USRTO ADD R0,SYSIOB-.USRTO(R1) ; AND POINTER TO USRBUF ADD R0,@SP ;RELOCATE RETURN ADDRESS RTS PC ;RETURN MEMERR: JMP OVERC .SBTTL COMMAND DISPATCHER ; THE FOLLOWING CODE IS CLEANUP AFTER AN EXIT HAS BEEN DONE. ; MEXIT IS CALLED WHEN THE USR HAS BEEN FRESHLY READ AND HAS ; POINTERS WHICH MUST BE RELOCATED. ; MEXIT2 IS USED WHEN A GOOD USR COPY IS IN THE STANDARD PLACE IN CORE MEXIT: JSR PC,LOCATE ;SET POINTERS INTO RMON MEXIT2: .IF EQ BF JSR PC,QRESET ;RESET THE IO QUEUE CLR @.RECURS ;NO COMPLETION ROUTINES ACTIVE CLR @.DFLG ;CLEAR ^C DELAY SWITCH MOV @#SYSPTR,R0 ;POINT TO SYSTEM CLR MONCAL-$RMON(R0) ;GET RID OF LINGERING MONITOR CALLS .IFTF MOV @.$KMLO,@.KMLOC ;KMON IS NOW IN CONTROL BIC #TTSPC$+TTLC$,@#JSW ;CLEAR OUT SPECIAL TTY MODE CLR GETCNT ;NO GETS YET MOV @#SYSPTR,R3 ;POINT TO RMON (NOT CONTIGUOUS WITH USR) MOV SP,KMONIN-$RMON(R3) ;KMON IS IN CONTROL CLR BLKEY-$RMON(R3) ;NO DIRECTORY IS IN CORE .IFT JSR PC,CLRHND ;RELEASE ALL NON-RES HANDLERS CLR $SYSCH+10-$RMON(R3) ;CLEAR SYS IO COUNT CLR EXTFLG-$RMON(R3) ;"EXIT" IS DONE NOW CLR TTIPRE-$RMON(R3) ;SO THAT ^C WON'T WAIT ON EXIT CLRB TTILCT+1-$RMON(R3) ;CLEAR TT: ^C FLAG .IFF MOV CNTXT-$RMON(R3),R2 ;ANOTHER ^C WILL NOT ABORT US CLR I.PTTI(R2) CLR EXTFLG-$RMON(R3) ;CLEAR EXIT IN PROGRESS FLAG .ENDC TST (SP)+ ;WHAT KIND OF EXIT ? BNE KCHAIN ;TEMPORARY INIT: JSR PC,CLRLOW ;CLEAR CCB IN MONITOR .HRESET ;SYSTEM RESET (HARDWARE & SOFTWARE) CTRLCK: BIC #CHAIN$,@#JSW ;STANDARD KMON LOOP IS NO CHAIN KCHAIN: MOV .USRBUF,R0 ;SET UP KMON STACK MOV R0,SYSIOB ;KMSTAK IS THE SAME AS BUFFER MOV R0,SP ;PUT NEW SP INTO REG 6 .IF NE BF .UNLOCK .ENDC .RCTRLO ;DISABLE CTRL/O ADDR KMCBUF,R5 ;POINT TO KMON COMMAND BUFFER MOV R5,R3 ;COPY POINTER BIT #CHAIN$,@#JSW ;IS THIS A CHAIN ENTRY? BEQ 19$ ;NO .IF NE BF .LOCK .ENDC JMP RUN ;YES. SIMULATE A RUN 19$: JSR PC,KCRLF ;RETURN THE CARRIAGE 2$: .RCTRLO MOV .$ENTR,R0 ;R0 -> $ENTRY TABLE MOV BA.NUM(R0),R0 ;R0 -> BA.SYS ENTRY BEQ 40$ ;BR IF NOT IN MEMORY TST 6(R0) ;IS IT ACTIVE? BNE 41$ ;BR IF ACTIVE, TO PRETTY UP LOG 40$: .TTYOUT #'. ;PRINT A DOT 41$: MOV #72.,R1 ;72. CHARS/LINE .IF EQ BF MOV #' ,@R5 ;PUT IN A BLANK FOR COMPARISON .ENDC 3$: .TTYIN ;GET CHAR FROM TTY CMPB #TAB,R0 ;IF IT IS A TAB BNE 31$ MOVB @R5,R0 ;CHANGE IT TO A SPACE 31$: CMPB @R5,R0 ;IF IT IS A SPACE BNE 32$ CMPB @R3,R0 ;AND WE ARE POINTING TO A SPACE BEQ 3$ ;THEN IGNORE IT 32$: CMPB #CR,R0 ;IGNORE CARRIAGE RETURNS BEQ 3$ DEC R1 ;ROOM FOR IT ? BMI 4$ ;NO, KEEP SKIPPING MOVB R0,-(R3) ;PUT BYTE IN BUFFER 4$: CMP #LF,R0 ;IS IT END OF LINE ? BNE 3$ ;NOT YET TST R1 ;DID BUFFER OVERFLOW ? BMI BADCOM ;YES, GIVE AN ERROR 45$: CLRB (R3)+ ;CHANGE THE LF TO A NULL CMP R5,R3 ;ANYTHING IN THE LINE ?? BEQ 2$ ;NO, GET A NEW LINE MOV R5,R3 ;SAVE START OF LINE PTR MOV -(R5),R1 ;GET FIRST TWO CHARS INC R5 ;START WITH THE SECOND CHAR 5$: TSTB (R5)+ ;IS THIS THE END OF THE LINE? BEQ 7$ ;YES. LEAVE R5 JUST BEFORE THE NULL DEC R5 ;NO. FIX R5 CMPB @R3,-(R5) ;AND IS THE NEXT CHAR BLANK? BNE 5$ ;NO, KEEP SKIPPING 7$: ADDR COMLST,R2 ;SETUP POINTER TO COMMAND LIST 10$: TST (R2) ;END OF LIST ? BEQ 20$ ;YES, TRY OVERLAYS CMP R1,(R2)+ ;IS THIS IT ?? BNE 10$ ;NO, KEEP TRYING MOV PC,R3 ;RELOCATE COMMAND ADDRESS XX=. ADD COMLSZ-2(R2),R3 ;JUMP TO COMMAND HANDLER BR 30$ ;GO CALL COMMAND 20$: MOV R5,R1 ;SAVE END OF COMMAND POINTER MOV R3,R5 ;POINT TO START OF CMD TST (R2)+ ;MOVE OVER 0 WORD JSR PC,GETNAM ;CONVERT TO RAD 50 MOV (R2)+,R3 ;R3 = COMMAND IN RAD 50 TST (R2)+ ;UNUSED PART OF NAME 21$: TST (R2) ;END OF LIST ? BEQ BADCOM ;YES, EVIL CMP R3,(R2)+ ;IS THIS IT ? BNE 21$ ;NOT YET ADD #OCOMSZ-2,R2 ;PUSH ON TO BLOCK # JSR PC,OVREAD ;READ IN THE OVERLAY 30$: CLR SAVSWT ;CLEAR SAVED INDICATOR IF E OR D .IF NE BF .LOCK .ENDC JSR PC,@R3 ;GO GO GO BR CTRLCK ;DONE MSGKM: .PRINT ;PRINT THE MESSAGE .EXIT BADCOM: KMEROR KCRLF: MOV PC,R0 ;GET A NULL BYTE MOV R0,R0 ;NO-OP WHOSE BOTTOM BYTE IS 0!!!!! .PRINT ;PRINTING NULLSTRING IS A CRLF RTS PC .SBTTL READ OVERLAY, LINK TO OVERLAY OVREAD: MOVB (R2)+,R0 ;GET RELATIVE OVLY BLOCK ADD @.$SWPBL,R0 ;MAKE IT ABSOLUTE CLR -(SP) ;MAKE ROOM FOR OFFSET MOVB (R2)+,@SP ;AND PUT IT IN ADDR OVLIOB,R5 ;IOB FOR OVERLAY I/O ADDR OVLY,R3 ;CORE ADDRESS CMP R0,(R5) ;IS BLOCK ALREADY IN ? BEQ 1$ ;YES, DON'T DO I/O MOV R0,(R5)+ ;REMEMBER WHICH OVLY IS IN MOV R3,@R5 ;SET CORE ADDR JSR PC,@.$SYS ;DO I/O FROM SYSTEM DEVICE BCS 10$ ;ERROR READING OVLY 1$: MOV R1,R5 ;REPOINT TO CMD ARGUMENTS ASL @SP ;REAL OFFSET ADD (SP)+,R3 ;POINT IT INTO BLOCK RTS PC ;RETURN 10$: CLR -(R5) ;NO OVERLAY IS IN KMEROR ; THIS ROUTINE IS USED TO LINK FROM ONE OVERLAY TO ANOTHER ; OVER THE LINK, R0, R1, AND R3 ARE DESTROYED. ; R2, R4, R5, AND THE STACK ARE PRESERVED OVLINK: MOV R5,R1 ;PRESERVE R5 OVER THE LINK JSR PC,OVREAD ;GO READ IN THE OVERLAY MOV (SP)+,R2 ;RESTORE R2 JMP @R3 ;ENTER THE OVERLAY .SBTTL BASE, EXAMINE .ENABL LSB B: JSR PC,OCTNUM ;GET THE BASE BIC #1,(SP) ;ONLY EVEN BASES MOV (SP)+,BASE ;SAVE IT 10$: RTS PC ;BACK TO KMON E: MOV BASE,R3 ;GET THE BASE ADDRESS JSR PC,OCTNUM ;GET FIRST ADDRESS BIC #1,(SP) ;EVEN ADDRESSES ONLY CLR R1 ;CLEAR COUNT (IN CASE ONLY 1) CMPB #'-,(R5) ;IS IT A DASH ?? BNE 1$ ;NO, JUST EXAMINE ONE WORD JSR PC,OCTNUM ;GET UPPER LIMIT MOV (SP)+,R1 ;MOVE IT TO COUNT REG SUB (SP),R1 ;GET COUNT BLO BADCOM ;BACKWARDS IS A NO-NO ROR R1 ;R1 HAS WORD COUNT - 1 1$: ADD (SP)+,R3 ;GET ADDRESS (BASE+GIVEN ADDRESS) 2$: MOV #10,R4 ;DISPLAY 8 WORDS PER LINE 3$: JSR PC,ADTRAN ;TRANSLATE ADDRESS IN CASE VIRT CORE TST (R3)+ ;BUMP ADDRESS FOR NEXT TIME MOV (R2),R2 ;GET THE WORD OPRINT: MOV #30,R0 ;CONVERT WORD TO OCTAL AND PRINT IT SEC 4$: ROL R2 ;DON'T TRY TO UNDERSTAND THIS ROUTINE ROLB R0 ; JUST USE IT & LOVE IT .TTYOUT MOV #206,R0 5$: ASL R2 ;DONE YET ? BEQ 6$ ;YES ROLB R0 BCS 5$ BR 4$ 6$: DEC R1 ;ANY MORE TO DO ? BMI 10$ ;NO, GO HOME .TTYOUT #40 ;PRINT SEPARATOR DEC R4 ;8/LINE BNE 3$ JSR PC,KCRLF ;PRINT CR LF BR 2$ .SBTTL DEPOSIT D: MOV BASE,R3 ;GET BASE ADDRESS JSR PC,OCTNUM ;GET LOCATION ADD (SP)+,R3 ;GET DESIRED ADDRESS BIC #1,R3 ;MAKE SURE ITS EVEN 7$: TSTB @R5 ;END OF LINE? BEQ SAVEVC ;YES, DONE MOV R3,R2 ;COPY DEPOSIT ADDRESS MOV @#SYSPTR,R0 ;POINT TO PERM CCB ADD #CCB-$RMON,R0 JSR PC,SETBIT ;SET BIT IN CCB JSR PC,ADTRAN ;TRANSLATE ADDRESS CMP R3,R2 ;WAS THIS ADDR IN VIRT CORE ?? BEQ 8$ ;NO, NOT IF THEY'RE THE SAME INC SAVSWT ;YES, SAVE THIS BLOCK LATER 8$: JSR PC,OCTNUM ;GET NEXT VALUE MOV (SP)+,(R2) ;STORE IT TST (R3)+ ;INCREMENT ADDRESS BR 7$ ;LOOP .DSABL LSB .SBTTL ADTRAN & SAVEVC .ENABL LSB ADTRAN: MOV @#SYSPTR,R2 ;POINT TO RESIDENT CMP R3,SYSLOW-$RMON(R2) ;IS ADDRESS IN RANGE? BHIS 3$ ;NO, GIVE ERROR ADDR KMON,R2 ;SETUP POINTER TO KMON BIC #777,R2 ;FORCE TO A BLOCK BOUNDARY SUB R3,R2 ;IS ADDRESS IN VIRT. CORE ? BLOS 1$ ;YES, GO DO VIRT. CORE MOV R3,R2 ;NO, REAL CORE IS EASY RTS PC 1$: ADDR SYSIOB-2,R5,PUSH ;SAVE R5, POINT TO SYS IOB NEG R2 ;GET DISPLACEMENT INTO VIRT. CORE CLRB R2 ;ZERO LOWER 8 BITS SWAB R2 ;GET THE BLOCK NUMBER IN SYS SCRATCH ASR R2 CMP R2,(R5)+ ;IS IT THE BLOCK WE'VE GOT ? BEQ 2$ ;YES JSR PC,SAVEVC ;SAVE VIRT CORE IF MODIFIED NEG 2(R5) ;MAKE WORD COUNT POSITIVE MOV R2,R0 ;GET DESIRED BLOCK NUMBER MOV R0,BLOKWG ;SAVE THIS JSR PC,SYSK ;READ FROM SYS SCRATCH AREA 2$: MOV R3,R2 ;GET REAL ADDRESS BIC #177000,R2 ;GET ADDRESS WITHIN BUFFER ADD (R5),R2 ;ADD START OF BUFFER BR 10$ ;POP R5 AND RETURN 3$: KMEROR SAVEVC: MOV #-400,SYSIOB+2 ;MAKE A ONE BLOCK WRITE ADDR SAVSWT,R5,PUSH ;SAVE R5, POINT TO SYSIOB-4 TST (R5)+ ;DID WE ALTER THIS ONE ? BEQ 10$ ;NO MOV (R5)+,R0 ;GET BLOCK NUMBER OF BLOCK IN CORE JSR PC,SYSK ;WRITE INTO SCRATCH AREA 10$: MOV (SP)+,R5 ;RESTORE POINTER TO SYS IO BLOCK RTS PC .DSABL LSB .SBTTL R (RUN FROM SY:) R: MOV (PC)+,R3 ;SET DEFAULT DEVICE TO SY: .RAD50 /SY / JSR PC,FILE ;GET THE FILE DESCRIPTOR CMP (PC)+,(R3) ;WAS ANOTHER DEVICE SPECIFIED ? .RAD50 /SY / BNE BCLNK ;YES, THAT'S A NO-NO .LOOKUP 17 ;OPEN IT ON CHANNEL 17 BCS NOTFND ;FILE NOT FOUND CLR @#USERTOP ;MAKE SURE USERTOP GETS SET BY CCBB0 JSR PC,CCBB0 ;GET CCB AND BLOCK 0 1$: MOV (R2)+,(R3)+ ;MOVE IN CCB DEC R1 ;DONE? BNE 1$ MOV SB17-(R3),R1 ;GET START BLOCK OF FILE ON SY INC R1 ;GET FIRST BLOCK TO READ MOV @#USERPC,R2 ;GET STARTING ADDRESS MOV #1000,R3 ;GET FIRST ADDRESS TO READ BEGIN: BIT #CHAIN$,@#JSW ;ARE WE CHAINED TO ? BNE 5$ ;YES, DO NOT RESET .SRESET ;NO, RESET ALL (EXCEPT MAYBE 17) 5$: MOV @#SYSPTR,R5 ;GET START OF RMON MOV @#USERTOP,R4 ;GET HIGHEST ADDRESS OF USER CORE TST @#USERSP ;IS USER STACK DEFINED ?? BNE 1$ ;YES, IF ITS NON-ZERO MOV #1000,@#USERSP ;NO STACK GIVEN, DEFAULT TO 1000 1$: MOV SYSLOW-$RMON(R5),R0 ;HIGHEST TOP IF USR CAN SWAP BIT #USR$,CONFIG-$RMON(R5) ;CAN THE USR SWAP? BEQ 3$ ;YES, LUCKY US MOV $USRLC-$RMON(R5),R0 ;NO, HIGHEST TOP IS THE USR 3$: CMP R0,R4 ;DOES IT OVERLAY TOP? BLOS OVERC ;FILE IS TOO BIG. GIVE ERROR .SETTOP R4 ;SET NEW TOP OF CORE SUB R3,R4 ;GET TOP - START = REMAINDER TO READ BCS 2$ ;IF NEGATIVE, NO READ NECESSARY ADD #KMBLK+4-$RMON,R5 ;POINT R5 TO KMBLK+4 IN RMON ROR R4 ;MAKE IT A WORD COUNT INC R4 ;DON'T FORGET LAST WORD MOV R4,-(R5) ;PUT REMAINDER WORD COUNT INTO I/O BLOCK MOV R3,-(R5) ;PUT BUFFER ADDRESS INTO I/O BLOCK MOV R1,R0 ;GET STARTING BLOCK OF FILE MOV R5,R1 ;SETUP POINTER TO RMON STACK ADD #SPTR-KMBLK,R1 ;RECALL WHERE R5 POINTS MOV R1,SP ;USE SYSTEM TEMPORARY STACK JMP RDOVLY-KMBLK(R5) ;GO READ IN THE PROGRAM 2$: JMP ENTRPG-$RMON(R5) ;SET STACK AND ENTER PROG NOTFND: KMEROR SFERR: KMEROR BCLNK: JMP BADCOM .SBTTL REENTER, RUN & START REENTR: BIT #RSTRT$,@#JSW ;IS PROG REENTERABLE ? BEQ BCLNK ;NO, ILLEGAL COMMAND MOV #-2,R2 ;USE START ADDRESS MINUS TWO BR STRE RUN: JSR PC,GET ;GET THE SAVE IMAGE CLR R2 ;USE THE START ADDRESS BR STRE STARTK: JSR PC,OCTNUM ;GET THE DESIRED STARTING ADDRESS MOV (SP)+,R2 BNE GOTADR STRE: ADD @#USERPC,R2 ;USE STARTING ADDRESS FROM CCB IF 0 GOTADR: ADDR KMON,R3 ;SETUP FIRST ADDRESS TO READ BIC #777,R3 ;ROUND TO A BLOCK MOV @.$SWPBL,R1 ;SETUP FIRST BLOCK TO READ BR BEGIN .SBTTL GET (ALSO USED BY RUN) OVERC: CLR @#USERTOP ;FILE WAS TOO BIG. CLEAR TOP KMEROR ;OF CORE FOR NEXT KMON CMD. GET: TST GETCNT ;SEE IF THIS IS FIRST GET. BNE 1$ ;N TH GET. LEAVE 50 ALONE JSR PC,CLRCCB ;CLEAR CCB AND USRTOP BIC #RSTRT$,@#JSW ;MAKE IT NOT RESTARTABLE INC GETCNT ;MARK A GET DONE 1$: JSR PC,GETHAN ;GET THE DEVICE HANDLER .LOOKUP 17 ;LOOKUP FILE TO BE GOT BCS NOTFND ;FILE NOT FOUND JSR PC,CCBB0 ;GET CCB AND BLOCK 0 CLR R5 ;ZERO THE BLOCK NUMBER ASL R1 ;SET CCB BYTE COUNT TO 16 MOV #200,R4 ;INITIALIZE TEST BIT (START AT BLOCK 1) CLRSB: CLR R0 ;CLEAR THE STARTING BLOCK NUMBER GETBIT: RORB R4 ;SHIFT TEST BIT BCS ORCCB ;IF CARRY SET, DONE WITH THIS BYTE INC R5 ;INCREMENT BLOCK NUMBER BITB R4,(R2) ;TEST BIT OF SAVE FILE'S CCB BEQ 4$ ;THIS BLOCK NOT USED TST R0 ;IS THIS FIRST BLOCK OF A SEQUENCE ? BNE GETBIT ;NO, STARTING BLOCK ALREADY SET MOV R5,R0 ;YES, SET STARTING BLOCK OF SEQUENCE BR GETBIT ;GO LOOK AT NEXT BIT OF MAP 4$: TST R0 ;WAS PRECEEDING BLOCK(S) USED ? BEQ GETBIT ;NO, NO READS ADDR KMON,R4,PUSH ;SAVE R4, POINT TO KMON MOV R5,-(SP) ;SAVE BLOCK NUMBER FOR LATER CLRB R4 ;MAKE IT AN EXACT BLOCK SWAB R4 ASR R4 ;MAKE IT A BLOCK NUMBER CMP R5,R4 ;DOES THIS SET OF BLOCKS OVERLAY KMON ? BLE NOSCRA ;NO, NOTHING INTO THE SYSTEM SCRATCH CMP R0,R4 ;DOES STARTING BLOCK OVERLAY KMON ? BGE ALSCRA ;YES, ALL INTO SYSTEM SCRATCH AREA MOV R4,R5 ;THIS SET OF BLOCKS LAYS ACROSS BOUNDARY JSR PC,READSF ;READ PART THAT FITS INTO REAL CORE MOV R4,R0 ;SET START BLOCK TO START OF VIRT CORE ALSCRA: SUB R4,R0 ;GET BLOCK # IN VIRT CORE INTO R0 ADD R0,R4 ;R4 HAS STARTING BLOCK IN FILE ALSCR1: MOV (SP),R5 ;GET NUMBER OF LAST BLOCK + 1 SUB R4,R5 ;NUMBER OF BLOCKS REMAINING TO GET BLE ENDSCR ;NONE LEFT IN THIS SEQUENCE CMP R5,#SWAPSZ ;SEE IF FILE FITS IN SCRATCH BGT OVERC ;IT DOESN'T GIVE ERROR MOV R0,-(SP) ;SAVE VIRT CORE BLOCK # MOV R4,R0 ;R0 CONTAINS BLOCK TO READ IN SAVE FILE CLR -(SP) ;USE WAIT I/O MOV #1000,-(SP) ;READ TWO BLOCKS DEC R5 ;IF THERE ARE TWO LEFT BNE 7$ ASR (SP) ;NOPE, ONLY ONE LEFT 7$: ADDR SYSIOB+2,R5 ;SETUP POINTER TO SYSTEM IO BLOCK MOV (SP),(R5) ;COPY WORD COUNT INTO SYS IO BLOCK NEG (R5) ;MAKE IT NEG.--A WRITE OPERATION MOV -(R5),-(SP) ;COPY BUFFER POINTER TO STACK EMT 200+17 ;READ FROM SAVE FILE SFELNK: BCS SFERR ;ERROR READING SAVE FILE MOV (SP),R0 ;RESTORE BLOCK # IN VIRT CORE TO R0 JSR PC,SYSK ;WRITE INTO SYS SCRATCH MOV (SP)+,R0 ;RESTORE STARTING BLOCK AGAIN CMPB (R0)+,(R0)+ ;INCREMENT IT BY TWO CMPB (R4)+,(R4)+ ;INCREMENT INPUT BLOCK # AS WELL BR ALSCR1 ;GO DO NEXT 2 BLOCKS NOSCRA: JSR PC,READSF ;READ FROM SAVE FILE DIRECT TO CORE ENDSCR: MOV (SP)+,R5 ;RESTORE CURRENT BLOCK NUMBER MOV (SP)+,R4 ;ALSO RESTORE MASK BR CLRSB ;GO TEST NEXT BIT ORCCB: BISB (R2)+,(R3)+ ;SET BITS IN RESIDENT CCB DEC R1 ;ANY MORE BYTES ? BNE GETBIT ;YES (NOTE CARRY IS STILL SET) RTS PC READSF: CLR -(SP) ;USE WAIT I/O SUB R0,R5 ;NUMBER OF BLOCKS SWAB R5 ;GET WORD COUNT MOV R5,-(SP) ;ONTO STACK MOV R0,-(SP) ;STARTING BLOCK NUMBER TO STACK SWAB (SP) ;MAKE IT AN ADDRESS ASL (SP) EMT 200+17 ;READ THE FILE BCS SFELNK ;ERROR READING FILE RTS PC .SBTTL SYSK, CLRCCB, CLRLOW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; SYSK IS USED TO DO I/O FROM/TO THE SYSTEM SCRATCH AREA. ; IT IS CALLED WITH R0 CONTAINING THE RELATIVE BLOCK NUMBER ; TO BE USED, AND R5 POINTING TO A THREE WORD BLOCK CONTAINING ; THE BUFFER ADDRESS, THE WORD COUNT (NEGATIVE FOR WRITE), ; AND A ZERO. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB SYSK: CLR @.BLKEY ;TELL USR THAT DIR NOT IN CORE MOV @.$SWPBL,-(SP) ;CHECK TO MAKE SURE WE ARE NOT ;READING/WRITING TOO MANY SCRATCH ;BLOCKS. THIS CODE COMPARES THE BLOCK ;TO BE WRITTEN WITH THE START OF ;THE MONITOR, AND ;WILL FAIL IF TOO MANY ARE REQUESTED. ADD (SP),R0 ;MAKE R0 ABSOLUTE BLOCK ADD #SWAPSZ,(SP) ;POINT TO START OF MONITOR MOV 2(R5),-(SP) ;COMPUTE HIGHEST SCRATCH TO WRITE BPL 5$ ;>0 IS READ NEG (SP) 5$: SWAB (SP) ;# BLOCKS TO WRITE. (1 OR 2) ADD R0,(SP) ;MAKE IT ABSOLUTE CMP (SP)+,(SP)+ ;GOING TOO FAR? BHI OVERC ;YES. QUIT. JSR PC,@.$SYS ;USE SYSTEM HANDLER BCC 10$ ;OK, RETURN SYIOER: KMEROR CLRLOW: MOV #PARMS,R1 2$: CLR (R1)+ ;CLEAR OUT 40-53 CMP R1,#PARMS+14 BLO 2$ CLRCCB: MOV @#SYSPTR,R1 ;POINT TO SYSTEM ADD #CCB-$RMON,R1 ;POINT TO CCB MOV #10,-(SP) ;10 WORDS TO CLEAR 1$: CLR (R1)+ DEC @SP BNE 1$ MOV (SP)+,@#USERTOP ;POP COUNT, USE IT TO CLEAR USERTOP 10$: RTS PC .DSABL LSB .SBTTL FILE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; FILE IS USED TO INTERFACE WITH THE CSI ROUTINE GETFD, ; USING THE DEFAULT EXTENSION .SAV ; NULL FILE NAME IS REJECTED WITH AN ERROR MESSAGE ; CALLING SEQUENCE: ; R3 = DEFAULT DEVICE NAME ; R5 -> INPUT STRING (BACKWARDS) ; RETURNS: ; R5 -> DELIMITING CHARACTER ; R3 -> 4-WORD FILE DESCRIPTOR AT LOCATION 'BLOCK' ; R0 = R3 -> 'BLOCK' FOR FILE-REFERENCING EMT'S ; DESTROYS: ; R2 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB FILE: .IF NE BF ;DV16 MOV @.$IMPUR,R2 ;R2 -> B/G $IMPUR AREA ;DV16 ADD #I.NAME,R2 ;R2 -> NAME BLOCK FOR JOB ;DV16 .IFTF ;DV16 JSR R1,1$ ;SAVE R1, POINT TO "SAV" .RAD50 "SAV" 1$: MOV #3*400+17,R0 ;CODE FOR PURGE CHANNEL 17 EMT 374 ;DO THE PURGE MOV R3,DEV1 ;PUT IN PROPER DEFAULT DEVICE NAME MOV #500,R0 ;SET R0 IN CASE OF CHAIN BIT @#JSW,#CHAIN$ ;IS CHAIN$ ON? BNE 2$ ;YES, DEV:FILNAM.EXT IS AT 400 .IFF ;DV16 ADDR BLOCK,R2 ;SETUP POINTER TO FILE DESCRIPTOR .IFTF ;DV16 JSR PC,GETFD ;GET THE FILE DESCRIPTOR (R0 -> BLOCK) 2$: MOV (SP)+,R1 ;RESTORE R1 MOV R0,R3 ;PUT F.D. POINTER INTO R3 TST (R3) ;WAS IT A NULL FILE ?? BEQ 3$ ;YES, THATS BAD TST 2(R3) ;FILE MUST BE SPECIFIED BNE RTS7 ;IT WAS .IFTF ;DV16 3$: KMEROR .IFT ;DV16 RFILE: JSR R1,1$ .RAD50 "REL" .ENDC ;DV16 .DSABL LSB .SBTTL CCBB0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CCBB0 IS USED TO READ IN BLOCK 0 OF A SAVE FILE. THIS ; BLOCK IS READ INTO THE USR BUFFER AND THEN SELECTIVELY ; MOVED INTO THE ZEROETH BLOCK OF CORE (ONLY CERTAIN WORDS ; ARE MOVED, THIS PROTECTS THE SYSTEMS TRAP VECTORS). ; THE USRTOP LOCATION IS SET TO THE MAXIMUM OF THE TOP OF ; THE CURRENT CONTENTS OF CORE AND THE TOP OF THE SAVE ; FILE BEING LOADED. ; RETURNS: ; R1 = 8. ; R2 -> LOCAL COPY OF CCB ; R3 -> CCB COPY IN RMON ; DESTROYS: R0, R5 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CCBB0: MOV SYSIOB,R5 ;GET POINTER TO BUFFER CLR R0 ;READ FROM RELATIVE BLOCK 0 CLR @.BLKEY ;TELL USR THAT DIR NOT IN CORE .READW 17,R5,#400 ;READ ONE BLOCK INTO BUFFER BCS SFELNK ;ERROR WHILE READING MOV @#SYSPTR,R3 ;POINT TO RESIDENT LOW CORE MAP ADD #LOWMAP-$RMON,R3 CLR R1 ;R1 POINTS TO LOW CORE MOV #JSW,R0 ;R0 -> JSW MOV @R0,-(SP) ;SAVE OLD JSW BIC #^C,@SP ;SAVE ONLY CHAIN INDICATION (BIT 400) 1$: MOVB (R3)+,@SP ;GET NEXT MAP BYTE SEC ;SET STOPPER ROLB @SP ;GET FIRST BIT 2$: BCS 3$ ;BIT ON => SKIP IT MOV @R5,@R1 ;MOVE IN A GOOD WORD 3$: CMP (R5)+,(R1)+ ;SKIP A WORD IN EACH ASLB @SP ;GET NEXT BIT BNE 2$ ; IF ANY CMP #500,R1 ;IS LOW PTR = 500 YET? BNE 1$ ;YES TST @SP ;ARE WE IN THE MIDST OF A CAHIN? BEQ 45$ ;NO, COPY 400-776 BIT @R0,#CHAIN$ ;DOES NEW JSW SAY PROTECT 500-776? BEQ 6$ ;NO 45$: BIC #CHAIN$,@R0 ;CLEAR CHAIN INDICATION IF ON 5$: MOV (R5)+,(R1)+ ;NOW MOVE IN THE OTHER 128. WORDS TSTB R1 ;IS LOW PTR = 1000 YET ? BNE 5$ 6$: BIS (SP)+,(R0)+ ;SET SAVED CHAIN INDICATION IN JSW TST (R0)+ ;R0 = 50 -> USERTOP SUB R1,R5 ;CORRECT R5 FOR AMT MOVED (400 OR 1000) ADD R0,R5 ;ADD 50, SO R5 -> NEW USERTOP CMP @R5,@R0 ;IS NEW USERTOP BIGGER THAN OLD? BLOS 7$ ;NO MOV @R5,@R0 ;YES, FIX IT UP 7$: ADD #400-USERTOP,R5 ;R5 -> TOP OF CCB IN FILE ADDR BLOCK+16.,R2 ;R2 -> TOP OF OUR CCB COPY MOV #8.*400+8.,R1 ;MOVE TWO 8'S TO R1 8$: MOV -(R5),-(R2) ;MOVE IN THE CCB DECB R1 ;DONE? BNE 8$ MOV @#SYSPTR,R3 ;POINT TO CCB IN RMON ADD #CCB-$RMON,R3 SWAB R1 ;GET 8 INTO R1 RTS PC .SBTTL GETHAN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; GETHAN IS USED BY GET, RUN, AND SAVE TO GET A FILE DESCRIPTOR ; AND THEN LOAD THE PROPER DEVICE HANDLER INTO THE KMON ; HANDLER AREA. IT USES SUBROUTINE 'FILE' WITH DEFAULT ; DEVICE DSK: TO GET THE FILE DESCRIPTOR. THE ROUTINE EXITS ; WITH THE HANDLER CORRESPONDING TO THE DEVICE NAMED IN ; THE FILE DESCRIPTOR IN CORE. IT LEAVES BOTH R0, AND R3 ; POINTING TO THE FILE DESCRIPTOR. NO UNNECESSARY HANDLER ; FETCHES ARE PERFORMED SINCE THE ROUTINE REMEMBERS THE ; NAME OF THE CURRENT HANDLER IN CORE. R5 IS LEFT POINTING AT ; THE CHARACTER THAT DELIMITED THE F.D. ; R1, R2, AND R4 ARE USED AS TEMPORARIES. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GETHAN: MOV (PC)+,R3 ;USE DK: AS DEFAULT DEVICE .RAD50 /DK / JSR PC,FILE ;GET FILE DESCRIPTOR ; ENTRY FOR REL FILES FROM FRUN OVERLAY GETHAR: ADDR DEVSTS,SP ;POINT TO DEV STATUS BLOCK EMT 342 ;IS HANDLER PRESENT ?? BCS BADHAN ;ERROR - NO SUCH DEVICE TST (R0)+ ;IS IT A DIRECTORY DEVICE ? BPL BADHAN ;NO, THATS ILLEGAL TST 2(R0) ;IS HANDLER RESIDENT ?? BNE HANIN ;YES CMP #MAXHAN,@R0 ;WILL IT FIT ?? BLT BADHAN ;NO ADD #OLDHAN-,R0 ;POINT TO OLD HANDLER NAME .RELEAS ;RELEASE OLD HANDLER MOV @R3,OLDHAN ;SAVE NEW HANDLER NAME ADDR HANDLR,SP ;POINT TO HANDLER SPACE ON STACK MOV R3,R0 ;POINT TO F.D. EMT 343 ;FETCH THE NEW HANDLER BCS BADHAN ;THE DEVICE MAY HAVE A NAME, BUT NOT ;A DEVICE HANDLER HANIN: MOV R3,R0 ;POINT TO F.D. RTS7: RTS PC BADHAN: KMEROR .SBTTL SETBIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; SETBIT IS USED TO SET BITS IN THE CORE CONTROL BLOCK ; AND TO UPDATE (IF NECESSARY) THE USERTOP (TOP OF USER ; CORE) LOCATION OF THE PARAMETER BLOCK. IT IS CALLED ; WITH THE ADDRESS CORRESPONDING TO THE FIRST BIT TO ; BE SET IN R2. THE ENTRY POINT NAMED SETBTS ; IS USED WHEN A SEQUENCE OF BITS IS TO BE SET. IN THIS ; CASE, R4 CONTAINS THE ADDRESS CORRESPONDING TO THE ; LAST BIT TO BE SET. R0 SHOULD CONTAIN A POINTER ; TO THE CCB TO BE ALTERED. ; R0, R1, R2, AND R4 ARE USED BY THIS ROUTINE. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SETBIT: MOV R2,R4 ;ONLY SET ONE BIT (LAST=FIRST) SETBTS: CMP @#USERTOP,R4 ;IS IT HIGHER THAN OLD TOP ?? BHI NOTHIR ;NO MOV R4,@#USERTOP ;YES, MAKE IT THE NEW TOP NOTHIR: BIS #777,R4 ;ROUND R4 TO TOP OF BLOCK DEC R4 ;ON A WORD BOUNDARY SUB R2,R4 ;GET ADDRESS DIFFERENCE CLRB R4 ;NOW MAKE THIS THE BIT COUNT - 1 SWAB R4 ASR R4 SWAB R2 ;MAKE THIS A BLOCK NUMBER SETBT2: ASR R2 MOV R2,R1 ;SAVE IT BIC #177407,R2 ;THIS BYTE IS INDEX INTO CCB (*20.) BIC #177770,R1 ;THIS IS BIT NUMBER WITHIN BYTE ASR R2 ;MAKE IT A BYTE INDEX INTO CCB ASR R2 ASR R2 ADD R0,R2 ;ADD ADDRESS OF DESIRED CCB ONEBIT: CLR R0 ;CLEAR MASK REGISTER SEC ;START WITH CARRY BIT SETMSK: RORB R0 ;ROTATE DEC R1 ;COUNT BPL SETMSK ;MASK NOT READY YET SETCCB: BISB R0,(R2) ;SET BIT IN CORRECT CCB DEC R4 ;ANY MORE BLOCKS (BITS) TO SET IN USE ? BMI RTS7 ;NO, RETURN RORB R0 ;SHIFT BIT AGAIN BCC SETCCB ;SET NEXT BIT IN THIS WORD INC R2 ;GO TO NEXT BYTE BR ONEBIT ;GO INITIALIZE PATTERN .SBTTL COMMAND LIST, STACK, AND HANDLER SPACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A TABLE ENTRY FOR A RESIDENT KMON COMMAND .MACRO CTBL CMD .WORD CMD-XX .ENDM CTBL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A TABLE ENTRY FOR AN OVERLAY COMMAND ; THE ENTRY IS 1 BYTE OF OVERLAY #, AND 1 BYTE OF WORD OFFSET ; INTO THE OVERLAY .MACRO OTBL CMD .BYTE N.'CMD,O.'CMD/2 .ENDM OTBL COMLST: .ASCII " RUREG E D BTSERNI" .WORD 0 .WORD 0,0 ;ROOM FOR RAD 50 CONVERSION OCOMLS: .RAD50 /DAT/ .RAD50 /TIM/ .RAD50 /SAV/ .RAD50 /ASS/ .RAD50 /LOA/ .RAD50 /UNL/ .RAD50 /CLO/ .RAD50 /GT / .RAD50 /SET/ .IF NE BF .RAD50 /FRU/ .RAD50 /SUS/ .RAD50 /RSU/ .ENDC .IIF NDF BANDW, .NLIST .IF DF BANDW .IF NE BF .RAD50 /TEC/ .RAD50 /MAK/ .ENDC .ENDC .IIF NDF BANDW, .LIST .WORD 0 COMLSZ = . - COMLST CTBL R CTBL RUN CTBL GET CTBL E CTBL D CTBL B CTBL STARTK CTBL REENTR CTBL INIT OCOMSZ = . - OCOMLS OTBL DATE OTBL TIME OTBL SAVEK OTBL ASSIGN OTBL LOAD OTBL UNLOAD OTBL CLOSEK OTBL GT OTBL SET .IF NE BF OTBL FRUN OTBL SPND OTBL RSUME .ENDC .IIF NDF BANDW, .NLIST .IF DF BANDW .IF NE BF OTBL TECO OTBL MAKE .ENDC .ENDC .IIF NDF BANDW, .LIST OVLIOB: .WORD 0 ;BLOCK NUMBER CURRENTLY IN CORE .WORD 0 ;AREA TO READ INTO .WORD 400*OVLYSZ ;READ ONE OR TWO BLOCKS .WORD 0 ;WAIT I/O BASE: .WORD 0 GETCNT: .WORD 0 SAVSWT: .WORD 0 BLOKWG: .WORD 0 SYSIOB: BSS 3 ;BLOCK FOR SYSTEM I/O OLDHAN: .BLKW 1 ;OLD HANDLER NAME (USED BY GET) BLOCK: .BLKW 8. ;USED FOR SAVE STATUS AND F.D. BLOCK OVLY: .BLKW 400*OVLYSZ ;AREA FOR OVERLAYS HANDLR: .BLKW MAXHAN/2 ;HANDLER FOR GET, RUN, SAVE .BLKW 34. ;MINIMUM SIZE OF KMON STACK KMONSZ = .-KMON+777/1000 ;SIZE OF KMON IN BLOCKS KMSIZE = KMONSZ*1000 ;SIZE OF KMON IN BYTES KMLEN = KMONSZ*400 ;SIZE OF KMON IN WORDS . = KMON + KMSIZE ;ROUND US UP TO A BLOCK .IIF DF NLKMON, .LIST .NLIST ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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 ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE ; OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DIGITAL. .LIST .IIF DF NLUSR, .NLIST ;USR UPDATE LEVEL 14 .SBTTL USR ENTRY, EMT 376 PROCESSOR RTORG: USRBUF: JSR PC,LOCATE ;FIND REAL POINTERS JMP @R5 ;AND GO TO IT! LOCATE: MOV R1,-(SP) MOV R2,-(SP) ;R2 IS VALUABLE. MOV @#SYSPTR,R5 ;ADDRESS OF THIS RMON MOV #/2,R2 ;NUMBER OF ITEMS TO RELOCATE ADDR RELIST,R1 ;GO THRU RELIST AND MAKE UP 10$: ADD R5,(R1)+ ; A LIST OF RESIDENT ADDRESSES WE NEED DEC R2 ;END OF LIST ? BNE 10$ ;NOT YET ADDR USRBUF,R5 ;POINT TO DIRECTORY BOTTOM MOV R5,.USRBU ;POINTER TO BUFFER ADD #12,R5 ;POINTER TO DIR BOTTOM MOV R5,.USRBO ;POINT INTO USR, NOT RMON. ADD #2000-12,R5 ;POINT TO TOP OF USRBUF (= USR) MOV R5,.USRTO ;SAVE OUR POINTER TO TOP OF USRBUF MOV R5,@.USRLO ;THE MONITOR WILL NOW CALL USR CLR @.BLKEY ;CLEAR DIRECT BLK IN CORE. MOV (SP)+,R2 MOV (SP)+,R1 RTS PC .IF EQ BF .SBTTL ERROR HANDLER ;************************************************** ; THIS IS THE ERROR PROCESSOR FOR RT11 SINGLE USER. ; EMT 376 BRINGS THE USER HERE WHEN A FATAL MONITOR TYPE ; ERROR HAS BEEN DETECTED. THE APRROPRIATE MESSAGE IS ; PRINTED, AS WELL AS THE PC OF THE USER EMT WHICH WAS IN ERROR. ; THE PROCESSOR IS ENTERED WITH R4= ERROR CODE AND R3=PC OF ERRANT EMT. ;************************************************** IOFSET = FATAL - USRBUF .ENABL LSB FATAL: JSR PC,LOCATE ;SET UP RELOCATION LIST ADDR IOTLS,R1 ;POINT TO POINTER LIST ASL R4 ;CODE TIMES 2 ADD R4,R1 ;ADD IN CODE MOV (R1),R1 ;MSG POINTER TO R1 ADD PC,R1 ;GET ABSOLUTE ADDRESS IOTPC: MOVB (R1)+,R0 ;PRINT CHAR BY CHAR BEQ 3$ ;0 MEANS DONE .TTYOUT ;PRINT IT BR IOTPC 3$: MOV #30,R0 ;PRINT THE PC SEC 4$: ROL R3 ROLB R0 .TTYOUT MOV #206,R0 5$: ASL R3 BEQ 6$ ROLB R0 BCS 5$ BR 4$ 6$: BIC #RSTRT$,@#JSW ;NO RESTART CLR R0 .EXIT ;LET'S GET OUT IOTLS: F.0 -IOTPC ;ILLEGAL USR/EXIT CALL F.1 -IOTPC ;NO DEVICE HANDLER F.2 -IOTPC ;DIRECTORY IO ERROR F.3 -IOTPC ;ERROR IN FETCH F.4 -IOTPC ;OVERLAY READ ERROR F.5 -IOTPC ;DIRECTORY OVERFLOW F.6 -IOTPC ;ADDRESS CHECK ERROR F.7 -IOTPC ;ILLEGAL CHANNEL NUMBER F.10 -IOTPC ;ILLEGAL EMT CODE F.11 -IOTPC ;TRAP TP LOC. 4 F.12 -IOTPC ;TRAP TO 10 F.13 -IOTPC ;FPP TRAP .MACRO ERRMSG CODE,TEXT .IRP ..TMP2,<\..TEMP> F.'..TMP2: .ASCIZ TEXT .ENDR CODE'.E = ..TEMP ..TEMP = ..TEMP+1 .ENDM ERRMSG ..TEMP = 0 ERRMSG USRX,<"?M-ILL USR "> ERRMSG NODV,<"?M-NO DEV "> ERRMSG DIRI,<"?M-DIR IO ERR "> ERRMSG FETC,<"?M-BAD FETCH "> ERRMSG OVLY,<"?M-OVLY ERR "> ERRMSG DOVR,<"?M-DIR OVFLO "> ERRMSG ADDR,<"?M-ILL ADDR "> ERRMSG CHAN,<"?M-ILL CHAN "> ERRMSG EMT,<"?M-ILL EMT "> ERRMSG TR04,<"?M-TRAP TO 4 "> ERRMSG TR10,<"?M-TRAP TO 10 "> ERRMSG FPP,<"?M-FP TRAP "> .EVEN .DSABL LSB .ENABL LSB CDFN: MOV ARGM1,R2 ;R2= # TO CREATE MOV R2,R1 ;AS DOES R1 FOR LATER MOV .I.CNU,R5 ;POINT R5 T0 ADD. OF # NOW AROUND CMPB R2,(R5) ;DEFINING <= WHAT WE HAVE NOW? ;DV1 BLOS 24$ ;YES. THAT'S DUMB. GIVE AN ERROR 21$: MOV .QSIZE,R3 ;WAIT FOR IO TO SUBSIDE CMP (R3)+,(R3) BNE 21$ MOV (R5),R4 ;MAKE R4= # WORDS IN CURRENT TABLE ASL R4 ASL R4 ADD (R5)+,R4 MOV (R5),R3 ;R3 IS WHERE THEY NOW START ASL R2 ;MAKE R2= # WDS TO CREATE ASL R2 ADD R1,R2 SUB R4,R2 ;NOW R2=NUMBER LEFT TO 0 OUT 22$: MOV (R3)+,(R0)+ ;COPY ALL OLD CHANNELS DEC R4 BNE 22$ 23$: CLR (R0)+ ;AND THEN ZERO THE REST DEC R2 BNE 23$ MOV (SP),(R5) ;ADDRESS OF NEW TABLE MOV R1,-(R5) ;NUMBER OF ENTRIES BR 25$ 24$: EMTERR+0 25$: JMP COMXIT .ENDC .DSABL LSB .SBTTL USR .ENABL LSB ; THESE PARAMETERS ARE OFFSETS ONTO THE STACK WHEN AN EMT IS RUNNING SAVE = 12 ;6 REGISTERS ON STACK OLDPS = SAVE+4 ;EMT OP. PROCESSOR STATUS ERRPS = OLDPS*2+2 ;EMT 17 ALTERS C BIT HERE ERRPC = OLDPS*2 ;PC OF ERRANT EMT . = RTORG+2000 MOV @SP,R0 ;RESET POINTER TO DEV:FILE.EXT .IF EQ BF TST @.RECUR ;CALLED VIA COMPLETION? BEQ USRA MONERR USRX.E,0,FATAL ;RECURSION IS FATAL ERROR USRA: .ENDC CLR @.SPUSR ;CLEAR SOFTWARE ERR FLAG MOV (R1)+,(PC)+ ;SAVE FIRST ARG ARGM1: .WORD 0 MOV (R1)+,(PC)+ ARGM2: .WORD 0 MOV R2,(PC)+ ;NEW/OLD FLAG USREMT: .WORD 0 MOV SP,(PC)+ ;CURRENT SP IN CASE ERROR USRSP: .WORD 0 CLR R5 ;SOME EMT'S WANT R5=0 ROL R2 ;CLEAR TOP BIT, MAKE INDEX INTO LIST. TST (R2)+ ;INDEX INTO OUR LIST ADD PC,R2 ADD (R2),PC ULS: QSET-ULS ;SETUP IO QUEUE .IF EQ BF CDFN-ULS ;DEFINE IO CHANNELS .IFTF DELETE-ULS ;DELETE FILE EMT PHETCH-ULS KLOSE-ULS ENTER-ULS LOOKUP-ULS RENAME-ULS GESTAT-ULS ;GET DEVICE STATUS .IFT SOFRST-ULS ;SOFT RESET ONLY HDRSET-ULS ;HARD +SOFT RESET .ENDC ..CSI = <. - ULS> / 2 ;INDEX NUMBER FOR CSI CSI-ULS ;COMMAND INTERPRETER ; USRPOP IS A BYTE TABLE GIVING THE NUMBER OF ARGUMENTS EACH USR ; REQUEST MAY REQUIRE TO BE POPPED OFF AT MONOUT. USRPOP: .BYTE 1 ; QSET HAS 1 ARG .IF EQ BF .BYTE 0 ;CDFN HAS NONE .IFTF .BYTE 0,1,0,1,0,0,1 .IFT .BYTE 0,0 ;HRESET AND SRESET ONLY IN SJ MONITOR .IFTF .BYTE 0 ;CSI .ENDC .EVEN ; COMERR IS THE COMMON ERROR EXIT FOR ALL FATAL USR ROUTINES. ; R0 WILL CONTAIN THE ERROR CODE TO BE USED BY EMT 376. COMERR: MOVB (R5),CODE ;R5 POINTS TO CODE MOV USRSP,SP ;RESET STACK CLR @.DFLG ;TURN OFF PROTECTION CLR @.BLKEY ;NO DIRECTORY IN CORE EMT 376 ;FATAL ERROR .BYTE 0 ;LEVEL CODE: .BYTE 0 ;CODE ; AT COMXIT, R2 IS LOADED WITH THE CORRECT NUMBER OF ARGS FOR MONOUT. ; FOR NEW FORMAT EMT'S, NO ARGS NEED TO BE POPPED. COMXIT: MOVB USREMT,R2 ;GET THE ORIGINAL FUNCTION ADD PC,R2 ;POINT TO USRPOP ENTRY MOVB USRPOP-.(R2),R2 ;PUT ARGUMENT NUMBER IN R2 USRB: JMP @.MONOU ;AND EXIT USR .DSABL LSB .SBTTL LOOKUP AND RENAME ; LOOKUP AND RENAME ARE USED TO OPEN A FILE FOR INPUT AND/OR OUTPUT. ; R0 -> DEV:FILE.EXT IN RAD50. ; THE DEVICE FOR THE EMT MUST BE IN CORE .ENABL LSB RENAME: MOV #RENAM$,R5 ;WILL BE RENAME BIT IN CSW LOOKUP: JSR R5,USRCOM ;(R5 IS CLEAR FOR LOOKUP) BR LNFILE ;NON FILE ORIENTED DEVICE BR SPLOOK ;SPECIAL DEVICE LOOKUP MOV R4,SBLK ;R4 CONTAINS SEGMENT START BLK JSR R5,DLEET ;GET A PERMANENT ENTRY OF A FILE NAME. BR LKER1 ;THAT DOESN'T EXIST. BIT #RENAM$,(R3) ;A RENAME DONE? BNE RNAM2 ;YES. PROCESS THE RENAME TST (R3)+ ;POINT TO CHANNEL INFORMATION ADD #E.LENG,R1 ;POINT TO LENGTH WORDS MOV SBLK,(R3)+ ;PUT STARTING BLOCK INTO CSW AREA MOV (R1),(SP) ;LENGTH TO R0 ON RETURN MOV (R1)+,(R3)+ ;AND ALSO TO CSW AREA MOV (R1)+,(R3)+ ;DATA LENGTH BR COMXIT RNAM2: ADD #10,R0 ;POINT TO NEW NAME MOV #EMPTY,(R1)+ ;SO DLEET CAN FIND OLD COPY MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ ;FILL IN NEW NAME MOV (R0)+,(R1)+ SUB #10,R1 ;POINT R1 AT STATUS WORD JMP CLOCOM ;DO COMMON CLOSE OPERATIONS LNFILE: TST (R3)+ ;LEAVE CSW ALONE, GO CLEAR START BLK BR DELOUT ;************************************************** ; SPLOOK, SPDEL, AND SPCLOS ARE ROUTINES ; TO HANDLE REQUESTS FOR SPECIAL DIRECTORY DEVICES ; THEY PASS THE INDICATED FUNCTION ON TO THE ; HANDLER THROUGH ROUTINE SPESHL ;************************************************** SPLOOK: TST R5 ;RENAME DONE? BNE LKER1 ;YES. GIVE ERROR 1 BIS #DWRIT$,(R3) ;REWRITE DIRECTORY BIT JSR R4,SPSHL1 .BYTE 377,LOOK.. BCC COMXIT ;NO ERROR ENER1: LKER1: EMTERR+1 ;CODE 1 ERROR DELOUT: CLR (R3)+ ;DEACTIVATE CHANNEL BR COMXIT SPDEL: JSR R4,SPSHL1 ;DO A DELETE .BYTE 377,DELE.. BCC DELOUT ;NO ERROR. DEACTIVATE CHANNEL BR LKER1 ;ERROR OCCURRED. SPCLOS: JSR R4,SPESHL .BYTE 377,CLOS.. ;DO A CLOSE BR DELOUT .DSABL LSB .IF EQ BF .SBTTL RESET, EXIT TO KMON ; THESE ARE THE ENTRIES FOR THE SOFT AND HARD RESET EMT'S SOFRST: MOV (PC)+,R0 ;JUST DO CHANNEL AND DEVICE RESET HDRSET: CLR R0 ;JUST HARDWARE RESET. JSR PC,RSTSR ;DO THE RESET BR COMXIT .ENDC .SBTTL DELETE ; DELETE USES USRCOM TO SET UP A CHANNEL FOR DIRECTORY ; OPERATIONS, AND THEN CALLS DLEET TO ACTUALLY FIND THE ; FILE TO BE DELETED. THE ENTRY IS MADE INTO ; AN EMPTY FILE. THE DIRECTORY CONSOLIDATOR IS CALLED ; AT CLSQSH, AND THE CHANNEL IS CLOSED. DELETE: JSR R5,USRCOM ;SETUP THE CHANNEL FOR DIRECTORY IO BR DELOUT ;NON FILE DEVICE BR SPDEL ;DO SPECIAL DELETE JSR R5,DLEET ;FIND THE FILE. R0 POINTS TO IT. BR LKER1 ;NO SUCH FILE TO DELETE MOV #EMPTY,(R1) ;MAKE ENTRY AN EMPTY JMP CLSQSH ;CONSOLIDATE SEGMENT AND EXIT .SBTTL ENTER ; ENTER PROCESSOR ; HANDLES OPENING OF NEW FILES ON DEVICES. THE FILE IS ADDED ; INTO THE DIRECTORY IN FRONT OF AN ALREADY EXISTING EMPTY ; DIRECTORY ENTRY. IF THE ENTRY BEFORE THE EMPTY IS A TENTATIVE ; FILE, AN EMPTY OF LENGTH 0 IS INSERTED AFTER THE SECOND ; TENTATIVE ENTRY .ENABL LSB ENTER: MOV #DWRIT$,R5 ;SET DIRECTORY REWRITE NEEDED JSR R5,USRCOM ;DO COMMON STARTUP BR ENOUT ;ENTER ON NON-FILE DEVICE IS EASY BR SPENTR ;SPECIAL ENTER IS SPECIAL MOV USRBUF+4,LSTBLK ;REMEMBER HIGHEST DIRECTORY BLOCK CLR FNAME ;USE FNAME BLOCK TO FIND LARGEST CLR FNAME+2 ; AND 2ND LARGEST ENTRIES BR 2$ ;ENTER LOOP (BLOCK 1 ALREADY IN CORE) 1$: JSR R5,NXBLK ;READ NEXT BLOCK INTO CORE BR 10$ ;NO MORE DIRECTORY 2$: JSR PC,CONSOL ;CONSOLIDATE THIS BLOCK MOV R4,SBLK ;REMEMBER START BLOCK 3$: ADDR FNAME,R5 ;POINT TO 2ND LARGEST SO FAR JSR R5,ENTRY ;GET AN EMPTY ENTRY EMPTY BR 1$ ;NO MORE EMPTIES IN THIS BLOCK MOV E.LENG(R1),R0 ;GET LENGTH OF EMPTY MOV ARGM1,R2 ;GET REQUESTED SIZE BEQ 4$ ;0 => GET LARGEST TWO CMP #-1,R2 ;-1 => LARGEST BNE 15$ ;NO, A SPECIFIC REQUEST 4$: CMP (R5)+,R0 ;2ND LARGEST : THIS HOLE BHIS 6$ ;NO GOOD, IGNORE IT CMP @R5,R0 ;LARGEST : THIS HOLE BHIS 5$ ; GREATER => THIS IS NEW 2ND LARGEST MOV @R5,-(R5) ;MOVE FORMER LARGEST TO 2ND SPOT ADD #8.,R5 ;ADVANCE POINTER MOV -(R5),-(R5) ;COPY BLOCK INDEX 5$: MOV R0,-(R5) ;SAVE HOLE SIZE MOV @R3,4(R5) ;SAVE BLOCK POINTER 6$: ADD R0,SBLK ;MAINTAIN START BLOCK JSR PC,INCR1 ;BUMP R1 POINTER BR 3$ ;KEEP LOOKING SPENTR: JSR R4,SPESHL ;SPECIAL DEVICE ENTER .BYTE 377,ENTR.. BCC ENOUT ;DONE GOOD EMTERR+0 ENOUT: JMP COMXIT 10$: TST (R5)+ ;END OF PASS 1. POINT R5 TO LARGEST MOV ARGM1,R2 ;GET REQUEST SIZE BNE 11$ ;MIGHT HAVE BEEN SPECIFIC OR MAX ROR @R5 ;TAKE HALF THE LARGEST HOLE CMP @R5,-(R5) ;COMPARE IT TO THE 2ND LARGEST HOLE BLO 13$ ;2ND LARGEST IS BIGGER TST (R5)+ ;THAT HALF IS BIGGER 13$: CMP @.MAXBL,@R5 ;ASKING FOR TOO MUCH? BHIS 12$ ;NO. LEAVE IT ALONE MOV @.MAXBL,@R5 ;GIVE ONLY THE MAXIMUM BR 12$ 11$: INC R2 ;IF IT WASN'T -1, BNE ENER1 ;THEN IT WAS A FAILING SPECIFIC REQUEST 12$: MOV @R5,ARGM1 ;CONVERT REQUEST TO SPECIFIC BEQ ENER1 ;GOLLY, THERE'S NO ROOM AT ALL BIC #DBLK$M,@R3 ;CLEAR OUT BLOCK NUMBER BIS 4(R5),@R3 ;START RESCAN AT A GOOD PLACE RENTR: JSR R5,BLKCHK ;GET DBLOCK INTO CORE BR 2$ ;START LOOP 15$: CMP R0,R2 ;SPECIFIC REQUEST SATISFIED? BLO 6$ ;NO. GET NEXT MOV R1,-(SP) ;SAVE POSITION OF EMPTY, AND MOV DREND,R1 ;SEE IF ROOM FOR 3 MORE ENTRIES JSR PC,INCR2 JSR PC,INCR1 CMP R1,.USRTO BHI EXTEND ;HAVE TO OPEN NEW BLOCK MOV (SP)+,R1 MOV SBLK,R4 ;SAVE STARTING BLOCK MOV R1,R5 SUB R2,E.LENG(R1) ;DECREASE LENGTH OF EMPTY SUB #L.ENTR,R5 ;STATUS OF PREVIOUS ENTRY SUB USRBUF+6,R5 ;WASTE WORDS CMP R5,.USRBO ;OUTSIDE DIRECTORY BUFF? BLO 20$ ;YES. PREVIOUS NOT TENTATIVE BIT #TENT,(R5) ;PREVIOUS TENTATIVE? BEQ 20$ ;GUESS NOT. JSR PC,PUSH ;PUT IN EMPTY OF LENGTH 0 MOV #EMPTY,(R1) ;STATUS ENTRY CLR E.LENG(R1) ;CLEAR OUT THE LENGTH JSR PC,INCR1 ;POINT TO NEXT ENTRY 20$: JSR PC,PUSH ;MAKE ROOM FOR REAL ENTRY MOV #TENT,(R1) ;AND MAKE IT TENTATIVE. MOV (SP),R0 ;RESET R0 TO DEV: CMP (R0)+,(R1)+ ;POINT TO NAME AREAS MOV (R0)+,(R1)+ ;FILL IN FILE NAME MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ MOV R2,(R1)+ ;LENGTH OF HOLE .IF NE BF MOVB CHNLRG,(R1)+ ;PUT IN CHANNEL OF REQUEST MOVB @.JOBNUM,(R1)+ ; AND JOB OF REQUESTOR .IFF MOV CHNLRG,(R1)+ ;PUT IN CHANNEL NUMBER .ENDC MOV @.$DATE,(R1)+ ;DATE WORD TST (R3)+ ;FILL IN CHANNEL STUFF CLR (R3) JSR R5,SEGRW2 ;WRITE THE SEGMENT 11*400 MOV R4,(R3)+ ;INSERT START BLOCK MOV R2,(R3)+ ;HOLE LENGTH CLR (R3) ;DATA LENGTH MOV -(R3),(SP) ;GIVE BACK THE HOLE LENGTH BR ENOUT .DSABL LSB .SBTTL DIRECTORY EXTEND ; ENTER EXTEND IS PERFORMED WHEN AN ENTRY WILL NOT FIT INTO ; AN EXISTING DIRECTORY BLOCK. IF THE DIRECTORY CONTAINS ANOTHER ; DIRECTORY BLOCK, EXTEND DOES THE FOLLOWING THINGS: ; FIND THE TOTAL NUMBER OF ENTRIES IN THE DIRECTORY ; SEGMENT. DIVIDE THAT BY 2, AND SET R1 TO THE ENTRY THAT IS ; ROUGHLY 1/2 THE WAY DOWN IN THE DIRECTORY. STARTING THERE, WE ; SEARCH FOR A PERMANENT OR TENTATIVE OR ENTRY ENTRY. WHEN AN ENTRY ; IS FOUND, THE CURRENT SEGMENT IS TERMINATED WITH AN END ; BLOCK MARK, AND WRITTEN OUT. THE REMAINING ENTRIES ARE THE FIRST ; ENTRIES IN A NEW SEGMENT. THE SEGMENTS ARE LINKED, AND THE NEWLY ; CREATED SEGMENT IS WRITTEN OUT. BLOCK 1 OF THE DIRECTORY IS ; UPDATED TO REFLECT THE HIGHEST BLOCK USED IN THE DIRECTORY, AND ; ENTER IS RESTARTED AT THE DIRECTORY BLOCK WHICH WAS SPLIT. EXTEND: TST (SP)+ ;CLEAN OFF STACK MOV (PC)+,R2 ;HIGHEST BLOCK NOW IN USE LSTBLK: 0 INC @.DFLG ;HOLD OFF ON ^C CMP R2,USRBUF ;IS THERE ANOTHER BLOCK? BLT 1$ ;YES, USE IT JSR R5,COMERR ;NO MORE SEGMENTS AVAILABLE .WORD DOVR.E 1$: CLR R4 ;NOW LOOK FOR END MARK JSR PC,NTHENT ;THIS CALL COUNTS THE ENTRIES ASR R4 NEG R4 ;GET THE HALF WAY ENTRY JSR PC,NTHENT 3$: BIT #PERM!TENT,(R1) ;IS IT PERMANENT OR TENTATIVE? BNE 2$ ADD E.LENG(R1),R5 ;NO-INCREASE START BLOCK OF NEW FILE JSR PC,INCR1 ;GET NEXT ENTRY BR 3$ 2$: MOV @R1,-(SP) ;SAVE TYPE OF ENTRY MOV #ENDBLK,(R1) ;TERMINATE SEGMENT INC R2 ;POINT TO NEW HIGH BLOCK IN DIRECT. MOV USRBUF+2,-(SP) ;SAVE LINK TO NEXT BLOCK MOV R2,USRBUF+2 ;LINK TO NEW BLOCK JSR R5,SEGRW2 ;WRITE OUT SHORTENED BLOCK 11*400 ;RE WRITE SEGMENT MOV .USRBU,R0 ;NOW CREATE NEW SEGMENT HEADER TST (R0)+ ;LEAVE # SEGMENTS OPEN ALONE MOV (SP)+,(R0)+ ;GET LINK TO NEXT SEGMENT MOV (SP)+,(R1) ;RESTORE ORIGINAL STATUS CMP (R0)+,(R0)+ ;IGNORE HIGH SEG AND # XTRA BYTES MOV R5,(R0)+ ;START BLOCK OF TSEGMENT 4$: MOV (R1)+,(R0)+ ;SLIDE DIRECTORY BUFF UP TO HEADER CMP R1,.USRTO BLOS 4$ MOV R2,R0 ;WRITE OUT NEW DIRECTORY BLOCK JSR R5,SEGRW 11*400 JSR R5,SEGRW1 ;READ IN DBLOCK 1 10*400 INC USRBUF+4 ;UPDATE HIGHEST BLOCK USED JSR R5,SEGRW1 ;AND REWRITE THE BLOCK 11*400 DEC @.DFLG CLR @.BLKEY ;GET CORRECT BLOCK IN CORE JMP RENTR ;RESTART ENTER NTHENT: ADDR USRBUF+10,R1 ;GET N'TH ENTRY IN DIRECTORY MOV (R1)+,R5 ;INITIAL START BLOCK OF FILES 1$: BIT (R1),#ENDBLK ;AT END OF SEGMENT? BNE 2$ ;YES. EXIT NOW ADD E.LENG(R1),R5 ;UPDATE START BLOCK JSR PC,INCR1 ;BUMP R1 TO NEXT ENTRY INC R4 ;R4 HAS DESIRED ENTRY, IN NEG. FORM BNE 1$ 2$: RTS PC .SBTTL GET DEVICE STATUS EMT ; DSTATUS RETURNS THE STATUS OF A PARTICULAR DEVICE IN THE SYSTEM. ; THE 2ND ARGUMENT IS A POINTER TO WHERE THE USER WANTS THE INFORMATION ; R0 -> THE DEVICE NAME IN RAD50. THE INFORMATION RETURNED IS: ; 1- $STAT TABLE ENTRY ; 2- SIZE OF DEVICE HANDLER IN WORDS ; 3- ENTRY POINT OF HANDLER. 0 IF NONRES. ; 4- SIZE OF DEV DIRECT IN 256 WORD BLOCKS ; R0 -> WORD ONE OF THE BLOCK ON RETURN. GESTAT: JSR R4,LK4DEV ;SEARCH TABLES FOR DEVICE BR FCE0 ;NO SUCH NAME MOV ARGM1,R0 ;POINTER TO USERS AREA MOV R0,@SP ;MAKE SURE HE GETS IT BACK MOV @R2,(R0)+ ;R2 POINTS TO STATUS TABLE ADD PC,R3 ;GET HANDLER SIZE FROM TABLE 1$: MOV $HSIZE-.(R3),(R0)+ ;(PIC) AND GIVE IT TO HIM MOV @R5,(R0)+ ;ENTRY POINT MOV $DVSIZE-1$(R3),(R0)+ BR PHOUT ;EXIT. ONE ARG ON STACK .SBTTL DEVICE HANDLER FETCH, DEFINE CHANNELS PHETCH: JSR R4,LK4DEV ;SEARCH FOR R0 FILE DESCRIPTOR BR FCE0 ;NO SUCH DEVICE MOV ARGM1,@SP ;LOAD POINT TO STACK (R0 ON RET.) CMP @SP,#400 ;< 400 WILL IMPLY A RELEASE BLOS RLEAS MOV R5,R4 ;LK4DEV LEFT R5 AT $ENTRY ENTRY .IF EQ BF TST (R5) ;IS IT ALREADY RESIDENT? BNE PHOUT ;YES, GO AWAY .IFF TST @.JOBNUM ;FETCH FROM FG? BEQ 1$ ;BRANCH IF NOT CMP @R5,@.SYSLO ;IS HANDLER IN BG OR NON-RES.? BLO 2$ ;YES, THAT'S BAD 1$: TST @R5 ;IS HANDLER RESIDENT? BNE PHOUT ;YES, GO ON. .ENDC MOV R3,R2 ;COPY DEVICE INDEX ADD PC,R2 ;AND IN A PIC WAY MOV $HSIZE-.(R2),R2 ;GET HANDLER SIZE MOV @#SYSPTR,R0 ;CHECK FOR OVERLAYING RMON ADD R0,R3 ;POINT R3 TO $DVREC IN RMON ADD #$DVREC-$RMON,R3 ;DV2 - TEST FOR KMON WAS REMOVED SO ALL KMON .FETCHES ARE ERROR CHECKED. SUB R2,R0 ;MUST LOAD BELOW HERE CMP (SP),R0 ;IS IT BELOW THE RMON ? BHI 2$ ;NO, BOOT HIM MOV .USRBU,R1 ;NOW TEST FOR LEGAL LIMITS SUB R2,R1 ;LOAD HANDLER. CAN'T OVERRUN CMP (SP),R1 ;USR OR RMON BLOS 3$ ADD #USRLEN*2,R1 ;SEE IF IT LOADS ABOVE USR ADD R2,R1 ;ADD LENGTH BACK CMP (SP),R1 ;R1 NOW POINTS TO TOP OF USR BHI 3$ 2$: JSR R5,COMERR ;ILLEGAL ADDRESS .WORD FETC.E 3$: MOV (R3),R0 ;GET RECORD NO OF HANDLER BEQ FCE0A ;0 BLOCK => NO DEVICE ADDR PHLST+6,R5 ;POINT TO ARG LIST CLR -(R5) ;WAIT FOR COMPLETION MOV R2,-(R5) ;SIZE IN BYTES ASR (R5) ;SIZE IN WORDS MOV (SP),-(R5) ;LOAD POINT JSR PC,@.$SYS ;READ HANDLER IN BCS 2$ ;LOAD FAILED 4$: MOV (SP),R0 ;NOW SET INTERRUPT VECTORS MOV (R0)+,R1 ;VECTOR ADDRESS TO R1 BEQ 6$ ;IF 0, DON'T CHANGE VECTOR MOV R0,(R1) ADD @R0,(R1)+ ;FILL IN FINAL ADDRESS OF INTERRUPT MOV #PR7,(R1)+ ;INTERRUPT STATUS 6$: CMP (R0)+,(R0)+ ;SKIP INTERRUPT OFFSET & PRIORITY MOV R0,(R4) ;ENTRY POINTS TO LAST Q ENTRY ADD R2,(SP) ;POINT TO ADDRESS ABOVE HANDLER MOV @SP,R2 ;MAKE LAST WORD OF HANDLER MOV .$INTEN,-(R2) ; POINT TO $INTEN PHOUT: JMP COMXIT RLEAS: CMP (R5),@.SYSLO ;TRYING TO KILL A RESIDENT DEV? BHI PHOUT ;YES. DON'T DO IT .IF NE BF TST @.JOBNU ;RELEASE FROM F/G? ;DV4 BNE PHOUT ;YES, IGNORE IT. ;DV4 .ENDC CLR (R5) ;0 ENTRY POINT BR PHOUT FCE0A: CLR (R4) ;ERASE ENTRY POINT FCE0: EMTERR+0 BR PHOUT .SBTTL USR INITIALIZATION FOR LOOKUP, ENTER, RENAME, DELETE ; USRCOM-- ; USRCOM IS USED BY LOOKUP/RENAME AND ENTER TO PREPARE A CHANNEL ; FOR I/O OPERATIONS. ON ENTRY, THE STACK POINTS TO THE OLD VALUE ; OF R5, WHICH INDICATES WHETHER AN ENTER, LOOKUP OR RENAME IS ; REQUIRED. USRCOM DOES THE FOLLOWING: ; TEST TO SEE IF CHANNEL IS OPEN ; TEST IF SPECIFIED DEVICE IS LEGAL ; READ FIRST DIRECTORY BLOCK OF THE PROPER DEVICE .ENABL LSB USRCOM: ASR R4 ;MAKE R4 INTO CHANNEL NUMBER MOV R4,CHNLRG ;SAVE CHANNEL SELECTOR TST (R3) ;CHANNEL ACTIVE? BMI 1$ ;YES, GIVE ERROR CLR 2(R3) ;CLEAR STARTING BLOCK MOV 2(SP),R0 ;RESTORE R0 MOV R5,-(SP) ;NEED TO SAVE REGISTERS 3,5 MOV R3,-(SP) JSR R4,LK4DEV ;IS DEVICE IN CORE? BR COMNDV ;NO SUCH NAME BEQ COMNDV ;NO DEVICE IS THERE! ;NOTE THAT R0 POINTS TO FILE.EXT .IF NE BF MOV R1,R5 ;COPY UNIT # ASR R5 ; UNIT /2 ADD R3,R5 ; +2*DEVICE INDEX ADD R3,R5 ADD .$OWNER,R5 ;POINT TO OWNERSHIP TABLE MOVB @R5,R5 ;R5 = OWNERSHIP BYTE BIT #1,R1 ;IF UNIT IS ODD, BEQ 2$ ASR R5 ;THEN USE HIGH 4 BITS ASR R5 ASR R5 ASR R5 2$: BIC #177760,R5 ;4 BIT FIELD BEQ 3$ ;0 => PUBLIC DEC R5 ;REMOVE GUARD BIT CMP @.JOBNUM,R5 ;DO WE OWN IT? BNE COMNDV ;NO, GIVE AN ERROR .ENDC 3$: MOV R3,R5 MOV (SP)+,R3 ;RESTORE CSW POINTER ADD R5,(R3) ADD #ACTIV$+DBLOK$*1,@R3 ;SET CHANNEL ACTIVE, DBLOCK=1 MOV (SP)+,R5 SWAB R1 ;R1 CONTAINS DEVICE # INDEX MOV R1,C.DEVQ(R3) ;PUT IT INTO CSW BLOCK TST (R2) ;IS IT FILE STRUCTURED? BPL USRNF ;NO. DON'T ALTER CHANNEL WORD BIS (SP),(R3) ;SET RENAME OR DIRECT. REWRITE BIT TST (R0) ;IS THE NAME NULL? BEQ USR3 ;IF YES, IT'S NON FILE OP. JSR R5,BLKCHK ;GET A DIRECTORY BLOCK IN CORE USR2: TST (R5)+ ;RETURN FOR FILE TYPE OP. ENXT: TST (R5)+ USR3: RTS R5 USRNF: BIT #SPECL$,(R2) ;IS IT A SPECIAL DEVICE? BEQ USR3 BIS (SP),(R3) ;SET REWRITE BIT FOR SPECIAL DEV BR ENXT ;SPECIAL DEVICE EXIT 1$: MOV (SP)+,R5 ;POP STACK BR FCE0 ;GIVE CHANNEL ACTIVE ERROR COMNDV: JSR R5,COMERR ;NO HANDLER THERE .WORD NODV.E .DSABL LSB .SBTTL ENTRY MATCH, PUSH ; ENTRY-- ; FIND AN ENTRY OF A SPECIFIED TYPE IN A DIRECTORY SEGMENT ; CALLING SEQUENCE: ; R1 -> DIRECTORY ENTRY ; JSR R5,ENTRY ; .WORD ENTRYTYPE (TENT, EMPTY, OR ENDBLK) ; ERROR RETURN - NO ENTRY FOUND ; NORMAL RETURN ; RETURNS: ; R1 -> ENTRY OF SPECIFIED TYPE, OR END-OF-BLOCK MARKER ; IF NO ENTRY IS FOUND ENTRY: BIT @R5,@R1 ;A MATCH? BNE USR2 ;YES, GET OUT BIT @R1,#ENDBLK ;END OF BLOCK? BNE ENXT ;YES, RETURN ADD E.LENG(R1),(PC)+ ;UPDATE LENGTH SBLK: 0 JSR PC,INCR1 ;NEXT ENTRY IN SEGMENT BR ENTRY ;AND LOOP ; PUSH-- ; USED TO PHYSICALLY ENLARGE DIRECTORY WHEN AN ENTER IS DONE. PUSH: MOV R3,-(SP) ;SAVE VITAL R3 POINTER MOV R1,R5 ;MARK POSITION OF EMPTY JSR R5,ENTRY ;FIND END OF DIRECTORY .WORD 0 ;SEARCH FOR NO MASK GETS TO END OF BLOCK! MOV R1,R3 ;R3 POINTS TO END OF DATA JSR PC,INCR1 ;ONE ENTRY PAST ENDBLK IS WHERE NEW ;DIRECTORY WILL END CMP (R3)+,(R1)+ ;MOVE ALL ENTRIES 2$: MOV -(R3),-(R1) CMP R3,R5 BNE 2$ MOV R5,R1 ;POINT BACK TO WHERE FILE GOES. MOV (SP)+,R3 ;RESTORE R3 RTS PC .SBTTL CHECK DIR. SEGMENT ; NXBLK GETS THE NEXT IN THE SEQUENCE OF DIRECTORY BLOCKS, ; IF ONE ACTUALLY EXISTS. NXBLK: MOV USRBUF+2,R0 ;IS THERE A NEXT BLOCK? BEQ ENRTS ;NO. SWAB R0 ;PUT BLOCK # IN PLACE BIC #DBLK$N,R0 ;ISOLATE BLOCK NUMBER BIC #DBLK$M,(R3) ;CLEAR OUT BLOCK # IN CSW BIS R0,(R3) TST (R5)+ ;SET NORMAL RETURN, FALL INTO BLKCHK ; BLKCHK-- ; THIS ROUTINE CHECKS THAT THE DIRECTORY BLOCK NUMBER INDICATED IN ; THE CURRENT CHANNEL STATUS WORD IS ACTUALLY IN CORE. ; IF IT IS NOT, THE IN-CORE POINTERS ARE UPDATED, AND THE ; PROPER BLOCK IS READ INTO CORE. BLKCHK: MOV R0,-(SP) ;SAVE NAME POINTER MOV (R3),R0 ;ISOLATE DESIRED BLOCK SWAB R0 BIC #177740,R0 MOV C.DEVQ(R3),-(SP) ;SEE IF DIRECTORY OF CORRECT DEV MOVB (R3),(SP) ;IS IN CORE. CHECK DEV POINTER, BIC #301,(SP) ;AND DEV. INDEX CMP R0,@.BLKEY ;CORRECT SEGMENT # IN CORE ? BNE 1$ ;NO, WE MUST READ CMP (SP),@.CHKEY ;CORRECT DEVICE & UNIT ? BEQ 2$ ;YES, NO NEED TO READ 1$: MOV R0,@.BLKEY ;SAVE THE BLOCK IN CORE JSR R5,SEGRW ;READ IT IN 10*400 ;READ EMT 2$: MOV (SP)+,@.CHKEY ;PURGE STACK, SET CHKEY ADDR USRBUF+10,R1 ;POINT R1 AT ENTRY HEADER MOV (R1)+,R4 ;SAVE FILE START BLOCK MOV (SP)+,R0 ;R0 POINTS TO FILE.EXT ENRTS: RTS R5 SEGRW1: MOV #1,R0 ;USE SEGMENT #1 BR SEGRW ;ENTER ROUTINE SEGRW2: MOV @.BLKEY,R0 SEGRW: ASL R0 ;DIRECT. BLK TO PHYSICAL BLOCK ADD #DOFSET,R0 ;OFFSET TO DIRECTORY CLR -(SP) ;ALWAYS WAIT FOR COMPLETION MOV #1000,-(SP) MOV .USRBU,-(SP) ;POINT TO BUFFER ON STACK MOV R0,-(SP) ;LOAD BLOCK NUMBER MOV (PC)+,-(SP) ;CHANNEL NUMBER TO LIST CHNLRG: 0 ADD (R5)+,(SP) ;ADD IN OP CODE MOV SP,R0 ;POINT R0 TO LIST EMT 375 ;AND DO THE EMT BCS IOER ;DEC DIDN'T HURT C BIT ADD #10.,SP ;BACK TO BEFORE ARGS RTS R5 .SBTTL SPECIAL DEVICES ; SPESHL IS THE HEART AND SOUL OF THE SPECIAL DEVICE FUNCTION PROCESSOR ; CALLING SEQUENCE: ; JSR R4,SPESHL ; .BYTE 377,FUNCTION ; FUNCTION BYTE IS USED IN A PSEUDO READC TO THE DEVICE HANDLER. ; THE Q MANAGER DETECTS THE 377 IN THE COMPLETION ADDRESS WORD, ; AND STUFFS THE FUNCTION CODE INTO THE FUNCTION BYTE IN THE Q ELEMENT. ; THE HANDLER THEN EXECUTES THE INDICATED JOB. SPSHL1: MOV ARGM1,ARGM2 SPESHL: BIC #EOF$+HDERR$,(R3) ; CLEAR END FILE, HARD ERR CLR -(SP) ;MAKE IT SYNCHRONOUS MOV (R4)+,-(SP) ;COMPLETION FUNCTION CLR -(SP) ;0 WORD COUNT MOV 8.(SP),-(SP) ;NAME POINTER (BUFFER POINTER) ADD #2,(SP) ;MAY BE ODD IN .CLOSE. POINT TO FILE NAME CLR -(SP) ;0 BLOCK FOR NOW. TST USREMT ;NEW FORMAT EMT? BPL 1$ ;NO. DO A REWIND MOV ARGM2,(SP) ;FILL IN FILE COUNT 1$: MOV CHNLRG,-(SP) ;NOW FORM FUNCTION WORD ADD #10*400,(SP) ;MAKE IT A READ-WAIT MOV SP,R0 ;POINT R0 TO OUR ARG. LIST EMT 375 ;READW BCS IOER ;IO ERROR SOMEWHERE ADD #12.,SP ;CLEAN OFF STACK CLR @.BLKEY ;NO DIRECTORY IN CORE MOV @.SPUSR,-(SP) ;WAS THERE A SOFTWARE ERROR? NEG (SP)+ ;SET CARRY IF SO (NON-0) RTS R4 IOER: JSR R5,COMERR ;M ERROR 5 .WORD DIRI.E .SBTTL DIRECTORY CONSOLIDATOR ; CONSOL REMOVES ANY UNNECESSARY ENTRIES FROM A GIVEN DIRECTORY. ; THIS IS DONE BEFORE AN ENTER AND AFTER A CLOSE. ; UNNECESSARY ENTRIES COME IN SEVERAL FLAVORS: ; A) UNASSOCIATED TENTATIVE ENTRIES ; B) MULTIPLE CONSECUTIVE EMPTIES ; C) EMPTIES OF LENGTH 0 FOLLOWING A PERMANENT ENTRY ; ; CONSOL MAKES TWO PASSES OVER THE DIRECTORY SEGMENT. ; IN PASS 1, UNASSOCIATED TENTATIVES ARE MADE INTO EMPTIES. ; IN PASS 2, CONSECUTIVE EMPTIES ARE CONSOLIDATED AND ; EMPTY ENTRIES PRECEEDED BY A PERMANENT ENTRY ARE DELETED. CONSOL: MOV R4,-(SP) ;SAVE ACTIVE REGISTERS MOV R3,-(SP) MOV R1,-(SP) ;R1 POINTS TO TOP OF DIRECTORY MOV #16,R4 ;PUT ENTRY SIZE INTO R4 ADD USRBUF+6,R4 1$: JSR R5,ENTRY ;GET A TENTATIVE ENTRY TENT BR 14$ ;NO MORE. DO PASS 2 .IF NE BF MOVB E.JNUM(R1),R2 ;GET JOB # OF TENTATIVE ADD .$IMPUR,R2 MOV @R2,R2 ;R2 -> IMPURE AREA OF CREATOR BEQ 3$ ;NO JOB, SO TENTATIVE IS UNUSED .IFTF CLR R5 ;GET CHANNEL NUMBER BISB E.CHAN(R1),R5 ; IN R5 .IFT CMPB I.CNUM(R2),R5 ;LEGAL CHANNEL FOR JOB? BLOS 3$ ;NO CMP @.CNTXT,R2 ;IS THIS OUR TENTATIVE? BNE 2$ ;NO .IFF CMPB @.I.CNU,R5 ;COMPARE WITH MAX CHAN. # BLOS 3$ .IFTF CMPB CHNLRG,R5 ;YES. IS TENTATIVE ON THIS CHANNEL? BEQ 3$ ;YES, CLOBBER IT 2$: ASL R5 ;CHANNEL * 10. MOV R5,-(SP) ASL R5 ASL R5 ADD (SP)+,R5 .IFT ADD I.CSW(R2),R5 ;R5 -> CHANNEL OF TENTATIVE .IFF ADD @.I.CSW,R5 ;R5 -> CHANNEL OF TENTATIVE .ENDC TST @R5 ;IS ASSOCIATED CHANNEL OPEN? BPL 3$ ;NO, TENT. IS INVALID MOV C.DEVQ(R5),R2 ;GET UNIT # IN HIGH ORDER CLRB R2 BISB @R5,R2 ;ASSEMBLE DEVICE INDEX BPL 3$ ;OOPS, ASSOCIATED CHANNEL IS LOOKED UP BIC #301,R2 ;R2 = CHKEY FOR TENTATIVE'S CHANNEL CMP @.CHKEY,R2 ;SAME DEVICE AND UNIT? BEQ 4$ ;YES, TENT.'S CHANNEL STILL OPEN ON ; THIS PARTICULAR TENTATIVE 3$: MOV #EMPTY,@R1 ;CONVERT TENT. TO EMPTY 4$: ADD R4,R1 ;NEXT ENTRY BR 1$ 14$: MOV (SP),R1 ;POINT R1 BACK TO TOP 5$: JSR R5,ENTRY ;GET AN EMPTY ENTRY EMPTY BR CNSLOV ;DONE. GET OUT MOV R1,R2 ADD R4,R2 ;POINT R2 TO NEXT ENTRY BIT #EMPTY,(R2) ;IS IT EMPTY? BEQ 7$ ;NO. CHECK FOR EMPTY OF LTH 0 ADD E.LENG(R2),E.LENG(R1) ;COMBINE LENGTHS. ; SQUEEZE THE DIRECTORY 6$: MOV R2,R5 ;THE ENTRY AT R2 WILL BE CRUNCHED ADD R4,R5 ;ONE ENTRY BEYOND MOV R1,-(SP) ;SAVE R1 JSR R5,ENTRY ;GET END OF DIRECTORY MARK .WORD 0 ;SEARCH FOR 0 FINDS END OF BLOCK MOV R1,R3 ;R3 POINTS TO END MARK 12$: MOV (R5)+,(R2)+ ;SQUEEZE THE ENTRY CMP R5,R3 BLOS 12$ MOV (SP)+,R1 ;RESTORE R1 BR 5$ 7$: TST E.LENG(R1) ;IS IT LENGTH 0? BNE 8$ ;NO. GET NEXT ENTRY MOV R1,R2 ;SEE IF PREVIOUS IS PERMANENT MOV R1,R3 SUB R4,R3 CMP R3,.USRBO ;DOING FIRST ENTRY IN DIRECT? BLO 8$ ;YES. GET NEXT ENTRY BIT #PERM,(R3) ;PERMANENT ENTRY? BNE 6$ ;YES, SQUEEZE IT OUT 8$: ADD R4,R1 ;ADVANCE TO NEXT ENTRY BR 5$ CNSLOV: MOV R1,(PC)+ ;SAVE POSITION OF END OF DIRECT DREND: 0 MOV (SP)+,R1 MOV (SP)+,R3 MOV (SP)+,R4 RTS PC .SBTTL DEVICE NAME SEARCH SR. ; THIS ROUTINE LOOKS UP A DEVICE NAME IN THE SYSTEM TABLES. ; IF THE DEVICE NAME IS ASSIGNED, THE ASSOCIATED PERM NAME IS USED. ; CALLING SEQUENCE: ; R0 -> DEVICE NAME BLOCK ; JSR R4,LK4DEV ; ERROR RETURN ; NORMAL RETURN ; RETURNS: ; R0 -> FILENAME IN BLOCK ; R1 = UNIT # ; R2 -> $STAT WORD ; R3 = DEVICE INDEX # ; R5 -> $ENTRY WORD ; COND.CODES SET FROM $ENTRY WORD LK4DEV: MOV (R0)+,R5 ;GET NAME IN R5, ADVANCE R0 BEQ 7$ ;NULL NAME GIVES ERROR RETURN MOV .$UNAM,R1 ;POINT TO LIST OF USER NAMES MOV #$SLOT+3,R3 ;COUNTER IN R3 1$: DEC R3 ;DONE USER NAME TABLE ? BEQ 2$ ;YES CMP R5,(R1)+ ;MATCH THIS ENTRY ? BNE 1$ ;NO, KEEP TRYING MOV $UNAM1-$UNAM2-2(R1),R5 ;GET ASSOCIATED PERM NAME 2$: MOV .$PNAM, R2 ;POINT TO PERM NAME TABLE CMP -(R2),-(R2) ;2 WORDS BEFORE TABLE MOV #-2,R3 ;CLEAR SLOT COUNTER 3$: MOV R5,R1 ;GET SEARCH OBJECT SUB (R2)+,R1 ;TRY THIS ENTRY BLO 4$ ;NO, ENTRY TOO HIGH BEQ 5$ ;EXACT MATCH SUB (PC)+,R1 ;TRY RANGE OF 0-7 UNIT .RAD50 / 0/ BLO 4$ ;NOT IN RANGE CMP R1,#7 BLOS 5$ ;GOT IT 4$: INC R3 ;INCREMENT SLOT # CMP R3,#$SLOT ;TOO MANY ? BLT 3$ ;NOT YET RTS R4 ;NOT FOUND. TAKE ERROR RETURN 5$: ASL R3 ;DOUBLE DEVICE INDEX BPL 55$ ;POSITIVE MEANS NOT DK OR SY MOV @.SYINDX,R3 ;GET INDEX OF SYSTEM DEVICE 55$: MOV .$ENTR,R5 ;POINT TO ENTRY POINT TABLE ADD R3,R5 ;INDEX TO PROPER ENTRY MOV R5,R2 ;COPY THAT POINTER ADD #$STAT-$ENTRY,R2 ;AND POINT R2 TO STATUS ENTRY TST (R4)+ ;TAKE THE SUCCESS RETURN TST (R5) ;SET COND CODE ON WHETHER HANDLER IS IN 7$: RTS R4 ;RETURN .SBTTL CLOSE PROCESSOR .ENABL LSB KLOSE: ASR R4 ;MAKE INTO A REAL CHANNEL MOV R4,CHNLRG MOV (R3),R5 ;SEE IF THIS IS SPECIAL BIC #177701,R5 ADD .$STAT,R5 BIT #SPECL$,(R5) BNE 10$ ;DO SPECIAL CLOSE CLR 2(R3) ;CLEAR ST BLOCK FOR READ/WRITE JSR R5,BLKCHK ;GET A DIRECTORY BLOCK IN CORE. BR 2$ ;AND ENTER LOOP 1$: JSR R5,NXBLK ;GET NEXT DIR BLOCK BR CLSOUT ;CANNOT FIND THAT TENTATIVE 2$: JSR R5,ENTRY ;FIND AN ENTRY 'TENTATIVE' TENT BR 1$ ;NOT IN THIS BLOCK .IF NE BF CMPB E.JNUM(R1),@.JOBNUM ;DOES TENTATIVE BELONG TO US? BNE 3$ ;NO .ENDC CMPB E.CHAN(R1),CHNLRG ;TENTATIVE ON THIS CHANNEL? BEQ CLOCOM ;YES. PROCESS IT 3$: JSR PC,INCR1 ;R1 TO NEXT ENTRY BR 2$ CLOCOM: ADDR FNAME,R0 ;PUT FILE NAME IN PERMANENT PLACE MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV @R1,@R0 ;MOVE EXTENSION CMP -(R0),-(R0) ;POINT R0 TO NAME SUB #6,R1 ;R1 TO STATUS ENTRY MOV R1,-(SP) MOV (R3),-(SP) ;SAVE FOR RE-READ OF THIS FILE BIC #DBLK$N,(SP) ;ISOLATE SEGMENT NUM. BIC #DBLK$M,(R3) ;START SEARCH AT BLOCK 1 ADD #DBLOK$,(R3) JSR R5,DLEET ;FIND OLD (PERMANENT) COPY BR 4$ ;NONE TO DELETE MOV #EMPTY,(R1) ;DELETE THE ONE WE FOUND MOV (R3),R1 ;SEE IF WE'RE IN SAME SEGMENT BIC #DBLK$N,R1 ;ISOLATE SEGMENT BITS CMP R1,(SP) BEQ 4$ ;YES. DON'T REWRITE SEGMENT INC @.DFLG ;NO. HOLD OFF ^C JSR PC,CLOSUP ;CONSOLIDATE AND REWRITE SEGMENT 4$: BIC #DBLK$M,(R3) ;PUT RIGHT SEG. BIS (SP)+,(R3) ;BACK INTO CSW WORD JSR R5,BLKCHK ;GET CORRECT BLOCK INTO CORE MOV (SP)+,R1 ;POINT TO ENTRY MOV #PERM,(R1) ;MAKE IT PERMANENT BIT #RENAM$,(R3) ;RENAME? BNE 5$ ;YES. LEAVE LENGTHS ALONE ADD #E.LENG,R1 ;OFFSET R1 TO LENGTH WORD MOV @R1,R2 ;NO, GET ALLOCATED LENGTH MOV C.USED(R3),@R1 ;CHANGE FILE ENTRY TO AMOUNT USED SUB @R1,R2 ;R2 NOW HAS UNUSED PORTION JSR PC,INCR1 ;POINT TO TRAILING EMPTY ADD R2,@R1 ;RECLAIM UNUSED SPACE CLSQSH: JSR PC,CLOSUP ;CONSOLIDATE AND REWRITE CLR @.DFLG ;ALLOW ^C CLSOUT: JMP DELOUT INCR2: MOV PC,-(SP) ;TWICE AROUND THE LOOP INCR1: ADD USRBUF+6,R1 ADD #16,R1 RTS PC ; THIS ROUTINE CONSOLIDATES A DIRECTORY SEGMENT AND REWRITES IT. CLOSUP: MOV R0,-(SP) ;SAVE FNAME POINTR MOV .USRBO,R1 ;BOTTOM OF SEGMENT BUFFER JSR PC,CONSOL ;CONSOLIDATE THE SEGMENT JSR R5,SEGRW2 ;RE WRITE THE SEGMENT 11*400 MOV (SP)+,R0 RTS PC 5$: TST (R1)+ MOV (R0)+,(R1)+ ;RE-INSERT RENAMED FILENAME MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ BR CLSQSH ;CLEAN UP AND GET OUT 10$: JSR R4,SPESHL ;DO SPECIAL DEVICE STUFF .BYTE 377,CLOS.. BR CLSOUT .DSABL LSB .SBTTL DLEET - LOCATE PERM FILE IN DIRECTORY ;DLEET-- ; DLEET IS USED TO LOCATE A PERMANENT FILE OF A GIVEN NAME ; CALLING SEQUENCE: ; R0 -> FILE NAME.EXT TO BE FOUND ; JSR R5,DLEET ; ERROR RETURN - NO SUCH FILE ; NORMAL RETURN ; RETURNS: ; R1 -> DIRECTORY ENTRY FOR FILE (STATUS WORD) ; DESTROYS: R2 DLEET: MOV R0,-(SP) ;SAVE FILE POINTER JSR R5,BLKCHK 10$: MOV (SP),R0 ;RESTORE POINTER JSR R5,ENTRY ;GET A PERM ENTRY PERM BR 4$ ;NOPE. SEE IF MORE TST (R1)+ ;POINT TO NAME MOV R1,R2 ADD #6,R2 ;R2 -> END OF NAME 1$: CMP (R0)+,(R1)+ BNE 3$ ;MISMATCH. CMP R1,R2 ;DONE? BNE 1$ SUB #10,R1 ;RESET R1 TO STATUS WORD. TST (R5)+ 2$: MOV (SP)+,R0 RTS R5 3$: MOV R2,R1 ;GET TO NEXT ENTRY ADD (R1)+,SBLK ;COMPUTE START BLOCK FOR LOOKUP CMP (R1)+,(R1)+ ADD USRBUF+6,R1 BR 10$ 4$: JSR R5,NXBLK BR 2$ ;NO MORE AT ALL! BR 10$ ;START A NEW SEGMENT .IF EQ BF .ENABL LSB .SBTTL RESET, RMON PTRS. RSTSR: BNE 3$ ;R0 NOT 0 MEANS SOFT RESET 1$: TST @.TTOBU ;WAIT FOR RING BUFF TO EMPTY BNE 1$ JSR PC,@.ZAP ;STOP ALL I/O ;DV15 3$: MOV #15.*5,R1 ;RESET TO NORMAL CHANNELS ;DV15 BIT #OVLY$,@#JSW ;OVERLAYS THERE? BNE 4$ ADD #5,R1 ;NO. CLEAR ALL 16 CHANNELS. 4$: MOV .$CSW,R2 ;RESET TO NORMAL CSW AREA MOV R2,@.I.CSW 5$: CLR (R2)+ DEC R1 BNE 5$ CLRHND: MOV .$ENTR,R2 ;NOW ZAP NON RESIDENT HANDLERS MOV #$SLOT,R1 6$: CMP (R2),@.SYSLO ;IS THIS LOADED OR SY:? BLO 7$ ;NO. ZERO IT'S $ENTRY SLOT CLR @(R2)+ ;YES. CLEAR BUSY FLAG BR 8$ 7$: CLR (R2)+ 8$: DEC R1 BNE 6$ QRESET: MOV .QSIZE,R1 ;ADD. OF QSIZE TO R1 CMP (R1)+,(R1) ;IS IO QUIESCENT? BLO QRESET ;NO. WAIT A WHILE MOV #1,-(R1) ;SIZE IS ONE ELEMENT MOV (R1)+,(R1)+ ;ALSO ONE ELEMENT AVAILABLE. MOV R1,(R1) ;POINT AVAIL TO THE Q ADD #2,(R1) MOV @.TTKS,-(SP) ;SET BIT ON FOR OUTPUT BIS #IENABL,@(SP)+ RTS PC .DSABL LSB .ENDC .SBTTL USR TABLES ; THIS IS A LIST OF POINTERS TO VARIOUS LOCATIONS IN THE RESIDENT. ; THE USR SETS UP THIS TABLE EACH TIME IT IS REREAD ; FROM THE DEVICE. THE LOCATIONS GET FILLED WITH THE ABSOLUTE ; ADDRESSES THEY REPRESENT. RELIST: .USRLO: .WORD USRLOC-$RMON ;USRLOC .KMLOC: .WORD KMLOC-$RMON ;KMLOC .$USRL: .WORD $USRLC-$RMON ;$USRLC .$KMLO: .WORD $KMLOC-$RMON ;$KMLOC .SYSLO: .WORD SYSLOW-$RMON ;SYSLOW .USRBU: .WORD USRBUF-$RMON ;START OF DIR BUFFER .USRBO: .WORD USRBUF+12-$RMON ;START OF DIR BUFFER+12 .USRTO: .WORD USRBUF+2000-$RMON ;END OF BUFFER .MONOU: .WORD MONOUT-$RMON ;MONOUT .$CSW: .WORD $CSW-$RMON ;$CSW .$UNAM: .WORD $UNAM2-$RMON ;$UNAM2 .$ENTR: .WORD $ENTRY-$RMON ;$ENTRY .SYINDX:.WORD SYINDX-$RMON .BLKEY: .WORD BLKEY-$RMON ;BLKEY .CHKEY: .WORD CHKEY-$RMON ;CHKEY .$DATE: .WORD $DATE-$RMON ;$DATE .DFLG: .WORD DFLG-$RMON ;ABORT HOLDOFF FLAG .$SYS: .WORD $SYS-$RMON ;MONITOR IO ENTRY POINT .$SWPB: .WORD $SWPBL-$RMON ;$SWPBL .$STAT: .WORD $STAT-$RMON .$PNAM: .WORD $PNAME-$RMON .SPUSR: .WORD SPUSR-$RMON .CORPT: .WORD CORPTR-$RMON ;POINTER TO FREE CORE LIST .$INTEN:.WORD $INTEN-$RMON .MAXBL: .WORD MAXBLK-$RMON ;MAXIMUM SIZE FOR ENTER .EXTFL: .WORD EXTFLG-$RMON ;CTRL/C INHIBIT ;DV6 .IF EQ BF .TTOBU: .WORD TTOBUF+2-$RMON ;OUTPUT RING BUFFER COUNT .I.CSW: .WORD I.CSW-$RMON ;POINTER TO CHANNEL POINTER .ZAP: .WORD ZAP-$RMON ;I/O HARD RESET ROUTINE ;DV15 .I.CNU: .WORD I.CNUM-$RMON ;MAXIMUM CHANNEL NUMBER .RECUR: .WORD RECURS-$RMON ;RECURS .QSIZE: .WORD QSIZE-$RMON ;ADDRESS OF Q SIZE WORD .TTKS: .WORD TTKS-$RMON .IFF .$OWNE: .WORD $OWNER-$RMON ;OWNERSHIP TABLE FOR DEVICES .CNTXT: .WORD CNTXT-$RMON ;CURRENT CONTEXT .$IMPUR:.WORD $IMPUR-$RMON ;TABLE OF IMPURE POINTERS .JOBNUM:.WORD JOBNUM-$RMON ;CURRENT JOB NUMBER .CSIER: .WORD CSIERR-$RMON ;MONITOR ENTRY POINT FOR CSI ERRORS .ENDC ENDLST: PHLST: .WORD 0 ;LIST USED FOR FETCH. THE FIRST FNAME: BSS 4 ;WORD IS ALWAYS 0. FNAME IS USED ;BY THE RENAME DIRECTIVE. ; THE FOLLOWING TABLES ARE FILLED BY THE HANDLR MACRO CALLS IN RMON ; $HSIZE IS A TABLE WHOSE ENTRIES ARE THE SIZES OF EACH DEVICE ; HANDLER IN BYTES. $HSIZE: BSS $SLOT ; $DVSIZ IS A TABLE WHOSE ENTRIES ARE THE DIRECTORY SIZES FOR ; EACH FILE STRUCTURED DEVICE IN THE SYSTEM $DVSIZ: BSS $SLOT .SBTTL QUEUE EXTEND EMT .ENABL LSB QSET: MOV R0,R5 ;NUMBER OF ADDITIONAL ENTRIES BLE QSOUT ;JUST FOOLING AROUND! MOV ARGM1,R1 ;ADDRESS OF FIRST NEW ENTRY MOV R1,R4 ;WE'LL LINK AVAIL TO THIS SOON .IF NE BF MOV @.CNTXT,R2 ;R2 -> CURRENT CONTEXT TST (R2)+ ;R2 -> AVAIL QUEUE HEAD .IFF MOV .QSIZE,R2 ;POINT R2 AT AVAIL CMP (R2)+,(R2)+ .ENDC ;WHERE AVAIL POINTS NOW, ;WE'LL POINT NEW LIST TO SAME PLACE 1$: MOV R1,R3 ADD #16,R1 MOV R1,(R3) DEC R0 BNE 1$ ;KEEP LINKING MOV #PR7,-(SP) ;DV15 JSR PC,2$ ;CAN'T ABIDE ANY INTERRUPTS HERE ;DV15 MOV (R2),(R3) ;POINT OUR LIST TO WHERE AVAIL GOES MOV R4,(R2) ;AND LINK AVAIL TO OUR LIST .IF EQ BF ADD R5,-(R2) ;INCREASE FREE AND TOTAL COUNT ADD R5,-(R2) .ENDC CLR -(SP) ;DV15 JSR PC,2$ ;BACK TO LEVEL 0 ;DV15 MOV R1,(SP) ;R0 POINTS TO NEXT FREE CORE QSOUT: JMP COMXIT 2$: RTI ;DV15 .DSABL LSB .SBTTL COMMAND STRING INTERPRETER CSI: MOV #13,R1 ;COUNT OF THINGS TO SAVE ADDR STKSAV,R2 ;SETUP POINTER TO STACK SAVE AREA 1$: MOV (SP)+,-(R2) ;SAVE THE STACK STUFF (BACKWARDS) DEC R1 ;ANY MORE ?? BNE 1$ ;YES ;NOTE - R2 -> CSI BUFFER NOW! MOV SP,STKLVL ;SAVE SP FOR POSSIBLE RESTART MOV R4,EMTMOD ;SAVE MODE FLAG. SPECIAL MODE? RESTRT: BNE 2$ ;DON'T CLOSE CHANNELS IN SPECIAL MODE MOV #6*400+10,R5 ;CLOSE CHANNELS 10-0 1$: MOV R5,R0 ;ISSUE CLOSE EMT 374 DECB R5 ;CHANNEL 0? BPL 1$ ;DO 'EM ALL 2$: MOV R2,R5 ;COPY BUFFER POINTER FOR LATER MOV STRING,R3 ;GET STRING ADDRESS .IF EQ BF BNE 3$ ;DON'T PRINT * IF FROM CORE MOV .$ENTR,R0 ;R0 -> $ENTRY TABLE MOV BA.NUM(R0),R0 ;R0 -> BA.SYS ENTRY BEQ 20$ ;BR IF NOT IN MEMORY TST 6(R0) ;IS BATCH RUNNING? BNE 3$ ;YES, SKIP PROMPT CHAR 20$: .TTYOUT #'* ;PROMPT USER WITH A * .ENDC 3$: MOV #74.,R1 ;SETUP COUNTER (72 CHARS) CLR R4 ;CLEAR OUTPUT FILES SWITCH 4$: TST R3 ;WHERE DOES INPUT COME FROM ? BEQ 8$ ;THE TELETYPE MOVB (R3)+,R0 ;GET CHAR FROM THE STRING BIC #177600,R0 ;ONLY USE SEVEN BITS BEQ 9$ ;TERMINATE ON ZERO CHAR 5$: CMP #'=,R0 ;CHECK FOR EQUALS BEQ 6$ ;YES CMP #'<,R0 ;< SAME AS = BNE 7$ ;NO INC R0 ;REPLACE < WITH = 6$: COM R4 ;PREVIOUS = ??? BNE 7$ ;FIRST TIME IS OK CLR R1 ;SET TO GIVE ERROR LATER 7$: DEC R1 ;COUNT DOWN CHARACTERS BLE 4$ ;IGNORE IF NO ROOM MOVB R0,-(R2) ;PUT CHAR INTO BUFFER (BACKWARDS) BR 4$ ;GO GET NEXT CHAR 8$: .TTYIN ;GET CHAR FROM SYS TTY HANDLER CMP #CR,R0 ;IS IT A CARRIAGE RETURN ? BEQ 8$ ;YES, IGNORE IT CMP #LF,R0 ;IS IT LF? BNE 5$ ;NO, PROCEED 9$: TST R1 ;OVERFLOW ? BLE SYNERR .SBTTL GET FILE DESCRIPTORS AND OPEN FILES CLRB -(R2) ;REPLACE CR WITH ZERO BYTE ;NOTE R5 -> CSIBUF = HANSPC ! MOV @R5,R2 ;IF SPECIAL MODE GET ADDR OF OUTPUT AREA MOV R2,REG0 ;IF GENERAL, GET HANDLER SPACE ADDRESS TST EMTMOD ;IS IT SPECIAL MODE ?? BEQ 11$ ;NO, DON'T CLEAR OUTPUT AREA MOV #39.,R1 ;COUNT MOV R2,R3 ;COPY POINTER 10$: CLR (R3)+ ;CLEAR DEC R1 ;MORE ? BNE 10$ ;YES 11$: CLR R3 ;FILE COUNTER CLR SWTCNT ;SWITCH COUNTER TST R4 ;INPUT LIST ONLY ?? BNE GETDE ;NO, START WITH OUTPUT FILES STRTIN: MOV #3,R3 ;BEGIN INPUT LIST MOV HANSPC,R2 ;SET FILE NUM = 3 AND R2 TO ADD #36,R2 ;START OF OUTPUT SPACE (SPECIAL MODE) CLR R4 ;SET SWITCH TO INPUT GETDE: MOV DEFEXT,R1 ;GET ADDRESS OF DEFAULT EXTENSIONS MOV #15270,DEV1 ;USE DEFAULT DEVICE "DK" NXTFIL: CMP R3,#10 ;HOW MANY FILES? BGT SYNERR ;TOO MANY. TST R4 ;OUTPUT OR INPUT FILES ?? BEQ 6$ ;INPUT TST (R1)+ ;OUTPUT FILES, GO TO NEXT EXTENSION 6$: TST (PC)+ ;GENERAL OR SPECIAL MODE ? EMTMOD: 0 BNE SPECAL ;SPECIAL, NO FETCH, ENTER, OR LOOKUP ADDR FILDES,R2 ;SETUP POINTER TO FILE DESCRIPTOR JSR PC,GETFD ;GET THE FILE DESCRIPTOR TST (R0) ;WAS IT A NULL FILE ? BEQ SWITCH ;YES MOV R0,-(SP) ;SAVE R0 MOV REG0,-(SP) ;HANDLER SPACE ADDRESS EMT 343 ;FETCH THE HANDLER BCS HANERR ;ERROR ON FETCH MOV R0,REG0 ;NEW HANDLER SPACE ADDR MOV R0,HANSPC ;CAN'T GO LOWER NOW! MOV (SP)+,R0 ;POINTER TO F.D. FOR LOOKUP OR ENTER TST R4 ;INPUT OR OUTPUT BEQ INFILE ;INPUT, NO OUTPUT CHECKS JSR PC,OUSTUF ;GO HANDLE SOME OUTPUT FILE CHECKS MOV (R2),-(SP) ;PUSH SIZE ONTO STACK MOV #EMT+40,-(SP) ;BUILD THE EMT ADD R3,@SP ;BAD TECHNIQUE MOV (SP)+,@PC ; BADDDDD HALT BCC SWITCH ;GO LOOK FOR SWITCHES CSIERR ,3 SPECAL: JSR PC,GETFD ;GET FILE DESCRIPTOR TST R4 ;INPUT OR OUTPUT BEQ SWITCH ;INPUT, GET SWITCHES TST (R0) ;NULL OUTPUT FILE? BEQ 1$ ;YES. JSR PC,OUSTUF ;HANDLE SOME OUTPUT FILE CHECKS 1$: TST (R2)+ ;BUMP POINTER BR SWITCH ;AND GO LOOK FOR SWITCHES INFILE: MOV #EMT+20,-(SP) ;MAKE THE EMT ADD R3,@SP ;PUT IN THE FILE NUMBER MOV (SP)+,@PC ;BAD TECHNIQUE HALT ;LOOKUP THE FILE BCC SWITCH ;FOUND IT. GO DO SWITCHES CSIERR ,4 ;GIVE ERROR .SBTTL GET SWITCHES ; THIS IS HERE SO EVERYBODY CAN REACH SYNERR NOSWIT: INC R3 ;INCREMENT FILE NUMBER CMPB @R5,#', ;LOOK FOR A COMMA BEQ NXTFIL ;YES, GET NEXT FILE CMPB @R5,#'= ;LOOK FOR EQUALS BEQ STRTIN ;START INPUT LIST MOV (PC)+,-(SP) ;PREPARE TO FIND A NULL BYTE SWTCNT: 0 TSTB (R5) ;IS IT A CR ?? BEQ RETURN ;YES. GO HOME SYNERR: CSIERR ,0 HANERR: CSIERR ,1 .ENABL LSB 5$: TST R0 ;NO ! OR :. IS THERE NO VALUE AT ALL? BMI SWITCH ;AN EARLIER VALUE MOV R0,-(SP) ;NO VALUE. JUST STUFF IT INC SWTCNT ;INCREMENT COUNT OF SWITCHES SWITCH: CMPB (R5),#'/ ;CHECK FOR / START OF SWITCH BNE NOSWIT ;NO SWITCH IF NO / MOVB -(R5),R0 ;GET SWITCH CHAR AND SAVE IT BEQ SYNERR ;ERROR IF CR SWAB R0 ;SWAP SWITCH CHAR TO ODD BYTE ADD R3,R0 ;ADD IN FILE NUMBER SWAB R0 ;SWAP IT BACK DEC R5 ;MOVE TO VALUE DELIMITER 10$: CMPB @R5,#'! ;DECIMAL SWITCH? SEC ;(SET CARRY FOR CALL) BEQ 1$ ;YES, GO GET IT CMPB @R5,#': ;IS THERE AN OCTAL VALUE (:XXXXX) BNE 5$ ;NO, THERE AIN'T CMPB #'A-1,-1(R5) ;CHECK FOR OCTAL OR RAD50 BLO 2$ ;ALPHA => RAD50 1$: JSR PC,CVTNUM ;CONVERT OCTAL OR DECIMAL NUMBER BR 3$ 2$: MOV R2,-(SP) ;SAVE R2 MOV SP,R2 ;RAD50 PACK RETURNS IN @R2 MOV @SP,-(SP) ;SAVE R2 FOR REAL, NOW MOV R0,-(SP) ;AND R0 JSR PC,GETNM1 ;PACK IT UP MOV (SP)+,R0 ;RESTORE R0 MOV (SP)+,R2 3$: BIS #100000,R0 ;SET VALUE FLAG MOV R0,-(SP) ;PUT STUFF ONTO STACK INC SWTCNT ;INCREMENT COUNT OF SWITCHES BR 10$ ;LOOK FOR ANOTHER SWITCH .DSABL LSB .SBTTL RETURN AND ERROR PROCESSING CSIER1: BIS #1,SAVSTK ;SET CARRY IN PS RETURN: MOV #10,R2 ;COUNT FOR STACK RESTORATION ADDR SAVSTK,R1 ;SETUP POINTER 1$: MOV (R1)+,-(SP) ;RESTORE STACK ELEMENT DEC R2 ;MORE ?? BNE 1$ ;YES ;NOTE R2=0 => NO ARGS TO POP .IF NE BF MOV @.CNTXT,-(SP) ;TURN OFF BIT THAT SUPPRESSES ADDR CHK BIC #CSIRN$,@(SP)+ ; IN THE JOB'S JSTAT .ENDC JMP @.MONOU ;RETURN TO RESIDENT. ; THIS IS THE CSI ERROR ROUTINE MSG: MOV (PC)+,SP ;RESTORE STACK (ELIMINATE JUNK) STKLVL: 0 MOVB (R0)+,@#ERRBYT TST STRING ;WHERE DID INPUT COME FROM ?? BNE CSIER1 ;FROM INSIDE, NO RESTART .PRINT ;OUTPUT STRING .IF EQ BF ADDR CSIBUF,R2 ;POINT TO BUFFER AGAIN TST EMTMOD ;SET COND. CODE FOR MADE JMP RESTRT ;TRY AGAIN (GET NEW LINE FROM TTY) .IFF MOV #13,R1 ;FIX UP STACK FOR A RETRY ADDR HANSPC,R2 ;POINT TO STUFF TO RESTORE 2$: MOV (R2)+,-(SP) DEC R1 BNE 2$ MOV EMTMOD,R4 ;RESTORE EMT MODE JMP @.CSIER ;GET RID OF USR, GET LINE, TRY AGAIN .ENDC .SBTTL OUSTUF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; OUSTUF VERIFIES THAT A FILE STRUCTURED DEVICE IS NOT ; BEING OPENED FOR OUTPUT AS NON-STRUCTURED (SYNTAX ERROR). ; IT THEN SCANS OFF A CONSTRUCTION OF THE FORM [DECIMAL NUMBER] ; WHICH SPECIFIES THE SIZE OF THE OUTPUT FILE IN BLOCKS. ; CALLING SEQUENCE: ; R0 -> FILE DESCRIPTOR IN RAD50 ; R2 -> WORD TO CONTAIN OUTPUT FILE SIZE ; R5 -> INPUT STRING ; RETURNS: ; R5 -> CHARACTER AFTER ] IF GIVEN, ELSE AFTER FILENAME ; @R2 = FILE SIZE, 0 IF NOT GIVEN ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB OUSTUF: MOV R0,-(SP) ;SAVE F.D. POINTER TST 2(R0) ;IS FILE NAME GIVEN ?? BNE 1$ ;YES ADDR DEVSTS,SP ;POINTER TO INFORMATION BLOCK EMT 342 ;GET DEVICE INFORMATION BCS HANERR ;ILLEGAL DEVICE TST @R0 ;IS IT A DIRECTORY DEVICE ?? BMI HANERR ;YES, THIS WILL DESTROY ITS DIRECTORY 1$: CLR @R2 ;ZERO DESTINATION OF SIZE CMPB @R5,#'[ ;IS IT A [ ?? BNE 3$ ;NO, NO SIZE SPECIFIED JSR PC,DECNUM ;GET THE SIZE IN BLOCKS CMPB @R5,#'] ;CHECK FOR ] BNE SYNERR ;ERROR IF NOT PRESENT DEC R5 ;MOV R5 TO NEXT CHAR 2$: MOV (SP)+,@R2 ;PUT SIZE WHERE IT BELONGS 3$: MOV (SP)+,R0 ;RESTORE F.D. POINTER RTS PC .SBTTL GET FILE DESCRIPTOR SUBROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; GETFD GETS A FILE DESCRIPTOR FROM THE INPUT STRING AND ; CREATES 4 WORDS OF RADIX 50 INFORMATION OF THE FORM: ; .RAD50 "DEV" ; .RAD50 "FILNAM" ; .RAD50 "EXT" ; CALLING SEQUENCE: ; R1 -> DEFAULT EXTENSION ; R2 -> OUTPUT AREA (4 WORDS) ; R5 -> INPUT STRING ; RETURNS: ; R0 -> ORIGINAL OUTPUT AREA (R2 INPUT) ; R2 -> WORD AFTER THE EXTENSION WORD ; R5 -> CHARACTER THAT DELIMITED THE NAME ; DESTROYS: R0 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GETFD: MOV R2,-(SP) ;SAVE R2 (LATER RESTORED INTO R0) JSR PC,GETNAM ;LOOK FOR DEVICE NAME BEQ 6$ ;IT WAS A NULL FILE CMPB @R5,#': ;DEVICE NAME FOLLOWED BY COLON BNE 5$ ;IF NO COLON, NOT A DEVICE NAME MOV (R2)+,DEV1 ;SAVE DEVICE NAME AS NEW DEFAULT JSR PC,GETNAM ;NOW LOOK FOR FILE NAME 4$: CMP (R2)+,(R2)+ ;SKIP PAST FILE NAME CMPB @R5,#'. ;IF PERIOD, EXTENSION FOLLOWS BNE 7$ ;NO . MEANS NO EXTENSION MOV 2(R2),-(SP) ;PRESERVE EXTRA WORD JSR PC,GETNAM ;GET EXTENSION TST (R2)+ ;SKIP PAST EXTENSION BR 2$ ;GO RESTORE SAVED WORD AND RETURN 5$: MOV @R2,-(SP) ;SAVE FIRST WORD OF FILE NAME MOV (PC)+,(R2)+ ;USE DEFAULT DEVICE DEV1: .RAD50 "DK" MOV (R2)+,@R2 ;COPY SECOND WORD OF FILE NAME MOV (SP)+,-(R2) ;PUT IN PREVIOUSLY SAVED FIRST WORD BR 4$ ;GO PROCESS EXTENSION 6$: ADD #6,R2 ;SKIP DEVICE AND FILE NAMES 7$: MOV @R1,(R2)+ ;PUT IN DEFAULT EXTENSION BR 3$ ;GO RESTORE R0 AND EXIT .DSABL LSB .SBTTL GET NAME SUBROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; GETNAM CONVERTS A SEQUENCE OF 0 TO 6 ALPHANUMERICS TO RAD50. ; A 2-WORD RESULT IS STORED AT THE PLACE POINTED TO BY R2. ; THE RESULT IS PADDED WITH 0'S (RAD50 BLANK) IF < 6 CHARACTERS. ; CALLING SEQUENCE: ; R2 -> 2-WORD RESULT AREA ; R5 -> SOURCE STRING (BACKWARDS) ; JSR PC,GETNAM ; RETURNS: ; R2 UNCHANGED ; R5 -> CHARACTER THAT DELIMITED THE NAME ; CONDITION CODE 'ZERO' IF NAME IS ALL ZEROS ; DESTROYS: R0 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB GETNM1: MOV R4,-(SP) ;ENTER HERE FOR 1-WORD CONVERSION MOV #20000,-(SP) BR 2$ GETNAM: MOV R4,-(SP) ;SAVE R4 MOV #22000,-(SP) ;MASK KEEPS TRACK OF WHERE WE ARE TST EMTMOD ;ARE WE IN SPECIAL MODE? BEQ 2$ ;NO, GENERAL ALLOWS NO * CMPB -(R5),#'* ;IS IS A STAR? BNE 1$ ;NO MOV #132500,(R2)+ ;PUT IN CODE FOR RAD 50 * CLR (R2)+ ;ZERO TOP OF NAME BR 4$ ;LEAVE 1$: INC R5 ;FIX R5 2$: CLR R4 ;CLEAR ACCUMULATOR 3$: MOVB -1(R5),R0 ;GET NEXT BYTE SUB #'9+1,R0 ;CHECK FOR DIGIT RANGE ADD #'9+1-'0,R0 BCC 12$ ;NO DIGIT ADD #36,R0 ;INCREASE R0 TO RAD50 DIGIT BR 13$ ;GO ADVANCE R5 11$: SUB #20,R0 ;TRY LOWER CASE 12$: SUB #20,R0 ;WE SUBTRACTED 60. NOW TRY FOR ALPHA BLE 14$ ;NO GOOD CMP R0,#'Z-100 ;IS IT ALPHA? BHI 11$ ;NO. GO TRY LOWER CASE 13$: CMPB -(R5),(PC)+ ;DECREMENT R5, SKIP NEXT INSTRUCTION 14$: CLR R0 ;DO NOT CHANGE R5, FILL WITH 0'S ASL R4 ;ASSEMBLE RAD50 ASL R4 ASL R4 ADD R4,R0 ASL R4 ASL R4 ADD R0,R4 ASL @SP ;ARE WE DONE YET? BCC 3$ ;NOT DONE THIS WORD MOV R4,(R2)+ ;DONE A WORD. PUT IT IN TST @SP ;DONE ALL WORDS? BNE 2$ ;NO, CLEAR ACCUMULATOR AND LOOP 4$: CMP -(R2),(SP)+ ;FIX R2, PRUNE STACK DEC R5 ;MAKE R5 -> DELIMITER MOV (SP)+,R4 ;RESTORE R4 TST -(R2) ;FIX R2, SET CONDITION CODES RTS PC .SBTTL OCTAL/DECIMAL CONVERSION ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; NUM GETS AN OCTAL/DECIMAL NUMBER FROM THE INPUT STRING ; AND RETURNS IT ON THE STACK. ; CALLING SEQUENCE: ; R5 -> INPUT STRING (BACKWARDS) ; JSR PC,OCTNUM/DECNUM/CVTNUM ; (IF CALLED AT CVTNUM, CARRY 0 => OCTAL, 1 => DECIMAL ; RETURNS: ; @SP IS CONVERTED NUMBER ; R5 -> DELIMITER ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB OCTNUM: TST (PC)+ ;CLEAR CARRY, SKIP THE SEC DECNUM: SEC ;INDICATE DECIMAL CVTNUM: MOV (SP),-(SP) ;SAVE RETURN & LEAVE ROOM FOR VALUE MOV R3,-(SP) ;SAVE REGISTERS MOV R4,-(SP) MOV #100004,-(SP) ;SET THE RADIX AND SET ASL TO GIVE CARRY ADC @SP CMPB -(R5),#'- ;IS IT A NEGATIVE NUMBER? BNE 1$ ;NO, GO BUMP R5 ADD #140000,@SP ;YES, DON'T BUMP R5 BUT LEAVE @SP<0 1$: ASL @SP ;DOUBLE RADIX ADC R5 ;FIX R5 IF NO - SIGN CLR R4 ;CLEAR ACCUMULATING REGISTER 2$: MOVB -(R5),R3 ;GET NEXT CHARACTER SUB #'0,R3 ;CHECK FOR A DIGIT CMPB R3,@SP BHIS 4$ ;NO,END OF NUMBER ASL R4 ;SHIFT ACCUMULATOR LEFT CMPB @SP,#12 ;IS IT OCTAL OR DECIMAL ?? BNE 3$ ADD R4,R3 ;DECIMAL, MULT OLD BY 10 (INSTEAD OF 8) 3$: ASL R4 ASL R4 ADD R3,R4 ;PUT IN NEW DIGIT BR 2$ ;GET NEXT DIGIT 4$: TST (SP)+ ;REMOVE RADIX BPL 5$ ;WAS IT MINUS? NEG R4 ;YEP, NEGATE IT 5$: MOV R4,6(SP) ;SAVE THE RESULT MOV (SP)+,R4 ;RESTORE REGS MOV (SP)+,R3 RTS PC .DSABL LSB .SBTTL LINE BUFFER AND STACK SAVE AREA .BLKB 74. ;CHARACTER BUFFER (CHARS GO BACKWARDS) KMCBUF: ;KMON COMMAND BUFFER .IF NE BF .BYTE 40,0 ;THIS BLANK IS USED BY THE KMON .BLKB 74. ;F/B NEEDS A SEPARATE BUFFER .ENDC CSIBUF: ;LINE BUFFER ALSO USED BY KMON HANSPC: .WORD 0 ;HANDLER SPACE ADDRESS DEFEXT: .WORD 0 ;DEFAULT EXTENSION BLOCK ADDRESS STRING: .WORD 0 ;INPUT STRING (0 MEANS INPUT FROM TTY) SAVSTK: .BLKW 7 ;STACK SAVE (PS,PC,R1,R2,R3,R4,R5,R0) REG0: .WORD 0 ;TOP OF HANDLER SPACE RETURNED HERE STKSAV: FILDES: .BLKW 5 ;FILE DESCRIPTOR (GENERAL MODE ONLY) DEVSTS: .BLKW 4 ;DEVICE INFORMATION BLOCK ; THE FOLLOWING ARE SIZE PARAMETERS FOR THE USR USRSZ = . - USRBUF + 777 / 1000 ;SIZE OF USR IN BLOCKS USRSIZE = USRSZ * 1000 ;SIZE OF USR IN BYTES USRLEN = USRSZ * 400 ;SIZE OF USR IN WORDS . = USRBUF + USRSIZE ; THIS ROUTINE MUST SIT AT THE TOP OF THE USR ; IT IS USED TO HELP MOVE THE KMON/USR DOWNWARD IN CORE . = . - 26. ;CAUTION ON THIS SIZE !!!!!!!! MOVEDN: MOV SP,R3 ;SAVE SP TO FIND IT IN LOOP CLR -(SP) ;AND MAKE US STOP AT STACK TOP 1$: MOV (R1)+,(R4)+ ;COPY A WORD BNE 1$ ;LOOP WHEN NON-0 CMP R1,PC ;ARE WE DONE (PAST OURSELVES)? BHI 2$ ;YES CMP R1,R3 ;DID WE GET THE STACK TOPPER ? BNE 1$ ;KEEP MOVING MOV R4,SP ;SWITCH TO NEW STACK (& POP!) BR 1$ ;AND CONTINUE 2$: ADD R0,@SP ;RELOCATE RETURN ADDRESS RTS PC ;BYE .WORD 0 ;THIS STOPS THE MOVE! .IF NE <. - MOVEDN> - 26. .ERROR SIZE OF MOVEDN CHANGED!!! .ENDC .CSECT SWAP ;NOW ALLOCATE ENOUGH SWAP BLOCKS . = . + KMSIZE + USRSIZ + 1000 ; THE EXTRA BLOCK IS BECAUSE WE SWAP TOO MUCH IF THE KMON ; IS NOT ON A BLOCK BOUNDARY SWAPSZ = KMONSZ + USRSZ + 1 .IIF DF NLUSR, .LIST .NLIST ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. .LIST .IIF DF NLRMON, .NLIST ;UPDATE LEVEL 09 .SBTTL MONITOR DATA BASE ; START OF RESIDENT MONITOR. .CSECT RT11 $RMON: JMP $INTEN $CSW: BSS 16.*5 ;CHANNEL STATUS TABLE SB17 = $CSW+<15.*5*2>+2 ;POINTS TO START BLOCK OF CHANNEL 17 HDERR$ = 1 ;BITS IN CSW WORD 0 INDX$M = 76 ;MASK FOR DEVICE INDEX RENAM$ = 100 DWRIT$ = 200 DBLOK$ = 400 DBLK$M = 17400 ;MASK FOR DIR. BLOCK # DBLK$N = 160377 ;COMPLEMETARY MASK EOF$ = 20000 ACTIV$ = 100000 C.SBLK = 2 ;OFFSETS INTO CHANNEL C.LENG = 4 C.USED = 6 C.DEVQ = 10 $SYSCH: .WORD 0,0 ;WD 1 USED AT $SYS .WORD 0 I.SPLS: I.SERR: .WORD 0 ;USED FOR HARD/SOFT ERRORS .WORD 0 BLKEY: 0 ;DIRECTORY BLOCK # IN CORE CHKEY: 0 ;DEVICE WHOSE DIRECTORY IS IN CORE $DATE: 0 ;DATE WORD DFLG: 0 ;DIRECTORY OP. IN PROGRESS FLAG $USRLC: USRBUF ;WHERE DIRECTORY BUFFER IS QCOMP: COMPLT ;HANDLERS GO HERE TO FINISH UP SPUSR: 0 ;SOFTWARE ERROR FLAG SYUNIT: 0 ;HOLDS UNIT WE BOOTED FROM SYSVER: .BYTE 2 ;VERSION NUMBER SYSUPD: .BYTE UPDATE ;EDIT NUMBER FOR VERSION CONFIG: .WORD 0 ;SYSTEM CONFIGURATION FLAGS SCROLL: .WORD 0 ;LINK TO GT40 SCROLLER CODE TTKS: 177560 ;CONSOLE IO ADDRESSES TTKB: 177562 TTPS: 177564 TTPB: 177566 MAXBLK: .WORD -1 ;MAXIMUM FILE SIZE ALLOCATED E16LST: LST16-$RMON ;PTR TO EMT 16 FOR BATCH $TIME: BSS 2 ;DOUBLE PRECISION TIMER SYNCH: .WORD SINK ;FOR COMPATIBILITY W/FB LOWMAP: ;MAP OF PROTECTED WORDS IN LOW CORE ; BYTES ARE READ FROM LEFT TO RIGHT. E.G., THE FOURTH BYTE PROTECTS ; THE RANGE 60-76, AND A VALUE OF 11110000 WOULD PROTECT 60-66. .RADIX 2 .BYTE 11111111,00111100,00001111,11110000 ;0-76 .BYTE 11000011,00000000,00000000,00000000 ;100-176 .BYTE 00111111,11000000,00110011,00110000 ;200-276 .BYTE 00000000,00000000,00000000,00000000 ;300-376 .BYTE 00000000,00000000,00000000,00000000 ;400-476 .RADIX 8. MAPOFF = LOWMAP- $RMON USRLOC: .WORD USRBUF ;WHERE USR IS AT ANY GIVEN MOMENT GTVECT: .WORD 320 ;WORD FOR GT40 ERRCNT: .WORD 0 ;ERROR COUNT RETURNED FROM CUSPS $MTPS: RTI ;DV15 $MFPS: BR GETPSW ;RETURN PS CONTENTS IN SP ;DV15 SYINDX: .WORD 0 ;SYSTEM DEVICE INDEX NUMBER SYINDO= SYINDX-$RMON SYSLOW: .WORD $RMON ;PSEUDO START OF MONITOR $UNAM1: BSS $SLOT ;ASSIGNED NAME TABLE - PERMANENT NAMES DKASSG= . - $RMON .RAD50 /DK0/ SYASSG = .-$RMON .RAD50 /SY0/ $UNAM2: BSS $SLOT ;ASSIGNED NAME TABLE - USER NAMES .RAD50 /DK / .RAD50 /SY / $PNAME: BSS $SLOT ;PERMANENT NAME TABLE $STAT: BSS $SLOT CORPTR: .WORD 0 ;FREE CORE POINTER CORPTR ;****UPDATE WITH BOOT***** FILST$ = 100000 RONLY$ = 40000 WONLY$ = 20000 SPECL$ = 10000 HNDLR$ = 4000 SPFUN$ = 2000 TTENTR: ;ENTRY POINT FOR TT:--ASSUMES 1 ST SLOT. $ENTRY: BSS $SLOT $PNAMO=$PNAME-$ENTRY $DVREC: BSS $SLOT CCB: BSS 10 ;RESIDENT CCB FOR KMON ;************************************************** ; THE FOLLOWING VALUES ARE FOR COMPATIBILITY WITH ; THE BF MONITOR. THEY ARE THE SINGLE USER ; EQUIVALENTS OF THE BF IMPURE AREA POINTERS. ;************************************************** I.CNUM: 16. ;INITIAL NUMBER OF CHANNELS DEFINED I.CSW: $CSW ;POINTER TO CSW AREA ;************************************************** .SBTTL DEVICE TABLES ;********************************************************************** ; ; THE FOLLOWING MACRO IS USED TO MAKE ENTRIES IN ALL ; THE DEVICE-RELATED TABLES, BOTH IN THE USR AND THE RMON. ; THE 4 MACRO ARGUMENTS ARE HANDLER NAME, # OF BLOCKS ON DEVICE, ; STATUS (FOR $STAT), AND ENTRY POINT (GLOBAL NAME). ; .MACRO DEVICE NAME,SIZ,STAT,ENTRY . = $HSIZE + HNUM .IF IDN NAME,DK .WORD SYSIZE .IFF .WORD NAME'SIZE .ENDC . = $DVSIZE + HNUM .WORD SIZ . = $PNAME + HNUM .RAD50 /NAME/ . = $STAT + HNUM .WORD STAT .IF NB ENTRY . = $ENTRY + HNUM .WORD ENTRY .ENDC HNUM = HNUM + 2 .ENDM DEVICE HNUM = 0 ;START OF WITH 0 DEVICE INDEX ... = . ;KEEP OUR PLACE ; NAME SIZE STATUS ENTRY ; ---- ---- ------ ----- TT.NUM = HNUM DEVICE TT 0 4 DEVICE DS 1024. 16+FILST$ DSSYS DEVICE RK 11300 0+FILST$ RKSYS DEVICE RF 2000 12+FILST$ RFSYS DEVICE PR 0 7+RONLY$ DEVICE PP 0 10+WONLY$ DEVICE MT 0 11+SPECL$+SPFUN$ DEVICE LP 0 3+WONLY$ DEVICE DT 1102 1+FILST$ DTSYS DEVICE CT 0 13+SPECL$+SPFUN$ DEVICE MM 0 20+SPECL$+SPFUN$ BA.NUM = HNUM DEVICE BA 0 4 DEVICE DP 40000. 21+FILST$ DPSYS DEVICE DX 494. 22+FILST$+SPFUN$ DXSYS .IIF NDF BANDW, .NLIST .IF DF BANDW DEVICE AM 200 15+FILST$ .ENDC .IIF NDF BANDW, .LIST . = ... ;BACK TO WHERE WE WERE .SBTTL DESCRIPTION OF MONITOR DATA BASE ;********************************************************************** ; CHANNEL STATUS TABLE---$CSW ; THIS TABLE CONTAINS 16 ENTRIES OF 5 WORDS EACH ; DESCRIBING THE I/O CHANNELS. THE FORMAT IS: ; ; OFFSET BIT(S) MEANING ; ------ ------ ----------------------------------------------- ; 0 0 1 => HARD ERROR OCCURED ON DEVICE ; 1-5 DEVICE INDEX IN TABLES ; 6 1 => RENAME OPERATION IN PROGRESS ; 7 1 => CLOSE REQUIRES DIRECTORY REWRITE ; 8-12 DIRECTORY BLOCK # OF FILE ; 13 1 => EOF FOUND ON CHANNEL ; 15 1 => CHANNEL ACTIVE ; 2 START BLOCK OF FILE ; 4 LENGTH OF FILE (HOLE) ALLOCATED ; 6 ACTUAL DATA LENGTH (HIGHEST BLK WRITTEN) ; 10 0-7 NUMBER OF REQUESTS PENDING ON THIS CHANNEL ; 8-15 PHYSICAL UNIT NUMBER ; ;********************************************************************** ; ; BLKEY AND CHKEY ARE USED TO INDICATE WHICH DIRECTORY IS IN CORE ; AND WHAT DEVICE THAT DIRECTORY IS ATTACHED TO. ; BLKEY IS THE NUMBER OF THE DIRECTORY SEGMENT NOW IN CORE ; SEGMENTS ARE NUMBERED 1-32. THEY ARE 2 PHYSICAL BLOCKS EACH. ; ; CHKEY DESCRIBES THE DEVICE TO WHICH THE DIRECTORY IS ATTACHED. ; THE EVEN BYTE CONTAINS THE DEVICE INDEX, IDENTIFYING THE DEVICE TYPE, ; AND THE ODD BYTE CONTAINS THE UNIT NUMBER OF THE DEVICE ; ;********************************************************************** ; ; USER NAME TABLES: $UNAM1 AND $UNAM2. ; THESE TABLES ARE USED TO HOLD THE DEVICE NAMES DEFINED VIA ; THE ASSIGN COMMAND. THE USER SPECIFIES 2 NAMES IN THE ASSIGN: ; .ASSIGN NAM1 NAM2 ; NAM1 IS THE SYSTEM PERMANENT NAME, AND NAM2 IS HIS SUPPLIED NAME. ; $UNAM2 CONTAINS THE USER'S NAME, AND AT THE CORRESPONDING ; LOCATION IN $UNAM1 IS THE SYSTEM NAME WHICH IS EQUATED TO IT. ; ;********************************************************************** ; ; $STAT CONTAINS INFORMATION ABOUT THE DEVICE TYPES AND THE STRUCTURE ; OF THE DEVICES IN THE SYSTEM. THE 2 BYTES IN EACH ENTRY ARE: ; EVEN BYTE: CONTAINS AN NUMBER WHICH IS UNIQUE TO THAT DEVICE: ; 0 = RK05 ; 1 = DECTAPE ; 2 = CASSETTE ; 3 = LINE PRINTER ; 4 = TTY (ASR 33,35) ; 5 = LA30 ; 6 = VT05 ; 7 = HI SPEED READER ; 10= HI SPEED PUNCH ; 11= MAGTAPE (TM11,TU10,TS03) ; 12= RF11 DISK ; 13= TA11 CASSETTE ; 14= CR11,CM11 CARD READER ; 15= RESERVED ; 16= RJS03/04 FIXED-HEAD DISKS ; 17= RESERVED ; 20= TJU16 MAGTAPE ; 21= RP11/RPR02/RP03 DISK ; 22= RX11/RX01 FLOPPY DISK ; ; ; THE ODD BYTE CONTAINS INFORMATION ON THE STRUCTURE OF THE DEVICE: ; BIT 15 1 => FILE STRUCTURED DEVICE ; 0 => NON FILE STRUCTURED ; BIT 14 1 => READ ONLY DEVICE (PTR) ; BIT 13 1 => WRITE ONLY DEVICE (LPT) ; BIT 12 1 => SPECIAL FILE DEVICE (CASSETTE) ; BIT 11 1 => TAKE HANDLER ABORT ENTRY ON JOB ABORT ;DV16 ; BIT 10 1 => HANDLER ACCEPTS .SPFUN ;DV17 ; ;********************************************************************** ; ; $ENTRY TABLE ; WHEN A DEVICE HANDLER IS IN CORE, THE $ENTRY WORD FOR THE ; DEVICE POINTS TO THE HANDLER (LAST Q-ELEMENT WORD). ; A ZERO WORD MEANS THE HANDLER IS NOT IN CORE. ; ;********************************************************************** .SBTTL EMT PROCESSOR, FPP EXCEPTION, TRAPS TO 4/10 ; THE FOLLOWING SUBROUTINE REFERENCES THE PS IN A MACHINE-INDEPENDENT ; MANNER, AT THE EXPENSE OF SOME EFFICIENCY. THE BOOTSTRAP MUST ; MODIFY THE CODE AT GETPSW+2, REPLACING IT WITH MFPS 2(SP). GETPSW: MOV (SP),-(SP) ;COPY RETURN ADDRESS ;DV15 MOV @#PS,2(SP) ;PS TO STACK ;DV15 RTS PC ;RETURN WITH PS ON STACK ;DV15 .ENABL LSB EMTPRO: BIC #1,2(SP) ;CLEAR C BIT JSR R1,SVREG ;SAVE REGISTERS CLR R2 ;FOR CALLING THE USR MOV SAVE+2(SP),R5 ;R5 -> WORD AFTER THE EMT MOV -(R5),R4 ;R4 = EMT INSTRUCTION CMPB R4,#374 ;IS IT NEW FORMAT? BHIS NEWEMT ;YES. MOV SP,R1 ;NO. POINT R1 TO ARGS ON STACK ADD #SAVE+6,R1 MOV R4,R5 ;COPY IT BIC #-20,R4 ;ISOLATE CHANNEL NUMBER BIC #177417,R5 ASR R5 ASR R5 ASR R5 BR EMTCOM ;MERGE WITH COMMON CODE NEWEMT: BNE 1$ ;EMT 375 OR 376 ADD #E375MX*400,R0 ;INDEX TO END OF LIST BR 3$ ;AND LINK WITH COMMON CODE 1$: CMPB R4,#376 ;IS IT 376 OR 377? BHI 20$ ;EMT 377 IS IGNORED BEQ E376 ;376 IS FATAL ERROR CODE MOV R0,R1 MOV (R1)+,R0 ;PUT CODE AND CHANNEL INTO R0 MOV (R1)+,(SP) ;NORMAL R0 ARG TO R0 ROR R2 ;C BIT SET FROM CMPB. R1 NOW ;POINTS TO ARG. LIST 3$: CLR R4 ;R4 WILL HOLD CHANNEL DATA BISB R0,R4 BEQ 4$ ;CHANNEL # IS 0. CMPB R4,I.CNUM ;COMPARE CHAN SPECIFIED W/# DECLARED BHIS CHANER ;CHANNEL IS TOO GREAT 4$: MOV R0,R5 ;FUNCTION GOES TO R5 CLRB R5 SWAB R5 CMPB #EMTMAX,R5 ;IS IT A LEGAL ONE? BLOS TOOBIG ;NO ASL R5 ;*2 FOR INDEXING MOV (SP),R0 ;R0 ARG BACK TO R0 EMTCOM: TST (R5)+ ;FIX INDEX INTO FUNCTION LIST MOV R5,-(SP) ;SAVE INDEX ADDR TTILCT,R5 ;POINT R5 TO LINE COUNT ;****NOTE---IT IS VITAL THAT R5 BE ;POINTED TO TTILCT HERE, AS CERTAIN ;EMT'S ASSUME THAT, AND AVOID DOING ;AN ADDR ADDRESS MACRO.******* ASL R4 ;MULTIPLY # CHANNELS BY 2 MOV R4,R3 ;NOW POINT R3 TO CORRECT CSW AREA ASL R3 ASL R3 ADD R4,R3 ADD I.CSW,R3 ADD PC,@SP ADD @(SP)+,PC ; THE FOLLOWING TABLE IS A LIST OF THE FUNCTIONS AVAILABLE AT ; THE EMT LEVEL. THE FUNCTIONS ARE DIVIDED INTO 2 MAIN GROUPS: ; THE EMT 375 FUNCTIONS COME FIRST, AND THE EMT 374 EMT'S ; FOLLOW. T1: D$LETE-T1 ; 0 DELETE L$OOK -T1 ; 1 LOOKUP E$NTER-T1 ; 2 ENTER T$RPST-T1 ; 3 SET 4/10 TRAPS R$NAME-T1 ; 4 RENAME S$AVST-T1 ; 5 SAVESTAT R$OPEN-T1 ; 6 REOPEN C$LOSE-T1 ; 7 CLOSE R$EAD -T1 ; 10 READ W$RITE-T1 ; 11 WRITE W$AIT -T1 ; 12 WAIT EMTDON-T1 ; 13 CHCOPY IN BF SYSTEM EMTDON-T1 ; 14 SPECIAL DEVICE LIST C$DFN -T1 ; 15 DEFINE CHANNELS EMT16 -T1 ; 'OLD' EMT 16 EMT17 -T1 ; USED FOR INTERNAL ERRORS G$TJB -T1 ; 20 GET JOB PARAMS ..GTIM = <. - T1> / 2 G$TIM -T1 ; 21 GET TIME OF DAY ..MRKT = <. - T1> / 2 EMTDON-T1 ; 22 MARK TIME IN BF EMTDON-T1 ; 23 CANCEL MARK TIME EMTDON-T1 ; 24 TIMED WAIT EMTDON-T1 ; 25 SEND DATA EMTDON-T1 ; 26 RECEIVE DATA EMTDON-T1 ; 27 CHANNEL STATUS S$FPA -T1 ; 30 SET FPP EXCEPTION EMTDON-T1 ; 31 PROTECT VECTORS S$PFUN-T1 ; 32 MAGTAPE/CASSETTE FONCS. EMTDON-T1 ; 33 CONTEXT SWITCH E375MX = .-T1/2 TSUB1: W$AIT -T1 ; 0 WAIT EMTDON-T1 ; 1 SUSPEND EMTDON-T1 ; 2 RESUME P$URGE-T1 ; 3 PURGE CHANNEL S$ERR -T1 ; 4 SET SOFT ERROR FLAG H$ERR -T1 ; 5 SET HARD ERROR FLAG C$LOSE-T1 ; 6 CLOSE IN NEW FORMAT L$OCK -T1 ; 7 TEST AND LOCK C$HAIN-T1 ; 10 CHAIN EMTDON-T1 ; 11 MWAIT E374MX = .-TSUB1/2 ;NUMBER OF EMT 374 FUNCTIONS EMTMAX = .-T1/2 ;TOTAL NUMBER OF EMTS TOOBIG: MONERR EMT.E,0 ;ILLEGAL EMT 20$: BR EMTOUT CHANER: MONERR CHAN.E,0 ;ILLEGAL CHANNEL ERR BR EMTOUT .DSABL LSB E376: MOV SAVE+2(SP),R0 ;R0 T0 CODE,LEVEL MOV ERRPC(SP),R3 ;PC INTO R3 MOVB (R0)+,R2 ;LEVEL TO R2 MOVB (R0)+,R4 ;ERROR CODE TO R4 BPL 1$ ;CODE >0 MEANS EITHER COM R4 ; NEGATIVE IS ONLY FATAL BR 2$ ;R4 NOE CODE. PRINT ERROR 1$: TST I.SERR ;GIVE FATAL ERROR? BNE 3$ ;NO. A SOFTY 2$: CLR @#UFLOAT ;SO WE CAN ENTER CLUSR2 MOV #1000,SP CLR RECURS ;NO COMPLETION ROUTINE .SRESET ;RESET IO QUEUE JSR PC,CLUSR2 ;GET FRESH USR IN MOV USRLOC,R5 ;JUMP UP INTO USR JMP IOFSET(R5) 3$: COMB R4 ;MAKE ERROR BYTE NEGATIVE MOVB R4,@#ERRBYT ADD #ERRPS,R2 ;POINT TO HIS C BIT ADD SP,R2 BIS #1,(R2) ;TURN ON USR'S C BIT MOV R0,SAVE+2(SP) ;NEW RETURN PC CLR R2 ;SO WE DON'T POP REGISTERS BR EMTOUT .ENABL LSB T$RPST: TST R0 ;IS THER AN ADDRESS? BNE 1$ ;YES. USE IT. MOV TRAPER,R0 ;NO. USE MONITOR'S NOW. 1$: MOV R0,(PC)+ ;SAVE TRAP ADDRESS. TRAPLC: .WORD MONTRP ;***SET BY BOOT**** BR EMTOUT MONTRP: BCS 20$ ;C SET => TRAP TO 10 SUB #12.,SP ;GET STACK RIGHT FOR ERROR MONERR TR04.E,0,FATAL ;FATAL...TRAP TO 4 20$: SUB #12.,SP MONERR TR10.E,0,FATAL ;FATAL...TRAP TO 10 TRAP4: TRAP10: ROL @#ERRBYT ;SAVE C BIT CMP #400,SP ;STACK OVERFLOW? BLO 24$ ;BRANCH IF NOT HALT ;HALT ON OVERFLOW BR .-2 24$: MOV TRAPLC,-(SP) ;SAVE USER ADDRESS BNE 25$ ;IF 0, USE MONITOR'S ADDRESS MOV TRAPER,(SP) TRAPER=.+2 25$: MOV #MONTRP,TRAPLC ;AND DISABLE TRAPS ASR @#ERRBYT ;RESTORE C BIT JMP @(SP)+ ;TO USER WITH C BIT SET RIGHT S$FPA: CMP #1,R0 ;ANY USER FPP ADDRESS? BLO 11$ ;NO. USE OUR OWN MOV FPPIGN,R0 ;NO. GIVE ?M- ERROR 11$: MOV R0,(PC)+ FPPADD: .WORD MONFPP ;****BOOT**** EMTOUT: JMP EMTDON FPPINT: BIT #HWFPU$,CONFIG ;DO WE HAVE FPP? BNE 13$ RTI ;NO. JUST RETURN 13$: STST -(SP) ;SAVE FPP STATUS MOV FPPADD,-(SP) ;SAVE HIS ADDRESS FPPIGN=.+2 MOV #MONFPP,FPPADD ;TURN OFF TRAPS JMP @(SP)+ MONFPP: SUB #14.,SP MONERR FPP.E,0,FATAL ;FATAL FPP TRAP .DSABL LSB .MACRO INTON ;MACRO TO ENABLE INTERRUPTS ;DV15 CLR -(SP) ;DV15 JSR PC,$MTPS ;DROP PRIORITY TO ZERO ;DV12,DV15 .ENDM INTON ;DV15 .MACRO INTOFF ;MACRO TO DISABLE INTERRUPTS ;DV15 MOV #PR7,-(SP) ;RAISE TO LEVEL 7 ;DV15 JSR PC,$MTPS ;DV15 .ENDM INTOFF ;DV15 .SBTTL SYNCH CODE SINK: CMP (R5)+,(SP)+ ;HERE WE HAVE TO SAVE R0,R1 MOV R0,-(SP) ;AND RESTORE R4,R5 MOV R1,-(SP) INTON ;DROP PRIORITY TO ZERO ;DV15 MOV 6(R4),R0 ;SETUP R0 WITH 4TH WD OF SYNC BLK JSR PC,(R5) ;RETURN TO USER CODE MOV (SP)+,R1 MOV (SP)+,R0 RTS PC .SBTTL EMT 16, USR CALLS EMT16: TST (R4)+ ;R4 HAS SUB CODE TO DO ADD PC,R4 ADD (R4),PC LST16: T$TIN -LST16 T$TOUT-LST16 D$STAT-LST16 ;DEVICE STATUS F$ETCH-LST16 ;FETCH/RELEASE C$SIGN-LST16 ;GENERAL MODE CSI C$SISP-LST16 ;SPECIAL MODE CSI L$OCK -LST16 ;LOCK USR U$NLOK-LST16 ;RELEASE USR E$XIT -LST16 ;EXIT PROGRAM P$RINT-LST16 ;STRING PRINT S$RSET-LST16 ;SOFT RESET Q$SET -LST16 ;SET IO QUEUE S$ETOP-LST16 ;SET TOP OF CORE R$CTLO-LST16 ;RESET ^O BIT EMTDON-LST16 H$RSET-LST16 ;HARD RESET ; FOLLOWING IS A TABLE OF CALLS INTO THE USR. R2 IS ; USED AS AN INDEX TO THE PROPER FUNCTION ONCE CONTROL ; HAS PASSED INTO THE USR. C$SIGN: CLR R4 ;******CSIGEN MUST BE FIRST********* C$SISP: INC R2 ;CSI SPECIAL H$RSET: INC R2 ;HARD RESET S$RSET: INC R2 ;SOFT RESET D$STAT: INC R2 ;DEVICE STATUS R$NAME: INC R2 ;RENAME L$OOK: INC R2 ;LOOKUP E$NTER: INC R2 ;ENTER C$LOS2: INC R2 ;CLOSE F$ETCH: INC R2 ;FETCH/RELEASE D$LETE: INC R2 ;DELETE C$DFN2: INC R2 ;DEFINE CHANNELS Q$SET: ;SET IO QUEUE JSR PC,CALUSR ;GRAB THE USR JMP @USRLOC ;TO THE USR NOW LKINT: ADC $TIME+2 ;LOW ORDER TIME ADC $TIME ;HIGH ORDER TIME RTI C$DFN: CLR USRLOC ;WE WILL READ A NEW USR NOW. BR C$DFN2 ;BACK TO MAIN STREAM .SBTTL CLOSE, HARD/SOFT ERRORS, GET TIME, GET JOB PARAMS .SBTTL CHAIN ;**************************************** ; CLOSE EMT ; IF NO DIRECTORY OPE@ATION IS REQUIRED, ; THE CHANNEL IS DISSOCIATED, AND THE ; OPERATION IS DONE. IF DIRECTORY WORK ; IS REQUIRED, THE USR IS CALLED. ;****************************************** C$LOSE: BIT #RENAM$+DWRIT$,(R3) ;DIRECTORY REWRITE NEEDED? BNE C$LOS2 ;YES. CALL USR P$URGE: CLR (R3)+ ;DISSOCIATE CHANNEL BR E16XT ;EXIT S$ERR: INC R2 ;EVEN BYTE WAS 0 FROM EMT PROCESSOR H$ERR: MOVB R2,I.SERR BR E16XT G$TIM: ADD #$TIME-TTILCT,R5 ;R5 POINTS TO TTILCT INTOFF ;KEEP OUT CLOCK INTERRUPT ;DV15 MOV (R5)+,(R0)+ ;HIGH TIME MOV (R5),(R0) ;LOW TIME BR E16XT G$TJB: CLR (R0)+ ;JOB # 0 MOV SYSLOW,(R0)+ ;HIGH LIMIT CLR (R0)+ ;0 IS LOW ADDR MOV I.CSW,(R0) ;CHANNEL AREA BR E16XT C$HAIN: BIS #CHAIN$,@#JSW ;SET CHAIN BIT MOV SP,R0 ;SO R0 IS NON-ZERO IN KMON BR CHXIT ;AND BRANCH INTO EXIT .SBTTL TTYIN/TTYOUT .ENABL LSB T$TIN: BIT #TTSPC$,@#JSW ;USER MODE TTY? BEQ 1$ ;NO. WE ARE WAITING FOR A LINE TST TTIBUF+4 ;YES. IS CHAR COUNT NON-0? BR 2$ 1$: TSTB (R5) ;IS LINE COUNT NON-0? 2$: BEQ NOINPT ;NO INPUT. RETURN ADDR TTIBUF+6,R1 ;EMT SIDE POINTER TO R1 INC (R1) ;BUMP POINTER TO NEXT CHAR CMP (R1),2(R1) ;DO WE NEED TO WRAP AROUND? BNE 3$ SUB #TTYIN,(R1) ;DECREASE POINTER 3$: MOVB @(R1),R0 ;MOVE THE CHAR. DEC -(R1) ;DECREASE COUNT MOV R0,R4 MOV R0,(SP) ;SET R0 FOR RETURN JSR PC,EOLTST BNE E16XT DECB (R5) CMP R0,#03 ;READING OUT A ^C? BNE E16XT BIS #100000,(R5) ;INHIBIT FURTHER TT: ACTION .EXIT ;YES. DO ^C EXIT E16XT: CLR R2 ;NO USER ARGS. TO POP ; THIS IS THE GENERAL END OF THE LINE FOR EMT'S E16.16: EMTDON: JSR R1,POPREG ;RESTORE A FEW REGISTERS RTI ;RETURN FROM EMT ; EMT 16 SUBFUNCTION 1--TTYOUT. THIS EMT PUTS A CHARACTER ; INTO THE OUTPUT RING BUFFER. T$TOUT: MOV R0,R4 JSR PC,OPUT ;PUT A CHAR OUT 4$: BCC E16XT ;IT FIT. NOINPT: EMTERR+0 ;RETURN WITH C SET E16LNK: BR E16XT ;RETURN, NO ARGS TO POP .DSABL LSB .ENABL LSB .SBTTL EXIT ;********************************************************************** ; EXIT EMT ; EXIT CAUSES THE EXECUTING PROGRAM TO TRANSFER CONTROL ; BACK TO THE MONITOR. THE MONITOR FILE SERVICES ; ARE PUT INTO THEIR NORMAL POSITION PRECEDING RMON, AND THE ; USER IS SWAPPED OUT IF NECESSARY. ; BEFORE CALLS ARE MADE TO THE IO ROUTINES, EXIT WAITS FOR ; ALL IO TO COMPLETE. WHEN IO IS DONE, EXIT POINTS THE QUEUE INTO ; THE MONITOR AREA, AND THE INITIATES IO CALLS TO READ IN THE ; MONITOR. NOTE THAT AT MEXIT THE Q IS RESET AGAIN TO ; CONTAIN THE CORRECT NUMBER OF ENTRIES. ;********************************************************************** E$XIT: BIC #CHAIN$,@#JSW ;TURN OFF THE CHAIN BIT! CHXIT: MOV SP,EXTFLG ;DOING AN EXIT. WE DON'T WANT ;TO RE ENTER THE EXIT ROUTINE ADDR AVAIL,R5 ;SET R5 TO FIRST ENTRY CMP -(R5),-(R5) ;ARE FREE=TOTAL NUMBER? BLT CHXIT ;NOT YET. CMP (R5)+,(R5)+ ;BACK TO AVAIL MOV R5,(R5) ;POINT Q INTO QSTART ENTRY ADD #2,(R5) CMP $ENTRY+TT.NUM,SYSLOW ;TT HANDLER LOADED? BHIS 1$ ;BR IF LOADED CLR $ENTRY+TT.NUM ;ELSE CLEAR ITS ENTRY 1$: ADD #SPTR-AVAIL,R5 ;SWITCH TO MONITOR STACK MOV R5,SP CLR I.SERR ;RESET FOR ?M- ERRORS CLR TRAPLC ;DISABLE USER TRAPS TO 4/10 ADD #$CSW-SPTR,R5 ;NOW RESET FOR 16 CHANNELS ADDR I.CSW,R2 ;ADDRESS OF CSW GOES HERE MOV R5,(R2) MOV #16.,-(R2) MOV R0,-(SP) ;SAVE R0. KMON TESTS VALUE. MOV $KMLOC,R2 ;POINT TO PERM ADDRESS FOR KMON TST KMLOC ;IS KEYBOARD IN CONTROL? BNE 5$ ;YES. GO TO MEXIT2 MOV $SWPBL,R0 ;START OF SWAP AREA TST @#JSW ;DOES USR FLOAT? BMI 2$ ;BRANCH IF NOT TST USRLOC ;IF USR NOT IN CORE, BEQ 2$ ;DON'T READ ANYTHING! JSR PC,$RSYS 2$: ADDR $SWPBL,R5 ;R5 TO IO LISTS MOV (R5)+,R0 ;BLOCK NUMBER ($SWPBL) CMP @#USERTOP,R2 ;DO WE HAVE TO SWAP? BLO 4$ ;NO. DON'T WRITE OUT USER MOV R2,(R5) ;GET ADDRESS TO WRITE FROM BIC #777,(R5) ;FULL BLOCK MOV (R5)+,(R5) ;COMPUTE SIZE TO WRITE SUB @#USERTO,(R5) BHI 3$ ;DIDN'T DESTROY ANYTHING! ROR (R5) ;WORD COUNT DEC (R5) TST -(R5) JSR PC,IOSR 4$: TST (R5)+ 3$: CMP (R5)+,(R5)+ ;READ IN KMON/USR ADD #SWAPSZ,R0 ;ADD IN # OF SWAP BLOCKS JSR PC,IOSR CMP -(R2),-(R2) ;POINT JMP TO MEXIT 5$: JMP MEXIT2-KMON(R2) $SWPBL: 0 EXLIST: 0 - 0 $KMLOC: KMON USRLEN+KMLEN 0 .DSABL LSB .SBTTL SET TOP, CANCEL ^O ; EMT16 SUBFUNCTION 14--SET TOP OF CORE. THIS EMT ; TAKES THE VALUE PASSED IN R0 AND INTERPRETS IT AS ; THE NEW TOP OF THE USER PROGRAM AREA. IF THE NEW VALUE ; OVERWRITES ANY CURRENTLY RESIDENT SECTION OF THE ; MONITOR, THAT SECTION IS MARKED AS BEING NON-RESIDENT. .ENABL LSB S$ETOP: BIS #USWAP$,@#JSW CMP R0,SYSLOW ;GOING TOO HIGH ? BLO 12$ ;NO, OK MOV SYSLOW,R0 ;RESET HIM TO HIGHEST 1$: TST -(R0) 12$: CMP R0,$KMLOC ;DESTROYING KEYBOARD? BLO 3$ CLR (PC)+ KMLOC: KMON CMP R0,$USRLC ;WIPING USR? BLO 3$ BIT #USR$,CONFIG ;IS USR MANUALLY LOCKED? BEQ 11$ ;NO. GO AHEAD AND SWAP MOV $USRLC,R0 ;SET TOP TO USR BR 1$ 11$: CLR USRLOC ;USR NON-RES. BIC #USWAP$,@#JSW 3$: MOV R0,(SP) ;RETURN TOP TO HIM MOV R0,@#USERTOP ;AND ALSO TO 50 E16XT1: 2$: BR E16LNK ;CANCEL CONTROL O R$CTLO: CLRB TTOCLO BR 2$ .SBTTL LOCK USR, INTERNAL ERROR EMT ; EMT 16 SUBFUNCTION 6--LOCK USR IN CORE ; IF A USER WANTS TO HAVE THE USR IN CORE FOR A SERIES OF ; I/O TYPE OPERATIONS, HE CAN LOCK IT INTO CORE WITH THE ; LOCK EMT. IF THE MONITOR IS ALREADY IN CORE, THIS ; OPERATION IS A NOP. L$OCK: JSR PC,CALUSR ;READ MONITOR IN BR 2$ ; EMT 17--USED FOR INTERNAL PURPOSES ONLY.. SHOULD NOT BE ; CALLED BY THE USER. MOVES AN ERROR CODE INTO LOCATION ; SET ASIDE FOR THE CODE, AND TURNS THE C BIT ON IN THE ; OFFENDING EMT'S STATUS. EMT17: ASR R4 ;NEED NUMBER BETWEEN 0-17 MOVB R4,@#ERRBYT 5$: BIS #1,ERRPS(SP) ;SET C BIT ON BR 2$ .DSABL LSB .SBTTL TTY INTERRUPT (INPUT) .ENABL LSB ; THE TTY SERVICE ROUTINES USE RING BUFFERS FOR ALL TTY IO. ; EACH RING BUFFER IS PRECEEDED BY A FOUR WORD RING BUFFER ; HEADER. THE HEADER WORDS ARE: ; 1) 'PUT' POINTER. TTY INPUT INTERRUPT ; POINTER INTO NEXT FREE BYTE ; 2) RING BUFFER CHARACTER COUNT ; 3) 'GET' POINTER. EMT PULLS CHARS. FROM THIS PTR. ; 4) ABSOLUTE UPPER LIMIT OF RING BUFFER. ; THE TTY OUTPUT RING HAS A HEADER FOR THE SAME PURPOSE. 40$: CMPB (R2)+,#'S&77 ;END OF 'MUST CHECK' LIST? BNE 3$ ;NOT YET. BIT #TTSPC$,@#JSW ;CHECK MORE SPECIALS? BNE TTINC3 ;NO. IN SPECIAL MODE BR 3$ ;OK. DO MORE CHECKS TTIINT: JSR R1,SVREG ;SAVE VOLATILE REGISTERS ADDR TTIBUF+4,R5 ;POINT TO RING COUNT MOV @TTKB,R0 ;CHARACTER INTO R0 INTON ;BACK TO LEVEL 0 ;DV15 ;*** FOLLOWING LINE MODIFIED BY GT ON TO INTERCEPT INPUT INTERRUPTS.**** SCLNK2: BIC #200,R0 ;STRIP OFF PARITY BIT BEQ TTIEX3 ;IGNORE NULLS BIT #TTLC$,@#JSW ;CONVERT TO UPPER CASE? BNE 1$ ;NO, CONVERSION IS DISABLED CMP R0,#141 ;CONVERT LOWER CASE BLT 1$ ;TO UPPER CASE CMP R0,#172 BGT 1$ BIC #40,R0 1$: ADDR TTIPRE,R1 ;R1 TO PREVIOUS WORD 2$: ADDR 4$,R2 ;POINT TO LIST OF SPECIAL CHARACTERS 3$: CLR R3 ;DO THIS BECAUSE MOVB IS BAD! BISB (R2)+,R3 ;ADDRESS DIFFERENCE TO R3 BEQ T.SPEC ;0 ENDS LIST. CHECK NON PRINTS. CMPB (R2),R0 ;IS IT A MATCH? BNE 40$ ;NO. SEE IF DONE FIRST PART YET. ADD R3,PC ;JUMP TP PROCESS 4$: .BYTE CTRLC -4$,'C&77 ;^C***KEEP ^S AS LAST IN .BYTE CTRLO -4$,'O&77 ;^O***THE LIST*** .BYTE CTRLQ -4$,'Q&77 ;^Q .BYTE CTRLS -4$,'S&77 ;^S .BYTE CTRLU-4$,'U&77 .BYTE ALT-4$, ESCAPE .BYTE ALT-4$, 175 .BYTE ALT-4$, 176 .BYTE RUB-4$, RUBOUT .BYTE TTINCC-4$,CR ;DON'T WANT TO ECHO ^CR .BYTE TTINCC-4$,LF .BYTE TTINCC-4$,FF .BYTE TTINCC-4$,TAB .WORD 0 .EVEN .DSABL LSB .ENABL LSB ALT: MOV #ESCAPE,R0 ;SET TO HANDLE ESCAPES BR TTINC3 ;SEND 33 TO BUFFER T.SPEC: CMP R0,#40 ;PRINTING CHAR? BGE TTINCC ;YES. JSR PC,EKOR0 ;NO. ECHO ^(CHAR) TTINCC: CMP #RUBOUT,(R1) ;WAS LAST A RUBOUT? BNE TTINC3 JSR PC,TTORUB ;ECHO A '\' TTINC3: MOV #BELL,R4 ;PRINT BELL IF BUFFER FULL CMP (R5),#TTYIN-1 ;WE ACTUALLY ONLY ALLOW 81 CHARACTERS ;THIS PREVENTS EVER HAVING THE RING ;BUFFER POINTERS THE SAME AND THUS ;LOCKING UP THE KEYBOARD BGE 3$ ;NO. DON'T ALTER TTIPRE INC (R5) ;BUMP CURRENT COUNT INC -(R5) ;BUMP INPUT POINTER CMP (R5),6(R5) ;TIME TO WRAP ABOUT? BNE 1$ SUB #TTYIN,(R5) 1$: MOVB R0,@(R5)+ ;PUT IN CHAR. AND GO TO COUNT MOV R0,R4 JSR PC,EOLTST BNE 2$ INCB TTILCT ;BUMP LINE COUNT 2$: MOV R0,(R1) 3$: BIT #TTSPC$,@#JSW ;DON'T ECHO IN USER MODE BNE 4$ TTIEXZ: TST SYNC ;SHOULD WE OUTPUT IT? BNE 4$ ;NO. JSR PC,TTOPUT ;OUTPUT THE CHARACTER 4$: MOV TTENTR,R4 ;IF TT HANDLER IS AROUND, GO TO IT BEQ 5$ ;IT ISN'T IN CORE JSR R4,6.(R4) ;AND GET THE CHARACTER WE PUT IN TTILCT-. 5$: SUB #3,R0 ;TEST FOR CARRIAGE RETURN CMP R0,#LF BEQ TTINC3 ;PUT IN LF WITH CR TTIEX3: BR E16XT1 TTIPRE: 0 ;PREVIOUS TTY INPUT CHAR. .DSABL LSB .SBTTL ^O, ^C^C, ^U, RUBOUT, INPUT BUFFER .SBTTL STRING PRINT CTRLO: CLR TTOBUF+2 ;CLEAR OUTPUT BUFFER MOV TTOBUF,TTOBUF+4 ;EQUATE BUFFER POINTERS JSR PC,EKOR0 ;ECHO ^O JSR PC,TTLFCR ;CR/LF COMB TTOCLO ;FLIP THE FLOP BR TTIEX3 ;************************************************** CTRLC: JSR PC,EKOR0 ;ECHO ^C JSR PC,TTLFCR ;GEN CR/LF AFTER ^C. MOV $ENTRY+BA.NUM,R3 ;IS BA.SYS RESIDENT? BEQ 1$ ;BR IF NOT RESIDENT CLR 6(R3) ;MAKE BATCH STOP COMPLETELY 1$: CMP R0,(R1) BNE TTINC3 TST (PC)+ ;ARE WE DOING AN EXIT NOW? EXTFLG: 0 BNE TTIEX3 ;YES. IGNORE THIS ONE TST DFLG ;DIRECT. OPERATION IN PROGRESS? BEQ CTRLC2 ;NO. OK TO EXIT MOV #140000,DFLG ;YES. DON'T HONOR ^C UNTIL DONE. BR TTIEX3 ;RETURN FROM INTERRUPT ;************************************************** CTRLU: JSR PC,EKOR0 ;ECHO ^U TTICTL: JSR PC,RUBCM2 ;TEST FOR EMPTY BUFF, AND IF ;NOT EMPTY, MOV LAST CHAR TO R4 BEQ TTIBUM JSR PC,RUBCOM BR TTICTL TTIBUM: CLR (R1) TTCRLF: JSR PC,TTLFCR BR TTIEX3 ;************************************************** CTRLS: MOV SP,SYNC ;STOP OUTPUT BR TTIEX3 CTRLQ: CLR SYNC ;RESUME OUTPUT CLR @TTPS ;CLEAR. NEXT WILL GEN INTERRUPT MOV #IENABL,@TTPS ;START INTERRUPTS BR TTIEX3 ;*************************************************** RUB: JSR PC,RUBCM2 ;TEST FOR BUFF EMPTY, IF NOT ;MOVE LAST CHAR TO R4 BEQ TTIBUM CMP R0,(R1) BEQ 1$ JSR PC,TTORUB ;ECHO A '\' MOV R0,(R1) 1$: MOVB @(R5),R4 JSR PC,RUBCOM BR TTIEXZ ;**************************************************** ; STRING PRINT EMT .ENABL LSB 1$: JSR R0,2$ ;PRINT CR,LF - WAIT FOR BUFFER ;DV14 .BYTE CR,LF,200,0 ;DV14 2$: TST (SP)+ ;PURGE STACK ;DV14 P$RINT: MOVB (R0)+,R4 ;CHARACTER TO R4 BEQ 1$ ;NULL MEANS DONE. DO CR/LF ;DV14 CMPB #200,R4 ;A 200 BYTE SAYS NO CRLF BEQ TTIEX3 3$: JSR PC,TTOPT2 ;OUTPUT CHAR ;DV14 BCS 3$ ;BUSY, TRY AGAIN ;DV14 BR P$RINT .DSABL LSB ;****************************************************** CTRLC2: JSR PC,ZAP ;RESET I/O ;DV15 MOV QSIZE,QCNT ;SET FREE ENTRIES=TOTAL ENTRIES .EXIT ;AND EXIT ; RESET ALL I/O, THEN RESTART THE CLOCK IF THERE IS ONE. ;DV15 ZAP: INC (PC)+ ;DELAY FOR 11/05 ;DV15 0 ;DV15 BNE ZAP ;DV15 RESET ;STOP ALL IO ;DV15 TST CONFIG ;DO WE HAVE A CLOCK? ;DV15 BPL 1$ ;NO ;DV15 BIT #LSI11$,CONFIG ;RUNNING ON LSI11?? ;DV15 BNE 1$ ;YES, NO LKCS TO WORRY ABOUT ;DV15 MOV #100,@#LKCS ;TURN ON THE CLOCK AGAIN ;DV15 1$: RTS PC ;RETURN ;DV15 TTLFCR: JSR R3,ECHO .BYTE CR,LF TTIRTS: RTS PC RUBCOM: CMP (R5),-2(R5) ;TIME TO WRAP AROUND? BNE 1$ ADD #TTYIN,(R5) ;RESET POINTER 1$: DEC (R5)+ ;NOW DECREASE THE POINTER ;AND BUMP TO COUNT DEC (R5) ;DECREASE CHAR. COUNT RTS PC ;**************************************** ; THESE RING POINTERS AND TTILCT MUST ; BE KEPT TOGETHER AND IN THIS ORDER FOR THE ; TT: HANDLER TO BE ABLE TO WORK ;****************************************** TTILCT: .BYTE 0 ;EVEN BYTE IS LINE COUNTER .BYTE 0 ;BIT 15 IS TT: INHIBIT FLAG ;IF ^C IS HIT, AND TT: IS ACTIVE, ;THIS BIT CAUSES TT: TO ABORT. TTIBUF = . IBUFR ;LOW LIMIT OF BUFFER IBUFR ;INTERRUPT SIDE POINTER 0 ;CURRENT COUNT IBUFR ;EMT SIDE POINTER IBUFR+TTYIN ;UPPER LIMIT TTOBUF=. OBUFR ;EMT SIDE PTR 0 ;COUNT OBUFR ;INT PTR. OBUFR+TTYOUT ;HI LIMIT TTOCLO: .BYTE 0,0 ;^O FLIP FLOP IBUFR: .BLKB TTYIN ;START OF RING BUFFER OBUFR: .BLKB TTYOUT .EVEN RUBCM2: TST (R5) ;IS IT EMPTY? BEQ TTIRTS ;BUFFER MUST BE EMPTY MOVB @-(R5),R4 ;PUT LAST CHAR INTO R4 EOLTST: CMPB R4,#LF BEQ 1$ CMPB R4,#03 BEQ 1$ CMPB R4,#'Z&32 ;IS IT EOF? 1$: RTS PC .SBTTL TTY OUTPUT ROUTINES, INTERRUPT ENTRY TTORUB: MOV #'\,R4 ;ECHO A \ TTOPUT: CMP R4,#ESCAPE ;ECHOING AN ESCAPE? BNE TTOPT2 ;NO. MOV #'$,R4 ;YES. ECHO DOLLAR SIGN TTOPT2: ; JSR PC,OPUT ;OUTPUT A CHAR. ;DV14 ; BCS TTOPT2 ;WAIT FOR ROOM ;DV14 ; RTS PC ;DV14 .ENABL LSB OPUT: TSTB TTOCLO ;IS ^O ON?;ALSO CLEAR C BNE 2$ ;ASSUME ITS OK. TTSCRL: BIC #177600,R4 ;NO PARITY BITS ADDR TTOBUF+2,R2 ;R2 TO COUNT CMP #TTYOUT-1,(R2) ;WILL THIS ONE FIT? BLO 3$ ;NO ; NOTE: C BIT IS SET MOVB R4,@-(R2) ;STORE CHARACTER IN BUFFER INC (R2) ;INCREASE POINTER CMP (R2),6(R2) ;TIME TO WRAP AROUND? BLO 1$ SUB #TTYOUT,(R2) ;DECREASE COUNT. 1$: INC 2(R2) ;BUMP COUNT IN RING BUFF MOV #100,@TTPS 2$: CLC ;C IS CLEAR 3$: RTS PC ; THIS TTY INTERRUPT SERVICE HANDLES TABS AND FILL CHARACTERS. TTOINT: ADDR TTOBUF+4,R5,PUSH ;SAVE R5, POINT TO COUNT JSR R4,TTO2 ;R4 TO TABCNT TABCNT: 0 ;# OF FILL OR SPACES TO PRINT FILLC: 0 ;CHARACTER TO PRINT CHCNT: 10 ;# SPACES TO NEXT TAB STOP TTO2: TST (PC)+ ;ARE WE DOING OUTPUT? SYNC: 0 BNE TTPOXT ;NO. JUST RTI DEC (R4)+ ;DOING TABS OR FILLS? BGT TPRNT3 ;YES. PRINT SOME ; BEQ 42$ ;PRINT ONE MORE AFTER FILLS ;DV9 31$: MOV R4,-(SP) ;SAVE VITAL R4 MOV TTENTR,R4 ;***IF TT: RESIDENT, AND BUSY, GO INTO ;*** THE WRITE PART OF TT: AND CHANGE ;***THE R5 POINTER BEQ 41$ ;NOT IN CORE JSR R4,8.(R4) ;OUTPUT INT. TTILCT-. 41$: MOV (SP)+,R4 ;RESTORE R4 42$: CMP (R5),2(R5) ;TIME TO WRAP AROUND? BNE 4$ SUB #TTYOUT,(R5) ;CYCLE POINTER 4$: DEC -(R5) ;DECREASE COUNT CMP (R5)+,#-1 ;DONE YET? BEQ TTODON ;***NOTE. WE DO THIS SO THAT TT: ;CAN USE THIS CODE ALSO**** MOVB @(R5)+,(R4) ;GET CHARATER CMP (R4),#40 ;TEST FOR PRINTING CHAR. BLT TCHKSP ;<40. CHECK SPECIALS BIC #177600,(R4)+ ;STRIP PARITY ;DV10 DEC (R4) ;DECREASE # TO NEXT STOP BNE TTPRNT ;IF 0, RESET TO 10 MOV #10,(R4) TTPRNT: TST -(R4) ;POINT TO FILLC TPRNT7: INC -(R5) ;NEXT BUFFER LOC TPRNT3: MOV (R4),@TTPB ;PRINT CHARACTER BR TTPOXT TCHKSP: CMP (R4),#TAB ;IS IT A TAB? BNE 5$ MOV #40,(R4)+ ;ECHO N SPACES MOV (R4),-4(R4) ;SET UP TABCNT BR 6$ ;RESET TAB STOP 5$: CMP (R4)+,#CR ;CARRIAGE RETURN BNE 7$ CLR -4(R4) ;END OF LINE. CLEAR FILL COUNT. 6$: MOV #10,(R4) 7$: TST -(R4) ;POINT TO FILLC CMPB (R4),@#TTFILL ;HAVE TO FILL? BNE TPRNT7 ;NO. JUST PRINT THIS ONE MOV (R4),@TTPB ;TYPE THIS ONE CLR (R4) ;FILLERS ARE NULLS CLR -(R4) ;POINT R1 TO FILL COUNT AND CLEAR IT MOVB @#TTNFIL,(R4) ;XFER FILL COUNT TO TABCNT INC -(R5) ;NEXT BUFFER WORD BR TTPOXT ;AND EXIT FOR NOW. TTODON: CLR @TTPS ;CLEAR INTERRUPTS CLR -(R5) TTPOXT: MOV (SP)+,R4 MOV (SP)+,R5 RTI .DSABL LSB ;************************************************** ; COMMON INTERRUPT ENTRY CODE. PUSHES R5,R4 ON STACK ; SETS PROPER PRIORITY, THEN RECALLS THE HANDLER ; VIA A JSR PC,. ON RETURN, REGS ARE RESTORED AND ; THE RTI IS DONE ;************************************************** $INTEN: MOV R4,-(SP) ;R5 IS ON STACK FROM JSR R5 ;******************************************************************** ; DV15 ; BOOT WILL OVERLAY FOLLOWING TWO INSTRUCTIONS WITH THE SEQUENCE: ; ; MFPS R4 ; BIC (R5)+,R4 ; MTPS R4 ; ; IF THE PROCESSOR DOES NOT HAVE A PS ADDRESS (LSI11). ;********************************************************************* MOV #PS,R4 ;R4 -> PS ;DV15 BIC (R5)+,@R4 ;SET PRIORITY BITS ;DV15 ;********************************************************************* JSR PC,(R5) ;CALL THE HANDLER BACK BR TTPOXT ;RESTORE REGS AND RTI .ENABL LSB .SBTTL READ/WRITE EMT HANDLERS, MT/CT FUNCS. S$PFUN: MOV (R3),R2 ;GET DEVICE INDEX BIC #^C76,R2 ADD PC,R2 ;MAKE IT PIC BIT #SPECL$,$STAT-.(R2) BEQ RWXT ;IT ISN'T SPECIAL MOVB #377,4(R1) ;BE NICE, GIVE HIM A 377 TST 4(R1) ;IF NOT <0, GIVE ERROR BPL 5$ R$EAD: JSR R4,TSWCNT ;DO SOME CHECKING NOP NOP NFREAD: MOV R4,(SP) ;SET WORD COUNT FOR R0 1$: BIT #HDERR$,(R3) ;HARD ERROR? BNE 6$ BIT #EOF$,(R3) ;END OF MEDIUM? BNE 4$ MOV R1,R5 ;POINT R5 AT ARG LIST TST -(R5) ;R5 TO TOP OF LIST. (BUFFER) MOV (R3),R2 ;ISOLATE ENTRY VALUE OF HANDLER BIC #177701,R2 ADDR $ENTRY,R2,ADD ;COMPUTE PHYSICAL ENTRY POINT MOV (R2),R2 ;TST HNDLR IN CORE, AND ;MOVE ENTRY PT. TO R2 BEQ 2$ ;NO HANDLER! ZOUNDS, MAN! ADD C.SBLK(R3),R0 ;MAKE BLOCK ABSOLUTE. MOV C.DEVQ(R3),R1 ;UNIT # TO R1 CLRB R1 JSR PC,QMANGR ;QUEUE AN ENTRY BIT #HDERR$,(R3) ;HARDWARE GOOF? BNE 6$ RWXT: MOV #3,R2 ;3 ARGUMENTS TO CLEAN UP BR E16.7A 2$: MONERR NODV.E,0 ;NO DEVICE HANDLER BR RWXT ;EXIT SOFTLY, DARLING 3$: TST (SP)+ ;PURGE STACK 4$: BIC #EOF$,(R3) ;CLEAR EOF BIT 5$: EMTERR+0 BR RWXT 6$: BIC #HDERR$,(R3) ;CLEAR ERROR BIT EMTERR+1 BR RWXT 7$: TST (SP)+ EMTERR+2 BR RWXT ;WRITE EMT W$RITE: JSR R4,TSWCNT BR NFWRIT ;NON FILE OR DIRECTORY OP. EMTERR+0 CMP R5,C.USED(R3) BLOS NFWRIT BIT #DWRIT$,(R3) ;ENTERED ? BEQ NFWRIT ;NO MOV R5,C.USED(R3) NFWRIT: MOV R4,(SP) ;WORD COUNT FOR R0 NEG R4 ;MAKE IT A WRITE BR 1$ ;DO COMMON STUFF .SBTTL READ/WRITE ROUTINE ; TSWCNT- ; TSWCNT SETS R5 TO THE REQUESTED WORD COUNT. ; R3 POINTS TO THE CHANNEL STATUS WORD ; IF THE STARTING BLOCK OF A CHANNEL IS 0, IT IS EITHER ; A NON-FILE STRUCTURED DEVICE, OR A DIRECTORY OPERATION. ; IN EITHER CASE, THE READ IS ALLOWED TO PROGRESS. TSWCNT: TST (R1)+ ;POINT TO WORD COUNT MOV (R1),R5 ;WORD COUNT TO R5 MOV R5,(SP) ;NOTE THAT R4 IS NOT VALUABLE ON ;ENTRY, AND THIS WILL CAUSE THE ;CORRECTED WORD COUNT TO BE RETURNED ;IN R4 MOV (R3),R2 ;STATUS PTR TO R1, AND ;IS CHANNEL OPEN? BPL 7$ ;NO. THAT 'S A NO-NO BIC #177701,R2 ;STATUS POINTER TO R1 ADDR $STAT,R2,ADD TST (R2) ;NON FILE DEVICE? BPL TSWOUT ;POSITIVE MEANS NON FILE BIC #EOF$,(R3) ;CLEAR EOF FOR FILE STRUCTURED TST C.SBLK(R3) ;0 HERE MEANS DIRECTORY OPERATION BEQ TSWOUT CMP (R4)+,(R4)+ ;TO LEGAL RETURN MOV C.LENG(R3),R2 ;FILE LENGTH TO R2 CMP R0,R2 ;IS BLOCK NUMBER LEGAL? BHIS 3$ ;NO. GENERATE EOF. ADD #377,R5 ;CHANGE WORD COUNT TO BLOCKS CLRB R5 SWAB R5 ADD R0,R5 ;NEW CLOSING LENGTH GUESS SUB R5,R2 ;WILL IT ALL FIT? BPL TSWOUT ;YES. GET OUT ADD R2,R5 ;MAKE R5 HIGHEST THAT IS LEGAL MOV R5,(SP) ;AND RETURN # WE READ. SUB R0,(SP) SWAB (SP) TST -(R4) ;TAKE EOF EXIT TSWOUT: RTS R4 .DSABL LSB .SBTTL SAVESTATUS AND REOPEN; I/O WAIT .SBTTL CHANNEL DEFINE S$AVST: TST (R3) ;IS THIS CHANNEL OPEN? BPL 1$ ;NO. SAVE 'NOT OPEN' STATUS TSTB (R3) ;WAS AN 'ENTER'DONE? BMI E5ER1 ;YES. NO SAVESTATUS PERMITTED 1$: MOV (R3),(R0)+ ;CHANNEL STAT. WORD CLR (R3)+ ;DEACTIVATE CHANNEL. .REPT 4 ;FILL IN REMAINING DATA MOV (R3)+,(R0)+ .ENDR XCLOSE: CLR R2 E16.7A: JMP EMTDON ; REOPEN---- R$OPEN: TST (R3) ;CHANNEL CAN'T BE IN USE BMI E5ER0 ;AMAZING! REOPEN IS INVERSE OF SAVE! .REPT 5 ;REPLACE THE WORDS MOV (R0)+,(R3)+ .ENDR BR XCLOSE E5ER0: EMTERR+0 BR XCLOSE ; EMT12--WAIT ON I/O. ALSO, THIS EMT RETURNS AN ERROR IF THE ; CHANNEL IS NOT ACTIVE. THIS GIVES A WAY OF CHECKING TO SEE IF ; A CHANNEL IS CURRENTL BEING USED. W$AIT: TST (R3) ;CHANNEL ACTIVE? BPL E5ER0 ;>0=> NO 1$: TSTB C.DEVQ(R3) ;WAIT TILL PENDING REQUESTS=0 BNE 1$ BIT #HDERR$,(R3) ;WAS THERE AN ERROR? BEQ XCLOSE ;NO. RETURN TO USER BIC #HDERR$,(R3) ;YES. CLEAR HARD ERROR BIT E5ER1: EMTERR+1 BR XCLOSE .SBTTL SWAP USR ROUTINE ; CALUSR---- ; THIS ROUTINE LOADS THE USR INTO CORE. ; THE USER PROGRAM IS SWAPPED OUT IF NECESSARY. CALUSR: INC MONCAL ;BUMP USAGE COUNT TST USRLOC ;MONITOR IN CORE? BNE MONRES CLUSR2: MOV @#UFLOAT,-(SP) ;ADDRESS OF FLOATING USR BEQ 1$ ;0 => USE STANDARD LOCATION ;DV20 BIT #USR$,CONFIG ;IS USR SWAPPABLE? ;DV20 BEQ 2$ ;YES, USE FLOATING ADDRESS ;DV20 1$: MOV $USRLC,(SP) ;LOAD BELOW RMON ;DV20 2$: MOV (SP),MONLOC ;SET UP I/O BLOCK ;DV20 TST @#JSW ;DO WE HAVE TO SWAP? BMI 3$ ;NO. READ IN USR. MOV $SWPBL,R0 ;WRITE USER OUT FIRST NEG MONLOC+2 ;MAKE IT A WRITE JSR PC,$WSYS 3$: MOV (PC)+,R0 $MONBL: 0 ;***BOOT*** MOV (SP)+,USRLOC ;MAKE MONITOR RESIDENT $RSYS: MOV #USRLEN,MONLOC+2 $WSYS: ADDR MONLOC,R5 ;POINT R5 TO MONLOC IOSR: JSR PC,$SYS BCS MONIOF MONRES: RTS PC .SBTTL USR RELEASE,RETURN, REG. SAVE&RESTORE .EVEN ; EMT 16-SUB 7--RELEASE USR FROM CORE. AFTER A LOCK IS DONE, ; THIS EMT RELEASES THE USR. ALSO, MONOUT IS THE RETURN POINT ; FROM ALL NON RESIDENT USR FUNCTIONS. ;NOTE THAT R2=0 HERE U$NLOK: TST MONCAL ;AT WHAT LEVEL ARE WE? BEQ E16.7A ;NOT LOCKED ! MONOUT: DEC (PC)+ ;TIME TO RE-READ USER? MONCAL: 0 BNE E16.7A ;I GUESS NOT. KMTST: TST KMONIN ;IS KMON IN CONTROL? BNE E16.7A ;YES. DON'T SWAP. TST DFLG ;DO WE HAVE TO SERVICE ^C? BPL 1$ ;>0 IMPLIES NO. .EXIT ;YES. EXIT. 1$: TST @#JSW ;DO WE HAVE TO SWAP? BMI E16.7A ;NO IF MINUS CLR USRLOC ;USR NO LONGER IN CORE CLR BLKEY ;KILLS DIRECTORY IN CORE MOV $SWPBL,R0 ;READ IN THE USER JSR PC,$RSYS BR E16.7A ;END OF EMT. SPAREA: ;COMMON EMT 375 LIST, AND KMBLK: BSS 5 ;IO BLOCK FOR 'FINAL' READ MONLOC: USRBUF USRLEN MONIOF: 0 ;HALT AT FATAL READ ERROR BR MONIOF ;PROTECTION!!! RDOVLY: JSR PC,IOSR ;I HOPE HANK SET IT UP RIGHT! ENTRPG: MOV @#USERSP,SP ;NEW STACK POINTER CLR (PC)+ ;USER IS RUNNING KMONIN: 1 JMP @R2 ;TO THE USER! .SBTTL ECHO, SVREG, POPREG ; ECHO--ECHOES CHARACTERS ON CONSOLE TTY ECHO: MOVB (R3)+,R4 JSR PC,TTOPUT MOVB (R3)+,R4 BEQ 1$ JSR PC,TTOPUT 1$: RTS R3 SVREG: MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV R0,-(SP) JMP (R1) ; POPREG--POP REGISTERS FROM THE STACK; ALSO, R2 CONTAINS THE NUMBER ; OF USER ARGUMENTS TO REMOVE FROM THE STACK. POPREG: MOV SAVE+4(SP),R3 ;SEE IF IT'S A NEW EMT CMPB #374,-2(R3) BLOS NOPOP ;YES. NO POPPING NEEDED ASL R2 ;WDS TO POP INTO BYTES BEQ NOPOP ;NONE TO DO MOV SP,R3 ;MARK CURRENT SPOT ADD #OLDPS+4,R3 ;TO PS/PC OF EMT ADD R3,R2 ;TO 1 ABOVE FIRST ARG. 1$: MOV -(R3),-(R2) ;MOVE THE CONTENTS CMP R3,SP ;DONE? BHI 1$ ;NOT YET MOV R2,SP ;YES. SET NEW STACK NOPOP: TST (SP)+ ;OLD VALUE OF R1..USELESS MOV (SP)+,R0 ;NOW RESTORE USER REGISTERS MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 RTS R1 EKOR0: MOVB R0,-(SP) ADD #100,(SP) ;ECHO THE UPPER CASE MOVB (SP)+,EBYT JSR R3,ECHO .BYTE '^ EBYT: .BYTE 0 ;HOLDS CHAR TO BE ECHOED RTS PC .SBTTL QUEUE AND QUEUE MANAGER ; RT11 IS DRIVEN FROM AN IO QUEUE. ; ALL IO REQUESTS ARE PUT INTO A COMMON QUEUE, AND THE ; INDIVIDUAL DEVICE DRIVERS TAKE THEIR JOBS FROM THAT QUEUE ; THE ENTRY POINT FOR MONITOR IO REQUESTS IS $SYS. THIS ENTRY ; SAVES ALL REGISTERS, AND INITIATES A CALL TO THE ; Q MANAGER $SYS: JSR R1,SVREG ;SAVE REGISTERS ADDR $SYSCH,R3 ;SYS CSW AREA CLR 10(R3) ;CLEAR SYS IO COUNT TO ;PREVENT SYSTEM HANG-UP. MOV SYUNIT,R1 ;SYS UNIT # TO R1 MOV (PC)+,R2 ;LAST Q ENTRY FOR SYS SYENTR: .WORD 0 SYENTO=SYENTR-$RMON MOV 2(R5),R4 ;SET WORD COUNT FOR XFER JSR PC,QMANGR ;Q A REQUEST 1$: JSR R1,NOPOP ;RESTORE REGISTERS ROR $SYSCH ;SEE IF ERROR IS ON RTS PC ;********************************************************************** ; THIS IS THE INITIAL Q ; ; KEEP THESE ENTRIES IN THIS ORDER ;************** .ENABL LSB QSIZE: 1 ;ONE ENTRY LONG QCNT: 1 ;ONE FREE ENTRY AVAIL: QSTART ;POINTS TO FIRST ELMENT QSTART: BSS 7 ;ONE ENTRY STANDARD ; QUEUE MANAGER. ; THE Q MANAGER IS ENTERED WHEN AN IO REQUEST IS TO BE PUT IN ; THE Q. THE ENTRY CONDITIONS ARE: ; CALLED BY- JSR PC,QMANGR ; REGISTERS: ; 0 BLOCK TO READ/WRITE ; 1 UNIT NUMBER IN LOW BITS OF ODD BYTE ; 2 POINTS TO 4TH WORD OF HANDLER ; 3 POINTER TO CHANNEL STATUS WORD ; 4 WORD COUNT FOR TRANSFER ; 5 POINTER TO ARGUMENT LIST QMANGR: MOV R4,-(SP) ;SAVE WORD COUNT FOR LATER 1$: ADDR QCNT,R4 ;R4 TO QCNT POINTER DEC (R4)+ ;IS THERE ROOM IN Q YET? BMI 9$ ;NO MOV R3,-(SP) ;SAVE REGISTERS MOV R0,-(SP) INTOFF ;LOCK OUT INTERRUPTS ;DV15 MOV (R4),R4 ;GET FIRST AVAILABLE ENTRY MOV (R4),AVAIL ;MAKE THE NEXT ELEMENT AVAILABLE INTON ;BACK TO LEVEL 0 ;DV15 CLR (R4)+ ;ZERO PTR. TO NEXT Q ELEMENT MOV R3,(R4)+ ;FILL IN Q: PTR TO CSW INCB 10(R3) ;BUMP CHANNEL Q REQUEST COUNT MOV R4,R3 MOV (SP)+,(R4)+ ;BLOCK NUMBER MOV R1,(R4)+ ;UNIT NUMBER MOV (R5)+,(R4)+ ;BUFF ADDRESS MOV 2(SP),(R4)+ ;WORD COUNT TST (R5)+ ;SKIP THIS WORD COUNT MOV (R5)+,(R4) ;COMPLETION FUNCTION ;************************************************** CMPB (R4),#377 ;SPECIAL CALL? BNE 2$ SWAB (R4) MOVB (R4),-6(R4) ;PUT CODE INTO CODE WD. MOV (R5)+,(R4) ;REAL COMPLETION ADD. BR 3$ 2$: CLRB -6(R4) ;NORMAL R/W OPERATION ;************************************************** 3$: MOV R5,-(SP) INTOFF ;LOCK OUT INTERRUPTS ;DV15 TST EXTFLG ;*IF EXIT IN PROGRESS, DON'T BNE 4$ ;*WAIT FOR SYS TO EMPTY OUT MOV (R2),R1 ;*IS DEVICE BUSY? BNE 5$ ;*YES. ADD NEW ELEMENT TO Q 4$: MOV R3,(R2)+ ;*SET DEVICE BUSY INTON ;BACK TO LEVEL 0 ;DV15 MOV R3,(R2)+ ;POINT BUSY FLAG AT Q ELEMENT JSR PC,(R2) ;START THE HANDLER BR 6$ 5$: MOV R3,-4(R1) ;* LINK NEW ELEMENT TO END OF Q MOV R3,(R2) ;* AND SET LAST Q ELEMENT TO IT INTON ;BACK TO LEVEL 0 ;DV15 6$: MOV (SP)+,R5 MOV (SP)+,R3 TST -(R5) ;GO TO COMPLETION? BNE 8$ 7$: TSTB 10(R3) ;WAIT FOR IO TO COMPLETE BNE 7$ 8$: MOV (SP)+,R4 ;KEEP STACK STRAIGHT RTS PC 9$: INC -(R4) 10$: TST (R4) ;WAIT FOR FREE BLE 10$ BR 1$ .DSABL LSB .SBTTL QUEUE COMPLETION, KMON STACK .ENABL LSB ; WHEN A DEVICE TRANSFER COMPLETES, THE HANDLER TRANSFERS TO ; COMPLT, TO START A NEW REQUEST OR TO ENTER THE COMPLETION ; ROUTINE SPECIFIED. ; ENTER WITH R4 AND R5 ON STACK. R4 POINTS TO THE LOCATION ; IN THE HANDLER WHICH POINTS TO THE CURRENT Q ENTRY BEING ; PROCESSED. COMP = 14 COMPLT: JSR R1,SVREG ;WILL NEED THIS FOR SPACE MOV (R4),R5 ;GET PTR. TO CURRENT Q ELEMENT BIT #HDERR$,@-(R5) ;HARD ERROR? BNE 7$ ;YES. GO SERVICE IT 1$: MOV (R5),R2 ;PUT CSW INTO R0 NOW MOV (R2),R0 ;THERE IT GOES! CLR R1 ;NOW DIVIDE TO GET CHAN. NUMBER SUB I.CSW,R2 ;SUBTRACT START OF CSW AREA 2$: SUB #10.,R2 ;DIVIDE BY 12(8) BYTES FOR CHAN NUM. BLO 3$ INC R1 ;CHANNEL NUMBER BUILT IN R1 BR 2$ 3$: ADD #10,(R5)+ ;NOW DECREASE PENDING IO Q DEC @-(R5) ;REQUESTS JSR PC,GETPSW ;GET PS, RETURNED ON STACK ;DV15 INTOFF ;LOCK OUT INTERRUPTS ;DV15 MOV -(R5),(R4) ;PTR. TO NEXT ELEMENT IF ANY BNE 4$ CLR -(R4) ;NONE. DEVICE IS FREE CLR R4 ;REMEMBER THAT IT IS FREE 4$: MOV AVAIL,(R5) ;PUT OLD ELEMENT INTO AVAILABLES MOV R5,AVAIL INC QCNT ;NEW ELEMENT AVAILABLE MOV COMP(R5),R5 ;COMPLETION ADDRESS JSR PC,$MTPS ;RESTORE PREVIOUS PS FROM STACK ;DV15 CMP #1,R5 ;GO TO A COMPLETIO ADDRESS? BHIS 5$ INC RECURS ;YES. SET MONITOR PROTECT MOV @#ERRBYT,-(SP) ;SAVE ERROR STATUS JSR PC,(R5) ;DO COMPLETION MOV (SP)+,@#ERRBYT DEC (PC)+ RECURS: 0 5$: TST R4 ;WAS DEVICE FREE BEFORE COMPLETION? BEQ 6$ ;YES. NO MORE ENTRIES NOW JSR PC,2(R4) ;CALL HANDLER TO START NEW TRANSFER 6$: JSR R1,NOPOP ;RESTORE REGS. RTS PC ;BACK INTO $INTEN 7$: TSTB @#JSW ;HALT ON HARD ERROR? BPL 1$ HALT . = . + 100 SPTR = . .DSABL LSB MAXSYH = DTSIZE .IIF GT RKSIZE-MAXSYH MAXSYH = RKSIZE .IIF GT DXSIZE-MAXSYH MAXSYH=DXSIZE RMONSZ = . + MAXSYH - $RMON + 777 / 1000 ;RMON LENGTH IN BLOCKS RMSIZE = RMONSZ * 1000 ;RMON LENGTH IN BYTES RMLEN = RMONSZ * 400 ;RMON LENGTH IN WORDS RT11SZ = KMONSZ + USRSZ + RMONSZ ;NUMBER OF BLOCKS IN ALL OF RT-11 RTSIZE = RT11SZ * 1000 ;SIZE OF RT-11 IN BYTES RTLEN = RT11SZ * 400 ;SIZE OF RT-11 IN WORDS FILLER= RT11SZ*1000-<.-KMON+MAXSYH> ;AMOUNT TO FILL TO PLACE THE ;KMON OVERLAYS ON A BLOCK .CSECT SYSHND ; SYSTEM HANDLER FITS IN THIS CSECT . = . + MAXSYH + FILLER .IIF DF NLRMON, .LIST .NLIST ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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 ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE ; OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DIGITAL. .LIST .IIF DF NLOVLY, .NLIST ;UPDATE LEVEL 18 .SBTTL KMON OVERLAYS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO BEGINS A NEW KMON OVERLAY BLOCK ; IF NOT THE FIRST BLOCK, IT ROUNDS UP TO BLOCK BOUNDARY ; IT THEN INCREMENTS THE OVERLAY NUMBER, STARTS A NEW CSECT, ; AND DEFINES OVLYST TO BE THE BLOCK START .MACRO OVERLAY .IF GE OVLYN .IIF GT <.-OVLYST>-<1000*OVLYSZ>, .ERROR ;PREVIOUS OVERLAY TOO LARGE .=OVLYST+<1000*OVLYSZ> .ENDC OVLYN=OVLYN+OVLYSZ .IRP N,<\OVLYN> .CSECT OVLY'N .ENDR OVLYST=. .ENDM OVERLAY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO STARTS A KMON OVERLAY COMMAND ; IT DEFINES N.CMD TO BE THE BLOCK NUMBER OF THE MONITOR FILE ; IN WHICH THE COMMAND RESIDES, AND O.CMD TO BE THE (WORD) ; OFFSET IN THE BLOCK AT WHICH THE COMMAND STARTS .MACRO OVCMD CMD N.'CMD=OVLYN+RT11SZ+SWAPSZ O.'CMD=.-OVLYST CMD: .ENDM OVCMD ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS MACRO GENERATES A CALL FR@M AN OVERLAY TO THE OUTSIDE WORLD ; IT COMPUTES THE PC-RELATIVE OFFSET FROM WHERE THE JSR WOULD ; BE IF THIS BLOCK WERE ACTUALLY IN THE KMON OVERLAY AREA .MACRO OJSR R,DEST JSR R,-<.+4-OVLYST>(PC) .ENDM OJSR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THESE MACROS ARE USED TO ACCESS LOCATIONS OUTSIDE THE OVERLAY ; REGION. THEY COMPUTE THE PC-RELATIVE ADDRESS AS IF THE INSTRUCTION ; WERE IN THE KMON OVERLAY AREA. .MACRO OCMP SRC,R CMP -<.+4-OVLYST>(PC),R .ENDM OCMP .MACRO OMOV SRC,R MOV -<.+4-OVLYST>(PC),R .ENDM OMOV .MACRO OADD SRC,R ADD -<.+4-OVLYST>(PC),R .ENDM OADD .MACRO OJMP DEST JMP -<.+4-OVLYST>(PC) .ENDM OJMP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS PERFORMS AN ADDR MACRO FROM AN OVERLAY BLOCK OF AN ADDRESS ; OUT IN THE REAL WORLD .MACRO OADDR ADR,REG,PUSH .IF IDN REG,SP MOV PC,-(SP) ADD #-<.-OVLYST>,(SP) .IFF .IF B PUSH MOV PC,REG .IFF JSR REG,(PC) .ENDC ADD #-<.-OVLYST>,REG .ENDC .ENDM OADDR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;DV15 ; THIS MACRO ALLOWS ACCESS TO THE INTON AND INTOFF ROUTINES ;DV15 ; LOCATED IN RMON, PERMITTING OVERLAYS TO ENABLE AND DISABLE ;DV15 ; INTERRUPTS. ;DV15 .MACRO OINTON ABC ;DV15 CLR -(SP) ;DV15 JSR PC,ABC ;DV15 .ENDM OINTON ;DV15 .MACRO OINTOF ABC ;DV15 MOV #PR7,-(SP) ;DV15 JSR PC,ABC ;DV15 .ENDM OINTOF ;DV15 .SBTTL DATE ; "THIRTY DAYS HATH SEPTEMBER, ; APRIL, JUNE, AND NOVEMBER; ; ALL THE REST HAVE THIRTY-ONE, ; EXCEPTING FEBRUARY ALONE, ; AND THAT HAS TWENTY-EIGHT DAYS CLEAR ; AND TWENTY-NINE IN EACH LEAP YEAR." ; - RICHARD GRAFTON,"ABRIDGEMENT OF THE CHRONICLES OF ENGLAND" OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS OVCMD DATE .ENABL LSB ADDR MONTHS,R4 ;POINT TO ASCII MONTH NAMES MOV @#SYSPTR,R0 ;POINT TO MONITOR TSTB -1(R5) ;WANT TO PRINT IT ? BEQ 10$ ;YAH CLR R1 ;CLEAR DATE ACCUMULATOR JSR R3,NUMK ;GET DAY IN R1 .BYTE 0.,31.-0. SWAB R1 ;PUT IT IN PLACE ASR R1 ASR R1 ASR R1 INC R5 ;FIX AND MOV R5,R3 ;SAVE PTR TO -MON-YY 1$: ADD #2000,R1 ;BUMP DATE TO NEXT MONTH TSTB 1(R4) ;END OF LIST ? BEQ 90$ ; DRAT MOV R3,R5 ;POINT R5 TO GIVEN -MON- MOV R4,R2 ;COPY PTR INTO LIST CMP (R4)+,(R4)+ ;ADVANCE FOR NEXT TIME 2$: CMPB -(R5),(R2)+ ;OK SO FAR ? BNE 1$ ;NO, TRY NEXT MONTH CMP R2,R4 ;DONE 5 ? BLOS 2$ ;KEEP TRYING JSR R3,NUMK ;A MATCH! ADD IN YEAR .BYTE 72.,99.-72. MOV R1,$DATE-$RMON(R0) 9$: RTS PC 10$: MOV $DATE-$RMON(R0),R2 ;GET THE DATE BIT #37,R2 ;IS THERE A DATE PRESENT? ;DV5 BEQ 90$ ;NONE. DO NOT PRINT IT 11$: MOV @SP,R0 ;GET TOP VALUE MOV R2,-(SP) ;MAKE IT 3 5-BIT FIELDS BIC #177740,(SP) ASR R2 ASR R2 ASR R2 ASR R2 ASR R2 BNE 11$ JSR PC,R10ONF ;PRINT IT DEC @SP ;INDEX INTO TABLE ASL @SP ASL @SP ADD (SP)+,R4 ;R4 POINTS TO -MMM- MOV #5,R2 ;5 CHARS 12$: .TTYOUT (R4)+ DEC R2 BNE 12$ TST (SP)+ ;PURGE DAY MOV (SP)+,R0 ;GET YEAR ADD #72.,R0 ; (REL 1972) JSR PC,R10OUT ;PRINT IT K0CRLF: OJMP KCRLF ;PRINT CR LF 90$: KMEROR NUMK: OJSR PC,DECNUM ;GET A NUMBER MOVB (R3)+,R2 ;GET LOW LIMIT SUB R2,@SP ;DECREASE NUMBER BLE 90$ ;TOO BAD MOVB (R3)+,R2 ;GET UPPER LIMIT CMP @SP,R2 ;TOO BIG ? BGT 90$ ADD (SP)+,R1 ;ADD IT IN RTS R3 .DSABL LSB .SBTTL TIME OVCMD TIME .ENABL LSB MOV @#SYSPTR,R0 ;CHECK FOR EXISTANCE OF CLOCK ADD #CONFIG-$RMON,R0 ;POINT TO CONFIGURATION WORD TST @R0 ;DID THE BOOTSTRAP FIND A CLOCK? BPL 91$ ;NO, TELL HIM SO BIT #CLK50$,@R0 ;IS IT A 50-CYCLE CLOCK? BEQ 101$ ;NO, 60 CYCLES MOVB #50.,11$ ;YES, SET 50 CYCLES MOVB #50.,CLKFRQ .IF NE BF MOV #101,GTM.HI-CONFIG(R0) ;# OF 50 CYCLE TICKS MOV #165400,GTM.LO-CONFIG(R0) ;IN A DAY .ENDC 101$: ADDR TMRLST,R3 ;POINT TO LIST MOV R3,R0 ;COPY POINTER TO .GTIM AREA MOV R3,-(R0) ;PUT IN ADDRESS TST -(R0) ;POINT TO PARAM BLOCK EMT 375 ;DO .GTIM TSTB -1(R5) ;WANT TO PRINT IT ? BEQ 10$ ;YAH CMP (R3)+,(R3)+ CLR R1 ;TIMER ACCUMULATOR IS R1/@SP CLR -(SP) 1$: OJSR PC,DECNUM ;GET NEXT VALUE MOVB (R3)+,R4 ;GET MAXIMUM CMP R4,@SP ;TOO BIG ? BLOS 90$ ;YES CMPB @R5,(R3)+ ;PROPER DELIMITER ? BEQ 2$ ;YES TSTB @R5 ;IS IT THE NULL BYTE ? BNE 90$ ;BAD SYNTAX INC R5 ;KEEP USING NULL 2$: ADD (SP)+,@SP ;ADD IN LOW ORDER ADC R1 ;BUBBLE TO HIGH ORDER MOVB @R3,R4 ;END OF TIME ? BEQ 4$ ;YES MOV R1,R2 ;NO. MULTIPLY TIME BY FACTOR MOV @SP,R0 ;COPY TIME TO R2/R0 3$: DEC R4 ;DONE MULTIPLY ? BEQ 1$ ;YES ADD R0,@SP ADC R1 ADD R2,R1 BR 3$ 4$: MOV @#SYSPTR,R0 .IF NE BF SUB TMRLST+2,@SP SBC R1 SUB TMRLST,R1 ADD (SP)+,$TIME+2-$RMON(R0) ;FIX TIM OF DAY ADC R1 ADD R1,$TIME-$RMON(R0) .IFF OINTOF 8$ ;TURN OFF INTERRUPTS ;DV15 MOV (SP),$TIME+2-$RMON(R0) ;PUT IT IN MONITOR MOV R1,$TIME-$RMON(R0) OINTON 8$ ;ENABLE INTERRUPTS ;DV15 TST (SP)+ .ENDC K0RTS: RTS PC ;GO BACK 8$: RTI ;DV15 10$: MOV (R3)+,R1 ;GET TIME OF DAY MOV (R3)+,R2 ;LOW ORDER IN R2 JSR R4,DIVIDE ;FIRST DIVIDE OUT THE TICKS/SECOND 11$: .WORD CLOCK MOV R5,R0 ;PUT -1 IN R0 FOR FLAG MOV #3,R3 ;LOOP 3 TIMES 12$: MOV R0,-(SP) ;SAVE REMAINDER (OR FLAG) JSR R4,DIVIDE ;DIVIDE BY 60. .WORD 60. DEC R3 ;LOOP BNE 12$ 13$: JSR PC,R10OUT ;PRINT THE NUMBER IN R0 MOV (SP)+,R2 ;GET NEXT VALUE BMI K0CRLF ;IF NEGATIVE, DONE .TTYOUT #': ;PUT OUT A SEPARATOR MOV R2,R0 ;COPY VALUE BR 13$ ;LOOP 90$: KMEROR 91$: KMEROR .DSABL LSB .SBTTL DECIMAL OUTPUT AND CONVERSION .ENABL LSB R10ONF: CMP #10.,R0 ;IS THE NUMBER ONE DIGIT? BHI 2$ ;YES, PUT IT OUT AS ONE R10OUT: SWAB R0 ;PUT NUMBER IN HIGH BYTE 1$: ADD #173001,R0 ;SUBTRACT 10 FROM HIGH, ADD 1 TO LOW BPL 1$ ;LOOP UNTIL OVERFLOW ADD #'0+<10.*400-1>,R0 ;FIX BOTH BYTES, ASCIIFY THE LOW .TTYOUT ;PRINT HIGH DIGIT SWAB R0 ;GET OTHER DIGIT 2$: ADD #'0,R0 ;ASCIIFY IT .TTYOUT RTS PC .DSABL LSB .IF NE BF ; THESE ARE LINKS TO OVERLAY COMMANDS WHICH ARE TOO FAR AWAY OVCMD SAVEK JMP OSAVE OVCMD ASSIGN JMP OASSIGN .ENDC DIVIDE: CLR R0 ;REMAINDER MOV #31.,R5 ;32. BITS 1$: ASL R2 ;DOUBLE PRECISION DIVIDE ROL R1 ROL R0 CMP R0,@R4 BLO 2$ SUB @R4,R0 INC R2 2$: DEC R5 BPL 1$ TST (R4)+ ;PUSH OVER RADIX RTS R4 MONTHS: .ASCIZ "-JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-" .BYTE 0,..GTIM .WORD 0 TMRLST: .WORD 0,0 .BYTE 24.,':,60.,':,60.,'. CLKFRQ: .BYTE CLOCK,377,0 .EVEN .SBTTL SAVE .IF EQ BF OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS OVCMD SAVEK .ENDC OSAVE: MOV #9.*400+8.,R4 ;COUNTERS IN R4 ADDR SAVBLK,R1 ;R1 -> INTERNAL COPY MOV @#USERTOP,(R1)+ ;SAVE A COPY OF THE TOP MOV @#SYSPTR,R3 ;R3 -> CCB IN RMON ADD #CCB-$RMON,R3 1$: MOV (R3)+,(R1)+ ;COPY A WORD DECB R4 BNE 1$ OJSR PC,GETHAN ;GET FILE NAME, HANDLER MOV R3,-(SP) ;SAVE POINTER TO FILE NAME TSTB @R5 ;IS IT EOL? BEQ DOSAVE ;YES, DO THE SAVE SWAB R4 ;GET COUNT OF 9 2$: CLR -(R1) ;CLEAR OUT TEMP CCB AND TEMP USERTOP DEC R4 BNE 2$ MOV R1,R3 ;R3 -> TEMP USERTOP 3$: TSTB @R5 ;END OF LINE? BEQ DOSAVE ;YES, NOW DO THE SAVE CMPB #' ,@R5 ;CHECK FOR ADDRESSES BEQ 103$ ;DELIMITED BY BLANK OR COMMA CMPB #',,@R5 BNE BADSAV ;NO, IT'S BAD 103$: JSR PC,SAVNUM ;GET A LOW ADDRESS MOV R4,R2 ;PUT IT IN R2 CMPB @R5,#'- ;IS IT A RANGE? BNE 4$ ;NO JSR PC,SAVNUM ;YUP, GET A HIGH ADDRESS CMP R4,R2 ;CHECK LEGALITY BLO BADSAV ;HIGH ADDRESS < LOW ADDRESS 4$: MOV R3,R0 ;COPY POINTER CMP (R0)+,R4 ;IS THIS THE LARGEST SO FAR? BHI 5$ ;NO MOV @#SYSPTR,R1 ;IS THIS TOO BIG FOR COMFORT? CMP R4,SYSLOW-$RMON(R1) BHIS BADSAV ;TRYING TO SAVE OUT OF RANGE MOV R4,@R3 ;SAVE TEMP USERTOP 5$: OJSR PC,NOTHIR ;SET BIT MAP (R0 -> TEMP BITMAP) BR 3$ ;AND TRY FOR MORE DOSAVE: OADDR KMON,R4 ;R4 -> KMON CLRB R4 ;ROUND DOWN TO A BLOCK BOUNDARY SWAB R4 ;MAKE IT A BLOCK COUNT ASR R4 MOV SAVBLK,R1 ;GET SAVE FILE'S USERTOP BEQ BADSAV ;CAN'T SAVE NOTHING CLRB R1 ;MAKE A BLOCK COUNT OF SAVE FILE SWAB R1 ASR R1 INC R1 ;DON'T FORGET THE LAST BLOCK MOV #3*400+17,R0 ;PURGE CH 17 EMT 374 .ENTER 17,(SP)+,R1 ;ENTER A FILE OF THE RIGHT SIZE BCS SAVERR ;OOPS, NO ROOM SUB R4,R1 ;R1 = COUNT OF BLOCKS IN SCRATCH AREA BPL 21$ ;THERE'S SOMETHING THERE ADD R1,R4 ;IT'S SHORTER THAN SCRATCH, ADJUST R4 21$: MOV #1000,R0 ;NOW COPY BLOCK 0 TO THE USR BUFFER OMOV .USRTOP,R3 CLR @<.BLKEY-OVLY>-<.+4-OVLYST>(PC) ;THE BUFFER IS DEAD 22$: MOV -(R0),-(R3) ;COPY IT TST R0 ;DOWN TO THE BEGINNING BNE 22$ ADDR SAVBLK,R2 ;POINT TO TEMP AREA MOV (R2)+,USERTOP(R3) ;PUT IN THE PROPER TOP ADDRESS MOV R3,R5 ;R3 -> USR BUFFER ADD #360,R5 ;R5 -> CCB IN USR BUFFER MOV #8.,R0 ;COUNT TO MOVE 23$: MOV (R2)+,(R5)+ DEC R0 BNE 23$ .WRITW 17,R3,#400 ;WRITE THE USR BUFFER AS BLOCK 0 (R0=0) BCS SAVERR ;OOPS DEC R4 ;COUNT DOWN BLOCKS TO DO BLE 40$ ;DONE ALREADY! CLR -(SP) ;WAIT I/O MOV R4,-(SP) ;BLOCK COUNT TO DO FROM IN CORE SWAB @SP ;WORD COUNT MOV #1000,-(SP) ;ADDRESS TO START WRITING MOV #1,R0 ;START AT BLOCK 1 EMT 220+17 ;WRITE BCS SAVERR ;OOPS CLR R3 ;CLEAR SCRATCH AREA BLOCK NUMBER 30$: DEC R1 ;ANY MORE TO DO IN SCRATCH AREA? BMI 40$ ;NO CLR -(SP) ;WAIT I/O MOV #1000,-(SP) ;NORMALLY DO 2 BLOCKS DEC R1 ;BUT IF ONLY ONE IS LEFT BPL 31$ ; THEN ASR @SP ; ONLY DO ONE 31$: OADDR SYSIOB+2,R5 ;R5 -> IOB FOR SCRATCH AREA MOV @SP,@R5 ;INSERT PROPER READ LENGTH MOV -(R5),-(SP) ;SAVE ADDRESS OF BUFFER MOV R3,R0 ;R3 HAS SYSTEM SCRATCH BLOCK # OJSR PC,SYSK ;DO THE READ MOV R4,R0 ;R4 = BLOCK NUMBER IN SAVE FILE EMT 220+17 ;WRITE BCS SAVERR ;OOPS TST (R3)+ ;BUMP SCRATCH BLOCK # BY 2 CMPB (R4)+,(R4)+ ;BUMP SAVE FILE BLOCK # BY 2 BR 30$ ;AND LOOP 40$: .CLOSE 17 ;DONE RTS PC ;SAY GOODBYE SAVNUM: MOV R5,-(SP) ;SAVE POINTER DEC @SP OJSR PC,OCTNUM ;GET A NUMBER MOV (SP)+,R4 ; IN R4 CMP (SP)+,R5 ;GOT ANYTHING? BEQ BADSAV ;NO, ERROR RTS PC BADSAV: KMEROR SAVERR: OJMP SFERR ;DO A SAVE FILE ERROR SAVBLK: .BLKW 9. .SBTTL ASSIGN .IF EQ BF OVCMD ASSIGN .ENDC .ENABL LSB OASSIGN:MOV #$SLOT,R1 ;SIZE OF SYSTEM TABLES OADDR BLOCK,R2 ;POINTER TO FD BLOCK MOV @#SYSPTR,R4 ;R4 -> RMON OJSR PC,GETNAM ;GET SYSTEM PERM NAME BEQ 10$ ;NONE. DO A DEASSIGN OF ALL 20$: TST (R2)+ ;SKIP SYSTEM NAME TSTB @R5 ;END OF COMMAND? BEQ HANERK ;YES, ILLEGAL COMMAND OJSR PC,GETNAM ;GET USER ASSIGNED NAME BEQ HANERK ;CAN'T HAVE NULL USER NAME MOV -2(R2),R5 ;SEARCH $PNAME FOR PERM NAME BEQ 4$ ;NO PERM NAME, DO A DEASSIGN ;DV3 MOV R4,R0 ;COPY PTR TO RMON ADD #$PNAME-$RMON,R0 ;R0 -> $PNAME TABLE 1$: MOV R5,R3 ;COPY SEARCH OBJECT SUB (R0)+,R3 ;IS PERM NAME IN THIS GROUP? BLO 2$ ;PERM NAME WAS TOO BIG BEQ 4$ ;EXACT MATCH SUB (PC)+,R3 ;IS IT DV0-DV7 ? .RAD50 / 0/ BLO 2$ ;NO CMP R3,#7 BLOS 4$ ;YES IT IS 2$: DEC R1 ;ANY MORE TO TRY ? BNE 1$ ;YES ;CAN'T PLACE HIS PERM NAME HANERK: OJMP BADHAN ; 4$: MOV #$SLOT,R1 ;FOUND VALID NAME. PUT USER'S ADD #$UNAM2+<2*$SLOT>-$RMON,R4 ;POINT TO TOP OF TABLE ;OF USER NAMES. CLR R3 ;R3 WILL POINT TO FIRST NULL SLOT 5$: CMP (R2),-(R4) ;FIND THIS USER NAME IF IT IS BEQ 8$ ; ALREADY ASSIGNED TST (R4) ;ELSE SEE IF 0 ENTRY BNE 6$ ; AND IF SO MOV R4,R3 ; REMEMBER IT 6$: DEC R1 ;ANY MORE? BNE 5$ ;YES TST R5 ;WERE WE WANTING TO CLEAR USER NAME ? BEQ HANERK ;YES, BUT THERE WASN'T ONE THERE MOV R3,R4 ;NO, WANT TO SET IT. SLOT HANDY? BEQ HANERK ;NO ROOM IN TABLE MOV @R2,@R4 ;PUT USER NAME IN TABLE 7$: MOV R5,$UNAM1-$UNAM2(R4) ;PUT PERM NAME IN TABLE RTS PC 8$: TST R5 ;FOUND USER NAME. SET PERM OR CLR USER? BNE 7$ ;GO SET PERM NAME CLR @R4 ;CLEAR THE USER NAME RTS PC 10$: TSTB @R5 ;WAS THE LINE NULL? BNE 20$ ;NO, GET USER NAME TO BE DEASSIGNED ADD #$UNAM2-$RMON,R4 ;POINT TO USER NAMES 11$: CLR (R4)+ DEC R1 BNE 11$ RTS PC .DSABL LSB .SBTTL LOAD OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS .IF NE BF OVCMD UNLOAD JMP UNLDIN OVCMD SPND TST (PC)+ ;CLEAR THE CARRY OVCMD RSUME SEC ;SET THE CARRY JMP SPNRSU ;ENTER SUSPEND/RESUME CODE OVCMD CLOSEK JMP CLOSEO OVCMD FRUN JMP OFRUN .ENDC .IIF NDF BANDW, .NLIST .IF DF BANDW OVCMD TECO JMP TECOO OVCMD MAKE JMP MAKEO .ENDC .IIF NDF BANDW, .LIST OVCMD LOAD .ENABL LSB 23$: OADDR DEVSTS,R2 ;POINT TO BUFFER AREA OJSR PC,GETNAM ;GET DEVICE NAME JSR PC,MAPIT ;MAP USER NAME TO PHYSICAL NAME CLR FTEMP .IF NE BF CLR R3 ;INIT JOB TO NOT OWNED CMPB #'=,(R5) ;ASSIGN COMING UP? BNE 20$ ;NO, SET TO UNOWNED CMPB #'B,-(R5) ;BACKGROUND? BEQ 8$ ;YES CMPB #'F,(R5) ;FOREGROUND JOB? BNE IMSG3 ;NO, ERROR TST (R3)+ ;SET JOB # 1 ; AT THIS POINT COULD TEST NEXT DIGIT FOR MULTIPLE FOREGROUND JOBS. 8$: INC R3 ;SET UP JOB ID DEC R5 ;SKIP OVER B OR F .ENDC 20$: MOV (R2),-(SP) ;SAVE DEVICE NAME .DSTAT R2,R2 ;GET STATUS BCS IMSG1 ;ERROR TST 4(R2) ;ALREADY RESIDENT? .IF NE BF BNE 5$ ;YES .IFF BNE 19$ ;ALREADY LOADED .ENDC MOV (SP)+,@R2 ;NAME TO BUFFER ; GET SIZE OF THE HANDLER, THEN ALLOCATE CORE AND FETCH IT. MOV 2(R2),R0 ;R0 = HANDLER SIZE MOV R2,-(SP) ;SAVE BUFFER ADDRESS MOV R3,-(SP) ;SAVE JOB NUMBER MOV SP,@<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;INHIBIT CTRL/C ;DV12 JSR PC,GETBLK ;GET CORE FOR HANDLER MOV (SP)+,R3 ;RESTORE JOB # BCC 3$ ;WAS KMON MOVED? SUB R0,R5 ;YES, RELOCATE SOME SUB R0,2(SP) ;ADDRESSES. SUB R0,(SP) 3$: MOV (SP),R0 ;POINT TO NAME AGAIN .FETCH R4 ;GET HANDLER IN CORE BCS IMSG0 ;ERROR, NO HANDLER MOV R4,FTEMP ;SAVE CORE PTR FOR ;RECOVERY ON ERROR ; PROTECT THE VECTORS OF THE NEWLY-LOADED DEVICE HANDLER. MOV @R4,R2 ;GET VECTOR ADDRESS BEQ 4$ ;NONE TO PROTECT MOV #1,R4 ;PROTECT TWO WORDS MOV @#SYSPTR,R0 ;POINT TO MAP BLOCK ADD #LOWMAP-$RMON,R0 ;TURN ON BITS OJSR PC,SETBT2 ;BY CALLING SETBIT 4$: .IF EQ BF BR 19$ .IFF MOV (SP)+,R2 ;POINT TO BUFFER AGAIN BR 20$ ;GET STATUS AGAIN ; NOW SEARCH $ENTRY FOR ALL DEVICES HAVING ENTRY POINTS ; MATCHING THE REQUESTED DEVICE'S ENTRY POINT. 5$: OMOV .$ENTR,R0 ;R0 -> $ENTRY TABLE CLR R1 ;CLEAR INDEX 6$: CMP 4(R2),(R0)+ ;ENTRY POINTS MATCH? BEQ 7$ ;YES, R1 NOW INDEX TO $PNAME 22$: TST (R1)+ ;NO, BUMP INDEX 2 CMP R1,#$SLOT*2 ;THRU THE TABLE? BLT 6$ ;NO, CONTINUE .ENDC IMSG2: MOV FTEMP,R4 ;R4 -> CORE ALLOC., IF ANY BEQ IMSG3 ;NONE, JUST MESG JSR PC,PUTBLK IMSG3: OJMP BADCOM ; IMSG0: JSR PC,PUTBLK ;RETURN TO FREE CORE LIST IMSG1: OJMP BADHAN .IF NE BF ; GET DEVICE UNIT # FROM SPECIFIED DEVICE NAME 7$: OMOV .$PNAM,-(SP) ;SP -> $PNAME TABLE ADD R1,(SP) ;(SP) -> SLOT IN $PNAME MOV 2(SP),R4 ;R4 = DEV. NAME/UNIT RAD50 SUB @(SP)+,R4 ;R4 = UNIT # RAD50 BEQ 9$ ;EXACT MATCH => UNIT 0 SUB (PC)+,R4 ;R4 = UNIT # OCTAL .RAD50 / 0/ CMP R4,#7 ;NO, UNIT > 7? BHI 22$ ;YES, TRY ANOTHER ; GOT UNIT NUMBER IN R4. NOW CHECK TO SEE IF IT IS THE SYSTEM ; UNIT OF THE SYSTEM DEVICE TYPE, WHICH CANNOT BE ATTACHED. 9$: MOV @#SYSPTR,R0 CMP 4(R2),R0 ;SYSTEM DEVICE? .DSABL LSB .ENABL LSB BLO 10$ ;NO, GO ON CMP SYUNIT-$RMON(R0),R4 ;YES, SYSTEM UNIT? BEQ IMSG1 ;YES, CAN'T ATTACH ; NOW THAT THE UNIT # IS KNOWN, A MASK CAN BE SET UP AND ; THE JOB ID PREPARED FOR INSERTION IN THE $OWNER TABLE. 10$: TST @R2 ;FILE STRUCTURED DEV? BPL 12$ ;NO MOV #17,FTEMP ;SET MASK FOR EVEN UNIT CLC ROR R4 ;UNIT/2 =BYTE # OF $OWNER BCC ESRCH ;C=1 IF ODD UNIT ASL R3 ;MOVE JOB ID CODE ASL R3 ;TO HIGH HALF BYTE ASL R3 ASL R3 MOV #360,FTEMP ;SET MASK FOR HIGH HALF BYTE BR ESRCH ; FOR NON-FILE STRUCTURED DEVICES, ALL UNITS ARE ASSIGNED ; TO THIS JOB. 12$: TST R3 ;UNASSIGNED? BEQ ESRCH ;YES, GO ON DEC R3 ;F OR B? BEQ 13$ ;MUST BE B MOV #21042,R3 ;ASSIGN ALL UNITS 13$: ADD #10421,R3 ; NOW SEARCH $ENTRY FOR ALL ENTRIES MATCHING THE SPECIFIED ; DEVICE ENTRY AND ASSIGN OWNERSHIP TO THEM. ESRCH: OMOV .$ENTR,R0 ;R0 -> $ENTRY CLR R1 ;INIT INDEX 15$: CMP 4(R2),(R0)+ ;ENTRIES MATCH? BEQ 16$ 22$: CMP (R1)+,(R1)+ ;BUMP INDEX BY 4 SINCE ;$OWNER HAS 2 WD ENTRIES CMP R1,#$SLOT*4 ;THRU THE TABLE? BLT 15$ ;DO SOME MORE BR 19$ ;YES, ALL DONE ; DETERMINE THE CORRECT HALF BYTE IN $OWNER TO SET THE ; OWNERSHIP INFORMATION. IN THE CASE OF NON-FILE STRUCTURED ; DEVICES ALL 8 UNITS ARE SET TO THE SAME OWNER. 16$: MOV R1,-(SP) ;SAVE INDEX OADD .$OWNE,R1 ;R1 -> $OWNER TABLE TST @R2 ;IS DEV FILE-STRUCTURED? BPL 18$ ;NO,SKIP THIS JAZZ ADD R4,R1 ;R1 -> BYTE TO MODIFY BICB FTEMP,(R1) ;CLEAR OWNERSHIP BISB R3,(R1) ;INSERT NEW OWNER 17$: MOV (SP)+,R1 ;RESTORE INDEX TO R1 BR 22$ ;DO ANOTHER 18$: MOV R3,(R1)+ ;SET ALL UNITS OWNED MOV R3,@R1 BR 17$ .ENDC 19$: TST (SP)+ ;CLEAR STACK CLR @<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;ENABLE CTRL/C ;DV12 TSTB (R5) ;END OF COMMAND STRING? BNE 21$ ;NO, MORE TO COME RTS PC ;YES, EXIT 21$: JMP LOAD .DSABL LSB FTEMP: .WORD 0 ;TEMPORARY STORE ; SUBROUTINE MAPS USER ASSIGNED DEVICE NAME TO PHYSICAL ; DEVICE NAME. ; ; R2 -> USER NAME (RAD50) ; R1,R3 DESTROYED MAPIT: OMOV .$UNAM,R1 ;R1 -> ASSIGN TABLE MOV #$SLOT+3,R3 ;R3 = # DEV. SLOTS + 3 1$: DEC R3 ;THRU THE TABLE? BEQ 2$ ;YES CMP (R2),(R1)+ ;FOUND A MATCH? BNE 1$ ;NO, TRY ANOTHER MOV $UNAM1-$UNAM2-2(R1),(R2) ;YES, REPLACE IT 2$: RTS PC ; GETBLK -- SUBROUTINE TO SEARCH FREE CORE LIST FOR A BLOCK EQUAL ; TO REQUESTED SIZE. IF NOT IN FREE CORE LIST, KMON/USR IS ; MOVED DOWN TO CREATE THE BLOCK. C IS SET IF KMON/USR WAS MOVED. ; ; CALL SEQUENCE: JSR PC,GETBLK ; R0=# BYTES DESIRED ; ; RETURNS WITH: R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (1ST WORD OF BLK) ; ; R1,R3 DESTROYED ; GETBLK: TST (R0)+ ;ADD 2 BYTES TO REQUEST OMOV .CORPT,R3 ;R3 -> FREE CORE LIST HEAD 1$: MOV 2(R3),R4 ;R4 -> NEXT FREE BLOCK OCMP .CORPT,R4 ;END OF LIST? BEQ 4$ ;YES, BACK AT LIST HEAD CMP (R4),R0 ;THIS BLOCK BIG ENOUGH? BGE 2$ ;YES, USE IT. MOV R4,R3 ;NO, TRY NEXT BLOCK BR 1$ 2$: SUB R0,(R4) ;BLK SIZE - REQUEST SIZE BNE 3$ ;EXACTLY THE SAME? MOV 2(R4),2(R3) ;YES, REMOVE FROM LIST 3$: ADD (R4),R4 ;R4 -> START OF BLOCK CLC BR 5$ ;GO EXIT 4$: SUB R0,(SP) ;RELOCATE RETURN ADDR. NEG R0 ;-SIZE => MOVE KMON DOWN ROR R0 ;HALVE IT, C=1 SO IT IS <0 OJSR PC,KUMOVE ;CALL TO MOVE KMON/USR NEG R0 ;FIX R0, SET CARRY 5$: MOV R0,(R4)+ ;STORE SIZE IN FIRST WORD RTS PC ; PUTBLK -- RETURNS A BLOCK OF CORE TO THE FREE CORE LIST. ; MERGES CONTIGUOUS BLOCKS OF CORE INTO A SINGLE BLOCK. ; RECLAIMS CORE FROM BLOCKS CONTIGUOUS TO KMON/USR BY ; SLIDING UP KMON/USR. C IS SET IF KMON/USR WAS MOVED. ; ; CALL SEQUENCE: JSR PC,PUTBLK ; ; R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (IN 1ST WORD OF BLK) ; ; R0,R1 DESTROYED ; PUTBLK: TST -(R4) ;POINT TO BLOCK SIZE IN 1ST WD. OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD 1$: MOV 2(R0),R1 ;R1 -> NEXT FREE BLOCK OCMP .CORPT,R1 ;LAST BLOCK IN LIST? BEQ 3$ ;YES, INSERT NEW BLOCK HERE CMP R1,R4 ;NO, NEXT BLOCK HIGHER IN CORE? BHI 2$ ;YES, INSERT BLOCK HERE MOV R1,R0 ;NO, R0 -> CURRENT BLOCK BR 1$ ;CONTINUE SEARCH ; UPPER BOUNDARY CHECK FOR CONTIGUOUS BLOCKS 2$: MOV R4,-(SP) ;COMPUTE ADDR OF END OF ADD (R4),(SP) ;NEW BLOCK OF CORE. CMP (SP)+,R1 ;TOUCHES NEXT BLOCK? BNE 3$ ;NO, CAN'T MERGE ADD (R1),(R4) ;YES, MERGE THE TWO MOV 2(R1),2(R4) ;BLOCKS INTO ONE. BR 4$ ;THE CHECK LOWER BOUND. 3$: MOV R1,2(R4) ;JUST LINK IN NEW BLK ; LOWER BOUND CHECK FOR CONTIGUOUS BLOCKS 4$: MOV R0,-(SP) ;IS NEW BLOCK CONTIGUOUS ADD (R0),(SP) ;WITH LOWER BLOCK? CMP (SP)+,R4 ;COMPARE BOUNDS BEQ 5$ ;CONTIGUOUS, SO MERGE THEM MOV R4,2(R0) ;NO, JUST LINK TO LOWER BR 6$ ;THEN GO ON 5$: ADD (R4),(R0) ;ADD SIZES TOGETHER MOV 2(R4),2(R0) ;AND RE-LINK THE LIST. ; CORE RECLAIM CHECK 6$: OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD MOV 2(R0),R1 ;R1 -> LOWEST FREE BLOCK MOV @<.SYSLO-OVLY>-<.+4-OVLYST>(PC),-(SP) CMP (SP)+,R1 ;CONTIGUOUS TO USR? CLC BNE 7$ ;NO, JUST EXIT BIT (R1)+,(R0)+ ;BUMP R1, R0, LEAVE C=0 MOV (R1),(R0) ;REMOVE FROM LIST MOV -(R1),R0 ;SIZE IN R0 ROR R0 ;HALVE IT, LEAVE > 0 OJSR PC,KUMOVE ;THEN SQUISH IT ADD R0,(SP) ;RELOCATE RETURN ADDRESS SEC 7$: RTS PC ;AND EXIT .SBTTL UNLOAD .IF EQ BF OVCMD UNLOAD .ENDC .ENABL LSB UNLDIN: OADDR DEVSTS,R2 ;POINT TO NAME BLOCK OJSR PC,GETNAM ;GET DEVICE NAME BEQ 23$ ;NULL NAME? MOV R2,R0 ;R0 -> NAME BLOCK MOV R5,-(SP) ;SAVE PLACE IN COMMAND MOV @#SYSPTR,R5 ;POINT TO RMON .IF NE BF MOV FCNTXT-$RMON(R5),R4 ;POINT TO CONTEXT BEQ 1$ ;NOPE, NO JOB IN CORE BIT #NORUN$,@R4 ;IS IT STILL ALIVE? BEQ FJERR ;YES, CAN'T TOUCH ANYTHING! 1$: CMP @R2,(PC)+ ;IS IT A SPECIAL UNLOAD FG? .RAD50 /FG / BEQ 30$ ;YES, GO UNLOAD THE FG .ENDC JSR PC,MAPIT ;MAP NAME TO PHYSICAL NAME CMP @R2,(PC)+ ;TRYING TO UNLOAD BATCH? .RAD50 /BA / BNE 2$ ;NO, SAFE TO PROCEDE CMP LST16-$RMON(R5),#T$TIN-LST16 ;IS BATCH STILL HOOKED IN? BNE 22$ ;YES, A WISE GUY! 2$: OJSR R4,LK4DEV ;LOOK FOR DEVICE BR 22$ ;ERROR DURING SEARCH MOV @R5,R4 ;HANDLER RESIDENT? BEQ 20$ ;NO, NOTHIN TO DO CLR R1 ;INITIALIZE INDEX OMOV .$ENTR,R0 ;R0 -> $ENTRY TABLE 3$: CMP R4,@R0 ;ENTRIES MATCH? BNE 4$ ;NO, TRY THE NEXT MOV SP,@<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;INHIBIT CTRL/C ;DV12 .IF NE BF MOV R1,R3 ;YES, GET INDEX OADD .$OWNE,R3 ;R3 -> SLOT IN $OWNER CLR (R3)+ ;CLEAR ALL OWNERSHIP CLR @R3 ;FROM 8 UNITS .ENDC CMP @#SYSPTR,@R0 ;IS DEVICE THE SYSTEM DEV? BLOS 4$ ;YES, LEAVE IT BE CLR @R0 ;ZERO ENTRY 4$: TST (R0)+ ;BUMP TO NEXT DEVICE CMP (R1)+,(R1)+ ;BUMP OWNER INDEX BY 4 BYTES CMP R1,#$SLOT*4 ;THRU THE TABLE? BLT 3$ ;NO, DO ANOTHER ; NOW ELIMINATE THE HANDLER, RETURNING CORE TO THE FREE LIST. CMP @#SYSPTR,R4 ;SYSTEM DEVICE? BLOS 20$ ;YES, SKIP THIS CMP -(R4),-(R4) MOV -(R4),R0 ;R0 = HANDLER VECTOR ADDR CLR (R0)+ ;CLEAR VECTOR AND PRIORITY CLR (R0) JSR PC,PUTBLK ;RETURN TO LIST BCC 20$ ;KMON/USR MOVED? ADD R0,(SP) ;YES, RELOC. SOME PTRS. ADD R0,2(SP) ; DONE WITH THIS DEVICE - IS THERE ANOTHER? 20$: MOV (SP)+,R5 ;R5 -> COMMAND LINE 21$: CLR @<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;ENABLE CTRL/C ;DV12 TSTB (R5) ;MORE COMING? BNE UNLDIN ;YES RTS PC ;NO, JUST EXIT NOHAN: ;DV12 22$: OJMP BADHAN ; 23$: OJMP BADCOM ; .DSABL LSB .IF NE BF ; THIS CODE UNLOADS AN INACTIVE FOREGROUND JOB THAT HAS ; BEEN ABORTED AND IS JUST LAYING AROUND. IT CLEARS OUT ; THE NECESSARY RMON POINTERS AND RECLAIMS THE CORE FOR USE ; BY THE SYSTEM. 30$: TST R4 ;F JOB IN CORE BEQ NOFERR ;NO, CAN'T DO IT MOV SP,@<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;INHIBIT CTRL/C ;DV12 CLR FCNTXT-$RMON(R5) ;MAKE THE FG VANISH BIC #FJOB$,CONFIG-$RMON(R5) ;SAY NO FG JOB JSR PC,PUTBLK ;THROW THE BUM OUT BCC 20$ ;NOTHING MOVED ADD R0,2(SP) ;FIX RETURN ADDRESS TO MONITOR ADD R0,@SP ;RECOVER AND RELOCATE R5 BR 20$ ;CONTINUE COMMAND NOFERR: KMEROR FJERR: KMEROR .ENDC .SBTTL CLOSE .IF EQ BF OVCMD CLOSEK .ENDC CLOSEO: OADDR HANDLR,R5 ;POINT R5 TO HANDLER SPACE OMOV .$CSW,R2 ;POINT TO CHANNEL TABLE MOV (PC)+,R4 ;SET UP CHANNEL 0 CLOSE .CLOSE 0 ;PROTOTYPE CLOSE 1$: MOV @R2,R0 ;TEST IF A FILE EXISTS ON CHANNEL BPL 3$ ;>0 IMPLIES NO FILE THERE BIC #177701,R0 ;ISOLATE INDEX . ADD @#SYSPTR,R0 ;POINT TO PERMANENT NAME ADD #$PNAME-$RMON,R0 MOV R0,-(SP) ;SAVE POINTER TO DEVICE NAME .FETCH R5 ;RE-FETCH DEVICE REQUIRED BCS NOHAN ;HANDLER FETCH FAILED ;DV12 2$: MOV R4,(PC) ;SET UP THE EMT ;DV12 HALT ;GETS A CLOSE EMT MOV (SP)+,R0 ;POINT TO DEVICE AGAIN .RELEASE ;MAKE IT VANISH 3$: INC R4 ;NEXT CHANNEL ADD #12,R2 ;POINT TO NEXT CHANNEL CMP R4,(PC)+ ;DONE YET ? .CLOSE 20 BLO 1$ ;NO .SRESET ;CLEAR OUT ALL HANDLERS AGAIN RTS PC ;AND RETURN ;CLSERR: KMEROR ;DV12 .IIF NDF BANDW, .NLIST .IF DF BANDW .IF NE BF TECOO: TST (PC)+ ;CLEAR CARRY MAKEO: SEC ;SET THE CARRY MOV #510,R0 ;POINT TO PARAMETER AREA MOV R0,R1 ;COPY IT 1$: MOVB -(R5),(R0)+ ;MOVE IN THE FILE NAME BNE 1$ RORB -(R0) ;SET MAKE INDICATOR BPL 2$ ;IF NOT "MAKE", SKIP LOVELY TEST CMP (R1)+,(PC)+ .ASCII "LO" BNE 2$ CMP (R1)+,(PC)+ .ASCII "VE" BNE 2$ CMP R0,R1 BHI 2$ ADDR 10$,R0 ;IT'S LOVE .PRINT 2$: ADDR 11$,R1 ;POINT TO FILE TO CHAIN MOV @#SYSPTR,R2 ;TEST FOR DISPLAY HARDWARE BIT #HWDSP$,CONFIG-$RMON(R2) BEQ 3$ ;NONE, USE TECO MOV #3*400+17,R0 ;PURGE CH 17 EMT 374 ;NO ERRORS POSSIBLE .LOOKUP 17,R1 ;DO WE HAVE GTECO? BCC 4$ ;YES. USE IT 3$: ADD #12$-11$,R1 ;USE TECO 4$: .SRESET ;RESET ALL MOV #500,R0 ;MOVE IN FILE NAME MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV #10*400,R0 ;CHAIN AWAY EMT 374 10$: .ASCIZ /NOT WAR?/ .EVEN 11$: .RAD50 /SY GTECO SAV/ 12$: .RAD50 /SY TECO SAV/ .ENDC .ENDC .IIF NDF BANDW, .LIST .IF EQ BF .NLIST ;DO NOT LIST SUS/RSU OR FRUN IF SJ MONITOR .IFF .SBTTL SUSPEND / RESUME SPNRSU: MOV @#SYSPTR,R1 ;POINT TO MONITOR MOV FCNTXT-$RMON(R1),R1 ;POINT TO FG IMPURE AREA BEQ 90$ ;OOPS, NO FOREGROUND BCS 1$ ;GO IF RESUME BIS #KSPND$,@R1 ;SET SUSPENSION BIT IN FG STATUS RTS PC ;RETURN 1$: BIC #KSPND$,@R1 ;CLEAR THE SUSPENSION BIT .EXIT ;LEAVE THIS WAY TO FORCE CONTEXT SWITCH 90$: KMEROR .SBTTL FRUN ; THIS IS THE FIRST PART OF FRUN STA=40 ;PROGRAM REL. START ADDR. STK=42 ;INITIAL STACK SETTING RSZ=52 ;DISPL. TO ROOT SIZE OSZ=54 ;DISPL. TO OVERLAY SIZE RID=56 ;REL FILE I.D. LOCATION RBD=60 ;DISPL. TO FIRST REL BLOCK FCHNM=16. ;NO. OF F JOB CHANNELS FMPUR=FCHNM*10.+IMPSIZ+10 ;SIZE OF F JOB IMPURE AREA FJOBNM=2 ;FOREGROUND JOB NUMBER OFRUN: MOV @#SYSPTR,R0 ;POINT TO RMON MOV FCNTXT-$RMON(R0),R4 ;GET F CONTEXT BEQ 1$ ;ZERO => NO F JOB IN CORE BIT #NORUN$,@R4 ;F JOB IN, IS IT ACTIVE? BEQ FJERR ;YES, GIVE AN ERROR MOV SP,@<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;INHIBIT CTRL/C ;DV12 CLR FCNTXT-$RMON(R0) ;VANISH BIC #FJOB$,CONFIG-$RMON(R0) ;SAY F JOB GONE JSR PC,PUTBLK ;RECOVER CORE FROM DEAD F JOB BCC 1$ ;WAS KMON/USR MOVED? ADD R0,(SP) ;YES, RELOC RETURN ADDR ADD R0,R5 ;AND STRING POINTER 1$: CLR @<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;ENABLE CTRL/C ;DV12 MOV (PC)+,R3 ;DEFAULT DEV. IS DK .RAD50 /DK / OADDR BLOCK,R2 ;R2 -> NAME BLOCK ;DV16 OJSR PC,RFILE ;GET FILE DESCRIPTOR OJSR PC,GETHAR ;AND HANDLER .LOOKUP 17 ;FIND FILE ON CHAN. 17 BCC 2$ ;O.K., CONTINUE OJMP NOTFND ;GIVE FILE NOT FOUND ERROR 2$: MOV @#SYSPTR,R3 ;POINT TO MONITOR MOV $CSW+<15.*5*2>-$RMON(R3),R3 ;GET CHANNEL 17 STATUS BIC #177701,R3 ;ISOLATE DEVICE INDEX OADD .$ENTRY,R3 ;R3 -> ENTRY FOR FRUN DEVICE CMP @<.SYSLO-OVLY>-<.+4-OVLYST>(PC),@R3 ;SYSTEM OR LOADED? BHI 3$ ;NO, FETCHED. LEAVE POINTER ALONE CLR R3 ;CLEAR POINTER SO FRUN WON'T RELOCATE 3$: MOV R3,-(SP) ;PRESERVE IT OVER THE LINK OVLINK FRU2 ;LINK TO THE REST OF THE COMMAND .SBTTL FRUN (PART 2) OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS OVCMD FRU2 .ENABL LSB MOV (SP)+,FRDEV ;RECOVER POINTER TO $ENTRY CLR PSWICH ;INIT SWITCH DATA CLR NVAL MOV #200*2,SVAL 1$: TSTB @R5 ;ANY SWITCHES COMING? BEQ 6$ ;NO, ALL DONE CMPB #'/,(R5) ;IS IT A /? BNE 4$ ;NO MOVB -(R5),R0 ;R0=SWITCH BEQ 4$ ;CR IS AN ERROR CMPB #'P,R0 ;P SWITCH? BEQ 5$ ;YES, PROCESS IMMED. CMPB #':,-(R5) ;OTHERS MUST HAVE VALUES BEQ 2$ ;: => OCTAL CMPB #'!,@R5 ;WHILE ! -> DECIMAL BNE 4$ ;NEITHER IS AN ERROR SEC ;SET C FOR DECIMAL 2$: OJSR PC,CVTNUM ;RETURNS VALUE IN STACK BCS 4$ ;WAY TOO BIG ASL (SP) ;CONVERT TO BYTES CMP #'N,R0 ;N SWITCH? BNE 3$ ;NO MOV (SP)+,(PC)+ ;SAVE IT NVAL: .WORD 0 BR 1$ 3$: CMP #'S,R0 ;S SWITCH? BNE 4$ ;THEN AN ERROR MOV (SP)+,(PC)+ ;SAVE IT SVAL: .WORD 0 ;# BYTES STACK SPACE ;ALSO TEMP. STORAGE BNE 1$ ;MUST BE NON-ZERO 4$: OJMP BADCOM ;KMEROR 5$: INC (PC)+ ;SET P SWITCH FLAG PSWICH: .WORD 0 ;PRINT BASE ADDR FLAG TSTB -(R5) BNE 1$ ;THEN LOOK FOR MORE 6$: OMOV .USRBU,R5 ;R5 -> USR BUFFER CLR @<.BLKEY-OVLY>-<.+4-OVLYST>(PC) ;NO DIRECTORY IN CORE MOV R5,RELBUF ;READ INTO USR BUFFER .DSABL LSB ; READ BLOCK 0 OF THE REL FILE -- THE PSEUDO CCB FOR REL FILES. CLR STMPUR ;NO CORE ALLOC. YET CLR RELBLK ;BLOCK # 0 JSR PC,RDBK0 ;READ INTO USR BUFFER .WAIT 17 ;WAIT FOR READ ; COMPUTE TOTAL PROGRAM CORE REQUIREMENTS AND ALLOCATE SPACE .ENABL LSB MOV R5,R3 ;POINT R3 TO SIZE OF ADD #RSZ,R3 ;ROOT IN CCB0 MOV (R3)+,R4 ;R4 = SIZE OF ROOT SEGMENT MOV @R3,(PC)+ ;SAVE OVERLAY INDICATOR ;DV22 OVFLG: .WORD 0 ;NON-ZERO => OVERLAYED ;DV22 MOV #FMPUR,R2 ;R2 = SIZE OF IMPURE AREA MOV STK(R5),-(SP) ;DID USER SPECIFY A STACK PTR? BNE 1$ ;YES ADD SVAL,R2 ;NO,ADD STACK SIZE 1$: MOV R2,-(SP) ;SAVE PROG. BASE OFFSET ADD R4,R2 ;R2 = OFFSET TO OVLY REGION ROR R4 ;CONVERT ROOT SIZE TO WORDS MOV R4,OVSIZ ;AND SET IN I/O BLOCK MOV R2,-(SP) ;SAVE OFFSET FOR OVLY I/O BLOCK ADD (R3)+,R2 ;R2 = PROG. HIGH LIMIT CMP (PC)+,(R3)+ ;IS THIS A REL FILE? .RAD50 /REL/ BEQ 2$ ;YES JMP FERR3 ;NO, ERROR EXIT 2$: MOV (R3),RELBLK ;SAVE REL BLK PTR MOV NVAL,R0 ;GET REQUESTED FREE CORE ADD R2,R0 ;ADD IMPURE AREA & PROG SIZE MOV SP,@<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;INHIBIT CTRL/C ;DV12 JSR PC,GETBL3 ;ALLOCATE SOME CORE BCC 3$ ;WAS KMON/USR MOVED? SUB R0,R5 ;YES, RELOCATE POINTERS SUB R0,6(SP) MOV (PC)+,R1 ;GET POINTER TO DEVICE HANDLER FRDEV: .WORD 0 BEQ 3$ ;SYSTEM OR LOADED, DON'T RELOCATE SUB R0,@R1 ;FETCHED. RELOCATE IT MOV @R1,R1 ;POINT TO RELOCATED HANDLER SUB R0,@-6(R1) ;RELOCATE ITS VECTOR ; CLEAR IMPURE AREA BEFORE INITIALIZING 3$: MOV #FMPUR/2,R0 ;CLEAR IMPURE AREA MOV R4,R1 ;R1 -> IMPURE AREA 4$: CLR (R1)+ DEC R0 BNE 4$ ; TRANSFER FILE NAME TO IMPURE AREA FROM SCRATCH AREA BLOCK ;DV16 MOV R4,R1 ;R1 -> IMPURE AREA ;DV16 ADD #I.NAME,R1 ;INDEX TO NAME AREA ;DV16 OADDR BLOCK,R0 ;R0 -> BLOCK IN KMON ;DV16 .REPT 4 MOV (R0)+,(R1)+ ;XFR FOUR WORDS ;DV16 .ENDR ; SAVE CONTENTS OF CCB 34-50 ON STACK FOR LATER USE ADD R4,(SP) ;RELOC OVLY OFFSET MOV (SP)+,SVAL ;SAVE TEMP. IN SVAL MOV (SP)+,R0 ;R0 = PROG. BASE OFFSET MOV (SP)+,R3 ;STACK SPECIFIED? BNE 5$ ;YES MOV R0,R3 ;SET UP STACK PTR VALUE 5$: ADD R4,R2 ;R2 = TOP OF PROGRAM MOV R5,R1 ;MAKE R1 -> 34(R5) ADD #34,R1 ADD R4,R0 ;RELOC PROG BASE ADDR MOV R0,STOVL ;SET IN I/O BLOCK TST PSWICH ;PRINT LOAD ADDRESS? BEQ 6$ ;NO MOV R0,PSWICH ;YES,THEN SAVE IT 6$: ADD R4,R3 ;RELOC. STACK PTR MOV R3,-(SP) ;THEN SAVE IT. CLR -(R3) ;DUMMY PSW ON STACK MOV R0,-(R3) ;SET F JOB PC TO ADD STA(R5),@R3 ;START ADDRESS ADD #-14,R3 ;BUMP PAST REG SAVE AREA MOV (R1)+,-(R3) ;SAVE 34 & 36 ON STACK BEQ 7$ ;TRAP ADDR SPECIFIED? ADD R0,(R3) ;YES, RELOCATE IT 7$: MOV (R1)+,-(R3) MOV (R1)+,-(R3) ;GET F JOB START ADDR ADD R0,(R3) ;RELOCATE IT MOV (SP)+,-(R3) ;STORE F JOB STACK PTR TST (R1)+ ;BUMP R1 UP TO 44(R5) MOV (R1)+,-(R3) ;SAVE F JSW MOV (R1)+,-(R3) ;SAVE USR AREA BEQ 8$ ;WAS IT SPECIFIED? ADD R0,(R3) ;YES, RELOCATE IT 8$: MOV R2,-(R3) ;STORE F JOB HI LIMIT MOV R2,-(SP) ;SAVE FOR STRTPG ADD NVAL,(SP) ;ADD FREE SPACE CLR -(R3) ;CLEAR 52(R5) MOV R3,I.SP(R4) ;SAVE STACK VALUE IN IMPURE AREA .DSABL LSB ; THIS CODE SETS UP AND RELOCATES THE POINTERS TO THE USR ; BUFFER USED BY THE REL BLOCK DOUBLE BUFFER LOGIC. ADDR BUFR1,R1 ;SET UP BUFFER POINTERS MOV #1000,R2 MOV R1,R0 MOV R1,-(R0) ;FIRST REL BLK IN BUFR2 MOV R5,(R1)+ ;SET UP BUFR1 MOV R5,(R1)+ MOV R2,@R1 ADD R2,-(R1) MOV (R1)+,R2 ADD R2,(R1)+ MOV R1,@R1 ADD #2,(R1)+ MOV R2,(R1)+ MOV R5,(R1)+ MOV R2,(R1)+ MOV @R0,@R1 ; IMPURE AREA INITIALIZATION -- THE F JOB IMPURE AREA PLACED ; BELOW THE ROOT SECTION OF THE PROGRAM MUST BE INITIALIZED. ; THIS AREA CONTAINS THE TTY RING BUFFERS, I/O QUEUE ELEMENTS, ; I/O CHANNELS AND CONTEXT INFORMATION. THE DISPLACEMENTS USED ; ARE DEFINED IN RMON. MOV R4,(PC)+ ;SAVE START OF IMPURE AREA STMPUR: .WORD 0 ;START OF IMPURE AREA MOV R4,R2 ;R4 -> START OF IMPURE AREA ADD #I.QUE,R2 ;R2 = ADDR. OF F QUEUE AREA MOV R2,I.QHDR(R4) ;SET UP Q PTR MOV #FJOBNM,I.JNUM(R4) ;SET UP JOB # MOV #FCHNM,I.CNUM(R4) ;AND NO. OF CHANNELS ADD #I.JID-I.QUE,R2 ;R2->START OF JOB I.D. AREA ;DV16 MOV R2,I.TID(R4) ;SAVE IN JOB I.D. PTR MOV (PC)+,(R2)+ ;INSERT F JOB ID .BYTE CR,LF MOV (PC)+,(R2)+ .BYTE 'F,'> MOV (PC)+,(R2)+ .BYTE CR,LF CLR (R2)+ ADD #IMPSIZ-I.NAME,R2 ;R2 -> CHANNEL AREA ;DV16 MOV R2,I.CSW(R4) ;STORE IN CH. PTR ADD #15.*5*2,R2 ;R2 -> FG CH 15. TST OVFLG ;WAS JOB OVERLAYED? ;DV22 BEQ 1$ ;NO, LEAVE CH. 17 CLOSED ;DV22 MOV #$CSW+<15.*5*2>-$RMON,R1 ;R1=DISP TO CH 15. ADD @#SYSPTR,R1 ;R1 -> BG CH 15. .REPT 5 MOV (R1)+,(R2)+ ;MOVE CH 15 TO FG (FOR OVLYS) .ENDR BR 2$ ;CONTINUE ;DV22 1$: ADD #5*2,R2 ;CORRECT POINTER ;DV22 2$: MOV R2,-(SP) ;SAVE F JOB LO LIMIT MOV R4,R2 ADD #I.ITOP+2,R2 ;R2 -> INPUT RING MOV R2,I.IRNG(R4) ;SET UP INPUT RING PTRS. MOV R2,I.IPUT(R4) MOV R2,I.IGET(R4) ADD #TTYIN,R2 ;R2 -> END OF INPUT RING MOV R2,I.ITOP(R4) ADD #I.OTOP-I.ITOP-TTYIN,R2 ;R2 -> OUTPUT RING MOV R2,I.OPUT(R4) ;SET UP OUTPUT RING PTRS. MOV R2,I.OGET(R4) ADD #TTYOUT,R2 ;R2 -> END OF OUTPUT RING MOV R2,I.OTOP(R4) MOV #ACTIV$+,I.MSG(R4) ;SET UP ;MESSAGE CHANNEL FOR F JOB. ; READ ROOT PROGRAM SECTION INTO CORE ADDR OVBK,R0 ;R0 -> I/O BLOCK MOV R0,-(SP) ;SAVE ON STACK MOV #1,@R0 ;ROOT ALWAYS IN BLK #1 MOV #10*400+17,-(R0) ;SET TO READ EMT 375 FERR0: BCS FERR1 ;GO RELOC ROOT ; SET UP TO RELOCATE THE ROOT SEGMENT NOW IN CORE RELSET: MOV STOVL,R1 ;R1=PROGRAM BASE JSR PC,RDBUF ;READ FIRST REL BLOCK MOV R4,R5 ;R4 SAME AS R5 ;TO TRIGGER A RDBUF ON ;1ST ENTRY TO GETWD. MOV SVAL,STOVL ;SET OVLY REGION ADDR IN I/O BLK CLR FLG2 ;MAKE SURE ITS CLEAR ; NOW RELOCATE THE ROOT SEGMENT .ENABL LSB 1$: JSR PC,GETWD ;GET A WD BCS ENDRUT ;-1 OR -2 RETURN MOV R2,R0 ;COMPUTE CORE ADDR TO RELOC ASL R0 ;CONVERT TO WORD BOUNDARY ADD R1,R0 ;R0 NOW -> WORD IN CORE JSR PC,RELOC ;RELOC THE WORD BR 1$ ;THEN DO ANOTHER ; READ AN OVERLAY SEGMENT INTO CORE WORK AREA. AFTER ; RELOCATING THE OVERLAY SEGMENT, IT WILL BE WRITTEN BACK ; INTO THE FILE FOR LOADING BY THE RESIDENT OVERLAY HANDLER. 2$: JSR PC,OVREL ;RELOCATE A WD 3$: JSR PC,GET2WD ;GET 2 REL WORDS BCC 2$ ;-1 OR -2 RETURN MOV (SP),R0 ;R0 -> I/O BLOCK BIS #400,-(R0) ;CHANGE READ CODE TO WRITE EMT 375 BCS FERR1 ENDRUT: TST FLG2 ;END OF ALL REL BLOCKS? BNE STRTPG ;YES, START THE PROG JSR PC,GET2WD ;NO, SET UP AN OVERLAY MOV (SP),R0 ;R0 -> OVBK MOV R2,@R0 ;SAVE OVERLAY BLOCK # MOV R3,OVSIZ ;AND THE SIZE MOV #10*400+17,-(R0) ;SET TO READ CODE EMT 375 BCC 3$ ;THEN GO RELOC FERR1: MOV STMPUR,R4 ;POINT R4 TO AREA BEQ FERR3 ;NONE ALLOC. YET JSR PC,PUTBL3 ;RELEASE CORE FERR3: KMEROR .DSABL LSB .ENABL LSB ; RELOCATE THE OVERLAY SEGMENT IN THE WORK AREA. OVREL: MOV R2,R0 ;MAKE R0 -> LOC TO RELOC ASL R0 ;ADJUST R0 TO WORD BOUNDARY ADD STOVL,R0 ;RELOC PTR MOV R3,@R0 ;SET UP TEXT IN CORE RELOC: ASL R2 ;EXTRACT RELOCATION SIGN BCS 1$ ;NEGATIVE RELOC? ADD R1,@R0 ;NO, ADDITIVE RELOC RTS PC 1$: SUB R1,@R0 2$: RTS PC ; SET UP FOREGROUND JOB LIMITS AND IMPURE POINTERS IN RMON. ; RETURN TO KMON WILL CAUSE CONTEXT SWITCHING TO ACTIVATE ; THE FOREGROUND JOB. STRTPG: TST (SP)+ ;POP OFF OVBK PTR MOV @#SYSPTR,R3 ;POINT TO RMON BIS #FJOB$,CONFIG-$RMON(R3) ;SAY F JOB IS IN MOV (SP)+,$JBLIM+<2*FJOBNM>+2-$RMON(R3) ;SET LOW LIMIT MOV (SP)+,$JBLIM+<2*FJOBNM>-$RMON(R3) ;AND F JOB HI LIMIT MOV STMPUR,$IMPUR+FJOBNM-$RMON(R3) ;AND SET IT UP CLR @<.EXTFL-OVLY>-<.+4-OVLYST>(PC) ;ENABLE CTRL/C ;DV12 MOV PSWICH,R2 ;R2= PROG.BASE ADDRESS BEQ 2$ ;PRINT IF NON-ZERO BIS #KSPND$,@STMPUR ;P SWTCH => FJOB SUSPENDED ADDR PMSG,R0 .PRINT CLR R1 ;SET UP TO ENTER OCTAL ;PRINT ROUTINE IN KMON. OJMP OPRINT .DSABL LSB ; THE FOLLOWING IS THE OVERLAY I/O BLOCK FOR READ/WRITE I/O. OVIOBK: .BYTE 17 ;CHANNEL 17 .BYTE 10 ;READ=10, WRITE=11 OVBK: .WORD 0 ;CURRENT OVERLAY BLOCK # STOVL: .WORD 0 ;START OF OVERLAY REGION OVSIZ: .WORD 0 ;CURRENT OVERLAY WORD SIZE .WORD 0 ;WAIT I/O FLG2: .WORD 0 ;END OF REL FLAG (IF NON-ZERO) ; FOLLOWING IS I/O BLOCK FOR READING REL BLOCKS RLIOBK: .BYTE 17,10 ;CH. 17;READ RELBLK: .WORD 0 ;CURRENT REL BLOCK RELBUF: .WORD 0 ;CURRENT BUFFER PTR .WORD 400,1 ;400 WORDS;DON'T WAIT PMSG: .ASCII "LOADED AT "<200> .EVEN ; SUBROUTINE TO GET ONE WORD FROM THE REL BLOCK BUFFERS. ; IF A BUFFER IS EMPTY, RDBUF IS CALLED TO SWITCH ; BUFFERS AND FILL THE EMPTY BUFFER. RDBUF: .WAIT 17 ;CHANNEL READY? MOV CURBUF,R0 ;R0 -> BUFFER IN USE MOV (R0)+,RELBUF ;PT TO CURRENT EMPTY BUFR MOV (R0)+,R4 ;SWITCH BUFFER PTS MOV (R0)+,R5 MOV (R0),CURBUF ;INDICATE NEW BUFR IN USE RDBK0: ADDR RLIOBK,R0 ;CURRENT REL BLK TO READ EMT 375 INC RELBLK ;BUMP REL BLOCK PTR BCC 1$ TSTB @#52 ;TEST ERROR BYTE BNE FERR1 ;HARD ERROR EXIT 1$: RTS PC GETWD: CMP R4,R5 ;END OF BUFFER? BLO 1$ ;NO JSR PC,RDBUF ;YES,SWITCH BUFFERS 1$: MOV (R4)+,R2 ;GET A WORD CMP #-2,R2 ;CHECK FOR -1 OR -2 BNE 2$ ;NOT -2 INC FLG2 ;SET -2 FLAG NON-ZERO SEC ;FLAG IT WITH C=1 2$: RTS PC GET2WD: JSR PC,GETWD ;GET A WORD BCS 1$ ;-1 OR -2 EXIT MOV R2,-(SP) ;SAVE TEMP JSR PC,GETWD ;GET 2ND WORD MOV R2,R3 MOV (SP)+,R2 ;FIRST ONE IN R2 1$: RTS PC ; BUFFER POINTERS -- THESE MUST BE KEPT CONTIGUOUS AND IN ; THIS ORDER, BOTH FOR SETUP AND FOR USE BY RDBUF. CURBUF: .WORD 0 ;ADDR OF CURRENT BUFFER PTR BUFR1: .WORD 0 ;ADDR OF THIS BUFFER .WORD 0 ;ADDR OF ALTERNATE BUFR .WORD 0 ;ADDR OF END OF ALT BUFR .WORD 0 ;ADDR OF ALT BUFR TABLE .WORD 0 .WORD 0 .WORD 0 .WORD 0 ; GETBLK -- SUBROUTINE TO SEARCH FREE CORE LIST FOR A BLOCK EQUAL ; TO REQUESTED SIZE. IF NOT IN FREE CORE LIST, KMON/USR IS ; MOVED DOWN TO CREATE THE BLOCK. ; ; CALL SEQUENCE: JSR PC,GETBLK ; R0=# BYTES DESIRED ; ; RETURNS WITH: R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (1ST WORD OF BLK) ; ; R1,R3 DESTROYED ; GETBL3: TST (R0)+ ;ADD 2 BYTES TO REQUEST OMOV .CORPT,R3 ;R3 -> FREE CORE LIST HEAD 1$: MOV 2(R3),R4 ;R4 -> NEXT FREE BLOCK OCMP .CORPT,R4 ;END OF LIST? BEQ 4$ ;YES, BACK AT LIST HEAD CMP (R4),R0 ;THIS BLOCK BIG ENOUGH? BGE 2$ ;YES, USE IT. MOV R4,R3 ;NO, TRY NEXT BLOCK BR 1$ 2$: SUB R0,(R4) ;BLK SIZE - REQUEST SIZE BNE 3$ ;EXACTLY THE SAME? MOV 2(R4),2(R3) ;YES, REMOVE FROM LIST 3$: ADD (R4),R4 ;R4 -> START OF BLOCK CLC BR 5$ ;GO EXIT 4$: SUB R0,(SP) ;RELOCATE RETURN ADDR. NEG R0 ;-SIZE => MOVE KMON DOWN ROR R0 ;HALVE IT, C=1 SO IT IS <0 OJSR PC,KUMOVE ;CALL TO MOVE KMON/USR NEG R0 ;FIX R0, SET CARRY 5$: MOV R0,(R4)+ ;STORE SIZE IN FIRST WORD RTS PC ; PUTBLK -- RETURNS A BLOCK OF CORE TO THE FREE CORE LIST. ; MERGES CONTIGUOUS BLOCKS OF CORE INTO A SINGLE BLOCK. ; RECLAIMS CORE FROM BLOCKS CONTIGUOUS TO KMON/USR BY ; SLIDING UP KMON/USR. ; ; CALL SEQUENCE: JSR PC,PUTBLK ; ; R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (IN 1ST WORD OF BLK) ; ; R0,R1 DESTROYED ; PUTBL3: TST -(R4) ;POINT TO BLOCK SIZE IN 1ST WD. OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD 1$: MOV 2(R0),R1 ;R1 -> NEXT FREE BLOCK OCMP .CORPT,R1 ;LAST BLOCK IN LIST? BEQ 3$ ;YES, INSERT NEW BLOCK HERE CMP R1,R4 ;NO, NEXT BLOCK HIGHER IN CORE? BHI 2$ ;YES, INSERT BLOCK HERE MOV R1,R0 ;NO, R0 -> CURRENT BLOCK BR 1$ ;CONTINUE SEARCH ; UPPER BOUNDARY CHECK FOR CONTIGUOUS BLOCKS 2$: MOV R4,-(SP) ;COMPUTE ADDR OF END OF ADD (R4),(SP) ;NEW BLOCK OF CORE. CMP (SP)+,R1 ;TOUCHES NEXT BLOCK? BNE 3$ ;NO, CAN'T MERGE ADD (R1)+,(R4)+ ;YES, MERGE THE TWO MOV (R1),(R4) ;BLOCKS INTO ONE. CMP -(R4),-(R1) ;FIX R4,R1 BR 4$ ;THE CHECK LOWER BOUND. 3$: MOV R1,2(R4) ;JUST LINK IN NEW BLK ; LOWER BOUND CHECK FOR CONTIGUOUS BLOCKS 4$: MOV R0,-(SP) ;IS NEW BLOCK CONTIGUOUS ADD (R0),(SP) ;WITH LOWER BLOCK? CMP (SP)+,R4 ;COMPARE BOUNDS BEQ 5$ ;CONTIGUOUS, SO MERGE THEM MOV R4,2(R0) ;NO, JUST LINK TO LOWER BR 6$ ;THEN GO ON 5$: ADD (R4)+,(R0)+ ;ADD SIZES TOGETHER MOV (R4),(R0) ;AND RE-LINK THE LIST. CMP -(R4),-(R0) ;FIX R4,R0 ; CORE RECLAIM CHECK 6$: OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD MOV 2(R0),R1 ;R1 -> LOWEST FREE BLOCK MOV @<.SYSLO-OVLY>-<.+4-OVLYST>(PC),-(SP) CMP (SP)+,R1 ;CONTIGUOUS TO KMON/USR? CLC BNE 7$ ;NO, JUST EXIT BIT (R1)+,(R0)+ ;BUMP R1, R0, LEAVE C=0 MOV (R1),(R0) ;REMOVE FROM LIST MOV -(R1),R0 ;SIZE IN R0 ROR R0 ;HALVE IT, LEAVE > 0 OJSR PC,KUMOVE ;THEN SQUISH IT ADD R0,(SP) ;RELOCATE RETURN ADDRESS SEC 7$: RTS PC ;AND EXIT .ENDC .IF EQ BF .LIST .ENDC .SBTTL GT ON/OFF OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS OVCMD GT MOV @#SYSPTR,R1 ;R1 -> RMON ADD #CONFIG-$RMON,R1 ;R1 -> CONFIG BIT #HWDSP$,(R1)+ ;DISPLAY HARDWARE PRESENT? BEQ BCELNK ;NO, NOTHING WE CAN DO .IF NE BF MOV FCNTXT-SCROLL(R1),R4 ;R4 -> FJOB CONTEXT BEQ 20$ ;ZERO => NO F JOB BIT #NORUN$,@R4 ;FOREGROUND ACTIVE? BEQ BCELNK ;YES, TOO DANGEROUS 20$: .ENDC OADDR DEVSTS,R2 ;R2 -> A BUFFER OJSR PC,GETNAM ;GET RAD50 ARGUMENT CMP (PC)+,@R2 ;TURN DISPLAY ON? .RAD50 /ON / BEQ GTON ;YES CMP (PC)+,@R2 ;TURN DISPLAY OFF? .RAD50 /OFF/ BEQ GTOFF ;YES BCELNK: OJMP BADCOM ; .ENABL LSB GTON: TST @R1 ;SCROLLER ALREADY IN CORE? BNE BCELNK ;YES, CAN'T DO JSR PC,VSTOP ;STOP DISPLAY IF RUNNING ADDR TSTIT,R0 ;R0 -> DISPLAY TEST FILE MOV R0,@#DPC ;RUN IT 2$: MOV @#DSR,R0 ;STOPPED? BPL 2$ ;LOOP UNTIL IT DOES BIT #40,R0 ;EDGE FLAG SET? BEQ 3$ ;NO, 17" SCOPE MOV (PC)+,R3 ;Y POS IN R3 YPS12: .WORD 1350 ;12" SCOPE Y POS DEFAULT MOV (PC)+,R4 ;LINE CT IN R4 LCT12: .WORD 37 ;12" SCOPE LINE CT DEFAULT .IF EQ BF MOV #72.,-(SP) ;SET UP LINE WIDTH ;DV13 .ENDC BR 4$ 3$: MOV (PC)+,R3 ;Y POS IN R3 YPS17: .WORD 1750 ;17" SCOPE Y POS DEFAULT MOV (PC)+,R4 ;LINE CT IN R4 LCT17: .WORD 50 ;17" SCOPE LINE CT DEFAULT .IF EQ BF MOV #80.,-(SP) ;SET UP LINE WIDTH ;DV13 .ENDC 4$: .DSABL LSB .ENABL LSB 1$: TSTB @R5 ;ARE THERE ANY TO PROCESS? BEQ 5$ ;NO 2$: CMPB #'/,@R5 ;SWITCH COMING? BNE BCELNK ;NO,ERROR EXIT MOVB -(R5),R0 ;SAVE SWITCH CMPB #':,-(R5) ;OCTAL VALUE? BEQ 3$ ;YES CMPB #'!,@R5 ;DECIMAL VALUE? BNE BCELNK ;NO, ERROR SEC ;FLAG DECIMAL AND 3$: OJSR PC,CVTNUM ;GO CONVERT VALUE CMPB #'T,R0 ;T SWITCH? BNE 4$ ;NO MOV (SP)+,R3 ;VALUE TO R3 BEQ BCELNK ;ZERO IS ILLEGAL CMP #1777,R3 ;LIMIT TO 1777(8) BLT BCELNK ;TOO BIG BR 1$ ;ANOTHER? 4$: CMPB #'L,R0 ;L SWITCH? BNE BCELNK ;NO, ERROR MOV (SP)+,R4 ;YES, VALUE TO R4 BEQ BCELNK ;ZERO IS ILLEGAL CMP #41.,R4 ;TOO BIG? BLT BCELNK ;YES, ERROR BR 1$ ;ANOTHER SWITCH? 5$: MOV R3,-(SP) ;SAVE Y POS ON STACK MOV R4,-(SP) ;SAVE LINE COUNT MOV #SCRSIZ,R0 ;R0 = SCROLLER SIZE ADD (PC)+,R0 ;PLUS TEXT BUFFER BUFSIZ: .WORD 4000 ;DEFAULT TEXT BUFFER SIZE IN BYTES MOV R1,-(SP) ;SAVE R1 JSR PC,GETBL4 ;ALLOCATE CORE MOV (SP)+,R1 ;RESTORE POINTER BCC 7$ ;KMON/USR MOVED? .IF NE BF ;DV13 SUB R0,4(SP) ;YES, RELOCATE RETURN .IFF ;DV13 SUB R0,6(SP) ;RELOCATE RETURN ;DV13 .ENDC ;DV13 7$: ; SET UP I/O BLOCK TO READ IN SCROLLER ADDR SCRIOB,R5 ;R5 -> I/O BUFR FOR SCROLLER MOV R4,@R5 ;STORE CORE ADDR MOV #SCRBLK,R0 ;R0 = REL. BLOCK OF SCROLLER ADD @<.$SWPB-OVLY>-<.+4-OVLYST>(PC),R0 ;ADD SWAP BLOCK OFFSET JSR PC,@<.$SYS-OVLY>-<.+4-OVLYST>(PC) ;CALL RMON ROUTINE TO READ BCS 10$ ;READ ERROR MOV BUFSIZ,R0 ;R0 = BUFFER SIZE JMP (R4) ;GO TO INIT ROUTINE 10$: JSR PC,PUTBL4 ;RECOVER CORE OJMP SYIOER ;JUMP TO .DSABL LSB GTOFF: MOV @R1,R4 ;O.K., GET ADDR OF SCRLR BEQ 2$ ;NOT THERE!! JSR PC,VSTOP ;GO STOP DISPLAY ; RESTORE LOCATIONS MODIFIED IN RMON. OINTOF 3$ ;LOCK OUT INTERRUPTS ;DV15 CLR @R1 ;CLEAR SCROLL PTR. BICB #14,LOWMAP+15-SCROLL(R1) ;CLEAR PROTECT BITS MOV #177600,R2 ;SET UP TO RESTORE CODE MOV #42700,(R1) ;BIC #,R0 MOV R2,(R1) ;#177600 .IF EQ BF MOV #42704,(R1) ;BIC #,R4 MOV R2,(R1) ;177600 .ENDC MOV (R4),(R1) MOV (R4),(R1) OINTON 3$ ;LOWER PRIORITY ;DV15 JSR PC,PUTBL4 ;RECOVER CORE BCC 2$ ;KMON/USR MOVED? ADD R0,(SP) ;YES, RELOC RETURN 2$: RTS PC 3$: RTI ;DV15 ; SUBROUTINE TO STOP THE DISPLAY DPC=172000 ;DISPLAY PROGRAM COUNTER DSR=172002 ;DISPLAY STATUS REGISTER VSTOP: ADDR STPIT,R2 ;R2 -> DISPLAY FILE 1$: MOV R2,@#DPC ;MOVE IT TO DISPLAY PC TST @#DSR ;STOPPED? BPL 1$ ;NO, DO IT AGAIN RTS PC ;YES, IT'S STOPPED! TSTIT: 114000 ;POINT MODE 0 1350 104000 ;SHORTV MODE 77 STPIT: 173000 ;STOP DISPLAY W/O INT. ; THIS IS THE I/O TABLE THAT DRIVES THE LOADING OF THE SCROLLER SCRIOB: .WORD 0 ;CORE ADDRESS TO LOAD SCROLLER .WORD SCRTOT ;SCROLLER SIZE IN WORDS .WORD 0 ;WAIT I/O ; GETBLK -- SUBROUTINE TO SEARCH FREE CORE LIST FOR A BLOCK EQUAL ; TO REQUESTED SIZE. IF NOT IN FREE CORE LIST, KMON/USR IS ; MOVED DOWN TO CREATE THE BLOCK. ; ; CALL SEQUENCE: JSR PC,GETBLK ; R0=# BYTES DESIRED ; ; RETURNS WITH: R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (1ST WORD OF BLK) ; ; R1,R3 DESTROYED ; GETBL4: TST (R0)+ ;ADD 2 BYTES TO REQUEST OMOV .CORPT,R3 ;R3 -> FREE CORE LIST HEAD 1$: MOV 2(R3),R4 ;R4 -> NEXT FREE BLOCK OCMP .CORPT,R4 ;END OF LIST? BEQ 4$ ;YES, BACK AT LIST HEAD CMP (R4),R0 ;THIS BLOCK BIG ENOUGH? BGE 2$ ;YES, USE IT. MOV R4,R3 ;NO, TRY NEXT BLOCK BR 1$ 2$: SUB R0,(R4) ;BLK SIZE - REQUEST SIZE BNE 3$ ;EXACTLY THE SAME? MOV 2(R4),2(R3) ;YES, REMOVE FROM LIST 3$: ADD (R4),R4 ;R4 -> START OF BLOCK CLC BR 5$ ;GO EXIT 4$: SUB R0,(SP) ;RELOCATE RETURN ADDR. NEG R0 ;-SIZE => MOVE KMON DOWN ROR R0 ;HALVE IT, C=1 SO IT IS <0 OJSR PC,KUMOVE ;CALL TO MOVE KMON/USR NEG R0 ;FIX R0, SET CARRY 5$: MOV R0,(R4)+ ;STORE SIZE IN FIRST WORD RTS PC ; PUTBLK -- RETURNS A BLOCK OF CORE TO THE FREE CORE LIST. ; MERGES CONTIGUOUS BLOCKS OF CORE INTO A SINGLE BLOCK. ; RECLAIMS CORE FROM BLOCKS CONTIGUOUS TO KMON/USR BY ; SLIDING UP KMON/USR. ; ; CALL SEQUENCE: JSR PC,PUTBLK ; ; R4 -> START OF BLOCK+2 ; (R4)-2 = SIZE OF BLOCK (IN 1ST WORD OF BLK) ; ; R0,R1 DESTROYED ; PUTBL4: TST -(R4) ;POINT TO BLOCK SIZE IN 1ST WD. OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD 1$: MOV 2(R0),R1 ;R1 -> NEXT FREE BLOCK OCMP .CORPT,R1 ;LAST BLOCK IN LIST? BEQ 3$ ;YES, INSERT NEW BLOCK HERE CMP R1,R4 ;NO, NEXT BLOCK HIGHER IN CORE? BHI 2$ ;YES, INSERT BLOCK HERE MOV R1,R0 ;NO, R0 -> CURRENT BLOCK BR 1$ ;CONTINUE SEARCH ; UPPER BOUNDARY CHECK FOR CONTIGUOUS BLOCKS 2$: MOV R4,-(SP) ;COMPUTE ADDR OF END OF ADD (R4),(SP) ;NEW BLOCK OF CORE. CMP (SP)+,R1 ;TOUCHES NEXT BLOCK? BNE 3$ ;NO, CAN'T MERGE ADD (R1)+,(R4)+ ;YES, MERGE THE TWO MOV (R1),(R4) ;BLOCKS INTO ONE. CMP -(R4),-(R1) ;FIX R4,R1 BR 4$ ;THE CHECK LOWER BOUND. 3$: MOV R1,2(R4) ;JUST LINK IN NEW BLK ; LOWER BOUND CHECK FOR CONTIGUOUS BLOCKS 4$: MOV R0,-(SP) ;IS NEW BLOCK CONTIGUOUS ADD (R0),(SP) ;WITH LOWER BLOCK? CMP (SP)+,R4 ;COMPARE BOUNDS BEQ 5$ ;CONTIGUOUS, SO MERGE THEM MOV R4,2(R0) ;NO, JUST LINK TO LOWER BR 6$ ;THEN GO ON 5$: ADD (R4)+,(R0)+ ;ADD SIZES TOGETHER MOV (R4),(R0) ;AND RE-LINK THE LIST. CMP -(R4),-(R0) ;FIX R4,R0 ; CORE RECLAIM CHECK 6$: OMOV .CORPT,R0 ;R0 -> FREE CORE LIST HEAD MOV 2(R0),R1 ;R1 -> LOWEST FREE BLOCK MOV @<.SYSLO-OVLY>-<.+4-OVLYST>(PC),-(SP) CMP (SP)+,R1 ;CONTIGUOUS TO KMON/USR? CLC BNE 7$ ;NO, JUST EXIT BIT (R1)+,(R0)+ ;BUMP R1, R0, LEAVE C=0 MOV (R1),(R0) ;REMOVE FROM LIST MOV -(R1),R0 ;SIZE IN R0 ROR R0 ;HALVE IT, LEAVE > 0 OJSR PC,KUMOVE ;THEN SQUISH IT ADD R0,(SP) ;RELOCATE RETURN ADDRESS SEC 7$: RTS PC ;AND EXIT .SBTTL SET COMMAND .IF EQ BF ;THIS CONDITION RUNS OVER THE WHOLE COMMAND OVERLAY BLKNUM = OVLYN+RT11SZ ;OVERLAY BLOCK # IN MONITR.SYS .IFTF OVCMD SET MOV @#SYSPTR,R0 ;POINT TO RESIDENT .IFF ;F/B MOV TTCNFG-$RMON(R0),SET58$ ;GET OLD CONFIG MOVB TTWIDTH-$RMON(R0),SET59$ ;GET OLD WIDTH .IFTF ;BOTH ADDR SET60$,R4 ;POINT R4 TO TTY STUFF HERE MOV CONFIG-$RMON(R0),R2 ;GET OLD CONFIG WORD BIC #^C,R2 ;ISOLATE OLD VALUE OF USR$ MOV R2,SET62$ ;SAVE IT JSR PC,SET90$ ;GET A HANDLER NAME JSR R4,SET98$ ;SKIP OVER COLON, IF ANY .WORD ': TST 2(R2) ;HANDLER NAMES ARE 1 WORD BNE SET42$ ;INVALID CMP @R2,(PC)+ ;IS IT 'SET USR'? .RAD50 /USR/ BEQ 1$ ;YES, NO READS OR WRITES ADD #SET50$-SET60$,R4 ;POINT TO TTY PARAMETERS CMP @R2,(PC)+ ;TTY IS SPECIAL .RAD50 /TTY/ BEQ 1$ ;USE THE LOCAL STUFF MOV (PC)+,-(R2) ;THE HANDLER IS ON SY: .RAD50 /SY / MOV #75273,6(R2) ;THIS IS .RAD50 /SYS/, THE EXTENSION MOV #3*400+17,R0 ;PURGE CHANNEL 17 EMT 374 .LOOKU 17,R2 ;LOOK UP THE HANDLER BCS SET40$ ;IT AIN'T THERE OMOV .USRBUF,R4 ;POINT TO USR BUFFER CLR @<.BLKEY-OVLY>-<.+4-OVLYST>(PC) ;WE CLOBBER DIRECTORY CLR R0 ;READ BLOCK 0 .READW 17,R4,#512. ;READ 1ST 2 BLOCKS INTO USR BUFFER BCS SET41$ ;SY I/O ERROR ADD #400,R4 ;R4 -> COMMAND TABLE 1$: MOVB -(R5),R0 ;ASSEMBLE 2 CHARACTERS TO CHECK FOR 'NO' SWAB R0 CLRB R0 BISB -(R5),R0 SUB #"ON,R0 ;CHECK FOR 'NO', LEAVE R0=0 IF 'NO' BEQ 11$ ;GO FIX FOR 'NO' CMPB (R5)+,(R5)+ ;FIX R5, WE GOT NO 'NO' BR 2$ 11$: JSR PC,SET96$ ;SKIP BLANKS AFTER 'NO', IF ANY 2$: JSR PC,SET90$ ;GET THE OPTION NAME MOV R4,R1 ;POINT TO OPTION TABLE BR 5$ ;ENTER LOOP 3$: TST (R1)+ ;SKIP 2ND WORD OF OPTION NAME 4$: CMP (R1)+,-(R2) ;SKIP FLAGS, FIX R2 5$: MOV (R1)+,R3 ;GET PRESET WORD BEQ SET42$ ;0 => END OF TABLE, ERROR CMP (R2)+,(R1)+ ;CHECK 1ST WORD OF NAME BNE 3$ ;NO CMP @R2,(R1)+ ;2ND WORD BNE 4$ ;NOT YET MOV R4,R2 ;COPY ENTRY POINTER MOV @R1,R1 ;R1 = FLAGS, OFFSET BMI 6$ ;'NO' IS ALLOWED TST R0 ;'NO' IS ILLEGAL. WAS IT GIVEN? BEQ SET42$ ;YES, ERROR 6$: TST R0 ;'NO' GIVEN? BNE 7$ ;NO CMP (R2)+,(R2)+ ;YES, ALTER ENTRY POINT 7$: ASL R1 ;DOUBLE OFFSET BPL 8$ ;NO NUMBER REQUIRED JSR R4,SET98$ ;NUMBER NEEDED. SKIP OVER OPTIONAL '=' .WORD '= BIC #100000,R1 ;FIX R1 MOV R5,R0 ;COPY LINE POINTER DEC R0 OJSR PC,DECNUM ;CALL NUMBER GETTER CMP R5,R0 ;DID THE POINTER MOVE? BEQ SET42$ ;NO NUMBER = ERROR MOV (SP)+,R0 ;GET NUMBER IN R0 JSR PC,SET95$ ;SKIP OVER BLANKS, IF ANY 8$: ADD R1,R2 ;ADDRESS OF ROUTINE IN R2 (CLEAR CARRY) JSR PC,@R2 ;CALL PARAMETER ROUTINE BCS SET42$ ;HANDLER DETECTED ERROR TSTB -1(R5) ;END OF LINE? BEQ SET10$ ;YES, CLOSE IT OUT JSR R4,SET98$ ;NO, SKIP OPTIONAL , .WORD ', BR 1$ ;LOOP SET10$: OCMP .USRBUF,R4 ;WAS THIS THE TTY OR USR? BHI SET45$ ;YES, IT WAS IN THE KMON OMOV .USRBUF,R4 ;REPOINT TO BUFFER CLR R0 ;WRITE BLOCK 0 .WRITW 17,R4,#512. ;REWRITE THE HANDLER BCS SET41$ ;ERROR (THIS IS A REALLY BAD ONE) RTS PC ;BACK TO THE SHADOWS AGAIN SET40$: OJMP BADHAN SET41$: OJMP SYIOER SET42$: OJMP BADCOM SET45$: MOV @#SYSPTR,R0 ;SET TTY OR SET USR. POINT TO RMON BIC #USR$,CONFIG-$RMON(R0) ;TURN OFF OLD VALUE OF USR$ BIS SET62$,CONFIG-$RMON(R0) ;AND PUT IN NEW VALUE .IFF ;F/B MOV SET58$,TTCNFG-$RMON(R0) ;PUT IN NEW TTY CONFIG MOVB SET59$,TTWIDT-$RMON(R0) ;AND NEW WIDTH ADD #LISTFB-$RMON,R0 ;POINT TO WORDS FOR F/B SWITCH MOV #100000,R1 ;THIS FLAG SETS OR CLEARS BIT #FBTTY$,SET58$ ;ON OR OFF? BNE 1$ ;ON BIS R1,(R0)+ ;OFF. TURN ON BIT SO IT NEVER MATCHES BIS R1,(R0)+ RTS PC 1$: BIC R1,(R0)+ BIC R1,(R0)+ .IFTF RTS PC SET60$: .WORD USR$ .RAD50 /SWAP / .WORD /2+100000 0 SET61$: CLR R3 ;SET USR$ OFF FOR 'SWAP' NOP MOV R3,(PC)+ SET62$: 0 RTS PC SET50$: .IFF ;F/B .WORD HWTAB$ .RAD50 /TAB / .WORD /2+100000 .WORD VT05$ .RAD50 /SCOPE / .WORD /2+100000 .WORD FORM$ .RAD50 /FORM / .WORD /2+100000 .WORD CRLF$ .RAD50 /CRLF / .WORD /2+100000 .WORD PAGE$ .RAD50 /PAGE / .WORD /2+100000 .WORD 30. .RAD50 /WIDTH / .WORD /2+40000 .WORD FBTTY$ .RAD50 /FB / .WORD /2+100000 .IFTF .WORD '_ ;DISABLE VT50 PRINT .RAD50 /COPY / .WORD /2+100000 .WORD '\ ;DISABLE SCREEN HOLD .RAD50 /HOLD / .WORD /2+100000 0 .IFF ;F/B SET51$: BR SET53$ 0 SET52$: BIC R3,(PC)+ SET58$: 0 RTS PC SET53$: BIS R3,SET58$ RTS PC SET54$: MOVB R0,(PC)+ SET59$: 0 CMPB R0,R3 RTS PC .IFTF ;BOTH ; THIS CODE SUPPORTS THE VT50 HOLD AND HARD COPY OPTIONS. ; IT TRANSMITS THE PROPER ESCAPE SEQUENCE TO THE TERMINAL, ; TOGGLING THE LOGIC EACH TIME THE SEQUENCE IS SENT. THE HOLD ; OPTION PUTS THE VT50 IN AUTO-PAGE MODE. THE COPY OPTION TURNS ; THE HARD-COPY UNIT ON AND OFF. SET70$: DEC R3 ;TURN THE OPTION ON NOP ;'NO' ENTRY POINT MOVB R3,ESCLOC ;INSERT ESCAPE CHARACTER ADDR ESCSEQ,R0 ;POINT TO STRING .PRINT ;AND OUTPUT IT RTS PC ESCSEQ: .BYTE 33 ESCLOC: .BYTE 0 .BYTE 0 .EVEN SET90$: OADDR DEVSTS+2,R2 ;POINT TO A HANDY BLOCK MOV R0,-(SP) ;SAVE R0 OJSR PC,GETNAM ;GET 2 WORDS OF RAD50 BEQ SET42$ ;ERROR MOV (SP)+,R0 ;RESTORE R0 SET95$: INC R5 ;START SCAN FOR NON-BLANK SET96$: CMPB -(R5),#40 ;BLANK? BEQ SET96$ ;YES, KEEP GOING INC R5 ;NO, BACK UP RTS PC SET98$: CMPB (R4)+,-(R5) ;ARE WE POINTING TO THE OPTIONAL BYTE? BNE SET100 ;NO SET99$: CMPB -(R5),#40 ;YES, SKIP OPTIONAL AND BLANKS BEQ SET99$ SET100: CMPB (R4)+,(R5)+ ;FIX R4 AND R5 RTS R4 ;OUT .ENDC ;.IF EQ BF .SBTTL VT11 SHIFT OUT INTERRUPT SERVICE OVERLAY SCRBLK=OVLYN+RT11SZ+SWAPSZ ;BLOCK # OF SCROLLER ; THIS OVERLAY BLOCK SHOULD FOLLOW THE GT OVERLAY ; AND BE THE LAST BLOCK IN THE OVERLAY FILE. ; THIS INTERRUPT HANDLER SERVICES THE SCROLL BUFFER ; DURING VT11 SUPPORT OF THE RT11 MONITOR. THE SHIFT OUT ; INTERRUPT WITH A CHARACTER CODE OF 77 IS USED TO ; INDICATE END OF SCREEN. IT PROVIDES A PERIODIC INTERRUPT ; FOR SERVICING THE SCROLLER. SINCE THE INTERRUPT IS REQUIRED ; TO REMOVE CHARACTERS FROM THE OUTPUT RING BUFFER, IT IS ; IMPORTANT THAT THE DPU BE RUNNING. THE USER WHO LINKS TO ; THE SCROLL FILE AND STOPS THE DPU FOR LONG PERIODS OF TIME ; WHILE USING TTY OUTPUT RISKS HANGING RT11. SCBGIN=. ; THE FOLLOWING 7 WORDS, SCTPS THRU SCPVEC, MUST BE FIRST ; AND THEIR ORDER SHOULD NOT BE CHANGED. SCTPS: .WORD 0 ;SET TO 100 TO INDICATE CHAR. READY SCTPB: .WORD 0 ;OUTPUT CHAR. FROM TTOINT IN RMON SCMAX: .WORD 0 ;MAX. LINES OF SCROLLING SCLINK: DJMP ;SCROLLER LINK FILE FOR USER LINKS SCTOP-SCTPS SCTC: .WORD SCTRLC-SCTPS ;ADDRESS OF CTRL/C ROUTINE SCPVEC: .WORD 64 ;TELEPRINTER VECTOR ;DV19 SCECHO: .BYTE 1 ;TTY ECHO FLAG(1 DON'T; -1 DO) SCTTF: .BYTE 0 ;TT WAIT FLAG SCSTOP: SCHEAD-2-SCTPS ;PTR TO STOP CODE SCHDP: .WORD SCHEAD-SCTPS ;POINTER TO HEADER SCCHMX: .WORD 0 ;MAX. CHAR. COUNT SCMCNT: .WORD 0 ;MASTER LINE COUNT SCADVF: .BYTE 0 ;PAGE ADVANCE FLAG(1=WAIT, 0=GO) SCLOCK: .BYTE 0 ;SCROLL LOCK FLAG(0 UNLOCK;NON-0 LOCK) SCPSSV: .WORD 0 ;SAVE AREA FOR TTPS CONTENTS SCPBSV: .WORD 0 ;SAVE AREA FOR TTPB CONTENTS $SCINT: MOV @#SYSPTR,-(SP) JSR R5,@(SP)+ ;GO TO SYSTEM STATE .WORD ^C&PR7 ;AT PRIORITY 0 ;DV19 MOV R3,-(SP) MOV SCTPB,R3 ;RESTORE R3 FOR ECHO SC1MOR: MOV SCTRLR,R5 ;POINT TO LAST CHAR. TSTB SCTTF ;TT ECHO IN PROGRESS? BNE 8$ ;YES TSTB SCADVF ;PAGE FULL? BNE SCRESM ;YES, RESUME DISPLAY CLR @SCPSSV ;CLEAR ANY INTR. TST SCTPS ;CHAR TO BE ADDED? BEQ SCRESM ;JUST EXIT 1$: TST SCTPB ;SOMETHING THERE? BNE 2$ ;YES, GO ON CLR -(SP) ;SIMUL. AN INTER. ;DV15 MOV @SCPVEC,R4 ;GET ADDR. IN TRAP ;DV19 JSR PC,(R4) ;CALL PRINTER ROUTINE 2$: MOV SCTPB,R3 ;CHAR TO R3 .IF NE BF ;F/B ONLY CMP #10,R3 ;BACK SPACE? BNE 4$ ;NO DEC R5 ;POINT TO PREV. CHAR CMP R5,SCBUFS ;WRAP AROUND? BHIS 3$ ;NO, O.K. MOV SCBUFE,R5 ;YES, WRAP TO END 3$: CMPB #12,@R5 ;BUT DON'T BACK SPACE BEQ 5$ ;OVER A LINE FEED DEC SCCHCT ;DECREASE COUNT CLR R3 ;CLEAR THE RUBOUT CLR SCTPB CLRB @R5 ;CLEAR CHAR IN SCROLL BR SCTRLR-2 ;GO NULL IT OUT .IFTF ;S/J OR F/B 4$: CMPB #16,R3 ;SHIFT OUT CODE? BNE 6$ ;NO, GO ON 5$: CLR R3 ;YES, NULL IT OUT 6$: CMPB #7,R3 ;IS IT A BELL? BEQ 7$ ;YES, FORCE AN ECHO TSTB SCECHO ;SHOULD WE ECHO? BPL 10$ ;NO, SCROLL ONLY 7$: INCB SCTTF ;SET TT WAIT FLAG 8$: TSTB @SCPSSV ;TTY BUSY? BEQ SCRESM ;YES, EXIT FOR NOW CLRB SCTTF ;CLEAR WAIT FLAG MOV R3,@SCPBSV ;SEND TO PRINTER 10$: CLR SCTPB ;THEN CLEAR BUFFER TST R3 ;IS IT A NULL? BEQ SCRESM ;YES, SKIP ALL THIS JSR PC,SCNSRT ;NO, INSERT INTO SCROLL .ENABL LSB .IFF ;S/J ONLY CMPB #CR,R3 ;IS IT A CARRIAGE RETURN? BNE 1$ ;NO CLR SC72CT ;CLEAR CHAR COUNT, NEW LINE 1$: .IFTF ;S/J OR F/B CMPB #LF,R3 ;LINE FEED? BNE 2$ ;NO JSR PC,SCPACK ;PACK LF WITH NULL? 2$: .IFF ;S/J ONLY ; TEST NUMBER OF CHARACTERS IN THIS LINE AND GENERATE A CR/LF ; IF THEY EXCEED 72. THEN RESET CHAR. COUNT FOR A NEW LINE. CMP SC72CT,SCLWID ;FULL LINE? ;DV13 BLT 5$ ;NO, GO ON ;DV13 MOV (PC)+,R3 ;YES, INSERT A CR .BYTE CR,LF JSR PC,SCNSRT SWAB R3 ;THEN A LF JSR PC,SCNSRT JSR PC,SCPACK ;PACK WORD WITH NULL? CLR SC72CT ;CLEAR CHARACTER COUNT 5$: .IFTF ;S/J OR F/B MOV R5,(PC)+ ;THEN SAVE THE SCTRLR: .WORD SCBUFR-SCTPS ;PTR TO LAST CHARACTER CLRB (R5)+ ;PUT A NULL AFTER LAST CHAR. ;EVEN IT SO STOP BIC #1,R5 ;CODE FITS ON WORD BOUND JSR PC,SCWRAP ;WRAP AROUND? MOV #SOCODE,(R5) ;INSERT STOP CODE TST SCLF ;WAS IT A LF? BEQ SC1MOR ;NO, GET ANOTHER CHAR. CLR SCLF ;YES, CLEAR THE FLAG SCRESM: MOV (SP)+,R3 SCSTRT: MOV SCHDP,@#DPC ;START DISPLAY RTS PC .IFF ;S/J ONLY ;DV13 SCLWID: .WORD 72. ;LINE WIDTH ;DV13 .IFTF ;S/J OR F/B ;DV13 .DSABL LSB ; SUBROUTINE TO INSERT A SINGLE CHARACTER INTO THE SCROLL BUFFER. ; TESTS FOR BUFFER FULL AND DELETES A LINE IF NECESSARY. ALSO ; CHECKS FOR WRAP AROUND. CHARACTER IN R3, BUFFER PTR. IN R5. .ENABL LSB SCNSRT: MOVB R3,(R5)+ ;MOVE CHAR TO BUFR INC (PC)+ ;BUMP CHAR COUNT SCCHCT: .WORD 0 ;CURRENT CHARACTER COUNT .IFF ;S/J ONLY CMPB R3,#40 ;IS IT PRINTING CHAR? BLT 1$ ;NO INC (PC)+ ;BUMP THE CURRENT SC72CT: .WORD 0 ;LINE CHARACTER COUNT .IFTF ;S/J OR F/B 1$: CMP SCCHCT,SCCHMX ;FULL? BLT 3$ ;NO TST SCLNCT ;YES, BUT IS THERE A LINE? BNE 2$ ;YES, GO AHEAD MOVB #LF,-(R5) ;NO LINE, SO CREATE ONE INC SCLNCT 2$: JSR PC,SCDEL ;DELETE A LINE 3$: JSR PC,SCWRAP ;CHECK FOR WRAP AROUND RTS PC .DSABL LSB .ENDC ; SUBROUTINE TO PROCESS LINE FEEDS. THE LINE COUNT IS INCREMENTED ; AND THE LINE FEED FLAG IS SET TO TERMINATE INPUT FOR THIS ; INTERRUPT. IF THE LF WAS INSERTED ON AN EVEN BYTE, A NULL ; IS PACKED INTO THE ODD BYTE SO THE NEXT LINE WILL START ON AN ; EVEN BYTE, AN ASSUMPTION MADE IN SCDEL. SCPACK: INC (PC)+ ;SET THE LF FLAG SCLF: .WORD 0 ;LINE FEED RECEIVED FLAG INC (PC)+ ;BUMP THE LINE COUNT SCLNCT: .WORD 0 ;CURRENT LINE COUNT CLR R3 BIT #1,R5 ;ODD BYTE? BEQ 2$ ;NO, GO ON JSR PC,SCNSRT ;YES, PACK WITH A NULL 2$: CMP SCLNCT,SCMAX ;TOO MANY LINES? BLT 3$ ;NO JSR PC,SCDEL ;YES,DELETE ONE BR 2$ 3$: RTS PC ; SUBROUTINE TO CHECK FOR WRAP AROUND. R5 IS POINTING TO SCROLL BUFFER. ; RESET R5 TO TOP OF SCROLL BUFFER IF NECESSARY. .ENABL LSB SCWRAP: CMP R5,SCBUFE ;END OF BUFFER? BLO 1$ MOV (PC)+,R5 ;YES, RESET R5 TO TOP SCBUFS: .WORD SCBUFR-SCTPS ;PTR TO START OF BUFFER 1$: RTS PC .DSABL LSB ; DELETE A LINE - R4 POINTS TO START OF FIRST LINE OF SCROLL DISPLAY. ; LINES ARE DELETED FROM THE TOP OF THE DISPLAY. .ENABL LSB SCDEL: MOV SCPNTR,R4 ;POINT TO FIRST LINE 1$: MOVB @R4,-(SP) ;GET A CHARACTER DEC SCCHCT ;DEC. CHAR COUNT JSR PC,SCCLR ;CLEAR OUT A CHAR. CMPB #LF,(SP)+ ;END OF LINE? =LF BNE 1$ ;NO, CLEAR ANOTHER DEC SCLNCT ;DECR. LINE COUNT BIT #1,R4 ;WAS LF ON EVEN BYTE? BEQ 2$ ;NO DEC SCCHCT ;YES,BUMP OVER NULL IN ODD BYTE INC R4 ;AND UPDATE POINTER 2$: MOV R4,SCPNTR ;RESET POINTER TSTB SCLOCK ;SCROLL LOCK IN EFFECT? BEQ 5$ ;NO INC (PC)+ ;INC. PAGE LINE COUNT SCPGCT: .WORD 1 ;PAGE LINE COUNT (INIT TO 1) CMP SCPGCT,SCMAX ;FILLED THE PAGE YET? BLT 5$ ;NO, O.K. INCB SCADVF ;YES, SET FLAG TO LOCK IT 5$: RTS PC .DSABL LSB ; SUBROUTINE TO CLEAR A CHARACTER AND CHANGE COUNT. SCCLR: CLRB (R4)+ ;CLEAR THE CHARACTER CMP R4,(PC)+ ;WRAP AROUND? SCBUFE: .WORD 0 ;PTR TO END OF BUFFER BLO 1$ ;NO MOV SCBUFS,R4 ;YES 1$: RTS PC .SBTTL CONTROL CHARACTER INTERCEPT ROUTINE ; ; THIS ROUTINE INTERCEPTS CONTROL CHARACTERS IN THE RT11 RMON ; TTY HANDLER BEFORE THEY ARE CONVERTED TO PRINTING FORMAT ; (^ CHAR.). CONTROL CHARACTERS USED BY THE SCROLLER ARE ; ACTED UPON BEFORE CONTROL IS RETURNED TO THE MONITOR. ; CONTROL C CAUSES RESTORATION OF THE SCROLL BUFFER TO THE ; DPU LOOP AND RESTORES THE SHIFT OUT INTERRUPT TRAP ADDR. ; ; THE OTHER CONTROL CHARACTERS HAVE THE FOLLOWING FUNCTIONS: ; ; CTRL A ADVANCE THE SCROLL A PAGE, IF LOCKED ; CTRL Q CLEAR THE SCROLL LOCK FLAG ; CTRL S SET THE SCROLL LOCK FLAG ; CTRL E TOGGLE THE TTY PRINTER ECHO FLAG ; THE BIC INSTRUCTION MUST HAVE THE TAG SCEXAM! .ENABL LSB SCEXAM: BIC #177600,R0 ;THIS INSTRUCTION MUST BE HERE .IF NE BF MOV @#30,-(SP) ;CHECK FOR PAGE MODE SUB #2,@SP TSTB @(SP)+ ;IS IT ON? BPL 99$ ;NO, SKIP THIS .ENDC CMP #'A-100,R0 ;CONTROL A? BEQ 3$ CMP #'Q-100,R0 ;CONTROL Q? BEQ 2$ CMP #'S-100,R0 ;CONTROL S? BEQ 4$ 99$: CMP #'C-100,R0 ;CONTROL C? BEQ 1$ CMP #'E-100,R0 ;CONTROL E? BNE 7$ ;NONE, JUST RETURN NEGB SCECHO ;TOGGLE ECHO FLAG BR 6$ ;THEN EXIT 1$: JSR PC,SCDSTP ;STOP DISPLAY FIRST CLR SCADVF ;PAGE ADVANCE FLAGS .IF EQ BF JSR PC,SCTRLC ;CALL CTRL/C CODE .IFF JSR PC,SCSTRT ;START THE DISPLAY .ENDC 7$: TST R0 ;SET UP TO RETURN RTS PC 2$: CLRB SCLOCK ;CLEAR SCROLL LOCK FLAG 3$: MOV #1,SCPGCT ;RESET PAGE LINE COUNT CLR R0 ;CLEAR ADVANCE FLAG BR 5$ 4$: MOVB R0,SCLOCK ;SET THE LOCK FLAG NON-0 5$: MOVB R0,SCADVF ;LOCK THE PAGE 6$: CLR R0 ;CHANGE TO NULL RTS PC .DSABL LSB ; CTRL/C ROUTINE TO UNLINK ANY USER FILE AND CLEAR THE VECTORS SCTRLC: MOV #SCTOP-SCTPS,SCLINK+2 ;RESTORE SCROLL MOV SCMCNT,SCMAX ;RESTORE LINE COUNT MOV R1,-(SP) MOV @#54,R1 ;POINT TO RMON BIC #GTLNK$,(R1) ;CLEAR USER LINK BIT MOV (R1),R1 ;R1 = VT11 VECTOR CLR (R1)+ CLR (R1)+ CLR (R1)+ CLR (R1)+ MOV (PC)+,(R1)+ ;SET UP VECTOR SCILOC: .WORD $SCINT-SCTPS ;ADDR OF INT. HANDLER MOV (PC)+,@R1 ;SET UP PRIORITY .WORD PR7 ;DISPLAY PRIORITY MOV (SP)+,R1 SCSLNK: JMP SCSTRT ;GO START DISPLAY ; SUBROUTINE TO STOP A VT11 DISPLAY PROCESSOR SCDSUP: MOV SCSTOP,@#DPC ;STOP THE DISPLAY SCDSTP: BIT #100100,@#DSR ;IS DISPLAY STOPPED? BEQ SCDSUP ;NO, MUST BE RUNNING RTS PC ; SUBROUTINE CALLED FROM TTOPUT IN RMON. IT INSURES ; THE DISPLAY IS STARTED AGAIN IF IT WAS ZAPPED BY A ; HARDWARE RESET FROM SOME CUSP. ; .IF EQ BF SCSTIT: BIC #177600,R4 ;DO INSTR THAT WAS OVRLYED TST @#DPC ;DISPLAY ZAPPED BY RESET? BEQ SCSLNK ;YES, GO START IT RTS PC ;RETURN TO MONITOR .ENDC .SBTTL HEAD OF SCROLL BUFFER ; THIS IS THE ACTUAL SCROLL BUFFER. THE HEADER AND ALL ; POINTERS ARE POSITIONED JUST BEHIND THE SCROLLER CODE ; TO FACILITATE RELOCATION ALONG WITH THE SCROLLER CODE, INDEPEN- ; DENT OF BUFFER SIZE. ONLY A FINAL DJMP TO BUFFER TOP IS REQUIRED ; AT BUFFER END. ; DISPLAY PROCESSOR MNEMONICS DNOP=164000 DSTOP=173400 DJMP=160000 CHAR=100000 POINT=114000 INT4=3000 LPOFF=100 BLKON=30 BLKOFF=20 SOCODE=77416 ;SHIFT OUT!177 JSRABS=004737 ;JSR (MODE 3) ; SCROLL HEADER 173000 ;STOP THE DISPLAY SCHEAD: CHAR!BLKON ;CHAR MODE!BLINKING .WORD 77417 ;SHIFT IN, THEN CURSOR POINT!BLKOFF!LPOFF!INT4 ;RESET CONDITIONS .WORD 0 SCYPS: .WORD 0 ;AND POSITION BEAM DJMP SCLINK-SCTPS ;JUMP TO LINK SEGMENT SCTOP: CHAR!BLKOFF!LPOFF ;RETURN HERE AND PREPARE .WORD 171040 ;INITIALIZE DISPLAY DJMP ;TO DISPLAY THE BUFFER. SCPNTR: .WORD SCBUFR-SCTPS ;JUMP TO FIRST LINE. SCBUFR: .WORD SOCODE ;END OF SCROLL ; ALL OF THE CODE THAT FOLLOWS IS ONE-TIME INITIALIZATION ; CODE THAT IS PLACED IN THE SCROLL BUFFER. IT WILL BE ; OVERLAYED WITH CHARACTERS ONCE THE SCROLLER STARTS. ; ASSUMES: R1 -> SCROLL WORD IN RMON (SCROLL) ; R4 -> BEGINNING OF SCROLL LOGIC (SCTPS) ; R0 = BUFFER SIZE ; DESTROYS: R0,R2,R3,R4 .MACRO RELOC TAG ADD R4,TAG .ENDM SCINIT: MOV (SP)+,(R4) ;SET UP LINE COUNT MOV (SP)+,(R4) ;AND Y POS .IF EQ BF MOV (SP)+,(R4) ;SET LINE WIDTH ;DV13 .ENDC MOV R4,@R1 ;STORE PTR TO SCROLLER MOV R0,(R4) ;AND BUFR SIZE RELOC SCTC RELOC SCLINK+2 RELOC SCTRLR RELOC SCBUFS RELOC SCPNTR RELOC SCSTOP RELOC SCHDP RELOC SCYPS+4 RELOC SCILOC RELOC SCTRLC+2 MOV SCPNTR,R3 ;POINT TO BUFFER ADD SCCHMX,R3 ;ADJUST TO END SUB #2,SCCHMX ;REDUCE CNT FOR STOP CODE MOV R3,SCBUFE ;STORE IT MOV #DJMP,(R3)+ ;THEN INSERT FINAL DJMP MOV SCPNTR,(R3)+ ;TO TOP OF BUFFER MOV @#SYSPTR,R0 ;NOW POINT TO RMON MOV #PR7,-(SP) ;WANT PRIORITY 7 ;DV15 JSR PC,100$ ;DV15 .IF EQ BF ;S/U MOV R4,R3 ADD #SCSTIT-SCTPS,R3 ;POINT TO SCSTIT MOV #TTSCRL-$RMON,R2 ;POINT TO TTSCRL ADD R0,R2 ;RELOCATE IT MOV #JSRABS,(R2)+ ;OVERLAY TTSCRL WITH MOV R3,(R2) ;JSR TO SCSTIT .IFTF ;BOTH MOV R4,R3 ADD #SCEXAM-SCTPS,R3 ;POINT TO SCEXAM MOV R0,R2 ADD #SCLNK2-$RMON,R2 ;POINT TO LOC. IN RMON .ENDC MOV #JSRABS,(R2)+ ;OVERLAY WITH JSR MOV R3,(R2) ;TO SCEXAM MOV (R1),SCPSSV ;SAVE CONTENTS MOV R4,(R1) ;DIVERT CHARS. TO SCROLLER TST (R4)+ MOV (R1),SCPBSV ;SAVE CONTENTS MOV R4,(R1) MOV (R1),R2 ;R2 -> VT11 VECTOR ADD #10,R2 ;ADJUST TO SHIFT OUT VECTOR MOV #1,R4 ;PROTECT TWO BITS MOV R1,R0 ;POINT R0 T0 THE ADD #LOWMAP-SCROLL,R0 ;PROTECT BIT MAP MOV (R1),R1 ;R1 -> KMON JSR PC,(R1) ;GO SET THE BITS JSR PC,SCTRLC ;START THE DISPLAY JSR PC,SCSTRT MOV (SP),-(SP) ;COPY RETURN ADDRESS ;DV15 CLR 2(SP) ;SIMULATE ZERO PRIORITY ;DV15 100$: RTI ;DV15 SCEND=. SCRSIZ=SCBUFR-SCBGIN+4 SCRTOT=/2 .SBTTL END .IIF DF NLOVLY, .LIST .END BF=1 ; RT-11 BOOTSTRAP ; ; DEC-11-ORBTA-E ; ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; CONDITIONAL ASSEMBLY OF BOOT FOR S/J OR F/B SYSTEM .IIF NDF BF BF=0 ;DEFAULT TO S/J ;BOOTSTRAP UPDATE LEVEL 10 .IF NE BF .SBTTL FOREGROUND/BACKGROUND .IFF .SBTTL SINGLE/JOB .ENDC .IF NDF $RFSYS ;TURN ON $RKSYS IF ALL OTHERS ARE OFF .IF NDF $DTSYS .IF NDF $DPSYS .IF NDF $DSSYS .IF NDF $RCSYS .IF NDF $DXSYS $RKSYS= 0 ;IT MUST BE AN RK SYSTEM .ENDC .ENDC .ENDC .ENDC .ENDC .ENDC UPDATE = 04. ;EXTERNAL UPDATE NUMBER .RADIX 10. .IRP ...,<\UPDATE> .IF DF $RKSYS .TITLE RK BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $RFSYS .TITLE RF BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $DTSYS .TITLE DT BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $DPSYS .TITLE DP BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $DSSYS .TITLE DS BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $DXSYS .TITLE DX BOOT V02C-0'... FOR RT-11 V02C .ENDC .IF DF $RCSYS .TITLE RC BOOT V02C-0'... FOR RT-11 V02C .ENDC .ENDR .RADIX 8. .SBTTL MACROS, GLOBALS .MCALL ..V1.. ..V1.. .MCALL .EXIT, .LOOKUP,.PRINT, .SAVESTATUS ; GLOBAL REFERENCES TO MONITOR: .GLOBL $DVREC, $ENTRY, $INPTR, $KMLOC, $MONBL, $PNAME, $SLOT .GLOBL $SWPBL, $USRLC, $PNAMO .GLOBL BSTRNG, CORPTR, DKASSG, FILLER, HWFPU$, HWDSP$, KMLOC .GLOBL KMON, KMONSZ, KW11L$, MAPOFF, QCOMP, RT11SZ .GLOBL RTLEN, RTSIZE, SWAPSZ, SYENTO, SYINDO, SYNCH, SYASSG .GLOBL SYSLOW, TTIBUF, TTOBUF, USRLOC, USRSZ, MAXSYH .GLOBL LSI11$,$MFPS,$INTEN,GETPSW ;DV15 .GLOBL RELLST ; FOLLOWING ARE GLOBALS FOR EITHER F/B OR S/J SYSTEM, BUT NOT BOTH .IF NE BF .GLOBL BCNTXT, BKGND1, BKGND2, BKGND3, CNTXT, FUDGE1, FUDGE2 .GLOBL MSGENT, RMONSP, SWIPTR, SWOPTR, TTIUSR, TTOUSR, .$CRTN .GLOBL IMPLOC ;DV15 .IFF .GLOBL AVAIL, I.CSW, FPPADD, FPPIGN, MONLOC, TRAPLC, TRAPER .ENDC PERM = 2000 ;STATUS WORD FOR PERMANENT FILE ENDBLK = 4000 ;STATUS OF END OF SEGMENT MARK JSW = 44 ;ADDRESS OF JOB STATUS SR = 177570 ;CONSOLE SWITCH REGISTER PS = 177776 ;PROCESSOR STATUS WORD ;DV15 PR0 = 0 PR4 = 200 PR7 = 340 ; REGISTER DEFINITIONS: R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; MONITOR OFFSET CONSTANTS CONFIG = 300 ;HARDWARE CONFIGURATION WORD SYUNIT = 274 ;SYSTEM UNIT # LKCS = 177546 ;CLOCK STATUS REGISTER GT40 = 172000 ;GT40 LOCATION TKS = 177560 ;KEYBOARD STATUS TKB = 177562 ; " BUFFER TPS = 177564 ;PRINTER STATUS TPB = 177566 ; " BUFFER .SBTTL ASECT .ASECT . = 0 240 ;BOOT VALIDATION PATTERN BR BOOT1 ;BRANCH TO REAL BOOT .IF NDF $DXSYS . = 34 ;PUT THE JUMP BOOT IN TRAP VECTOR BOOT1: JMP BOOT ;START THE BOOTSTRAP .IFF CSGO= 1 ;START FUNCTION CSEBUF= 2 ;EMPTY BUFFER CSRD= 6 ;READ SECTOR CSUNIT= 20 ;UNIT 1 SELECTION CSDONE= 40 ;RX DONE CSTR= 200 ;RXDB TRANSFER READY CSERR= 100000 ;RX ERROR RXCS= 177170 ;RXCS STATUS REGISTER . = 14 ;INITIALIZE BPT AND IOT VECTORS .WORD READS ;ON BPT INTERUPT TO READS ROUTINE .WORD 340 ;PS SET TO 7 ;DV15 .WORD WAIT ;ON IOT INTERUPT TO WAIT ROUTINE .WORD 340 ;PS SET TO 7 ;DV15 . = 34 ;34-52 USEABLE BOOT1: MOVB UNITRD(R0),RDCMD;SET READ FUNCTION FOR CORRECT UNIT RETRY: MOV @PC,SP ;INIT SP WITH NEXT INSTRUCTION MOV #200,R2 ;AREA TO READ IN NEXT PART OF BOOT CLR R0 ;SET TRACK NUMBER BR 2$ ;OUT OF ROOM HERE, GO TO CONTINUATION . = 70 ;PAPER TAPE VECTORS 2$: MOV SP,R1 ;SET TO BIG WORD COUNT INC R0 ;SET TO ABSOLUTE TRACK 1 BR 3$ ;BRANCH TO CONTINUATION . = 104 ;PROGRAMMABLE CLOCK 3$: MOV @PC,R3 ;ABSOLUTE SECTOR 3 FOR NEXT PART BPT ;CALL READS SUBROUTINE BR BOOT2 ;BRANCH TO CONTINUATION UNITRD: .BYTE CSGO+CSRD ;READ FROM UNIT 0, SETS WEIRD BUT OK PS .BYTE CSGO+CSRD+CSUNIT;READ FROM UNIT 1 . = 120 ;LOTS OF UNUSED VECTORS, (DR-11B?) READS: MOV #RXCS,R4 ;R4 -> RX STATUS REGISTER MOV R4,R5 ;R5 WILL POINT TO RX DATA BUFFER MOV (PC)+,(R5)+ ;INITIATE READ FUNCTION RDCMD: .WORD 0 ;GETS FILLED WITH READ COMMAND IOT ;CALL WAIT SUBROUTINE MOV R3,@R5 ;LOAD SECTOR NUMBER INTO RXDB IOT ;CALL WAIT SUBROUTINE MOV R0,@R5 ;LOAD TRACK NUMBER INTO RXDB IOT ;CALL WAIT SUBROUTINE MOV #CSGO+CSEBUF,@R4;LOAD EMPTY BUFFER FUNCTION INTO RXCS BROFFS = READF-. ;USE FOR COMPUTING BR OFFSET ;LP1 RDX: IOT ;CALL WAIT SUBROUTINE ;LP1 TSTB @R4 ;IS TRANSFER READY UP? BPL RTIRET ;BRANCH IF NOT, SECTOR MUST BE LOADED MOVB @R5,(R2)+ ;MOVE DATA BYTE TO MEMORY DEC R1 ;CHECK BYTE COUNT BGT RDX ;LOOP AS LONG AS WORD COUNT NOT UP ;LP1 CLR R2 ;KLUDGE TO SLUFF BUFFER IF SHORT WD CNT BR RDX ;LOOP ;LP1 WAIT: TST @R4 ;IS TR, ERR, DONE UP? INT ENB CAN'T BE BEQ WAIT ;LOOP TILL SOMETHING BMI RETRY ;START AGAIN IF ERROR RTIRET: RTI ;RETURN . = 200 ;SECTOR 2 OF RX BOOT BOOT2: CMPB (R3)+,(R3)+ ;BUMP TO SECTOR 5 BPT ;CALL READS SUBROUTINE CMPB (R3)+,(R3)+ ;BUMP TO SECTOR 7 BPT ;CALL READS SUBROUTINE BIT #CSUNIT,RDCMD ;CHECK UNIT ID BNE 1$ ;BRANCH IF BOOTING UNIT 1, R0=1 CLR R0 ;SET TO UNIT 0 1$: MOV R0,(PC)+ ;SAVE UNIT BOOTED FROM FOR LATER BTUNIT: .WORD 0 ;SAVE THE UNIT HERE MOV #TRWAIT,@#20 ;LETS HANDLE ERRORS DIFFERENTLY MOV (PC)+,@(PC)+ ;USE FASTER ROUTINE TO EMPTY SILO ;LP1 BR .+BROFFS ;REPLACE IOT AT RDX WITH THIS INSTR ;LP1 RDX ;-> TO REPLACED INSTRUCTION ;LP1 BR BOOT ;NOW WE ARE READY TO DO THE REAL BOOT . = 330 ;SKIP OVER SIGNON MESSAGE ;LP1 READF: TST @R4 ;ERROR, DONE, OR TR UP? ;LP1 BEQ READF ;BR IF NOT ;LP1 BMI BIOERR ;BR IF ERROR ;LP1 TSTB @R4 ;TR OR DONE? ;LP1 BPL RTIRET ;BR IF DONE ;LP1 MOVB @R5,(R2)+ ;MOVE DATA BYTE TO MEMORY ;LP1 DEC R1 ;CHECK BYTE COUNT ;LP1 BGT READF ;LOOP IF MORE ;LP1 CLR R2 ;SLUFF BUFFER IF SHORT WD CNT ;LP1 BR READF ;LOOP ;LP1 .ENDC .IF DF $RKSYS . = 330 ; BLOOK IS THE ARGUMENT AREA FOR AN RT-11 LOOKUP. BLOOK: .RAD50 /SY / FNAME: .WORD 0,0 ;FILENAME GOES HERE .RAD50 /SYS/ CBLOK: .BLKW 5 ;SAVESTATUS GOES HERE .ENDC ; FOLLOWING ARE THE BOOTSTRAP I/O DRIVERS FOR EACH VALID ; SYSTEM DEVICE. ; CALLING SEQUENCE: ; R0 = PHYSICAL BLOCK TO READ/WRITE ; R1 = WORD COUNT ; R2 = BUFFER ADDRESS ; R3,R4,R5 ARE AVAILABLE AND MAY BE DESTROYED BY THE DRIVER ; THE DRIVER MUST GO TO BIOERR IF A FATAL I/O ERROR OCCURS. ; IT MUST ALSO INVOKE THE MACRO SYSDEV .MACRO SYSDEV NAME,VECTOR .GLOBL NAME'INT, NAME'SIZE ;DEFINE SYSTEM DEVICE INTERRUPT & SIZE SYNAME = 0 .IRPC X, SYNAME = *50 .ENDR SYVEC = VECTOR ;IT VECTORS TO THIS LOCATION . = SYVEC ;AT THE VECTORS .WORD NAME'INT,340 ; PUT A VECTOR TO THE SYSTEM HANDLER .IF NDF $DXSYS ;DV15 . = SYSIZE .WORD NAME'SIZE ;PUT HANDLER SIZE WHERE IT CAN BE USED .ENDC ;DV15 . = 402 ;AND START THE CODE AT 402 SYBITO = VECTOR / 20 ;OFFSET INTO BIT MAP FOR PROTECTION SYBITS = ^B11000000 ;COMPUTE ACTUAL BITS .REPT / 4 ;VECTOR IS A MULTIPLE OF 4 SYBITS = SYBITS / 4 ;SHIFT RIGHT 2 MORE BITS .ENDR .ENDM SYSDEV .IF DF $DSSYS ;RS SYSTEM .SBTTL BOOTSTRAP I/O DRIVER - RS11 ; RS11 DISK HANDLER .IF DF MBUSSC SYSDEV DS,150 RSCS2 = 176310 .ENDC .IF NDF MBUSSC SYSDEV DS,204 RSCS2=172050 .ENDC READ: MOV R0,R4 ;COPY BLOCK NUMBER MOV #RSCS2,R5 ;POINT TO REGISTERS MOV (R5),-(SP) ;SAVE UNIT # MOV #40,@R5 ;CONTROLLER CLEAR BIT #2,16(R5) ;WHAT IS IT? BNE 1$ ;IT'S AN RS04 ASL R4 ;IT'S AN RS03 1$: ASL R4 ;CONVERT TO TRACK/SECTOR BIC #^C7,(SP) ;STRIP TO UNIT BITS MOV (SP)+,(R5) ;SET UNIT MOV R4,-(R5) ;SET BLOCK MOV R2,-(R5) MOV R1,-(R5) NEG @R5 MOV #71,-(R5) ;GO, READ, NO INTERRUPT 2$: BIT #100200,@R5 ;WAIT FOR DONE OR ERROR BEQ 2$ BMI BIOERR ;BOOT ERROR RTS PC .ENDC .IF DF $DPSYS ;CONDITIONAL FOR RP11 DISK .SBTTL BOOTSTRAP I/O DRIVER - RP11 ; RP11 DISK DRIVER SYSDEV DP,254 ;DEVICE IS RP. IT VECTORS TO 254 RPCS= 176714 ;RP11 DEVICE CONTROL REG RPDS= 176710 ;RP03 DEVICE STATUS REG RPDA= 176724 ;RP03 DISK ADRS REGISTER CS.GO= 000001 ;GO BIT IN CONTROL & STATUS CS.RD= 000004 ;READ FUNCTION CODE CS.DRV= 003400 ;UNIT SELECT BITS DS.ATT= 000377 ;UNIT ATTN BITS READ: MOV R0,R3 ;R3 = BLOCK # JSR R2,DIV ;GET SECTOR NUMBER .WORD 10. ;BY DIVIDING BY 10 MOV R4,-(SP) ;SAVE SECTOR MOV R5,R3 ;SET NEW DIVIDEND JSR R2,DIV ;AND COMPUTE CYL & TRACK .WORD 20. ;BY DIVIDING BY 20 SWAB R4 ;POSITION TRACK IN HIGH BYTE BIS (SP)+,R4 ;AND INSTALL SECTOR MOV #RPDA,R3 ;R3 -> DISK ADRS REG MOV R4,@R3 ;SET TRACK & SECTOR MOV R5,-(R3) ;AND CYLINDER MOV R2,-(R3) ;AND BUS ADDRESS MOV R1,-(R3) ;AND WORD COUNT NEG @R3 ;MAKE NEGATIVE BIC #^C,-(R3) ;CLEAR ALL BUT UNIT # BIS #CS.RD+CS.GO,@R3 ; AND START READ 1$: TSTB @R3 ;WAIT UNTIL TRANSFER COMPLETE BPL 1$ TST @R3 ;ANY ERRORS? BMI BIOERR ;YES MOVB #DS.ATT,@#RPDS ;CLEAR UNIT ATTN FOR BOTH CLRB @#RPDS ; OLD & ECO'D CONTROLLERS RTS PC ;ELSE JUST RETURN ; DIVIDE ROUTINE FOR RP HANDLER. ; R5 = R3 / @R2, REMAINDER IN R4 DIV: CLR R5 ;QUOT. = 0 CLR R4 ;REM. = 0 TST R3 ;IS DIVIDEND 0? BEQ 4$ ;YES - JUST RETURN COM R5 ;QUOT. = -1 & SET CARRY 1$: ROL R3 ;NORMALIZE BCC 1$ 2$: ROL R4 ;SHIFT & SUBTRACT CMP R4,@R2 BLO 3$ SUB @R2,R4 3$: ROL R5 ASL R3 BNE 2$ COM R5 ;FIX QUOTIENT 4$: TST (R2)+ RTS R2 .ENDC .IF DF $RKSYS!$RFSYS!$RCSYS .IFDF $RFSYS ;CONDITIONAL FOR RF DISK .SBTTL BOOTSTRAP I/O DRIVER - RF11 ; RF11 DISK HANDLER SYSDEV RF,204 ;DEVICE IS RF. IT VECTORS TO 204. RFCS = 177460 ;CONTROL & STATUS REGISTER RFWC = 177462 ;WORD COUNT RFMA = 177464 ;MEMORY ADDRESS RFDA = 177466 ;DISK ADDRESS RFDE = 177470 ;DISK ADDRESS EXTENSION RFDB = 177472 ;DATA BUFFER READ: MOV #RFDA,R3 ;POINT TO DISK ADDRESS MOV R0,R5 ;COPY BLOCK NUMBER SWAB R5 ;MULTIPLY BY 256 TO GET WORD # ON DISK MOV R5,R4 ;SAVE HIGH ORDER DISK ADDRESS CLRB R5 ;MAKE DA AN EVEN BLOCK NUMBER MOV R5,(R3)+ ;PUT LOW ORDER ADDRESS IN CONTROLLER BIC #177740,R4 ;ISOLATE HIGH ORDER ADDRESS MOV R4,(R3) ;PUT IT IN CONTROLLER TST -(R3) ;RESET POINTER .ENDC .IFDF $RCSYS ;CONDITIONAL FOR RC (RS64) DISK .SBTTL BOOTSTRAP I/O DRIVER - RC11 ; RC11 DISK HANDLER SYSDEV RC,210 ;DEVICE IS RC. IT VECTORS TO 210 ; RC11 CONTROL REGISTERS RCLA= 177440 ;LOOK AHEAD REGISTER RCDA= 177442 ;DISK ADDRESS REGISTER RCER= 177444 ;DISK ERROR STATUS REGISTER RCCS= 177446 ;DISK CONTROL & STATUS REGISTER RCWC= 177450 ;WORD COUNT REGISTER RCCA= 177452 ;CURRENT ADDRESS REGISTER RCMN= 177454 ;MAINTENANCE REGISTER RCDB= 177456 ;DATA BUFFER REGISTER READ: MOV #RCDA,R3 ;PT TO DISK ADR REGISTER MOV R0,R5 ;GET BLOCK NUMBER ASL R5 ;CALCULATE DISK ADR FOR RCDA ASL R5 ;(UNIT,TRACK # & SECTOR ADR) ASL R5 ;[32 * 8=256] MOV R5,@R3 ;IND PROPER DISK ADR ADD #12,R3 ;PT TO CURRENT ADR REG + 12 ; /(INTERFACE TO COMMON CODE) .ENDC .IFDF $RKSYS .SBTTL BOOTSTRAP I/O DRIVER - RK05 ; RK05 DISK HANDLER SYSDEV RK,220 ;DEVICE IS RK. IT VECTORS TO 220 RKDA = 177412 ;RK DISK ADDRESS READ: MOV #14,R3 ;PHYSICAL BLOCK TO RK DISK ADD. BR 2$ ;ENTER BLOCK # COMPUTATION 1$: ADD #20,R3 ;CONVERT DISK ADDRESS 2$: SUB #14,R0 BPL 1$ ADD R3,R0 ;R0 HAS DISK ADDRESS 5$: MOV #RKDA,R3 ;POINT TO HARDWARE DISK ADDR REGISTER BIC #17777,@R3 ;LEAVE THE UNIT NUMBER BIS R0,(R3) ;PUT DISK ADDRESS INTO CONTROLLER .ENDC ; THIS CODE IS COMMON TO RK05,RC11 AND RF11 HANDLERS MOV R2,-(R3) ;BUFFER ADD. MOV R1,-(R3) ;WORD COUNT NEG (R3) ;(NEGATIVE) MOV #5,-(R3) ;START DISK READ 3$: TSTB (R3) ;WAIT UNTIL COMPLETE BPL 3$ TST (R3) ;ANY ERRORS? BMI BIOERR ;HARD HALT ON ERROR RTS PC .ENDC .IF DF $DTSYS .SBTTL BOOTSTRAP I/O DRIVER - DECTAPE ; DECTAPE BOOTSRAP HANDLER SYSDEV DT,214 ;DEVICE IS DT. IT VECTORS TO 214. TCCM = 177342 ;COMMAND REGISTER TCDT = 177350 ;DATA REGISTER TCST = 177340 ;STATUS REGISTER READ: MOV #TCCM,R4 ;R4 -> COMMAND REG MOV #TCDT,R3 ;R3 -> DATA REG DTSRCH: MOV R0,R5 ;COPY BLOCK NUMBER SUB #2,R5 ;SEARCH FOR 2 EARLIER MOV #4003,@R4 ;REVERSE,RNUM 2$: BIT #100200,@R4 ;WAIT TILL BLOCK FOUND BEQ 2$ BMI DTERR CMP R5,@R3 ;IS IT THE DESIRED BLOCK BLT DTSRCH ;NO,CONTINUE SEARCHING DTFWRD: MOV #3,@R4 ;SEARCH FORWARD (RNUM) 4$: BIT #100200,@R4 ;WAIT BEQ 4$ BMI DTERR CMP R0,@R3 ;DESIRED BLOCK BGT DTFWRD ;NO-SEARCH FORWARD BLT DTSRCH ;NO-SEARCH REVERSE MOV R2,-(R3) ;BUFFER ADDRESS NEG R1 MOV R1,-(R3) ;WORD COUNT MOV #5,@R4 ;READ DT4: BIT #100200,@R4 ;WAIT FOR COMPLETION BEQ DT4 BMI BIOERR ;READ ERROR CLR @R4 ;STOP DT RTS PC DTERR: TST @#TCST ;WHAT KIND OF ERROR ? BPL BIOERR ;NOT END ZONE BIT #4000,@R4 ;REVERSE? BNE DTFWRD ;THEN GO SEARCH FORWARD BR DTSRCH ;ELSE SEARCH REVERSE .ENDC .IF DF $DXSYS ;FLOPPY SYSTEM .SBTTL BOOTSTRAP I/O DRIVER - FLOPPY SYSDEV DX,264 ;FLOPPY VECTORS THROUGH 264 READ: ASL R0 ;CONVERT BLOCK TO LOGICAL SECTOR ASL R0 ;LSN=BLOCK*4 ASL R1 ;MAKE WORD COUNT BYTE COUNT 1$: MOV R0,-(SP) ;SAVE LSN FOR LATER MOV R0,R3 ;WE NEED 2 COPIES OF LSN FOR MAPPER MOV R0,R4 CLR R0 ;INIT FOR TRACK QUOTIENT BR 3$ ;JUMP INTO DIVIDE LOOP 2$: SUB #23.,R3 ;PERFORM MAGIC TRACK DISPLACEMENT 3$: INC R0 ;BUMP QUOTIENT, STARTS AT TRACK 1 SUB #26.,R4 ;TRACK=INTEGER(LSN/26) BPL 2$ ;LOOP - R4=REM(LSN/26)-26 CMP #-14.,R4 ;SET C IF SECTOR MAPS TO 1-13 ROL R3 ;PERFORM 2:1 INTERLEAVE 4$: SUB #26.,R3 ;ADJUST SECTOR INTO RANGE -1,-26 BPL 4$ ;(DIVIDE FOR REMAINDER ONLY) ADD #27.,R3 ;NOW PUT SECTOR INTO RANGE 1-26 BPT ;CALL READS SUBROUTINE MOV (SP)+,R0 ;GET THE LSN AGAIN INC R0 ;SET UP FOR NEXT LSN TST R1 ;WHATS LEFT IN THE WORD COUNT BGT 1$ ;BRANCH TO TRANSFER ANOTHER SECTOR RTS PC ;RETURN TRWAIT: TST @R4 ;ERROR, DONE, OR TR UP? BEQ TRWAIT ;BR IF NOT BPL RTIRET ;RETURN FROM INTERUPT ;***** THIS MUST FALL INTO BIOERR ***** .ENDC BIOERR: JSR R0,REPORT ;SAY THAT WE GOT ERROR .ASCIZ <15><12>\?B-I/O ERROR\<12> .EVEN .SBTTL BOOTSTRAP CORE DETERMINATION REPOR1: MOVB (R0)+,@#TPB ;PUT ANOTHER CHARACTER OUT REPORT: TSTB @#TPS ;WAIT FOR TYPER READY BPL REPORT ; ... TSTB @R0 ;ANYTHING MORE ? BNE REPOR1 ;YES, LOOP RESET ;STOP ALL DEVICES HALT BR .-2 ;KEEP HIM FROM CONTINUING BOOT: MOV #10000,SP ;SET STACK POINTER MOV #2,R0 ;READ IN SECOND PART OF BOOT MOV #*400,R1 ;EVERY BLOCK BUT THE ONE WE ARE IN MOV #1000,R2 ;INTO LOCATION 1000 JSR PC,READ .IIF GT .-1000, .ERROR ;BOOTSTRAP BLOCK 0 TOO BIG MOV #4,R3 ;POINT TO TRAP LOCATIONS MOV @R3,R5 ;SAVE TRAP LOC MOV #NXM,@R3 ;SET TRAP FOR NON EXISTENT MEMORY ;DV15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THIS BOOTSTRAP CAN SIMULATE ANY SIZE PDP-11. ; IF LOCATION 'FIDDLE' IS A HALT, THE CPU WILL STOP DURING THE BOOT. ; ON CONTINUE, THE TOP 5 BITS OF THE SWITCH REGISTER ARE USED TO ; SET THE TOP OF AVAILABLE CORE AS A MULTIPLE OF 1K. ; IF THE SR IS >= 160000 OR IF FIDDLE IS A BR 1$ , ; THE BOOTSTRAP WILL DO A NORMAL CORE DETERMINATION. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ENABL LSB FIDDLE: BR 1$ ;CHANGE TO HALT FOR FIDDLING MOV @#SR,R2 ;GET SWITCH VALUE BIC #3777,R2 ;ISOLATE TOP 5 BITS (1K INCREMENTS) CMP R2,#160000 ;SHOULD WE DO NORMAL CHECK ? BLO NXM ;NO, USE THE SR VALUE 1$: CLR R2 ;LOOK FOR TOP OF CORE 2$: ADD #4000,R2 ;MOVE TO NEXT 1K BANK CMP R2,#160000 ;REACHED 28K YET ? BEQ NXM ;YES, DO A 28K SYSTEM TST @R2 ;NO, SEE IF THIS LOCATION EXISTS BR 2$ ;KEEP GOING IF WE DIDN'T TRAP NXM: MOV #BCLR,@R3 ;NONMEMORY TRAPS HERE ;DV15 MOV @R3,10 ;BAD INSTRUCTIONS TRAP HERE MOV #TSLIST,R1 ;BITS FOR CLEARING ON ERROR TRAPS MOV R1,R0 .IF DF $DXSYS!$RKSYS ;DV15 TST @#PS ;TEST FOR LSI11 ;DV15 BIC (R1)+,-(R0) ;CLEAR BIT IF NOT LSI11, ADVANCE LIST ;DV15 BNE 5$ ;BR IF LSI11, ASSUME A CLOCK ;DV15 .IFTF ;DV15 TST @(PC)+ ;CHECK PRESENCE OF CLOCK LK.CS: .WORD LKCS .IFT ;DV15 5$: BIS (R1)+,@R0 ;ADVANCE LIST ;DV15 .IFF ;DV15 BIS (R1)+,-(R0) ;ADVANCE LIST ;DV15 .ENDC ;DV15 .DSABL LSB TST @#GT40 ;CHECK FOR DISPLAY BIS (R1)+,@R0 CFCC ;CHECK FOR FPU BIS (R1)+,@R0 MOV R5,(R3)+ ;RESTORE TRAP TST (R3)+ ;BUMP TO POINT TO 10 ;DV15 MOV R5,@R3 ;RESTORE 10 ;DV15 SUB #RTSIZE,R2 ;R2 NOW POINTS TO WHERE WE WANT THE KMON ADD #FILLER,R2 ;ABUT IT AGAINST THE TOP OF CORE .IF NDF $DXSYS ;DV15 SUB (PC)+,R2 ;RECOVER UNUSED CORE FROM SY: SYSIZE = . . = .+2 ;SYSTEM HANDLER SIZE PUT HERE ADD #MAXSYH,R2 ;THIS WAY BECAUSE NO GLOBAL ARITH. .ENDC ;DV15 CMP R2,#10000 ;IS IT JUST TOO TINY ? BLO TOOSML ;YES MOV R2,-(SP) ;PUT LOAD ADDRESS ON STACK MOV #1,R0 ;NOW READ FIRST DIRECTORY BLOCK DFND: ASL R0 ADD #4,R0 ;DIRECTORY STARTS AT 6 MOV #1000,R1 MOV #BUFFB,R2 JSR PC,READ ;READ THE SEGMENT MOV #BUFFB+10,R1 ;POINT TO START BLOCK WORD MOV (R1)+,R0 MONF: MOV R1,R2 ;SAVE ADDRESS OF STATUS WORD BIT #PERM,(R1)+ ;IS IT A PERMANENT FILE? BEQ 1$ ;NO. WE ARE TRYING TO FIND THE SUB (PC)+,(R1)+ ;FILE MONITR.SYS, AS THAT IS .RAD50 /MON/ ;THE CURRENT MONITOR. SUB (PC)+,(R1)+ .RAD50 /ITR/ SUB (PC)+,(R1) .RAD50 /SYS/ BNE 1$ ;LAST WAS NOT .SYS EXTENSION BIS -(R1),-(R1) ;BOTH MUST BE 0 BEQ MONFND ;FOUND THE MONITOR 1$: BIT #ENDBLK,(R2) ;IS THIS ALL IN SEGMENT? BNE 2$ ;YES. READ NEXT, IF ANY. ADD 10(R2),R0 ;INCREASE START BLOCK ADD #16,R2 ;GET TO NEXT ENTRY ADD BUFFB+6,R2 MOV R2,R1 ;POINT R1 TO NEXT BR MONF 2$: MOV BUFFB+2,R0 ;SEE IF NEXT IS AVAILABLE BNE DFND ;YES. CONTINUE JSR R0,REPORT ;HE AIN'T GOT A MONITOR .ASCIZ <15><12>\?B-NO MONITR.SYS\<12> .EVEN TOOSML: JSR R0,REPORT ;HE IS IN A TINY MACHINE .ASCIZ <15><12>\?B-NOT ENOUGH CORE\<12> .EVEN .SBTTL READ MONITOR, LOOKUP HANDLERS MONFND: MOV @SP,R2 ;RECALL LOAD LOCATION ADD #BOOTSZ,R0 ;BUMP R0 OVER BOOT RECORDS MOV R0,-(SP) ;SAVE SWAP BLOCK POINTER .IF NDF $DXSYS ;DV15 MOV #MAXSYH,R1 ;DO GLOBAL ARITHMETIC HERE SUB SYSIZE,R1 ;R1 = MAXSYH-SYSIZE (BYTES) ADD #FILLER,R1 ;ADD AMOUNT OF EXTRA STUFF .IFF ;DV15 MOV #FILLER,R1 ;AMOUNT OF EXTRA STUFF ;DV15 .ENDC ;DV15 ASR R1 ;(WORDS) NEG R1 ;(TO SUBTRACT) ADD #RTLEN,R1 ;LENGTH TO LOAD (WORDS) ADD #SWAPSZ,R0 ;POINT TO BLOCK WITH KMON JSR PC,READ ;READ THE MONITOR INTO PLACE MOV #RELLST,R0 ;POINT TO LIST OF THINGS TO RELOCATE MOV (SP)+,R1 ;R1 = SWAP BLOCK NUMBER MOV (SP)+,R4 ;R4 -> KMON IN CORE SUB #KMON,R4 ;SUBTRACT LOCATION KMON WAS LINKED TO MOV R1,$SWPBL(R4) ;R4 = BIAS. SET UP SWAP BLOCK # ADD #SWAPSZ,R1 ADD #KMONSZ,R1 MOV R1,$MONBL(R4) ;SET USR BLOCK # 1$: ADD R4,@(R0)+ ;RELOCATE A POINTER IN THE ASECT CMP R0,#RELST2 ;DONE YET ? BLO 1$ ;NO MOV (R0)+,R5 ;GET POINTER TO THING IN MONITOR 2$: ADD R4,R5 ;BIAS THE POINTER ADD R4,@R5 ;NOW RELOCATE THE WORD MOV (R0)+,R5 ;GET NEXT POINTER BNE 2$ .IF DF $DXSYS!$RKSYS ;DV15 BIT #LSI11$,BCNFG ;AN LSI11 MACHINE?? ;DV15 BEQ 4$ ;NO, SKIP CODE MODIFICATION ;DV15 MOV (R0)+,R5 ;YES, GET ADDR OF PS REFERENCE ;DV15 3$: ADD R4,R5 ;BIAS THE POINTER ;DV15 MOV (R0)+,@R5 ;MODIFY THE CODE ;DV15 MOV (R0)+,R5 ;GET NEXT POINTER ;DV15 BNE 3$ ;BRANCH IF MORE ;DV15 .ENDC ;DV15 4$: MOV @#54,R0 ;POINT TO MONITOR ;DV15 .IF DF $RKSYS!$DXSYS!$DPSYS!$DSSYS ;THE RK,RX,RP,RJSO3/4 CAN BOOT FROM ANY UNIT .IF DF $RKSYS ;CODE FOR RK MOV @#RKDA,R1 ;GET THE RK UNIT NUMBER ROL R1 ROL R1 ROL R1 ROL R1 BIC #^C7,R1 ;EXTRACT IT .ENDC ;DF $RKSYS .IF DF $DSSYS ;CODE FOR RJS03/4 MOV @#RSCS2,R1 ;UNIT # INTO R1 BIC #^C7,R1 ;STRIP TO 3 BITS .ENDC .IF DF $DPSYS ;RP11 MOV @#RPCS,R1 ;GET CONTROLLER STATUS REG INTO R1 BIC #^C,R1 ;STRIP TO UNIT NUMBER SWAB R1 ;UNIT # INTO BITS 2-0 .ENDC ;DF $DPSYS .IF DF $DXSYS ;FLOPPY MOV BTUNIT,R1 ;GET BOOTED UNIT (STORED BY BOOT2) .ENDC ;DF $DXSYS ADD R1,DKASSG(R0) ;FIX PERMANENT PSEUDO-ASSIGNMENTS ADD R1,SYASSG(R0) MOVB R1,SYUNIT+1(R0) ;SET UNIT NUMBER WE BOOTED .ENDC ;DF $RKSYS!$DXSYS!DPSYS .ENABL LSB BIS BCNFG,CONFIG(R0) ;SET HARDWARE CONFIGURATION CLR R3 ;COUNT DEVICE SLOTS MOV #$ENTRY,R1 ;POINT TO $ENTRY TABLE IN RMON ADD R4,R1 4$: TST (R1)+ ;RESIDENT DEVICE ? BEQ 5$ ;NO, SKIP IT ADD R4,-(R1) ;YES, FIX HANDLER POINTER CMP $PNAMO(R1),#SYNAME ;IS THIS THE SYSTEM DEVICE? BNE 45$ ;NO MOV R3,SYINDO(R0) ;SET SYSTEM INDEX NUMBER ADD R3,SYINDO(R0) ;(DOUBLED) MOV @R1,SYENTO(R0) ;AND SET UP SYSTEM ENTRY POINTER 45$: TST (R1)+ 5$: INC R3 ;ANY MORE ? CMP #$SLOT,R3 BNE 4$ ADD #SYBITO,R0 ;ADD IN OFFSET TO SYSTEM VECTOR IN MAP BISB #SYBITS,MAPOFF(R0) ;AND PROTECT IT MOV #$PNAME,R1 ;POINT TO PERM NAME TABLE ADD R4,R1 ADD #$DVREC,R4 ;POINT R4 TO $DVREC IN RMON MOV #$SLOT,R3 ;NUMBER TO LOOK UP 6$: MOV (R1)+,FNAME ;FILL IN NAME IN LOOKUP .LOOKUP 0,#BLOOK ;LOOKUP SY:HH.SYS BCC 7$ ;GO IF THERE CLR (R4)+ ;CLEAR RECORD NUMBER BR 8$ 7$: .SAVEST 0,#CBLOK ;SAVE STATUS OF THING MOV CBLOK+2,@R4 ;SET STARTING RECORD INC (R4)+ ;FIX IT 8$: DEC R3 BNE 6$ MOV #100000,@#JSW ;NOTHING TO SWAP .PRINT #BSTRNG ;PRINT BOOT HEADER CLR R0 MOV (PC)+,(R0)+ BIC R0,R0 MOV (PC)+,(R0)+ .EXIT .IF DF $DXSYS!$RKSYS ;DV15 BIT #LSI11$,BCNFG ;IF THIS IS AN LSI11 ;DV15 BNE 10$ ;NO CLOCK STATUS REGISTER ;DV15 .ENDC ;DV15 BIT #KW11L$,BCNFG ;AND IF HE HAS A CLOCK BEQ 10$ ; WE TURN IT MOV #100,@LK.CS ; ON .IF NDF $DXSYS MOV #100,@(PC)+ ;PATCH TO SET KW11-P PRESET COUNT .WORD LKCS .ENDC 10$: CLR R0 .EXIT .DSABL LSB BCLR: CLR @R1 ;TRAP MEANS THIS CONFIGURATION NYET RTI ;UNTRAP .SBTTL RELOCATION LIST RELLST: 4 ;ILLEGAL MEM AND INST. TRAPS 10 30 ;EMT 54 ;ADDRESS OF RMON 60 ;TTY VECTORS 64 100 ;CLOCK VECTOR SYVEC ;SYSTEM DEVICE VECTOR 244 ;LOCATION OF FPU TRAP RELST2: USRLOC ;LOCATION OF USR NOW $USRLC ;ADDRESS OF 'NORMAL' USR QCOMP ;QUEUE COMPLETION $KMLOC ;ADDRESS OF KMON TTIBUF ;TTY RING BUFFER--INPUT TTIBUF+2 TTIBUF+6 TTIBUF+10 TTOBUF ;TTY RING BUFFER--OUTPUT TTOBUF+4 TTOBUF+6 SYSLOW ;LOWEST USED LOCATION CORPTR+2 ;FREE CORE LIST $INPTR ;POINTER TO $INTEN IN RESIDENT HANDLER SYNCH ;SYNCHRONIZATION ADDRESS .IF NE BF MSGENT ;RELOCATE F/B STUFF HERE IMPLOC ;DV16 TTIUSR TTOUSR FUDGE1 FUDGE2 BKGND1 BKGND2 BKGND3 CNTXT BCNTXT RMONSP SWIPTR SWOPTR .$CRTN .IFF TRAPLC TRAPER ;LOCS FOR TRAPS TO 4/10 FPPADD FPPIGN ;FPP SERVICE FOR MONITOR MONLOC ;WHERE USR WILL SIT I.CSW ;SINGLE USER STUFF HERE AVAIL ;MONITOR FREE Q POINTER .ENDC 0 ;END OF LIST OF ADDRESSES ; CODE MODIFICATION LIST FOR LSI11 PROCESSORS ;DV15 .IF DF $DXSYS DXINT+4 ;RUN DX AT PRI 0 ON LSI-11 ;DV24 ^C&PR7 ;DV24 .ENDC .IF DF $DXSYS!$RKSYS ;DV15 GETPSW+2 ;DV15 MFPS 2(SP) ;DV15 . = . - 2 ;DV15 GETPSW+4 ;DV15 2 ;DV15 GETPSW+6 ;DV15 RTS PC ;DV15 .IF EQ BF ;DV15 $INTEN+2 ;DV15 MFPS R4 ;DV15 $INTEN+4 ;DV15 BIC (R5)+,R4 ;DV15 $INTEN+6 ;DV15 MTPS R4 ;DV15 .IFF ;DV15 RMONSP+4 ;DV15 MFPS R4 ;DV15 RMONSP+6 ;DV15 BIC (R5)+,R4 ;DV15 RMONSP+10 ;DV15 MTPS R4 ;DV15 .ENDC ;DV15 0 ;END OF LIST ;DV15 BCNFG: .WORD LSI11$ ;BOOT CONFIGURATION WORD-DO NOT MOVE ;DV15 TSLIST: .WORD LSI11$,KW11L$,HWDSP$,HWFPU$ ;BITS IN CONFIG WORD ;DV15 .IFF ;DV15 BCNFG: .WORD 0 ;BOOT CONFIGURATION WORD-DO NOT MOVE ;DV15 TSLIST: .WORD KW11L$,HWDSP$,HWFPU$ ;BITS IN CONFIG WORD ;DV15 .ENDC ;DV15 .IF NDF $RKSYS ; BLOOK IS THE ARGUMENT AREA FOR AN RT-11 LOOKUP. BLOOK: .RAD50 /SY / FNAME: .WORD 0,0 ;FILENAME GOES HERE .RAD50 /SYS/ CBLOK: .BLKW 1 ;SAVESTATUS GOES HERE .ENDC BUFFB = . + 12 BOOTSZ = . + 777 / 1000 . = BOOTSZ * 1000 .END $RFSYS=1 $DTSYS=1 $DPSYS=1 $DXSYS=1 $DSSYS=1 .TITLE DP V02-06 ; RT-11 RP02 (RP11C) DISK HANDLER ; ; DEC-11-ORTXA-E ; ; RRB, ABC, RB ; JULY 1974 / FEBRUARY 1975 ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; REGISTER SYMBOLS R0= %0 R1= %1 R2= %2 R3= %3 R4= %4 R5= %5 SP= %6 PC= %7 ; SYSTEM EQUATES PR5= 240 PR7= 340 SYSPTR= 54 OFFSET= 270 ; GLOBALS FOR USE AS SYSTEM DEVICE .GLOBL DPINT, SYINPR .GLOBL RKSYS, RFSYS, DTSYS, DSSYS, $INPTR, $INTEN .GLOBL DPSYS,RP23, DXSYS ; RP SYSTEM DEFINITIONAL EQUATES DXSYS= 0 DTSYS= 0 RFSYS= 0 RKSYS= 0 DSSYS= 0 ; RP CONTROLLER REGISTERS RPVEC= 254 ;VECTOR ADDRESS RPDS= 176710 ;DEVICE STATUS RPER= 176712 ;ERROR RPCS= 176714 ;CONTROL & STATUS RPWC= 176716 ;WORD COUNT RPBA= 176720 ;BUS ADDRESS RPCA= 176722 ;CYLINDER ADDRESS RPDA= 176724 ;DISK ADDRESS RPM1= 176726 ;MAINTENANCE 1 RPM2= 176730 ;MAINTENANCE 2 RPM3= 176732 ;MAINTENANCE 3 SUCA= 176734 ;SELECTED UNIT CYLINDER ADDRESS SILO= 176736 ;SILO MEMORY ; CONTROL & STATUS BITS CS.GO= 000001 ;GO CS.WRT= 000002 ;WRITE CS.RD= 000004 ;READ CS.WTC= 000006 ;WRITE CHECK CS.SEK= 000010 ;SEEK CS.WTN= 000012 ;WRITE (NO SEEK) CS.HOM= 000014 ;HOME SEEK CS.RDN= 000016 ;READ (NO SEEK) CS.MEM= 000060 ;MEMORY EXTENSION CS.INT= 000100 ;INTERRUPT ENABLE CS.RDY= 000200 ;READY CS.DRV= 003400 ;DRIVE SELECT CS.HDR= 004000 ;HEADER CS.MOD= 010000 ;DECSYSTEM-10 OR PDP-15 FORMAT CS.AIE= 020000 ;ATTENTION INTERRUPT ENABLE CS.HER= 040000 ;HARD ERROR CS.ERR= 100000 ;ERROR ; DEVICE STATUS BITS DS.ATT= 000377 ;ATTENTION, UNITS 0-7 DS.WTP= 000400 ;WRITE PROTECT DS.FUS= 001000 ;FILE UNSAFE DS.SUW= 002000 ;SEEK UNDERWAY DS.SIN= 004000 ;SEEK INCOMPLETE DS.HNF= 010000 ;HEADER NOT FOUND DS.RP3= 020000 ;UNIT IS RP03 DS.ONL= 040000 ;UNIT ONLINE DS.RDY= 100000 ;UNIT READY RPCNT= 10. ;ERROR RETRY COUNT .CSECT SYSHND START: .WORD RPVEC ;VECTOR .WORD DPINT-. ;OFFSET TO INTERRUPT SERVICE .WORD PR7 DPSYS: RPLQE: .WORD 0 RPCQE: .WORD 0 ;CURRENT QUEUE ELEMENT POINTER ; ENTRY POINT MOV #RPCNT,(PC)+ ;SET RETRY COUNT & CLR HOME SEEK FLG RPTRY: .WORD 0 ;RETRY COUNT & HOME SEEK FLAG ;HIGH ORDER BYTE OF RPTRY IS A FLAG USED FOR ;ERROR RETRY CONTROL ; RPTRY+1=0 MEANS FIRST RETRY SEQUENCE ; >0 MEANS HOME SEEK IN PROGRESS ; <0 MEANS SECOND RETRY SEQUENCE ;ERROR RECOVERY PATH IS 10 RETRIES,HOME SEEK,10 MORE RETRIES RPAGN: MOV @RPCQE,R5 ;R5 = BLOCK # OF REQUEST CMP #40000.,R5 ;IS BLOCK NUMBER LEGAL? BLOS RPERR ;NOPE MOV R2,-(SP) MOV R3,-(SP) JSR R1,DIV ;R3 = R5/10., R2 = REMAINDER .WORD 10. ; R2=SECTOR MOV R2,R4 ;REMEMBER SECTOR MOV R3,R5 ;SET NEW DIVIDEND JSR R1,DIV ;COMPUTE CYL & TRACK .WORD 20. ; (20. TRACKS/CYL) SWAB R2 ;R2 HIGH BYTE = TRACK BIS R2,R4 ;R4 = TRACK & SECTOR MOV RPCQE,R5 ;R5 -> CURRENT QUEUE ELEMENT TST (R5)+ ;R5 -> UNIT NUMBER MOV (R5)+,-(SP) ;SAVE IT BIT #4*400,@SP ;OTHER HALF OF DISK? ;THE FOLLOWING LOCATION GETS PATCHED TO CHANGE THIS HANDLER ;FROM AN RP02 HANDLER TO ONE CAPABLE OF HANDLING RP03'S AS WELL AS ;RP02'S. FOR AN RP02 ONLY HANDLER,SET LOC RP23 TO A "BR 1$". FOR A ;HANDLER CAPABLE OF HANDLING RP02 AND RP03 (MAX OF FOUR UNITS ),SET ;THIS LOCATION TO "BEQ 1$". RP23: BR 1$ ;NOPE ADD #200.,R3 ;ELSE CYL = CYL + 200. BIC #4*400,@SP ;AND UNIT=UNIT-4 1$: BIC #174377,@SP ;STRIP TO UNIT BUTS CMP R3,#202. ;CYL>202? BLE 5$ ;YES-PROCEED WITH OPERATION BIC #3400,@#RPCS ;CLEAR CURRENT DRIVE SELECTION BIS (SP),@#RPCS ;SELECT RQUESTED DRIVE BIT #DS.RP3,@#RPDS ;IS THIS DRIVE AN RP03? BNE 5$ ;YES-CYLINDERS > 312 EXIST ADD #6,SP ;NO-THEN WE MUST PREVENT ACCESS TO BR RPERR ;CYL>202,IN CASE RP11C NOT ECO'D 5$: MOV #RPDA,R2 ;PREPARE TO LOAD REGISTERS MOV R4,@R2 ;SET TRACK & SECTOR MOV R3,-(R2) ;SET CYLINDER MOV (R5)+,-(R2) ;SET BUS ADDRESS MOV #CS.INT+CS.WRT+CS.GO,R3 ;ASSUME WRITE MOV @R5,-(R2) ;SET WORD COUNT BEQ 3$ ;IT'S A SEEK BMI 2$ ;IT'S INDEED A WRITE NEG @R2 ;ELSE A READ ADD #CS.RD-CS.WRT,R3 2$: BIS (SP)+,R3 ;INSERT UNIT NUMBER MOV R3,-(R2) ;START OPERATION MOV (SP)+,R3 ;RESTORE REGS MOV (SP)+,R2 RTS PC ;AND RETURN TO MONITOR 3$: ADD #CS.SEK-CS.WRT,R3 ;MAKE SEEK OPERATION BR 2$ ; ABORT ENTRY BR RPABRT ;ABORT CURRENT OPERATION ; INTERRUPT SERVICE SYINPR= PR7 DPINT: JSR R5,@$INPTR ;ENTER SYSTEM STATE .WORD ^C&PR7 MOV #RPCS,R4 ;R4 -> CONTROL & STATUS BIC #CS.AIE+CS.INT,@R4 ;CLEAR INTERRUPT ENABLE MOVB #DS.ATT,-4(R4) ;CLEAR ATTENTION SUMMARY CLRB -4(R4) ;FOR BOTH OLD & ECO'D CONTROLLERS TSTB RPTRY+1 ;HOME SEEK IN PROGRESS? BGT RPHOME ;YES TST @R4 ;ANY ERRORS? BPL RPDONE ;NOPE DECB RPTRY ;ANY MORE RETRIES? BGT RPAGN ;YES-RETRY TSTB RPTRY+1 ;HAVE WE DONE HOME SEEK FOR THIS ERROR YET? BMI RPERR ;BRANCH IF YES-FATAL ERROR INCB RPTRY+1 ;ELSE SET HOME SEEK IN PROGRESS FLAG BIS #CS.AIE,@R4 ;ENABLE ATTENTION INTERRUPT FROM SEEK DONE MOVB #CS.HOM+CS.INT+CS.GO,@R4 ;AND ISSUE HOME SEEK TO SAME UNIT RTS PC RPHOME: MOV #177412,RPTRY ;SET HOME SEEK DONE FLAG AND SET RETRY COUNT TO 10 TST @R4 ;HOME SEEK SUCCESSFUL? BPL RPAGN ;YES-RETRY 8 MORE TIMES RPERR: MOV RPCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT BIS #1,@-(R4) ;SET HARD ERROR IN CSW RPABRT: MOV #1,@#RPCS ;IDLE CONTROLLER RPDONE: MOV PC,R4 ;PREPARE TO EXIT TO MONITOR ADD #RPCQE-.,R4 MOV @#SYSPTR,R5 JMP @OFFSET(R5) ;RETURN TO Q MANAGER ; DIVIDE ROUTINE ; ; DIVIDES R5 BY @R1, RETURNS: ; QUOTIENT IN R3, REMAINDER IN R2 ; ; CALLED BY: JSR R1,DIV ; .WORD DIV: CLR R3 ;INIT QUOTIENT CLR R2 ;AND REMAINDER TST R5 ;IS DIVIDEND 0? BEQ 4$ ;YES - JUST RETURN NOW COM R3 ;QUOT.=-1 & SET CARRY 1$: ROL R5 ;NORMALIZE BCC 1$ 2$: ROL R2 ;SHIFT & SUBTRACT CMP R2,@R1 BLO 3$ SUB @R1,R2 3$: ROL R3 ASL R5 BNE 2$ COM R3 ;FIX QUOTIENT 4$: TST (R1)+ ;BUMP PAST DIVISOR RTS R1 ;AND RETURN $INPTR: .WORD $INTEN ;PLUGGED TO POINT TO COMMON ENTRY RPSIZE= .-START .END ; RT-11 RX01 DISK HANDLER ; DEC-11-ORXHA-E ; ; ; ; ; ; ; ; ; ; ; COPYRIGHT (C) 1975 BY DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSSETTS 01754 ; ; ; ; ; ; ; ; ; ; 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 DIGITAL. ; ; 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. ; ; ; ; ; ; ; ; ; ; ; ; ; .TITLE RX01 HANDLER V01-02 ; H.J. R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; SYSTEM EQUATES PR4=200 PR5=240 PR7=340 SYINPR=PR7 SYSPTR=54 OFFSET=270 ; GLOBALS FOR USE AS SYSTEM DEVICE .GLOBL SYSTAT,SYSIZE,SBLOCK,SY,DXINT,SYINPR .GLOBL RKSYS,RFSYS,DTSYS,DSSYS,DPSYS,DXSYS .GLOBL $INPTR,$INTEN ; RX SYSTEM DEFINITIONAL EQUATES DTSYS=0 RFSYS=0 RKSYS=0 DSSYS=0 DPSYS=0 SBLOCK=494. SYSTAT=100022 ; RX CONTROLLER REGISTERS RXCS=177170 RXDB=177172 RXVEC=264 ; CONTROL AND STATUS BITS CSGO=1 ;INITIATE FUNCTION ; FUNCTIONS (BITS 1-3) CSFBUF= 0*2 ;FILL SILO (PRE-WRITE) CSEBUF= 1*2 ;EMPTY SILO (POST-READ) CSWRT= 2*2 ;WRITE SECTOR CSRD= 3*2 ;READ SECTOR CSRDST= 5*2 ;READ STATUS CSWRTD= 6*2 ;WRITE SECTOR WITH DELETED DATA CSMAIN= 7*2 ;MAINTENANCE CSRDWR= CSRD&CSWRT ;READ OR WRITE BIT CSUNIT= 20 ;UNIT BIT CSDONE= 40 ;DONE BIT CSINT= 100 ;INTERUPT ENABLE CSTR= 200 ;TRANSFER REQUEST CSINIT= 40000 ;RX11 INITIALIZE CSERR= 100000 ;ERROR DBDD= 100 ;DELETED DATA MARK DBIN= 4 ;RX INIT DONE INDICATOR RETRY=8. ;RETRY COUNT SPFUNC= 100000 ;SPECIAL FUNCTIONS FLAG ; GENERAL COMMENTS: ; ; THIS HANDLER SERVES AS THE STANDARD RT-11 RX01 DEVICE HANDLER AS ; BOTH THE SYSTEM DEVICE HANDLER AND NON-SYSTEM HANDLER. IT ALSO PRO- ; VIDES THREE SPECIAL FUNCTION CAPABILITIES TO SUPPORT PHYSICAL I/O ; ON THE FLOPPY AS A FOREIGN VOLUME. THE SPECIAL FUNCTIONS ARE: ; CODE ACTION ; 377 ABSOLUTE SECTOR READ. WCNT=TRACK, BLK=SECTOR, BUFFER=65 ; WORD BUFFER OF WHICH WORD 1 IS DELETED DATA FLAG. ; 376 ABSOLUTE SECTOR WRITE. ARGUMENTS SAME AS READ. ; 375 ABSOLUTE SECTOR WRITE WITH DELETED DATA. 1ST WORD ; OF 65 WORD BUFFER ALWAYS SET TO 0. ; ; IN STANDARD RT-11 MODE A 2:1 INTERLEAVE IS USED ON A SINGLE TRACK AND ; A 6 SECTOR SKEW IS USED ACROSS TRACKS. TRACK 0 IS LEFT ALONE FOR ; PROPOSED ANSI COMPATABILITY. .CSECT SYSHND RXSTRT: .WORD RXVEC ;VECTOR LOCATION .WORD DXINT-. ;OFFSET TO INTERUPT SERVICE .WORD PR7 ;INTERUPT AT PRIORITY 7 DXSYS: SY: RXLQE: .WORD 0 ;LAST QUEUE ELEMENT POINTER RXCQE: .WORD 0 ;CURRENT QUEUE ELEMENT POINTER ; REQUEST ENTRY POINT CMP -(SP),-(SP) ;RESERVE 2 WORDS ON TO STACK TO USE ;COMMON EXIT SEQUENCE MOV RXCQE,R3 ;GET POINTER TO I/O ELEMENT MOV (R3)+,R5 ;GET BLOCK NUMBER MOV #CSGO+CSRD,R4 ;FORM A GUESS AT RXCS FUNCTION MOVB (R3)+,R1 ;SAVE FUNCTION FOR LATER BITB #6,@R3 ;ANY UNITS BUT 0 OR 1? BNE RXERR ;BRANCH IF YES, ERROR BITB #1,(R3)+ ;CHECK FOR UNIT 0 OR 1? BEQ 1$ ;BRANCH IF 0 BIS #CSUNIT,R4 ;UPDATE GUESS AT RXCS 1$: MOV (R3)+,R0 ;SAVE THE BUFFER ADDRESS MOV @R3,R2 ;GET WORD COUNT BPL 2$ ;TAKE ABSOLUTE VALUE ; BIC #CSEBUF,R4 ;WRITE FUNCTIONS ARE 0,2 SO CLEAR 1 BIT CMPB -(R4),-(R4) ;EQUIVALENT TO ABOVE BIC NEG R2 ;MAKES IT POSITIVE 2$: ADD PC,R1 ;FORM PIC REFERENCE TO CHGTBL MOVB CHGTBL-.(R1),R3 ;GET FUNCTION MODIFIER ROR R1 ;SET C TO FLAG IF SPECIAL FUNCTION ROR R3 ;SET SIGN TO SPFUNC FLAG (NON-OBVIOUS!) ADD R3,R4 ;MODIFY FUNCTION BASED ON READ/WRITE BMI 3$ ;BRANCH IF SPECIAL FUNCTION REQUEST ASL R5 ;MAKE A LOGICAL SECTOR NUMBER ASL R5 ;BLOCK*4 ASL R2 ;MAKE WORD COUNT UNSIGNED BYTE COUNT BR 4$ ;SKIP SPECIAL FUNCTION INITING 3$: CLR (R0)+ ;CLEAR DELETED DATA FLAG WORD MOV R2,PHYTRK ;SAVE TRACK FOR LATER MOV #128.,R2 ;SET THE BYTE COUNT TO 128 4$: MOV R0,BUFRAD ;SAVE FOR LATER MOV R5,RXLSN ;SAVE FOR LATER MOV R4,RXFUN2 ;SAVE READ OR WRITE RXCS COMMAND MOV R2,BYTCNT ;SAVE FOR LATER MOV #RETRY,(PC)+ ;SET RETRY COUNT RXTRY: .WORD 0 ;RETRY COUNT RXINIT: CLR R3 ;SET THIS IS INITIAL INTERRUPT FLAG BR RXWAIT ;PERFORM A RETURN TO WAIT FOR INTERUPT RXERR: MOV RXCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT BIS #1,@-(R4) ;SET HARD ERROR IN CSW RXDONE: MOV (SP)+,R3 ;RESTORE SOME REGS MOV (SP)+,R2 CLR @RXCSA ;DISABLE FLOPPY INTERRUPTS BR RXEXIT ;SKIP RX INITIALIZE FUNCTION ; RX ABORT ENTRY BR RXABRT ;ABORT OPERATION ; INTERUPT ENTRY DXINT: JSR R5,@$INPTR ;FIX MY PRIORITY .WORD ^C&PR7 ;DROP TO 5 MOV R2,-(SP) ;SAVE SOME REGS MOV R3,-(SP) MOV (PC)+,R4 ;GET ADDRESS OF RX STATUS RXCSA: .WORD RXCS ;ONLY POINTER TO I/O PAGE MOV R4,R5 ;POINT R5 TO RX DATA BUFFER TST (R5)+ ;CHECK FOR ERROR BMI RXERR1 ;BRANCH IF ERROR ; CODE FOR FLOPPY POWER FAIL ; BIT #DBIN,@R5 ;DID INITIALIZE APPEAR IN RXES? ; BNE RXERR1 ;BRANCH IF SO TO RETRY NEG (PC)+ ;IS THIS INITIAL INTERRUPT? C=0 IF YES INTINT: .WORD 0 ;INTERNAL INITIAL INTERUPT FLAG MOV #128.,R3 ;INIT R3 FOR 128 BYTES, USED LATER BIT #CSEBUF,RXFUN2 ;READ OR WRITE INTERUPT? BNE 2$ ;BRANCH IF READ BCC 1$ ;BRANCH TO AVOID UPDATING POINTERS JSR PC,NXTSEC ;SET UP FOR NEXT WRITE 1$: JSR R0,SILOFE ;LOAD THE SILO ;SILOFE ARG LIST MOVB (R2)+,@R5 ;MOVB TO BE PLACED IN-LINE IN SILOFE .WORD CSGO+CSFBUF ;FILL BUFFER COMMAND CLRB @R5 ;ZERO FILL SECTOR INSTRUCTION WHICH ;WOULD BE USED FOR SHORT WRITES ; BR 3$ ;SKIP READ FINISHING, (C BIT IS 0) 2$: BCC 3$ ;BRANCH TO AVOID EMPTYING SILO TST RXFUN2 ;IS THIS SPECIAL FUNCTION REQUEST? BPL 4$ ;BRANCH IF NOT SPECIAL FUNCTION CALL BIT #DBDD,@R5 ;IS DELETED DATA FLAG PRESENT? BEQ 4$ ;BRANCH IF IT IS MOV BUFRAD,R2 ;GET ADDRESS OF USER BUFFER AREA INC -(R2) ;SET FLAG WORD TO 1 INDICATING DEL DATA 4$: JSR R0,SILOFE ;MOVE THE DATA INTO MEMORY FROM SILO ;SILOFE ARG LIST MOVB @R5,(R2)+ ;MOVB TO BE PLACED IN LINE IN SILOFE .WORD CSGO+CSEBUF ;EMPTY BUFFER COMMAND MOVB @R5,R2 ;DATA SLUFFER TO BE USED FOR SHORT READ JSR PC,NXTSEC ;SET UP TO READ NEXT SECTOR 3$: MOV (PC)+,R3 ;GET THE LOGICAL SECTOR NUMBER RXLSN: .WORD 0 ;LOGICAL SECTOR NUMBER KEPT HERE MOV (PC)+,R2 ;IF SPECIAL FUNCTION R3 GETS SECTOR PHYTRK: .WORD 0 ;ABSOLUTE TRACK FOR SPECIAL FUNCS TST RXFUN2 ;IS THIS SPECIAL FUNCTION? BMI DOFUNC ;BRANCH IF SPECIAL FUNCTIONS ; FLOPPY INTERLEAVE ALGORITHM MOV #8.,R2 ;LOOP COUNT 1$: CMP #6400,R3 ;DOES 26 GO INTO DIVIDEND? BHI 2$ ;BRANCH IF NOT, C CLEAR ADD #171400,R3 ;SUBTRACT 26 FROM DIVIDEND, SETS C 2$: ROL R3 ;SHIFT DIVIDEND AND QUOTIENT DEC R2 ;DEC LOOP COUNT BGT 1$ ;BRANCH TILL DIVIDE DONE MOVB R3,R2 ;COPY TRACK NUMBER CLRB R3 ;REMOVE TRACK NUMBER FROM REMAINDER SWAB R3 ;GET REMAINDER CMP #12.,R3 ;C=1 IF 13<=R3<=25, ELSE C=0 ROL R3 ;DOUBLE FOR 2 TO 1 INTERLEAVE ;C-BIT COMES IN FOR SECTOR GROUP ASL R2 ;ADD TRACK TO TRACK SKEW TO SECTOR ADD R2,R3 ;SKEW BY 2* TRACK ADD R2,R3 ;SKEW BY 4* TRACK ADD R2,R3 ;SKEW BY 6* TRACK ASR R2 ;REFIX TRACK NUMBER INC R2 ;PUT TRACK # IN RANGE 1-76 TO HANDLE ;ANSI FLOPPY, TRACK 0 IS LEFT ALONE 3$: SUB #26.,R3 ;MODULO SECTOR INTO RANGE -26,-1 BGE 3$ ;LOOP TILL REMAINDER GOES NEGATIVE ADD #27.,R3 ;PUT SECTOR IN RANGE 1,26 DOFUNC: MOV (PC)+,@R4 ;SET THE FUNCTION RXFUN2: .WORD 0 ;READ OR WRITE COMMAND ON CORRECT UNIT 1$: TSTB @R4 ;WAIT FOR TRANSFER READY BEQ 1$ ;WAIT BPL RXERR1 ;TR IS NOT UP, THATS AN ERROR MOV R3,@R5 ;SET SECTOR FOR FLOPPY 2$: TSTB @R4 ;WAIT FOR TRANSFER READY BEQ 2$ ;WAIT BMI SECOK ;BRANCH IF TR UP, ELSE ERROR RXERR1: DEC RXTRY ;SHOULD WE TRY AGAIN? BLT RXERR ;BRANCH IF NO, RETRY COUNT EXPIRED MOV #CSINIT,@R4 ;START A RECALIBRATE BR RXINIT ;EXIT THROUGH START OPERATION CODE SECOK: MOV R2,@R5 ;SET TRACK FOR FLOPPY RXWAIT: MOV R3,INTINT ;INTINT >0 FOR PROCESS INTERRUPT ENTRY MOV (SP)+,R3 ;RESTORE THE REGS MOV (SP)+,R2 BIS #CSINT,@RXCSA ;ENABLE FLOPPY INTERRUPTS, THIS SHOULD ;CAUSE AN INTERRUPT WHEN DONE IS UP RETURN: RTS PC ;RETURN, WE'LL BE BACK WITH AN INTERUPT NXTSEC: ADD R3,BUFRAD ;UPDATE BUFFER ADDRESS INC RXLSN ;BUMP LOGICAL SECTOR SUB R3,BYTCNT ;REDUCE THE AMOUNT LEFT TO TRANSFER BHI RETURN ;BRANCH IF WE ARE NOT DONE CLR BYTCNT ;INIT FOR POSSIBLE SHORT WRITE BIT #CSEBUF+SPFUNC,RXFUN2 ;IS THIS A READ OR SPECIAL ;FUNCTION OPERATION? BNE 1$ ;BRANCH IF EITHER, FOR .WRITE WE HAVE ;TO 0 TO THE END OF A BLOCK BIT #3,RXLSN ;ARE WE AT 1ST SECTOR IN BLOCK? BNE RETURN ;BRANCH IF NOT TO CONTINUE 1$: TST (SP)+ ;POP RETURN ADDRESS FROM STACK BR RXDONE ;REQUEST DONE RXABRT: MOV #CSINIT,@RXCSA ;PERFORM AN RX11 INITIALIZE RXEXIT: MOV PC,R4 ;EXIT TO MONITOR FREEING QUEUE ELEMENT ADD #RXCQE-.,R4 ;R4 HAS ADDRESS OF RXCQE MOV @#SYSPTR,R5 JMP @OFFSET(R5) ;GO BACK TO MONITOR ; R3 IS 128 ON ENTRY ; THIS ROUTINE ASSUMES ERROR CAN NOT COME UP DURING A FILL OR EMPTY!! SILOFE: MOV (R0)+,EFBUF ;PUT CORRECT MOV INSTRUCTION IN FOR ;EITHER FILLING OR EMPTYING RX BUFFER MOV (R0)+,@R4 ;INITIATE FILL OR EMPTY BUFFER COMMAND MOV (PC)+,-(SP) ;ASSUME MAXIMUM OF BYTCNT TO MOVE FROM ;BUFFER BYTCNT: .WORD 0 ;THE BYTE COUNT IS KEPT HERE BEQ ZFILL ;BRANCH IF SEEK OR SHORT WRITE ;NOTE SEEK DOES THE EMPTY (TIME WASTER) CMP @SP,R3 ;NOW MAKE SURE COUNT IS 128 OR LESS BLOS 1$ ;BRANCH IF @SP IS 128 OR LESS MOV R3,@SP ;RESET COUNT TO 128 1$: MOV (PC)+,R2 ;PUT THE BUFFER ADDRESS IN R2 BUFRAD: .WORD 0 ;THE BUFFER ADDRESS IS KEPT HERE TRBYT: TSTB @R4 ;WAIT FOR TRANSFER READY BPL TRBYT ;BRANCH IF TR NOT UP EFBUF: HALT ;INSTRUCTION TO MOV OR SLUFF DATA FROM ;BUFFER GETS PLACED HERE ; MOVE DATA SLUFF DATA ;MOVB (R2)+,@R5 CLRB @R5 FILL ;MOVB @R5,(R2)+ MOVB @R5,R2 EMPTY DEC @SP ;CHECK FOR COUNT DONE BGT TRBYT ;STILL MORE TO TRANSFER ZFILL: MOV @R0,EFBUF ;CHANGE MOV INSTRUCTION TO CORRECT ;INSTR FOR SLUFFING DATA TO/FROM BUFFER 1$: TSTB @R4 ;WAIT LOOP BEQ 1$ ;WAIT FOR SOME INDICATION (TR,DONE) BMI EFBUF ;BRANCH IF TR CAME UP TO SLUFF DATA BIT (R0)+,(SP)+ ;BUMP R0 TO RETURN ADDR AND REMOVE JUNK ;WORD FROM STACK LEAVING C BIT=0 RTS R0 ;RETURN .BYTE 6*2 ;READ+GO -> WRITE DELETED+GO .BYTE -2*2 ;READ+GO -> WRITE+GO .BYTE 0*2 ;READ+GO -> READ+GO CHGTBL: .BYTE 0*2 ;READ/WRITE STAY THE SAME .EVEN $INPTR: .WORD $INTEN ;INTERUPT ENTRY COMMMUNICATIONS WORD SYSIZE=.-RXSTRT ;TOTAL SIZE OF HANDLER .END .TITLE RK05 V02-09 ; RT-11 DISK (RK11) HANDLER ; ; DEC-11-ORKHA-E ; ; EF/ABC/RGB ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; ; REGISTER DEFINITIONS R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 PR5 = 240 PR7 = 340 SYSPTR = 54 OFFSET = 270 ; GLOBAL DEFINITIONS .GLOBL RKINT .GLOBL DPSYS, DSSYS, DXSYS .GLOBL RKSYS, RFSYS, DTSYS, $INPTR, $INTEN DTSYS = 0 ;THIS IS RK HANDLER DSSYS = 0 DXSYS = 0 DPSYS = 0 RFSYS = 0 ; RK CONTROL DEFINITIONS: RKDS = 177400 RKER = 177402 RKCS = 177404 RKWC = 177406 RKBA = 177410 RKDA = 177412 RKCNT = 10 ;# ERROR RETRYS .CSECT SYSHND START: .WORD 220 ;RK TRAP ADDRESS .WORD RKINT-. ;OFFSET FROM INTERRUPT ADDRESS .WORD PR7 ;SERVICE INTERRUPT AT LEVEL 7 RKSYS: RKLQE: .WORD 0 ;LAST Q ENTRY ADDRESS RKCQE: .WORD 0 ;CURRENT Q ENTRY ADDRESS MOV #RKCNT,(PC)+ ;SET ERROR RETRIES RETRY: 0 ;HIGH ORDER BIT USED FOR "RESET IN PROGRESS FLAG" MOV RKCQE,R5 ;GET Q PARAMETER POINTER MOV @R5,R2 ;R2 = BLOCK NUMBER MOV 2(R5),R4 ;R4 = UNIT NUMBER ASR R4 ;ISOLATE UNIT BITS IN HIGH 3 BITS ASR R4 ASR R4 SWAB R4 BIC #^C<160000>,R4 BR 2$ ;ENTER COMPUTATION LOOP 1$: ADD R2,R4 ;ADD 16R TO ADDRESS ASR R2 ;R2 = 8R ASR R2 ;R2 = 4R ADD R3,R2 ;R2 = 4R+S = NEW N 2$: MOV R2,R3 ;R3 = N = 16R+S BIC #177760,R3 ;R3 = S BIC R3,R2 ;R2 = 16R BNE 1$ ;LOOP IF R <> 0 CMP #12.,R3 ;IF S < 12. BGT 3$ ; THEN F(S) = S ADD #4,R3 ; ELSE F(S)=F(12+S')=16+S'=4+S 3$: ADD R3,R4 ;R4 NOW CONTAINS RK ADDRESS MOV R4,DISKAD ;SAVE DISK ADDRESS AGAIN: MOV RKCQE,R5 ;POINT R5 TO Q ELEMENT MOV #RKDA,R4 ;POINT TO DISK ADDRESS REG MOV (PC)+,@R4 ;PUT IN ADDRESS & UNIT SELECT DISKAD: 0 ;SAVED COMPUTED DISK ADDRESS CMP (R5)+,(R5)+ ;ADVANCE TO BUFFER ADDRESS IN Q ELT MOV (R5)+,-(R4) ;PUT IN BUFFER ADDRESS MOV (R5)+,-(R4) ;PUT IN WORD COUNT BEQ 6$ ;0 COUNT => SEEK BMI 5$ ;NEGATIVE => WRITE NEG @R4 ;POSITIVE => READ. FIX FOR CONTROLLER MOV #105,-(R4) ;START UP A READ RTS PC ;RETURN TO MONITOR TO AWAIT INTERRUPT 5$: MOV #103,-(R4) ;START UP A WRITE RTS PC ;AWAIT INTERRUPT 6$: MOV #111,-(R4) ;START UP A SEEK RTS PC ;AWAIT INTERRUPT ; NOTE THAT THE RTS PC ABOVE SERVES AS THE ABORT ENTRY FOR THE RK RKINT: JSR R5,@$INPTR ;DO IT. INTO MONITOR .WORD ^C&PR7 ;RUN AT LEVEL 5 MOV #RKER,R5 ;POINT TO ERROR STATUS REGISTER MOV (R5)+,R4 ;SAVE ERRORS IN R4,POINT TO RKCS TST RETRY ;WERE WE DOING A DRIVE RESET? BPL 2$ ;NO-NORMAL OPERATION TST @R5 ;YES-ANY ERROR BMI 2$ ;YES-HANDLE NORMALLY BIT #20000,@R5 ;RESET COMPLETE? BEQ RTSPC ;NO-DISMISS INTERRUPT-RK11 WILL INTERRUPT ;AGAIN WHEN RESET COMPLETE 1$: CLRB RETRY+1 ;YES-CLEAR RESET FLAG BR AGAIN ;AND RETRY OPERATION 2$: CMP @R5,#310 ;IS THIS FIRST OF TWO INTERRUPTS CAUSED BY SEEK? BEQ RTSPC ;YES-IGNORE IT.RK WILL INTERRUPT AGAIN ;WHEN SEEK COMPLETE TST @R5 ;ANY ERRORS? BPL DONE ;NO-OPERATION COMPLETE MOV #1,@R5 ;YES-RESET CONTROL 3$: TSTB @R5 ;WAIT BPL 3$ DECB RETRY ;DECREASE RETRY COUNT BEQ HERROR ;NONE LEFT-HARD ERROR BIT #110000,R4 ;SEEK INCOMPLETE OR DRIVE ERROR? ; 100000=DRIVE ERROR ; 010000=SEEK ERROR BEQ 1$ ;NO-RETRY OPERATION MOV DISKAD,@#RKDA ;YES-RESELECT DRIVE MOV #115,@R5 ;START A DRIVE RESET BIS #100000,RETRY ;SET FLAG RTSPC: RTS PC ;AWAIT INTERRUPT HERROR: MOV RKCQE,R5 ;GET POINTER TO Q ELEMENT BIS #1,@-(R5) ;GIVE OUR USER AN ERROR IN CHANNEL DONE: CLR RETRY ;CLEAR ANY FLAGS MOV PC,R4 ;EXIT TO Q MANAGER ADD #RKCQE-.,R4 MOV @#SYSPTR,R5 JMP @OFFSET(R5) $INPTR: .WORD $INTEN ;MONITOR INTERRUPT ENTRY POINT RKSIZE = .-START .END .TITLE RF V01-01 THE RT-11 RF/RS DISK HANDLER ; RT-11 RF11/RS11 HANDLER ; ; DEC-11-ORFHA-E ; ; ABC/EF ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; .CSECT SYSHND .GLOBL RFINT, DTSYS, RKSYS .GLOBL DPSYS, DSSYS, DXSYS .GLOBL RFSYS, $INPTR, $INTEN, $PATCH RFCS = 177460 ;CONTROL AND STATUS RFWC = 177462 ;WORD COUNT RFMA = 177464 ;MEMORY ADDR RFDA = 177466 ;DISK ADDR RFAE = 177470 ;ADDRESS EXTENTION CMAINH = 400 ;INHIBIT INCREMENT OF MEMORY ADDRESS RFVEC = 204 ;RF INTERRUPT VECTOR R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 MONLOW = 54 OFFSET = 270 RD = 105 WR = 103 ; RKSYS = 0 DTSYS = 0 DXSYS =0 DPSYS = 0 DSSYS = 0 PR7 = 340 ;PRIORITY 7 PR5 = 240 FIRST: .WORD RFVEC ;ADDR OF INTERRUPT VECTOR .WORD RFINT-. ;OFFSET TO INTERRUPT ROUTINE .WORD PR7 ;PRIORITY 7 RFSYS: RFLQE: .WORD 0 ;POINTER TO LAST Q ENTRY RFCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ENTRY: MOV #7,(PC)+ ;LOAD RETRY COUNT RFTRY: .WORD 0 AGAIN: JSR R0,RFCOMN ;DO COMMON STUFF TO START ZERO: .WORD 0 ;NO INHIBIT INCREMENT MOV (R5)+,-(R4) ;BUFFER ADDRESS TO RFMA MOV (R5)+,-(R4) ;WORD COUNT MOV #WR,R5 ;ASSUME WRITE TST @R4 ;CHECK WORD COUNT BEQ RFHOME ;NO I/O ! BMI 1$ ;WRITE WAS RIGHT MOV #RD,R5 ;NO, READ NEG @R4 ;NEGATE WORD COUNT 1$: MOV R5,-(R4) ;START IT MOVING RTS PC ;OK, GANG ; INTERRUPT ROUTINE BR RFABORT ;ENTRY TO ABORT XFER RFINT: JSR R5,@$INPTR ;DO COMMON ENTRY CODE .WORD ^C&PR7 MOV RFCQE,R5 ;R5=POINTER TO CQE TST @#RFCS ;TEST FOR ERROR BPL RFFILL ;IF B15 OFF GO HOME DEC RFTRY ;DEC RETRY COUNT BGT AGAIN ;RETRY BIS #HDERR,@-2(R5) ;SET HARD ERR FLAG RFHOME: MOV PC,R4 ADD #RFCQE-.,R4 ;PIC ADDR OF RFCQE TO R4 MOV @#MONLOW,R5 JMP @OFFSET(R5) ;GO HOME TO MOMMA RFABORT:MOV #400,@#RFCS ;POWER CLEAR TO ABORT BR RFHOME RFFILL: JSR R0,RFCOMN ;DO COMMON START .WORD CMAINH MOV 2(R5),R5 ;GET WORD COUNT BPL RFHOME ;IT WAS A READ, NO NEED TO FILL TSTB R5 ;WAS IT AN EVEN # OF BLOCKS? BEQ RFHOME ;YEP NEG R5 ;MAKE IT POSITIVE ADD R5,@R4 ;FIX UP RF DISK ADDRESS ADC 2(R4) ;INCLUDING ADDRESS EXTENSION BIS #177400,R5 ;MAKE IT LESS THAN 256 WORDS MOV PC,-(R4) ;POINT MEMORY ADDRESS TO A 0 ADD #ZERO-.,@R4 ;(PIC) MOV R5,-(R4) ;SET WORD COUNT MOV #WR,-(R4) ;START IT WRITING RTS PC ;OUT POPHOM: MOV (SP)+,R0 ;RESTORE R0 BR RFHOME RFCOMN: MOV #RFAE,R4 ;POINT TO ADDRESS EXTENSION REG BIT @R0,@R4 ;DID WE JUST FINISH FILLING? BNE POPHOM ;YES. FILL CALLED US, BUT GO FINISH MOV #400,@#RFCS ;POWER CLEAR THE RF MOV RFCQE,R5 ;GET Q ELT POINTER MOV (R5)+,-(SP) ;GET BLOCK NUMBER SWAB @SP ; * 256 = ADDRESS ON DISK MOV @SP,@R4 ;SET ADDRESS EXTENSION FROM HIGH BITS BIC #177740,@R4 ;ONLY THE RELEVANT BITS BIS (R0)+,@R4 ;TURN ON INHIBIT IF NEEDED CLRB @SP ;ROUND ACTUAL ADDRESS TO BLOCK MOV (SP)+,-(R4) ;SET RFDA TST (R5)+ ;ADVANCE OVER UNIT # RTS R0 ;RETURN $INPTR: .WORD $INTEN RFSIZE = .-FIRST $PATCH: ;PATCH AREA FOR MONITR FOLLOWS .END .TITLE DT V02-08 12-APR-74 ; RT-11 DECTAPE (TC11) HANDLER ; ; DEC-11-ORTDA-E ; ; RB/EF ; ; AUGUST, 1974 ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; .CSECT SYSHND .ENABL LSB R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 PS=177776 ; DECTAPE CONTROL REGISTERS TCDT = 177350 ;DATA REGISTER TCST = 177340 ;CONTROL AND STATUS REGISTER TCCM = 177342 ;COMMAND REGISTER TCWC = 177344 ;WORD COUNT REGISTER TCBA = 177346 ;BUS ADDRESS REGISTER TCVEC = 214 ;TC11 INTERRUPT VECTOR ;CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 ;HARD ERROR BIT MONLOW = 54 ;MONITOR BASE POINTER OFFSET = 270 ;POINTER TO Q MANAGER COMP ENTRY .GLOBL DTSYS, RKSYS, RFSYS, DPSYS, DSSYS, DXSYS .GLOBL $INPTR, $INTEN, DTINT RKSYS = 0 ;RK IS NOT RESIDENT RFSYS = 0 ;NEITHER IS RF DXSYS = 0 DPSYS = 0 DSSYS = 0 PR7 = 340 ;ENTERS AT LEVEL 7 BEG: ; LOAD POINT .WORD TCVEC ;ADDRESS OF INTERRUPT VECTOR .WORD DTINT-. ;OFFSET TO INTERRUPT SERVICE .WORD PR7 ;PRIORITY 7 DTSYS: DTLQE: .WORD 0 ;POINTER TO LAST Q ENTRY DTCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ; ENTRY POINT MOV #8.,(PC)+ ;INIT THE RETRY COUNT DTTRY: .WORD 0 ;RETRY COUNTER CLR -(SP) ;FAKE AN INTERRUPT ;DV15 JSR PC,DTINT RTS PC ;BACK TO MONITOR ;INTERRUPT SERVICE BR DTSTOP ;ABORT CALL FROM BF SYSTEM DTINT: JSR R5,@$INPTR ;NOW JSR TO COMMON CODE .WORD ^C<300>&PR7 ;RUN AT LEVEL 6 MOV R0,-(SP) MOV DTCQE,R0 ;RO POINTS TO Q ELEMENT MOV #TCCM,R4 ;R4 POINTS TO CONTROL REGISTER MOV (R0)+,-(SP) ;DESIRED BLOCK # ONTO STACK MOV (R0)+,R5 ;UNIT # INTO R5 BIC #^C<3400>,R5 ;ISOLATE UNIT NUMBER BIT #100100,(R4) ;ERROR BIT ON? BMI DTERR ;YES BEQ RETRY ;IF INTERRUPT IS OFF,WE ARE INITIATING ;A REQUEST BIT #2,(R4) ;SEARCHING? BEQ DTDONE ;NO-A READ OR WRITE JUST COMPLETED CMP @#TCDT,BWANT ;COMPARE ACTUAL BLOCK TO DESIRED BLOCK BEQ BLKFND ;FOUND IT DIRECT: BLE FORWARD ;SEARCH IN THE FORWARD DIRECTION REVERSE:BIS #4000,R5 ;SET REVERSE BIT SUB #2,(SP) ;SEARCH FOR TW0 BLOCKS BEFORE ONE ;ACTUALLY DESIRED (TO ALLOW ;SPACE FOR THE TURN-AROUND BR FORWARD ;DON'T SET DELAY INHIBIT FORW1: BIS #10000,R5 ;TAPE IS ALREADY MOVING FORWARD ;SO INHIBIT HARDWARE DELAY FORWARD:BIS #103,R5 ;INTERRUPT ENABLE,RNUM,AND GO MOV (SP)+,BWANT ;REMEMBER THE BLOCK WE ARE LOOKING FOR RETRNI: MOV R5,(R4) ;TELL CONTROLLER TO GO MOV (SP)+,R0 ;RESTORE R0 RTS PC ;BACK INTO MONITOR ENDZR: BIT #4000,(R4) ;WERE WE IN REVERSE? BEQ REVERSE ;NO-REVERSE TAPE BLKFND: BIT #4000,(R4) ;WERE WE GOING FORWARD? BNE FORWARD ;NO-WE HAVE TO TURN AROUND ; INITIATE READ/WRITE REQUEST BIS #10115,R5 ;ASSUME WRITE MOV (R0)+,@#TCBA ;CORE ADDRESS MOV (R0),(SP) ;WORD COUNT (OVER BLOCK #) BMI 1$ ;WRITE WAS A GOOD GUESS BEQ DTDONE ;IF ZERO,SEEK NEG (SP) ;READ-NEGATE WORD COUNT BIC #10,R5 ;SET READ FUNCTION 1$: MOV (SP)+,@#TCWC ;SET WORD COUNT BR RETRNI ; ERROR ROUTINE DTERR: BIT #104000,@#TCST ;ENDZ ERROR? BPL NOTEZ ;NOT ENDZ BIT #2,(R4) ;WERE WE SEARCHING? BNE ENDZR ;YES-REVERSE TAPE NOTEZ: DEC DTTRY ;MORE TRIES LEFT? BGT RETRY ;YES BIS #HDERR,@-6(R0) ;NO-SET HARD ERROR BIT ; OPERATION FINISHED DTDONE: TST (SP)+ ;POP BLOCK MOV (SP)+,R0 ;RESTORE R0 DTSTOP: MOVB #11,@#TCCM ;STOP SELECTED DRIVE MOV PC,R4 ADD #DTCQE-.,R4 ;ADDR OF CQE IN R4 MOV @#MONLOW,R5 JMP @OFFSET(R5) ; RETRY CODE RETRY: TSTB @#TCST ;TAPE UP TO SPEED? BMI FORW1 ;YES-AVOID STOPPING TAPE ADD #4,BWANT ;NO-IT TAKES 4 BLOCKS TO START AND STOP CMP (PC)+,(SP) ;MAKE AN ATTEMPT TO START IN THE BWANT: 0 ;RIGHT DIRECTION BASED ON LAST BLOCK BR DIRECT ;DESIRED $INPTR: .WORD $INTEN DTSIZE = .-BEG ;SIZE OF DT HANDLER .END .TITLE TT V02-04 ; TT HANDLER FOR RT-11 V2C ; DEC-11-ORTTA-E ; EF ; COPYRIGHT 1974,1975 ; DIGITAL EQUIPMENT CORP. ; MAYNARD, MASSACHUSETTS 01754 ; 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 DIGITAL. ; ; 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 RESPONSIBLITY FOR ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR ; RELIABILITY OF ITS SOFTWARE ON EQUIPMENT WHICH IS ; NOT SUPPLIED BY DIGITAL. .MCALL .REGDEF,.TTINR .CSECT TT ; OFFSET DEFINITIONS: MONLOW = 54 ;POINTER TO RMON OFFSET = 270 ;OFFSET TO Q COMPLETION TTPS = 310 ;OFFSETS TO TT REGS. TTPB = 312 EOF$ = 20000 ;EOF BIT IN CHAN. STATUS WORD .REGDEF .ENABL LSB .WORD 0 ;SO FETCH LEAVES VECTORS ALONE .WORD 0,0 TTLQE: .WORD 0 ;LAST Q ELEMENT POINTER TTCQE: .WORD 0 ;CURRENT Q POINTER TT: BR TTSET ;DO SETUP FOR TRANSFER BR TTRD ;A READ INTERRUPT OCCURRED JSR R2,(PC) ;SAVE R2; POINT R2 TO POINTERS ADD #RING+2-.,R2 ;R2 TO COUNT WORD MOV R4,-(SP) ADD @R4,R4 ;CHECK MONITOR'S ^O FLAG TST @R4 ;IS ^C STRUCK? BMI DON1 TST OPFLG ;DOING A TRANSFER? BPL COMX ;NO. LEAVE TT2: TST 20.(R4) ;IS ^O ON? BNE DONE ;YEP. IGNORE BUFFER 1$: TST (R2)+ ;MORE OUTPUT? BEQ 3$ ;NO. RESTORE R5 TSTB @(R2) ;IS CHARACTER NULL? BEQ 2$ ;YES. SKIP IT MOV R2,R5 BR COMX 2$: INC @R2 DEC -(R2) BR 1$ 3$: MOV R4,R5 ;NO MORE. RESET R5 TO MON. RING PTR. ADD #16.,R5 BR DONE ;LEAVE COMPLETION ALONE DON1: MOV TTCQE,R2 ;MAKE SURE WE DON'T RECALL A COMPLETION CLR 10(R2) ;ROUTINE BY CLEARING IT IF IT EXISTS DONE: JSR PC,FINIS ;CLEAN UP TIME MOV PC,R2 ;SEE IF FINIS QUEUED ANOTHER OPERATION ADD #RING+2-.,R2 MOV (SP),R4 ;MAKE R4 OK FOR BR TO TT2 ADD @R4,R4 TST (R2) ;ANY LEFT OR NEW TRANSFERS? BNE TT2 ;YES. SERVICE THEM CLRB 1(R4) COMX: MOV (SP)+,R4 MOV (SP)+,R2 OIGNR: TST (R4)+ RTS R4 .DSABL LSB TTRD: TST TTCQE ;WERE WE CALLED BY READ/WRITE? BEQ OIGNR ;NO. LEAVE JSR R2,(PC) ADD #RING+4-.,R2 ;POINT TO USER'S BUFF PTR. MOV R4,-(SP) ADD @R4,R4 ;SEE IF ^C STRUCK TST @R4 BMI DON1 1$: JSR R4,GETCHR ;GET CHAR FROM RING BUFFER BR COMX ;NONE WAS FOUND BR 1$ ;ONE WAS FOUND BR DONE .ENABL LSB TTSET: JSR R2,(PC) ;HERE FOR SETUP ADD #RING-.,R2 MOV R4,-(SP) MOV R3,-(SP) MOV @#MONLOW,R3 ;POINTER TO RMON MOV TTCQE,R4 ;FILL INTERNAL POINTERS CMP (R4)+,(R4)+ ;BUMP TO BUFF ADDRESS MOV (R4)+,(R2)+ MOV (R4),(R2) ;WORD COUNT MOV @R2,-(SP) ;SAVE FOR LATER BGT 1$ ;>0 INDICATES A READ ;DV11 BEQ 5$ ;0 => SEEK; IGNORE IT ;DV11 NEG (R2) ;A WRITE. FLIP WD COUNT 1$: ASL (R2)+ ;MAKE IT BYTES MOV -(R4),(R2)+ ;SECOND BUFF POINTER MOV (R4),(R2) ;UPPER LIMIT ADD -4(R2),(R2) MOV (SP),(PC)+ ;SET OP IN PROGRESS OPFLG: .WORD 0 BMI 3$ MOV #'^,@TTPB(R3) ;YES. GENERATE AN ^ 3$: MOV #100,@TTPS(R3) ;SET INTERRUPTS TST (SP)+ BMI 6$ ;NOT DOING A READ. ;DV11 TST -(R2) ;R2 TO USER'S BUFF PTR 4$: JSR R4,GETCHR ;FOR READ AHEAD BR 6$ ;NONE THERE BR 4$ ;GOT ONE. ANY MORE? 5$: JSR PC,FINIS ;EOF ON ENTRY. 6$: MOV (SP)+,R3 MOV (SP)+,R4 MOV (SP)+,R2 RTS PC .DSABL LSB GETCHR: MOV R0,-(SP) ;R0 MAY HAVE SOMETHING WE NEED .TTINR ;GET CHAR FROM MONITOR BCS CHRET ;NOTHING THERE TST OPFLG ;WERE WE CALLED VIA A READ? BLE CHRET ;NO. IGNORE IT TST (R4)+ ;SKIP THAT RETURN CMP R0,#'Z&77 ;IS IT EOF? BEQ 1$ MOVB R0,@(R2)+ ;STORE IT INC -2(R2) ;DECREMENT POINTER ;DV11 CMP (R2),-(R2) ;ARE WE AT THE END OF BYTE COUNT? BEQ 4$ ;YES. NO NEED TO ZERO BUFFER ;DV11 BR CHRET 1$: CMP (R2)+,(R2) ;ARE THEY EQUAL? BHIS 3$ ;YES. CLRB @-(R2) ;ZERO BUFF INC (R2) BR 1$ 3$: MOV TTCQE,R2 ;SET EOF IN CSW WORD BIS #EOF$,@-(R2) 4$: TST (R4)+ ;TAKE EOF RETURN ;DV11 CHRET: MOV (SP)+,R0 RTS R4 RING: .WORD 0,0,0,0 FINIS: CLR OPFLG ;NOTHING GOING ON. CLR RING+2 ;SO CODE AT DONE WON'T GO TO TT2 ON ^C MOV PC,R4 ;TO Q COMPLETION. ADD #TTCQE-.,R4 TST @R4 ;SHOLD WE GO THERE? BEQ 1$ ;NO. NOTHING TO DO. MOV @#MONLOW,R2 JSR PC,@OFFSET(R2) 1$: RTS PC .END TTRD: TST TTLQE ;IF ZERO, HANDLER NOT CALLED BEQ OIGNR TST OPFLG ;BUSY? BEQ OIGNR ;NO. JUST GET OUT MOV R2,-(SP) ;SAVE R2,R4 MOV R4,-(SP) TTRD2: MOV PC,R2 ;NOW POINT R2 AT CTRL CHARS ADD #CTBL-.,R2 JSR PC,TYPAHD ;SEE IF THERE IS TYPE AHEAD CMPB R0,(R2)+ ;IS IT ^C? BEQ CTRLC TST OPFLG ;ARE WE REALLY DOING A READ? BMI COMX ;NO. LOOK NO FURTHER CMPB R0,(R2)+ ;IS IT ^Z? BEQ EOF ;YES. END OF INPUT TST (R2)+ ;SKIP TO BUFF POINTER CMP (R2)+,4(R2) ;TIME TO QUIT? BEQ EOF1 ;YES. BUT DON'T ZERO BUFFER TST (R5) ;IS THERE STILL TYPE AHEAD? BEQ 3$ ;NO. INC -(R2) ;YES. BUMP POINTER MOVB R0,@(R2)+ BR TTRD2 3$: CLR (R2) SWTR5: MOV R2,R5 BR COMX CTRLC: TST OPFLG ;DOING A READ? BPL 1$ CMP R0,(R1) ;NO. SEE IF THIS IS 2ND ^C BNE COMX ;NO. LET MONITOR HAVE IT 1$: ADD (R4),R4 ;THIS ^C GETS US OUT CLR (R4)+ ;CLEAR MONITOR LINE COUNT TST (R4)+ ;SKIP TO POINTER MOV (R4)+,-(SP) ;EQUATE POINTERS CLR (R4)+ ;ZERO COUNT MOV (SP)+,(R4) MOV R0,(R1) ;MAKE IT 2ND ^C CLR (PC)+ ;SO ^C WILL ECHO OPFLG: .WORD 0 BR COMX ;AND GET OUT EOF: TST (R2)+ ;R2 TO POINTER INC (R2) ;DON'T WIPE LAST CHAR. 1$: CLRB @(R2)+ ;ZERO REMAINDER OF BUFFER INC -(R2) CMP (R2),6(R2) ;DONE? BNE 1$ EOF1: MOV TTCQE,R2 ;SET EOF BIT BIS #EOF$,@-(R2) ADD (R4),R4 CLR (R4)+ ;CLEAR LINE COUNT CLR OPFLG ;UNBUSY IT BR DONE TTSET: JSR R2,(PC) ADD #PRING-.,R2 ;SETUP FAKE RING BUFFER MOV R4,-(SP) MOV R3,-(SP) ;NEED EXTRA REGISTER HERE MOV @#MONLOW,R3 MOV TTCQE,R4 CMP (R4)+,(R4)+ ;POINT TO BUFFER ADD. MOV (R4),(R2)+ ;LOW LIMIT MOV (R4)+,(R2)+ ;RING POINTER MOV (R4),(R2) ;WORD COUNT BMI 3$ ;IF READ, DECREASE INITIAL PTR DEC -2(R2) 3$: MOV (R4),OPFLG ;OP FLAG. >0=READ <0=WRITE BPL 1$ NEG (R2) ;A WRITE. MAKE WCNT POS. 1$: ASL (R2)+ ;CHANGE IT TO BYTE COUNT MOV -(R4),(R2)+ ;RING POINTER MOV (R4),(R2) ;HI LIMIT ADD -4(R2),(R2) TST OPFLG ;A WRITE? BPL 4$ 2$: MOV #100,@TTPS(R3) ;YES. START IT UP MOV (SP)+,R3 MOV (SP)+,R4 MOV (SP)+,R2 RTS PC 4$: MOV #'^,@TTPB(R3) ;GENERATE AN ^ ON READ BR 2$ TYPAHD: TST (R5) ;ANY TYPE AHEAD? BEQ 2$ TST CHSAVE ;ARE WE HOLDING A CHARACTER? BNE 1$ ;YES. DON'T STORE ANOTHER MOV R0,CHSAVE ;NO. STORE THE ONE READ FROM TTY 1$: DEC (R5)+ ;YES. DECREASE COUNT IN RING INC (R5)+ ;POINTER UPDATE MOVB @-(R5),R0 ;CHARACTER TO R0 TST -(R5) ;BACK TO COUNT RTS PC 2$: MOV (PC)+,R0 ;RESTORE SAVED INTERRUPT CHAR. CHSAVE: .WORD 0 CLR CHSAVE RTS PC CTBL: .BYTE 'C&77,'Z&77 PRING: .WORD 0,0,0,0,0 .END .TITLE LP V02-06 20-OCT-75 ; RT-11 LINE PRINTER (LP/LS11) HANDLER ; ; DEC-11-ORTLA-E ; ; RGB/EP/ABC/EF/DV ; ; MARCH 1973/FEBRUARY 1974 ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; LINE PRINTER CONTROL REGISTERS (STANDARD UNIBUS LOCATIONS) ;LP.S = 177514 ;LINE PRINTER CONTROL REGISTER ;LP.B = 177516 ;LINE PRINTER DATA BUFFER ;LP.VEC = 200 ;LINE PRINTER VECTOR ADDR ; DEFAULT CONTROL REGISTER DEFINITIONS .IIF NDF LP.S, LP.S = 177514 .IIF NDF LP.B, LP.B = 177516 .IIF NDF LP.VEC, LP.VEC = 200 ;CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 ;HARD ERROR BIT MONLOW = 54 ;BASE ADDR OF MONITOR OFFSET = 270 ;POINTER TO Q MANAGER COMP ENTRY PR7 = 340 PR4 = 200 ; ASCII CONSTANTS CR = 15 LF = 12 FF = 14 HT = 11 COLSIZ = 132. ;132 COLS .GLOBL COLCNT ; THE FOLLOWING ARE THE PARAMETERS FOR INTERFACE TO THE MONITOR 'SET' COMMAND .ASECT . = 400 .WORD 30. ;MINIMUM WIDTH .RAD50 /WIDTH / .WORD /2+40000 ;NO 'NO' OPTION, NUMBER REQUIRED NOP ;NO CR => NOP CROPT .RAD50 /CR / .WORD /2+100000 ;ALLOW 'NO' NOP ;NO FORM0 => NOP FFOPT .RAD50 /FORM0 / .WORD /2+100000 ;ALLOW 'NO' BMI LPERR-ERROPT+. ;NO HANG BY GOING TO ERROR .RAD50 /HANG / .WORD /2+100000 ;ALLOW 'NO' .WORD 40 ;FOR NO LC, CONVERT LC TO UC .RAD50 /LC / .WORD /2+100000 BNE IGNORE-CTROPT+. ;IGNORE CTRL CHAR IF NOCTRL .RAD50 /CTRL / .WORD /2+100000 ;ALLOW 'NO' 0 ;END OF LIST O.WIDTH:MOV R0,COLCNT ;NEW WIDTH TO 2 CONSTANTS MOV R0,RSTC+2 CMP R0,R3 ;ERROR IF < 30. RTS PC O.CR: MOV (PC)+,R3 ;NO 'NO', SO SET TO DO CR BEQ RSTC-CROPT+. MOV R3,CROPT ;SET CR OPTION RTS PC O.FORM0:MOV (PC)+,R3 ;SET TO DO FORMFEEDS ON BLOCK 0 BEQ BLK0-FFOPT+. MOV R3,FFOPT RTS PC O.HANG: MOV (PC)+,R3 ;SET TO HANG BMI RET-ERROPT+. MOV R3,ERROPT RTS PC O.LC: CLR R3 ;FOR 'LC', LEAVE LOWER CASE STUFF ALONE NOP MOV R3,LCOPT RTS PC O.CTRL: MOV (PC)+,R3 ;SET TO PASS ALL NON-PRINTING CHAR BNE PC1-CTROPT+. MOV R3,CTROPT RTS PC .=1000 ; LOAD POINT LOADPT: .WORD LP.VEC ;ADDR OF INTERRUPT VECTOR .WORD LPINT-. ;OFFSET TO INTERRUPT SERVICE .WORD PR7 ;PRIORITY 7 LPLQE: .WORD 0 ;POINTER TO LAST Q ENTRY LPCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ; ENTRY POINT LP: MOV LPCQE,R4 ;R4 POINTS TO CURRENT Q ENTRY ASL 6(R4) ;WORD COUNT TO BYTE COUNT BCC LPERR ;A READ REQUEST IS ILLEGAL BIS #100,@LPS ;CAUSE AN INTERRUPT,STARTING TRANSFER RTS PC ; INTERRUPT SERVICE BR LPDONE ;ABORT ENTRY POINT LPINT: JSR R5,@INTEN ;INTO SYSTEM STATE .WORD ^C&PR7 MOV LPCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT TST @(PC)+ ;ERROR CONDITION? LPS: .WORD LP.S ;LINE PRINTER STATUS REGISTER ERROPT: BMI RET ;YES-HANG TILL CORRECTED TST (R4)+ ;IS THIS BLOCK 0? FFOPT: BEQ BLK0 ;YES - OUTPUT INITIAL FORM FEED TST (R4)+ ;AND POINT TO ADRS OF NEXT CHAR LPNEXT: TSTB @LPS ;READY FOR ANOTHER CHAR YET? BPL RET ;NOPE - RETURN FROM INTERRUPT ASLB (PC)+ ;TAB IN PROGRESS? TABFLG: .WORD 0 BNE TAB ;BRANCH IF DOING TAB IGNORE: MOVB @(R4)+,R5 ;GET NEXT CHAR (IF ANY) BIC #177600,R5 ;7-BIT TST (R4) ;ANY MORE CHARS? BEQ LPDONE ;NO:FINISHED INC (R4) ;YES, DECREMENT COUNT (IT WAS NEGATIVE) INC -(R4) ;BUMP BUFFER POINTER CMPB R5,#40 ;PRINTING CHAR? BLO CHRTST ;NO-GO TEST FOR SPECIAL CHAR. CMPB #140,R5 ;LOWER CASE? BHIS PCHAR ;NO SUB (PC)+,R5 ;YES, CONVERT IF DESIRED LCOPT: 40 PCHAR: DEC (PC)+ ;ANY ROOM LEFT ON LINE? COLCNT: .WORD COLSIZ ;# OF PRINTER COLUMNS LEFT BLT IGNORE ;NO MORE ROOM ON LINE,DON'T PRINT CHAR ASLB (PC)+ ;UPDATE TAB COUNT TABCNT: .WORD 1 BEQ RSTTAB ;RESET TAB PC1: MOVB R5,@#LP.B ;PRINT THE CHAR BR LPNEXT ;TRY FOR NEXT CHAR RET: RTS PC CHRTST: CMPB R5,#HT ;IS CHAR A TAB? BEQ TABSET ;YES-RESET TAB CMPB R5,#LF ;IS IT LF? BEQ RSTC ;YES-RESTORE COLUMN COUNT CMPB R5,#CR ;IS IT CR? CROPT: BEQ RSTC ;PRINT UNLESS MODIFIED CMPB R5,#FF ;IS IT A FF? CTROPT: BNE IGNORE ;IGNORE NON-PRINT CHARS UNLESS MODIFIED RSTC: MOV #COLSIZ,COLCNT ;RE-INITIALIZE COLUMN COUNTER RSTTAB: MOV #1,TABCNT ;RESET TAB COUNTER BR PC1 ;PRINT THE CHAR TABSET: MOV TABCNT,TABFLG ;SET UP TAB TAB: MOV #40,R5 ;PRINT SPACES BR PCHAR BLK0: INC -(R4) ;MAKE SURE WE ONLY COME HERE ONCE CMP (R4)+,(R4)+ ;POINT TO ADRS OF NEXT CHAR MOV #FF,R5 ;PRINT INITIAL FF BR RSTC LPERR: BIS #HDERR,@-(R4) ;SET HARD ERROR BIT ; OPERATION COMPLETE LPDONE: CLR @LPS ;TURN OFF INTERRUPT MOV PC,R4 ADD #LPCQE-.,R4 ;ADDR OF CQE IN R3 MOV @#MONLOW,R5 JMP @OFFSET(R5) ;JUMP TO Q MANAGER INTEN: 0 LPSIZE = .-LOADPT .END .TITLE PR V02-04 ; RT-11 HIGH SPEED PAPER TAPE READER (PC11) HANDLER ; ; DEC-11-ORPHA-E ; ; ABC/ECB/RGB/EF/DV ; ; MAY 1974 ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; .CSECT PC11PR R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; PAPER TAPE READER CONTROL REGISTERS PRS = 177550 ;CONTROL REGISTER PRB = 177552 ;DATA REGISTER PRVEC = 70 ;READER VECTOR ADDR PRGO = 1 ;READER ENABLE BIT PINT = 101 ;INTERRUPT ENABLE BIT AND GO BIT ; CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 ;HARD ERROR BIT MONLOW = 54 ;POINTER TO MONITOR BASE OFFSET = 270 ;POINTER TO Q MANAGER COMPLETION ENTRY PR4 = 200 ;PRIORITY 4 PR7 = 340 ;PRIORITY 7 ; LOAD POINT PRSTRT: .WORD PRVEC ;ADDR OF INTERRUPT VECTOR .WORD PRINT-. ;OFFSET TO INTERRUPT ENTRY .WORD 340 ;PRIORITY 7 PRLQE: .WORD 0 ;POINTER TO LAST Q ENTRY PRCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ; ENTRY POINT PR: MOV PRCQE,R4 ;POINTER TO Q ENTRY IN R4 ASL 6(R4) ;WORD COUNT TO BYTE COUNT BCS PRERR ;A WRITE REQUEST IS ILLEGAL TO PR BEQ SEEK ;A REQUEST FOR 0 BYTES IS A SEEK TST @#PRS ;IS READER READY? BMI PRERR ;NO. NO TAPE, PROBABLY MOV #PINT,@#PRS ;ENABLE READER INTERRUPT, GET A CHAR RTS PC BR PRABRT ;ABORT ENTRY FOR F/B ; INTERRUPT SERVICE PRINT: JSR R5,@$INTEN ;RETURN AT LEVEL 4 .WORD ^C&PR7 MOV PRCQE,R4 ;R4 POINTS TO Q ENTRY ADD #4,R4 ;POINT R4 TO BUFFER ADDRESS TST @#PRS ;ANY ERRORS? BMI PREOF ;YES-TREAT AS EOF MOVB @#PRB,@(R4) ;PUT CHAR IN BUFFER INC (R4)+ ;BUMP BUFFER POINTER DEC @R4 ;DECREASE BYTE COUNT BEQ PRDONE ;IF ZERO,WE ARE DONE BIS #PRGO,@#PRS ;RE-ENABLE READER RTS PC PREO1: INC (R4) PREOF: CLRB @(R4) ;CLEAR REMAINDER OF BUFFER DEC 2(R4) BNE PREO1 ;MORE BIS #20000,@-6(R4) ;SET EOF BIT IN CHANNEL STATUS ; OPERATION COMPLETE SEEK: PRABRT: PRDONE: BIC #PINT,@#PRS ;TURN OFF THE READER INTERRUPT ;IN CASE WE GET AN ERROR LATER MOV PC,R4 ADD #PRCQE-.,R4 ;GET ADDR OF CURRENT Q ENTRY MOV @#MONLOW,R5 JMP @OFFSET(R5) ;TO MONITOR COMPLETION PRERR: BIS #HDERR,@-(R4) ;SET HARD ERROR BIT BR PRDONE ;AND COMPLETE OPERATION $INTEN: .WORD 0 ;MODIFIED BY .FETCH PRSIZE=.-PRSTRT .END .TITLE PP V02-04 11/12/75 ; RT-11 HIGH SPEED PAPER TAPE (PC11) PUNCH HANDLER ; ; DEC-11-ORTPA-E ; ; ABC/RGB/DV ; ; MAY 1974 ; ; COPYRIGHT (C) 1974,1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; 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 DIGITAL. ; ; 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. ; .CSECT PC11PP R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; PAPER TAPE PUNCH CONTROL REGISTERS PPS = 177554 ;PUNCH CONTROL REGISTER PPB = 177556 ;PUNCH DATA BUFFER PPVEC = 74 ;PUNCH VECTOR ADDR ; CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 ;HARD ERROR BIT MONLOW = 54 ;MONITOR BASE ADDR OFFSET = 270 ;POINTER TO Q MANAGER COMPL ENTRY PS = 177776 ;PSW PR7 = 340 ;PRIORITY 7 PR4 = 200 ;PRIORITY 4 ; LOAD POINT LOADPT: .WORD PPVEC ;ADDR OF INTERRUPT VECTOR .WORD PPINT-. ;OFFSET TO INTERRUPT SERVICE .WORD PR7 ;PRIORITY 4 PPLQE: .WORD 0 ;POINTER TO LAST Q ENTRY PPCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ; ENTRY POINT PP: MOV PPCQE,R4 ;R4 POINTS TO CURRENT Q ENTRY ASL 6(R4) ;WORD COUNT TO BYTE COUNT BCC PPERR ;A READ REQUEST IS ILLEGAL BIS #100,@#PPS ;CAUSES INTERRUPT,STARTING TRANSFER RTS PC BR PPDONE ;ABORT BY STOPPING ; INTERRUPT SERVICE PPINT: JSR R5,@$INPTR .WORD ^C&PR7 MOV PPCQE,R4 ;R4 POINTS TO CURRENT Q ENTRY TST @#PPS ;ERROR? BMI PPERR ;YES-PUNCH OUT OF PAPER ADD #6,R4 ;POINT R4 TO BYTE COUNT TST @R4 ;ANY MORE CHARS TO OUTPUT? BEQ PPDONE ;NO-TRANSFER DONE INC @R4 ;DECREMENT BYTE COUNT (IT IS NEGATIVE) MOVB @-(R4),@#PPB ;PUNCH CHARACTER INC @R4 ;BUMP POINTER RTS PC PPERR: BIS #HDERR,@-(R4) ;SET HARD ERROR BIT PPDONE: CLR @#PPS ;CLEAR INTERRUPT ENABLE MOV PC,R4 ADD #PPCQE-.,R4 ;ADDR OF NEXT Q ENTRY POINTER MOV @#MONLOW,R5 JMP @OFFSET(R5) ;JUMP TO Q MANAGER $INPTR: .WORD 0 ;POINTS TO COMMON ENTRY CODE PPSIZE = .-LOADPT .END