15/11/2016

Amiga Emulation 101

Hey everyone! I mentioned I've been working on an Amiga article. Sadly I got sidetracked: I had to upgrade to Windows 10, and found myself thwarted when moving my existing Amiga setup from the Linux laptop. I could have worked out the culprit (smart money's on memory corruption on the USB stick) but troubleshooting bores me to tears. I decided to make a new installation instead, with all the usual programs necessary for coding on the Amiga. At which point I realized, hey, someone other than me might find this useful.

So, in short, here's how to set up an easy-to-use Amiga 1200 desktop environment on either Linux or Windows.


Setting up the A1200

Ah, the trusty Amiga 1200. In my opinion, the 1200 sits closest to the sweet spot of the Amiga experience: faster than the 500, reasonably inexpensive to purchase, with four times the chip memory, gobs of expansion options and of course the AGA graphics. Back then, it was as if someone had taken the 500 and improved it across the board.

Of course, in hindsight, it wasn't a perfect machine. Blitter fill rates, sound quality, number of hardware sprites and floppy drive capacity hadn't kept pace with the other improvements. The AGA architecture, while more capable in certain areas, lacked the elegant, Swiss-watch interconnectedness of the OCS and ECS machines. Mostly, the 1200 was too little and too late, debuting half a decade after the point of being able to replicate the revolution that the original Amiga 1000 had been.

Nevertheless, the 1200 remains the easiest way to achieve a reasonable desktop experience on a low-end Amiga. Therefore, while the A500 or A2000 may be a "purer" way of experiencing the Amiga, this is not what we'll do in this instance. Instead, we'll emulate an Amiga 1200.

This tutorial has the following prerequisites:

  • a modern desktop, preferably running Windows 7/8/10 or Linux,
  • an internet connection, and
  • a ROM file of the A1200's kickstart chip (see below),
  • a full set of Workbench 3.1 floppy disks (or images thereof), and
  • snacks (optional).

The kick-rom (that is the kickstart file) is an image of the physical ROM chip that sits on the Amiga 1200 motherboard. The 1200 was originally released with version 3.0 of kickstart; the difference to 3.1 is fairly marginal and should not matter much for this tutorial. What does matter is that the emulation software we're going to use requires the kick-rom file to operate. Without that ROM file, the emulator will not run, and the ROM file is not free to distribute.

How to get a kick-rom file? Well, if you own a physical Amiga 1200 with access to Internet, you can download a program called GrabKick from Aminet. That will extract a file which you can then transfer to the PC.

The alternative is to buy the ROM from Cloanto, the current distributors. Their Amiga Forever package is a very good purchase; they offer various software and ROM packages as well as a complete easy to use Amiga environment at a very reasonable price. We're going to try a different approach to theirs for this tutorial, however, so if you buy their CD, don't bother installing the whole package.

FS-UAE

We're going to use an emulator, and when it comes to the Amiga, there's really only one: UAE. The acronym is commonly interpreted to mean Universal Amiga Emulator, but it originally stood for the Unusable Amiga Emulator, due to its inability to even boot. Further refinement provided the features theretofore missing. With the introduction of just-in-time compiling it got a hefty speed boost, and UAE today is fast enough to emulate Amigas with PowerPC accelerators and GPUs while still remaining cycle-exact.

UAE comes in different flavors, one of which is called FS-UAE. The FS part is the GUI built on top of UAE, and for my money it's a far more uncluttered and usable experience than WinUAE. As a bonus, it is available for major Linux flavors as well as Windows, and behaves identically between platforms. Download FS-UAE and install it according to these instructions (with the current version, you no longer need to edit the config files).

The first thing you need to do is to import the kickstarts. By clicking the top left icon, you will see a menu. Here, you either select Import Kickstarts... (if you extracted a free-standing kick-rom file) or Amiga Forever Import... if using Amiga Forever. Next, under Amiga Model, select A1200 and the appropriate ROM configuration (either 3.0 or 3.1/020 will do fine). Under Joystick & Mouse Port, select No Host Device for the joystick -- this will allow you to use the arrow keys when coding. Finally, register and save this as your configuration (left-hand list box).

Next, in the tab list, click on the tab icon that looks like a black chip. This takes you to the Kickstart ROM tab. Here, select Custom and choose your kick-rom file. You may also tick "Zorro II Fast RAM" - select the largest amount. Save configuration.

