Trailing-Edge
-
PDP-10 Archives
-
FORTRAN-10_V7wLink_Feb83
-
forerr.mac
There are 27 other files named forerr.mac in the archive. Click here to see a list.
SEARCH FORPRM
TV FORERR ERROR HANDLER,7(3260)
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;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.
COMMENT \
***** Begin Revision History *****
1100 CKS 13-Jun-79
New
1403 DAW 6-Apr-81
Get rid of magic JOBDAT numbers that prevents users
from loading FOROTS at places other than 400K.
1437 DAW 17-Apr-81
Change FILOP error code 12 from "No such device" to "Can't OPEN
device"-- open of LPT could cause this.
1464 DAW 21-May-81
Put all "ERR" and "IOERR" messages in this file.
1473 CKS 21-May-81
Many error message fixes.
1504 BL 1-Jun-81 Q10-06141
Prevent TRACEBACK default call from displaying itself.
1532 DAW 14-Jul-81
OPEN rewrite: Base level 1
1533 DAW 14-Jul-81
Errors that were supposed to print input record didn't.
Also they would mess up the error message text for ERRSNS.
1537 DAW 16-Jul-81
More work on OPEN for TOPS-20.
1560 DAW 28-Jul-81
OPEN rewrite: Base level 2
1573 DAW 31-Jul-81
Eliminate typing random CRLF's when ERR= branch taken.
1603 DAW 12-Aug-81
Don't type statement name more than once if many IOERR's
are done.
1611 DAW 17-Aug-81
"%integer overflow" bombed out pgm instead of continuing..
1624 DAW 21-Aug-81
"?Illegal record number" got record number from wrong ac.
1625 DAW 21-Aug-81
Get rid of "DF".
1630 JLC 24-Aug-81
Illegal magtape OP's now illegal.
1642 JLC 27-Aug-81
Replace %FILOP calls with FILOPs.
1645 DAW 28-Aug-81
Get to column 1 before errors on TOPS-10.
1651 DAW 31-Aug-81
Do TRMOP. function to wait for output done before getting HPOS.
(Fix to 1645).
1652 DAW 1-Sep-81
Make "IOE" a "?" error.
1656 DAW 2-Sep-81
Get rid of magic numbers.
1661 BL 4-Sep-81
Fix incorrect info coming from TRACE; & illegal instruction return.
1662 DAW 4-SEP-81
%CALU; user error handling routine.
1665 DAW 8-Sep-81
D.TTY hack.
1706 DAW 11-Sep-81
Lots of changes to error messages, codes, etc.
1725 DAW 18-Sep-81
Better error reporting in OPEN args & dialog strings.
1737 DAW 23-Sep-81
Fix "RBR" error.
1753 DAW 29-Sep-81
IOERR's and LERR's to type the PC.
1760 JLC 5-Oct-81
Print 2 decimal places for time typouts.
1762 DAW 6-Oct-81 Q10-06581
Don't print format with error in wrong place.
1763 DAW 7-Oct-81
Fatal error "?Can't write to LINED file".
1766 DAW 7-Oct-81
Don't type PC flags as part of the PC.
1773 DAW 8-Oct-81
Change "CMU" to "IEM" - internal error in mem. management.
1774 DAW 8-Oct-81
Change message for FILOP. code 52 to "Device is assigned by
another job".
2003 BL 14-Oct-81 Q10-06574
Change data type "0" from "U" to "I".
2013 DAW 19-Oct-81
Fix TRACE to store "..." at end of string, not into a literal.
2022 DAW 22-Oct-81
Better error message for TOPS-20 when the JFNs run out.
2031 DAW 27-Oct-81
Fix smashing of AC if no symbols loaded.
***** Begin Version 7 *****
3035 JLC 5-Feb-82
Add error messages for new binary code. Combine
error message for ordinary I/O and ENCODE/DECODE.
3037 JLC 11-Feb-82
Add new error msg for dump mode IO list too long.
Removed non-fatal error messages for magtape.
3056 JLC 23-Mar-82
Separated error messages from FORERR into FORMSG.MAC.
Fixed error buffer typeout so it doesn't trash the FOROTS
data area if the record is very long. Make TRACE work
in extended sections.
3122 JLC 28-May-82
Rework of error entry. Moved %IOERR into FORERR. Rework
of calling user program.
3125 JLC 3-May-82
Moved the error character to the beginning of the error macros.
3136 JLC 26-Jun-82
Separated the 2nd error number from the type code in the
trap subroutine block.
3140 JLC 2-Jul-82
Get proper PC for $P in extended sections.
3141 JLC 2-Jul-82
Fix to edit 3140.
3147 AHM 8-Jul-82
Fix GETPC so that it doesn't die trying to evaluate the jump
address of PUSHJs and overlay calls. Merely setting the sign
bit on a word that has bit 1 set (such as the PUSHJ
instruction) resulted in a type 3 indirect word that causes an
ill mem ref. Bit 0 must be set and bit 1 must be cleared.
3151 AHM 13-Jul-82
Add a whole new ADRCHK for Tops-20 that decides whether or not
a PC is believable by checking whether it refers to an
existing section. Also, preserve section numbers in GETPC.
3155 AHM 19-Jul-82
Remove a lot of code that discards section numbers around
ADDPCM, TRACEL and SYMSRH. Also, make ADRCHK punt on section
numbers that are greater than 37.
3161 JLC 16-Aug-82
Added $R, to print out a record number from CREC(D).
3162 AHM 23-Aug-82
Make the Tops-20 ADRCHK light FH%EPR when running in a
non-zero section so that addresses getting checked don't have
section 0 interpreted as "our section".
3165 JLC 28-Aug-82
Fix error record typout by rewriting it.
3166 JLC 31-Aug-82
Eliminate ER2PTR ref, fix SYMSRH so it doesn't need XHLLI,
which isn't defined on the -10.
3172 JLC 2-Sep-82
Fix code at NERR1 to get proper PDP to use for NOSYM. Fix
NOSYM so it wasn't fooled by T2 pointing to MAIN. if no
stuff on stack.
3175 JLC 8-Sep-82
Fix $I to get the error bits from the right place.
3176 JLC 9-Sep-82
Installed disk quota exceeded trap.
3200 JLC 24-Sep-82
Save ACs in 3 separate local areas instead of on the stack,
to avoid problems with global stacks. Fix I/O within I/O,
that is, used A.UNIT instead of UNUM(U) to type the unit
number in the fatal message.
3201 JLC 4-Oct-82
Add kluge to prevent tracing arg lists of MTHCPX routines which
don't have an arglist.
3202 JLC 26-Oct-82
Fix AC save routines so they don't use the stack, so that
non-zero section stacks are TRACEable.
3216 JLC 16-Nov-82
Restore the ERSTKP on ERR= and IOSTAT=.
3217 PLB 17-Nov-82
Change ADRCHK to check %FSECT to get FOROTS section.
3225 JLC 24-Nov-82
Type nulls in records and FORMATs as spaces. Fix TRACE for
calls from APR traps.
3231 JLC 14-Dec-82
Fix GETPC for multiple sections of code, allow indexed PUSHJs
and indexed and indirected XMOVEIs.
3240 JLC 20-Dec-82
Fix TRACE called from a user program - was using last stored
trace stack.
3250 JLC 7-Jan-83
Use SVEACS for TRACE instead of %SAVAC, so user can trace
from ERRSET subroutine on I/O warnings.
3252 JLC 12-Jan-83
Fix RENAME error msg reporting, by making $F get an argument,
supplied in the error msg macro.
3253 JLC 14-Jan-83
Fix TRACE so it saves and restores the GETPC return PC.
3260 JLC 17-Jan-83
Fix library error reporting with no symbols so that positive
PC offsets get out. Fix TRACE not to print PCs on every line
if it is the ERRSET routine.
***** End Revision History *****
\
ENTRY %ERINI,%TRACX,%IOERR,%OTSER,%TRPER
EXTERN %UDBAD,%RNAMD,%RNAMU,%FSECT,I.BAT,%PC1,%ABORT,I.XSIR
EXTERN %SETAV,%FREBL,%EOREC,%HALT,%SAVAC,%CIPOS
EXTERN E.NAM
EXTERN %SAVE1,%SAVE2,%SAVE3,AU.ACS
EXTERN %ERRCT,%ERRLM,%ERRSB,%ERRSZ,%ERRBK,%NAMLN
EXTERN %POPJ,%POPJ1
EXTERN %STADD
EXTERN %RIPOS,%SIPOS,%IBYTE
EXTERN FMT.BP,FMT.BG,FMT.SZ,USR.SZ
EXTERN A.END,A.ERR,A.IOS,%CUNIT
EXTERN %FSECT ;FOROTS section,,0
IF10,<
EXTERN %NCHRR ;# chars parsed in string
EXTERN %SRCBP ;Current BP to source string containing error.
EXTERN %MSLVL
>;END IF10
INTERN %ERNM1,%ERNM2,%UNFXD,%FIXED,%ERTYP,%ERPDP,%ERRPC,%ERCHR
INTERN %DFERR,%ERNAM,%LERN1,%LERN2,%TRPDP
SEGMENT CODE
IF10,<
%DFERR: $SNH ;NO DISK-FULL HANDLER NEEDED ON TOPS-10
>
IF20,<
;DISK FULL ERROR HANDLER
;GETS HERE VIA THE SOFWARE INTERRUPT SYSTEM IF THE USER HAS NOT
;STOLEN THE CHANNEL FROM FOROTS. TREATED LIKE ANY OTHER I/O ERROR,
;EXCEPT THAT IF THE PROCESS IS INTERACTIVE, IT DOES A HALTF% TO
;LET THE USER EXPUNGE OR OTHERWISE CLEAN UP THE DISK, AND THEN,
;IF CONTINUED, WILL DEBRK% TO CONTINUE THE PROCESS. IF THE PROCESS
;IS BATCH, WE JUST JUMP OFF TO %ABORT TO CLOSE ALL FILES.
;FOR THE ERR= AND IOSTAT= CASE, IT IS COMPLICATED BY THE FACT
;THAT WE MUST DO A DEBRK%, BUT WE DO NOT WANT TO CONTINUE
;THE PROCESS AT THE INTERRUPTED LOCATION, SO WE MUST SUBSTITUTE
;THE ERR= OR (FOR IOSTAT WITH OLDER .REL FILES) THE RETURN ADDRESS
;FROM THE FOROTS CALL FOR THE INTERRUPT ADDRESS.
%DFERR: SKIPE I.BAT ;BATCH JOB?
JRST SETDBK ;YES. DEBREAK AND HANDLE ERR= OR ABORT
SKIPN A.ERR ;ERR= OR IOSTAT= SPECIFIED?
SKIPE A.IOS
JRST SETDBK ;YES. SET DEBREAK ADDRESS TO ERROR HANDLER
$ECALL DQE ;NO. PRINT DISK QUOTA EXCEEDED MESSAGE
$ECALL ETC ;TELL USER TO EXPUNGE AND CONTINUE
HALTF% ;HALT THE PROCESS
DEBRK% ;CONTINUE THE PROCESS IF CONTINUED
SETDBK: PUSH P,T1 ;SAVE T1 VERY TEMPORARILY
XMOVEI T1,DFDBK ;SET DEBREAK ADDRESS HERE
SKIPN I.XSIR ;USING EXTENDED PSI TABLE?
JRST STDBS0 ;NO
MOVEM T1,%PC1+1
POP P,T1 ;RESTORE T1
DEBRK%
STDBS0: HRRM T1,%PC1 ;STORE PC
POP P,T1 ;RESTORE T1
DEBRK% ;AND DEBREAK
DFDBK: $ECALL DQE,%ABORT ;AND PRINT ERROR MESSAGE AND DIE
> ;END IF20
;HERE FROM ERROR MACROS
;
;CALLS:
;
; $ERR (CHR,COD,N1,N2,MSG,ARGS,FLGS) ;FOROTS ERROR OR PROMPT LINE
; $IOERR (CHR,COD,N1,N2,MSG,ARGS,FLGS) ;I/O ERROR
; $LERR (CHR,COD,N1,N2,MSG,ARGS,FLGS) ;MATHLIB ERROR
; $FERR (CHR,COD,N1,N2,MSG,ARGS,FLGS) ;FORLIB ERROR
; $TERR (CHR,COD,N1,N2,MSG,ARGS,FLGS) ;APR TRAP CALL
;
;CHR INITIAL CHAR FOR ERROR MESSAGE ([, %, ?)
; IF [, MESSAGE IS TERMINATED WITH ]
; IF ?, TYPEAHEAD CLEARED AFTER MESSAGE
; IF NULL, 3-CHAR PREFIX ISN'T TYPED
; IF $, FIRST ARG IS INITIAL CHAR
;COD 3-CHARACTER PREFIX
;N1 ERROR CLASS NUMBER
;N2 2ND ERROR NUMBER
;MSG TEXT OF ERROR MESSAGE
; $ INDICATES AN ARG TO BE SUBSTITUTED INTO THE MESSAGE
; THE CHAR AFTER THE $ GIVES THE FORMAT OF THE SUBSTITUTION
;ARGS LIST OF ARGUMENT ADDRESSES, ONE-TO-ONE CORRESPONDENCE WITH $S
; IN MESSAGE TEXT
;FLGS ERROR FLAGS
;
;THE ERROR MACROS GENERATE 1 WORD IN LINE, SO CAN BE SKIPPED OVER.
;THEY DO NOT ALTER ANY ACS.
%ERINI: XMOVEI T1,ERRSTK ;SETUP ERROR STACK
MOVEM T1,ERSTKP
POPJ P,
%IOERR: POP P,IOERP ;SAVE ARG POINTER
PUSHJ P,SVEACS ;SAVE THE ACS ON THE ERROR STACK
MOVE P2,IOERP ;GET ARG POINTER
MOVEM P2,%ERPTR ;SAVE FOR COMMON ROUTINES
MOVE T2,%NUM1(P2) ;GET ERROR CLASS NUMBER
MOVEM T2,%ERNM1 ;SAVE ERROR CLASS NUMBER
MOVEM T2,%LERN1 ;ALSO SAVE IT SEMI-PERMANENTLY
MOVE T2,%NUM2(P2) ;GET 2ND ERROR NUMBER
MOVEM T2,%ERNM2 ;SAVE 2ND ERROR NUMBER
MOVEM T2,%LERN2 ;ALSO SAVE IT SEMI-PERMANENTLY
XMOVEI T1,%ARGS-1(P2) ;GET ARGUMENT POINTER
MOVEM T1,ARGPTR ;SAVE IT
MOVE T1,%CHR(P2) ;GET CHARACTER
CAIN T1,"$" ;CHARACTER IN ARGUMENT?
PUSHJ P,GETARG ;YES. GET IT
MOVEM T1,%ERCHR ;SAVE IT FOR MESSAGE
;Iff this is a "?" error, do the ERR= or END= stuff
CAIE T1,"?" ;"?" says take ERR= if we can.
JRST NERR1 ;Not fatal, just go type message
;Fatal error. Clear %UDBAD
; This is so all the IOLST. calls that follow an IO call that gets
; a fatal error will not screw up things any more.
SKIPGE %ERNM2 ;EOF?
SKIPN T1,A.END ;Yes, use END= address not ERR=
;But if no END= specified, use ERR=
MOVE T1,A.ERR ;Get ERR= Address
JUMPE T1,NERR ;IF ANY
;Take END= or ERR= branch.
;Address of where to go is in T1.
;T2 contains the error number
MOVE P,AU.ACS ;GET ADDR OF USER'S ACS
MOVE P,P(P) ;GET THE OLD STACK
MOVEM T1,(P) ;Store return address
ADJSP P,1 ;WE NEED OUR ACS BACK
PUSHJ P,%EMSGT ;Get error message text for ERSNS.
PUSHJ P,DEALCB ;Deallocate RENAMD, RENAMU if necessary
PUSHJ P,FXTRET ;FIXUP STUFF TO RETURN
MOVE T2,%ERNM2 ;GET 2ND ERROR NUMBER
SKIPE T1,A.IOS ;Any IOSTAT=?
MOVEM T2,(T1) ;Yes, store it
MOVNI T1,20 ;ADJUST ERROR STACK POINTER
ADDM T1,ERSTKP ;TOSS THE SAVED FOROTS ACS
POPJ P, ;RETURN TO USER PROGRAM
;No END= or ERR= specified
NERR: SKIPN A.IOS ;How about IOSTAT=?
JRST NERR1 ;No
;Return to next statement in the program.
PUSHJ P,%EMSGT ;Get error message text for ERRSNS.
PUSHJ P,DEALCB ;Deallocate RENAMD, RENAMU if necessary
PUSHJ P,FXTRET ;Fixup stuff to return
MOVE P,AU.ACS ;GET ADDR OF USER'S ACS
MOVE P,P(P) ;RESET STACK
ADJSP P,1 ; Fix so we get our acs back
MOVE T2,%ERNM2 ;GET 2ND ERROR NUMBER
MOVEM T2,@A.IOS ;STORE IN IOSTAT VARIABLE
MOVNI T1,20 ;ADJUST ERROR STACK POINTER
ADDM T1,ERSTKP ;TOSS THE SAVED FOROTS ACS
POPJ P, ;Return to next statement in pgm.
;Routine to fixup stuff to return from IO error.
FXTRET: SKIPN %UDBAD ;ANY DDB ALLOCATED?
POPJ P, ;No. Don't deallocate
TXNE F,F%DCU ;Deallocate "D" and "U"?
PUSHJ P,FXTRTD ;Yes, do that
FXTRT1: PJRST %SETAV ;Set associate-variable and return
;Deallocate "U" and "D" before returning.
FXTRTD: MOVEI T1,(U) ;Get address of "U"
PUSHJ P,%FREBLK ;Free it
MOVEI T1,(D) ;Get address of "D"
PJRST %FREBLK ;Free it and return
;Deallocate %RNAMD, %RNAMU if necessary
; having this routine here greatly simplifies error handling in CLOSE.
DEALCB: SKIPN T1,%RNAMD
POPJ P, ;Not necessary
PUSHJ P,%FREBLK
MOVE T1,%RNAMU
PJRST %FREBLK ;Deallocate and return
;Print out the error.
NERR1: MOVE P1,AU.ACS ;GET ADDR OF USER'S ACS
MOVE P1,P(P1) ;GET USER'S STACK PNTR
MOVEM P1,%TRPDP ;SAVE FOR TRACE
PUSHJ P,GETPC ;GET CALLER, CALLED ADDR
MOVEM P1,%ERPDP ;SAVE NEXT STACK IN CASE NO SYMBOLS
MOVEM T1,%ERRPC ;SAVE PC OF CALL
SETZM MSGPC ;ASSUME NO PC DESIRED IN MESSAGE
PUSHJ P,%CHKEL ;CHECK IF WE SHOULD PRINT MESSAGE
JRST CALRET ;DON'T
SKIPE %NAMLN ;NAME LINE ALREADY OUT?
JRST NOPFL ;YES, SKIP I/O NAME LINE
MOVE T1,%ERRPC ;GET ERROR PC
MOVEM T1,MSGPC ;SAVE IT FOR MESSAGE
XMOVEI T2,E.NAM+%EOFF ;POINT TO MESSAGE DESIRED
MOVEM T2,%ERPTR ;SAVE POINTER
PUSHJ P,FOREC ;OUTPUT IT
SETZM MSGPC ;NO PC PRINTOUT ON SUBSEQUENT LINES
MOVE T1,IOERP ;GET ORIGINAL POINTER BACK
MOVEM T1,%ERPTR ;SAVE POINTER
SETOM %NAMLN ;SET FLAG SO WE DON'T GET NAME LINE AGAIN
NOPFL: PUSHJ P,FOREC ;OUTPUT THE MESSAGE
PJRST CALRET ;CALL USER ROUTINE, RESTORE ACS, RETURN
%TRPER: POP P,%ERPTR ;GET ERROR BLOCK POINTER
PUSHJ P,SVEACS ;SAVE THE ACS ON THE ERROR STACK
MOVE T1,%ERPDP ;GET USER'S PDP
MOVEM T1,%TRPDP ;SAVE FOR TRACE
MOVE T1,%ERRPC ;GET ERROR PC
MOVEM T1,MSGPC ;SAVE FOR MESSAGE
MOVE T1,%ERPTR ;GET ERROR BLOCK POINTER
MOVE T2,%NUM1(T1) ;GET ERROR CLASS NUMBER
MOVEM T2,%ERNM1 ;SAVE ERROR CLASS NUMBER
MOVE T2,%NUM2(T1) ;GET 2ND ERROR NUMBER
MOVEM T2,%ERNM2 ;SAVE 2ND ERROR NUMBER
PUSHJ P,%CHKEL ;CHECK IF WE WANT MESSAGE
JRST CALRET ;WE DON'T
PUSHJ P,FOREC ;OUTPUT THE MESSAGE
PJRST CALRET ;CALL USER ROUTINE, RESTORE ACS, RETURN
%OTSER: POP P,%ERPTR ;GET ERROR BLOCK POINTER
MOVEM P,%ERPDP ;SAVE CALLER ADDR FOR MSG
PUSHJ P,SVEACS ;SAVE ACS
MOVE T1,AU.ACS ;GET ADDR OF USER'S ACS
MOVE T1,P(T1) ;GET USER'S STACK PNTR
MOVEM T1,%TRPDP ;SAVE FOR TRACE
MOVE T1,%ERPTR ;GET ERROR BLOCK POINTER
MOVE T2,%NUM1(T1) ;GET ERROR CLASS NUMBER
MOVEM T2,%ERNM1 ;SAVE ERROR CLASS NUMBER
MOVE T2,%NUM2(T1) ;GET 2ND ERROR NUMBER
MOVEM T2,%ERNM2 ;SAVE 2ND ERROR NUMBER
SETZM %ERRPC ;NO PC TO GIVE
SETZM MSGPC ;DON'T PRINT PC IN GENERAL
PUSHJ P,%CHKEL ;CHECK IF WE WANT MESSAGE
JRST CALRET ;WE DON'T
PUSHJ P,FOREC ;OUTPUT MESSAGE
PJRST CALRET ;RESTORE ACS, RETURN
FENTRY (MTHER,FORER)
POP P,%ERPTR ;SAVE ERROR BLOCK POINTER
MOVEM P,%TRPDP ;SAVE PDP FOR TRACE
PUSHJ P,SVEACS ;SAVE ACS ON STACK
MOVE T1,%ERPTR ;GET ERROR BLOCK POINTER
MOVE T2,%NUM1(T1) ;GET ERROR CLASS NUMBER
MOVEM T2,%ERNM1 ;SAVE ERROR CLASS NUMBER
MOVE T2,%NUM2(T1) ;GET 2ND ERROR NUMBER
MOVEM T2,%ERNM2 ;SAVE 2ND ERROR NUMBER
MOVE P1,%TRPDP ;GET ERROR STACK PNTR AGAIN
PUSHJ P,GETPC ;GET CALLER ADDR
MOVEM T1,%ERRPC ;SAVE IT
MOVEM T1,MSGPC ;SAVE FOR MESSAGE
MOVE T1,-1(T2) ;GET NAME OF LIBRARY ROUTINE
MOVEM T1,%ERNAM ;SAVE FOR MESSAGE
MOVEM P1,%ERPDP ;SAVE USER'S STACK PNTR
PUSHJ P,%CHKEL ;CHECK IF WE WANT MESSAGE
JRST CALRET ;WE DON'T
PUSHJ P,FOREC ;OUTPUT MESSAGE
CALRET: PUSHJ P,ECALU ;CALL USER SUBROUTINE
PUSHJ P,ECALB ;CALL DEBUGGER BREAK IF ANY
MOVNI T1,20 ;DROP THE ERROR STACK POINTER
ADDM T1,ERSTKP ;A BLOCK OF ACS
HRLZ 16,ERSTKP ;RESTORE ACS
BLT 16,16
POPJ P,
FOREC: MOVE P2,%ERPTR ;POINT TO ERROR BLOCK
PUSHJ P,EMSGT0 ;Get error message text
SKIPE MSGPC ;PC TO PRINT?
PUSHJ P,ADDPCM ;YES. Add PC to message text.
PUSHJ P,EMSGT1 ;Append null to string so can output msg.
MOVEI T1,ERRBUF ;POINT TO MESSAGE
HRLI T1,(POINT 7)
PUSHJ P,%EOREC ;TYPE MESSAGE
MOVE T1,%FLGS(P2) ;GET FLAGS
TXNE T1,I%REC ;TYPE RECORD WITH ARROW UNDER IT IF REQUESTED
JRST RECTYP
TXNE T1,I%REC1 ;TYPE RECORD WITH ARROW MOVED back 1
JRST RCTYB1
TXNE T1,I%FMT ;TYPE FORMAT WITH ARROW UNDER IT
JRST FMTTYP
IF10,<
TXNE T1,I%TCH ;Type character string in error?
JRST CHSTYP
>;END IF10
MOVE T1,INICHR ;GET THE INITIAL CHAR AGAIN
CAIN T1,"@" ;WAS IT REALLY BAD?
JRST %HALT ;YES. STOP EVERYTHING
POPJ P,
%CHKEL: MOVE T1,%ERPTR ;GET ERROR BLOCK POINTER
MOVE T2,%NUM1(T1) ;GET 1ST ERROR NUMBER
JUMPL T2,%POPJ1 ;IF NEGATIVE, DON'T CHECK LIMITS
CAIL T2,%ERRSZ ;WITHIN ERROR TABLE?
JRST %POPJ1 ;NO. DON'T CHECK ANYTHING
AOS %ERRCT(T2) ;INCREMENT LIBRARY ERROR COUNT
MOVE T3,%CHR(T1) ;GET INITIAL CHARACTER
CAIN T3,"?" ;FATAL ERROR?
JRST %POPJ1 ;YES. DON'T CHECK LIMITS
MOVE T3,%ERRCT(T2) ;GET # ERRORS SO FAR
CAMG T3,%ERRLM(T2) ;PAST LIMIT?
AOS (P) ;NO. SKIP RETURN
POPJ P,
ECALB: SKIPN P1,%ERRBK ;GET BREAK ADDR
POPJ P, ;NONE
MOVE T1,%ERNM1 ;GET ERROR CLASS #
MOVEM T1,%EARG1 ;SAVE IT
MOVE T1,%ERRPC ;GET PC
MOVEM T1,%EARG2 ;SAVE IT
MOVE T1,%ERNM2 ;GET 2ND ERROR NUMBER
MOVEM T1,%EARG3 ;SAVE IT
XMOVEI L,%EARGL ;POINT TO ARGLST
PJRST (P1) ;** Call user routine **
ECALU: SKIPGE T1,%ERNM1 ;GET ERROR CLASS, NO SUBR IF NEGATIVE
POPJ P,
CAIGE T1,%ERRSZ ;WITHIN TABLE?
SKIPN P1,%ERRSB(T1) ;YES. ANY USER TRAP ROUTINE SPECIFIED?
POPJ P, ;NO. RETURN
MOVEM T1,%EARG1 ;SAVE IT
MOVE T1,%ERRPC ;GET PC
MOVEM T1,%EARG2 ;SAVE IT
MOVE T1,%ERNM2 ;GET 2ND ERROR NUMBER
MOVEM T1,%EARG3 ;SAVE IT
DOCALU: XMOVEI L,%EARGL ;POINT TO ARGLST
PJRST (P1) ;** Call user routine **
-4,,0
%EARGL: IFIW TP%INT,%EARG1
IFIW TP%INT,%EARG2
IFIW TP%INT,%EARG3
IFIW TP%INT,%ERTYP
IFIW TP%UDF,%UNFXD
IFIW TP%UDF,%FIXED
SEGMENT DATA
ERSTKP: BLOCK 1 ;ERROR AC STACK POINTER
ERRSTK: BLOCK 60 ;ERROR AC STACK
MSGPC: BLOCK 1 ;PC FOR MESSAGE
AERACS: BLOCK 1 ;ADDRESS OF SAVED ACS
IOERP: BLOCK 1 ;IOERR PNTR SAVE LOC
;ARGS FOR USER ROUTINE
%EARG1: BLOCK 1 ;ERROR CLASS NUMBER
%EARG2: BLOCK 1 ;PC
%EARG3: BLOCK 1 ;ERROR 2ND NUMBER
%ERTYP: BLOCK 1 ;VARIABLE TYPE
%UNFXD: BLOCK 4 ;UNFIXED RESULT
%FIXED: BLOCK 4 ;FIXED RESULT
%LERN1: BLOCK 1 ;ERROR CLASS NUMBER, NOT CLEARED
%LERN2: BLOCK 1 ;2ND ERROR NUMBER, NOT CLEARED
%ERNM1: BLOCK 1 ;ERROR CLASS NUMBER
%ERNM2: BLOCK 1 ;2ND ERROR NUMBER
%ERNAM: BLOCK 1 ;ROUTINE NAME FOR MESSAGE
%ERRPC: BLOCK 1 ;PC TO TYPE
%ERPTR: BLOCK 1 ;POINTER TO ERROR BLOCK
%ERPDP: BLOCK 1 ;STACK POINTER FOR GETPC, NOSYM
%ERCHR: BLOCK 1 ;ERROR CHAR FOR I/O ERRORS
%TRPDP: BLOCK 1 ;PDP FOR TRACE
SEGMENT CODE
;Routine to save the acs
;Call: PUSHJ P,SVEACS
; <return here>
SVEACS: DMOVEM 0,@ERSTKP ;SAVE 0 AND 1
MOVE 1,ERSTKP ;GET BASE OF SAVED ACS
MOVEM 1,AERACS ;SAVE FOR MSG
MOVEI 0,(1) ;SETUP FOR BLT
ADD 0,[2,,2] ;SAVE 2-17
BLT 0,17(1)
MOVEI 0,20 ;AND ADJUST THE ERROR STACK
ADDM 0,ERSTKP
POPJ P,
;%EMSGT - Get error message text in ERRBUF.
; This routine just sets it up, it does not type it.
; (In case of taking the ERR= branch you don't want to!).
;Input:
;P2 points to error arg block.
%EMSGT: PUSHJ P,EMSGT0 ;Get message text with no null
;Enter here to append null to error string
EMSGT1: MOVE T1,INICHR ;GET INITIAL CHAR AGAIN
CAIE T1,"[" ;OPEN BRACKET?
JRST EMSNUL ;NO. GO INSERT NULL
MOVEI T1,"]" ;YES, TYPE CLOSING BRACKET
PUSHJ P,EPUTCH
EMSNUL: SETZ T1, ;And store a null
IDPB T1,ERRPTR
POPJ P, ;Return
EMSGT0: MOVE P3,%MSG(P2) ;MAKE POINTER TO INPUT ERROR STRING
MOVE T1,[POINT 7,ERRBUF] ;SET POINTER TO START OF OUTPUT ERR STRING
MOVEM T1,ERRPTR
MOVEI T1,5*LERRBF-1 ;SET COUNT (LEAVE SPACE FOR A NULL)
MOVEM T1,ERRCNT
XMOVEI T1,%ARGS-1(P2) ;GET ARG POINTER
MOVEM T1,ARGPTR
MOVE T1,%CHR(P2) ;GET INITIAL CHAR
CAIN T1,"$" ;INDIRECT CHAR?
PUSHJ P,GETARG ;YES, GET PREFIX CHAR
MOVEM T1,INICHR ;SAVE IT
CAIN T1,"@" ;IS IT REALLY BAD?
MOVEI T1,"?" ;YES. SUBSTITUTE A QUERY
PUSHJ P,TYPEQM ;Type it.
ENXTCH: ILDB T1,P3 ;GET NEXT CHAR FROM MSG
JUMPE T1,%POPJ ;END. WE'RE DONE
CAIE T1,"$" ;SPECIAL CHAR?
JRST ECHR ;NO, JUST NORMAL TEXT CHAR
SETZ T2, ;CLEAR ARG
ERARGL: ILDB T1,P3 ;GET CHAR AFTER $
CAIL T1,"0" ;DIGIT?
CAILE T1,"9"
JRST ERRCMD ;NO, GO EXECUTE COMMAND CHAR
IMULI T2,^D10 ;ADD DIGIT INTO ARGUMENT
ADDI T2,-"0"(T1)
JRST ERARGL ;GO FINISH ARG
ERRCMD: MOVEM T2,ERRARG ;SAVE ARGUMENT TO COMMAND
MOVSI T2,-LERRTB ;GET AOBJN POINTER TO ERR TABLE
ERTBLP: HLRZ T3,ERRTAB(T2) ;GET CHAR
CAIE T1,(T3) ;MATCH?
AOBJN T2,ERTBLP ;NO, KEEP LOOKING
JUMPGE T2,ENXTCH ;NOT FOUND, IGNORE
HRRZ T2,ERRTAB(T2) ;GET ROUTINE ADDRESS
PUSHJ P,(T2) ;CALL ROUTINE
JRST ENXTCH ;LOOP
ECHR: PUSHJ P,EPUTCH ;PUT CHAR IN OUTPUT STRING
JRST ENXTCH ;LOOP
;TABLE OF SPECIAL CHAR ACTIONS IN MESSAGES
ERRTAB: XWD "$",$$ ;TYPE $
XWD "[",$LAB ;TYPE LEFT ANGLE BRACKET
XWD "O",$O ;OCTAL NUMBER
XWD "D",$D ;DECIMAL NUMBER
XWD "A",$A ;ASCIZ STRING
XWD "C",$C ;ASCII CHAR, RIGHT-JUSTIFIED
XWD "S",$S ;SIXBIT WORD
XWD "R",$R ;RECORD NUMBER
XWD "L",$L ;TYPE VALUE AS SYMBOL+OFFSET
XWD "N",$N ;NAME OF ROUTINE (SIXBIT) FROM %ERNAM [NO ARG]
XWD "X",$X ;XWD FORMAT, OCTAL
XWD "5",$5 ;RADIX50 WORD
XWD "T",$T ;SPACES TO GET TO COL N
IF20,< XWD "J",$J > ;JSYS ERROR MESSAGE [NO ARG]
XWD "Y",$Y ;MS TIME AS HH:MM:SS.SS
XWD "P",$P ;ERROR PC, OCTAL [NO ARG]
IF10,< XWD "E",$E > ;LOOKUP/ENTER/RENAME ERROR STRING
IF10,< XWD "I",$I > ;IO ERROR BITS CONVERTED TO ASCII [USES (D)]
XWD "F",$F ;FILESPEC FROM DDB [NO ARG, USES (D)]
IF10,< XWD "Z",$Z > ;SIXBIZ OR ASCIZ STRING
IF20,< XWD "Z",$A > ;SIXBIZ OR ASCIZ STRING
XWD "U",$U ;UNIT NUMBER, DON'T TYPE IF NEGATIVE [NO ARG]
LERRTB==.-ERRTAB
$LAB: SKIPA T1,["<"] ;TYPE LEFT ANGLE BRACKET [BALANCING >]
$$: MOVEI T1,"$" ;TYPE $
PJRST EPUTCH
$U: MOVE T1,%CUNIT ;GET UNIT #
JUMPL T1,%POPJ ;DON'T PRINT NEGATIVE UNITS
PUSH P,T1 ;SAVE THE UNIT NUMBER
MOVEI T1,[ASCIZ /unit /]
PUSHJ P,ASCTYP
POP P,T1 ;GET THE UNIT NUMBER AGAIN
MOVEI T3,^D10 ;RADIX 10
PJRST NUMLP ;OUTPUT IT
$R: MOVE T1,CREC(D) ;GET CURRENT RECORD NUMBER
JRST DPOS ;GO PRINT IT
$D: PUSHJ P,GETARG ;GET NUMBER TO TYPE
DNOUT: JUMPGE T1,DPOS ;ALL OK IF IT'S POSITIVE
PUSH P,T1 ;NEGATIVE, TYPE MINUS SIGN
MOVEI T1,"-"
PUSHJ P,EPUTCH
POP P,T1
MOVM T1,T1
DPOS: MOVEI T3,^D10 ;RADIX 10
JRST NUMLP
$C: PUSHJ P,GETARG
CAIL T1," "
PJRST EPUTCH
PUSH P,T1
MOVEI T1,"^"
PUSHJ P,EPUTCH
POP P,T1
ADDI T1,100
PJRST EPUTCH
$N: MOVE T2,%ERNAM
NOPLP: JUMPE T2,%POPJ ;DONE IF ONLY SPACES LEFT
SETZ T1, ;CLEAR CHAR
LSHC T1,6 ;GET CHAR
ADDI T1,40 ;CONVERT TO ASCII
CAIE T1,"." ;PRINT IF NOT DOT
PUSHJ P,EPUTCH ;OUTPUT CHAR
JRST NOPLP
$S: PUSHJ P,GETARG
SIXTYP: MOVE T2,T1
S1: JUMPE T2,%POPJ
SETZ T1,
LSHC T1,6
ADDI T1,40
PUSHJ P,EPUTCH
JRST S1
$X: PUSHJ P,GETARG
XWDTYP: PUSH P,T1
HLRZ T1,T1
PUSHJ P,OCTTYP
MOVEI T1,","
PUSHJ P,EPUTCH
POP P,T1
MOVEI T1,(T1)
PJRST OCTTYP
$OFFS: PUSHJ P,GETARG ;GET ARG
OFFTYP: JUMPE T1,%POPJ ;DON'T TYPE 0
PUSH P,T1 ;SAVE IT
CAIGE T1,0 ;POSITIVE?
SKIPA T1,["-"] ;NO
MOVEI T1,"+" ;YES
PUSHJ P,EPUTCH ;TYPE SIGN
POP P,T1
MOVM T1,T1
JRST OCTTYP ;TYPE OCTAL NUMBER
$O: SKIPE ERRARG ;$1O MEANS TYPE SIGN FIRST
JRST $OFFS
PUSHJ P,GETARG ;GET ARG IN T1
OCTTYP: MOVEI T3,^D8
NUMLP: LSHC T1,-^D35
LSH T2,-1
DIVI T1,(T3)
JUMPE T1,.+4
PUSH P,T2
PUSHJ P,NUMLP
POP P,T2
MOVEI T1,"0"(T2)
PJRST EPUTCH
$P: MOVE T1,%ERPDP ;GET PDP OF ERROR.
MOVE T1,(T1) ;GET THE CALLER ADDR+1
SUBI T1,1 ;GET ADDR OF CALL
SKIPN %FSECT ;NON-ZERO SECTION?
MOVEI T1,(T1) ;NO. EXCLUDE FLAGS
PJRST OCTTYP ;TYPE IT IN OCTAL
$Y: PUSHJ P,GETARG ;GET TIME IN MS
ADDI T1,5 ;ROUND TO HUNDREDTHS
IDIVI T1,^D10
IDIVI T1,^D100 ;GET SECONDS AND HUNDREDTHS
PUSH P,T2 ;SAVE HUNDREDTHS
PUSHJ P,XTIME ;TYPE HH:MM:SS
MOVEI T1,"." ;TYPE .S
PUSHJ P,EPUTCH
POP P,T1 ;GET HUNDREDTHS
IDIVI T1,^D10 ;BREAK INTO 2 DIGITS
ADDI T1,"0" ;MAKE ASCII
PUSHJ P,EPUTCH ;OUTPUT IT
MOVEI T1,"0"(T2) ;MAKE 2ND DIGIT ASCII
PJRST EPUTCH ;TYPE IT
XTIME: IDIVI T1,^D60 ;GET BASE-60 DIGIT
JUMPE T1,TIMEX ;IF LAST ONE, DONE
PUSH P,T2 ;SAVE A DIGIT
PUSHJ P,XTIME ;TYPE REST OF NUMBER
MOVEI T1,":" ;TYPE COLON
PUSHJ P,EPUTCH
POP P,T2 ;GET DIGIT BACK
IDIVI T2,^D10 ;GET 2 DECIMAL DIGITS
MOVEI T1,"0"(T2) ;TYPE 2-DIGIT NUMBER
PUSHJ P,EPUTCH
MOVEI T1,"0"(T3)
PJRST EPUTCH
TIMEX: IDIVI T2,^D10 ;GET HIGH-ORDER DIGITS
MOVEI T1,"0"(T2)
CAIE T1,"0"
PUSHJ P,EPUTCH
MOVEI T1,"0"(T3)
PJRST EPUTCH
$L: PUSHJ P,GETARG ;GET PC TO CONVERT
MOVEM T1,ORGADR ;SAVE IT
PUSHJ P,SYMCNV ;CONVERT TO LABEL + OFFSET
SKIPN T1,SYMNAM ;GET SYMBOL NAME
JRST MODCNV ;NONE. PRINT MODULE + OFFSET
PUSHJ P,R50TYP ;TYPE IT
MOVE T1,SYMOFF ;GET OFFSET FROM SYMBOL
PJRST OFFTYP ;TYPE IT
MODCNV: MOVE P1,%ERPDP ;GET USER'S PDP
SETZM EADDR
NSYM0: PUSHJ P,GETPC ;GET A PC FROM STACK
JUMPE P1,NSYM1 ;NONE LEFT, DONE
CAML T2,EADDR ;BETTER THAN PREVIOUS BEST APPROXIMATION?
CAMLE T2,ORGADR ;YES, BUT NOT PAST ARG PC?
JRST NSYM0 ;NO, SKIP IT
MOVEM T2,EADDR ;SAVE ROUTINE ADDRESS
JRST NSYM0 ;LOOK THROUGH WHOLE STACK
NSYM1: SKIPN P1,EADDR ;GET ROUTINE ADDRESS
SKIPA P1,%STADD ;NONE FOUND, USE MAIN START ADDRESS
SKIPA T1,-1(P1) ;GET ROUTINE NAME
MOVE T1,['MAIN. '] ;OR MAIN PROGRAM NAME
PUSHJ P,SIXTYP ;TYPE IT
MOVE T1,ORGADR ;GET ARG PC
SUB T1,P1 ;SUBTRACT ROUTINE ADDRESS
PJRST OFFTYP ;TYPE OFFSET
;Routine called to append the PC to the error message.
ADDPCM: MOVEI T1,[ASCIZ/ at /]
PUSHJ P,ASCTYP
MOVE T1,MSGPC ;[3155] Get PC
MOVEM T1,ORGADR ;SAVE FOR CONVERSION
PUSHJ P,SYMCNV ;CONVERT TO LABEL+OFFSET
SKIPN T1,SYMNAM ;GET SYMBOL NAME
JRST NOSYM ;NONE. TRY SEARCHING MODULE NAMES
PUSHJ P,R50TYP ;TYPE RADIX50 SYMBOL
MOVE T1,SYMOFF ;GET OFFSET FROM SYMBOL
PUSHJ P,OFFTYP ;TYPE IT AS SIGNED OCTAL
MOVEI T1,[ASCIZ / in /] ;TYPE NOISE WORD FOR MODULE NAME
PUSHJ P,ASCTYP
MOVE T1,SYMMOD ;GET MODULE NAME
PUSHJ P,R50TYP ;TYPE IT TOO
PCTYP: MOVEI T1,[ASCIZ / (PC /] ;FINISH UP WITH THE OCTAL ADDRESS
PUSHJ P,ASCTYP
HLRZ T1,MSGPC ;GET SECTION #
JUMPE T1,PCTYP0
PUSHJ P,OCTTYP ;Type section #
MOVEI T1,","
PUSHJ P,EPUTCH
PUSHJ P,EPUTCH ;",,"
PCTYP0: HRRZ T1,MSGPC ;GET LOCAL ADDR
PUSHJ P,OCTTYP
MOVEI T1,")"
PJRST EPUTCH
NOSYM: MOVE P1,%ERPDP ;GET USER'S PDP
PUSHJ P,GETPC ;GET A PC FROM STACK
JUMPE P1,USMAIN ;NONE. USE MAIN.
MOVE P1,T2 ;GET ROUTINE ADDR
MOVE T1,-1(P1) ;GET ROUTINE NAME
JRST NSTYPE ;GO TYPE THEM
USMAIN: MOVE P1,%STADD ;NONE FOUND, USE MAIN START ADDRESS
MOVE T1,['MAIN. '] ;OR MAIN PROGRAM NAME
NSTYPE: PUSHJ P,SIXTYP ;TYPE IT
MOVE T1,ORGADR ;GET ARG PC
SUB T1,P1 ;SUBTRACT ROUTINE ADDRESS
PUSHJ P,OFFTYP ;TYPE OFFSET
PJRST PCTYP ;GO TYPE PC IN OCTAL
$5: PUSHJ P,GETARG ;GET ARG IN T1
JUMPE T1,%POPJ
PUSH P,T1
MOVEI T1," "
PUSHJ P,EPUTCH
POP P,T1
R50TYP:
R50LP: IDIVI T1,50
JUMPE T1,.+4
PUSH P,T2
PUSHJ P,R50LP
POP P,T2
JUMPE T2,%POPJ
MOVEI T1,<"0"-R50(0)>(T2)
CAILE T1,"9"
ADDI T1,"A"-R50(A)-"0"+R50(0)
CAILE T1,"Z"
SUBI T1,-<"$"-R50($)-"A"+R50(A)>
CAIN T1,"$"-1
MOVEI T1,"."
JRST EPUTCH
EPUTCH: AOS COLCNT ;KEEP TRACK OF WHAT COL WE'RE ON
SOSL ERRCNT ;DECREMENT COUNT OF CHARS LEFT
IDPB T1,ERRPTR ;SPACE LEFT, STORE CHAR
POPJ P,
;GETARG - GETS THE NEXT ARG ON THE ARGUMENT LIST.
;DOES NOT SUPPORT INDEXING OR INDIRECTION
GETARG: AOS T1,ARGPTR ;GET CURRENT POINTER
MOVE T1,(T1) ;GET ARG ADDR
CAIG T1,17 ;IS ARG IN AC?
JRST ACARG ;YES. GO GET IT
HLL T1,ARGPTR ;ADD SECTION # OF CALLER
MOVE T1,(T1) ;GET ACTUAL ARG
POPJ P,
ACARG: ADD T1,AERACS ;POINT TO SAVED AC
MOVE T1,(T1) ;GET ACTUAL ARG
POPJ P,
IF10,<
XLIST
LIT
LIST
$E: PUSHJ P,GETARG ;GET ERR CODE
CAIL T1,0 ;NEGATIVE?
CAILE T1,LERMAX ;OR TOO BIG?
JRST LERUNK ;YES, TYPE GENERAL-PURPOSE MSG
ADDM T1,%ERNM2 ;Fix error number
IDIVI T1,4 ;GET STRING OFFSET
LDB T1,LERTBL(T2)
CAIN T1,777 ;NO MSG FOR THIS ERROR?
JRST LERUNK ;YES, GO TYPE G.P. MSG
MOVEI T1,LERMSG(T1) ;GET STRING ADDRESS
PJRST ASCTYP ;GO TYPE IT
LERUNK: MOVEI T1,[ASCIZ /Unknown FILOP error, code /]
PUSHJ P,ASCTYP
MOVE T1,@ARGPTR ;GET ERROR CODE BACK
PJRST OCTTYP ;TYPE IT
LERTBL: POINT 9,LERPTR(T1),8
POINT 9,LERPTR(T1),17
POINT 9,LERPTR(T1),26
POINT 9,LERPTR(T1),35
DEFINE X (STRG) <
XOFFS==[ASCIZ \STRG\]-LERMSG
XXX (XOFFS)
>
DEFINE XX (STRG) <
XXX (-1)
>
DEFINE XXX (OFFS) <
XXXWD==XXXWD + <OFFS&777>_<XXXCT*9>
XXXCT==XXXCT-1
IFL XXXCT,<
EXP XXXWD
XXXWD==0
XXXCT==3
>
>
XXXWD==0
XXXCT==3
LERPTR: X No such file ;0
X No such directory ;1
X Protection failure ;2
X File is being modified ;3
X File already exists ;4
XX Illegal sequence of UUOs ;5
X RIB error ;6
XX Bad format .SAV file ;7
XX Insufficient memory ;10
X Device is not available ;11
X Can't OPEN device ;12
XX Illegal UUO ;13
X Device full ;14
X Device is write locked ;15
X Insufficient monitor table space ;16
XX Can't allocate contiguous space ;17
XX Requested block not free ;20
X Can't write a directory ;21
X Directory is not empty ;22
X No such directory ;23
X Search list empty ;24
X SFDs nested too deep ;25
X All structures have NOCREATE set ;26
XX Segment not in swap space ;27
X Can't update file ;30
XX Page overlap ;31
XX Not logged in ;32
X Locks still set ;33
XX Bad format .EXE file ;34
XX Extension must be .EXE ;35
XX .EXE directory too big ;36
X Network full ;37
X Task not available ;40
X No such node ;41
X SFD in use ;42
X File has an NDR lock ;43
X Monitor use count overflow ;44
X Can't rename SFD downward ;45
XX Channel not open ;46
X Device is down ;47
X Device is restricted ;50
X Device must be mounted ;51
X Device is assigned to another job ;52
XX Illegal data mode ;53
XX Unknown OPEN bits ;54
X Device is not available ;55
X Funny space full ;56
X Too many open units ;57
XX Unknown function code ;60
XX Illegal channel number ;61
XX Illegal channel number ;62
LERMAX==62 ;MAX STRING IN TABLE
IFN XXXCT-3,<EXP XXXWD>
LERMSG: ;LIT
XLIST
LIT
LIST
;STILL IF10
;TYPE IO ERROR MESSAGE
$I: PUSHJ P,%SAVE3 ;SAVE P ACS
MOVEI T1,[ASCIZ /IO error /]
PUSHJ P,ASCTYP
PUSHJ P,GETARG ;GET BITS
HRLZ P1,T1 ;SAVE THEM, IN LH
PUSHJ P,OCTTYP ;TYPE THEM IN OCTAL
MOVE D,AERACS ;GET ADDRESS OF SAVED ACS
MOVE D,D(D) ;GET DDB POINTER
TLZ P1,-1-IO.ERR-IO.EOF-IO.EOT ;CLEAR BORING BITS
LOAD T4,DVTYP(D) ;GET DEVTYP
CAIN T4,.TYMTA ;MTA?
TLZ P1,IO.EOT ;NO, EOT ISN'T REALLY EOT, SO IS BORING
LOAD T1,INDX(D) ;GET DEV INDEX
CAIN T1,DI.DSK ;DISK?
MOVEI T4,.TYDSK ;YES, SPOOLED DEV OR REAL DISK
MOVEI P3,IBUF-1 ;POINT TO BUFFER FOR MSGS
JRST IOENXT ;GO DO FIRST BIT
IOELP: ANDCM P1,[EXP 1B0,1B1,1B2,1B3,1B4,1B5,1B6,1B7](P2) ;CLEAR BIT
DPB P2,[POINT 3,T4,29] ;STORE ERROR CODE WITH DEVTYP
MOVEI T3,(T4) ;COPY ERR BIT & DEV TYP
IOELP1: MOVE T2,[-LITAB,,ITAB] ;POINT TO TABLE
IOELP2: LDB T1,[POINT 9,(T2),9] ;GET ERR BIT & DEVTYP
CAIE T1,(T3) ;MATCH?
AOBJN T2,IOELP2 ;NO, KEEP LOOKING
JUMPL T2,IOEEND ;JUMP IF WE FOUND IT
ORI T3,.TYXXX ;USE DEFAULT IF NOT FOUND
JRST IOELP1
IOEEND: MOVE T2,(T2) ;GET MESSAGE POINTER
PUSH P3,T2 ;SAVE MESSAGE FOR THIS BIT
IOENXT: JFFO P1,IOELP ;DO NEXT BIT
PUSH P3,[0] ;FLAG END OF LIST
MOVEI P1,IBUF
SKIPA T1,[[ASCIZ / (/]] ;FIRST MSG GETS PAREN
MSGLP: MOVEI T1,[ASCIZ /, /] ;OTHERS GET COMMAS
SKIPN P2,(P1) ;GET A MSG
JRST MSGEND ;NONE LEFT
PUSHJ P,ASCTYP ;TYPE PAREN OR COMMA
CAIL P2,0 ;ROUTINE TO CALL?
PUSHJ P,(P2) ;YES, CALL IT
SKIPE T1,P2 ;POINT TO STRING
PUSHJ P,ASCTYP ;TYPE IT
AOJA P1,MSGLP ;LOOP OVER ALL MSGS
MSGEND: MOVEI T1,")" ;TYPE CLOSE PAREN
SKIPE IBUF
PUSHJ P,EPUTCH
HLLZ T2,CHAN(D) ;CLEAR ERROR BITS
HRRI T2,.FOSET
MOVE T3,@ARGPTR ;GET BITS BACK
ANDI T3,-1-IO.ERR ;CLEAR ERR BITS, LEAVE EOF AND EOT
MOVE T1,[2,,T2] ;SET LENGTH, ADDRESS
FILOP. T1, ;DO FILOP
JFCL
POPJ P,
;STILL IF10
.TYXXX==77 ;FAKE DEVTYP FOR DEFAULT DEVICE
DEFINE X (DEV,ERR,FATAL<0>,MSG) <
BYTE (1)1(3)^L<IO.'ERR,,0>(6).TY'DEV(1)FATAL(7)0(18)[ASCIZ \MSG\]
>
DEFINE XS (DEV,ERR,FATAL<0>,SUB) <
BYTE (1)0(3)^L<IO.'ERR,,0>(6).TY'DEV(1)FATAL(7)0(18)SUB
>
ITAB: X CDP,BKT,,card too large
X CDR,IMP,,nonbinary card
X CDR,DTE,,checksum error
X MTA,IMP,1,write locked
X MTA,DTE,,parity error
X MTA,BKT,,record exceeds BLOCKSIZE
X MTA,EOT,1,EOT
X PTR,IMP,,block incomplete
X PTR,DTE,,checksum error
X PTY,BKT,,char lost
X TTY,IMP,1,not assigned
X TTY,DER,1,^C typed
X TTY,DTE,,echo check
X TTY,BKT,,char lost
XS DSK,IMP,1,DSKIMP ;write locked or RIB error
X DSK,DTE,,parity error
XS DSK,BKT,1,DSKBKT ;str full or quota exceeded
X DTA,IMP,1,write locked
X DTA,DTE,,parity error
X DTA,BKT,1,tape full
X XXX,IMP,1,improper mode (whatever that means)
XS XXX,DER,,XXXDER ;device error
X XXX,DTE,,data error
X XXX,BKT,,block too large
X XXX,EOF,,end of file
X XXX,EOT,,EOT ;SNH
LITAB==.-ITAB
SEGMENT DATA
IBUF: BLOCK 6 ;ONE MESSAGE EACH FOR 5 POSSIBLE BITS
DCBLK: BLOCK 1+.DCFCT ;ARG BLOCK FOR DSKCHR
SEGMENT CODE
;STILL IF10
DSKBKT: SKIPN T1,RDEV(D) ;GET STR FILE IS ON
JRST DSKFUL ;CAN'T, JUST SAY DISK FULL
MOVEM T1,DCBLK ;SAVE FOR DSKCHR
MOVE T1,[1+.DCFCT,,DCBLK] ;SET UP FOR DSKCHR
DSKCHR T1,UU.PHY ;FIND SPACE REMAINING
JRST DSKFUL
MOVE P2,[X (DSK,BKT,1,quota or storage exceeded)]
SKIPG DCBLK+.DCUFT ;CHECK BLOCKS LEFT IN QUOTA
MOVE P2,[X (DSK,BKT,1,quota exceeded)]
SKIPG DCBLK+.DCFCT ;CHECK BLOCKS LEFT ON STR
DSKFUL: MOVE P2,[X (DSK,BKT,1,structure full)]
POPJ P,
DSKIMP: SKIPN T1,RDEV(D) ;GET STR NAME
JRST DSKWL ;CAN'T
MOVEM T1,DCBLK ;SAVE FOR DSKCHR
MOVE T1,[1,,DCBLK] ;SET FOR DSKCHR
DSKCHR T1,UU.PHY ;FIND WRITE-LOCK STATUS
JRST DSKWL
TXNE T1,DC.HWP+DC.SWP ;CHECK WRITE PROTECTION
JRST DSKWL ; IT'S WRITE-LOCK
MOVE T1,LKPB+.RBSTS(D) ;GET RIB STATUS WORD
MOVE P2,[X (DSK,IMP,1,checksum error)]
TXNN T1,RP.FCE ;CHECKSUM ERROR?
MOVE P2,[X (DSK,IMP,1,RIB error)] ;NO
POPJ P,
DSKWL: MOVE P2,[X (DSK,IMP,1,write locked)]
POPJ P,
XXXDER: SETZ P2, ;CLEAR OUTPUT MSG, WE'LL DO THE TYPING
MOVEI T1,[ASCIZ /device error/]
PUSHJ P,ASCTYP
LDB T1,[POINTR CHAN(D),FO.CHN] ;GET CHANNEL NUMBER
DEVSTS T1, ;GET CONI AT LAST INTERRUPT
POPJ P, ;CAN'T
PUSH P,T1 ;TYPE IT
MOVEI T1,[ASCIZ /, CONI /]
PUSHJ P,ASCTYP
POP P,T1
PJRST OCTTYP
;STILL IF10
;TYPE FILESPEC FROM DDB POINTED TO BY D
$F: PUSHJ P,GETARG ;GET UDB ADDRESS
JUMPE T1,%POPJ ;IF ZERO, NOTHING TO PRINT
SKIPN D,DDBAD(T1) ;GET DDB POINTER
POPJ P, ;NONE. DON'T PRINT TRASH
SKIPN DEV(D) ;DEVICE
POPJ P, ;NO DEVICE, NO INFO AT ALL
MOVE T1,DEV(D) ;GET DEVICE NAME
PUSHJ P,SIXTYP
MOVEI T1,":"
PUSHJ P,EPUTCH
SKIPN T1,FILE(D) ;FILENAME
POPJ P,
PUSHJ P,SIXTYP
MOVEI T1,"."
SKIPE EXT(D)
PUSHJ P,EPUTCH
HLLZ T1,EXT(D)
PUSHJ P,SIXTYP
SKIPN PTHB+.PTPPN(D) ;PATH
POPJ P,
MOVEI T1,"["
PUSHJ P,EPUTCH
MOVE T1,PTHB+.PTPPN(D)
PUSHJ P,XWDTYP
XMOVEI T1,PTHB+.PTPPN+1(D)
PUSH P,T1
SFDLP: SKIPN @(P)
JRST SFDEND
MOVEI T1,","
PUSHJ P,EPUTCH
MOVE T1,@(P)
PUSHJ P,SIXTYP
AOS (P)
JRST SFDLP
SFDEND: POP P,(P)
MOVEI T1,"]"
PUSHJ P,EPUTCH
POPJ P, ;DONE
> ;IF10
IF20,<
$J: MOVEI T1,.FHSLF ;GET JSYS ERROR NUMBER FOR LAST ERROR
GETER%
ERJMP .+1
MOVEI T2,(T2) ;GET JUST RIGHT HALF
SKIPN %ERNM2 ;IS 2ND ERROR NUMBER 0?
MOVEM T2,%ERNM2 ;YES. STORE JSYS ERROR NUMBER
CAIN T2,GJFX3 ;"No JFNs available"?
JRST NOJFNA ;Yes, doing ERSTR% doesn't help!
MOVE T1,ERRPTR ;GET POINTER TO DESTINATION STRING
HRLI T2,.FHSLF
MOVN T3,ERRCNT ;NEGATIVE OF NUMBER OF CHARS IN BUFFER
MOVSI T3,(T3) ;IN LEFT HALF
ERSTR% ;GET ERROR STRING
JRST ERNSE ;NO SUCH ERROR
TRN ;STRING TOO SHORT, MSG TRUNCATED
MOVEM T1,ERRPTR ;STORE NEW STRING POINTER
HLRE T3,T3 ;GET LEFTOVER COUNT
MOVMM T3,ERRCNT ;SAVE IT
POPJ P,
NOJFNA: MOVEI T1,[ASCIZ/no JFNs available/] ;Get error
PJRST ASCTYP
ERNSE: SKIPA T1,[[ASCIZ /(undefined error number)/]]
ERERR: MOVEI T1,[ASCIZ /(error in ERSTR)/]
PJRST ASCTYP
;Type filespec from DDB
$F: PUSHJ P,GETARG ;GET UDB ADDRESS
JUMPE T1,%POPJ ;IF ZERO, NOTHING TO PRINT
SKIPN D,DDBAD(T1) ;GET DDB POINTER
POPJ P, ;NONE. DON'T PRINT TRASH
LOAD T2,IJFN(D) ;Get JFN of file
JUMPE T2,FNOJFN ;None yet
CAIN T2,.PRIIN ;Can't do JFNS on .PRIIN
JRST NJFNS1
HRROI T1,JFNBUF ;Store filespec in temp buffer
SETZ T3, ;Set for default JFNS
JFNS%
ERJMP FNOJFN ;?can't, JFN must be bogus
JRST NJFNS2
;The JFN is actually .PRIIN
NJFNS1: MOVE T1,[ASCIZ/TTY:/]
MOVEM T1,JFNBUF
NJFNS2: MOVEI T1,JFNBUF ;Point to ASCIZ string to append
PJRST ASCTYP ;Append it and return
;No JFN available
FNOJFN: SKIPN DEV(D) ;ANY DEVICE?
POPJ P, ;NO. NOTHING ELSE, EITHER
XMOVEI T1,DEV(D) ;Put device
PUSHJ P,ASCTYP ;into buffer
MOVEI T1,":"
PUSHJ P,EPUTCH
SKIPN DIR(D) ;Directory known yet?
JRST FLEXGN ;No
TXNE F,F%PPN ;PPN instead of directory string?
JRST NJFNE3 ;Yes, another special case
MOVEI T1,"<"
PUSHJ P,EPUTCH
XMOVEI T1,DIR(D)
PUSHJ P,ASCTYP ;DIRECTORY
MOVEI T1,">"
PUSHJ P,EPUTCH
;Here to finish putting out FILE.EXT.GEN
FLEXGN: SKIPN FILE(D) ;ANY FILE GIVEN?
POPJ P, ;NO. NOTHING MORE TO PRINT
XMOVEI T1,FILE(D)
PUSHJ P,ASCTYP
MOVEI T1,"."
PUSHJ P,EPUTCH
XMOVEI T1,EXT(D)
PUSHJ P,ASCTYP
MOVEI T1,"."
PUSHJ P,EPUTCH
MOVE T1,XGEN(D) ;Get gen number
PJRST DNOUT ;Print decimal # and return
NJFNE3: MOVEI T1,"["
PUSHJ P,EPUTCH
MOVE T1,DEV(D)
PUSHJ P,XWDTYP ;Type nn,,nn
MOVEI T1,"]"
PUSHJ P,EPUTCH
JRST FLEXGN ;Type FILE.EXT.GN and return
SEGMENT DATA
JFNBUF: BLOCK ^D60 ;Buffer for JFNS string
SEGMENT CODE
>;END IF20
$T: MOVE T2,ERRARG ;GET COL TO TAB TO
SUB T2,COLCNT ;GET NUMBER OF SPACES WE NEED
MOVEI T1," "
PUSHJ P,EPUTCH ;TYPE A SPACE
SOJG T2,.-1 ;LOOP UNTIL AT DESIRED COL
POPJ P, ;DONE
IF10,<
$Z: PUSHJ P,GETARG ;GET ADDRESS OF STRING
HRLI T1,(POINT 6,) ;MAKE INTO BYTE POINTER
MOVE T4,T1 ;IN SAFE PLACE
SIXLP: ILDB T1,T4 ;GET CHAR
JUMPE T1,%POPJ ;SPACE TERMINATES STRING
ADDI T1,40 ;CONVERT TO ASCII
PUSHJ P,EPUTCH ;TYPE IT
JRST SIXLP ;LOOP
> ;IF10
$A: PUSHJ P,GETARG ;GET ADDRESS OF STRING
ASCTYP: HRLI T1,(POINT 7,) ;MAKE INTO BYTE POINTER
MOVE T4,T1 ;PUT IN SAFE PLACE
ASCLP: ILDB T1,T4 ;GET CHAR OF STRING
JUMPE T1,%POPJ ;NULL TERMINATES STRING
PUSHJ P,EPUTCH ;TYPE CHAR
JRST ASCLP ;LOOP
;Routine to get initial PREFIX part of message
;CAll: t1/ prefix char
TYPEQM: JUMPE T1,TYPQM1 ;Don't type anything if no char
PUSHJ P,EPUTCH ;Type char
IF10,<
MOVE T1,%MSLVL ;Get message level
TXNN T1,JW.WPR ;Does user want prefix?
JRST NPR ;No, skip it
HLRZ T1,%COD(P2) ;Get 3-letter error code
HRLI T1,'FRS' ;Put in FOROTS prefix
PUSHJ P,SIXTYP ;Type it
MOVEI T1," " ;Follow with space
PUSHJ P,EPUTCH
NPR:
>;END IF10
TYPQM1: SETZM COLCNT ;Start counting cols for tabs
POPJ P, ;Return
;TYPE INPUT RECORD (PRESUMABLY CONTAINING AN ERROR) AND PUT AN ARROW
;UNDER THE ERRONEOUS CHARACTER. THE ERROR POSITION IS GOTTEN FROM RPOS.
RCTYB1: MOVNI T1,1 ;MOVE POINTER BACK 1 CHAR
PUSHJ P,%CIPOS
RECTYP: PUSHJ P,%RIPOS ;GET POSITION OF NEXT CHAR
SUBI T1,1 ;GET POSITION OF BAD CHAR
MOVEI T2,(T1) ;COPY IT
CAILE T2,BEFSIZ ;MORE THAN WILL FIT?
MOVEI T2,BEFSIZ ;YES. SUBSTITUTE JUST ENOUGH
MOVEM T2,ERRPOS ;SAVE FOR PRINTING THE ARROW
SUBI T1,(T2) ;CHOP OFF UNNEEDED CHARS
ADDI T1,1 ;POINT TO CORRECT CHAR
PUSHJ P,%SIPOS
MOVE T1,[POINT 7,ER1BUF] ;PREPARE TO COPY RECORD TO ERROR BUFFER
MOVEM T1,ER1PTR ;SAVE PNTR
MOVE T3,ERRPOS ;GET POSITION OF BAD CHAR
SOJLE T3,ILCPEC ;GET # CHARS PRECEDING IT FOR ARROW
ILCLP: PUSHJ P,%IBYTE ;GET CHAR FROM RECORD
PUSHJ P,PUTERC ;PUT IN BUFFER, SPACE IN ARROW LINE
SOJG T3,ILCLP ;COPY RECORD UP TO BAD CHAR
ILCPEC: PUSHJ P,%IBYTE ;GET BAD CHAR
PUSHJ P,PUTER1 ;STORE IT
MOVEI T3,BEFSIZ+AFTSIZ ;GET TOTAL ALLOWED SANDWICH
SUB T3,ERRPOS ;MINUS CHARS ALREADY OUT
ILCLP2: SKIPG IRCNT(D) ;AND CHARS IN RECORD?
JRST ILCEND ;NO
PUSHJ P,%IBYTE ;GET NEXT CHAR
PUSHJ P,PUTER1 ;STORE IT
SOJG T3,ILCLP2
ILCEND: PUSHJ P,BUFTYP ;TYPE RECORD
PJRST AROUT ;NOW OUTPUT ARROW LINE
PUTERC: CAIN T1,177 ;RUBOUT?
MOVNI T1,1 ;YES. MAKE IT -1
CAIN T1,0 ;NULL?
MOVEI T1," " ;YES. MAKE IT A SPACE
CAIGE T1," " ;OR OTHER NON-PRINTING CHAR?
JRST ERCTL ;YES. GO PRECEDE WITH "^"
IDPB T1,ER1PTR ;NO. JUST DEPOSIT IT
POPJ P,
PUTER1: CAIN T1,177 ;RUBOUT?
MOVNI T1,1 ;YES. MAKE IT -1
CAIN T1,0 ;NULL?
MOVEI T1," " ;YES. MAKE IT A SPACE
CAIGE T1," " ;OTHER NON-PRINTING CHAR?
JRST ER1CTL ;YES. PRECEDE WITH "^"
IDPB T1,ER1PTR ;NO. JUST STORE IT
POPJ P,
ERCTL: AOS ERRPOS ;INCR ARROW SPACE COUNT FOR "^"
ER1CTL: MOVEI T2,"^" ;OUTPUT UP-ARROW
IDPB T2,ER1PTR
ADDI T1,100 ;CTL CHARS TO UPPER CASE, RUBOUT TO "?"
IDPB T1,ER1PTR ;STORE IT
POPJ P,
BUFTYP: SETZ T1, ;STORE NULL AT END OF BOTH STRINGS
IDPB T1,ER1PTR
MOVE T1,[POINT 7,ER1BUF] ;ERROR BUFFER
PJRST %EOREC ;Type it and return
AROUT: MOVE T3,[POINT 7,ER1BUF] ;POINT TO ERROR BUFFER AGAIN
MOVE T2,ERRPOS ;GET SPACE COUNT
SOJLE T2,PUTARO ;NO PRECEDING SPACES, JUST OUTPUT ARROW
MOVEI T1," " ;PUT SPACES INTO BUFFER
AROLP: IDPB T1,T3
SOJG T2,AROLP
PUTARO: MOVEI T1,"^" ;PUT IN ARROW
IDPB T1,T3
SETZ T1, ;PUT IN NULL
IDPB T1,T3
MOVE T1,[POINT 7,ER1BUF] ;POINT TO IT YET AGAIN
PJRST %EOREC ;TYPE IT
;TYPE FORMAT (PRESUMABLY CONTAINING AN ERROR) AND PUT AN ARROW UNDER THE
;ERRONEOUS CHARACTER. THE ERROR POSITION IS GOTTEN FROM FMT.BP.
FMTTYP: MOVE T1,USR.SZ ;GET FORMAT SIZE
SUB T1,FMT.SZ ;GET CURRENT POSITION
MOVEI T2,(T1) ;COPY IT
CAILE T2,BEFSIZ ;TOO BIG?
MOVEI T2,BEFSIZ ;YES. TRUNCATE IT
MOVEM T2,ERRPOS ;SAVE ERROR CHAR POSITION
SUBI T1,(T2) ;GET NUMBER OF CHARS TO SKIP
MOVE T3,USR.SZ ;GET # CHARS IN FORMAT AGAIN
SUBI T3,(T1) ;GET # CHARS IN TRUNCATED FORMAT
CAILE T3,BEFSIZ+AFTSIZ ;BUT NOT MORE THAN A PROPER SANDWICH
MOVEI T3,BEFSIZ+AFTSIZ
MOVEM T3,ERRCNT ;SAVE IT
ADJBP T1,FMT.BG ;GET A POINTER TO THE FORMAT
MOVEM T1,ERRPTR ;SAVE IT
MOVE T1,[POINT 7,ER1BUF] ;POINT TO ERROR BUFFER
MOVEM T1,ER1PTR
MOVE T3,ERRPOS ;GET # CHARS PRECEDING ERROR CHAR
SOJLE T3,FMTPEC ;IF NONE, GO OUTPUT ERROR CHAR
FMTELP: ILDB T1,ERRPTR ;GET A CHAR
PUSHJ P,PUTERC ;STORE IN ERROR BUFFER, SPACE IN ARROW LINE
SOJG T3,FMTELP
FMTPEC: ILDB T1,ERRPTR ;GET ERROR CHAR
PUSHJ P,PUTER1 ;STORE IN ERROR BUFFER
MOVE T3,ERRCNT ;GET TOTAL # CHARS AGAIN
SUB T3,ERRPOS ;GET SIZE OF REST OF FORMAT
FMTEL2: ILDB T1,ERRPTR ;GET ANOTHER FORMAT CHAR
PUSHJ P,PUTER1 ;STORE IN ERROR BUFFER
SOJG T3,FMTEL2
PUSHJ P,BUFTYP ;OUTPUT FORMAT
PJRST AROUT ;OUTPUT ARROW LINE
IF10,<
;Type string with error in it, with arrow under the current char.
; %NCHRR is # of chars parsed so far (and the error position).
;%SRCBP is the CURRENT source byte ptr.
CHSTYP: HRRZ T3,%NCHRR ;Get # chars
MOVEM T3,ERRPOS ;SAVE FOR ARROW TYPOUT
MOVNI T3,(T3) ;NEGATIVE
ADJBP T3,%SRCBP ;POINT TO BEG OF STRING
MOVEM T3,ERRPTR ;SAVE IT
MOVE T1,[POINT 7,ER1BUF] ;Place to put it
MOVEM T1,ER1PTR
HRRZ T3,%NCHRR ;GET # CHARS PREVIOUS TO ERROR CHAR
SOJLE T3,CHSPEC ;IF NONE, JUST OUTPUT ERROR CHAR
CHSLP: ILDB T1,ERRPTR ;Get char
PUSHJ P,PUTERC ;STORE IN ERROR BUFFER, SPACE IN ARROW LINE
SOJG T3,CHSLP ;Loop till copied
CHSPEC: ILDB T1,ERRPTR ;GET ERROR CHAR
PUSHJ P,PUTER1 ;STORE IN ERROR BUFFER
PUSHJ P,BUFTYP ;OUTPUT STRING
PJRST AROUT ;OUTPUT ARROW LINE
>;END IF10
SEGMENT DATA
BEFSIZ==^D50 ;50 CHARS BEFORE ILCHR PRINTED
AFTSIZ==^D20 ;20 CHARS AFTER ILCHR
RERRBF==30 ;LENGTH OF RECORD AND FORMAT BUFFER
LERRBF==60 ;LENGTH OF MESSAGE BUFFER, WORDS
G.ERBF:: ;GLOBAL TAG
ERRBUF: BLOCK LERRBF ;BUFFER FOR THE ERROR MESSAGE
ERRCNT: BLOCK 1 ;COUNT OF CHARS LEFT IN IT
ERRPTR: BLOCK 1 ;POINTER TO NEXT FREE CHAR
ER1PTR: BLOCK 1 ;POINTER TO ERROR LINE BUFFER
ER1BUF: BLOCK RERRBF ;Buffer for the record
ERRPOS: BLOCK 1 ;POSITION OF ERROR CHARACTER
INICHR: BLOCK 1 ;PREFIX CHAR OF ERROR MESSAGE
ERRARG: BLOCK 1 ;ARG TO $<N>X COMMAND
COLCNT: BLOCK 1 ;COLUMN NUMBER
ARGPTR: BLOCK 1 ;POINTER TO NEXT ARG
EADDR: BLOCK 1 ;ERROR ADDRESS TEMP
SUBTTL TRACE
SEGMENT CODE
$ERR (,TR0,-1,0)
$ERR (,TR1,-1,0,<$S$7T($O)$16T$[$[---$23T$S$1O$34T($L)$48T$O$54T$A>,<RNAME,RPC,CNAME,OFFS,CPC,TRARGS,RGPTR>)
$ERR (,TRC,-1,0,<Name (Loc) $[$[--- Caller (Loc) Args Types>)
FENTRY (TRACE)
MOVEM P,%TRPDP ;USER STACK IS TRACE STACK
MOVEM P,%ERPDP ;AND ERROR STACK FOR MODCNV
PUSHJ P,SVEACS ;SAVE USER'S ACS
%TRACX: SETZM MSGPC ;NO PC ON EACH MESSAGE, PLEASE
MOVE P1,%TRPDP ;GET TRACE PDP
PUSHJ P,GETPC ;GET TOP CALL ON STACK
JUMPE P1,%POPJ ;NONE THERE, RETURN NOW
MOVEM P1,SAVPC ;SAVE DECREMENTED PC
MOVEM T1,CPC ;[3155] Save caller PC
MOVEM T2,RPC ;[3155] Save routine address
HLL T3,-1(T3) ;-COUNT,,ARGLST
MOVEM T3,TRARGS ;SAVE FOR LATER
MOVE T3,-1(T2) ;GET SIXBIT SUBROUTINE NAME
MOVEM T3,RNAME ;SAVE IT
XMOVEI T1,E.TR0+%EOFF ;OUTPUT BLANK LINE
MOVEM T1,%ERPTR
PUSHJ P,FOREC
XMOVEI T1,E.TRC+%EOFF ;OUTPUT TRACE HEADER
MOVEM T1,%ERPTR
PUSHJ P,FOREC
TRACEL: MOVE P1,SAVPC ;GET DECREMENTED PC FROM LAST CALL
PUSHJ P,GETPC ;GET NEXT PC ON STACK
MOVEM P1,SAVPC ;AND SAVE DECREMENTED ONE
PUSH P,T1 ;SAVE INFO FOR NEXT LOOP
PUSH P,T2
PUSH P,T3
MOVE T4,CPC ;GET CALLER PC
SUB T4,T2 ;[3155] Subtract start of caller's routine
MOVEM T4,OFFS
CAIN P1,0 ;MAIN PROGRAM?
SKIPA T4,[SIXBIT /MAIN./] ;YES, GET ITS NAME
MOVE T4,-1(T2) ;SUBROUTINE, GET NAME
MOVEM T4,CNAME ;SAVE AS CALLER'S NAME
SETZM STRNG ;INIT TO NULLS
MOVE T1,[STRNG,,STRNG+1] ;SETUP
BLT T1,STRNG+STRWDS-1 ;INIT STRING
MOVE T1,[POINT 7,STRNG] ;PTR TO STRING
MOVEM T1,RGPTR ;STORE FOR ERR MACRO
MOVE T3,TRARGS ;RETRIEVE [-COUNT,,ARGLST]
HLRE T4,T3 ;COUNT
MOVNM T4,TRARGS ;STORE FOR ERR MACRO
SKIPN T4,TRARGS ;ANY ARGS?
JRST TRCSHO ; NOPE, GO DISPLAY
CAIG T4,STRLEN ;TOO MANY ARGS TO DISPLAY?
JRST TRCPTR ; NOPE, GO FINISH SETTING UP
HRLI T3,-STRLEN ;SET AOBJ PTR TO MAX
MOVE T4,[ASCIZ/.../] ;UNDISPLAYED ARGS
MOVEM T4,STRNG+STRWDS ;STORE
TRCPTR: MOVE T4,[POINT 7,STRNG] ;DEST PTR
TRCRGL: LDB T1,[POINT 4,(T3),12] ;GET DATA TYPE
IDIVI T1,5 ;IN WHICH WORD IS SYMBOL?
MOVE T0,TYPCOD(T1) ;LOAD THE WORD
IMULI T2,7 ;REMAINDER TO BIT OFFSET
ROT T0,7(T2) ;RIGHT JUSTIFY DATA TYPE SYMBOL
IDPB T0,T4 ;SYMBOL TO STRNG
AOBJN T3,TRCRGL ;LOOP IF MORE ARGS
TRCSHO: XMOVEI T1,E.TR1+%EOFF ;OUTPUT A TRACE LINE
MOVEM T1,%ERPTR
PUSHJ P,FOREC
POP P,T3 ;RESTORE 'GETPC' DATA FOR LOOP
POP P,T2
POP P,T1
MOVEM T1,CPC ;[3155] Save caller PC
MOVEM T2,RPC ;[3155] Save routine address
HLL T3,-1(T3) ;-COUNT,,ARGLST
MOVEM T3,TRARGS ;SAVE FOR LATER
MOVE T3,-1(T2) ;GET SIXBIT SUBROUTINE NAME
MOVEM T3,RNAME ;SAVE IT
SKIPE SAVPC ;ANY MORE STACK TO TRACE?
JRST TRACEL ;YES. GO DO IT
XMOVEI T1,E.TR0+%EOFF ;NO. OUTPUT BLANK LINE
MOVEM T1,%ERPTR
PJRST FOREC ;AND LEAVE
STRWDS==3 ;WORDS TO ACCOMODATE ARGUMENT SYMBOL STRING
STRLEN==5*STRWDS ;5 ASCII BYTES PER WORD
; 0123456701234567
TYPCOD: ASCII /OLIUFUOSDIOGXCUH/
repeat 0,<
DATA TYPE
0 INTEGER
1 LOGICAL
2 INTEGER
3
4 REAL
5
6 OCTAL
7 STATEMENT LABEL
10 DOUBLE REAL
11 DOUBLE INTEGER
12 DOUBLE OCTAL
13 G-FLOATING
14 COMPLEX
15 CHARACTER
16
17 LITERAL STRING
>
SEGMENT DATA
STRNG: BLOCK STRWDS+1 ;SYMBOL STRING + '...'
SAVPC: BLOCK 1 ;PLACE FOR DECREMENTED PC FROM GETPC
CPC: BLOCK 1 ;CALLER PC
RPC: BLOCK 1 ;ROUTINE PC
CNAME: BLOCK 1 ;CALLER NAME
RNAME: BLOCK 1 ;ROUTINE NAME
OFFS: BLOCK 1 ;OFFSET FROM BEGINNING OF CALLER
TRARGS: BLOCK 1 ;# ARGUMENTS
RGPTR: BLOCK 1 ;STRING POINTER FOR ERROR MACRO
SEGMENT CODE
;ROUTINE TO FIND THE NEXT PC ON THE STACK
;ARG: P1 = POINTER TO STACK
;RETURN: P1 = UPDATED TO PAST RETURNED PC, 0 IF NO PC FOUND
; T1 = PC OF PUSHJ
; T2 = DEST ADDRESS OF PUSHJ
; T3 = ADDRESS OF ARG LIST
GETPC: MOVE T1,(P1) ;GET SOMETHING OFF STACK
CAMN T1,['STOP!!'] ;MAGIC END-OF-STACK CONSTANT?
JRST GETPCE ;YES, GO RETURN END-OF-STACK INDICATION
SKIPN %FSECT ;NON-ZERO SECTION?
TLZ T1,-1 ;[3151] No, discard section 0 flag bits
TLNE T1,(77B5) ;[3151] Leftmost 6 bits must be zero by now
SOJA P1,GETPC ;[3151] Nope, can't be a saved PC
PUSHJ P,ADRCHK ;CHECK THAT ADDRESS IS REASONABLE
SOJA P1,GETPC ;NOT, NOT A PC
MOVE T1,(P1) ;GET ENTIRE ADDR AGAIN
SKIPN %FSECT ;SECTION ZERO?
TLZ T1,-1 ;[3151] Yes, throw away flag bits
HLLZM T1,PCSECT ;SAVE SECTION #
SUBI T1,1 ;DECR PC
HLRZ T2,(T1) ;GET INSTRUCTION POINTED TO BY STACK
TRZ T2,37 ;TURN OFF INDIRECT AND INDEX
CAIE T2,(PUSHJ P,) ;A SUBROUTINE CALL?
SOJA P1,GETPC ;NO, NOT A PC
HLRZ T2,-1(T1) ;GET INSTRUCTION BEFORE THE PUSHJ
TRZ T2,37 ;TURN OFF INDEIRECT AND INDEX
CAIE T2,(MOVEI L,) ;CORRECT?
CAIN T2,(XMOVEI L,) ; (The other choice)
TRNA ;Yes
SOJA P1,GETPC ;NO
MOVE T3,(T1) ;GET THE PUSH INST
TLNE T3,17 ;INDEXED?
JRST UNKDST ;YES. DESTINATION UNKNOWN
HRRZ T2,(T1) ;GET THE PUSHJ INST DEST
HLL T2,PCSECT ;GET SECTION FROM CALLER ADDR
TLNE T3,(@) ;INDIRECT?
XMOVEI T2,@(T2) ;YES. GET DEST ADDR OF PUSHJ
HLRZ T3,(T2) ;GET INSTRUCTION AT THAT ADDRESS
CAIE T3,(JSP 1,) ;POSSIBLE OVRLAY CALL?
JRST GETPC1 ;NO
HRRZ T3,(T2) ;GET RH OF JSP
MOVE T4,-1(T3) ;GET WORD BEFORE JSP TARGET
CAME T4,['.OVRLA'] ;IS IT LINK'S OVERLAY ROUTINE?
JRST GETPC1 ;NO, NOT AN OVERLAY CALL
MOVE T2,(T3) ;GET THE WORD AFTER THE JSP
TLO T2,(IFIW) ;MAKE IT A LOCAL
TLZ T2,(1B1) ;[3147] Clear the undefined IFIW bit
XMOVEI T2,@T2 ;GET THE DEST ADDR OF THE OVERLAY CALL
JRST GETPC1 ;AND PROCESS IT
UNKDST: XMOVEI T2,1+[EXP <SIXBIT /UNKNWN/>,0]
GETPC1: MOVE T3,-1(T2) ;GET ROUTINE NAME
TLNN T3,770000 ;FIRST 6 BITS NON-ZERO?
JRST ZERARG ;YES. THERE IS NO ARG LIST
MOVE T4,-1(T1) ;GET XMOVEI OR MOVEI AGAIN
TLNE T4,17 ;INDEXED?
JRST ZERARG ;YES. UNKNOWN ARG LIST
HRRZ T3,-1(T1) ;GET ARG LIST ADDRESS FROM MOVEI INSTRUCTION
HLL T3,PCSECT ;ADD IN SECTION #
TLNE T4,(@) ;INDIRECT XMOVEI?
XMOVEI T3,@(T3) ;YES. RESOLVE IT
MOVS T4,-1(T3) ;GET ARG COUNT FROM -1 WORD OF LIST
CAIL T4,400000 ;MUST BE NEGATIVE
CAILE T4,777777
JUMPN T4,GETPCN ;OR ZERO
SOJA P1,%POPJ ;DONE
GETPCN: SOJA P1,GETPC ;NOT SO, NOT A POSSIBLE PC
ZERARG: XMOVEI T3,1+[EXP 0,0] ;POINT T3 AT NULL ARG LIST
SOJA P1,%POPJ ;DONE
GETPCE: SETZ P1, ;FLAG THAT PDL IS DONE
SETZ T1, ;Return a zero.
MOVE T2,%STADD ;GET START ADDRESS
MOVEI T3,1+[0] ;NO ARGS
POPJ P, ;DONE
;ROUTINE TO ADDRESS CHECK A PC
;ARG: T1 = ADDRESS
;SKIP RETURN IF ADDRESS OK, NONSKIP OTHERWISE
;ADDRESS IS OK IF IT'S IN LOW SEGMENT, HIGH SEGMENT, OR FOROTS
ADRCHK:
IF10,< ;[3151] This code doesn't work for Tops-20
CAIGE T1,140 ;BELOW LOW SEG START?
POPJ P, ;NO, BAD
CAMG T1,.JBREL ;BELOW LOW SEG END?
JRST %POPJ1 ;YES, FINE
SKIPE T2,.JBHRL ;GET HIGH SEG POINTER
CAILE T1,(T2) ;COULD ADDRESS BE IN HIGH SEG?
POPJ P, ;NO
HLRZ T3,T2 ;GET HIGH SEG LENGTH
SUBI T2,(T3) ;GET HIGH SEG ORIGIN
CAIL T1,(T2) ;IS ADDRESS IN HIGH SEG?
AOS (P) ;YES, IT'S OK
POPJ P, ;ADDRESS IS ILLEGAL
> ;[3151] End of IF10
IF20,<
FH%EPN==1B19 ;[3162] Extended page number (Release 5 symbol)
TXNE T1,777B8 ;[3155] Does the page number fit on a KL ?
POPJ P, ;[3155] No, can't be a good address
LSH T1,-^D9 ;[3151] Change to page number
HRLI T1,.FHSLF ;[3151] Inquire about our process
SKIPE %FSECT ;[3217] Running in a non-zero section ?
TXO T1,(FH%EPN) ;[3162] Yes, don't let section 0 be defaulted
RPACS% ;[3151] See what the page's attributes are
ERJMP RETURN ;[3151] Definitely not a return PC, punt
TXNE T2,PA%PEX ;[3151] Does the page exist ?
AOS (P) ;[3151] Yes, set up for skip (success return)
RETURN: POPJ P, ;[3151] Return
> ;[3151] End of IF20
;ROUTINE TO CONVERT AN ADDRESS INTO SYMBOL+OFFSET
;ARG: ORGADR = ADDRESS TO CONVERT
;RETURN: SYMNAM = RADIX50 SYMBOL NAME
; SYMVAL = VALUE OF SYMBOL
; SYMOFF = OFFSET FROM SYMBOL
; SYMMOD = RADIX50 MODULE NAME
;THIS ROUTINE FINDS THE LARGEST SYMBOL LESS THAN OR EQUAL TO THE ADDRESS.
;IT IS DESIGNED FOR CONVERTING PCS ... IT ASSUMES THAT THE USEFUL SYMBOLS
;IN ANY ROUTINE HAVE VALUES GREATER THAN THE ROUTINE START ADDRESS.
;ZERO IS RETURNED IN SYMNAM IF THERE IS NO SYMBOL TABLE OR IF THE ADDRESS
;IS NOT IN ANY MODULE (FUNCTION, SUBROUTINE, OR MAIN PROGRAM) IN THE TABLE.
;MODULE NAMES ARE USED AS LAST-DITCH CANDIDATES FOR SYMBOLS.
SYMCNV: SETZM SYMNAM ;CLEAR THE MATCHED SYMBOL & VALUE
SETZM SYMVAL
SETZM SYMMOD ;AND MODULE NAME
MOVE T2,.JBSYM ;GET LOW SYMTAB START
JUMPE T2,CNVDON ;NONE. ONLY LOOK IN THE LOWSEG FOR NOW
PUSHJ P,SYMSRH ;DO A SEARCH
JRST CNVDON ;NO VALID SYMBOLS
MOVEM T1,SYMNAM ;SAVE THE SYMBOL NAME
MOVEM T2,SYMVAL ;AND ITS VALUE
MOVEM T3,SYMMOD ;AND MODULE NAME
MOVE T1,ORGADR ;GET ORIGINAL ADDR
SUB T1,SYMVAL ;TURN INTO OFFSET FROM SYMBOL FOUND
MOVEM T1,SYMOFF ;AND SAVE IT
CNVDON: POPJ P,
SYMSRH: XMOVEI T4,(T2) ;[3155] Make into global address
MOVEM T4,SYMBEG ;[3155] Save address
HLRE T2,T2 ;GET SYMTAB LENGTH
MOVM T2,T2 ;[3166] MAKE IT POSITIVE
ADD T2,T4 ;[3166] GET SYMBOL TABLE END + 1
SETZB T4,MODEND ;CLEAR MODULE NAME AND END ADDRESS
SETZM SRHVAL ;INITIALIZE BEST-SO-FAR MODULE ADDRESS
SETZM SRHSYM ;AND SYMBOL
MODLP: MOVE T1,T2 ;POINT TO START OF MODULE
CAMG T1,SYMBEG ;STILL IN SYMBOL TABLE?
JRST MODLPE ;NO, SEARCH DONE
HLRE T2,-1(T1) ;GET -LENGTH OF MODULE SYMBOLS
SKIPGE T2 ;[3155] If positive, junk symbol table format
TRNE T2,1 ;MUST ALSO BE EVEN
POPJ P, ;[3155] Odd, go die
HRRZ T3,-1(T1) ;GET LAST WORD IN MODULE, START ADDRESS
XMOVEI T3,(T3) ;[3166] INSERT OUR SECTION NUMBER
MOVE T4,-2(T1) ;AND NEXT TO LAST, MODULE NAME
TLNE T4,740000 ;AN ACTUAL MODULE NAME?
POPJ P, ;[3155] No, invalid symbol table format
ADD T2,T1 ;POINT TO START OF MODULE SYMBOLS
CAMG T3,ORGADR ;DOES MODULE START AFTER ADDRESS TO CONVERT?
CAMGE T3,SRHVAL ;NO, IS MODULE BETTER THAN PREVIOUS BEST?
JRST MODLP ;NO, LOOP UNTIL FIND APPROPRIATE MODULE
MOVEM T1,MODEND ;SAVE END+1 ADDRESS OF MODULE SYMBOLS
MOVEM T3,SRHVAL ;SAVE MODULE ADDRESS
MOVEM T4,SRHSYM ;AND MODULE NAME AS SYMBOL NAME
MOVEM T4,SRHMOD ;ALSO SAVE MODULE NAME FOR MESSAGES
JRST MODLP ;SEARCH WHOLE SYMBOL TABLE
MODLPE: SKIPN T1,MODEND ;GET END+1 ADDRESS OF SYMBOLS
POPJ P, ;[3155] No suitable module, can't do conversion
HLRE T2,-1(T1) ;FIND START ADDRESS OF SYMBOLS
ADD T1,T2
;NOW HAVE T1 POINTING TO FIRST SYMBOL IN MODULE, AND
;MODEND = END+1 ADDRESS OF SYMBOLS IN MODULE
SYMLP: MOVE T2,1(T1) ;GET A SYMBOL VALUE
CAMG T2,ORGADR ;BELOW DESIRED ADDRESS?
CAMGE T2,SRHVAL ;YES, BETTER VALUE THAN PREVIOUS BEST?
JRST SYMLPN ;NO, FORGET IT
PUSHJ P,SUPCHK ;IS SYMBOL OF FORM <n>M?
JRST SYMLPN ;YES, FORGET IT EVER HAPPENED
DMOVE T2,(T1) ;GET SYMBOL AND VALUE
MOVEM T2,SRHSYM ;SAVE NEW SYMBOL NAME
MOVEM T3,SRHVAL ;SAVE NEW BEST VALUE
SYMLPN: ADDI T1,2 ;BUMP TO NEXT SYMBOL
CAMGE T1,MODEND ;AT END OF MODULE?
JRST SYMLP ;NO, SEARCH WHOLE THING
AOS (P) ;INCREMENT RETURN ADDRESS
MOVE T1,SRHSYM ;GET SYMBOL
TLZ T1,740000 ;CLEAR HIGH BITS OF SYMBOL
MOVE T2,SRHVAL ;GET ITS VALUE
MOVE T3,SRHMOD ;AND GET THE MODULE NAME
POPJ P,
SEGMENT DATA
PCSECT: BLOCK 1 ;SECTION # FOR GETPC IN LEFT HALF
SRHSYM: BLOCK 1 ;SYMBOL
SRHVAL: BLOCK 1 ;ITS VALUE
SRHMOD: BLOCK 1 ;RADIX50 MODULE NAME FROM SYMBOL SEARCH
ORGADR: BLOCK 1 ;ADDR WE'RE TRYING TO MATCH
SYMBEG: BLOCK 1 ;BEG OF SYMBOL TABLE
MODEND: BLOCK 1 ;MODULE END
SYMNAM: BLOCK 1 ;FINAL SYMBOL
SYMVAL: BLOCK 1 ;FINAL VALUE
SYMOFF: BLOCK 1 ;OFFSET OF ADDR FROM SYMBOL
SYMMOD: BLOCK 1 ;FINAL MODULE NAME
SEGMENT CODE
;ROUTINE TO DECIDE IF A SYMBOL SHOULD BE SUPPRESSED FROM TYPEOUT
;ARG: T1 = POINTER TO SYMBOL
;NONSKIP RETURN IF SYMBOL SHOULD BE SUPPRESSED.
;SUPPRESSED SYMBOLS ARE:
; COMPILER-GENERATED TEMP LABELS OF THE FORM <DIGITS>M
; SYMBOLS (CURRENTLY GENERATED ONLY BY MACRO) DEFINED WITH ==
;PRESERVES T1
SUPCHK: MOVE T2,(T1) ;GET RADIX50 SYMBOL NAME
JUMPL T2,%POPJ ;IF SUPPRESS BIT SET, SUPPRESS SYMBOL
TLZ T2,740000 ;CLEAR EXTRA BITS
IDIVI T2,50 ;GET LOW-ORDER CHAR IN T4
JUMPE T2,%POPJ1 ;IF SYMBOL WAS ONLY 1 CHAR, NOT AN M-SYMBOL
CAIE T3,R50(M) ;DOES SYMBOL END WITH M?
JRST %POPJ1 ;NO, NOT AN M-SYMBOL
SCHKLP: IDIVI T2,50 ;GET NEXT CHAR
CAIL T3,R50(0) ;IS IT A DIGIT?
CAILE T3,R50(9)
JRST %POPJ1 ;NONDIGIT, NOT AN M-SYMBOL
JUMPN T2,SCHKLP ;CHECK WHOLE SYMBOL FOR DIGITNESS
POPJ P, ;SYMBOL IS AN M-SYMBOL, SUPPRESS IT
PURGE $SEG$
END