Trailing-Edge
-
PDP-10 Archives
-
decuslib10-11
-
43,50530/ipcf.mac
There are 57 other files named ipcf.mac in the archive. Click here to see a list.
SUBTTL CONDITIONAL ASSEMBLY THINGS
SEARCH MACTEN,UUOSYM
SALL
ND FTKI10,1 ;KI-10
ND FTVM,FTKI10 ;USE VM FEATURES
ND PAGMES,FTVM ;INCLUDE ABILITY TO SEND PAGES
IFE FTKI10,<
FTVM==0 ;NO VM FEATURES UNLESS AT LEAST KI
PURGE DMOVE,DMOVEM ;WE SHALL REDEFINE AS MACROS
DEFINE DMOVE(AC,M)<
MOVE AC,M
MOVE AC+1,1+M
>
DEFINE DMOVEM(AC,M)<
MOVEM AC,M
MOVEM AC+1,1+M
>
> ;END OF IFE FTKI10
IFE FTVM,PAGMES==0 ;NO PAGES WITHOUT VM FEATURES.
IFE PAGMES,<
SMLMES==1 ;INCLUDE ABILITY TO SEND SMALL MESSAGES
SNDMUL==0> ;IF CAN'T SEND PAGES, CAN'T SEND SEVERAL.
ND KLUDGE,1 ;KLUDGES TO GET AROUND MONITOR BUGS.
ND LANGUAGE,0 ;0 FOR F-10 CALLING CONVENTIONS
;1 FOR SAIL
;2 FOR BLISS
ND TYPERR,1 ;+ FOR SEPERATE MESSAGES FOR EACH ERROR CODE
;- FOR 1 MESSAGE +OCTAL CODE
;0 FOR NO ERROR TYPER
ND HIPAGE,700 ;1ST PAGE ATTEMPTED TO GET+1
ND SNDMUL,1 ;BY DEFAULT, INCLUDE CODE TO SEND MULTIPLE PAGES
ND NUMMES,14 ;SAVE UP TO 12 MESSAGES, BY DEFAULT.
ND MAXEXP,12 ;LARGEST EXPECTED NON-PAGE MESSAGE.
;IF A LARGER ONE COMES, A PAGE WILL
;BE CREATED FOR THE PURPOSE.
IFL <MAXEXP-10>,<MAXEXP==10> ;INFO WANTS 8 WORDS.
ND IPCGTB,1 ;GETTAB ROUTINES BY DEFAULT.
ND IPCCRT,1 ;[SYSTEM]IPCC ROUTINES BY DEFAULT.
ND SMLMES,1 ;INCLUDE ABILITY TO SEND NON-PAGES.
ND CORMAN,1 ;0 TO USE LANGUAGE OTS CORE MANAGEMENT
;1 TO DO OWN .JBFF CORE MANAGEMENT
SUBTTL AC'S AND DEFINITIONS.
IFE LANGUAGE,<
IFE CORMAN,<
TITLE IPCFOR--FORTRAN-10 CALLABLE SUBROUTINES FOR IPCF.
ND PURESW,0> ;BY DEFAULT, PUT CODE IN LOW SEG
IFN CORMAN,<
TITLE IPCPAS--FORTRAN-10 CALLABLE SUBROUTINES FOR IPCF. PASCAL VERSION
ND PURESW,1> ;BY DEFAULT, PUT CODE IN HIGH SEGMENT
T0=0 ;TEMPORARY THAT NEED NOT BE PRESERVED
T1=1 ;ANOTHER AC " " " " "
T2=2
T3=3
T4=4
P1=5 ;START OF A BLOCK OF 5 AC'S THAT MUST BE PRESERVED
P2=6
P3=7
P4=10
ARGS=16 ;POINTER TO ARGUMENT BLOCK
P=17 ;STACK POINTER
;CALLING CONVENTION MACROS
DEFINE FENTER(N),<>
DEFINE FEXIT(N),<POPJ P,>
DEFINE VMOVE(REG,NUM),<MOVE REG,@NUM(ARGS)>
DEFINE RMOVE(REG,NUM),<MOVE REG,@NUM(ARGS)>
DEFINE RMOVEI(REG,NUM),<MOVEI REG,@NUM(ARGS)>
DEFINE RMOVEM(REG,NUM),<MOVEM REG,@NUM(ARGS)>
DEFINE RHRRZM(REG,NUM),<HRRZM REG,@NUM(ARGS)>
DEFINE RHLRZM(REG,NUM),<HLRZM REG,@NUM(ARGS)>
DEFINE VHRL(REG,NUM),<HRL REG,@NUM(ARGS)>
DEFINE RPOP(REG,NUM),<POP REG,@NUM(ARGS)>
DEFINE RHRRI(REG,NUM),<HRRI REG,@NUM(ARGS)>
DEFINE VSKIPE(REG,NUM),<SKIPE REG,@NUM(ARGS)>
DEFINE RSK IPE(REG,NUM),<SKIPE REG,@NUM(ARGS)>
DEFINE VSKIPG(REG,NUM),<SKIPG REG,@NUM(ARGS)>
DEFINE VSKIPN(REG,NUM),<SKIPN REG,@NUM(ARGS)>
DEFINE VSKPLE(REG,NUM),<SKIPLE REG,@NUM(ARGS)>
DEFINE RSKPLE(REG,NUM),<SKIPLE REG,@NUM(ARGS)>
DEFINE RSETZM(NUM),<SETZM @NUM(ARGS)>
DEFINE RAOS(NUM),<AOS @NUM(ARGS)>
DEFINE VMOVM(REG,NUM),<MOVM REG,@NUM(ARGS)>
DEFINE GETCOUNT(REG),<
HLRE REG,-1(ARGS)
MOVMS REG>
> ;END OF IFE LANGUAGE
IFE LANGUAGE-1,<
TITLE IPCSAI--SAIL CALLABLE SUBROUTINES FOR IPCF
T0=0
T1=1
T2=2
T3=3
T4=4
P1=5
P2=6
P3=7
P4=10
F=12
USER=15 ;POINTER TO USER TABLE
P=17 ;NORMAL STACK
ND PURESW,0 ;BY DEFAULT, PUT CODE IN LOW SEG
;*****THE FOLLOWING PARAMETERS MAY BE SAIL VERSION NUMBER DEPENDENT!
;THEY ARE INDICES INTO THE USER TABLE
TOPBYTE==11 ;INDEX INTO GOGTAB OF NEXT FREE BYTE OF STRING SPACE
REMCHAR==12 ;REMAINING FREE CHARS IN STRING SPACE
DEFINE FENTER(N),<
PUSH P,F ;SAVE FREG
MOVEI F,-N-1(P)> ;AND SET UP NEW ONE
DEFINE FEXIT(N),<
POP P,F ;RESTORE OLD F REGISTER
SUB P,[N+1,,N+1] ;REMOVE PARAMETERS FROM STACK
JRST @N+1(P)> ;AND RETURN TO USER
DEFINE VMOVE(REG,NUM),<MOVE REG,NUM(F)>
DEFINE RMOVE(REG,NUM),<MOVE REG,@NUM(F)>
DEFINE RMOVEI(REG,NUM),<MOVEI REG,@NUM(F)>
DE FINE RMOVEM(REG,NUM),<MOVEM REG,@NUM(F)>
DEFINE RHRRZM(REG,NUM),<HRRZM REG,@NUM(F)>
DEFINE RHLRZM(REG,NUM),<HLRZM REG,@NUM(F)>
DEFINE VHRL(REG,NUM),<HRL REG,NUM(F)>
DEFINE RPOP(REG,NUM),<POP REG,@NUM(F)>
DEFINE RHRRI(REG,NUM),<HRRI REG,@NUM(F)>
DEFINE VSKIPE(REG,NUM),<SKIPE REG,NUM(F)>
DEFINE RSKIPE(REG,NUM),<SKIPE REG,@NUM(F)>
DEFINE VSKIPG(REG,NUM),<SKIPG REG,NUM(F)>
DEFINE VSKIPN(REG,NUM),<SKIPN REG,NUM(F)>
DEFINE VSKPLE(REG,NUM),<SKIPLE REG,NUM(F)>
DEFINE RSKPLE(REG,NUM),<SKIPLE REG,@NUM(F)>
DEFINE RSETZM(NUM),<SETZM @NUM(F)>
DEFINE RAOS(NUM),<AOS @NUM(F)>
DEFINE VMOVM(REG,NUM),<MOVM REG,NUM(F)>
> ; END OF IFE LANGUAGE-1
IFE LANGUAGE-2,<
TITLE IPCBLI--BLISS CALLABLE SUBROUTINES FOR IPCF
SREG=0
FREG=2
T0=3
T1=4
T2=5
T3=6
T4=7
P1=10
P2=11
P3=12
P4=13
P=17
ND PURESW,1 ;TWO-SEG CODE, BY DEFAULT
CORMAN==1 ;BLISS HAS NO OTS, HENCE NO DEFAULT CORE MANAGEMENT
DEFINE FENTER(N),<
EXCH SREG,P ;PUT STACK IN AN INDEX REGISTER
PUSH P,FREG ;SAVE OLD FREG
PUSH P,12 ;ALSO SAVE P3
PUSH P,13 ;AND P4
MOVEI FREG,-N-3(P)> ;SET UP NEW FREG
DEFINE FEXIT(N),<
POP P,13 ;RESTORE OLD REGISTER 13
POP P,12 ;AND REGISTER 12
POP P,FREG ;AND OLD FREG
EXCH SREG,P ;PUT STACK POINTER BACK WH ERE BLISS EXPECTS
POPJ SREG,> ;AND RETURN
DEFINE VMOVE(REG,NUM),<MOVE REG,NUM(FREG)>
DEFINE RMOVE(REG,NUM),<MOVE REG,@NUM(FREG)>
DEFINE RMOVEI(REG,NUM),<MOVEI REG,@NUM(FREG)>
DEFINE RMOVEM(REG,NUM),<MOVEM REG,@NUM(FREG)>
DEFINE RHRRZM(REG,NUM),<HRRZM REG,@NUM(FREG)>
DEFINE RHLRZM(REG,NUM),<HLRZM REG,@NUM(FREG)>
DEFINE VHRL(REG,NUM),<HRL REG,NUM(FREG)>
DEFINE RPOP(REG,NUM),<POP REG,@NUM(FREG)>
DEFINE RHRRI(REG,NUM),<HRRI REG,@NUM(FREG)>
DEFINE VSKIPE(REG,NUM),<SKIPE REG,NUM(FREG)>
DEFINE RSKIPE(REG,NUM),<SKIPE REG,@NUM(FREG)>
DEFINE VSKIPG(REG,NUM),<SKIPG REG,NUM(FREG)>
DEFINE VSKIPN(REG,NUM),<SKIPN RE G,NUM(FREG)>
DEFINE VSKPLE(REG,NUM),<SKIPLE REG,NUM(FREG)>
DEFINE RSKPLE(REG,NUM),<SKIPLE REG,@NUM(FREG)>
DEFINE RSETZM(NUM),<SETZM @NUM(FREG)>
DEFINE RAOS(NUM),<AOS @NUM(FREG)>
DEFINE VMOVM(REG,NUM),<MOVM REG,NUM(FREG)>
> ;END OF IFE LANGUAGE-2
IFG LANGUAGE-2,<
PRINTX ?SORRY, ONLY F10 & SAIL & BLISS CALLING SEQUENCES WRITTEN
PASS2
END>
IFL LANGUAGE,<
PRINTX ?SORRY, ONLY F10 & SAIL & BLISS CALLING SEQUENCES WRITTEN
PASS2
END>
SUBTTL REVISION HISTORY
VWHO==0
VMAJOR==2
VMINOR==0
VEDIT==25
%%IPCF==:BYTE (3)VWHO(9)VMAJOR(6)VMINOR(18)VEDIT
PURGE VWHO,VMAJOR,VMINOR,VEDIT
;%1(0) -- FIRST F ULLY WORKING SET OF ROUTINE.
;1 CREATE FTKI10 CONDITIONAL AND DEFINE DMOVE AND DMOVEM AS MACROS FOR A KA.
;2 CREATE FTVM CONDITIONAL AND ALLOW USE OF A NON-VM MONITOR. (ORIGINAL
; PACKAGE WAS HIGHLY VM DEPENDENT)
;3 IN IPCRCV, SAVE MESSAGE AT END, RATHER THAN AT BEGINNING
;4 IN IPCINF, ALWAYS CLEAR 30TH CHARACTER OF NAME TO FORCE ASCIZ (ANSWER TO A QAR).
;5 CREATE UFUNCT CONDITIONAL TO ALLOW USE OF FUNCT. ROUTINE IN FOROTS FOR
; SAFER CORE ALLOCATION.
;6 CREATE LANGUAGE CONDITIONAL. SOONER OR LATER I SHALL GET AROUND
; TO WRITING THE ROUTINES FOR A BLISS-10 CALLING SEQUENCE, RATHER THAN
; FORCING BLISS ROUTINES TO GO TH ROUGH A FCALL ROUTINE.
;7 IMPROVE SELF CONTAINED CORE MANAGEMENT OF SMALL MESSAGES.
;10 FIX BUG WHICH PREVENTED SMALL MESSAGES FROM BEING SAVED CORRECTLY.
; (BLT WAS NOT BEING SET UP RIGHT FOR A MESSAGE AT DBLK).
;11 FIX BUG IN SNDINF ABOUT SAVING MESSAGES WHILE WAITING FOR INFO'S RESPONSE.
;12 FIX BUG IN SAVMES THAT SAVED MESSAGE INFO ON TOP OF PREVIOUSLY SAVED INFO.
;13 MORE EFFICIENT PAGE SAVING WITH FUNCT.
;%1A(13) Dec 21,1974
;14 DEFINE FENTER,FEXIT, AND GETCOUNT MACROS IN PREPARATION FOR
; PROVIDING SAIL CALLING CONVENTION. THESE ATTEMPT TO MAKE THE ROUTINES
; LANGUAGE INDEPENDENT FOR CALLING CONVENTION, ROUTINE EXI T AND ENTRY,
; AND ARGUMENT COUNTING.
;15 DEFINE V????? MACROS TO MANIPULATE A VALUE PARAMETER, AND R????? MACROS
; TO MANIPULATE REFERENCE PARAMETERS. MAKE SURE THAT ALL ROUTINES EXIT
; THROUGH A SINGLE EXIT POINT PER ROUTINE. REMOVE CALLS TO SAVE4 AND
; SAVE2 IN TOPLEVEL IPC??? ROUTINES. THESE ARE NOT NECESSARY FOR EITHER
; FORTRAN OR SAIL, AND THEY SCREW UP SAIL'S EXIT SEQUENCE.
;16 REALLY CLEAN UP CORE MANAGEMENT. GET RID OF UFUNCT CONDITIONAL & CREATE
; CORMAN CONDITIONAL (=1, DO OWN .JBFF CORE MANAGEMENT. =0, USE ROUTINES
; IN OTS).
;17 LANGUAGE=2 PROVIDES BLISS CALLING CONVENTION
;20 CLEAN UP IPCSND.
;21 IF A LLCPG CAN'T GET A PAGE IN CORE, GET IT ON DSK. THIS PATCH WAS
; INSERTED INTO THE LISP CALLABLE VERSION A LONG TIME AGO, BUT NEVER
; INSERTED HERE.
;22 IF A JOB'S WORKING SET IS CORMAX, IPCFR. WILL FAIL WITH CODE 13
; IF THIS HAPPENS, PAGE SOMETHING OUT (ANYTHING--ACTUALLY, PAGE 1 IS USED)
; AND TRY AGAIN. TOO BAD YOU CAN'T ASK PFH TO SELECT WHAT TO PAGE OUT...
;23 FIX UP EDIT 22 SO IT PAGES OUT THE FIRST PAGE IN THE WORKING SET.
;24 PUT IN SEVERAL PATCHES FROM THE LISP VERSION FOR IPCCON
;25 UPDATE TO 603; RETURN UP TO 6 WORDS OF QUEUE INFO, RATHER THAN 4
SUBTTL STORAGE
IFN PURESW,<
TWOSEG 400000
RELOC 0>
D BLK: BLOCK 2 ;2 WORDS IN FRONT OF NAME
MYNAME: BLOCK MAXEXP-2 ;THE NAME ITSELF
PIDUS: BLOCK 1 ;OUR PID
SAVCOD: BLOCK 1 ;FUNCTION CODE SAVED HERE
SAVBLK: BLOCK 6 ;IPCFQ. PACKET OF SAVED MESSAGE
SAVNUM: BLOCK 1 ;HOW MANY MESSAGES ARE BEING SAVED.
MESTAB: BLOCK 7*NUMMES ;POINTERS TO START OF EACH SAVED MESSAGE FOLLOWED BY
;THE QUEUE ENTRY FOR THE MESSAGE.
SVMES1: BLOCK 1 ;ADDRESS IN MESTAB OF 1ST SAVED MESSAGE
SVMESN: BLOCK 1 ;ADDRESS IN MESTAB OF THE LAST MESSAGE
INFIND: BLOCK 1 ;0 IF EXPECTING REPLY FROM INFO, NON-0 IF
;EXPECTING REPLY FROM IPCC.
IFN IPCCRT,<
CONPID: BLOCK 1> ;PID OF [SYSTEM]IPCC
I FE LANGUAGE!CORMAN,< ;FORTRAN WITH OTS CORE MANAGEMENT?
FUNCT: BLOCK 1 ;FUNCT. FUNCTION
ERROR: BLOCK 1 ;ERROR CODE
STATUS: BLOCK 1 ;ACTUAL ERROR CODE
ARG1: BLOCK 1 ;FIRST ARGUMENT
ARG2: BLOCK 1 ;SECOND ARGUMENT
> ;END OF IFE LANGUAGE!CORMAN ;FORTRAN WITH OTS CORE MANAGEMENT
IFN CORMAN,< ;IF WE DO OUR OWN CORE MANAGEMENT...
FRECOR: BLOCK 1 ;POINTER TO FREE-CORE LIST
> ;END OF IFN CORMAN
IFN FTVM,< ;IF HAVE VM MONITOR
BLOCK 1
PAGTAB: BLOCK 17 ;ARRAY OF BITS FOR WORKING SET
> ;END OF IFN FTVM
IFN PURESW,<
RELOC 400000>
SUBTTL IPCINF--IPC [SYSTEM]INFO CALLS
ENTRY IPCINF
;THE FOLLOWING ROUTINE PREPARES TO MAKE A REQUEST TO [SYSTEM]INFO. IT SETS
;UP SOME PRELIMINARY INFORMATION, CHECKS THE VALIDITY OF THE FUNCTION, AND
;DISPATCHES TO THE PROPER CODE TO HANDLE THAT PARTICULAR FUNCTION.
;CALL: INTEGER ERROR,FUNCT,CODE,DUPPID,PID,FLAG,NAME(6)
; OR DOUBLE PRECISION NAME
; CALL IPCINF(ERROR,FUNCT,CODE,DUPPID,PID,FLAG,NAME)
;ERROR IS RETURNED 0 IF NO ERROR, POSITIVE IF IPCF ERROR, NEGATIVE IF OTHER ERROR.
;FUNCT IS THE FUNCTION TO HAVE INFO DO. THE MAGNITUDE MUST BE IN THE RANGE 1 TO 7.
; POSITIVE IF CONTROL IS TO RETURNED IMMEDIATELY AFTER THE FUNCTION IS SUBMITTED.
; NEGATIVE IF ROUTINE WILL WAIT FOR THE ANSWER, SA VING PACKETS UNTIL IT ARRIVES.
;CODE IS AN 18 BIT QUANTITY TO ALLOW THE USER TO ASSOCIATE AN ANSWER WITH A REQUEST.
;DUPPID IS THE PID OF THE USER TO RECEIVE A DUPLICATE COPY OF THE REPLY, OR IS 0.
;PID IS EITHER THE ARGUMENT OR IS RETURNED. IT MAY BE EITHER A PID OR A JOB NUMBER.
;FLAG DETERMINES THE HANDLING OF THE NAME:
; IF NAME IS AN ARGUMENT, AND:
; FLAG .LT. 0, NAME IS A DOUBLE PRECISION ASCII STRING.
; FLAG .EQ. 0, NAME IS NOT SUPPLIED. IPCINF MUST MAKE A DOUBLE
; PRECISION, BLANK FILLED, ASCII STRING FROM THE PROGRAM NAME.
; FLAG .GT. 0, NAME IS A 6 WORD ASCII STRING. BEFORE SENDING,
; THE LAST CHARACTER WILL BE CLEARED TO MAKE SURE THE
; NAME IS ASCIZ.
; IF NAME IS RETURNED, AND:
; FLAG .LE. 0, NAME IS DOUBLE PRECISION. (2 WORDS SUPPLIED OUT OF 6).
; FLAG .GT. 0, NAME IS 6 WORDS.
;NAME IS EITHER USED AS AN ARGUMENT OR IS RETURNED.
;THE FUNCTIONS ARE:
;1 CALL IPCINF(ERROR,1,CODE,DUPPID,PID,FLAG,NAME)
; RETURN THE PID CORRESPONDING TO THE NAME.
;2 CALL IPCINF(ERROR,2,CODE,DUPPID,PID,FLAG,NAME)
; RETURN THE NAME CORRESPONDING TO THE PID.
;3 CALL IPCINF(ERROR,3,CODE,DUPPID,PID,FLAG,NAME)
; ASSIGN THE NAME AND RETURN A PID TO BE DROPPED ON RESET.
;4 CALL IPCINF(ERROR,4,CODE,DUPPID,PID,FLAG,NAME)
; ASSIGN THE NAME AND RETURN A PID TO BE DROPPED ON LOGOUT.
;FOR THE FOLLOWING 3 FUNCTIONS, IF FLAG IS NON-0, PRIVILEGES WILL BE INVOKED.
;IF FLAG IS NOT PRESENT OR IS PRESENT AND IS 0, PRIVILEGES WILL NOT BE INVOKED.
;5 CALL IPCINF(ERROR,5,CODE,DUPPID,PID,FLAG)
; DROP THE PID.
;FOR THE FOLLOWING TWO FUNCTIONS, JOB MUST NOT BE A PID.
;6 CALL IPCINF(ERROR,6,CODE,DUPPID,JOB,FLAG)
; DROP ALL PIDS FOR JOB THAT WERE SIGNED OUT UNTIL RESET.
;7 CALL IPCINF(ERROR,7,CODE,DUPPID,JOB,FLAG)
; DROP ALL PIDS FOR JOB.
IPCINF: FENTER(7)
PUSHJ P,SETINF ;SET UP SAVBLK TO CALL [SYSTEM]INFO
VMOVM T0,1 ;GET THE POSITIVE FUNCTION CODE
SKIPLE T0 ;-3 MEANS INVALID FUNCTION
CAILE T0,7 ;FUNCTION .LE. 7?
JRST [PUSHJ P,RETM3 ;NOPE. UNKNOWN FUNCTION.
JRST XITINF]
VHRL T0,2 ;GET THE CODE HE SPECIFIED
MOVEM T0,SAVCOD ;SAVE FOR GETANS
VMOVE T1,3 ;AND THE PID TO RECEIVE A DUPLICATE RESPONSE
DMOVEM T0,DBLK ;STORE IN BEGINNING OF [SYSTEM]INFO ARG BLOCK.
HRRZ T1,T0 ;GET FUNCTION AGAIN
HRRZ T1,INFDIS-1(T1) ;GET ADDRESS FROM DISPATCH TABLE
PUSHJ P,(T1) ;GO THERE.
XITINF: FEXIT(7) ;RETURN TO USER
SUBTTL IPCANS--GET ANSWER FROM [SYSTEM]INFO
ENTRY IPCANS
;THE FOLLOWING ROUTINE COMPLETES A REQUEST TO [SYSTEM]INFO OR [SYSTEM]IPCC.
;IT REQUIRES THAT THE TOP PACKET IN THE QUEUE WAS SENT BY [SYSTEM]INFO OR
;[SYSTEM]IPCC AND WILL COMPLETE THE REQUEST ACCORDING TO WHAT THE FUNCTION IN
;THE RETURN MESSAGE IS.
;THE ARGUMENTS FOR IPCANS ARE THE SAME AS FOR THE CORRESPONDING INFO OR IPCC
;REQUEST BEYOND THE FIRST 4.
;CALL: INTEGER ERROR,FUNCT,CODE,PID,FLAG,NAME
; CALL IPCANS(ERROR,FUNCT,CODE,WHO,SUBSEQUENT ARGUMENTS)
;FUNCT IS RETURNED AS THE FUNCTION CODE IN THE MESSAGE FROM INFO.
;CODE IS RETURNED FROM THE USER SPECIFIED CODE IN THE MESSAGE FROM INFO.
;WHO IS A CODE INDICATING WHO THE MESSAGE IS FROM.
;PID IS RETURNED IF THE FUNCTION RETURNS A PID.
;NAME IS RETURNED IF THE FUNCTI ON RETURNS A NAME.
;FLAG INDICATES HOW NAME IS TO BE STORED. SEE IPCINF.
;ERROR IS NON-0 IF TOP PACKET IS NOT FROM INFO, SOME UUO ERROR OCCURRED,
; OR THE ERROR CODE FIELD OF THE PACKET IS NON-0.
IPCANS: FENTER(7)
PUSHJ P,INFCHK ;SEE IF FROM INFO
JRST XITANS ;NOT INFO OR IPCC. ERROR ALREADY SET UP.
IFN IPCCRT,<
JFCL> ;[SYSTEM]IPCC
IFE IPCCRT,<
JRST [PUSHJ P,RETM4 ;IPCC. STILL NOT INFO.
JRST XITANS]>
RMOVEM T0,3 ;SAVE FROM WHO
SKIPE SAVNUM ;DO WE ALREADY HAVE THE MESSAGE?
JRST IPCAN2 ;YES--DON'T GET THE NEXT ONE
PUSHJ P,SETINF ;SET UP INFO CALL
IPCFR. T1, ;DO IT
JRST [PUSHJ P,ERRRET ;N O GOOD.
JRST XITANS]
IPCAN2: MOVE T1,(P1) ;GET FIRST WORD OF MESSAGE
RHRRZM T1,1 ;STORE THE FUNCTION
RHLRZM T1,2 ;AND THE CODE
LDB T1,[POINT 6,(P2),29] ;READ ERROR FIELD INTO T1
JUMPN T1,DMSG ;RETURN ERROR IF NON-ZERO
HRRZ T1,(P1) ;RETRIEVE FUNCTION AGAIN
IFN IPCCRT,<
CAIN T0,.IPCCC ;WAS MESSAGE FROM IPCC?
JRST ISIPCC> ;YES--HANDLE ELSEWHERE
CAILE T1,7 ;DO WE KNOW ABOUT THIS FUNCTION?
JRST [PUSHJ P,RETM3 ;NOPE
JRST XITANS]
HLRZ T1,INFDIS-1(T1) ;GET DISPATCH ADDRESS
PUSHJ P,(T1) ;DISPATCH
SKIPE SAVNUM ;WERE WE LOOKING AT A SAVED MESSAGE?
PUSHJ P,IPCDS1 ;YES--KILL IT
XITANS: FEXIT(7)
DMSG: PUSH P,T1 ;SAVE ANY ERROR WE MAY HAVE HAD
SKIPE SAVNUM ;LOOKING AT A SAVED MESSAGE?
PUSHJ P,IPCDS1 ;YES--DELETE IT
RPOP P,0 ;RESTORE THE ERROR CODE
JRST XITANS ;AND RETURN
IFN IPCCRT,<
ISIPCC: CAILE T1,25 ;WITHIN RANGE?
JRST [PUSHJ P,RETM5 ;NO--FUNCTION OUT OF RANGE
JRST XITANS]
HLRZ T1,CONDIS-1(T1) ;GET PROPER DISPATCH ADDRESS
PUSHJ P,(T1) ;CALL THE ROUTINE
SKIPE SAVNUM ;MESSAGE SAVED?
PUSHJ P,IPCDS1 ;YES--DISCARD IT
JRST XITANS ;RETURN
> ;END OF IFN IPCCRT
SUBTTL IPCFUN--GET INFO FUNCTION OF TOP PACKET.
ENTRY IPCFUN
;THE FOLLOWING SUBROUTINE CHECKS IF THE TOP PACKET IN THE QUEU E IS FROM
;[SYSTEM]INFO OR [SYSTEM]IPCC. IF SO, IT WILL READ IN AND RETAIN THE MESSAGE,
;RETURNING THE CODE AND FUNCTION FROM THE FIRST WORD.
;CALL: INTEGER ERROR,FUNCT,CODE,WHO
; CALL IPCFUN(ERROR,FUNCT,CODE,WHO)
;WHO IS RETURNED TO INDICATE WHO THE MESSAGE IS FROM:
; WHO=1 ;[SYSTEM]IPCC
; WHO=2 ;PUBLIC [SYSTEM]INFO
; WHO=3 ;PRIVATE [SYSTEM]INFO
;IF TOP MESSAGE IS NOT FROM INFO, IT WILL NOT BE RECEIVED AND ERROR WILL BE -4.
IPCFUN: FENTER(4)
PUSHJ P,INFCHK ;SEE IF INFO OR IPCC
JRST XITFUN ;NEITHER. ERROR ALREADY SET
IFN IPCCRT,<
JFCL> ;IPCC
IFE IPCCRT,<
JRST [PUSHJ P,RETM4 ;IPCC
JRST XITFUN]>
R MOVEM T0,3 ;STORE T0 IN WHO
SKIPE SAVNUM ;STORING THIS MESSAGE?
JRST GOTMES ;YES--LOOK AT IT
PUSHJ P,GETMES ;NO--GET IT
JRST XITFUN ;ERROR SOMEWHERE
PUSHJ P,SAVMES ;AND SAVE IT
JRST XITFUN ;ERROR
GOTMES: MOVE T1,(P1) ;GET FIRST WORD OF MESSAGE IN T1
RHLRZM T1,2 ;STORE CODE
RHRRZM T1,1 ;AND FUNCTION
PUSHJ P,GODRET ;AND RETURN
XITFUN: FEXIT(4)
SUBTTL DISPATCH TABLES
;THE FOLLOWING TABLE HAS ENTRIES FOR EACH [SYSTEM]INFO FUNCTION. FORMAT:
; ADR TO RECEIVE MESSAGE FROM INFO,,ADR TO SEND MESSAGE TO INFO
INFDIS: GOTPDM,,GETPDM
GOTNPD,,GETNPD
GOTPDM,,GETPDM
GOTPDM,,GETPDM
GODRET,,PIDGO
GOD RET,,PIDGO
GODRET,,PIDGO
IFN IPCCRT,<
;THE FOLLOWING TABLE HAS SIMILAR ENTRIES FOR EACH [SYSTEM]IPCC FUNCTION.
CONDIS: GODRET,,GIVJOB
GODRET,,GIVJOB
GETIN,,GJBGIN
GETPID,,GJBGPD
GODRET,,GIVJOB
GETPID,,MAKPID
GODRET,,SETQOT
GODRET,,CHGJOB
GETPID,,GJBGPD
GETMPD,,GJGMPD
GETQOT,,GJGQOT
GODRET,,GIVJOB
GODRET,,RETM3
GODRET,,RETM3
GODRET,,RETM3
GODRET,,RETM3
GODRET,,RETM3
GODRET,,RETM3
GODRET,,RETM3
GODRET,,CHGJOB
GETPID,,GJBGPD
> ;END OF IFN IPCCRT
SUBTTL INFDIS--ROUTINES TO HANDLE SYSTEM INFO FUNCTIONS.
;ROUTINE TO SEND A NAME AND RECEIVE A PID.
GETPDM: VSKIPE 0,5 ;FLAG.NE.0?
JR ST NAMSUP ;YES--A NAME IS SUPPLIED. USE IT.
HRROI T0,.GTPRG ;NO--CREATE A NAME OUT OF OUR PROGRAM NAME
GETTAB T0, ;-1,,3 IS PROGRAM NAME INDEX FOR OUR JOB.
JRST RETM2 ;VERY UNUSUAL
MOVE P1,[POINT 6,T0] ;SIXBIT POINTER
MOVE P2,[POINT 7,MYNAME] ;ASCII POINTER
MOVE P3,[ASCII / /] ;5 SPACES
MOVEM P3,MYNAME ;INITIALIZE FIRST 2 WORDS OF NAME WITH BLANKS
MOVEM P3,MYNAME+1 ;...
MOVNI P4,6 ;ALLOW UP TO SIX CHARACTERS
CLOOP: ILDB T1,P1 ;GET FIRST SIXBIT CHARACTER IN T1
ADDI T1,40 ;CONVERT TO ASCII
IDPB T1,P2 ;DEPOSIT IN NAME
AOJL P4,CLOOP ;REPEAT 6 TIMES
CLRNAM: SETZB T0,T1 ;CLEAR 2 AC'S
DMOVEM T0,M YNAME+2 ;CLEAR 2ND 2 WORDS
DMOVEM T0,MYNAME+4 ;AND 3RD SET OF 2 WORDS
GETNAM: PUSHJ P,SNDINF ;SEND THE MESSAGE TO INFO
POPJ P, ;TIME TO RETURN.
GOTPDM: MOVE T1,1(P1) ;GET THE PID
JUMPE T1,RETM1 ;MUST BE A PID
RMOVEM T1,4 ;STORE IN THE PROPER PLACE
HRRZ T0,(P1) ;GET THE FUNCTION CODE
CAIE T0,.IPCII ;SIGNING OUT UNTIL RESET?
CAIN T0,.IPCIJ ;OR LOGOUT?
MOVEM T1,PIDUS ;YES--REMEMBER AS DEFAULT PID
GODRET: RSETZM 0 ;CLEAR ERROR
POPJ P, ;AND RETURN
IFN LANGUAGE-1,< ;FORTRAN OR BLISS
NAMSUP: RMOVEI P1,6 ;GET ADDRESS OF NAME IN P1
DMOVE T0,0(P1) ;GET 1ST 2 WORDS OF NAME
DMOVEM T0,MYNAME ;STORE THEM
V SKIPG 0,5 ;IS MORE SUPPLIED?
JRST CLRNAM ;NO--CLEAR REST OF NAME
DMOVE T0,2(P1) ;GET 2ND SET OF 2 WORDS
DMOVEM T0,MYNAME+2 ;STORE THEM
DMOVE T0,4(P1) ;AND LAST 2 WORDS
TRZ T1,377 ;CLEAR THE LAST CHARACTER
DMOVEM T0,MYNAME+4 ;STORE THEM
JRST GETNAM ;SEND AWAY
> ;END OF IFN LANGUAGE-1 ;FORTRAN OR BLISS
IFE LANGUAGE-1,< ;SAIL
NAMSUP: SETZM MYNAME ;CLEAR FIRST WORD OF NAME
MOVE T0,[MYNAME,,MYNAME+1] ;PREPARE FOR BLT
BLT T0,MYNAME+5 ;CLEAR REST OF NAME
RMOVEI T1,6 ;GET ADR OF STRING DESCRIPTOR
HRRZ T0,-1(T1) ;BYTE COUNT IN T0
CAILE T0,^D29 ;TOO MANY?
MOVEI T0,^D29 ;YES--TRUNCATE
MOVE P1,0(T1) ;GE T SUPPLIED BYTE POINTER
MOVE P2,[POINT 7,MYNAME] ;AND POINTER TO DESTINATION
STRLOP: SOJL T0,GETNAM ;IF DONE, SEND NAME TO [INFO]
ILDB T1,P1 ;GET CHAR FROM SUPPLIED NAME
IDPB T1,P2 ;STORE IN MESSAGE
JRST STRLOP ;CHECK IF DONE
> ;END OF IFE LANGUAGE-1 ;SAIL
;HERE TO SEND A PID AND RECEIVE A NAME.
GETNPD: RMOVE T1,4 ;GET PID SUPPLIED
MOVEM T1,DBLK+2 ;STORE IT
PUSHJ P,SNDINF ;SEND IT AWAY
POPJ P, ;TIME TO RETURN
GOTNPD: RMOVEI P2,6 ;GET ADDRESS OF WHERE TO STORE NAME
IFN LANGUAGE-1,< ;FORTRAN OR BLISS
DMOVE T0,2(P1) ;GET 1ST 2 WORDS OF NAME
DMOVEM T0,0(P2) ;STORE THEM
VSKIPG 0,5 ;GET MORE?
JRST G ODRET ;NO--GOOD RETURN
DMOVE T0,4(P1) ;2 MORE
DMOVEM T0,2(P2) ;STORE
DMOVE T0,6(P1) ;2 MORE
DMOVEM T0,4(P2) ;STORE
JRST GODRET ;RETURN
> ;END OF IFN LANGUAGE-1 ;FORTRAN OR BLISS
IFE LANGUAGE-1,< ;SAIL
SETZ T0, ;CLEAR CHAR COUNTER
MOVE T1,[POINT 7,2(P1)] ;POINT INTO NAME
CCLOOP: ILDB T2,T1 ;GET A CHAR
SKIPE T2 ;NULL?
AOJA T0,CCLOOP ;NO--COUNT IT AND LOOP
PUSH P,T0 ;PUSH CHAR COUNT
EXCH F,-2(P) ;RESTORE "SAIL" TYPE F-REG
PUSHJ P,STRGC## ;MAKE SURE THERE ARE THAT MANY CHARS AVAILABLE
EXCH F,-1(P) ;NOW GET BACK "IPCSAI" TYPE F-REG
MOVE USER,GOGTAB## ;POINT TO USER TABLE
ADDM T0,REMCHAR(USER) ;U PDATE FREE CHAR COUNT
MOVE T2,TOPBYTE(USER) ;GET BYTE POINTER TO FIRST FREE BYTE
HRRM T0,-1(P2) ;STORE CHAR COUNT
MOVEM T2,0(P2) ;AND BYTE POINTER
MOVE T1,[POINT 7,2(P1)] ;POINT TO NAME AGAIN
STMKLP: SOJL T0,STOBYT ;RETURN IF STORED WHOLE STRING
ILDB T3,T1 ;GET A CHAR
IDPB T3,T2 ;STORE IT
JRST STMKLP ;LOOP BACK TO CONTINUE MAKING STRING
STOBYT: MOVEM T2,TOPBYTE(USER) ;STORE NEW FIRST FREE CHAR
JRST GODRET ;AND GIVE A GOOD RETURN
> ;END OF IFE LANGUAGE-1 ;SAIL
;THE FOLLOWING ROUTINE SENDS A PID, OPTIONALLY INVOKING PRIVILEGES.
PIDGO:
IFE LANGUAGE,< ;FORTRAN? (ONLY LANGUAGE WITH VAR # OF ARGS..)
GETCOUN T(T1) ;GET ARG COUNT IN T1
CAIG T1,5 ;FLAG SUPPLIED?
JRST SPID> ;NO--NON-PRIVILEGED REQUEST
MOVX T1,IP.CFP ;PRIVILEGE BIT.
VSKIPE 0,5 ;FLAG NON-ZERO?
IORM T1,SAVBLK ;YES--SET FLAG
SPID: RMOVE T1,4 ;GET PID TO SEND
MOVEM T1,DBLK+2 ;STORE IT
PUSHJ P,SNDINF ;SEND THE MESSAGE
POPJ P, ;TOUGH ROCKS, BABY.
JRST GODRET ;GOOD RETURN
SUBTTL IPCCON--REQUESTS TO IPCC
IFN IPCCRT,<
ENTRY IPCCON
;THE FOLLOWING ROUTINE MAKES A REQUEST TO [SYSTEM]IPCC.
;CALL: INTEGER ERROR,FUNCT,CODE,FLAG
; CALL IPCCON(ERROR,FUNCT,CODE,FLAG,FUNCTION DEPENDENT ARGUMENTS)
;ERROR IS RETURNED NON-0 ON ANY ERROR
;FUNCT IS THE DE SIRED FUNCTION
;CODE IS AN 18 BIT QUANTITY SUPPLIED BY THE USER TO IDENTIFY THE REQUEST.
;FLAG IS NON-0 TO INVOKE PRIVILEGES
;THE POSSIBLE CALLS ARE:
;1 CALL IPCCON(ERROR,1,CODE,FLAG,JOBPID)
; ENABLE JOB'S ABILITY TO RECEIVE PACKETS.
; PRIVILEGED FUNCTION IF NOT YOUR OWN JOB.
;2 CALL IPCCON(ERROR,2,CODE,FLAG,JOBPID)
; DISABLE JOB'S ABILITY TO RECEIVE PACKETS.
; PRIVILEGED FUNCTION IF NOT YOUR OWN JOB.
;3 CALL IPCCON(ERROR,3,CODE,FLAG,JOBPID,INFPID)
; RETURN PID OF [SYSTEM]INFO IN INFPID.
;4 CALL IPCCON(ERROR,4,CODE,FLAG,JOBPID,INFPID)
; CREATE A [SYSTEM]INFO FOR A SPECIFIED JOB (PRIVILEGED FUNCTION).
; INFPID I S RETURNED AS THE PID OF THE NEW INFO.
;5 CALL IPCCON(ERROR,5,CODE,FLAG,PID)
; DESTROY A PID (PRIVILEGED FUNCTION).
;6 CALL IPCCON(ERROR,6,CODE,FLAG,JOB,PID,TYPE)
; CREATE A PID FOR A SPECIFIED JOB (PRIVILEGED FUNCTION).
; TYPE IS NON-0 IF THE PID IS TO BE DROPPED ON RESET,
; 0 IF PID IS TO BE DROPPED ON LOGOUT.
;7 CALL IPCCON(ERROR,7,CODE,FLAG,PIDJOB,SND,RCV)
; SET SEND AND RECEIVE QUOTAS FOR A JOB (PRIVILEGED FUNCTION).
;10 CALL IPCCON(ERROR,8,CODE,FLAG,PIDJOB,NEWJOB)
; CHANGE THE JOB NUMBER ASSOCIATED WITH A PID (PRIVILEGED FUNCTION).
;11 CALL IPCCON(ERROR,9,CODE,FLAG,PIDJOB,JOB)
; FIND THE JOB NUMBER OF A PID .
;12 CALL IPCCON(ERROR,10,CODE,FLAG,JOB,PIDCNT,PIDARR)
; FIND 1 OR MORE PIDS OF A JOB.
; PIDARR IS AN ARRAY THAT THE PIDS ARE LEFT IN.
; PIDCNT IS INITIALLY THE NUMBER OF ELEMENTS IN THE ARRAY, AND IS
; RETURNED AS THE NUMBER OF PIDS FOUND.
;13 CALL IPCCON(ERROR,11,CODE,FLAG,JOB,SND,RCV)
; FIND SEND AND RECEIVE QUOTAS OF A JOB.
;14 CALL IPCCON(ERROR,12,CODE,FLAG,JOB)
; UNBLOCK A JOB FROM RESET.
;24 CALL IPCCON(ERROR,20,CODE,FLAG,INDEX,PID)
; SET THE SPECIFIED INDEX IN THE SYSTEM PID TABLE
;25 CALL IPCCON(ERROR,20,CODE,FLAG,INDEX,PID)
; READ THE SPECIFIED ELEMENT FROM THE SYSTEM PID TABLE
IPCCON: FENTER (7)
PUSHJ P,SETINF ;SET UP SAVBLK
SKIPE T1,CONPID ;DO WE KNOW THE PID OF IPCC?
JRST STPID ;YES--PUT IN SAVBLK
MOVX T1,%IPCCP ;GETTAB TO FIND IT
GETTAB T1, ;DO SO
JRST [PUSHJ P,RETM2 ;IMPOSSIBLE UUO FAILURE
JRST XITCON]
MOVEM T1,CONPID ;WE'LL KNOW NEXT TIME
STPID: MOVEM T1,SAVBLK+2 ;STORE IN RECEIVER'S PID
MOVX T1,IP.CFP ;PRIVILEGE BIT
VSKIPE 0,3 ;SHOULD WE INVOKE PRIVILEGES?
IORM T1,SAVBLK ;YES--SET BIT
VMOVM T0,1 ;GET POSITIVE FUNCTION
SKIPE T0 ;FUNCTION = 0?
CAILE T0,25 ;LE 15?
JRST [PUSHJ P,RETM3 ;STORE ERROR
JRST XITCON] ;AND LEAVE ROUTINE
VHRL T0,2 ;GET USER SPECIFIED CODE
VMOVE T1,4 ;ALSO JOB NUMBER TO DO IT TO/FOR
DMOVEM T0,DBLK ;STORE
MOVEM T0,SAVCOD ;ALSO STORE FOR GETANS
HRRZ T1,T0 ;GET FUNCTION AGAIN
HRRZ T1,CONDIS-1(T1) ;GET WHERE TO GO
PUSHJ P,(T1) ;AND GO THERE.
XITCON: FEXIT (7)
SUBTTL CONDIS--ROUTINES TO HANDLE [SYSTEM]IPCC FUNCTIONS
;CREATE A PID. PID EXPECTED IN RETURN
MAKPID: HRRZS DBLK+1 ;JOB NUMBER IN RIGHT HALF
MOVSI T1,(1B0) ;PREPARE TO SET BIT
RSKIPE 0,6 ;SIGN OUT UNTIL LOGOUT?
IORM T1,DBLK+1 ;NO--UNTIL RESET
;SEND MESSAGE TO IPCC. PID OR JOB EXPECTED IN RETURN IN WORD 2
GJBGPD: PUSHJ P,SNDCON ;SEND THE MESSAGE TO IPCC
POPJ P, ;ERROR MAYBE
GETPID: MOVE T1,2(P1) ;GET PID RETURNED
RMOVEM T1,5 ;STORE IT
JRST GODRET ;AND GIVE A GOOD RETURN
;SEND MESSAGE TO IPCC. PID OR JOB EXPECTED IN RETURN IN WORD 1
GJBGIN: PUSHJ P,SNDCON ;SEND THE MESSAGE
POPJ P, ;DONE
GETIN: MOVE T1,1(P1) ;GET RESPONSE
RMOVEM T1,5 ;AND STORE
JRST GODRET
;SET QUOTAS FOR A JOB. NO ANSWER EXPECTED.
SETQOT: RMOVE T0,5 ;GET SEND QUOTA
RMOVE T1,6 ;GET RECEIVE QUOTA
ANDI T1,777 ;...
DPB T0,[POINT 9,T1,26] ;COMBINE THE 2
SGJOB: MOVEM T1,DBLK+2 ;AND STORE
GIVJOB: PUSHJ P,SNDCON ;SEND TO IPCC
POPJ P, ;RETURN
JRST GODRET ;SUCCESS
;CHANGE THE JOB NUMBER ASSOCIATED WITH A PID
CHGJOB: RMOVE T1,5 ;GET NEW JOB NUMBER
JRST SGJOB ;STORE T1 AND SEND MESSAGE
;FIND SEVERAL PIDS FOR A JOB NUMBER
GJGMPD: PUSHJ P,SNDCON ;SEND TO IPCC
POPJ P, ;RETURN
GETMPD: RMOVE P2,5 ;GET SIZE OF ARRAY
CAILE P2,-2(P3) ;LARGER THAN MESSAGE?
MOVEI P2,-2(P3) ;YES--LOOK ONLY AT MESSAGE
SETZ T0, ;CLEAR COUNTER
JUMPLE P2,RETPCN ;RETURN 0 IF NON-POSITIVE COUNT
RMOVEI P4,6 ;P4 IS ADDRESS OF ARRAY
MPDLOP: AOS T0 ;INCREMENT PID-COUNT
SKIPN T1,2(P1) ;IS THERE A NEXT PID?
SOJA T0,RETPCN ;YES--RETURN T0-1
MOVEM T1,(P4) ;STORE IN ARRAY
AOS P4 ;POINT TO NEXT ARRAY ELEMENT
CAME T0,P2 ;DONE ENOUGH?
AOJA P1,MPDLOP ;NO--TRY FOR SOME MORE
RETPCN: RMOVEM T0,5 ;STORE PID-COUNT
JRST GODRET ;GOOD RETURN
;FIND QUOTAS FOR A JOB
GJGQOT: PUSHJ P,SNDCON ;SEND MESSAGE
POPJ P, ;RETURN
GETQOT: LDB T1,[POINT 9,2(P1),35] ;GET RECEIVE QUOTA
RMOVEM T1,6 ;AND STORE IT
LDB T1,[POINT 9,2(P1),26] ;GET SEND QUOTA
RMOVEM T1,5 ;STORE THAT TOO
JRST GODRET ;RETURN
> ;END OF IFN IPCCRT
SUBTTL IPCGET--IPCF MISCELLANEOUS DATA
IFN IPCGTB,<
ENTRY IPCGET
;THIS ROUTINE RETURNS THE CONTENTS OF GETTAB TABLE 77.
;CALL: INTEGER COUNT,INFARR(0/9)
; CALL IPCGET(COUNT,INFARR)
;IF COUNT IS .LT. 0 OR .GT. 9, ALL ENTRIES IN THE TABLE WILL BE RETURNED.
;IF 0.LE.COUNT.LE.9, THEN ENTRIES 0-COUNT ARE RETURNED.
;COUNT IS RETURNED WITH THE NUMBER OF ENTRIES SUCCESSFULLY GOTTEN.
;N INFARR(N)
;0 MAXIMUM PACKET LENGTH
;1 PID OF SYSTEM-WIDE [SYSTEM]INFO
;2 DEFAULT QUOTA
;3 TOTAL PACKETS SENT SINCE RELOAD
;4 TOTAL PACKETS OUTSTANDING
;5 PID OF [SYSTEM]IPCC
;6 PID MASK
;7 LENGTH OF PID TABLE
;8 NUMBER OF PIDS NOW DEFINED
;9 TOTAL PIDS DEFINED SINCE RELOAD
IPCGET: FENTER (2)
RSKPLE P1,0 ;NEGATIVE COUNT?
CAILE P1,11 ;OR TOO BIG?
MOVEI P1,11 ;ONE OF THOSE.
RMOVEI T1,1 ;T1 = ADDRESS OF ARRAY
SETZ P2, ;P2=CURRENT ENTRY NUMBER
GETLOP: MOVEI T0,.GTIP C ;IPCF MISCELLANEOUS DATA TABLE
HRL T0,P2 ;ENTRY COUNT
GETTAB T0, ;FIND DATA
SOJA P2,XITGET ;RETURN COUNT
MOVEM T0,(T1) ;STORE
AOS T1 ;POINT TO NEXT ARRAY CELL
IFN IPCCRT,<
CAIN P2,5 ;IS THIS THE PID OF [SYSTEM]IPCC?
MOVEM T0,CONPID> ;YES--STORE IT
CAME P1,P2 ;ARE WE DONE?
AOJA P2,GETLOP ;NO--CARRY ON
XITGET: RMOVEM P2,0 ;STORE COUNT
FEXIT (2)
SUBTTL IPCGTJ--GET IPCF INFO FOR ANY JOB
ENTRY IPCGTJ
;THIS ROUTINE RETURNS THE IPCF INFORMATION FOR A JOB THAT CAN BE FOUND FROM
;GETTAB TABLES.
;CALL: INTEGER COUNT,INFARR(0/4),JOB
; CALL IPCGTJ(COUNT,INFARR,JOB)
;RETURNS:
;N TABLE# INFARR(N)
; 0 76 PROCESS COMMUNICATION ID
;1 104 IPCF STATISTICS
;2 105 IPCF POINTERS AND COUNTS
;3 106 PID OF JOB'S [SYSTEM]INFO
;4 107 IPCF FLAGS AND QUOTAS
IPCGTJ: FENTER (3)
RSKPLE P1,0 ;NEGATIVE COUNT?
CAILE P1,4 ;OR TOO MANY TABLES?
MOVEI P1,4 ;ONE OF THOSE.
RMOVEI T1,1 ;ARRAY ADDRESS IN RH(T1)
VHRL T1,2 ;JOB # IN LH(T1)
SETZ P2, ;TABLE COUNTER
GTLOP1: HRRZ T0,[ .GTPID
.GTIPA
.GTIPP
.GTIPI
.GTIPQ](P2) ;TABLE NUMBER
HLL T0,T1 ;AND JOB NUMBER
GETTAB T0, ;FIND THE INFO
SOJA P2,XITGTJ ;ERROR
MOVEM T0,(T1) ;STORE
AOS T1 ;INCREMENT ARRAY POINTER
CAME P1,P2 ;DONE?
AOJA P2,GTLOP1 ;NO-- CARRY ON
XITGTJ: RMOVEM P2,0 ;STORE FINAL COUNT
FEXIT (3)
> ;END OF IFN IPCGTB
SUBTTL IPCQER--QUERY STATUS OF INPUT QUEUE
ENTRY IPCQER
;THE FOLLOWING SUBROUTINE QUERIES THE STATUS OF THE IPCF INPUT QUEUE AND
;RETURNS THE INFORMATION IT FINDS.
;CALL: INTEGER ERROR,FLAGS,HISPID,MYPID,MESLEN,PPN,PRIVS,QUELEN
; CALL IPCQER(ERROR,FLAGS,HISPID,MYPID,MESLEN,QUELEN,PPN,PRIVS)
IPCQER: FENTER (^D8)
PUSHJ P,QUERY ;GET INFORMATION ABOUT TOP PACKET
JRST [PUSHJ P,ERRRET ;OOPS! GIVE AN ERROR
JRST XITQER]
IPCQR1: DMOVE T0,0(P2) ;GET FIRST 2 WORDS OF PACKET INFO
RMOVEM T0,1 ;FLAGS
RMOVEM T1,2 ;AND HIS PID
DMOVE T 0,2(P2) ;AND THE LAST 2 WORDS
RMOVEM T0,3 ;AND MY PID
RHLRZM T1,4 ;STORE THE LENGTH OF THE PACKET
RHRRZM T1,5 ;STORE THE NUMBER OF PACKETS IN THE QUEUE
IFE LANGUAGE,< ;FORTRAN
GETCOUNT(T2) ;GET ARG COUNT
CAIG T2,6 ;GTR 6 ARGS?
JRST XITQR1> ;NO--DON'T STORE EXTRAS. (WE MAKE THIS CHECK
; FOR COMPATIBILITY WITH OLD PROGRAMS)
DMOVE T0,4(P2) ;GET LAST TWO WORDS
RMOVEM T0,6 ;STORE PPN
RMOVEM T1,7 ;AND PRIVS
XITQR1: PUSHJ P,GODRET ;AND GIVE A GOOD RETURN
XITQER: FEXIT (^D8)
ENTRY IPCWQR
;THIS SUBROUTINE IS THE SAME AS IPCQER IF ANY PACKET EXISTS IN THE QUEUE.
;IF THE QUEUE IS EMPTY, THIS ROUTINE WILL WAIT UNTIL A PACKET ARRIVES
;AND THEN WILL FINISH AS IPCQER.
;CALL: INTEGER ERROR,FLAGS,HISPID,MYPID,MESLEN,QUELEN,PPN,PRIVS
; CALL IPCWQR(ERROR,FLAGS,HISPID,MYPID,MESLEN,QUELEN,PPN,PRIVS)
IPCWQR: FENTER (^D8)
IPCWQ1: PUSHJ P,QUERY ;FIND OUT ABOUT TOP PACKET
TRNA ;ERROR--SKIP
JRST IPCQR1 ;FINISH AS IF IPCQER
CAXE T1,IPCNP% ;PACKET NOT THERE ERROR?
JRST [PUSHJ P,ERRRET ;NO--WORSE ERROR
JRST XITQER]
MOVX T1,HB.IPC+HB.RWJ ;HIBERNATE WAKE ON IPCF. ONLY THIS
;JOB CAN WAKE ITSELF.
HIBER T1, ;GO TO SLEEP. IF A PACKET IS THERE ALREADY,
;WAKE UP IMMEDIATELY.
JRST [PUSHJ P,RETM2 ;IMPOSSIBLE UU O FAILURE.
JRST XITQER]
JRST IPCWQ1 ;QUERY THE QUEUE.
SUBTTL IPCSML--SEND A SMALL MESSAGE
IFN SMLMES,<
ENTRY IPCSML
;THIS ROUTINE ATTEMPTS TO SEND A BLOCK OF DATA AS A SMALL MESSAGE
;CALL: INTEGER ERROR,MYPID,HISPID,LENGTH,ADR
; CALL IPCSML(ERROR,MYPID,HISPID,LENGTH,ADR)
IPCSML: FENTER (5)
SETZ P1, ;NO FLAGS
VSKIPN P2,1 ;DID HE SPECIFY MY PID?
MOVE P2,PIDUS ;NO--USE THE ONE WE REMEMBERED
VMOVE P3,2 ;SET UP HIS PID.
VSKIPG P4,3 ;ACCEPT ONLY POSITIVE LENGTHS
JRST [PUSHJ P,RETM3 ;TELL HIM WE DON'T KNOW WHAT TO DO.
JRST XITSML]
HRLZS P4 ;PUT LENGTH IN LEFT HALF
RHRRI P4,4 ;GET ADDRESS OF MESSAGE
MOVE T1,[4,,P1] ;PREPARE TO SEND
IPCFS. T1, ;DO SO
JRST [PUSHJ P,ERRRET ;STORE ERROR
JRST XITSML]
PUSHJ P,GODRET ;GOOD RETURN
XITSML: FEXIT (5)
> ;END OF IFN SMLMES
SUBTTL IPCSND--SEND A PAGE OF INFORMATION
IFN PAGMES,<
ENTRY IPCSND
;THE FOLLOWING ROUTINE WILL PACK A PAGE WITH BLOCKS OF DATA AND SEND IT TO
;WHOEVER IS SPECIFIED AS THE RECEIVER.
;CALL: INTEGER ERROR,MYPID,HISPID,FLAG,PAGCNT,LEN1,LEN2,...LENN
; CALL IPCSND(ERROR,MYPID,HISPID,FLAG,PAGCNT,LEN1,ADR1,LEN2,ADR2,...LENN,ADRN)
;ANY NUMBER OF BLOCKS OF DATA MAY BE PACKED ON THE PAGE.
;IF FLAG IS 0, ONLY ONE PAGE WILL BE SENT. IE, IF TH E TOTAL LENGTH
;IS GREATER THAN 512(DECIMAL) ONLY THE FIRST 512 WORDS WILL BE SENT.
;IF FLAG IS NON-0, AS MANY PAGES WILL BE SENT AS ARE NEEDED.
;PAGCNT IS RETURNED WITH THE NUMBER OF PAGES SENT SUCCESSFULLY.
;MYPID IS OPTIONAL. IF 0, THE PID MOST RECENTLY INITIALIZED WILL BE USED.
IPCSND: FENTER (7)
RSETZM 4 ;CLEAR PAGE COUNTER
IFN LANGUAGE,< ;IF NOT FORTRAN, CHECK IF WE HAVE ANYTHING TO DO
VSKIPG 0,5 ;LENGTH GTR 0?
JRST GODSND> ;NO--GIVE A GOOD RETURN
PUSHJ P,ALLCPG ;GET A PAGE--RETURN NUMBER IN P4
JRST XITSND ;NONE AVAILABLE.
MOVX P1,IP.CFV ;FLAG TO INDICATE PAGE MODE IPCF SEND.
VSKIPN P2,1 ;IS MY PI D SPECIFIED?
MOVE P2,PIDUS ;NO--USE THE ONE WE REMEMBERED
VMOVE P3,2 ;GET PID OF DESIRED RECEIVER
HRLI P4,1000 ;LENGTH OF MESSAGE IS 512 WORDS
DMOVEM P1,SAVBLK ;STORE 1ST 2 WORDS OF PACKET
DMOVEM P3,SAVBLK+2 ;AND THE LAST 2 WORDS
LSH P4,11 ;CONVERT PAGES TO WORDS
MOVEI P2,1000 ;HOW MANY WORDS ARE ALLOWED
IFE LANGUAGE,< ;FORTRAN?
MOVE P3,-1(ARGS) ;GET -ARG COUNT,,0
HRR P3,ARGS ;P3 IS NOW AN AOBJN POINTER
ADD P3,[5,,5] ;POINT TO FIRST LENGTH
GETARG: MOVE P1,@0(P3) ;GET LENGTH IN P1
MOVEI T0,@1(P3) ;AND ADDRESS OF ARRAY IN T0
JUMPLE P1,NXTARG ;IF LENGTH LEQ 0, LOOK AT NEXT ARG
> ;END OF IFE LANGUAGE ;F ORTRAN
IFN LANGUAGE,< ;NOT FORTRAN?
VMOVE P1,5 ;GET NUMBER OF WORDS TO SEND
RMOVEI T0,6 ;AND THE ADDRESS WHERE THEY RESIDE
> ;END OF IFN LANGUAGE ;NOT FORTRAN
PUSHJ P,PCKMSG ;PACK THE ARGUMENT ONTO THE PAGE
JRST XITSND ;FAILURE, FOR SOME REASON
IFE LANGUAGE,< ;FORTRAN
NXTARG: AOBJN P3,.+1 ;POINT TO NEXT ARGS
AOBJN P3,GETARG ;AND PROCESS THEM, TOO
> ;END OF IFE LANGUAGE
PUSHJ P,SNDPAG ;SEND THE PAGE!
JRST XITSND ;NO?
GODSND: PUSHJ P,GODRET ;GOOD RETURN
XITSND: FEXIT (7)
PCKMSG: JUMPLE P2,SNDCHK ;IF NO ROOM ON PAGE, SEE IF SHOULD SEND MESSAGE
HRRZ T1,P1 ;GET # OF WORDS IN ARGUMENT
CAMLE T1,P2 ;ROOM ON PAGE?
MOVE T1,P2 ;NO--ONLY FILL UP PAGE
HRRZ T2,P4 ;RH(T2) = DESTINATION ADDRESS
HRL T2,T0 ;LH(T2) = SOURCE ADDRESS
MOVE T3,T1 ;T3 IS # OF WORDS WE WILL TRANSFER
ADDI T3,-1(P4) ;NOW T3 IS ADR OF LAST WORD TO TRANSFER INTO
BLT T2,(T3) ;TRANSFER THE WORDS!
SUB P2,T1 ;DECREASE # OF WORDS REMAINING ON PAGE
SUB P1,T1 ;AND # OF WORDS REMAINING IN ARGUMENT
ADD P4,T1 ;INCREASE ADDRESS OF FREE SPACE ON PAGE
ADD T0,T1 ;AND ADDRESS OF ARG
SNDCHK:
IFN SNDMUL,< ;IF WE WILL SEND MULTIPLE PAGES...
SKIPLE P1 ;COPIED WHOLE ARG?
VSKIPN 0,3 ;NO--DOES USER WANT US TO SEND SEVERAL PAGES?
> ;END OF IFN SND MUL
JRST .POPJ1 ;WHOLE ARG OR DON'T CONTINUE--GIVE GOOD RETURN
IFN SNDMUL,< ;IF WE SEND MULTIPLE PAGES....
MOVE P2,T0 ;SAVE ADDRESS OF PARTIAL ARG
PUSHJ P,SNDPAG ;SEND THE PAGE!
POPJ P, ;FAILURE?
PUSHJ P,ALLCPG ;GET A NEW PAGE
POPJ P, ;WHAT??? WE JUST RELEASED A PAGE!
HRRM P4,SAVBLK+3 ;STORE NEW PAGE NUMBER
LSH P4,11 ;MAKE INTO A PAGE ADDRESS
MOVE T0,P2 ;RESTORE ADDRESS OF ARGUMENT
MOVEI P2,1000 ;1000 FREE WORDS ON THIS PAGE
JRST PCKMSG ;CONTINUE SENDING THIS ARGUMENT
> ;END OF IFN SNDMUL
SNDPAG: MOVE T1,[4,,SAVBLK]
IPCFS. T1, ;SEND THE PAGE!
JRST [PUSHJ P,ERRRET ;FAILED. STORE THE ERR OR CODE
PUSHJ P,KILPAG ;DELETE THE PAGE WE CREATED
POPJ P,] ;GIVE NON-SKIP RETURN
RAOS 4 ;INCREMENT COUNT OF SUCCESSFUL SENDS
JRST .POPJ1 ;AND GIVE A SKIP RETURN
ALLCPG: PUSHJ P,GETPAG ;GET A PAGE TO USE
JRST RETM2 ;NONE AVAILABLE?
MOVEI T2,1 ;ONE ARGUMENT
MOVE T3,P4 ;COPY PAGE NUMBER
MOVE T1,[.PAGCD,,T2] ;AC FOR PAGE. UUO
PAGE. T1, ;GET THE PAGE!
TRNA ;COULD NOT--TRY TO GET THE PAGE ON DISK
JRST .POPJ1 ;SUCCESS. SKIP RETURN WITH PAGE# IN P4
TLO T3,(1B1) ;SET BIT TO GET PAGE ON DISK
MOVE T1,[.PAGCD,,T2] ;RESET PAGE. UUO AC
PAGE. T1, ;AND ALLOCATE THAT PAGE!
JRST RETM2 ;COULD NOT.
JRST .POPJ1 ;SUCCESS. SKIP RETURN WITH PAGE # IN P4
> ;END OF IFN PAGMES
SUBTTL IPCRCV--RECEIVE A MESSAGE
ENTRY IPCRCV
;THE FOLLOWING ROUTINE WILL RECEIVE A MESSAGE AND UNPACK IT INTO BLOCKS
;WHERE EVER THE USER SPECIFIES.
;CALL: INTEGER ERROR,MYPID,HISPID,FLAG,OFFSET,LEN1,LEN2,LEN3,...LENN
; CALL IPCRCV(ERROR,MYPID,HISPID,FLAG,OFFSET,LEN1,ADR1,LEN2,ADR2...LENN,ADRN)
;MYPID AND HISPID ARE RETURNED.
;OFFSET IS THE WORD IN THE MESSAGE TO START AT (0-777).
;IF FLAG IS NON-0, THE MESSAGE WILL BE SAVED AFTER THIS ROUTINE
IPCRCV: FENTER (7)
SKIPE SAVNUM ;ARE WE SAVING A MESSAGE?
JRST [ MOVE T1,SVMES1 ;GET ADDRES S OF INFO OF FIRST MESSAGE.
HRRZ P1,(T1) ;GET ADDRESS
HLRZ P3,4(T1) ;LENGTH OF MESSAGE.
DMOVE T0,2(T1) ;GET PIDS IN T0 AND T1
JRST ARDSV1] ;AND FINISH
PUSHJ P,GETMES ;GET THE MESSAGE
JRST XITRCV ;COULDN'T
DMOVE T0,SAVBLK+1 ;GET THE PIDS IN T0, T1
ARDSV1: PUSHJ P,DORCV ;RECEIVE THE MESSAGE
VSKIPN 0,3 ;WE'VE DONE IT. SHALL WE SAVE IT?
JRST NOSAVE ;NO--DELETE IT.
SKIPE SAVNUM ;ALREADY SAVING A MESSAGE?
JRST XITRCV ;YES--THIS MESSAGE MUST BE ALREADY SAVED
PUSHJ P,SAVMES ;NO--SAVE THIS MESSAGE.
JRST XITRCV ;SOME ERROR. ALREADY RETURNED CODE.
XITRCV: FEXIT (7)
NOSAVE: SKIPE SAVNUM ;WERE WE SAVING A MESSAGE?
JRST [ PUSHJ P,IPCDS1 ;YES--DELETE IT
JRST XITRCV]
IFN FTVM,<
JUMPN P4,[PUSHJ P,KILPAG ;DELETE ANY PAGE WE CREATED
JRST XITRCV]
> ;END OF IFN FTVM
CAIN P1,DBLK ;NO--IS THE MESSAGE AT DBLK?
JRST XITRCV ;YES--WE ARE DONE
HRRZ T1,P1 ;NO--MUST RETURN CORE. T1<--ADDRESS
HRRZ T2,P3 ;T2<--WORD COUNT
PUSHJ P,RETCOR
JRST XITRCV
DORCV: PUSHJ P,.SAVE4 ;SAVE FOR SAVMES
RMOVEM T1,1 ;STORE MY PID
RMOVEM T0,2 ;STORE HIS PID
VSKIPG T1,4 ;GOOD OFFSET?
JRST NOOFF ;NOPE.
SUB P3,T1 ;LESS NUMBER OF WORDS IN OFFSET
ADD P1,T1 ;START AT BEGINNING+OFFSET
JUMPLE P3,GODRET ;MAYBE WE AR E DONE.
NOOFF:
IFE LANGUAGE,< ;FORTRAN? (ONLY LANG WITH VARIABLE # OF ARGS)
MOVE P4,-1(ARGS) ;LH(P4) = - ARG COUNT
HRR P4,ARGS ;P4 IS NOW AOBJN POINTER TO ARG LIST
ADD P4,[5,,5] ;SKIP 5 ARGS
JUMPGE P4,GODRET ;RETURN NOW IF NONE SPECIFIED
RCVLOP: MOVE T4,@(P4) ;T4=HOW MANY WORDS ARE DESIRED THIS TIME
MOVEI T0,@1(P4) ;RH(T0)=ADDRESS OF WHERE MESSAGE GOES
JUMPLE T4,NXRSPC ;DO SOMETHING
> ;END OF IFE LANGUAGE ;FORTRAN?
IFN LANGUAGE,< ;NOT FORTRAN?
VMOVE T4,5 ;GET # OF WORDS TO TRANSFER
RMOVEI T0,6 ;AND WHERE TO PUT THEM
JUMPLE T4,GODRET ;LEAVE, IF NOTHING TO DO
> ;END OF IFN LANGUAGE ;NOT FORTRAN?
CAMLE T4,P3 ;ARE THERE THAT MANY WORDS?
MOVE T4,P3 ;NO--STORE ONLY AS MANY AS THERE ARE.
HRRZ T1,T0 ;SAME FOR T1
SOS T1 ;-1
HRL T0,P1 ;T0=WHERE WORDS ARE,,WHERE THEY GO
HRLI T1,(BLT T0,(T4)) ;T1 IS A BLT INSTRUCTION
XCT T1 ;DO IT
IFE LANGUAGE,< ;FORTRAN?
ADD P1,T4 ;UPDATE POINTER TO WHERE WORDS ARE
SUB P3,T4 ;COUNT DOWN WORDS REMAINING
JUMPLE P3,GODRET ;DONE RECEIVING IF NONE LEFT
NXRSPC: AOBJN P4,.+1 ;POINT TO NEXT ARGS
AOBJN P4,RCVLOP ;IF ANY
> ;END OF IFE LANGUAGE ;FORTRAN?
PJRST GODRET ;RETURN
SUBTTL IPCDIS--DISCARD A PACKET
ENTRY IPCDIS
;THE FOLLOWING ROUTINE DISCARDS THE TOP PACKET IN THE QUEUE.
;CALL: INTEGER ERROR
; CALL IPCDIS(ERROR)
;OTHER ENTRIES (FOR INTERNAL USE ONLY):
; PUSHJ P,IPCDS1 ;DELETE NEXT SAVED OR UNSAVED MESSAGE
; PUSHJ P,IPCDSC ;DELETE NEXT UNSAVED MESSAGE
IPCDIS: FENTER (1)
PUSHJ P,IPCDS1 ;DISCARD THE MESSAGE
FEXIT (1)
IPCDS1: SKIPN SAVNUM ;SAVING A PACKET?
JRST IPCDSC ;NO--BETTER FIND ABOUT TOP ONE
MOVE P1,SVMES1 ;GET ADDRESS OF 1ST SAVED PACKET INFO IN P1.
HRRZ T1,(P1) ;GET ADDRESS OF SAVED MESSAGE
HLRZ T2,4(P1) ;AND IT'S LENGTH
PUSHJ P,RETCOR ;RETURN THE CORE
CAIL P1,MESTAB+<NUMMES*7>-7 ;ARE WE ON THE LAST SLOT?
MOVEI P1,MESTAB-7 ;YES--NEXT IS 1ST SLOT
ADDI P1, 7 ;POINT TO NEXT
MOVEM P1,SVMES1 ;SAVE NEW POINTER
SOS SAVNUM ;DECREMENT COUNT OF SAVED MESSAGES
JRST GODRET ;AND GIVE A GOOD RETURN
IPCDSC: MOVE T1,[4,,P1] ;READ PACKET INTO P1-4
IPCFQ. T1, ;QUERY THE QUEUE
JRST ERRRET ;WHAT?
IFN KLUDGE,<
JUMPE P4,RET3> ;PAGE NOT THERE ERROR?
TXO P1,IP.CFT ;NO--FLAG TO READ AS MUCH AS WILL FIT
MOVEI P4,DBLK ;0 WORDS AT DBLK
IPCFR. T1, ;GET THE MESSAGE
JRST ERRRET ;SHOULDN'T HAPPEN, BUT...
JRST GODRET ;GOOD RETURN
SUBTTL IPCERR--TYPE AN ERROR MESSAGE
IFG TYPERR,<
ENTRY IPCERR
;THE FOLLOWING ROUTINE TYPES A MESSAGE IDENTIFYING AN ERROR RETURNED BY
; ANY OF THE ABOVE ROUTINES
;CALL: INTEGER ERROR
; CALL IPCERR(ERROR)
IPCERR: FENTER (1)
VMOVE T1,0 ;GET ERROR CODE
MOVM T0,T1 ;GET POSITIVE ERROR
TLNE T0,-1 ;ANYTHING IN LEFT HALF?
MOVEI T1,0 ;YES--IPCF MUST NOT BE IMPLEMENTED
OUTCHR ["?"] ;ERROR PREFIX CHAR
CAIL T1,INFERR ;SEE IF INFO ERROR
CAILE T1,77 ; (RANGE INFERR TO 77)
JRST IPCER1 ;NO--TRY NORMAL IPCF ERROR
SUBI T1,INFERR-MAXERR-1 ;YES--REMOVE TABLE OFFSET
JRST IPCER2 ;AND ISSUE MESSAGE
IPCER1: CAIG T1,MAXERR ;DO WE UNDERSTAND THIS ERROR?
CAMGE T1,[MINERR] ;CHECK LOWER BOUND
JRST UNKERR ;NO--HANDLE SEPERATELY
IPCER2: OUTSTR @ERRTBL(T1) ;T YPE MESSAGE FOLLOWED BY A CRLF
IPCERT: OUTSTR [ASCIZ \.
\]
FEXIT (1) ;RETURN
UNKERR: OUTSTR [ASCIZ \Unknown IPCF error code \]
MOVE T0,T1 ;ERROR CODE TYPED FROM T0
PUSHJ P,TYPOCT ;TYPE ERROR CODE IN OCTAL
JRST IPCERT
;TABLE OF ERROR MESSAGES
ETBSTR: [ASCIZ \No room to store message\]
[ASCIZ \Message not from INFO or IPCC\]
[ASCIZ \Message not from INFO\]
[ASCIZ \Unknown function\]
[ASCIZ \Impossible UUO failure\]
[ASCIZ \Unkown receiver\]
MINERR==ETBSTR-.
ERRTBL: [ASCIZ \IPCF not implemented\]
[ASCIZ \Address check\]
[ASCIZ \UUO block not long enough\]
[ASCIZ \No packet in queue\]
[ASCIZ \P age in use\]
[ASCIZ \Data too long for buffer\]
[ASCIZ \Destination unknown\]
[ASCIZ \Destination disabled\]
[ASCIZ \Sending quota exceeded\]
[ASCIZ \Receiving quota exceeded\]
[ASCIZ \System storage exceeded\]
[ASCIZ \Unknown page (send), existing page (receive)\]
[ASCIZ \Invalid sender\]
[ASCIZ \Insufficient privileges\]
[ASCIZ \Unknown function\]
[ASCIZ \Bad job number\]
[ASCIZ \PID table full\]
[ASCIZ \Page requested with non-page packet next\]
[ASCIZ \Paging i/o error\]
[ASCIZ \Bad index into system PID table\]
[ASCIZ \Undefined ID in system PID table\]
MAXERR==.-ERRTBL-1 ;HIGHEST KNOWN ERROR CODE
[ASCIZ \INFO had an internal error\]
[ASCIZ \INFO ran into an IPCF rejection\]
[ASCIZ \INFO failed to complete an assign\]
[ASCIZ \INFO ran out of PIDs\]
[ASCIZ \INFO could not identify the PID\]
[ASCIZ \INFO found a duplicate name\]
[ASCIZ \INFO knew of no such name\]
[ASCIZ \INFO determined that name has illegal characters\]
INFERR==100-<.-<ERRTBL+MAXERR+1>> ;FIRST INFO ERROR
> ;END OF IFG TYPERR
IFL TYPERR,<
ENTRY IPCERR
;THE FOLLOWING ROUTINE TYPES A MESSAGE INDENTIFYING NUMERICALLY AN IPCF ERROR.
;CALL: INTEGER ERROR
; CALL IPCERR(ERROR)
IPCERR: FENTER (1)
VMOVE T0,0 ;GET ERROR CODE IN T1
OUTSTR [ASCIZ \?IPCF error code \]
PUSHJ P,TYPOCT ;TYPE T1 IN OCTAL
OUTSTR [ASCIZ \.
\]
FEXIT (1) ;RETURN
> ;END OF IFL TYPERR
IFN TYPERR,<
;THE FOLLOWING ROUTINE TYPES THE NUMBER IN T0 IN OCTAL.
TYPOCT: JUMPGE T0,TYPOC1 ;JUMP IF NON-NEGATIVE
MOVMS T0 ;ELSE, GET MAGNITUDE
OUTCHR ["-"] ;AND ISSUE A MINUS SIGN.
TYPOC1: IDIVI T0,10 ;DIVIDE BY 8
HRLM T1,(P) ;SAVE REMAINDER
SKIPE T0 ;DONE?
PUSHJ P,TYPOC1 ;NO--REPEAT
HLRZ T1,(P) ;RESTORE A DIGIT
ADDI T1,"0" ;CONVERT TO ASCII
OUTCHR T1 ;TYPE IT
POPJ P, ;AND RETURN TO WHERE YOU CAME FROM
> ;END OF IFN TYPERR
SUBTTL LOW LEVEL CORE ALLOCATION R OUTINES
;GETCOR--ALLOCATE A BLOCK OF CORE. ACCEPTS # OF WORDS TO ALLOCATE IN T2,
;AND RETURNS ADDRESS OF A BLOCK THAT SIZE IN T1 (T2 UNHARMED)
;SKIP RETURN IF SUCCESS, NON-SKIP IF NO CORE AVAILABLE
;RETCOR--DEALLOCATE A BLOCK OF CORE. ACCEPTS T1=ADDRESS OF BLOCK, T2 = SIZE
;OF BLOCK. ALWAYS NON-SKIP RETURN.
IFE CORMAN,< ;USE LANGUAGE SPECIFIC CORE ALLOCATION
IFE LANGUAGE,< ;FORTRAN
GETCOR: MOVEI T1,6 ;FUNCTION 6 IS GET CORE
MOVEM T1,FUNCT ;STORE IN FUNCTION VARIABLE
MOVEM T2,ARG2 ;STORE REQUESTED # OF WORDS
PUSHJ P,CALFNC ;CALL FUNCT.
POPJ P, ;ERROR
MOVE T1,ARG1 ;GET ADDRESS OF CORE
JRST .POPJ 1 ;AND GIVE A SKIP RETURN
RETCOR: MOVEM T1,ARG1 ;STORE ADDRESS OF CORE
MOVEM T2,ARG2 ;AND HOW MANY WORDS
MOVEI T1,7 ;FUNCTION 7 IS RETURN CORE
MOVEM T1,FUNCT
PUSHJ P,CALFNC ;CALL FUNCT.
POPJ P, ;ERROR
POPJ P, ;OK
CALFNC: PUSH P,ARGS ;SAVE REG 16
MOVEI ARGS,FRGLST ;POINT TO FUNCT. ARG LIST
PUSHJ P,FUNCT.## ;CALL OTS!
POP P,ARGS ;RESTORE ARG POINTER
SKIPN STATUS ;SUCCESS?
AOS (P) ;YES--SET UP SKIP
POPJ P, ;RETURN
-5,,0
FRGLST: ARG 2,FUNCT ;FUNCTION
ARG 2,ERROR ;ERROR MESSAGE
ARG 2,STATUS ;RETURNED STATUS
ARG 2,ARG1 ;FIRST ARGUMENT
ARG 2,ARG2 ;SECOND ARGUMENT
> ;END OF IFE LANGUAGE ;FORTRAN
IFE LANGUAGE-1,< ;SAIL
GETCOR: PUSH P,3 ;SAVE REGISTER 3
MOVE 3,T2 ;PLACE REQUESTED WORDS INTO IT
PUSHJ P,CORGET## ;GET THAT MUCH CORE!
JRST [POP P,3 ;RESTORE REG 3
POPJ P,] ;AND GIVE NON-SKIP RETURN
MOVE T1,2 ;COPY ADDRESS INTO T1
MOVE T2,3 ;RESTORE WORD COUNT INTO T2
POP P,3 ;RESTORE REG 3
JRST .POPJ1 ;AND GIVE A SKIP RETURN
RETCOR: PUSH P,2 ;SAVE REGISTER 2
MOVE 2,T1 ;STORE ADDRESS OF CORE BLOCK TO RETURN
PUSHJ P,CORREL## ;RELEASE THE CORE!
POP P,2 ;RESTORE REGISTER 2
POPJ P, ;AND RETURN
> ;END OF IFE LANGUAGE-1 ;SAIL
> ;END OF IFE CORMAN
IFN CORMAN,< ;DOI NG OWN CORE ALLOCATION...
;IF WE DO OUR OWN CORE MANAGEMENT, A VERY SIMPLE SCHEME IS USED:
; IF A SIMPLE FIRST FIT SEARCH ON THE FREE CHAIN FINDS A SUITABLE BLOCK, IT
;IS REMOVED FROM THE FREE CHAIN AND ITS ADDRESS IS RETURNED TO THE USER. ELSE,
;IF THE USER REQUESTS N WORDS, N+1 ARE ALLOCATED AT .JBFF. THE 0 WORD CONTAINS
;<SIZE OF BLOCK,,NEXT BLOCK IN FREE CHAIN>. THE ADDRESS OF THE 1ST WORD IS RETURNED
;TO THE USER
GETCOR: PUSHJ P,CHKLST ;IS THERE A SUITABLE BLOCK IN THE FREE-CORE LIST?
JRST .POPJ1 ;YES--T1 ALREADY SET UP. GIVE A SKIP RETURN
MOVE T1,.JBFF## ;NO--GET FIRST FREE LOC AT END OF CORE
ADD T1,T2 ;POINT TO LAST DESIRED WORD
CAMG T1,.JBREL## ;HAVE ENOUGH CORE?
JRST HAVCOR ;YES--SKIP UUO
PUSH P,T1 ;SAVE LAST WORD'S ADR
CORE T1, ;ALLOCATE MORE CORE
JRST [POP P,T1 ;RESTORE T1
POPJ P,] ;AND GIVE NON-SKIP RETURN
POP P,T1 ;RESTORE T1
HAVCOR: EXCH T1,.JBFF## ;STORE ADR(LAST WORD) & GET ADR(FIRST WORD)
AOS .JBFF## ;.JBFF NOW POINTS TO FIRST FREE WORD
HRLZM T2,(T1) ;STORE SIZE OF BLOCK IN FIRST WORD
AOJA T1,.POPJ1 ;POINT TO FIRST WORD USER SEES, AND GIVE SKIP RETURN
CHKLST: SKIPN T1,FRECOR ;IS THERE A FREE CORE LIST?
JRST .POPJ1 ;NO--GIVE SKIP RETURN
PUSH P,T3 ;BE NICE AND SAVE TEMP AC'S NEEDED
PUSH P,T4
MOVEI T3,FRECOR+1 ;PRETEND ADR IN T1 IS CORE BLOCK LIKE WE CREATE
CORLOP: HLRZ T4,-1(T1) ;GET SIZE OF THIS CORE BLOCK
CAML T4,T2 ;BIG ENOUGH?
JRST [ HRRZ T4,-1(T1) ;YES--GET ADR(NEXT CORE BLOCK)
HRRM T4,-1(T3) ;AND STORE IN PREVIOUS BLOCK'S LINK
POP P,T4 ;RESTORE TEMPORARIES
POP P,T3
POPJ P,] ;AND GIVE A NON-SKIP RETURN
MOVE T3,T1 ;NO--SAVE POINTER TO PREVIOUS BLOCK
HRRZ T1,-1(T1) ;AND GET NEW CURRENT BLOCK
JUMPN T1,CORLOP ;IF IT EXISTS...
POP P,T4 ;NOTHING IN CORE LIST IS SUITABLE. RESTORE TEMPS
POP P,T3
JRST .POPJ1 ;AND GIVE A SKIP RETURN
RETCOR: HRRZ T2,FRECOR ;GET POINTER TO PR EVIOUS 1ST AVAILABLE CORE BLOCK
HRRM T2,-1(T1) ;STORE IN NEXT FIELD OF THIS BLOCK
HRRZM T1,FRECOR ;AND STORE POINTER TO THIS BLOCK IN FRONT OF LIST
POPJ P, ;RETURN
ENTRY IPCINI ;MUST ALSO PROVIDE A ROUTINE TO INITIALIZE FRECOR
IPCINI::SETZM FRECOR ;FORGET WHAT WE THINK WE KNOW
IFN LANGUAGE-2,< ;NOT BLISS?
POPJ P,> ;RETURN THROUGH P
IFE LANGUAGE-2,< ;BLISS?
POPJ SREG,> ;RETURN THROUGH SREG
> ;END OF IFN CORMAN
SUBTTL COMMON ROUTINES FOR INTERNAL USE ONLY
;THE FOLLOWING ROUTINE STORES ITS RETURN ADDRESS ON THE STACK AND
;SAVES P1-P4. A POPJ WILL RETURN TO RET4 WHICH WILL RESTORE THE AC'S
;AND RETURN TO THE CALLING PROGRAM.
;BORROWED FROM SCAN %7(535)
.SAVE4: EXCH P1,(P) ;SAVE P1, GET CALLER PC
HRLI P1,(P) ;GET ADDRESS WHERE P1 IS SAVED
PUSH P,P2 ;SAVE P2
PUSH P,P3 ;SAVE P3
PUSH P,P4 ;SAVE P4
PUSHJ P,SAVJMP ;STACK NEW RETURN PC AND JUMP
POP P,P4 ;RESTORE P4
POP P,P3 ;RESTORE P3
POP P,P2 ;RESTORE P2
POP P,P1 ;RESTORE P1
POPJ P, ;AND RETURN
;THE FOLLOWING INSTRUCTION RESTORES P1 AND DISPATCHES TO THE CALLER
SAVJMP: JRA P1,(P1) ;RETURN TO CALLER
;ERROR RETURNING
RETM6: SKIPA T1,[-6] ;-6 ERROR RETURN MEANS COULD NOT SAVE MESSAGE.
RETM5: MOVNI T1,5 ;-5 ERROR RETURN MEANS MESSAGE NOT FROM I NFO OR IPCC.
JRST ERRRET
RETM4: SKIPA T1,[-4] ;-4 ERROR RETURN MEANS MESSAGE NOT FROM INFO
RETM3: MOVNI T1,3 ;-3 ERROR RETURN MEANS UNKNOWN FUNCTION
JRST ERRRET ;ISSUE IT
RETM2: SKIPA T1,[-2] ;-2 ERROR RETURN MEANS IMPOSSIBLE UUO FAILURE
RETM1: MOVNI T1,1 ;-1 ERROR RETURN MEANS UNKNOWN NAME
ERRRET: RMOVEM T1,0 ;STORE ERROR CODE
POPJ P, ;RETURN
IFN KLUDGE,<
RET3: MOVEI T1,3
JRST ERRRET
> ;END OF IFN KLUDGE
;THE FOLLOWING ROUTINE SENDS A MESSAGE TO [SYSTEM]INFO
;AND OPTIONALLY RECEIVES AN ANSWER.
;RETURNS WITH P1=ADDRESS OF MESSAGE AND P3=# OF WORDS IN MESSAGE.
SNDCON: SETOM INFIND ;-1 MEANS ANSWER FRO M IPCC
TRNA ;AND SKIP
SNDINF: SETZM INFIND ;0 MEANS ANSWER FROM INFO
MOVE T1,[6,,SAVBLK] ;POINTER TO SEND BLOCK
IPCFS. T1, ;SEND THE MESSAGE TO INFO
JRST ERRRET ;COULDN'T
VSKPLE 0,1 ;SHOULD WE WAIT FOR AN ANSWER?
JRST GODRET ;NO--RETURN NOW
GETANS: MOVE T1,[6,,SAVBLK] ;PREPARE TO QUERY QUEUE
IPCFQ. T1, ;DO SO
JRST INFWAT ;WELL, WE ARE PROBABLY FASTER THAN INFO.
IFN KLUDGE,<
SKIPN SAVBLK+3 ;IS THERE REALLY A MESSAGE?
JRST WTINF> ;NO--GO WAIT FOR INFO
LDB T0,[POINT 3,SAVBLK,32] ;GET SENDER'S CODE
CAIE T0,.IPCCF ;SEE IF FROM SYSTEM [SYSTEM]INFO
CAIN T0,.IPCCP ; OR IF FROM LOCAL [SYSTEM]INFO
SKIPE INFIND ;WAITING FOR INFO?
JRST CHKCON ;YES--RECEIVE MESSAGE AND CHECK IT OUT
CHKMES: PUSHJ P,GETMES ;GET THE MESSAGE
POPJ P, ;COULDN'T
MOVE T1,(P1) ;GET FIRST WORD
CAMN T1,SAVCOD ;IS IT WHAT WE EXPECT?
JRST [ LDB T1,[POINT 6,SAVBLK,29] ;YES--SEE IF AN ERROR WAS RETURNED
JUMPN T1,ERRRET ;IF SO, INFORM USER
JRST .POPJ1] ;NONE--GIVE GOOD RETURN
PUSHJ P,SAVMES ;WRONG MESSAGE--SAVE IT
POPJ P, ;COULDN'T
JRST GETANS ;NO--TRY AGAIN
CHKCON: CAIN T0,.IPCCC ;NOT INFO. IPCC?
SKIPN INFIND ;YES. DO WE WANT TO HEAR FROM HIM?
TRNA ;NO...
JRST CHKMES ;YES--CHECK IT OUT.
PUSHJ P,GETMES ;GET T HE MESSAGE
POPJ P, ;COULDN'T
PUSHJ P,SAVMES ;AND SAVE IT
POPJ P, ;COULDN'T
JRST GETANS ;AND REPEAT.
INFWAT: CAXE T1,IPCNP% ;PACKET NOT THERE ERROR?
JRST ERRRET ;NOPE--RETURN
WTINF: MOVX T1,HB.IPC+HB.RWJ ;SLEEP UNTIL INFO CALLS
HIBER T1, ;DO IT
JRST RETM2 ;SET ERROR=-2 AND DO A NON-SKIP RETURN.
JRST GETANS ;TRY AGAIN
;THE FOLLOWING ROUTINE SETS UP P1 AS THE ADDRESS OF THE NEXT MESSAGE IN THE QUEUE
;AND P2 AS THE ADDRESS OF THE QUEUE INFO BLOCK. (UNLESS MESSAGES ARE BEING
;SAVED, THESE WILL ALWAYS BE DBLK AND SAVBLK, RESPECTIVELY.)
;IT WILL QUERY THE QUEUE IF NECESSARY AND DO A SKIP RETURN IF A LL OK.
QUERY: SKIPN SAVNUM ;SAVING A MESSAGE?
JRST FINDOU ;NO--FIND OUT ABOUT A NEW ONE
HRRZ P2,SVMES1 ;PACKET INFO ADDRESS IN P2
HRRZ P1,(P2) ;PAGE ADDRESS IN P1
AOJA P2,.POPJ1 ;POINT TO QUEUE INFO AND RETURN
FINDOU: MOVE T1,[6,,SAVBLK] ;PREPARE TO GET QUEUE INFO AT SAVBLK
IPCFQ. T1, ;DO IT.
POPJ P, ;ERROR
IFN KLUDGE,<
SKIPN SAVBLK+3 ;IS THERE REALLY A PACKET?
JRST RET3> ;NO.
MOVEI P1,DBLK ;DBLK MAY BE WHERE THE PACKET WILL GO
MOVEI P2,SAVBLK ;SAVBLK IS WHERE THE QUEUE INFO IS
.POPJ1: AOS (P) ;DO A SKIP RETURN
.POPJ: POPJ P, ;RETURN
;THE FOLLOWING ROUTINE WILL FIND OUT IF THE TOP PACKET IS FROM [SYSTEM]INFO
;OR [SYSTEM]IPCC. NON-SKIP WITH 0(ARGS)SET IF NEITHER, SKIP IF IPCC, DOUBLE
;SKIP IF INFO. T0 IS WHO FIELD.
INFCHK: PUSHJ P,QUERY ;FIND OUT ABOUT TOP PACKET
JRST ERRRET ;COULDN'T
LDB T0,[POINT 3,(P2),32] ;GET SENDER'S CODE
CAIE T0,.IPCCF ;FROM SYSTEM-WIDE [SYSTEM]INFO?
CAIN T0,.IPCCP ;OR FROM LOCAL [SYSTEM]INFO?
.POPJ2: AOSA (P) ;DOUBLE SKIP--IS FROM INFO
CAIN T0,.IPCCC ;FROM [SYSTEM]IPCC?
JRST .POPJ1 ;YES--SKIP RETURN
JRST RETM5 ;NOT FROM INFO OR IPCC
;THE FOLLOWING PREPARES TO SEND OR RECEIVE A MESSAGE FROM INFO.
SETINF: SETZM SAVBLK ;NO FLAGS
SETZM SAVBLK+1 ;FROM US
SETZM SA VBLK+2 ;TO INFO
MOVE T1,[^D8,,DBLK] ;POINTER TO DATA
MOVEM T1,SAVBLK+3 ;STORE IN LAST WORD
MOVE T1,[6,,SAVBLK] ;READY TO USE
POPJ P, ;SO RETURN
SUBTTL INTERNAL ROUTINES FOR PAGE MANAGEMENT.
IFN FTVM,<
;THE FOLLOWING ROUTINE FINDS A FREE PAGE NUMBER AND LEAVES IT IN P4.
GETPAG: MOVEI P4,HIPAGE ;START CHECKING WITH PAGE 677
GPLOOP: SOJLE P4,.POPJ ;ERROR RETURN IF WE GET DOWN TO PAGE 0
HRRZ T1,P4 ;PAGE TO CHECK IN RIGHT HALF
HRLI T1,.PAGCA ;CHECK PAGE ACCESS FUNCTION
PAGE. T1, ;CHECK IT OUT
POPJ P, ;ERROR RETURN
JUMPGE T1,GPLOOP ;IF NEGATIVE, PAGE DOES NOT EXIST
JRST .POPJ1 ;DO A SKIP RETURN
;TH E FOLLOWING ROUTINE DESTROYS THE PAGE WHOSE NUMBER IS IN RH(SAVBLK+3)
KILPAG: HRRZ P4,SAVBLK+3 ;GET PAGE NUMBER
HRLI P4,(1B0) ;SET SIGN BIT SO DESTROY PAGE
MOVEI P3,1 ;ONLY ONE
MOVE P2,[.PAGCD,,P3] ;P2 IS AC FOR PAGE. UUO
PAGE. P2, ;GET RID OF THE PAGE
POPJ P, ;WELL, WE DID WHAT WE COULD.
POPJ P, ;RETURN
> ;END OF IFN FTVM
SUBTTL INTERNAL ROUTINE TO RECEIVE A MESSAGE
;ROUTINE TRIES TO READ IN THE NEXT MESSAGE. IF A PAGE, CHOOSES A SUITABLE PAGE.
;GETS MESSAGE, AND RETURNS. IF A SMALL MESSAGE, READ INTO DBLK IF IT FITS, ELSE
;IF SMLPAG EXISTS AND THERE IS ROOM AT END, PUT IT THERE. ELSE, CREATE A NEW
; PAGE AND PUT AT BEGINNING. IPCFQ. BLOCK WILL BE IN SAVBLK.
;ACS: P1=START OF MESSAGE
; P3=# OF WORDS IN MESSAGE
; P4=0 OR PAGE NUMBER OF PAGE JUST CREATED.
;SKIP RETURN IF ALL WENT WELL, NON-SKIP WITH ERROR IN 0(ARGS) ELSE.
GETMES: MOVE T1,[6,,SAVBLK] ;PREPARE TO FIND OUT ABOUT QUEUE
IPCFQ. T1, ;DO SO.
JRST ERRRET ;NOPE
IFN KLUDGE,<
SKIPN SAVBLK+3 ;REALLY A MESSAGE?
JRST RET3> ;NO.
HLRZ P3,SAVBLK+3 ;NO--GET LENGTH.
IFN FTVM,<
MOVE P2,SAVBLK ;GET FLAGS
TXNE P2,IP.CFV ;PAGE MODE?
JRST PGMS> ;YES
CAILE P3,MAXEXP ;TOO BIG FOR DBLK?
JRST TOOBIG ;YES.
MOVEI P1,DBLK ;DBLK IS WHERE WE WANT TO PUT IT.
NOPG: SETZ P4, ;NO PAGE WAS CREATED
IPG: HRR T0,P1 ;WHERE IT GOES IN RIGHT HALF
HRL T0,P3 ;LENGTH IN LEFT HALF OF T0
MOVX T1,IP.CFV ;GET PAGE MODE BIT
ANDM T1,SAVBLK ;CLEAR REST OF FLAG WORD
EXCH T0,SAVBLK+3 ;USE IPCFQ. BLOCK
MOVE T1,[6,,SAVBLK] ;SET UP TO RECEIVE
IPCFR. T1, ;DO SO
IFN FTVM,JRST CHKPAG ;COULD NOT ;MAY BE RECOVERABLE
IFE FTVM,JRST ERRRET ;COULD NOT ;IS NOT RECOVERABLE
EXCH T0,SAVBLK+3 ;RESTORE SAVBLK
SKIPE P4 ;WAS THIS A PAGE?
LSH P1,^D9 ;YES--CONVERT P1 TO AN ADDRESS
JRST .POPJ1 ;AND DO A SKIP RETURN
IFN FTVM,<
;HERE IF IPCF RECEIVE FAILS. MAY BE ABLE TO RECOVER BY PAGING S OMEONE OUT
CHKPAG: SKIPE P4 ;PAGE MODE MESSAGE?
CAXE T1,IPCUP% ;YES--NO ROOM IN CORE MESSAGE?
JRST ERRRET ;NOT PAGE, OR NOT THAT ERROR
;NOW WE KNOW WE CAN RECOVER IF WE JUST PAGE SOMEBODY OUT. BUT WHO?
MOVEI T1,17 ;17 WORDS IN PAGE TABLE
MOVEM T1,PAGTAB-1 ;STORE IN PAGE. UUO ARG LIST
MOVX T1,<.PAGWS,,PAGTAB-1> ;GET WORKING SET
PAGE. T1,
JRST RETM2 ;"IMPOSSIBLE"
MOVEI T1,0 ;A FEW PAGES WE DON'T WANT TO PAGE OUT
PUSHJ P,CLRPBT ;E.G. PAGE 0
MOVEI T1,CHKPG1 ;AND CRITICAL SECTION BELOW
PUSHJ P,CLRPBT
MOVEI T2,CHKPG2 ;END OF CRITICAL SECTION
PUSHJ P,CLRPBT ;IN CASE CROSSES PAGE BOUNDARY
HRLZI T1,-17 ;NOW SEARCH FOR FIRST PAGE IN WORKING SET
SKIPN T2,PAGTAB(T1) ;FIND NON-ZERO WORD
AOBJN T1,.-1
JUMPGE T1,RETM2 ;NONE - IRRECOVERABLE
JFFO T2,.+1 ;FIND NON-ZERO BIT IN THAT WORD
TLZ T1,-1 ;T1 IS NOW HIGHORDER PART OF PAGE NO.
IMULI T1,^D36 ;GET IT IN RIGHT PLACE
ADD T3,T1 ;T3 IS LOWORDER, SO COMBINE
TLO T3,(1B0) ;ADD CODE TO PAGE IT OUT
MOVEI T2,1 ;THAT ONE PAGE ONLY
MOVX T1,<.PAGIO,,T2> ;PAGE IT OUT
;BEGIN CRITICAL SECTION - BETTER NOT PAGE OUT ANY OF THIS STUFF, SINCE
;IF WE DID IT WOULD GET PAGED IN AGAIN!
CHKPG1: PAGE. T1, ;DO IT!
JRST RETM2 ;COULD NOT
MOVE T1,[4,,SAVBLK] ;TRY UUO AGAIN
IPCF R. T1,
CHKPG2: JRST ERRRET ;FAILED AGAIN??
;END OF CRITICAL SECTION, SINCE IPCF HAS BEEN DONE
EXCH T0,SAVBLK+3 ;RESTORE QUEUE INFO
LSH P1,^D9 ;CONVERT PAGE # TO PAGE ADDRESS
JRST .POPJ1 ;AND GIVE A GOOD RETURN
;CLRPBT - REMOVE BIT FROM PAGE MAP - T1=ADDRESS ON PAGE TO REMOVE
CLRPBT: LSH T1,-^D9 ;MAKE ADDR INTO PAGE NO.
IDIVI T1,^D36 ;T1=WORD IN MAP, T2=BIT
MOVSI T3,400000 ;BIT MASK
MOVNS T2 ;BIT NO. - NEG. FOR RIGHT SHIFT
LSH T3,(T2) ;NOW MASK RIGHT BIT
ANDCAM T3,PAGTAB(T1) ;CLEAR BIT IN MEMORY
POPJ P,
PGMS: PUSHJ P,GETPAG ;FIND A FREE PAGE
JRST RETM2 ;NONE?
HRRZ P1,P4 ;STORE PAGE # IN P1
JRST IPG ;AND CARRY ON
> ;END OF IFN FTVM
TOOBIG: HRRZ T2,P3 ;GET # OF WORDS REQUIRED IN T2
PUSHJ P,GETCOR ;GET THAT MUCH CORE!
JRST RETM2 ;NONE?
HRRZ P1,T1 ;SAVE ADDRESS IN P1
JRST NOPG ;AND CARRY ON
SUBTTL INTERNAL ROUTINE TO SAVE A MESSAGE.
;ROUTINE TRIES TO SAVE THE MESSAGE JUST READ.
;NEEDS ACS AS THEY ARE RETURNED FROM GETMES.
SAVMES: SKIPE T1,SAVNUM ;ARE WE SAVING ANYTHING?
JRST NOTFIR ;YES--NOT FIRST MESSAGE
MOVEI P2,MESTAB ;NO--INITIALIZE.
MOVEM P2,SVMES1 ;STORE WHERE THE FIRST MESSAGE IS.
JRST BYPS1 ;BYPASS UNNECESSARY CODE.
NOTFIR: CAIL T1,NUMMES ;IS THERE A FREE MESSAGE SLOT?
JRST RETM6 ;NOPE. RETURN -6 AS ERROR
MOVE P2,SVMESN ;GET LAST JOB USED
CAIN P2,MESTAB+<7*NUMMES>-7 ;LAST SLOT?
MOVEI P2,MESTAB-7 ;YES--NEXT IS FIRST
ADDI P2,7 ;POINT TO NEXT SLOT.
BYPS1: MOVEM P2,SVMESN ;UPDATE LAST MESSAGE SAVED POINTER
DMOVE T0,SAVBLK ;GET FIRST 2 WORDS OF QUEUE INFO
DMOVEM T0,1(P2) ;STORE IN MESSAGE TABLE
DMOVE T0,SAVBLK+2 ;GET NEXT 2 WORDS OF QUEUE ENTRY
DMOVEM T0,3(P2) ;STORE
DMOVE T0,SAVBLK+4 ;GET LAST TWO WORDS
DMOVEM T0,5(P2) ;AND STORE THEM
AOS SAVNUM ;INCREMENT COUNT OF SAVED MESSAGES
MOVEM P1,(P2) ;ASSUME P1 IS ADR OF FINAL RESTING PLACE OF MESSAGE.
CAIE P1,DBLK ;IS MESSA GE AT DBLK?
JUMPE P4,.POPJ1 ;NO. IF NOT A PAGE, EITHER, WE NEED DO NO MORE
HLRZ T2,SAVBLK+3 ;GET SIZE OF MESSAGE IN T2
PUSHJ P,GETCOR ;GET THAT MUCH CORE
JRST [SOS SAVNUM ;NO CORE? THEN UNSAVE MESSAGE.
JRST RETM2]
MOVEM T1,(P2) ;STORE ADDRESS IN QUEUE
ADDI T2,-1(T1) ;T2 IS NOW ADDRESS OF LAST WORD OF NEW MESSAGE
HRL T1,P1 ;T1 == OLD MESSAGE,,NEW MESSAGE
BLT T1,(T2) ;MOVE THE MESSAGE!
JRST .POPJ1 ;AND GIVE A SKIP RETURN
SUBTTL END AND SUCH THINGS
;LITERALS
XLIST
LIT
LIST
END