Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/rts/ocsp.mac
There are 2 other files named ocsp.mac in the archive. Click here to see a list.
	SUBTTL OCSP  - Start a SIMULA program
	SUBTTL Lars Enderin /LE/	11-Oct-1972

X17=17
.JBREN=124
.JBOPS=135
	SEARCH	SIMMAC,SIMMCR,SIMRPA

	SALL
	RTITLE	OCSP

	INTERN	OCSPVR


		edit(303)
OCSPVR==VERRTS	;[303]

	EXTERN	.JBFF,.JBOPC,.JBREL,.JBSA
	EXTERN	.MAIN,.MAINL



	LOC	.JBOPS
	BYTE	(6)1(12)VSIMRT(18)0

	LOC	.JBREN
	Z	.OCRE0

	MACINIT

	IF1,<
	IFNDEF QNHGH,<;[225]
	IFN QDEC20,<QNHGH==1>
	IFE QDEC20,<QNHGH==2>
	>
	IFE QNHGH,<QNHGH==1>
	QRTHGH==SIXBIT/SIMR00/+VSIMRT_6
	IFE <QNHGH-2>,<QRTHGH==QRTHGH+2>
	>
Comment;

.OCSP	(start program)

Purpose
-------
To set up the environment for a SIMULA program.  Called by  a  SIMULA
main program at its entry point.

Input conditions
----------------
XCB = outermost program block address.  X1 = 0  or  address  of  area
where SIMDDT is (to be) loaded.  According to the calling sequence:
	JSP XFP,.OCSP
	JFCL runswitches address
the address of a file specification string is  passed  as  an  inline
parameter following a JSP.

Function
--------
If X1 = 0, load X1 from YOCDDT, which is non-zero if  SIMDDT
was  loaded at a previous program start or reenter after GET
or LOAD.  If X1 was non-zero, save it in YOCDDT  for  future
use.   To  guard  against  any  breakpoint  UUO's being left
around from a  possible  call  on  SIMDDT  in  the  previous
execution,  call  OCSPDR,  which  makes  sure  there  are no
breakpoints left.  Save all accumulators  in  dynamic  core.
GETSEG SIMRTS, if it was not loaded together with the object
code from the SIMULA compilation.  If .OCSP was loaded,  but
not SIMRTS, .JBOPS left half will be non-zero as a result of
a direct assignment in the OCSP module.  SIMRTS, which  must
be loaded after .OCSP, sets .JBOPS to zero at load time.  At
load time, define the reentry point (.JBREN) as the  address
of  the  code used to load SIMDDT.
Clear the static area. Initialize lookup and GETSEG info for
SIMDDT and the high segments.	      Set X2 to the address of
.YXAC (first pseudo ac), X3 = address (.MAINL) of  the  main
program  line  number  table.	  When  the  selected run time
system is safely in core, pass control to .OCIN in SIMRTS by
a  JRST  instruction.   .OCIN will finish the initialization
needed to start a SIMULA program.

Exit conditions
---------------
All registers are saved in YACSAV[0-17](XLOW) as  they  were
on  entry  to  OCSP.   X2  contains the address of the first
pseudo ac location.  X3 = .MAINL, the address  of  the  main
program  line  number  table.
X4 = address of .OCGS.	 The saved X16 value gives the
return to object code  after  RTS  initialization,  and  the
saved  value of X1 indicates where SIMDDT is (to be) loaded,
if it was requested by REENTER or the  DEBUG  command.   The
cell  .JBOPS has the address of the low segment STATIC area,
which is to be addressed via the register XLOW designated by
the  LOWADR  and  SETLOW  macros.   Exit  from OCSP is via a
branch to OCIN, which will eventually branch to  OCEI,  that
returns to object code.

Error exits
-----------
If GETSEG of the high segment fails, return to monitor level
with  monitor message Cannot GET SIMR??.	       If CORE
is scarce, EXIT 1, after ZYQNEC message.  If the core limits
can be increased, CONTINUE will cause the core request to be
re-issued.
;
	SUBTTL	.OCSP - Routine to get the SIMULA RTS high segment

	RELOC	0
	ENTRY	.OCSP	;Main entry from a SIMULA main program to initialize RTS

			edit(242)
