mirror of https://github.com/inolen/redream.git
use -fms-extensions for anonymous base device struct
This commit is contained in:
parent
17fecaeae0
commit
bc632abacd
|
@ -1,5 +1,6 @@
|
|||
.
|
||||
/build
|
||||
debug
|
||||
Makefile
|
||||
*.swo
|
||||
*.swp
|
||||
|
|
249
CMakeLists.txt
249
CMakeLists.txt
|
@ -218,7 +218,7 @@ endif()
|
|||
source_group_by_dir(REDREAM_SOURCES)
|
||||
|
||||
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
|
||||
set(REDREAM_COMPILE_FLAGS -Wall -Wextra -Werror -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-strict-aliasing -D_GNU_SOURCE)
|
||||
set(REDREAM_COMPILE_FLAGS -fms-extensions -Wall -Wextra -Werror -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-strict-aliasing -D_GNU_SOURCE)
|
||||
|
||||
# some flavors of GCC require this to be defined for the PR* macros in inttypes.h
|
||||
if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
@ -273,131 +273,130 @@ target_link_libraries(recc ${REDREAM_LIBS})
|
|||
target_compile_definitions(recc PRIVATE MICROPROFILE_ENABLED=0 ${REDREAM_DEFS})
|
||||
target_compile_options(recc PRIVATE ${REDREAM_COMPILE_FLAGS})
|
||||
|
||||
|
||||
#--------------------------------------------------
|
||||
# tests
|
||||
#--------------------------------------------------
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "")
|
||||
add_subdirectory(deps/gtest-1.7.0 EXCLUDE_FROM_ALL)
|
||||
|
||||
# compile master .inc file from .s files in test/asm
|
||||
set(TEST_ASM
|
||||
test/asm/add.s
|
||||
test/asm/addc.s
|
||||
test/asm/addv.s
|
||||
test/asm/and.s
|
||||
test/asm/bf.s
|
||||
test/asm/bra.s
|
||||
test/asm/braf.s
|
||||
test/asm/bsr.s
|
||||
test/asm/bsrf.s
|
||||
test/asm/bt.s
|
||||
test/asm/cmp.s
|
||||
test/asm/div0.s
|
||||
test/asm/div1s.s
|
||||
test/asm/div1u.s
|
||||
test/asm/dmul.s
|
||||
test/asm/dt.s
|
||||
test/asm/ext.s
|
||||
test/asm/fabs.s
|
||||
test/asm/fadd.s
|
||||
test/asm/fcmpeq.s
|
||||
test/asm/fcmpgt.s
|
||||
test/asm/fcnv.s
|
||||
test/asm/fdiv.s
|
||||
test/asm/fipr.s
|
||||
test/asm/fld.s
|
||||
test/asm/float.s
|
||||
test/asm/fmac.s
|
||||
test/asm/fmov.s
|
||||
test/asm/fmov_load.s
|
||||
test/asm/fmov_index_load.s
|
||||
test/asm/fmov_store.s
|
||||
test/asm/fmov_index_store.s
|
||||
test/asm/fmov_save.s
|
||||
test/asm/fmov_restore.s
|
||||
test/asm/fmul.s
|
||||
test/asm/fneg.s
|
||||
test/asm/frchg.s
|
||||
test/asm/fsca.s
|
||||
test/asm/fschg.s
|
||||
test/asm/fsrra.s
|
||||
test/asm/fsqrt.s
|
||||
test/asm/fsub.s
|
||||
test/asm/ftrc.s
|
||||
test/asm/ftrv.s
|
||||
test/asm/jmp.s
|
||||
test/asm/jsr.s
|
||||
test/asm/ldc.s
|
||||
test/asm/ldcl.s
|
||||
test/asm/lds.s
|
||||
test/asm/ldsl.s
|
||||
test/asm/mova.s
|
||||
test/asm/movb.s
|
||||
test/asm/movl.s
|
||||
test/asm/movt.s
|
||||
test/asm/movw.s
|
||||
test/asm/mul.s
|
||||
test/asm/neg.s
|
||||
test/asm/negc.s
|
||||
test/asm/not.s
|
||||
test/asm/or.s
|
||||
test/asm/rot.s
|
||||
test/asm/sha.s
|
||||
test/asm/shl.s
|
||||
test/asm/sub.s
|
||||
test/asm/subc.s
|
||||
test/asm/subv.s
|
||||
test/asm/swap.s
|
||||
test/asm/tst.s
|
||||
test/asm/xor.s
|
||||
)
|
||||
set(asm_inc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.inc)
|
||||
|
||||
# compile tests into include file if the sh4 toolchain is available
|
||||
find_package(PythonInterp)
|
||||
find_program(SH_AS NAMES sh-elf-as)
|
||||
find_program(SH_LD NAMES sh-elf-ld)
|
||||
find_program(SH_NM NAMES sh-elf-nm)
|
||||
find_program(SH_OBJCOPY NAMES sh-elf-objcopy)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message(WARNING "Could not find python interpreter, won't be able to generate tests")
|
||||
elseif(NOT SH_AS)
|
||||
message(WARNING "Could not find sh-elf-as, won't be able to generate tests")
|
||||
elseif(NOT SH_LD)
|
||||
message(WARNING "Could not find sh-elf-ld, won't be able to generate tests")
|
||||
elseif(NOT SH_NM)
|
||||
message(WARNING "Could not find sh-elf-nm, won't be able to generate tests")
|
||||
elseif(NOT SH_OBJCOPY)
|
||||
message(WARNING "Could not find sh-elf-objcopy, won't be able to generate tests")
|
||||
else()
|
||||
add_custom_command(OUTPUT ${asm_inc}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.py -as ${SH_AS} -ld ${SH_LD} -nm ${SH_NM} -objcopy ${SH_OBJCOPY} -o ${asm_inc} ${TEST_ASM}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.py ${TEST_ASM}
|
||||
COMMENT "Assembling ${asm_inc} for ${TEST_ASM}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
VERBATIM)
|
||||
endif()
|
||||
|
||||
# build test binary
|
||||
set(RETEST_SOURCES
|
||||
${REDREAM_SOURCES}
|
||||
#test/test_interval_tree.cc
|
||||
#test/test_intrusive_list.cc
|
||||
test/test_list.cc
|
||||
test/test_dead_code_elimination_pass.cc
|
||||
test/test_load_store_elimination_pass.cc
|
||||
#test/test_minmax_heap.cc
|
||||
test/test_sh4.cc
|
||||
${asm_inc})
|
||||
list(REMOVE_ITEM RETEST_SOURCES src/main.c)
|
||||
|
||||
# assign source groups for visual studio projects
|
||||
source_group_by_dir(RETEST_SOURCES)
|
||||
|
||||
add_executable(retest ${RETEST_SOURCES})
|
||||
target_include_directories(retest PUBLIC deps/gtest-1.7.0/include src/ test/ ${REDREAM_INCLUDE_DIRS})
|
||||
target_link_libraries(retest gtest gtest_main ${REDREAM_LIBS})
|
||||
target_compile_definitions(retest PRIVATE ${REDREAM_DEFS})
|
||||
target_compile_options(retest PRIVATE ${REDREAM_COMPILE_FLAGS})
|
||||
#set(gtest_force_shared_crt ON CACHE BOOL "")
|
||||
#add_subdirectory(deps/gtest-1.7.0 EXCLUDE_FROM_ALL)
|
||||
#
|
||||
## compile master .inc file from .s files in test/asm
|
||||
#set(TEST_ASM
|
||||
# test/asm/add.s
|
||||
# test/asm/addc.s
|
||||
# test/asm/addv.s
|
||||
# test/asm/and.s
|
||||
# test/asm/bf.s
|
||||
# test/asm/bra.s
|
||||
# test/asm/braf.s
|
||||
# test/asm/bsr.s
|
||||
# test/asm/bsrf.s
|
||||
# test/asm/bt.s
|
||||
# test/asm/cmp.s
|
||||
# test/asm/div0.s
|
||||
# test/asm/div1s.s
|
||||
# test/asm/div1u.s
|
||||
# test/asm/dmul.s
|
||||
# test/asm/dt.s
|
||||
# test/asm/ext.s
|
||||
# test/asm/fabs.s
|
||||
# test/asm/fadd.s
|
||||
# test/asm/fcmpeq.s
|
||||
# test/asm/fcmpgt.s
|
||||
# test/asm/fcnv.s
|
||||
# test/asm/fdiv.s
|
||||
# test/asm/fipr.s
|
||||
# test/asm/fld.s
|
||||
# test/asm/float.s
|
||||
# test/asm/fmac.s
|
||||
# test/asm/fmov.s
|
||||
# test/asm/fmov_load.s
|
||||
# test/asm/fmov_index_load.s
|
||||
# test/asm/fmov_store.s
|
||||
# test/asm/fmov_index_store.s
|
||||
# test/asm/fmov_save.s
|
||||
# test/asm/fmov_restore.s
|
||||
# test/asm/fmul.s
|
||||
# test/asm/fneg.s
|
||||
# test/asm/frchg.s
|
||||
# test/asm/fsca.s
|
||||
# test/asm/fschg.s
|
||||
# test/asm/fsrra.s
|
||||
# test/asm/fsqrt.s
|
||||
# test/asm/fsub.s
|
||||
# test/asm/ftrc.s
|
||||
# test/asm/ftrv.s
|
||||
# test/asm/jmp.s
|
||||
# test/asm/jsr.s
|
||||
# test/asm/ldc.s
|
||||
# test/asm/ldcl.s
|
||||
# test/asm/lds.s
|
||||
# test/asm/ldsl.s
|
||||
# test/asm/mova.s
|
||||
# test/asm/movb.s
|
||||
# test/asm/movl.s
|
||||
# test/asm/movt.s
|
||||
# test/asm/movw.s
|
||||
# test/asm/mul.s
|
||||
# test/asm/neg.s
|
||||
# test/asm/negc.s
|
||||
# test/asm/not.s
|
||||
# test/asm/or.s
|
||||
# test/asm/rot.s
|
||||
# test/asm/sha.s
|
||||
# test/asm/shl.s
|
||||
# test/asm/sub.s
|
||||
# test/asm/subc.s
|
||||
# test/asm/subv.s
|
||||
# test/asm/swap.s
|
||||
# test/asm/tst.s
|
||||
# test/asm/xor.s
|
||||
# )
|
||||
#set(asm_inc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.inc)
|
||||
#
|
||||
## compile tests into include file if the sh4 toolchain is available
|
||||
#find_package(PythonInterp)
|
||||
#find_program(SH_AS NAMES sh-elf-as)
|
||||
#find_program(SH_LD NAMES sh-elf-ld)
|
||||
#find_program(SH_NM NAMES sh-elf-nm)
|
||||
#find_program(SH_OBJCOPY NAMES sh-elf-objcopy)
|
||||
#if(NOT PYTHONINTERP_FOUND)
|
||||
# message(WARNING "Could not find python interpreter, won't be able to generate tests")
|
||||
#elseif(NOT SH_AS)
|
||||
# message(WARNING "Could not find sh-elf-as, won't be able to generate tests")
|
||||
#elseif(NOT SH_LD)
|
||||
# message(WARNING "Could not find sh-elf-ld, won't be able to generate tests")
|
||||
#elseif(NOT SH_NM)
|
||||
# message(WARNING "Could not find sh-elf-nm, won't be able to generate tests")
|
||||
#elseif(NOT SH_OBJCOPY)
|
||||
# message(WARNING "Could not find sh-elf-objcopy, won't be able to generate tests")
|
||||
#else()
|
||||
# add_custom_command(OUTPUT ${asm_inc}
|
||||
# COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.py -as ${SH_AS} -ld ${SH_LD} -nm ${SH_NM} -objcopy ${SH_OBJCOPY} -o ${asm_inc} ${TEST_ASM}
|
||||
# DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sh4.py ${TEST_ASM}
|
||||
# COMMENT "Assembling ${asm_inc} for ${TEST_ASM}"
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
# VERBATIM)
|
||||
#endif()
|
||||
#
|
||||
## build test binary
|
||||
#set(RETEST_SOURCES
|
||||
# ${REDREAM_SOURCES}
|
||||
# #test/test_interval_tree.cc
|
||||
# #test/test_intrusive_list.cc
|
||||
# test/test_list.cc
|
||||
# test/test_dead_code_elimination_pass.cc
|
||||
# test/test_load_store_elimination_pass.cc
|
||||
# #test/test_minmax_heap.cc
|
||||
# test/test_sh4.cc
|
||||
# ${asm_inc})
|
||||
#list(REMOVE_ITEM RETEST_SOURCES src/main.c)
|
||||
#
|
||||
## assign source groups for visual studio projects
|
||||
#source_group_by_dir(RETEST_SOURCES)
|
||||
#
|
||||
#add_executable(retest ${RETEST_SOURCES})
|
||||
#target_include_directories(retest PUBLIC deps/gtest-1.7.0/include src/ test/ ${REDREAM_INCLUDE_DIRS})
|
||||
#target_link_libraries(retest gtest gtest_main ${REDREAM_LIBS})
|
||||
#target_compile_definitions(retest PRIVATE ${REDREAM_DEFS})
|
||||
#target_compile_options(retest PRIVATE ${REDREAM_COMPILE_FLAGS})
|
||||
|
|
|
@ -41,7 +41,7 @@ static bool emu_load_bios(struct emu *emu, const char *path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
uint8_t *bios = as_translate(emu->dc->sh4->base.memory->space, BIOS_BEGIN);
|
||||
uint8_t *bios = as_translate(emu->dc->sh4->memory->space, BIOS_BEGIN);
|
||||
int n = (int)fread(bios, sizeof(uint8_t), size, fp);
|
||||
fclose(fp);
|
||||
|
||||
|
@ -73,7 +73,7 @@ static bool emu_load_flash(struct emu *emu, const char *path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
uint8_t *flash = as_translate(emu->dc->sh4->base.memory->space, FLASH_BEGIN);
|
||||
uint8_t *flash = as_translate(emu->dc->sh4->memory->space, FLASH_BEGIN);
|
||||
int n = (int)fread(flash, sizeof(uint8_t), size, fp);
|
||||
fclose(fp);
|
||||
|
||||
|
@ -96,7 +96,7 @@ static bool emu_launch_bin(struct emu *emu, const char *path) {
|
|||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
// load to 0x0c010000 (area 3) which is where 1ST_READ.BIN is loaded to
|
||||
uint8_t *data = as_translate(emu->dc->sh4->base.memory->space, 0x0c010000);
|
||||
uint8_t *data = as_translate(emu->dc->sh4->memory->space, 0x0c010000);
|
||||
int n = (int)fread(data, sizeof(uint8_t), size, fp);
|
||||
fclose(fp);
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
#include "hw/sh4/sh4.h"
|
||||
|
||||
struct aica {
|
||||
struct device base;
|
||||
struct device;
|
||||
|
||||
struct arm *arm;
|
||||
uint8_t *aica_regs;
|
||||
uint8_t *wave_ram;
|
||||
|
@ -87,12 +88,12 @@ define_write_wave(w16, uint16_t);
|
|||
define_write_wave(w32, uint32_t);
|
||||
|
||||
static bool aica_init(struct device *dev) {
|
||||
struct aica *aica = container_of(dev, struct aica, base);
|
||||
struct dreamcast *dc = aica->base.dc;
|
||||
struct aica *aica = (struct aica *)dev;
|
||||
struct dreamcast *dc = aica->dc;
|
||||
|
||||
aica->arm = dc->arm;
|
||||
aica->aica_regs = as_translate(dc->sh4->base.memory->space, 0x00700000);
|
||||
aica->wave_ram = as_translate(dc->sh4->base.memory->space, 0x00800000);
|
||||
aica->aica_regs = as_translate(dc->sh4->memory->space, 0x00700000);
|
||||
aica->wave_ram = as_translate(dc->sh4->memory->space, 0x00800000);
|
||||
aica->common_data = (struct common_data *)(aica->aica_regs + 0x2800);
|
||||
|
||||
arm_suspend(aica->arm);
|
||||
|
@ -107,7 +108,7 @@ struct aica *aica_create(struct dreamcast *dc) {
|
|||
}
|
||||
|
||||
void aica_destroy(struct aica *aica) {
|
||||
dc_destroy_device(&aica->base);
|
||||
dc_destroy_device((struct device *)aica);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "hw/dreamcast.h"
|
||||
|
||||
struct arm {
|
||||
struct device base;
|
||||
struct device;
|
||||
};
|
||||
|
||||
static bool arm_init(struct device *dev) {
|
||||
|
@ -16,22 +16,22 @@ static void arm_run(struct device *dev, int64_t ns) {
|
|||
}
|
||||
|
||||
void arm_suspend(struct arm *arm) {
|
||||
arm->base.execute->suspended = true;
|
||||
arm->execute->suspended = true;
|
||||
}
|
||||
|
||||
void arm_resume(struct arm *arm) {
|
||||
arm->base.execute->suspended = false;
|
||||
arm->execute->suspended = false;
|
||||
}
|
||||
|
||||
struct arm *arm_create(struct dreamcast *dc) {
|
||||
struct arm *arm = dc_create_device(dc, sizeof(struct arm), "arm", &arm_init);
|
||||
arm->base.execute = execute_interface_create(&arm_run);
|
||||
arm->execute = dc_create_execute_interface(&arm_run);
|
||||
return arm;
|
||||
}
|
||||
|
||||
void arm_destroy(struct arm *arm) {
|
||||
execute_interface_destroy(arm->base.execute);
|
||||
dc_destroy_device(&arm->base);
|
||||
dc_destroy_execute_interface(arm->execute);
|
||||
dc_destroy_device((struct device *)arm);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -15,77 +15,10 @@
|
|||
|
||||
DEFINE_OPTION_BOOL(gdb, false, "Run gdb debug server");
|
||||
|
||||
struct execute_interface *execute_interface_create(device_run_cb run) {
|
||||
struct execute_interface *execute =
|
||||
calloc(1, sizeof(struct execute_interface));
|
||||
execute->run = run;
|
||||
return execute;
|
||||
}
|
||||
|
||||
void execute_interface_destroy(struct execute_interface *execute) {
|
||||
free(execute);
|
||||
}
|
||||
|
||||
struct memory_interface *memory_interface_create(struct dreamcast *dc,
|
||||
address_map_cb mapper) {
|
||||
struct memory_interface *memory = calloc(1, sizeof(struct memory_interface));
|
||||
memory->mapper = mapper;
|
||||
memory->space = as_create(dc);
|
||||
return memory;
|
||||
}
|
||||
|
||||
void memory_interface_destroy(struct memory_interface *memory) {
|
||||
as_destroy(memory->space);
|
||||
free(memory);
|
||||
}
|
||||
|
||||
struct window_interface *window_interface_create(
|
||||
device_paint_cb paint, device_paint_debug_menu_cb paint_debug_menu,
|
||||
device_keydown_cb keydown) {
|
||||
struct window_interface *window = calloc(1, sizeof(struct window_interface));
|
||||
window->paint = paint;
|
||||
window->paint_debug_menu = paint_debug_menu;
|
||||
window->keydown = keydown;
|
||||
return window;
|
||||
}
|
||||
|
||||
void window_interface_destroy(struct window_interface *window) {
|
||||
free(window);
|
||||
}
|
||||
|
||||
void device_run(struct device *dev, int64_t ns) {
|
||||
dev->execute->run(dev, ns);
|
||||
}
|
||||
|
||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||
bool (*init)(struct device *dev)) {
|
||||
struct device *dev = calloc(1, size);
|
||||
|
||||
dev->dc = dc;
|
||||
dev->name = name;
|
||||
dev->init = init;
|
||||
|
||||
list_add(&dc->devices, &dev->it);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
struct device *dc_get_device(struct dreamcast *dc, const char *name) {
|
||||
list_for_each_entry(dev, &dc->devices, struct device, it) {
|
||||
if (!strcmp(dev->name, name)) {
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dc_destroy_device(struct device *dev) {
|
||||
list_remove(&dev->dc->devices, &dev->it);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
bool dc_init(struct dreamcast *dc) {
|
||||
if (dc->debugger && !debugger_init(dc->debugger)) {
|
||||
dc_destroy(dc);
|
||||
|
@ -150,6 +83,73 @@ void dc_keydown(struct dreamcast *dc, enum keycode code, int16_t value) {
|
|||
}
|
||||
}
|
||||
|
||||
struct execute_interface *dc_create_execute_interface(device_run_cb run) {
|
||||
struct execute_interface *execute =
|
||||
calloc(1, sizeof(struct execute_interface));
|
||||
execute->run = run;
|
||||
return execute;
|
||||
}
|
||||
|
||||
void dc_destroy_execute_interface(struct execute_interface *execute) {
|
||||
free(execute);
|
||||
}
|
||||
|
||||
struct memory_interface *dc_create_memory_interface(struct dreamcast *dc,
|
||||
address_map_cb mapper) {
|
||||
struct memory_interface *memory = calloc(1, sizeof(struct memory_interface));
|
||||
memory->mapper = mapper;
|
||||
memory->space = as_create(dc);
|
||||
return memory;
|
||||
}
|
||||
|
||||
void dc_destroy_memory_interface(struct memory_interface *memory) {
|
||||
as_destroy(memory->space);
|
||||
free(memory);
|
||||
}
|
||||
|
||||
struct window_interface *dc_create_window_interface(
|
||||
device_paint_cb paint, device_paint_debug_menu_cb paint_debug_menu,
|
||||
device_keydown_cb keydown) {
|
||||
struct window_interface *window = calloc(1, sizeof(struct window_interface));
|
||||
window->paint = paint;
|
||||
window->paint_debug_menu = paint_debug_menu;
|
||||
window->keydown = keydown;
|
||||
return window;
|
||||
}
|
||||
|
||||
void dc_destroy_window_interface(struct window_interface *window) {
|
||||
free(window);
|
||||
}
|
||||
|
||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||
bool (*init)(struct device *dev)) {
|
||||
struct device *dev = calloc(1, size);
|
||||
|
||||
dev->dc = dc;
|
||||
dev->name = name;
|
||||
dev->init = init;
|
||||
|
||||
list_add(&dc->devices, &dev->it);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
struct device *dc_get_device(struct dreamcast *dc, const char *name) {
|
||||
list_for_each_entry(dev, &dc->devices, struct device, it) {
|
||||
if (!strcmp(dev->name, name)) {
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dc_destroy_device(struct device *dev) {
|
||||
list_remove(&dev->dc->devices, &dev->it);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
struct dreamcast *dc_create(struct rb *rb) {
|
||||
struct dreamcast *dc = calloc(1, sizeof(struct dreamcast));
|
||||
|
||||
|
|
|
@ -64,40 +64,27 @@ struct execute_interface {
|
|||
bool suspended;
|
||||
};
|
||||
|
||||
struct execute_interface *execute_interface_create(device_run_cb run);
|
||||
void execute_interface_destroy(struct execute_interface *execute);
|
||||
|
||||
// memory interface
|
||||
struct memory_interface {
|
||||
address_map_cb mapper;
|
||||
struct address_space *space;
|
||||
};
|
||||
|
||||
struct memory_interface *memory_interface_create(struct dreamcast *dc,
|
||||
address_map_cb mapper);
|
||||
void memory_interface_destroy(struct memory_interface *memory);
|
||||
|
||||
// window interface
|
||||
typedef void (*device_paint_cb)(struct device *);
|
||||
typedef void (*device_paint_debug_menu_cb)(struct device *,
|
||||
struct nk_context *);
|
||||
typedef void (*device_keydown_cb)(struct device *, enum keycode, int16_t);
|
||||
|
||||
// winder interface
|
||||
struct window_interface {
|
||||
device_paint_cb paint;
|
||||
device_paint_debug_menu_cb paint_debug_menu;
|
||||
device_keydown_cb keydown;
|
||||
};
|
||||
|
||||
struct window_interface *window_interface_create(
|
||||
device_paint_cb paint, device_paint_debug_menu_cb paint_debug_menu,
|
||||
device_keydown_cb keydown);
|
||||
void window_interface_destroy(struct window_interface *window);
|
||||
|
||||
//
|
||||
// device
|
||||
//
|
||||
|
||||
struct device {
|
||||
struct dreamcast *dc;
|
||||
const char *name;
|
||||
|
@ -128,11 +115,6 @@ struct dreamcast {
|
|||
struct list devices;
|
||||
};
|
||||
|
||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||
bool (*init)(struct device *dev));
|
||||
struct device *dc_get_device(struct dreamcast *dc, const char *name);
|
||||
void dc_destroy_device(struct device *dev);
|
||||
|
||||
bool dc_init(struct dreamcast *dc);
|
||||
void dc_suspend(struct dreamcast *dc);
|
||||
void dc_resume(struct dreamcast *dc);
|
||||
|
@ -141,6 +123,23 @@ void dc_paint(struct dreamcast *dc);
|
|||
void dc_paint_debug_menu(struct dreamcast *dc, struct nk_context *ctx);
|
||||
void dc_keydown(struct dreamcast *dc, enum keycode code, int16_t value);
|
||||
|
||||
struct execute_interface *dc_create_execute_interface(device_run_cb run);
|
||||
void dc_destroy_execute_interface(struct execute_interface *execute);
|
||||
|
||||
struct memory_interface *dc_create_memory_interface(struct dreamcast *dc,
|
||||
address_map_cb mapper);
|
||||
void dc_destroy_memory_interface(struct memory_interface *memory);
|
||||
|
||||
struct window_interface *dc_create_window_interface(
|
||||
device_paint_cb paint, device_paint_debug_menu_cb paint_debug_menu,
|
||||
device_keydown_cb keydown);
|
||||
void dc_destroy_window_interface(struct window_interface *window);
|
||||
|
||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||
bool (*init)(struct device *dev));
|
||||
struct device *dc_get_device(struct dreamcast *dc, const char *name);
|
||||
void dc_destroy_device(struct device *dev);
|
||||
|
||||
struct dreamcast *dc_create(struct rb *rb);
|
||||
void dc_destroy(struct dreamcast *dc);
|
||||
|
||||
|
|
|
@ -46,10 +46,8 @@ struct cdread {
|
|||
};
|
||||
|
||||
struct gdrom {
|
||||
struct device base;
|
||||
|
||||
struct device;
|
||||
struct holly *holly;
|
||||
|
||||
enum gd_state state;
|
||||
struct disc *disc;
|
||||
union gd_features features;
|
||||
|
@ -57,14 +55,13 @@ struct gdrom {
|
|||
union gd_sectnum sectnum;
|
||||
union gd_bytect byte_count;
|
||||
union gd_status status;
|
||||
|
||||
struct cdread req;
|
||||
|
||||
// pio state
|
||||
uint8_t pio_buffer[0x10000];
|
||||
int pio_head;
|
||||
int pio_size;
|
||||
int pio_read;
|
||||
|
||||
// dma state
|
||||
uint8_t *dma_buffer;
|
||||
int dma_capacity;
|
||||
int dma_head;
|
||||
|
@ -606,8 +603,8 @@ REG_W32(struct gdrom *gd, GD_STATUS_COMMAND) {
|
|||
}
|
||||
|
||||
static bool gdrom_init(struct device *dev) {
|
||||
struct gdrom *gd = container_of(dev, struct gdrom, base);
|
||||
struct dreamcast *dc = gd->base.dc;
|
||||
struct gdrom *gd = (struct gdrom *)dev;
|
||||
struct dreamcast *dc = gd->dc;
|
||||
|
||||
gd->holly = dc->holly;
|
||||
|
||||
|
@ -692,5 +689,5 @@ void gdrom_destroy(struct gdrom *gd) {
|
|||
disc_destroy(gd->disc);
|
||||
}
|
||||
|
||||
dc_destroy_device(&gd->base);
|
||||
dc_destroy_device((struct device *)gd);
|
||||
}
|
||||
|
|
|
@ -289,8 +289,8 @@ REG_W32(struct holly *hl, SB_PDST) {
|
|||
}
|
||||
|
||||
static bool holly_init(struct device *dev) {
|
||||
struct holly *hl = container_of(dev, struct holly, base);
|
||||
struct dreamcast *dc = hl->base.dc;
|
||||
struct holly *hl = (struct holly *)dev;
|
||||
struct dreamcast *dc = hl->dc;
|
||||
|
||||
hl->gdrom = dc->gdrom;
|
||||
hl->maple = dc->maple;
|
||||
|
@ -395,7 +395,7 @@ struct holly *holly_create(struct dreamcast *dc) {
|
|||
}
|
||||
|
||||
void holly_destroy(struct holly *hl) {
|
||||
dc_destroy_device(&hl->base);
|
||||
dc_destroy_device((struct device *)hl);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -12,12 +12,10 @@ struct maple;
|
|||
struct sh4;
|
||||
|
||||
struct holly {
|
||||
struct device base;
|
||||
|
||||
struct device;
|
||||
struct gdrom *gdrom;
|
||||
struct maple *maple;
|
||||
struct sh4 *sh4;
|
||||
|
||||
uint32_t reg[NUM_HOLLY_REGS];
|
||||
void *reg_data[NUM_HOLLY_REGS];
|
||||
reg_read_cb reg_read[NUM_HOLLY_REGS];
|
||||
|
|
|
@ -162,12 +162,12 @@ REG_W32(struct pvr *pvr, FB_R_CTRL) {
|
|||
}
|
||||
|
||||
static bool pvr_init(struct device *dev) {
|
||||
struct pvr *pvr = container_of(dev, struct pvr, base);
|
||||
struct dreamcast *dc = pvr->base.dc;
|
||||
struct pvr *pvr = (struct pvr *)dev;
|
||||
struct dreamcast *dc = pvr->dc;
|
||||
|
||||
pvr->scheduler = dc->scheduler;
|
||||
pvr->holly = dc->holly;
|
||||
pvr->space = dc->sh4->base.memory->space;
|
||||
pvr->space = dc->sh4->memory->space;
|
||||
pvr->palette_ram = as_translate(pvr->space, 0x005f9000);
|
||||
pvr->video_ram = as_translate(pvr->space, 0x04000000);
|
||||
|
||||
|
@ -202,7 +202,7 @@ struct pvr *pvr_create(struct dreamcast *dc) {
|
|||
}
|
||||
|
||||
void pvr_destroy(struct pvr *pvr) {
|
||||
dc_destroy_device(&pvr->base);
|
||||
dc_destroy_device((struct device *)pvr);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -11,12 +11,10 @@ struct dreamcast;
|
|||
struct holly;
|
||||
|
||||
struct pvr {
|
||||
struct device base;
|
||||
|
||||
struct device;
|
||||
struct scheduler *scheduler;
|
||||
struct holly *holly;
|
||||
struct address_space *space;
|
||||
|
||||
uint8_t *palette_ram;
|
||||
uint8_t *video_ram;
|
||||
uint32_t reg[NUM_PVR_REGS];
|
||||
|
|
|
@ -26,7 +26,7 @@ struct ta_texture_entry {
|
|||
};
|
||||
|
||||
struct ta {
|
||||
struct device base;
|
||||
struct device;
|
||||
struct texture_provider provider;
|
||||
struct rb *rb;
|
||||
struct tr *tr;
|
||||
|
@ -708,13 +708,13 @@ REG_W32(struct ta *ta, STARTRENDER) {
|
|||
}
|
||||
|
||||
static bool ta_init(struct device *dev) {
|
||||
struct ta *ta = container_of(dev, struct ta, base);
|
||||
struct dreamcast *dc = ta->base.dc;
|
||||
struct ta *ta = (struct ta *)dev;
|
||||
struct dreamcast *dc = ta->dc;
|
||||
|
||||
ta->scheduler = dc->scheduler;
|
||||
ta->holly = dc->holly;
|
||||
ta->pvr = dc->pvr;
|
||||
ta->space = dc->sh4->base.memory->space;
|
||||
ta->space = dc->sh4->memory->space;
|
||||
ta->video_ram = as_translate(ta->space, 0x04000000);
|
||||
ta->palette_ram = as_translate(ta->space, 0x005f9000);
|
||||
|
||||
|
@ -774,7 +774,7 @@ static void ta_toggle_tracing(struct ta *ta) {
|
|||
}
|
||||
|
||||
static void ta_paint(struct device *dev) {
|
||||
struct ta *ta = container_of(dev, struct ta, base);
|
||||
struct ta *ta = (struct ta *)dev;
|
||||
struct render_ctx *rctx = &ta->render_context;
|
||||
|
||||
mutex_lock(ta->pending_mutex);
|
||||
|
@ -799,7 +799,7 @@ static void ta_paint(struct device *dev) {
|
|||
}
|
||||
|
||||
static void ta_paint_debug_menu(struct device *dev, struct nk_context *ctx) {
|
||||
struct ta *ta = container_of(dev, struct ta, base);
|
||||
struct ta *ta = (struct ta *)dev;
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_TAB, "ta", NK_MINIMIZED)) {
|
||||
nk_value_int(ctx, "frames skipped", ta->frames_skipped);
|
||||
|
@ -862,8 +862,8 @@ struct ta *ta_create(struct dreamcast *dc, struct rb *rb) {
|
|||
ta_build_tables();
|
||||
|
||||
struct ta *ta = dc_create_device(dc, sizeof(struct ta), "ta", &ta_init);
|
||||
ta->base.window =
|
||||
window_interface_create(&ta_paint, &ta_paint_debug_menu, NULL);
|
||||
ta->window =
|
||||
dc_create_window_interface(&ta_paint, &ta_paint_debug_menu, NULL);
|
||||
ta->provider =
|
||||
(struct texture_provider){ta, &ta_texture_provider_find_texture};
|
||||
ta->rb = rb;
|
||||
|
@ -876,8 +876,8 @@ struct ta *ta_create(struct dreamcast *dc, struct rb *rb) {
|
|||
void ta_destroy(struct ta *ta) {
|
||||
mutex_destroy(ta->pending_mutex);
|
||||
tr_destroy(ta->tr);
|
||||
window_interface_destroy(ta->base.window);
|
||||
dc_destroy_device(&ta->base);
|
||||
dc_destroy_window_interface(ta->window);
|
||||
dc_destroy_device((struct device *)ta);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "hw/sh4/sh4.h"
|
||||
|
||||
struct maple {
|
||||
struct device base;
|
||||
struct device;
|
||||
struct holly *holly;
|
||||
struct address_space *space;
|
||||
struct maple_device *devices[4];
|
||||
|
@ -60,11 +60,11 @@ REG_W32(struct maple *mp, SB_MDST) {
|
|||
}
|
||||
|
||||
static bool maple_init(struct device *dev) {
|
||||
struct maple *mp = container_of(dev, struct maple, base);
|
||||
struct dreamcast *dc = mp->base.dc;
|
||||
struct maple *mp = (struct maple *)dev;
|
||||
struct dreamcast *dc = mp->dc;
|
||||
|
||||
mp->holly = dc->holly;
|
||||
mp->space = dc->sh4->base.memory->space;
|
||||
mp->space = dc->sh4->memory->space;
|
||||
|
||||
#define MAPLE_REG_R32(name) \
|
||||
mp->holly->reg_data[name] = mp; \
|
||||
|
@ -81,7 +81,7 @@ static bool maple_init(struct device *dev) {
|
|||
}
|
||||
|
||||
static void maple_keydown(struct device *dev, enum keycode key, int16_t value) {
|
||||
struct maple *mp = container_of(dev, struct maple, base);
|
||||
struct maple *mp = (struct maple *)dev;
|
||||
struct maple_device *mp_dev = mp->devices[0];
|
||||
|
||||
if (mp_dev) {
|
||||
|
@ -107,7 +107,7 @@ void maple_vblank(struct maple *mp) {
|
|||
struct maple *maple_create(struct dreamcast *dc) {
|
||||
struct maple *mp =
|
||||
dc_create_device(dc, sizeof(struct maple), "maple", &maple_init);
|
||||
mp->base.window = window_interface_create(NULL, NULL, &maple_keydown);
|
||||
mp->window = dc_create_window_interface(NULL, NULL, &maple_keydown);
|
||||
|
||||
mp->devices[0] = controller_create();
|
||||
|
||||
|
@ -123,7 +123,7 @@ void maple_destroy(struct maple *mp) {
|
|||
}
|
||||
}
|
||||
|
||||
window_interface_destroy(mp->base.window);
|
||||
dc_destroy_window_interface(mp->window);
|
||||
|
||||
dc_destroy_device(&mp->base);
|
||||
dc_destroy_device((struct device *)mp);
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ static void sh4_ccn_reset(struct sh4 *sh4) {
|
|||
|
||||
static uint32_t sh4_compile_pc() {
|
||||
uint32_t guest_addr = g_sh4->ctx.pc;
|
||||
uint8_t *guest_ptr = as_translate(g_sh4->base.memory->space, guest_addr);
|
||||
uint8_t *guest_ptr = as_translate(g_sh4->memory->space, guest_addr);
|
||||
|
||||
int flags = 0;
|
||||
if (g_sh4->ctx.fpscr & PR) {
|
||||
|
@ -303,7 +303,7 @@ static void sh4_invalid_instr(struct sh4_ctx *ctx, uint64_t data) {
|
|||
// self->ctx.num_cycles = 0;
|
||||
|
||||
// // let the debugger know execution has stopped
|
||||
// self->dc.base->debugger->Trap();
|
||||
// self->dc->debugger->Trap();
|
||||
}
|
||||
|
||||
static void sh4_prefetch(struct sh4_ctx *ctx, uint64_t data) {
|
||||
|
@ -385,7 +385,7 @@ static void sh4_fpscr_updated(struct sh4_ctx *ctx, uint64_t old_fpscr) {
|
|||
// sh4->ctx.pc = code();
|
||||
|
||||
// // let the debugger know we've stopped
|
||||
// dc_.base->debugger->Trap();
|
||||
// dc->debugger->Trap();
|
||||
// }
|
||||
|
||||
// static void sh4_debug_add_breakpoint(int type, uint32_t addr) {
|
||||
|
@ -696,24 +696,19 @@ REG_W32(struct sh4 *sh4, TCNT2) {
|
|||
}
|
||||
|
||||
static bool sh4_init(struct device *dev) {
|
||||
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||
struct dreamcast *dc = sh4->base.dc;
|
||||
struct sh4 *sh4 = (struct sh4 *)dev;
|
||||
struct dreamcast *dc = sh4->dc;
|
||||
|
||||
sh4->scheduler = dc->scheduler;
|
||||
sh4->space = sh4->base.memory->space;
|
||||
sh4->space = sh4->memory->space;
|
||||
|
||||
sh4->memory_if =
|
||||
(struct jit_memory_interface){&sh4->ctx,
|
||||
sh4->base.memory->space->protected_base,
|
||||
sh4->base.memory->space,
|
||||
&as_read8,
|
||||
&as_read16,
|
||||
&as_read32,
|
||||
&as_read64,
|
||||
&as_write8,
|
||||
&as_write16,
|
||||
&as_write32,
|
||||
&as_write64};
|
||||
sh4->memory_if = (struct jit_memory_interface){
|
||||
&sh4->ctx, sh4->memory->space->protected_base,
|
||||
sh4->memory->space, &as_read8,
|
||||
&as_read16, &as_read32,
|
||||
&as_read64, &as_write8,
|
||||
&as_write16, &as_write32,
|
||||
&as_write64};
|
||||
sh4->code_cache = sh4_cache_create(&sh4->memory_if, &sh4_compile_pc);
|
||||
|
||||
// initialize context
|
||||
|
@ -772,7 +767,7 @@ static bool sh4_init(struct device *dev) {
|
|||
}
|
||||
|
||||
static void sh4_paint_debug_menu(struct device *dev, struct nk_context *ctx) {
|
||||
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||
struct sh4 *sh4 = (struct sh4 *)dev;
|
||||
struct sh4_perf *perf = &sh4->perf;
|
||||
|
||||
if (nk_tree_push(ctx, NK_TREE_TAB, "sh4", NK_MINIMIZED)) {
|
||||
|
@ -807,7 +802,7 @@ void sh4_set_pc(struct sh4 *sh4, uint32_t pc) {
|
|||
}
|
||||
|
||||
static void sh4_run_inner(struct device *dev, int64_t ns) {
|
||||
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||
struct sh4 *sh4 = (struct sh4 *)dev;
|
||||
|
||||
// execute at least 1 cycle. the tests rely on this to step block by block
|
||||
int64_t cycles = MAX(NANO_TO_CYCLES(ns, SH4_CLOCK_FREQ), INT64_C(1));
|
||||
|
@ -932,9 +927,9 @@ void sh4_ddt(struct sh4 *sh4, struct sh4_dtr *dtr) {
|
|||
|
||||
struct sh4 *sh4_create(struct dreamcast *dc) {
|
||||
struct sh4 *sh4 = dc_create_device(dc, sizeof(struct sh4), "sh", &sh4_init);
|
||||
sh4->base.execute = execute_interface_create(&sh4_run);
|
||||
sh4->base.memory = memory_interface_create(dc, &sh4_data_map);
|
||||
sh4->base.window = window_interface_create(NULL, &sh4_paint_debug_menu, NULL);
|
||||
sh4->execute = dc_create_execute_interface(&sh4_run);
|
||||
sh4->memory = dc_create_memory_interface(dc, &sh4_data_map);
|
||||
sh4->window = dc_create_window_interface(NULL, &sh4_paint_debug_menu, NULL);
|
||||
|
||||
g_sh4 = sh4;
|
||||
|
||||
|
@ -948,10 +943,10 @@ void sh4_destroy(struct sh4 *sh4) {
|
|||
sh4_cache_destroy(sh4->code_cache);
|
||||
}
|
||||
|
||||
window_interface_destroy(sh4->base.window);
|
||||
memory_interface_destroy(sh4->base.memory);
|
||||
execute_interface_destroy(sh4->base.execute);
|
||||
dc_destroy_device(&sh4->base);
|
||||
dc_destroy_window_interface(sh4->window);
|
||||
dc_destroy_memory_interface(sh4->memory);
|
||||
dc_destroy_execute_interface(sh4->execute);
|
||||
dc_destroy_device((struct device *)sh4);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -34,16 +34,14 @@ struct sh4_perf {
|
|||
};
|
||||
|
||||
struct sh4 {
|
||||
struct device base;
|
||||
struct device;
|
||||
struct scheduler *scheduler;
|
||||
struct address_space *space;
|
||||
|
||||
struct jit_memory_interface memory_if;
|
||||
struct sh4_cache *code_cache;
|
||||
struct sh4_ctx ctx;
|
||||
uint8_t cache[0x2000]; // 8kb cache
|
||||
// std::map<uint32_t, uint16_t> breakpoints;
|
||||
|
||||
uint32_t reg[NUM_SH4_REGS];
|
||||
void *reg_data[NUM_SH4_REGS];
|
||||
reg_read_cb reg_read[NUM_SH4_REGS];
|
||||
|
|
|
@ -110,7 +110,7 @@ static void run_sh4_test(const struct sh4_test &test) {
|
|||
int aligned_size = align_up(test.buffer_size, 4);
|
||||
uint8_t *aligned_buffer = reinterpret_cast<uint8_t *>(alloca(aligned_size));
|
||||
memcpy(aligned_buffer, test.buffer, test.buffer_size);
|
||||
as_memcpy_to_guest(dc->sh4->base.memory->space, 0x8c010000, aligned_buffer,
|
||||
as_memcpy_to_guest(dc->sh4->memory->space, 0x8c010000, aligned_buffer,
|
||||
aligned_size);
|
||||
|
||||
// skip to the test's offset
|
||||
|
|
Loading…
Reference in New Issue