Thank you for your fast answer.
Last night I changed the address variable to local, and I got the following results: 0,1,2,3,2,3,2,3,... So, the TR pin does change, after all. I's certainly not in the order I expected (I was expecting 3,2,1,0,3,...), but hey, at least I didn't blow up the console port.
I'm only guessing here, but it seems the console keeps repeating 2,3,... because the Saturn encodes the Peripheral ID in these nibbles. In my case, they are:
Nibble3 (12): 11 00
Nibble2 (07): 01 11
The Saturn peripheral ID is:
bit3: (1|1)=1
bit2: (0|0)=0
bit1: (0|1)=1
bit0: (1|1)=1
which gives 1011=11. According to the SMPC User's Manual, this is OK.
Actually, Sega seems to have followed some sort of MegaDrive/Genesis peripheral ID convention. Anyway, I already expected this result, that's why I chose 12 for the third nibble value. That's because:
bit3: (L TRG, don't care | always 1, tied to VCC inside the pad) = 1
bit2: (always 0, tied to GND | always 0, tied to GND) = 0
bit1: (RIGHT | LEFT) = 1, since they can't both be pressed.
bit0: (UP | DOWN) = 1, same here.
So I guess I'm dealing with a timing issue, after all.
Yes, I do have an optimization option, which is optimizing for size (I'm not using the Arduino IDE, I'm using AtmelStudi6 with the Arduino libraries). I'm a total noob (this is my second project) and I'm learning as I go. I've never dealt with ASM before, but I'll try to understand your code and implement your suggestions.
Many thanks, micro.