Monday, November 27, 2006

XeO3: Pausing to gather our thoughts...

Yes I know... I've not done much XeO3 stuff for a while. I'm actually busy learning electronics, something I've always wanted to do but never found the time (or books) to learn. However, I've now gotten some of these so I'm trying to learn the fundamentals just now and that takes time... time that would normally be spent on XeO3. This has of course given rise to some new possibilities. The whole reason for learning this stuff is so that I can build add-on's for my retro machines, and we're currently wondering if you can build a retro game cartridge cheaply enough that people would buy XeO3 as a cartridge..... Anyway, this is all a sideline just now...The new cache system still has a nasty bug in it and is currently corrupting memory, so I'll have to track that down soon, and then try and tackle the weapons once I get over the initial electronics hurdle, I'll be back on XeO3.....honest :)

Friday, November 24, 2006

OOOooooo.....Interesting.....very interesting.....

U.S. Copyright Office issues new abandonware rights>>

Here's something abandonware enthusiasts can be thankful for: the Library of Congress yesterday approved six exemptions to US copyright. The one most pertinent to gamers is that, for archival purposes, copy protection on software no longer being sold or supported by its copyright holder can be cracked.What does this mean? Well, those retro games -- classic or otherwise -- that you can't seem to find anywhere can now be preserved without fear of ramifications. Although it is still unlawful to distribute the old games, free or otherwise, rarely do any abandonware cases go to court. The ruling is more symbolic than anything, but a step in the right direction.

Thursday, November 23, 2006

XeO3: Please Wait....Loading............

I was testing out TNT's new 1581 turbo loader last night, and WOW! what a speed. The whole thing loads in less the 10 seconds! Thats 179 blocks (45k) that load in a blip! While speaking to Luca I had mentioned that if I thought that most folk had a 1581, then I wouldn't worry about packing in the front end to the main EXE as it would all load in under a second! Pitty...Oh well, I guess the only way to really guarantee that kind of thing is to make a proper cartridge game; which is also somthing I considered BTW. Using a cart as a large instant Disk would be very neat, and I do think I'll do an MMC64 version that does just that! Once

the C64 version is done, I'll start splitting it off into parts and putting them on a memory card so that it can act like a cartridge. This not only gives instant loading, but also a huge capacity. I wonder how many MMC64's have been sold? The good thing is that unlike the SuperCPU, these are still being sold! So if someone wants to play XeO3 from cartridge, they can run out and buy one! I'll have to do a little investigation as to how it all works, but from what I've seen, it should be easy enough.

I wonder how much these cost to make.... If you could get it down a bit, you could bundle one with the game and sell it cased so it looked like a normal cart - even though there was an MMC inside! Althought thats probably taking it too far.....

Sunday, November 19, 2006

XeO3: Spectrum Wars....

I've been trying to fix a +3 spectrum for Russell today. I have 3 of them, but only 1 working one - and even that one isn't perfect as the load/save cable has been butchered to make a SAVE-ONLY cable. This probably happened when the socket broke. However, I've ripped them appart, took the working drive and put it inside one of the other machines (that has a proper tape connector) and all is well. So at least I have 1 fully working +3.

As for the others, well I discovered that on both disk drives, the belt has degraded too much and is now more or less just a blob of rubber. Fortunately I have 2 spare belts (no idea where I got them...but you can get them from ebay these days), and I've repaired both. But only one of them is actually fully functional. The other kinda works, but doesn't read anything. I suspect it might be the heads needing cleaned, but theres always the chance its just plain dead.

It was touch and go for a little on the working drive as when I opened it up, a tiny pin dropped out and I had NO idea where it came from - and the drive didn't work without it. But, after searching for a while on the NET, turns out its the write pin or something and I was able to plop it back into place.

