Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic instructions #42

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
565f587
Migrate NOP and LD r,r (#40)
kremi151 Nov 16, 2020
92fdb7a
LD (a16),A (#40)
kremi151 Nov 18, 2020
b933820
Add default case (#40)
kremi151 Nov 18, 2020
c72cb9a
LD A,(a16) (#40)
kremi151 Nov 18, 2020
5453258
LD A,(a16) (#40)
kremi151 Nov 18, 2020
5adb259
LD (C),A and LD A,(C) (#40)
kremi151 Nov 18, 2020
f9bdc51
LD A,d8 (#40)
kremi151 Nov 18, 2020
6226821
LD (ss),d16 (#40)
kremi151 Nov 18, 2020
009a4e1
LD SP,d16, LD (a16),SP, LD r,d8 (#40)
kremi151 Nov 18, 2020
a89bdc6
LD (HL),d8, LD (ss),A, LD A,(ss) (#40)
kremi151 Nov 18, 2020
06efbaf
LD (HLI/D),A, LD A,(HLI/D) (#40)
kremi151 Nov 18, 2020
8f16a0b
Migrate remaining load instructions (#40)
kremi151 Nov 30, 2020
1a5920a
Remove unused source files (#40)
kremi151 Nov 30, 2020
c5ecd1b
Migrate ADD and ADC instructions (#40)
kremi151 Dec 1, 2020
0d964be
Migrate SUB and SBC instructions (#40)
kremi151 Dec 3, 2020
872be65
Migrate JP instructions (#40)
kremi151 Dec 3, 2020
df590ed
Migrate JR instructions (#40)
kremi151 Dec 4, 2020
b1f0974
Improve JP and JR logginh (#40)
kremi151 Dec 4, 2020
58810bb
Refactor method names of JR instructions (#40)
kremi151 Dec 4, 2020
03f08d4
Fix clock counts of JR instructions (#40)
kremi151 Dec 4, 2020
af0083b
Migrate CALL instructions (#40)
kremi151 Dec 4, 2020
b600598
Migrate RET and RETI instructions (#40)
kremi151 Dec 4, 2020
2946d27
Migrate RST instructions (#40)
kremi151 Dec 4, 2020
b5ded40
Migrate CP intstructions (#40)
kremi151 Dec 4, 2020
ab8cdc7
Migrate INC instructions (#40)
kremi151 Dec 5, 2020
0aad607
Migrate DEC instructions (#40)
kremi151 Dec 5, 2020
7994cff
Migrate OR instructions (#40)
kremi151 Dec 5, 2020
95a474c
Migrate AND instructions (#40)
kremi151 Dec 5, 2020
8b6f7ff
Migrate XOR instructions (#40)
kremi151 Dec 5, 2020
052ddee
Migrate rotation and shift instructions (#40)
kremi151 Dec 5, 2020
68c761a
Migrate PUSH and POP instructions (#40)
kremi151 Dec 5, 2020
956c30d
Migrate DAA instruction (#40)
kremi151 Dec 5, 2020
d987911
Apply 8 bit masks when setting Zero flags (#40)
kremi151 Dec 5, 2020
fbaf854
Migrate CPL, SCF and CCF instructions (#40)
kremi151 Dec 5, 2020
6079e97
Migrate EI and DI instructions (#40)
kremi151 Dec 5, 2020
f995293
Migrate STOP and HALT instructions (#40)
kremi151 Dec 5, 2020
9200263
Skeleton for prefix migrations (#40)
kremi151 Dec 5, 2020
c298615
Migrate RLC prefix instructions (#40)
kremi151 Dec 5, 2020
1a14792
Migrate RLC (HL) prefix instruction (#40)
kremi151 Dec 5, 2020
d8e5c74
Migrate RRC prefix instructions (#40)
kremi151 Dec 5, 2020
1a8743d
Migrate RL and RR prefix instructions (#40)
kremi151 Dec 5, 2020
f6ec634
Migrate SLA and SRA prefix instructions (#40)
kremi151 Dec 5, 2020
34536b1
Revise bit shifts (#40)
kremi151 Dec 5, 2020
ffd3a38
Migrate SWAP prefix instructions (#40)
kremi151 Dec 6, 2020
7d5f629
Migrate SRL prefix instructions (#40)
kremi151 Dec 6, 2020
c5558f8
Migrate BIT prefix instructions (#40)
kremi151 Dec 6, 2020
0892caf
Migrate RES prefix instructions (#40)
kremi151 Dec 6, 2020
14f7ca5
Migrate SET prefix instructions (#40)
kremi151 Dec 6, 2020
c545ddc
Cleanup old code (#40)
kremi151 Dec 6, 2020
3d9e1fb
Fix broken context types (#40)
kremi151 Dec 6, 2020
3d64768
Fix deprecation in ALU (#40)
kremi151 Dec 6, 2020
757f0be
Remove erroneous import (#40)
kremi151 Dec 6, 2020
9dec553
[WIP] Duct tape CPU implementation to use atomic instruction executio…
kremi151 Dec 6, 2020
c11454c
Fix unit tests compilation (#40)
kremi151 Dec 6, 2020
410b3ab
Fix register types (#40)
kremi151 Dec 6, 2020
d58af39
Fix deprecated use of addToSP (#40)
kremi151 Dec 6, 2020
f1f59e7
Fix DAA (#40)
kremi151 Dec 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 21 additions & 25 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,16 @@ set(SOURCES
source/cartridge/mbc2.cpp
source/cartridge/mbc_none.cpp
source/memory/ppu_memory.cpp
source/operands/instruction_context.cpp
source/operands/alu.cpp
source/operands/loads.cpp
source/operands/misc.cpp
source/operands/prefix.cpp
source/operands/reads.cpp
source/operands/writes.cpp
source/operands/jumps.cpp
source/operands/rot_shifts.cpp
source/operands/conditions.cpp
source/operands/debug.cpp
source/operands/decoder.cpp
source/instructions/debug.cpp
source/instructions/instructions.cpp
source/instructions/context.cpp
source/instructions/loads.cpp
source/instructions/alu.cpp
source/instructions/jumps.cpp
source/instructions/rot_shifts.cpp
source/instructions/stack.cpp
source/instructions/misc.cpp
source/instructions/prefix.cpp
source/util/registers.cpp
source/util/flags.cpp
source/exception/state_exception.cpp
Expand All @@ -49,6 +47,7 @@ set(HEADERS
source/emulator/io_registers.h
source/emulator/cpu.h
source/emulator/ppu.h
source/emulator/state_types.h
source/controllers/controllers.h
source/controllers/serial.h
source/controllers/serial_null.h
Expand All @@ -70,19 +69,16 @@ set(HEADERS
source/cartridge/mbc2.h
source/cartridge/mbc_none.h
source/memory/ppu_memory.h
source/operands/instruction_context.h
source/operands/alu.h
source/operands/loads.h
source/operands/instructions.h
source/operands/misc.h
source/operands/prefix.h
source/operands/reads.h
source/operands/writes.h
source/operands/jumps.h
source/operands/rot_shifts.h
source/operands/conditions.h
source/operands/debug.h
source/operands/decoder.h
source/instructions/debug.h
source/instructions/instructions.h
source/instructions/context.h
source/instructions/loads.h
source/instructions/alu.h
source/instructions/jumps.h
source/instructions/rot_shifts.h
source/instructions/stack.h
source/instructions/misc.h
source/instructions/prefix.h
source/util/endianness.h
source/util/registers.h
source/util/flags.h
Expand Down
59 changes: 21 additions & 38 deletions core/source/emulator/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <util/registers.h>
#include <util/return_codes.h>
#include <emulator/io_registers.h>
#include <instructions/instructions.h>

using namespace FunkyBoy;

Expand All @@ -31,7 +32,7 @@ CPU::CPU(GameBoyType gbType, MemoryPtr memory, const io_registers& ioRegisters)
, instrContext(gbType)
, timerOverflowingCycles(-1)
, delayedTIMAIncrease(false)
, operandIndex(0)
, currentOpcode(0)
, joypadWasNotPressed(true)
#ifdef FB_DEBUG_WRITE_EXECUTION_LOG
, file("exec_opcodes_fb_v2.txt")
Expand Down Expand Up @@ -61,7 +62,6 @@ CPU::CPU(GameBoyType gbType, MemoryPtr memory, const io_registers& ioRegisters)
instrContext.regA = regA;
instrContext.progCounter = 0;
instrContext.stackPointer = 0xFFFE;
instrContext.operands = operands;
instrContext.interruptMasterEnable = IMEState::DISABLED;
instrContext.haltBugRequested = false;
instrContext.cpuState = CPUState::RUNNING;
Expand All @@ -70,11 +70,6 @@ CPU::CPU(GameBoyType gbType, MemoryPtr memory, const io_registers& ioRegisters)
instrContext.executionLog = &file;
#endif

// Fetch/Execute overlapping -> initial fetch is performed without executing any other instruction
// To simulate this, we set a NOP as the first instruction, which does nothing
operands[0] = Operands::nop;
operands[1] = nullptr;

// Initialize registers
powerUpInit();
}
Expand Down Expand Up @@ -182,16 +177,15 @@ ret_code CPU::doCycle() {
if (instrContext.cpuState == CPUState::RUNNING) {
memory->doDMA(); // TODO: Implement delay of 2 clocks

auto op = operands[operandIndex++];

if (operands[operandIndex] == nullptr) {
shouldFetch = true;
result |= FB_RET_INSTRUCTION_DONE;
int clocks = Instructions::execute(currentOpcode, instrContext, *memory);
if (clocks <= 0) {
fprintf(stderr, "Illegal instruction 0x%02X at 0x%04X\n", currentOpcode, instrContext.progCounter - 1);
return 0;
}

if (!op(instrContext, *memory)) {
shouldFetch = true;
}
shouldFetch = true;
result |= FB_RET_INSTRUCTION_DONE;

shouldDoInterrupts = shouldFetch;
}

Expand All @@ -208,32 +202,21 @@ ret_code CPU::doCycle() {
}

if (interruptServiced || (shouldFetch && instrContext.cpuState == CPUState::RUNNING)) { // TODO: Can this be simplified to just instrContext.cpuState == CPUState::RUNNING ?
result |= doFetchAndDecode();
operandIndex = 0;
return result;
}

return result;
}

ret_code CPU::doFetchAndDecode() {
if (!instrContext.haltBugRequested) {
instrContext.instr = memory->read8BitsAt(instrContext.progCounter++);
} else {
instrContext.instr = memory->read8BitsAt(instrContext.progCounter);
instrContext.haltBugRequested = false;
}

// Fetch next opcode
if (!instrContext.haltBugRequested) {
currentOpcode = memory->read8BitsAt(instrContext.progCounter++);
} else {
currentOpcode = memory->read8BitsAt(instrContext.progCounter);
instrContext.haltBugRequested = false;
}
#ifdef FB_DEBUG_WRITE_EXECUTION_LOG
FunkyBoy::Debug::writeExecutionToLog('I', file, instrContext);
instr++;
FunkyBoy::Debug::writeExecutionToLog('I', file, instrContext);
instr++;
#endif

if (!Operands::decodeOpcode(instrContext.instr, operands)) {
fprintf(stderr, "Illegal instruction 0x%02X at 0x%04X\n", instrContext.instr, instrContext.progCounter - 1);
return 0;
return result | FB_RET_SUCCESS;
}
return FB_RET_SUCCESS;

return result;
}

inline memory_address getInterruptStartAddress(InterruptType type) {
Expand Down
29 changes: 13 additions & 16 deletions core/source/emulator/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include <memory>
#include <util/testing.h>
#include <util/debug.h>
#include <operands/decoder.h>
#include <operands/debug.h>
#include <instructions/instructions.h>
#include <instructions/debug.h>
#include <emulator/gb_type.h>
#include <emulator/io_registers.h>

Expand Down Expand Up @@ -53,10 +53,7 @@ namespace FunkyBoy {
std::ofstream file;
#endif

u8 registers[8]{};

u8 operandIndex;
Operand operands[25]{};
register_t registers[8]{};

i8 timerOverflowingCycles;
bool delayedTIMAIncrease;
Expand All @@ -66,15 +63,15 @@ namespace FunkyBoy {
void powerUpInit();

ret_code doCycle();
ret_code doFetchAndDecode();

void doJoypad();
bool doInterrupts();
void doTimers(u8 clocks);

test_public:

InstrContext instrContext;
Instructions::context instrContext;
opcode_t currentOpcode;

u16 readAF();
void writeAF(u16 val);
Expand All @@ -85,14 +82,14 @@ namespace FunkyBoy {

// Do not free these pointers, they are proxies to specific locations in the registers array

u8 *regB;
u8 *regC;
u8 *regD;
u8 *regE;
u8 *regH;
u8 *regL;
u8 *regF_do_not_use_directly;
u8 *regA;
register_t *regB;
register_t *regC;
register_t *regD;
register_t *regE;
register_t *regH;
register_t *regL;
register_t *regF_do_not_use_directly;
register_t *regA;

public:
CPU(GameBoyType gbType, MemoryPtr memory, const io_registers& ioRegisters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,24 @@
* limitations under the License.
*/

#ifndef FB_CORE_OPERANDS_H
#define FB_CORE_OPERANDS_H
#ifndef FB_CORE_EMULATOR_STATE_TYPES_H
#define FB_CORE_EMULATOR_STATE_TYPES_H

#include <operands/instruction_context.h>
#include <operands/misc.h>
#include <operands/prefix.h>
#include <operands/alu.h>
#include <operands/loads.h>
#include <operands/reads.h>
#include <operands/writes.h>
#include <operands/jumps.h>
#include <operands/rot_shifts.h>
#include <operands/conditions.h>
namespace FunkyBoy {

#endif //FB_CORE_OPERANDS_H
enum IMEState {
DISABLED = 0,
REQUEST_ENABLE = 1,
ENABLING = 2,
ENABLED = 3
};

enum CPUState {
RUNNING = 0,
HALTED = 1,
STOPPED = 2
};

}

#endif //FB_CORE_EMULATOR_STATE_TYPES_H
Loading