% % MakeALU.red - Make an arithmatic logic unit prom for CS427 calculator. % % John Peterson % Computer Science Department % University of Utah % Date 22-Feb-83 % (c) 1983 JW Peterson. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The prom used for the calculator is an Intel 2716 type. It has 11 address % lines and eight output lines, accessed as follows: % % Output lines: % 7 6 5 4 3 2 1 0 % --+--+--+--+--+--+--+--- % |xxxxxxx|CO|d3 d2 d1 d0| % ------------------------ % V V V % | | +-------> Output Data (d3= MSB) % | +-------------> Carry/Borrow Out (1= carry/borrow) % | also Compare Out (1= A greater) % +--------------------> Not used % % The input (address lines) are allocated as follows: % % % 10 9 8 7 6 5 4 3 2 1 0 % +--+--+--+--+--+--+--+--+--+--+--- % |f1 f0|CI|a3 a2 a1 a0|b3 b2 b1 b0| % ---------------------------------- % ^ ^ ^ ^ % | | | +-----< B digit input (b3=MSB)(from Treg) % | | +-----------------< A digit input (a3=MSB)(main bus) % | +------------------------< Carry/Borrow In % +-----------------------------< Function Code: % f1 f0 Function % ------- ---------- % 0 0 Add a to b % 0 1 Subtract a from b (b-a) % 1 0 Subtract b from a (a-b) % 1 1 Compare a to b % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The prom is used with the following scheme for arithmatic. Since Trying % to subtract big numbers from little ones produces incorrect results (no % intermediate sign info) % % Input Signs % function A B Action Taken % --------- ------------- --- ---------------------------- % + + (1) ALU:= A + B; Sgn:= + % % + - (2) if A >=B then ALU:= A - B, Sgn:= + % if A < B then ALU:= B - A, Sgn:= - % Addition: % - + (3) if A > B then ALU:= A - B, Sgn:= - % if A <=B then ALU:= B - A, Sgn:= + % % - - (4) ALU:=A + B, Sgn:= - % -------------------------------------------------------------- % + + Same as (2), above. % % + - Same as (1), above. % Subtraction: % - + Same as (4), above. % % - - Same as (3), above. % % To facilitate the compare function, some tricks are used. First, the compare % works from right to left, to maintain uniformity (and possibly microcode!) % with the other functions. The carry is used to move along the previous % digit's result; so the same carry latch hardware can be used. See GenValue % (below) for the exact algorithm. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The Prom is stored as an array of 2048 bytes (chars) Fluid '(Prom); procedure initprom(); << Prom:=Make!-HalfWords(2047, 16#FF); % avoid printing out all 2k locs! NIL; >>; InitProm(); % % GetAddress- Returns the PROM address as a function of the data inputs. % procedure GetAddress(Function, CarryIn, Adigit, Bdigit); begin scalar Address; Address:=Function * 2#1000000000 + %...shift function nine bits... CarryIn * 2#100000000 + %...CarryIn eight bits... Adigit * 2#10000 + %...Adigit four bits, and... Bdigit; %...add in the B digit. return Address; end; % % GetProm- Returns the contents of the PROM as a function of the inputs % procedure GetProm(Funct, Ci, A, B); Prom[ GetAddress(Funct,Ci, A, B) ]; % % PutProm- Places the Value into the Prom at the address specified by inputs % procedure PutProm(Value, Funct, Ci, A, B); Prom[ GetAddress(Funct,Ci, A, B) ]:=Value; % % Exam- Gets the results from the prom in human-readable form (split out carry) % procedure Exam(Funct, Ci, A, B); begin scalar Value; Value:=Prom[ GetAddress(Funct,Ci, A, B) ]; if Value >= 2#10000 then << Prin2("carry=1, "); Prin2(Value-2#10000); >> else << Prin2("carry=0, "); Prin2(Value); >>; end; % % GenValue- Generates the proper value for the prom from the given inputs. % Assumes the prom is used as a sequential device (four bits at a % time), and the carry from the last digit is fed into the next % (initial carry should be 0). % procedure GenValue(Funct, CarryIn, A, B); begin scalar ALUresult; % result of op. case Funct of 2#00: % Addition: ALU:=A + B + CarryIn << ALUresult:= A + B + CarryIn; if ALUresult >= 10 then ALUresult:=remainder(ALUresult,10) + % lower part of digit... 2#10000; %..plus carry. >>; 2#01: % Subtraction: ALU:=B - A - BorrowIn (B must be larger than A) << ALUresult:= B - A - CarryIn; if ALUresult < 0 then ALUresult:=ALUresult+10 + % Add back 10 two get actual digit... 2#10000; %..and toss carry in too. >>; 2#10: % Subtraction: ALU:=A - B - BorrowIn (A must be larger than B) << ALUresult:= A - B - CarryIn; if ALUresult < 0 then ALUresult:=ALUresult+10 + % Add back 10 two get actual digit... 2#10000; %..and toss carry in too. >>; 2#11: % Compare: ALU(cmp)=1 if A > B << if A=B then if CarryIn=0 then ALUresult:=0 else ALUresult:=2#10000; % no change. if AB then ALUresult:=2#10000; >>; Otherwise: << Prin2("Bogas FUNCTION in GenValue! "); Terpri(); >>; end; % case return ALUresult; end; % % MakeProm- Fill the Prom with all the possible input values % Procedure MakeProm(); begin scalar Functs, Carry, A,B; for Functs:=2#00:2#11 do for Carry:=0:1 do for A:=0:9 do for B:=0:9 do PutProm( GenValue(Functs,Carry,A,B), Functs,Carry,A,B); end; % % DumpProm- Dump the Prom out to FileName in the specified format % (see 427 handout). % Procedure DumpProm(FileName); begin scalar Addr,i,PromAddr, % Prom address adds 400 % (toaster oddity). PromChan; prin2("Calculating contents..."); TerPri(); MakeProm(); prin2("Dumping prom..."); TerPri(); PromChan:=Open(FileName, 'OUTPUT); Addr:=0; While Addr < 2048 do << PromAddr:=Addr+16#400; ChannelPrintHex(PromChan,PromAddr/256); % High byte ChannelPrintHex(PromChan,remainder(PromAddr,256)); % low.. for i:=0:7 do << ChannelPrin2(PromChan," "); ChannelPrintHex(PromChan, Prom[Addr+i]); >>; ChannelPrintF(PromChan, "%n"); Addr:=Addr+8; >>; Close(PromChan); Prin2("Done."); TerPri(); end; % % PrintHex- Print a hex byte. % procedure HexKludge(Chan,x); % can't get chars out of PSL begin case X of 10: ChannelPrin2(Chan,"A"); 11: ChannelPrin2(Chan,"B"); 12: ChannelPrin2(Chan,"C"); 13: ChannelPrin2(Chan,"D"); 14: ChannelPrin2(Chan,"E"); 15: ChannelPrin2(Chan,"F"); end; end; Procedure ChannelPrintHex(Chan,Byte); begin scalar nybble; nybble:=Byte/16; if Nybble > 9 then HexKludge(Chan,Nybble) else ChannelPrin2(Chan,Nybble); Nybble:=Remainder(Byte,16); if Nybble > 9 then HexKludge(Chan,Nybble) else ChannelPrin2(Chan,Nybble); end;