On Sat, Jan 20, 2018 at 11:39:59PM -0800, David Fifield wrote:
> /usr/games/bcd formats its input as punched cards. It has an internal
> table that maps each byte value to a 12-bit code, representing a pattern
> of holes in one column of the card. The table is missing an element at
> index 0x5c (ASCII '\\'), which causes the succeeding elements to be
> misaligned. You can see it by looking at the rows that correspond to
> uppercase and lowercase letters; punch card codes don't distinguish case
> so uppercase and lowercase are supposed to map to the same code. But the
> lowercase codes are shifted by one position:
> index 0x40 "@ABCD..." -> 0x022, 0x900, 0x880, 0x840, 0x820, ...
> index 0x60 "`abcd..." -> 0x900, 0x880, 0x840, 0x820, 0x810, ...
> Now, in the specific case of lowercase letters, the error doesn't
> matter, because the program calls toupper before doing the table lookup.
> But the codes for 0x5c '\\', 0x5d ']', 0x5e '^', and 0x5f '_' are wrong,
> compared to the table in an early version of bcd and a reference of
> punch card codes I found. And indexes 0x60 '`' and 0x61 'a' map to the
> same code, 0x900, because 'a' is affected by toupper and '`' is not.
>
> The evident intention of the table is that the second half should be the
> same as the first half; i.e., the most significant bit of the index does
> not matter. But the missing element messes that up too.
>
> Finally, the table has the code 0x30f at indexes 0x5f '_' and 0xdf (or
> indexes 0x60 '`' and 0xe0 after correcting the misalignment). I suspect
> the code 0x30f is nonsense--garbage data resulting from a buffer
> overflow in an even older version of bcd.c. What code to use for it is
> debatable, as '`' doesn't seem to have been used on punch cards, but
> following historical example we can assign it 0x022, the same as index
> 0x40 '@'.
>
> The included patch fixes the above problems. It modifies the table thus:
> Insert 0x806 at index 0x5c '\\', shifting later elements by one
> Change index 0x60 '`' from 0x30f to 0x022
> Change index 0xe0 from 0x30f to 0x022
> Trim the now-extraneous final element 0x000
Thanks for the diff and the analysis. I'll handle it from here.
-Otto