The last +3 is pretty dead though; well....kind of. It boots, and you get the Copyright message at the start, but the menu doesn't appear. It just stays on the copyright message. I swapped the ROMS with one of the working +3's, and it was the same, so the ROM's are fine. I suspect its waiting on something, but I've no idea what. I have a multiface +3 and it can break in and works fine, so the Z80 is working okay as well. Oh, and if I reset and hold down BREAK, I get the test picture and the machine beeps away. Very odd. Still, I might butcher it so I can get a working tape connector on the other machine which now is working thanks to the 3rd drive having its belt replaced.

I've also discovered a really cool TZX 2 WAV program which converts TZX files into WAV files, which can then be played out the PC's audio and loaded in on a REAL spectrum! Very cool indeed. I've been busy taking snapshots of them and saving them to disk - its great seeing all my old fav's on the real machine again. And it's also shown that Cobra DOES indeed run in a frame.... After seeing Russell's scrolling code - I wonder how he managed that!

So, the next thing to probably try is chopping the end of a +3 lightgun and using that AUX port to download programs directly. I'm not convinced this will be terribly quick, but I guess at least Russell will be able to view his work on a real machine.

Edit: Oh....I did try Xeo3 on the +3, but it didn't work since Russ uses that 48k ULA hack. This means I'll have to hook up a real 48k spectrum to see it....Perhaps later :)

Thursday, November 16, 2006

Retro TV.

THIS is an old BBC documentary about Imagine and Ocean... Pretty funny to see now, but I would have loved to have seen it back in the day.... Have a watch... pretty good fun.

Tuesday, November 14, 2006

XeO3: Father Ted....

Okay.... I've gotten the TED sound playing the main theme, although its been a bit of a nightmare.... it turns out that normally these operate at location $D400 - the original location of the SID on the C64. But add-on for the plus/4 is mapped to $fd40 (or $fe80), but when the card isn't there then this is just normal IO space - and theres no RAM there. This means it just doesn't work! What I've ended up doing is making a relocate routine that runs through SID music player and then moves the writes to the SID card to an area of memory the Frequency convertor can get access to. I've also managed to shrink it down by 50 bytes, but I've had to add the relocate routine... so I've uised up just over 1k for this. for the REALLY bad news! This routine takes around 16 scan lines to run, and thats on top of the SID player! This is very painful! So, if we run low on memory again, this is the first to go as it will slow the game down in busy areas.

Still, I've given Luca the mconv source and he can release it on +4 world at somepoint so others can use it. As I said earlier, the source lets you play around with it easier..... as well as relocate it and change the storage locations.

XeO3: Mr. Ted Sound

The current poll on plus/4 world showing that only 28% of users have a SID card has forced me to include the TED frequancy convertor MConv. This unfortunatly steals yet another 1024 bytes leaving me with only 3k in the main code block. I spent last night disassembling it and typing it back in so that I have a source version and can relocate it all easily. Once it's fully working I'll let Luca upload it back onto Plus/4 world so everyone can get some use from it. It makes it very simple to relocate, change the SID base address and basiclly fiddle with the code. I'll also be able to shrink it very slightly since there were a few NOP's and the like due to it being written in the monitor. Having done a full game like that, I can appreciate the problems involved....

Once this is working, I'll get back to the sprite cache and finish that off, and then hit the weapon system I think.

Sunday, November 12, 2006

XeO3: The big push.

After a small break due to family, work and a cold, I'm now back on track and pushing down the memory to try and free up as much as I can for the last chunk of code. I've rewriten the sprite cache, packed the sprite data and done a general re-jig of the data layout. I've managed to save 4K which means everything can move up by a whole bank ($1000) and this lets me easily pack this 4K in with the current code and data, which brings the grand total memory free to 6.5k - which isn't bad at all. Of course theres still lots to do, but this should give me plenty of space to do it! The remaining 1.5k is right at the top of memory, which makes it a bit of a faff to use for most things - unless I can generate tables there.

