fixed unneeded ppu read access, causing the vram address to be incremented when it shouldnt be

This commit is contained in:
Lauchmelder 2021-10-30 19:36:32 +02:00
parent 35b67dac5f
commit 2fdae00ff8
6 changed files with 41 additions and 11 deletions

View file

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.8) cmake_minimum_required (VERSION 3.8)
add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.h" "ppu.c" "mapper.h" "mappers/mapper000.h" "mappers/mapper000.c" "mapper.c") add_executable (nesemu "main.c" "bus.c" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.c" "mappers/mapper000.c" "mapper.c")
target_include_directories(nesemu PUBLIC ${SDL2_INCLUDE_DIRS}) target_include_directories(nesemu PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(nesemu PUBLIC ${SDL2_LIBRARIES}) target_link_libraries(nesemu PUBLIC ${SDL2_LIBRARIES})

View file

@ -34,7 +34,7 @@ struct Bus* createBus(SDL_Renderer* renderer)
memset(bus->ram, 0x00, 0x18); memset(bus->ram, 0x00, 0x18);
// Create and insert cartridge // Create and insert cartridge
bus->cartridge = createCartridge(bus, "roms/donkeykong.nes"); bus->cartridge = createCartridge(bus, "roms/nestest.nes");
// Create CPU and attach it // Create CPU and attach it
bus->cpu = createCPU(bus); bus->cpu = createCPU(bus);

View file

@ -12,7 +12,7 @@ static inline void Push(struct Bus* bus, Byte val)
static inline Byte Pop(struct Bus* bus) static inline Byte Pop(struct Bus* bus)
{ {
return readBus(bus, 0x0100 + (++bus->cpu->sp)); return readBus(bus, 0x0100 + (++bus->cpu->sp), 0);
} }
struct CPU* createCPU(struct Bus* parent) struct CPU* createCPU(struct Bus* parent)
@ -26,7 +26,7 @@ struct CPU* createCPU(struct Bus* parent)
// TODO: THIS IS JUST FOR THE TEST ROM // TODO: THIS IS JUST FOR THE TEST ROM
cpu->pc.word = 0xC000; cpu->pc.word = 0xC000;
cpu->pc.word = ((Word)readBus(parent, 0xFFFD) << 8) | readBus(parent, 0xFFFC); cpu->pc.word = ((Word)readBus(parent, 0xFFFD, 0) << 8) | readBus(parent, 0xFFFC, 0);
cpu->status.raw = 0x34; cpu->status.raw = 0x34;
cpu->acc = 0; cpu->acc = 0;
@ -94,7 +94,7 @@ int tickCPU(struct CPU* cpu)
if (cpu->remainingCycles == 0) if (cpu->remainingCycles == 0)
{ {
fetch(cpu); prepareFetch(cpu);
execute(cpu); execute(cpu);
return 1; return 1;
} }
@ -107,7 +107,7 @@ void tickInstr(struct CPU* cpu)
while (!tickCPU(cpu)); while (!tickCPU(cpu));
} }
void fetch(struct CPU* cpu) void prepareFetch(struct CPU* cpu)
{ {
Byte opcodeVal = readBus(cpu->bus, cpu->pc.word); Byte opcodeVal = readBus(cpu->bus, cpu->pc.word);
cpu->currentOpcode = OPCODE_TABLE + opcodeVal; cpu->currentOpcode = OPCODE_TABLE + opcodeVal;
@ -161,7 +161,7 @@ void fetch(struct CPU* cpu)
} break; } break;
case IMM: case IMM:
cpu->fetchedVal = readBus(cpu->bus, cpu->pc.word++); cpu->fetchedAddress = cpu->pc.word++;
return; return;
case IMP: case IMP:
@ -221,8 +221,12 @@ void fetch(struct CPU* cpu)
} break; } break;
} }
}
cpu->fetchedVal = readBus(cpu->bus, cpu->fetchedAddress); void fetch(struct CPU* cpu)
{
if(cpu->currentOpcode->addr != IMP)
cpu->fetchedVal = readBus(cpu->bus, cpu->fetchedAddress);
} }
void execute(struct CPU* cpu) void execute(struct CPU* cpu)
@ -233,6 +237,7 @@ void execute(struct CPU* cpu)
{ {
case ADC: case ADC:
{ {
fetch(cpu);
Word result = cpu->acc + cpu->fetchedVal + cpu->status.carry; Word result = cpu->acc + cpu->fetchedVal + cpu->status.carry;
cpu->status.carry = (result > 0xFF); cpu->status.carry = (result > 0xFF);
@ -245,6 +250,7 @@ void execute(struct CPU* cpu)
case AND: case AND:
{ {
fetch(cpu);
cpu->acc &= cpu->fetchedVal; cpu->acc &= cpu->fetchedVal;
cpu->status.negative = (cpu->acc >> 7); cpu->status.negative = (cpu->acc >> 7);
@ -253,6 +259,7 @@ void execute(struct CPU* cpu)
case ASL: case ASL:
{ {
fetch(cpu);
cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80);
cpu->fetchedVal <<= 1; cpu->fetchedVal <<= 1;
@ -379,6 +386,7 @@ void execute(struct CPU* cpu)
case BIT: case BIT:
{ {
fetch(cpu);
cpu->status.negative = (cpu->fetchedVal >> 7); cpu->status.negative = (cpu->fetchedVal >> 7);
cpu->status.overflow = (cpu->fetchedVal >> 6); cpu->status.overflow = (cpu->fetchedVal >> 6);
cpu->status.zero = ((cpu->acc & cpu->fetchedVal) == 0x00); cpu->status.zero = ((cpu->acc & cpu->fetchedVal) == 0x00);
@ -415,6 +423,7 @@ void execute(struct CPU* cpu)
case CMP: case CMP:
{ {
fetch(cpu);
Byte result = cpu->acc - cpu->fetchedVal; Byte result = cpu->acc - cpu->fetchedVal;
cpu->status.negative = (result >> 7); cpu->status.negative = (result >> 7);
@ -424,6 +433,7 @@ void execute(struct CPU* cpu)
case CPX: case CPX:
{ {
fetch(cpu);
Byte result = cpu->x - cpu->fetchedVal; Byte result = cpu->x - cpu->fetchedVal;
cpu->status.negative = (result >> 7); cpu->status.negative = (result >> 7);
@ -433,6 +443,7 @@ void execute(struct CPU* cpu)
case CPY: case CPY:
{ {
fetch(cpu);
Byte result = cpu->y - cpu->fetchedVal; Byte result = cpu->y - cpu->fetchedVal;
cpu->status.negative = (result >> 7); cpu->status.negative = (result >> 7);
@ -442,6 +453,7 @@ void execute(struct CPU* cpu)
case DCP: case DCP:
{ {
fetch(cpu);
cpu->fetchedVal--; cpu->fetchedVal--;
writeBus(cpu->bus, cpu->fetchedAddress, cpu->fetchedVal); writeBus(cpu->bus, cpu->fetchedAddress, cpu->fetchedVal);
Byte result = cpu->acc - cpu->fetchedVal; Byte result = cpu->acc - cpu->fetchedVal;
@ -455,6 +467,7 @@ void execute(struct CPU* cpu)
case DEC: case DEC:
{ {
fetch(cpu);
cpu->fetchedVal--; cpu->fetchedVal--;
cpu->status.negative = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.negative = ((cpu->fetchedVal & 0x80) == 0x80);
@ -481,6 +494,7 @@ void execute(struct CPU* cpu)
case EOR: case EOR:
{ {
fetch(cpu);
cpu->acc ^= cpu->fetchedVal; cpu->acc ^= cpu->fetchedVal;
cpu->status.negative = (cpu->acc >> 7); cpu->status.negative = (cpu->acc >> 7);
@ -489,6 +503,7 @@ void execute(struct CPU* cpu)
case INC: case INC:
{ {
fetch(cpu);
cpu->fetchedVal++; cpu->fetchedVal++;
cpu->status.negative = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.negative = ((cpu->fetchedVal & 0x80) == 0x80);
@ -515,6 +530,7 @@ void execute(struct CPU* cpu)
case ISC: case ISC:
{ {
fetch(cpu);
cpu->fetchedVal++; cpu->fetchedVal++;
writeBus(cpu->bus, cpu->fetchedAddress, cpu->fetchedVal); writeBus(cpu->bus, cpu->fetchedAddress, cpu->fetchedVal);
Word result = cpu->acc + ~cpu->fetchedVal + cpu->status.carry; Word result = cpu->acc + ~cpu->fetchedVal + cpu->status.carry;
@ -545,6 +561,7 @@ void execute(struct CPU* cpu)
case LAX: case LAX:
{ {
fetch(cpu);
cpu->acc = cpu->fetchedVal; cpu->acc = cpu->fetchedVal;
cpu->x = cpu->fetchedVal; cpu->x = cpu->fetchedVal;
@ -554,6 +571,7 @@ void execute(struct CPU* cpu)
case LDA: case LDA:
{ {
fetch(cpu);
cpu->acc = cpu->fetchedVal; cpu->acc = cpu->fetchedVal;
cpu->status.negative = (cpu->acc >> 7); cpu->status.negative = (cpu->acc >> 7);
@ -562,6 +580,7 @@ void execute(struct CPU* cpu)
case LDX: case LDX:
{ {
fetch(cpu);
cpu->x = cpu->fetchedVal; cpu->x = cpu->fetchedVal;
cpu->status.negative = (cpu->x >> 7); cpu->status.negative = (cpu->x >> 7);
@ -570,6 +589,7 @@ void execute(struct CPU* cpu)
case LDY: case LDY:
{ {
fetch(cpu);
cpu->y = cpu->fetchedVal; cpu->y = cpu->fetchedVal;
cpu->status.negative = (cpu->y >> 7); cpu->status.negative = (cpu->y >> 7);
@ -578,6 +598,7 @@ void execute(struct CPU* cpu)
case LSR: case LSR:
{ {
fetch(cpu);
cpu->status.negative = 0; cpu->status.negative = 0;
cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01); cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01);
@ -598,6 +619,7 @@ void execute(struct CPU* cpu)
case ORA: case ORA:
{ {
fetch(cpu);
cpu->acc |= cpu->fetchedVal; cpu->acc |= cpu->fetchedVal;
cpu->status.negative = (cpu->acc >> 7); cpu->status.negative = (cpu->acc >> 7);
@ -630,6 +652,7 @@ void execute(struct CPU* cpu)
case RLA: case RLA:
{ {
fetch(cpu);
Byte oldCarry = cpu->status.carry; Byte oldCarry = cpu->status.carry;
cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80);
@ -647,6 +670,7 @@ void execute(struct CPU* cpu)
case ROL: case ROL:
{ {
fetch(cpu);
Byte oldCarry = cpu->status.carry; Byte oldCarry = cpu->status.carry;
cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80);
@ -664,6 +688,7 @@ void execute(struct CPU* cpu)
case ROR: case ROR:
{ {
fetch(cpu);
Byte oldCarry = cpu->status.carry; Byte oldCarry = cpu->status.carry;
cpu->status.negative = oldCarry; cpu->status.negative = oldCarry;
cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01); cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01);
@ -681,6 +706,7 @@ void execute(struct CPU* cpu)
case RRA: case RRA:
{ {
fetch(cpu);
Byte oldCarry = cpu->status.carry; Byte oldCarry = cpu->status.carry;
cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01); cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01);
@ -722,6 +748,7 @@ void execute(struct CPU* cpu)
case SBC: case SBC:
{ {
fetch(cpu);
Word result = cpu->acc + ~cpu->fetchedVal + cpu->status.carry; Word result = cpu->acc + ~cpu->fetchedVal + cpu->status.carry;
cpu->status.carry = ((result & 0x8000) != 0x8000); cpu->status.carry = ((result & 0x8000) != 0x8000);
@ -749,6 +776,7 @@ void execute(struct CPU* cpu)
case SLO: case SLO:
{ {
fetch(cpu);
cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80); cpu->status.carry = ((cpu->fetchedVal & 0x80) == 0x80);
cpu->fetchedVal <<= 1; cpu->fetchedVal <<= 1;
@ -764,6 +792,7 @@ void execute(struct CPU* cpu)
case SRE: case SRE:
{ {
fetch(cpu);
cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01); cpu->status.carry = ((cpu->fetchedVal & 0x01) == 0x01);
cpu->fetchedVal >>= 1; cpu->fetchedVal >>= 1;

View file

@ -94,6 +94,7 @@ void destroyCPU(struct CPU* cpu);
int tickCPU(struct CPU* cpu); int tickCPU(struct CPU* cpu);
void tickInstr(struct CPU* cpu); void tickInstr(struct CPU* cpu);
void prepareFetch(struct CPU* cpu);
void fetch(struct CPU* cpu); void fetch(struct CPU* cpu);
void execute(struct CPU* cpu); void execute(struct CPU* cpu);

View file

@ -16,7 +16,7 @@ void logBusState(struct Bus* bus)
Word instructionBytes[3]; Word instructionBytes[3];
for (int i = 0; i < bus->cpu->currentOpcode->length; i++) for (int i = 0; i < bus->cpu->currentOpcode->length; i++)
{ {
instructionBytes[i] = readBus(bus, oldPC + i); instructionBytes[i] = readBus(bus, oldPC + i, 0);
sprintf(buffer + 3 * i, "%02X ", instructionBytes[i]); sprintf(buffer + 3 * i, "%02X ", instructionBytes[i]);
} }

View file

@ -151,7 +151,7 @@ Byte ppuRead(struct PPU* ppu, Word addr)
fprintf(stderr, "PPU access violation at $%04X", ppu->ppuAddress.raw); fprintf(stderr, "PPU access violation at $%04X", ppu->ppuAddress.raw);
exit(1); exit(1);
} }
ppu->ppuAddress.raw += ppu->ppuCtrl.increment; ppu->ppuAddress.raw += 1 + 31 * (ppu->ppuCtrl.increment == 1);
} }
break; break;
@ -213,7 +213,7 @@ void ppuWrite(struct PPU* ppu, Word addr, Byte val)
fprintf(stderr, "PPU access violation at $%04X", ppu->ppuAddress.raw); fprintf(stderr, "PPU access violation at $%04X", ppu->ppuAddress.raw);
exit(1); exit(1);
} }
ppu->ppuAddress.raw += (ppu->ppuCtrl.increment == 0 ? 1 : 32); ppu->ppuAddress.raw += 1 + 31 * (ppu->ppuCtrl.increment == 1);
break; break;
} }