On the first cycle, the opcode is read, and the program counter is incremented past it. (In an emulator, this will usually take place before the switch statement).
Code:
Opcode = CPU_Read (CPU_PC.Word++);
On the second cycle, the pointer address is read into a temporary register, and the program counter is incremented again.
Code:
Temp = CPU_Read (CPU_PC.Word++);
On the third cycle, a dummy read is performed from the temporary address, and then the X register is added to the temporary register. This temporary register is 8 bits, so if it goes past $FF it will wrap around to $00, *not* $100.
Code:
CPU_Read (Temp);
Temp += CPU_X;
On the fourth cycle, the low byte of the effective address is read, and then the temporary register is incremented.
Code:
Address.Low = CPU_Read (Temp++);
On the fifth cycle, the high byte of the effective address is read.
Code:
Address.High = CPU_Read (Temp);
After this, the standard read, write, or RMW stuff is performed using the effective address.