So, now that this little(!) task is taken care of, I can start to go through my to-do list. If I get the weapon system working, Luca and I can try and release a test level which won't be used in the final game, but will give us feedback on difficulty levels from - well all of you. If you look at Luca's page, you'll see he did another level based on the level 1 graphics. This is the one you'll get to play with first.

But before I do all that, I'll need to test the new cache system and make sure its holding up okay, and then try and insert the code I took out before that actually makes the cache work properly. If that still doesn't work as well as I hope, then I'll change it all again and make it a simple queue.

It should also be noted that the remaining 6.5k is IT. There is no more free memory after this runs out, which means if I need more space, then I need to start cutting things out....Lets hope it doesn't come to that.

Wednesday, November 08, 2006

XeO3: Sprites....damn them....

Well, Russell and I have discussed this cache problem at length, and came to the simple, resounding conclusion - I'm a moron. When I started doing the sprite routine some 6 years or more ago, I hadn't done any real 6502 in anger (as it were), for over 10 years before that! And when I designed it, I used normal structures of things. This is bad. In 6502 you really want to use the index registers and multiple arrays for structs. Like this.....

dw Next
dw Last
db index
db flags
ds 8
ds 72

But instead, you should really do this....
NextIndex   ds  140
LastIndex ds 140
index ds 140
flags ds 140
GfxLo ds 140
GfxHi ds 140

Now, you really have to wonder why I haven't clicked with this before since my scripting system does just that! Well, now that I know, I'll make it part of the rewrite of the sprite system, but this is a pretty large undertaking and will take time...... bugger.

Anyway, even after I do all this Im still not sure I'll be able to use the cache to its full. Even at 40-50 cycles, thats almost a full scanline, and with 10 sprites, thats a lot to waste every game cycle. With a simple circular list, you only lost around 20-30 every minute or so....

Doing this change will also allow me to remove the redundent 8 bytes in each sprite-cache block, which will help save space overall.

Tuesday, November 07, 2006

XeO3: The Sprite Cache.

I finally got around to visualising the sprite cache, and in doing so I was in for a shock. It wasn't working! Well, not the way I'd planned. When I originally designed it, I had intended for sprites that were used a lot to stay in the cache, so I'd used a doubly linked list so that I could unlink and entry and place it at the bottom. This would then keep it as far from the TOP (which is the next free slot) as possible. Its a simple idea that works extremely well when used with textures on the PC. However, mine wasn't working - in fact, all that was happening was I was operating a simple queue system. It came off the front, and went on the rear. This means that when enough baddies have passed, I have to recache the graphics that are still in use - like the player ship. This wasn't the idea at all!

So, I added the missing code to push it down to the bottom of the stack where it would stay until it hadn't been used in ages and then it would get freed and used again. However...being a ful 16bit doubly linked list - it isn't quick, and sprite engine takes a hammering because of it; way too much in fact. So now I'm left wondering if I should in fact scrap this idea, and just use a simple queue. This would help speed up allocations, but I'd still have the same issues I have now - which you don't really notice anyway!

I'm just not sure.... the whole concept of the sprite system came about because I wanted to use the texture cache idea to help keep things fast, and now thats the code thats slowing it all down!


XeO3: ZZZZZZZZZZzzzzzzzzzzzzzzzz..............

Yep....did nothing but sleep again last night..Oh well... Just as well this isn't my day job.....

I have been thinking about the absolute limits of memory I can free up though, and I reckon I can claw back around 4k from various sources - tops. After that, I need to start cutting features.

   1k  -   Sprite Cache by seperating all the sprite data from from the sprite structure.
1k - Sprite definitions. Just now there is a 16bit pointer to a cached rotation,
if I change this to a cache number, I can save 8 bytes per sprite *167 sprites,
but I'll then need a 300 byte look-up table, so gain around 1k overall.
1k - Paths. I really dont think Im going to need a full 4k for the scripting. The levels
aren't that long really (compared to Blood Money which used 4k for paths as well),
so I can probably cut at least 1K, possibly 1.5k
1.5k- Theres currently a free block right at the top of memory of 1.5k which Im desperately
trying to hold on to, but if push comes to shove.... it'll have to go too.

