The IBM PC: More Memory, Courtesy Your Keyboard

February 27, 2021

One of the best things about networked computers is being able to download more RAM when you need it. It’s pretty handy, I’ve been doing that since the BBS and modem days. I still download RAM on my smartphone, and it–

I tell Topaz that RAM doublers don't actually work and he smashes his phone.

Well…what if I told you that, on older IBM PCs, there was a key you could hit on your keyboard that would give you…

Topaz says 'All the RAM you could possibly ever need, I say no, he drops an IBM M Series keyboard.

Ok, fine…sigh…it’s not actually a key on your keyboard, but it is in the thing your keyboard plugs into to talk to the rest of the computer. And…yes, it can give you more RAM. Kinda sorta.

The IBM PC was designed from the start to have max 1MB of RAM, because that’s the most the 8086 could handle and RAM was expensive back then. Due to how the chip was designed, accessing all that 1MB was…a little odd.

Processors use memory addresses, a number starting from 0, to figure out the place in RAM where data can be written to and read from. The 8086 was a 16 bit processor, as the size of pieces of data it was designed to work with was 16 bits - 2 bytes, or the numbers 0-65535 - wide. Programmers call the size of data a processor is designed to work with a word. This means that, if an 8086 only used one word as a pmemory address, you’d have at most 64 kilobytes to use. Even the Commodore 128 could do better than that.

Processors will have a different sized value, separate from the word size, as the address width, which they use to find stuff in RAM. Usually the address width is double the word size, or some multiple of 8 bits so you can stick with bytes for everything. Keeping it in bytes makes it easier for processors, and easier on programmers when writing software. The 8086 has an address width of 20 bits, which is 2 and a half bytes, or one and one quarter words.

Of course it has to be different.

So instead of taking two words and sticking them together, like on a Commodore 64 whose word size is 8 bits:

C64 memory addresses

Or, doing what Apple did on the 68000 and taking two 16 bit words, sticking them together, and using one of the bytes in there as data for the garbage collector:

68000 Mac memory addresses, made from two words, one byte in the word being for flags

The 8086 stuck two 16 bit words, a segment and an offset, together with MATH. Hexadecimal math.

Segment:offset 1234:ABCD wraps to 1C0FD
Segment:offset FFFF:FFFF wraps to 10FFEF

It’s a neat approach. But it has a problem. The 8086 would lop off everything that went over those last five characters, like how letterboxing a show shot at 16:9 and broadcast on 4:3 TVs would cut out the stuff no one expected to see:

A sitcom shot with two characters in a scene, letterboxed.

Take away that assumption by releasing the show on DVD in 16:9 format, and you start running into some unexpected results:

The same scene, but with the letterboxing removed, and you can see additional things on the sides.

The addresses FFFF:FFFF and 0FFE:000F go to the same memory location, 0FFEF, on an 8086, but not on a 286, where they would go to 10FFEF and 0FFEF, respectively. A program could get quite confused if it writes to 10FFEF and then hopes to find the data again at 0FFEF.

So what’s the solution? You hard wire the part of the 286 (Addressing line 20, or the A20 line) that allows addresses to go over 20 bits to a switch on the motherboard. If the switch is off, addresses wrap around, and if it’s on, they don’t. And the best place for that switch? Why, an unused part of the keyboard controller, of course!

Now, you can’t expect humans to know to push a switch on their keyboard to activate this. The switch stays off, unless a program like Rebel Assault or the operating system specifically requests it. But when that switch is turned on?

It’s 10000% totally exactly like downloading more RAM.

Changelog

  • 2021-02-27: Initial post