saturday, 12 june 2010

posted at 21:32 | comments

Today I declared myself officially on the Google Wave bandwagon when I released a tiny Wave client called ripple. I wrote it to see if it would be possible to make Wave work in only HTML, something we may soon want for work if we're to provide an accessible alternative interface to Wave for our users.

From what I'm hearing from the Wave crew, this is also the first example of doing something significant with Wave in Perl. That's exciting.

There's more detail on the splash page, but here's some quicky links to get you started:

friday, 14 may 2010

posted at 09:28 | comments

Another little program from my toolbox. This one I'm quite proud of. Its a tiny little file transfer tool I call otfile (that is, one time file).

The idea is this. Quite often I need to send a file to someone on the work network. These can vary from small data files or images to multiple gigabytes of raw data or confidential documents. Our network is fast and the network and servers themselves are considered secure so I don't have to worry about eavesdropping, but there's a real problem with the transport mechanisms - they all suck.

I can put the file in an email, but there are transmission and storage size restrictions. Its also fiddly - create message, attach file, send.

I can put the file on a web server, but the only ones I have ready access to are publically-accessible, so I have to set up an access control. If its a large file then I have to think about disk space on the server (usually an issue) and then I have to wait while the file copies before sending the recipient a link. Oh, and I have to test that link myself because invariably I've screwed up file permissions or something else.

Probably the closest to what I want is file transfer via IM, but for various reasons that's currently blocked at the network level. I could probably get that block changed but it'd mean a bunch of negotiations for something that isn't actually related to my job. Its not worth my time.

