Page Numbers: Yes X: 530 Y: 10.5" First Page: 1 Not-on-first-page
Margins: Top: 1.3" Bottom: 1"
Heading: Not-on-first-page
Internal Description of MidasEdward R. Fiala30 November 1979
INTERNAL DESCRIPTION
OF MIDAS
30 November 1979
by
Edward R. Fiala
Xerox Palo Alto Research Center
3333 Coyote Hill Rd.
Palo Alto, CA. 94304
Filed on: [Ivy]<DoradoDocs>MidasInternal.press
Sources on: [Ivy]<DoradoSource>MidasInternal.dm
This document describes the internal organization of Midas, so that anyone who wishes to do so can adapt Midas to a new hardware system.

TABLE OF CONTENTS
l.Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.How to Get Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.General Organization and Command Files . . . . . . . . . . . . . 7
4.Source File Organization . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.Picking Up New Midas Releases . . . . . . . . . . . . . . . . . . . . 8
6.Storage Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
7.Display Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
8.Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10
9.Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
10.Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
11.Every Time List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13
12.Files and sysZone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
13.Errors and Overlays . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
14.Hardware Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
15.Debug Overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20
16.Test Overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21
17.Field Overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
18.PEScan Overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
External Procedures and Statics by File
1.Midas.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23
2.MInit0.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
3.MInit1.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26
4.MInit2.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
5.MTxtBuf.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
6.MAsm.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
7.MData.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31
8.MSym.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32
9.MSymOv.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
10.MIOC.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
11.MOverlay.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34
12.MDisp.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
13.Gacha10.Br . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
14.MRgn.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
15.MMenu.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
16.MMprgn.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39
17.MMprgnOv.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
18.MCmd.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
19.MCmdOv.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43
20.MBrkP.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43
21.MGo.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43
22.MGoOvl.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
23.MRGo.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
24.MLoad.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
25.MPattern.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
26.MDebug.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
27.MDebugAsm.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
28.MTest.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46
29.MFieldLp.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
30.MCollect.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
31.MPEScan.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
32.MPrins.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
33.xxActions.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
34.xxTables.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
35.xxREG.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48
36.xxMEM.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
37.xxRES.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49
38.xxBrkP.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
39.xxGo.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
40.xxLoad.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
41.xxDebug.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
42.xxTest.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
43.xxTestAsm.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
44.xxField.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
45.xxFieldAsm.Asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
46.xxPEScan.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .52
47.xxVM.Bcpl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
1. Introduction
This document is intended to serve as a guide for people who wish to adapt Midas for use as a debugger on a new hardware configuration. It is revised from time-to-time, but should not be relied on for total accuracy--see the sources to answer detailed questions.
2. How to Get Started
There are two Midas implementations which you might wish to use as a starting point: D0 and Dorado. Both implementations share a large body of machine-independent code, with D0 Midas not using some of the hardware checkout modules. D0 Midas interfaces to the hardware by exchanging messages with a kernel microprogram running on the D0; it can cause the D0 to boot itself, but its control over the hardware is then limited to whatever the kernel can do; the kernel program implements stop-and-go, insert/remove breakpoints, and register/memory read-write.
Dorado Midas controls the hardware directly, which allows a number of hardware checkout aids that would be impractical on the D0. Dorado Midas is more extensively developed, with numerous actions for setting the clock speed, doing parity-error scanning, hardware configuration control, and other features.
Breakpoints are simply implemented on Dorado, complicated on the D0 (because Dorado microinstructions have breakpoint bits, while D0 microinstructions don’t, so on D0, the broken instruction must be saved and restored). Microprocessor stop and go is complicated on both machines. Hardware reset is complicated on the Dorado, less so on the D0.
If you want a quick, primitive Midas implementation, you should probably start with D0 Midas; if you want a medium to fully developed debugging system, then your choice might be governed by whether Midas will control the target machine through a kernel program (in which case start with D0 Midas) or directly (in which case start with Dorado Midas); you may wish to obtain listings of both versions for comparison purposes.
The discussion below assumes that you start with the Dorado Midas; the instructions below would be similar for D0 Midas, for the most part replacing "Dorado" and "D1" by "D0" is would you would do.
1. Step 1 was to obtain this document ([Ivy]<DoradoDocs>MidasInternal.Press) and the user manual ([Ivy]<DoradoDocs>MidasManual.press); you should read the user manual through, skipping sections obviously specific to the Dorado implementation. Then you should read the first part of this document (stop when you get to the description of the external procedures); then return to these instructions.
2. Obtain a blank (i.e., useless) Alto disk, ether-boot the NetExec, and run NewOS.boot. Go through the long installation dialog selecting the "Erase a disk before installing" option. When that finishes, retrieve [Ivy]<DoradoSource>MidasDevelopmentDisk.Cm and execute it. This will setup your Alto disk with the files needed to prepare Dorado Midas. Note that your disk will have been loaded with .br files from MidasOtherBinaries.Dm but will not contain the sources for these; if you have to obtain these sources for some reason, they are on [Ivy]<DoradoSource>MidasOtherSources.Dm.
3. Use Empress to print D1Prin2.Bcpl, D1Reset.Bcpl, D1GoOvl.Bcpl, and D1LdrTest.Bcpl. You won’t need these files, but they may be useful to you as examples, so get the listings now.
4. Delete D1Prin*.*, D1Sim*.*, D1Mic*.*, D1Config.Bcpl, D1Reset.Bcpl, D1Poke.Bcpl, D1Ti.Bcpl, D1hwcheck.Bcpl, D1mic*.*, D1instrs.D, and D1DMux.D. These source files for the Dorado Midas are totally uninteresting to you, except for the ones which you have already listed. The remaining files named D1*.* contain stuff which you will be modifying to adapt Midas to your new hardware system.
5. The disk prepared with the MidasDevelopmentDisk.Cm command file includes the runtime files for Dorado Midas. If you have not used Midas before, you might want to try out the Dorado Midas on your Alto to see how different features work--it will operate intelligibly without any hardware connected to your machine. After playing with Midas.Run, delete all of the files named *.Midas except for Midas.Midas and Special.Midas and delete Midas.Run, Midas.Syms, Midas.Bs, Midas.Fixups, Midas.Compare, Midas.RunProg, and Midas.Dtach; DO NOT DELETE Midas.Bcpl, Midas.Errors, or Midas.Programs.
6. Your disk will also have Neptune.Run, Chat.Run, Micro.Run, and Empress.Run, which can be deleted if space is tight.
7. Print *.Bcpl, *.Asm, *.D, *.Cm, *.Midas, *.mc, and Midas.Programs; make two notebooks sorted in the order of the files in MSources.Cm and D1Sources.Cm; you have already deleted most of the files named in D1Sources.Cm, so don’t worry about the ones that don’t exist. In each notebook you can conveniently group all *.Cm files into a single section; use another notebook section for *.Midas and Midas.Programs. You will gradually replace the files in D1Sources.Cm by your edited versions of these as you adapt Midas to your new hardware configuration.
8. There are only a few edits to the files in MSources.Cm required, as discussed in the "Hardware Interface" section later.
9. You should recompile the machine-independent part of Midas with @MComp.Cm when you have completed the edits for ValSize, TValSize, etc.
10. Edit the D1xx.Bcpl and D1xx.Asm files and convert these as appropriate for your hardware; comments in the listings should serve as a guide for how to do the editing. Replace the "D1" part of these file names with a good prefix for your hardware (e.g., "M68", "D0", etc. have been used for other implementations of Midas); write your edited versions of the D1*.* files onto files with appropriately chosen names. When you are happy with your edited versions, you can delete the D1*.* files (but probably retain the original listings in case some problem comes up later).
11. A good order for editing the files is as follows:
a. D1.d and D1regmem.d
b. D1i0.bcpl (use the Doradomc.Br microcode file until such time as you implement your own special microcode).
c. D1i1.bcpl
d. D1i2.bcpl
e. D1Tables.Asm (fill in each table with stuff for your registers and memories--all edits are straightforward; initially use RDatatoCSS and MDatatoCSS for all the prettyprint table entries; later replace these with special prettyprint procedures when you code them).
f. In D1Asm.Asm edit CertifyAV and ConvertAV for your hardware; retain the error strings and the GetFrame thing near the beginning of the file; delete approximately everything else.
g. D1reg.Bcpl and D1mem.Bcpl (complicated edits to create the Get and Put procedures for your registers and memories).
h. D1res.Bcpl (may want to put some code in ReadAllRegs depending upon how you arrange the Get and Put interface to your hardware).
i. D1Go.Bcpl (complicated edits and the procedures are not designed very well, but can probably struggle through these eventually; may have to change MGo.Bcpl also--many changes were made in MGo.Bcpl for D0).
j. D1Debug.Bcpl (probably no edits required)
k. D1Field.Bcpl and D1Fieldasm.Asm (may want to rip this out by removing the entry for the field test in D1actions.Asm; otherwise easy edits)
l. D1Test.Bcpl D1TestAsm.Asm (easy edits, but might want to eliminate the Test, TestAll, continue-test, and continue-tall items from D1Actions.Asm altogether)
m. D1Load.Bcpl (easy edits).
n. D1PEScan.Bcpl (might want to rip this out unless you have memories that can be scanned for parity errors).
o. D1Actions.Asm--may want to remove some actions or add some; may want to change some of the flags in the table and in MCommon.D.
p. D1VM.Bcpl--probably want to retain FastSearch and RetrieveBlock procedures; VA/AA stuff may or may not be relevant to your hardware.
12. Replace the D1Sources.Cm, D1Binaries.Cm, D1Comp.Cm, D1DumpSources.CM, and D1DumpRun.Cm command files with the equivalents for your implementation.
14. Edit the D1Load.Cm command file as appropriate for your implementation; be careful not to change the ordering of the Init2, Load, and Test overlays; be sure to leave the init0 and init1 files in the correct place. There is some advantage in putting the most frequently accessed overlays immediately after Test because Midas will fill any left-over core space with the first few overlays.
15. Copy the relevant Builtin definitions and mimic the memory definitions on page 1 of D1DLang.Mc and mimic the address symbol definitions in Loader.Mc to create a micro source file which defines the memories in which you have pre-defined symbols. This will include copying the stuff for the MDATA memory (BITS-CHECKED, etc.) and the MADDR memory (LOOP-COUNT, etc.) from Loader.Mc; the other stuff in D1DLang.Mc and Loader.Mc is irrelevant. You will wind up with a source file that can be assembled with Micro to produce a .Mb (micro-binary) file which defines these addresses for loading by the Midas.Midas command file.
16. Edit the Midas.Midas command file (controls the initial display configuration) and Midas.Programs (defines command files).
17. Edit the D1DumpRun.Cm command file as appropriate for your Midas; it should contain the names of the *.midas files that you ordinarily dump as part of a Midas release.
18. Recompile the machine-dependent part of Midas with your equivalent of @D1Comp.Cm.
NOTES:
1. Avoid changing stuff in the machine-independent part of Midas because this will prevent you from incorporating new releases of Midas in the future without massaging the files you have edited. A particularly troublesome area in Midas is the "Go" stuff which you may be tempted to change because it is rather kludgey; if you think of a better way to do this, please talk with Fiala to see if this can be made better.
3. General Organization and Command Files
Midas is stored on [Ivy]<DoradoSource> in five dump files:
MidasSources.Dmmachine-independent source files
MidasDoradoSources.Dmmachine-dependent source files for Dorado Midas
MidasOtherBinaries.Dm.Br and some other files needed by Midas that don’t have sources in MidasSources.Dm (MDI.Br, LoadRAM.Br, Overlaysinit.Br, DoradoMC.Br, Gacha10.Br, MDirs.Br, DirScanA.Br, DiskStreamsScan.Br, KeyStreamsA.Br, and KeyStreamsB.Br)
MidasOtherSources.Dmsource files for MidasOtherBinaries.Dm and some other stuff not ordinarily needed during Midas development
DoradoMC.Dmsources for special Alto microcode needed for Dorado Midas (also need the BCPLRuntime microcode package).
Midas also uses (from [Maxc1]<Alto>) Time.Dm (contains TimeConvA.Br, TimeConvB.Br, and TimeIO.Br), and LoadRam.Br. MidasOtherBinaries.Dm contains OverlaysInit.Br and MDI.Br, which are variations of standard packages that you should not replace by more recent releases. Gacha10.Br (in MidasOtherBinaries.Dm) is obtained by applying the program MakeFont (from MakeFont.Bcpl) to Gacha10.Al.
The DoradoMC.Br file, which contains special Alto microcode used by Midas in driving the Dorado, includes the BcplRuntime package; sources for DoradoMC.Br are in [Ivy]<DoradoSource>DoradoMC.Dm; you also need [Maxc1]<alto>PackMu.Run (?), Mu.Run (?), and ?? to do Alto microcode development.
The machine-independent sources contain four declaration files called MDecl.D, MCommon.D, MAsmCommon.D, and MMenus.d. MDecl.D and MMenus.d should not be used by any machine-dependent files (except that xxLoad.Bcpl may include MDecl.D). MCommon.d and MAsmCommon.d may be used by both machine-dependent and machine-independent sources.
Naming conventions are as follows: Midas sources all begin with "M"; machine-dependent sources with a distinctive sequence (e.g., "D1", "D0", or "M68"). The machine-independent command files are MSources.Cm, MBinaries.Cm, MComp.Cm, and MDumpSources.Cm; machine-dependent command files are D1Sources.Cm, D1Binaries.Cm, D1Comp.Cm, D1DumpSources.Cm, and D1Load.Cm (or "D0...", or "M68...").
4. Source File Organization
The one important convention in organizing the source files is that the linkage in the "external" statements should be expicitly shown, so that every externally-referenced static is preceded by a comment showing what file it is in. This allows references to be tracked down when changes are made or during debugging. See the machine-independent sources for examples of this and for other formatting conventions.
5. Picking Up New Midas Releases
After you have started developing Midas for a new hardware system, there may be new releases of the machine-independent software which you want to pick up. To do this you will load the new version of [Ivy]<DoradoSource>MidasSources.Dm and the single file D1Actions.Asm from MidasDoradoSources.Dm. However, before doing this, you will have to preserve any machine-independent files that you have modified (probably by renaming them), so that you can resolve your modifications against those in the new release.
You will probably have modified MCommon.D, maybe MAsmCommon.D, maybe MGo.Bcpl, and certainly xxActions.Asm. Since you have saved the listings of these files from the previous Midas release, you will be able to identify changes in the new release and can then merge your edits with those in the machine-dependent sources. Then recompile the machine-independent sources.
6. Storage Allocation
The Midas allocator is only used during initialization. It acquires all storage between the end of Midas code and the OS, Junta’ed to levKeyboard. From this all other storage needed is allocated.
All storage is allocated using either GetStorage(Size) or GetEvenStorage(Size). Blocks allocated by these routines do not have any header word and cannot be deallocated. Midas does not use GetFixed.
Storage is allocated beginning just below the OS and working down toward Midas code at lower addresses. This direction of allocation is desirable because it permits storage occupied by initialization procedures to be added to the storage area after execution without fragmentation.
The allocation is divided into three stages. During Init0 (in the MInit0.bcpl file) big blocks and blocks which can be initialized quickly are allocated. This is done prior to a Midas/I check in Init0B(). Storage allocated after the Midas/I check is preserved on a state file. This should be limited to small blocks which take a long time to initialize.
When Midas/I is not typed, this code is not executed and the storage area is instead restored by RestoreState(..) (in Midas.bcpl) from the state file. Presently, Midas/I takes about 10 seconds compared to about 3 seconds when Midas/I isn’t typed. This varies somewhat according to placement of files on the disk and details of the machine-dependent code; these times are measured from the beginning of Midas initialization and do not include approximately 5 or 6 seconds consumed by the Alto Executive to roll in the Midas.run core image from the disk.
Note that two state files must be created by the Midas.Midas initialization command file: Midas.RunProg, from which state is restored on a RunProg action, and Midas.Dtach, from which state is restored on a Dtach action. Other Midas implementations may not require any distinction between these two. The easiest method is to leave Midas unchanged and write the extra state file, even though it is unneeded; this will leave the machine-independent sources untouched.
If you want to eliminate the extraneous state file, Midas.Dtach, remove the SetupFPN calls for Midas.Dtach from MInit0.bcpl (and fix up the file name indices and the NFNames manifest); then remove the extra WriteState action from Midas.Midas; then replace the "(Dtach ? DtachFP,RunProgFP)" clause in the CmdRunProg procedure in MCmd.bcpl by "RunProgFP".
Final initialization is carried out by the Init2 overlay. Storage allocated by Init2() is not preserved on the state file. The final action of Init2() is to load overlays into any unused storage; these overlays get peeled away as a microprogram being loaded consumes the storage for symbols.
The first big block of storage allocated by Init0 is for display bit buffers. Presently, all but 9 buffers are also used as an OverlayZone when commands in overlays are executed. At these times the top part of the display is blank. The Alloc package in the OS is used to manage OverlayZone. Overlays are not written back on the disk when they are flushed.
7. Display Management
Midas has its own baroque display management stuff, handled in three levels. The lowest level consists of a pool of bit buffers, a table of line control blocks (An LCB consists of one DCB for the text and one for the leading between lines), and a vector of strings called ScreenTV. The screen size is determined by the statics ScreenHeight and ScreenWidth in the machine-dependent part of Midas.
An effort has been made to manage the display quickly without requiring much extra storage. At the same time, the algorithms avoid trashing the display by ensuring that bit buffers are not in use when they are grabbed for use in OverlayZone or for another screen line.
Two extra bit buffers exist. The number of extras is significant after a "Go" or "Test" action when many registers have changed. In this case, the algorithm, to avoid trashing the screen, must paint a new bit buffer for each changed line, then wait for the vertical interrupt to ensure that the old bit buffer is no longer in use, and finally assign the new bit buffer to the DCB and free up the old one. The number of extra bit buffers and the time required to convert a screen line into a bit buffer determines how many times it is necessary to wait for the vertical interrupt in this situation. It was empirically determined that two extra bit buffers worked well enough.
Strings pointed to by ScreenTV are painted into bit buffers by ClearAndScanConvert (in MAsm.Asm), called by GetFreeBitBuffer (MDisp.Bcpl).
Above the low-level display driver is the Region stuff in MRgn.Bcpl. Presently there are three kinds of regions: menus, the input text line, and comment lines. More about regions in a moment.
At the top level, text is sent to the display by stream operations (Wss, Wns, Puts, Resets, etc.) The streams first write into TextVec’s. A TextVec is a one-character/word vector with word 0 containing the number of characters.
All menus are built by writing initially into the ItemV TextVec, as discussed later. MarkMenus moves the characters from ItemV into ScreenTV using PaintItem (hand-coded).
The input text line, command comment lines, and program line have separate TextVec’s. When these are written via Puts or Resets, the DispDirty flag is set for the region. DispDirty causes PaintRgnLine to be called eventually (from DriverLoop’s call to UpdateDisplay or by a direct call to UpdateDisplay), and that moves the text into ScreenTV.
The algorithms attempt to avoid unnecessary screen rebuilding. This is done as follows: First, UpdateMPDValues() in MMPRgn.Bcpl is called by the machine-dependent code, when it believes the displayed values should be reread from the hardware; the machine-independent part of Midas never calls this procedure. UpdateMPDValues() will call the MGetMemData or MGetRegData procedures in the machine-dependent code for every memory word or register currently displayed, update the value in the MPD structure for that item, and set a flag indicating that the display should be updated, if the new value is different from the old. MGetMemData and MGetRegData may return false, if, for some reason, the value cannot be obtained from the hardware at that time (e.g., when the machine is running, these procedures may return a false value).
The machine-dependent code can also call UpdateMPDValues(true) which is like UpdateMPDValues() except that only those displayed items marked with the AlwaysUpdate attribute (from the MEMCON or REGCON table) will be updated. This variation is used for items that are dynamically updated on the display, such as the UPTIME register on Dorado Midas.
Next, MPDEveryTime(..) in MMPRgn.Bcpl is called by the Midas DriverLoop procedure. MPDEveryTime will rebuild ScreenTV for every MPD item that has been marked by UpdateMPDValues (and there are several other reasons for rebuilding the text vectors). It sets the ScreenLineDirty vector to true for each screen line that has changed. Only when this flag is true is a new bit buffer constructed.
When the display is off during command files, display rebuilding is deferred until the display is turned on again.
8. Symbol Table
The Midas symbol table is an alphabetically sorted two-level symbol table consisting of a 256-word HeadBlock at the top level and one or more 1024-word Blocks in core. The final allocation by Init2 assigns unused storage to overlays. The overlays are peeled off and more Blocks made as symbol table storage is needed for a microprogram.
When the symbol table size overflows resident core Blocks, it is swapped off Swatee (It may be desirable to replace Swatee by Midas.SymTab during initial debugging, and a simple edit to MInit0.Bcpl will make this substitution.). The record file (Swatee), managed by GetBlock, PutBlock, etc. procedures in MSym.Bcpl and MSymOv.Bcpl, is also used for virtual memory mapping information and for the FastSearch stuff discussed below.
HeadBlock and regular Blocks have identical structure: a header defined by the BH structure in MDecl.D, followed by a table of block-relative pointers growing upward from the header; symbol records grow downward from the end of the block.
Symbol records consist of a bcpl string followed by the value part of the record. In the HeadBlock, all values are one-word long--the index of that page on Swatee (called BlockAddr). The HeadBlock contains one entry for the smallest symbol on each regular Block. In regular Blocks, the value part of the record is one of the forms described by the Symb structure in MDecl.D.
Code for managing the symbol table is in MSym.Bcpl (resident) and MSymOv.Bcpl (Load overlay). New symbols are entered only during initialization and loading, so these procedures can be in an overlay. EvalAText looks up symbols and UpdateRcd enters new ones. SearchBlocks scans for the nearest less-equal symbol to a particular value. SearchBlocks is called after SS and Go to show the symbolic equivalent of the address at which the microprogram stopped (SearchBlocks is also used in many other situations). It takes about .07 seconds to scan 1000 symbols with SearchBlocks plus about .15 seconds for each block read from the disk.
Large programs can result in the symbol table being spread over 20 or more symbol blocks, and SearchBlocks becomes slow. For this reason, SearchBlocks calls a procedure FastSearch(..) before scanning the blocks. The CleanUpBlocks() procedure in D1Load.Bcpl shows how inverted tables can be built for faster searching, and the FastSearch(..) and RetrieveBlock(..) procedures in D1VM.Bcpl show how this is handled. You may be able to incorporate the Dorado FastSearch code almost verbatim.
The symbol table is built as follows: First, Init1() enters symbols for the register and memory names. Next, the Midas.Midas command file loads some address symbols for LOW-ADDRESS, HIGH-ADDRESS, BITS-CHECKED, etc.--symbols in the fake MDATA and MADDR memories used by the Test and TestAll actions. The machine-dependent code may also enter a number of other symbols into the symbol table during Init1. Note that these address definitions are defined in an ordinary microprogram that is loaded during execution of the Midas.Midas command file.
Next, if the user loads a microprogram, address symbols in that microprogram are entered. Since Micro alphabetically orders symbols, UpdateRcd (in MSymOv.Bcpl) first compares a new symbol against the one last inserted and the one after that. If the new symbol is between these two, it is immediately inserted. Otherwise, a binary search is done on the HeadBlock to find the Block containing the new symbol, then another binary search in that Block to find the position.
If the new symbol won’t fit on the Block selected, BlockSplit() is called. BlockSplit creates a new symbol Block, using unused core if possible, else peeling overlays until there is space for a Block, else writing a dirty block onto Swatee and reclaiming that space. The symbols on the Block that overflowed are divided between the old and new blocks.
BlockSplit is optimized for symbol insertions in alphabetical order into a table nearly empty at the beginning of the load. The division point leaves the original block at least as full as the BlockBreak parameter. If the new symbol is above BlockBreak, all symbols below it will be left in the original Block. Hence, the number of symbols above the division point is always less-equal to the number in the symbol table at the beginning of the load. If this number is small compared with the number that fit in a Block, then Blocks wind up nearly full, and any Blocks written on the disk will not have to be reread during loading. If the symbol that caused overflow is below BlockBreak, then it will be inserted on the original block and it may be necessary to read the split-off block from the disk later. For these reasons, it is desirable for the number of symbols at the onset of a load to be small (This is unfortunately not the case on Dorado).
9. Actions
All work done by Midas is initated by Actions. Actions may be invoked either by clicking the mouse over a menu item, by naming the Action in a command file, or by typing the command character(s) for the Action on the keyboard.
All permanently-defined actions are in the xxActions.Asm file. This consists of a big table with 5 words per action, interpreted according to the Action structure in MDecl.D. Many actions in the command menu use CreateAction(..) to create temporary actions during execution; the actions created this way are written into the unused area at the end of the ActionBlock table. These are destroyed at exit by QuitCmdOverlay(..).
The way the parts of an Action are used is discussed later in the description of the CreateAction(..) procedure. The MenuMChange(..) procedure in MMenu.Bcpl and the DoAction(..), DoTextAction(..), CreateAction(..), and ForgetTemporaryActions() procedures in MMenu.Bcpl are the ones relevant to actions.
In the ActionBlock in xxActions.Asm is a sequence of actions that appear in the primary command menu. These are put up by FormCmdmenuText() which calls ShowActions(..) in MCmd.Bcpl. Flags in the last word of each Action control when it appears in the menu, and you may want to modify the flags and the code in FormCmdmenuText(..) for a particular machine.
Actions which put up alternate menus are normally invoked by StartCmdOverlay in the lvProc entry of the Action, and the procedure that returns a procedure for forming the alternate menu is the Arg word in the Action. StartCmdOverlay(..) does ErrorProtect(lvProc, ..). A good example of a complicated action that uses an alternate command menu is in D1Reset.Bcpl (which you listed).
10. Menus
Every name-value area on the display is a Menu, and the command area at the bottom of the screen is also a Menu. Each menu is described by an MDFS structure as given in MDecl.D.
Name-value menus are defined in the machine-dependent InitMPInterface() procedure called by Init1(). InitMPInterface() calls NewMPDispBlock(..) which in turn calls MakeMenuRegion(..) to carry out the definition. The command menu is defined by a call on MakeMenuRegion in MInit1.Bcpl.
DriverLoop(), the main loop of Midas, reads mouse information each time through, detecting changes in position or mouse buttons. When the mouse migrates across region boundaries, deSelectMenu(..) is called to make a deselected menu region be black-on-white again. MenuMChange(..) is called when the mouse buttons or character position change in a menu region. MenuMChange(..) in turn calls the mouse-change and Action procedures defined in the Action table entry for the selected Action.
In addition, deSelectMenu() calls MPDdeSelect(..) for name-value menus.
Menu formation delimits strings as menu items each paired with an Action procedure called when a mouse button is released while that item is selected. MPDEveryTime(..) in MMPrgn.Bcpl loops over all name-value menus (MPD’s), forming these menus with FormMenu(FormMPDmenu,MPD). FormMenu initializes the menu region to empty and ItemStream to empty then calls FormMPDmenu(MPD). This routine puts up sequences of characters and calls MarkMenus(Action) to pair that sequence of characters with an Action. MarkMenus reinitializes ItemStream to empty. This mess winds up with the SizeVec and ProcVec vectors in the MDFS structure for that menu region describing the correspondence between characters on the display and Actions to carry out.
A similar sequence of procedure calls is used to form the command menu, but the composite procedure FormCmdMenu() is used to do this. Also, the WsMarkA(Action) procedure is used to do Wss(ItemStream,action-name); MarkMenus(Action); Puts(ItemStream,$ ); MarkMenus(0).
11. Every Time List
Midas uses a table of procedure names and arguments called the EveryTimeList for things that must be done every time through DriverLoop. MPDEveryTime is put on this list by Init1(); MPDEveryTime calls HWEveryTime to do any machine-dependent stuff (HWEveryTime will be a no-op procedure on most Midas implementations). Indefinite Action routines, such as the one for Go, add procedures to check for termination. The TimeOut action adds a procedure.
EveryTimeList is managed by AddToEveryTimeList(Proc,Arg) which returns a pointer that can be passed to RemoveFromEveryTimeList().