Since we're at it, we could start thinking about how to modify
the data path of the MC14500 design to run arithmetic.
I'm leaving out a few little details, like the XOR gate
needed to store the complement of RR to memory,
and the fact that not all instructions do modify
the Result Register (RR) and the Carry Flag (C).
We still have the Logic Unit (LU) from the MC14500,
but in order to build a full adder,
we have to send the output of the LU and the Carry Flag
through an XOR gate before writing the result into RR.
For logic instructions (and for some of the arithmetic instructions),
it's necessary to keep the Carry input at the XOR 0,
so we have to insert an AND gate.
Some of the arithmetic instructions might want to have the C Flag set,
like when processing the first Bit for a subtraction,
so we insert an OR gate into the output of the Carry Flag.
Like with our other ALU examples, the LU emits the propagate (P) signal,
which routes the Carry Flag from the previous Bit to the Carry of the next
Bit, when P is active.
For RR + mem, the LU is configurated as XOR.
For RR - mem, we calculate RR + /mem.
Inverting one input of a XOR gate is the same as inverting the output,
so the LU is configurated as XNOR when calculating RR - mem.
For some of the arithmetic instructions you might want to add 0 or 1 to RR.
Fortunately we already have the DIN Flag,
which is ANDed with the Bit from memory.
For loading a copy from the Carry Flag into the Result Register,
set the LU output to 0, and enable the Carry to pass through
the XOR into RR.
For loading a copy of RR into the Carry Flag, set the LU output to 0
and activate both AND gates for RR + mem, RR - mem...
so that RR is passed through, while the Bit from memory is ignored.
Of course, the processor would need to have more than 16 instructions,
and the instruction word wouldn't fit into 4 Bit anymore.
15 11 8 7 0 ------------------ |0000|Tttt|########| ------------------
An instruction word like that loads an 8 Bit literal value
into a timer (hey, it's just an example).
Except when Bit 11 is 0. Depending on Bit 8, the value
is loaded into the high or low Byte of a pointer,
which is selected by Bit 9 and Bit 10.
It's easy.
We might want to have the 16 Bits for all the counters
mapped into memory to be able to do some address calculation.
For instance:
0x10..0x1F = Pointer 1.
0x20..0x2F = Pointer 2.
0x30..0x3F = Pointer 3.
A memory read/write at 0x04..0x07 would read/write the
memory Bit selected by Pointer 1, for 0x08..0x0B it's Pointer 2,
0x0C..0x0F it's Pointer 3.
You sure noticed, that I'm suggesting to reserve 4 Bits per Pointer.
That's because we could tie the control signals for the counters/Pointers
to the address lines A0 and A1, to trigger things like
postincrement/predecrement.
The only thing we need is a "LOOP" instruction,
to run a set of instructions like
LD [A]+ ADC [B]+ STO [Q]+8 times when adding two Bytes in memory.
Maybe tied to "Flag 0" again...
The disadvantage of such a design is, that it might require
more transistors, logic gates, flipflops, whatever...
than just building a minimalistic 16 Bit CPU.
...do we really need
LD A SBC B STO QOr could we replace that with
LDC B ADC A STO Q
Hmm...
[HOME] [UP]/ [BACK] [1] [2] [3] [4] [5] [6] [7] [8] [NEXT]
(c) Dieter Mueller 2008