Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93k-bb - 10,7/galaxy/glxlib/glxini.mac
There are 31 other files named glxini.mac in the archive. Click here to see a list.
TITLE GLXINI - Bootstrap code for GALAXY runtime system
SUBTTL Irwin L. Goverman/ILG/PJT/DC/DPM/CTK 25-Sep-83

;
;
;        COPYRIGHT (c) 1975,1976,1977,1978,1979,1980,1981,1982,
;			 1983,1984,1985,1986
;                    DIGITAL EQUIPMENT CORPORATION
;			 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  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.


;This module is loaded in the low segment of any program
;	using the GALAXY library code, GLXLIB.

	SEARCH	GLXMAC			;SEARCH GLXMAC FOR SYMBOL DEFS
	PROLOG(GLXINI,INI)

	INIEDT==24			;EDIT LEVEL FOR MODULE
SUBTTL Table of Contents


;               TABLE OF CONTENTS FOR GLXINI
;
;
;                        SECTION                                   PAGE
;    1. Table of Contents.........................................   2
;    2. Revision History..........................................   3
;    3. I%INIT - Initialize the runtime system....................   4
;    4. ACQLIB - Acquire the run-time system......................   5
;    5. CHKLIB - Routine to test if library is in place...........   7
;    6. TRYSEG - Routine to fetch runtime system..................   8
SUBTTL	Revision History

COMMENT \

Revision History

EDIT	GCO	DISCRIPTION

0002		Changed I%INIT so it can accept a zero length IB and
		to pass the major change level in S2 instead of IB.PID
0004		Changed PROLOG to process GLXINI as a library component
0005		Pull PFH out of GLXINI. It now lives in the sharable
		high segment
0006		using stkvars to provide space for string for gtjfn
		change tryseg to get the entire exe file instead of
		certain pages
0007		Define %%.GLX external to pick it up from the main program
0010		Don't $STOP if MERGE. UUO fails, it'll just
		?Ill mem ref
0011		Correct logic for deceiding where to obtain OTS. In particular,
		add SFD support.
0012		Plug a security leak that allowed a JACCT'ed program to grab
		a private copy of the library.
0013		Make GLXLIB run execute-only.
		 1) Set up APR trap prior to call to I%INI1.
		 2) Remove code to merge GLXLIB data pages.
0014		Restructure GLXLIB
		 1) Rework CDO macro to generate a table that kinda parallels
		    thehigh segment entry vector and call it ENTVEC just to
		    cunfuse things. This is required for extended addressing
		    and saves and incompatible change later on.
		 2) If the program is execute-only, do a physical-only GETSEG.
0015	3/21/81  Change .JBHGH reference in I%INIT (for T20) to use .JBHSO
		Change reference to CORG in CHKLIB to use .JBHSO instead
0016	3/27/81  Change $RETT at ACQL.3+5 to POPJ since the entry vector
		is not yet set up.
0017	4/6/81  Restructure GLXINI so the 20 works.  Force all system
		dependent code into TRYSEG and CHKLIB.  Find the
		beginning of the dispatch table by getting the entry
		vector on the 20.  Set .JBHSO ourselves so DDT can find
		symbols.
0020	4/14/81  Set right half of .JBHRL to -1 so DDT believes the symbols.
0021	7/13/81  Do not initialize the entry vector if already initialized.
0022	9/25/83	Fix non problem coding error.
		SPR 10-33434/CTK
0024	6/23/89	Fix to use SEGOP. UUO for 7.04 and later monitors, so
		that GLXLIB can be an additional hiseg.
		GCO 10671  /RCB


\ ;end of revision history
SUBTTL	User referenced entry vector


; All references to the OTS by the user are through ENTVEC table
;
	ZZ==0				;;INITIALIZE COUNTER
DEFINE	CDO	(X),<			;;MACRO TO DEFINE ENTRY POINTS
	IFNB <X>,<X::>			;;DEFINE GLOBAL IF NOT NULL
	JRST	@.+1			;;DISPATCH
	EXP	ZZ			;;STORE INDEX INTO GLXOTS
	ZZ==ZZ+1			;;POINT TO NEXT ENTRY
>					;;END OF CDO MACRO

DEFINE	NT(X),<				;;MACRO FOR GLXINI ENTRY POINTS
	IFNB <X>,<GLOB X>		;;MAKE ENTRY POINT GLOBAL
	BLOCK	2			;;KEEP THE VECTOR STRAIGHT
	ZZ=ZZ+1				;;POINT TO THE NEXT ENTRY
>					;;END NT MACRO

