Unexpected unsigned-to-signed promotion

This shows 0x8000:

  byte b = 0x80;
  unsigned long ul = 256;
  unsigned long r = b * ul;
  Serial.println(r, HEX);

So it appears that what dc42 said is correct (the second quote, about the shift operations).