So I wrote otfile. You run it with a single file as an argument, and it creates a web server on your machine with a randomised url for the file. You paste the url into an instant messaging session (I'm chatting with my team all day long). They click it, file downloads directly from the source, and then crucially, the script exits and the web server goes away. That url, while open for anyone to connect to, is near impossible to guess and only works once. That's secure enough for me.

The major thing I think this is missing right now is the ability to do multiple files at once. Its not that big of an issue because its pretty easy to run multiple instances - just a shell loop. If I went for multiple files I'd have to decide if I want to make it produce multiple urls (a pain to paste and to then require someone to click on them all), produce a directory listing (what are the semantics? when do the files disappear? when does the server shut down?) or build some kind of archive on the fly (cute, but is that painful for the receiver?). I'll probably just dodge it until I use it like that enough to be able to ask the receiver what they would have expected.

#!/usr/bin/env perl

use 5.010;

use warnings;
use strict;

use autodie;

use File::MMagic;
use File::stat;
use UUID::Tiny;
use Sys::HostIP;
use URI::Escape;
use Term::ProgressBar;

use base qw(HTTP::Server::Simple);

my @preferered_interfaces = qw(eth0 wlan0);

say "usage: otfile <file>" and exit 1 if @ARGV != 1;

my ($file) = @ARGV;

open my $fh, "<", $file; close $fh;

my $mm = File::MMagic->new;
my $type = $mm->checktype_filename($file);

my $size = (stat $file)->size;

my ($fileonly) = $file =~ m{/?([^/]+)$};

my $uuid = create_UUID_as_string(UUID_V4);

print "I: serving '$file' as '$fileonly', size $size, type $type\n";

my $server = __PACKAGE__->new;

my $interfaces = Sys::HostIP->interfaces;
my ($ip) = grep { defined } (@{$interfaces}{@preferered_interfaces}, Sys::HostIP->ip);

my $port = $server->port;
my $path = "/$uuid/".uri_escape($fileonly);
my $url = "http://$ip:$port$path";

print "I: url is: $url\n";

$server->run;

my $error;

sub setup {
    my ($self, %args) = @_;

    print STDERR "I: request from $args{peername}\n";

    if ($args{path} ne $path) {
        $error = "403 Forbidden";
        print STDERR "E: invalid request for $args{path}\n";
    }
}

sub handler {
    my ($self) = @_;

    if ($error) {
        print "HTTP/1.0 $error\n";
        print "Pragma: no-cache\n";
        print "\n";
        return;
    }

    open my $fh, "<", $file;

    print "HTTP/1.0 200 OK\n";
    print "Pragma: no-cache\n";
    print "Content-type: $type\n";
    print "Content-length: $size\n";
    print "Content-disposition: inline; filename=\"$fileonly\"\n";
    print "\n";

    my $p = Term::ProgressBar->new({
        name => $fileonly,
        count => $size,
        ETA => "linear",
    });
    $p->minor(0);

    my $total = 0;
    while (my $len = sysread $fh, my $buf, 4096) {
        print $buf;
        $total += $len;
        $p->update($total);
    }

    $p->update($size);

    close $fh;

    exit;
}

sub print_banner {}

I really need to set up a repository for things like this. Not hard to do of course, I'm just not sure if I should have one repository per tool, even if its just a single file, or all these unrelated things in one repository. I'll probably just do the latter; its way easier to manage.

wednesday, 28 april 2010

posted at 22:36 | comments

Its kind of hilarious that out of everything I've done in the last couple of months this is the thing I decide to come up for air with, but its been that kind of a day. This is the result of three hours of study and hacking. Its using the new IMAP OAUTH mechanism implemented by Gmail to let me login as one of my users via IMAP.

#!/usr/bin/env perl

use warnings;
use strict;

use Net::OAuth;
use URI::Escape;
use MIME::Base64;
use Mail::IMAPClient;

# user to connect as
my $username = q{some.user};
# apps domain
my $domain   = q{some.domain.com};
# oauth consumer secret. dig it out of the "advanced settings" area of the apps dashboard
my $secret   = q{abcdefghijklmnopqrstuvwx};

my $url = 'https://mail.google.com/mail/b/'.$username.'@'.$domain.'/imap/';

my $oauth = Net::OAuth->request('consumer')->new(
    consumer_key     => $domain,
    consumer_secret  => $secret,
    request_url      => $url,
    request_method   => 'GET',
    signature_method => 'HMAC-SHA1',
    timestamp        => time,
    nonce            => int(rand(99999999)),
    extra_params => {
        'xoauth_requestor_id' => $username.'@'.$domain,
    },
);
$oauth->sign;

my $sig = $oauth->to_authorization_header;
$sig =~ s/^OAuth/'GET '.$oauth->request_url.'?xoauth_requestor_id='.uri_escape($username.'@'.$domain)/e;
$sig = encode_base64($sig, '');

my $imap = Mail::IMAPClient->new(
    Server        => 'imap.gmail.com',
    Port          => 993,
    Ssl           => 1,
    Uid           => 1,
);
$imap->authenticate('XOAUTH', sub { $sig }) or die "auth failed: ".$imap->LastError;

print "$_\n" for $imap->folders;

I guess three-legged OAuth would be pretty similar to get going, but I don't have a particular need for it right now.

thursday, 4 march 2010

posted at 09:51 | comments

Nothing big to report, just work plodding along, so here's an update in pictures.

Here's the fully assembled N64 RGB DAC board:

It's not currently working though, so some debugging is required. When I hook it up I get no picture, and occassionally it seems to short out the whole console. I haven't really had time to diagnose it properly yet. I'm mostly waiting to figure out a systematic approach, since its all a bit confusing right now.

My other project is the USB-to-N64 controller bridge. I've written a lot of AVR assembly for this so far but haven't done any actual hardware work. Its coming very soon though, so I very carefully removed the cable from one of my controllers (so I have the option of putting it back together later) and added some pins to the end so I can connect up a breadboard:

This is my first outing with shrinkwrap tube and it was a breeze. My wife has a hot air gun that she uses for her craft work, mostly with embossing inks, so I borrowed it and it worked brilliantly. I was surprised at how much physical strength it actually gives.

This is the insides of my N64:

The large ribbon is the digital signal tap for the RGB DAC, soldered to the inputs on the existing composite DAC chip (easier to solder to that chip than to the much narrower output pins on the video chip. The brown/black pair in the left is the 3.3v power feed for the RGB DAC. Over there on the right under everything is a DE9 D-sub connector with lines for the outputs from the RGB DAC (the narrower ribbon), audio from under the multi-out (the purple/gray/white ribbon) and a 5v line that's needed for some SCART signalling (the fat red wire). Right now its actually hooked to a 3.3v line under the board because I was testing something. Soon I'll hook it instead to the 5V regulator you see just to the right of the composite DAC.

Finally, some recent ebay loot:

Clockwise from top left: a pack of 78L33 3.3v voltage regulators; a sheet of 6 74HC374 8-bit latches and 4 74HC04 inverters; an anti-static pack containing two ATmega88 microcontrollers; a giant roll of 560-ohm 1% resistors (190 left on the roll); a tube of 74HC04 inverters; and a pack of 10n ceramic capacitors (which I use for IC bypass caps).

As I've mentioned before, ebay is an incredible source of cheap parts. There's less than $30 of parts in this picture, and that's not everything I've bought recently. I love getting home every second day and there's a little parcel waiting for me!

tuesday, 9 february 2010

posted at 08:49 | comments

My laptop has had an interesting couple of days. The main filesystem went read-only a couple of nights ago after a couple of random journal errors. After being fsck'd and cleaned up it did it again, so I reinstalled it and restored it from backup yesterday. Then last night it overheated, leading me to open the case and clean the wall of dust out of the fan. Its back together now, but a couple of lost of tiny parts means I have no indicator lights and no trackpoint. Fortunately the trackpad still works, but its taking a little getting used to. On the other hand, its not burning my lap or my hands anymore, so its probably an overall victory though its not quite feeling that way yet.

One of the things I did lose in the rebuild, due to it not living in one of my backup locations (which is /etc/ and /home/rob) is my cute little mobile roaming script. I rewrote it on the bus on the way home yesterday and thought that perhaps its interesting enough to post here.

The basic idea is that every day I switch between at least two networks. My home network has a PC in the hall cupboard which among other things runs a web proxy and a mail server. Its also the firewall, so web and mail traffic can't go out directly. Work on the other hand, implements transparent proxying (with some network authentication) and has a SMTP server, but naturally it has a different address. I also occassionally use other networks (friend's places, coffee shops, etc) which usually have no facilities at all, requiring me to fend for myself.

My laptop runs a SMTP server (Postfix) of course, because that's just what you do on Unix. I also run a Squid proxy which I point all my local HTTP clients at. This way, when I move networks, I only have to reconfigure the local proxy rather than tweak every web client I have.

I spent a long time looking for a decent roaming reconfiguration package, but I never managed to find one. Some would try to do network detection and too often get it wrong. Some would have overly complicated and/or feature deficient configuration languages. I vaguely recall that I really liked one of them but it was tightly integrated with NetworkManager, which I don't use because it could never seem to keep the network alive for more than a few minutes (and it appears to be pretty much tied to the GUI, which is painful when I need network on the console).

So, in the finest open source tradition, I rolled my own. The script itself is trivial; its just a tiny template expander. I'll list the script in a moment, but first I'll talk about its operation.

The script, which I call location, takes a location name on the command line (like home or work), runs over a (hardcoded) list of config files, reads them in, modifies them, and spits them out to the same file. It makes modifications according to templates that may exist in the file. If the file has no template, then location ends up emitting the unchanged file.

In any file you want it to modify, you add an appropriate template. This is the template I have in my /etc/postfix/main.cf:

### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE

When it finds itself inside a template, location stops its normal operation of outputting the lines of the file as-is and instead starts parsing. Interesting lines begin with ##, anything else is ignored. Its the third character that determines how the line is interpreted. So far I have the following functions:

  • #: do nothing, just output the line
  • @: emit if at location. If the location specified on the command line matches the first argument to @, then the rest of the line is added to the file as-is.
  • !: run command. Calls a shell to run the specified command after the file has been generated.
  • >: interpolate line. Include the rest of the line in the file, but expand any %variable%-type markers. So far only %location% is defined, and is replaced with the location specified on the command line.

(I'll provide an example of that last one in a moment).

So in the case of main.cf, lets say we ran location with home as the location. This would result in the template section being written to the output file as:

### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE

The listed commands are then run, which cause Postfix to be restarted and the mail queue to be flushed:

/etc/init.d/postfix restart
sleep 1
/usr/bin/mailq -q

Naturally Postfix interprets the template parts of the file as comments, so nothing to worry about. The next time location is run, the "bare" relayhost line is ignored, so it doesn't get in the way.

The config for Squid is similar. Because Squid's config file is huge, I don't quite trust my script to handle the whole thing sanely, so at the bottom of squid.conf I've added:

include /etc/squid/location.conf

And in location.conf I have:

### START-LOCATION-TEMPLATE
##@ home cache_peer lookout.home parent 8080 0 default
##@ home never_direct allow all
##! /etc/init.d/squid restart
### END-LOCATION-TEMPLATE

By default Squid will try and hit the internet directly, which is fine for work and unknown locations. For home, i need to force it to always go to an upstream proxy, which is what those the cache_peer and never_direct directives will achieve.

The proxy at work used to be an authenticating proxy, so I had to specify both a peer and a username/password combination. This made the required amount of variable config a little unwieldy to be include in a template, which is where the > function came from. location.conf used to have this:

##> include /etc/squid/upstream.%location%.conf

Which would arrange for upstream.home.conf, upstream.work.conf, etc to be included depending on the location. There's every chance this will come in useful again one day, so I've left the code in there for now.

Here's the script in its entirety:

#!/usr/bin/env perl

use 5.010;

use warnings;
use strict;

my @files = qw(
    /etc/squid/location.conf
    /etc/postfix/main.cf
);

use autodie qw(:default exec);

use FindBin;

if ($< != 0) {
    exec "/usr/bin/sudo", "$FindBin::Bin/$FindBin::Script", @ARGV;
}

say "usage: location <where>" and exit 1 if @ARGV != 1;

my ($location) = @ARGV;

for my $file (@files) {
    say "building: $file";

    my @out;
    my @cmd;

    open my $in, "<", $file;

    my $in_template = 0;
    while (my $line = <$in>) {
        chomp $line;

        if ($line =~ m/^### START-LOCATION-TEMPLATE/) {
            $in_template = 1;
            push @out, $line;
            next;
        }

        if ($line =~ m/^### END-LOCATION-TEMPLATE/) {
            $in_template = 0;
            push @out, $line;
            next;
        }

        if (!$in_template) {
            push @out, $line;
            next;
        }

        my ($tag) = $line =~ m/^##([#@!>])/;
        if (!$tag) {
            next;
        }

        given ($tag) {
            when ('#') {
                push @out, $line;
                next;
            }

            when ('@') {
                push @out, $line;

                my ($want, $rest) = $line =~ m/^##@ (\w+) (.*)/;
                if ($want eq $location) {
                    push @out, $rest;
                }

                next;
            }

            when ('!') {
                push @out, $line;

                my ($cmd) = $line =~ m/^##! (.*)/;
                push @cmd, $cmd;

                next;
            }

            when ('>') {
                push @out, $line;

                my ($rest) = $line =~ m/^##> (.*)/;

                $rest =~ s/%location%/$location/g;

                push @out, $rest;
            }
        }
    }

    die "$file: unclosed location template" if $in_template;

    close $in;

    open my $out, ">", $file;
    say $out $_ for @out;
    close $out;

    for my $cmd (@cmd) {
        say "running: $cmd";
        system $cmd;
    }
}

Because its so trivial and I only run it a couple of times a day, I just run it when I get to work (location work) or when I get home (location home). If I felt inclined I could probably hook it up to my network stuff but I think that would be more trouble than its worth.

On occassion I have to use Windows on the same machine. I have no idea how to achieve something similar there, so I just reconfigure my browser. Fortunately I don't go there often, and almost never from work. This is why I like open source. I can make my system work in exactly the way I want and usually with a minimum of fuss.

thursday, 4 february 2010

posted at 21:23 | comments

A couple of weeks ago I placed an order with BatchPCB for the N64 RGB DAC board. Today I received two of them!

I'm quite excited to see the design all professional looking. If I'm really lucky they might even work!

As I understand it sometimes the fabs will make extras of a board in case something goes wrong. If they all come out fine then there's not much to do with the extras, so they just chuck them in as a bonus. That's good; now I have a spare if something goes wrong and I don't feel like I got such a bad deal with the insane postage cost.

eBay is the best source of cheap components in bulk. There's hundreds of stores all selling manner of things in huge quantities for mere pennies and half of the time with free shipping. This time around I've picked these up:

All for the bargain basement price of $22.50. Sure, I have to wait a couple of weeks, but I'm not in any hurry here. If I'd been really smart I would've ordered the parts a couple of weeks ago. Oh well :)

friday, 29 january 2010

posted at 09:28 | comments

Ok, so what am I working on. Part two of my N64 modernisation project is to arrange it so that USB controllers can be used with the Nintendo 64.

The reasoning here is pretty simple. N64 controllers have a design flaw. I don't fully understand it, but the gist is that there's a magic powder inside the analog sticks that gives them their "springiness" and makes them return to centre. As the controllers wear, the powder escapes and it gets to the point where the sticks won't return to centre anymore as well as losing their sensitivity. Mine have held up pretty well, mostly because I've gone to great pains to take care of them, but they're fifteen years old now and they're starting to show it.

Obviously these controllers aren't manufactured anymore. Its not enough to buy used ones, for obvious reasons, and new ones are difficult to come by. Not impossible - I've seen them on eBay and in shops like Gametraders and Cash Converters, and I guess I wouldn't need to buy many of them, but still, they aren't exactly cheap or plentiful.

A better option is USB gamepads. As you'd expect from any PC peripheral, they're common as dirt and the good ones (eg Logitech or XBox) are comfortable, sturdy and responsive. So my thought has been to arrange it so that these sticks can be used with the N64.

First stop: Google. There's lots of projects where people have interfaced N64 controllers to something else (USB, parallel, Gamecube/Wii) or interfaced similar controllers (Gamecube) to the N64. As far as I've been able to tell though, nobody has ever got a USB stick going on a N64. Great, new territory - seems I can't avoid it.

I've spent the last couple of weeks researching and thinking and while I haven't yet done any testing with real hardware, I think I have a rough concept for how an interface might work. There's three aspects to it:

  • Acting as a USB host controller and HID class implementation.
  • Translating USB gamepad data into equivalent N64 button/position data
  • Speaking the proprietary N64 controller protocol.

The translation is fairly straight forward. The gamepads I'm interested in (I'll be using a Logitech Dual Action pad for my testing) have (at least) two sticks, a direction pad, four buttons and two shoulder buttons. There's enough here to map to the N64 layout, which is one stick, a direction pad, two buttons (A and B), a second directional pad (C) and two shoulder buttons. The left shoulder maps to the Z trigger or the real left shoulder, as they were never used together on the N64 due to the structure of the controller. The second stick on the Logitech pad will map to the C buttons, with some threshold to determine if the analog stick is considered "pushed" or not.

The USB side is interesting. Its pretty easy to build a AVR-based USB device. V-USB is a very good software stack to turn an AVR into a USB device controller, or you can use one of the numerous chips from FTDI. For a USB host however, the options are far less compelling. As far as I'm able to tell, V-USB does not implement a USB host controller at all. I had intended to use the FTDI Vinculum VDIP1, but as I mentioned previously, the cost of shipping is prohibitive. After some more searching yesterday I found SIAM32, a software USB host controller implemented by a student project team at Cornell. I think some combination of their code and the V-USB code should be enough to implement a minimal host controller and HID class, which is all I need.

On the other side is the N64 controller protocol. Although its proprietary, its long been studied and is pretty well understood. The most useful sources of information have been tzanger's n64dev page and Micah Dowty's Cube64 project.

Its a command based protocol. The N64 sends a command, and the controller sends the response. There's no provision for the controller to initiate a data send - the N64 regularly polls the controller by sending a "get status" command, to which the controller response by sending a data packet containing the current state of the buttons and stick. There's also commands in there ask the controller if its there and what peripherals it has attached (such as a rumble or memory pak), as well as reading and writing to the memory card. Its pretty simple really, which is good - I like simple.

The connection to the N64 has three lines - +3.3V, ground and data. Obviously the power lines play no part in the communication. All that happens on the data line.

The most difficult thing about the data protocol itself is its strict timing requirements, as it typical of a serial protocol without a seperate clock. The line begins in a high (logical 1) state, held there by a pull-up resistor in the controller itself (the line is never explicitly driven high by either end).

A single byte consists of eight data bits and one stop bit. A single bit is 4 microseconds wide. To start the bit, the sender pulls the line low for 1us. The next two microseconds are either high or low, depending on the value of the bit. The final microsecond is high, then it goes again. After all eight bits are sent, the final 4us are all high to signal the end of the byte. See tzanger's page - it has some diagrams that make it easier to follow.

What this means is that however I implement this I need to be able to sample or transition the data line every microsecond. At 16MHz, that means I need to do something every sixteen cycles. Most instructions on the AVR take a single cycle to execute, so there's plenty of time to do things in between, but because I need to be able to respond to the N64 sending data within 2us, its pretty much impossible to run the USB host out of the same AVR.

So my interface has two AVRs - one doing the N64 comms, the other managing USB. This complicates things as now some mechanism is required for the two AVRs to communicate with each other.

This is the bit I'm not quite sure about. I originally thought to have the AVR ports tied together such that the USB AVR could just chuck the current state on the port and the N64 AVR could read it whenever it wanted. This is no good though because the entire controller state is 32 bits wide - sixteen for the button state, eight for the analog stick X axis and eight more for the Y axis. I don't really have the bandwidth available to do it that way, not even with the larger AVRs, which would be overkill in every other way anyway.

I've been thinking about perhaps using eight lines and sending the data a byte at a time, but at that point I've now got the two AVRs needing to coordinate communication when they could both be interrupted at any moment, breaking the whole thing. It might work if I allowed the transfer to be interrupted and in that case the N64 AVR will just use the last button state, but then this means that the USB AVR would have to be constantly streaming the current state rather than just sending updates when transitions occur. If it didn't then a state transition could be lost if the transfer is interrupted.

There's always the option of putting four eight-bit latches in between the two AVRs and storing the state there, as they can effectively be thought of as memories with seperate read and write channels. This however means slower access (external memories access instructions take two cycles in most cases instead of one) which might present timing problems, as well as requiring more board space.

I need to study the AVR datasheets to figure out if any of the peripherals it comes with can help me out. I'm sure a simple solution will present itself, I just have to find it. Fortunately the need for it is quite a way off. The USB and N64 comms need to be developed first, and they need to be done in isolation to ensure they work correctly.

So that's where I'm at. So far I'm just getting my development environment setup. This week I've built myself an AVR programmer which is working nicely, so next I need to write a few basic programs and make sure my laptop is setup properly and I know what I'm doing. Then the real work can begin :)

thursday, 28 january 2010

posted at 09:05 | comments

I was supposed to blog more often, but as usual I missed it. I'm not just going to dump everything though, but rather try and break things up a bit into more logical chunks. So today lets talk about shopping!

I've been looking around for local suppliers of parts and toys. In the past I've always just taken a trip down to my local Jaycar for whatever I needed, but I'm increasingly coming to understand that their range is actually quite limited for what I want and the prices are quite expensive. So I've naturally turned to the internet for help.

The first stop was RS Electronics. They're one of the big industry suppliers, and have a warehouse in Port Melbourne (which means fast shipping). Somehow they also offer free delivery. I placed an order with a couple of weeks ago as a tester, though still for stuff I needed: a couple of AVRs, a PIC, and some 20Mhz crystals. They had the chips in stock and they arrived by courier the next day. The crystals were only available in their UK warehouse, so they didn't arrive, but neither did they bill for them straight away either. I was a little confused as to whether or not they were still on order or if I had to do something else, so I sent an email. A couple of hours later I got a phone call from a lovely lady who apologised for the confusion and said she'd make sure the order was still good. Obviously it worked, because a week later my parts arrived. So +1 to RS. Mid-range prices, fast free shipping, excellent customer support.

Now I had 20Mhz crystals for the PIC, but I was still looking for 16Mhz crystals for the AVRs. I couldn't initially find anyone that stocked them locally, but eBay had the answer. The ALLEPARTS store operates out of China and has bulk components for a pittance and free shipping (how do folks afford this, I don't get it). The paltry sum of $8 resulted in a pack of 20 crystals arriving a couple of weeks later. That's an insane price - Jaycar charge $5 PER CRYSTAL! There are other very similar stores on eBay, but I'll probably end up back there because now I know them.