.OCSP:	L	X10,XFP	;[242] Save return for OCIN
	SKIPN	X1
	 SKIPN	X1,YOCDDT
	  ST	X1,YOCDDT	;Save SIMDDT base or zero
	JSR	OCSPDR		;Reset any breakpoints in code
	LI	.OCRE1		;Change reentry point
				edit(303)
	SKIPE	.JBREN		;[303] If it was not set, leave it
	 ST	.JBREN		; undefined
	RESET			;Reset all software channels
				;and set .JBFF = .JBSA<LH>
	HRRZ	X17,.JBFF	;Get first free lowseg location
	HRRM	X17,.JBOPS	;Save as a base for STATIC area
	LI	X17,YLOW	;Space at least for STATIC area
	ADDB	X17,.JBFF	;Update .JBFF
	ADDI	X17,QPOLMI+1000
	IF	;Additional core is needed
		CAMG	X17,.JBREL
		GOTO	FALSE
	THEN	;try to get it
		CORE	X17,
		 GOTO	RESERR	;Hard luck, must quit
	FI
	SETLOW		;Standard base reg XLOW
	L	XLOW,.JBOPS	;Get base of STATIC area and left flags
	; - Clear STATIC area -
	HRRI	X2,YACSAV+21(XLOW)
	HRLI	X2,-1(X2)
	SETZM	YACSAV+20(XLOW)
	BLT	X2,@.JBREL
	ST	X1,YDSBA1(XLOW)		;[242]
	ST	XCB,YOCXCB(XLOW)	;[242]
;Initialize GETSEG-LOOKUP info
	edit(225)
TOPS10,<;[225]
	L	[QDEPPN]
	ST	YDEPPN(XLOW)
	L	[QHEPPN]
	ST	YHEPPN(XLOW)
	L	[QRTPPN]
	ST	YRTPPN(XLOW)
>
	L	[QSYSDEV]
	ST	YOCDEV(XLOW)
		edit(277)
	IF	;[277] No hiseg or not correct initial hiseg
		L	[-2,,.GTPRG]	;[277] Get hiseg name
		GETTAB
		 GOTO	TRUE		;No hiseg
tops10,<
		JUMPE	FALSE		;Hiseg from same file as lowseg
> ;tops10
		CAMN	[QRTHGH]
		 GOTO	FALSE		;Correct hiseg already
		HRROI	X1,.GTPRG	;Lowseg name
		GETTAB	X1,
		 GOTO	TRUE
		CAMN	X1		;Load if not same as hiseg
		 GOTO	FALSE
	THEN	;GETSEG initial hiseg
		L	X1,[QRTHGH]
		ST	X1,YRTHGH(XLOW)
		ST	X10,YACSAV+X10(XLOW)	;[242]
		JSR	.OCGS
		L	X10,YACSAV+X10(XLOW)	;[242]
	ELSE	;[277] May have to use SETUWP to avoid store traps
		edit(277)
		LI	X2,.MAIN
		IF	;Main prog in hiseg
			CAIG	X2,400K
			GOTO	FALSE
		THEN	;Remove write protection
			SETZ	X2,
			SETUWP	X2,
			 CAI	;Ignore error ret (take a chance)
	FI	FI
	HRRZS	XLOW,.JBOPS	;[242] Clear .JBOPS<LH> to show hiseg loaded
	LI	X2,.YXAC	;First pseudo ac location
	LI	X3,.MAINL	;Line number table for SIMDDT
	LI	X4,.OCGS
IFN	QDEBUG,<
OCINIT::
>
	BRANCH	OCIN		;Do rest of initialization

RESERR:	CLEARO
	OUTSTR	[ASCIZ/
?ZYQNCA No core available - can not proceed
/]
	EXIT	1,
	GOTO	.OCSP		;Try again if CONTINUE command given
	SUBTTL	OCGS - Get a high segment; [1C]

Comment;

Purpose:	To GETSEG a high segment initially or at segment swap

Entry conditions:
		X1 = SIXBIT name of wanted hiseg. Standard XLOW loaded.

Call:		By JSR .OCGS or JSR @YOCGS(XLOW)

Function:	Prevent REENTER by changing .JBREN.
		Clear any previously loaded hiseg by CORE.
		Try to GETSEG the high segment from YOCDEV(XLOW) with ppn=0.
		If that fails, try same device with ppn=YOCPPN(XLOW).
		On failure, the monitor gives an error message because of
		the HALT placed after the last GETSEG.

Exit:		To saved return address with new high segment loaded.

Error exit:	To monitor on final GETSEG failure.

;

	SETLOW	;Use standard XLOW
