.NONUMBER .LM 0 ^PY^- .PAGE SIZE 58,85 .LM 10 .RM 75 .NO FILL .NO JUSTIFY # .SKIP 5 .CENTER The RSX Multi-Tasker .CENTER February, 1987 .SKIP .CENTER ^IS144^G"Illegitimus Non Carborundum Est"^IS204^G .SKIP .CENTER Fine Realtime Commentary Since 1975 .SKIP 6 .CENTER ^&Table of Contents\& .SKIP 2 .TAB STOPS 60 Food for Thought RSX-1 The Editor's Corner RSX-1 Software Dispatching RSX-2 Submitting Articles to the Multi-Tasker RSX-3 And That's The Way Things Are RSX-3 The Bag of Tricks RSX-4 It's In the Code RSX-5 MT: Driver SPR RSX-6 The Notebooks of Justin L. Hewser RSX-8 Base Conversion Command File RSX-10 Topological Walk to an ODL RSX-12 .JUSTIFY .FILL .PAGE .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT Food for Thought .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT # .SKIP 7 .AUTOPARAGRAPH .CENTER ^&Food for Thought\& .SKIP "When a man drinks water, or does anything for the sake of practice, whenever there is an opportunity he tells it to all: "I drink water."# Is it for this that you drink water, for the purpose of drinking water? Man, if it is good for you to drink, drink; but if not, you are acting ridiculously. But if it is good for you and you do drink, say nothing about it to those who are displeased with water-drinkers. What then, do you wish to please these very men?" .SKIP 2 .INDENT 30 ^IS144^G- Epictetus^IS204^G .INDENT 30 ^IS144^G##Discourses, Book III^IS204^G .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Editor's Corner .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .SKIP 9 .CENTER ^&The Editor's Corner\& .SKIP .CENTER Bruce R. Mitchell .SKIP Yes, indeed, my faithful audience - once again, despite popular demand, and frequent inspections by the Committee for the Public Morals, it's the Multi-Tasker Variety Show and Digital Comedy Hour. It's a mixed bag of entries this month. As always, the "Bag of Tricks" discusses Macro ways and means. This month - how to use that tricky Extend Task directive profitably, while minimizing trouble making it work. We also see the reappearance of a column long-absent from the Multi-Tasker, "It's In the Code", dealing with interesting little tidbits in the RSX system code. Something else long absent from the Multi-Tasker, and particularly appropriate in view of this month's editorial, an SPR on the MT: driver which should be of interest to every system manager whose system supports MT: and powerfail. A new series by Jim Bostwick and Jim McGlinchey debuts this issue, with "The Notebooks of Justin L. Hewser."# Justin is familiar to readers of the Multi-Tasker for his guest editorials; here are some of his sow's ears of wisdom. Rounding out the issue is a command file to translate numbers without counting on fingers or scribbling, and one of the classic RSX SIG technical articles - the "Topological Walk to an ODL". Again, the editor thanks each and every respondent to the continuing call for more articles. Keep them coming; I've got a little something for all submittors. Sometimes it may even be useful. And - oh yes, if you don't want to ^&write\& an article, at least drop a line telling what kind of articles you'd like to ^&see\& in the Multi-Tasker. Ho, varlet! Where's my boots? It's time to kick the dog again. .TEST PAGE 5 .SKIP 2 .CENTER ----- Software Dispatching ----- In recent years, Digital has tended more and more to feed its customers predigested pap when it comes to ongoing support of DEC software. The late great ^&Software Dispatch\& is a prime example of this tendency. There was a time when the ^&Software Dispatch\& was the primary source of solutions for problems with RSX systems. When a problem - such as the egregious TKB problem in M-Plus V1.0 - occurred, the ^&Dispatch\& had it in print in the next issue. Digital didn't have to hold releases of software for bug fixes, and the customers didn't have to wait six months for the next Autopatch to come out. The recent history of the ^&Dispatch\&, however, indicates that this once useful tool is becoming a sword suspended over the users' heads. Complaints often heard about the ^&Dispatch\& include: .SKIP o##Holding back important information .BREAK o##Not telling about all the problems .BREAK o##"It will be fixed in Update n", regardless of severity .BREAK o##Fixes are at least 4 months away from when seen .BREAK o##No fixes at all for layered products .BREAK o##DECnet patches appear once a year, then it's a ^&pile\& Perhaps the most common complaint, however, is that the ^&Dispatch\&, once an alternative to purchasing Autopatch service, is no longer an alternative. Patches must be purchased through Update service, and are available nowhere else. Digital is certainly not entirely at fault in this matter. When the ^&Dispatch\& was publishing patches, many SPRs were the result of incorrect and incompetent patching by users. It is certainly no surprise that DEC wanted to eliminate such overhead in the SPR process. Yes, it ^&is\& certainly much more convenient for Digital. .TEST PAGE 5 .SKIP 2 .CENTER ----- Submitting Articles to the Multi-Tasker ----- Please submit machine readable media when possible. RX01, RX02, RX50, or 9 channel magtape at 800 or 1600 BPI are best. Any RSX volume format is acceptable except ROLLIN or PRESRV. ANSI, BRU and DOS FLX formats are well-liked by the Editor's tape drive. Submissions which aren't machine readable take longer to get into print. The editor is lazy and types mass quantities only once a month when progress reports are due. If you preformat a submission in RUNOFF format, please set page size 58,80; left margin 10; right margin 75; and, when changing margins, use incremental changes rather than absolute. The editor blesses you for the consideration. Send all submissions to: .SKIP .NO FILL .NO JUSTIFY Bruce R. Mitchell Machine Intelligence and Industrial Magic PO Box 816 Byron, MN 55920 .JUSTIFY .FILL .TEST PAGE 5 .SKIP 2 .CENTER ----- And That's The Way Things Are ----- _... this month in Pool Lowbegone, where Digital Equipment's earnings are strong, the future outlook is good-looking, and the industry standing is above average. .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Bag of Tricks .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 7 .CENTER ^&The Bag of Tricks: MACRO-11\& .SKIP .CENTER James A. McGlinchey .CENTER 5 Skyline Drive .CENTER Essex Junction, VT###05452 .SKIP In this month's article we examine the problem of a task getting into memory and finding out the programmer didn't allocate enough data buffer space to do . There are two ways of handling the problem of getting more data buffering space for a task in a running RSX system. The task can: .SKIP o##Be installed with a maximum increment .BREAK o##Extend itself for more workspace .SKIP It can give up, too, but this isn't very useful, so we won't look at it any further. If a task is installed with a maximum increment, it loads more slowly than it would if installed with a minimum increment. There's also the problem of where the extra space is going to appear in the task's virtual memory space. (It hangs off the end of the task, which is probably ^¬\& contiguous with the program's original buffer.) On the other hand, if a task extends itself while running, it loads more quickly than it would if installed with a large increment. But there's still the problem of where the extra space is going to appear in the task's virtual memory space. The task ^&can\& keep track of additional buffer space through the .LIMIT assembler directive. .LIMIT tells the task its highest Taskbuild memory address; any extension appears immediately after that point. But this means that the task must manage two buffers rather than one. It is much simpler to force the buffer in question to be the last thing in the task's virtual address space, so the whole buffer ends up contiguous and no fiddling about is necessary. This sounds tricky, but is actually pretty straightforward. The Taskbuilder assigns .PSECTs to virtual memory in ascending Radix-50 alphabetical order. Macro accepts .PSECTs with names "AAAAAA" through "......". This means that the highest valid .PSECT name is "......". "$$$$$$" is equally good; both translate to Rad50 values higher than those of valid alphanumerics. Anything put in such a .PSECT is relocated by TKB to occupy the highest possible section of virtual memory. So, this is where the program's expandable buffer should reside - and to ensure that the buffer is contiguous, ^¬hing\& else should reside in that .PSECT. The following code, culled from a Macro program which reads in block-structured files, illustrates this approach. .SKIP 3 .NO FILL .NO JUSTIFY _.PSECT $$$$$$, RW, D BUFFER: .BLKB <512. * BUFSIZ> ; Disk file block buffer _.PSECT CODE, RO, I ... preceding code ... ; See if file is bigger than local buffer; if so, extend MOV F.HIBK(R0), R1 ; Load high block number CMP R1, _#BUFSIZ ; Can we read it all now? BLOS 50$ ; If so, go read it SUB _#BUFSIZ, R1 ; Subtract buffer size ASH _#3, R1 ; Convert to 64-byte chunks EXTK$S R1 ; Try to extend the buffer MOV $DSW, R1 ; Extend successfully? BPL 50$ ; If so, go read it all ... error processing ... ; File small enough to read whole, so read the whole thing 50$: ... code continues ... .FILL .JUSTIFY .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT It's In the Code .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 7 .CENTER ^&It's In the Code\& .SKIP ^IS144^GThe following article appeared, as if by magic, on the Editor's desk one day. Nobody admits to knowing from whence it came. It's the straight poop, though. ---#The Editor^IS204^G .SKIP Ever since support for I/D space arrived on the M-Plus scene to keep me from making "just one more overlay", I have tried with only limited success to convert RSX utilities to be flat, I/D tasks. One of the first programs to try was MAC, the Macro-11 assembler. Anything to make SYSgen go a little faster, right? Incredibly, the work was already done for me on one of the M-Plus Field Test kits. Included in the documentation was a TKB command file for flattening the assembler. Comparing performances of the I/D version against the "vanilla" version showed a respectable improvement which varied on the complexity of the source file. Since that early version, the "unsupported" command file has tagged along, requiring a few changes to accomodate changes in the assembler. While bringing up V3.0C, in the process of meandering through the [1,20] UFD looking at the updated command files, I noted that "support" for I/D space had slipped in. All that has to be done to enable this feature is: .SKIP o##Edit [1,20]MACBLD.BLD .BREAK o##Change the line: .BREAK ###.IFNDF $ID .SETF $ID .BREAK ###to .BREAK ###.IFNDF $ID .SETT $ID .BREAK o###Proceed with the SYSgen as usual. .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT MT: Driver SPR .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 7 .CENTER ^&MT: Driver SPR\& .SKIP ^IS144^GThe following article also appeared, as if by magic, on the Editor's desk one day. I don't know if this is for V2.1, V3.0 or both. ---#The Editor^IS204^G .SKIP 2 .CENTER Power Fail Recovery Problems with MT: Driver .SKIP 2 Problem: RSX-11M-Plus systems do not recover from power failures if the system has devices served by the MT: driver (MTDRV). .SKIP 2 Diagnosis: Under M-Plus, the power fail entry point for a device driver must handle two different calls. First, the driver is called to handle controller power fail recovery, with R2 containing the KRB address, R3 containing the CTB address, and the carry bit set. The driver is called once for each controller. The driver is also called to handle unit power fail recovery, with R3 containing the controller index, R4 containing the SCB address, R5 containing the UCB address, and the carry bit clear. The driver is called once for each unit. MTDRV makes no distinction between the two calls. The driver always assumes that R5 contains a UCB address as it attempts to select a tape unit. This causes unpredictable results when the controller power fail recovery call is performed. .SKIP 2 Solution: The following correction file to MTDRV.MAC corrects the problem. The patch utilizes the controller power fail recovery call by performing a Power Clear on the CSR in case the controller comes up in an undefined state. .SKIP 3 .NO FILL .NO JUSTIFY MTDRV.MAC;2/AU:72./-BF=[11,10]MTDRV.MAC;1 \ -2,2 .IDENT /05.07A/ -11,11 ; Version 05.07A -56 ; ; JLH001 -- Correct power fail logic % -511,511,/;JLH001/ MTPWF: BCC 188$ ; If cc- unit powerfail call BIS _#CS.CLR, @(R2) ; Power clear the controller BR 189$ ; And return 188$: BISB _#US.PWF, U.STS(R5) ; Set power fail indicator -512,,/;JLH001/ 189$: / .JUSTIFY .FILL .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT The Notebooks of Justin L. Hewser .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 6 .CENTER ^&The Notebooks of Justin L. Hewser\& .SKIP .CENTER Jim Bostwick .CENTER Cargill, Inc. .CENTER PO Box 9300 .CENTER Minneapolis, MN###55440 .SKIP At a recent LUG meeting, a stranger gave me a thick looseleaf notebook. "I'm leaving RSX for UNIX," said the stranger; "maybe somebody could use my programming notes." I barely had time to thank the masked man, much less get his name, before he had faded into the crowd. What a treasure trove! Here was an experienced RSX person who actually kept notes on how he did things! At that moment, I resolved to give these gems the widest possible distribution. This column is the result. However, as I began to leaf through the notebook, it became clear that rather than an undiscovered Ralph or Jim or Alan, what I possessed was something truly extraordinary: The notebook of none other than Justin L. Hewser himself! We all know Justin: he has been seen in nearly every programming shop. His is the desk in the corner, right next to Murphy. Yes, ^&him\&. Justin is a prolific programmer, and we have all at one time or another been forced to work with his product. Forced, because we'd sooner do real-time COBOL than look at his stuff voluntarily! _... all of which makes this column even more necessary. This may be the only existing documentation of the vast body of software produced by Justin L. Hewser. It must not be hoarded. Every programmer should be forced to benefit from it. So - each month, I will reproduce one of the programming notes from the book, along with explanatory notes of my own. The resulting collection should make a dandy supplement to your shop's programming notes. (Justin, like Murphy, will always be with us. Since we have to live with his code, we need all the help in understanding it we can get.) This month's note is from the FORTRAN section of the Notebook, though it applies equally well to most languages. It involves the use of logical assignments ("pseudodevices") to provide "device independent output". .SKIP 2 .LM +10 .RM -5 ^IS144^G*F231. -- Using Pseudodevices .SKIP Never code a device name into the program. Always use a pseudodevice. That way, real devices can be changed without redoing the program. .SKIP Do this with an ASG=dev:lun statement option to the linker. Then, install the program, and do ASN dev:=realdev: before running the program. .NO FILL .SKIP INS FOO ASN TT5:=FO1: ASN DL0:=FO2: RUN FOO^IS204^G .FILL .LM -10 .RM +5 .SKIP Justin (as is often the case) is on the right track here. His boss probably dictated the use of logical assignments, and Justin is trying hard to comply. He doesn't quite get it right, however, which may explain the margin note ("This doesn't work.") found in the original. What Justin forgot is that logical assignments are resolved at INStall time. In the example, INStall cannot find FO1: or FO2:, and defaults to SY0:. This may result in surprising behavior. ^&Bad juju\&. The quick fix is to do the device assignments before installing the program. You still have to remember to remove and reinstall it whenever the assignments change - an easy thing to forget. The correct fix is to code Assign LUN (Macro: ALUN$, Fortran: Call ASSIGN) directives in the program. Mapping of pseudo to real devices is then done at run time, not at install time. One is no longer dependent upon INStall to do what the task is able to do for itself. There is a wealth of information in Justin's notebooks. I have only begun to analyze them in detail. Here are some candidates for future columns: .SKIP o##Using Disk-resident Overlays to Reduce Checkpointing .BREAK o##Finite-Element Analysis in LISP .BREAK o##Using IND for Word Processing .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT Base Conversion Command File .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 6 .CENTER ^&Base Conversion Command File\& .SKIP .CENTER James Fullerton .CENTER Institute of Logopedics, Inc. .CENTER Research Division .CENTER 2400 Jardine Drive .CENTER Wichita, KS###67219 .SKIP Every now and then those of us who deal with PDP-11 hardware need to convert back and forth from decimal, octal and binary. Doing this by hand is tedious, and I am too cheap to add to my calculator collection by purchasing an HP-16C. Instead, I wrote an indirect command file to do most of those conversions. (The omitted conversions are binary to anything else). This is one of those things that should probably be written in some real programming language, but I didn't bother for the following reasons: .SKIP o##Most base conversions I need to do involve bases 2, 8 and 10 .BREAK o##The INDIRECT solution is reasonably fast .BREAK o##Space is at a premium on my system .BREAK o##Most conversion program images require more than six blocks! .SKIP 2 .NO FILL .NO JUSTIFY .disable lowercase,display .enable substitution,quiet ;------------------------------------------------------------- ; CONVERT converts input arguments from one base to another. ; ; Command line format: ; @CONVERT number,from,to ; where: is the number to convert, ; is the base of the number ; is the base to convert it to. ; Valid values: D (decimal), O (octal). ; Valid values: D (decimal), O (octal), B (binary). ;------------------------------------------------------------- _.if p1 = "" .exit .parse p1 ",," n from to .test n .enable lowercase _.; Make sure the input is a number _.iff .gosub error .disable lowercase _.; Test and for validity. .setf valid _.if from = "D" .or .if from = "O" .sett valid .enable lowercase _.iff valid .gosub error 'from' is an invalid base. .disable lowercase .setf valid _.if to = "D" .or .if to = "O" .or .if to = "B" .sett valid .enable lowercase _.iff valid .gosub error 'to' is an invalid base. _.; If = then no conversion is implied. _.if from = to .gosub error No conversion implied. .disable lowercase _.; If convert to binary is requested, convert to octal first. .setf binary _.if to <> "B" .goto convrt .sett binary .sets to "O" _.; Convert the number. It is possible to have conversion of _.; octal to octal here, so there is no need to convert if _.; that is the case. _.convrt: .sets base10 "" _.if from = "D" .sets base10 "." .set'from' number .setn number 'n''base10' _.if from <> to .set'to' number _.iff binary .gosub shonum ='number' _.; If conversion to binary requested, build the binary table. .sets b0 "000" .sets b1 "001" .sets b2 "010" .sets b3 "011" .sets b4 "100" .sets b5 "101" .sets b6 "110" .sets b7 "111" .sets octal "'number'" .test octal .sets bin "" .setn d 1 .setn len _.o2bin: _.; Convert one digit at a time to binary. _.if d > len .gosub shonum ='bin' .sets odigit octal[d:d] .sets bin bin+" "+b'odigit' .inc d .goto o2bin _.;------------------------------------------------------------- _.; Number display routine. _.;------------------------------------------------------------- _.shonum: .disable quiet ;'comman' .enable quiet .exit _.;------------------------------------------------------------- _.; Error message routine. _.;------------------------------------------------------------- _.error: .disable quiet ;CONVERT - 'comman' .enable quiet .exit .JUSTIFY .FILL .COMMENT .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT Topological Walk to an ODL .COMMENT +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COMMENT .TEST PAGE 15 .SKIP 6 .CENTER ^&Topological Walk to an ODL\& .SKIP .CENTER ###John Covert#####Bruce Mitchell#####Denny Walthers .CENTER Digital Equipment#######MIIM###########Kendall McGaw .SKIP ^IS144^GThis is the second in a series of reprints of landmark RSX technical articles. The original article has been augmented with text reprinted by permission from a forthcoming book by Messrs. Mitchell and Walthers, copyright (c) 1986. ---#The Editor^IS204^G .SKIP 2 .HL 1 The Overlay Descriptor Language Clearly, the Taskbuilder is not intelligent enough to figure out an appropriate memory allocation for an overlaid task. Overlay structures are specified to the Taskbuilder through a simple language called ^&ODL\&, the Overlay Descriptor Language. ODL files (viz., file containing ODL specification lines) are supplied to the Taskbuilder to control the building of a task. While ODL looks rather formidable to those unfamiliar with it, as we shall use it, it is actually quite straightforward. Macro programmers will grasp it immediately, and programmers in other languages will not find it difficult. .HL 2 The Topological Walk ODL is necessary to build overlaid tasks, so it must be learned. Fortunately, there is a relatively painless way to write overlay descriptors without an extensive knowledge of ODL. This method is topologically based, and was first presented to RSX users by John Covert of the RSX implementation group. It is called the ^&topological walk\& method. The topological walk method requires the use of a memory allocation diagram and uses a simple set of rules to build the overlay descriptor: .LIST .LE Start in the lower left corner of the memory allocation diagram in the root segment. .LE Proceed up the diagram as far as possible without hitting the top or empty space, crossing into new segments as needed. .LE Proceed to the right of the diagram until a vertical line is encountered. .LE If the current location is the base of the vertical line, cross the vertical line and go back to step 2. .LE If the current location is not the base of the vertical line, proceed down the vertical line until the line terminates. .LE If the current location is not the lower right hand corner of the diagram in the root segment, cross the vertical line and go back to step 2. .LE Return to the starting point and draw arrows in the direction of the walk at every point a line was crossed into a new segment. .END LIST Now write the overlay descriptor for the task, using the following set of rules: .LIST .LE Write: .ROOT .LE Follow the line. Write down the next element of the overlay descriptor at each arrow, based on the direction of the arrows: .SKIP o##For up arrows, write: -( .BREAK o##For right arrows, write: , .BREAK o##For down arrows, write: ) .END LIST .HL 2 Example Walk Here is an example walk on a simple memory allocation diagram: .TEST PAGE 15 .SKIP 2 .NO FILL .NO JUSTIFY xxxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxx x x x x x x x x x x x RRSEG x x RSTS x x WALLS x x FLOOR x x DOOR x x x x x x x x x x x xxxxxxxxxx _^-------xxx>------v _^-------xxx>-------xxx>------v x x x x x x x RBGSEG x x BLUE x x GREEN x x x x x x x _^--------xxx>-----------------xxx>----------------------------v x x x ROOT SEGMENT (PSROOT) x x x x-------------------------------------------------------------x .JUSTIFY .FILL .SKIP For the example shown here, the overlay descriptor produced by the topological walk is: .SKIP _.ROOT PSROOT-(RBGSEG,BLUE-(RRSEG,RSTS),GREEN,(WALLS,FLOOR,DOOR)) .HL 2 Breaking Up Complex Descriptors The topological walk method shown above produces a correct overlay descriptor for any program. It is clear, though, that for large tasks with many overlays, the descriptor produced may be much longer than one line. ODL provides methods to break up complex descriptors into a more easily readable, writeable and comprehensible form. This is done using the .FCTR (Factor) operator. The .FCTR operator breaks up complex overlay descriptors much as subroutines break up a complex program. It breaks a large and incomprehensible whole into a tree-type structure which can be readily understood. An overlay descriptor broken up with .FCTRs is the Taskbuilder's equivalent of the calling tree for the task. The .FCTR is used as follows. Looking at the memory allocation diagram for the example task, it is clear that there are three main overlay areas. Let's call them ONE, TWO and THREE. ONE contains RBGSEG. TWO contains BLUE, RRSEG and RSTS. THREE contains GREEN, WALLS, FLOOR and DOOR. Now let's break up the example overlay descriptor using the .FCTR operator. The rules for doing this are simple: .LIST .LE Working bottom to top and right to left on the memory allocation diagram, group the modules in each major overlay area. .LE Write the modules in each group down and give each group a name. .LE Make a copy of the original overlay descriptor. .LE Start with the first named group of modules. .LE At the bottom of the copy, write: : .FCTR .LE In the original overlay descriptor, find the first module in this group. Copy the descriptor onto the .FCTR line until all modules in the group are copied and all parentheses are closed. .LE Replace the copied part of the original descriptor line with . .LE Repeat steps 5 through 7 for each group until the ODL is completely processed. .LE Write .END on a line following the last line. .END LIST This process can be repeated, going one level of segments up the calling tree each time, as often as necessary to break up extremely complex overlay descriptors. If this process is carried to the extreme of individual modules, the resulting overlay descriptor is an exact model of the calling tree. .HL 2 Example Breakup Here is an example breakup of the ODL produced by the topological walk on the original memory allocation diagram: .SKIP 2 .NO FILL .NO JUSTIFY .ROOT PSROOT-(ONE,TWO,THREE) ONE: .FCTR RBGSEG TWO: .FCTR BLUE-(RRSEG,RSTS) THREE: .FCTR GREEN-(WALLS,FLOOR,DOOR) .END .JUSTIFY .FILL .SKIP This structure makes it clear that the root segment calls three major overlay areas, and clarifies the structure of each individual overlay area.