At this point I had enough to get on with the first stages of my next project, which I'll write about soon. While waiting for parts I spent a lot of time trawling for other suppliers, and found all sorts of stuff along the way.

First, the venerable SparkFun. They seem to be near the centre of the hobbyist electronic world, supplying lots of common and uncommon parts and kits, and working hard to make parts that are difficult to get or to work with accessible to mortals (eg by building breakout boards). There's tutorials and forums and all manner of things. I've spent a lot of time here reading things (particularly the Eagle tutorials) and generally lusting after things, and I probably would have laid down a chunk of cash pretty quickly if it wasn't for the insane price of shipping to Australia, a topic I'll rant about soon. Not being able to just buy stuff immediately forced me to continue looking locally for suppliers, but also to really consider what I actually need.

For example: I'm mesmerised by the Arduino, and I'm of course not the only one. My first thought was that it would be the perfect platform for learning AVR stuff, and so I determined that this was what I needed. Upon further study, I started to realise that while it is very very cool, its not at all what I want. Its a great tool for rapid development, and its been positioned so that non-technical people can use it too, but from what I can gather, its has way more overheard than I want. I'll get into it more when I talk about my new project next time, but I need some very specific hardware with insanely quick response times. The code is likely going to need to be cycle-counted to work properly.

I could do this with the Arduino by bypassing its firmware and development environment and else and just using it as an AVR board, but by the time I do that I've removed all the things that make it special and worth the extra cash. Its not hideously expensive but if you hadn't already gathered, I am (for a variety of reasons) working on less than a shoestring budget. I can't justify the cost. But I'm still very interested in the platform, and I'm thinking about buying the starter kit for a tech-savvy friend that hasn't done any kind of electronics stuff before.

Lets talk about international shipping. Its insane. There's a world of interesting and reasonably priced parts that become inaccessible because the price of shipping is often more than the price of the part itself! My current hate is the FTDI Vinculum VDIP1. Its a brilliant little module that acts as a USB host controller. This week I could just find $40 for the part itself, but I can't justify $80 once shipping from the UK is factored in. I haven't yet found a local supplier that prices it reasonably; RS have it for $70 which is slightly better but still more than I want to spend. Honestly, the freight plane pilot could put this thing in his pocket; that's how small it is. How can that kind of cost be justified?

PCB manufacture is another thing that's going to hurt. I've been spending a lot of time in Eagle and it makes preparing PCBs a snap. As I mentioned previously, I planned to try BatchPCB to get my DAC board fabricated. I sent the order in a couple of weeks ago. The board itself came to a quite reasonable US$15. By the time handling and shipping was factored in, it blew out to a cool US$50. I made the order anyway, because I want/need the board and I'm treating it as a trial, but its only going to be something I can do for complex designs. This seems to just be the nature of the industry though; board manufacture isn't cheap on small scales. I have heard good things about Seeed Studio and their efforts to make this sort of thing more accessible, but I haven't quite figured out how they work yet.

That's the shipping news. Lets get back on to buying things.

So local stores! I've managed to get a few recommendations from the local HackerSpace group (what an awesome idea, can't wait to get more involved with this). Little Bird Electronics appear to be a local SparkFun reseller, though I think they have a few other bits. I'm intending to buy a Bus Pirate from them soon, as it looks like an incredibly useful bit of kit to have on the desk.

Via Jon Oxer at Practical Arduino I found ProtoStack. They don't have a huge range, but they do have all the "essentials" for microcontroller hacking. Here's a tip though - make it clear on your website which country you're in. If I'd come across this site on my own, I probably wouldn't have looked at it in any great depth because the prices are in US dollars, the site is a .com, etc - I would have gone "crap range, US = crazy shipping, ignore". It was only because Jon's video mentioned that they're in Australia that I took the time to look at them in depth. Shipping is only $5 so on the occassion that I need something they have, I will be buying from them.

Anyway, that's about all I have about shopping for now. I have a bunch of other local sites bookmarked, but I haven't done anything more than a cursory search on most of them. I'm starting to get a list of affordable places to buy things together, though there's still a couple of bits I need to find. Fortunately I now have enough parts to do a good portion of my prototyping. That's a story for next time!

sunday, 17 january 2010

posted at 22:20 | comments

Here it is, first post of the new year on the last day of my almost-four-week break from work. The time off has been awesome because I've gotten so much down. Apart from various parties and outings and other festivities, most of the first two weeks were spent organising the garage in a pretty serious way. I took almost all of my old computer gear to the local tip (who are participating in the Byteback program, making my culling reasonably environmentally-friendly). This is a pretty big thing for me, as I'm a hoarder and had kept all sorts of stuff (mostly for sentimental reasons) dating back to 1982. I've kept one working model of every computer and console I had for posterity and/or hacking, but have thrown all the extras and all the PC stuff I had that I'll likely never use. I've kept a few things that might have some actual monetary or other value as collectables, and I'll put those up on eBay when I get around to it.

As a result of all this, my garage has just about nothing in it, so I've set up a desk and sorted all my various electronics bits, tools and whatever so they're all nicely labeled and accessible. I even put in some halogen lights so the whole place is extremely well lit and I can see what I'm doing. And no computer in sight, though I am dragging the laptop out there with me.

All of this is to support this weeks' new hobby, which is getting back into hardware hacking in a pretty serious way. I'm not sure if its as a result of general burnout or because I'm now write code for my job rather than hacking to support my job as I was previously, but I found towards the end of last year that I just had no brain for code by the time I got home. I'm thinking that perhaps hardware is close enough to what I know to hold my interest and not be completely impossible, but different enough that there's room in my brain for it. Time shall tell.

Anyway, back in May I bought a RGB-to-HDMI converter and did some work to get my Amiga going on my LCD TV. As I mentioned then, my next project was to get RGB out of my Nintendo 64 so that I could play it without it looking horrible. I began work on what seemed like a fairly modest project: to build Tim Worthington's N64 RGB DAC using discrete logic rather than a CPLD (which at the time seemed way to complicated).

At the time I didn't really want to commit any money to this project as I didn't know if it was something that I was actually capable of doing. Since I had some stripboard, connectors and most of the other parts I'd need I opted to just build the thing on stripboard and buy the few chips and resistors that I'd need.

In hindsight this turned out to be the wrong decision. Routing data buses on stripboard means a lot of bits of wire flying around, and it doesn't help that the board has to be small to fit inside the case. Over the course of the next couple of months I got perhaps three-quarters of the way there, and after a big effort in the last two weeks I produced this monstrosity:

Yeah, I know. There's more pics on Flickr but it doesn't get any prettier.

There's not much to it. Its four data latches (one for each of red, green and blue and one for the control lines), a couple of support chips and three R2R ladders.

In spite of the mess I still had high hopes for it, so I hooked it up and to my great surprise it (sorta) worked. Here's what Super Mario 64 looks like on my TV with the standard composite cable:

The major thing I'm trying to fix here is the weird "hatching" effect on high-contrast edges (like the life/star counters). Its not bad in static screens, but once things start moving its a horror on the eyes; its pretty much impossible to play.

But, with the magic of wires, we get this:

As you can see, everything is nice and crispy, which is was the desired result. Some of the colours are off though, which obviously isn't right.

Another example, this time from Yoshi's Story:

Composite:

RGB:

I haven't had the chance to really think about it in depth but with the way that the colours are generally brighter and Mario's clothes are washed out, and the way the other colours appear, my gut feeling is that I've wired the inputs to the R2R ladders wrong in such a way that they're off by one bit. With the board being so insane though I figured I have pretty much no chance of debugging it and even if I do figure it out its going to kill my fingers to try and make any changes to the board.

Actually getting the damn thing to work though has given me a lot of confidence and so I've decided to build it again, but this time done right, which means a real PCB. So over the last week I've been teaching myself how to use Eagle, a circuit and PCB designer that seems to be pretty popular. The learning curve is pretty steep, but I've made some good progress with it.

The first thing you do is draw the circuit. I've pretty much just copied Tim's design, getting this:

Next comes the board layout. Its pretty straightforward: setup the board size, place the components, then add all the wire routes to the board. The last bit is made simple using Eagle's autorouter. Various forums and whatnot suggest that real board designers don't use the autorouter, but I don't care - it seems like it will work well enough and I'm just a noob here so I'll take all the help I can get.

I also found a wonderful little program called Eagle3D which produced 3D renders of Eagle boards, including components. I ran mine through it to see what it would look like and got this:

Top side:

Bottom side:

I'm feeling pretty good about this! I'll sit on this for a couple of days just to make sure I've got it right, then I'll send it off to BatchPCB, a PCB fabrication service that will do short runs (even one) for reasonable prices.

I've no doubt that I've missed something, and it won't work properly the first time, but at least this board can be debugged. I see some good looking games in my future :)

thursday, 10 december 2009

posted at 21:20 | comments
tags:

