Sunday, November 2, 2008

Press play on tape - c64 revival band

It's certainly not a secret I'm a Spectrum addicted, yet I have a thing for home computers in general. So, today I'll post something about a Commodore 64 (!) revival band. They're called Press play on tape and they really rock: my advice is to check their site out and enjoy their music. Have fun!

Sunday, October 26, 2008

Dog risks life for kittens

This is not a word play and the subject would be definitely off-topic if it weren't for the "random things" part of the blog subtitle ;) Anyway, it's been a while since I posted something and I've found this piece of news quite moving.

Tuesday, September 16, 2008

Why java.io.PrintStream is badly designed

Sweeping the exceptions under the carpet is considered a bad practice, I mean really bad practice. Consider, for instance,
try {
  do something
} catch (SomeException e) {
  set a flag (or, even worse, do nothing!)
}

Obviously, one of the great advantages of having an exception mechanism is that programmers do not need to explicitly check for error conditions after every single statement: when something wrong happens, an exception is thrown and it will be handled where it is sensible to do so (low-level code can't usually know what to do but, thanks to the automatic propagation of exceptions, it luckily doesn't have to).

When exceptions are swept under the carpet, instead, higher level-code can't react with some sensible action (when something wrong happens) for the simple reason that such a code has no way to know that something has happened! Well, ok, if a flag is set, then the high-level code could do something if it checks for the flag after every single statement. This works, but it clutters the code with a series of "if (flag is set) do something appropriate" that could be totally avoided by simply using the exception mechanism in the first place.

I hope everyone agrees that sweeping exceptions sucks; keeping this in mind, let's read the documentation of java.io.PrintStream (from the API docs): Two other features are provided as well. Unlike other output streams, a PrintStream never throws an IOException; instead, exceptional situations merely set an internal flag that can be tested via the checkError method. Ah ah! They call it a feature! I'm so sorry I've missed the point and I thought it's a bad hack to avoid to follow their "Catch or Specify requirement".

I know: it would be annoying to declare that every method that prints something may throw java.io.IOException, yet, it would be the only correct way to handle the error condition. With a flag we:

  1. have to check the flag everytime
  2. lose both the reason (the type of the exception) and the place (the line of code) where something bad has happened

Is this the worst thing about the class PrintStream? Actually, no, it isn't: PrintStream extends Outpustream, overriding the write methods with its set-the-flag semantics. So, every time you handle an OutputStream you're handling something that may or may not throws exceptions in the way it should!

Sun has admirably implemented two "features" ;) in one fell swoop:

  • sweeping the exceptions under the carpet (bad practice)
  • defining a subtype whose methods do not respect the specification of its supertype, that clearly states that an exception is thrown when an I/O error occurs (awful practice)

Monday, September 15, 2008

Who wants to be a researcher?

In [Javascript is not enabled; please enable JS in your browser to see the counter], an open competition will take place at my university to fill a position as Assistant Professor. Will I get the position or the sack? ;)

I'm excited, kinda scared and counting the seconds down.

Sunday, September 7, 2008

Running Turbo Pascal 1.0 on (a real) Spectrum +3

As I wrote in my previous post, I was determined to run Turbo Pascal 1.0 on a (real) Spectrum +3. The issue is how to dump a DSK image file (on the PC) onto an actual three-inch Amstrad/Sinclair floppy disk (like the one shown in the second picture by a friend of mine who, by the way, is a very skilled hacker).

One obvious way is to connect a three-inch floppy drive to a modern PC. While this should work, I've already tried and failed :-(
Moreover, in doing so I was always worrying about damaging the floppy drive, the PC or both. For these reasons, I was looking for an "all software" solution.

Luckily, I've found a very nice utility in the Alchemist Software PD/Shareware Library allowing to backup (and then restore) disks to tapes. Basically, this utility dumps the disk tracks to a series of data files. Each disk (actually, each side of a disk) is dumped into five 36K blocks, which is hardly surprising considering we need to dump 180K and the available RAM is about 40K. Curiously, this neat utility cannot be found in the Utils section. To obtain this utility you need to download the game Cannon Bubble +3, from the Games section. While it is indeed a good game, we're not interested in the game per se, but rather in the bundled utility.

