TITLE[D1Alu.mc...April 2, 1980 9:47 AM...Taft];

%This file defines ALU operations for the program. Definitions for all
possible ALU operations are given here with one line/definition.

The lines for the 20 operations enabled should have the "n" replaced by
consecutive values from 0 to 17. 16 should be "NOT A" for the shifter and
17 is normally used as a variable by BitBlt, but can be used otherwise,
if desired. Other lines should be commented out. The definitions here are
the ones used by all the standard emulators (Alto, Mesa, Lisp, Smalltalk),
except that ALUF[17] = "2A" is used only by the Alto emulator and may be
redefined in other emulators.

Note that the letter "E" added as an argument where noted below converts
the operation to emulator-only. This is intended for locations used as
variables by BitBlt, which must restore the smashed ALUFM locations to
the proper value before exit. In the standard emulators, BitBlt uses
ALUF[15] and ALUF[17] as variables, but saves and restores their former
contents.

The "A" and "B" operations must both be defined because many macros
optionally route using either A or B for RB, T, MD, and Q (B path is
preferred). Since ALUF[0] is the default for microinstructions, it should
contain a non-arithmetic operation to preserve CARRY and OVERFLOW branch
conditions.

Also, when running Midas the "B" operation is stored in ALUFM 0 and the
NOT A operation in ALUFM 16, so these should be loaded the same way
by the microprogram to avoid confusion, unless there is some good reason
to do otherwise.

Note that an important choice must be made between the arithmetic and
logical versions of ALU←A. The arithmetic version allows XORCARRY with
ALU←A but smashes OVERFLOW and CARRY branch conditions on ALU←A.
The standard emulators use the arithmetic ALU←A.
%

ABOPB[PD←,,0,25];
*ALU←B (use n=0)
ABOPA[PD←,,1,0];
*ALU←A
*(arithmetic--so XORCARRY ok. Requires no more
*time than boolean "A" in absence of carryin)
*ABOPA[PD←,,n,37];
*ALU←A (logical, so XORCARRY illegal but OVERFLOW
*and CARRY branch conditions not smashed).

*"NOT B" and "NOT A" must be both defined also.
ABOPB[NOT,,14,13];
*NOT B
ABOPA[NOT,,16,1];
*NOT A (use n=16 for shifter)

*Operations of no args (4th arg = letter E makes emulator-only)
ZALUOP[A0,11,31];
*A0 [= all zeroes]
*ZALUOP[A1,n,7];
*A1 [= all ones]

*Arithmetic operations of two args [do not accept "slow" (external)
*B sources] (5th arg = letter E makes emulator-only)
SALUOP[,+,,2,,14];
*A+B
SALUOP[,+,+1,3,,214];
*A+B+1
SALUOP[,-,,4,,222];
*A-B
SALUOP[,-,-1,5,,22];
*A-B-1

*Boolean operations of two args (5th arg = letter E makes emulator-only)
**Note how synonyms are defined for # (XOR) and = (XNOR, EQV)
ALUOP[,AND,,6,,35];
*A AND B
ALUOP[,OR,,7,,27];
*A OR B
ALUOP[,#,,10,,23];
XALUOP[,XOR,,10];*A # B (A XOR B)
*ALUOP[,=,,n,,15];
XALUOP[,XNOR,,n];XALUOP[,EQV,,n];
ALUOP[,AND NOT,,15,E,33];
*A AND NOT B [= A AND (NOT B)]
*ALUOP[,OR NOT,,n,,17];
*A OR NOT B [= A OR (NOT B)]
*ALUOP[NOT,AND,,n,,21];
*NOT A AND B [= (NOT A) AND B]
*ALUOP[NOT,OR,,n,,5];
*NOT A OR B [= (NOT A) OR B]
*ALUOP[NOT,AND NOT,,n,,11];
*NOT A AND NOT B [= (NOT A) AND (NOT B)]
*ALUOP[NOT,OR NOT,,n,,3];
*NOT A OR NOT B [= (NOT A) OR (NOT B)]

*Operations of one arg (5th arg = letter E makes emulator-only)
AOP[2,,17,6,E];
*2A -- defined in Alto emulator only
*AOP[2,+1,n,206];
*2A+1
AOP[,+1,12,200];
*A+1
AOP[,-1,13,36];
*A-1