Day two of training today. I had to run off early, but not before getting a crash course in Moose. I've been watching Moose for a couple of years, and have a project in mind for it, but haven't got around to doing anything with it yet. Doing a few basic exercises with it was awesome just to see what it can do, but I did manage to get frustrated by three things within the first ten minutes.

  1. The first thing I noticed is that every attribute accessor created is publically available. There isn't really a way to make an attribute that is read/write from inside the class but read-only from outside. The fine manual suggests this:

    has 'attr' => (
        is     => 'ro',
        writer => '_set_attr',
    );
    

    This works ok, but its still possible for code outside the class to call _set_attr directly. Until we get lexical subs its impossible to make the writer method invisible to the outside world, but until then I'd still like it to be possible for Moose to produce an accessor that can check its caller.

    In a similar vein, its not possible to create proper protected or private attributes. Private attributes can sort of be done by assigning directly to the object hash:

    $self->{attr} = 1;
    

    I don't like this because it because it makes assumptions about the internal implementation of the objects (and with Moose I'd like to remain as ignorant as possible on this point), but also because it provides no type or constraint checking.

    Protected attributes (that is, attributes private to a class and its subclass) seem to be completely impossible.

  2. By default, a Moose class quietly accept any and all parameters passed to its constructor, regardless of whether or not they correspond to an attribute in the class or its parents. This confused me for a moment as I've come from Params::Validate which allows you to declare parameter types and constraints much like Moose attribute declarations, but dies if you provide a parameter that is not declared. The fine inhabitants of #moose on irc.perl.org pointed me at MooseX::StrictConstructor, which does what I want - dies if undefined parameters are provided.

    It gets better though. I was declaring an attribute that I wanted to be impossible to initialise via the constructor as I planned to set its initial value in BUILD, and to allow the user to provide a value only to ignore it is confusing. The manual explains that specifying init_arg => undef in the attribute definition will arrange for that parameter passed to the constructor to be ignored, but again, it does it quietly.

    It turns out (again via #moose) that combining MooseX::StrictConstructor with init_arg => undef yields the desired results. I can live with that, but I would never have anticipated that result from the documentation. Hmph.

  3. Moose doesn't provide any syntactic sugar for class attributes/methods. A quick search just now turns up MooseX::ClassAttribute which will probably be as much as I'll need, at least initially, but I was surprised that core Moose didn't have anything for this. Are class attributes so uncommon?

At the end of the day though, these are all pretty minor nits. Moose is awesome. Its very actively maintained and developed by a number of incredibly smart people, so its not going away any time soon. I'm looking forward to having the time to do something serious with it.

thursday, 10 december 2009

posted at 11:26 | comments
tags:

Work is sending me on a Perl Training Australia course this week, so I'm getting to hang out with Paul and Jacinta and get a good refresher on Perl OO. I wouldn't say I needed it, but I've been enjoying the discussion and it never hurts to make sure that your accumulated understanding matches the current reality.

One of the exercises involved a class representing a coin with methods to flip the coin. One of the things we were asked to do at one point was to create an array of coins and do various things to them. My first instinct to create the array was to do this:

my @coins = (Coin->new) x 10;

I was saddened but not surprised to find that this doesn't work. As the following test demonstrates the left hand side is only evaluated once and then just copied, so I ended up with an array containing ten references to the same object:

$ perl -E '$c = 0; @x = ($c++) x 10; say @x'
0000000000

The best I could come up with is this, which I don't think reads anywhere near as well:

my @coins = map { Coin->new } (1..10);

We briefly discussed whether it would be worth developing a core patch to do something like it, but realistically the only option that preserves a reasonable amount of backward compatibility is to only reevaluate the left side for a very specific set of types, namely code references, giving something like this:

my @coins = (sub { Coin->new }) x 10;

Given that that really doesn't read particularly better than the version using map, and not knowing if anything smarter is possble (and how to do it if it is), and knowing that the core developers aren't particularly keen on new features to existing constructs at the best of times, I've opted to leave it for now but keep my eyes open for things like this.

One part of another exercise had me dealing with decks of cards. Internally I represented suits as integers, with the following list to assist with the as_string method:

my @suits = qw(hearts spades clubs diamonds);

When I got to adding the initialiser for the class, naturally I wanted to be able to specify a string. The usual thing I'd do here is create a hash from @suits with the values as the integer array indexes. This time I came up with this one-liner to determine the index of a value in an array:

my $index = do { my $found; grep { $found = 1 if $_ eq $needle; $found ? 0 : 1 } @haystack };

It plays on the fact the grep in scalar context returns the number of matches; that is, the number of times the code block evaluates true. All this does is arranges it such that the block is true for every array index before the wanted value but false for every index after (and including) the wanted index. If $index == @haystack, then it wasn't found.

Its certainly not optimal - a binary search is always going to be quicker, and you'd nearly always want to use the hash method if you were doing it many times, but it was certainly fun to write a cute oneliner to do it.

monday, 2 november 2009

posted at 08:17 | comments
tags:

A couple of months ago I started work in a new job, doing various programmery things for the Monash student intranet thing The job description says "web programmer", but there hasn't been much web yet. At this point I'm mostly concentrating on the glue code needed to hook up various Google services to our environment. 99% of the code I'm writing and working on is Perl.

I've been using Perl for ages though. For the last nine-and-a-bit years I've been a mail sysadmin at Monash, and while the "core" of our systems has always been full-on professional mail software packages (both proprietary and open-source), all the bits in between have always been Perl. We've written all sorts of stuff, from full web environments and workflow packages to all the traditional sysadmin tools like log parsers, report generators, config builders and everything in between. There's never been any question for us - Perl is just so obvious for this kind of work.

Previously though, Perl was merely a tool that I used to get the job done. In many ways though its now become the job itself. For any given day I can be reasonably confident that most of it will be reading or writing Perl code, whereas before I'd only bust it out when I needed it. Additionally, I haven't really done this type of work before so I'm getting lots of ideas for stuff I want to play with on my own time and also finding gaps in my knowledge that I want to fill out. So now I'm finding just about every moment I'm at the computer I'm doing something with Perl, far more than ever before.

So, I've decided that it would be really good to finally join the mob rather than just hang around the edges looking in. I'm signing up for the Iron Man challenge to keep me honest, and I'm moving my code to Github for a bit more visibility. This is going be an interesting change for me, as in both blogging and coding I'm used to producing something large and fully-formed before showing the world, but obviously that doesn't work if you need to post once a week. I've started making a list of little Perl things I can write about in a couple of paragraphs, so hopefully I'll be able to keep it fresh.

Additionally, I've committed myself to writing everything I possibly can in Perl. I have a long history with C as well, and for the longest time always reached for it for anything closer to the hardware/OS (a fuzzy line, but typically that means server-type things). No more. From now on unless there's a very specific reason why Perl is unsuitable, I'll be choosing Perl for my code.

So that's it. Hi :)

thursday, 22 october 2009

posted at 13:33 | comments

As is often the case with me, what started as a small hack to blosxom to make it do tags and per-tag feeds turned into me rewriting it from the bottom up. I quite like what its become, though I doubt its of much use to anybody but myself. Give me a yell if you want the code.

Anyway, now the whole site has proper tags, and you can use them to subscribe to just bits of my ramblings rather than the whole lot, which should make a huge difference considering how much I don't actually write. Oh, and there Atom feeds too if you like that sort of thing.

To celebrate this momentous occasion, I've moved the whole mess to a new and somewhat relevant domain, eatenbyagrue.org. I think I got all the redirects right, so existing subscriptions should work ok.

That's all. Back to work shortly.

tuesday, 29 september 2009

posted at 21:16 | comments

I love blosxom, so I persist with it, but its a nightmare to refactor. It could have done what it does just as well without being quite as clever. I wonder if that's why development on it is mostly dead. In any case, the refactoring goes well, and I hope soon to have something that does exactly what I want (which I'll talk about more soon; better to spend my time on code right now).

thursday, 24 september 2009

posted at 22:59 | comments

Tonight I wrote a simple tag plugin for blosxom (the blog engine I use), imported all the categories from the old Wordpress blog as tags, and wrote some CSS to make it work properly. There's still a bit more to do, notably making the tags into links that take you to ther posts tagged the same thing as well as getting per-tag feeds going (though the RSS plugin needs a lot of work anyway).

The plugin, for the curious:

package tags;

use vars qw($tags);

sub start { 1 }

sub story {
    my ($pkg, $currentdir, $head_ref) = @_;

    $tags = '';
    if ($meta::tags) {
        my @tags = split /\s+/, $meta::tags;
        $tags = "<div class='tags'>tags: <ul>";
        $tags .= "<li>$_</li>" for @tags;
        $tags .= "</ul></div>";
    }
}

1;

Obviously, its really the meta plugin that does most of the heavy lifting.

So now at the top of a post I write something like:

meta-tags: site perl

and tags pop out. Lovely!

friday, 18 september 2009

posted at 22:25 | comments
tags:

Ooh, it has been a while, and a lot has happened. If I wrote properly about everything, I'd be here all day, so here's my usual long list of stuff I've been up to. Much of it is interrelated in strange ways, so this is not necessarily chronological. You'll get over it.

  • pyro, my trusty laptop, suffered a massive hard drive crash about a month ago after a bungled gparted session. I have backups of all the really critical stuff, so it wasn't a complete tragedy, but there's plenty of stuff that I may have lost. I say "may", because via the magic of e2extract I seem to have determined that while the directory structure is completely destroyed, most of the data is intact. I currently have a 120GB filesystem image sitting on an external hard drive waiting for me to get around to sifting through it for data.
  • as a result, I haven't really touched any AROS code since then. Unless I can save my git pack files, I actually have lost quite a few of my private development branches (anything not saved to repo.or.cz. The hosted rewrite is still there at least, should I ever decide to get back to.
  • so, laptop rebuild. Its actually much better put together now, I think. The Linux side has less warts than it did before, and most of the hardware seems to be working just fine. On the Windows side I installed Windows 7, and I'm actually quite impressed with it (and I've never been impressed with Windows in the past). It seems to perform much better than XP ever did (I never tried Vista).
  • I bought my wife a new laptop, and installed 7 there too, and she's very happy with it too.
  • not one to make the same mistake twice, the very next day after the crash I went out and bought a 1TB external drive and bolted it to our home server and setup automatic backup regimes for both our laptops. This is particularly good for the wife, who has several gigabytes of photos from the last five years of our life (since the kids have been around).
  • without much motiviation to salvage my code, and with work proving rather taxing on my brain, I started spending my evenings loading up Windows and playing Left 4 Dead. A lot. They recently released support for third-party maps and stuff, so my brothers and I have been trying some really great new campaigns and having a lot of fun with it.
  • then the really interesting bit happened. I was approached by another area within my division and was asked if I was interested in coming across to work on an extremely interesting new project. I can't go into details yet (the whole thing is still tied up in legals), but essentially I'm getting paid the same to cut code and design systems, with no management responsibility of any kind. This is something close to my dream job and something I never thought I'd be able to get at Monash, so after a token amount of consideration I left my job of nine years and took the plunge. Today is my fifth day and so far I'm loving it - the work is interesting, the enviroment is comfortable and the mood among my coworkers is very happy and light, which makes a huge difference from the doom and gloom that permeated my former life. I do miss my team though - I've worked with some of them so long that they've become like family to me. At least they're only a short walk away, so I can still get a coffee with them from time to time.
  • for various reasons I'm not allowed to keep my laptop, which belongs to my old department (though they're kindly letting me continue to use it for a little while), so my nice new job have bought me a nice new laptop. Christened junai, it arrived yesterday and I should be able to bring it home and switch to using it full-time today. Cloning a Debian system is trivial, by the way.
  • the new job is all Perl, which I unfortunately haven't had much time for lately, so as well as enjoying the day I'm finding I'm getting home and wanting to work on that too. Since it fits in with work doing it on my own time is actually just more of the same rather than being yet another thing I have to try and fit into my life. As such, I'm thinking I might spend some of my spare time getting a pile of unreleased code into shape and onto the CPAN, and maybe, just maybe, getting along to the occassional Melbourne.pm meeting.

I think that's everything. The other thing I'm going to try and do is blog a little more often, probably by lowering my standards a little and not writing an epic tome each time :)

monday, 27 july 2009

posted at 19:25 | comments
tags:

The last couple of months have been busy but I've managed to find bits of time here and there to hack on the new AROS hosted port. Last week I really got the guts of the task switching and interrupt code working the way I wanted, which is what I'm here to tell you about today.

Task switching in a typical multitasking system is very simple in concept. Imagine a computer running a single task. There's a big pile of instructions in memory somewhere, and the processor just runs them in sequence. It will keep doing that until something stops it. That something is the most important requirement to make preemptive multitasking work.

What usually happens (again in very simple terms) is that there's an extra bit of circuitry somewhere in the computer that works as a timer. Every now and again (though tens or hundreds of times a seconds), it will prod the CPU. In response, the CPU will stop what its doing and go and run a different bit of code somewhere else in memory. The "prod" is known as an interrupt (or Interrupt Request (IRQ)), and the bit of code that runs is the interrupt handler (or more formally, the Interrupt Service Routine (ISR)). Its the handler's job to arrange for a different task to run.

