Google
 

Trailing-Edge - PDP-10 Archives - tops20-v7-ft-dist2-clock - language-sources/uddt.mac
There are 8 other files named uddt.mac in the archive. Click here to see a list.
; UPD ID= 577, SNARK:<6.UTILITIES>UDDT.MAC.3,   8-Aug-84 10:19:39 by PROBINSON
TITLE	UDDT -- EMULATE USER DDT
SUBTTL	/PTR	26-JUL-84


	COMMENT	\

UDDT  --  "Dynamic Debugging Technique" stub for TOPS-20

Copyright (C) 1984
Digital Equipment Corporation, Maynard, Massachusetts, U.S.A.

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.

\


;UDDT VERSION IDENTIFICATION

MAJVER==43	;MAJOR VERSION LEVEL
MINVER==0	;MINOR (MAINTENANCE RELEASE) LEVEL
CSTVER==0	;CUSTOMER VERSION (WHO LAST . . .)
EDTVER==6	;EDIT LEVEL

%%UDDT==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>

	IF2	<PURGE MAJVER,MINVER,CSTVER,EDTVER>
	SUBTTL	JUSTIFICATION FOR EXISTENCE

	COMMENT	\

Historically, TOPS-20 UDDT.EXE (or UDDT-20) has been merged into a section
containing a program to be debugged, and has occupied the last few pages in
that section (pages 764 through 777).  Many programs have been written that
rely on DDT's start address and the location of some internal symbol pointer
locations; DDT starts at 770000, and symbol table pointers may be "stuffed"
into DDT via "MOVEM @770001" and "MOVEM @770002" instructions.  While this
may not be good programming practice, it was at the time the only solution
to a variety of problems created when the early TOPS-20 developers made a
half-hearted attempt to remove dependencies on JOBDAT from DDT.

Starting with version 43 of DDT, however, serious space problems prompted
the migration of UDDT-20 from the last few pages of the user's section into
its own section.  With an entire section to play with, UDDT's immediate space
problems have been solved.  All the user programs and CUSPS which rely on
UDDT existing in a fixed location, though, are up the creek.

This program fills the gap by looking like UDDT-20 to programs, but the
only function it performs is to bring in the real DDT into its own section
and start it.  Otherwise everything is left up to DDT proper.

Note: normal user DDT on TOPS-20 is now referred to as XDDT, and this
program is known as UDDT.  This comment is the only place within this
program where the terminology is inconsistent.

	\
	SUBTTL	REVISION HISTORY

;INITIAL UDDT.MAC CREATED 7-MAY-84

;1	PTR	13-JUN-84
;	IF WE ARE SDDT, REMIND USER THAT SDDT IS OBSOLETE BEFORE ENTERING
;	REAL DDT.  ALSO SET SYSTEM NAME TO XDDT FOR PROPER STATS.

;2	PTR	15-JUN-84
;	DON'T BE SO NASTY ON KS'S, JUST DO A HALTF%.

;3	PTR	 5-JUL-84
;	INCLUDE MORE DESCRIPTIVE ERROR MESSAGES.

;4	PTR	18-JUL-84
;	REMOVE "SDDT SUPERSEDED BY XDDT" MESSAGE.  MAKE OTHER MESSAGES
;	BE MIXED CASE (MORE LIKE EXEC MESSAGES).

;5	PTR	19-JUL-84
;	PUT ERJMP AFTER PDVOP% TO PREVENT ILL INSTR ERRORS DUE TO MONITOR BUG.

;6	PTR	26-JUL-84
;	MAKE A PLACE FOR XDDT TO RETURN TO ON ^Z.  THIS SOLVES MULTIPLE
;	PROBLEMS WITH SECTION-0 STYLE PSI.  THIS EDIT REQUIRED BY EDIT
;	556 OF XDDT.
	SUBTTL	UNIVERSALS, MACROS, OPDEFS

	SALL			;CLEAN LISTINGS
	.DIREC	FLBLST		;CLEANER LISTINGS

	SEARCH	MONSYM,MACSYM	;ALL STANDARD TOPS-20 DEFINITIONS

DEFINE	ND(S,V),<IF2,<IFDEF S,<S==S>> IFNDEF S,<S==V>> ;NOT IN MACSYM

;MACROS TO MOVE/MOVEM T1,@T IN ANY SECTION

DEFINE FETCH,<
	XMOVEI	IRET,.+2
	XJRST	[1,,IFET]>