Now this is a fair bit to free up, and the sprite stuff will take a little bit of work but once done, that should set us on course to finish up the main code. wow....code complete...who would have though it... Still, not there yet!

The to-do list is currently...

  Finish Weapon system
Finish loader with the new Turbo Loader
Add loading screen
Add High scrore table to the front end (top 10)
Save High scores to disk
Add TED music player - if possible
Add multi-load for more levels (make sure its a variable number for skining later)
Do a TEST level that we can release to help get the difficulty right.
Make all levels
End sequance - even if its a simple one

I think that about covers it..... Still lots to do, but we're over the hill and rolling down the other side.

Sunday, November 05, 2006

XeO3: Another day, another feature....

I've been playing with the sprite routine again last night, and came up with a nice little feature that I'll use when baddies are shot. As you can see the sprites now turn completely single colour and flash when they get struck. On the C64 something this is pretty easy to do since each sprite has its own colour, so you can just flash that - but when drawing software sprites, its not as simple - this is in fact a whole new sprite! Or is it.... All I do for this is to use an inverse of the AUTOMASK and ORA the data into the display. The automask if you'll recall is a way of automatically masking MCM pixel data, and given any sprite the automask works out the data needed to MASK it on - so invert that, and you have your FLAT sprite.

Like everything, its not without its expense. It costs around 200 bytes for the code, and is slightly slower (when a sprite is over space) than normal. But it only happens every now and then, and being able to tell you've hit something is great, particually on baddies that take plently of wallop - or ones with limited collision areas - like a BOSS or something.

I also had to get Luca to swap all the colours to make use of it as it must use colour bits %11 or I have to AND as well.... Still, its a neat little touch so we'll probably try and keep it in.

Its also that time again, and I have to go hunting for memory once more. I've decided to rewrite yet more areas of the sprite routine - mainly the data structures as this should save around 2k overall - quite a saving. But theres a lot of work involved; I'm going to replace the cache pointers with a cache index (and a small table). Also, due to the way I move sprites up and down, I have 8 bytes at the start of every cache block to allow for a sprite to move down (I move the draw pointer up 1, the sprite gets drawn down 1 pixel mode), and because these are located directly beside the cache info, I have to repeat these 8 bytes all the time. However, if I split up the INFO structs, and the DATA itself, I can store 8 bytes at the start, and then remove all the others - again, a small table will probably suffice.

Saturday, November 04, 2006

XeO3: Faster and faster....

The thing I love most about fully open development is that no matter how clever you think you've been, and how well you think you've written something, someone almost always comes along and improves it! It's not that I'm bad at what I do, or that the other person is way smarter; no, it's simply that a fresh pair of eyes and a different brain can pickup on small things you've missed. This is especially true if you've been staring at the same few lines for months trying to improve it. You're brain gets into a rut, and you just can't get past what you see. Open internet development gets rid of this by allowing anyone on the web to help. Sometimes the codes so obscure that no one can understand it - but thats fine, your no worse off... But other times, its a nice small snippet that someone points out something and you slap your forehead and say "why didn't I think of that!!"

Heres a case in point.... Some time back I was struggling to find a faster way to fire bullets, and it took me several days to come up with what I thought was the perfect solution - and to be fair to me, it was pretty spiffy. So I happily posted it for everyone to see and use. Heres the original...

FreeList db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,$ff
; Usage:- AllocBullet [x|y] Specify the X or Y register that hold the bullet to free
AllocBullet macro
ld\0 FreeIndex ; 3 ldx FreeIndex
lda FreeList,\0 ; 4 lda FreeList
bmi !NoneFree ; 2 bmi !NoneFree
in\0 ; 2 inx
st\0 FreeIndex ; 3 stx FreeIndex
ta\0 ; 2 tax
dec BullInUse,\0 ; - dont count this... its not in the new one.
ta\0 ; 2 = 18 tax X=next free bullet (or $ff for none left).
; (best case=12) Negative flag SET on none left