ENTVEC::LIBVEC				;DEFINE ALL ENTRY POINTS
	EXP	-1			;TERMINATE VECTOR

WORK:	BLOCK	20			;Get space for working
ARG:	BLOCK	.SGFSP+1		;Get space for argument block...
ARGFIL:	BLOCK	.SGFLN			;SPACE FOR FILESPEC BLOCK
OLDMON:	BLOCK	1			;FLAG FOR WHETHER SEGOP. EXISTS

; Set up correct places to search for the library depending on the system.

TOPS10<
DSKDEV:	SIXBIT/DSK/
SYSDEV:	SIXBIT/SYS/
> ; End of TOPS10

TOPS20<
DSKDEV:	[ASCIZ/DSK:/]
SYSDEV:	[ASCIZ/SYS:/]
> ; End of TOPS20

COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1971,1986.
ALL RIGHTS RESERVED.
\;END OF COPYRIGHT MACRO
SUBTTL I%INIT - Initialize the runtime system


;Entry point for segment and module initialization

;CALL IS:	S1/ Length of IB (Runtime Initialization Block)
;		S2/ Address of IB

	ENTRY	I%INIT

I%INIT:	PUSH	P,S1			;SAVE INPUT ARGS AWAY
	PUSH	P,S2			;
	PUSHJ	P,CHKLIB		;SEE IF THE LIBRARY IS ALREADY THERE
	JUMPT	INIT.2			;IT IS - SKIP LOTS OF STUFF
	PUSHJ	P,ACQLIB		;ACQUIRE THE LIBRARY SYSTEM
	SKIPE	ENTVEC+1		;Is the entry vector initialized?
	JRST	INIT.2			;Yes, don't do it again.
	SETZM	S2			;Set up index

INIT.1:	ADDM	S1,ENTVEC+1(S2)		;ADJUST INDEX INTO GLXOTS
	ADDI	S2,2			;ACCOUNT FOR TWO WORD ENTRIES
	SKIPL	ENTVEC(S2)		;END OF VECTOR ?
	JRST	INIT.1			;NO - LOOP

INIT.2:	POP	P,S2			;RESTORE USER'S S2
	POP	P,S1			;RESTORE USER'S S1

SEGIN::	HRLI	S1,%%.GLX		;LOAD VERSION
	PUSHJ	P,ENTVEC		;CONTINUE INITIALIZATION
	$RETT				;RETURN TO CALLER
SUBTTL	ACQLIB - Acquire the run-time system


; Here if the OTS is not in place.  If this is a debugging world,
; look first in DSK:.  If that fails, or if we are not debugging,
; look in SYS:.  If not found, give an error message and quit.
; If found, return the address of the dispatch table for the library
; in S1.
;
; Call:		No arguments
;
; Return:	S1 / Address of OTS dispatch table (returned from TRYSEG)
;
ACQLIB:	SKIPN	DEBUGW			;Debugging ?
	JRST	ACQL.1			;Nope - skip checking on DSK
	MOVE	S1,DSKDEV		;Try generic DSK
	PUSHJ	P,TRYSEG		;Try it again
	JUMPT	ACQL.2			;If sucessful - finish up

ACQL.1:	MOVE	S1,SYSDEV		;Try SYS
	PUSHJ	P,TRYSEG		;One more time
	JUMPT	ACQL.2			;If sucessful - finish up

TOPS10<
	OUTSTR	[ASCIZ	|? GLXINI - Unable to obtain run-time system|]
	MONRT.				;Stop
> ; End of TOPS10

TOPS20<
	HRROI	S1,[ASCIZ \? GLXINI - Unable to obtain run-time system
\]
	PSOUT
	HALTF
> ; End of TOPS20

	JRST	.-1			;We really don't want to continue

ACQL.2:	POPJ	P,			;Return
SUBTTL CHKLIB - Routine to test if library is in place

;CHKLIB	looks for the first page of the OTS library. If this page
;	is there, it is assumed that the library was loaded with the
;	calling program, or has been pre-merged.

;CALL IS:	No arguments
;
;TRUE RETURN:	Library is in place
;
;FALSE RETURN:	Library is not there

CHKLIB:

