When more sprites collide

Debunking Debunking “not rocket science – part 5”

TMR of the rival blog “C64 Crap Debunk” https://c64crapdebunk.wordpress.com/ (a maths whiz who can remember lots of five digit memory locations) has had the cheek to try and debunk my amazing post “Oh that would be VERY difficult – Part 5”, so here‘s my reply about how he‘s talking crap as usual.

The author’s entire blog consists purely of his biased, illogical, factually inaccurate and often desperately pathetic, childlike rants, so claiming that anybody else is “talking crap” is quite frankly farcical. Your correspondent still isn’t a “maths whiz” by any stretch of the imagination, much as the author apparently needs that to be the case.

This blog is mainly about how Commodore even dared to unleash a computer on unsuspecting consumers which contained a three channel/three note polyphonic synthesiser chip, as well as colour hires graphics, but didn‘t include a programming language which supported those features.

And, as we’ve noted at length dear reader, other computers that the author has talked about previously also have their issues on that front; where is the BASIC support in the Atari 8-bit series or Texas TI-99/4a for the hardware sprites that both platforms have for example? Come to think of it, where are the Atari BASIC commands for handling those powerful display lists?

Oh that’s right dear reader, despite lacking BASIC support for those features these machines somehow magically don’t count because they’re not the C64.

I‘m trying to avoid featuring any advanced tools running on x86 PC type computers which the vast majority of C64 owners couldn‘t afford back in those days.

Pretty much anybody writing 8-bit software now in anything approaching a serious capacity uses cross development tools because they’re convenient; the source code can be posted online for others to learn from, build times are in seconds rather than minutes or in the case of the clunkier tools, hours backups can be automated and there’s no dealing with thirty plus year old magnetic media with the reliability issues that would bring to the table.

But your correspondent and others who have responded to the author have also paid their dues over the years or in some cases decades with native tools and, whilst the author doesn’t share that knowledge or experience, his “I know best” attitude leads him to believe that his uneducated and biased opinion is somehow more valid than everyone else.

As for the amounts of RAM available on different computers, there was the Amstrad CPC family which managed to have more RAM free to BASIC than the C64 AND another 16K dedicated to hires graphics,  while MSX computers had about 28K free to BASIC plus another 16K of video RAM. The Commodore Plus/4 declared 60671 bytes free to BASIC on its startup screen.

Anybody sensible would expect that a machine released after the C64 would in some way improve on it, even if that improvement is less than 4K extra for BASIC in the case of the Amstrad CPC which came out two years after the C64.

All the official Commodore Manuals kept mentioning using BASIC with five digit memory locations.

The C64 manual contains a small program which puts a sprite-based hot air balloon on screen and, despite the author’s claim above, at line 10 of said program is the command V=53248 followed by a comment reading “START OF DISPLAY CHIP” – he might have “forgotten” about that but the author has mentioned typing it in previously so can’t claim ignorance here.

BASIC Sprites (C64)Above is a screenshot of said program running with that line shown on screen (the RUN 10 command skips the PRINT command before it which would have cleared the screen).

They could have avoided this by suggesting programming in Assembly Language with a prepared file of equates giving meaningful names to those locations, as well as predefined Macro routines, which are a bit like BASIC commands, translated into pre prepared routines of Assembly Language commands.

Being overly enthusiastic when assigning labels in this way can cause memory issues on larger programs since each reference to said labels will take space away from the actual assembly language –  STA 53280 will be significantly more efficiently stored by an assembler with a good tokeniser than STA BORDER for example – so anybody “back in the day” optimising their code to claw back memory would first purge the comments before moving on to those labels.

Whilst we’re here, the author hasn’t described macros very well presumably because he’s never used them; they’re just fragments of frequently used code which might be used multiple times within a program so, whilst a macro may do something BASIC-like such as place text on the screen, how the data is actually passed to that code will be very different.

TMR made the revelation “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” I don‘t think I ever knew that before!

This is actually documented in the C64 manual straight after the program example with the hot air balloon which the author has previously talked about typing in so it really shouldn’t have been new information to him unless his “I know best” attitude meant that he couldn’t be bothered to read the manual properly. There’s even a link to the relevant part of said tome included within one of the author’s posts linked above, but please click here to visit it directly and scroll down to the top of page 73 where line 11 of that program is explained with a handy diagram showing the bits and their values.

Of course, I read back in in 1984 that variables such as V were often defined as 53248 ($D000), then offsets such as V+1, V+10, etc, were used for the various VIC-II chip registers […] but it seemed to me there there were hundreds or even thousands of five digit memory locations to remember apart from the VIC-II and SID chip registers, so that wasn‘t much help!

It doesn’t matter if he believed that there were “hundreds or even thousands” of registers because there weren’t and the mistake was nothing to do with the C64, it’s manual, Commodore or indeed anyone or anything else and purely down to the author himself. As was literally just pointed out at the start of the above paragraph, there’s no actual need to memorise five digit numbers either so the subsequent whining – along with all of the complaints on previous posts – is therefore debunked by his own words. Again.

