mirror of
https://github.com/libretro/mgba.git
synced 2024-11-23 16:10:01 +00:00
SM83: Rename LR35902 to SM83
This commit is contained in:
parent
b6f863be26
commit
51a122f20d
3
CHANGES
3
CHANGES
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
112
include/mgba/internal/sm83/decoder.h
Normal file
112
include/mgba/internal/sm83/decoder.h
Normal 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
|
528
include/mgba/internal/sm83/emitter-sm83.h
Normal file
528
include/mgba/internal/sm83/emitter-sm83.h
Normal 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
|
@ -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
|
||||
|
146
include/mgba/internal/sm83/sm83.h
Normal file
146
include/mgba/internal/sm83/sm83.h
Normal 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
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
44
src/gb/gb.c
44
src/gb/gb.c
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
@ -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;
|
||||
}
|
@ -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)
|
||||
};
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
@ -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());
|
||||
|
@ -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
16
src/sm83/CMakeLists.txt
Normal 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)
|
@ -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;
|
||||
}
|
@ -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;
|
@ -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
580
src/sm83/decoder.c
Normal 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
820
src/sm83/isa-sm83.c
Normal 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)
|
||||
};
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user