• Please review our updated Terms and Rules here

Parity Flag

neilobremski

Experienced Member
Joined
Oct 9, 2016
Messages
55
Location
Seattle, USA
My understanding of the parity flag (PF) is that it's set when the result (low 8 bits) of the previous operation is EVEN otherwise it's cleared to mean ODD. What am I missing?

Code:
XOR AX, AX	; PF=1 (DEBUG shows "PE")
ADD AL, 02	; PF=0 (DEBUG shows "PO")
OR  AL, AL	; PF=0 (but AL==0x02, which is even!)
 
Parity is determined by the number of '1' bits in a number, not by the value itself.

So:

0 = 0000 0000 = even
1 = 0000 0001 = odd
2 = 0000 0010 = odd
3 = 0000 0011 = even
4 = 0000 0100 = odd
5 = 0000 0101 = even

Count the number of "1" bits in the binary number; if that number is even, it's even parity; otherwise, it's odd.

Or, to quote Seymour Cray, when asked why the CDC 6000 machines didn't use parity on memory: "Parity is for farmers".
(His later machines not only used parity, but SECDED)
 
Yeah, parity isn't terribly useful for games programming. It was intended for finding errors when doing communications, and is also useful for checking the C2 flag on floating-point operations, but I've never actually had reason to use it myself.

To figure out if a number is even or odd, use "test operand,1" and then check the zero flag (jz or jnz) - zf will be set for an even number.
 
The parity flag is very rarely used and as far as I know, is never used by HLL compilers (at least, I have never seen it in use from looking at disassembled code) but it can be useful for saving a few bytes on rare occasions. Currently, there are only four occurences in the entire XTIDE Universal BIOS project;

http://www.xtideuniversalbios.org/b...sal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm
Code:
	; Heads must be 16, 32, 64, 128 or 255 (round up to the nearest)
	; Max = 255
	mov	cl, 16					; Min number of heads
.CompareNextValidNumberOfHeads:
	cmp	ax, cx
	jbe	SHORT .NumberOfHeadsNowInCX
	eSHL_IM	cx, 1					; Double number of heads
	jpo	SHORT .CompareNextValidNumberOfHeads	; Reached 256 heads?
	dec	cx					;  If so, limit heads to 255
.NumberOfHeadsNowInCX:
	mov	bx, cx					; Number of heads are returned in BL
	mov	bh, LBA_ASSIST_SPT			; Sectors per Track
The trick here is that CX, initially 16, a power of 2 which means it has just one bit set (parity=odd), can be shifted until that bit moves into CH and CL becomes zero (parity=even) in which case a single byte instruction (DEC CX) can be used to set CX to the max number of heads=255. Shifting only CL would result in the bit being "lost" (into the carry flag) which would force me to use a two-byte instruction like DEC CL or MOV CL, 255 or SBB CL, CL instead.

http://www.xtideuniversalbios.org/b...BIOS/Src/Handlers/Int13h/AH24h_HSetBlocks.asm
Code:
	; All valid block sizes are powers of 2 which means BL have just one bit set (parity odd).
	; Incrementing BX will cause all block sizes except 1 to have two bits set (parity even).
	; Note that PF reflects only the lowest 8 bits of any register being modified.
	inc	bx			; 1 -> 2 ?
	jpo	SHORT .DisableBlockMode	; Jump if BL = 2
	dec	bx			; Restore block size (was larger than 1)
This is pretty self-explanatory. INC BX is a single byte instruction as opposed to CMP BL/BX, IMM which is 3 bytes or TEST BL/BX, IMM which is 3-4 bytes. (This code is part of a routine that disables block mode entirely if the block size is 1).

http://www.xtideuniversalbios.org/b...al_BIOS_Configurator_v2/Src/IdeAutodetect.asm
Code:
	; Detect 8-bit devices only if MODULE_8BIT_IDE is available
	test	BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
	jz	SHORT NoIdeDeviceFound
	jpo	SHORT .SkipXTCF			; Only 1 bit set means no MODULE_8BIT_IDE_ADVANCED

http://www.xtideuniversalbios.org/b...urator_v2/Src/Menupages/IdeControllerMenu.asm
Code:
	; Remaining device types all require MODULE_8BIT_IDE or MODULE_8BIT_IDE_ADVANCED
	test	BYTE [es:ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
	jz	SHORT .SupportForDeviceNotAvailable

	; We know MODULE_8BIT_IDE is included
	lahf	; Save the PF
	cmp	al, DEVICE_8BIT_XTIDE_REV2
	jbe	SHORT .ChangingToXTIDEorXTCF
	sahf	; Restore the PF
	jpo	SHORT .SupportForDeviceNotAvailable	; Jump if no MODULE_8BIT_IDE_ADVANCED
These last two examples both rely on the fact that FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED can't exist without FLG_ROMVARS_MODULE_8BIT_IDE.

I would love to see if anyone else has come up with nifty uses for the parity flag.
 
The parity flag is a holdover from the Intel 8008, which, in turn comes from the Datapoint 2200. Since Intel was bidding the 8008 as a processor for the 2200, it naturally followed the instruction set. I don't have a clue as to what use the 2200 had for it. Probably just an engineer's "good idea".

The parity flag was probably obsolete by the time of the 8080. What would have served the same purpose and have been far more useful would have been a fast "count the ones" instruction.
 
The parity flag is a holdover from the Intel 8008, which, in turn comes from the Datapoint 2200. Since Intel was bidding the 8008 as a processor for the 2200, it naturally followed the instruction set. I don't have a clue as to what use the 2200 had for it. Probably just an engineer's "good idea".

The parity flag was probably obsolete by the time of the 8080. What would have served the same purpose and have been far more useful would have been a fast "count the ones" instruction.

Which modern x86 processors does have (POPCNT).
 
So did the CDC 6600 more than 50 years ago... (CXi Xk = 47ikk opcode)--and even had a separate functional unit for just that single instruction. Word was back then that Seymour was asked to include it by a "secret" government organization.

What was the first system to have such an instruction?
 
I ended up using the parity flag in my 512-byte DONKEY remake, as an extra modification to a pseudo-random number (to determine the next donkey's lane); but then my code was rushed and isn't something one should learn from. :) Still, that's about the only use I could think of for PF - cheap in terms of code size.
 
The parity bit is sometimes used as a ninth bit in RS485 communication (to identify a slave address for example) and with some clever manipulation you can preset the parity bit to 0 or 1 by selecting even/odd parity in the communication adapter after calculating parity of the the data byte first..
 
I'm not maintaining that parity isn't used, but that it's mostly a hardware, not a software matter. SCSI, for example, has an option for parity checking, as do many memory systems and serial I/O configurations. But none of that is done with software.

Looking over the Datapoint 2200 architecture, it's not clear that the parity branches were of any practical use.
 
Back
Top