Trailing-Edge
-
PDP-10 Archives
-
BB-D480C-SB_1981
-
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,6(2031)
;COPYRIGHT (C) 1981 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;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.
***** End Revision History *****
\
ENTRY FORER%,%forer,%ERARG
ENTRY %ERRST,%EMSGT,%FOREC,%ERSVV,%ERRRS
ENTRY TRACE%,%TRACE
IFN FTSHR,<
EXTERN F.CODE,Z.ERR,F.HSM >
EXTERN %SAVE,%SAVE1,%SAVE2,%SAVE3
EXTERN %APRCT,%APRLM,%APRSB
EXTERN %POPJ,%POPJ1,%ABORT,%CRLF
IF10,< EXTERN I.MSG,G.IS,%TIOS,%RESP >
IF20,< EXTERN G.LJE >
EXTERN I.SA,G.FERR,I.FLAG
EXTERN %RPOS,%SPOS,%IBYTE,%OBYTE
EXTERN %OPNK1,%OPNV1,%OPNK2,%OPNV2
EXTERN FMT.BP,FMT.BG,FMT.SZ
EXTERN %IONAM
IF10,< EXTERN %ARGNM ;Name of argument where error occured.
EXTERN %NCHRR ;# chars parsed in string
EXTERN %SRCBP ;Current BP to source string containing error.
>;END IF10
EXTERN I.RUNTM
EXTERN U.ERR ;If errors are diverted, this is non-zero.
EXTERN D.TTY ;DDB address of TTY: (if OPEN)
EXTERN %CALU ;Routine to call a user error handling routine.
SEGMENT ERR
; *** LIST OF FOROTS ERRORS ***
RADIX 10
; *** The following errors do NOT type a filename ***
ERR (SNH,?,Internal FOROTS error at $P)
ERR (EDE,$,$A error at $1L,<T1,%IONAM,T3>)
ERR (INI,?,INQUIRE not implemented)
ERR (IEM,?,FOROTS internal error in memory management)
ERR (MFU,?,Memory full)
ERR (APR,%,$A at $1L,<T3,T2>)
ERR (FFX,?,FOROP function code exceeds range)
ERR (TIM,,CPU time $Y Elapsed time $Y,<I.RUNTM,T1>)
ERR (SM1,,$D$3T$A$A,<T2,T4,T3>)
ERR (CLA,%,CLOSE unit $D: arguments ignored because unit is not open,<T2>)
ERR (RFN,[,Attempted RENAME to $F)
ERR (NAM,$,$A unit $D $F at $1L,<T2,%IONAM,T1,T3>)
IF20,<
ERR (IJE,?,"Impossible" JSYS error at $P - $J)
ERR (IGN,?,Illegal generation number $A,<0(L)>)
>;END IF20
IF10,<
ERR (DST,$,Error in dialog string,<T2>)
ERR (CCP,?,Can't create page $O (PAGE. error $O),<T1,P4>)
ERR (CDP,?,Can't destroy page $O (PAGE. error $O),<T2,T1>)
>;END IF10
; *** IO ERRORS **
;These type out the filename first, set ERSNS numbers,
; take ERR= branch if specified.
;0 -- No error detected
IOERR (EFS,0,0,[,Enter correct file specs)
IF10, IOERR (QUE,0,0,[,$A,<[%RESP]>)
;23 -- Error in magtape operations
IF20, IOERR (ILM,23,0,?,Unexpected MTOPR% error: $J)
IF10,<
IOERR (UTE,23,530,?,Unexpected TAPOP error $O,<T1>)
IOERR (UME,23,531,?,Unexpected MTCHR error $O,<T1>)
IOERR (UTO,23,537,?,Unexpected TAPOP. error $O trying to set $A,<T3,P1>)
>
;24 -- End of file
IOERR (EOF,24,-1,?,End of file)
;25 -- Record or record number error
IOERR (BBF,25,302,?,Bad format binary file)
IOERR (RNR,25,510,?,Record $D has not been written,<T1>)
IOERR (IRN,25,512,?,Illegal record number $D,<T3>)
IF20, IOERR (CBI,25,536,?,Can't backspace image file with no RECORDSIZE)
;28 -- CLOSE error
IF20, IOERR (CLF,28,0,?,Can't CLOSE file: $J)
IF20, IOERR (RNM,28,0,?,Can't rename file: $J)
IF10, IOERR (CLS,28,250,?,CLOSE failed, $I,<T1>) ;Type IO error bits
IF10, IOERR (DEL,28,250,?,Can't delete file: $E,<T1>)
IF10, IOERR (RNM,28,250,?,Can't rename file: $E,<T1>)
IF20, IOERR (FD1,28,527,?,File to RENAME is not on DISK)
IF10, IOERR (FD1,28,527,?,File to RENAME is not on DISK or DECTAPE)
IF20, IOERR (FD2,28,528,?,File to RENAME to is not on DISK)
IF10, IOERR (FD2,28,528,?,File to RENAME to is not on DISK or DECTAPE)
IOERR (DSS,28,549,%,DISPOSE='SAVE' assumed - device is not disk)
IF10, IOERR (CQF,28,550,%,<Can't queue file, QUEUE. error $O>,<T1>)
;30 -- OPEN error
IF20, IOERR (OPE,30,0,?,Can't OPEN file: $J)
IF20, IOERR (UFS,30,0,?,Can't switch file to UNFORMATTED: $J)
IF20, IOERR (UMO,30,0,%,$J trying to set tape $A,<P1>)
IF20, IOERR (APP,30,0,?,Can't setup to append to magtape file: $J)
IOERR (RRR,30,240,?,Random IO requires /RECORDSIZE)
IOERR (RR1,30,240,?,Random IO requires RECORDSIZE specifier in OPEN statement,,I%UNI)
IF10, IOERR (NFC,30,242,?,Too many open units)
IF20, IOERR (NSD,30,245,?,No such device $A,<T1>)
IF10, IOERR (NSD,30,245,?,No such device $S,<DEV(D)>)
IOERR (IAC,30,248,?,/ACCESS:$Z illegal for this device,<T1>)
IOERR (IDM,30,249,?,/MODE:$Z illegal for this device,<T1>)
IF10, IOERR (OPN,30,250,?,Can't OPEN file: $E,<T1>)
IF20, IOERR (PPN,30,405,?,Error translating PPN to DIRECTORY: $J)
IOERR (ISW,30,506,?,Incompatible attributes /$Z$Z /$Z$Z,<%OPNK1,%OPNV1,%OPNK2,%OPNV2>)
IOERR (SNM,30,523,?,No filespec information allowed for SCRATCH files)
IOERR (BSI,30,535,%,BLOCKSIZE ignored: device is not a magnetic tape)
IOERR (SDO,30,540,?,Same device open on unit $D with conflicting specifiers,<T2>)
;31 -- Mixed ACCESS modes
IOERR (CDI,31,315,?,Can't do $A I/O to $A file,<T2,T3>)
;32 -- Illegal logical unit number
IOERR (IUN,32,239,?,Illegal unit number $D,<T2>,I%UNI)
;39 -- REREAD error
IOERR (RBR,39,310,?,REREAD not proceeded by READ,,I%UNI)
;45 -- OPEN/CLOSE statement syntax error
IF20, IOERR (JSE,45,0,?,$J)
IF20, IOERR (JSA,45,0,?,$J - $Z,<T1>) ;For COMND errors
IOERR (ESV,45,241,?,$A keyword value /$Z$Z,<P2,T1,T5>)
IF10, IOERR (USW,45,241,?,Unknown switch /$S,<T5>)
IF10, IOERR (ASW,45,241,?,Ambiguous switch /$S,<T5>)
IOERR (DTL,45,533,?,Dialog string too long)
IF20, IOERR (EDS,45,539,?,Error in dialog string - $J)
IF20, IOERR (EDA,45,539,?,Error in dialog string - $J - $Z,<T1>) ;For COMND errors
IOERR (UOA,45,541,%,<Unknown OPEN keyword $D, ignored>,<P1>)
IOERR (NCK,45,542,%,$Z in CLOSE is meaningless - ignored,<T1>)
IOERR (RND,45,543,%,No filename specified-- DISPOSE='RENAME' ignored)
IF10, IOERR (NDI,45,544,?,No device specified with ":")
IF10, IOERR (IPP,45,545,?,Illegal PPN)
IF10, IOERR (TMF,45,546,?,Too many SFDs)
IF10, IOERR (NSI,45,547,?,Null SFD)
IF10, IOERR (IDD,45,548,?,Illegal character $C in $A argument,<T1,%ARGNM>,I%TCH)
IOERR (NQS,45,551,?,PADCHAR must be single char in double quotes)
;47 -- WRITE on READ-only file
IOERR (CDT,47,263,?,Can't $A an $A-only file,<T1,T2>)
IOERR (CWL,47,554,?,Can't write a file with MODE='LINED')
;59 -- List-directed input data error
IOERR (IDL,59,313,?,Illegal delimiter in list-directed input,,I%REC)
;62 -- Syntax error in FORMAT
IOERR (ILF,62,301,?,Illegal character in format,,I%FMT)
IOERR (DLF,62,306,?,Data in IO list but not in format,,I%FMT)
IOERR (ARC,62,532,?,Ambiguous repeat count,,I%FMT)
IOERR (IRC,62,538,?,Illegal repeat count,,I%FMT)
IOERR (IHC,62,552,?,Illegal Hollerith constant,,I%FMT)
IOERR (IFW,62,553,?,Illegal field width,,I%FMT)
;63 -- Output conversion error
IOERR (ETL,63,509,%,Record length exceeds string length) ;ENCODE
IOERR (FTS,63,534,%,Output field width too small)
;64 -- Input conversion error
IOERR (ILC,64,307,?,Illegal character in data,,I%REC)
IOERR (IL1,64,307,?,Illegal character in data,,I%REC1)
IOERR (IOV,64,571,%,Integer overflow,,I%REC)
;81 -- FOROTS calling error
IOERR (UNS,81,501,?,Unit not specified,,I%UNI)
IOERR (WNA,81,504,?,<Wrong number of arguments>)
IOERR (IOL,81,508,?,Bad IO list)
;799 -- Unclassifiable data error
IOERR (VNN,799,309,?,Variable $S not in namelist,<T1>,I%REC)
IOERR (NEQ,799,513,?,Found "$C" when expecting "=",<T1>,I%REC)
IOERR (NRP,799,514,?,Missing right paren,,I%REC)
IOERR (ILN,799,515,?,Variable or namelist does not start with letter,,I%REC)
IOERR (ILS,799,516,?,Illegal Subscript,,I%REC)
IOERR (CCC,799,519,?,Can't convert constant to correct type,,I%REC)
IOERR (STL,799,520,?,Alpha string too long,,I%REC)
IOERR (RPE,799,521,?,Illegal repeat count,,I%REC) ;In NAMELIST
IOERR (SNV,799,522,?,Sign with null value,,I%REC)
;899 -- Unclassifiable device errors
IF20, IOERR (OSW,899,0,?,Can't switch to output: $J)
IF10, IOERR (OSW,899,250,?,Can't switch to output: $E,<T1>)
IF20, IOERR (INP,899,401,%,$J) ;Input error bits - warn user
IF20, IOERR (INX,899,401,?,$J) ;Too many "INP" errors happened
IF20, IOERR (OUT,899,401,%,$J) ;Output error bit - warning
IF20, IOERR (OUX,899,401,?,$J) ;Too many "OUT" errors happened
IF20, IOERR (INY,899,401,?,$J) ;Input error bits (DISK) fatal.
IF20, IOERR (OUY,899,401,?,$J) ;Output error bits (DISK) fatal.
IF10, IOERR (IOE,899,400,?,$I,<T1>) ;General-purpose I/O error
RADIX 8
;HERE FROM ERROR MACROS
;
;CALLS:
;
; ERR (COD,CHR,MSG,ARGS)
; LERR (COD,CHR,MSG,ARGS)
;
;COD 3-CHARACTER PREFIX
;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
;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
;
;THE ERR AND LERR MACROS GENERATE 1 WORD IN LINE, SO CAN BE SKIPPED OVER.
;LERR DOES NOT ALTER ANY ACS, AND ERR DOES NOT ALTER ANY EXCEPT T0.
'FORER.' ;LERR ENTRY, FOR FORLIB USE
FORER%: POP P,T1 ;RESTORE T1, SAVED BY ENTRY CODE
PUSHJ P,SVEACS ;Save acs in ERRACS
POP P,P1 ;GET POINTER TO ERROR ARG BLOCK
POP P,T1 ;GET ARG COUNT
JUMPE T1,LIMCHK ;IF NONE, SKIP ARG TRANSFER
MOVEI T2,%ERARG-1(T1) ;SET DESTINATION ADDRESS FOR TRANSFER
ARGXFR: POP P,(T2) ;MOVE AN ARG FROM STACK TO %ERARG LIST
SUBI T2,1 ;INCREMENT DEST ADDRESS
SOJG T1,ARGXFR ;MOVE ALL ARGS
LIMCHK: PUSHJ P,GTCONT ;Get continue address
SETOM LIBFLG ;FLAG ERROR IS FROM LIBRARY
MOVE F,I.FLAG ;CLEAR FLAGS
AOS T1,%APRCT+.ETLRE ;INCREMENT LIBRARY ERROR COUNT
CAMLE T1,%APRLM+.ETLRE ;PAST LIMIT?
JRST ERET ;YES, RETURN WITHOUT TYPING MESSAGE
MOVE P2,P1 ;Save P1 (GETPC uses it)
XMOVEI P1,(P) ;Point to current stack position
PUSHJ P,GETPC
MOVEM T1,LERRPC ;Store PC for the LERR message
MOVE P1,P2 ;Restore ptr to error block
JRST %FOREC ;Continue below
;ERR ENTRY, FOR INTERNAL FOROTS USE
%FORER: PUSHJ P,%ERRST ;Get set to start error message
;Enter here from %IOERR or LERR to get message text and
; type out the error, then continue at the appropriate address.
%FOREC: PUSHJ P,EMSGT0 ;Get error message text
SKIPN LIBFLG ;LERR?
JRST FOREC1 ;No
PUSHJ P,ADDPCM ;Add PC to message text.
FOREC1: PUSHJ P,EMSGT1 ;Append null to string so can output msg.
MOVE T1,INICHR ;Get initial char
PUSHJ P,POSEFL ;if ?, do a CLRBFI; position to column 1
MOVEI T1,ERRBUF ;POINT TO MESSAGE
PUSHJ P,%EOREC## ;TYPE MESSAGE
MOVE T1,0(P1) ;GET FLAGS
TRNE T1,I%REC ;TYPE RECORD WITH ARROW UNDER IT IF REQUESTED
JRST RECT0
TRNE T1,I%REC1 ;TYPE RECORD WITH ARROW MOVED OVER 1
JRST RECT1
TRNE T1,I%FMT ;TYPE FORMAT WITH ARROW UNDER IT
JRST [PUSHJ P,FMTTYP
JRST ERET]
IF10,<
TRNE T1,I%TCH ;Type character string in error?
PUSHJ P,CHSTYP
>;END IF10
JRST ERET ;Done
;Type REC with arrow under it
RECT0: PUSHJ P,RECTYP
JRST RECT2 ;Go see if also type FORMAT
;Type REC with arrow under .-1
RECT1: PUSHJ P,RECTY1
RECT2:
; JRST ERET
;Call user routine (if specified)
ERET: SKIPE LIBFLG ;ERROR FROM LIBRARY ROUTINE?
SKIPN T1,%APRSB+.ETLRE ;YES, ANY USER TRAP ROUTINE SPECIFIED?
JRST ERET1 ;NO, GO RETURN
MOVEI T2,1(P) ;PUSH ERRACS SO USER ROUTINE CAN CALL FORERR
HRLI T2,ERRACS
ADJSP P,17
BLT T2,(P)
PUSH P,CONT ;And continue address
MOVEI T2,.ETLRE ;T2= error number
MOVE T3,ERRPC ;T3= PC
PUSHJ P,%CALU ;** Call user routine **
POP P,CONT ;Restore our continue address
ADJSP P,-17 ;POP ERRACS
MOVSI T1,1(P)
HRRI T1,ERRACS
BLT T1,ERRACS+16
ERET1: MOVE T1,CONT ;Continue from error
XMOVEI T1,(T1)
MOVEM T1,CONT ;Get address we can JRST @
MOVSI 16,ERRACS ;RESTORE 0-16
BLT 16,16
JRST @CONT ;Continue from error
SEGMENT DATA
CONT: BLOCK 1 ;Continue address from errors
RTADRE: BLOCK 1 ;Return address from various routines
; (Useful if the routine has to mess
; with the stack).
ERRSRA: BLOCK 1 ;Return address from %ERRST
LERRPC: BLOCK 1 ;Pc to type out in LERR.
SEGMENT ERR
;%ERRST - Routine to setup for ERR or IOERR
;Call: PUSHJ P,%ERRST ;at the start
; <return here>
;Saves the acs in ERRACS, clears LIBFLG, gets return address
%ERRST: POP P,ERRSRA ;Get return address of this routine
PUSHJ P,SVEACS ;Save the acs
POP P,P1 ;Get ptr to arg address
PUSHJ P,GTCONT ;Get continue address
SETZM LIBFLG ;Note error is from inside FOROTS
JRST @ERRSRA ;Return
;Routine to save the acs in ERRACS
;Call: PUSHJ P,SVEACS
; <return here>
SVEACS: POP P,RTADRE ;Get return address from this routine
MOVEM 17,ERRACS+17 ;SAVE ALL ACS
MOVEI 17,ERRACS
BLT 17,ERRACS+16
MOVE 17,ERRACS+17
JRST @RTADRE ;Return from SVEACS
;Routine to get continue address
;Call:
; PUSHJ P,GTCONT
; <return here>
; This routine sets CONT to continue address (or 0 if none supplied),
; and finds ERRPC = PC of the error PUSHJ.
GTCONT: POP P,RTADRE ;Get return address from routine
SETZM CONT ;Assume no continue address
MOVE T1,0(P) ;See if top of stack is continue address
TLC T1,-1
TLCN T1,-1 ;Skip if it's not
POP P,CONT ;It is, get it
POP P,T1 ;Get return PC of error call
SKIPN CONT ;Did we get a continue address?
MOVEM T1,CONT ;No, store it
SOJ T1, ;Decrement to get PC of the PUSHJ
MOVEM T1,ERRPC
JRST @RTADRE ;Return from GTCONT
;%ERSVV - Save error parameters on stack so we can call ERR again
;Called from %IOERR routine.
%ERSVV: POP P,RTADRE ;Get return address
MOVEI T1,1(P) ;Push ERRACS
HRLI T1,ERRACS
ADJSP P,17
BLT T1,(P)
PUSH P,CONT ;Push continue address
MOVEI T2,^D6 ;Push err macro's args
PUSH P,%ERARG(T2)
SOJGE T2,.-1
JRST @RTADRE ;Return from %ERSVV
;%ERRRS - Restore error parameters
;Called from %IOERR routine as compliment to %ERRSV
%ERRRS: POP P,RTADRE ;Get return address
MOVSI T2,-<^D6+1> ;Pop err macro's args
POP P,%ERARG(T2)
AOBJN T2,.-1
POP P,CONT ;POP continue address
ADJSP P,-17 ;POP ERRACS
MOVSI T1,1(P)
HRRI T1,ERRACS
BLT T1,ERRACS+16
ANDX F,F%NION ;Remember flags possibly set
IORM F,ERRACS+F ; in %IOERR
JRST @RTADRE ;Return from %ERRRS
;%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:
;P1 points to error arg block.
%EMSGT: PUSHJ P,EMSGT0 ;Get message text with no null
;Enter here to append null to error string
EMSGT1: SETZ T1, ;And store a null
IDPB T1,ERRPTR
POPJ P, ;Return
EMSGT0: MOVEI P2,2(P1) ;MAKE POINTER TO INPUT ERROR STRING
HRLI P2,(POINT 7,)
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
MOVEI T1,%ERARG-1 ;SET POINTER TO START OF ARGS
MOVEM T1,ARGPTR
LDB T1,[POINT 7,0(P1),6] ;GET INITIAL PREFIX CHAR
CAIN T1,"$" ;INDIRECT CHAR?
PUSHJ P,GETARG ;YES, GET PREFIX CHAR
MOVEM T1,INICHR ;SAVE IT
PUSHJ P,TYPEQM ;Type it.
ENXTCH: ILDB T1,P2 ;GET NEXT CHAR FROM MSG
JUMPE T1,ETYPIT ;END, GO TYPE IT
CAIE T1,"$" ;SPECIAL CHAR?
JRST ECHR ;NO, JUST NORMAL TEXT CHAR
SETZ T2, ;CLEAR ARG
ERARGL: ILDB T1,P2 ;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
ETYPIT: MOVE T1,INICHR ;GET INITIAL CHAR AGAIN
CAIE T1,"[" ;OPEN BRACKET?
POPJ P, ;No, return now
MOVEI T1,"]" ;YES, TYPE CLOSING BRACKET
PJRST EPUTCH ; and return
;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 "X",$X ;XWD FORMAT, OCTAL
XWD "5",$5 ;RADIX50 WORD
XWD "L",$L ;ADDRESS AS LABEL+OFFSET
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.S
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
LERRTB==.-ERRTAB
$LAB: SKIPA T1,["<"] ;TYPE LEFT ANGLE BRACKET [BALANCING >]
$$: MOVEI T1,"$" ;TYPE $
PJRST EPUTCH
$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
$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: HRRZ T1,ERRPC ;GET PC OF ERROR
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
;Routine called by LERR's to append the PC to the error string.
ADDPCM: MOVEI T1,[ASCIZ/ at /]
PUSHJ P,ASCTYP
MOVE T1,LERRPC ;Get PC
SETOM ERRARG ;Set ERRARG non-zero so it types
; "in <module name>" if it can.
PJRST LERR$L ;Append the string and return
$L: PUSHJ P,%SAVE2##
PUSHJ P,GETARG
;Enter here if you have T1= PC.
;Set ERRARG= 1 to type "in Module name", 0 if you don't want that.
LERR$L: XMOVEI T1,(T1) ;Just get the PC
PUSH P,T1 ;To type out
HRRZ T1,T1 ;Just get RH to search local section sym tab.
PUSHJ P,SYMCNV ;CONVERT TO LABEL+OFFSET
PJRST NOSYM
PUSH P,T2 ;STORE OFFSET ON STACK
PUSHJ P,R50TYP ;TYPE RADIX50 SYMBOL
POP P,T1 ;GET OFFSET BACK
PUSHJ P,OFFTYP ;TYPE IT AS SIGNED OCTAL
SKIPN ERRARG ;IS THAT ALL WE WANT?
JRST [ADJSP P,-1 ;YES, RETURN
POPJ P,]
MOVEI T1,[ASCIZ / in /] ;TYPE NOISE WORD FOR MODULE NAME
PUSHJ P,ASCTYP
MOVE T1,MODNAM ;GET MODULE
PUSHJ P,R50TYP ;TYPE IT TOO
PCTYP: MOVEI T1,[ASCIZ / (PC /] ;FINISH UP WITH THE OCTAL ADDRESS
PUSHJ P,ASCTYP ; FOR LUCK
POP P,T1
TLNE T1,-1 ;Extended section?
JRST PCTYP1 ;Yes, type N,,M
PCTYP0: PUSHJ P,OCTTYP
MOVEI T1,")"
PJRST EPUTCH
PCTYP1: PUSH P,T1
HLRZ T1,T1
PUSHJ P,OCTTYP ;Type section #
MOVEI T1,","
PUSHJ P,EPUTCH
PUSHJ P,EPUTCH ;",,"
POP P,T1
HRRZ T1,T1 ;RH of PC
JRST PCTYP0
NOSYM: DMOVEM P1,SVP12 ;Save P1 and P2
MOVE P2,(P) ;Get address we're searching for
MOVE P1,P ;Copy stack ptr.
STKVAR <ADDR> ;ALLOCATE LOCAL VARIABLES
SETZM ADDR
NSYM0: PUSHJ P,GETPC ;GET A PC FROM STACK
JUMPE P1,NSYM1 ;NONE LEFT, DONE
CAML T2,ADDR ;BETTER THAN PREVIOUS BEST APPROXIMATION?
CAMLE T2,P2 ;YES, BUT NOT PAST ARG PC?
JRST NSYM0 ;NO, SKIP IT
MOVEM T2,ADDR ;SAVE ROUTINE ADDRESS
JRST NSYM0 ;LOOK THROUGH WHOLE STACK
NSYM1: SKIPN P1,ADDR ;GET ROUTINE ADDRESS
SKIPA P1,I.SA ;NONE FOUND, USE MAIN START ADDRESS
SKIPA T1,-1(P1) ;GET ROUTINE NAME
MOVE T1,['MAIN. '] ;OR MAIN PROGRAM NAME
UNSTK ;DISCARD STACK VARS
;PC still on top of stack
PUSHJ P,SIXTYP ;TYPE IT
MOVE T1,P2 ;GET ARG PC
SUB T1,P1 ;SUBTRACT ROUTINE ADDRESS
PUSHJ P,OFFTYP ;TYPE OFFSET
DMOVE P1,SVP12 ;Restore P1 and P2..
SKIPE ERRARG ;IS THAT ALL?
PJRST PCTYP ;NO, ADD PC IN OCTAL
ADJSP P,-1 ;DISCARD PC
POPJ P, ;RETURN
SEGMENT DATA
SVP12: BLOCK 2 ;Saved P1, P2 for duration of NOSYM
SEGMENT ERR
$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: AOS T1,ARGPTR ;BUMP TO NEXT ARG IN LIST
MOVE T1,(T1) ;GET 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,G.IS ;Fix error number
SKIPE T2,%TIOS ;Any IOSTAT= variable?
ADDM T1,(T2) ;Yes, fix that number, too.
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
PUSHJ P,OCTTYP ;TYPE THEM IN OCTAL
MOVE D,ERRACS+D ;GET DDB POINTER
HRLZ P1,@ARGPTR ;GET BITS BACK, IN LH
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
TLNE T2,(1B10) ;FATAL?
JRST [XMOVEI T1,%ABORT ;Yes, change continue address
MOVEM T1,CONT ;So job will be aborted.
JRST .+1]
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 ERR
;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: MOVE D,ERRACS+D ;RESTORE D
SKIPN T1,DEV(D) ;DEVICE
POPJ P, ;NO DEVICE, NO INFO AT ALL
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: HRRZ T2,G.LJE ;Get last 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
JRST ERERR ;;; STRING TOO SHORT, MSG TRUNCATED
MOVEM T1,ERRPTR ;STORE NEW STRING POINTER
;;;DO SOMETHING ABOUT ERRCNT
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
; (uses no args except "D")
$F: MOVE D,ERRACS+D ;Restore D
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: 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: 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 ERR
>;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,I.MSG ;Get message level
TXNN T1,JW.WPR ;Does user want prefix?
JRST NPR ;No, skip it
HLRZ T1,1(P1) ;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
;Routine to position terminal to column 1, and clear user's
; input buffer if error starts with "?".
;Call:
; t1/ initial character
POSEFL: JUMPE T1,%POPJ ;IF NO SPECIAL FIRST CHAR, NO SPECIAL ACTION
SKIPE U.ERR ;Don't screw around with TTY if diverting errors
POPJ P,
PUSHJ P,CLRCTO ;Clear Control-O
SKIPE D.TTY ;Any TTY DDB?
POPJ P, ;Yes, let EOREC worry about positioning
;Make sure TTY is at column 1 before typing the error
IF20,<
PUSH P,T1 ;Save 1st char
MOVEI T1,.PRIOU ;READ COL TERMINAL IS AT
RFPOS%
HRROI T1,%CRLF ;GET SET TO TYPE CRLF
TRNE T2,-1 ;IS TERMINAL AT COL 1?
PSOUT% ;NO, GET IT THERE
POP P,T1 ;Restore 1st char
POPJ P, ;Return
>;END IF20
IF10,<
PUSH P,T1 ;Save char
MOVNI T1,1 ;Get the controlling TTY's UDX.
TRMNO. T1,
JRST ATCL1 ;?Can't, assume at column 1
MOVEM T1,TRMPAL+1 ;Save UDX in arg list
;Wait for any terminal output in progress to finish
MOVEI T1,.TOOIP ;Return "output-in-progress" bit setting
MOVEM T1,TRMPAL
WAITOU: MOVE T1,[XWD 2,TRMPAL] ;Ready for TRMOP.
TRMOP. T1, ;Get output-in-progress bit
JRST ATCL1 ;?can't, assume at column 1
JUMPE T1,GTHPOS ;Jump if all output done
MOVEI T1,^D250 ;Wait a little while (1/4 sec.)
HIBER T1,
$SNH ;?Shouldn't ever fail
JRST WAITOU
;Read TTY's horizonal position
GTHPOS: MOVEI T1,.TOHPS ;Return horizontal position of TTY
MOVEM T1,TRMPAL
MOVE T1,[XWD 2,TRMPAL] ;Length,,arglist address
TRMOP. T1, ;Do the TRMOP.
JRST ATCL1 ;?Can't, assume at column 1
JUMPE T1,ATCL1 ;0 means at column 1 now
OUTSTR %CRLF ;Else type a CRLF
ATCL1: POP P,T1 ;Restore ac
CAIE T1,"?" ;SERIOUS ERROR?
POPJ P, ;No, done
CLRBFI ;CLEAR TYPEAHEAD
POPJ P, ;Return
SEGMENT DATA
TRMPAL: BLOCK 2 ;TRMOP. arg block
SEGMENT CODE
> ;IF10
;Routine to clear terminal's CTRL/O.
;Preserves T1
CLRCTO:
IF20,<
PUSH P,T1 ;SAVE CHAR
MOVEI T1,.PRIOU ;CLEAR ^O
RFMOD%
TXZE T2,TT%OSP
SFMOD%
POP P,T1
POPJ P, ;Return
>
IF10,<
SKPINL ;Clear ^O
JFCL
POPJ P,
>
;TYPE INPUT RECORD (PRESUMABLY CONTAINING AN ERROR) AND PUT AN ARROW
;UNDER THE ERRONEOUS CHARACTER. THE ERROR POSITION IS GOTTEN FROM RPOS.
RECTYP: TDZA T1,T1 ;CLEAR OFFSET
RECTY1: MOVEI T1,1 ;SET OFFSET (NECESSARY BECAUSE NAMELIST
; HAS BACKSPACED THE RECORD POINTER)
STKVAR <ERRPOS,ERROFS> ;ALLOCATE SPACE ON STACK
MOVEM T1,ERRPOS ;STORE OFFSET
PUSHJ P,%RPOS ;READ RECORD POINTER
SUBI T1,1
ADDM T1,ERRPOS ;SAVE FOR PRINTING THE ARROW
MOVEI T1,1 ;Reset to start of record
PUSHJ P,%SPOS
SETZM ERROFS ;CLEAR ARROW OFFSET CAUSED BY CONTROL CHARS
MOVE T2,[POINT 7,ER1BUF] ;PREPARE TO COPY RECORD TO ERROR BUFFER
MOVX T1,D%EOR ;Clear "END OF RECORD" bit
ANDCAM T1,FLAGS(D)
ILCLP: PUSHJ P,%IBYTE ;GET CHAR FROM RECORD
MOVE T0,FLAGS(D)
TXNE T0,D%EOR ;End of record?
JRST ILCEND ;YES, FINE
CAIL T1," " ;CONTROL CHAR?
CAIL T1,177 ;OR RUBOUT?
JRST ILCCTL ;YES, HANDLE PROPERLY
IDPB T1,T2 ;STORE CHAR IN ERROR BUFFER
JRST ILCLP ;COPY WHOLE RECORD
ILCCTL: CAIN T1,177 ;RUBOUT?
SETO T1, ;YES, TURN INTO CONTROL-?
MOVEI T3,"^" ;GET CONTROL CHAR PREFIX
IDPB T3,T2 ;STORE IN BUFFER
ADDI T1,100 ;CONVERT CONTROL CHAR TO UPPER CASE
IDPB T1,T2 ;STORE IT
PUSHJ P,%RPOS ;GET CURRENT POS
SUBI T1,1
CAMGE T1,ERRPOS ;ARE WE AFTER ERROR CHAR?
AOS ERROFS ;NO, THE ARROW WILL MOVE THE ERROR CHAR OVER ONE
JRST ILCLP ;CONTINUE
ILCEND: PUSHJ P,BUFTYP ;TYPE ERROR RECORD
MOVE T2,[POINT 7,ER1BUF] ;START AT BEGINNING OF BUFFER AGAIN
MOVE T3,ERRPOS ;GET COL TO PUT ARROW IN
ADD T3,ERROFS ;MOVED OVER ONE FOR EACH CONTROL CHAR
MOVEI T1," " ;GET MOVING-OVER CHAR
SOJLE T3,ARROW ;IF COL 1, GO TYPE ARROW
IDPB T1,T2 ;STORE SPACE IN BUFFER
SOJG T3,.-1 ;STORE A BUNCH OF THEM
ARROW: MOVEI T1,"^" ;GET POINTER
IDPB T1,T2 ;STORE IT TOO
PUSHJ P,BUFTYP ;TYPE THE ARROW
UNSTK ;REMOVE STACK VARIABLES
POPJ P, ;return
BUFTYP: MOVEI T1,0 ;End with <NUL>
IDPB T1,T2
MOVEI T1,ER1BUF ;Point to buffer
PJRST %EOREC## ;Type it and return
;TYPE FORMAT (PRESUMABLY CONTAINING AN ERROR) AND PUT AN ARROW UNDER THE
;ERRONEOUS CHARACTER. THE ERROR POSITION IS GOTTEN FROM FMT.BP.
FMTTYP: STKVAR <INCR,ARRW> ;ALLOCATE TEMPS
SETZM INCR ;FORMAT LENGTH IS FMT.SZ CHARS COUNTING FROM
;FMT.BP, FORMAT STARTS AT FMT.BG. INCR IS 0
;BETWEEN FMT.BG AND FMT.BP, 1 AFTERWARD
MOVE T1,FMT.BG ;POINT TO BEGINNING OF FORMAT
MOVE T2,[POINT 7,ER1BUF] ;POINT TO PLACE TO COPY IT TO
MOVE T3,FMT.SZ ;GET COUNT OF CHARS AFTER ARROW
SETOM ARRW ;INIT ARROW POSITION
FMTTLP: CAME T1,FMT.BP ;POINTING TO CURRENT FORMAT POSITION?
JRST FMTT1 ;NO
MOVEI T0,1 ;YES, SET INCR TO 1
MOVEM T0,INCR
JRST FMTT2
FMTT1: SKIPN INCR ;INCREMENT ARROW POSITION
AOS ARRW
FMTT2: SUB T3,INCR ;CHECK COUNT
JUMPL T3,FMTTE ;FORMAT IS COPIED
ILDB T0,T1 ;GET CHAR FROM FORMAT
IDPB T0,T2 ;COPY INTO OUR BUFFER
JRST FMTTLP ;COPY WHOLE FORMAT
FMTTE: PUSHJ P,BUFTYP ;TYPE ERRONEOUS FORMAT
MOVE T1,ARRW ;GET COUNT OF SPACES BEFORE ARROW
MOVE T2,[POINT 7,ER1BUF] ;POINT TO BUFFER
JUMPLE T1,FMTA1 ;NO SPACES, SKIP
MOVEI T3," " ;GET A SPACE
IDPB T3,T2 ;STORE A SPACE
SOJG T1,.-1 ;STORE BUNCHES OF SPACES
FMTA1: MOVEI T3,"^" ;GET THE ARROW
IDPB T3,T2 ;STORE IT
PUSHJ P,BUFTYP ;TYPE THE ARROW
UNSTK ;DISCARD LOCALS
POPJ P, ;Return
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 T1,%NCHRR ;Get # chars
IDIVI T1,5 ;This gets us to old B.P.
MOVE T3,%SRCBP ;Get source byte ptr
SUBI T3,1(T1) ;Backup # words + 1
MOVEI T1,5 ;# chars in full word
SUB T1,T2 ;Get # byte to go forward now
IBP T3 ;(At least 1)
SOJG T1,.-1 ;Get correct BP.
MOVE T2,[POINT 7,ER1BUF] ;Place to put it
HRRZ T4,%NCHRR ;Get # chars
ILDB T0,T3 ;Get char
IDPB T0,T2 ;Store in ER1BUF
SOJG T4,.-2 ;Loop till copied
PUSHJ P,BUFTYP ;Type the buffer
HRRZ T4,%NCHRR ;Get # chars again
MOVE T2,[POINT 7,ER1BUF] ;Put spaces here until arrow
MOVEI T0," " ;Get a space
CHSTP1: SOJLE T4,CHSTP2 ;Go print arrow
IDPB T0,T2 ;Store a space
JRST CHSTP1
CHSTP2: MOVEI T0,"^" ;Up-arrow
IDPB T0,T2
PUSHJ P,BUFTYP ;Type that line
POPJ P, ;Return.
>;END IF10
SEGMENT DATA
LERRBF==30 ;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
ER1BUF: BLOCK LERRBF ;Buffer for the record
INICHR: BLOCK 1 ;PREFIX CHAR OF ERROR MESSAGE
ERRPC: BLOCK 1 ;PC OF THE PUSHJ TO FORER%
ERRARG: BLOCK 1 ;ARG TO $<N>X COMMAND
COLCNT: BLOCK 1 ;COLUMN NUMBER
LIBFLG: BLOCK 1 ;-1 IF FROM LIBRARY, 0 IF FROM INSIDE FOROTS
ARGPTR: BLOCK 1 ;POINTER TO NEXT ARG
%ERARG: BLOCK 10 ;THE ARG VALUES
ERRACS: BLOCK 20 ;SAVED ACS
MODNAM: BLOCK 1 ;RADIX50 MODULE NAME FROM SYMBOL SEARCH
SUBTTL ERROR CLEANUP
;%ERSET SETS A CLEANUP ROUTINE TO BE CALLED IF AN ERROR OCCURS IN A ROUTINE OR
;ANY OF ITS SUBROUTINES.
;
;ARGS: T1 = CLEANUP ROUTINE ADDRESS
;
;IF THE ERR OR IOERR MACRO IS ENCOUNTERED BEFORE THE POPJ AT THE END OF THE
;ROUTINE, THE CLEANUP ROUTINE IS CALLED BEFORE THE ERROR MESSAGE IS TYPED.
;CLEANUP ROUTINES ARE CALLED FOR ALL NESTED ROUTINES THAT LEAD TO THE POINT OF
;THE ERROR. IF ALL CLEANUP ROUTINES RETURN NORMALLY, THE ERROR MESSAGE IS
;TYPED AND EXECUTION CONTINUES WITH THE CONTINUE ADDRESS IN THE ERR MACRO
;(USUALLY %ABORT TO STOP THE JOB).
;TRACE
SEGMENT ERR
SIXBIT /TRACE./
TRACE%:
PUSHJ P,%SAVE ;SAVE USER'S ACS
%TRACE:
PUSHJ P,%SAVE1 ;SAVE P ACS
HRRZ P1,P ;SAVE POINTER TO TOP OF STACK
PUSHJ P,GETPC ;GET TOP CALL ON STACK
JUMPE P1,TRCRET ;NONE THERE, RETURN NOW
ERR ()
ERR (TRC,,<Name (Loc) $[$[--- Caller (Loc) Args Types>)
TRACEL: HRRZM T1,CPC ;SAVE CALLER PC
HRRZM T2,RPC ;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
PUSHJ P,GETPC ;GET NEXT PC ON STACK
PUSH P,T1 ;SAVE INFO FOR NEXT LOOP
PUSH P,T2
PUSH P,T3
MOVE T4,CPC ;GET CALLER PC
SUBI T4,(T2) ;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: ERR (TR1,,<$S$7T($O)$16T$[$[---$23T$S$1O$34T($L)$48T$O$54T$A>,<RNAME,RPC,CNAME,OFFS,CPC,TRARGS,RGPTR>)
POP P,T3 ;RESTORE 'GETPC' DATA FOR LOOP
POP P,T2
POP P,T1
JUMPN P1,TRACEL ;LOOP
TRCRET:
POPJ P,
STRWDS==3 ;WORDS TO ACCOMODATE ARGUMENT SYMBOL STRING
STRLEN==5*STRWDS ;5 ASCII BYTES PER WORD
; 0123456701234567
TYPCOD: ASCII /OLIUFUOSDIOGCXUK/
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 + '...'
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
;[***] FOLLOWING CODE WON'T WORK IN NONZERO SECTION
TLC T1,010000 ;USER MODE MUST BE ON
TLNE T1,031637 ;OTHER BITS MUST BE OFF
GETPCN: SOJA P1,GETPC ;NOT SO, NOT A POSSIBLE PC
MOVEI T1,(T1) ;DISCARD LH
PUSHJ P,ADRCHK ;CHECK THAT ADDRESS IS REASONABLE
SOJA P1,GETPC ;NOT, NOT A PC
MOVEI T1,-1(T1) ;DECREMENT PC
HLRZ T2,(T1) ;GET INSTRUCTION POINTED TO BY STACK
CAIE T2,(PUSHJ P,) ;A SUBROUTINE CALL?
CAIN T2,(PUSHJ P,@) ;OR INDIRECT CALL?
JRST .+2 ;YES, OK
SOJA P1,GETPC ;NO, NOT A PC
HLRZ T2,-1(T1) ;GET INSTRUCTION BEFORE THE PUSHJ
CAIE T2,(MOVEI L,) ;CORRECT?
CAIN T2,(XMOVEI L,) ; (The other choice)
TRNA ;Yes
SOJA P1,GETPC ;NO
MOVEI T2,@(T1) ;GET DEST ADDRESS 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
HRRZ T2,@1(T3) ;GET DEST POINTED TO BY WORD AFTER JSP
GETPC1: HLRZ T3,(T2) ;GET INSTRUCTION AT TARGET ADDRESS
CAIE T3,(PUSHJ P,) ;POSSIBLE FOROTS DISPATCH IN RESET.?
JRST GETPC2 ;NO
HRRZ T3,(T2) ;GET EFFECTIVE ADDRESS OF PUSHJ
MOVS T4,(T3) ;GET INST AT THAT ADDRESS
CAIE T4,(EXCH 1,(P)) ;CORRECT?
JRST GETPC2 ;NO
HLRZ T4,1(T3) ;GET NEXT INST
CAIE T4,(ADD 1,) ;CORRECT?
JRST GETPC2 ;NO
MOVE T4,2(T3) ;GET NEXT INST
CAME T4,[TLZ 1,-1] ;CORRECT?
JRST GETPC2 ;NO
HLRZ T4,3(T3) ;GET NEXT INST
CAIE T4,(JRST (1)) ;CORRECT?
JRST GETPC2 ;NO
HRRE T4,3(T3) ;GET EFFECTIVE ADDRESS OF JRST
ADD T4,@1(T3) ;ADD IN FOROTS BASE FROM ADD
ADDI T2,1(T4) ;ADJUST PUSHJ DEST TO REAL DEST
GETPC2: HLRZ T3,(T2) ;GET INST AT DEST ADDRESS
CAIN T3,(PORTAL) ;ENTRY POINT?
MOVEI T2,@(T2) ;YES, FOLLOW TO ITS EFFECTIVE ADDRESS
HRRZ T3,-1(T1) ;GET ARG LIST ADDRESS FROM MOVEI INSTRUCTION
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
GETPCE: SETZ P1, ;FLAG THAT PDL IS DONE
SETZ T1, ;Return a zero.
MOVE T2,I.SA ;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
;PRESERVES T1
ADRCHK: 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?
JRST ADRCK1 ;NO
HLRZ T3,T2 ;GET HIGH SEG LENGTH
SUBI T2,(T3) ;GET HIGH SEG ORIGIN
CAIL T1,(T2) ;IS ADDRESS IN HIGH SEG?
JRST %POPJ1 ;YES, IT'S OK
ADRCK1:
IFN FTSHR,< ;IF FOROTS LOADED OUTSIDE HIGH AND LOW SEGS
CAIL T1,F.CODE ;IS ADDRESS IN FOROTS?
CAILE T1,Z.ERR
POPJ P, ;NO, ILLEGAL ADDRESS
JRST %POPJ1 ;YES, OK
>
IFE FTSHR,<
POPJ P, ;ADDRESS IS ILLEGAL
>
;ROUTINE TO CONVERT AN ADDRESS INTO SYMBOL+OFFSET
;ARG: T1 = ADDRESS TO CONVERT
;RETURN: T1 = RADIX50 SYMBOL NAME
; T2 = OFFSET FROM SYMBOL
;SKIP RETURN IF A SUITABLE SYMBOL FOUND, NONSKIP OTHERWISE
;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.
;THE NONSKIP RETURN IS TAKEN 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: MOVEM T1,ADR ;SAVE THE ADDR WE WANT TO MATCH
SETZM TSYM ;CLEAR THE MATCHED SYMBOL & VALUE
SETZM TVAL
SETZM TMOD ;AND MODULE NAME
MOVE T2,.JBSYM ;GET LOW SYMTAB START
JUMPE T2,TRYFRS ;None. Try FOROTS's one.
PUSHJ P,SYMSRH ;DO A SEARCH
JRST TRYFRS ;No valid symbols
DMOVEM T1,TSYM ;SAVE THE RESULT
MOVEM T3,TMOD ;AND MODULE NAME
TRYFRS:
IFN FTSHR,<
MOVE T2,F.HSM ;GET FOROTS SYMBOL TABLE PNTR
JUMPE T2,CNVDON ;DONE IF IT'S ZERO
PUSHJ P,SYMSRH ;SEARCH YET AGAIN
JRST CNVDON ;NO VALID SYMBOLS
CAMG T2,TVAL ;IF IT IS NOT A BETTER FIT
JRST CNVDON ;LEAVE
DMOVEM T1,TSYM ;ELSE REPLACE IT
MOVEM T3,TMOD ;AND MODULE NAME
> ;FTSHR
CNVDON: SKIPE T1,TSYM ;DID WE GET ANYTHING?
AOS (P) ;YES. SKIP RETURN
MOVE T2,ADR ;GET ORIG ADDR
SUB T2,TVAL ;TURN SYMBOL ADDR INTO OFFSET
MOVE T3,TMOD ;GET THE BEST MODULE NAME
MOVEM T3,MODNAM ;SAVE FOR ERROR TYPEOUT
POPJ P,
SYMSRH: HRRZM T2,SYMBEG ;SAVE ADDRESS
HLRE T2,T2 ;GET SYMTAB LENGTH
SUB T2,SYMBEG ;GET NEG (SYMTAB END + 1)
MOVM T2,T2 ;GET POSITIVE
SETZB T4,MODEND ;CLEAR MODULE NAME AND END ADDRESS
SETZM VAL ;INITIALIZE BEST-SO-FAR MODULE ADDRESS
SETZM SYM ;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
JUMPGE T2,SYMRET ;IF POSITIVE, JUNK SYMBOL TABLE FORMAT
TRNE T2,1 ;MUST ALSO BE EVEN
JRST SYMRET ;ODD, GO DIE
HRRZ T3,-1(T1) ;GET LAST WORD IN MODULE, START ADDRESS
MOVE T4,-2(T1) ;AND NEXT TO LAST, MODULE NAME
TLNE T4,740000 ;AN ACTUAL MODULE NAME?
JRST SYMRET ;NO, INVALID SYMBOL TABLE FORMAT
ADD T2,T1 ;POINT TO START OF MODULE SYMBOLS
CAMG T3,ADR ;DOES MODULE START AFTER ADDRESS TO CONVERT?
CAMGE T3,VAL ;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,VAL ;SAVE MODULE ADDRESS
MOVEM T4,SYM ;AND MODULE NAME AS SYMBOL NAME
MOVEM T4,MODNAM ;ALSO SAVE MODULE NAME FOR MESSAGES
JRST MODLP ;SEARCH WHOLE SYMBOL TABLE
MODLPE: SKIPN T1,MODEND ;GET END+1 ADDRESS OF SYMBOLS
JRST SYMRET ;NO SUITABLE MODULE FOUND, 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,ADR ;BELOW DESIRED ADDRESS?
CAMGE T2,VAL ;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,SYM ;SAVE NEW SYMBOL NAME
MOVEM T3,VAL ;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
DMOVE T1,SYM ;GET SYMBOL AND ADDRESS TO CONVERT
TLZ T1,740000 ;CLEAR HIGH BITS OF SYMBOL
MOVE T3,MODNAM ;AND GET THE MODULE NAME
SYMRET: POPJ P,
SEGMENT DATA
SYM: BLOCK 1 ;SYMBOL
VAL: BLOCK 1 ;ITS VALUE
ADR: BLOCK 1 ;ADDR WE'RE TRYING TO MATCH
SYMBEG: BLOCK 1 ;BEG OF SYMBOL TABLE
MODEND: BLOCK 1 ;MODULE END
TSYM: BLOCK 1 ;TEST SYMBOL
TVAL: BLOCK 1 ;TEST VALUE
TMOD: BLOCK 1 ;TEST MODULE NAME
SEGMENT ERR
;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
;HERE FROM ADJSP MACRO ON NON-KL IF ADD MAKES P GO POSITIVE
IFE FTKL,<
%STKOV::
ERR (POV,?,PDL overflow,,%HALT##)
>
PURGE $SEG$
END