As some of you know @polpo is RE the Image Writer Apple Talk option card. I was in a chat with him and he shared a dump of a 32 byte NVSRAM chip on the board. It appeared to contain the contents of the printers name on the Appletalk/LocalTalk network - but was in no discernible format.
This contains the String "Golden Software" - can you see it? We couldn't at first...
Many random attempts were had. Was it a Pascal string? No that would still overlap with ASCII except for the first char being the len.
Was it a different encoding? little endien or big? etc etc. Nothing was making sense.
I threw it into a few AI models to see if they saw pattern, no dice.
Our first break was talking while Joe from JCM was there - he mentioned that Apple II's stored their text with bit flags such as bit 8 denoting end of string. This _almost_ made sense, except for another example hex dump that flag was set at the 31st bit on a 32 bit string.. which was odd. This also changed our perspective from Mac centric strings to Apple II (as the ImageWriter can be used on an Apple II as well)
Nothing was making sense - no patterns emerging. We even dumped the ROM and found the name of the Apple employee in 1984 who wrote this and @tom_B was poking around at Linkedin/etc to see if they were still around.
Then polpo had a realization:
here's something I just realized about this NVSRAM chip - it's organized as 16x16 so writes are done 16 bits at a time. and I think they're written little endian. so A is 82 and B is 42, and "AB" gets written to a cell as "4282"
This was the break needed! With those two pieces of information we can now decode. The rules are
Bit 8 denotes a end of string
Bit 7 is always 1
Bit 6 is a lower case flag
Bits 1-5 are the character data offset from asci ord(a|A) - 1
Decoded ASCII String: Golden Software
Success!
To decode we have to take the hex, flip every other bytes position, then decode with those rules. I made a very quick and dirty python script in ~30 minutes.
Useful? No. An interesting puzzle to spend a few hours on, for sure. And now we know how the network name is stored on the LocalTalk option card.
This contains the String "Golden Software" - can you see it? We couldn't at first...
Many random attempts were had. Was it a Pascal string? No that would still overlap with ASCII except for the first char being the len.
Was it a different encoding? little endien or big? etc etc. Nothing was making sense.
I threw it into a few AI models to see if they saw pattern, no dice.
Our first break was talking while Joe from JCM was there - he mentioned that Apple II's stored their text with bit flags such as bit 8 denoting end of string. This _almost_ made sense, except for another example hex dump that flag was set at the 31st bit on a 32 bit string.. which was odd. This also changed our perspective from Mac centric strings to Apple II (as the ImageWriter can be used on an Apple II as well)
Nothing was making sense - no patterns emerging. We even dumped the ROM and found the name of the Apple employee in 1984 who wrote this and @tom_B was poking around at Linkedin/etc to see if they were still around.
Then polpo had a realization:
here's something I just realized about this NVSRAM chip - it's organized as 16x16 so writes are done 16 bits at a time. and I think they're written little endian. so A is 82 and B is 42, and "AB" gets written to a cell as "4282"
This was the break needed! With those two pieces of information we can now decode. The rules are
Bit 8 denotes a end of string
Bit 7 is always 1
Bit 6 is a lower case flag
Bits 1-5 are the character data offset from asci ord(a|A) - 1
Decoded ASCII String: Golden Software
Success!
To decode we have to take the hex, flip every other bytes position, then decode with those rules. I made a very quick and dirty python script in ~30 minutes.
Useful? No. An interesting puzzle to spend a few hours on, for sure. And now we know how the network name is stored on the LocalTalk option card.
Python:
def bit_reverse(i, n):
return int(format(i, '0%db' % n)[::-1], 2)
def hex_to_ascii(hex_input):
byte_pairs = [hex_input[i:i + 2] for i in range(0, len(hex_input), 2)]
sorted_bytes = []
i = 0
while i < len(byte_pairs):
sorted_bytes.append(byte_pairs[i + 1])
sorted_bytes.append(byte_pairs[i])
i = i + 2
result = []
for byte_pair in sorted_bytes:
byte = int(byte_pair, 16)
print(f'h: {byte_pair} - {byte:b}')
end_of_string = (byte >> 0) & 1
lowercase_flag = (byte >> 2) & 1
numeric_flag = (byte >> 3) & 1
char_offset = byte >> 3
char_offset = bit_reverse(char_offset, 5)
if char_offset == 0:
char = " " # special case, space
elif lowercase_flag:
char = chr(ord('a') + char_offset - 1)
else:
char = chr(ord('A') + char_offset - 1)
# TODO: numbers, other mac roman stuff
result.append(char)
if end_of_string:
break
return ''.join(result)
hex_input = "F6E2263676A6CA0466F6EE2E4E8604A7"
ascii_output = hex_to_ascii(hex_input)
print("Decoded ASCII String:", ascii_output)
Last edited: