diff --git a/Core/apu.c b/Core/apu.c index cfee4df..2196997 100644 --- a/Core/apu.c +++ b/Core/apu.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "gb.h" static const uint8_t duties[] = { diff --git a/Core/cheats.h b/Core/cheats.h index 6577be3..9c38f4b 100644 --- a/Core/cheats.h +++ b/Core/cheats.h @@ -1,5 +1,6 @@ #ifndef cheats_h #define cheats_h +#ifndef GB_DISABLE_CHEATS #include "defs.h" #define GB_CHEAT_ANY_BANK 0xFFFF @@ -17,12 +18,8 @@ void GB_load_cheats(GB_gameboy_t *gb, const char *path); int GB_save_cheats(GB_gameboy_t *gb, const char *path); #ifdef GB_INTERNAL -#ifdef GB_DISABLE_CHEATS -#define GB_apply_cheat(...) -#else internal void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value); #endif -#endif typedef struct { size_t size; @@ -38,5 +35,9 @@ struct GB_cheat_s { bool enabled; char description[128]; }; - +#else +#ifdef GB_INTERNAL +#define GB_apply_cheat(...) +#endif // GB_INTERNAL +#endif // GB_DISABLE_CHEATS #endif diff --git a/Core/debugger.h b/Core/debugger.h index 7c226e2..a69d11a 100644 --- a/Core/debugger.h +++ b/Core/debugger.h @@ -1,5 +1,6 @@ #ifndef debugger_h #define debugger_h +#ifndef GB_DISABLE_DEBUGGER #include #include #include "defs.h" @@ -7,17 +8,20 @@ void GB_debugger_break(GB_gameboy_t *gb); #ifdef GB_INTERNAL -#ifdef GB_DISABLE_DEBUGGER -#define GB_debugger_run(gb) (void)0 -#define GB_debugger_handle_async_commands(gb) (void)0 -#define GB_debugger_ret_hook(gb) (void)0 -#define GB_debugger_call_hook(gb, addr) (void)addr -#define GB_debugger_test_write_watchpoint(gb, addr, value) ((void)addr, (void)value) -#define GB_debugger_test_read_watchpoint(gb, addr) (void)addr -#define GB_debugger_add_symbol(gb, bank, address, symbol) ((void)bank, (void)address, (void)symbol) -#define GB_debugger_break(gb) (void)0 - +bool /* Returns true if debugger waits for more commands. Not relevant for non-GB_INTERNAL */ #else +void +#endif +GB_debugger_execute_command(GB_gameboy_t *gb, char *input); /* Destroys input. */ +char *GB_debugger_complete_substring(GB_gameboy_t *gb, char *input, uintptr_t *context); /* Destroys input, result requires free */ +void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path); +const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr); +bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result, uint16_t *result_bank); /* result_bank is -1 if unused. */ +bool GB_debugger_is_stopped(GB_gameboy_t *gb); +void GB_debugger_set_disabled(GB_gameboy_t *gb, bool disabled); +void GB_debugger_clear_symbols(GB_gameboy_t *gb); + +#ifdef GB_INTERNAL internal void GB_debugger_run(GB_gameboy_t *gb); internal void GB_debugger_handle_async_commands(GB_gameboy_t *gb); internal void GB_debugger_call_hook(GB_gameboy_t *gb, uint16_t call_addr); @@ -26,21 +30,20 @@ internal void GB_debugger_test_write_watchpoint(GB_gameboy_t *gb, uint16_t addr, internal void GB_debugger_test_read_watchpoint(GB_gameboy_t *gb, uint16_t addr); internal const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr); internal void GB_debugger_add_symbol(GB_gameboy_t *gb, uint16_t bank, uint16_t address, const char *symbol); -#endif /* GB_DISABLE_DEBUGGER */ #endif +#else // GB_DISABLE_DEBUGGER #ifdef GB_INTERNAL -bool /* Returns true if debugger waits for more commands. Not relevant for non-GB_INTERNAL */ -#else -void -#endif -GB_debugger_execute_command(GB_gameboy_t *gb, char *input); /* Destroys input. */ -char *GB_debugger_complete_substring(GB_gameboy_t *gb, char *input, uintptr_t *context); /* Destroys input, result requires free */ +#define GB_debugger_run(gb) (void)0 +#define GB_debugger_handle_async_commands(gb) (void)0 +#define GB_debugger_ret_hook(gb) (void)0 +#define GB_debugger_call_hook(gb, addr) (void)addr +#define GB_debugger_test_write_watchpoint(gb, addr, value) ((void)addr, (void)value) +#define GB_debugger_test_read_watchpoint(gb, addr) (void)addr +#define GB_debugger_add_symbol(gb, bank, address, symbol) ((void)bank, (void)address, (void)symbol) +#define GB_debugger_break(gb) (void)0 +#endif // GB_INTERNAL + +#endif // GB_DISABLE_DEBUGGER -void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path); -const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr); -bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result, uint16_t *result_bank); /* result_bank is -1 if unused. */ -bool GB_debugger_is_stopped(GB_gameboy_t *gb); -void GB_debugger_set_disabled(GB_gameboy_t *gb, bool disabled); -void GB_debugger_clear_symbols(GB_gameboy_t *gb); #endif diff --git a/Core/gb.c b/Core/gb.c index 75de6f8..de84912 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -211,11 +211,19 @@ void GB_free(GB_gameboy_t *gb) if (gb->rom) { free(gb->rom); } + if (gb->sgb) { + free(gb->sgb); + } +#ifndef GB_DISABLE_DEBUGGER + GB_debugger_clear_symbols(gb); +#endif + GB_rewind_reset(gb); +#ifndef GB_DISABLE_CHEATS if (gb->breakpoints) { free(gb->breakpoints); } - if (gb->sgb) { - free(gb->sgb); + if (gb->watchpoints) { + free(gb->watchpoints); } if (gb->nontrivial_jump_state) { free(gb->nontrivial_jump_state); @@ -223,11 +231,6 @@ void GB_free(GB_gameboy_t *gb) if (gb->undo_state) { free(gb->undo_state); } -#ifndef GB_DISABLE_DEBUGGER - GB_debugger_clear_symbols(gb); -#endif - GB_rewind_reset(gb); -#ifndef GB_DISABLE_CHEATS while (gb->cheats) { GB_remove_cheat(gb, gb->cheats[0]); } @@ -1762,10 +1765,12 @@ static void GB_reset_internal(GB_gameboy_t *gb, bool quick) GB_set_internal_div_counter(gb, 8); +#ifndef GB_DISABLE_DEBUGGER if (gb->nontrivial_jump_state) { free(gb->nontrivial_jump_state); gb->nontrivial_jump_state = NULL; } +#endif if (!quick) { reset_ram(gb); @@ -1812,10 +1817,12 @@ void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model) gb->ram = realloc(gb->ram, gb->ram_size = 0x2000); gb->vram = realloc(gb->vram, gb->vram_size = 0x2000); } +#ifndef GB_DISABLE_DEBUGGER if (gb->undo_state) { free(gb->undo_state); gb->undo_state = NULL; } +#endif GB_rewind_reset(gb); GB_reset(gb); load_default_border(gb); diff --git a/Core/gb.h b/Core/gb.h index 94a89b1..dce544d 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -724,6 +724,7 @@ struct GB_gameboy_internal_s { GB_lcd_status_callback_t lcd_status_callback; GB_debugger_reload_callback_t debugger_reload_callback; +#ifndef GB_DISABLE_DEBUGGER /*** Debugger ***/ volatile bool debug_stopped, debug_disable; bool debug_fin_command, debug_next_command; @@ -765,7 +766,9 @@ struct GB_gameboy_internal_s { /* Undo */ uint8_t *undo_state; const char *undo_label; +#endif +#ifndef GB_DISABLE_REWIND /* Rewind */ size_t rewind_buffer_length; size_t rewind_state_size; @@ -775,6 +778,7 @@ struct GB_gameboy_internal_s { unsigned pos; } *rewind_sequences; // lasts about 4 seconds size_t rewind_pos; +#endif /* SGB - saved and allocated optionally */ GB_sgb_t *sgb; @@ -783,11 +787,13 @@ struct GB_gameboy_internal_s { double sgb_intro_sweep_phase; double sgb_intro_sweep_previous_sample; - /* Cheats */ +#ifndef GB_DISABLE_CHEATS + /* Cheats */ bool cheat_enabled; size_t cheat_count; GB_cheat_t **cheats; GB_cheat_hash_t *cheat_hash[256]; +#endif /* Misc */ bool turbo; diff --git a/Core/memory.c b/Core/memory.c index b1f61c9..5ada092 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -1,5 +1,6 @@ #include #include +#include #include "gb.h" typedef uint8_t read_function_t(GB_gameboy_t *gb, uint16_t addr); @@ -758,9 +759,11 @@ uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr) { GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) +#ifndef GB_DISABLE_DEBUGGER if (unlikely(gb->n_watchpoints)) { GB_debugger_test_read_watchpoint(gb, addr); } +#endif if (unlikely(is_addr_in_dma_use(gb, addr))) { if (GB_is_cgb(gb) && bus_for_addr(gb, addr) == GB_BUS_MAIN && gb->dma_current_src >= 0xE000) { /* This is cart specific! Everdrive 7X on a CGB-A or 0 behaves differently. */ @@ -1760,10 +1763,11 @@ void GB_set_write_memory_callback(GB_gameboy_t *gb, GB_write_memory_callback_t c void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) { GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) - +#ifndef GB_DISABLE_DEBUGGER if (unlikely(gb->n_watchpoints)) { GB_debugger_test_write_watchpoint(gb, addr, value); } +#endif if (bus_for_addr(gb, addr) == GB_BUS_MAIN && addr < 0xFF00) { gb->data_bus = value; gb->data_bus_decay_countdown = gb->data_bus_decay; diff --git a/Core/printer.c b/Core/printer.c index 93f51fa..005f452 100644 --- a/Core/printer.c +++ b/Core/printer.c @@ -1,4 +1,5 @@ #include "gb.h" +#include /* TODO: Emulation is VERY basic and assumes the ROM correctly uses the printer's interface. Incorrect usage is not correctly emulated, as it's not well documented, nor do I diff --git a/Core/rewind.h b/Core/rewind.h index 750b2bc..f08bf3e 100644 --- a/Core/rewind.h +++ b/Core/rewind.h @@ -1,6 +1,6 @@ #ifndef rewind_h #define rewind_h - +#ifndef GB_DISABLE_REWIND #include #include "defs.h" @@ -12,3 +12,4 @@ void GB_set_rewind_length(GB_gameboy_t *gb, double seconds); void GB_rewind_reset(GB_gameboy_t *gb); #endif +#endif diff --git a/Core/save_state.c b/Core/save_state.c index aefc72e..bb49215 100644 --- a/Core/save_state.c +++ b/Core/save_state.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #ifdef GB_BIG_ENDIAN #define BESS_NAME "SameBoy v" GB_VERSION " (Big Endian)" diff --git a/Core/sgb.c b/Core/sgb.c index 8a29d50..036ef2f 100644 --- a/Core/sgb.c +++ b/Core/sgb.c @@ -2,6 +2,7 @@ #include "random.h" #include #include +#include #ifndef M_PI #define M_PI 3.14159265358979323846 diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index b590c00..9129dc6 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -949,9 +949,11 @@ LD_X_Y(a,b) LD_X_Y(a,c) LD_X_Y(a,d) LD_X_Y(a,e) LD_X_Y(a,h) LD_X_Y(a,l) LD_X_DHL // fire the debugger if software breakpoints are enabled static void ld_b_b(GB_gameboy_t *gb, uint8_t opcode) { +#ifndef GB_DISABLE_DEBUGGER if (gb->has_software_breakpoints) { GB_debugger_break(gb); } +#endif } static void add_a_r(GB_gameboy_t *gb, uint8_t opcode) diff --git a/Core/sm83_cpu.h b/Core/sm83_cpu.h index 9839c58..94abe7c 100644 --- a/Core/sm83_cpu.h +++ b/Core/sm83_cpu.h @@ -3,7 +3,9 @@ #include "defs.h" #include +#ifndef GB_DISABLE_DEBUGGER void GB_cpu_disassemble(GB_gameboy_t *gb, uint16_t pc, uint16_t count); +#endif #ifdef GB_INTERNAL internal void GB_cpu_run(GB_gameboy_t *gb); #endif diff --git a/Core/symbol_hash.h b/Core/symbol_hash.h index 773074f..2812774 100644 --- a/Core/symbol_hash.h +++ b/Core/symbol_hash.h @@ -1,6 +1,6 @@ #ifndef symbol_hash_h #define symbol_hash_h - +#ifndef GB_DISABLE_DEBUGGER #include #include #include @@ -34,5 +34,5 @@ internal const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16 internal GB_symbol_map_t *GB_map_alloc(void); internal void GB_map_free(GB_symbol_map_t *map); #endif - +#endif #endif diff --git a/Core/timing.c b/Core/timing.c index 7d2ca94..993fbbd 100644 --- a/Core/timing.c +++ b/Core/timing.c @@ -436,7 +436,9 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) } } +#ifndef GB_DISABLE_DEBUGGER gb->debugger_ticks += cycles; +#endif if (gb->speed_switch_freeze) { if (gb->speed_switch_freeze >= cycles) { @@ -451,7 +453,9 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) cycles <<= 1; } +#ifndef GB_DISABLE_DEBUGGER gb->absolute_debugger_ticks += cycles; +#endif // Not affected by speed boost if (likely(gb->io_registers[GB_IO_LCDC] & GB_LCDC_ENABLE)) { diff --git a/Core/workboy.c b/Core/workboy.c index 8144022..df69f34 100644 --- a/Core/workboy.c +++ b/Core/workboy.c @@ -1,5 +1,6 @@ #include "gb.h" #include +#include static inline uint8_t int_to_bcd(uint8_t i) { diff --git a/Makefile b/Makefile index dd871d8..6643088 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,46 @@ ifeq ($(MAKECMDGOALS),) MAKECMDGOALS := $(DEFAULT) endif +ifneq ($(DISABLE_TIMEKEEPING),) +CFLAGS += -DGB_DISABLE_TIMEKEEPING +CPPP_FLAGS += -DGB_DISABLE_TIMEKEEPING +else +CPPP_FLAGS += -UGB_DISABLE_TIMEKEEPING +endif + +ifneq ($(DISABLE_REWIND),) +CFLAGS += -DGB_DISABLE_REWIND +CPPP_FLAGS += -DGB_DISABLE_REWIND +CORE_FILTER += Core/rewind.c +else +CPPP_FLAGS += -UGB_DISABLE_REWIND +endif + +ifneq ($(DISABLE_DEBUGGER),) +CFLAGS += -DGB_DISABLE_DEBUGGER +CPPP_FLAGS += -DGB_DISABLE_DEBUGGER +CORE_FILTER += Core/debugger.c Core/sm83_disassembler.c Core/symbol_hash.c +else +CPPP_FLAGS += -UGB_DISABLE_DEBUGGER +endif + +ifneq ($(DISABLE_CHEATS),) +CFLAGS += -DGB_DISABLE_CHEATS +CPPP_FLAGS += -DGB_DISABLE_CHEATS +CORE_FILTER += Core/cheats.c +else +CPPP_FLAGS += -UGB_DISABLE_CHEATS +endif + +ifneq ($(CORE_FILTER)$(DISABLE_TIMEKEEPING),) +ifneq ($(MAKECMDGOALS),lib) +$(error SameBoy features can only be disabled when compiling the 'lib' target) +endif +endif + +CPPP_FLAGS += -UGB_INTERNAL + + include version.mk COPYRIGHT_YEAR := $(shell grep -oE "20[2-9][0-9]" LICENSE) export VERSION @@ -284,7 +324,7 @@ endif # Get a list of our source files and their respective object file targets -CORE_SOURCES := $(shell ls Core/*.c) +CORE_SOURCES := $(filter-out $(CORE_FILTER),$(shell ls Core/*.c)) CORE_HEADERS := $(shell ls Core/*.h) SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG) $(patsubst %,SDL/audio/%.c,$(SDL_AUDIO_DRIVERS)) TESTER_SOURCES := $(shell ls Tester/*.c) @@ -673,7 +713,7 @@ $(LIB)/libsameboy.a: $(LIB)/libsameboy.o $(INC)/%.h: Core/%.h -@$(MKDIR) -p $(dir $@) -@# CPPP doesn't like multibyte characters, so we replace the single quote character before processing so it doesn't complain - sed "s/'/@SINGLE_QUOTE@/g" $^ | cppp -UGB_INTERNAL | sed "s/@SINGLE_QUOTE@/'/g" > $@ + sed "s/'/@SINGLE_QUOTE@/g" $^ | cppp $(CPPP_FLAGS) | sed "s/@SINGLE_QUOTE@/'/g" > $@ lib-unsupported: @echo Due to limitations of lld-link, compiling SameBoy as a library on Windows is not supported. diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 2093d0d..72fcd38 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -9,7 +9,6 @@ SOURCES_C := $(CORE_DIR)/Core/gb.c \ $(CORE_DIR)/Core/mbc.c \ $(CORE_DIR)/Core/timing.c \ $(CORE_DIR)/Core/display.c \ - $(CORE_DIR)/Core/symbol_hash.c \ $(CORE_DIR)/Core/camera.c \ $(CORE_DIR)/Core/sm83_cpu.c \ $(CORE_DIR)/Core/joypad.c \