Something the CPU will do when responding to the interrupt is to save its complete state (known as the context) before it calls the handler. That is, somewhere in memory (typically on the stack) it will save a copy of all its registers, the stack pointer, the program counter and everything else it needs to continue running the program from where it was stopped. This is necessary as the handler will need to use those registers in order to do its work. Many CPUs provide a single instruction to restore the entire CPU state in one go.

To make task switching work, the interrupt handler will take a copy of the context and store it inside the OS task state, which usually contains lots of other info about the running task, such as memory it has allocated, files it has open, etc. Then, the handler chooses another task based on some criteria (this is the scheduler). Finally, it copies the saved context from the state of the task to wherever the CPU needs it, then tells the CPU to reload the context and leave the handler. The handler "returns" to running the newly selected task. This process contiues ad infinitum and you get the illusion that your computer is doing lots of things at the same time.

The existing Unix-hosted version of AROS does fundamentally the same thing, but in a highly convoluted way. The main thing to note is all tasks run inside a single Unix process, which then does some deep magic with Unix signals to make interrupts and task switches are happening. The kind of magic employed is highly OS-specific, and although I don't know exactly why it was done the way it was, I can guess that it was one of:

  • The facilities for user-space task switching weren't available or were incomplete when it was first written (I know this was the case for Linux)
  • Originally AROS was much more tightly integrated with the Linux desktop (eg one AROS window per X11 window, etc)

Times have changed though, and so what I'm trying to do is make a new port that is designed to be much closer structurally to its native cousins. I'm realising this through a number of mechanisms provided by POSIX: threads, signals and the ucontext set of functions (though somewhat ironically these have been removed from the latest versions of POSIX and SUS).

What I do is this. I create a thread to mimic the function of the timer interrupt delivery circuit. It sits in a tight loop, waiting a little while then sending a signal to the "main" thread. This obviously mimics the the interrupt that would exist on a real system, and causes the main thread to stop what its doing and jump to a signal handler.

When a signal is delivered to a Unix process, the kernel saves the current process state (context) onto the stack and then calls a signal handler function. When the handler returns, the kernel reloads the state from the stack and continues from where it was. This sounds like almost exactly what we want, except Unix typically doesn't provide a portable way to get at the saved state on the stack. The existing hosted AROS implementation for Linux uses a bunch of Linux-specific knowledge to dig into the stack and get the data it needs, but thats obviously not portable. These days however, we have the ucontext functions which, while not without their quirks, are far more useful.

The prototypes look like this:

  • int getcontext(ucontext_t *ucp);
  • int setcontext(const ucontext_t *ucp);
  • void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
  • int swapcontext(ucontext_t *oucp, ucontext_t *ucp);

For those who've seen setjmp() and longjmp() before, getcontext() and setcontext() will be quite familiar in function. getcontext() takes a copy of the current process state, including the CPU context, and drops it into the memory pointed to by ucp. setcontext() restores the process state and CPU context from whatever is saved in in ucp, effectively causing a direct jump to the point just after the getcontext(). What this means is that you get the appearance of setcontext() never returning, whereas getcontext() can return multiple times. Interesting times indeed.

makecontext() takes an existing context and modifies it such that when setcontext() is called on it it will jump to func with the arguments specified on the on the stack. You actually need to do a bit of fiddling inside ucp before calling it, to setup an alternate stack for the context to run on and so forth. For the most part this call is not particularly useful except when setting up.

Finally, swapcontext() is an atomic context get-and-set. That is, it does this:

getcontext(oucp);
setcontext(ucp);

except that a later setcontext(oucp) will return to the point after the call to swapcontext().

Armed with this knowledge, we can now take a look at the (slightly simplified) implementation. The task switch "interrupt" handler, is a two-stage process. The first part, which as far as the Unix kernel is concerned is the actual signal handler, looks like this:

ucontext_t irq_ctx;
char irq_stack[SIGSTKSZ];

void irq_trampoline (int signo, siginfo_t *si, void *vctx) {
    getcontext(&irq_ctx);
    irq_ctx.uc_stack.ss_sp = (void *) irq_stack;
    irq_ctx.uc_stack.ss_size = SIGSTKSZ;
    irq_ctx.uc_stack.ss_flags = 0;
    makecontext(&irq_ctx, (void (*)()) irq_handler, 0);

    swapcontext((ucontext_t *) GetIntETask(SysBase->ThisTask)->iet_Context, &irq_ctx);
}   

(irq_stack is initialised during startup as irq_stack = malloc(SIGSTKSZ))

So the signal from the timer thread arrives, and the current task gets interrupted and we arrive here. The getcontext() and makecontext() bit sets up a new context that, when called, will call the actual interrupt handler (ie the scheduler etc) and select a new task.

Its the call to swapcontext() that is most interesting. What this does is save the current context into the current task structure, and switch to the interrupt handler proper. The handler calls into the scheduler to choose another task then calls setcontext() on its saved context to start it up. The subtlety is in the fact that when the saved context is later used to start the task up again, it will return to the point just after the call to swapcontext(), immediately drop off the end of the signal handler and head back to where it was.

You might wonder why the more obvious method of using getcontext() to save the context then calling the scheduler directly isn't used. The problem comes from the fact that when getcontext() "returns", the caller has no way of knowing if it was the initial call to save the context, or if it was as a result of setcontext() being called. Without this knowledge, we're left to this kind of trickery so that the only time we end up after the context being save is when the context is reloaded.

(This is the opposite of setjmp(), which returns zero from its initial call and non-zero after a call to longjmp(). It perhaps makes the code easier to read to just have a call and test to determine what to do next, but its slightly slower and it would also result in the handler being run on the task stack, which means making the handler more complicated to make sure it rewinds correctly when the task is switched back. Or tricks can be played with sigaltstack(), which further complicates things.

The actual implementation is naturally a little more complicated, mostly because it has to deal with so-called "system calls", which is what happens when an application triggers a task switch (eg by calling Wait()). To allow that, each interrupt signal carries a numeric id that allows the trampoline and handler to determine what type of interrupt was requested. Then, when Exec wants to force a task switch, it will trigger the interrupt requesting it, which will make the scheduler with the main task "stopped", as above, but with slightly different semantics. It doesn't add much code though, and the technique is identical.

There's still lots to be done to clean up the scheduler, which so far is a hack job of the hack job already present in the mingw32 port. The next thing to do is continue to work on the boot sequence, which is almost there but is just a tiny bit finicky at the moment (that's a technical term). Next time I think I'll write about the new host module setup which blows hostlib.resource out of the water (if you know what that is)!

monday, 29 june 2009

posted at 22:09 | comments
tags:

My current bus activity is AROS hacking. I've actually been doing at least an hour a day for the last couple of months, so I'm making plenty of progress, but I'm off on a long and exciting tangent so it all seems quite different to what I was doing before.

I started thinking about what it would take to make cairo a "first-class" graphics system, sitting directly on top of the graphics drivers, bypassing graphics.library completely. This isn't a crazy idea - a major part of graphics.library is providing drawing and font rendering primitives, similar conceptually to what cairo does (though cairo is of course far more advanced). My thought is that we make the graphics system at the bottom of the stack for apps do all sorts of crazy compositing and whatever other eyecandy effects, and the whole desktop benefits. Initially it could operate alongside graphics.library, but it'd also probably be reasonable to implement graphics.library functions on top of cairo at some later time.

From there I started looking at the graphics driver API. What we have works well enough (despite the deficiencies that I've complained about in the past), but its not a particularly good fit to the cairo backend API, and from what I understand, not a great match for a modern 2D hardware interface either. So the next thing I started thinging about was to change the graphics drivers to have the exact same interface as the cairo backend API. From there, a driver and/or the hardware could directly accelerate cairo drawing operations. The cairo software fallbacks are pretty heavily tested and optimised (including some tight assembly versions of things where necessary), so I'd expect that even a graphics card or whatever that doesn't offer a lot of function could still go faster than, say, the current SDL driver (which uses the graphics.hidd fallbacks for just about everything currently).

So now I'm looking at drivers. As you know, I work in hosted, so my two examples are the X11 and SDL drivers. Something I hate about the X11 driver is how closely tied to the underlying kernel implementation. I took some steps to deal with this when I wrote the SDL driver with hostlib.resource, but its not perfect, and lately something has changed in the X11 driver to require it to be linked with the kernel once again. Besides that, the X11 driver is ancient, hailing from a time where AROS windows were X11 windows, and it retains a lot of that structure even though its no longer the way the world works. Also, it relies on the X11 "backing store" feature, which is usually disabled and will shortly be removed from Xorg. In short, the thing needs a rewrite.

So yay, rewriting one, maybe two, graphics drivers. Down a level to figure out what's going on the core, and sure enough, more work required there. In the last few years the structure of an AROS kernel has changed to be a minimal kernel.resource which implements the absolute minimum required to initialise the memory and task-switching hardware and hand control to exec.library. The loader (typically GRUB) can optionally get whatever modules (libraries, resources, devices, etc) into memory and make them available to exec when it starts. This is the basic idea behind the so-called "modular kernel", which has been implemented in the x86_64, Efika, SAM (both PPC), and more recently, mingw32 ports. The only ports that don't do this are the first two - Linux hosted and i386-pc.

The mingw32 port is particularly interesting. Its a hosted port to Windows, and in essence uses the OS threading system to implement a minimal virtual machine, all within kernel.resource. It has a small bootloader that loads an ELF kernel, making it so that stock AROS i386 code can be used even on Windows which doesn't use ELF itself. The other thing it does is neatly split modules into host-side and AROS-side parts. The AROS parts are handled as normal modules, but in their initialisation they call into hostlib.resource (which is now contained within kernel.resource) to load and link the host-side part. These are standard shared libraries (ie DLLs) which can bring in any library dependencies they need, neatly avoiding the problem contained within the X11 and SDL drivers in that its kinda painful to find the needed libraries at runtime. This way, you just find what you need at link time.

And so, after all this, I'm doing a new port of AROS to Linux, based on the structure used for the mingw32 port. I'm improving on it a bit though. There's still too much arch-specific code in exec.library (like thread context manipulation) which I'm hiding inside kernel.resource. I'm also adding a host.resource which will provide ways for modules to hook into the system main loop inside kernel.resource to do things like "virtual" hardware and the like (ie faking interrupts and such). The mingw32 port did this via special architecture-specific calls in kernel.resource, but I want to try to make kernel.resource have a standard interface across all ports, so they can all run an exec.library that is substantially the same.

So that's some kind of plan. I'm currently at the point where the kernel.resource boots and gets exec.library online. The next thing I need to do is reimplement my task switching and interrupt core which I never tested. If you feel like googling something, it turns out that ucontext_t is not particularly easy to copy or cache on Linux due to the Linux people messing up the way they store the floating point state. I need to rewrite it based on the wonderful context_demo.c example, which never requires an explicit context copy and should do much better. After that I should be able to hook DOS up and get something interesting happening.

I'll keep working and maybe let you know some more in another month or two :)

sunday, 28 june 2009

posted at 20:42 | comments
tags:

Yeah, its been a while. I'm still here, and I've done heaps of stuff since last time, but I just haven't gotten around to writing about it yet. I'll get there.

What I'm here for tonight is to tell you about something new. I know there's people out there blogging about AROS. I'm subscribed to a few of them myself. I'm sure I haven't got all of them though. So I'm putting together a planet to list them all:

If you're trying to follow what's going on with AROS, it'll be good for you to subscribe to this planet, as you'll find out everything that's going on. If you're blogging about AROS, it'll be good for you to be on this planet, as you make sure that everyone is reading your stuff and you benefit from other people's popularity.

If you write about AROS, email me (rob@cataclysm.cx) or ping me on IRC (fce2 on irc.freenode.org). Let me know the location of your RSS or Atom feed, and I'll add you. Its cool if you have non-AROS stuff in there, this is about AROS people as well as AROS itself.

If this gets big and popular, I'll see what I can do to get a better URL. How does planet.aros.org sound? :)

Oh, and I need to do something to pretty it up a bit. If you feel like doing something there, drop me a line.

saturday, 9 may 2009

posted at 08:16 | comments

Gub and Penny went out with a friend last night, so with the girls in bed I got a solid five hour block all to myself. At the end of the night I'd achieved something I'm quite proud of:

This is my ancient Amiga 500 hooked up to my nice tv via the RGB-to-HDMI converter I got for my birthday.

I built two cables. The first is the main one that I'll need for all the things I intend to do with this converter. It turns the somewhat unwieldy SCART input on the converter into a rather more convenient DE9 connector. I've done my own version of the Game Station X connector - I've left out the Luma and Chroma lines but added a ground line. So in short, this cable is carrying the red, green and blue video lines, left and right audio, ground and a +5V line - everything I need.

There's not much to it. The only tricky bit is that SCART has a line (BLNK on pin 16) that selects whether the input is composite or RGB. The line needs to be fed 1-3V to select RGB; leaving it unconnected gives composite. Connecting it to the +5V line via a 180-ohm resistor makes a nice voltage divider and provides the needed signal.

The second cable is one that takes the video off the Amiga and turns it into my custom format. I originally intended to modify the cable I built years ago to connect the Amiga to my 1084S monitor (which died long ago), but on opening it I found that the cable was a five-core cable and wasn't carrying the +5V line. A quick dig around in the garage revealed a short length of six-core phone cable, so I used this to build a new cable. I also had to cannibalise a 2xRCA-2xRCA cable to provide the audio (which doesn't come through the video port on the Amiga but instead via two RCA ports), so I now have this rather peculiar looking plug with two distinct cables coming out of it.

