
This time, right to business! We are studying the math instructions which are listed in chart 4. This is where it starts getting a little more difficult, but not so that you can’t handle it. Up to this point, most of the lessons have been peripheral background needed to make sense out of the rest of the discussion.
We only have two math functions available to us: Addition and Subtraction. As with Ld, this is not as limited as it first sounds. A study of Math Theory would teach you that all math functions are performed with addition. I’ll not try to explain this further as it would fill a volume larger than all TDM’s published to date. The point we need to understand and absorb is that multiplication is performed by repetitive additions. Likewise, division can be achieved by repetitive subtraction.
It is important that this makes sense to you. Think about the multiplication problem of 12X6. It can be solved by either of the following:
12
12
12 12
x 6 12
72 12
+12
72
Can you see how we can solve division problems by repetitive subtraction? If we had the problem 72/12, how many times can we subtract 12 from 72? Is there a remainder? Simple, isn’t it?
This brings us to the first instruction…Add. We have already seen Add in operation, in Lesson 2, and probably have a good idea of its function. Trust me, it performs addition. Some of the later instructions will not be so obvious. We would read the instruction, Add A,E, as “add the value in the E register to the value in the A register and store the result in the A register”.
In lesson 3, we learned that the A register is called the “Accumulator”. The A register is the only register that can “accumulate” the results of eight bit arithmetic. If we had wanted the result in the E register, we would need to assign it. Can you guess the needed instruction? You get an “A” if you said Ld A,E. Otherwise, go back to lesson 3.
We also have available the instruction, Sub. The A register performs a special purpose here also. The A register is the only register we can subtract from. As with Add, the A register accumulates the result. You may see this instruction written as Sub A,C or Sub C. They mean the same thing. We will use Sub C as the A register is always implied in eight bit arithmetic.
I have mentioned several times that the A register will accumulate the results of eight bit arithmetic. We need to leave the instructions for some more background.
We have already learned that a single register may only contain a value in the range 0-255. There is a condition known as an “overflow” which occurs when these values are exceeded. The simplest way to describe overflow is by example. Let’s assume we are adding 255+1. We have not discussed number systems yet (that’s a later lesson) but let’s show our example in binary as it will demonstrate the point dramatically:
Decimal Binary
255 11111111
+ 1 + 1
256 1 00000000
Look closely at the binary example. Each digit represents a bit of the A register (or any other eight bit location). Assume for now that my answer is correct, and you will note that we are now trying to place a nine bit number into an eight bit hole! The answer returned in this case would be 0, instead of the expected answer of 256. Our example shows an eight bit overflow, but can you see how we overflow a register pair (sixteen bits)?
Our friend, the CPU, has a special register, F, which we learned stands for Flag. It is called this because its job is to keep track of various things for the CPU. This is accomplished by the setting or re-setting of a bit of the F register. Setting a bit makes it a 1, and re-setting it makes it a 0. We will discuss this in some detail at a later time.
The bits are referred to as flags due to the fact that they indicate wether or not a certain condition exists. The flag we are now interested in, is the Carry flag. We will also discuss the F register later, therefore, we only need to consider the Carry flag now.
In the above example, we found we would receive an answer of 0. The ninth digit is not lost, as it is placed in the F register as the carry flag. In other words, the Carry flag takes on the value (either 1 or 0) of the overflow from out arithmetic operation. We will soon wee why we would want to save the carry.
Back to the math instructions. We have available the instruction ADC which is read add with carry. To see the difference, another example:
Add A,E means Let A=A+E
ADC A,E means Let A=A+E+Carry (keeping in
mind that the carry will again
be set or reset by the result)
ADC will allow us to chain together the needed additions to guarantee the correct result. Some of the same results can be achieved with the register pair instructions, however, there can still be overflows. Study the following to see what I mean:
Ld HL,0040h Ld H,00h
Ld BC,7FFFh Ld L,40h
Add HL,BC Ld B,FFh
Ld B,H Ld c,7fh
Ld C,L Ld A,L
Ret Add A,C
Ld L,A
Ld A,H
ADC A,B
Ld B,A
Ld C,L
Ret
Both of these routines will do the same job. Which makes more sense? Uses less memory? Executes faster? The point is that there are many ways to get the job done and many considerations to why we should choose one over another.
We also have SBC or subtract with carry. This one is special because it is the only way to perform sixteen bit subtraction. We cannot Sub HL,BC. We must SBC HL,BC which implies we know the status of the carry flag. We may not know what’s on carry’s mind, but we can clear the carry flag prior to performing a SBC by doing an addition, that we know will not generate a carry. One that will work in all cases is Add A,0. The value of A is unchanged and the carry flag is reset (0) or cleared as there is no overflow. We will find other ways to clear carry, soon.
We need to be aware that HL acts as the accumulator for sixteen bit arithmetic operations. HL has much the same favorite status with the CPU as does A. The reason we need an eight and a sixteen bit accumulator is that we cannot add or subtract registers from register pairs and vice versa. In other words, we cannot Add HL,A.
The last instructions for this lesson are special cases of Add and Sub. They are Inc and Dec which are short for increment and decrement. Each will Inc or Dec by one. For example:
Inc HL means Let HL=HL+1 Dec HL means Let HL=HL-1
Armed with these new instructions, see if you can rewrite the addition routine we had in lesson 2, to avoid the overflow error it contains. Make sure the last instruction is a Ret and use PRINT USR address to run it and return the answer to BASIC. See if you can write a similar routine to perform subtraction.
A final note on the charts I am providing. This is the last time I will include the abbreviations comments. Also, you can usually substitue IX or IY for HL and (IX+d) or (IY+d) for (HL). Therefore, I will not include them in the charts.
Until next time…happy computin’.
Chart 4
Registers ! Register Pairs
-------------------!------------------
Add A,r ! Add HL,rr
Add A,n ! Add HL,SP
Add A,(HL) ! Add IX,rr
Add A,(IX+d) ! Add IX,SP
Add A,(IY+d) ! Add IY,rr
! Add IY,SP
ADC A,r !
ADC A,n ! ADC HL,rr
ADC A,(HL) ! ADC HL,SP
!
Sub r ! SBC HL,rr
Sub n ! SBC HL,SP
Sub (HL) !
! Inc rr
SBC A,r ! Inc SP
SBC A,n !
SBC A,(HL) ! Dec rr
! Dec Sp
Inc r !
Inc (HL) !
!
Dec r !
Dec (HL) !
Where: r =any single register
rr =any register pair
n =any numeric constant 0-255
nn =any numeric constant 0-65535
d =any displacement 0-255
pq =any address