Inter-Office Memorandum
To Burdock Users  Date March 27, 1985
From Hal Murray  Location PARC
Subject Burdock Manual Organization CSL
Introduction
Burdock is a program to help debug DLion and Dicentra microcode and hardware.
Dick Snow did some of the early work on Burdock. Pitts Jarvis did most of the work on Alto Burdock. It was used to debug the early DLion hardware and microcode. If you are into trivia, ask your old timer friends about the Burdock Ether Kludge.
There are two versions of Burdock. One for debugging DLions, and another for debugging Dicentras.
There are no pictures in this memo so many details will make more sense if you can get somebody to give you a quick demo.
DLion Burdock
The DLion version of Burdock has two windows. One is for debugging/controlling the CP and one for working on the IOP. Unfortunately, the old Logic Analyzer lashup from Alto Burdock to the Tektronix logic analyzer plugin for a scope has never been revived.
I haven't worked with DLion burdock for a long time, so you should be extra suspicious about parts of this memo the talk about DLions, expecially parts that talk about the IOP.
Dicentra Burdock
The Dicentra version of Burdock also has two windows. Again, the first one is for debugging/controlling the CP. The second one is the History Buffer. It's a logic analyzer for tracing execution of CP microcode. (Dicentras don't have an IOP, so there isn't any need for an IOP Window.)
Where to find it
There is probably a Burdock subdirectory on your favorite AMesa/APilot archive directory. Mesa 11.1 is archived on [Ramrod:OSBU North:Xerox]<AMesa>11.1>. The DLion version is BurdockDLion.bcd. The Dicentra version is BurdockDicentra.bcd. They are on the Burdock>Friends subdirectory. (You don't need anything else to get Burdock off the ground. The CP Kernel microcode and things like that are TableCompiled and Bound into the config.)
Numbers are HEX
Burdock thinks in HEX! Except for a few places like messages that printout bits/second, ALL numbers in Burdock default to HEX. When typing in numbers, you have to use a leading 0 if it would start with a letter. If you want to specify a decimal number, append a 'd. If you want to specify an octal number, append a 'b. For uniformity, you can append a 'x, but that's the default.
User.cm
Burdock uses the normal Tools Window routines. At startup time, they scan your user.cm to determine where to place the windows. I suggest you add the following to your user.cm.
  [CP Panel]
  WindowBox: [x: 0, y: 30, w: 512, h: 540]

  [IOP Panel]
  WindowBox: [x: 512, y: 30, w: 512, h: 540]

  [History Buffer]
  WindowBox: [x: 512, y: 30, w: 512, h: 540]
Hardware Requirements
You need a DLion to run Burdock.
To debug a second DLion, you also need a pair of Song boards. One board is mounted on each DLion. It plugs into the Burdock Port on the IOP. That's an 18 pin socket on the bottom front of the IOP board as you face the machine. It's outside the stiffening bar. The Song boards are connected by some cables. I don't know the details. (You can also use a Burdock Box, but you won't like that since something is flakey, and you will loose contact with your debuggee at the critical point.)
The debuggee DLion also needs a special Kernel PROM on the IOP board. It's a replacement for the PROM containing the boot time diagnostics. Beware: A DLion with a Kernel PROM won't boot unless it is connected to a Song board or a Burdock Box.
To debug a Dicentra, you need a Debugger board and its cable. One end of the cable plugs into the 26 pin connector on the Debugger board. The other goes into the Burdock Port on the DLion's IOP.
Bugs
No matter what you type, Burdock shouldn't go to CoPilot, CoCoPilot, 915 or whatever. If you find a problem, tell me. It's probably easy to fix it.
Panels
The bottom part of the CP Window and the IOP Window is a control Panel. Panels don't follow the normal Tajo user interface conventions.
Each Panel has three columns of tiles. Each tile has a flag character, a left side that contains a symbolic location to be displayed, and a right side that shows the contents of that location. As you move the mouse around in a Panel, the side of the tile under the mouse will be blackened.
The flag character is normally blank. It is a * if the contents of that tile have changed during the last refresh of that cell. It is a ~ if the location has changed but the CP or IOP is running so the contents can't be refreshed.
If you click the left mouse button (Point) while it is over a blackened tile, the contents of the TypeIn field will be stored into the blackened tile slot. If TypeIn is empty, the current selection will be used. If the store goes into the left side of a tile, the corresponding contents to the right side will be displayed. If the store goes into the right side of a tile, they will be read back and displayed. Note that there is a separate TypeIn slot for each Panel.
If you click the right mouse button (Adjust) over the left or right sides of a tile, it's text string will be appended to TypeIn.
If you click the left mouse button (Point) over a tile while LeftShift is down, the left side of the tile will be bumped by +1 and the right side of the tile will be refreshed. TypeIn is used as a work area for the symbolic evaluation of the expression. The text for the new left side will be normalized by the symbol machinery. (If there is a name it will be used. If not the closest one will be used to build a symbol+number expression.)
If you click the right mouse button (Adjust) while LeftShift is down, the left side of the tile will be bumped by -1 and the right side of the tile will be refreshed. (Again, TypeIn is used as a work area.)
If you click the right and left mouse buttons (Menu) while LeftShift is down, the column will be filled by adding +1 to the left side for each tile in the column, and the corresponding right sides will be displayed. TypeIn ends up with the symbolic expression for the last tile used.
You can scan things rapidly by holding the mouse over the top tile of a column and alternately doing stores and fills.
CP Window
The CP Window is used to examine and control the CP. It has 3 sections. The top section is a FileWindow used to record a running commentary of various interesting things. The log file is CP.log$. The second section is a FormSW. Most of it is commands, but there are a few typein slots and a slot to show the current state of the CP. The rest of the window is the CP Panel.
CP State
Burdock keeps track of the State of the CP. Many operations require that CP to be in a reasonable state. CP/IOP Dead means that the CP has crashed, the IOP has crashed, or the CP hasn't been Booted yet. Halted means that the CP has been initialized (Booted) and is now stopped. It could have run some already. If so it has been manually stopped. Running means that the CP is running user code. (It's running the CP Kernel when it's in the Halted or CPBreak states.) CPBreak means that the CP has hit a breakpoint. IOPStopped means that the IOP is stopped or at a breakpoint. The CP must be Stopped before it can be manipulated. The CP could be stopped automatically when the IOP stops, but refreshing the CP Panel usually takes several seconds, and that's a waste of time if you are chasing an IOP bug.
Burdock polls the state of the CP. When it changes a message is printed in the log window. If it changes to Halted or CPBreak, the CP Panel is refreshed.
Built-in symbols
The CP symbol manipulaton routines contain a large collection of built-in symbols.
.CR n is location n of Real Control Store. .CV n is location n of Virtual Control Store. (The nth instruction in the microcode listing.) Pass 2 of Mass determines the mapping between CR and CV.
.MR n is location n of Main Real memory. .MV n is location n of Main Virtual memory.
.MAP n is the nth word of the map.
.RH n, .R n, .U n, .TPC n, .LINK n, Q, and L0 through L7 are the obvious things. So are .IB, .PC16, .STACKP, .IBPTR, .MINT, .EKERR.
A number is normally interpreted as a location in main memory.
If an expression for an R register in the left side of a tile in the CP Panel is prefixed with a $, the RH/R pair will be displayed as a 24 bit number.
CP Kernel
The CP Kernel currently (11.1) uses locations 0F6F, 0F77 and 0F7F through 0FFF. (Except for a typing error, the appropiate reserves are in InitDLion.mc.) I think the Dicentra version is actually a few words smaller, but I haven't gotten interested enough to check. For Diagnostics and such where space isn't critical, I reserve 0F5F through 0FFF.
CP Breakpoints
The DLion CP can have up to 16 breakpoints. The Dicentra can have up to 256.
While the CP is stopped, the breakpoints are temporarily removed so they will be invisible if you examine Control Store. When the CP is started, the instruction at each breakpoint is replaced with a jump to the CP Kernel.
Breaks at c2 and c3 are risky. If a memory operation was started, the results will be lost. You can't set a break at a c* instruction because Burdock needs the cycle info to build the right breakpoint instruction. If you hit a breakpoint on the wrong cycle, Burdock will probably declare the CP to be dead. (This whole mess is asking to be cleaned up. It might not be too hard.)
CP Commands
Boot! goes through various steps to initialize the CP and the CP Panel so you can start debugging. It forgets all the current CP symbols and break points. It then does a low level boot on the CP. On the DLion, this will automatically boot the IOP unless it is already talking to Burdock. Then the CP Kernel is loaded into Contol Store, and the CP Kernel task is started up running the Kernel. Dicentras don't have tasking, but the innards of Burdock save and restore the CP's PC to fake the kernel and emulator tasks. After the CP Kernel is loaded, Burdock looks around for extra banks of Control Store, and if it finds any, it loads a copy of the Kernel into each extra bank. Finally, Burdock reinitializes the CP Panel.
All of the various Load commands use the current selection to specify a filename. For loading microcode, the default extension is .fb. For loading symbols, the extension is .st.
Load! is used to load microcode into Control Store. First it resets the CP symbols, CP breakpoints, and CP Panel. Then it loads the microcode. Then the CP Panel is reset.
LoadMore! loads microcode and symbols without resetting anything. This is useful if you have more than one bank of Control Store. (The symbol tables probably get confused if you load two hunks of microcode into the same bank, even if they don't smash each other. This could be fixed.)
Start! evaluates the current expression as a CP symbol. The answer contains a task number, a cycle number, and a control store address. If the cycle number is c1, then the TPC for the specified task is set to the control store address. Then the CP is Continue!ed.
Continue! just lets the CP start running again. On a DLion, the IOP will be continued too if that makes sense.
Stop! stops the CP. The CP Panel will be automatically refreshed.
Run! runs a Burdock command file. The filname is in the File: slot. If that is empty, the current selection is used. The default extension is .burdock.
LoadRaw! is a hack for loading a diagnostic or scope loop when the CP is too sick to run Burdock's Kernel. It resets everything, loads the microcode and symbols, and then starts running the CP's Kernel task. Thus your microcode should specify a StartAddress for task 7.
LoadNoSyms! is like Load! except that loading the symbols is skipped. This saves time if you don't need them.
LoadSymbols! is used to load symbols when you change your mind after using LoadNoSyms.
LoadGerm! is used to load a germ into memory. It assumes that the initial microcode has already initialized the map. The default extension is .germ.
LoadReal! is leftover from the old Alto days before LoadGerm and LoadBoot existed. The default extension is .cpr. It loads a file into CP main memory. This was also used to dump fancy pictures into DLion display memory.
Using LoadReal to load a germ is a krock. Unfortunately, nobody has taken the time to cleanup the mess in this corner of the DLion world. Most of the space in the germRM files is taken up by blank map entrys, and thus most of the time spent loading the germ is wasted. On top of that, you need a separate file for each size machine.
LoadBoot! loads a boot file. Like LoadGerm, it assumes that the initial microcode has already set up the map. The default file extension is .boot.
Refresh! refreshes the CP Panel. This involves reading all of the specified locations and updating the display. A * will appear next to each slot that changes. The display is automatically refreshed each time the CP is stopped or hits a breakpoint. Manual refresh can be used to see if the hardware has changed it's mind, or to catch the sneaky case when you have two slots pointing at the same register and you changed one of them since the display was last refreshed.
What! evaluates the current selection as a CP symbol and prints the answer out in hex, decimal, and octal. If the selection is just a number, this can be used to convert from one base to another.
ListBreaks! lists the current CP breakpoints.
ClearAllBreaks! forgets all of the current CP breakpoints.
UnBreak! evaluates the current selection as a CP symbol, and if there is a breakpoint at that location, it is cleared.
Break! evaluates the current selection as a CP symbol, and sets a CP breakpoint there.
Compare! uses the current selection to read a microcode file. Each word is compared with the contents of Control Store. If they are different, an error message is printed. (On a Dicentra, this can be used to check Control Store PROMs. See the Dicentra documentation.)
CrossJump! is a hack to help microcoders locate instructions that might be easy to bum out.
Remember, it's a hack. Thus the user interface is a bit crude. First Boot the CP and Load your microcode. Then, without changing the selection, poke CrossJump. Each line of prinout contains a list of addresses. The instructions at those locations are all identical.
The trick is to look at (all) the previous instructions of each candidate to see if any of them can be changed to jump to one of the alternates. Lots of times you can't do it because of addressing constraints. If the constraint is loading a link register, you can sometimes move it back an instruction or two.
When I scanned the microcode I'm using in the Dicentra, the printout was 2.5 pages long. I easily found a dozen instructions to merge, and there were another dozen (or so) in parts of the Emulator that I have not changed from the DLion.
IOP Window
The IOP Window is used to examine and control the IOP. It has 4 sections. The top section is a small FormSW with 2 commands. The next section is FileWindow used to record a running commentary of various interesting things. The log file is IOP.log$. The third section is a FormSW. Most of it is commands, but there are a few typein slots and a slot to show the current state of the IOP. The rest of the window is the IOP Panel.
IOP State
Burdock keeps track of the State of the IOP. Many operations require that IOP to be in a reasonable state. Dead means that the IOP has crashed, or it hasn't been Booted yet. Booted means that the IOP has been initialized (Booted) but the PC hasn't been initialized yet. Halted means that the IOP has been running and is now stopped. Running means that the IOP is running user code. (It's running the IOP Kernel when it's in the Booted, Halted or Break states.) Break means that the IOP has hit a breakpoint. CP Halt/Break means that the IOP is in limbo because it noticed that the CP encountered a breakpoint or it was halted (by Burdock) to halt the CP.
Burdock polls the state of the IOP. When it changes a message is printed in the log window. If it changes to Halted or Break, the IOP Panel is refreshed.
IOP Breakpoints
IOP Breakpoints use an RST 2 instruction. You can assemble one into your code to "Call Burdock".
There is no limit to the number of IOP breakpoints that can be active at the same time.
Built-in symbols
The IOP symbol manipulaton routines contain several built-in symbols.
B, C, D, E, H, L, M, A, PCH, PCL, SPH, SPL, Flags, and RIM are symbols for the obvious registers. BC, DE, HL, SP, PSW, and PC are symbols for the obvious register pairs.
A raw number is an address in IOP memory.
If an expression for an address in IOP memory is prefixed with a $, that location will be displayed in word mode. If an expression for an address in IOP memory is prefixed with %, that location will be displayed as an instruction.
IOP Commands
Stack! displays clumpSize words from the stack.
Instructions! evaluates the current selection as an IOP symbol, and then starting there, displays clumpSize instructions.
Boot! goes through various steps to initialize the IOP and the IOP Panel so you can start debugging. It forgets all the current IOP symbols and break points. It then does a low level boot on the IOP and establishes contact with the IOP Kernel. Finally, Burdock reinitializes the IOP Panel and preloads it with a default collection of tiles. This operation leaves the CP in the Dead state.
All of the various Load commands use the current selection to specify a filename. For loading IOP code, the default extension is .bin.
Load! is used to load microcode into IOP RAM. First it resets the IOP symbols, IOP breakpoints. Then it loads the IOP code. Then the IOP Panel is reset.
Start! evaluates the current expression as an IOP symbol, sets the PC to that location, and Continue!s the IOP. The CP will be automatically continued first if that makes sense.
Step! lets the IOP execute one instruction and then refreshes the IOP Panel. This is implemented by automatically inserting a breakpoint at the next location, so that interrupt routines may get to run. If the instruction to be executed is a conditional jump, two breakpoints are inserted.
Continue! just lets the IOP start running again. Again, the CP will be automatically continued first if that makes sense.
Stop! stops the IOP. The IOP Panel will be automatically refreshed.
Run! runs a Burdock command file. The filename is in the File: slot. If that is empty, the current selection is used. The default extension is .burdock.
LoadNoSyms! is like Load! except that the symbols are not loaded into the symbol table. This saves time if you don't need them.
LoadSymbols! is used to load symbols when you change your mind after using LoadNoSyms.
LoadModSymbols! loads the symbols for the module specified by the current selection.
Refresh! refreshes the IOP Panel. This involves reading all of the specified locations and updating the display. A * will appear next to each slot that changes. The display is automatically refreshed each time the IOP is stopped or hits a breakpoint. Manual refresh can be used to see if the hardware has changed its mind, or to catch the sneaky case when you have two slots pointing at the same register and you changed one of them since the display was last refreshed.
What! evaluates the current selection as an IOP symbol and prints the answer out in hex, decimal, and octal. If the selection is just a number, this can be used to convert from one base to another.
ListBreaks! lists the current IOP breakpoints.
ClearAllBreaks! forgets all of the current IOP breakpoints.
UnBreak! evaluates the current selection as a IOP symbol, and if there is a breakpoint at that location, it is cleared.
Break! evaluates the current selection as a IOP symbol, and sets a IOP breakpoint there.
HB Window
The HB Window is used to examine and control the history buffer. It has 2 sections. The top section is a FormSW used to interact with the history buffer. The rest of the window is FileWindow. Mostly, it is used to display the microcode PCs that were recorded by the history buffer hardware. The log file is HB.log$.
HB Operation
The history buffer is a 256 word RAM. Each time the clock ticks, the microcode PC and 8 extra bits are written into a word of the RAM, and the pointer into the RAM is advanced. When the PC matches the specified Target, n more words are written, and then the RAM is frozen. If n is big, the buffer will contain mostly data for events after the trigger. If n is small, the buffer will contain data for events before the trigger point.
Think of the history buffer as a horizontal strip of 256 cells with time going from left to right. The trigger point must be located somewhere within the strip. The software does all the work needed to correct for the wraparound of the buffer pointer. Offset is a parameter slot in the HB Window that controls the distance from the left edge of the buffer to the trigger point. If Offset is small, you get mostly events after the trigger point.
When the history buffer finishes collecting a sample of data, Burdock will automatically printout the information. Since 256 samples is usually way more than desired, the HB Window contains 2 more parameters to control the printout. Before is the number of words to the left of the trigger to be printed. After is the number of words to the right of the trigger point to be printed.
Warning: Before, Offset, and After are decimal numbers.
HB Printout
The history buffer printout is several columns for each sample.
The first column is the decimal offset of this line from the front of the buffer. It will be preceded by a * if this is the trigger point.
The next column is the PC in hex.
The next two columns are the 8 extra bits in binary and hex. Look at the prints to see the default setup for the extra bits.
The next two columns assume the standard setup for the extra bits. It will show a "D" is DoIt is on, and c1, c2, or c3 depending upon the cycle.
The last column is the symbolic location in control store corresponding the the PC. If the cycle number of that instruction doesn't match what's observed in the extra bits, a conspicious warning will also be printed.
HB Clocks
There are 4 possible clocks that can be used to write data into the history buffer
Clock will show every microinstruction. This is normally the desired case.
ARC (Always Running Clock) will also show wait states. There is at least one with every microinstruction, but memory operations normally include several more.
Cycle1 will show the first microinstruction of each click. (Actually, it triggers during c3 since that's when NIA is pointing to a c1 instruction.) This just reduces the amount of data that gets stored by a factor of 3. Almost always, you can guess what the missing instructions were.
IBDisp will show the first instruction of each new Mesa byte code. Except for unusual cases, this is not very interesting.
HB Commands
Arm! evaluates the string in Target as a CP symbol, and sets up the HB matcher to trigger on that address.
Display! displays the data in the history buffer using the current values of Before and After.
ManualTrigger! kicks the hardware so that it acts like the address matcher has seen the target. Again, Burdock will automatically display things. This is handy if you don't know what your microcode is doing. You need to Arm the HB before ManualTrigger will do anything. If you can't think of any symbol to type into Target so you can Arm things, use .CR 0.
Fine print: If you are clocking on IBDisp, and you get a CP Break shortly after triggering the history buffer, it may appear as though it hasn't yet triggered. That's because there haven't yet been enough IBDisps to finish filling up the buffer. ManualTrigger will automatically switch to ARC clocking for long enough when necessary to avoid this problem.
LoadArmAndGo! does a LoadRaw of the file specified in File, Arms the history buffer at the location specified at Target, and then Continues the CP. This is a convenient way to start a low level CP diagnostic.
BB! (Boot Button) flaps INIT/ on the Multibus backplane.
There are several commands on the History Buffer Window that are mostly left over from hardware debugging.
Stop! stops the CP.
Step! lets the CP execute an instruction.
StepFast! goes into a loop single stepping the CP. This is handy for scoping the stop/go operations.
StepFastFromCSA! is like StepFast, but the UseCSA bit is left on, so the Debugger board provides the same next instruction independent of where the microcode tries to jump.
Go! undoes the effects of Stop.
UseROM is a boolean used to switch the debugger board into working with the Control Store ROM on the CP board. This can be used to Compare microcode on the disk with the contents of PROMs. UseROM doesn't do anything until the next time you interact with the debugger board, so poke BB! or something to make sure it gets noticed.
Command Files
Burdock has a complicated command file facility. Fortunately, reasonable problems are easy. The easiest way to get a command file going is to start with an existing one, and make whatever changes are necessary.
Command files can be run from the Run! command in the CP window or the IOP window, or from the Burdock.~ command in the Exec. The default extension for command files is .burdock.
Any error in a command file terminates execution immediately. The error message includes the position within the command file of the offending statement.
Comments
Text enclosed with matching |s is ignored.
Functions
Most of the commands available in the CP or IOP windows are also available as functions within Burdock command files. They use Mesa procedure call syntax. If the names would clash, the names for the IOP commands are suffixed with "IOP". For example, "Boot[];" will boot the CP, "BootIOP[];" will boot the IOP, and "Break[Foo];" will set a CP breakpoint at location Foo.
Arguments to commands should be quoted if they might confuse the scanner.
Commands that start execution take an additional parameter: the number of milliseconds to wait for the CP or IOP to stop running. (The normal reason for stopping is a breakpoint.) An omitted parameter means don't wait at all. (Of course, you can't do much while it's still running.) A value of 0 means wait forever. Remember, numbers used to specify wait times are interpreted as hex.
Here is a checklist of CP commands:
  Boot[];
  Break[where];
  ClearCPPanel[];
  Compare[filename];
  Continue[(waittime)];
  Load[filename];
  LoadBoot[filename];
  LoadGerm[filename];
  LoadMore[filename];
  LoadNoSymbols[filename];
  LoadReal[filename];
  Reset[];
  SetBank[bankNumber];
  Start[filename(, waittime)];
  Stop[];
  Unbreak[where];
Here is a checklist of IOP commands:
  BootIOP[];
  BreakIOP[where];
  ClearIOPPanel[];
  ContinueIOP[(waittime)];
  LoadIOP[filename];.
  LoadIOPModuleSymbols[filename];
  LoadIOPNoSymbols[filename];
  LoadIOPSymbols[filename];
  StartIOP[where(, waittime)];
  StopIOP[];
  UnbreakIOP[where];
Here is a checklist of HB commands:
  Arm[where];
Panel Setup
Command files can also initialize tiles in the Panel areas. "CP[3,0]! Foo" stores "Foo" into the left side of the tile in the third row of the first column in the CP Panel. "CP[3,0]! Foo ← 13" sets it up and then stores 13 (hex) into Foo. "IOP[..]" is used to setup IOP tiles.
Tiles can be named (for use with conditionals and WriteLoc) by preceeding the CP with tileName=. It's a good idea to use the name of the register in the tile as the name of the tile.
Conditionals, Branching, Hacking
SetMP[tileName] puts the right side of a tile into the MP. (This number won't be in hex.)
Tag: defines tag at the current position in the command file.
GOTO[tag] resumes execution of the command file at the position corresponding to tag. Forward and backward jumps are both legal.
IF operand relation operand {...};. Each operand is either a tileName or a hex constant. The relations include >, >=, <, <=, =, and #. Conditionals can be nested.
Log Files
Close[]; closes the current log file if there is one open.
OpenToAppend[filename]; opens a log file in append mode.
OpenToWrite[filename]; opens a log file in write mode.
Write[quoted string]; writes its argument into the log file. (Write[] is legal, and doesn't do anything.)
WriteLine[quoted string]; writes its argument into the log file, and then writes a CR. WriteLine[] just writes a CR.
WriteLoc[tileName(, width)]; writes the right side of the designated tile into the log file in hex. If width is specified, leading blanks will be added to make the string written at least that wide.
WriteTime[]; writes the current time into the log file.
Simple nontrivial example
| Mumble.burdock, HGM, March 22, 1985 2:18:56 am PST |
Boot[];
Load[MemTest];
errorCount= CP[00, 0]! errorCount ← 0;
passCount= CP[01, 0]! passCount ← 0;
reason=  CP[02, 0]! reason ← 0;
address=  CP[03, 0]! $address ← 0;
expected= CP[04, 0]! expected ← 0;
found=  CP[05, 0]! found ← 0;
Break[Error];     | reason = 1 |
Break[AnotherGoodPass]; | reason = 2 |
Loop:
Continue[0]:
SetMP[passCount]:
IF reason = 2 { GOTO[Loop]; }:
OpenToAppend["Mumble.log"];
WriteTime[];
WriteLoc[errorCount, 4];
WriteLoc[passCount, 5];
WriteLoc[address, 8];
WriteLoc[expected, 5];
WriteLoc[found, 5];
WriteLine[];
Close[];
IF errorCount < 100 { GOTO[Loop]; }:
Want more details?
Look at the code. It's CommandFiler.mesa.
Odds and Ends
Because it already contained related code, the Burdock subdirectory and/or df file also include several other handy programs.
Hardware checkout
TestUmbilical is a program for checking out DLion-DLion Burdock Boxes. I assume it works with Song boards too, but I've never tried it. TestUmbilical is pretty simple minded, but I have forgotten all the details. It probably includes several scope loops. Look at the source code if you have any questions.
TestDebuggerBoard and TestHistoryBuffer are used to debug the Dicentra debugger board. See the Dicentra Manual for more information.
CSBankTester is used to test extra banks of CP Control Store. It is packaged with Burdock as an inactive tool because the DLion uses the CP Kernel to set the bank register.
CPKernelTester is leftover from when I was trying to understand how the CP Kernel worked. It might be handy if you are chasing obscure problems. It too is packaged with Burdock as an inactive tool.
Making Dicentra PROMs
MakeControlStoreMB and MakeGermMB are used to make Dicentra PROMs. They register Exec commands with the corresponding name.
Mesa Debugging
When bringing up the first member of a new family of machines, there is a time when it mostly runs, but the Emulator or Germ doesn't work well enough to be TeleDebugged. At this stage, you end up doing a lot of pointer chasing to follow stacks and such. Machines are good at that sort of thing. I'm lazy.
CPMesa is a tool that is included with Burdock. Normally it's inactive. It has two commands. DispStack displays the current stack in HEX. Each frame is a separate line. ListProc displays the current list of processes.
CP Symbols
CPSymbolsDebug is another normally inactive tool that comes packaged with Burdock. It's leftover from when I was debugging the symbol table machinery. It will dump the symbol tables into a log file. If you are trying to understand all the uses for all of the registers, this might be handy. (Use the What command if you are just interested in a few registers.)