Using this utility in Spectaculator it's easy to create a (virtual tape) TZX file containing the dump of any DSK image file. In my test I used the Turbo Pascal image file I've previously created.

I thought (hoped) to bring this TZX into a real Speccy using an SD card and the ZXMMC+ interface. This would have been amazingly fast and cool ;) ... unfortunately, my plan have failed because I haven't figured out how to use the ResiDOS, needed to load the virtual tape stored in the SD card, and the +3 floppy drive (when the ResiDOS is active the drive identifiers are mapped to the SD card slots). I think there must be some workaround, but I haven't found it out yet.

So, how did I manage to dump the disk? Well, in the old-fashioned, simple and painfully slow way of using the EAR socket of the Speccy (as you might remember, it takes about five minutes to load a 48K game and we need to dump 180K... you do the math!). What I did is equivalent to dumping the DSK image into a real tape and then load it into the Speccy... but without the real tape ;)

I've connected the Speccy to the soundcard of my PC and I've used the tape recorder of Spectaculator to play the just-created virtual tape. If you try this way, make sure to select "Boost loading noise volume" in the options for the Cassette Recorder (Main menu -> Options... -> Cassette Recorder).

While I'm not totally satisfied because the way I had to fall back on the soundcard-based solution, it indeed worked :-) as the third picture shows.

Monday, September 1, 2008

Running Turbo Pascal 1.0, on the CP/M, on the Spectrum +3 (emulated on Windows)

I've never been a fan of the Pascal programming language; actually, I can't stand it... for a lot of reasons, many of which can be found in the (old and must-read) paper "Why Pascal is not my Favorite Programming Language" by Brian Kernighan.

However, Turbo Pascal was different. The language was still not my favorite, but I have to admit it was far better than the standard one and the IDE was quite revolutionary for its time. I've used Turbo Pascal in the early nineties for some projects in high-school and college and, after that, I thought that was it.

Well, never say never I guess: today, when I've come across Turbo Pascal 1.0, in a wave of nostalgia I felt the urge to write and compile an "Hello World" program in dare I say ... Pascal! ;-)

It turns out that my favorite computer, in its +3 flavor, can run CP/M... how interesting! In the picture you can see Spectaculator (probably the best Spectrum emulator around) running my just-written one-liner Pascal program, compiled with Turbo Pascal one-oh :-)

In preparing this little experiment, I've found invaluable the French program (with, luckily, a French/English GUI) Manage DSK, that can create DSK disk images from a collection of files on your PC. In my case, the files contained in the Turbo Pascal ZIP archive.

For unknown reasons, in the conversion process I had to pretend that all the files were ASCII even if they're clearly not. I've noticed that in converting the files as binaries the program prepends some sort of header, which makes them unusable (maybe this has something to do with how the Amstrad CPC handles files, I don't know).

My experiment is not over though: now I have to run it on the real hardware. So, I need to find a way to put the Turbo Pascal files on an actual 3-inch disk. I think I can use an SD card and the almighty ;) zxmmc+ interface to bring the data in the real-Speccy realm, so I can then dump the image on an actual disk. This will be (probably) the topic for a future post: stay tuned.

Tuesday, August 12, 2008

A not so obvious answer to: Can Java interfaces have static initializers?