.OCGS::	BEGIN
	Z	;Call by JSR
	ST	X1,YOCHNM(XLOW)	;Hiseg name
	LI	.OCRE1		;Save and change .JBREN
	EXCH	.JBREN
	ST	YOCREN(XLOW)
	MOVSI	X1,1	;Set flag to clear any previously loaded hiseg
	CORE	X1,
	 NOP		;Ignore errors
	SETZM	YOCPPN(XLOW)	;Try own area or sys first
	LI	X1,YOCGSB(XLOW)
	GETSEG	X1,	;Get the high segment
	 SKIPA
	  GOTO	L9	;Found first time
	LOWADR
	L	X1,YRTPPN(XLOW);Try standard ppn if not found on own area
	ST	X1,YOCPPN(XLOW)
	LI	X1,YOCGSB(XLOW)
	GETSEG	X1,
	 HALT		;Give up, cannot find requested hiseg
L9():!	LOWADR
	L	YOCREN(XLOW)	;Restore .JBREN
	EXCH	.JBREN
	BRANCH	@.OCGS
	ENDD

	SUBTTL	OCSPDR - CALL SIMDDT TO REMOVE BREAKPOINTS

Comment;

This routine is called at start of a SIMULA program to ensure
that no old  breakpoint instructions are left in the compiled
code from an earlier (dynamic) invocation of SIMDDT.  This is
possible if this is a START or REENTER of a program which was
started once before since the last LOAD or GET (etc.) command.
;

OCSPDR:	Z		;NOTE! called by JSR!
	HRRZ	.JBOPS
	IF	;Non-zero address
		JUMPE	FALSE
	THEN	;RTS initialized already (restart implied)
		STACK	XLOW
		LOWADR
		SKIPE	XDBAS,YDSBAS(XLOW)
		 EXEC	QDSINS(XDBAS)	;remove breakpoints
					; (and perhaps other things)
		L	X1,YOCDDT
		UNSTK	XLOW
	FI
	BRANCH	@OCSPDR		;RETURN

	SUBTTL	REENTRY POINTS

Comment;

The reentry point entries are arranged as is seen below because
the standard reentry point (.OCRE) or the initial reentry point
(.OCRE0) may be manipulated from the high segment.    No matter
which reentry point is in effect, and even if the RTS is not at
all initialized, the standard reentry point can always be found
via the current .JBREN contents + 1 . The initial reentry point
can then be found  at the  address  before the standard reentry
point.
;

	Z	.OCRE0	;Initial reenter address
.OCRE:	GOTO	OCRE	;Standard reenter address
	LI	.OCRE
.OCRE0::GOTO	OCRE0
	LI	.OCRE
.OCRE1::GOTO	OCRE1
	LI	.OCRE
.OCRE2::GOTO	OCRE2
	LI	.OCRE

	SUBTTL	OCRE - main routine for REENTER

Comment;

Purpose:	At REENTER, to load and call SIMDDT when allowed
		(YDSCSW=0),      to prepare for deferred REENTER
		(YDSCSW>0), or write a message (YDSCSW<0).

Entry conditions:
		.JBOPC  is  assumed  to  contain  the  interrupt
		address from a ^C  (may  be  faked  via  OCRET).
		YDSCSW governs the action.     .JBOPS right half
		contains  the address  of the STATIC low segment
		area. No assumptions are made about the contents
		of accumulators,    but the RTS is assumed to be
		active.

Exit conditions:
		Depending on the value of YDSCSW at entry,   the
		following conditions hold on exit:
		YDSCSW = 0  - SIMDDT was loaded if necessary and
		called.  Apart from the space occupied by SIMDDT
		if loaded dynamically,   the storage pool is not
		changed.  Values of some variables may have been
		changed via SIMDDT commands.   The registers are
		restored as they were on entry.
		YDSCSW > 0    - YOBJRT (stack bottom) is changed
		so that  instead  of returning to compiled code,
		the final return from the  RTS  routine  called
		from the program is to OCRET.    YDSCAD has the
		old value of YOBJRT.   YDSCSW < 0 on exit,  i e
		interruptions  are  prevented  until  OCRET  is
		reached.   Other storage cells and the ac's are
		preserved as on entry.
		YDSCSW < 0 - no change in registers or data.

