Tuesday 24 May 2016

Cycles of indecision

Absolutely no progress to report. Work has been taking its toll lately and to be honest, atm when I'm not working and the kids are in bed I'm more inclined to chill out in front of the Giro d'Italia than spend even more time sitting in front of a computer screen.

I do have to admit that I've lost a bit of momentum on the project and still undecided on whether to persist with the on-the-fly rotation or just bite the bullet and finish off my original (pre-rotated graphics) attempt. The latter - although more work - is more likely to be able to handle colour and sound... however I will get this tack working perfectly (even if only for demonstration) before I make up my mind for good.

Friday 20 May 2016

Still in the red... but much improved

Thanks to jmk, the rotation code is much improved - almost twice as fast in fact! So with some renewed enthusiasm, I added the routine to draw the shields and the game display is complete - except for the scores which I need to relocate to the side of the screen.

The red colour indicates time spent in the VBLANK ISR

Still not a lot of headroom for the VBLANK ISR code which, as you can see above, now encroaches on half the frame, where the mid-screen ISR is scheduled to run. Ordinarily that would show as blue but in the above screen shot, it's happening in the black area above the shields.

There are still some graphical glitches to iron out - my dirty rectangle code needs some tweaking - but the game is certainly playable and it's a reasonably accurate representation of the actual Space Invaders display.

I was originally intending on widening the Coco display from 256 to 320 pixels, but that would actually complicate the calculations for the rotated screen address; right now it's a simple byte-swap and an 8-bit and+neg+add sequence. I'll have to evaluate the implications.

Thursday 19 May 2016

Mostly working.

Usual story, busy with work blah blah.

I have managed to get it mostly working though - except for the shields. The rotation code is brain-dead brute-force, and given that the VBLANK ISR now takes most of the frame to execute, there's going to have to be a lot of optimisation if it's going to be playable, let-alone add colour and sound. But I still think it can be done.

I should note that I do appreciate the coding/optimisation suggestions tendered in the comments, and will certainly be visiting those again when the time comes.

But the important part is that I've now wrapped my head around what needs to be done. Tonight, for example, I racked my brains trying to find which routine wiped the invaders as they moved - in particular when they hit the edge of the screen and move down. Finally it dawned on me that they don't get erased, but in fact get redrawn by the shifted sprite routine - with a shift value of 0. This has the effect of wiping the 8 pixels above the invader (each and every time).

There's still a chance that I'll get all this done and then need to return to the original plan though...

Tuesday 17 May 2016

Some lunchtime progress; draw and erase 'simple' sprite routines. These draw, and erase, byte-aligned sprites respectively.

Byte-aligned sprites are rendered/reased

Rotating is all the more complicated (=slow) without an 8-bit rotation on the 6809.

Monday 16 May 2016

Seeing double

Next-to-no time to work on Space Invaders lately, but managed to find 10 minutes here and there a few times since the last post, and tonight I finished another intermediate task.

The idea was to duplicate the screen, to achieve a few goals. One was to identify each of the routines in the code that will require extending to render the rotated screen. FTR there are 11 such routines. In each case, I simply added code to the end of the routine to (also) re-render the video to the Coco3 display. This code will ultimately rotate the graphics on-the-fly. It should be obvious that during the process, I had to take note to preserve and restore any registers that were assumed to be a certain value on return from the rendering routine.

Another goal was to gauge how much processor time was still available during the interrupts. The good news is that, whilst the VBLANK interrupt now encroaches on the visible display (as it no doubt does on arcade hardware) there still seems to be plenty of headroom for further complexities.

Next step is to add the rotation. Looking at my old Space Invaders TRS-80 Bootleg Project code, it was all done brute-force using a few assembler macros. No harm in at least giving that a go; it should mean there's not a lot of code required to achieve all of the rotations!

UPDATE: A little more progress. Three (3) of the eleven routines are complete; the two clear routines and the routine to draw the line along the bottom. None of these required any graphics rotations and were more-or-less simple rewrites.