DEFINE STORE,<
	XMOVEI	IRET,.+2
	XJRST	[1,,ISTO]>

;MACRO TO TURN A FETCHED ADDRESS INTO A REAL ADDRESS

DEFINE RESOLVE,<
	SKIPL	T1
	SKIPA	T,T1
	HRR	T,T1>

;MACRO FOR TYPING ERRORS

DEFINE FATAL($MSG),<
	JRST [	TMSG	<$MSG>
		JRST	ERR]>

OPDEF	SKPS0	[SKIPE	SECDDT]	;SKIP IF RUNNING IN ZERO
OPDEF	SKPNS0	[SKIPN	SECDDT]	;SKIP IF RUNNING IN NON-ZERO
	SUBTTL	ASSEMBLY PARAMTERS

;DEFINE ACCUMULATORS

T0=0
T1=1
T2=2
T3=3
T4=4
T=5
I0=6	;START OF FETCH/DEPMEM CODE
P=17

;ASSEMBLY CONSTANTS

	ND	LPDL,^D100	;100 WORDS IS ENOUGH STACK FOR EVERYBODY
	MAXADR==37,,777777	;MAXIMUM VIRTUAL MEMORY ADDRESS FOR A KL

;WORDS IN XDDT'S EXPORTED INFORMATION BLOCK

	.DDCNT==0		;VECTOR COUNT WORD
	.DDDDT==.DDCNT+1	;POINTER TO DDT START
	.DD0BP==.DDDDT+1	;POINTER TO $0BPT [JSR @.DD0BP+DDTEXP##]
	.DD$5M==.DD0BP+1	;POINTER TO SYTLOC ($5M)
	.DDSEC==.DD$5M+1	;POINTER TO SECUDD

.DDLEN==.DDSEC+1		;WORDS IN BLOCK


;************************************************************
;
;	TEMP DEFS TIL UNIVERSALS HAVE THEM INCORPORATED
;
;************************************************************

;PDV AND SYMBOL VECTOR SYMBOLS

ND	.PVEXP,.PVSTR		;EXPORTED INFO BLOCK
IF2,<PURGE .PVSTR>		;START ADDRESS IS OBSOLETE
	SUBTTL	MEMORY ALLOCATION PARAMETERS

;THE FOLLOWING PARAMETERS CONTROL WHERE UDDT GETS LOADED.

;RUNLOC		WHERE UDDT'S CODE WILL GO AT RUNTIME.  IF NEGATIVE,
;		UDDT'S CODE WILL START AT RELOCATABLE ZERO.
;
;VARLOC		WHERE UDDT'S VARIABLES WILL GO AT RUNTIME.  IF
;		NEGATIVE, UDDT'S VARIABLES WILL IMMEDIATELY
;		FOLLOW THE CODE.


;DEFAULT RUNLOC AND VARLOC

	ND	RUNLOC,770000	;TOPS-20 USER DDT'S OLD ORIGIN

	ND	VARLOC,771000	;VARS WILL FOLLOW CODE

;SETUP TO ALLOCATE UDDT'S CODE AT THE RIGHT PLACE

    IFGE RUNLOC,<

	IFGE VARLOC,<
	.PSECT	DDTCOD/RONLY,RUNLOC	;READ-ONLY IF VARS GO ELSEWHERE
	BEG.C==.
	> ;END IFGE VARLOC

	IFL VARLOC,<
	.PSECT	DDTALL/RWRITE,RUNLOC	;READ/WRITE IF WE GET VARS TOO
	BEG.A==.
	> ;END IFL VARLOC

    > ;END IFGE RUNLOC


    IFL RUNLOC,<
	RELOC	0		;START AT RELOCATABLE 0 IF NO RUNLOC
    > ;END IFL RUNLOC
	SUBTTL	START UDDT

UDDT:	JRST	.+2		;"JRST 770002"
	SETA	DDSYM		;NO-OP THAT LOOKS LIKE IFIW
	SETA	DDUSY		;SO JRST .+2 CAN FALL THROUGH HERE
	SETA	DDHLTA		;[6] ^Z RETURN FOR XDDT
	JSR	SAVE		;PRESERVE A FEW THINGS
	JRST	DDT1		;JUMP OVER LEGAL NOTICE

;LEGAL NOTICE FOR BINARIES

	ASCII	"Copyright (C) Digital Equipment Corporation 1984"

DDT1:	PUSHJ	P,PDVSRH	;LOOK FOR XDDT
	 PUSHJ	P,GTXDDT	;NOT ALREADY IN MEMORY, BRING IT IN
	ADDI	T,.PVEXP	;WANT THE EXPORT BLOCK
	FETCH			;GRAB THE CONTENTS
	SKIPN	T1		;[3] CAN'T BE ZERO OR WE'RE SUNK
	 FATAL	<No DDT export block address>	;[4]
	RESOLVE			;GET FULL ADDRESS INTO T
	ADDI	T,.DDCNT	;WANT THE COUNT WORD
	FETCH			;GRAB COUNT
	CAIGE	T1,.DDLEN	;LONG ENOUGH?
	 FATAL	<DDT export block too short>	;[4]
	ADDI	T,.DDSEC-.DDCNT	;LOOK AT SECTION SPECIFIER
	PUSH	P,T		;SAVE ITS ADDRESS
	FETCH			;GET IT
	RESOLVE			;MAKE IT A REAL ADDRESS
	MOVE	T1,SECDDT	;GET OUR OWN SECTION
	STORE			;AND STUFF IT INTO REAL DDT
	POP	P,T		;GET BACK TO EXPORT BLOCK
	SUBI	T,.DDSEC-.DDDDT	;LOOK AT ENTRY WORD
	FETCH			;GET THE ADDRESS WORD
	RESOLVE			;GET THE ADDRESS
	JRST	RESTOR		;JUMP INTO REAL DDT
	SUBTTL	ENTER UDDT -- SAVE

;SAVE -- SUBROUTINE TO SAVE USER CONTEXT ON ENTRY TO UDDT
;CALL:
;	JSR	SAVE
;	RETURN
;
;SAVES USER CONTEXT (ACS AND FLAGS).
;ALWAYS SETS UP UDDT CONTEXT SO UDDT WILL BE IN A KNOWN STATE.

SAVEG:	DMOVEM	16,AC0+16	;SAVE SOME ACS
	XHLLI	17,.		;GET SECTION,,0
	HLLZ	16,SAVE		;GET SECTION 0 PC FLAGS
	SKIPE	17		;IN NON-ZERO SECTION?
	XSFM	16		;YES, ASK CPU FOR PC FLAGS
	MOVEM	16,XSAVE	;SAVE PC FLAGS FOR LATER XJRSTF
	MOVEM	17,SECDDT	;SAVE OUR SECTION NUMBER
	HRRZI	16,AC0		;SAVE REMAINING ACS
	BLT	16,AC0+15

;SET UP DDT'S FIXED ACS

	MOVE	P,[IOWD LPDL,PDL]  ;SET UP STACK POINTER
	MOVE	IRET,[SETI0,,I0]   ;SET UP SOME ACS FOR FETCH/STORE MACROS
	BLT	IRET,IRET

;NOW CHECK CPU TYPE.  HAD BETTER BE A KL.
;KS AND KL MODEL A'S CAN'T RUN DDT V43 (OR TOPS-20 V6, FOR THAT MATTER).
;UNFORTUNATELY THERE IS NO CLEAR WAY OF DISTINGUISHING KL A'S AND B'S.

	MOVEI	T1,-1		;A LARGER-THAN-ONE-DIGIT VALUE
	SETZB	T2,T4		;CLEAR STRING BYTE PTR.
	MOVEI	T3,1		;SET DOUBLE LENGTH BINARY RESULT
	EXTEND	T0,[CVTBDO]	;CONVERT BINARY TO DECIMAL
	TLNE	T3,200000	;KL10 MICROCODE SETS THIS BIT
	JRST	@SAVE		;IT'S A KL, ALL DONE
	TMSG	<
? UDDT STUB RUNNING ON NON-KL PROCESSOR>
	HALTF%			;[2] CAN'T GO ON
	JRST	.-1		;[2] OR CONTINUE, EITHER
	SUBTTL	LEAVE UDDT -- RESTOR, DDHLTA

;RESTOR -- RESTORES USER STUFF AND JUMPS INTO DDT.
;
;  T/	ADDRESS TO JUMP TO
;	JRST	RESTOR
;DOES NOT RETURN

RESTOR:	MOVEM	T,SAVE		;PUT ADDRESS IN PROPER PLACE
	HRLZI	17,AC0		;RESTORE USER'S ACS
	BLT	17,17
	XJRSTF	XSAVE		;NEED XJRSTF TO SWITCH SECTIONS


;DDHLTA -- WHERE XDDT WILL RETURN ON ^Z
;COME HERE WITH ALL USER CONTEXT RESTORED (BY XDDT)

DDHLTA:	HALTF%			;[6] DO THE HALT
	JRST	UDDT		;[6] RESTART ON A CONTINUE
	SUBTTL	PDVSRH -- SEARCH FOR XDDT'S PDV

;PDVSRH -- LOOKS FOR A PDV WITH NAME "DDT%"
;CALL:
;	PUSHJ	P,PDVSRH
;	 NO DDT% PDV
;	PDV EXISTS, ADDRESS IN T
;PRESERVES NO ACS

PDVSRH:	SKIPE	T,PDVA		;DID WE ALREADY DO THIS?
	JRST	CPOPJ1		;YES, JUST SKIP RETURN
	PUSHJ	P,PDVINI	;SET UP PDVOP% ARG BLOCK
	MOVEI	T1,.POLOC	;LOCATE FUNCTION
	XMOVEI	T2,PDVARG	;ADDRESS OF ARG BLOCK
	HRROI	T3,[ASCIZ/DDT%/]  ;THE PDV WE ARE LOOKING FOR
	PDVOP%			;FIND THE PDV
	 ERJMP	CPOPJ		;[5] SOMEBODY DIED, NO DDT AROUND
	MOVE	T,PDVA		;GET ADDRESS IN CASE IT WORKED
	SKIPE	PDVARG+.POCT2	;ANYTHING FOUND?
CPOPJ1:	AOS	(P)		;YES, SIGNAL FOUND
CPOPJ:	POPJ	P,		;AND RETURN

;PDVINI SETS UP PARAMETERS IN THE PDVOP% ARG BLOCK
PDVINI:	MOVEI	T,1		;ONLY 1-WORD BLOCK
	MOVEM	T,PDVARG+.POCT2	;SET THE COUNT WORD
	XMOVEI	T,PDVA		;POINT TO DATA "BLOCK"
	MOVEM	T,PDVARG+.PODAT	;SO PDVOP% CAN FIND IT
	POPJ	P,		;ALL DONE
	SUBTTL	MERGE XDDT INTO MEMORY

;GTXDDT -- MERGES SYS:XDDT.EXE INTO MEMORY AND FINDS ITS PDVA.
;CALL:
;	PUSHJ	P,GTXDDT
;	RETURN WITH PDVA IN T
;PRESERVES NO ACS

GTXDDT:	MOVX	T1,.FHSLF	;WANT THIS PROCESS'
	XGVEC%			;ENTRY VECTOR
	DMOVEM	T2,EVEC		;SAVE OVER GET% OF XDDT

;FIND AN AVAILABLE SECTION

	PUSHJ	P,GETSEC	;CREATE A HIGH-NUMBERED SECTION
	MOVEM	T,GETARG+.GBASE	;STORE FOR GET%
	MOVX	T,GT%BAS	;WE ARE SPECIFYING A SECTION NUMBER
	MOVEM	T,GETARG+.GFLAG	;TELL GET%

;LOOK FOR SYS:XDDT.EXE (IGNORE USER'S LOGICAL NAMES IF WE ARE EXECUTE-ONLY).

	MOVX	T1,RF%LNG!.FHSLF;GET PROCESS STATUS (LONG FORM)
	XMOVEI	T2,RFSARG	;INTO THE ARG BLOCK
	RFSTS%			;GET STATUS
	MOVX	T1,GJ%SHT!GJ%OLD;SHORT FORM, FILE ALREADY THERE
	MOVE	T2,RFSARG+.RFSFL  ;GET FLAGS
	TXNE	T2,RF%EXO	;EXECUTE-ONLY FORK?
	TXO	T1,GJ%PHY	;YES, USE "PHYSICAL" SYS:
	HRROI	T2,[ASCIZ/SYS:XDDT.EXE/]  ;REAL DDT
	GTJFN%			;FIND THE FILE
	 ERJMP	NODDT		;NOT THERE ?!?

;MERGE XDDT INTO MEMORY

	HRLI	T1,.FHSLF	;WANT IT IN OUR PROCESS (JFN ALREADY IN T1)
	TXO	T1,GT%ARG	;FLAG ARG BLOCK IN T2
	XMOVEI	T2,GETARG	;POINT TO ARG BLOCK
	GET%			;MERGE IT IN
	 ERJMP	NODDT		;CAN'T ?!?

;RESTORE OUR ORIGINAL ENTRY VECTOR IF WE'RE NOT SDDT
;IF WE ARE SDDT, DON'T CHANGE THE ENTRY VECTOR.  THAT WAY XDDT WILL
;THINK IT'S ALONE IN THE FORK AND WILL ACT LIKE SDDT.

	DMOVE	T2,EVEC		;ORIGINAL ENTRY VECTOR
	XMOVEI	T,UDDT		;GET OUR START ADDRESS
	CAMN	T,T3		;[1] ARE WE SDDT?
	JRST	GTSDDT		;[1] YES, SET IT UP
	MOVX	T1,.FHSLF	;[1] THIS PROCESS
	XSVEC%			;[1] BACK TO ORIGINAL
	JRST	GTXDD1		;[1] GO LOOK FOR PDV

GTSDDT:	MOVX	T1,<SIXBIT/XDDT/>  ;[4] SET OUR SYSTEM NAME
	MOVE	T2,T1		;[1] AND PRIVATE NAME
	SETSN%			;[1]
	 ERJMP	.+1		;[1] IGNORE IMPOSSIBLE ERRORS

;NOW FIND XDDT'S PDV.

GTXDD1:	PUSHJ	P,PDVSRH	;HAD BETTER BE THERE
	 FATAL	<SYS:XDDT.EXE does not have proper PDV>	;[4]
	POPJ	P,		;ALL DONE
	SUBTTL	GETSEC -- CREATE A NEW SECTION

;GETSEC -- CREATES A HIGH-NUMBERED SECTION FOR XDDT TO LIVE IN
;CALL:
;	PUSHJ	P,GETSEC
;	RETURN WITH 0,,SECTION IN T
;PRESERVES NO ACS

GETSEC:	MOVEI	T,37		;HIGHEST POSSIBLE SECTION
GETSE0:	HRLI	T1,.FHSLF	;LOOKING AT OUR PROCESS
	HRR	T1,T		;AND THIS SECTION
	RSMAP%			;GET THE INFO
	TXNN	T2,PA%PEX	;SECTION EXISTS?
	JRST	GETSE2		;NO, GO CREATE IT
	SOJG	T,GETSE0	;YES, ANY LEFT?
	FATAL	<No free section for XDDT>	;[4] NO (ZERO ALWAYS EXISTS)

GETSE2:	SETZ	T1,		;CREATE SECTION FUNCTION
	HRLI	T2,.FHSLF	;IN THIS PROCESS
	HRR	T2,T		;THIS SECTION
	MOVX	T3,SM%RD!SM%WR!SM%EX!1	;CREATE ONE SECTION WITH FULL ACCESS
	SMAP%			;ZINGO!
	POPJ	P,		;ALL DONE


;ERROR HANDLING -- NODDT, ERR

NODDT:	TMSG	<
? >				;TYPE LEADING ?
	MOVX	T1,.PRIOU	;USER'S TTY
	HRLOI	T2,.FHSLF	;THIS PROCESS,,LAST ERROR
	SETZ	T3,		;NO LIMIT
	ERSTR%			;TYPE THE MESSAGE
	 JFCL
	 JFCL
ERR:	TMSG	<
? Error encountered while attempting to load XDDT>	;[4]
	HALTF%			;DIE
	JRST	.-1		;STAY DEAD
	SUBTTL	PURE STORAGE

;DATA FOR FETCH/STORE MACROS

SETI0:				;START OF BLOCK TO BLT
	PHASE	I0		;PHASE TO ACS
IFET:!	SKIPA	T1,@T		;FETCH FROM ADDRESS IN T
ISTO:!	MOVEM	T1,@T		;STORE INTO ADDRESS IN T
	XJRST	IRET		;ALL DONE
IRET:!	Z			;FIXED UP AT RUNTIME
	DEPHASE			;BACK TO NORMAL

IFG IRET-16,<PRINTX	? FETCH/STORE CODE TOO LONG FOR ACS>

;SET UP PROPER PSECTS IF NECESSARY

	LIT			;LITERALS ARE ALWAYS PURE

    IFGE RUNLOC,<

	IFGE VARLOC,<

	END.C==.			;REMEMBER END OF CODE LOCATION
	LEN.C==END.C-BEG.C		;DETERMINE PSECT LENGTH
	.ENDPS	DDTCOD			;END OF CODE PSECT

	.PSECT	DDTVAR/RWRITE,VARLOC	;VARS IN READ/WRITE PSECT
	BEG.V==.

	> ;END IFGE VARLOC

    > ;END IFGE RUNLOC
	SUBTTL	IMPURE STORAGE

;PDVOP% ARGUMENTS
;.POCT2, .PODAT FILLED IN AT RUNTIME

PDVARG:	EXP	6		;.POCT1, WORDS IN BLOCK
	EXP	.FHSLF		;.POPHD, FORK HANDLE
	EXP	0		;.POCT2, WORDS IN DATA BLOCK
	EXP	0		;.PODAT, ADDRESS OF DATA BLOCK
	EXP	0		;.POADR, START ADDRESS OF RANGE
	EXP	MAXADR		;.POADE, END ADDRESS OF RANGE
PDVA:	EXP	0		;ADDRESS OF XDDT'S PDV

;RFSTS% ARGUMENTS

RFSARG:	BLOCK	5		;FOR LONG-FORM RFSTS%

;GET% ARGUMENTS

GETARG:	BLOCK	4		;FOR LONG-FORM GET%

;STORAGE FOR SAVE/RESTORE

XSAVE:	BLOCK	1		;PC FLAGS
SAVE:	EXP	%%UDDT		;JSR TO HERE
	JRST	SAVEG		;THEN JUMP TO ROUTINE

;MISCELLANEOUS STORAGE

AC0:	BLOCK	20		;USER'S ACS
SECDDT:	BLOCK	1		;OUR SECTION,,0
EVEC:	BLOCK	2		;REMEMBER ENTRY VECTOR OVER GET%
DDSYM:	BLOCK	1		;POSSIBLE STUFFED DEFINED POINTER
DDUSY:	BLOCK	1		;POSSIBLE STUFFED UNDEFINED POINTER

PDL:	BLOCK	LPDL		;STACK

  IFGE RUNLOC,<
    IFGE VARLOC,<
	END.V==.			;REMEMBER END OF VARS LOCATION
	LEN.V==END.V-BEG.V		;DETERMINE PSECT LENGTH
	.ENDPS	DDTVAR			;END OF VAR PSECT
    > ;END IFGE VARLOC

    IFL VARLOC,<
	END.A==.
	LEN.A==END.A-BEG.A
	.ENDPS	DDTALL
    > ;END IFL VARLOC
  > ;END IFGE RUNLOC
	SUBTTL	SPACE LEFT AND END OF EVERYTHING

DEFINE PRROOM(SPACE,NAME),<
	IF2,<	PRINTX	[SPACE words left in NAME area]
	>
> ;END DEFINE PRROOM

DEFINE PRFULL(SPACE,NAME),<
	IF2,<	PRINTX	? NAME area overflowed by SPACE words
	>
> ;END DEFINE PRFULL

	RADIX	10

    IFGE RUNLOC,<

	IFGE VARLOC,<

;REPORT CODE SPACE REMAINING

	IFGE VARLOC-RUNLOC,<CODSPC==VARLOC-<RUNLOC+LEN.C>>
	IFL VARLOC-RUNLOC,<CODSPC==^O1000000-<RUNLOC+LEN.C>>

	IFGE CODSPC,<PRROOM(\CODSPC,<code>)>
	IFL CODSPC,<PRFULL(\<-CODSPC>,<code>)>

;REPORT DATA SPACE REMAINING

	IFGE VARLOC-RUNLOC,<VARSPC==^O1000000-<VARLOC+LEN.V>>
	IFL VARLOC-RUNLOC,<VARSPC==RUNLOC-<VARLOC+LEN.V>>

	IFGE VARSPC,<PRROOM(\VARSPC,<data>)>
	IFL VARSPC,<PRFULL(\<-VARSPC>,<data>)>

	> ;END IFGE VARLOC

	IFL VARLOC,<

;REPORT TOTAL SPACE REMAINING

	ALLSPC==^O1000000-<RUNLOC+LEN.A>
	IFGE ALLSPC,<PRROOM(\ALLSPC,<DDT's>)>
	IFL ALLSPC,<PRFULL(\<-ALLSPC>,<DDT's>)>

	> ;END IFL VARLOC

    > ;END IFGE RUNLOC

	RADIX 8

	END	<1,,UDDT>