Debunking Oh that would be very difficult – part 5
Goodness dear reader, a new post from the author without any preamble regarding Brexit or his current living arrangements and it actually talks about a C64 program for a change! Perhaps this was a new year’s resolution for him?
This post is based round a comment I received eleven months ago from someone called Mark. It demonstrates […] collision detection and moving a sprite after the collision in the awful Commodore BASIC V2. Nothing like this appeared in any official Commodore manuals for the C64.
We’ve noted this on previous occasions dear reader, but this isn’t something exclusive to the C64 because there is, for example, nothing at all about hardware sprites in the Atari 8-bit manual and no support for said feature from BASIC past the POKE command.
I must apologise for taking so long to make another post, but I‘m now dealing with a lot of complicated programming techniques on the C64, to try and reveal how some people managed to program it!
People “managed to program” the C64 by learning how to program it and there are no incantations or arcane rituals involved so anyone willing to put the required effort in could and indeed can pick the relevant knowledge up without needing to sacrifice the family goat. The author wasn’t willing to do so (regardless of the goat) but there are tens of thousands of programs archived online by amateur developers who managed it quite happily that more than counter his personal perspective on the subject regardless of what his ego may feel is the case.
I actually remember looking up all the memory locations used with the PEEK and POKE commands in this listing, then writing a very detailed summary trying to explain what was going on. Unfortunately, that text file is absolutely nowhere to be found now. I‘ve looked for it on several Linux partitions, a Windows partition on both my laptops, as well as in drafts folders for all my email addresses and I just can‘t find it, so I‘ve had to start again from scratch!
Despite the author’s inability to keep his own affairs in order, the sprite to sprite collision register isn’t really rocket science to use dear reader; each of the eight hardware sprites is represented by one bit in the register’s byte so testing the state of that bit tells the program if the relevant sprite has been involved in a collision. The same is true of the sprite to background collisions and indeed several other sprite registers.
It turned out [the author’s father] didn‘t even know about RAM and neither did I. What I mean is that I later made the very depressing discovery that although the Commodore 64 had 64K of RAM chips inside it, there was no easy way of using all this RAM, and no way I could find out of how to use it.
The C64’s full memory is available from assembly language and information regarding that utilisation was readily available for anybody who actually bothered to look. Every program your correspondent has posted under the C64CD label is disabling the ROMs even though the vast majority of those releases don’t use any of that space.
This information was actually on the startup screen which included the message “38911 BASIC BYTES FREE”. As 1K=1024 bytes, this means just under 38K! The ZX Sinclair Spectrum 48K has about 40K free to BASIC.
Let’s pause to add a little more context that the author seems to have “neglected”; the C64 is being kept honest by it’s power up message yes, but the Atari 800XL or 65XE also have 64K of memory but only serve up 37,902 bytes for BASIC programs, almost an entire 1K less than what the C64 has on offer. And the author’s beloved Amstrad CPC664 didn’t allocate anywhere near its entire 64K to BASIC either, having a mere 3K of RAM more than the Breadbin.
The author might want to look more closely at the larger variants of said machines as well, because a 128K Atari 8-bit or Amstrad CPC machine will offer the same amount of RAM as its 64K sibling for BASIC programs (meaning that only one third of their available RAM can be accessed) and the MSX2 doesn’t even give that much a 128K system! But for some reason the C64 is the only machine earning the author’s rather hypocritical ire for not having the majority of it’s memory available for some reason…
The Commodore Plus 4 was a better designed computer than the Commodore 64, because it came with a much better BASIC called Commodore BASIC 3.5, as well as 4 pieces of software built in on ROM, plus a Machine Code Monitor.
Having a better BASIC really doesn’t equate to it being a “better designed computer”, countless Plus/4 owners with machines containing blown chips can attest to that and a 64K expanded C16 is considered to be the better choice for many fans of the series. Having the built-in machine code monitor is indeed a nice feature – software publishers of the day would have disagreed however, since it was also an excellent tool for cracking their copy protection – but the productivity suite has never been well regarded so a C64 with third party offerings could do just as good a job.
In the program above, line 10 prints PETSCII character 147 to clear the screen, because we‘re only using the normal text screen, instead of a graphics screen. After this, V is definted as 53248, the base address of the VIC-II chip, meaning the first register.
As a reminder here dear reader, the author has whined previously about having to memorise five digit memory locations on the C64 and how difficult he personally finds that to be, but this work around using the variable V being “definted “ as 53248 was present in the C64’s manual. He either didn’t bother reading the manual or has rather stubbornly chosen to ignore it for over three decades since then because it would negate his “argument”.
Line 12 positions and prints two solid circle graphics characters. This line really shows how inadequate Commodore BASIC V2 is when it comes to positioning characters to print!
Except it doesn’t dear reader, that’s merely the way this line can be represented in a listing that could be posted to the author’s blog as a comment and a mixture of some or all of those CHR$ commands could simply be stored as embedded control codes within a regular PRINT command. The author might not like this inline approach but that’s merely his personal opinion and clearing the screen, positioning the cursor or changing its colour can all optionally be done from within a PRINT statement alongside the text being outputted. In some respects this is a more efficient approach than the one used by other BASICs where it’s necessary to stop mid sentence to change text colour via a bespoke command.
The sprites are then drawn on the screen when locations 2040 and 2041 are each POKEd with 192. This could be bitwise programming of registers, setting certain bits.
Locations 2040 to 2047 are the last eight bytes of the 1K block being used for the screen RAM – that starts at 1024 – and their job is to point the VIC-II at the sprite definitions within the current 16K video bank. In the code supplied, multiplying the value written to those locations by 64 will get the actual address of the data, in this case 192 times 64 is 12288.
Hardware-based sprites aren’t drawn to the screen itself and co-exist in the same way that Post-It notes can be stuck over the contents of a computer monitor but don’t have any effect on the areas of the screen they obscure.
Line 25 is setting up sprite coordinates, but I don‘t understand how these coordinates work! I‘ve tried changing the numbers, but with unusual results. This is the text screen we‘re using, but sprites aren‘t part of the background, so may be using some other kind of coordinates system.
The sprites don’t use the screen’s co-ordinates because they work independently of the screen itself – the same is true for other platforms including the Atari 8-bit – and, because sprites can move into the border areas to allow objects to enter or leave the screen smoothly, they therefore need different co-ordinates. The top left corner of the visible screen for a sprite on the C64 has the X value of 24 and Y is 50.
Line 34 is using the previously undeclared variable CD, which I assume means Collision Detection, by checking if it equals 0. As it‘s never mentioned previously, then it MUST be equal to 0. Then if XX=1, meaning a collision has happened, DX=-DX, so that the vertical direction is reversed. After this POKE V+3 changes the sprite 1 vertical coordinate, then CD is set to 20, which at least means it‘s no longer 0, but it‘s not clear what this does!
This part of the program is dealing with collision detection between the moving sprite and the background, with CD being used as a timer; when a collision occurs CD is set to 20 and, until that timer decreases back to zero (line 35 handles that side of things, lowering the value by one with every pass of the loop) further collisions are ignored. This is done to avoid accidentally detecting the same collision twice, so your correspondent would hazard a guess that CD is perhaps short for Collision Delay?
Line 35 looks like it may contain some kind of errror, as it reads “35 IF CD0 THEN CD=CD-1”. I think this is where the command ELSE may have come in useful. It may mean IF CD=0, meaning that the conditiion in the previous line has failed, or that for some strange reason the programmer wanted to cancel out the previous command “CD=20”, but why?! It looks like it may have something to do with the direction of a sprite, instead of with collision detection.
Line 35 is an interesting one dear reader, there’s certainly a typo but your correspondent isn’t sure if it was meant to be IF CD>0 or just IF CD since both are valid. The program is actually doing the latter anyway since everything after the second character of the variable name is ignored – so that part at least is a happy accident – but your correspondent did a little digging and tested IF CD to find that it works in the same way on a number of other BASIC dialects.
This business of POKEing a location with its own contents is one of the most confusing things about the Commodore 64!
No dear reader, it’s not confusing in the same way that any BASIC dialect can add or subtract values from a variable’s current state with commands such as X=X+4. The only real difference is that the variables don’t need to be involved.
It‘s been very difficult writing this post, so I‘ve decided to split it into two parts. Luckily for you, this means the next part explaining the program in detail, along with a conversion into one or more other BASIC dialects, will follow fairly soon.
Your correspondent is very much looking forward to seeing how the author deals with converting a listing he doesn’t properly understand even at a BASIC level before the C64-specific register reads and writes are taken into consideration. The author despises the C64 for not, to his mind at least, being easy to understand in this context so it’ll be very interesting indeed to see how he feels about platforms like the Spectrum , Apple II or BBC Micro after trying to implement both the sprites themselves and their collisions completely in software.
 Each sprite definition is 63 bytes long but they’re stored as 64 byte blocks in memory; this is sensible since it gives us 256 sprites in the current video bank and the data pointers are all 8-bit numbers so can only be a value from 0 to 255.