TOPS10 <
	SETZM	OLDMON			;ASSUME A NEW MONITOR
	MOVX	S1,OTSNAM		;NAME OF DESIRED HISEG
	MOVEM	S1,ARG+.SGSNM		;SET FOR .SGINF CALL
	SETZM	ARG+.SGSGN		;WE DON'T KNOW THE SEGMENT NUMBER YET
	SETZM	ARG+.SGFLG		;WE NEED NO FLAGS
	XMOVEI	S1,ARGFIL		;POINT TO THE FILE BLOCK
	MOVEM	S1,ARG+.SGFSP		;SET IN THE ARGUMENT BLOCK
	MOVX	S1,<.SGFSP+1,,.SGINF>	;LENGTH,,FUNCTION
	MOVEM	S1,ARG+.SGFNC		;SET FOR UUO
	MOVE	S1,[IFIW ARG]		;LOCAL POINTER TO THE ARG BLOCK
	SEGOP.	S1,			;SEE IF WE HAVE THE SEGMENT
	  TRNA				;MAYBE NOT--ANALYZE ERROR
	JRST	.RETT			;YES--RETURN GOODNESS
	JUMPGE	S1,.RETF		;IF AN ERROR CODE, THEN WE DON'T HAVE IT

;HERE IF SEGOP. FAILED DUE TO AN OLD MONITOR.  CHECK THE OLD WAY.

	SETOM	OLDMON			;TELL TRYSEG THERE'S NO SEGOP. UUO
	HRRZ	S1,.JBHRL		;Get highest addr in high seg
	SKIPN	S1			;Is there a segment? Yes, skip
	TDZA	TF,TF			;LOAD "FALSE" INTO TF
	MOVX	TF,TRUE			;ELSE ITS THERE
	POPJ	P,			;RETURN IN EITHER CASE
> ;END TOPS10 CONDITIONAL

TOPS20 <
	MOVE	S1,.JBHSO		;FIRST PAGE OF LIBRARY
	JUMPE	S1,[MOVX TF,FALSE	;If zero, then not set up
		    JRST CHKL.1]	;Return false
	HRLI	S1,.FHSLF		;FOR THIS PROCESS,
	RPACS				;READ THE ACCESS BITS
	  ERJMP .+2			;IF FAILS, SAY OTS NOT THERE
	TXNN	S2,PA%PEX		;CHECK FOR PAGE'S EXISTENCE
	TDZA	TF,TF			;IF PAGES DON'T EXIST, RETURN
	MOVX	TF,TRUE			;ELSE TRUE,INDICATING OTS IN PLACE
CHKL.1:	POPJ	P,			;RETURN
> ;END TOPS20 CONDITIONAL
SUBTTL TRYSEG - Routine to fetch runtime system

;CALL IS:	S1/ Device to get runtime system from in SIXBIT (TOPS10)
;		    Address of device string (TOPS20)
;
;TRUE RETURN:	Segment is in place
;  with		S1/ Address of dispatch table
;FALSE RETURN:	Segment could not be obtained

TOPS10 <

	JS.XO==2000			;EXECUTE-ONLY BIT IN JOB STATUS WORD

TRYSEG:	MOVEM	S1,ARGFIL+0		;STORE DEVICE NAME
	MOVX	S1,OTSNAM		;NAME OF OTS
	MOVEM	S1,ARGFIL+1		;STORE THE FILE NAME
	HRROI	S2,.GTSTS		;GET JOB STATUS
	GETTAB	S2,			;FROM THE MONITOR
	  SETZ	S2,			;CAN'T - ASSUME NOT EXECUTE ONLY
	TRNN	S2,JS.XO		;EXECUTE ONLY?
	  TDZA	S2,S2			;NO
	MOVX	S2,UU.PHY		;YES - SET FOR PHYSICAL ONLY GETSEG
	SKIPE	OLDMON			;IF WE KNOW THAT SEGOP. WON'T DO,
	JRST	TRYS.2			;THEN DON'T ATTEMPT IT
	SETZM	ARGFIL+2		;DEFAULT EXTENSION
	SETZM	ARGFIL+3		;AND PPN
	SETZM	ARGFIL+4		;AND PATH
	MOVEI	S1,.SGGET		;OUR FUNCTION CODE
	HRRM	S1,ARG			;SET IN ARG BLOCK
	XMOVEI	S1,ARG			;POINT TO THE ARGUMENT BLOCK
	SEGOP.	S1,(S2)			;TRY TO GET THE SEGMENT
	  JRST	.RETF			;PROPAGATE FAILURE
	HRRZ	S1,ARG+.SGORG		;GET THE LOCAL ORIGIN
	PG2ADR	S1,			;CONVERT PAGE NUMBER TO ADDRESS
	HRR	S1,.JBHSA(S1)		;ENTRY IS AT THE OTS START ADDRESS
	JRST	.RETT			;WE WIN
