started opcodes
This commit is contained in:
parent
4b22287ad0
commit
458500bd59
|
@ -1,6 +1,6 @@
|
|||
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)
|
||||
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
|
||||
{
|
||||
// rom->read()
|
||||
val = readCartridge(bus->cartridge, addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ void writeBus(struct Bus* bus, Word addr, Byte val)
|
|||
}
|
||||
else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space
|
||||
{
|
||||
// rom->write()
|
||||
writeCartridge(bus->cartridge, addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -81,3 +81,9 @@ void writeBus(struct Bus* bus, Word addr, Byte val)
|
|||
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);
|
||||
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_
|
|
@ -40,10 +40,8 @@ struct Cartridge* createCartridge(struct Bus* parent, const char* filepath)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// Open ROM
|
||||
FILE* fp = fopen(filepath, "rb");
|
||||
|
||||
// readCartridge header
|
||||
struct INES_Header header;
|
||||
fread(&header, sizeof(header), 1, fp);
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ struct CPU* createCPU(struct Bus* parent)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// TODO: THIS IS JUST FOR THE TEST ROM
|
||||
cpu->pc = 0xC000;
|
||||
|
||||
cpu->bus = parent;
|
||||
return cpu;
|
||||
}
|
||||
|
@ -21,3 +24,39 @@ void destroyCPU(struct CPU* 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;
|
||||
|
||||
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
|
||||
{
|
||||
Byte acc;
|
||||
|
@ -29,10 +58,21 @@ struct CPU
|
|||
|
||||
Word pc;
|
||||
|
||||
Byte remainingCycles;
|
||||
Byte fetchedVal;
|
||||
Word fetchedAddress;
|
||||
const struct Opcode* currentOpcode;
|
||||
|
||||
struct Bus* bus;
|
||||
};
|
||||
|
||||
struct CPU* createCPU(struct Bus* parent);
|
||||
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_
|
|
@ -3,6 +3,12 @@
|
|||
int main()
|
||||
{
|
||||
struct Bus* bus = createBus();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
tick(bus);
|
||||
}
|
||||
|
||||
destroyBus(bus);
|
||||
|
||||
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