diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..32b6644 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,16 @@ +FROM ghcr.io/classpaddev/hollyhock-3:v2.1.1 AS toolchain + +FROM mcr.microsoft.com/devcontainers/base:debian12 AS base + +# Install required packages KEEP IN SYNC (+clangd bear python nano) +RUN apt-get update -y && apt-get upgrade -y && \ + apt-get install -y --no-install-recommends \ + make libncurses6 zstd zlib1g \ + gawk wget bzip2 xz-utils unzip \ + patch libstdc++6 rsync git mold \ + nano clangd-19 bear python3 python-is-python3 +RUN apt-get install -y --reinstall ca-certificates +COPY --from=toolchain /toolchain /toolchain +COPY --from=toolchain /sdk /sdk +ENV PATH=$PATH:/toolchain/bin +ENV SDK_DIR=/sdk diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..f90b782 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,19 @@ +{ + "build": { + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.makefile-tools", + "ms-vscode.cpptools-themes", + "ms-vscode.cpptools", + "xaver.clang-format", + "llvm-vs-code-extensions.vscode-clangd", + "ZixuanWang.linkerscript", + "ms-azuretools.vscode-docker", + "ms-python.python" + ] + } + } +} \ No newline at end of file diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 523a4c4..5595cd4 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/classpaddev/hollyhock-3 + image: ghcr.io/classpaddev/hollyhock-3:v2.1.1 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} diff --git a/.gitignore b/.gitignore index 6723e3e..f8bc7a0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,12 @@ peanut-sdl peanut-debug tags -.vscode +.cache +compile_commands.json obj dist -*.hhk -*.bin +*.elf +*.hh3 # OS items .DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1686474 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "clangd.arguments": [ + "--query-driver=/toolchain/bin/sh4a_nofpueb-elf-*" + ], + "clangd.path": "clangd-19" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..13c5916 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "make -j", + "problemMatcher": [ + "$gcc" + ] + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index 8117cf7..d66161c 100644 --- a/Makefile +++ b/Makefile @@ -2,69 +2,58 @@ # The .hhk file is the original format, the bin file is a newer format. APP_NAME:=CPBoy -ifndef SDK_DIR -$(error You need to define the SDK_DIR environment variable, and point it to the sdk/ folder) -endif +SDK_DIR?=/sdk -AS:=sh4aeb-elf-gcc +AS:=sh4a_nofpueb-elf-gcc AS_FLAGS:= -COMMON_FLAGS:=-fshort-wchar -O2 -m4a-nofpu -ffunction-sections -fdata-sections #-flto +COMMON_FLAGS:=-Ofast -gdwarf-5 -ffunction-sections -fdata-sections -flto=auto -ffat-lto-objects #-fstack-protector-all INCLUDES:=-I $(SDK_DIR)/include/ WARNINGS:=-Wall -Wextra -CC:=sh4aeb-elf-gcc +CC:=sh4a_nofpueb-elf-gcc CC_FLAGS:=$(COMMON_FLAGS) $(INCLUDES) $(WARNINGS) -CXX:=sh4aeb-elf-g++ +CXX:=sh4a_nofpueb-elf-g++ CXX_FLAGS:=-fno-exceptions -fno-rtti -Wno-write-strings $(COMMON_FLAGS) $(INCLUDES) $(WARNINGS) LD:=$(CXX) -LD_FLAGS:= $(COMMON_FLAGS) $(WARNINGS) -Wno-undef -Wl,--gc-sections +LD_FLAGS:=$(COMMON_FLAGS) $(WARNINGS) -Wl,-Ttext-segment,0x8C052800 -Wno-undef -Wl,--gc-sections #-fno-lto -v -READELF:=sh4aeb-elf-readelf -OBJCOPY:=sh4aeb-elf-objcopy +READELF:=sh4a_nofpueb-elf-readelf +OBJCOPY:=sh4a_nofpueb-elf-objcopy +STRIP:=sh4a_nofpueb-elf-strip SOURCEDIR = src BUILDDIR = obj OUTDIR = dist -BINDIR = $(OUTDIR)/CPBoy/bin -AS_SOURCES:=$(shell find $(SOURCEDIR) -name '*.s') +AS_SOURCES:=$(shell find $(SOURCEDIR) -name '*.S') CC_SOURCES:=$(shell find $(SOURCEDIR) -name '*.c') CXX_SOURCES:=$(shell find $(SOURCEDIR) -name '*.cpp') -OBJECTS := $(addprefix $(BUILDDIR)/,$(AS_SOURCES:.s=.o)) \ +OBJECTS := $(addprefix $(BUILDDIR)/,$(AS_SOURCES:.S=.o)) \ $(addprefix $(BUILDDIR)/,$(CC_SOURCES:.c=.o)) \ $(addprefix $(BUILDDIR)/,$(CXX_SOURCES:.cpp=.o)) +APP_HH3:=$(OUTDIR)/$(APP_NAME).hh3 APP_ELF:=$(OUTDIR)/$(APP_NAME).elf -APP_BIN:=$(OUTDIR)/$(APP_NAME).bin -IL_BIN:=$(BINDIR)/il.bin -Y_BIN:=$(BINDIR)/y.bin -bin: $(APP_BIN) $(IL_BIN) $(Y_BIN) Makefile +.DEFAULT_GOAL=all -hhk: $(APP_ELF) Makefile +hh3: $(APP_HH3) Makefile +elf: $(APP_ELF) Makefile -all: $(APP_ELF) $(APP_BIN) $(IL_BIN) $(Y_BIN) Makefile +all: $(APP_ELF) $(APP_HH3) Makefile clean: rm -rf $(BUILDDIR) $(OUTDIR) -$(APP_BIN): $(APP_ELF) - $(OBJCOPY) --remove-section=.oc_mem* --set-section-flags .bss=alloc,load,contents,data --output-target=binary $(APP_ELF) $@ +%.hh3: %.elf + $(STRIP) -o $@ $^ -$(IL_BIN): $(APP_ELF) +$(APP_ELF): $(OBJECTS) $(SDK_DIR)/libsdk.a mkdir -p $(dir $@) - $(OBJCOPY) --only-section=.oc_mem.il* --output-target=binary $(APP_ELF) $@ - -$(Y_BIN): $(APP_ELF) - mkdir -p $(dir $@) - $(OBJCOPY) --only-section=.oc_mem.y* --output-target=binary $(APP_ELF) $@ - -$(APP_ELF): $(OBJECTS) $(SDK_DIR)/libsdk.a linker.ld - mkdir -p $(dir $@) - $(LD) -T linker.ld -Wl,-Map $@.map -o $@ $(LD_FLAGS) $(OBJECTS) -L$(SDK_DIR) -lsdk + $(LD) -Wl,-Map $@.map -o $@ $(LD_FLAGS) $(OBJECTS) -L$(SDK_DIR) -lsdk # We're not actually building sdk.o, just telling the user they need to do it # themselves. Just using the target to trigger an error when the file is @@ -72,7 +61,7 @@ $(APP_ELF): $(OBJECTS) $(SDK_DIR)/libsdk.a linker.ld $(SDK_DIR)/libsdk.a: @echo "You need to build the SDK before using it. Run make in the SDK directory, and check the README.md in the SDK directory for more information" && exit 1 -$(BUILDDIR)/%.o: %.s +$(BUILDDIR)/%.o: %.S mkdir -p $(dir $@) $(AS) -c $< -o $@ $(AS_FLAGS) @@ -88,6 +77,5 @@ $(BUILDDIR)/%.o: %.c $(BUILDDIR)/%.o: %.cpp mkdir -p $(dir $@) $(CXX) -c $< -o $@ $(CXX_FLAGS) - @$(READELF) $@ -S | grep ".ctors" > /dev/null && echo "ERROR: Global constructors aren't supported." && rm $@ && exit 1 || exit 0 -.PHONY: bin hhk all clean \ No newline at end of file +.PHONY: elf hh3 all clean diff --git a/README.md b/README.md index b830451..db93848 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,6 @@ You will need to have the [Hollyhock-3 CFW](https://github.com/ClasspadDev/holly ├── run.bin (Hollyhock launcher) ├── CPBoy.bin (Main CPBoy executable) └── CPBoy/ - ├── bin/ - | ├── il.bin - | └── y.bin └── roms/ └── ** Put your roms in here ** ``` diff --git a/linker.ld b/linker.ld deleted file mode 100644 index 9e83cc8..0000000 --- a/linker.ld +++ /dev/null @@ -1,67 +0,0 @@ -STARTUP(crt0.o); -ENTRY(_start); - -SECTIONS { - start_address = 0x8CFE6000; - .bootstrap.start start_address : AT(start_address) { - *(.bootstrap.start*) - } - info_address = 0x8CFE6010; - . = info_address; - .hollyhock_name : { - KEEP(*(.hollyhock_name)) - } - .hollyhock_description : { - KEEP(*(.hollyhock_description)) - } - .hollyhock_author : { - KEEP(*(.hollyhock_author)) - } - .hollyhock_version : { - KEEP(*(.hollyhock_version)) - } - - .text : { - *(.text*) - *(.rodata*) - } - - .data : { - *(.data*) - } - - _edata = .; - PROVIDE(edata = .); - - .bss : { - *(.bss*) - *(COMMON) - } - - _end = .; - PROVIDE(end = .); - - x_mem_addr = 0xE5007000; - . = x_mem_addr; - - .oc_mem.x : { - *(.oc_mem.x) - } - - y_mem_addr = 0xE5017000; - . = y_mem_addr; - - .oc_mem.y : { - *(.oc_mem.y.dma) - *(.oc_mem.y.text) - *(.oc_mem.y.data) - } - - il_mem_addr = 0xE5200000; - . = il_mem_addr; - - .oc_mem.il : { - *(.oc_mem.il.data) - *(.oc_mem.il.text) - } -} \ No newline at end of file diff --git a/src/cas/bootstrap.cpp b/src/cas/bootstrap.cpp index 0db8df9..925ab9b 100644 --- a/src/cas/bootstrap.cpp +++ b/src/cas/bootstrap.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include "cpu/cpg.h" #include "cpu/cmt.h" #include "cpu/dmac.h" @@ -11,27 +11,8 @@ #include "../core/error.h" #include "../helpers/fileio.h" -// All external binaries have to be defined here -const char *bin_files[] = { - "il.bin", - "y.bin" -}; - -void *load_addresses[] = { - IL_MEMORY, - Y_MEMORY_0 -}; - -uint8_t load_bins(const char **bin_files, void **load_addresses, size_t bin_count); - uint8_t setup_cas() { - // Load external binaries - if (load_bins(bin_files, load_addresses, sizeof(load_addresses) / sizeof(void *))) - { - return 1; - } - // Enable DMA Controller POWER_MSTPCR0->DMAC = 0; DMAC_DMAOR->raw = 0; @@ -62,26 +43,3 @@ void restore_cas() // Restore clock speed cpg_set_pll_mul(CPG_PLL_MUL_DEFAULT); } - -uint8_t load_bins(const char **bin_files, void **load_addresses, size_t bin_count) -{ - for (size_t i = 0; i < bin_count; i++) - { - char bin_path[MAX_FILENAME_LEN] = DIRECTORY_BIN "\\" ; - strlcat(bin_path, bin_files[i], sizeof(bin_path)); - - size_t bin_size; - - if (get_file_size(bin_path, &bin_size)) - { - return 1; - } - - if (read_file(bin_path, load_addresses[i], bin_size)) - { - return 1; - } - } - - return 0; -} diff --git a/src/cas/cpu/stack.S b/src/cas/cpu/stack.S new file mode 100644 index 0000000..0aae669 --- /dev/null +++ b/src/cas/cpu/stack.S @@ -0,0 +1,21 @@ +#define _CONCAT(a, b) a##b +#define CONCAT(a, b) _CONCAT(a, b) +#define G(l) CONCAT(__USER_LABEL_PREFIX__, l) + +.global G(on_alt_stack) + +.text +.align 2 +G(on_alt_stack): +// r4 - void *stack +// r5 - void (*fun)(void *arg1) +// r6 - void *arg1 + mov.l r15, @-r4 + sts.l pr, @-r4 + mov r5, r1 + mov r4, r15 + jsr @r1 + mov r6, r4 + lds.l @r15+, pr + rts + mov.l @r15+, r15 diff --git a/src/cas/cpu/stack.h b/src/cas/cpu/stack.h index 88ea862..871b07f 100644 --- a/src/cas/cpu/stack.h +++ b/src/cas/cpu/stack.h @@ -1,7 +1,4 @@ #include extern "C" -void *set_stack_ptr(void *ptr); - -extern "C" -void *get_stack_ptr(); +void on_alt_stack(void *stack, void (*fun)(void *arg1), void *arg1); diff --git a/src/cas/cpu/stack.s b/src/cas/cpu/stack.s deleted file mode 100644 index a56ffed..0000000 --- a/src/cas/cpu/stack.s +++ /dev/null @@ -1,13 +0,0 @@ -.global _set_stack_ptr -.global _get_stack_ptr - -.align 2 -_set_stack_ptr: - mov r4, r15 - rts - mov r4, r0 - -_get_stack_ptr: - mov r15, r0 - rts - nop diff --git a/src/cas/display.h b/src/cas/display.h deleted file mode 100644 index 03417ee..0000000 --- a/src/cas/display.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -#define SCREEN_DATA_REGISTER ((volatile uint32_t *)0xB4000000) - -inline void prepare_gb_lcd() -{ - // ((void(*)(int, int, int, int))0x80038068)(0, CAS_LCD_WIDTH - 1, 0, (LCD_HEIGHT * 2) - 1); - ((void(*)(int, int, int, int))0x80038a10)(0, CAS_LCD_WIDTH - 1, 0, (LCD_HEIGHT * 2) - 1); - // ((void(*)(int))0x80038040)(0x2c); - ((void(*)(int))0x800389e8)(0x2c); -} diff --git a/src/core/cart_ram.cpp b/src/core/cart_ram.cpp index 126c0ff..8b10f46 100644 --- a/src/core/cart_ram.cpp +++ b/src/core/cart_ram.cpp @@ -1,7 +1,7 @@ #include "cart_ram.h" #include -#include +#include #include "error.h" #include "emulator.h" #include "../helpers/macros.h" diff --git a/src/core/controls.cpp b/src/core/controls.cpp index d42e178..32fc38a 100644 --- a/src/core/controls.cpp +++ b/src/core/controls.cpp @@ -1,8 +1,8 @@ #include "controls.h" -#include -#include -#include +#include +#include +#include #include "preferences.h" #include "emulator.h" #include "error.h" diff --git a/src/core/controls.h b/src/core/controls.h index 0683b95..5288721 100644 --- a/src/core/controls.h +++ b/src/core/controls.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include "../core/peanut_gb_header.h" #define DEFAULT_GB_KEY_A_0 KEY_EXE diff --git a/src/core/emulator.cpp b/src/core/emulator.cpp index b64d7ae..d1e7212 100644 --- a/src/core/emulator.cpp +++ b/src/core/emulator.cpp @@ -1,18 +1,19 @@ #include "emulator.h" +#include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "controls.h" #include "cart_ram.h" #include "error.h" #include "frametimes.h" #include "peanut_gb.h" -#include "../cas/display.h" #include "../cas/cpu/cmt.h" #include "../cas/cpu/cpg.h" #include "../cas/cpu/dmac.h" @@ -26,12 +27,12 @@ #define INPUT_NONE 0 #define INPUT_OPEN_MENU 1 -#define STACK_PTR_ADDR (void *)((uint32_t)Y_MEMORY_1 + (0x1000 - 4)) +#define STACK_PTR_ADDR (void *)((uint32_t)Y_MEMORY_1 + 0x1000) /* Global arrays in OC-Memory */ uint8_t gb_wram[WRAM_SIZE]; uint8_t gb_vram[VRAM_SIZE] __attribute__((section(".oc_mem.x"))); -uint8_t gb_oam[OAM_SIZE] __attribute__((section(".oc_mem.y.dma"))); +uint8_t gb_oam[OAM_SIZE] __attribute__((section(".oc_mem.y.dma"), aligned(alignof(long)))); uint8_t gb_hram_io[HRAM_IO_SIZE] __attribute__((section(".oc_mem.y.data"))); uint8_t execution_handle_input(struct gb_s *gb) @@ -143,7 +144,7 @@ void set_overclock(struct gb_s *gb, bool enabled) } // Draws scanline into framebuffer. -void lcd_draw_line(struct gb_s *gb, const uint32_t pixels[160], +void __attribute__((section(".oc_mem.il.text"), noinline)) lcd_draw_line(struct gb_s *gb, const uint32_t pixels[160], const uint_fast8_t line) { emu_preferences *preferences = (emu_preferences *)gb->direct.priv; @@ -151,28 +152,46 @@ void lcd_draw_line(struct gb_s *gb, const uint32_t pixels[160], // Wait for previous DMA to complete dma_wait(DMAC_CHCR_0); - if (unlikely(line == 0)) - { - prepare_gb_lcd(); - } - // When emulator will be paused, render a full frame in vram if (unlikely(preferences->emulator_paused)) { - for (uint16_t i = 0; i < LCD_WIDTH; i++) + if (!gb->direct.interlace) + { + memcpy(vram + (CAS_LCD_WIDTH * (line * 2)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 + 1)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + return; + } + + if (line == 1) + { + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 - 2)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + } + if (line != 0) + { + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 - 1)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + } + memcpy(vram + (CAS_LCD_WIDTH * (line * 2)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 + 1)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + if (line != LCD_WIDTH - 1) { - *(uint32_t *)&vram[(i * 2) + ((line * 2) * CAS_LCD_WIDTH)] = pixels[i]; - *(uint32_t *)&vram[(i * 2) + (((line * 2) + 1) * CAS_LCD_WIDTH)] = pixels[i]; + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 + 2)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); + } + if (line == LCD_WIDTH - 2) + { + memcpy(vram + (CAS_LCD_WIDTH * (line * 2 + 3)), pixels, CAS_LCD_WIDTH * sizeof(*vram)); } return; } + LCD_SetDrawingBounds(0, CAS_LCD_WIDTH - 1, line * 2, line * 2 + 1); + LCD_SendCommand(COMMAND_PREPARE_FOR_DRAW_DATA); + // Initialize DMA settings dmac_chcr tmp_chcr = { .raw = 0 }; - tmp_chcr.TS_0 = SIZE_32_0; - tmp_chcr.TS_1 = SIZE_32_1; - tmp_chcr.DM = DAR_FIXED_SOFT; + tmp_chcr.TS_0 = SIZE_2_0; + tmp_chcr.TS_1 = SIZE_2_1; + tmp_chcr.DM = DAR_FIXED_HARD; tmp_chcr.SM = SAR_INCREMENT; tmp_chcr.RS = AUTO; tmp_chcr.TB = CYCLE_STEAL; @@ -182,13 +201,29 @@ void lcd_draw_line(struct gb_s *gb, const uint32_t pixels[160], DMAC_CHCR_0->raw = 0; *DMAC_SAR_0 = (uint32_t)pixels; // P4 Area (OC-Memory) => Physical address is same as virtual - *DMAC_DAR_0 = (uint32_t)SCREEN_DATA_REGISTER & 0x1FFFFFFF; // P2 Area => Physical address is virtual with 3 ms bits cleared - *DMAC_TCR_0 = (CAS_LCD_WIDTH * 2) / 32 * 2; // (Pixels per line * bytes per pixel) / dmac operation bytes * 2 lines - *DMAC_TCRB_0 = ((CAS_LCD_WIDTH * 2 / 32) << 16) - | (CAS_LCD_WIDTH * 2 / 32); + *DMAC_DAR_0 = (uint32_t)lcd_data_port & 0x1FFFFFFF; // P2 Area => Physical address is virtual with 3 ms bits cleared + *DMAC_TCR_0 = CAS_LCD_WIDTH * 2; // (Pixels per line * bytes per pixel) / dmac operation bytes * 2 lines + *DMAC_TCRB_0 = (CAS_LCD_WIDTH << 16) + | CAS_LCD_WIDTH; + // make sure we can acces it from ram + for (size_t i = 0; i < (CAS_LCD_WIDTH * 2); i += 32) + { + __asm__ volatile ("ocbwb @%0" : : "r"((uintptr_t)pixels + i)); + } + __asm__ volatile ("ocbwb @%0" : : "r"((uintptr_t)pixels + (CAS_LCD_WIDTH * 2) - 1)); + + // Start Channel 0 DMAC_CHCR_0->raw = tmp_chcr.raw; + /*for (uint16_t i = 0; i < LCD_WIDTH; i++) { + *lcd_data_port = (uint16_t)pixels[i]; + *lcd_data_port = (uint16_t)(pixels[i] >> 16); + } + for (uint16_t i = 0; i < LCD_WIDTH; i++) { + *lcd_data_port = (uint16_t)pixels[i]; + *lcd_data_port = (uint16_t)(pixels[i] >> 16); + }*/ } // Handles an error reported by the emulator. The emulator context may be used @@ -319,7 +354,7 @@ uint8_t close_rom(struct gb_s *gb) return return_code; } -uint8_t execute_rom(struct gb_s *gb) +uint8_t __attribute__((section(".oc_mem.il.text"), noinline, optimize("Os"))) execute_rom(struct gb_s *gb) { emu_preferences *preferences = (emu_preferences *)gb->direct.priv; frametime_counter_set(gb); @@ -334,13 +369,9 @@ uint8_t execute_rom(struct gb_s *gb) gb_tick_rtc(gb); } - void *tmp_stack_ptr_bak = get_stack_ptr(); - set_stack_ptr(STACK_PTR_ADDR); - // Run CPU until next frame - gb_run_frame(gb); - - set_stack_ptr(tmp_stack_ptr_bak); + on_alt_stack(STACK_PTR_ADDR, (void (*)(void *))gb_run_frame, (void *)gb); + //gb_run_frame(gb); frametime_counter_wait(gb); @@ -399,7 +430,7 @@ uint8_t run_emulator(struct gb_s *gb, emu_preferences *prefs) if (prepare_emulator(gb, prefs) != 0) { return 1; - } + } // Render preview of menu fillScreen(0x0000); diff --git a/src/core/error.cpp b/src/core/error.cpp index 21892b4..0d89ab4 100644 --- a/src/core/error.cpp +++ b/src/core/error.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "../emu_ui/components.h" #include "../emu_ui/colors.h" #include "../helpers/functions.h" @@ -21,8 +22,6 @@ const char *error_messages[] = { ERROR_MSG_ESTRBUFEMPTY, }; -uint8_t errno; - char error_file[ERROR_MAX_FILE_LEN]; char error_info[ERROR_MAX_INFO_LEN]; diff --git a/src/core/error.h b/src/core/error.h index 1aad854..1035f52 100644 --- a/src/core/error.h +++ b/src/core/error.h @@ -35,7 +35,8 @@ /*! @brief Stores information about an error */ -extern uint8_t errno; +#include +//extern uint8_t errno; /*! @brief The file in which an error occured diff --git a/src/core/palettes.cpp b/src/core/palettes.cpp index 744761b..ff8c83d 100644 --- a/src/core/palettes.cpp +++ b/src/core/palettes.cpp @@ -3,8 +3,8 @@ #include #include #include -#include -#include +#include +#include #include "error.h" #include "emulator.h" #include "../helpers/fileio.h" diff --git a/src/core/peanut_gb.h b/src/core/peanut_gb.h index d755a13..1eae5de 100644 --- a/src/core/peanut_gb.h +++ b/src/core/peanut_gb.h @@ -33,6 +33,7 @@ #pragma once #include "peanut_gb_header.h" +#include #include /* Required for int types */ #include #include "../helpers/macros.h" @@ -40,8 +41,8 @@ #include "../cas/cpu/dmac.h" #include "../cas/cpu/mmu.h" -#include -#include +#include +#include #define PEANUT_GB_IS_LITTLE_ENDIAN 0 @@ -89,7 +90,7 @@ /* Adds more code to improve LCD rendering accuracy. */ #ifndef PEANUT_GB_HIGH_LCD_ACCURACY -# define PEANUT_GB_HIGH_LCD_ACCURACY 0 +# define PEANUT_GB_HIGH_LCD_ACCURACY 1 #endif /* Use intrinsic functions. This may produce smaller and faster code. */ @@ -397,8 +398,8 @@ #define IO_STAT_MODE_SEARCH_TRANSFER 3 #define IO_STAT_MODE_VBLANK_OR_TRANSFER_MASK 0x1 -/* Two pixel arrays for double buffering */ -uint32_t lcd_pixels[2][LCD_WIDTH] __attribute__((section(".oc_mem.y.dma"))); +/* four pixel arrays for double buffering and interlacing */ +uint32_t lcd_pixels[4][LCD_WIDTH] __attribute__((section(".oc_mem.y.dma"), aligned(32))); void __attribute__((section(".oc_mem.il.text"))) __set_rom_bank(struct gb_s *gb) { @@ -445,12 +446,14 @@ void __attribute__((section(".oc_mem.il.text"))) __set_cram_bank(struct gb_s *gb gb->memory_map[0xB] = gb->memory_map[0xA] + 0x1000; } -void __attribute__((section(".oc_mem.il.text"))) __gb_dma(struct gb_s *gb, uint16_t addr) +void /*__attribute__((section(".oc_mem.il.text")))*/ __gb_dma(struct gb_s *gb, uint16_t addr) { - dma_wait(DMAC_CHCR_1); + // take more precausions before reabeling. + + //dma_wait(DMAC_CHCR_1); /* Start DMA operation on Channel 1 */ - dmac_chcr tmp_chcr = { .raw = 0 }; + /*dmac_chcr tmp_chcr = { .raw = 0 }; tmp_chcr.TS_0 = SIZE_16x2_0; tmp_chcr.TS_1 = SIZE_16x2_1; tmp_chcr.DM = DAR_INCREMENT; @@ -468,14 +471,16 @@ void __attribute__((section(".oc_mem.il.text"))) __gb_dma(struct gb_s *gb, uint1 *DMAC_DAR_1 = (uint32_t)gb->oam; // Will be in P4 Area => Physical address is same as virtual *DMAC_TCR_1 = OAM_SIZE / 32; - DMAC_CHCR_1->raw = tmp_chcr.raw; + DMAC_CHCR_1->raw = tmp_chcr.raw;*/ + + memcpy(gb->oam, gb->memory_map[PEANUT_GB_GET_MSN16(addr)] + (addr & 0xF00), OAM_SIZE); } /** * Internal function used to read bytes. * addr is host platform endian. */ -uint8_t __attribute__((section(".oc_mem.il.text"))) __gb_read(struct gb_s *gb, uint16_t addr) +uint8_t __attribute__((section(".oc_mem.il.text"), noinline)) __gb_read(struct gb_s *gb, uint16_t addr) { if (PEANUT_GB_GET_MSN16(addr) == 0xF) { @@ -521,7 +526,7 @@ uint8_t __attribute__((section(".oc_mem.il.text"))) __gb_read(struct gb_s *gb, u /** * Internal function used to write bytes. */ -void __attribute__((section(".oc_mem.il.text"))) __gb_write(struct gb_s *gb, uint_fast16_t addr, uint8_t val) +void __attribute__((section(".oc_mem.il.text"), noinline)) __gb_write(struct gb_s *gb, uint_fast16_t addr, uint8_t val) { switch(PEANUT_GB_GET_MSN16(addr)) { @@ -1013,13 +1018,9 @@ struct sprite_data { }; #if PEANUT_GB_HIGH_LCD_ACCURACY -static int compare_sprites(const void *in1, const void *in2) +static int compare_sprites(const struct sprite_data *sd1, const struct sprite_data *sd2) { - const struct sprite_data *sd1, *sd2; int x_res; - - sd1 = (struct sprite_data *)in1; - sd2 = (struct sprite_data *)in2; x_res = (int)sd1->x - (int)sd2->x; if(x_res != 0) return x_res; @@ -1028,13 +1029,13 @@ static int compare_sprites(const void *in1, const void *in2) } #endif -void __attribute__((section(".oc_mem.il.text"))) __gb_draw_line(struct gb_s *gb) +void __attribute__((section(".oc_mem.il.text"), noinline, optimize("Os"))) __gb_draw_line(struct gb_s *gb) { emu_preferences *preferences = (emu_preferences *)gb->direct.priv; palette selected_palette = preferences->palettes[preferences->config.selected_palette]; /* Select which buffer to use for the current line */ - uint32_t *pixels = lcd_pixels[gb->hram_io[IO_LY] % 2]; + uint32_t *pixels = lcd_pixels[gb->hram_io[IO_LY] % 4]; /* If LCD not initialised by front-end, don't render anything. */ if(gb->display.lcd_draw_line == NULL) @@ -1220,13 +1221,13 @@ void __attribute__((section(".oc_mem.il.text"))) __gb_draw_line(struct gb_s *gb) #if PEANUT_GB_HIGH_LCD_ACCURACY uint8_t number_of_sprites = 0; - struct sprite_data sprites_to_render[NUM_SPRITES]; + struct sprite_data sprites_to_render[MAX_SPRITES_LINE]; /* Record number of sprites on the line being rendered, limited * to the maximum number sprites that the Game Boy is able to * render on each line (10 sprites). */ for(sprite_number = 0; - sprite_number < PEANUT_GB_ARRAYSIZE(sprites_to_render); + sprite_number < NUM_SPRITES; sprite_number++) { /* Sprite Y position. */ @@ -1240,18 +1241,27 @@ void __attribute__((section(".oc_mem.il.text"))) __gb_draw_line(struct gb_s *gb) || gb->hram_io[IO_LY] + 16 < OY) continue; + struct sprite_data current; + current.sprite_number = sprite_number; + current.x = OX; - sprites_to_render[number_of_sprites].sprite_number = sprite_number; - sprites_to_render[number_of_sprites].x = OX; - number_of_sprites++; + uint8_t place; + for (place = number_of_sprites; place != 0; place--) + { + if(compare_sprites(&sprites_to_render[place - 1], ¤t) < 0) + break; + } + if(place >= MAX_SPRITES_LINE) + continue; + memmove( + &sprites_to_render[place + 1], + &sprites_to_render[place], + (MAX_SPRITES_LINE - place - 1) * sizeof(current) + ); + if(number_of_sprites <= MAX_SPRITES_LINE) + number_of_sprites++; + sprites_to_render[place] = current; } - - /* If maximum number of sprites reached, prioritise X - * coordinate and object location in OAM. */ - qsort(&sprites_to_render[0], number_of_sprites, - sizeof(sprites_to_render[0]), compare_sprites); - if(number_of_sprites > MAX_SPRITES_LINE) - number_of_sprites = MAX_SPRITES_LINE; #endif /* Render each sprite, from low priority to high priority. */ @@ -1330,7 +1340,7 @@ void __attribute__((section(".oc_mem.il.text"))) __gb_draw_line(struct gb_s *gb) uint8_t c = (t1 & 0x1) | ((t2 & 0x1) << 1); // check transparency / sprite overlap / background overlap - if(c && !(OF & OBJ_PRIORITY && !((pixels[disp_x] & 0xFFFF) == selected_palette.data[LCD_PALETTE_BG >> 2][gb->display.bg_palette[0]]))) + if((c && !(OF & OBJ_PRIORITY && !((pixels[disp_x] & 0xFFFF) == selected_palette.data[LCD_PALETTE_BG >> 2][gb->display.bg_palette[0]])))) { /* Set pixel colour. */ pixels[disp_x] = (OF & OBJ_PALETTE) @@ -3021,13 +3031,12 @@ void __gb_step_cpu(struct gb_s *gb) /* If interlaced is activated, change which lines get * updated. Also, only update lines on frames that are * actually drawn when frame skip is enabled. */ - // if(gb->direct.interlace && - // (!gb->direct.frame_skip || - // gb->display.frame_skip_count)) - // { - // gb->display.interlace_count = - // !gb->display.interlace_count; - // } + if(gb->direct.interlace && + (!gb->direct.frame_skip || + gb->direct.frame_drawn)) + { + gb->display.interlace_count ^= 1; + } #endif } /* Normal Line */ @@ -3083,7 +3092,7 @@ void __gb_step_cpu(struct gb_s *gb) /* If halted, loop until an interrupt occurs. */ } -void __attribute__((section(".oc_mem.il.text"))) gb_run_frame(struct gb_s *gb) +void gb_run_frame(struct gb_s *gb) { gb->gb_frame = 0; diff --git a/src/core/peanut_gb_header.h b/src/core/peanut_gb_header.h index d0c221f..7958fa4 100644 --- a/src/core/peanut_gb_header.h +++ b/src/core/peanut_gb_header.h @@ -90,7 +90,7 @@ /* Adds more code to improve LCD rendering accuracy. */ #ifndef PEANUT_GB_HIGH_LCD_ACCURACY -# define PEANUT_GB_HIGH_LCD_ACCURACY 0 +# define PEANUT_GB_HIGH_LCD_ACCURACY 1 #endif /* Use intrinsic functions. This may produce smaller and faster code. */ diff --git a/src/core/preferences.cpp b/src/core/preferences.cpp index 8c33dee..4874c3f 100644 --- a/src/core/preferences.cpp +++ b/src/core/preferences.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include "../helpers/fileio.h" #include "../helpers/ini.h" #include "../helpers/functions.h" @@ -85,8 +85,7 @@ uint8_t process_config_ini(char *ini_string, uint32_t len, struct gb_s *gb) if (interl_en) { - set_interlacing(gb, false); // Interlacing is currently not working and therefore defaults to disabled - // set_interlacing(gb, interl_en->value_int); + set_interlacing(gb, interl_en->value_int); } if (emu_speed) diff --git a/src/emu_ui/components.cpp b/src/emu_ui/components.cpp index 83e0ff0..c915c53 100644 --- a/src/emu_ui/components.cpp +++ b/src/emu_ui/components.cpp @@ -3,22 +3,18 @@ #include #include #include -#include -#include +#include +#include +#include +#include #include "../emu_ui/input.h" #include "../emu_ui/font.h" #include "../emu_ui/effects.h" #include "../emu_ui/colors.h" #include "../helpers/macros.h" -// Use namespace because of conflicting function declarations in mem.hpp and string.h -namespace hhk -{ - #include -} - -#define CAS_LCD_WIDTH 320 -#define CAS_LCD_HEIGHT 528 +#define CAS_LCD_WIDTH ::width +#define CAS_LCD_HEIGHT ::height #define SLIDER_HANDLE_WIDTH 4 #define SLIDER_TRACK_HEIGHT 2 diff --git a/src/emu_ui/effects.cpp b/src/emu_ui/effects.cpp index 570f7e3..83624e0 100644 --- a/src/emu_ui/effects.cpp +++ b/src/emu_ui/effects.cpp @@ -1,11 +1,11 @@ #include "effects.h" #include -#include -#include +#include +#include -#define CAS_LCD_WIDTH 320 -#define CAS_LCD_HEIGHT 528 +#define CAS_LCD_WIDTH ::width +#define CAS_LCD_HEIGHT ::height #define EFFECT_DARKEN 13108 diff --git a/src/emu_ui/font.cpp b/src/emu_ui/font.cpp index f310a44..c203a24 100644 --- a/src/emu_ui/font.cpp +++ b/src/emu_ui/font.cpp @@ -2,12 +2,13 @@ #include #include -#include +#include +#include #include "components.h" -#define FONTBASE 0x80633f50 // 0x8062F4C8 -#define DISPLAY_WIDTH 320 -#define DISPLAY_HEIGHT 528 +#define FONTBASE ::DEBUG_FONTBASE +#define DISPLAY_WIDTH ::width +#define DISPLAY_HEIGHT ::height char hex_chars[17] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; @@ -132,7 +133,7 @@ void print_char(char character, uint16_t x, uint16_t y, uint8_t size, } // now draw the character - uint16_t *pixel = (uint16_t *)(FONTBASE + (0xC0 * charIndex)); + uint16_t *pixel = (uint16_t *)(FONTBASE + (DEBUG_CHAR_WIDTH * DEBUG_CHAR_HEIGHT * charIndex)); uint16_t tempXPos = x; uint16_t tempYPos = y + 1; diff --git a/src/emu_ui/input.cpp b/src/emu_ui/input.cpp index 8a68e24..2ea67b0 100644 --- a/src/emu_ui/input.cpp +++ b/src/emu_ui/input.cpp @@ -1,8 +1,9 @@ #include "input.h" #include -#include -#include +#include +#include +#include #include "menu/menu.h" uint32_t key_streak; // Holds the streak amount diff --git a/src/emu_ui/menu/menu.cpp b/src/emu_ui/menu/menu.cpp index 63db7dd..51c7fdf 100644 --- a/src/emu_ui/menu/menu.cpp +++ b/src/emu_ui/menu/menu.cpp @@ -3,9 +3,11 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include "sdk/os/debug.h" #include "tabs/current.h" #include "tabs/load.h" #include "tabs/saves.h" @@ -23,11 +25,6 @@ #include "../../helpers/functions.h" #include "../../helpers/fileio.h" -// Use namespace because of conflicting function declarations in mem.hpp and string.h -namespace hhk -{ - #include -} #define MENU_DESCRIPTION_HEIGHT 37 #define MENU_DESCRIPTION_X_OFFSET STD_CONTENT_OFFSET @@ -290,7 +287,6 @@ menu *prepare_menu_info(menu *menu, gb_s *gb) { return nullptr; } - if (!prepare_tab_load(&(menu->tabs[2]))) { return nullptr; diff --git a/src/emu_ui/menu/tabs/current.cpp b/src/emu_ui/menu/tabs/current.cpp index 7a106c6..d99329e 100644 --- a/src/emu_ui/menu/tabs/current.cpp +++ b/src/emu_ui/menu/tabs/current.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "../menu.h" #include "../../components.h" #include "../../colors.h" @@ -12,34 +14,30 @@ #include "../../../helpers/macros.h" #include "../../../helpers/functions.h" -namespace hhk -{ - #include -} - #define TAB_CURRENT_TITLE "Current" -#define TAB_CUR_ITEM_COUNT 5 +#define TAB_CUR_ITEM_COUNT 6 #define TAB_CUR_ITEM_FRAMESKIP_INDEX 0 #define TAB_CUR_ITEM_FRAMESKIP_TITLE "Frameskipping" -#define TAB_CUR_ITEM_FRAMESKIP_SUBTITLE "Skips rendering and LCD-Refresh" +#define TAB_CUR_ITEM_FRAMESKIP_SUBTITLE "Skips rendering and LCD-Refresh for a number of frames" -#define TAB_CUR_ITEM_INTERL_INDEX 0 +#define TAB_CUR_ITEM_INTERL_INDEX 1 #define TAB_CUR_ITEM_INTERL_TITLE "Interlacing" +#define TAB_CUR_ITEM_INTERL_SUBTITLE "Skips rendering and LCD-Refresh for each other line" -#define TAB_CUR_ITEM_SPEED_INDEX 1 +#define TAB_CUR_ITEM_SPEED_INDEX 2 #define TAB_CUR_ITEM_SPEED_TITLE "Emulation Speed" #define TAB_CUR_ITEM_SPEED_SUBTITLE "Set the emulation speed target" -#define TAB_CUR_ITEM_OVERCLOCK_INDEX 2 +#define TAB_CUR_ITEM_OVERCLOCK_INDEX 3 #define TAB_CUR_ITEM_OVERCLOCK_TITLE "Overclock" -#define TAB_CUR_ITEM_PALETTE_INDEX 3 +#define TAB_CUR_ITEM_PALETTE_INDEX 4 #define TAB_CUR_ITEM_PALETTE_TITLE "Color Palette" #define TAB_CUR_ITEM_PALETTE_SUBTITLE "Select a palette for this ROM" -#define TAB_CUR_ITEM_QUIT_INDEX 4 +#define TAB_CUR_ITEM_QUIT_INDEX 5 #define TAB_CUR_ITEM_QUIT_TITLE "Quit CPBoy" #define DIALOG_FRAMESKIP_ITEM_COUNT 3 @@ -583,7 +581,7 @@ menu_tab *prepare_tab_current(menu_tab *tab, emu_preferences *preferences) tab->items[TAB_CUR_ITEM_FRAMESKIP_INDEX].disabled = false; tab->items[TAB_CUR_ITEM_SPEED_INDEX].disabled = false; tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].disabled = false; - // tab->items[TAB_CUR_ITEM_INTERL_INDEX].disabled = false; + tab->items[TAB_CUR_ITEM_INTERL_INDEX].disabled = false; tab->items[TAB_CUR_ITEM_PALETTE_INDEX].disabled = false; tab->items[TAB_CUR_ITEM_QUIT_INDEX].disabled = false; @@ -591,7 +589,7 @@ menu_tab *prepare_tab_current(menu_tab *tab, emu_preferences *preferences) strlcpy(tab->items[TAB_CUR_ITEM_FRAMESKIP_INDEX].title, TAB_CUR_ITEM_FRAMESKIP_TITLE, sizeof(tab->items[TAB_CUR_ITEM_FRAMESKIP_INDEX].title)); strlcpy(tab->items[TAB_CUR_ITEM_SPEED_INDEX].title, TAB_CUR_ITEM_SPEED_TITLE, sizeof(tab->items[TAB_CUR_ITEM_SPEED_INDEX].title)); strlcpy(tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].title, TAB_CUR_ITEM_OVERCLOCK_TITLE, sizeof(tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].title)); - // strlcpy(tab->items[TAB_CUR_ITEM_INTERL_INDEX].title, TAB_CUR_ITEM_INTERL_TITLE, sizeof(tab->items[TAB_CUR_ITEM_INTERL_INDEX].title)); + strlcpy(tab->items[TAB_CUR_ITEM_INTERL_INDEX].title, TAB_CUR_ITEM_INTERL_TITLE, sizeof(tab->items[TAB_CUR_ITEM_INTERL_INDEX].title)); strlcpy(tab->items[TAB_CUR_ITEM_PALETTE_INDEX].title, TAB_CUR_ITEM_PALETTE_TITLE, sizeof(tab->items[TAB_CUR_ITEM_PALETTE_INDEX].title)); strlcpy(tab->items[TAB_CUR_ITEM_QUIT_INDEX].title, TAB_CUR_ITEM_QUIT_TITLE, sizeof(tab->items[TAB_CUR_ITEM_QUIT_INDEX].title)); @@ -619,9 +617,9 @@ menu_tab *prepare_tab_current(menu_tab *tab, emu_preferences *preferences) strlcat(tab->items[TAB_CUR_ITEM_SPEED_INDEX].value, "%", sizeof(tab->items[TAB_CUR_ITEM_SPEED_INDEX].value)); } - // strlcpy(tab->items[TAB_CUR_ITEM_INTERL_INDEX].value, - // (preferences->config.interlacing_enabled)? "Enabled" : "Disabled", - // sizeof(tab->items[TAB_CUR_ITEM_INTERL_INDEX].value)); + strlcpy(tab->items[TAB_CUR_ITEM_INTERL_INDEX].value, + (preferences->config.interlacing_enabled)? "Enabled" : "Disabled", + sizeof(tab->items[TAB_CUR_ITEM_INTERL_INDEX].value)); strlcpy(tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].value, (preferences->config.overclock_enabled)? "Enabled" : "Disabled", sizeof(tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].value)); @@ -633,8 +631,8 @@ menu_tab *prepare_tab_current(menu_tab *tab, emu_preferences *preferences) // Value color for each item tab->items[TAB_CUR_ITEM_FRAMESKIP_INDEX].value_color = (preferences->config.frameskip_enabled)? COLOR_SUCCESS : COLOR_DANGER; - // tab->items[TAB_CUR_ITEM_INTERL_INDEX].value_color = - // (preferences->config.interlacing_enabled)? COLOR_SUCCESS : COLOR_DANGER; + tab->items[TAB_CUR_ITEM_INTERL_INDEX].value_color = + (preferences->config.interlacing_enabled)? COLOR_SUCCESS : COLOR_DANGER; tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].value_color = (preferences->config.overclock_enabled)? COLOR_SUCCESS : COLOR_DANGER; tab->items[TAB_CUR_ITEM_SPEED_INDEX].value_color = COLOR_SUCCESS; @@ -643,7 +641,7 @@ menu_tab *prepare_tab_current(menu_tab *tab, emu_preferences *preferences) // Action for each item tab->items[TAB_CUR_ITEM_FRAMESKIP_INDEX].action = action_frameskip_selection; tab->items[TAB_CUR_ITEM_SPEED_INDEX].action = action_speed_selection; - // tab->items[TAB_CUR_ITEM_INTERL_INDEX].action = action_interlacing_selection; + tab->items[TAB_CUR_ITEM_INTERL_INDEX].action = action_interlacing_selection; tab->items[TAB_CUR_ITEM_OVERCLOCK_INDEX].action = action_overclock_selection; tab->items[TAB_CUR_ITEM_PALETTE_INDEX].action = action_palette_selection; tab->items[TAB_CUR_ITEM_QUIT_INDEX].action = action_quit_emulator; diff --git a/src/emu_ui/menu/tabs/load.cpp b/src/emu_ui/menu/tabs/load.cpp index ef6f4e6..cfcb44d 100644 --- a/src/emu_ui/menu/tabs/load.cpp +++ b/src/emu_ui/menu/tabs/load.cpp @@ -2,7 +2,10 @@ #include #include -#include +#include +#include +#include +#include #include "../menu.h" #include "../../components.h" #include "../../colors.h" @@ -14,11 +17,6 @@ #include "../../../helpers/fileio.h" #include "../../../helpers/functions.h" -namespace hhk -{ - #include -} - #define TAB_LOAD_TITLE "Load" #define TAB_LOAD_ITEM_COUNT 20 diff --git a/src/emu_ui/menu/tabs/saves.cpp b/src/emu_ui/menu/tabs/saves.cpp index 56ab81d..4f37fef 100644 --- a/src/emu_ui/menu/tabs/saves.cpp +++ b/src/emu_ui/menu/tabs/saves.cpp @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include "../menu.h" #include "../../components.h" #include "../../colors.h" @@ -12,11 +13,6 @@ #include "../../../core/error.h" #include "../../../helpers/macros.h" -namespace hhk -{ - #include -} - #define TAB_SAVES_TITLE "Saves" int32_t dummy_function(menu_item *item, gb_s *gb) { return 0; } diff --git a/src/emu_ui/menu/tabs/settings.cpp b/src/emu_ui/menu/tabs/settings.cpp index 7b4f880..b06598e 100644 --- a/src/emu_ui/menu/tabs/settings.cpp +++ b/src/emu_ui/menu/tabs/settings.cpp @@ -3,8 +3,10 @@ #include #include -#include -#include +#include +#include +#include +#include #include "../menu.h" #include "../../components.h" #include "../../colors.h" @@ -13,11 +15,7 @@ #include "../../input.h" #include "../../../core/error.h" #include "../../../helpers/macros.h" - -namespace hhk -{ - #include -} +#include "sdk/calc/calc.h" #define TAB_SETTINGS_TITLE "Settings" #define TAB_SETTINGS_DESCRIPTION "Settings" @@ -124,7 +122,7 @@ void draw_controls_alert(emu_preferences *preferences, uint8_t selected_item) // Draw button title switch (preferences->controls[i][0]) { - case KEY_SHIFT: + case (unsigned int)KEY_SHIFT: strcpy(title, CAS_KEY_TEXT_SHIFT); break; case KEY_CLEAR: @@ -179,7 +177,7 @@ void draw_controls_alert(emu_preferences *preferences, uint8_t selected_item) switch (preferences->controls[i][1]) { - case KEY_KEYBOARD: + case (unsigned int)KEY_KEYBOARD: strcpy(title, CAS_KEY_TEXT_KEYBOARD); break; case KEY_UP: diff --git a/src/helpers/fileio.cpp b/src/helpers/fileio.cpp index b7eca94..4f316b1 100644 --- a/src/helpers/fileio.cpp +++ b/src/helpers/fileio.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include "../core/error.h" #include "functions.h" @@ -36,7 +36,7 @@ uint8_t _read_mcs(const char *dir, const char *name, void **buf, uint32_t *size, const char *err_file, uint32_t err_line) { char *name2; - uint8_t var_type; + MCS_VariableType var_type; int32_t ret = MCS_GetVariable(dir, name, &var_type, &name2, buf, size); @@ -173,14 +173,14 @@ uint8_t find_files(const char *path, char (*buf)[MAX_FILENAME_LEN], uint8_t max) return 0; } - wchar_t wpath[MAX_FILENAME_LEN]; - wchar_t filename[MAX_FILENAME_LEN]; + char_const16_t wpath[MAX_FILENAME_LEN]; + char_const16_t filename[MAX_FILENAME_LEN]; struct File_FindInfo info; int handle; int32_t ret; uint8_t file_count = 0; - char_to_wchar(wpath, path); + char_to_char_const16(wpath, path); ret = File_FindFirst(wpath, &handle, filename, &info); @@ -193,7 +193,7 @@ uint8_t find_files(const char *path, char (*buf)[MAX_FILENAME_LEN], uint8_t max) if (filename[0] != '.') { // Copy file name - wchar_to_char(buf[file_count], filename); + char_const16_to_char(buf[file_count], filename); file_count++; } } diff --git a/src/helpers/functions.cpp b/src/helpers/functions.cpp index acca376..5638662 100644 --- a/src/helpers/functions.cpp +++ b/src/helpers/functions.cpp @@ -3,10 +3,11 @@ #include #include #include +#include -wchar_t *char_to_wchar(wchar_t *wstr, const char *str) +char_const16_t *char_to_char_const16(char_const16_t *wstr, const char *str) { - wchar_t *dest = wstr; + char_const16_t *dest = wstr; for (const char *c = str; *c; c++, dest++) { @@ -18,11 +19,11 @@ wchar_t *char_to_wchar(wchar_t *wstr, const char *str) return wstr; } -char *wchar_to_char(char *str, const wchar_t *wstr) +char *char_const16_to_char(char *str, const char_const16_t *wstr) { char *dest = str; - for (const wchar_t *c = wstr; *c; c++, dest++) + for (const char_const16_t *c = wstr; *c; c++, dest++) { *dest = *c; } diff --git a/src/helpers/functions.h b/src/helpers/functions.h index 668cba6..04ef5dd 100644 --- a/src/helpers/functions.h +++ b/src/helpers/functions.h @@ -1,6 +1,7 @@ #pragma once #include +#include template T clamp(T val, T min, T max) @@ -25,6 +26,6 @@ T hash_string(const char *str, T range) } char *itoa_leading_zeros(uint32_t val, char *str, uint8_t base, uint8_t digits); -wchar_t *char_to_wchar(wchar_t *wstr, const char *str); -char *wchar_to_char(char *str, const wchar_t *wstr); +char_const16_t *char_to_char_const16(char_const16_t *wstr, const char *str); +char *char_const16_to_char(char *str, const char_const16_t *wstr); uint32_t align_val(uint32_t val, uint32_t at); diff --git a/src/helpers/ini.cpp b/src/helpers/ini.cpp index 1bbcedc..39fda25 100644 --- a/src/helpers/ini.cpp +++ b/src/helpers/ini.cpp @@ -2,17 +2,12 @@ #include #include -#include +#include +#include #include "../core/error.h" #include "../emu_ui/font.h" #include "../helpers/functions.h" -// Use namespace because of conflicting function declarations in mem.hpp and string.h -namespace hhk -{ - #include -} - #define TMP_STRING_LEN INI_MAX_VALUE_LEN #define INI_LINE_TYPE_SECTION 0 #define INI_LINE_TYPE_KEY 1 diff --git a/src/helpers/macros.h b/src/helpers/macros.h index 7787e72..8a4a7e7 100644 --- a/src/helpers/macros.h +++ b/src/helpers/macros.h @@ -1,14 +1,15 @@ #pragma once +#include #include "../core/preferences.h" #define XSTR(x) STR(x) #define STR(x) #x -#define CPBOY_VERSION "v0.3.0" +#define CPBOY_VERSION "v0.3.1" -#define CAS_LCD_WIDTH 320 -#define CAS_LCD_HEIGHT 528 +#define CAS_LCD_WIDTH ::width +#define CAS_LCD_HEIGHT ::height #define MAX_FILENAME_LEN 200 @@ -16,7 +17,6 @@ #define DIRECTORY_MAIN "\\fls0\\CPBoy\\" #define DIRECTORY_ROM DIRECTORY_MAIN "roms" -#define DIRECTORY_BIN DIRECTORY_MAIN "bin" #define EXTENSION_ROM ".gb" diff --git a/src/main.cpp b/src/main.cpp index b1eb9b7..bd98ea5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,8 +22,10 @@ * IN THE SOFTWARE. */ -#include -#include +#include +#include +#include +#include #include "cas/bootstrap.h" #include "core/emulator.h" #include "core/error.h" @@ -35,11 +37,10 @@ APP_VERSION(CPBOY_VERSION) gb_s main_gb __attribute__((section(".oc_mem.y.data"))); emu_preferences main_preferences __attribute__((section(".oc_mem.y.data"))); +std::remove_pointer_t (*vram_backup)[width * height]; int main() { - calcInit(); - if (setup_cas()) { error_crash_alert(get_error_string(errno)); @@ -53,7 +54,18 @@ int main() } end: - restore_cas(); - calcEnd(); + restore_cas(); return 0; } + +extern "C" void calcInit() +{ + vram_backup = reinterpret_cast(new std::remove_pointer_t); + std::memcpy(*vram_backup, vram, sizeof(*vram_backup)); +} + +extern "C" void calcExit() +{ + std::memcpy(vram, *vram_backup, sizeof(*vram_backup)); + delete[] vram_backup; +} diff --git a/src/stack.cpp b/src/stack.cpp new file mode 100644 index 0000000..c0f0b37 --- /dev/null +++ b/src/stack.cpp @@ -0,0 +1,18 @@ +#include "sdk/os/debug.h" +#include "sdk/os/lcd.h" +#include +#include +#include + +extern "C" constexpr unsigned int __stack_chk_guard = 0xEEEEEEEE; + +extern "C" void __attribute__((noreturn)) __stack_chk_fail() { + std::jmp_buf buf; + setjmp(buf); + for (std::size_t e = 0; e < sizeof(buf) / sizeof(*buf); e++) { + Debug_Printf(3, e, true, 0, "%u: %08x", e, buf[e]); + } + LCD_Refresh(); + Debug_WaitKey(); + std::exit(EXIT_FAILURE); +} \ No newline at end of file