Chicken and rice

July 7th, 2008

It's recipe week this week at Reenigne blog. Not my usual fare, but not completely without precedent either. Some of these recipes (including this one) are from my mother, others I've made up or adapted myself.

  • 1 onion peeled & chopped
  • 1 carrot peeled & chopped
  • 3 sticks of celery washed & chopped
  • about 2 tbsps oil
  • about 2 tbsps flour
  • 1lb chicken
  • 1 chicken (or vegetable if vegetarians are joining in!) stock cube stock cube dissolved in 10 - 15 fl oz boiling water
  • handful frozen peas &/or sweetcorn
  • a few mushrooms sliced
  • about 2fl oz cream

If the chicken is raw cut it into bit size bits and fry it in oil 'til it's browned. It doesn't have to be cooked through at this stage. Remove it from the pan with a slotted spoon to drain the oil off. Now fry the onion, carrot & celery in the oil 'til they just start to brown but you don't want them too dark. Add the flour and stir it in until it coats the vegetables and cooks a bit. Add the liquid gradually, - stirring all the time and bring to the boil still stirring. It should thicken.

Add the peas, sweetcorn and mushrooms. If you're feeding vegetarians, separate out their bit and add the chicken to the rest. You could add other vegetables or extra mushrooms to the vege bit. Season with salt & pepper and simmer the whole lot until the chicken is cooked through and the vegetables
are tender. If it's not thick enough you can add some cornflour mixed with water to make it thicker. Add the cream at the end. If you've got any herbs bung them in too and it'll be even yummier.

Cook the rice in a separate pan while the whole thing is cooking.

You can adapt it as you see fit - put in leftover sausages for example or add a bit of chopped up bacon with the onion etc if you're all meat eaters, or serve it with pasta instead of rice.

Generations of screen sizes

July 6th, 2008

If you make a list of common screen resolutions and plot them on a log/log scale, you will notice that a regular pattern emerges - given an x by y resolution, x*2 by y*2 also tends to be common. However the sizes are not evenly distributed throughout logarithmic spaces - there are gaps which suggest different "generations" of monitor sizes, each monitor having 4 times the number of pixels as the corresponding monitor in the previous generation. I suspect this is because of the influence of TV - the resolutions are clustered around powers of 2 of TV resolutions.

Generation 1 - 256-480 pixels wide, 180-300 pixels tall (non-interlaced TV, handhelds)
Generation 2 - 512-960 pixels wide, 360-600 pixels tall (interlaced TV, older computer monitors)
Generation 3 - 1024-1920 pixels wide, 720-1200 pixels tall (most current computer monitors)
Generation 4 - 2048-3840 pixels wide, 1440-2400 pixels tall ("Q" standards - very high end monitors)
Generation 5 - 4096-7680 pixels wide, 2880-4800 pixels tall ("H" standards - no monitors exist yet)

Screen aspect ratios as musical notes

July 5th, 2008

Aspect ratios of televisions and computer monitors tend to be ratios of small integers. On my desk right now I have 3 monitors that are 4:3 and one that is 8:5.

Another thing involving ratios of small integers is musical intervals in Just Intonation.

C 1:1
C# 16:15
D 9:8
D# 6:5
E 5:4 5:4 monitors exist but are not common
F 4:3 the most common non-widescreen aspect ratio
G 3:2 3:2 monitors exist but are not common
G# 8:5 the most common computer widescreen format
A 5:3 5:3 monitors exist but are not common
A# 16:9 HDTV format
B 15:8

Lispy composable compiler

July 4th, 2008

When I finally write the compiler for my super-language, I want to make it nice and modular - i.e. make it very easy to compile different languages, target different architectures and include different optimizations.

In order to achieve this I will need to have some kind of intermediate form in which pieces of code in various states of compilation to be transmitted from one module to another.

This form should be as simple as possible but should also make it possible to express all the complexities that occur in real code. In short, it will need to be a tree structure.

While I'm not convinced that the Lisp idea of "code without syntax" is a great one (I think every available visual/syntactical clue makes it easier to understand unfamiliar code) I have to admit that the lisp data structures (SExps and Lists) are perfect for this role. I wouldn't expect people to be reading large quantities of this code but it's handy to be able to print it out for debugging purposes.