If someone decided that their main requirement was that they must buy a computer which had sprites, here were their choices, at least in Britain. Buy a Commodore 64 and end up with an extremely crappy BASIC. Buy an Atari 400/800/XL/XE but not get much support

The amusing term here is “not get much support” dear reader; the Atari 8-bit’s BASIC has exactly the same amount of direct support for the hardware sprites as can be found on the C64 because it’s all handled using POKEs, albeit significantly more POKEs on the Atari for vertical motion. The other difference is that, whilst Commodore’s “extremely crappy” BASIC includes bitwise operations which can be utilised for checking collision registers[1], the same isn’t true for the Atari so the program and indeed programmer will need to do far more work in order to achieve a similar effect.

Battered 800XL manualAnd whilst there are examples for using hardware sprites in the C64’s manual, your correspondent recently found the book which shipped alongside his Atari 800XL in 1984 – the author would have received it as well had he made a different purchasing decision back then – and the same isn’t true there. It’s a mere 64 pages long, of which only ten are the English version of the text and there’s absolutely nothing in there to teach a new user BASIC apart from one page with three short sample programs which don’t come with an explanation of what they actually do.

As for converting this program listing to a BASIC for spriteless computers, it presents no problems. This is because the main difference between sprites and UDGs is that sprites are independent of the background graphics, meaning they can move over any background graphics without disturbing them, while UDGs or character graphics are part of the background graphics, so they can‘t do that without careful programming. This usually involves the use of XOR or EOR. In this example there are no background graphics, though!

There are a couple of background elements that the moving sprite partially passes over – the collisions wouldn’t register otherwise – and the sprites themselves overlap as well so that will need to be dealt with via some form of masking; both sprites are also moving a pixel each refresh so the author’s software sprite routine is going to have to emulate that along with handling pixel accurate collision detection between those elements. Doing all of that from BASIC is going to be glacially slow.

Soon, I hope to post a conversion of the listing in question into Commodore BASIC V7 for the C128!

If his C128-specific BASIC version of the program actually materialises your correspondent has already ported his assembly language version for that platform whilst composing this post so, although there are no changes to the core program, we can spend a little time examining the small differences within the initialisation code and memory positioning between the two machines for assembly language programming.

Of course, if the author had any courage in his convictions the first platforms he’d be converting the program to are the Atari 8-bit or Texas TI-99/4A since aiming for a machine released after the C64 doesn’t prove much of anything…

[1] The Atari 8-bit’s BASIC actually has a command for reading the joystick ports but it returns a byte with the bits either set or unset depending on what the hardware is doing; not being able to AND specific bits off for testing from BASIC means that more code is required to handle all of the possible states.

Advertisements
Posted in Debunking | Tagged , , , , , | Leave a comment

When sprites collide

Well over a month ago the author posted a BASIC program that he’d been given for the C64 which used the hardware sprites and their collision registers, claiming that it showed “one sprite bouncing off another on the C64”. This isn’t really the case of course, because reacting to a collision in this way doesn’t meet any of the definitions of the word “bounce“, instead one sprite is merely sliding downwards when a collision is detected between it and another moving horizontally.

BASIC Collisions (C64)

Linguistic issues aside, the author also promised his readers that another post “explaining the program in detail, along with a conversion into one or more other BASIC dialects” would be following “fairly soon” but there hasn’t been a peep out of him since then. It’s difficult to know if dissecting a mere 11 lines of program or converting it to another BASIC variant is what has delayed that follow up but, just to get the ball rolling a little, let’s go through the C64 listing line by line to see what it actually does.

10 PRINT CHR$(147):V=53248

In turn, the PRINT command is clearing the screen – character code 147 is the same as hitting shift and Clr/Home – and 53248 is the base address of the VIC-II’s registers in memory so V is being set up to point at those locations and subsequent register writes will be done as an offset from that value. This saves anyone having to remember five digit register locations.

12 PRINT CHR$(13);CHR$(13);CHR$(13):PRINT SPC(2)CHR$(209)SPC(22)CHR$(209)

The first PRINT command here is moving the cursor down by three lines, whilst the second prints two spaces, a ball character, 22 spaces and another ball character.[1]

15 FOR T=12288 TO 12350:POKE T,255:NEXT:POKE 2040,192:POKE 2041,192

This builds some sprite data by filling the memory between 12288 and 12350 with a value of 255, making it a solid 24 by 21 pixel block. 2040 and 2041 are the sprite data pointers for sprites 0 and 1, they can point at any 64 byte block in the current 16K video bank and multiplying the value 192 by 64 gets the memory area that the loop has just filled at 12288.

20 POKE V+39,1:POKE V+40,3:SC=V+31:SS=V+30

