%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Microcode for CS427 Calculator Project
% John Peterson
% 11-MAR-83
%
% This file is meant to be fed into the MakeCode.Red RLISP microcode
% assembler.
%
%
% Surprize as of 8-mar-83...functions need dummys in front of them, or
% operations in the RomVects
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Properties for OpList. RomVal determines the Rom and the bit in that Rom
% each control line has. Inverted contains the logic (Pos/Neg) for each line
(DefPin IncStk (Rom1 . 2#10000000)) % Increment stack on NEXT cycle
(Invert IncStk)
(DefPin DecStk (Rom2 . 2#1)) % Decrement stack on NEXT cycle
(Invert DecStk)
(DefPin SgnEna (Rom2 . 2#10)) % Enable the sign
(DefPin LoadStk (Rom2 . 2#100)) % Load the stack
(DefPin BusEna0 (Rom2 . 2#1000)) % Buss enable bit 0
(DefPin BusEna1 (Rom2 . 2#10000)) % Buss enable bit 1
(DefPin LoadTreg (Rom2 . 2#100000)) % Load the Treg
(DefPin IncLB (Rom2 . 2#1000000)) % Increment the lower bits reg
(Invert IncLb)
(DefPin DecLB (Rom2 . 2#10000000)) % Decrement the lower bits reg
(Invert DecLB)
(DefPin TOSsel (Rom3 . 2#1)) % Select TOS if 0, BOS if 1
(Invert TOSsel)
(DefPin ClrLB (Rom3 . 2#10)) % Clear the lower bits and god knows what else
(DefPin ClrTreg (Rom3 . 2#100)) % Clear the T Register
(DefPin ClrBTOS (Rom3 . 2#1000)) % Clear the B/TOS register
(DefPin CarryJmp (Rom3 . 2#10000)) % Gate Carry bit into next state
(Invert CarryJmp)
(DefPin ALUf1 (Rom3 . 2#100000)) % ALU function bit 1
(DefPin ALUf0 (Rom3 . 2#1000000)) % ALU function bit 0
(DefPin Select (Rom3 . 2#10000000)) % Select LoadALU, KeyJmp functions
%
% Macros
%
(DefMacro ReadStk ()) % Gate the Stack onto the bus
(DefMacro ReadTreg (BusEna1)) % Gate T register onto the bus
(DefMacro ReadALU (BusEna0 BusEna1)) % Gate the ALU onto the bus
(DefMacro ReadKbd (BusEna0)) % Gate the keyboard onto the bus
(DefMacro ALUadd ()) % Add Treg and stack (00)
(DefMacro ALUsubBus (ALUf0)) % Subtract Bus from Treg (01)
(DefMacro ALUsubTreg (ALUf1)) % Subtract Treg from Bus (10)
(DefMacro ALUcomp (ALUf1 ALUf0)) % compare Treg to bus (11)
% Gate Key and function into next state (requires Select)
(DefMacro KeyJmp (Select ClrTreg))
(DefMacro LoadALU (Select ClrBTOS)) % Load data from bus into ALU
%
%
% Jumps to 'Sanity' upon master clear & one clock pulse. All other non-vector
% code is relative to here.
%
(Location Sanity 00 (ClrTreg ClrBTOS ClrLB)) % Init registers
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is the return point for all functions. It remains in this idle
% loop until until the ReadKbd sends it off to a function.
%
(Label TopLoop PC)
(NEXT ()) % Branch around null keyboard vector
%
% The combination of ReadKbd, ALUF0 and F1 serves as a keyboard acknowledge.
% ClrLB is issued to reset some things.
%
(Next (ReadKbd ALUf1 ALUf0 ClrLB)) %%%% This serves as a keyboard ack
(label DispLoop PC)
%
(Next (ReadStk IncLB)) % Read digit 0
(Next (ReadStk IncLB)) % move to digit one
(next (ReadStk IncLB)) % ..digit two
(Next (ReadStk IncLB)) % digit three
(Next (SgnEna ReadStk)) % The sign bit
(Next (ReadKbd KeyJmp)) % Do jump
(Jmp DispLoop (ReadStk)) % loop if no jmp taken.
%
% Possible functions follow.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% Clear the X register %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(Label ClearX PC) % Clear the X register
(Next ()) % dummy
(Next (ClrLB ClrTreg SgnEna ReadTreg LoadStk)) % Bop LB and Treg, clear sign
(Next (LoadStk IncLB ReadTreg)) % Wipe out succesive stack locations.
(Next (LoadStk IncLB ReadTreg))
(Next (LoadStk IncLB ReadTreg))
(Next (LoadStk ReadTreg))
(JMP TopLoop (ClrLB)) % also blitz the LB just to make sure...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% Enter a digit %%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(Label Digit PC) % handle digit entry
(Next ()) % dummy (sigh)
(Next (DecLB)) % Need to backstep twice, so we're pointing at digit
(Next (DecLB)) % two (third one over)
(Next (LoadTreg ReadStk IncLB)) % Treg <- Stack
(Next (LoadStk ReadTreg DecLB)) % Stack+1 <-Treg
(Next (DecLB)) % Move back to one below above
(Next (LoadTreg ReadStk IncLB)) % Treg <- Stack
(Next (LoadStk ReadTreg DecLB)) % Stack+1 <-Treg
(Next (DecLB)) % Move back to one below above
(Next (LoadTreg ReadStk IncLB)) % Treg <- Stack
(Next (LoadStk ReadTreg DecLB)) % Stack+1 <-Treg
(Jmp TopLoop (LoadStk ReadKbd)) % Stack<-Kbd
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%% Change the sign %%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(Label ChangeSign PC)
(Next (ReadStk SgnEna LoadTreg)) % Hardware compliments from Stack to Treg...
(Jmp TopLoop (LoadStk SgnEna ReadTreg)) % Write it back to the stack
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% Enter a number on the stack %%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(Label Enter PC) % Enter (& push) stack
(Next ())
(Next (LoadTreg ReadStk IncStk)) % Stack to Treg
(Next (LoadStk ReadTreg DecStk IncLB)) % Treg to Stack-1, next digit
(Next (LoadTreg ReadStk IncStk)) % Stack to Treg
(Next (LoadStk ReadTreg DecStk IncLB)) % Treg to Stack-1, next digit
(Next (LoadTreg ReadStk IncStk)) % Stack to Treg
(Next (LoadStk ReadTreg DecStk IncLB)) % Treg to Stack-1, next digit
(Next (LoadTreg ReadStk IncStk)) % Stack to Treg
%
% To copy the sign, it has to be complimented, since the harware reverses
% the sign.
%
(Next (LoadStk ReadTreg DecStk IncLB)) % Copy last, wrap LB back to sign
(Next (LoadTreg SgnEna IncStk ReadStk)) %copy sign; gets inverted
(Jmp ChangeSign (LoadStk ReadTreg SgnEna)) % get invert sign, then comp again
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ARITHMATIC FUNCTIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is the exit point for all arithmatic functions. It copies down the
% Top of Stack (TOS) element.
%
(Label AddSubExit PC)
(Next (LoadTreg ReadStk TOSsel DecStk ClrLB)) % Treg <-- TOS
(Next (ReadTreg LoadStk TOSsel IncStk IncLB)) % Tos -1 <--Treg
(Next (LoadTreg ReadStk TOSsel DecStk)) % Treg <-- TOS
(Next (ReadTreg LoadStk TOSsel IncStk IncLB)) % Tos -1 <--Treg
(Next (LoadTreg ReadStk TOSsel DecStk)) % Treg <-- TOS
(Next (ReadTreg LoadStk TOSsel IncStk IncLB)) % Tos -1 <--Treg
(Next (LoadTreg ReadStk TOSsel DecStk)) % Treg <-- TOS
(Jmp TopLoop (ReadTreg LoadStk TOSsel)) % Tos -1 <--Treg, TOS=TOS-1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Result:=A + B, Add two numbers.
%
(Label AplusB PC) % zap carry
(Next (LoadTreg ReadStk IncStk ClrLB)) % Treg<--(BOS), move to BOS+1
(Next (LoadALU ReadStk ALUadd DecStk)) % ALU<--(BOS+1), move back to BOS
(Next (ReadALU LoadStk IncLB)) % (BOS)<--ALU, Next Digit.
(Next (LoadTreg ReadStk IncStk)) % Treg<--(BOS), move to BOS+1
(Next (LoadALU ReadStk ALUadd DecStk)) % ALU<--(BOS+1), move back to BOS
(Next (ReadALU LoadStk IncLB)) % (BOS)<--ALU, Next Digit.
(Next (LoadTreg ReadStk IncStk)) % Treg<--(BOS), move to BOS+1
(Next (LoadALU ReadStk ALUadd DecStk)) % ALU<--(BOS+1), move back to BOS
(Next (ReadALU LoadStk IncLB)) % (BOS)<--ALU, Next Digit.
(Next (LoadTreg ReadStk IncStk)) % Treg<--(BOS), move to BOS+1
(Next (LoadALU ReadStk ALUadd DecStk)) % ALU<--(BOS+1), move back to BOS
(Jmp AddSubExit (ReadALU LoadStk IncLB)) % (BOS)<--ALU, Next Digit, finish
%
% Result:=B - A
%
(Label BminusA PC)
(Next (ClrLB)) % Zap carry again...
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubBus DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubBus DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubBus DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubBus DecStk)) % Subtract to Y, jmp
(Jmp AddSubExit (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
%
% Result:= A - B
%
(Label AminusB PC)
(Next (ClrLB)) % Zap carry again...
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubTreg DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubTreg DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubTreg DecStk)) % Subtract to Y
(Next (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUsubTreg DecStk)) % Subtract to Y, jmp
(Jmp AddSubExit (LoadStk ReadALU IncLB)) % Replace into stack, on to Y
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% What follows are the four "cases" outlined in the notebook
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Case 1: Result:=A + B, Sign Plus
%
(Label Case1 PC) % (also zap carry)
(Jmp AplusB (ClrTreg SgnEna LoadStk ReadTreg ClrLB)) % clear the sign and add.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Case2: if A >= B then ALU:=A - B, Sgn:=+
% if A < B then ALU:= B - A, Sgn:=- Assume we're pointing at X
%
% if B is smaller we'll arrive here to set sign to plus...
(Label AminusBsignPlus PC)
(Jmp AminusB (ClrTreg SgnEna LoadStk ReadTreg ClrLB))
%
(Label Case2 PC)
(Next (ClrLB)) % Zap ALU carry
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB CarryJmp)) % Compare to Y, tst res
(CarryVect AminusBsignPlus (ClrTreg SgnEna LoadStk ReadTreg ClrLB)) % Jmp if A is bigger, want sign minus
% If A is smaller then set sign to minus
(Next (ClrTreg SgnEna LoadStk ReadTreg)) %...First set it to 0 (positive)
(Next (ReadStk LoadTreg SgnEna)) % then load the treg to comp
(Jmp BminusA (ReadTreg LoadStk SgnEna ClrLB)) % then write back and jmp
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Case 3: if A > B then result:=A - B, Sign:= -
% if B <= A then result:=B - A, Sign:= +
%
(Label AminusBsignMinus PC)
(Next (LoadStk SgnEna ReadTreg ClrTreg)) % clear the sign
(Next (LoadTreg SgnEna ReadStk)) % put minus in treg
(Jmp BminusA (LoadStk SgnEna ReadTreg ClrLB)) % put comp'ed treg into stack
%
(Label Case3 PC)
(Next (ClrLB)) % Zap ALU carry
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB)) % Compare to Y
(Next (LoadTreg ReadStk IncStk)) % Load the Treg with X
(Next (LoadALU ReadStk ALUcomp DecStk IncLB CarryJmp)) % Compare to Y, tst res
% if A is larger, then jmp else..
(CarryVect AminusBsignMinus (LoadStk SgnEna ReadTreg ClrTreg))
% B is larger, so set sign to plus
(jmp BminusA (LoadStk SgnEna ReadTreg ClrTreg ClrLB)) % Set sign to zero
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Case 4: res:=A + B, Sign minus
%
(Label Case4 PC)
(Next (LoadStk SgnEna ReadTreg ClrTreg)) % clear the sign
(Next (LoadTreg SgnEna ReadStk)) % put minus in treg
(Jmp AplusB (LoadStk SgnEna ReadTreg ClrLB)) % put comp'ed treg into stack
%
% The actual addition function
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Real Addition %%%%%%%%%%%%%%%%%%%
(Label AddXnegitive PC)
(Next (SgnEna ALUcomp LoadALU CarryJmp DecStk)) %Test sign of Y (but dec to x)
(CarryVect Case4 (ReadStk)) % X neg but Y pos
(jmp Case3 (ReadStk)) %
%
%
(Label Add PC)
(Next (ClrTreg ClrLB DecStk)) % make way for treg compare, reset carry to ALU
(Next (SgnEna ALUcomp LoadALU IncStk CarryJmp)) %test Sign of X register; move to Y
(CarryVect AddXnegitive (ClrLB SgnEna ALUcomp LoadALU CarryJmp DecStk))
(Next ()) % Pray for subtraction
(Next ())
(Next (SgnEna ALUcomp LoadALU ReadStk ClrLB CarryJmp DecStk))
% Test sign of Y register
(CarryVect Case2 (ReadStk ClrLB)) % X was cool but Y wasn't
(jmp Case1 (ReadStk))
%
% These Vectors catch a digit pressed, and head for the Digit u-code routine
%
(RomVect 2#0010000000 Digit (ReadStk)) % digit pressed (ignore 8 possible)
(RomVect 2#0010010000 Digit (ReadStk)) % digit pressed (kinds of bus junk)
(RomVect 2#0010100000 Digit (ReadStk)) % digit pressed
(RomVect 2#0010110000 Digit (ReadStk)) % digit pressed
(RomVect 2#0011000000 Digit (ReadStk)) % digit pressed
(RomVect 2#0011010000 Digit (ReadStk)) % digit pressed
(RomVect 2#0011100000 Digit (ReadStk)) % digit pressed
(RomVect 2#0011110000 Digit (ReadStk)) % digit pressed
%
% These functions catch the functions and head for the right one.
%
(RomVect 2#0100000000 TopLoop (ReadStk)) %function pressed (ignore 8 possible)
(RomVect 2#0100010000 TopLoop (ReadStk)) %function pressed (kinds of bus junk)
(RomVect 2#0100100000 Add (ReadStk ClrTreg ClrLB DecStk)) % Add key
(RomVect 2#0100110000 TopLoop (ReadStk)) % function pressed
(RomVect 2#0101000000 ClearX (ReadStk)) % CLX key
(RomVect 2#0101010000 ChangeSign (ReadStk SgnEna LoadTreg)) % Change the sign
(RomVect 2#0101100000 TopLoop (ReadStk DecStk)) % Goofy roll
(RomVect 2#0101110000 Enter (ReadStk)) % Enter into stack
% Also have vectors in case the carry inputs are crazy. Note this
% Assumes the keyboard inputs are quite, which is OK since MasterClear
% should zap them anyway.
(RomVect 2#1000000000 Sanity ())