started opcodes
This commit is contained in:
parent
4b22287ad0
commit
458500bd59
|
@ -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")
|
add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c" "opcodes.c")
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_definitions(nesemu PUBLIC _CRT_SECURE_NO_WARNINGS)
|
target_compile_definitions(nesemu PUBLIC _CRT_SECURE_NO_WARNINGS)
|
||||||
|
|
|
@ -53,7 +53,7 @@ Byte readBus(struct Bus* bus, Word addr)
|
||||||
}
|
}
|
||||||
else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space
|
else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space
|
||||||
{
|
{
|
||||||
// rom->read()
|
val = readCartridge(bus->cartridge, addr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,7 @@ void writeBus(struct Bus* bus, Word addr, Byte val)
|
||||||
}
|
}
|
||||||
else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space
|
else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space
|
||||||
{
|
{
|
||||||
// rom->write()
|
writeCartridge(bus->cartridge, addr, val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -81,3 +81,9 @@ void writeBus(struct Bus* bus, Word addr, Byte val)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tick(struct Bus* bus)
|
||||||
|
{
|
||||||
|
tickInstr(bus->cpu);
|
||||||
|
}
|
|
@ -25,4 +25,8 @@ void destroyBus(struct Bus* bus);
|
||||||
Byte readBus(struct Bus* bus, Word addr);
|
Byte readBus(struct Bus* bus, Word addr);
|
||||||
void writeBus(struct Bus* bus, Word addr, Byte val);
|
void writeBus(struct Bus* bus, Word addr, Byte val);
|
||||||
|
|
||||||
|
|
||||||
|
// Ticks the master clock 12 times (i.e. 1 CPU tick & 3 PPU dots)
|
||||||
|
void tick(struct Bus* bus);
|
||||||
|
|
||||||
#endif // _BUS_H_
|
#endif // _BUS_H_
|
|
@ -40,10 +40,8 @@ struct Cartridge* createCartridge(struct Bus* parent, const char* filepath)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open ROM
|
|
||||||
FILE* fp = fopen(filepath, "rb");
|
FILE* fp = fopen(filepath, "rb");
|
||||||
|
|
||||||
// readCartridge header
|
|
||||||
struct INES_Header header;
|
struct INES_Header header;
|
||||||
fread(&header, sizeof(header), 1, fp);
|
fread(&header, sizeof(header), 1, fp);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ struct CPU* createCPU(struct Bus* parent)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: THIS IS JUST FOR THE TEST ROM
|
||||||
|
cpu->pc = 0xC000;
|
||||||
|
|
||||||
cpu->bus = parent;
|
cpu->bus = parent;
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
@ -21,3 +24,39 @@ void destroyCPU(struct CPU* cpu)
|
||||||
{
|
{
|
||||||
free(cpu);
|
free(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tickCPU(struct CPU* cpu)
|
||||||
|
{
|
||||||
|
if (cpu->fetchedVal != 0)
|
||||||
|
{
|
||||||
|
cpu->fetchedVal--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(cpu);
|
||||||
|
execute(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tickInstr(struct CPU* cpu)
|
||||||
|
{
|
||||||
|
while (cpu->remainingCycles > 1)
|
||||||
|
tickCPU(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetch(struct CPU* cpu)
|
||||||
|
{
|
||||||
|
Byte opcodeVal = readBus(cpu->bus, cpu->pc);
|
||||||
|
cpu->currentOpcode = OPCODE_TABLE + opcodeVal;
|
||||||
|
|
||||||
|
if (cpu->currentOpcode->op == Unknown)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unknown opcode: %x", opcodeVal);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute(struct CPU* cpu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,35 @@
|
||||||
|
|
||||||
struct Bus;
|
struct Bus;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XXX = 0,
|
||||||
|
ADC, AND, ASL, BCC, BCS, BEQ, BIT, BMI,
|
||||||
|
BNE, BPL, BRK, BVC, BVS, CLC, CLD, CLI,
|
||||||
|
CLV, CMP, CPX, CPY, DEC, DEX, DEY, EOR,
|
||||||
|
INC, INX, INY, JMP, JSR, LDA, LDX, LDY,
|
||||||
|
LSR, NOP, ORA, PHA, PHP, PLA, PLP, ROL,
|
||||||
|
ROR, RTI, RTS, SBC, SEC, SED, SEI, STA,
|
||||||
|
STX, STY, TAX, TAY, TSX, TXA, TXS, TYA
|
||||||
|
} Operation;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ACC, ABS, ABX, ABY, IMM, IMP, IND, XIN, INY, REL, ZPG, ZPX, ZPY
|
||||||
|
} AddrMode;
|
||||||
|
|
||||||
|
struct Opcode
|
||||||
|
{
|
||||||
|
Operation op;
|
||||||
|
AddrMode addr;
|
||||||
|
Byte cycles;
|
||||||
|
|
||||||
|
const char str[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct Opcode OPCODE_MATRIX[512];
|
||||||
|
|
||||||
|
|
||||||
struct CPU
|
struct CPU
|
||||||
{
|
{
|
||||||
Byte acc;
|
Byte acc;
|
||||||
|
@ -29,10 +58,21 @@ struct CPU
|
||||||
|
|
||||||
Word pc;
|
Word pc;
|
||||||
|
|
||||||
|
Byte remainingCycles;
|
||||||
|
Byte fetchedVal;
|
||||||
|
Word fetchedAddress;
|
||||||
|
const struct Opcode* currentOpcode;
|
||||||
|
|
||||||
struct Bus* bus;
|
struct Bus* bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPU* createCPU(struct Bus* parent);
|
struct CPU* createCPU(struct Bus* parent);
|
||||||
void destroyCPU(struct CPU* cpu);
|
void destroyCPU(struct CPU* cpu);
|
||||||
|
|
||||||
|
void tickCPU(struct CPU* cpu);
|
||||||
|
void tickInstr(struct CPU* cpu);
|
||||||
|
|
||||||
|
void fetch(struct CPU* cpu);
|
||||||
|
void execute(struct CPU* cpu);
|
||||||
|
|
||||||
#endif // _CPU_H_
|
#endif // _CPU_H_
|
|
@ -3,6 +3,12 @@
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
struct Bus* bus = createBus();
|
struct Bus* bus = createBus();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
tick(bus);
|
||||||
|
}
|
||||||
|
|
||||||
destroyBus(bus);
|
destroyBus(bus);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
142
NES Emulator/opcodes.c
Normal file
142
NES Emulator/opcodes.c
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
#define NEW_OPCODE(op, addr, cyc) {op, addr, cyc, #op}
|
||||||
|
|
||||||
|
const struct Opcode OPCODE_TABLE[256] =
|
||||||
|
{
|
||||||
|
/* 00 */ NEW_OPCODE(BRK, IMP, 7),
|
||||||
|
/* 01 */ NEW_OPCODE(ORA, XIN, 6),
|
||||||
|
/* 02 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 03 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 04 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 05 */ NEW_OPCODE(ORA, ZPG, 3),
|
||||||
|
/* 06 */ NEW_OPCODE(ASL, ZPG, 5),
|
||||||
|
/* 07 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 08 */ NEW_OPCODE(PHP, IMP, 3),
|
||||||
|
/* 09 */ NEW_OPCODE(ORA, IMM, 2),
|
||||||
|
/* 0A */ NEW_OPCODE(ASL, ACC, 2),
|
||||||
|
/* 0B */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 0C */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 0D */ NEW_OPCODE(ORA, ABS, 4),
|
||||||
|
/* 0E */ NEW_OPCODE(ASL, ABS, 6),
|
||||||
|
/* 0F */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
|
||||||
|
/* 10 */ NEW_OPCODE(BPL, REL, 2),
|
||||||
|
/* 11 */ NEW_OPCODE(ORA, INY, 5),
|
||||||
|
/* 12 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 13 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 14 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 15 */ NEW_OPCODE(ORA, ZPX, 4),
|
||||||
|
/* 16 */ NEW_OPCODE(ASL, ZPX, 6),
|
||||||
|
/* 17 */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 18 */ NEW_OPCODE(CLC, IMP, 2),
|
||||||
|
/* 19 */ NEW_OPCODE(ORA, ABY, 4),
|
||||||
|
/* 1A */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 1B */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 1C */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
/* 1D */ NEW_OPCODE(ORA, ABX, 4),
|
||||||
|
/* 1E */ NEW_OPCODE(ASL, ABX, 7),
|
||||||
|
/* 1F */ NEW_OPCODE(XXX, IMP, 0),
|
||||||
|
|
||||||
|
///* 20 */ NEW_OPCODE(JSR, ABS),
|
||||||
|
///* 21 */ NEW_OPCODE(AND, XIN),
|
||||||
|
///* 22 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 23 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 24 */ NEW_OPCODE(BIT, ZPG),
|
||||||
|
///* 25 */ NEW_OPCODE(AND, ZPG),
|
||||||
|
///* 26 */ NEW_OPCODE(ROL, ZPG),
|
||||||
|
///* 27 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 28 */ NEW_OPCODE(PLP, IMP),
|
||||||
|
///* 29 */ NEW_OPCODE(AND, IMM),
|
||||||
|
///* 2A */ NEW_OPCODE(ROL, ACC),
|
||||||
|
///* 2B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 2C */ NEW_OPCODE(BIT, ABS),
|
||||||
|
///* 2D */ NEW_OPCODE(AND, ABS),
|
||||||
|
///* 2E */ NEW_OPCODE(ROL, ABS),
|
||||||
|
///* 2F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
|
||||||
|
///* 30 */ NEW_OPCODE(BMI, REL),
|
||||||
|
///* 31 */ NEW_OPCODE(AND, INY),
|
||||||
|
///* 32 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 33 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 34 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 35 */ NEW_OPCODE(AND, ZPX),
|
||||||
|
///* 36 */ NEW_OPCODE(ROL, ZPX),
|
||||||
|
///* 37 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 38 */ NEW_OPCODE(SEC, IMP),
|
||||||
|
///* 39 */ NEW_OPCODE(AND, ABY),
|
||||||
|
///* 3A */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 3B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 3C */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 3D */ NEW_OPCODE(AND, ABX),
|
||||||
|
///* 3E */ NEW_OPCODE(ROL, ABX),
|
||||||
|
///* 3F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
|
||||||
|
///* 40 */ NEW_OPCODE(RTI, IMP),
|
||||||
|
///* 41 */ NEW_OPCODE(EOR, XIN),
|
||||||
|
///* 42 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 43 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 44 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 45 */ NEW_OPCODE(EOR, ZPG),
|
||||||
|
///* 46 */ NEW_OPCODE(LSR, ZPG),
|
||||||
|
///* 47 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 48 */ NEW_OPCODE(PHA, IMP),
|
||||||
|
///* 49 */ NEW_OPCODE(EOR, IMM),
|
||||||
|
///* 4A */ NEW_OPCODE(LSR, ACC),
|
||||||
|
///* 4B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 4C */ NEW_OPCODE(JMP, ABS),
|
||||||
|
///* 4D */ NEW_OPCODE(EOR, ABS),
|
||||||
|
///* 4E */ NEW_OPCODE(LSR, ABS),
|
||||||
|
///* 4F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
|
||||||
|
///* 50 */ NEW_OPCODE(BVC, REL),
|
||||||
|
///* 51 */ NEW_OPCODE(EOR, INY),
|
||||||
|
///* 52 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 53 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 54 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 55 */ NEW_OPCODE(EOR, ZPX),
|
||||||
|
///* 56 */ NEW_OPCODE(LSR, ZPX),
|
||||||
|
///* 57 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 58 */ NEW_OPCODE(CLI, IMP),
|
||||||
|
///* 59 */ NEW_OPCODE(EOR, ABY),
|
||||||
|
///* 5A */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 5B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 5C */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 5D */ NEW_OPCODE(EOR, ABX),
|
||||||
|
///* 5E */ NEW_OPCODE(LSR, ABX),
|
||||||
|
///* 5F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
|
||||||
|
///* 60 */ NEW_OPCODE(RTS, IMP),
|
||||||
|
///* 61 */ NEW_OPCODE(ADC, XIN),
|
||||||
|
///* 62 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 63 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 64 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 65 */ NEW_OPCODE(ADC, ZPG),
|
||||||
|
///* 66 */ NEW_OPCODE(ROR, ZPG),
|
||||||
|
///* 67 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 68 */ NEW_OPCODE(PLA, IMP),
|
||||||
|
///* 69 */ NEW_OPCODE(ADC, IMM),
|
||||||
|
///* 6A */ NEW_OPCODE(ROR, ACC),
|
||||||
|
///* 6B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 6C */ NEW_OPCODE(JMP, IND),
|
||||||
|
///* 6D */ NEW_OPCODE(ADC, ABS),
|
||||||
|
///* 6E */ NEW_OPCODE(ROR, ABS),
|
||||||
|
///* 6F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
|
||||||
|
///* 70 */ NEW_OPCODE(BVS, REL),
|
||||||
|
///* 71 */ NEW_OPCODE(ADC, INY),
|
||||||
|
///* 72 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 73 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 74 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 75 */ NEW_OPCODE(ADC, ZPX),
|
||||||
|
///* 76 */ NEW_OPCODE(ROR, ZPX),
|
||||||
|
///* 77 */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 78 */ NEW_OPCODE(SEI, IMP),
|
||||||
|
///* 79 */ NEW_OPCODE(ADC, ABY),
|
||||||
|
///* 7A */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 7B */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 7C */ NEW_OPCODE(XXX, IMP),
|
||||||
|
///* 7D */ NEW_OPCODE(ADC, ABX),
|
||||||
|
///* 7E */ NEW_OPCODE(ROR, ABX),
|
||||||
|
///* 7F */ NEW_OPCODE(XXX, IMP),
|
||||||
|
}
|
Loading…
Reference in a new issue