Trailing-Edge
-
PDP-10 Archives
-
BB-H138E-BM
-
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>