CPU addressing modes

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
CPU addressing modes
by on (#34269)
Hi all.

Just getting started on my emulator, so I'm working on the CPU at the minute. I'm not sure if I'm understanding the addressing modes right though...

Would the following be right to calculate operand addresses?

Code:
#define ADDR_ZP      (ram[g_cpu.pc++])
#define ADDR_ZPX   (ram[g_cpu.pc++] + g_cpu.x)
#define ADDR_ZPY   (ram[g_cpu.pc++] + g_cpu.y)
#define ADDR_ABS   (cpu_read(g_cpu.pc++) | (cpu_read(g_cpu.pc++) << 8))
#define ADDR_ABSX   ((cpu_read(g_cpu.pc++) | ((cpu_read(g_cpu.pc++) << 8))) + g_cpu.x)
#define ADDR_ABSY   ((cpu_read(g_cpu.pc++) | ((cpu_read(g_cpu.pc++) << 8))) + g_cpu.y)
#define ADDR_INDX   ((cpu_read(g_cpu.pc++ + g_cpu.x)) | (cpu_read(g_cpu.pc++) << 8))
#define ADDR_INDY   ((cpu_read(g_cpu.pc++)) | ((cpu_read(g_cpu.pc++) << 8) + g_cpu.y)))   


I'm accessing RAM directly for zero page accesses, and cpu_read is my standard IO function.

Thanks for any help/suggestions you can give :)

by on (#34270)
Comments:

ADDR_ZP, ADDR_ZPX, ADDR_ZPY, ADDR_ABS, ADDR_ABSX, and ADDR_ABSY all look okay. You might want to & 0xFF the PC address result on ADDR_ZP, depending upon how high g_cpu.pc can go.

Your ADDR_INDX and ADDR_INDY are hard to interpret unless you give more detail about how they're being used. They should be following this logic (best to explain it, rather than just give you formulae). Assume the following memory layout:

memory[$00] = $FA
memory[$01] = $80
memory[$02] = $81
memory[$03] = $C0
memory[$80FA] = $EE
memory[$80FB] = $FF
memory[$8180] = $CC
memory[$8181] = $BB
memory[$C081] = $AA

For ADDR_INDX:

LDX #0
LDA ($00,X)

Effective address of $80FA. A = data read from $80FA, thus A = $EE.

LDX #1
LDA ($00,X)

Effective address of $8180. A = data read from $8180, thus A = $CC.

LDX #1
LDA ($01,X)

Effective address of $C081. A = data read from $C081, thus A = $AA.



For ADDR_INDY:

LDY #0
LDA ($00),Y

Effective address of $80FA + $00. A = data read from $80FA, thus A = $EE.

LDY #1
LDA ($00),Y

Effective address of $80FA + $01. A = data read from $80FB, thus A = $FF.

LDY #1
LDA ($01),Y

Effective address of $8180 + $01. A = data read from $8181, thus A = $BB.

An easier way to remember the two addressing modes: (ZP,X) is called pre-indexed, and (ZP),Y is called post-indexed.


Don't forget about cycle additions in the case of page wrapping, too. Details:

http://www.obelisk.demon.co.uk/6502/reference.html#LDA

by on (#34300)
Thanks for that koitsu, I always do better with some examples!
I think I've got that sorted now :)

An unrelated question - does anyone know what status flags are set on CPU reset?

by on (#34303)
thinkpad240 wrote:
An unrelated question - does anyone know what status flags are set on CPU reset?


They are unaffected, except the Interrupt flag is set.

by on (#34304)
- I don't know if the compiler would guess this...

Code:
((cpu_read(g_cpu.pc++)) | ((cpu_read(g_cpu.pc++) << 8) + g_cpu.y)))


- My suggestion: don't write like function(value++), but instead use function(value); value++. ;)

by on (#34312)
Your use of ++ twice in one expression is undefined. While the function call itself is a sequence point, there is no guarantee regarding the order the calls are evaluated in. You should explicitly adjust the PC afterwards, either using gcc's statements as expressions extension, or some other bit of code.

by on (#34314)
Quote:
You should explicitly adjust the PC afterwards, either using gcc's statements as expressions extension, or some other bit of code.

Stick to standard C, since undefined in the original expression means "could crash program", not just "could give different values".

addr = cpu_read(g_cpu.pc) + cpu_read(g_cpu.pc+1)*0x100 + g_cpu.y;
g_cpu.pc += 2;

by on (#34315)
Duly noted, thanks guys. I'd actually already ditched the incrementing from within the macro, it was giving me problems elsewhere, and as you've pointed out, would have only given me even more problems later on.

Your help is much appreciated.