@@ -692,7 +692,18 @@ typedef struct {
692692} EmulatorState ;
693693
694694const size_t s_emulator_state_size = sizeof (EmulatorState );
695-
695+ #ifdef RGBDS_LIVE
696+ #ifndef BREAKPOINTS_MAX_BANKS_NUMBER 1
697+ #define BREAKPOINTS_MAX_BANKS_NUMBER 1
698+ #endif
699+ typedef uint32_t breakpoints_type ;
700+ #define MEMORY_SIZE (64 * 1024)
701+ #define BREAKPOINTS_BIT_SIZE (sizeof(breakpoints_type) * 8)
702+ #define BREAKPOINTS_SIZE ((BREAKPOINTS_MAX_BANKS_NUMBER * MEMORY_SIZE) / BREAKPOINTS_BIT_SIZE)
703+ #define BREAKPOINTS_SHIFT (__builtin_ctz(BREAKPOINTS_BIT_SIZE))
704+ #define BREAKPOINTS_MASK (BREAKPOINTS_BIT_SIZE - 1)
705+ #define BREAKPOINTS_BANK_SHIFT (16 - BREAKPOINTS_SHIFT)
706+ #endif
696707struct Emulator {
697708 EmulatorConfig config ;
698709 FileData file_data ;
@@ -713,7 +724,7 @@ struct Emulator {
713724 CgbColorCurve cgb_color_curve ;
714725 ApuLog apu_log ;
715726#ifdef RGBDS_LIVE
716- Bool breakpoint [0x10000 ] ;
727+ breakpoints_type breakpoint [BREAKPOINTS_SIZE ] __attribute__(( aligned ( 8 ))) ;
717728#endif
718729};
719730
@@ -4637,14 +4648,42 @@ static void execute_instruction(Emulator* e) {
46374648 REG .PC = new_pc ;
46384649}
46394650
4651+ #ifdef RGBDS_LIVE
4652+ static inline uint32_t emulator_get_banked_PC_inline (Emulator * e ) {
4653+ #if BREAKPOINTS_MAX_BANKS_NUMBER > 1
4654+ uint16_t pc = REG .PC ;
4655+ if (pc < 0x4000 ) {
4656+ return (MMAP_STATE .rom_base [0 ] << (16 - ROM_BANK_SHIFT )) | pc ;
4657+ } else if (pc < 0x8000 ) {
4658+ return (MMAP_STATE .rom_base [1 ] << (16 - ROM_BANK_SHIFT )) | pc ;
4659+ } else if (pc < 0xA000 ) {
4660+ return (e -> state .vram .bank << 16 ) | pc ;
4661+ } else if (pc < 0xC000 ) {
4662+ return (MMAP_STATE .ext_ram_base << (16 - EXT_RAM_BANK_SHIFT )) | pc ;
4663+ } else if (pc < 0xE000 ) {
4664+ return (e -> state .wram .bank << 16 ) | pc ;
4665+ }
4666+ return pc ;
4667+ #else
4668+ return REG .PC
4669+ #endif
4670+ }
4671+
4672+ static inline bool is_breakpoint (Emulator * e , uint32_t banked_pc ) {
4673+ uint32_t idx = banked_pc >> BREAKPOINTS_SHIFT ;
4674+ return (e -> breakpoint [idx ] & ((breakpoints_type )1 << (banked_pc & BREAKPOINTS_MASK )));
4675+ }
4676+ #endif
4677+
46404678static void emulator_step_internal (Emulator * e ) {
46414679 if (HDMA .state == DMA_INACTIVE ) {
46424680 if (HOOK0_FALSE (emulator_step )) {
46434681 return ;
46444682 }
46454683 execute_instruction (e );
46464684#ifdef RGBDS_LIVE
4647- if (e -> breakpoint [REG .PC ]) {
4685+ uint32_t banked_pc = emulator_get_banked_PC_inline (e );
4686+ if (is_breakpoint (e , banked_pc )) {
46484687 e -> state .event |= EMULATOR_EVENT_BREAKPOINT ;
46494688 }
46504689#endif
@@ -5145,14 +5184,19 @@ void emulator_write_mem(Emulator* e, u16 addr, u8 data) {
51455184}
51465185
51475186#ifdef RGBDS_LIVE
5148- void emulator_set_breakpoint (Emulator * e , Address addr ) {
5149- e -> breakpoint [addr ] = TRUE;
5187+ void emulator_set_breakpoint (Emulator * e , uint32_t addr ) {
5188+ uint32_t idx = addr >> BREAKPOINTS_SHIFT ;
5189+ e -> breakpoint [idx ] |= ((breakpoints_type )1 << (addr & BREAKPOINTS_MASK ));
51505190}
51515191
51525192void emulator_clear_breakpoints (Emulator * e ) {
51535193 ZERO_MEMORY (e -> breakpoint );
51545194}
51555195
5196+ uint32_t emulator_get_banked_PC (Emulator * e ) {
5197+ return emulator_get_banked_PC_inline (e );
5198+ }
5199+
51565200void emulator_render_vram (Emulator * e , u32 * buffer ) {
51575201 memset (buffer , 0 , sizeof (u32 ) * 256 * 256 );
51585202 for (int ty = 0 ; ty < 24 ; ty ++ ) {
@@ -5260,6 +5304,8 @@ void emulator_render_vram(Emulator* e, u32* buffer) {}
52605304
52615305void emulator_render_background (Emulator * e , u32 * buffer , int type ) {}
52625306
5307+ uint32_t emulator_get_banked_PC (Emulator * e ) { return REG .PC ; }
5308+
52635309#endif
52645310
52655311#ifdef GBSTUDIO
0 commit comments