Static initializers are blocks of code that are automatically executed when a class is initialized. They are particularly handy when an expression is not enough to calculate an initial value or when the evaluation of an initializing expression may throw a (checked) exception. For instance, suppose we want to initialize a (final static) field me with the IP address of the local machine. We'd like to write:
import java.net.*;
class C {
  final static InetAddress me = InetAddress.getLocalHost();
}
but we can't because, as the compiler duly reminds us, "unreported exception java.net.UnknownHostException; must be caught or declared to be thrown". Ok, that's what static initializers are for:
import java.net.*;
class C {
  static final InetAddress me;
  static {
    
InetAddress addr = null;
    try {
      
addr = InetAddress.getLocalHost();
    } catch (UnknownHostException uhe) {
      uhe.printStackTrace();
      System.exit(-1);
    
}
    
me = addr;
  }
}
Now, the raison d'ĂȘtre of this post: what if C were an interface? Could we write the following? (fields are implicitly static and final in interfaces)
interface I {
  InetAddress me;
  static {
... as before ... }
}
Well, we could write that but it won't compile ;)
Is there any workaround? Yes, there is. However, before presenting it, allow me to make another point.
Tricky question: can interfaces have static initializers? After all, interfaces cannot contain code... can they?
Since I've said the question is tricky, you've probably guessed it right... yes, interfaces can indeed have static initializers, yet you (programmer) are not allowed to write static initializers inside interfaces. Uh... does the last sentence make any sense at all? Allow me to explain; please consider:
interface Universe {
  static final Integer theAnswer = new Integer(42);
}
That's it: Universe is an interface with a (well hidden?) static initializer! The expression new Integer(42) is not a compile-time constant, so the compiler emits the code for evaluating the expression inside a static initializer. Skeptical? Well, let's see what javap -c Universe has to say about it:
interface Universe{
public static final java.lang.Integer theAnswer;

static {};
  Code:
   0:   new     #1; //class java/lang/Integer
   3:   dup
   4:   bipush  42
   6:   invokespecial   #2; //Method java/lang/Integer." ":(I)V
   9:   putstatic       #3; //Field theAnswer:Ljava/lang/Integer;
   12:  return

}
if that isn't a static initializer, I don't really know what it is ;)
I think it's rather curious that programmers are not allowed to (explicitly) write static initializers in interfaces; I don't really see what problems could arise in allowing it.
However, there is a simple workaround: put the code inside static methods of a dummy nested class (this class should be private, but we can't make it private as all interface members are implicitly public). In our running example this idea translates to:
import java.net.*;
interface I {
  InetAddress me = Dummy.getAddress();
  class Dummy {
    private static InetAddress getAddress() {
      try {
        return InetAddress.getLocalHost();
      } catch (UnknownHostException uhe) {
        uhe.printStackTrace();
        System.exit(-1);
        return null; // not really, but makes the compiler happy
      }
    }
  }
}

Friday, August 8, 2008

Alice: a very cool way to teach programming

Alice is a freely available teaching tool designed to be a student's first exposure to object-oriented programming.

The idea reminds me of the Turtle Graphics of LOGO, that is, making the programming activity more "tangible" by leveraging a parallel with the real world, where (real) objects can interact. Anyway, about thirty years have passed since those seminal ideas were born and Alice is definitely up-to-date.

Alice is an innovative 3D programming environment that allows to learn fundamental programming concepts in the context of creating animated movies. In Alice, 3-D objects (people, animals and so on) populate a virtual world and students can create programs to animate these objects. I've particularly liked the way programs can be built: everything is very visual and you can do a lot of things by simply choosing actions and their objects. The environment is a sort of an extremely simplified IDE, which is great as the students can get accustomed to the environments they will use later. Also, it's easy to construct new actions by making sequences, loops and so on... that, is programming but without the hassle of pairing curly braces ;)

The current version of Alice (2.0) seems very promising but rather limited in what you can do after the basic skill has been acquired (which is quite a goal anyway!), however the next version promises to bring Java and the Sims-2 characters into play! I'm looking forward to that: if I have to teach basic programming skills, that's a tool I'd love to play with.
If you're a teacher, then I strongly suggest to check Alice out!
(it requires no installation and can run on Windows, Linux and Mac OS X)

Tuesday, August 5, 2008

Installing fully encrypted Windows and Ubuntu on the EEE 900

In the last few days I've played a lot with my latest toy, an ASUS EEE 900, that I really love. The only thing I have a hard time with is its keyboard: it's very small, which is both cute and uncomfortable (anyway, an external rollable keyboard could easily solve this matter).