Now, this was a pretty fantastic improvement over the original which was just a loop through "N" bullets. It was fast, it didn't matter how many bullets you had to allocate from, the time was linear. Great! Then along came TNT (who incedently is doing a cool remake of paradriod), who quickly pointed out that if I reversed the stack it would be even quicker - like this:-

AllocBullet macro
ld\0 FreeIndex ; 3
bmi !NoneFree ; 2 (best case=6)
lda FreeList,\0 ; 4
de\0 ; 2
st\0 FreeIndex ; 4
ta\0 ; 2 = 17

Now I had fiddled with the routine for some time, but had missed this simple switch, and this is the great thing about open internet development. My game goes faster, and I hardly had to lift a finger! While it appears to be a small change, allocations happen all the time, so if you can knock of a cycle, or make it early out quicker, then its all good.

Anyway.... the reason for all this is that I've been retro fitting all my allocators with TNT's new version, and it reminded me why I'm doing all this in the first place: Open Internet Development is good, for a retro scene - its vital!

XeO3: Surprise Surprise!!!

I've spent the evening playing with the main game again, this time adding a couple of new cool features that we'll keep quiet about for the time being. However I was also adding the speedup I was on about yesterday to the X axis this time and in doing so I managed to speed up Y a bit as well. Doing this then led me to this new feature - its pretty cool, and its somthing that a C64 would struggle to do properly - if at all! The current thinking is that each port of the game will actually have quite a bit different, to the extent that some would say its not a true port, but a different game. While I could cripple one version to make anothers more like it, I don't want to - I want each machine to be pushed to its limits, even if that means adding features that the other versions won't have!

Purists will complain that they want XeO3 ported exactly, but I think having a great game - regardless of what the original looked like - is more important. It also means there may be several new games fo people to play which look only vuagely like each other. The style and baddies will be the same, but I suspect the levels and probably the paths they follow will all differ - weapons should be fine though. If someone wants an identical port - they can do it themselves by mixing code from one playform to the others.

However, this also free's me up to use the C64 sprites better, have more detailed backgrounds and all that this entails, and it also means that the spectrum version can push its own strengths - should be good!!!

One thing has occured to me though, I'm going to have to untangle the sprite routine from the Plus/4 version into some sort of framework so others can use it properly! Its a bit intertwined just now and some might have difficulty extracting it....

Thursday, November 02, 2006

XeO3: Go faster sprites....

Just had a small brainwave..... Normally 16x16 sprites actually draw 24x24 due to rotation, however when the sprite "fits" perfectly inside a 16x16 (say its coordinate is 0,0 and hence has no actual rotation), you can drop the surrounding characters. While drawing the chars themselves don't take long, they still have to get masked. BUT! becasue +4 sprites are character based, so is my clipping routeing, which means I can drop any individual character from the sprite simply by flagging the character its about to overdraw as $FF. This is how I do clipping off the top and edges, I just have a table of indexes some of which point to $FF characters.

Normal NoY NoX NoX&Y

Anyway, what I now do is check to see if the Y coordinate has a fractional component, and if not, I set the bottom row to be clipped! If we still have to draw the full 24x24 sprite (which is most of the time), then this only adds 30 cycles PER sprite(300 over all), which isn't much - really. However, if we find we're dipping below our desired framerate I now have another tool to help speed things up. Take a sprite that simply flys across the screen, well if I make sure this sprite does this on an 8 pixel Y boundary, then its always going to be significantly faster due to the fact it will never draw the lower row.

I could do the same on X where I drop the last row, but because of the scrolling, this won't happen very often... I'll probably try it and see, but I think the Y check is good enough.

