
DevelopmentSega Master System / Mark III / Game Gear 
Home  Forums  Games  Scans  Maps  Cheats  Credits 
Sometimes you want to represent signed numbers, sometimes you don't. But it can be a hassle to convert between them, and having to deal with both might require different instructions. It's also handy to be able to quickly tell if a number's positive or negative. Two's complement notation solves this by not requiring any conversion, by allowing you to use the same operations on both types of number, and having a single bit of the number tell the sign.
In an 8bit unsigned representation, you can represent any number from 0 to 255. You should understand that already before attempting to understand this.
In two's complement notation, the numbers 0 to 127 have exactly the same representation as the unsigned version: %00000000
= $00
= 0 up to %01111111
= $7f
= 127. Thus, you don't need to do any conversion between signed and unsigned numbers (so long as the unsigned number is less than 128; bigger numbers can't be represented anyway). This gives the entire positive range; you may notice this is all values with the high bit set to 0.
The negative numbers are represented by the high bit being 1
. 1 is represented by %11111111
= $ff
, and increasingly negative numbers (2, 3, ...) are represented by increasingly smaller binary numbers ($fe
, $fd
,...).
Binary  Hex  2's complement 

%01111111  $7f  +127 
%01111110  $7e  +126 
%01111101  $7d  +125 
%01111100  $7c  +124 
...  
%00000100  $04  +4 
%00000011  $03  +3 
%00000010  $02  +2 
%00000001  $01  +1 
%00000000  $00  0 
%11111111  $ff  1 
%11111110  $fe  2 
%11111101  $fd  3 
%11111100  $fc  4 
...  
%10000011  $83  125 
%10000010  $82  126 
%10000001  $81  127 
%10000000  $80  128 
Because of the continuous representation around the $ff
to 00
boundary, normal unsigned operations give correct results with two's complement numbers. All you really need is some way to know when the number breaks the 128/+127 boundary, which is given by the overflow flag.
Two's complement can be horribly confusing. You don't have to even consider it most of the time when coding on the Z80; you can just ignore it and treat all your numbers as unsigned and you're unlikely to meet any insurmountable problems. However, when you come to a situation where you need it, just give it a go without thinking too much and chances are, you'll find it does exactly what you want with little effort.