The first module I decided to build for the project was the ALU, combined with the A and B registers. I found the ALU simpler to build because it doesn't hold any state.
I designed an 8-bit ALU that has 2 8-bit inputs (A and B), as well as a carry-in input and an opcode of 4 bits (therefore supporting 16 operations). It outputs an 8-bit result as well as 4 flags (N, V, C, Z).
Here is a description of the 16 supported operations:
#define ALU_ADC 0 // Add with carry, for ADC instruction#define ALU_AND 1 // Logical AND, for AND instruction#define ALU_BIT 2 // BIT instruction#define ALU_CMP 3 // CMP, for CMP instructions#define ALU_DEC 4 // Decrement B#define ALU_EOR 5 // Logical XOR, for EOR instruction#define ALU_INC 6 // Increment B#define ALU_LSR 7 // Logical Shift Right B#define ALU_ORA 8 // Logial OR, for ORA instruction#define ALU_ROL 9 // Rotate Left#define ALU_ROR 10 // Rotate Left#define ALU_SBC 11 // Subtract with carry, for SBC instruction#define ALU_PASS 12 // Passthru B. Can be used to set the N and Z flags#define ALU_ADD 13 // Add without carry, used in addressing modes#define ALU_SXT 14 // Sign extend, used in relative addressing#define ALU_ASL 15 // Arithmetic Shift Left
All of the data-related 6502 flags (i.e N, Z, V, C) are output by the ALU, so in some cases it is necessary to use the ALU_PASS op to get some flags set, even though there is not really a need for an arithmetic or logic operation. I made this design choice to keep things simple and the chip count low.
To implement the ALU I used 2 SST39SF020A Flash memory chips, that each have 18 address inputs and 8 data outputs. One Flash memory computes the low 4 bits of the result, the other one the high 4 bits. There a few control signals between both of them, to propagate the carry and other data useful for the flags. For example, the low part has a Z output that indicates if the lower 4 bits are zero, which the high part uses, in addition to its own 4-bt result, to compute the real Z flag.
Here is a picture of the completed assembly:
The controls signals and flag outputs are on top using the black connectors, and the green wires at the bottom will connect to the data bus.