As for the remaining eight (8) routines, they've all been modified to draw the graphics at the correct screen location. One of them, the routine that draws the shields, will have to be modified in the caller as well as it sets the video address of each individual shield.

The Coco3 screen in its correct orientation

Right now it's crashing, but that's not totally unexpected.

Friday 13 May 2016

Changing tack

I've been overwhelmed with work the last few days - and still am - but whilst watching Quartus do its thing (it's about as exciting as watching paint dry) and pondering Space Invaders, I'm seriously considering changing tack altogether.

To some extent, the original game was optimised for the rotated display; the player, the invaders and the saucer all move left/right and thus don't require the shifted rendering routine. Even worse, the shields are each offset 45 pixels from the one to the left, which means they too will require shifting.

Way back in 2003 (gosh!) I worked on what I called the Space Invaders TRS-80 'Bootleg' Project, in which I patched the arcade ROMs to run on the TRS-80 Model 4 with the aftermarket uLabs Grafyx Solution high resolution graphics board. It was only partly successful for reasons you can read about on the link if you're interested.

The strategy I took in that project was to retain all of the original rendering, but rather than render to video memory, it was rendered to an off-sceen buffer. The patches then modified each rendering routine to update the Grafyx Solution video memory, rotating each 'dirty rectangle' on-the-fly. It was much, much simpler to implement and, with a 4MHz Z80, there was enough head room for the rotation calculations. It's a pity the Grafyx Solution video bandwidth was the show-stopper.

I think it's worth at least giving it a go on the Coco3. Once the playfield has been drawn at the start of each player's turn, there's really very little rendering per frame. I'm pretty sure the 1.79MHz 6809 is up to the task, especially given the results of the profiling I did recently.

Time to dig out that Z80 code from 2003...

UPDATE: During lunch today I've just backed out the rotation changes and in preparation for the new scheme, moved the Space Invaders video memory (buffer) from $0000 to $2000. I had to fix a couple of latent bugs that weren't apparent when the video memory was based at $0000.

I've also had an idea; now that I'm re-rendering from the original video RAM to the Coco3 display, it should be relatively simple to change to 2BPP and add colour at the same time - effectively killing two birds with one stone!

Thursday 12 May 2016

More rotation WIP

Busy with work but managed a few more updates to the rotation.

The aliens are drawn now in the correct position and orientation, as is the bottom line of the screen, the remaining bases icons and the player is sort-of but not-quite right.

As yet I haven't had to change many constants at all; most values are calculated from the original with a macro, which is nice. The main changes have been to the sprite erasing/rendering routines, for which there are about a half-dozen. These are temporary hacks until I optimise the sprite data format.

There will be a few instances where I need to patch the code so that it differs slightly from the original. For example, the saucer sprite is 24 pixels wide, with 4 zero pixels each side to negate the need for erasing it as it moves. However, the Score Advance Table draws only the middle 16 pixels; something I can't do on a rotated screen. For that matter the saucer render will have to call the shifted sprite routine, rather than the simple (non-shifted) sprite routine.

Anyway, coming along, if a little more involved than I first envisaged.

Wednesday 11 May 2016

Rotation

Started on the rotation tonight. There is a build option to specify rotated or non-rotated screen, mainly for prosperity. To this end, I've defined a couple of macros that calculate the correct VRAM address (at assembly time) depending on the rotation option, so the code is still clean.

Rotation of 8 & 16-pixel-wide graphics done

It's very preliminary atm. I've only rotated 8x8 pixel blocks; although sprites that are wider can be rendered (see above) they really should be reorganised to optimise rendering. That'll come later.

I've retained the 256-pixel-wide screen for now, to simplify the rotation. When it's all done, I'll change it to 320 pixels wide (hopefully just modify a macro or two) and move the scores.


Tuesday 10 May 2016

By popular demand - my Coco3 setup

