Can someone help me figure out what this loop is doing?

  // send CRC
  uint8_t crc = 0XFF;
  if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
  if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
  spiSend(crc);
  
  // wait for response
  for (uint8_t retry = 0; ((r1 = spiRec()) & 0X80) && retry != 0XFF; retry++);

The bit there where it waits for a response is confusing me.

If I understand this correctly, a byte is read from the SD card into R1. R1 is then ANDed with 0x80. So it appears to be looking to see if a particular bit is set in the reply. If no bit is set, then that side of the equation evaluates to false.

Then retry is compared to 0xFF. If it isn't 0xFF, then it evaluates to true, and the loop continues. This makes sense. It's trying 255 times to get the response its looking for.

But it's the first part that doesn't make sense to me. If it's waiting for a response from the card, why does it continue only if a particular bit is not set? Wouldn't a card that is not responding return 0? And wouldn't 0 & 0x80 evaluate to false, and cause the loop to exit prematurely?

A loop finishes on a false in the test condition. So it is looping until either 0x80 bit is false or it has tried 255 times. (As the && will be false if either term is false.)

Wouldn't a card that is not responding return 0?

Not necessarily. It depends on the specification for the card. It could also be that the programmer wanted to make sure that he was looking for the top bit and not just a non-zero value, which could be noise on the comms line, for example.

If the card did return 0, then you would get:

0x00 & 0x80 = 0 = false, which means the loop would be broken.

That's why I'm asking. I would expect the card to return 0 if it's not responding. But maybe it returns 0xFF instead, until it responds, and then it responds with that particular bit not being set.

Anyway I guess this code was not what was broken because I found the issue elsewhere.

0xFF is also -1 a very common error value ...

Well I was thinking more along the lines of the data line just being stuck high while the card isn't responding.