I've managed to get Windows XP and Ubuntu working, sharing a data partition on a fully encrypted disk (well, actually "fully" means "all partitions except for the Linux /boot").
Also, I've installed both operating systems using a pendrive, without resorting to an external CD/DVD reader (that I don't have). While all the information on how to do this are already around, in a form or another, I hope that this mini-tutorial (but long post), containing pointers to the tutorials and tools I've used, will be useful anyway.

Before going on, let me state a thing very clearly: this mini-tutorial is targeted to sysadmins: you can easily lose your data or make your computer stop working when "playing" with partitions, MBRs and so on. I'm just telling what worked for me once. There are no guarantees that what I'm describing here will work for you too. So, please read everything once and don't even start if there is anything unclear.

My EEE PC has 20 GB, split into two drives of 4 and 16 giga. I've decided to install Windows on the first drive (4 giga), use 8 giga for a shared data partition and leave the remaining 8 giga for Ubuntu. The shared partition will be encrypted using true crypt, and formatted with NTFS for obvious reasons; that is, I have no idea how to mount ext3 partitions on XP and FAT... well... sucks ;-)

First of all, how can we install an operating system without a CD reader? We can create a bootable Windows Installation Pendrive, using an installation CD (or, of course, a mounted ISO) and USB Multiboot. It's a very easy to use program and the pendrive created with USB Multiboot has worked like a charm. Roughly the same idea works for Ubuntu, but we'll talk about it in the following.

So, let's start booting from the Pendrive containing the Windows Installation. In order to boot from the pendrive, you have to change the boot order in the EEE BIOS; to enter the BIOS press F2 while booting.

Now, take a deep breath and erase all partitions. I know: it's scary and the feeling of having just done something really bad will haunt you until you'll see the Windows logon screen ;-)
Then, proceed with the installation of XP on the first drive (that is, create a single NTFS partition as large as possible).

Note: rest assured that in the end both operating systems will be on encrypted partitions, but we'll reach that goal in a few steps. First we'll install Windows on a plain partition and create the shared data partition, then we'll install Ubuntu on a (newly created) encrypted partition, and finally we'll encrypt the Windows system partition and format the shared (encrypted) data partition.

If everything has gone as it should, you can now boot Windows. Inside Windows, create the 8 giga data partition (using the Disk Management function of XP) but don't format it yet, we'll format it using truecrypt later. You'll probably want to install Windows drivers now; just download them from the ASUS site and follows the instructions. Hopefully, there are no surprises there. Let's think about Ubuntu now.

While there are Ubuntu distributions for the EEE (for instance, Ubuntu Eee), I think their installation don't allow to encrypt the drive, so we're going to use the official Alternate Install CD and then we'll apply some patches to make all the feature of the EEE work.

