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”
Just recently, Hewson have re-released their old classic hit Technician Ted on the Rack-it budget label. That was originally written in the good old days of circa 1984. During the writing of the game, time was no problem as no-one even knew of its existence apart from the two authors. This meant that it was possible to give it the final polish that a lot of games don’t have even today. A case in point was the loading routine. When thinking up new ideas for a project, it is virtually impossible to stand poised like the statue of ‘The Thinker’ for any length of time and hope lo come up with anything.
For these who have never seen the loader, I will describe it. The screen clears and prints a couple of banners — one at the top and one at the bottom. In the bottom banner there is a countdown clock (in seconds) which decrements during the load. In the middle blank section of the screen there are 10 ‘Technician Teds’ running left and right at various speeds, also while the game is loading. Remember this was done five years ago when the best loaders of the era consisted of nothing more than a pretty picture to look at for 4 minutes (more interesting to boil an egg, eh!) Right, how is it done?
Glancing through the Spectrum disassembly of the tape loading routine (from 0556H to 0604H), there are quite a few bits of code dedicated to delays. Specifically at 05E7H there is a delay of 358 T-states every time that particular sub-routine is called. The routine is named ‘EDGE1’ in the Spectrum ROM disassembly book as its function is to count the ‘edges’ of the square wave signal from the cassette signal. Considering that Z80 instructions in normal use can range from 4 T-states to say 19 T-states then we could simply replace this delay routine with a more useful routine which did clever things like countdown clocks or Teds running round the screen. Sounds simple, doesn’t it?
This How the Hell within a How the Hell explains the normal tape signal for a better understanding of the delays talked about in the previous paragraph. Referring to figure 1, the diagram shows the electrical signal as it is saved to tape. Bit 4 of the output port 0FEH is piped through to the socket on the side of your Spectrum. To send a signal through to this socket, we send a precise ‘serial’ code as in figure 2 for saving. To turn the port ‘on’ we would do this:
LD A,0 OUT (0FE),A
To turn the port ‘off’ we would do this:
LD A,16 OUT (0FE),A
Note that the terms ‘on’ and ‘off’ are seemingly contradictory as ‘on’ has bit 4 = 0 and ‘off’ has bit 4 = 1. The terms on and off don't really mean anything more than the fact that the electrical signal at the ear socket can alternate between 5 volts and 0 volts when we send the tape signal.
The first section of the tape signal is termed the ‘leader’ and it comprises of several hundred alternations between ‘on’ and ‘off’. This is the steady tone you can hear when loading a program at the start. Figure 1 shows only a few pulses but more importantly is the timing for these pulses. Each period of the port being on or off last for 2168 T-states and so it produces a steady tone of about 1600 Hertz.
Following the leader pulses is a synchronisation pulse. This is a period of ‘off’ which lasts 667 T-states followed by an ‘on’ period of 735 T-states. Notice that figure 1 is not drawn to scale. The sync pulse is followed by the data in bit form. Suppose you had typed in SAVE "DATA" CODE 30000,10 then the routine would take the byte stored at 30000 and shift each bit leftwards until all 8 bits had been saved. The format for the saved bits takes one of two forms —
To summarise then, the signal is a few seconds of a leader tone followed by one sync pulse of considerably shorter duration than the leader tone pulses. The sync pulse is then followed by the data pulses in the respective forms. Incidentally, the term ‘baud rate’ which refers to the speed of load operation (i.e. the slower the speed the more bored you get!) is variable depending on the data. If you save all zeros then it will also load back quicker than saving all 255's. This is due to the 1 bits lasting twice as long as the 0's. So he baud rate quoted is only an average of saving an equal number of 1's and 0's.
Now the input signal is clear in your mind, remember the EDGE1 routine I spoke of earlier. In the loading routine it becomes necessary to perform lots of high speed reading of the input port and checking whether the signal has changed from one state to the other within certain critical time constraints. I say critical but there has to be a certain amount of leeway in the timing because not all tape recorders play back at precisely the same speed. There is also the effect of waw and flutter on the signal which basically means that the length of each pulse — leader, sync or data will vary quite considerably from that that was saved. Fortunately the EDGE1 routine has an overhead of 358 T-states before it starts timing the received pulses — it is this valuable time that we use in our loader. Incidentally 358 T-states is approximately 100 microseconds in duration — not exactly time to watch an epic!
Obviously it is not simple to run another routine in 100 microsecond chunks and we also have to worry about contended/uncontended RAM. The Spectrum, like most other home computers, has a problem when the screen is stored in the same memory map as the RAM used for programs and data etc. This is because the video circuitry has to access the memory without fail every 50th of a second. If the Z80 wants to read or write to the screen at the same instant as the video circuitry, the Z80 has to wait for a while until the video has done its stuff. If the Z80 had priority over the video circuitry, our picture would suffer from incredible interference so poor old Z80 suffers instead. The net result is that the processor true speed is reduced by some 25% in the video or contended memory. As the tape routines are so precise — especially during the save, they need to be replaced in ROM or in uncontended RAM.
The placement of the routine is easy — we will put our loader in uncontended RAM in a convenient location. The other difficulty is that during our 100 microsecond of activity we will be accessing the screen — for our countdown clock for example. This makes it difficult to accurately work out the exact timing so we have to resort to some field testing by varying the timing until we get the most reliable results.
Now you should understand how it all works but what else can we do with the 100 microseconds of ‘free’ time? A few thoughts sprang to mind — but I did think it would be quite a challenge to have a simple game to play while the main one was loading. A suitable candidate for this type of game is the old letter shuffle thing. They are made out of plastic and have an array of letters with one position vacant. After scrambling the letters up, the object of the game is to shuffle the letters back into the original layout. I am presently working on this task and should have the finished code in time for the next How the Hell. It will function as a normal byte loading routine but with this ‘Letter Shuffle’ game working while the loader is working. The BASIC program below is the letter shuffle so if you type it in and run it you will have an idea of what to expect next month.
|