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
101 lines
2.2 KiB
C
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++;
|
|
}
|
|
}
|