helpline |
Andrew Hewson tackles some misconceptions
READERS will be aware that I use letters I receive as the basis for an article on a given topic rather than restricting myself to direct answers to each question posed. I use the approach principally to make the column interesting to all readers rather than the few who may share a particular problem with a particular correspondent. As a result, more than a single sentence from each letter is rarely published.
Recently I have become aware from reading a number of letters again that the questions posed are often based on a misconception of one kind or another, even to the extent that the fundamental question does not exist. It is difficult to answer such letters without publishing them more or less in full. To illustrate the point, consider the following from Larry Simpson. He writes:
I gained the impression from reading about machine code that it was an improvement on Basic partly because hex numbers were used which were more closely related to the binary system of the computer. If so, why do you recommend the use of a hex loader program whose only purpose appears to be to convert hex code back into decimal and poke it into memory?
In attempting to answer the question I feel like the man who, when asked the directions to a particular town, replied "If I were going there I wouldn't start from here". In the same way I cannot tackle Simpson's question without backtracking and correcting some of his ideas.
First, it is not correct to say that machine code is an improvement on Basic. I would prefer to say that some tasks can be undertaken by programs written in machine code which could not be undertaken by a Basic program or, if they could, they would be too slow to be satisfactory. Thus it is necessary sometimes to resort to machine language to complete a specific programming task. Writing machine code programs, however, is a skilful and time-consuming process; nobody in his right mind would choose to write a routine in machine language if a Basic routine could do the same job at an acceptable speed.
Second, the difference between Basic and machine language has little to do with the difference between hexadecimal and decimal. In Sinclair computers a Basic program is interpreted each and every time it is executed. In other words, each program line is analysed by the routines in ROM to work out the exact form of each command and then the command is executed.
A machine language program, in contrast, is not analysed at all by the ROM routines, although the program may make use of ROM routines for its own purposes; rather the form of the machine language is such that it drives the microprocessor at the heart of the computer directly.
It is as if the analytical capabilities of the ROM routines which form the Basic interpreter are a very crude imitation of those of the human brain. When a soldier on parade is given the command Forward March his brain interprets the command and despatches a complex sequence of electrical impulses to the muscles of his arms and legs which cause them to contract and relax in such a way as to drive his body forward in the required fashion. The electrical impulses form the "machine code routines" which drive his muscles.
In principle it would be possible to mimic those impulses artificially and, given sufficient surgical skill, to direct them into the soldier's spinal column so that he could be made to walk involuntarily without his brain performing its usual interpretive function.
Finally, I do not recommend the routine use of the simple loader programs which I have included in the column from time to time. Their purpose is to enable all readers to load and try the machine code routines which also appear in the column. Simpson is correct in one respect - their only function is to POKE numbers, in decimal or hexadecimal as appropriate, into locations in memory, because it is those numbers which cause the microprocessor to perform the required task.
Where can I find the addresses of the Spectrum ROM routines and can you explain how to use them? asks Michael Dobson. The most comprehensive sources of information are the books by Dr Ian Logan, The Complete Spectrum ROM Disassembly and Sinclair ZX-81 ROM Disassembly, parts A and B. The books list the entire contents of the appropriate ROM with a certain amount of information on the action of each section of code.
They are unsuitable for a beginner because a great deal of material concerning the operation of the Z-80 processor is taken for granted. Hence I would suggest that the average reader starts with one of the many introductory books on assembly language programming which usually contain information on some of the routines.
Jean-Hugues Belpois requests information on such a routine. He writes: Can you publish a routine which will print the amount of free memory remaining for use on a Spectrum?
It is not necessary for me to offer such a routine for the Spectrum because a similar one already exists in ROM at address 7962. The routine returns, via the BC register pair, the amount of ROM and RAM already in use on the 48K machine - or the amount plus 32768 on the 16K machine. Hence to use the routine on both the 16K and the 48K machine enter:
PRINT 65536 - USR 7962
The ZX-81 ROM does not contain the equivalent routine, so I have shown an alternative in table one. The routine can be loaded with the inevitable decimal loader listed in table two. To call the routine enter:
PRINT USR 16514
|
Steven Neal asks an interesting question. He writes: How can specific characters be removed from the screen on the ZX-81 while leaving the bulk of the display intact? The solution to the problem is straightforward. In essence, it is necessary to scan through the display file, testing each location to see if it contains the code of the character to be deleted. If it does, then POKE zero ix, the code for a blank - into the location. The display file lies in the area in memory between the addresses pointed to by the DFILE and VARS systems variables. Those two variables are held at 16396 and 16400 respectively. A suitable Basic program is listed in table three.
|
That type of routine can be used to tidy the ZX-81 display when successive calculations are being performed. In those situations an annoying problem can arise when the PRINT AT command is used to overwrite the result of a previous calculation with a new value, because the command does not necessarily cover the result completely. For example, if 3.333333 is overwritten by 4.5 the display will show 4.533333, which is very misleading.
Clearly a routine which deletes all numbers from the display selectively is required. The routine must also be capable of detecting and deleting a decimal point embedded in a number and the presence of a number in scientific notation, e.g., 130,000,000 which is PRINTed as 1.3 E 8. The machine code routine listed in table four performs all those functions.
|
I wrote a machine code routine to undertake the task because a Basic program would have been too slow to be satisfactory. The routine illustrates the speed of machine code; when it is used digits on the screen disappear quickly.
Unfortunately it is not possible to write an equivalent routine for the Spectrum, because the display is handled in a different fashion.
The Basic program in table five illustrates the technique. The first loop PRINTS the letters in blue INK on white PAPER and the numbers in black INK on white PAPER. The attribute value of the black/white combination is 57. Hence the second loop searches the attribute file, locating the bytes which contain 57. When such a location is found its contents are changed to 63.
|
Finally, an apology. I write the column using a word processor package on a microcomputer. Unfortunately the printing head of the printer I use does not have a greater than or a less than sign, so I add those characters by hand before the manuscript is despatched to the editor. Unfortunately I forgot to do so for the column which appeared in the August issue. Hence lines 50 and 60 of the Basic program in table three of that issue should in each case contain a greater than sign immediately before the 57.