RetroEdit: Cleaning up.

Okay, back to real work again.... I'm cleaning up my RetroBitmap control and converting the rest of the application to use it, which is taking a little longer than planned. I now also have to re-evaluate whether I want to have a per-sprite HIRES/MCM switch. While not really important for a C64/Plus4 it might be down the line if I decided to add Amiga editing and add a "number of colours" mode. This might mean you couldn't edit 16 and 32 colour sprites in the same project. However, changing each sprite can be a pain depending on what your doing. I'm still not sure how I'll handle this, but Im edging towards each sprite still having their own mode.

The Control now renders everything correctly and I can now play animations back as before, although I've still to add the all important keyboard short-cuts. The control can now also be any size (although, there may be invalid combinations like a 13x13 in MCM etc.) and can render to any size bitmap. The bitmap is public so that you can replicate it in other controls; I for example scale it and use it to display the various sizes of the sprite without having to re-render it. I hope to add some sort of custom exporter-pluging system (at somepoint) so you can save your own formats. I was reading the discussion on WorldOfSpectrum forums and they were talking about a funny zig-zag format. I'll try and add all the common ones from the start, and then let you do plugin's for any new formats.

All this is pretty far down the line....Possibly even after XeO3 is finished. Also, I plan to save everything in some sort of IFF format (project files that is) so that they are easy to disect; if anyone else has an opinion, nows the time to object. I was considering just using some of C#'s native serializing stuff, but I want folk to be able to extract stuff from it if then need to.

Oh...and one last thing..... Do people just want a load of sprites that the can "view" as animations, or do they want a list of anims that the program orginises nicely for them? Just now I have (say) 167 sprites, and I set IN and OUT points and then view the anims. This is very easy to use, but it means I cant set up say a "baddie" animation and save out delays etc. But usually these numbers are different for each program so its not worth it..... anyone have an opinion on that?

Wednesday, November 01, 2006


I've now finished my new uploader, and it's actually turned out to be a fairly good idea. I've been using my MMC64 to upload and play C64 games. It turns out however, that it just isn't very good as some file - anything really big I suspect. I have several .PRG files which I thought had gotten corrupted because the MMC64 wouldn't run them properly, however, my download program manages fine. This could be for a few reasons though. The MMC64 hasn't actually started BASIC yet, so it may not have everything ready to run these programs, or it might be that its not setting up certain BASIC addresses for the unpackers or something. Or it could just be that its too big and simply won't work.

Whatever the case, my uploader manages these games fine! It takes around 6 seconds to transfer a full sized C64 program which is pretty quick. I currently use the MMC64 to load the boot program which is much quicker than loading off disk, and then my command line tool to send the .PRG file I want to run. I'll probably expand this to include .P00 and .T64 files as well as these are pretty simple and would be quite handy. I could write a little GUI tool I guess, which would be particually handy if all you're doing is running games. But I suspect most people have other ways of getting stuff to the C64 (let alone having to build the cable( so I'll not worry about it just yet.

Anyway, if you want it.... you can download it from my minus4 site, It includes the to .PRG files for the C64 and the +4, both are tiny and if need be, could be typed in. The wiring diagram is in the text file - Enjoy!

I'm also planing to port my DEBUGSTUB I have for the Plus/4 over to the C64, as this will let me control the C64 fom the PC. The initial plan was to write a full and proper remote debugger, complete with source level debugging. I got as far as being able to start/stop programs, and then single step them but it needs lots of work. However, as a side line, this program lets me control the Plus4 completely from the PC side, meaning I can download images, sounds and tools to it and use it as a slave for editing. Imaging having a PC editor that shows you the graphics on the PC AND on the Plus/4 as you draw them. This would be extremely handy as viewing on a TV changes things hugely. If I ever learn enough electronics to be able to build a Spectrum interface, then I'd probably add this kind of thing there as well.... RetroEdit could be turn out to be extremely cool.