TRYS.2:	MOVE	S1,[0,,WORK+0]		;BLT THE ACS AWAY
	BLT	S1,WORK+17		;STORE THEM
	MOVEI	S1,ARGFIL		;GET LOCATION OF BLOCK
	GETSEG	S1,(S2)			;ATTACH HIGH SEGMENT
	  TDZA	TF,TF			;IF FAILS, FAKE A FALSE
	MOVX	TF,TRUE			;ELSE LOAD A "TRUE"
	MOVE	S1,[WORK+S2,,S2]	;RESTORE SOME ACS
	BLT	S1,17			;
	JUMPF	TRYS.1			;False, return

	MOVE	S1,[XWD -2,.GTUPM]	;Get UPM word for our high seg.
	GETTAB	S1,			;Ask the monitor
	  HRLI	S1,.JBHGH		;Monitor won't give it, assume 400000
	HLRZS	S1			;Get high seg start adr
	ADDI	S1,.JBHDA		;Point past JOBDAT

TRYS.1:	POPJ	P,			;RETURN

> ;END TOPS10 CONDITIONAL
TOPS20 <

TRYSEG:	MOVE	TF,S1			;Save device string a second
	MOVX	S1,.FHSLF		;For self
	GEVEC				;Get entry vector word
	PUSH	P,S2			;And save it
	MOVE	S1,TF			;Restore s1

	HRLI	S1,(POINT 7,0)		;Make the address a byte pointer
	MOVE	S2,[POINT 7,WORK]	;Generate a pointer to destination for
					;  string
TRYS.1:	ILDB	TF,S1			;Get a byte of the device string
	JUMPE	TF,TRYS.2		;Done?
	IDPB	TF,S2			;No, save the byte
	JRST	TRYS.1			;Go get another

TRYS.2:	MOVE	S1,[POINT 7,OTSNAM]	;Get the name of the OTS

TRYS.3:	ILDB	TF,S1			;Get a byte of the OTS name
	IDPB	TF,S2			;Save the byte
	JUMPN	TF,TRYS.3		;Get till done

	MOVX	S1,GJ%SHT+GJ%OLD	;SHORT GTJFN, OLD FILE
	MOVE	S2,[POINT 7,WORK]	;Get the pointer to the beginning of
					;  the string
	GTJFN				;TRY TO GET A HANDLE ON THE FILE
	  JRST	TRYS.4			;FAKE A FALSE RETURN
	TXO	S1,GT%ADR		;SET BIT FOR ADDRESS SELECTION
	HRLI	S1,.FHSLF		;FOR MYSELF
	MOVE	S2,[1,,760]		;ALL PAGES FROM 1 TO 760
	GET				;GET THE SEGMENT
	  ERJMP	TRYS.4			;IF GET FAILS, RETURN FALSE

	MOVX	S1,.FHSLF		;For self
	GEVEC				;Get entry vector word for OTS
	HRRZS	S2,S2			;Get only the address
	MOVE	TF,S2			;Save it
	ADR2PG	S2			;Make a page number
	MOVEM	S2,.JBHSO		;Save it for DDT and CHKLIB
	HLLOM	S2,.JBHRL##		;Convince DDT to use the symbols
	POP	P,S2			;Restore entry vector word
	SEVEC				;Set it back
	MOVE	S1,TF			;Get address of dispatch vector
	MOVX	TF,TRUE			;We are ok
	JRST	TRYS.5			;go to return

TRYS.4:	MOVX	TF,FALSE		;HERE FOR FALSE RETURN
	POP	P,S2			;Restore stack
TRYS.5:	POPJ	P,			;AND RETURN
> ;END TOPS20 CONDITIONAL
	SUBTTL	RETURN ENTRY POINTS

; These are alternate return points that can be called from
;the user program to avoid having to go through the OTS. Since
;most programs do a lot of $RETx's, using these routines can
;save a great deal of time.
;
; Note: any resemblence to this code, and that found that in GLXCOM
;is purely intentional.

; .RETT and .RETF are called via the $RETT and $RETF macros and can also
; be called directly.  They both set the value of TF, one to TRUE and the other
; to FALSE.  After doing this, they return via a POPJ P,
;
.RETF:	TDZA	TF,TF		;ZEROS MEAN FALSE
.RETT:	SETO	TF,		;ONES MEAN TRUE
	POPJ	P,		;RETURN


; The .POPJ and .POPJ1 routines can be jumped
; to get a return, without changing the value in the TF register
;
.POPJ1:	AOS	(P)		;SKIP
.POPJ:	POPJ	P,		;RETURN
INI%L:
	END