SM83: Rename LR35902 to SM83

This commit is contained in:
Vicki Pfau 2020-01-01 11:35:00 -08:00
parent b6f863be26
commit 51a122f20d
40 changed files with 2475 additions and 2474 deletions

View File

@ -64,7 +64,6 @@ Misc:
- GBA Savedata: EEPROM performance fixes
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
- Debugger: Add breakpoint and watchpoint listing
- LR35902: Support PC-relative opcode decoding
- mGUI: Remember name and position of last loaded game
- OpenGL: Only resize textures when needed
- Qt: Don't unload ROM immediately if it crashes
@ -82,6 +81,7 @@ Misc:
- Qt: Show list of all sprites in sprite view
- Qt: Add option for disabling OSD messages
- Qt, OpenGL: Disable integer scaling for dimensions that don't fit
- SM83: Support PC-relative opcode decoding
- Switch: Dynamic display resizing
- Switch: Support file associations
- Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292)
@ -114,6 +114,7 @@ Misc:
- Debugger: Separate aliases from main commands
- Debugger: Print break-/watchpoint ID when breaking in CLI
- SDL: Use controller GUID instead of name
- SM83: Rename LR35902 to SM83
0.8 beta 1: (2019-10-20)
- Initial beta for 0.8

View File

@ -726,7 +726,7 @@ add_subdirectory(src/arm)
add_subdirectory(src/core)
add_subdirectory(src/gb)
add_subdirectory(src/gba)
add_subdirectory(src/lr35902)
add_subdirectory(src/sm83)
add_subdirectory(src/util)
list(APPEND GUI_SRC ${EXTRA_GUI_SRC})
@ -735,9 +735,9 @@ list(APPEND UTIL_SRC ${CMAKE_CURRENT_BINARY_DIR}/version.c)
set(TEST_SRC ${CORE_TEST_SRC})
if(M_CORE_GB)
add_definitions(-DM_CORE_GB)
list(APPEND CORE_SRC ${LR35902_SRC} ${GB_SRC})
list(APPEND DEBUGGER_SRC ${LR35902_DEBUGGER_SRC} ${GB_DEBUGGER_SRC})
list(APPEND TEST_SRC ${LR35902_TEST_SRC} ${GB_TEST_SRC})
list(APPEND CORE_SRC ${SM83_SRC} ${GB_SRC})
list(APPEND DEBUGGER_SRC ${SM83_DEBUGGER_SRC} ${GB_DEBUGGER_SRC})
list(APPEND TEST_SRC ${SM83_TEST_SRC} ${GB_TEST_SRC})
endif()
if(M_CORE_GBA)

View File

@ -21,9 +21,9 @@ CXX_GUARD_START
#include <mgba/internal/gb/timer.h>
#include <mgba/internal/gb/video.h>
extern const uint32_t DMG_LR35902_FREQUENCY;
extern const uint32_t CGB_LR35902_FREQUENCY;
extern const uint32_t SGB_LR35902_FREQUENCY;
extern const uint32_t DMG_SM83_FREQUENCY;
extern const uint32_t CGB_SM83_FREQUENCY;
extern const uint32_t SGB_SM83_FREQUENCY;
mLOG_DECLARE_CATEGORY(GB);
@ -72,13 +72,13 @@ enum GBSGBCommand {
SGB_OBJ_TRN
};
struct LR35902Core;
struct SM83Core;
struct mCoreSync;
struct mAVStream;
struct GB {
struct mCPUComponent d;
struct LR35902Core* cpu;
struct SM83Core* cpu;
struct GBMemory memory;
struct GBVideo video;
struct GBTimer timer;
@ -150,14 +150,14 @@ struct GBCartridge {
void GBCreate(struct GB* gb);
void GBDestroy(struct GB* gb);
void GBReset(struct LR35902Core* cpu);
void GBReset(struct SM83Core* cpu);
void GBSkipBIOS(struct GB* gb);
void GBMapBIOS(struct GB* gb);
void GBUnmapBIOS(struct GB* gb);
void GBDetectModel(struct GB* gb);
void GBUpdateIRQs(struct GB* gb);
void GBHalt(struct LR35902Core* cpu);
void GBHalt(struct SM83Core* cpu);
struct VFile;
bool GBLoadROM(struct GB* gb, struct VFile* vf);

View File

@ -204,24 +204,24 @@ struct GBMemory {
struct mImageSource* cam;
};
struct LR35902Core;
struct SM83Core;
void GBMemoryInit(struct GB* gb);
void GBMemoryDeinit(struct GB* gb);
void GBMemoryReset(struct GB* gb);
void GBMemorySwitchWramBank(struct GBMemory* memory, int bank);
uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address);
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value);
uint8_t GBLoad8(struct SM83Core* cpu, uint16_t address);
void GBStore8(struct SM83Core* cpu, uint16_t address, int8_t value);
int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address);
int GBCurrentSegment(struct SM83Core* cpu, uint16_t address);
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
uint8_t GBView8(struct SM83Core* cpu, uint16_t address, int segment);
void GBMemoryDMA(struct GB* gb, uint16_t base);
uint8_t GBMemoryWriteHDMA5(struct GB* gb, uint8_t value);
void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment);
void GBPatch8(struct SM83Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment);
struct GBSerializedState;
void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state);

View File

@ -1,112 +0,0 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef LR35902_DECODER_H
#define LR35902_DECODER_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum LR35902Condition {
LR35902_COND_NONE = 0x0,
LR35902_COND_C = 0x1,
LR35902_COND_Z = 0x2,
LR35902_COND_NC = 0x3,
LR35902_COND_NZ = 0x4
};
enum LR35902Mnemonic {
LR35902_MN_ILL = 0,
LR35902_MN_ADC,
LR35902_MN_ADD,
LR35902_MN_AND,
LR35902_MN_BIT,
LR35902_MN_CALL,
LR35902_MN_CCF,
LR35902_MN_CP,
LR35902_MN_CPL,
LR35902_MN_DAA,
LR35902_MN_DEC,
LR35902_MN_DI,
LR35902_MN_EI,
LR35902_MN_HALT,
LR35902_MN_INC,
LR35902_MN_JP,
LR35902_MN_JR,
LR35902_MN_LD,
LR35902_MN_NOP,
LR35902_MN_OR,
LR35902_MN_POP,
LR35902_MN_PUSH,
LR35902_MN_RES,
LR35902_MN_RET,
LR35902_MN_RETI,
LR35902_MN_RL,
LR35902_MN_RLC,
LR35902_MN_RR,
LR35902_MN_RRC,
LR35902_MN_RST,
LR35902_MN_SBC,
LR35902_MN_SCF,
LR35902_MN_SET,
LR35902_MN_SLA,
LR35902_MN_SRA,
LR35902_MN_SRL,
LR35902_MN_STOP,
LR35902_MN_SUB,
LR35902_MN_SWAP,
LR35902_MN_XOR,
LR35902_MN_MAX
};
enum LR35902Register {
LR35902_REG_B = 1,
LR35902_REG_C,
LR35902_REG_D,
LR35902_REG_E,
LR35902_REG_H,
LR35902_REG_L,
LR35902_REG_A,
LR35902_REG_F,
LR35902_REG_BC,
LR35902_REG_DE,
LR35902_REG_HL,
LR35902_REG_AF,
LR35902_REG_SP,
LR35902_REG_PC
};
enum {
LR35902_OP_FLAG_IMPLICIT = 1,
LR35902_OP_FLAG_MEMORY = 2,
LR35902_OP_FLAG_INCREMENT = 4,
LR35902_OP_FLAG_DECREMENT = 8,
LR35902_OP_FLAG_RELATIVE = 16,
};
struct LR35902Operand {
uint8_t reg;
uint8_t flags;
uint16_t immediate;
};
struct LR35902InstructionInfo {
uint8_t opcode[3];
uint8_t opcodeSize;
struct LR35902Operand op1;
struct LR35902Operand op2;
unsigned mnemonic;
unsigned condition;
};
size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info);
int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen);
CXX_GUARD_END
#endif

View File

@ -1,528 +0,0 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef EMITTER_LR35902_H
#define EMITTER_LR35902_H
#define DECLARE_INSTRUCTION_LR35902(EMITTER, NAME) \
EMITTER ## NAME
#define DECLARE_LR35902_EMITTER_BLOCK(EMITTER) \
DECLARE_INSTRUCTION_LR35902(EMITTER, NOP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDBC_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCA_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDISP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL_BC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_BC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCA_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, STOP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDDE_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLA_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JR), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL_DE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_DE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRA_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JRNZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDIHLA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DAA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JRZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_IHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPL_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JRNC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDSP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDDHLA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCSP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INC_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DEC_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SCF), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JRC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL_SP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_DHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECSP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DECA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CCF), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDB_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDC_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDD_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDE_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDL_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, HALT), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUBA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ANDA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XORA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ORA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CPA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RETNZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, POPBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JPNZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CALLNZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, PUSHBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST00), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RETZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RET), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JPZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CALLZ), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CALL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST08), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RETNC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, POPDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JPNC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CALLNC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, PUSHDE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SUB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST10), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RETC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RETI), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JPC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CALLC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SBC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST18), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDIOA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, POPHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDIOCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, PUSHHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, AND), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST20), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ADDSP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, JPHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDIA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, XOR), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST28), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDAIO), \
DECLARE_INSTRUCTION_LR35902(EMITTER, POPAF), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDAIOC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, DI), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, PUSHAF), \
DECLARE_INSTRUCTION_LR35902(EMITTER, OR), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST30), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDHL_SP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDSP_HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, LDAI), \
DECLARE_INSTRUCTION_LR35902(EMITTER, EI), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, ILL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, CP), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RST38)
#define DECLARE_LR35902_CB_EMITTER_BLOCK(EMITTER) \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRCA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RLA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RRA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SLAA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRAA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SWAPA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLB), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLC), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLD), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLE), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLH), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SRLA), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT0A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT1A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT2A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT3A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT4A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT5A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT6A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, BIT7A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES0A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES1A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES2A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES3A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES4A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES5A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES6A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, RES7A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET0A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET1A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET2A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET3A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET4A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET5A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET6A), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7B), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7C), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7D), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7E), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7H), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7L), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7HL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, SET7A)
#endif

View File

@ -1,146 +0,0 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef LR35902_H
#define LR35902_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/internal/lr35902/isa-lr35902.h>
struct LR35902Core;
#pragma pack(push, 1)
union FlagRegister {
struct {
#if defined(__POWERPC__) || defined(__PPC__)
unsigned z : 1;
unsigned n : 1;
unsigned h : 1;
unsigned c : 1;
unsigned unused : 4;
#else
unsigned unused : 4;
unsigned c : 1;
unsigned h : 1;
unsigned n : 1;
unsigned z : 1;
#endif
};
uint8_t packed;
};
#pragma pack(pop)
enum LR35902ExecutionState {
LR35902_CORE_FETCH = 3,
LR35902_CORE_IDLE_0 = 0,
LR35902_CORE_IDLE_1 = 1,
LR35902_CORE_EXECUTE = 2,
LR35902_CORE_MEMORY_LOAD = 7,
LR35902_CORE_MEMORY_STORE = 11,
LR35902_CORE_READ_PC = 15,
LR35902_CORE_STALL = 19,
LR35902_CORE_OP2 = 23
};
struct LR35902Memory {
uint8_t (*cpuLoad8)(struct LR35902Core*, uint16_t address);
uint8_t (*load8)(struct LR35902Core*, uint16_t address);
void (*store8)(struct LR35902Core*, uint16_t address, int8_t value);
int (*currentSegment)(struct LR35902Core*, uint16_t address);
const uint8_t* activeRegion;
uint16_t activeMask;
uint16_t activeRegionEnd;
void (*setActiveRegion)(struct LR35902Core*, uint16_t address);
};
struct LR35902InterruptHandler {
void (*reset)(struct LR35902Core* cpu);
void (*processEvents)(struct LR35902Core* cpu);
void (*setInterrupts)(struct LR35902Core* cpu, bool enable);
uint16_t (*irqVector)(struct LR35902Core* cpu);
void (*halt)(struct LR35902Core* cpu);
void (*stop)(struct LR35902Core* cpu);
void (*hitIllegal)(struct LR35902Core* cpu);
};
struct LR35902Core {
#pragma pack(push, 1)
union {
struct {
union FlagRegister f;
uint8_t a;
};
uint16_t af;
};
#pragma pack(pop)
union {
struct {
uint8_t c;
uint8_t b;
};
uint16_t bc;
};
union {
struct {
uint8_t e;
uint8_t d;
};
uint16_t de;
};
union {
struct {
uint8_t l;
uint8_t h;
};
uint16_t hl;
};
uint16_t sp;
uint16_t pc;
uint16_t index;
int32_t cycles;
int32_t nextEvent;
enum LR35902ExecutionState executionState;
bool halted;
uint8_t bus;
bool condition;
LR35902Instruction instruction;
bool irqPending;
struct LR35902Memory memory;
struct LR35902InterruptHandler irqh;
struct mCPUComponent* master;
size_t numComponents;
struct mCPUComponent** components;
};
void LR35902Init(struct LR35902Core* cpu);
void LR35902Deinit(struct LR35902Core* cpu);
void LR35902SetComponents(struct LR35902Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
void LR35902HotplugAttach(struct LR35902Core* cpu, size_t slot);
void LR35902HotplugDetach(struct LR35902Core* cpu, size_t slot);
void LR35902Reset(struct LR35902Core* cpu);
void LR35902RaiseIRQ(struct LR35902Core* cpu);
void LR35902Tick(struct LR35902Core* cpu);
void LR35902Run(struct LR35902Core* cpu);
CXX_GUARD_END
#endif

View File

@ -3,15 +3,15 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef LR35902_CLI_DEBUGGER_H
#define LR35902_CLI_DEBUGGER_H
#ifndef SM83_CLI_DEBUGGER_H
#define SM83_CLI_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct CLIDebuggerSystem;
void LR35902CLIDebuggerCreate(struct CLIDebuggerSystem* debugger);
void SM83CLIDebuggerCreate(struct CLIDebuggerSystem* debugger);
CXX_GUARD_END

View File

@ -3,8 +3,8 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef LR35902_DEBUGGER_H
#define LR35902_DEBUGGER_H
#ifndef SM83_DEBUGGER_H
#define SM83_DEBUGGER_H
#include <mgba-util/common.h>
@ -12,31 +12,31 @@ CXX_GUARD_START
#include <mgba/debugger/debugger.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
struct LR35902Segment {
struct SM83Segment {
uint16_t start;
uint16_t end;
const char* name;
};
struct CLIDebuggerSystem;
struct LR35902Debugger {
struct SM83Debugger {
struct mDebuggerPlatform d;
struct LR35902Core* cpu;
struct SM83Core* cpu;
struct mBreakpointList breakpoints;
struct mWatchpointList watchpoints;
struct LR35902Memory originalMemory;
struct SM83Memory originalMemory;
ssize_t nextId;
const struct LR35902Segment* segments;
const struct SM83Segment* segments;
void (*printStatus)(struct CLIDebuggerSystem*);
};
struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void);
struct mDebuggerPlatform* SM83DebuggerPlatformCreate(void);
CXX_GUARD_END

View File

@ -3,17 +3,17 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef LR35902_MEMORY_DEBUGGER_H
#define LR35902_MEMORY_DEBUGGER_H
#ifndef SM83_MEMORY_DEBUGGER_H
#define SM83_MEMORY_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct LR35902Debugger;
struct SM83Debugger;
void LR35902DebuggerInstallMemoryShim(struct LR35902Debugger* debugger);
void LR35902DebuggerRemoveMemoryShim(struct LR35902Debugger* debugger);
void SM83DebuggerInstallMemoryShim(struct SM83Debugger* debugger);
void SM83DebuggerRemoveMemoryShim(struct SM83Debugger* debugger);
CXX_GUARD_END

View File

@ -0,0 +1,112 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SM83_DECODER_H
#define SM83_DECODER_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum SM83Condition {
SM83_COND_NONE = 0x0,
SM83_COND_C = 0x1,
SM83_COND_Z = 0x2,
SM83_COND_NC = 0x3,
SM83_COND_NZ = 0x4
};
enum SM83Mnemonic {
SM83_MN_ILL = 0,
SM83_MN_ADC,
SM83_MN_ADD,
SM83_MN_AND,
SM83_MN_BIT,
SM83_MN_CALL,
SM83_MN_CCF,
SM83_MN_CP,
SM83_MN_CPL,
SM83_MN_DAA,
SM83_MN_DEC,
SM83_MN_DI,
SM83_MN_EI,
SM83_MN_HALT,
SM83_MN_INC,
SM83_MN_JP,
SM83_MN_JR,
SM83_MN_LD,
SM83_MN_NOP,
SM83_MN_OR,
SM83_MN_POP,
SM83_MN_PUSH,
SM83_MN_RES,
SM83_MN_RET,
SM83_MN_RETI,
SM83_MN_RL,
SM83_MN_RLC,
SM83_MN_RR,
SM83_MN_RRC,
SM83_MN_RST,
SM83_MN_SBC,
SM83_MN_SCF,
SM83_MN_SET,
SM83_MN_SLA,
SM83_MN_SRA,
SM83_MN_SRL,
SM83_MN_STOP,
SM83_MN_SUB,
SM83_MN_SWAP,
SM83_MN_XOR,
SM83_MN_MAX
};
enum SM83Register {
SM83_REG_B = 1,
SM83_REG_C,
SM83_REG_D,
SM83_REG_E,
SM83_REG_H,
SM83_REG_L,
SM83_REG_A,
SM83_REG_F,
SM83_REG_BC,
SM83_REG_DE,
SM83_REG_HL,
SM83_REG_AF,
SM83_REG_SP,
SM83_REG_PC
};
enum {
SM83_OP_FLAG_IMPLICIT = 1,
SM83_OP_FLAG_MEMORY = 2,
SM83_OP_FLAG_INCREMENT = 4,
SM83_OP_FLAG_DECREMENT = 8,
SM83_OP_FLAG_RELATIVE = 16,
};
struct SM83Operand {
uint8_t reg;
uint8_t flags;
uint16_t immediate;
};
struct SM83InstructionInfo {
uint8_t opcode[3];
uint8_t opcodeSize;
struct SM83Operand op1;
struct SM83Operand op2;
unsigned mnemonic;
unsigned condition;
};
size_t SM83Decode(uint8_t opcode, struct SM83InstructionInfo* info);
int SM83Disassemble(struct SM83InstructionInfo* info, uint16_t pc, char* buffer, int blen);
CXX_GUARD_END
#endif

View File

@ -0,0 +1,528 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef EMITTER_SM83_H
#define EMITTER_SM83_H
#define DECLARE_INSTRUCTION_SM83(EMITTER, NAME) \
EMITTER ## NAME
#define DECLARE_SM83_EMITTER_BLOCK(EMITTER) \
DECLARE_INSTRUCTION_SM83(EMITTER, NOP), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDBC_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCB), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECB), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCA_), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDISP), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDHL_BC), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_BC), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCC), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECC), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCA_), \
DECLARE_INSTRUCTION_SM83(EMITTER, STOP), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDDE_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCD), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECD), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLA_), \
DECLARE_INSTRUCTION_SM83(EMITTER, JR), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDHL_DE), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_DE), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCE), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECE), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRA_), \
DECLARE_INSTRUCTION_SM83(EMITTER, JRNZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDIHLA), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCH), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECH), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_), \
DECLARE_INSTRUCTION_SM83(EMITTER, DAA), \
DECLARE_INSTRUCTION_SM83(EMITTER, JRZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDHL_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_IHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCL), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPL_), \
DECLARE_INSTRUCTION_SM83(EMITTER, JRNC), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDSP), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDDHLA), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCSP), \
DECLARE_INSTRUCTION_SM83(EMITTER, INC_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, DEC_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_), \
DECLARE_INSTRUCTION_SM83(EMITTER, SCF), \
DECLARE_INSTRUCTION_SM83(EMITTER, JRC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDHL_SP), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_DHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECSP), \
DECLARE_INSTRUCTION_SM83(EMITTER, INCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, DECA), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_), \
DECLARE_INSTRUCTION_SM83(EMITTER, CCF), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDB_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDC_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDD_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDE_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDH_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDL_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, HALT), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_B), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_C), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_D), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_E), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_H), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_L), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDA_A), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDB), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDD), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDH), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDA), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCB), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCD), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCE), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCH), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUBA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDB), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDD), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDH), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ANDA), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORB), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORC), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORD), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORE), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORH), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORL), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, XORA), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORB), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORD), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORE), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORH), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ORA), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPB), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPC), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPD), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPE), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPH), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPL), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, CPA), \
DECLARE_INSTRUCTION_SM83(EMITTER, RETNZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, POPBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, JPNZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, JP), \
DECLARE_INSTRUCTION_SM83(EMITTER, CALLNZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, PUSHBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADD), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST00), \
DECLARE_INSTRUCTION_SM83(EMITTER, RETZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, RET), \
DECLARE_INSTRUCTION_SM83(EMITTER, JPZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, CB), \
DECLARE_INSTRUCTION_SM83(EMITTER, CALLZ), \
DECLARE_INSTRUCTION_SM83(EMITTER, CALL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST08), \
DECLARE_INSTRUCTION_SM83(EMITTER, RETNC), \
DECLARE_INSTRUCTION_SM83(EMITTER, POPDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, JPNC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, CALLNC), \
DECLARE_INSTRUCTION_SM83(EMITTER, PUSHDE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SUB), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST10), \
DECLARE_INSTRUCTION_SM83(EMITTER, RETC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RETI), \
DECLARE_INSTRUCTION_SM83(EMITTER, JPC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, CALLC), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SBC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST18), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDIOA), \
DECLARE_INSTRUCTION_SM83(EMITTER, POPHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDIOCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, PUSHHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, AND), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST20), \
DECLARE_INSTRUCTION_SM83(EMITTER, ADDSP), \
DECLARE_INSTRUCTION_SM83(EMITTER, JPHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDIA), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, XOR), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST28), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDAIO), \
DECLARE_INSTRUCTION_SM83(EMITTER, POPAF), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDAIOC), \
DECLARE_INSTRUCTION_SM83(EMITTER, DI), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, PUSHAF), \
DECLARE_INSTRUCTION_SM83(EMITTER, OR), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST30), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDHL_SP), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDSP_HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, LDAI), \
DECLARE_INSTRUCTION_SM83(EMITTER, EI), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, ILL), \
DECLARE_INSTRUCTION_SM83(EMITTER, CP), \
DECLARE_INSTRUCTION_SM83(EMITTER, RST38)
#define DECLARE_SM83_CB_EMITTER_BLOCK(EMITTER) \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCB), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCD), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCE), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCH), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCB), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCD), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCE), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCH), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRCA), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLB), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLD), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLE), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLH), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RLA), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRB), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRC), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRD), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRE), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRH), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RRA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SLAA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRAA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SWAPA), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLB), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLC), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLD), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLE), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLH), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLHL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SRLA), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT0A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT1A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT2A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT3A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT4A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT5A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT6A), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7B), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7C), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7D), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7E), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7H), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7L), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, BIT7A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES0A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES1A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES2A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES3A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES4A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES5A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES6A), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7B), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7C), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7D), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7E), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7H), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7L), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, RES7A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET0A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET1A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET2A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET3A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET4A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET5A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET6A), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7B), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7C), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7D), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7E), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7H), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7L), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7HL), \
DECLARE_INSTRUCTION_SM83(EMITTER, SET7A)
#endif