While there is a "standard" way to install Ubuntu from a pendrive, it didn't work for me. After a couple of failed attempts, I've luckily found a blog post with detailed instructions that worked :-)
Bear in mind that those instructions are for Gutsy, so you have to change a few URLs (http://archive.ubuntu.com/ubuntu/dists/hardy/main/installer-i386/current/images/hd-media/...) to install the current version of Ubuntu.

Now you should be able to install Ubuntu booting from the pendrive, as we did with Windows. As I said before, we're going to install Ubuntu on an already encrypted partition, so in the installer choose to manually partition the drives and be careful; a very useful tutorial can be found in this blog post. Basically, along the (unformatted) 8 giga data partition, create a small boot partition (the only partition that will remain unencrypted) and a “physical volume for encryption” in the remaining space. Inside this volume, create a “physical volume for LVM”, containing a swap partition and the root partition with the remaining space.
Install Ubuntu and, for the time being, allow the installer to write GRUB on the MBR.

Now you should be able to boot both the unencrypted Windows and the encrypted Ubuntu. I've stressed you should because, well, I couldn't :-(
GRUB was correctly installed on the MBR, but from GRUB I could only boot Ubuntu. Windows boot failed saying that the file hal.dll was missing or corrupted.
So, I booted Ubuntu (not that I had much choice) and mounted the NTFS Windows system partition under Linux. I looked inside the folder system32 and there it was: hal.dll. So it was certainly not missing, maybe corrupted? Maybe. Maybe not. Indeed, it was not.
I solved the problem editing the file c:\boot.ini, which is a sort of GRUB menu.lst, replacing a 1 into a 0 because... it felt right... I know it's stupid, yet it worked. Windows booted, although showing a strange error on a command console that popped up from nowhere. Unfortunately I haven't written the error down and it vanished without ever reappearing.
My point is: I've fixed the problem, but I don't know why and, moreover, I don't understand what went wrong. I mean: before installing Ubuntu, Windows worked fine with the given boot.ini and Ubuntu installer should have not touched the first drive at all, so the old boot.ini should have worked fine. There it is: an unsolved mystery. I'm writing this down for a reason though: if the same thing happens to you, don't panic and don't trust Windows error messages ;-)

Now it's time configure Ubuntu for the EEE. Fortunately, there are pre-made scripts that do all the dirty work :-)
I've used this script, which is a slight modification of this one (see the site) to make it work for the EEE 900.
Of course, check the script before running it (you're reading a tutorial about installing everything on an encrypted drive, please don't tell me that you'd blindly run any script linked from a blog post!).
Alas, the code of the wireless drivers has changed, so after having run the script, check the README inside madwifi-ng-r3366+ar5007 and follow those instructions. For more tweakings, check this site.

Back to our installation story: when you can boot both (unencrypted) Windows and (encrypted) Ubuntu it's time to encrypt Windows. Before doing that, you need to install GRUB to a partition because the MBR will be overwritten by the Truecrypt loader. The truecrypt loader can do two thing: the former is starting up Windows from an encrypted partition (duh!), and the latter is passing the control to another bootloader, which can be installed in any partition (even on the second drive). In my case, the Linux boot partition was /dev/sdb3 so I've installed GRUB there issuing sudo grub-install /dev/sdb3

Now, boot Windows, download and install truecrypt (reboot if necessary), and encrypt the system partition (from truecrypt menu: System -> Encrypt System Partition/Drive...). Truecrypt will create an ISO of its rescue-disk (specific for your system) and will not continue until you've successfully burnt the ISO on a CD. Uhm... ok, it's a sensible choice and it's probably idiot-proof... yet, I didn't have (and want to connect) an external CD burner. So I copied the ISO to a pendrive (because making a copy is sensible) and cheated ;-) mounting the just-copied ISO with an old version of Daemon Tools. That did the trick :-)
Note: old version of Daemon Tools were free, with no strings attached. As far as I understand, now there exists a lite version that can be freely used for private use but I'm not sure. Anyway, any tool that allows you to mount an ISO file as a drive should work as well.

After a reboot, your Windows system partition will be encrypted, so it remains to encrypt the last partition: the shared one. Now, it's a piece of cake: just use truecrypt to create an NTFS volume (Volumes -> Create New Volume... -> Create a volume within a non-system partition/device).

At this point, on power up the EEE will start showing the truecrypt loader screen. From there you can either: enter the passphrase and boot Windows, or press ESC and use GRUB to boot Linux (the passphrase will be asked shortly thereafter).

In Linux, after you've installed the package truecrypt, you can mount the shared partition with:
truecrypt --filesystem=ntfs --mount /dev/sdb1 mountpoint
or by using the Truecrypt GUI (of course, assuming /dev/sdb1 is the shared partition)

Phew! This was indeed a long post, my longest post ever (among all the three I've written so far :-) )

Monday, August 4, 2008

Audiotapes, a trip down memory lane

Once upon a time there were homecomputers, that used analogue audio tapes to store programs. Those who've played with computers in the eighties will surely recognize some of these tapes from tapedeck.org

Saturday, August 2, 2008

Achieving your childhood dreams

Randy Pausch was an American professor of computer science, who died from cancer when he was 47.

Randy has achieved worldwide fame for his "The Last Lecture", a speech entitled Achieving your childhood dreams, that manages to be touching, fun and extremely inspiring.