ysyx-workbench/am-kernels/kernels/litenes/src/cpu-addressing.c
tracer-ysyx d08c2860da > compile NEMU
ysyx_22040000 李心杨
Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar  1 12:35:11 UTC 2024 x86_64 GNU/Linux
 16:26:21  up 4 days  3:32,  2 users,  load average: 0.85, 0.91, 0.95
2024-03-24 16:26:21 +08:00

101 lines
2.2 KiB
C

#include "cpu.h"
#include "cpu-internal.h"
#include "memory.h"
// CPU Addressing Modes
void cpu_address_implied() { }
void cpu_address_immediate() {
op_value = memory_readb(cpu.PC);
cpu.PC++;
}
void cpu_address_zero_page() {
op_address = memory_readb(cpu.PC);
op_value = CPU_RAM[op_address];
cpu.PC++;
}
void cpu_address_zero_page_x() {
op_address = (memory_readb(cpu.PC) + cpu.X) & 0xFF;
op_value = CPU_RAM[op_address];
cpu.PC++;
}
void cpu_address_zero_page_y() {
op_address = (memory_readb(cpu.PC) + cpu.Y) & 0xFF;
op_value = CPU_RAM[op_address];
cpu.PC++;
}
void cpu_address_absolute() {
op_address = memory_readw(cpu.PC);
op_value = memory_readb(op_address);
cpu.PC += 2;
}
void cpu_address_absolute_x() {
op_address = memory_readw(cpu.PC) + cpu.X;
op_value = memory_readb(op_address);
cpu.PC += 2;
if ((op_address >> 8) != (cpu.PC >> 8)) {
op_cycles++;
}
}
void cpu_address_absolute_y() {
op_address = (memory_readw(cpu.PC) + cpu.Y) & 0xFFFF;
op_value = memory_readb(op_address);
cpu.PC += 2;
if ((op_address >> 8) != (cpu.PC >> 8)) {
op_cycles++;
}
}
void cpu_address_relative() {
op_address = memory_readb(cpu.PC);
cpu.PC++;
if (op_address & 0x80)
op_address -= 0x100;
op_address += cpu.PC;
if ((op_address >> 8) != (cpu.PC >> 8)) {
op_cycles++;
}
}
void cpu_address_indirect() {
word arg_addr = memory_readw(cpu.PC);
// The famous 6502 bug when instead of reading from $C0FF/$C100 it reads from $C0FF/$C000
if ((arg_addr & 0xFF) == 0xFF) {
// Buggy code
op_address = (memory_readb(arg_addr & 0xFF00) << 8) + memory_readb(arg_addr);
}
else {
// Normal code
op_address = memory_readw(arg_addr);
}
cpu.PC += 2;
}
void cpu_address_indirect_x() {
byte arg_addr = memory_readb(cpu.PC);
op_address = (memory_readb((arg_addr + cpu.X + 1) & 0xFF) << 8) | memory_readb((arg_addr + cpu.X) & 0xFF);
op_value = memory_readb(op_address);
cpu.PC++;
}
void cpu_address_indirect_y() {
byte arg_addr = memory_readb(cpu.PC);
op_address = (((memory_readb((arg_addr + 1) & 0xFF) << 8) | memory_readb(arg_addr)) + cpu.Y) & 0xFFFF;
op_value = memory_readb(op_address);
cpu.PC++;
if ((op_address >> 8) != (cpu.PC >> 8)) {
op_cycles++;
}
}