• Please review our updated Terms and Rules here

What's your favourite serial keystroke encoding?

reenigne

Veteran Member
Joined
Dec 13, 2008
Messages
717
Location
Cornwall, UK
I'm writing a little Arduino program to simulate a PC/XT keyboard, so that I can have a PC or XT on my workbench as well as a modern PC and control the former with the latter (and so that I don't have to devote space to two keyboards). This program will have several modes. In one mode it'll just take scancodes from the serial port and output them to the keyboard port (and I'll probably write a little program for the modern PC to act as a "virtual PC/XT keyboard").

I thought it might also come in handy to also have an ASCII mode, so that you can just use a standard serial terminal (physical or virtual) as a PC/XT keyboard - when you send an ASCII character over the serial link the Arduino program will convert it to a sequence of press and release scancodes to type that character.

Which brings me to my question - if I were to add to this ASCII mode capability to send codes corresponding to cursor movement keys (Up, Down, Left, Right, Home, End, PgUp, PgDn), function keys (F1-F10), other keys (Esc, PrtSc, Del etc.) and possibly even keystrokes modified by combinations of Shift, Ctrl and Alt, what protocol should I use? Excluding Enter, Backspace and Tab (which seem to be mostly standard), there seem to be lots of different standards to choose from. PuTTY seems to have at least 6 (ESC[n~, Linux, Xterm R6, VT400, VT100+ and SCO) plus standard or rxvt for Home and End. What's your favourite and why (and where can I find a list of keys and corresponding byte sequences for it)? I'd be especially interested to hear from you if you'd have a use for this program when it's finished (e.g. if you have a 5150 and a VT100 gathering dust in your basement and you'd like to be able to connect them together).

If you're interested I'm putting the code for this online here. As well as sending keystrokes to the PC/XT I'm also experimenting with sending data back (the clock line can be pulled low by clearing bit 6 of port 0x61) so that with suitable software on both machines, I can write programs on the modern PC, download them to the PC/XT, run them and get results back all over the keyboard port (so no expansion cards necessary!). One other fun little feature that I'm planning - as well as pretending to be a keyboard, it'll also be able to pretend to be the little doodad that IBM used to plug into the keyboard port for manufacturing tests - if the BIOS detects the presence of this device it downloads a program from it into RAM and executes it early in the boot sequence. This is one way it'll be able to run programs on the PC/XT - I'm also planning to teach it to type in machine code programs via the BASIC interpreter or via DEBUG, so there's several ways it can bootstrap itself.
 
it'll also be able to pretend to be the little doodad that IBM used to plug into the keyboard port for manufacturing tests - if the BIOS detects the presence of this device it downloads a program from it into RAM and executes it early in the boot sequence

I've never heard of this before - do you have said device? I'm just then wondering if the PC's cassette port was little more than a keyboard port in this mode?
 
I've never heard of this before - do you have said device?

I don't - as far as I know it was never sold or existed outside of an IBM factory (it may have been a part of a large testing machine). I only know about it from examining the BIOS code, which is printed with helpful comments in the technical reference manual. One of these comments reads:

Code:
;------------------------------------------------------------------------
;       LOAD A BLOCK OF TEST CODE THROUGH THE KEYBOARD PORT             :
;       FOR MANUFACTURING TEST.                                         :
;       THIS ROUTINE WILL LOAD A TEST (MAX LENGTH=FAFFH) THROUGH        :
;       THE KEYBOARD PORT. CODE WILL BE LOADED AT LOCATION              :
;       0000:0500. AFTER LOADING, CONTROL WILL BE TRANSFERRED           :
;       TO LOCATION 0000:0500. STACK WILL BE LOCATED JUST BELOW         :
;       THE TEST CODE. THIS ROUTINE ASSUMES THAT THE FIRST 2            :
;       BYTES TRANSFERRED CONTAIN THE COUNT OF BYTES TO BE LOADED       :
;       (BYTE 1=COUNT LOW, BYTE 2=COUNT HI.)                            :
;------------------------------------------------------------------------

This code is executed when the keyboard returns 0x65 instead of 0xAA on a reset:

Code:
        CALL    KBD_RESET               ; SEE IF MFG JUMPER IN
        CMP     BL,0AAH                 ; KEYBOARD PRESENT?
        JE      E6
        CMP     BL,065H                 ; LOAD MFG. TEST REQUEST?
        JNE     D3B
        JMP     MFG_BOOT                ; GO TO BOOTSTRAP IF SO

I'm just then wondering if the PC's cassette port was little more than a keyboard port in this mode?

It's not - you can see the schematics for both ports in the 5150 technical reference manual and the similarities don't extend further than the physical connector and the fact that both are ultimately controlled by the 8255 PPI. The keyboard data line goes into a shift register and there is some logic to fire an interrupt when a full byte is received. The cassette output line is connected to the same timer output line used for the speaker, and the cassette input line is amplified and connected to a different pin on the PPI (so the deserialization is done in software, which I think is the same way most 8-bit micros did it). The cassette port also has a relay to control the data direction, and one for the cassette motor.
 
VT-100, but that's not being very precise--note that VT100 is modal--and most implementations are very incomplete. The other issue is that since ESC is used as both a lead-in character for control functions and is also present as a standalone keyboard key, the recipient needs to be able to determine what's being sent. Usually, a timer figures this out.

In any case, ECMA-48 is probably the "official" standard. However, you may be better off investigating the set used by commercial products such as PC Anywhere or Carbon Copy.
 
At the risk of getting rotten tomatoes thrown at me, you could compile libtermcap for your micro (assuming there's space) and support them all!
 
Yes but you can never make everyone happy. That's why there are hundreds if not thousands of translations for termcap. Besides, some computer vintage hobbyist may drag out their 1960's Rand teletype and want to use it as their XT keyboard!
 
Thanks! Heh, I fear I've made some work for myself - I guess I'll see what PuTTY outputs in VT100 mode (since that's what I've been using as a serial terminal lately). I don't think termcap will fit into an Arduino, though...
 
I use similar devices (Hagstrom KE-24s) daily to let an incompatible RS-232 system talk to a PC's PS/2 or USB keyboard port.

They store the translation tables in an 8-pin 1/2K 27LC04 serial EEPROM and come with a configuration program to let you define whatever translation you want, either serial-to-ASCII or serial-to-scancode; maybe that's something you want to consider.

Remember that in ASCII mode you'll have issues with the special multiple-key keyboard codes like ALT/CTL-something etc. (including the all-important CTL/ALT/Del of course ;-) ).
 
Last edited:
Back
Top