Trailing-Edge
-
PDP-10 Archives
-
BB-4172G-BM
-
language-sources/glxint.mac
There are 37 other files named glxint.mac in the archive. Click here to see a list.
TITLE GLXINT - Operating system interface for GALAXY
SUBTTL Irwin L. Goverman/ILG /PJT/MLB/DC 3-Jul-79
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979
; DIGITAL EQUIPMENT CORPORATION
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
;This module provides commonly used routines that are dependent
; upon the operating system.
SEARCH GLXMAC ;GET NECESSARY SYMBOLS
PROLOG(GLXINT,INT) ;GENERATE PROLOG CODE
SEARCH ORNMAC ;GET WTO SYMBOLS
INTEDT==47 ;EDIT NUMBER
SUBTTL Table of Contents
; TABLE OF CONTENTS FOR GLXINT
;
;
; SECTION PAGE
; 1. Table of Contents......................................... 2
; 2. Revision History.......................................... 3
; 3. Entry Points Found in GLXINT.............................. 4
; 4. Local Definitions......................................... 5
; 5. Module Storage............................................ 6
; 6. I%INI1 - Continue Library Initialization.................. 7
; 7. CREDAT - Create data pages for OTS........................ 9
; 8. SETTRP - Setup for APR Trapping........................... 10
; 9. IINIT - Initialize the interrupt system data base......... 11
; 10. I%IOFF-I%ION - Turn interrupt system off and on........... 12
; 11. Processor for each interrupt level........................ 13
; 12. I%EXIT - Exit from the program............................ 14
; 13. I%NOW - Get time of day.................................. 14
; 14. I%SLP - Dismiss the program for a while.................. 15
; 15. I%HOST -- Get Host Name/Number of Central Site...... 16
; 16. GETLOC -- GET CENTRAL SITE LOCATION................. 17
; 17. I%JINF -- Canonical Job Information................. 18
; 18. I%JINF ROUTINES FOR THE -10............................... 19
; 19. I%JINF SPECIAL ROUTINES FOR THE -20....................... 20
; 20. I%WTO - ACK, WTO, WTOR MSG PROCESSOR.................... 21
; 21. MORE WTO ACTION ROUTINES.................................. 23
SUBTTL Revision History
COMMENT \
Edit GCO Reason
---- ------- -------------------------------------------------------
0001 Create GLXINT module
0002 G011 Add I%IWTO routine to SETUP WTO message
Add I%SWTO routine to SEND WTO message
Add I%SOPR routine to SEND TO ORION
Add I%WTO routine to PUT TEXT IN MESSAGE
0003 G016 On the -10 add APRENB trapping for PDL-OV, ILL-MEM-REF,
0004 G023 Fix WTO Routines to use new messages
and NON-EX-MEM.
0005 G029 Zero the Library data pages to make Library restartable
0006 G032 SUPPLEMENT THE WTO PROCESSORS WITH A ROUTINE TO PROCESS
ACK, WTO, AND WTOR MESSAGES.
0007 G036 Have APR trap set pc into AC 0 for now
0010 G049 Fix I%SOPR
0011 Add Defaulting for IB and change Calling of I%INI1
to keep the Pid pure in callers address space
0012 Support Multiple interrupt levels on the 20
0013 Handle send errors for I%SOPR if user doesn't want
send errors returned.
Make I%EXIT do a reset if not debugging
0014 Add I%HOST and correct I%EXIT to be the same in all
cases(i.e debugging and real)
0015 Add I%JINF call to Library with defined functions in GLXMAC
0016 Convert Module to use I%JINF where possible
0017 Fix $ACK message to lite the WT.SJI bit to suppress
Job info on Display
0020 Rework I%%WTI to handle blocks
Rename to I%%WTO, remove old I%%WTO, I%%WTI code.
0021 Remove I%IWTO,I%SWTO,I%WTO, Rename I%%WTO to I%WTO
0022 Rework of IB, PIB.
0023 Add global routine to get program version #
0024 Add action routines for WTO blocks NOD, JOB
Make APT $STOP print out error PC
0025 Restore S1, S2, TF on return from WTO
0026 FIX GJBLOC TO NOT CLOBBER T4. INSTEAD USE TF
0027 CHANGE NAME OF WT.JOB ACTION ROUTINE TO WTPJBN
0030 Change WT.MIN, WT.MAX to WO.MIN, WO.MAX
0031 Load real WT.JOB in WTPJBN routine
0032 ADD IB.PRG INTO IB DEFAULTS
0033 Add Support for -20 Panic Channels if using Interrupt system
and Channels are not enabled.
0034 Change SAVE to $SAVE
0035 Add WTO support code for Application Code Block and Object Type
Block
0036 Make all calls to I%WTO send a packet if its feasible.
0037 Fix WTO routines so args in S1,S2 work
0040 Fix 0037 so it BLTs a whole object block
0041 Remove setting for WT.SJI if ACK code specified
0042 Fix WTO range check stopcode to dump offending addrs
0043 Move PFH into library
0044 Change the %FATAL for the Version SKEW between GLXINI and GLXLIB
0045 Add WTO support for .MSFLG
0046 Change $FATAL for incompatible Library and I%EXIT to just
text to be dumped by the K%SOUT routine. This covers the
case of the library not being initialized.
0047 Change the error message for incompatible library and GLXINI.
\ ;END OF REVISION HISTORY
SUBTTL Entry Points Found in GLXINT
ENTRY I%INI1 ;INITIALIZE THE MODULE
ENTRY I%NOW ;GET TIME OF DAY
ENTRY I%EXIT ;EXIT FROM PROGRAM
ENTRY I%ION ;INTERRUPTS ON
ENTRY I%IOFF ;INTERRUPTS OFF
ENTRY I%SLP ;SLEEP FOR A WHILE
ENTRY I%INT1 ;CREATE ALL ENTRIES
ENTRY I%INT2 ;FOR INTERRUPT LEVELS
ENTRY I%INT3 ;
ENTRY I%SOPR ;SEND TO OPR ROUTINE.
ENTRY I%WTO ;ACK, WTO, WTOR MSG PROCESSOR
ENTRY I%HOST ;GET HOST NAME/NUMBER
ENTRY I%JINF ;CANONICAL JOB INFO BLOCK
SUBTTL Local Definitions
;Since the number of levels of interrupt differs from system to system,
; all code that deals with interrupt levels is under the DOLEV macro.
; To use this macro, define X(LVL) to generate the proper code for one
; level, using LVL as the suffix. Then the invokation of DOLEV will
; create redundant code for each level wanted (INT.LV defined in GLXMAC).
; (INT.LV and INT.MX defined in GLXMAC)
DEFINE DOLEV (LVLS<INT.LV>)<
LSTOF.
ZZ==1 ;;START AT LEVEL 1
REPEAT LVLS,<
X(\ZZ) ;;EXPAND DEFINED CODE FOR EACH LEVEL
ZZ==ZZ+1 ;;STEP TO NEXT LEVEL
>
LSTON.
> ;END OF DOLEV DEFINITION
SUBTTL Module Storage
EXT RSEFLG ;RETURN SEND ERROR FLAG
$DATA I%INT1,2 ;LEVEL 1 INTERRUPT ENTRY
$DATA I%INT2,2 ;LEVEL 2 INTERRUPT
$DATA I%INT3,2 ;LEVEL 3 INTERRUPT
DEFINE X(LVL)<
$DATA LEVPL'LVL,IPL.SZ ;;PUSHDOWN LIST FOR EACH LEVEL
$DATA SAVAC'LVL,20 ;;AC SAVE AREA FOR EACH LEVEL
> ;END OF PER LEVEL DEFINITIONS
DOLEV ;;EXPAND FOR EACH VALID LEVEL
$GDATA MYJOB ;MY JOB NUMBER
$DATA AWOKEN ;USED FOR SLEEP/WAKE CODE
$GDATA BASINT ;BASE OF INTERRUPT SYSTEM
$GDATA INTRPC ;INTERRUPT PC ADDRESS
$GDATA IIB,IB.SZ ;FULL SIZED IB
$DATA PRMADR ;WTO PARM ADDRESS
$DATA RETADR ;Holds return PC
$DATA THSPRM ;Address of current WTO parameter
$DATA S1%S2,2 ;WTO SAVE AREA FOR S1, S2.
$DATA WTOBLT ;OBJECT BLK END ADDRESS FOR WTO BLT
$DATA STF ;Save for TF during WTO
$DATA MSGADR ;WTO MESSAGE ADDRESS.
$DATA BYTPTR ;WTO MSG BYTE PTR.
$DATA BYTCNT ;WTO MSG BYTE COUNT.
$DATA WTOSAB,SAB.SZ ;WTO SAB BLOCK.
$GDATA D%END,0 ;Last adrs in library data space
SUBTTL I%INI1 - Continue Library Initialization
;Called from I%INIT to initialize this module and the rest of the library
;CALL IS: S1/ LENGTH OF THE USER SUPPLIED IB
; S2/ %%.GLX ,, USER SUPPLIED IB ADDRESS
;
;TRUE RETURN: ALWAYS
IFE GLXPURE,<
I%INIT::HRLI S2,%%.GLX ;For low-seg library, initialize here
>
I%INI1: PUSHJ P,.SAVE2## ;SAVE TWO REGISTERS
DMOVE P1,S1 ;SAVE IB LENGTH AND LOCATION
PUSHJ P,CREDAT ;CREATE THE DATA PAGES
DEFINE DEFAULTS <
LSTOF.
XX IB.PRG,FWMASK,'NONAME' ;;PROGRAM NAME
XX IB.OUT,FWMASK,T%TTY ;;$TEXT OUTPUT ROUTINE
;;XX IB.IPC,IP.PSI,0 ;;IPCF PSI FLAG
;;XX IB.IPC,IP.JWP,0 ;;IPCF JOB WIDE PID FLAG
XX IB.FLG,IP.STP,0 ;;ORION GETS STOP CODES FLAG
;;XX IB.IPC,IP.SPB,0 ;;ACCEPT PRIV OF SENDER FLAG
;;XX IB.IPC,IP.RSE,0 ;;RETURN SEND ERROR FLAG
;;XX IB.IPC,IP.CHN,0 ;;IPCF CHANNEL OR OFFSET
;;XX IB.IPC,IP.SPI,0 ;;SYSTEM WIDE COMPONENT FIELD
;;XX IB.IPP,IP.MNP,0 ;;MAXIMUM NUMBER OF PIDS
;;XX IB.IPP,IP.SQT,0 ;;SEND QUOTA
;;XX IB.IPP,IP.RQT,0 ;;RECIEVE QUOTA
;;XX IB.PID,FWMASK,0 ;;REQUESTED PID
;;XX IB.VER,FWMASK,0 ;;PROGRAM VERSION NUMBER
XX IB.INT,FWMASK,0 ;;INTERRUPT VECTORS
XX IB.FLG,IT.OCT,0 ;;OPEN TERMINAL FOR S%CMND
XX IB.ERR,FWMASK,0 ;;USER $TEXT ERROR EXIT ROUTINE
XX IB.PIB,FWMASK,0 ;;PID block address
LSTON.
>
DEFINE XX (LOC,MSK,DEF,%L1) <
CAIG P1,LOC ;;SUPPLIED BY USER?
JRST %L1 ;;NO -- SUPPLY OUR DEFAULT
LOAD S1,LOC'(P2),MSK ;;YES -- GET WHAT THE SUPPLIED
SKIPN S1 ;;NULL FIELD?
%L1: MOVX S1,DEF ;;YES -- SUPPLY OUR DEFAULT
STORE S1,IIB+LOC,MSK ;;STORE IN PERSONAL IB
SUPPRESS %L1
> ;END SETDEF
DEFAULTS ;;SET INTERNAL DEFAULTS
HLRZ S2,P2 ;GET %%.GLX SUPPLIED BY I%INIT
CAIE S2,%%.GLX ;CHECK MAJOR CHANGE LEVEL
JRST [MOVEI S1,[ASCIZ/? This program is incompatible with GLXLIB and must be recompiled.
/]
PUSHJ P,K%SOUT ;DUMP IT OUT
PUSHJ P,I%EXIT] ;STOP THE PROCESS
SETOM S1 ;SET FOR MY JOB
MOVX S2,JI.JNO ;GET THE JOB NUMBER
PUSHJ P,I%JINF ;GET THE DATA IN S2
MOVEM S2,MYJOB ;SAVE MY JOB NUMBER
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,M%INIT## ;INITIALIZE THE MEMORY SYSTEM
PUSHJ P,SETPFH## ;Setup the fault handler (-10 only)
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,.INIT## ;INITIALIZE THE COMMON MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,T%INIT## ;INITIALIZE THE TEXT MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,IINIT ;INITIALIZE THE INTERRUPT SYSTEM
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,C%INIT## ;INITIALIZE THE COMMUNICATIONS MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,F%INIT## ;INITIALIZE THE FILE MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,L%INIT## ;INITIALIZE THE LINKED LIST MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,K%INIT## ;INITIALIZE THE TERMINAL KEYBOARD MODULE
DMOVE S1,INT.D ;POINT TO FULL IB
PUSHJ P,S%INIT## ;INIT THE COMMAND SCANNER
MOVX S1,<SI.FLG+SP.OPR> ;SEND TO SPECIAL PID ...OPR
MOVEM S1,WTOSAB+SAB.SI ;SAVE IN WTOSAB
SETZM WTOSAB+SAB.PD ;CLEAR PID WORD
$RETT ;RETURN TO CALLER
INT.D: EXP IB.SZ,IIB ;Common args for the initializers
SUBTTL CREDAT - Create data pages for OTS
;All library modules allocate memory storage via the $DATA and $GDATA
; macros. These macros assign blocks of storage in the DATA PSECT.
; One the -10, those pages are allocated in a segment of memory
; which looks like 'low-segment' code, even though it is in high memory.
; On the -10, we have to MERGE in the rest of the EXE file
; and thus create the DATA space, unless these pages
; already exist. GLXINI does this for us, since it
; knows exactly where the high segment came from.
; On both systems, all the DATA space is zeroed, whether
; the pages were created or existed because of a restart
; Note that GLXINT must be loaded last to insure that it
; has knowledge of all the locations used by members of the OTS.
; For a low-segment loadable library, $DATA space is non-contiguous
; and must be zeroed piece by piece.
;CALL IS: No arguments
;TRUE RETURN: Always
CREDAT:
IFN GLXPURE,<
DMOVE S1,[EXP D%END-D%BEG##,D%BEG##] ;Aim at the block
$CALL .ZCHNK ;Clear out the data space, and return
$RETT
>;END IFN GLXPURE
IFE GLXPURE,<
PUSH P,P1 ;Preserve a reg
MOVSI P1,-CRELEN ;MAke AOBJN ptr to data table
CRED.0: HLRZ S1,CRED.T(P1) ;Get length of entry
JUMPE S1,CRED.1 ;None for this module, try next
HRRZ S2,CRED.T(P1) ;Get addr of block
$CALL .ZCHNK ;Clear out this module's storage
CRED.1: AOBJN P1,CRED.0 ;Try next module
POP P,P1 ;Get back the work reg
$RETT
DEFINE GLX(MOD,EDT,LOD,GCO,WHO,DATE,NOTE)<
IFDIF <MOD><MAC>,<
IFDIF <MOD><INI>,<
GLOB (MOD'%DL) ;Globalize $DATA length
GLOB (MOD'%D) ;Globalize $DATA start adr
XWD MOD'%DL,MOD'%D ;Length,,adr
>
>
>;END DEFINE GLX
CRED.T:
MODULES ;Build all the $DATA zeroing code
CRELEN==.-CRED.T ;Length of table
>;END IFE GLXPURE
SUBTTL SETTRP - Setup for APR Trapping
SETTRP:
TOPS10 <
MOVEI S1,TRPADR ;GET TRAP ROUTINE ADDRESS
MOVEM S1,.JBAPR ;STORE IT
MOVX S1,AP.POV+AP.ILM+AP.NXM ;GET TRAP TYPES
APRENB S1, ;ENABLE THEM
$RETT ;RETURN
> ;END TOPS10 CONDITIONAL
TOPS20 <
SKIPN S1,BASINT ;INTERRUPT SYSTEM PRESENT
$RETT ;NO..IGNORE SETUP
HRRZ S1,S1 ;GET CHANNEL TABLE ADDRESS
MOVE S2,[1,,TRPPDL] ;TRAP ADDRESS FOR INTERRUPTS
SKIPN .ICPOV(S1) ;PDL OVERFLOW SETUP?
MOVEM S2,.ICPOV(S1) ;SAVE TRAP ADDRESS
MOVE S2,[1,,TRPIIT] ;TRAP ADDRESS FOR INTERRUPTS
SKIPN .ICILI(S1) ;ILLEGAL INSTRUCTION?
MOVEM S2,.ICILI(S1) ;SAVE TRAP ADDRESS
MOVE S2,[1,,TRPIMR] ;TRAP ADDRESS FOR INTERRUPTS
SKIPN .ICIRD(S1) ;ILLEGAL MEMORY READ?
MOVEM S2,.ICIRD(S1) ;SAVE TRAP ADDRESS
MOVE S2,[1,,TRPIMW] ;TRAP ADDRESS FOR INTERRUPTS
SKIPN .ICIWR(S1) ;ILLEGAL MEMORY WRITE?
MOVEM S2,.ICIWR(S1) ;SAVE TRAP ADDRESS
MOVEI S1,.FHSLF ;GET MY PROCESS HANDLE
MOVX S2,<1B<.ICPOV>!1B<.ICILI>!1B<.ICIRD>!1B<.ICIWR>>
AIC ;ACTIVATE THE CHANNELS
ERJMP SETT.E ;ERROR
HLRZ S1,BASINT ;GET LEVEL TABLE
MOVE S1,(S1) ;GET ADDRESS OF LEVEL PC SAVE
MOVEM S1,INTRPC ;SAVE INTRPC
$RETT ;RETURN
SETT.E: $STOP(CSP,Cannot Activate Panic Channels)
>;END TOPS20
;HERE ON AN APR TRAP
TOPS10 <
TRPADR: MOVE TF,.JBCNI ;GET APR CONI AT TRAP
TXNE TF,<1B19> ;Was it PDL OVF?
$STOP(PDL,<Pushdown list overflow^I/TRPPC/>)
$STOP(APT,<Illegal memory reference^I/TRPPC/>)
TRPPC: ITEXT (< at PC ^O/.JBTPC,RHMASK/>)
>;END TOPS10 CONDITIONAL
TOPS20 <
TRPPDL: $BGINT 1 ;SETUP INTERRUPT LEVEL
PUSHJ P,TRPSET ;SETUP TRAP
$STOP(PDL,Pushdown List Overflow^I/TRPPC/)
TRPIIT: $BGINT 1 ;SETUP ILLEGAL INSTRUCTION
PUSHJ P,TRPSET ;SETUP TRAP
MOVE P,SAVAC1+17 ;GET ORIGINAL STACK BACK
$STOP(IST,Illegal Instruction Trap^I/TRPPC/)
TRPIMR: $BGINT 1 ;SETUP ILLEGAL MEMORY READ
PUSHJ P,TRPSET ;SETUP TRAP
MOVE P,SAVAC1+17 ;GET ORIGINAL STACK BACK
$STOP(IMR,Illegal Memory Read^I/TRPPC/)
TRPIMW: $BGINT 1 ;SETUP ILLEGAL MEMORY WRITE
PUSHJ P,TRPSET ;SETUP TRAP
MOVE P,SAVAC1+17 ;GET ORIGINAL STACK BACK
$STOP(IMW,Illegal Memory Write^I/TRPPC/)
TRPPC: ITEXT (< at PC ^O/INTRPC,RHMASK/ Stack ^O/SAVAC1+17/>)
TRPSET: PUSH P,S1 ;SAVE S1
MOVE S1,@INTRPC ;GET THE PC
MOVEM S1,INTRPC ;SAVE THE PC
POP P,S1 ;RESTORE S1
POPJ P, ;RETURN
>;END TOPS20
SUBTTL IINIT - Initialize the interrupt system data base
;Information in the IB must be remembered for operation of the interrupt
; system. Also, since the entries to the interrupt level setup routines
; are in impure storage, they must be set up.
; CALL IS: S1/ Size of the IB
; S2/ Address of the IB
;
; TRUE RETURN: Always
IINIT: SETOM AWOKEN ;ALWAYS PRETEND SOMETHING HAPPENED
MOVE S1,[XWD IINI.1,I%INT1] ;PREPARE THE INTERRUPT ROUTINES
BLT S1,I%INT1+SZ.INB-1 ;FOR LATER USE
MOVE S1,IB.INT(S2) ;GET THE BASE OF THE INTERRUPT SYSTEM
MOVEM S1,BASINT ;STORE FOR LATER
JUMPE S1,IINI.2 ;IF NO INTERRUPT SYSTEM, DO SOMETHING ELSE
PUSHJ P,SETINT ;SET IT UP FOR USER
SKIPT ;DID IT WORK OK?
$STOP(CSI,Cannot set up interrupt system)
JRST IINI.3 ;SETUP APR TRAPS AND RETURN
IINI.1:
DEFINE X(LVL)<
Z ;JSR PC STORAGE FOR LEVEL
JRST INTC.'LVL ;PROCESSING DISPATH FOR LEVEL
> ;END OF PER LEVEL DEFINITION
DOLEV (3) ;FORCE HEADER FOR THREE POSSIBLE LEVELS
SZ.INB==.-IINI.1 ;SIZE OF BLOCK
IINI.2: MOVE S1,[PUSHJ P,S..NIS] ;NO INTERRUPT SYSTEM,SO SAY SO
DEFINE X(LVL),<MOVEM S1,1+I%INT'LVL> ;STORE IN EACH PLACE APPLICABLE
DOLEV
JRST IINI.3 ;SETUP APR TRAPS AND RETURN
$STOP(NIS,No interrupt system set up)
IINI.3: PJRST SETTRP ;SETUP APRS AND RETURN
SUBTTL I%IOFF-I%ION - Turn interrupt system off and on
;When interrupts can not be accepted, they can be switched on
; and off via these routines.
;CALL IS: NO ARGUMENTS
;TRUE RETURN: ALWAYS
TOPS10 <
I%ION: SKIPA S1,[PS.FON] ;FLAG TO TURN ON SYSTEM
I%IOFF: MOVX S1,PS.FOF ;FLAG TO TURN OFF SYSTEM
SKIPN BASINT ;DID USER ENABLE INTERRUPTS?
$RETT ;NO, JUST RETURN
PISYS. S1, ;ALTER THE STATE
$STOP(CCI,Cannot change interrupt state)
$RETT ;AND RETURN
SETINT: PIINI. S1, ;HERE TO SET UP VECTOR
$RETF ;FALSE IF CANNOT SET IT UP
$RETT ;OTHERWISE, ALL IS OK
> ;END TOPS10 CONDITIONAL
TOPS20 <
I%ION: SKIPN BASINT ;SKIP IF USER ENABLED INTERRUPTS
$RETT ;AND RETURN
MOVX S1,.FHSLF ;FOR MYSELF
EIR ;TURN ON INTERRUPTS
ERCAL S..CCI ;IF CANNOT DO IT
$RETT
I%IOFF: SKIPN BASINT ;SKIP IF WE ARE DOING INTERRUPTS
$RETT ;AND RETURN
MOVX S1,.FHSLF ;FOR MYSELF
DIR ;DISABLE INTERRUPTS
ERJMP .+2
$RETT ;RETURN AFTER CHANGE
$STOP(CCI,Cannot change interrupt state)
SETINT: MOVE S2,S1 ;GET LEVTAB,,CHNTAB OF CALLER
MOVX S1,.FHSLF ;AND FOR MYSELF,
SIR ;ESTABLISH THE INTERRUPT SYSTEM
ERJMP .RETF ;IF IT FAILS, SAY SO
$RETT ;OTHERWISE, TAKE GOOD RETURN
> ;END TOPS20 CONDITIONAL
SUBTTL Processor for each interrupt level
;Each level of interrupt starts off with a $BGINT instruction
;which does a JSR to the appropriate I%INTx routine. These in turn
;call the continuation routines which set the DEBRK code as a co-routine.
;When interrupt processing is done for this level, a $DEBRK is done
;which does the proper post interrupt processing.
DEFINE X(LVL)<
INTC.'LVL:
IFGE INT.LV-LVL,<
MOVEM 0,SAVAC'LVL ;;SAVE AC 0 AWAY
MOVE 0,[XWD 1,1+SAVAC'LVL] ;;BLT POINTER TO SAVE THE ACS
BLT 0,17+SAVAC'LVL ;;SAVE ALL ACS
MOVE 17,[IOWD IPL.SZ,LEVPL'LVL] ;;SET UP INTERRUPT LEVEL PDL
PUSH P,[Z DBRK'LVL] ;;SET UP CO-ROUTINE RETURN
JRST @I%INT'LVL ;;AND CONTINUE
DBRK'LVL: ;;HERE WHEN INTERRUPT IS OVER
TOPS20 < ;;WAKE UP CODE FOR TOPS-20
SETOM AWOKEN ;;WE HAVE A WAKE UP COMING
MOVEI T1,SLP1 ;;LABEL FOR FORCED WAKE UP
HLRZ S2,BASINT ;;GET LEVTAB'S ADDRESS
ADDI S2,LVL-1 ;;GET OFFSET TO THIS LEVEL'S POINTER
HRRZ S2,0(S2) ;;GET WHERE PC IS STORED
HRRZ S1,0(S2) ;;GET PC INTERRUPTED FROM
CAIL S1,SLP0 ;;INSIDE SLEEP CODE BLOCK?
CAILE S1,SLP1 ;;
SKIPA ;;NO, NO NEED TO ALTER PC
HRRM T1,0(S2) ;;ELSE STORE NEW PC TO FORCE WAKE-UP
> ;END TOPS20 CONDITIONAL
MOVE 17,[XWD SAVAC'LVL,0] ;;RESTORE THE ACS
BLT 17,17 ;;OF PREVIOUS CONTEXT
TOPS20 <
DEBRK ;;DISMISS THE INTERRUPT
ERCAL S..NIP ;;IF DEBRK FAILS
> ;END TOPS20 CONDITIONAL
TOPS10 <
DEBRK. ;;DISMISS THE INTERRUPT
PUSHJ P,S..DUF ;IF UUO FAILS
PUSHJ P,S..NIP ;IF NONE IN PROGRESS
> ;END TOPS10 CONDITIONAL
> ;END IFGE INT.LV-LVL
IFL INT.LV-LVL,<
$STOP(IN'LVL,Level LVL interrupts not supported)
> ;END IFL INT.LV-LVL
> ;END OF X DEFINITION
DOLEV (INT.MX) ;EXPAND CODE OR STOP CODE FOR ALL LEVELS
$STOP(NIP,No interrupt is in progress) ;COMMON STOP CODES
$STOP(DUF,DEBRK UUO failed)
SUBTTL I%EXIT - Exit from the program
;This routine provides a non-continuable exit from the calling
; program.
;CALL IS: No argument
;
;NO RETURN IS PROVIDED
I%EXIT: RESET ;NO -- DO A RESET
$HALT ;STOP THE PROCESS
MOVEI S1,[ASCIZ/? Can't continue
/]
PUSHJ P,K%SOUT ;DUMP THE MESSAGE
JRST I%EXIT ;LOOP BACK
SUBTTL I%NOW - Get time of day
;CALL IS: No arguments
;
;TRUE RETURN: S1/ Time and date in UDT format
TOPS10 <
I%NOW: MOVX S1,%CNDTM ;GET TIME AND DATE FROM
GETTAB S1, ;THE MONITOR
$STOP(DTU,Date/Time unavailable)
$RETT ;RETURN S1/HAS UDT
> ;END TOPS10 CONDITIONAL
TOPS20 <
I%NOW: GTAD ;GET DATE AND TIME
$RETT ;AND RETURN THEM
> ;END TOPS20 CONDITIONAL
SUBTTL I%SLP - Dismiss the program for a while
;When programs need to suspend operation for a time or want to block
; indefinitely, they should use the I%SLP routine.
; Any interrupts will cause the end of sleeping, as will certain
; spurious conditions. Programs using I%SLP should not depend
; on premature wake-up not happening.
;CALL IS: S1/ Number of seconds to sleep, or 0 for infinite sleep
;
;TRUE RETURN: Always
I%SLP: SKIPGE S1 ;IF A NEGATIVE NUMBER,
MOVEI S1,1 ;SLEEP FOR A SECOND
CAILE S1,^D60 ;IF MORE THAN A MINUTE
MOVEI S1,^D60 ;SLEEP FOR A MINUTE
IMULI S1,^D1000 ;CONVERT SECONDS TO MILLISECONDS
TOPS10 <
HIBER S1, ;DO HIBERNATE FOR SLEEPING
$STOP(HUF,HIBER UUO failed)
$RETT ;RETURN AFTER SLEEPING
> ;END TOPS10 CONDITIONAL
TOPS20 <
SLP0: SKIPE AWOKEN ;SEE IF A WAKE UP HAS OCCURRED
JRST SLP1 ;YES, DON'T SLEEP AT ALL
SKIPN S1 ;TIMED SLEEP?
WAIT ;NO, SLEEP INDEFINITELY
DISMS ;ELSE SLEEP FOR SPECIFIED SECONDS
JFCL ;USE A LOCATION
SLP1: SETZM AWOKEN ;CLEAR "NEED WAKE UP" FLAG
$RETT ;RETURN TO CALLER
> ;END TOPS20 CONDITIONAL
SUBTTL I%HOST -- Get Host Name/Number of Central Site
;THIS ROUTINE WILL RETURN THE NODE NAME AND NUMBER (-10 ONLY)
;FOR THE CENTRAL SITE.
;
;CALL: NO ARGUMENTS
;
;RETURN: S1/ HOST NAME IN SIXBIT
; S2/ HOST NUMBER (-10) OR ZERO (-20)
;
SUBTTL GETLOC -- GET CENTRAL SITE LOCATION
I%HOST:
IFN FTUUOS,<
MOVEI S2,.GTLOC ;GET LOCATION OF JOB 0
GETTAB S2, ;...
JRST HOST.2 ;SETUP DEFAULT AND RETURN
HOST.1: PUSHJ P,.SAVE3 ;GET THREE ACS
MOVSI P1,.NDRNN ;NODE NUMBER TO NAME CONVERSION
HRRI P1,P2 ;ADDRESS BLOCK IN P2
HRRZI P2,2 ;2 ARGS SPECIFIED..LENGTH
MOVE P3,S2 ;NODE NUMBER TO CONVERT,,RIGHT HALF
NODE. P1, ;ISSUE NODE UUO
JRST HOST.2 ;TAKE DEFAULTS
MOVE S1,P1 ;PUT NAME IN S1
$RETT ;RETURN TRUE
HOST.2: MOVE S1,[SIXBIT/LOCAL/] ;GET THE DEFAULT NAME
SETZ S2, ;DEFAULT NUMBER
$RETT ;RETURN S1,,NODE NAME
>;END FTUUOS
IFN FTJSYS,<
PUSHJ P,.SAVET ;SAVE THE T REGS
MOVX S1,.NDGLN ;GET LOCAL NODE NAME JSYS CODE
MOVEI S2,TF ;GET ARGUMENT BLOCK ADDRESS
HRROI TF,T1 ;MAKE BYTE POINTER TO T1
DMOVE T1,[ASCIZ/LOCAL/] ;SETUP DEFAULT NAME
NODE ;GET THE LOCAL NODE NAME
ERJMP .+1 ;PROCESS DEFAULT
MOVE T3,[POINT 7,T1] ;GET POINTER TO NODE NAME
MOVE T4,[POINT 6,S1] ;GET OUTPUT POINTER
SETZ S1, ;SET OUTPUT BUFFER TO NULLS
HOST.1: ILDB S2,T3 ;GET AN INPUT BYTE
JUMPE S2,HOST.2 ;NULL,,GO FINISH UP
SUBI S2,40 ;MAKE IT SIXBIT
IDPB S2,T4 ;SAVE IT
JRST HOST.1 ;AND GO PROCESS ANOTHER
HOST.2: SETZ S2, ;0 FOR NODE NUMBER
$RETT ;AND RETURN
>;END FTJSYS
SUBTTL I%JINF -- Canonical Job Information
;This Call is designed to provide a system independent way of getting Job
;information.
;
; CALL : S1/ JOB NUMBER OR -1 FOR CURRENT JOB
; S2/ FUNCTION CODE
;
;
; RETURN TRUE: S1/ JOB NUMBER PRESERVED FROM CALL
; S2/ RETURNED VALUE FOR FUNCTION
; RETURN FALSE: S1/ ERROR CODE
;
; DEFINED ERROR CODES
;
; ERUJI$ - UNDEFINED JOB INFO FUNCTION
; ERIJN$ - INVALID JOB NUMBER
I%JINF: CAIL S2,JI.MIN ;CHECK FUNCTION RANGE
CAILE S2,JI.MAX ;WITHIN BOUNDS
$RETE(UJI) ;UNDEFINED JOB INFO FUNCTION
MOVE S2,JINFTB-1(S2) ;GET THE DATA
SKIPL S2 ;FUNCTION CODE OR ROUTINE
JRST JINF.1 ;FUNCTION CODE DO THE WORK
HRRZS S2 ;GET ROUTINE ADDRESS
PJRST (S2) ;PROCESS THE FUNCTION
JINF.1:
TOPS10<
HRL S2,S1 ;PLACE JOB NUMBER IN LEFT HALF
GETTAB S2, ;GET THE INFO
$RETE(IJN) ;INVALID JOB NUMBER
$RETT ;RETURN TRUE
>;END TOPS10
TOPS20<
$SAVE T1 ;SAVE T1
MOVE T1,S2 ;GET THE FUNCTION CODE
MOVSI S2,-1 ;1 WORD TO RETURN
HRRI S2,T1 ;RESULT IN T1
GETJI ;GET THE INFO
$RETE(IJN) ;INVALID JOB NUMBER
MOVE S2,T1 ;GET RETURNED DATA
$RETT ;RETURN TRUE
>;END TOPS20
;JOB INFO FUNCTION DISPATCH TABLE
DEFINE X(A,B,C),<
JI.'A==JI.'A ;GET SYMBOLS
TOPS10<C>
TOPS20<B>
>;END X
JINFTB: JBTAB ;EXPAND THE TABLE
SUBTTL I%JINF ROUTINES FOR THE -10
TOPS10<
;GET THE PATH DIRECTORY
GJBPTH: PUSHJ P,.SAVET ;SAVE THE T REGS
MOVS T1,S1 ;PUT JOB NUMBER IN T1
HRRI T1,.PTFRD ;READ DIRECTORY PATH
MOVSI S2,3 ;LENGTH OF BLOCK
HRRI S2,T1 ;ADDRESS OF BLOCK
PATH. S2, ;DO THE FUNCTION
$RETE(IJN) ;INVALID JOB NUMBER
MOVE S2,T3 ;GET THE PPN
$RETT ;RETURN TRUE
;GET THE CONTROLLING JOB NUMBER
GJBCJB: MOVE S2,S1 ;GET JOB NUMBER
CTLJOB S2, ;GET CONTROLLING JOB
$RETE(IJN) ;INVALID JOB NUMBER
$RETT ;CONTROLLING JOB OR -1 IF NOT CONTROLLED
;GET THE JOB NUMBER OF MY JOB
GJBJNO: SKIPL S2,S1 ;CHECK IF FOR ME
$RETE(IJN) ;INVALID JOB NUMBER
PJOB S2, ;GET THE JOB NUMBER
$RETT ;RETURN TRUE
;GET THE JOBS TERMINAL NUMBER
GJBTTY: MOVE S2,S1 ;SAVE THE JOB NUMBER
TRMNO. S2, ;GET THE TERMINAL NUMBER
JRST GJBT.1 ;ERROR..CHECK FOR DETACHED
TRZ S2,.UXTRM ;MAKE TERMINAL NUMBER
$RETT ;RETURN TRUE
GJBT.1: MOVN S2,S1 ;GET NEGATIEV JOB NUMBER IN S1
JOBSTS S2, ;DO JOBSTS UUO
$RETE(IJN) ;INVALID JOB NUMBER
TXNN S2,JB.UJA ;JOB NUMBER ASSIGNED
$RETE(IJN) ;INVALID JOB NUMBER
SETOM S2 ;-1 IF DETACHED
$RETT ;RETURN
GJBVER::MOVE S1,.JBVER ;Yes, get our version
$RETT ;Done
GJBRTM: SKIPGE S1 ;Want our job (-1)?
SETZ S1, ;Yes, adjust to RUNTIm UUO convetion
MOVE S2,S1 ;SAVE THE NUMBER AND GET VALUE IN S2
RUNTIM S2, ;Ask the monitor
$RETT ;Give it to user
>;END TOPS10
SUBTTL I%JINF SPECIAL ROUTINES FOR THE -20
TOPS20<
GJBLOC:
PUSHJ P,.SAVET ;SAVE THE ACS
HRRI T1,.JILLO ;GET THE FUNCTION CODE
MOVSI S2,-1 ;1 WORD TO RETURN
HRRI S2,T2 ;RESULT IN T2
HRROI T2,T3 ;POINTER TO T3
GETJI ;GET THE INFO
$RETE(IJN) ;INVALID JOB NUMBER
MOVE T1,[POINT 7,T3] ;SETUP INPUT POINTER
MOVE TF,[POINT 6,S2] ;GET OUTPUT POINTER
SETZ S2, ;SET OUTPUT BUFFER TO NULLS
GJBL.1: ILDB T2,T1 ;GET AN INPUT BYTE
JUMPE T2,.RETT ;NULL,,GO FINISH UP
SUBI T2,40 ;MAKE IT SIXBIT
IDPB T2,TF ;SAVE IT
JRST GJBL.1 ;AND GO PROCESS ANOTHER
GJBVER:: MOVX S1,.FHSLF ;Yes, aim at my process
GEVEC ;Get my entry info
HLRZ S1,S2 ;Get length
CAIN S1,(JRST) ;Is it an old entry vector (JRST start)
JRST [MOVE S1,137 ;Yes, get version ala TOPS-10
$RETT] ;Give that to user
CAIGE S1,2 ;Does it contain a version?
TDZA S1,S1 ;No, return 0
MOVE S1,2(S2) ;Yes, get it
$RETT ;Done
>;END TOPS20
SUBTTL I%WTO - ACK, WTO, WTOR MSG PROCESSOR
;THIS ROUTINE WILL GET A PAGE FROM THE MEMORY MANAGER, SET IT UP
;AS AN ACK, WTO OR WTOR MESSAGE AND THEN CALL $TEXT TO CREATE
;THE MESSAGE BODY.
I%WTO: PUSH P,(P) ;Copy return PC
POP P,RETADR ;And save for final POPJ
POP P,PRMADR ;GET THE PARM ADDRESS.
DMOVEM S1,S1%S2 ;SAVE THE TRASH AC'S.
MOVEM TF,STF ;SAVE TF ACROSS WTO
PUSHJ P,M%GPAG ;GET A PAGE FOR IPCF.
MOVEM S1,WTOSAB+SAB.MS ;SAVE THE PAGE ADDRESS.
MOVEI S2,.OHDRS ;GET OFFSET TO MSG BLOCKS.
STORE S2,.MSTYP(S1),MS.CNT ;SAVE IT IN THE MSG.
ADDI S2,ARG.HD(S1) ;Get addr of first free in msg
MOVEM S2,MSGADR ;Save for building
DEFINE NXTWTO(HERE),<
IFNB <HERE>,<NXTWT:> ;;If this is a definition, just define return loc
IFB <HERE>,<JRST NXTWT>;;Else just return
>;END DEFINE NXTWTO
NXTWTO(HERE) ;Define the loop location for the action routines
AOS S1,PRMADR ;BUMP OVER THE 'JRST'
;Get addr of this entry
SKIPN S1,(S1) ;End of list?
JRST IWTOFN ;Yes, all done
MOVEM S1,THSPRM ;Save arg for computing effective addr
DMOVE S1,S1%S2 ;Get back to user context
MOVEI S1,@THSPRM ;Get addr from block
EXCH S1,THSPRM ;Save for action routine
LDB S1,[POINT 9,S1,8] ;Get op-code field
CAIL S1,WO.MIN ;Is it ..
CAILE S1,WO.MAX ; .. in range?
$STOP (WFO,<WTO Function ^O/S1/ Out of range at address ^O/PRMADR,RHMASK/>)
JRST @WTDSP-WO.MIN(S1) ;In range, do the work, and return via
;NXTWTO We'd like to do a PUSHJ here,
;but that would destroy the user's
;stack context
WTDSP: DEFINE .EAWTO(SUF,CODE),<$SET(WO.'SUF'-WO.MIN,,WTP'SUF')>
$BUILD WO.MAX-WO.MIN+1
ALLWTO
$EOB
;Here when all thru processing the user blocks
IWTOFN: PUSHJ P,I%WT.3 ;Send the message to OPR
PUSH P,RETADR ;Fix up stack for user again
DMOVE S1,S1%S2 ;Get back the users scratch regs
MOVE TF,STF ;Get back caller's TF
POPJ P, ;Go back to call + 1
;Action routines for each of the op-code types in the WTO macro
;Action routine for setting the message type
WTPMTY: MOVE S1,WTOSAB+SAB.MS ;Get address of message
MOVE S2,THSPRM ;Get addr of parameter
STORE S2,.MSTYP(S1),MS.TYP ;Fill in message type
NXTWTO ;Try for next parameter
;Action routine for building the message type line
WTPTYP: MOVEI S1,.WTTYP ;Get code for type block
JRST IWTX.1 ;And do the $TEXT
;Action routine for building the text block
WTPTXT: MOVEI S1,.WTTXT ;Get code for text block
IWTX.1: MOVE S2,MSGADR ;Get addr of message
STORE S1,ARG.HD(S2),AR.TYP ;Save the block type
ADD S2,[POINT 7,ARG.DA] ;CREATE A BYTE PTR TO THE DATA AREA.
MOVEM S2,BYTPTR ;AND SAVE IT.
SETZM BYTCNT ;Clear the # bytes put into message
DMOVE S1,S1%S2 ;Get back to caller's context
$TEXT (IWTODP,<^I/@THSPRM/^0>) ;Fill in the text
MOVE S1,BYTCNT ;Get # chars moved
IDIVI S1,5 ;Convert to words
SKIPE S2 ;Any remainder?
AOS S1 ;Yes, take another word
ADDI S1,ARG.DA ;Account for arg header block
;Fall thru to add variable block
;Here to add a block whose length is in S1 to the message
IWTO.A: MOVE S2,MSGADR ;Get back start of arg block
STORE S1,ARG.HD(S2),AR.LEN ;Set length of block
ADDM S1,MSGADR ;Next block goes farther down
MOVE S2,WTOSAB+SAB.MS ;Get addr of entire message
AOS .OARGC(S2) ;Indicate another arg block is here
PUSH P,T1 ;Save a reg for a second
LOAD T1,.MSTYP(S2),MS.CNT ;Get old length of message
ADDI T1,(S1) ;Account for this block
STORE T1,.MSTYP(S2),MS.CNT ;Update message length
POP P,T1 ;Restore scratch reg
NXTWTO ;Continue scanning the WTO blocks
;Action routine for setting the header flags .MSFLG
WTPMFL: DMOVE S1,S1%S2 ;Get back to caller's context
MOVE S1,@THSPRM ;Get arg word passed
WTPMF1: MOVE S2,WTOSAB+SAB.MS ;And aim at message again
IORM S1,.MSFLG(S2) ;Store the flags
NXTWTO ;Continue
;Action routine for setting the message flags
WTPFLG: DMOVE S1,S1%S2 ;Get back to caller's context
MOVE S1,@THSPRM ;Get arg word passed
WTPFL1: MOVE S2,WTOSAB+SAB.MS ;And aim at message again
IORM S1,.OFLAG(S2) ;Store the flags
NXTWTO ;Continue
;Action routine for filling in the ack code
WTPACK: DMOVE S1,S1%S2 ;Get back to caller's context
MOVE S1,@THSPRM ;Get the users ack code
MOVE S2,WTOSAB+SAB.MS ;Aim at message again
STORE S1,.MSCOD(S2) ;Stuff it in
NXTWTO ;Continue
;Action routine for adding the Object block
WTPOBJ: DMOVE S1,S1%S2 ;Get back to caller's context
HRLI TF,@THSPRM ;Get start adrs of users obj block
MOVE S1,MSGADR ;Get start of next block
MOVX S2,.WTOBJ ;Get block type
STORE S2,ARG.HD(S1),AR.TYP ;Save in block header
MOVEI S1,ARG.DA(S1) ;Point to the block data
HRR TF,S1 ;Set dest. for BLT to data area
ADDI S1,OBJ.SZ-1 ;Compute terminating adrs for BLT
HRRZM S1,WTOBLT ;Save in memory (not in an AC)
DMOVE S1,S1%S2 ;Get back to caller's context
BLT TF,@WTOBLT ;Move in the Obj block
MOVEI S1,OBJ.SZ+ARG.DA ;Get size of space added
PJRST IWTO.A ;Update the message
; IWTODP - $TEXT ACTION ROUTINE TO BUILD THE ACK, WTO, & WTOR.
;THIS ROUTINE IS THE ACTION ROUTINE FOR $TEXT. IT BUILDS THE
;MESSAGE BLOCKS.
IWTODP: IDPB S1,BYTPTR ;SAVE THE BYTE IN THE MSG.
AOS BYTCNT ;BUMP BYTE COUNT
$RETT ;RETURN QUICK !!
SUBTTL WTPACD, WTOOCD ACTION ROUTINES
WTPOCD: SKIPA S2,[EXP .WTOCD] ;OBJECT TYPE BLOCK
WTPACD: MOVEI S2,.WTACD ;APPLICATION CODE BLOCK
JRST WTPN.1 ;USE THE COMMON ROUTINE
SUBTTL MORE WTO ACTION ROUTINES
WTPJBN: SKIPA S2,[EXP .WTJOB] ;Get block type - JOB
WTPNOD: MOVX S2,.WTDES ;Get block type - DEST NODE
WTPN.1: MOVE S1,MSGADR ;Get first free in message
STORE S2,ARG.HD(S1),AR.TYP ;Save either block type
MOVE S2,@THSPRM ;Get job # or SIXBIT node name
STORE S2,ARG.DA(S1) ;Save in block
MOVEI S1,ARG.DA+1 ;Get length of block (Hdr + 1 data)
PJRST IWTO.A ;Update message length, arg counts
I%SOPR: MOVEM S1,WTOSAB+SAB.MS ;SAVE THE PAGE ADDRESS IN THE SAB.
I%WT.3: MOVEI S1,PAGSIZ ;GET SIZE OF MESSAGE
MOVEM S1,WTOSAB+SAB.LN ;SAVE IN LENGTH WORD OF WTOSAB
SETZM STF ;CLEAR PACKET MODE FLAG WORD
MOVE S1,WTOSAB+SAB.MS ;GET THE MESSAGE ADDRESS
LOAD S1,.MSTYP(S1),MS.CNT ;GET THE MESSAGE LENGTH
CAMLE S1,MAXPAK## ;CAN WE SEND IT AS A PACKET ???
JRST I%WT.4 ;NO,,SEND IT AS A PAGE
MOVEM S1,WTOSAB+SAB.LN ;YES,,SAVE THE MSG LENGTH IN THE SAB
SETOM STF ;SET THE PACKET MODE IPCF FLAG
I%WT.4: MOVEI S1,SAB.SZ ;PICK UP THE SAB SIZE.
MOVEI S2,WTOSAB ;PICK UP THE SAB ADDRESS.
PUSHJ P,C%SEND ;SEND THE WTO.
JUMPT [SKIPN STF ;MSG WAS SENT OK,,WAS IT A PACKET ??
$RETT ;NO,,THEN JUST RETURN
MOVE S1,WTOSAB+SAB.MS ;YES,,GET THE MESSAGE ADDRESS
PJRST M%RPAG ] ;RETURN THE PAGE AND EXIT
SKIPE RSEFLG ;SEND FAILED,,DO WE RETURN ??
JRST [MOVE S1,WTOSAB+SAB.MS ;YES,,GET THE MESSAGE ADDRESS
PUSHJ P,M%RPAG ;RETURN THE PAGE
$RETF ] ;AND RETURN
CAIE S1,ERRQF$ ;NO -- IS IT RECIEVE OR
CAIN S1,ERSQF$ ; SEND QUOTA ERROR ???
JRST I%WT.4 ;YES -- RETRY
CAIE S1,ERNSP$ ;IS IT NO SUCH PID
CAIN S1,ERSLE$ ;OR SYSTEM LIMITS EXCEEDED?
JRST I%WT.4 ;YES -- RETRY
$FATAL (Send to ORION failed) ;DIE !!
INT%L: ;LABEL THE LITERAL POOL.
LSTOF.
LIT
LSTON.
CEND=:.-1 ;LABEL LAST OTS LOCATION
END