diff --git a/README.md b/README.md index 21ec8899..ebbbc56b 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,7 @@ A list of [known ITS machines](doc/machines.md). - TECO, editor. - TELNET, Telnet client. - TELSER, Telnet/Supdup server. + - TEN50, TOPS-10 emulator. - TIME, displays date/time/uptime and other info. - TIMES, TCP time server. - TIMOON, displays the time and phase of the moon. diff --git a/build/build.tcl b/build/build.tcl index 67a5be31..ad5388b4 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -980,6 +980,10 @@ respond "*" ":kill\r" respond "*" ":midas decsys;_decbot\r" expect ":KILL" +# ten50 +respond "*" ":midas sys3;ts ten50_mrc; ten50\r" +expect ":KILL" + # stktrn respond "*" ":fail sail;stktrn rel_sail;stktrn >\r" respond "*" "\032:kill\r" diff --git a/src/mrc/ten50.1 b/src/mrc/ten50.1 new file mode 100644 index 00000000..0ecf2885 --- /dev/null +++ b/src/mrc/ten50.1 @@ -0,0 +1,7479 @@ +;** S.MAC ** SYSTEM PARAMETERS + +TITLE TEN50 + +;ACCUMULATOR ASSIGNMENTS + +IOS=0 ;I/O DEVICE STATUS WORD +TAC=1 ;TEMPORARY, CLEARLY A TACKY MONITOR +TAC1=2 ;TEMPORARY +PDP=3 ;PUSH DOWN POINTER +ITEM=4 ;BUFFER ITEM COUNT +DAT=5 ;TTY INPUT BUFFER POINTER +JBUF==DAT ;ADDRESS OF 3 WORD BUFFER HEADER IN USER AREA +DEVDAT=6 ;RH = ADDRESS OF CURRENT DEVICE DATA BLOCK +PROG=7 +TEM=10 ;TEMPORARY +DSER=11 +BUFPNT=12 ;USED AS TEMPORARY AC IN COMCON +UCHN=BUFPNT +BUFWRD=13 ;USED AS TEMP AC IN COMCON +UUO=14 ;USED AS TEMP AC IN COMCON +AC1=15 ;USED AS TEMP AC IN COMCON +AC2=16 ;USED AS TEMP AC IN COMCON +AC3=17 + +;10/50 SYSTEM UUO DEFINITIONS + +CALLI==47000,, +OPEN==50000,, +RELEAS==71000,, +LOOKUP==76000,, +ENTER==77000,, + +;MACRO TO ASSEMBLE A BYTE POINTER DEC-STYLE + +DEFINE POINT ?S,ADDR,B=-1 +<<<<35.-.RADIX 10.,B>&77>_30.\<<.RADIX 10.,S>&77>_24.> ADDR>TERMIN + ;** S.MAC ** DEVICE DATA BLOCK NAMES + +DEVNAM==0 ;NAME IN SIXBIT ASCII + ; C(LH)=DEVICE MNEMONIC + ; C(RH)=DEVICE NUMBER, LEFT JUSTIFIED +DEVCHR==1 ;CHARACTERISTIC + ; LH = # FSIZ CHUNKS NECESSARY TO MAKE NEW DDB + ; (FOR PROTOTYPE DDB'S ONLY) + ; BITS 24-35=BUFFER SIZE +DEVIOS==2 ;STATUS WORD +DEVSER==3 ; C(LH)=NEXT DDB IN CHAIN + ; C(RH)=ADDRESS OF DEVICE SERVICE DISPATCH TABLE + + ;DEVICE SERVICE DISPATCH TABLE ASSIGNMENTS + DRL==0 ;RELEASE + DCL==1 ;CLOSE + DCLO==DCL ;CLOSE OUTPUT + ;IMMEDIATE PART OF CLOSE UUO + CLSOUT==1 ;INHIBIT CLOSING OUTPUT + CLSIN==2 ;INHIBIT CLOSING INPUT + DOU==2 ;OUTPUT + DIN==3 ;INPUT. SHORT DISPATCH TABLE + DEN==4 ;ENTER + DLK==5 ;LOOKUP + DDO==6 ;DUMP MODE OUTPUT + DDI==7 ;DUMP MODE INPUT + DSO==10 ;SETO + DSI==11 ;SETI + DRN==13 ;RENAME + DCLI==14 ;CLOSE INPUT + ;END OF LONG DISPATCH TABLE + +DEVMOD==4 + +;RIGHT HALF DEVICE CHARACTERISTIC WORD (DEVCHR UUO) + ASSCON==400000 ;ASSIGNED BY CONCOLE ("ASSIGN" COMMAND) + ASSPRG==200000 ;ASSIGNED BY PROGRAM (INIT UUO) + +;LEFT HALF DEVICE CHARACTERISTICS (DEVCHR UUO) + DVOUT==1 ;OUTPUT DEVICE + DVIN==2 ;INPUT DEVICE + DVDIR==4 ;DEVICE HAS A DIRECTORY + DVTTY==10 ;A TTY + DVAVAL==40 ;1 IF DEVICE IS AVAILABLE TO THIS JOB. + ; SET BY DEVCHR UUO + DVLNG==1000 ;DEVICE HAS LONG DISPATCH TABLE. + ; (OTHER UUO'S BESIDES INPUT, OUTPUT, CLOSE, RELEASE) + TTYUSE==10000 ;TTY IN USE + TTYATC==20000 ;TTY ATTACHED TO JOB (ONLY TRUE FOR CONSOLE) + DVLPT==40000 ;DEVICE IS AN LPT (CARRIAGE CONTROL IN FORTRAN) + DVDSK==200000 ;A DISK + +DEVLOG==5 ;LOGICAL NAME +DEVBUF==6 ; +DEVIAD==7 ; C(RH)=RELATIVE ADDRESS OF INPUT BUFFER + ; THE SERVICE ROUTINE IS FILLING +DEVADR==DEVIAD ; +DEVOAD==10 ;C(RH)=RELATIVE ADDRESS OF OUTPUT BUFFER THE + ; SERVICE ROUTINE IS EMPTYING +DEVPTR==DEVOAD +DEVCHN==11 ;KEEPS I.T.S.-ASSOCIATED CHANNELS + ; BITS 0-3: INPUT-ASSOCIATED CHANNEL + ; (BYTE POINTER = PDEVI) + ; BITS 4-7: OUTPUT-ASSOCIATED CHANNEL + ; (BYTE POINTER = PDEVO) +ITSNAM==12 ;I.T.S. NAME AND .OPEN MODE + ITSIOF==1 ;DENOTES INPUT (=0) OR OUTPUT (=1) IN .OPEN'S +DEVCTR==13 + +;FOR LONG DISPATCH TABLE DEVICES ONLY: + +DEVFIL==13 +DEVEXT==14 +DEVPPN==15 + ;** S.MAC ** I/O STATUS WORD ASSIGNMENTS + +;DATA MODES: BITS 32-35 (BYTE POINTER=PIOMOD) +A==0 ;ASCII +AL==1 ;ASCII LINE +I==10 ;IMAGE +IB==13 ;IMAGE BINARY +B==14 ;BINARY +SD==15 ;USED TO SIGNAL LOWEST DUMP MODE +DR==16 ;DUMP BY RECORDS +D==17 ;DUMP ACROSS RECORDS + +;RIGHT HALF (USER) +IOWC==20 ;DON'T COMPUTE WORD COUNT +IOCON==40 ;CONTINUOUS (CONT=0) + ; IN CONTINUOUS MODE WE WILL FILL UP FORWARD + ; INPUT BUFFERS +IOACT==10000 ;DEVICE ACTIVE (ONLY USED BY UUOCON TO + ; CLEAR BIT DURING SETSTS) +IODEND==20000 ;DATA END ENCOUNTERED +IOBKTL==40000 ;BLOCK TOO LARGE +IODTER==100000 ;DATA ERROR (CHECKSUM OR PARITY) +IODERR==200000 ;HARD DEVICE ERROR (OTHER THAN CHECKSUM OR PARITY) +IOIMPM==400000 ;IMPROPER MODE + +;LEFT HALF (SYSTEM) +IOW==1 ;I/O WAIT +IOBEG==2 +IOFST==4 +IOEND==40 ;SERVICE ROUTINE HAS TRANSMITTED LAST DATA + +;REST OF BITS IN LH ARE DEVICE DEPENDENT EXCEPT BIT 14 (=10) + ;** S.MAC ** HARDWARE BITS + +USRMOD==10000 ;LH PC WORD, MACHINE WAS IN USER MODE WHEN PC WAS STORED + +;LEFT HALF USRJDA (JOB DEVICE ASSIGNMENTS) +; UUO'S FOR THIS CHANNEL SINCE LAST INIT + +INITB==400000 ;INIT +IBUFB==200000 ;INIT W/I.BUFFER SPECIFIED +OBUFB==100000 ;INIT W/O.BUFFER SPECIFIED +LOOKB==40000 ;LOOKUP +ENTRB==20000 ;ENTER +INPB==10000 ;INPUT +OUTPB==4000 ;OUTPUT +ICLOSB==2000 ;INPUT CLOSE +OCLOSB==1000 ;OUTPUT CLOSE +INBFB==400 ;INBUF +OUTBFB==200 ;OUTBUF +SYSDEV==100 ;THIS DEVICE IS THE SYSTEM DEVICE +RENMB==40 ;RENAME UUO +DSKRLB==20 ;TO DISTINGUISH RESET UUO FROM RELEASE + +;ERROR CORES RETURNED TO USERS ON LOOKUP AND ENTER AND RENAMES +; IN RH OF 2ND WORD OF 4 WORD ARGUMENT BLOCK +;THE SAME ERROR CODES ARE RETURNED IN RUN UUO + +FNFERR==0 ;FILE NOT FOUND OR 0 FILE NAME +IPPERR==1 ;INCORRECT PROJECT-PROGRAMMER NUMBERS +FBMERR==3 ;FILE BEING MODIFIED +AEFERR==4 ;ALREADY EXISTING FILE +NLEERR==5 ;NEITHER LOOKUP OR ENTER (RENAME ONLY) +NSFERR==7 ;NOT A SAVE FILE (RUN UUO ONLY) +NECERR==10 ;NOT ENOUGH CORE (RUN UUO ONLY) +NSDERR==12 ;NO SUCH DEVICE (RUN UUO ONLY) + +;JOB BUFFER AREA HEADER + +JBFADR==0 ;BIT 0=1 IF THIS BUFFER RING HAS NEVER BEEN + ; REFERENCED FROM THE USER'S PROGRAM BY + ; AN INPUT OR OUTPUT COMMAND. + ; BITS 1-17=UNUSED + ; BITS 18-35=CURRENT BUFFER ADDRESS +JBFPTR==1 ;BYTE POINTER TO NEXT BYTE-1 +JBFCTR==2 ;POSITIVE ITEM COUNT + +;JOB BUFFER HEADER + +IOUSE==400000 ;1 IF BUFFER IS FULL + ; 0 IF BUFFER IS EMPTY + ; BITS 1-17=BUFFER SIZE + ; BITS 18-35=NEXT BUFFER ADDRESS + +;JOB STATUS WORD (JBTSTS) + +RUN==400000 ;USER WANTS JOB TO RUN +JERR==20000 ;A MONITOR DETECTED ERROR HAS OCCURRED + ; JOB CANNOT CONTINUE + ;** DSKSER.MAC ** DSK DDB + +DSDDB: SIXBIT IDSKI + XWD DSKCOR 201 ;BUFFER SIZE IN 24-35 + 0 ;DEVIOS + DSKDSP ;DEVSER: LH= ADR. OF NEXT DDB + ; RH = ADR. OF DISPATCH TABLE + XWD DVOUT+DVIN+DVDIR+DVDSK+DVLNG 154403 ;DEVMOD + 0 ;LOGICAL NAME + 0 ;DEVBUF: LH = ADR. OF O/P BUF. HDR. + ; RH = ADR. OF I/P BUF. HDR. + 0 ;DEVIAD - REL. ADR. OF INPUT BUFFER BEING FILLED + 0 ;DEVOAD + 0 ;DEVCHN : 0-3 = ITS INPUT CHANNEL + ; 4-7 = ITS OUTPUT CHANNEL + IBMDE,,(SIXBIT /DSK/) ;ITSNAM : 8-17 = MODE FOR .OPEN (=IMAGE, BLOCK) + ; 18-35 = ITS DEVICE NAME FOR .OPEN + +DSLEN==.-DSDDB ;= LENGTH OF INITIAL NON-ZERO SEGMENT OF DSDDB + + ;DEVCTR + 0 ;DEVFIL - FILENAME + 0 ;DEVEXT - EXTENSION + 0 ;DEVPPN +DEVCNT==.-DSDDB + 0 ;RH = COUNT OF BLOCKS IN FILE +SETCNT==.-DSDDB + 0 ;RH = USETO, USETI COUNTER +PTR1==.-DSDDB + + LOC DSDDB+DSLEN ;RELOCATE OURSELVES BACKWARDS OVER TRAILING + ; ZERO FRAGMENT OF DSDDB + +ITSNPT: POINT 28,ITSNAM(DEVDAT),35, ;POINTER TO ITS NAME AND MODE + ;** DSKSER.MAC ** PARAMETERS ASSOCIATED WITH DISK SERVICE: + +DRNAM==0 ;NAME IS IN FIRST WORD OF DIR. ENTRY +DREXT==1 ;EXT. IS IN SECOND WORD OF DIR. ENTRY +DRPROT==2 ;PROT, DATE, TIME IN THIRD WORD +DRSIZ==3 ;SIZE & FORWARD LINK IN FOURTH WORD + +BLKP2==7 ; # OF BITS TO SHIFT TO CONVERT + ;BETWEEN # BLOCKS AND # WORDS +BLKSIZ==200 ; # 0F WORDS/BLOCK +STDPRT==055 ;STANDARD PROTECTION KEY (I.T.S. << C.I.A.) + ;HOWEVER, YOU CAN'T WRITE IN ANOTHER LUSER'S + ;DIR ANYWAY, SO 055 IS BETTER THAN 000. + +;ERROR CODES FOR LOOKUP, ENTER AND/OR RENAME + +NOTINU==0 ;NO SUCH FILE IN UFD +NOTINM==1 ;NO SUCH UFD IN MFD +PROTF==2 ;FILE PROTECTED FROM THIS OPERATION ( E+1 ) +NORITE==3 ;FILE BEING WRITTEN +RENFAL==4 ;TRIED TO RENAME TO EXISTING NAME +NOFIL.==5 ;TRIED TO RENAME WITH NO FILE SELECTED + + +;DISK DISPATCH TABLE + +DSKDSP: JRST DFREL ;RELEASE + JRST DFCLSO ;CLOSE OUTPUT + JRST DFOUT ;OUTPUT + JRST DFIN ;INPUT + JRST DFENTR ;ENTER + JRST DFLOOK ;LOOKUP + JRST DFDMPO ;DUMP OUTPUT + JRST DFDMPI ;DUMP INPUT + JRST DFSET ;USETO + JRST DFSET ;USETI + POPJ PDP, ;UGETF + JRST DFREN ;RENAME + JRST DFCLSI ;CLOSE INPUT + POPJ PDP, ;UTPCLR + POPJ PDP, ;MTAPE + + +REASSI: +SETUWP: +REMAP: +UGTSEG: +DFDMPO: +DFDMPI: +DFSET: JSP TAC,ERRPTU + ASCIZ /Unimplemented UUO/ + MOVE TAC1,UUO0 + SOJA TAC1,PCPNT + + ;** DSKSER.MAC ** ENTER UUO + +DFENTR: PUSHJ PDP,GETWDU ;NULL FILENAME? + JUMPE TAC,DFER12 ;IF SO, ERROR + TLNE DEVDAT,LOOKB ;NO, HAS LOOKUP BEEN DONE? + JRST DFENT5 ;YES, ERROR FOR NOW - UPDATE MODE + ;NOT IMPLEMENTED YET + + MOVEM TAC,DEVFIL(DEVDAT) ;STORE FILENAME IN DDB + PUSHJ PDP,GETWD1 ;GET EXT. + TLNN TAC,-1 ; NULL EXTENSIONS BEING ILLEGAL ON ITS, + JRST DFER12 ; WE COP OUT WITH ILLEGAL NAME + HLLZM TAC,DEVEXT(DEVDAT) ;STORE IN DDB + HRRI UUO,2(UUO) ;GET SPECIFIED PPN + PUSHJ PDP,GETWDU + PUSHJ PDP,PPTOSN ;CONVERT TO SNAME + HRRI UUO,-3(UUO) ;RESET ACCUMULATOR "UUO" + TLNE DEVDAT,SYSDEV ;IS THIS SYSTEM DEVICE? + MOVE TAC,SYSPP ;YES, THEN GET SNAME OF "SYS" + CAME TAC,SNAME ;IS IT HIS SNAME? + JRST DFERR5 ;NO, ERROR FOR TRYING TO WRITE INTO + ;ANOTHER AREA + MOVEM TAC,DEVPPN(DEVDAT) ;YES, STORE IN DDB + MOVE TAC,DEVFIL(DEVDAT) ;GET FILENAME + MOVE TAC1,DEVEXT(DEVDAT) ;AND EXT. + SKIPA AC1,USRHCU ;GET HGHEST CHAN. IN USE AND SEE IF THIS FILE + ;IS BEING WRITTEN ON ANOTHER CHANNEL +ENTCK: SOJL AC1,DFENT1 ;OK IF NOT BEING WRITTEN NOW + SKIPE AC2,USRJDA(AC1) ;IS THIS CHAN. IN USE? + TLNN AC2,ENTRB ;YES, HAS AN ENTER BEEN DONE ON IT? + JRST ENTCK ;NO, LOOP + CAMN TAC,DEVFIL(AC2) ;YES, WAS IT DONE ON THIS FILE? + CAME TAC1,DEVEXT(AC2) + JRST ENTCK ;NO, LOOP +DFERR6: MOVEI TAC1,NORITE ;ERROR - FILE BEING WRITTEN NOW!! + JRST DFERRY +DFERR5: MOVEI TAC1,PROTF ;TELL HIM PROTECTION ERROR + JRST DFERRY + ;** DSKSER.MAC ** + +DFENT1: LDB TAC,PDEVO ;GET ITS O/P CHANNEL + JUMPN TAC,.+4 ;MOVE ON IF ALREADY ONE + PUSHJ PDP,GTFCHN ;NOT YET, GET ONE + JRST NOCHNE ;NONE AVAILABLE - ERROR + DPB TAC,PDEVO ;OK, STORE IT + PUSHJ PDP,GTTIME ;GET CURRENT TIME + IDIVI TAC,JIFMIN ;FORM MINUTES PAST MIDNITE + DPB TAC,[POINT 11,DEVCHN(DEVDAT),23,] ;STORE IN DDB + PUSHJ PDP,GTDATE ;GET TODAY'S DATE + DPB TAC,[POINT 12,DEVCHN(DEVDAT),35,] ;STORE IN DDB + LDB AC2,PDEVO ;GET CHANNEL # + PUSHJ PDP,SETENT ;SET UP A .OPEN FOR OUTPUT INSTR. + XCT TAC ;DO THE .OPEN + JRST DFERR6 ;FAILURE, ASSUME FILE BEING WRITTEN + SETZM DEVCNT(DEVDAT) ;INITIALIZE LENGTH +DFENT2: MOVEI TAC,1 ;INITALIZE SETCNT + MOVEM TAC,SETCNT(DEVDAT) + JRST CPOPJ1 ;SKIP RETURN + +;THIS LITTLE ROUTINE TAKES THE CONTENTS OF AC2 AS AN I.T.S. +;CHANNEL # AND RETURNS WITH THE SIXBIT OF THE CHANNEL IN AC2 AND +;SIXBIT/TMP/ IN AC3. HENCE, AC2 & AC3 REPRESENT A UNIQUE FILENAME. + +MKFNNM: IDIVI AC2,10 + ROT AC3,-6 + LSHC AC2,30. + ADD AC2,[SIXBIT/000UFD/] + MOVSI AC3,'TMP ;USE SIXBIT/TMP/ AS NAME2 + POPJ PDP, ;RETURN WITH AC2 & AC3 SET UP + +DFENT5: JSP TAC,ERRPTU + ASCIZ *Update mode not available* + JRST EXCALP + +NOCHNE: JSP TAC,ERRPTU + ASCIZ *Channel overflow* + JRST EXCALP + +SETENT: MOVEI TAC,(AC2) ;MAKE COPY OF CHAN. # + PUSHJ PDP,MKFNNM ;MAKE FUNNY NAME "UNAME ITS.CHN.#" + LDB AC1,ITSNPT ;SET UP ITS DEVICE NAME + TLO AC1,ITSIOF ;SET FOR OUTPUT + IORI TAC,<41>_4+_13. ;SET UP .OPEN INSTR. + ROT TAC,-13. ;POSITION IT + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** LOOKUP UUO + +DFLOOK: PUSHJ PDP,GETWDU ;GET THE FILE NAME + JUMPE TAC,DFER12 ;ERROR IF NULL + MOVEM TAC,DEVFIL(DEVDAT) ;NOT NULL, STORE IN DDB + PUSHJ PDP,GETWD1 ;GET EXTENSION + TLNN TAC,-1 ; NULL EXTENSIONS ARE ILLEGAL ON ITS + JRST DFER12 ; SO COP OUT WITH ILLEGAL NAME + HLLZM TAC,DEVEXT(DEVDAT) ;STORE IN DDB + HRRI UUO,2(UUO) ;GET PPN + PUSHJ PDP,GETWDU + PUSHJ PDP,PPTOSN ;CONVERT TO SNAME + TLNE DEVDAT,SYSDEV ;IS THIS DEVICE SYS ? + MOVE TAC,SYSPP ;YES, THEN GET SNAME OF "SYS" + MOVEM TAC,DEVPPN(DEVDAT) ;STORE IN DDB + HRRI UUO,-3(UUO) ;RESTORE UUO + HLRZ TAC1,DEVEXT(DEVDAT) ;GET EXT. INTO RH + CAIN TAC1,(SIXBIT /UFD/) ;IS IT "UFD" ? + CAME TAC,SYSPP ;YES, IS THIS SYS PPN? + JRST NOTUFD ;NO, ORDINARY FILE + LDB TAC,PDEVI ;YES, GET ITS INPUT CHANNEL + JUMPN TAC,.+4 ;MOVE ON IF ALREADY HAVE ONE + PUSHJ PDP,GTFCHN ;NO, GET ONE + JRST NOCHNE ;ERROR - NONE AVAILABLE + DPB TAC,PDEVI ;OK, STORE IT + MOVEI AC2,(TAC) ;GET CHAN. # INTO AC2 + PUSHJ PDP,SETENT ;SET UP .OPEN FOR OUTPUT ON FUNNY NAME + XCT TAC ;DO IT! + JRST DFERR6 ;SHOULDN'T HAPPEN, BUT FILE IS BEING WRITTEN NOW + MOVE TAC,DEVFIL(DEVDAT) ;GET SPECIFIED PPN + PUSHJ PDP,PPTOSN ;CONVERT TO SNAME + MOVEI TAC1,RDUFD ;SET UP ADR. FOR RFD + SETZM DEVCNT(DEVDAT) ;INITIALIZE LENGTH OF FILE + PUSHJ PDP,RFD ;START READING THE UFD AND WRITING + ;A 10/50 - LOOKING COPY FOR HIM TO READ + JRST DFERR7 ;NO SUCH UFD - PASS IT ON TO HIM + MOVE TAC1,DEVCNT(DEVDAT) ;GET # OF WORDS IN UFD. + ANDI TAC1,177 ;ISOLATE THE # LEFT TO BE WRITTEN OUT + MOVNI TAC1,(TAC1) ;NEGATE IT + MOVSI TAC1,(TAC1) ;PUT IN LH IN PREPARATION FOR .IOT + TLNE TAC1,777777 ;ARE THERE ANY WORDS LEFT TO BE WRITTEN? + PUSHJ PDP,RDUFD1 ;YES, DO SO + LDB TAC,PDEVI ;ALL FINISHED - GET CHAN. # + PUSHJ PDP,ITSCL1 ;AND CLOSE IT + LDB AC2,PDEVI ;GET CHAN. # AGAIN + PUSHJ PDP,SETENT ;AND SET UP TO READ WHAT WE JUST WROTE + TLZ AC1,ITSIOF ;WE WANT TO READ IT, REMEMBER! + XCT TAC ;OK, .OPEN IT FOR READING + JRST DFERR6 ;BULL SHIT! - BUT COP OUT BY SAYING + ;THAT FILE IS BEING WRITTEN + ;** DSKSER.MAC ** + +ENDUFD: PUSHJ PDP,GTDATE ;GET TODAY'S DATE AS ACCESS DATE + HRLI TAC,(SIXBIT /UFD/) ;AND PROPER EXT. + MOVEM TAC,FILNM1 ;STORE FOR RETURN TO USER + MOVEI TAC,10000 ;CAUSE VERY EARLY DATE AND TIME OF CREATION + MOVEM TAC,FILNM2 ;BECAUSE IT WOULD LOOK PRETTY SILLY + ;IF THE UFD WAS NEWER THAN SOME OF ITS FILES!! + MOVNS TAC,DEVCNT(DEVDAT) ;NEGATE SIZE + HRLZM TAC,FILNM3 ;AND STORE A COPY FOR USER + JRST LEXIS1 ;GIVE IT ALL TO HIM AND RETURN + + +RDUFD: MOVEI TAC1,2 ;INCREASE # OF WORDS IN UFD BY 2 + ADDB TAC1,DEVCNT(DEVDAT) ;AND GET A COPY OF RESULT + CAIE TAC1,200 ;DEFENSIVE!!! + ANDI TAC1,177 ;ISOLATE BLOCK RESIDUE + MOVE TAC,FILNAM ;STORE FILENAME AND EXT. IN BUFFER TO + MOVEM TAC,MONBUF-2(TAC1) ;BE OUTPUT WHEN FULL, AND + MOVE TAC,FILNM1 ;ALSO AT END IF NECESSARY + MOVEM TAC,MONBUF-1(TAC1) + TRNE TAC1,177 ;IS MONITOR BUFFER FULL OF UFD GOODS? + POPJ PDP, ;NO, BACK FOR MORE + MOVSI TAC1,-200 ;YES, SET UP TO OUTPUT FULL BLOCK +RDUFD1: HRRI TAC1,MONBUF ;PUT ADR. OF BUFFER INTO .IOT POINTER + LDB TAC,PDEVI ;GET CHAN. # + IORI TAC,<40_4>+ ;MAKE .IOT INSTRUCTION + ROT TAC,-13. ;POSITION IT + XCT TAC ;SEND THE BUFFER ( OR PART OF IT IF END ) + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** + +NOTUFD: MOVEI TAC1,LEXIST ;SET UP ADR. OF ROUTINE + PUSHJ PDP,RFD ;READ FILE DIRECTORY ( SNAME IN TAC ) +DFERR4: SKIPA TAC1,RHEQ1 ;NOT IN MFD (ERROR CODE = 1) +DFERR7: MOVEI TAC1,NOTINU ;FILE NOT IN UFD (ERROR CODE = 0) +DFER12: ;ZERO FILENAME SPECIFIED - TAC = 0 +DFERRY: PUSHJ PDP,GETWD1 ;GET E+1 + HRRI TAC,(TAC1) ;PUT ERROR CODE IN + JRST STOTAC ;STORE IT BACK + ;AND GIVE ERROR RETURN + +DFER10: SKIPA TAC1,RHEQ4 ;RENAME TO EXISTING NAME (ERROR CODE = 4) +DFER11: MOVEI TAC1,5 ;ATTEMPT TO RENAME WITHOUT PREVIOUS LOOKUP OR ENTER + JRST DFERRY + +LEXIST: MOVE TAC,FILNAM ;IS THIS THE FILE WE WANT? + HLLZ TAC1,FILNM1 + CAMN TAC,DEVFIL(DEVDAT) + CAME TAC1,DEVEXT(DEVDAT) +RHEQ1: POPJ PDP,1 ;NO, RETURN FOR ANOTHER + SUB PDP,[XWD RFDSTK RFDSTK] ;YES, FIX PDP + HLRZ TAC,FILNM3 ;GET FILE'S SIZE + MOVEM TAC,DEVCNT(DEVDAT) ;STORE IN DDB + LDB TAC,PDEVI ;GET ITS CHAN. # + JUMPN TAC,.+4 ;IF WE ALREADY HAVE ONE, MOVE ON + PUSHJ PDP,GTFCHN ;NO, GET ONE + JRST NOCHNE ;ERROR - NONE AVAILABLE + DPB TAC,PDEVI ;OK, STORE IN DDB + MOVSI TAC1,ITSIOF ;SET UP FOR INPUT + ANDCAM TAC1,ITSNAM(DEVDAT) + ROT TAC,-13. ;POSITION CHAN. # + IOR TAC,[.OPEN 0,ITSNAM(DEVDAT)] ;SET UP .OPEN INSTR. + MOVE AC1,DEVPPN(DEVDAT) ;GET THE SNAME WE WANT THE FILE FROM + CAME AC1,SNAME ;IS IT HIS OWN FILE WE WANT? + .SUSET [.SSNAME,,AC1] ;NO, SET CURRENT SNAME TO THIS ONE + ;TEMPORARILY - WE WILL CHANGE IT BACK + ;IN A JIFFY. + XCT TAC ;DO THE .OPEN + JRST LEXIS2 ;FAILURE, ASSUME FILE NOT FOUND - BUT + ;DON'T FORGET TO CHANGE SNAME BACK + ;IF NECESSARY + CAME AC1,SNAME ;OK, IF WE CHANGED THE SNAME, + .SUSET [.SSNAME,,SNAME] ;CHANGE IT BACK +LEXIS1: MOVE TAC,FILNM1 ;SEND THREE NEW WORDS TO USER + PUSHJ PDP,STOTC1 + MOVE TAC,FILNM2 + PUSHJ PDP,STOTC1 + MOVE TAC,FILNM3 + PUSHJ PDP,STOTC1 + JRST DFENT2 ;INITIALIZE SETCNT AND GIVE OK RETURN + +LEXIS2: CAME AC1,SNAME ;DID WE CHANGE THE SNAME? + .SUSET [.SSNAME,,SNAME] ;YES, CHANGE IT BACK + JRST DFERR7 ;NOW GIVE ERROR RETURN + ;** DSKSER.MAC ** RENAME UUO + +DFREN: PUSHJ PDP,DFRENX +RHEQ4: POPJ PDP,4 + JRST CPOPJ1 + +DFRENX: SKIPN DEVFIL(DEVDAT) ;IS THERE AN OLD FILE? + JRST DFER11 ;NO, UNDEFINED FILE ERROR + MOVE TAC,DEVPPN(DEVDAT) ;YES, GET THE UFD + CAME TAC,SNAME ;IS IT HIS? + JRST DFERR5 ;NO, PROTECTION FAILURE! + PUSHJ PDP,GETWDU ;GET SPECIFIED FILENAME + JUMPE TAC,DFREN7 ;TRYING TO DELETE IF ZERO + MOVE AC1,TAC ;NOT ZERO, SAVE IT IN AC1 + PUSHJ PDP,GETWD1 ;GET EXT. + HRR TAC,DEVEXT(DEVDAT) ;CAUSE RIGHT HALVES TO MATCH AND GET FUNNY. + CAMN AC1,DEVFIL(DEVDAT) ;SAME FILENAME? + CAME TAC,DEVEXT(DEVDAT) ;YES, SAME EXT? + JRST .+2 ;NO, SEE ABOUT RENAMING + JRST CPOPJ1 ;YES, GOOD RETURN BECAUSE ONLY TRYING + ;TO CHANGE PROTECTION + EXCH AC1,DEVFIL(DEVDAT) ;SWAP NAMES TEMPORARILY + EXCH TAC,DEVEXT(DEVDAT) + MOVEM AC1,FRENAM+1 ;STORE FOR POSSIBLE RENAME + MOVEM TAC,FRENAM+2 + PUSHJ PDP,FNDFIL ;SEE IF NEW FILE ALREADY EXISTS + JUMPN AC1,DFRNX3 ;SWAP NAMES BACK & GIVE ERROR IF IT DOES + TLNE DEVDAT,ENTRB ;OK, ARE WE WRITING? + JRST DFRNX4 ;NO, HANDLE DIFFERENTLY + PUSH PDP,DEVDAT ;SAVE DEVDAT + MOVEI DEVDAT,FRENAM+1-DEVFIL ;MAKE DEVDAT POINT TO OLD NAMES + PUSHJ PDP,FNDFIL ;FIND FILE + POP PDP,DEVDAT ;RESTORE DEVDAT + JUMPE AC1,DFRNX5 ;IF NOT THERE, HE MUST HAVE DELETED + ;IT ON ANOTHER CHANNEL. + MOVE TAC,DEVFIL(DEVDAT) ;GET NEW FILENAME + MOVE TAC1,DEVEXT(DEVDAT) ;AND EXT. + MOVEM TAC,FRENAM+3 ;STORE FOR RENAME + MOVEM TAC1,FRENAM+4 + .FDELE FRENAM ;CHANGE THE NAMES + JRST DFRNX3 ;ERROR, ASSUME NEW FILE SNUCK INTO EXISTENCE + HLLM TAC1,DREXT(AC1) ;OK, STORE NEW EXT. IN DIR. ENTRY + MOVE TAC,FRENAM+3 ;GET NEW NAME + MOVEM TAC,DRNAM(AC1) ;STORE IT IN DIR. ENTRY ALSO + AOS (PDP) ;CAUSE THERE TO BE SKIP RETURN + JRST DFCLSI ;FROM CLOSING INPUT + ;** DSKSER.MAC ** + +DFRNX5: SKIPA AC1,[DFERR7] ;LOAD ADR. OF ERROR +DFRNX3: MOVEI AC1,DFER10 ;LOAD ADR. OF ERROR + MOVE TAC,FRENAM+1 ;GET ORIGINAL NAME BACK + MOVEM TAC,DEVFIL(DEVDAT) + HLLZ TAC,FRENAM+2 ;EXT. ALSO + MOVEM TAC,DEVEXT(DEVDAT) + JRST (AC1) ;AND GIVE CORRECT ERROR RETURN +DFRNX4: AOS (PDP) ;CAUSE SUCCESSFUL RETURN + JRST DFCLSO ;FROM CLOSING OUTPUT + +DFREN7: PUSHJ PDP,DEL.IT ;DELETE THE FILE HE WAS READING OR WRITING + TLZ DEVDAT,LOOKB+ENTRB ;CLEAR FACT THAT HE WAS READING OR WRITING + ;SINCE HE JUST DELETED IT + AOBJN PDP,UINIT5 ;GIVE SUCCESSFUL RETURN + ;*** NOTE: THIS IS POTENTIALLY RISKY IF THIS OCCURS + ;WHEN WE ARE NEAR END OF STACK!!!***** + ;** DSKSER.MAC ** CLOSE UUO + +;CLOSE AN OUTPUT FILE + +DFCLSO: TLNN DEVDAT,ENTRB ;ENTER DONE YET? + POPJ PDP, ;NO, FORGET IT + LDB TAC,PIOMOD ;IS IT DUMP MODE? + CAIGE TAC,DR + TLNE DEVDAT,DSKRLB ;NO, IS RESET UUO IN PROGRESS? + JRST DFCL2 ;YES TO EITHER QUESTION + HLRZ TAC,DEVBUF(DEVDAT) ;NO, GET ADR. OF OUTPUT + ;BUFFER HEADER BLOCK + .UMOVE TAC1,(TAC) ;GET FIRST WORD - VIRGIN BUFFERS?? + ; TAC1 POINTS TO CURRENT BUFFER + JUMPLE TAC1,DFCL2 ;YES, DON'T OUTPUT + ADDI TAC,1 ;POINT TAC AT OUTPUT BYTE POINTER + ADDI TAC1,1 ;POINT TAC1 AT WORD COUNT OF BUFFER + ; THE WORD COUNT JUST PRECEDES DATA WORDS + .UMOVE AC1,(TAC) ;GET OUTPUT BYTE POINTER + MOVEI AC1,(AC1) ;ISOLATE RH + JUMPE AC1,.+2 ;DON'T CALCULATE WORD COUNT IF BYTE + ;POINTER NOT SET UP + SUBI AC1,(TAC1) ;CALCULATE # WORDS USER FILLED + TRNE IOS,IOWC ;IS USER KEEPING OWN COUNT? + .UMOVE AC1,(TAC1) ;YES, USE HIS COUNT INSTEAD + MOVEI AC1,(AC1) ;ISOLATE RH + JUMPE AC1,DFCL2 ;IF COUNT = 0, DON'T OUTPUT + ;0-WORD FINAL BLOCK + PUSHJ PDP,OUT ;GO WRITE LAST PARTIAL BLOCK + +DFCL2: TLZ DEVDAT,ENTRB ;TURN THIS OFF NOW + + ;CHECK FOR UPDATE MODE HERE ******** + + TLNE DEVDAT,DSKRLB ;IS RESET UUO IN PROGRESS? + JRST DFC16A ;YES + PUSHJ PDP,DEL.IT ;NO, DELETE FILE WITH THIS + ;NAME AND EXT. + HRRE TAC,DEVCNT(DEVDAT) ;GET SIZE OF FILE + MOVN TAC,TAC + HLLZ TAC,DEVEXT(DEVDAT) ;FORM COMPLETE SECOND NAME + MOVEM TAC,FOPRNM+4 ;STORE FOR .FDELE (RENAME) + MOVEM TAC,DEVEXT(DEVDAT) ;ALSO STORE IN DDB SO THAT A SEQUENCE OF + ; ENTER/CLOSE/RENAME WORKS. RENAME EXPECTS COMPLETE FILE NAME IN DEVFIL/ + ; DEVEXT. + LDB TAC,PDEVO ;GET CHANNEL # + MOVEM TAC,FOPRNM+2 + MOVE TAC,DEVFIL(DEVDAT) ;GET FIRST NAME + MOVEM TAC,FOPRNM+3 +DFCL2A: .FDELE FOPRNM ;DO A RENAME WHILE WRITING + JRST CLSFAL ;FAILURE - COINCIDENTAL, BUT HE MUST HAVE + ;SNUCK IN A FILE OF EXACTLY THE SAME NAME. + ;WE WILL DELETE IT AND TRY AGAIN, BECAUSE + ;WE ARE SUPPOSED TO SUPERCEDE + ;** DSKSER.MAC ** + + MOVEI AC1,1 ;OK, GET A CHUNK FOR NEW DIR. ENTRY + PUSHJ PDP,GTF + HRRE TAC,DEVCNT(DEVDAT) ;GET SIZE OF FILE + MOVN TAC,TAC + MOVSI TAC,(TAC) + HRR TAC,DIRLST ;AND LINK NEW CHUNK INTO CHAIN + HRRM AC1,DIRLST + MOVEM TAC,DRSIZ(AC1) + PUSHJ PDP,GTDATE ;GET TODAY'S DATE FOR ACCESS DATE + HLL TAC,DEVEXT(DEVDAT) ;ALSO EXT. + MOVEM TAC,DREXT(AC1) ;STORE IN DIR. ENTRY + MOVEM TAC,DRPROT(AC1) ;STORE AS CREATION DATE ALSO - + ;REST OF WORD GETS FILLED IN + ;CORRECTLY BELOW + PUSHJ PDP,GTTIME ;GET # JIFFIES PAST MIDNITE + IDIVI TAC,JIFMIN ;FORM # MINUTES + DPB TAC,[POINT 11,DRPROT(AC1),23,] ;STORE + LDB TAC,PIOMOD ;GET DATA MODE OF INIT + IORI TAC,_4 ;PUT IN STD. PROTECTION KEY + DPB TAC,[POINT 13,DRPROT(AC1),12,] ;STORE IN DIR. ENTRY + MOVE TAC,DEVFIL(DEVDAT) ;DON'T FORGET FILENAME + MOVEM TAC,DRNAM(AC1) +ITSCLO: LDB TAC,PDEVO ;GET CHAN. # +ITSCL1: ROT TAC,-13. ;POSITION IT + IOR TAC,[.CLOSE 0,] ;MAKE A .CLOSE INSTR. + XCT TAC ;DO IT! + POPJ PDP, ;RETURN + + +DFC16A: PUSHJ PDP,ITSCLO ;CLOSE THE OUTPUT CHANNEL + LDB AC2,PDEVO ;GET THAT CHANNEL # + PUSHJ PDP,MKFNNM ;MAKE "FUNNY NAME" OUT OF IT + MOVEM AC2,FRENAM+1 ;STORE NAME1 FOR DELETE + MOVEM AC3,FRENAM+2 ;NAME2 ALSO + SETZM FRENAM+3 ;CAUSE IT TO BE DELETED + .FDELE FRENAM ;DO SO. + POPJ PDP, ;RETURN ANYWAY + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** + +CLSFAL: MOVEM TAC,FRENAM+1 ;STORE NAME1 TO BE DELETED + MOVE TAC,FOPRNM+4 ;GET NAME2 FROM RENAME + MOVEM TAC,FRENAM+2 ;STORE FOR DELETE + .FDELE FRENAM ;DELETE IT + JFCL ;SO WHAT! + JRST DFCL2A ;TRY RENAME AGAIN + + +;HERE TO DELETE ALL FILES WHOSE NAME & EXT. MATCH +;THOSE IN DDB POINTED TO IN DEVDAT. + +FNDFIL: MOVEI AC1,DIRLST-FSIZ+1 ;INITIALIZE LOOP + MOVE TAC,DEVFIL(DEVDAT) ;GET NAME + HLRZ AC3,DEVEXT(DEVDAT) ;AND EXTENSION +FNDF.1: MOVEI AC2,(AC1) ;COPY POINTER + HRRZ AC1,DRSIZ(AC1) ;POINT TO NEXT ENTRY + JUMPE AC1,CPOPJ ;ZERO DENOTES END - RETURN + HLRZ TAC1,DREXT(AC1) ;GET EXT. + CAMN TAC,DRNAM(AC1) ;MATCH? + CAIE TAC1,(AC3) + JRST FNDF.1 ;NO, CONTINUE + POPJ PDP, ;YES, RETURN WITH AC1 POINTING TO DIR. ENTRY + ;AND TAC & TAC1 CONTAINING NAME AND EXT. +DEL.IT: PUSHJ PDP,FNDFIL ;FIND THE FILE + JUMPE AC1,CPOPJ ;NULL INDICATES NON-EXISTENT + MOVEM TAC,FRENAM+1 ;YES, STORE NAME1 FOR DELETE + HLRZ TAC,DRSIZ(AC1) ;GET SIZE + HRLZ TAC,TAC1 ;SET UP NAME2 + MOVEM TAC,FRENAM+2 ;STORE IT + HRRZ TAC,DRSIZ(AC1) ;GET ADR. OF NEXT ENTRY + HRRM TAC,DRSIZ(AC2) ;LINK PREVIOUS TO IT - I.E., UNLINK THIS ONE + SETZM FRENAM+3 ;CAUSE DELETION + MOVEI AC2,(AC1) + MOVEI AC1,1 + PUSHJ PDP,RTF + .FDELE FRENAM ;DELETE FILE + JFCL + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** CLOSE AN INPUT FILE + +;IF IT HAS BEEN BOTH "LOOKUP" AND "INPUT", THEN UPDATE THE +;ACCESS DATE. INITIALLY, BECAUSE WE DO .OPEN WHEN WE PERFORM +;THE LOOKUP, WE MUST UPDATE THE ACCESS DATE EVEN THOUGH NO +;INPUT WAS DONE. IF THE FILE BEING CLOSED IS IN OUR USER'S +;AREA, THEN UPDATE THE ACCESS DATE IN THE DIR. ENTRY. IF IT +;BELONGS TO ANOTHER USER, AND THAT USER'S UFD IS IN TOP 1K, +;ERASE THE FACT THAT WE HAVE IT UP THERE. ALTERNATIVELY, +;WE WOULD LIKE TO UPDATE THE ACCESS DATE IN THE UFD IN THE TOP 1K. + + +DFCLSI: TLZN DEVDAT,LOOKB ;ANY REASON TO BOTHER? + POPJ PDP, ;NO, RETURN + +DFCL21: +DFCL23: +; TLZN DEVDAT,INPB ;HAS AN INPUT BEEN DONE? +; POPJ PDP, ;NO, RETURN + MOVE TAC,DEVPPN(DEVDAT) ;YES, GET PPN OF THIS FILE + PUSHJ PDP,PPTOSN ;CONVERT TO SNAME + CAME TAC,SNAME ;IS IT THIS USER'S? + JRST DFCL30 ;NO, NOT IN GOOD FORM; FIX ANOTHER WAY. + PUSHJ PDP,FNDFIL ;YES, POINT TO DIR. ENTRY + JUMPE AC1,CPOPJ ;NOT THERE ANY LONGER, OH WELL..... + PUSHJ PDP,GTDATE ;GET TODAY'S DATE + DPB TAC,[POINT 12,DREXT(AC1),35,] ;STORE IN DIR. ENTRY + POPJ PDP, ;RETURN +DFCL30: HRRZ AC1,HLADR ;GET ADR. OF BEGIN OF UFD + JUMPE AC1,CPOPJ ;IF NONE, RETURN + MOVE TAC,UDNAME(AC1) ;GET THE OWNER'S SNAME + CAMN TAC,DEVPPN(DEVDAT) ;IS IT HIS FILE BEING CLOSED? + SETZM UDNAME(AC1) ;YES, ERASE THE FACT THAT HE IS IN. + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** RELEASE UUO + +DFREL: TLO DEVDAT,DSKRLB ;NOTE THAT RELEASE (VIA RESET UUO) + ;IS IN PROGRESS + PUSHJ PDP,DFCLSI ;CLOSE INPUT FIRST + PUSHJ PDP,DFCLSO ;THEN CLOSE OUTPUT + TLZ DEVDAT,DSKRLB ;CLEAR RELEASE MARKER + POPJ PDP, ;RETURN + ;** DSKSER.MAC ** INPUT UUO + +DFIN: TLNN DEVDAT,LOOKB ;FILE OPRN? + JRST DFERR2 ;NO, UNDEFINED FILE + +DFIN1: TLNE IOS,IOEND ;ANY MORE INPUT? + POPJ PDP, ;NO, LEAVE + HRRE AC1,DEVCNT(DEVDAT) ;GET SIZE OF FILE WE ARE READING + JUMPLE AC1,.+2 ;IF # OF BLOCKS, + LSH AC1,BLKP2 ;MAKE # OF WORDS + MOVM AC1,AC1 ;MAKE POS. # WORDS REGARDLESS + MOVE AC2,SETCNT(DEVDAT) ;GET BLOCK # TO READ NEXT + SUBI AC2,1 ;FORM MINIMUM # WORDS NEEDED IN FILE TO BE + LSH AC2,BLKP2 ;ABLE TO READ THIS BLOCK + SUB AC2,AC1 ;IF PAST END OF FILE, + JUMPGE AC2,DFIN1E ;SET END AND RETURN + CAMGE AC2,[-BLKSIZ] ;IS THIS THE LAST READ? + MOVNI AC2,BLKSIZ ;NO, ONLY READ A MAX. OF ONE DEC 10/50 BLOCK + HRLZI AC2,(AC2) ;SET UP POINTER WORD FOR .IOT + HRRI AC2,MONBUF+1 + LDB TAC1,PDEVI ;GET CHAN. # + IORI TAC1,<40_4>+ ;SET UP .IOT + ROT TAC1,-13. ;POSITION IT + PUSH PDP,AC2 ;SAVE .IOT POINTER WORD + XCT TAC1 ;DO IT! + POP PDP,TAC1 ;RESTORE PREVIOUS POINTER WORD + HLRE TAC1,TAC1 ;GET LH ( COUNT ) + HLRE AC2,AC2 ;GET POST FACTO COUNT + SUB AC2,TAC1 ;GET # WORDS TRANSFERRED IN + JUMPE AC2,DFIN1E ;END IF NOTHING READ + HRRZ TAC1,DEVIAD(DEVDAT) ;GET ADR. OF CURRENT BUFFER + .UMOVE AC1,1(TAC1) ;GET WORD WHICH HOLDS WORD COUNT + HRRI AC1,(AC2) ;PUT THIS WORD COUNT IN IT + MOVEM AC1,MONBUF ;STORE FOR TRANSFER INTO BUFFER + MOVEI TAC1,1(TAC1) ;POINT TO FIRST DATA WORD OF BUFFER + HRLI TAC1,MONBUF ;SET UP TO GIVE USER HIS BUFFER + ADDI AC1,(TAC1) ;POINT TO LAST LOC. IN BUFFER TO BE FILLED + .UBLTO TAC1,(AC1) ;OFF IT GOES! + AOS SETCNT(DEVDAT) ;NEXT BLOCK # + CAIE AC2,BLKSIZ ;DID WE JUST READ A FULL 10/50 BLOCK? + PUSHJ PDP,DFIN1E ;NO, SET END + PUSHJ PDP,ADVBFF ;YES, ANY MORE EMPTY BUFFERS? + POPJ PDP, ;NO, RETURN + JRST DFIN1 ;YES, SEE ABOUT FILLING ANOTHER WHILE WE ARE HERE +DFIN1E: TLO IOS,IOEND ;SET END + MOVEM IOS,DEVIOS(DEVDAT) + POPJ PDP, ;RETURN +DFERR2: MOVEI IOS,IOIMPM + IORB IOS,DEVIOS(DEVDAT) + POPJ PDP, + ;** DSKSER.MAC ** OUTPUT UUO + +DFOUT: TLNN DEVDAT,ENTRB ;FILE OPEN? + JRST DFERR2 ;NO, UNDEFINED FILE +DFOUT1: HRLZ TAC1,DEVOAD(DEVDAT) ;GET ADR. OF BUFFER IN USER AREA + HRRI TAC1,MONBUF+1 ;SET UP DESTINATION ( +1 WHICH GOES AWAY BELOW ) + ADDI TAC1,777777 ;DECREASE RH BY 1 AND INCREASE LH BY 1 + .UBLTI TAC1,MONBUF+BLKSIZ ;GET THE ENTIRE BUFFER + HRRZ TAC1,MONBUF ;GET WORD COUNT + PUSHJ PDP,UPDEVC ;UPDATE DEVCNT + AOS SETCNT(DEVDAT) ;INCREMENT BLOCK # + MOVE TAC1,[XWD -200 MONBUF+1] ;SET UP .IOT + LDB TAC,PDEVO ;GET OUTPUT CHAN. # + IORI TAC,<40_4>+ + ROT TAC,-13. ;POSITION THE .IOT INSTRUCTION + XCT TAC ;DO IT! + PUSHJ PDP,ADVBFE ;ANY MORE OUTPUT TO DO? + POPJ PDP, ;NO, RETURN + JRST DFOUT1 ;YES, DO ANOTHER BUFFER + ;** DSKSER.MAC ** + +;CLEAR OUT DDB AT RELEASE TIME +; COULD BE A TTY DDB OR A DSK DDB (SIZE IS INCLUDED IN LH OF DEVCHR) + +CLRDDB: MOVEI AC2,DSKDDB ;POINT TO PROTOTYPE +CLDDB1: MOVEI AC1,(AC2) ;MAKE COPY OF POINTER + HLRZ AC2,DEVSER(AC1) ;GET LINK TO NEXT DDB + JUMPE AC2,CPOPJ ;0 MEANS END + CAIE AC2,(DEVDAT) ;IS THIS THE ONE? + JRST CLDDB1 ;NO, TRY NEXT + MOVE TAC,DEVSER(AC2) ;YES, GET LINK OF NEXT DDB + HLLM TAC,DEVSER(AC1) ;STORE IN PREVIOUS + HLRZ AC1,DEVCHR(DEVDAT) ;SET UP # CHUNKS TO RETURN + JRST RTF ;RETURN THEM AND RETURN + +;BUILD A DSK DDB + +SETDDB: PUSH PDP,TAC ;SAVE THIS AC + MOVE TAC,DEVMOD(DEVDAT) + TRNE TAC,ASSPRG ;HAS INIT BEEN DONE YET? + JRST SETDD0 ;YES, COPY PROTOTYPE + MOVEI TAC,(DEVDAT) ;NO, GET ADR. OF DDB + CAIE TAC,DSKDDB ;IS IT PROTOTYPE? + JRST TPOPJ ;NO, THEN WE ALREADY HAVE A COPY OF IT - RETURN +SETDD0: MOVEI AC1,DSKCOR ;GET FREE CORE FOR DSK DDB + PUSHJ PDP,GTF + HRRI DEVDAT,(AC1) ;POINT DEVDAT AT NEW CORE (DDB) + HRLI AC1,DSKDDB ;XWD SOURCE DESTINATION + BLT AC1,DSLEN-1(DEVDAT) ;COPY PROTOTYPE UNTIL THAT POINT WHERE + ; REST OF DDB IS ZERO + SETZM DSLEN(DEVDAT) ;THEN ZERO THE REST + HRLZI AC1,DSLEN(DEVDAT) + HRRI AC1,DSLEN+1(DEVDAT) + BLT AC1,PTR1-1(DEVDAT) + HRLM DEVDAT,DEVSER+DSKDDB ;LINK IN NEW DDB + JRST TPOPJ ;RESTORE TAC AND RETURN + ;** DSKSER.MAC ** + +;UPDATE DEVCNT IF NECESSARY. +;DEVCNT HAS SIZE OF FILE IN RH ( IN WORDS IF POSITIVE, BLOCK +;COUNT IF NEGATIVE) + +;ENTER WITH SIZE OF CURRENT BLOCK IN TAC1 + +UPDEVC: HRRZ TAC,SETCNT(DEVDAT) ;CONVERT CURRENT RELATIVE + SUBI TAC,1 ;BLOCK # TO WORDS + LSH TAC,BLKP2 + ADD TAC,TAC1 ;ADD IN THESE ADDITIONAL WORDS + HRRZ TAC1,DEVCNT(DEVDAT) ;PICK UP PREVIOUS MAXIMUM + TRNE TAC1,400000 ;FILE SIZE FOR COMPARISON + JRST UPDVC2 ;IF > 2**17, COMPARE NEG. BLOCK COUNTS + TLNN TAC,-1 ;NO, IS NEW SIZE > 2**17 WORDS? + TRNE TAC,400000 + JRST UPDVC1 ;YES, SAVE NEG. BLOCK COUNT + CAILE TAC,(TAC1) ;NO, COMPARE POSITIVE WORD COUNTS + HRRM TAC,DEVCNT(DEVDAT) ;UPDATE MAX. FILE SIZE ONLY + ;IF PREVIOUS MAX. EXCEEDED + POPJ PDP, ;AND RETURN +UPDVC1: IORI TAC1,-1 ;SET PREV. MAX. AS ONLY ONE BLOCK + ;(FORCING CURRENT BLOCK COUNT TO BE STORED) +UPDVC2: ADDI TAC,BLKSIZ-1 ;CONVERT POS. WORD COUNT + LSH TAC,-BLKP2 ;TO NEG. BLOCK COUNT + MOVN TAC,TAC + TRON TAC,400000 ;MORE THAN 2**17 BLOCKS IN FILE NOW? + TROA IOS,IOBKTL ;YES, ABSURDITY!! STORE BLOCK COUNT MOD 2**17 + CAILE TAC1,(TAC) ;NO, COMPARE PREVIOUS MAX. WITH PRESENT SIZE + HRRM TAC,DEVCNT(DEVDAT) ;STORE NEW MAX. FILE SIZE ONLY IF + ;PREV. MAX. EXCEEDED + POPJ PDP, ;RETURN + ;** UUOCON.MAC ** + +;ENTER WITH # OF CONTIGUOUS "FSIZ"-WORD CHUNKS DESIRED IN AC1. +;RETURN WITH ADR. OF FIRST WORD OF BLOCK IN AC1. +;AC'S AC1, AC2, AND AC3 ARE USED AND CLOBBERED + +GTF: PUSH PDP,AC1 ;SAVE # DESIRED +GTF0: MOVEI AC2,FREEPT-FSIZ+1 ;SAVE INITIAL POINTER + PUSH PDP,AC2 + HRRZ AC3,FREEPT ;GET ADR. OF FIRST CHUNK +GTF1: JUMPE AC3,GTFAIL ;IF END, NOT ENUF! + MOVEM AC2,(PDP) ;SAVE PTR. TO FIRST CHUNK + MOVE AC1,-1(PDP) ;GET # DESIRED + MOVEI AC2,(AC3) ;COPY ADR. OF CURRENT CHUNK +GTF2: SOJLE AC1,GTWIN ;FOUND ENOUGH? - YES! + HRRZ AC3,FSIZ-1(AC2) ;NO, GET NEXT + CAIE AC3,FSIZ(AC2) ;CONTIGUOUS? + JRST GTF1 ;NO, MOVE ON + MOVEI AC2,(AC3) ;YES, MAKE IT LAST SO FAR + JRST GTF2 ;AND CONTINUE + +GTWIN: POP PDP,AC2 ;GET PTR. TO FIRST CHUNK + HRRZ AC1,FSIZ-1(AC2) ;PUT ADR. OF FIRST CHUNK INTO T + MOVE AC3,(PDP) ;REDUCE FRENUM BY AMT. WE ARE GIVING HIM + SUB AC3,FRENUM + MOVNM AC3,FRENUM + POP PDP,AC3 ;GET # CHUNKS WE ARE GIVING HIM + IMULI AC3,FSIZ ;FORM # OF WORDS BEING RETURNED + ADDI AC3,-1(AC1) ;FORM ADR. OF LAST WORD OF BLOCK + HRRZ AC3,(AC3) ;UNLINK THIS BLOCK + HRRM AC3,FSIZ-1(AC2) + POPJ PDP, ;RETURN TO USER WITH ADR. OF BLK IN T. + ;HERE WHEN NOT ENOUGH CONTIGUOUS CHUNKS. +;IF # DESIRED IS AVAILABLE BUT NOT CONTIGUOUS AT THE MOMENAC1, "GCOL" +;IS CALLED TO COMPACTIFY. +;IF NOT, "ADD1K" IS CALLED TO APPEND ONE MORE K OF CORE ABOVE +;CURRENT TOP OF FREE CORE. + +GTFAIL: MOVE AC1,-1(PDP) ;PICK UP # HE WANTS + CAMLE AC1,FRENUM ;IS IT WORTHWHILE TO COMPACTIFY? + JRST GTFAL1 ;NO, JUST GET ANOTHER K OF CORE + PUSHJ PDP,GCOL ;YES, DO SO +GTFAL0: POP PDP,AC1 ;NOW, TRY FOR THE DESIRED # + JRST GTF0 + +GTFAL1: PUSHJ PDP,ADD1K ;GET 1K MORE FOR FREE CORE AREA + JRST GTFAL0 ;RETURN FOR ANOTHER TRY + + +;CALL HERE TO GET 1 MORE K OF CORE FOR FREE CORE AREA. +;IF A UFD OCCUPIES TOP K, IT IS MOVED UP. THE ADDITIONAL +;K OF CORE IS ADDED TO THE FREE LIST. +;AC'S AC1, AC2, AND AC3 ARE CLOBBERED. + +ADD1K: MOVS AC1,HLADR ;GET ADR. OF TOP OF FREE CORE + HRRI AC1,4000(AC1) ;MAKE IT 1 MORE + TLZE AC1,777777 ;IS THERE A UFD? + MOVEI AC1,2000(AC1) ;YES, ACCOUNT FOR IT + LSH AC1,-10. ;FORM # K WE WANT + .CORE (AC1) ;GET IT! + JRST SYSERR ;*** COULDN'T GET ANOTHER K!! *** + HRRZ AC1,HLADR ;GET ADR. OF UFD. + JUMPE AC1,ADD1K1 ;NO UFD, MOVE ON + HRLI AC1,(AC1) ;PREPARE TO MOVE UFD TO NEW K + ADDI AC1,2000 ;FORM NEW BEGIN ADR. FOR UFD + HRRM AC1,HLADR ;STORE IT + MOVEI AC2,1777(AC1) ;SET UP FINAL "TO ADR." + BLT AC1,(AC2) ;MOVE THE UFD UP! +ADD1K1: HLRZ AC3,HLADR ;GET OLD TOP OF FREE CORE + MOVEI AC1,2000(AC3) ;FORM MAX. OF NEW TOP + IORI AC1,1777 + SUBI AC1,(AC3) ;FORM # WORDS AVAILABLE FOR FREE CHUNKS + IDIVI AC1,FSIZ ;FORM # CHUNKS + MOVEI AC2,FSIZ ;FORM NEW TOP OF FREE CORE + IMULI AC2,(AC1) + ADDI AC2,(AC3) + HRLM AC2,HLADR ;STORE IT + MOVEI AC2,1(AC3) ;SET UP ADR. OF FIRST NEW CHUNK + JRST RTF0 ;PLACE NEW CHUNKS AT END OF LIST + ;AND RETURN + ;CALL HERE TO RETURN # OF CONTIGUOUS FREE CHUNKS IN AC1 STARTING AT ADR. +;IN AC2. +;ATTEMPT WILL BE MADE TO GIVE 1K BACK TO ITS IF POSSIBLE. ALL EXCEPT +;"GCOL" SHOULD CALL HERE. ( "GCOL" CALLS RTF0. ) + +RTF: PUSHJ PDP,RTF0 ;RETURN THE CHUNKS + MOVE AC2,FRENUM ;GET TOTAL # FREE CHUNKS + CAIG AC2,2000/FSIZ+MINFRE;CAN WE AFFORD TO + ;GIVE 1K BACK TO ITS ? + POPJ PDP, ;NO, RETURN + PUSH PDP,AC1 ;YES, SAVE # CHUNKS JUST RETURNED + PUSHJ PDP,GCOL ;GARBAGE COLLECT SO THAT FREE CHUNKS + ;WILL FLOAT TO TOP + SUBI AC1,2000/FSIZ ;REDUCE # FREE CHUNKS + MOVEM AC1,FRENUM + MOVS AC1,HLADR ;GET HIGH ADR. INTO RH + SUBI AC1,2000 ;REDUCE BY 1K + IORI AC1,1777 + MOVEI AC2,1(AC1) ;REDUCE TO ACCOUNT FOR FSIZ OFFSET + SUB AC2,FREEPT + IDIVI AC2,FSIZ + SUBI AC1,(AC3) + HRLM AC1,HLADR ;AND STORE NEW VALUE + TLNN AC1,777777 ;IS THERE A UFD IN CORE NOW? + JRST RTF9 ;NO, MOVE ON + HLRZ AC2,AC1 ;YES, MOVE IT DOWN 1K + HRLI AC2,-2000(AC2) + HLRM AC2,HLADR ;FIX PTR. TO UFD + MOVEI AC1,-1(AC2) + MOVS AC2,AC2 + BLT AC2,(AC1) +RTF9: ADDI AC1,2000 ;GIVE BACK 1K NOW + LSH AC1,-10. + .CORE (AC1) + JRST SYSERR ;NOT SUPPOSED TO BE UNGRATEFUL!! + POP PDP,AC1 ;RESTORE AC1. + POPJ PDP, ;AND RETURN + ;ENTER WITH # OF CHUNKS TO RETURN IN AC1, AND ADR. OF FIRST CHUNK IN AC2. +;RETURNS WITH # CHUNKS RETURNED STILL IN AC1, BUT AC2 IS CLOBBERED. +; *** AC1 MUST BE GREATER THAN 0!! *** + +RTF0: PUSH PDP,AC1 ;SAVE # CHUNKS BEING RETURNED + PUSH PDP,AC1 ;SAVE ANOTHER COPY FOR COUNTER + PUSH PDP,AC2 ;SAVE ADR. OF BLOCK + MOVEI AC2,FREEPT-FSIZ+1 ;GET ADR. OF FIRST PTR. +RTF1: MOVEI AC1,(AC2) ;COPY ADR. OF PTR. + HRRZ AC2,FSIZ-1(AC1) ;GET ADR. NEXT CHUNK + CAMG AC2,(PDP) ;GREATER THAN BLOCK BEING RETURNED? + JUMPN AC2,RTF1 ;NO, BUT IS IT END? - NO, CONTINUE + EXCH AC2,(PDP) ;YES, GET ADR. OF BLOCK AND SAVE CURRENT + HRRM AC2,FSIZ-1(AC1) ;NEXT CHUNK. LINK BLOCK INTO CHAIN +RTF2: SOSG -1(PDP) ;ANY CHUNKS LEFT TO RETURN? + JRST RTF3 ;NO, FINISH UP + ADDI AC2,FSIZ ;YES, GIVE ANOTHER CHUNK + HRRM AC2,-1(AC2) ;BACK CONTIGUOUSLY + JRST RTF2 ;CONTINUE +RTF3: POP PDP,AC1 ;GET ADR. OF NEXT CHUNK + HRRM AC1,FSIZ-1(AC2) ;LINK IT IN + POP PDP,AC1 ;RESTORE STACK + POP PDP,AC1 ;RESTORE # CHUNKS RETURNED + ADDM AC1,FRENUM ;ADD TO TOTAL # FREE CHUNKS + POPJ PDP, ;RETURN + ;CALL HERE TO COMPACTIFY ALL CHUNKS IN USE AND CAUSE ALL FREE CHUNKS +;TO FLOAT TO TOP OF FREE CORE AREA. AC'S AC1, AC2, AND AC3 ARE CLOBBERED. + +GCOL: HLRZ AC1,HLADR ;GET ADR. OF TOP OF FREE CORE AREA + PUSH PDP,AC1 ;AND SAVE +GCOL0: HRRZ AC1,FREEPT ;GET FIRST FREE CHUNK ADR. + JUMPE AC1,GCOL7 ;IF END, FINISH UP +GCOL1: MOVEI AC2,(AC1) ;PUT ADR. INTO AC2. + HRRZ AC1,FSIZ-1(AC2) ;GET ADR. OF NEXT CHUNK + CAIN AC1,FSIZ(AC2) ;CONTIGUOUS? + JRST GCOL1 ;YES, CONTINUE + ;NO, MAKE THIS CHUNK THE FIRST FREE AND + EXCH AC1,FREEPT ;GET ADR. OF CURRENT "FIRST FREE" + HRL AC1,AC1 ;GET COPY OF THE ADR. INTO LH, ALSO + SUBI AC2,-FSIZ(AC1) ;FORM # CONTIGUOUS FREE WORDS + PUSH PDP,AC2 ;SAVE THIS # + MOVEI AC3,DEVLST-DEVSER ;SET UP PTR. TO FIRST DDB PTR. +GCOL2: MOVEI AC2,(AC3) ;PUT ADR. INTO AC2. + HLRZ AC3,DEVSER(AC2) ;GET ADR. OF NEXT DDB. + JUMPE AC3,GCOL21 ;IF END, MOVE ON + CAIG AC3,(AC1) ;IS THIS DDB ABOVE LOWEST FREE CORE? + JRST GCOL2 ;NO + SUB AC3,(PDP) ;YES, CORRECT PTR. TO WHERE DDB WILL BE + HRLM AC3,DEVSER(AC2) + ADD AC3,(PDP) ;NOW RESET THE DDB PTR. + JRST GCOL2 ;CONTINUE +GCOL21: MOVEI AC2,FREEPT-FSIZ+1 ;SET UP PTR. TO FREE CORE PTR. +GCOL3: HRRZ AC3,FSIZ-1(AC2) ;GET ADR. OF NEXT FREE CHUNK + JUMPE AC3,GCOL4 ;IF END, MOVE ON + SUB AC3,(PDP) ;CORRECT PTR. TO ACCOUNT FOR SHUFFLE + HRRM AC3,FSIZ-1(AC2) + ADD AC3,(PDP) + MOVEI AC2,(AC3) ;PUT PTR. INTO AC2. + JRST GCOL3 ;AND CONTINUE +GCOL4: MOVEI AC3,DIRLST-FSIZ+1 ;GET PTR. TO FIRST DIRECTORY + ;ENTRY PTR. +GCOL5: MOVEI AC2,(AC3) ;COPY PTR. INTO AC2 + HRRZ AC3,FSIZ-1(AC2) ;GET ADR. OF NEXT DIR. ENTRY + JUMPE AC3,GCOL6 ;IF END, MOVE ON + CAIG AC3,(AC1) ;WILL THIS ENTRY BE MOVED? + JRST GCOL5 ;NO + SUB AC3,(PDP) ;YES, CORRECT THE PTR. + HRRM AC3,FSIZ-1(AC2) + ADD AC3,(PDP) + JRST GCOL5 ;CONTINUE +GCOL6: POP PDP,AC2 ;GET # OF CONTIGUOUS WORDS + ADDI AC1,(AC2) ;SET UP TO TRANSFER DOWN + MOVS AC1,AC1 + EXCH AC2,(PDP) ;UPDATE ADR. OF TOP OF FREE CORE + SUBB AC2,(PDP) ;AND USE AS LAST "TO ADR." IN BLT + BLT AC1,(AC2) ;MOVE SOME CORE DOWN + JRST GCOL0 ;DO FOR NEXT CONTIGUOUS CHUNKS +GCOL7: EXCH AC1,FRENUM ;GET # FREE CHUNKS AND ZERO IN + ;PREPARATION FOR CALL TO "RTF0". + POP PDP,AC2 ;GET ADR. OF FIRST CHUNK TO BE RETURNED + JRST RTF0 ;GIVE BACK THE FREE CHUNKS WHICH ARE NOW + ;CONTIGUOUS AND JUST BELOW THE UFD + ;(IF ANY) + ;HERE TO DO AN EXEC UUO + +DOXUUO: ADDI UCHN,1 ;INCREMENT RETURN ADR. PAST UUO + TLZ UCHN,USRMOD ;BE SURE USER MODE IS OFF + MOVEM UCHN,UUO0 ;STORE PC IN UUO0 + MOVE UUO,@-1(UCHN) ;GET THE UUO ITSELF + HRRZS USRPD1 ;BE SURE USER MODE BIT IS OFF IN USRPD1!! + JRST UUOSY1 ;GO DO THE EXEC UUO + +;HERE ON UUO FROM USER + +UUOUSR: MOVE UUO,FORTY ;GET THE UUO + MOVE PDP,UPDP ;INIT THE PUSH-DOWN POINTER +UUOSY1: PUSH PDP,UUO0 ;SAVE RETURN ADR. ON STACK + TLNN UUO,740000 ;GREATER THAN 40? +ILEGAL: JRST UUOERR ;NO, 0-37 ILLEGAL! + HLRZ TAC1,UUO ; FETCH THE INSTRUCTION + CAIN TAC1,(PORTAL) ; WAS IT A PORTAL? + JRST [HRRM UUO,(PDP) ; YES, FAKE DOING A JRST + JRST USRXIT] ; AND DISMISS THE "uUO" + LDB TAC1,[POINT 9,UUO,8,] ;GET UUO OP CODE + CAIL TAC1,100 ;GREATER OR EQUAL TO 100 ? + JRST ILLINS ;YES, BAD INSTRUCTION + LDB UCHN,PUUOAC ;GET AC FIELD + SKIPE DEVDAT,USRJDA(UCHN) ;ADR. OF DDB. + CAMLE UCHN,USRHCU ;IS CHAN. LESS OR EQUAL TO HIGHEST USED? + JRST NOCHAN ;CHANNEL NOT ASSIGNED - CHECK IT OUT + MOVE IOS,DEVIOS(DEVDAT) ;GET DDB STATUS + MOVE DSER,DEVSER(DEVDAT) ;AND ADR. OF I/O SERVICE DISP. + CAIL TAC1,LNGUUO ;IS THIS LONG DISP. TABLE UUO ? + JRST DISP1 ;YES +DISP0: ROT TAC1,-1 ;NO, GET DISPATCH TABLE ENTRY + MOVE DAT,UUOTAB-20(TAC1) +DISP2: JUMPL TAC1,.+2 ;ODD USES RH + MOVS DAT,DAT ;EVEN USES LH + HLL DAT,(PDP) ;PICK UP FLAGS OF PC ON STACK + TLNN DAT,USRMOD ;IS IT UUO FROM EXEC? + JRST (DAT) ;YES, RETURN ADR. IS ALREADY THERE. + PUSHJ PDP,(DAT) ;NO, DO THE UUO FOR THE USER + JRST .+2 ;NON-SKIP RETURN TO USER +USRXT1: AOS (PDP) ;SKIP RETURN TO USER +USRXIT: SKIPL JBTSTS ;HAS A "CALLI 1,12" OR A "HALT" + ;BEEN EXECUTED? OR, HAS A PRE-STORED + ;^C BEEN FOUND? + PUSHJ PDP,USCHED ;YES, WAIT UNTIL USER CONTINUES + ;OR DOES SOMETHING ELSE. + POP PDP,UUO0 ;GET USER RETURN ADR. + .USET UPRGO,[.SUPC,,UUO0] ;SET UP THE INFERIOR'S PC + .USET UPRGO,[.SUSTP,,[0]] ;AND ALLOW HIM TO RUN AGAIN + JRST URETRN ;AND RETURN + + NOCHAN: CAIGE TAC1,IOUUO ;IS THIS AN I/O UUO ? + JRST DISP0 ;NO, GO DISPATCH + CAIE TAC1,70 ;YES, BUT "CLOSE" AND + CAIN TAC1,71 ;"RELEASE" ARE ALWAYS LEGAL + JRST USRXIT + JRST IOIERR ;OTHERS ARE ILLEGAL - PRINT + ;"I/O TO UNASSIGNED CHANNEL" + +DISP1: MOVE TAC,DEVMOD(DEVDAT) ;DOES THIS DEVICE + TLNE TAC,DVLNG ;HAVE A LONG DISPATCH TABLE? + JRST DISP0 ;YES, DISPATCH + CAIGE TAC1,76 ;NO, IS IT "LOOKUP" OR "ENTER" ? + JRST USRXIT ;NO, NON-SKIP RETURN TO USER + JRST USRXT1 ;YES, SKIP RETURN TO USER + ;TABLE OF UUO DISPATCH ADDRESSES +;IN FORMAT: +; +; XWD 40,41 +; XWD 42,43 +; . +; . +; XWD 76,77 + + +UUOTAB: XWD UCALL UINIT ;(40,41) CALL,INIT + XWD UUOERR UUOERR ;(42,43) FOR FUTURE EXPANSION + XWD UUOERR UUOERR ;(44,45) " + XWD UUOERR UCALLI ;(46,47) CALLI + XWD UOPEN TTYUUO ;(50,51) OPEN,TTCALL + XWD ILEGAL ILEGAL ;(52,53) FOR DEC EXPANSION + XWD ILEGAL URENAM ;(54,55) RENAME +IOUUO==55 ;LOWEST I/O UUO (RENAME) + XWD TIN TOUT ;(56,57) IN,OUT + XWD SETIOS USTATO ;(60,61) SETSTS,STATO + XWD USTATS USTATZ ;(62,63) GETSTS,STATZ + XWD UINBF UOUTBF ;(64,65) INBUF,OUTBUF + XWD IN UOUT ;(66,67) INPUT,OUTPUT + XWD CLOSE1 RELEA1 ;(70,71) CLOSE,RELEASE +LNGUUO==72 ;LOWEST LONG DISPATCH TABLE UUO + XWD CPOPJ CPOPJ ;(72,73) MTAPE,GETF + XWD UDSI UDSO ;(74,75) USETI,USETO + XWD UDLK UDEN ;(76,77) LOOKUP,ENTER + ;CALL UUO DISPATCH TABLE +;NEW UUO'S MUST BE ADDED AT THE END SINCE CALLI DEPENDS ON +;POSITION IN TABLE. + +DEFINE CNAMES + X LIGHTS,LIGHTS ;( -1 ) DISPLAY AC ON CONSOLE SWITCHES +TERMIN + +DEFINE NAMES + X RESET,RESET ;( 0 ) RESET I/O + X DDTIN,DDTIN ;( 1 ) GET DDT CHAR. + X SETDDT,SETDDT ;( 2 ) SET DDT LOC. IN PROTECTED AREA + X DDTOUT,DDTOUT ;( 3 ) SEND DDT CHAR. + X DEVCHR,DVCHR ;( 4 ) DEVICE CHARACTERISTICS + X DDTGT,CPOPJ ;( 5 ) GET DDT MODE ** NO-OP ** + X GETCHR,DVCHR ;( 6 ) DEVICE CHARACTERISTICS *SAME AS 4* + X DDTRL,CPOPJ ;( 7 ) RELEASE DDT MODE ** NO-OP ** + X WAIT,CPOPJ ;( 10 ) WAIT TILL DEVICE INACTIVE + X CORE,CORUUO ;( 11 ) CORE UUO + X EXIT,EXIT ;( 12 ) EXIT + X UTPCLR,CPOPJ ;( 13 ) CLEAR DECTAPE DIR. ** NO-OP ** + X DATE,DATE ;( 14 ) GET DATE + X LOGIN,ULOGIN ;( 15 ) LOGIN + X APRENB,APRENB ;( 16 ) ENABLE APR FOR TRAPPING + X LOGOUT,LOGOUT ;( 17 ) LOGOUT + X SWITCH,SWITCH ;( 20 ) READ DATA SWITCHES + X REASSIGN,REASSIGN ;( 21 ) REASSIGN DEVICE TO ANOTHER JOB ** NO-OP ** + X TIMER,TIMER ;( 22 ) RETURN JIFFY CLOCK TIME + X MSTIME,MSTIME ;( 23 ) RETURN MILLISEC. CLOCK TIME + X GETPPN,GETPPN ;( 24 ) RETURN PROJ.-PROG. # + X TRPSET,CPOPJ ;( 25 ) SET PI TRAP ** ERROR ** + X TRPJEN,UUOERR ;( 26 ) DISMISS TO EXEC. ** ERROR ** + X RUNTIM,JOBTIM ;( 27 ) RETURN TOTAL JOB RUNNING TIME + X PJOB,JOBNO ;( 30 ) RETURN JOB # + X SLEEP,SLEEP ;( 31 ) SLEEP FOR N SECONDS + X SETPOV,SETPOV ;( 32 ) SET PUSHDOWN OVERFLOW TRAP + X PEEK,CPOPJ ;( 33 ) ALWAYS ERROR RETURN + X GETLIN,GETLN ;( 34 ) GET TTY LINE # + X RUN,URUN ;( 35 ) RUN DEV:FILE + X SETUWP,SETUWP ;( 36 ) SET OR CLEAR USER MODE WRITE PROTECT + X REMAP,REMAP ;( 37 ) REMAP TOP OF LOW SEG. INTO HIGH SEG. + X GETSEG,UGTSEG ;( 40 ) GET HIGH SEGMENT + X GETTAB,GETTAB ;( 41 ) GET CONTENTS OF A MONITOR TABLE ENTRY + X SPY,CPOPJ ;( 42 ) SPY ** ERROR ** + X SETNAM,SETNAM ;( 43 ) SET NAME OF THIS PROGRAM + X UUOERR,UUOERR ;( 44 ) ILLEGAL UUO +TERMIN + ;GENERATE SIXBIT TABLE OF UUO NAMES + +DEFINE X A,B + SIXBIT /A/ +TERMIN + +;GENERATE D.E.C. TABLE + +UCLTAB: NAMES +UCLLEN==.-UCLTAB + +;GENERATE DISPATCH TABLES + +DEFINE X A,B + ZZ==ZZ+1 +TERMIN + +DEFINE XX C + UUOERR,,C +TERMIN + +ZZ==0 +;COUNT # OF CUSTOMER DEFINED CALL'S + CNAMES + +CCLLEN==:ZZ + +DEFINE X A,B + IFE ZZ&1,[ + DEFINE XX C + B,,C + TERMIN + ] + IFN ZZ&1,XX B + ZZ==ZZ+1 +TERMIN + +;GENERATE CUSTOMER TABLE + +CUSTAB: CNAMES + +ZZ==0 +;GENERATE D.E.C. TABLE + +UCLJMP: NAMES + +IFN ZZ&1,XX 0 ;GEN. LAST WORD IF ODD # + ; CALL D,[SIXBIT /NAME/] +;WHERE NAME IS THE NAME OF A SYSTEM ROUTINE. +;IF NO SYSTEM ROUTINE WITH THE SPECIFIED NAME IS FOUND, +;THIS ROUTINE EXITS TO UUOERR. +; +;CONTENTS OF USER AC PLACED IN TAC, UUO SET TO POINT +;TO USER AC, ITEM SET TO JOB # ( 0 ) + +UCALL: PUSHJ PDP,GETWDU ;SET TAC FROM CONTENTS OF EFFECTIVE + ;ADDRESS OF UUO FROM EITHER HIGH OR LOW SEG + MOVSI TAC1,-UCLLEN + CAME TAC,UCLTAB(TAC1) ;SEARCH SYSTEM ROUTINE NAME TABLE + AOBJN TAC1,.-1 + JUMPG TAC1,UUOERR ;ERROR IF NOT FOUND + HRRI UUO,(TAC1) ;STORE INDEX IN UUO, JUST AS IF USER HAD + ;DONE CALLI UUO + +;CALLI UUO - CALL IMMEDIATE +; +; CALLI D,E +; WHERE E IS RELATIVE INDEX IN CALL TABLE + +UCALLI: HRRE TAC1,UUO ;GET CALLI # ( POS. = D.E.C., NEG. = CUST. ) + CAML TAC1,[-CCLLEN] ;MORE NEG. THAN CUST. ? + CAIL TAC1,UCLLEN ;OR MORE POS. THAN D.E.C. ? + POPJ PDP, ;YES, RETURN TO TREAT AS NO-OP + MOVE UUO,(PDP) ;ARE WE DOING AN EXEC UUO ? + TLNE UUO,USRMOD + POP PDP,TAC ;NO - MUST BE A USER UUO. TAKE ONE ELEMENT OFF STACK. + MOVEI UUO,(UCHN) ;UUO AC FIELD + PUSHJ PDP,GETWDU ;PICK UP CONTENTS OF AC + ROT TAC1,-1 ;DIVIDE BY 2, SAVING REMAINDER + MOVE DAT,UCLJMP(TAC1) ;GET DISPATCH TABLE ENTRY + JRST DISP2 ;GO DISPATCH + ;EXIT UUO ROUTINE +;IF AC FIELD = 0, PRINT +; Exit +; ^C +; . +;CONTINUE WILL NOT WORK +; +;IF AC FIELD IS NON-ZERO, ONLY PRINT " . " +;DO NOT RELEASE DEVICES; CONTINUE WILL WORK. + +EXIT: JUMPN UCHN,MONRET ;IS AC FIELD NON-ZERO ? + PUSHJ PDP,IORELS ;NO, RELEASE ALL DEVICES + PUSHJ PDP,TTYFUW ;FIND TTY FOR CURRENT JOB, SET ITEM TO JOB #, + ;DAT TO OUTPUT BYTE PTR., DEVDAT TO TTY DDB. + JSP TAC,PHOLD ;MOVE "EXIT" TO OUTPUT BUFFER, STOP JOB, + ;START TTY, AND PREVENT "CONTINUE" FROM WORKING + ASCIZ / +Exit/ + +;EXIT UUO FOR NON-ZERO AC FIELD +;RETURN TTY TO MONITOR MODE, STOP JOB, DON'T RELEASE DEVICES. +;ALLOW "CONTINUE" TO RETURN TO THE LOC. AFTER THE EXIT UUO. + +MONRET: PUSHJ PDP,TTYFUW ;FIND TTY, ETC. + PUSHJ PDP,PRCRCC ;PRINT CRLF ^C CRLF + PUSHJ PDP,PRPER ;AND PERIOD + PUSHJ PDP,TTYSTC + JRST STOP1 ;START TTY IN MONITOR MODE AND STOP JOB + +;SET PUSHDOWN OVERFLOW TRAP - "SETPOV" + +SETPOV: .UMOVM TAC,JOBAPR ;GIVE A COPY TO USER + MOVEI TAC,1_19. + JRST APRENB ;SET TRAP LOC. + + +;LOGOUT UUO ROUTINE + +ULOGIN: .SUSET [.RUNAME,,TAC] ;GET USER NAME + HLLOS TAC + AOJN TAC,UUOERR ;ILLEGAL UUO IF LOGGED IN + .VALUE [ASCIZ/b:PROCED :ATTACH /] + .SUSET [.SSNAME,,TAC1] + .UCLOSE UPRGO, ;FREE CURRENT INFERIOR + .CALL [SETZ ? SIXBIT/LOGIN/ ? MOVE TAC1 ? SETZ [SIXBIT/TEN50/]] + JRST UUOERR ;YOU LOSE + JRST GO ;SUCCESS RETURN + +LOGOUT: PUSHJ PDP,INLMES + ASCII/Kjob +./ + .LOGOUT ;LOG OUT IF TOP LEVEL + .BREAK 16,164000 ;ASK DDT TO MERELY KILL THIS ONE + +;RESET UUO ROUTINE + +RESET: + PUSHJ PDP,IOKILL ;RELEASE ALL DEVICES + MOVSI TAC,777777-USRMOD ;CLEAR ALL UUO PC FLAGS IN LH, + ;EXCEPT FOR USER MODE + ANDCAM TAC,USRPD1 ;LEAVE USER MODE OFF ALSO, IF RESET FROM "SIM" + ;FALL INTO APRENB WITH RH OF TAC=0 + ;SO THAT ALL APR INTERRUPTS WILL BE DISABLED + ;ROUTINE TO SET UP APR FOR USER TRAPPING +; +; 1B18 REPETITIVE ENABLE +; 1B19 PUSHDOWN OVERFLOW +; 1B22 ILLEGAL MEMORY +; 1B23 NON-EXISTENT MEMORY +; 1B26 CLOCK +; 1B29 FLOATING POINT OVERFLOW +; 1B32 ARITHMETIC OVERFLOW + +APRENB: TRZ TAC,1_23.+1_26. ;THESE TWO BITS ARE ILLEGAL BECAUSE + ;NON-EX. MEM. DOESN'T APPLY & CLOCK + ;IS UNIMPLEMENTABLE + HRRM TAC,ITSENB ;SET RH OF OUR LOC. + JRST SETAPR ;FINISH UP + ;SHOW C(TAC) IN THE LIGHTS + +LIGHTS: DATAO TAC ;DISPLAY TAC IN LIGHTS + POPJ PDP, ;RETURN + +;RETURN CONTENTS OF CONSOLE SWITCHES + +SWITCH: DATAI TAC ;GET CONTENTS OF SWITCHES + JRST STOTAC ;GIVE IT TO USER + +;RETURN JOB # TO USER + +JOBNO: SKIPA TAC,JOB + +;RETURN THE DATE TO THE USER + +DATE: PUSHJ PDP,GTDATE ;GET TODAY'S DATE IN DEC 12-BIT FORMAT + JRST STOTAC ;GIVE IT TO USER IN SPECIFIED AC + +;RETURN JOB RUNNING TIME IN MILLISECONDS + +GTJBTM: .SUSET [.RRUNT,,TAC] + ADD TAC,TRTPI ;ADD IN RUN TIME FOR PAST INFERIORS + SKIPE TAC1,JBTADR ;IS THERE AN INFERIOR ? + .USET UPRGO,[.RRUNT,,TAC1] ;YES - READ ITS ACCUMULATED TIME + ADD TAC,TAC1 ;ADD IT IN (OR ZERO IF NO INFERIOR EXISTS) + FSC TAC,233 ;FLOAT TOTAL + FMPR TAC,[.OP FDVR 4.069 1.0^3] ;CONVERT TO MILLISECONDS + FADR TAC,[0.5] ;ROUND TO NEAREST MILLISECOND + UFA TAC,[233000,,0] ;FIX RESEULT, LEAVE ANSWER IN AC(TAC1) + LDB TAC,[POINT 27,TAC1,35,] ;COLLECT BOTTOM 27. BITS OF TAC1 + POPJ PDP, ;RETURN WITH # MILLISECONDS IN TAC + +;RUNTIM CALLI + +JOBTIM: PUSHJ PDP,GTJBTM ;GET JOB RUNNING TIME IN MILLISECONDS + JRST STOTAC ;RETURN THAT TO USER + +;RETURN TIME OF DAY IN MILLISECONDS + +MSTIME: PUSHJ PDP,GTTIME ;GET # JIFFIES PAST MIDNIGHT + IMULI TAC,1000. + IDIVI TAC,JIFSEC + JRST STOTAC + +;PUT JOB TO SLEEP FOR N SECONDS + +SLEEP: IMULI TAC,30. ;FORM # OF 1/30 SECONDS + CAILE TAC,68.*30. ;LARGER THAN D.E.C. MAXIMUM ? + MOVEI TAC,1 ;YES, JUST A SHORT SNOOZE!! + .SLEEP TAC, + POPJ PDP, ;WE HAVE AWOKEN, RETURN + +;ROUTINE TO GET WORD FROM USER AREA AT UUO LEVEL +;RETURN ONLY IF ADR. OK; WORD IN TAC +;UPON ENTERING, ADR. OF DESIRED WORD IS IN UUO. + +GETWD1: HRRI UUO,1(UUO) ;INCREMENT ADR. + +GETWDU: MOVE TAC,USRPD1 ;IS IT USER MODE? + TLNN TAC,USRMOD + JRST GTWDU1 ;NO, GET WORD FROM OUR CORE + PUSHJ PDP,GETWRD ;CHECK LEGALITY AND GET WORD + JRST UUOERR ;ADR. OUT OF BOUNDS +LCPOPJ: +RMPERR: POPJ PDP, ;OK, TAC HAS DESIRED WORD +GTWDU1: MOVE TAC,(UUO) ;GET WORD FROM OUR CORE + POPJ PDP, ;RETURN + + +;RETURN TIME OF DAY IN JIFFIES + +TIMER: PUSHJ PDP,GTTIME ;GET # JIFFIES PAST MIDNIGHT + JRST STOTAC ;AND GO TO STOTAC + +;ROUTINE TO STORE CONTENTS OF TAC IN USER AREA AS SPECIFIED BY UUO + +STOTC1: HRRI UUO,1(UUO) ;INCREMENT UUO BEFORE DOING STOTAC + +STOTAC: MOVE AC1,USRPD1 ;ARE WE IN USER MODE? + TLNN AC1,USRMOD + JRST STO1TC ;NO, PUT THE WORD IN OUR CORE + HRRZ AC1,UUO ;YES, GET ADR. + PUSHJ PDP,UADCK1 ;IS IT IN BOUNDS? + .UMOVM TAC,(UUO) ;YES, STORE IT IN USER'S CORE + POPJ PDP, ;RETURN +STO1TC: MOVEM TAC,(UUO) ;STORE WORD IN OUR CORE + POPJ PDP, ;AND RETURN + ;RETURN DEVICE CHARACTERISTICS + +DVCHR: PUSHJ PDP,DEVSRC ;SEARCH FOR DEVICE + JRST RTZER ;NOT A DEVICE, RETURN ZERO + MOVE TAC,DEVMOD(DEVDAT) ;FOUND, GET DEVMOD + TLO TAC,DVAVAL ;AND TELL HIM DEVICE IS AVAILABLE TO HIM + JRST STOTAC + +;RETURN PROJECT-PROGRAMMER # IN SPECIFIED AC + +GETPPN: SKIPA TAC,PRJPRG ;GET HIS PPN +RTZER: SETZ TAC, ;RETURN ZERO TO USER + JRST STOTAC + +;SET DDT START ADR. FOR "DDT" COMMAND + +SETDDT: MOVEM TAC,USRDDT ;STORE IN OUR COPY + .UMOVM TAC,JOBDDT ;GIVE HIM A COPY, TOO. + POPJ PDP, ;RETURN + +GETLN: PUSHJ PDP,TTYFND ;FIND USER'S TTY + MOVE TAC,DEVNAM(DEVDAT) ;GET NAME + JRST STOTAC ;GIVE IT TO USER + +SETNAM: MOVEM TAC,JBTPRG ;STORE PROGRAM NAME + PUSHJ PDP,SPRGNM ;CHANGE NAME OF CURRENT INFERIOR TO + ; REFLECT RESULT OF UUO. + POPJ PDP, ;RETURN + ;GETTAB UUO +; +;UUO TO RETURN CONTENTS OF A MONITOR JOB TABLE +;CALL: HRROI AC,TABLE NUMBER +; HRLI AC,JOB NUMBER (OPTIONAL) +; CALLI AC,41 +; ERROR RETURN (AC PRESERVED) - IF LH NOT NEG. OR = THIS JOB # +; NORMAL RETURN - AC=0 IF TABLE UNDEFINED + +GETTAB: HLRZ ITEM,TAC ;GET USER SUPPLIED JOB NUMBER + CAME ITEM,JOB ;IT MUST BE EITHER HIS JOB # + SKIPGE TAC ;OR NEGATIVE + TLZA TAC,-1 ;OK, CLEAR LH + POPJ PDP, ;NO, GIVE ERROR RETURN WITH AC UNCHANGED + CAILE TAC,MXGTB ;IT MUST BE A TABLE WE ARE CONCERNED WITH + TDZA TAC,TAC ;NO, RETURN WITH HIS AC ZEROED + XCT GTTBL(TAC) ;OK, DO THE RIGHT THING + AOS (PDP) ;GIVE GOOD RETURN + JRST STOTAC ;WITH AC FILLED + +GTTBL: MOVE TAC,JBTSTS ;GIVE HIM HIS JOB STATUS + MOVE TAC,JBTADR ;GIVE HIM RELOC. & PROT. DATA + MOVE TAC,PRJPRG ;HIS PPN + MOVE TAC,JBTPRG ;HIS PROGRAM NAME + PUSHJ PDP,GTJBTM ;HIS JOB'S TOTAL RUNNING TIME +MXGTB==.-GTTBL + ;OPEN UUO - PERFORMS SAME OPERATION AS INIT +;CALLING SEQUENCE: +; OPEN D,ADR +; ERROR RETURN +; DEVICE INITED + +;LH(ADR) = 0 , RH(ADR) = DATA MODE +;C(ADR+1) = SIXBIT /DEVICE NAME/ +;LH(ADR+2) = OUTPUT BUFFER HEADER ADR. +;RH(ADR+2) = INPUT " " " + +UOPEN: PUSHJ PDP,GETWDU ;SET TAC TO MODE + AOJA UUO,UINIT0 ;MAKE UUO POINT TO ARG+1 + ;AND FINISH OPEN + + +;INIT UUO +; +; INIT D,MODE +; SIXBIT /DEVICE NAME/ +; XWD OBUF,IBUF +; ERROR RETURN +; DEVICE INITED + +UINIT: MOVEI TAC,(UUO) ;SAVE STATUS BITS IN TAC + HRR UUO,-1(PDP) ;SET UUO TO ADR+1 OF ARGS. + AOS -1(PDP) ;SET RETURN TO SKIP THE 2 ARGS. + AOS -1(PDP) +UINIT0: PUSH PDP,UUO ;SAVE ADR+1 OF USER ARGS. + PUSH PDP,TAC ;SAVE I/O STATUS BITS + SKIPE DEVDAT,USRJDA(UCHN) ;IS A DEVICE ALREADY ASSIGNED + ;TO THIS CHANNEL? + CAMLE UCHN,USRHCU ;YES, IS CHAN. # <= HIGHEST IN USE? + JRST UINITA ;NO, NO PREVIOUS DEVICE TO RELEASE + PUSHJ PDP,RELEA0 ;YES, RELEASE PREV. DEVICE ON THIS CHAN +UINITA: MOVE UUO,-1(PDP) ;RESTORE UUO + PUSHJ PDP,GETWDU ;C(TAC) = DEVICE NAME + ;IF NOT IN BOUNDS, ERROR + PUSHJ PDP,DEVSRC ;SEARCH FOR DEVICE NAME (SET SYSDEV BIT + ;IN LH OF DEVDAT IF THIS IS "SYS") + JRST UINITE ;NO SUCH DEVICE + MOVE UUO,(PDP) ;RESTORE USER'S MODE SETTING + PUSHJ PDP,CHKMOD ;CHECK FOR LEGAL MODE; IF ERROR, + ;DON'T RETURN + UINIT1: +;CODE TO GO HERE IF DTA'S BECOME A REALITY IN "SIM" + +UINITB: MOVEI TAC1,ASSPRG ;ASSIGN DEVICE BY PROGRAM. + PUSHJ PDP,ASSASG + JRST UINIT6 ;NOT AVAILABLE - ERROR RETURN + POP PDP,UUO ;RESTORE USER'S MODE + LDB UCHN,[POINT 4,(PDP),12,] ;RESTORE CHANNEL # - CLOBBERED + ;IF ASSASG CALLS GTF + PUSHJ PDP,SETIOS ;SET DDB IOS STATUS WORD FROM + ;RIGHT HALF OF UUO + MOVSI IOS,IOBEG ;SET IOBEG + IORB IOS,DEVIOS(DEVDAT) +UINITL: CAMG UCHN,USRHCU ;IS THIS CHAN. > HIGHEST IN USE? + JRST UINITC ;NO + AOS TAC,USRHCU ;YES, BUMP HIGHEST SO FAR + .UMOVM TAC,JOBHCU + SETZB UUO,USRJDA(TAC) ;AND CLEAR IT OUT + .UMOVM UUO,JOBJDA(TAC) + JRST UINITL ;AND KEEP LOOKING +UINITC: TLO DEVDAT,INITB+ICLOSB+OCLOSB ;SET INIT + ;UUO BIT AND PREVENT SUPERFLUOUS + ;CALLS TO CLOSE + AOS UUO,(PDP) ;ADVANCE TO THIRD ARG. + PUSHJ PDP,GETWDU ;C(TAC) = BUFFER HEADER ADR. + HLRZ TAC1,TAC ;GET OUTPUT BUFFER HEADER ADR. + JUMPE TAC1,UINIT4 ;WAS ONE SPECIFIED? + HRLM TAC1,DEVBUF(DEVDAT) ;YES, SET DDB + TLO DEVDAT,OBUFB ;NOTE OUTPUT BUFFER SPECIFIED + PUSHJ PDP,UINITZ ;INITIALIZE OUTPUT BUFFER HEADER + UINIT4: PUSHJ PDP,GETWDU ;GET THE CONTENTS OF ARG. 3 AGAIN + HRRZ TAC1,TAC ;GET INPUT BUFFER HEADER ADR. + JUMPE TAC1,UINIT5 ;WAS ONE SPECIFIED? + HRRM TAC,DEVBUF(DEVDAT) ;YES, SET DDB + TLO DEVDAT,IBUFB ;NOTE INPUT BUFFER SPECIFIED + MOVSI IOS,IOEND ;CLEAR EOF FLAG + ANDCAB IOS,DEVIOS(DEVDAT) + PUSHJ PDP,UINITZ ;INITIALIZE INPUT BUFFER HEADER +UINIT5: MOVEM DEVDAT,USRJDA(UCHN) ;STORE UUO BITS AND DDB ADR. + .UMOVM DEVDAT,JOBJDA(UCHN) + JRST TPOPJ1 ;GIVE GOOD RETURN + +UINIT6: +;CODE TO BE ADDED HERE FOR DTA'S (IN FUTURE MAYBE) + +UINITE: POP PDP,TAC ;RESTORE STACK + JRST TPOPJ ;AND GIVE ERROR RETURN + UINITZ: MOVEI AC1,2(TAC1) ;IS ADR. OF 3RD WORD IN BOUNDS? + PUSHJ PDP,UADRCK + SETZ AC1, ;YES, ZAP 1ST & 3RD WORDS + .UMOVM AC1,(TAC1) + .UMOVM AC1,2(TAC1) + PUSHJ PDP,SETBYT ;SET BYTE SIZE FROM IOS + .UMOVE AC1,1(TAC1) ;GET 2ND WORD + HRRI TAC,(AC1) ;USE RH + .UMOVM TAC,1(TAC1) ;STORE BYTE SIZE AND RH + POPJ PDP, ;RETURN + +;HERE WHEN WE GET ONLY PART WAY THROUGH INIT'ING A DEVICE + +UINERR: PUSHJ PDP,RELEA0 ;RELEASE DEVICE + JRST TPOPJ ;GIVE ERROR RETURN + ;ENTER UUO - HERE ONLY IF DEVICE HAS LONG DISPATCH TABLE + +UDEN: MOVEI TAC,CLSIN + TLNN DEVDAT,OCLOSB ;FILE OPEN? + PUSHJ PDP,UDLKC ;YES, CLOSE IT (OCLOSB_1) + TLO IOS,IOBEG + ANDCMI IOS,776000 + MOVEM IOS,DEVIOS(DEVDAT) + HLLM DEVDAT,USRJDA(UCHN) ;STORE UUO BITS + .UMOVE TAC,JOBJDA(UCHN) ;AND GIVE HIM A COPY + HLL TAC,DEVDAT + .UMOVM TAC,JOBJDA(UCHN) + PUSHJ PDP,DEN(DSER) ;ATTEMPT AN ENTER + POPJ PDP, ;FAILURE, RETURN + TLZ DEVDAT,OCLOSB + TLO DEVDAT,ENTRB ;NOTE SUCCESSFUL ENTER + JRST DLKDEN ;STORE THE PROGRESS BITS + +;LOOKUP UUO - LONG DISPATCH DEVICES ONLY + +UDLK: MOVEI TAC,CLSOUT ;INHIBIT OUTPUT CLOSE BIT + TLNN DEVDAT,ICLOSB ;FILE OPEN? + PUSHJ PDP,UDLKC ;YES, CLOSE IT (ICLOSB_1) + TDZ IOS,[XWD IOEND 776000] + MOVEM IOS,DEVIOS(DEVDAT) + HLLM DEVDAT,USRJDA(UCHN) ;STORE UUO BITS + .UMOVE TAC,JOBJDA(UCHN) ;STORE A COPY FOR HIM + HLL TAC,DEVDAT + .UMOVM TAC,JOBJDA(UCHN) + PUSHJ PDP,DLK(DSER) ;DO THE LOOKUP + POPJ PDP, ;FAILURE! + TLZ DEVDAT,ICLOSB + TLO DEVDAT,LOOKB ;NOTE SUCCESSFUL LOOKUP +DLKDEN: LDB TAC,PUUOAC ;GET CHANNEL # + PUSH PDP,ITEM ;SAVE AN AC + HLLM DEVDAT,USRJDA(TAC) ;STORE UUO PROGRESS BITS + .UMOVE ITEM,JOBJDA(TAC) ;COPY FOR OUR USER + HLL ITEM,DEVDAT + .UMOVM TAC,JOBJDA(TAC) + JRST IPOPJ1 ;RESTORE ITEM AND RETURN + +UDLKC: PUSH PDP,UUO + HRRI UUO,(TAC) + PUSHJ PDP,CLOSE1 + POP PDP,UUO + POPJ PDP, + ;DO "INBUF" AND "OUTBUF" HERE + +UOUTBF: TLO DEVDAT,OUTBFB ;NOTE OUTBUF UUO + PUSH PDP,BUFPNT ;SAVE BUFPNT + PUSHJ PDP,BUFCLC ;SET UP BUFFER RING + HLRZ TAC,DEVBUF(DEVDAT) ;GET ADR. OF OUTPUT BUFFER HEADER + HRRM BUFPNT,DEVOAD(DEVDAT) ;STORE ADR. OF FIRST BUFFER IN RING + +UOBF1: .UMOVM BUFPNT,(TAC) ;POINT HEADER AT FIRST BUFFER IN RING + LDB TAC,PUUOAC + MOVEM DEVDAT,USRJDA(TAC) + .UMOVM DEVDAT,JOBJDA(TAC) + POP PDP,BUFPNT ;RESTORE BUFPNT + POPJ PDP, ;RETURN FROM UUO + +UINBF: TLO DEVDAT,INBFB ;NOTE INBUF UUO + PUSH PDP,BUFPNT ;SAVE BUFPNT + PUSHJ PDP,BUFCLC ;SET UP RING + HRRM BUFPNT,DEVIAD(DEVDAT) ;POINT TO FIRST BUFFER + HRRZ TAC,DEVBUF(DEVDAT) ;GET ADR. OF INPUT HEADER + JRST UOBF1 ;FINISH UP + ;ROUTINE TO SET UP N-RING BUFFER IN USER AREA + +BUFCLC: PUSH PDP,BUFWRD ;SAVE BUFWRD + LDB TAC,[XWD 1400+DEVDAT DEVCHR] ;GET THE BUFFER SIZE + .UMOVE BUFPNT,JOBFF ;GET FIRST FREE + 1 + MOVEI BUFPNT,1(BUFPNT) + MOVEI BUFWRD,(BUFPNT) + HRL BUFWRD,TAC ;BUFWRD = BUFFER SIZE , FIRST FREE + 1 + ADDI TAC,2 ;BUF. SIZE + 2 + MOVEI TAC1,(UUO) ;GET # BUFFERS DESIRED + MOVEI AC1,(TAC) ;BUF. SIZE + 2 + IMULI AC1,(TAC1) ;TIMES # BUFFERS + ADDI AC1,(BUFWRD) + MOVEI AC1,(AC1) ;FORM LAST ADR. NEEDED + CAMG AC1,USRREL ;DOES HE HAVE ENOUGH CORE? + JRST BUFC1 ;YES, MOVE ON + + ;NO, EXPAND USER'S CORE + PUSH PDP,TAC ;SAVE BUNCH OF AC'S + PUSH PDP,UUO + PUSH PDP,TAC1 ;** ALL MAY NOT NEED TO BE SAVED ** + PUSH PDP,BUFPNT + PUSH PDP,BUFWRD + PUSH PDP,DEVDAT + PUSH PDP,DSER + SETZ ITEM, ;SET JOB # + MOVE TAC,AC1 ;ARGUMENT GOES IN AC(TAC) + MOVEI UUO,UUO ;FOR "STOTAC" + PUSHJ PDP,CORUUO ;TRY TO GET THE CORE + JFCL ;CAN'T GET IT - ADR. CHECK WILL CATCH IT + POP PDP,DSER + POP PDP,DEVDAT + POP PDP,BUFWRD + POP PDP,BUFPNT + POP PDP,TAC1 + POP PDP,UUO + POP PDP,TAC + BUFC1: ADDI BUFWRD,(TAC) + MOVEI AC1,(BUFPNT) ;IS LAST ADR. IN BOUNDS? + PUSHJ PDP,UADRCK + .UMOVM BUFWRD,(BUFPNT) ;YES, SET UP THIS HEADER + MOVEI BUFPNT,(BUFWRD) + SOJG TAC1,BUFC1 ;LINK ALL BUFFERS + .UMOVE AC1,JOBFF + HRRI BUFWRD,1(AC1) ;DO NOT DESTROY LH OF AC(BURWRD) (=BUFFER SIZE) + MOVEI AC1,-2(BUFPNT) ;CHECK LAST ADR. OF HEADER + PUSHJ PDP,UADRCK + SUBI BUFPNT,(TAC) + .UMOVM BUFWRD,(BUFPNT) ;LINK LAST BUFFER TO FIRST + .UMOVE AC1,JOBFF + ADDI BUFPNT,-1(TAC) + HRRI AC1,(BUFPNT) + .UMOVM AC1,JOBFF + MOVEI BUFPNT,(BUFWRD) ;BUFPNT = IOUSE , ADR. FIRST BUFFER + HRLI BUFPNT,IOUSE + POP PDP,BUFWRD ;RESTORE BUFWRD + POPJ PDP, ;RETURN + ;ROUTINE TO CLEAR I/O BUFFER IN USER AREA +;CALLED AT UUO LEVEL + +;CALL: HRRZ TAC,REL. ADR. OF 2ND WORD OF USER BUFFER +; PUSHJ PDP,BUFCLR +; ERROR RETURN - MEMORY EXCEEDED +; EXIT RETURN HERE IF MEMORY NOT EXCEEDED +;CLEARS THE WORD COUNT AND DATA AREA OF THE BUFFER WHOSE ADR. +;IS IN TAC 18-35. + +BUFCLR: PUSHJ PDP,IADRCK ;IN BOUNDS? + POPJ PDP, ;NO, ERROR RETURN + PUSH PDP,TAC ;SAVE FIRST BUFFER ADR. + .UMOVE TAC1,(TAC) ;GET SIZE (18-35) INTO RH TAC1 + HLRZ TAC1,TAC1 + ANDCMI TAC1,400000 + ADDI TAC,(TAC1) ;LAST ADR.=2ND ADR. + SIZE + PUSHJ PDP,IADRCK ;LAST ADR. IN BOUNDS? + JRST TPOPJ ;NO, ERROR RETURN + PUSHJ PDP,CLRMBF ;CLEAR MONBUF...MONBUF+MBFSIZ-1 + POP PDP,TAC1 ;RESTORE FIRST ADR. + ADDI TAC1,1 ;BEGIN CLEARING BUFFER AT WORD COUNT + ; I.E. AT 3RD WORD OF BUFFER + HRLI TAC1,MONBUF ;ZERO BUFFER BY SENDING ENOUGH ZEROS + ;FROM MONBUF + .UBLTO TAC1,(TAC) ;CLEAR BUFFER + JRST CPOPJ1 ;SUCCESSFUL RETURN + ;ROUTINE TO RETURN # OF ITEMS IN BUFFER + +;CALL: PUSHJ PDP,ITMSET +; EXIT ALWAYS RETURN HERE +;SETS AC ITEM = (BUFFER SIZE - 1)*[WORD LENGTH/BYTE SIZE] + + +;CALL: PUSHJ PDP,ITMCNT +; EXIT ALWAYS RETURNS HERE +;SETS AC ITEM = C(ITEM)*[WORD LENGTH/BYTE SIZE] + + +;CALL: PUSHJ PDP,ITMCT1 +; EXIT ALWAYS RETURNS HERE +;SETS AC ITEM = C(ITEM)*[WORD LENGTH/C(TAC1)] + + +ITMSET: .UMOVE ITEM,@DEVADR(DEVDAT) ;GET HEADER WORD + ASH ITEM,-18. ;GET BITS 1-17 INTO RH + MOVEI ITEM,-1(ITEM) ;GET BUFFER SIZE - 1 +ITMCNT: LDB TAC1,[POINT 6,DEVPTR(DEVDAT),11,] ;TAC1 = BYTE SIZE +ITMCT1: MOVEI TAC,36. ;ITEM = C(ITEM)*[WORD LENGTH/C(TAC1)] + IDIVI TAC,(TAC1) + IMULI ITEM,(TAC) + POPJ PDP, ;RETURN + + + +;ROUTINE TO SET DEVICE STATUS WORD FROM UUO + +SETIOS: PUSHJ PDP,CHKMOD ;CHECK FOR LEGAL MODE, IF NOT RIGHT, + ;DON'T RETURN + ANDCMI UUO,IOACT ;LET USER SET ALL EXCEPT IOACT + HRRM UUO,DEVIOS(DEVDAT) + POPJ PDP, + + +;CHECK FOR LEGAL MODE FOR A DEVICE + +CHKMOD: LDB TAC1,[POINT 4,UUO,35,] ;GET DEVICE DATA MODE + MOVEI TAC,1 ;CHECK FOR LEGALITY + LSH TAC,(TAC1) + TDNN TAC,DEVMOD(DEVDAT) + JRST ILLMOD ;ILLEGAL DATA MODE + POPJ PDP, ;OK + ;CALLING SEQUENCE: +; PUSHJ PDP,IOSETC +; EXIT ;ALWAYS RETURN HERE + +;SETS JBFPTR18-35:=C(TAC1 18-35) +; JBFCTR:=C(ITEM)*[WORD LENGTH/BYTE SIZE] +;WHERE WORD LENGTH:= 36 DECIMAL +; BYTE SIZE:=C(JBFPTR 6-11) +; [X]:= INTEGER PART OF X + +IOSETC: ADDI JBUF,1 ;JBFPTR 12-18:=0 + .UMOVE TAC,(JBUF) ;JBFPTR 18-35:=C(TAC1 18-35)+1 + TLZ TAC,770000 + HRRI TAC,1(TAC1) + .UMOVM TAC,(JBUF) + LDB TAC1,[POINT 6,TAC,11,] ;TAC1:= BYTE SIZE + PUSHJ PDP,ITMCT1 ;JBFCTR:=C(ITEM)*[36/BYTE SIZE] + ADDI JBUF,1 ;POINT TO BYTE COUNT + ;THIS INSTR. CAN BE REMOVED IF IT IS NOT NECESSARY TO RETURN + ;WITH JBUF POINTING TO BYTE COUNT. - IF IT IS REMOVED, + ;THE FOLLOWING INSTR. SHOULD BE: .UMOVM ITEM,1(JBUF) + .UMOVM ITEM,(JBUF) ;STORE THE BYTE COUNT IN 3RD WORD + POPJ PDP, ;RETURN + ;SET UP BYTE POINTER AND ITEM COUNT +;CALL: PUSHJ PDP,NEWBUF +; ADR. CHECK WHEN SETTING UP BUFFER +; OK RETURN + +NEWBF1: +NEWBUF: HRRZ TAC,DEVADR(DEVDAT) ;TAC = INPUT BUF. HDR. ADR. + PUSHJ PDP,BUFCLR ;CLEAR INPUT BUFFER + POPJ PDP, ;ADR. CHECK, PASS IT ON +;**********THE ENCLOSED CODE MAY NOT BE NEEDED!********** + MOVSI TAC,7737 + AND TAC,DEVPTR(DEVDAT) ;DEVPTR 0-5 = 0, 12 = 0 + HRR TAC,DEVADR(DEVDAT) ;DEVPTR 18-35 = C(DEVADR 18-35) + ADDI TAC,1 ; + 1 + MOVEM TAC,DEVPTR(DEVDAT) + PUSHJ PDP,ITMSET ;SET # ITEMS IN BUFFER + MOVEM ITEM,DEVCTR(DEVDAT) ;DEVCTR = ITEM COUNT + JRST CPOPJ1 ;SKIP RETURN (OK) + + +;ROUTINE TO SET UP BYTE POINTER ACCORDING TO DATA MODE +;CALL: PUSHJ PDP,SETBYT +; ALWAYS RETURNS HERE +;SETS: TAC 0-5 = 0 +; TAC 6-11 = S +; TAC 12-17 = 0 +;WHERE S=36 IF DATA MODE (IOS 32-35) IS BINARY (B), IMAGE (I), +;IMAGE BINARY (IB), OR DUMP (SD,D,DR) +;S=7 IF DATA MODE IS ASCII (A) OR ASCII LINE (AL). + +SETBYT: HRLI TAC,700 ;ASSUME ASCII TO START + TRNE IOS,14 ;CORRECT ASSUMPTION ? + HRLI TAC,4400 ;NO, 10 OR GREATER ::= S=36. + POPJ PDP, ;RETURN + ;RENAME UUO - HERE ON SHORT DISPATCH TABLE DEVICES TOO + +URENAM: MOVE TAC,DEVMOD(DEVDAT) ;DOES THIS DEVICE HAVE LONG + ;DISPATCH TABLE? + TLNN TAC,DVLNG + JRST CPOPJ1 ;NO, GIVE SKIP RETURN TO USER + JRST DRN(DSER) ;YES, DISPATCH TO SERVICE ROUTINE + +;SETO UUO - SET NEXT OUTPUT BLOCK NUMBER + +UDSO: JRST DSO(DSER) + +;SETI UUO - SET NEXT INPUT BLOCK NUMBER + +UDSI: JRST DSI(DSER) + + ;HERE ON INPUT UUO + +IN: TLO DEVDAT,INPB + TLZ DEVDAT,ICLOSB + .UMOVE TAC,JOBJDA(UCHN) ;BIT SETTINGS INTO LH OF JDA LOC + HLL TAC,DEVDAT + .UMOVM TAC,JOBJDA(UCHN) + HLLM DEVDAT,USRJDA(UCHN) ;OUR COPY ALSO + LDB TAC,PIOMOD ;GET I/O MODE + CAIL TAC,SD ;IS IT DUMP? + JRST INDMP ;YES +IN1: HRRZ JBUF,DEVBUF(DEVDAT) ;NO, GET ADR. OF BUFFER HDR. + MOVSI TAC,IOUSE ;SET UP "USE BIT" + MOVEI AC1,2(JBUF) ;CHECK BUFFER HDR. FOR IN BOUNDS + PUSHJ PDP,UADRCK + MOVE IOS,DEVIOS(DEVDAT) ;SET UP I/O STATUS AGAIN BECAUSE + ;IOS IS CLOBBERED BY AUTO. CORE + ;EXPANSION ON IMPLICIT INBUF ON + ;FIRST INPUT + .UMOVE TAC1,(JBUF) ;GET FIRST WORD OF HEADER + JUMPLE TAC1,INPUTF ;SET UP BUFFER IF NECESSARY AND + ;DO FIRST I/O + MOVEI AC1,(TAC1) ;OTHERWISE, CHECK ADR. + PUSHJ PDP,UADRCK + MOVE IOS,DEVIOS(DEVDAT) + .UMOVE AC1,(TAC1) ;CURRENT BUFFER + JUMPGE AC1,INPT1 ;MOVE ON IF FREE (IOUSE=0) + ANDCAB TAC,AC1 ;NOT FREE - CLEAR USE BIT AND GET + ;POINTER TO NEXT BUFFER + .UMOVM AC1,(TAC1) + HLL TAC,TAC1 ;SET WORD1 IN 3-WORD HEADER TO + .UMOVM TAC,(JBUF) ;POINT TO NEXT BUFFER + MOVEI AC1,(TAC) ;AND CHECK ITS ADR. + PUSHJ PDP,UADRCK + MOVE AC1,DEVMOD(DEVDAT) ;GET DEVICE CHAR. WORD + TLNN AC1,DVTTY ;IS IT A TTY? + .UMOVE TAC,(TAC) ;NO, GET POINTER 1 BUFFER AHEAD OF NEXT BUFFER + MOVEI AC1,(TAC) ;SEE IF USER HAS CLOBBERED POINTER + PUSHJ PDP,UADRCK + .UMOVE AC1,(TAC) ;IS THE USE BIT SET? + JUMPL AC1,INPT0C + PUSHJ PDP,CALIN ;NO, HAVE SERVICE ROUTINE FILL EMPTY BUFFER +INPT0C: .UMOVE TAC1,(TAC1) ;GET USE BIT FOR NEXT BUFFER +INPT2: +INPT0A: .UMOVE AC1,(TAC1) + JUMPGE AC1,INEOF ;IF NOT FILLED YET, MUST BE EOF OR ERROR + INPUT2: .UMOVE ITEM,1(TAC1) ;GET WORD COUNT + MOVEI ITEM,(ITEM) ;RIGHT HALF ONLY + JRST IOSETC ;SET ITEM COUNT AND BYTE POINTER AND RETURN TO USER +INEOF: TDNN IOS,[XWD IOEND IODERR+IOBKTL+IODTER+IOIMPM] + ;IS EOF OR ERROR BIT SET BY SERVICE ROUTINE + JSP DAT,UUOERR ;NO, MONITOR ERROR AT UUO LEVEL + TLNE IOS,IOEND ;IS THIS EOF? + IORI IOS,IODEND ;YES, SET EOF BIT FOR USER + IORM IOS,DEVIOS(DEVDAT) + POPJ PDP, ;RETURN + +;HERE ON FIRST INPUT AFTER INIT, INIT & LOOKUP, OR INIT & LOOKUP & INPUT + +INPUTF: ANDCAB TAC,TAC1 ;MARK THAT BUFFERS HAVE BEEN REFERENCED + .UMOVM TAC,(JBUF) ;BY CLEARING SIGN BIT OF FIRST WORD IN 3-WORD + ;BUFFER HEADER + JUMPE TAC,INPUT3 ;HAS A RING BEEN SET UP YET? + HRRZ AC1,TAC1 ;YES, ADR. CHECK FIRST USER BUFFER + PUSHJ PDP,UADRCK + .UMOVE AC1,(TAC1) ;IS USE BIT SET IN FIRST USER INPUT BUFFER? + ; THIS CAN HAPPEN IF TTY AND USER HAS TYPED IN + ; A LINE AFTER INBUF BUT BEFORE FIRST INPUT UUO + JUMPLE AC1,INPUT2 ;YES, DO NOT CALL SERVICE ROUTINE (SCNSRF) SINCE + ;USER BUFFER ALREADY HAS DATA + HRRM TAC,DEVIAD(DEVDAT) ;NO, STORE ADR. OF 2ND WORD OF BUFFER + ;FOR SERVICE ROUTINE +INPT1: PUSHJ PDP,CALIN ;FILL BUFFER + JRST INPT2 +INPUT3: HRRI UUO,2 ;BUFFERS NOT SET UP YET - SET UP 2 + PUSHJ PDP,UINBF + ANDCMI UUO,-1 ;CLEAR RIGHT HALF + JRST IN1 + +INDMP: JRST DDI(DSER) ;CALL SERVICE ROUTINE AND RETURN +CALIN: TLNE IOS,IOEND + POPJ PDP, + PUSH PDP,TAC1 + PUSH PDP,JBUF + HRRZ AC1,DEVIAD(DEVDAT) ;IS FIRST ADR. ABOVE JOB DATA AREA? + CAIG AC1,JOBPFI + JRST ADRERR ;NO, PRINT ERROR AND STOP JOB + .UMOVE AC2,(AC1) ;GET LENGTH OF BUFFER + LDB AC2,[POINT 17,AC2,17,] ;AND IGNORE USE BIT + ADDI AC1,(AC2) + CAMLE AC1,USRREL ;IS LAST ADR. IN BOUNDS? + JRST ADRERR ;NO, STOP JOB AND PRINT ERROR MESSAGE + PUSHJ PDP,DIN(DSER) ;YES, DISPATCH TO SERVICE ROUTINE + POP PDP,JBUF + POP PDP,TAC1 + POPJ PDP, + ;HERE ON OUTPUT UUO + +UOUT: TLO DEVDAT,OUTPB ;SET OUTPUT UUO BIT + TLZ DEVDAT,OCLOSB ;CLEAR CLOSE OUTPUT BIT + +;HERE FROM SERVICE ROUTINES ON CLOSE UUO + +OUT: .UMOVE TAC,JOBJDA(UCHN) ;GET JDA WORD + HLL TAC,DEVDAT ;PUT IN LH BIT SETTINGS + .UMOVM TAC,JOBJDA(UCHN) ;STORE BACK + HLLM DEVDAT,USRJDA(UCHN) ;MAKE COPY FOR US ALSO + LDB TAC,PIOMOD ;GET DATA MODE + CAIL TAC,SD ;DUMP MODE? + JRST OUTDMP ;YES + PUSHJ PDP,OUTA ;NO, CHECK FOR NON-ZERO ADR. + ;(USER CHANGING RING) + HLRZ JBUF,DEVBUF(DEVDAT) ;REL. ADR. OF O/P BUFFER HEADER + MOVEI AC1,2(JBUF) ;CHECK END OF 3-WORD HEADER + PUSHJ PDP,UADRCK + .UMOVE TAC1,(JBUF) ;GET FIRST WORD OF BUFFER HEADER + JUMPLE TAC1,OUTF ;RING NOT SET UP, OR FIRST + ;REFERENCE TO RING + .UMOVE TAC,1(JBUF) ;GET RH OF BYTE POINTER + ANDI TAC,777777 + JUMPE TAC,.+2 + SUBI TAC,1(TAC1) ;DISTANCE FILLED BY USER + TRNE IOS,IOWC ;DOES USER WANT SYSTEM TO COMPUTE + ;WORD COUNT FROM BYTE POINTER + JRST OUT2 ;NO + MOVEI AC1,1(TAC1) ;YES, PROCEED ONLY IF ADR. OF + ;WORD COUNT IS IN BOUNDS + ADDI AC1,(TAC) ;FORM REL. ADR. OF LAST WORD TO OUTPUT + PUSHJ PDP,UADRCK + .UMOVE AC1,1(TAC1) ;GET THIRD WORD OF BUFFER + HRRI AC1,(TAC) ;PUT WORD COUNT IN + .UMOVM AC1,1(TAC1) ;STORE BACK +OUT2: .UMOVE TAC,(TAC1) ;GET 2ND WORD IN BUFFER + TLO TAC,IOUSE ;SET USE BIT + .UMOVM TAC,(TAC1) ;STORE BACK + .UMOVE IOS,(JBUF) ;GET FIRST WORD IN HEADER + ;(POINTER TO CURRENT BUFFER) + HRRI IOS,(TAC) ;ADVANCE CURRENT BUFFER ADR. + .UMOVM IOS,(JBUF) + MOVE IOS,DEVIOS(DEVDAT) ;GET STATUS WORD + PUSHJ PDP,DOU(DSER) ;DO OUTPUT + HLRZ JBUF,DEVBUF(DEVDAT) ;REL. ADR. OF BUFFER HEADER + .UMOVE TAC1,(JBUF) ;REL. ADR. OF SECOND WORD OF BUFFER + MOVEI AC1,(TAC1) + PUSHJ PDP,UADRCK + .UMOVE TAC,1(JBUF) + ANDCMI TAC,777777 + .UMOVM TAC,1(JBUF) + JRST OUTS ;RETURN TO USER +OUTF: JUMPL TAC1,OUTF1 + HRRI UUO,2 ;SET UP TWO-BUFFER RING + PUSHJ PDP,UOUTBF ;IF NONE SET UP YET + HLRZ JBUF,DEVBUF(DEVDAT) ;RESET JBUF (GETS CLOBBERED) +OUTF1: .UMOVE TAC,(JBUF) ;CLEAR USE BIT + TLZ TAC,IOUSE + .UMOVM TAC,(JBUF) + HRRM TAC,DEVOAD(DEVDAT) + +OUTS: .UMOVE TAC,(JBUF) ;CLEAR NEXT OUTPUT BUFFER + ANDI TAC,777777 + PUSHJ PDP,BUFCLR + JRST ADRERR ;ADR. CHECK + .UMOVE TAC1,(JBUF) + .UMOVE ITEM,(TAC1) + LDB ITEM,[POINT 17,ITEM,17,] + SOJA ITEM,IOSETC + +OUTDMP: JRST DDO(DSER) ;DO DUMP OUTPUT AND RETURN TO USER + OUTA: TRNN UUO,777774 ;IS BUFFER ADR.SPECIFIED? + POPJ PDP, ;NO + HLRZ JBUF,DEVBUF(DEVDAT) + .UMOVE TAC,(JBUF) + HRRI TAC,(UUO) + HRRM UUO,DEVOAD(DEVDAT) + TLZ TAC,IOUSE + .UMOVM TAC,(JBUF) + POPJ PDP, + ;RELEASE A DEVICE + +RELEA0: +RELEA1: +RELEA2: +RELEA3: ANDCMI UUO,-1 ;CLOSE BOTH INPUT AND OUTPUT + PUSHJ PDP,CLOSE1 +; PUSHJ PDP,WAIT1 ;**** THIS PROBABLY ISN'T NEEDED *** +RELEA5: PUSHJ PDP,DRL(DSER) ;DO DEVICE-DEPENDENT STUFF + MOVEI IOS,IOACT ;CLEAR I/O ACTIVE BIT + ANDCAB IOS,DEVIOS(DEVDAT) ;AND SET IOS +;*** CODE NEEDED IF WE IMPLEMENT DTA'S *** + SETZB DAT,USRJDA(UCHN) ;CLEAR DEVICE ASSIGNMENT + .UMOVM DAT,JOBJDA(UCHN) + MOVE TAC,USRHCU ;THE COLLOWING CODE PERFORMS 2 FUNCTIONS. + ; (1) REDUCES USRHCU TO PROPER VALUE IF WE HAVE JUST RELEASED + ; HIGHEST USER CHANNEL ASSIGNED. (2) CHECKS IF DEVICE + ; CURRENTLY INITED ON ANOTHER CHANNEL, E.G. THE TTY. +RELEA4: HRRZ TAC1,USRJDA(TAC) + JUMPN DAT,RELE4A + MOVEI DAT,(TAC1) + MOVEM TAC,USRHCU +RELE4A: CAIE TAC1,(DEVDAT) + SOJGE TAC,RELEA4 + MOVE TAC1,USRHCU + .UMOVM TAC1,JOBHCU + JUMPGE TAC,CPOPJ ;JUMP IF WE FOUND A MATCH TO DEVDAT + ; IN ONE OF THE USER'S JDA ENTRIES + HLLZS DEVIAD(DEVDAT) ;CLEAR INPUT AND + HLLZS DEVOAD(DEVDAT) ;OUTPUT BUFFER ADDRESSES + +;CALLED HERE FROM "ESTOP" +RELEA9: +RELEA7: LDB TAC,PDEVI ;GET ITS CHANNEL # THIS ONE IS USING + CAIL TAC,FFITSC ;IS IT TO BE RETURNED? + PUSHJ PDP,RTFCHN ;YES, RETURN THE CHANNEL + DPB TAC,PDEVI ;COPY BACK OR CLEAR FIELD IN THE DDB. + LDB TAC,PDEVO ;GET ITS OUTPUT CHANNEL + CAIL TAC,FFITSC ;SHOULD WE RETURN IT? + PUSHJ PDP,RTFCHN ;YES, RETURN IT. + DPB TAC,PDEVO ;EITHER COPY BACK OR ZERO FIELD IN DDB + MOVEI TAC1,ASSPRG ;CLEAR "ASSIGNED BY PROG." BIT + +;CALLED HERE FROM "DEASSIGN" +RELEA6: ANDCAB TAC1,DEVMOD(DEVDAT) + TRNE TAC1,ASSCON+ASSPRG ;YES, CAN WE RETURN THE DDB? + POPJ PDP, ;NO, RETURN + ;YES - WE WILL RETURN DDB IF IT'S FOUND AFTER DSKDDB IN THE + ; CHAIN OF DDB'S. NOTE THAT THE DDB'S FOUND BEFORE AND + ; INCLUDING DSKDDB ARE PROTECTED FROM DELETION. + PUSH PDP,ITEM ;SAVE ITEM + PUSHJ PDP,CLRDDB ;RETURN DISK OR TTYNM DDB TO FREE STORAGE + JRST IPOPJ ;RESTORE ITEM AND RETURN + ;STATUS UUOS + +;CALL: STATO D,MASK +; EXIT1 ALL SELECTED BITS ARE 0 +; EXIT2 SOME SELECTED BITS ARE 1 +;TEST BITS OF I/O STATUS WORD OF DEVICE ON USER'S CHANNEL D WHICH +;ARE SELECTED BY MASK. + +USTATO: TRNE IOS,(UUO) ;SKIP RETURN IF ANY INDICATED BITS ARE 1 + AOS (PDP) + POPJ PDP, + + +;CALL: STATUS D,ADR +; EXIT ALWAYS RETURN HERE +;STORES I/O STATUS WORD OF DEVICE ON CHANNEL D IN LOC. ADR. + +USTATS: HRRZ TAC,IOS ;GET USER HALF OF IOS + JRST STOTAC ;ADR. CHECK AND STORE IN USER AREA + + +;CALL: STATZ D,MASK +; EXIT1 SOME SELECTED BITS ARE 1 +; EXIT2 ALL SELECTED BITS ARE 0 +;TST BITS OF I/O STATUS WORD OF DEVICE ON USER CHANNEL D WHICH +;ARE SELECTED BY MASK. + +USTATZ: TRNN IOS,(UUO) ;SKIP RET. IF ALL INDICATED BITS ARE 0. + AOS (PDP) + POPJ PDP, + ;IN UUO - LIKE INPUT, BUT SKIPS IF EOF OR ERRORS + +TIN: PUSHJ PDP,IN ;DO INPUT UUO + TRNE IOS,IOBKTL+IODTER+IODERR+IOIMPM+IODEND + AOS (PDP) + POPJ PDP, + + + +;OUT UUO - LIKE OUTPUT, BUT SKIPS IF ERRORS + +TOUT: PUSHJ PDP,UOUT ;DO OUTPUT UUO + TRNE IOS,IOBKTL+IODTER+IODERR+IOIMPM + AOS (PDP) + POPJ PDP, + ;ROUTINE TO ADVANCE OUTPUT BUFFER + +;CALL: PUSHJ PDP,ADVBFE +; EXIT1 NEXT BUFFER EMPTY +; EXIT2 NEXT BUFFER FULL + +ADVBFE: HRRZ TAC1,DEVOAD(DEVDAT) ;ADR. OF 2ND WORD OF LAST BUF. + JUMPE TAC1,CPOPJ ;RETURN IF CLEARED BY RELEASE + .UMOVM IOS,-1(TAC1) ;NO, STORE STATUS IN FIRST WORD + .UMOVE TAC,(TAC1) ;GET 2ND WORD + TLZ TAC,IOUSE ;CLEAR IOUSE + .UMOVM TAC,(TAC1) ;STORE BACK + MOVEI TAC,(TAC) ;ISOLATE NEXT BUFFER ADR. IN RH. + CAILE TAC,JOBPFI ;IS IT IN PROTECTED PART OF JOBDAT? + CAML TAC,USRREL ;NO, IS IT ABOVE HIS AREA? + POPJ PDP, ;YES, DON'T STORE NEXT ADR., BUT + ;CATCH THE ERROR LATER + HRRM TAC,DEVOAD(DEVDAT) ;NOW, STORE NEXT BUFFER ADR. + +;ENTER HERE FROM SCNSER TO CHECK IF NEXT BUFFER FULL OF DATA YET + +ADVBE1: .UMOVE TAC,@DEVOAD(DEVDAT) ;IS IOUSE = 0? + JUMPGE TAC,CPOPJ ;IF SO, EXIT1, BUFFER IS EMPTY + JRST ADVBF1 ;IF NOT, GO SEE IF USER TYPED ^C. + ;ROUTINE TO ADVANCE INPUT BUFFER +;CALL: PUSHJ PDP,ADVBFF +; EXIT1 ;NEXT BUFFER FULL +; EXIT2 ;NEXT BUFFER EMPTY + +ADVBFF: HRRZ TAC1,DEVIAD(DEVDAT) ;ADR. OF LAST INPUT BUFFER + JUMPE TAC1,CPOPJ ;RETURN IF CLEARED BY RELEASE + .UMOVM IOS,-1(TAC1) ;NO, STORE IOS IN FIRST WORD + .UMOVE TAC,(TAC1) ;GET 2ND WORD + TLO TAC,IOUSE ;IOUSE = 1 + .UMOVM TAC,(TAC1) ;STORE BACK + MOVEI TAC,(TAC) ;ISOALTE ADR. OF NEXT BUFFER IN RH + CAILE TAC,JOBPFI ;IN PROTECTED PART OF JOBDAT? + CAML TAC,USRREL ;NO, ABOVE HIS AREA? + POPJ PDP, ;YES, GIVE STOP RETURN + HRRM TAC,DEVIAD(DEVDAT) ;YES, STORE ADR. OF NEXT BUFFER + .UMOVE TAC1,(TAC) ;GET 2ND WORD OF NEXT BUFFER + JUMPL TAC1,CPOPJ ;GIVE STOP RETURN IF NEXT INPUT BUFFER + ;IS STILL FULL + HLRZ TAC1,TAC1 ;GET LENGTH OF BUFFER INTO RH + ADDI TAC,(TAC1) ;FORM ADR. OF LAST WORD + CAMLE TAC,USRREL ;IN BOUNDS? + POPJ PDP, ;NO, GIVE STOP RETURN; WE'LL SCREW HIM LATER +ADVBF1: SKIPGE TAC,JBTSTS ;IS RUN BIT ON? + TRNE IOS,IOCON ;YES, IS IT NON-DISCONTINUOUS MODE? + POPJ PDP, ;NO, STOP RETURN + JRST CPOPJ1 ;YES, GO RETURN + ;ROUTINE TO ADDRESS CHECK AT UUO LEVEL ONLY +;CALL HRRZ AC1,REL. ADR. +; PUSHJ PDP,UADCK1 +; NEVER RETURNS IF ERROR, STOPS JOB AND PRINTS ERROR +;BAD ADR. IF IN LOC. 20-JOBPFI IN JOB DATA AREA +; OR IF ABOVE C(USRREL) + +UADCK1: TRNN AC1,777760 ;IN USER AC'S ? + POPJ PDP, ;YES, ADR. IS OK + +;SAME AS ABOVE BUT AC'S ARE ILLEGAL ALSO + +UADRCK: CAILE AC1,JOBPFI ;IS ADR. IN I/O PROTECTED PART OF JOBDAT? + CAMLE AC1,USRREL ;NO, IS IT ABOVE PROT.? + JRST ADRERR ;YES, STOP JOB AND PRINT ERROR + POPJ PDP, ;NO, OK! + +;ROUTINE TO ADR. CHECK AT ANY LEVEL +;CALL HRRZ TAC,REL. ADR. +; PUSHJ PDP,IADRCK +; ERROR RETURN +; OK RETURN + +IADRCK: CAILE TAC,JOBPFI ;IN PROTECTED PART OF JOBDAT? + CAMLE TAC,USRREL ;NO, ABOVE PROT.? + POPJ PDP, ;YES, ERROR RETURN + JRST CPOPJ1 ;NO, OK RETURN + ;ROUTINE TO CHECK VALIDITY OF A DUMP MODE COMMAND LIST + +;CALL: MOVE UUO,[XWD 0 REL.ADR. OF FIRST COMMAND] +; PUSHJ PDP,COMCHK +; ADR. CHECK RETURN +; OK RETURN - SUM OF LH OF IOWDS IN DAT +; ADR. OF FIRST IOWD WITH NEG. LH IN UUO + +COMCHK: PUSH PDP,UUO ;SAVE POINTER TO LIST + PUSH PDP,AC2 + MOVEI AC1,JOBPFI ;ALR. OF HIGHEST I/O PROTECTED LOC. + ;IN JOB DATA AREA + SKIPGE USRHCU ;SAVE OR GET IN PROGRESS? + MOVEI AC1,JOBSAV ;YES, HIGHEST LOC. NOT WRITTEN BY SAVE + SETZB DAT,AC2 ;CLEAR WORD COUNT & ADR. OF FIRST IOWD + MOVEI ITEM,100 ;"ONLY" 100 LISTS!! ?(HA, HA)? + JRST COMCK1 +COMCK0: HRRI UUO,(TAC1) ;CHANGE COMMAND LIST POINTER + ;ON "GO TO" WORD + HRRI TAC,(TAC1) ;SET UP TAC FOR IADRCK + PUSHJ PDP,IADRCK + JRST COMCKE ;BAD ADR. +COMCK1: SOJLE ITEM,COMCKE ;EXCEEDED 100 YET? + .UMOVE TAC1,(UUO) ;NO, GET NEXT IOWD + JUMPE TAC1,COMCK2 ;MOVE ON IF END OF LIST + JUMPG TAC1,COMCK0 ;NO, IS IT "GO TO" WORD? + HLRE TAC,TAC1 ;NO, SAVE NEG. WORD COUNT + MOVEI TAC1,(TAC1) ;GET LOWEST ADR.-1 + CAIGE TAC1,(AC1) ;IS IT GREATER THAN LOC. PROTECTED + ;FROM I/O ? + JRST COMCKE ;NO, ERROR RETURN + SUB TAC1,TAC ;YES, COMPUTE LAST LOC. + CAMLE TAC1,USRREL ;IN BOUNDS? + JRST COMCKE ;NO, ERROR RETURN + SUB DAT,TAC ;YES, ACCUMULATE WORD COUNT + JUMPE AC2,.+2 ;IS THIS FIRST IOWD? + MOVE AC2,UUO ;YES, SAVE ADR. IN AC2 + AOJA UUO,COMCK1 ;GET NEXT IOWD + +COMCK2: JUMPE AC2,.+2 ;ANY IOWD'S WITH LH NEGATIVE? + MOVE UUO,AC2 ;YES, POINT UUO AT FIRST ONE + POP PDP,AC2 ;RESTORE THIS AC + JRST TPOPJ1 ;REMOVE SAVED UUO AND SKIP RETURN + +COMCKE: POP PDP,AC2 + POP PDP,UUO ;RESTORE ORIGINAL UUO + POPJ PDP, ;ERROR RETURN + CLOSE1: +; PUSHJ PDP,WAIT1 ;PROBABLY DON'T NEED THIS **** + TRNN UUO,CLSIN ;SUPPRESS INPUT CLOSE? + TLOE DEVDAT,ICLOSB ;NO, HAS IT ALREADY BEEN CLOSED? + JRST UCLS2 ;YES + LDB TAC,PIOMOD ;NO, GET I/O MODE + CAIGE TAC,SD ;DUMP MODE? + JRST UCLSBI ;NO, CLOSE BUFFERED INPUT +UCLS5: PUSHJ PDP,DCLI(DSER) ;YES, DO DEVICE-DEPENDENT STUFF + JRST UCLS2 ;WHICH BETTER NOT DESTROY UUO, DEVDAT, + ;UCHN, OR DSER +UCLSBI: MOVE TAC,DEVMOD(DEVDAT) + TLNE DEVDAT,INPB+INBFB ;WAS AN INPUT BUFFER SET UP? + JRST UCLS4 ;YES + TLNE TAC,DVDSK ;NO, ARE WE CLOSING A DISK FILE? + JRST UCLS5 ;YES, DO DEVICE-DEPENDENT ANYWAY + JRST UCLS2 ;NO, CLOSE OF INPUT NOT NECESSARY + +UCLS4: TLNE TAC,DVLNG ;IS THIS A LONG DISPATCH TABLE? + PUSHJ PDP,DCLI(DSER) ;YES, CLOSE INPUT + HRRZ TAC1,DEVBUF(DEVDAT) ;GET ADR. OF USER'S INPUT BUFFER + .UMOVE DAT,(TAC1) ;GET FIRST WORD OF 3-WORD HEADER + ANDI DAT,-1 ;RH ONLY + MOVEI TAC1,(DAT) ;SAVE A COPY + JUMPE DAT,UCLS1 ;HAS A RING BEEN SET UP? + MOVEI AC1,(DAT) ;YES, IS ADR. SPECIFIED BY CONTENTS OF + PUSHJ PDP,UADRCK ;FIRST WORD IN BOUNDS? + SETZ AC1, ;YES, CLEAR +UCLS0: .UMOVE DAT,(DAT) ;ADVANCE CURRENT INPUT BUFFER ADR. + CAIN AC1,(DAT) ;IS THIS SAME BUFFER AS LAST ONE? + JRST UCLS1 ;YES, BAD RING - IT IS LOOPING ON SELF + MOVEI AC1,(DAT) ;NO, IS ADR. OK? + PUSHJ PDP,UADRCK + .UMOVE TAC,(DAT) ;YES, CLEAR USE BIT + TLZ TAC,IOUSE + .UMOVM TAC,(DAT) + CAIE TAC1,(DAT) ;DONE? + JRST UCLS0 ;NO + +UCLS1: HRRZ DAT,DEVBUF(DEVDAT) + .UMOVE TAC,(DAT) + TLO TAC,IOUSE ;FLAG AS VIRGIN BUFFER IN 3-WORD HEADER + .UMOVM TAC,(DAT) + SETZ TAC, + .UMOVM TAC,2(DAT) ;CLEAR INPUT ITEM COUNT + MOVE IOS,[XWD IOEND IODEND] + ANDCAB IOS,DEVIOS(DEVDAT) + UCLS2: TRNN UUO,CLSOUT ;SUPPRESS OUTPUT CLOSE? + TLOE DEVDAT,OCLOSB ;NO, OUTPUT ALREADY CLOSED? + JRST UCLS3 ;YES + LDB TAC,PIOMOD ;NO + CAIGE TAC,SD ;IS IT DUMP MODE? + JRST UCLSBO ;NO, CLOSE BUFFERED OUTPUT +UCLS7: PUSHJ PDP,DCL(DSER) ;YES, DO DEVICE-DEPENDENT + JRST UCLS3 + +UCLSBO: TLNN DEVDAT,OUTBFB+OUTPB ;WAS AN OUTPUT BUFFER SET UP? + JRST UCLS6 ;NO + HLRZ DAT,DEVBUF(DEVDAT) ;VIRGIN OUTPUT BUFFER? + .UMOVE TAC,(DAT) + JUMPLE TAC,UCLS6 ;YES, DON'T CLOSE UNLESS IT IS DISK +UCLS2A: MOVE DSER,DEVSER(DEVDAT) ;NO, HAS SERVICE ROUTINE + .UMOVE TAC,@DEVOAD(DEVDAT) ;WRITTEN NEXT BUFFER YET ? + JUMPGE TAC,UCLS2B ;YES + ANDCMI IOS,760000 ;NO, CLEAR ERROR BITS AND START + ;OUTPUT DEVICE + PUSH PDP,UUO + PUSHJ PDP,DOU(DSER) ;CALL SERVICE ROUTINE TO DO OUTPUT + POP PDP,UUO +;** PUSHJ PDP,WAIT1 ;PROBABLY UNNECESSARY *** + TRNN IOS,760000 ;ERROR? + JRST UCLS2A ;NO, RETURN WHEN ALL EMPTIED + +UCLS2B: MOVE DSER,DEVSER(DEVDAT) + PUSHJ PDP,DCL(DSER) ;CLOSE OUTPUT BUFFER + HLRZ DAT,DEVBUF(DEVDAT) + .UMOVE TAC,(DAT) + TLO TAC,IOUSE + .UMOVM TAC,(DAT) + SETZ TAC, + .UMOVM TAC,2(DAT) ;JBFCTR = 0 +;** PUSHJ PDP,WAIT1 ;PROBABLY UNNECESSARY *** + TLO DEVDAT,OCLOSB ;SET OCLOSB AFTER OUTPUT IS COMPLETE +UCLS3: MOVEM DEVDAT,USRJDA(UCHN) + .UMOVM DEVDAT,JOBJDA(UCHN) + POPJ PDP, + +UCLS6: MOVSI TAC,DVDSK ;CLOSING A DISK FILE? + TDNE TAC,DEVMOD(DEVDAT) + JRST UCLS7 ;YES, DO DISK CLOSE ANYWAY + JRST UCLS3 ;NO, FINISH UP + ;ROUTINE TO RELEASE ALL DEVICES ASSIGNED TO JOB + +IORELS: MOVEI TAC,RELEA3 ;RELEASE ALL I/O DEVICES ( DON'T CLOSE ) +IOALL: PUSH PDP,TAC ;SAVE ADR. OF SUBROUTINE + PUSH PDP,UUO ;SAVE UUO + SETZB UCHN,UUO ;START WITH USER CHANNEL # 0 + +IOALL1: CAMLE UCHN,USRHCU ;IS IT GREATER THAN HIGHEST + ;CHANNEL USED? + JUMPN UCHN,IOALL2 ;YES, RETURN - BUT, IF USRHCU IS NEG., ASSUME + ;SAVGET WHICH USES CHANNEL 0. + SKIPN DEVDAT,USRJDA(UCHN) ;GET DDB FOR THIS CHANNEL; + ;IS IT IN USE? + AOJA UCHN,IOALL1 ;NO, KEEP GOING + MOVE IOS,DEVIOS(DEVDAT) ;YES, SET UP FOR SUB. CALL + DPB UCHN,PUUOAC + MOVE DSER,DEVSER(DEVDAT) + PUSHJ PDP,@-1(PDP) ;CALL THE SPECIFIED SUBROUTINE + AOJA UCHN,IOALL1 ;CONTINIUE WITH NEXT CHANNEL +IOALL2: POP PDP,UUO ;RESTORE UUO + SETZ ITEM, ;RESET JOB # + JRST TPOPJ ;RESTORE TAC AND RETURN + + +;KILL ALL DEVICES (RELEASE WITHOUT WAITING FOR DEVICE INACTIVE) + +IOKILL: MOVEI TAC,RELEA5 ;SET UP ADR. OF SUB. + PUSHJ PDP,IOALL ;RELEASE WITHOUT WAITING + + +;ROUTINE TO CLEAR PROTECTED JOB DATA AREA IN MONITOR +;AND RECLAIM FREE AREA ABOVE USER PROGRAM FOR I/O BUFFERS + +SETUSR: .UMOVE TAC,JOBSA ;RESET FIRST FREE LOC. FOR THIS JOB + HLRZ TAC,TAC + .UMOVM TAC,JOBFF + +CLRUSR: SETZ TAC, ;INITIALIZE APR TRAPPING + .UMOVM TAC,JOBHCU ;CLEAR HIGHEST CHANNEL IN USE + MOVEI TAC,USRLO1 ;CLEAR SOME OF JOBDAT + HRLI TAC,USRLO + SETZM USRLO + BLT TAC,USRHI + SETZM USRHCU + MOVEI TAC,JOBLO ;CLEAR IT IN PROCEDURE ALSO + HRLI TAC,USRLO + .UBLTO TAC,JOBHI + POPJ PDP, + ;ASSIGN DEVICE IF UNASSIGNED +;CALL: MOVE DEVDAT,ADR. OF DDB +; MOVEI TAC1, EITHER ASSPRG OR ASSCON +; PUSHJ PDP,ASSASG +; CAN'T ASSIGN RETURN +; ASSIGNED RETURN + +ASSASG: MOVSI TAC,DVDSK ;SET UP "I'M A DISK" BIT + TDNE TAC,DEVMOD(DEVDAT) ;IS THIS A DSK? + PUSHJ PDP,SETDDB ;YES - GET A DSK DDB +ASSAS1: IORM TAC1,DEVMOD(DEVDAT) ;SET WHICHEVER ONE HE WANTS + JRST CPOPJ1 ;GIVE GOOD RETURN + ;SEARCH FOR DEVICE WHOSE NAME IS IN TAC +;SEARCH FOR LOGICAL NAME FIRST. + +DEVSRC: PUSHJ PDP,DEVLG ;SEARCH LOGICAL NAMES FIRST + JRST DEVPHY ;NOT FOUND, SEARCH PHYSICAL NAMES + JRST CPOPJ1 ;FOUND, GIVE SKIP RETURN + +DEVLG: HLRZ DEVDAT,DEVLST ;BEGINNING OF DDB CHAIN +DEVLP0: CAMN TAC,DEVLOG(DEVDAT) ;EQUAL LOGICAL NAME? + JUMPN TAC,CPOPJ1 ;YES, BUT GOOD ONLY IF NON-ZERO +DEV0: HLRZ DEVDAT,DEVSER(DEVDAT) ;NO, KEEP LOOKING + JUMPN DEVDAT,DEVLP0 + POPJ PDP, ;NOT FOUND + + +;SEARCH PHYSICAL NAMES + +DEVPHY: MOVEI TAC1,SYSDEV ;START OFF ASSUMING "SYS" + CAME TAC,[SIXBIT /SYS/] ;IS THAT RIGHT? + TRZA TAC1,SYSDEV ;NO, TURN OFF FLAG + MOVSI TAC,(SIXBIT /DSK/) ;YES, USE DSK + HLRZ DEVDAT,DEVLST ;SEARCH DDB'S +DEVLP1: TLO DEVDAT,(TAC1) ;SET SYS. BIT IF ON + CAMN TAC,DEVNAM(DEVDAT) ;MATCH? + JUMPN TAC,CPOPJ1 ;YES, IF NAME NON-ZERO +DEVPH1: HLRZ DEVDAT,DEVSER(DEVDAT) ;NO, GET NEXT IN CHAIN + JUMPN DEVDAT,DEVLP1 ;CONTINUE IF NOT END + CAME TAC,[SIXBIT /TTY/] ;IS IT PUBLIC NAME "TTY"? + JRST GETDDB ;NO, SEE IF IT IS A TTYNN + PUSHJ PDP,TTYFND ;YES, FIND USER'S TTY DDB + JRST CPOPJ1 ;AND GIVE SUCCESSFUL RETURN + SUBTTL LUUO HANDLER + +.UMOVE=1_27. ;OPDEF FOR .UMOVE +.UMOVM=2_27. ;OPDEF FOR .UMOVM +.UBLTI=3_27. ;OPDEF FOR .UBLTI +.UBLTO=4_27. ;OPDEF FOR .UBLTO + +UUOHAN: PUSH PDP,TAC ;SAVE TAC + LDB TAC,P40AC ;GET THE AC FIELD FROM UUO IN 40 + CAIN TAC,TAC ;IS HE SPECIFYING AC "TAC" ? + MOVEI TAC,(PDP) ;YES, POINT TO ITS CONTENTS, SEEING AS WE + ;HAVE CLOBBERED THE AC ITSELF. + TLO TAC,777777 ;PUT -1 IN LH FOR POSSIBLE .IOT ON IT + PUSH PDP,TAC ;SAVE FOR LATER USE + LDB TAC,P40OP ;GET THE OP CODE FROM THE UUO + CAIG TAC,HIUUO ;IS IT IN RANGE? + JRST @UUDISP-1(TAC) ;YES, DISPATCH + JRST SYSERR ;NO, ERROR! + JRST .-1 + +UUDISP: UMOVE ;MOVE THE SPECIFIED LOC. IN INFERIOR + ;INTO THE SPECIFIED ACCUMULATOR + UMOVM ;STORE THE CONTENTS OF THE SPECIFIED + ;ACCUMULATOR INTO THE SPECIFIED LOC. + ;IN INFERIOR + UBLTI ;BLOCK TRANSFER FROM INFERIOR TO "SIM" + UBLTO ;BLOCK TRANSFER FROM "SIM" TO INFERIOR +HIUUO==.-UUDISP + +P40OP: POINT 9,40,8, ;BYTE POINTER TO OP-CODE FIELD OF UUO +P40AC: POINT 4,40,12, ;BYTE POINTER TO AC FIELD OF UUO + UMOVE: .ACCES UPRGI,40 ;SET UP TO ACCESS INFERIOR LOC. + .IOT UPRGI,(PDP) ;SUCK SPECIFIED WORD INTO RIGHT AC +T2POPJ: POP PDP,TAC ;REMOVE ONE STACK LOC. + JRST TPOPJ ;RESTORE TAC AND RETURN + +UMOVM: .ACCES UPRGO,40 ;SET UP DESTINATION ADR. + .IOT UPRGO,(PDP) ;SEND THE WORD THERE + JRST T2POPJ ;RESTORE AND RETURN + +;THIS SUBROUTINE GETS THE CONTENTS OF THE AC SPECIFIED IN +;THE UUO INTO TAC + +UUOSUB: LDB TAC,P40AC ;GET SPECIFIED AC + CAIN TAC,TAC ;IS IT TAC? + SKIPA TAC,-2(PDP) ;YES, GET CONTENTS OF TAC + MOVE TAC,(TAC) ;NO, GET OTHER CONTENTS + POPJ PDP, ;RETURN + +UBLTI: PUSHJ PDP,UUOSUB ;GET CONTENTS OF AC INTO TAC + MOVS TAC,TAC ;SWAP HALVES + .ACCES UPRGI,TAC ;ACCESS THE "FROM ADR." + HLRZ TAC,TAC ;ISOLATE "TO ADR." + MOVEM TAC,1(PDP) ;STORE TEMPORARILY + SUBI TAC,@40 ;FORM -LENGTH + HRLZI TAC,-1(TAC) + HRR TAC,1(PDP) ;PICK UP "TO ADR." + .IOT UPRGI,TAC ;MAKE TRANSFER + JRST T2POPJ ;RESTORE AND RETURN + +UBLTO: PUSHJ PDP,UUOSUB ;GET CONTENTS OF AC INTO TAC + .ACCES UPRGO,TAC ;ACCESS "TO ADR." + MOVEM TAC,1(PDP) ;STORE "FROM ADR." TEMPORARILY + SUBI TAC,@40 ;FORM -LENGTH + HRLZI TAC,-1(TAC) + HLR TAC,1(PDP) ;RESTORE "FROM ADR." + .IOT UPRGO,TAC ;MAKE TRANSFER + JRST T2POPJ ;RESTORE AND RETURN + ;** CLOCK1.MAC ** PAGE 4 + +;APR INTERRUPTS COME HERE +; IF FROM USER'S PROGRAM, WE FIRST GENERATED CLASS-3 INTERRUPT TO SUPERIOR. +; APRCHL: PC IN USER PROGRAM (INCL. USRMOD BIT) +; APRERR: I.T.S. PIRQC FLAGS FROM INFERIOR AT TIME OF INTERRUPT. +; IF FROM MONITOR, A CLASS-2 INTERRUPT WAS GENERATED TO BREAK FROM +; UUO CONTROLLER - THEN OPERATING AT CLASS-3 INTERRUPT LEVEL. +; APRCHL: PC IN MONITOR (NO USRMOD BIT) +; APRERR: I.T.S. PIRQC FLAGS OF SUPERIOR AT TIME OF INTERRUPT + +APRER: MOVE TAC,APRCHL ;GET PC + MOVE TAC1,APRERR ;USER ENABLED FOR THIS ERROR ? + TDNN TAC1,ITSENB + JRST APRER2 ;NO + SETZM APRERR + .UMOVM TAC,JOBTPC ;STORE PC IN JOB DATA AREA + ANDCM TAC1,[BIOADC\200000\AROIF\ARFOIF] ;CLEAR OUT ALL BUT MEANINGFUL BITS + + ;NOTE - WE WOULD ORDINARILY HAVE BPIPI(=4) SET DUE TO I.T.S. + ; METHOD OF INTERRUPTING SUPERIOR WHEN INFERIOR RECEIVED ENABLED + ; INTERRUPT IN UTRAP MODE. + + TLZE TAC1,(ARFOIF) ;ARFOIF FOUND ? + TRO TAC1,100 ;CHANGE TO FOV IF SO, ALSO RESETTING ARFOIF BIT + MOVE TAC,ITSENB + TLNE TAC,(ARFOIF) ;DIDDLE AC(TAC) TO MAKE IT LOOK LIKE A CONI APR, WORD. + TRO TAC1,200 ;C.F. PDP10 REFERENCE MANUAL, P 97. + TRNE TAC,AROIF + TRO TAC1,20 + TRZ TAC1,400000 ;CLEAR "LEAVE INTERRUPTS ENABLED" BIT + .UMOVM TAC1,JOBCNI + MOVE TAC1,ITSENB + TRNN TAC1,400000 ;DOES USER WANT TRAPS DISABLE WHENEVER ONE OCCURS + JRST APDSBL ;YES - DO SO + +APRER5: .UMOVE TAC,JOBAPR ;GET USER LOC TO TRAP TO + .USET UPRGO,[.SUPC,,TAC] ;SET STARTING ADDR + .USET UPRGO,[.SUSTP,,[0]] ;START HIM UP + POPJ PDP, ;RETURN TO INTERRUPT ROUTINE + +APDSBL: SETZM ITSENB ;NOTHING ENABLED FOR USER + .USET UPRGO,[.SMASK,,[BIOADC\BILLOP\200000]] + ;VIRGIN STATUS OF MASK - THE SAME AS WHEN PROCEDURE WAS CREATED + JRST APRER5 + ;** CLOCK1.MAC ** PAGES 5+7 + +APRER2: TRNE TAC1,BIOADC\200000 ;IS THIS A TRAP WE WISH TO SIGNAL + ; AS AN ERROR ? + JRST SAVPC ;SAVE A MONITOR PC SO THAT THE + ; USER WILL NOT CONFUSE JOBPC W/INTERRUPT LOCATION. + ; AT SAVPC: WE GO TO APRILM:[ERRCON] WHICH WILL GET + ; US TO HOLD:[CLOCK1] WHERE ERROR BIT WILL BE SET IN + ; JOB STATUS WORD. + JRST SYSERR ;YES + +;HERE WHILE PROCESSING A TELETYPE INPUT UUO AND WE ARE WAITING +; FOR CHARACTER OR STORED ^C SEEN. +;CALL: PUSHJ PDP,WSCHED +; RETURN HERE WHEN RUNNABLE AGAIN + +WSCHED: POP PDP,AC3 + TLZ AC3,USRMOD + MOVEM AC3,USRPC + .UMOVM AC3,JOBPC + MOVEI AC3,USRDAC ;COPY OUR AC'S TO DUMP AREA + BLT AC3,USRD16 + JRST USCHD1 + + +;HERE FROM UUO EXIT CODE WHEN JOB RETURNS TO UUO CONTROLLER WHERE +; RETURN PC NOW IN MONITOR MODE. PROGRAM MUST HAVE EXECUTED A +; SOFT EXIT (CALLI 1,12) OR A HALT. +;CALL: PUSHJ PDP,USCHED +; RETURN HERE WHEN JOB RUNNABLE + +USCHED: POP PDP,AC3 ;COLLECT RETURN ADDR INTO MONITOR + TLZ AC3,USRMOD ; AND RESET USRMOD BIT SO USER KNOWS WHAT'S UP + MOVEM AC3,USRPC + .UMOVM AC3,JOBPC + MOVEM PDP,USRDPD +USCHD1: MOVE AC3,USRPD1 + .UMOVM AC3,JOBPD1 + JRST RSCHED + ;** CLOCK1.MAC ** PAGES 8,9,+13 + +SAVPC: JSP TAC,.+1 ;GET A REASONNABLE PC + TLZ TAC,USRMOD ;RESET USER MODE BIT + MOVEM TAC,USRPC + SKIPE USRREL ;DON'T TRY TO WRITE INTO NON-EXISTENT INFERIOR + .UMOVM TAC,JOBPC + SKIPE TAC,APRERR ;IS THIS AN APR ERROR OR AN ERROR STOP ? + JRST APRILM ;APR ERROR-TYPE ERROR MESSAGE. + JRST RSCHED ;ELSE WAIT FOR USER TO DO SOMETHING. + +RSCHED: JRST PW2IB ;GO WAIT FOR USER TO TYPE IN SOMETHING. + ; A COMMAND WOULD BE NICE IF WE'RE IN TPMON-MODE. + ; ELSE ANY ODL CHAR WILL DO. + +;ROUTINE TO SET SOFTWARE RELOCATION INFORMATION FOR USER +;CALLED FROM: +; CORE ROUTINE WHEN CORE REASSIGNED FOR CURRENT USER +; CORE UUO +; REMAP UUO +; CALL RESET UUO +; +;CALL: STORE PROTECTION FOR SEG IN JBTADR+1 +; PUSHJ PDP,SETREL +; ALWAYS RETURN, C(ITEM)=JOB # (=0) +; C(PROG)=XWD PROT,,0 FOR LOWSEG + +SETREL: MOVE PROG,JBTADR + HLRZM PROG,USRREL + JUMPE PROG,SETHRD + MOVE PROG,USRREL + .UMOVM PROG,JOBREL + MOVE PROG,JBTADR +SETHRD: POPJ PDP, + + ;** CLOCK1.MAC ** PAGES 14+16 + +;ROUTINE TO ENABLE/DISABLE APR TRAPPING FROM INFERIOR +;CALL: MOVEI TAC,APR CONSO FLAGS, DEC STYLE +; PUSHJ PDP,SETAPR +; RETURN W/APR RESET + +;FOR I.T.S., WE HAVE THE FOLLOWING INTERRUPT REQUEST TRANFORMATIONS. +;WE OBSERVE THEM TO SET UP PROPER PIRQC MASK. +; +; DEC BIT ITS BIT +; 400000 D.N.A.(="REPETITIVE ENABLE") +; 200000(PDL) SAME(UNNAMED) +; 20000(MEM PROT) SAME=BIOADC) +; 100(FOV) 400,,(=ARFOIF) +; 10(AROV) SAME(=AROIF) + +SETAPR: ANDI TAC,620110 + TRZE TAC,100 ;FOV -> + TDO TAC,[ARFOIF] ; ARFOIF + MOVEM TAC,ITSENB + .USET UPRGO,[.RMASK,,TAC] + AND TAC,[ARFOIF\AROIF] ;ALWAYS LEAVE PDL OVF + ILL MEM ON + IOR TAC,ITSENB + TRZ TAC,400000 ;WE DON'T WANT TO SET THIS D.N.A. BIT + .USET UPRGO,[.SMASK,,TAC] ;ENABLE HIM FOR DESIRED TRAPPING CONDITIONS + POPJ PDP, + +;ROUTINE TO STOP JOB, SET ERROR BIT, AND PRINT MESSAGE +;THEN ADD ^C +;CALL: MOVEI TAC,ADDR. OF MESSAGE +; PUSHJ PDP,PHOLD + +PHOLD: PUSHJ PDP,CONMES +HOLD: PUSHJ PDP,INLMES + ASCIZ / +^C +./ +HOLD1: PUSHJ PDP,TTYSTC ;MAKE SURE TTY STAYS IN MONITOR MODE + ; FALL INTO ESTOP + ;** CLOCK1.MAC ** PAGES 17+18 + +;ROUTINE TO STOP USER AND FLAG AS ERROR STOP + +ESTOP: + +;ESTOP1: ;ESTOP1 CALLED ONLY FROM CLRJOB: (IN CORE1). + ; CLRJOB: CALLED ONLY FROM SYSINI. I DON'T THINK WE NEED + ; ESTOP1. + + MOVSI TAC,JERR ;SET ERROR BIT + IORM TAC,JBTSTS ;SO 'CONTINUE' WON'T WORK + + MOVE TAC,TTYOIP + JUMPE TAC,.+4 + AOJE TAC,.+2 + .RESET CTYI, + SETZM TTYOIP + ;FALL INTO STOP1 BELOW + +;ROUTINE TO STOP ANY JOB +;CALL: PUSHJ PDP,STOP1 +; EXIT + +STOP1: MOVSI TAC,RUN + TDNN TAC,JBTSTS ;RUNNING ? + JRST STOP1A ;NO + ANDCAM TAC,JBTSTS ;YES - BUT IT WON'T BE BY THE TIME WE'RE DONE + + .USET UPRGO,[.RUSTP,,TAC] ;IS USER ALREADY STOPPED ? + TLNN TAC,100000 ;I.E. IS BIT ON ? + JRST STOP1B ;NO - STILL RUNNING + MOVSI TAC,377 + ANDCAM TAC,INTR + .USET UPRGO,[.RPIRQC,,TAC] ;STOPPED - ARE THERE REQUESTS PENDING ? + TDZN TAC,[BUTRAP\BIOADC\BILLOP\200000\AROIF\ARFOIF] + JRST STOP1A ;NO - MUST HAVE BEEN LEFT IN MONITOR WAITING + ; AND FOUND THE ^C -- OR CALLI 12 CAME HERE, PC ALREADY SAVED + ; -- OR HALT SEEN +STOP1B: .USET UPRGO,[.SUSTP,,[100000,,0]] ;STOP HIM +STOP1C: .USET UPRGO,[.RUPC,,USRPC] + MOVE TAC,USRPC + .UMOVM TAC,JOBPC + .USET UPRGO,[.RPIRQC,,TAC] + TDZN TAC,[BUTRAP\BIOADC\BILLOP\200000\AROIF\ARFOIF] + JRST STOP1A + .USET UPRGO,[.SPIRQC,,TAC] ;RESET POSSIBLE INFERIOR INTERRUPT BITS + .SUSET [.SIFPIR,,[400000,,0]] ;PREVENT A STOPPED USER FROM + ;CAUSING SPURIOUS INTERRUPTS. + MOVE TAC,USRPC ;NOW DROP PC BACK 1 LOCATION + HRRI TAC,-1(TAC) + MOVEM TAC,USRPC + .UMOVM TAC,JOBPC + +STOP1A: MOVEI TAC,NULPDL ;NOW TO TELL WHETHER WE ARRIVED HERE VIA A + ; UUO OR A COMMAND + CAIGE TAC,(PDP) ;IF PD STACK POINTS TO SOMEWHERE IN NPDL, THEN + ; WE ARRIVED VIA A COMMAND + POPJ PDP, ;AND IF SO, RETURN + MOVE TAC,JBTSTS ;ERROR IN JOB ? + TLNE TAC,JERR + JRST SAVPC ;YES - SAVE A MONITOR PC SO USER KNOWS + ; THAT HE DIDN'T COME FROM THERE + POPJ PDP, ;RETURN TO CALLER IF WE STOPPED W/O + ; ERR'ING -- SPECIFICALLY BY "HALT" COMMAND OR VIA A SOFT + ; EXIT OR VIA A PROGRAM HALT + ;** CLOCK1.MAC ** PAGES 20+21 + +;ROUTINE TO SETUP AC'S FOR MONITOR JOB STARTING AT UUO LEVEL. +; SETS UP PROG W/PROTECTION AND PDP W/PUSHDOWN POINTER TO LIST WHICH +; WOULD ORDINARILY BE IN USER'S JOB DATA AREA + +MONSTR: MOVE PROG,JBTADR ;SET UP PROG + MOVE PDP,UPDP ;START UP POINTER TO USEFFUL PC + HRRZ TAC1,TAC1 ;THIS TURNS OF USER MODE BIT + PUSH PDP,TAC1 ;EXEC JOB ABOUT TO START ! + JRST (TAC) ;RETURN AND DO MONITOR JOB + +;1. TAC1=ESTOP IF CALLED BY CORE0 -> ESTOP MEANS THAT THERE MAY BE +; NO CONTINUE AFTER A CORE 0. +;2. TAC1 IMMATERIAL WHEN CALLED BY FINISH. +;3. TAC1=RETURN FROM SG1 WHEN CALLED FROM SG1. (SG1 ED BY A +; JSP TAC1,SG1.) THEN THE PDPJ PDP, AT END OF SG1: WINS. +; SG1->CALLED FROM: +; GETJOB P 70 COMCON +; RUNJOB P 70 COMCON +; SAVJOB P 67 COMCON + +;ROUTINE TO SET JOB READY TO RUN +;CALL: MOVE TAC1,STARTING PC +; PUSHJ PDP,USTART(PC TO USER MODE),MSTART(PC TO MONITOR MODE) +; RETURN IMMEDIATELY + +USTART: MOVE TAC,USRPC ;GET OLD PC + TLNE TAC,USRMOD ;IN USER MODE ? + JRST USTRT1 ;YES + MOVE TAC,USRPD1 ;NO - IT MUST HAVE BEEN A UUO THEREFORE + ; (OR A PROGRAM HALT) + HRRI TAC,-1(TAC) ;ADDRESS IN USER CORE MAY BE FOUND IN FIRST + ;LOCATION OF STACK +USTRT1: .UMOVM TAC,JOBOPC + HLL TAC1,TAC ;PRESERVE USER APR FLAGS + TLO TAC1,USRMOD ;MAKE USRE PC IN USWER MODE + TLZ TAC1,37 ;+ NO INDIRECT BITS OR INDEX FLAG. + +;MSTART - CALLED FROM COMMAND DECODER AT 'SAVE', 'GET', +; 'REASSIGN', AND 'FINISH'. +;ALSO CALLED VIA MONJOB FROM 'KJOB' AND 'CORE 0.' +;ALSO EXECUTED WHEN USTART: DROPS THROUGH + +MSTART: + MOVEM TAC1,USRPC + .UMOVM TAC1,JOBPC + MOVSI TAC,JERR ;CLEAR ERROR BIT + ANDCAM TAC,JBTSTS + JRST TTYSET ;SET TTY TO INITIAL CONDITION + ;** CLOCK1.MAC ** PAGES 22+29 + +;SETS JOB TO RUN - ESSENTIALLY COMBINES AXN OF SETRUN AND +; CONTEXT SWITCHING AT CIP7: + +SETRUN: MOVSI TAC,RUN + IORM TAC,JBTSTS + MOVE TAC,USRPC ;DO WE GO TO USER OR MONITOR (VIA MSTART) ? + TLNE TAC,USRMOD ;AND NOW, WE CHECK + JRST SETR3 + MOVSI 17,USRDAC ;RESTORE PC'S + BLT 17,16 + JRST @USRPC ;TO MONITOR + +SETR3: .USET UPRGO,[.SUPC,,USRPC] + .USET UPRGO,[.SUSTP,,[0]] ;START HIM UP HERE + POPJ PDP, + +;WSYNC IS CALLED TO WAIT UNTIL SETIOD IS CALLED BY INTERRUPT SERVICE ROUTINE - +; AND THERE ONLY ACTIVE INTERRUPTS NOW WILL BE THOSE FROM THE TTY. + +; WE ARRIVE HERE EXCLUSIVELY FROM THE TTY ROUTINE. AT TYWYNC: WE ARRIVE +; WITH BITS TTYIOW SET IN AC(IOS). FROM MONUS6: (STORED ^C), WE ALSO HAVE +; TPMON SET. WE NOW PUT OURSELVES INTO I/O WAIT STATE - TO BE +; CHECKED BY OUR TTY INTERRUPT ROUTINE AFTER CHARACTERS HAVE BEEN INPUT + +WSYNC: MOVSI IOS,IOW ;SETUP I/O WAIT + IORM IOS,DEVIOS(DDB) + PUSHJ PDP,WSCHED + ANDCAB IOS,DEVIOS(DDB) ;RETURNS HERE + POPJ PDP, + ;** COMCON.MAC ** + +;TEMPORARY ACCUMULATORS + +T==BUFPNT +T1==BUFWRD +T2==UUO +T3==AC1 +T4==AC2 + +COMMAND: + + MOVEI DAT,TTIBUF(DEVDAT) ;THIS ALLOWS US TO DO GETCHR'S + ;NOTE: ACCUMULATORS ARE ALREADY SET UP HAVING BEEN + ; STARTED UP BY OUR GENERAL CONSOLE INTERRUPT ROUTINE. + ; WE FOUND THAT THE TTY IS IN MONITOR MODE AND THAT A BREAK + ; CHARACTER WAS JUST SEEN. + + MOVE LINE,TITCTR(DDB) + DPB LINE,PCOMIC ;SAVE COMMAND INPUT COUNTER + MOVEI ITEM,0 ;THAT'S THE JOB NUMBER WE SET OURSELVES TO BE + PUSH PDP,DEVDAT + PUSHJ PDP,CTEXT ;SCAN COMMAND NAME, RETURN IT IN AC(TAC1) + MOVE T,TAC1 ;COPY COMMAND + MOVNI T1,1 ;SET MASK ALL ONES + LSH T1,-6 ;CLEAR OUT ONE MORE CHAR + LSH T,6 ;SHIFT 1 COMMAND CHAR OFF + JUMPN T,.-2 ;IF NOT END OF COMMAND, GO BACK + MOVEI T4,0 + MOVSI T,-DISPL ;SEARCH COMMAND TABLE FOR MATCH +COMLP: MOVE T2,COMTAB(T) ;GET NEXT ENTRY FROM COMMAND TABLE + TDZ T2,T1 ;MASK OUT CHAR 5 + CAMN TAC1,COMTAB(T) ;EXACT MATCH ? + JRST COMFND ;YES, THIS IS IT + CAME TAC1,T2 ;MATCH WITH MASK ? + JRST COMNEQ ;NO, NOT EVEN THEN + TROE T4,1 ;MATCHES W/MASK, IS THIS FIRST ? + TROA T4,2 ;NO, TELL OURSELVES THAT + MOVE T3,T +COMNEQ: AOBJN T,COMLP ;NO, KEEP LOOKING + CAIN T4,1 ;DID ONE AND ONLY ONE COMMAND MATCH ? + MOVE T,T3 ;YES, GET ITS INDEX + ;IF NOT --- THEN WE LET DISPATCH ENTRY FALL THROUGH TIL LAST, + ; LAST ENTRY IS THE ERROR DISPATCH + ;** COMCON.MAC ** PAGES 3,4,5+6 + +COMFND: MOVE TAC1,DISP(T) ;GET DISPATCH TABLE ENTRY + PUSH PDP,TAC1 ;SAVE RH(DISPATCH ADDR.+BITS) + MOVE T,JBTSTS ;COLLECT JOB STATUS WORD FOR OURSELVES + +CHKRUN: TLNE T,RUN ;RUN BIT ON ? + TLNN TAC1,NORUN ;AND IS THAT OK ? + JRST CHKACT ;YES + JSP TAC,COMER + ASCIZ /?Please type ^C first +/ + +CHKACT: MOVE PROG,JBTADR ;XWD PROTECTION,RELOCATION + TLNE TAC1,NOCORE ;NEED CORE ? + JRST COMGO ;NO - NO NEED TO CHECK ANY FURTHER + JUMPN PROG,COMGO ;BETTER HAVE SOME + JSP TAC,COMER + ASCIZ /?No core assigned +/ + +COMER: MOVEI TAC1,CERR + +COMGO: +COMDIS: + MOVEI IOS,0 + PUSHJ PDP,(TAC1) + +;RETURN FROM COMMAND SETUP ROUTINE + +COMRET: POP PDP,T1 + POP PDP,DEVDAT + LDB TEM,TITAKR(DEVDAT) + PUSHJ PDP,SKPBRK + SOS TISYNC(DEVDAT) + JUMPGE ITEM,PCRLF + MOVSI T1,ERRFLG + ;** COMCON.MAC ** PAGES 7+8 + +PCRLF: TLNN T1,NOCRLF ;SUPPRESS CRLF ? + PUSHJ PDP,CRLF ;NO + TLNN T1,NOPER ;SUPPRESS PRINTING PERIOD ? + PUSHJ PDP,PRPER ;NO + JUMPL ITEM,PCRLF1 + TLNE T1,TTYRNU ;JOB TO RUN IN USER MODE ? + PUSHJ PDP,TTYUSR + TLNE T1,TTYRNC + PUSHJ PDP,SETRUN + POPJ PDP, + +PCRLF1: POPJ PDP, + + +SKPBRK: PUSH PDP,TAC +SKPBR2: PUSHJ PDP,SPCHEK + JRST SKPBR1 + TLNE TAC,BREAKB ;IS THIS THE BREAK ? + JRST TPOPJ ;YES - RETURN +SKPBR1: PUSHJ PDP,GETCHR ;GET ANOTHER + JUMPN TEM,SKPBR2 ;IS IT IS ? + MOVEI TEM,12 ;NO MORE - FORCE A BREAK + DPB TEM,TITAKR(DEVDAT) + JRST TPOPJ ;AND RETURN + +;TABLE OF CONSOLE COMMANDS + +;BITS CHECKED BEFORE DISPATCHING TO COMMAND SETUP ROUTINE + +NOCORE==400000 ;NO CORE NEEDED FOR COMMAND +NORUN==10000 ;CANNOT BE EXECUTED WHILE JOB IS RUNNING + +;BITS CHECK AFTER RETURN FROM COMMAND SETUP ROUTINE + +NOCRLF==200 ;NO PRINTING OF +NOPER==100 ;NO PRINTING OF PERIOD +TTYRNU==40 ;SET TTY TO USER MODE AND START JOB +TTYRNC==20 ;KEEP TTY IN COMMAND MODE AND START JOB +ERRFLG==1 ;COMMAND ERROR + ;** COMCON.MAC ** PAGE 9 + +DEFINE NAMES + C []CBLANK,NOCORE\NOCRLF + C START,START,NOPER\TTYRNU\NORUN + C HALT,STOP,NOCORE + C R,RCOM,NOCORE\NOPER\TTYRNU\NORUN + C RUN,RUNCOM,NOCORE\NOPER\TTYRNU\NORUN + C CORE,CORE,NOCORE\NORUN + C GET,GET,NOCRLF\NOPER\TTYRNC\NOCORE\NORUN + C SAVE,SAVE,NOCRLF\NOPER\TTYRNC\NORUN + C CONTIN,CONT,NOPER\TTYRNU\NORUN + C D,DCOM + C E,ECOM,NOCRLF + C PJOB,PJOB,NOCORE + C ASSIGN,ASSIGN,NOCORE + C DEASSI,DEASSI,NOCORE + C DDT,DDTGO,NOPER\TTYRNU\NORUN + C FINISH,CFINI,TTYRNC\NORUN + C REENTE,REENTE,TTYRNU\NOPER\NORUN + C CSTART,STARTC,TTYRNC\NORUN + C CCONTI,CCONT,TTYRNC\NORUN + C DAYTIM,DAYTIM,NOCORE + C TIME,RUNTIM,NOCORE + C RESOUR,FREDEV,NOCORE + C COMPIL,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C COPY,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C CREF,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C DEBUG,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C DELETE,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C DIRECT,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C EXECUT,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C LIST,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C LOAD,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C MAKE,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C RENAME,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C TECO,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C TYPE,CCLRUN,NOCORE\NOPER\TTYRNU\NOCRLF\NORUN + C LOGIN,LOGIN,NOCORE\NOPER\NOCRLF\NORUN + C KJOB,LOGOUT,NOCORE\NOPER\NOCRLF\NORUN + C HELP,HELP,NOCORE + C PPPN,PPN,NOCORE + C SNAME,SNA,NOCORE + TERMIN + +DEFINE C A,B,C + SIXBIT /A/ + TERMIN + +COMTAB: NAMES + +DISPL==.-COMTAB + +DEFINE C A,B,D + D,,B + TERMIN + +DISP: NAMES + NOCORE,,NOCOM + ;** COMCON.MAC ** PAGES 12,13,14+15 + +;CALLED FROM COMMAND DECODER +; DEVDAT=ADDR OF CTY DDB +; PROG=XWD PROT., (O IF NO CORE) + +COR0: JUMPE PROG,CPOPJ ;RETURN IF JOB DOES NOT HAVE CORE + MOVEI TAC1,ESTOP + JSP TAC,MONSTR + PUSHJ PDP,RESET ;RELEASE ALL IO DEVICES + PUSHJ PDP,TTYFNU + MOVEI TAC,0 + SOS (PDP) ;NEGATE SKIP RETURN WHICH CORE1 WILL DO + JRST CORE1 + +; "PJOB" - PRINT JOB # OF JOB + +PJOB: MOVE TAC,JOB ;JOB # = I.T.S. USER INDEX OF SIM PROCEDURE +DECLF: PUSHJ PDP,RADX10 ;PRINT AS A DEC # + JRST CRLF + +;ERROR IN COMMAND + +CERR: JRST ERRMES + +; "START L" OR "START" + +START: + +; "CSTART L" OR "CSTART" + +STARTC: .UMOVE TAC1,JOBSA + PUSH PDP,TAC1 ;SAVE USER'S JOBFF + PUSHJ PDP,OCTIN + SKIPA TAC1,(PDP) + JRST STRTC1 ;ILLEGAL CHARACTER + POP PDP,(PDP) ;ADJUST STACK + JRST CHKSTR + +STRTC1: POP PDP,(PDP) ;ADJUST STACK + JRST COMERA + ;** COMCON.MAC ** PAGES 16+17 + +HELP: PUSHJ PDP,INLMES + ASCIZ/The monitor has the following commands: +/ + MOVSI AC1,1-DISPL ;LOAD AN AOBJN PNTR +HELP1: TRNN AC1,7 ;SHOULD I CRLF? + PUSHJ PDP,CRLF + MOVE TAC1,COMTAB+1(AC1) ;LOAD A COMMAND + PUSHJ PDP,PRNAME ;TYPE IT + PUSHJ PDP,INLMES + ASCII / / + AOBJN AC1,HELP1 ;TYPE ANOTHER + JRST CRLF ;TYPE A CRLF +REENTER: + .UMOVE TAC1,JOBREN ;GET REENTER ADDRESS FROM JOB DATA AREA + JRST CHKSTR + +DDTGO: MOVE TAC1,USRDDT + +CHKSTR: TLZ TAC1,-1 ;ZERO LEFT HALF + JUMPN TAC1,USTART + JSP TAC,ERRMES + ASCIZ /?No start adr +/ + +; "HALT" OR "^C" +;SCANNER ROUTINE DUMMY UP STOP WHEN ^C TYPED IN. + +STOP: PUSHJ PDP,INLMES ;TYPE MESSAGE + ASCIZ /^C +/ + JRST STOP1 ;STOP JOB + +; "CCONTINUE" - CONTINUE EXECUTION (TTY REMAINS IN COMMAND MODE) + +CCONT: ;SAME AS "CONTINUE" + + +; "CONTINUE" - CONTINUE EXECUTION FROM WHERE USER LEFT OFF + +CONT: MOVSI TAC1,JERR + TDNN TAC1,JBTSTS ;IS JOB ERROR SET ? + POPJ PDP, ;NO - COMMAND DECODER WILL DO THE REST + JSP TAC,ERRMES ;YES - PRINT CAN'T CONTINUE + ASCIZ /?Can't continue +/ + ;** COMCON.MAC ** PAGES 18+19 + +; "CORE NN" - ASSIGNS NN*1024. WORDS OF CORE TO JOB +; "CORE" WITH NO ARGUMENT WILL PRINT NO. OF FREE BLOCKS LEFT WITHOUT +; AFFECTING CURRENT ASSIGNMENT OF CORE + +CORE: PUSHJ PDP,DECIN ;GET NN - NO. OF 1K BLOCKS + JRST COR3 ;NO ARG. SPECIFIED, JUST TYPE CURRENT CORE ALLOCATION + JRST COMERA ;ILLEGAL DECIMAL CHARACTER RETURN + JUMPE TAC1,COR1 + LSH TAC1,12 ;CONVERT 1K BLOCKS TO WORDS + MOVEI TAC,-1(TAC1) ;HIGHEST REL ADR. = LENGTH-1 OF LOW SEG. + PUSHJ PDP,CORE0 ;TRY TO ASSIGN CORE - ONLY LOWSEG CORE EVER GETS REASSIGNED + JRST COR2 ;CORE NOT AVAILABLE - PRINT MESSAGE + POPJ PDP, + +;USER ASKING FOR 0K +COR1: JRST COR0 ;GO RELEASE ALL DEVICES IF HE HAS CORE + +;ERROR DURING ATTEMPT TO REASSIGN CORE +; COMES HERE UPON FAIL RETURN FROM CORE0:[CORE1] + +COR2: MOVE DEVDAT,-2(PDP) ;RESTORE TTY DDB ADDR + PUSHJ PDP,COR3 + PUSHJ PDP,INLMES + ASCIZ "?" + MOVNI ITEM,1 ;SIGNAL ERROR + POPJ PDP, + +COR3: MOVEI ITEM,0 + PUSHJ PDP,PRTSEG ;PRINT SIZE OF LOWSEG + PUSHJ PDP,INLMES + ASCIZ "/" + MOVE TAC,CORMAX ;PRINT MAX. NO OF BLOCKS IN PHYSICAL + LSH TAC,-12 ;CORE AVAILABLE TO A SINGLE USER + PUSHJ PDP,RADX10 + PUSHJ PDP,INLMES + ASCIZ /K core +/ + POPJ PDP, + ;** COMCON.MAC ** PAGES 20,22+23 + +; "SAVE FILE-NAME [PROJ.,PROG.] CORE" - SAVES JOB AREA ON RETRIEVABLE DEVICE. +; NO ATTEMPT IS MADE TO SAVE DEVICE ASSIGNMENTS, AC'S, OR PC. + +SAVE: HRRI IOS,SAVJOB ;SET UP TO RUN SAVJOB + PUSHJ PDP,CTEXT1 ;DISPATCH + SKIPE SDVNMF + JRST SGSET + CAIE TAC1, + MOVEM TAC1,JBTPRG + MOVSI TAC1,'DSK + JRST SGSET + +GET: MOVEI IOS,GETJOB + PUSHJ PDP,CTEXT1 + SKIPE SDVNMF + JRST RUNCM + CAIE TAC1, + MOVEM TAC1,JBTPRG + MOVSI TAC1,'DSK + JRST RUNCM + +LOGIN: PUSHJ PDP,CTEXT1 ;GET A LOGIN NAME + JRST ULOGIN ;AND LOG ME IN + +CCLRUN: MOVE TAC,[SIXBIT /COMPIL/] + JRST ARCOM ;RUN IT + +; "R CUSPNAME CORE" - DOES "RUN SYS:CUSPNAME" + +ARCOM: PUSHJ PDP,SKPBRK ;DELETE ANY ARGS +ARCOM1: MOVEM TAC,JBTPRG +RCOM: MOVSI TAC1,(SIXBIT /SYS/) ;READ FROM SYS DEVICE + JRST RUNCO2 + + +; "RUN DEVICE:FILE[PROJ.,PROG.] (CORE)" +; DOES A CORE, GET, START ALL IN ONE. +; IF CORE ARG MISSING, SIZE IN DIRECTORY IS USED + +RUNCOM: PUSHJ PDP,CTEXT1 ;GET DEVICE NAME FROM COMMAND STRING + SKIPE SDVNMF ;WAS IT A DEVICE NAME? + JRST RUNCO2-1 ;NO, ASSUME DSK + CAIE TAC1, + MOVEM TAC1,JBTPRG ;SET PROGRAM NAME THEN + MOVSI TAC1,'DSK + PUSHJ PDP,SPRGNM ;NAME INFERIOR "NULL" - IF THERE IS ONE +RUNCO2: MOVEI IOS,RUNJOB ;ROUTINE ADDR + +RUNCM: PUSHJ PDP,GETMIN + JRST SGSET + ;** COMCON.MAC ** PAGES 24,25+26 + +; "ASSIGN DEV:NAME" - ASSIGN DEVICE TO JOB AND GIVE IT A LOGICAL NAME + +ASSIGN: PUSHJ PDP,CTEXT1 ;GET FIRST ARG TO AC(TAC1)=DEV + JUMPE TAC1,NOTENF ;NO ARGUMENT TYPED IF=0 + MOVE T1,TAC1 ;SAVE DEVICE NAME + PUSH PDP,DEVDAT ;SAVE TTY DDB - WE WILL LIKELY LOSE CONTENTS OF DEVDAT + ; WHEN WE GO THROUGH DDB'S ETC., BELOW. + MOVE TAC,TAC1 ;DEV NAME -> AC(TAC) + PUSHJ PDP,DEVPHY ;LOOK FOR MATCH OF PHYSICAL NAMES - TAKES NAME + ; IN AC(TAC). USES AC(DEVDAT) TO CHAIN THROUGH DDB'S. SUCCESS IF + ; EXACT MATCH - E.G. LPT. + JRST ASSG3 ;FAIL + JRST ASSG4 ;MATCH FOUND + +ASSG3: POP PDP,DEVDAT ;RESTORE TTY DDB + JRST NOTDEV ;TYPE ERROR + +MXDDDB==16. + +ASSG4: CAME T1,[SIXBIT /DSK/] ;IS THIS "ASSIGN DSK" + JRST ASSG5 ;NO + EXCH DEVDAT,0(PDP) ;COLLECT TTY DDB - SAVE CURRENT DDB + PUSHJ PDP,CTEXT1 ;GET LOGICAL NAME ARG. + MOVE TAC,TAC1 ;COPY TO AC(TAC) FOR DEVLG ROUTINE + JUMPE TAC,ASSF1 ;NO LOG. NAME SPECIFIED + ;THUS THIS IS SIMPLY THE COMMAND "ASSIGN DSK" + ; AND WE MAKE IT A NO-OP SINCE IT WILL ONLY CHEW UP A DDB + ; TO BE FREED ONLY AT "DEASSIGN" OR "FINISH DSK" TIME + PUSHJ PDP,DEVLG ;IS THERE A MATCH ? + JRST .+2 ;NO - GOOD - WE MAY USE NAME + JRST ASSF0 ;YES - ERROR, DO NOT ASSIGN + POP PDP,DEVDAT ;RETRIEVE DDB ADDR + PUSH PDP,TAC ;SAVE LOG. NAME + MOVEI AC1,MXDDDB ;MAX # OF ASSIGNED DSK DDB'S ALLOWED + HLRZ AC2,DSKDDB+DEVSER ;BEGIN LOOKING THROUGH + ; CHAIN OF DDB'S (WE WILL FIND TTYNM AND DSK DDB'S THERE) + MOVSI AC3,DVDSK ;CHECK DSK BIT AS WE GO THROUGH +ASSG4A: JUMPE AC2,ASSG4C ;IF END OF CHAIN, ALL OK + TDNN AC3,DEVMOD(AC2) ;THIS ONE A DSK ? + JRST ASSG4B ;NO + SKIPE DEVLOG(AC2) ;DOES THIS DSK DDB HAVE A LOGICAL NAME ? + ; (IF ASSIGNED BY CONSOLE, IT MUST) + SOJLE AC1,ASSER2 ;YES - HAVE WE ALREADY ASSIGNED MAX # ? +ASSG4B: HLRZ AC2,DEVSER(AC2) ;NO - KEEP CHAINING + JRST ASSG4A +ASSG4C: MOVEI TAC1,ASSCON + PUSHJ PDP,ASSASG ;ASSIGN-BY-CONSOLE + JRST SYSERR ;CAN'T HAPPEN, WE SHOULD ALWAYS BE ABLE TO GRAB A DSK DDB + POP PDP,TAC ;RESTORE LOG. NAME + JRST ASSF2 ;+ FINISH OFF "ASSIGN"MENT + +ASSG5: ;PHYSICAL NAMES MATCH - AND NAME .NE. "DSK" + MOVEI TAC1,ASSCON ;SO DO "ASSIGN" + PUSHJ PDP,ASSASG + JRST ASSER1 ;("ALREADY ASSIGNED TO ANOTHER JOB" -- WON'T HAPPEN TO US!) + JRST ASSFIN ;SUCCESS + +; "ALREADY ASSIGNED TO ANOTHER JOB" -- WE SHOULD NEVER GET HERE! + +ASSER1: JRST SYSERR + +ASSER2: POP PDP,DEVDAT ;ADJUST STACK + MOVE DEVDAT,-2(PDP) ;GET TTY DDB ADR. + JSP TAC,ERRMES + ASCIZ /?Too many disk DDB's +/ + ;** COMCON.MAC ** PAGE 27 + +;DEVICE ASSIGNED, GIVE IT A LOGICAL NAME + +ASSFIN: SETZM DEVLOG(DEVDAT) ;CLEAR LOGICAL NAME + EXCH DEVDAT,0(PDP) ;GET TTY DDB, SAVE DEVICE DDB + PUSHJ PDP,CTEXT1 ;GET LOG. NAME ARG. - IF ANY + SKIPE TAC,TAC1 ;WAS THERE ANY ? + PUSHJ PDP,DEVLG ;YES - IS IT IN USE ALREADY ? + JRST ASSF1 ;NO - OR NO LOG NAME SPECFIED + +ASSF0: MOVEI TAC,LOGERR ;YES - PRINT ERROR + MOVE DEVDAT,-3(PDP) ;RESTORE TTY DDB !! + PUSHJ PDP,ERRMES ;TYPE ERROR MESSAGE + MOVEI TAC,0 +ASSF1: POP PDP,DEVDAT ;RESTORE DDB FOUND IN DEVPHY: +ASSF2: MOVEM TAC,DEVLOG(DEVDAT) ;STORE LOG. NAME IN DDB + MOVE TAC1,DEVNAM(DEVDAT) ;PHYSICAL NAME + MOVE DEVDAT,-2(PDP) ;RESTORE TTY DDB + PUSHJ PDP,PRNAME + JSP TAC,CONMES + ASCIZ / Assigned +/ + +LOGERR: ASCIZ /%Logical name was in use, / + ;** COMCON.MAC ** PAGE 28 + +; "DEASSIGN DEVICE" - DEASSIGNS DEVICE FROM CONSOLE + +DEASSI: PUSHJ PDP,CTEXT1 ;GET DEVICE NAME + JUMPE TAC1,DEASTY ;NO ARG IF 0, DEASSIGN ALL BUT TTY + MOVE TAC,TAC1 ;DEVICE NAME + PUSHJ PDP,DEVSRC ;SEARCH FOR IT + JRST DEAER1 ;NOT FOUND + PUSHJ PDP,DEASG ;FOUND, DEASSIGN IT + JRST DEAER2 ;NOT PREVIOUSLY ASSIGNED + POPJ PDP, + +NOTDEV: +DEAER1: MOVE DEVDAT,-2(PDP) ;RESTORE TTY DDB + JSP TAC,ERRMES + ASCIZ /?No such device +/ + +DEAER2: MOVE TAC1,DEVNAM(DEVDAT) ;PRINT PHYSICAL DEV NAME + MOVE DEVDAT,-2(PDP) ;RESTORE TTY DDB + PUSHJ PDP,INLMES + ASCIZ "?" + PUSHJ PDP,PRNAME + JSP TAC,ERRMES + ASCIZ / Wasn't assigned +/ + ;** COMCON.MAC ** PAGES 37-39 + +; "DAYTIME" - PRINT TIME OF DAY + +DAYTIM: .RDATE TAC1, ;READ DATE AS SIXBIT /YYMMDD/ + PUSH PDP,TAC1 ;SAVE IT + LSH TAC1,24. ;PRINT DAY + PUSHJ PDP,PRNAME + LDB TAC,[POINT 7,(PDP),23,] ;GET SUFFICIENT PART OF MONTH + TRZE TAC,100 ;IS MONTH 10, 11, OR 12 ? + SKIPA TAC,MONTAB-20-1+10.(TAC) ;YES, GET 10. MORE THAN INDEX, + ;WHICH IS NOW EQUAL TO 0, 1, OR 2 (+20). + MOVE TAC,MONTAB-20-1(TAC) + MOVEM TAC,DAMESS ;STORE FOR PRINTOUT + MOVEI TAC,DAMESS + PUSHJ PDP,CONMES ;PRINT MONTH AS "-MON-" + POP PDP,TAC1 ;RESTORE /YYMMDD/ + TLZ TAC1,77 ;MAKE THIRD BYTE NULL TO END STRING + ;AT TWO CHARS. + PUSHJ PDP,PRNAME ;PRINT YEAR + PUSHJ PDP,PRSPC ;PRINT SOME SPACES + .RTIME TAC1, ;READ TIME -> AC(TAC1) + JRST PRTIM1 + +; "TIME" - PRINTS TOTAL AND INCREMENTAL RUNNING TIME FOR A JOB. +; TOTAL RUNNING TIME FOR PAST INFERIORS KEPT IN TRTPI +; TOTAL RUNNING TIME FOR PAST INFERIORS SINCE LAST "TIME" COMMAND KEPT IN TRTPIT +; TOTAL RUNNING TIME FOR SIMULATOR AT LAST "TIME" COMMAND KEPT IN TRTST +; TOTAL RUNNING TIME FOR INFERIOR AT LAST "TIME" COMMAND KEPT IN TRTIT +; (=0 IF THERE IS NONE.) +; ALL TIME KEPT IN 4.069 MICROSECOND UNITS + +RUNTIM: PUSHJ PDP,DECIN ;GET SECOND ARG IF THERE + JRST .+3 ;NO ARG SEEN, ALL OK + JRST COMERA ;ILLEGAL CHARACTER + JUMPN TAC1,COMERA ;IF HE SPECIFIES ANY JOB, IT HAD BETTER BE JOB 0 + MOVN TAC,TRTIT + SKIPE JBTADR ;INFERIOR ? + .USET UPRGO,[.RRUNT,,TRTIT] + ADD TAC,TRTIT ;=0 IF NO INFERIOR + ADD TAC,TRTPIT + SETZM TRTPIT ;RESET ACCUMULATED TIME OF PAST INFERIORS + ; SINCE LAST "TIME" COMMAND + PUSHJ PDP,PRTIM. + ASCIZ / (/ + MOVN TAC,TRTST ;INCREMENTAL TIME FOR SUPERIOR = + .SUSET [.RRUNT,,TRTST] ;CURRENT RUN TIME - RUN TIME AT LAST "TIME" COMMAND + ADD TAC,TRTST + PUSHJ PDP,PRTIM. + ASCIZ /) +/ + MOVE TAC,TRTIT ;NOW PRINT TOTAL RUN TIME FOR ALL INFERIORS + ADD TAC,TRTPI + PUSHJ PDP,PRTIM. + ASCIZ / (/ + MOVE TAC,TRTST ;AND SAME FOR SIM PROCEDURE + PUSHJ PDP,PRTIM. + ASCIZ /) +/ + POPJ PDP, + ;** COMCON.MAC ** PAGE 41 + +; "EXAMINE LOC" - LOOKS AT CONTENTS OF LOC AND PRINTS IN OCTAL. +;IF LOC IS MISSING, NEXT LOC IS PRINTED IF PREVIOUS WAS E COMMAND. +;PRINTS SAME LOC IF PREVIOUS WAS D COMMAND. +; IS PRINTED INSTEAD OF (LIKE DDT). + +ECOM: SKIPGE USREXM ;WAS PREVIOUS D OR E COMMAND. A D COMMAND ? + AOS USREXM ;NO, IT WAS E. INCREMENT IN CASE HE TYPES NO ARG. + HRROS USREXM ;YES, FLAG THAT E HAPPENED LAST (LH=-1) + PUSHJ PDP,OCTIN ;GET OCTAL LOCATION + SKIPA TAC1,USREXM ;NONE SPECIFIED, USE LAST LOC OF D OR NEXT OF E + JRST COMERA ;ILLEGAL CHARACTER + HRRM TAC1,USREXM ;SAVE ADDR + HRRZI UUO,(TAC1) + PUSHJ PDP,GETWRD ;GET WORD FROM LOW OR HIGH SEG + JRST ECOMA ;ERROR, OUT OF BOUNDS + PUSH PDP,TAC ;SAVE CONTENTS OF LOC TO BE PRINTED + HRRZ TAC,USREXM ;PRINT LOC BEING EXAMINED + PUSHJ PDP,OCTPNT + PUSHJ PDP,INLMES + ASCIZ */ * ;PRINT SLASH, + HLRZ TAC,(PDP) ;PRINT LH + PUSHJ PDP,OCTPNT + PUSHJ PDP,INLMES ;PRINT SPACE + ASCIZ / / + HRRZ TAC,(PDP) ;PRINT RH + PUSHJ PDP,OCTPNT + PUSHJ PDP,INLMES ;PRINT FINAL TAB + ASCIZ / / + JRST TPOPJ ;READJUST STACK AND RETURN + ;** COMCON.MAC ** PAGES 42-44 + +; "DEPOSIT LH RH LOC" - DEPOSITS XWD LH,RH->LOC. +;IF LOC ARG. IS MISSING, ASSUME NEXT LOC IF PREVIOUS D, SAME LOC IF +;PREVIOUS D. + +DCOM: PUSHJ PDP,OCTIN ;GET LH + JRST NOTENF ;NOT ENOUGH ARGUMENTS + JRST COMERA ;ILLEGAL CHARACTER + HRLM TAC1,IOS ;SAVE LH + PUSHJ PDP,OCTIN ;GET RH + JRST NOTENF + JRST COMERA + HRRM TAC1,IOS ;SAVE RH + SKIPL USREXM ;WAS PREVIOUS D OR E. AN E COMMAND ? + AOS USREXM ;NO, INCREMENT IN CASE USER TYPES NO 3RD ARG. + HRRZS USREXM ;FLAG THAT D WAS DONE LAST (LH=0) + PUSHJ PDP,OCTIN ;GET LOC ARG. + SKIPA TAC1,USREXM ;NONE SPECIFIED, USE LAST OF E OR NEXT OF D + JRST COMERA ;ILLEGAL CHARACTER + HLRZ TAC,PROG ;GET PROTECTION + CAILE TAC1,17 ;AC'S ARE OK + CAILE TAC1,JOBPFI ;NO. > HIGHEST LOC PROTECTED FROM IO ? + CAILE TAC1,(TAC) ;IN BOUNDS ? + JRST DCOMA ;NO + HRRM TAC1,USREXM + .UMOVM IOS,(TAC1) ;STORE IT AWAY + POPJ PDP, + +DCOMA: +ECOMA: JSP TAC,ERRMES + ASCIZ /?Out of bounds +/ + +;"BLANK" OR NO ALPHANUMERIC BEFORE BREAK CHAR COMMAND +;DISPATCHED TO LIKE ANY OTHER COMMAND + +CBLANK: CAIE TEM,12 ;WAS BREAK LF ? + CAIN TEM,"; + POPJ PDP, ;YES IGNORE + +;COMMAND NOT IN COMMAND DIRECTORY + +NOCOM: PUSHJ PDP,INLMES + ASCIZ "?" + JRST COMERR ;NO, APPEND ? TO WHAT HE TYPED IN + ;** COMCON.MAC ** PAGE 45 + +; "FINISH DEVICE" - CLOSES, RELEASES, AND DEASSIGNS DEVICE. +; FINISHES LOGICAL "DEVICE" IF ONE EXISTS +; IF NO LOGICAL MATCH IS FOUND, PHYSICAL "DEVICE" IS FINISHED. +; NOTE: PHYSICAL "DSK" IS TREATED SPECIALLY -- ALL CHANNELS OPEN +; ON PHYSICAL DSK ARE FINISHED. +; JOB MUST HAVE CORE + +CFINI: PUSHJ PDP,CTEXT1 ;GET "DEVICE" ARG. + JUMPE TAC1,NOTENF ;AND THERE MUST BE ONE + MOVE TAC,TAC1 ;PREPARE TO LOOK FOR DEVICE + PUSHJ PDP,DEVLG ;FIRST LOOK FOR A LOGICAL MATCH + JRST FDV4 ;NO MATCH - LOOK FOR PHYSICAL + JRST FDV5 ;WE'RE GOLDEN ! + +FDV4: PUSHJ PDP,DEVPHY ;LOOK FOR MATCH OF PHYSICAL NAME + JRST NOTDEV ;NO MATCH + CAIN DEVDAT,DSKDDB ;HAVE WE FOUND THE PROTOTYPE + ; DSK DDB IN LOOKING FOR A MATCH TO PHYSICAL "DSK" ? + AOBJN PDP,DEVPH1 ;YES - RESTORE OLD PD POINTER W/RETURN + SEARCH + ; FOR AN ACTIVE DDB + HLRZ TAC,DEVNAM(DEVDAT) ;LOOK AT PHYSICAL NAME OF MATCH + CAIN TAC,(SIXBIT /DSK/) ;="DSK" ? + TLO DEVDAT,-1 ;YES - FLAG DEVDAT +FDV5: MOVEM DEVDAT,USRFDV ;SAVE DDB ADDR + MOVE DEVDAT,-2(PDP) ;COLLECT TTY DDB ADDRESS - IT LIES BENEATH RETURN + ; ADDR AND DISP FOR COMMAND. + JSP TAC1,MSTART ;SET UP MONITOR JOB + JSP TAC,MONSTR ;SET UP AC(PDP)+AC(PROG)(=AC(JDAT)) + MOVE ITEM,USRFDV ;GET THAT SPECIAL DDB ADDR +FDV2: MOVE UCHN,USRHCU +FDV1: HRRZ DEVDAT,USRJDA(UCHN) ;GET NEXT DEVICE + MOVSI UUO,071000 ;SET UP RELEASE UUO + DPB UCHN,PUUOAC ;WITH CHANNEL NUMBER + PUSH PDP,UCHN + CAIE DEVDAT,(ITEM) ;MATCH ? + JRST FDV6 ;NO - LOOK AT NEXT CHANNEL LOWER + JSP UCHN,DOXUUO ;YES - EXECUTE THE RELEASE UUO FROM + UUO ;THE MONITOR.. USES THIS LOCATION TO POINT TO + ; LOCATION WHERE UUO STORED +FDV6: POP PDP,UCHN + SOJGE UCHN,FDV1 + PUSHJ PDP,DEASG ;DEASSIGN DEVICE + JFCL ;IGNORE IF NOT ASSIGNED-BY-CONSOLE + TLNN ITEM,-1 ;WAS THIS A PHYSICAL MATCH TO "DSK" + JRST ESTOP + HRROI ITEM,DSKDDB ;COLLECT POINTER TO PROTOTYPE DDB. + ; WE RESTART OUR SEARCH HERE SINCE DDB'S MAY HAVE BEEN + ; SHUFFLED IN FREE CORE DUE TO THE RELEAS 0, . +FDV3: TRNN ITEM,-1 ;END OF CHAIN + JRST ESTOP ;YES + HLRZ TAC,DEVNAM(ITEM) ;LOOK FOR MORE PHYSICAL DSK DDB'S + CAIN TAC,(SIXBIT /DSK/) ;A WINNER ? + JRST FDV2 ;YES + HLRO ITEM,DEVSER(ITEM) ;NO - KEEP CHAINING THROUGH DDB'S, STILL LOOKING + JRST FDV3 + ;** COMCON.MAC ** PAGE 46 + +; "RESOURCES" - PRINT OUT # FREE DISK BLOCKS (= # FREE TRACKS * 8) + +FREDEV: PUSHJ PDP,INLMES + ASCIZ /DSK:/ + HRRZ TAC1,NQSV ;COLLECT VALUES OF NQS, + HLLZ T,QACTV ;QACT, + HRLZ T1,QTUTOV ;QTUTO, + HLLZ AC1,QSFTV ;AND QSFT FROM VALUE-SAVE LOCATIONS READ DURING INITIALIZATION + HRRI T,AC2 ;ALL .GETLOC CALLS RETURN VALUES INTO AC(AC2) + HRRI T1,AC2 + HRRI AC1,AC2 + MOVEI TAC,0 ;SET TOTAL FREE TRACKS = 0 TO BEGIN WITH +FREDV2: + .GETLOC T, ;QACT ENTRY -> AC(AC2) + JUMPL AC2,FREDV1 ;=0 ? + .GETLOC T1, ;YES - GET QTUTO ENTRY + TLNE AC2,40000 ;DIR IN ? + JRST FREDV1 ;NO + .GETLOC AC1, ;GET # FREE TRACKS (I.E. QSFT ENTRY) + ADD TAC,AC2 +FREDV1: ADD T,[1,,] ;INCREMENT ABSLOC POINTER IN .GETLOC ARGUMENTS + ADD T1,[1,,] + ADD AC1,[1,,] + SOJG TAC1,FREDV2 ;MORE PACKS + LSH TAC,3 ;MULITPLY # FREE TRACKS BY 8 = # FREE 128.-WORD BLOCKS + PUSHJ PDP,RADX10 + PUSHJ PDP,INLMES + ASCIZ / +LPT:,TTY:/ + JRST CRLF + +;CONVERT SNAME TO PROJECT,PROGRAMMER NUMBER + +PPN: PUSHJ PDP,CTEXT1 ;COLLECT SNAME + SKIPN TAC,TAC1 ;DID HE REALLY SAY SOMETHING ? + MOVE TAC,SNAME ;NO, USE HIS OWN SNAME + PUSH PDP,TAC ;SAVE CONVERTED [PROJ,PROG] + MOVEI TEM,"[ + PUSHJ PDP,OUTCHS + HLRZ TAC,(PDP) ;COLLECT PROJECT # + PUSHJ PDP,PRTOCT ;PRINT IT, WITHOUT LEADING ZEROES + MOVEI TEM,", + PUSHJ PDP,OUTCHS + HRRZ TAC,(PDP) + PUSHJ PDP,PRTOCT + MOVEI TEM,"] + PUSHJ PDP,OUTCHS + JRST TPOPJ + +;CONVERT [PROJECT,PROGRAMMER] # TO SNAME + +SNA: PUSHJ PDP,PJPGNO ;GET PROJ,PROG + MOVE TAC,AC2 + PUSHJ PDP,PPTOSN ;CONVERT IT TO A SNAME + MOVE TAC1,TAC + JRST PRNAME ;AND PRINT IT + ;** COMCON.MAC ** PAGES 49+50 + +;ROUTINE TO RETURN NEXT ALPHANUMERIC STRING +; IN COMMAND LINE (SIXBIT) +;CALL: MOVE TAC,BYTE POINTER TO PREVIOUS CHAR. +; PUSHJ PDP,CTEXT +; SIXBIT STRING RETURNED LEFT JUSTIFIED IN AC(TAC1) + +CTEXT: PUSHJ PDP,SKIPS ;CALL HERE IF AT START OF LINE + CAIA ;THE FASTEST SKIP IN THE WEST ! + +CTEXT1: PUSHJ PDP,SKIPS1 ;SKIP LEADING SPACES, TABS, NULLS, AND CLEAR AC (TAC1) + ; DO NOT RETURN IF WAS PREVIOUS BREAK + SETZM SDVNMF ; CLEAR "sAW DEVICE NAME" FLAG + MOVE T,[POINT 6,TAC1,-1,] + LDB TEM,TAKR(DAT) + JRST CTEX1 +CTEX0: PUSHJ PDP,GETCHR +CTEX1: PUSHJ PDP,CTEX + TRC TEM,40 ;-> SIXBIT + TLNE T,770000 ;6 CHARS ? + IDPB TEM,T ;NO- ADD IT ON + JRST CTEX0 + +;SCAN FOR ALPHANUMERIC CHAR IN TEM + +CTEX: CAILE TEM,"Z+40 ;GREATER THAN LC Z ? + JRST CTEXA ;YES, NOT SIXBIT + CAIL TEM,"A+40 ;LOWER CASE LETTER ? + TRZ TEM,40 ;YES, MAKE IT UPPER CASE + CAIL TEM,"0 + CAILE TEM,"Z ;AS THEY SAY, "LETTERS ARE LARGER THAN NOS." + JRST CTEXA ;NEITHER + CAILE TEM,"9 + CAIL TEM,"A + POPJ PDP, +CTEXA: CAIE TEM,": ;DEVICE NAME + JRST .+3 + SETOM SDVNMF + PUSHJ PDP,GETCHR + CAIE TEM,3 + JRST TPOPJ ;(-> POP PDP,TAC; POPJ PDP,) + ; I.E. -- RETURN TO ROUTINE WHICH CALLED CTEXT +CTXCNC: MOVSI TAC1,(SIXBIT /HAL/) ;GET HERE VIA CTEX: OR SKIPS: + MOVEI TEM,12 ; I.E. -- ALWAYS A LEVEL DOWN FROM CTEXT: + JRST TPOPJ ;THAT'S WHY WE CAN TO THIS W/RELATIVE IMPUNITY + ;** COMCON.MAC ** PAGES 51+52 + +;ROUTINE TO IGNORE LEADING SPACES, TABS, AND NULLS +;ALSO CLEARS TAC1 +;DOES NOT RETURN IF PREVIOUS CHAR. OR NEXT NON-SPACING +;CHAR. IS (IE POP SUBROUTINE LEVEL UP 1 ON RETURN) +;CALL: MOVE TAC,BYTE POINTER TO PREVIOUS BREAK CHAR. +; PUSHJ PDP,SKIPS1 + +SKIPS: PUSHJ PDP,GETCHR ;GET FIRST CHAR ON LINE +SKIPS1: MOVEI TAC1,0 ;FOR CTEXT, DECIN + LDB TEM,TAKR(DAT) + CAIN TEM,15 ;= ? +SKIPSA: PUSHJ PDP,GETCHR ;NULL ? + JUMPE TEM,SKIPS3 ;NULL, OR +NULL + PUSHJ PDP,SPCHEK ;SPECIAL ? + JRST SKIPS2 ;NO + TLNE TAC,BREAKB ;BREAK ? + JRST SKIPS3 +SKIPS2: CAIG TEM,40 ;SPACE OR CNTRL CHAR ? + JRST SKIPSA ;YES - SKIP IT + POPJ PDP, +SKIPS3: CAIN TEM,3 ;^C ? + JRST CTXCNC + MOVEI TEM,12 + JRST TPOPJ + +COMERP: POP PDP,T ;REMOVE SUBROUTINE RETURN BEFORE CALLING COMERA +COMERA: PUSHJ PDP,GETCHR ;MOVE UP A CHAR + +;ROUTINE TO REPLACE LAST CHARACTER IN INPUT STRING BY "?" +; AND SET AS OUTPUT +;CALL: MOVE TAC,BYTE POINTER TO LAST CHAR. IN INPUT STRING +; PUSHJ PDP,COMERR + +COMERR: + MOVE T,TITAKR(DEVDAT) + PUSHJ PDP,TRESCN +COMERL: + PUSHJ PDP,GETCHR + CAMN T,TITAKR(DEVDAT) + JRST COMER1 + PUSHJ PDP,OUTCHS + JUMPN TEM,COMERL + +COMER1: PUSHJ PDP,SETBFI + AOS TISYNC(DEVDAT) + MOVEI TEM,"? + PUSHJ PDP,OUTCHS + JRST CRLF + ;** COMCON.MAC ** PAGES 53-55 + +;ROUTINE TO PRINT A COMMAND ERROR MESSGE + +ERRMES: MOVNI ITEM,1 + JRST CONMES + +;ROUTINE TO PRINT CARRIAGE RETURN-LINEFEED +;CALL: PUSHJ PDP,CRLF + +CRLF: MOVEI TAC,[ASCII / +/] + +;ROUTINE TO TYPE ASCII CHAR. STRING +;CALL: MOVE TAC,ADDRESS OF ASCII MESSAGE +; PUSHJ PDP,CONMES +; STRING TERMINATED BY NULL +;CONMES DOES NOT START TTY +;CONMS1 - SAME CALLING SEQUENCE AS CONMES, EXCEPT LH IS BYTE POINTER + +CONMES: HRLI TAC,440700 ;FORM ASCIZ BYTE POINTER +CONMS1: PUSH PDP,TAC ;SAVE BYTE POINTER +CON0: ILDB TEM,(PDP) ;GET NEXT CHAR. + JUMPE TEM,TPOPJ ;IS IT NULL ? (IF SO, RESTORE AC(TAC) AND RETURN) +CONOUT: + PUSHJ PDP,OUTCHS + JRST CON0 + +;ROUTINE TO PRINT INLINE ASCIZ MESSAGE +;CALL: PUSHJ PDP,INLMES +; ASCIZ /THE MESSAGE/ +;RETURN TO NEXT LOC AFTER MESSAGE + +INLMES: POP PDP,TAC ;SET UP PRINT ADDRESS FOR CONMES + PUSHJ PDP,CONMES + JRST 1(TAC) ;RETURN TO NEXT LOC AFTER MESSAGE + +;ROUTINE TO APPEND ? TO ERROR MESSAGE +;CALL: PUSHJ PDP,PRQM +; RETURN + +PRQM: MOVEI TEM,"? + JRST OUTCHS + +PRSPC: MOVEI TAC,[ASCIZ / /] + JRST CONMES + +;ROUTINE TO PRINT "TOO FEW ARGUMENTS" +;CALL: PUSHJ PDP,NOTENF + +NOTENF: JSP TAC,ERRMES + ASCIZ /?Too few arguments +/ + +;ROUTINE TO PRINT CRLF ^C CRLF +;CALL: PUSHJ PDP,PRCRCC +; RETURN + +PRCRCC: JSP TAC,CONMES + ASCIZ/ +^C +/ + +;ROUTINE TO PRINT PERIOD +;CALL: PUSHJ PDP,PRPER +; RETURN + +PRPER: JSP TAC,CONMES + ASCIZ /./ + ;** COMCON.MAC ** PAGE 57 + +;ROUTINE TO READ CONSOLE AND CONVERT ANY RADIX # +;CALL: MOVE TAC1,DESIRED RADIX +; PUSHJ PDP,ANYRIN +; NO-ARG.-TYPED RETURN, AC(TAC1)=0 +; ILLEGAL CHAR RETURN +; NORMAL EXIT - AC(TAC1) CONTAINS # +;SCAN STOPS ON FIRST , DASH, SPACE, TAB, OR ILLEGAL CHARACTER +;SKIPS LEADING SPACES AND TABS. + +R==BUFWRD ;RADIX AC + +DECIN1: +DECIN: MOVEI R,12 ;DECIMAL INPUT + JRST ANYRIN + +OCTIN: MOVEI R,10 ;OCTAL INPUT +ANYRIN: PUSHJ PDP,SKIPS1 ;SKIP LEADING SPACES, TABS, NULL + ; DO NOT RETURN IF WAS PREVIOUS BREAK OR THIS BREAK +OCT0: CAIGE TEM,175 ;ALTMODES (175 OR 176) ? + CAIN TEM,"[ ;NO. LT BRACKET (SO SPACE NOT REQ BEFORE [P,P] ) + JRST CPOPJ2 + CAIE TEM,"- ;DASH + CAIG TEM,40 ;SPACE OR ? + JRST CPOPJ2 ;YES - ONLY LEGA TERMINATORS + CAIE TEM,", ;COMMA ? + CAIN TEM,"] ;RT BRACKET ? + JRST CPOPJ2 ;YES + SUBI TEM,60 + JUMPL TEM,CPOPJ1 + CAML TEM,R ;>= RADIX ? + JRST CPOPJ1 ;YES - ERROR + IMUL TAC1,R + ADD TAC1,TEM + PUSHJ PDP,GETCHR ;GET NEXT CHAR + JRST OCT0 + ;** COMCON.MAC ** PAGE 56 + +;ROUTINE TO DEASSIGN A DEVICE +;CALL: MOVE DEVDAT,DEV DATA BLOCK +; PUSHJ PDP,DEASG +; ERROR - NOT PREVIOUSLY ASSIGNED +; OK RETURN W/DEVICE DEASSIGNED + +DEASG: SETZM DEVLOG(DEVDAT) ;CLEAR LOGICAL NAME + MOVE TAC1,DEVMOD(DEVDAT) ;GET DEVICE CHAR. + TRNE TAC1,ASSCON ;IS DEV ASSIGNED-BY-CONSOLE + AOS (PDP) + MOVEI TAC1,ASSCON ;SET UP ASSIGNED-BY-CONSOLE BIT FOR RELEA6 + JRST RELEA6 ;RELEASE DDB + +;ROUTINE TO DEASSIGN ALL DEVICES EXCEPT LOGICAL TTY +;CALL: MOVE DEVDAT,ADR. OF DEVICE NO T BE DEASSIGNED +; PUSHJ PDP,DEASTY + +DEASTY: PUSH PDP,DEVDAT ;SAVE TTYDDB ADDR + HLRZ DEVDAT,DEVLST ;SEARCH ALL DDB'S +DEA1: CAIE DEVDAT,@(PDP) ;IS THIS SPECIAL ? + PUSHJ PDP,DEASG ;NO - TRY TO DEASSIGN IT + JFCL ;IF WE FAIL, WHO CARES ? + HLRZ DEVDAT,DEVSER(DEVDAT) + JUMPN DEVDAT,DEA1 + POP PDP,DEVDAT ;RESTORE TTY DDB ADDR + POPJ PDP, ;AND RETURN + ;** COMCON.MAC ** PAGE 58 + +;GET PROJECT-PROGRAMMER NUMBERS +;CALL: PUSHJ PDP,PJPGNO +; +;(AC2)LH _ PROJECT # +;(AC2)RH _ PROGRAMMER # +;(AC2)=0 IF NO []'S TYPED +; THE TERMINAL ] IS OPTIONAL + +PP0: PUSHJ PDP,SKIPS1 +PJPGNO: CAIN TEM,"[ ;IS IT A "[" ? + JRST PP1 ;YES, GET PROJ-PROG NUMBERS FROM INSIDE + CAIE TEM," ;NO, IS IT A SPACE ? + CAIN TEM,11 ;OR A TAB ? + JRST PP0 ;YES, KEEP LOOKING + MOVEI AC2,0 ;NEITHER SPACE NOR TAB, THUS RETURN 0 + ; MEANING NO PROJ-PROG # ENCOUNTERED + POPJ PDP, +PP1: PUSHJ PDP,SKIPS + PUSHJ PDP,OCTIN ;GET FIRST ARG. - PROJ # + JRST COMERP ;NO ARG. + JRST COMERP ;ILLEGAL OCTAL CHAR GIVEN + HRL AC2,TAC1 ;ENTER ARG + CAIE TEM,", ;LOOK FOR TERMINAL COMMA + JRST COMERP ;NOT FOUND + PUSHJ PDP,SKIPS + PUSHJ PDP,OCTIN ;GET SECOND ARG + JRST COMERP + JRST COMERP + HRR AC2,TAC1 ;ENTER IT + PUSHJ PDP,SKIPS1 ;SKIP BLANKS + CAIN TEM,"] ;IS USUAL ENDING "]" ? + PUSHJ PDP,GETCHR ;YES, SKIP IT SO FINAL "]" IS OPTIONAL + POPJ PDP, + ;** COMCON.MAC ** PAGES 59+60 + +;ROUTINE TO PRINT TIME AS HOURS, MINUTES, SECONDS, AND HUNDRETHS +; FORMAT IS HH:MM:SS.HH +;CALL: MOVE TAC,TIME IN JIFFIES +; PUSHJ PDP,PRTIME + +;JIFMIN=NO. OF JIFFIES/MIN +;JIFSEC=NO. OF JIFFIES/SEC +;JIFSC2=1/2 JIFSEC + +PRTIME: IDIVI TAC,JIFMIN ;FORM MINUTES + PUSH PDP,TAC1 ;SAVE REMAINDER IN MIN + JUMPE TAC,PR1 + IDIVI TAC,60. ;HOURS, MINUTES IN AC(TAC),AC(TAC1) + JUMPE TAC,PR0 ;SUPPRESS 0 HOURS + PUSHJ PDP,RADX10 ;PRINT "HH" OR "H" + PUSHJ PDP,INLMES ;THEN ":" + ASCIZ /:/ +PR0: MOVE TAC,TAC1 ;GET MINUTES + PUSHJ PDP,PRT2 ;PRINT "MM:" + PUSHJ PDP,INLMES + ASCIZ /:/ +PR1: POP PDP,TAC ;RESTORE SECONDS + IDIVI TAC,JIFSEC ;JIFFIES/SEC + PUSHJ PDP,RADX10 ;PRINT SECONDS + PUSHJ PDP,PRPER ;PRINT "." + MOVE TAC,TAC1 ;# JIFFIES + IMULI TAC,100. + ADDI TAC,JIFSC2 + IDIVI TAC,JIFSEC ;IN HUNDRETHS + JRST PRT2 + +;ROUTINE TO PRINT HH:MM - AS ENTERED IN 6-BIT CHARACTERS IN AC(TAC) +; VIA THE .RTIME UUO - I.E. SIXBIT /HHMMSS/. + +PRTIM1: PUSH PDP,TAC1 + TLZ TAC1,77 ;ONLY TWO CHARS. THIS OUTPUT + PUSHJ PDP,PRNAME ;HH + PUSHJ PDP,INLMES + ASCIZ /:/ ;: + POP PDP,TAC1 + LSH TAC1,12. ;PUT MM INTO LT. 12. BITS + TLZ TAC1,77 + PUSHJ PDP,PRNAME ;MM + JRST CRLF ; + +PRT2: MOVEI TEM,"0 ;PRINT DEC NO. IN 2 PLACES + CAIGE TAC,10. + XCT CONOUT ;PUT OUT LEADING 0 IF < 10 + JRST RADX10 + ;** COMCON.MAC ** PAGES 61+62 + +;ROUTINE TO PRINT SIZE OF LOGICAL SEGMENT (LOW OR HIGH) +;CALL: MOVE ITEM,(0=LOW SEG, 1=HIGH SEG) +; PUSHJ PDP,PRTSEG +; RETURN + +PRTSEG: PUSHJ PDP,SEGSIZ ;TAC1=SIZE OF HIGH OR LOW SEG + MOVEI TAC,(TAC1) ;RADX10 TAKES DEC. NO. IN AC(TAC) + JRST RADX10 ;PRINT DECIMAL + +;ROUTINE TO RETURN SIZE OF HIGH OR LOW SEG +;CALL: MOVE ITEM,(0=LOW SEG, 1=HIGH SEG) +; PUSHJ PDP,SEGSIZ +; RETURN W/SIZE IN K IN AC(TAC1) + +SEGSIZ: HLRZ TAC1,JBTADR(ITEM) + JUMPE TAC1,CPOPJ + LSH TAC1,-12 ;CONVERT TO #K-1 + AOJA TAC1,CPOPJ ;NOW MAKE IT RIGHT + +GETMIN: PUSH PDP,DEVDAT ;SAVE TTY DDB ADDR + PUSH PDP,IOS ;DISPATCH ADDRESS + MOVEI TAC,JOBDA ;LENGTH OF JOBDAT AREA + PUSHJ PDP,CORE0 ;ASSIGN JOBDA WORD - AND WE HAD BETTER + ; COLLECT AN INFERIOR PROCEDURE IF WE DON'T HAVE + ; ONE ALREADY + JFCL + POP PDP,IOS + POP PDP,DEVDAT + POPJ PDP, + ;** COMCON.MAC ** PAGE 63 + +;ROUTINE TO GET 1 WORD FROM USER AREA WHICH CAN BE IN LOW OR HIGH SEG +;CALL: HRR UUO,USER ADDRESS +; PUSHJ PDP,GETWRD +; ERROR RETURN - ADDR OUT OF BOUNDS +; OK RETURN - CONTENTS IN AC(TAC) + +GETWRD: HLRZ TAC,JBTADR + CAIGE TAC,(UUO) + POPJ PDP, ;ERROR RETURN IF LOWSEG ONLY + .UMOVE TAC,(UUO) + JRST CPOPJ1 + ;** COMCON.MAC ** PAGE 65 + +SGSET: JUMPE TAC1,NOTENF ;GOT TO HAVE A DEVICE NAME + MOVEM TAC1,SGADEV + PUSHJ PDP,CTEXT1 + CAIN TAC1, ;WAS THERE A NAME? + MOVE TAC1,JBTPRG ;NO, USE DEFAULT NAME + JUMPE TAC1,NOTENF ;IF STILL NONE, THEN COMPLAIN + MOVEM TAC1,SGANAM ;FILE NAME + MOVEM TAC1,JBTPRG + PUSHJ PDP,SPRGNM + MOVEI TAC1,0 + CAIN TEM,". ;X10N SPECIFIED ? + PUSHJ PDP,CTEXT ;YES - SO COLLECT IT + HLLZM TAC1,SGAEXT ;SAVE IT FOR FUTURE LOOKUP OR ENTER + SETZM SGADAT + PUSHJ PDP,PJPGNO ;GET [PROJ,PROG] + MOVEM AC2,SGAPPN ;SGAPPN=7 + + PUSHJ PDP,DECIN1 ;CORE ARG (OPTIONAL 3RD ARG) + JRST SGSET1 ;RETURNS HERE IF NO ARG FOUND + JRST COMERA ;ILLEGAL CHARACTER + LSH TAC1,12 + SUBI TAC1,1 ;CONVERT TO HIGHEST LEGAL ADDRESS +SGSET1: MOVEM TAC1,SGANEW ;SGANEW=15 + HRRZ TAC1,IOS ;WE ARE ABOUT TO START A "MONITOR JOB" + ; GUARANTEE LH=0 - SINCE IT WILL BE ADDED + ; TO STARTING ADDRESS (IF A RUN COMMAND) + JRST MSTART + ;** COMCON.MAC ** PAGE 66 + +;ROUTINE TO PICK UP ARGUMENTS FOR RUN UUO. +; THIS ROUTINE DOES THE SAME THING AS SGSET, EXCEPT THAT ARGUMENTS +; ARE OBTAINED FROM USER UUO ARGUMENTS INSTEAD OF FROM CONSOLE COMMAND. +; THE USER'S ARGS ARE MOVED TO (SGA...) LOCATIONS. USER AC FIELD AND +; START PC OFFSET ARE SAVED ON PD LIST AT JOBPD3. JBTPRG NOT SET FOR LOW SEG. +;CALL: MOVE TAC,CONTENTS OF USER AC +; MOVE PROG,[PROT.,,0] +; PUSHJ PDP,GETARG +; RETURN + +GETARG: HRR UUO,TAC ;MOVE ADR OF ARG LIST TO AC(UUO) + EXCH TAC,(PDP) ;AND ONTO PD LIST + PUSH PDP,TAC ;MOVE RETURN PC UP ONE + LDB TAC,PUUOAC ;UUSER AC FIELD IN RUN UUO + HRRM TAC,-1(PDP) ;JOBPD1 NOW HAS S.A.INCR,,USER AC + PUSHJ PDP,GETWRD ;GET FIRST ARG. FROM USER - USES AC(UUO) FOR ADDR. + MOVEM TAC,SGADEV + PUSHJ PDP,GETWD1 ;GET NEXT ARG + MOVEM TAC,SGANAM + PUSHJ PDP,GETWD1 ;GET 3RD ARG + MOVE TAC1,TAC ;PUT ARG IN AC(TAC1), SO SAME + ; AS SGSET RETURN FROM CTEXT + MOVEM TAC1,SGAEXT ;STORE X10N + PUSHJ PDP,GETWD1 ;4TH ARG - DATE WORD + MOVEM TAC,SGADAT + PUSHJ PDP,GETWD1 ;[PROJ.,PROG.] + MOVEM TAC,SGAPPN + PUSHJ PDP,GETWD1 ;CORE ARG OR 0 [HIGHEST LOC OR 0] + HRRZM TAC,SGANEW + JRST SG2A ;GO SET UP LOWER CORE AND RETURN + ;** COMCON.MAC ** PAGES 67-69 + +;SAVE JOB AREA ON RETREIVABLE STORAGE +; NO ATTEMPT IS MADE TO SAVE STATUS OF IO DEVICES, JOBPDP, +; OR AC'S. IN FACT THE ONLY USEFUL THING WHICH MAY BE DONE +; WITH A JOB AREA AFTER IT HAS BEEN SAVED IS TO START EXECUTION +; OVER AT THE STARTING ADDRESS. + +SAVJOB: JSP TAC1,SG1 ;SET UP AC'C, RESET DEVICES + HLRE TAC1,SGADMP ; - NO. OF WORDS TO WRITE + PUSHJ PDP,CKIOWD ;CHECK USER'S CORE ARG. (IF ANY) WITH + ;AMOUNT TO WRITE. RETURNS ONLY IF 0 OR NOT SMALLER. + .UMOVE TAC1,JOBCOR + HRRI TAC1,(TAC) + .UMOVM TAC1,JOBCOR ;STORE MAX. SIZE OF FILE OR CORE ARG. + .UMOVE TAC,JOB41 ;SAVE USER UUO HANDLING INSTR. + .UMOVM TAC,JOBS41 ;HIGHER UP SO IT GETS SAVED + .UMOVE TAC,JOBDDT ;SAVE DDT STARTING ADR. ALSO + .UMOVM TAC,JOBSDD + MOVEI TAC,SGCHN ;SET UP TO USE A SPECIFIC I.T.S. CHANNEL + DPB TAC,PDEVO + .IOPUSH SGCHN, ;SAVE STATUS OF WHATEVER IS THERE NOW + JSP UCHN,DOXUUO ;DO THE ENTER + [ENTER 0,SGANAM] + JRST SAVERR ;DIR. FULL OR PROTECTION FAILURE + .UMOVE TEM,JOBSA ;SAVE START ADR. + HLRE ITEM,SGADMP ;IOWD FOR THIS SIZE CORE + ; - LENGTH TO WRITE + MOVN ITEM,ITEM ;POSITIVE LENGTH + MOVEI ITEM,JOBSVM(ITEM) ;ADD IN FIRST LOC.-1 TO WRITE, + ; WHICH = HIGHEST LOC. FOR END TEST. + PUSH PDP,ITEM ;SAVE ON STACK + MOVEI TAC1,JOBSDD ;START BY SETTING PTR. TO FIRST USER ADR. +SVLUP: MOVEI TAC,MONBUF+1 ;SET UP TO BRING A BUFFER LOAD + ;INTO MONBUF FROM USER CORE. (MAX. OF MBFSIZ-1) + HRLI TAC,(TAC1) + MOVE DAT,(PDP) ;GET HIGHEST ADR. + SUBI DAT,-1(TAC1) ;FORM # WORDS REMAINING TO BE SAVED + JUMPE DAT,SVLP7 ;FINISH UP IF WE ARE DONE + CAILE DAT,MBFSIZ-1 ;IS IT GREATER THAN MBFSIZ-1? + MOVEI DAT,MBFSIZ-1 ;YES, READ MAX. OF MBFSIZ-1, BUT AVOID TRYING + ;TO READ MORE THAN THERE MAY BE + .UBLTI TAC,MONBUF(DAT) + MOVNI ITEM,(DAT) ;SET UP AOBJN POINTER TO DATA WORDS + HRLZI ITEM,(ITEM) + HRRI ITEM,MONBUF+1 + MOVEI DAT,MONBUF ;ADR. OF FIRST IOWD + JRST SVLP2 ;GET INTO IT A BIT +SVLP1: MOVEI DAT,(ITEM) ;SET ADR. WHERE NEXT IOWD TO GO +SVLP2: SKIPE (ITEM) ;IS THIS A DATA WORD? + JRST SVLP3 ;YES + AOBJP ITEM,.+2 ;NO, INCREMENT POINTER INTO MONBUF + ;BUT MOVE ON IF NOTHING LEFT + AOJA TAC1,SVLP2 ;OK, INCREMENT USER ADR. AND CONTINUE + ADDI TAC1,1 + SUBI DAT,MONBUF ;ALL OF MONBUF CHECKED - FORM # WORDS + ;IN MONBUF TO BE OUTPUT (SAVED) + MOVNI DAT,(DAT) ;FORM .IOT POINTER +SVLP2A: ADDM DAT,DEVCNT(DEVDAT) ;UPDATE NEG. WORD COUNT OF FILE + HRLI DAT,MONBUF + MOVS DAT,DAT + TLNE DAT,-1 ;IS THERE REALLY ANYTHING TO SEND? + .IOT SGCHN,DAT ;YES, OUTPUT DATA & IOWD'S TO FILE + JRST SVLUP ;NEXT MONBUF LOAD + +SVLP3: MOVEI AC1,1(DAT) ;PICK UP ADR. WHERE FIRST DATA + ;WORD SHOULD BE + CAIN AC1,(ITEM) ;IS IT THERE? (AFTER IOWD LOC.) + JRST SVLP4 ;YES, MOVE ON + HRLI AC1,(ITEM) ;NO,MOVE REMAINDER OF MONBUF SO AS TO + ;START THERE + HRRI ITEM,1(DAT) ;POINT THERE + HLRE TAC,ITEM ;GET NEG. COUNT OF WORDS TO + MOVN TAC,TAC ;BE MOVED AND MAKE POSITIVE + ADDI TAC,(DAT) ;FORM FINAL "TO ADR." FOR BLT + BLT AC1,(TAC) ;FILL IN THE PREVIOUS ZEROES +SVLP4: HRLOI AC1,-1(TAC1) ;START IOWD +SVLP5: ADDI TAC1,1 ;POINT TO NEXT USER ADR. + AOBJP ITEM,SVLP6 ;POINT TO NEXT WORD IN MONBUF; + ;MOVE ON IF NONE LEFT + SKIPE (ITEM) ;NEXT WORD NON-ZERO? + SOJA AC1,SVLP5 ;YES, COUNT IT AND CHECK NEXT + MOVSM AC1,(DAT) ;NO, STORE IOWD + JRST SVLP1 ;AND CONTINUE + +SVLP6: MOVSM AC1,(DAT) ;STORE IOWD + SUBI ITEM,MONBUF ;FIGURE # WORDS TO BE SENT + MOVNI DAT,(ITEM) ;MAKE NEGATIVE IN PREPARATION FOR SAVING + JRST SVLP2A ;OUTPUT THE GOODS FROM MONBUF AND CONTINUE + +SVLP7: HRLI TEM,254000 ;PUT JRST C(JOBSA) AT END OF FILE + HRROI DAT,TEM ;FORM POINTER WORD FOR .IOT + .IOT SGCHN,DAT ;OUT GOES LAST WORD + SOS DEVCNT(DEVDAT) ;ONE MORE WORD TO COUNT + MOVNS DEVCNT(DEVDAT) ;MAKE THAT WORD COUNT POSITIVE + ; DEVCNT CONTAINS EITHER A -BLOCK OR +WORD COUNT + POP PDP,DAT ;RESTORE STACK + +SAVFIN: PUSHJ PDP,SGREL + JSP TAC,PHOLD ;PRINT MESSAGE AND STOP JOB + ASCIZ /Job saved/ + +SAVERR: PUSHJ PDP,SGRLE1 ;RELEASE DEVICE, FIND TTY, AND PRINT ? + JSP TAC,PHOLD ;PRINT MESSAGE AND STOP JOB + ASCIZ /Protection failure/ + ;** COMCON.MAC ** PAGE 70 + +GETJOB: JSP TAC1,SG1 + PUSHJ PDP,GETJB ;GET OUR JOB - AND RETURN IF THERE ARE NO ERRORS + JSP TAC,PHOLD + ASCIZ /Job setup/ + +;THIS GETS A JOB AREA FROM A RETRIEVAL DEVICE AND STARTS IT UP. +; JOB HAS JUST A JOB DATA AREA ASSIGNED WHEN CONTROL GETS HERE. + +RUNJOB: JSP TAC1,SG1 ;SETUP AC'S,SETUP LOWER CORE + JRST URUN1 ;LH OF PC WORD=0 + ;** COMCON.MAC ** PAGE 71 + +;RUN UUO +;CALL: MOVE AC,[XWD N,D] +; CALL AC,[SIXBIT /RUN/] +; ERROR RETURN -UNLESS LH=HALT - PRINT CONSOLE MESSAGE IF NO +; IF OK, TRANSFER TO C(JOBSA)+N FOR NEW PROGRAM + +;WHERE: D/ DEV NAME +; D+1/ FILE NAME +; D+2/ FILE EXT OR 0 +; D+3/ DATE, ETC. +; D+4/ PROJECT-PROGRAMMER # OR 0 (=CURRENT) +; D+5/ HIGHEST LOC DESIRED (OR 0) - LH IGNORED + +URUN: PUSHJ PDP,RESET ;RELEASE DEVICES. AC(UUO) PRESERVED. + .UMOVE TAC,(UUO) ;USER'S CALLING AC + PUSHJ PDP,GETARG ;GET 6 ARGUMENTS FROM USER + STORE. SAVE S.A. INCR. (LH + ; OR AC(TAC)) + USER AC # (IN CASE OF ERROR RETURN). + MOVE TAC,SGANAM + MOVEM TAC,JBTPRG + PUSHJ PDP,SPRGNM ;SEG NAME OF INFERIOR +URUN1: PUSHJ PDP,GETJB ;GET BOTH LOW + HIGH SEGMENTS + HLRZ TAC1,(PDP) ;GET S.A. INCREMENT + PUSH PDP,TAC1 ;SAVE IT MOMENTARILY + .UMOVE TAC1,JOBSA ;ADD IT TO JOBSA + ADD TAC1,(PDP) + .UMOVM TAC1,JOBSA ;SAVE IT AWAY SO ^C, START WILL START PROGRAM + ; AT SAME STARTING ADDRESS + HRLI TAC1,USRMOD ;SET USER MODE BIT + MOVEM TAC1,(PDP) + JRST USRXIT + ;** COMCON.MAC ** PAGES 73-74 + +;ROUTINE TO SETUP ACS, RESET IO, AND SETUP LOWER CORE +; LOCATIONS FOR SAVE AND GET +; SGADMP SET TO IOWD FOR THIS CORE SIZE +;CALL: JSP TAC1,SG1 +; ALWAYS RETURN HERE, UNLESS DEVICE NOT FOUND +; DEVDAT SETUP TO DEVICE DATA BLOCK AND INIT'ED + +SG1: JSP TAC,MONSTR ;SETUP PROG,PDP + ; PUT TAC1 ON END OF PD LIST (EXEC MODE PC, SO ERROR MESSAGES WILL + ; ALWAYS PRINT. SEE SGRELE.) +SG2: PUSHJ PDP,RESET ;RELEASE ALL DEVICES +SG2A: MOVEI TAC,DR ;DUMP MODE 16 + MOVEM TAC,SGAMOD ;STORE FOR OPEN UUO + .UMOVE TAC,JOBCOR ;RESET RIGHT HALF OF JOBCOR + HLLZ TAC,TAC + .UMOVM TAC,JOBCOR ;IN THREE INSTRUCTIONS + SETZM SGAHED ;CLEAR BUFFER HEADER ARG. FOR OPEN UUO + JSP UCHN,DOXUUO ;TRY TO ASSIGN DEVICE + [OPEN 0,SGAMOD] + JRST SGERRA ;NO SUCH DEVICE + ;DEVICE INIT'ED +SG3: .UMOVE TAC,JOBFF ;FIRST FREE LOC IN JOB + ; (SET FROM LH OF JOBSA WHICH IS SET BY LOADER.) + MOVEI TAC,-1(TAC) ;MAKE LAST LOC TO SAVE OR GET (MAKE 0=777777) + SKIPN USRDDT ;USER DDT IN USE, SAVE ALL OF CORE + PUSHJ PDP,IADRCK ;NO - ADDRESS TOO SMALL OR TOO LARGE ? + MOVE TAC,USRREL ;YES, DUMP ALL OF CORE RATHER THAN + ; GIVE ADDRESS CHECK MESSAGE - HIGHEST REL. ADR. + MOVNI TAC,(TAC) ;MAKE IT NEGATIVE + ADDI TAC,JOBSVM ;LOWER CORE NOT DUMPED + HRLI TAC,JOBSVM ;IE FIRST LOC-1 TO BE DUMPED + MOVSM TAC,SGADMP ;STORE IOWD OF THIS SIZE CORE +SG4: + MOVE TAC,SGAPPN ;MAKE USRE 4TH WORD IS PROJ.,PROG. + MOVEM TAC,SGALEN ;INSERT IT INTO PROPER PLACE IN LOOKUP/ENTER BLOCK + SKIPN TAC,SGAEXT ;DID USER SPECIFY AN X10N ? + MOVSI TAC,SAVDMP ;NO, USE .SAV + MOVEM TAC,SGAEXT + POPJ PDP, + + +;ERROR IN OPEN OF SAVGET DEVICE + +SGERRA: MOVEI TAC,NSDERR ;ERROR CODE IN CASE RUN UUO (NO SUCH DEVICE) + PUSHJ PDP,SGRELE ;RETURN TO USER IF RUN UUO + ; OR FIND TTY AND PRINT ? + JSP TAC,PHOLD + ASCIZ /No such device/ + ;** COMCON.MAC ** PAGES 75-80 + +;ROUTINE TO GET FILE FROM DEVICE +;CALL: AC'S PROG, PDP,DEVDAT SETUP +; PUSHJ PDP,GETJB +; RETURN ONLY IF EVERYTHING OK + +GETJB: + .IOPUSH SGCHN, ;SAVE AN I.T.S. CHANNEL TEMPORARILY WHILST WE + ; DO SOME INPUT + MOVEI TAC,SGCHN + DPB TAC,PDEVI ;INSERT SGCHN INTO DEVCHN WORD OF THIS DDB + ; SO UUOCON WON'T GO LOOKING FOR A CHANNEL TO USE. + JSP UCHN,DOXUUO ;TRY A LOOKUP ON OUR LOW SEG FILE + ; (EXT=SAV) + [LOOKUP 0,SGANAM] + JRST NOFILE ;GO PRINT FILE.EXT NOT FOUND + + ;AND THAT LOOKUP BETTER RETURN THE FILE SIZE PROPERLY + ; INTO SGALEN + + HLRE TAC1,SGALEN ;-NO. OF WORDS IN FILE + PUSHJ PDP,CKIOWD ;CHECK USER'S SUPPLIED ARGUMENT TO MAKE SURE NOT + ; TOO SMALL + ;RETURN LARGER OF FILE SIZE OR CORE ARG + PUSHJ PDP,GETCOR ;GET WHAT WE THINK WILL BE ENOUGH CORE FOR NOW + + HRRZS USRPD1 ;TURN OFF USER MODE PC FLAG IN CASE THIS IS + ; A RUN UUO, SO ERRORS WILL NOT TRY TO RETURN TO USER + MOVE TAC,USRPD1 ;TELL USER TOO ! + .UMOVM TAC,JOBPD1 + ;** COMCON.MAC ** PAGES 75-80 + +;READ IN USER FILE PIECE BY PIECE USING MONBUF TO READ DATA + +;EXPAND: + HLRE AC3,SGALEN ;COMPUTE HIGHEST LEGAL ADDRESS THAT WE WOULD HAVE + ; HAVE TO REFERENCE WERE WE IN USER CORE DOING THE 10-50 + ; XPAND. (NOTE: FOR SOME SAVE'ED FILES, THE FILE LENGTH + ; WILL BE ROUNDED UP TO THE NEXT INTERVAL OF 8 128-WORD + ; BLOCKS. BUT THAT WON'T SCREW US UP.) + MOVN AC3,AC3 + ADDI AC3,JOBSVM ;JOBSVM=75 + + HRROI TAC,MONBUF ;READ ONE WORD INTO MONBUF + .IOT SGCHN,TAC ;READ IN FIRST WORD OF FILE SO THAT WE CAN + ; DO OUR INITIAL .ACCESS UUO, ETC. SEE II.T.S.R.M. P 40 + + SKIPL TAC,MONBUF + JRST SYSERR ;OLD FORMAT SAVE FILE + HRRZ TAC,TAC + CAILE TAC,JOBDDT ;JOBDDT=74 + JRST EXPND1 + JRST SYSERR ;???? + ;** COMCON.MAC ** PAGES 75-80 + +EXPND1: PUSHJ PDP,CHKADR + ADDI TAC,1 ;SET UP A .ACCESS WORD + .ACCESS UPRGO,TAC ;FIRST DO AN .ACCESS TO OUR + ; INFERIOR TO THE RIGHT PLACE + MOVEI TAC,JOBSV ;JOBSV=76 - PLACE WHERE JOBS ARE SAVED FROM +EXPLP1: HRRZ AC1,MONBUF ;GET NEXT IOWD + CAIGE AC1,JOBSAV ;JOBSAV=73 + AOJA AC1,TOOLOW + + HLRE AC1,MONBUF ;- WORD COUNT OF THIS BLOCK + MOVN AC1,AC1 ;+ WORD COUNT + ADDI TAC,1(AC1) ;PLACE WHERE WE WOULD BE AFTER HAVING PROCESSED THIS BLOCK. + ; WE AACCOUNT FOR THE HEADER IOWD BY ADDING 1. + CAMLE TAC,AC3 ;AND NOW WE CHECK - IS IT WITHIN RANGE ? + JRST SGDOER ;NO + PUSH PDP,MONBUF ;NOW READ AND WRITE A TOTAL OF AC(AC1) WORDS + +EXPLP2: MOVNI AC2,MBFSIZ + CAIGE AC1,MBFSIZ + MOVN AC2,AC1 + ADD AC1,AC2 ;AC(AC1) NOW CONTAINS # WORD LEFT TO PROCESS + HRLZ AC2,AC2 + HRRI AC2,MONBUF + MOVEM AC2,1(PDP) ;SAVE IO WORD + .IOT SGCHN,AC2 ;CAUSE IT WILL BE CHANGED HERE !! + .IOT UPRGO,1(PDP) ;WRITE THESE WORDS OUT + + JUMPG AC1,EXPLP2 ;MORE TO READ ? + ;** COMCON.MAC ** PAGES 75-80 + +;AS WE ARE MERRILY GOING ALONG HERE, WE MAY WELL BE EXPANDING THE +; AMOUNT OF CORE ASSIGNED TO OUR SOLICITOUS LITTLE USER, SO THAT +; IS WHY WE HAVE THE CHKADR ROUTINE CALLS. + + HRRZ TAC1,(PDP) ;ADDR-1 + HLRE AC2,(PDP) ;- WORD COUNT + SUB TAC1,AC2 ;AC(TAC1) NOW CONTAINS THE LAST WORD + ;WE JUST WROTE INTO + POP PDP,(PDP) ;READJST STACK + + HRROI AC1,MONBUF ;READ NEXT HEADER WORD + .IOT SGCHN,AC1 + PUSHJ PDP,CHKADR ;EVERY TIME WE HAVE A HEADER WORD IN + ; MONBUF, WE CALL CHKADR TO BE SURE THAT WE KNOW HOW MUCH + ; CORE IS BEING USED BY THE USER + SKIPL AC1,MONBUF + JRST EXPLP4 ;MAYBE THESE INSTRUCTIONS SHOULD GO ABOVE THE CALL TO CHKADR + + HRRZ AC1,AC1 ;ADDR-1, IT HAD BETTER BE >= AC(TAC1) + SUBI AC1,(TAC1) ;AC1 NOW CONTAINS THE # OF WORDS AFTER OUR + ; LAST BLOCK AND BEFORE THE NEXT + JUMPL AC1,SGDOER ;AS WE SAID, IT HAD BETTER BE >= 0 + JUMPE AC1,EXPLP1 ;IF=0, THEN DON'T DO ANYTHING + PUSH PDP,MONBUF + PUSHJ PDP,CLRMBF ;CLEAR OUR MONBUF +EXPL3: MOVNI AC2,MBFSIZ + CAIGE AC1,MBFSIZ + MOVN AC2,AC1 + ADD AC1,AC2 + HRLZ AC2,AC2 + HRRI AC2,MONBUF + .IOT UPRGO,AC2 ;WRITE OUT SOME ZEROES + JUMPG AC1,EXPL3 + POP PDP,MONBUF ;RESTORE MONBUF + JRST EXPLP1 + ;** COMCON.MAC ** PAGES 75-80 + +EXPLP4: + .UMOVE AC1,JOBSDD ;=114 + SETZ AC2, + .UMOVM AC2,JOBSDD + .UMOVM AC1,JOBDDT ;=74 + JRST SGDO2 + +TOOLOW: JRST SYSERR ;COMPRESSED DATA FOUND BELOW JOBSDD + + +SGDO2: MOVEM AC1,USRDDT ;COPY DDT STARTING ADDR INTO MONITOR PROTECTED AREA + +;CHECK FOR TRANSMISSION ERROR +;ACTUALLY THIS SHOULD BE DONE AT EXPLP4: + + .UMOVE TAC,JOBS41 ;RESTORE USER UUO LOC + .UMOVM TAC,JOB41 ;SAVED BY "SAVE" + +LOWFIN: .UMOVE TAC,JOBCOR ;CORE ARG FROM PREVIOUS "SAVE" + HRRZ TAC,TAC + SKIPN TAC ;IS THIS AN OLD FORMAT FILE W/NO CORE ARG TO SAVE ? + MOVE TAC,USRREL ;YES - USE ASSIGNMENT MADE WHEN LOW FILE READ IN + PUSHJ PDP,CKSARG ;RETURN ONLY IF USER'S SUPPLIED ARG IS 0 + ; OR NOT < SAVE CORE ARG, RETURN LARGER + PUSHJ PDP,GETCOR ;TRY TO GET THIS AMOUNT OF CORE + .UMOVE TAC,JOBCOR ;HIGHEST LOC ASSIGNED TO LOW SEG + HRR TAC,USRREL ;SET INITIAL CORE ASSIGNMENT IN JOB DATA AREA + ; FOR USER TO USE TO RESET CORE TO INITIAL SETTING + .UMOVM TAC,JOBCOR ;WHEN PROGRAM IS RESTARTED + JRST SGREL + +SGDOER: PUSH PDP,CHNSAT + JSP UCHN,DOXUUO + [RELEAS 0,] + POP PDP,CHNSAT + .IOPOP SGCHN, + JRST ADRERR + + +;ROUTINE TO RELEASE DEVICE AND FIND TTY + +SGREL: SKIPN USRJDA ;HAS CHANNEL BEEN RELEASED ALREADY ? + JRST TTYFUW ;YES, FIND TTY + PUSH PDP,IOS ;NO - WELL THEN DO IT + PUSH PDP,CHNSAT + JSP UCHN,DOXUUO + [RELEAS 0,] + POP PDP,CHNSAT + .IOPOP SGCHN, + POP PDP,IOS + JRST TTYFUW ;FIND TTY + ;** COMCON.MAC ** PAGE 81 + +;ROUTINE TO CHECK USER SUPPLIED CORE ARG AND +; CHECK TO SEE IF 0 OR >= IOWD USED TO SAVE OR GET FILE +;CALL: HLRE TAC1,-NO. OR WORDS IN FILE +; PUSHJ PDP,CKIOWD +; RETURN W/GREATER OF 2 POSITIVE #'S IN AC(TAC) W/1777 IOR'ED IN +; DO NOT RETURN IF CORE ARG SUPPLIED TOO SMALL + +CKIOWD: MOVEI TAC,JOBSVM + SUB TAC,TAC1 ;JOBSVM- (-# OF WORDS) + ; FALL INTO CKSARG + +;ROUTINE TO CHECK USER SUPPLIED CORE ARG AND CHECK IF 0 +; OR >= CORE ARG FOR PREVIOUS SAVE +;CALL: (HRRZ TAC,JOBCOR) ;WRITTEN WHEN FILE SAVED +; PUSHJ PDP,CKSARG +; RETURN W/LARGER OF 2 IN AC(TAC) ONLY IF USER ARG NOT TOO SMALL + +CKSARG: IORI TAC,1777 + CAMG TAC,SGANEW ;USER ARG BIGGER ? + SKIPA TAC,SGANEW ;YES (OR =) + SKIPN SGANEW ;DID HE SAY ANYTHING ? + POPJ PDP, + +;ROUTINE TO PRINT #K OF CORE NEEDED +;CALL: MOVE TAC,HIGHEST REL. USER ADR. +; PUSHJ PDP,NROOM1 +; NEVER RETURN + +NROOM1: PUSH PDP,TAC ;YES, USER'S SUPPLIED CORE TOO SMALL +NOROOM: MOVEI TAC,NECERR ;ERROR CODE IN CASE THIS IS RUN UUO (NOT ENOUGH CORE) + PUSHJ PDP,SGRELE ;RELEASE DEVICE AND ERROR RETURN TO USER IN RUN UUO + ; OR FIND TTY AND PRINT ? + HRRZ TAC,(PDP) ;GET AMOUNT OF CORE REQUESTED + LSH TAC,-12 ;CONVERT TO # OF 1K BLOCKS-1 + PUSHJ PDP,DECP1 ;ADD 1 PRINT PRINT DECIMAL + JSP TAC,PHOLD ;STOP JOB + ASCIZ /K of core needed/ + ;** COMCON.MAC ** PAGES 82+83 + +GETCOR: PUSH PDP,TAC ;SAVE CORE ARG IN CASE OF ERROR + HRRZ ITEM,TAC + JSP UCHN,DOXUUO + [CALLI ITEM,11] + JRST NOROOM + JRST TPOPJ + +;ROUTINE TO PRINT FILE NOT FOUND + +NOFILE: +; MOVEI TAC,FNFERR ;ERROR IN CASE THIS IS RUN UUO (FILE NOT FOUND) + PUSHJ PDP,SGRELL ;RETURN DISK LOOKUP/ENTER ERROR CODE. + ; RELEASE DEVICE AND ERROR RETURN TO USER IF HE WANTED. + ; OR FIND TTY AND PRINT ? + MOVE TAC1,SGANAM ;PRINT FILE NAME + PUSHJ PDP,PRNAME + PUSHJ PDP,PRPER ;PRINT PERIOD + HLLZ TAC1,SGAEXT ;PRINT X10N + PUSHJ PDP,PRNAME + JSP TAC,PHOLD ;STOP JOB + ASCIZ / Not found/ + ;** COMCON.MAC ** PAGE 84 + +;ROUTINE TO RELEASE DEVICE ON AN ERROR AND CHECK TO SEE IF WE +; ERRED IN MONITOR OR USER UUO +; -IF A USER UUO -> GIVE ERROR RETURN UNLESS WE FIND A HALT +; AT RETURN LOCATION +; -OTHERWISE -> FIND TTY AND PRINT ? AND RETURN TO CALLER +; WHERE MORE INFORMATION IS PRINTED AND SO AS TO LET CALLER +; STOP JOB +;CALL: MOVEI TAC,ERROR CODE +; PUSHJ PDP,SGRELE +; DO NOT RETURN TO CALLER IF HE WANTS RETURN ON RUN AND GETSEG UUO'S + +SGRELL: HRRZ TAC,SGAEXT ;RETURN DISK SERVICE ERROR CODE +SGRELE: MOVE TAC1,USRPD1 ;GET FIRST PC ON PD LIST + TLNN TAC1,USRMOD ;USER UUO ? + JRST SGRLE1 ;NO + PUSH PDP,TAC ;SAVE ERROR CODE + HRR UUO,TAC1 ;ADDR OF RETURN AFTER RUN OR GETSEG + PUSHJ PDP,GETWDU + HLRZ TAC1,TAC ;GET OP CODE + POP PDP,TAC ;RESTORE AC(TAC) + CAIN TAC1,(HALT) + JRST SGRLE1 + HRR UUO,USRPD3 ;AC # OF CURRENT UUO + PUSHJ PDP,STOTAC ;STORE ERROR # IN USER AC + SKIPN USRJDA+0 ;DO NOT RELEASE CHANNEL 0 IF NOT INIT'ED YET. + ; UUO CONTROLLER DOES NOT ALLOW THIS FROM EXEC MODE. + JRST SGRLE2 + + PUSH PDP,CHNSAT + JSP UCHN,DOXUUO + [RELEAS 0,] + POP PDP,CHNSAT + .IOPOP SGCHN, + +SGRLE2: PUSH PDP,USRPD1 ;PUT RETURN AT END OF PDLIST -- THEN RETURN THERE + JRST USRXIT + +SGRLE1: PUSHJ PDP,SGREL ;RELEASE S/G-DEVICE AND FIND TTY + JSP TAC,CONMES + ASCIZ /?/ + ;** COMCON.MAC ** MISC ROUTINES -- CHKADR AND SPRGNM AND TNAME + +;ROUTINE TO MAKE SURE THAT THE REST OF OUR SYSTEM +; KNOWS WHETHER CORE IS EXPANDING OR NOT AS WE BUSILY EXPAND +; THE CURRENT FILE READ IN DUE TO GET OR RUN COMMANDS, +; OR DUE TO THE RUN UUO + +CHKADR: SKIPL AC1,MONBUF ;WILL THIS BLOCK CAUSE MORE CORE TO BE USED ? + POPJ PDP, ;NO - LAST WORD OF FILE + HLRE AC1,AC1 ;-WORD COUNT OF THIS BLOCK + MOVNM AC1,1(PDP) ;GRAB A FREE STORAGE LOCATION + HRRZ AC1,MONBUF ;NOW DETERMINE HOW HIGH WE WILL GO + ADDM AC1,1(PDP) ;HIGHEST ADDRESS WRITTEN INTO BY THIS + ; BLOCK NOW IN LOCATION BEYOND CURRENT PD STACK + HLRZ AC1,JBTADR ;WILL THIS INCREASE AMOUNT OF LOW CORE WE WILL NEED + CAML AC1,1(PDP) + JRST CPOPJ ;NO - SO JUST RETURN + EXCH TAC,1(PDP) + PUSH PDP,1(PDP) + PUSH PDP,TAC1 + PUSHJ PDP,GETCOR ;GET OURSELVES SOME CORE + POP PDP,TAC1 + ADDI TAC1,1 + .ACCESS UPRGO,TAC1 ;RESET OUR .ACCESS POINTER, IT WILL BE MODIFIED + ; IN THE CORUUO WHEN WORDS IN THE JOB DATA AREA ARE SENT WITH + ; .UMOVM'S. + SUBI TAC1,1 ;READJUST AC(TAC1) + JRST TPOPJ ;RETURN AFTER RESTORING AC(TAC) + + +;ROUTINE TO SET PROGRAM NAME TO JBTPRG LOCATION - RECENTLY MODIFIED BY THE +; PROGRAM. JBTPRG CHANGED BY RUN UUO, RUN COMMAND, GET COMMAND + +SPRGNM: PUSHJ PDP,TNAME + SKIPE JBTADR ;DO WE HAVE A LIVE INFERIOR AT PRESENT ? + .USET UPRGO,[.SJNAME,,FILNM2] ;TRY TO SET UP THE JNAME OF OUR + ; INFERIOR. + POPJ PDP, + +;ROUTINE TO TEST PROPOSED JNAME AS ENTERED IN JBTPRG TO BE SURE +; THAT THE NAME IS NOT ALREADY IN USE AS THE NAME OF A CURRENT +; INFERIOR. THE NAME, OR ITS SUBSTITUTE IS LEFT IN FILNM2, AND +; FILNAM AND FILNM1 ARE LEFT WITH DATA SUITABLE FOR .OPEN'S + +TNAME: PUSH PDP,TAC + SETZM FILNM1 ;THE SYSTEM WILL SUPPLY CURRENT UNAME + SKIPN TAC,JBTPRG + MOVE TAC,NULNAM ;USE NULNAM: IF USER IS ZEROING JBTPRG + MOVEM TAC,FILNM2 + SKIPE TAC,JBTADR ;DO WE HAVE AN INFERIOR ? + .USET UPRGO,[.RJNAME,,TAC] + CAMN TAC,FILNM2 ;IF SO, DOES IT HAVE A MATCHING JNAME ? + JRST TPOPJ1 ;YES - SKIP RETURN. + ; WE EXPECT THAT THIS SKIP RETURN WILL ONLY AFFECT CALLING + ; SEQUENCE AT SPRGNM: AS OPPOSED TO THAT IN [CORE1] + MOVEI TAC,(SIXBIT /USR/) + HRLI TAC,IBOMDE ;TEST JNAME TO SEE IF AN INFERIOR HAS THIS NAME + MOVEM TAC,FILNAM + .IOPUSH UPRGO, +TNAME2: .OPEN UPRGO,FILNAM ;WE WANT A SUCCESS RETURN + JRST TNAME1 ;IN USE, TRY ANOTHER + .UCLOSE UPRGO, ;DELETE THIS INFERIOR, WE WERE JUST CHECKING + .IOPOP UPRGO, ;RESTORE UPRGO + JRST TPOPJ ;AND RETURN, RESTORING AC(TAC) +TNAME1: .GENSYM TAC, ;COLLECT A SYSTEM GENERATED NAME + MOVEM TAC,FILNM2 ;AND TRY AGAIN + JRST TNAME2 + ;** COMCON.MAC ** MISC ROUTINES -- PRTIM. + +;ROUTINE TO INTERFACE "TIME" ROUTINE AND DEC ROUTINE, PRTIME: (PRINTS TIME +; IN HH:MM:SS.DD FOR ARG IN JIFSECS). +;CALL: MOVE TAC,TIME IN 4.069 MICROSECOND UNITS +; PUSHJ PDP,PRTIM. +; RETURN + +PRTIM.: FSC TAC,233 ;FLOAT # 4.069 MICROSECOND UNITS + FMPR TAC,[.OP FMPR <.OP FDVR 4.069 1.0^6> 60.0] + ;CONVERT TO # MICROSECONDS + ; 4.069 MICROSECOND -> JIFFSECS. + ;CONVERT TO SECONDS + ;TO JIFFIES + FADR TAC,[0.5] ;ROUNDED + UFA TAC,[233000,,0] ;NOW FIX RESULT + LDB TAC,[POINT 27,TAC1,35,] ; AND COLLECT BOTTOM 27 BITS + PUSHJ PDP,PRTIME + JRST INLMES ;PRINT TRAILING MESSAGE AFTER CALL + ;** COMMON.MAC ** + +;** PAGE 2 ** + +JIFSEC==60. ;60 JIFFIES/SECOND +JIFSC2==JIFSEC/2 ;# JIFFIES IN A HALF SECOND (FOR ROUNDING) +JIFMIN==JIFSEC*60. ;# JIFFIES/MINUTE + +;** PAGE 8 ** + +CORMAX: 1000000 ;MAX # WORD AVAILABLE FOR USER + ; USED BY CORUUO:[CORE1] + ; USED BY "CORE" COMMAND[COMCON] + ;=MAXIMUM CORE REQUEST+1 (I.E. LARGEST REL. ADR.+1) + +;MONITOR COMMON DATA AREA + +STTYBF==20 ;THIS ACTUALLY IS DEFINED IN PTYSRF + + +;** PAGE 34 ** + +;MONTH TABLE FOR DAYTIME COMMAND PRINTING + +MONTAB: ASCII /-Jan-/ + ASCII /-Feb-/ + ASCII /-Mar-/ + ASCII /-Apr-/ + ASCII /-May-/ + ASCII /-Jun-/ + ASCII /-Jul-/ + ASCII /-Aug-/ + ASCII /-Sep-/ + ASCII /-Oct-/ + ASCII /-Nov-/ + ASCII /-Dec-/ + +;** PAGE 36 ** + +CPOPJ2: AOS (PDP) ;DOUBLE SKIP RETURN +CPOPJ1: AOS (PDP) ;SKIP SUBROUTINE RETURN +CPOPJ: POPJ PDP, + +TPOPJ1: AOS -1(PDP) ;RESTORE AC(TAC) AND SKIP SUBROUTINE RETURN +TPOPJ: POP PDP,TAC ;RESTORE AC(TAC) + POPJ PDP, +IPOPJ1: AOS -1(PDP) +IPOPJ: POP PDP,ITEM ;RESTORE ITEM + POPJ PDP, + +SYSPP: SIXBIT /DECSYS/ + +;** PAGE 37 ** + +PUUOAC: POINT 4,UUO,12, ;UUO AC FIELD +PIOMOD: POINT 4,IOS,35, ;MODE BITS +PDEVI: POINT 4,DEVCHN(DEVDAT),3, +PDEVO: POINT 4,DEVCHN(DEVDAT),7, + +;** PAGE 48 ** + +SAVDMP=='SAV + ;** CORE1 .MAC ** PAGE 2 + +;CORE UUO +;CALL: MOVEI AC,HIGHEST REL. ADR. DESIRED IN LOW SEG +; HRLI AC,HIGHEST REL. ADR. DESIRED IN HIGH SEG +; CALL AC,[SIXBIT /CORE/] +; ERROR RETURN +; OK RETURN TO USER +;RETURN MAX. NO. BLOCKS ALLOWED +;LH=0 -> DO NOT CHANGE HIGH SEG ASSIGNMENT +;RH=0 -> DO NOT CHANGE LOW SEG ASSIGNMENT +;BOTH HALVES=0 -> ERROR, RETURN MAX. NO. OF BLOCKS IMMEDIATELY W/O AFFECTING CORE + +CORUUO: JUMPE TAC,ZERCOR ;IS HE ASKING FOR ZERO CORE ? + PUSH PDP,TAC ;NO - SAVE HIGHEST ADDRESS + MOVEI TAC,(TAC) + JUMPE TAC,CORU1 ;IS RH=0 (IF SO - DO NOT CHANGE LOW SEG) + IORI TAC,1777 + SETZ ITEM, ;SET FOR LOW SEG. + PUSHJ PDP,CORE1 + JRST CORERR + +CORU1: HLRZ TAC,(PDP) + CAMG TAC,USRREL + AOS -1(PDP) ;PREPARE FOR SUCCESSFUL RETURN +CORERR: POP PDP,TAC + +ZERCOR: MOVE TAC,CORMAX ;# BLOCKS AVAILABLE + LSH TAC,-12 + JRST STOTAC + ;** CORE1 .MAC ** PAGES 8-18 + +;CALL: MOVE TAC,HIGHEST LEGAL ADDRESSABLE LOC. DESIRED +; MOVEI ITEM,(0=LOWCORE, 1=HIGH CORE) +; MOVE PROG,[XWD PROT.,0] = JBTADR(ITEM) +; PUSHJ PDP,CORE0 +; ERROR - NOT ENOUGH CORE +; OK RETURN +;AC(PROG)(=AC(JDAT)) SET TO NEW CORE ASSIGNMENT + +CORE0: ;CALLED BY GETMIN: (AMONG OTHER PLACES) + ; ALSO BY THE CORE UUO + + ;DROPS THROUGH TO CORE1, REGARDLESS: + ; REASON -> CORE IS ALWAYS "IN CORE" + +CORE1: + JUMPE PROG,CORGET ;OLD ASSIGNMENT=0 ? + ; IF YES, DON'T WORRY ABOUT IT + + JUMPN TAC,CORE1B ;ARE WE TRYING TO RELEASE ALL OF CORE ? + ; YES + PUSHJ PDP,RTV ;RESET "TIME" VARIABLES + .UCLOSE UPRGO, ;DESTROY INFERIOR + ; THEN CODE AT CORE1I SETS JBTbDR ENTRY TO 0 SINCE + ; WE ALREADY KNOW THAT AC(TAC)=0 + JRST CORE1I + ;** CORE1 .MAC ** PAGE 8-18 + +;COMES HERE IF OLD ASSIGNMENT .EQ. 0 AND NEW ASSIGNMENT .NE. 0 + +CORE1B: CAILE TAC,JOBDA ;LOW SEG - AND DOING A RESET ? + JRST CORE1F ;NO + PUSHJ PDP,RTV ;RESET "TIME" VARIABLES + .RESET UPRGO, ; AHA - WE FINALLY GET CLEARANCE + .USET UPRGO,[.SMASK,,[BIOADC\BILLOP\200000]] + .USET UPRGO,[.SUTRP,,[1]] + IORI TAC,1777 +CORE1I: MOVSI PROG,(TAC) + MOVEM PROG,JBTADR(ITEM) +CORE1L: PUSHJ PDP,SETREL + JRST CPOPJ1 + ;** CORE1 .MAC ** PAGES 8-18 + +CORGET: + JUMPE TAC,CPOPJ1 ;IS REQUESTED CORE=0, IF SO, DON'T BOTHER + ; DOING ANYTHING + +;NOW WE SEE THAT CORE IS BEING REQUESTED WHEN WE PREVIOUSLY HAVE HAD NO +; CORE ASSIGNED (AND THUS WERE WITHOUT AN INFERIOR). SO SET ONE UP. + +;NOTE: WE WILL USE PROG AS A FREE ACCUMULATOR + + PUSHJ PDP,TNAME ;TEST PROPOSED NAME + MOVEI PROG,IBOMDE ;IMAGE, BLOCK, OUTPUT MODE + HRLM PROG,FILNAM + .OPEN UPRGO,FILNAM ;CREATE THE INFERIOR HERE + JRST SYSERR + .USET UPRGO,[.SMASK,,[BIOADC\BILLOP\200000]] ;SET UP INTERRUPT BITS HERE. + .USET UPRGO,[.SUTRP,,[1]] ; THEY INCLUDE MEM PROT VIOLATION, SYS UUO TRAP, ILLEGAL INSTR, + ; PDL OVF, RESPECTIVELY. + MOVEI PROG,IBIMDE ;THIS IS SO THAT I CAN SEE YOU BETTER + HRLM PROG,FILNAM + .OPEN UPRGI,FILNAM + JRST SYSERR + MOVSI PROG,1777 + MOVEM PROG,JBTADR ;WE KNOW WE HAVE 1K OF LOW CORE AT THIS POINT + ;** CORE1 .MAC ** PAGES 8-18 + +;WE ARRIVE HERE HAVING MADE THE DECISION THAT THE CURRENT ASSIGNMENT OF CORE +; WILL NEEDS CHANGE THE FIRST ILLEGAL ADDRESS OF OUR INFERIOR. +; ASSIGNMENT OR CHANGE TO LOW SEG WHERE THERE IS NO HIGH SEG AROUND + +CORE1F: IORI TAC,1777 + HLRZ PROG,JBTADR(ITEM) ;ARE WE REQUESTING SAME AS BEFORE ? + CAMN PROG,TAC + JRST CORE1L ;YES - DON'T BOTHER WITH ANY MUCKING AROUND + ADDI TAC,1 + .USET UPRGO,[.SMEMT,,TAC] + SUBI TAC,1 + JRST CORE1I + ;** CORE1. MAC ** MISC + +;ROUTINE TO RESET "TIME" VAIABLE FOR PROCEDURE ON CHANNEL UPRGO, THIS +; ROUTINE CALLED JUST BEFORE PROCEDURE TO BE DESTROYED (AT "CORE 0" TIME). +; ALSO CALLED WHEN .RESET TO BE EXECUTED WHEN USER REQUESTS NEW CORE (AT GETMIN: +; TIME). +;CALL: PUSHJ PDP,RTV +; DESTROYS AC(PROG) + +RTV: + .USET UPRGO,[.RRUNT,,PROG] ;READ CURRENT RUN TIME OF INFERIOR JUST BEFORE + ; WE DESTROY IT + ADDM PROG,TRTPI ;ADD IT TO "TOTAL RUN TIME FOR PAST INFERIORS" + ADDM PROG,TRTPIT ;ADD IT TO "T.R.T FOR PAST INFERIORS SINCE LAST "TIME" + ; COMMAND" + MOVN PROG,TRTIT ;WE MAY HAVE DONE A "TIME" WHILE IN THE MIDST OF THE PROCEDURE + ADDM PROG,TRTPIT ;TO BE DESTROYED. THUS TRTPIT MUST BE DECREMENTED BY THE RUN TIME + SETZM TRTIT ; FOUND AT THAT MOMENT. + POPJ PDP, + ;** ERRCON.MAC ** PAGES 1+2 + +;APR-DETECTED ERRORS +; PUSHDOWN OVERFLOW AND ILLEGAL MEMORY +; FOR WHICH THE USER IS NOT ENABLED. + +APRILM: SETZM APRERR ;RESET APRERR WORD FOR NEXT ERROR + +APRIL1: TRNN TAC,BIOADC ;MEM PROT VIOLATION ?? + JRST APRPDL ;NO + +;ROUTINE TO HANDLE ILLEGAL MEMORY REFERENCES DUE TO PROTECTION FAILURES. +; CALLED EXCLUSIVELY FROM MAIN INTERRUPT DRIVER WHEN INFERIOR +; INTERRUPT DETECTED AND BIOADR (BIT 2.5) SEEN IN PIRQC WORD. + + HRRZ TAC,APRPC + CAMG TAC,USRREL + +;IS PC IN USER ASSSIGNED CORE AREAS ? + + JRST APRILR ;YES - MUST BE ILL MEM REF + JSP TAC,ERRPTU ;NO + ASCIZ /PC out of bounds/ + JRST APRSCD + +APRILR: JSP TAC,ERRPTU + ASCIZ /Ill mem ref/ + JRST APRSCD + +APRPDL: JSP TAC,ERRPTU + ASCIZ /PDL ov/ + +APRSCD: MOVE TAC1,APRPC + JRST PCPNT + + +;ADDRESS CHECK ERROR +;DEVDAT MUST BE SET UP TO POINT TO OFFENDING DEVICE + +ADRERR: JSP TAC,ERRPTU + ASCIZ /Address check for / + JRST DEVEXC ;PRINT "DEVICE XXX; UUO AT USER/EXEC YYY" + ; THEN STOP JOB AND FLAG AS AN ERROR STOP. + ;** ERRCON.MAC ** PAGES 3+4 + +;INPUT UUO FOR OUTPUT DEVICE + +ILLINP: JSP TAC,ERRPTU + ASCIZ /Device / + PUSHJ PDP,ERNAM ;PRINT "DEVICE XXX" + JSP TAC,UUOMES ;PRINT MESSAGE + ASCIZ / cannot do input/ + +;ILLEGAL DEVICE DATA MODE (INIT, OPEN, OR SETSTS UUO'S) + +ILLMOD: JSP TAC,ERRPTU + ASCIZ /Illegal data mode for / + JRST DEVEXC ;PRINT "DEVICE XXX", AND UUOPC + +;IO UUO TO USER CHANNEL W/NO PREVIOUS INIT OR OPEN + +IOIERR: JSP TAC,ERRPTU + ASCIZ /IO to unassigned channel/ + JRST UUOPCP + ;** ERRCON.MAC ** PAGES 5+6 + +;SYSTEM ERROR + +SYSERR: JSP TAC,ERRPTU + ASCIZ/System error/ + MOVE TAC1,UUO0 + SOJA TAC1,PCPNT + +;ILLEGAL UUO + +UUOERR: JSP TAC,ERRPTU + ASCIZ /Illegal UUO/ + MOVE TAC1,UUO0 ;GET UUOPC + SOJA TAC1,PCPNT + +;ILLEGAL INSTRUCTION +; HALT INSTRUCTION IS A SPECIAL CASE WHICH STOPS JOB +; BUT THE USER MAY CONTINUE FROM IT. (AT EFFECTIVE ADDR.) + +ILLINS: HLRZ TAC,UUO + CAIN TAC,254200 ;A JRST 4, ? + JRST HALTI ;YES + JSP TAC,ERRPTU ;NO + ASCIZ /Ill inst./ + JRST UUOPCP + +HALTI: JSP TAC,ERRPTU + ASCIZ /Halt/ + SOS TAC1,USRPD1 ;UUO PC = LOC OF HALT+1 + PUSHJ PDP,PCP ;PRINT "AT USER XXX" + PUSHJ PDP,INLMES + ASCIZ / + +./ + HRRM UUO,USRPD1 ;SAVE EFFECTIVE ADDR + PUSHJ PDP,TTYSTC + PUSHJ PDP,STOP1 + PUSH PDP,USRPD1 ;SAVE "RETURN" ADDR - LET UUO EXIT ROUTINES + ; TAKE CARE OF US - NOTE IT WILL FIND A STOPPED JOB. + JRST USRXIT + +;ROUTINE TO PRINT "DEVICE XXX; UUO AT EXEC/USER YYY" +; THEN STOP JOB + +DEVEXC: PUSHJ PDP,ERNAM + JRST EXCALP + ;** ERRCON.MAC ** PAGES 8+9 + +;COMMON ERROR MESSAGE SETUP ROUTINE +;CALL: JSP TAC,ERRPTU +; ASCIZ /MESSAGE/ +; AC(DEVDAT) SAVED IN 0(PDP) +; AC(DAT) SAVED IN -1(PDP) + +ERRPTU: +ERRDEV: PUSH PDP,DAT + PUSH PDP,DEVDAT + PUSH PDP,TAC + MOVE PROG,JBTADR + PUSHJ PDP,TTYFNU + PUSHJ PDP,INLMES + ASCIZ /? +?/ + JRST INLMES ;PRINT CALLER REQUESTED MESSAGE AND RETURN + +;ROUTINE TO PRINT UUO PC AND STOP JOB +; IF IN USER MODE PC WILL PRINT AS "AT USER XXX" +; IF IN EXEC MODE -- "AT EXEC XXX; UUO AT EXEC/USER YYY" + +UUOMES: PUSHJ PDP,CONMES ;PRINT MESSAGE POINTER TO BY TAC +UUOPCP: MOVE TAC1,USRPD1 ;UUO PC + SOJA TAC1,PCPNT ;DECREMENT TO POINT TO UUO + + +;ROUTINE TO PRINT 1 OF 3 MESSAGES AND STOP JOB +; "AT EXEC XXX; UUO AT EXEC YYY" +; "AT EXEC XXX; UUO AT USER YYY" +; "AT USER YYY" +;CALL: MOVE TAC1,XXX +; PUSHJ PDP,PCPNT + +PCPNT: PUSHJ PDP,PCP + TLNE TAC1,USRMOD + JRST PCSTOP + +;ROUTINE TO PRINT 1 OF 2 MESSAGES AND STOP JOB +; ";UUO AT EXEC YYY" +; ";UUO AT USER YYY" + +EXCALP: PUSHJ PDP,INLMES + ASCIZ /; UUO/ + MOVE TAC1,USRPD1 ;UUOPC + SUBI TAC1,1 + PUSHJ PDP,PCP +PCSTOP: PUSHJ PDP,HOLD ;STOP JOB + POP PDP,DEVDAT ;RETURNS ONLY IF AT "INTERRUPT LEVEL"; + ; I.E. FROM COMMAND SCANNER OR FROM APR INTERRUPT + JRST TPOPJ ;RETURN AFTER REMOVING STACKED INFO STORED AT ERRPTU: + ;** ERRCON.MAC ** PAGE 10 + +;ROUTINE TO PRINT PC AS "EXEC XXX" OR "USER XXX" +;CALL: MOVE TAC1,PC TO PRINT(LH(FLAGS) +; PUSHJ PDP,PCP + +XMODE: ASCIZ / at exec PC / + +UMODE: ASCIZ / at user PC / + +PCP: MOVEI TAC,XMODE + TLNE TAC1,USRMOD + MOVEI TAC,UMODE + PUSHJ PDP,CONMES + HRRZ TAC,TAC1 ;PRINT RH IN OCTAL + ; FALL INTO OCTPNT + +;ROUTINE TO PRINT 6 DIGIT OCTAL # +;CALL: HRR TAC,OCTAL # +; PUSHJ PDP,OCTPNT +; RETURN AC(TAC1) PRESERVED, AC(TAC) DESTROYED + +OCTPNT: HRLZ TAC,TAC ;MOVE TO LH FOR ROTATING + TRO TAC,700000 ;SET UP AN END FLAG + + +OCTP1: ROT TAC,3 ;GET NEXT OCTAL DIGIT + TLNN TAC,-1 ;WAS THAT FLAG ? + POPJ PDP, ;YES - DO NOT PRINT - ONLY RETURN TO LOSER + PUSHJ PDP,PRTNUM ;NO, PRINT OCTAL DIGIT + HRRI TAC,0 ;CLEAR RH + JRST OCTP1 + +;ROUTINE TO ADD 1 TO TAC AND PRINT DECIMAL + +DECP1: AOJA TAC,RADX10 ;ADD 1 AND GO PRINT + +;ROUTINE TO PRINT DECIMAL +;CALL: MOVE TAC,DECIMAL # +; PUSHJ PDP,RADX10 +; RETURN -- TAC1 PRESERVED, TAC DESTROYED + +RADX10: PUSH PDP,TAC1 ;SAVE TAC1 + PUSHJ PDP,PRTDIG ;PRINT DECIMAL DIGITS + POP PDP,TAC1 ;RESTORE TAC1 +EIGHT: POPJ PDP,10 + +;RECURSIVE DECIMAL PRINT ROUTINE +;CALL: MOVE TAC,DECIMAL # +; PUSHJ PDP,PRTDIG + +PRTOCT: SKIPA TEM,EIGHT ;RADIX 8. PRINT ROUTINE +PRTDIG: MOVEI TEM,12 ;RADIX 10. PRINT ROUTINE +PRTDG1: IDIVI TAC,(TEM) ;DIVIDE BY 10 + HRLM TAC1,(PDP) ;RT HALF ON PD LIST + JUMPE TAC,.+2 ;FINISHED + PUSHJ PDP,PRTDG1 ;NO + HLRZ TAC,(PDP) ;GET LAST # +PRTNUM: MOVEI TEM,60(TAC) ;PUT CHAR IN CHAR AC (TEM=CHREC) + JRST OUTCHS ;OUTPUT CHAR + ;** ERRCON.MAC ** PAGE 11 + +;ROUTINE TO PRINT "DEVICE XXX" +;CALL: PUSH PDP,DEVDAT +; PUSHJ PDP,ERNAM + +ERNAM: PUSHJ PDP,INLMES + ASCIZ /Device / + SKIPE TAC1,-1(PDP) + MOVE TAC1,DEVNAM(TAC1) ;FALL INTO PRNAME + +;ROUTINE TO PRINT SIXBIT NAME +;CALL: MOVE TAC1,NAME +; PUSHJ PDP,PRNAME + +PRNAME: ;PRINT SIXBIT NAME IN AC(TAC1) + MOVEI TAC,0 + LSHC TAC,6 ;SHIFT IN NEXT CHAR + JUMPE TAC,CPOPJ + MOVEI TEM,40(TAC) ;MAKE IT ASCII + PUSHJ PDP,OUTCHS + JRST PRNAME + ;** ERRCON.MAC ** MISC + +;TNM DEVICE FAILED DURING ATTEMPTED .OPEN +; MUST BE ILLEGAL OR IN USE AS A CONSOLE TTY + +TTYNA: JSP TAC1,ERRAVL ;RETURN PDEVO CHANNEL TO COMMON POOL + 0 ;BUT DON'T TYPE A MESSAGE + PUSHJ PDP,ERNAM ;"ERROR IN JOB XX + ;DEVICE TTYNM" + JSP TAC,UUOMES + ASCIZ / not available/ + +;.OPEN ON DEVICE TPL: FAILURE +; MUST BE A FULL DIRECTORY + +TPLNA: JSP TAC1,ERRAVL ;RETURN PDEVO CHANNEL TO POOL + 0 + PUSHJ PDP,ERNAM + JSP TAC,UUOMES + ASCIZ / not available/ + +ERRAVL: LDB TAC,PDEVO ;FREE UP CHANNEL + PUSHJ PDP,RTFCHN + SETZ TAC, + DPB TAC,PDEVO + MOVEI TAC,(TAC1) + JRST ERRPTU + ;** JOBDAT.MAC ** + +JOBDAC==20 +JOBDPD==JOBDAC+PDP +JOBD16==JOBDAC+16 + +JOB41==41 ;USER UUO JSR LOCATION +JOBREL==44 ;LH=0, RH=HIGHEST REL. ADR. IN USER AREA + ; (IE LOW SEGMENT). SET BY MONITOR EACH TIME JOB CHANGES + ; CORE SIZE. +JOBPD1==45 +JOBPRT==72 ;FIRST LOC PROTECTED +JOBHCU==72 +JOBPC==JOBHCU+1 +JOBDDT==74 ;LH UNUSED + ;RH=STARTING ADDRESS OF USER DDT +JOBSAV==JOBDDT-1 ;FIRST LOC-1 WRITTEN BY SAVE COMMAND +JOBJDA==JOBDDT+1 ;JOB DEVICE ASSIGNMENT TABLE + ; LH=UUO'S DONE SO FAR + ; RH=ADR. OF DEVICE DATA BLOCK IN MONITOR +JOBLO==JOBJDA ;FIRST LOC TO ZERO OUT DURING A RESET UUO +JOBSV==JOBJDA+1 ;FIRST LOC READ INTO OR WRITTEN FROM BY NEW + ; SAVGET WHICH ZERO-COMPRESSES. THIS LOC CONTAINS + ; THE FIRST IOWD W/NO. OF DATA WORDS IN LH, FIRST ADR-1 + ; IN RH. +JOBSVM==JOBSV-1 ;FIRST LOC-1 USED FOR SETTING UP DUMP MODE + ; COMMAND LIST FOR SAVGET +JOBSDD==JOBJDA+17 ;PLACE TO SAVE JOBDDT ON SAVE +JOBPFI==JOBJDA+17 ;HIGHEST LOC IN JOB DATA AREA PROTECTED FROM IO +JOBHI==JOBJDA+17 ;LAST LOC TO ZERO OUT DURING A RESET UUO (C.F. USRHI) +JOBHRL==115 ;LH IS FIRST FREE LOC IN HIGH SEG RELATIVE TO ORIGIN. + ; ANALAGOUS TO LH OF JOBSA FOR LOW SEG. (IE LH=LENGTH TO + ; SAVE ON SAVE COMMAND). SET BY LOADER. + ; RH ANALAGOUS TO JOBREL, IE HIGHEST LEGAL USER ADDRESS IN HIGH SEG. +JOBSA==120 ;LH=INITIAL FIRST FREE LOCATION IN LOW SEG (SET BY LOADER) + ;RH=STARTING ADDRESS OF USER PROGRAM + ;(SET FROM HIGH DATA AREA ON GET IF NO LOW FILE) +JOBFF==121 ;CURRENT FIRST FREE LCATION IN LOW SEG USED + ; AND UPDATED BY MONITOR TO ASSIGN IO BUFFERS IN TOP OF USER + ; AREA. + ; USER MAY CHANGE CONTENTS IN ORDER TO AFFECT PLACEMENT OF + ; BUFFERS BY MONITOR +JOBS41==122 ;C(JOB41) SAVED HERE ON SAVE COMMAND. + ; RESTORE FROM HERE ON GET. +JOBREN==124 ;REENTER ADDRESS FOR REENTER COMMAND. + ; (SET FROM HIGH DATA AREA ON GET IF NO SAVE FILE) +JOBAPR==125 ;PLACE TO TRAP TO IN USER AREA ON APR TRAP. + ; ENABLED BY APRENB UUO. +JOBCNI==126 ;APR IS "CONI'ED" INTO C(JOBCNI) ON APR TRAP +JOBTPC==127 ;PC IS STORED HERE ON USER APR TRAP +JOBOPC==130 ;OLD PC IS STORED HERE ON START, DDT, REENTER, + ; STARTC COMMANDS. +JOBCOR==133 ;(SET FOM HIGH DATA AREA IN NO LOW FILE) + ; LH=HIGHEST LOCATION LOADED (LOW SEG) W/PROG OR DATA. + ; (BLOCK STATEMENTS DO NO COUNT HERE). SAVE WILL NOT + ; WRITE THE LOWSEG OF A 2 SEG PROG IF LH IS <= 137 + ; AND GET WILL NOT READ. + ; RH=SIZE OF CORE FROM LOW SEG ON RUN, SAVE, GET COMMANDS. + ; (SET FROM HIGH DATA AREA ON GET IF NOT LOW FILE) + ; SET BY SAVE TO CORE ASSIGNMENT TO BE USED ON GET (UNLESS USER + ; TYPES A LARGER ARG TO GET) TO FRIST FREE LOC-1 (OR TOP + ; OF USER DDT) OR TO USER'S CORE ARG TO SAVE IF BIFFER. + ; GET ALWAYS SET RH TO INITIAL CORE ASSIGNMENT SO THAT PROG + ; CAN RESTORE CORE TO ORIGINAL ASSIGNMENT ON RESTARTING. +JOBVER==137 ;CONTAINS VERSION # (OCTAL) OF CUSP BEING RUN IN RH +JOBDA==140 ;FIRST LOC NOT USED BY JOB DATA AREA +JOBHSA==400000 ;A COPY OF JOBSA +JOBH41==400001 ;A COPY OF JOB41 +JOBHCR==400002 ;A COPY OF JOBCOR +JOBHRN==400003 ;A COPY OF JOBHRL/JOBREN +JOBHVR==400004 ;A COPY OF JOBVER +JOBHNM==400005 ;HIGH SEGMENT NAME +JOBHSM==400006 ;HIGH SEGMENT SYMBOLS +JOBHDA==400010 ;FIRST LOCATION NOT USED + ;** LPTSER.MAC ** + +LPTSIZ==201 + +LP0DDB: SIXBIT /LPT/ ;DEVNAM + LPTSIZ ;DEVCHR. (LH UNUSED SINCE THIS DDB IS NEVER USED AS A PROTOTYPE) + ; RH - SIZE OF BUFFER + 0 ;DEVIOS + LPTDSP ;DEVSER + DVOUT+DVLPT,,1_A+1_AL+1_I ;DEVMOD + +LP0LEN==.-LP0DDB ;LENGTH OF NON-ZERO SEGMENT OF LP0DDB + + 0 ;DEVLOG + 0 ;DEVBUF + 0 ;DEVIAD + 0 ;DEVOAD + 0 ;DEVCHN + +LP0DDS==.-LP0DDB + + LOC LP0DDB+LP0LEN ;RELOCATE OURSELVES OVER ZERO SEGMENT OF + ; LP0DDB + ;** LPTSER.MAC ** + +;LINE PRINTER SERVICE DISPATCH TABLE + +LPTDSP: JRST CPOPJ ;RELEASE + JRST LPTCLS ;CLOSE + JRST LPTOUT ;OUTPUT + JRST ILLINP ;INPUT + +LPTCLS: PUSHJ PDP,OUT ;WRITE OUT LAST BUFFER IF THERE IS SOMETHING THERE + LDB TAC,PDEVO ;HAVE WE REALLY SET UP AN ACTIVE TPL: FILE ? + JUMPE TAC,CPOPJ ;NO + ROT TAC,-13. ;INSERT CHANNEL # INTO AC FIELD + IOR TAC,[.CLOSE 0,] ;CONSTRUCT A .CLOSE CHNUM, + XCT TAC ;DO IT + LDB TAC,PDEVO ;NOW RETURN CHANNEL TO GENERAL POOL + PUSHJ PDP,RTFCHN + SETZ TAC, + DPB TAC,PDEVO ;AND SIGNAL NO ACTIVE FILE IN LPTDDB + POPJ PDP, + ;** LPTSER.MAC ** + +;LINE PRINTER OUTPUT UUO ROUTINE + +LPTOUT: HRRZ TAC,DEVOAD(DEVDAT) ;GET ADDR IN USER CORE OF CURRENT BUFFER + HRLZI TAC,1(TAC) ;WE WANT TO BEGIN READING FROM 3RD WORD OF BUFFER + HRRI TAC,MONBUF ;AND WE WILL PUT IT INTO MONBUF + .UBLTI TAC,MONBUF+LPTSIZ-1 ;READ IN LPTSIZ WORDS + HRRZ TAC1,MONBUF ;-WORD COUNT + JUMPE TAC1,LPTOU2 ;IF=0, THERE IS NOTHING TO DO + LDB TAC,PDEVO ;HAVE WE AN ACTIVE TPL: FILE SET UP ? + JUMPN TAC,LPTOU1 ;SKIP TO LPTOU1: IF SO + PUSHJ PDP,GTFCHN ;NOT SO, FIRST GET A CHANNEL FOR OURSELVES + JRST NOCHNE + DPB TAC,PDEVO ;INSERT IT INTO LPTDDB: + ROT TAC,-13. ;CONSTRUCT A .OPEN CHNUM,FILNAM + IOR TAC,[.OPEN 0,FILNAM] + MOVE AC1,[IBOMDE,,(SIXBIT /TPL/)] + MOVEM AC1,FILNAM + XCT TAC ;DO THAT .OPEN + JRST TPLNA ;THE TPL: DEVICE WILL NOT ACCEPT THE .OPEN +LPTOU1: IMULI TAC1,5 ;-> # OF CHARACTERS TO PROCESS + MOVE AC1,[POINT 7,MONBUF,35,] + MOVE AC2,[POINT 7,MONBUF,35,] + ILDB AC3,AC1 ;COLLECT CHARACTER FROM TAKER + JUMPE AC3,.+3 ;FILTER OUT NULLS AND EMBEDDED ^C'S + CAIE AC3,3 + IDPB AC3,AC2 ;A GOOD CHARACTER GOES BACK INTO PUTTER + SOJG TAC1,.-4 + MOVEI TAC1,(AC2) + MOVEI TAC,3 + IDPB TAC,AC2 ;FILL OUT FINAL WORD WITH ^C'S + CAIN TAC1,(AC2) + JRST .-2 + MOVNI TAC1,-MONBUF(TAC1) + HRLZI TAC1,(TAC1) + HRRI TAC1,MONBUF+1 ;BEGIN WRITING AT MONBUF+1 + LDB TAC,PDEVO ;NOW THE .IOT-WORD IS SETUP, NEXT CONSTRUCT + ROT TAC,-13. ;THE .IOT ITSELF + IOR TAC,[.IOT 0,TAC1] + XCT TAC ;WRITE OUT THIS BUFFER'S WORTH +LPTOU2: PUSHJ PDP,ADVBFE ;ADVANCE OUTPUT BUFFER + POPJ PDP, + JRST OUT ;MORE TO OUTPUT, FIRST GO COMPUTE PROPER WORD COUNT + ;** SCNSRF.MAC ** + +;DATA STRUCTURES AND PARAMETERS + +;TTY DDB FORMAT + +; DEVCHR: RIGHT HALF +; BITS 24-35 = MONITOR BUFFER SIZE+1 + +; DEVIOS: LEFT HALF + IOSUPR==200 ;SUPPRESS ALL OUTPUT TILL NEXT + ;INPUT OR INIT (^0) + TPMON==400 ;TTY IS IN MONITOR COMMAND MODE + DDTM==1000 ;DDT MODE + SYNC==20000 ;BREAK CHAR SEEN - SIGNAL TO + ;INCREMENT SYNC COUNT + TTYIOW==400000 ;TTY INPUT WAIT BIT -- RESET BY CHAR INTERRUPT + ;PROCESSOR AND USED AS A SWITCH WHEN PROGRAM NO LONGER WAITING FOR TTY + +; DEVIOS: RIGHT HALF + FCS==100 ;FULL CHARACTER SET. PASS ON ALL + ;CHARS EXCEPT ^C - NO SPECIAL PROCESSING + NOECHO==200 ;ECHO SUPPRESSION REQUESTED BY PROG + DLRSUP==400 ;400 SUPPRESSES "$" FOR ALTMODE + +; DEVIAD: BITS 6-12 = HORIZONTAL POSITION +; (BYTE POINTER = PHPOS) + +;THE FOLLOWING ARE DIFINITIONS OF THE RELATIVE LOCATIONS OF THE +;BUFFER PARAMETER WORDS OF THE DEVICE DATA BLOCK + +BUF==0 ;BUF(DAT) CONTAINS POINTER TO BEG. OF CURRENT BUFFER +PUTR==1 ;PUTR(DAT) = BYTE POINTER TO PUT CHARACTERS INTO BUFFER. + ; IT MUST ALWAYS BE AHEAD OF OR EQUAL TO THE TAKER POINTER. +PCTR==2 ;NUMBER OF TIMES PUTR MAY BE INCREMENTED BEFORE + ; REACHING THE LAST BYTE IN THE LAST WORD OF THE BUFFER. +TAKR==3 ;TAKER POINTER TO PICK UP CHARACTERS. + ; WHEN THE TAKR IS EQUAL TO THE PUTR, THE BUFFER IS "EMPTY." +TCTR==4 ;COUNT OF NUMBER OF TIMES TAKR CAN BE INCREMENTED BEFORE + ; REACHING PHYSICAL END OF THE BUFFER. +FCTR==5 ;COUNT OF FREE CHARACTERS LEFT IN BUFFER, I.E. + ; HOW MANY TIMES THE PUTR MAY BE INCREMENTED BEFORE IT WOULD + ; COME AROUND AND "STEP ON" THE TAKR. WHEN =0, NO MORE CHARS + ; MAY BE PLACED IN THE BUFFER. + ;** SCNSRF.MAC ** + +;DEFINITION OF LINE CHARACTERISTCS (SEE TTYLIN OF SCNDDB) + +FULTWX==4 ;SELF-ECHOING FULL DUPLEX (I.E. DATEL) +T35==10 ;MODEL 35 +T37==20 ;MODEL 37 +ROBTPD==40 ;RUBOUT TYPED LAST (ECHO \ BEFORE NEXT CHAR.) + +LGLSET==T35+T37+FULTWX ;THESE CAN BE SET OR RESET BY PROGRAM + +;ACCUMULATOR ASSIGNMENTS + +CHREC==TEM ;AC FOR CHARACTER +DDB==DEVDAT ;ADDRESS OF DEVICE DATA BLOCK +LINE==TAC1 ;SCANNER LINE NUMBER +HPOS==ITEM ;HORIZONTAL POSITION OF TTY (0-71) + +;BYTE POINTERS + +PHPOS: POINT 7,DEVIAD(DEVDAT),12, ;HORIZONTAL POSITION +PCOMIC: POINT 9,TTYPTR(DDB),19, ;FOR RESCANNING COMMAND INPUT LINE +PLSTLC: POINT 9,TTYPTR(DDB),28, ;FOR ^U DELETION + +;TTYPTR CONTAINS THE FOLLOWING BYTES: +; +; 11-19 PCOMIC, FOR COMMAND RESCAN +; 20-28 PLSTLC, FOR ^U + ;** SCNSRF.MAC ** PAGE 8 + +SETBFI: MOVEI DAT,1 + DPB DAT,PCOMIC ;FOR RESCAN + DPB DAT,PLSTLC ;FOR ^U + MOVEI DAT,TTIBUF(DDB) + SETZM TISYNC(DDB) ;ZERO BREAK COUNT + MOVE TAC,BUF(DAT) + HRLI TAC,(POINT 7,,-1,) + MOVEM TAC,TAKR(DAT) + MOVEM TAC,PUTR(DAT) + MOVEI TAC,1 + MOVEM TAC,TCTR(DAT) + MOVEM TAC,PCTR(DAT) + HLRZ TAC,BUF(DAT) + MOVEM TAC,FCTR(DAT) + POPJ PDP, + +TSETBF: PUSHJ PDP,SETBFI +SETBF2: .RESET CTYO, + POPJ PDP, + + +;ROUTINE TO PUT A CHARACTER INTO A BUFFER +;CALL MOVEI DAT,TTXBUF(DDB) ;SPECIFIES BUFFER +; PUSHJ PDP,PUTCHI +; ERROR RETURN, BUFFER "FULL" +; SUCCESSFUL RETURN + +PUTCHI: SOSGE FCTR(DAT) + JRST PUTCI0 + SOSLE PCTR(DAT) ;LAST BYTE IN BUFFER FILLED ? + JRST PUTCI1 ;NO - GO AHEAD + PUSH PDP,TAC + MOVE TAC,BUF(DAT) + HLRZM TAC,PCTR(DAT) + HRLI TAC,440700 ;MAKE A BYTE POINTER + MOVEM TAC,PUTR(DAT) ;STORE IT + POP PDP,TAC ;RESTORE TAC +PUTCI1: IDPB CHREC,PUTR(DAT) + JRST CPOPJ1 + + ;** SCNSRF.MAC ** PAGES 9+10 + +;ROUTINE TO PICK UP A CHARACTER FROM ANY BUFFER +;CALL MOVEI DAT,TTXBUF(DDB) ;SPECIFIES BUFFER +; PUSHJ PDP,GETCHR +; ONLY RETURNS TO HERE + +GETCHR: HLRZ CHREC,BUF(DAT) ;SIZE OF THIS BUFFER + CAMG CHREC,FCTR(DAT) + JRST GETCH1 + SOSLE TCTR(DAT) + JRST GETCH2 + MOVE CHREC,BUF(DAT) + HLRZM CHREC,TCTR(DAT) + HRLI CHREC,440700 + MOVEM CHREC,TAKR(DAT) +GETCH2: ILDB CHREC,TAKR(DAT) + AOS FCTR(DAT) + JUMPE CHREC,GETCHR + POPJ PDP, +GETCH1: TDZA CHREC,CHREC +PUTCI0: AOS FCTR(DAT) + POPJ PDP, + +;ROUTINE TO PLACE A CHARACTER INTO THE OUTPUT BUFFER + +PUTCHO: PUSH PDP,TAC ;SAVE TAC + LDB TAC,PDEVO ;GET OUTPUT CHANNEL ON I.T.S. + DPB TAC,[POINT 4,TAC,12,] ; AND STICK IT IN CURRENT AC + TLO TAC,(.IOT) + HRRI TAC,CHREC +PUTCH: XCT TAC + JRST TPOPJ ;POP PDP -> AC(TAC), THEN RETURN + +;ROUTINE TO CHECK IF A CHARACTER IS SPECIAL (ASCII 0-37, 175-177) +;CALL MOVE CHREC,CHAR. TO BE CHECKED +; PUSHJ PDP,SPCHEK +; RETURN1 IF REGULAR ASCII CHAR (40-174), C(TAC)=0 +; RETURN2 IF SPECIAL CHAR., TAC LOADED WITH WORD FROM SPCTAB + +SPCHEK: MOVEI TAC,0 + CAIGE CHREC,40 + JRST SPCHK1 + CAIG CHREC,174 + POPJ PDP, + SKIPA TAC,SPCTAB-135(CHREC) +SPCHK1: MOVE TAC,SPCTAB(CHREC) + JRST CPOPJ1 ;SKIP RETURN + ;** SCNSRF.MAC ** PAGE 11 + +;SPECIAL CHARACTER TABLE +;FORMAT XWD BITS,ADDRESS OF ROUTINE + +;HIGH ORDER BITS IN LEFT HALF: + +SPACTN==400000 ;SPECIAL ACTION TO BE TAKEN +SPOUT==100000 ;SPECIAL HANDLING ON UUO OUTPUT + ; I.E. VT,FF,HT +BREAKB==20000 ;BREAK CHARACTER +FCSBRK==4000 ;BREAK CHARACTER IN FCS (100) MODE +ECHSUP==2000 ;SUPPRESS ECHO OF CHAR ITSELF + +SPCTAB: ECHSUP,,0 ;NULL + ECHSUP,,0 ;^A + ECHSUP,,0 ;^B + SPACTN+ECHSUP+BREAKB,,CONTC ;^C + ECHSUP,,0 ;^D + ECHSUP,,0 ;^E + ECHSUP,,0 ;^F + FCSBRK,,0 ;^G + SPACTN,,CONTH ;^H + SPACTN+SPOUT,,CONTI ;^I + BREAKB,,0 ;^J + SPACTN+SPOUT+BREAKB,,CONTK ;^K + SPACTN+SPOUT+BREAKB,,CONTL ;^L + SPACTN,,CR ;^M + ECHSUP,,0 ;^N + SPACTN,,CONTO ;^O SUPPRESS OUTPUT + ECHSUP,,0 ;^P + ECHSUP,,0 ;^Q + ECHSUP,,0 ;^R + ECHSUP,,0 ;^S + ECHSUP,,0 ;^T + SPACTN,,CONTU ;^U + ECHSUP,,0 ;^V + ECHSUP,,0 ;^W + ECHSUP,,0 ;^X + ECHSUP,,0 ;^Y + SPACTN+BREAKB+ECHSUP,,CONTZ ;^Z + SPACTN+BREAKB+ECHSUP,,ALTMOD ;ASCII 33 + ECHSUP,,0 ;ASCII 34 + ECHSUP,,0 ;ASCII 35 + ECHSUP,,0 ;ASCII 36 + ECHSUP,,0 ;ASCII 37 + +;CHARS 0-40 ABOVE, 175-177 BELOW: + + SPACTN+BREAKB+ECHSUP,,ALTMOD ;ASCII 175 + SPACTN+BREAKB+ECHSUP,,ALTMOD ;ASCII 176 + SPACTN+ECHSUP+FCSBRK,,RUBOUT ;177 + ;** SCNSRF.MAC ** PAGE 12 + +;INPUT TO DDT +;CALL AC,[SIXBIT /DDTIN/] +;BUFFER AREA MUST BE 21 WORDS LONG + +DDTIN: PUSHJ PDP,TTYFNU + MOVSI IOS,TTYIOW+DDTM + IORB IOS,DEVIOS(DDB) ;PUT INTO I/O WAIT + ; IF WE FIND AN EMPTY BUFFER + MOVE TAC,TIPUTR(DDB) ;PLACE IN BUFFER TO PUT NEXT CHAR + CAMN TAC,TITAKR(DDB) ;ANYTHING IN BUFFER ? + PUSHJ PDP,TWSYNC ;NO + MOVSI IOS,TTYIOW + ANDCAB IOS,DEVIOS(DDB) + MOVSI TAC,IOFST+DDTM + IORM TAC,DEVIOS(DEVDAT) + .UMOVE TAC,(UUO) ;CONTENTS OF USER AC + HRRZ TAC,TAC + ADDI TAC,21 + PUSHJ PDP,IADRCK + JRST ADRERR + SUBI TAC,21 + PUSHJ PDP,IADRCK + JRST ADRERR + PUSH PDP,TAC + MOVE AC2,[POINT 7,MONBUF,-1,] ;TEMPORARILY PUT CHARS INTO MONBUF - SEND THEM + ; TO USER W/A .UBLTO + MOVEI DAT,TTIBUF(DDB) + MOVEI AC1,<21*5>-1 ;= # CHARS ALLOWED + ;** SCNSRF.MAC ** PAGE 13 + +XFRIN: PUSHJ PDP,GETCHR + JUMPE CHREC,XFRIN2 + PUSHJ PDP,SPCHEK + JRST XFRIN1 + TLNE TAC,FCSBRK+BREAKB + SOS TISYNC(DDB) +XFRIN1: CAIN CHREC,3 ;A PRESTORED ^C ? + JRST DDTCNC ;YES - GO INTO MONITOR MODE + IDPB CHREC,AC2 ;PUT CHAR INTO INTERMEDIARY BUFFER + SOJG AC1,XFRIN +XFRIN2: MOVEI CHREC,0 ;TERMINATE STRING + IDPB CHREC,AC2 + MOVSI TAC,IOSUPR + ANDCAM TAC,DEVIOS(DEVDAT) + HRRZI AC2,-MONBUF(AC2) ;= WORD # WHERE FINAL STRING STORED + POP PDP,TAC ;TAC HAS ADR IN USER AREA + ADDI AC2,(TAC) ;COMPUTE FINAL ADDR IN USER AREA + ; AC(AC2) = "TO" ADDR + HRLI TAC,MONBUF ;THE "FROM" ADDR + .UBLTO TAC,(AC2) ;ZAP IT TO USER + POPJ PDP, ;ALL DONE + +DDTCNC: PUSHJ PDP,STLNAC ;GET LINE CHARACTERISTICS + JRST MONUS6 ;GO PROCESS ^C + +;TWSYNC: IS CALLED FOR INPUT IO WAIT. SPECIFICALLY FROM 4 PLACES. +; (1) DDTIN: WAITING FOR INPUT IN DDT MODE, (2) TTYIN: WAITING FOR INPUT +; IN LINE MODE (INPUT UUO FOR TTY), (3) INCHWL: TTCALL WAITING FOR +; CHARACTER, LINE MODE, AND (4) INCHRW: TTCALL WAITING FOR A +; CHARACTER, DDT MODE. + +TWSYNC: JRST WSYNC + + ;AT WSYNC: WE WILL SAVE THE BULK OF OUR ACCUMULATORS, INCLUDING + ; OUR PUSHDOWN STACK. NOTE: THE IOACT BIT IN AC(IOS) IS ALWAYS SET WHICH + ; WOULD INVOKE SAVING ACCUMULATORS. SINCE WE DO NOT WISH TO LOSE + ; OUR PUSHDOWN STORAGE, WE WILL HAVE TO HAVE TWO PUSHDOWN LISTS - + ; CORRESPONDING TO THAT USED BY THE SCANNER SERVICE AND THE INITIAL PART + ; OF THE COMMAND DECODER (IN NULL JOB) AND THAT OF UUOCON AND COMCON + ; AFTER MONSTR HAS BEEN CALLED. + ;** SCNSRF.MAC ** PAGES 14+15 + +;OUTPUT FROM DDT +;CALL AC,[SIXBIT /DDTOUT/] +; AC HAS POINTER TO DDT OUTPUT BUFFER + +DDTOUT: PUSHJ PDP,TTYFNU + .UMOVE UUO,(UUO) +DDT5: MOVSI IOS,DDTM + IORB IOS,DEVIOS(DDB) + PUSHJ PDP,TYUUO ;SIGNAL TTY OUTPUT UUO IN PROGRESS + HRRI UUO,-1(UUO) ;COMPENSATE FOR GETWD1: +DDT2: MOVE DAT,[440700,,TAC] ;BYTE POINTER TO AC(TAC) + PUSHJ PDP,GETWD1 ;GET THE USER'S WORD +DDT3: TLNN DAT,760000 ;ANY CHARS LEFT? + JRST DDT2 ;NO - NEXT WORD NEEDED + ILDB CHREC,DAT ;YES - GET NEXT + JUMPE CHREC,CPOPJ ;NULL ENDS THE STRING + PUSHJ PDP,OUTCHR ;OUTPUT CHAR + JRST DDT3 + +TYUUO: TLNE IOS,IOSUPR ;WILL CHARACTERS ACTUALLY GO OUT ? +TTYUU1: JRST CPOPJ ;NO + SETOM TTYOIP ;YES, SIGNAL TTY OUTPUT IN PROGRESS + SETZM CNCLAS ;AND NOT ^C LAST + LDB CHREC,TITAKR+CTYDDB ;WAS LAST CHAR TYPED A ^C ? + CAIN CHREC,3 + SETOM CNCLAS ;YES, SET FLAG + .DISMIS TTYUU1 ;AND NOW LEAVE INTERRUPT LEVEL !!! + ;** SCNSRF.MAC ** PAGE 15 + +;OUTCHR: CALLED TO OUTPUT A CHARACTER +; AC(DAT) AND AC(DDB) MUST BE SET UP +; CHECK IS MADE FOR WHETHER SPECIAL ECHO IS REQUIRED +; RIGHT THINGS ARE DONE WITH PHPOS AND HPOS (NEEDN'T BE SET) +;CALL: MOVE CHREC,CHAR TO BE OUTPUT +; PUSHJ PDP,OUTCHR +; RETURN, WITH CHAR, OR ITS SPECIAL ECHO OUTPUT + +OUTCHR: TLNE IOS,IOSUPR ;I/O OFF DUE TO ^O ? + POPJ PDP, ;YES, RETURN +OUTCHS: PUSH PDP,TAC + PUSH PDP,HPOS + PUSH PDP,TAC1 ;(TAC1=LINE) + ANDI CHREC,177 ;MASK JUNK + LDB HPOS,PHPOS ;GET HORIZONTAL POSITION + PUSHJ PDP,ADJHP ;FIGURE OUT WHAT NEW HPOS WOULD BE + JFCL ;IGNORE SKIP/NO SKIP RETURN + PUSH PDP,IOS ;SAVE IO STATUS + TRZ IOS,NOECHO + CAILE HPOS,72. + PUSHJ PDP,CRLFEC + POP PDP,IOS + TLNE TAC,SPOUT ;VT,FF,HT ? + JRST OUTCH1 ;YES + PUSHJ PDP,PUTCHO ;NO - PLACE IN BUFFER +OUTCH3: DPB HPOS,PHPOS ;UPDATE HPOS + POP PDP,TAC1 + POP PDP,HPOS + JRST TPOPJ ;AREN'T WE GLAD THAT WE PUSH'ED TAC FIRST, FOR WE + ;MAY USE THE TPOPJ EXIT + ;** SCNSRF.MAC ** PAGE 16 + +;HERE ON UUO OUTPUT OF HT,FF,VT + +OUTCH1: MOVE LINE,TTYLIN(DDB) ;GET LINE CHARACTERISTICS + TLNE LINE,T35 ;SMART TTY ? + JRST OUTC1A ;YES + MOVE TAC,CHREC ;NO - COPY CHAR + MOVEI CHREC,40 ;SIMULATE WITH SPACES + LDB HPOS,PHPOS + CAIE TAC,11 ;HT ? + MOVEI CHREC,12 ;NO - FOR VT,FF SIMULATE WITH LINEFEEDS + CAIN TAC,14 ;FF ? + MOVNI HPOS,10 ;YES -> 8 LINEFEEDS + CAIN TAC,13 ;VT ? + MOVNI HPOS,4 ;YES -> 4 LINEFEEDS +OUTC1B: PUSHJ PDP,PUTCHO ;OUTPUT SIMULATED EQUIVALENT + ADDI HPOS,1 ;VT'S AND FF'S WORK THEIR WAY FROM A NEGATIVE HPOS TO 0. + ; HT WORKS ITS WAY TO A TAB STOP. + TRNE HPOS,7 + JRST OUTC1B + JRST OUTCH3 + +OUTC1A: PUSHJ PDP,PUTCHO ;HERE ON OUTPUT OF HT,FF,VT TO A MODEL 35 + JRST OUTCH3 + + +ADJHP: CAILE CHREC,174 ;HIGH SPECIALS + JRST SPCHEK ;YES - NO CHANGE IN HPOS + CAIL CHREC,40 ;CONTROL CHAR ? + AOJA HPOS,SPCHEK ;NO + CAIN CHREC,10 ;BACKSPACE ? + SOJL HPOS,.+2 ;YES + CAIN CHREC,15 ; ? + MOVEI HPOS,0 ;YES + CAIE CHREC,11 ; ? + JRST SPCHEK ;NO + TRO HPOS,7 ;ROUND UP 8 IN 2 INSTRS + AOJA HPOS,SPCHEK + ;** SCNSRF.MAC ** PAGE 20 + +ZZ==. + +SCNDDB: SIXBIT /TTY/ ;DEVNAM + SCNCOR,,STTYBF+1 ;DEVCHR + 0 ;DEVIOS + SCNDSP ;DEVSER - ADDRESS OF TTY SERVICER + DVTTY+DVOUT+TTYUSE,,3 ;DEVMOD - TTY DOES ASCII/ASCII-LINE + ; OUTPUT + ; (ONLY CTY DOES BOTH INPUT AND OUTPUT) + 0 ;DEVLOG - LOGICAL NAME (6 BYTES) + 0 ;DEVBUF - O.B./I.B. HEADER ADDRESSES + 0 ;DEVIAD - CURRENT I.B. ADDRESS + ; AND HORIZONTAL POSITION (BITS 6-12.) + 0 ;DEVOAD - NOT USED BY TTY (BUT USED BY OTHERS) + 0 ;DEVCHN - I.T.S.-ASSOCIATED CHANNELS +TTIBUF==.-ZZ + STTYBF*5,,0 ;ADDR OF TTY I.B. + +SCNLEN==.-SCNDDB + +TIPUTR==.-ZZ ;TTY I.B. PUTTER + 0 +TIPCTR==.-ZZ ;# CHARS LEFT IN I.B. BEFORE LAST + 0 ;LAST BYTE IS REACHED +TITAKR==.-ZZ ;TAKER + 0 +TITCTR==.-ZZ + 0 +TIFCTR==.-ZZ ;FREE CTR - # CHARS LEFT FOR PUTTING + 0 +TIBF==.-ZZ + BLOCK STTYBF +TTYPTR==.-ZZ + 0 +TISYNC==.-ZZ ;COUNTS BREAK CHARACTERS + 0 +TTYLIN==.-ZZ ;WHERE LINTAB BITS WOULD ORDINARILY GO + 0 +TTYCHR==STTYBF*5 +SCNDDS==.-ZZ ;LENGTH OF PROTOTYPE DDB + + LOC SCNDDB+SCNLEN ;FROM TIPUTR TO THE END OF SCNDDB THERE ARE ONLY ZEROES + ;** SCNSRF.MAC ** PAGE 23 + +;DEVICE DEPENDENT PART OF IO UUOS + +;DISPATCH TABLE + +SCNDSP: JRST TTYREL ;RELEASE + JRST OUT ;CLOSE + JRST TTYOUT ;OUTPUT + +TTYIN: ;INPUT + MOVSI IOS,TTYIOW + IORB IOS,DEVIOS(DDB) + MOVSI IOS,DDTM+TPMON ;ZAP USER OUT OF COMMAND MODE IF PROGRAM WANTS DATA FROM + ; USER (E.G. DURING A CSTART OR CCONTINUE) + ANDCAB IOS,DEVIOS(IOS) + PUSHJ PDP,STLNAC + SKIPG TISYNC(DDB) + PUSHJ PDP,TWSYNC + PUSHJ PDP,MONUSR +TENDIN: MOVSI IOS,TTYIOW+DDTM+IOSUPR +T0POPJ: ANDCAB IOS,DEVIOS(DDB) + POPJ PDP, + ;** SCNSRF.MAC ** PAGE 24 + +;ROUTINE TO MOVE LINE OR STRING FROM TTY INPUT BUFFER TO USER'S I.BUFFER. +; CALLED FROM INPUT UUO ONLY. THE ROUTINE CONSTRUCTS AN IMAGE OF THE +; USER'S BUFFER IN CORE, DATA BEGINNING AT MONBUF+1 + +MONUSR: HRRZ TAC,DEVIAD(DDB) ;ADDRESS OF BUFFER IN USER AREA + PUSHJ PDP,BUFCLR ;CLEAR WHOLE BUFFER + JRST ADRERR ;ADDR CHECK RETURN + PUSHJ PDP,CLRMBF ;CLEAR MONBUF SO THAT A PARITALLY FILLED DATA WORD + ; WILL BE FILLED WITH ZEROES + PUSHJ PDP,STLNAC ;SET UP AC(LINE) + MOVEI AC2,TTYCHR ;MAX # CHARACTERS + MOVE AC1,[10700,,MONBUF] ;BEGIN ZIPPING CHARACTERS INTO MONBUF+1. + ; WE USE THIS BYTE POINTER RATHER THAN 440700,,MONBUF+1 SO THAT + ; WE CAN DO A SUBTRACT-IMMEDIATE ON MONBUF TO FIND OUT HOW MANY WORDS ARE + ; FILLED WITH DATA + MOVEI DAT,TTIBUF(DDB) ;SPECIFIY USER'S I.BUFFER +MONUS1: PUSHJ PDP,GETCHR ;GET A CHAR + JUMPE CHREC,MONUS3 ;=0 -> EMPTY + IDPB CHREC,AC1 ;PUT CHAR -> MONBUF + PUSHJ PDP,SPCHEK ;SPECIAL CHARACTER ? + JRST MONUS2 ;NO + TLNE TAC,FCSBRK+BREAKB ;BREAK CHAR ? + SOSA TISYNC(DDB) ;YES - REDUCE SYNC +MONUS2: SOJG AC2,MONUS1 ;NON-BREAK + CAIN CHREC,3 ;^C ? + JRST MONUS7 ;YES + MOVEI IOS,0 + CAIN CHREC,"Z-100 ;^Z ? + MOVSI IOS,IOEND ;YES + IORB IOS,DEVIOS(DDB) + +MONUS3: HRRZ AC2,DEVIAD(DDB) + .UMOVE AC2,1(AC2) ;COLLECT 3RD WORD OF BUFFER + MOVEM AC2,MONBUF ;PUT IT INTO INTERMEDIATE BUFFER + ; WE WILL UPDATE ITS RIGHT HALF + SUBI AC1,MONBUF ;COMPUTE # WORDS USED + HRRM AC1,MONBUF ;EVERYTHING ALL SET UP + HRRZ AC2,DEVIAD(DDB) ;THE "TO" ADDRESS-1 + HRRZI AC2,1(AC2) ;BEGIN 1 WORD BEFORE BUFFER DATA + HRLI AC2,MONBUF ;THE "FROM" ADDRESS + ADDI AC1,(AC2) ;COMPUTE THE ADDRESS OF THE FINAL WORD TRANSFERRED + .UBLTO AC2,(AC1) ;SOCK IT TO USER + + PUSHJ PDP,ADVBFF ;INPUT UUO DONE, NEXT BUFFER IN USE ? + JRST MONUS5 ;YES - ALL DONE + SKIPLE TISYNC(DDB) ;NO - BUT CAN BE GIVE HIM MORE ? + JRST MONUS8 ;YES + +MONUS5: MOVSI IOS,IOFST + IORB IOS,DEVIOS(DDB) + POPJ PDP, + ;** SCNSRF.MAC ** PAGE 25 + +MONUS6: PUSHJ PDP,CNCMOD ;^C MODE + MOVSI TAC,70000 ;DECREMENT TAKR + ADDM TAC,TITAKR(DDB) ;SO NEXT ILDB WILL GET ^C + AOS TITCTR(DDB) ;ADJUST FREE COUNTER + SOS TIFCTR(DDB) + AOS TISYNC(DDB) + PUSHJ PDP,COMSET + JRST WSYNC ;SAVE PUSHDOWN STACK IN USER AREA AND GET COMMAND + ; PUSHDOWN STACK IS VITAL BECAUSE JOBPC WILL ONLY HAVE + ; A MONITOR PC POINTING INTO THE SIMULATOR. JOBPD1 WILL + ; CONTAIN WHAT WE ARE INTERESTED IN. + + +MONUS7: MOVSI IOS,TTYIOW + IORB IOS,DEVIOS(DDB) + PUSHJ PDP,MONUS6 ;GET ^C TO COMMAND DECODER + JRST TTYIN ;A "CONTINUE" WILL GET US BACK HERE - EXCEPT THAT + ; USTART: REINVOKES THE CALLING USER UUO FROM THE USER'S PROGRAM + ; THUS, I DON'T THINK WE EVER GET HERE + +MONUS8: TLNN IOS,IOEND ;ROOM FOR ANOTHER BUFFER, BUT HAVE WE SEEN A ^Z ? + JRST MONUSR ;NO + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 26+27 + +;OUTPUT UUO + +TTYOUT: LDB TAC,PDEVO ;DO WE HAVE A CHANNEL ALREADY ASSIGNED ? + JUMPN TAC,TYOUT1 + PUSHJ PDP,GTFCHN ;NO - GET ONE + JRST NOCHNE ;NONE AVAILABLE + DPB TAC,PDEVO + LDB TAC1,[POINT 12,DEVNAM(DDB),29,] ;COLLECT NM CHARACTERS FROM TTY NAME + ; NOTE AC(TAC1)=AC(LINE) - BUT STLNAC: SETS UP LINE BEFORE WE + ; REALLY DO ANYTHING + IORI TAC1,(SIXBIT /T/) ;MAKE TNM DEVICE NAME + HRLI TAC1,CTYOMD ;.OPEN IT IN IMAGE, UNIT, OUTPUT MODE + MOVEM TAC1,FILNAM ;SAVE IT AWAY FOR THE .OPEN + SETZM FILNM1 + SETZM FILNM2 + ROT TAC,-13. ;INSERT CHANNEL NUMBER INTO AC FIELD + IOR TAC,[.OPEN 0,FILNAM] ;CONSTRUCT THE .OPEN + XCT TAC ;DO IT + JRST TTYNA ;FAILED +TYOUT1: MOVSI IOS,IOBEG + TDNE IOS,DEVIOS(DDB) + TLO IOS,IOSUPR ;KILL ^O ON FIRST OUTPUT + IOR IOS,[TPMON+DDTM,,] + ANDCAM IOS,DEVIOS(DDB) + MOVSI IOS,IOFST + IORB IOS,DEVIOS(DDB) + PUSHJ PDP,TYUUO ;SIGNAL TTY OUTPUT IN PROGRESS IF + ; CHARS ARE REALLY GOING OUT + + PUSHJ PDP,STLNAC ;GET LINE CHARACTERISTICS - NEEDED WHEN WE OUTPUT THE + PUSHJ PDP,USRMON ; IN USRMON: + PUSHJ PDP,ADVBFE + JFCL ;MORE BUFFER AVAILABLE + POPJ PDP, ;NO MORE BUFFERS + +;ROUTINE TO MOVE USER OUTPUT BUFFER TO MONITOR OUTPUT BUFFER. + +USRMON: HRRZ AC1,DEVOAD(DDB) ;GET O.BUFFER ADDR + PUSHJ PDP,UADRCK ;AND CHECK IT + .UMOVE AC2,1(AC1) ;READ 3RD WORD OF CURRENT BUFFER + HRRZ AC2,AC2 ;RH ONLY (=WORD COUNT). C.F. P 398 DEC PDP10 R.M. (1969) + SKIPN AC2 ;# OF WORDS TO OUTPUT + MOVEI AC2,1 + ADDI AC1,-1(AC2) ;COMPUTE L.W. IN BUFFER UNLESS .LT. 1 WORD + PUSHJ PDP,UADRCK ;AND BE SURE THAT IT'S OK + + HRRZ AC1,DEVOAD(DDB) ;ADDR OF BUF + HRLZI AC1,2(AC1) ;DATA BEGINS 2 WORDS LATER - "FROM" + HRRI AC1,MONBUF ;NOW READ INTO MONBUF + .UBLTI AC1,MONBUF-1(AC2) + MOVE AC1,[POINT 7,MONBUF,-1,] + IMULI AC2,5 ;COMPUTE # OF WORDS +USRMN2: ILDB CHREC,AC1 ;PICK UP CHARACTER + JUMPE CHREC,USRMN5 ;IF NULL, IGNORE + PUSHJ PDP,OUTCHR ;PLACE IN OUTBUF +USRMN5: SOJG AC2,USRMN2 + POPJ PDP, + ;** SCNSRF.MAC ** PAGE 28 + +;TTCALL - QUANTITY IN AC FIELD DETERMINES AXN OF UUO + +TTYUUO: PUSHJ PDP,TTYFNU ;FIND OUR TTY DDB ADDR + PICK UP RANDOM INFO + CAIL UCHN,TTUUOL ;TOO HIGH AC FIELD ? + POPJ PDP, ;YES - NO-OP + CAIE UCHN,1 ;A READ OPERATION ? + CAIN UCHN,3 ;I.E., PURE ? + JRST @TTUUOT(UCHN) ;YES - NO ADDR CHECK REQ. + HRRZ AC1,UUO + PUSHJ PDP,UADCK1 + JRST @TTUUOT(UCHN) ;DISPATCH + +TTUUOT: INCHRW ;(0) INPUT CHAR, WAIT TILL TYPED + ONEOUT ;(1) OUTPUT A CHARACTER + INCHRS ;(2) INPUT A CHAR, AND SKIP + OUTSTR ;(3) OUTPUT A STRING + INCHWL ;(4) INPUT CHAR, WAIT, LINE MODE + INCHSL ;(5) INPUT CHAR, SKIP, LINE MODE + GETLIN ;(6) GET LINE CHARACTERISTICS WORD + SETLIN ;(7) SET BITS IN LH OF TTYLIN + TRESCU ;(10) BACK UP POINTER TO COMMAND + SETBFI ;(11) CLEAR INPUT BUFFER + SETBF2 ;(12) CLEAR OUTPUT BUFFER + SKPINC ;(13) SKIP IF CHAR TO INPUT + SKPINL ;(14) SKIP IF LINE TO INPUT + IONEOU ;(15) OUTPUT AN IMAGE CHARACTER + +TTUUOL==.-TTUUOT + ;** SCNSRF.MAC ** PAGE 29 + +;INPUT A CHARACTER + SKIP +; IF NONE TYPED, THEN DON'T SKIP + +INCHSL: SKIPG TISYNC(DDB) ;ANY LINES IN BUFFER ? + JRST NOCTRO ;NO, RETURN CLEARING ^O +INCHRS: MOVEI DAT,TTIBUF(DDB) ;GET A CHARACTER + PUSHJ PDP,GETCHR ; FROM TTI BUFFER + JUMPE CHREC,NOCTRO ;RETURN IF NULL (EMPTY BUFFER) - THIS ALSO + ; CLEARS ^O BIT (=IOSUPR) + PUSHJ PDP,SPCHEK ;COLLECT SPCTAB ENTRY + JFCL + TLNE TAC,FCSBRK+BREAKB + SOS TISYNC(DDB) ;DECREMENT SYNC COUNT + PUSHJ PDP,TENDIN + CAIN CHREC,3 ;^C ? + JRST MONUS6 ;YES + .UMOVM CHREC,(UUO) ;MOVE INTO LOC SPECIFIED BY AC(UUO) + JRST CPOPJ1 ;SKIP RETURN + +;INPUT A CHAR + WAIT, LINE MODE + +INCHWL: PUSHJ PDP,INCHSL ;ANY CHARACTERS ? + JRST .+2 ;NO + POPJ PDP, ;YES - GIVE IT TO USER + MOVSI IOS,TTYIOW ;NONE, WAIT FOR IT + IORM IOS,DEVIOS(DDB) + MOVSI IOS,DDTM ;CLERA DDT MODE BRAK FLAG + ANDCAB IOS,DEVIOS(DDB) + PUSHJ PDP,TWSYNC ;WAIT + JRST INCHWL ;AND TRY AGAIN + +;OUTPUT A STRING + +OUTSTR: JRST DDT5 ;JUST USE DDT OUTPUT CODE + +SKPINL: SKIPLE TISYNC(DDB) ;INPUT BUFFER HAVE A LINE ? + AOS 0(PDP) ;YES - SKIP + JRST NOCTRO ;RETURN, CLEARING ^O + +SKPINC: HLRZ TAC,TTIBUF(DDB) ;SIZE OF BUFFER + CAMLE TAC,TIFCTR(DDB) ;SIZE > # FREE CHARS + AOS 0(PDP) ;YES - SKIP +NOCTRO: MOVSI IOS,IOSUPR ;^O BIT + JRST T0POPJ + ;** SCNSRF.MAC ** PAGE 30 + +;MORE ROUTINES CALLED BY TTYUUO DISPATCHER + +;INCHRW GOES INTO "I/O WAIT" IF NO CHARACTER HAS BEEN TYPED--HO SKIPS + +INCHRW: PUSHJ PDP,INCHRS ;GET A CHAR IF ONE IS THERE + JRST .+2 ;NONE THERE + POPJ PDP, + MOVSI IOS,TTYIOW+DDTM ;SET UP FOR TTY IOWAIT + IORB IOS,DEVIOS(DDB) + PUSHJ PDP,TWSYNC ;WAIT FOR CHAR TO BE TYPED + JRST INCHRW ;GO GET IT + + +;ONEOUT OUTPUT ONE CHARACTER + +ONEOUT: PUSHJ PDP,GETWDU ;PICK UP CHAR FROM USER + MOVE CHREC,TAC ;PUT IT INTO PROPER AC + ANDI CHREC,177 ;ONLY LAST 7 BITS + JUMPE CHREC,CPOPJ ;AND NO NULLS + JRST OUTCHR ;TYPE IT + +IONEOU: PUSHJ PDP,GETWDU ;PICK UP A CHARACTER + MOVE CHREC,TAC + JRST OUTCHR ;AND TYPE IT + +;GETLIN PUTS LINE CHARACTERISTICS WORD IN ADDR OF UUO AC FIELD + +GETLIN: .UMOVE TAC,(UUO) + SKIPL TAC, ;DOES USER WISH HIS OWN LINE + MOVEI LINE,0 + .UMOVM LINE,(UUO) + POPJ PDP, + +;ROUTINE TO SET LINE CHARACTERICS THAT ARE SETABLE + +SETLIN: MOVSI TAC,LGLSET + ANDCAM TAC,TTYLIN(DDB) + .UMOVE TAC,(UUO) + AND TAC,[LGLSET,,] + IORM TAC,TTYLIN(DDB) ;SET ONLY THOSE BITS THAT USER WANTS TO SET + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 34+35 + +TRESCN: LDB TAC,PCOMIC + MOVEM TAC,TITCTR(DDB) + PUSHJ PDP,TBYTEP + MOVEM TAC,TITAKR(DDB) +TRESC1: MOVE TAC,TIPCTR(DDB) ;COMPUTE NEW FREE COUNT + SUB TAC,TITCTR(DDB) + SKIPG TAC + ADDI TAC,TTYCHR + MOVEM TAC,TIFCTR(DDB) + JRST STLNAC + +TRESCU: PUSHJ PDP,TRESCN + SETZM TISYNC(DDB) + MOVEI DAT,TTIBUF(DDB) +TRESCL: PUSHJ PDP,GETCHR + JUMPE CHREC,TRESCN ;HAVE WE PASSED THROUGH ALL AVAILABLE CHARS ? + PUSHJ PDP,SPCHEK ;NO - KEEP COUNTING BREAKS + JRST TRESCL + TLNE TAC,FCSBRK+BREAKB + AOS TISYNC(DDB) + JRST TRESCL + +TLHBYT: 350700,,0 + 260700,,0 + 170700,,0 + 100700,,0 + 010700,,0 + +TBYTEP: PUSH PDP,TAC1 + MOVNS TAC + SKIPGE TAC + ADDI TAC,TTYCHR + IDIVI TAC,5 + ADD TAC,TTIBUF(DDB) + HLL TAC,TLHBYT(TAC1) + POP PDP,TAC1 + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 36-40 + +;ROUTINE TO FIND USER'S CONSOLE TTY + +TTYFNU: +TTYFUW: +TTYFND: + JRST TTYSRC + +;DEVICE DEPENDENT PART OF RELEASE UUO + +TTYREL: MOVEI IOS,-1 ;CLEAR INITED STUFF IN IOS + JRST T0POPJ ;GO CLEAR OUT IOS BITS + +;ROUTINE TO SET TTY INTO USER MODE +;CALL: MOVE DEVDAT,ADDRESS OF DEVICE DATA BLOCK +; PUSHJ PDP,TTYSET + +TTYSET: MOVSI IOS,DDTM+IOSUPR+TTYIOW+IOW + JRST T0POPJ ;CLEAR THESE BITS IN AC(IOS) AND RETURN + +;ROUTINE TO "SEARCH" FOR USER'S CONSOLE TTY + +TTYSRC: MOVEI DDB,CTYDDB + MOVE IOS,DEVIOS(DDB) +STLNAC: MOVE LINE,TTYLIN(DDB) + POPJ PDP, + +TTYSTC: MOVSI TAC,TPMON ;PUT TTY IN MONITOR MODE + IORM TAC,DEVIOS(DDB) + ;DROP THROUGH TO START UP CODE + +TTYSTR: MOVSI IOS,DDTM+IOSUPR+IOBEG + ANDCAB IOS,DEVIOS(DDB) + SKIPLE TISYNC ;DID USER TYPE AHEAD + PUSHJ PDP,COMSET ;YES (COMSET WILL RETURN IMMEDIATELY IF NOT IN MONITOR MODE) + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 42+47 + +;ROUTINE TO START UP JOB +;CALL: MOVE DEVDAT,TTY DDB ADR. +; PUSHJ PDP,TTYUSR +; TTY WILL GO INTO USER MODE + +TTYUSR: MOVSI IOS,TPMON ;PUT TTY IN USER MODE + ANDCAM IOS,DEVIOS(DDB) + JRST SETRUN + +;ROUTINE TO "WAKE UP" COMMAND DECODER IF TPMON SET + +COMSET: TLNN IOS,TPMON ;MONITOR MODE ? + POPJ PDP, ;NO - RETURN + MOVSI IOS,IOFST ;SET FIRST BUFFER FLAG + IORB IOS,DEVIOS(DDB) + POPJ PDP, ;AND RETURN - COMMAND AXN TAKEN AUTOMATICALLY AT + ; END OF CHAR INT PROCESSING AND UUO INT PROCESSING + ;** SCNSRF.MAC ** PAGE 50 + +;KEYBOARD EDITOR ROUTINE +;UPON RECEIPT OF A CHARACTER, THIS ROUTINE DETERMINES WHAT TO DO +;WITH IT: WHETHER IT'S A SPECIAL CHARACTER NEEDING SPECIAL ECHOING, +;WHETHER SOME OTHER CHARACTER IS TO BE STORED IN ITS PLACE, WHETHER +;IT IS A BREAK CHARACTER (LINE TERMINATOR), OR WHETHER THE CHARACTER +;TYPED IS A SIGNAL TO UNDERTAKE SOME SPECIAL ACTION. +; THIS ROUTINE CALLS SPCHEK:, WHICH MAKES USE OF THE SPECIAL +;CHARACTER TABLE, SPCTAB. NOTE THAT IF A CHARACTER IS TO +;DISPATCH TO A "SPECIAL ACTION ROUTINE" OR A SPECIAL ECHO ROUTINE, +;THE LEFT HALF OF THE CORRESPONDING CHARACTER-WORD MUST HAVE SPACTN SET +;AND THE ADDRESS OF THE SPECIAL ROUTINE MUST BE ASSEMBLED INTO THE +;RIGHT HALF OF THE WORD. +;CALL: HAVE 7-BIT ASCII CHARACTER IN AC(CHREC) +; LDB HPOS,PHPOS +; MOVEI DAT,TTIBUF(DDB) +; PUSHJ PDP,TTEDIT +; RETURN WITH ACTION DONE, SYNC (LH OF AC(IOS)) SET IF BREAK CHAR STORED. + +TTEDIT: PUSHJ PDP,ADJHP + JRST TIPACK ;NOT SPECIAL + MOVSI IOS,0 ;RESET IOS + TLNE TAC,BREAKB+FCSBRK ;BREAK CHAR ? + + ;NOTE: FCSBRK CHAR IS BREAK BOTH IN NORMAL AND FCS MODES + + TLO IOS,SYNC ;BREAK CHAR, SET SYNC + IORB IOS,DEVIOS(DDB) + JUMPL TAC,0(TAC) ;DISPATCH IF SPACTN - I.E. SPECIAL CHAR +TIPACK: CAIGE CHREC,140 ;L.C. LETTER ? + JRST TTIPUT ;NO + TLNN LINE,T37 ;YES - IN MODEL-37 MODE ? + TRZ CHREC,40 ;NO - MAKE IT U.C. +TTIPUT: TLZE LINE,ROBTPD ;ARE WE IN DELETE MODE ? + PUSHJ PDP,BSECHO ;YES - OUTPUT A "\" +TTIPT1: PUSHJ PDP,PUTCHI ;PUT CHAR IN INPUT BUFFER + JRST INBFUL ;BUT IT WON'T GO + TLNN TAC,ECHSUP ;TO BE ECHOED ? + TLNE LINE,FULTWX ;YES - AND HAS IT BEEN ALREADY ? + JRST SPCECO ;SEE IF SPECIAL ECHO +DUPLX1: PUSH PDP,TAC ;SAVE TAC (=SPCTAB ENTRY) + TLNN IOS,TPMON ;MON MODE ? + TRNN IOS,NOECHO ; + PUSHJ PDP,PUTCHO ;OUTPUT CHAR + JRST TPOPJ ;RETURN + RESTORE AC(TAC) + +SPCECO: JUMPE CHREC,CPOPJ ;NEVER ECHO NULLS + CAIE CHREC,3 + CAIN CHREC,32 + POPJ PDP, + CAIN CHREC,33 + POPJ PDP, + CAIGE CHREC,7 ;ECHO BELOW ^G + JRST UPRCTL ;DO IT + CAILE CHREC,15 + CAIL CHREC,40 + POPJ PDP, +UPRCTL: PUSH PDP,CHREC + MOVEI CHREC,"^ + PUSHJ PDP,PUTCHO + MOVE CHREC,(PDP) + ADDI CHREC,"@ + PUSHJ PDP,PUTCHO + POP PDP,CHREC + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 51+52 + +INBFUL: MOVSI IOS,SYNC ;DON'T REGISTER THIS AS SYNC + ANDCAB IOS,DEVIOS(DDB) ;SINCE CHAR NOT STORED + CAIN CHREC,3 ;WAS XTRA CHAR A ^C ? + JRST CNCTS1 ;YES - PANIC + MOVEI CHREC,7 ;NO - ECHO BELL TO SHOW LOSSAGE + JRST PUTCHO + +CONTC: PUSHJ PDP,DELETL ;DELETE CURRENT LINE + MOVE TAC,SPCTAB+3 ;RETRIEVE SPCTAB ENTRY +CONTZ: PUSHJ PDP,CNTLEC ;OUTPUT ^C OR ^Z + PUSHJ PDP,CRLFEC ;OUTPUT A + JRST TTIPUT ;AND STORE CHAR + +CONTO: PUSHJ PDP,SETBF2 ;CLEAR CTYO OUTPUT BUFFER + SKIPE TTYOIP ;AT SPECIAL (NON-INTERRUPT) LEVEL ? + JRST CONTU1 ;YES, ALL OF THIS HAS BEEN DONE FOR US + MOVSI IOS,IOSUPR ;GET THAT IOSUPRESS BIT + XORB IOS,DEVIOS(DDB) ;AND FLIP IT OFF + JRST CONTU1 +CONTU: TLNE IOS,DDTM ;IN DDT MODE ? + JRST TTIPUT ;YES - PASS CHAR + TLZ LINE,ROBTPD + PUSHJ PDP,DELETL +CONTU1: PUSHJ PDP,CNTLEC ;ECHO ^O OR ^U + JRST CRLFEC ;OUTPUT - THEN RETURN W/O STORING CHAR + +ALTMOD: HRRI TAC,(CHREC) ;SAVE WHICH KIND OF ALTMODE + MOVEI CHREC,44 ;ECHO A $ + TLNN IOS,TPMON ;IF IN MONITOR MODE + TRNN IOS,DLRSUP ;OR IF IN USER MODE (WITHOUT $-SUPPRESS SET) + PUSHJ PDP,AOJDPX + MOVEI CHREC,(TAC) ;RESTORE CHAR, BUT + TRNN IOS,FCS ;IF NOT FCS MODE -> CONVERT TO 33 + MOVEI CHREC,33 + JRST TTIPUT ;AND STORE + ;** SCNSRF.MAC ** PAGE 53 + +CONTHR: SOJ HPOS, ;COMES HERE IF RUBBING OUT A ^H +CONTH: TLNE LINE,T37 ; + JRST TTIPUT ;JUST PASS TO PROG IF A MODEL 37 + + ;NOTE: A MODEL 33/35 -> ALTMODE + +RUBOUT: TLNE IOS,TPMON ;IN MONITOR COMMAND MODE, NOT A BREAK CHAR + JRST RUBOU2 + TDNE IOS,[DDTM,,FCS] + JRST TTIPT1 ;STORE RUBOUT IF DDT OR FCS +RUBOU2: MOVSI IOS,SYNC ;NOT A BREAK + ANDCAB IOS,DEVIOS(DDB) ;BREAK - SO CLEAR BREAK-FOUND BIT + LDB CHREC,PUTR(DAT) ;GET LAST CHAR INPUT + PUSHJ PDP,DCPUTR ;BACK UP TIPUTR + ; DCPUTR USED PLSTLC TO INSURE THAT WE DON'T BACK UP OVER A BREAK + JRST RUBOU1 ;EMPTY ALREADY + TLON LINE,ROBTPD ;MARK RUBOUT --- AND WERE WE IN RUBOUT MODE DEJA ? + PUSHJ PDP,BSECHO ;NO - TURN HIM ON TO US + PUSHJ PDP,SPCHEK ;GET SPECIAL BITS FOR CHAR JUST UNZAPPED + ;MIGHT 'A BEEN A , ETC. +AOJDPX: AOJA HPOS,DUPLX1 ;NOT SPECIAL -- OUTPUT IT AND COUNT HPOS + TLNE TAC,SPACTN ;IF IT IS REALLY SPECIAL, + JRST -1(TAC) ; USE ALTERNATE SPECIAL CHAR ROUTINE + ; ENTRY WHEN IN RUBOUT MODE + POPJ PDP, ;OTHERWISE, RETURN + +RUBOU1: TLZE LINE,ROBTPD ;END OF INPUT STREAM REACHED + PUSHJ PDP,BSECHO ;OUTPUT A "\" AND + JRST CRLFEC + +CONTK: HRRI TAC,4 ;HERE ON VT + CAIA +CONTL: HRRI TAC,10 ;HERE ON FF + TLNE LINE,T35 ;DOES TTY HAVE VERT MECHANICS ? + JRST TTIPUT ;YES + ;NO - FALL INTO SIMFF + ;** SCNSRF.MAC ** PAGE 54 + +;ROUTINE TO SIMULATE VT OF FF WITH LINEFEEDS +; IF THIS IS NOT A MODEL 35 TTY + +SIMFF: TLO TAC,ECHSUP ;DON'T OUTPUT A FF OR A VT TO A MODEL 33 + PUSHJ PDP,TTIPUT ;PUT IT IN BUFFER + MOVEI CHREC,12 ;NOW SIMULATE FF OR VT WITH LF'S + PUSHJ PDP,DUPLX1 ;OUTPUT ECHO OF LF + TRNE TAC,17 ;DONE YET ? + SOJA TAC,.-2 ;NO - OUTPUT MORE + POPJ PDP, ;DONE + +CONTIR: JRST CONTI1 ;COMES HERE HERE TO RUBOUT A TAB +CONTI: TLNN LINE,T35 ;HERE ON HT + TLO TAC,ECHSUP + PUSHJ PDP,TTIPUT ;PUT INTO BUFFER, MAYBE ECHO + TLNE LINE,T35 + POPJ PDP, ;IF ECHOED, RETURN + ;NOT ECHOED, WE MUST SIMULATE WITH SPACES + LDB HPOS,PHPOS ;GET OUR OLD HORIZONTAL POSITION BEFORE + ; IT WAS CHANGED BY ADJHP: +CONTI2: MOVEI CHREC,40 ;SEND SPACES FOR THAT TAB + PUSHJ PDP,AOJDPX ;OUTPUT A SPACE + TRNE HPOS,7 ;AT A TAB STOP ? + JRST .-2 ;NO - WE NEED TYPE MORE SPACES + POPJ PDP, ;YES - STOP + +CONTI1: TLNN LINE,T35 ;A MODEL 35 ? + JRST CONTI2 ;YES - SIMULATE A TAB USING CURRENT (!!) + ; HPOS VALUE (WE COULD HAVE JUST TYPED OUR INITIAL "\") + TRO HPOS,7 ;INDICATE THAT WE ARE AT A TAB STOP + AOJA HPOS,DUPLX1 ;IN TWO INSTRUCTIONS (C.F. ADJHP:) + ;** SCNSRF.MAC ** PAGES 55-56 + +CRLFEC: MOVEI HPOS,1 ;ECHO A CR, LF, SAVING CHREC + PUSH PDP,CHREC + MOVEI CHREC,15 ;CR + PUSHJ PDP,DUPLX1 + MOVEI CHREC,12 ;LF + PUSHJ PDP,DUPLX1 +CHPOPJ: POP PDP,CHREC ;RESTORE CHREC + POPJ PDP, + +CNTLEC: HRRI TAC,100(CHREC) ;AND NOW, TO NORMALCY + MOVEI CHREC,"^ + PUSHJ PDP,AOJDPX ;TYPE THE ^ + MOVEI CHREC,(TAC) ;TYPE THE UN-CONTROL VERSION OF THE CHAR + PUSHJ PDP,AOJDPX + TRZ CHREC,100 ;MAKE IT A CONTROL CHAR AGAIN + POPJ PDP, + +CR: MOVEI HPOS,0 ;HERE ON INPUT OF A CARRIAGE RETURN + PUSHJ PDP,TTIPUT + MOVEI CHREC,12 ;FOLLOW IT WITH A + MOVSI IOS,SYNC ;WHICH IS A BREAK + IORB IOS,DEVIOS(DDB) + JRST TTIPUT + +CNCTST: + +;NO NEED HERE TO CHECK JACCT BIT IN JBTSTS - WE +; DO NOT USE PRIVILEGED CUSPS, ETC. + + LDB TAC,TIPUTR(DDB) ;LOOK AT LAST CHAR INSERTED + CAIE TAC,3 + POPJ PDP, +CNCTS1: PUSHJ PDP,TSETBF ;STOP I/O, BY CLEARING BUFFERS + MOVEI DAT,TTIBUF(DDB) + MOVE TAC,SPCTAB+3 ;GET BACK ENTRY + +CNCMOD: MOVSI IOS,DDTM+IOSUPR + ANDCAM IOS,DEVIOS(DDB) + MOVSI IOS,TPMON+IOFST + IORB IOS,DEVIOS(DDB) + POPJ PDP, + ;** SCNSRF.MAC ** PAGES 57+60 + +;ROUTINE TO ECHO BACKSLASH + +BSECHO: PUSH PDP,CHREC + MOVEI CHREC,"\ + PUSHJ PDP,AOJDPX + JRST CHPOPJ + +;ROUTINE TO DECREMENT PUTR + +DCPUTR: LDB TAC,PLSTLC ;CHECK FOR NONE TO DELETE + CAMN TAC,PCTR(DAT) + POPJ PDP, + MOVSI TAC,70000 + ADD TAC,PUTR(DAT) + TLNE TAC,400000 + ADD TAC,[347777,,-1] + MOVEM TAC,PUTR(DAT) + AOS FCTR(DAT) + AOS TAC,PCTR(DAT) + CAIG TAC,TTYCHR + JRST CPOPJ1 ;SKIP + SUBI TAC,TTYCHR ;WE HAVE JUST BACKED UP OVER THE FRONT + MOVEM TAC,PCTR(DAT) ;END OF THE BUFFER + MOVEI TAC,STTYBF + ADDM TAC,PUTR(DAT) + JRST CPOPJ1 + +;ROUTINE TO DELETE CURRENT LINE (^U) + +DELETL: LDB TAC,PLSTLC ;COUNTER AT LAST LINE + MOVEM TAC,TIPCTR(DDB) ;RESTORE COUNT TO THIS VALUE + PUSHJ PDP,TBYTEP ;CONVERT TO BYTE POINTER + MOVEM TAC,TIPUTR(DDB) + JRST TRESC1 ;COMPUTE NEW TIFCTR + +;ROUTINE TO SETUP DDB +;CALL: MOVE TAC,[TTY##] +; PUSHJ PDP,GETDDB +; NOT AVAILABLE RETURN +; RETURN WITH LINE AND DDB SETUP + +GETDDB: HLRZ AC1,TAC + CAIE AC1,(SIXBIT /TTY/) ;TTY PREFIX ? + POPJ PDP, ;NO - CAN'T HELP YOU OUT + TRNE TAC,770000 ;HE HAD BETTER BE REQUESTING TTYNM + TRNE TAC,77 ;AND NOTHING ELSE + POPJ PDP, + PUSH PDP,TAC ;SAVE TTYNM NAME + HRLZ TAC,TAC ;NOW LET'S BE SURE THAT BOTH N AND M ARE DIGITS +GETDB3: ROT TAC,6 ;GET NEXT DIG + TRZE TAC,20 ;20 BIT BETTER BE ON + TRNE TAC,50 ;AND NO OTHER HIGH ORDER BITS + JRST TPOPJ ;ELSE LOSE + TLNE TAC,-1 ;MORE ? + JRST GETDB3 ;YES + MOVEI AC1,SCNCOR + PUSHJ PDP,GTF ;GET SCNCOR # OR CONTIGUOUS FREE BLOCKS + HRRI DDB,(AC1) ;MOVE THAT ADDRESS TO AC(DDB) + PUSH PDP,DAT ;MAKE SURE THAT WE DON'T LOSE AC(DAT) + PUSHJ PDP,MNTDDB ;MAKE NEW TTY DDB + POP PDP,DAT + POP PDP,DEVNAM(DDB) ;AND PLACE TTYNM INTO DEVNAM + JRST CPOPJ1 ;SUCCESS RETURN + ;** RFD ** + +;I.T.S. FILE DIRECTORY PARAMETERS +; C.F. P 285, I.T.S. SYSTEM LISTING + +;RANDOM INFO + +UFDBYT==6 ;SIZE OF BYTES +UFDBPW==36./UFDBYT ;# BYTES PER WORD + +UDNAMP==1 ;PNTR TO ORG OF NAME AREA +UDNAME==2 ;USER NAME +UDDESC==11. ;FIRST LOCATION AVAILABLE FOR DESC + +;UFD DESCRIPTORS +; 0 -> FREE +; 1-UDTKMX -> TAKE NEXT N +; UDTKMX+1 THROUGH UDWPH-1 -> SKIP N-UDTKMX AND TAKE 1 +; 40-BIT SET -> LOAD ADDR. LOWEST 5 BITS + NEXT 2 CHARS (17. BITS IN ALL) + +UDTKMX==12. ;HIGHEST "TAKE N" CODE +UDWPH==31. ;PLACE HOLDER ON WRITE (OR NULL FILE) +NXLBYT==2 ;# ADDITIONAL BYTES FOR LOAD ADDR + +;NAME DATA AREA +LUNBLK==5 ;LENGTH OF USER FILE NAME BLOCK +UNFN1==0 ; FILE NAME 1 +UNFN2==1 ; FILE NAME 2 +UNRNDM==2 ; ALL KINDS OF RANDOM INFO + UNLINK==1 ;LINK BIT + UNWRIT==4 ;OPEN FOR WRITING + UNCDEL==20 ;DELETE WHEN CLOSED + UNPDEL==40 ;DELETE FROM UNMOUNTED PACK + DELBTS==UNCDEL+UNPDEL ;DELETED -- IGNORE + UNIGFL==DELBTS+UNWRIT ;BITS TO IGNORE FILE + UNDSCP==1500,, ;PNTR TO DESC +UNDATE==3 ; DATE, ETC. + UNTIM==2200,, ;COMPACTED TIME OF DAY + UNREFT==341000,, ;DAYS AFTER CREATION LAST REFERENCED + UNMON==270400,, ;MONTH + UNDAY==220500,, ;DAY + UNYRD==330100,, ;YEAR BIT + +;UNDATE: +; --/--/--/--/--/--/ --/--/--/--/--/--/ +; 0......78.......17 +; LAST REF YR MO DAY COMPACTED TIME OF CREATION IN 1/2 SECS. + ;** RFD ** + +;READ FILE DIRECTORY +; TAC/SNAME OF DESIRED DIRECTORY +; TAC1/ADDRESS OF DISPATCH ROUTINE + +;EVERY TIME A 4-WORD ENTRY IS COMPLETE, AND PLACED IN WORDS +; FILNAM...FILNAM+3(=FILNM3), WE DO A PUSHJ PDP,(TAC1), +; WHICH SHOULD DO APPROPRIATE THINGS WITH THE DIRECTORY +; ENTRY. SPECIFICALLY WE WOULD EXPECT THE (TAC1) CO-ROUTINE +; EITHER TO ENTER THE FILENAME INTO THE USER DIRECTORY +; (A PART OF LIST STORAGE), OR THE FILENAME WOULD BE +; SENT OUT TO A PSEUDO U.F.D. FILE. + +;NOTE - ONLY THOSE FILES WHOSE 2ND FILE NAME BEGINS WITH +; THE CHARACTERS "DEC" (C.F. SNFID -- AN ASSEMBLY PARAMETER) AND WITH 4TH CHAR OF 2ND NAME=0 +; PLUS HIGH ORDER BIT OF 5TH CHAR SET ARE VISIBLE TO US. OTHERS +; ARE TREATED AS SPURIOUS. + +;DEFINE ACCUMULATORS + +T==BUFPNT +T1==BUFWRD +T2==UUO +T3==AC1 +T4==AC2 +T5==AC3 + +RFDSTK==10. ;= PC + # ELEMENTS STORED ON PD STACK + ; WHEN TAC1 CO-ROUTINE CALLED + PC OF CALLING SEQ + ; + PC TO CO-ROUTINE. + ; THUS, THE CALLER'S RETURN POINTER IS IN -RFDSTK+3(PDP) + +RFD: PUSH PDP,T ;SAVE ALL ACCUMULATORS WE USE + PUSH PDP,T1 ;THEY ARE RESTORED AT UFDFIN: -- THE COMMON EXIT + PUSH PDP,T2 + PUSH PDP,T3 + PUSH PDP,T4 + PUSH PDP,T5 + CAME TAC,SNAME ;IS USER READING HIS OWN UFD ? + ; I.E. AC(TAC)=SNAME OR =0 + JRST RFD4 ;NO + SKIPE DIRLST ;YES - IF SO - DO WE HAVE IT IN CORE ? + ; (INITIALLY WE WON'T, AND IF USER USES "REFRESH" COMMAND, IT WILL BE + ; BE RESET.) + JRST RICUFD ;YES- READ IN-CORE UFD + ;** RFD ** + +RFD4: HRRZ T,HLADR ;DO WE HAVE A DIRECTORY IN CORE ? + JUMPN T,RFD1 ;YES + HLRZ T,HLADR ;NO + ADDI T,4000 ;PREPARE FOR A .CORE TO GIVE US ONE MORE K + LSH T,-12 + .CORE (T) + JRST SYSERR + HLRZ T,HLADR + IORI T,1777 + ADDI T,1 + HRRM T,HLADR + JRST RFD2 ;NOW READ IN THE DIRECTORY + +RFD1: CAMN TAC,UDNAMP(T) ;MATCH FOUND TO IN CORE DIRECTORY ? + JRST RFD3 ;YES - USE IT + +RFD2: HRRZI T1,(SIXBIT /DSK/) + HRLI T1,IBIMDE ;IMAGE, BLOCK, INPUT MODE + MOVEM T1,FILNAM + MOVE T1,[SIXBIT /.FILE./] + MOVEM T1,FILNM1 + MOVE T1,[SIXBIT /(DIR)/] + MOVEM T1,FILNM2 + CAME TAC,SNAME ;ARE WE READING OUR OWN UFD ? + .SUSET [.SSNAME,,TAC] ;NO - SO DIRECT US TO THE RIGHT ONE + .IOPUSH UFD, + .OPEN UFD,FILNAM + JRST OPNERR ;ERROR -> DIRECTORY NOT FOUND + ; OR NOT NOW AVAILABLE +RFD2A: AOS -RFDSTK+4(PDP) + CAME TAC,SNAME + .SUSET [.SSNAME,,SNAME] + + HRLI T,-1024. + .IOT UFD,T ;READ IN THE DIRECTORY + + .IOPOP UFD, ;RESTORE CHANNEL + ;** RFD ** + + HRRZ T,HLADR ;ADDRESS OF UFD + MOVE T1,T + ADD T1,UDNAMP(T1) ;GET ADDR OF FIRST FILE NAME + +PASS1: CAIL T1,1024.(T) ;DONE W/FIRST PASS ? + JRST PASS2 ;YES + + SKIPE UNFN1(T1) ;NULL NAME ? + JRST PASS1A ;NO +PASS1B: SETZM UNFN1(T1) ;YES +PASS1C: ADDI T1,LUNBLK ;ADVANCE TO NEXT ENTRY + JRST PASS1 + +PASS1A: MOVE T2,UNRNDM(T1) ;IS THIS A LINK OR A FILE TO BE IGNORED ? + TLNE T2,UNIGFL+UNLINK + JRST PASS1B ;YES - SO SET NAME1=0 TO ERASE IT FROM FUTURE PASSES + HRRZ T2,UNFN2(T1) ;GET LAST 3 CHARS IN EXT + JUMPE T2,PASS1C ;IS IT GOOD? + JRST PASS1B ;NO GOOD, DEC SYSTEM ONLY ALLOWS 3 + ;** RFD ** + +;.OPEN FAILURE WHILE TRYING TO READ UFD +; IF IT WAS DUE TO A "DIRECTORY NOT AVAILABLE" ERROR WE PATIENTLY +; RETRY TO READ THE DIRECTORY IN QUESTION, WAITING 3 SECONDS +; EACH TIME. WE TRY UP TO 5 TIMES. +; IF IT WAS DUE TO A NON-EXISTENT USER WE RETURN TO CALLER AFTER +; RESTORING AC'S. WE GIVE HIM A NON-SKIP RETURN. + +OPNERR: .STATUS UFD,T2 ;WHAT WENT WRONG ?? + LDB T2,[POINT 6,T2,17,] ;COLLECT ERROR CODE FROM BITS 3.1-3.6 + CAIE T2,20 ;DOES USER EXIST ? + JRST OPNER1 ;YES +OPNER3: .IOPOP UFD, ;NO - RESTORE TEMP UFD CHANNEL + CAME TAC,SNAME ;IS IT THE RIGHT SNAME? + .SUSET [.SSNAME,,SNAME] ;NO, SET IT STRAIGHT + JRST UFDFIN ;NON-SKIP RETURN. FIRST RESTORE AC'S + +OPNER1: MOVEI T3,5 ;TRY SLEEPING 3 SECS THEN RETRY. + ; UP TO 5 TIMES OVER +OPNER2: MOVEI T2,90. + .SLEEP T2, + .OPEN UFD, ;TRY + SKIPA ;LOSE + JRST RFD2A ;WIN + SOJG T3,OPNER2 ;TRY AGAIN ? + JRST OPNER3 ;NO - THAT'S ENOUGH OF THIS - LET'S LOSE + ;** RFD ** + +PASS2: MOVE T1,T + ADD T1,UDNAMP(T1) +PASS2B: CAIL T1,1024.(T) ;HAVE WE ADVANCED BEYOND END IN LOOKING + ; FOR A NEW BASE NAME ? + JRST RFD3 ;YES - NOW GO HAVE FUN + SKIPE T2,UNFN1(T1) ;ENTRY NULL ? + JRST PASS2A ;NO - USE IT +PASS2C: ADDI T1,LUNBLK ;ADVANCE + JRST PASS2B ;AND CHECK NEXT + +PASS2A: HLLZ T3,UNFN2(T1) ;READ NAME2 - 1ST 3 CHARS + MOVE T5,T1 ;NEW POINTER +PASS2D: ADDI T5,LUNBLK + CAIL T5,1024.(T) ;HAVE WE PASSED TESTING FOR CURRENT BASE ? + JRST PASS2C ;YES - TRY NEXT BASE + JRST PASS2D ;NO - ADVANCE + ;** RFD ** + +RFD3: HRRZ T1,HLADR + ADD T1,UDNAMP(T1) ;ADD VALUE OF NAME AREA POINTER + +UQL4C: CAIL T1,1024.(T) ;ARE WE DONE ? + JRST UFDFIN ;YES + + SKIPE UNFN1(T1) ;NULL FILE ? + JRST UQL4B ;NO +UQL4D: ADDI T1,LUNBLK ;YES - GO TO NEXT ENTRY + JRST UQL4C + +UQL4B: MOVE T2,UNFN1(T1) ;GET + STASH FIRST NAME + MOVEM T2,FILNAM + HLLZ T2,UNFN2(T1) ;DITTO FOR SECOND + HLLZM T2,FILNM1 + SETZM FILNM2 + SETZM FILNM3 + LDB T2,[UNYRD+UNDATE(T1)] + + SKIPN T2 ;YEAR BIT SET ? + SKIPA T3,YRESET ;NO - LOAD PROPER YEAR EQUIV + MOVE T3,YSET ;YES + + SUBI T3,64. ;NOW CONVERT TO DEC FORMAT + IMULI T3,12. ; C.F. P 377 DEC-PDP10(1969) REFERENCE MANUAL + + LDB T2,[UNMON+UNDATE(T1)] + ADDI T3,-1(T2) + IMULI T3,31. + LDB T2,[UNDAY+UNDATE(T1)] + ADDI T3,-1(T2) + DPB T3,[POINT 12,FILNM2,35,] ;-> E+3(24-35) + LSH T3,-12. ;DATE75 HACKERY + DPB T3,[POINT 3,FILNM1,20,] ;HIGH ORDER 3 BITS + LDB T2,[UNREFT+UNDATE(T1)] + ADDI T3,(T2) + ;GET DATE LAST REFERENCED + DPB T3,[POINT 15,FILNM1,35,] ;-> E+1(21-35) + ;** RFD ** + +;NOW DETERMINE CREATION TIME OF DAY + + LDB T2,[UNTIM+UNDATE(T1)] ;GET IT INTO 1/2 SECS. + IDIVI T2,120. ;THERE ARE 120 1/2 SECS. PER MIN + DPB T2,[POINT 11,FILNM2,23,] ;-> E+2(13-23) + +;MODE/PROTECTION BITS + + SETZ T2, ;ALWAYS .IOASC + DPB T2,[POINT 4,FILNM2,12,] ;MODE + MOVEI T2,055 ;ALWAYS 055 + DPB T2,[POINT 9,FILNM2,8,] ;PROT. + +;NOW DETERMINE FILE LENGTH. FIRST WE USE DESCRIPTOR +; BYTES TO COLLECT BASIC LENGTH. THEN WE ADJUST. + + LDB T2,[UNDSCP+UNRNDM(T1)] + IDIVI T2,UFDBPW + ADDI T2,UDDESC(T) ;TO POINT TO DESCRIPTOR AREA + HLL T2,QBTBLI(T3) + MOVNI T4,1 +UQL5: ILDB T3,T2 ;GET NEXT DESC BYTE + JUMPE T3,UQL5A ;STOP IF DESC=0 + CAILE T3,UDTKMX + JRST UQL5B + ADD T4,T3 + JRST UQL5 + +UQL5B: CAIN T3,UDWPH ;PLACE HOLDER ? + JRST UQL5 ;YES + CAIG T3,UDWPH + AOJA T4,UQL5 + REPEAT NXLBYT,[IBP T2 +] + AOJA T4,UQL5 + +UQL5A: LDB T3,[POINT 10,UNFN2(T1),35,] ;COLLECT INCR. + ; WE HAVE AUTOMATICALLY STARTED FILE LENGTH + ; AT -1024. WORDS + SKIPN T3 ;=0? + AOJ T4, + IMULI T4,8.*128. + ADDI T4,(T3) + SKIPGE T4 + SETZ T4, ;NOW WE HAVE A LENGTH IN WORDS + CAMLE T4,[2_17.] + JRST GT2.17 + MOVNS T4 +ILNGTH: HRLZM T4,FILNM3 + SUBI T1,(T) ;MAKE T1 A RELATIVE POINTER IN CASE CORE HAS + ; TO BE EXPANDED IN THE CO-ROUTINE + PUSHJ PDP,GT1UF ;GOT 1 USER FILE + ; NOW USER'S RETURN ADDR IN -RFDSTK+2(PDP) + HRRZ T,HLADR ;SET UP AC(T) IN CASE HLADR CHANGES + ADDI T1,(T) ;AND MAKE AC(T1) RIGHT + JRST UQL4D + ;** RFD ** + +GT2.17: MOVE T3,T4 + IDIVI T3,128. + SKIPE T4 + AOJ T3, + MOVE T4,T3 + JRST ILNGTH ;INSERT LENGTH + +UFDFIN: POP PDP,T5 ;RESTORE ALL THOSE AC'S + POP PDP,T4 + POP PDP,T3 + POP PDP,T2 + POP PDP,T1 + POP PDP,T + POPJ PDP, ;AND THEN GO AWAY + ;** RFD ** + +;READ RHROUGH IN-CORE SIMULATOR UFD + PASS IT ALONG TO USER, ENTRY-BY-ENTRY. + + +RICUFD: AOS -RFDSTK+4(PDP) + HRRZ T1,DIRLST ;COLLECT BEGINNING OF UFD +RICUF1: JUMPE T1,UFDFIN + HRLZ T2,T1 + HRRI T2,FILNAM ;THE "TO ADDRESS" + BLT T2,FILNAM+FSIZ-1 + PUSHJ PDP,GT1UF + HRRZ T1,FSIZ-1(T1) ;COLLECT NEXT POINTER + JRST RICUF1 + + +;GOT 1 UF (USER FILE ENTRY) + +GT1UF: PUSH PDP,TAC1 + EXCH T,-RFDSTK+3(PDP) + EXCH T1,-RFDSTK+4(PDP) + EXCH T2,-RFDSTK+5(PDP) + EXCH T3,-RFDSTK+6(PDP) + EXCH T4,-RFDSTK+7(PDP) + EXCH T5,-RFDSTK+8.(PDP) + PUSHJ PDP,(TAC1) + ;USER'S RETURN PC NOW IN -RFDSTK+1(PDP) + EXCH T5,-RFDSTK+8.(PDP) + EXCH T4,-RFDSTK+7(PDP) + EXCH T3,-RFDSTK+6(PDP) + EXCH T2,-RFDSTK+5(PDP) + EXCH T1,-RFDSTK+4(PDP) + EXCH T,-RFDSTK+3(PDP) + POP PDP,TAC1 + POPJ PDP, + +QBTBLI: 440600,, + 360600,, + 300600,, + 220600,, + 140600,, + 060600,, + ;** CLRMBF ** + +CLRMBF: PUSH PDP,TAC + HRRZI TAC,MONBUF+1 + HRLI TAC,MONBUF + SETZM MONBUF + BLT TAC,MONBUF+MBFSIZ-1 + JRST TPOPJ ;RESTORE AC(TAC) AND RETURN + ;** RANDOM SIMULATOR ROUTINES ** + +;ENTER WITH PPN IN TAC; RETURN WITH SNAME IN TAC. +;TAC1 GETS CLOBBERED. + +PPTOSN: CAMN TAC,[XWD 1 4] ;IF HE IS SPECIFYING 1,4 (SYS. PPN) + MOVE TAC,SYSPP ;CAUSE THE RESULT TO BE "DECSYS" + CAIN TAC, ;IS IT MYSELF? + MOVE TAC,SNAME ;THEN MAKE IT ME!! + POPJ PDP, ;AND RETURN + +;FIND FREE I.T.S. CHANNEL +;CALLING SEQUENCE: +; PUSHJ P,GTFCHN +; ERROR RETURN ( NONE LEFT ) +; OK RETURN - CHANNEL # IN TAC +;NO AC'S ARE CLOBBERED (EXCEPT TAC!) + +GTFCHN: PUSH PDP,TAC1 ;SAVE TAC1 + MOVSI TAC1,400000_-15. ;POSITION A BIT CORRESPONDING + ;TO CHANNEL 17 + MOVEI TAC,17 ;LOOK FOR FREE CHAN. FROM 17 DOWN TO 0 +GTFCH1: TDNN TAC1,CHNSAT ;IS THIS ONE FREE? + JRST GTFCH2 ;YES, USE IT + LSH TAC1,1 ;NO, SHIFT TO CHECK NEXT + SOJGE TAC,GTFCH1 ;TRIED ALL YET? + SOS -1(PDP) ;YES, CAUSE NON-SKIP RETURN + ;TAC1 NOW = 0 BECAUSE WE MOVED + ;THE BIT ALL THE WAY OUT +GTFCH2: IORM TAC1,CHNSAT ;GRAB THE CHANNEL (IF ANY) + POP PDP,TAC1 ;RESTORE TAC1 + JRST CPOPJ1 ;SKIP RETURN (UNLESS FAILURE ABOVE) + +;RETURN THE ITS CHANNEL WHOSE # IS IN TAC TO A STATE OF +;AVAILABILITY BY CLEARING THE ASSOCIATED BIT IN "CHNSAT". + +RTFCHN: MOVNI TAC,(TAC) ;NEGATE CHANNEL # + HRLI TAC,400000 ;PUT MASK BIT IN BIT 0 + LSH TAC,(TAC) ;POSITION IT TO CORRESPOND WITH CHAN. # + ANDCAB TAC,CHNSAT ;TURN IT OFF IN CHNSAT AND GUARANTEE + ;THAT RH OF TAC IS CLEAR + POPJ PDP, ;RETURN + ;** RANDOM SIMULATOR ROUTINES ** + +;RETURN THE CURRENT TIME OF DAY IN JIFFIES (1/60 SECOND) +;PAST MIDNIGHT IN TAC. + +GTTIME: PUSH PDP,TAC1 ;SAVE TAC1 + PUSH PDP,[0] ;INITIALIZE RESULT + .RTIME TAC1, ;GET TIME IN SIXBIT FROM ITS + PUSHJ PDP,GTTIM1 ;HANDLE HOURS + PUSHJ PDP,GTTIM1 ;HANDLE MINUTES + PUSHJ PDP,GTTIM1 ;HANDLE SECONDS + POP PDP,TAC ;PUT RESULTING # JIFFIES IN TAC +T1POPJ: POP PDP,TAC1 ;RESTORE TAC1 + POPJ PDP, ;AND RETURN + +GTTIM1: PUSHJ PDP,CNVDEC ;GET NEXT TWO SIXBIT DIGITS FROM TAC1 (LEFT) + ;AND CONVERT TO DECIMAL + ADD TAC,-1(PDP) ;UPDATE RUNNING TOTAL + IMULI TAC,60. + MOVEM TAC,-1(PDP) ;STORE BACK + POPJ PDP, ;RETURN + +;TAKES BITS 0-11 OF TAC1 AS TWO SIXBIT DIGITS AND RETURNS +;THEIR DECIMAL EQUIVALENT IN TAC; ALSO SHIFTS TAC1 LEFT 12 PLACES. + +CNVDEC: LSHC TAC,12. ;GET NEXT TWO SIXBIT #'S + PUSH PDP,TAC1 ;SAVE RESULTING TAC1 + ANDI TAC,1717 ;KEEP ONLY PERTINENT BITS + LSHC TAC,-6 ;SEPARATE DIGITS + LSH TAC1,-30. + IMULI TAC,10. ;MAKE 10'S + ADDI TAC,(TAC1) ;FORM DECIMAL EQUIVALENT + JRST T1POPJ ;RESTORE TAC1 AND RETURN + +;RETURN TODAY'S DATE IN TAC IN STANDARD DEC FORMAT: +; DATE=((YEAR-1964)*12+(MONTH-1))*31+DAY-1 + +GTDATE: PUSH PDP,TAC1 ;SAVE TAC1 + .RDATE TAC1, ;GET TODAY'S DATE IN SIXBIT + PUSHJ PDP,CNVDEC ;GET YEAR + SUBI TAC,64. + IMULI TAC,12. ;FORM PARTIAL # MONTHS + PUSH PDP,TAC ;SAVE PARTIAL RESULT + PUSHJ PDP,CNVDEC ;GET MONTH + SUBI TAC,1 ;MINUS 1 + ADD TAC,(PDP) ;FORM TOTAL # MONTHS + IMULI TAC,31. ;FORM PARTIAL # DAYS + MOVEM TAC,(PDP) ;STORE BACK + PUSHJ PDP,CNVDEC ;GET DAY + POP PDP,TAC1 ;RESTORE PARTIAL # DAYS + ADDI TAC,-1(TAC1) ;FORM FINAL RESULT IN TAC + JRST T1POPJ ;RESTORE TAC1 AND RETURN + ;** SIM ** + +;ACCUMULATOR ASSIGNMENTS + +CHREC==TEM +DDB==DEVDAT +LINE==TAC1 +HPOS==ITEM +T4==AC2 + +;I.T.S. FIXED CHANNEL ASSIGNMENTS + +UPRGI==0 ;CHANNEL ASSOCIATED W/USER TO READ HIS CORE +UPRGO==1 ;CHANNEL ASSOCIATED W/USER TO WRITE INTO HIS CORE +CTYI==2 ;CHANNEL ASSOCIATED W/CONSOLE TTY INPUT +CTYO==3 ;CHANNEL ASSOCIATED W/CONSOLE TTY OUTPUT + +FFITSC==4 ;FIRST FREE DYNAMIC I.T.S. CHANNEL + +;TEMPORARILY USED CHANNELS +; SAVED BEFORE AND RESTORED AFTER USAGE WITH .IOPOP'S AND .IOPUSH'S + +UFD==FFITSC ;TO USE WHILE READING UFD'S +SGCHN==FFITSC ;TO USE DURING "GET" AND "SAVE" COMMANDS + +;INTERRUPT BITS AS FOUND IN PIRQC INTERRUPT REQUEST WORDS + +BPIPI==4 ;BAD LOCATION 42 +AROIF==10 ;ARITHMETIC OVERFLOW +BILLOP==40 ;ILLEGAL INSTRUCTION +BIOADC==20000 ;MEMORY PROTECTION VIOLATION +BUTRAP==40,, ;SYSTEM UUO TO USER TRAP +ARFOIF==400,, ;ARITHMETIC FLOATING OVERFLOW + +;FREE STORAGE PARAMETERS + +FSIZ==4 ;# WORDS/CELL ENTRY +DSKCOR==</FSIZ>+1 ;# OF FSIZ-SIZE CHUNKS IN A DSK DDB +SCNCOR==</FSIZ>+1 ;# OF FSIZ-SIZE CHUNKS IN A TTY DDB +MINFRE==DSKCOR ;MINIMUM NUMBER OF FREE CHUNKS IN ORDER TO + ; PROMPT RETURNING 1K TO SYSTEM WHEN MORE THAN 1K + ; OF FREE STORAGE EXISTS. + ; (AT PRESENT WE WANT TO BE SURE THAT THERE WILL BE AT LEAST + ; ENOUGH ROOM FOR ONE DSK DDB, SINCE THE REPETITIVE ASSIGNMENT + ; AND RELEASE OF A DSK DDB MIGHT CAUSE CORE TO THRASH) +IFG SCNCOR-DSKCOR,[MINFRE==SCNCOR] + ;** SIM ** + +;COMMON I/O MODE DEFINITIONS + +IBMDE==6 ;IMAGE, BLOCK +IBIMDE==6 ;IMAGE, BLOCK, INPUT +IBOMDE==7 ;IMAGE, BLOCK, OUTPUT +CTYIMD==4 ;IMAGE, UNIT, INPUT + ; (MODE FOR CTY INPUT) + ; (IMAGE -> HANDLE SPECIAL CHARS OURSELVES; + ; UNIT -> 1 CHAR AT A TIME) +CTYOMD==5 ;IMAGE, UNIT, OUTPUT + ; (MODE FOR CTY OUTPUT) + +;SPECIAL NOTE: +; I.T.S. REFERENCE MANUAL, PAGE 52, SAYS IMAGE MODE => NO +; I.T.S.-SUPPLIED ECHO AND NO MODIFICATION OF CHAR CODES. +; IT IS ASSUMED THAT DEFAULT CONDITION IS THAT ALL CHARS +; ARE BREAK CHARS. + + +;COMMON FILE NAMES + +NULNAM: SIXBIT /NULL/ ;NAME FOR INFERIOR WHEN JBTPRG=0 + +;PUSHDOWN POINTERS + +UJOBPD==-40 ;=-LENGTH OF UUO/MONITOR JOB PUSHDOWN STACK +UPDP: UJOBPD,,USRPDL + +NJOBPD==-40 +NPDP: NJOBPD,,NULPDL + +;DEFINE FIRST SAVED AC ON RECEIVING CLASS-3 INTERRUPT +; (MUST BE >= 17) + +FSAC==17 + ;** SIM -- STARTUP AND INITIALIZATION ** + +GO: + +;ALLOCATE MEMORY + + .CORE _-10. + .VALUE + + MOVE PDP,NPDP ;COLLECT A PUSH DOWN POINTER + +;CLEAR ALL OF WRITABLE CORE + + SETZM FRSTWR ;CLEAR FIRST WORD + MOVE TAC,[FRSTWR,,FRSTWR+1] + BLT TAC,FRSTFR-1 ;COPY THE ZERO WORD BY WORD TIL WE GET TO THE LAST + +;INITIALIZE HLADR SO THAT FREE CORE ROUTINES WILL BEGIN TO WORK + + HRLZI TAC,<<&776000-FRSTFR>/FSIZ>*FSIZ+FRSTFR-1 + ;= "LAST LOCATION" USED BY FREE CORE ROUTINES + ; THIS WILL BE CHAINED JUST AFTER WE "RETURN" ALL CORE AFTER + ; END OF WRITABLE CORE UP TO NEXT K BOUNDARY + MOVEM TAC,HLADR + +;GIVE AWAY AS MUCH AS POSSIBLE TO INITIAL FREE STORAGE, AFTER +; INITIALIZNG FREE CORE WRITABLE WORDS. + + MOVEI AC1,<&776000-FRSTFR>/FSIZ + JUMPE AC1,.+3 + MOVEI AC2,FRSTFR + PUSHJ PDP,RTF ;"RETURN" CONTIGUOUS FREE CHUNKS STARTING + ; AT FRSTFR + +;INITIALIZE CHNSAT + + MOVSI TAC,-1_<18.-FFITSC> ;PLACE A BIT IN LH OF CHNSAT FOR + MOVEM TAC,CHNSAT ;FOR EVERY I.T.S. CHANNEL WE INTEND TO PREEMPT + +;INITIALIZE DDB'S + + MOVEI DDB,CTYDDB + PUSHJ PDP,MNTDDB + MOVEI DAT,CTYI + DPB DAT,PDEVI + MOVEI DAT,CTYO + DPB DAT,PDEVO + MOVSI IOS,TPMON ;TTY IN MONITOR MODE + MOVEM IOS,DEVIOS(DDB) + MOVSI TAC,DVIN+TTYATC ;INSERT INPUT-DEVICE BIT INTO DEVICE + IORM TAC,DEVMOD+CTYDDB ;DESCRIPTION OF USER'S CONSOLE TTY + ; ALSO INCLUDE TTY ATTACHED TO JOB BIT + + HRLZI AC1,LP0DDB ;INITIALIZE NON-ZERO SEGMENT OF LINE PRINTER DDB + HRRI AC1,LPTDDB + BLT AC1,LPTDDB+LP0LEN-1 + + HRLZI AC1,DSDDB ;DITTO FOR PROTOTYPE DSK DDB + HRRI AC1,DSKDDB + BLT AC1,DSKDDB+DSLEN-1 + + MOVSM DDB,DEVLST ;CTY BECOMES FIRST DDB IN CHAIN + MOVSI TAC,LPTDDB + HLLM TAC,DEVSER+CTYDDB + MOVSI TAC,DSKDDB ;PROTOTYPE DSK DDB ALWAYS LAST OF NON-EXPANDING + HLLM TAC,DEVSER+LPTDDB ;DDB'S + ;** SIM -- INITIALIZATION ** + +;INITIALIZE FILE DIRECTORY + + .SUSET [.RSNAME,,SNAME] ;READ CURRENT POINTER TO UFD + MOVE TAC,SNAME ;PREPARE TO INITIALIZE PRJPRG WORD + MOVEM TAC,PRJPRG ;DONE + +;MISC NON-ZERO WORDS IN WRITABLE CORE + + MOVE TAC,[JRST PRCINT] + MOVEM TAC,INTR2 + + MOVEI TAC,(SIXBIT /DSK/) + MOVEM TAC,FRENAM + + .SUSET [.RUIND,,JOB] + + MOVE TAC,[SQUOZE 0,NQS] ;COLLECT SYSTEM VALUES FOR VARIABLES + .EVAL TAC, ;USED BY "RESOURCES" COMMAND + .VALUE + HRRZM TAC,NQSV + MOVE TAC,[SQUOZE 0,QACT] + .EVAL TAC, + .VALUE + HRLM TAC,QACTV + MOVE TAC,[SQUOZE 0,QTUTO] + .EVAL TAC, + .VALUE + HRRZM TAC,QTUTOV + MOVE TAC,[SQUOZE 0,QSFT] + .EVAL TAC, + .VALUE + HRLM TAC,QSFTV + + .RYEAR TAC, + MOVEI TAC,-3554(TAC) + MOVEI TAC1,TAC + + PUSH PDP,TAC1 ;SAVE YEARPH + ADD TAC1,TAC ;TAC1 NOW HAS THE YEAR WHICH CORRESPONDS TO + ;MISMATCH BETWEEN YEAR BIT IN UNDATE (OF UFD) AND LAST BIT OF YEAR. + ; SOMETIMES A NON-MATCH->"LAST" YEAR, SOMETIMES A NON-MATCH + ; -> "NEXT" YEAR. + + MOVE T1,TAC ;IT WILL BE YEAR GIVEN IF YEAR BIT RESET + MOVE T2,TAC ;T2 WILL BE YEAR IF YEAR BIT SET + TRNN TAC,1 ;IS THIS AN EVEN YEAR ? + SKIPA T2,TAC1 ;YES - YEAR BIT BEING SET -> CHANGE + MOVE T1,TAC1 ;NO - YEAR BIT RESET -> CHANGE + MOVEM T2,YSET + MOVEM T1,YRESET + POP PDP,TAC1 ;RESTORE AC(TAC1)=YEARPH + ;** SIM -- INITIALIZATION ** + +;NOW TO FOOL AROUND FINDING WHETHER OR NOT THE YEAR BIT +; IN A DATE (LAST 28. BITS OF UNDATE ENTRY=DATE) SHOULD BE XOR'ED TO MAKE A +; SIMPLE COMPARE OF .GT. OR .LT. WORK. + + ADDI TAC1,1 ;-1->0, 1->2 + ASH TAC1,-1 ;YEARPH=-1 -> 0 -> 0 + ;YEARPH=1 -> 2 -> 1 + XOR TAC1,TAC + XORI TAC1,1 + ANDI TAC1,1 ;YEARPH=-1, YEAR EVEN -> 1 + ;YEARPH=-1, YEAR ODD -> 1 -> 0 + ;YEARPH=1, YEAR EVEN -> 1 -> 0 + ;YEARPH=1, YEAR ODD -> 0 -> 1 + +;RESULT=1 -> BIT MUST BE XOR'ED TO WIN +;RESULT=0 -> BIT MUST BE UNCHANGED TO WIN (BUT XOR'ING WON'T HURT) + + LSH TAC1,27. ;PUT RESULT IN RIGHT PLACE FOR THE XOR + MOVEM TAC1,XRYRBT + +;INITIALZE UUO EXECUTE LOCATION + + MOVE TAC,[JSR UUOH] ;THE INITIAL PART OF USER UUO HANDLING TAKES PLACE IN WRITABLE CORE + MOVEM TAC,41 ;SINCE I.T.S. ALWAYS SIMULATES A JSR TO THE EA OF 41 + MOVE TAC,[PUSH PDP,UUOH] ;WE THEN SIMULATE A PUSHJ PDP,UUOHAN AS IF IT CAME FROM 41 + MOVEM TAC,UUOH1 + MOVE TAC,[JRST UUOHAN] + MOVEM TAC,UUOH2 + +;INITIAIZATION OF CONSOLE TTY +; INCLUDED IN THE DDB OF EVERY DEVICE ARE THE I.T.S. +; CHANNEL #'S ASSOCIATED WITH INPUT AND OUTPUT OF +; EVERY CHANNEL. FOR TTY (OR, MORE GENERALLY, FOR ANY +; CLASS 3 INTERRUPT DUE TO THE GENERAL CONDITION: +; BUFFERED TTY INPUT ON CHANNEL.) EVENTUALLY, IT IS EXPECTED THAT +; > 1 TTY DEVICE MAY BE ATTACHED TO A JOB. +; (E.G. SELECTRIC TTY FOR SCRIPT OUTPUT.) + + HRRZI TEM,(SIXBIT /TTY/) + HRLI TEM,CTYIMD ;MODE OF CTY INPUT + MOVEM TEM,FILNAM + SETZM FILNM1 + SETZM FILNM2 + +;NOW GRAB I.T.S. CHANNELS FOR CTY (ASSUMING THAT WE HAVE +; CONTROL OF CONSOLE) + + .OPEN CTYI,FILNAM ;AND GRAB IT + .VALUE ;OPEN CTYI, FAILURE + HRLZI TEM,CTYOMD ;CTY OUTPUT MODE + HLLM TEM,FILNAM + .OPEN CTYO,FILNAM + .VALUE ;OPEN CTYO, FAILURE + +;RESET THE OLD TTY CHANNELS + .RESET CTYI, + .RESET CTYO, + .RESET UPRGO, + .DISMIS [.+1] + ;THIS SHOULD HELP US OUT ESPECIALLY IF WE HAPPENED TO + ; RESTART THE PROGRAM NEVER HAVING .DISMISS'ED + ; OURSELVES FROM OUR INTERRUPT ROUTINE. + ;** SIM ** + + MOVE TAC,SNAME ;NOW'S THE TIME TO READ IN OUR UFD + MOVEI TAC1,INITFD ;HERE'S WHERE WE GO EACH TIME AN ENTRY IS FOUND + PUSHJ PDP,RFD ;READ THE UFD IN, SKIPS IF FOUND + HRROS DIRLST ;NON-SKIP, USER HAS NO DIRECTORY + MOVSI TAC,200000 ;INSERT BIT 1 IN LEFT HALF OF DIRLST IF USER HAS A DIR + SKIPL DIRLST + IORM TAC,DIRLST + HRRZ TAC,HLADR ;COLLECT ADDRESS OF FIRST WORD IN TOP K + LSH TAC,-12 ;CONVERT IT TO A CORE SIZE + .CORE (TAC) ;REDUCE CORE TO THAT AMOUNT + .VALUE + HLLZS HLADR ;AND INFORM THE WORLD THAT IT IS NO LONGER THERE + .IOT CTYO,.CR + .IOT CTYO,.LF + .IOT CTYO,PERIOD ;TYPE A PERIOD AS SIGNON + +;NOW LET'S GET THE OLD INTERRUPT ROUTINES IN ORDER + + MOVE DAT,[JSR INTR] + MOVEM DAT,42 + .IOPDL ;RESET I/O PUSHDOWN LIST + .SUSET [.SMASK,,[0]] ;RESET PRIQC INTERRUPT MASK + .SUSET [.SMSK2,,[377,,1_]] ;THIS ENABLES THE TTY INPUT INTERRUPT. + ; ALSO ENABLED ARE BITS TO ALLOW INTERRUPTS GENERATED + ; BY ANY INFERIOR. BOTH ARE WORD-2 INTERRUPTS. BOTH ARE + ; CLASS-3 INTERRUPTS. + +;NOW IT'S BEDDY-BY TIME ... ZZZZZZ + +DSLEEP: JFCL + .HANG + ;** SIM ** + +;DESCRIPTION OF INTERRUPT TIMING AND PROCESSING. + +; WE ORDINARILY WILL BE EXPECTED TO HANDLE 2 TYPES OF INTERRUPTS: +; (1) CHARACTER-TYPED-ON-USER'S-TTY INTERRUPTS, AND (2) INFERIOR +; INTERRUPT DUE TO ATTEMPTED EXECUTION OF A SYSTEM UUO. +; BOTH OF THESE ARE CLASS-3 INTERRUPTS. + +; DURING REAL EXECUTION OF USER PROGRAMS, THE SECOND TYPE OF INTERRUPT, +; AS DESCRIBED ABOVE, IS EXPANDED TO INCLUDE INTERRUPTS BY +; THE INFERIOR DUE TO ILLEGAL OP CODES, PUSHDOWN OVERFLOW, AND +; MEMORY PROTECTION VIOLATIONS BESIDES THE SYSTEM UUO INTERRUPTS. +; IN FACT, THE USER MAY WISH TO ENABLE ARITHMETIC AND FLOATING OVERFLOW +; TRAPPING, IN WHICH CASE THESE CONDITIONS MAY CAUSE THE INFERIOR +; TO GENERATE CLASS-3 INTERRUPTS, WHICH IN THIS CASE WILL +; ALSO GENERATE "BAD LOCATION 42" INTERRUPTS - AND +; SINCE THESE ARE CLASS-2 INTERRUPTS, THEY WILL CAUSE AN INTERRUPT HERE. + +; THE TIMING BETWEEN INTERRUPT PROCESSING FOR CHARACTERS AND +; INFERIORS IS SOMEWHAT INVOLVED, SINCE SOME SCHEDULING IS NEEDS +; COMBINED WITH EVERYTHING ELSE. + +; CHARACTER INTERRUPTS ARE HANDLED FIRST. CHARACTERS ARE INPUT UNTIL +; THEY ARE EXHAUSTED WITH REPEATED .ITYIC INSTRUCTIONS. THEN, IF WE FIND THAT A BREAK +; CHARACTER HAS BEEN RECEIVED THEN EITHER THE COMMAND DECODER OR THE +; USER UUO ROUTINES WILL BE EXECUTED, DEPENDING WHETHER THE USER +; WAS IN COMMAND MODE OR TELETYPE-INPUT-WAIT MODE. + +; IF NO TTY INTERRUPT WAS RECEIVED, OR IF NO BREAK +; CHARACTERS WERE SEEN, THE INTERRUPT REQUEST WORD +; IS CHECKED FOR INFERIOR INTERRUPT REQUEST +; BITS (BITS 3.1-3.8). IF FOUND, INTERRUPTS DUE TO ATTEMPTED EXECUTION OF +; SYSTEM UUOS OR ILLEGAL OP CODES ARE HANDLED BY UUOCON. IF THE USER IS +; ENABLED FOR OTHER INTERRUPTS SEEN IN THE INFERIOR'S PIRQC WORD, +; CONTROL IS PASSED TO HIM. OTHERWISE, THE INTERRUPT MUST BE DUE +; TO MEMORY PROT VIOLATIONS OR A USER-UNENABLED CONDITION. +; IN THIS CASE CONTROL IS PASSED TO ERRCON WHERE AN ERROR MESSAGE IS TYPED. + +; SHOULD THE USER RETURN FROM UUO PROCESSING IN MONITOR MODE (WHICH WOULD HAPPEN +; AS THE RESULT OF A CALLI 12, FOR EXAMPLE), WE CHECK TO SEE IF COMMAND LINES +; ARE PENDING. + ;** SIM ** + +;PROCESS WORD1 INTERRUPTS + +PRCINT: SKIPL INTR ;WORD1 INTERRUPT (PIRQC-TYPE) ? + JRST SYSERR ;STOP IF WORD1 INTERRUPT FOUND + +;PROCESS WORD2 INTERRUPTS + + MOVEM 17,SAV17 + MOVE 17,INTR + TRNN 17,1_ ;CONSOLE INTERRUPT ? + JRST PW2IB ;NO + SKIPN TTYOIP + JRST PW2IW + SOS TTYOIP + MOVEI 17,CTYI + .ITYIC 17, + JRST SYSERR + CAIE 17,3 ;^C ? + JRST PW2IY + SKIPN CNCLAS + JRST PW2IZ + TLO IOS,IOSUPR ;SUPPRESS OUTPUT FOR WHATEVER TTY THIS HAPPENS TO BE. + ; SINCE IOS ISN'T STORED BACK INTO DDB, WE WON'T BE THIS WAY FOR + ; LONG. BUT ^C^C IS TOP PRIORITY. + JRST PW2IX +PW2IZ: SETOM CNCLAS + JRST ENDINT +PW2IY: SETZM CNCLAS + CAIE 17,17 ;^O ? + JRST ENDINT + MOVSI 17,IOSUPR + XORB 17,DEVIOS+CTYDDB + MOVE IOS,DEVIOS(DDB) ;RESTORE AC(IOS) +PW2IX: HRRZ 17,INTR1 + CAIN 17,PUTCH ;IS THIS THE XCT TAC WHICH .IOT'S + AOS INTR1 + JRST ENDINT + +PW2IW: MOVE PDP,NPDP ;START UP WITH A PUSHDOWN STACK + MOVEI DDB,CTYDDB +PW2IA: SKIPN TTYOIP + JRST PW2II + AOSL TTYOIP + .DISMIS DSLEEP + JRST PW2IJ +PW2II: MOVEI CHREC,CTYI + .ITYIC CHREC, ;READ NEXT CHAR + JRST PW2IB ;NO MORE LEFT TO PROCESS +PW2IJ: .IOT CTYI,CHREC ;.IOT THE CHARACTER + ;** SIM ** + +;CODE HERE BASED ON SCNSRF, COMMON RECEIVER INTERRUPT ROUTINE +; FOR ALL KEYBOARD DEVICES. CODE AT RECINT:, FF. (PP 44-45) + + TRNN CHREC,177 ;IGNORE NULLS + JRST PW2IA + HLLZ LINE,TTYLIN(DDB) + MOVE IOS,DEVIOS(DDB) +;RECIN2: + ANDI CHREC,177 ;7-BIT ASCII ONLY + CAIN CHREC,3 ;^C ? + PUSHJ PDP,CNCTST ;YES - SEE IF 2ND IN A ROW + LDB HPOS,PHPOS ;PICK UP HORIZONTAL POSITION OF OUTPUT CHAR + MOVEI DAT,TTIBUF(DDB) + PUSHJ PDP,TTEDIT ;GO EDIT (+ ECHO) CHAR + TRNN IOS,NOECHO ;ECHO-ING DONE ? + DPB HPOS,PHPOS ;YUP - UPDATE + HLLM LINE,TTYLIN(DDB) + + TLNN IOS,SYNC+DDTM ;WAS A BREAK CHAR TYPED ? + JRST PW2IA ;NO - SO THAT'S ALL THERE IS TO THIS CHAR + SKIPG TISYNC(DDB) ;HAVE WE ALREADY SET THIS LOSER FOR COMMAND ? + PUSHJ PDP,COMSET ;NO - SET UP IOFST IN AC(IOS) IF TPMON SET + TLNE IOS,SYNC + AOS TISYNC(DDB) ;TISYNC GETS INCREMENTED IF BREAKB OR FCSBRK SEEND + ; IN LH OF SPCTAB ENTRY FOR CHAR. (OR IF CHAR=). + MOVSI IOS,SYNC + ANDCAB IOS,DEVIOS(DDB) ;CLEAR SYNC BIT + MOVE TAC,TIPCTR(DDB) ;ALL BREAK CHARS (WHICH CAUSE SYNC TO BE SET) + DPB TAC,PLSTLC ;AND ALL CHARS RECEIVED IN DDT MODE CAUSED ^U UPDATING. + TLNE IOS,IOW ;IN I/O WAIT ? + TLZN IOS,TTYIOW ;AND STILL THERE ? + JRST PW2IA ;NO + MOVEM IOS,DEVIOS(DDB) ;CLEAR "STILL WAITING BIT" + JRST PW2IA ;ALL DONE W/THIS CHAR, LOOK FOR NEXT + ;** SIM ** + +;TTY CHARS HAVE BEEN SEEN, BUT NOW THEY HAVE BEEN EXHAUSTED. +; CALL COMMAND DECODER IF IN MONITOR MODE. UPON RETURN FROM COMMAND, +; CALL DECODER AGAIN IF WE ARE STILL IN MONITOR MODE AND THERE ARE MORE COMMANDS +; WAITING. + +PW2IB: SKIPN TTYOIP ;TTY OUTPUT IN PROGRESS ? + JRST .+3 ;NO + .SUSET [.SIFPIR,,INTR] ;YES - FIRST MAKE SURE THAT WE GET THIS INTERRUPT + ; A SECOND TIME, WHEN WE CAN REALLY DO SOMETHING WITH IT + JRST @INTR1 ;FINISH UP WITH THOSE CHARS FIRST + MOVE PDP,NPDP + PUSHJ PDP,TTYFNU + TLNN IOS,TPMON ;IN MONITOR MODE ? + JRST PW2IF ;NO - NOW CHECK INTERRUPTS FROM INFERIORS. NOTE, + ; THIS BIT MAY HAVE BEEN SET AT INTERRUPT TIME, BUT + ; CLEARED IF COMMAND FORCED JOB TO BE STOPPED. + SKIPG TISYNC(DDB) ;COMMANDS WAITING ? + JRST PW2IC ;NO + PUSHJ PDP,COMMAND ;CALL COMMAND DECODER. + ; WE ARE IN MONITOR MODE AND A COMMAND LINE IS WAITING. + ; COMMAND: HAD BETTER REDUCE TISYNC TO MAKE THIS ALL WORK. + JRST PW2IB ;LOOK TO SEE IF MORE COMMANDS ARE WAITING + +PW2IF: TLNE IOS,IOW ;ARE WE IN IOWAIT ? + TLNE IOS,TTYIOW ;AND STILL WAITING ? + JRST PW2IC ;YES + + MOVSI AC3,USRDAC ;NO - PREPARE TO GO BACK INTO MIDDLE OR USER UUO PROCESSING + BLT AC3,16 ;RESTORE AC'S + JRST @USRPC ;GO BACK INTO OUR CODING + ;** SIM ** + +;NOW CHECK TO SEE IF INFERIOR INTERRUPT TO BE PROCESSED. +; IT MAY HAVE BEEN CAUSED BY AN ILLEGAL INSTRUCTION, A SYSTEM UUO +; (OPCODES 40-127, AND 0), OR AN ILLEGAL REFERENCE TO MEMORY. +; THIS BIT WILL BE TURNED OFF IF WE WERE REQUESTED TO STOP JOB BY +; COMMAND DECODER. THE USER PC WILL HAVE BEEN DECREMENTED BY 1 SO +; THAT A 'CONTINUE' WILL WORK. + +PW2IC: MOVE TAC,INTR + TLZN TAC,377 ;ANY INTERRUPTS FROM OUR (IN FACT, ANY) INFERIOR ? + JRST ENDINT ;NO - ALL DONE + MOVEM TAC,INTR ;RESET INTR.3 SO WE DON'T GET HERE AGAIN + SKIPL JBTSTS ;DO WE UNDERSTAND THIS TO BE A RUNNING PROGRAM ? + JRST SYSERR ;IF NOT - LOSE BIG + + .USET UPRGO,[.RPIRQC,,TAC] ;READ IN HIS INTERRUPT REQUEST WORD + TDZN TAC,[BUTRAP\BILLOP] ;ILLEGAL INSTRUCTION OR SYS UUO TRAP ?? + JRST PW2ID ;NO - MUST BE A MEM VIOLATION OR PDL OVFOR AROV OR FOV + .USET UPRGO,[.SPIRQC,,TAC] ;RESET REQUEST + + .USET UPRGO,[.RSV40,,FORTY] ;SET UP LOCATIONS SO THAT UUOCON HAS A HOLD ON THE WORLD + .USET UPRGO,[.RUPC,,UUO0] ;READS USER'S AT TIME OF TRAPPING UUO + JRST UUOUSR ;CALL UUO CONTROLLER +URETRN: ;RETURNS HERE + + SKIPN TTYOIP ;TTY OUTPUT IN PROGRESS + JRST PW2IB ;RETURN TO SEE IF WE HAVE SWITCHED MODES - IF WE HAVE, + ; COMMANDS MAY BE READY TO PROCESS + ; (NOTE THAT WE START USING NPDP AGAIN) + JRST PW2IW + ;** SIM ** + +PW2ID: PUSH PDP,TAC + TDZN TAC,[BIOADC\200000\AROIF\ARFOIF\BPIPI] ;DID WE GET SOME COMBINATION OF + ; ANTICIPATED INTERRUPTS ? + JRST SYSERR ;NO !! + .USET UPRGO,[.SPIRQC,,TAC] ;RESET REQUEST WORD + +;PROCESS USER INTERRUPTS FOR ILL MEM/PC OUT OF BOUNDS, PDL OVF, AROV, AND FOV. +; RESTART USER IF HE WISHES TO HANDLE TRAPS. +; ALWAYS RETURNS + + POP PDP,APRERR ;STORE INTERRUPT FLAGS + ; (ALSO USED AS AN ERROR FLAG) + .USET UPRGO,[.RUPC,,APRCHL] + PUSHJ PDP,APRER + JRST PW2IB ;GO BACK- WE MAY HAVE SWITCHED TO MONITOR MODE W/SOME + ; COMMANDS READY IN OUR INPUT BUFFER. WE DON'T PROCESS WORD2 + ; INTERRUPTS MORE THAN ONCE EACH DUE TO THE FACT THAT INTR: + ; WAS SUITABLY CLEARED. + + +ENDINT: + MOVE 17,SAV17 + .DISMIS INTR1 ;SEE I.T.S.R.M. P 96 + ;** SIM -- A COUPLE OF MISC ROUTINES USED DURING INITIALIZATION ** + +MNTDDB: ;MAKE A NEW TTY DDB STARTING AT LOCATION + ; AS ADDRESSED BY AC(DDB). ESSENTIALLY COPIES OUT + ; PROTOTYPE (THERE THERE HAD BETTER BE ENOUGH ROOM) + ; AND THEN COMPUTES AN IMMEDIATE ADDR (OR 2) AND PUTS THEM INTO + ; THE NEW DDB AT THEIR PROPER PLACES. SEE TTYINI:, + ; SCNSRF, P 7. + HRLZI AC1,SCNDDB ;GET ADDR OF THAT PROTOTYPE + HRRI AC1,(DEVDAT) + BLT AC1,SCNLEN-1(DEVDAT) ;WRITE OUT INITIAL SCNLEN WORDS FROM + ; PROTOTYPE + SETZM SCNLEN(DEVDAT) ;THEN ZERO OUT THE REST + HRLZI AC1,SCNLEN(DEVDAT) + HRRI AC1,SCNLEN+1(DEVDAT) + BLT AC1,SCNDDS-1(DEVDAT) + HRRZI TEM,TIBF(DDB) + HRRM TEM,TTIBUF(DDB) + JRST TSETBF + +INITFD: + MOVEI AC1,1 ;GET 1 CHUNK FOR THIS UFD ENTRY + PUSHJ PDP,GTF ;RETURNS ADDRESS OF CHUNK IN T -- OUR "TO ADDRESS" + MOVE T1,AC1 + HRLI T1,FILNAM ;THE "FROM ADDRESS" + BLT T1,FSIZ-1(AC1) ;ZAP + MOVE T1,DIRLST ;INSERT THIS CHUNK AS THE NEW BEGINNING ENTRY + ; THIS PREVENTS US FROM GETTING SCREWED IF CORE HAS + ; TO BE MOVED, THEREBY CHANGING THE ADDRESSES OF + ; SPECIFIC UFD ENTRIES. + HRRM AC1,DIRLST + HRRM T1,FSIZ-1(AC1) + POPJ PDP, ;RETURN TO LET RFD: GIVE US SOME MORE ENTRIES + + +PERIOD: ". +.CR: 15 +.LF: 12 + +;LITERALS GO HERE + + CONSTANTS + +;PATCH SPACE HERE + +PATCH: BLOCK 100. + ;** SIM -- WRITABLE CORE ** + + +FRSTWR==. ;FIRST LOCATION OF WRITABLE CORE + +INTR: 0 +INTR1: 0 + ;LOCATION 42 (THE INTERRUPT LOCATION) HAS A JSR + ; INTR. THE USER'S APPROPRIATE INTERRUPT WORD GETS STORED + ; HERE. SEE I.T.S. REFERENCE MANUAL, P 93. + ;THE INTERRUPT REALLY CAUSES A JSR TO INTR1. +INTR2: JRST PRCINT ;GO TO OUR INTERRUPT PROCESSOR + + +FRENAM: 0,,(SIXBIT /DSK/) ;DEVICE NAME + 0 ;FILE TO BE DELETED OR RENAMED + 0 ;FILE TO BE DELETED OR RENAMED + 0 ;NEW NAME1 OR 0 FOR DELETE +FOPRNM: 0 ;NEW NAME2 OR INSIGNIFICANT + 0 ;ALWAYS = 0 +FILNAM: 0 ;FOR OUR .OPEN'S +FILNM1: 0 ;NAME1 +FILNM2: 0 ;NAME2 +FILNM3: 0 ;USED BY MISC FOR RENAMING +FILNM4: 0 + +DIRLST: 0 ;RH POINTS TO LIST OF USER DIRECTORY ENTRIES, + ; EACH "FSIZ LONG. FORWARD POINTER IN ENTRY FOUND IN RH + ; OR LAST WORD. +DEVLST: 0 ;LH POINTS TO DDB CHAIN, THE FIRST OF WHICH IS THAT + ; FOR THE CTY. FORWARD POINTERS FOUND IN LH OF DEVSER WORD OF DDB. +HLADR: 0 ;RH=ADDRESS OF 1K DIRECTORY BLOCK IF IT EXISTS, + ; 0 IF NOT + ;LH = LAST LOCATION USED BY FREE CORE ROUTINES. MUST + ; BE INITIALIZED WHEN INITIAL BLOCK OF FREE CORE GIVEN TO FREE STORAGE ROUTINE +FRENUM: 0 ;# FREE CELLS, EACH "FSIZ" LONG +FREEPT: 0 ;RH POINTS TO LIST OF FREE CELLS. FORWARD POINTER IN + ; CELL BLOCK IN RH OF LAST WORD + +CHNSAT: 0 ;I.T.S. CHANNEL ASIGNMENTS TABLE + +TTYOIP: 0 +CNCLAS: 0 + +SAV17: 0 + +SNAME: 0 ;SNAME FOR CURRENT USER - USED BY RFD: +JOB: 0 ;USER INDEX OF SIM PROCEDURE (USED AS JOB NUMBER) + +NQSV: ;SAVE-LOCATIONS OF VARIABLES USED IN "RESOURCES" COMMAND +QACTV: 0 ;VALUES OCCUPY HALF WORDS ONLY +QTUTOV: +QSFTV: 0 + +DAMESS: ASCII /-Jan-/ ;C.F. [CLOCK1, P 1] + ;*** WE DEPEND ON YSET HAVING A NULL INITIAL BYTE *** + +YSET: 0 ;YEAR TO USE IF YEAR BIT FOUND TO BE SET +YRESET: 0 ;YEAR TO USE IF YEAR BIT FOUND TO BE RESET +XRYRBT: 0 ;BIT TO XOR TO 28 BIT CREATION DATE FOUND IN + ; UNDATE WORD OF I.T.S. UFD ENTRY TO MAKE SIMPLE + ; .LT., .GT. COMPARING WORK TO DETERMINE IF ONE FILE NEWER + ; THAN ANOTHER + +;"TIME" STORAGE CELLS + +TRTPI: 0 ;TOTAL RUN TIME FOR PAST INFERIORS +TRTPIT: 0 ;TOTAL RUN TIME FOR PAST INFERIORS SINCE LAST "TIME" + ; COMMAND +TRTST: 0 ;TOTAL RUN TIME FOR SIMULATOR AT LAST "TIME" COMMAND +TRTIT: 0 ;TOTAL RUN TIME FOR CURRENT INFERIOR AT LAST "TIME" COMMAND. + ;ALL VALUES STORED IN 4.069 MICROSECOND UNITS + +;APR TRAPPING VARIABLES + +APRCHL: 0 +APRPC=APRCHL +APRERR: 0 +ITSENB: 0 ;I.T.S. INTERRUPT REQUEST WORD + ; (IE I.T.S. VERSION OF USER'S ENABLED TRAPS) + + +;PUSHDOWN STORAGE + +USRPD1=. +USRPDL=USRPD1-1 +USRPD3=USRPDL+3 + BLOCK -UJOBPD + +NULPDL=.-1 + BLOCK -NJOBPD + +;C.F. COMMON.MAC PAGE 6 + +USRREL: 0 +USRHCU: 0 ;HIGHEST USER I/O CHANNEL IN USE. + ; 0 MEANS EITHER NONE OF CHANNEL 0 IN USE. +USRPC: 0 +USRDDT: 0 ;RH=STARTING ADDRESS OF USER DDT. + ; LH UNUSED +USRJDA: BLOCK 20 ;RH=JOB DEVICE ASSIGNMENTS (DEVICE DATA BLOCK + ; ADRESSES) + ;LH=UUO'S DONE SO FAR FOR THIS CHANNEL. + ;0 MEANS NO DEVICE INITIALIZED ON THIS CHANNEL. +USRLO==USRJDA ;FIRST LOCATION TO ZERO OUT IN CORE ON RESET UUO +USRLO1==USRLO+1 +USRHI==.-1 ;LAST LOC AFFECTED BY THE ABOVE + +USRFDV: 0 ;USED BY "FINISH" CODING +USREXM: 0 ;USED BY EXAMINE/DEPOSIT COMMANDS + +;USER DUMP AC AREA + +USRDAC==. +USRDPD==USRDAC+PDP +USRD16==USRDAC+16 + BLOCK 17 + +;C.F. COMMON.MAC PAGES 12-13 + +JBTSTS: 0 ;JOB STATUS WORD +JBTADR: 0 +JBTNAM: ;NAME OF HIGH SEGMENT (FILE IT WAS INITIALIZED FROM) +JBTPRG: 0 ;NAME OF FILE USED IN LAST R, RUN, GET, ETC. +PRJPRG: 0 ;USER'S "PROJECT-PROGRAMMER #" (CONVERTED FROM USER'S SNAME) + +;UUOCON STORAGE CELLS + +FORTY: 0 ;CONTENTS OF MONITOR LOCATION 40 IF WERE TO HAVE + ; RECEIVED A TRAP FROM USER ON ILLEGAL INSTRUCTION OR + ; SYSTEM UUO +UUO0: 0 ;D.E.C. MONITOR WOULD HAVE DONE A JSR UUO0 + ; UPON RECEIVING A LOCATION 40 TRAP + +;UUO HANDLER VARIABLES (HANDLES UUO'S 0-37) VIA I.T.S. MONITOR + +UUOH: 0 ;I.T.S. SIMULATES A JSR TO HERE +UUOH1: PUSH PDP,UUOH ;FIRST WE SAVE RETURN POINTER ON PUSHDOWN STACK +UUOH2: JRST UUOHAN ;THEN CALL THE UUO HANDLER + +MBFSIZ==200 +MONBUF: BLOCK MBFSIZ + + + +;C.F. COMCON.MAC PAGE 64 + +;SAVGET CORE LOCATION USED FOR UUOS TO MONITOR. +; USED IN SAVGET IN SEGCON.MAC + +SGANAM: 0 ;FILE NAME +SGAEXT: 0 ;FILE X10N +SGADAT: 0 ;FILE CREATION DATE AND TIME +SGALEN: 0 ;PROJECT-PROGRAMMER NUMBER +SGAPPN: 0 ;PLACE TO SAVE PROJ.,PROG. USED TYPED IN +SGAMOD: 0 ;IOS MODE WORD FOR OPEN UUO +SGADEV: 0 ;DEVICE NAME +SGAHED: 0 ;I/O BUFFER HEADER ADDRESSES (=0) +SGADMP: 0 +SGANEW: 0 ;NEW CORE ASSIGNMENT SPECIFIED BY 3RD ARG +SGAHGH: 0 ;LH=EXT TO USE FOR SAVING HIGH SEG +SGALOW: 0 ;LH=EXT WHICH USER TYPED FOR SAVE OR GET + ; OR .SAV IF HE DIDN'T TYPE ARG W/LEADING PERIOD. + ;RH=0 +SDVNMF: 0 ;SAW DEVICE FLAG +CTYDDB: BLOCK SCNDDS + +LPTDDB: BLOCK LP0DDS ;LINE PRINTER DDB + +DSKDDB: BLOCK PTR1 ;PROTOTYPE DSK DDB + +FRSTFR=. + + END GO