A Symbol (what lispers call a SExp, S-Expression or Symbolic Expression) is either an Integer, a String, an Atom, a List or a Vector. Integers are what you'd expect them to be. Strings are used to hold things like variable names. Atoms are displayed as strings but treated as unique, opaque integers internally. All you do with an Atom is compare it to another Atom and see if they are the same. See Stringy Identifiers for another perspective on these. This is not quite the same as the lisp usage of the word, where integers are also atoms.

A List (delimited with parentheses) is effectively an object. It consists one or more Symbols, the first of which must be an Atom. It has a type, which is represented by its Atom and the number and types of the following Symbols.

A Vector [delimited with square brackets] is effectively an array of length possibly not known until run-time. This can be used for a sequence of statements (for example) or for the bytes in the compiled program before it is output to disk. Lisp doesn't distinguish between lists and vectors but I think it is useful to keep them separate.

It is not a coincidence that this is quite similar to the RTL of GCC. Many of the same problems are being solved, and I was learning about RTL when I came up with this. However, this structure is a little more general-purpose and a little simpler. In particular it can also be used for front-ends.

These expressions will generally be manipulated by pattern matchers - that is, we search through the program for an object matching some characteristics, perform some transformation on it and then substitute the result for the original object.

For example, here is a part of an x86 assembler written in a hypothetical language which has support for these Symbols built in:

    with(x) {
        match (`jmp` d:Int):
            if (isSByte(d))
                becomes (`db` [0xeb d]);
            else
                becomes (`db` [0xe9 bytesFromDWord(d)]);
        ...
    }

This matches a List which consists of the `jmp` atom followed by an integer (which we will call d). We pass that integer to a function and (depending on the result) we emit one of two possible forms of the x86 JMP instruction. As "bytesFromDWord" is known to be a function and not an Symbol, it is evaluated and the result placed into the vector rather than two Symbols (bytesFromDWord and (d)) being created and placed into the vector.

This works just as well for the front end. The "unless" statement that I have written about before can be broken down using this code:

    match (`unless` condition): becomes (`if` (`!` condition));

And we should have this optimization as well, in case condition is itself a negated condition:

    match (`!` (`!` x)): becomes (x);

Quite a lot of the compiler can be written very easily and tersely this way. There are some complications to do with the order in which transformations are applied, though - we would rather avoid having to specify that explicitly and let the computer figure it out. But the order might depend in quite a complicated way on the context. One way to deal with this might be to keep the pre-transformed Symbol around and continue to match against it even after it has been replaced. Another might be for transformations to transform other transformations as they are applied to the Symbols. I haven't quite figured this bit out yet. This seems like one of those problems that might be technically intractable but always works out to be fast enough in practice.

