Trailing-Edge
-
PDP-10 Archives
-
BB-JF18A-BM
-
sources/dynlib/mthdyn.mac
There are 3 other files named mthdyn.mac in the archive. Click here to see a list.
TITLE MTHDYN -- TOPS-20 RTL interface to MTHLIB
SEARCH DYNSYM,DDBSYM,MONSYM,MACSYM,MTHPRM
;
; COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1984, 1986.
; ALL RIGHTS RESERVED.
;
; 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 THAT IS NOT SUPPLIED BY DIGITAL.
;
COMMENT \
***** Begin Revision History *****
MTHDUM.MAC
3224 JLC 10-Dec-82
New module, derived from FORERR, for MACRO use of
the math library.
***** Start MTHDYN.MAC *****
V1.0
DD-B 9-NOV-83
Start making this part of the dynamic run-time library.
Restriction: MTHLIB routines cannot be reentered. MTHLIB
itself cannot be reentered. Don't call MTHLIB routines from
places that can be reached by interrupting out of MTHLIB!
Version 1.1
;.EDIT 50 Formally go to version 1.1, update copyright, insert V1.1
; development changes (previously V2)
; DDB,15-Jan-85,SPR:NONE
***** End Revision History *****
\
SALL
ENTRY MTHER.
INTERN PDLBOT
INTERN %FSECT,%LFIXD,%LERTP
EXTERNAL RTLERS,SG$SIG,SG$DLG
SEGMENT CODE
; This, as far as I am concerned, is the guts of the whole thing.
; This routine is called by the $LERR macros that exist in MTHLIB.
; The PUSHJ P, in the $LERR call is followed by an error block (see definition
; of $lerr in MTHPRM) which gives error information. In addition, this
; relies on many globals.
MTHER.: POP P,%ERPTR ;SAVE ERROR BLOCK POINTER
MOVEM P, %ERPDP
SAVACS ;Save 0-16 on stack
XMOVEI T0, .SVAC0(17) ;Get address of AC0
MOVEM T0, AERACS ;Need to know how to find them later
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,%ERPDP ;GET ERROR STACK PNTR AGAIN
PUSHJ P,GETPC ;GET CALLER ADDR
;(returns T1, T2, T3)
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
; Cheat -- we will now ask RTLERS to make us a block for our own nefarious
; purposes.
MMGLEN==60 ;Length to allow for message in words
PUSH P, [MMGLEN,,0]
PUSH P, [MT$OEM]
CALL RTLERS
MOVE P7, T1 ;Save SG block address
MOVE T1, %ERRPC
MOVEM T1, .SGPC(P7) ;PC call to MTHLIB that got error
SETZM .SGDAT(P7) ;No user data
XMOVEI T1, .SGLEN(P7) ;There is no DATA area
;Put message over the EXTRA and MESSAGE areas
TXO T1, 67B5 ;9-BIT OWGBP
MOVEM T1, .SGMSG(P7) ;Message pointer
MOVEM T1, ERRPTR
MOVX T1, MMGLEN*4-1
MOVEM T1, ERRCNT
FOREC: MOVE P2,%ERPTR ;POINT TO ERROR BLOCK
PUSHJ P,EMSGT0 ;Get error message text with no NUL
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.
; Now we have a MT$OEM block all filled out, address in P7
; Now make an MT$ERR block, point it at the OEM block, and signal it
PUSH P, %ERNM1
PUSH P, %ERNM2
PUSH P, %LERTP
XMOVEI T1, %LFIXD
PUSH P, T1
PUSH P, [4]
PUSH P, [MT$ERR]
CALL RTLERS
MOVE T0, %ERRPC
MOVEM T0, .SGPC(T1)
MOVEM P7, .SGNXT(T1)
MOVEM T1, P7
CALL SG$SIG
MOVE T1, P7
CALL SG$DLG ;De-allocate the signal chain
RSTACS ;Restore saved ACs if continued
; fall through to exit
; Used to do conditional POPJ with a JUMPE, SOJLE, or whatever
%POPJ: POPJ P,
;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: XMOVEI P1,(P1) ;GET EXTENDED ADDR
GETPCL: MOVE T1,(P1) ;GET SOMETHING OFF STACK
CAMN T1,['STOP!!'] ;MAGIC END-OF-STACK CONSTANT?
JRST GETPCE ;YES, GO RETURN END-OF-STACK INDICATION
CAMGE P1,PDLBOT ;MIGHT NOT BE A TRACE USER
JRST GETPCE ;SO LEAVE IF BELOW PDP FOR %ERINI
TLNE T1,(77B5) ;[3151] Leftmost 6 bits must be zero by now
SOJA P1,GETPCL ;[3151] Nope, can't be a saved PC
PUSHJ P,ADRCHK ;CHECK THAT ADDRESS IS REASONABLE
SOJA P1,GETPCL ;NOT, NOT A PC
MOVE T1,(P1) ;GET ENTIRE ADDR AGAIN
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,GETPCL ;NO, NOT A PC
HLRZ T2,-1(T1) ;GET INSTRUCTION BEFORE THE PUSHJ
TRZ T2,37 ;TURN OFF INDIRECT AND INDEX
CAIE T2,(MOVEI CX,) ;CORRECT?
CAIN T2,(XMOVEI CX,) ; (The other choice)
TRNA ;Yes
SOJA P1,GETPCL ;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,@0(T2) ;YES. GET DEST ADDR OF PUSHJ
;Note: if multi-level indirect, indexing after
;the first level won't be trapped, but still
;won't work. This could give faulty error
;reports.
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,GETPCL ;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.
XMOVEI T2,1+[EXP <SIXBIT /UNKNWN/>,0]
XMOVEI T3,1+[EXP <0>,<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 page number is valid and page exists.
ADRCHK:
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
TXO T1,(FH%EPN) ;[3162] 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
;%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
; This is a subroutine.
; Arguments:
; P2/ Address of error block
; ERRPTR/ Pointer to destination string
; ERRCNT/ Count of characters available at destination string
EMSGT0: GETBP P3, %MSG(P2), T1 ;Get proper byte pointer to input error string
; Take the pointer to output error string in ERRPTR on entry
; Take the count of characters available at ERRPTR in ERRCNT on entry
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,EPUTCH ;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
ILDB T1,P3 ;GET NEXT CHAR
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 "A",$A ;ASCIZ STRING
XWD "O",$O ;OCTAL NUMBER
XWD "S",$S ;SIXBIT WORD
XWD "N",$N ;NAME OF ROUTINE (SIXBIT) FROM %ERNAM [NO ARG]
XWD "5",$5 ;RADIX50 WORD
XWD "P",$P ;ERROR PC, OCTAL [NO ARG]
LERRTB==.-ERRTAB
$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
PCTYP: 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
PJRST OCTTYP
$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
$O: 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
PJRST OCTTYP ;TYPE IT IN OCTAL
;Routine called to append the PC to the error message.
ADDPCM: MOVEI T1,[ASCIZ/ at PC /]
PUSHJ P,ASCTYP
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,
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
;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,
SEGMENT DATA
%ERTYP: BLOCK 1 ;VARIABLE TYPE
%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
ERSTKP:: BLOCK 1 ;ERROR AC STACK POINTER (IFIW)
ERRSTK:: BLOCK 60 ;ERROR AC STACK
MSGPC: BLOCK 1 ;PC FOR MESSAGE
AERACS: BLOCK 1 ;ADDRESS OF SAVED ACS
LERRBF==60
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
ERRARG: BLOCK 1 ;ARG TO $<N>X COMMAND
COLCNT: BLOCK 1 ;COLUMN NUMBER
ARGPTR: BLOCK 1 ;POINTER TO NEXT ARG
INICHR: BLOCK 1 ;INITIAL ERROR CHAR
%FSECT: BLOCK 1 ;LH=SECTION NUMBER OF ERROR ROUTINE
PCSECT: BLOCK 1 ;SECTION OF CALLER ROUTINE
PDLBOT: BLOCK 1 ;PDP BOTTOM IN CASE NON-TRACE STACK
%LFIXD: BLOCK 1 ;User-fixed result of routine
%LERTP: BLOCK 1 ;Error type code
END