Function:	Save  all  ac's  in the area starting at offset
		YUUOAC of the STATIC area.      Stack .JBOPC as
		return address.   Change .JBREN to prevent OCRE
		to be entered when active.  If YDSLOAD is zero,
		the  RTS  is  not yet equipped to handle SIMDDT
		dynamically.    Just continue with a message in
		this case.
		If REENTER is forbidden (YDSCSW < 0),    type a
		message and continue with restored registers.
		If REENTER is deferred (YDSCSW > 0),     change
		stack bottom to point to OCRET,  save old stack
		bottom in YDSCAD,  copy any inline parameter to
		OCRET-1,   forbid REENTER and continue with the
		ac's restored.
		If YDSCSW is zero,        set switch to prevent
		garbage collection in SIMDDT, load SIMDDT, call
		the DSINR entry, reset the g c switch,  restore
		ac's and return.
;

OCRE:	PROC
	SAVEALLACS
	LOWADR
	STACK	.JBOPC	;Fake return
	EXCH	.JBREN	;Divert REENTER to another entry point
	LI	.OCRE2
	EXCH	.JBREN
	IF	;RTS set up to handle SIMDDT dynamically
		SKIPN	YDSLOAD(XLOW)
		GOTO	FALSE
	THEN	;See if SIMDDT can be called
						edit(41)
		SETON	YDSSUP(XLOW)		;[41] suppress current SIMDDT command if possible
		IF	;Inhibiting switch is zero
			SKIPE	YDSCSW(XLOW)
			GOTO	FALSE
		THEN	;We may stop right now and call SIMDDT
			HRROS	YDSCAD(XLOW)	;Mark .OCRE entry
			SETON	SWNOGC(XLOW)	;Prevent garbage collection
			EXEC	@YDSLOAD(XLOW)	;Load SIMDDT
			SETOFF	SWNOGC(XLOW)	;[41]
			EXEC	QDSINR(XDBAS)	;Call DSINR entry
						edit(242)
			SETOFF	SWNOGC(XLOW)	;[242] [41]
		ELSE
		IF	;REENTER should be deferred
			SKIPG	YDSCSW(XLOW)
			GOTO	FALSE
		THEN	;Prepare for call to SIMDDT at return point
			LI	OCRET
			;Check for inline param - must be copied
			HRRZ	X2,X17		;Current stack location
			CAIG	X2,YOBJRT(XLOW)	;If at code level, cannot stop
			 RFAIL	YDSCSW inconsistent
			HRRZ	X2,YOBJRT(XLOW)	;Code return address
			MOVM	X1,(X2)
			IF	;left half was a small neg or pos number
				TLNE	X1,(777B8)
				GOTO	FALSE
			THEN	;Copy inline param
				L	X1,(X2)
				AOS	X2	;Account for the parameter
				ST	X1,OCRET-1
				LI	OCRET-1
			FI
			ST	YOBJRT(XLOW)
			ST	X2,YDSCAD(XLOW)
				edit(124)
			IF	;[124] Stopped in input wait
				L	X2,@.JBOPC
				CAME	X2,[XCT	1]
				GOTO	FALSE
				MOVSI	(777B8)
				AND	YUUOAC+X1(XLOW)
				CAME	[IN]
				GOTO	FALSE
			THEN	;Tell the user to input a line
				OUTSTR	[ASCIZ/
[ZYQPID Please input a line of data so SIMDDT can be entered]
/]
			FI	;[124]
			HRROS	YDSCSW(XLOW)	;Inhibit ^C-REENTER
			GOTO	L9
		ELSE
			OUTSTR	[ASCIZ/
[ZYQCSH Cannot stop here]/]
	FI	FI	FI
	OUTSTR	[ASCIZ/ ... continuing ...
/]
L9():!	LI	.OCRE	;Reinstate ordinary REENTER
	ST	.JBREN
	MOVSI	X16,YUUOAC(XLOW)	;Restore all registers before returning
	BLT	X16,X16
	RETURN
	EPROC

Comment;	This routine is in effect interposed between the SIMULA
		program and the RTS when a ^C-REENTER sequence is issued
		inside a RTS routine which cannot be interrupted just anywhere,
		but which has a definite return point to compiled code.
		This return point was found at the stack bottom (YOBJRT), which
		was modified to point to OCRET or to the cell before, which
		has a copy of any inline parameter. The original contents of
		YOBJRT was saved in YDSCAD(XLOW). OCRET fakes a
		^C-REENTER sequence issued at the return point.
;

	NOP			;Copy of inline param if any
