Article 1334 of alt.sys.perq: Path: mystica!uunet!news.mathworks.com!europa.eng.gtefsd.com!howland.reston.ans.net!pipex!warwick!bsmail!siva.bris.ac.uk!ard From: ard@siva.bris.ac.uk (PDP11 Hacker .....) Newsgroups: alt.sys.perq Subject: Part 3 of the Introduction to Microcode Message-ID: <12DEC199416475552@siva.bris.ac.uk> Date: 12 Dec 94 15:47:00 GMT Sender: usenet@info.bris.ac.uk (Usenet news owner) Organization: University of Bristol Physics Department Lines: 123 News-Software: VAX/VMS VNEWS 1.41 Nntp-Posting-Host: siva.bris.ac.uk Here's part 3 of the tutuorial on POS microcode - this starts explaining conditional jumps and the like. -------------------------------------------- Microcode jumps and conditionals -------------------------------- The previous microcode examples have had a simple execution path - the instructions were simply executed in the order that they appeared. In order to write more complex (and useful) microprograms, it is necessary to use conditional jump instructions to modify this execution path. The ',next' phrase, which causes the microcode intstructions to be executed in this simple order, was mentioned in part 1 of this tutorial. It can be replaced by more complex jump phrases, including conditionals, and by using these, loops and similar structures can be built. The example chosen to illustrate this is the simple successive addition multiplier. Now, this is not the best way to multiply on a PERQ, and this program is not even the fastest way to perform successive addition, but it is easy to understand and demonstrates the necessary instructions. Here's a source listing of the microcode. !mult.micro - successive add multiplier define(mult1,330); define(mult2,331); define(acc,332); place(7000,7777); loc(7000), mult1:=tos,pop,next; mult2:=tos,pop,next; acc:=0,next; mlp: acc:=acc+mult1,next; mult2:=mult2-1,next; if neq goto(mlp); tos:=acc,push,next; nextinst(0); end; The program starts by defining the names to be used for the 3 registers needed by the program, mult1, mult2 and acc. mult1 and mult2 will be used to store the 2 input numbers, while acc operates as an accumulator to store the product. The microde itself begins at location 7000 (octal), as defined by the 'loc(7000),' phrase. The first 2 program instructions simply pop the top 2 expression stack levels into mult1 and mult2. Similar instructions have been used in previous examples, and thus they need not be expalined here. The third instruction 'acc:=0,next' should also be familiar, and simply clears the accumulator register. The next line 'mlp:....next;' introduces the concept of a label. These work just like labels in normal assembler, or in Pascal, and provide a symbolic name which can be used to refer to the instruction. The label must end in colon. Although it's conventional to start labels in column 1, and to indent all other instructions, neither of these are required. Apart from the label, the rest of the instruction should be familiar by now, and simply adds mult1 to acc. The next instruction, which decrememnts mult2, has no new phrases either. The next line, 'if neq goto (mlp);' is the conditional jump. The first thing to realise is that the conditional part of this instruction operates on the result of the previous instruction - even if there had been an ALU phrase in this instruction, the jump would still have depended on the result of mult2-1 in the previous instruction. One other thing that should be noted is that the condition codes are set on _every_ instruction - so that even if the ALU phrase had not save the result in a register, the condition codes would still be updated. Since it is impossible to have a binary instruction without some numbers in the ALU control fields, it is also impossible to have a microinstruction that does not affect the condition codes. Here, the condition is 'if neq'. This tests the previous result against 0, and passes if the nesult was non-zero. The 'goto (mlp)' jump phrase jumps to the label mlp if the condition is true, and continues with the next instruction if it is false. Thus, on each pass through the loop, mult1 is added to acc, mult2 is decremented, and the loop is repeated if mult2 has not got to 0. Thus, at the end of the loop acc contains the product of mult1 and mult2 as required. The next instruction pushes the contents of acc onto the expression stack in the usual way, and the program endes with a 'nextinst(0)' jump phrase as before. Both of these instructions have appeared in previous programs, and have thus been explained earlier. This program takes 2 numbers off the expressions stack and returns one. A suitable pascal driver to test the multiplier is given here : program mult(input,output); imports controlstore from controlstore; var microcode:microfile; x,y,z:integer; begin; reset(microcode,'mult.bin'); loadcontrolstore(microcode); close(microcode); write('Enter 2 numbers'); readln(x,y); writeln('calling microcode'); loadexpr(x); loadexpr(y); loadexpr(lor(shift(#7000,8),shift(#7000,-8))); inlinebyte(#277); {JCS instruction} storexpr(z); writeln(z); end. There are no new concepts in this program - it loads the microcode binary into the control store, gets two integers (x and y) from the user, and pushes them onto the expression stack. It then calls the microcode in the usual way, and pops the result into z. This answer is then displayed and the program terminates. These two files should be transfered to the perq (or typed in), and called mult.micro (the microcode) and mult.pas (the pascal driver). They should then be built in the usual way. This example should work on any perq - an OIO board is not required. Now execute mult.run (the result of compiling and linking the driver), and enter 2 numbers (separated by a space). The product, in decimal, should be displayed. -tony Bristol University takes no responsibility for the views expressed in this posting. They are the personal views of the user concerned.