ASCII code nightmares? Disillusioned with disassemblers? Baffled by bytes? If you’re having problems with programming, whether they alliterate or not, Andrew Hewson is your man. Drop him a line and he’ll be investigating the problem before you can say “Ram Dos Buffer Interface Edge Connector”
A couple of letters landed on my desk last month with questions such as, ‘How do you use the ﬂoating point calculator?’ from Frode Tennebo in Norway and ‘How do you draw lines and plot in machine code?’ from Gordon Bissell of Stafford. This month I hope to answer both questions with a few practical examples including circle and plot routines in machine code.
Machine code is easy once you have learnt the basics and start to use it more frequently, like learning a foreign language in fact. The numbers we deal with are all INTEGERS and there are no complicated decimal numbers or fractions to worry about. This is great for most applications but at some point in time you will want to do something where the odd cosine or square root is required and with integers, we can’t simply round up the result and expect the calculation to work out. In a game, for example, the main character might have a single byte for each of the X and Y co-ordinates of its screen position. Each byte gives us a resolution of 1 pixel but as this is the smallest resolution of movement then it is perfectly adequate. We treat each byte as an integer and there are no problems. In fact, if we had a co-ordinate system with a resolution down to 0.001 or one-thousandth of a pixel it would just mean designing an overly-complicated routine to handle those smaller floating point numbers — hence the reason for shying away from FP.
This is the standard way of accessing the calculator:
RST 28H DEFB A2H ; Stack a half (0.5) DEFB A4H ; Stack ten (10) DEFB 04H ; Command code for multiply DEFB 38H ; Exit calculator command JUMP 2DA2H ; Exit via floating point to 'BC'
The RST instruction enters the calculator. The two bytes A2H and A4H are special commands that deposit the values 0.5 and 10 on the stack. There are 5 of these ‘special’ values:
After putting 0.5 and 10 on the stack, we tell the calculator to multiply the two items on the top of the stack with the O4H command code. Finally we exit the calculator with the code 38H. However, to be of any use to us we have to get the result into a register for further use. There is a very useful routine which performs the function ‘Floating point to BC’ at address 2DA2 hex. It rounds the floating point number and puts it into BC and the accumulator is a copy of C.
There are a couple of ways to do this. If we are using any of the 5 special values above, we just use the commands A0H to A4H. Typically we would want to be able to put in values from a register pair, say. The routine to do this is at 2D2B hex. It will place at the top of the calculator stack the value held in the BC register pair. This works like so:
; We will demonstrate 21x43 LD BC,21 CALL 2D2BH ; First we stack 21 LD BC,43 CALL 2D2BH ; Now we stack 43 RST 28H ; Enter the calculator DEFB 04H ; Multiply 21x43 DEFB 38H ; Exit the calculator JUMP 2DA2H ; Result in BC
The result here in BC should be 21 x 43 = 903.
In a calculation, it may be what is called ‘Unary’ meaning functions such as — 1/x, SQR x, SIN x, etc. The actual calculation is just acting on the ‘last value’ on the stack. These are Unary calculations.
When we perform the calculation 3 x 10, this is known as a binary operation i.e. there are two values on the stack. This use of the word binary is not to be confused with the normal Base 2 ‘1’s and ‘0’s type of binary we all know.
Finally, the calculator has 6 memories which can be used for temporary storage (as well as the calculator stack). Operations using the memories are termed ‘manipulatory’ as they do not actually calculate anything.
Although the calculator stack is not to be confused with the Z80 machine code stack, it still has to be treated like one — we use the DELETE command in the calculator which has the code 02H to tidy up the stack — a bit like the POP instruction in Z80 code.
Circles can be drawn with clever algorithms that don’t need ﬂoating point arithmetic but here I will demonstrate a relatively standard trigonometric method of drawing circles. The routine is based around an interactive solution where we only have to use the slow COSINE and SINE calculations once for the whole circle. For avid mathematicians out there, the formulae can be found on page 73 of the book Computer Graphics by John Lansdown and published by Hodder and Stoughton.
The Spectrum machine code looks like this:
Previous article in series (issue 89)
Next article in series (issue 91)