Make Home & End keys behave like Windows on Mac OS X  

I’ve been using Mac OS X daily since 2001 when I purchased my Titanium PowerBook and I still can’t get used the home and end key behavior.

If, like me, you want Home to send you to the start of the line and not to the top of the document then create a file called DefaultKeyBinding.dict in your ~/Library/KeyBindings folder (might need to create that folder too) with the following contents:

{
    "\UF729"  = moveToBeginningOfParagraph:; // home
    "\UF72B"  = moveToEndOfParagraph:; // end
    "$\UF729" = moveToBeginningOfParagraphAndModifySelection:; // shift-home
    "$\UF72B" = moveToEndOfParagraphAndModifySelection:; // shift-end
    "^\UF729" = moveToBeginningOfDocument:; // ctrl-home
    "^\UF72B" = moveToEndOfDocument:; // ctrl-end
    "^$\UF729" = moveToBeginningOfDocumentAndModifySelection:; // ctrl-shift-home
    "^$\UF72B" = moveToEndOfDocumentAndModifySelection:; // ctrl-shift-end
}

This remapping does the following in most Mac apps including Chrome (some apps do their own key handling):

  • Home and End will go to start and end of line
  • ShiftHome and ShiftEnd will select to start and end of line
  • CtrlHome and CtrlEnd will go to start and end of document
  • ShiftCtrlHome and ShiftCtrlEnd will select to start and end of document

Note that you will need to reboot after creating this file for it to take effect.

Also: If you have a PC keyboard with LED backlighting and would like the scroll-lock, num-lock or caps-lock LEDs on when using your Mac check out my free SetLEDS for Mac

[)amien

Revitalizing a BBC Micro  

Moving house means making possessions count so my collection of vintage computers has shrunk over the years and the bar keeps getting higher. Right now:

  1. It works – Test it, repair it or part with it. A wealth of online technical information makes this easier than ever.
  2. A small footprint – Eject unusable peripherals and accessories. Keep the essentials.
  3. Make it usable – Forget slow-loading tapes and corrupt disks, a fast loading is essential.
  4. Something special – It should either be collectable or one I have a connection with.

