The Atari 2600 is a difficult machine to program, but the 6502 assembly language in which this programming is done is relatively easy to understand. Nonetheless, there are certain features of this language that I still don't completely understand. One of these is the indexed indirect mode that I taked about in a previous entry, but this is not a particularly useful feature. The other issue for me is two's complement binary arithmetic which I view as a necessary evil. Two's complement is not specific to the 6502, but this is the only context that I regularly come in direct contact with it. I undertand the principles behind the notation, but something always seems to go wrong when I attempt to put it into practice.
Two's complement notation allows you to represent numbers in the range 0->255 or -128 to +127. The numbers 0->127 are represented the same way in both schemes. Similarly, if you only need to deal with positive numbers then there is no real difficulty. However, negative numbers get a bit more tricky! In this case, the upper bit of the number represents the sign, e.g. 0xxxxxxx is a positive number and 1xxxxxxx is a negative number. You might think that -1 would simply be represented as 10000001, but this is not how things are done as there would be two zero values (+0 and -0). Instead, to convert a number into its negation you invert the bits and add 1, so -1 becomes 11111111, which is 255 in the normal way. This scheme is very clever as it does not require any extra hardware to cope with negative numbers, but can be a pain from a programming perspective.
The problem that I have with two's complement is that you have to be very aware of the ranges of your numbers or nasty things will happen, e.g. 130-5 can give you unexpected results if you are not careful! Also, if you try to mix numbers of both kinds, or do signed comparisons on unsigned numbers then you are likely to end up with a headache. In the past, I have usually avoided these problems by sticking to positive numbers, but in my Juno First project the complexities of two's complement have been unavoidable. In particular, the speed of the spaceship is represented as a number from -16->16, and the coordinates of the aliens are represented as numbers from 0->255 which wrap around. I have spent the last week trying to get the aliens to move forward and backwards properly. This has been significantly complicated by the fact that the aliens move at different speeds depending on where they are on the screen, i.e. aliens in the distance move slower than those in the foreground.
The results of my efforts are attached to this message. The aliens are stationary (for now), but move forward and backward according to the movement of the spaceship. In Juno First, the top of the screen acts as a kind of scanner which shows the aliens far in the distance. If you move backwards, then these aliens appear from behind, i.e. the play area wraps around. The movement of the aliens is slighly jerky, but I hope that the illusion of perspective is there. Let me know if you think this looks OK, or if this could be done in a better way, also let me know if the flicker is acceptable (using the phosphor option on Z26 or stella helps a lot).
The code for the alien movement is not yet complete. In particular, if you change direction some of the sprites will disappear for a bit until the flickersort code moves them back into the right order. I haven't yet figured out completely how to avoid this, but I think that it can be addressed using a circular buffer. I am still using a sprite index in this version, but I have implemented Manuel's cool suggestion, where the index values are the same as their positions within the index. Thanks for all the other suggestions - I still haven't completely decided on the final solution. However, the flickersort and index creation are now done by the same code which saves a lot of cycles. I realised that the values in the index were precisely those that were not swapped during the flicker sort routine
The game is still coming along nicely, but I really could use some extra memory! There are now just four main parts of that have to be done in the core before the game will become playable:
- Finish the sprite sorting/disappearing issue, so that the sprites are always drawn in the correct order.
- Implement collision detection, so that the aliens can be destroyed.
- Implement procedural movements for the aliens, so that each type of alien moves in a different way.
- Figure out how to spawn new aliens, so that they appear in the correct place at the right time.
After various comments yesterday about jerky sprites I went back and looked at the alien movement code. A bit of searching revealed an implicit assumption that the sprite positions were in a strictly increasing order, though this is not always the case when using flickersort. I have now removed this assumption and posted the new version below. Unfortunately this change is rather computationally expensive, so there are less sprites on the screen. However, I hope that this now removes most of the jerkiness from the sprite movements? If so, then I will work on optimising this solution.