One of the most intriguing things you’ll frequently find yourself considering when you think about a DIY Compiler is how much effort goes even into the tiniest nooks and crannies. Once you have to find a way to address the hardware directly, you’re immediately transported back into the exciting days of the late 1950s and early 1960s when computing was a wholly DIY affair – and involved incredible amounts of effort. Fortunately the processors of today come with a fair few of these things built in.

Take, for instance, incrementing. Decimally, all that is that you add 1 to any given number:

1 + 1 = 2

2 + 1 = 3

3 + 1 = 4

and so on

But of course, as you plan your DIY Compiler, you have to transform this to digital format:

0000 0001 + 0000 0001 = 0000 0010

0000 0010 + 0000 0001 = 0000 0011

0000 0011 + 0000 0001 = 0000 0100

and so forth

So you immediately have two things to think about: carry and maximum amounts.

The carry drove Charles Babbage crazy when he came up with the Difference Engine, and you can see why here. For binary calculation, it’s a little simpler – instead of carrying when 9 gives way to 10, there are only two states. It happens much more often though. So accommodating the binary carry means you have two operations: one replacing a 0 with a 1, and one pushing a 1 further left, leaving a 0 in its wake. (Which can then be replaced with a 1 again if necessary.)

The carry, then, makes the above numerical examples rather intricate. Taking the first of the two numbers to be added as the starting point and assuming the result is computed in the first of the two index registers, we get:

MOVE LEFT for 1 + 1 = 2;

MOVE LEFT and INCREMENT for 2 + 1 = 3; and

MOVE LEFT and MOVE LEFT for 3 + 1 = 4.

The last one is interesting because it shows that MOVE LEFT is also actually two movements: moving the 1 one step further left, and placing a 0 at its origin. The first MOVE LEFT moves the rightward 1, placing a 0 there, and causes the second 1 from the right to be likewise replaced with MOVE LEFT. Et voila: a 1 with two 0s to its right.

But what if we add

1111 1111 + 0000 0001?

Obviously, the result would be

1 0000 0000.

But just as obviously, this brings us beyond the maximum amount to be stored in this index register. We could then either spill into another index register, or we could set a wraparound carry – then the equation looks as follows:

1111 1111 + 0000 0001 = 0000 0001

Both ways of dealing with this problem have their advantages and drawbacks, as usual. It looks as though our friend TYDAC, as well as the IBM 1401, mostly relied on wraparound carries.

The reason for this is that a wraparound carry allows DECREMENTs. Consinder these two equations with a wraparound carry:

0000 0100 – 0000 0001 and

0000 0100 + 1111 1110

The second index register of the last one is the *two’s complement* of the second index register of the first one. Note what happens:

0000 0100 – 0000 0001 = 0000 0011

0000 0100 + 1111 1110 = 0000 0011

Why? Because the second one is implemented as follows (right to left):

0 + 0 = 0

1 + 0 = 1 (INCREMENT)

1 + 1 = 10, so a 0 with a carry of 1 (MOVE LEFT)

1 + 1 = 10 (MOVE LEFT)

1 + 1 = 10 (MOVE LEFT)

1 + 1 = 10 (MOVE LEFT)

1 + 1 = 10 (MOVE LEFT)

1 + 1 = 10 (MOVE LEFT)

But with that last one we’ve wrapped around, and the final carry places a 1 where the initial 0 is – and so we get 0000 0011, which is of course the correct result.

What a stroke of luck it is that I can rely on this stuff already being there when I set up my Opcode!

## One thought on “Increments”