Merge branch 'master' into timing
# Conflicts: # Core/display.c # Core/z80_cpu.c
This commit is contained in:
commit
b702d56547
@ -12,6 +12,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
enum {
|
enum {
|
||||||
LVALUE_MEMORY,
|
LVALUE_MEMORY,
|
||||||
|
LVALUE_MEMORY16,
|
||||||
LVALUE_REG16,
|
LVALUE_REG16,
|
||||||
LVALUE_REG_H,
|
LVALUE_REG_H,
|
||||||
LVALUE_REG_L,
|
LVALUE_REG_L,
|
||||||
@ -210,6 +211,19 @@ static value_t read_lvalue(GB_gameboy_t *gb, lvalue_t lvalue)
|
|||||||
}
|
}
|
||||||
return VALUE_16(GB_read_memory(gb, lvalue.memory_address.value));
|
return VALUE_16(GB_read_memory(gb, lvalue.memory_address.value));
|
||||||
|
|
||||||
|
case LVALUE_MEMORY16:
|
||||||
|
if (lvalue.memory_address.has_bank) {
|
||||||
|
banking_state_t state;
|
||||||
|
save_banking_state(gb, &state);
|
||||||
|
switch_banking_state(gb, lvalue.memory_address.bank);
|
||||||
|
value_t r = VALUE_16(GB_read_memory(gb, lvalue.memory_address.value));
|
||||||
|
restore_banking_state(gb, &state);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return VALUE_16(GB_read_memory(gb, lvalue.memory_address.value) |
|
||||||
|
(GB_read_memory(gb, lvalue.memory_address.value + 1) * 0x100));
|
||||||
|
|
||||||
|
|
||||||
case LVALUE_REG16:
|
case LVALUE_REG16:
|
||||||
return VALUE_16(*lvalue.register_address);
|
return VALUE_16(*lvalue.register_address);
|
||||||
|
|
||||||
@ -236,6 +250,19 @@ static void write_lvalue(GB_gameboy_t *gb, lvalue_t lvalue, uint16_t value)
|
|||||||
GB_write_memory(gb, lvalue.memory_address.value, value);
|
GB_write_memory(gb, lvalue.memory_address.value, value);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case LVALUE_MEMORY16:
|
||||||
|
if (lvalue.memory_address.has_bank) {
|
||||||
|
banking_state_t state;
|
||||||
|
save_banking_state(gb, &state);
|
||||||
|
switch_banking_state(gb, lvalue.memory_address.bank);
|
||||||
|
GB_write_memory(gb, lvalue.memory_address.value, value);
|
||||||
|
restore_banking_state(gb, &state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GB_write_memory(gb, lvalue.memory_address.value, value);
|
||||||
|
GB_write_memory(gb, lvalue.memory_address.value + 1, value >> 8);
|
||||||
|
return;
|
||||||
|
|
||||||
case LVALUE_REG16:
|
case LVALUE_REG16:
|
||||||
*lvalue.register_address = value;
|
*lvalue.register_address = value;
|
||||||
return;
|
return;
|
||||||
@ -382,6 +409,22 @@ static lvalue_t debugger_evaluate_lvalue(GB_gameboy_t *gb, const char *string,
|
|||||||
return (lvalue_t){LVALUE_MEMORY, .memory_address = debugger_evaluate(gb, string + 1, length - 2, error, watchpoint_address, watchpoint_new_value)};
|
return (lvalue_t){LVALUE_MEMORY, .memory_address = debugger_evaluate(gb, string + 1, length - 2, error, watchpoint_address, watchpoint_new_value)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (string[0] == '{' && string[length - 1] == '}') {
|
||||||
|
// Attempt to strip curly parentheses (memory dereference)
|
||||||
|
signed int depth = 0;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (string[i] == '{') depth++;
|
||||||
|
if (depth == 0) {
|
||||||
|
// First and last are not matching
|
||||||
|
depth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (string[i] == '}') depth--;
|
||||||
|
}
|
||||||
|
if (depth == 0) {
|
||||||
|
return (lvalue_t){LVALUE_MEMORY16, .memory_address = debugger_evaluate(gb, string + 1, length - 2, error, watchpoint_address, watchpoint_new_value)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
if (string[0] != '$' && (string[0] < '0' || string[0] > '9')) {
|
if (string[0] != '$' && (string[0] < '0' || string[0] > '9')) {
|
||||||
@ -486,7 +529,33 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
|
|||||||
}
|
}
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (string[0] == '{' && string[length - 1] == '}') {
|
||||||
|
// Attempt to strip curly parentheses (memory dereference)
|
||||||
|
signed int depth = 0;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (string[i] == '{') depth++;
|
||||||
|
if (depth == 0) {
|
||||||
|
// First and last are not matching
|
||||||
|
depth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (string[i] == '}') depth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth == 0) {
|
||||||
|
value_t addr = debugger_evaluate(gb, string + 1, length - 2, error, watchpoint_address, watchpoint_new_value);
|
||||||
|
banking_state_t state;
|
||||||
|
if (addr.bank) {
|
||||||
|
save_banking_state(gb, &state);
|
||||||
|
switch_banking_state(gb, addr.bank);
|
||||||
|
}
|
||||||
|
ret = VALUE_16(GB_read_memory(gb, addr.value) | (GB_read_memory(gb, addr.value + 1) * 0x100));
|
||||||
|
if (addr.bank) {
|
||||||
|
restore_banking_state(gb, &state);
|
||||||
|
}
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Search for lowest priority operator
|
// Search for lowest priority operator
|
||||||
signed int depth = 0;
|
signed int depth = 0;
|
||||||
|
@ -254,7 +254,7 @@ struct GB_gameboy_internal_s {
|
|||||||
bool halted;
|
bool halted;
|
||||||
bool stopped;
|
bool stopped;
|
||||||
bool boot_rom_finished;
|
bool boot_rom_finished;
|
||||||
bool ime_toggle; /* ei (and di in CGB) have delayed effects.*/
|
bool ime_toggle; /* ei has delayed a effect.*/
|
||||||
bool halt_bug;
|
bool halt_bug;
|
||||||
|
|
||||||
/* Misc state */
|
/* Misc state */
|
||||||
@ -275,6 +275,7 @@ struct GB_gameboy_internal_s {
|
|||||||
uint16_t dma_current_src;
|
uint16_t dma_current_src;
|
||||||
int16_t dma_cycles;
|
int16_t dma_cycles;
|
||||||
bool is_dma_restarting;
|
bool is_dma_restarting;
|
||||||
|
uint8_t last_opcode_read; /* Required to emulte HDMA reads from Exxx */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* MBC */
|
/* MBC */
|
||||||
|
@ -110,6 +110,10 @@ static uint8_t read_banked_ram(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (gb->hdma_on) {
|
||||||
|
return gb->last_opcode_read;
|
||||||
|
}
|
||||||
|
|
||||||
if (addr < 0xFE00) {
|
if (addr < 0xFE00) {
|
||||||
return gb->ram[addr & 0x0FFF];
|
return gb->ram[addr & 0x0FFF];
|
||||||
}
|
}
|
||||||
@ -122,7 +126,8 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0xFF00) {
|
if (addr < 0xFF00) {
|
||||||
/* Unusable. CGB results are verified, but DMG results were tested on a SGB2 */
|
/* Unusable. CGB results are verified, but DMG results were tested on a SGB2 */
|
||||||
|
/* Also, writes to this area are not emulated */
|
||||||
if ((gb->io_registers[GB_IO_STAT] & 0x3) >= 2) { /* Seems to be disabled in Modes 2 and 3 */
|
if ((gb->io_registers[GB_IO_STAT] & 0x3) >= 2) { /* Seems to be disabled in Modes 2 and 3 */
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -1398,11 +1398,11 @@ void GB_cpu_run(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
/* Run mode */
|
/* Run mode */
|
||||||
else if(!gb->halted) {
|
else if(!gb->halted) {
|
||||||
uint8_t opcode = GB_read_memory(gb, gb->pc++);
|
gb->last_opcode_read = GB_read_memory(gb, gb->pc++);
|
||||||
if (gb->halt_bug) {
|
if (gb->halt_bug) {
|
||||||
gb->pc--;
|
gb->pc--;
|
||||||
gb->halt_bug = false;
|
gb->halt_bug = false;
|
||||||
}
|
}
|
||||||
opcodes[opcode](gb, opcode);
|
opcodes[gb->last_opcode_read](gb, gb->last_opcode_read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ static void call_a16(GB_gameboy_t *gb, uint8_t opcode, uint16_t *pc)
|
|||||||
{
|
{
|
||||||
(*pc)++;
|
(*pc)++;
|
||||||
uint16_t addr = GB_read_memory(gb, *pc) | (GB_read_memory(gb, *pc + 1) << 8);
|
uint16_t addr = GB_read_memory(gb, *pc) | (GB_read_memory(gb, *pc + 1) << 8);
|
||||||
const char *symbol = GB_debugger_name_for_address(gb, 0xff00 + addr);
|
const char *symbol = GB_debugger_name_for_address(gb, addr);
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
GB_log(gb, "CALL %s ; =$%04x\n", symbol, addr);
|
GB_log(gb, "CALL %s ; =$%04x\n", symbol, addr);
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ static const struct menu_item paused_menu[] = {
|
|||||||
{"Keyboard", enter_controls_menu},
|
{"Keyboard", enter_controls_menu},
|
||||||
{"Joypad", enter_joypad_menu},
|
{"Joypad", enter_joypad_menu},
|
||||||
{"Help", item_help},
|
{"Help", item_help},
|
||||||
{"Exit", item_exit},
|
{"Quit SameBoy", item_exit},
|
||||||
{NULL,}
|
{NULL,}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,14 +23,29 @@ ifeq ($(TARGET_ARCH),mips)
|
|||||||
LOCAL_CXXFLAGS += -DANDROID_MIPS
|
LOCAL_CXXFLAGS += -DANDROID_MIPS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CORE_DIR := ../..
|
CORE_DIR := $(realpath ../..)
|
||||||
|
|
||||||
include ../Makefile.common
|
include ../Makefile.common
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C)
|
LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C)
|
||||||
LOCAL_CFLAGS += -DINLINE=inline -DHAVE_STDINT_H -DHAVE_INTTYPES_H -D__LIBRETRO__ -DNDEBUG -D_USE_MATH_DEFINES -DGB_INTERNAL -std=c99 -I$(CORE_DIR) -DSAMEBOY_CORE_VERSION=\"$(VERSION)\"
|
LOCAL_CFLAGS += -DINLINE=inline -DHAVE_STDINT_H -DHAVE_INTTYPES_H -D__LIBRETRO__ -DNDEBUG -D_USE_MATH_DEFINES -DGB_INTERNAL -std=c99 -I$(CORE_DIR) -DSAMEBOY_CORE_VERSION=\"$(VERSION)\" -DDISABLE_DEBUGGER -DDISABLE_TIMEKEEPING -Wno-multichar
|
||||||
|
|
||||||
LOCAL_C_INCLUDES = $(INCFLAGS)
|
LOCAL_C_INCLUDES = $(INCFLAGS)
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
$(CORE_DIR)/libretro/%_boot.c: $(CORE_DIR)/build/bin/BootROMs/%_boot.bin
|
||||||
|
echo "/* AUTO-GENERATED */" > $@
|
||||||
|
echo "const unsigned char $(notdir $(@:%.c=%))[] = {" >> $@
|
||||||
|
ifneq ($(findstring Haiku,$(shell uname -s)),)
|
||||||
|
# turns out od is posix, hexdump is not hence is less portable
|
||||||
|
# this is still rather ugly and could be done better I guess
|
||||||
|
od -A none -t x1 -v $< | sed -e 's/^\ /0x/' -e 's/\ /,\ 0x/g' -e 's/$$/,/g' | tr '\n' ' ' >> $@
|
||||||
|
else
|
||||||
|
hexdump -v -e '/1 "0x%02x, "' $< >> $@
|
||||||
|
endif
|
||||||
|
echo "};" >> $@
|
||||||
|
echo "const unsigned $(notdir $(@:%.c=%))_length = sizeof($(notdir $(@:%.c=%)));" >> $@
|
||||||
|
|
||||||
|
$(CORE_DIR)/build/bin/BootROMs/%_boot.bin:
|
||||||
|
$(MAKE) -C .. $(patsubst $(CORE_DIR)/%,%,$@)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user