I've been inundated with requests (at last count, at least 1) to show my development set-up. Of course all my coding and initial testing is done on my desktop PC using AS6809 and MESS, and no point showing that off. But I do have a few pictures of my Coco3 and shiny new CocoSDC.

CocoSDC Floppy Disk emulator

The CocoSDC allows you to simultaneously use real floppy drives (via an MPI), disk images on a DriveWire server (eg. PC), and of course the disk images stored on the SD card. At the moment I'm just writing the Space Invaders disk image to the SD card each time, but for extended development-test cycles it's much more convenient to use a DriveWire cable (I can't find mine atm). For anyone interested in finding out more about this piece of hardware, here's the link to the homepage.

The perspex case was a limited run. I'm glad I bought one - a year before I even owned a CocoSDC - I think it looks pretty neat!

Coco3 running Space Invaders from the CocoSDC

And here's my Coco3 set-up, balanced on the edge of the desk amid a rat's nest of cables. It's an '87 GIME with a Cloud-9 512KB upgrade, using low-profile SIMMs that were pulled from classic Macintosh machines. One day I'll swap it for a Triad. I'm having trouble finding a display that will work with the Coco; I've commandeered the kids' TV which was stored away for a few weeks whilst the wife paints the playroom, so I'm living on borrowed time in that respect.

There's the obligatory Dilbert mug of course, and to the right is my new EPROM eraser, atop which sits my sole remaining cartridge PCB and a handful of EPROMs that have been used to test Lode Runner, Knight Lore and now Space Invaders.

UPDATE: I've found the issue with interrupts on the real hardware! A temporary hack fixes the issue - just need to work out how to do a proper fix, and then I can release an Alpha!

UPDATE #2: Alpha release available for download.

The issue was related to GIME timer interrupts in MESS vs real hardware - seems there is a discrepancy. More details to follow.

Interrupting my debugging with CocoSDC

Firstly, more experimentation suggests the problems are related to interrupts, but still no solution atm.

Another thing I did was add code to change the palette within the two ISRs, to see how much time was being spent inside them; most of the code is actually running in either or the other. Turns out the Coco isn't even breaking a sweat on Space Invaders. The VBORD (VBLANK) interrupt is finished even before the raster gets to the 1st active line of the display (I only started to see it when I extended it with ballast code), and the TIMER (mid-screen) interrupt varies between about 7 and 15% of the frame. So no chance of missing interrupts and both sound and colour are looking good right now!

Of course, there's the minor issue of the game not running.

One observation I've made is that things move way too quickly in one half (the top half) of the screen, which suggests that perhaps the VBORD interrupt is running more often than it should - which could happen if it isn't acknowledged properly.

Anyway, erasing and burning EPROMs is simply way too painful when debugging code, so I finally bit the bullet and assembled my CocoSDC (bought the case in Nov 2014, the PCB in Nov 2015). And I'm happy to say that the disk version of Space Invaders runs as expected. As does Lode Runner and Knight Lore, with the exception of a glitch on the text-mode splash screens which, oddly, isn't present on the cartridge version.

The CocoSDC is one cool piece of kit!

Sunday 8 May 2016

This is the last bug (said every software engineer ever)

At one point during the port I had to disable (skip) the demo mode because bugs at the time would cause it to crash which of course hampered debugging of the splash animations for one, and also the game play indirectly. Being so focused on completing the game play, I'd completely forgotten about this and when I re-enabled it today, I was reminded of the bug where the player base just moves to the right side of the screen and sits there.

Fortunately it took about 2 minutes to find and fix; yet another endianity bug in a small block of data that is copied to RAM on start-up, that had slipped under the radar, it not being commented in the disassembly. So bug #13 done and dusted.

Rather than pursue the elusive 2-player issue right now, I decided to get the disk version working and add appropriate splash screen and README.TXT content. So the minute I fix what I firmly believe is the final bug, and test on real hardware, I can release an Alpha for general consumption.

Stay tuned, we'll be back shortly.

UPDATE: My daughter wanted to play horse Duplo with my wife, so I snuck away and managed to find the last bug - a register value that was being overwritten by 6809-specific implementation. That register contained the delta-x value for moving the invaders, which should have been either +/-2, but was overwritten with -4 every time (I didn't notice). Hence the invaders not wiping properly. Bug #14 squashed.

Now to fire up my brand new, as-yet unused EPROM eraser and see if it runs on real hardware!

UPDATE #2: I actually found a blank EPROM so no waiting for the eraser, but an unexpected result. The game runs, but the invaders aren't firing back at all, and it seems the player's shot is too fast. Reminds me of an earlier observation during the porting process. Interesting... without looking into it, I do have one guess.

UPDATE #3: Well my theory on why it's not running on real hardware didn't pan out, so right now I'm stumped. Mind you, I've spent about 2 minutes looking at it, so I likely haven't exhausted all avenues just yet. I'll need to spend at least another 2 minutes before I get to that point...

It's Game Over - thankfully!

Literally 10 minutes to work on Space Invaders thus far this weekend, but I did manage to squash bug #12 - the 2-player game not ending. A simple case of using STA instead of CLR.

I think that just leaves the one bug (lucky #13) now; invaders not being erased properly when player 1 or 2 game is restored. At this point I don't have a theory for the cause of the problem, I simply can't think of what bug could manifest itself in this way. Would be ironic, if not really frustrating, if this one (#13) proved elusive for the next few days.

Once this is fixed, and there aren't any further apparent bugs, I'll get the disk image running properly, test it on real hardware, and release an 'alpha' version that people can try just to get a feel for what they can expect on the Coco3 once I rotate the screen.

I've been thinking about the sound support lately and will have to do some research on whether samples, or pre-rendered waveforms (or possibly both) are the way to go. I purposefully coded all the sound routines whilst porting to the Coco3 - short of the actual port I/O - to better facilitate adding sound. On the arcade hardware, the port I/O simply turns on/off each of the discrete sound circuits, so they'll need to be replaced with flags in RAM.

Friday 6 May 2016

1's company, 2's a crowd!

Another lunch break, another bug fixed. I decided to look at the invader shot frequency since I was getting nowhere with the 2-player game issues, and it was yet another endianity issue. The shot frequency is dependent on the MSB of the player's score; having swapped the endianity for all 16-bit values on the 6809, it was looking at the LSB. Bug #11 down.

As far as I can tell, the single player game is now complete and running 100%. So there's just the 2-player game that has issues; I know of one, possibly two different bugs.

Hopefully, an alpha release is imminent!

Thursday 5 May 2016

One step forward, two steps back

Lunchtime bug fix #8, the game crashing after player 1 dies in a 2-player game. There was an issue with the routine that remembers the shields; the game progresses to player 2 now.

However, after player 2 dies, player 1 subsequently dies immediately and their game ends, printing the "GAME OVER" message on the wrong row of the screen. And ditto then for player 2. We'll call these bugs #10 & #11... so currently 8 down, 3 to go.

UPDATE: Well, I guess I've never actually played 2-players on Space Invaders before; turns out the "GAME OVER" message is actually printed at the correct position on the screen; below the shields! What was in the wrong position though, was the bottom line, because the byte value was hard-coded in-line, and I hadn't reversed the bits for it.

So replacing bug #11 with an actual bug (fixed), that's 9 down, 2 (at least) to go! Now to find out why the 2-player game isn't working properly...

UPDATE #2: Again, fixed bug #10 and bug #12 appears - when player 1 starts up after player 2 dies, the invaders aren't erased properly, and eventually the game resets. 10 down, 2 (still) to go. I suspect there's at least one more bug - the 2-player game never ends even after players run out of bases. Could be parasitic to one of the two remaining bugs, but probably not.

Once the two-player game is working, and it's very close now, it's just the bomb frequency, and there's a routine specifically for that. Agonisingly close now!

Wednesday 4 May 2016

Bonus bugs!

Well my prediction of a half-dozen bugs is looking pretty shaky already. I've had to fix three (3) bugs just to get the saucer to appear, and in the correct position. Then for the first hit of the saucer I got 300 pts (dubious), and for the next hit I got "CLE" points. That'll be bug #4 already...

UPDATE: Bug #4 squashed. Saucer working now.

UPDATE #2: Bug #5 - 2nd and subsequent waves of aliens not appearing in the correct position - squashed at lunchtime. Next bug - extra alien added when player dies.

UPDATE #3: Couldn't help myself, squeezed in another two bug fixes before finishing lunch.

Bug #6 - extra alien added when player dies, as mentioned above, fixed.

Bug #7 - bonus ship icon not displayed, also fixed.

Next bug - program freezes on 2 player game after player 1 dies.

Another bug I've noticed - and I can't explain how it's even possible - the invaders are dropping 3 and (I think) even 4 bombs at a time!?! IIUC there's only provision in the code for two at any one time!?! Certainly an interesting one, and the game is definitely more difficult because of it!

So we're at 9 bugs now, although I'm not aware of any others, so it's close!

Tuesday 3 May 2016

Space Invaders in 6809. Now with added bugs.

At lunchtime today I dug in and managed to finish porting the remaining 8080 code to 6809.

There are a number of bugs that make the game less playable than it was in the past, but I'm hoping there's nothing too difficult to track down. That said, it'll probably take a few nights of debugging to get it running 100% correctly.

In the process I'll clean up a few 'nasty' bits of code to make it a bit more relocatable on the Coco; as-is the data - both in ROM and in RAM - is byte-for-byte aligned with the original. That's something that I won't be able to preserve when I rotate the graphics, so I need to make sure it's not going to break when it's not aligned.

Hopefully the next update will be reporting a flawless port!

UPDATE: Well not flawless yet, but much improved. If I absolutely had to guess, I'd say about a half-dozen more bugs to find and fix (I can count 4 off the top of my head) - the game is so simple that most of the bugs should show themselves quite readily.

Fixed a few bugs in the invaders firing and high score calculations. The game crashes now; I suspect at the point that the saucer is to appear (I've yet to see it!)

Added dipswitches - currently build options - but they do work. I'll likely add them to the Coco3 splash screen before the game is launched. Also added the TILT input, which can be initiated on the Coco3 using the <CTRL><BREAK> keyboard combination - to be used for rage-quitting!

Monday 2 May 2016

Bug fixes that don't!

If there's one thing that I really hate, it's when you finally track down a bug, say to yourself "Ah ha - that would explain it!", duly fix it... and then the bug is still there. Happened to me (again) with the column firing. Having said that, it's better than before (so I did actually fix something) but still not quite right.

And speaking of bugs, in the process of trying to fix the aforementioned, it dawned on me that my shadow Z80 registers - stored in Direct Page memory - weren't preserved when interrupts fired! Fortunately there wasn't much else stored in that memory, so it was a simple matter of changing DP when entering and exiting from an interrupt service routine. Something that wasn't an issue in Knight Lore, for example, as there were no interrupts!

Frustrated with alien firing bugs, I instead implemented the player being destroyed. So now you can start a game that actually does end. At last count there were at least three (3) known bugs - none too major - but at least I've almost ported all the code to 6809. In fact, I'm tempted just to press on and complete the porting process before even attempting to fix any but the most obvious-to-fix bugs...

I've hit 4,000 lines in the source file now, and there really can't be much left; mainly to do with the saucer and I can't think of much else.

Ocne the porting and debugging is done, I need to rotate the screen. That process is going to be a little more involved than I first imagined, but still not too daunting. I am going to attempt to have the screen rotation as a build option, rather than completely abandon the non-rotated screen.

Then there's the issue of 2BPP colour, and then sound & joystick support...