The most surprising thing about all this is that it worked first time. I dabble but I am most certainly not an electronics guy. There was a few tricky bits where I just took the option that seemed most obvious, but I really expected it not to work because I hadn't understood some obscure detail. I'm excited that I'm able to do this! I keep old game systems around because I like to play the games from time to time, but most people when hooking their old machines up to a new tv and seeing it looking crap would be powerless to do anything about it. I like that I know enough to be able to buy or build things that can make it work!

It does seem that my Amiga has suffered from its long storage. Half the time it doesn't start at all, and sometimes it crashes at boot:

But damn, that text is crisp!

Next is the Nintendo 64 mod to get the RGB lines out. I'm hoping to find some time for it this weekend.

monday, 4 may 2009

posted at 11:39 | comments

I'm pretty sick right now and was just getting ready to go to bed when someone knocked on the door and handed me a package:

Its my birthday present!

Inside, a plain unbranded box. China's very finest:

Inside that, a few things: a single page "manual", the converter unit itself, a custom breakout cable for component & audio input (eg from a DVD player) and the power supply with an awesome giant UK plug, egads.

Front and back sides of the converter unit:

This afternoon I'll go around to Dick Smith and grab a power converter so I can plug it in and then give it a test with the DVD player. If I get some time tonight and its not too cold I'll camp out in the garage and start trying to build some cables.

sunday, 3 may 2009

posted at 22:49 | comments

Long ago I wrote a SDL driver for AROS hosted. Back then I wrote about it being slow because of deficiencies in the driver interface that require flushing the output to the screen for every pixel plotted by software fallbacks. Go and read that first.

I never did finish my implementation originally, but in the last week I've resurrected the branch and completed it. Its taken adding an UpdateRect method to the bitmap class and then modifying graphics.library to call it after ever operation. If its running a tight loop to paint a rectangle or something, it will call this once when its finished to push its output.

To test, I removed all the "accelerated" methods in the SDL bitmap class, leaving only GetPixel and PutPixel. Back when I first writing sdl.hidd this was all I had implemented, and it worked fine, but was slow enough that you could watch the individual pixels appear on the screen. With the UpdateRect stuff its now very usable. Its not blinding fast, but its snappy enough to be comfortable.

And the best thing is that no changes are required to existing graphics drivers. For those, the call to UpdateRect will just use the baseclass version, which is a no-op. I've confirmed this is actually the case with the X11 driver, so yay.

I'm not sure what's next for my hacking. I'm really just studying graphics.library and graphics.hidd at the moment, trying to get my head around how it all fits together. Something big is coming, I'm just not sure what it looks like yet :)

tuesday, 28 april 2009

posted at 08:39 | comments
tags:

It would appear I'm back in the AROS game for a little while. I got a nice email asking for some help with fat.handler so I decided that I'd look into it. In the last 18 months a few things have been broken in things that I care about which were causing my particular configuration to fail to build, so I had to get into the code to fix them. While doing this I started to remember that I actually quite like hacking on AROS and miss it. That and my brain seems ready for a challenge again.

Of course this time around, I'd like to avoid the frustrations that contributed to me quitting last time. So this is my plan:

  • I will only work on things that interest me
  • I will not work for money
  • I will not take on significant commitments (ie "sure, I can take a look at that bug" is ok, but "sure, I'll write you a browser" is not)
  • I will not get involved in any political stuff like arguments about project governance, goals (backward compatibility) or anything else

The last point is key. There was a few times previously that I had to do things the wrong way just so that backwards compatibility would be maintained, a goal that I never agreed with. This time, I won't be arguing about it, I'll just be doing what I want to do. Its a light fork, if you like.

I've got a new repository set up over at repo.or.cz. "cake" is what I'm calling my mini-project for now. I'll be committing everything I do there, as well as keeping the AROS mainline there (manually updated as necessary). I will commit things to the AROS Subversion repository as appropriate, but when I do something that causes significant breakage then it will live here. In true open source fashion, anyone who wants my stuff can get it from me and build their own, or if demand gets high, maybe I'll provide some builds or something. We'll see.

So here we go, the brave new world. I'm great at changing my mind, so we'll see how long this lasts :)

monday, 27 april 2009

posted at 08:23 | comments

It was my birthday last week, so on Saturday a bunch of friends and family joined me for lunch at a nice little café near my house. I had an awesome time and felt very special, yay :) The big surprise though was people's overwhelming generosity. Gub had let everyone know about my project and so I'm now sitting on a fat wad of cash to support it, more than I'm probably going to need to get everything to make this happen. So yeah, pretty amazed.

So yesterday I ordered the SCART-to-HDMI converter that is the critical piece in all these. I'm expecting it to arrive late this week or early next. While I'm waiting I need to make a list of parts I'll need to make the necessary cables and connectors. I'm thinking on Thursday I'll head to RS to get what I need. I'd usually go to Jaycar but they don't appear to have SCART connectors. On the other hand, they do have the cheapest HDMI cables I'm likely to get, so maybe I'll just order a single SCART connector online and then build a single adaptor or something. Haven't quite figured it all out yet.

sunday, 19 april 2009

posted at 17:21 | comments
tags:

I've booked a hard rubbish collection with the local council for next week, so I've spent the last few days piling stuff on the nature strip. Its been very purging, and the garage is looking great. As usual a few things have been "stolen" from the pile, which is fine with me - better someone gets some use out of it. What has me curious is why people have chosen the things they have. For example:

  • I put out the six pieces of a plastic kids cubby (four walls and two roof pieces) that broke in a storm. Someone has taken two walls and two roof pieces, but left the other two walls.
  • I put out a laser printer which as far as I know works fine except for needing toner. Fair enough to nab it, except that whoever took it left the paper tray.
  • I put out two computers. One was an old Pentium II in perfect working order (even has a disk and memory in it), but the case was in terrible condition. The other was an ancient HP Vectra that I gutted for parts such that all I threw is the box and motherbord. The first is still there, the second is gone.
  • I put out a box containing three broken CD drives, four broken floppy drives and a bunch of random cables. It got taken within half an hour of going out.
  • I put out a fully working G3 iMac (one of the original blue ones). It got taken, and in its place was a fully working G3 PowerMac (again, the blue one). That one I grabbed myself for contemplation and hacking.

So I'm not quite sure what people are thinking. I suppose if you can find a use for my junk then more power to you.

friday, 10 april 2009

posted at 00:18 | comments
tags:

She's here!

Penelope (Penny) Norris arrived just before 2pm Thursday by caesarian section. Compared to her sisters she's tiny at 3.4kg (7.5lbs), but she's still got the patented Norris large head. I've already poked fun at her with things like "orange on a toothpick" and "sputnik", but I encourage you to join in too.

Her head is cute actually. Its almost spherical with a squished old-man face right in the middle. She frowns a lot too so she really does look like a grumpy old man.

We're still trying to work out who she looks like. At first she appeared to be a clone of Beth (her 18-month-old sister), but having spent the day with her she really seems to be taking on a bit of a look of her own. So far I think she might look a bit like my eldest younger brother.

Anyway its late and I'm tired, so off to bed. Tomorrow I take Francesca in to meet her. Thats going to be insane.

thursday, 9 april 2009

posted at 06:41 | comments
tags:

If all goes according to plan then in just a few short hours I'll be the father of three girls. I'm actually rather nervous which seems strange considering I've done this twice before. If its the kind of thing you go in for then please send up a prayer for Gub, bub, the girls and the army of family looking after them for the next few days. I'll be online tonight with photos and the like.

wednesday, 1 april 2009

posted at 21:37 | comments

I had a bit of time to today to read about how to get older consoles to make nicer pictures on the big screen and found that things are much simpler than I thought and this shouldn't be that hard and quite a bit less expensive than expected.

There's two parts to it. Lets assume that we can get raw analog red, green and blue signals out of the console. From this we build a SCART cable and plug it into a SCART-to-HDMI converter. That should be all thats necessary, for about $150 plus whatever shipping from the UK costs for a small box. Unless I can find a local supplier, but it would probably cost about the same.

The tricky bit is getting RGB off the console. In PAL land, the SNES and the Gamecube have RGB right on the MultiAV connector. Its good to know its there, but its not particularly useful since the MultiAV connector isn't a standard plug I can get hold of, and hacking an extra one won't help since the cable doesn't expose all the pins.

For the N64 I'll have to grab the RGB lines directly from the video DAC. It ends up being about the same amount of work because I'll be exposing a new port on the back with some kind of common connector.

So it should actually be doable, assuming the converter works. Yeah, I'm not really nutting anything out, its all documented and tested already, I just have to put all the pieces together.

tuesday, 31 march 2009

posted at 22:16 | comments
  • mood: positive
  • music: regurgitator

Oh boy, long time. Probably about to get longer given that in just nine days, assuming all goes to plan, I'll be the proud father of three girls, up from the two I have today. So with that in mind I though it best to do the big dump list of everything that's been happening lately so I don't have it swimming around in my head too long.

Homewise:

  • As mentioned, I have a new kid arriving next week. I'm spending a great deal of time getting stuff done around the house in preparation for that and generally supporting my wife, who remains in good spirits despite spending being exhausted all day long and still somehow managing to take care of the other two, both very demanding in their own way.
  • The upcoming larger family has required upgrades, so we now have a larger car, larger couch and larger tv.
  • The family won't be getting any larger after this, courtesy of Dr. Walters. I can't recommend him enough for this type of thing; he was fast, non-threatening and completely transparent. The only downside of the whole experience is that I didn't get to be number 13000 - I had to settle for 12980. Ok, the only other downside is that I don't have access to the totally insanely awesome sleep drugs he uses. I was out chasing space shuttles and I liked it that way!
  • I've been seeing a psychologist to help with my brain problems. She's been awesome, though I'm not very good at doing my homework which I think may be annoying her a bit.

