[1]as opposed to something which is a lousy game and just sells on the strength of the multi-player novelty.
[2]Proprietary Acorn network for the BBC Micro and Archimedes.
[3]RS232C is the industry standard. RS423 on the BBC micro and RS422 on the Macintosh are both compatible with this when used with appropriately wired leads.
[4]This is a fairly optimistic estimate unless the tank is not moving and not shooting and not refueling from a base and no mines are exploding and even then processes like tree growing will be putting data onto the network.
[5]The performance now well exceeds the original hopes and it is felt that it could have far wider application than just as a medium for games, particularly in distributed database contexts.
Please note that apparent similarities with either IBM Token Ring or Cambridge Ring are superficial.
[6]Musical Instrument Digital Interface -- a 37K baud CSMA type interface for connecting electronic musical instruments (such as synthesizers and samplers) together, provided as standard on the Atari ST.
[7]A network protocol which allows a program to use different networks (including Ethernet and Token Ring) via standard, network-independent, calls to a program called the LLC (Logical Link Controller).
[8]A shell could be off the edge of the screen when it hits its target. Even the tank itself need not be on the screen if a remote pillbox view has been selected.
[9]Or, more to the point, it can move at a shallow angle, eg. one pixel to the right and 1/8 pixel up, so that after every 8 moves to the right it will move up one pixel.
[10]Only a small area of this, about 100 squares x 50 squares, is occupied by land. The rest is deep sea.
[11]A bradian is a unit of angular measure, perverted to suit the whim of these new-fangled binary machines -- there are 256 of them in a circle.
[12]This range calculation is done correctly, with R(x[2]+y[2]) which gives the pillbox a circular domain of fire, instead of a simple bounding box which would give is a square domain of fire.
[13]When this player is referred to, it means the one who is sitting in front of this machine, on which this incarnation of the program is running, driving this tank around. There is a real sense in which it is meaningful to talk about one tank being special compared to all the others, and that is the one whose data has its prime site in this machine. Of course, this special tank is different for each machine.
[14]Erased from the object list. They are not immediately erased from the screen of course, the background squares which they cover are marked for redrawing, which will erase the shells on the next screen refresh.
[15]50 times a second, after drawing each frame, the electron beam returns to the top of the screen to start the next one. During this short interval, about 3ms, the processor can do anything to the picture in the framestore without risking causing any visual anomalies on the screen.
[16]It would also be nice to get zero flicker by engineering that the `time not on screen' falls only when the electron beam is actually drawing somewhere totally different on the screen, but this is very complicated.
[17]16 different characters are drawn for each of these objects, facing in the 16 different compass directions.
[18]Only if the character has actually been drawn. If the screen has not been refreshed since the last time the character was sent to setob then it will not have even been drawn yet so there is no point in redrawing background squares to erase it.
[19]Explosions are drawn as an animation of 8 characters, which show the explosion rapidly grow and then fade away. The next character of the animation may not always be the numerically following character, since if it is a long time since the last screen refresh some intermediate characters will be omitted. Otherwise, explosions would seem to explode more slowly when the machine was busy and the foreground processes were running slower. If it is a very long time since the last screen refresh then the explosion will simply be erased since it should in fact have already faded away by now.
[20]A field is one pass of the screen from (top to bottom) by the electron beam, taking 1/50 second, and drawing 312 lines of 64us each. Usually, two such fields, interlaced, are used to make the familiar 625 line 25Hz frame. In this case the display only has 256 lines, so a single, non-interlaced, 312 line field is sufficient, and 50 different images per second can be shown, instead of the normal 25 frames per second of a UHF television picture.
[21]1/50 second to draw the screen + 1/50 second `head-start' on the electron beam = 1/25 second.
[22]In fact, the `point- to- point message' type of communication turned out to be very rare. Virtually all messages were global broadcasts telling everyone in the game what particular changes to the map (and other actions) were to be performed.
[23]ie. it simply neglects to forward received bytes to the next machine. When a machine starts transmitting, it sets a flag to prevent this forwarding of bytes. When it finishes transmitting, this flag remains set until the final byte of the packet has come all the way round the ring (possibly up to 1/15 of a second later) and the whole packet has been received. The flag is then cleared and forwarding resumes until next time.
[24]If it is not, or a receiver overrun occurs (the processor not accepting the byte before the next one arrives) then this causes a `failure' and the network recovery software is invoked -- see later. Parity checking is available too, but is not used because the extra bit would make the network about 10% slower.
[25]This interval determines the maximum amount of time for which interrupts may be disabled. At 4800 baud, or 480 characters per second, it is about 2ms. At 9600 baud it is only 1ms. This means that it is not acceptable to simply disable interrupts during some critical operation on a shared data structure (to prevent it being accessed by another process) as this would cause incoming data to be lost.
[26]Since RS232 (and its derivatives) use an asynchronous protocol, where each byte is framed by start and stop bits, the receiver at the other end is not perturbed by long paused between characters, and will simply wait until it sees the start bit of the next character arrive.
[27]This assumes that the input is itself a continuous stream with no pauses in it, as indeed it is.
[28]Strange in that it has instructions like `Draw Shell' and `Explode Mine'
[29]A memory address which is an exact multiple of &100. ie the low byte of the address is &00.
[30]On the BBC micro, when an interrupt is processed, the value of the Accumulator is placed in location &FC. If you wish to re-enable interrupts during your interrupt routine, then you must push the contents of location &FC onto the stack (because it will probably be corrupted by another interrupt), and then restore A from the stack instead of &FC at the end.
[31]Cyclic Redundancy Check -- a method of testing to see if data is corrupted. It is more robust than either parity or checksum methods because it is much less likely that two errors will cancel out each others' effects in the check data. For example, parity will detect any single bit error, but if there are two faulty bits then the parity will indicate (falsely) that the data is correct. If two bytes are somehow transposed, then a checksum will still add up to the correct sum, indicating (falsely) that the data is correct. A CRC algorithm will correctly detect both of these errors, and many more, particularly `burst errors', which are common.
[32]Developed Easter 1988
[33]It was not thought of as such originally, but I later realized that it performed an analogous function to the token in an IBM Token Ring.
[34]37 * (8*8). Each character was an 8*8 pixel square.
[35] 7us to move a byte -- just under 2us per pixel (4 two-colour pixels per byte).
[36]An important rule is that no player may make direct changes to the map. If a square is changed, then the program must not change the map data structure directly -- it must send an opcode round the network to inform all other machines of the change, and make the change itself when it receives its own packet back round the ring, just as it would if it was to receive a map change instruction in a packet sent by any other player.
[37]As well as being unacceptable from the theoretical point of view, this is likely to annoy players considerably. If you are pursuing someone and they are able to escape through a solid building through which you are unable to follow (because on their screen it happens to appear as a square of road but on yours it is a building), then this is likely to make the whole game seem rather pointless.
[38]Note that this is the normal use of the RTS/CTS handshaking lines. They cannot be used in this way in this network because the previous machine would have nowhere to put the excess data either.
[39]It does not bother to check it against the one which was sent, to make sure that no bytes have changed, because, even if they have, it is too late to do anything about it now -- it will have been received and executed by the other machines in the ring. The CRC is relied on to detect bad packets. While it is possible that the CRC check could succeed for a bad packet, there is a low probability that it will do so. Unfortunately, it is impossible for any scheme to guarantee transmission of data. However complex the checks and redundancy, there is always the small probability that with very bad luck, probability could contrive to totally alter the bytes in a packet so that another, different, valid packet is formed. Even checking what comes back round the ring cannot guarantee anything, because probability could contrive to restore the packet just before it got to you and you would never know. Since we have accepted that the best we can ever manage to do is to reduce the probability of bad packets not being detected, if we wish to do this, we may as well concentrate the effort in improving the CRC as anywhere else in the structure of the program. To provide a mechanism for countermanding a packet which has been executed by everyone would complicate the program greatly, with negligible improvement in performance.
[40]12 of the other stations will be receiving zeroes too, but will be ignoring them. The criterion to restart is to receive 20 zeroes and to have a packet which needs transmitting.
[41]New position on the screen -- because the view has moved. Of course its actual position in the World has not changed!
[42]ie. one or two network character times. This is not much better than was available before by simply disabling interrupts, but is much safer of course. If more time is required then a routine lockwhensafe may be called. This checks to see if the incoming packet is both from the preceding station in the ring, and nearly finished, in which case it blocks until the token has been received and transmission of the new packet has started.
[43]Now [1]/4 second with the network running at 9600 baud.
[44]Notice the plural `results'. Some of my routines take a pair of coordinates as parameters, and return another pair as result, often with an error condition indicated by the state of the carry flag. This allows the calling routine to use a BCS instruction to test whether the call succeeded. All this has to be done far more clumsily in C.
[45]Some C compilers now support register variables for parameters and function return types, but none that I know of on the Macintosh.
[46]A BBC micro with one page (16K) of sideways RAM is required. All BBC Masters have this RAM.
[47]About 1 minute to assemble the whole 100K of source. Assembly could be started from any module and would work upwards to module six without the need to re- assemble the lower modules. Since the bulk of the code in the bottom modules was tried tested and debugged, assembly time was more usually only 20 or 30 seconds.
[48]There are 216 of these
[49]Initially it was simple, but see "Foundations" for detail of how it was later changed.
[50]Actually two pixels, because in Mode 2 (160x256), pixels are wide and thin, so two pixels vertically make a small square dot. Otherwise, the aspect ratio of the map on the screen would have been wrong.
[51]Thanks to James Everard here for designing me an excellent map while I was spending my time working on the program. Thanks also for the graphics characters, many of which were designed by him too.
[52]Yes, 76,800 baud, 71/2K bytes per second. This is not a standard RS232C rate.
[53]This is a historical joke, from when the program was simply going to be a two-player game. Someone said, "Oh, I see, it's like MUD (Multi User Dungeon), only for two players ... er ... DUD (Dual User Dungeon)." The game became multi-user, but the filename stuck.
![]()