View File

@ -3,17 +3,17 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ISA_LR35902_H
#define ISA_LR35902_H
#ifndef ISA_SM83_H
#define ISA_SM83_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct LR35902Core;
struct SM83Core;
typedef void (*LR35902Instruction)(struct LR35902Core*);
extern const LR35902Instruction _lr35902InstructionTable[0x100];
typedef void (*SM83Instruction)(struct SM83Core*);
extern const SM83Instruction _sm83InstructionTable[0x100];
CXX_GUARD_END

View File

@ -0,0 +1,146 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SM83_H
#define SM83_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/internal/sm83/isa-sm83.h>
struct SM83Core;
#pragma pack(push, 1)
union FlagRegister {
struct {
#if defined(__POWERPC__) || defined(__PPC__)
unsigned z : 1;
unsigned n : 1;
unsigned h : 1;
unsigned c : 1;
unsigned unused : 4;
#else
unsigned unused : 4;
unsigned c : 1;
unsigned h : 1;
unsigned n : 1;
unsigned z : 1;
#endif
};
uint8_t packed;
};
#pragma pack(pop)
enum SM83ExecutionState {
SM83_CORE_FETCH = 3,
SM83_CORE_IDLE_0 = 0,
SM83_CORE_IDLE_1 = 1,
SM83_CORE_EXECUTE = 2,
SM83_CORE_MEMORY_LOAD = 7,
SM83_CORE_MEMORY_STORE = 11,
SM83_CORE_READ_PC = 15,
SM83_CORE_STALL = 19,
SM83_CORE_OP2 = 23
};
struct SM83Memory {
uint8_t (*cpuLoad8)(struct SM83Core*, uint16_t address);
uint8_t (*load8)(struct SM83Core*, uint16_t address);
void (*store8)(struct SM83Core*, uint16_t address, int8_t value);
int (*currentSegment)(struct SM83Core*, uint16_t address);
const uint8_t* activeRegion;
uint16_t activeMask;
uint16_t activeRegionEnd;
void (*setActiveRegion)(struct SM83Core*, uint16_t address);
};
struct SM83InterruptHandler {
void (*reset)(struct SM83Core* cpu);
void (*processEvents)(struct SM83Core* cpu);
void (*setInterrupts)(struct SM83Core* cpu, bool enable);
uint16_t (*irqVector)(struct SM83Core* cpu);
void (*halt)(struct SM83Core* cpu);
void (*stop)(struct SM83Core* cpu);
void (*hitIllegal)(struct SM83Core* cpu);
};
struct SM83Core {
#pragma pack(push, 1)
union {
struct {
union FlagRegister f;
uint8_t a;
};
uint16_t af;
};
#pragma pack(pop)
union {
struct {
uint8_t c;
uint8_t b;
};
uint16_t bc;
};
union {
struct {
uint8_t e;
uint8_t d;
};
uint16_t de;
};
union {
struct {
uint8_t l;
uint8_t h;
};
uint16_t hl;
};
uint16_t sp;
uint16_t pc;
uint16_t index;
int32_t cycles;
int32_t nextEvent;
enum SM83ExecutionState executionState;
bool halted;
uint8_t bus;
bool condition;
SM83Instruction instruction;
bool irqPending;
struct SM83Memory memory;
struct SM83InterruptHandler irqh;
struct mCPUComponent* master;
size_t numComponents;
struct mCPUComponent** components;
};
void SM83Init(struct SM83Core* cpu);
void SM83Deinit(struct SM83Core* cpu);
void SM83SetComponents(struct SM83Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
void SM83HotplugAttach(struct SM83Core* cpu, size_t slot);
void SM83HotplugDetach(struct SM83Core* cpu, size_t slot);
void SM83Reset(struct SM83Core* cpu);
void SM83RaiseIRQ(struct SM83Core* cpu);
void SM83Tick(struct SM83Core* cpu);
void SM83Run(struct SM83Core* cpu);
CXX_GUARD_END
#endif

View File

@ -16,9 +16,9 @@
#define blip_add_delta blip_add_delta_fast
#endif
#define FRAME_CYCLES (DMG_LR35902_FREQUENCY >> 9)
#define FRAME_CYCLES (DMG_SM83_FREQUENCY >> 9)
const uint32_t DMG_LR35902_FREQUENCY = 0x400000;
const uint32_t DMG_SM83_FREQUENCY = 0x400000;
static const int CLOCKS_PER_BLIP_FRAME = 0x1000;
static const unsigned BLIP_BUFFER_SIZE = 0x4000;
const int GB_AUDIO_VOLUME_MAX = 0x100;
@ -51,10 +51,10 @@ void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAu
audio->samples = samples;
audio->left = blip_new(BLIP_BUFFER_SIZE);
audio->right = blip_new(BLIP_BUFFER_SIZE);
audio->clockRate = DMG_LR35902_FREQUENCY;
audio->clockRate = DMG_SM83_FREQUENCY;
// Guess too large; we hang producing extra samples if we guess too low
blip_set_rates(audio->left, DMG_LR35902_FREQUENCY, 96000);
blip_set_rates(audio->right, DMG_LR35902_FREQUENCY, 96000);
blip_set_rates(audio->left, DMG_SM83_FREQUENCY, 96000);
blip_set_rates(audio->right, DMG_SM83_FREQUENCY, 96000);
audio->forceDisableCh[0] = false;
audio->forceDisableCh[1] = false;
audio->forceDisableCh[2] = false;

View File

@ -18,8 +18,8 @@
#include <mgba/internal/gb/renderers/software.h>
#include <mgba/internal/gb/renderers/proxy.h>
#include <mgba/internal/gb/serialize.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/lr35902/debugger/debugger.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/sm83/debugger/debugger.h>
#include <mgba-util/crc32.h>
#include <mgba-util/memory.h>
#include <mgba-util/patch.h>
@ -77,7 +77,7 @@ struct GBCore {
static bool _GBCoreInit(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core;
struct LR35902Core* cpu = anonymousMemoryMap(sizeof(struct LR35902Core));
struct SM83Core* cpu = anonymousMemoryMap(sizeof(struct SM83Core));
struct GB* gb = anonymousMemoryMap(sizeof(struct GB));
if (!cpu || !gb) {
free(cpu);
@ -93,8 +93,8 @@ static bool _GBCoreInit(struct mCore* core) {
GBCreate(gb);
memset(gbcore->components, 0, sizeof(gbcore->components));
LR35902SetComponents(cpu, &gb->d, CPU_COMPONENT_MAX, gbcore->components);
LR35902Init(cpu);
SM83SetComponents(cpu, &gb->d, CPU_COMPONENT_MAX, gbcore->components);
SM83Init(cpu);
mRTCGenericSourceInit(&core->rtc, core);
gb->memory.rtc = &core->rtc.d;
@ -112,9 +112,9 @@ static bool _GBCoreInit(struct mCore* core) {
}
static void _GBCoreDeinit(struct mCore* core) {
LR35902Deinit(core->cpu);
SM83Deinit(core->cpu);
GBDestroy(core->board);
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
mappedMemoryFree(core->cpu, sizeof(struct SM83Core));
mappedMemoryFree(core->board, sizeof(struct GB));
#if defined USE_DEBUGGERS && (!defined(MINIMAL_CORE) || MINIMAL_CORE < 2)
mDirectorySetDeinit(&core->dirs);
@ -385,9 +385,9 @@ static bool _GBCoreLoadPatch(struct mCore* core, struct VFile* vf) {
static void _GBCoreUnloadROM(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core;
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
if (gbcore->cheatDevice) {
LR35902HotplugDetach(cpu, CPU_COMPONENT_CHEAT_DEVICE);
SM83HotplugDetach(cpu, CPU_COMPONENT_CHEAT_DEVICE);
cpu->components[CPU_COMPONENT_CHEAT_DEVICE] = NULL;
mCheatDeviceDestroy(gbcore->cheatDevice);
gbcore->cheatDevice = NULL;
@ -514,7 +514,7 @@ static void _GBCoreReset(struct mCore* core) {
}
#endif
LR35902Reset(core->cpu);
SM83Reset(core->cpu);
if (core->opts.skipBios) {
GBSkipBIOS(core->board);
@ -525,19 +525,19 @@ static void _GBCoreRunFrame(struct mCore* core) {
struct GB* gb = core->board;
int32_t frameCounter = gb->video.frameCounter;
while (gb->video.frameCounter == frameCounter) {
LR35902Run(core->cpu);
SM83Run(core->cpu);
}
}
static void _GBCoreRunLoop(struct mCore* core) {
LR35902Run(core->cpu);
SM83Run(core->cpu);
}
static void _GBCoreStep(struct mCore* core) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
do {
LR35902Tick(cpu);
} while (cpu->executionState != LR35902_CORE_FETCH);
SM83Tick(cpu);
} while (cpu->executionState != SM83_CORE_FETCH);
}
static size_t _GBCoreStateSize(struct mCore* core) {
@ -550,9 +550,9 @@ static bool _GBCoreLoadState(struct mCore* core, const void* state) {
}
static bool _GBCoreSaveState(struct mCore* core, void* state) {
struct LR35902Core* cpu = core->cpu;
while (cpu->executionState != LR35902_CORE_FETCH) {
LR35902Tick(cpu);
struct SM83Core* cpu = core->cpu;
while (cpu->executionState != SM83_CORE_FETCH) {
SM83Tick(cpu);
}
GBSerialize(core->board, state);
return true;
@ -588,7 +588,7 @@ static int32_t _GBCoreFrameCycles(const struct mCore* core) {
static int32_t _GBCoreFrequency(const struct mCore* core) {
UNUSED(core);
// TODO: GB differences
return DMG_LR35902_FREQUENCY;
return DMG_SM83_FREQUENCY;
}
static void _GBCoreGetGameTitle(const struct mCore* core, char* title) {
@ -617,34 +617,34 @@ static void _GBCoreSetPeripheral(struct mCore* core, int type, void* periph) {
}
static uint32_t _GBCoreBusRead8(struct mCore* core, uint32_t address) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return cpu->memory.load8(cpu, address);
}
static uint32_t _GBCoreBusRead16(struct mCore* core, uint32_t address) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return cpu->memory.load8(cpu, address) | (cpu->memory.load8(cpu, address + 1) << 8);
}
static uint32_t _GBCoreBusRead32(struct mCore* core, uint32_t address) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return cpu->memory.load8(cpu, address) | (cpu->memory.load8(cpu, address + 1) << 8) |
(cpu->memory.load8(cpu, address + 2) << 16) | (cpu->memory.load8(cpu, address + 3) << 24);
}
static void _GBCoreBusWrite8(struct mCore* core, uint32_t address, uint8_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
cpu->memory.store8(cpu, address, value);
}
static void _GBCoreBusWrite16(struct mCore* core, uint32_t address, uint16_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
cpu->memory.store8(cpu, address, value);
cpu->memory.store8(cpu, address + 1, value >> 8);
}
static void _GBCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
cpu->memory.store8(cpu, address, value);
cpu->memory.store8(cpu, address + 1, value >> 8);
cpu->memory.store8(cpu, address + 2, value >> 16);
@ -652,34 +652,34 @@ static void _GBCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t val
}
static uint32_t _GBCoreRawRead8(struct mCore* core, uint32_t address, int segment) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return GBView8(cpu, address, segment);
}
static uint32_t _GBCoreRawRead16(struct mCore* core, uint32_t address, int segment) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return GBView8(cpu, address, segment) | (GBView8(cpu, address + 1, segment) << 8);
}
static uint32_t _GBCoreRawRead32(struct mCore* core, uint32_t address, int segment) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
return GBView8(cpu, address, segment) | (GBView8(cpu, address + 1, segment) << 8) |
(GBView8(cpu, address + 2, segment) << 16) | (GBView8(cpu, address + 3, segment) << 24);
}
static void _GBCoreRawWrite8(struct mCore* core, uint32_t address, int segment, uint8_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
GBPatch8(cpu, address, value, NULL, segment);
}
static void _GBCoreRawWrite16(struct mCore* core, uint32_t address, int segment, uint16_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
GBPatch8(cpu, address, value, NULL, segment);
GBPatch8(cpu, address + 1, value >> 8, NULL, segment);
}
static void _GBCoreRawWrite32(struct mCore* core, uint32_t address, int segment, uint32_t value) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
GBPatch8(cpu, address, value, NULL, segment);
GBPatch8(cpu, address + 1, value >> 8, NULL, segment);
GBPatch8(cpu, address + 2, value >> 16, NULL, segment);
@ -745,7 +745,7 @@ static struct mDebuggerPlatform* _GBCoreDebuggerPlatform(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core;
struct GB* gb = core->board;
if (!gbcore->debuggerPlatform) {
struct LR35902Debugger* platform = (struct LR35902Debugger*) GBDebuggerCreate(gb);
struct SM83Debugger* platform = (struct SM83Debugger*) GBDebuggerCreate(gb);
gbcore->debuggerPlatform = &platform->d;
}
return gbcore->debuggerPlatform;
@ -756,19 +756,19 @@ static struct CLIDebuggerSystem* _GBCoreCliDebuggerSystem(struct mCore* core) {
}
static void _GBCoreAttachDebugger(struct mCore* core, struct mDebugger* debugger) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
if (core->debugger) {
LR35902HotplugDetach(cpu, CPU_COMPONENT_DEBUGGER);
SM83HotplugDetach(cpu, CPU_COMPONENT_DEBUGGER);
}
cpu->components[CPU_COMPONENT_DEBUGGER] = &debugger->d;
LR35902HotplugAttach(cpu, CPU_COMPONENT_DEBUGGER);
SM83HotplugAttach(cpu, CPU_COMPONENT_DEBUGGER);
core->debugger = debugger;
}
static void _GBCoreDetachDebugger(struct mCore* core) {
struct LR35902Core* cpu = core->cpu;
struct SM83Core* cpu = core->cpu;
if (core->debugger) {
LR35902HotplugDetach(cpu, CPU_COMPONENT_DEBUGGER);
SM83HotplugDetach(cpu, CPU_COMPONENT_DEBUGGER);
}
cpu->components[CPU_COMPONENT_DEBUGGER] = NULL;
core->debugger = NULL;
@ -806,8 +806,8 @@ static struct mCheatDevice* _GBCoreCheatDevice(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core;
if (!gbcore->cheatDevice) {
gbcore->cheatDevice = GBCheatDeviceCreate();
((struct LR35902Core*) core->cpu)->components[CPU_COMPONENT_CHEAT_DEVICE] = &gbcore->cheatDevice->d;
LR35902HotplugAttach(core->cpu, CPU_COMPONENT_CHEAT_DEVICE);
((struct SM83Core*) core->cpu)->components[CPU_COMPONENT_CHEAT_DEVICE] = &gbcore->cheatDevice->d;
SM83HotplugAttach(core->cpu, CPU_COMPONENT_CHEAT_DEVICE);
gbcore->cheatDevice->p = core;
}
return gbcore->cheatDevice;
@ -1076,7 +1076,7 @@ static void _GBVLPReset(struct mCore* core) {
GBVideoAssociateRenderer(&gb->video, renderer);
}
LR35902Reset(core->cpu);
SM83Reset(core->cpu);
mVideoLogContextRewind(gbcore->logContext, core);
GBVideoProxyRendererShim(&gb->video, &gbcore->proxyRenderer);

View File

@ -10,7 +10,7 @@
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/video.h>
#include <mgba/internal/lr35902/debugger/cli-debugger.h>
#include <mgba/internal/sm83/debugger/cli-debugger.h>
static void _GBCLIDebuggerInit(struct CLIDebuggerSystem*);
static bool _GBCLIDebuggerCustom(struct CLIDebuggerSystem*);
@ -29,7 +29,7 @@ struct CLIDebuggerCommandSummary _GBCLIDebuggerCommands[] = {
struct CLIDebuggerSystem* GBCLIDebuggerCreate(struct mCore* core) {
UNUSED(core);
struct GBCLIDebugger* debugger = malloc(sizeof(struct GBCLIDebugger));
LR35902CLIDebuggerCreate(&debugger->d);
SM83CLIDebuggerCreate(&debugger->d);
debugger->d.init = _GBCLIDebuggerInit;
debugger->d.deinit = NULL;
debugger->d.custom = _GBCLIDebuggerCustom;

View File

@ -10,15 +10,15 @@
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/memory.h>
#include <mgba/internal/lr35902/debugger/debugger.h>
#include <mgba/internal/sm83/debugger/debugger.h>
static const struct LR35902Segment _GBSegments[] = {
static const struct SM83Segment _GBSegments[] = {
{ .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM },
{ .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 },
{ 0 }
};
static const struct LR35902Segment _GBCSegments[] = {
static const struct SM83Segment _GBCSegments[] = {
{ .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM },
{ .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 },
{ .name = "WRAM", .start = GB_BASE_WORKING_RAM_BANK1, .end = 0xE000 },
@ -35,7 +35,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
}
struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb) {
struct LR35902Debugger* platform = (struct LR35902Debugger*) LR35902DebuggerPlatformCreate();
struct SM83Debugger* platform = (struct SM83Debugger*) SM83DebuggerPlatformCreate();
if (gb->model >= GB_MODEL_CGB) {
platform->segments = _GBCSegments;
} else {

View File

@ -7,7 +7,7 @@
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/mbc.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/core/core.h>
#include <mgba/core/cheats.h>
@ -19,8 +19,8 @@
#define CLEANUP_THRESHOLD 15
const uint32_t CGB_LR35902_FREQUENCY = 0x800000;
const uint32_t SGB_LR35902_FREQUENCY = 0x418B1E;
const uint32_t CGB_SM83_FREQUENCY = 0x800000;
const uint32_t SGB_SM83_FREQUENCY = 0x418B1E;
const uint32_t GB_COMPONENT_MAGIC = 0x400000;
@ -37,12 +37,12 @@ mLOG_DEFINE_CATEGORY(GB, "GB", "gb");
static void GBInit(void* cpu, struct mCPUComponent* component);
static void GBDeinit(struct mCPUComponent* component);
static void GBInterruptHandlerInit(struct LR35902InterruptHandler* irqh);
static void GBProcessEvents(struct LR35902Core* cpu);
static void GBSetInterrupts(struct LR35902Core* cpu, bool enable);
static uint16_t GBIRQVector(struct LR35902Core* cpu);
static void GBIllegal(struct LR35902Core* cpu);
static void GBStop(struct LR35902Core* cpu);
static void GBInterruptHandlerInit(struct SM83InterruptHandler* irqh);
static void GBProcessEvents(struct SM83Core* cpu);
static void GBSetInterrupts(struct SM83Core* cpu, bool enable);
static uint16_t GBIRQVector(struct SM83Core* cpu);
static void GBIllegal(struct SM83Core* cpu);
static void GBStop(struct SM83Core* cpu);
static void _enableInterrupts(struct mTiming* timing, void* user, uint32_t cyclesLate);
@ -119,7 +119,7 @@ bool GBLoadROM(struct GB* gb, struct VFile* vf) {
GBMBCInit(gb);
if (gb->cpu) {
struct LR35902Core* cpu = gb->cpu;
struct SM83Core* cpu = gb->cpu;
cpu->memory.setActiveRegion(cpu, cpu->pc);
}
@ -135,7 +135,7 @@ void GBYankROM(struct GB* gb) {
gb->memory.sramAccess = false;
if (gb->cpu) {
struct LR35902Core* cpu = gb->cpu;
struct SM83Core* cpu = gb->cpu;
cpu->memory.setActiveRegion(cpu, cpu->pc);
}
}
@ -375,7 +375,7 @@ void GBDestroy(struct GB* gb) {
mCoreCallbacksListDeinit(&gb->coreCallbacks);
}
void GBInterruptHandlerInit(struct LR35902InterruptHandler* irqh) {
void GBInterruptHandlerInit(struct SM83InterruptHandler* irqh) {
irqh->reset = GBReset;
irqh->processEvents = GBProcessEvents;
irqh->setInterrupts = GBSetInterrupts;
@ -410,7 +410,7 @@ bool GBIsBIOS(struct VFile* vf) {
}
}
void GBReset(struct LR35902Core* cpu) {
void GBReset(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
gb->memory.romBase = gb->memory.rom;
GBDetectModel(gb);
@ -477,7 +477,7 @@ void GBReset(struct LR35902Core* cpu) {
}
void GBSkipBIOS(struct GB* gb) {
struct LR35902Core* cpu = gb->cpu;
struct SM83Core* cpu = gb->cpu;
int nextDiv = 0;
switch (gb->model) {
@ -656,10 +656,10 @@ void GBUpdateIRQs(struct GB* gb) {
if (gb->cpu->irqPending) {
return;
}
LR35902RaiseIRQ(gb->cpu);
SM83RaiseIRQ(gb->cpu);
}
void GBProcessEvents(struct LR35902Core* cpu) {
void GBProcessEvents(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
do {
int32_t cycles = cpu->cycles;
@ -687,7 +687,7 @@ void GBProcessEvents(struct LR35902Core* cpu) {
gb->earlyExit = false;
}
void GBSetInterrupts(struct LR35902Core* cpu, bool enable) {
void GBSetInterrupts(struct SM83Core* cpu, bool enable) {
struct GB* gb = (struct GB*) cpu->master;
mTimingDeschedule(&gb->timing, &gb->eiPending);
if (!enable) {
@ -698,7 +698,7 @@ void GBSetInterrupts(struct LR35902Core* cpu, bool enable) {
}
}
uint16_t GBIRQVector(struct LR35902Core* cpu) {
uint16_t GBIRQVector(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
int irqs = gb->memory.ie & gb->memory.io[REG_IF];
@ -733,7 +733,7 @@ static void _enableInterrupts(struct mTiming* timing, void* user, uint32_t cycle
GBUpdateIRQs(gb);
}
void GBHalt(struct LR35902Core* cpu) {
void GBHalt(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
if (!(gb->memory.ie & gb->memory.io[REG_IF] & 0x1F)) {
cpu->cycles = cpu->nextEvent;
@ -743,7 +743,7 @@ void GBHalt(struct LR35902Core* cpu) {
}
}
void GBStop(struct LR35902Core* cpu) {
void GBStop(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
if (cpu->bus) {
mLOG(GB, GAME_ERROR, "Hit illegal stop at address %04X:%02X", cpu->pc, cpu->bus);
@ -758,7 +758,7 @@ void GBStop(struct LR35902Core* cpu) {
if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) {
struct mDebuggerEntryInfo info = {
.address = cpu->pc - 1,
.type.bp.opcode = 0x1000 | cpu->bus
.type.bp.opcode = 0x1000 | cpu->bus,
};
mDebuggerEnter((struct mDebugger*) cpu->components[CPU_COMPONENT_DEBUGGER], DEBUGGER_ENTER_ILLEGAL_OP, &info);
}
@ -770,7 +770,7 @@ void GBStop(struct LR35902Core* cpu) {
// TODO: Actually stop
}
void GBIllegal(struct LR35902Core* cpu) {
void GBIllegal(struct SM83Core* cpu) {
struct GB* gb = (struct GB*) cpu->master;
mLOG(GB, GAME_ERROR, "Hit illegal opcode at address %04X:%02X", cpu->pc, cpu->bus);
#ifdef USE_DEBUGGERS

View File

@ -6,7 +6,7 @@
#include <mgba/internal/gb/mbc.h>
#include <mgba/core/interface.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/memory.h>
#include <mgba-util/crc32.h>

View File

@ -10,7 +10,7 @@
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/mbc.h>
#include <mgba/internal/gb/serialize.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba-util/memory.h>
@ -51,7 +51,7 @@ static const uint8_t _blockedRegion[1] = { 0xFF };
static void _pristineCow(struct GB* gba);
static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) {
static uint8_t GBFastLoad8(struct SM83Core* cpu, uint16_t address) {
if (UNLIKELY(address >= cpu->memory.activeRegionEnd)) {
cpu->memory.setActiveRegion(cpu, address);
return cpu->memory.cpuLoad8(cpu, address);
@ -59,7 +59,7 @@ static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) {
return cpu->memory.activeRegion[address & cpu->memory.activeMask];
}
static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) {
static void GBSetActiveRegion(struct SM83Core* cpu, uint16_t address) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
switch (address >> 12) {
@ -127,7 +127,7 @@ static void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t
static void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate);
void GBMemoryInit(struct GB* gb) {
struct LR35902Core* cpu = gb->cpu;
struct SM83Core* cpu = gb->cpu;
cpu->memory.cpuLoad8 = GBLoad8;
cpu->memory.load8 = GBLoad8;
cpu->memory.store8 = GBStore8;
@ -242,7 +242,7 @@ void GBMemorySwitchWramBank(struct GBMemory* memory, int bank) {
memory->wramCurrentBank = bank;
}
uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) {
uint8_t GBLoad8(struct SM83Core* cpu, uint16_t address) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
if (gb->memory.dmaRemaining) {
@ -324,7 +324,7 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) {
}
}
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
void GBStore8(struct SM83Core* cpu, uint16_t address, int8_t value) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
if (gb->memory.dmaRemaining) {
@ -395,7 +395,7 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
}
}
int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address) {
int GBCurrentSegment(struct SM83Core* cpu, uint16_t address) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
switch (address >> 12) {
@ -425,7 +425,7 @@ int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address) {
}
}
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment) {
uint8_t GBView8(struct SM83Core* cpu, uint16_t address, int segment) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
switch (address >> 12) {
@ -604,7 +604,7 @@ void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cycles
}
}
void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment) {
void GBPatch8(struct SM83Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;
int8_t oldValue = -1;

View File

@ -7,7 +7,7 @@
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/timer.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba-util/memory.h>
@ -104,11 +104,11 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
mLOG(GB_STATE, WARN, "Savestate is corrupted: CPU cycles are negative");
error = true;
}
if (state->cpu.executionState != LR35902_CORE_FETCH) {
if (state->cpu.executionState != SM83_CORE_FETCH) {
mLOG(GB_STATE, WARN, "Savestate is corrupted: Execution state is not FETCH");
error = true;
}
if (check >= (int32_t) DMG_LR35902_FREQUENCY) {
if (check >= (int32_t) DMG_SM83_FREQUENCY) {
mLOG(GB_STATE, WARN, "Savestate is corrupted: CPU cycles are too high");
error = true;
}

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/gb/timer.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/serialize.h>

View File

@ -12,7 +12,7 @@
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/renderers/cache-set.h>
#include <mgba/internal/gb/serialize.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba-util/memory.h>
@ -339,7 +339,7 @@ void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLate) {
UNUSED(cyclesLate);
struct GBVideo* video = context;
if (video->p->cpu->executionState != LR35902_CORE_FETCH) {
if (video->p->cpu->executionState != SM83_CORE_FETCH) {
mTimingSchedule(timing, &video->frameEvent, 4 - ((video->p->cpu->executionState + 1) & 3));
return;
}

View File

@ -1,16 +0,0 @@
include(ExportDirectory)
set(SOURCE_FILES
decoder.c
isa-lr35902.c
lr35902.c)
set(DEBUGGER_FILES
debugger/cli-debugger.c
debugger/debugger.c
debugger/memory-debugger.c)
source_group("LR35902 core" FILES ${SOURCE_FILES})
source_group("ARM LR35902" FILES ${DEBUGGER_FILES})
export_directory(LR35902 SOURCE_FILES)
export_directory(LR35902_DEBUGGER DEBUGGER_FILES)

View File

@ -1,580 +0,0 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/decoder.h>
#include <mgba/internal/lr35902/emitter-lr35902.h>
#include <mgba/internal/lr35902/lr35902.h>
typedef size_t (*LR35902Decoder)(uint8_t opcode, struct LR35902InstructionInfo* info);
#define DEFINE_DECODER_LR35902(NAME, BODY) \
static size_t _LR35902Decode ## NAME (uint8_t opcode, struct LR35902InstructionInfo* info) { \
UNUSED(opcode); \
info->mnemonic = LR35902_MN_RST; \
BODY; \
return 0; \
}
DEFINE_DECODER_LR35902(NOP, info->mnemonic = LR35902_MN_NOP;)
#define DEFINE_LD_DECODER_LR35902_NOHL(NAME) \
DEFINE_DECODER_LR35902(LD ## NAME ## _A, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_A) \
DEFINE_DECODER_LR35902(LD ## NAME ## _B, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_B) \
DEFINE_DECODER_LR35902(LD ## NAME ## _C, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_C) \
DEFINE_DECODER_LR35902(LD ## NAME ## _D, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_D) \
DEFINE_DECODER_LR35902(LD ## NAME ## _E, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_E) \
DEFINE_DECODER_LR35902(LD ## NAME ## _H, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_H) \
DEFINE_DECODER_LR35902(LD ## NAME ## _L, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_L)
#define DEFINE_LD_DECODER_LR35902_MEM(NAME, REG) \
DEFINE_DECODER_LR35902(LD ## NAME ## _ ## REG, info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
info->op2.reg = LR35902_REG_ ## REG; \
info->op2.flags = LR35902_OP_FLAG_MEMORY;)
#define DEFINE_LD_DECODER_LR35902_MEM_2(NAME, REG) \
DEFINE_DECODER_LR35902(LD ## REG ## _ ## NAME, info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## REG; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_ ## NAME;)
#define DEFINE_LD_DECODER_LR35902(NAME) \
DEFINE_LD_DECODER_LR35902_MEM(NAME, HL) \
DEFINE_LD_DECODER_LR35902_MEM_2(NAME, HL) \
DEFINE_DECODER_LR35902(LD ## NAME ## _, info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
return 1;) \
DEFINE_LD_DECODER_LR35902_NOHL(NAME)
#define DEFINE_LD_2_DECODER_LR35902(NAME) \
DEFINE_DECODER_LR35902(LD ## NAME, info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_ ## NAME; \
return 2;)
DEFINE_LD_DECODER_LR35902(B);
DEFINE_LD_DECODER_LR35902(C);
DEFINE_LD_DECODER_LR35902(D);
DEFINE_LD_DECODER_LR35902(E);
DEFINE_LD_DECODER_LR35902(H);
DEFINE_LD_DECODER_LR35902(L);
DEFINE_LD_DECODER_LR35902(A);
DEFINE_LD_DECODER_LR35902_MEM(A, BC);
DEFINE_LD_DECODER_LR35902_MEM(A, DE);
DEFINE_LD_2_DECODER_LR35902(BC);
DEFINE_LD_2_DECODER_LR35902(DE);
DEFINE_LD_2_DECODER_LR35902(HL);
DEFINE_LD_2_DECODER_LR35902(SP);
DEFINE_DECODER_LR35902(LDHL_, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_HL; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
return 1;)
DEFINE_DECODER_LR35902(LDHL_SP, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_HL; \
info->op2.reg = LR35902_REG_SP; \
return 1;)
DEFINE_DECODER_LR35902(LDSP_HL, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_SP; \
info->op2.reg = LR35902_REG_HL;)
DEFINE_DECODER_LR35902(LDAIOC, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_A; \
info->op2.reg = LR35902_REG_C; \
info->op2.immediate = 0xFF00; \
info->op2.flags = LR35902_OP_FLAG_MEMORY;)
DEFINE_DECODER_LR35902(LDIOCA, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_C; \
info->op1.immediate = 0xFF00; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A;)
DEFINE_DECODER_LR35902(LDAIO, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_A; \
info->op2.immediate = 0xFF00; \
info->op2.flags = LR35902_OP_FLAG_MEMORY; \
return 1;)
DEFINE_DECODER_LR35902(LDIOA, \
info->mnemonic = LR35902_MN_LD; \
info->op1.immediate = 0xFF00; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A; \
return 1;)
#define DEFINE_ALU_DECODER_LR35902_NOHL(NAME) \
DEFINE_DECODER_LR35902(NAME ## A, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A) \
DEFINE_DECODER_LR35902(NAME ## B, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_B) \
DEFINE_DECODER_LR35902(NAME ## C, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_C) \
DEFINE_DECODER_LR35902(NAME ## D, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_D) \
DEFINE_DECODER_LR35902(NAME ## E, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_E) \
DEFINE_DECODER_LR35902(NAME ## H, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_H) \
DEFINE_DECODER_LR35902(NAME ## L, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_L)
#define DEFINE_ALU_DECODER_LR35902_MEM(NAME, REG) \
DEFINE_DECODER_LR35902(NAME ## REG, info->mnemonic = LR35902_MN_ ## NAME; \
info->op1.reg = LR35902_REG_HL; \
info->op1.flags = LR35902_OP_FLAG_MEMORY;)
#define DEFINE_ALU_DECODER_LR35902(NAME) \
DEFINE_ALU_DECODER_LR35902_MEM(NAME, HL) \
DEFINE_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME; \
info->op1.reg = LR35902_REG_A; \
info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
return 1;) \
DEFINE_ALU_DECODER_LR35902_NOHL(NAME)
DEFINE_ALU_DECODER_LR35902_NOHL(INC);
DEFINE_ALU_DECODER_LR35902_NOHL(DEC);
DEFINE_ALU_DECODER_LR35902(AND);
DEFINE_ALU_DECODER_LR35902(XOR);
DEFINE_ALU_DECODER_LR35902(OR);
DEFINE_ALU_DECODER_LR35902(CP);
DEFINE_ALU_DECODER_LR35902(ADD);
DEFINE_ALU_DECODER_LR35902(ADC);
DEFINE_ALU_DECODER_LR35902(SUB);
DEFINE_ALU_DECODER_LR35902(SBC);
#define DEFINE_ALU_DECODER_LR35902_ADD_HL(REG) \
DEFINE_DECODER_LR35902(ADDHL_ ## REG, info->mnemonic = LR35902_MN_ADD; \
info->op1.reg = LR35902_REG_HL; \
info->op2.reg = LR35902_REG_ ## REG;)
DEFINE_ALU_DECODER_LR35902_ADD_HL(BC)
DEFINE_ALU_DECODER_LR35902_ADD_HL(DE)
DEFINE_ALU_DECODER_LR35902_ADD_HL(HL)
DEFINE_ALU_DECODER_LR35902_ADD_HL(SP)
DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \
info->op1.reg = LR35902_REG_SP; \
return 1;)
#define DEFINE_CONDITIONAL_DECODER_LR35902(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(, 0) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, LR35902_COND_C) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Z, LR35902_COND_Z) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NC, LR35902_COND_NC) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NZ, LR35902_COND_NZ)
#define DEFINE_JP_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_LR35902(JP ## CONDITION_NAME, \
info->mnemonic = LR35902_MN_JP; \
info->condition = CONDITION; \
return 2;)
#define DEFINE_JR_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \
info->mnemonic = LR35902_MN_JR; \
info->condition = CONDITION; \
info->op1.flags = LR35902_OP_FLAG_RELATIVE; \
return 1;)
#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_LR35902(CALL ## CONDITION_NAME, \
info->mnemonic = LR35902_MN_CALL; \
info->condition = CONDITION; \
return 2;)
#define DEFINE_RET_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_LR35902(RET ## CONDITION_NAME, \
info->mnemonic = LR35902_MN_RET; \
info->condition = CONDITION;)
DEFINE_CONDITIONAL_DECODER_LR35902(JP);
DEFINE_CONDITIONAL_DECODER_LR35902(JR);
DEFINE_CONDITIONAL_DECODER_LR35902(CALL);
DEFINE_CONDITIONAL_DECODER_LR35902(RET);
DEFINE_DECODER_LR35902(JPHL, \
info->mnemonic = LR35902_MN_JP; \
info->op1.reg = LR35902_REG_HL)
DEFINE_DECODER_LR35902(RETI, info->mnemonic = LR35902_MN_RETI)
DEFINE_DECODER_LR35902(LDBC_A, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_BC; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A;)
DEFINE_DECODER_LR35902(LDDE_A, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_DE; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A;)
DEFINE_DECODER_LR35902(LDIA, \
info->mnemonic = LR35902_MN_LD; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A; \
return 2;)
DEFINE_DECODER_LR35902(LDAI, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_A; \
info->op2.flags = LR35902_OP_FLAG_MEMORY; \
return 2;)
DEFINE_DECODER_LR35902(LDISP, \
info->mnemonic = LR35902_MN_LD; \
info->op1.flags = LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_SP; \
return 2;)
DEFINE_DECODER_LR35902(LDIHLA, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_HL; \
info->op1.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A;)
DEFINE_DECODER_LR35902(LDDHLA, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_HL; \
info->op1.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY; \
info->op2.reg = LR35902_REG_A;)
DEFINE_DECODER_LR35902(LDA_IHL, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_A; \
info->op2.reg = LR35902_REG_HL; \
info->op2.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY;)
DEFINE_DECODER_LR35902(LDA_DHL, \
info->mnemonic = LR35902_MN_LD; \
info->op1.reg = LR35902_REG_A; \
info->op2.reg = LR35902_REG_HL; \
info->op2.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY;)
#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
DEFINE_DECODER_LR35902(INC ## REG, info->mnemonic = LR35902_MN_INC; info->op1.reg = LR35902_REG_ ## REG) \
DEFINE_DECODER_LR35902(DEC ## REG, info->mnemonic = LR35902_MN_DEC; info->op1.reg = LR35902_REG_ ## REG)
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(SP);
DEFINE_DECODER_LR35902(INC_HL,
info->mnemonic = LR35902_MN_INC;
info->op1.reg = LR35902_REG_HL;
info->op1.flags = LR35902_OP_FLAG_MEMORY;)
DEFINE_DECODER_LR35902(DEC_HL,
info->mnemonic = LR35902_MN_DEC;
info->op1.reg = LR35902_REG_HL;
info->op1.flags = LR35902_OP_FLAG_MEMORY;)
DEFINE_DECODER_LR35902(SCF, info->mnemonic = LR35902_MN_SCF)
DEFINE_DECODER_LR35902(CCF, info->mnemonic = LR35902_MN_CCF)
DEFINE_DECODER_LR35902(CPL_, info->mnemonic = LR35902_MN_CPL)
DEFINE_DECODER_LR35902(DAA, info->mnemonic = LR35902_MN_DAA)
#define DEFINE_POPPUSH_DECODER_LR35902(REG) \
DEFINE_DECODER_LR35902(POP ## REG, \
info->mnemonic = LR35902_MN_POP; \
info->op1.reg = LR35902_REG_ ## REG;) \
DEFINE_DECODER_LR35902(PUSH ## REG, \
info->mnemonic = LR35902_MN_PUSH; \
info->op1.reg = LR35902_REG_ ## REG;) \
DEFINE_POPPUSH_DECODER_LR35902(BC);
DEFINE_POPPUSH_DECODER_LR35902(DE);
DEFINE_POPPUSH_DECODER_LR35902(HL);
DEFINE_POPPUSH_DECODER_LR35902(AF);
#define DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, OP) \
DEFINE_DECODER_LR35902(NAME ## B, info->OP.reg = LR35902_REG_B; BODY) \
DEFINE_DECODER_LR35902(NAME ## C, info->OP.reg = LR35902_REG_C; BODY) \
DEFINE_DECODER_LR35902(NAME ## D, info->OP.reg = LR35902_REG_D; BODY) \
DEFINE_DECODER_LR35902(NAME ## E, info->OP.reg = LR35902_REG_E; BODY) \
DEFINE_DECODER_LR35902(NAME ## H, info->OP.reg = LR35902_REG_H; BODY) \
DEFINE_DECODER_LR35902(NAME ## L, info->OP.reg = LR35902_REG_L; BODY) \
DEFINE_DECODER_LR35902(NAME ## HL, info->OP.reg = LR35902_REG_HL; info->OP.flags = LR35902_OP_FLAG_MEMORY; BODY) \
DEFINE_DECODER_LR35902(NAME ## A, info->OP.reg = LR35902_REG_A; BODY)
#define DEFINE_CB_2_DECODER_LR35902(NAME, BODY) \
DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op2)
#define DEFINE_CB_1_DECODER_LR35902(NAME, BODY) \
DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op1)
#define DEFINE_CB_DECODER_LR35902(NAME, BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 1, info->op1.immediate = 1; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 2, info->op1.immediate = 2; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 3, info->op1.immediate = 3; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 4, info->op1.immediate = 4; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 5, info->op1.immediate = 5; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 6, info->op1.immediate = 6; BODY) \
DEFINE_CB_2_DECODER_LR35902(NAME ## 7, info->op1.immediate = 7; BODY)
DEFINE_CB_DECODER_LR35902(BIT, info->mnemonic = LR35902_MN_BIT)
DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES)
DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET)
#define DEFINE_CB_X_DECODER_LR35902(NAME) \
DEFINE_CB_1_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \
DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; \
info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
info->op1.reg = LR35902_REG_A;)
DEFINE_CB_X_DECODER_LR35902(RL)
DEFINE_CB_X_DECODER_LR35902(RLC)
DEFINE_CB_X_DECODER_LR35902(RR)
DEFINE_CB_X_DECODER_LR35902(RRC)
DEFINE_CB_1_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA)
DEFINE_CB_1_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA)
DEFINE_CB_1_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL)
DEFINE_CB_1_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP)
DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI)
DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI)
DEFINE_DECODER_LR35902(HALT, info->mnemonic = LR35902_MN_HALT)
DEFINE_DECODER_LR35902(ILL, info->mnemonic = LR35902_MN_ILL)
DEFINE_DECODER_LR35902(STOP, info->mnemonic = LR35902_MN_STOP; return 1)
#define DEFINE_RST_DECODER_LR35902(VEC) \
DEFINE_DECODER_LR35902(RST ## VEC, info->op1.immediate = 0x ## VEC;)
DEFINE_RST_DECODER_LR35902(00);
DEFINE_RST_DECODER_LR35902(08);
DEFINE_RST_DECODER_LR35902(10);
DEFINE_RST_DECODER_LR35902(18);
DEFINE_RST_DECODER_LR35902(20);
DEFINE_RST_DECODER_LR35902(28);
DEFINE_RST_DECODER_LR35902(30);
DEFINE_RST_DECODER_LR35902(38);
DEFINE_DECODER_LR35902(CB, return 1)
const LR35902Decoder _lr35902DecoderTable[0x100] = {
DECLARE_LR35902_EMITTER_BLOCK(_LR35902Decode)
};
const LR35902Decoder _lr35902CBDecoderTable[0x100] = {
DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Decode)
};
size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info) {
if (info->opcodeSize == sizeof(info->opcode)) {
return 0;
}
info->opcode[info->opcodeSize] = opcode;
LR35902Decoder decoder;
switch (info->opcodeSize) {
case 0:
decoder = _lr35902DecoderTable[opcode];
break;
case 1:
if (info->opcode[0] == 0xCB) {
decoder = _lr35902CBDecoderTable[opcode];
break;
}
// Fall through
case 2:
++info->opcodeSize;
if (info->op1.reg) {
info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
} else {
info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
}
return 0;
}
++info->opcodeSize;
return decoder(opcode, info);
}
#define ADVANCE(AMOUNT) \
if (AMOUNT >= blen) { \
buffer[blen - 1] = '\0'; \
return total; \
} \
total += AMOUNT; \
buffer += AMOUNT; \
blen -= AMOUNT;
static const char* _lr35902Conditions[] = {
NULL,
"c",
"z",
"nc",
"nz",
};
static const char* _lr35902Registers[] = {
"",
"b",
"c",
"d",
"e",
"h",
"l",
"a",
"f",
"bc",
"de",
"hl",
"af",
"sp",
"pc",
};
static const char* _lr35902MnemonicStrings[] = {
"--",
"adc",
"add",
"and",
"bit",
"call",
"ccf",
"cp",
"cpl",
"daa",
"dec",
"di",
"ei",
"halt",
"inc",
"jp",
"jr",
"ld",
"nop",
"or",
"pop",
"push",
"res",
"ret",
"reti",
"rl",
"rlc",
"rr",
"rrc",
"rst",
"sbc",
"scf",
"set",
"sla",
"sra",
"srl",
"stop",
"sub",
"swap",
"xor",
"ill"
};
static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, int blen) {
int total = 0;
if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
return 0;
}
strncpy(buffer, " ", blen - 1);
ADVANCE(1);
if (op.flags & LR35902_OP_FLAG_MEMORY) {
strncpy(buffer, "[", blen - 1);
ADVANCE(1);
}
if (op.reg) {
int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
ADVANCE(written);
} else {
int written;
if (op.flags & LR35902_OP_FLAG_RELATIVE) {
written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
} else {
written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
}
ADVANCE(written);
if (op.reg) {
strncpy(buffer, "+", blen - 1);
ADVANCE(1);
}
}
if (op.flags & LR35902_OP_FLAG_INCREMENT) {
strncpy(buffer, "+", blen - 1);
ADVANCE(1);
}
if (op.flags & LR35902_OP_FLAG_DECREMENT) {
strncpy(buffer, "-", blen - 1);
ADVANCE(1);
}
if (op.flags & LR35902_OP_FLAG_MEMORY) {
strncpy(buffer, "]", blen - 1);
ADVANCE(1);
}
return total;
}
int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) {
const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
int written;
int total = 0;
const char* cond = _lr35902Conditions[info->condition];
written = snprintf(buffer, blen - 1, "%s", mnemonic);
ADVANCE(written);
if (cond) {
written = snprintf(buffer, blen - 1, " %s", cond);
ADVANCE(written);
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
strncpy(buffer, ",", blen - 1);
ADVANCE(1);
}
}
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
written = _decodeOperand(info->op1, pc, buffer, blen);
ADVANCE(written);
}
if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
if (written) {
strncpy(buffer, ",", blen - 1);
ADVANCE(1);
}
written = _decodeOperand(info->op2, pc, buffer, blen);
ADVANCE(written);
}
buffer[blen - 1] = '\0';
return total;
}

View File

@ -1,820 +0,0 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/isa-lr35902.h>
#include <mgba/internal/lr35902/emitter-lr35902.h>
#include <mgba/internal/lr35902/lr35902.h>
static inline uint16_t LR35902ReadHL(struct LR35902Core* cpu) {
uint16_t hl;
LOAD_16LE(hl, 0, &cpu->hl);
return hl;
}
static inline void LR35902WriteHL(struct LR35902Core* cpu, uint16_t hl) {
STORE_16LE(hl, 0, &cpu->hl);
}
static inline uint16_t LR35902ReadBC(struct LR35902Core* cpu) {
uint16_t bc;
LOAD_16LE(bc, 0, &cpu->bc);
return bc;
}
static inline void LR35902WriteBC(struct LR35902Core* cpu, uint16_t bc) {
STORE_16LE(bc, 0, &cpu->bc);
}
static inline uint16_t LR35902ReadDE(struct LR35902Core* cpu) {
uint16_t de;
LOAD_16LE(de, 0, &cpu->de);
return de;
}
static inline void LR35902WriteDE(struct LR35902Core* cpu, uint16_t de) {
STORE_16LE(de, 0, &cpu->de);
}
#define DEFINE_INSTRUCTION_LR35902(NAME, BODY) \
static void _LR35902Instruction ## NAME (struct LR35902Core* cpu) { \
UNUSED(cpu); \
BODY; \
}
DEFINE_INSTRUCTION_LR35902(NOP,);
#define DEFINE_CONDITIONAL_ONLY_INSTRUCTION_LR35902(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, cpu->f.c) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Z, cpu->f.z) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NC, !cpu->f.c) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NZ, !cpu->f.z)
#define DEFINE_CONDITIONAL_INSTRUCTION_LR35902(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(, true) \
DEFINE_CONDITIONAL_ONLY_INSTRUCTION_LR35902(NAME)
DEFINE_INSTRUCTION_LR35902(JPFinish,
if (cpu->condition) {
cpu->pc = (cpu->bus << 8) | cpu->index;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = LR35902_CORE_STALL;
})
DEFINE_INSTRUCTION_LR35902(JPDelay,
cpu->executionState = LR35902_CORE_READ_PC;
cpu->instruction = _LR35902InstructionJPFinish;
cpu->index = cpu->bus;)
#define DEFINE_JP_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_LR35902(JP ## CONDITION_NAME, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionJPDelay; \
cpu->condition = CONDITION;)
DEFINE_CONDITIONAL_INSTRUCTION_LR35902(JP);
DEFINE_INSTRUCTION_LR35902(JPHL,
cpu->pc = LR35902ReadHL(cpu);
cpu->memory.setActiveRegion(cpu, cpu->pc);)
DEFINE_INSTRUCTION_LR35902(JRFinish,
if (cpu->condition) {
cpu->pc += (int8_t) cpu->bus;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = LR35902_CORE_STALL;
})
#define DEFINE_JR_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_LR35902(JR ## CONDITION_NAME, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionJRFinish; \
cpu->condition = CONDITION;)
DEFINE_CONDITIONAL_INSTRUCTION_LR35902(JR);
DEFINE_INSTRUCTION_LR35902(CALLUpdateSPL,
--cpu->index;
cpu->bus = cpu->sp;
cpu->sp = cpu->index;
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(CALLUpdateSPH,
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionCALLUpdateSPL;)
DEFINE_INSTRUCTION_LR35902(CALLUpdatePCH,
if (cpu->condition) {
int newPc = (cpu->bus << 8) | cpu->index;
cpu->bus = cpu->pc >> 8;
cpu->index = cpu->sp - 1;
cpu->sp = cpu->pc; // GROSS
cpu->pc = newPc;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = LR35902_CORE_OP2;
cpu->instruction = _LR35902InstructionCALLUpdateSPH;
})
DEFINE_INSTRUCTION_LR35902(CALLUpdatePCL,
cpu->executionState = LR35902_CORE_READ_PC;
cpu->index = cpu->bus;
cpu->instruction = _LR35902InstructionCALLUpdatePCH)
#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_LR35902(CALL ## CONDITION_NAME, \
cpu->condition = CONDITION; \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionCALLUpdatePCL;)
DEFINE_CONDITIONAL_INSTRUCTION_LR35902(CALL)
DEFINE_INSTRUCTION_LR35902(RETFinish,
cpu->sp += 2; /* TODO: Atomic incrementing? */
cpu->pc |= cpu->bus << 8;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = LR35902_CORE_STALL;)
DEFINE_INSTRUCTION_LR35902(RETUpdateSPL,
cpu->index = cpu->sp + 1;
cpu->pc = cpu->bus;
cpu->executionState = LR35902_CORE_MEMORY_LOAD;
cpu->instruction = _LR35902InstructionRETFinish;)
DEFINE_INSTRUCTION_LR35902(RETUpdateSPH,
if (cpu->condition) {
cpu->index = cpu->sp;
cpu->executionState = LR35902_CORE_MEMORY_LOAD;
cpu->instruction = _LR35902InstructionRETUpdateSPL;
})
#define DEFINE_RET_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_LR35902(RET ## CONDITION_NAME, \
cpu->condition = CONDITION; \
cpu->executionState = LR35902_CORE_OP2; \
cpu->instruction = _LR35902InstructionRETUpdateSPH;)
DEFINE_INSTRUCTION_LR35902(RET,
cpu->condition = true;
_LR35902InstructionRETUpdateSPH(cpu);)
DEFINE_INSTRUCTION_LR35902(RETI,
cpu->condition = true;
cpu->irqh.setInterrupts(cpu, true);
_LR35902InstructionRETUpdateSPH(cpu);)
DEFINE_CONDITIONAL_ONLY_INSTRUCTION_LR35902(RET)
#define DEFINE_AND_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(AND ## NAME, \
cpu->a &= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 1;)
#define DEFINE_XOR_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(XOR ## NAME, \
cpu->a ^= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 0;)
#define DEFINE_OR_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(OR ## NAME, \
cpu->a |= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 0;)
#define DEFINE_CP_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(CP ## NAME, \
int diff = cpu->a - OPERAND; \
cpu->f.n = 1; \
cpu->f.z = !(diff & 0xFF); \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
cpu->f.c = diff < 0;)
#define DEFINE_LDB__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDB_ ## NAME, \
cpu->b = OPERAND;)
#define DEFINE_LDC__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDC_ ## NAME, \
cpu->c = OPERAND;)
#define DEFINE_LDD__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDD_ ## NAME, \
cpu->d = OPERAND;)
#define DEFINE_LDE__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDE_ ## NAME, \
cpu->e = OPERAND;)
#define DEFINE_LDH__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDH_ ## NAME, \
cpu->h = OPERAND;)
#define DEFINE_LDL__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDL_ ## NAME, \
cpu->l = OPERAND;)
#define DEFINE_LDHL__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDHL_ ## NAME, \
cpu->bus = OPERAND; \
cpu->index = LR35902ReadHL(cpu); \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
#define DEFINE_LDA__INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(LDA_ ## NAME, \
cpu->a = OPERAND;)
#define DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(A, cpu->a); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(B, cpu->b); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, cpu->c); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(D, cpu->d); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(E, cpu->e); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(H, cpu->h); \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(L, cpu->l);
DEFINE_INSTRUCTION_LR35902(LDHL_Bus, \
cpu->index = LR35902ReadHL(cpu); \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDHL_, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDHL_Bus;)
DEFINE_INSTRUCTION_LR35902(LDHL_SPDelay,
int diff = (int8_t) cpu->bus;
int sum = cpu->sp + diff;
LR35902WriteHL(cpu, sum);
cpu->executionState = LR35902_CORE_STALL;
cpu->f.z = 0;
cpu->f.n = 0;
cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
DEFINE_INSTRUCTION_LR35902(LDHL_SP,
cpu->executionState = LR35902_CORE_READ_PC;
cpu->instruction = _LR35902InstructionLDHL_SPDelay;)
DEFINE_INSTRUCTION_LR35902(LDSP_HL,
cpu->sp = LR35902ReadHL(cpu);
cpu->executionState = LR35902_CORE_STALL;)
#define DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, REG) \
DEFINE_INSTRUCTION_LR35902(NAME ## REG, \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->index = LR35902Read ## REG (cpu); \
cpu->instruction = _LR35902Instruction ## NAME ## Bus;)
#define DEFINE_ALU_INSTRUCTION_LR35902(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Bus, cpu->bus); \
DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, HL) \
DEFINE_INSTRUCTION_LR35902(NAME, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902Instruction ## NAME ## Bus;) \
DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME)
DEFINE_ALU_INSTRUCTION_LR35902(AND);
DEFINE_ALU_INSTRUCTION_LR35902(XOR);
DEFINE_ALU_INSTRUCTION_LR35902(OR);
DEFINE_ALU_INSTRUCTION_LR35902(CP);
static void _LR35902InstructionLDB_Bus(struct LR35902Core*);
static void _LR35902InstructionLDC_Bus(struct LR35902Core*);
static void _LR35902InstructionLDD_Bus(struct LR35902Core*);
static void _LR35902InstructionLDE_Bus(struct LR35902Core*);
static void _LR35902InstructionLDH_Bus(struct LR35902Core*);
static void _LR35902InstructionLDL_Bus(struct LR35902Core*);
static void _LR35902InstructionLDHL_Bus(struct LR35902Core*);
static void _LR35902InstructionLDA_Bus(struct LR35902Core*);
#define DEFINE_ADD_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(ADD ## NAME, \
int diff = cpu->a + OPERAND; \
cpu->f.n = 0; \
cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_ADC_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(ADC ## NAME, \
int diff = cpu->a + OPERAND + cpu->f.c; \
cpu->f.n = 0; \
cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) + cpu->f.c >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_SUB_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(SUB ## NAME, \
int diff = cpu->a - OPERAND; \
cpu->f.n = 1; \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
cpu->f.c = diff < 0; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_SBC_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(SBC ## NAME, \
int diff = cpu->a - OPERAND - cpu->f.c; \
cpu->f.n = 1; \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) - cpu->f.c < 0; \
cpu->f.c = diff < 0; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
DEFINE_ALU_INSTRUCTION_LR35902(LDB_);
DEFINE_ALU_INSTRUCTION_LR35902(LDC_);
DEFINE_ALU_INSTRUCTION_LR35902(LDD_);
DEFINE_ALU_INSTRUCTION_LR35902(LDE_);
DEFINE_ALU_INSTRUCTION_LR35902(LDH_);
DEFINE_ALU_INSTRUCTION_LR35902(LDL_);
DEFINE_ALU_INSTRUCTION_LR35902_NOHL(LDHL_);
DEFINE_ALU_INSTRUCTION_LR35902(LDA_);
DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, BC);
DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, DE);
DEFINE_ALU_INSTRUCTION_LR35902(ADD);
DEFINE_ALU_INSTRUCTION_LR35902(ADC);
DEFINE_ALU_INSTRUCTION_LR35902(SUB);
DEFINE_ALU_INSTRUCTION_LR35902(SBC);
DEFINE_INSTRUCTION_LR35902(ADDSPFinish,
cpu->sp = cpu->index;
cpu->executionState = LR35902_CORE_STALL;)
DEFINE_INSTRUCTION_LR35902(ADDSPDelay,
int diff = (int8_t) cpu->bus;
int sum = cpu->sp + diff;
cpu->index = sum;
cpu->executionState = LR35902_CORE_OP2;
cpu->instruction = _LR35902InstructionADDSPFinish;
cpu->f.z = 0;
cpu->f.n = 0;
cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
DEFINE_INSTRUCTION_LR35902(ADDSP,
cpu->executionState = LR35902_CORE_READ_PC;
cpu->instruction = _LR35902InstructionADDSPDelay;)
DEFINE_INSTRUCTION_LR35902(LDBCDelay, \
cpu->c = cpu->bus; \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDB_Bus;)
DEFINE_INSTRUCTION_LR35902(LDBC, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDBCDelay;)
DEFINE_INSTRUCTION_LR35902(LDBC_A, \
cpu->index = LR35902ReadBC(cpu); \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDDEDelay, \
cpu->e = cpu->bus; \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDD_Bus;)
DEFINE_INSTRUCTION_LR35902(LDDE, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDDEDelay;)
DEFINE_INSTRUCTION_LR35902(LDDE_A, \
cpu->index = LR35902ReadDE(cpu); \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDHLDelay, \
cpu->l = cpu->bus; \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDH_Bus;)
DEFINE_INSTRUCTION_LR35902(LDHL, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDHLDelay;)
DEFINE_INSTRUCTION_LR35902(LDSPFinish, cpu->sp |= cpu->bus << 8;)
DEFINE_INSTRUCTION_LR35902(LDSPDelay, \
cpu->sp = cpu->bus; \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDSPFinish;)
DEFINE_INSTRUCTION_LR35902(LDSP, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDSPDelay;)
DEFINE_INSTRUCTION_LR35902(LDIHLA, \
cpu->index = LR35902ReadHL(cpu); \
LR35902WriteHL(cpu, cpu->index + 1); \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDDHLA, \
cpu->index = LR35902ReadHL(cpu); \
LR35902WriteHL(cpu, cpu->index - 1); \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDA_IHL, \
cpu->index = LR35902ReadHL(cpu); \
LR35902WriteHL(cpu, cpu->index + 1); \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902InstructionLDA_Bus;)
DEFINE_INSTRUCTION_LR35902(LDA_DHL, \
cpu->index = LR35902ReadHL(cpu); \
LR35902WriteHL(cpu, cpu->index - 1); \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902InstructionLDA_Bus;)
DEFINE_INSTRUCTION_LR35902(LDIAFinish, \
cpu->index |= cpu->bus << 8;
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDIADelay, \
cpu->index = cpu->bus;
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDIAFinish;)
DEFINE_INSTRUCTION_LR35902(LDIA, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDIADelay;)
DEFINE_INSTRUCTION_LR35902(LDAIFinish, \
cpu->index |= cpu->bus << 8;
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902InstructionLDA_Bus;)
DEFINE_INSTRUCTION_LR35902(LDAIDelay, \
cpu->index = cpu->bus;
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDAIFinish;)
DEFINE_INSTRUCTION_LR35902(LDAI, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDAIDelay;)
DEFINE_INSTRUCTION_LR35902(LDAIOC, \
cpu->index = 0xFF00 | cpu->c; \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902InstructionLDA_Bus;)
DEFINE_INSTRUCTION_LR35902(LDIOCA, \
cpu->index = 0xFF00 | cpu->c; \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDAIODelay, \
cpu->index = 0xFF00 | cpu->bus; \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902InstructionLDA_Bus;)
DEFINE_INSTRUCTION_LR35902(LDAIO, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDAIODelay;)
DEFINE_INSTRUCTION_LR35902(LDIOADelay, \
cpu->index = 0xFF00 | cpu->bus; \
cpu->bus = cpu->a; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDIOA, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionLDIOADelay;)
DEFINE_INSTRUCTION_LR35902(LDISPStoreH,
++cpu->index;
cpu->bus = cpu->sp >> 8;
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionNOP;)
DEFINE_INSTRUCTION_LR35902(LDISPStoreL,
cpu->index |= cpu->bus << 8;
cpu->bus = cpu->sp;
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionLDISPStoreH;)
DEFINE_INSTRUCTION_LR35902(LDISPReadAddr,
cpu->index = cpu->bus;
cpu->executionState = LR35902_CORE_READ_PC;
cpu->instruction = _LR35902InstructionLDISPStoreL;)
DEFINE_INSTRUCTION_LR35902(LDISP,
cpu->executionState = LR35902_CORE_READ_PC;
cpu->instruction = _LR35902InstructionLDISPReadAddr;)
#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
DEFINE_INSTRUCTION_LR35902(INC ## REG, \
uint16_t reg = LR35902Read ## REG (cpu); \
LR35902Write ## REG (cpu, reg + 1); \
cpu->executionState = LR35902_CORE_STALL;) \
DEFINE_INSTRUCTION_LR35902(DEC ## REG, \
uint16_t reg = LR35902Read ## REG (cpu); \
LR35902Write ## REG (cpu, reg - 1); \
cpu->executionState = LR35902_CORE_STALL;)
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
#define DEFINE_ADD_HL_INSTRUCTION_LR35902(REG, L, H) \
DEFINE_INSTRUCTION_LR35902(ADDHL_ ## REG ## Finish, \
int diff = H + cpu->h + cpu->f.c; \
cpu->f.n = 0; \
cpu->f.h = (H & 0xF) + (cpu->h & 0xF) + cpu->f.c >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->h = diff;) \
DEFINE_INSTRUCTION_LR35902(ADDHL_ ## REG, \
int diff = L + cpu->l; \
cpu->l = diff; \
cpu->f.c = diff >= 0x100; \
cpu->executionState = LR35902_CORE_OP2; \
cpu->instruction = _LR35902InstructionADDHL_ ## REG ## Finish;)
DEFINE_ADD_HL_INSTRUCTION_LR35902(BC, cpu->c, cpu->b);
DEFINE_ADD_HL_INSTRUCTION_LR35902(DE, cpu->e, cpu->d);
DEFINE_ADD_HL_INSTRUCTION_LR35902(HL, cpu->l, cpu->h);
DEFINE_ADD_HL_INSTRUCTION_LR35902(SP, (cpu->sp & 0xFF), (cpu->sp >> 8));
#define DEFINE_INC_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(INC ## NAME, \
int diff = OPERAND + 1; \
cpu->f.h = (OPERAND & 0xF) == 0xF; \
OPERAND = diff; \
cpu->f.n = 0; \
cpu->f.z = !OPERAND;)
#define DEFINE_DEC_INSTRUCTION_LR35902(NAME, OPERAND) \
DEFINE_INSTRUCTION_LR35902(DEC ## NAME, \
int diff = OPERAND - 1; \
cpu->f.h = (OPERAND & 0xF) == 0x0; \
OPERAND = diff; \
cpu->f.n = 1; \
cpu->f.z = !OPERAND;)
DEFINE_ALU_INSTRUCTION_LR35902_NOHL(INC);
DEFINE_ALU_INSTRUCTION_LR35902_NOHL(DEC);
DEFINE_INSTRUCTION_LR35902(INC_HLDelay,
int diff = cpu->bus + 1;
cpu->f.n = 0;
cpu->f.h = (cpu->bus & 0xF) == 0xF;
cpu->bus = diff;
cpu->f.z = !cpu->bus;
cpu->instruction = _LR35902InstructionNOP;
cpu->executionState = LR35902_CORE_MEMORY_STORE;)
DEFINE_INSTRUCTION_LR35902(INC_HL,
cpu->index = LR35902ReadHL(cpu);
cpu->instruction = _LR35902InstructionINC_HLDelay;
cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
DEFINE_INSTRUCTION_LR35902(DEC_HLDelay,
int diff = cpu->bus - 1;
cpu->f.n = 1;
cpu->f.h = (cpu->bus & 0xF) == 0;
cpu->bus = diff;
cpu->f.z = !cpu->bus;
cpu->instruction = _LR35902InstructionNOP;
cpu->executionState = LR35902_CORE_MEMORY_STORE;)
DEFINE_INSTRUCTION_LR35902(DEC_HL,
cpu->index = LR35902ReadHL(cpu);
cpu->instruction = _LR35902InstructionDEC_HLDelay;
cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
DEFINE_INSTRUCTION_LR35902(INCSP,
++cpu->sp;
cpu->executionState = LR35902_CORE_STALL;)
DEFINE_INSTRUCTION_LR35902(DECSP,
--cpu->sp;
cpu->executionState = LR35902_CORE_STALL;)
DEFINE_INSTRUCTION_LR35902(SCF,
cpu->f.c = 1;
cpu->f.h = 0;
cpu->f.n = 0;)
DEFINE_INSTRUCTION_LR35902(CCF,
cpu->f.c ^= 1;
cpu->f.h = 0;
cpu->f.n = 0;)
DEFINE_INSTRUCTION_LR35902(CPL_,
cpu->a ^= 0xFF;
cpu->f.h = 1;
cpu->f.n = 1;)
DEFINE_INSTRUCTION_LR35902(DAA,
if (cpu->f.n) {
if (cpu->f.h) {
cpu->a += 0xFA;
}
if (cpu->f.c) {
cpu->a += 0xA0;
}
} else {
int a = cpu->a;
if ((cpu->a & 0xF) > 0x9 || cpu->f.h) {
a += 0x6;
}
if ((a & 0x1F0) > 0x90 || cpu->f.c) {
a += 0x60;
cpu->f.c = 1;
} else {
cpu->f.c = 0;
}
cpu->a = a;
}
cpu->f.h = 0;
cpu->f.z = !cpu->a;)
#define DEFINE_POPPUSH_INSTRUCTION_LR35902(REG, HH, H, L) \
DEFINE_INSTRUCTION_LR35902(POP ## REG ## Delay, \
cpu-> L = cpu->bus; \
cpu->f.packed &= 0xF0; \
cpu->index = cpu->sp; \
++cpu->sp; \
cpu->instruction = _LR35902InstructionLD ## HH ## _Bus; \
cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
DEFINE_INSTRUCTION_LR35902(POP ## REG, \
cpu->index = cpu->sp; \
++cpu->sp; \
cpu->instruction = _LR35902InstructionPOP ## REG ## Delay; \
cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Finish, \
cpu->executionState = LR35902_CORE_STALL;) \
DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Delay, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu-> L; \
cpu->instruction = _LR35902InstructionPUSH ## REG ## Finish; \
cpu->executionState = LR35902_CORE_MEMORY_STORE;) \
DEFINE_INSTRUCTION_LR35902(PUSH ## REG, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu-> H; \
cpu->instruction = _LR35902InstructionPUSH ## REG ## Delay; \
cpu->executionState = LR35902_CORE_MEMORY_STORE;)
DEFINE_POPPUSH_INSTRUCTION_LR35902(BC, B, b, c);
DEFINE_POPPUSH_INSTRUCTION_LR35902(DE, D, d, e);
DEFINE_POPPUSH_INSTRUCTION_LR35902(HL, H, h, l);
DEFINE_POPPUSH_INSTRUCTION_LR35902(AF, A, a, f.packed);
#define DEFINE_CB_2_INSTRUCTION_LR35902(NAME, WB, BODY) \
DEFINE_INSTRUCTION_LR35902(NAME ## B, uint8_t reg = cpu->b; BODY; cpu->b = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## C, uint8_t reg = cpu->c; BODY; cpu->c = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## D, uint8_t reg = cpu->d; BODY; cpu->d = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## E, uint8_t reg = cpu->e; BODY; cpu->e = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## H, uint8_t reg = cpu->h; BODY; cpu->h = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## L, uint8_t reg = cpu->l; BODY; cpu->l = reg) \
DEFINE_INSTRUCTION_LR35902(NAME ## HLDelay, \
uint8_t reg = cpu->bus; \
BODY; \
cpu->bus = reg; \
cpu->executionState = WB; \
cpu->instruction = _LR35902InstructionNOP;) \
DEFINE_INSTRUCTION_LR35902(NAME ## HL, \
cpu->index = LR35902ReadHL(cpu); \
cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
cpu->instruction = _LR35902Instruction ## NAME ## HLDelay;) \
DEFINE_INSTRUCTION_LR35902(NAME ## A, uint8_t reg = cpu->a; BODY; cpu->a = reg)
#define DEFINE_CB_INSTRUCTION_LR35902(NAME, WB, BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 0, WB, uint8_t bit = 1; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 1, WB, uint8_t bit = 2; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 2, WB, uint8_t bit = 4; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 3, WB, uint8_t bit = 8; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 4, WB, uint8_t bit = 16; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 5, WB, uint8_t bit = 32; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 6, WB, uint8_t bit = 64; BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME ## 7, WB, uint8_t bit = 128; BODY)
DEFINE_CB_INSTRUCTION_LR35902(BIT, LR35902_CORE_FETCH, cpu->f.n = 0; cpu->f.h = 1; cpu->f.z = !(reg & bit))
DEFINE_CB_INSTRUCTION_LR35902(RES, LR35902_CORE_MEMORY_STORE, reg &= ~bit)
DEFINE_CB_INSTRUCTION_LR35902(SET, LR35902_CORE_MEMORY_STORE, reg |= bit)
#define DEFINE_CB_ALU_INSTRUCTION_LR35902(NAME, BODY) \
DEFINE_CB_2_INSTRUCTION_LR35902(NAME, LR35902_CORE_MEMORY_STORE, \
BODY; \
cpu->f.n = 0; \
cpu->f.h = 0; \
cpu->f.z = !reg;)
DEFINE_CB_ALU_INSTRUCTION_LR35902(RL, int wide = (reg << 1) | cpu->f.c; reg = wide; cpu->f.c = wide >> 8)
DEFINE_CB_ALU_INSTRUCTION_LR35902(RLC, reg = (reg << 1) | (reg >> 7); cpu->f.c = reg & 1)
DEFINE_CB_ALU_INSTRUCTION_LR35902(RR, int low = reg & 1; reg = (reg >> 1) | (cpu->f.c << 7); cpu->f.c = low)
DEFINE_CB_ALU_INSTRUCTION_LR35902(RRC, int low = reg & 1; reg = (reg >> 1) | (low << 7); cpu->f.c = low)
DEFINE_CB_ALU_INSTRUCTION_LR35902(SLA, cpu->f.c = reg >> 7; reg <<= 1)
DEFINE_CB_ALU_INSTRUCTION_LR35902(SRA, cpu->f.c = reg & 1; reg = ((int8_t) reg) >> 1)
DEFINE_CB_ALU_INSTRUCTION_LR35902(SRL, cpu->f.c = reg & 1; reg >>= 1)
DEFINE_CB_ALU_INSTRUCTION_LR35902(SWAP, reg = (reg << 4) | (reg >> 4); cpu->f.c = 0)
DEFINE_INSTRUCTION_LR35902(RLA_,
int wide = (cpu->a << 1) | cpu->f.c;
cpu->a = wide;
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = wide >> 8;)
DEFINE_INSTRUCTION_LR35902(RLCA_,
cpu->a = (cpu->a << 1) | (cpu->a >> 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = cpu->a & 1;)
DEFINE_INSTRUCTION_LR35902(RRA_,
int low = cpu->a & 1;
cpu->a = (cpu->a >> 1) | (cpu->f.c << 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = low;)
DEFINE_INSTRUCTION_LR35902(RRCA_,
int low = cpu->a & 1;
cpu->a = (cpu->a >> 1) | (low << 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = low;)
DEFINE_INSTRUCTION_LR35902(DI, cpu->irqh.setInterrupts(cpu, false));
DEFINE_INSTRUCTION_LR35902(EI, cpu->irqh.setInterrupts(cpu, true));
DEFINE_INSTRUCTION_LR35902(HALT, cpu->irqh.halt(cpu));
#define DEFINE_RST_INSTRUCTION_LR35902(VEC) \
DEFINE_INSTRUCTION_LR35902(RST ## VEC ## UpdateSPL, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu->pc; \
cpu->pc = 0x ## VEC; \
cpu->memory.setActiveRegion(cpu, cpu->pc); \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionNOP;) \
DEFINE_INSTRUCTION_LR35902(RST ## VEC ## UpdateSPH, \
--cpu->sp;\
cpu->index = cpu->sp; \
cpu->bus = cpu->pc >> 8; \
cpu->executionState = LR35902_CORE_MEMORY_STORE; \
cpu->instruction = _LR35902InstructionRST ## VEC ## UpdateSPL;) \
DEFINE_INSTRUCTION_LR35902(RST ## VEC, \
cpu->executionState = LR35902_CORE_OP2; \
cpu->instruction = _LR35902InstructionRST ## VEC ## UpdateSPH;)
DEFINE_RST_INSTRUCTION_LR35902(00);
DEFINE_RST_INSTRUCTION_LR35902(08);
DEFINE_RST_INSTRUCTION_LR35902(10);
DEFINE_RST_INSTRUCTION_LR35902(18);
DEFINE_RST_INSTRUCTION_LR35902(20);
DEFINE_RST_INSTRUCTION_LR35902(28);
DEFINE_RST_INSTRUCTION_LR35902(30);
DEFINE_RST_INSTRUCTION_LR35902(38);
DEFINE_INSTRUCTION_LR35902(ILL, cpu->irqh.hitIllegal(cpu));
DEFINE_INSTRUCTION_LR35902(STOP2, cpu->irqh.stop(cpu));
DEFINE_INSTRUCTION_LR35902(STOP, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionSTOP2;)
static const LR35902Instruction _lr35902CBInstructionTable[0x100] = {
DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Instruction)
};
DEFINE_INSTRUCTION_LR35902(CBDelegate, _lr35902CBInstructionTable[cpu->bus](cpu))
DEFINE_INSTRUCTION_LR35902(CB, \
cpu->executionState = LR35902_CORE_READ_PC; \
cpu->instruction = _LR35902InstructionCBDelegate;)
const LR35902Instruction _lr35902InstructionTable[0x100] = {
DECLARE_LR35902_EMITTER_BLOCK(_LR35902Instruction)
};

View File

@ -62,7 +62,7 @@ void free(void*);
#include <mgba/internal/gba/renderers/cache-set.h>
#endif
#ifdef M_CORE_GB
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gba/input.h>
#include <mgba/internal/gb/renderers/cache-set.h>

View File

@ -37,7 +37,7 @@ ffi.set_source("mgba._pylib", """
#include <mgba/internal/gba/gba.h>
#include <mgba/internal/gba/input.h>
#include <mgba/internal/gba/renderers/cache-set.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/renderers/cache-set.h>
#include <mgba-util/png-io.h>

View File

@ -4,7 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from ._pylib import ffi, lib # pylint: disable=no-name-in-module
from .lr35902 import LR35902Core
from .sm83 import SM83Core
from .core import Core, needs_reset
from .memory import Memory
from .tile import Sprite
@ -25,7 +25,7 @@ class GB(Core):
super(GB, self).__init__(native)
self._native = ffi.cast("struct GB*", native.board)
self.sprites = GBObjs(self)
self.cpu = LR35902Core(self._core.cpu)
self.cpu = SM83Core(self._core.cpu)
self.memory = None
self._link = None

View File

@ -6,10 +6,10 @@
from ._pylib import ffi # pylint: disable=no-name-in-module
class LR35902Core:
class SM83Core:
# pylint: disable=invalid-name
def __init__(self, native):
self._native = ffi.cast("struct LR35902Core*", native)
self._native = ffi.cast("struct SM83Core*", native)
@property
def a(self):

View File

@ -11,7 +11,7 @@
#include <mgba/internal/arm/arm.h>
#endif
#ifdef M_CORE_GB
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#endif
#include <QFontDatabase>
@ -94,7 +94,7 @@ void RegisterView::updateRegisters() {
#endif
#ifdef M_CORE_GB
case PLATFORM_GB:
updateRegistersLR35902();
updateRegistersSM83();
break;
#endif
default:
@ -127,9 +127,9 @@ void RegisterView::updateRegistersARM() {
#endif
#ifdef M_CORE_GB
void RegisterView::updateRegistersLR35902() {
void RegisterView::updateRegistersSM83() {
CoreController::Interrupter interrupter(m_controller);
struct LR35902Core* core = static_cast<LR35902Core*>(m_controller->thread()->core->cpu);
struct SM83Core* core = static_cast<SM83Core*>(m_controller->thread()->core->cpu);
m_registers["a"]->setText(QString("%1").arg((uint8_t) core->a, 2, 16, QChar('0')).toUpper());
m_registers["f"]->setText(QString("%1").arg((uint8_t) core->f.packed, 2, 16, QChar('0')).toUpper());
m_registers["b"]->setText(QString("%1").arg((uint8_t) core->b, 2, 16, QChar('0')).toUpper());

View File

@ -31,7 +31,7 @@ private:
void updateRegistersARM();
#endif
#ifdef M_CORE_GB
void updateRegistersLR35902();
void updateRegistersSM83();
#endif
QMap<QString, QLabel*> m_registers;

16
src/sm83/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
include(ExportDirectory)
set(SOURCE_FILES
decoder.c
isa-sm83.c
sm83.c)
set(DEBUGGER_FILES
debugger/cli-debugger.c
debugger/debugger.c
debugger/memory-debugger.c)
source_group("SM83 core" FILES ${SOURCE_FILES})
source_group("SM83 debugger" FILES ${DEBUGGER_FILES})
export_directory(SM83 SOURCE_FILES)
export_directory(SM83_DEBUGGER DEBUGGER_FILES)

View File

@ -3,20 +3,20 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/debugger/cli-debugger.h>
#include <mgba/internal/sm83/debugger/cli-debugger.h>
#include <mgba/core/core.h>
#include <mgba/internal/debugger/cli-debugger.h>
#include <mgba/internal/lr35902/decoder.h>
#include <mgba/internal/lr35902/debugger/debugger.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/decoder.h>
#include <mgba/internal/sm83/debugger/debugger.h>
#include <mgba/internal/sm83/sm83.h>
static void _printStatus(struct CLIDebuggerSystem*);
static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVector* dv);
static uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address, int segment);
static struct CLIDebuggerCommandSummary _lr35902Commands[] = {
static struct CLIDebuggerCommandSummary _sm83Commands[] = {
{ 0, 0, 0, 0 }
};
@ -29,7 +29,7 @@ static inline void _printFlags(struct CLIDebuggerBackend* be, union FlagRegister
}
static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVector* dv) {
struct LR35902Core* cpu = debugger->p->d.core->cpu;
struct SM83Core* cpu = debugger->p->d.core->cpu;
uint16_t address;
int segment = -1;
@ -57,7 +57,7 @@ static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVect
static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address, int segment) {
struct CLIDebuggerBackend* be = debugger->backend;
struct LR35902InstructionInfo info = {0};
struct SM83InstructionInfo info = {0};
char disassembly[48];
char* disPtr = disassembly;
if (segment >= 0) {
@ -70,18 +70,18 @@ static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address
instruction = debugger->d.core->rawRead8(debugger->d.core, address, segment);
disPtr += snprintf(disPtr, sizeof(disassembly) - (disPtr - disassembly), "%02X", instruction);
++address;
bytesRemaining += LR35902Decode(instruction, &info);
bytesRemaining += SM83Decode(instruction, &info);
};
disPtr[0] = '\t';
++disPtr;
LR35902Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly));
SM83Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly));
be->printf(be, "%s\n", disassembly);
return address;
}
static void _printStatus(struct CLIDebuggerSystem* debugger) {
struct CLIDebuggerBackend* be = debugger->p->backend;
struct LR35902Core* cpu = debugger->p->d.core->cpu;
struct SM83Core* cpu = debugger->p->d.core->cpu;
be->printf(be, "A: %02X F: %02X (AF: %04X)\n", cpu->a, cpu->f.packed, cpu->af);
be->printf(be, "B: %02X C: %02X (BC: %04X)\n", cpu->b, cpu->c, cpu->bc);
be->printf(be, "D: %02X E: %02X (DE: %04X)\n", cpu->d, cpu->e, cpu->de);
@ -89,7 +89,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
_printFlags(be, cpu->f);
struct LR35902Debugger* platDebugger = (struct LR35902Debugger*) debugger->p->d.platform;
struct SM83Debugger* platDebugger = (struct SM83Debugger*) debugger->p->d.platform;
size_t i;
for (i = 0; platDebugger->segments[i].name; ++i) {
be->printf(be, "%s%s: %02X", i ? " " : "", platDebugger->segments[i].name, cpu->memory.currentSegment(cpu, platDebugger->segments[i].start));
@ -103,10 +103,10 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
_printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc));
}
void LR35902CLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
void SM83CLIDebuggerCreate(struct CLIDebuggerSystem* debugger) {
debugger->printStatus = _printStatus;
debugger->disassemble = _disassemble;
debugger->platformName = "SM83";
debugger->platformCommands = _lr35902Commands;
debugger->platformCommands = _sm83Commands;
debugger->platformCommandAliases = NULL;
}

View File

@ -3,15 +3,15 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/debugger/debugger.h>
#include <mgba/internal/sm83/debugger/debugger.h>
#include <mgba/core/core.h>
#include <mgba/internal/debugger/parser.h>
#include <mgba/internal/lr35902/decoder.h>
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/lr35902/debugger/memory-debugger.h>
#include <mgba/internal/sm83/decoder.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/sm83/debugger/memory-debugger.h>
static struct mBreakpoint* _lookupBreakpoint(struct mBreakpointList* breakpoints, struct LR35902Core* cpu) {
static struct mBreakpoint* _lookupBreakpoint(struct mBreakpointList* breakpoints, struct SM83Core* cpu) {
size_t i;
for (i = 0; i < mBreakpointListSize(breakpoints); ++i) {
struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i);
@ -39,8 +39,8 @@ static void _destroyWatchpoint(struct mWatchpoint* watchpoint) {
}
}
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static void SM83DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
struct mBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu);
if (!breakpoint) {
return;
@ -59,43 +59,43 @@ static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info);
}
static void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform);
static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform);
static void SM83DebuggerInit(void* cpu, struct mDebuggerPlatform* platform);
static void SM83DebuggerDeinit(struct mDebuggerPlatform* platform);
static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
static void SM83DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, const struct mBreakpoint*);
static void LR35902DebuggerListBreakpoints(struct mDebuggerPlatform*, struct mBreakpointList*);
static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, ssize_t id);
static ssize_t LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform*, const struct mWatchpoint*);
static void LR35902DebuggerListWatchpoints(struct mDebuggerPlatform*, struct mWatchpointList*);
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
static void LR35902DebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
static bool LR35902DebuggerGetRegister(struct mDebuggerPlatform*, const char* name, int32_t* value);
static bool LR35902DebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value);
static ssize_t SM83DebuggerSetBreakpoint(struct mDebuggerPlatform*, const struct mBreakpoint*);
static void SM83DebuggerListBreakpoints(struct mDebuggerPlatform*, struct mBreakpointList*);
static bool SM83DebuggerClearBreakpoint(struct mDebuggerPlatform*, ssize_t id);
static ssize_t SM83DebuggerSetWatchpoint(struct mDebuggerPlatform*, const struct mWatchpoint*);
static void SM83DebuggerListWatchpoints(struct mDebuggerPlatform*, struct mWatchpointList*);
static void SM83DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
static bool SM83DebuggerHasBreakpoints(struct mDebuggerPlatform*);
static void SM83DebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length);
static bool SM83DebuggerGetRegister(struct mDebuggerPlatform*, const char* name, int32_t* value);
static bool SM83DebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value);
struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) {
struct LR35902Debugger* platform = malloc(sizeof(struct LR35902Debugger));
platform->d.entered = LR35902DebuggerEnter;
platform->d.init = LR35902DebuggerInit;
platform->d.deinit = LR35902DebuggerDeinit;
platform->d.setBreakpoint = LR35902DebuggerSetBreakpoint;
platform->d.listBreakpoints = LR35902DebuggerListBreakpoints;
platform->d.clearBreakpoint = LR35902DebuggerClearBreakpoint;
platform->d.setWatchpoint = LR35902DebuggerSetWatchpoint;
platform->d.listWatchpoints = LR35902DebuggerListWatchpoints;
platform->d.checkBreakpoints = LR35902DebuggerCheckBreakpoints;
platform->d.hasBreakpoints = LR35902DebuggerHasBreakpoints;
platform->d.trace = LR35902DebuggerTrace;
platform->d.getRegister = LR35902DebuggerGetRegister;
platform->d.setRegister = LR35902DebuggerSetRegister;
struct mDebuggerPlatform* SM83DebuggerPlatformCreate(void) {
struct SM83Debugger* platform = malloc(sizeof(struct SM83Debugger));
platform->d.entered = SM83DebuggerEnter;
platform->d.init = SM83DebuggerInit;
platform->d.deinit = SM83DebuggerDeinit;
platform->d.setBreakpoint = SM83DebuggerSetBreakpoint;
platform->d.listBreakpoints = SM83DebuggerListBreakpoints;
platform->d.clearBreakpoint = SM83DebuggerClearBreakpoint;
platform->d.setWatchpoint = SM83DebuggerSetWatchpoint;
platform->d.listWatchpoints = SM83DebuggerListWatchpoints;
platform->d.checkBreakpoints = SM83DebuggerCheckBreakpoints;
platform->d.hasBreakpoints = SM83DebuggerHasBreakpoints;
platform->d.trace = SM83DebuggerTrace;
platform->d.getRegister = SM83DebuggerGetRegister;
platform->d.setRegister = SM83DebuggerSetRegister;
platform->printStatus = NULL;
return &platform->d;
}
void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
void SM83DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) {
struct SM83Debugger* debugger = (struct SM83Debugger*) platform;
debugger->cpu = cpu;
debugger->originalMemory = debugger->cpu->memory;
mBreakpointListInit(&debugger->breakpoints, 0);
@ -103,8 +103,8 @@ void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) {
debugger->nextId = 1;
}
void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
void SM83DebuggerDeinit(struct mDebuggerPlatform* platform) {
struct SM83Debugger* debugger = (struct SM83Debugger*) platform;
size_t i;
for (i = 0; i < mBreakpointListSize(&debugger->breakpoints); ++i) {
_destroyBreakpoint(mBreakpointListGetPointer(&debugger->breakpoints, i));
@ -117,11 +117,11 @@ void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) {
mWatchpointListDeinit(&debugger->watchpoints);
}
static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
static void SM83DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
UNUSED(reason);
UNUSED(info);
struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
struct LR35902Core* cpu = debugger->cpu;
struct SM83Debugger* debugger = (struct SM83Debugger*) platform;
struct SM83Core* cpu = debugger->cpu;
cpu->nextEvent = cpu->cycles;
if (debugger->d.p->entered) {
@ -129,8 +129,8 @@ static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebug
}
}
static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struct mBreakpoint* info) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static ssize_t SM83DebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struct mBreakpoint* info) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
struct mBreakpoint* breakpoint = mBreakpointListAppend(&debugger->breakpoints);
*breakpoint = *info;
breakpoint->id = debugger->nextId;
@ -139,8 +139,8 @@ static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, const s
}
static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static bool SM83DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
size_t i;
struct mBreakpointList* breakpoints = &debugger->breakpoints;
@ -160,7 +160,7 @@ static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t
_destroyWatchpoint(watchpoint);
mWatchpointListShift(watchpoints, i, 1);
if (!mWatchpointListSize(&debugger->watchpoints)) {
LR35902DebuggerRemoveMemoryShim(debugger);
SM83DebuggerRemoveMemoryShim(debugger);
}
return true;
}
@ -168,15 +168,15 @@ static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t
return false;
}
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform* d) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static bool SM83DebuggerHasBreakpoints(struct mDebuggerPlatform* d) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
return mBreakpointListSize(&debugger->breakpoints) || mWatchpointListSize(&debugger->watchpoints);
}
static ssize_t LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform* d, const struct mWatchpoint* info) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static ssize_t SM83DebuggerSetWatchpoint(struct mDebuggerPlatform* d, const struct mWatchpoint* info) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
if (!mWatchpointListSize(&debugger->watchpoints)) {
LR35902DebuggerInstallMemoryShim(debugger);
SM83DebuggerInstallMemoryShim(debugger);
}
struct mWatchpoint* watchpoint = mWatchpointListAppend(&debugger->watchpoints);
*watchpoint = *info;
@ -185,25 +185,25 @@ static ssize_t LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform* d, const s
return watchpoint->id;
}
static void LR35902DebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static void SM83DebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
mBreakpointListClear(list);
mBreakpointListCopy(list, &debugger->breakpoints);
}
static void LR35902DebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
static void SM83DebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
mWatchpointListClear(list);
mWatchpointListCopy(list, &debugger->watchpoints);
}
static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* length) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
struct LR35902Core* cpu = debugger->cpu;
static void SM83DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* length) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
struct SM83Core* cpu = debugger->cpu;
char disassembly[64];
struct LR35902InstructionInfo info = {{0}};
struct SM83InstructionInfo info = {{0}};
char* disPtr = disassembly;
uint8_t instruction;
uint16_t address = cpu->pc;
@ -212,12 +212,12 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t*
instruction = debugger->d.p->core->rawRead8(debugger->d.p->core, address, -1);
disPtr += snprintf(disPtr, sizeof(disassembly) - (disPtr - disassembly), "%02X", instruction);
++address;
bytesRemaining += LR35902Decode(instruction, &info);
bytesRemaining += SM83Decode(instruction, &info);
};
disPtr[0] = ':';
disPtr[1] = ' ';
disPtr += 2;
LR35902Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly));
SM83Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly));
*length = snprintf(out, *length, "A: %02X F: %02X B: %02X C: %02X D: %02X E: %02X H: %02X L: %02X SP: %04X PC: %02X:%04X | %s",
cpu->a, cpu->f.packed, cpu->b, cpu->c,
@ -225,9 +225,9 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t*
cpu->sp, cpu->memory.currentSegment(cpu, cpu->pc), cpu->pc, disassembly);
}
bool LR35902DebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, int32_t* value) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
struct LR35902Core* cpu = debugger->cpu;
bool SM83DebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, int32_t* value) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
struct SM83Core* cpu = debugger->cpu;
if (strcmp(name, "a") == 0) {
*value = cpu->a;
@ -288,9 +288,9 @@ bool LR35902DebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, i
return false;
}
bool LR35902DebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32_t value) {
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
struct LR35902Core* cpu = debugger->cpu;
bool SM83DebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32_t value) {
struct SM83Debugger* debugger = (struct SM83Debugger*) d;
struct SM83Core* cpu = debugger->cpu;
if (strcmp(name, "a") == 0) {
cpu->a = value;

View File

@ -3,16 +3,16 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/debugger/memory-debugger.h>
#include <mgba/internal/sm83/debugger/memory-debugger.h>
#include <mgba/internal/debugger/parser.h>
#include <mgba/internal/lr35902/debugger/debugger.h>
#include <mgba/internal/sm83/debugger/debugger.h>
#include <mgba-util/math.h>
#include <string.h>
static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue);
static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue);
#define FIND_DEBUGGER(DEBUGGER, CPU) \
do { \
@ -20,7 +20,7 @@ static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address
size_t i; \
for (i = 0; i < CPU->numComponents; ++i) { \
if (CPU->components[i]->id == DEBUGGER_ID) { \
DEBUGGER = (struct LR35902Debugger*) ((struct mDebugger*) cpu->components[i])->platform; \
DEBUGGER = (struct SM83Debugger*) ((struct mDebugger*) cpu->components[i])->platform; \
goto debuggerFound; \
} \
} \
@ -30,7 +30,7 @@ static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address
#define CREATE_WATCHPOINT_SHIM(NAME, RW, VALUE, RETURN, TYPES, ...) \
static RETURN DebuggerShim_ ## NAME TYPES { \
struct LR35902Debugger* debugger; \
struct SM83Debugger* debugger; \
FIND_DEBUGGER(debugger, cpu); \
struct mDebuggerEntryInfo info; \
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_ ## RW, VALUE)) { \
@ -39,10 +39,10 @@ static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
}
CREATE_WATCHPOINT_SHIM(load8, READ, 0, uint8_t, (struct LR35902Core* cpu, uint16_t address), address)
CREATE_WATCHPOINT_SHIM(store8, WRITE, value, void, (struct LR35902Core* cpu, uint16_t address, int8_t value), address, value)
CREATE_WATCHPOINT_SHIM(load8, READ, 0, uint8_t, (struct SM83Core* cpu, uint16_t address), address)
CREATE_WATCHPOINT_SHIM(store8, WRITE, value, void, (struct SM83Core* cpu, uint16_t address, int8_t value), address, value)
static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue) {
static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue) {
struct mWatchpoint* watchpoint;
size_t i;
for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) {
@ -67,13 +67,13 @@ static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address
return false;
}
void LR35902DebuggerInstallMemoryShim(struct LR35902Debugger* debugger) {
void SM83DebuggerInstallMemoryShim(struct SM83Debugger* debugger) {
debugger->originalMemory = debugger->cpu->memory;
debugger->cpu->memory.store8 = DebuggerShim_store8;
debugger->cpu->memory.load8 = DebuggerShim_load8;
}
void LR35902DebuggerRemoveMemoryShim(struct LR35902Debugger* debugger) {
void SM83DebuggerRemoveMemoryShim(struct SM83Debugger* debugger) {
debugger->cpu->memory.store8 = debugger->originalMemory.store8;
debugger->cpu->memory.load8 = debugger->originalMemory.load8;
}

580
src/sm83/decoder.c Normal file
View File

@ -0,0 +1,580 @@
/* Copyright (c) 2013-2017 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/sm83/decoder.h>
#include <mgba/internal/sm83/emitter-sm83.h>
#include <mgba/internal/sm83/sm83.h>
typedef size_t (*SM83Decoder)(uint8_t opcode, struct SM83InstructionInfo* info);
#define DEFINE_DECODER_SM83(NAME, BODY) \
static size_t _SM83Decode ## NAME (uint8_t opcode, struct SM83InstructionInfo* info) { \
UNUSED(opcode); \
info->mnemonic = SM83_MN_RST; \
BODY; \
return 0; \
}
DEFINE_DECODER_SM83(NOP, info->mnemonic = SM83_MN_NOP;)
#define DEFINE_LD_DECODER_SM83_NOHL(NAME) \
DEFINE_DECODER_SM83(LD ## NAME ## _A, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_A) \
DEFINE_DECODER_SM83(LD ## NAME ## _B, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_B) \
DEFINE_DECODER_SM83(LD ## NAME ## _C, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_C) \
DEFINE_DECODER_SM83(LD ## NAME ## _D, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_D) \
DEFINE_DECODER_SM83(LD ## NAME ## _E, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_E) \
DEFINE_DECODER_SM83(LD ## NAME ## _H, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_H) \
DEFINE_DECODER_SM83(LD ## NAME ## _L, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_L)
#define DEFINE_LD_DECODER_SM83_MEM(NAME, REG) \
DEFINE_DECODER_SM83(LD ## NAME ## _ ## REG, info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
info->op2.reg = SM83_REG_ ## REG; \
info->op2.flags = SM83_OP_FLAG_MEMORY;)
#define DEFINE_LD_DECODER_SM83_MEM_2(NAME, REG) \
DEFINE_DECODER_SM83(LD ## REG ## _ ## NAME, info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## REG; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_ ## NAME;)
#define DEFINE_LD_DECODER_SM83(NAME) \
DEFINE_LD_DECODER_SM83_MEM(NAME, HL) \
DEFINE_LD_DECODER_SM83_MEM_2(NAME, HL) \
DEFINE_DECODER_SM83(LD ## NAME ## _, info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
return 1;) \
DEFINE_LD_DECODER_SM83_NOHL(NAME)
#define DEFINE_LD_2_DECODER_SM83(NAME) \
DEFINE_DECODER_SM83(LD ## NAME, info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_ ## NAME; \
return 2;)
DEFINE_LD_DECODER_SM83(B);
DEFINE_LD_DECODER_SM83(C);
DEFINE_LD_DECODER_SM83(D);
DEFINE_LD_DECODER_SM83(E);
DEFINE_LD_DECODER_SM83(H);
DEFINE_LD_DECODER_SM83(L);
DEFINE_LD_DECODER_SM83(A);
DEFINE_LD_DECODER_SM83_MEM(A, BC);
DEFINE_LD_DECODER_SM83_MEM(A, DE);
DEFINE_LD_2_DECODER_SM83(BC);
DEFINE_LD_2_DECODER_SM83(DE);
DEFINE_LD_2_DECODER_SM83(HL);
DEFINE_LD_2_DECODER_SM83(SP);
DEFINE_DECODER_SM83(LDHL_, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_HL; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
return 1;)
DEFINE_DECODER_SM83(LDHL_SP, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_HL; \
info->op2.reg = SM83_REG_SP; \
return 1;)
DEFINE_DECODER_SM83(LDSP_HL, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_SP; \
info->op2.reg = SM83_REG_HL;)
DEFINE_DECODER_SM83(LDAIOC, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_A; \
info->op2.reg = SM83_REG_C; \
info->op2.immediate = 0xFF00; \
info->op2.flags = SM83_OP_FLAG_MEMORY;)
DEFINE_DECODER_SM83(LDIOCA, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_C; \
info->op1.immediate = 0xFF00; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A;)
DEFINE_DECODER_SM83(LDAIO, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_A; \
info->op2.immediate = 0xFF00; \
info->op2.flags = SM83_OP_FLAG_MEMORY; \
return 1;)
DEFINE_DECODER_SM83(LDIOA, \
info->mnemonic = SM83_MN_LD; \
info->op1.immediate = 0xFF00; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A; \
return 1;)
#define DEFINE_ALU_DECODER_SM83_NOHL(NAME) \
DEFINE_DECODER_SM83(NAME ## A, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_A) \
DEFINE_DECODER_SM83(NAME ## B, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_B) \
DEFINE_DECODER_SM83(NAME ## C, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_C) \
DEFINE_DECODER_SM83(NAME ## D, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_D) \
DEFINE_DECODER_SM83(NAME ## E, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_E) \
DEFINE_DECODER_SM83(NAME ## H, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_H) \
DEFINE_DECODER_SM83(NAME ## L, info->mnemonic = SM83_MN_ ## NAME; info->op1.reg = SM83_REG_L)
#define DEFINE_ALU_DECODER_SM83_MEM(NAME, REG) \
DEFINE_DECODER_SM83(NAME ## REG, info->mnemonic = SM83_MN_ ## NAME; \
info->op1.reg = SM83_REG_HL; \
info->op1.flags = SM83_OP_FLAG_MEMORY;)
#define DEFINE_ALU_DECODER_SM83(NAME) \
DEFINE_ALU_DECODER_SM83_MEM(NAME, HL) \
DEFINE_DECODER_SM83(NAME, info->mnemonic = SM83_MN_ ## NAME; \
info->op1.reg = SM83_REG_A; \
info->op1.flags = SM83_OP_FLAG_IMPLICIT; \
return 1;) \
DEFINE_ALU_DECODER_SM83_NOHL(NAME)
DEFINE_ALU_DECODER_SM83_NOHL(INC);
DEFINE_ALU_DECODER_SM83_NOHL(DEC);
DEFINE_ALU_DECODER_SM83(AND);
DEFINE_ALU_DECODER_SM83(XOR);
DEFINE_ALU_DECODER_SM83(OR);
DEFINE_ALU_DECODER_SM83(CP);
DEFINE_ALU_DECODER_SM83(ADD);
DEFINE_ALU_DECODER_SM83(ADC);
DEFINE_ALU_DECODER_SM83(SUB);
DEFINE_ALU_DECODER_SM83(SBC);
#define DEFINE_ALU_DECODER_SM83_ADD_HL(REG) \
DEFINE_DECODER_SM83(ADDHL_ ## REG, info->mnemonic = SM83_MN_ADD; \
info->op1.reg = SM83_REG_HL; \
info->op2.reg = SM83_REG_ ## REG;)
DEFINE_ALU_DECODER_SM83_ADD_HL(BC)
DEFINE_ALU_DECODER_SM83_ADD_HL(DE)
DEFINE_ALU_DECODER_SM83_ADD_HL(HL)
DEFINE_ALU_DECODER_SM83_ADD_HL(SP)
DEFINE_DECODER_SM83(ADDSP, info->mnemonic = SM83_MN_ADD; \
info->op1.reg = SM83_REG_SP; \
return 1;)
#define DEFINE_CONDITIONAL_DECODER_SM83(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(, 0) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(C, SM83_COND_C) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(Z, SM83_COND_Z) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(NC, SM83_COND_NC) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(NZ, SM83_COND_NZ)
#define DEFINE_JP_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_SM83(JP ## CONDITION_NAME, \
info->mnemonic = SM83_MN_JP; \
info->condition = CONDITION; \
return 2;)
#define DEFINE_JR_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_SM83(JR ## CONDITION_NAME, \
info->mnemonic = SM83_MN_JR; \
info->condition = CONDITION; \
info->op1.flags = SM83_OP_FLAG_RELATIVE; \
return 1;)
#define DEFINE_CALL_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_SM83(CALL ## CONDITION_NAME, \
info->mnemonic = SM83_MN_CALL; \
info->condition = CONDITION; \
return 2;)
#define DEFINE_RET_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_DECODER_SM83(RET ## CONDITION_NAME, \
info->mnemonic = SM83_MN_RET; \
info->condition = CONDITION;)
DEFINE_CONDITIONAL_DECODER_SM83(JP);
DEFINE_CONDITIONAL_DECODER_SM83(JR);
DEFINE_CONDITIONAL_DECODER_SM83(CALL);
DEFINE_CONDITIONAL_DECODER_SM83(RET);
DEFINE_DECODER_SM83(JPHL, \
info->mnemonic = SM83_MN_JP; \
info->op1.reg = SM83_REG_HL)
DEFINE_DECODER_SM83(RETI, info->mnemonic = SM83_MN_RETI)
DEFINE_DECODER_SM83(LDBC_A, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_BC; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A;)
DEFINE_DECODER_SM83(LDDE_A, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_DE; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A;)
DEFINE_DECODER_SM83(LDIA, \
info->mnemonic = SM83_MN_LD; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A; \
return 2;)
DEFINE_DECODER_SM83(LDAI, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_A; \
info->op2.flags = SM83_OP_FLAG_MEMORY; \
return 2;)
DEFINE_DECODER_SM83(LDISP, \
info->mnemonic = SM83_MN_LD; \
info->op1.flags = SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_SP; \
return 2;)
DEFINE_DECODER_SM83(LDIHLA, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_HL; \
info->op1.flags = SM83_OP_FLAG_INCREMENT | SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A;)
DEFINE_DECODER_SM83(LDDHLA, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_HL; \
info->op1.flags = SM83_OP_FLAG_DECREMENT | SM83_OP_FLAG_MEMORY; \
info->op2.reg = SM83_REG_A;)
DEFINE_DECODER_SM83(LDA_IHL, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_A; \
info->op2.reg = SM83_REG_HL; \
info->op2.flags = SM83_OP_FLAG_INCREMENT | SM83_OP_FLAG_MEMORY;)
DEFINE_DECODER_SM83(LDA_DHL, \
info->mnemonic = SM83_MN_LD; \
info->op1.reg = SM83_REG_A; \
info->op2.reg = SM83_REG_HL; \
info->op2.flags = SM83_OP_FLAG_DECREMENT | SM83_OP_FLAG_MEMORY;)
#define DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(REG) \
DEFINE_DECODER_SM83(INC ## REG, info->mnemonic = SM83_MN_INC; info->op1.reg = SM83_REG_ ## REG) \
DEFINE_DECODER_SM83(DEC ## REG, info->mnemonic = SM83_MN_DEC; info->op1.reg = SM83_REG_ ## REG)
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(BC);
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(DE);
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(HL);
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(SP);
DEFINE_DECODER_SM83(INC_HL,
info->mnemonic = SM83_MN_INC;
info->op1.reg = SM83_REG_HL;
info->op1.flags = SM83_OP_FLAG_MEMORY;)
DEFINE_DECODER_SM83(DEC_HL,
info->mnemonic = SM83_MN_DEC;
info->op1.reg = SM83_REG_HL;
info->op1.flags = SM83_OP_FLAG_MEMORY;)
DEFINE_DECODER_SM83(SCF, info->mnemonic = SM83_MN_SCF)
DEFINE_DECODER_SM83(CCF, info->mnemonic = SM83_MN_CCF)
DEFINE_DECODER_SM83(CPL_, info->mnemonic = SM83_MN_CPL)
DEFINE_DECODER_SM83(DAA, info->mnemonic = SM83_MN_DAA)
#define DEFINE_POPPUSH_DECODER_SM83(REG) \
DEFINE_DECODER_SM83(POP ## REG, \
info->mnemonic = SM83_MN_POP; \
info->op1.reg = SM83_REG_ ## REG;) \
DEFINE_DECODER_SM83(PUSH ## REG, \
info->mnemonic = SM83_MN_PUSH; \
info->op1.reg = SM83_REG_ ## REG;) \
DEFINE_POPPUSH_DECODER_SM83(BC);
DEFINE_POPPUSH_DECODER_SM83(DE);
DEFINE_POPPUSH_DECODER_SM83(HL);
DEFINE_POPPUSH_DECODER_SM83(AF);
#define DEFINE_CB_OP_DECODER_SM83(NAME, BODY, OP) \
DEFINE_DECODER_SM83(NAME ## B, info->OP.reg = SM83_REG_B; BODY) \
DEFINE_DECODER_SM83(NAME ## C, info->OP.reg = SM83_REG_C; BODY) \
DEFINE_DECODER_SM83(NAME ## D, info->OP.reg = SM83_REG_D; BODY) \
DEFINE_DECODER_SM83(NAME ## E, info->OP.reg = SM83_REG_E; BODY) \
DEFINE_DECODER_SM83(NAME ## H, info->OP.reg = SM83_REG_H; BODY) \
DEFINE_DECODER_SM83(NAME ## L, info->OP.reg = SM83_REG_L; BODY) \
DEFINE_DECODER_SM83(NAME ## HL, info->OP.reg = SM83_REG_HL; info->OP.flags = SM83_OP_FLAG_MEMORY; BODY) \
DEFINE_DECODER_SM83(NAME ## A, info->OP.reg = SM83_REG_A; BODY)
#define DEFINE_CB_2_DECODER_SM83(NAME, BODY) \
DEFINE_CB_OP_DECODER_SM83(NAME, BODY, op2)
#define DEFINE_CB_1_DECODER_SM83(NAME, BODY) \
DEFINE_CB_OP_DECODER_SM83(NAME, BODY, op1)
#define DEFINE_CB_DECODER_SM83(NAME, BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 0, info->op1.immediate = 0; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 1, info->op1.immediate = 1; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 2, info->op1.immediate = 2; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 3, info->op1.immediate = 3; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 4, info->op1.immediate = 4; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 5, info->op1.immediate = 5; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 6, info->op1.immediate = 6; BODY) \
DEFINE_CB_2_DECODER_SM83(NAME ## 7, info->op1.immediate = 7; BODY)
DEFINE_CB_DECODER_SM83(BIT, info->mnemonic = SM83_MN_BIT)
DEFINE_CB_DECODER_SM83(RES, info->mnemonic = SM83_MN_RES)
DEFINE_CB_DECODER_SM83(SET, info->mnemonic = SM83_MN_SET)
#define DEFINE_CB_X_DECODER_SM83(NAME) \
DEFINE_CB_1_DECODER_SM83(NAME, info->mnemonic = SM83_MN_ ## NAME) \
DEFINE_DECODER_SM83(NAME ## A_, info->mnemonic = SM83_MN_ ## NAME; \
info->op1.flags = SM83_OP_FLAG_IMPLICIT; \
info->op1.reg = SM83_REG_A;)
DEFINE_CB_X_DECODER_SM83(RL)
DEFINE_CB_X_DECODER_SM83(RLC)
DEFINE_CB_X_DECODER_SM83(RR)
DEFINE_CB_X_DECODER_SM83(RRC)
DEFINE_CB_1_DECODER_SM83(SLA, info->mnemonic = SM83_MN_SLA)
DEFINE_CB_1_DECODER_SM83(SRA, info->mnemonic = SM83_MN_SRA)
DEFINE_CB_1_DECODER_SM83(SRL, info->mnemonic = SM83_MN_SRL)
DEFINE_CB_1_DECODER_SM83(SWAP, info->mnemonic = SM83_MN_SWAP)
DEFINE_DECODER_SM83(DI, info->mnemonic = SM83_MN_DI)
DEFINE_DECODER_SM83(EI, info->mnemonic = SM83_MN_EI)
DEFINE_DECODER_SM83(HALT, info->mnemonic = SM83_MN_HALT)
DEFINE_DECODER_SM83(ILL, info->mnemonic = SM83_MN_ILL)
DEFINE_DECODER_SM83(STOP, info->mnemonic = SM83_MN_STOP; return 1)
#define DEFINE_RST_DECODER_SM83(VEC) \
DEFINE_DECODER_SM83(RST ## VEC, info->op1.immediate = 0x ## VEC;)
DEFINE_RST_DECODER_SM83(00);
DEFINE_RST_DECODER_SM83(08);
DEFINE_RST_DECODER_SM83(10);
DEFINE_RST_DECODER_SM83(18);
DEFINE_RST_DECODER_SM83(20);
DEFINE_RST_DECODER_SM83(28);
DEFINE_RST_DECODER_SM83(30);
DEFINE_RST_DECODER_SM83(38);
DEFINE_DECODER_SM83(CB, return 1)
const SM83Decoder _sm83DecoderTable[0x100] = {
DECLARE_SM83_EMITTER_BLOCK(_SM83Decode)
};
const SM83Decoder _sm83CBDecoderTable[0x100] = {
DECLARE_SM83_CB_EMITTER_BLOCK(_SM83Decode)
};
size_t SM83Decode(uint8_t opcode, struct SM83InstructionInfo* info) {
if (info->opcodeSize == sizeof(info->opcode)) {
return 0;
}
info->opcode[info->opcodeSize] = opcode;
SM83Decoder decoder;
switch (info->opcodeSize) {
case 0:
decoder = _sm83DecoderTable[opcode];
break;
case 1:
if (info->opcode[0] == 0xCB) {
decoder = _sm83CBDecoderTable[opcode];
break;
}
// Fall through
case 2:
++info->opcodeSize;
if (info->op1.reg) {
info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
} else {
info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
}
return 0;
}
++info->opcodeSize;
return decoder(opcode, info);
}
#define ADVANCE(AMOUNT) \
if (AMOUNT >= blen) { \
buffer[blen - 1] = '\0'; \
return total; \
} \
total += AMOUNT; \
buffer += AMOUNT; \
blen -= AMOUNT;
static const char* _sm83Conditions[] = {
NULL,
"c",
"z",
"nc",
"nz",
};
static const char* _sm83Registers[] = {
"",
"b",
"c",
"d",
"e",
"h",
"l",
"a",
"f",
"bc",
"de",
"hl",
"af",
"sp",
"pc",
};
static const char* _sm83MnemonicStrings[] = {
"--",
"adc",
"add",
"and",
"bit",
"call",
"ccf",
"cp",
"cpl",
"daa",
"dec",
"di",
"ei",
"halt",
"inc",
"jp",
"jr",
"ld",
"nop",
"or",
"pop",
"push",
"res",
"ret",
"reti",
"rl",
"rlc",
"rr",
"rrc",
"rst",
"sbc",
"scf",
"set",
"sla",
"sra",
"srl",
"stop",
"sub",
"swap",
"xor",
"ill"
};
static int _decodeOperand(struct SM83Operand op, uint16_t pc, char* buffer, int blen) {
int total = 0;
if (op.flags & SM83_OP_FLAG_IMPLICIT) {
return 0;
}
strncpy(buffer, " ", blen - 1);
ADVANCE(1);
if (op.flags & SM83_OP_FLAG_MEMORY) {
strncpy(buffer, "[", blen - 1);
ADVANCE(1);
}
if (op.reg) {
int written = snprintf(buffer, blen - 1, "%s", _sm83Registers[op.reg]);
ADVANCE(written);
} else {
int written;
if (op.flags & SM83_OP_FLAG_RELATIVE) {
written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
} else {
written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
}
ADVANCE(written);
if (op.reg) {
strncpy(buffer, "+", blen - 1);
ADVANCE(1);
}
}
if (op.flags & SM83_OP_FLAG_INCREMENT) {
strncpy(buffer, "+", blen - 1);
ADVANCE(1);
}
if (op.flags & SM83_OP_FLAG_DECREMENT) {
strncpy(buffer, "-", blen - 1);
ADVANCE(1);
}
if (op.flags & SM83_OP_FLAG_MEMORY) {
strncpy(buffer, "]", blen - 1);
ADVANCE(1);
}
return total;
}
int SM83Disassemble(struct SM83InstructionInfo* info, uint16_t pc, char* buffer, int blen) {
const char* mnemonic = _sm83MnemonicStrings[info->mnemonic];
int written;
int total = 0;
const char* cond = _sm83Conditions[info->condition];
written = snprintf(buffer, blen - 1, "%s", mnemonic);
ADVANCE(written);
if (cond) {
written = snprintf(buffer, blen - 1, " %s", cond);
ADVANCE(written);
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
strncpy(buffer, ",", blen - 1);
ADVANCE(1);
}
}
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
written = _decodeOperand(info->op1, pc, buffer, blen);
ADVANCE(written);
}
if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
if (written) {
strncpy(buffer, ",", blen - 1);
ADVANCE(1);
}
written = _decodeOperand(info->op2, pc, buffer, blen);
ADVANCE(written);
}
buffer[blen - 1] = '\0';
return total;
}

820
src/sm83/isa-sm83.c Normal file
View File

@ -0,0 +1,820 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/sm83/isa-sm83.h>
#include <mgba/internal/sm83/emitter-sm83.h>
#include <mgba/internal/sm83/sm83.h>
static inline uint16_t SM83ReadHL(struct SM83Core* cpu) {
uint16_t hl;
LOAD_16LE(hl, 0, &cpu->hl);
return hl;
}
static inline void SM83WriteHL(struct SM83Core* cpu, uint16_t hl) {
STORE_16LE(hl, 0, &cpu->hl);
}
static inline uint16_t SM83ReadBC(struct SM83Core* cpu) {
uint16_t bc;
LOAD_16LE(bc, 0, &cpu->bc);
return bc;
}
static inline void SM83WriteBC(struct SM83Core* cpu, uint16_t bc) {
STORE_16LE(bc, 0, &cpu->bc);
}
static inline uint16_t SM83ReadDE(struct SM83Core* cpu) {
uint16_t de;
LOAD_16LE(de, 0, &cpu->de);
return de;
}
static inline void SM83WriteDE(struct SM83Core* cpu, uint16_t de) {
STORE_16LE(de, 0, &cpu->de);
}
#define DEFINE_INSTRUCTION_SM83(NAME, BODY) \
static void _SM83Instruction ## NAME (struct SM83Core* cpu) { \
UNUSED(cpu); \
BODY; \
}
DEFINE_INSTRUCTION_SM83(NOP,);
#define DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(C, cpu->f.c) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(Z, cpu->f.z) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(NC, !cpu->f.c) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(NZ, !cpu->f.z)
#define DEFINE_CONDITIONAL_INSTRUCTION_SM83(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(, true) \
DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(NAME)
DEFINE_INSTRUCTION_SM83(JPFinish,
if (cpu->condition) {
cpu->pc = (cpu->bus << 8) | cpu->index;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = SM83_CORE_STALL;
})
DEFINE_INSTRUCTION_SM83(JPDelay,
cpu->executionState = SM83_CORE_READ_PC;
cpu->instruction = _SM83InstructionJPFinish;
cpu->index = cpu->bus;)
#define DEFINE_JP_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_SM83(JP ## CONDITION_NAME, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionJPDelay; \
cpu->condition = CONDITION;)
DEFINE_CONDITIONAL_INSTRUCTION_SM83(JP);
DEFINE_INSTRUCTION_SM83(JPHL,
cpu->pc = SM83ReadHL(cpu);
cpu->memory.setActiveRegion(cpu, cpu->pc);)
DEFINE_INSTRUCTION_SM83(JRFinish,
if (cpu->condition) {
cpu->pc += (int8_t) cpu->bus;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = SM83_CORE_STALL;
})
#define DEFINE_JR_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_SM83(JR ## CONDITION_NAME, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionJRFinish; \
cpu->condition = CONDITION;)
DEFINE_CONDITIONAL_INSTRUCTION_SM83(JR);
DEFINE_INSTRUCTION_SM83(CALLUpdateSPL,
--cpu->index;
cpu->bus = cpu->sp;
cpu->sp = cpu->index;
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(CALLUpdateSPH,
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionCALLUpdateSPL;)
DEFINE_INSTRUCTION_SM83(CALLUpdatePCH,
if (cpu->condition) {
int newPc = (cpu->bus << 8) | cpu->index;
cpu->bus = cpu->pc >> 8;
cpu->index = cpu->sp - 1;
cpu->sp = cpu->pc; // GROSS
cpu->pc = newPc;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = SM83_CORE_OP2;
cpu->instruction = _SM83InstructionCALLUpdateSPH;
})
DEFINE_INSTRUCTION_SM83(CALLUpdatePCL,
cpu->executionState = SM83_CORE_READ_PC;
cpu->index = cpu->bus;
cpu->instruction = _SM83InstructionCALLUpdatePCH)
#define DEFINE_CALL_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_SM83(CALL ## CONDITION_NAME, \
cpu->condition = CONDITION; \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionCALLUpdatePCL;)
DEFINE_CONDITIONAL_INSTRUCTION_SM83(CALL)
DEFINE_INSTRUCTION_SM83(RETFinish,
cpu->sp += 2; /* TODO: Atomic incrementing? */
cpu->pc |= cpu->bus << 8;
cpu->memory.setActiveRegion(cpu, cpu->pc);
cpu->executionState = SM83_CORE_STALL;)
DEFINE_INSTRUCTION_SM83(RETUpdateSPL,
cpu->index = cpu->sp + 1;
cpu->pc = cpu->bus;
cpu->executionState = SM83_CORE_MEMORY_LOAD;
cpu->instruction = _SM83InstructionRETFinish;)
DEFINE_INSTRUCTION_SM83(RETUpdateSPH,
if (cpu->condition) {
cpu->index = cpu->sp;
cpu->executionState = SM83_CORE_MEMORY_LOAD;
cpu->instruction = _SM83InstructionRETUpdateSPL;
})
#define DEFINE_RET_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
DEFINE_INSTRUCTION_SM83(RET ## CONDITION_NAME, \
cpu->condition = CONDITION; \
cpu->executionState = SM83_CORE_OP2; \
cpu->instruction = _SM83InstructionRETUpdateSPH;)
DEFINE_INSTRUCTION_SM83(RET,
cpu->condition = true;
_SM83InstructionRETUpdateSPH(cpu);)
DEFINE_INSTRUCTION_SM83(RETI,
cpu->condition = true;
cpu->irqh.setInterrupts(cpu, true);
_SM83InstructionRETUpdateSPH(cpu);)
DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(RET)
#define DEFINE_AND_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(AND ## NAME, \
cpu->a &= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 1;)
#define DEFINE_XOR_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(XOR ## NAME, \
cpu->a ^= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 0;)
#define DEFINE_OR_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(OR ## NAME, \
cpu->a |= OPERAND; \
cpu->f.z = !cpu->a; \
cpu->f.n = 0; \
cpu->f.c = 0; \
cpu->f.h = 0;)
#define DEFINE_CP_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(CP ## NAME, \
int diff = cpu->a - OPERAND; \
cpu->f.n = 1; \
cpu->f.z = !(diff & 0xFF); \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
cpu->f.c = diff < 0;)
#define DEFINE_LDB__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDB_ ## NAME, \
cpu->b = OPERAND;)
#define DEFINE_LDC__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDC_ ## NAME, \
cpu->c = OPERAND;)
#define DEFINE_LDD__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDD_ ## NAME, \
cpu->d = OPERAND;)
#define DEFINE_LDE__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDE_ ## NAME, \
cpu->e = OPERAND;)
#define DEFINE_LDH__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDH_ ## NAME, \
cpu->h = OPERAND;)
#define DEFINE_LDL__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDL_ ## NAME, \
cpu->l = OPERAND;)
#define DEFINE_LDHL__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDHL_ ## NAME, \
cpu->bus = OPERAND; \
cpu->index = SM83ReadHL(cpu); \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
#define DEFINE_LDA__INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(LDA_ ## NAME, \
cpu->a = OPERAND;)
#define DEFINE_ALU_INSTRUCTION_SM83_NOHL(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(A, cpu->a); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(B, cpu->b); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(C, cpu->c); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(D, cpu->d); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(E, cpu->e); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(H, cpu->h); \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(L, cpu->l);
DEFINE_INSTRUCTION_SM83(LDHL_Bus, \
cpu->index = SM83ReadHL(cpu); \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDHL_, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDHL_Bus;)
DEFINE_INSTRUCTION_SM83(LDHL_SPDelay,
int diff = (int8_t) cpu->bus;
int sum = cpu->sp + diff;
SM83WriteHL(cpu, sum);
cpu->executionState = SM83_CORE_STALL;
cpu->f.z = 0;
cpu->f.n = 0;
cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
DEFINE_INSTRUCTION_SM83(LDHL_SP,
cpu->executionState = SM83_CORE_READ_PC;
cpu->instruction = _SM83InstructionLDHL_SPDelay;)
DEFINE_INSTRUCTION_SM83(LDSP_HL,
cpu->sp = SM83ReadHL(cpu);
cpu->executionState = SM83_CORE_STALL;)
#define DEFINE_ALU_INSTRUCTION_SM83_MEM(NAME, REG) \
DEFINE_INSTRUCTION_SM83(NAME ## REG, \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->index = SM83Read ## REG (cpu); \
cpu->instruction = _SM83Instruction ## NAME ## Bus;)
#define DEFINE_ALU_INSTRUCTION_SM83(NAME) \
DEFINE_ ## NAME ## _INSTRUCTION_SM83(Bus, cpu->bus); \
DEFINE_ALU_INSTRUCTION_SM83_MEM(NAME, HL) \
DEFINE_INSTRUCTION_SM83(NAME, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83Instruction ## NAME ## Bus;) \
DEFINE_ALU_INSTRUCTION_SM83_NOHL(NAME)
DEFINE_ALU_INSTRUCTION_SM83(AND);
DEFINE_ALU_INSTRUCTION_SM83(XOR);
DEFINE_ALU_INSTRUCTION_SM83(OR);
DEFINE_ALU_INSTRUCTION_SM83(CP);
static void _SM83InstructionLDB_Bus(struct SM83Core*);
static void _SM83InstructionLDC_Bus(struct SM83Core*);
static void _SM83InstructionLDD_Bus(struct SM83Core*);
static void _SM83InstructionLDE_Bus(struct SM83Core*);
static void _SM83InstructionLDH_Bus(struct SM83Core*);
static void _SM83InstructionLDL_Bus(struct SM83Core*);
static void _SM83InstructionLDHL_Bus(struct SM83Core*);
static void _SM83InstructionLDA_Bus(struct SM83Core*);
#define DEFINE_ADD_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(ADD ## NAME, \
int diff = cpu->a + OPERAND; \
cpu->f.n = 0; \
cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_ADC_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(ADC ## NAME, \
int diff = cpu->a + OPERAND + cpu->f.c; \
cpu->f.n = 0; \
cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) + cpu->f.c >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_SUB_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(SUB ## NAME, \
int diff = cpu->a - OPERAND; \
cpu->f.n = 1; \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
cpu->f.c = diff < 0; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
#define DEFINE_SBC_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(SBC ## NAME, \
int diff = cpu->a - OPERAND - cpu->f.c; \
cpu->f.n = 1; \
cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) - cpu->f.c < 0; \
cpu->f.c = diff < 0; \
cpu->a = diff; \
cpu->f.z = !cpu->a;)
DEFINE_ALU_INSTRUCTION_SM83(LDB_);
DEFINE_ALU_INSTRUCTION_SM83(LDC_);
DEFINE_ALU_INSTRUCTION_SM83(LDD_);
DEFINE_ALU_INSTRUCTION_SM83(LDE_);
DEFINE_ALU_INSTRUCTION_SM83(LDH_);
DEFINE_ALU_INSTRUCTION_SM83(LDL_);
DEFINE_ALU_INSTRUCTION_SM83_NOHL(LDHL_);
DEFINE_ALU_INSTRUCTION_SM83(LDA_);
DEFINE_ALU_INSTRUCTION_SM83_MEM(LDA_, BC);
DEFINE_ALU_INSTRUCTION_SM83_MEM(LDA_, DE);
DEFINE_ALU_INSTRUCTION_SM83(ADD);
DEFINE_ALU_INSTRUCTION_SM83(ADC);
DEFINE_ALU_INSTRUCTION_SM83(SUB);
DEFINE_ALU_INSTRUCTION_SM83(SBC);
DEFINE_INSTRUCTION_SM83(ADDSPFinish,
cpu->sp = cpu->index;
cpu->executionState = SM83_CORE_STALL;)
DEFINE_INSTRUCTION_SM83(ADDSPDelay,
int diff = (int8_t) cpu->bus;
int sum = cpu->sp + diff;
cpu->index = sum;
cpu->executionState = SM83_CORE_OP2;
cpu->instruction = _SM83InstructionADDSPFinish;
cpu->f.z = 0;
cpu->f.n = 0;
cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
DEFINE_INSTRUCTION_SM83(ADDSP,
cpu->executionState = SM83_CORE_READ_PC;
cpu->instruction = _SM83InstructionADDSPDelay;)
DEFINE_INSTRUCTION_SM83(LDBCDelay, \
cpu->c = cpu->bus; \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDB_Bus;)
DEFINE_INSTRUCTION_SM83(LDBC, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDBCDelay;)
DEFINE_INSTRUCTION_SM83(LDBC_A, \
cpu->index = SM83ReadBC(cpu); \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDDEDelay, \
cpu->e = cpu->bus; \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDD_Bus;)
DEFINE_INSTRUCTION_SM83(LDDE, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDDEDelay;)
DEFINE_INSTRUCTION_SM83(LDDE_A, \
cpu->index = SM83ReadDE(cpu); \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDHLDelay, \
cpu->l = cpu->bus; \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDH_Bus;)
DEFINE_INSTRUCTION_SM83(LDHL, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDHLDelay;)
DEFINE_INSTRUCTION_SM83(LDSPFinish, cpu->sp |= cpu->bus << 8;)
DEFINE_INSTRUCTION_SM83(LDSPDelay, \
cpu->sp = cpu->bus; \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDSPFinish;)
DEFINE_INSTRUCTION_SM83(LDSP, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDSPDelay;)
DEFINE_INSTRUCTION_SM83(LDIHLA, \
cpu->index = SM83ReadHL(cpu); \
SM83WriteHL(cpu, cpu->index + 1); \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDDHLA, \
cpu->index = SM83ReadHL(cpu); \
SM83WriteHL(cpu, cpu->index - 1); \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDA_IHL, \
cpu->index = SM83ReadHL(cpu); \
SM83WriteHL(cpu, cpu->index + 1); \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83InstructionLDA_Bus;)
DEFINE_INSTRUCTION_SM83(LDA_DHL, \
cpu->index = SM83ReadHL(cpu); \
SM83WriteHL(cpu, cpu->index - 1); \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83InstructionLDA_Bus;)
DEFINE_INSTRUCTION_SM83(LDIAFinish, \
cpu->index |= cpu->bus << 8;
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDIADelay, \
cpu->index = cpu->bus;
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDIAFinish;)
DEFINE_INSTRUCTION_SM83(LDIA, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDIADelay;)
DEFINE_INSTRUCTION_SM83(LDAIFinish, \
cpu->index |= cpu->bus << 8;
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83InstructionLDA_Bus;)
DEFINE_INSTRUCTION_SM83(LDAIDelay, \
cpu->index = cpu->bus;
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDAIFinish;)
DEFINE_INSTRUCTION_SM83(LDAI, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDAIDelay;)
DEFINE_INSTRUCTION_SM83(LDAIOC, \
cpu->index = 0xFF00 | cpu->c; \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83InstructionLDA_Bus;)
DEFINE_INSTRUCTION_SM83(LDIOCA, \
cpu->index = 0xFF00 | cpu->c; \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDAIODelay, \
cpu->index = 0xFF00 | cpu->bus; \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83InstructionLDA_Bus;)
DEFINE_INSTRUCTION_SM83(LDAIO, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDAIODelay;)
DEFINE_INSTRUCTION_SM83(LDIOADelay, \
cpu->index = 0xFF00 | cpu->bus; \
cpu->bus = cpu->a; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDIOA, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionLDIOADelay;)
DEFINE_INSTRUCTION_SM83(LDISPStoreH,
++cpu->index;
cpu->bus = cpu->sp >> 8;
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionNOP;)
DEFINE_INSTRUCTION_SM83(LDISPStoreL,
cpu->index |= cpu->bus << 8;
cpu->bus = cpu->sp;
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionLDISPStoreH;)
DEFINE_INSTRUCTION_SM83(LDISPReadAddr,
cpu->index = cpu->bus;
cpu->executionState = SM83_CORE_READ_PC;
cpu->instruction = _SM83InstructionLDISPStoreL;)
DEFINE_INSTRUCTION_SM83(LDISP,
cpu->executionState = SM83_CORE_READ_PC;
cpu->instruction = _SM83InstructionLDISPReadAddr;)
#define DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(REG) \
DEFINE_INSTRUCTION_SM83(INC ## REG, \
uint16_t reg = SM83Read ## REG (cpu); \
SM83Write ## REG (cpu, reg + 1); \
cpu->executionState = SM83_CORE_STALL;) \
DEFINE_INSTRUCTION_SM83(DEC ## REG, \
uint16_t reg = SM83Read ## REG (cpu); \
SM83Write ## REG (cpu, reg - 1); \
cpu->executionState = SM83_CORE_STALL;)
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(BC);
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(DE);
DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(HL);
#define DEFINE_ADD_HL_INSTRUCTION_SM83(REG, L, H) \
DEFINE_INSTRUCTION_SM83(ADDHL_ ## REG ## Finish, \
int diff = H + cpu->h + cpu->f.c; \
cpu->f.n = 0; \
cpu->f.h = (H & 0xF) + (cpu->h & 0xF) + cpu->f.c >= 0x10; \
cpu->f.c = diff >= 0x100; \
cpu->h = diff;) \
DEFINE_INSTRUCTION_SM83(ADDHL_ ## REG, \
int diff = L + cpu->l; \
cpu->l = diff; \
cpu->f.c = diff >= 0x100; \
cpu->executionState = SM83_CORE_OP2; \
cpu->instruction = _SM83InstructionADDHL_ ## REG ## Finish;)
DEFINE_ADD_HL_INSTRUCTION_SM83(BC, cpu->c, cpu->b);
DEFINE_ADD_HL_INSTRUCTION_SM83(DE, cpu->e, cpu->d);
DEFINE_ADD_HL_INSTRUCTION_SM83(HL, cpu->l, cpu->h);
DEFINE_ADD_HL_INSTRUCTION_SM83(SP, (cpu->sp & 0xFF), (cpu->sp >> 8));
#define DEFINE_INC_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(INC ## NAME, \
int diff = OPERAND + 1; \
cpu->f.h = (OPERAND & 0xF) == 0xF; \
OPERAND = diff; \
cpu->f.n = 0; \
cpu->f.z = !OPERAND;)
#define DEFINE_DEC_INSTRUCTION_SM83(NAME, OPERAND) \
DEFINE_INSTRUCTION_SM83(DEC ## NAME, \
int diff = OPERAND - 1; \
cpu->f.h = (OPERAND & 0xF) == 0x0; \
OPERAND = diff; \
cpu->f.n = 1; \
cpu->f.z = !OPERAND;)
DEFINE_ALU_INSTRUCTION_SM83_NOHL(INC);
DEFINE_ALU_INSTRUCTION_SM83_NOHL(DEC);
DEFINE_INSTRUCTION_SM83(INC_HLDelay,
int diff = cpu->bus + 1;
cpu->f.n = 0;
cpu->f.h = (cpu->bus & 0xF) == 0xF;
cpu->bus = diff;
cpu->f.z = !cpu->bus;
cpu->instruction = _SM83InstructionNOP;
cpu->executionState = SM83_CORE_MEMORY_STORE;)
DEFINE_INSTRUCTION_SM83(INC_HL,
cpu->index = SM83ReadHL(cpu);
cpu->instruction = _SM83InstructionINC_HLDelay;
cpu->executionState = SM83_CORE_MEMORY_LOAD;)
DEFINE_INSTRUCTION_SM83(DEC_HLDelay,
int diff = cpu->bus - 1;
cpu->f.n = 1;
cpu->f.h = (cpu->bus & 0xF) == 0;
cpu->bus = diff;
cpu->f.z = !cpu->bus;
cpu->instruction = _SM83InstructionNOP;
cpu->executionState = SM83_CORE_MEMORY_STORE;)
DEFINE_INSTRUCTION_SM83(DEC_HL,
cpu->index = SM83ReadHL(cpu);
cpu->instruction = _SM83InstructionDEC_HLDelay;
cpu->executionState = SM83_CORE_MEMORY_LOAD;)
DEFINE_INSTRUCTION_SM83(INCSP,
++cpu->sp;
cpu->executionState = SM83_CORE_STALL;)
DEFINE_INSTRUCTION_SM83(DECSP,
--cpu->sp;
cpu->executionState = SM83_CORE_STALL;)
DEFINE_INSTRUCTION_SM83(SCF,
cpu->f.c = 1;
cpu->f.h = 0;
cpu->f.n = 0;)
DEFINE_INSTRUCTION_SM83(CCF,
cpu->f.c ^= 1;
cpu->f.h = 0;
cpu->f.n = 0;)
DEFINE_INSTRUCTION_SM83(CPL_,
cpu->a ^= 0xFF;
cpu->f.h = 1;
cpu->f.n = 1;)
DEFINE_INSTRUCTION_SM83(DAA,
if (cpu->f.n) {
if (cpu->f.h) {
cpu->a += 0xFA;
}
if (cpu->f.c) {
cpu->a += 0xA0;
}
} else {
int a = cpu->a;
if ((cpu->a & 0xF) > 0x9 || cpu->f.h) {
a += 0x6;
}
if ((a & 0x1F0) > 0x90 || cpu->f.c) {
a += 0x60;
cpu->f.c = 1;
} else {
cpu->f.c = 0;
}
cpu->a = a;
}
cpu->f.h = 0;
cpu->f.z = !cpu->a;)
#define DEFINE_POPPUSH_INSTRUCTION_SM83(REG, HH, H, L) \
DEFINE_INSTRUCTION_SM83(POP ## REG ## Delay, \
cpu-> L = cpu->bus; \
cpu->f.packed &= 0xF0; \
cpu->index = cpu->sp; \
++cpu->sp; \
cpu->instruction = _SM83InstructionLD ## HH ## _Bus; \
cpu->executionState = SM83_CORE_MEMORY_LOAD;) \
DEFINE_INSTRUCTION_SM83(POP ## REG, \
cpu->index = cpu->sp; \
++cpu->sp; \
cpu->instruction = _SM83InstructionPOP ## REG ## Delay; \
cpu->executionState = SM83_CORE_MEMORY_LOAD;) \
DEFINE_INSTRUCTION_SM83(PUSH ## REG ## Finish, \
cpu->executionState = SM83_CORE_STALL;) \
DEFINE_INSTRUCTION_SM83(PUSH ## REG ## Delay, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu-> L; \
cpu->instruction = _SM83InstructionPUSH ## REG ## Finish; \
cpu->executionState = SM83_CORE_MEMORY_STORE;) \
DEFINE_INSTRUCTION_SM83(PUSH ## REG, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu-> H; \
cpu->instruction = _SM83InstructionPUSH ## REG ## Delay; \
cpu->executionState = SM83_CORE_MEMORY_STORE;)
DEFINE_POPPUSH_INSTRUCTION_SM83(BC, B, b, c);
DEFINE_POPPUSH_INSTRUCTION_SM83(DE, D, d, e);
DEFINE_POPPUSH_INSTRUCTION_SM83(HL, H, h, l);
DEFINE_POPPUSH_INSTRUCTION_SM83(AF, A, a, f.packed);
#define DEFINE_CB_2_INSTRUCTION_SM83(NAME, WB, BODY) \
DEFINE_INSTRUCTION_SM83(NAME ## B, uint8_t reg = cpu->b; BODY; cpu->b = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## C, uint8_t reg = cpu->c; BODY; cpu->c = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## D, uint8_t reg = cpu->d; BODY; cpu->d = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## E, uint8_t reg = cpu->e; BODY; cpu->e = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## H, uint8_t reg = cpu->h; BODY; cpu->h = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## L, uint8_t reg = cpu->l; BODY; cpu->l = reg) \
DEFINE_INSTRUCTION_SM83(NAME ## HLDelay, \
uint8_t reg = cpu->bus; \
BODY; \
cpu->bus = reg; \
cpu->executionState = WB; \
cpu->instruction = _SM83InstructionNOP;) \
DEFINE_INSTRUCTION_SM83(NAME ## HL, \
cpu->index = SM83ReadHL(cpu); \
cpu->executionState = SM83_CORE_MEMORY_LOAD; \
cpu->instruction = _SM83Instruction ## NAME ## HLDelay;) \
DEFINE_INSTRUCTION_SM83(NAME ## A, uint8_t reg = cpu->a; BODY; cpu->a = reg)
#define DEFINE_CB_INSTRUCTION_SM83(NAME, WB, BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 0, WB, uint8_t bit = 1; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 1, WB, uint8_t bit = 2; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 2, WB, uint8_t bit = 4; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 3, WB, uint8_t bit = 8; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 4, WB, uint8_t bit = 16; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 5, WB, uint8_t bit = 32; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 6, WB, uint8_t bit = 64; BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 7, WB, uint8_t bit = 128; BODY)
DEFINE_CB_INSTRUCTION_SM83(BIT, SM83_CORE_FETCH, cpu->f.n = 0; cpu->f.h = 1; cpu->f.z = !(reg & bit))
DEFINE_CB_INSTRUCTION_SM83(RES, SM83_CORE_MEMORY_STORE, reg &= ~bit)
DEFINE_CB_INSTRUCTION_SM83(SET, SM83_CORE_MEMORY_STORE, reg |= bit)
#define DEFINE_CB_ALU_INSTRUCTION_SM83(NAME, BODY) \
DEFINE_CB_2_INSTRUCTION_SM83(NAME, SM83_CORE_MEMORY_STORE, \
BODY; \
cpu->f.n = 0; \
cpu->f.h = 0; \
cpu->f.z = !reg;)
DEFINE_CB_ALU_INSTRUCTION_SM83(RL, int wide = (reg << 1) | cpu->f.c; reg = wide; cpu->f.c = wide >> 8)
DEFINE_CB_ALU_INSTRUCTION_SM83(RLC, reg = (reg << 1) | (reg >> 7); cpu->f.c = reg & 1)
DEFINE_CB_ALU_INSTRUCTION_SM83(RR, int low = reg & 1; reg = (reg >> 1) | (cpu->f.c << 7); cpu->f.c = low)
DEFINE_CB_ALU_INSTRUCTION_SM83(RRC, int low = reg & 1; reg = (reg >> 1) | (low << 7); cpu->f.c = low)
DEFINE_CB_ALU_INSTRUCTION_SM83(SLA, cpu->f.c = reg >> 7; reg <<= 1)
DEFINE_CB_ALU_INSTRUCTION_SM83(SRA, cpu->f.c = reg & 1; reg = ((int8_t) reg) >> 1)
DEFINE_CB_ALU_INSTRUCTION_SM83(SRL, cpu->f.c = reg & 1; reg >>= 1)
DEFINE_CB_ALU_INSTRUCTION_SM83(SWAP, reg = (reg << 4) | (reg >> 4); cpu->f.c = 0)
DEFINE_INSTRUCTION_SM83(RLA_,
int wide = (cpu->a << 1) | cpu->f.c;
cpu->a = wide;
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = wide >> 8;)
DEFINE_INSTRUCTION_SM83(RLCA_,
cpu->a = (cpu->a << 1) | (cpu->a >> 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = cpu->a & 1;)
DEFINE_INSTRUCTION_SM83(RRA_,
int low = cpu->a & 1;
cpu->a = (cpu->a >> 1) | (cpu->f.c << 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = low;)
DEFINE_INSTRUCTION_SM83(RRCA_,
int low = cpu->a & 1;
cpu->a = (cpu->a >> 1) | (low << 7);
cpu->f.z = 0;
cpu->f.h = 0;
cpu->f.n = 0;
cpu->f.c = low;)
DEFINE_INSTRUCTION_SM83(DI, cpu->irqh.setInterrupts(cpu, false));
DEFINE_INSTRUCTION_SM83(EI, cpu->irqh.setInterrupts(cpu, true));
DEFINE_INSTRUCTION_SM83(HALT, cpu->irqh.halt(cpu));
#define DEFINE_RST_INSTRUCTION_SM83(VEC) \
DEFINE_INSTRUCTION_SM83(RST ## VEC ## UpdateSPL, \
--cpu->sp; \
cpu->index = cpu->sp; \
cpu->bus = cpu->pc; \
cpu->pc = 0x ## VEC; \
cpu->memory.setActiveRegion(cpu, cpu->pc); \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionNOP;) \
DEFINE_INSTRUCTION_SM83(RST ## VEC ## UpdateSPH, \
--cpu->sp;\
cpu->index = cpu->sp; \
cpu->bus = cpu->pc >> 8; \
cpu->executionState = SM83_CORE_MEMORY_STORE; \
cpu->instruction = _SM83InstructionRST ## VEC ## UpdateSPL;) \
DEFINE_INSTRUCTION_SM83(RST ## VEC, \
cpu->executionState = SM83_CORE_OP2; \
cpu->instruction = _SM83InstructionRST ## VEC ## UpdateSPH;)
DEFINE_RST_INSTRUCTION_SM83(00);
DEFINE_RST_INSTRUCTION_SM83(08);
DEFINE_RST_INSTRUCTION_SM83(10);
DEFINE_RST_INSTRUCTION_SM83(18);
DEFINE_RST_INSTRUCTION_SM83(20);
DEFINE_RST_INSTRUCTION_SM83(28);
DEFINE_RST_INSTRUCTION_SM83(30);
DEFINE_RST_INSTRUCTION_SM83(38);
DEFINE_INSTRUCTION_SM83(ILL, cpu->irqh.hitIllegal(cpu));
DEFINE_INSTRUCTION_SM83(STOP2, cpu->irqh.stop(cpu));
DEFINE_INSTRUCTION_SM83(STOP, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionSTOP2;)
static const SM83Instruction _sm83CBInstructionTable[0x100] = {
DECLARE_SM83_CB_EMITTER_BLOCK(_SM83Instruction)
};
DEFINE_INSTRUCTION_SM83(CBDelegate, _sm83CBInstructionTable[cpu->bus](cpu))
DEFINE_INSTRUCTION_SM83(CB, \
cpu->executionState = SM83_CORE_READ_PC; \
cpu->instruction = _SM83InstructionCBDelegate;)
const SM83Instruction _sm83InstructionTable[0x100] = {
DECLARE_SM83_EMITTER_BLOCK(_SM83Instruction)
};

View File

@ -3,11 +3,11 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/lr35902/lr35902.h>
#include <mgba/internal/sm83/sm83.h>
#include <mgba/internal/lr35902/isa-lr35902.h>
#include <mgba/internal/sm83/isa-sm83.h>
void LR35902Init(struct LR35902Core* cpu) {
void SM83Init(struct SM83Core* cpu) {
cpu->master->init(cpu, cpu->master);
size_t i;
for (i = 0; i < cpu->numComponents; ++i) {
@ -17,7 +17,7 @@ void LR35902Init(struct LR35902Core* cpu) {
}
}
void LR35902Deinit(struct LR35902Core* cpu) {
void SM83Deinit(struct SM83Core* cpu) {
if (cpu->master->deinit) {
cpu->master->deinit(cpu->master);
}
@ -29,28 +29,28 @@ void LR35902Deinit(struct LR35902Core* cpu) {
}
}
void LR35902SetComponents(struct LR35902Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras) {
void SM83SetComponents(struct SM83Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras) {
cpu->master = master;
cpu->numComponents = extra;
cpu->components = extras;
}
void LR35902HotplugAttach(struct LR35902Core* cpu, size_t slot) {
void SM83HotplugAttach(struct SM83Core* cpu, size_t slot) {
if (slot >= cpu->numComponents) {
return;
}
cpu->components[slot]->init(cpu, cpu->components[slot]);
}
void LR35902HotplugDetach(struct LR35902Core* cpu, size_t slot) {
void SM83HotplugDetach(struct SM83Core* cpu, size_t slot) {
if (slot >= cpu->numComponents) {
return;
}
cpu->components[slot]->deinit(cpu->components[slot]);
}
void LR35902Reset(struct LR35902Core* cpu) {
void SM83Reset(struct SM83Core* cpu) {
cpu->af = 0;
cpu->bc = 0;
cpu->de = 0;
@ -63,117 +63,117 @@ void LR35902Reset(struct LR35902Core* cpu) {
cpu->cycles = 0;
cpu->nextEvent = 0;
cpu->executionState = LR35902_CORE_FETCH;
cpu->executionState = SM83_CORE_FETCH;
cpu->halted = 0;
cpu->irqPending = false;
cpu->irqh.reset(cpu);
}
void LR35902RaiseIRQ(struct LR35902Core* cpu) {
void SM83RaiseIRQ(struct SM83Core* cpu) {
cpu->irqPending = true;
}
static void _LR35902InstructionIRQStall(struct LR35902Core* cpu) {
cpu->executionState = LR35902_CORE_STALL;
static void _SM83InstructionIRQStall(struct SM83Core* cpu) {
cpu->executionState = SM83_CORE_STALL;
}
static void _LR35902InstructionIRQFinish(struct LR35902Core* cpu) {
cpu->executionState = LR35902_CORE_OP2;
cpu->instruction = _LR35902InstructionIRQStall;
static void _SM83InstructionIRQFinish(struct SM83Core* cpu) {
cpu->executionState = SM83_CORE_OP2;
cpu->instruction = _SM83InstructionIRQStall;
}
static void _LR35902InstructionIRQDelay(struct LR35902Core* cpu) {
static void _SM83InstructionIRQDelay(struct SM83Core* cpu) {
--cpu->sp;
cpu->index = cpu->sp;
cpu->bus = cpu->pc;
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionIRQFinish;
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionIRQFinish;
cpu->pc = cpu->irqh.irqVector(cpu);
cpu->memory.setActiveRegion(cpu, cpu->pc);
}
static void _LR35902InstructionIRQ(struct LR35902Core* cpu) {
static void _SM83InstructionIRQ(struct SM83Core* cpu) {
--cpu->sp;
cpu->index = cpu->sp;
cpu->bus = cpu->pc >> 8;
cpu->executionState = LR35902_CORE_MEMORY_STORE;
cpu->instruction = _LR35902InstructionIRQDelay;
cpu->executionState = SM83_CORE_MEMORY_STORE;
cpu->instruction = _SM83InstructionIRQDelay;
}
static void _LR35902Step(struct LR35902Core* cpu) {
static void _SM83Step(struct SM83Core* cpu) {
++cpu->cycles;
enum LR35902ExecutionState state = cpu->executionState;
cpu->executionState = LR35902_CORE_IDLE_0;
enum SM83ExecutionState state = cpu->executionState;
cpu->executionState = SM83_CORE_IDLE_0;
switch (state) {
case LR35902_CORE_FETCH:
case SM83_CORE_FETCH:
if (cpu->irqPending) {
cpu->index = cpu->sp;
cpu->irqPending = false;
cpu->instruction = _LR35902InstructionIRQ;
cpu->instruction = _SM83InstructionIRQ;
cpu->irqh.setInterrupts(cpu, false);
break;
}
cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc);
cpu->instruction = _lr35902InstructionTable[cpu->bus];
cpu->instruction = _sm83InstructionTable[cpu->bus];
++cpu->pc;
break;
case LR35902_CORE_MEMORY_LOAD:
case SM83_CORE_MEMORY_LOAD:
cpu->bus = cpu->memory.load8(cpu, cpu->index);
break;
case LR35902_CORE_MEMORY_STORE:
case SM83_CORE_MEMORY_STORE:
cpu->memory.store8(cpu, cpu->index, cpu->bus);
break;
case LR35902_CORE_READ_PC:
case SM83_CORE_READ_PC:
cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc);
++cpu->pc;
break;
case LR35902_CORE_STALL:
cpu->instruction = _lr35902InstructionTable[0]; // NOP
case SM83_CORE_STALL:
cpu->instruction = _sm83InstructionTable[0]; // NOP
break;
default:
break;
}
}
void LR35902Tick(struct LR35902Core* cpu) {
void SM83Tick(struct SM83Core* cpu) {
while (cpu->cycles >= cpu->nextEvent) {
cpu->irqh.processEvents(cpu);
}
_LR35902Step(cpu);
_SM83Step(cpu);
if (cpu->cycles + 2 >= cpu->nextEvent) {
int32_t diff = cpu->nextEvent - cpu->cycles;
cpu->cycles = cpu->nextEvent;
cpu->executionState += diff;
cpu->irqh.processEvents(cpu);
cpu->cycles += LR35902_CORE_EXECUTE - cpu->executionState;
cpu->cycles += SM83_CORE_EXECUTE - cpu->executionState;
} else {
cpu->cycles += 2;
}
cpu->executionState = LR35902_CORE_FETCH;
cpu->executionState = SM83_CORE_FETCH;
cpu->instruction(cpu);
++cpu->cycles;
}
void LR35902Run(struct LR35902Core* cpu) {
void SM83Run(struct SM83Core* cpu) {
bool running = true;
while (running || cpu->executionState != LR35902_CORE_FETCH) {
while (running || cpu->executionState != SM83_CORE_FETCH) {
if (cpu->cycles >= cpu->nextEvent) {
cpu->irqh.processEvents(cpu);
break;
}
_LR35902Step(cpu);
_SM83Step(cpu);
if (cpu->cycles + 2 >= cpu->nextEvent) {
int32_t diff = cpu->nextEvent - cpu->cycles;
cpu->cycles = cpu->nextEvent;
cpu->executionState += diff;
cpu->irqh.processEvents(cpu);
cpu->cycles += LR35902_CORE_EXECUTE - cpu->executionState;
cpu->cycles += SM83_CORE_EXECUTE - cpu->executionState;
running = false;
} else {
cpu->cycles += 2;
}
cpu->executionState = LR35902_CORE_FETCH;
cpu->executionState = SM83_CORE_FETCH;
cpu->instruction(cpu);
++cpu->cycles;
}