With some cleverness, it ought to be possible to write a very good compiler this way. Great speed is possible as no string handling is done after the initial parsing phase and symbol table lookups (e.g. we don't write out assembler instructions and rely on a separate assembler to assemble them, though we could still easily obtain assembly code if necessary by having a separate output module.) Many speed improvements are possible (e.g. by performing some transformations when the compiler is compiled).

But the really great thing about this scheme is that code for the compiler is completely self-describing - it's exactly the code one would hope to be able to write.

Having a set format for code also enables the scenario I wrote about in Compiler compilers.

Finally, this structure works just as well for disassemblers and decompilers as it does for compilers and assemblers. Some of the algorithms will be different most of the transformations probably cannot be reversed directly but many of the same patterns show up.

Sampling keyboard

July 3rd, 2008

I'd like to write a piece of software which makes it trivially easy to record and instantaneously play back sound. This piece of software would be operated by holding down keys on the computer's keyboard. For example:

  1. Holding down 'R' records whatever goes into the computer's microphone while the key is held down and stored in the next unused buffer.
  2. Holding down 'P' plays back all the buffers at the same time (until the last buffer runs out or the key is released, whichever happens first).
  3. Holding down 'B' does both (with appropriate cancellation of the output signal from the input signal).

This software would enable a truly epic (and slightly shorter than normal) reading of the children's book "Doggies". For those unfamiliar with the book, there are ten dogs, each of which has a different bark ("Woof", "Yap yap", "Ruff ruff ruff" etc.). On the first page the first dog barks, on the second page the first and second dogs bark and so on.

With the aid of this software, the human reader/operator need only make each dog sound once. Furthermore, all the dog sounds would be heard simultaneously, making the immediate vicinity sound like a dog pound by page ten.

I'm sure there are other uses too, but this was the inspiration.

PAL version of demo machine

July 2nd, 2008

The demo machine described the other day could easily be generalized to PAL output. There are some complexities though. Because of the missing quarter cycle of the carrier frequency per line, the PAL signal for a still image repeats every 4 frames. This means that in order to do the same "extremely simple, highly standards-compliant demo" that was possible on the original demo machine for NTSC, we need 2.7Mb of sample data. Let's run with this and round up the PAL machine's memory to 4Mb - rather than making the PAL machine as similar as possible to the NTSC machine, we should take the opportunity to introduce some variety.

Similarly, the CPU clock speed for the PAL machine should be (exactly) 17.734475MHz.

Generating interesting standard PAL signals does have some complications that NTSC signals don't have. Because of the 25Hz offset, the colour carrier frequency starts at a different phase on each line, meaning that a sprite needs to have different sample data depending on its vertical position. I expect that most demos written for the machine would use one of three simplications of the PAL standard (as most if not all computers and consoles that generate PAL signals did):

  1. eliminate the 25Hz offset so that the colour carrier phase repeats every 4 lines
  2. use a whole number of subcarrier cycles per line (making the chroma patterns vertical)
  3. eliminate interlacing, doubling the frame rate at the expense of halving the vertical resolution

These simplifications change the horizontal and vertical retrace frequencies slightly from the standard 15.625KHz and 50Hz rates, but not so much that real hardware is likely to fail to display the intended image.

NTSC decoder

July 1st, 2008

I want to write a piece of software that simulates a colour television (well, monitor really). It would really be a filter - the input is a sampled, quantized composite (CVBS) signal at some sample rate and the output is a series of video frames scaled to some resolution. I'd want the composite->RGB transformation to be done at the same time as the horizontal scaling to maximize quality whilst minimizing computation time. That means dynamically generating the appropriate filter kernel for a particular pixel width and sample rate.

Such a thing would be particularly useful for emulating old computers and consoles which generated a composite colour signal directly (including the demo machine of yesterday's post). In particular, it would render colour artifacts and interlacing perfectly). It would also be useful for simulating (for example) how an image would look on a TV for applications like DVD mastering.

This is the kind of image it will be able to generate (this mock-up was done at fixed resolution and not in real time):

No high-frequency chroma filtering was done on this image, so you can see the chroma artifacts. I wanted to include an animation showing the dot-crawl effects, but animated GIFs don't go up to 60fps. It does look uncannily like a TV screen though.

Writing this filter might even inspire me to fix up the NTSC emulation in MESS and improve the video emulation of machines like CGA, Apple II, CoCo and Atari 400/800.

Demo machine

June 30th, 2008

If one were to design a computer specifically for the purpose of having Oldskool-style demos written for it, what would it be like?

I came up with a few requirements:

  • Oldskool "feel"
  • Attractive output: sampled sound and realistic looking (still) images can be achieved very easily
  • The more skilled the programmer, the better effects can be achieved - very great skill is required for the best effects
  • Hardware as simple as possible
  • Easy to emulate
  • Fun to program

To get that Oldskool feel but still allow realistic looking still images, I decided to base it around a composite NTSC signal. It turns out there is a standard for digital composite NTSC signals - SMPTE 244M, so I just picked the 8-bit version of that. The video hardware is about as simple as video hardware could possibly be - just an 8-bit DAC that repeatedly cycles through a consecutive region of memory and dumps the bytes to the output at a frequency of 14.318MHz (4 times the color carrier frequency). This is also the CPU clock speed (the CPU is in sync with the pixel clock).

Technically, a still image in this format that is fully NTSC compliant requires 955,500 bytes (933Kb) of memory (2 frames*910*525) because the color carrier phase alternates between frames. Given that the machine's memory size should be a power of 2 (so that we can map 32-bit addresses to physical addresses just by clearing the top bits) I decided to give it 1Mb (any more and it stops being so Oldskool). This doesn't necessarily mean that you need to use almost all the memory to store the framebuffer - by tweaking the burst/sync patterns you can get a 912*525 (468Kb) interlaced mode where you only need one frame, or a 912*262 (233Kb) non-interlaced mode (again with only frame), both of which should be compatible with any composite monitor. These have usable resolutions (including the overscan area) of about 720*480 and 720*240 respectively (with respective CGA-esque pixel aspect ratios of 5:6 and 5:12). So this gives a nice bit of flexibility to software with no extra hardware complexity.

One disadvantage of this setup is that it may be possible for software to damage some composite monitors by creating sync pulses too often. So one would probably want to use an emulator when testing/debugging programs! Also, scrolling is fiddly because you have to move the image data independently of the sync/burst pulses. There are block move instructions which can move 4 pixels per clock to help with this, though.

Audio is done in a very similar way to video - set the beginning and end of the region of memory and the hardware cycles through that memory range turning bytes into samples and putting them through a DAC. Another register is used to set the sample rate (I decided a fixed rate would be too inflexible).

Programs are just 1Mb memory images which are dumped into RAM. The first two words of RAM are the instruction pointer and the stack pointer, so execution starts at the address pointed to by the word at 0. I/O registers are also at the start of the memory region.

Most instructions are 1 cycle long (with the exception of instructions like the equivalents of "REP MOVSB" and "REP STOSB") to enable effects that require cycle counting to be done as easily as possible. Most instructions are 1 byte long (with the exception of instructions that have a 1-byte, 2-byte or 4-byte immediate argument). The CPU is 32-bit (to make addressing that 1Mb of memory easy). The architecture is stack machine based (kind of like Java) - I have a soft spot for such architectures because they're really easy to write decent compilers for (registers are helpful at the hardware level for making processors fast, but that isn't a particular concern here). Devolving the CPU has some ideas for generating a good instruction set.

Because of the cycle counting and simplicity requirements, there are no hardware interrupts - all timing must be done by cycle counting. This also means that there are no instructions whose purpose is to determine some value N and take O(N) time to do it - so no "REP SCASB" in this architecture. I don't think that is very useful for demos anyway, and it's a non-goal of this design to be suitable for general purpose computing tasks like searching and parsing.

It would be pretty easy to generalize this architecture to make a games machine - just have a register whose bits reflect the up/down status of controller buttons.

Now, while I'd like to believe that building such a machine would revitalize the Oldskool demo scene by providing a new focal point, I suspect a more realistic point of view is that because programming such a machine would be such a non-applicable skill, because the limitations of the machine constrain the possible effects, and because there would be none of the nostalgia inspired by actual Oldskool hardware, nobody would actually be interested. But it's still an interesting exercise!

Vocalsynth

June 29th, 2008

A fun toy would be a musical instrument with a microphone that can detect and modify pitch in real time. So if you sing an A but play a B it will transpose your voice up a tone. I understand such things are common in modern recording studios but I'm not sure if they work in real time (besides which, I don't think it would be too difficult to create such a thing from scratch).

Better still would be if it was polyphonic, so you sing a note, play a chord and hear a trio.

My favorite programming font

June 28th, 2008

Many colleagues, on seeing my screen for the first time, have been horrified at how small the text on my screen is. I tend to use 1600x1200 monitors, and a 6x8 pixel font for coding purposes. I have good vision at normal head/screen distances and I like to be able to see a lot of text at once (I can see the "big picture" and also the details without having to explicitly zoom).

My preferred font is the 6 point Terminal font that comes with Windows. When I started my new job, I switched to a Linux machine for most of my day-to-day work and one thing that took me a long time to figure out was how to get my terminal windows to display this font. I got it working in XTerm but copy and paste works better in Gnome terminal, which refused to acknowledge any non-TrueType fonts or even bitmap fonts in a TrueType package.

I eventually went through the same route that this guy went through to create his fonts - I extracted the bitmaps from the .fon file and turned them into outlines by creating a square for each dark pixel. The resulting .ttf file is 30 times as big as the original bitmap but it seems to work fine with everything I've thrown at it.

Here is the resulting TrueType font and here is what it looks like: