The KS10 I/O instructions and interrupt architecture offend me. The instructions are gross and are unnecessarily slow. They calculate their effective address in a different way from all other instructions, they are hard to use, they look like they would use read-pause-write Unibus cycles but actually don't, they provide some extra features similar to the halfword-test instructions that don't really work the way you would want them to. Proposed replacement instructions (different opcodes): IORD AC,E IOWRT AC,E Transfer C(AC) to/from an I/O device. C(E) has controller number in 14-17, Unibus address in 18-35. IORDI AC,E IOWRTI AC,E Same but E is a Unibus address on controller 3, which is the Unibus that most devices are on. IORDQ AC,E IOWRTQ AC,E Same but E is a Unibus address on controller 1, which is the Unibus that the disk is on. "Q" stands for "disk" I guess. Note that there is no support for byte operations at all. We could make a bit in C(E) for IORD/IOWRT turn that on. Byte input operations are not distinguished from word input operations on the Unibus. None of the devices on the KS10 that I know of makes any use of byte operations, so I suggest not wasting the microcode space, instruction speed, and hacking time on this marginal feature. [JTW 7/5 .... Two issues involved in doing an I/O instr; Getting a 30-bit "I/O address" Deciding what to do with it. The two steps are logically seperate. The current DEC KS essentially gets the 30-bit I/O address by performing a standard effective address calculation that follows the new, "extended" rules. Unfortunately, the implementation sucks, it doesn't *really* follow the rules, and it doesn't happen until after the instruction is decoded, which wastes a lot of time. On a machine that really supported extended addressing the I/O instructions could use the same effective address calculation that the other instructions did, and would not be slowed down. I suppose this is why the DEC ones look like that. Dave proposes to get the 30-bit address by adding a level of indirection, using the standard 18-bit calculation to give the location of 30-bit address word. We then get back the speed we lost by adding the memory access by special-casing the most common I/O devices. Taking the general case of each, I don't know which is faster, doing an extra ucode address calculation or fetching another word. The DEC- style instrs do have some advantages; they let you throw the controller number in an index register and use the same code for all, and they make more sense in the context of an (imaginary) extended machine with a unibus on it. The special-case instrs are clearly simpler and faster than either of the general-case approaches. So I think maybe we should just do the special-case ones and use the DEC general-case ones. I don't think it would be a good idea to start adding flag bits (like "byte instr" or similar) to the 30-bit address, because then it isn't an address any more, and the nice model breaks. Summary: For now just add IORDI, IOWRI, IORDQ, IOWRQ. No byte kludges. Maybe later some atomic set-clear instrs that use the unibus right. .... JTW] Interrupts: The DEC microcode looks for two instructions, JSR and XPCW, in interrupt locations, and does random things vaguely related to normal execution of those instructions. It halts if it sees anything else. Instead, I propose abandoning the idea of interrupt-vector elements being instructions. This applies both to EPT locations 42-57 and to the arrays for Unibus vectored interrupts. These locations instead contain interrupt vector words, which look like save-context-address,,new-context-address The two addresses are physical addresses of context words; the "save" word is written with the current state of the machine, then the "new" word is read and the state of the machine is set to that. A context word looks like: 4.9-3.5 PC flags 3.4 1 if 3.3-3.1 are valid 3.3-3.1 Current AC block 2.9-1.1 PC Bit 3.4 is always set in the saved context. The new context can either continue to use the same AC block, or switch to a new AC block. The "previous AC block" is not affected by this. This takes advantage of the fact that neither ITS nor the KS10 hardware supports "extended addressing". There are also new instructions JRST 3, and JRST 13,. C(E) is a context word, which is restored into the state of the processor. JRST 13, also dismisses the current interrupt. These two instructions are analogous to JRST 2, and JRST 12, respectively. What all this accomplishes is to enable assignment of private AC blocks to certain interrupt handlers, avoiding the need to save and restore ACs in them. This can make DZ11 per-character interrupts quicker, for example. [JTW 7/5 .... Well, physical addresses are 20 bits, so you can't have old context pointer,,new context pointer in a vector word unless you are willing to limit them to only part of memory, which is a kludge. I also think it would be nice if the scheme we adopt works for an extended machine, on the off chance that the issue ever comes up. On the other hand having the vector contain a physical address has got to be faster than doing a full exec virtual effective address calculation and decoding a slightly munged instruction. How about: Interrupt vector (41-57 or entry in the UBA table) contains the physical address of a block of four words comprising two "Flag-PC Doublewords", one each for old and new context. A flag-PC doubleword is: Word 1: 4.9 - 3.5 Flags 3.4 - 3.1 MBZ 2.9 Valid AC block 2.8 - 2.6 Current AC block 2.5 - 2.4 Free 2.3 - 1.1 Previous Context Section (0 on KS) Word 2: 4.9 - 4.4 MBZ 4.3 - 1.1 PC This is compatable with all DEC uses of this word. Note that word 1 bits 2.9 - 1.1 are defined as "processor-dependent". My definition is an extension of what the Model B KL does. XJRSTF (JRST 5,) and XJEN (JRST 6,) can be used as they stand, except that they should also restore the AC block, I guess. What is lost with this scheme is the ability to specify seperate old and new context areas. I don't know if this is useful for ITS or not. .... JTW]