Merge branch 'master' (early part) into medusa
jump to
@@ -84,7 +84,6 @@ - GBA BIOS: Fix clobbered registers in CpuSet (fixes mgba.io/i/1531)
- 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@@ -102,6 +101,7 @@ - Qt: Add copy and QoL improvements to graphic views (closes mgba.io/i/1541)
- 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)@@ -111,20 +111,33 @@ - ARM: Fix STR writeback pipeline stage
- ARM: Partially fix LDM/STM writeback with empty register list - ARM: Fix stepping when events are pending - GBA DMA: Fix case where DMAs could get misaligned (fixes mgba.io/i/1092) + - GBA Memory: Fix open bus from IWRAM (fixes mgba.io/i/1575) - GBA Video: Fix OpenGL renderer 512x512 backgrounds (fixes mgba.io/i/1572) - - GBA Memory: Fix open bus from IWRAM (fixes mgba.io/i/1575) + - GBA Video: Fix BLDY for semitransparent sprite on non-target-2 backgrounds + - GBA Video: Fix effects blending improperly in some non-last windows Other fixes: - 3DS: Fix screen darkening (fixes mgba.io/i/1562) - Core: Fix uninitialized memory issues with graphics caches - Core: Return null for out of bounds cached tile VRAM querying - - Vita: Fix analog controls (fixes mgba.io/i/1554) + - OpenGL: Only invalidate texture if dimensions change (fixes mgba.io/i/1612) - Qt: Fix fast forward mute being reset (fixes mgba.io/i/1574) - Qt: Fix scrollbar arrows in memory view (fixes mgba.io/i/1558) - Qt: Fix several cases where shader selections don't get saved - Qt: Fix division by zero error in invalid TilePainter state + - Qt: Fix "restart needed" dialog after first config (fixes mgba.io/i/1601) + - Qt: Fix undesired screen filtering when paused (fixes mgba.io/i/1602) + - Qt: Fix sprite view using wrong base address (fixes mgba.io/i/1603) + - Qt: Fix inability to clear default keybindings + - Vita: Fix analog controls (fixes mgba.io/i/1554) Misc: - GB Memory: Support manual SRAM editing (fixes mgba.io/i/1580) + - GBA Audio: Redo channel 4 batching for GBA only + - GBA I/O: Stop logging several harmless invalid register reads + - 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 + - Tools: Allow using threaded renderer in perf.py 0.8 beta 1: (2019-10-20) - Initial beta for 0.8
@@ -501,7 +501,7 @@ list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/cli-debugger.c)
list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/debugger/cli.c) endif() if(M_CORE_GB) - list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/cli-debugger.c) + list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/sm83/debugger/cli-debugger.c) endif() if(M_CORE_DS) list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/cli-debugger.c)@@ -744,7 +744,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})@@ -753,9 +753,9 @@
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)
@@ -285,7 +285,7 @@
Copyright --------- -medusa is Copyright © 2013 – 2019 Jeffrey Pfau. It is distributed under the [Mozilla Public License version 2.0](https://www.mozilla.org/MPL/2.0/). A copy of the license is available in the distributed LICENSE file. +medusa is Copyright © 2013 – 2020 Jeffrey Pfau. It is distributed under the [Mozilla Public License version 2.0](https://www.mozilla.org/MPL/2.0/). A copy of the license is available in the distributed LICENSE file. medusa contains the following third-party libraries:
@@ -228,7 +228,7 @@
Copyright --------- -Copyright für mGBA © 2013 – 2018 Jeffrey Pfau. mGBA wird unter der [Mozilla Public License version 2.0](https://www.mozilla.org/MPL/2.0/) veröffentlicht. Eine Kopie der Lizenz ist in der mitgelieferten Datei LICENSE verfügbar. +Copyright für mGBA © 2013 – 2020 Jeffrey Pfau. mGBA wird unter der [Mozilla Public License version 2.0](https://www.mozilla.org/MPL/2.0/) veröffentlicht. Eine Kopie der Lizenz ist in der mitgelieferten Datei LICENSE verfügbar. mGBA beinhaltet die folgenden Bibliotheken von Drittanbietern:
@@ -69,6 +69,7 @@ uint32_t opcode;
enum mBreakpointType breakType; } bp; } type; + ssize_t pointId; }; struct mBreakpoint {
@@ -42,6 +42,11 @@ const char* format;
const char* summary; }; +struct CLIDebuggerCommandAlias { + const char* name; + const char* original; +}; + struct CLIDebuggerSystem { struct CLIDebugger* p;@@ -53,8 +58,10 @@ void (*disassemble)(struct CLIDebuggerSystem*, struct CLIDebugVector* dv);
void (*printStatus)(struct CLIDebuggerSystem*); struct CLIDebuggerCommandSummary* commands; + struct CLIDebuggerCommandAlias* commandAliases; const char* name; struct CLIDebuggerCommandSummary* platformCommands; + struct CLIDebuggerCommandAlias* platformCommandAliases; const char* platformName; };
@@ -139,6 +139,7 @@
uint32_t lfsr; int nSamples; int samples; + uint32_t lastEvent; int8_t sample; };
@@ -21,9 +21,9 @@ #include <mgba/internal/gb/sio.h>
#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 @@ SGB_MASK_EN,
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 @@
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 mRumble* rumble;
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);
@@ -79,7 +79,7 @@ * | 0x00098 - 0x0009B: Envelepe timing
* | bits 0 - 2: Remaining length * | bits 3 - 5: Next step * | bits 6 - 31: Reserved - * | 0x00098 - 0x0009F: Reserved + * | 0x0009C - 0x0009F: Last event * | 0x000A0 - 0x000A3: Next event * 0x000A4 - 0x000B7: Audio miscellaneous state * | TODO: Fix this, they're in big-endian order, but field is little-endian@@ -224,7 +224,7 @@ } ch3;
struct { int32_t lfsr; GBSerializedAudioEnvelope envelope; - int32_t reserved; + int32_t lastEvent; uint32_t nextEvent; } ch4; };
@@ -143,7 +143,8 @@ struct Window windows[MAX_WINDOW];
struct GBAVideoSoftwareBackground bg[4]; - int oamDirty; + bool forceTarget1; + bool oamDirty; int oamMax; struct GBAVideoRendererSprite sprites[128]; int tileStride;
@@ -61,7 +61,7 @@ * | 0x00180 - 0x00183: Envelepe timing
* | bits 0 - 2: Remaining length * | bits 3 - 5: Next step * | bits 6 - 31: Reserved - * | 0x00184 - 0x00187: Reserved + * | 0x00184 - 0x00187: Last event * | 0x00188 - 0x0018B: Next event * 0x0018C - 0x001AB: Audio FIFO 1 * 0x001AC - 0x001CB: Audio FIFO 2
@@ -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
@@ -1,20 +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_MEMORY_DEBUGGER_H -#define LR35902_MEMORY_DEBUGGER_H - -#include <mgba-util/common.h> - -CXX_GUARD_START - -struct LR35902Debugger; - -void LR35902DebuggerInstallMemoryShim(struct LR35902Debugger* debugger); -void LR35902DebuggerRemoveMemoryShim(struct LR35902Debugger* debugger); - -CXX_GUARD_END - -#endif
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,20 @@
+/* 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_MEMORY_DEBUGGER_H +#define SM83_MEMORY_DEBUGGER_H + +#include <mgba-util/common.h> + +CXX_GUARD_START + +struct SM83Debugger; + +void SM83DebuggerInstallMemoryShim(struct SM83Debugger* debugger); +void SM83DebuggerRemoveMemoryShim(struct SM83Debugger* debugger); + +CXX_GUARD_END + +#endif
@@ -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
@@ -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
@@ -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
@@ -1,9 +1,6 @@
+Miras Absar Jaime J. Denizard Benedikt Feih -Oskenso Kashi -The Libretro Team Mored1984 -Rhys Powell Johnathan Roatch Yuri Kunde Schlesner -Voidheim
@@ -22,17 +22,21 @@ static void _disassembleMode(struct CLIDebugger*, struct CLIDebugVector*, enum ExecutionMode mode);
static uint32_t _printLine(struct CLIDebugger* debugger, uint32_t address, enum ExecutionMode mode); static struct CLIDebuggerCommandSummary _armCommands[] = { - { "b/a", _setBreakpointARM, "I", "Set a software breakpoint as ARM" }, - { "b/t", _setBreakpointThumb, "I", "Set a software breakpoint as Thumb" }, { "break/a", _setBreakpointARM, "I", "Set a software breakpoint as ARM" }, { "break/t", _setBreakpointThumb, "I", "Set a software breakpoint as Thumb" }, - { "dis/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, - { "dis/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, - { "disasm/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, - { "disasm/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, { "disassemble/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, { "disassemble/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, { 0, 0, 0, 0 } +}; + +static struct CLIDebuggerCommandAlias _armCommandAliases[] = { + { "b/a", "break/a" }, + { "b/t", "break/t" }, + { "dis/a", "disassemble/a" }, + { "dis/t", "disassemble/t" }, + { "disasm/a", "disassemble/a" }, + { "disasm/t", "disassemble/t" }, + { 0, 0 } }; static inline void _printPSR(struct CLIDebuggerBackend* be, union PSR psr) {@@ -175,4 +179,5 @@ debugger->printStatus = _printStatus;
debugger->disassemble = _disassemble; debugger->platformName = "ARM"; debugger->platformCommands = _armCommands; + debugger->platformCommandAliases = _armCommandAliases; }
@@ -60,7 +60,8 @@ }
} struct mDebuggerEntryInfo info = { .address = breakpoint->d.address, - .type.bp.breakType = BREAKPOINT_HARDWARE + .type.bp.breakType = BREAKPOINT_HARDWARE, + .pointId = breakpoint->d.id }; mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); }@@ -142,6 +143,7 @@ if (reason == DEBUGGER_ENTER_BREAKPOINT) {
struct ARMDebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu)); if (breakpoint && breakpoint->d.type == BREAKPOINT_SOFTWARE) { info->address = breakpoint->d.address; + info->pointId = breakpoint->d.id; if (debugger->clearSoftwareBreakpoint) { debugger->clearSoftwareBreakpoint(debugger, breakpoint); }
@@ -121,6 +121,7 @@ info->type.wp.newValue = newValue;
info->address = address; info->type.wp.watchType = watchpoint->type; info->type.wp.accessType = type; + info->pointId = watchpoint->id; return true; } }
@@ -71,32 +71,17 @@ static void _source(struct CLIDebugger*, struct CLIDebugVector*);
#endif static struct CLIDebuggerCommandSummary _debuggerCommands[] = { - { "b", _setBreakpoint, "Is", "Set a breakpoint" }, { "break", _setBreakpoint, "Is", "Set a breakpoint" }, - { "c", _continue, "", "Continue execution" }, { "continue", _continue, "", "Continue execution" }, - { "d", _clearBreakpoint, "I", "Delete a breakpoint or watchpoint" }, { "delete", _clearBreakpoint, "I", "Delete a breakpoint or watchpoint" }, - { "dis", _disassemble, "Ii", "Disassemble instructions" }, - { "disasm", _disassemble, "Ii", "Disassemble instructions" }, { "disassemble", _disassemble, "Ii", "Disassemble instructions" }, - { "h", _printHelp, "S", "Print help" }, { "help", _printHelp, "S", "Print help" }, - { "i", _printStatus, "", "Print the current status" }, - { "info", _printStatus, "", "Print the current status" }, - { "lb", _listBreakpoints, "", "List breakpoints" }, { "listb", _listBreakpoints, "", "List breakpoints" }, - { "lw", _listWatchpoints, "", "List watchpoints" }, { "listw", _listWatchpoints, "", "List watchpoints" }, - { "n", _next, "", "Execute next instruction" }, { "next", _next, "", "Execute next instruction" }, - { "p", _print, "S+", "Print a value" }, - { "p/t", _printBin, "S+", "Print a value as binary" }, - { "p/x", _printHex, "S+", "Print a value as hexadecimal" }, { "print", _print, "S+", "Print a value" }, { "print/t", _printBin, "S+", "Print a value as binary" }, { "print/x", _printHex, "S+", "Print a value as hexadecimal" }, - { "q", _quit, "", "Quit the emulator" }, { "quit", _quit, "", "Quit the emulator" }, { "reset", _reset, "", "Reset the emulation" }, { "r/1", _readByte, "I", "Read a byte from a specified offset" },@@ -104,7 +89,6 @@ { "r/2", _readHalfword, "I", "Read a halfword from a specified offset" },
{ "r/4", _readWord, "I", "Read a word from a specified offset" }, { "status", _printStatus, "", "Print the current status" }, { "trace", _trace, "Is", "Trace a number of instructions" }, - { "w", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, { "w/r", _writeRegister, "SI", "Write a register" },@@ -123,6 +107,26 @@ #if !defined(NDEBUG) && !defined(_WIN32)
{ "!", _breakInto, "", "Break into attached debugger (for developers)" }, #endif { 0, 0, 0, 0 } +}; + +static struct CLIDebuggerCommandAlias _debuggerCommandAliases[] = { + { "b", "break" }, + { "c", "continue" }, + { "d", "delete" }, + { "dis", "disassemble" }, + { "disasm", "disassemble" }, + { "h", "help" }, + { "i", "status" }, + { "info", "status" }, + { "lb", "listb" }, + { "lw", "listw" }, + { "n", "next" }, + { "p", "print" }, + { "p/t", "print/t" }, + { "p/x", "print/x" }, + { "q", "quit" }, + { "w", "watch" }, + { 0, 0 } }; #if !defined(NDEBUG) && !defined(_WIN32)@@ -232,42 +236,71 @@ }
debugger->backend->printf(debugger->backend, " 0x%08X\n", intValue); } +static void _printCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases) { + int i; + for (i = 0; commands[i].name; ++i) { + debugger->backend->printf(debugger->backend, "%-15s %s\n", commands[i].name, commands[i].summary); + if (aliases) { + bool printedAlias = false; + int j; + for (j = 0; aliases[j].name; ++j) { + if (strcmp(aliases[j].original, commands[i].name) == 0) { + if (!printedAlias) { + debugger->backend->printf(debugger->backend, " Aliases:"); + printedAlias = true; + } + debugger->backend->printf(debugger->backend, " %s", aliases[j].name); + } + } + if (printedAlias) { + debugger->backend->printf(debugger->backend, "\n"); + } + } + } +} + +static void _printCommandSummary(struct CLIDebugger* debugger, const char* name, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases) { + int i; + for (i = 0; commands[i].name; ++i) { + if (strcmp(commands[i].name, name) == 0) { + debugger->backend->printf(debugger->backend, " %s\n", commands[i].summary); + if (aliases) { + bool printedAlias = false; + int j; + for (j = 0; aliases[j].name; ++j) { + if (strcmp(aliases[j].original, commands[i].name) == 0) { + if (!printedAlias) { + debugger->backend->printf(debugger->backend, " Aliases:"); + printedAlias = true; + } + debugger->backend->printf(debugger->backend, " %s", aliases[j].name); + } + } + if (printedAlias) { + debugger->backend->printf(debugger->backend, "\n"); + } + } + return; + } + } +} + static void _printHelp(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { UNUSED(dv); if (!dv) { debugger->backend->printf(debugger->backend, "Generic commands:\n"); - int i; - for (i = 0; _debuggerCommands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", _debuggerCommands[i].name, _debuggerCommands[i].summary); - } + _printCommands(debugger, _debuggerCommands, _debuggerCommandAliases); if (debugger->system) { - debugger->backend->printf(debugger->backend, "%s commands:\n", debugger->system->platformName); - for (i = 0; debugger->system->platformCommands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", debugger->system->platformCommands[i].name, debugger->system->platformCommands[i].summary); - } - debugger->backend->printf(debugger->backend, "%s commands:\n", debugger->system->name); - for (i = 0; debugger->system->commands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", debugger->system->commands[i].name, debugger->system->commands[i].summary); - } + debugger->backend->printf(debugger->backend, "\n%s commands:\n", debugger->system->platformName); + _printCommands(debugger, debugger->system->platformCommands, debugger->system->platformCommandAliases); + debugger->backend->printf(debugger->backend, "\n%s commands:\n", debugger->system->name); + _printCommands(debugger, debugger->system->commands, debugger->system->commandAliases); } } else { - int i; - for (i = 0; _debuggerCommands[i].name; ++i) { - if (strcmp(_debuggerCommands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", _debuggerCommands[i].summary); - } - } + _printCommandSummary(debugger, dv->charValue, _debuggerCommands, _debuggerCommandAliases); if (debugger->system) { - for (i = 0; debugger->system->platformCommands[i].name; ++i) { - if (strcmp(debugger->system->platformCommands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", debugger->system->platformCommands[i].summary); - } - } - for (i = 0; debugger->system->commands[i].name; ++i) { - if (strcmp(debugger->system->commands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", debugger->system->commands[i].summary); - } - } + _printCommandSummary(debugger, dv->charValue, debugger->system->platformCommands, debugger->system->platformCommandAliases); + _printCommandSummary(debugger, dv->charValue, debugger->system->commands, debugger->system->commandAliases); } } }@@ -784,11 +817,22 @@ }
return dv; } -static int _tryCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, const char* command, size_t commandLen, const char* args, size_t argsLen) { +static int _tryCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases, const char* command, size_t commandLen, const char* args, size_t argsLen) { struct CLIDebugVector* dv = NULL; struct CLIDebugVector* dvLast = NULL; int i; const char* name; + if (aliases) { + for (i = 0; (name = aliases[i].name); ++i) { + if (strlen(name) != commandLen) { + continue; + } + if (strncasecmp(name, command, commandLen) == 0) { + command = aliases[i].original; + commandLen = strlen(aliases[i].original); + } + } + } for (i = 0; (name = commands[i].name); ++i) { if (strlen(name) != commandLen) { continue;@@ -885,11 +929,11 @@ const char* args = 0;
if (firstSpace) { args = firstSpace + 1; } - int result = _tryCommands(debugger, _debuggerCommands, line, cmdLength, args, count - cmdLength - 1); + int result = _tryCommands(debugger, _debuggerCommands, _debuggerCommandAliases, line, cmdLength, args, count - cmdLength - 1); if (result < 0 && debugger->system) { - result = _tryCommands(debugger, debugger->system->commands, line, cmdLength, args, count - cmdLength - 1); + result = _tryCommands(debugger, debugger->system->commands, debugger->system->commandAliases, line, cmdLength, args, count - cmdLength - 1); if (result < 0) { - result = _tryCommands(debugger, debugger->system->platformCommands, line, cmdLength, args, count - cmdLength - 1); + result = _tryCommands(debugger, debugger->system->platformCommands, debugger->system->platformCommandAliases, line, cmdLength, args, count - cmdLength - 1); } } if (result < 0) {@@ -932,7 +976,11 @@ case DEBUGGER_ENTER_ATTACHED:
break; case DEBUGGER_ENTER_BREAKPOINT: if (info) { - cliDebugger->backend->printf(cliDebugger->backend, "Hit breakpoint at 0x%08X\n", info->address); + if (info->pointId > 0) { + cliDebugger->backend->printf(cliDebugger->backend, "Hit breakpoint %zi at 0x%08X\n", info->pointId, info->address); + } else { + cliDebugger->backend->printf(cliDebugger->backend, "Hit unknown breakpoint at 0x%08X\n", info->address); + } } else { cliDebugger->backend->printf(cliDebugger->backend, "Hit breakpoint\n"); }@@ -940,9 +988,9 @@ break;
case DEBUGGER_ENTER_WATCHPOINT: if (info) { if (info->type.wp.accessType & WATCHPOINT_WRITE) { - cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (new value = 0x%08X, old value = 0x%08X)\n", info->address, info->type.wp.newValue, info->type.wp.oldValue); + cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint %zi at 0x%08X: (new value = 0x%08X, old value = 0x%08X)\n", info->pointId, info->address, info->type.wp.newValue, info->type.wp.oldValue); } else { - cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (value = 0x%08X)\n", info->address, info->type.wp.oldValue); + cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint %zi at 0x%08X: (value = 0x%08X)\n", info->pointId, info->address, info->type.wp.oldValue); } } else { cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint\n");
@@ -16,9 +16,9 @@ #ifdef _3DS
#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 GBAudioStyle style) {
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;@@ -359,6 +359,7 @@ }
} void GBAudioWriteNR43(struct GBAudio* audio, uint8_t value) { + // TODO: Reschedule event audio->ch4.ratio = GBAudioRegisterNoiseFeedbackGetRatio(value); audio->ch4.frequency = GBAudioRegisterNoiseFeedbackGetFrequency(value); audio->ch4.power = GBAudioRegisterNoiseFeedbackGetPower(value);@@ -933,14 +934,32 @@ int32_t cycles = ch->ratio ? 2 * ch->ratio : 1;
cycles <<= ch->frequency; cycles *= 8 * audio->timingFactor; - int lsb = ch->lfsr & 1; - ch->sample = lsb * ch->envelope.currentVolume; - ++ch->nSamples; - ch->samples += ch->sample; - ch->lfsr >>= 1; - ch->lfsr ^= (lsb * 0x60) << (ch->power ? 0 : 8); + uint32_t last = 0; + uint32_t now = cycles; + uint32_t next = cycles - cyclesLate; - mTimingSchedule(timing, &audio->ch4Event, cycles - cyclesLate); + if (audio->style == GB_AUDIO_GBA) { + last = ch->lastEvent; + now = mTimingCurrentTime(timing) - cyclesLate; + ch->lastEvent = now; + now -= last; + last = 0; + if (audio->sampleInterval > next) { + // TODO: Make batching work when descheduled + next = audio->sampleInterval; + } + } + + for (; last < now; last += cycles) { + int lsb = ch->lfsr & 1; + ch->sample = lsb * ch->envelope.currentVolume; + ++ch->nSamples; + ch->samples += ch->sample; + ch->lfsr >>= 1; + ch->lfsr ^= (lsb * 0x60) << (ch->power ? 0 : 8); + } + + mTimingSchedule(timing, &audio->ch4Event, next); } void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGState* state, uint32_t* flagsOut) {@@ -984,6 +1003,7 @@ STORE_32LE(audio->ch4.lfsr, 0, &state->ch4.lfsr);
ch4Flags = GBSerializedAudioEnvelopeSetLength(ch4Flags, audio->ch4.length); ch4Flags = GBSerializedAudioEnvelopeSetNextStep(ch4Flags, audio->ch4.envelope.nextStep); STORE_32LE(ch4Flags, 0, &state->ch4.envelope); + STORE_32LE(audio->ch4.lastEvent, 0, &state->ch4.lastEvent); STORE_32LE(audio->ch4Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch4.nextEvent); STORE_32LE(flags, 0, flagsOut);@@ -1055,8 +1075,13 @@ audio->ch4.envelope.dead = GBSerializedAudioFlagsGetCh4Dead(flags);
audio->ch4.length = GBSerializedAudioEnvelopeGetLength(ch4Flags); audio->ch4.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch4Flags); LOAD_32LE(audio->ch4.lfsr, 0, &state->ch4.lfsr); + LOAD_32LE(audio->ch4.lastEvent, 0, &state->ch4.lastEvent); LOAD_32LE(when, 0, &state->ch4.nextEvent); if (audio->ch4.envelope.dead < 2 && audio->playingCh4) { + if (when - audio->ch4.lastEvent > (uint32_t) audio->sampleInterval) { + // Back-compat: fake this value + audio->ch4.lastEvent = when - audio->sampleInterval; + } mTimingSchedule(audio->timing, &audio->ch4Event, when); } }
@@ -19,8 +19,8 @@ #include <mgba/internal/gb/overrides.h>
#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>@@ -82,7 +82,7 @@
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);@@ -98,8 +98,8 @@ gbcore->cheatDevice = NULL;
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;@@ -121,9 +121,9 @@ return true;
} 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);@@ -397,9 +397,9 @@ }
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;@@ -526,7 +526,7 @@ }
} #endif - LR35902Reset(core->cpu); + SM83Reset(core->cpu); if (core->opts.skipBios) { GBSkipBIOS(core->board);@@ -537,19 +537,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) {@@ -562,9 +562,9 @@ return GBDeserialize(core->board, 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;@@ -611,7 +611,7 @@
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) {@@ -640,34 +640,34 @@ }
} 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);@@ -675,34 +675,34 @@ cpu->memory.store8(cpu, address + 3, value >> 24);
} 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);@@ -768,7 +768,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;@@ -779,19 +779,19 @@ return GBCLIDebuggerCreate(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;@@ -829,8 +829,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;@@ -1101,7 +1101,7 @@ struct GBVideoRenderer* renderer = &gbcore->renderer.d;
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/core/serialize.h>
#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,13 +29,14 @@
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; debugger->d.name = "Game Boy"; debugger->d.commands = _GBCLIDebuggerCommands; + debugger->d.commandAliases = NULL; debugger->core = core;
@@ -10,15 +10,15 @@ #include <mgba/internal/debugger/cli-debugger.h>
#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 @@ be->printf(be, "Next video mode: %i\n", mTimingUntil(&gb->timing, &gb->video.modeEvent) / 4);
} 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 {
@@ -7,7 +7,7 @@ #include <mgba/internal/gb/gb.h>
#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 @@ #include <mgba-util/vfs.h>
#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 @@ gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize);
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 @@ gb->memory.mbcType = GB_MBC_NONE;
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 @@ GBSIODeinit(&gb->sio);
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 @@ return false;
} } -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 @@ GBSavedataUnmask(gb);
} 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 @@ }
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 @@ } while (cpu->cycles >= cpu->nextEvent);
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 @@ mTimingSchedule(&gb->timing, &gb->eiPending, 4);
} } -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 @@ gb->memory.ime = true;
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 @@ mLOG(GB, STUB, "Unimplemented HALT bug");
} } -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 @@ #ifdef USE_DEBUGGERS
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 @@ }
// 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 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#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/gb.h>
#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 @@ }
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 cyclesLate);
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 @@ memory->wramBank = &memory->wram[GB_SIZE_WORKING_RAM_BANK0 * 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 @@ return GBIORead(gb, REG_IE);
} } -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 @@ }
} } -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 @@ return 0;
} } -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 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/serialize.h>
#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 @@ if (check < 0) {
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 @@ * 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/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/gb.h>
#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 _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; }
@@ -35,6 +35,7 @@ debugger->d.custom = _GBACLIDebuggerCustom;
debugger->d.name = "Game Boy Advance"; debugger->d.commands = _GBACLIDebuggerCommands; + debugger->d.commandAliases = NULL; debugger->core = core;
@@ -747,7 +747,8 @@ case CPU_COMPONENT_DEBUGGER:
if (gba->debugger) { struct mDebuggerEntryInfo info = { .address = _ARMPCAddress(cpu), - .type.bp.breakType = BREAKPOINT_SOFTWARE + .type.bp.breakType = BREAKPOINT_SOFTWARE, + .pointId = -1 }; mDebuggerEnter(gba->debugger->d.p, DEBUGGER_ENTER_BREAKPOINT, &info); }
@@ -826,8 +826,10 @@ case REG_DMA0CNT_LO:
case REG_DMA1CNT_LO: case REG_DMA2CNT_LO: case REG_DMA3CNT_LO: - // Write-only register - mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address); + // Many, many things read from the DMA register + case REG_MAX: + // Some bad interrupt libraries will read from this + // (Silent) write-only register return 0; case REG_JOY_RECV_LO:@@ -900,8 +902,6 @@ case REG_WAITCNT:
case REG_IME: // Handled transparently by registers break; - case REG_MAX: - // Some bad interrupt libraries will read from this case 0x066: case 0x06E: case 0x076:
@@ -253,7 +253,7 @@ return 0;
} int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlGetBlendEnable(renderer->objwin.packed) != GBAWindowControlIsBlendEnable(renderer->currentWindow.packed); - int variant = renderer->target1Obj && + int variant = (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT || objwinSlowPath) {@@ -263,6 +263,7 @@ target2 |= renderer->bg[1].target2;
target2 |= renderer->bg[2].target2; target2 |= renderer->bg[3].target2; if (target2) { + renderer->forceTarget1 = true; flags |= FLAG_REBLEND; variant = 0; } else {
@@ -36,8 +36,6 @@ static void GBAVideoSoftwareRendererWriteBGY_LO(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value); static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value); -static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y); - static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer); static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y);@@ -597,6 +595,7 @@ if (softwareRenderer->blendDirty) {
_updatePalettes(softwareRenderer); softwareRenderer->blendDirty = false; } + softwareRenderer->forceTarget1 = false; softwareRenderer->bg[0].highlight = softwareRenderer->d.highlightBG[0]; softwareRenderer->bg[1].highlight = softwareRenderer->d.highlightBG[1];@@ -652,9 +651,8 @@ }
} } } - if (softwareRenderer->target1Obj && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) { - int x = 0; - uint32_t mask = FLAG_REBLEND | FLAG_TARGET_1 | FLAG_IS_BACKGROUND; + if (softwareRenderer->forceTarget1 && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) { + uint32_t mask = FLAG_REBLEND | FLAG_IS_BACKGROUND; uint32_t match = FLAG_REBLEND; if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { mask |= FLAG_OBJWIN;@@ -662,11 +660,13 @@ if (GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed)) {
match |= FLAG_OBJWIN; } } + int x = 0; for (w = 0; w < softwareRenderer->nWindows; ++w) { + int end = softwareRenderer->windows[w].endX; if (!GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { + x = end; continue; } - int end = softwareRenderer->windows[w].endX; if (softwareRenderer->blendEffect == BLEND_DARKEN) { for (; x < end; ++x) { uint32_t color = softwareRenderer->row[x];
@@ -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)
@@ -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 @@ f.c ? 'C' : '-');
} 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 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 @@ for (bytesRemaining = 1; bytesRemaining; --bytesRemaining) {
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 @@ be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl);
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,9 +103,10 @@ }
_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 = "GB-Z80"; - debugger->platformCommands = _lr35902Commands; + debugger->platformName = "SM83"; + debugger->platformCommands = _sm83Commands; + debugger->platformCommandAliases = NULL; }
@@ -1,353 +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/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> - -static struct mBreakpoint* _lookupBreakpoint(struct mBreakpointList* breakpoints, struct LR35902Core* cpu) { - size_t i; - for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { - struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); - if (breakpoint->address != cpu->pc) { - continue; - } - if (breakpoint->segment < 0 || breakpoint->segment == cpu->memory.currentSegment(cpu, breakpoint->address)) { - return breakpoint; - } - } - return NULL; -} - -static void _destroyBreakpoint(struct mBreakpoint* breakpoint) { - if (breakpoint->condition) { - parseFree(breakpoint->condition); - free(breakpoint->condition); - } -} - -static void _destroyWatchpoint(struct mWatchpoint* watchpoint) { - if (watchpoint->condition) { - parseFree(watchpoint->condition); - free(watchpoint->condition); - } -} - -static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct mBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu); - if (!breakpoint) { - return; - } - if (breakpoint->condition) { - int32_t value; - int segment; - if (!mDebuggerEvaluateParseTree(d->p, breakpoint->condition, &value, &segment) || !(value || segment >= 0)) { - return; - } - } - struct mDebuggerEntryInfo info = { - .address = breakpoint->address - }; - mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); -} - -static void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform); -static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform); - -static void LR35902DebuggerEnter(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); - -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; - platform->printStatus = NULL; - return &platform->d; -} - -void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; - debugger->cpu = cpu; - debugger->originalMemory = debugger->cpu->memory; - mBreakpointListInit(&debugger->breakpoints, 0); - mWatchpointListInit(&debugger->watchpoints, 0); - debugger->nextId = 1; -} - -void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; - size_t i; - for (i = 0; i < mBreakpointListSize(&debugger->breakpoints); ++i) { - _destroyBreakpoint(mBreakpointListGetPointer(&debugger->breakpoints, i)); - } - mBreakpointListDeinit(&debugger->breakpoints); - - for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { - _destroyWatchpoint(mWatchpointListGetPointer(&debugger->watchpoints, i)); - } - mWatchpointListDeinit(&debugger->watchpoints); -} - -static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { - UNUSED(reason); - UNUSED(info); - struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; - struct LR35902Core* cpu = debugger->cpu; - cpu->nextEvent = cpu->cycles; - - if (debugger->d.p->entered) { - debugger->d.p->entered(debugger->d.p, reason, info); - } -} - -static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struct mBreakpoint* info) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct mBreakpoint* breakpoint = mBreakpointListAppend(&debugger->breakpoints); - *breakpoint = *info; - breakpoint->id = debugger->nextId; - ++debugger->nextId; - return breakpoint->id; - -} - -static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - size_t i; - - struct mBreakpointList* breakpoints = &debugger->breakpoints; - for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { - struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); - if (breakpoint->id == id) { - _destroyBreakpoint(breakpoint); - mBreakpointListShift(breakpoints, i, 1); - return true; - } - } - - struct mWatchpointList* watchpoints = &debugger->watchpoints; - for (i = 0; i < mWatchpointListSize(watchpoints); ++i) { - struct mWatchpoint* watchpoint = mWatchpointListGetPointer(watchpoints, i); - if (watchpoint->id == id) { - _destroyWatchpoint(watchpoint); - mWatchpointListShift(watchpoints, i, 1); - if (!mWatchpointListSize(&debugger->watchpoints)) { - LR35902DebuggerRemoveMemoryShim(debugger); - } - return true; - } - } - return false; -} - -static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform* d) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) 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; - if (!mWatchpointListSize(&debugger->watchpoints)) { - LR35902DebuggerInstallMemoryShim(debugger); - } - struct mWatchpoint* watchpoint = mWatchpointListAppend(&debugger->watchpoints); - *watchpoint = *info; - watchpoint->id = debugger->nextId; - ++debugger->nextId; - return watchpoint->id; -} - -static void LR35902DebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - mBreakpointListClear(list); - mBreakpointListCopy(list, &debugger->breakpoints); -} - -static void LR35902DebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) 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; - - char disassembly[64]; - - struct LR35902InstructionInfo info = {{0}}; - char* disPtr = disassembly; - uint8_t instruction; - uint16_t address = cpu->pc; - size_t bytesRemaining = 1; - for (bytesRemaining = 1; bytesRemaining; --bytesRemaining) { - 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); - }; - disPtr[0] = ':'; - disPtr[1] = ' '; - disPtr += 2; - LR35902Disassemble(&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, - cpu->d, cpu->e, cpu->h, cpu->l, - 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; - - if (strcmp(name, "a") == 0) { - *value = cpu->a; - return true; - } - if (strcmp(name, "b") == 0) { - *value = cpu->b; - return true; - } - if (strcmp(name, "c") == 0) { - *value = cpu->c; - return true; - } - if (strcmp(name, "d") == 0) { - *value = cpu->d; - return true; - } - if (strcmp(name, "e") == 0) { - *value = cpu->e; - return true; - } - if (strcmp(name, "h") == 0) { - *value = cpu->h; - return true; - } - if (strcmp(name, "l") == 0) { - *value = cpu->l; - return true; - } - if (strcmp(name, "bc") == 0) { - *value = cpu->bc; - return true; - } - if (strcmp(name, "de") == 0) { - *value = cpu->de; - return true; - } - if (strcmp(name, "hl") == 0) { - *value = cpu->hl; - return true; - } - if (strcmp(name, "af") == 0) { - *value = cpu->af; - return true; - } - if (strcmp(name, "pc") == 0) { - *value = cpu->pc; - return true; - } - if (strcmp(name, "sp") == 0) { - *value = cpu->sp; - return true; - } - if (strcmp(name, "f") == 0) { - *value = cpu->f.packed; - return true; - } - return false; -} - -bool LR35902DebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32_t value) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct LR35902Core* cpu = debugger->cpu; - - if (strcmp(name, "a") == 0) { - cpu->a = value; - return true; - } - if (strcmp(name, "b") == 0) { - cpu->b = value; - return true; - } - if (strcmp(name, "c") == 0) { - cpu->c = value; - return true; - } - if (strcmp(name, "d") == 0) { - cpu->d = value; - return true; - } - if (strcmp(name, "e") == 0) { - cpu->e = value; - return true; - } - if (strcmp(name, "h") == 0) { - cpu->h = value; - return true; - } - if (strcmp(name, "l") == 0) { - cpu->l = value; - return true; - } - if (strcmp(name, "bc") == 0) { - cpu->bc = value; - return true; - } - if (strcmp(name, "de") == 0) { - cpu->de = value; - return true; - } - if (strcmp(name, "hl") == 0) { - cpu->hl = value; - return true; - } - if (strcmp(name, "af") == 0) { - cpu->af = value; - cpu->f.packed &= 0xF0; - return true; - } - if (strcmp(name, "pc") == 0) { - cpu->pc = value; - cpu->memory.setActiveRegion(cpu, cpu->pc); - return true; - } - if (strcmp(name, "sp") == 0) { - cpu->sp = value; - return true; - } - if (strcmp(name, "f") == 0) { - cpu->f.packed = value & 0xF0; - return true; - } - return false; -}
@@ -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 @@ DEBUGGER = 0; \
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 @@ } while(0)
#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 @@ } \
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) {@@ -60,19 +60,20 @@ info->type.wp.newValue = newValue;
info->address = address; info->type.wp.watchType = watchpoint->type; info->type.wp.accessType = type; + info->pointId = watchpoint->id; return true; } } 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; }
@@ -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) -};
@@ -1,180 +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/lr35902.h> - -#include <mgba/internal/lr35902/isa-lr35902.h> - -void LR35902Init(struct LR35902Core* cpu) { - cpu->master->init(cpu, cpu->master); - size_t i; - for (i = 0; i < cpu->numComponents; ++i) { - if (cpu->components[i] && cpu->components[i]->init) { - cpu->components[i]->init(cpu, cpu->components[i]); - } - } -} - -void LR35902Deinit(struct LR35902Core* cpu) { - if (cpu->master->deinit) { - cpu->master->deinit(cpu->master); - } - size_t i; - for (i = 0; i < cpu->numComponents; ++i) { - if (cpu->components[i] && cpu->components[i]->deinit) { - cpu->components[i]->deinit(cpu->components[i]); - } - } -} - -void LR35902SetComponents(struct LR35902Core* 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) { - if (slot >= cpu->numComponents) { - return; - } - cpu->components[slot]->init(cpu, cpu->components[slot]); -} - -void LR35902HotplugDetach(struct LR35902Core* cpu, size_t slot) { - if (slot >= cpu->numComponents) { - return; - } - cpu->components[slot]->deinit(cpu->components[slot]); -} - -void LR35902Reset(struct LR35902Core* cpu) { - cpu->af = 0; - cpu->bc = 0; - cpu->de = 0; - cpu->hl = 0; - - cpu->sp = 0; - cpu->pc = 0; - - cpu->instruction = 0; - - cpu->cycles = 0; - cpu->nextEvent = 0; - cpu->executionState = LR35902_CORE_FETCH; - cpu->halted = 0; - - cpu->irqPending = false; - cpu->irqh.reset(cpu); -} - -void LR35902RaiseIRQ(struct LR35902Core* cpu) { - cpu->irqPending = true; -} - -static void _LR35902InstructionIRQStall(struct LR35902Core* cpu) { - cpu->executionState = LR35902_CORE_STALL; -} - -static void _LR35902InstructionIRQFinish(struct LR35902Core* cpu) { - cpu->executionState = LR35902_CORE_OP2; - cpu->instruction = _LR35902InstructionIRQStall; -} - -static void _LR35902InstructionIRQDelay(struct LR35902Core* cpu) { - --cpu->sp; - cpu->index = cpu->sp; - cpu->bus = cpu->pc; - cpu->executionState = LR35902_CORE_MEMORY_STORE; - cpu->instruction = _LR35902InstructionIRQFinish; - cpu->pc = cpu->irqh.irqVector(cpu); - cpu->memory.setActiveRegion(cpu, cpu->pc); -} - -static void _LR35902InstructionIRQ(struct LR35902Core* cpu) { - --cpu->sp; - cpu->index = cpu->sp; - cpu->bus = cpu->pc >> 8; - cpu->executionState = LR35902_CORE_MEMORY_STORE; - cpu->instruction = _LR35902InstructionIRQDelay; -} - -static void _LR35902Step(struct LR35902Core* cpu) { - ++cpu->cycles; - enum LR35902ExecutionState state = cpu->executionState; - cpu->executionState = LR35902_CORE_IDLE_0; - switch (state) { - case LR35902_CORE_FETCH: - if (cpu->irqPending) { - cpu->index = cpu->sp; - cpu->irqPending = false; - cpu->instruction = _LR35902InstructionIRQ; - cpu->irqh.setInterrupts(cpu, false); - break; - } - cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); - cpu->instruction = _lr35902InstructionTable[cpu->bus]; - ++cpu->pc; - break; - case LR35902_CORE_MEMORY_LOAD: - cpu->bus = cpu->memory.load8(cpu, cpu->index); - break; - case LR35902_CORE_MEMORY_STORE: - cpu->memory.store8(cpu, cpu->index, cpu->bus); - break; - case LR35902_CORE_READ_PC: - cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); - ++cpu->pc; - break; - case LR35902_CORE_STALL: - cpu->instruction = _lr35902InstructionTable[0]; // NOP - break; - default: - break; - } -} - -void LR35902Tick(struct LR35902Core* cpu) { - while (cpu->cycles >= cpu->nextEvent) { - cpu->irqh.processEvents(cpu); - } - _LR35902Step(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; - } else { - cpu->cycles += 2; - } - cpu->executionState = LR35902_CORE_FETCH; - cpu->instruction(cpu); - ++cpu->cycles; -} - -void LR35902Run(struct LR35902Core* cpu) { - bool running = true; - while (running || cpu->executionState != LR35902_CORE_FETCH) { - if (cpu->cycles >= cpu->nextEvent) { - cpu->irqh.processEvents(cpu); - break; - } - _LR35902Step(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; - running = false; - } else { - cpu->cycles += 2; - } - cpu->executionState = LR35902_CORE_FETCH; - cpu->instruction(cpu); - ++cpu->cycles; - } -}
@@ -17,6 +17,8 @@
static void mGLContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct mGLContext* context = (struct mGLContext*) v; + v->width = 1; + v->height = 1; glGenTextures(2, context->tex); glBindTexture(GL_TEXTURE_2D, context->tex[0]); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);@@ -35,6 +37,9 @@ }
static void mGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { struct mGLContext* context = (struct mGLContext*) v; + if (width == v->width && height == v->height) { + return; + } v->width = width; v->height = height;
@@ -98,6 +98,8 @@
static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct mGLES2Context* context = (struct mGLES2Context*) v; + v->width = 1; + v->height = 1; glGenTextures(1, &context->tex); glBindTexture(GL_TEXTURE_2D, context->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);@@ -172,6 +174,9 @@ }
static void mGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { struct mGLES2Context* context = (struct mGLES2Context*) v; + if (width == v->width && height == v->height) { + return; + } v->width = width; v->height = height;
@@ -63,7 +63,7 @@ #include <mgba/internal/gba/input.h>
#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>
@@ -39,7 +39,7 @@ #include <mgba/internal/ds/input.h>
#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 @@ # 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/. 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 @@ def __init__(self, native):
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 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
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):
@@ -72,8 +72,10 @@ if (action->isActive()) {
qaction->setChecked(true); } const Shortcut* shortcut = shortcuts.shortcut(actionName); - if (shortcut && shortcut->shortcut() > 0) { - qaction->setShortcut(QKeySequence(shortcut->shortcut())); + if (shortcut) { + if (shortcut->shortcut() > 0) { + qaction->setShortcut(QKeySequence(shortcut->shortcut())); + } } else if (!m_defaultShortcuts[actionName].isEmpty()) { qaction->setShortcut(m_defaultShortcuts[actionName][0]); }
@@ -231,7 +231,7 @@ bindKey(m_keyR, GBA_KEY_R);
m_controller->saveConfiguration(m_type); #ifdef BUILD_SDL - if (m_profileSelect) { + if (m_profileSelect && m_profileSelect->count()) { m_controller->setPreferredGamepad(m_type, m_profileSelect->currentIndex()); } #endif
@@ -120,6 +120,7 @@ } else {
m_ui.palette->setText(QString::number(newInfo.paletteId)); m_ui.tile->setBoundary(2048, 0, 2); m_ui.tile->setPalette(newInfo.paletteId); + m_boundary = 2048; } if (newInfo != m_objInfo) { force = true;
@@ -11,7 +11,7 @@ #ifdef M_CORE_GBA
#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 @@ break;
#endif #ifdef M_CORE_GB case PLATFORM_GB: - updateRegistersLR35902(); + updateRegistersSM83(); break; #endif default:@@ -127,9 +127,9 @@ }
#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 @@ #ifdef M_CORE_GBA
void updateRegistersARM(); #endif #ifdef M_CORE_GB - void updateRegistersLR35902(); + void updateRegistersSM83(); #endif QMap<QString, QLabel*> m_registers;
@@ -466,9 +466,12 @@ emit displayDriverChanged();
} QVariant cameraDriver = m_ui.cameraDriver->itemData(m_ui.cameraDriver->currentIndex()); - if (cameraDriver != m_controller->getQtOption("cameraDriver")) { + QVariant oldCameraDriver = m_controller->getQtOption("cameraDriver"); + if (cameraDriver != oldCameraDriver) { m_controller->setQtOption("cameraDriver", cameraDriver); - emit cameraDriverChanged(); + if (cameraDriver.toInt() != static_cast<int>(InputController::CameraDriver::NONE) || !oldCameraDriver.isNull()) { + emit cameraDriverChanged(); + } } QVariant camera = m_ui.camera->itemData(m_ui.camera->currentIndex());
@@ -292,6 +292,7 @@ if (m_display) {
m_display->lockAspectRatio(opts->lockAspectRatio); m_display->filter(opts->resampleVideo); } + m_screenWidget->filter(opts->resampleVideo); m_inputController.setScreensaverSuspendable(opts->suspendScreensaver); }@@ -975,6 +976,7 @@ m_display->lockAspectRatio(opts->lockAspectRatio);
m_display->lockIntegerScaling(opts->lockIntegerScaling); m_display->interframeBlending(opts->interframeBlending); m_display->filter(opts->resampleVideo); + m_screenWidget->filter(opts->resampleVideo); m_config->updateOption("showOSD"); #if defined(BUILD_GL) || defined(BUILD_GLES2) if (opts->shader) {@@ -1479,6 +1481,7 @@ resampleVideo->connect([this](const QVariant& value) {
if (m_display) { m_display->filter(value.toBool()); } + m_screenWidget->filter(value.toBool()); }, this); m_config->updateOption("resampleVideo");@@ -1995,11 +1998,15 @@ m_centered = false;
m_lockAspectRatio = lock; } +void WindowBackground::filter(bool filter) { + m_filter = filter; +} + void WindowBackground::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); const QPixmap& logo = pixmap(); QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::SmoothPixmapTransform, m_filter); painter.fillRect(QRect(QPoint(), size()), Qt::black); QSize s = size(); QSize ds = s;
@@ -244,6 +244,7 @@ void setDimensions(int width, int height);
void setCenteredAspectRatio(int width, int height); void setLockIntegerScaling(bool lock); void setLockAspectRatio(bool lock); + void filter(bool filter); const QPixmap& pixmap() const { return m_pixmap; }@@ -258,6 +259,7 @@ int m_aspectWidth;
int m_aspectHeight; bool m_lockAspectRatio; bool m_lockIntegerScaling; + bool m_filter; }; }
@@ -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)
@@ -0,0 +1,354 @@
+/* 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/debugger/debugger.h> + +#include <mgba/core/core.h> +#include <mgba/internal/debugger/parser.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 SM83Core* cpu) { + size_t i; + for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { + struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); + if (breakpoint->address != cpu->pc) { + continue; + } + if (breakpoint->segment < 0 || breakpoint->segment == cpu->memory.currentSegment(cpu, breakpoint->address)) { + return breakpoint; + } + } + return NULL; +} + +static void _destroyBreakpoint(struct mBreakpoint* breakpoint) { + if (breakpoint->condition) { + parseFree(breakpoint->condition); + free(breakpoint->condition); + } +} + +static void _destroyWatchpoint(struct mWatchpoint* watchpoint) { + if (watchpoint->condition) { + parseFree(watchpoint->condition); + free(watchpoint->condition); + } +} + +static void SM83DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + struct mBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu); + if (!breakpoint) { + return; + } + if (breakpoint->condition) { + int32_t value; + int segment; + if (!mDebuggerEvaluateParseTree(d->p, breakpoint->condition, &value, &segment) || !(value || segment >= 0)) { + return; + } + } + struct mDebuggerEntryInfo info = { + .address = breakpoint->address, + .pointId = breakpoint->id + }; + mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); +} + +static void SM83DebuggerInit(void* cpu, struct mDebuggerPlatform* platform); +static void SM83DebuggerDeinit(struct mDebuggerPlatform* platform); + +static void SM83DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info); + +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* 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 SM83DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { + struct SM83Debugger* debugger = (struct SM83Debugger*) platform; + debugger->cpu = cpu; + debugger->originalMemory = debugger->cpu->memory; + mBreakpointListInit(&debugger->breakpoints, 0); + mWatchpointListInit(&debugger->watchpoints, 0); + debugger->nextId = 1; +} + +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)); + } + mBreakpointListDeinit(&debugger->breakpoints); + + for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { + _destroyWatchpoint(mWatchpointListGetPointer(&debugger->watchpoints, i)); + } + mWatchpointListDeinit(&debugger->watchpoints); +} + +static void SM83DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { + UNUSED(reason); + UNUSED(info); + struct SM83Debugger* debugger = (struct SM83Debugger*) platform; + struct SM83Core* cpu = debugger->cpu; + cpu->nextEvent = cpu->cycles; + + if (debugger->d.p->entered) { + debugger->d.p->entered(debugger->d.p, reason, info); + } +} + +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; + ++debugger->nextId; + return breakpoint->id; + +} + +static bool SM83DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + size_t i; + + struct mBreakpointList* breakpoints = &debugger->breakpoints; + for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { + struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); + if (breakpoint->id == id) { + _destroyBreakpoint(breakpoint); + mBreakpointListShift(breakpoints, i, 1); + return true; + } + } + + struct mWatchpointList* watchpoints = &debugger->watchpoints; + for (i = 0; i < mWatchpointListSize(watchpoints); ++i) { + struct mWatchpoint* watchpoint = mWatchpointListGetPointer(watchpoints, i); + if (watchpoint->id == id) { + _destroyWatchpoint(watchpoint); + mWatchpointListShift(watchpoints, i, 1); + if (!mWatchpointListSize(&debugger->watchpoints)) { + SM83DebuggerRemoveMemoryShim(debugger); + } + return true; + } + } + return false; +} + +static bool SM83DebuggerHasBreakpoints(struct mDebuggerPlatform* d) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + return mBreakpointListSize(&debugger->breakpoints) || mWatchpointListSize(&debugger->watchpoints); +} + +static ssize_t SM83DebuggerSetWatchpoint(struct mDebuggerPlatform* d, const struct mWatchpoint* info) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + if (!mWatchpointListSize(&debugger->watchpoints)) { + SM83DebuggerInstallMemoryShim(debugger); + } + struct mWatchpoint* watchpoint = mWatchpointListAppend(&debugger->watchpoints); + *watchpoint = *info; + watchpoint->id = debugger->nextId; + ++debugger->nextId; + return watchpoint->id; +} + +static void SM83DebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + mBreakpointListClear(list); + mBreakpointListCopy(list, &debugger->breakpoints); +} + +static void SM83DebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) { + struct SM83Debugger* debugger = (struct SM83Debugger*) d; + mWatchpointListClear(list); + mWatchpointListCopy(list, &debugger->watchpoints); +} + +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 SM83InstructionInfo info = {{0}}; + char* disPtr = disassembly; + uint8_t instruction; + uint16_t address = cpu->pc; + size_t bytesRemaining = 1; + for (bytesRemaining = 1; bytesRemaining; --bytesRemaining) { + instruction = debugger->d.p->core->rawRead8(debugger->d.p->core, address, -1); + disPtr += snprintf(disPtr, sizeof(disassembly) - (disPtr - disassembly), "%02X", instruction); + ++address; + bytesRemaining += SM83Decode(instruction, &info); + }; + disPtr[0] = ':'; + disPtr[1] = ' '; + disPtr += 2; + 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, + cpu->d, cpu->e, cpu->h, cpu->l, + cpu->sp, cpu->memory.currentSegment(cpu, cpu->pc), cpu->pc, disassembly); +} + +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; + return true; + } + if (strcmp(name, "b") == 0) { + *value = cpu->b; + return true; + } + if (strcmp(name, "c") == 0) { + *value = cpu->c; + return true; + } + if (strcmp(name, "d") == 0) { + *value = cpu->d; + return true; + } + if (strcmp(name, "e") == 0) { + *value = cpu->e; + return true; + } + if (strcmp(name, "h") == 0) { + *value = cpu->h; + return true; + } + if (strcmp(name, "l") == 0) { + *value = cpu->l; + return true; + } + if (strcmp(name, "bc") == 0) { + *value = cpu->bc; + return true; + } + if (strcmp(name, "de") == 0) { + *value = cpu->de; + return true; + } + if (strcmp(name, "hl") == 0) { + *value = cpu->hl; + return true; + } + if (strcmp(name, "af") == 0) { + *value = cpu->af; + return true; + } + if (strcmp(name, "pc") == 0) { + *value = cpu->pc; + return true; + } + if (strcmp(name, "sp") == 0) { + *value = cpu->sp; + return true; + } + if (strcmp(name, "f") == 0) { + *value = cpu->f.packed; + return true; + } + return false; +} + +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; + return true; + } + if (strcmp(name, "b") == 0) { + cpu->b = value; + return true; + } + if (strcmp(name, "c") == 0) { + cpu->c = value; + return true; + } + if (strcmp(name, "d") == 0) { + cpu->d = value; + return true; + } + if (strcmp(name, "e") == 0) { + cpu->e = value; + return true; + } + if (strcmp(name, "h") == 0) { + cpu->h = value; + return true; + } + if (strcmp(name, "l") == 0) { + cpu->l = value; + return true; + } + if (strcmp(name, "bc") == 0) { + cpu->bc = value; + return true; + } + if (strcmp(name, "de") == 0) { + cpu->de = value; + return true; + } + if (strcmp(name, "hl") == 0) { + cpu->hl = value; + return true; + } + if (strcmp(name, "af") == 0) { + cpu->af = value; + cpu->f.packed &= 0xF0; + return true; + } + if (strcmp(name, "pc") == 0) { + cpu->pc = value; + cpu->memory.setActiveRegion(cpu, cpu->pc); + return true; + } + if (strcmp(name, "sp") == 0) { + cpu->sp = value; + return true; + } + if (strcmp(name, "f") == 0) { + cpu->f.packed = value & 0xF0; + return true; + } + return false; +}
@@ -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; +}
@@ -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) +};
@@ -0,0 +1,180 @@
+/* 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/sm83.h> + +#include <mgba/internal/sm83/isa-sm83.h> + +void SM83Init(struct SM83Core* cpu) { + cpu->master->init(cpu, cpu->master); + size_t i; + for (i = 0; i < cpu->numComponents; ++i) { + if (cpu->components[i] && cpu->components[i]->init) { + cpu->components[i]->init(cpu, cpu->components[i]); + } + } +} + +void SM83Deinit(struct SM83Core* cpu) { + if (cpu->master->deinit) { + cpu->master->deinit(cpu->master); + } + size_t i; + for (i = 0; i < cpu->numComponents; ++i) { + if (cpu->components[i] && cpu->components[i]->deinit) { + cpu->components[i]->deinit(cpu->components[i]); + } + } +} + +void SM83SetComponents(struct SM83Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras) { + cpu->master = master; + cpu->numComponents = extra; + cpu->components = extras; +} + + +void SM83HotplugAttach(struct SM83Core* cpu, size_t slot) { + if (slot >= cpu->numComponents) { + return; + } + cpu->components[slot]->init(cpu, cpu->components[slot]); +} + +void SM83HotplugDetach(struct SM83Core* cpu, size_t slot) { + if (slot >= cpu->numComponents) { + return; + } + cpu->components[slot]->deinit(cpu->components[slot]); +} + +void SM83Reset(struct SM83Core* cpu) { + cpu->af = 0; + cpu->bc = 0; + cpu->de = 0; + cpu->hl = 0; + + cpu->sp = 0; + cpu->pc = 0; + + cpu->instruction = 0; + + cpu->cycles = 0; + cpu->nextEvent = 0; + cpu->executionState = SM83_CORE_FETCH; + cpu->halted = 0; + + cpu->irqPending = false; + cpu->irqh.reset(cpu); +} + +void SM83RaiseIRQ(struct SM83Core* cpu) { + cpu->irqPending = true; +} + +static void _SM83InstructionIRQStall(struct SM83Core* cpu) { + cpu->executionState = SM83_CORE_STALL; +} + +static void _SM83InstructionIRQFinish(struct SM83Core* cpu) { + cpu->executionState = SM83_CORE_OP2; + cpu->instruction = _SM83InstructionIRQStall; +} + +static void _SM83InstructionIRQDelay(struct SM83Core* cpu) { + --cpu->sp; + cpu->index = cpu->sp; + cpu->bus = cpu->pc; + cpu->executionState = SM83_CORE_MEMORY_STORE; + cpu->instruction = _SM83InstructionIRQFinish; + cpu->pc = cpu->irqh.irqVector(cpu); + cpu->memory.setActiveRegion(cpu, cpu->pc); +} + +static void _SM83InstructionIRQ(struct SM83Core* cpu) { + --cpu->sp; + cpu->index = cpu->sp; + cpu->bus = cpu->pc >> 8; + cpu->executionState = SM83_CORE_MEMORY_STORE; + cpu->instruction = _SM83InstructionIRQDelay; +} + +static void _SM83Step(struct SM83Core* cpu) { + ++cpu->cycles; + enum SM83ExecutionState state = cpu->executionState; + cpu->executionState = SM83_CORE_IDLE_0; + switch (state) { + case SM83_CORE_FETCH: + if (cpu->irqPending) { + cpu->index = cpu->sp; + cpu->irqPending = false; + cpu->instruction = _SM83InstructionIRQ; + cpu->irqh.setInterrupts(cpu, false); + break; + } + cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); + cpu->instruction = _sm83InstructionTable[cpu->bus]; + ++cpu->pc; + break; + case SM83_CORE_MEMORY_LOAD: + cpu->bus = cpu->memory.load8(cpu, cpu->index); + break; + case SM83_CORE_MEMORY_STORE: + cpu->memory.store8(cpu, cpu->index, cpu->bus); + break; + case SM83_CORE_READ_PC: + cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); + ++cpu->pc; + break; + case SM83_CORE_STALL: + cpu->instruction = _sm83InstructionTable[0]; // NOP + break; + default: + break; + } +} + +void SM83Tick(struct SM83Core* cpu) { + while (cpu->cycles >= cpu->nextEvent) { + cpu->irqh.processEvents(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 += SM83_CORE_EXECUTE - cpu->executionState; + } else { + cpu->cycles += 2; + } + cpu->executionState = SM83_CORE_FETCH; + cpu->instruction(cpu); + ++cpu->cycles; +} + +void SM83Run(struct SM83Core* cpu) { + bool running = true; + while (running || cpu->executionState != SM83_CORE_FETCH) { + if (cpu->cycles >= cpu->nextEvent) { + cpu->irqh.processEvents(cpu); + break; + } + _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 += SM83_CORE_EXECUTE - cpu->executionState; + running = false; + } else { + cpu->cycles += 2; + } + cpu->executionState = SM83_CORE_FETCH; + cpu->instruction(cpu); + ++cpu->cycles; + } +}
@@ -28,8 +28,10 @@
def run(self, cwd): args = [os.path.join(os.getcwd(), self.EXECUTABLE), '-P'] args.extend(self.get_args()) - if self.renderer != 'software': + if not self.renderer: args.append('-N') + elif self.renderer == 'threaded-software': + args.append('-T') args.append(self.rom) env = {} if 'LD_LIBRARY_PATH' in os.environ:@@ -91,8 +93,10 @@ server_command = [os.path.join(os.getcwd(), PerfTest.EXECUTABLE)]
server_command.extend(['--', '-PD', '0']) if hasattr(test, "frames"): server_command.extend(['-F', str(test.frames)]) - if test.renderer != "software": + if not test.renderer: server_command.append('-N') + elif test.renderer == 'threaded-software': + server_command.append('-T') subprocess.check_call(server_command) time.sleep(4) self.socket = socket.create_connection(self.address, timeout=1000)@@ -170,13 +174,19 @@ parser = argparse.ArgumentParser()
parser.add_argument('-w', '--wall-time', type=float, default=0, metavar='TIME', help='wall-clock time') parser.add_argument('-g', '--game-frames', type=int, default=0, metavar='FRAMES', help='game-clock frames') parser.add_argument('-N', '--disable-renderer', action='store_const', const=True, help='disable video rendering') + parser.add_argument('-T', '--threaded-renderer', action='store_const', const=True, help='threaded video rendering') parser.add_argument('-s', '--server', metavar='ADDRESS', help='run on server') parser.add_argument('-S', '--server-command', metavar='COMMAND', help='command to launch server') parser.add_argument('-o', '--out', metavar='FILE', help='output file path') parser.add_argument('directory', help='directory containing ROM files') args = parser.parse_args() - s = Suite(args.directory, wall=args.wall_time, game=args.game_frames, renderer=None if args.disable_renderer else 'software') + renderer = 'software' + if args.disable_renderer: + renderer = None + elif args.threaded_renderer: + renderer = 'threaded-software' + s = Suite(args.directory, wall=args.wall_time, game=args.game_frames, renderer=renderer) if args.server: if args.server_command: server = PerfServer(args.server, args.server_command)