Set sprite 0’s colour to white and sprite 1 to cyan. SC is being given the location for the sprite to background collision register while SS is being set to the one which deals with sprite to sprite impacts.

25 X=80:DX=1:POKE V,X:POKE V+2,125:POKE V+1,80:POKE V+3,80:C=0:POKE V+21,3

In order, initialise the variable X which holds sprite 0’s current X position, write that value to the actual X register for sprite 0, set sprite 1’s X position to 125, set both sprite Y registers to 80, set C to zero (this appears to be orphaned since it’s not used elsewhere, your correspondent is assuming it’s actually a typo and should say CD=0) and enable sprites 0 and 1 – up until this point the sprites were there but not visible.

30 X=X+DX:POKE V,X

Add the current speed to sprite 0’s X position and then write that value to the relevant hardware sprite register.

33 XX=PEEK(SC):XY=PEEK(SS)

Read the collision registers. SC is the register for sprite to background collisions so XX gets its current state and the register at SS deals with sprite to sprite and that’s what ends up in XY.

34 IF CD=0 THEN IF XX=1 THEN DX=-DX:POKE V+3,PEEK(V+3)-23:CD=20

If the collision delay is zero and the value read from the sprite to background collision register is 1 (so sprite 0 has collided with the background) then invert the X direction, subtract 23 from the height of sprite 1 (essentially resetting it) and set the collision delay to 20 to make sure a second collision doesn’t happen for a few iterations of the loop.

35 IF CD0 THEN CD=CD-1

If the collision delay is greater than zero, decrease it by one until it’s zero for line 34 to start checking the sprite to background collisions.

As noted in your correspondent’s previous post, this functions perfectly but presumably by accident; IF CD0 is actually being treated as just IF CD and any value greater than 0 triggers the condition. Your correspondent is assuming it was actually meant to say IF CD>0 since that usage is more commonplace.

38 IF XY=3 THEN POKE V+3,PEEK(V+3)+1

Let’s check to see if a collision has occurred between the two hardware sprites and make sprite 1 move downwards one pixel if so. The reason for XY being checked for the value 3 is that this is a bitwise operation, sprite 0 is represented by the first bit in the byte (which equates to the number 1) and sprite 1 is represented as the second byte (which has a value of 2) so 1 + 2 = 3.

46 GOTO 30

And finally, since we’re all done it’s time to GOTO back to the start of the main loop at line 30.

Just for good measure and to kill a little time on a quiet Thursday, your correspondent has also converted the BASIC program into assembly language (shown in the video above) and the source code is available to examine over at Github. For another, more fleshed out working example of hardware sprite to sprite and sprite to background collision it’s also worth prodding around inside your correspondent’s previous release Super Hyperzap since it utilises both.

Hopefully this post – and perhaps even the assembly language conversion – will enable the author to move forwards towards his stated goal of converting the above program to other flavours of BASIC, because watching him floundering with dialects on other platforms that either don’t have hardware sprites or support them from BASIC should prove to be amusing. Your correspondent wonders if the author will look at the MSX series (released after the C64) first or try to convert the listing to a machine that was released at the same time as the C64 or before it?

[1] This is a somewhat long-winded approach but necessary to make the program transportable as text over the internet; the same effect could be achieved more optimally either with inline commands – these and the previous line’s PRINT command could even be rolled into a single command – or with one PRINT to clear the screen and four POKEs to the video and colour RAM to position the balls.

Posted in Meta Discussion, Programming | Tagged , , , , , | Leave a comment

Release Notes – Super Galax-I-Birds (C64)

Graphics artist and musician Andy has recently been getting his head around C64 assembly language and your correspondent has been one of the people offering help along the way. As part of the learning process Andy has been looking through some of the source code your correspondent posted at Github including Super Hyperzap and, after understanding what it was doing, started making his own modifications; initially this involved changing cosmetic features such as graphics and music, but soon there was new code being bolted in and now the code supports two players and stores a high score for each.

Super Galax-I-Birds (C64)The result of his exploration is Super Galax-I-Birds, which is something of a homage to a rather silly but entertaining budget blaster from Sensible Software which was published in 1986 by Firebird; Galax-I-Birds is similar to the kind of shoot ‘em up that some novice programmers will write for the C64 and was actually one of the inspirations for the original Hyperzap when your correspondent himself was still in the process of learning assembly language so, in a sense at least, this release completes a wide and slightly meandering circle which was unwittingly started over three decades ago. And on a totally unrelated note, your correspondent suddenly finds himself feeling rather old…?

Super Galax-i-Birds was released under the C64CD banner at Andy’s request – making it the first program published on said “label” which wasn’t coded by your correspondent – and also serves to demonstrate at least one way that new programmers learnt and indeed still learn how to program the C64. His modified version of the source code has been included in the archive with the game itself for future beginners to learn from.

Posted in Programming | Tagged , , , , , , , , | 2 Comments