program t35; { t35 -- `not', on both of the operand types it is defined for. TPSRC9 neglevel picks the instruction from the operand's type before it emits anything: CMP.B CL,#$0A ; integer ? JZ negnot ; -> CALL loadatom ; NOT AX (F7 D0) CMP.B CL,#$0B ; boolean ? CALL errnz ; -> error 47 for anything else CALL loadatom ; -> XOR AL,#01 (34 01) This compiler used to emit NOT AX for both of them, so every boolean came out wrong one way: `not (a = a)' computed 0FFFEh and the runtime's wrbool tests [BP+4] <> 0, which reads 0FFFEh as TRUE. Pascal says FALSE. Exec86 and qemu agreed with each other and both disagreed with Pascal, which is what pins the fault on the compiler and not on the interpreter. The integer half is here because it is the other arm of the same branch: `not a' has to stay NOT AX, and must not be dragged along to XOR AL,#01 by a fix aimed at booleans. A BOOLEAN variable is one byte and LoadAtom clears AH after a byte load, so XOR AL,#01 cannot leave a dirty high byte for wrbool to trip over. Every expectation below is derived from Pascal's definition - `not' on an integer is the 16-bit one's complement, `not' on a boolean is logical negation - and from nowhere else. } var a : integer; b : boolean; begin a := 17; writeln (not a); writeln (not (a = 17)); writeln (not (a = 18)); writeln (not (a > 100)); b := a = 17; writeln (not b); b := a = 18; writeln (not b); writeln (not 5) end.