home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / INTER38C.ZIP / 86BUGS.LST next >
File List  |  1993-12-05  |  14KB  |  386 lines

  1. Last Change 7/17/93.  Please send updates directly to Harald.
  2.  
  3.  
  4. 86BUGS.LST   revision 1.0
  5. By Harald Feldmann (harald.feldmann@almac.co.uk), mail address:
  6. Hamarsoft, p.o. box 91, 6114 ZH  Susteren, The Netherlands.
  7. (Please retain my name and address in the document)
  8.  
  9. This file lists undocumented and buggy instructions of the Intel 80x86
  10. family of processors. Some of the information was obtained from the book
  11. "Programmer's technical reference, the processor and coprocessor; by
  12. Robert L. Hummel; Ziff davis press. ISBN 1-56276-016-5 Which is highly
  13. recommended. Note that Intel does not support the special features and
  14. may decide to drop opcode variants and instructions in future products.
  15.  
  16. All mentioned trademarks and/or tradenames are owned by the respective
  17. owners and are acknowledged.
  18.  
  19. Undocumented instructions and undocumented features of Intel and IIT
  20. processors:
  21.  
  22. AAD:        OPCODE: d5,0a     OPCODE VARIANT
  23.  
  24.         This instruction regularly performs the following action:
  25.         - unpacked BCD in AX      example (AX = 0104h)
  26.         - AL = AH * 10d + AL          (AL = 0eh )
  27.         - AH = 00              (AH = 00h )
  28.  
  29.         The normal opcode decodes as follows: d5,0a
  30.         The instruction itself is an instruction plus operand. By
  31.         replacing the second byte with any number in the range 00 -
  32.         ff we can build our own instruction AAD for various number
  33.         systems in those ranges. For example by coding d5,10 we
  34.         achieve an instruction that performs: AL = AH * 16d + AL.
  35.  
  36.         Note: the variant is not supported on all 80x86-compatible
  37.         CPUs, notably the NEC V-series, because some hard-code the
  38.         divisor at 0Ah
  39.  
  40. AAM:        OPCODE: d4,0a     OPCODE VARIANT
  41.  
  42.         This instruction regularly performs the following action:
  43.         - binary number in AL
  44.         - AH = AL / 10d
  45.         - AL = AL MOD 10d
  46.  
  47.         Thus creating an unpacked BCD in AX.
  48.         The normal opcode decodes as follows: d4,0a
  49.         The instruction itself is an instruction plus operand. By
  50.         replacing the second byte with any number in the range 00 -
  51.         ff we can build our own instruction AAM for various number
  52.         systems in that range. For example by coding d4,07 we
  53.         achieve an instruction that performs: AH = AL / 07d, AL = AL
  54.         MOD 07d
  55.  
  56.         The AAD and AAM opcode variants have been found in Future
  57.         Domain SCSI controller ROMS.
  58.  
  59.  
  60. LOADALL:    OPCODE: 0f,05 (i80286) & 0f,07 (i80386 & i80486)
  61.         UNDOCUMENTED
  62.  
  63.         Load _ALL_ processor registers. Does exactly as the name
  64.         suggests, separate versions for i80286 and i80386 exist. The
  65.         i80286 LOADALL instruction reads a block of 102 bytes into
  66.         the chip, starting at address 000800 hex. The i80286 LOADALL
  67.         takes 195 clocks to execute.
  68.         The sequence is as follows (Hex address, Bytes, Register):
  69.  
  70.         0800: 6 N/A
  71.         0806: 2 MSW (Machine Status Word)
  72.         0808: 14 N/A
  73.         0816: 2 TR (Task Register)
  74.         0818: 2 FLAGS (Flags)
  75.         081a: 2 IP (Instruction Pointer)
  76.         081c: 2 LDT (Local Descriptor Table)
  77.         081e: 2 DS (Data Segment)
  78.         0820: 2 SS (Stack Segment)
  79.         0822: 2 CS (Code Segment)
  80.         0824: 2 ES (Extra Segment)
  81.         0826: 2 DI (Destination Index)
  82.         0828: 2 SI (Source Index)
  83.         082a: 2 BP (Base Pointer)
  84.         082c: 2 SP (Stack Pointer)
  85.         082e: 2 BX (BX register)
  86.         0830: 2 DX (DX register)
  87.         0832: 2 CX (CX register)
  88.         0834: 2 AX (AX register)
  89.         0836: 6 ES cache (ES descriptor _cache_)
  90.         083c: 6 CS cache (CS descriptor _cache_)
  91.         0842: 6 SS cache (SS descriptor _cache_)
  92.         0848: 6 DS cache (DS descriptor _cache_)
  93.         084e: 6 GDTR (Global Descriptor Table)
  94.         0854: 6 LDT cache (Local Descriptor_cache_)
  95.         085a: 6 IDTR (Interrupt Descriptor table)
  96.         0860: 6 TSS cache (Task State Segment _cache_)
  97.  
  98.         Descriptor cache entries are internal copies of the
  99.         original registers (the LDT cache is normally a copy of the
  100.         last regularly _loaded_ LDT). Note that after executing
  101.         LOADALL, the chip will use the _cache_ registers without
  102.         re-checking the caches against the regular registers. That
  103.         means that cache and register do not have to be the same.
  104.         Caches are updated when the original register is loaded
  105.         again. Both will then contain the same value.
  106.  
  107.         Descriptor caches layout:
  108.         3 bytes       24 bit physical address of segment
  109.         1 byte       access rights byte, mapped as access right
  110.                byte in a regular descriptor. The present
  111.                bit now represents a valid bit. If this bit
  112.                is cleared (zero) the segment is invalid and
  113.                accessing it will trigger exception 0dh. The
  114.                DPL (Descriptor Privilege Level) fields of
  115.                the CS and SS descriptor caches determine
  116.                the CPL (Current Privilege Level).
  117.         2 bytes       16 bit segment limit.
  118.         This layout is the same for the GDTR and IDTR registers,
  119.         except that the access rights byte must be zero.
  120.  
  121.  
  122.         i80386 LOADALL:
  123.         The i80386 variant loads 204 (dec) bytes from the address at
  124.         ES:EDI and resumes execution in the specified state.
  125.         No timing information available.
  126.  
  127.         relative offset: Bytes:   Registers:
  128.         0000:         4          CR0
  129.         0004:         4          EFLAGS
  130.         0008:         4          EIP
  131.         000c:         4          EDI
  132.         0010:         4          ESI
  133.         0014:         4          EBP
  134.         0018:         4          ESP
  135.         001c:         4          EBX
  136.         0020:         4          EDX
  137.         0024:         4          ECX
  138.         0028:         4          EAX
  139.         002c:         4          DR6
  140.         0030:         4          DR7
  141.         0034:         4          TR
  142.         0038:         4          LDT
  143.         003c:         4          GS (zero extended)
  144.         0040:         4          FS (zero extended)
  145.         0044:         4          DS (zero extended)
  146.         0048:         4          SS (zero extended)
  147.         004c:         4          CS (zero extended)
  148.         0050:         4          ES (zero extended)
  149.         0054:        12          TSS descriptor cache
  150.         0060:        12          IDT descriptor cache
  151.         006c:        12          GDT descriptor cache
  152.         0078:        12          LDT descriptor cache
  153.         0084:        12          GS descriptor cache
  154.         0090:        12          FS descriptor cache
  155.         009c:        12          DS descriptor cache
  156.         00a8:        12          SS descriptor cache
  157.         00b4:        12          CS descriptor cache
  158.         00c0:        12          ES descriptor cache
  159.  
  160.         Descriptor caches layout:
  161.         1 byte       zero
  162.         1 byte       access rights byte, same as i80286
  163.         2 bytes       zero
  164.         4 bytes       32 bit physical base address of segment
  165.         4 bytes       32 bit segment limit
  166.  
  167.  
  168. UNKNOWN:    OPCODE: 0f,04     UNDOCUMENTED
  169.  
  170.         This instruction is likely to be an alias for the LOADALL on
  171.         the i80286. It is not documented and is even marked as
  172.         unused in the 'Programmer's technical reference'. Still it
  173.         executes on the i80286. >> info wanted <<
  174.  
  175.  
  176. SETALC:     OPCODE: d6          UNDOCUMENTED
  177.  
  178.         This instruction copies the Carry Flag to the AL register.
  179.         In case of a CY, AL becomes ffh. When the Carry Flag is
  180.         cleared, AL becomes 00.
  181.  
  182.  
  183. Floating Point special instructions:
  184.  
  185. FMUL4X4:    OPCODE: db,f1     IIT ONLY
  186.  
  187.         This instruction is available only on the IIT (Integrated
  188.         Information Technology Inc.) math processors.
  189.         Takes 242 clocks.
  190.         The instruction performs a 4x4 matrix multiply in one
  191.         instruction using four banks of 8 floating point registers.
  192.         The operands must be loaded to a specific bank in a specific
  193.         order. The equation solved can be represented by:
  194.  
  195.         Xn = (A00 * Xo) + (A01 * Xo) + (A02 * Xo) + (A03 * Xo)
  196.         Yn = (A10 * Yo) + (A11 * Yo) + (A12 * Yo) + (A13 * Yo)
  197.         Zn = (A20 * Zo) + (A21 * Zo) + (A22 * Zo) + (A23 * Zo)
  198.         Vn = (A30 * Vo) + (A31 * Vo) + (A32 * Vo) + (A33 * Vo)
  199.  
  200.         Where Xo stands for the original X value and Xn for the
  201.         result. Operands must be loaded to the following registers
  202.         in the specified banks in the specified order.
  203.  
  204.            Before FMUL4X4         After FMUL4X4
  205.  
  206.                 bank           bank
  207.         Register:    0    1      2         0
  208.  
  209.         ST(0)  Xo   A33  A31        Xn
  210.         ST(1)  Yo   A23  A21        Yn
  211.         ST(2)  Zo   A13  A11        Zn
  212.         ST(3)  Vo   A03  A01        Vn
  213.         ST(4)        A32  A30         ?
  214.         ST(5)        A22  A20         ?
  215.         ST(6)        A12  A10         ?
  216.         ST(7)        A02  A00         ?
  217.  
  218.  
  219.  
  220.         All four banks can be selected by using the bankswitching
  221.         instructions, but only bank 0, 1 and 2 make sense since bank
  222.         3 is an internal scratchpad. The separate banks can contain
  223.         8 floating points and may be re-used with normal
  224.         instructions. Each bank acts like an independent i80287,
  225.         except when bankswitched inbetween, in those cases where the
  226.         initial status is not maintained;
  227.  
  228.         Pseudo- multichip operation can be performed in each bank
  229.         and even in multiple banks at the same time (although only
  230.         one instruction will operate on one register at any given
  231.         time), provided that the active register and top register
  232.         are not changed after switching from bank to bank.
  233.  
  234.  
  235.         EXAMPLE:
  236.         FINIT                 ; reset control word
  237.         FSBP1                 ; select bank 1
  238.         FLD DWORD PTR es:[si]         ; first original
  239.         FLD DWORD PTR es:[si+4]      ; second original
  240.         FLD DWORD PTR es:[si+8]      ; third original
  241.         FSTCW WORD PTR [bx]         ; save FPU control status
  242.         FSBP2                 ; NOTE ! you will see three
  243.                            active registers in this
  244.                            bank when using a
  245.                            debugger
  246.         FINIT                 ; nothing visible
  247.         FLD DWORD PTR [si]         ; new value
  248.         FLD DWORD PTR [si+4]         ; second new value
  249.         FADD ST,ST(1)             ; two values visible
  250.         FSTP DWORD PTR [si+8]         ; one value visible
  251.         FSBP1                 ; one original visible
  252.         FLDCW WORD PTR [bx]         ; restore FPU status to the
  253.                            one active in bank 1,
  254.                            causing original three
  255.                            values to be visible
  256.                            again in correct
  257.                            sequence
  258.  
  259.         ... simply continue with what you wanted to do with
  260.         those numbers from es:[si], they are still there.
  261.  
  262.         FLD DWORD PTR [si+8]         ; for instance...
  263.  
  264.  
  265.         This feature of the IIT chips can be used to perform complex
  266.         operations in registers with many components remaining the
  267.         same for a large dataset, only saving intermediary results
  268.         to ONE memory location, bankswitching to the next series of
  269.         operands, loading that ONE operand and continuing the
  270.         calculation with the next set of operands already in that
  271.         bank. This does require another read into the new bank but
  272.         may save time and memoryspace compared to memory based
  273.         operands or multiple pass algorithms with multiple arrays of
  274.         intermediary results.
  275.  
  276.  
  277.  
  278. BANKSWITCH INSTRUCTIONS:
  279.  
  280. FSBP0:        OPCODE: db,e8     IIT ONLY
  281.         Selects the original bank. (default) (6 clocks)
  282.  
  283.  
  284. FSBP1:        OPCODE: db,eb     IIT ONLY
  285.  
  286.         Selects bank 1 from FMUL4X4 instruction diagram (6 clocks)
  287.  
  288.  
  289. FSBP2:        OPCODE: db,ea     IIT ONLY
  290.  
  291.         Selects bank 2 from FMUL4X4 instruction diagram (6 clocks)
  292.  
  293. FSBP3:        OPCODE: db,e9     IIT ONLY     UNDOCUMENTED
  294.         Selects the scratchpad bank3 used by the FMUL4X4 internally.
  295.         Not very useful but funny to look at... How-to: load
  296.         any value into bank 0,1 or 2 until you have a full 8
  297.         registers, then execute this bankswitch. Using a
  298.         debugger like CodeView you are now able to inspect the
  299.         bank3 registers. (most likely to take 6 clocks)
  300.  
  301.  
  302.  
  303. TRIGONIOMETRIC FUNCTIONS:
  304.  
  305.         Apparently the IIT 2c87 recognises and executes some
  306.         i80387 trigoniometric functions. UNDOCUMENTED
  307.         FSIN (sine) and FCOS (cosine) have been tested and function
  308.         according to the Intel 80387 specifications. FSINCOS
  309.         (available on the Intel 80287XL, 80387 and up) does not
  310.         work.
  311.  
  312. FSIN:        OPCODE: d9,fe     IIT 2c87+ (also Intel 80387+) UNDOCUMENTED
  313.         Calculates the sine of the input in radians in ST(0). After
  314.         calculation, ST(0) contains the sine. Takes approximately
  315.         120 clocks.
  316.  
  317. FCOS:        OPCODE: d9,ff     IIT 2c87+ (also Intel 80387+) UNDOCUMENTED
  318.         Calculates the cosine of the input in radians in ST(0).
  319.         After calculation, ST(0) contains the cosine. Takes
  320.         approximately 120 clocks.
  321.  
  322.  
  323. ... CUT HERE FOR FIRST REVISION, next part is to be revised ...
  324.  
  325.  
  326.  
  327. Instructions by mnemonic mnemonic:
  328. opcode: processor:  remark & remedy:
  329.  
  330. AAA           i80286 & i80386 & i80486
  331.  
  332. CMPS            i80286
  333. CMPXCHG         i80486
  334. FINIT
  335. FSTSW
  336. FSTCW
  337.  
  338.  
  339. INS            i80286 &
  340.             i80386 &
  341.             i80486
  342.  
  343. INVD            i80486
  344.  
  345.  
  346.  
  347. MOV to SS     n/a    early 8088  Some early 8088 would not properly
  348.                     disable interrupts after a move to
  349.                     the SS register. Workaround would
  350.                     be to explicitly clear the
  351.                     interrupts, update SS and SP and
  352.                     then re-enable the interrupts.
  353.                     Typically this would occur in a
  354.                     situation where one would relocate
  355.                     a stack in memory, more than 64Kb
  356.                     from the original one, updating
  357.                     both SS and SP like in:
  358.                       MOV SS,AX  ; would disable
  359.                            interrupts
  360.                            automatically during
  361.                            this and next
  362.                            instruction.
  363.                       MOV SP,DX  ; interrupts disabled
  364.                       ...     ; interrupts enabled.
  365.  
  366.  
  367. multiple prefixes
  368. with REPx        8088 & 8086 They would not properly restart at
  369.                     the first prefix byte after an
  370.                     interrupt. when more than one
  371.                     prefix is used. e.g. LOCK REP MOVSW
  372.                     CS:[bx]. A workaround is to test
  373.                     after the instruction for CX==0,
  374.                     here: LOCK REP MOVSW CS:[BX] OR
  375.                     CX,CX JNZ here because of the CS
  376.                     override, the REP and LOCK prefixes
  377.                     would not be recognised to be part
  378.                     of the instruction and the REP MOVSW
  379.                     would be aborted. This also seems to
  380.                     be the case for a REP MOVSW CS:[BX]
  381.                     Note that this also implies that
  382.                     REPZ, REPNZ are affected in SCASW
  383.                     for instance.
  384.  
  385.                                                         
  386.