Now, click on the floppy icon in the tab list. This allows you to uncheck (and thus activate) all four potential floppy drives, which we will do for the sake of convenience. More important is the Media Swap List; FS-UAE requires you to add all floppies you can use beforehand. Click the plus sign, then select all the Workbench 3.x disks.

So far, we've set up a fairly standardized Amiga 1200 with some extra peripherals. However, there's one thing missing that we really need: a hard disk. Click the main menu (top left tab icon). From the menu, select HDF Creator... and create a non-partitioned HD file which you call System (a size of 60 MB should be enough). This creates a file that acts as a hard drive. Select the Hard Drives tab, and pick the file you just created.

Now, start FS-UAE with the Workbench disk in you primary floppy drive. Boot it up. You'll see your hard drive as an unformatted non-Dos disk. Click on it, select Format from the menu, using FFS (Fast File System) with no trash can. Format. Now, load the Install disk into DF1:, and Locale and Extras in the other two. Double-click on the Install disk, then on the Install Workbench icon. In the installer, select intermediate level, and when it comes to installation directory, select your System hard drive (for some stupid reason, the default is DF0:!). Installation should prompt you for disks as they are needed. Once you're done, Workbench 3.x will have been installed.

Configuring Workbench

The first thing you need to do is close down the Amiga. We need some way to get files onto the machine, and the easiest way is for you to mount a second hard drive under the hard drives tab. Instead of mounting a hard file, you can mount a Windows or Linux directory. I usually find it simplest just to mount the Downloads folder. Now you can freely move files between your main computer and onto the Amiga. Workbench will treat it as if it's a regular hard drive (as long as you select "show hidden files" from the menu).

Workbench is pretty well set up for serious work right off the bat, but there are a few things it lacks. Its greatest Achilles' Heel is arguably the lack of a decent command line interface. While the default CLI is leagues beyond MS-DOS, that's really damning with faint praise. To fix this, we're going to download KingCON (also known as Newshell) off of Aminet. KingCON is unfortunately packed in lha format. You can either use a free utility like 7-zip to open it up on the PC, or download Lha from Aminet. If you do the latter, move Lha.run to RAM:, execute the file there, then copy the archiver (called lha_68020) to the System:C/ folder. The other files are unnecessary.

Next, move KingCON_1.3 to RAM: and unpack it there. Execute the installer, and follow the instructions (basically, you enter the cli, type "ed s:user-startup", change KRAW and KCON to RAW and CON, and add the unmount CON: / unmount RAW: commands as it directs).

Slightly complicated? Perhaps. On balance, I think the new CLI (which lets you use the TAB key to autocomplete or choose files from inside a file requester) is easily worth the small hassle of installation.

Back up the hard-file; we're almost done.

Making it pretty (optional)

Workbench does look a bit drab. Nothing that can't be fixed, however -- all you need is to download Magic User Interface and MagicWB. Copy them to RAM: as usual, and then install.

Conclusion

You should now have an Amiga WB environment up and running. I've tried to keep my tutorial as general as possible, so I've avoided actual programming environments, DirOpus, graphics editors like DPaint, et cetera. There's a ton of useful software to that effect, and I'll mention others when needed.

This has been a primer on how to painlessly set up an emulated Amiga environment. I hope you liked it and will, as always, be grateful for feedback.

08/11/2016

