Trailing-Edge
-
PDP-10 Archives
-
red405a2
-
uetp/lib/oper20.mac
There is 1 other file named oper20.mac in the archive. Click here to see a list.
;<EIBEN.U>OPER20.MAC.1, 5-Jun-79 11:54:34, EDIT BY EIBEN
TITLE OPER20 PERFORM FUNCTIONS AT INTERVALS
SUBTTL C.MITCHELL 1977. WRITTEN AT COLOGNE.
SEARCH MONSYM,MACSYM,CMLBSM
IFNDEF .PSECT,<
.DIRECT .XTABM>
SALL
;ENTRY VECTOR
PRGCST==0 ;CUSTOMER ID
PRGVER==1 ;VERSION NUMBER
PRGMIN==0 ;MINOR VERSION
PRGEDT==0 ;EDIT NUMBER
ENTVEC: JRST START ;START ADDRESS
JRST PARSE ;REENTER ADDRESS
PRGCST_^D33+PRGVER_^D24+PRGMIN_^D18+PRGEDT
;LOCAL SYMBOLS
WAKUPT==^D1*^D60*^D1000 ;SLEEP TIME IN MILLISECONDS
ZONDIV==^D15 ;MINUTES IN A TIME ZONE
;(SHOULD BE A DIVISOR OF ONE HOUR)
PAGE
SUBTTL INITIALISATION AND COMMAND PARSING
START: RESET ;THE WORLD
MOVE P,[IOWD NPDL,STACK##] ;RESET PUSH DOWN POINTER
MOVX A,<GJ%OLD> ;GET TAKE FILE
HRRI A,[ASCIZ /SYS:/] ;FROM SYS:
SETZM B ;NO DIRECTORY
HRROI C,[ASCIZ /NORCMD/] ;DEFAULT NAME
HRRZI D,[ASCIZ /CMD/] ;AND EXTENSION
PUSHJ P,FNDFIL## ;GET JFN FOR IT
ERROR PARSE,<CANNOT FIND STANDARD "TAKE" FILE>
HRRZ INP,T1 ;SAVE JFN
PUSHJ P,ABSTAK ;ABSORB FILE
ERROR PARSE,<ERROR ABSORBING STANDARD "TAKE" FILE>
MOVX A,<GJ%OFG> ;NO FILE YET
SETZM B ;OUR DIRECTORY
HRROI C,[ASCIZ /OPER20/] ;DEFAULT NAME
HRRZI D,[ASCIZ /LOG/] ;AND EXTENSION
PUSHJ P,FNDFIL## ;GET JFN FOR IT
ERROR PARSE,<BAD NAME FOR DEFAULT LOG FILE>
HRRZM T1,LOGSPC ;SAVE JFN
JRST ENBLAG ;GO START
;HERE TO START A NEW COMMAND.
PARSE: MOVE P,[IOWD NPDL,STACK##] ;RESET PUSH DOWN POINTER
MOVEI OUTP,.PRIOU ;RESET TO OUTPUT TO TTY
PUSHJ P,TSTWHL## ;ARE WE PRIVILEDGED?
SKIPA T1,[-1,,NPVPMT] ;NO
HRROI T1,PRVPMT ;YES
MOVEI T2,CMDTAB ;POINT TO COMMAND TABLE
PUSHJ P,CDSRGS## ;SAVE ARGUMENTS
PUSHJ P,CDSETP## ;SET UP AND INITIALISE
PARSE1: MOVE T2,CMDT2## ;POINT TO TABLE
PUSHJ P,CDGKEY## ;GET COMMAND
JRST PARSE1 ;REPARSE
ERROR PARSE,<NOT A VALID COMMAND>
HRRZ T2,(T2) ;GET DISPATCH
PUSHJ P,(T2) ;GO DO IT
JRST PARSE1 ;REPARSE
JRST PARSE ;DO NEXT
PAGE
SUBTTL COMMAND TABLES ETC.
PRVPMT: ASCIZ /(PRIV) OPER20>/
NPVPMT: ASCIZ /OPER20>/
CMDTAB: CMDSIZ,,CMDMAX
TB (.CONT,CONTINUE)
TB (.DSABL##,DISABLE)
TB (.ENABL##,ENABLE)
TB (.EXIT##,EXIT)
TB (.TAKE,TAKE)
CMDSIZ==.-CMDTAB-1
CMDMAX==CMDSIZ+1
PAGE
SUBTTL EXIT FROM PROGRAM
;ROUTINE CALLED FROM ".EXIT" IN ADMLIB
CLSUP:: SETZM CNTADR ;NOT ALLOWED TO CONTINUE
POPJ P, ;THAT'S ALL
;HERE TO CONTINUE WITH "TAKE" FILE
.CONT: HRROI T2,[ASCIZ /WITH CURRENT "TAKE" FILE/]
PUSHJ P,CRMNOI## ;MAKE NOISE
PUSHJ P,CRGTCM## ;GET CONFIRMATION
PJRST CPOPJ1## ;BAD
SKIPN CNTADR ;INTERCEPTED?
ERROR CPOPJ1##,<JOB WAS NOT IN SUSPENDED STATE>
JRST ENBLAG ;GO CONTINUE
PAGE
SUBTTL TAKE COMMAND
;HERE TO GET FILENAME FOR COMMANDS
.TAKE: HRROI T2,[ASCIZ /COMMANDS FROM FILE/]
PUSHJ P,CRMNOI## ;MAKE NOISE
PUSHJ P,CRIFSP## ;GET SPEC
ERROR CPOPJ1##,<CANNOT FIND FILE>
PUSHJ P,CRGTCM## ;GET CONFIRMATION
PJRST CPOPJ1## ;BAD
HRRZ INP,T2 ;SAVE JFN
PUSHJ P,ABSTAK ;ABSORB TAKE FILE
ERROR CPOPJ1##,<ERROR ABSORBING "TAKE" FILE>
HRROI T1,[ASCIZ /LOG FILE: /]
MOVX A,<GJ%OFG> ;STRING ONLY
SETZM B ;IN OUR DIRECTORY
HRROI C,[ASCIZ /OPER20/]
HRRZI D,[ASCIZ /LOG/] ;DEFAULT FILE
PUSHJ P,CCGTFL## ;GET JFN
HRRZM T2,LOGSPC ;SAVE IT
ENBLAG: PUSHJ P,ENBINT ;ENABLE INTERRUPTS
SETZM PTYJOB ;NO PTY IN USE
JRST LOOP ;DO MAIN LOOP
;HERE TO ABSORB "TAKE" FILE
ABSTAK: PUSHJ P,OPFLIA## ;OPEN FOR INPUT ASCII
POPJ P, ;BAD
HRROI OUTP,TAKSPC ;WRITE IT TO CORE
READLP: PUSHJ P,JBIN## ;READ A CHARACTER
JRST EOFFIL ;EOF
JUMPE T2,READLP ;NO ZEROS
PUSHJ P,JBOUT## ;WRITE IT TO CORE
POPJ P, ;BAD
JRST READLP ;DO ALL
EOFFIL: PUSHJ P,RDRCEF## ;EOF?
POPJ P, ;BAD
SETZM T2 ;MAKE ASCIZ
IDPB T2,OUTP ;SAVE IT
PUSHJ P,CIFLLJ## ;CLOSE UP
JFCL ;NO ERRORS
SETOM ZONE ;FLAG NO PASS YET
PJRST CPOPJ1## ;OK
PAGE
;THE MAIN LOOP
LOOP: SETOM T2 ;GET TIME AND DATE
SETZM T4 ;NOTHING SPECIAL
ODCNV ;GET IT
HLRZM T2,YEAR ;SAVE YEAR
HRRZM T2,MONTH ;SAVE MONTH
HLRZM T3,DAY ;SAVE DAY
HRRZM T3,WEEKDY ;AND DAY OF WEEK
HRRZS T4 ;GET TIME IN SECONDS SINCE MIDNIGHT
IDIVI T4,^D60 ;GET MINUTES SINCE MIDNIGHT
IDIVI T4,^D60 ;GET HOURS AND MINUTES
MOVEM T4,HOURS ;SAVE HOURS
MOVEM T5,MINUTS ;AND MINUTES
IDIVI T5,ZONDIV ;WHICH QUARTER ARE WE?
SKIPL ZONE ;JUST STARTED?
CAMN T5,ZONE ;WHAT WE WANT TO BE?
SKIPA ;YES
JRST NOPASS ;NO
MOVEM T5,ZONE ;SAVE ZONE
SETOB D,PNT ;FIRST LEVEL AND WE WANT TO CONTINUE
HRROI INP,TAKSPC ;POINT TO IN-CORE FILE
LOOP1: PUSHJ P,JBIN## ;GET A CHARACTER
ERROR GIVEUP,<ERROR IN "TAKE" FILE>
JUMPE T2,LOOP2 ;FOUND END
CAIE T2,"%" ;START OF COMMAND?
JRST LOOP1 ;LOOK
PUSHJ P,OBEYCM ;OBEY COMMANDS
ERROR GIVEUP,<ABORTING "TAKE" FILE>
GIVEUP: TDZA PNT,PNT ;EXIT
JRST LOOP1 ;GET NEXT
LOOP2: SKIPN PTYJOB ;WE HAVE A PTY?
JRST LOOP3 ;NO
PUSHJ P,DOCPTG ;EXHAUST AND LOG CHARACTERS
JRST .-1 ;DO ALL
MOVE INP,PTYJFN ;GET PTY JFNS
MOVE OUTP,PTYJFN ;BOTH OF THEM
PUSHJ P,LOGOUT ;LOGOUT
SETZM PTYJOB ;NO MORE JOB
HRRZ OUTP,LOGJFN ;GET LOG JFN
PUSHJ P,COFLDJ## ;CLOSE IT
ERROR .+1,<ERROR CLOSING LOG FILE>
LOOP3: JUMPE PNT,LOOPE ;FINISH UP
AOS T1,ZONE ;INCREMENT ZONE
ANDI T1,3 ;ADJUST
MOVEM T1,ZONE ;RESAVE IT
NOPASS: MOVE T1,[EXP WAKUPT] ;HOW LONG TO SLEEP
DISMS ;SLEEP
JRST LOOP ;DO ANOTHER LOOP
LOOPE: HALTF ;THATS IT
PAGE
SUBTTL OBEY COMMANDS FROM FILE
OBEYCM: AOS D ;UP ONE LEVEL
SETZM OBEYIT(D) ;ASSUME WE DON'T WANT IT
MOVEM INP,LSTCOM ;SAVE BYTE POINTER
MOVEI T2,OBYTAB ;TABLE OF COMMANDS
PUSHJ P,OBYCMD ;INTERPRET COMMAND AND SET "OBEYIT"
JRST OBYERR ;BAD
ERROR OBCEXT,<"EXIT" COMMAND ENCOUNTERED>
PJRST OBEYDN ;NO SUBCOMMAND
PUSHJ P,OBYBRC ;DECODE STUFF INSIDE BRACKETS
PJRST OBYERR ;ERROR
PJRST OBCEXT ;EXIT
OBEYDN: SOS D ;DOWN A LEVEL
PJRST OBCOK ;FINISHED
;HERE ON ERROR
OBYERR:SKIPE D ;NOT AT FIRST LEVEL?
JRST OBYERE ;THAN DON'T GET NOISY
HRROI T1,[ASCIZ /
?ERROR DURING COMMAND INTERPRETATION.
ERROR OCCURRED AROUND ---
/]
PSOUT ;TELL HIM
MOVE T1,LSTCOM ;POINT TO IT
PSOUT
OBYERE: SOS D ;COUNT DOWN LEVEL
POPJ P, ;OK
;RETURNS
OBCBRC: AOS (P) ;RETURN WHEN BRACKETS FOLLOW
OBCOK: AOS (P) ;RETURN WHEN NO BRACKETS
OBCEXT: AOS (P) ;RETURN TO EXIT
OBCERR: POPJ P, ;ERROR RETURN
PAGE
;TABLE OF COMMANDS
OBYTAB: OBYSIZ,,OBYMAX
TB (.ALWYS,ALWAYS)
TB (.CLEAR,CLEAR)
TB (.CREAT,CREATE)
TB (.DATE,DATE)
TB (.DELET,DELETE)
TB (.EVERY,EVERYDAY)
TB (OBCEXT,EXIT)
TB (.FRIDY,FRIDAYS)
TB (.IFFCM,IF)
TB (.IFFNS,IF-NOT)
TB (.IFTES,IF-THEN-ELSE)
TB (.MONDY,MONDAYS)
TB (.SATDY,SATURDAYS)
TB (.SETFL,SET)
TB (.SUNDY,SUNDAYS)
TB (.THUDY,THURSDAYS)
TB (.TUEDY,TUESDAYS)
TB (.WEDDY,WEDNESDAYS)
TB (.WEEDY,WEEKDAYS)
OBYSIZ==.-OBYTAB-1
OBYMAX==OBYSIZ+1
PAGE
SUBTTL COMMANDS
;WEEKDAYS
.WEEDY: MOVE T1,WEEKDY ;GET DAY OF THE WEEK
CAIGE T1,5 ;WEEKDAY?
JRST .EVERY ;YES
JRST TIMGET ;NO
;MONDAYS
.MONDY: MOVEI T1,0 ;VALUE
JRST DAYCHK ;CHECK IT
;TUESDAYS
.TUEDY: MOVEI T1,1 ;VALUE
JRST DAYCHK ;CHECK IT
;WEDNESDAYS
.WEDDY: MOVEI T1,2 ;VALUE
JRST DAYCHK ;CHECK IT
;THURSDAYS
.THUDY: MOVEI T1,3 ;VALUE
JRST DAYCHK ;CHECK IT
;FRIDAYS
.FRIDY: MOVEI T1,4 ;VALUE
JRST DAYCHK ;CHECK IT
;SATURDAYS
.SATDY: MOVEI T1,5 ;VALUE
JRST DAYCHK ;CHECK IT
;SUNDAYS
.SUNDY: MOVEI T1,6 ;VALUE
DAYCHK: CAMN T1,WEEKDY ;MATCH TODAY?
.EVERY: SETOM OBEYIT(D) ;YES--CONSIDER THIS COMMAND
JRST TIMGET ;GO GET THE TIME
PAGE
;HERE TO GET TIME RANGES
TIMGET: MOVEI T2,RNGTAB ;GET TABLE OF KEYWORDS
PJRST OBYCMD ;OBEY KEY WORD
;TABLE OF KEYWORDS FOR TIME RANGES
RNGTAB: RNGSIZ,,RNGMAX
TB (.RNGAF,AFTER)
TB (.RNGAT,AT)
TB (.RNGBF,BEFORE)
TB (.RNGBT,BETWEEN)
RNGSIZ==.-RNGTAB-1
RNGMAX==RNGSIZ+1
;HERE FOR BETWEEN
.RNGBT: PUSHJ P,.RNGAF ;AFTER FIRST
PJRST OBCERR ;ERROR
PJRST OBCEXT ;SHOULD NOT GET HERE
PJRST OBCOK ;OR HERE
PJRST .RNGBF ;AND BEFORE
;HERE FOR PRECISE TIME
.RNGAT: PUSHJ P,GETTIM ;GET TIME
ERROR OBCERR,<ERROR IN TIME>
IDIVI T4,^D60 ;GET HOURS
MOVEM T4,COMHRS ;SAVE HOURS
MOVEM T5,COMMTS ;AND MINUTES
CAME T4,HOURS ;MATCH?
JRST NOMTCH ;NO
MOVE T1,COMMTS ;GET MINUTES
IDIVI T1,ZONDIV ;IN OUR TIME ZONE?
CAME T1,ZONE ;WELL?
NOMTCH: SETZM OBEYIT(D) ;NO
PJRST OBCBRC ;GO OBEY BRACKETS
PAGE
;HERE FOR BEFORE
.RNGBF: PUSHJ P,GETTIM ;GET TIME
ERROR OBCERR,<ERROR IN "BEFORE" TIME SPECIFICATION>
CAMLE A,T4 ;BEFORE?
SETZM OBEYIT(D) ;NO
PJRST OBCBRC ;GO OBEY BRACKETS
;HERE FOR AFTER
.RNGAF: PUSHJ P,GETTIM ;GET TIME
ERROR OBCERR,<ERROR IN "AFTER" TIME SPECIFICATION>
CAMGE A,T4 ;AFTER?
SETZM OBEYIT(D) ;NO
PJRST OBCBRC ;OK
;ROUTINE TO GET A TIME FROM A COMMAND AND RETURN THE
;TIME AS THE NUMBER OF MINUTES PAST MIDNIGHT IN T4. ALSO
;RETURN THE SAME FOR THE CURRENT TIME.
GETTIM: MOVX T2,<IT%NDA> ;TIME ONLY
MOVE T1,INP ;GET POINTER
IDTNC ;GET IT
POPJ P, ;BAD
MOVE INP,T1 ;GET POINTER BACK
HRRZS T4 ;GET JUST TIME
IDIVI T4,^D60 ;MAKE MINUTES
MOVE A,HOURS ;GET CURRENT TIME
IMULI A,^D60 ;GET MINUTES
ADD A,MINUTS ;ADD IN EXCESS
PJRST CPOPJ1## ;OK
PAGE
;HERE FOR "DATE" COMMAND
.DATE: MOVX T2,<IT%NTI> ;NO TIME NOW
MOVE T1,INP ;WHERE TO GET IT
IDTNC ;GET IT
ERROR OBCERR,<BAD DATE ENCOUNTERED DURING "DATE" COMMAND>
MOVE INP,T1 ;SAVE BYTE POINTER
HLRZM T2,COMYER ;SAVE YEAR
HRRZM T2,COMMON ;AND MONTH
HLRZM T3,COMDAY ;SAVE DAY
HRRZM T3,COMWKD ;AND DAY OF THE WEEK
SETOM OBEYIT(D) ;ASSUME WE ARE CORRECT
MOVE T1,COMYER ;GET YEAR
CAME T1,YEAR ;SAME AS US?
JRST NOTDAT ;NO
MOVE T1,COMMON ;GET MONTH
CAME T1,MONTH ;SAME AS US?
JRST NOTDAT ;NO
MOVE T1,COMDAY ;GET DAY
CAME T1,DAY ;SAME AS US?
NOTDAT: SETZM OBEYIT(D) ;NO
PJRST TIMGET ;GET TIME
;"ALWAYS" COMMAND
.ALWYS: SETOM OBEYIT(D) ;ALWAYS IS ALWAYS
PJRST OBCBRC ;ALWAYS GOOD!!
PAGE
;HERE TO CREATE A FILE (DISK FLAG)
.CREAT: MOVX T1,<GJ%FOU> ;NEW FILE
MOVE T2,INP ;POINT TO FILESPEC
GTJFN ;GET A JFN FOR IT
JRST CREFL1 ;COULD NOT
MOVE INP,T2 ;RESAVE POINTER
PUSH P,OUTP ;SAVE OUTPUT JFN
HRRZ OUTP,T1 ;SAVE IT
PUSHJ P,OPFLOA## ;OPEN IT FOR OUTPUT
JRST CREFL2 ;COULD NOT
PUSHJ P,COFLLJ## ;CLOSE IT UP
JRST CREFL2 ;COULD NOT
POP P,OUTP ;RESTORE OUTPUT JFN
PJRST OBCOK ;DONE
;HERE ON ERRORS
CREFL1: SKIPA INP,T2 ;RESTORE BYTE POINTER
CREFL2: POP P,OUTP ;RESTORE OUTPUT JFN
ERROR OBCERR,<UNABLE TO CREATE DISK FLAG FILE>
;HERE TO DELETE A FILE (DISK FLAG)
.DELET: MOVX T1,<GJ%OLD> ;MUST EXIT
MOVE T2,INP ;POINT TO SPEC
GTJFN ;GET JFN FOR IT
JRST DELFL1 ;COULD NOT
MOVE INP,T2 ;RESAVE POINTER
HRLI T1,(DF%EXP) ;EXPUNGE IT
DELF ;DO IT
PJRST DELFL2 ;COULD NOT
PJRST OBCOK ;OK
;HERE ON ERRORS
DELFL1: MOVE INP,T2 ;RESTORE POINTER
DELFL2: ERROR OBCERR,<UNABLE TO DELETE DISK FLAG FILE>
PAGE
;HERE TO CLEAR FLAGS
.CLEAR: MOVEI T2,CLRTAB ;POINT TO TABLE
PJRST OBYCMD ;OBEY IT
;TABLE OF "CLEAR" SUBCOMMANDS
CLRTAB: CLRSIZ,,CLRMAX
TB (.CLFL1,FLAG1)
TB (.CLFL2,FLAG2)
TB (.CLFL3,FLAG3)
TB (.CLFL4,FLAG4)
TB (.CLFL5,FLAG5)
TB (.CLFL6,FLAG6)
TB (.CLFL7,FLAG7)
TB (.CLFL8,FLAG8)
TB (.CLFLS,FLAGS)
CLRSIZ==.-CLRTAB-1
CLRMAX==CLRSIZ+1
.CLFL1: SETZM FLAG1 ;CLEAR FLAG1
PJRST OBCOK ;OK
.CLFL2: SETZM FLAG2 ;CLEAR FLAG2
PJRST OBCOK ;OK
.CLFL3: SETZM FLAG3 ;CLEAR FLAG3
PJRST OBCOK ;OK
.CLFL4: SETZM FLAG4 ;CLEAR FLAG4
PJRST OBCOK ;OK
.CLFL5: SETZM FLAG5 ;CLEAR FLAG5
PJRST OBCOK ;OK
.CLFL6: SETZM FLAG6 ;CLEAR FLAG6
PJRST OBCOK ;OK
.CLFL7: SETZM FLAG7 ;CLEAR FLAG7
PJRST OBCOK ;OK
.CLFL8: SETZM FLAG8 ;CLEAR FLAG8
PJRST OBCOK ;OK
.CLFLS: MOVEI T1,FLAG1 ;CLEAR ALL FLAGS
MOVEI T2,FLAG8 ;DO ALL
PUSHJ P,BLTCLR## ;DO IT
PJRST OBCOK ;OK
PAGE
;HERE TO SET FLAGS
.SETFL: MOVEI T2,SETTAB ;POINT TO TABLE
PJRST OBYCMD ;DO IT
;TABLE OF "SET" SUBCOMMANDS
SETTAB: SETSIZ,,SETMAX
TB (.STFL1,FLAG1)
TB (.STFL2,FLAG2)
TB (.STFL3,FLAG3)
TB (.STFL4,FLAG4)
TB (.STFL5,FLAG5)
TB (.STFL6,FLAG6)
TB (.STFL7,FLAG7)
TB (.STFL8,FLAG8)
TB (.STFLS,FLAGS)
SETSIZ==.-SETTAB-1
SETMAX==SETSIZ+1
.STFL1: SETOM FLAG1 ;SET FLAG1
PJRST OBCOK ;OK
.STFL2: SETOM FLAG2 ;SET FLAG2
PJRST OBCOK ;OK
.STFL3: SETOM FLAG3 ;SET FLAG3
PJRST OBCOK ;OK
.STFL4: SETOM FLAG4 ;SET FLAG4
PJRST OBCOK ;OK
.STFL5: SETOM FLAG5 ;SET FLAG5
PJRST OBCOK ;OK
.STFL6: SETOM FLAG6 ;SET FLAG6
PJRST OBCOK ;OK
.STFL7: SETOM FLAG7 ;SET FLAG7
PJRST OBCOK ;OK
.STFL8: SETOM FLAG8 ;SET FLAG8
PJRST OBCOK ;OK
.STFLS: MOVEI T1,FLAG1 ;SET ALL FLAGS
MOVEI T2,FLAG8 ;DO ALL
PUSHJ P,BLTONE## ;DO IT
PJRST OBCOK ;OK
PAGE
;"IF" COMMAND
.IFFCM: MOVEI T2,IFFTAB ;AVAILABLE COMMANDS
PJRST OBYCMD ;OBEY IT
;"IF-THEN-ELSE" COMMAND
.IFTES: MOVEI T2,IFFTAB ;AVAILABLE COMMANDS
PUSHJ P,OBYCMD ;OBEY IT
PJRST OBCERR ;ERROR
PJRST OBCEXT ;SHOULD NOT GET HERE
PJRST OBCOK ;OR HERE!!
PUSHJ P,OBYBRC ;OBEY FIRST SET OF BRACKETS
PJRST OBCERR ;ERROR
PJRST OBCEXT ;EXIT
SETCMM OBEYIT(D) ;COMPLEMENT FLAG
PJRST OBCBRC ;GO DO NEXT SET OF BRACKETS
;"IF-NOT" COMMAND
.IFFNS: MOVEI T2,IFFTAB ;POINT TO TABLE
PUSHJ P,OBYCMD ;SET "OBEYIT"
PJRST OBCERR ;ERROR
PJRST OBCEXT ;SHOULD NOT GET HERE
PJRST OBCOK ;OR HERE!!
SETCMM OBEYIT(D) ;COMPLEMENT FLAG
PJRST OBCBRC ;OBEY BRACKETS
;TABLE OF "IF" SUBCOMMANDS
IFFTAB: IFFSIZ,,IFFMAX
TB (.IFFIL,FILE)
TB (.IFFL1,FLAG1)
TB (.IFFL2,FLAG2)
TB (.IFFL3,FLAG3)
TB (.IFFL4,FLAG4)
TB (.IFFL5,FLAG5)
TB (.IFFL6,FLAG6)
TB (.IFFL7,FLAG7)
TB (.IFFL8,FLAG8)
TB (.IFSTR,STRUCTURE)
IFFSIZ==.-IFFTAB-1
IFFMAX==IFFSIZ+1
PAGE
;HERE FOR "IF STRUCTURE (MOUNTED)"
.IFSTR: MOVE T1,INP ;GET BYTE POINTER
STDEV ;GET STRING
TDZA T2,T2 ;DOES NOT EXIST
SETOM T2 ;EXISTS
MOVEM T2,OBEYIT(D) ;SAVE RESULT OF TEST
MOVE INP,T1 ;SAVE BYTE POINTER
PJRST OBCBRC ;BRACKETS FOLLOW
;HERE FOR "IF FILE (EXISTS)"
.IFFIL: MOVX T1,<GJ%OLD> ;MUST EXIST
MOVE T2,INP ;GET BYTE POINTER
GTJFN ;FIND IT
TDZA T3,T3 ;DOES NOT EXITS
SETOM T3 ;EXISTS
MOVEM T3,OBEYIT(D) ;SET FLAG
MOVE INP,T2 ;RESET BYTE POINTER
RLJFN ;RELEASE JFN
JFCL ;NO ERRORS
PJRST OBCBRC ;LOOK FOR BRACKETS
;HERE FOR "IF FLAGX"
.IFFL1: SKIPA T1,FLAG1 ;GET STATUS OF FLAG1
.IFFL2: MOVE T1,FLAG2 ;GET STATUS OF FLAG2
PJRST .IFFLS ;SET IT
.IFFL3: SKIPA T1,FLAG3 ;GET STATUS OF FLAG3
.IFFL4: MOVE T1,FLAG4 ;GET STATUS OF FLAG4
PJRST .IFFLS ;SET IT
.IFFL5: SKIPA T1,FLAG5 ;GET STATUS OF FLAG5
.IFFL6: MOVE T1,FLAG6 ;GET STATUS OF FLAG6
PJRST .IFFLS ;SET IT
.IFFL7: SKIPA T1,FLAG7 ;GET STATUS OF FLAG7
.IFFL8: MOVE T1,FLAG8 ;GET STATUS OF FLAG8
.IFFLS: MOVEM T1,OBEYIT(D) ;SET "OBEYIT"
PJRST OBCBRC ;OBEY BRACKETS
PAGE
;ROUTINE TO INTERPRET COMMANDS. ENTER WITH T2 POINTING TO
;TABLE OF LEGAL COMMANDS. RETURN +1 ON ERROR, SKIP IF OK.
OBYCMD: PUSH P,OUTP ;SAVE OUTPUT JFN
PUSH P,T2 ;SAVE ADDRESS OF COMMAND TABLE
HRROI OUTP,ATTOM ;WHERE TO BUILD COMMAND
OBYCM1: PUSHJ P,JBIN## ;GET CHARACTER
PJRST OBYCM4 ;SHOULD NOT GET HERE
CAIL T2,"a" ;LOWER CASE?
CAILE T2,"z" ;ANY OF THEM?
SKIPA ;NO
SUBI T2,40 ;MAKE UPPER CASE
CAIL T2,"A" ;LETTER?
CAILE T2,"Z" ;ANY OF THEM?
CAIN T2,"-" ;HYPHEN?
JRST OBYCM2 ;OK
CAIL T2,"0" ;NUMERIC?
CAILE T2,"9" ;ANY OF THEM?
JRST OBYCM3 ;NO
OBYCM2: PUSHJ P,JBOUT## ;OK--USE IT
PJRST OBYCM4 ;SHOULD NOT COME HERE
JRST OBYCM1 ;LOOP UP
;HERE AT END OF COMMAND
OBYCM3: SETZB T2,LEVBRC(D) ;MAKE ASCIZ, AND NO BRACKETS SEEN YET
PUSHJ P,JBOUT ;WRITE IT
PJRST OBYCM4 ;BAD
POP P,T1 ;POINT TO TABLE
POP P,OUTP ;RESTORE OUTPUT JFN
HRROI T2,ATTOM ;POINT TO COMMAND
TBLUK ;FIND IT
TXNN T2,<TL%ABR+TL%EXM> ;WELL?
PJRST OBYCM5 ;NO
HRRZ T1,(T1) ;GET DISPATCH
PUSHJ P,(T1) ;OBEY COMMAND
PJRST OBYCM5 ;BAD
PJRST OBCEXT ;EXIT
PJRST OBCOK ;NO BRACKETS FOLLOWING
PUSHJ P,JBKJFN## ;BACKUP BYTE POINTER
JFCL ;PRESS ON
LOOKBC: PUSHJ P,JBIN## ;GET A CHARACTER
PJRST OBYCM5 ;BAD
JUMPE T2,OBYCM5 ;BAD
CAIE T2,"<" ;FOUND OPEN BRACKET?
JRST LOOKBC ;NO
PJRST OBCBRC ;DECODE COMMANDS
;HERE ON ERROR
OBYCM4: POP P,T2 ;TABLE ADDRESS
POP P,OUTP ;OUTPUT JFN
OBYCM5: ERROR OBCERR,<ILLEGAL FORMAT IN COMMAND ARGUMENT>
PAGE
;HERE TO DO COMMAND IF "OBEYIT" NON-ZERO
;OTHERWISE, SKIP OVER COMMAND.
DOCLP1: TDZA BUF,BUF ;NOT LINE FEED
OBYBRC: SETOM BUF ;LINE FEED
SKIPE PTYJOB ;DO WE HAVE A JOB?
SKIPN OBEYIT(D) ;ARE WE OBEYING COMMAND?
JRST DOCLP4 ;NO
DOCLP3: MOVE T1,PTYJFN ;FOR PTY
MOVX T2,<.MOPIH> ;NEED INPUT?
MTOPR ;TEST
JUMPN T2,DOCLP4 ;YES
PUSHJ P,DOCPTG ;GET CHARACTER FROM PTY
JRST .-1 ;DO ALL
JRST DOCLP3 ;TEST AGAIN
DOCLP4: ILDB T2,INP ;GET CHARACTER
JUMPE T2,OBCERR ;END OF FILE
CAIN T2,12 ;LINE FEED?
JRST OBYBRC ;YES--FLAG AND IGNORE IT
CAIN T2,"<" ;OPEN BRACKET?
AOS LEVBRC(D) ;COUNT BRAKETS
CAIE T2,">" ;CLOSED BRACKET?
JRST DOCLP5 ;NO
SOSGE LEVBRC(D) ;DECREMENT COUNT OF BRACKETS
PJRST [SETOM BUF ;PRETEND BEGINNING OF LINE
PJRST OBCOK] ;FINISHED
DOCLP5: SKIPN OBEYIT(D) ;OBEY IT?
JRST DOCLP1 ;NO
CAIN T2,"%" ;SUBCOMMAND?
JUMPL BUF,NSTCOM ;SUBCOMMAND
CAIN T2,"^" ;UP ARROW?
PUSHJ P,UPAROW ;YES
MOVE OUTP,PTYJFN ;GET JFN
SKIPE PTYJOB ;WE HAVE A JOB?
JRST DOCLP6 ;YES
PUSHJ P,NEWJOB ;GET ONE
PJRST OBCERR
DOCLP6: PUSHJ P,JBOUT## ;SEND CHARACTER TO PTY
ERROR OBCERR,<UNABLE TO SEND TO PTY>
JRST DOCLP1 ;CHECK NEXT
;HERE IF WE FIND AN UP ARROW
UPAROW: ILDB T2,INP ;GET NEXT CHARACTER
CAIE T2,"^" ;ANOTHER ONE?
ANDI T2,37 ;SEND CONTROL CHARACTER
POPJ P, ;THAT'S ALL
PAGE
;HERE TO LOGIN A NEW JOB. PRESERVE T2.
NEWJOB: PUSH P,T2 ;SAVE CHARACTER IN T2
PUSHJ P,OPNLOG ;OPEN LOG FILE
ERROR CPOPJ##,<UNABLE TO OPEN LOG FILE>
PUSH P,INP ;SAVE BYTE POINTER
SETZM PTYECH ;ECHO NOTHING
PUSHJ P,LOGGIN ;LOGIN A JOB
ERROR NEWJER,<UNABLE TO LOGIN A JOB>
MOVEM OUTP,PTYJFN ;SAVE PTY JFN
SETOM PTYJOB ;WE HAVE A JOB
HRROI T2,[ASCIZ /
;********** NEW LOGIN SESSION **********
SYSTAT DIRECTORY .
/]
PUSHJ P,STGOUT## ;START OFF
AOS -2(P) ;OK
NEWJER: POP P,INP ;RESTORE INPUT JFN
PJRST T2POPJ## ;AND CHARACTER
;HERE FOR NESTED COMMANDS
NSTCOM: PUSHJ P,OBEYCM ;OBEY IT
PJRST OBCERR ;ERROR
PJRST OBCEXT ;EXIT
JRST OBYBRC ;CONTINUE
;ROUTINE TO GET AND LOG A CHARACTER FROM THE PTY
DOCPTG: PUSH P,INP ;SAVE INPUT JFN
MOVE INP,PTYJFN ;GET PTY JFN
PUSHJ P,PTICHR ;GET A CHARACTER FROM THE PTY
JUMPE T2,DOCPT1 ;NONE THERE
PUSH P,OUTP ;SAVE JFN
MOVE OUTP,LOGJFN ;GET LOG JFN
CAIN T2,12 ;LINE FEED?
PUSHJ P,STAMP ;DATE STAMP
PUSHJ P,CHROUT## ;TYPE IT
POP P,OUTP ;RESTORE JFN
POP P,INP ;AND INPUT JFN
POPJ P, ;WE DID SOMETHING
DOCPT1: POP P,INP ;RESTORE INPUT JFN
PJRST CPOPJ1## ;NOTHING THERE
;HERE TO DATE STAMP LOG
STAMP: PUSHJ P,CHROUT## ;PRINT LINE FEED
PUSHJ P,DATMOT## ;PRINT DATE AND TIME
MOVEI T2," " ;TAB
POPJ P, ;PRINT IT
PAGE
;HERE TO OPEN LOG FILE
OPNLOG: MOVE T2,LOGSPC ;GET JFN SPEC
HRROI T1,SPARE ;WHERE TO WRITE IT
SETZM T3 ;FULL SPEC
JFNS ;GET IT
MOVX T1,<GJ%SHT> ;SHORT FORM
HRROI T2,SPARE ;POINT TO SPEC
GTJFN ;GET JFN FOR IT
POPJ P, ;CANNOT
HRRZM T1,LOGJFN ;SAVE JFN
MOVE OUTP,LOGJFN ;GET JFN
PJRST OPFLOA## ;OPEN IT
PAGE
SUBTTL INTERRUPT HANDLING
;ENABLE INTERRUPT FOR TTY INPUT.
ENBINT: MOVEI T1,400000 ;FOR US
EIR ;ENABLE INTERRUPTS
MOVE T2,[LEVTAB,,CHNTAB]
MOVEI T1,400000 ;INITIALISE FOR US
SIR
CIS ;CLEAR INTERRUPTS
MOVE T1,[.TICTI,,0] ;INPUT ON CHANNEL 0
ATI ;ASSOCIATE IT
MOVEI T1,400000 ;FOR US
MOVSI T2,400000 ;ACTIVATE CHANNEL 0
AIC ;DO IT
POPJ P, ;OK
;DISABLE TTY INPUT INTERRUPT
DISIN1: AOS (P) ;GIVE SKIP RETURN
DISINT: MOVEI T1,400000 ;FOR US
MOVSI T2,400000 ;TURN OFF CHANNEL
DIC ;DO IT
POPJ P, ;OK
;INTERRUPT TABLES
LEVTAB: PCSAV1
CHNTAB: 1,,INPTTY ;TTY INPUT
;HERE ON TTY INPUT
INPTTY: MOVEI T1,PARSE ;WHERE TO GO
MOVEM T1,PCSAV1 ;CLOBBER PC
SETOM CNTADR ;WE ARE SUSPENDED
PUSHJ P,DISINT ;TURN OFF
DEBRK ;DISMISS
PAGE
SUBTTL PTY ROUTINES
;ROUTINE TO GET A PTY
PTYOPN: PUSHJ P,TBPPAR## ;GET PTY PARAMETERS
HRRZM T1,OUTP ;SAVE FIRST ONE
HLLZM T1,T4 ;GET NUMBER OF PTYS
MOVNS T4 ;MAKE A POINTER
GETPA: MOVSI T1,600013 ;PTY DESIGNATOR
HRRI T1,(T4) ;GET NEXT ONE
DVCHR ;GET CHARACTERISTICS
TXNN T2,DV%AV ;AVAILABLE?
JRST GETPB ;NO
MOVE T2,T1 ;GET DESIGNATOR IN AC1
HRROI T1,PTYNAM ;GET STRING
DEVST ;GET STATUS
JRST GETPB
MOVEI T2,":" ;GET A COLON
IDPB T2,T1 ;AT THE END
MOVEI T2,0
IDPB T2,T1 ;ASCIZ
MOVX T1,GJ%SHT!GJ%ACC
HRROI T2,PTYNAM ;STRING
GTJFN
JRST GETPB ;CANNOT USE IT
PUSH P,T1 ;SAVE JFN
MOVE T2,[7B5!1B19!1B20!1B29]
OPENF
JRST GETPC ;FAILED
POP P,INP ;GET JFN BACK
ADD T4,OUTP
TRO T4,(1B0)
HRRZM T4,PTYNUM ;SAVE DESIGNATOR NUMBER
HRRZS INP ;JUST JFN
HRRZ OUTP,INP ;FOR INPUT AND OUTPUT
JRST CPOPJ1
GETPC: POP P,T1
RLJFN ;RELEASE JFN
JFCL
GETPB: AOBJN T4,GETPA ;LOOP UP
POPJ P, ;FAILED
PAGE
;ROUTINE TO GET CHAR FROM THE PTY. ECHO TO TTY IF
;PTYECH NON-ZERO.
PTISLP: MOVEI T1,^D100 ;SLEEP FOR 100 MS
DISMS ;DO IT
PTICHR: MOVE T1,PTYNUM ;GET PTY
SOBE ;ANYTHING THERE?
JRST PTIBYT ;YES--GET IT
MOVE T1,OUTP ;CHECK PTY
MOVEI T2,.MOPIH ;DOES IT NEED INPUT?
SETZM T3
MTOPR ;CHECK
TDZN T2,[777777,,777777] ;WELL?
JRST PTISLP ;TRY AGAIN
MOVE T1,PTYNUM ;HAVE ONE FINAL LOOK
SOBE ;ANYTHING THERE?
JRST PTIBYT ;YES
POPJ P, ;MUST BE DRY
PTIBYT: MOVE T1,INP ;GET JFN
BIN
JFCL
PUSH P,T2 ;SAVE CHAR
MOVE T1,T2
SKIPE PTYECH
PBOUT ;SEND IT
JFCL
POP P,T2 ;RESTORE CHAR
ANDI T2,177 ;STRIP HIGH BIT
CAIE T2,15 ;CARRIAGE RETURN?
CAIN T2,177 ;OR RUBBOUT?
JRST PTICHR ;IGNORE
POPJ P,
PAGE
;ROUTINE TO WAIT FOR A PROMPT CHAR FROM PTY
PMPTWT: HRROI T1,[ASCIZ /?/] ;ERROR STATE
HRROI T2,[ASCIZ /@/] ;UNPRIVILEDGED
HRROI T3,[ASCIZ /$/] ;PRIVILEDGED
PUSHJ P,PTYLKK ;FIND THEM
POPJ P,
JRST CPOPJ1
AOS (P)
JRST CPOPJ1
;ROUTINES TO SEND ALTMODE OR ^C TO PTY
PTOALT: MOVEI T2,175 ;CHAR TO SEND
JRST CHROUT## ;SEND IT
PTOCNC: MOVEI T2,3 ;SEND ^C
JRST CHROUT##
PAGE
;ROUTINE TO LOOK AT PTY AND MATCH OUTPUT WITH 3 STRINGS
PTYLKK: SKIPE T1 ;T1 VALID?
HRLI T1,440700 ;MAKE A BP
MOVEM T1,MTCHTB ;SAVE IT
SKIPE T2 ;T2 VALID
HRLI T2,440700 ;MAKE A BP
MOVEM T2,MTCHTB+1 ;SAVE IT
SKIPE T3 ;T3 VALID
HRLI T3,440700 ;MAKE A BP
MOVEM T3,MTCHTB+2 ;SAVE IT
PTYLK2: MOVE T1,[MTCHTB,,MTCHT1] ;COPY TABLE
BLT T1,MTCHT1+2 ;DO IT
PTYLK1: PUSHJ P,PTICHR ;GET CHAR
CAIN T2,12 ;LINE FEED?
JRST PTYLK2 ;YES--RESET
MOVE P1,[-3,,0] ;MAKE POINTER
PTYLK3: SKIPN MTCHT1(P1) ;ENTRY VALID?
JRST NTVAL ;NO
ILDB T1,MTCHT1(P1) ;GET A CHAR
JUMPE T1,MTCH ;FOUND END
CAME T1,T2 ;MATCH CHARACTERS?
SETZM MTCHT1(P1) ;NO--NO LONGER VALID
NTVAL: AOBJN P1,PTYLK3 ;LOOP UP
JUMPE T2,CPOPJ## ;ZERO MEANS NO MORE
JRST PTYLK1 ;GET NEXT CHAR
MTCH: HRRZS P1 ;GET INDEX
ADDM P1,(P) ;ADJUST POINTER
JUMPE T2,CPOPJ## ;IF ZERO --RETURN
PTYLK4: PUSHJ P,PTICHR ;ELSE DRAIN PTY
JUMPN T2,PTYLK4 ;KEEP ON
POPJ P,
PAGE
;ROUTINE TO LOGIN A JOB ON THE PTY
LOGGIN: PUSHJ P,PTYOPN ;GET A PTY
POPJ P, ;CANNOT
PUSHJ P,PTOCNC ;SEND IT
MOVEI T1,^D5000 ;WAIT A WHILE
DISMS ;FOR MONITOR TO CATCH UP
PUSHJ P,PMPTWT ;WAIT FOR PROMPT
POPJ P, ;BAD
JFCL
HRROI T2,[ASCIZ /LOG/]
PUSHJ P,STGOUT## ;SEND IT
PUSHJ P,PTOALT ;SEND ALTMODE
GJINF ;GET OUR DIRECTORY NUMBER
MOVE T2,T1 ;COPY IT
MOVE T1,OUTP ;SEND IT TO THE PTY
DIRST
JFCL
HRROI T2,[ASCIZ / FOO F-S/]
PUSHJ P,STGOUT## ;FINISH OFF
PUSHJ P,CROUT## ;SEND CR
PUSHJ P,PMPTWT ;GET PROMPT BACK
POPJ P, ;NOT THERE
JFCL
HRROI T2,[ASCIZ /CONNECT /]
PUSHJ P,STGOUT## ;CONNECT TO DIRECTORY
GJINF ;GET JOB INFO
HRRZ T1,OUTP ;GET JFN
DIRST ;SEND IT
POPJ P, ;COULD NOT
PUSHJ P,CROUT## ;SEND CR
PUSHJ P,PMPTWT ;WAIT FOR PROMPT
POPJ P, ;COULD NOT
JFCL ;OK
JRST CPOPJ1 ;LOGGED IN
PAGE
;ROUTINE TO LOG JOB OFF
LOGOUT: PUSHJ P,PTOCNC
PUSHJ P,PMPTWT ;WAIT FOR PROMPT
JFCL
JFCL
HRROI T2,[ASCIZ /LOGOUT/]
PUSHJ P,STGOUT## ;SEND IT
PUSHJ P,CROUT##
SETZB T1,T3 ;WAIT FOR MESSAGE
HRROI T2,[ASCIZ / U/]
PUSHJ P,PTYLKK ;WAIT FOR IT
JFCL
JFCL
MOVE T1,INP ;GET JFN
CLOSF ;RELEASE PTY
JFCL
POPJ P,
PAGE
SUBTTL STOREAGE
;LOCAL STOREAGE
YEAR: BLOCK 1 ;CURRENT YEAR
MONTH: BLOCK 1 ;CURRENT MONTH
DAY: BLOCK 1 ;CURRENT DAY
WEEKDY: BLOCK 1 ;DAY OF THE WEEK
HOURS: BLOCK 1 ;HOURS SINCE MIDNIGHT
MINUTS: BLOCK 1 ;MINUTES PAST THE HOUR
ZONE: BLOCK 1 ;TIME ZONE IN HOUR
COMYER: BLOCK 1 ;YEAR OF COMMAND
COMMON: BLOCK 1 ;MONTH OF COMMAND
COMDAY: BLOCK 1 ;DAY OF COMMAND
COMWKD: BLOCK 1 ;DAY OF WEEK
COMHRS: BLOCK 1 ;HOURS SINCE MIDNIGHT
COMMTS: BLOCK 1 ;MINUTES PAST THE HOUR
PCSAV1: BLOCK 1 ;SAVE PC ON CHANNEL 0 INTERRUPT
ATTOM: BLOCK 10 ;FOR COMMAND
OBEYIT: BLOCK 100 ;FLAG WHETHER TO OBEY IT
LEVBRC: BLOCK 100 ;COUNT OF MATCHING BRACKETS
LOGJFN: BLOCK 1 ;FOR LOG FILE JFN
LOGSPC: BLOCK 1 ;FOR LOG FILE JFN SPEC
SPARE: BLOCK 50 ;FOR LOG FILE NAME
PTYJOB: BLOCK 1 ;-1 IF PTY IN USE
PTYJFN: BLOCK 1 ;PTY OUTPUT JFN
PTYNAM: BLOCK 10 ;FOR PTY NAME
PTYNUM: BLOCK 1 ;FOR PTY NUMBER
PTYECH: BLOCK 1 ;IF -1 ECHO PTY OUTPUT
MTCHTB: BLOCK 5 ;FOR PROMPT MATCHING
MTCHT1: BLOCK 5 ;TABLES
CNTADR: BLOCK 1 ;-1 IF INTERRUPTED
LSTCOM: BLOCK 1 ;POINTER TO LAST COMMAND
PAGE
;LOCAL STOREAGE (CONTINUED)
FLAG1: BLOCK 1 ;FLAG 1
FLAG2: BLOCK 1 ;FLAG 2
FLAG3: BLOCK 1 ;FLAG 3
FLAG4: BLOCK 1 ;FLAG 4
FLAG5: BLOCK 1 ;FLAG 5
FLAG6: BLOCK 1 ;FLAG 6
FLAG7: BLOCK 1 ;FLAG 7
FLAG8: BLOCK 1 ;FLAG 8
TAKSPC: BLOCK 3000 ;SPACE FOR "TAKE" FILE
END <3,ENTVEC>