saturday, 11 august 2007

posted at 14:09
  • mood: unfocused
  • music: jch - carcrash

I feel like I should write something, though I haven't really done much lately so this is going to be boring.

I went back to work this week after a wonderful week off, and I really didn't want to be there. Its been a frustratingly slow and boring week, but it got better towards the end. Next week should be much better as we're finally ready to begin installing production servers rather than treading water like we have been for the last few months.

I haven't written any code in the last week, mostly because work has been so draining. My bus trips have consisted solely of playing Advance Wars, which is still as good as ever although its starting to get harder and I'm really having to think hard, which means I lose a lot on a week like this one.

I still need to fix up the circle routine. I bought a nice pad of graph paper and when I feel like it I'll sit down and work out the maths again from first principles, as I don't fully understand Steve Judd's algorithm. I still see no reason why a convincing tunnel effect shouldn't be possible. I'm eager to get it out of the way because I really want to a filled 3D polygon spinner; I have a neat idea for a technique that should make the thing fly.

On the day I bought Advance Wars I also bought a C64 DTV. Its very cool, and I'm really excited about the idea of building a full computer out of it - its a C64 but with some nifty new features, mostly new graphics modes and more colours. I noticed the colours were really washed out so some searching revealed a detailed analysis and fix of the problem. I implemented it on Sunday night, in a horribly hackish way with big chunky resistors across SMD resistors, with a pair of pliers and my bulky old soldering iron. My games now look beautiful.

My two goals for my DTV is to build it into a keyboard, and to give it a SD card reader. Its still pretty far off, but it should be a fun project.

That reminded me of just how much I enjoy doing electronics work, and I've always wanted to design and build a computer from scratch, so I started looking into that again. Of course I love the 6502 and friends, and I always assumed that that is what I'd use. These parts are just a paint to get hold of though (no local source), so I've been looking for something else. I've pretty much settled on the Atmel AVR line of microcontrollers - the instruction set looks closer to the 6502 than the main alternative, the Microchip PIC, and seems to have less limitations.

