Strings can often provide solid clues or anchors when reversing code, as the strings referenced often give away the purpose of a piece of code in human-readable terms. The problem with the 2465 readout system, in this respect, is that the strings are all written in the readout system’s alphabet.

Locating the OSD strings and converting them to ASCII would greatly help the reversing effort, so that’s what I did.

Deciphering

In order to decipher the OSD alphabet it’s necessary to understand how the readout system works. Thankfully, the “Theory of Operation” (ToO) section in the service manuals has a solid explanation of how the readout system renders the contents of character RAM to the CRT, through the contents of the character ROM.

The ToO describes how the circuitry works in excruciating detail, but the gist of it is this:

  1. A byte in the readout RAM selects a character to display.

    The start address of the character in character ROM is simply the readout RAM byte value * 16.

  2. Readout characters comprise a series of dots.

    Each dot is encoded into a byte, where the X, Y coordinates of each dot are respectively encoded in 3 and 4 bits of the byte. This means each character can be as wide as 8 dots, but as tall as 16.

  3. A dot with the MSB clear ends the character.

The way this is laid out is that some characters are designed to be used in pairs to make a single large character. As the end goal is to be able to convert a series of OSD bytes into a human-readable string, these pairwise characters are considered a single character for our purposes.

After some experimentation, I wrote a relatively simple python script to convert the character ROM to a bunch of PNG files.

Initially I assumed that “small” characters would be 8x8 while the dual “large” characters would be 16x16. This is however not true. There are several “small” characters that extend below the 8 row boundary. All the small characters below are rendered to 16 rows, though few use the space.

The Alphabet

I wager that the organization of this alphabet is largely determined by the glyphs Tektronix wanted to display. Note that any glyph that needs more than 16 dots will consume the subsequent character position, so there are several gaps in the character codes. The first subsumed code is 0x03, followed by 0x07 and 0x0B.

It’s also interesting to note that all the digits occur 4 times in this alphabet, as they appear both large and small, as well as with and without a decimal point.

Code Character
0x00 00 character
0x0201 0201 character
0x04 04 character
0x0605 0605 character
0x08 08 character
0x0A09 0A09 character
0x0C 0C character
0x0E0D 0E0D character
0x0F 0F character
0x10 10 character
0x1211 1211 character
0x13 13 character
0x14 14 character
0x1615 1615 character
0x18 18 character
0x1A19 1A19 character
0x1C 1C character
0x1E1D 1E1D character
0x1F 1F character
0x20 20 character
0x2221 2221 character
0x24 24 character
0x2625 2625 character
0x28 28 character
0x2A 2A character
0x2B 2B character
0x2C 2C character
0x2D 2D character
0x2E 2E character
0x30 30 character
0x31 31 character
0x32 32 character
0x34 34 character
0x35 35 character
0x36 36 character
0x3837 3837 character
0x3A 3A character
0x3C3B 3C3B character
0x3E 3E character
0x403F 403F character
0x42 42 character
0x4443 4443 character
0x46 46 character
0x4847 4847 character
0x4A 4A character
0x4C4B 4C4B character
0x4E 4E character
0x504F 504F character
0x52 52 character
0x5453 5453 character
0x56 56 character
0x5857 5857 character
0x5A 5A character
0x5C5B 5C5B character
0x5E 5E character
0x60 60 character
0x62 62 character
0x64 64 character
0x66 66 character
0x68 68 character
0x6A 6A character
0x6C 6C character
0x6E6D 6E6D character
0x70 70 character
0x7271 7271 character
0x74 74 character
0x7675 7675 character
0x78 78 character
0x7B7A 7B7A character
0x7C 7C character
0x7D 7D character
0x7E 7E character
0x8180 8180 character
0x82 82 character
0x84 84 character
0x86 86 character
0x88 88 character
0x8A 8A character
0x8C 8C character
0x8E 8E character
0x90 90 character
0x92 92 character
0x94 94 character
0x96 96 character
0x98 98 character
0x9A99 9A99 character
0x9C 9C character
0x9E9D 9E9D character
0xA0 A0 character
0xA2A1 A2A1 character
0xA5A4 A5A4 character
0xA6 A6 character
0xA7 A7 character
0xA8 A8 character
0xA9 A9 character
0xAA AA character
0xAC AC character
0xAEAD AEAD character
0xB0 B0 character
0xB1 B1 character
0xB2 B2 character
0xB4 B4 character
0xB5 B5 character
0xB6 B6 character
0xB8 B8 character
0xBAB9 BAB9 character
0xBC BC character
0xBD BD character
0xBE BE character
0xC0 C0 character
0xC2C1 C2C1 character
0xC4 C4 character
0xC6C5 C6C5 character
0xC8 C8 character
0xCAC9 CAC9 character
0xCC CC character
0xCECD CECD character
0xD0 D0 character
0xD2D1 D2D1 character
0xD4 D4 character
0xD6D5 D6D5 character
0xD8D7 D8D7 character
0xDAD9 DAD9 character
0xDCDB DCDB character
0xDFDE DFDE character
0xE0 E0 character
0xE2E1 E2E1 character
0xE4 E4 character
0xE6 E6 character
0xE8 E8 character
0xEA EA character
0xEC EC character
0xED ED character
0xEE EE character
0xF0 F0 character
0xF1 F1 character
0xF3F2 F3F2 character
0xF5F4 F5F4 character
0xF6 F6 character
0xF7 F7 character
0xF8 F8 character
0xFA FA character
0xFB FB character
0xFC FC character
0xFE FE character