DORADOMICROASSEMBLER21 July 1980byEdward FialaXerox Palo Alto Research Center3333 Coyote Hill RoadPalo Alto, California, 94304Filed on:[Ivy]DoradoMicroassembler.PressSources on:[Ivy]DoradoMicroassembler.DmThis manual describes the Dorado microassembly language, based upon the 8 October 1979 release of theDorado Hardware Manual, and hardware changes up to the release date of this manual.This manual is the property of Xerox Corporation and is to be used solely for evaluative purposes. No partthereof may be reproduced, stored in a retrieval system, transmitted, disseminated, or disclosed to others inany form or by any means without prior written permission from Xerox.$JpE %>&q )p9Tr%S5q 0;!.* !,y$s+y#G *yHeyRrysby8E(yDry8cJ\Dorado MicroassemblerEdward R. Fiala21 July 19802TABLE OF CONTENTS l.Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.Assembly Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.Debugging Microprograms . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.Cross Reference Listings . . . . . . . . . . . . . . . . . . . . . . . . . . 9 6.Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 7.Conditional Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . .10 8.Simplified Parsing Rules . . . . . . . . . . . . . . . . . . . . . . . . . .11 9.Statements Controlling Assembly . . . . . . . . . . . . . . . . . . . .1210.Forward References . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1411.Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1512.Repeat Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1513.Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1614.Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1615.Small Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1816.Assembling Base Register Names . . . . . . . . . . . . . . . . . . . .1817.Assembling Device Numbers for TIOA . . . . . . . . . . . . . . . .1918.Symbolic Use of Task Numbers . . . . . . . . . . . . . . . . . . . . .1919.Assembling Data for RM . . . . . . . . . . . . . . . . . . . . . . . . . .2020.Assembling Data for STK . . . . . . . . . . . . . . . . . . . . . . . . .2121.Assembling Data Items In the Instruction Memory . . . . . . . .2122.Assembling for IFUM . . . . . . . . . . . . . . . . . . . . . . . . . . . .2223.Assembling for ALUFM . . . . . . . . . . . . . . . . . . . . . . . . . .2324.General Comments on Instruction Statements . . . . . . . . . . .2525.Small Constant Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . .2726.A Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2827.B Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2928.RM and STK Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . .3229.Shifter Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3530.ALU Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3831.Memory References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3932.Standalone Functions, Block, and Breakpoint . . . . . . . . . . . .4033.Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4133.1.What the Branch Hardware Does . . . . . . . . . . . . . . .4133.2.Branch Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . .4233.3.Dispatch Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . .4434.Placement Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . .4535.Microcode Overlays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4636.Instruction Memory Read-Write . . . . . . . . . . . . . . . . . . . . .4837.Reading and Loading Task PC's . . . . . . . . . . . . . . . . . . . . .4938.Divide and Multiply . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5039.Programming Tips and Examples . . . . . . . . . . . . . . . . . . . .52A1.MicroD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53A2.Recent Hardware and Assembler Changes . . . . . . . . . . . . . .62 fu!r4] HYfu ^tZr S<X M<W P<UM I<S L<Q P<O L<N# L<LX G<J L<H T<F O<E- R<Cc S<A O<? F<> B<<8 F<:n J<8 I<6 ?<5 K<3C H<1y @</ L<- S<, S<*N J<( Q<& O<$ M<#$ C<!Y Q< /;< /F< /F</ L<d N< G< G< M<: E<U R<  A< 18]oDorado MicroassemblerEdward R. Fiala21 July 198031. PreliminariesThe Dorado microprogramming language is implemented as a set of definitions on top of themachine-independent assembler Micro; Micro is an Alto program, so assemblies are carried outeither on an Alto or on some other machine (e.g., D0 or Dorado) emulating an Alto. Theassembly language is based upon the machine description in the 8 October 1979 release of DoradoHardware Manual and several hardware changes that have occurred since then.Files referred to in this manual are as follows:DocumentationWhen Using the Assembler[Ivy][Ivy]DoradoManual-A.PressD1Lang.McDoradoManual-B.PressD1Alu.McDoradoManual-Figs.Press[Maxc1]DoradoMidasManual.PressMicro.Run[Maxc1]MicroD.RunMicro.PressThe assembly language is defined by D1Lang.Mc and D1Alu.Mc; you must modify D1Alu.Mc asdiscussed later. I have tried to make D1Lang.Mc and this documentation complete, so you shouldnot need to refer to the Micro manual or study D1Lang for further details, except where notedhere.Micro flushes Bravo trailers, so you can use Bravo formatting if you want to. However, the crossreference program, MCross, which is expected to produce primary microprogram documentation,does not handle Bravo trailers. Also, line numbers in Micro error messages may be more difficultto correlate with source statements because of the line breaks inserted by Bravo's hardcopycommand. I advise against Bravo formatting for these reasons.I recommend use of Gacha8 (i.e., a relatively small fixed-pitch font) for printing program listings,and use of Gacha10.Al for editing source files with Bravo. The smaller font is desirable becausesome statements will be long, and a smaller font will allow you to get these on one text line. Bravotab stops should be set at precisely 8 character intervals for identical tabulation in Bravo andMCross.The two relevant lines in USER.CM for BRAVO are:FONT:0 GACHA 8 GACHA 10TABS: Standard tab width = 1795You will probably want to delete the other Font lines for Bravo in User.Cm.I also recommend that you read the hardware manual through once or twice and beginprogramming with Figure 1 of the hardware manual in front of you for reference. fu!r4] HYfu ^t []rU YP WR U#6C$UU S gT3< P0yMv #yKas#:J'G:H'G:G?# :E'GyD}'G :C ?rD >G <8W :n 6N 517$ 3g&; 1 O /> ,_?% *3. (B# '\ %5 !0ysy RrK L O =S<Dorado MicroassemblerEdward R. Fiala21 July 19804Note: All arithmetic in this manual and in Dorado microassembler source files is in octal.2. Assembly ProceduresD1Alu.Mc must be edited to define the ALU definitions for your program as discussed in the"Assembling For ALUFM" section. Suppose that you put these definitions on AluDefs.Mc. Thena microassembly is accomplished as follows:Micro/L D1Lang AluDefs Source1 Source2 ... SourceNThis causes the source files "D1Lang.Mc", "AluDefs.Mc", "Source1.Mc", ..., "SourceN.Mc" to beassembled. The global switch "/L" causes an expanded assembly listing to be produced on"SourceN.LS"; if "/L" is omitted, no listing is made. The assembler also outputs "SourceN.Dib"(intermediate binary and addresses), "SourceN.Er" (error messages, which are also printed on thedisplay), and "SourceN.St" (the Micro symbol table after assembling SourceN.Mc).In other words, Micro assembles a sequence of source files with default extension ".Mc" andoutputs four files whose extensions are ".Dib", ".Er", ".Ls", and ".St". The default name for theseis the name of the last source file to be assembled. Direct output to particular files as follows:Micro Sys/L/B D1Lang AluDefs Source1 ... SourceNcauses the four output files to be "Sys.Ls", "Sys.St", "Sys.Dib", and "Sys.Er."A summary of local and global Micro switches is as follows:Global:/LProduce an expanded listing of the output/NSuppress .Mb file output/UConvert text in all source files to upper case/OOmit .St fileLocal:/RRecover from symbol table file/LPut expanded listing on named file/BPut binary output on named file with extension .Dib. Default symbol table (.St) and errorlisting (.Er) to named file./EPut error listing on named file/SPut symbol table on named file/UConvert text in named file to upper caseAssemblies are slow--it should take about 9 minutes to assemble a 400010-instruction program.INSERT[file] statements, described later, can be put in source files so you don't have to type asmany source files on the command line. However, this will slow assembly because each INSERTmakes a separate call on the directory lookup code (about 1 second), but all names on the commandline are looked up at once. A better shortcut is to define command files to carry out yourassemblies. fu!r4] HYfu _r=ur Z t VrJ TW S+yPWs2 Mr)4 K>U Is5* G8( EP BlS @U >Lx;s0 89rO 4;x2s\/)\0/\./.\-z/ x+E\/\)/"\(=/J/&\%X/\#/\"P/( r##usr ^ H ;& SV   A=SDorado MicroassemblerEdward R. Fiala21 July 19805After obtaining an error-free assembly from Micro, you must postprocess the .Dib file with MicroDto transform it appropriately for loading by Midas. This is accomplished as follows:MicroD SysMicroD displays a progress message while churning away, and requires about 55 seconds to processa 400010-instruction file (longer when large listings are produced). The local "/O" switch directs theoutput to the named file rather than to the last-named input file (default extension .Mb), so:MicroD NewSys/O Sysputs the output of MicroD for the input file Sys.Dib onto NewSys.Mb.In this example, there is only one input file for MicroD (Sys.Dib)--it is also possible to assemblesource files independently using the symbol table (.St) file produced by Micro to establish a basispoint for further assemblies, thereby reducing assembly time. For example, you can build aAluDefs.St file as follows:Micro/U D1Lang AluDefsThen do all further assemblies as follows:Micro/O/U AluDefs/R Sys/B Source1 ... SourceNMicroD AluDefs SysPreassembling D1Lang and AluDefs in this way saves about 10 seconds of assembly time.MicroD can relocate code in IM (but not in any other memories). On very large programs, such asthe system microcode, it is possible to proceed as follows:Micro/U D1Lang AluDefs RegDefsMicro/O/U RegDefs/R Source1Micro/O/U RegDefs/R Source2 ...Micro/O/U RegDefs/R SourceNMicroD Sys/O RegDefs Source1 Source2 ... SourceNwhere Source1 ... SourceN may assemble IM and IFUM locations but must not assemble any RMor ALUFM locations; i.e., forward and external references are permitted only in instruction branchclauses and in target addresses for IFUM locations, so everything else must be predefined inRegDefs.St. One advantage of this method is that Source1 ... SourceN can be independentlymaintained without having to reassemble the entire system for every change; another advantage isthat it avoids symbol table overflow--some large programs are near to overflowing at present.However, whenever any RM or ALUFM assignments change, it will still be necessary to reassembleeverything, and when everything is reassembled the total assembly time will be about 9 minutesrather than 6 minutes.Note that you do not need anything special in your source files to declare labels which are exported(defined here, used elsewhere) or imported (used here, defined elsewhere). Micro assumes that anyundefined branch symbol is meant to be imported (but gives you the list just so you can check),and MicroD assumes that all labels are exported. MicroD also discards all but the last definition ofa name (e.g., the symbol "ILC" is defined in every file as the address of the last microinstruction). fu!r4] HYfu _r2/ ]KUxZs W;rQ UpTsUpr_ ST xPs MrD J#X HYc F[ DyBs >r*y;s-y: 7BrU 3 V 2;y/Dsy-y,y+"y)y(`0 %r-, #G[ !}\ = S H R8& V  KK !A H 8- :+ >\2 Dorado MicroassemblerEdward R. Fiala21 July 19806MicroD produces up to seven output files, depending upon the local and global switches specifiedon the command line. The name for these files is determined as discussed earlier, followed by theextensions given below (i.e., Sys.Mb, Sys.Dls, ... , SysOccupied.Mc):.MbBinary output consisting of address symbols for debugging and binary data forvarious memories; this file is produced unless the global /P switch on thecommand line suppresses it..DlsListing file always produced--it contains the Executive command line and allstrings printed on the display while MicroD is running (i.e., progress informationand error messages); this is followed by a table showing the number of freelocations on each page of IM, and by a list of data and address symbols in eachmemory (which can be modified by various global and local switches discussedbelow)..RegsRegister allocation listing produced if the global /R switch is specified; it lists innumerical order RM locations and address symbols associated with each..CSMapControl store map produced when the global /M switch is specified; when MicroDinput consists of a number of modules (i.e., of .Dib files), the .CSMap file willshow for each page in the control store (i.e., each page in IMX) the number ofwords in each module allocated on that page and the number of free locations inthe page..CSChartA file showing which .Dib file contained the instruction at each real address, sortedby real address; this is produced only when the global /E switch is specified and isintended for hardware debugging with a logic analyzer..absDLSA file giving the correlation between real and imaginary IM addresses, sorted byreal address; this is produced only when the global /H switch is specified and isintended for hardware debugging with a logic analyzer.Occupied.McA file which can be assembled to reserve all locations occupied by the currentimage. It contains IMReserve declarations for every location into which MicroDhas placed an instruction. The intent is that this file be used when buildingoverlays to run on top of the current mage.A summary of the local and global MicroD switches is as follows:Global:/AList only absolutely-placed IM locations/CConcise listing--list everything except octal contents of IM/DDebug--print a large amount of debugging information/EProduce a .CSChart file (of every location)/HProduce a .absDLS file (useful for hardware debugging)/IIgnore OnPage/KUnused for Dorado/MProduce a .CSMap file/NNo listing--IM contents are not listed/OProduce the Occupied.Mc output file containing IMReserve statements for all locations filledby MicroD/PPrint only--suppresses all MicroD actions and just lists all .Dib files/RProduce a .Regs file/SList symbols for all memories (except Version, RVRel, Disp, IMLock, and IMMask, which fu!r4] HYfu _rN ]K\ [ExXx ," V/ TxQ )# PF  NF/ L{ C JL HxE M DFxA  = ?A,% =v3 ;; 9x6 ,) 5< 3C6x0; ? .q D ,6x) N 'O & . $>+ @x s\/  \/0;\/3\~/*'~ \/#.\v/iv \/\n/ "Cn\/%\f/ f+$/\ / * F\ /  \ y/ "i yI  V=]Dorado MicroassemblerEdward R. Fiala21 July 19807are consumed by MicroD). /N prevents /S from listing IM symbols./TTrace--print a trace of calls on the storage allocator/XExternal--allow references to unbound symbols in the .Mb fileLocal:/AList only absolutely-placed IM locations--overrides global setting/CConcise listing--overrides global setting/LList everything--overrides global setting/NNo IM listing--overrides global setting/OOutput file/VVersion number/ZSpecifies scratch file to use instead of SwateeGlobal switches are usually specified on the command line as "MicroD/nmo Sys/O ..." but MicroDaccepts "MicroD Sys/O ... ~/nmo" as an alternative. This alternate form is useful with commandfiles because it allows varying switches to be specified at the end of the command line. In otherwords, if one has prepared a command file Foo.Cm containing "MicroD/n Sys/O ...," the "~"feature allows variant switches via "@Foo ~/nmo" to the alto Executive.Only one of the /A, /C, or /N global switches, which control additional material printed in the .Dlsfile, can be meaningful--when none of these switches is specified a verbose (/L) listing will beproduced. The /A, /C, /L, and /N local switches overrule the global switches for a particular file.The ordering of these is as follows: /L is most verbose; /A prints less information than /L; /Cprints all other memories but not IM; and /N prints neither IM nor other memory information.MicroD outputs a ".Mb" file, consisting of blocks of data that can be loaded into various Doradomemories and of addresses associated with particular locations in memories. The memories are asfollows:IM44-bit x 10000-word instruction memory(placement and other information brings total width to 140 bits)RM20-bit x 400-word register bank memorySTK20-bit x 400-word stack memoryIFUM40-bit x 2000-word instruction fetch unit memoryALUFM10-bit x 20-word ALU control memoryBR40-bit x 40-word base register memory (only for debugging symbols)BRX40-bit x 4-word MemBX-relative base register memory (only for debugging symbols)DEVICE20-bit x 400-word fake memory for device address symbolsTASKN20-bit x 20-word fake memory for task number symbolsIn addition, four other memories called VERSION, RVREL, IMLOCK, and IMMASK areproduced by Micro and consumed by MicroD, but these are invisible to the programmer. Only thedata contents for IM and IFUM are affected by the operation of MicroD; address symbols and datafor other memories are transmitted to the output file exactly as they are received by MicroD.There are at present no facilities provided for microcode overlays. However, such a facility will beprovided eventually. fu!r4] HYfu/_9sA\]/]^]5\\1/[\1;xY\/ YY7\Xx/X!Xx(\V/VV(\Up/UUp&\S/ \Rh/ \P// Mr,2 KC J;' H6E FkG B40 A.X ?dR =Y ;!; 8]>" 6G 4x2s & 0@x/! &x- x, 0x* #x) Bx' Px&  8x$ 4 !6r7 kZ F %8 d"C  h S>QFDorado MicroassemblerEdward R. Fiala21 July 198083. Error MessagesDuring assembly, error messages and assembly progress messages are output to both the display andthe error file.Micro error messages are in one of two forms, like the following:... source statement ...218...error message-or-... source statement ...TAG+39...error messageThe first example indicates an error on the 218th line of the source file. This form is used forerrors that precede the first label in the file. The second form is used afterwards, indicating anerror on the 39th line after the label "TAG".Note that the line count measures 's in the source, so if you are using Bravo formatting in thesource files, you may have trouble distinguishing 's from line breaks inserted by Bravo'shardcopy command.The "TITLE" statement in each source outputs a message of the form:1...title...IM.address.=341This message indicates that the assembler has started working on that source file."IM.address.=.341" indicates that the first IM location assembled in this source file is the 341st inthe microprogram. This will be helpful in correlating source statements with error messages fromthe postprocessor, MicroD.The most common assembly errors result from references to undefined symbols and from setting asingle instruction field multiple times (e.g., attempting to use the FF field twice in one instruction).I do not believe that you will have any trouble figuring out what these messages mean, so nocomments are offered here.After Micro has finished an assembly, it returns to the Executive leaving a message like "Time: 22seconds; 0 errors, 0 warnings, 20007 words free" in the system window. Only when the error orwarning counts are non-zero do you have to look in the .Er file for detailed information abouterrors.MicroD error messages are intended to be self-explanatory. fu!r4] HYfu ^t []r># Y V!AyS_syQyOyMyL5 Hr9( Gc EQ- A+8 @8% >J :Cy8s 4r~7 2\ 12E /h +&8 *+!G (`Y & #$J !YG "<  R:>  >NDorado MicroassemblerEdward R. Fiala21 July 198094. Debugging MicroprogramsThere is no simulator for Dorado. Microprograms are debugged directly on the hardware usingfacilities provided by Midas. To debug microprograms you will need to load Midas and itsauxiliary files as discussed in the Midas manual.Midas facilities consist of a number of hardware tests, a loader for Dorado microprograms, set/clearbreakpoints, start, step, or halt the machine, and examine and modify storage. Addresses definedduring assembly may be examined on the display. Midas works with both the imaginary IMaddresses defined in your source program and with the absolute IM addresses assigned toinstructions by MicroD.5. Cross Reference ListingsThe cross-reference program for Dorado microprograms is a Tenex subsystem called MCross. It issignificantly easier to maintain large microprograms when cross-reference listings are available, soyou are advised to store your sources on a Tenex directory and make your listings using MCross.Obviously, you can only use MCross if you have a timesharing account on Maxc. If not, you willhave to do without cross-reference listings until MCross is implemented on Alto (no one is workingon that now).A typical dialog with MCross is given below. The program is more-or-less self-documenting andwill give you a list of its commands if you type "?".@MCROSSOutput File:LPT:GACHA8.EPMachine:D(selects Dorado syntax)Action:U(convert to upper case)Action:N(read def's, no printout)File:D1LANGAction:CL(read def's, produce cross ref)File:Src1Action:CLFile:Src2Action:P(print operation usage statistics)Action:G(print global cross reference)Action:E@6. CommentsMicro ignores all non-printing characters and Bravo trailers. This means that you can freely usespaces, tabs, and carriage returns to format your file for readability without in any way affecting themeaning of the statements. fu!r4] HYfu ^t []r0, Y'2 W1 TVD RH PH NK M, H6t DrD B9+ A.%: =%: ;[ :' 61- 45y2)sy0  y/h#y.#y,#y+E y)#y(y'#y%y$a#"y##y!y ? lt r># 0F! e =SDorado MicroassemblerEdward R. Fiala21 July 198010Comments are handled as follows:"*" begins a comment terminated by carriage return."%" begins a comment terminated by the next "%". This is used for multi-line comments.";" terminates a statement. Note that if you omit the ";" terminating a statement, and, forexample, put a "*" to begin a comment, the same statement will be continued on the nextline.Micro's COMCHAR feature provides one method of producing multi-statement conditionalassemblies (This method is now obsolete). COMCHAR is used as follows. Suppose you want tohave conditional assemblies based on whether the microcode is being assembled for a 4K or 16KDorado configuration. To do this define "~" as the comment character for 4K (i.e.,COMCHAR[~];) and "!" as the comment character for 16K. Then in the source files:*! 4K configuration only ...statements for 4K configuration...*!*~ 16K configuration only ...statements for 16K configuration...*~In other words, "*" followed by the comment character is equivalent to "%" and is terminated bythe carriage return following its next occurrence.7. Conditional AssemblyD1Lang defines IF, ELSEIF, ELSE, ENDIF macros for doing multi-statement conditionalassemblies; IF's may be nested up to four levels deep. The syntax for these is as follows::IF[Display]; ... statements assembled if Display is non-zero...:ELSEIF[OldDisplay]; ... statements assembled if Display is zero and OldDisplay non-zero...:ELSE; ... statements assembled if both Display and OldDisplay are zero...:ENDIF;Note that each of the conditional names must be preceded by ":"; the implementation of these isdiscussed in the Micro manual. Any number of ELSEIF's may be used after an IF, followed by anoptional ELSE and a mandatory ENDIF. The arguments to IF and ELSEIF must be integers.Warning: The :IF, :ELSEIF, :ELSE, and :ENDIF must be the first characters in a statement. Inthe following example:FlshCore::IF[MappedStorage];... statements ...:ELSE;... statements ...:ENDIF; fu!r4] Gfu _ry[3yY&1yVgFyT KyR O`T M2) K0- J435 H6QyDyB&yA.y?dy='y; 8]@ 62 1t .*r"1#" ,_6%y)s y(=4y&y%|Hy$y"Ey!Y  rS @=! u9 wrU 9ywsyyU y  p=\Dorado MicroassemblerEdward R. Fiala21 July 198011":IF" is illegal because, due to the "FlshCore" label, ":IF" are not the first characters of astatement.8. Simplified Parsing RulesAfter comments, false conditionals, and non-printing characters are stripped out, the rest of the textforms statements.Statements are terminated by ";". You can have as many statements as you want on a text line,and you can spread statements over as many text lines as you want. Statements may be indefinitelylong.However, the size of Micro's statement buffer limits statements to 500-decimal characters at any onetime. If this is exceeded at any time during the assembly of a statement, an error message isoutput. Since horrendous macro expansions occur during instruction assembly, it is possible thatinstruction statements may overflow. If this occurs, the size of the statement buffer can beexpanded (Tell me.).The special characters in statements are:"[" and "]"for enclosing builtin, macro, field, memory, and address argument lists;"(" and ")"for causing nested evaluation;"_"as the final character of the token to its left;":"to put the address to its left into the symbol table with value equal to the currentlocation and current memory, and as the first character of a statement to be evaluatedeven in the false arm of a conditional;","separates clauses or arguments;";"separates statements;"#"#1, #2, etc., are the formal parameters inside macro definitions;"01234567"are number components (all arithmetic in octal).All other printing characters are ordinary symbol constituents, so it is perfectly ok to have symbolscontaining "+", "-", "&", etc. which would be syntactically significant in other languages. Also,don't forget that blanks, carriage returns, and tabs are syntactically meaningless (flushed by theprescan), so "T+Q" = "T + Q", each of which is a single symbol.The debugger Midas requires all address symbols to be upper case; since both Micro and MCrosshave switches that convert all source file characters to upper case, you can follow your owncapitalization conventions but must convert to upper case at assembly time using the /U switch.Experience suggests that consistent capitalization conventions are desirable, although there is notmuch agreement on exactly what conventions should be used. In this manual I follow capitalizationconventions which you may consider as a non-binding proposal. My convention is as follows:The first letter of each word is capitalized. fu!r4] Gfu _r6( ]K XUt TrZ Su r OE MB L HS F? E \ C@O Au >)x;As Ex9 x70x6K.&4F3'x1x0;x.Ax, 0 )rB# '*8 & "@ $>? u% r > 7T lu3r ;' Lye- >SDorado MicroassemblerEdward R. Fiala21 July 198012When a symbol consists of several words run together, the first letter of each subword iscapitalized (e.g., "FreezeBC," "StkP").When a symbol is formed by running together the first letters from several words, thenthese are all capitalized (e.g., "MC").Micro builtins, memory names, and important assembly directives that should stand out inthe source, such as TITLE, END, IF, etc. are all capitals.Midas also limits address symbols to 13 characters in length; if you assemble longer addresses, youwill still be able to load and run your program with Midas, but you won't be able to examinesymbols longer than 13 characters. Although 13-character addresses are acceptable, Midas must fitan address symbol, an offset, and the value at that location in a screen window; if total text lengthexceeds window width then the offset and name are truncated to fit, producing a confusing displayimage. For this reason, ordinarily limit IM addresses to 9 characters to avoid truncation.Also, avoid using any of the characters "=," "#," "+," "-," and "!" in address symbols; these aresyntactically significant to Midas and may cause trouble when debugging. Finally, avoid definingsymbols that end with the character "@"; the internal symbols in D0Lang.Mc by convention endwith "@," so you might have name conflicts with reserved words if you also define symbols endingwith "@."Statements are divided into clauses separated by commas, which are evaluated right-to-left. Anindefinite number of clauses may appear in a statement.Examples of clauses are:NAME,NAME[ARG1,ARG2,...,ARGN],FOO_FOO1_FOO2_P+Q+1,P+Q+1 is referred to as a "source" while FOO_, FOO1_, andFOO2_ are "destinations" or "sinks".P_STEMP,NAME[N1[N2[ARG]],ARG2]_FOO[X],Further discussion about clause evaluation is postponed until later.9. Statements Controlling AssemblyEach source file should begin with a TITLE statement as follows::TITLE[Source1];The TITLE statement:a.prints a message in the .Er file and on the display which will help you correlatesubsequent error messages with source statements which caused them;b.puts the assembler in "Emulator" mode and "Subroutine" mode (discussed later). fu!r4] Gfuy_rSy]K'yY=yX'yTQyR: O` u+r' M> K T JA$ H6-4 Fk[ Bu:r A.8u ?dr5 =P ; 8]ur 2 67 3 x0_sx.x-#"#+$x*x(` %rD t# r@ys rx(:'*:]Cx :6 =ZgDorado MicroassemblerEdward R. Fiala21 July 198013The final file to be assembled should be terminated with an END statement::END[Source1];Currently, the END statement assembles "MIDASBREAK: Return, BreakPoint, At[7776]" andprints some statistical information about the program on the .Er file. MIDASBREAK is needed toimplement the subroutine-call feature which you might use when debugging with Midas. Whenyou are going to independently assemble a number of source files, and then load the .Dib files intoMicroD, you should put an END statement only on the last file to be loaded.Note that the ":" preceding TITLE and END is optional; inserting the ":" will cause statementevaluation even in the false arm of a conditional, so an appropriate message can be printed to helpdetect :IF's unmatched by :ENDIF's. The "Source1" argument to :END is also optional.You may at any place in the program include an INSERT statement:INSERT[SourceX];This is equivalent to the text of the file SourceX.MC.The message printed on the .Er file by TITLE is most helpful in correlating subsequent errormessages if any INSERT statements occur either before the TITLE statement or at the end of thefile (before the END statement). INSERT works ok anywhere, but it might be harder to figure outwhich statement suffered an error if you deviate from this recommendation.The hardware has some operations executed differently for emulator, fault, and input/output tasks.For example, stack and _ID operations are only available to the emulator task; Map_ and Flush_only to the emulator and fault tasks; IOFetch_ and IOStore_ only to io tasks. The TITLEstatement initializes to assemble for the emulator task. This can be done independently by thestatement:Set[XTask,0];The assembler bases its error-checking upon the value of XTask. The programmer should correctlyset XTask to 0 (emulator), 17 (fault task), or some value in the range 1 to 16 (io tasks).In the event you request a listing by putting "/L" in the Micro command line, the exact stuffprinted is determined by declarations that can be put anywhere in your program.D1Lang selects verbose listing output. However, you will generally not want to print this listing.The MicroD listing is normally more useful during debugging.If you want to modify the default listing control in D1Lang for any reason, you can do this usingthe LIST statement, as follows:LIST[memory,mode]; fu!r4] Gfu _rJy\Ts Yr G W;_ Up+/ SX Q(u"r Ni@ L#@ JU Gb@yDs ARr6 =&6 <? :K\ 8J 5R 3C8& 1y.* /X - y+"s 'r5+ & @ "M O Z'ur <  S Sys j n>TDorado MicroassemblerEdward R. Fiala21 July 198014where the "memory" may be any of the ones given earlier and the mode the OR of the following:20(TAG) nnnnnn nnnnnn (octal value printout in 16-bit units)10alphabetically-ordered list of address symbols 4numerically-ordered list of address symbols 2(TAG) FF_3, JCN_4, etc (list of field stores) 1(TAG) nnnn nnnn nnnn (octal value printout)Note: The listing output will be incorrect in fields affected by forward references (i.e., references toas yet undefined addresses); such fields will be incorrectly listed as containing their default values.Micro has a recently added TRACEMODE builtin which you may prefer to use instead of anassembly listing for the purposes of debugging complicated macros. TRACEMODE allows symboltable insertions and macro expansions to be printed in the .Er file. See the Micro manual fordetails about TRACEMODE.When an instruction statement does not contain a branch clause, the assembler (i.e., MicroD) mustcause it to branch to the next instruction inline. For programs which nearly fill the microstore, it isimportant to allow MicroD flexibility in locating the next instruction. If it is permissible to smashthe Link register, then MicroD has more locations to choose from and might be able to pack themicrostore tighter.To tell the assembler whether or not it is ok to smash Link, two declaration statements areprovided:Subroutine;tells the assembler that it must not smash Link. The TITLE statement puts the assembler inSubroutine mode.Top Level;tells the assembler that it is ok to smash Link.There is more detailed discussion on these in the section on branching.10. Forward ReferencesMicro and D1Lang have an extremely limited ability to handle forward references. The only legalforward references are to instruction labels from either branch clauses or IFUM assemblystatements. Anything else must be defined before it is referenced. fu!r4] Gfu _rNy\Ts :yZ .yY yX2 (yV & Surd Q<+ NFD L{K J^ H EtZ CS AT @'7 >J :L 9 y6Ks 2rE 12y.qs +ir0 'G #t rur& %3 C =LYDorado MicroassemblerEdward R. Fiala21 July 19801511. IntegersMicro provides builtin operations for manipulating 20-bit assembly-time integers. These havenothing to do with code generation or storage for any memories. Integers are used to implementassembly switches such as XTask and to control Repeat statements. The operations given in thetable below are included here for completeness, but hopefully you will not have to use any of themexcept SET:Set[NAME,OCT]Defines NAME as an integer with value OCT. Changes the value of NAME ifalready defined.Select[i,C0,...,Cn]i is an integer 0 to n. Evaluates C0 if i = 0, C1 if i = 1, etc.Add[O1,...,O8]Sum of up to 8 integers O1 ... O8.Sub[O1, ... ,O8]O1-O2-...-O8IFE[O1,O2,C1,C2]Evaluates clause C1 if O1 equals O2, else C2.IFG[O1,O2,C1,C2]Evaluates C1 if O1 greater than O2, else C2.Not[O1]Ones complement of O1.Or[O1,O2,...,O8]Inclusive 'OR' of up to 8 integers.Xor[O1,O2,...,O8]Exclusive 'OR' of up to 8 integers.And[O1,O2,...,O8]'AND' of up to 8 integers.LShift[O1,N]O1 lshift NRShift[O1,N]O1 rshift NOCT in the Set[NAME,OCT] clause, may be any expression which evaluates to an integer, e.g.:Set[NAME, Add[Not[X], And[Y,Z,3], W]]where W, X, Y, and Z are integers.If you want to do arithmetic on an address, then it must be converted to an integer using the IPoperator, e.g.:IP[FOO]takes the integer part of the address FOOAdd[3,IP[FOO]]is legalAdd[3,FOO]is illegalSome restrictions on doing arithmetic on IM addresses are discussed later.12. Repeat StatementsThe assortment of macros and junk in the D1Lang file successfully conceals Micro's complicatedmacro, neutral, memory, field, and address stuff for ordinary use of the assembler.However, using the Repeat builtin may require you to understand underlying machinery--in adiagnostic you might want to assemble a large block of instructions differing only a little bit fromeach other, and you want to avoid typing the same instruction over and over.Instruction statements are assembled relative to a location counter called ILC. This is originally setto 0 and is bumped every time an instruction is assembled. To do a Repeat, you must directlyreference ILC as follows:Repeat[20,ILC[(...instruction statement...)]]; fu!r4] Gfu ^t []r2+ Y-2 WQ UJ T3 xQqs = PxNi/xL "xK xIs-xG,xF$xD}#xB#xA.x?  x=  :r Qx7s% 4r" 1Z /Dy,s)y+" y)  &srJ !}t  r4* @S A _ 9L U Y 2y ps. M=\Dorado MicroassemblerEdward R. Fiala21 July 198016This would assemble the instruction 20 times. If you want to be bumping some field in theinstruction each time, you would proceed as follows:Set[X,0];Repeat[20,ILC[(Set[X,Add[X,1]],...instruction statement...)]];where the instruction statement would use X someplace.For a complicated Repeat, you may have to know details in D1Lang. For this you will have todelve into it and figure out how things work.13. ParametersParameters are special assembly-time data objects that you may define as building blocks fromwhich constants, small constants, RM, or IM data may be constructed. Three macros defineparameters:MP[NAME,OCT];makes a parameter of NAME with value OCTSP[NAME,P1,...,P8];makes NAME a parameter equal to the sum of P1,...,P8, which are parameters orintegers.NSP[NAME,P1,...,P8];makes NAME a parameter equal to the ones complement of the sum of P1,...,P8,which are parameters or integers.The parameter "NAME" is defined by the integer "NAME!" (The "!" is a symbol constituentadded so that a constant, small constant, or RM address can have an identical NAME.), so it ok touse the NAME again as an address, small constant, or constant. However, you cannot use it formore than one of these.14. ConstantsThe hardware allows a constant to be generated on B that is the 10-bit FF field of the instruction ineither the left or right half of the 20-bit data path and either 0 or 377 in the other 10-bit byte."Literal" constants such as "322C", "177422C", "32400C", or "32377C" may be inserted ininstructions without previous definition.Negative constants such as "-1C", "-55C", etc. are also legal.Alternatively, constants may be constructed from parameters, integers, or addresses using thefollowing macros:MC[NAME,P1,...,P8];defines NAME as a constant whose value is the sum of P1...P8 (integers orparameters).NMC[NAME,P1,...,P8];defines NAME as the ones complement of the sum. fu!r4] Gfu _r#7 ]K4yZsyY)> Ur6 RhA P- Kt H6r$9 FkE D xAs (x@*#>x<L;! 89r; 6oB 4H 2 -t *rr32 (Q %58 #j) > <! xs&# x/ =S_Dorado MicroassemblerEdward R. Fiala21 July 198017Warning: The two macros above also define NAME as a parameter. You must not redefine aparameter with the same name as a constant because the binding of the constant is to the name ofits associated parameter (i.e., to "NAME!"), not to its value. In other words, if you redefine aparameter with the same name as a constant, you will redefine the constant also.Because the definition of a constant also defines a parameter of the same name, it is possible tocascade a number of constant definitions to create various useful values. Here is an example ofhow several constant definitions can be cascaded:MC[B0,100000];MC[B1,40000];MC[B2,20000];MC[B01,B0,B1];MC[B02,B01,B2];Occasionally, you may wish to create a constant whose value is an arithmetic expression or anexpression including an address in RM. Here are several examples of ways to do this:IP[RAddr]CA constant whose value is an RM addressAdd[3,LShift[X,4]]CA constant whose value is a function of the integer X fu!r4] Gfu _wrA ]K R [01 YP VD$= Ty+5 R1xOs xN xM, xK xJj GrZ EQUxBs 'x@5 @='i|Dorado MicroassemblerEdward R. Fiala21 July 19801815. Small ConstantsThe hardware allows low bits of the FF field in an instruction to be used as operands for functionsselected by high bits of the FF field. When used this way, the low bits of FF are called a smallconstant."Literal" small constants such as "17S", "1S", etc. may appear in instructions without previousdefinition. Alternatively, small constants can be defined in advance by the following macro:MSC[NAME,P1,...,P4];*defines NAME as a small constant with value = sum of P1...P4.Warning: MSC also defines NAME as a parameter. If you redefine the parameter with the samename as the small constant, you will also redefine the small constant.The RBase[RMADDR] macro is used to construct correct small constants for loading into theRBase_ register prior to referencing the RM address or RM region RMADDR; RM references willbe discussed later.Some example clauses using small constants are as follows:RBase_RBase[RTEMP],*Addresses the RM region containing address RTEMPCnt_13S,*Loads Cnt with 13Small constants cannot be used as B constants--they are not equivalent to constants.16. Assembling Base Register NamesBase registers are referred to when loading MemBase and in assembling for IFUM. Base registersare defined by clauses of the form:BR[MDS,1];*Define MDS as base register 1BR[CODEBASE,37];*Define CODEBASE as base register 37Since your program can also refer to the four base registers pointed at by the MemBX register, aseparate construct is provided to define names for this purpose:BRX[LOCAL,n];*Define LOCAL as MemBX-relative base register n = 0 to 3Address symbols defined by BR and BRX can then be used as in "MemBase_MDS" or"MemBaseX_LOCAL" in the program, and these names can be used in IFUM assembly statementsas discussed later. In addition, the address symbols will be used by Midas when pretty-printingmicroinstructions. fp!q4] Gfp ^r []q&= Y6&p Wq TV_ R=xOsQ> L{tq= JF G?"7 EtL C @7:x=vs1x; 8qT 3r# 0qO .M#x+s x)$ &qE $@x" s 8 q  6 7! &=# [t =NDorado MicroassemblerEdward R. Fiala21 July 19801917. Assembling Device Numbers for TIOADevice numbers are defined symbolically by clauses of the form:DEVICE[DSP,120];This defines DSP as an address symbol that will be used in symbolic printout by Midas when thenumber 120 appears in the TIOA register.During assembly the name DSP can then be used as a constant. For example,T_DSP;TIOA_T;causes TIOA to be loaded with the full 8-bit device address. Alternatively, in situations where youare sure that the high 5 bits of TIOA contain the correct value, you can use the short method ofloading TIOA, as follows:TIOA[DSP];This loads the low three bits of TIOA with the low three bits of DSP while leaving the high fivebits of TIOA unchanged.18. Symbolic Use of Task NumbersTask numbers are defined symbolically by clauses of the form:TASKN[FLT,17];*Define the fault task as 17FLT can then be referred to during assembly by the following kinds of clauses:RdTPC_FLT;*Read TPC[FLT] into LinkLdTPC_FLT;*Load TPC[FLT] from the value in LinkWakeup[FLT];*Initiate a wakeup for FLTFLT will also be passed as an address to Midas and will be used in printing the contents ofCTASK, TASK, NEXT, etc. symbolically. Since Midas may eventually print task specific registeraddresses symbolically also (e.g. TIOA DSPTSK 120, RBASE DSPTSK 10), it is desirable to keepthe task names fairly short to avoid using too much of the display window during debugging.The task names EMU for the emulator (task 0) and FLT for the fault task (17) are predefined inD1Lang.mc. fp!q4] Gfp ^r' []q?xXs UMqN S( PJxMOsxK Hq` FJ E xBIs >q` =/ 89r! 4q=x2s  .qNx+s x* %x)4  %q[ $6( "PL *1 L I  =M Dorado MicroassemblerEdward R. Fiala21 July 19802019. Assembling Data for RMThe assembler can assemble data and assign addresses in RM in several ways discussed in thissection.The hardware allows any one of the 20 registers pointed to by RBase to be read/written by aninstruction. To define 20-long regions of RM:RMRegion[RGNNAME];*allocates a 20-long region RGNNAMENew regions are allocated in blocks of 20 starting at 0 and ascending by 20 for each new region.I.e., the first region you define is 0 to 17, next 20 to 37, etc. up to 360 to 377.After defining a region with RMRegion, you can proceed immediately to define addresses in thatmemory using the macros given below. Alternatively, you can reselect that region at a later time:SetRMRegion[RGNNAME];*reselects a region RGNNAME for allocation"Literals" in RM, such as "32224R", may be referenced in instructions without previous definition.The first reference to an RM literal will assemble the literal value into a register in the currentregion. Subsequent references to the literal will refer to the same location in RM. It is illegal toduplicate a literal in more than one region.Other ways of assigning storage in a region are as follows:RV[NAME,P1,...,P8];*define NAME as an address in the current region with value = sum of*parameters.RVN[NAME];*Defines NAME in current region without initial value.Reserve[N];*Skips N (an integer < 20) words in the regionDefine variables with RVN rather than a useless initial value because this will prevent the "Cmpr"action in Midas (which compares the microstore image against what you loaded) from reportingfictitious errors. In system microcode (as opposed to diagnostics), any occurrence of a variable withan initial value is probably a programming error since it requires a reload to restore the initialvalue. Hence, if you have variables with initial values, you probably should store the initial valueselsewhere (in IM, for example), define the variables with RVN, and copy the initial values into theregisters during initialization.The assembler checks at assembly-time that the base for an RM address agrees with the valuebelieved to be in RBase. This is controlled by the following macros:KnowRBase[RGNNAME];*declares RGNNAME to be in RBaseDontKnowRBase;*declares that the contents of RBase are unknownThe small-constant clauses that load RBase (see the Small Constants section) change the assembly-time parameter for the current region. fp!q4] Gfp ^r []q#9 Y V!A TV.xQs# NFqQ L{S I G G?<&xD}s* A.qQ ?dW =[ ;, 8];x5s54: x2 6x0 . -q=% +.. *P (=F &sQ $D " k= Exsx8 0 qL & >T3Dorado MicroassemblerEdward R. Fiala21 July 198021It may be convenient to code subroutines that use temporary storage in RM and are called withseveral possible values in RBase. For example, a programming convention might reserve the firsttwo words in each of several regions as temporary storage for subroutines. Then the subroutine willwant to reference these words in a regionless way.To do this, first reserve temporaries for each region (using Reserve). Then define a regionless RMaddress as follows:RVREL[NAME,DISP];*declares NAME a regionless address in RM with displacement DISP*relative to the current value in RBase.The subroutine would then reference NAME. These references would not cause "Invalid RBase"error messages.20. Assembling Data for STKThe hardware allows the 400-word STK memory to be treated as four separate stacks of 100 wordseach. We expect at least one of these four stacks to be used as the Mesa evaluation stack, andperhaps all four will be used for this purpose, representing different procedure frames or something.However, it is also possible that one or more of the four STK regions will be used to hold data insome way other than as a stack. For example, STK is the best available memory for (emulator-only) tables because it is the only memory with an indexable address.The assembler has several macros that allow data to be assembled for STK. These are:STKRegion[i];*where i = 0 to 3 selects one of the four STK regions for allocation.STKWrd[i];*where i = 0 to 77, sets the word for the next allocation.STKVal[p0,p1, ... , p8];*sums up to 9 parameters and stores the result in the currently selected*STK word, and then advances to the next word.21. Assembling Data Items In the Instruction MemoryIf you do not want to clutter RM with infrequently referenced constants or variables, and if you arewilling to cope with the hardware kludges for reading/writing the instruction memory as data, thenyou can store data items in IM.To assemble a table of data in the instruction memory:Set[T1Loc,100];Data[(TABLE1: Byt0[P1,...,P8] Byt1[...] Byt2[...] Byt3[...], At[T1Loc])];Data[(Byt0[P1,...,P8] Byt1[...] Byt2[...] Byt3[...], At[T1Loc,1])];...where TABLE1 is an IM address symbol equal to the location of the first instruction in the table,P1, ..., P8 are parameters or integers. Byt0, Byt1, Byt2, and Byt3 assemble for the different 9-bitbytes of the instruction and correspond to the bits read by ReadIM[0], ReadIM[1], ReadIM[2], andReadIM[3]. "At" is discused in the "Placement" section later. Sample sequences for reading andwriting IM are given in the "Programming Examples" section. fp!q4] Gfp _q-0 ]K/1 [d Y2 VDJ TyxQs)PW( Mq0+ K> FHr BqK A V ?AU ;=% :R 89E 4Ux2s $!x0_ :x.,-V. (r4 %q^ #GW !}  6xIsxIxCx' qG  Y C T xP ; F g>[ Dorado MicroassemblerEdward R. Fiala21 July 198022It is important to note that while Byt0 and Byt2 may assemble data items up to 9 bits wide, Byt1and Byt3 are limited to 8-bit wide items because the 9th bits for these are parity bits, and theassembler will not let you load bad parity into IM as part of a data item.22. Assembling for IFUMMicro assembles data for an imaginary IFU identical to the Dorado IFU except that the address ofthe target location in IM is a full 14-bit address rather than the compact 12-bit form used byDorado. MicroD imposes the necessary placement constraints on IFU target addresses in IM andtransforms the imaginary IFU instruction into the form expected by Dorado.Before using any of the IFU macros discussed below, you must declare the instruction set numberas follows:InsSet[0,1];*Declares instruction set 0 with 1 instruction per entry vectorInsSet[1,4];*Declares instruction set 1 with 4 instructions per entry vectorInsSet[2,4];*Declares instruction set 2 with 4 instructions per entry vectorInsSet[3,1];*Declares instruction set 3 with 1 instruction per entry vectorYou can define parameters or integers to use in place of the literal arguments to InsSet, if you wantto.It is desirable, though not required, for an IFUM assembly statement to be given after its targetinstruction has been assembled to avoid a forward reference. This reduces work required by bothMicro and MicroD, so the assembly will run faster.There are three macros defined for assembling IFUm words. These are:IFUReg[opcode,length,memb,rbaseb,ifad,n,sign,pa];*Regular opcodeIFUPause[opcode,length,memb,rbaseb,ifad,n,sign,pa];*Pause opcodeIFUJmp[opcode,2,memb,rbaseb,ifad,sign];*2-byte jump opcodeIFUJmp[opcode,1,memb,rbaseb,ifad,disp];*1-byte jump opcodeIn these:ArgumentValueEffectopcode0 to 377Together with InsSet, opcode specifies the IFUM word to be loaded.length1 to 3Number of bytes in the opcode.n0 to 16First operand delivered by _ID -or-17if no operand.sign0 or 1Operand sign or sign extension (see hardware documentation).pa0 or 10 if not packed-alpha, 1 if packed-alpha.membBRX address0..MemBX[0:1]..address loaded into MemBase -or-BR addressThe BR address must identify BR 34 to BR 37; a value of 4 to 7 is assembledinto memb; 34+memb[1:2] is loaded into MemBase at t0 of the entryinstruction.rbaseb0 or 1RM region loaded into RBase at t0 of the entry instruction.ifadIM addressthe tag on the first instruction in the IFU entry vector for the opcode.disp-40 to +37The displacement of a one-byte jump opcode (fills in the n, sign, and pa fieldsappropriately) fp!q4] Gfp _qP ]KX [J Vr Sq3- QN T OF MJ JGO H| xEs ?xDZ @xB @xA ? >Jq50 < 9 :pq 7BX 5x2 2Ey/Ds8"O'F*,/5y-8"O'F*,/5 y,8"O'F*5y+"8"O'F*5 'qx%uQx" sQ:x QxQ}Q xQ5xuQ(x Qm QA Q 3 Qe xQTx: Q :x Q*%QU   2=YDorado MicroassemblerEdward R. Fiala21 July 198023"ifad" is the address of the first instruction in the entry vector for the opcode. The last InsSetpseudooperation specified the number of entry instructions per vector. You must put theseinstructions in sequence in the source file beginning with the one whose tag is "ifad."Warning: The assembler does not check that you have done this.For one-byte jump opcodes, the assembler will correctly transform the "disp" argument, whichshould be an integer in the range -40 to +37, into proper values for the "n," "sign," and "pa"fields of the IFUM word (see hardware manual). For two-byte jumps, only the "sign" field isutilized by the hardware, and the assembler will put don't-care values into "n" and "pa."Since the above macros are fairly jaw-breaking (six or eight arguments), you may wish to useMicro's macro-definition capability to define shorter forms for your own use. You may also wish touse the "Repeat" builtin to define blocks of opcodes. Here are two examples:*Macro to define Byte Lisp opcodes of length 1*Byte Lisp is instruction set number 1M[RegOp,IFUReg[#1,1,MDS,0,#2,17,0,0]];RegOp[0,CONS];RegOp[1,RPLACA];RegOp[2,RPLACD];*Generate 20 one-byte jump instructions with displacements from 1 to 20Set[DX,1];Repeat[20,IFUJmp[Add[77,DX],1,MDS,JMP,DX] Set[DX,Add[DX,1]]];I think that assembling data for IFUM is the only place where falling back to basic Microconstructs such as Macro definition will be desirable.23. Assembling for ALUFMThe processor's Alu provides all 20 boolean operations on A and B and 20 arithmetic operations,each with an optional carry. Only about 11 of the 40 possible arithmetic functions seem to me tohave any hope of application (See the MECL System Design Handbook specification for theMC10181 ic's, if you are curious about the others.)The 20-word ALUFM memory contains six Alu control signals in each word. Since only 20 of the31 potentially useful Alu operations can be stored in ALUFM, you must define a suitable subset byediting the D1Alu.Mc file according to instructions on its first page; this file must be assembledafter D1Lang as discussed in the "Assembly Procedures" section. This will assemble storage forALUFM and define all macros pertinent to each Alu operation. 16 operations believed most usefulare *'ed in the table below, leaving two operations unspecified.Addresses 16 and 17 are special--these are the two addresses used by shift operations. Byconvention, ALUFM 16 must contain the controls for "not A" (so the shifter output on A, which isinverted, will go through the Alu to the masker). ALUFM 17 is not presently constrained (Perhapsthe "A" operation, which would allow shifter output to be inverted before masking, is a good choicefor ALUFM 17).Note: You must define both "A" and "B" because those sources which can be optionally routedover either A or B (i.e., RM, T, Q, and MD) require that both paths be available through the Alu. fp!q4] Gfp _qc ]K: [W Ytq7 VD P Ty@ R3) PY Mr!; Kc IMyGs.yE&yDZ&yA y@[y>y<\Gy: y9= 6KqR 46 /r ,q? *N[ (!6 &3 #G%8 !}^ X _ =# R@ &4 T Ka Q  DpqE y V 2>]Dorado MicroassemblerEdward R. Fiala21 July 198024Both "not A" and "not B" must be defined for the same reason (and "not A" is required for theshifter).The XorCarry and XorSavedCarry functions modify the input carry and the Carry20 function OR'sa 1 into the carry out of the low-order four-bit ALU slice; these are written as standalone clauses;since carries affect only arithmetic, they are useless noops with logical operations.BitBlt is expected to use ALUFM 15 and 17 as variables. However, if BitBlt restores these uponexit, and if they are preserved across map faults and other traps, the emulator will be able to usetwo other operations; you should edit D1Alu.Mc to define these operations as "emulator-only" sothat an error will be flagged if they are erroneously used by any task other than the emulator. Tosupport restoration of these prior to exit from BitBlt, D1Lang defines symbols AFMn (n = 0 to 17)as constants equal to the normal contents of corresponding ALUFM locations. These allow normalcontents of an ALUFM location to be restored as follows:T_AFM17;*T _ normal contents of ALUFM location 17ALUFMRW_T, ALUF[17];The AFMn constants are also used to initialize ALUFM during boot-loading.Below, the potentially useful Alu operations are listed:A00A1-1*AA straight through (arithmetic)AA straignt through (logical)*BB straight through*not Aones complement of A*not Bones complement of B*A and Blogical andnot A and Bparsed (not A) and Bnot A and not Bparsed (not A) and (not B)A and not Bparsed A and (not B)*A or Binclusive 'OR'A or not Bparsed A or (not B)not A or Bparsed (not A) or Bnot A or not Bparsed (not A) or (not B)*A#Bexclusive 'OR'*A xor Bexclusive 'OR' (alternate syntax)A=Bequivalence or exclusive norA xnor Bequivalence (alternate syntax)A eqv Bequivalence (alternate syntax)*A+Bsum*A+B+1*A-B-1equals A+(not B)*A-Bdifference*A-1*A+12AA+A2A+1*Indicates that these are defined for system microcode fp!q4] Gfp _qE ]K YG XN VDU R@ QN O=J MrN KK IX H8yEQs)yC A qI =8\:s#\9w#8\#\6#5U\#3\#2\#12\#\/ # \.q#\- # +\#\*N # \( # \' #&,\# $\#\#j#\" # \ #  \#\I\#\# J\\\#\(y5 f=WcDorado MicroassemblerEdward R. Fiala21 July 19802524. General Comments on Instruction StatementsThe general layout of an instruction statement is as follows:TAG:branch clause, T_MD, rmaddr_(A phrase) and (B phrase), function, placement;TAG is an instruction memory address symbol. This may be used in branch clauses as discussedlater. Micro places instructions sequentially starting at 0; then the postprocessing program MicroDrelocates, or places, the instructions at their runtime locations.Branch and placement clauses are discussed later. They present no special problems inunderstanding and are easy to program.Functions that don't involve routing data from one place to another are also easy to program--youjust write the appropriate name as a separate clause in the instruction, as discussed in the"Standalone Clauses" section.However, clauses that involve moving data from one place to another are tricky. This section triesto present the general concepts behind programming these clauses.Data-routing clauses all have one or more "_"'s in them and require parentheses in some places tocause evaluation in the correct order. One of these clauses is evaluated from right-to-left, or from"source" to "destinations".If there is only one source and one destination in the clause, no problem: simply write"destination_source", e.g.:MemBase_MDS,T_RMADDR,The assembler figures out how to route data from the RM addressRMADDR to B (or A if B has been used) then through the Alu andinto T.RMADDR_34C,Again the assembler figures out how to construct the constant 34, route itonto B and through the Alu, and into the correct RM address.When you have A or B phrases embedded in Alu expressions, then you have to use parentheses,e.g.:T_(Fetch_RMADDR)+1,The assembler routes the contents of the RM address RMADDR ontoboth A and Mar, does A+1 in the Alu, routes the Alu onto PD, andstores PD in T.T_(Fetch_T)+(Q_RMADDR)The assembler routes RM address RMADDR onto B and into Q, T ontoboth A and Mar, performs "A+B" in the Alu, routes the Alu onto PD,and loads PD into T.In assembling the first clause above, the assembler proceeds in the following way:a.RMADDR is looked up first and recognized as an RM address. The proper value isassembled for the RStk field of the instruction. At this point data from RMADDRmight be routed over either A or B. fp!q4] Gfp ^r/ []q=yXs(K UMqW S:* QB NF!V L{& I M G?\ Et BU @7A </2 :e 90 5= 3x12s x/!4 !.*-!,x+" !4!)< &sq[ $x!s!+! 8!%x}!-!5 ! mqRx:L:1D :f# , =WDorado MicroassemblerEdward R. Fiala21 July 198026b.Fetch_ is looked up next. The ASel field is set to cause the fetch, and RM is routedonto A using FF[0:1] (There are some complications when FF has been used as aconstant.).c.A+1 is recognized as an Alu operation, AluF is set to cause A+1, and the data isnow at PD.d.Finally, the assembler identifies T_PD and modifies the LC field appropriately.Note: The "()" in the above example are not optional. If you omit them, the assembler would lookup "RMADDR+1", which would be undefined.One general idea in the above is that at each stage the source is routed only as far as necessary toload it into the destination.Note:T_Fetch_RMADDR,is legalT_Fetch_(RMADDR),is legalT_(Fetch_RMADDR),is legalFetch_T_RMADDR,is illegalThe last clause above is illegal because, by the time the assembler recognizes Fetch_, it has alreadyrouted the source data past A and through the Alu, and there is no path from the Alu to Mar. Theassembler is not clever enough to remember that the data originally started on A.Here are some more "()" examples:T_T+(RMADDR),is legal--"()" are mandatory around all A and B sources except "T","MD", "Q", and "ID".T_(T)+(RMADDR),is legal--"()" optional around "T", "MD", "Q", and "ID".T_(T+(RMADDR)),is legal--extra "()" around an entire source always OK(T_T+(RMADDR)),is legalT_(T+(RMADDR)) rsh 1,is legal--"()" are mandatoryT_T+(RMADDR) rsh 1,is illegal--the assembler will evaluate RMADDR OK, but it won'trecognize the rest.You must also write clauses in the correct order. Since the assembler evaluates clauses from right-to-left, whenever there are different ways to do something, the assembler will pick one of the ways,and you must be sure that it makes the correct choice by putting the clauses in the correct order.The five decisions of interest are:a.Branch clauses--the assembler has to know whether FF is available for a branchcondition, long goto, or long call. The assembler has special stuff to figure this out, soyou can position the branch clause anywhere in the instruction statement.b.RM, T, MD, or Q routed through Alu clauses--the assembler will use B for thisrouting unless you have already used B for something else. Hence, if you are using Bfor something else, put that clause to the right in the instruction statement. fp!q4] Gfpx_q:U:]KC :[ xX:?:VD xR:&) O`pqH M( J#Q HYxEus!D7!B!Au! >&qV <\D :Q 7!x4^s !1!2x1U!8x/!6x.!x,_!x*! 0!)W & qQ $>04 "s"@ #x:N:D:Ix:9:M:N  =W_Dorado MicroassemblerEdward R. Fiala21 July 198027c.Different RM addresses for read and write--Be sure that the RADDR2_ destination isto the left of the RADDR1 source in the instruction statement.d.Shifter operations that OR shifter output with another A source before routingthrough the Alu--this is rarely done, ordinarily an error. If you really want to do this,the shifter clause should be to the right in the instruction statement.e.Put FF>77 clauses to the right of A clauses. If you violate this rule, correctstatements will still assemble correctly, but some erroneous statements won't getchecked by the assembler.I think that the above cases are the only ones where the assembler's decision algorithms might causetrouble. Obeying (b) through (f) above nearly always produces a statement that will assemblecorrectly, and I think that any legal instruction can be written in a way that satisfies these. If youencounter problems with these rules, see me.25. Small Constant ClausesThe hardware allows low bits of FF in instructions to be used as literal values in several places.The valid clauses for these uses are:MemBase_SC,MemBase loaded from small constant (unusual) -or- MemBase_MDSMemBase loaded from value of BR address symbol (usual)RBase_SC,RBase loaded from small constant (unusual) RBase_RBase[RADDR]-or- RBase_RBase[RGNNAME]Normal ways to load RBaseCNT_SC,Loop counter from small constantMemBX_SC,MemBX loaded with 0 to 3MemBaseX_SC,MemBase loaded with 0..MemBX[0:1]..SC (unusual) -or- MemBaseX_LOCALwhere LOCAL is a BRX address (usual) -or- MemBase_LOCALsame as MemBase_LOCALA_SC,A from 0 to 17 (usually embedded in Alu expression)Fetch_SC,Memory reference from small constantIn the above "SC" can be any of the small constant tokens discussed in the earlier section on smallconstants, namely, a literal like "14S" or a name defined by MSC.The blocks of FF decodes for waking up tasks and loading the low bits of TIOA are not written assmall constant clauses. Instead Wakeup[task] and TIOA[device] are used (i.e., standalone clauses);the arguments to these should be address symbols in the TASKN and DEVICE memories,respectively, as discussed earlier. An alternative syntax for Wakeup[task] is Notify[n], where n is aninteger (0 to 17) specifying the task to be awakened; this alternate syntax is not expected to beuseful except for diagnostics checking out the control section. fp!q4] Gfpx_q:-%:]Kpq3xY:N:XB:VDp%qxR:#,:Q<:O= KD JO H6N Fk, Aur >qZ <8%y9ws Q1y8 Q/y6Q*y5UQy3Qy2Qy12Qy/ Q5y.qQ$y-Qy+Q3y*NQ$ 'qD %5A !@ Y . E c$C [ ? j >ODorado MicroassemblerEdward R. Fiala21 July 19802826. A ClausesIf you study the way in which various operations are encoded in the ASel and FF fields of theinstruction (see hardware manual), you will discover that activity on A is usually encoded in theASel field, leaving FF available for encoding another function. Memory references use FF[0:1] aswell as ASel, leaving FF[2:7] available for encoding one of 100 common functions and branchconditions.When FF is used literally as a constant on B, the A source is limited to RM, T, or ID, and thesource for memory references is limited to T or RM.Shift operations are hardware sources of A, but the assembler treats these as PD outputs. In otherwords, the various shift-and-mask statements assemble the "shift" value into ASel and select eitherthe "not A" Alu operation (AluF = 16) or the variable Alu operation (AluF = 17), as discussed inthe shifter section.An A source can be any of the following:ADummy source for clause splitting. It indicates that the source for some destination is A (Youprobably won't ever use this because normally the A source and destination are written as a singleclause.).RADDRAn RM address (never uses FF except to OR with shifts)TUses only ASel if not with a memory reference, only FF[0:1] with Fetch_ or Store_, or FF (<100) with other memory referencesIDUses only ASel if not with a memory reference, only FF[0:1] with Fetch_ or Store_, undefined forother memory referencesMDUses ASel and FFQUses FF (< 100)0S to 17SUses FF (< 100)Rule: You have to enclose small constant and RM addresses in "()" when they are embedded in anAlu expression; "()" are optional for other A sources.Destinations for A are the Alu, the eight memory references and other control functions in thememory section, and RF_ and WF_ for shifter-setup. A destinations can be any of the following:Fetch_Start memory fetch--uses ASel onlyIFetch_Start memory fetch in which ID from the IFU replaces low bits of BR (see hardwaremanual)--uses ASel and FF[0:1] (emulator only).LongFetch_Start memory fetch in which B extends the displacement on Mar (see hardware manual)--usesASel and FF[0:1].Store_Start memory store--uses ASel only (data for write must be put on B in a separate clause)IOFetch_Start 20-word fetch on behalf of io device--uses ASel and FF[0:1] (illegal in emulator or faulttask)IOStore_Start 20-word store on behalf of io device--uses ASel and FF[0:1] (illegal in emulator or faulttask)PreFetch_Put 20-word data unit in cache--uses ASel and FF[0:1]Map_Write Map for VA, data on B--uses ASel and FF[0:1] (emulator or fault task only)RMap_Does the Map_ reference together with the ReadMAP function, suppressing the write of theMap so that old data can be read non-destructively in the Pipe; since the FF field is used forReadMAP, the displacement for the reference can only come from an RM/STK address(emulator or fault task only).Flush_Purge VA from cache--uses ASel and FF[0:1] (emulator or fault task only) fp!q4] Gfp ^r []q4) YG W$= UT T3 P=! N3 KO I9* GX F$ B(x?sO>K=/x;6x9G8!x6F5xx3x2)x0 -3tqY +i6 'D &,_x#js~"x!~=~ b/x ~B~Zx~:x ~5*~x~_~x~5xT~ Cx~ K~LR ~ 9~ x ~H =]KXDorado MicroassemblerEdward R. Fiala21 July 198029DummyRef_Loads VA into the Pipe (for reading BR's)any Alu expression or destinationBRLo_Uses FF (> 77)BRHi_Uses FF (> 77)CFlags_Uses FF (> 77)RF_Uses FF (> 77). Read-field setup for shifter.WF_Uses FF (> 77). Write-field setup for shifter.A_No-op destination--simply routes the source onto AThe primary memory operations Fetch_ and Store_, do not prevent FF from being used as a Bconstant, an "insert field" or "extract field" value, or a long goto/call. FF can be used in theseways if the A source is an RM address or T. However, when FF is not used in these ways, FF[0:1]must encode the source for the reference (RM, T, or ID). The eight secondary memory references(IFetch_, LongFetch_, Map_, Flush_, IOFetch_, IOStore_, DummyRef_, and PreFetch_)require FF[0:1] for encoding. This means that only functions 0 to 77 can be encoded in the sameinstruction with a memory operation, and secondary memory references consume FF to specify anysource other than an RM address.The above can be combined arbitrary ways and used in Alu expressions, e.g.:RADDR_T_Fetch_ID,T_RADDR_Fetch_2S,T_(Fetch_T)+(RADDR),The MCR register has some bits loaded from A and some from B. This is encoded by a stand-alone clause of the form "LoadMCR[A,B]", where A and B are A and B source clauses respectively,as discussed later.Warning: If you illegally write an expression that uses one of the FF decodes between 100 and 377to the left of a memory reference clause with RM or T as the source, the assembler will not detectthe error.27. B ClausesThe common B sources can be selected by the BSel field in the instruction, leaving FF free forother uses. Less common sources are encoded by functions (FF > 77), and for these BSel mayoptionally encode the Q_ destination. With common sources, B destinations are selected byfunctions.The implications of this arrangement are as follows:You can route any common B source (RM, T, MD, or Q) through the Alu into RM or Twhile using FF for something else.You can route any common source to any destination by using FF. fp!q4] Gfpx_9s~)x]!x[~ xZC~ xX~ xV~.xUM~/xS~2 PWq$5 NH L=# J8' I-B Gb)7 E$: C @[Ky=sy<8y: 7q*0 5_ 3 0tq; .5- , 'r $q'7 "$8 +/ % 4x-#x"x?. =TzDorado MicroassemblerEdward R. Fiala21 July 198030You can route any uncommon source through the Alu or to Q_ by using FF.B sources can be any of the following (all of the FF's are > 77):BDummy source for clause splitting (You probably will never use this since it is normallypossible to embed the B phrase inside the B arm of the Alu phrase.)ConstantsUses FF--see earlier constant sectionRADDRTMDMemory dataQLinkUses FFRWCPRegUses FF (does Link_B' and B_CPReg, intended for Midas)--overrules loading of Link byCall or Return in the same instructionDBufUses FFFaultInfo'Uses FFPipe0Uses FF (VAHi is a synonym)Pipe1Uses FF (VALo is a synonym)Pipe2'Uses FFPipe3'Uses FF (Map' is a synonym)Pipe4'Uses FF (Errors' is a synonym)Config'Module indicators and IC size stuff--uses FFPipe5Uses FF (PRef is a synonym)--cache stuff and reference flagsPCX'Uses FFEvCntA'Uses FFEvCntB'Uses FFIFUMRH'Low part of IFU data--uses FFIFUMLH'High part of IFU data--uses FFNote: All FF-encoded B sources except PCX', EvCntA', and EvCntB' (i.e., those from the IFUboard) are too slow for Alu arithmetic; the assembler will flag an error if you use any other FF-encoded B source in an arithmetic expression.Rule: When used in an Alu phrase, B sources must be enclosed in "()", except that "()" areoptional around "T", "Q", and "MD".B destinations can be any of the following:B_No-op destination--simply routes source onto BDBuf_A no-op destination. Actual loading of Dbuf is enabled by the Store_ memoryoperation; this is just for readability.MapBuf_Another no-op destination. Actual loading of MapBuf is enabled by the Map_memory operation.Q_Uses FF (< 100) ordinarily, or BSel with FF-encoded B sourcesCnt_Uses FF (> 77)Link_Uses FF (> 77)--overrules loading of Link by Call, Return, or CoReturn in sameinstructionPCF_Uses FF (> 77)--loads PC and starts IFUStkP_Uses FF (> 77)TIOA_Uses FF (> 77)--TIOA loaded from B[0:7]Output_Uses FF (< 100)MemBase_Uses FF (> 77); loads from B[3:7].RBase_Uses FF (> 77); loads from B[14:17]. fp!q4] Gfpx_qG [AxXs~:~WCxU~%xT3xRxP~ xO=xM~xK~Q~J&xH~xG? ~xE~xC~xBI~x@~x>~x=S~,x;~<x:~x8]~x6~x5~x3g~ 0pqC .M] ,- )tq H 'F# #+x!s@.xk@E@ (xc@1@x[@=x@ x @,"@ x@'x]@ x@'x@x g@"x @$ =]n7Dorado MicroassemblerEdward R. Fiala21 July 198031Pointers_Uses FF (> 77); does both MemBase_B[3:7] and RBase_B[14:17].ShC_Uses FF (see "Shifter Clauses")Hold&TaskSim_Uses FF (> 77)InsSetOrEvent_Uses FF (> 77)MOS_Uses FF (> 77), synonym for InsSetOrEvent_GenOut_Uses FF (> 77), general output to io devicesEventCntB_Uses FF (> 77), synonym for GenOut_IFUMRH_Uses FF (> 77) (B must remain good through the following instruction--seehardware manual).IFUMLH_Uses FF (> 77) (B must regain good through the following instruction)BrkIns_Uses FF (> 77); loads from B[0:7]IFUTest_Uses FF (> 77)ALUFMRW_Uses FF (> 77)--this one is simultaneously a B destination and an ALU source--the clause "AluF[n]" must appear in the same instruction where n (0 to 17) selectsthe location in ALUFM that is read and writtenLdTPC_Uses JCN, forces low bit of RStk to be 1. Data on B is the task number whosePC is loaded from Link.RdTPC_Uses JCN, forces low bit of RStk to be 0. Data on B is the task number whosePC is read into Link.IMLHR0Pok_IMLHR0Pbad_IMLHR0'Pok_IMLHR0'Pbad_IMRHBPok_IMRHBPbad_IMRHB'Pok_IMRHB'Pbad_Use JCN and RStk[1:3]. These 10 kludge destinations are various forms forwriting IM, where the parity (POK or PBAD), the 21st data bit (RStk.0 or RStk.0'for the left-half, Block or Block' for the right-half), and the half-word (left orright) are specified in the macro name and assembled into RStk[1:3]. The other20 data bits are written from B.BDispatch_Uses FF (< 100). 8-way dispatch on B[13:15]BigBDispatch_Uses FF (< 100). 256-way dispatch on B[8:15].MidasStrobe_Uses FF (> 77). Shifts out DMux addess bit in B[4].any ALU destinationSome examples of instructions which read and write ALUFM are as follows:T_(ALUFMRW_T), A+B+1;Loads ALUFM[X] with value in T, where X is the location assembledwith control for A+B+1; the old contents of ALUFM[X] are savedin T.T_ALUFMEM, AluF[3];Reads ALUFM[3] through PD into T fp!q4] Gfpx_9s@<x]@x[ @ xZC @ xX@*xV@,xUM @#xS@"'@RExP@ExN@!xMO@ xK@:@JG,&@H.xG?@9@ExD7@9@BxA. x? x= x<8 x:x8 x7B x5 @@ @4:4@2&,@1yO@0x.q @,x, @.x+" @4x){ &,qHx#js"s2 "s" "s x"sz 8dI,Dorado MicroassemblerEdward R. Fiala21 July 19803228. RM and STK ClausesThe hardware complicates references to RM by providing only four bits of RM address in theinstruction (The Block bit in combination with these four encodes stack reference options for theemulator task). The remaining four address bits come from the RBase register which theprogrammer must load appropriately before the reference.Micro will flag an error if an RM read reference is not in the 20-word RM region believed to bepointed at by RBase, and it will use the change-RBase-for-write FF decodes (FF > 77) for RMwrite references outside the current region. To disable error checking, the programmer must defineand reference regionless RVREL addresses, as discussed in the "Assembling Data For RM" section;RVREL addresses should be used only in a section of code which has multiple entries that setupRBase with different values.The current region is specified by the following statements:DontKnowRBase;*Contents of RBase is unknown--any read reference is an errorKnowRBase[RGNNAME];*RBase points at the RM region RGNNAMEKnowRBase[RADDR];*RBase points at the RM region containing the address RADDRThe TITLE statement also declares DontKnowRBase.In addition, RBase may be loaded, as discussed earlier, by a clause (FF > 77) of the form:RBase_RBase[RADDR], -or-RBase_RBase[RGNNAME],These both load RBase and declare KnowRBase[RGNNAME], so subsequent instructions will beassembled assuming that the newly-loaded region is in RBase; this is normally what the programmerwants.Since (at t0 of the entry instruction for an opcode) the IFU initializes RBase to point at the RM 0or RM 20 region, the programmer should usually insert a KnowRBase[RGN0] orKnowRBase[RGN1] declaration before this.It is permitted to both read and write RM in one instruction. Normally, the read and writeaddresses are identical. However, a block of 20 functions (FF < 100) changes the RM address forthe write, permitting different registers in the current region to be read and written. Thesefunctions are also used when the stack is referenced during the read portion of the instruction and aregister in the current RM region during the write part. However, there is no way to read fromRM and write the STK in the same instruction.Another block of 20 functions (FF > 77) changes the RBase part of the RM write address. Theassembler will output one of these functions when it believes that RBase does not contain theproper value for writing the selected register. fp!q4] Gfp ^r []q)1 YG WD U8 RP P N NS M,)6 Ka&8 I F$<yCcs =yB&y@; =Sq0 97#y7sy5 2pq!7 0<% . +i *s+iq7 )E '( $aI "*6 J e 7U l- I 01, e/ =SDorado MicroassemblerEdward R. Fiala21 July 198033Warning: If you inadvertently write an illegal statement like:RADDR2_Fetch_RADDR1; -or-RADDR2_Fetch_T; -or-RADDR2_Store_T, MD_Q;where RADDR2 is not in the current RM region, the assembler will produce a garbage instructionbecause the change-RBase-for-write function produced for RADDR2_ will clobber the FF[0:1] fieldwhich must not be clobbered by anything to the left of the Fetch_ or Store_. The assembler willnot flag this error.RM addresses can be used as sources for A or B destinations, and this doesn't require any extrafields in the instruction. RM addresses can be used in Alu phrases, and, in this case, the RMaddress has to be enclosed in "()".RM addresses can be destinations for Alu operations, for the Input, InputNoPE, Cnt, Pointers,TIOA&StkP, ALUFMem, and ALUFMRW functions, and for MD--they can also be destinationsfor Alu sources. For these simply write the register name followed by "_".Some examples of RM clauses are the following:RTEMP1_RTEMP0,uses FF because address written different from address readFetch_RTEMP0, Q_RTEMP0,routes RTEMP0 onto A for a Fetch and onto B to save it in Q. These have to be written asseparate clauses.RTEMP0_(ALUFMRW_RTEMP0), AluF[17]loads ALUFM[17] from RTEMP0 and saves the old value of ALUFM[17] in RTEMP0.RTEMP0_Inputroutes IOB data onto PD and store in RTEMP0.It is (just barely) conceivable that you may wish to create a constant whose value is an RM address.To do this you can use the following kludge:B_IP[RADDR]CThis puts a constant whose value is the address of RADDR onto B.References to STK are illegal except in the emulator task. The operations read the word pointed toby StkP, then adjust the stack pointer in the ways below, then write the selected item (if any) at themodified or unmodified address. When you write at the modified address, the assembler willautomatically supply the ModStkPBeforeW FF decode.StkP[0:1] select one of two separate stacks, and StkP[2:7] address the word in the stack selected byStkP[0:1]. fp!q4] Gfp _tq6y\TsyZyY VDqO TyM R` P MrU KD I# Fk Q D; BK ?d.xSDorado MicroassemblerEdward R. Fiala21 July 198034The hardware StkError signal occurs, waking up task 17, before any instruction in which StkPoverflows or underflows. However, when StkP is initially 0, underflow should usually occur whenTOS (top-of-stack) is referenced in that instruction but not when the pointer is incremented withoutreference. Hence, the assembler outputs a different code in RStk when incrementing StkP withoutreference than when incrementing in conjunction with a read of TOS. In addition, an example inthe "Instruction Fetch Unit" chapter of the hardware manual shows several situations where TOS iscopied into T without knowing whether the stack is empty; in this case the programmer wants todisable the underflow check, even though he is referencing TOS.The stuff provided by the assembler assumes that your program will use the stack in the mannerenvisioned by the hardware design, as follows: An empty stack is represented by StkP containing 0;StkP will sensibly point at either the last item pushed or the item before that, according toprogramming convention; a push increments StkP and writes in one instruction (or increments StkPin one instruction and writes in the next according to programming convention); a pop can read theitem being popped in the same instruction if desired.Names in the first column below are "sources" for reading the top STK entry; the name modifier,"&+n" or "&-n" controls StkP modification, which always occurs after the top stack entry is read.Second column names are used instead of first column names when it is permissible for the stack tobe empty--this aims at the case when TOS is copied into T without knowing whether or not thestack is empty. The third column are "destinations" for writing the top STK entry; here also StkPis modified after the top stack entry is written. The fourth column are destinations that modifyStkP before writing; they use the ModStkPBeforeW function (FF<100) to do this. Finally, the fifthcolumn are used to modify StkP in an instruction which makes no reference to STK.Mod StkPMod StkPMod StkPMod StkPRead StackNo StkP=0 UFLAfter writeBefore writeNo refStack&+3StackNOUFL&+3Stack&+3_Stack+3_StkP+3Stack&+2StackNOUFL&+2Stack&+2_Stack+2_StkP+2Stack&+1StackNOUFL&+1Stack&+1_Stack+1_StkP+1StackStackNOUFLStack_Stack&-1Stack&-1_Stack-1_StkP-1Stack&-2Stack&-2_Stack-2_StkP-2Stack&-3Stack&-3_Stack-3_StkP-3Stack&-4Stack&-4_Stack-4_StkP-4The RStk[0] bit will wind up equal to 1 whenever the StkP=0 underflow check should be made bythe hardware. When the stack appears as both a source and a destination in the instruction, themodifiers must match, so the Stack&+i source can only be used with the Stack+i_ or Stack&+i_destinations.StkP_ may be loaded from B. RestoreStkP is a standalone function, written as a separate clause. fp!q4] Gfp _qB ]KU [#A YA W/0 V!^ TVF R? O^ MOR KP I9' Gb F$5 BP @?pq ? U =ST ;S 9 pq< 7pqW 6(Q2u$-z4y1  $ -z 4y.s $-z5y-3 $-z5y+ $-z5y*r $y)$-z5y'$-z5y&O$-z5y$$-z5 !qI H  %7 @ D  >OLDorado MicroassemblerEdward R. Fiala21 July 19803529. Shifter ClausesThe shifter may be used in two ways. The first way specifies the shift operation and the othercontrol information for the shift in a single instruction. This uses up the ASel, BSel, and FF fieldsof the instruction while allowing data in either T or a selected RM address to source the shifter.The second method specifies that shift controls loaded into SHC by a previous instruction (viaShC_B, WF_A, or RF_A) be used. In this case only the ASel field is used up by the shiftoperation.The semantic shifter operations when shift controls are specified in FF are as follows (The right-most 20 bits of the 40-bit quantity participating in a cycle are the result.):a.Left shift data in RM or in T by 0-17;b.Right shift data in RM or in T by 0-17;c.Right-justify (or load) an arbitrary field from RM or T;d.Right cycle the 40-bit quantity RM.T, T.RM, RM.RM, or T.T by 0-17;e.Left cycle the 40-bit quantity RM.T, T.RM, RM.RM, or T.T by 0-17;f.Deposit RM or T into an arbitrary field of a word coming from MD.g.Deposit RM or T into an arbitrary field of a word of zeroes.For these, the assembler fabricates an FF value describing the shift, sets BSel to cause the FF-controlled shift, and forces ASel to select a shift. "LdF" stands for "load-field" and "DpF" for"deposit-field". The assembler defines the following macros:T_Lsh[x,count,y];*Invokes ShiftRMask (or ShMDRMask)T_Rsh[x,count,y];*Invokes ShiftLMask (or ShMDLMask)T_LdF[x,size,pos,y];*Invokes ShiftLMask (or ShMDLMask)T_DpF[x,size,pos,y];*Invokes ShiftBothMasks (or ShMDBothMasks)T_Rcy[u,v,count];*Invokes ShiftNoMaskT_Lcy[u,v,count];*Invokes ShiftNoMaskIn the above:count =distance of the shift or cycle (0 <= count <= 17)size =number of bits in the fieldpos =number of bits to the right of the fieldx =source for the shift (RADDR or T)y =value replacing masked-out bits (0 or MD, defaulted to 0 if the arg is omitted)u and v =T and an RADDR in any combinationcount =distance of the shift.The macros given above invoke the Alu operation in ALUFM 16 which should be "not A"; theequivalent macros named XLsh, XRsh, XLdF, XDpF, XRcy, and XLcy invoke the Alu operation inALUFM 17.The above pseudo-operations include all of the conceptual shift options which are possible when theshift function is carried out in the same instruction with loading ShC. There are no other cleveruses of FF-controlled shifts that I am aware of. fp!q4] Gfp ^r []q_ YO WP TV> RC P MOB! KNyH:&yFH:'yD}:8yB:By@:Ay?:Ay=S:< 9)7 8$= 6K=y3sQ"y2)Q"y0Q"y/hQ*y.Qy,Q )Wq y&s )y%5 y# "y"s y! Jy yQ  qK 8C m c 1G f0 =W&Dorado MicroassemblerEdward R. Fiala21 July 198036Notes:1) The hardware does not allow an arithmetic Alu operation in conjunction with the Shift...Mask,and the assembler does not check for this.2) The Alu<0, Alu=0, Carry', and Overflow' branch conditions apply to the output of the Alubefore it has gone through the masker, so the value tested by these is generally different from thevalue produced by the shift-and-mask. However, when ShiftNoMask is used, the Alu=0 branchcondition will still apply.The hardware also has three ways of loading ShC_. These are implemented by functions. Forthese you write a separate clause as follows:RF_A,Read-field (do ShiftLMask later)WF_A,Write-field (do ShMDBothMasks later)ShC_B,Generalwhere "B" is any B source and "A" any A source.You should study the shift control figure in the hardware manual to absorb how these work. Themost general control of the shifter (ShC_B) allows the 40-bit input quantity to be specified as eitherT..T, T..R, R..T, or R..R. In other words, you can carry out either a 20-bit or 40-bit cycle bychoosing the shifter input control bits appropriately. In addition, if you use the RIsID or TIsID(FF < 100) function in the instruction that carries out the shift, you can replace either the T orRM/STK component of the shift by ID, conceivably useful.The read-field and write-field operations were intended to support corresponding Mesa operations,which put 8-bit field descriptors on A (usually from ID). Since these use both FF and A, whileproviding no capabilities beyond that of the FF-controlled shift, it won't normally be convenient touse them in other contexts.For situations when you need more flexibility than is provided by the FF-controlled shifts, theassembler defines the following macro for constructing complete 20-bit shifter-control constants inRM:RVSH[NAME,LMASK,RMASK,TRSEL,COUNT];"NAME" is the name of the RM variable, TRSEL is 0 to specify R..R as the 40-bit input to theshifter, 1 to specify R..T, 2 for T..R, and 3 for T..T. The interpretation of the other arguments isdiscussed in the hardware manual. Having constructed such a descriptor, you can load SHC_ fromit as follows:ShC_NAMEThe shift hardware forces the Alu operation to be the one defined by ALUFM 16 or ALUFM 17.By convention, ALUFM 16 contains the "not A" Alu operation--this is the one ordinarily requiredbecause the shifter output appears complemented on A and is normally routed straight through theAlu to the masker.ALUFM 17 is (will probably be) reserved as a variable. BitBlt will load ALUFM 17 with assortedcontrols to accomplish the strange things it does. fp!q4] Gfp _ [qL Y* VgG Tpq'6 R@ Q MV K-yI syG$yFH Bq/ ?Z =24 ;E :'G 8]F 68 3 7* 1U9& /D - *N5* (6- &y#s# qD J "= I ys 9qA nK T  gC 2 B U>]Dorado MicroassemblerEdward R. Fiala21 July 198037The Shift...Mask and ShMD...Mask functions may be written with the RADDR input to the shifteras an argument, or the RADDR argument may be omitted if irrelevant or specified elsewhere in theinstruction, as follows:For Aluf = 16For Aluf = 17ShiftNoMask[RADDR]XShiftNoMask[RADDR]ShiftLMask[RADDR]XShiftLMask[RADDR]ShiftRMask[RADDR]XShiftRMask[RADDR]ShiftBothMasks[RADDR]XShiftBothMasks[RADDR]ShMDLMask[RADDR]XShMDLMask[RADDR]ShMDRMask[RADDR]XShMDRMask[RADDR]ShMDBothMasks[RADDR]XShMDBothMask[RADDR]where RADDR may be any RM address including the stack sources discussed earlier. Thedifference between Shift... and ShMD... is that the former replaces masked out bits with 0, while thelatter replaces masked out bits with MD from the memory. All of these shift-and-mask functionsare treated like Alu operations, so the result may be routed into an RM address or T.Here are some examples:RTEMP_ShiftLMaskRM address specified elsewhere in the instructionT_ShiftRMask[RTEMP]RM address specified in the shift expressionRTEMP_Lsh[RTEMP,3,0];Use of Lsh macro--masked out bits replaced by zeroesRTEMP_Lsh[RTEMP,3]Use of Lsh macro--masked out bits replaced by zeroesRTEMP_Lsh[T,3];Use of Lsh macro with source data for shift from TT_Lsh[T,3,MD];Use of Lsh with MD replacing masked-out bitsT_Rsh[RTEMP,17];Right-shift data in RTEMP 17 positionsT_Rcy[RTEMP,T,3];Right-cycle the 40-bit quantity RTEMP..T by 3 positionsT_Lcy[T,RTEMP,3];Left-cycle T..RTEMP 3 positionsT_DpF[T,3,10,MD];Deposit T[15:17] into MD[6:10]T_LdF[RTEMP,2,12];Right-justify RTEMP[4:5] and leave result in TWhen the shifter is used, the 4-way multiplexor for other A inputs is normally disabled by thehardware. However, if you write another A source clause to the left of the shift-and-mask clause inthe instruction statement, then that source (coded by the FF field) will be ORed with the shifteroutput on A before going through the Alu, e.g.:A_T, T_ShiftLMask[RTEMP]'Or' shifter output with data from Twould shift the 40-bit quantity RTEMP..T according to the control in ShC, OR that with T, NOTthis in the Alu, clear some of the left-most bits in the result according to the LMask specified inShC, and finally load this into T. Since the shifter output is complemented on A, the actual dataappearing at the masker inputs is [shifter and not T]. Hence, the shifted data is masked once by"not T" and then again by the selected masks. fp!q4] Gfp _qB ]KY [yXu "s yVs"syU*"syS"syRh"syQ"syO"syNF"s JqF I-X Gb@ EU B%y?ds"s1y>"s,y<"s4y;A"s4y9"s2y8 "s,y7"s&y5"s7y4^"sy2"sy1"s. .MqB ,13 *$= (/y&,s"s "qN !` HZ }J - l=LDorado MicroassemblerEdward R. Fiala21 July 19803830. ALU ClausesThe operations performed by the Alu were given in the section on ALUFM. In "not A and not B",for example, "A" and "B" may be, respectively, any A or B sources.Rule: The safe way to write the Alu phrase is to enclose the A and B sources in "()", e.g., "not(RADDR) and not (T)". However, you may omit the "()" around "ID", "T", "Q" or "MD", if youwant to (and assembly is slightly quicker when you omit the "()").Rule: You must not write "not A and B" as "(not A) and B". In other words, it is illegal to putrandom "()" in the Alu phrase, even though that may clarify the meaning. If you tried to do this,the assembler would recognize "not A" as an Alu phrase and then give you an error like"PDANDB undefined". The "()" are only legal around the "A" and "B" parts of ALU expressions.Rule: When used in conjunction with the Alu Lsh 1, Lcy 1, Rsh 1, Rcy 1, BRsh 1, or ARsh 1functions, the above would be written like "(not (RADDR) and not (T)) Lsh 1"; i.e., the entire Aluoperation is enclosed in "()" followed by the "Lsh 1" or whatever.The last carry out of the Alu can be xor'ed with the carry from the ALUFM memory. This iscaused by the XorSavedCarry function, written as a separate clause. Carry20 is also written as aseparate clause.If you have not defined the arithmetic Alu operation with the kind of carry bit you need, then youmust explicitly write XorCarry as a separate clause in the instruction. For example,(RTEMP)+T, XorCarry;*Equivalent to (RTEMP)+T+1(RTEMP)-T, XorCarry;*Equivalent to (RTEMP)-T-1(RTEMP)-T-1, XorCarry;*Equivalent to (RTEMP)-TThe legal destinations for an Alu source expression are:RADDR_Any RM destinationStack_or any other stack destination--emulator onlyT_PD_This no-op destination is necessary when the Alu operation is "A" or "B" (i.e., A straight throughor B straight through) and the Alu output is not being loaded by any real destination. It ensuresthat the source gets routed through the Alu, which might be necessary for an Alu branch conditionin the next instruction.The Input and InputNoPE functions (FF < 100), ALUFMem, ALUFMRW_, Cnt, Pointers, ShC,TIOA&StkP functions (FF > 77) and shifter operations discussed in the last section may be usedinstead of an Alu operation (These are alternative inputs to the hardware's PD path.). Hence, theycan feed RADDR_ or T_ destinations.Here are some examples of other Alu clauses:T_((RTEMP)+T) Lsh 1Use of Alu lshift 1 functionT_T Rsh 1Use of Alu rshift 1 functionT_(T) Rsh 1"()" are optional around "T"T_RTEMP"()" are optional around a single sourceT_(RTEMP) Lcy 1"()" required around an RM address with anything elseT_((RTEMP)+T) Rcy 1RTEMP_(RTEMP) BRsh 1Alu rshift 1 bringing Alu carry into bit 0 fp!q4] Gfp ^r []qK YB V!tq N TVW RB OtqX MOL K? I!< FHtqN D}S BB ?AW =vT ; 89S 6oUy3s%5 y2L%5 y0%5  -q8x*sx)4-x'x%Q$b#$I! tqO > K # ,ys#y#y #y#(y ^#1y y #' y=]@Dorado MicroassemblerEdward R. Fiala21 July 198039RTEMP_(RTEMP) ARsh 1Arithmetic rshift 1 preserving signT_T xor (377C)T_ID, Carry20Carry20 function is separate clauseT_ALUFMem, Aluf[17]Save ALUFM[17] in TT_0HLiteral reference to then contents of the ALUFM location containing 0T_(ALUFMRW_RTEMP), Aluf[17]Saves ALUFM[17] in T, loads it from RTEMPWarning: If you erroneously write an instruction statement that routes the Alu through PD andalso routes Input or ALUFMem through PD, the assembler won't give you any error message.31. Memory ReferencesMemory references are initiated with A clauses as discussed earlier--the assembler does not makeany distinction between the hardware's Mar bus and the A bus.From the viewpoint of what can be encoded in an instruction, it is convenient to distinguish Fetch_and Store_ from other references; only these two allow the displacement to be sourced from T oran RM address while FF remains available for use as a constant or a long branch; only these twoallow the displacement to be sourced from T, ID, MD, or Q using only FF[0:1], so FF[2:7] remainavailable for encoding another function. All other references require FF to be used whenspecifying any source other than an RM address. Since FF[0:1] encode alternate sources for thedisplacement or alternate references, only the first 100 functions can be used in the sameinstruction; functions 100 to 377 cannot be encoded.The Store_ and Map_ references not only use a displacement on A but also accept data on B.However, if you forget to route data onto B, the assembler won't flag your error.In the same statement with Store_, you should normally write "DBuf_bsource" to show explicitlythat the data on B (bsource) is intended for the Store_; similarly with Map_, you should write"MapBuf_bsource." The "DBuf_" and "MapBuf_" are just for readability, since the hardware willload from B regardless of what you write in the instruction statement (DBuf/MapBuf are the namesof the buffer registers in the memory section that get loaded when you do a Store_/Map_).At t0 of the entry instruction for an opcode, MemBase is loaded by the IFU with either a MemBX-relative value between 0 and 3 or an absolute number between 34 and 37. Base register 37 is usedas the code base by the IFU. The FlipMemBase function loads MemBase with its current value xor1 and MemBase_small constant loads with any value between 0 and 37.After a Fetch_, MD may be read in any of the following ways:RTEMP_MDLoad into any RM or STK registerT_MDadest_MDAny A destination (i.e., Alu or another memory request)bdest_MDAny B destinationImplicit use by ShMD...MaskThe time required for a memory reference not confined to the cache (i.e., a cache reference thatmisses or an io reference) is about 1.7 ms. A Fetch_ reference confined to the cache finishes in twocycles, which means that MD can be loaded into RM or T in the next instruction, or onto A or Bor used in ShMD...Mask in the second instruction after the Fetch_ without being held. fp!q4] Gfpy_9s# y] y\w #y[#yY#,yXU#$ UtqO S<D NFr JqW I = E[ C U B_ @7F >m-, <? :U 9 4 5H 3Q 0_^ .L ,^ *G )4= %%5s%q= #V "-[ bC <y/s~yy~7y9~y CqX x(vq7 "< U >]o6Dorado MicroassemblerEdward R. Fiala21 July 19804032. Standalone Functions, Block, and BreakpointRule: Standalone clauses should be put to the right of A clauses in an instruction statement; theassembler will generate correct output regardless of where the clause appears, but an FF > 77function to the left of a memory reference clause (which is an error) will not be flagged, if youviolate the rule.The following summarizes standalone functions, each written as a separate clause.BreakPoint(Not a function)--causes loading with bad parity in both halves of IM,interpreted as a breakpoint by MidasBlock(Not a function)--causes the Block bit to be set in the instruction (only legal innon-emulator tasks)RestoreStkPFF > 77--restores StkP to the value saved after the last IFU dispatchXorCarryFF < 100--complement the carryin from the ALUFM ramXorSavedCarryFF < 100--xor carryin from the ALUFM ram with the carryout of the lastinstruction executed by this task.Carry20FF < 100--OR 1 into the carry into Alu[13] (The hardware Alu is composedof four four-bit IC's; this function OR's 1 into the carry out of the low-orderIC.)FreezeBCFF < 100--freeze task-specific branch conditionsTIsIDFF < 100RIsIDFF < 100FlipMemBaseFF < 100--MemBase_MemBase xor 1MultiplyFF < 100TaskingOnFF > 77--enabling tasking is delayed until the next instruction for the currenttask is executedTaskingOffFF > 77UseDMDFF > 77--execute the manifold operation for the current DMux addressDivideFF > 77CDivideFF > 77IFUResetFF > 77--reset the IFULoadMCR[A,B]FF > 77--Routes first arg onto A, second onto B; loads MCR from theappropriate bits off of each bus.LoadTestSyndromeFF > 77--loads TestSyndrome from DBuf (used after a Store_).RescheduleFF > 77--cause the second IFUJump to enter a trap vectorRescheduleNowFF > 77--cause the next IFUJump to enter a trap vectorNoRescheduleFF > 77--turns off the ReSchedule conditionIFUTickFF > 77--generates the next clock for the IFU testing stuff.AckJunkTWFF > 77TIOA[device]FF > 77--loads TIOA[5:7] from FF[5:7].Wakeup[taskx]FF = 360 to 377--issue a wakeup to taskx, previously defined byTASKN[taskx,n].Notify[n]same as notify, but n is an integer 0 to 17; the Wakeup form shouldordinarily be used (exception: control section diagnostics)Cnt-1FF < 100--uses the Cnt=0&-1 branch condition function for its side-effectwithout imposing any placement constraint on the successor. The successormust be forced to lie at an odd location (e.g., by using DispTable).* The TGetsMD, ModStkPBeforeW, and ReadMAP functions are never written explicitly by programmers; theReadMAP function is imposed automatically by the RMap_ reference, ModStkPBeforeW by the appropriatestack operations, and TGetsMD when both T and an RM address are loaded from MD. fp!q4] Gfp ^r0 []tq#pq Y] WA U RQxOs Q8 QNi$xLQIQKaxI QExHQ3xFk Q(QE "xCcQ/QB)&Q@x>Q0x=SQx;Qx: Qx8]Qx6Q3Q5Ux3 Qx2Q@x0_Qx.Qx-Qx+i Q.Q*!x(`Q<x& Q8x% Q6x#j Q+x!Q<x Qxt Q&x Q 'QlxQ0Qd;xQ5Q\< QDxT*;xPxO o=XaDorado MicroassemblerEdward R. Fiala21 July 19804133. BranchingThis section discusses branch clauses in instruction statements, declarations which affect branching,and dispatch clauses.Micro assembles instructions for an imaginary machine identical to Dorado but with additionalfields assembled for its postprocessor. The imaginary machine is characterized by full-size 14-bitbranch addresses in instructions and 14-bit program addresses in IFUM. MicroD places instructionsand transforms the .Dib file for the imaginary machine into a .Mb file for Dorado. Algorithmsused by MicroD are described in the appendix.33.1. What the Branch Hardware DoesDorado implements three kinds of control transfers determined by the value in the JCN field of aninstruction: jumps, returns, and IFU jumps; jumps may be "local," "global," "long," or"conditional." The processor always branches or returns--the hardware contains no concept of not-branching or of falling through to the next instruction.Returns and IFU jumps load the Link register unconditionally; jumps load Link iff the targetaddress is 0 mod 20. For all of these, the value loaded into Link, if any, is ((.+1) & 77) + (. &7700); i.e., Link is loaded with caller's address +1 (carries not propagating beyond the low six bits).For reasons that will be apparent, it is convenient to view the microstore as composed of 100 pagesof 100 words each. Local jumps transfer control to any location on the current page, global jumpsto location 0 on any page, and long jumps to any location in the microstore (using the FF field toextend JCN).An explicit branch clause may be unconditional or conditional. When conditional, the branchaddress is executed next, if the condition is false, or the branch address OR 1, if the condition istrue. The decision to load Link (i.e., Call or Goto) is based upon the false branch address.Branch conditions may be encoded as functions (FF < 100), in the JCN field, or both (when twoBC's are specified, the true path takes if either condition is true). When encoded in JCN, the falsebranch address must be at locations 4, 6, 10, ... , or 36 in the current page. When the BC is codedonly in FF, the false branch address can be at any even location in the same page or at a globallocation.The locations which are multiples of 4 are IFU targets. Namely, it is possible to origin an IFUentry vector at these points.Dispatches allow an instruction to modify the branch address of the next instruction for the sametask. The address modification consists of "OR"ing bits computed by the dispatch with the branchaddress computed in cycle i+1. fp!q4] Gfp ^r []q41 Y V!N TVK R$> P;# N- Jt$ G?q=$ Et*8+ CZ A8 >m> <R :X 7f] 5\ 302 2 .D ,K *B 'S %_ #Q "-2. b 8( & C (9  > =T3Dorado MicroassemblerEdward R. Fiala21 July 19804233.2. Branch ClausesThe assembly language has IFUJump and Return constructs analogous to the underlying hardwareoperations. However, the complications surrounding jumps are, for the most part, concealed fromthe programmer.If the programmer doesn't specify any branch clause in the instruction statement, the assembler willfabricate a jump to the next instruction inline. Several constructs of the form:Goto[ba, bc1, bc2] -or-DblGoto[batrue,bafalse,bc1,bc2]are defined (see below), where both branch conditions are optional in the "Goto" form, and thesecond branch condition is optional in the "DblGoto" form. "Goto" indicates that the Link registermust not be modified and "Call" that Link must loaded with the address of the next instructioninline; "Branch" is deliberately indefinite about whether a "Goto" or "Call" is done.Branch addresses for these may be either instruction tags or one of the following special symbols: .-3 .-2 .-1 . .+1 .+2 .+3, where "." refers to the current instruction and the others are relative to thisinline. [It is obviously possible to define .-4, .+4, .-5, etc., but my feeling is that it is bad style tojump further than +/- 3 without using a tag. If anyone finds this inconvenient, please let meknow.]Branch condition arguments may be either "regular" (one of the 10 in the hardware manual) or"complementary" (complements of the 10 in the hardware manual). The branch conditions arenamed as follows:RegularComplementaryAlu=0Alu#0Alu<0Alu>=0Cnt=0&-1Cnt#0&-1Also decrements Cnt after testing for the branchR<0R>=0R oddR evenCarry'CarryRescheduleReschedule'(Emulator task only)IOAtten'IOAtten(io tasks only--same encoding as Reschedule)OverflowOverflow'(FF encoding only)Alu<=0Alu>0Combination of Alu=0 in FF and Alu<0 in JCNWhen complementary branch conditions are used, the assembler simply reverses the order of thebranch tags. Hence, DblGoto[T1,T2,com C1, com C2] = DblGoto[T2,T1,C1,C2]. This is providedas a programming convenience.Warning: If two branch conditions appear in a statement, they must be both regular or bothcomplementary. When two regular branch conditions are used, the true path takes if either is true.However, when two complementary branch conditions are used, the true path takes only when bothare true. Don't get confused by this. fp!q4] Gfp _t [q,0 YG X TS RQyO`yM J#V HYL FI DU AR<* ?h =%F ;[ :' 67% 4Z 3 y0_u0 y.*s0y,0y+i0&0y*0y(0y'F0y% 0 &y$0&,y#$0&y 0&+ qD J   tq!p qp  q< O :& 0 >WDorado MicroassemblerEdward R. Fiala21 July 198043The "Top Level" and "Subroutine" declarations control assembler error checking. In Top Levelmode, calls and dispatches are legal, returns are illegal, and branches may have target addresses thatlie on either call or goto locations. In Subroutine mode, calls and dispatches are illegal, returns arelegal, and branch targets are required to be at goto locations.The assembler constructs are given below, where "<>" denote optional args; C1 and C2 either twohardware branch conditions or complements of two hardware branch conditions:Return[]To Link and smashes Link--illegal in Top Level mode. A branch condition (usesFF < 100) makes sense only when the caller has skip/noskip return pointscreated by an SCall, DblSCall, or SCoReturn.CoReturn[]Like Return but Link_.+1 and next instruction inline placed at .+1.DblBranch[T1,T2,C1<,C2>]To T1 if C1 or C2 true, else to T2. T1 will be placed at T2 OR 1; placementof T2 is limited to goto locations in Subroutine mode, else unconstrained.DblGoto[T1,T2,C1<,C2>]like DblBranch[T1,T2,C1<,C2>] constraining T2 placement to goto locations.DblCall[T1,T2,C1<,C2>]like DblBranch[T1,T2,C1<,C2>], constraining next instruction inline to be at.+1, and limiting T2 to call locations. Illegal in Subroutine mode.Branch[T1<,C1<,C2>>]To T1 if C1 or C2 is true or if both branch conditions are omitted; otherwise tonext instruction inline. When conditional, T1 will be placed at .+1 OR 1. InSubroutine mode, either .+1 (conditional) or T1 (unconditional) constrained togoto locations.Goto[T1<,C1<,C2>>]like Branch[T1<,C1<,C2>>] constrains either T1 (unconditional) or nextinstruction inline (conditional) to goto locations.Call[T1<,C1<,C2>>]like Branch[T1<,C1<,C2>>]; illegal in Subroutine mode; complementary BC'sillegal; constrains next instruction inline to be at .+1; constrains placement ofeither T1 (unconditional) or next instruction inline (conditional) to call locations.Discussed below.IFUJump[i<,C1>]Dispatch to the i'th entry vector of the next opcode (An error is flagged if i >=the entry vector size specified by the last InsSet declaration). A branch conditionwould only be used if a conditional exit programming convention is followed, asdiscussed in the hardware manual; complementary BC's are illegal.DblSCall[T1,T2,C1<,C2>]= DblCall[...] and forces odd placement of the instruction and placement of thenext two instructions inline at .+1 and .+2 so that the subroutine can doskip/noskip Return by using a branch condition.SCall[T1<,C1<,C2>>]= Call[T1<,C1<,C2>>] and forces odd placement of the instruction andplacement of the next two instructions inline at .+1 and .+2 so that thesubroutine being called can do skip/noskip Return by using a branch condition.Complementary branch conditions are illegal.SCoReturn[]= CoReturn but forces placement at an odd location and placement of the nexttwo instructions inline at .+1 and .+2. A complementary branch condition isillegal and use of any branch condition only makes sense when the caller enteredby means of SCall or SCoReturn.--No branch clause = Branch[.+1]A Branch while Top Level is in force imposes less placement constraints on the target instruction(s)because it permits either the Call or Goto locations to be used.DblBranch, DblGoto, and DblCall are expected to be less frequent than Branch, Goto, and Call fp!q4] Gfp _q? ]K15 [44 Y? VDD TyLxQs GPW9N,xLX CxI AHY;xE-xCCADx?C =3<\,":x8] > 63x4^"'2Q1-(0;x-A,<"2* B){Ax&2%|+$/x!}, 8C Z,x)#[.Px q\ @ pI 6 )=\`Dorado MicroassemblerEdward R. Fiala21 July 198044because programmers ordinarily think of branching or falling-through rather than branching to oneof a pair of instructions.For an unconditional top level Branch, MicroD outputs a long call or long goto if the FF field isunused, and imposes no constraint on the placement of either the instruction or its target. If FF isused, then the branch target will have to be in one of the 100 same-page or 100 global branchlocations reachable by a JCN branch.An unconditional Call is assembled as a long call if FF is unused. In this case, the branch addressmay be any call location. If FF is used, then the target address has to be one of the 3 call locationsin the same page or one of the 100 global call locations. The next instruction inline is placed at.+1 within the page.A conditional Call is just barely possible. It requires the next instruction inline to besimultaneously at the true branch address xor 1 and at the address of the caller +1. Since the truebranch address must be at a location with four low bits equal 0001, these conditions are only met atthree positions within a page (e.g., the Call, false target, and true target may be placed at 17, 20,and 21; at 37, 40, and 41; or at 57, 60, and 61 in the page). This implies that complementary BC'sare illegal with Call, nor can you encode two consecutive instructions each containing a conditionalCall, nor can you have more than one conditional call to a single subroutine.It is also impossible to have a Call in an instruction which is the false target of a conditional Branchbecause the return of the Call would be to the true target of the previous conditional branch.An unconditional Return branches to Link, normally containing the address of the caller +1.There is no placement constraint on an instruction containing a Return.A conditional Return goes to Link if the branch condition is false or to Link or'ed with 1 if thecondition is true. This allows a skip/noskip return to the caller, which only makes sense if thecaller imposed the necessary placement constraints on his two successor instructions by using anSCall, DblSCall, or SCoReturn.An unconditional Goto is assembled as a long goto if FF is unused. If FF is used, then the branchaddress has to be one of the 74 goto locations in the same page.Suggestion: In programs that nearly fill the control store, or in smaller programs that have largeinstruction clusters, you should carefully use Branch rather than Goto in Top Level mode to giveMicroD greater freedom in placing instructions; in Subroutine mode, you may use either Branch orGoto, but I suggest that you pick a consistent convention: either always use Goto or always Branch.33.3. Dispatch ClausesThe assembly language defines the following dispatch clauses:BDispatch_B10-way dispatch on B[15:17]BigBDispatch_B400-way dispatch on B[10:17] fp!q4] Gfp _q] ]K YM X<) VD] Ty$ QQ O=K MrV K H68" Fk6. DQ BH A P ?AJ =vM :*> 89V 42) 2G //2 -4- +N *+ &7+ $@ !}p q7! X G T t eq=ys QyC Q F  >WDorado MicroassemblerEdward R. Fiala21 July 198045Multiply is also a dispatch. Dispatches OR bits into the branch address computed by the nextinstruction for the same task. This means that the programmer must impose the necessaryconstraints on the target instructions in the dispatch table himself--MicroD won't do it for him.This is done using placement declarations as discussed in the next section.34. Placement DeclarationsWhen an IFU location is assembled, the address to which it dispatches is automatically marked asan IFU entry--no explicit declaration is required when assembling that instruction. In other words:IFUReg[n,TAG,..otherjunk..]; *Opcode n PUSH2automatically makes TAG an IFU entry. When you specified the opcode set with InsSet[i,n], youdeclared that there would be n entries for each IFU dispatch in the instruction set. You must putthe n entries in sequence in the source, with the first at TAG and the others after that.Global entries are declared by a "Global" clause in a statement, e.g.:DONEXT: Return, T_ID, Global;Global declarations cause placement at one of the 100 global call locations in the microstore.Global placement must be explicitly declared--MicroD handles most placement automatically, but itdoes not automatically assign globals.Placement requirements for instructions in a dispatch table (i.e., of instuctions which are the targetsof BDispatch_B, BigBDispatch_B, etc., or of a computed Return) may be declared either throughusing "At" on every instruction in the table (see below), or, under suitable conditions, using theDispTable macro.DispTable[LENGTH,MASK,VALUE] appearing as a clause in an instruction statement causes thatstatement to begin a group of LENGTH consecutively-placed statements, 1 <= LENGTH <= 20.The first statement is placed so that [address and MASK] = VALUE. MASK defaults to [nextpower of 2 >= LENGTH] - 1, and VALUE defaults to 0. Note that LENGTH+VALUE must be<= 20.A 10-way BDispatch might be written as follows:BDispatch_RTEMP;... , Goto[SWITCH];SWITCH:... , DispTable[10];*B[15:17] = 0... ;*B[15:17] = 1...... ;*B[15:17]=7where the three instructions in the dispatch need not be consecutive in the assembly source. fp!q4] Gfp _q@ ]KN [ S YK Tr QNq.2 O]yLs- Isq&8 GT E: BlFy?s <\q&8 :A 8& 5U*= 3] 1^ / ,N *F (2' '# I %X !/ %s y )W )W A )W qK J>TDorado MicroassemblerEdward R. Fiala21 July 198046An instruction containing the clause "At[N]" will be forced by the assembler to appear at absolutelocation N in the microstore. "At[N1,N2]" in an instruction is equivalent to At[Add[N1,N2]]. "At"will be necessary for the special IFU trap locations and for instructions in dispatch tables that donot meet the constraints of the DispTable macro above. The currently reserved locations in IM aregiven in the hardware manual.Warning: In addition, because instruction addressess are unknown during assembly, it is illegal tocreate parameters, constants, or RM data referring in any way to absolute locations. To do this, youmust manually locate each affected instruction with "At" and do arithmetic on integers with thesame values as the instruction locations. This will probably be required for the startup instructionsof all tasks, which must be loaded into Link for a LdTPC_.Normally, MicroD automatically chooses the page assignment for an instruction not constrained by"At"--the TITLE statement enables automatic page assignment. However, the following macros areavailable for constraining the page on which an instruction is placed:OnPage[n];as a separate statement will constrain MicroD to place subsequently assembledinstructions on locations on page n (i.e., in the range n*100 through n*100 +77).AutoPage[n];undoes OnPage and allows MicroD freedom to place anywhere.OnPage may be useful in dealing with microcode overlays, as discussed later.In addition to the above placement macros, there are two macros for "reserving" and "unreserving"locations in IM. These macros, which direct MicroD to avoid placing instructions in particularmicrostore locations, are as follows:IMReserve[p,w,n];where p, w, and n are integers, reserves n locations beginning at word w on pagep.IMUnreserve[p,w,n];unreserves n locations beginning at word w on page p.35. Microcode OverlaysThe barest minimum provisions are made for microcode overlays. Because we cannot handledynamic relocation, non-conflicting placements must be made for the resident system and alloverlays that may be used with it. There are several ways that safe placement may beaccomplished:First, MicroD can write an xxOccupied.Mc file in which all locations used in the resident systemloadup are indicated by IMReserve statements. The xxOccupied.Mc file can be loaded with anoverlay to ensure safe placement by MicroD of code in the overlay. A disadvantage of this methodis that whenever the system microcode is modified, all overlays using this method must beregenerated.Next, the resident microcode can itself reserve regions of the microstore with IMReserve so thatoverlays confining themselves to the reserved area need not be regenerated when a new system isreleased.Thirdly, throwaway initialization code may be manually placed by means of OnPage or At fp!q4] Gfp _qI ]KF [L Y6, W Tytq!9 R#B PJ O X MO: IA H0/ FHFxCs IB%M@x>& : :qL 7f"? 5T 3%x1s>/x-5 (=r $q*. #; !6 ) , k ` /!: dR ?  ]N >!  VV : =]Dorado MicroassemblerEdward R. Fiala21 July 198047declarations that totally fill some pages of the microstore, and these pages are available to overlaysafter execution. If this method is used in conjunction with one of the first two methods,IMUnreserve declarations can be used to free up the pages filled with the throwaway code.Finally, particular instructions in the resident system may be overwritten by particular instructionsin an overlay; these must be manually placed with "At" declarations in both the system microcodeand the overlay. fp!q4] Gfp _q@& ]KA [Y X'> VD1/ Ty T2=GDorado MicroassemblerEdward R. Fiala21 July 19804836. Instruction Memory Read-WriteThe hardware provides an efficient method for loading the instruction memory (which might becommon if microcode overlays are used) and a painful method of reading the instruction memory(unlikely to be dynamically frequent). Each instruction that reads or writes IM takes three cycles.IM read/write is encoded in the JCN and RSTK fields of the instruction, so you may not programany control clause in the same instruction. The instruction after the one doing the read or writemust be at .+1 within the page, and the assembler automatically imposes this constraint, so you donot have to use "At[N]". Tasking must be off.For loading IM, the address to be written is first loaded into Link_, then the left or right half iswritten from a B source. RSTK[1:3] control left/right half, good/bad parity, and the 17th data bit(RSTK.0 or Block), so there is little flexibility in selecting an RM address for use with the write--you probably should source the data from T, Q, or Cnt. Link is smashed with .+1 after the write,so it has to be reloaded before writing the other half of IM. The following sequence is an example:%Have 16 bits of left-half data at STK[StkP], RStk.0 and JCN.7 value in the sign bit and low bit ofSTK[StkP-1], respectively, and 16 bits of right-half data in STK[StkP-2]. Write this data into the IM addressin Q with good parity.%T_Stack&-1, Link_Q;TaskingOff, Stack&-1, Branch[R0TRUE,R<0];IMLHR0'POK_T;T_Stack&+1, Link_Q;WRH:Stack&-2, Branch[BTRUE,R ODD];IMRHB'POK_T;IMWFIN:TaskingOn;...R0TRUE:IMLHR0POK_T;T_Stack&+1, Link_Q, Branch[WRH];BTRUE:IMRHBPOK_T;T_Stack&-2, Branch[IMWFIN];The IM write instructions take three cycles each but are otherwise indistinguishable from ordinaryinstructions. This means that there are no strange restrictions on other actions carried out in thesame instruction.IM data are read nine bits at-a-time, with the address again coming from Link and the byte numberfrom RStk[2:3]. The data arrangement is shown in a figure of the hardware manual and is readback by the B_Link function in the cycle immediately after the read.%Have IM address in RM location RTemp1. Read the left-half of IM to RTemp3 right-half to RTemp2using RTemp0 as temp storage. Assume RBase points at correct region of RM at call. The extra bits of IM(P.16, P.17, RStk.0, and Block) are flushed. RTemp0 to RTemp3 are RM locations whose low bits are 0, 1, 2,and 3, respectively. RRetn is another RM location in the same region as RTemp0 to RTemp3% fp!q4] Gfp ^r" []qS YV W'= TVG RJ PC N. K); I_ G41 F$Z DZ+9yAsPy@795y>y=v<:)9T 7y651 y3 2py/ .qy+ *r '#q$> %X@$ # a QM Dys`ydUyOyEyB =SDorado MicroassemblerEdward R. Fiala21 July 198049Subroutine;RDIMD:RRetn_Link;*Save return to caller of subroutineTop Level;Link_RTemp1;TaskingOff;ReadIM[1];RTemp0_Link;*RTemp0[7:17]_byte 1Link_RTemp1;ReadIM[0], T_Lsh[RTemp0,10];*T[0:7]_byte 1 flushing parity bitRTemp3_Link;*RTemp3[7:17]_byte 0Link_RTemp1;*RTemp3_byte0,,byte 1 (flushing RSTK.0 bit)ReadIM[3], RTemp3_Lcy[RTemp3,T,10];RTemp2_Link;*RTemp2[7:17]_byte 3Link_RTemp1;ReadIM[2], T_Lsh[RTemp2,10];*T[0:7]_byte 3, flushing parity bitRTemp2_Link;*RTemp2[7:17]_byte 2TaskingOn;Link_RRetn;*Restore return address to LINKSubroutine;*RTemp2_byte2,,byte3 flushing JCN.7Return, RTemp2_Lcy[T,RTemp2,10];37. Reading and Loading Task PC'sThe method by which task PC's (TPC) are loaded for specific tasks, like the IM read/write, is afunny format RETURN in the JCN field of the instruction. Consequently, control clauses areverboten in the instructions that do this, and, again, the successor to the instruction that does theTPC read/load must be at .+1 within the page (automatically constrained by the assembler).Tasking must be off.Data for TPC goes to/from LINK, task number from B[14:17].Two macros are defined for reading and writing TPC from Link (These are B destinations.):LdTPC_Loads TPC for task from LINK, task number from B[14:17]RdTPC_Reads TPC for task into LINK, task number from B[14:17]These macros fill in JCN appropriately. Normally, the task number on B will be a constantproduced by mentioning the name of a task you have previously defined with TASKN, e.g.:TASKN[DSP,14];*Define DSP as the display taskLink_DSPST;*Load Link with starting addressTaskingOff;*Require tasking off during LdTPC_LdTPC_DSP;*is then equivalent to LdTPC_14C;TaskingOn; fp!q4] Gfpy_9s y\ )W$yY W^ U T S< )WQ Pz)W O )WM yLX+J#I )WH6 F)W Et )WD B )Wy@ y=v#< 7Br" 3q;$ 29" 0; Z .q#7 , )4: %"7y#s7y!7 Qq N "6ys )W' )W )W"e )W!  >U*Dorado MicroassemblerEdward R. Fiala21 July 19805038. Divide and MultiplyThe Dorado hardware defines special standalone functions Multiply, Divide, and CDivide whichallow multiplication to be carried out in a one-cycle loop and division in a two cycle loop.The hardware actions caused by these functions are as follows:Multiply:PD_ALUCarry..ALU/2Q_ALU[17]..Q/2Next branch address_ whatever it is 'or' 2 if Q[16] is 1Divide:PD_2*ALU..Q[00]Q_2*Q..ALUCarry'The following examples show how these are used:%At entry:RTemp/ multiplier (20-bit unsigned)T/ multiplicand (20-bit unsigned)At exit:RTemp..Q/ 40-bit resultThe first step is outside the inner loop. It moves the multiplier into Q and tests Q[17]. The second step, alsooutside the inner loop, tests Q[16] with the Multiply function and initializes the result (computed in RTemp)to 0. It enters the inner loop at the "add" or "no-add" position based upon step 1. The Multiply functionalso causes a dispatch, so the inner loop is entered with the "add" or "no add" decision already made for thetwo low bits of multiplier, 0 in Q[0], and untested multiplier bits in Q[1:16]. The inner loop does 16 usefulMultiply steps, 1 useless step testing the 0 that started out in Q[0], and then the exit instruction does a finalMultiply testing the low bit of the result, leaving the result in RTemp[0:17]..Q[0:17]. Instruction placement iscritical. The two exit instructions have to be located so that 'or'ing 2 into their locations doesn't change thelocation. The inner loop instructions have to be located so that the first is a fast-goto location and a multipleof 4. This can only be satisfied if the low four bits of address are 4, 10, or 14.%MULT:Q_RTemp;Goto[.+2,R Even], B_RTemp, Cnt_16S;Goto[M1], RTemp_T-T, Multiply;Goto[M0], RTemp_T-T, Multiply;DTABLE[MulX,0,7770]; *Dispatch table origin 0 mod 10 (0 and 1 unused).MXIT0:Dat[MulX,2];Return, Dat[MulX,3];*Here after Q[16] was 0 (no add)M0:DblGoto[M0,M0E,Cnt#0&-1], RTemp_RTemp, Multiply, Dat[MulX,4];M0E:Goto[MXIT0], RTemp_RTemp, Multiply, Dat[MulX,5];*Here after Q[16] was 1 (add)M1:DblGoto[M0,M0E,Cnt#0&-1], RTemp_(RTemp)+T, Multiply, Dat[MulX,6];Goto[MXIT0], RTemp_(RTemp)+T, Multiply, Dat[MulX,7];%At entry:RTemp/ most significant 20 bits of 40-bit unsigned dividendQ/ least significant part of dividendT/ divisor (20-bit unsigned)At exit:Q/ quotient (20-bit unsigned)RTemp/ remainder (20-bit unsigned) fp!q4] Gfp ^r []qN Y)3 V!>yS_s\Q\P \O=8yL\K>\I Fq/yCs yBl#yA !y?y>Jy;*Gy:K#Jy8&Ey7Oy6(Sy4&Ky3g]y2I(y0.Dy/DSy-y+E)#('#y$Fy#$ !y%y=yc0yyAA4y yB;y%yy yy ^" n ;=Z Dorado MicroassemblerEdward R. Fiala21 July 198051Each divide step shifts Q[0] from the low part of the dividend into the high part of the dividend while doingthe Divide function and testing for exit. The second instruction chooses between add or subtract, based uponwhether or not the last add/subtract "succeeded".The duplicated instructions are required because they are part of branch condition pairs.%DIV:(RTemp)-T, Cnt_17S;Goto[DivOK,Carry'];*Test whether the divide is possibleReturn, RTemp_T-T;*Return 0 indicating impossibleDivOK:PD_T;Goto[BigDiv,Alu<0];*Branch for the hard caseDblGoto[DvExit,DvTest,Cnt=0&-1], RTemp_(RTemp)-T, Divide;*Easy case--divisor bit 0 is 0DvTest:DblGoto[Dv0,Dv1,Carry'];Dv0:DblGoto[DvExit,DvTest,Cnt=0&-1], RTemp_(RTemp)+T, Divide;Dv1:DblGoto[DvExit,DvTest,Cnt=0&-1], RTemp_(RTemp)-T, Divide;DvExit:Goto[DvXit0,Carry'];DvXit1:(RTemp)-T, Divide;DblGoto[DvXitFix,DvXitOK,Alu<0], RTemp_(RTemp)-T;DvXit0:(RTemp)+T, Divide;DblGoto[DvXitFix,DvXitOK,Alu<0], RTemp_(RTemp)+T;*Fix for having subtracted too much in last stepDvXitFix:Return, RTemp_(RTemp)+T;*Adjust remainderDvXitOK:Return;*Hard case--bit 0 of divisor is 1BigDiv:DblGoto[BigDvd,BDvLp1,Alu<0], RTemp_(RTemp)-T, Divide;BDL2:DblGoto[BigDvd,BDvLp1,Alu<0], RTemp_(RTemp)-T, Divide;BDvLp:DblGoto[BigDvd,BDvLp1,Alu<0], RTemp_(RTemp)-T, Divide;BDvLp1:RTemp_(RTemp)+T;Goto[BDvLp,Cnt#0&-1], RTemp_(RTemp)+T;BDvXit:(RTemp)-T, Divide;BDvXit0:DblGoto[DvXitFix,DvXitOK,Carry'], RTemp_(RTemp)-T;BRDX:Goto[BDvXit0],(RTemp)-T,Divide;*Big partial dividend, check for carryBigDvd:Goto[BigDvH,Carry'];DblGoto[BDvXit,BDvLp,Cnt=0&-1], PD_RTemp;*Most complicated case--big R and no carryBigDvH:RTemp_(RTemp)+T, Goto[.+2,Cnt#0&-1];*R+2T-TBRDX1:PD_(A_RTemp), CDivide, Return;*Force carry to 0--1 bit in QBigRLP:Goto[BrDvXit,Cnt=0&-1], RTemp_(A_RTemp), CDivide;Goto[BDL2,Alu>=0], PD_RTemp;Goto[BigRLP], RTemp_(RTemp)-T;*Exit for the hard casesBrDvXit:Goto[BRDX,Alu>=0];RTemp_(RTemp)-T, Goto[BRDX1]; fp!q4] Gfpy_9smy]Ny\w1yYYyXxyUTy)W$S)WyPzO)WM9yKyIyHY9yF9yDZyBA1y@7>1y=v0y<:)W y9T7y5U!y36y26y126y/.q&y-y+*N2y(y&O&y$#)y *y$.qy.yy/1myyn  8cWDorado MicroassemblerEdward R. Fiala21 July 19805239. Programming Tips and ExamplesExperience suggests that it is necessary to worry about availability of FF for use in long branches.For this reason you should try to leave the FF field free for a long branch when this doesn't addextra instructions.Another issue to be concerned with is usage of Alu operations. Preliminary versions of the Mesaand Alto emulators have suggested that the 15 operations *'ed in the "Assembling for ALUFM"section will be required. At the moment, A0 is also defined. However, try to avoid using A0 andother doubtful operations unless you really need them. In those places where A0 would be thesimplest, try to use A-B with the same source for both A and B instead. Similarly, try to use A-B-1rather than A1 and XOR rather than EQV. If you need an extra operation to save time or space,go ahead and use it, but don't do this needlessly in case we decide to change the selection ofoperations later.Also, BitBlt uses two ALUFM locations as variable operations but should restore these to standardvalues before exiting to the next opcode. If these two operations are restored, the emulator willhave 17 Alu operations available, though other tasks will have only 15 available. The comments inthe D1Alu.Mc file show how to define the two "emulator only" operations so that the assemblerwill flag an error when one of these is used from an io task.It is also important to take full advantage of the various numbers which can be delivered by _IDwhen programming emulators. These are the operand, argument bytes alpha and beta, and theninstruction length endlessly. For example, on Mesa DIVIDE, it was possible to use length=1 tonegate the quotient and remainder with (ID)-T-1 (etc.). Also, the same instruction can be used forNOT and NEG opcodes and the same exit instruction for ADD and SUB. Try to exploit thevarious options afforded by this.The examples below will be augmented as more code is available.*Mesa Read-Field opcodeRDFLD:IFetch_Stack, TIsID;*Calc. pointer as MDS+a+StackStack_MD, RF_ID;*IFU supplies bIFUJump[0], Stack_ShiftLMask;*Shift and mask, Stack_result*Opcode 23, type = regular, length = 3 bytes, MemBase_MDS, RBase_0, no operandIFUReg[23,3,MDS,0,RDFLD,17,0,0];*Mesa Write-Field opcodeWRTFLD:T_(IFetch_Stack&-1)+T, TIsID;*Calc pointer and save in TWF_ID, RTemp_T;*T_field descriptorT_ShMDBothMasks[Stack&-1];*Deposit Stack in MD and popIFUJump[0], Store_RTemp, DBuf_T;*Store result, exit*Opcode 24, type regular, length = 3 bytes, MemBase_MDS, RBase_0, no operandIFUREG[24,3,MDS,0,WRTFLD,17,0,0];*Random number generator using 8 words of RM as storage for the "state" of*the generator. fp!q4] Gfp ^r" []qG Ya W TV+5 RD PG N:# M,<( Ka4* I^ G DZ<% B)9 @(: >,1 =/= 9O 7H 6(+3 4^!B 2B 0! -V?y*sy),ts'i, t%s,y#GNy!yHy,, &,, y'Ly!y(Jy >Vg%Dorado MicroassemblerEdward R. Fiala21 July 198053RMRegion[Other];RV[RGState,0]; RV[Rand,0];RMRegion[Random];RV[R0,134134]; RV[R1,054206];RV[R2,036711]; RV[R3,103625];RV[R4,117253]; RV[R5,154737];RV[R6,041344]; RV[R7,006712];SET[X,20];*A "call" locationRGen:Goto[RGen1], T_R0, RBase_RBase[Rand], At[X];Goto[RGen1], T_R1, RBase_RBase[Rand], At[X,1];Goto[RGen1], T_R2, RBase_RBase[Rand], At[X,2];Goto[RGen1], T_R3, RBase_RBase[Rand], At[X,3];Goto[RGen1], T_R4, RBase_RBase[Rand], At[X,4];Goto[RGen1], T_R5, RBase_RBase[Rand], At[X,5];Goto[RGen1], T_R6, RBase_RBase[Rand], At[X,6];Goto[RGen1], T_R7, RBase_RBase[Rand], At[X,7];RGEN1:Return, T_Rand_(Rand)+T;*The calls are as follows:RGState_(RGState)+1, BDispatch_RGState;Call[RGEN], RBase_RBase[Random];*Return random number in T*Test-and-set in one instruction for use by different tasks that control*each other. Sign bit of RM register RFlag is the lock.RFlag_(RFlag) or (100000C), Branch[AlreadyLocked,R<0];*Alternative lock procedure: store -1 in RFlag when unlocked; then:RFlag_(RFlag)+1, Branch[AlreadyLocked,R>=0];Appendix 1. MicroDMicroD transforms .Dib files produced by Micro into .Mb files. Since instruction placement isfairly tedious, the display shows a progress message, so you can monitor progress of the load. Thesequence of progress messages is as follows:Loading File1...Loading File2... ...Loading FileN...N instructions, M words for symbolsLinking...Building allocation lists...Assigning locations...Reloading binaries...Checking assignment...Writing .MB...N words freeError messages may appear at any time. Some of these immediately abort the load, but most errorsdo not abort until the end of the current progress step. In other words, errors during "Linking...",will usually abort at the end of this loading phase; errors during "Building allocation lists...", usuallyabort at the end of this phase, etc. fp!q4] Gfpy_9sy]y[:yYyXxyWyUyS yQ,PW.N.M.L5.J.Is.H.yEtyB@7'>,y<8Hy:89w6y6D5x, 0r -3q^ +iQ ),y&sy%|y$y"y!Y#y yy7yyuy y eq&; P J $d =YMDorado MicroassemblerEdward R. Fiala21 July 198054After "Building allocation lists..." has completed, all bugs will have been detected except conflictingabsolute addresses (two AT's at same location) and various overflows (too many globals, too manyIFU entries, too many instructions on a page, etc.).The data printout for IFUM and RM is in two columns. For RM the address symbol(s) associatedwith a location are printed to the right of the data. For IFUM, the IM target symbol is printed tothe right of the data. For IM, the printout is like the following:345457 23456 23457FOO346601233333144444meaning that the 345th instruction assembled by Micro with label "FOO" was placed at absolutelocation 457 and the two 16-bit numbers are the octal contents of the instruction.The error messages produced by MicroD contain the symbolic address of the instruction at whichthe error was detected, when relevant.Micro Output for the Imaginary MachineMicro outputs stuff for IM, RM, IFUM, ALUFM, STK, and fake memories called BR, BRX,DEVICE, TASKN, VERSION, RVREL, IMLOCK, and IMMASK.MicroD transforms only IM and IFUM data. Addresses in all memories and data in all memoriesexcept IM and IFUM pass through MicroD to the .Mb output file unchanged--this excludes dataand addresses for VERSION, RVREL, IMLOCK, and IMMASK, which are fake memories whosecontents and address symbols are consumed and flushed by MicroD.Data are output for IM, IFUM, ALUFM, RM, and STK in the form expected by MicroD andMidas, as given below. BR, BRX, DEVICE, and TASKN have address symbols useful whendebugging with Midas but no data are output for these memories. In summary, we have:IMTransformed by MicroD--see belowIFUMTransformed by MicroD--see belowRM20-bits per wordSTK20-bits per word (Most programs don't assemble anything for this memory, but provision is madefor this.)ALUFM10-bits per word with 0 and 3:7 containing the 6 bits loaded into the ALUFM ramBRbase register address symbols for debuggingBRXMemBX-relative base register address symbols for debuggingDEVICEio device address symbols for debuggingTASKNtask address symbols for debuggingVERSION1-word memory defining the machine as Dorado for MicroD.IMLOCK10000-word x 1-bit memory; a 1 in an IMLOCK word prevents MicroD from placing anyinstruction in the corresponding location of the microstore.IMMASK10000-word x 24-bit memory defining dispatch table length and allowable placement of first word.IM and IFUM parity bits expected by the hardware are computed by neither Micro nor MicroD;Midas computes these at the time it does the load. fp!q4] Gfp _qK ]KW [4 XH VDD TyCxQs\/xPW\/ MqF K>R GB F& Au& >Jq,' <2 9 3) 7BR 5x-& 3@ 0;$/ .q7 ,/&x)sx(`x&x%XV# x"s?x +xk:x'xc"x/8xE J<x2. wqN 2  f=W-Dorado MicroassemblerEdward R. Fiala21 July 198055Micro outputs a modified form of Dorado IFUM words, as follows:PA 1 bitPacked-a bitNEnt 2 bitsNumber of instructions in target sequence 1 bitUnusedIFAD14 bitsImaginary address of target instructionSign 1 bit 3 bitsUnused (parity bits filled in by Midas)Length' 2 bitsopcode length (1, 2, or 3 bytes)RBaseB' 1 bitRBase initializationMemB 3 bitsMemBase initializationPause' 1 bitJump' 1 bitN 4 bitsAll of the bits are located in positions compatible with IFUMRH_/IFUMLH_ except for IFAD,which has two extra bits. These extra bits are positioned to avoid conflict with realIFUMRH_/IFUMLH_ data bits.MicroD will transform IFAD into a real address and output the proper 12 bits in 0 to 11 of the firstword, as well as zeroing the extraneous bits.Micro outputs for each instruction assembled the 42-bit (+2 parity bits) instruction and four extrawords of stuff needed by MicroD as follows:Dorado instr.42 bitsComplete except for branch address stuffP016 1 bitLoad bad parity into IM[0:20]P2141 1 bitLoad bad parity into IM[21:41]14 bitsunused 1 bitunusedW0@ 1 bitPlace at location W0Glb@ 1 bitPlace at a global locationOnPg@ 1 bitPlace on the page specified in W0W014 bitsLocation for placement if W0@ or OnPg@ = 1Returns 1 bitThis instruction does a Return, CoReturn, or IFUJump(or IM or TPC read/write)Calls 1 bitThis instruction does a Call or CoReturnJBC 1 bitThis instruction has a branch condition in JCNUsesFF 1 bitFF field unavailable for long goto or long callW114 bitsImaginary address of unconditional or false branch(7777 defaults this to .+1)Branches 1 bitThis instruction does a BranchGoes 1 bitThis instruction does a GotoEmul 1 bitPrint as emulator instructionIsCond 1 bitThis instr has a branch condition (i.e., W2 at W1 OR 1)W214 bitsImaginary true address of conditional branch(7777 defaults this to .+1)W1 and W2 may receive automatic Micro fixups if they are forward references. fp!q4] Gfp _q?x\1s/tsxZ/#Y/xW/'xTS_/'xQ/xPW/xN/xMOxKxJG Fq8! E-2C3 Cc ?J >&- :03 8+x6(s x4x3g2/hx.x,x+Ex)"x'F0%x$$x#$*x!-x b)xcxxxA3x# 1qL =V!Dorado MicroassemblerEdward R. Fiala21 July 198056Micro finishes assembly for all bits of the instruction except those referring to instruction locations.In other words, the only job of MicroD is assigning absolute locations for the instructions andstoring appropriate stuff in the JCN fields (and for long calls, in the FF fields) of the instructionsand in the address fields of IFU words.For conditional branches, the branch condition(s) are already in FF or in JCN, so MicroD does notfix up those parts of the instruction. For Return, CoReturn, IFUJump, IM read/write, and TPCread/write, JCN is also complete.A more precise meaning for some of these bits is as follows:IsCondThe instruction at imaginary address W2 must be placed at the absolutelocation assigned to W1 xor 1.ReturnsJCN has been completely assembled by Micro; W1 and W2 are irrelevant.CallsThe next instruction in sequence must be at .+1 within the same page, and,unless Returns is also 1, the instruction W1 must be placed at a call locationin the microstore.Instruction PlacementThe discussion here describes the original design of MicroD by E. Fiala. The actual MicroD,designed and implemented by L. Deutsch, differs from this description in a number of ways. Thereis presently no description of the existing program.The "Load" pass of MicroD loads the .Dib file output by Micro into simulated memories andexecutes fixups. After loading, all addresses and all data not needed during placement computationsare flushed; after placement computation is finished, the .Dib binaries are reread, modified with theplacement information and output on the .MB output file.After loading, several passes are made over IM data as described below. During the "Link" passsimulated memory for an instruction is viewed as follows:AlcPtr20 bitsPoints at alist header (now 0)Link20 bitsPointer to next alist item (now 0) 4 bitstail of Dorado instruction14 bitsUnused 1 bitUnusedPlace 3 bits0 = W0 is the absolute address of this instruction1 = Place at a global location2 = Place at a global and place W0 at . xor 13 = IFU entry4 = Place at even location and place W0 at . xor 15 = IFU entry and place W0 at . xor 16 = Place at odd location and place W0 at . xor 17 = None of the aboveW014 bitsAbsolute addr of this instr if Place = 0Imaginary addr of instr at . xor 1 if Place indicates itReturns 1 bitJCN field fully assembled; ignore W1 and W2 fp!q4] Gfp _qN ]K[ [$B Y' VDX TyU R! O=<xK*JxF+xCEB%)%@[ <u 8qH 6': 54 1U /22 .(= ,<8 (I '9x$>sx!x2A- 2&]1x ;8x y( f V>].Dorado MicroassemblerEdward R. Fiala21 July 198057Calls 1 bitPlace next instr. at (.+1 & 77)+(. & 7700); require W1 tolie at a call location unless Returns is 1JBC 1 bitPlace W1 and W2 at a reachable JCN branch condition targetUsesFF 1 bitFF field unavailable for long goto or long callW114 bitsImaginary address of branch from this instructionBranches 1 bitDoes a BranchGoes 1 bitDoes a Goto 1 bitUnusedIsCond 1 bitHas a branch conditionW214 bitsSecond imaginary address of DBLxxx or .+1JBCT 1 bitThe target of a JCN-encoded conditional branchGoedTo 1 bitThe target of an unconditional or false conditional GotoCalled 1 bitTarget of unconditional or false conditional CalljbcLink15 bits7777 if no JCN conditional branch else 10000+imag addr"Link" then scans IM, doing the following for each word:a.AlcPtr and Link are initialized to 0.b.If W2 is relevant (= IsCond & not Returns), then W2 must be at W1 xor 1, so the W0and Place fields are set appropriately for both words, making error checks forinconsistent constraints.c.The JBCT, GoedTo, and Called bits are set in W1 as appropriate (ignored if Returnseq 1).d.The word containing W2, now disposed of, is converted into a brLink. If Returns or(not IsCond & not UsesFF), then W1 can be anywhere and no restriction ispropagated. Otherwise, W1 must be in the same page as this instruction. EitherbrLink or jbcLink is set to 10000+W1 and the other is set to 7777 (= empty).jbcLink is used when the branch target must be a reachable JCN-encoded conditionalbranch location.While propagating xor1 relationships, error checks ensure that no situations where differentinstructions must be xor1 to the same instruction occur. If such errors are detected, error messagesare output, and at the end of "Link" assembly terminates."Link" then scans simulated IFUM and, for IFU entries which have been loaded, sets the IFUEstate in Place for addresses branched to from the IFU; if NEnt is greater than 1, then Calls is set 1in the first NEnt-1 instructions of the entry vector.At the end of "Link" simulated memory is as follows:AlcPtr20 bitsPointer to the alist headerLink20 bitsPointer to next alist item 1 bitUnusedPlace 3 bitsPlacement constraintW014 bitsAbsolute address of this instruction if Place eq 0 fp!q4] Gfpx_9s4]*x\w5x[-xY(xWxUTVxRxQ#xN+xM5xL5+xJ2 Gq8xD}%xAu+':?6:=x:R:9 x6::4:7:2p6:0($:.::- )9# 'e & 9 "5& V 5 4xsx0x1x* =W^gDorado MicroassemblerEdward R. Fiala21 July 198058Returns 1 bitJCN is correct and W1 is irrelevantCalls 1 bitthe next imaginary instr must be placed at .+1JBC 1 bitA branch condition is in JCNUsesFF 1 bitFF field not available for long call or long gotoW114 bitsImaginary address of branch from this instructionState 3 bitsState of allocation list (now 0)brLink15 bitsImaginary addr of next instr in page or 7777B if emptyJBCT 1 bitTarget of branch with condition in JCNGoedTo 1 bitPlace at a goto locationCalled 1 bitPlace at a call locationjbcLink15 bitsImaginary addr of next instr in subpage or 7777B if emptyAt the end of "Link" each instruction contains a collection of flags and W0 describing restrictionson its placement, and the lists beginning at jbcLink and brLink thread through instructions on thesame subpage or same page. W1, UsesFF, and Returns indicate how the JCN (and sometimes theFF) field must be filled in for its own branch. Calls connects it to the instruction at .+1, and Callsin the preceding imaginary word may connect it to .-1.The "AList" pass of MicroD transforms data structures left by "Link" into a form more amenableto allocation. The word containing W0 and the JBCT, GoedTo, and Called bits are processed sothat the placement constraints are contained in a one-word "Mask" and in the three-bit "State"field. The jbcLink and brLink lists are transformed into circular lists as follows:a.Initially, xxLink contains 7777B (empty) or 10000+imaginary addr, interpreted as an"unmarked" pointer.b.Imaginary addr in xxLink is interpreted as a "marked" pointer (which implies thatimaginary address 7777 is unusable--sorry about that, but the allocator is unlikely tobe good enough to assemble 100% of the microstore anyway).c.During the scan of IM, if xxLink is already marked, skip it. Otherwise,d.Follow and mark the xxLinks until either 7777 (empty) or a marked link isencountered. If empty, change that to a marked pointer to the starting xxLink. If amarked pointer, splice the list just scanned in at that place, except that if the markedpointer is at the original xxLink then done (List was already circular).Next, "alists" of instructions connected by Calls or Xor1 are built. Alists have the property that theplacement of every instruction in the alist is determined unambiguously by the placement of anyother element. Alists begin at a header and thread through the Link words of IM entries in thealist. The interpretation of State is as follows:0Absolute--list contains absolutely located instructions -or-Page-relative--alist contains instructions whose low 6 bits are located1Other--placement constraint encoded in Mask (currently unused) fp!q4] Gfpx_9sx]+x\wx[/xY(xWxU-xSxQxPWxN0 KqD IQ HD FH61 D}6 A 5) ?A&7 =vA ;Tx89:(+:6ox3g:L:1@:/:x,:Hx): F:'S:&,B:$aH D# %%: ZP 2x:<:SGx:> ~ n=TPDorado MicroassemblerEdward R. Fiala21 July 1980592Xor1--two-instruction alist with instructions at an xor1 pair, legal placements encodedin Mask3Plus1--multi-instruction alist with instructions bearing a .+1 relationship topredecessors4AnyCall--one-instruction at any call location5AnyGo--one-instruction at any goto location6AnyIFUE--one-instruction at any IFU entry7Any--one-instruction arbitrarily locatedLegal alists containing arbitary combinations of Calls and Xor1 constraints are transformable into a"Plus1" list. Header locations for the alists are determined as follows:a.Absolutely-located alists have their header in the PageTab entry (see below) for theappropriate absolute page. All absolutely-located instructions in that page are on thatsingle alist.b.Page-relative alists (i.e., ones containing a Global) have header in GlobTab.c.AnyCall, AnyGo, AnyIFUE, and Any instructions which have both jbcLink andbrLink equal to 7777 (empty), are combined onto single lists. These are notconsidered to be part of any instruction cluster and are allocated at the last possiblemoment. Instructions which are only reached by long Goto/Call or IFU dispatch andwhich themselves do long Goto/Call, Return, or IFUJump wind up on these lists.d.All other alists have their headers in AlcTab.The AlcPtr word in each IM word's structure points at the alist header. This is needed forclustering instructions into pages.The "Cluster" pass of MicroD groups and sorts the alists into clusters of instructions that mustappear on the same 64-word page of the microstore. This is done in the following steps:a.Absolute clusters for pages 0-77 are collected and sorted by size.b.Global clusters are collected and sorted by size.c.Global clusters are merged into page 0-77 clusters.d.Remaining clusters are collected and sorted by size.e.Remaining clusters are merged into page 0-77 clusters.f.The page-independent AnyCall, AnyGo, AnyIFUE, and Any alists are allocated.The "seed" alist for the cluster gathering procedures is obtained as follows:a.The PageTab entry for a page contains its absolutely-located instructions.b.GlobTab entries not absorbed during (a) are seeds for global clusters.c.Take AlcTab entries not absorbed collecting other clusters in an arbitrary order. fp!q4] Gfpx_q:<:]KxZ:gN:X xVD:-xS:+xQ:)xNi:( J04 I-IxF$:P:DZX:B x?:Mx<:8::8:8E:7/#:5U#+x2L:. .5& -# )1/ 'Xx$:Bx#:1x!6:3xk:4x:6x:@ dMx\:Jx:Fx:J =VDorado MicroassemblerEdward R. Fiala21 July 198060Note: The circular jbcLink and brLink lists form a fully-connected structure, so the cluster gatheringprocess can begin with an arbitrary seed alist. The purpose of collecting the clusters in the carefulorder described above is to avoid unnecessary sorting of the clusters and avoid undesirable thrashingby the cluster-merging heuristic.As a cluster is collected, the alists composing it are aggregated into adjacent AlcTab locations, andthe single-instruction alists (probably 80% of all instructions are on single-instruction alists) arerplaca'd onto special lists for the cluster. The PageTab or ClusTab structure describing a cluster isas follows:a.Pointer to first AlcTab alist.b.Count of alists in AlcTab.c.Header for AnyCall instructions in cluster.d.Header for AnyGoto instructions in cluster.e.Header for Anywhere instructions in cluster.f.Header for absolutely-located/page-relative instructions in page/cluster.g.Count of total instructions in cluster.PageTab only:h.Count of total goto locations occupied by current allocation of page.i.Count of total call locations.j.Count of total JCN locations.k.Count of total JCN conditional branch goto locations.l.Count of total JCN conditional branch call locations.m.4-word bit table for allocation.This information is needed by the allocate-and-merge heuristic. A rough sketch of the heuristic isas follows:a.Initially, each PageTab entry contains the assorted lists described above and an emptybit table for the page.b.The alists in AlcTab are sorted into a desired allocation order (undecided how thisworks at present).c.The AlcTab alists are allocated, the bit table bits filled in, and the tentatively assignedlocation stored in brLink (which is no longer needed).d.The assorted counts are filled in by counting the ones in the bit table appropriately.To these counts are added the lengths of the Anyxx lists.e.Merges are considered in the order of decreasing size. Namely, the can-I-mergequestion is asked for the largest entry in ClusTab with the largest entry in PageTaband then successively smaller PageTab entries until the answer is "yes".f.If either the PageTab or the ClusTab entry contains only alists beginning in the Anyxxheaders (i.e., there are no AlcTab alists for the cluster), then the merge question canbe answered by considering only the assorted counts. Otherwise, the counts willprovide a certain negative answer for most situations when the merge is impossible. fp!q4] Gfp _q T ]KN [8- Y! VDA$ Ty.7 RY P yMryKyI+yH+yFH,yD}IyB'y?A y=vEy;y9y85y6K5y4 1B! /D x,<:G:*rx':N:& x#j:R:!6x: J:79x:?: I:Hxe:::S:6:> =YM$Dorado MicroassemblerEdward R. Fiala21 July 198061g.If the PageTab entry is empty (i.e., the page hasn't been used yet), then the merge isok, so the page-relative alists in the cluster are converted to absolute, the AlcTab alistsare sorted into position and the bit table and counts are filled in as above. This mayresult in an error if the cluster is too big for one page.h.If the counts indicate that a merge is probably ok, then the bit table in PageTab iscopied and an attempt is made to allocate the alists in the cluster without changingany location assignments already made for the PageTab alists. If this succeeds theclusters are merged with the cluster's AlcTab alists being appended after the onesalready in PageTab.i.If (h) fails the answer is presently assumed to be "no". (This can be improved laterby resorting the alists in PageTab and in the cluster, but maybe the heuristic will workwell enough without resorting to this time-consuming reallocation.)j.If the answer is "no" then loop to the next smaller PageTab entry.The "Allocate" pass of MicroD is carried out as follows: Each entry in PageTab now representsinstructions that will wind up on a single absolute page. AlcTab alists have already been assignedabsolute locations (assignment in brLink). Absolute locations are now assigned to the remaininginstructions on the AnyCall, AnyGoto, and Any lists for each page. Then the instructions on thepage-independent AnyCall, AnyGoto, and Any lists are allocated wherever there is space.The "Relocation" pass of MicroD rereads the .Dib binaries, checks assignments of IM words, andoutputs a .Mb file in the form expected by Midas. Memory definitions, addresses, and data for allmemories except IM and IFUM are output unchanged in the order read, except that the fakememories intended only for MicroD (RVREL, IMLOCK, VERSION, and IMLOCK) are flushed.IM addresses are also output unchanged--they are not relocated because Midas works with theunrelocated addresses.However, modified definitions for IM and IFUM are output, and MicroD builds an in-core datastructure for IM and IFUM words so that these memories can be listed on the .Dls file. To do this,it compresses Dorado instructions into the form shown below; IM address symbols are appended tothe appropriate symbol chain.MicroD fills in JCN (and sometimes FF) fields of instructions and IFUM words with absoluteinformation. In filling in JCN the rules are as follows:1.If the instruction has a branch condition in JCN, only JCN[1:4], the 4 bits selectingfrom 16 possible target addresses, are filled in by MicroD (other bits were filled byMicro.).2.If the instruction has Returns=1, no fixup is made.3.Otherwise, all bits JCN[0:7] are set by MicroD to the correct values, and for longgotos/calls FF[0:7] are also set. fp!q4] Gfpx_q:$2:]K<:[@:Y:xW:/%:UMK:S-&:Q?:OxMO:2#:K@:ICxG:B C> A!B @R >JH <W 9 +3 7B^ 5xC 39 14' 0 ,D *Z )!> 'F #F " 9xk:D:&/:x8:3x:6:! >S"Dorado MicroassemblerEdward R. Fiala21 July 198062MicroD must also zero the extraneous bits in each IFUM word.After this, representation of the IM words is as follows:Dorado instr.44 bits14 bitsunused 2 bitsunusedUndef 1 bitThis bit must be 0Emul 1 bitPrint out as an emulator instructionAbsAddr14 bitsSymLink20 bitsPointer to chain of symbolsThen:a.Memory definition blocks compatible with Midas are output for all memories on the.Mb file; the sizes expected by Midas are as follows:IM10000 words x 100-bits (IM representation given above with SymLink removed)IFUM 2000 words x 40-bitsotherpassed through MicroD unchangedb.Data blocks are output on the .Mb file for all memories. IM words are representedby the 14-bit absolute address as well as the data, so that both the imaginary andabsolute addresses are available to Midas during debugging.c.IM words are output as data blocks beginning at 0 and extending to the last imaginarylocation used by the program.d.Finally, the Micro endblock is output.Appendix 2. Recent Hardware and Assembler Changes1.The Micro "While" builtin has been added (affecting D1Lang internally but probablyuninteresting to programmers).2.The DispTable placement macro has been added, supported by the IMMask memory inMicroD.3.The StackNOUFL, StackNOUFL&+1, StackNOUFL&+2, and StackNOUFL&+3 macroshave been added to read the top stack entry without checking for a StkP=0 underflowcondition.4.The macros for restoring an ALUFM entry that has been smashed have been added; the nHliterals have been removed.5.The "Cnt-1" macro has been added to use the Cnt=0&-1 branch condition for its side effect. fp!q4] Gfp _q< [9xXs WTxSxR"xPxN# JqxH6:#.:Fk5CsBB%@[x=q: G:<-%::K;x7:,):5x3C:& .Mr2 *q25x) %2Ox# b2FxJx [2 Kx 2EZ =T3Dorado MicroassemblerEdward R. Fiala21 July 1980636."SetRMRegion" has been added so that the definition of an RM region can be in a differentfile from definitions for registers in that region.7.The BRX (fake) memory has been added for use in contexts which specify the MemBX-relativeloading of MemBase (e.g., in defining IFUM entries, MemBaseX_SC)8.The "IMReserve" and "IMUnreserve" macros have been added to prevent/allow MicroD use ofabsolute microstore locations.9.The "OnPage" and "AutoPage" macros have been added to force MicroD placement on aparticular page and to allow general placement (primarily for microcode overlays). fp!q4] Gfp _q2Yx]K3 Y2(1xX@ T2DxR O`22xMRx MN=W HELVETICA TIMESROMAN  TIMESROMAN  TIMESROMAN TIMESROMAN  TIMESROMAN  TIMESROMAN TIMESROMAN  TIMESROMAN  TIMESROMAN  TIMESROMAN  TIMESROMAN TIMESROMAN  TIMESROMANHIPPO  TIMESROMAN  TIMESROMAN  TIMESROMAN  TIMESROMANHIPPO  TIMESROMAN  | #`+328>CJPV[bgj-oGtzy $  !)/7:A FMS[`hlnu|j/@DoradoMicroAssembler.PressFiala21-Jul-80 23:11:56 PDT