On (Recursion (Recursion (Recursion ...

Hello everyone! I had an Amiga article all planned and ready, but since I couldn't make up my mind on the exact restrictions, I kept putting it off. Enough is enough. Now I found myself with a rather stream-of-conscious take on a common programming technique. To wit, it's about the use of recursion, and my struggle to make intuitive sense of it.

So, without further ado, here we go.

On recursion

The effective exploitation of his powers of abstraction must be regarded as one of the most vital activities of a competent programmer.
--Edsger W. Dijkstra

What's the best way to understand recursion? As the old joke has it, you must first learn recursion. Proponents of this technique claim it is an intuitively obvious, far-simpler way of iteration compared to the more popular imperative ones, and that it's only our mindset (maimed as it is by earlier exposure to imperative programming) that has us thinking otherwise.

Personally, I think that's a crock of shit. We all know recursion isn't simple, otherwise the joke would make no sense.

Holding up recursion as some sort of replacement for iteration is also bullshit. Loops are good. For-loops are okay. While-loops are good. All of them work in place of recursion, but that doesn't make them the same. They handle iteration differently. They have different strengths. They are separate idioms. And so, as in all programming, they require separate metaphors to be properly explained.

Now, it's no wonder that imperative programmers are used to while loops: it's built into our metaphor about how programs are supposed to execute. Recursion, though, requires us to revise our expectations. Loops are like a moving watch, with hands (numbers) that increase in proportion to each other, one sometimes triggering an alarm (a specific method call) or clicks over into a new state. So what makes a useful recursion metaphor?

Well... for me, recursion is all about what you see from where you are.

Traditional loops are flat. We see everything as one big field of similar items, or a big mass of numbers. All of these numbers are operated on by the loop, so we need to understand them and their interactions as a gestalt, as a whole. If we don't understand everything about the loop and the data on which it operates, the loop will at some point go off the rails. Those are a lot of factors for a programmer to juggle.

Recursion is different. In a proper recursive algorithm, your data is a structure, a grid. The shape of the grid doesn't really matter: all that matters is what happens on your immediate position on the grid. All you need to remember is that once you step one level up and down in the recursion, you are in effect moving along the grid. That's intrinsic to the structure, to the algorithm's idiom, so you don't need to keep track of it. All you need is to understand what happens at the specific point you occupy.

To me, where the metaphor of regular loop suggests enumeration, the metaphor of recursion suggests traversal. A regular loop chews through items on a level playing field. Recursion moves from node to node, like a spider flitting across a web. That makes recursion a natural fit for things that have tree-like behavior, but less ideal for things like iterating across flat containers. It also means the node is all you need to care about, which means less cognitive work.

Recursion can replace loops in a pinch, yes. By the same token, a wrench can do the work of a hammer. That doesn't make it the best tool for the job.

Perhaps I'm still poisoned by imperative thinking. It may be that Dijkstra, from whatever coder heaven he now resides, is even now shaking his head and muttering something about the irreparable damage of BASIC. Nevertheless, and this may sound paradoxical, I think recursion is even more useful if placed in constraints. And when it comes to coding, perhaps an abundance of metaphors isn't such a bad thing.

That's it for now. If you still have problems wrapping your head around recursion, I refer you to this article.

09/10/2016

Interactive Fiction with Inform 7

I like the idea of writing Interactive Fiction. If you're here, chances are that you do, too.

Today, there are many options for writing parser-based IF. I'm a C++ programmer by trade, but perhaps surprisingly, my tool of choice isn't the C-like TADS 3. Instead, I decided to learn Inform 7, where the code you write is essentially English.

This won't be an I7 tutorial. Several excellent ones already exist online, and there's also a book on the subject. Instead, I thought I'd list a few techniques that make I7 writing easier.

When a phrase might yield "nothing", always make it an object

It's a common pattern: you write a bit of code to pick out a specific object according to certain criteria. The problem is, sometimes there is no valid result. In that case, you want "nothing."

Your bedroom is a room. The house door is a door. It is west from the bedroom and east from the Garden. The house door is locked. The key is here. The key unlocks the house door.
The Lodestone Room is west of the Garden. 

The player carries the brass compass. The description of the brass compass is "The dial points quiveringly to the [magnetic direction]." 

To decide which direction is magnetic direction:
 decide on the best route from the location to the Lodestone Room, using even locked doors.

There's a problem here. When we reach the lodestone room, the compass will generate a runtime error, because nothing is of the wrong type: not a direction, but an object.

This is easy enough to fix: just make the return type of the phrase into an object.

Your bedroom is a room. The house door is a door. It is west from the bedroom and east from the Garden. The house door is locked. The key is here. The key unlocks the house door.
The Lodestone Room is west of the Garden. 

The player carries the brass compass. The description of the brass compass is "The dial [if the magnetic direction is nothing]spins and spins, not settling on any direction[otherwise]points quiveringly to the [magnetic direction][end if]." 

To decide which object is magnetic direction:
 decide on the best route from the location to the Lodestone Room, using even locked doors.
Of course, there are phrases that should never yield nothing. For such phrases, it's prudent to retain as much type information as possible.

On changing the auto-generated prose text for supporters

One of my pet peeves in Inform 7 comes up when I want to describe a room containing a supporter. When the supporter is empty, it's okay. The problem comes when the supporter holds something.
Moldavian Grouse
A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead.

You can see a bar (on which is a shot of fine whiskey) here.

>x bar
As old and sturdy as a fallen oak. 
On the bar is a shot of fine whiskey.
There are several interrelated and unrelated issues at play here. The first is the parenthesized part after mentioning the bar. In this case, that issue easily resolved by giving the bar an initial appearance. While that won't work for a portable supporter, it does us nicely here:

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."

The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar." The description of the bar is "As old and sturdy as a fallen oak." On the bar is a shot of fine whiskey.
This raises a different problem, though: now there's a tacked-on message below the bar's initial appearance, saying "On the bar is a shot of fine whiskey." How do we change that?

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."
The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar[if something is on the bar], [a list of things on the bar] atop it[end if]." The description of the bar is "As old and sturdy as a fallen oak." On the bar is a shot of fine whiskey.

Interestingly, that kills the supplementary "On the bar..." message!

There's no magic to it, though. What happens is that, by printing a list of things during the room description, Inform correctly deduces that we've mentioned them. A mentioned thing is not listed again (in fact, when it automatically enumerates things in the room, that Activity is actually named "listing unmentioned things").

However, there's still one remaining problem, the generic listing of items upon the supporter. Unlike the case with room description, that listing is not suppressed by mentioning the item beforehand. What's at work here is the examine supporters rule, which looks like this:

Carry out examining (this is the examine supporters rule):
 if the noun is a supporter:
  if something described which is not scenery is on the noun and something which is not the player is on the noun:
   say "On [the noun] " (A);
   list the contents of the noun, as a sentence, tersely, not listing concealed items, prefacing with is/are, including contents, giving brief inventory information;
   say ".";
   now examine text printed is true.

That rule is easy enough to turn off, like so:

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."

The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar[if something is on the bar], [a list of things on the bar] atop it[end if]." The description of the bar is "As old and sturdy as a fallen oak[if there is something on the bar], holding [the list of things on the bar][end if]." On the bar is a shot of fine whiskey.

The examine supporters rule does nothing when examining the bar.

Of course, this also lists scenery items, and it would also list the player should the player be on the bar. In this instance though, the above is perfectly adequate.

The going action allows two prepositions, both useful

This one is short and sweet. Not too long ago, I was told of a particular turn of phrase with useful properties. This is about the going action. Consider the following:

The Shadowy Forest is a room. "Gloomy pine trees surround you in the gathering mist. The haze makes it difficult to see clearly, although you can just about make out a sloping trail to the west."
The Brook Clearing is west of the Forest. "A merry brook winds its way through the turf here."

Instead of going nowhere, say "You'd just get lost."
Instead of going up in location, say "There's no way you could climb, given your back problems."

How does this work? Well, there are a few prepositions bound to the going action. First, it's "going [direction] from" and "going [direction] to". These refer to the action of going a valid direction. Then, there's "going nowhere", which refers to going (but failing to go) in any invalid direction.

Both of these wholly depend on whether the direction is valid or not. But sometimes, you don't want to do that; sometimes, you want to intercept the mere attempt to go in a given direction (no matter if it's a valid one or no). For that purpose, you can use the "going [direction] in" construction.



That concludes my first Inform 7 piece. Thank you for reading. Although I hope this post was useful, it may need improvement, and any feedback you could give would be much appreciated.

26/09/2016

Introductions

Whether you're a stranger or an old friend who stumbled inside, hello and welcome! 

My name is Björn Paulsen. I'm a several things: a software developer by trade, a nerd by nature, a Swede by birth, and a father by the skin of my teeth. And while I don't pretend to have reached mastery in any of these noble pursuits, I hope I'll have enough to say about some of them to provide some entertainment.

It's not my first blog. I once kept a Livejournal account, which was succeeded by my own Wordpress page hosted from a server in my closet. The first was awkward to administrate, the second impossible to migrate. For a time, as opportunity died, so did my interest.

Public participation in sites like Facebook or Quora, however, can only hold one's interest for so long. One day, I realized I'd missed having a blog. So I started to look around. At first blush, Blogger seemed a reasonable platform. I signed up.

The next few posts will probably be me trying to get the hang of this format. I'm not going to emulate my previous blogs in terms of style, even though I may occasionally post older stuff that I'm particularly happy with. This is a fresh start, and deserving of a fresh tack.

Thanks for reading this far. There'll be more soon, proper content. Stick around.