A heads-up on a project I have been having lately: Patching the firmware to natively put out recognizable-keys instead of the NOTIS special-keys. It turns out to be very doable, given you have a fresh 8751 to burn, as well as a programmer.
First of all, I have been able to read out the v2.1 firmware using this type of dumper:
https://github.com/JohnDMcMaster/8051dumper . The particular chip in question is the mask-ROM plastic DIP edition. Very early keyboards usually have a ceramic DIP, the 8751 EPROM-based one with a quartz window, and those might have the protection-fuses activated. My own TDV 5010 with firmware v1.4 unfortunately has this, and the v2.1 dump I was able to make is from a friend's TDV 5010.
Making this firmware output media-keys is rather simple. There is already settings in there for defining keys with the 0xE0 prefix, so all you really need to do is to patch up to four or five data-tables. After this, the only thing remaining is really just to adjust the checksum byte at the end of the file before burning it to an empty 8751.
------------------
So, for the technical bits.
We are only really changing the scancode data in some tables here, so we don't really need to know too much how the code works. One thing to note, though, is which index in a table corresponds to what key on the keyboard itself. This overview may help:
Code: Select all
Index: Key:
0x01 HJELP
0x02 /\/\/\
0x16 [Stroked down-arrow]
0x17 -->|
0x18 |<--
0x27 >> <<
0x2B <> ><
0x2D JUST
0x3B FLYTT
0x46 STRYK
0x4B MERK
0x4D KOPI
0x69 ORD
0x6C SETN
0x6E FELT
0x6F AVSN
0x79 SLUTT
0x7C SKRIV
0x7D [Sideways u-turn arrow]
0x7F ANGRE
For the four scancode-tables, the index can be directly used as a byte-offset. This is convenient, as the tables are neatly laid out on the following addresses towards the end of the ROM:
- 0x0D34: Base scancodes for set 1
- 0x0D84: Base scancodes for set 2
- 0x0E34: Base scancodes for set 3
- 0x0E84: Keytype definitions
For the scancode sets, the content will be used as-is for the base scancode. Patching these is simple, but we need to change the fourth table as well in order to change the 0x80 prefix. This requites a bit of understanding on how the keytypes are defined. Each byte here contains primarely two groups of 3 bits, one defining if the key is a modifier, the other defining scancode structure:
Code: Select all
Keytype definitions:
76543210 <- Bit-nr.
||||||
|||+++- 0 = Normal Key No prefix
||| 1 = Extended Key 0xE0 prefix
||| 2 = Cursor navigation (Special cases)
||| 3 = NumPad slash (Special case)
||| 4 = PrtScr (Special case)
||| 5 = Pause/Break (Special case)
||| 6 = Key disabled for ordinary use No handling
||| 7 = NOTIS special 0x80 prefix
|||
+++---- 0 = Normal Key
1 = L Shift
2 = R Shift
3 = L/R Alt
4 = L/R Ctrl
5 = Num Lock
6 = Caps Lock
7 = Insert
If you look up the bytes for the NOTIS keys, you will see that all of them use the bit-pattern of xx000111. This will make the firmware add the 0x80 prefix, and we want to change this to 0xE0. The 0xE0 prefix is used for the navigation-keys, which is handy since all we have to do is just changing the xx000111 to xx000001. It's also possible to do as you want here, for example if you want to make some keys into non-media keys, just plain scancodes without additional prefixes, you can use xx000000 too, or if you hit some of the extra keys on accident a lot you can permanently silence any of them with xx000110.
The checksum is located at 0x0FFF. Tandberg used a special type of checksum, where the ordinary 32-bit sum (calculated from summing all bytes in the whole binary) is expected to fold down to 0xAA. The folding process consist of adding all bytes of the checksum together, and if the result is still not within 256, the folding is then repeated on the previous result untill you get something that does add to less than 256. In effect, this will be the ordinary 8-bit sum of the binary, but with the number of 8-bit overflows added to the count as well. If you want to test this for yourself, you can try to calculate it on the unpatched binary. After patching, you need to adjust the checksum-byte so it all adds up correctly.
..In essence, if you just add the 4 bytes making up the full 32-bit sum, a valid checksums is either 0x0AA, 0x1A9, 0x2A8 or 0x3A7.
------------------
I did not mention the last table yet. This is only relevant for scancode set 3, which is seldom used. In any way, the table for this is located at 0x0B71. The format is as follows, and pay attention to the bit-endianess:
Code: Select all
76543210 <- Bit-nr. in each byte
||||||||
||||||++- Entry for Index nr. [byte-offset x 4 + 3]
||||++--- Entry for Index nr. [byte-offset x 4 + 2]
||++----- Entry for Index nr. [byte-offset x 4 + 1]
++------- Entry for Index nr. [byte-offset x 4]
10 <------- Bit-nr. in each entry
||
|+- Typematic enabled by default if 1
+-- Release (break) scancode enabled by default if 1
------------------
That was it, I hope this can come in handy for other people than me.