OCRET:	SETLOW
	EXCH	XLOW,.JBOPS	;Provide addressing for STATIC area
	ST	.JBOPC		;Save X0
	L	YDSCAD(XLOW)	;Where to return from SIMDDT
	EXCH	.JBOPC		;Restore X0, fake ^C address
	SETZM	YDSCSW(XLOW)	;Allow ^C-REENTER
	EXCH	XLOW,.JBOPS	;Restore XLOW and .JBOPS
	BRANCH	.OCRE		;Fake REENTER

	SUBTTL	OCRE0 - initial reentry point

Comment;

Entry conditions:
		OCRE0 is entered via  REENTER  or  directly
		from  LINK-10  after  loading.   The SIMULA
		program either has not yet been started  or
		has completed execution via OCEP.

Function:	Change  .JBREN  to  .OCRE1.   If  YOCDDT  is
		non-zero,  SIMDDT  is assumed to be in core
		at the address given there.  X1  is  loaded
		with the address and the SIMULA  program is
		entered  at  its  secondary   entry   point
		(.MAIn+2).  If YOCDDT was zero, call OCSPDR
		to remove any breakpoints which may be left
		around  since a previous dynamic invocation
		of SIMDDT.  RESET  channels  and  .JBFF  to
		start  over with fresh core.  Reserve space
		for SIMDDT  (CORE  UUO  if  necessary)  and
		record  its address in X1, setting the left
		half to -1 to signal deferred SIMDDT  load.
		Clear  the first word reserved to show that
		SIMDDT is not yet  in.   Change  .JBFF  and
		.JBSA(LH)  so  that a subsequent RESET does
		not free the space set aside for SIMDDT.

Exit:		To start of compiled main program  (.MAIN+2)
		with X1 = SIMDDT address.

Error exit:	To .MAIN (primary entry  for  main  program)
		with error message.
;

OCRE0:	PROC	;Used before start of program
	LI	.OCRE1		;Provisional reentry point until RTS ready
	ST	.JBREN
	LI	.MAIN
	HRRM	.JBSA
	SKIPE	X1,YOCDDT	;If SIMDDT is in core, just get its address
	 BRANCH	.MAIN+2
	JSR	OCSPDR		;Remove any old breakpoints
	RESET
	;Reserve space for SIMDDT now, read it in OCEI
	HLRO	X1,.JBSA	;SIMDDT base in right half, neg left half
				;signals deferred load
	LI	X2,QDSLG
	ADDB	X2,.JBFF
	IF	;No room
		CAMG	X2,.JBREL
		GOTO	FALSE
	THEN
		CORE	X2,
		GOTO	L9
	FI
	SETZM	(X1)		;Flag SIMDDT not yet in
	L	X2,.JBFF
	HRLM	X2,.JBSA	;Reserve the space over start command
	BRANCH	.MAIN+2
L9():!	OUTSTR	[ASCIZ/
%ZYQNEC Not enough core. Cannot load SIMDDT
/]
	BRANCH	.MAIN	;Ignore SIMDDT request
	EPROC

	SUBTTL	OCRE1, OCRE2 - intermediate reentry points

OCRE1:	;Used before memory setup
	OUTSTR	[ASCIZ/
[ZYQNYI RTS not yet initialized, continuing ...]
/]
	JRSTF	@.JBOPC


OCRE2:	;Used when SIMDDT cannot be called
		edit(41)
	OUTSTR	[ASCIZ/
[ZYQCCS Current SIMDDT command suppressed] /] ;[41]
	EXCH	XLOW,.JBOPS		;[41]
	SETON	YDSSUP(XLOW)		;[41] suppress current SIMDDT command if possible
	EXCH	XLOW,.JBOPS		;[41]
	JRSTF	@.JBOPC

	SUBTTL	GLOBAL VARIABLES AND TABLES

YOCDDT:	Z	;Base of SIMDDT, or zero

;;DEFINE EXTENDED (PSEUDO) AC LOCATIONS OF THE FORM .YXAn
;
	DEFINE	X(N)<.YXA'N'::	Z>
	Q==0
	XALL
.YXAC::	;first pseudo ac location
	REPEAT	<QNAC>,<
	Q==Q+1
	X(\Q)
>
	SALL

;Define interface to FORTRAN standard functions

.YFADR::	EXP	.YFARG,.YFAR2	;Address list
.YFARG::	BLOCK	2		;First parameter
.YFAR2::	BLOCK	2		;Second parameter

; Definitions for FORTRAN library subroutine exits

EXIT.=:	FOREX
		edit(21)
STOP.=:	FOREX	;[21]
FORER.::EXEC	FORER

INTERN CONT
OPDEF CONT[JRSTF @130]

	LIT
	END