First define your purpose.
If you want to make something easier for the programmers, model something that exists that is analogous to what you wish to interface.
For example, if an input device that takes in serial data meant to be asynchronous, expect the program to access it one 7/8-bit character at a time, then you need to implement all of the following to make any sense:
6xx1 - Skip on the input flag is set. Do NOT do anything else.
6xx2 - clear the input flag and the AC. This allows it to be microprogrammed with the other instructions.
6xx4 - .OR. transfer data into the AC. Note: The data is that associated with the reason the input flag raised. This expressly is NOT a license to get new data; in fact NEVER do that.
6xx6 is thus clear the input flag and load the data into the AC.
Why the seeming complications? The simple answer of course is: BECAUSE.
Programmers who really know the keyboard interface used every smidgen of the hardware. Control-C etc. checking is based on the notion of maintaining the flag so it can be re-read by another program. The buffer will be checked for say control-C by reading with the 6xx4 instruction by an .or. transfer; the flag is NOT disturbed by doing this.
The whole reason for all of this is because the major basic tenet of PDP-8 operating systems is only the "kernel" is resident, meaning the system device handler, which will bring in other code to process this situation than was that which detected it. The basic non-resldency of the operating system thus requires a way to know that it was brought in by a hasty exit, not a normal termination because the program ran out of stuff to do, etc. Thus, the notion of a logical abort is implemented this way.
Again, my example is of a terminal input that is essentially a keyboard, real or emulated by another device pumping the data into the interface a character at a time.
Frill instructions have been added over the years; compatible software has to not depend on them, but custom software can embrace it.
6xx0 - clear the input flag; do nothing else. The seeming redundancy is because the real ASR-33 or ASR-35 teletype cannot help but read a character in on the reader by hardware design. But since that's not possible, clearing the flag just starts the reader up. The only way to NOT read the paper-tape is to leave the flag up. Interrupt-driven programs like FOCAL, 1969 cannot handle that. Thus, the KL8E and KL8-JA added 6030 - clear the keyboard input flag because if relevant 6032 cleared the flag and started the reader [and also cleared the AC].
Again, if this is not your device, don't worry about it. Also remember, that you cannot have an IOT0 on a negative or positive buss machine which means if your device needs it, it won't work on the older hardware.
6xx3 is essentially reserved for arcanity such as load the baud rate from the low-order 4 bits using the DEC standard baud rates. Likely used on the serial port associated with a printer or comm port such as on the VT78.
6xx5 is often something like interrupt enable the device per ac[11]. On the KL8 interfaces, this is a bit complicated because it affects both the input and the output, but an LPT output like a device 66 parallel could do that for itself alone. And on the KL8, the other IOT5 could be skip on an interrupt is coming from one or the other side of the dual-direction interface; the reason is to get past tty interrupts as quickly as possible to service higher-priority interrupts, and if a TTY is the source, take a little extra cycles to figure which one; lowers the worst-case latency on faster devices, but again, makes it dependent on the newer interface.
You rarely see 6xx7. On the older machines it is possible to decode it, but the simplest is the simple IOT1, IOT2, IOT4 approach because on the older bus they all are possible and can be combined, OR they can be partially decoded with a bit more effort; the most effort is needed to pick up that unique 6xx7, so by choice it hardly happened. Of course if you have an Omnibus or newer, all of these considerations are moot; all 8 instructions are equally easy to decode.
On the output side, the frill of 6xx0 is to set the flag unconditionally to "prime the pump" for the output routines. Again, not possible on the older hardware.
6xx1 is skip on output done flag and nothing else.
6xx2 is clear the output flag and nothing else.
6xx4 is output the character; thus 6xx6 is 2 then 4 combined in that order.
We already dealt with potential 6xx3 and 6xx5 frills above.
If you do this, you can be a console device and be compatible with all sorts of stuff like various handlers. Good software generally specifies the device codes to easily change definitions. But the instructions themselves have to match with expectations.
By all means possible strictly avoid what the RX8E and the DECmates do; it's poison and why OS/8 can never quite run on any DECmate and the variants that do, don't quite work [to varying extents]. Years ago, I bit the bullet and "got religion" with P?S/8 so all programs can always work also on a DECmate, but all the "soul" of the interface had to be removed to maintain dual-compatibility. [But P?S/8, unlike OS/8, totally supports control-s/control-q protocol; in OS/8 only the KL8E handler does, not anything else. Ask people who learned the hard way why they cannot use VT-100 unless the baud rate is slowed down to *minimize* the console splats; to eliminate them means running not much faster than an ASR-33.]
It was a lot of work to do it, and I regretted having to merely because some dimwits never asked software people what compatibility was needed; they copied the RX8E interface which is a really poor idea; it's a multiple-flag device short on instructions, so they made every one of them skip on and also clear the associated flag. So, some other dimwit thought that that was the prototypical interface instead of an aberration. It's just a hop, skip [and not a jump] to why all DECmates are incompatible.
[Note: To even contemplate fixing OS/8 the same way requires a) rewriting everything, b) trying to locate free bits in the system device handler area. a) is merely a major amount of work, b) is very little work that could take an infinite amount of time to implement.]
cjl