Workwise:

  • Work has been crazy, the same project I've bene working on for the last two years continuing to kill me.
  • But, there's been a big change in the last two weeks. In the hopes of making the project go faster, the entire project team has been whisked out from under me and reassigned to a new manager they've imported for just this purpose. At the time I had some pretty serious reservations about it all, but as me and my boss work through all the transition and handover stuff with them we're increasingly finding ourselves with plenty of time with which to contemplate all the work that we've wanted to do in the last couple of years but couldn't ever get priority for. Work is suddenly relaxing again, and in a little while might even be fun! Imagine that!

Techwise:

  • I've been hacking on OpenTTD a lot in the last couple of weeks, finding my way around the codebase by implementing a new kind of depot. Great fun, highly motivating.
  • Gub bought me a new DS to replace the one I destroyed, and I've been liking the new GTA game, so much so that I may actually buy it soon (yarr).
  • Given the aforementioned new tv, I've been looking for ways to hook up my older game consoles to it via something other than composite, which while not bad from the Gamecube is a complete disaster from the N64 with a tv that can see every flaw in the produced image. Whatever I do is going to end up being a big job but in the course of my searching for details I've found the magnificent GameSX.com and their RGB+Video forums. I'm slowly working my way through just about everything here, but its becoming increasingly obvious that I require a XRGB-3, but $600 is a bit out of my price range. Lots of study required to figure out what I can do myself, though I suspect I'll run into the same problem I always have with hardware hacking in that I don't have the equipment required to make it happen. Its fun to think about it at least!

So yeah, thats where I'm at. I guess you won't hear from me for a while again, except next week to post some pics. Lucky you!

wednesday, 28 january 2009

posted at 22:26 | comments

After my lack of motivation I've had a couple more interesting ideas and so I've started very slowly poking at them, being very careful to not overdo it in an attempt to avoid the burnout. So far it seems to be working!

The short is that my mate Sam and I have been pondering for a year or more the idea of building an arcade cabinet that runs emulators for various old systems (MAME and such). He's a high school woodworking teacher and cabinetmaker by trade so he's perfectly qualified to build the box. I know a thing or two about computers, so I can do that bit. The problem so far is that we've never really had any good place to build it - I have a garage but no tools, Sam had no space at all.

He's just recently moved house and is finishing getting his own garage all kitted out with workbenches and drop saws and drill presses and other things that scare me and he's now ready to build something, so we're taking another look at it. I've managed to scrounge enough parts to build a reasonably good rig, though the ridiculous weather is making me reluctant to go out to the shed to work on it. Arcade Gaming Australia have all the buttons, joysticks and other bits that we'll need. There's only one thing left - an awesome UI for choosing games and things. Yay software!

So tonight I've been sitting under the air conditioner fiddling with Clutter. Its a library for making fancy interfaces by using lots of 3D stuff under the hood. As far as I can tell the most well known example of the type of thing its for is Apple's Cover Flow. Just from playing with some of the samples I already have some idea of how I'd like a game selector to look, so I've started experimenting using the Perl bindings.

The basic idea is that you set up a bunch of actors, which are basic visual elements - some text or an image for example. You can specify various transformations for an actor, eg scaling, rotating, etc. After that, you place your actors somewhere on the stage, which is roughly analogous to a window.

Next is where I get a little confused, but not so much that I can't get something done. You setup a timeline, which has two paramaters - number of frames, and frames per second. You hook up an "alpha" to the timeline, which is a function that gets called every frame, and returns a number that I don't fully understand the purpose of yet. The number is used to drive "behaviours" attached to each actor, which makes them do something depending on the current distance through the timeline. A behaviour might be to move the actor around the stage, rotate it, or something more clever.

There's also an input layer, but I haven't really started looking at that yet.

So here's the fruits of my evening. It takes a random image and rolls it around a window.

#!/usr/bin/env perl

use 5.10.0;

use strict;
use warnings;

use Glib qw( :constants );
use Clutter qw( :init );

say "usage: roll image" and exit -1 if !@ARGV;

my $stage = Clutter::Stage->get_default;
$stage->set_color(Clutter::Color->parse("DarkSlateGray"));
$stage->signal_connect('key-press-event' => sub { Clutter->main_quit });
$stage->set_size(800, 600);

my $actor = Clutter::Texture->new($ARGV[0]);
$actor->set_anchor_point($actor->get_width / 2, $actor->get_height / 2);
$actor->set_position($stage->get_width / 2, $stage->get_height / 2);
$stage->add($actor);

my $timeline = Clutter::Timeline->new(100, 26);
$timeline->set(loop => TRUE);

my $alpha = Clutter::Alpha->new($timeline, sub {
    my ($alpha) = @_;
    return int($alpha->get_timeline->get_progress * Clutter::Alpha->MAX_ALPHA);
});

my $rotate = Clutter::Behaviour::Rotate->new($alpha, "z-axis", "cw", 0.0, 359.0);
$rotate->apply($actor);

my $path = Clutter::Behaviour::Path->new($alpha, [ $actor->get_width,                     $actor->get_height                      ],
                                                 [ $actor->get_width,                     $stage->get_height - $actor->get_height ],
                                                 [ $stage->get_width - $actor->get_width, $stage->get_height - $actor->get_height ],
                                                 [ $stage->get_width - $actor->get_width, $actor->get_height                      ],
                                                 [ $actor->get_width,                     $actor->get_height                      ]);
$path->apply($actor);

$timeline->start;

$stage->show;

Clutter->main;

Hard to show it here, but here you go:

Of course I have no idea if this is the "right" way to do it, but it seems to perform well enough so it will do for now. Next is to make a little photo thumbnail viewer, using the arrow keys to scroll through the photos and a little zooming magic.

tuesday, 20 january 2009

posted at 07:36 | comments
tags:

I haven't written any code for ages and ages. I'm having a lot of troubled getting motivated, and although I've had a few idea I haven't really come across anything sufficiently challenging or world-changing to really get excited about it. Some ideas I've had that haven't got anywhere, in no particular order:

  • A group chat client (IRC, Jabber MUC, etc) that allows images, videos, etc from the web to be embedded directly in it so that when we share links I don't have to click everything. I started prototyping this in Perl using WebKitGtk, but it doesn't have API that allows a page to be added to incrementally, and I don't really want to get back into hacking on WebKit right now.

  • A version of Settlers of Catan with a really sweet AJAX/DHTML/Web 2.0/buzzwordish interface. Currently the options for playing Settlers on a computer appear to on your local machine with Pioneers or on the web through Java applets. I got as far as thinking about the AI and poking at the Pioneers code a bit before realising that the only interesting bit is too hard for me which means borrowing the AI code and then writing the web interface, which is totally boring.

  • A browser-based sprite engine. THe idea is you'd throw in a bunch of images, specify coordinates and any filters/transformations you might want, and it takes care of their display. Again though, its hacking browser stuff which I'm pretty much over at this point in my career.

  • A web-based forum that doesn't suck. I'm quite over every bit of web software requiring a database and having insanely complicated interfaces. I had a thought of some kind of cross between Digg, the Joel On Software forums (design notes) and an image board. Basically no mad hierarchy of forums and posts, no threads, no userpic/sig/meta clutter on every post, and no login requirement. Internally its very much like blosxom, just a simple one-file script that you can drop into your cgi-bin and it just goes, and that you can extend in any way you like with plugins. The whole thing would be backed by git and just be sweetness. I made a good bit of progress on this but at the end of the day its basically a repeat of the code I've just written to get this blog updated, and its for web forums which I hate and avoid as much as I can anyway.

  • A database diff tool for Lotus Notes databases. This is kind of interesting, and it would help a lot at work and dodge the need for us to buy any more stupidly expensive licenses for a commercial product, but the Notes API really really sucks and I haven't been able to get a working development environment working on Debian yet, which means I'm going to have to use a Redhat VM if I want to make this work. That amount of effort for what is really part of my job in my spare time is just too much.

So there you go. A few reasonably good ideas, but no motivation. As a result I've been killing time playing games, but that's starting to wear a bit thin. I'm not sure what to do right now, because I really feel like I want to write something. Motivation came easily when I was working on jabberd2 - we were changing the world! It was easy for AROS because I'd never worked on an so many different facets of an operating system before and everywhere I turned there was something new to be done. None of the above so far fit into one of those categories. Every existing project I've considered so far doesn't seem to be either groundbreaking enough or have enough for me to learn to make it worth the effort. I'm not sure what to do now.

Its likely I'm growing old and curmudgeonly. I hope I can get interested soon, if for no other reason than my bus trips are getting boring.

monday, 19 january 2009

posted at 22:12 | comments
tags:

This is a rant. You're not expected to agree or care.

I bought Left 4 Dead a few weeks ago. Its a good game. Not the best game ever, but enjoyable enough. Nice idea, fun to play, etc. But, as usual, its being ruined by the internet.

I was in the mood for a game tonight so I hopped on and started looking around. I had no success finding anything interesting, just frustration. The first game had four players that based on their names were clearly affiliated with the same clan or whatever. Two of them joined survivors, the other two infected. I was survivors, and me and the other random got jumped within about a minute in while they stood idly by and did nothing. I quit shortly after.

Second game saw me on the infected side. I make some good attacks and finished with the most points, which made me happy. On our turn as survivors they somehow decided without speaking to go in another direction to what's done most commonly. Because I didn't know about it, I got seperated and they had to come back for me. I asked them to let me know if they're planning to run off with out me next time, and they voted to kick me out of the game.

By this time I'm pretty annoyed, but I decided to give it another try. The other players were at least communicative, so I knew that they wanted to rush, and I was ready for that. There's still the number one rule of this game to be remembered though - stick together. The front two rushed a little too fast through the apartments, while me and another got pinned in a place where we couldn't be saved. Leaving us behind was apparently our fault, and we got an earful for it. I just couldn't bothered after this and quit the game.

So here's a good game that I like playing and while I'm not the greatest player in the world I don't think I'm a complete passenger either. So why is so difficult to find a good game? Am I destined to play by myself forever?

So yeah, people have ruined the internet. I'm not telling you anything new. But still, sigh.

sunday, 11 january 2009

posted at 10:50 | comments
tags:

I just spammed Planet Linux Australia and probably anyone else who subscribes to my feed with all the posts I just brought back to life. I'm sorry :(

sunday, 11 january 2009

posted at 09:04 | comments
tags:

I've just added all the posts from my old Wordpress blog to this. Its taken a few days since I had to write a little HTML-to-Markdown converter, and then manually clean a bunch of problems, but its here now. There's probably still a bit of brokenness, but it shouldn't be too much now. No comments yet, but I'll bring those across once I write some code to hit the disqus API properly.

wednesday, 7 january 2009

posted at 08:02 | comments
tags:

I bought a pile of games through Steam a few weeks ago and as part of the deal I was given a guest pass for each of Counter-Strike: Source and Team Fortress 2. I don't need them but if I don't give them away soon they'll expire. If you haven't played one or both of these games and you'd like to give them a try, drop me an email and I'll send them your way.

wednesday, 31 december 2008

posted at 10:32 | comments
tags:

I've had a nice week. Christmas things were awesome, lots of fun and I scored very well - my own copy of Settlers of Catan and the Cities and Knights expansion, some tshirts, IT Crowd and Frontline DVDs and some DS accessories. People are learning my tastes well, it seems :)

Sadly I've managed to break my DS. I put some screen protectors on it a while ago but they've got pretty scratched, so I decided to replace them. When I lifted the one off the bottom screen I managed to bring the touch lens with it, so even though I've put it back on the touch screen doesn't work. I can still play most games and I wasn't playing it much at the moment anyway, so getting it fixed isn't desperately urgent, but its a bit annoying. I'm still looking into repairs. I can get a brand new LCD+touch screen element for about $70, but I'd have to install it myself and I don't know if I really need all that since the LCD works. I'd need to get special screwdrivers too. I'd rather just get someone to fix it for me but since i can get a new one for $190 I'm not sure how much effort it is. I'll probably leave it until it starts to become a problem.

