💾 Archived View for gemini.spam.works › mirrors › textfiles › hamradio › v20_bug.txt captured on 2023-01-29 at 08:11:51.

View Raw

More Information

⬅️ Previous capture (2020-10-31)

-=-=-=-=-=-=-

                         NEC V20/V30 Bug
                         Howard Vigorita
                 New York Amateur Computer Club

I recently saw a message from Jonathan Platt on a Florida bulletin
board which mentioned rumors of a bug in the NEC V20/V30 processor.
For those of you that are interested, I've documented the bug below
using a V30 chip. Basically, the NEC chips fail to implement the 2
byte version of the POP instruction. This is not a serious bug;
the Intel register PUSH & POP instructions are duplicated in two
sets of instructions and all the assemblers and compilers I've seen
default to the shorter single byte set in favor of the two byte
set.

For those unfamiliar with the longer PUSH/POP form, the two byte
form of the PUSH (which works) will be shown first. The 'debug'
program is fed input from the 'testpush' file. The AX register is
loaded with FFFF hex, pushed onto the stack with the two byte PUSH,
then POPed into the CX register with the single byte POP opcode.
Note that the two byte PUSH is entered using a DB to load in the
FFF0 opcode. The '-u' command issued below shows that although
debug's '-a' command defaults to the short form POP, the long form
is interpreted properly when encountered. 

	A>debug < testpush

	-a 100

	0A7F:0100 mov ax,ffff
	0A7F:0103 db ff,f0
	0A7F:0105 pop cx
	0A7F:0106 nop
	0A7F:0107 

	-u 100,106

	0A7F:0100 B8FFFF        MOV     AX,FFFF                            
	0A7F:0103 FFF0          PUSH    AX                                 
	0A7F:0105 59            POP     CX                                 
	0A7F:0106 90            NOP                                        

	-g =100 106
                     
     AX=FFFF  BX=0000  CX=FFFF  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000  
     DS=0A7F  ES=0A7F  SS=0A7F  CS=0A7F  IP=0106   NV UP DI PL NZ NA PO NC 
     0A7F:0106 90            NOP                                        

	-q

The CX register ended up with FFFF hex as expected.

But the inverse operation does not work on the NEC chip. Below, 'testpop'
feeds input to 'debug'. The AX register is loaded with FFFF, a one byte
opcode PUSH AX is done, followed by the two byte form of the POP into CX.
Again, the two byte POP is implemented by DB'ing its 8FC1 opcode. Although
the SP register (stack pointer) is properly adjusted by the POP, the FFFF
hex does not end up in CX as it should:

	A>debug < testpop

	-a 100

	0A7F:0100 mov ax,ffff
	0A7F:0103 push ax
	0A7F:0104 db 8f,c1
	0A7F:0106 nop
	0A7F:0107

	-u 100,106

	0A7F:0100 B8FFFF        MOV     AX,FFFF                            
	0A7F:0103 50            PUSH    AX                                 
	0A7F:0104 8FC1          POP     CX                                 
	0A7F:0106 90            NOP                                        

	-g =100 106

     AX=FFFF  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000  
     DS=0A7F  ES=0A7F  SS=0A7F  CS=0A7F  IP=0106   NV UP DI PL NZ NA PO NC 
     0A7F:0106 90            NOP                                        

	-q

The above 'feature' can be exploited in distinguishing between NEC and
Intel chips. It is much simpler than the technique of issuing a unique
NEC instruction and intercepting the error trap interrupt.