e _vߋt The volume labeled "VMS Exchange" is not a system volume. VMS ExchangeMIDDLETON DECVMSEXCHNGkQ*(%*(kQ*(z*Iq *ă*ă%*ă[*ăkQ*ăxQ*ăv'*ă.kQ *ă3Ԁ*ă5kQO*ăy:ƒ*ăkQkQ*ă\}kQ*ăƀ%*ăԀkQ*ă*ă%*ăv)*ăƒ-ăy:ƒV -.sbttl COMMAND PARSING ROUTINES ; This is a collection of routines to parse-out and identify a command ; embedded in an input string. ; Brought to you by: ; William K. Walker ; Monsanto Research Corp. ; P. O. Box 32 ; Miamisburg, OH 45342 ; (513) 865-3557 .mcall push, pop .psect cexrtn .sbttl . Usage ; A typical procedure for using these routines is as follows: ; 1) Point R0 into your input buffer at the first character of the ; command that you want to extract and identify. ; 2) Point R1 at the buffer that the extracted command will be ; placed in. ; 3) Point R2 at a table of command terminator characters (this table ; is essentially an ASCIZ string). ; 4) Point R4 at the beginning of the reference string address list ; (list of pointers to the ASCIZ strings that represent the valid ; commands). ; 5) Call GETCOM to extract the command from the input buffer and put ; it in the command buffer. ; 6) Call CSCAN to compare the contents of the command buffer against ; the list of valid commands. ; 7) Use the offset returned by CSCAN in R5 to go do something. ; There is no inherent limit on the length of an input string or the length ; of a command. Commands may include any character (including control ; characters!) except the separator/terminator characters in the specified ; terminator table (null is always a terminator as well). GETCOM contains ; a "pre-done" terminator table at address TMTBL containing blank, "/", "=", ; and comma. Colon can also be added to this list by using address TMTBLC. ; Note that command reference strings may not include lower-case (a-z) ; characters. ; Note also that these routines can be used to handle any component of an ; input string with definable separator/terminators. For example, ; GETCOM/CSCAN could be used in a program mainline to process a command ; and invoke the appropriate command execution routine and this latter ; routine could use GETCOM/CSCAN to process the arguments that were included ; in the input line. .sbttl . Example ; The following is a sample program that uses this GETCOM/CSCAN calling ; sequence to print some useless but illuminating(?) messages in response to ; various commands. ; .title whose.mac ; .enabl lc ; ; ; Program to illustrate GETCOM/CSCAN command interpretation ; ; .mcall .gtlin, .print, .exit ; .globl getcom, cscan ; ; whose: ; .gtlin #inpbuf,#prompt ;Get a line of input from console ; mov #inpbuf,r0 ;R0 => input buffer ; mov #cmdbuf,r1 ;R1 => command buffer ; mov #tmtbl,r2 ;R2 => default terminator table ; mov #rsalst,r4 ;R4 => reference string addr. list ; call getcom ;Extract command ; call cscan ;Try to identify it ; call @cealst(r5) ;Call appropriate routine ; .exit ;Quit ; ; inpbuf: .blkb 81. ;Input buffer ; cmdbuf: .blkb 81. ;Command buffer ; prompt: .ascii /Whose is it? /<200> ;Prompt text for .GTLIN ; .even ; ; ; Reference string address list ; ; rsalst: .word smine ; .word smystf ; .word sours ; .word syours ; .word 0 ; ; ; Command reference strings ; ; syours: .asciz /YOURS/ ; smine: .asciz /MINE/ ; smystf: .asciz /MY_STUFF/ ; sours: .asciz /OURS/ ; .even ; ; ;Dispatch table for commands ; ; .word badcom ; .word ambcom ; cealst: .word mine ; .word mine ; .word ours ; .word yours ; ; ; Command execution routines... ; ; badcom: mov #badmsg,r0 ; br prntit ; ambcom: mov #ambmsg,r0 ; br prntit ; yours: mov #yoursm,r0 ; br prntit ; mine: mov #minem,r0 ; br prntit ; ours: mov #oursm,r0 ; prntit: .print ; return ; ; badmsg: .asciz /?Invalid Command?/ ; ambmsg: .asciz /?Ambiguous Command?/ ; yoursm: .asciz /That's Yours/ ; minem: .asciz /That's Mine/ ; oursm: .asciz /That's Ours/ ; .even ; ; .end whose .sbttl . getcom ; GETCOM ; ====== ; ; This routine moves a command from a specified string into a command ; buffer. The string representing the command is assumed to be terminated ; when a null or one of the characters in a specified terminator table ; is encountered. The command in the command buffer is terminated with a ; null. ; On entry, R0 points at the beginning of the input string (the command is ; assumed to start at the beginning of the string), R1 points at the ; command buffer, and R2 points at a table of terminator characters. ; On return, R0 points at the first of the input string following the ; command, R1 points at the loaded command buffer, and R2 points at the ; terminator table used. ; Note that a default terminator table is supplied at TMTBL and TMTBLC. ; Register use summary: ; ; on entry, R0 points into input buffer, at 1st char. of command ; R1 points at command output buffer ; R2 points at terminator table ; R3 unused ; R4 unused ; R5 unused ; ; on return, R0 points into input buffer, 1 char. past command ; R1 unchanged, points at command output buffer ; R2 unchanged, points at terminator table ; R3 undisturbed ; R4 undisturbed ; R5 undisturbed getcom:: push ;Save R1, R4, R2 clr r4 getch: movb (r0)+,r4 ;Get a character bicb #200,r4 ;Strip parity bne sftch ;Branch if not null getcqt: clrb @r1 ;End command with null dec r0 ;Adjust string pointer pop ;Restore R2, R1 and R4 return sftch: cmpb r4,#'a ;Shift lower case to upper case... blt tstch cmpb r4,#'z bgt tstch bicb #40,r4 tstch: mov (sp),r2 ;Get pointer to terminator table 10$: tstb (r2) ;End of list? beq putch ;Branch if so cmpb r4,(r2)+ ;Got match with this terminator? beq getcqt ;Branch if so br 10$ ;Otherwise, go check next terminator putch: movb r4,(r1)+ ;Move character to command buffer br getch ;Get another tmtblc: .ascii ":" ;Default terminator table... tmtbl: .ascii " " .ascii "/" .ascii "=" .ascii "," .byte 0 .sbttl . cscan ; CSCAN ; ===== ; ; This routine scans a list for a given command ; On entry, R1 points at the command buffer (loaded by "GETCOM"). R4 ; points at the command reference string address list (RSAL). This list ; contains the pointers to the ASCIZ strings that represent the set of valid ; commands. These pointers should be in alphabetical order by the referenced ; strings (i.e., the reference strings can be in any order, but the address ; list should point to them in alphabetical order). ; On return, R1 and R4 are unchanged. ; ; R5 contains the offset into the address list where the command was found. ; If the command is not found, R5=-4. If the command is ambiguous, R5=-2. ; ; R3 contains information on the exactness of the match between the command ; and the reference string. If the match was exact, R3=0. If CSCAN found a ; match, but it was not exact (i.e., the reference string found was longer ; than the command string), R3=1. If no match was found, R3=-1. Note that an ; ambiguous command will result in R3=1. ; Register use summary: ; ; on entry, R0 unused ; R1 points at command buffer ; R2 unused ; R3 unused on entry ; R4 points at command RSAL ; R5 unused on entry ; ; on return, R0 undisturbed ; R1 unchanged, points at command buffer ; R2 undisturbed ; R3 contains match data ; R4 unchanged, points at command RSAL ; R5 contains match offset data cscan:: clr r5 ;Set list index=0 push ;Save R2, R4 cagain: mov (r4)+,r2 ;Point at reference string bne csrch ;End of list? mov #-2,r5 ;Yes, command not found crtrn: asl r5 ;Make index an offset pop ;Restore R4 return ;Quit csrch: push r1 ;Save R1 (points at command) call ccomp ;Compare with list entry pop r1 ;Restore R1 tst r3 ;Check result of comparison bgt cnextc ;>0, might be a hit beq crtrn ;=0, exact match inc r5 ;Bump list index br cagain ;Try again cnextc: mov @r4,r2 ;Point at next reference string beq crtrn ;End of list? push ;Save R3, R1... call ccomp ;Do comparison pop r1 ;Restore R1 tst r3 ;Match? bmi 10$ ;No, return mov #-1,r5 ;Yes, command is ambiguous 10$: pop r3 ;Restore R3 br crtrn ;Go quit .sbttl . ccomp ; This routine compares a command string (pointed to by R1) with a ; reference string (pointed to by R2). The result is returned in R3. ; If a command of length n matches the first n characters of the reference ; string, R3=1. If the two strings match exactly, R3=0. R3=-1 if the ; strings do not match. ccomp:: clr r3 ;R3 is match/no match flag tstb @r1 ;Null command string? beq 15$ ;Yes, return as no match 10$: tstb @r1 ;End of command string? beq 20$ ;Branch if so cmpb (r1)+,(r2)+ ;Compare characters beq 10$ ;Branch if same 15$: dec r3 ;No match, R3=-1 return ;Quit 20$: tstb @r2 ;End of reference string also? beq 25$ ;Yes, exact match, R3=0 inc r3 ;R3=1 25$: return ;Return ! command file to build ! CI handler ! ===================== ! ! input device is DK: ! ! output device is DK: ! ! for RT-11 V05.02 ! or later only ! macro ci link/nobit/exec:ci.sys ci del ci.obj .mcall .module .module CI release=V03 version=03 comment= audit=yes .rem | ------------------------------------------------------------------------------ Another handleroid brought to you by: William K. Walker Monsanto Research Corp. P. O. Box 32 A-152 Miamisburg, OH 45342 (513) 865-3557 This handleroid allows you to turn the various RT-11 Command Line Interpreters (CLI's) on or off using SET commands. It will also show which CLI's are enabled. There are four CLI's: UCF (User Commands First), DCL (Digital Command Language), CCL (Concise Command Language), and UCL (User Command Linkage). Refer to the RT-11 documentation for an explanation of each. The possible SET commands for the CI (Command Interpreter) handleroid are: SET CI [NO]UCF -- turn UCF on/off SET CI [NO]DCL -- turn DCL on/off SET CI [NO]CCL -- turn CCL on/off SET CI [NO]UCL -- turn UCL on/off SET CI HELP -- display SET commands and version/release of CI SET CI RESET -- same as SET CI NOUCF,DCL,CCL,UCL SET CI SHOW -- display the active CLI's By default, RT-11 has all CLI's enabled except UCF. In other words, the normal situation is equivalent to SET CI NOUCF,DCL,CCL,UCL Thus, if you issued a SET CI SHOW command under an unaltered monitor, CI would report ?CI-I-CLI's enabled: DCL CCL UCL Note that SET CI RESET restores/insures the above default condition. It is not possible to INSTALL CI. This is because CI contains only SET code. As there is no executable handler code, there is no reason why CI should be installable -- it would just waste a device slot in the monitor tables that could be used for something else. The monitor will execute the SET options as long as CI has the right name and resides on SY:. Thus, for the RT-11 SJ and FB monitors, the file should be SY:CI.SYS. If you are going to use it under XM, make a copy named SY:CIX.SYS. If you are running under the RTEM monitor, it should be named SY:CIM.SYS. NOTE TO RTEM USERS ~~~~~~~~~~~~~~~~~~ CI, when running under RTEM, will default to having all CLI's turned on (SET CI RESET equivalent to SET CI UCF,DCL,CCL,UCL). The text displayed by SET CI HELP will also change to reflect this condition. ***************************************************************************** * WARNING: Turning off both DCL and CCL effectively turns off the monitor. * ***************************************************************************** NOTE ~~~~ CI will not run under versions of RT-11 prior to V5.2 (RTEM V2.1). It will not work under TSX-Plus -- versions as late as V6.01 have not yet implemented the necessary support. -----------------------------------------------------------------------------| ; Various handy constants... jsw = 44 ;Address of job status word edit$ = 20 ; JSW disable SL editor bit sysgen = 372 ;Offset to monitor sysgen features word rtem$ = 10 ; RTEM monitor bit sysver = 276 ;Offset to RT-11 version/release data $inddv = 426 ;RMON fixed offset pointer to IND device name, unit ucf$ = 1 ;CLI enable bits in CLIFLG byte... dcl$ = 2 ccl$ = 4 ucl$ = 10 lf = 012 ;Linefeed cr = 015 ;Carriage return ; Necessary macro's... .mcall .addr, .assume, .drdef, .gtlin, .print ; The RTV5.3 conditional enables support for the new handler macros introduced ; with RT-11 V5.3. The current default is to disable this support. However, ; these new macros will be required for V5.4. Later versions of this handler ; will have this support enabled as the default condition. .iif ndf rtv5.3 rtv5.3 = 0 .iif ne rtv5.3 rtv5.3 = 1 ; Driver definitions... ; ; Since we only do SET code, we are both read-only and write-only. .drdef ci, 377, ronly$!wonly$, 0, 0, 0 .iif ne rtv5.3 .drest class=dvc.ps ; "Installation" code... ; ; This is really "uninstallation" code. Since CI only does SET code, there is ; no reason for it to be installed in the monitor tables. .drins ci nop sec ;Always fail to install... return ; Routine to make "context" adjustments to CI SET code... ; ; The RTEM monitor uses the UCF facility to implement some RTEM-specific ; monitor commands. Thus, UCF is turned on by default under RTEM. UCF is off ; by default under RT-11. C.NTXT checks to see if we are running under RTEM, ; and, if necessary, dynamically modifies the effect of SET CI HELP and SET CI ; RESET. c.ntxt: mov r0,-(sp) ;Save R0 mov pc,r0 ;Get value of monitor SYSGEN word... add #c.area-.,r0 emt 375 bitb #rtem$,r0 ;Running under RTEM? beq 10$ ;Branch if not inc r3 ;Sets UCF$ if called by RESET routine movb #40,mhelpm ;Change "NOUCF" to " UCF" in help text... movb #40,mhelpm+1 10$: mov (sp)+,r0 ;Restore R0 return ;Quit c.area: .byte 0, 34 ;EMT arguments for getting SYSGEN value... .word sysgen ; Note that we have stuck the context checking routine into the unused area ; belonging to the installation code. Next, we'd better make sure that we ; don't overflow into the area reserved for the handler SET code. .assume . le 400 message=<;*** OVERFLOW INTO SET OPTION TABLES ***> ; SET option tables... .drset UCF, ucf$, o.ucf, no .drset DCL, dcl$, o.dcl, no .drset CCL, ccl$, o.ccl, no .drset UCL, ucl$, o.ucl, no .drset HELP, 1, o.help .drset RESET, , o.rset .drset SHOW, 5, o.show ; SET CI [NO]UCF, [NO]DCL, [NO]CCL, [NO]UCL o.ucf: o.dcl: o.ccl: o.ucl: br o.set ;Branch to code to turn a CLI on nop o.clr: call o.ciwd ;R0 => 1 word past CLIFLG/CLITYP word mov -(r0),r1 ;Save CLIFLG/CLITYP value mov r0,-(sp) ;Save CLIFLG/CLITYP address on stack bic #^C<6>,r1 ;Mask for DCL, CCL bits bic r3,r1 ;See if we would have neither bne 10$ ;Branch if at least one left active bis #edit$,@#jsw ;Disable SL editor .addr #mwarn,r2 ;R2 => warning message mov #512,r1 ;R1 => input buffer .gtlin r1,r2 ;Issue warning, get response bicb #^C<137>,(r1) ;Did the idiot answer "yes"?... cmpb (r1),#'Y bne 20$ ;Just go quit if not mov pc,r0 ;Issue Pontius Pilate message... add #mstupd-.,r0 .print 10$: bic r3,@(sp) ;Clear requested bit 20$: tst (sp)+ ;Clean up the stack br o.good ; and quit o.set: call o.ciwd ;R0 => 1 word past CLIFLG/CLITYP word bis r3,-(r0) ;Turn on the selected CLI return ; SET CI RESET o.rset: call o.ciwd ;R0 => 1 word past CLIFLG/CLITYP word bic #1,-(r0) ;Assume UCF is to be turned off call c.ntxt ;Do any context adjustments bis r3,(r0) ;Restore default CLI's return ; SET CI HELP o.help: call c.ntxt ;Do possible context adjustment mov pc,r0 ;Calculate address of help test... add #mhelp-.,r0 .print ;Print it br o.good ;Quit with carry clear ; SET CI SHOW o.show: call o.ciwd ;Make R0 point at INDDEV (1 word past CLIFLG) mov -(r0),r2 ;Put CLIFLG/CLITYP word in R2 .addr #m,r1 ;"...CLI's enabled:"... .print r1 add #m1-m,r1 ;Point at first one to check... br 20$ 10$: add #m2-m1-1,r1 ;Point at next 20$: bitb (r1)+,r2 ;This CLI active? beq 30$ ;Branch if not .print r1 ;Otherwise, print following text 30$: sob r3,10$ ;Go look at next one until done br o.good ;Quit with no error ; Routine to check for RT-11 version and return with address of INDDEV in R0. ; ; O.CIWD attempts to prevent the user from inadvertantly zapping the monitor ; by checking the RT-11 release/version word to make sure that we are running ; under a V5.2 or later monitor. This is not a sure thing because some ; versions of V5.1 had a bug that screwed up this information. ; ; If the release/version is OK, the address of INDDEV is returned in R0, and ; the carry bit is clear. o.ciwd: .addr #o.area,r1 ;Get version/release of RT-11 (pic-style)... mov r1,r0 emt 375 swab r0 ;Are we running V5.2 or later?... cmp r0,#<5*400!2> bge 10$ ;Branch if so add #10,r1 ;If not, point R1 at error message .print r1 ;"...Wrong version of RT-11" tst (sp)+ ;Pop stack to force a return to monitor br o.bad ;Go quit 10$: add #4,r1 ;Get pointer to INDDEV word mov r1,r0 ; (1 word past CLIFLG)... emt 375 o.good: tst (pc)+ ;Return with carry clear... o.bad: sec return .assume . le 1000 message=<;*** SET CODE IS TOO LARGE ***> ; This is the dummy handler code which is included for hand-holding purposes. .drbeg ci ciint:: .drfin ci .drend ci ; Data area...don't mess with the order of this stuff!!! o.area: .byte 0, 34 ;Argument area for EMT's used by O.CIWD... .word sysver .byte 0, 34 .word $inddv .nlist bex .nlcsi type=i, part=prefix ;ASCII stuff... .asciz "F-Wrong version of RT-11" m: .nlcsi type=i,part=prefix .ascii "I-CLI's enabled:"<200> m1: .ascii < 1>" UCF"<200> m2: .ascii < 2>" DCL"<200> .ascii < 4>" CCL"<200> .ascii <10>" UCL"<200><17><0> mhelp: .byte cr, lf .nlcsi type=i .byte cr, lf, lf .ascii "SET CI [NO]UCF -- turn UCF on/off" .ascii "SET CI [NO]DCL -- turn DCL on/off" .ascii "SET CI [NO]CCL -- turn CCL on/off" .ascii "SET CI [NO]UCL -- turn UCL on/off" .ascii "SET CI HELP -- display this text" .ascii "SET CI RESET -- same as SET CI " mhelpm: .ascii "NOUCF,DCL,CCL,UCL" .asciz "SET CI SHOW -- display active CLI's" mwarn: .ascii "Disable access to monitor commands/utilities; " .ascii "Are you sure? "<200> mstupd: .ascii "OK...it's your funeral!" .even .list bex ; Here we must ensure that we are entirely within the first two blocks of the ; handler. Only blocks 0 and 1 are loaded in memory when SET code is ; executed. .assume <.-cistrt> le 1000 message=<;*** EXCEEDED HANDLER BLOCK 1 ***> .end 62 `Q&e  Dă2dN[q`"FxU$ &E@U$e7Jf& ŠWYeT@ 9 HP @E P e& "e@eeB@~eL@ e@ e@ e,}?CI-F-Wrong version of RT-11?CI-I-CLI's enabled: UCF DCL CCL UCL CI V03.03 SET CI [NO]UCF -- turn UCF on/off SET CI [NO]DCL -- turn DCL on/off SET CI [NO]CCL -- turn CCL on/off SET CI [NO]UCL -- turn UCL on/off SET CI HELP -- display this text SET CI RESET -- same as SET CI NOUCF,DCL,CCL,UCL SET CI SHOW -- display active CLI'sDisable access to monitor commands/utilities; Are you sure? OK...it's your funeral! RT-11 V5.1 USERS IF YOU ARE GOING TO USE THIS VERSION OF UCL+ UNDER THE RT-11 V5.1 MONITOR (OR EQUIVALENT RTEM-11 MONITOR), YOU MUST APPLY THE PATCH IN THE SECTION OF THE DOCUMENTA- TION TITLED "PATCHING UCL+ FOR RT-11 V5.1" FOR UCL+ TO WORK PROPERLY (IT'S NOT MY FAULT -- IT'S DEC'S FAULT). V07.54 OR EARLIER UCL+ USERS THE "CD" AND "RNO" COMMANDS ARE NO LONGER INCLUDED IN THE DISTRIBUTED UCL+ PROGRAM. "CD" CAN NOW BE DEFINED AS A SYMBOL, AS CAN A BASE-LINE "RNO" COMMAND. SEE THE APPLICATION NOTES FOR DETAILS. THE STANDARD, HARD-WIRED "RNO" COMMAND IS ALSO AVAILABLE AS A CONDI- TIONAL ASSEMBLY. Your first step should be to print the documentation. It is con- tained in the file UCL.DOC and runs about 65 pages. The major executable components of this kit are: o UCL.SAV - the UCL+ program o UCLXM.SAV - a special XM version of UCL+ (RT-11 V5.2 or later only) o UCLHLP.TXT - the help text necessary to build a UCL+ help program o CI.SYS - the Command Line Interpreter handler (also RT-11 V5.2 or later only) Installation instructions for the various UCL+ components are in- cluded in the documentation. UCL+ supports RT-11 monitors starting with V5.0 and TSX-Plus starting with V4.1. It also runs under the RT-11 emulator (RTEM) on RSX-11 and VMS systems. It will support, without modifica- tion, the following command interpretation facilities: o UCL (User Command Linkage) for RT-11 and TSX-Plus o UCF (User Commands First) for RT-11 o UCI (User Command Interpreter) for TSX-Plus ; Conditionals file for assembly of UCL+ .iif ndf ucl$xm, ucl$xm = 0 ; Form .TITLE, .IDENT, etc.; define RLS, VZN .mcall vrdata .iif eq ucl$xm, vrdata .iif ne ucl$xm, vrdata xmucl=yes ; Conditionals... .if eq ucl$xm blok1 = 1 ;BLOK1 is actual 1st block in SAV image for .iff ; symbol/status area blok1 = 3 .endc .iif ndf rno$c, rno$c = 0 ;rno$c = 1 enables RNO command .iif ndf uci$c, uci$c = 1 ;uci$c = 0 disables UCI_MODE command .iif eq uci$c, pfx = 0 .iif ndf pfx, pfx = '. ;Prefix character for HW commands in UCI_MODE ; pfx = 0 disables this feature .iif ndf dfpfx, dfpfx = '[ ;Prefix and suffix characters for argument .iif ndf dfsfx, dfsfx = '] ; default strings ; Special conditionals .iif ndf okray, okray = 0 .iif ndf c4ell, c4ell = 0 ; .MCALL necessary macros .mcall .chain, .close, .csigen, .csispc, .exit, .fetch, .gtlin, .gval .mcall .herr, .lookup, .print, .purge, .rctrlo, .readw, .serr, .settop .mcall .sreset, .ttyout, .writw ;(in UCLMAC library...) .mcall push, pop, .cscan, .getcom, .gtrec, .prlin .include "ucl.mac" .include "ucltxt.mac" .include "ucltbl.mac" .include "uclhwc.mac" .include "cex.mac" top:: .end ucl ! command file to build ! UCL+ program ! ===================== ! ! input device is DK: ! ! output device is DK: ! LIB/MAC UCLMAC UCLMAC R MACRO UCL=UCLMAC/M,UCL.CND ^C LINK/BOUND:512./MAP:UCL UCL MAIN DEL UCLMAC.MLB,UCL.OBJ UU UU CCCCCC LL UU UU CCCCCC LL UU UU CC CC LL ++ UU UU CC CC LL ++ UU UU CC LL ++ UU UU CC LL ++ UU UU CC LL ++++++++++ UU UU CC LL ++++++++++ UU UU CC LL ++ UU UU CC LL ++ UU UU CC CC LL ++ UU UU CC CC LL ++ UUUUUU CCCCCC LLLLLLLLLL UUUUUU CCCCCC LLLLLLLLLL USER COMMAND LINKAGE-plus V07.55b 20 Apr 1987 William K. Walker Monsanto Research Corp. P. O. Box 32 Miamisburg, OH 45342 (513) 865-3557 SPECIAL NOTE TO SCIENTISTS/RESEARCHERS Read the manual! Page ii TABLE OF CONTENTS 1.0 ACKNOWLEDGEMENTS . . . . . . . . . . . . . . . . . . . . . . 1 2.0 IMPORTANT NOTICES . . . . . . . . . . . . . . . . . . . . . 1 3.0 BEFORE YOU GET STARTED . . . . . . . . . . . . . . . . . . . 1 4.0 ABOUT THIS DOCUMENT . . . . . . . . . . . . . . . . . . . . 2 5.0 INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . 3 5.1 UCL+ Differences . . . . . . . . . . . . . . . . . . . . . . 3 5.2 UCL+ Enhancements . . . . . . . . . . . . . . . . . . . . . 4 6.0 INSTALLATION . . . . . . . . . . . . . . . . . . . . . . . . 6 6.1 Installing UCL.SAV . . . . . . . . . . . . . . . . . . . . . 7 6.1.1 Installing UCL.SAV On RT-11 Systems . . . . . . . . . . . 7 6.1.1.1 Installation As A UCL (UCL.SAV) . . . . . . . . . . . . 7 6.1.1.2 Installation As A UCF (UCF.SAV) . . . . . . . . . . . . 8 6.1.2 Installing UCL.SAV On TSX-Plus Systems . . . . . . . . . . 8 6.1.2.1 Installation As A UCL (TSXUCL.SAV) . . . . . . . . . . . 8 6.1.2.2 Installation As A UCI (UKMON.SAV) . . . . . . . . . . . 9 6.2 Installing UCLXM.SAV . . . . . . . . . . . . . . . . . . . . 9 6.2.1 Installing UCLXM.SAV On RT-11 Systems . . . . . . . . . 10 6.2.1.1 Installation As A UCL (UCL.SAV) . . . . . . . . . . . 10 6.2.1.2 Installation As A UCF (UCF.SAV) . . . . . . . . . . . 11 6.2.2 Installing UCLXM.SAV On TSX-Plus Systems . . . . . . . . 12 6.2.2.1 Installation As A UCL (TSXUCL.SAV) . . . . . . . . . . 12 6.2.2.2 Installation As A UCI (UKMON.SAV) . . . . . . . . . . 13 6.3 Installing The CI Handler . . . . . . . . . . . . . . . . 13 6.4 Installing UCL+ HELP . . . . . . . . . . . . . . . . . . . 14 6.5 Installing The UCL+ Distribution Under RTEM . . . . . . . 15 7.0 HOW IT WORKS . . . . . . . . . . . . . . . . . . . . . . . 16 7.1 RT-11 Command Processing With UCL Support . . . . . . . . 16 7.2 RT-11 Command Processing With UCF Support . . . . . . . . 17 7.3 TSX-Plus Command Processing . . . . . . . . . . . . . . . 17 8.0 SYMBOLS . . . . . . . . . . . . . . . . . . . . . . . . . 19 8.1 Defining Symbols . . . . . . . . . . . . . . . . . . . . . 19 8.2 Deleting Symbols . . . . . . . . . . . . . . . . . . . . . 21 8.3 Entering Special Characters . . . . . . . . . . . . . . . 21 8.4 Running UCL+ Directly . . . . . . . . . . . . . . . . . . 22 8.5 Advanced Techniques . . . . . . . . . . . . . . . . . . . 23 8.5.1 Using The Quote Character ("|") . . . . . . . . . . . . 23 8.5.2 Argument String Parsing ("^n") . . . . . . . . . . . . . 24 8.5.3 Specifying Default Strings . . . . . . . . . . . . . . . 25 9.0 "HARD-WIRED" COMMANDS . . . . . . . . . . . . . . . . . . 27 9.1 CHAIN Command . . . . . . . . . . . . . . . . . . . . . . 27 Page iii 9.2 DISPLAY Command . . . . . . . . . . . . . . . . . . . . . 28 9.3 ERASE Command . . . . . . . . . . . . . . . . . . . . . . 29 9.4 LIST Command . . . . . . . . . . . . . . . . . . . . . . . 29 9.5 NOSL/SLON Command . . . . . . . . . . . . . . . . . . . . 31 9.6 PASS_ON Command . . . . . . . . . . . . . . . . . . . . . 31 9.7 PATH Command . . . . . . . . . . . . . . . . . . . . . . . 32 9.8 PROMPT Command . . . . . . . . . . . . . . . . . . . . . . 32 9.9 RECALL Command . . . . . . . . . . . . . . . . . . . . . . 33 9.10 RELOAD command . . . . . . . . . . . . . . . . . . . . . 33 9.11 STORE Command . . . . . . . . . . . . . . . . . . . . . . 34 9.12 UCI_MODE Command . . . . . . . . . . . . . . . . . . . . 34 10.0 CI HANDLER . . . . . . . . . . . . . . . . . . . . . . . 36 11.0 ERROR MESSAGES . . . . . . . . . . . . . . . . . . . . . 38 11.1 UCL+ "Warning" Messages (?UCL-W-...) . . . . . . . . . . 38 11.2 UCL+ "Fatal" Messages (?UCL-F-...) . . . . . . . . . . . 38 11.3 Global Region Loader Errors (?UCLGRL-F-...) . . . . . . . 42 11.4 CI Handler Errors (?CI-...) . . . . . . . . . . . . . . . 42 12.0 EXAMPLES . . . . . . . . . . . . . . . . . . . . . . . . 44 13.0 V7 RELEASE NOTES . . . . . . . . . . . . . . . . . . . . 45 14.0 APPLICATION NOTES . . . . . . . . . . . . . . . . . . . . 48 14.1 Executing Command/Control Files "By-Name" . . . . . . . . 48 14.2 Sending Escape Sequences To The Printer . . . . . . . . . 48 14.3 Moving From UCL+ V6x To UCL+ V7.xx . . . . . . . . . . . 49 14.4 Moving From UCL+ V6x Or V7.xx To UCL+ (XM) V7.xx . . . . 50 14.5 Disabling Argument Parsing . . . . . . . . . . . . . . . 50 14.6 Hints and Kinks: UCF, UCI, And SET UCL FIRST . . . . . . 51 14.6.1 Interception Of Monitor Commands . . . . . . . . . . . 51 14.6.2 Improper Expansion Of Monitor Commands . . . . . . . . 52 14.6.3 Single Key Commands . . . . . . . . . . . . . . . . . . 52 14.7 UCL+ Assembly Conditionals . . . . . . . . . . . . . . . 52 14.8 Modifying RT-11 To Change The UCL/UCF Device/File Name . . . . . . . . . . . . . . . . . . . . . . . . . . 53 14.9 Modifying TSX-Plus To Change The UCL/UCI Defaults . . . . 55 14.10 Controlling Command Line Factoring . . . . . . . . . . . 55 14.11 Patching UCL+ For RT-11 V5.1 . . . . . . . . . . . . . . 57 14.12 Implementing The CD And RNO Commands . . . . . . . . . . 58 15.0 REPORTING PROBLEMS AND SUGGESTIONS . . . . . . . . . . . 59 16.0 WISH LIST . . . . . . . . . . . . . . . . . . . . . . . . 60 17.0 UCL+ COMMAND AND SYNTAX SUMMARY . . . . . . . . . . . . . 61 UCL+ -- User Command Linkage Program - V07.55b Page 1 Spring 1987 DECUS Release 1.0 ACKNOWLEDGEMENTS Throughout this document, reference is made to the RT-11 and TSX-Plus operating systems. RT-11 is a product of Digital Equip- ment Corporation, Maynard, MA; TSX-Plus is a product of S & H Computer Systems, Nashville, TN. The "^0" construct and the facility for entering octal character codes were added at the suggestion of C. E. Chew of Australia -- thus ending an unprecedented four months of stability for the UCL+ package. The idea of adding a provision for specifying default argument strings in symbol definitions came from Rally Barnard, Albu- querque, NM. The field testing for this version was performed by Rally Barnard (when he wasn't busy suggesting changes), John Crowell, and my- self (when I wasn't busy making changes). 2.0 IMPORTANT NOTICES RT-11 V5.1 USERS ________________ IF YOU ARE GOING TO USE THIS VERSION OF UCL+ UNDER AN RT-11 V5.1 MONITOR (OR EQUIVALENT RTEM-11 MONITOR), YOU MUST APPLY THE PATCH IN SECTION 14.11 FOR UCL+ TO WORK PROPERLY (IT'S NOT MY FAULT -- IT'S DEC'S FAULT). V07.54 OR EARLIER UCL+ USERS ____________________________ THE "CD" AND "RNO" COMMANDS ARE NO LONGER INCLUDED IN THE DISTRI- BUTED UCL+ PROGRAM. "CD" CAN NOW BE DEFINED AS A SYMBOL, AS CAN A BASE-LINE "RNO" COMMAND. SEE THE APPLICATION NOTE, SECTION 14.12, FOR DETAILS. THE STANDARD, HARD-WIRED "RNO" COMMAND IS ALSO AVAILABLE AS A CONDITIONAL ASSEMBLY (SEE SECTION 14.7). 3.0 BEFORE YOU GET STARTED Before you start using UCL+, there are a few things that you should keep in mind. o You don't have to get fancy. With a couple of fairly minor exceptions, you can just use UCL+ as a direct replacement for your distributed UCL. Try the sneaky stuff once you get accustomed to the basic facilities. o If you intend to use the extended features, particularly UCF or UCI_MODE, make sure you read the available UCL+ -- User Command Linkage Program - V07.55b Page 2 Spring 1987 DECUS Release documentation. Note that there are a number of goodies contained in the application notes (section 14.0) at the end of this manual. o READ THE INSTALLATION INSTRUCTIONS (section 6.0) for your particular environment. o RTEM users can assume that the material concerning RT-11 also applies to the RTEM equivalent environment. The significant exceptions are the installation procedures and the use of the UCF facility. 4.0 ABOUT THIS DOCUMENT A fair amount of effort has gone into this manual to give reason- ably comprehensive coverage of the contents of the UCL+ distribu- tion kit. It does not, however, attempt to include material already available in the relevant operating system documentation, nor is there extensive coverage of internals. Where examples are felt to be necessary, the following conven- tions are followed: o examples, unless otherwise noted, are for RT-11 V5.0; no "factoring" is used o in most examples, operator input is underlined o all visible lines of input are assumed to be terminated with a carriage return o "non-printing" characters and control characters are identified by an abbreviation enclosed by angle brackets ("<>"); e.g., - = carriage return (CR) - = escape (ESC) - = control-C (ETX) - = control-Y (EM) Note, however, that instances of digits enclosed in an- gle brackets (e.g.,"<003>") are a part of the normal UCL+ symbol definition syntax. o examples and procedure descriptions, except where noted, assume that all necessary files are on the default device (DK:) UCL+ -- User Command Linkage Program - V07.55b Page 3 Spring 1987 DECUS Release 5.0 INTRODUCTION UCL+ is a user command linkage program for use with RT-11 V5 or later, RTEM V2.0 or later, and TSX-Plus V4.1 or later monitors. It contains full support for the user command related features of these operating systems. These include: o UCL - User Command Linkage (RT-11, RTEM, and TSX-Plus) o UCI - User Command Interpreter (TSX-Plus, starting with V5.0) o UCF - User Commands First (RT-11, starting with V5.2) In general, UCL+ can be used as a direct replacement for the "UCL's" distributed with these operating systems. There are some relatively minor incompatibilities between UCL+ and the distri- buted versions, as well as a substantial number of enhancements. The remainder of this section summarizes these differences. 5.1 UCL+ Differences UCL+ is upward compatible with the UCL program distributed with RT-11 (and the TSX-Plus TSXUCL program) with the following excep- tions. o UCL+ accepts the "VMS-like" symbol definition syntax used by DEC's UCL, but it ignores it. Instead, the number of characters that must be typed to specify a command or symbol unambiguously is a function of con- text. E.g., if you have defined two symbols starting with "S", "SUPPER" and "SUPER", you must type four characters to distinguish between them. However, if they are "SIPPER" and "SUPER", only two characters are necessary. o UCL+ currently allows symbol names of no more than six characters. If you use a longer name in a definition, UCL+ will truncate it to six characters and issue a warning message to that effect. o UCL+ is different from the TSX-Plus TSXUCL program in that all commands and symbols are "global", rather than local to a specific user. In addition, UCL+ does not "forget" symbol definitions after a user logs off. UCL+ -- User Command Linkage Program - V07.55b Page 4 Spring 1987 DECUS Release 5.2 UCL+ Enhancements UCL+ contains a number of extensions to the distributed RT-11 and TSX-Plus UCL programs. The following list is a summary of the most important ones. Refer to the relevant sections of this do- cument for further detail. o UCL+ is optimized to minimize disk access. The symbol definitions are contained in internal tables rather than a separate data file and an "execute-immediate" mode is available for commands that are defined in terms of other UCL commands. o More than one symbol definition can be deleted in a sin- gle command line via the ERASE command. All current symbol definitions can be removed with ERASE *. o You can chain to additional "UCL's". o A "run-by-name path" can be defined which extends the monitor's "run-from-SY:" default. o You can STORE/RECALL the program settings to/from a separate file. You can do this in either "binary" or "journal" mode. Journal files can be edited. o A PASS_ON command is included that allows you to force UCL+ to "pass-on" a given command string to the next program in the chain (the default mode) or to a program that you specify. o Symbol expansions can be DISPLAYed with or without exe- cution. The DISPLAY command can also be used to output ASCII strings to the console or printer (handy for sneaky escape sequences). o If you run it directly, UCL+ will accept lower-case input and most control characters. o You may, in addition to the symbol definitions, list other program parameters as well. List output may be directed to devices/files other than the console. o UCL+ can be employed, via the UCI_MODE command, as a "User Command Interpreter" (UCI). This functionality was added with UCL+ V7 to take advantage of the UCI facility in TSX-Plus. o You may dynamically redefine the prompt string issued by UCL+. UCL+ -- User Command Linkage Program - V07.55b Page 5 Spring 1987 DECUS Release o A "quoting" facility is available to override the effect of "operator" characters. o In order to allow more complex command definitions, UCL+ supports the parsing of argument strings into as many as nine sub-strings. o You may define default values for argument strings and argument sub-strings. o You can enter and use virtually any character, including eight-bit and control characters, in a symbol defini- tion. o If you have an RT-11 V5.2 or later monitor, you can take advantage of some additional features: - A CI "handleroid" is included which allows you to control and display the action of the various Com- mand Language Interpreters (CLI's). For example, SET CI UCF turns on the User Commands First (UCF) facility. - A special version of UCL+ is available for the XM monitor. Almost the entire program is continuously resident in a global region in extended memory. It is very fast, and uses only 512 (decimal) words of low memory. UCL+ -- User Command Linkage Program - V07.55b Page 6 Spring 1987 DECUS Release 6.0 INSTALLATION This section of the manual contains information on the installa- tion of the major components of the UCL+ distribution. These are: o UCL.SAV - the "vanilla" UCL+ program (section 6.1) o UCLXM.SAV - a special XM version of UCL+ (section 6.2) o CI.SYS - the Command Line Interpreter handler (section 6.3) o UCLHLP.TXT - the help text necessary to build a UCL+ help program (section 6.4) As with all sections of this document, a basic familiarity with RT-11 and, if applicable, TSX-Plus is assumed. In all of the examples in this section, the UCL+ distribution is assumed to be on the default device, DK:. Examples, unless otherwise noted, will work on RT-11 V5.0 or later systems and/or the functionally equivalent version of TSX-Plus or RTEM. TSX-Plus users should also note that the installation procedures for TSX assume that the user has sufficient privilege to execute them -- i.e., installation will be probably be accomplished by the system manager. The examples also assume that you are going to use the default program names when you install the various components. There are cases where this may not be true (for example, if you use both the SJ and XM RT-11 monitors). See the application notes, sec- tions 14.8 and 14.9, for information on changing these defaults. If you are converting from any version of UCL+ prior to V07.50, you should also read section 8.5 and the application note in sec- tion 14.5. Please remember that reasonable attempts are made to keep succes- sive versions of UCL+ upward compatible, but there is no guarantee that they are downward compatible. Thus, V7.55 will accept V7.54 journal files, but it is very unlikely that things will work the other way around. V07.54 OR EARLIER UCL+ USERS The "CD" and "RNO" commands are no longer included in the distributed UCL+ program. "CD" can now be defined as a symbol, as can a base-line "RNO" command. See the application note, section 14.12, for details. The UCL+ -- User Command Linkage Program - V07.55b Page 7 Spring 1987 DECUS Release standard, hard-wired "RNO" command is also available as a conditional assembly (see section 14.7). 6.1 Installing UCL.SAV UCL.SAV is the "vanilla" UCL+ program. It will run under ver- sions of RT-11 beginning with V5.0 (and the equivalent RTEM releases) and versions of TSX-Plus starting with V4.1. As it does a context check on start-up, it is not necessary to generate a special version for either operating system. It is, in fact (and by design), possible to use the same copy of UCL+ in both environments. The installation procedure may differ, however, in some cases. 6.1.1 Installing UCL.SAV On RT-11 Systems - For all versions of RT-11, UCL+ serves as a direct replacement for the distributed UCL program (note that the V5.0 distribution contained no UCL program). For those versions of RT-11 supporting User Commands First (UCF), UCL+ can be used as a UCF also (except RTEM). 6.1.1.1 Installation As A UCL (UCL.SAV) - If you are already using a previous version of UCL+, you should first save your cur- rent symbol/status data. For example, .STORE SY:CURENT _______________ To install UCL.SAV, just copy it to the system device: .COPY UCL.SAV SY:UCL.SAV _______________________ If you are not a previous UCL+ user, you're done. Otherwise, the next step depends on whether your old UCL+ is V6x or V7.xx. If it is V6x, apply the patch described in the application notes (section 14.3). If it is V7.xx, you can skip the patch and type .RECALL SY:CURENT ________________ to load the symbol/status data into your new copy of UCL+. Note that the above procedure is the same for TSX-Plus V4.1 users. UCL+ -- User Command Linkage Program - V07.55b Page 8 Spring 1987 DECUS Release 6.1.1.2 Installation As A UCF (UCF.SAV) - Beginning with V5.2, RT-11 supports User Commands First (UCF) as well as UCL. If you wish to use UCL+ as a UCF, you need only make a copy with the appropriate name and turn on UCF support in the monitor. Unless you are doing something sneaky, the installation procedure is as follows (note that this command sequence is for RT-11 V5.2): .copy ucl.sav sy:ucf.sav _______________________ .r ucf _____ UCL> prompt "ucf> " ______________ ucf> ________ The easiest way to invoke UCF processing is via the CI handler. I.e., .set ci ucf,show _______________ ?CI-I-CLI's enabled: UCF DCL CCL UCL When UCL+ runs as UCF, it automatically detects this condition, and processes commands appropriately. 6.1.2 Installing UCL.SAV On TSX-Plus Systems - If you are run- ning TSX-Plus V4.1, installation is the same as it is for RT-11 (section 6.1.1). If you are running V5.0 or later, the procedure is somewhat different. Note that you should make sure that UCL support is enabled when you execute your initial TSGEN. Also note that TSX-Plus users must have read/write access to the UCL+ program if they are to be able to define or erase symbols. The easiest way to accomplish this is to include an ACCESS com- mand in the user's logon command file. For example: ACCESS SY:TSXUCL.SAV 6.1.2.1 Installation As A UCL (TSXUCL.SAV) - If you are already using a previous version of UCL+, you should first save your cur- rent symbol/status data. For example, .STORE SY:CURENT _______________ To install UCL.SAV, just copy it to the system device. Note that the default TSX-Plus name for UCL is TSXUCL.SAV. .COPY UCL.SAV SY:TSXUCL.SAV __________________________ If you are not a previous UCL+ user, you're done, and you can proceed to define the symbols that you intend to use. Otherwise, UCL+ -- User Command Linkage Program - V07.55b Page 9 Spring 1987 DECUS Release the next step depends on whether your old UCL+ is V6x or V7.xx. If it is V6x, apply the patch described in the application notes (section 14.3). If it is V7.xx, you can skip the patch and type .RECALL SY:CURENT ________________ to load the symbol/status data into your new copy of UCL+. 6.1.2.2 Installation As A UCI (UKMON.SAV) - UCL+ can also be used on a TSX-Plus V5.0 or later system as a User Command Inter- preter (UCI). The following example illustrates a typical in- stallation with the default UCI name of UKMON.SAV. Note that the command prompt is changed during this procedure to help distin- guish the "UCI" copy of UCL+ from other copies that might exist on the same system as "UCL's". .COPY UCL.SAV SY:UKMON.SAV _________________________ .R UKMON _______ UCL> uci "ukmon> " _____________ ukmon> ________ You would invoke UKMON.SAV as a UCI by typing .SET KMON UCI ____________ 6.2 Installing UCLXM.SAV UCLXM.SAV is a special version of UCL+ for use with the extended memory (XM) monitor on systems running RT-11 V5.2 or later. It can also be used under TSX-Plus monitors that are compatible with RT-11 V5.2 (TSX-Plus V6.0 or later). UCLXM has a minimal low memory presence -- typically, about 512 (decimal) words. The remainder of the program, about 10K words, resides in a global region in extended memory. In the RT-11 environment, UCLXM is significantly faster than the "vanilla" UCL+ due to the fact that all but a two-block "stub" is permanently memory resident. UCLXM is a direct, functional replacement for the distributed UCL program. As with the "vanilla" UCL+ program, UCLXM can also be used as a UCF program. Under TSX-Plus, speed improvement resulting from the use of UCLXM instead of the regular UCL+ program will depend on such factors as the amount of memory available for cache, and the amount of swapping normally seen on the system. It is interesting to note, however, that the "low memory" image of UCLXM is less than 512 bytes (a user job size of 8kb under a V6.1 monitor). This is due to the fact that the bulk of the program (20kb) resides in a shared global region. If multiple copies of UCL+ are running UCL+ -- User Command Linkage Program - V07.55b Page 10 Spring 1987 DECUS Release simultaneously, they are all sharing the same global region and, thus, sharing most of their run-time code. WARNING!!! Do not attempt to run UCLXM.SAV under a monitor that is not compatible with RT-11 V5.2 or later. The results are unpredictable -- your system may crash. 6.2.1 Installing UCLXM.SAV On RT-11 Systems - Installing the XM version of UCL+ under RT-11 is a reasonably straightforward pro- cess, although there may be some special considerations if you are "porting" from an earlier, non-XM version of UCL+. All examples in this section are for an RT-11 V5.2 monitor. 6.2.1.1 Installation As A UCL (UCL.SAV) - If you are already using a previous version of UCL+, you should first save your cur- rent symbol/status data. For example, .store sy:curent _______________ If your previous version of UCL+ was also the XM version, you should REMOVE the global region. .remove ucl __________ To install UCLXM.SAV, copy it to the system device as UCL.SAV. .copy uclxm.sav sy:ucl.sav _________________________ If you are not a previous UCL+ user, you're done, and you can proceed to define the symbols that you intend to use. Otherwise, the next step depends on whether your old UCL+ is an XM version or a non-XM version. If it is a non-XM version of UCL+, follow the procedure described in the application notes (section 14.4) to transport your symbol definitions. If your previous UCL+ is an XM version, you can just type .recall sy:curent ________________ to load the symbol/status data into your new copy of UCL+. Finally, it is a good idea to run UCL and change the command prompt. .r ucl _____ UCL+ -- User Command Linkage Program - V07.55b Page 11 Spring 1987 DECUS Release UCL> prompt "uclxm> " ________________ uclxm> ________ 6.2.1.2 Installation As A UCF (UCF.SAV) - Beginning with V5.2, RT-11 supports User Commands First (UCF) as well as UCL. If you wish to use UCL+ as a UCF, you need to make a copy with the appropriate name and turn on UCF support in the monitor. Unless you plan to do something sneaky (like letting UCL and UCF share the same global region -- risky!), you must also patch your UCF so that it will establish it's own, unique global region in ex- tended memory. The installation procedure is as follows. Remove the UCF global region and create a new copy of UCF.SAV on SY:. .remove ucf __________ .copy uclxm.sav sy:ucf.sav _________________________ Next, apply the customization patch to cause UCF.SAV to use a unique global region. .sipp sy:ucf.sav/a _________________ Base? _____ Offset? 1024 ____ Base Offset Old New? 000000 001024 101704 ;R __ 000000 001024 ;RUCF _____ 000000 001026 < > ________ Following this, it is recommended that you run UCF and change the command prompt. .r ucf _____ UCL> prompt "ucfxm> " ________________ ucfxm> ________ The easiest way to invoke UCF processing is via the CI handler. I.e., .set ci ucf,show _______________ ?CI-I-CLI's enabled: UCF DCL CCL UCL When UCL+ runs as UCF, it automatically detects this condition, and processes commands appropriately. UCL+ -- User Command Linkage Program - V07.55b Page 12 Spring 1987 DECUS Release 6.2.2 Installing UCLXM.SAV On TSX-Plus Systems - Installing the XM version of UCL+ under TSX-Plus is similar to the RT-11 pro- cedure. As with RT-11, there may be some special considerations if you are "porting" from an earlier, non-XM version of UCL+. In addition, the XM version of UCL+ must be able to use TSX-Plus global region support. This can be accomplished by editing TSGEN.MAC prior to building TSX-Plus, or through the use of the INSTALL command. PRO/TSX-Plus users must use the INSTALL com- mand, since TSGEN.MAC is not included in the PRO distribution. For a V6.1 monitor, the command is as follows install add sy:tsxucl.sav/priv=(nodebug,sysgbl) The best place to put this command is in a detached job command file that is executed when TSX-Plus is booted. Also note that TSX-Plus users must have read/write access to the UCL+ program if they are to be able to define or erase symbols. The easiest way to accomplish this is to include an ACCESS com- mand in the user's logon command file. For example: ACCESS SY:TSXUCL.SAV All examples in this section are for a TSX-Plus V6.0 monitor. 6.2.2.1 Installation As A UCL (TSXUCL.SAV) - If you are already using a previous version of UCL+, you should first save your cur- rent symbol/status data. For example, .store sy:curent _______________ If your previous version of UCL+ was also the XM version, you should REMOVE the global region. .remove ucl __________ To install UCLXM.SAV, copy it to the system device as TSXUCL.SAV. .copy uclxm.sav sy:tsxucl.sav ____________________________ If you are not a previous UCL+ user, you're done, and you can proceed to define the symbols that you intend to use. Otherwise, the next step depends on whether your old UCL+ is an XM version or a non-XM version. If it is a non-XM version of UCL+, follow the procedure described in the application notes (section 14.4) to transport your symbol definitions. If your previous UCL+ is an XM version, you can just type .recall sy:curent ________________ UCL+ -- User Command Linkage Program - V07.55b Page 13 Spring 1987 DECUS Release to load the symbol/status data into your new copy of UCL+. Finally, it is a good idea to run TSXUCL and change the command prompt. .r tsxucl ________ UCL> prompt "tsxucl> " _________________ tsxucl> ________ 6.2.2.2 Installation As A UCI (UKMON.SAV) - Under TSX-Plus, UCL+ can also be used as a User Command Interpreter (UCI). The following example illustrates a typical installation with the default UCI name of UKMON.SAV. Note that the name of the global region used by UKMON.SAV is changed from the default value of "UCL". Note also that the command prompt is changed during this procedure to help distinguish the "UCI" copy of UCL+ from other copies that might exist on the same system as "UCL's". .copy uclxm.sav sy:ukmon.sav ___________________________ .sipp sy:ukmon.sav/a ___________________ Base? _____ Offset? 1024 ____ Base Offset Old New? 000000 001024 101704 ;R __ 000000 001024 ;RUKM _____ 000000 001026 < > ;RON ____ 000000 001030 < FP> ________ .r ukmon _______ UCL> uci "ukmon> " _____________ ukmon> ________ You would invoke UKMON.SAV as a UCI by typing .set kmon uci ____________ 6.3 Installing The CI Handler The CI (Command line Interpreter) handler can be used on RT-11 V5.2 or later systems to control the action of the various com- mand line interpreters (CLI's). It contains no executable ______________ handler code; all it does is execute SET commands. Installation ____________ is, therefore, very simple. Just copy CI.SYS to your system device, giving it the name appropriate to your particular moni- tor. For non-XM versions of the RT-11 monitor: .copy/sys ci.sys sy: ___________________ UCL+ -- User Command Linkage Program - V07.55b Page 14 Spring 1987 DECUS Release For the XM monitor: .copy/sys ci.sys sy:cix.sys __________________________ See section 10.0 for more information in the CI handler. 6.4 Installing UCL+ HELP The UCL+ distribution includes a help-text file named UCLHLP.TXT. You can use this file to set up on-line help text for UCL+ com- mands in one of two ways: o The most general, and most tedious, method is to edit the HELP macros contained in UCLHLP.TXT into HELP.TXT and then rebuild the HELP program. This technique is described in the RT-11 Installation Guide. If you are using version 5.1 or later of RT-11, you will have to use SPLIT.SAV to create HELP.EXE and HELP.TXT (see file UNSUP.TXT on the RT-11 distribution kit). Note that both the RT-11 and UCL+ help text files contain a macro named "HELP." You should retain the RT-11 version of this macro. o The second approach involves the creation of a separate HELP program for UCL+. In this case, you create a macro library from UCLHLP.TXT, build a secondary HELP program, and define a symbol (I like to use HLP) to invoke it. The following example assumes that you are using RT V5.1. All required files are assumed to be on the default device (DK:). .SPLIT HELP.EXE=HELP.SAV/B:7 ___________________________ .LIB/MAC UCLHLP UCLHLP.TXT _________________________ .COP HELP.EXE+UCLHLP.MLB UCLHLP.SAV __________________________________ .COP UCLHLP.SAV SY: __________________ .HLP==R UCLHLP\^ _______________ NOTE If you are using RT-11 V5.2, the SPLIT boundaries are different for HELP.SAV. In the above example, the value for the "/B" switch in the first line becomes 10 (octal) instead of 7. This boundary may, of course, change again in later versions of RT-11. UCL+ -- User Command Linkage Program - V07.55b Page 15 Spring 1987 DECUS Release 6.5 Installing The UCL+ Distribution Under RTEM The following special considerations and restrictions apply to using the UCL+ package under the RT-11 Emulator (RTEM): o The UCL program (UCL.SAV) should be placed in your "private" area. The distributed UCL program resides in the read-only portion of the virtual system device. The system manager should either rename the distributed UCL program (if there is one) or delete it. Otherwise, the installation procedure is the same as for RT-11 systems (section 6.1.1.1). o If it is to be used, the CI handler should be placed in the "mark zone" portion of the virtual system device. This is normally done by the system manager. Section 6.3 contains further information on installing this handler. o Later versions of RTEM use the UCF facility to implement specialized commands for this environment. Thus, the UCF facility is not available to RTEM users. o The UCL+ help facility is normally installed in the "shared" area of the virtual system device. See section 6.4 for further information on installing the UCL+ help text. In summary: the UCL+ program is placed in the user's "private" area; the help program and the CI handler are installed by the system manager in the "shared" area, with the handler residing in the "mark zone." UCL+ -- User Command Linkage Program - V07.55b Page 16 Spring 1987 DECUS Release 7.0 HOW IT WORKS First, read the appropriate sections of the RT-11 Software Sup- port Manual (for version 5.0, this is sections 2.2.4.1 and 2.2.4.2 -- pages 2-39 through 2-41). If you are running RT-11 version 5.2 or later, and you are interested in User Commands First (UCF), read that stuff too. TSX-Plus users should check out the additional material in the TSX manuals on User Command Interpreters (UCI's) and the UCL SET commands. OK, now that you've done your homework (and saved me a lot of typing)... 7.1 RT-11 Command Processing With UCL Support As you will recall, if you are using a version of RT-11 that is sysgened to support User Command Linkage, RT goes through a cer- tain logical sequence to evaluate a command line. First, it looks at the first word to see if this a valid RT-11 command. If not, it looks on SY: for a program to run that has the same name as this first word (let's call it "word1"). If "SY:word1.SAV" is not found, it runs SY:UCL.SAV (if it exists) and passes the en- tire command line to UCL. UCL+ understands two types of commands: "hard-wired" commands (LIST or RECALL, for example), which are "built in" to UCL+ (hereafter referred to simply as "commands"), and "symbols", which are commands that you define (or modify or delete) from the console. When UCL+ receives a command line, it first checks to see if word1 is a valid command and, if so, calls the appropriate routine. If the command check fails, UCL+ looks for a match against the currently defined symbols and, if successful, invokes the symbol processing stuff. Next, if the PATH command is turned on, UCL+ uses the "run-by-name" path to look for a program named "dev:word1.SAV" (the default is dev=DK) and, if it finds it, runs it by passing the command "RUN command-string" to RT-11. Finally, if all else fails, UCL+ exits with a "?UCL-F-Invalid command" error message or, if the CHAIN command is in effect, UCL+ chains to the specified program, and passes it the original command line. UCL+ -- User Command Linkage Program - V07.55b Page 17 Spring 1987 DECUS Release In summary then, when you enter a command: o RT-11 tries to execute it, then o RT-11 tries to run it off SY:, then o UCL+ tries to execute it as a command, then o UCL+ tries to execute it as a symbol, then o UCL+ tries to "run-by-name", then o you either get a nasty comment or UCL+ chains to another program. 7.2 RT-11 Command Processing With UCF Support If your RT-11 is version 5.2 or later, you have support available for User Commands First (UCF) processing. If you turn UCF sup- port on (this can be done with the CI handler; see section 10.0), RT-11 will collect your command line and, after checking for IND syntax, pass it directly to a program named SY:UCF.SAV. You can use UCL+ as a "UCF" by making a copy of it named UCF.SAV. UCL+ will now be intercepting commands before the monitor gets ______ them! This can get really tricky because UCF can, in effect, override normal RT-11 commands. The implications of all this can get pretty complicated and are beyond the scope of this manual; read the RT-11 documentation and release notes for details. The main thing to remember is that UCL+ processes unrecognized commands differently when it is running as UCF than it does when it is running as UCL. As UCF, it passes unknown commands to the monitor; as UCL it issues an error message. This makes sense, because UCF gets commands first while UCL gets them last. The simplest situation, with UCF support turned on and UCL turned off, causes command lines to be processed in the following sequence: o UCF tries to execute it as a command, then o UCF tries to execute it as a symbol, then o UCF tries to "run-by-name", then o RT-11 tries to execute it, then o RT-11 tries to run it off SY:, then o you get "?KMON-F-Invalid command" 7.3 TSX-Plus Command Processing If you are using UCL+ with TSX-Plus version 4.1, things work more or less the same as they do with RT-11 (see section 7.1): TSX passes the command string to UCL+ only if KMON fails to recognize it. Things get a little more complicated, however, if you are running under a V5.0 or later monitor. UCL+ -- User Command Linkage Program - V07.55b Page 18 Spring 1987 DECUS Release o TSX-Plus V5.0 looks for a "UCL" named SY:TSXUCL.SAV. Version 4.1 uses the same name as RT-11 (SY:UCL.SAV). o Version 5 implements a UCL "SET option". SET UCL NONE turns off user command linkage (now who would want to do that?). SET UCL LAST causes command processing to work like it did under V4.1 (except you get a "?KMON-F-Unrecognizable command" error message instead of "?UCL-F-Invalid command"). SET UCL MIDDLE allows TSXUCL to examine the command string after it is in- spected for a match against the monitor commands, but before command file/run-by-name processing. SET UCL FIRST causes TSXUCL to be invoked prior to all KMON pro- cessing (i.e., it works like the RT-11 UCF facility -- see section 7.2). Note that MIDDLE will cause UCL+'s run-by-name path to take priority over TSX's; FIRST will, in addition, give priority to UCL+ commands over KMON commands (i.e., you can replace monitor commands with UCL+ commands). o Unless UCL is set FIRST, the monitor DISPLAY command will preempt the UCL+ DISPLAY command. This means that you will need to define a symbol in order to invoke the UCL+ DISPLAY command properly (for example, DSPLAY==_d). o UCL+ can also be used, under TSX, as a User Command In- terpreter (UCI). When UCI support is turned on (via the SET KMON UCI command), the UCI effectively replaces the ________ keyboard monitor (note that this is different from SET UCL FIRST where KMON collects the command, and then passes it to UCL). UCL+ can be used as a UCI by making a copy of it with the appropriate name (the default is SY:UKMON.SAV) and utilizing the UCL+ UCI_MODE command. See the TSX-Plus user documentation for further information. UCL+ -- User Command Linkage Program - V07.55b Page 19 Spring 1987 DECUS Release 8.0 SYMBOLS This is probably the most important section of this manual. The main reason for using UCL+ (unless you just don't like to have a lot of empty space on your disk) is that it gives you the ability dynamically to define your own commands. For the pur- poses of this document, these user-defined commands will be referred to as "symbols". The following sections present a sum- mary of how to define and manipulate these symbols. 8.1 Defining Symbols Symbols are defined by entering a "symbol definition string" in the format symbol==definition where "symbol" is the command you are defining (6 characters max.), "==" is the symbol definition operator, and "definition" is the character-string (72 characters max.) that will govern the way that the symbol is replaced (expanded) when it is inter- preted. NOTE DEC's UCL uses a more "VMS-like" structure for defining symbols (possible example: REB*OOT:==BOOT DL0: vs. REBOOT==BOOT DL0:). UCL+ will accept the DEC format as well as the "normal" one. In the simplest case, suppose you define the symbol "BUILD" by entering BUILD==EX/MAC/NORUN If you subsequently enter BUILD MYFILE this line is interpreted by UCL+ and passed back to RT-11 as EX/MAC/NORUN MYFILE You may also get multiple-line definitions via the backslash ("\") character. For example, the symbol "WHEN" defined as WHEN==DATE\TIME UCL+ -- User Command Linkage Program - V07.55b Page 20 Spring 1987 DECUS Release executes as if you had typed DATE TIME A "^" character or characters in the definition governs where the "argument-part" of the input command string is inserted when a symbol is expanded. Thus, BUILD==EX/MAC/NORUN and BUILD==EX/MAC/NORUN ^ are equivalent symbol definitions. The "^" operator is really handy when the "argument-part" is to be embedded in the middle of the expansion somewhere rather than tacked on the end. For example: VERSIO==RESORC SY:^.SAV/V If you type VERSION PIP this symbol will expand as RESORC SY:PIP.SAV/V Finally, you may precede the "definition-part" with an underscore character ("_"). This will cause UCL+ to process the symbol ex- pansion in "execute-immediate" mode. In other words, you are telling UCL+ that you are defining one symbol in terms of another symbol or hard-wired command. Thus, the expanded symbol is pro- cessed immediately by UCL+ rather than being passed on to RT-11 as a command string. This speeds up command execution substan- tially. For example, SAY==DISPLAY "^" (example 1) and SAY==_DISPLAY "^" (example 2) are equivalent definitions. If you type SAY HELLO both will expand (on the first pass through UCL+) as UCL+ -- User Command Linkage Program - V07.55b Page 21 Spring 1987 DECUS Release DISPLAY "HELLO" But, in the first instance, the UCL+ program will be invoked ___ twice: once to expand SAY HELLO and pass the string back to RT-11, and a second time to execute DISPLAY "HELLO". In the second example, UCL+ expands the command and then immediately ex- ecutes the resultant command string. Thus, example 2 executes much faster, especially on a floppy-based system, because UCL+ is only run once to process it, instead of twice. Note that you are restricted to using "_" with definitions that expand to a single line. A==_B\C\D will not work correctly (well, not in this version anyways). 8.2 Deleting Symbols Individual symbols can be deleted either by redefining them with a null definition or with the ERASE command. For example, sup- pose you have defined a symbol TEMP as TEMP==EDIT MYFILE.MAC\DELETE MYFILE.BAK You can delete this symbol by typing TEMP== (UCL+ will display the message "?UCL-W-Erased symbol TEMP") or you can type ERASE TEMP with the same effect. If you wish to delete more than one sym- bol, the ERASE command is more efficient (see section 9.3 for more details on the ERASE command). 8.3 Entering Special Characters There are a number of characters that cannot be typed directly. Examples of these "special" characters include control characters intercepted by RT-11 (control-O, control-S, etc.), and eight-bit codes recognized by some of the newer terminals and printers. If you need to include a character of this type in a symbol defini- tion, you can do so by entering its octal value in the form UCL+ -- User Command Linkage Program - V07.55b Page 22 Spring 1987 DECUS Release where "nnn" is an octal number of up to three digits. For example, to define a symbol, "BELL", which will ring the bell on the console: BELL==_D "<007> Actually, it is not necessary to enter all three digits; you may omit the leading zeros. Thus, the bell character could also be represented as "<07>" or "<7>". Note that UCL+ treats an invalid "" sequence as if it were just a normal string of characters. Thus, "<507>" would not be translated into a character because 507 is too big to be a one-byte value (the maximum value is 377 octal). Likewise, "<209>" would be ignored since 9 is an invalid octal digit. 8.4 Running UCL+ Directly You can also define (or erase) symbols by running UCL+ directly and proceeding as described above in response to the "UCL>" prompt. There is one significant difference, however: you can include almost any character that you wish in a symbol definition (upper/lower case, escape, etc.) as long as RT-11 does not inter- cept it for it's own purposes (you couldn't use control-O, for example). In some cases, this is an easier way to enter a "spe- cial" character than the method described in the previous section (8.3). This is particularly true if you are using an earlier version of RT-11 that does not allow the entry of lower case characters at the monitor level. For instance, the escape sequence [H[J can be used to clear the screen on a VT100-style terminal. The following dialogue would define a symbol "CLS" to accomplish this (items enclosed in angle brackets represent single control characters; e.g., ): .UCL UCL> cls==_d "[H[J UCL> Note that, if the single-line editor was enabled, you would have to turn it off before defining the above symbol. The applications notes, particularly the section on defining sym- bols that invoke command files and IND control files (section 14.1) and the discussion of command line factoring (section UCL+ -- User Command Linkage Program - V07.55b Page 23 Spring 1987 DECUS Release 14.10), contain further examples of when it is useful to run UCL+ directly. 8.5 Advanced Techniques This section contains a description of the "quoting", "argument parsing", and "default string" features of UCL+. The first two were added to UCL+ beginning with V07.50; the last appeared in V07.55. These features are very useful, but they should be used with a little care and forethought. In particular, it is impor- tant to understand how they work (and, perhaps, experiment a bit) when defining UCL+ symbols that have nested expansions. 8.5.1 Using The Quote Character ("|") - Quoting is primarily used to force UCL+ to treat an operator (the "^" and "\" characters, for example) as normal text. This is done by pre- ceeding the character to be quoted by the "|" operator. The most common application is to allow characters to be displayed as part of a text string that would normally be interpreted as operators. For example, the symbol definition: EXAMPL==_D "|\" Typing EXAMPL would print a "\" at the console. As a more useful illustration, suppose you wanted to send a line of ReGIS graphics instructions to a VT241 (to change the screen colors, perhaps). You will need to preceed the graphics output with the text "Pp" and follow it with "\" ("" in- dicates the escape character). Under TSX-Plus, the following symbol definition will do the trick (note the use of the quote character to display the "\"). regis==disp "Pp"\disp "^"\disp "|\" An alternate method is to enter the octal code for the escape character rather than typing it in directly (escape=33 octal): regis==disp "<33>Pp"\disp "^"\disp "<33>|\" Refer to section 14.10 of the "Application Notes" for a discus- sion on implementing this symbol under RT-11. It is good policy, by the way, to use the quote character only when it is required. The other thing to watch out for is nested command expansions (a symbol defined in terms of another symbol defined in terms of another...). Consider, for example, the problem of defining a UCL+ -- User Command Linkage Program - V07.55b Page 24 Spring 1987 DECUS Release symbol to display the quote character itself. The actual symbol definition is EXAMPL==_D "||||" Why four quote characters? Because this definition results in ____ two "quoting scans": once when the EXAMPL symbol is processed and expanded, and once when the resultant D (DISPLAY) command is scanned. In other words, the keyboard command to print a "|" is DISPLAY "||" In order to define a symbol whose expansion is the above command, you must quote both quotes! (Typing DISPLAY "|" prints the second quotation mark, not a "|" -- think about it.) Most situations are not as messy as this one. The best rule of thumb is to "work from the bottom up." 8.5.2 Argument String Parsing ("^n") - Argument string parsing allows you to extend the function of the "^" operator. UCL+ can break up the "argument part" of a command string into as many as nine sub-strings. These sub-strings are specified by following the "^" operator with a number from "1" to "9." UCL+ assumes that the sub-strings are separated by spaces. For example, the phrase "this is a test" consists of four sub-strings. As a simple il- lustration of how this works in practice, consider the following symbol definition. EXAMPL==_D "^2 ^1" If you type EXAMPL YOU THERE UCL+ will, in turn, display THERE YOU A more useful example is PMOVE -- a symbol for "moving" protected files: PMOVE==UNPRO/SYS ^1\COP/SYS/DEL/PROT ^ This command will copy a protected file from one place to another, and then delete the original copy of the file. By the way, once you have PMOVE defined, you can define a sneaky symbol that deletes protected files: PDELET==_PMOVE ^ NL: UCL+ -- User Command Linkage Program - V07.55b Page 25 Spring 1987 DECUS Release The combination "^0" has a special meaning. This construct will supply the number of sub-strings (up to a maximum of nine) that occur within a given argument string. For example, consider the following symbol definition: EXAMPL==_D ""^" HAS ^0 WORDS IN IT" If you type EXAMPL THIS IS A TEST UCL+ will print "THIS IS A TEST" HAS 4 WORDS IN IT The "^0" construct is most likely to be used when UCL+ builds a string to be passed to another program. This other program may wish to use the number of sub-strings as a first-line error check. Using argument parsing is not nearly as tricky as quoting (sec- tion 8.5.1, above), but there are a couple of basics that you must keep in mind. o The "^" operator, unmodified by a trailing numeric value, causes the entire argument string, including em- bedded spaces, to be inserted into the command expan- sion. An operator of the form "^n" inserts a sub-string without the "framing" spaces; i.e., the sub-string will never contain blanks. o Any construction of the form "^n" is treated as a pars- ing operator. However, the sequence "^|n" is not. In other words, in an instance where you need to disable parsing, quote the "n". 8.5.3 Specifying Default Strings - When you are defining a sym- bol, there may be instances where you wish to supply a default argument string or sub-string. This default string will be in- serted into the command expansion if the operator does not enter an argument string. Default strings are specified by enclosing the text in square brackets ("[]") immediately following the in- sertion operator ("^" or "^n" where "n" is a digit from 1 to 9). A simple and useful example of this technique is the "CD" com- mand. Prior to UCL+ V07.55, CD was a hard-wired command because it was too complex to define as a symbol. If you typed just "CD" with no argument, it expanded into the RT-11 command string "AS- SIGN SY DK." If you included the name of a device, it produced "ASSIGN device DK" (e.g., CD DY0 became ASSIGN DY0 DK). This can UCL+ -- User Command Linkage Program - V07.55b Page 26 Spring 1987 DECUS Release be a very handy command if, for example, you frequently bounce around between a number of logical devices. By taking advantage of the "default string" feature of UCL+, you can define the CD command as a symbol: CD==ASSIGN ^[SY] DK If you don't specify an argument string, the default string "SY" automatically will be inserted. Thus, "CD" becomes "ASSIGN SY DK", and "CD FOO" expands as "ASSIGN FOO DK." Default strings can also be used in conjunction with argument parsing. The following example defines an "RNO" command which invokes the RUNOFF program: RNO==R RUNOFF\^2[LP:]=^1\<003> If you type "RNO SCHMOO", RUNOFF processes file SCHMOO.DOC and directs output to the printer (LP: is the default output speci- fication). I.e., you get the following command expansion: R RUNOFF LP:=SCHMOO If you supply an output spec, it overrides the default text. Thus, "RNO SCHMOO TEMP.TXT becomes: R RUNOFF TEMP.TXT=SCHMOO There are a couple of points to keep in mind when you use the default string facility: o The default text is "sticky." Once the text for an in- sertion operator has been defined, it stays defined. Thus, defining something like ZORCH==_D "^1[MY] ^1[TEXT]" is a waste of typing. UCL+ scans symbol definitions from left to right, and it will always pick up, and use, the default text "MY"; "TEXT" will never be used. o Default text insertion is not nested. The default string is treated strictly as text (although quoting works). A construction such as "^2[^1]" will not cause the first sub-string to be used as the default for the second sub-string; instead, the text "^1" will be inserted. UCL+ -- User Command Linkage Program - V07.55b Page 27 Spring 1987 DECUS Release 9.0 "HARD-WIRED" COMMANDS The following is a brief description of the commands "hard-wired" into UCL+. Commands such as CHAIN, DISPLAY, ERASE, LIST, etc. are required to support the various UCL+ functional goodies. NOSL and SLON, are included because they are handy, they are too complex to implement as symbols, and they serve as good examples of how to add your own hard-wired commands. Note that, as with RT-11 commands, UCL+ commands and symbols need not be typed in their entirety to be recognized. You need only type enough characters to make a command unambiguous (and to keep it from being mistaken as an RT-11 command). For example, "LIST COMMANDS" can be abbreviated as "LIS CO" ("LI CO" would be inter- preted by RT-11 as a "LINK" command). The commands are listed in alphabetical order. Underlining with "====" is used to highlight the command itself. Optional modi- fiers, switches, and so forth, are enclosed in square brackets ("[]") and these may be nested (for example, [["]prompt-text["]] indicates that the quotes are optional as well as the entire ar- gument). 9.1 CHAIN Command [NO]CHAIN [file-spec] ===== "Set Up Exit-On-Bad-Command Chain" The CHAIN command allows you to specify a program for UCL+ to chain to if UCL+ is unable to interpret a given command. The original command string is passed to the specified program in the same form and in the same fashion that the string was given to UCL+. Issuing a CHAIN command with no argument restores or re- tains the most recent CHAIN file specification. Note that the CHAIN command will also disable UCI_MODE if it is in effect (see also section 9.12). NOCHAIN disables chaining. Examples: NOCHAIN CHAIN SY:BADWRD.SAV UCL+ -- User Command Linkage Program - V07.55b Page 28 Spring 1987 DECUS Release 9.2 DISPLAY Command DISPLAY[/switches] command-string ======= or DISPLAY "string["] ======= "Display Command Expansion or String" The DISPLAY command prints the expansion of the specified UCL+ command or symbol or, if you enclose the argument with quotation marks, the indicated string is simply printed as is followed by a carriage-return/line-feed. If the trailing quote is omitted, no carriage control is appended (this is the preferred method for sending escape sequences). Output can be directed to the console (the default), the printer, or some other specified device/file. Switches: /EXECUTE prints the expanded command and then executes it (not valid if DISPLAYing a string). /NOEXECUTE suppresses command execution (default). /FORM0 allows the printer handler to do a formfeed be- fore the first page of output (default; has no effect unless SET LP FORM0 command is in effect) /NOFORM0 prevents the printer handler from executing a formfeed before the first page of output (recom- mended if you are sending escape sequences to the printer) /PRINTER directs output to the printer (device LP:). /OUTPUT:file-spec directs output to the specified device/file. /TERMINAL directs output to the console (default). Note that the DISPLAY command is only valid for commands that cause a command expansion to be passed to the keyboard monitor. It also does not work across a CHAIN. Attempting to DISPLAY a "non-expandable" command will cause a "?UCL-F-Invalid DISPLAY ar- gument" error message to be issued. Examples: DISPLAY CD DL0 UCL+ -- User Command Linkage Program - V07.55b Page 29 Spring 1987 DECUS Release DISPLAY/EXECUTE SLON DISPLAY "HERE ARE TWO BEEPS<7><7>" DISPLAY/PRINTER "LINE OF TEXT" 9.3 ERASE Command ERASE[/switches] symbol1[,symbol2,...] ===== "Erase Symbol(s)" The ERASE command allows you to delete a symbol or symbols that have been previously defined. If you specify the entire symbol name, it is deleted with no verification prompt. If you only type enough of the name to be unambiguous, you will get an "Are You Sure?" prompt. The command "ERASE *" will delete all of the symbols. Switches: /NOQUERY omits verification prompt /QUERY ask for operator verification (default if ERASE * used) Examples: ERASE ZOOT,FINSTER,WALD ERASE * 9.4 LIST Command LIST[/switch] thing1[,thing2,...] ==== "List Current Commands/Symbols/Attributes" The LIST command lists the "hard-wired" commands, currently de- fined symbols, CHAIN assignment/status, run-by-name path, and present release/version to the specified device or file. If you type a LIST command with no arguments, the symbols are listed. If you omit the output specification, output is directed to the console. Switches: /FORM0 allows the printer handler to do a formfeed UCL+ -- User Command Linkage Program - V07.55b Page 30 Spring 1987 DECUS Release before the first page of output (default; has no effect unless SET LP FORM0 command is in effect) /NOFORM0 prevents the printer handler from executing a formfeed before the first page of output /OUTPUT:file-spec sends output to the specified device/file /PRINTER sends output to the printer (LP:) /TERMINAL sends output to the console (default) Arguments: ALL list commands, symbols, chain data, path list, and version. ("LIST *" has the same effect) CHAIN list the program to chain to if a command cannot be identified COMMANDS list the "hard-wired" commands PATH list the current run-by-name path list SYMBOLS list the current symbol definitions (default) VERSION list the program name and version NOTE If you list a symbol whose definition contains non-printing characters (an escape character, for exam- ple), UCL+ will indicate their presence by printing the octal code for each character enclosed in angle brackets. E.g., the "CLS" example in section 8.4 in- cludes escape characters (escape=33 octal). It would list as CLS ==_d "<033>[H<033>[J Examples: LIST LIST CHAIN,PATH LIST/PRINTER * UCL+ -- User Command Linkage Program - V07.55b Page 31 Spring 1987 DECUS Release 9.5 NOSL/SLON Command NOSL or SLON ==== ==== "SL editor on/off" These commands turn the single-line editor off or on. If UCL+ is being run directly, the effect is to toggle SL lo- cally. This assumes, of course, that SL was installed and turned on prior to running UCL+ and that SL is enabled for use by user programs. This is particularly handy if you need to include characters in a symbol definition that are intercepted by the single-line editor. For example, if you wished to define a sym- bol that rings the bell on the console, you could use the follow- ing sequence of commands: .UCL UCL> nosl UCL> bell==_d " If NOSL or SLON is entered via the monitor, the effect is the same as typing, respectively, SET SL OFF or SET SL ON. 9.6 PASS_ON Command PASS_ON[/TO:program-name] command-string ======= "Pass On Command To Next (or another) Program" This command tells UCL+ to pass the specified command-string on to the program that you specified via the CHAIN command. If you specify a "program-name", then the command is passed to this pro- gram instead. If CHAINing is not in effect, and you failed to specify a program to chain to, you get your hand slapped with "?UCL-F-No CHAIN in effect". Note that the command string is passed "UCL-style" (byte count at location 510, string starting at 512) not "run-by-name" style. /TO:program-name causes the command-string to be passed to the specified program Examples: PASS_ON LIST PASS_ON/TO:BADWRD NUTS==_D "NUTS TO YOU TOO" UCL+ -- User Command Linkage Program - V07.55b Page 32 Spring 1987 DECUS Release 9.7 PATH Command [NO]PATH [device1[,device2,...]] ==== "Set Up 'Run-by-name' Search Path" If UCL+ does not "know" a given command, it follows the device list set up with the PATH command in attempting a "run-by-name". It uses DK: by default. When you enter a new device list, it replaces the old one. The limit is about 20 device mnemonics. It is not necessary to include the trailing colon when you specify a device; "DL0:" and "DL0" are interpreted in the same way. The NOPATH command disables the "run-by-name" function. If you have previously issued a NOPATH command, typing the PATH command by itself (no arguments) restores the old search path. Examples: PATH DK,DL0,DL1 NOPATH PATH DU0:,DU1: 9.8 PROMPT Command PROMPT [["]prompt-text["]] ====== "Change Prompt String" The PROMPT command is used to change the UCL+ input prompt. This command is frequently employed when UCL+ is being used in "UCI mode". The replacement prompt text may optionally be enclosed in quotes. If you issue the PROMPT command with no argument, the default prompt ("UCL> ") is restored. Examples: PATH UCLXM> PATH "TSXUCL> " UCL+ -- User Command Linkage Program - V07.55b Page 33 Spring 1987 DECUS Release 9.9 RECALL Command RECALL[/switches] file-spec ====== "Recall Symbol Definition and Status Tables" Recalls (loads) the symbol definition and status area from a file that has previously been created with the STORE command. The default device is DK:. The default extension is .UCL (ie, DK:filnam.UCL where "filnam" is the file name you specify) if you are running the "vanilla" UCL+ program, .UCX if you are using the special XM version of UCL+, and .UCJ if the /JOURNAL switch is in effect (either version). Switches: /BINARY this is the default; loads a file created as a binary image of the UCL+ symbol/status area /JOURNAL loads a "journal" file; echos the input to the con- sole if /NOQUIET is in effect /NOQUIET allows echo of commands to console when doing /JOURNAL input; use this switch with caution, especially if commands may include console escape sequences /QUIET this is the default; suppresses echo of commands when doing /JOURNAL input; invalid with /BINARY; also suppresses "warning level" messages (e.g., "?UCL-W-Replaced existing symbol") Examples: RECALL SY:UCLXM RECALL/JOURNAL BADWRD 9.10 RELOAD command RELOAD ====== "Reload The UCL+ Global Region" When you are using the special XM version of UCL+, almost the en- tire program is permanently resident in a global region in ex- tended memory. The RELOAD command allows you to force UCL+ to reload this memory region from the copy of the UCL+ program that you are currently running. UCL+ -- User Command Linkage Program - V07.55b Page 34 Spring 1987 DECUS Release The RELOAD command always forces UCL+ to run; it does not return to the monitor automatically. This occurs even if you issue the RELOAD command at the monitor level. 9.11 STORE Command STORE[/switches] file-spec ===== "Store Current Symbol Definition and Status Tables" The STORE command causes the symbol/status blocks to be written to a specified file. The default device is DK:. The default ex- tension is .UCL (ie, DK:filnam.UCL where "filnam" is the file name you specify) if you are running the "vanilla" UCL+ program, .UCX if you are using the special XM version of UCL+, and .UCJ if the /JOURNAL switch is in effect (either version). Switches: /BINARY this is the default; stores a file as a binary image of the UCL+ symbol/status area /JOURNAL writes a "journal" file; the file is stored as the series of commands necessary to recreate the present UCL+ configuration; i.e., as an "editable" command file Examples: STORE SY:UCL STORE/JOURNAL BADWRD 9.12 UCI_MODE Command [NO]UCI_MODE [["]prompt-text["]] ======== "Switch 'UCI Mode' On/Off" The UCI_MODE command is employed to set up UCL+ for use as a "User Command Interpreter" (UCI). TSX-Plus provides a facility for designating UCI's. Typically, a UCI is used to process user input either prior to, or instead of, the normal keyboard monitor (KMON). Issuing a UCI_MODE command has the following effect on UCL+: o CHAINing is disabled. Non-UCL+ command strings are passed to KMON for execution. UCL+ -- User Command Linkage Program - V07.55b Page 35 Spring 1987 DECUS Release o If specified, the "prompt-text" replaces the normal UCL+ line prompt; if no "prompt-text" is specified, the default prompt ("UCL> ") is assumed (same effect as a PROMPT command). o The names of the hard-wired commands are changed by the ________________________________________________________ addition of a "prefix character". Unless you reassemble ________________________________ UCL+ to change or eliminate it (see section 14.7), this character is a period ("."). Thus, for example, the LIST command becomes ".LIST". NOUCI_MODE acts as follows: o The CHAINing condition in effect prior to the UCI_MODE command is restored. o If no prompt-text is specified, the default UCL+ prompt is restored ("UCL> "). o The normal hard-wired command names are restored. Examples: UCI_MODE "UKMON> " NOUCI_MODE UCL+ -- User Command Linkage Program - V07.55b Page 36 Spring 1987 DECUS Release 10.0 CI HANDLER This "handleroid" allows you to turn the various RT-11 Command Line Interpreters (CLI's) on or off using SET commands. It will also show which CLI's are enabled. There are four CLI's: UCF (User Commands First), DCL (Digital Command Language), CCL (Concise Command Language), and UCL (User Command Linkage). Refer to the RT-11 documentation for an explanation of each. The possible SET commands for the CI (Command Interpreter) handleroid are: SET CI [NO]UCF -- turn UCF on/off SET CI [NO]DCL -- turn DCL on/off SET CI [NO]CCL -- turn CCL on/off SET CI [NO]UCL -- turn UCL on/off SET CI HELP -- display SET commands SET CI RESET -- same as SET CI NOUCF,DCL,CCL,UCL SET CI SHOW -- display the active CLI's By default, RT-11 has all CLI's enabled except UCF. In other words, the normal situation is equivalent to SET CI NOUCF,DCL,CCL,UCL Thus, if you issued a SET CI SHOW command under an unaltered monitor, CI would report ?CI-I-CLI's enabled: DCL CCL UCL Note that SET CI RESET restores/insures the above default condi- tion. It is not possible to INSTALL CI. This is because CI contains only SET code. As there is no executable handler code, there is no reason why CI should be installable -- it would just waste a device slot in the monitor tables that could be used for some- thing else. The monitor will execute the SET options as long as CI has the right name and resides on SY:. Thus, for the RT-11 SJ and FB monitors, the file should be SY:CI.SYS. If you are going to use it under XM, make a copy named SY:CIX.SYS. Under RTEM, it should reside in the "mark zone" as SY:CIM.SYS. NOTE TO RTEM USERS RTEM V2.1 uses the UCF facility to implement additional monitor commands and options that are specific to the RTEM environment. The CI handler automatically adjusts to this requirement. Under RTEM, SET CI RESET is equivalent to SET CI UCF,DCL,CCL,UCL. The text dis- played by SET CI HELP will reflect this difference also. UCL+ -- User Command Linkage Program - V07.55b Page 37 Spring 1987 DECUS Release WARNING!!! Turning off both DCL and CCL effectively turns off the monitor. NOTE CI will not run under versions of RT-11 prior to V5.2. It will not work properly with TSX-Plus either. UCL+ -- User Command Linkage Program - V07.55b Page 38 Spring 1987 DECUS Release 11.0 ERROR MESSAGES The following are the error messages for the current UCL+ pack- age. There are two levels of severity. "Warning" level messages are preceeded with the prefix "?program-W-" (for example, "?UCL-W-Replaced existing symbol"), and they indicate that the program may have done something that produced an erroneous result. Warning level conditions do not cause program termina- tion. "Fatal" messages are issued when UCL+ detects an error condition that prevents the program from producing any useable output. These messages are preceeded with "?program-F-" (for ex- ample, "?UCL-F-Ambiguous command C"). 11.1 UCL+ "Warning" Messages (?UCL-W-...) Erased symbol A....A Issued when you erase a symbol via the "null definition" method. "A....A" is the symbol name. Replaced existing symbol Indicates that you have replaced an existing symbol definition with another. Truncating symbol definition to 72 characters You have used too many characters to describe a symbol defini- tion. UCL+ stores the new symbol, but truncates the definition part to 72 characters. Truncating symbol name to 6 characters You have used too many characters in a symbol name. UCL+ stores the new symbol, but truncates the name to 6 characters. 11.2 UCL+ "Fatal" Messages (?UCL-F-...) If you are running under a TSX-Plus V5, or later, monitor, those messages flagged with "(*)" will result in a "?KMON-F-Unrecognizable command" error message unless UCL+ is run directly. Ambiguous command A....A (*) UCL+ -- User Command Linkage Program - V07.55b Page 39 Spring 1987 DECUS Release You have not typed enough characters for UCL+ to determine which command or symbol to execute. "A....A" is the unidentified com- mand. Ambiguous switch A....A You have not typed enough characters for UCL+ to determine which command switch to use. "A....A" is the text of the unknown switch. Ambiguous symbol A....A You issued an ERASE command without specifying enough characters for UCL+ to determine which symbol to erase. "A....A" is the name of the ambiguous symbol specification. Conflicting switches You specified two or more command switches that conflict with one another (for example, DISPLAY/TERM/PRINT...). File not found A....A The RECALL command was unable to find the file that you speci- fied. "A....A" is the file name causing the error. Illegal file name A....A You specified a file name in an invalid format (for example, too many characters, or invalid characters). "A....A" is the errone- ous file name. Invalid argument A....A You issued a hard-wired command with an invalid argument (for ex- ample, LIST X). "A....A" is the text of the argument causing the error. Invalid device You specified a device that is unknown to the operating system. This error occurs with the RECALL or STORE command. It may also occur if you make an error when you use LIST/OUT:. UCL+ -- User Command Linkage Program - V07.55b Page 40 Spring 1987 DECUS Release Invalid command A....A (*) UCL+ was unable to recognize the command string (no match with the hard-wired commands, no match with the symbols, the "run-by-name" search failed, and no CHAIN was in effect). "A....A" is the unknown command string. Invalid DISPLAY argument A....A You attempted to DISPLAY something that is not DISPLAYable (i.e., the input command does not result in a command expansion; a LIST command, for example), or you tried to DISPLAY a command or sym- bol that does not exist. "A....A" is the text of the invalid DISPLAY target. Invalid or missing option You specified an incorrect option to a command switch, or you failed to specify an option value where one was required. Invalid switch A....A You specified an illegal command switch. "A....A" is the switch causing the error. Not enough room for file A....A The STORE command was unable to find enough room for the output file (18 blocks are required). "A....A" is the file name. Read error A....A UCL+ encountered an error when it attempted to read data from a file. This error is most commonly generated by the RECALL com- mand. This may be due to a hard input error, but the usual cause is an attempt to RECALL a journal file without specifying the /JOURNAL switch to the RECALL command. "A....A" is the name of the file in which the error occurred. RELOAD invalid while journaling The journal file that you specified in a RECALL/JOURNAL command contained a symbol name that UCL+ interpreted as a RELOAD com- mand. Edit the journal file to correct this error and try the RECALL command again. UCL+ -- User Command Linkage Program - V07.55b Page 41 Spring 1987 DECUS Release Symbol definition table full You attempted to define a new symbol, but UCL+ had no room left to store the definition. Symbol not found A....A The ERASE command was unable to find the name of the symbol that you specified. "A....A" is the unknown symbol. UCI_MODE invalid for this monitor You issued a UCI_MODE command when you were running under RT-11 or a version of TSX-Plus prior to V5.0. Unable to access LP: UCL+ was unable to find device LP:, or another job "owns" LP:. This error may occur when you use the /PRINT option, and it's most frequent cause is the failure to make a logical assignment for LP:. Write error A....A UCL+ encountered an error when it attempted to write data to a file. This error is generated by the STORE command, and it im- plies that the area where the ".UCL" file was created is cor- rupted. "A....A" is the name of the file in which the error occurred. Wrong file format A....A You attempted to execute a RECALL/JOURNAL on a binary format file or a RECALL/BINARY on a journal file. "A....A" is the name of the file that you attempted to RECALL. Wrong version of UCL A....A You tried to RECALL a symbol definition/status file that was created by a version of UCL+ that is too old. For example, a ".UCL" file created by a V1 UCL+ would be incompatible with a V7 series program. "A....A" is the offending file name. UCL+ -- User Command Linkage Program - V07.55b Page 42 Spring 1987 DECUS Release 11.3 Global Region Loader Errors (?UCLGRL-F-...) If you are running the XM version of UCL+, you may occasionally see error messages from the global region loader. These messages are all "fatal" errors and will be prefixed with "?UCLGRL-F-" (for example, "?UCLGRL-F-No room"). No room You have insufficient memory for the loader to run. This is highly unlikely under normal circumstances; the loader never re- quires more than 768 words of low memory. Not XM monitor You attempted to run the XM version of UCL, but you were not us- ing the extended memory monitor. PLAS error Some sort of memory management related error occurred when the loader attempted to create or attach to the global region. The most likely causes under RT-11 are a shortage of extended memory, or an attempt to create too many global regions. If you are run- ning under a TSX-Plus V6.0 or later monitor, this error can also occur if you do not have SYSGBL privilege. I/O error The loader encountered a problem when it attempted to access the program image on disk. Possible causes include a bad block within the program disk image, or the program storage device may be write protected. 11.4 CI Handler Errors (?CI-...) The CI handler generates messages for two error conditions as follows. ?CI-F-Wrong version of RT-11 You attempted you use the CI handler with a version of RT-11 prior to V5.2. UCL+ -- User Command Linkage Program - V07.55b Page 43 Spring 1987 DECUS Release ?CI-W-Disable access to monitor commands/utilities; Are you sure? You have issued a SET command to CI that will result in turning off both DCL (Digital Command Language) and CCL (Concise Command Language). You are, in effect, asking to turn off your entire RT-11 command interface (except for a few of the UCL+ hard-wired commands, assuming that UCF or UCL is still enabled). In keeping with the idea that RT-11 is an "open system", CI will go ahead and do this if you respond with "Y" for yes. UCL+ -- User Command Linkage Program - V07.55b Page 44 Spring 1987 DECUS Release 12.0 EXAMPLES Here are a few examples of some of the symbol definitions that I use frequently. They are shown below in the same fashion that they would be listed via a LIST command. BIG ==_d "<033>#3^<033>E<033>#4^" BUILD ==delete/info ^.bak\execute/norun ^\delete ^.obj CLS ==_d "<033>[H<033>[J DBO ==dir/brief/order:type EXIT ==\ HLP ==r uclhlp\^ INSPEC==edit/inspect J ==show jobs MEMORY==show memory MOVE ==cop/sys/del NEW ==dir/new NOQUIE==set tt noquiet NOWIDE==_d "<033>[?3l<033>[?25h PDELET==_PMOVE ^ NL: PICH10==_d/p/nof "<033>[1w PICH16==_d/p/nof "<033>[4w PMOVE ==unpro/sys ^1\cop/del/sys/prot ^ QUIET ==set tt quiet REBOOT==dup sy:/o/y RNO ==r runoff\^2[lp:]=^1\<003> SAY ==_d "^" SS ==sh sub SUM ==dir/sum ULINE ==_d "<033>[4m^<033>[0m" VERSIO==resorc sy:^.sav/v VT100 ==set tt scope,tab,nocrlf WIDE ==_d "<033>[?3h<033>[?25h XM ==boot sy:rt11xm.sys UCL+ -- User Command Linkage Program - V07.55b Page 45 Spring 1987 DECUS Release 13.0 V7 RELEASE NOTES UCL+ V7 contains a number of extensions to, and minor differences from, V6L (the last publicly released V6 series UCL+). Changes to previous V07.xx versions: o I changed the release/version designation. V7C was fol- lowed by V07.04. o UCL+ has been updated to work properly under TSX-Plus V5. o Support has been added to UCL+ to allow it to be used as a User Command Interpreter (UCI). This was implemented when the author discovered that TSX-Plus version 5 was distributed with a UCI facility (heh, heh, heh)... As a consequence, the UCI_MODE/NOUCI_MODE and PROMPT commands were added to allow UCL+ to be dynamically reconfigured for use as a UCI. See section 14.6 in the application notes and the description of the UCI_MODE command (section 9.12) for further information on this feature. o CHAIN and PATH work somewhat differently than in previ- ous versions. The /RESET switch has been removed. NOCHAIN and NOPATH commands have been added. The effect of these latter commands is to disable their respective functions. A subsequent CHAIN or PATH command with no argument restores the previous condition. Note that a CHAIN command will turn off UCI_MODE if it is in effect. o The /ALL switch has been removed from the ERASE command. For V7, the equivalent to the old "ERASE/ALL" command is now "ERASE *". o The LIST command has been expanded. Either "LIST ALL" or "LIST *" will produce a full listing. "LIST VERSION" has been added. o A bug has been fixed concerning the way that UCL+ deter- mines command ambiguity. Formerly, UCL+ would report a command as ambiguous if it detected an ambiguous match within the hard-wired commands. UCL+ now searches the symbols as well before returning an error. A non-ambiguous match in the hard-wired command list still takes priority over searching the symbol list. UCL+ -- User Command Linkage Program - V07.55b Page 46 Spring 1987 DECUS Release o The DISPLAY command has been cleaned up. UCL+ now re- fuses to DISPLAY "non-expandable" command strings (most of the hard-wired commands, insertion or replacement of symbol definitions, symbols defined in "chained-to" UCL's). o A special "XM version" of UCL+ is now included on the distribution kit. It is intended for use with monitors having support for global regions in extended memory (i.e., RT-11 V5.2 or later; TSX-Plus V6.0 or later). Almost all of the "UCLXM" executable code is permanently memory resident. It is very fast, and uses only 512 (decimal) words of low memory. An additional hard-wired command, "RELOAD", has been added to UCLXM. o Beginning with V07.46, the method that UCL+ uses to search the "run-by-name" path list has been changed slightly. UCL+ no longer exits to the monitor if it en- counters the name of a non-existent device. Instead, it ignores the error, and tries the next device in the list. o V07.47 contains code to "work around" some inconsisten- cies in the RT-11 spooler. If, for example, you issue a DISPLAY/PRINT/NOFORM0 command with spooler flag page support enabled, you will no longer get an unwanted flag page. UCL+ also avoids the generation of a gratuitous trailing form feed when the SET LP ENDPAG=n option is in effect. o V07.50 introduces two new advanced features: "quoting" and argument parsing. Quoting allows you to use the quote character ("|") to force UCL+ to treat the character immediately following it as text, regardless of any special meaning that it might normally have to the UCL+ parser. Argument parsing makes it possible to indicate where a specific fragment of the argument text is to be inserted when building a command string. o With V07.53, the default mode for RECALL/JOURNAL has been changed from /NOQUIET to /QUIET. Changes to the latest version (V07.55b): o Some minor bugs were fixed in the "run-by-name" and sym- bol format checking algorithms. o STORE/JOURNAL now outputs NOCHAIN and NOPATH commands if the CHAIN and PATH facilities have been disabled. UCL+ -- User Command Linkage Program - V07.55b Page 47 Spring 1987 DECUS Release o The "^0" construct was added to allow the insertion of information about how many sub-strings were contained in an argument string. o Support was added to allow the specification of octal character codes (""); the output of the DISPLAY, LIST, and STORE/JOURNAL commands was changed to this format also. o The CI handler had a bug which crashed RTEM if the "...Are you sure?" message was triggered; this has been fixed. The CI version is now V03.03. o Provision was added to allow the specification of default text for the "^" and "^n" insertion operators. o The CD and RNO hard-wired commands were removed. CD can be defined as a symbol; a base-line RNO command can be specified as a symbol, or the hard-wired version enabled with an assembly conditional. UCL+ -- User Command Linkage Program - V07.55b Page 48 Spring 1987 DECUS Release 14.0 APPLICATION NOTES This section contains an assortment of hints, restrictions, cus- tomization patches, and notes for the current version of UCL+. 14.1 Executing Command/Control Files "By-Name" UCL+ can be used to execute indirect command files and IND con- trol files "by-name". In fact, if you set things up properly, you can ensure that they are executed in the proper context re- gardless of whether SET KMON IND is in effect or not. The fol- lowing examples illustrate the technique. Note that you must run UCL+ directly to define the necessary symbol for a command file. For command files: .UCL ___ UCL> zoot==$@sy:zoot _______________ UCL> ________ For control files: .FEEP==IND SY:FEEP _________________ 14.2 Sending Escape Sequences To The Printer Starting with V6K, the LIST and DISPLAY commands include a FORM0/NOFORM0 option. This option allows you to optionally dis- able the effect of the "SET LP FORM0" command; i.e., output can be directed to the printer without a preceding formfeed. This technique is most useful when you wish to send an escape sequence to the printer without triggering a gratuitous blank page. A handy way to accomplish this is to define a generalized symbol for doing this sort of thing: .CQWENC==_D/P/NOF "<033>^ You can then define specific printer-control commands by using the general symbol like a "function". For example, to define commands to control the pitch of an LA50/100/120 style printer: .UCL UCL> pich10==_cqwenc [1w UCL> pich16==_cqwenc [4w UCL> UCL+ -- User Command Linkage Program - V07.55b Page 49 Spring 1987 DECUS Release 14.3 Moving From UCL+ V6x To UCL+ V7.xx UCL+ V7 will not allow you to RECALL version 6 or earlier series .UCL files. There is a technique, using the RT-11 utility SIPP, that will allow you to transfer your symbol definitions, etc. without reentering them all. The patch proceeds as follows: o Using SIPP, change the embedded version number at loca- tion 21620 in the old ".UCL" file from 6 to 7. o RUN a V7.xx copy of UCL+ and RECALL the patched sym- bol/status file. o Issue a PROMPT command to restore the "UCL>" prompt. o Issue a STORE command to write a new ".UCL" file. o If you need the CD or RNO commands, you can implement them by using the techniques described in section 14.12. In the example below, both the ".UCL" file and the V7 copy of UCL.SAV are assumed to be on DK:; "xxxxxx.UCL" is your V6x ".UCL" file. Note that the SIPP patch is for a V6L file. Also note the use of the /A switch. .R SIPP ______ *xxxxxx.UCL/A ____________ Base? _____ Offset? 21620 _____ Base Offset Old New? 000000 021620 006006 \ _ Base Offset Old New? 000000 021620 006 7 _ 000000 021621 014 ________ * ________ .RUN UCL _______ prompt ______ UCL> recall xxxxxx _____________ UCL> store xxxxxx ____________ UCL> ________ . Once the above commands have been executed, the resulting V7 copy of UCL.SAV will be in the same configuration as your original V6 copy. UCL+ -- User Command Linkage Program - V07.55b Page 50 Spring 1987 DECUS Release WARNING!!! The above patch will not work for the XM version of UCL+. You must apply the method described in the fol- lowing application note if you intend to run the XM version. 14.4 Moving From UCL+ V6x Or V7.xx To UCL+ (XM) V7.xx If you wish to use the XM version of UCL+, you can transfer the symbol/status data from a non-XM version of UCL+ in the following fashion: o If your old ".UCL" file is V6x, apply the patch described in the preceding application note to a "vanilla" copy (i.e., the non-XM version) of the current UCL+ program. If your file was created with a V7.xx UCL+, just run the distributed non-XM UCL+ program and execute a RECALL command. o Run the "vanilla" UCL+ and issue a STORE/JOURNAL command to produce a ".UCJ" file. o Run the XM version of UCL+ and issue a RECALL/JOURNAL to load the symbol/status data written out in the previous step. o If you need the CD or RNO commands, you can implement them by using the techniques described in section 14.12. 14.5 Disabling Argument Parsing There may be instances where you do not wish the sequence "^n" to ___ insert an argument sub-string. This is most likely to occur if you are converting an earlier version of UCL+ to a V07.50 or later version and have a symbol definition that is supposed to concatenate the argument string with a number. The solution is to use the "|" operator to quote the "n". The easiest way to il- lustrate this is with an example. Suppose we define a symbol named EXAMPL in the following fashion (RT-11 V5.2 syntax): exampl==_d "^2" If you type exampl I am R2D UCL+ -- User Command Linkage Program - V07.55b Page 51 Spring 1987 DECUS Release UCL+ will display only the word am because it takes the characters "^2" to mean "insert the second argument sub-string here." However, if you define EXAMPL as exampl==_d "^|2" and type exampl I am R2D UCL+ will then correctly display I am R2D2 Because you have "quoted" the "2", UCL+ interprets the definition as "insert the entire argument string ahead of the '2'." 14.6 Hints and Kinks: UCF, UCI, And SET UCL FIRST If you are using UCL+ as a UCI, command lines are inspected by UCL+ before they are processed by the operating system's keyboard ______ monitor (KMON). If you are using UCL+ as UCF or, under TSX-Plus, with SET UCL FIRST in effect, KMON collects the command line, but it is passed to UCL+ without interpretation. In any of these in- stances, the effect is that UCL+ inspects the command before the monitor does. Only if UCL+ does not recognize the command will the monitor see the command line in unaltered form. This occa- sions a couple of "gotchas" that you have to watch out for. 14.6.1 Interception Of Monitor Commands - Some valid KMON com- mands may be trapped prematurely by UCL+. This situation occurs when there is a conflict between a monitor command or normal com- mand abbreviation and a symbol name. For example, the HELP com- mand under TSX-Plus would normally be invoked as "H", "HE", "HEL", or "HELP". If you wish to avoid a conflict with, say, a symbol named "HELLO", then it would be necessary to define the following symbols: H==HELP HE==HELP HEL==HELP conversely, the above situation allows you to override monitor commands with your own. E.g., DELETE==_d "The DELETE command is not allowed!" UCL+ -- User Command Linkage Program - V07.55b Page 52 Spring 1987 DECUS Release 14.6.2 Improper Expansion Of Monitor Commands - This second gotcha is a little more subtle. Some monitor commands have the same name as the utilities that they invoke. If you are, for example, running as UCF with PATH in effect, this can cause invalid command expansions. As an illustration, suppose your run-by-name path is "DK:" and DK: is currently assigned to SY:. The command "DUMP/TERM RUB- ISH.DAT" should be passed to KMON undisturbed (assuming that you haven't defined your own DUMP command). However, UCL+ will spot program DUMP.SAV on "DK:", and expand the command as "RUN DK:DUMP/TERM RUBISH.DAT". DUMP will see something like "RUBISH.DAT=/TERM" and give you what might seem, at the time, to be a mysterious error message. I normally avoid this problem by disabling the run-by-name path (NOPATH command). If you have a need to retain the run-by-name search path, define some symbols that will cause UCL+ to, in ef- fect, pass your command line to the monitor in an unaltered form. For the preceeding example, define DUMP==DUMP 14.6.3 Single Key Commands - All is not gotchas... UCL+ is not very picky about the characters that you use in sym- bol names. If you are using UCL+ as a UCI under TSX-Plus, then you are running UCL+ directly whenever you input a command line. This means that you can define some handy single-key symbols that the monitor would strongly disapprove of under normal circum- stances. For example: \==edit ??????==help One user that I know of (Ray Moran) places his VT100 in alternate keypad mode (with a UCL+ command, of course!) and executes sym- bols whose names correspond to the escape sequences generated by the individual keys. If you are using a VT220, or anything with an LK201 style key- board. You have even more keys that you can define! 14.7 UCL+ Assembly Conditionals You can build a somewhat customized version of UCL+ by modifying the conditionals file, UCL.CND, prior to assembly. UCL+ -- User Command Linkage Program - V07.55b Page 53 Spring 1987 DECUS Release The prefix conditional, PFX, determines the prefix character used by UCL+ when UCI_MODE is in effect. You can change this prefix by changing the definition of PFX from a period (".") to some other character. Default strings are delineated by square brackets ("[]"). If you wish to use some other set of characters, change the values for DFPFX and DFSFX to modify, respectively, the prefix and suffix character. A hard-wired RNO command can be enabled by defining the condi- tional RNO$C: RNO$C = 1 Edit this line into the beginning of file UCL.CND. RNO is a DCL-style command for use with DECUS RUNOFF M02.4. The documen- tation for RNO can be found in the source file UCLHWC.MAC. Including the RNO command increases the size of UCL+ by 430 decimal words. Use the command file UCL.COM to build UCL+. Use UCLXM.COM to build the XM version. 14.8 Modifying RT-11 To Change The UCL/UCF Device/File Name The RT-11 monitor can be modified to run UCL.SAV or UCF.SAV from some device other than SY:. The name of the UCL or UCF program can also be changed. To accomplish this, you need to know the offsets for some or all of the following locations in the monitor: o ..UCLD - UCL device name o ..UCLF - UCL file name o ..UCFD - UCF device name o ..UCFF - UCF file name The values located at the above offsets are all radix-50 and, as you might expect, the file name immediately follows the device name. I.e., ..UCLF is located at ..UCLD+2 and ..UCFF at ..UCFD+2. If you are an orderly person, you can find the values for these offsets by inspecting the link map for your monitor. Note that, if your monitor version is earlier than V5.2, there will not be any ..UCFD/..UCFF values. UCL+ -- User Command Linkage Program - V07.55b Page 54 Spring 1987 DECUS Release If you are a somewhat disorderly person (perhaps you are undergo- ing TECO withdrawal), you can find ..UCLF and ..UCFF by employing the SIPP search function and looking for a radix-50 UCL or UCF, respectively. In either case, once you know where these locations are, you can use SIPP to patch your monitor to taste. In the following exam- ple, the UCL device is patched from "SY:" to "UCL:". I usually do this because I can then assign some other device to be UCL: in my start-up command file (VM: is a nice choice). The labels ..UCLD and ..UCLF represent the offsets that were obtained from the monitor's link map. .SIPP RT11XM.SYS/A _________________ Base? _____ Offset? ..UCLD ______ Base Offset Old New? 000000 ..UCLD 075250 ;R __ 000000 ..UCLD ;RUCL _____ 000000 ..UCLF ________ If you run more than one type of RT-11 monitor on your system, you may wish to use different copies of UCL and/or UCF depending on which monitor is booted. In the example below, the XM monitor is patched to run UCLXM.SAV rather than UCL.SAV. .SIPP RT11XM.SYS/A _________________ Base? _____ Offset? ..UCLF ______ Base Offset Old New? 000000 ..UCLF 101704 ;R __ 000000 ..UCLF _____ 000000 ..UCLF+2 < > ;RXM ____ 000000 ..UCLF+4 ________ There is no such thing as a free lunch. Be aware of the follow- ing "patch catches": o If you install either of the above patches, you should use the UCL+ LIST command to obtain a list of the cur- rent symbol definitions even if you are using a version of RT-11 that supports the command "SHOW COMMANDS." The reason for this is that RT-11 responds to "SHOW COM- MANDS" by attempting to run SY:UCL.SAV, even though you have changed the name of the "UCL" that it uses for all other purposes. This problem exists in RT-11 versions as recent as V5.4 -- presumably, it will be fixed sooner or later. UCL+ -- User Command Linkage Program - V07.55b Page 55 Spring 1987 DECUS Release o If you change the RT-11 UCL device name, remember that symbol definitions, and such like, will be installed in the copy of UCL+ on the device that you specified. If that device is VM:, and you have defined some symbols that you don't want to lose, use the STORE command, or some other technique, to save the UCL+ context on a non-volatile device. 14.9 Modifying TSX-Plus To Change The UCL/UCI Defaults If you select UCL support when you generate TSX-Plus (if not, why are you reading this?), the default UCL program name is SY:TSXUCL.SAV (if you are running V5.0 or later). Likewise, the default name for user-written UCI's is SY:UKMON.SAV. The easiest way to change these names is to edit the TSGEN.MAC file prior to building TSX-Plus. These values are not normally modified by the user and, thus, will not be found within the "user area" of TSGEN.MAC. If you hunt around with the editor, however, you should be able to find them. For example, if you have V5.1B and want to change the UCL default name, you will discover a line of code that should look like UCLNAM: .RAD50 /SY TSXUCLSAV/ If you are modifying the UCI default, you will find something like UKMNAM: .RAD50 /SY UKMON SAV/ To change the defaults, edit the rad50 file names prior to assem- bling TSGEN.MAC. For instance, you could edit the value at label "UCLNAM:" to change the UCL name from SY:TSXUCL.SAV to UCL:TSXUCL.SAV. Further variations on this theme I leave as an exercise to the user. 14.10 Controlling Command Line Factoring Both RT-11 and TSX-Plus support command line factoring. However, they don't execute it in the same processing sequence. This can effect the way that you define a symbol that employs factoring as part of it's definition. For example, suppose that you wish to define a symbol, "FTN", to invoke the FORTRAN compiler in a specialized fashion that com- piles one or more files resident on device "FTN:". If you are using TSX-Plus, you can define the symbol at the monitor level: .FTN==FORT FTN:(^) _________________ UCL+ -- User Command Linkage Program - V07.55b Page 56 Spring 1987 DECUS Release However, the example above will not work properly if you are run- ning RT-11. This is because RT-11 expands the factoring prior to passing the command line to UCL+. Thus, RT-11 would remove the "unnecessary" parentheses in the preceeding monitor level com- mand, and UCL+ would see the definition as "FTN==FORT FTN:^". The solution, in this case, is to run UCL+ directly: .R UCL _____ UCL> ftn==fort ftn:(^) _________________ UCL> ________ The tendency of RT-11 to pass "rare" rather than "raw" commands to UCL+ can cause more subtle problems also. Suppose, for example, that you wanted to define a command to send a line of ReGIS graphics instructions to a VT241 to change the screen colors. You must preceed the graphics output with the text "Pp" and follow it with "\" ("" indicates the escape character). At first glance, it would seem that the fol- lowing symbol definition sequence would do the trick (note the use of the quote operator to display the ""). .R UCL UCL> regis==disp "<033>Pp"\disp ^\disp "<033>|\" UCL> color==_regis S(M0(AH0L50S100)1( etc... UCL> Unfortunately, since RT-11 is allowed to "touch" the color speci- fication string in the above example, it will strip out most of the parentheses, and the COLOR command will not work. One solu- tion is to define the REGIS symbol in such a way that it will run UCL+ directly (the EXIT symbol is necessary to force a return to the monitor). .R UCL UCL> regis==r ucl\d "<033>Pp"\d "^"\d "<033>|\"\exit UCL> exit==\ UCL> color==_regis S(M0(AH0L50S100)1( etc... UCL> UCL+ -- User Command Linkage Program - V07.55b Page 57 Spring 1987 DECUS Release 14.11 Patching UCL+ For RT-11 V5.1 When you run the UCL+ program, it executes a "context check" to determine which environment it is running in. Unfortunately, there is a bug in RT-11 V5.1 which sets some extraneous bits in the monitor version code. This causes the non-XM version of UCL+ to behave incorrectly when running under V5.1. If you are using UCL+ with RT-11 V5.1, apply the following patch to the file UCL.SAV to force UCL+ to assume that it is running under V5.1. Look at the link map on the UCL+ distribution (UCL.MAP) and find the value of the label "FUDGE" (when this document was prepared, the value for "FUDGE" was 026204, but you should check the link map just to make sure). Use SIPP to disable the release/version check in the context routine ("" denotes a carriage return, "" is a control-Y, operator input is underlined): .SIPP UCL.SAV/A ______________ Base? _____ Offset? FUDGE _____ Base Offset Old New? 000000 FUDGE 002002 240 ___ 000000 FUDGE+2 005067 ________ Note that it is not necessary to apply this type of patch to the XM version of UCL+ (UCLXM.SAV) because it will not run under ver- sions of RT-11 prior to V5.2. UCL+ -- User Command Linkage Program - V07.55b Page 58 Spring 1987 DECUS Release 14.12 Implementing The CD And RNO Commands The CD and RNO hard-wired commands were dropped from UCL+ begin- ning with V07.55. CD was eliminated because the inclusion of support for default strings in UCL+ made it possible to define CD as a symbol. RNO is no longer included because almost everyone was using it at a base-line level only and, thus, an RNO symbol definition would serve just as well in most cases. If you need the CD command, you can define it as a symbol in the following fashion: CD==ASSIGN ^[SY] DK A base-line RNO symbol can be defined as: RNO==R RUNOFF\^2[LP:]=^1\<003> There are, of course, several variants on the RNO symbol. For example, if you always emulate form-feeds with line-feeds, you can force the /F option into the output specification: RNO==R RUNOFF\^2[LP:]/F=^1\<003> Both the CD and RNO symbols are discussed in more detail in the discussion on "Advanced Techniques", section 8.5.3. There is also a journal file on the UCL+ distribution kit named UCLINI.UCJ that contains symbol definitions for CD and RNO. If you wish, you can define these symbols by simply RECALLing the journal file. E.g., RECALL/JOURNAL UCLINI If you need the full-fledged, hard-wired RNO command, it can be enabled by modifying the UCL+ conditionals file (UCL.CND) and re- building UCL+. The "UCL+ Assembly Conditionals" application note (section 14.7) explains how to do this. UCL+ -- User Command Linkage Program - V07.55b Page 59 Spring 1987 DECUS Release 15.0 REPORTING PROBLEMS AND SUGGESTIONS I want to know about bugs! I am also interested in suggestions for improving UCL+ as well as any interesting applications that you may have found for it. I can be contacted at one of the following addresses: William K. Walker Monsanto Research Corp. P. O. Box 32 Miamisburg, OH 45342 (513) 865-3557 William K. Walker P. 0. Box 149 Alpha, OH 45301 (513) 426-7094/0344 If you are on Compuserve, my ID is 71066,24. Leave a message in EMAIL or in the PDP-11 SIG (within the SIG, address stuff to "Bill Walker 71066,24"). If you have access to Western Union EasyLink, my mailbox number is 62752448. If you discover a genuine bug in the current version of UCL+, and you are the first to report it, you get a post-paid copy of the next release -- you can even keep the floppy. UCL+ -- User Command Linkage Program - V07.55b Page 60 Spring 1987 DECUS Release 16.0 WISH LIST Aside from the usual fiddling about with the internals, I cur- rently plan to make the following additions/changes to future versions of UCL+: o a revision to the STORE and RECALL commands that will eliminate the incompatibility between .UCL and .UCX files, o a reasonable way to change the number of characters al- located for symbol names and symbol definitions, o a method to change the total number of symbol defini- tions allowed in UCL+, o some further extensions to the LIST and DISPLAY com- mands, and o provision for the "nesting" of default string specifica- tions. I do NOT intend to implement a "symbol definition editor". Use STORE/JOURNAL and edit the output. I also don't plan to add an "F77" command -- I am hoping that the RT-11 people will do this. UCL+ -- User Command Linkage Program - V07.55b Page 61 Spring 1987 DECUS Release 17.0 UCL+ COMMAND AND SYNTAX SUMMARY SYMBOL DEFINITION SYNTAX ________________________ name==definition where "name" is a six-character symbol name "definition" specifies the symbol expansion OPERATORS _________ == symbol definition \ line separation/termination ^n[text] argument insertion if "n" used, insert nth part if "[text]" used, "text" is default string _ "execute-immediate" flag insert character whose octal code is "nnn" | quote flag; treat next character as text only "HARD-WIRED" COMMANDS _____________________ CHAIN Sets up UCL+ exit chaining DISPLAY Displays a string or UCL+ command/symbol expansion ERASE Deletes one or more UCL+ symbols LIST Lists the current UCL+ commands/symbols/status NOSL Turns the single-line editor off PASS_ON Passes a command string to a program "UCL-style" PATH Sets up the UCL+ "run-by-name" path PROMPT Sets the UCL+ command-line prompt string RECALL Loads symbol definition and status tables RELOAD Reloads a UCL+ global region (XM version only) SLON Turns the single-line editor on STORE Saves the UCL+ symbol definition and status tables UCI_MODE Set UCL+ "pass-line-to-KMON" mode (TSX-Plus only) .sbttl INTRODUCTION .rem ` This version of UCL is brought to you by: William K. Walker Monsanto Research Corp. P. O. Box 32 Miamisburg, OH 45342 (513) 865-3557 UCL+ is a user command linkage program for use with RT-11 V5 or later, and TSX-Plus V4.1 or later. It contains full support for the UCL/UCF/UCI facilities in these monitors. It is upward compatible with the UCL program distributed with RT-11 V5.2 with the following exceptions: 1. UCL+ accepts the "VMS-like" symbol definition syntax used by DEC's UCL, but it ignores it. Instead, the number of characters that must be typed to specify a command or symbol unambiguously is a function of context. E.g., if you have defined two symbols starting with "S", "SUPPER" and "SUPER", you must type four characters to distinguish between them. However, if they are "SIPPER" and "SUPER", only two characters are necessary. 2. UCL+ currently allows symbol names of no more than six characters. If you use a longer name in a definition, UCL+ will truncate it to six characters and issue a warning message to that effect. 3. In addition, it is different from the TSX-Plus V5.1 TSXUCL program in that all symbols are "global" rather than "local". It also does not "forget" symbol definitions after logoff. UCL+ contains a number of extensions to the distributed UCL program: 1. UCL+ is optimized to minimize disk access. The symbol definitions are contained in internal tables rather than a separate data file and an "execute-immediate" mode is available for commands that are defined in terms of other UCL commands. 2. More than one symbol definition can be deleted in a single command line via the ERASE command. All current symbol definitions can be removed with ERASE or ERASE *. 3. Provision has been made to chain to additional "UCL's". 4. A "run-by-name path" can be defined which extends the RT-11 "run- from-SY:" default. 5. You can STORE/RECALL the program settings to/from a separate file. You can do this in either a "binary" or "journaling" mode. Journal files can be edited. 6. A PASS_ON command is included that allows you to force UCL+ to "pass-on" a given command string to the next program in the chain (the default mode) or to a program that you specify. 7. Symbol expansions can be DISPLAYed with or without execution. The DISPLAY command can also be used to print pre-defined ASCII strings at the console (handy for sneaky escape sequences). 8. Provision has been made to make the addition of "hard-wired" commands fairly easy. These are, typically, commands that are too complex to define as symbols. A command of this type is included as a conditional assembly: a DCL-style RNO command for use with DECUS RUNOFF version M02.4. 9. If you run it directly, UCL+ will accept lower-case input. 10. You may, in addition to the symbol definitions, list other program parameters, and list output may be directed to devices/files other than the console. 11. UCL+ can be employed, via the UCI_MODE command, as a User Command Interpreter (UCI). This functionality was added with UCL+ V7 to take advantage of the UCI linkage available in TSX+ and Share-11. 12. You may dynamically redefine the prompt string issued by UCL+. 13. A "quoting" facility is available to override the effect of "operator" characters. 14. In order to allow more complex command definitions, UCL+ supports the parsing of argument strings into as many as nine sub-strings. 15. A CI "handleroid" is included which allows you, under RT-11 V5.2 or later, to control and display the action of the various Command Language Interpreters (CLI's). For example, SET CI UCF turns on User Commands First support. 16. A special version of UCL+ is available for V5.2 or later RT-11 XM monitors. This version is very fast, and uses only about 500 decimal words of low memory. Here's how everything works: First, read sections 2.2.4.1 and 2.2.4.2 (pages 2-39 through 2-41) of the version 5 Software Support Manual... OK, now that you've done your homework (and saved me a lot of typing)... As you will recall, if you are using a version of RT-11 that is sysgened to support User Command Linkage, RT goes through a certain logical sequence to evaluate a command line. First, it looks at the first word to see if this a valid RT-11 command. If not, it looks on SY: for a program to run that has the same name as this first word (let's call it "word1"). If "SY:word1.SAV" is not found, it runs SY:UCL.SAV (if it exists) and passes the entire command line to UCL in the chain area. UCL understands two types of commands: "hard-wired" commands, which are installed by modifying the UCL source code (hereafter referred to simply as "commands"), and "symbols", which are commands that you define (or modify or delete) from the console. First, UCL checks to see if word1 is a valid command and, if so, calls the appropriate routine. If the command check fails, UCL looks for a match against the currently defined symbols and, if successful, invokes the symbol processing stuff (redefinition of a symbol is trapped at this point also). Next, UCL checks to see if a new symbol is being defined and takes care of it if so. Finally, UCL uses the "run-by-name" path to look for "dev:word1.SAV" (the default is dev=DK:) and, if found, runs it by passing the command "RUN command-string" to RT-11. If all else fails, you get a "?UCL-F-Invalid Command" or "?UCL-F-Ambiguous Command" (whichever is appropriate) error message. UNLESS the CHAIN command is in effect -- in which case it chains to the specified program, passing it the original command line. In summary then, when you enter a command: 1) RT-11 tries to execute it, then 2) RT-11 tries to run it off SY:, then 3) UCL tries to execute it as a command, then 4) UCL tries to execute it as a symbol, then 5) UCL tries to run it off one of the series of devices in the run-by-name path, then 6) you either get a nasty comment or UCL chains to another program (NOTE: In UCI mode, UCL+ attempts to process the command line before passing it to the monitor.) Oh yeah, symbols are defined by entering a "symbol definition string" in the format: symbol==definition. Where "symbol" is the command you are defining (6 characters max.) and "definition" is the character-string (72 characters max.) that will govern the way that the symbol is replaced when it is interpreted. In the simplest case, suppose you define the symbol "BUILD" by entering BUILD==EX/MAC/NORUN If you subsequently enter BUILD MYFILE this line is interpreted by UCL and passed back to RT-11 as EX/MAC/NORUN MYFILE You may also get multiple-line definitions via the backslash ("\") character. For example, the symbol "WHEN" defined as WHEN==DATE\TIME executes as if you had typed DATE TIME A "^" character or characters in the definition governs where the "argument-part" of the input command string is inserted when a symbol is expanded. Thus, BUILD==EX/MAC/NORUN and BUILD==EX/MAC/NORUN ^ are equivalent symbol definitions. The "^" operator is really handy when the "argument-part" is to be embedded in the middle of the expansion somewhere rather than tacked on the end. For example: VERSIO==RESORC SY:^.SAV/V If you type VERSION PIP this symbol will expand as RESORC SY:PIP.SAV/V Finally, you may precede the "definition-part" with an underscore character ("_"). This will cause UCL to process the symbol expansion in "execute-immediate" mode. This means that the expanded symbol is processed immediately by UCL rather than being passed on to RT-11 as a command string. This feature will speed up command execution substantially in those cases where one symbol is defined in terms of another symbol or hard-wired command. For example, SAY==DISPLAY "^" and SAY==_DISPLAY "^" are equivalent definitions. If you type SAY HELLO both will expand as DISPLAY "HELLO" BUT, in the first instance, the UCL program will be invoked twice: once to expand SAY HELLO and pass the string back to RT-11, and a second time to execute DISPLAY "HELLO". However, in the second example, UCL expands the command and then immediately executes the resultant command string. This latter form executes much faster, especially on a floppy-based system! Note that you are restricted to using "_" with definitions that expand to a single line. A==_B\C\D will not work correctly. Two advanced features, "quoting" and "argument string parsing", were added starting with V07.50. Preceeding an "operator" such as "^" with the quote character ("|") causes it to be treated as normal text. UCL+ can also break the argument part of a command string into as many as nine sub-strings (sub- strings are assumed to be delineated by spaces). Insertion of these sub- strings is controlled by suffixing the insert operator ("^") with a number from 1 through 9 -- thus, the third substring is denoted with a "^3" sequence. ` .sbttl ADDRESSES, VALUES, DEFINITIONS ; ============================== .sbttl . Handy RT Addresses and Bit Definitions jsw = 44 ;Job Status Word userto = 50 ;Location of program's high limit address errbyt = 52 ;RT's error byte userrb = 53 ;User error byte tsxsiz = 56 ;SETSIZ location for TSX+ chname = 500 ;CHAIN program name in syscom area bytcnt = 510 ;Byte count in syscom area cmdbuf = 512 ;Command text in syscom area sysver = 276 ;Offset to RT-11 version/release data config = 300 ;Offset to RMON configuration word sysgen = 372 ;Offset to RMON sysgen features word $inddv = 426 ;RMON fixed offset pointer to INDDEV warn$ = 2 ;"Warning" bit in user error byte sever$ = 10 ;"Severe error" bit in user error byte edit$ = 20 ;SL disable bit in JSW spxit$ = 40 ;JSW bit for special chain exit ovly$ = 1000 ;Overlay bit in JSW kt11$ = 10000 ;XM bit in configuration word ttlc$ = 40000 ;Lower case bit in JSW tsxp$ = 100000 ;TSX+ bit in sysgen features word and STATUS + ; CLI enabled bits in CLIFLG byte (invalid prior to RT-11 V5.2)... ucfon = 1 dclon = 2 cclon = 4 uclon = 10 ucfxit = 200 ;When set, UCF is passing line to KMON ; CLI type values in CLITYP byte (invalid prior to RT-11 V5.2)... ucf$cl = 0 ;Running as UCF dcl$cl = 1 ;Run from DCL ccl$cl = 2 ;Run from CCL ucl$cl = 3 ;Running as UCL .sbttl . Status Bits For STATUS (+) and PFLAGS (*) ; STATUS... runc = 1 ;UCL invoked by RUN command + ximm = 2 ;Execute-immediate flag + dspla = 4 ;DISPLAY command encountered + dsplx = 10 ;DISPLAY/EXECUTE encountered + odopn = 20 ;A device/file is open for LIST output + hwamb = 40 ;Ambiguous command after "hard-wired" search + ; 100 RESERVED ucimd = 200 ;UCI_MODE in effect +* ucfmd = 400 ;Running as UCF + jrnli = 1000 ;Journal input active + jrnlo = 2000 ;Journal output active + jrnlq = 4000 ;Do "quiet" journaling + eefnd = 10000 ;Input string contains a symbol definition operator ("==") + ; 20000 RESERVED + rtv5.2 = 40000 ;Running under RT-11 V5.2 + ;tsxp$ = 100000 ;TSX+ bit in sysgen features word and STATUS + <= NOTE ; PFLAGS... uclxm = 1 ;Special XM version of UCL * ;ucimd = 200 ;UCI_MODE in effect +* <= NOTE .sbttl . Status Bits For PLINE Routine PLSTAT Status Word plprg = 1 ;Purge channel on completion plnf0 = 200 ;/NOFORM0 in effect plprn = 100000 ;/PRINT in effect .sbttl . Status Bits For Command Execution Status cxdsp = 200 ;Command is potentially DISPLAYable cxnuc = 100000 ;Command-line text may not be "memorized" .sbttl . Switch Bit Definitions all = 1 ;/ALL noq = 2 ;/NOQUERY qry = 4 ;/QUERY out = 40 ;/OUTPUT prn = 100 ;/PRINTER trm = 200 ;/TERMINAL exe = 400 ;/EXECUTE nex = 1000 ;/NOEXECUTE fm0 = 2000 ;/FORM0 nf0 = 4000 ;/NOFORM0 badopt = 40000 ;Invalid switch option cnswer = 100000 ;Conflicting switches .sbttl . Other Values nsyms = 111. ;Maximum number of symbol definitions lcccc = 6 ;Maximum length of symbol name lssss = 72. ;Maximum length of symbol definition lsyms = lcccc+lssss+2 ;Maximum length of a symbol definition buffer nbloks = 18. ;Number of symbol blocks chbufl = 182. ;Buffer length "chain area" buffsz = chbufl + 2 ;Size of input line buffer lf = 012 ;Linefeed cr = 015 ;Carriage Return space = 040 ;Space bit7 = 200 bit15 = 100000 .asect ; Setting the overlay bit in the JSW will cause channel 17 to automatically ; be open to UCL.SAV... ; Also set lower-case bit for TT: input... . = jsw .word ttlc$ ! ovly$ ; Put the number of K words required by UCL+ in location 56. If run under ; TSX-Plus, this will prevent unnecessary swapping. .if eq ucl$xm . = tsxsiz .word / 4000 .endc .sbttl SYMBOL/STATUS BLOCKS ; ==================== .psect ssblks ; These buffers will form blocks 1 - 18 of the file's SAV image (blocks 3 - ; 20 for the XM version). The first 112 words form table SDSAT, the symbol ; definition string address table. It contains the addresses of the existing ; symbol definition strings, sorted in string alphabetical order (what do you ; mean, why? it's faster to search for a match and determine ambiguity this ; way... you don't think I'd go to all this trouble for nothing do you? ...it ; also makes them list nicely). The remaining 111 x 80 byte area contains the ; buffers for 111 symbol definition strings. ; ; A symbol definition string is entered at the console as ; "symbol==definition" (example: HANG==SUSPEND RTMON) and stored in a ; symbol definition string buffer in the format: ; ; CCCCCC0SSSSSSSSSSSS...SSSSSSSSSSSS0 ; ; where ; ; CCCCCC is an up-to-six character symbol, padded with nulls, ; ; 0 represents a null byte, and ; ; SSS... is the symbol definition (72 char. max., null padded). ; ; The first byte is set to 377 if a particular buffer is unused. ; ; The latter part of the last block contains the UCL version and release ; numbers, the "run-by-name" path and, possibly, the name of a file for ; a chain exit. ; ; When any of the information in these blocks is changed (symbol is ; defined, redefined, deleted; path/chain data is modified), the updated ; versions of blocks 1 - 18 are written to UCL.SAV. sdsat:: ;Symbol definition string address table... .blkw nsyms-1 sdsatl: .word 0 ;Last possible address entry in table sdsate: .word 0 ;End of table, always 0 sdsbfr: .rept nsyms ;Symbol definition string buffers... .byte 377 .blkb lsyms-1 .endr vznrls: .byte rls,vzn ;Release, version pthbuf: .asciz /DK:/ ;Path list buffer .blkw 39. chanto: .word 0 ;Name of program to chain to .blkw 7 prompt: .ascii /UCL> /<200> ;Prompt string .byte 0,0,0 pflags: ;"Permanent" flags byte .if eq ucl$xm .byte 0 .iff .byte uclxm .endc ; NOTE: Use LINK/BOUNDARY:512. to force MAIN psect to start on a block ; boundary!!! .sbttl PROGRAM MAINLINE ; ================ .psect main vrshun: vrstr ;ID string goes here... ; UCL can be entered in one of two ways. Usually, it is invoked by RT-11 ; because RT was unable to interpret a command line. In this case, the ; original command line text is passed to UCL in the chain area starting at ; location 512 with the byte count in the word at 510. UCL detects this ; non-zero byte count, moves the command line to it's input buffer, ; processes it, and executes the appropriate return to the monitor. ; ; A byte count of zero indicates that UCL has been invoked with a monitor R ; or RUN command. This situation causes UCL to request an input line from ; the console (or an indirect command file). Command line processing is the ; same as above with one exception: if command execution does not require a ; return to the monitor (e.g., LIST SYMBOLS), UCL prompts for another ; command line after processing the previous line. ucl:: mov #buff,r2 ;R2=>input buffer clrb (r2) ;Initialize it mov @#bytcnt,r0 ;Get no. of bytes in command line beq 20$ ;If none, just go check context mov #cmdbuf,r1 ;R1=>command line from RT-11 tstb (r1) ;If null line, check context... beq 20$ 10$: movb (r1)+,(r2)+ ;Move command line into buffer... sob r0,10$ clrb (r2) 20$: call contxt ;Do various run-time context checks tstb buff ;If we got text from the chain area, bne 50$ ; go process it 30$: .rctrlo ;Ask for a command line... .gtlin #buff,#prompt bis #runc,status ;Set "we been run" flag mov #buff,r0 ;Anything entered?... mov r0,r1 call adjr0 tstb (r0) beq 30$ ;Nope, ask again 40$: movb (r0)+,(r1)+ ;Ensure leading blanks squeezed out... bne 40$ 50$: bic #ximm,status ;Clear "execute-immediate" flag call ccproc ;Handle any "" stuff call qtproc ;Do quoting; make buffer copy for symbol proc .getcom #buff,#cmd ;Get command into command buffer... call tstsho ;Handle possible V5.2 "show commands" stuff bcs 70$ ;Branch if we took care of any call clencm ;Zap any "other-UCL-style" stuff .if ne uci$c call ucitst ;Handle any UCI_MODE arrangements .endc .cscan ,#rsalst ;Look for a match call @cealst(r5) ;Execute the indicated routine bit #jrnli,status ;Journaling active? beq 60$ ;Branch if not .gtrec #buff ;Get the next input record bcc 50$ ;Go process it if no EOF br 70$ ;Go quit otherwise 60$: bit #ximm,status ;"Execute-immediate" flag set? bne 50$ ;Branch if so 70$: bit #runc,status ;Were we RUN? bne 30$ ;Branch if so .settop #0 ;Exit otherwise... .exit .sbttl TRAPS: BAD AND AMBIGUOUS COMMANDS ; ================================= ; The following stuff is the traps for invalid (BADCOM) and ambiguous (AMBCOM) ; commands. ; ; First, BADCOM tries to execute the command as a symbol. ; ; Next, BADCOM tests for a "==" sequence in the input string to see if someone ; is trying to insert a new symbol definition (redefining a symbol is trapped ; in step 1). ; ; Finally, BADCOM checks to see if the command represents a file, not on SY:, ; that it could attempt to RUN (if the file was on SY:, RT would have RUN it, ; and UCL would not have been invoked in the first place). If a file is ; found, BADCOM sticks the string "RUN" ahead of the full original input ; string and passes the whole assemblage back to RT-11 as a command string. ; If no file is found and the CHAIN command is not in effect, BADCOM reports ; an invalid command. If CHAIN is in effect, the original command line is ; loaded into the chain area and UCL chains to the specified program. ; ; In short, BADCOM triggers symbol processing and chaining and implements a ; non-SY: "run-by-name" facility as well as trapping invalid commands. ; ; AMBCOM traps and reports ambiguous commands for UCL. ; When we enter this piece of code below, we have failed to find a match with ; any of the "hard-wired" commands. The next step is to scan the symbol ; definitions. A match here will result in either the execution or ; redefinition of a symbol. .sbttl . badcom badcom:: push cmd+6 ;Save 7th character in command clrb cmd+6 ;Truncate command to 6 characters .cscan ,#sdsat ;Try for a match in SDS table pop cmd+6 ;Restore 7th command character jmp @sealst(r5) ;Go handle result of scan ; If no symbol is found either, the above JMP instruction enters here. ; Three possibilities now remain: we are inserting a new symbol ; definition, we wish to run a program that does not reside on DK:, or, last ; but not least, this really is a bad command. badcm0: push r0 ;Save pointer to command line... mov #buff,r0 call adjr0 mov r0,savr0 pop r0 bit #eefnd,status ;Hmmm...are we defining a symbol? beq 20$ ;Branch if not 10$: jmp synsrt ;Go handle symbol otherwise 20$: bit #hwamb,status ;Should it actually be ambiguous? bne ambcom ;Branch if so ;Try for a non-SY: "run-by-name"... mov #4,r0 ;"DEV:" prefix on command?... 30$: tstb (r1) ; (fixup to handle unexpected spaces beq 60$ ; and nulls courtesy C. E. Chew -- cmpb (r1),#space ; Why didn't I catch that?!) beq 60$ cmpb (r1)+,#': beq 40$ sob r0,30$ br 60$ 40$: clrb rundev ;Ensure null at end of "RUN " command 50$: mov savr0,r0 ;Go do "run-by-name"... mov #runcmd,r1 jmp subcmd 60$: mov #pthbuf,r0 ;R0 => path data buffer tstb (r0) ;Skip path stuff if null list... ble badcmx 70$: .getcom ,#cmd ;Get a "DEV:" into command buffer tstb (r0) ;End of path list? beq 80$ ;Branch if so inc r0 ;Skip the comma 80$: push r0 ;Save R0 (points at next "DEV:") mov r1,r0 ;Get length of device mnemonic... call len add r5,r1 ;Concatenate command to "DEV:"... .getcom savr0 clrb 6(r1) ;Ensure 6-char name .serr ;Inhibit abort on monitor errors mov sp,spsav ;See if there is a file out there called .csigen dspace,#dext,#cmd ;"DEV:command.SAV"... mov spsav,sp ;Restore the stack pointer bcc 90$ ;Branch if file found (carry untouched by mov) .herr ;Turn .serr off pop r0 ;Restore R0 (points at next "DEV:" in path) tstb (r0) ;End of the path? beq badcmx ;Go complain if so br 70$ ;Otherwise, go try next "DEV:" 90$: .close #3 ;Hand-holding .herr ;Turn .serr off pop r0 ;Restore R0 (points at next "DEV:" in path) mov #cmd,r1 ;Build "RUN DEV:" string... call tstdmn .getcom r1,#rundev br 50$ ;Go do "run-by-name" badcmx: bit #,status ;UCF/UCI_MODE? beq 10$ ;Go check CHAINing if not mov savr0,r1 ;If UCF/UCI_MODE, set up to pass original line mov #scrach,r0 ; to KMON... clr (r0) jmp subcmd ;And go do it 10$: tst chanto ;Are we gonna CHAIN? bgt chanr ;Branch to chain stuff if so mov #mbad,r5 ;"Invalid Command"... mov savr0,r0 ;R0 => original command string br tsttsx ; Traps for ambiguous commands come here: .sbttl . ambcom ambchw:: bis #hwamb,status ;Set hard-wired ambiguity bit jmp badcom ;Go check symbols ambcom:: bic #hwamb,status ;Clean up status word bit #eefnd,status ;Defining a symbol? bne synsrt ;Branch if so mov #mamb,r5 ;"Ambiguous Command"... mov #buff,r0 tsttsx: bit #runc,status ;Were we RUN? bne 20$ ;Branch if so tst status ;Running under TSX+? bpl 10$ ;Branch if not mov #huh,r1 ;R1 => "?" prefix jmp subcmd ;Let TSX take a look at the command... 10$: bit #ucfmd,status ;Running as UCF? bne badcmx ;Branch if so 20$: mov r0,r4 ;R4 => unrecognized command string br ferrx ;Go do "fatal" error exit... ;Invalid DISPLAY stuff comes here: baddsp:: mov #mbadsp,r5 ;"Invalid DISPLAY Argument"... mov savr0,r4 ;R4 => buffer contents jmp ferrx ;Go complain .sbttl . chanr ; This code is executed if UCL can not identify the command and if the CHAIN ; command is in effect. The CHANR0 entry point is for routines that set up ; their own chaining text (the PASS_ON command, for example). .enabl lsb chanr:: bit #dspla,status ;DISPLAY active? beq 10$ ;Branch if not jmp baddsp 10$: push #bfsav ;Stash address of original input text mov sp,spsav ;Save current stack pointer .csispc #scrach,#dext,#chanto ;convert filename to RAD50, lazy way mov spsav,sp ;Restore stack pointer chanr0: mov #4,r0 ;Move filename to chain area... mov #scrach+36,r1 mov #chname,r2 20$: mov (r1)+,(r2)+ sob r0,20$ pop r1 ;R1 => Original input text mov #cmdbuf,r2 ;R2 => chain text data area 30$: movb (r1)+,(r2)+ ;Move text to data area... beq 40$ inc r0 br 30$ 40$: mov r0,@#bytcnt ;Put length of text string in data area mov #1000,sp ;Reset stack pointer .sreset ;Make sure every little thing is cleaned up .chain ;Bye! .dsabl lsb .sbttl EXIT FOR "SEVERE" ERRORS ; ======================== .sbttl . ferrx ; "Severe" errors handled here... ; ; On entry, ; R5 => message text ; R4 => any additional text (=0 if none) ; ; Message issued is "?UCL-F- ; ; If UCL was invoked by RT-11, a hard exit is executed with the "severe ; error" bit set. ; ; If UCL was run directly, FERRX returns to the program mainline. ferrx:: bic #,status ;Zap any DISPLAY bits .print #muclf ;"?UCL-F-" mov r5,r0 ;R5 => error message .print ;Print it mov r4,r0 ;R4 => additional text bne 10$ ;Branch if we have some mov #crlf,r0 ;Just do a cr/lf otherwise 10$: .print ;Print text bit #runc,status ;Were we RUN? beq 20$ ;Branch if not mov #776,sp ;Force a return to the mainline return ; if we were... 20$: bisb #sever$,@#userrb ;Set error bit .settop #0 ; and do a hard exit... clr r0 .exit .sbttl SYMBOL PROCESSING ROUTINES ; ========================== .sbttl . synsrt ; SYNSRT inserts a new definition into the tables. ; On entry, R0 is pointing at the definition string in the input buffer, BUFF ; (i.e., just after the "==") and R1 points at the command buffer, CMD which ; contains the string representing the symbol. synsrt:: bit #dspla,status ;DISPLAY active? beq 10$ ;Branch if not jmp badcm0 10$: tst sdsatl ;Test last entry in SDS table beq 30$ ;Branch if room available 20$: mov #synrm,r5 ;"No Room" and go exit... clr r4 jmp ferrx 30$: call syfee ;Make R0 point at definition string in BFSAV call adjr0 ;Skip any leading blanks in definition tstb (r0) ;Null definition string? bne 40$ ;Branch if not .gtlin #bfsav,#sydefq ;"Symbol Definition?" mov #bfsav,r0 ;R0 => input buffer (contains definition) br 30$ ;Go check definition just entered 40$: mov #sdsbfr,r2 ;R2 => SDS buffer mov #nsyms,r3 ;R3 = max. no. symbols 50$: cmpb (r2),#377 ;Is this slot available? beq 60$ ;Branch if so add #lsyms,r2 ;R2 => next slot sob r3,50$ ;Go check next slot br 20$ ;Oops! no room (shouldn't get here) 60$: push ;Save addresses of slot to fill and definition mov #lcccc,r3 ;R3 = max. symbol length call ccopy ;Copy symbol to buffer slot inc r3 ; and pad with nulls... 70$: clrb (r2)+ sob r3,70$ pop r1 ;R1 => definition string (old R0 value) mov #lssss,r3 ;r3 = max. def. string length call ccopy ;Copy def. string to slot inc r3 ; and pad with nulls... 80$: clrb (r2)+ sob r3,80$ ;OK, now we sort the address table so ; it points in alphabetical order... pop r1 ;R1 => slot address (old R2 value) mov #sdsate,r4 ;R4 => end of SDS address table mov #nsyms,r5 ;R5 = max. no. entries 90$: tst -(r4) ;Find last non-zero entry... bne 100$ sob r5,90$ mov r1,(r4) ;Must be empty... br wtstbl 100$: mov (r4),r2 ;Point at symbol string call scomp ;Compare new one with it... tst r3 bgt 110$ ;Branch if new > this one mov (r4),2(r4) ;Move this address down one sub #2,r4 ;Point at next address up sob r5,100$ ; and go do another comparison 110$: mov r1,2(r4) ;Insert address of new definition .sbttl . wtstbl ; Here we write the revised symbol definition blocks into UCL.SAV... wtstbl:: mov #blok1,wblok ;Set initial block no. mov #sdsat,wbufa ;Set address of initial block to write mov #nbloks,r5 ;R5 = no. blocks to write 20$: .writw #area,#17 ;Write a block bcs 30$ ;Branch on error inc wblok ;Bump block no. add #512.,wbufa ;Bump buffer address sob r5,20$ return ;Return 30$: mov #wtfail,r5 ;"Output Error..." clr r4 ; and exit... jmp ferrx .sbttl . syproc ; This section processes a symbol that has been found to exist in the symbol ; definition string buffer area. ; It either, ; 1) uses the definition string for the symbol and the remainder of the ; original input string to build a command sequence and pass it to ; RT-11 for execution, or ; 2) detects that this is a redefinition of an existing symbol, and ; takes the appropriate action to update the definition. .enabl lsb syproc:: bit #eefnd,status ;Symbol definition? bne syrepl ;Branch if so push r0 ;Save R0 call adjr0 ;Skip leading blanks in input string mov r0,r4 ;Set R4 = R0 clr r0 ;Set R0 = 0 (counts no. char. copied) mov sdsat(r5),r1 ;R1 => sym. def. string buffer add #,r1 ;R1 => part to substitute cmpb (r1),#'_ ;Definition flagged for "execute-immediate"? bne 10$ ;Branch if not bis #ximm,status ;Flag it if so inc r1 ;Adjust pointer 10$: mov #chbuf,r2 ;R2 => "chain buffer" mov #chbufl-1,r3 ;R3 = max. # char. in final command string(s) clr r5 ;Set R5 = 0 (counts no. of argument inserts) call sparse ;Parse the argument string 20$: call scopy ;Copy/build a command line tst r3 ;Hit byte limit? beq 30$ ;Branch if so tstb -1(r1) ;Done? bne 20$ ;Branch if not pop r1 ;Get R1 off stack (old R0) tst r5 ;Used input string remainder yet? bne 30$ ;Branch if so tstb -(r2) ;Adjust R2 call ccopy ;Copy input string stuff 30$: clrb (r2) ;Ensure trailing null mov #chbuf,r1 ;R1 => "chain buffer" bit #dspla,status ;"Display" flag set? bne 40$ ;Branch if so bit #ximm,status ;"Execute immediate"? bne sypxim ;Branch if so 40$: jmp setcm0 ;Go execute result of your labors... sypxim: mov #buff,r0 ;R0 => UCL input buffer 50$: movb (r1)+,(r0)+ ;Move fleshed-out command into input bne 50$ ; buffer... return ;Return to mainline .dsabl lsb .sbttl . syrepl syrepl:: bit #dspla,status ;DISPLAY active? beq 10$ ;Branch if not jmp badcm0 ;Take error exit 10$: tst r3 ;Exact match? beq 20$ ;Branch if so jmp synsrt ;Go do an insert otherwise 20$: call adjr0 ;Skip leading blanks tstb (r0) ;Null definition? bne 30$ ;Branch if not jmp er1sy0 ;Must want to erase it... 30$: call syfee ;Make R0 point at definition string in BFSAV mov r0,r1 ;R1 => new substitution string mov sdsat(r5),r2 ;Make R2 => destination for new sub. string... add #,r2 mov #lssss,r3 ;R3 = max. string length call ccopy ;Copy the string inc r3 ;Pad it with nulls... 40$: clrb (r2)+ sob r3,40$ call wtstbl ;Go write out changes.. mov #reswrn,wrnmad ;"Replaced Existing Symbol"... call wrngm bit #runc,status ;Were we run? beq 50$ ;Branch if so bisb #warn$,@#userrb ;Set warning bit in user error byte 50$: return .sbttl . syfee ; SYFEE is used by some of the symbol processing routines to locate the ; beginning of the symbol definition string in BFSAV (buffer containing ; the raw copy of the original input string). syfeet: .asciz "=" ;Terminator table for .getcom syfee: push r1 ;Save R1 .getcom #bfsav,#bfsav,#syfeet ;Make R0 point at "=="... inc r0 ;Make R0 point at second "=" (probably) cmpb (r0)+,#'= ;Check for possible gratuitous quote char. beq 10$ ;Branch if it is a "=" inc r0 ;Compensate for quote operator if not 10$: pop r1 ;Restore R1 call adjr0 ;Skip any leading blanks return ;Quit .sbttl . scopy ; This routine copies/builds a command line to the "chain buffer". This is ; done by copying a symbol definition string until a null byte or a "\" is ; encountered. Any time a "^" is encountered during the copying process, the ; "argument-part" of the original UCL input string is inserted at that point. ; If a two-character string is encountered in the format "^n", where "n" is ; in the range "0" through "9", then a parsed section of the argument string ; is inserted. The sequence "^0" is a special case: it is the ASCII digit ; representing the number of non-null segments in the argument string. A ; space or a null is a terminator for the purposes of string parsing ; (e.g., if the string is "me too", ^0 = "2", ^1 = "me", and ^2 = "too"). ; ; If string insertion is indicated and the corresponding string is null, ; SCOPY checks the symbol definition string to see if a default string has ; been defined. If so, the default string is inserted. ; ; Register use is as follows: ; ; R0 is incremented by the number of bytes copied ; R1 points at the symbol definition string ; R2 points at the output buffer ; R3 on entry, contains the maximum number of bytes to copy ; R4 points at the argument string to be inserted ; R5 is incremented every time an argument is inserted scopy: 10$: cmpb (r1),#'| ;Quote character? bne 20$ ;Branch if not inc r1 ;If so, skip it, and br 100$ ; force copy of next character 20$: cmpb (r1),#'\ ;"\" encountered? bne 40$ ;Branch if not tst r3 ;Copy count exhausted? beq 30$ ;Branch if so clrb (r2)+ ;Insert a null byte dec r3 ;Adjust copy counts... inc r0 inc r1 ;Adjust input pointer 30$: return 40$: cmpb (r1),#'^ ;"insert argument" flag encountered? bne 100$ ;Branch if not push r1 ;Save R1 inc r1 ;Point at next character cmpb (r1),#'0 ;Is it a "0" through "9"?... blt 60$ cmpb (r1),#'9 bgt 60$ mov r1,(sp) ;Save R1 (incremented) push r4 ;Save R4 movb (r1),r4 ;Get the character bic #^C<17>,r4 ;Make it an offset into the parse address asl r4 ; table... inc r1 ;See if a default string call tstdf ; is defined... bcs 50$ ;Nope mov dfstat,2(sp) ;Yep, adjust stacked input pointer tstb @paddr(r4) ;Pointing at a null string? bne 50$ ;Branch if not inc r1 ;Adjust string address mov r1,paddr(r4) ;Store in sub-string index and merge ; with "normal" sub-string processing... 50$: mov paddr(r4),r1 ;R1 now points to the nth argument section call ccopyt ;Insert the sub-string 55$: pop r4 ;Restore R4 br 90$ ;Go clean up 60$: call tstdf ;Test for a default string... bcs 80$ ;Branch if none mov dfstat,(sp) ;Otherwise, update stacked input pointer tstb (r4) ;Null argument string? bne 80$ ;Branch if not inc r1 ;Make R1 point at default string push r4 ;Save R4 70$: movb (r1)+,(r4)+ ;Move default string into argument cmp r1,2(sp) ; string buffer... blo 70$ clrb (r4) ;Add trailing null pop r4 ;Restore R4 call sparse ;Parse arg. string for sub-string locations 80$: mov r4,r1 ;Make R1 => argument string call ccopy ;Insert it 90$: inc r5 ;Bump insert counter pop r1 ;Restore R1 inc r1 ;Adjust input pointer br 10$ ;Go look at next character 100$: tst r3 ;Copy count OK? beq 110$ ;Branch if done movb (r1)+,(r2)+ ;Copy a character inc r0 ;Adjust counters... dec r3 beq 110$ ;Branch if done tstb -1(r1) ;Did we just copy a null? bne 10$ ;If not, go get next 110$: return .sbttl . sparse ; SPARSE is used to parse a string based on the number of embedded blanks. ; It doesn't modify the string; it just produces an address list pointing ; to the sections framed by a leading blank and a trailing blank or null. ; ; Nine string addresses are produced. If there are less than nine sections, ; the remaining addresses point at the trailing null byte. ; ; The "zeroth" address at the beginning of the address list is a special ; case. It points to an ASCII digit representing the number of non-null ; string sections. ; ; On entry, R4 is assumed to point at the string to be parsed. ; No registers are disturbed by this routine (no guarantees are made about ; the author, however). sparse: push ;Save working registers mov #paddr+2,r1 ;R1 => parse address list mov r4,r0 ;R0 => string to be parsed mov #9.,r2 ;R2 = no. of addresses to be calculated clr pcount ;Initialize count for non-null segments br 20$ ;Go do first string segment 10$: cmpb (r0),#space ;Found a space? beq 20$ ;Branch if so tstb (r0) ;Or was it a null? beq 30$ ;Branch if this is true inc r0 ;Bump the string pointer br 10$ ;Go look at next character 20$: call adjr0 ;Skip any leading blanks 30$: mov r0,(r1)+ ;Stash the address of this segment tstb (r0) ;Was this a null segment? beq 40$ ;Branch if so inc pcount ;If non-null, increment counter 40$: sob r2,10$ ;If not done, go look for next terminator bisb #60,pcount ;Make PCOUNT value ASCII pop ;Restore working registers return ;Quit .sbttl . tstee ; This routine tests for the presence of an "==" sequence in a string pointed ; to by R0. If it tests true, the carry is cleared and R0 points at the byte ; following the "==". If false, the carry bit is set and R0 is unchanged. ; TSTEE also sets the EEFND bit in STATUS if an "==" string is found. ; ; Note that the test fails if there are any intervening non-blank characters. tstee: bic #eefnd,status ;Reset "== found" bit in STATUS push r0 ;Save R0 call adjr0 ;Skip any blanks cmpb (r0)+,#'= ;"="? bne 10$ ;Branch if not cmpb (r0)+,#'= ;Another "="? beq 20$ ;Branch if so 10$: pop r0 ;Restore R0 sec ;Set carry return 20$: tst (sp)+ ;Adjust stack bis #eefnd,status ;Set "== found" bit in STATUS clc ;Clear carry return .sbttl . tstfmt ; Routine to check the format of a symbol definition string... ; ; Tests are made on the lengths of the symbol name and the symbol ; definition. A warning message is issued if the symbol name or definition is ; too long. On entry, R1 points at the symbol name in CMD which has already ; been purged of extraneous characters. The original input string, ; processed for "" sequences, is stored in BFSAV. tstfmt: push ;Save R5, R0 mov r1,r0 ;R0 => symbol name call len ;Check length... cmp r5,#lcccc ble 10$ mov #trswrn,wrnmad ;"Truncating Symbol Name..." call wrngm 10$: mov #bfsav,r0 ;R0 => input string call syfee ;Make R0 point at definition part call len ;Check length of definition... cmp r5,#lssss ble 20$ mov #trdwrn,wrnmad ;"Truncating Symbol Definition..." call wrngm 20$: pop ;Restore R0, R5 return .sbttl . tstdf ; Routine to test if a string meets the format to specify a default ; string. The format is ; ; [s...s] ; ; where "s...s" is the default string framed by square brackets (the ; framing characters can be changed by modifying assembly conditionals ; DFPFX and DFSFX). ; ; On entry, R1 is assumed to point at the "[". ; ; On return, if the format test fails, carry is set and DFSTAT = 0 ; if the test succeeds, carry is clear and DFSTAT contains ; the address of the trailing frame character ; ; No registers are destroyed. tstdf: push r1 ;Save R1 cmpb (r1),#dfpfx ;Prefix character? beq 10$ ;Branch if so 5$: clr dfstat ;Indicate test failure br 30$ ; and go quit 10$: tstb (r1)+ ;Null byte? beq 5$ ;Just quit if so cmpb (r1),#'| ;Quote character? bne 20$ ;Nope inc r1 ;Yep, don't check next character... br 10$ 20$: cmpb (r1),#dfsfx ;Suffix character? bne 10$ ;Keep looking if not mov r1,dfstat ;Store suffix pointer tst (pc)+ ;Clear carry 30$: sec ;Come here to set carry pop r1 ;Restore R1 (carry unaffected) return ;Quit .sbttl . scomp ; This routine compares two strings. ; On entry, ; R1 => string 1 ; R2 => string 2 ; On return, ; R3 = -1, s1 < s2 ; 0, s1 = s2 ; 1, s1 > s2 scomp: push ;Save r2,r1... clr r3 ;Assume strings equal 10$: cmpb (r1)+,(r2)+ ;Compare a pair of characters blt 30$ ;Branch if 1st smaller bgt 40$ ;Branch if 1st larger tstb -1(r1) ;Past end of 1st string? bne 10$ ;Go look at next character if not 20$: pop ;Restore r1,r2... return 30$: dec r3 ;Flag 1st < 2nd br 20$ 40$: inc r3 ;Flag 1st > 2nd br 20$ .sbttl UTILITY ROUTINES FOR PROCESSING COMMAND LINES ; ============================================= .sbttl . clencm ; CLENCM provides some basic clean-up and testing for input text if a symbol ; is being defined or deleted. "Extraneous" characters, allowed for ; compatibility with the distributed RT-11 UCL program, are stripped out. ; The symbol name and definition are checked for length. ; ; On entry, R1 points at the symbol name in CMD; R0 points at the argument ; boundary in BUFF (at the "==" if this is a symbol operation). clencm: call tstee ;Symbol definition? bcs 50$ ;Just quit if not push ;Save R0, R1 10$: tstb (r1)+ ;Find end of command string... bne 10$ dec r1 cmpb -(r1),#': ;Is last character a ":"? bne 40$ ;Quit if not clrb (r1) ;Zap it if so mov (sp),r1 ;Retrieve command pointer 20$: tstb (r1) ;Null byte? beq 40$ ;Go quit if it is cmpb (r1)+,#'* ;"*" encountered? bne 20$ ;Branch if not mov r1,r0 ;Point R0 at position of "*"... dec r0 30$: movb (r1)+,(r0)+ ;Shift rest of command left 1 byte... bne 30$ 40$: pop ;Restore R1, R0 call tstfmt ;Check the symbol definition format 50$: return .sbttl . contxt ; This routine checks the UCL run-time context. It decides if we are running ; under a version of RT-11 or TSX-Plus that we should know about, bombs the ; XM version if things are not right, checks to see if we are being run as a ; UCF, and cleans up any extraneous .GTLIN input. ; ; NOTE ; ~~~~ ; RT-11 V5.1 contains a bug that causes extraneous bits to be set in the ; monitor release/version word. The code at label "FUDGE" should be NOPed ; for early patch level V5.1 monitors to disable the release/version test. ; Failure to do so may cause UCL+ to behave incorrectly. Of course, no ; such test is done in the XM version of UCL+ since it uses features of ; RT-11 that were not available prior to V5.2. .enabl lsb contxt:: mov #rtv5.2,status ;Assume RT-11 V5.2 compatible monitor .if eq ucl$xm .gval #scrach+2,#sysver ;Get version/release of RT-11 swab r0 ;Make it "comparable" cmp r0,#<5*400!2> ;Preserve the RT-11 V5.2 flag in STATUS if fudge:: bge 20$ ; we are running under that version or later clr status ;Zap RT-11 V5.2 bit .endc 20$: bis #tsxp$,status ;Assume TSX+ .gval #scrach+2,#sysgen ;Get contents of SYSGEN word in RMON tst r0 ;Running under TSX+ V5 or later? bmi 40$ ;Branch if so bic #tsxp$,status ;Reset TSX+ status bit .if eq ucl$xm .gval #scrach+2,#config ;Get contents of CONFIG word in RMON bit #kt11$,r0 ;XM monitor? beq 40$ ;Branch if not .settop #-2 ;Ensure we "own" handler load area .endc 40$: .if ne ucl$xm mov @#userto,dspace ;Save pointer to handler load area .endc ; (in LOW memory!) bit #rtv5.2,status ;RT-11 V5.2 style monitor? beq 50$ ;Branch if not tst status ;TSX+? bmi 50$ ;Branch if so .gval #scrach+2,#$inddv ;R0 => INDDEV word (1 word past CLIFLG) mov -(r0),r5 ;Put CLIFLG/CLITYP word in R5 mov r0,cliadr ;Save this pointer bic #^C<3*400>,r5 ;Mask for the bits we want bne 60$ ;Branch if result non-zero (0 means UCF) bis #ucfmd,status ;Set UCF mode bit in STATUS, bisb #ucfon,(r0) ; set UCFON bit in monitor CLIFLG byte, 50$: return ; and quit 60$: cmp r5,# ;Just quit if we are running as UCL... beq 50$ tstb buff ;Anything picked up from chain area? beq 50$ ;Just return if not .gtlin #scrach+2 ;Otherwise, flush the .GTLIN input text return ; and quit .dsabl lsb .sbttl . ccproc ; CCPROC "filters" the string in BUFF by converting instances of "" ; into the equivalent single ASCII character with value "nnn" octal. ccproc: push ;Save registers we will use mov #buff,r1 ;R1 => BUFF for input mov r1,r2 ;R2 => BUFF for output br 20$ 10$: cmpb -1(r2),#'| ;Last one a quote character? bne 20$ ;If not, no problem movb (r1)+,r0 ;If so, just copy this one... br 30$ 20$: call ccasc ;Filter a character 30$: movb r0,(r2)+ ;Store it bne 10$ ;Keep going if it wasn't a null pop ;Restore registers return ;Quit .sbttl . qtproc ; This routine does the initial processing of any quote characters that ; may appear in an input string. Unless a symbol is being defined, it is ; desireable not to have quote characters embedded in the string. Thus, ; QTPROC does two things: ; ; 1) It puts a copy of the original string in the buffer BFSAV. ; ; 2) It "quote processes" the string in BUFF. I.e., each time it ; encounters a quote character, it strips it out, and retains the ; following character. qtproc: push ;Save the registers we will use mov #buff,r0 ;R0 => input string buffer mov #bfsav,r1 ;R1 => save area for original string 10$: movb (r0)+,(r1)+ ;Make a copy of the original string... bne 10$ mov #buff,r0 ;R0 => input string buffer mov #bfsav,r1 ;R1 => save area for original string 15$: cmpb (r1),#'| ;Quote character? bne 20$ ;Branch if not inc r1 ;If so, skip it 20$: movb (r1)+,(r0)+ ;Move a character back into BUFF bne 15$ ;Continue until null byte found pop ;Restore working registers return ;Quit .sbttl . tstsho ; This routine checks to see if a string passed to UCL is in the format: ; "=" ; TSTSHO is invoked after a call to GETCOM with R0 pointing at the ; terminator encountered in the input buffer and R1 pointing at the ; string that has been copied into the command buffer. If the string is in ; the above format, it is assumed to be the result (or equivalent) of an RT-11 ; SHOW COMMANDS command. If so, TSTSHO executes an internal LIST SYMBOLS ; command, sets the carry bit, and returns. If not, TSTSHO just returns with ; the carry clear. tstsho: cmpb (r0),#'= ;R0 pointing at "="? bne 10$ ;Go quit if not tstb 1(r0) ;Null immediately following "="? beq 20$ ;Go do listing if so 10$: clc ;Clear carry and quit... return 20$: mov #prlfnm,r0 ;Copy the string to PLINE's file name 30$: movb (r1)+,(r0)+ ; buffer... bne 30$ call plinit ;Ensure that PLINE is initialized call lists ;Force a LIST SYMBOLS .prlin #0 ;Clean up any leftovers in last block sec ;Set carry and quit... return .sbttl . swtchs ; Routine to process switches... ; This routine uses the GETCOM/CSCAN calling sequence to detect and report on ; any switches that might be present in a command line. ; ; On entry: ; ; R0 points into the input buffer, immediately after the command or ; argument that may be followed by some switches. ; ; R4 points at an argument list: ; ; _________ ; R4 => | SRSAL | ; --------- ; | SEAL | ; --------- ; | SSBL | ; --------- ; | STXAL | ; --------- ; ; SRSAL is the address of the beginning of a switch reference string ; address list. This list is similar to the RSAL for commands. It ; is a list of pointers to the ASCIZ strings representing the valid ; switches. As with commands, these addresses are sorted in alpha- ; betical order by the strings that they refer to. ; ; SEAL is the address of a switch execution address list, sorted by ; the referenced switch strings. This list contains the addresses of ; the routines that will be executed when a given switch is found. ; ; SSBL is the address of the beginning of a switch status bit list. ; This list is a series of contiguous words containing the bit(s) that ; should be set in the switch status word SWSTAT if a given ; corresponding switch is detected and these words should be in ; alphabetical order by their referenced switches. ; ; STXAL is the address of an optional switch text address list. It uses ; the same ordering as the above lists and contains pointers to ASCIZ ; strings that represent the output switch text to be generated by the ; corresponding switch handing routines. For example, a /STRIP switch ; might generate the text "/S" in the switch text buffer when building ; an output command string. ; ; ; On return: ; ; R0 will be pointing at the next byte past the last detected switch. ; ; R1 - R4 will be unchanged ; ; R5 will contain one of the following values: ; ; -8 invalid switch option ; -6 conflicting switches ; -4 invalid switch ; -2 ambiguous switch ; 0 no errors ; ; SWSTAT will contain the status bit(s) for any detected switches. ; ; The ERASE and RNO command routines contain examples of switch processing. swtchs:: clr swstat ;Clear any old switch status bits mov #stxbuf,stxbp ;Reset pointer into STXBUF push ;Save R1 - R4... 10$: push r4 mov #swbuf,r1 ;R1 => switch buffer call adjr0 ;Skip leading blanks cmpb (r0),#'/ ;Find a switch? bne 20$ ;Branch if not... inc r0 ;Extract the switch string... .getcom ,#swbuf,#tmtblc .cscan ,(r4) ;Try to identify it tst r5 ;Error? bmi 30$ ;Branch if so pop r4 ;Restore R4 (points at argument list) mov 2(r4),r3 ;R3 => switch execution addr. list add r5,r3 ;R3 => addr. of switch routine to execute call @(r3) ;Go process switch bcc 10$ ;Go look for another switch if no errors mov #-6,r5 ;Assume conflicting switches bit #cnswer,swstat ; and test for this bne 40$ ; and branch if so mov #-10,r5 ;Otherwise, it must be invalid switch option br 40$ ;Go quit 20$: clr r5 ;Clear R5 (no errors) 30$: pop r4 ;Restore R4 - R1... 40$: pop return ; The following is a selection of switch handling routines. They are used by ; ERASE and RNO and, as they handle fairly common situations, could be used ; by any new hard-wired commands that you might add. ; ; On entry to any switch routine: ; ; R0 points at the byte in the input buffer immediately following the ; switch string being processed. Note that this means that, if the ; switch takes an argument, R0 will be pointing at the beginning of ; the argument string (example: "/OUT:MYFILE; R0 points at ":"). ; ; R4 points at the argument list (described at beginning of SWTCHS ; routine). ; ; R5 contains the current offset into the switch Execution Address ; List and, thus, the proper offset for locating the appropriate ; bit mask in SSBL and the output switch text in STXAL. ; ; On return: ; ; Any appropriate status bits should be set in SWSTAT. Note that ; if an error flag bit is set (conflicting switch or invalid option), ; SWTCHS will set the appropriate offset in R5. ; ; The carry bit should be set if an error occurred and cleared ; otherwise. ; ; If the routine processed a switch option, R0 should be pointing at ; the next character past it in the input buffer. R0 should be ; undisturbed otherwise. .sbttl . swbits ; SWBITS is used to set the appropriate bits in SWSTAT. swbits: push r5 ;Save R5 add 4(r4),r5 ;R5 => bit mask bis (r5),swstat ;Set switch status bit(s) pop r5 ;Restore R5 clc ;Clear carry return ;Return .sbttl . prntsr ; /PRINTER switch routine... prntsr: push ;Save R0 and R1... .getcom #lpnam,#outfnm ;Move "LP:" to buffer pop ;Restore R1 and R0... bis #plprn,plstat ;Flag /PRINT for PLINE (in case it's called) jmp swbits ;Go finish up (set SWSTAT bit & clear carry) lpnam: .asciz /LP:/ .even .sbttl . termsr ; /TERMINAL switch routine... termsr: push ;Save R0 and R1... .getcom #ttnam,#outfnm ;Move "TT:" to buffer pop ;Restore R1 and R0... jmp swbits ;Go finish up (set SWSTAT bit & clear carry) ttnam: .asciz /TT:/ .even .sbttl . outsr ; /OUTPUT:filename switch... outsr: call swbits ;Set status cmpb (r0),#': ;Pointing at ":"? beq 10$ ;Branch if so bis #badopt,swstat ;Error: set bad option flag, sec ; set carry, return ; and return 10$: push r1 ;Save R1 inc r0 ;Point at filename .getcom ,#outfnm ;Put filename in buffer pop r1 ;Restore R1 clc ;Clear carry return .sbttl . frmsr, nfrmsr ; /[NO]FORM0 switch... nfrmsr: mov #1,wblok0 ;Set PLINE to start output with block 1 bisb #plnf0,plstat ; and set flag in PLSTAT br frmsr0 frmsr: clr wblok0 ;Set PLINE to start output with block 0 bicb #plnf0,plstat ; and ensure flag is cleared in PLSTAT frmsr0: jmp swbits ;Go set designated SWSTAT bits .sbttl . stxotx ; This is a general routine for switches that map: ; "/input-switch-text:option-text" => "/output-switch-text:option-text" ; Example: "/END:7" => "/E:7." ; The mapped string is appended to any existing text in STXBUF. Note that ; a decimal point is appended to numeric options. stxotx: call gstxp ;R1 => output switch text call ctstxb ;Copy to STXBUF call getopt ;Get any option stuff bcc 20$ ;Branch if there is some dec stxbp ;Zap extraneous ":" in output... clrb @stxbp 10$: jmp swbits ;Go update switch status 20$: push r1 ;Save R1 (points at option text) 30$: cmpb (r1),#'0 ;See if option text is entirely numeric... blt 40$ cmpb (r1)+,#'9 bgt 40$ tstb (r1) bne 30$ movb #'.,(r1)+ ;Append decimal point... clrb (r1) 40$: pop r1 ;Restore R1 call ctstxb ;Append option text br 10$ ;Go quit .sbttl . stxoly ; General routine for switches that map: ; "/input-switch-text" => "/output-switch-text" ; Example: "/NOUNDERLINE" => "/U:N" stxoly: call gstxp ;R1 => output switch text call ctstxb ;Copy to STXBUF call swbits ;Update switch status call getopt ;Test for and skip any option stuff bcs 10$ ;Branch if none bis #badopt,swstat ;Error: shouldn't be any options... sec return 10$: clc ;Return with no errors return .sbttl . gstxp ; This routine can be used in a switch handling routine to point R1 ; at the appropriate output switch text. gstxp: mov 6(r4),r1 ;R1 => STX address list add r5,r1 ;R1 => STX address mov (r1),r1 ;R1 => STX return .sbttl . ctstxb ; This routine appends output switch text to the contents of the switch ; text buffer, STXBUF. ; ; On entry, ; R1 => switch text to be appended. ; On return, ; The text is appended to the current contents of STXBUF, ; the pointer STXBP is updated. ; The contents of R0 and R2 - R5 are undisturbed. ctstxb: push ;Save R0, R2, R3... mov #80.,r3 ;Use CCOPY to append the text... mov stxbp,r2 call ccopy clrb (r2) ;Insert null byte mov r2,stxbp ;Save current last character position pop ;Restore R3, R2, R0... return .sbttl . getopt ; This routine extracts the text for an option from the input buffer ; and puts it in the option buffer, OPBUF. ; ; On entry, it is assumed that R0 points at the beginning of some option ; text in the input buffer. ; ; On return, R0 will point at the character immediately following the option ; text in the input buffer, a copy of the option text will be in the buffer ; OPBUF, R1 will be pointing at OPBUF, and the carry bit will be cleared. ; If no option is located, R0 and R1 will be undisturbed and the carry will ; be set. getopt: call adjr0 ;Skip leading blanks cmpb (r0),#': ;Pointing at ":"? beq 10$ ;Branch if so sec ;No option, set carry and return ; return 10$: inc r0 ;Point at option text .getcom ,#opbuf ;Copy option text to buffer clc ;Clear carry and return ; return ; Here are some standard switch error traps for command routines that ; want to use 'em... .sbttl . badopx badopx: mov #mbadop,r5 ;"Invalid Option..." br cnfsw0 .sbttl . cnfswx cnfswx: mov #mcnfsw,r5 ;"Conflicting Switches..." cnfsw0: clr r4 jmp ferrx .sbttl . badswx badswx: mov #mbadsw,r5 ;"Invalid Switch..." br ambsw0 .sbttl . ambswx ambswx: mov #mambsw,r5 ;"Ambiguous Switch..." ambsw0: mov #swbuf,r4 jmp ferrx .sbttl . setcmd, setcm0 ; Routine to pass a command string or strings to RT-11... ; ; This routine passes one or more ASCIZ strings to RT-11 for execution. ; On entry, R1 points at a word containing the number of bytes in the ; string(s). It is assumed that the ASCIZ stuff immediately follows the ; byte count (i.e., 2 + address in R1 = address of text to be passed). ; At entry SETCM0, R0 should contain the byte count, and R1 the text address. setcmd: mov (r1)+,r0 ;Put byte count in R0 cmp r0,#chbufl ;R0 less than or equal to max? ble setcm0 ;Branch if so mov #chbufl,r0 ;If not, set to max setcm0: bit #dspla,status ;Display bit set? beq 5$ ;Branch if not call dsplst 5$: mov #bytcnt,r2 ;R2 => syscom area mov r0,(r2)+ ;Store byte count mov #1000,sp ;Reset stack pointer (now we're committed!) 10$: movb (r1)+,(r2)+ ;Move text into syscom... sob r0,10$ bis #spxit$,@#jsw ;Tell RT what we've done bit #ucfmd,status ;Running as UCF? beq 20$ ;Branch if not bisb #ucfxit,@cliadr ;Set "UCF has something for you" bit 20$: .settop #0 ;Do a hard exit... clr r0 .exit .sbttl . subcmd ; Routine to substitute a UCL command for an RT command (presumably)... ; ; What this routine actually does is copy the string pointed to by R1 into ; buffer CHBUF followed by the string pointed to by R0. It then causes this ; concatenated string to be passed to RT-11 as a command string. ; ; Note that, on entry to a CSE routine, R0 points at the remainder of the ; original input string following the command that UCL has parsed-out and ; interpreted. For example, this would allow a CSE routine for a BUILD ; command to change the input string "BUILD/MAC MYPROG" ; to "EXECUTE/NORUN/MAC MYPROG" ; and then cause it to be executed by simply pointing R1 at the .ASCIZ string ; for "EXECUTE/NORUN" and calling or jumping to SUBCMD. subcmd: push r0 ;Save contents of R0 on stack clr r0 ;Clear R0 mov #chbuf,r2 ;R2 => CHBUF mov #chbufl-1,r3 ;Put max byte count in R3 call ccopy ;Copy first part of string into CHBUF pop r1 ;Get address of 2nd part of string off stack call ccopy ;Stuff 2nd string into CHBUF clrb (r2) ;Terminate with null byte... inc r0 mov #chbuf,r1 ;Point R1 at concatenated string and br setcm0 ; go pass it to RT-11 as a command string .sbttl . ccopy, ccopy0, ccopyx, ccopys ; Command string copy routine... ; ; On entry, R1 points at the string to be copied ; R2 points at the destination for the string ; R3 contains the maximum allowable number of bytes to copy ; ; R0 is incremented by the number of bytes copied ; R3 is decremented by the same amount ; ; Copying is terminated by the detection of a null byte in the input string ; (the null byte is NOT copied!!!) or if the value in R3 decrements to zero. ccopy: tstb (r1) ;Null byte? beq 10$ ;Yep... movb (r1)+,(r2)+ ;Move a byte inc r0 ;Bump byte count sob r3,ccopy ;Continue if copy limit not exceeded 10$: return ;Otherwise, return ; Command string copy with null (CCOPY with null terminator)... ; ; This routine works just like CCOPY above except that it copies the ; terminator byte (null) as well. The null is not copied if this would exceed ; the "maximum allowable number of bytes to copy" value in R3. ccopy0: call ccopy ;Copy the string (less null) tst r3 ;Max. copy count exhausted? beq 10$ ;Branch if so movb (r1)+,(r2)+ ;Copy the null inc r0 ;Adjust byte count dec r3 ;Adjust copy counter 10$: return ; The following set of CCOPYx routines are used for copying argument sub- ; strings. Entry for the group is normally at CCOPYT. ; ; ---------- ; ; CCOPYT copies argument sub-strings in either "default-spec" or "normal" ; modes. The method used depends on whether the sub-string is preceded by ; the default sub-string prefix character or not. ccopyt: cmpb -1(r1),#dfpfx ;String preceded by "default prefix"? bne ccopys ;Branch to CCOPYS routine if not ; Command string copy. Terminates on framing suffix character for default ; sub-strings. Also recognizes quoting. ccopyx: tstb (r1) ;Null byte? beq 30$ ;Yep... cmpb (r1),#'| ;Quote character? bne 10$ ;Nope inc r1 ;Yep, force copy of next character... br 20$ 10$: cmpb (r1),#dfsfx ;Match with trailing framer? beq 30$ ;Branch on this one too 20$: movb (r1)+,(r2)+ ;Move a byte inc r0 ;Bump byte count sob r3,ccopyx ;Continue if copy limit not exceeded 30$: return ;Otherwise, return ; Command string copy, terminates on a space or null. ccopys: tstb (r1) ;Null byte? beq 10$ ;Yep... cmpb (r1),#space ;Space? beq 10$ ;Quit if so movb (r1)+,(r2)+ ;Move a byte inc r0 ;Bump byte count sob r3,ccopys ;Continue if copy limit not exceeded 10$: return ;Otherwise, return .sbttl . adjr0 ; Routine to skip leading spaces... ; ; This routine adjusts the buffer pointer (assumed to be R0) to point at the ; first non-blank character encountered. adjr0: tstb @r0 ;Pointing at a null? beq 10$ ;Branch if so cmpb (r0)+,#space ;Blank? beq adjr0 ;Branch if so dec r0 ;Adjust the pointer and 10$: return ; quit .sbttl . len ; Routine to return the length of a string... ; ; On entry, R0 points at the string to be inspected -- it is assumed to be ; terminated with a null. ; ; On return, R0 is unchanged and R5 contains the number of bytes in the ; string. len: push r0 ;Save R0 clr r5 ;Clear R5 10$: tstb (r0)+ ;Null? beq 20$ ;Branch if so inc r5 ;Bump byte count br 10$ ;Go look at next one 20$: pop r0 ;Restore R0 return .sbttl . wrngm ; Routine to issue warning messages... ; ; Prints "?UCL-W-". Address of should be in location ; WRNMAD. If RUNC bit not set in STATUS, also sets WARN$ bit in user ; error byte. Message is not issued if RECALL/JOURNAL is in effect. wrngm: bit #jrnlq,status ;Doing quiet journaling? bne 10$ ;Branch if so push r0 ;Save R0 .print #muclw ;"?UCL-W-" .print wrnmad ; pop r0 ;Restore R0 10$: bit #runc,status ;Were we RUN? bne 20$ ;Branch if so bisb #warn$,@#userrb ;Set "warning" bit in user error byte 20$: return .sbttl . pline ; PLINE is a subroutine to do .PRINT-style output to a device/file. ; ; On entry, R0 points at the string to be output and the ascii name of the ; file to be used should be in buffer PRLFNM ; ; PLINE will open the output file at the first write. If R0=0, PLINE will ; clean up and close the file. ; ; If no file is specified in PRLFNM, PLINE just does .PRINT's ; ; In order to keep the RT-11 spooler from screwing things up, PLINE does a ; non file structured lookup on LP: if both the /PRINT and /NOFORM0 switches ; are in effect. In this case, it also purges the I/O channel when output is ; complete to avoid the possible output of a trailing form feed. ; ; PLINE has it's own status word, PLSTAT, with the following bits defined: ; ; PLPRG = 1 purge bit ; PLNF0 = 200 /NOFORM0 in effect ; PLPRN = 100000 /PRINT in effect pline: push ;Save the registers we're going to use mov r0,r4 ;R4 => string to output bne 10$ ;Branch if not zero (not closing file) jmp plclos ;Go close up 10$: bit #odopn,status ;Got a file open? bne 90$ ;Branch if so tstb prlfnm ;Is there a file to open? bne 20$ ;Branch if so .print ;Just print line at console jmp plinx ;Go quit 20$: mov #prlfnm,r5 ;R5 => output spec 30$: tstb (r5) ;Find end of string... beq 40$ inc r5 br 30$ 40$: movb #'=,(r5) ;Stick "=" on end mov r5,plcfn0 ;Store location of "=" inc r5 ;Ensure trailing null... clrb (r5) tst plstat ;/PRINT in effect?... bpl 70$ tstb plstat ;/NOFORM0 in effect?... bpl 70$ bisb #plprg,plstat ;Set purge flag mov #^RLP,scrach ;Put rad50 "LP" in scratch area clr scrach+2 ; followed by 0 word .fetch dspace,#scrach ;Fetch the LP handler bcc 60$ ;Branch if no error mov #dmnerr,r5 ;Do fatal error "no device" otherwise... call plcfn 50$: jmp ferrx 60$: .lookup #area,#0,#scrach ;Non file structured lookup on LP: bcc 80$ ;Branch if no error mov #lpluer,r5 ;Fatal error "Unable to access LP:"... clr r4 br 50$ 70$: mov sp,spsav ;Save stack pointer .csigen dspace,#dext,#prlfnm ;Open output file mov spsav,sp ;Restore stack bcs plcser ;Handle errors 80$: bis #odopn,status ;Tell 'em we're open mov #obufr,obptr ;Init output buffer pointer mov wblok0,wblok ; and block number 90$: mov obptr,r1 ;R1 => next loc in output buffer 100$: movb (r4)+,(r1)+ ;Put a character in buffer bgt 120$ ;Branch if not a terminator bmi 110$ ;Branch if end of string (200 byte) mov #eolstr,r4 ;Append cr/lf... dec r1 br 100$ 110$: dec r1 ;Adjust and store next loc pointer... mov r1,obptr br plinx ;Go quit 120$: cmp r1,#obptr ;Buffer full? blt 100$ ;Branch if not .writw #area,#0,#obufr ;Write a block bcs plwter ;Handle any errors inc wblok ;Bump block number mov #obufr,r1 ;Reset pointer br 100$ ;Go get next character eolstr: .byte cr,lf,200,0 ;Carriage return/linefeed string ; Close the output file... plclos: bit #odopn,status ;File open or just .PRINTing? beq 40$ ;Branch if no file mov obptr,r1 ;R1 => next loc in buffer cmp r1,#obptr ;Buffer full? beq 20$ ;Branch if so 10$: clrb (r1)+ ;Append a null byte cmp r1,#obptr ;Buffer full? blt 10$ ;Branch if not .writw #area,#0,#obufr ;Write last block bcs plwter ;Handle errors 20$: bitb #plprg,plstat ;Purge bit set in PLSTAT? beq 30$ ;Nope .purge #0 ;Yep, purge channel 0 instead of closing it... br 40$ 30$: .close #0 ;Close the file 40$: call plinit ;Reset flags, status, etc. plinx: pop ;Restore registers return ; Initialization routine for PLINE... plinit: bic #odopn,status ;Reset status and file name buffer... clrb prlfnm clr plstat ;Reset PLSTAT clr wblok0 ;Reset initial output block number return ; Error traps... plcser: call plcfn ;Set up for error message jmp opnur0 ;Go handle error plwter: call plcfn ;Set up for error message jmp sterx0 ;Go handle error plcfn: mov #prlfnm,r4 ;R4 => file name clrb @plcfn0 ;Zap "=" return plcfn0: .word 0 ;Pointer to "=" at end of file name .sbttl . grec ; GREC inputs records from a file in a manner similar to the .GTLIN request. ; On entry, a file is assumed to be open on channel 3, the initial block ; number for the .READW (WBLOK) should be set, and the input buffer pointer ; (IBPTR) should point BEYOND the end of the I/O buffer (IBUFR). R0 should ; point at the buffer to receive the record retrieved by GREC. ; When GREC detects an end-of-file condition it closes the input channel, ; clears the JRNLI bit in STATUS, and sets the carry bit. ; On normal return, the carry is clear and no registers are disturbed. grec:: push ;Save the working registers bit #jrnlq,status ;Do this quietly? bne 10$ ;Branch if so .print #prompt ;Issue prompt... 10$: mov (sp),r0 mov ibptr,r1 ;R1 => next record in input buffer mov #buffsz-2,r3 ;R3 = max record length 20$: cmp r1,#ibufr+512. ;Time to read another block? blo 30$ ;Branch if not push r0 .readw #area,#3,#ibufr,,rblksv ;Read a block bcs grrder ;Branch on error pop r0 ;Restore R0 mov #ibufr,r1 ;Reset buffer pointer inc rblksv ;Bump block no. for next read 30$: movb (r1)+,r2 ;Get a character bicb #^C<177>,r2 ;Strip parity beq 20$ ;Branch if null cmpb r2,#lf ;Ignore linefeed... beq 20$ cmpb r2,#cr ;Carriage return? bne 50$ ;Branch if not clrb (r0) ;Mark end of record with null mov r1,ibptr ;Save buffer pointer value pop r0 ;Print what we got... bit #jrnlq,status bne 40$ .print 40$: pop ;Restore the registers clc ;Indicate a record is available return ; and quit 50$: clrb (r0) ;Ensure potential end-of-record byte dec r3 ;Decrement record byte count ble 20$ ;Just ignore character if record at max length movb r2,(r0)+ ;Stuff character in record buffer br 20$ ;Go look for another grrder: bic #,status ;Reset JRNLI/JRNLQ bits in STATUS tstb @#errbyt ;End of file? bne 10$ ;Branch if not .close #3 ;Close the channel .print #eofmsg ;"" pop ;Restore the registers sec ;Indicate end-of-file return ; and quit 10$: .if eq ucl$xm mov #rclerr,r5 ;R5 => "Read error" mov #eronjf,r4 ;R4 => "on journal file" jmp ferrx ;Take fatal error exit .iff push #rclerr ;Put error message on stack jmp @#grl$xx ;Take global loader error exit .endc .sbttl . ccasc ; CCASC converts a string of the form "" into an ASCII character ; represented by the octal value "nnn". If, on entry to CCASC, R1 is ; not pointing to a string of this form, the ASCII character is just ; passed through. ; ; On entry: R1 => string ; ; On return: R1 => next character position ; R0 = "filtered" character ccasc: movb (r1)+,r0 ;R0 = 1st character cmpb r0,#'< ;Is it a "<"? beq 10$ ;If so, check for and process "" return ;Just return otherwise 10$: push ;Save working regs, R0 at base of stack mov #4,r2 ;R2 = max. remaining char in "" 20$: cmpb (r1)+,#'> ;Look for trailing ">" beq 30$ ;Branch if found sob r2,20$ ;If not found within limit, 25$: pop ; clean up and quit... return 30$: dec r1 ;Make R1 point at last presumed digit neg r2 ;Calculate no. of digits... add #4,r2 mov r2,r0 ;Save no. in R0 for later 40$: cmpb -(r1),#'0 ;If digits are not legit, just quit... blo 25$ cmpb (r1),#'7 bhi 25$ sob r2,40$ clr r3 ;Clear R3; it will contain result 50$: asl r3 ;Shift 3 bits to left (mult. by 8) asl r3 asl r3 movb (r1)+,r2 ;Get an ASCII digit bic #^C<7>,r2 ;Mask for lower 3 bits bis r2,r3 ;Set them in result sob r0,50$ ;Do next digit, if more of them cmp r3,#377 ;If result is too large, bhi 25$ ; just give up mov r3,(sp) ;Otherwise, update stacked R0 inc r1 ; and R1 values... mov r1,2(sp) br 25$ ;Go quit .sbttl . bytasc, octasc ; BYTASC transforms non-printing characters (8-bit, control, and DEL) into ; an output string of the form ""; normal 7-bit characters are not ; disturbed. ; ; On input, R0 contains the character to be processed; R1 points at the ; output buffer. ; ; On return, R0 is destroyed; R1 points at the next byte past the end of ; the output string. bytasc: bic #^C<377>,r0 ;Strip for byte of interest bne 20$ ;Branch if it is not a null 10$: movb r0,(r1)+ ;Put character in output buffer return ;Quit 20$: cmp r0,#177 ;Do we have DEL or greater (8-bit)? bge 30$ ;Branch if so cmp r0,#space ;Just pass it through if it is printable... bge 10$ ;Make OCTASC routine give us "1nnn" to 30$: bis #1000,r0 ; force leading zeros call octasc ;Convert to octal ASCII movb #'<,-4(r1) ;Enclose result in brackets... movb #'>,(r1)+ return ;Quit ; OCTASC converts a binary value to an octal ASCII string ; ; On input, R0 contains the value to be converted; R1 points at the output ; buffer. ; ; On return, R0 is destroyed; R1 points at the next character position past ; the output string. octasc: mov r0,-(sp) ;Put R0 on stack bic #^C<7>,(sp) ;Mask for lower 3 bits add #60,(sp) ;Make result an ASCII digit ror r0 ;Rotate next group of 3 bits into low asr r0 ; order bits of R0... asr r0 beq 20$ ;If result is zero, we are done call octasc ;If not, call ourself 20$: movb (sp)+,(r1)+ ;LIFO from stack to text buffer... return .sbttl UCL DATA AREA ; ============= .sbttl . Pointers, Register Storage, Status dspace: .word top ;Address of handler load area spsav: .word 0 ;Save area for stack pointer savr0: .word 0 ;Save area for BUFF pointer cliadr: .word 0 ;Save area for address of CLIFLG/CLITYP word status: .word 0 ;Program status word swstat: .word 0 ;Switch status word plstat: .word 0 ;PLINE status word wrnmad: .word 0 ;Address of warning message for WRNGM dfstat: .word 0 ;TSTDF's status word .sbttl . Buffers bfsav:: .blkb buffsz ;Save area for input string buff:: .blkb buffsz ;Input buffer cmd:: .blkb 82. ;Buffer for command parsing swbuf:: .blkb 82. ;Buffer for switch parsing opbuf:: .blkb 82. ;Buffer for option parsing stxbp:: .word stxbuf ;Pointer to next byte in STXBUF stxbuf: .blkb 82. ;Buffer for output switch text outfnm: .blkb 42. ;Buffer for output file name prlfnm: .blkb 42. ;Buffer for PLINE's output file name chbuf: .blkb buffsz-2 ;Intermediate "chain exit" buffer scrach: .blkw buffsz ;Scratch area ibufr: obufr: .blkw 256. ;General I/O buffer ibptr: obptr: .word 0 ;Pointer for above rblksv: .word 0 ;Save area for .READW block number .sbttl . Argument Blocks area: .word 0 ;Argument block area for .WRITW/.READW's... wblok: .word 0 wbufa: .word 0 wcnt: .word 256. .word 0 wblok0: .word 0 ;Initial block no. for .WRITW output dext: .rad50 "SAV" ;Default extensions for .CSIGEN call .rad50 "LST" .word 0,0 paddr:: .word pcount ;SPARSE routine's address list area .blkw 9. pcount: .word 0 RT-11 LINK V05.15 Load Map Monday 20-Apr-87 15:40 Page 1 UCL .SAV Title: UCL Ident: V07.55 Section Addr Size Global Value Global Value Global Value . ABS. 000000 001000 = 256. words (RW,I,GBL,ABS,OVR) RLS 000007 VZN 000067 .AUDIT 107125 SSBLKS 001000 022000 = 4608. words (RW,I,LCL,REL,CON) SDSAT 001000 MAIN 023000 012270 = 2652. words (RW,I,LCL,REL,CON) UCL 023024 BADCOM 023312 AMBCHW 023746 AMBCOM 023760 BADDSP 024050 CHANR 024064 FERRX 024210 SYNSRT 024300 WTSTBL 024542 SYPROC 024632 SYREPL 025016 CONTXT 026150 FUDGE 026204 SWTCHS 026626 GREC 030744 BFSAV 031526 BUFF 032016 CMD 032306 SWBUF 032430 OPBUF 032552 STXBP 032674 PADDR 035242 TEXT 035270 002042 = 529. words (RW,I,LCL,REL,CON) UCLTBL 037332 001122 = 297. words (RW,I,LCL,REL,CON) CEALST 037336 RSALST 037400 CXSLST 040050 SEALST 040116 UCLHWC 040454 005712 = 1509. words (RW,I,LCL,REL,CON) NCHAIN 040454 CHAIN 040470 DSPLAY 040604 DSPLST 041210 ERASE 041546 LISTER 042352 NOSL 043760 SLON 044016 PASS 044120 NPATH 044422 PATH 044432 TSTDMN 044572 PROMT 044662 RECALL 044764 OPNUCL 045240 STORE 045732 UCIMOD 046242 NUCIMD 046266 CEXRTN 046366 000236 = 79. words (RW,I,LCL,REL,CON) GETCOM 046366 CSCAN 046470 CCOMP 046572 TOP 046624 Transfer address = 023024, High limit = 046622 = 9929. words &BM U77DK:UCL> UCL+ V07.55 b4 HJɋR~ 6 4%& U 4 ȋE  443M t&   B&? & >5 4 6 ن5 5  7  ^& }N@&4 : 7X 5T w5 H uɋW W: ~7" :w%ȋE43M %ȋ &@ Aa 3M %1  :4 ȋ4 !@:3M :%5 | 7 w ,<d U ` wE V 5P a=45@  : :w5* 0= wT5 wV3 7:% 87@R~JR HE <@3<5 + 5 w 0= w  Bȋ V3:& V3oeP~&  ~H  ~o CL   4Jt($: 0  eNN= w5 6& ~ AeW_U d6 l    d65V 5N wx4P58 w w ȋw 8BeH  ~ < 5+=fV3V3h* x" =  W| FW\  W^9f W0W9N&DE  v: t::  R̋  &Tv   "    R &f: 7 f ȋ  ȋ H~0@E& == Uf&@ W!<< V3 fW!HcfW0W9ɋѕ.  ,  "  :U@VAaA&P  : j53M << w*==5w@ 5 HR~U $5Հ & d6  d6ɋR ~ R W[ɋ W| W]R ~ɋW R ~ȋ  & Ћ 5&4<鈀5+f&fw5Nw:6͋ ͕=w@ $!M\7 Z7z> w:7> NH::6<^U:8r | r h  ^1  wT :W :: 80 > 8 8 5 W :W :: 80  E7|7 7  wR wj:6?f&5Z%鈀W :&:t80 "8 ZBŀ  w>5鈃 E ߋ* -<鈀 >>w@<f&W>~  eW0W7~ BEP~  vE  U <ѕ>&Ee0  M5v N:UCL> RUN ?Symbol definition? Command? Erase all symbolsErase symbol Are you sure? Symbol? Valid commands: No "run-by-name" path NOPATH "Run-by-name" path: Current symbols: Symbols defined Entries remaining CHAIN in effect to No CHAIN in effect NOCHAIN Pass-line-to-KMON in effect (UCF) (UCI_MODE) File? PROMPT PATH CHAIN ?UCL-W-Truncating symbol name to 6 charactersTruncating symbol definition to 72 charactersReplaced existing symbolErased symbol ?UCL-F-Invalid or missing option Conflicting switches Invalid command Ambiguous command Invalid DISPLAY argument Symbol definition table full Output error while updating symbol blocks Invalid argument Invalid switch Ambiguous switch Illegal file name File not found Not enough room for file Protected file already exists Read error Write error Wrong version of UCL Wrong file format UCI_MODE invalid for this monitor Symbol not found Ambiguous symbol Invalid device Unable to access LP: -- running as UCFon journal file&'D8AAfCD,AIGLPHIIIHKL:#?*?3?:?@?I?Q?W?c?l?r?z????.CHAIN.DISPLAY.ERASE.LIST.NOCHAIN.NOPATH.NOSL.NOUCI_MODE.PASS_ON.PATH.PROMPT.RECALL.SLON.STORE.UCI_MODE*ALLBINARYCOMMANDSEXECUTEFORM0JOURNALNOEXECUTENOFORM0NOQUERYNOQUIETOUTPUTPRINTERPROMPTQUERYQUIETTOSYMBOLSTERMINALVERSION&'))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) @U 4ŀE ȋ%&~=ww5<> ,^C  }PCU5U nȋ&V37dC &  P4:& 4 2ȋ FV3 "4 44W" &ыЋW"W|0 " E 43M  ? (@w}>&fC3< 3< C NɕC ~3< 5pFEd5\E T,w5BwU65,w??????@ @N/T/^/d/CGCGZGGG*CPC:C 7 D $ +}D5:4;& p׭lY B~oȕePE~ V*7nȋ 4;& 4ȋ43M ȋ 76  }D 5"#A4 5:44;& ׭Y e W!U  4鈇 |ȋ<DDn>>4w??N/T/^/d/--DDD G }G $ȋ X \43M 7"4G   LGȋ  $}LG  D5m; o!5o@7 r7 ; @7 X7 ; 7N ҕ ҕ=ҕ=e  7 j  ɕ& e:  3< 8& 03< ( ; ?@ 2 N;54; 5 U; %  < % 5$5 ,; ; ;5v< ; % z5R? h &< X% P; Fy=4wT??#??l? @@N/T/(G'LELEFFF\FbE,F5U &f6:65 x5`75w5w????@ @N/T/^/d/GGZGGGGGG FU$H5H툇wb (E$,H SET SL OFF SET SL ON5 5w߇ I > }I 6̋&7:&:6=w5%  ; tȋV3:& V3 Xȋf LV37I  2&w`@N/T/^/d/\.HII Հz&ŀr ȋ%P 43M  .&  ȋ  wҕ, >wf&@2M l@ W! E`Օ:  p&f" ɋ:% 嗨" ʕwnKUN }K  702 U(7 d:\EĝV7 RN:0  4e0Nĭ(  w"> >8>Ew&f zȋ 4<& 47 NKnTK >KVFKD>f74 ŗ* EZKwJăッ[22]=[-1]==>===w7 UEU???@N/T/^/d/dKKKKKKKK }K 87V P(77 |: 0  be^N>w8 `U7 28&:6 (< % 3< E ՀO .w ŀ;Ł K>w% n &? UXf& ŀ az ʋ: /=, & f &  f   ɋɋR ʋ .mcall vrdata vrdata UCLGRL remark= ; This program is the "front end" of the XM version of UCL+ (UCLXM.SAV). ; ; UCLXM.SAV is built in two parts: this program, and a special XM assembly ; of the UCL+ program, linked with a base address of 20000. UCLGRL is ; concatenated with the part of the UCL+ binary that starts at 20000 to form ; UCLGRL.SAV. ; ; The front end section is the only part that resides in low memory; the ; actual UCL+ executable code runs out of a global region in extended memory ; with a virtual base address of 20000. The first time that UCLXM runs after ; a boot, the loader code creates the global region, loads the UCL+ program ; into it, and commences execution. At any successive time that UCLXM is run, ; the loader merely attaches to the global region, and jumps to the start ; address. .mcall .addr, .assume, .craw, .crrg, .elrg, .exit, .gval, .map .mcall .print, .rdbbk, .readw, .settop, .wdbbk, .writw .iif ndf grl$sz, grl$sz ==: 10.*1024./32. ;Default size of global region ucl$sp ==: 1000 ;UCL code's stack pointer grl$sp ==: 1010 ;Our stack pointer userpc = 40 ;Program start address usersp = 42 ;Program initial stack pointer jsw = 44 ;Job status word ovly$ = 1000 ;Overlay bit in JSW userto = 50 ;Program high limit errbyt = 52 ;Monitor error reporting byte userrb = 53 ;User program error byte sever$ = 10 ;"Severe" error bit in USERRB tsxsiz = 56 ;SETSIZ location for TSX+ (no. of K words program requires) config = 300 ;Monitor offset to configuration word kt11$ = 10000 ;XM bit in configuration word xe.prv = 15 ;.CRRG error code: global region privately owned .asect . = usersp .word grl$sp ;Initial stack pointer value .word ovly$ ;Lie to RT-11 so chan 17 will be open into ourselves . = tsxsiz .word 1 ;If TSX+: 1 KW low memory is more than enough . = grl$sp ;Our stack goes here ; Program data area pcsav:: .word 0 ;Storage for UCL code start address spsav:: .word ucl$sp ;Storage for UCL code stack pointer jswsav::.word 0 ;Storage for UCL code job status word region: .rdbbk grl$sz, , name=ucl window: .wdbbk 1, grl$sz parea: .blkw 6 ;Argument area for plas programmed requests area: .blkw 5 ;Argument area for other programmed requests grl$nm ==: region+r.gnam ; ASCII stuff .nlist bex merpfx: .nlcsi part=prefix, type=i .ascii "F-"<200> msette: .asciz "No room" mplase: .asciz "PLAS error" mioerr: .asciz "I/O error" mcntxe: .asciz "Not XM monitor" .even .list bex start:: mov #mcntxe,r1 ;Set up for possible context error .gval #area,#config ;Get contents of CONFIG word in RMON bit #kt11$,r0 ;XM monitor? beq ferx00 ;Take error trap if not start0: .crrg #parea,#region ;Create a global region bcs plaser ;Branch on error ; We have now successfully allocated/created the global region. ; Now map it to a window, load the UCL code if necessary, and ; initiate execution of the code. mov region+r.gid,window+w.nrid ;Put region ID in the WDB .craw #parea,#window ;Create a window bcs plaser ;If error, go handle it .map #parea,#window ;Map the window to the region bcs plaser ;If error, go handle it bit #rs.new,region+r.gsts ;Did we just create the global region? bne grl$rl ;Go load UCL code, if so tst pcsav ;Make sure we have a PC value beq grl$rl ;Branch if not bis jswsav,@#jsw ;Set any extra JSW bits the UCL code wants mov spsav,sp ; and set up the user stack pointer jmp @pcsav ;Go execute UCL code ; Here we load the UCL code into the global region ; This is also the "reload" entry point. grl$rl:: call rlodr ; Now detach from global region to make it shareable. Then loop ; back and reattach to global region. call detach ;Detach from global region bcs plaser ;Branch if there is an error br start0 ;Go reattach to global region ; Routine to detach from a global region detach: .elrg #parea,#region ;Detach from global region return ; Error traps... plaser: mov #mplase,r1 ;PLAS routines enter here ferxit: bis #,region+r.gsts ;Attempt to eliminate global call detach ; region ferx00: .print #merpfx ;Print error message prefix .print r1 ;Print error message bisb #sever$,@#userrb ; indicate a severe error to system, clr r0 ; and do a hard exit... .exit ; GRL$XX is an entry point from the user program which can be used to reload ; the program's UCL code prior to taking a "fatal" exit. The address of ; an error message is assumed to be on the stack. grl$xx:: call rlodr ;Reload the UCL code mov (sp)+,r1 ;Put message address in R1 br ferx00 ;Do "fatal" exit ioerr: mov #mioerr,r1 ;.READW/.WRITW error trap br ferxit ; RLODR reads in block 0 of the concatenated UCL code file and sets up some ; pointers and data. It then reads the remainder into the global region and ; returns. relbk0 = /512.+1 rlodr:: mov #msette,r1 ;Assume possible .SETTOP error .settop #buf+510. ;Get some space for the I/O buffer cmp r0,#buf+510 ;Branch if no room (unlikely!!!)... blo ferxit mov #relbk0,r2 ;R2 = 1st block to read mov #buf,r1 ;R1 => I/O buffer .readw #area,#17,r1,#256.,r2 ;Read the UCL code block 0 bcs ioerr ;Handle errors mov jsw(r1),jswsav ;Save UCL code JSW mov userpc(r1),pcsav ;Save UCL start address .writw #area,#17,#1000,,#1 ;Save our own block 1 configuration mov userto(r1),r3 ;R3 = UCL program high limit clc ;Make high limit a word count... ror r3 sub #7777,r3 ;Adjust for 20000 base address inc r2 ;Bump block no. for UCL code read .readw #area,#17,#20000,r3,r2 ;Load UCL code's image bcs ioerr ; into global region... return ;Quit .assume . le 2000 message=<;*** LOADER CODE TOO LARGE ***> buf:: .end start ;I/O buffer starts here .MACRO CHAIN CHAIN Sets up UCL+ exit chaining SYNTAX [NO]CHAIN program-name SEMANTICS The CHAIN command allows you to specify a program for UCL+ to chain to if it is unable to interpret a given command. The original command string is passed to the specified program in the same form and fashion that the string was originally given to UCL+. NOCHAIN disables chaining; a subsequent CHAIN command with no argument restores it. OPTIONS None EXAMPLES CHAIN SY:BADWRD.SAV NOCHAIN CHAIN INSULT CHAIN UCL.DEC .ENDM .MACRO DISPLAY DISPLAY Displays a string or UCL+ command/symbol expansion SYNTAX DISPLAY[/options] command-string or DISPLAY[/options] "string["] SEMANTICS The DISPLAY command outputs the expansion of the specified UCL+ command or symbol or, if you enclose the argument with quotation marks, the indicated string is simply output "as-is", followed by a carriage-return/line-feed. If the trailing quote is omitted, no carriage control is appended (this is the preferred method for sending escape sequences to a device). OPTIONS EXECUTE Prints the expanded command and then executes it (not valid if DISPLAYing a string) FORM0 Enables formfeed before first output page to printer (default; has no effect if "SET LP FORM0" command not in effect) NOEXECUTE Suppresses command execution (default) NOFORM0 Suppresses first page formfeed action to printer PRINTER Causes output to be sent to the printer (device LP:) OUTPUT:file-spec Directs output to the specified device/file TERMINAL Directs output to the console (default) EXAMPLES DISPLAY SLON BELL==_display/printer/noform0 "^G DISPLAY "HI THERE..." .ENDM .MACRO ERASE ERASE Deletes one or more UCL+ symbols SYNTAX ERASE[/options] symbol[,...,symbol] SEMANTICS The ERASE command allows you to delete a symbol or symbols that have been previously defined via UCL+. If you specify the entire symbol name, it is deleted with no verification prompt. If you only type enough of the name to be unambiguous, you will get an "Are you sure?" prompt. Typing "ERASE *" erases all of the symbols. OPTIONS NOQUERY Causes the verification prompt to be omitted QUERY Forces verification for every deletion (default if /ALL used) EXAMPLES ERASE TEST ERASE * ERASE/NOQUERY REB,NASTY,IBM .ENDM .MACRO HELP HELP User Command Linkage-plus program (UCL+) SYNTAX command or symbol-definition or UCL command or symbol-definition or UCL UCL> command or symbol-definition SEMANTICS The UCL+ program allows on-line creation of user-defined commands (or "symbols"). It also implements a number of useful "hard-wired" commands. Symbols are defined using the format: symbol==definition If UCL+ is run directly, lower-case letters and control- characters can be included in the symbol definition. (See the UCL+ documentation and the Software Support Manual for usage and operational details.) COMMANDS (hard-wired; type "HELP command" for more details) CHAIN/NOCHAIN Sets up CHAINing to an additional "UCL" DISPLAY Displays a string or command expansion ERASE Deletes a symbol or symbols LIST Lists symbol definitions and various UCL+ parameters NOSL Turns the single-line editor off PASS_ON Targets a command to a specific "UCL" PATH/NOPATH Sets up the "run-by-name" path PROMPT Sets the UCL+ command-line prompt string RECALL Loads a previously STOREd set of symbol definitions and parameters RELOAD (XM version only) Reloads a UCL+ global region SLON Turns the single-line editor on STORE Saves the current UCL+ symbol definitions and program parameters UCI_MODE/NOUCI_MODE (TSX-Plus only) Causes UCL+ to pass unrecognized lines to the keyboard monitor EXAMPLES LIST COMMANDS REBOOT==BOOT SY: UCI_MODE "MYKMON> " UCL UCL> bill==$@wrk:bill UCL> nosl UCL> bell==_display "^G UCL> ^C .ENDM .MACRO LIST LIST Lists the current UCL+ commands/symbols/status SYNTAX LIST[/options] [arguments] SEMANTICS The UCL+ LIST command lists the program version, "hard-wired" commands, currently defined symbols, CHAIN assignment/status, UC handler status, and run-by-name path to a specified device or file. If you type a LIST command with no arguments, the symbols are listed. If you omit the output specification, output is directed to the console. OPTIONS FORM0 Enables formfeed before first output page to printer (default; has no effect if "SET LP FORM0" command not in effect) NOFORM0 Suppresses first page formfeed action to printer OUTPUT:filespec Sends output to the specified device/file PRINTER Sends output to the printer (device LP:) TERMINAL Sends output to the console (default) ARGUMENTS ALL Lists commands, symbols, chain data, and path list (same as LIST *) CHAIN Lists the chain data COMMANDS Lists the "hard-wired" commands PATH Lists the current "run-by-name" path SYMBOLS Lists the current symbol definitions (default) VERSION Lists the program name and version EXAMPLES LIST/PRINTER ALL LIST LIST COMMANDS,SYMBOLS .ENDM .MACRO NOSL NOSL Turns the single-line editor off (UCL+ command) SYNTAX NOSL SEMANTICS The NOSL command can have either a "global" or "local" effect. If you run UCL+ directly (i.e., you have a "UCL>" prompt), the single-line editor is only turned off within the UCL+ program. This is particularly handy if you need to include characters in a symbol definition that would be intercepted by the single-line editor. If you type the NOSL command at the monitor level, it is equivalent to a "SET SL OFF" command. (See also the SLON command.) OPTIONS None EXAMPLES NOSL .ENDM .MACRO PASS_ON PASS_ON Passes a command string to a program "UCL-style" SYNTAX PASS_ON[/TO:program-name] command-string SEMANTICS This command tells UCL+ to pass the specified command-string on to the program that you specified via the CHAIN command. If you include a "program-name", then the command is passed to this program instead. Note that the command is passed "UCL-style". OPTIONS TO:program-name Causes the command-string to be passed to the specified program EXAMPLES PASS_ON XYZZY PASS_ON REMARK==DISPLAY "HELLO SAILOR" PASS_ON/TO:BADWRD LIST SYMBOLS .ENDM .MACRO PATH PATH Sets up the UCL+ "run-by-name" path SYNTAX [NO]PATH device[,...,device] SEMANTICS If UCL+ does not know a given command, it follows the device list set up with the PATH command in attempting a "run-by- name". You can establish a list of up to about 20 device mnemonics. NOPATH disables "run-by-name"; a subsequent PATH command with no argument restores it. OPTIONS None EXAMPLES PATH DK:,DY1: PATH DZ0,LD1 NOPATH .ENDM .MACRO PROMPT PROMPT Sets the UCL+ command-line prompt string SYNTAX PROMPT ["]prompt-text["] SEMANTICS Changes the prompt string issued by UCL+ when it is run directly. The maximum length of the prompt is eight characters. The prompt- text may optionally be enclosed with quotes. A PROMPT command issued with no prompt-text argument restores the default prompt ("UCL> "). OPTIONS None EXAMPLES PROMPT "MYSTUF> " PROMPT PROMPT $ .ENDM .MACRO RECALL RECALL Loads symbol definition and status tables into UCL+ SYNTAX RECALL[/options] filespec SEMANTICS Recalls (loads) the UCL+ symbol definition and status area from a file that has previously been created with the STORE command. The default device for this file is DK: and the default extension is .UCL (.UCX if using the special XM version of UCL+). If the /JOURNAL option is used, the default extension is .UCJ. OPTIONS BINARY Recall a binary format file (default) JOURNAL Recall a file created in "journal" mode NOQUIET Used with /JOURNAL to allow input lines to be echoed to the console QUIET Used with /JOURNAL to suppress output to the console (default) EXAMPLES RECALL SY:UCL RECALL/JOURNAL BADWRD .ENDM .MACRO RELOAD RELOAD Reloads a UCL+ global region (XM version only) SYNTAX RELOAD SEMANTICS The RELOAD command is valid only for the XM version of UCL+. It forces a reload of the UCL+ executable image into the applicable global region in extended memory. OPTIONS None EXAMPLES RELOAD .ENDM .MACRO SLON SLON Turns the single-line editor on (UCL+ command) SYNTAX SLON SEMANTICS The UCL+ SLON command is equivalent to typing "SET SL ON". (See also the NOSL command.) OPTIONS None EXAMPLES SLON .ENDM .MACRO STORE STORE Saves the UCL+ symbol definition and status tables SYNTAX STORE[/option] FILESPEC SEMANTICS Causes the UCL+ program's symbol/status blocks to be written to the specified file. The default device for this file is DK: and the default extension is .UCL (.UCX if using the special XM version of UCL+). If the /JOURNAL option is used, the default extension is .UCJ. OPTIONS BINARY Store the symbol/status data in binary form (default) JOURNAL Store the symbol/status data in "journal" format EXAMPLES STORE SY:UCL STORE/JOURNAL BADWRD .ENDM .MACRO UCI_MODE UCI_MODE Set UCL+ "pass-line-to-KMON" mode (TSX-Plus only) SYNTAX [NO]UCI_MODE ["]prompt-text["] SEMANTICS Causes UCL+ to pass unrecognized lines to the keyboard monitor. I.e., UCL+ acts as a "User Command Interpreter" (UCI). Replacement text for the UCL+ command line prompt may be included. The default is to use/restore the normal prompt (see also the PROMPT command). NOUCI_MODE restores the previously set CHAINing mode. When UCI_MODE is in effect, hard-wired commands must be preceded by a "prefix character" (the default is a ".") to be recognized by UCL+. OPTIONS None EXAMPLES UCI_MODE "MYUCI> " UCI_MODE .NOUCI_MODE .NOUCI_MODE $ .ENDM .MACRO UCL UCL User Command Linkage-plus program (UCL+) SYNTAX command or symbol-definition or UCL command or symbol-definition or UCL UCL> command or symbol-definition SEMANTICS The UCL+ program allows on-line creation of user-defined commands (or "symbols"). It also implements a number of useful "hard-wired" commands. Symbols are defined using the format: symbol==definition If UCL+ is run directly, lower-case letters and control- characters can be included in the symbol definition. (See the UCL+ documentation and the Software Support Manual for usage and operational details.) COMMANDS (hard-wired; type "HELP command" for more details) CHAIN/NOCHAIN Sets up CHAINing to an additional "UCL" DISPLAY Displays a string or command expansion ERASE Deletes a symbol or symbols LIST Lists symbol definitions and various UCL+ parameters NOSL Turns the single-line editor off PASS_ON Targets a command to a specific "UCL" PATH/NOPATH Sets up the "run-by-name" path PROMPT Sets the UCL+ command-line prompt string RECALL Loads a previously STOREd set of symbol definitions and parameters RELOAD Reloads a UCL+ global region SLON Turns the single-line editor on STORE Saves the current UCL+ symbol definitions and program parameters UCI_MODE/NOUCI_MODE Causes UCL+ to pass unrecognized lines to the keyboard monitor (TSX-Plus only) EXAMPLES LIST COMMANDS REBOOT==BOOT SY: UCI_MODE "MYKMON> " UCL UCL> bill==$@wrk:bill UCL> nosl UCL> bell==_display "^G UCL> ^C .ENDM .MACRO .99999 .ENDM .sbttl "HARD-WIRED" COMMANDS ; ===================== ; Command Execution Routines ; -------------------------- ; ; This is a collection of routines that illustrate some of the types of ; things that you can do with "hard-wired" commands. Some of them might not ; be useful to you. You can get rid of them by editing them out completely ; (don't forget the reference string and the entries in the tables CEALST and ; RSALST) or, more simply, just remove the appropriate CEALST and RSALST ; table entries and leave the code lying around for reference. In some cases, ; (the RNO command, for example) the command routines can be included or ; eliminated by supplying the appropriate conditional during assembly. .psect uclhwc .sbttl . chain, nochain ; "Set Up Exit-On-Bad Command Chain" [NO]CHAIN file-spec ; ===== .enabl lsb nchain:: call 40$ ;NOCHAIN enters here bis #bit15,chanto br 30$ chain:: call 40$ bicb #ucimd,pflags ;Disable UCI_MODE bic #bit15,chanto ;Restore possible chaining data call adjr0 ;Skip leading blanks tstb (r0) ;Null file name? beq 30$ ;Branch if so mov #chanto,r1 ;R1 => filename buffer for CHAIN mov #15.,r2 ;R2 = max. length for filename push r0 ;Save buffer pointer 10$: movb (r0)+,(r1)+ ;Move filename to CHAIN filename buffer... beq 20$ sob r2,10$ pop r4 ;Oops! filename too long... mov #millfn,r5 15$: jmp ferrx 20$: pop r0 ;Clean up stack and 30$: jmp wtstbl ; go write out changes 40$: bit #ucfmd,status ;Running as UCF? bne 50$ ;Go gripe if so return 50$: mov #mbad,r5 ;"Invalid command -- running as UCF"... mov #mrucf,r4 br 15$ .dsabl lsb .sbttl . display ; "Display Command Expansion" DISPLAY command-string ; ======= /EXECUTE ; /NOEXECUTE ; /FORM0 ; /NOFORM0 ; /PRINTER ; /OUT:file-spec ; /TERMINAL dsplay:: call plinit ;Init PLINE routine mov sp,dspsp ;Save current stack pointer value mov #dsparl,r4 ;R4 => arg. list for switches call swtchs ;Check for switches tst r5 ;Any errors? bpl 10$ ;Branch if not mov dspsp,sp ;Clean up stack and jmp @dspsea(r5) ; go handle errors 10$: bis #dspla,status ;Set display bit in status bit #exe,swstat ;"/EXECUTE"? beq 20$ ;Branch if not bis #dsplx,status ;Set display+execute bit in status 20$: call adjr0 30$: tstb (r0) ;Command entered? beq 35$ ;Branch if not push r0 ;Stash this pointer .getcom #bfsav,#scrach+2,#dstmtb ;Find unmodified argument... call adjr0 mov r0,r1 ;Save this pointer pop r0 ;Restore BUFF pointer br 40$ 35$: .gtlin #buff,#dspqry ;"Command?" mov #buff,r0 ;R0 => input buffer call adjr0 ;Skip leading blanks tstb (r0) ;Null string? beq 35$ ;Branch if so call qtproc ;Do quote processing mov #bfsav,r0 ;Skip leading blanks in raw string... call adjr0 mov r0,r1 ;Save the pointer mov #buff,r0 ;Skip leading blanks in "quoted" string... call adjr0 40$: mov #buff,r2 ;Left justify remainder of input buffer... 50$: movb (r0)+,(r2)+ bne 50$ mov #buff,r0 ;R0 => "quoted" command string cmpb (r1)+,#'" ;Just print the line? bne 90$ ;Branch if not inc r0 ;Skip leading " push r0 ;Save R0 60$: tstb (r1)+ ;Find end of unmodified text... bne 60$ 65$: tstb (r0)+ ;Also find end of "quoted" text... bne 65$ cmpb -2(r1),#'" ;Last character a " ? bne 70$ ;Branch if not cmpb -3(r1),#'| ;Has trailing " been quoted? beq 70$ ;Branch if so clrb -2(r0) ;Replace " with null in "quoted" string 70$: movb #200,-(r0) ;Replace null with 200 byte (no cr/lf) pop r0 ;Restore R0 .prlin ;Print remainder of input line... .prlin #0 bic #dspla!dsplx,status ;Zap any display bits in status word return 90$: mov #r0,savr0 ;Save buffer pointer .getcom ,#cmd ;Cause command execution (ensure rest of call clencm ; buffer pointers reset)... .cscan ,#rsalst tstb cxslst(r5) bmi 100$ jmp baddsp 100$: jmp @cealst(r5) ; This routine lists a command expansion. On entry, R0 contains the byte ; count and R1 the text address. It forces a return to the mainline unless ; the display+execute bit is set in STATUS. dsplst:: push ;Save R0 - R3... mov r0,r2 ;Put byte count in r2 mov r1,r3 ;Put input pointer in R3 .prlin #crlf ;Print a blank line 10$: movb (r3)+,r0 ;Get a character bne 20$ ;Branch if not null .prlin #crlf ;Print a CR/LF... br 40$ 20$: mov #ctrlch,r1 ;R1 => output buffer call bytasc ;Produce output character(s) movb #200,(r1) ;No cr/lf .prlin #ctrlch ;Print the character(s) 40$: sob r2,10$ ;If not done, go do another .prlin #crlf ;Print a blank line .prlin #0 ;Clean up any remaining output pop ;Restore R3 - R0... bit #dsplx,status ;Go ahead and execute the command? bne 60$ ;Branch if so mov dspsp,sp ;Nope, reset stack 50$: bic #,status ;Ensure display, execute bits clear return ; and return 60$: bit #ximm,status ;Execute immediate? beq 50$ ;Branch if not bic #,status ;Kill display bits mov dspsp,sp ;Reset stack jmp sypxim ;Return via execute immediate code .nlist bex ctrlch: .asciz "" ;Reserve enough room to display .list bex ; eight-bit/control characters .even ; Switch routines: dspexs: bit #nex,swstat ;Switch conflict? bne dspcsw ;Branch if so jmp swbits ;Go set bit in SWSTAT otherwise dspcsw: bis #cnswer,swstat ;Set "conflicting switches" flag sec ;Set carry and return ; return dspnxs: bit #exe,swstat ;Switch conflict? bne dspcsw ;Branch if so jmp swbits ;Go set bit in SWSTAT otherwise dspsp: .word 0 ;Save area for stack pointer ; Reference string address list for switches: dsprsa: .word exesw .word frmsw .word nexsw .word nfrmsw .word outsw .word prnsw .word trmsw .word 0 ; Switch status bit list: dspssb: .word exe .word fm0 .word nex .word nf0 .word out .word prn .word trm ; String execution address list: .word badopx .word cnfswx .word badswx .word ambswx dspsea: .word dspexs .word lisfm0 .word dspnxs .word lisnf0 .word lisout .word lisprn .word listrm ; Argument list for SWTCHS call: dsparl: .word dsprsa .word dspsea .word dspssb dstmtb: .asciz " " ;Terminator table for .GETCOM call .sbttl . erase ; "Erase A Symbol" ERASE sym1,sym2,... ; ===== /NOQUERY ; /QUERY sbksiz = /2 erase:: clr wrnmad ;Clear warning message buffer mov #ersarl,r4 ;R4 => switch processing argument list call swtchs ;Check for and flag switches tst r5 ;Any errors? bpl er1sym ;Branch if not jmp @erseal(r5) ;Go handle errors ; Erase all symbols... eralt: bit #noq,swstat ;"/NOQUERY"? bne 10$ ;Branch if set .print #eraqry ;"Erase All Symbols" .gtlin #buff,#rusure ;"Are You Sure?" bicb #40,buff ;"Y"-for-yes?... cmpb buff,#'Y beq 10$ ;Branch if so return 10$: mov #sdsat,r0 ;Clear entire symbol area... mov #sbksiz,r1 20$: clr (r0)+ sob r1,20$ mov #sdsbfr,r0 ;Insert "string deleted" bytes... mov #nsyms,r1 30$: movb #377,(r0) add #lsyms,r0 sob r1,30$ call wtstbl ;Write changes to SAV image and return ; return ; Erase one symbol at a time... .enabl lsb er1sym: call adjr0 ;Skip any blanks cmpb (r0),#'* ;Erase all? beq eralt ;Branch if so mov r0,savr0 ;Save input buffer pointer tstb (r0) ;Null byte? bne 10$ ;Branch if not .gtlin #buff,#er1qry ;"Symbol?" mov #buff,r0 tstb (r0) ;Null response? bne er1sym ;Branch if not return ;Return otherwise 10$: .getcom ,#cmd ;Extract symbol from input string tstb (r0) ;Last symbol in list? beq 20$ ;Branch if so inc r0 ;Skip separator 20$: mov r0,savr0 ;Save pointer .cscan ,#sdsat ;Try to find entry we want to erase tst r5 ;Find it? bpl 30$ ;Branch if so jmp @er1erx(r5) ;Go handle errors 30$: tst r3 ;Find an exact match? beq 40$ ;Branch if so bit #noq,swstat ;"/NOQUERY" bit set? bne 60$ ;Branch if it is mov sdsat(r5),r1 ;R1 => symbol definition string mov #cmd,r2 ;R2 => command buffer mov #6,r3 ;R3 = max. no. characters to copy call ccopy ;Copy full name of symbol into command buffer clrb (r2) ;Terminate with null br 50$ ;Go ask about this 40$: bit #qry,swstat ;"/QUERY"? beq 60$ ;Branch if not 50$: .print #ersqry ;"Erase Symbol...?" .print #cmd .gtlin #buff,#rusure ;"Are You Sure?" bicb #40,buff ;"Y"-for-yes?... cmpb buff,#'Y bne eraseq ;Branch if not 60$: add #sdsat,r5 ;R5 => symbol string address movb #377,@(r5) ;Flag string entry as deleted 70$: clr (r5) ;Clear address entry cmp r5,#sdsatl ;Last entry in table? beq eraseq ;Branch if so mov 2(r5),(r5)+ ;Shift up next address entry br 70$ ;Go shift next one eraseq: call wtstbl ;Write changes to SAV image tst wrnmad ;Doing "erase by name"? beq 80$ ;Branch if not call wrngm ;"UCL-W-Erased Symbol xxxxxx"... .print #cmd return 80$: mov savr0,r0 ;Get pointer to next symbol name call adjr0 ;Skip leading blanks tstb (r0) ;End of list? bne 10$ ;Branch if not return ; Entry for "erase by name"... er1sy0: mov #erawrn,wrnmad ;Set up for erase warning message br 60$ ;Go do it .dsabl lsb ; Error traps for ERASE .word er1erx .word er1er0 er1erx: mov #er1nfm,r5 ;"Symbol Not Found..." br er1er1 er1er0: mov #er1amm,r5 ;"Ambiguous Symbol..." er1er1: mov #cmd,r4 jmp ferrx ; Switch reference string address list for ERASE: ersal: .word noqsw .word qrysw .word 0 ; Switch status bit list for ERASE: erssbl: .word noq .word qry ; Switch execution address list: .word badopx .word cnfswx .word badswx .word ambswx erseal: .word swbits .word swbits ; Argument list for SWTCHS call: ersarl: .word ersal .word erseal .word erssbl .sbttl . list ; "List Current UCL Commands" LIST arg1,arg2,... ; ==== /OUT:file-spec ALL ; /PRINTER CHAIN ; /TERMINAL COMMANDS ; /FORM0 PATH ; /NOFORM0 SYMBOLS ; VERSION lister:: call plinit ;Init PLINE routine mov #liswal,r4 ;R4 => argument list for SWTCHS call call swtchs ;Check for switches tst r5 ;Any errors? bpl 10$ ;Branch if not jmp @liswel(r5) ;Handle errors 10$: call adjr0 ;Skip any intervening blanks in input string tstb (r0) ;Null argument? bne 30$ ;Branch if not call lists ;Force default to "LIST SYMBOLS" 20$: .prlin #0 ;Clean up any remaining output return ;Quit 30$: .getcom ,#cmd ;Move argument to command buffer mov r0,savr0 ;Save input buffer pointer .cscan ,#lisal ;Look for valid argument tst r5 ;Invalid argument? bmi 40$ ;Branch if so call @liseal(r5) ;Go execute appropriate routine mov savr0,r0 ;Restore input buffer pointer tstb (r0) ;Done? beq 20$ ;Branch if so inc r0 ;Point at next argument br 30$ ;Go handle it 40$: .prlin #0 ;Clean up any remaining output jmp @liseal(r5) ;Go handle errors lista: ;"LIST ALL"... call listv ;List version call listc ;List commands call lists ;List symbols call listp ;List path call listx ;List chain return lists: ;"LIST SYMBOLS"... bit #jrnlo,status ;Journaling active? bne 5$ ;Branch if so .prlin #listsm ;"Current Symbols" 5$: mov #nsyms,r5 ;R5 = max. no. symbols mov #sdsat,r4 ;R4 => SDS addr. table 10$: mov (r4)+,r1 ;R1 => next string address bne 20$ ;Branch if not end of table bit #jrnlo,status ;If journaling, just quit... bne 15$ mov #nsyms,r0 ;R0 = max. no. symbols sub r5,r0 ;Make R0 = no. symbols defined mov #scrach,r1 ;R1 => scratch buffer (for ASCII decimal) call binasc ;Convert to ASCII .prlin #scrach ;"nnn Symbols Defined"... .prlin #listsd mov r5,r0 ;R0 = no. remaining entries mov #scrach,r1 ;R1 => buffer for ASCII call binasc ;Convert to ASCII .prlin #scrach ;"nnn Entries Remain"... .prlin #listse 15$: return ;Quit 20$: mov #scrach,r2 ;R2 => buffer for output string mov #,r3 ;R3 = max. no. characters to copy mov #-7,r0 ;R0 counts no. of characters copied call ccopy ;Copy symbol part to buffer br 40$ 30$: movb #space,(r2)+ ;Pad to 6 characters with blanks... 40$: inc r0 bne 30$ 50$: movb #'=,(r2)+ ;Insert "=="... movb #'=,(r2)+ mov r2,r1 ;Put output pointer in R1 mov -2(r4),r2 ;Copy definition part (expand non-printing add #,r2 ; stuff into "" format)... 60$: movb (r2)+,r0 beq 80$ call bytasc dec r3 bne 60$ 80$: clrb (r1) ;Terminate with null .prlin #scrach ;Print result dec r5 ;Adjust counter br 10$ ;Go get next string ; Routine to convert a binary value in R0 to a decimal ASCII string. ; On entry, R1 points at the output buffer. On return, R1 points at ; a terminating 200 byte. binasc: call 10$ ;Call conversion routine movb #200,(r1) ;Add terminating byte return ;Quit 10$: push r0 ;Binary to decimal ASCII conversion clr r0 ; routine... 20$: inc r0 ;Stolen from page 2-67 of the V5 sub #10.,(sp) ; Programmer's Reference Manual bge 20$ add #72,(sp) dec r0 beq 30$ call binasc 30$: movb (sp)+,(r1)+ return .enabl lsb listv: .prlin #crlf ;List program name/version... .prlin #vrshun 30$: .prlin #crlf return listc: ;"LIST COMMANDS"... .prlin #listcm ;"Valid Commands:" mov #rsals0,r1 ;R1 => Reference String Address List; skip "?" 40$: mov (r1)+,r0 ;Point R0 at a string beq 30$ ;Go quit if we've hit end of list .prlin ;Print the string br 40$ ;Go look for the next one listp: ;"LIST PATH" tstb pthbuf ;Do we have anything to list? bgt 50$ ;Branch if so mov #listpj,r0 ;Assume we are journaling bit #jrnlo,status ;Journaling? bne 45$ ;Branch if so mov #listp0,r0 ;Otherwise, use LIST-style test 45$: .prlin ;"No Run-by-name path" / "NOPATH" ... return 50$: bit #jrnlo,status ;Journaling?... bne 55$ .prlin #listpm ;"Run-by-name" path:" .prlin #pthbuf ;Print the path... br 30$ 55$: .prlin #pthmsg ;"PATH " .prlin #pthbuf ;Print the path... return listx: bit #jrnlo,status ;Journaling? bne 80$ ;Branch if so bit #,status ;Branch if UCF/UCI_MODE in effect... bne 60$ tst chanto ;Is CHAIN in effect? bgt 70$ ;Branch if so .prlin #listx0 ;"No CHAIN In Effect" br 30$ 60$: .prlin #listxu ;"Pass-Line-To-KMON In Effect..." mov #listxf,r0 ;Assume running as UCF bit #ucimd,status ;UCI_MODE? beq 65$ ;Go print message if not mov #listxi,r0 ;R0 => "(UCI_MODE)" 65$: .prlin ;Print the text br 30$ 70$: .prlin #listxm ;"CHAIN In Effect To..." .prlin #chanto br 30$ ; Journal code... 80$: .if ne uci$c bit #ucimd,status ;UCI_MODE? beq 90$ ;Branch if not .prlin #sucimd ;"UCI_MODE" return ;Quit .endc 90$: tst chanto ;Chaining turned on?... ble 95$ ;Branch if not .prlin #chnmsg ;"CHAIN " .prlin #chanto ;List chain file name return ; and quit 95$: .prlin #listxj ;"NOCHAIN"... return .dsabl lsb badarg: mov #mbadrg,r5 ;Issue "?UCL-F-Invalid Argument"... mov #cmd,r4 jmp ferrx ;Take "fatal" error exit ; Reference string address list for LIST: lisal: .word star .word allsw .word schain .word comsw .word spath .word symsw .word versw .word 0 ; Argument execution address list for LIST: .word badopx .word cnfswx .word badarg .word ambcom liseal: .word lista .word lista .word listx .word listc .word listp .word lists .word listv ; Switch handling routines... lisout: bit #,swstat ;Any switch conflicts? beq lisou0 ;Branch if not liscns: bis #cnswer,swstat ;Return with error sec return lisou0: call outsr ;Go handle switch bcc lisscp ;If no errors, go set up output file name return lisscp: push ;Save R0, R1 mov #outfnm,r0 ;Move file name from OUTFNM to PRLFNM... mov #prlfnm,r1 10$: movb (r0)+,(r1)+ bne 10$ pop ;Restore R1, R0 return lisprn: bit #,swstat ;Any switch conflicts? bne liscns ;Branch if so call prntsr ;Go handle switch bcc lisscp ;If not errors, stick "LP:" in PRLFNM buffers return listrm: bit #,swstat ;Any switch conflicts? bne liscns ;Branch if so clrb prlfnm ;Just do .PRINT's... clc return lisfm0: bit #nf0,swstat ;Any switch conflicts? bne liscns ;Branch if so jmp frmsr ;Go handle switch otherwise lisnf0: bit #fm0,swstat ;Any switch conflicts? bne liscns ;Branch if so jmp nfrmsr ;Go handle switch otherwise ; Switch Reference String Address List for LIST liswrs: .word frmsw, nfrmsw, outsw, prnsw, trmsw, 0 ; Switch Status-Bit List liswbl: .word fm0, nf0, out, prn, trm ; Switch Execution Address List .word badopx .word cnfswx .word badswx .word ambswx liswel: .word lisfm0 .word lisnf0 .word lisout .word lisprn .word listrm ; Argument List for SWTCHS call liswal: .word liswrs, liswel, liswbl .sbttl . nosl, slon ; "SL editor on/off" NOSL or SLON ; ==== ==== ; These commands turn the single-line editor off/on. ; ; If UCL is RUN directly, the effect is to toggle SL locally. This assumes, ; of course, that SL was installed and turned on prior to running UCL and that ; SL is enabled for use by user programs. ; ; If NOSL or SLON is entered via the monitor, the effect is the same as ; typing, respectively, SET SL OFF or SET SL ON. .enabl lsb nosl:: call dsptst ;Check DISPLAY,RUN status bis #edit$,@#jsw ;Set "disable SL" bit in JSW mov #nosltx,r1 ;R1 => "SET SL OFF" 10$: bit #runc,status ;Were we RUN? beq 30$ ;Branch if not 20$: .rctrlo ;Ensure JSW updated return 30$: jmp setcmd ;Pass command to monitor slon:: call dsptst ;Check DISPLAY,RUN status bic #edit$,@#JSW ;Allow program to use SL mov #slontx,r1 ;R1 => "SET SL ON" br 10$ ;Go take appropriate action .nlist bex nosltx: .word 50$-40$ 40$: .asciz /SET SL OFF/ 50$: .byte 0 .even slontx: .word 70$-60$ 60$: .asciz /SET SL ON/ 70$: .byte 0 .even .list bex .dsabl lsb dsptst: bit #dspla,status ;DISPLAY active? beq 10$ ;Branch if not bit #runc,status ;Were we RUN? beq 10$ ;Branch if not jmp baddsp ;Complain if both true 10$: return .sbttl . pass_on ; "Pass-on Command To Next (or another) Program" PASS_ON command ; ======= /TO:program-name ; This command tells UCL to pass the specified command- ; string on to the program that you specified via the ; CHAIN command. If you specify a "program-name", then ; the command is passed to this program instead. If ; CHAINing is not in effect, and you failed to specify ; a program to chain to, you get your hand slapped with ; "UCL-F-No CHAIN In Effect". ; ; Note that the command string is passed "UCL-style" ; (byte count at location 510, string starting at 512) ; not "run-by-name" style. pass:: mov #pasarl,r4 ;Check for /TO: switch... call swtchs tst r5 ;Errors? bpl 10$ ;Branch if not jmp @passea(r5) ;Go handle errors 10$: tst swstat ;/TO: invoked? beq 50$ ;Branch if not mov #outfnm,r4 ;R4 => file-spec tstb (r4) ;Null file-spec? beq 30$ ;Branch if so 15$: push r0 ;Save R0 and mov sp,spsav ; current stack pointer .csispc #scrach,#dext,r4 ;convert filename to RAD50, lazy way mov spsav,sp ;Restore stack pointer pop r0 ; and R0 (carry unaffected) bcs 20$ ;Branch on error br 60$ ;Everything looks OK, proceed 20$: mov #prlfnm,r4 ;Oops! Bad file name... 30$: mov #millfn,r5 40$: jmp ferrx 50$: bit #,status ;UCF/UCI_MODE in effect? bne 55$ ;Branch if so mov #chanto,r4 ;Is there a file-spec for chaining?... tst (r4) bpl 15$ ;If so, go set up the RAD50 for the chainer 55$: clr r4 ;"No CHAIN In Effect"... mov #listx0+2,r5 br 40$ 60$: call adjr0 ;Skip any intervening blanks tstb (r0) ;Null command string? bne 70$ ;Branch if not 65$: .gtlin #bfsav,#dspqry ;"Command?" mov #bfsav,r0 ;R0 => command-string call adjr0 ;Skip any intervening blanks tstb (r0) ;Null command string? beq 65$ ;Branch if so br 75$ ;Otherwise, go pass it to chainer 70$: push r1 ;Find address of original argument text... call adjr0 .getcom #bfsav,#scrach+2,#patmtb pop r1 call adjr0 ;Skip leading blanks 75$: push r0 ;Put result where chain code can find it jmp chanr0 ;Go hand off to chainer pasrsa: .word tosw ;Reference string address for switch .word 0 .word badopx ;Switch execution address list .word cnfswx .word badswx .word ambswx passea: .word outsr ;(use /OUT switch code) passsb: .word 1 ;Switch status bit pasarl: .word pasrsa ;Argument list for SWTCHS call .word passea .word passsb patmtb: .asciz " " ;Terminator table for .GETCOM call .sbttl . path, nopath ; "Set Up 'Run-by-name' Search Path" [NO]PATH dev1,dev2,... ; ==== ; If a command or symbol is not found, UCL follows the ; list of devices set up with the PATH command in ; attempting a "run-by-name". ; The limit is about 20 device mnemonics. comma = 054 .enabl lsb npath:: bisb #bit7,pthbuf ;NOPATH enters here... br 45$ path:: bicb #bit7,pthbuf ;Restore possible path list call adjr0 ;Skip leading blanks tstb (r0) ;Null list? beq 45$ ;Branch if so mov #20.,r4 ;R4 = max. no. of devices mov #pthbuf,r2 ;R2 => path buffer mov #80.,r3 ;R3 = max. no. bytes to copy 30$: call adjr0 ;Get a mnemonic... .getcom ,#cmd call tstdmn ;Check it bcs 60$ ;Branch on error push r0 ;Copy mnemonic to path buffer... call ccopy pop r0 call adjr0 ;If end of list, go quit... tstb (r0) beq 40$ inc r0 ;Skip separator (comma presumably) dec r4 ;Adjust device count bne 50$ ;Branch if still room 40$: clrb (r2) ;Add terminating null 45$: jmp wtstbl ;Go write changes 50$: movb #comma,(r2)+ ;Stick in a comma br 30$ ;Go get next device name 60$: clr r4 ;"Illegal Device"... mov #dmnerr,r5 jmp ferrx .dsabl lsb ; Routine to check a device mnemonic and force a colon on the end. ; ; On entry: ; R1 => device mnemonic ; ; On return: ; R1 is unchanged ; carry is set if mnemonic too long or too short ; carry is clear if no error tstdmn:: push ;Save R5, R0 .getcom r1,,#tmtblc ;Trim possible ":"... mov r1,r0 ;Get length of mnemonic... call len pop r0 ;Restore R0 cmp r5,#3 ;Check for valid length... bgt 10$ tst r5 bgt 20$ 10$: pop r5 ;Error: restore R5, sec ; set carry, and return ; return 20$: add r1,r5 ;R5 => end of mnemonic movb #':,(r5)+ ;Put ":" on end and clrb (r5) ; trailing null pop r5 ;Restore R5 clc ; clear carry, and return ; return .sbttl . prompt ; "Set new UCL prompt" PROMPT prompt-text ; ====== ; PROMPT replaces the current UCL+ prompt string with ; a new one. If no prompt-text is entered the default ; ("UCL> ") is restored. promt:: call adjr0 ;Skip leading blanks push ;Save working registers cmpb (r0),#'" ;Skip optional " mark... bne 20$ inc r0 20$: mov r0,r1 ;R1 => prompt-text tstb (r1) ;If no text, use default... bne 30$ mov #dfpmt,r1 30$: mov #prompt,r2 ;R2 => prompt buffer mov #8.,r3 ;R3 = maximum allowable length call ccopy ;Copy the prompt-text cmpb -(r2),#'" ;Zap optional " mark... beq 40$ inc r2 40$: movb #200,(r2) ;Terminate with 200 byte (no cr/lf) pop ;Restore registers jmp wtstbl ;Preserve changes .sbttl . reload .if ne ucl$xm ; "Reload the Global Region from the SAV Image" RELOAD ; ====== ; Loads the UCL global region from the SAV image of the program currently ; running and then restarts UCL. Among other things, this is a sneaky way ; to load different program images into the global region without REMOVEing ; the region. reload:: bit #jrnli,status ;Is dummy RELOADing during journaling? beq 10$ ;Branch if not mov #milrel,r5 ;R5 => "RELOAD invalid while journaling" clr r4 jmp ferrx ;Take fatal error exit 10$: clr @#bytcnt ;Keep ourselves from looping forever jmp @#grl$rl ;Jump to the global loaders reload entry ; point... .endc .sbttl . recall ; "Recall Symbol Definition and Status Tables" RECALL file-spec ; ====== /BINARY ; /JOURNAL ; /[NO]QUIET ; ; Recalls (loads) the symbol definition and status area from a file that ; has previously been created with the STORE command. The default device ; is DK: and the default extension is .UCL (ie, DK:filnam.UCL where "filnam" ; is the file name you specify). The /NOQUIET switch is used to enable ; echoing of input lines to the console during journaling. The default is ; /QUIET. ; ; If the /JOURNAL switch is in effect, the default output file extension ; is .UCJ. ; ; The XM version of UCL defaults to a .UCX extension for non-journal files. recall:: mov #srcarl,r4 ;R4 => argument list for SWTCHS call bis #jrnlq,status ;Assume /QUIET call swtchs ;Look for /JOURNAL, etc. tst r5 ;Any errors? bpl 5$ ;Branch if not jmp @srcsea(r5) ;Go handle switch error 5$: call adjr0 ;Point at the file name clr r5 ;Open the file... call opnucl mov r0,savr0 ;Save file name pointer tstb swstat ;/JOURNAL? bpl 8$ ;Branch if not bis #jrnli,status ;Set journal mode input flag clr rblksv ;Init variables for GREC routine... mov #ibufr+512.,ibptr return ;Quit 8$: bic #jrnlq,status ;Remove possible /QUIET flag movb vznrls,r4 ;Get current version... clr wblok ;Load symbol definition/status stuff from mov #sdsat,wbufa ; file... mov #nbloks,r5 10$: .readw #area,#3 bcs 30$ inc wblok add #512.,wbufa sob r5,10$ cmpb vznrls,r4 ;Loaded stuff same release? bne 20$ ;Branch if not bitb #uclxm,pflags ;Test for XM version bit... .iif eq ucl$xm bne 35$ .iif ne ucl$xm beq 35$ .close #3 ;Close the input channel jmp wtstbl ;Go update UCL.SAV ; error traps... 20$: mov #vrerr,r5 ;R5 => "Wrong Version..." br 40$ ;Go take error exit 30$: mov #rclerr,r5 ;R5 => "Read Error..." br 40$ ;Go take error exit 35$: mov #minvff,r5 ;"Wrong file format..." 40$: .close #3 ;Make sure input channel closed .if eq ucl$xm mov savr0,r4 ;R4 => input file name (as entered) bic #runc,status ;Force an exit (tables might be screwed-up) jmp ferrx ;Go complain and quit .iff push r5 jmp @#grl$xx ;Jump to reload code in global region loader .endc ; This routine opens a UCL (or UCX) file. It is used by the RECALL and STORE ; commands. ; On entry: ; R0 points at the file name (ASCIZ string) ; R5 = 0 to open an existing file (RECALL) ; = -1 to open a new file (STORE) ; The registers are undisturbed on return. ; ; OPNUCL also prompts for a file name, if necessary. opnucl:: push ;Save R0 - R3 10$: call adjr0 ;Null file name?... tstb (r0) bne 20$ ;Branch if not .gtlin #buff,#filqry ;"File?"... mov #buff,r0 br 10$ 20$: mov r0,r1 ;Copy file name to scratch area... mov #scrach,r2 mov #14.,r3 call ccopy tst r5 ;Open old or new file? bpl 30$ ;Branch if old mov #newsfx,r1 ;Stick "[22]=" after file name tstb swstat ; unless we're journaling... bpl 25$ mov #maxsfx,r1 ;If /JOURNAL, use "[-1]="... 25$: mov #6,r3 call ccopy 30$: clrb (r2) ;Add terminating null mov #uclext,r1 ;R1 => assumed default extension list tstb swstat ;If journaling active, use other list... bpl 40$ mov #ucjext,r1 40$: mov sp,spsav ;Open the file.. .csigen dspace,r1,#scrach mov spsav,sp ;Clean up the stack bcs opnurx ;Branch on error pop ;Restore R3 - R0 return ; error trap... opnurx: mov 6(sp),r4 ;Make R4 => file name (old R0)... opnur0: clr r5 ;Make R5 index to error message... movb @#errbyt,r5 asl r5 .purge #0 ;Ensure any open channels cleaned-up... .purge #3 mov opnuet(r5),r5 ;Point at error message jmp ferrx ;Go complain and quit ; data area for OPNUCL... .if eq ucl$xm ;Default extensions for .CSIGEN call uclext: .rad50 "UCL" .rad50 "UCL" .word 0,0 .iff uclext: .rad50 "UCX" .rad50 "UCX" .word 0,0 .endc ucjext: .rad50 "UCJ" .rad50 "UCJ" .word 0,0 newsfx: .asciz /[22]=/ maxsfx: .asciz /[-1]=/ .even opnuet: .word millfn ;Error message address table .word dmnerr .word mpfilf .word mnroom .word mfilnf ; Routines for STORE/RECALL switch processing .enabl lsb ;/BINARY... bnswr: tstb swstat ;Switch conflict?... bmi 20$ tstb swstat+1 bne 20$ 10$: jmp swbits ;Otherwise, go set up switch status word 20$: clr swstat ;Ensure switch status reset bis #cnswer,swstat ;Set "conflicting switches" bit in SWSTAT sec ;Flag the error return ; and quit ;/JOURNAL... jnswr: tstb swstat ;Did cretin ask for both modes? bne 20$ ;If so, go say something about it br 10$ ;Otherwise, go set switch status ;/NOQUIET... nqtswr: tstb swstat+1 ;Check for switch conflict... bgt 20$ tstb swstat bgt 20$ bic #jrnlq,status ;Echo journal input lines to console... br 10$ ;/QUIET... qtswr: tstb swstat+1 ;Check for switch conflict... bmi 20$ tstb swstat bgt 20$ bis #jrnlq,status ;Tell UCL+ to journal quietly... br 10$ .dsabl lsb ; Tables for STORE/RECALL switch processing... srcrsa: .word bnysw, jnlsw, noqtsw, qtsw, 0 ;Reference string addresses .word badopx, cnfswx, badswx, ambswx srcsea: .word bnswr, jnswr, nqtswr, qtswr ;Switch execution address list srcssb: .word 1, 200, 100000, 400 ;Switch status bit list srcarl: .word srcrsa, srcsea, srcssb ;Argument list for SWTCHS call .sbttl . store ; "Store Current Symbol Definition and Status Tables" STORE file-spec ; ===== /BINARY ; /JOURNAL ; ; The STORE command causes the symbol/status blocks to be written to a ; specified file. The default device is DK:, the default extension .UCL ; (DK:filnam.UCL). ; ; The /JOURNAL switch causes the default extension to be .UCJ for the ; output file. ; ; The XM version of UCL defaults to a .UCX extension for non-journal output ; files. store:: mov #srcarl,r4 ;R4 => argument list for SWTCHS call call swtchs ;Look for /JOURNAL tst r5 ;Any errors? bpl 5$ ;Branch if not jmp @srcsea(r5) ;Go handle switch error 5$: call adjr0 ;Point at filename mov r0,savr0 ;Save pointer to file name mov #-1,r5 ;Open the file... call opnucl tstb swstat ;/JOURNAL? bmi storej ;Branch if so movb #rls,vznrls ;Ensure version/release stuff current... movb #vzn,vznrls+1 clr wblok ;Write-out the symbol/status blocks... mov #sdsat,wbufa mov #nbloks,r5 10$: .writw #area,#0 bcs sterx inc wblok add #512.,wbufa sob r5,10$ .close #0 ;Close the output channel return ; error trap sterx: mov savr0,r4 ;R4 => file name sterx0: mov #strerr,r5 ;R5 => "Write Error..." .purge #0 ;Close channel; don't make file permanent jmp ferrx ;Go complain ; Here we handle STORE/JOURNAL... storej: call plinit ;Ensure PLINE initialized bis #,status ;Set "output dev open" & "journal out" clr wblok ;Init output block and buffer pointer... mov #obufr,obptr mov savr0,r4 ;Move filename to PLINE's buffer (for error mov #prlfnm,r5 ; messages)... 10$: movb (r4)+,(r5)+ bne 10$ call lists ;List symbols, call listp ; path, call listx ; chaining, .prlin #pmtmsg ; and prompt text... .prlin #prompt .prlin #crlf .prlin #0 ;Close out the file bic #jrnlo,status ;Reset JRNLO bit return ; and quit .sbttl . uci_mode, nouci_mode .if ne uci$c ; "Switch UCI_MODE operation on/off" [NO]UCI_MODE prompt-string ; ======== ; UCI_MODE sets the "pass line to KMON" flag ; and then executes the equivalent of a ; "PROMPT=prompt-string" command. ; ; NOUCI_MODE does a "PROMPT=prompt-string". ; The "pass line to KMON" flag is cleared. .enabl lsb ; UCI_MODE... ucimod:: tst status ;Is this a legal command for this monitor? bpl 15$ ;Branch if not bisb #ucimd,pflags ;Set UCI_MODE flag .if ne pfx call 20$ ;Activate prefix for hard-wired commands .endc 10$: jmp promt ;PROMPT=... ; NOUCI_MODE... nucimd:: tst status ;Is this a legal command for this monitor? bpl 15$ ;Branch if not bicb #ucimd,pflags ;Clear UCI_MODE and RUN flags... bicb #,status br 10$ ;Go do PROMPT=... 15$: clr r4 ;Execute "...invalid for this monitor" fatal mov #miluci,r5 ; error exit jmp ferrx ; If UCI_MODE is in effect, this routine adjusts the string pointers for the ; hard-wired commands to point at the prefix character. ucitst: tstb pflags ;UCI_MODE in effect? bpl 40$ ;Branch if not .if ne pfx tstb status ;Prefix stuff already done? bmi 40$ ;Branch if so 20$: push r0 ;Save R0 mov #rsals0,r0 ;R0 => reference string address list 30$: dec (r0)+ ;Point at command prefix character tst (r0) ;Done? bne 30$ ;Branch if not pop r0 ;Restore R0 .endc bis #ucimd,status ;Flag completion 40$: return ; and quit .dsabl lsb .endc .sbttl . rno .if ne rno$c ; Runoff Command Routine RNO/switches file-spec ; === ; ; RNO/switches MYFILE becomes RUNOFF outspec/switches=MYFILE ; This set of routines and tables implements an RNO command for use with ; DECUS RUNOFF version M02.4. ; ; The command switches and the RUNOFF switches and file specifications ; that they map to are as follows: ; ; RNO RUNOFF ; --- ------ ; /BEGIN:n /B:n ; /START:n ; ; /END:n /E:n ; ; /ONLY:n /B:n/E:n ; /PAGE:n ; ; /FORMLENGTH:n /F:n ; ; /HYPHENATION /H:YES ; ; /NOHYPHENATION /H:NO ; ; /HELP /I ; /INFORMATION ; ; /STRIP /S ; ; /NOSTRIP ignored ; ; /UNDERLINE /U:L ; /UNDERLINE:BACKSPACE /U:B ; :SIMULATED /U:S ; :NONE /U:N ; ; /NOUNDERLINE /U:N ; ; /VERSION /V ; ; /WAIT /W ; ; output specifications: ; ; /OUT:filename filename...= ; ; /PRINTER LP:...= ; ; /TERMINAL TT:...= ; ; no output spec. or LP:...= ; /DEFAULTS rno:: clrb outfnm ;Init. output file buffer mov #rnalst,r4 ;R5 => switch argument list call swtchs ;Process switches jmp @rnovec(r5) ;Go do whatever is right ; Above jump enters at RNOOK if no problems with switches rnook: call adjr0 ;Skip leading blanks tstb (r0) ;Null input file? bne 10$ ;Branch if not bit #4,swstat ;Input file required? bne 10$ ;Branch if not .gtlin #buff,#rnpmt ;"Input File?"... mov #buff,r0 br rnook 10$: push r0 ;Save R0 clr r0 ;Actual byte count accumulates in R0 mov #chbuf,r2 ;R2 => "chain buffer" mov #chbufl,r3 ;R3 = max. byte copy count mov #rnotxt,r1 ;Put "R RUNOFF" in chain buffer call ccopy0 bit #2,swstat ;Any output spec. entered? bne 20$ ;Branch if yes bit #4,swstat ;Output file required? bne 30$ ;Branch if not mov #deftxt,r1 ;Use "LP:" otherwise... call ccopy br 30$ 20$: mov #outfnm,r1 ;Copy output spec... call ccopy 30$: mov #stxbuf,r1 ;Copy switches... call ccopy mov #eqlsin,r1 ;Insert "="... call ccopy pop r1 ;R1 => input spec. (old R0) call ccopy0 ;Copy it to chain buffer mov #uarowc,r1 ;Copy in "^C"... call ccopy0 mov #chbuf,r1 ;Pass command line to RT-11... jmp setcm0 ; Specialized switch routines for RNO... ; /OUT:filename rnoutr: bit #2,swstat ;Already have output spec? bne confsw ;Yes jmp outsr ;No confsw: bis #cnswer,swstat ;Set "conflicting switches" flag sec ;Set carry bit return ; /PRINTER rnprnr: bit #2,swstat bne confsw jmp prntsr ; /TERMINAL rntrmr: bit #2,swstat bne confsw jmp termsr ; /DEFAULTS rndefr: bit #2,swstat ;Previous output specs? bne confsw push ;Save R0, R1... mov #deftxt,r0 ;Copy default stuff to output-spec. buffer... mov #outfnm,r1 10$: movb (r0)+,(r1)+ bne 10$ pop ;Restore R1, R0... jmp swbits ;Update switch status ; /ONLY:n and /PAGE:n rnolyr: mov #rnbsrs,r1 ;R1 => "/B:" call ctstxb ;Append it to switch text buffer call getopt ;Get the "n" part into OPBUF bcc 20$ ;Branch if it was there dec stxbp ;Zap unneeded ":"... clrb @stxbp 10$: jmp swbits ;Go update switch status 20$: push r1 ;Save R1 (points at the "n" part) 30$: cmpb (r1),#'0 ;See if "n" text is entirely numeric... blt 40$ cmpb (r1)+,#'9 bgt 40$ tstb (r1) bne 30$ movb #'.,(r1)+ ;They're all numbers; append decimal point... clrb (r1) 40$: pop r1 ;Restore R1 call ctstxb ;Append the "n" to the switch text buffer mov #rnesrs,r1 ;R1 => "/E:" call ctstxb ;Copy this part mov #opbuf,r1 ;R1 => "n" part again call ctstxb ;Copy it br 10$ ;Go quit ; /UNDERLINE:option rnuswr: call adjr0 ;Skip leading blanks cmpb (r0),#': ;Is there an option? beq 10$ ;Yes... jmp stxoly ;No, take default 10$: call getopt ;Put option in OPBUF push ;Save R3 - R5 .cscan ,#uswrsa ;Look for a match... mov r5,r1 ;Put offset in R1 bpl 20$ ;Branch if there was a match bis #badopt,swstat ;Set "bad option" flag br 30$ ; and branch 20$: mov uswsta(r1),r1 ;R1 => switch text call ctstxb ;Copy to STX buffer 30$: pop ;Restore R5 - R3... call swbits ;Update switch status bit #badopt,swstat ;Did we have bad option? beq 40$ ;Branch if not sec return 40$: clc ;Return with no errors... return ; Reference string address list for UNDERLINE options... uswrsa: .word uswb, uswn, usws, 0 ; Reference strings for options... .nlist bex uswb: .asciz /BACKSPACE/ uswn: .asciz /NONE/ usws: .asciz /SIMULATED/ .list bex .even ; UNDERLINE switch text address list... uswsta: .word rnusrb, rnusrn, rnusrs ; Address lists, tables, text for RNO command... .nlist bex rnpmt: .ascii "Input File? "<200> rnotxt: .asciz "R RUNOFF" deftxt: .asciz "LP:" eqlsin: .asciz "=" uarowc: .byte 3,0 ; Reference strings for switches: rnob: .asciz /BEGIN/ rnosta: .asciz /START/ rnod: .asciz /DEFAULTS/ rnoe: .asciz /END/ rnof: .asciz /FORMLENGTH/ rnohy: .asciz /HYPHENATION/ rnonhy: .asciz /NOHYPHENATION/ rnoi: .asciz /INFORMATION/ rnoh: .asciz /HELP/ rnooly: .asciz /ONLY/ rnoout: .asciz /OUTPUT/ rnopag: .asciz /PAGE/ rnoprn: .asciz /PRINTER/ rnos: .asciz /STRIP/ rnons: .asciz /NOSTRIP/ rnotrm: .asciz /TERMINAL/ rnou: .asciz /UNDERLINE/ rnonu: .asciz /NOUNDERLINE/ rnov: .asciz /VERSION/ rnow: .asciz /WAIT/ ; Switch text for output: rnbsrs: .asciz "/B:" rndsrs: .asciz "/D" rnesrs: .asciz "/E:" rnfsrs: .asciz "/F:" rnhsry: .asciz "/H:YES" rnhsrn: .asciz "/H:NO" rnisrs: .asciz "/I" rnssrs: .asciz "/S" rnusrb: .asciz "/U:B" rnusrl: .asciz "/U:L" rnusrn: .asciz "/U:N" rnusrs: .asciz "/U:S" rnvsrs: .asciz "/V" rnwsrs: .asciz "/W" .list bex .even ; Switch reference string address list: rnsrsa: .word rnob, rnod, rnoe, rnof, rnoh .word rnohy, rnoi, rnonhy, rnons, rnonu .word rnooly, rnoout, rnopag, rnoprn, rnosta .word rnos, rnotrm, rnou, rnov, rnow .word 0 ; Switch execution address list: rnseal: .word stxotx, rndefr, stxotx, stxotx, stxoly .word stxoly, stxoly, stxoly, swbits, stxoly .word rnolyr, rnoutr, rnolyr, rnprnr, stxotx .word stxoly, rntrmr, rnuswr, stxoly, stxoly ; Switch status bit list: rnssbl: .word 1, 2, 1, 1, 4 .word 1, 4, 1, 1, 1 .word 1, 2, 1, 2, 1 .word 1, 2, 1, 4, 1 ; Switch text address list: rnstxa: .word rnbsrs, rndsrs, rnesrs, rnfsrs, rnisrs .word rnhsry, rnisrs, rnhsrn, 0, rnusrn .word 0, 0, 0, 0, rnbsrs .word rnssrs, 0, rnusrl, rnvsrs, rnwsrs ; Argument list for SWTCHS call: rnalst: .word rnsrsa .word rnseal .word rnssbl .word rnstxa ; Jump table for results of switch parsing: .word badopx .word cnfswx .word badswx .word ambswx rnovec: .word rnook .endc CD ==assign ^[sy] dk RNO ==r runoff\^2[lp:]=^1\<003> ; VRDATA -- form .TITLE, .IDENT, etc. ; define variables RLS (release) and VZN (version) for UCL+ .MACRO VRDATA NAME=UCL,VRZHN=55,REMARK=,XMUCL=NO,RLEAS=07,RTYPE=V,VLEVL= .MCALL .MODULE .IF IDN .IF IDN .MODULE UCL, VERSION=VRZHN,COMMENT=<'REMARK'>,AUDIT=YES,GLOBAL=VZN,MODNAME=,RELEASE=RTYPE'RLEAS .MACRO VRSTR .ASCII " UCL+ " .NLCSI TYPE=I,PART=RLSVER .ASCIZ "'VLEVL'" .EVEN .ENDM .IFF .MODULE UCL, VERSION=VRZHN,COMMENT=<'REMARK'>, LIB=YES,GLOBAL=VZN,MODNAME=,RELEASE=RTYPE'RLEAS .MACRO VRSTR .ASCII " UCL+ (XM) " .NLCSI TYPE=I,PART=RLSVER .ASCIZ "'VLEVL'" .EVEN .ENDM .ENDC RLS ==:'RLEAS'. .IFF .MODULE 'NAME',VERSION=VRZHN,COMMENT=<'REMARK'>,AUDIT=YES,RELEASE=RTYPE'RLEAS .ENDC .ENDM ; PUSH -- push thing(s) onto stack .MACRO PUSH THINGS .IRP THING, MOV THING,-(SP) .ENDR .ENDM ; POP -- pop thing(s) off stack .MACRO POP THINGS .IRP THING, MOV (SP)+,THING .ENDR .ENDM ; .GETCOM -- extract a command from a string .MACRO .GETCO BUFR,CBUFR,TMTABL .IF NB .IF DIF ,R0 MOV BUFR,R0 .ENDC .ENDC .IF NB .IF DIF ,R1 MOV CBUFR,R1 .ENDC .ENDC .IF DIF ,R2 MOV R2,-(SP) .IF NB MOV TMTABL,R2 .IFF MOV #TMTBL,R2 .ENDC .ENDC CALL GETCOM .IF DIF ,R2 MOV (SP)+,R2 .ENDC .ENDM ; .CSCAN -- identify a command .MACRO .CSCAN CBUFR,RSAL .IF NB .IF DIF ,R1 MOV CBUFR,R1 .ENDC .ENDC .IF NB .IF DIF ,R4 MOV RSAL,R4 .ENDC .ENDC CALL CSCAN .ENDM ; .PRLIN -- make call to PLINE routine work like .PRINT .MACRO .PRLIN ADDR .IF NB .IF DIF ,R0 .IF DIF ,#0 MOV ADDR,R0 .IFF CLR R0 .ENDC .ENDC .ENDC CALL PLINE .ENDM ; .GTREC -- make call to GREC work similar to .GTLIN .MACRO .GTREC ADDR .IF NB .IF DIF ,R0 .IF DIF ,#0 MOV ADDR,R0 .IFF CLR R0 .ENDC .ENDC .ENDC CALL GREC .ENDM .sbttl COMMAND TABLES AND REFERENCE STRINGS ; ==================================== ; Refer to the material in CEX.MAC for information on how these tables are ; used in processing commands. .psect ucltbl .sbttl . Command Execution Address List .word badcom, ambchw ;Bad and ambiguous commands cealst:: .word lister ;Hidden "?" command for TSX+ V5; same as LIST .word chain ;CHAIN .word dsplay ;DISPLAY .word erase ;ERASE .word lister ;LIST .word nchain ;NOCHAIN .word npath ;NOPATH .word nosl ;NOSL .iif ne uci$c, .word nucimd ;NOUCI_MODE .word pass ;PASS .word path ;PATH .word promt ;PROMPT .word recall ;RECALL .iif ne ucl$xm, .word reload ;RELOAD .iif ne rno$c, .word rno ;RNO .word slon ;SLON .word store ;STORE .iif ne uci$c, .word ucimod ;UCI_MODE .word 0 .sbttl . Reference String Address List rsalst:: .word huh rsals0: .word schain .word sdspla .word serase .word sliste .word snchan .word snpath .word snosl .iif ne uci$c, .word snucim .word spass .word spath .word spromt .word srecal .iif ne ucl$xm, .word sreloa .iif ne rno$c, .word srno .word sslon .word sstore .iif ne uci$c, .word sucimd .word 0 .sbttl . Reference Strings: Commands ; The "PFX" values in this list are the hard-wired command prefix characters ; used when UCI_MODE is in effect. ; Handy macro: .macro hwrfst label, prefix, text .iif ne prefix, .byte prefix label': .asciz "'text'" .endm .nlist bex hwrfst schain, pfx, text=CHAIN hwrfst sdspla, pfx, text=DISPLAY hwrfst serase, pfx, text=ERASE hwrfst sliste, pfx, text=LIST hwrfst snchan, pfx, text=NOCHAIN hwrfst snpath, pfx, text=NOPATH hwrfst snosl, pfx, text=NOSL .if ne uci$c hwrfst snucim, pfx, text=NOUCI_MODE .endc hwrfst spass, pfx, text=PASS_ON hwrfst spath, pfx, text=PATH hwrfst spromt, pfx, text=PROMPT hwrfst srecal, pfx, text=RECALL .if ne ucl$xm hwrfst sreloa, pfx, text=RELOAD .endc .if ne rno$c hwrfst srno, pfx, text=RNO .endc hwrfst sslon, pfx, text=SLON hwrfst sstore, pfx, text=STORE .if ne uci$c hwrfst sucimd, pfx, text=UCI_MODE .endc .even .sbttl . Reference Strings: Switches & Arguments star: .asciz /*/ allsw: .asciz /ALL/ bnysw: .asciz /BINARY/ comsw: .asciz /COMMANDS/ exesw: .asciz /EXECUTE/ frmsw: .asciz /FORM0/ jnlsw: .asciz /JOURNAL/ nexsw: .asciz /NOEXECUTE/ nfrmsw: .asciz /NOFORM0/ noqsw: .asciz /NOQUERY/ noqtsw: .asciz /NOQUIET/ outsw: .asciz /OUTPUT/ prnsw: .asciz /PRINTER/ pmtsw: .asciz /PROMPT/ qrysw: .asciz /QUERY/ qtsw: .asciz /QUIET/ tosw: .asciz /TO/ symsw: .asciz /SYMBOLS/ trmsw: .asciz /TERMINAL/ versw: .asciz /VERSION/ .list bex .even .sbttl . Command Execution Status List ; This list provides information about the execution characteristics of the ; hard-wired commands. ; cxdsp ==> Command is potentially DISPLAYable ; cxnuc ==> Command text may not be "memorized" .word cxdsp,cxdsp ;Bad and abiguous commands cxslst:: .word 0 ;Hidden "?" command for TSX-Plus V5; same as LIST .word 0 ;CHAIN .word 0 ;DISPLAY .word 0 ;ERASE .word cxnuc ;LIST .word 0 ;NOCHAIN .word 0 ;NOPATH .word cxdsp ;NOSL .iif ne uci$c, .word 0 ;NOUCI_MODE .word cxnuc ;PASS .word 0 ;PATH .word 0 ;PROMPT .word 0 ;RECALL .iif ne ucl$xm, .word 0 ;RELOAD .iif ne rno$c, .word cxdsp ;RNO .word cxdsp ;SLON .word 0 ;STORE .iif ne uci$c, .word 0 ;UCI_MODE .word 0 .sbttl . Symbol Execution Address List .word badcm0 .word ambcom sealst:: .rept nsyms .word syproc .endr ! ! UCLTXF.COM ! ! Command file to invoke ! TRANSF and send the UCL+ ! distribution from DK: on ! the host computer to DK: ! on the remote. ! ! The most essential files (binaries ! and documentation) are transmitted ! first. ! R TRANSF ! binaries and documentation... README.1ST/T=README.1ST/S UCL.SAV/T=UCL.SAV/S UCLXM.SAV/T=UCLXM.SAV/S CI.SYS/T=CI.SYS/S UCL.DOC/T=UCL.DOC/S UCLHLP.TXT/T=UCLHLP.TXT/S UCL.MAP/T=UCL.MAP/S UCLINI.UCJ/T=UCLINI.UCJ/S ! sources... UCL.CND/T=UCL.CND/S UCLXM.CND/T=UCLXM.CND/S CI.COM/T=CI.COM/S UCL.COM/T=UCL.COM/S UCLXM.COM/T=UCLXM.COM/S CEX.MAC/T=CEX.MAC/S CI.MAC/T=CI.MAC/S UCL.MAC/T=UCL.MAC/S UCLGRL.MAC/T=UCLGRL.MAC/S UCLHWC.MAC/T=UCLHWC.MAC/S UCLMAC.MAC/T=UCLMAC.MAC/S UCLTBL.MAC/T=UCLTBL.MAC/S UCLTXT.MAC/T=UCLTXT.MAC/S UCLTXF.COM/T=UCLTXF.COM/S ^C .sbttl ASCII STUFF ; =========== .sbttl . Prompts and Listing Text .psect text .nlist bex dfpmt: .ascii "UCL> "<200><0> ;Default .gtlin prompt runcmd: .ascii "RUN " rundev: .blkb 5 huh: .asciz "?" sydefq: .ascii "Symbol definition? "<200> dspqry: .ascii "Command? "<200> eraqry: .asciz "Erase all symbols" ersqry: .ascii "Erase symbol "<200> rusure: .ascii "Are you sure? "<200> er1qry: .ascii "Symbol? "<200> listcm: .asciz "Valid commands:" listp0: .asciz /No "run-by-name" path/ listpj: .asciz "NOPATH" listpm: .asciz /"Run-by-name" path:/ listsm: .asciz "Current symbols:" listsd: .asciz " Symbols defined" listse: .asciz " Entries remaining" listxm: .ascii "CHAIN in effect to "<200> listx0: .asciz "No CHAIN in effect" listxj: .asciz "NOCHAIN" listxu: .ascii "Pass-line-to-KMON in effect "<200> listxf: .asciz "(UCF)" listxi: .asciz "(UCI_MODE)" filqry: .ascii "File? "<200> pmtmsg: .ascii "PROMPT "<200> pthmsg: .ascii "PATH "<200> chnmsg: .ascii "CHAIN "<200> .if eq okray eofmsg: .asciz "" .iff eofmsg: .ascii "" .asciz "?UCL-I-Is that OK, Ray?" .endc crlf: .byte 0 .sbttl . Error Messages, "Warning" muclw: .ascii "?UCL-W-"<200> trswrn: .asciz "Truncating symbol name to 6 characters" trdwrn: .asciz "Truncating symbol definition to 72 characters" reswrn: .asciz "Replaced existing symbol" erawrn: .ascii "Erased symbol "<200> .sbttl . Error Messages, "Fatal" ; Fatal messages are terminated with <200>. This allows for optional ; secondary text. .if eq c4ell muclf: .ascii "?UCL-F-"<200> .iff muclf: .ascii "?UCL-F-Try again, schmuck - "<200> .endc mbadop: .ascii "Invalid or missing option "<200> mcnfsw: .ascii "Conflicting switches "<200> mbad: .ascii "Invalid command "<200> mamb: .ascii "Ambiguous command "<200> mbadsp: .ascii "Invalid DISPLAY argument "<200> synrm: .ascii "Symbol definition table full "<200> wtfail: .ascii "Output error while updating symbol blocks "<200> mbadrg: .ascii "Invalid argument "<200> mbadsw: .ascii "Invalid switch "<200> mambsw: .ascii "Ambiguous switch "<200> millfn: .ascii "Illegal file name "<200> mfilnf: .ascii "File not found "<200> mnroom: .ascii "Not enough room for file "<200> mpfilf: .ascii "Protected file already exists "<200> rclerr: .ascii "Read error "<200> strerr: .ascii "Write error "<200> vrerr: .ascii "Wrong version of UCL "<200> minvff: .ascii "Wrong file format "<200> .iif ne ucl$xm, milrel: .ascii "RELOAD invalid while journaling "<200> .iif ne uci$c, miluci: .ascii "UCI_MODE invalid for this monitor "<200> er1nfm: .ascii "Symbol not found "<200> er1amm: .ascii "Ambiguous symbol "<200> dmnerr: .ascii "Invalid device "<200> lpluer: .ascii "Unable to access LP: "<200> mrucf: .asciz "-- running as UCF" eronjf: .asciz "on journal file" .list bex .even ; Conditional to turn on RT-11 V5.2 (or later) XM monitor support ucl$xm = 1 ! command file to build UCL+ program -- XM version ! ================================================ ! ! input device is DK:, output device is DK: ! ! for RT-11 V05.02 or later monitors only ! ! note that SPLIT program is required ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ r libr uclmac=uclmac/m ^C r macro uclgrl=uclmac/m,uclgrl uclxm=uclmac/m,uclxm.cnd,ucl.cnd ^C r link uclgrl,,uclgrl=uclgrl uclxm.exe=uclgrl.stb,uclxm/b:20000/y:512. main ^C del uclmac.mlb,uclxm.obj,uclgrl.obj,uclgrl.stb r split uclxm.0,,uclxm.20=uclxm.exe/b:1:20 ^C del uclxm.exe cop uclgrl.sav+uclxm.0+uclxm.20 uclxm.sav del uclxm.0,uclxm.20,uclgrl.sav vU7@ ă@?UCLGRL-F-No roomPLAS errorI/O errorNot XM monitorf45B(2hx(&(5@  0].$& J  (QU  >@+ \I 4p0 w$w 4 0 C(  4 0 D Bk7DK:UCL>  UCL+ (XM) V07.55 bQ HJɋR~ 6 QC& U Q ȋE z QREk &   N&\ & \5r Q  ن5^ 5V  7  j& }N^&Q  7" 5 w5  uɋW W: ~7k XwTCȋEREk %ȋ &@ Aa Ek %1  jXR ȋR !@XEk F%5P F T w ,Z. U * wE 5 aZQ5   Xwf5 0Z wT5 w&Q TjXC U@R~JR HE Z@Z5n + 5P w [ w  ȋ &QX& &Q oeP~&  ~H r ~ o CL   4Jt ^X 0  eN[ w5v 6& L A eW_UV 4T l    4T5 5 wFQP5 w w ȋw| 8B eH ^ ~ aZ 5+=f&Q&QnH " =  dW| FW\  W^9f W0W9N&DE  @rX trXrX  ̋  &Tv   "    R &ftX 7 0 ȋ  ȋ ~0 E& j== Urf&@ PW! Z^ P&Q 4W!H3ZB 4fW[7 . ыW| W]w f R   H&fы W:  ɋW*@ P B@UT E(z5@| vT7\EURW!T& & 切&fQB|@ d&fQ&QQ&QW| P= TP ,  7 Sf&R v/ RDk n  Ca 5` fmwSB&fLSEk UwLP:&f,LSEk wTT: :U@f SEk  Հ7 ŀwX V \ x ?w>fW0W9ɋѕ.  ,  "  :U@RAaA&P  : :SEk ZZ w\[[k[RwJ@ 5 ,HR~U $5Հ & 4T  4TɋR ~ R W[ɋ W| W]R ~ɋW R ~ȋ  & Ћ 5&Z鈀5+f&fw5Nw T͋ ͕=w@ $!MX7 VTv\ w^XT\ JDjX T8^U6ZVn x n d  2O  wP :W ZX^X ZV0 > 4 ZV 5 W ZXW ZX^X ZV0  E7x7 7  w w T?f&5VC鈀W ZX&^XpZV0 "ZV VBŀ  w:5鈃 E ߋ* Y鈀[_(@<f&W>~  eW0W7~ BEP~  vE  U <ѕ>&Ee0  kSv NXUCL> RUN ?Symbol definition? Command? Erase all symbolsErase symbol Are you sure? Symbol? Valid commands: No "run-by-name" path NOPATH "Run-by-name" path: Current symbols: Symbols defined Entries remaining CHAIN in effect to No CHAIN in effect NOCHAIN Pass-line-to-KMON in effect (UCF) (UCI_MODE) File? PROMPT PATH CHAIN ?UCL-W-Truncating symbol name to 6 charactersTruncating symbol definition to 72 charactersReplaced existing symbolErased symbol ?UCL-F-Invalid or missing option Conflicting switches Invalid command Ambiguous command Invalid DISPLAY argument Symbol definition table full Output error while updating symbol blocks Invalid argument Invalid switch Ambiguous switch Illegal file name File not found Not enough room for file Protected file already exists Read error Write error Wrong version of UCL Wrong file format RELOAD invalid while journaling UCI_MODE invalid for this monitor Symbol not found Ambiguous symbol Invalid device Unable to access LP: -- running as UCFon journal fileDEb8__fab,_gejPfgghgfijX] ])]0]6]?]G]M]Y]b]h]p]x]]]].CHAIN.DISPLAY.ERASE.LIST.NOCHAIN.NOPATH.NOSL.NOUCI_MODE.PASS_ON.PATH.PROMPT.RECALL.RELOAD.SLON.STORE.UCI_MODE*ALLBINARYCOMMANDSEXECUTEFORM0JOURNALNOEXECUTENOFORM0NOQUERYNOQUIETOUTPUTPRINTERPROMPTQUERYQUIETTOSYMBOLSTERMINALVERSIONDEGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG @U 4ŀE ȋC&~}[w$w5Z\ ^a }PaUv5rUh Bȋ&&QTda 8  $QX& Q ȋ &Q Q QQW" &ыЋW"W|0 E REk  \ &^w}\&fCZ Z a ɕa ~Z x r5@FE45,E $,w 5wU5w]]]]]]^ @"M(M2M8MaeaeZeee*aPa:a 7 b +}b5XQX& @׭ȋ QX& QȋREk  ȋ 7 0 }b 5#A R j 5XRQX& r׭nY e W! U  ~R鈇r PȋzZlbb_\q\Rw]]"M(M2M8MKKbbb e t }e ȋ X 0REk 74e   Leȋ  }Le  D5=Y o !5o@T rT RY @T XT cY TN ҕ ҕ=ҕ=e  T >  ɕ& e:  Z D Z X \@ 2 Y5Y 5 %Y C Y C 5r$5j ,Y ~Y tY5FY `xY VC N5"] < Y ,C $Y I[RwZ]]]]b] ^^"M(M(eELcLcdFd\dbc,d5U &fS T5 L5`~7d5nw5bw]]]]^ @"M(M2M8MeeZeeeeee FU$f5툇w6 (E$,f SET SL OFF SET SL ON55w߇ g  }g S̋&TjX& T}[w5C  Y Hȋ&QX& &Q ,ȋf &QTg  &wf^"M(M2M8M0Lfgg Հz&ŀr ȋCP REk  .& T ȋ  wҕ, \wf&@Dk ~@ vW! E`Օ:  D&f" ɋXC 嗨" ʕwt5"\ w H_iU N }i  7 U7 ZXEĝ<7  ^X0  eNĭ s w[[\f_(&f <ȋ QY& QT `i,fi PiXifT ŗ* Eliw>ЃЃƒƒ[22]=[-1]=}[\[[[wL7 UxEnkdUZ]]]^"M(M2M8Mviiiiiiii v }i 7 (x7s7 > :^X 0  eN[w, "U7 ZV T Y C Z Ej dՀ= .w Pŀ)ŁB <\w , &\ Uf& ŀ az ʋ: /=, & f &  f   ɋɋR ʋ CLS ==_DISP "<033>[H<033>[J" EDT ==EDIT GTOFF ==D 174000=0 GTON ==D 174000=40 LD ==MOU LD0: SY:^.DSK\ASS LD0: DK:\DISP "?LD-I-DK: assigned to ^" LD1 ==MOU LD1: SY:^.DSK\DISP "?LD-I-^.DSK mounted as LD1:" LD2 ==MOU LD2: SY:^.DSK\DISP "?LD-I-^.DSK mounted as LD2:" LDEF ==SHOW SUB LDIR ==DIR SY:*.DSK/ALPHA LNEW ==CREA SY:^1.DSK/ALLOC:^2[1000]\MOU LD0: SY:^.DSK\ASS LD0: DK:\INIT DK: PD ==ASS ^ DK:\DISP "?SD-I-DK: assigned to ^" PUR ==DEL *.BAK SD ==_PD SETDAT==DISP "ENTER DATE dd-mmm-yy"\DATE ^ SY ==ASSIGN SY: DK:\DISP "?SD-I-DK: assigned to SY:" UP ==ASSIGN SY: DK:\DISP "?SD-I-DK: assigned to SY:" VRUN ==R VBGEXE PATH DK: NOCHAIN PROMPT UCLxm> ۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m۶m