Sunday was game time, mostly Left 4 Dead, Counterstrike and Day of Defeat. We also played Ricochet which is really quite cool if a little simple. All good fun, as usual. Tonight is more games, this time of the board game variety. In reality it'll just be Settlers since everyone knows how to play already.

I watched all of the Boxing Day Test, which was an excellent game even if we did lose. I predicted at the end of day two that we'd lose even though we were in a position where a loss was close to impossible, and so it came to pass. Go seer. Apparently on day two South Africa were at $13 to win; shame I didn't get some of that action.

In between all this I've done the gardening, got hold of a really awesome wooden cubby that I'll put together for the girls in the next couple of days, done a pile of chores, read lots and generally had a nice relaxing time. Gotta go back to work on Monday but I think I'll be pretty flaked by then which is exactly what I needed.

wednesday, 24 december 2008

posted at 15:30 | comments
tags:

For the first time in a few years I'm actually excited about Christmas, for several reasons:

  • The girls (Francesca in particular) are finally old enough to really get into the day and I love watching them,
  • I've had the money and the motivation to find what I think are some really awesome and quite thoughtful gifts for my lady
  • I've heard I'm getting some awesome stuff and I'm excited to find out what
  • In the last year I've had many opportunities to get to know my family again and I love spending time with them and will get to do so tomorrow
  • The food I've seen prepared so far is looking damn nice

Hope you have a good day too. On, and if for whatever reason you don't do Christmas, have a good day anyway :)

monday, 22 december 2008

posted at 14:48 | comments

Well here it is, all new prettiness that I've been planning and threatening for a little while now. I've been almost about to write something for a few months but I was kinda sick of the old orange and green, and I knew I didn't want Wordpress anymore so I didn't really want to do much until I'd figured out what it would look like and all that.

The whole thing is based on blosxom, a pile of custom plugins, a sweet preprocessor and managed through git. Markdown makes it so I can just type normally and get all my formatting for free. I'm trying disqus for the comments, since I really wanted to get away from needing to run a database and the have anonymous posting which is all I really need.

I bought art from iStockphoto (that cute monster eating the rocket) because I couldn't find what for free, and I'm actually really happy with it. As usual daniel figured out all the tricky CSS bits because I really really suck at it, so its a big happy team effort.

There's not really much left to do apart from some style tweaks and sorting out exactly what I want in that right bar. Its all nice and good and happy, I'm quite pleased :)

thursday, 17 july 2008

posted at 09:07 | comments

So, long time huh. Time to write something, I guess.

Its hard to write again after a break, not least because so much as happened in the last three weeks that unless I write for another three weeks I'm never going to cover it all. So right now I'm not going to try. i'll just write about what I've been working on, get caught up to some degree, and maybe come back to any other interesting stuff down the track. So here we go!

I've long threatened picking up a DS homebrew kit and doing something interesting with it. I finally snagged a M3 DS Real from the Monash post office, of all places. Its a cute little thing. I got a 4GB microSD card with it, so I should have enough grunt to do anything I could ever hope to do with it. The next thing is just to work out what that is. I have an idea of course, one probably rather predictable if you know me.

I have an interest bordering on an infatuation with the game Frontier: First Encounters; specifically the JJFFE variant. Its a great game, and the effort and style that went into making an old Windows game come to life on more modern systems still totally imprresses me. John Jordan took the game binary and run it through a custom disassembler that produced an assembler source file that would compile on whatever platform he chose. His disassembler also identified operating system calls for graphics, sound, input and filesystem access, which he then abstracted and reimplemented for DirectX, SDL, and whatever else. So now the game runs on (i386) Linux without issue as well as on modern Windows systems. He even fixed a heap of bugs. Thats great!

I've messed with this code at various times. I implemented the OS abstraction for AROS a couple of years before I got involved in AROS proper. (That work later led to me working on some graphics subsystem speedups and a SDL graphics driver for AROS). I've also long dreamed of somehow converting it to pure C so that it could be hacked on properly. I've dabbled with this at various times, both using automatic and manual techniques, but haven't really got very far mostly because of because of the limited success others have had with the general problem of decompiling assembly back to C.

So anyway, I got a DS kit, and of course started to think about how cool it would be to play FFE on it, and also about how to take advantage of the dual screen and touch screen. I've been dreaming of interesting UI changes that would make the game work much better on the DS, but of course first I have to get the game working there. That is not a trivial task, and has been the subject of inquiry for the last couple of weeks.

The problem is obvious. The DS has a pair of ARM CPUs. The JJFFE source is in i386 assembly. So there are really only two options - some sort of emulation, or converting the code to a higher-level language and then recompiling it for ARM.

Emulation would only really require a processor emulator for the game core since all the systems interaction could be done in C, and perhaps would have been the easier option, it doesn't help much with my eventual goal (or "hope", rather) of making significant modifications to the code to support the DS hardware properly. So instead, I've again returned to converting the assembler code to C.

As mentioned above though, this is something I'd pretty much given up on as being too difficult. I thought about it for a while and realised as a first cut, I don't need to convert it back to anything resembling its original C. Instead, what if I was write an assmbler that produced C code that implemented the processor instructions, rather than producing raw machine code. The result would look much like C - we'd essentially have a kind of static CPU emulator built into the program code itself, with global variables representing the processor stack and registers. But, it could be recompiled for another CPU, which is the point of the exercise.

This seemed like a reasonable approach, but writing an assembler is insanely complicated. After attempting a hacky parser in Perl, I decided that nothing short of a full assembler would be able to do the job. NASM proved too complicated to penetrate, but then I found YASM, which is a highly modular clone of NASM.

So I took YASM and started writing a custom object format, one that would output C code. However, after experimenting to gain some experience with the interface, I realised that I was just getting the raw machine code and then converting it to C with a little bit of symbol table gymnastics to identify and produce simple unadorned C functions. This reminded me of a project I worked on for a while in 2004 that turns out to be much better suited. That project is a custom disassembler/decompiler of the same kind of was used to produce JJFFE in the first place! Let me explain.

Another old game that I love is Transport Tycoon (actually its sequel, Transport Tycoon Deluxe). At the time, it was Windows-only. There was a project called TTDPatch which would take the server binary and hook all sorts of stuff into it to add new features and fix bugs and whatever else. This worked well, but it was still Windows-only. Wine did a reasonable job with it, but it was still less than ideal. So I decided that I'd give it the same treatment as FFE got, and produce a disassembly and system abstraction that could be run anywhere.

I spent a lot of time studying JJFFE and Jordan's decompiler and even had a series of email discussions with him to get a feel for just how to do this. After several weeks I managed to get my decompiler to the stage where it produced a viable disassembly and C file of OS call stubs. But, as fate would have it, the day it compiled and ran for the first time (segfaulting of course, as I hadn't yet learnt about how Windows uses the %fs segment register), OpenTTD was announced, which was essentially a conversion of the original game back to C. My decompiler had no further reason to exist, and so I abandoned it.

The way it worked was pretty straightforward. It implemented what is essentially a Portable Executable (ie the Windows binary format, like ELF for Unix) loader with calls into the NASM disassembler to analyse the code and produce a disassembly and a stub file. Simplified, it does the following:

  • Inspect the program binary and find the code, data, bss, import and relocation segments.
  • Load the program binary into RAM.
  • Apply the relocations to produce a complete program image, additionally creating a "label" for each relocation.
  • Inspect the import section to build a list of all the external libraries and functions that the program wants.
  • Disassemble the code segments to find all the relocation labels that are in use and what they point to. From the instruction type, we can determine whether the target is code, data, bss (ie unitialised data), a vector table, etc.
  • Disassemble from each code label to the next to find any other labels missed in the first disassmble run. That might have happened, for example, if there were "garbage" bytes in between the end of one function and the start of another that caused the wrong disassembly to be produced crossing the function boundary.
  • Do this dissambly over and over until no new labels are produced.
  • Run through any relocation labels that have not been processed yet, and make them data labels. This works off the assumption that if the linker thought it important enough to include a relocation, we should probably include whatever that relocation points to in the output, even though we couldn't actually find it in the code.
  • Output EXTERN declarations for each external function name.
  • Disassemble from each code label again, this time producing actual output. Any memory references in the output (ie things beginning with 0x) get replaced with their corresponding label, if there is one.
  • "Disassemble" from each data label, producing raw byte output (ie db or dd). For any data that was referenced via a relocation, produce the corresponding label.
  • "Disassemble" from each bss label, producing a memory reservation in the output (ie `resb

Theoretically, the resulting output from that is just about usable. There's a bit of manual cleanup that has to happen (like the mentioned deal with the %fs register), but this output should at least compile and link, which is most of the fun. Theoretically you implement the stubs for your platform and you're away.

So, back to our original problem of producing C from a binary. I realised that in this code, I'd already done most of what I needed. I know where all the function boundaries, jump points, vector tables and data are. All that needs to happen is instead of producing formatted assembly, all I need to do is produce some equivalent bit of C code. There's some complication of course, like the fact that sometimes several instructions map to a single C construct (like if or while) but I figure I'm most of the way there.

So right now, I'm working on cleaning up and generalise the decompiler, which I've christened opsoup. It was pretty heavily tied to the PE format before, which of course is no good for me - I need ELF. I'm not bothering with trying to keep it compatible with PE at this point, as I have a pretty specific purpose. I can always add that back in later if I ever need it.

I have absolutely no idea how this is going to go, but its fun finding out. In adition to playing my game, I'm hoping that having the code in C, even horrible not-quite-C, will make it much easier to gradually convert some of the code in actual nice C (due to the availability of things like gdb and printf). I don't expect it to happen fast, but I've been hacking at this code on-and-off for the last five years, so messing with it for another five doesn't really concern me that much.

thursday, 19 june 2008

posted at 00:49 | comments
tags:
  • mood: modular

A few random things I've been working on lately:

  • Started migrating this blog into ikiwiki. Stuck on a problem with file create/modify times not being preserved, which makes complete sense but is annoying. I think a plugin is required, much like one I wrote for blosxom once upon a time.

  • Made progress with Test::MockTerm. The terminal itself works, with open() and POSIX::isatty() being overidden correctly. I'm currently planning the interface for sending and handling control characters (and from there emulating Term::ReadKey). Its hairy.

  • Made a new release of XML::Quick after a couple of years. The test suite now runs (the were bugs in the suite itself) and an ancient bug was taken care of to boot.

  • Dug out XML::Spice, something I started a couple of years ago as an answer to Python's stan XML generation library. It already has some funky magic in place that lets you call the generator function to create some piece of XML which totally complete and usable, but then call the generator again with that returned chunk as one of the arguments to have it embed that chunk into another chunk of XML. At this point both are valid, but it can do some funky stuff like move and reprefix namespace declarations to make the result more concise without changing the semantics. It does this without having to reparse the original XML. You have to read the tests to find out more. In any case, its not finished yet and perhaps never will be since I'm long over XML.

  • Also dug out HTML::Calendar::Render (no link yet), which you give a bunch of events and it creates a calendar using HTML tables. This was done for work, at a time when we temporarily needed an alternative view to our corporate calendar system. Producing calendars in HTML is nothing new, but this is prettier than any of others I've seen on CPAN. It works really hard to produce stuff that looks like your calendar in something like Outlook, where overlapping events appear next to each other at half-width. This one I'm kinda interested in getting into some kind of release quality. The plan is to split out the tree generator from the renderer itself, so you can add modules that might render it with or without HTML tables, in PDF, or via cairo. Coming soon I guess.