For my first trick, I want to implement a video generator, which would eventually become the video subsystem for my computer. I've found a couple of projects where people have done this before (AVR-based or PIC-based), and it doesn't seem overly complicated. Initially it'll be a standalone generator with perhaps a simple command setup so that an external processor can drive it, but there'll be no general-purpose framebuffer (ie, user programs won't be able to draw directly). I will want the ability to do direct drawing eventually though, which means DMA blitting, memory sharing (eg like the C64 does with its wacky CPU-disabling stuff, or dual-channel RAM. Or maybe something else, I don't know yet. Its why I'm avoiding it for now :P

I decided that if any of this is ever going to happen, then I'm going to have to do it a little bit at a time - if I wait until I have time and money to do it all at once, it will never happen. To that end I went to Jaycar last night and bought a logic probe, something I've been hankering for for over 18 months. The game is afoot!

sunday, 22 july 2007

posted at 16:01
  • mood: ninja
  • music: jeroen tel - cybernoid ii

I've been working on the polar coordinate plotter over the last few days, and I'm making some good progress. This, however, is not a circle:

I know why its happening, but haven't yet worked out a fix. I'll blog about it later, once it get it working properly.

Anyway, I wanted to do something different in the spare couple of hours I had yesterday, so I wrote a little tool for working with character sets. Its available over at toybox: 64charset

It has three basic functions: create a charset from a definition file, decompile a charset into a definition file, and view a charset. What this gives is the ability to edit a character set in a text editor. Its not as convenient as working in a real editor, but for quick edits and hacks you can't beat it.

It was a hell of a lot of fun to write, and I had the whole thing working in about three hours of actual work, which I was really impressed with. Perl is just an incredible language for getting shit done fast. This fact is nothing new to me, I've been using Perl for as long as I've been using Unix, but every now again you get reminded of just how truly excellent it can be. The SDL bindings are pretty awesome too.

tuesday, 17 july 2007

posted at 17:30

Over the last couple of days I've finally made some decent progress with the C64 version of the tunnel:

My reflection code isn't quite right yet, so its disabled here. The fact that this is a static image isn't really hurting you much - if you were running it for real, you'd being watching it in all of its glorious three frames per second. Pretty woeful, really.

I haven't really optimised the code much. I did spend some time on the plot routine this morning, which can now plot a single [x,y] point in 54-55 cycles. I feel like I should be able to shave perhaps ten cycles off, though I'm not seeing where yet. My clear routine, as usual, is the killer - its still a naive implementation that clears the entire bitmap. I attempted to make it a little smarter by having the plot routine record which page its writing to, and only clearing the dirty pages (via some hefty unrolled loops) which gained a me a single FPS, but its not really enough. I want to only clear the points that were plotted, but at a potential 4096 plots (64 rings x 64 plots per ring, since every eighth point is plotted), the cost would be prohibitive - it would take 8K to store all the memory pointers for those plots, which would at least triple the time taken to clear as the naive approach! I need to think on this more.

The real killer though, seems to be the fact that every point requires a bunch of table lookups, at least three: the ring offset indexes, then the ring offset itself, and the ring point position as well. I don't see how I'm going to able to optimise this much. It is in a tight loop so even small gains should make a difference, but I'm hoping to get this thing at least to 25 FPS (50 seems a far off impossibility at this stage).

I do have another idea though. Since the whole thing is just drawing circles, it occurs to me that rather than using a [x,y] plotter, I could be better served by a [r,θ] plotter (ie one that uses polar coordinates rather than cartesian coordinates). This way I could do away with all the circle table, because the rings would just drawn by looping θ from 0 to 255. Each ring is achieved by looping the radius.

Of course, the plotter then needs to know how to convert r and θ into memory locations, but that should be easy enough with appropriately-constructed tables. The equations for converting polar coordinates to cartesian coordinates are:

x = r * cos(θ)
y = r * sin(θ)

That multiply is a problem, but I've recently found out about a super-fast multiplication technique based on logarithms. In essence:

f(x) = x^2/4
a*b = f(a+b) - f(a-b)

So we keep a table of squares which lets the multiplication happen very quickly. After that, the x and y offset are added and the point is converted to a memory location and plotted. I'm hoping that by spending some time working on the tables I can embed a good amount of the memory location stuff in the tables themselves, reducing the amount of work that needs to be done.

I've still got half an hour of bus trip left. To work!

sunday, 15 july 2007

posted at 16:56

Its been another busy week. As expected, work was crazy, and will continue to be for a few weeks yet, so its unlikely that you'll see massive amounts of code coming from me; I'm just too tired after a whole day of hacking too. But I still get little bits done, and make steady progress.

I'm still working on the tunnel. During the week I put together a first cut of the code, which naturally didn't work. I'd hadn't realised just how much debugging tools make life easier. Its being a complete pain to debug - I can't print values out at key points! I have the VICE monitor only, which only lets me inspect memory, and since my intuition hasn't come back yet those numbers are really difficult to use without a good mental model. I have managed to debug my point plotting routine so far, so thats something. Next time around (tonight if I'm not too tired, otherwise on the bus tomorrow) I'll be stripping back the code to a straight circle drawing routine, and then building it back up from there. I have a feeling this may yield some optimisations in the end, as in my efforts to port my C version I lost sight of the fact that all this routine needs to do is draw circles of various sizes, nothing more. Here's hoping.

I had a bit of an epiphany this morning about how to make filled multicolour vectors run really fast. It works off the fact that only the face edges have more than one colour. The areas within each face are just a single colour.

Naturally, I'd expect that I'd just have to fill in each and every pixel in that space, but not so. Since they're just solid blocks of colour, I can modify the value in the colour map and effectively "paint" an 8x8 area by just storing to a single memory location, rather than eight (assuming a heavily-optimised routine). Clearing also becomes easier - only the locations that have an edge on it need to be cleared, again speeding things.

I have to assume that this technique has been thought of/used in existing routines, because filled vectors got boring in 1994, but I'm still happy that I came up with the idea independently. Improving my vector code will be my next trick after the tunnel, I think.

friday, 6 july 2007

posted at 22:01

I have a development environment for demos! I didn't have much luck figuring out the cc65 linker - I think its really meant for "proper" linking, like real relocatable Unixy kind of things (and I'm being highly descriptive, I know). The assembler is good though - I like the format (very close to Turbo Assembler), and via cl65 its trivial to run.

So, I've written a couple of tools to make things work the way I want. 64asm loops over all .s in the current directory, extracts their start address from a .ORG directive, and calls cl65 to assemble them. The start address gets embedded into the filename for 64link. This one takes multiple files with their load locations in the filename, loads them all into a "virtual" 64K memory space, and then spits the whole lot out in a format that can be loaded directly by a C64. Now building a demo part from source and pulling in all its necessary pieces (music, graphics, tables, text, etc) is two simple commands. The gory details are over at toybox.

There's a few other tools I'll need as time goes on - a sine/cosine table generator, an ASCII-to-screencode and a code relocator, and probably others. I'd also like to write a proper 64 assembly mode for VIM with syntax highlighting. And while we're at it, a crazy-smart hex editing mode for VIM would be totally awesome - every hex editor I've tried so far is complete pants.

I've been refactoring an unreleased demopart from 1997 to get a feel for the new setup. Its working perfectly, which makes me happy. I wrote some rather shoddy code in those days so I've been able to clean up a fair bit of it. Most notably, I've removed all the self-modifying code - its really not a smart idea. I've also been adding comments, but its tricky - I didn't write any comments the first time, and the whole thing is based on some rather complex maths I worked out when I wrote it (reducing rotation matrix calculations so that there's no multiplications in it), so I don't quite get all of it. Its proven the development environment is solid though, which makes me happy.

