> IND → SI JMPS X0 8 test instruction bit 3: jump if LODS
> DI → IND W DA,BL MOVS path: write to DI
Is "W DA,BL" a typo, should it be "W DS,BL"?
> IND → SI JMPS X0 8 test instruction bit 3: jump if LODS
> DI → IND W DA,BL MOVS path: write to DI
Is "W DA,BL" a typo, should it be "W DS,BL"?
Andrew Jenner's microcode disassembly used the original names. I've been changing the register names to the modern names, but missed that one. So it should probably be "W ES,BL", although I don't really like "BL" either. (Maybe "PM" would make more sense for plus/minus?)
A bit more on the original register names. The original 8080-inspired registers XA, BC, DE, HL were renamed to AX, CX, DX, BX. The original registers MP, IJ, IK were renamed to BP, SI, DI.
There's a diagram showing the original registers in the patent: https://patents.google.com/patent/US4449184A
Another thing I just noticed:
> Apparently a comprehensive solution (e.g. counting the prefixes or providing a buffer to hold prefixed during an interrupt) was impractical for the 8086.
Did you have a particular kind of buffer in mind? The buffer could not be internal (i.e. not exposed to the programmer), because the interrupt handler itself could use string instructions. Or, it could just switch over to some other code entirely, and switch back much later.
I guess since interrupts already push not just the usual CS:IP on the stack like a far call would, but also the FLAGS register, so that the special IRET could restore it, the x86 could also have pushed additional data describing the "prefix state"?
Or maybe even try to cram it into the FLAGS bits that were still unused originally? With the 7 spare bits of the 8086, the 4 segment prefixes (of which only can be active at any time, so 2 bits), plus LOCK, would fit and leave 4 bits to spare.
It would be interesting to find out what the real solution was in later x86 processors. I'm sure someone has looked into this.
** 0.1010101x STOS
0 IK -> IND 0 F1 6 ;check count if repeated
1 M -> OPR 6 W DA,BL
2 1 DEC tmpa
3 IND -> IK 0 NF1 7 ;exit if no repeat
4 SIGMA -> BC 5 INT RPTI ;handle interrupt
5 BC -> tmpa 0 NZ 1 ;redundant check???
6 BC -> tmpa 0 NBCZ 1 ;loop while Not BC Zero
7 4 none RNI
** 1.10100100 string instr interrupted (RPTI:)
0 PC -> tmpb 4 none SUSP
1 1 DEC tmpb
2 SIGMA -> tmpb 0 F1 5
3 0 PFX 6
4 SIGMA -> PC 4 FLUSH RNI ;PC corrected
5 SIGMA -> tmpb 0 UNC 3 ;has REP
6 SIGMA -> tmpb 0 UNC 4 ;has seg pfx
7 4 none none
edit- Posting code for STOS since it's simple, even though segment prefixes don't affect its function.
- No idea if line 5 could be removed, maybe needed for timing?
- MOVS, INS and OUTS use a special memory-to-memory/IO operation encoded as 'W IRQ DD,BL'. It doesn't use the IND register at all, maybe the internal DMA controller instead?
The 8086 patent also only included a few examples, and the naming conventions for microcode registers and instructions. The full microcode for that one was disassembled by Andrew Jenner.
It would be interesting to know how they sped up multiplication and division between the 8086 and 80186!
At least now the solution is to simply pass the full PC of the instruction thorough the pipeline. Or at the very least mark the PC for each ROB entry, and offsets for each instruction in the ROB entry.
As an aside do you know yet what you're going to work on once you've mined out the 8086?
The names are those used in a patent filed by Intel and come from before the official documentation for the 8086 was written. It might make the microcode a bit more readable to invent a different notation that is more in line with normal x86 assembly, but then again this is a very niche topic :)