Recent casualties were my Apple ][e (no disks), Acorn ARM (wouldn’t boot) and Commodore VIC 20 (poor state). Next up is my Acorn BBC Micro B:

BBC attached to Amstrad monitor and giant twin floppy drives

Physical inspection

My ‘Beeb’ is in good condition and works well although the case screws have long since disappeared (a common theme in my collection) and it needed a good clean. These older mechanical keyboards attract serious dust and dirt.

Schools were filled with BBCs in the 80s and I’ve written about the origins of this love affair before. I learned first BBC BASIC and then some 6502 assembly (mixing it with Basic) while at school. I later picked this machine up around 91 after seeing a local paper advertisement.

A giant twin 5.25″ drive housing system (shown above) contained my one still-functional floppy drive. I want to be able to read some physical disks but in keeping with the minimal footprint I transplanted the floppy drive into a 5.25″ externally powered CD-ROM enclosure. Big reduction.

The BBC Micro has a few video output options – UHF, composite over BNC and RGB over 6-pin DIN connector. By a staggering coincidence the pinout is identical to the Amstrad CPC so works directly my Amstrad monitor, no adaptor cable required this time!

Replacement media, SD cards via GoSDC

BBC Micro with SD Card fitted

SD cards are my replacement storage of choice for vintage systems. I chose John Kortink’s GoSDC for the following reasons:

  1. Supports MMC, SD, SDHC up to 32GB
  2. Internally fits into a spare ROM socket
  3. Adds operating system commands for great integration
  4. Supports disc images, tape images and ROM images

Retro Isle comprehensively reviewed GoSDC in February (2015) and have a bunch of usage tips and tricks too.

Getting started with GoSDC

The device plugs into a ROM slot but to make life easy you can give it access to a second one so it can patch the filing system. The docs are complex as they describe the many possibilities available. Here’s my setup that works well on a BBC Micro Model B (known as Option B in the docs):

  1. Remove Acorn DFS ROM
  2. Fit GoSDC in slot third from right
  3. Fit cable from GoSDC jumper (middle-left) to pin 6 up from bottom right
  4. You should be left with the Acorn OS ROMs in the ROM sockets to the left of GoSDC

Once fitted, slide in an SD card and power up your BBC and you should see the usual welcome screen. Then type *SDCINFO and see the results:

BBC Computer 32K

Acorn DFS

BASIC

>*SDCINFO

GoSDC (mbe) 1.05 (01 Sep 2014)

ROM slots : main 15, free 13

Flash ROM : S25FL007, 1024 KiB

Flash card : SDHC, 7580 MiB

Available areas
---------------
X :     416256 bytes
1 : 4294966784 bytes
2 : 3653238784 bytes

>

If you see ROM slots main and free with numbers your device is correctly controlling two slots and can patch the DFS for you. If not, check the adapter and cable.

If you see “GoSDC : No flash card inserted” check the card is securely in and power cycle the machine. If it still doesn’t recognize it try another card. Note: When switching card you will need to press CtrlBreak for the machine to recognize it.

The first time you use a card you’ll need to format it. The command and subsequent output should look like this:

>*SDCTOOL SDCFO
Formatting area ... done
Verifying format ... ok
Please hard-reset your machine now
>

If you have a card greater than 4GB then it will create 4GB areas which can be switched between with *SDCAREA number. I’d recommend switching to the additional areas, formatting and CtrlBreak after each before you put any software on it as this command will wipe it out again.

Finally you’ll need to tell GoSDC to provide a patched filing system like this:

*SDCCONFIG FSNR 1
*SDCCONFIG FSRM 13
*SDCRESET
  • 1 sets Acorn DFS on my machine although the docs says it should be 2
  • 13 should match the free ROM slot shown in *SDCINFO

If you mess up your ROM selection and are unable to type because of ‘No drive’ do not fear! Press caps-lock and break twice to get the prompt back and choose another.

Finding old software

One option is to image all your floppy discs to SD card but you are probably going to find that those discs are corrupted. Thirty year old floppy disks are not reliable.

Another option is to download old software online. This can be a grey area as the software is copyrighted but no longer sold and many authors are okay with allowing it (e.g. Ian Bell and David Braben of Elite fame). A great site that honors the wishes of authors can be found at the weirdly named Stairway to Hell.

The author of GoSDC supplies Windows scripts to download, unpack and write the files to disc which I took the liberty of porting to Bash so they could be used on Mac OS X and Linux.

Recommended old games

Purely based on subjective childhood experiences…

  • Elite a 3D space trading game so good they recently Kickstarted Elite 4
  • Citadel one hundred screens of arcade adventure madness
  • Chuckie Egg quick platform dash with birds, ducks, eggs and platforms
  • Repton Boulderdash to the next level, try 1 or 3, Repton 2 is insanely hard
  • Granny’s Garden educational fun alas distribution is denied as they sell an iPad version

Using GoSDC

Once the card is loaded up with software the actual commands are simple:

*SDCLIST

Will list the contents although you’ll probably want to put a wildcard after it to limit it down. Remember CtrlShift pauses the screen on the BBC!

Then, to mount a disc you use *SDCDISC and provide the name to mount. You can also use wildcards here and it will pick up the first match. e.g.

*SDCDISC *Chuckie*

Once mounted hold down Shift and tap Break to boot the game (or educational title, right?)

A few other useful commands are:

*. List contents of a disc
*EXEC !BOOT Is what ShiftBreak actually does
CHAIN "filename" To LOAD and RUN a BASIC program from disc
*filename To execute machine code programs from disc

I put some BBC Micro tips and tricks together or you can can grab PDFs of pretty much every book created for the BBC Micro .

You can also see which discs are currently selected using *SDCDISC with no arguments. You’ll note you can mount a second disc and the command to do that is *SDCEXTRA with usage otherwise exactly like *SDCDISC.

GoSDC can do much more including imaging your real floppy discs and writing them back out so be sure to check out the comprehensive documentation which also includes how to upgrade the firmware (use another memory card as that process uses FAT no the GoSDC file system)

Out for Pi Day!

Pi Day (3/14/15 = 3.1415) was last weekend and my work put on a session for kids about how to program the Raspberry Pi using Scratch and a breadboard (using CanaKits so we had a breadboard, LEDs, switches, wires, resistors etc.).

Me helping some kids with a circuit connected to their Pi!

The original Raspberry Pi was heavily inspired by the BBC Micro and even the name “Model B” took cues from the original. Few people also seem to realize that the manufacturer of the BBC Micro – Acorn – went on to create a processor for it’s sequel the Acorn RISC Machine or ARM for short. That’s right, the Pi is powered by an Acorn processor design (like most smartphones) so it made sense to bring it in.

Alas it was a hectic event with little time to show the machine. In fact just sitting there it popped a capacitor in a puff of smoke!

Power supply repair

Despite the noise and smoke the dying capacitor didn’t actually stop the machine working as it is part of the electromagnetic interference suppression not the power circuitry itself. Still, it should be repaired and I thought I may as well replace the other X2 film capacitor as they have been failing over the last 30 years.

BBC power supply with blown X2 capacitor BBC power supply with new X2 capacitors

I picked up a couple of RIFA PME 271 M capacitors – 100nf and 10nf – (with a matching pitch so they would fit correctly) from Mouser for less than $2 each plus shipping. Five minutes of desoldering and soldering later and it was good as new!

[)amien

Sequence averages in Scala  

I’ve been learning Scala and decided to put together a C# to Scala cheat sheet. All is going pretty well but then I got stuck on the equivalent of Average.

Enumerable.Average in .NET calculates a mean average from your sequence by summing up all the values and counting them in a single pass then returning the sum divided by the count in a floating point format (or decimal).

The problem

Given that Scala has nothing built-in there are more than a few suggestions online that boil down to:

val average = seq.sum / seq.length

This has a few problems:

  1. Visiting a sequence twice can be inefficient
  2. Sum can overflow as it is the same type as the sequence
  3. Applied to an integer without casting it returns an integer average

A solution

Scala provides a useful high-order function called foldLeft. Its job is to take an initial state and a function then keep applying the function with each value to the state. So one more efficient solution to the problem is:

val average = seq.foldLeft((0.0, 1)) ((acc, i) => ((acc._1 + (i - acc._1) / acc._2), acc._2 + 1))._1

How does this work?

What we do here is calculate an average as we go, adding the new weighted average each time.

It achieves this by setting up a tuple to contain our initial state with (0.0, 1). This specifies our starting average of 0.0 and our starting position of 1.

The next part specifies the function that takes that state as acc (for accumulator) and the next value in the sequence as i and calculates our rolling average for each value and increases the position as it goes along.

Finally at the end of our call we specify ._1 which tells the compiler we want the first value from the tuple – the average – as we no longer care about the position.

If you wanted to make this function more reusable you could do this:

def average(s: Seq[Int]): Double = s.foldLeft((0.0, 1)) ((acc, i) => ((acc._1 + (i - acc._1) / acc._2), acc._2 + 1))._1

Be aware you might need multiple overloads for each numeric sequence type you want to be able to average given the lack of a common numeric trait that allows for the subtraction and division.

Precision and rounding

There is some slight variance in results between this approach and the total / count due to rounding precision. If you wanted to preserve that you could always add and then divide at the end still in a single pass much like .NET does but with Scala’s foldLeft rather than a foreach.

def average(s: Seq[Int]): Double = { val t = s.foldLeft((0.0, 0)) ((acc, i) => (acc._1 + i, acc._2 + 1)); t._1 / t._2 }

[)amien

Optimizing Sum, Count, Min, Max and Average with LINQ  

LINQ is a great tool for C# programmers letting you use familiar syntax with a variety of backend systems without having to learn another language or paradigm for many query operations.

Ensuring that the queries still perform well can be a bit of a chore and one set that fails quite badly are the aggregate operations when you want more than one.

Multiple sequential queries (bad)

var count = db.Invoices.Count();
var total = db.Invoices.Sum(i => i.Paid);
var average = db.Invoices.Average(i => i.Paid);

Will issue three separate requests. There is nothing a LINQ provider can do to optimize that pattern as they are three discrete statements.

Background

If we wanted these values by country we could do this in LINQ:

var a = db.Invoices.GroupBy(i => i.Country)
          .Select(g => new { Country = g.Key,
                             Count = g.Count(),
                             Total = g.Sum(i => i.Paid),
                             Average = g.Average(i => i.Paid) });

Which gets us everything in a single statement broken down by country. In SQL this is:

SELECT Country, Count(*), Sum(Paid), Average(Paid)
    FROM Invoices GROUP BY Country

Many data sources including SQL are happy to provide aggregate values without a group by so how do we generate that from LINQ?

In the absence of a Group method that doesn’t take a property we need to fake it and because of the way many LINQ providers optimize out parts of the tree we can:

Single optimized query (good)

Replacing the property in a GroupBy with a constant value gives us an optimized single query:

var a = db.Invoices.GroupBy(i => 1)
          .Select(g => new { Count = g.Count(),
                             Total = g.Sum(i => i.Paid),
                             Average = g.Average(i => i.Paid) });

Here are the providers I’ve tried:

  • LINQ to Objects (Works although constant is likely evaluated)
  • LINQ to SQL (Works although passes 1 parameter to SQL)
  • Entity Framework 6 (Works although query is a little obscure)
  • Elasticsearch (Works and optimizes out totally)

Count+Where optimizations

If we are performing counts with a predicate or against a where we can also optimize these.

var high = db.Invoices.Count(i => i.Paid >= 1000);
var low = db.Invoices.Where(i => i.Paid < 1000).Count();
var sum = db.Invoices.Sum(i => i.Paid);

Then we can express this as:

var a = db.Invoices.GroupBy(g => 1)
          .Select(g => new { High = g.Count(i => i.Paid >= 1000),
                             Low = g.Count(i => i.Paid < 1000),
                             Sum = g.Sum(i => i.Paid) });

[)amien