Next is to implement the dot tunnel :P

thursday, 5 july 2007

posted at 15:56

Fast update, just about to head out of the office for another day.

Work has been psychotically busy, leaving me with very little brain space at the end of the day, so I haven't done much code in the last few days - its just too hard to think. What I have been doing is updating my entry and the System entry over at the CSDb. Finally, you can get some insight into where I came from. There's still a bit of stuff to upload and cross-reference, but its much more complete than it was a week ago.

I'm also idly pondering this demo that we're wanting to make. I've started experimenting with the assembler portion of cc65, because it seems to have pretty much everything that I might want. I'm not yet sure how to get it to link things using a custom memory map rather than it just assuming it has the run of the place, but I think I know where I'm going wrong. I'll have another crack at it on the bus, using the vector part I wrote TEN YEARS AGO this month. Good grief.

After that I guess I'll poke at something AROS again. I am unfocused at the moment, but I'm fortunate that AROS is too - there's plenty of places where I can fiddle for an hour, fix or add something tiny, and it still counts as progress.

thursday, 28 june 2007

posted at 16:07

Last night I took a break from AROS and starting fiddling with some graphics stuff. A few of us old Aussie C64 guys are planning a get together soon, with a hope of producing a new demo. Whether that will happen or we'll just end up drinking or goofing off remains to be seen, but I'll go in with the best intentions.

Something I always wanted to write for the C64 is a dot tunnel. Its pretty simple in concept - plot a number of concentric rings and move them about in such a way that it looks like you're flying down a never-ending circular tunnel. Last night I started fiddling with the concept using SDL. This morning on the bus I got the last kinks out and came up with this:

I brought it into work and showed Sam (our resident math/graphics geek), and suggested drawing some lines to see the effect better. I hadn't thought of this initially because there's just no way the C64 will be able to cope with plotting that many points each frame, but it was certainly worth a look. We made it plot lines instead of dots to draw the circles, and then added some nice lines in between the circles to give even better depth:

(It looks better when its moving, really).

Its a great hack, with no real 3D involved. At boot it calculates 64 circles with ever-decreasing diameter, and two tables (one sine, one cosine) for the movement. Each frame it computes the new location of the inner circle, but remembers the previous locations and plots each other circle at one of the old positions, moving outwards. Its kinda hard to explain here in text, but I can post some code if anyone is interested.

I've done some basic sums and at least 20KB, possibly up to 40KB (depending on how I store the graphics and the ninth x-coordinate bit) of table space will be required to port this to the C64. Should leave just enough room for colour, music, code and a loader :)

friday, 22 june 2007

posted at 11:35

I just dug out my copies of C64 demos by System and all the source code I could find for stuff I wrote at the time. Most of it is going to be unintelligible unless you've done C64 assembly yourself, but its useful for historical purposes, I guess. All I ask is that you be ignore the poor readability, lack of understanding of the hardware features, self-modifying code, and combination of angst and bravado, both misguided. When you're a teenager (this code ranges from 1992-1998, so I was 12-18) you say stupid things :)

(Shockwave has more stuff that may or may not include stuff by me. Same warning applies).